<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio_vgpio.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio_vgpio.c$
* $Version : 3.8.3.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the GPIO standard functions used on boards
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "lwgpio_vgpio.h"
#include "lwgpio.h"


const volatile uint32_t *pcr_reg_arr[] = { 
    &PORT_PCR_REG(PORT0_BASE_PTR, 0),
    &PORT_PCR_REG(PORT1_BASE_PTR, 0),
    &PORT_PCR_REG(PORT2_BASE_PTR, 0),
    &PORT_PCR_REG(PORT3_BASE_PTR, 0),
    &PORT_PCR_REG(PORT4_BASE_PTR, 0)
#ifdef PORT5_BASE_PTR
    ,&PORT_PCR_REG(PORT5_BASE_PTR, 0)
#endif
};

const static GPIO_MemMapPtr gpio_ptr_arr[] = {
    PT0_BASE_PTR,
    PT1_BASE_PTR,
    PT2_BASE_PTR,
    PT3_BASE_PTR,
    PT4_BASE_PTR
#ifdef PORT5_BASE_PTR
    ,PT5_BASE_PTR
#endif
};


#define LWGPIO_PIN_FROM_ID(id) (((id) & LWGPIO_PIN_MASK) >> LWGPIO_PIN_SHIFT)

#define LWGPIO_PORT_FROM_ID(id) (((id) & LWGPIO_PORT_MASK) >> LWGPIO_PORT_SHIFT)

/* Interrupt mode definitions */
#define LWGPIO_INT_MODE_SHIFT (16) /* place it here to have on the same place as PCR_IRQC */
#define LWGPIO_INT_MODE_MASK (0x0F << LWGPIO_INT_MODE_SHIFT)
#define LWGPIO_INT_MODE(x) (((x) << LWGPIO_INT_MODE_SHIFT) & LWGPIO_INT_MODE_MASK)
#define LWGPIO_INT_MODE_FROM_ID(id) (((id) & LWGPIO_INT_MODE_MASK) >> LWGPIO_INT_MODE_SHIFT)

// /* Direction field definitions */
// #define LWGPIO_DIR_SHIFT (20)
// #define LWGPIO_DIR_MASK (0x01 << LWGPIO_DIR_SHIFT)

#define MUX_GPIO 0x0 /* GPIO is in Alternative 0 peripheral mode */

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_init
* Returned Value   : TRUE if succesfull, FALSE otherwise
* Comments         :
*    Decodes ID to HW specific struct and then performs pin initialization
*
*END*********************************************************************/
boolean lwgpio_init
(
    /* Pointer to LWGPIO internal structure to be filled in */
    LWGPIO_STRUCT_PTR handle,
    /* Pin ID, bitmask integer value */
    LWGPIO_PIN_ID     id,
    /* Direction to be set within initialization */
    LWGPIO_DIR        dir,
    /* Value to be set within initialization */
    LWGPIO_VALUE      value
)
{ /* Body */
    uint_32 port_idx, pin_idx, temp, ta, tb;
    PORT_MemMapPtr port_ptr;
    
    port_idx = LWGPIO_PORT_FROM_ID(id);
    pin_idx = LWGPIO_PIN_FROM_ID(id);
    handle->flags = id;
    handle->pcr_reg = (uint_32 *) pcr_reg_arr[port_idx] + pin_idx;
    handle->gpio_ptr = gpio_ptr_arr[port_idx];
    handle->pinmask = 1 << pin_idx;
    handle->iomuxc_reg = (uint_32 *)&IOMUXC_RGPIO(((port_idx << 5) + pin_idx));
    
    /* Set value prior to set to output */
    if (value != LWGPIO_VALUE_NOCHANGE) {
        /* Note: there is no check for values not defined as LWGPIO_VALUE enum */
        lwgpio_set_value(handle, value);
    }

    if (dir != LWGPIO_DIR_NOCHANGE) {
        /* Note: there is no check for values not defined as LWGPIO_DIR enum */
        lwgpio_set_direction(handle, dir);
    }

    return TRUE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_attribute
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    Sets attributes
*
*END*********************************************************************/
boolean lwgpio_set_attribute
(
    /* Pin handle to get function from */
    LWGPIO_STRUCT_PTR  handle,
    /* PORT attribute */
    uint_32 attribute_id,
    /* Attribute value */
    uint_32 value
)
{
    uint_32 temp = 0;
    switch (attribute_id) 
    {
        case(LWGPIO_ATTR_PULL_UP):
        {
            if (value == LWGPIO_AVAL_ENABLE)
            {
                /* select pull mode, enable pull mode */
                temp = *handle->iomuxc_reg;
                temp |= IOMUXC_SW_MUX_CTL_PAD_PAD_PUE(1) | IOMUXC_SW_MUX_CTL_PAD_PAD_PKE(1);
                /* if pull down resistor is selected, change to 47k pull up */
                if (!(temp & IOMUXC_SW_MUX_CTL_PAD_PAD_PUS_MASK))
                {
                    temp = IOMUXC_SW_MUX_CTL_PAD_PAD_PUS(1);
                }
                *handle->iomuxc_reg = temp;
            }
            else
            {
                *handle->iomuxc_reg &= ~IOMUXC_SW_MUX_CTL_PAD_PAD_PKE_MASK;
            }
            break;
        }
        case(LWGPIO_ATTR_PULL_DOWN):
        {
            if (value == LWGPIO_AVAL_ENABLE)
            {
                temp = *handle->iomuxc_reg;
                /* select 100k pull down resistor */
                temp &= ~(IOMUXC_SW_MUX_CTL_PAD_PAD_PUS_MASK);
                /* select pull mode, enable pull mode */
                temp |= IOMUXC_SW_MUX_CTL_PAD_PAD_PUE(1) | IOMUXC_SW_MUX_CTL_PAD_PAD_PKE(1);
                *handle->iomuxc_reg = temp;
            } 
            else 
            {
                *handle->iomuxc_reg &= ~IOMUXC_SW_MUX_CTL_PAD_PAD_PKE_MASK;
            }
            break;
        }
        case(LWGPIO_ATTR_SLEW_RATE):
        {
            if (value == LWGPIO_AVAL_SLEW_RATE_SLOW)
            {
                *handle->iomuxc_reg |= IOMUXC_SW_MUX_CTL_PAD_PAD_SRE(1);
            }
            else
            {
                *handle->iomuxc_reg &= ~(IOMUXC_SW_MUX_CTL_PAD_PAD_SRE(1));
            }
            break;
        }
        case(LWGPIO_ATTR_OPEN_DRAIN):
        {
            if (value == LWGPIO_AVAL_ENABLE)
            {
                *handle->iomuxc_reg |= IOMUXC_SW_MUX_CTL_PAD_ODE(1);
            }
            else
            {
                *handle->iomuxc_reg &= ~(IOMUXC_SW_MUX_CTL_PAD_ODE(1));
            }
            break;
        }
        case(LWGPIO_ATTR_DRIVE_STRENGTH):
        {
            *handle->pcr_reg = \
                (*handle->pcr_reg & (~IOMUXC_SW_MUX_CTL_PAD_PAD_DSE_MASK)) | \
                IOMUXC_SW_MUX_CTL_PAD_PAD_DSE(value);
            break;
        }
        default:
            return FALSE;
    }
    return TRUE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_functionality
* Returned Value   : void
* Comments         :
*    Sets functionality (peripheral mode) of the pin
*
*END*********************************************************************/
void lwgpio_set_functionality
(
    /* Pin handle to set function on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Function to be set (integer value) */
    uint_32            function
)
{
    *handle->iomuxc_reg &= ~IOMUXC_SW_MUX_CTL_PAD_PAD_MUX_MODE_MASK;
    *handle->iomuxc_reg |= IOMUXC_SW_MUX_CTL_PAD_PAD_MUX_MODE(function);
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_functionality
* Returned Value   : void
* Comments         :
*    Gets functionality (peripheral mode) of the pin
*
*END*********************************************************************/
uint_32 lwgpio_get_functionality
(
    /* Pin handle to get function from */
    LWGPIO_STRUCT_PTR  handle
)
{
    return (*handle->iomuxc_reg & IOMUXC_SW_MUX_CTL_PAD_PAD_MUX_MODE_MASK) >> IOMUXC_SW_MUX_CTL_PAD_PAD_MUX_MODE_SHIFT;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_direction
* Returned Value   : void
* Comments         :
*    Sets direction of the pin
*
*END*********************************************************************/
void lwgpio_set_direction
(
    /* Pin handle to set direction on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Direction to be set */
    LWGPIO_DIR         dir
)
{
    uint_32 temp;
    if (dir == LWGPIO_DIR_INPUT) {
        temp = *handle->iomuxc_reg;
        temp &= ~(IOMUXC_SW_MUX_CTL_PAD_PAD_OBE_MASK | IOMUXC_SW_MUX_CTL_PAD_PAD_DSE_MASK);
        temp |= IOMUXC_SW_MUX_CTL_PAD_PAD_IBE(1);
        *handle->iomuxc_reg = temp;
    }
    else if (dir == LWGPIO_DIR_OUTPUT) {
        temp = *handle->iomuxc_reg;
        temp &= ~(IOMUXC_SW_MUX_CTL_PAD_PAD_IBE_MASK);
        temp |= IOMUXC_SW_MUX_CTL_PAD_PAD_OBE(1);
        /* DSE disabled, set 1 - k150 */
        if (!(temp & IOMUXC_SW_MUX_CTL_PAD_PAD_DSE_MASK))
        {
            temp |= IOMUXC_SW_MUX_CTL_PAD_PAD_DSE(1);
        }
        *handle->iomuxc_reg = temp;
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_value
* Returned Value   : void
* Comments         :
*    Sets value (output latch) of the pin
*
*END*********************************************************************/
void lwgpio_set_value
(
    /* Pin handle to set value on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Direction to be set */
    LWGPIO_VALUE       out_value
)
{
    if (out_value == LWGPIO_VALUE_LOW) {
        handle->gpio_ptr->PDOR &= ~handle->pinmask;
    }
    else if (out_value == LWGPIO_VALUE_HIGH) {
        handle->gpio_ptr->PDOR |= handle->pinmask;
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_toggle_value
* Returned Value   : void
* Comments         :
*    Toggles value of output latch of the pin
*
*END*********************************************************************/
void lwgpio_toggle_value
(
    /* Pin handle to toggle value on */
    LWGPIO_STRUCT_PTR  handle
)
{
    handle->gpio_ptr->PTOR = handle->pinmask;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_value
* Returned Value   : LWGPIO_VALUE of pin status
* Comments         :
*    Returns value (output latch or read data) of the pin
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_value
(
    /* Pin handle to get value from */
    LWGPIO_STRUCT_PTR  handle
)
{
    uint_32 temp = IOMUXC_SW_MUX_CTL_PAD_PAD_IBE_MASK;
    /* if the pin is set to input */
    // TODO: temp is used as workaround, otherwise compiler will use ldrh/ldrb instruction and cause unhandled interrupt
    if ((uint_32)(*handle->iomuxc_reg) & temp)
       return (handle->gpio_ptr->PDIR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
    /* if the pin is set to output */
    temp = IOMUXC_SW_MUX_CTL_PAD_PAD_OBE_MASK;
    if ((*handle->iomuxc_reg) & temp)
       return (handle->gpio_ptr->PDOR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
    
    return (handle->gpio_ptr->PDIR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_raw
* Returned Value   : LWGPIO_VALUE of pin status
* Comments         :
*    Returns read level of the pin
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_raw
(
    /* Pin handle to get value from */
    LWGPIO_STRUCT_PTR  handle
)
{
    return (handle->gpio_ptr->PDIR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_init
* Returned Value   : TRUE if succesfull, FALSE otherwise
* Comments         :
*    Initializes pin to generate interrupt
*
*END*********************************************************************/
boolean lwgpio_int_init
(
    /* Pin handle to initialize interrupt on */
    LWGPIO_STRUCT_PTR handle,
    /* Interrupt mode */
    LWGPIO_INT_MODE   mode
)
{ /* Body */
    /*
    Settings of PORT_PCR_IRQC according mode:
    PORT_PCR_IRQC | LOW | HIGH | FALLING | RISING | mode
    ----------------------------------------------------
               0  |   0 |    0 |       0 |      0 |    0
     0x08 + 0x01  |   0 |    0 |       0 |      1 |    1
     0x08 + 0x02  |   0 |    0 |       1 |      0 |    2
     0x08 + 0x03  |   0 |    0 |       1 |      1 |    3
     0x08 + 0x04  |   0 |    1 |       0 |      0 |    4
     unsupported  |   0 |    1 |       0 |      1 |    5
     unsupported  |   0 |    1 |       1 |      0 |    6
     unsupported  |   0 |    1 |       1 |      1 |    7
     0x08 + 0x00  |   1 |    0 |       0 |      0 |    8
     unsupported  |   1 |    0 |       0 |      1 |    9
     unsupported  |   1 |    0 |       1 |      0 |   10
     unsupported  |   1 |    0 |       1 |      1 |   11
     unsupported  |   1 |    1 |       0 |      0 |   12
     unsupported  |   1 |    1 |       0 |      1 |   13
     unsupported  |   1 |    1 |       1 |      0 |   14
     unsupported  |   1 |    1 |       1 |      1 |   15
    */

     if (mode > 4 && mode != LWGPIO_INT_MODE_LOW)
         return FALSE;
     
     if (mode) {
         /* Store mode value and use it when enabling interrupt */
         handle->flags &= ~LWGPIO_INT_MODE_MASK;
         handle->flags |= LWGPIO_INT_MODE(0x08 | mode & 0x07); /* see PCR_IRQC register field definition */
     }

    return TRUE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_enable
* Returned Value   : void
* Comments         :
*    Enables / disables interrupts for specified pin
*
*END*********************************************************************/
void lwgpio_int_enable
(
    /* Pin handle to enable interrupt on */
    LWGPIO_STRUCT_PTR handle,
    /* Enable or disable interrupt? TRUE = enable */
    boolean           ena
)
{ /* Body */
     if (ena) {
         /* enable pin interrupts */
         *handle->pcr_reg &= ~PORT_PCR_IRQC_MASK;
         *handle->pcr_reg |= handle->flags & PORT_PCR_IRQC_MASK; /* the IRQ mode flags are on the same place as PCR_IRQC */
     }
     else {
         /* disable pin interrupts */
         *handle->pcr_reg &= ~PORT_PCR_IRQC_MASK;
     }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_get_flag
* Returned Value   : TRUE if interrupt flag is set
* Comments         :
*    Checks if there is pending interrupt flag for specified pin
*
*END*********************************************************************/
boolean lwgpio_int_get_flag
(
    /* Pin handle to get interrupt flag on */
    LWGPIO_STRUCT_PTR handle
)
{ /* Body */
    return (*handle->pcr_reg & PORT_PCR_ISF_MASK) ? TRUE : FALSE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_clear_flag
* Returned Value   : void
* Comments         :
*    Clears pending interrupt flag on peripheral
*
*END*********************************************************************/
void lwgpio_int_clear_flag
(
    /* Pin handle to clear interrupt flag on */
    LWGPIO_STRUCT_PTR handle
)
{ /* Body */
    /* Clear interrupt flag. Note that if an interrupt was acknowledged by NVIC,
    it will generate interrupt anyway. Interrupts on NVIC are grouped for each
    port */
    *handle->pcr_reg |= PORT_PCR_ISF_MASK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_gpio_base_address
* Returned Value   : pointer to base of GPIO registers
* Comments         :
*    This function returns base address of GPIO related register space.
*
*END*********************************************************************/
uint_32 lwgpio_int_get_vector
(
    /* Pin handle to get vector of */
    LWGPIO_STRUCT_PTR  handle
)
{
#if PSP_MQX_CPU_IS_VYBRID_A5
	// return GIC ID
	return 155 + LWGPIO_PORT_FROM_ID(handle->flags);
#elif PSP_MQX_CPU_IS_VYBRID_M4
	// return CM4 VECTOR
	return 123 + LWGPIO_PORT_FROM_ID(handle->flags);
#else
	#error "Unsupported core"
#endif
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/host_ch9.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_ch9.c$
* $Version : 3.8.23.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains standard device requests (USB Chapter 9)
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_ch9.h"
#include "host_main.h"
#include "host_dev_list.h"

/* Prototype, copy to stack frames for each use instance */

static const USB_SETUP req_prototype = 
{
   0,          /* request type */ 
   0,          /* request */
   {0,0},      /* WVALUE  */
   {0,0},      /* WINDEX  */
   {0,0}       /* WLENGTH  */
};

/* Unpublished functions, not intended for application use */
static void  usb_host_cntrl_transaction_done(_usb_pipe_handle, pointer, uchar_ptr, uint_32, USB_STATUS);

static USB_STATUS  usb_host_ch9_dev_req(_usb_device_instance_handle, USB_SETUP_PTR, uchar_ptr);
 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_cntrl_transaction_done
* Returned Value : none
* Comments       :
*     Callback function to process transaction-done events
*     State machine for enumeration/subsequent transactions
*     Between states, the 8-byte buffer in device_instance
*        is used to save the first part of the configuration.
*     Pointer desc in various flavors (uchar_ptr, cfig_ptr)
*        is used to parse this buffer in various ways. 
* 
*END*--------------------------------------------------------------------*/
static void  usb_host_cntrl_transaction_done
   (
      /* [IN] the pipe handle */
      _usb_pipe_handle  handle,

      /* [IN] The user parameter */
      pointer           user_parm,

      /* [IN] the buffer */
      uchar_ptr         buffer,

      /* [IN] The length of the transfer */
      uint_32           length,

      /* [IN] status of the transfer */
      USB_STATUS        status
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
   PIPE_STRUCT_PTR            pipe_ptr = (PIPE_STRUCT_PTR)handle;
   DEV_INSTANCE_PTR           dev_inst_ptr = (DEV_INSTANCE_PTR)pipe_ptr->DEV_INSTANCE;
   DESCRIPTOR_UNION           desc;
   int_32                     config_size;
   DEV_MEMORY_PTR             dev_mem;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_cntrl_transaction_done");
   #endif

   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)dev_inst_ptr->host;

   switch (status) {
      case USB_OK:
         dev_inst_ptr->ctrl_retries = USBCFG_CTRL_RETRY;
         break;

      case USBERR_TR_FAILED:
         if (buffer != NULL) {
            dev_inst_ptr->ctrl_retries--;
            if (dev_inst_ptr->ctrl_retries) {
               if (dev_inst_ptr->state == DEVSTATE_DEVDESC8) {
                  /* dont jump to DEVSTATE_INITIAL state, get descriptor instead */
                  status = _usb_host_ch9_get_descriptor((_usb_device_instance_handle)dev_inst_ptr,
                     USB_DESC_TYPE_DEV << 8, 0, 8, 
                     (uchar_ptr)buffer);
                  return;
               }
               else {
                  dev_inst_ptr->state--; /* back to previous enum state */
                  status = USB_OK;
                  //_time_delay(100);
               }
            }
         } else
            dev_inst_ptr->state = DEVSTATE_INITIAL;
         break;

      case USBERR_ENDPOINT_STALLED:
         dev_inst_ptr->ctrl_retries--;
         if (dev_inst_ptr->ctrl_retries) {
            status = _usb_host_ch9_clear_feature((_usb_device_instance_handle)dev_inst_ptr, REQ_TYPE_ENDPOINT, 0, ENDPOINT_HALT);
            if (status == USB_OK) {
                //_time_delay(100);
			}
         }
         break;

      default:
         dev_inst_ptr->state = DEVSTATE_INITIAL;
         break;
   }

   if (status != USB_OK)
      return;

   /*----------------------------------------------------**
   ** Enumeration state machine -- cases are named after **
   ** the just-completed transactions.                   **
   **----------------------------------------------------*/
   
   switch (dev_inst_ptr->state) {
      case DEVSTATE_INITIAL:      /* initial device state = forever error state */
         break;   
      case DEVSTATE_DEVDESC8:     /* device descriptor [0..7]*/
         /* We must have received the first 8 bytes in 
         ** dev_inst_ptr->dev_descriptor which contains the 
         ** max packet size for this control endpoint 
         */
         pipe_ptr->MAX_PACKET_SIZE = 
            dev_inst_ptr->dev_descriptor.bMaxPacketSize;
            
         /* Notify device driver of MaxPacketSize0 for this device */
         status = _usb_host_update_max_packet_size_call_interface (usb_host_ptr, pipe_ptr);
         
         if (status != USB_OK)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }
         else
         {
            dev_inst_ptr->state = DEVSTATE_ADDR_SET;
         }

         /* Now set the address that we assigned when we initialized 
         ** the device instance struct for this device 
         */
         status = _usb_host_ch9_set_address((_usb_device_instance_handle)dev_inst_ptr);
         
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;
      case DEVSTATE_ADDR_SET:     /* address set */
         pipe_ptr->DEVICE_ADDRESS = dev_inst_ptr->address;
         
         /* Notify device driver of USB device's new address */
         status = _usb_host_update_device_address_call_interface (usb_host_ptr, pipe_ptr);
         
         if (status != USB_OK)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         dev_inst_ptr->state = DEVSTATE_DEV_DESC;

         /* Now get the full descriptor */
         status = _usb_host_ch9_get_descriptor((_usb_device_instance_handle)dev_inst_ptr,
            USB_DESC_TYPE_DEV << 8, 
            0, 
            USB_DESC_LEN_DEV,
            (uchar_ptr)&dev_inst_ptr->dev_descriptor);
            
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;   
      case DEVSTATE_DEV_DESC:     /* full device descriptor received */
         /* Now lets get the first 9 bytes of the configuration descriptor 
         */
         desc.pntr = &dev_inst_ptr->buffer;
         dev_inst_ptr->state = DEVSTATE_GET_CFG9;
         status = _usb_host_ch9_get_descriptor((_usb_device_instance_handle)dev_inst_ptr,
            USB_DESC_TYPE_CFG << 8 | dev_inst_ptr->cfg_value, 
            0, 
            sizeof(dev_inst_ptr->buffer),
            desc.bufr);
            
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;
      case DEVSTATE_GET_CFG9:     /* Read 9 bytes of config descriptor */
         dev_inst_ptr->state = DEVSTATE_SET_CFG;
         /* Now select the configuration as specified in the 
         ** descriptor 
         */
         desc.cfig = (CONFIGURATION_DESCRIPTOR_PTR)dev_inst_ptr->buffer;
         config_size = SHORT_UNALIGNED_LE_TO_HOST(desc.cfig->wTotalLength);

         desc.pntr = &dev_inst_ptr->buffer;
         if (USB_OK != usb_dev_list_get_mem(dev_inst_ptr,
            config_size,
            USB_MEMTYPE_CONFIG,
            1,
            &dev_mem))
         {
            #ifdef _HOST_DEBUG_
               DEBUG_LOG_TRACE("usb_host_cntrl_transaction_done");
            #endif
            return;
         }
         /* Move the pointer to the aligned payload */
         desc.pntr = dev_mem->payload.data + dev_mem->offset;
         
#ifdef __USB_OTG__
         dev_inst_ptr->state = DEVSTATE_CHK_OTG;
#else
         dev_inst_ptr->state = DEVSTATE_SET_CFG;
#endif
         /* We can only read one config descriptor at a time */
         status = _usb_host_ch9_get_descriptor((_usb_device_instance_handle)dev_inst_ptr,
            (USB_DESC_TYPE_CFG << 8) | dev_inst_ptr->cfg_value, 
            0, 
            (uint_16)config_size,
            desc.bufr);
            
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;   

      case DEVSTATE_CHK_OTG:
         /* Point to the memory owned by this device */
         /* FIXME: it is presumed that memlist points to the config descriptor */
         desc.pntr = dev_inst_ptr->memlist->payload.data + dev_inst_ptr->memlist->offset;

         /* We will always start with config desc so update the search pointer */
         config_size = SHORT_UNALIGNED_LE_TO_HOST(desc.cfig->wTotalLength);
         config_size -= desc.cfig->bLength;
         desc.word += desc.cfig->bLength;

         while (config_size) {
            if (desc.otg->bDescriptorType == USB_DESC_TYPE_OTG) {
               /* Found the OTG descriptor */
               break;
            } /* Endif */
            config_size -= desc.intf->bLength;
            desc.word += desc.intf->bLength;
         } /* EndWhile */

         /* Check for an OTG descriptor */
         dev_inst_ptr->state = DEVSTATE_SET_CFG;

         if (config_size && desc.otg->bDescriptorType == USB_DESC_TYPE_OTG &&
            (desc.otg->bmAttributes & OTG_HNP_SUPPORT))
         {
            status = _usb_host_ch9_set_feature(dev_inst_ptr, 0, 0, 4);
            
            if (status != USB_STATUS_TRANSFER_QUEUED)
            {
               dev_inst_ptr->state = DEVSTATE_INITIAL;
               break;
            }
            else
            {
               break;
            }

         } /* Endif */

         /* Fall through */

      case DEVSTATE_SET_CFG:     /* config descriptor [0..8] */

         /* Point to the memory owned by this device */
         /* FIXME: it is presumed that memlist points to the config descriptor */
         desc.pntr = dev_inst_ptr->memlist->payload.data + dev_inst_ptr->memlist->offset;

         dev_inst_ptr->state = DEVSTATE_CFG_READ;
         dev_inst_ptr->cfg_value = desc.cfig->bConfigurationValue;
         status = _usb_host_ch9_set_configuration(dev_inst_ptr, dev_inst_ptr->cfg_value);
            
         if (status != USB_STATUS_TRANSFER_QUEUED)
         {
            dev_inst_ptr->state = DEVSTATE_INITIAL;
            break;
         }

         break;   

      case DEVSTATE_CFG_READ:     /* full config desc. read in */
         dev_inst_ptr->state = DEVSTATE_APP_CALL;

         /* Scan the configuration descriptor to find out the total 
         ** number of interfaces available. This will be the upper 
         ** bound for searching through the interface descriptors' 
         ** array
         */
         dev_inst_ptr->num_of_interfaces = 0;

         /* Point to the memory owned by this device */
         /* FIXME: it is presumed that memlist points to the config descriptor */
         desc.pntr = dev_inst_ptr->memlist->payload.data + dev_inst_ptr->memlist->offset;

         /* We will always start with config desc so update the search pointer */
         config_size = SHORT_UNALIGNED_LE_TO_HOST(desc.cfig->wTotalLength);
         config_size -= desc.cfig->bLength;
         desc.word += desc.cfig->bLength;
         
         while (config_size > 0) {
            if (desc.intf->bDescriptorType == USB_DESC_TYPE_IF) {
               /* Found an interface */
               dev_inst_ptr->num_of_interfaces++;
            } /* Endif */
            if (desc.intf->bLength) {
               config_size -= desc.intf->bLength;
               desc.word += desc.intf->bLength;
            } else {
               /* Zero-sized interface found */
               status = USBERR_INVALID_CFIG_NUM;
               break;
            }
         } /* EndWhile */
         if (config_size < 0) {
            /* Error: we have not read the configuration descriptor properly,
            ** some part is missing. Symptom: there is not config descriptor
            ** info left for latest descriptor.
            */
            status = USBERR_INVALID_CFIG_NUM;
         }
         if (status == USBERR_INVALID_CFIG_NUM) {
            /* TODO: Remove config descriptor from memlist and try to re-read. */
            break;
         }

         /* Don't select an interface here. The device driver will 
         ** select the interface 
         */

      case DEVSTATE_APP_CALL:     /* full config desc. read in */
         dev_inst_ptr->state = DEVSTATE_SET_INTF;
         if (dev_inst_ptr->new_config != 0) {
            /* We have just read a new configuration descriptor */
            dev_inst_ptr->new_config = 0;
            usb_hostdev_attach_detach(dev_inst_ptr, USB_CONFIG_EVENT);
         } else {
            usb_hostdev_attach_detach(dev_inst_ptr, USB_ATTACH_EVENT);
         } /* EndIf */
         break;

      case DEVSTATE_SET_INTF:    /* Select interface done */
         dev_inst_ptr->state = DEVSTATE_ENUM_OK;
         usb_hostdev_attach_detach(dev_inst_ptr, USB_INTF_EVENT);
         break;
      default:
         dev_inst_ptr->state = DEVSTATE_ENUM_OK;
         case DEVSTATE_ENUM_OK:   /* enumeration complete */
            if ((dev_inst_ptr->control_callback != NULL))
               dev_inst_ptr->control_callback
                  (handle,
                  user_parm,
                  buffer,
                  length,
                  status);
            break;   
      } /* EndSwitch */

   #ifdef _HOST_DEBUG_
   if (dev_inst_ptr->state == DEVSTATE_INITIAL)
   {
      DEBUG_LOG_TRACE("usb_host_cntrl_transaction_done FAILED");
   }
   else
   {
      DEBUG_LOG_TRACE("usb_host_cntrl_transaction_done SUCCESSFUL");
   }
   #endif
      
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_register_ch9_callback
* Returned Value : USB_OK, or error status
* Comments       :
*     This function registers a callback function that will be called 
*  to notify the user of a ch9 command completion. This should be used 
*  only after enumeration is completed
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_register_ch9_callback
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* Callback upon completion */
      tr_callback                   callback,

      /* User provided callback param */
      pointer                       callback_param
   )
{ /* Body */
   DEV_INSTANCE_PTR           dev_inst_ptr;
   USB_STATUS                 error;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_register_ch9_callback");
   #endif
   /* Verify that device handle is valid */
   USB_lock();   
   error = usb_hostdev_validate(dev_handle);

   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_register_ch9_callback, device not found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */
     
   dev_inst_ptr = (DEV_INSTANCE_PTR)dev_handle;

   /* This will be called if the device is already enumerated */
   dev_inst_ptr->control_callback = callback;
   dev_inst_ptr->control_callback_param = callback_param;

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_register_ch9_callback, SUCCESSFUL");
   #endif
   return USB_OK;

} /* EndBody */
    
    
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_ch9_dev_req
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device requests in Chapter 9.
*        See Table 9-3 p. 250 of USB 2.0 specification.
*     This code does minimal error checking, on the assumption
*        that it is called only from wrappers in this file.
*     It is presumed that this function is called with USB interrupts disabled
* 
*END*--------------------------------------------------------------------*/
static USB_STATUS  usb_host_ch9_dev_req
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,
         
      /* Device Request to send */
      USB_SETUP_PTR                 devreq_ptr,
         
      /* buffer to send/receive */
      uchar_ptr                     buff_ptr
   )
{ /* Body */
   DEV_INSTANCE_PTR           dev_ptr;
   _usb_pipe_handle           pipe_handle;
   TR_INIT_PARAM_STRUCT       tr;
   USB_STATUS                 error;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_ch9_dev_req");
   #endif
   
   /* Verify that device handle is valid */
   error = usb_hostdev_validate(dev_handle);

   if (error != USB_OK) 
   {

      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_ch9_dev_req device not found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */
     
   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;
   pipe_handle = dev_ptr->control_pipe;

   /* Initialize the TR with TR index and default control callback 
   ** function if there is one registered 
   */
   usb_hostdev_tr_init(&tr, dev_ptr->control_callback, dev_ptr->control_callback_param);
   
   /* Set buffer length if required */
   switch (devreq_ptr->BREQUEST) {
      case REQ_SET_DESCRIPTOR:
         tr.G.TX_BUFFER = buff_ptr;
         tr.G.TX_LENGTH = SHORT_UNALIGNED_LE_TO_HOST(devreq_ptr->WLENGTH);
         break;
      case REQ_GET_CONFIGURATION:
      case REQ_GET_DESCRIPTOR:
      case REQ_GET_INTERFACE:
      case REQ_GET_STATUS:
      case REQ_SYNCH_FRAME:
         tr.G.RX_BUFFER = buff_ptr;
         tr.G.RX_LENGTH = SHORT_UNALIGNED_LE_TO_HOST(devreq_ptr->WLENGTH);
         break;
   } /* EndSwitch */

   tr.DEV_REQ_PTR = (uchar_ptr)devreq_ptr;

   if ((dev_ptr->state < DEVSTATE_ENUM_OK) ||
      (tr.G.CALLBACK == NULL))
   {
      tr.G.CALLBACK = usb_host_cntrl_transaction_done;
      tr.G.CALLBACK_PARAM = NULL;
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_ch9_dev_req SUCCESSFUL");
   #endif
   error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr);
   
   return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_clear_feature
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_clear_feature
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* request type device/interface/endpoint */
      uint_8                        req_type,

      /* device = 0, or interface/endpoint */
      uint_8                        intf_endpt,

      /* feature selection */
      uint_16                       feature
   )
{ /* Body */

   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_clear_feature");
   #endif

   USB_lock();
   
   switch (req_type) {
      case REQ_TYPE_DEVICE:
         break;
      case REQ_TYPE_INTERFACE:
      case REQ_TYPE_ENDPOINT:
         *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(intf_endpt);
         break;
      default:
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_ch9_clear_feature, invalid request");
         #endif
         return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_BMREQ_TYPE);
   } /* EndSwitch */

   request.BMREQUESTTYPE = (uchar)(req_type | REQ_TYPE_OUT);
   request.BREQUEST = REQ_CLEAR_FEATURE;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT(feature);

   error = usb_host_ch9_dev_req(dev_handle, &request, NULL);

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_clear_feature, SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_get_configuration
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_get_configuration
   (
      /* [IN] usb device */
      _usb_device_instance_handle   dev_handle,

      /* [OUT] configuration value */
      uchar_ptr                     buffer
   )
{ /* Body */

   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_get_configuration");
   #endif
   
   USB_lock();

   request.BMREQUESTTYPE = REQ_TYPE_DEVICE | REQ_TYPE_IN;
   request.BREQUEST = REQ_GET_CONFIGURATION;
   *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT_CONST(1);

   error = usb_host_ch9_dev_req(dev_handle, &request, buffer);

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_get_configuration, SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_get_descriptor
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_get_descriptor
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,
      /* descriptor type & index */
      uint_16                       type_index,
      /* Language ID or 0 */
      uint_16                       lang_id,
      /* buffer length */
      uint_16                       buflen,         
      /* descriptor buffer */
      uchar_ptr                     buffer
   )
{ /* Body */

   USB_SETUP  request;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_get_descriptor");
   #endif

   USB_lock();

   request.BMREQUESTTYPE = REQ_TYPE_DEVICE | REQ_TYPE_IN;
   request.BREQUEST = REQ_GET_DESCRIPTOR;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT(type_index);
   *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(lang_id);
   *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT(buflen);

   error = usb_host_ch9_dev_req(dev_handle, &request, buffer);

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_get_descriptor, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_get_interface
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_get_interface
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* interface index */
      uint_8            interface,

      /* alternate setting buffer */
      uchar_ptr         buffer
   )
{ /* Body */

   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_get_interface");
   #endif

   USB_lock();

   request.BMREQUESTTYPE = REQ_TYPE_INTERFACE | REQ_TYPE_IN;
   request.BREQUEST = REQ_GET_INTERFACE;
   *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(interface);
   *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT_CONST(1);

   error = usb_host_ch9_dev_req(dev_handle, &request, buffer);

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_get_interface, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_get_status
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_get_status
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* request type device/interface/endpoint */
      uint_8            req_type,

      /* device = 0, or interface/endpoint */
      uint_8            intf_endpt,

      /* returned status */
      uchar_ptr         buffer
   )
{ /* Body */

   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_get_status");
   #endif

   USB_lock();

   switch (req_type) {
      case REQ_TYPE_DEVICE:
      case REQ_TYPE_INTERFACE:
      case REQ_TYPE_ENDPOINT:
         break;
      default:
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_ch9_get_status, invalid parameter");
         #endif
         return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_BMREQ_TYPE);
   } /* EndSwitch */

   request.BMREQUESTTYPE = (uchar)(req_type | REQ_TYPE_IN);
   request.BREQUEST = REQ_GET_STATUS;
   *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(intf_endpt);
   *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT_CONST(2);

   error = usb_host_ch9_dev_req(dev_handle, &request, buffer);
   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_get_status, SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_set_address
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_set_address
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle
   )
{ /* Body */

   DEV_INSTANCE_PTR  dev_ptr = (DEV_INSTANCE_PTR)dev_handle;
   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_address");
   #endif

   USB_lock();

   request.BMREQUESTTYPE = REQ_TYPE_DEVICE | REQ_TYPE_OUT;
   request.BREQUEST = REQ_SET_ADDRESS;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT(dev_ptr->address);

   error = usb_host_ch9_dev_req(dev_handle, &request, NULL);

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_address,SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_set_configuration
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_set_configuration
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* configuration value */
      uint_16                       config
   )
{ /* Body */

   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_configuration");
   #endif

   USB_lock();

   request.BMREQUESTTYPE = REQ_TYPE_DEVICE | REQ_TYPE_OUT;
   request.BREQUEST = REQ_SET_CONFIGURATION;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT(config);

   error = usb_host_ch9_dev_req(dev_handle, &request, NULL);

   USB_unlock();
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_configuration SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_set_descriptor
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_set_descriptor
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* descriptor type & index */
      uint_16           type_index,

      /* Language ID or 0 */
      uint_16           lang_id,

      /* buffer length */
      uint_16           buflen,         

      /* descriptor buffer */
      uchar_ptr         buffer
   )
{ /* Body */

   USB_SETUP  request;
   USB_STATUS error = USB_OK;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_descriptor");
   #endif

   USB_lock();

   request.BMREQUESTTYPE = REQ_TYPE_DEVICE | REQ_TYPE_OUT;
   request.BREQUEST = REQ_SET_DESCRIPTOR;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT(type_index);
   *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(lang_id);
   *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT(buflen);

   error = usb_host_ch9_dev_req(dev_handle, &request, buffer);

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_descriptor SUCCESSFUL");
   #endif

   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_set_feature
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_set_feature
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* request type device/interface/endpoint */
      uint_8            req_type,

      /* device = 0, or interface/endpoint */
      uint_8            intf_endpt,

      /* feature selection */
      uint_16           feature
   )
{ /* Body */

   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_feature");
   #endif

   USB_lock();
   switch (req_type) {
      case REQ_TYPE_DEVICE:
         break;
      case REQ_TYPE_INTERFACE:
      case REQ_TYPE_ENDPOINT:
         *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(intf_endpt);
         break;
      default:
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_ch9_set_feature, invalid param");
         #endif
         return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_BMREQ_TYPE);
   } /* EndSwitch */

   request.BMREQUESTTYPE = (uchar)(req_type | REQ_TYPE_OUT);
   request.BREQUEST = REQ_SET_FEATURE;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT(feature);

   error = usb_host_ch9_dev_req(dev_handle, &request, NULL);

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_feature, SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_set_interface
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_set_interface
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* alternate setting */
      uint_8            alternate,

      /* interface */
      uint_8            intf
   )
{ /* Body */

   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_interface");
   #endif

   USB_lock();   

   request.BMREQUESTTYPE = REQ_TYPE_INTERFACE | REQ_TYPE_OUT;
   request.BREQUEST = REQ_SET_INTERFACE;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT(alternate);
   *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(intf);

   error = usb_host_ch9_dev_req(dev_handle, &request, NULL);

   USB_unlock();
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_set_interface, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_ch9_synch_frame
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device request in Chapter 9.
*     See Table 9-3 p. 250 of USB 2.0 specification.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_ch9_synch_frame
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* interface index */
      uint_8            interface,

      /* configuration buffer */
      uchar_ptr         buffer
   )
{ /* Body */

   USB_SETUP  request = req_prototype;
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_synch_frame");
   #endif

   USB_lock();

   request.BMREQUESTTYPE = REQ_TYPE_ENDPOINT | REQ_TYPE_IN;
   request.BREQUEST = REQ_SYNCH_FRAME;
   *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(interface);
   *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT_CONST(2);

   error = usb_host_ch9_dev_req(dev_handle, &request, buffer);

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_ch9_synch_frame, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_hostdev_cntrl_request
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process class- or vendor-specific control pipe device
*     requests.
*
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_hostdev_cntrl_request
   (
      /* usb device */
      _usb_device_instance_handle   dev_handle,

      /* Device Request to send */
      USB_SETUP_PTR                 devreq,

      /* buffer to send/receive */
      uchar_ptr                     buff_ptr,

      /* callback upon completion */
      tr_callback                   callback,

      /* [IN] the parameter to pass back to the callback function */
      pointer                       callback_param
   )
{ /* Body */

   DEV_INSTANCE_PTR           dev_ptr;
   _usb_pipe_handle           pipe_handle;
   TR_INIT_PARAM_STRUCT       tr;
   USB_STATUS                 error = USB_OK;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request");
   #endif
   
   /* Verify that device handle is valid */
   USB_lock();
   error = usb_hostdev_validate(dev_handle);

   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, invalid device handle");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */
      

   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;

   if (dev_ptr->state < DEVSTATE_ENUM_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, no device found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */

   pipe_handle = dev_ptr->control_pipe;

   usb_hostdev_tr_init(&tr, callback, callback_param);

   /* Set TR buffer length as required */
   if ((REQ_TYPE_IN & devreq->BMREQUESTTYPE) != 0) {
      tr.G.RX_BUFFER = buff_ptr;
      tr.G.RX_LENGTH = SHORT_UNALIGNED_LE_TO_HOST(devreq->WLENGTH);
   } else {
      tr.G.TX_BUFFER = buff_ptr;
      tr.G.TX_LENGTH = SHORT_UNALIGNED_LE_TO_HOST(devreq->WLENGTH);
   } /* EndIf */

   tr.DEV_REQ_PTR = (uchar_ptr)devreq;

   error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr);

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request,SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_handle.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_handle.c$
* $Version : 3.8.12.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains functions related to using file handles.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Get_handle
* Returned Value   :  a file handle
* Comments  :
*    Creates a new file handle and adds it the to queue of open handles.
*
*END*---------------------------------------------------------------------*/

MFS_HANDLE_PTR MFS_Get_handle
    (
    MFS_DRIVE_STRUCT_PTR   drive_ptr,       /*[IN] the drive on which to operate */
    MFS_DIR_ENTRY_PTR      dir_entry_ptr    /* [IN] pointer to the directory information for this file handle */
    )
{
    MFS_HANDLE_PTR    handle_ptr;

    handle_ptr = _partition_alloc_system_zero( drive_ptr->HANDLE_PARTITION );

    /*
    ** initialize the handle
    */
    if ( handle_ptr != NULL )
    {

        _queue_enqueue( &drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) handle_ptr);

        handle_ptr->VALID = MFS_VALID;

        if ( dir_entry_ptr )
        {
            _mem_copy(dir_entry_ptr, &handle_ptr->DIR_ENTRY,sizeof(MFS_DIR_ENTRY));
        }
    }
    return(handle_ptr);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Free_handle
* Returned Value   :  none
* Comments  :
*      Add the handle to the freelist of handles kept in the configuration
*       data.
*END*---------------------------------------------------------------------*/

void MFS_Free_handle
    (
    MFS_DRIVE_STRUCT_PTR      drive_ptr,    /*[IN] the drive on which to operate */
    MFS_HANDLE_PTR            handle_ptr    /*[IN] handle to be released */
    )
{
    if ( handle_ptr != NULL )
    {
        /* Unlink handle from HANDLE_LIST */
        _queue_unlink( &drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) handle_ptr);

        /* clear out the handle and add to the freelist */
        handle_ptr->VALID = ~handle_ptr->VALID;
        _partition_free(handle_ptr);
    }

}  



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Find_handle
* Returned Value   :  void
* Comments  :
*
*END*---------------------------------------------------------------------*/

MFS_HANDLE_PTR MFS_Find_handle
    (
    MFS_DRIVE_STRUCT_PTR   drive_ptr,    /*[IN] the drive on which to operate */
    uint_32                dir_cluster,
    uint_32                dir_index
    )
{
   MFS_HANDLE_PTR   next_handle;

    next_handle = (MFS_HANDLE_PTR) _queue_head(&(drive_ptr->HANDLE_LIST));
    while ( next_handle )
    {
        if ((next_handle->DIR_CLUSTER == dir_cluster) && (next_handle->DIR_INDEX == dir_index))  
        {
            break;
        }
        next_handle = (MFS_HANDLE_PTR) _queue_next(&drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) next_handle);
    }  
    return next_handle;
}  


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/soip.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: soip.c$
* $Version : 3.8.4.0$
* $Date    : Oct-1-2012$
*
* Comments:
*
*   This file contains the implementation of getsockopt()
*   and setsockopt() at the SOL_IP level.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"

#define RTCS_ENTER(f,a) RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_IP_ ## f, a)

#define RTCS_EXIT(f,a)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_IP_ ## f, a); \
                        return a


uint_32 SOL_IP_getsockopt  (uint_32, uint_32, uint_32, pointer, uint_32 _PTR_);
uint_32 SOL_IP_setsockopt  (uint_32, uint_32, uint_32, pointer, uint_32);

const RTCS_SOCKOPT_CALL_STRUCT SOL_IP_CALL = {
   SOL_IP_getsockopt,
   SOL_IP_setsockopt
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_IP_getsockopt
* Returned Value  : error code
* Comments  :  Obtain the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_IP_getsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] buffer for the current value of the option */
      uint_32  _PTR_ optlen
         /* [IN/OUT] length of the option value, in bytes */
   )
{ /* Body */
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;
   uint_32                       error;

   RTCS_ENTER(GETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   switch (optname) {

      case RTCS_SO_IP_RX_DEST:
         if (*optlen < sizeof(_ip_address)) {
            RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION);
         } /* Endif */

         *(_ip_address _PTR_)optval = socket_ptr->LINK_OPTIONS.RX.DEST;
         *optlen = sizeof(_ip_address);
         break;

      case RTCS_SO_IP_RX_TTL:
         if (!*optlen) {
            RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION);
         } /* Endif */

         *(uchar_ptr)optval = socket_ptr->LINK_OPTIONS.RX.TTL;
         *optlen = sizeof(uchar);
         break;

/* Start CR 1146 */
      case RTCS_SO_IP_TX_TTL:
         if (!*optlen) {
            RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION);
         } /* Endif */

         *(uchar_ptr)optval = socket_ptr->LINK_OPTIONS.TX.TTL;
         *optlen = sizeof(uchar);
         break;
/* End CR 1146 */

/* Start CR 9999-7 */
      case RTCS_SO_IP_LOCAL_ADDR:
         if (*optlen < sizeof(_ip_address)) {
            RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION);
         } /* Endif */

         if ( socket_ptr->TCB_PTR != NULL)  {
            *(_ip_address _PTR_)optval = socket_ptr->TCB_PTR->local_host;   
         } else  {
            *(_ip_address _PTR_)optval = 0;
         }
         *optlen = sizeof(_ip_address);
         break;
/* End CR 9999-7 */

      case RTCS_SO_IP_RX_TOS:
         if (!*optlen) {
            RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION);
         } /* Endif */

         *(uchar_ptr)optval = socket_ptr->LINK_OPTIONS.RX.TOS;
         *optlen = sizeof(uchar);
         break;

      case RTCS_SO_IP_TX_TOS:
         if (!*optlen) {
            RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_SHORT_OPTION);
         } /* Endif */

         *(uchar_ptr)optval = socket_ptr->LINK_OPTIONS.TX.TOS;
         *optlen = sizeof(uchar);
         break;         
         
       default:
         error = RTCSERR_SOCK_INVALID_OPTION;
      } /* Endswitch */

   RTCS_EXIT(GETSOCKOPT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_IP_setsockopt
* Returned Value  : error code
* Comments  :  Modify the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_IP_setsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] new value for the option */
      uint_32        optlen
         /* [IN] length of the option value, in bytes */
   )
{ /* Body */
/* Start CR 1146  */
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;
   uint_32     error;

   RTCS_ENTER(SETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   switch (optname) {

      case RTCS_SO_IP_TX_TTL:
         if (!optlen) {
            error =  RTCSERR_SOCK_SHORT_OPTION;
         } else  {
            socket_ptr->LINK_OPTIONS.TX.TTL = *(uchar_ptr)optval;
            /* Propogate the option to the TCB */
            if (socket_ptr->TCB_PTR != NULL)  {
               socket_ptr->TCB_PTR->TX.TTL = socket_ptr->LINK_OPTIONS.TX.TTL;
            }
            error = RTCS_OK;
         } /* Endif */
         break;
      case RTCS_SO_IP_TX_TOS:
         if (!optlen) {
            error =  RTCSERR_SOCK_SHORT_OPTION;
         } else  {
            socket_ptr->LINK_OPTIONS.TX.TOS = *(uchar_ptr)optval;
            /* Propogate the option to the TCB */
            if (socket_ptr->TCB_PTR != NULL)  {
               socket_ptr->TCB_PTR->TX.TOS = socket_ptr->LINK_OPTIONS.TX.TOS;
            }
            error = RTCS_OK;
         } /* Endif */
         break;
         
       default:
         error = RTCSERR_SOCK_INVALID_OPTION;
      } /* Endswitch */
/* End CR 1146 */

   RTCS_EXIT(SETSOCKOPT, error);
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/core_mutex/core_mutex.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: core_mutex.c$
* $Version : 3.8.4.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains the source functions for functions required to
*   control the PBRIDGE.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include <core_mutex.h>

static CORE_MUTEX_COMPONENT_PTR _core_mutex_component_ptr = NULL;

/*FUNCTION****************************************************************
*
* Function Name    : _core_mutext_get_component_ptr
* Returned Value   : CORE_MUTEX_COMPONENT_PTR
* Comments         :
*    This function gets the core mutex component pointer.
*
*END*********************************************************************/

CORE_MUTEX_COMPONENT_PTR _core_mutext_get_component_ptr(void)
{
   return _core_mutex_component_ptr;
}


/*FUNCTION****************************************************************
*
* Function Name    : _core_mutext_set_component_ptr
* Returned Value   :
* Comments         :
*    This function sets the core mutex component pointer.
*
*END*********************************************************************/

void _core_mutext_set_component_ptr(CORE_MUTEX_COMPONENT_PTR p)
{
   _core_mutex_component_ptr=p;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwadc/lwadc.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2011 Embedded Access Inc
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwadc.h$
* $Version : 3.8.2.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*   LWADC driver header file
*
*END************************************************************************/
#ifndef __lwadc_h__
#define __lwadc_h__

typedef enum {
    LWADC_RESOLUTION=1,
    LWADC_REFERENCE,
    LWADC_FREQUENCY,
    LWADC_DIVIDER,
    LWADC_DIFFERENTIAL,
    LWADC_POWER_DOWN,
    LWADC_NUMERATOR ,
    LWADC_DENOMINATOR,
    LWADC_FORMAT,
    LWADC_INPUT_CONVERSION_ENABLE
} LWADC_ATTRIBUTE;

#define LWADC_FORMAT_LEFT_JUSTIFIED     1
#define LWADC_FORMAT_RIGHT_JUSTIFIED    2

typedef uint_32 LWADC_VALUE, * LWADC_VALUE_PTR;

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

boolean _lwadc_init( const LWADC_INIT_STRUCT * init_ptr);
boolean _lwadc_init_input( LWADC_STRUCT_PTR lwadc_ptr, uint_32 input);
boolean _lwadc_read_raw( LWADC_STRUCT_PTR lwadc_ptr,  LWADC_VALUE_PTR outSample);
boolean _lwadc_read( LWADC_STRUCT_PTR lwadc_ptr, LWADC_VALUE_PTR outSample);
boolean _lwadc_wait_next( LWADC_STRUCT_PTR lwadc_ptr);
boolean _lwadc_read_average( LWADC_STRUCT_PTR lwadc_ptr, uint_32 num_samples, LWADC_VALUE_PTR outSample);
boolean _lwadc_set_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute, uint_32 value);
boolean _lwadc_get_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute, uint_32_ptr value_ptr);

#ifdef __cplusplus
}
#endif

#endif //__lwadc_h__


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/int_ctrl/int_ctrl_mcf5225.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: int_ctrl_mcf5225.c$
* $Version : 3.7.10.0$
* $Date    : Mar-9-2011$
*
* Comments:
*
*   This file contains definitions for the MFC5225 interrupt controller
*   functions.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "bsp.h"

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : compute_icntl_registers
* Returned Value  : uint_32
* Comments        :
*   Compute which registers to touch for the given interrupt number
*
*END*---------------------------------------------------------------------*/

static boolean compute_icntl_registers
   (
      // [IN] Interrupt number
      PSP_INTERRUPT_TABLE_INDEX irq,

      // [OUT] Interrupt control register
      volatile uchar _PTR_ _PTR_    ictlr,

      // [OUT] Interrupt mask register
      volatile uint_32 _PTR_ _PTR_  maskr,

      // [OUT] Interrupt mask register bit
      uint_32_ptr                   bit,

      // [OUT] Interrupt clear bit 0 pointer to register
      volatile uint_32 _PTR_ _PTR_  clear
   )
{ /* Body */

   VMCF52XX_ICTRL0_STRUCT_PTR ictrl0;
   VMCF52XX_ICTRL1_STRUCT_PTR ictrl1;

   if (irq >= PSP_INT_FIRST_EXTERNAL) {
      uint_32 index = irq - PSP_INT_FIRST_EXTERNAL;

      if (index < 32) {
         ictrl0 = PSP_GET_ICTRL0_BASE();
         *ictlr = &ictrl0->ICR[index];
         *maskr = &ictrl0->ICTRL.IMRL;
         *bit = 1 << index;
         *clear = &ictrl0->ICTRL.IMRL;
         return TRUE;
      } /* Endif */

      if (index < 64) {
         ictrl0 = PSP_GET_ICTRL0_BASE();
         *ictlr = &ictrl0->ICR[index];
         *maskr = &ictrl0->ICTRL.IMRH;
         *bit = 1 << (index - 32);
         *clear = &ictrl0->ICTRL.IMRL;
         return TRUE;
      } /* Endif */

      if (index < 96){
         index = irq - MCF5225_ICTRL1_BASEx;
         ictrl1 = PSP_GET_ICTRL1_BASE();
         *ictlr = &ictrl1->ICR[index];
         *maskr = &ictrl1->ICTRL.IMRL;
         *bit = 1 << (index - 64);
         *clear = &ictrl1->ICTRL.IMRL;
         return TRUE;
      } /* Endif */

      if (index < 128){
         index = irq - MCF5225_ICTRL1_BASEx;
         ictrl1 = PSP_GET_ICTRL1_BASE();
         *ictlr = &ictrl1->ICR[index];
         *maskr = &ictrl1->ICTRL.IMRH;
         *bit = 1 << (index - 96);
         *clear = &ictrl1->ICTRL.IMRL;
         return TRUE;
      } /* Endif */

   } /* Endif */

   return FALSE;

} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _mcf5225_int_init
* Returned Value  : uint_32
* Comments        :
*   Initialize a specific interrupt in the proper interrupt controller
*
*END*---------------------------------------------------------------------*/

uint_32 _mcf5225_int_init
   (
      // [IN} Interrupt number
      PSP_INTERRUPT_TABLE_INDEX irq,

      // [IN} Interrupt priority level
      _int_level                level,

      // [IN} Interrupt sub-priority level within priority
      _int_priority             sublevel,

      // [IN} Unmask the interrupt now?
      boolean                   unmask
   )
{ /* Body */

   volatile uchar _PTR_   ictrl;
   volatile uint_32 _PTR_ maskr, _PTR_ clear;
   uint_32 bit, mask;
   uint_32 temp;

   if (compute_icntl_registers(irq,&ictrl,&maskr,&bit,&clear)) {
      temp = _psp_get_sr();
      _psp_set_sr(temp | 0x0700);
      mask = *maskr;
      if (!unmask) {
         *maskr = mask | bit;
      } /* Endif */
      *ictrl = ((level & 7) << 3) | (sublevel & 7);
      if (unmask) {
         *maskr = mask & ~bit;
         *clear = *clear & 0xFFFFFFFE;
      } /* Endif */
      _psp_set_sr(temp);
      return MQX_OK;
   } /* Endif */

   return MQX_INVALID_PARAMETER;

} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _mcf5225_int_unmask
* Returned Value  : uint_32
* Comments        :
*   Clear the mask bit that inhibits the interrupt
*
*END*---------------------------------------------------------------------*/

uint_32 _mcf5225_int_unmask
   (
      // [IN} Interrupt number
      PSP_INTERRUPT_TABLE_INDEX irq
   )
{ /* Body */

   volatile uchar _PTR_   ictrl;
   volatile uint_32 _PTR_ maskr, _PTR_ clear;
   uint_32 bit;

   if (compute_icntl_registers(irq,&ictrl,&maskr,&bit,&clear)) {
      *maskr = *maskr & ~bit;
      *clear = *clear & 0xFFFFFFFE;
      return MQX_OK;
   } /* Endif */

   return MQX_INVALID_PARAMETER;

} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _mcf5225_int_mask
* Returned Value  : uint_32
* Comments        :
*   Set the mask bit that inhibits the interrupt
*
*END*---------------------------------------------------------------------*/

uint_32 _mcf5225_int_mask
   (
      // [IN} Interrupt number
      PSP_INTERRUPT_TABLE_INDEX irq
   )
{ /* Body */

   volatile uchar _PTR_   ictrl;
   volatile uint_32 _PTR_ maskr, _PTR_ clear;
   uint_32 bit;

   if (compute_icntl_registers(irq,&ictrl,&maskr,&bit,&clear)) {
      *maskr = *maskr | bit;
      return MQX_OK;
   } /* Endif */

   return MQX_INVALID_PARAMETER;

} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _mcf5225_int_mask_all
* Returned Value  : void
* Comments        :
*   Mask all external interrupts
*
*END*---------------------------------------------------------------------*/

void  _mcf5225_int_mask_all
   (
      void
   )
{ /* Body */

   PSP_GET_ICTRL0_BASE()->ICTRL.IMRL = MCF52XX_ICTR_IMRL_MASKALL;
   PSP_GET_ICTRL1_BASE()->ICTRL.IMRL = MCF52XX_ICTR_IMRL_MASKALL;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sai/sai_mk60.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sai_mk60.c$
* $Version : 3.8.3.0$
* $Date    : Aug-23-2012$
*
* Comments:
*
*   This file contains board-specific SAI initialization functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "sai.h"
#include "sai_ksai.h"
#include "sai_ksai_prv.h"

/*FUNCTION****************************************************************
*
* Function Name    : _bsp_get_sai_base_address
* Returned Value   : address if successful, NULL otherwise
* Comments         :
*    This function returns the base register address of the corresponding SAI device.
*
*END*********************************************************************/

pointer _bsp_get_sai_base_address
(
    uint_8 dev_num
)
{
    pointer addr;

    switch (dev_num)
    {
        case 0:
            addr = (pointer)I2S0_BASE_PTR;
            break;
#if !defined(MCU_MK60D10)
	case 1:
            addr = (pointer)I2S1_BASE_PTR;
            break;
#endif
        default:
            addr = NULL;
            break;
    }
    
    return addr;
}

/*FUNCTION****************************************************************
*
* Function Name    : _bsp_get_sai_tx_vector
* Returned Value   : vector number if successful, 0 otherwise
* Comments         :
*    This function returns desired interrupt tx vector number for specified SAI device.
*
*END*********************************************************************/

uint_32 _bsp_get_sai_tx_vector
(
    uint_8 dev_num
)
{
    uint_32 vector;
    
    switch (dev_num)
    {
        case 0:
            vector = INT_I2S0_Tx;
            break;
#if !defined(MCU_MK60D10)
        case 1:
            vector = INT_I2S1_Tx;
            break;
#endif
        default:
            vector = 0;
            break;
    }
    
    return vector;
}

/*FUNCTION****************************************************************
*
* Function Name    : _bsp_get_sai_rx_vector
* Returned Value   : vector number if successful, 0 otherwise
* Comments         :
*    This function returns desired interrupt rx vector number for specified SAI device.
*
*END*********************************************************************/

uint_32 _bsp_get_sai_rx_vector
(
    uint_8 dev_num
)
{
    uint_32 vector;
    
    switch (dev_num)
    {
        case 0:
            vector = INT_I2S0_Rx;
            break;
#if !defined(MCU_MK60D10)
        case 1:
            vector = INT_I2S1_Rx;
            break;
#endif
        default:
            vector = 0;
            break;
    }
    
    return vector;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/solink.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: solink.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the implementation of getsockopt()
*   and setsockopt() at the SOL_LINK level.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"

#define RTCS_ENTER(f,a) RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_LINK_ ## f, a)

#define RTCS_EXIT(f,a)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_LINK_ ## f, a); \
                        return a


uint_32 SOL_LINK_getsockopt (uint_32, uint_32, uint_32, pointer, uint_32 _PTR_);
uint_32 SOL_LINK_setsockopt (uint_32, uint_32, uint_32, pointer, uint_32);

const RTCS_SOCKOPT_CALL_STRUCT SOL_LINK_CALL = {
   SOL_LINK_getsockopt,
   SOL_LINK_setsockopt
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_LINK_getsockopt
* Returned Value  : error code
* Comments  :  Obtain the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_LINK_getsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] buffer for the current value of the option */
      uint_32  _PTR_ optlen
         /* [IN/OUT] length of the option value, in bytes */
   )
{ /* Body */
   /* Start SPR P122-0266-34. remove all warnings from RTCS code. */
#if RTCSCFG_LINKOPT_8023 || RTCSCFG_LINKOPT_8021Q_PRIO
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;
#endif

   RTCS_ENTER(GETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   switch (optname) {

#if RTCSCFG_LINKOPT_8023
   case RTCS_SO_LINK_RX_8023:
      *(uint_32_ptr)optval = socket_ptr->LINK_OPTIONS.RX.OPT_8023;
      break;
   case RTCS_SO_LINK_TX_8023:
      *(uint_32_ptr)optval = socket_ptr->LINK_OPTIONS.TX.OPT_8023;
      /* break; */
       *optlen = sizeof(uint_32);
      RTCS_EXIT(GETSOCKOPT, RTCS_OK);
#endif

#if RTCSCFG_LINKOPT_8021Q_PRIO
   case RTCS_SO_LINK_RX_8021Q_PRIO:
      *(int_32_ptr)optval = socket_ptr->LINK_OPTIONS.RX.OPT_PRIO ? socket_ptr->LINK_OPTIONS.RX.PRIO : -1;
      break;
   case RTCS_SO_LINK_TX_8021Q_PRIO:
      *(int_32_ptr)optval = socket_ptr->LINK_OPTIONS.TX.OPT_PRIO ? socket_ptr->LINK_OPTIONS.TX.PRIO : -1;
      /* break; */
      *optlen = sizeof(uint_32);
      RTCS_EXIT(GETSOCKOPT, RTCS_OK);
#endif

   default:
      RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID_OPTION);
   } /* Endswitch */

   /* *optlen = sizeof(uint_32); */
   /* RTCS_EXIT(GETSOCKOPT, RTCS_OK); */
   /* End SPR P122-0266-34. */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_LINK_setsockopt
* Returned Value  : error code
* Comments  :  Modify the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_LINK_setsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] new value for the option */
      uint_32        optlen
         /* [IN] length of the option value, in bytes */
   )
{ /* Body */
/* Start SPR P122-0266-34 remove all warnings from RTCS code. */
#if RTCSCFG_LINKOPT_8023 || RTCSCFG_LINKOPT_8021Q_PRIO
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;
#endif

   RTCS_ENTER(SETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   switch (optname) {

#if RTCSCFG_LINKOPT_8023
   case RTCS_SO_LINK_TX_8023:
      socket_ptr->LINK_OPTIONS.TX.OPT_8023 = *(uint_32_ptr)optval ? TRUE : FALSE;
      /* break; */
      RTCS_EXIT(SETSOCKOPT, RTCS_OK);
#endif

#if RTCSCFG_LINKOPT_8021Q_PRIO
   case RTCS_SO_LINK_TX_8021Q_PRIO:
      if (*(int_32_ptr)optval == -1) {
         socket_ptr->LINK_OPTIONS.TX.OPT_PRIO = 0;
      } else {
         socket_ptr->LINK_OPTIONS.TX.OPT_PRIO = 1;
         socket_ptr->LINK_OPTIONS.TX.PRIO = *(int_32_ptr)optval;
      } /* Endif */
      /* break; */
      RTCS_EXIT(SETSOCKOPT, RTCS_OK);
#endif

   default:
      RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID_OPTION);
   } /* Endswitch */

   /* RTCS_EXIT(SETSOCKOPT, RTCS_OK); */
   /* End SPR P122-0266-34. */

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/i2c_qi2c_prv.h<|end_filename|>
#ifndef _i2c_qi2c_prv_h
#define _i2c_qi2c_prv_h
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_qi2c_prv.h$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the I2C drivers for PPC family.
*
*END************************************************************************/



/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** QI2C_INFO_STRUCT
** Run time state information for each serial channel
*/
typedef struct qi2c_info_struct
{
    /* Current initialized values */
    QI2C_INIT_STRUCT                  INIT;

    VQI2C_REG_STRUCT_PTR              I2C_PTR;

    /* The previous interrupt handler and data */
    void                  (_CODE_PTR_ OLD_ISR)(pointer);
    pointer                           OLD_ISR_DATA;

    /* Interrupt vector */
    uint_32                           VECTOR;
   
    /* Actual baudrate table index */
    uint_8                            BAUD_INDEX;

    /* Actual mode */
    uint_8                            MODE;

    /* Actual state */
    uint_8                            STATE;

    /* Destination address */
    uint_8                            ADDRESSEE;
   
   /* Operation flags */
    uint_8                            OPERATION;

    /* Interrupt disabling workaround flag */
    uint_8                            INT_REQUEST;
    /* Number of bytes requested for receive */
    uint_32                           RX_REQUEST;

    /* Pointer to the buffer to use for Tx/Rx data */
    uchar_ptr                         RX_BUFFER;

    /* Rx write index */
    uint_32                           RX_IN;

    /* Rx read index */
    uint_32                           RX_OUT;

    /* Pointer to the buffer to use for current Tx data */
    uchar_ptr                         TX_BUFFER;

    /* Tx write index */
    uint_32                           TX_IN;

    /* Tx read index */
    uint_32                           TX_OUT;

    /* Statistical information */
    I2C_STATISTICS_STRUCT             STATISTICS;

} QI2C_INFO_STRUCT, _PTR_ QI2C_INFO_STRUCT_PTR;

typedef volatile struct qi2c_info_struct * VQI2C_INFO_STRUCT_PTR; 

/*
** QI2C_BAUDRATE_STRUCT
*/
typedef struct qi2c_baudrate_struct
{
    /* Baudrate */
    uint_32                           BAUD_RATE;

    /* Divider */
    uint_8                            IC;

} QI2C_BAUDRATE_STRUCT, _PTR_ QI2C_BAUDRATE_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern pointer _bsp_get_qi2c_base_address (uint_8);
extern uint_32 _bsp_get_qi2c_vector (uint_8);

#ifdef __cplusplus
}
#endif


#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/iop_inst.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iop_inst.c$
* $Version : 3.8.4.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This file contains the function for installing a dynamic device
*   driver.
*
*END************************************************************************/

/* suppress warning if partition component is not enabled in MQX */
#define MQX_DISABLE_CONFIG_CHECK 1

#include <string.h>
#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "partition.h"
#include "io_pcb.h"
#include "iopcbprv.h"

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_pcb_dev_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a device dynamically, so tasks can fopen to it.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_pcb_dev_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr             identifier,
  
      /* [IN] The I/O open function */
      _mqx_int (_CODE_PTR_ io_open)(FILE_DEVICE_STRUCT_PTR,
         char _PTR_, char _PTR_),

      /* [IN] The I/O close function */
      _mqx_int (_CODE_PTR_ io_close)(FILE_DEVICE_STRUCT_PTR),

      /* [IN] The I/O read function */
      _mqx_int (_CODE_PTR_ io_read)(FILE_DEVICE_STRUCT_PTR,
         IO_PCB_STRUCT _PTR_ _PTR_),

      /* [IN] The I/O write function */
      _mqx_int (_CODE_PTR_ io_write)(FILE_DEVICE_STRUCT_PTR,
         IO_PCB_STRUCT _PTR_),

      /* [IN] The I/O ioctl function */
      _mqx_int (_CODE_PTR_ io_ioctl)(FILE_DEVICE_STRUCT_PTR, _mqx_uint,
         pointer),

      /* [IN] The I/O uninstall function */
      _mqx_int (_CODE_PTR_ io_uninstall)(IO_PCB_DEVICE_STRUCT_PTR),

      /* [IN] The I/O initialization data */
      pointer              io_init_data_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR   kernel_data;
   IO_PCB_DEVICE_STRUCT_PTR dev_ptr;

   kernel_data = _mqx_get_kernel_data();

#if MQX_CHECK_ERRORS
   if ((io_open == NULL) || (io_close == NULL)){
      return(MQX_INVALID_PARAMETER);
   }/* Endif */

   /* Check to see if device already installed */
   _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   /* Start CR 460 */
   if (kernel_data->IO_DEVICES.NEXT == NULL) {
      /* Set up the device driver queue */
      _QUEUE_INIT(&kernel_data->IO_DEVICES, 0);
   } /* Endif */
   /* End CR 460 */
   dev_ptr = (IO_PCB_DEVICE_STRUCT_PTR)((pointer)kernel_data->IO_DEVICES.NEXT);
   while (dev_ptr != (IO_PCB_DEVICE_STRUCT_PTR)
      ((pointer)&kernel_data->IO_DEVICES.NEXT))
   {
      if (!strncmp(identifier, dev_ptr->IDENTIFIER, IO_MAXIMUM_NAME_LENGTH)) {
         _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
         return(IO_DEVICE_EXISTS);
      } /* Endif */
      dev_ptr = (IO_PCB_DEVICE_STRUCT_PTR)((pointer)dev_ptr->QUEUE_ELEMENT.NEXT);
   } /* Endwhile */
   _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
#endif
   
   dev_ptr     = (pointer)_mem_alloc_system_zero(
      (_mem_size)sizeof(IO_PCB_DEVICE_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   }/* Endif */
#endif
   
   dev_ptr->IDENTIFIER      = identifier;
   dev_ptr->IO_OPEN         = io_open;
   dev_ptr->IO_CLOSE        = io_close;
   dev_ptr->IO_READ         = io_read;
   dev_ptr->IO_WRITE        = io_write;
   dev_ptr->IO_IOCTL        = io_ioctl;
   dev_ptr->IO_UNINSTALL    = io_uninstall;
   dev_ptr->DRIVER_INIT_PTR = io_init_data_ptr;

   _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   _QUEUE_ENQUEUE(&kernel_data->IO_DEVICES, dev_ptr);
   _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);

   return MQX_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_pcb_dev_uninstall
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    UnInstall a device dynamically.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_pcb_dev_uninstall
   (
      /* [IN] A string that identifies the device */
      char_ptr           identifier
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR   kernel_data;
   IO_PCB_DEVICE_STRUCT_PTR dev_ptr;

   kernel_data = _mqx_get_kernel_data();

   _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   /* Check to see if device already installed */
   dev_ptr = (IO_PCB_DEVICE_STRUCT_PTR)((pointer)kernel_data->IO_DEVICES.NEXT);
   while (dev_ptr != (IO_PCB_DEVICE_STRUCT_PTR)
      ((pointer)&kernel_data->IO_DEVICES.NEXT))
   {
      if (!strncmp(identifier, dev_ptr->IDENTIFIER, IO_MAXIMUM_NAME_LENGTH)) {
         break;
      } /* Endif */
      dev_ptr = (IO_PCB_DEVICE_STRUCT_PTR)((pointer)dev_ptr->QUEUE_ELEMENT.NEXT);
   } /* Endwhile */
   if (dev_ptr == (IO_PCB_DEVICE_STRUCT_PTR)
      ((pointer)&kernel_data->IO_DEVICES.NEXT))
   {
      dev_ptr = NULL;
   } /* Endif */
   if (dev_ptr)  {
      if (dev_ptr->IO_UNINSTALL)  {
         (*dev_ptr->IO_UNINSTALL)(dev_ptr);
      } /* Endif */
      _QUEUE_REMOVE(&kernel_data->IO_DEVICES, dev_ptr);
   } /* Endif */
   _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   if (dev_ptr) {
      _mem_free(dev_ptr);
      return MQX_OK;
   }/* Endif */
   return(IO_PCB_DEVICE_DOES_NOT_EXIST);
   
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_usb.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_usb.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains board-specific USB initialization functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"

const struct usb_ehci_dev_init_struct _ehci0_dev_init_param = {
    (pointer)USBHS_BASE_PTR,
    (uchar_ptr)USBHS_BASE_PTR + 0x100,
    (uchar_ptr)USBHS_BASE_PTR + 0x80,
    NULL,
    INT_USBHS, //vector
    3  //priority
};

const struct usb_ehci_host_init_struct _ehci0_host_init_param = {
    (pointer)USBHS_BASE_PTR,
    (uchar_ptr)USBHS_BASE_PTR + 0x100,
    (uchar_ptr)USBHS_BASE_PTR + 0x80,
    BSP_EHCI_HS,
    INT_USBHS, //vector
    3,  //priority
    1024 //size of periodic list [items]
};

const struct usb_khci_dev_init_struct _khci0_dev_init_param = {
    (pointer)USB0_BASE_PTR,
    INT_USB0, //vector
    3,  //priority
    16  //max. endpoints
};

const struct usb_khci_host_init_struct _khci0_host_init_param = {
    (pointer)USB0_BASE_PTR,
    INT_USB0, //vector
    3  //priority
};

const pointer _bsp_usb_table[] = 
{
    (pointer) &_ehci0_dev_init_param,
    (pointer) &_khci0_dev_init_param,
    (pointer) &_ehci0_host_init_param,
    (pointer) &_khci0_host_init_param
};


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_read.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_read.c$
* $Version : 3.8.9.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   Contains the function read.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Reads form the specified stream.
 * 
 * \param[in] file_ptr The stream to perform the operation on.
 * \param[in] data_ptr The data location to read to.
 * \param[in] num      The number of bytes to read.
 * 
 * \return Number of characters read.
 * \return IO_ERROR   
 */ 
_mqx_int _io_read
   ( 
      MQX_FILE_PTR file_ptr,
      pointer      data_ptr,
      _mqx_int     num      
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   dev_ptr;
   char_ptr               data = (char_ptr) data_ptr;
   _mqx_int               res = 0;

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(IO_ERROR);
   } /* Endif */
#endif

   if (!file_ptr->HAVE_UNGOT_CHARACTER || num > 1) {

        dev_ptr = file_ptr->DEV_PTR;
#if MQX_CHECK_ERRORS
        if (dev_ptr->IO_READ == NULL) {
            file_ptr->ERROR = MQX_IO_OPERATION_NOT_AVAILABLE;
            return (IO_ERROR);
        } /* Endif */
#endif

        if (file_ptr->HAVE_UNGOT_CHARACTER) {
            res = (*dev_ptr->IO_READ)(file_ptr, data+1, num-1);
        }
        else {
            res = (*dev_ptr->IO_READ)(file_ptr, data, num);
        }
        if (res<0) return res;
   }
      
   if ( file_ptr->HAVE_UNGOT_CHARACTER ) {
       if (num <= 0) return 0;
       *data = (char)file_ptr->UNGOT_CHARACTER;
       file_ptr->HAVE_UNGOT_CHARACTER = FALSE;
       res++;
   } /* Endif */

   return res;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_uinst.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_uinst.c$
* $Version : 3.5.4.0$
* $Date    : Dec-8-2009$
*
* Comments:
*
*   This file contains the function for un-installing a dynamic device
*   driver.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#ifdef NULL
#undef NULL
#endif
#include <string.h>
#ifndef NULL
#define NULL ((pointer)0)
#endif

#if MQX_USE_IO


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dev_uninstall
* Returned Value   : _mqx_int a task error code or MQX_OK
* Comments         :
*    Un-Install a device dynamically.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_dev_uninstall
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr           identifier
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   IO_DEVICE_STRUCT_PTR   dev_ptr;
   _mqx_int               result = IO_OK;

   _GET_KERNEL_DATA(kernel_data);

   /* Find the device */
   _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)kernel_data->IO_DEVICES.NEXT);
   while (dev_ptr != (pointer)&kernel_data->IO_DEVICES.NEXT) {
      if (!strncmp(identifier, dev_ptr->IDENTIFIER, IO_MAXIMUM_NAME_LENGTH)) {
         /* Found it */
         if (dev_ptr->IO_UNINSTALL != NULL) {
            result = (*dev_ptr->IO_UNINSTALL)(dev_ptr);
            if (result == IO_OK) {
               _QUEUE_REMOVE(&kernel_data->IO_DEVICES, dev_ptr);
               _mem_free(dev_ptr);
            } /* Endif */
         } /* Endif */
         _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
         return(result);
      } /* Endif */
      dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)dev_ptr->QUEUE_ELEMENT.NEXT);
   } /* Endwhile */
   _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);

   return(IO_DEVICE_DOES_NOT_EXIST);

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_lpm.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*****************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: init_lpm.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains Low Power Manager initialization information.
*
*END************************************************************************/


#include "mqx.h"
#include "bsp.h"


#if MQX_ENABLE_LOW_POWER


#ifndef PE_LDD_VERSION


const LPM_CPU_OPERATION_MODE LPM_CPU_OPERATION_MODES[LPM_OPERATION_MODES] = 
{
    // LPM_OPERATION_MODE_RUN
    {
        LPM_CPU_POWER_MODE_RUN,                     // Index of predefined mode
        0,                                          // Additional mode flags
        0,                                          // Mode wake up events from pins 0..3
        0,                                          // Mode wake up events from pins 4..7
        0,                                          // Mode wake up events from pins 8..11
        0,                                          // Mode wake up events from pins 12..15
        0                                           // Mode wake up events from internal input sources
    },
    // LPM_OPERATION_MODE_WAIT
    {
        LPM_CPU_POWER_MODE_VLPR,                    // Index of predefined mode
        0,                                          // Additional mode flags
        0,                                          // Mode wake up events from pins 0..3
        0,                                          // Mode wake up events from pins 4..7
        0,                                          // Mode wake up events from pins 8..11
        0,                                          // Mode wake up events from pins 12..15
        0                                           // Mode wake up events from internal input sources
    },
    // LPM_OPERATION_MODE_SLEEP
    {
        LPM_CPU_POWER_MODE_WAIT,                    // Index of predefined mode
        LPM_CPU_POWER_MODE_FLAG_SLEEP_ON_EXIT,      // Additional mode flags
        0,                                          // Mode wake up events from pins 0..3
        0,                                          // Mode wake up events from pins 4..7
        0,                                          // Mode wake up events from pins 8..11
        0,                                          // Mode wake up events from pins 12..15
        0                                           // Mode wake up events from internal input sources
    },
    // LPM_OPERATION_MODE_STOP
    {
        LPM_CPU_POWER_MODE_LLS,                     // Index of predefined mode
        0,                                          // Additional mode flags
        0,                                          // Mode wake up events from pins 0..3
        0,                                          // Mode wake up events from pins 4..7
        0,                                          // Mode wake up events from pins 8..11
        0,                                          // Mode wake up events from pins 12..15
        LLWU_ME_WUME0_MASK                          // Mode wake up events from internal input sources - LPT
    }
};


#else


const LPM_CPU_OPERATION_MODE LPM_CPU_OPERATION_MODES[1] = {0};


#endif


#endif


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/ppp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ppp.c$
* $Version : 3.8.11.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains the implementation of the PPP
*   initialization routines.
*
*END************************************************************************/

#include <ppp.h>
#include "ppp_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_initialize
* Returned Value  :  error code
* Comments        :
*     Initializes PPP for a handle.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_initialize
   (
      _iopcb_handle       device,
            /* [IN] - I/O stream to use */
      _ppp_handle _PTR_   handle
            /* [OUT] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   PPP_CFG_PTR          ppp_ptr;
   uint_32              i, error;

   /* Allocate the state structure */
   ppp_ptr = PPP_memalloc(sizeof(PPP_CFG));
   if (!ppp_ptr) {
      return RTCSERR_PPP_ALLOC_FAILED;
   } /* Endif */

   /* Initialize it */
   PPP_memzero(ppp_ptr, sizeof(PPP_CFG));
   ppp_ptr->LINK_STATE = FALSE;
   ppp_ptr->DEVICE = device;
   for (i = 0; i < PPP_CALL_MAX; i++) {
      ppp_ptr->LCP_CALL[i].CALLBACK = NULL;
      ppp_ptr->LCP_CALL[i].PARAM    = NULL;
   } /* Endfor */
   ppp_ptr->PROT_CALLS = NULL;
   ppp_ptr->RECV_OPTIONS = &PPP_DEFAULT_OPTIONS;
   ppp_ptr->SEND_OPTIONS = &PPP_DEFAULT_OPTIONS;

   /* Initialize the lwsem */
   if (PPP_mutex_init(&ppp_ptr->MUTEX)) {
      return RTCSERR_PPP_INIT_MUTEX_FAILED;
   } /* Endif */

   /* Initialize LCP */
   error = LCP_init(ppp_ptr);
   if (error) {
      PPP_mutex_destroy(&ppp_ptr->MUTEX);
      return error;
   } /* Endif */

   /* Initialize CCP */
   error = CCP_init(ppp_ptr);
   if (error) {
      LCP_destroy(ppp_ptr);
      PPP_mutex_destroy(&ppp_ptr->MUTEX);
      return error;
   } /* Endif */
   CCP_open(ppp_ptr);

   /* Create a pool of message buffers */
   ppp_ptr->MSG_POOL = RTCS_msgpool_create(sizeof(PPP_MESSAGE),
      PPP_MESSAGE_INITCOUNT, PPP_MESSAGE_GROWTH, PPP_MESSAGE_LIMIT);
   if (ppp_ptr->MSG_POOL == MSGPOOL_NULL_POOL_ID) {
      CCP_destroy(ppp_ptr);
      LCP_destroy(ppp_ptr);
      PPP_mutex_destroy(&ppp_ptr->MUTEX);
      return RTCSERR_PPP_CREATE_PKT_POOL_FAILED;
   } /* Endif */

 
   /* Create the Tx Task */
   error = RTCS_task_create("PPP tx", _PPPTASK_priority,
      _PPPTASK_stacksize + 1000,
      PPP_tx_task, ppp_ptr);
   if (error) {
     RTCS_msgpool_destroy(ppp_ptr->MSG_POOL);
      CCP_destroy(ppp_ptr);
      LCP_destroy(ppp_ptr);
     PPP_mutex_destroy(&ppp_ptr->MUTEX);
      return error;
   } /* Endif */

   /* Create the Rx Task        */
   /* Set task ready for run    */
   ppp_ptr->STOP_RX = FALSE; 
   
   error = RTCS_task_create("PPP rx", _PPPTASK_priority,
      _PPPTASK_stacksize + 1000,
      PPP_rx_task, ppp_ptr);
   if (error) {
      RTCS_msgpool_destroy(ppp_ptr->MSG_POOL);
      CCP_destroy(ppp_ptr);
      LCP_destroy(ppp_ptr);
      PPP_mutex_destroy(&ppp_ptr->MUTEX);
      return error;
   } /* Endif */

   /* Return the handle */
   ppp_ptr->VALID = PPP_VALID;
   *handle = ppp_ptr;
   return PPP_OK;

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_shutdown
* Returned Value  :  error code
* Comments        :
*     Destroys a PPP handle and frees all resources.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_shutdown
   (
      _ppp_handle  handle
       /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 
   
   PPP_CFG_PTR    ppp_ptr = handle;
   _rtcs_sem      sem;
   uint_32         error = RTCS_OK;
   /* wait time  in 0.1 Sec */
   uint_32        wait_time  = 50; 
   /* delay time in mS */ 
   uint_32        delay_time = 100; 

   PPP_lowerdown(ppp_ptr);
   ppp_ptr->STOP_RX = TRUE;    
   while(ppp_ptr->STOP_RX)  
   {  
      /* Waiting before Rx task  will be closed or kill it. */
      _time_delay(delay_time);
       wait_time--;
       if(!wait_time)
       {
          error = RTCSERR_TIMEOUT;
          RTCS_task_destroy(ppp_ptr->RX_TASKID);
          break;
       }
   }
   /* Kill Tx task */
   RTCS_sem_init(&sem);
   PPP_send_shutdown(ppp_ptr, &sem);
   RTCS_sem_wait(&sem);
   RTCS_sem_destroy(&sem);
   RTCS_msgpool_destroy(ppp_ptr->MSG_POOL);
   CCP_destroy(ppp_ptr);
   LCP_destroy(ppp_ptr);
   PPP_mutex_destroy(&ppp_ptr->MUTEX);
   PPP_memfree(handle);
   return(error);
#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_pcballoc
* Returned Value  :  pointer to allocated PCB
* Comments        :
*     Called by PPPFSM_send* and {P,CH}AP_send.  Dynamically
*     allocates a PCB.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

PCB_PTR PPP_pcballoc
   (
      uint_16 protocol,
            /* [IN] - PPP protocol */
      uint_32 size
            /* [IN] - max size of packet, excluding protocol */
   )
{ /* Body */
   PCB_FRAGMENT _PTR_ pcb_frag_ptr;
   PCB_PTR packet;

   packet = _mem_alloc_system(sizeof(PCB) + sizeof(PCB_FRAGMENT) + 2 + size);
   if (packet) {
      packet->FREE = (void (_CODE_PTR_)(PCB_PTR))_mem_free;
      /* Start SPR P122-0266-22 remove all warnings from RTCS code. */
      /*  packet->FRAG[0].LENGTH   = size + 2; */
      /*  packet->FRAG[0].FRAGMENT = (uchar_ptr)packet + sizeof(PCB) + sizeof(PCB_FRAGMENT); */
      /*  packet->FRAG[1].LENGTH   = 0; */
      /*  packet->FRAG[1].FRAGMENT = NULL; */
      /*  htons(packet->FRAG[0].FRAGMENT, protocol); */
      pcb_frag_ptr = packet->FRAG;
      pcb_frag_ptr->LENGTH   = size + 2;
      pcb_frag_ptr->FRAGMENT = (uchar_ptr)packet + sizeof(PCB) +
         sizeof(PCB_FRAGMENT);
      htons(pcb_frag_ptr->FRAGMENT, protocol);
      pcb_frag_ptr++;
      pcb_frag_ptr->LENGTH   = 0;
      pcb_frag_ptr->FRAGMENT = NULL;
      /* End SPR P122-0266-22 */
   } /* Endif */

   return packet;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_getcall
* Returned Value  :  error code
* Comments        :
*     Retrieves an application callback function.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_getcall
   (
      _ppp_handle             handle,
            /* [IN] - the PPP state structure */
      uint_32                 callnum,
            /* [IN] - PPP callback */
      void (_CODE_PTR_ _PTR_  callback)(),
            /* [OUT] - callback function */
      pointer          _PTR_  callparam
            /* [OUT] - callback parameter */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   PPP_CFG_PTR ppp_ptr = handle;
   PPP_CALL_INTERNAL_PTR call_ptr;

      /* Do some error checking */
  if (ppp_ptr->VALID != PPP_VALID) {
      return RTCSERR_PPP_INVALID_HANDLE;
   } else if (callnum >= PPP_CALL_MAX) {
      return RTCSERR_PPP_INVALID_CALLBACK;
   } /* Endif */

   call_ptr   = &ppp_ptr->LCP_CALL[callnum];
   *callback  = call_ptr->CALLBACK;
   *callparam = call_ptr->PARAM;
   return PPP_OK;

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */    

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_setcall
* Returned Value  :  error code
* Comments        :
*     Sets an application callback function.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_setcall
   (
      _ppp_handle             handle,
            /* [IN] - the PPP state structure */
      uint_32                 callnum,
            /* [IN] - PPP callback */
      void (_CODE_PTR_ _PTR_  callback)(),
            /* [IN/OUT] - callback function */
      pointer          _PTR_  callparam
            /* [IN/OUT] - callback parameter */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   PPP_CFG_PTR ppp_ptr = handle;
   PPP_CALL_INTERNAL_PTR call_ptr;
   void (_CODE_PTR_ oldfn)();
   pointer oldparam;

      /* Do some error checking */
   if (ppp_ptr->VALID != PPP_VALID) {
      return RTCSERR_PPP_INVALID_HANDLE;
   } else if (callnum >= PPP_CALL_MAX) {
      return RTCSERR_PPP_INVALID_CALLBACK;
   } /* Endif */

   call_ptr = &ppp_ptr->LCP_CALL[callnum];
   oldfn    = call_ptr->CALLBACK;
   oldparam = call_ptr->PARAM;
   call_ptr->CALLBACK = *callback;
   call_ptr->PARAM    = *callparam;
   *callback  = oldfn;
   *callparam = oldparam;
   return PPP_OK;

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */    

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_getmtu
* Returned Value  :  MTU
* Comments        :
*     Retrieves the negotiated MTU (i.e. the peer's MRU)
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_getmtu
   (
      _ppp_handle       handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;
   return ppp_ptr->SEND_OPTIONS->MRU;

#else

    return 0;    

#endif /* RTCSCFG_ENABLE_IP4 */ 
   
} /* Endbody */


/* Start CR 2207 */
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_set_secrets
* Returned Value  :  
* Comments        :
*     
*
*END*-----------------------------------------------------------------*/

boolean PPP_set_secrets
   (
      _ppp_handle       handle,
            /* [IN] - the PPP state structure */
      uint_32           secret_number,

      PPP_SECRET_PTR    secret_ptr

   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;
   boolean     success=TRUE;

   switch (secret_number) {
      case PPP_PAP_LSECRET:
         PPP_SECRET(ppp_ptr, _PPP_PAP_LSECRET) = secret_ptr;
         break;

      case PPP_PAP_RSECRETS:
         PPP_SECRET(ppp_ptr, _PPP_PAP_RSECRETS) = secret_ptr;
         break;

      case PPP_CHAP_LSECRETS:
         PPP_SECRET(ppp_ptr, _PPP_CHAP_LSECRETS) = secret_ptr;
         break;

      case PPP_CHAP_RSECRETS:
         PPP_SECRET(ppp_ptr, _PPP_CHAP_RSECRETS) = secret_ptr;
         break;
   
      default:
         success=FALSE;
   }

   return success;

#else

    return FALSE;    

#endif /* RTCSCFG_ENABLE_IP4 */ 
   
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_set_chap_lname
* Returned Value  :  
* Comments        :
*     
*
*END*-----------------------------------------------------------------*/

boolean PPP_set_chap_lname
   (
      _ppp_handle       handle,
            /* [IN] - the PPP state structure */
      char_ptr    lname

   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;
   PPP_SECRET(ppp_ptr, _PPP_CHAP_LNAME) = lname;
   return TRUE;

#else

    return FALSE;    

#endif /* RTCSCFG_ENABLE_IP4 */ 
   
} /* Endbody */
/* End CR 2207 */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_SensorTSIL.c<|end_filename|>
/***********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
*********************************************************************************************************************//*!
*
* @file   TSS_SensorTSIL.c
*
* @brief  Contains functions to Perform the sensing to the electrodes and set the status for each electrode
*
* @version 1.0.27.0
*
* @date Sep-20-2012
*
*
***********************************************************************************************************************/

#include "TSS_SensorTSIL.h"

#if TSS_DETECT_METHOD(TSIL)
  
  #if TSS_HCS08_MCU || TSS_CFV1_MCU
  
    #if TSS_USE_SIMPLE_LOW_LEVEL

      /***************** ROM & RAM Data definition *******************/
  
      #if TSS_N_ELECTRODES > 0
        #if TSS_DETECT_EL_METHOD(0,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(0) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 1
        #if TSS_DETECT_EL_METHOD(1,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(1) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 2
        #if TSS_DETECT_EL_METHOD(2,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(2) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 3
        #if TSS_DETECT_EL_METHOD(3,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(3) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 4
        #if TSS_DETECT_EL_METHOD(4,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(4) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 5
        #if TSS_DETECT_EL_METHOD(5,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(5) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 6
        #if TSS_DETECT_EL_METHOD(6,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(6) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 7
        #if TSS_DETECT_EL_METHOD(7,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(7) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 8
        #if TSS_DETECT_EL_METHOD(8,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(8) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 9
        #if TSS_DETECT_EL_METHOD(9,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(9) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 10
        #if TSS_DETECT_EL_METHOD(10,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(10) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 11
        #if TSS_DETECT_EL_METHOD(11,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(11) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 12
        #if TSS_DETECT_EL_METHOD(12,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(12) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 13
        #if TSS_DETECT_EL_METHOD(13,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(13) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 14
        #if TSS_DETECT_EL_METHOD(14,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(14) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 15
        #if TSS_DETECT_EL_METHOD(15,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(15) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 16
        #if TSS_DETECT_EL_METHOD(16,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(16) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 17
        #if TSS_DETECT_EL_METHOD(17,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(17) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 18
        #if TSS_DETECT_EL_METHOD(18,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(18) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 19
        #if TSS_DETECT_EL_METHOD(19,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(19) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 20
        #if TSS_DETECT_EL_METHOD(20,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(20) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 21
        #if TSS_DETECT_EL_METHOD(21,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(21) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 22
        #if TSS_DETECT_EL_METHOD(22,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(22) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 23
        #if TSS_DETECT_EL_METHOD(23,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(23) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 24
        #if TSS_DETECT_EL_METHOD(24,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(24) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 25
        #if TSS_DETECT_EL_METHOD(25,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(25) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 26
        #if TSS_DETECT_EL_METHOD(26,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(26) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 27
        #if TSS_DETECT_EL_METHOD(27,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(27) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 28
        #if TSS_DETECT_EL_METHOD(28,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(28) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 29
        #if TSS_DETECT_EL_METHOD(29,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(29) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 30
        #if TSS_DETECT_EL_METHOD(30,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(30) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 31
        #if TSS_DETECT_EL_METHOD(31,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(31) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 32
        #if TSS_DETECT_EL_METHOD(32,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(32) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 33
        #if TSS_DETECT_EL_METHOD(33,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(33) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 34
        #if TSS_DETECT_EL_METHOD(34,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(34) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 35
        #if TSS_DETECT_EL_METHOD(35,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(35) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 36
        #if TSS_DETECT_EL_METHOD(36,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(36) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 37
        #if TSS_DETECT_EL_METHOD(37,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(37) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 38
        #if TSS_DETECT_EL_METHOD(38,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(38) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 39
        #if TSS_DETECT_EL_METHOD(39,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(39) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 40
        #if TSS_DETECT_EL_METHOD(40,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(40) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 41
        #if TSS_DETECT_EL_METHOD(41,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(41) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 42
        #if TSS_DETECT_EL_METHOD(42,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(42) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 43
        #if TSS_DETECT_EL_METHOD(43,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(43) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 44
        #if TSS_DETECT_EL_METHOD(44,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(44) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 45
        #if TSS_DETECT_EL_METHOD(45,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(45) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 46
        #if TSS_DETECT_EL_METHOD(46,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(46) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 47
        #if TSS_DETECT_EL_METHOD(47,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(47) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 48
        #if TSS_DETECT_EL_METHOD(48,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(48) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 49
        #if TSS_DETECT_EL_METHOD(49,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(49) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 50
        #if TSS_DETECT_EL_METHOD(50,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(50) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 51
        #if TSS_DETECT_EL_METHOD(51,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(51) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 52
        #if TSS_DETECT_EL_METHOD(52,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(52) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 53
        #if TSS_DETECT_EL_METHOD(53,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(53) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 54
        #if TSS_DETECT_EL_METHOD(54,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(54) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 55
        #if TSS_DETECT_EL_METHOD(55,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(55) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 56
        #if TSS_DETECT_EL_METHOD(56,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(56) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 57
        #if TSS_DETECT_EL_METHOD(57,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(57) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 58
        #if TSS_DETECT_EL_METHOD(58,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(58) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 59
        #if TSS_DETECT_EL_METHOD(59,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(59) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 60
        #if TSS_DETECT_EL_METHOD(60,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(60) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 61
        #if TSS_DETECT_EL_METHOD(61,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(61) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 62
        #if TSS_DETECT_EL_METHOD(62,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(62) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      #if TSS_N_ELECTRODES > 63
        #if TSS_DETECT_EL_METHOD(63,TSIL)
            const TSS_TSIL_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(63) };
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
                
      /***************************************************************************//*!
      *                                 Types 
      ****************************************************************************/
  
      /* TSIL Recalibration Struct */    
                  
      typedef struct {
        UINT8 u8TSIPS;
        UINT8 u8TSIExtChrg;          
        UINT16 u16Distance;
      } TSIL_CALIBRATION;
      
      static UINT16 tsi_au16Resolution; /* TSIL resolution */
  
      /************************** Prototypes ***************************/
      UINT8 TSIL_InitModule(void);
      UINT8 TSIL_SetNSamples(void);
      UINT8 TSIL_Recalibrate(void);
      UINT8 TSIL_InitTrigger(void);
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL General Initialization
      *
      * @param  psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitModule(void)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
  
        /* TSI_CS0 Settings */
        TSS_GET_TSIL_REGISTER(CS0) = 0; /* Erase CS0 - Turn OFF TSI*/ 
        
        /* TSI_CS2 Settings */
        TSS_GET_TSIL_REGISTER(CS2) = 0; /* Erase CS2 */
        /* Both OSC settings */
        #if TSS_TSIL_DVOLT != 0
          TSS_GET_TSIL_REGISTER(CS2) |= TSIL_CS2_DVOLT_FIT(TSS_TSIL_DVOLT);     /* Delta Voltage settings for ElOSC and RefOSC 0 = 1.03 V, 3 = 0.29 V */
        #endif
        /* TSI RefOSC definitions */
        TSS_GET_TSIL_REGISTER(CS2) |= TSIL_CS2_REFCHRG_FIT(TSS_TSIL_REFCHRG);   /* Reference Oscillator Charge Current 0 = 500 nA, 7 = 64uA */ 
     
        return u8Result;
      }  
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Number of Samples Settings
      *
      * @param  psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_SetNSamples(void)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        UINT8 u8NSamples;
  
        TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module*/
        TSS_GET_TSIL_REGISTER(CS1) &= ~((UINT8)TSI_CS1_NSCN_MASK);      /* Erase NSCN */
        /* Number of Samples settings */
        u8NSamples = tss_CSSys.NSamples;
        TSS_GET_TSIL_REGISTER(CS1) |= TSIL_CS1_NSCN_FIT(u8NSamples-1u);  /* Number of Consecutive Scans per Electrode 0 = 1 scan, 31 = 32 scans*/
        
        return u8Result;
      }  
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Recalibration
      *
      * @param  *psMethodROMDataStruct - Specification of ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      #if ((TSS_TSIL_EXTCHRG_RANGE == 1) && (TSS_TSIL_PS_RANGE == 1))  
        UINT8 TSIL_Recalibrate(void)
        {
          UINT8 u8Result = TSS_INIT_STATUS_OK;

          TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module */
          TSS_GET_TSIL_REGISTER(CS1) &= ~((UINT8)TSI_CS1_PS_MASK);        /* Erase PS */
          TSS_GET_TSIL_REGISTER(CS1) |= TSIL_CS1_PS_FIT(TSS_TSIL_PS_LOW_LIMIT); /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
          TSS_GET_TSIL_REGISTER(CS2) &= ~((UINT8)TSI_CS2_EXTCHRG_MASK);   /* Erase ExtChrg */
          TSS_GET_TSIL_REGISTER(CS2) |= TSIL_CS2_EXTCHRG_FIT(TSS_TSIL_EXTCHRG_LOW_LIMIT); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
          
          tsi_au16Resolution = TSS_TSIL_RESOLUTION_VALUE;   /* Store the resolution value */
          
          return u8Result;
        }  
      #else
        #ifdef TSS_ONPROXIMITY_CALLBACK
          UINT8 TSIL_Recalibrate(void)
          {
            TSIL_CALIBRATION FinalTSICalibration;
            TSIL_CALIBRATION FinalTSICalibrationBelow;
            TSIL_CALIBRATION TempTSICalibration;
            TSIL_CALIBRATION OldTSICalibration;
            UINT8 u8Result = TSS_INIT_STATUS_OK;
            UINT8 u8ElCounter;
            UINT8 u8TSIPSTemp;
            UINT8 u8TSIExtChrgTemp;
            UINT8 u8CalibrationComplete;
            UINT16 u16CapSampleTemp;
            UINT8 u8Iteration;
            UINT16 u16CapSampleAverage;
            UINT8 u8FinalTSICalibrationFound;
          #if defined(TSS_ONPROXIMITY_CALLBACK) || TSS_LOWPOWER_USED          
            UINT8 u8Temp;
          #endif
            UINT16 u16ResolutionValue;
            UINT8 u8EXTCHRGRange;
            UINT8 u8PSHighLimit;
            UINT8 u8Found;
            
            /* Save previous TSI Calibration */
            OldTSICalibration.u8TSIPS = (UINT8) ((TSS_GET_TSIL_REGISTER(CS1) & TSI_CS1_PS_MASK) >> TSI_CS1_PS_BITNUM);
            OldTSICalibration.u8TSIExtChrg = (UINT8) ((TSS_GET_TSIL_REGISTER(CS2) & TSI_CS2_EXTCHRG_MASK) >> TSI_CS2_EXTCHRG_BITNUM);
            /* Set Variables */
            if (tss_CSSys.SystemConfig.ProximityEn)
            {
              u16ResolutionValue = TSS_TSIL_PROX_RESOLUTION_VALUE;
              u8EXTCHRGRange = TSS_TSIL_PROX_EXTCHRG_RANGE;
              u8PSHighLimit = TSS_TSIL_PROX_PS_HIGH_LIMIT;        
              u8TSIPSTemp = TSS_TSIL_PROX_PS_LOW_LIMIT;
            }else{
              u16ResolutionValue = TSS_TSIL_RESOLUTION_VALUE;
              u8EXTCHRGRange = TSS_TSIL_EXTCHRG_RANGE;
              u8PSHighLimit = TSS_TSIL_PS_HIGH_LIMIT;
              u8TSIPSTemp = TSS_TSIL_PS_LOW_LIMIT;
            }
            /* Do Autocalibration */ 
            FinalTSICalibration.u16Distance = 0xFFFFu;
            FinalTSICalibrationBelow.u16Distance = 0xFFFFu;
            u8FinalTSICalibrationFound = 0u;
            /* Set TSI registers for Single measurement */
            TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module */ 
            TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIIEN_MASK);    /* Disable Interrupts */
            TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_STM_MASK);    /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
            /* Check if all electrodes has proper Counter value */
            do {
              u8TSIExtChrgTemp = TSS_TSIL_EXTCHRG_LOW_LIMIT + (u8EXTCHRGRange / 2u);
              u8Iteration = 0u;        
              TempTSICalibration.u16Distance = 0xFFFFu;
              u8Found = 0u;
              do {
                /* Increase iteration level */
                u8Iteration += 1u;
                /* Check if all electrodes has proper Counter value */
                u8CalibrationComplete = 1u;
                u16CapSampleAverage = 0u;              
                /* Go through all enabled pins */
                for(u8ElCounter = 0u; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) 
                {
                  if (TSS_GET_MODULE_ID(TSS_TSIL_MAIN_MODULE_NAME) == ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ModuleID)
                  {
                    u8Temp = TSS_INIT_STATUS_OK;
                    if (tss_CSSys.SystemConfig.ProximityEn || tss_CSSys.SystemConfig.LowPowerEn)
                    {
                      if (u8ElCounter == tss_CSSys.LowPowerElectrode)
                      {
                        u8Temp = TSS_INIT_STATUS_LOWPOWER_SET;
                      }
                    } else if (tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & ( 1u << (u8ElCounter & 0x07u)))
                    {
                      u8Temp = TSS_INIT_STATUS_LOWPOWER_SET;                  
                    }
                    /* Read TSI Counter if allowed */
                    if (u8Temp == TSS_INIT_STATUS_LOWPOWER_SET)
                    {
                      /* Configure TSIL */
                      TSS_GET_TSIL_REGISTER(CS1) &= ~((UINT8)TSI_CS1_PS_MASK);      /* Erase PS */
                      TSS_GET_TSIL_REGISTER(CS1) |= TSIL_CS1_PS_FIT(u8TSIPSTemp);   /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
                      TSS_GET_TSIL_REGISTER(CS2) &= ~((UINT8)TSI_CS2_EXTCHRG_MASK); /* Erase ExtChrg */
                      TSS_GET_TSIL_REGISTER(CS2) |= TSIL_CS2_EXTCHRG_FIT(u8TSIExtChrgTemp); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
                      /* Read TSI Counter */
                      u16CapSampleTemp = tss_faSampleElectrodeLow[u8ElCounter]();             /* Samples one electrode */
                      if (u16CapSampleTemp < u16ResolutionValue) 
                      {
                        u8CalibrationComplete = 0u; /* Capacitance value is small */
                      }
                        if (u16CapSampleAverage == 0u)
                        {
                          u16CapSampleAverage = u16CapSampleTemp;
                        } else {
                          u16CapSampleAverage = (u16CapSampleAverage >> 1u) + (u16CapSampleTemp >> 1u);
                        }
                    }
                  } 
                }
                /* Evaluate Measurement - Reuse of u16CapSampleTemp */
                if(u16CapSampleAverage > u16ResolutionValue )
                {
                  u16CapSampleTemp = u16CapSampleAverage - u16ResolutionValue;
                } else {
                  u16CapSampleTemp = u16ResolutionValue - u16CapSampleAverage;
                }
                
                /* All samples > resolution AND (Avarage > resolution OR already found and tune it) */
                if ((u8CalibrationComplete == 1u ) && ((u16CapSampleAverage > u16ResolutionValue) || (u8Found && (TempTSICalibration.u16Distance >= u16CapSampleTemp)))) 
                {
                  TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                  TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                  TempTSICalibration.u16Distance = u16CapSampleTemp;
                  u8Found++; /* Match for set PS found */ 
                } else if (TempTSICalibration.u16Distance >= u16CapSampleTemp && (u8Found ==0))  
                {
                  TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                  TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                  TempTSICalibration.u16Distance = u16CapSampleTemp;
                }
                /* Change ExtCharge within the interval */
                if(u8CalibrationComplete == 1u)
                {
                    u8TSIExtChrgTemp += ((u8EXTCHRGRange / 2u) >> u8Iteration);
                }
                else
                {
                    u8TSIExtChrgTemp -= ((u8EXTCHRGRange / 2u) >> u8Iteration);
                }
              } while (((u8EXTCHRGRange / 2u) >> u8Iteration) > 0u);
            /* The value only if a distance is lower and was found with sufficient resolution */
            if ((FinalTSICalibration.u16Distance >= TempTSICalibration.u16Distance) && (u8Found > 0))
            {
              FinalTSICalibration.u8TSIPS = TempTSICalibration.u8TSIPS;
              FinalTSICalibration.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
              FinalTSICalibration.u16Distance = TempTSICalibration.u16Distance;
              u8FinalTSICalibrationFound++;
            } else if (FinalTSICalibrationBelow.u16Distance >= TempTSICalibration.u16Distance && u8FinalTSICalibrationFound == 0)
            {
              /* Calibration not sufficient to the set resolution */
              FinalTSICalibrationBelow.u8TSIPS = TempTSICalibration.u8TSIPS;
              FinalTSICalibrationBelow.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
              FinalTSICalibrationBelow.u16Distance = TempTSICalibration.u16Distance;
            }
            
            u8TSIPSTemp++; /* Increment PS current */
            } while (u8TSIPSTemp < (u8PSHighLimit + 1u)); 
            
            /* Check if searching was succesful */
            if (u8FinalTSICalibrationFound)
            {  
              tsi_au16Resolution = u16ResolutionValue;  /* Store the resolution value */
            } else {
              FinalTSICalibration.u8TSIPS = FinalTSICalibrationBelow.u8TSIPS;
              FinalTSICalibration.u8TSIExtChrg = FinalTSICalibrationBelow.u8TSIExtChrg;
              /* Reuse of u8Iteration & u16CapSampleTemp*/
              u8Iteration = 0u;  
              u16CapSampleTemp = u16ResolutionValue - FinalTSICalibrationBelow.u16Distance;
              /* Determine TSS Resolution (highest bit set) */
              while (u16CapSampleTemp >> u8Iteration)
              {
                u8Iteration++;
              }
              /* Store the present resolution value */
              tsi_au16Resolution = (1u << (UINT8)(u8Iteration - 1u)); 
            } 
              /* Set Final Found values */                
              TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module */
              TSS_GET_TSIL_REGISTER(CS1) &= ~((UINT8)TSI_CS1_PS_MASK);        /* Erase PS */
              TSS_GET_TSIL_REGISTER(CS1) |= TSIL_CS1_PS_FIT(FinalTSICalibration.u8TSIPS); /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
              TSS_GET_TSIL_REGISTER(CS2) &= ~((UINT8)TSI_CS2_EXTCHRG_MASK);   /* Erase ExtChrg */
              TSS_GET_TSIL_REGISTER(CS2) |= TSIL_CS2_EXTCHRG_FIT(FinalTSICalibration.u8TSIExtChrg); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
              /* Save Value for Proximity function */
              if (tss_CSSys.SystemConfig.ProximityEn)
              {
                tss_u16CapSample = FinalTSICalibration.u16Distance + u16ResolutionValue;
              }
              /* Indication of changed configuration */
              if ((OldTSICalibration.u8TSIPS != FinalTSICalibration.u8TSIPS) || (OldTSICalibration.u8TSIExtChrg != FinalTSICalibration.u8TSIExtChrg))
              {
                u8Result |= TSS_INIT_STATUS_CALIBRATION_CHANGED;    
              }            
      
            return u8Result;
          }
        #else        
          UINT8 TSIL_Recalibrate(void)
          {
            TSIL_CALIBRATION FinalTSICalibration;
            TSIL_CALIBRATION FinalTSICalibrationBelow;
            TSIL_CALIBRATION TempTSICalibration;
            TSIL_CALIBRATION OldTSICalibration;
            UINT8 u8result = TSS_INIT_STATUS_OK;
            UINT8 u8ElCounter;
            UINT8 u8TSIPSTemp;
            UINT8 u8TSIExtChrgTemp;
            UINT8 u8CalibrationComplete;
            UINT16 u16CapSampleTemp;
            UINT8 u8Iteration;
            UINT16 u16CapSampleAverage;
            UINT8 u8FinalTSICalibrationFound;
            UINT8 u8Found;
            
            /* Save previous TSI Calibration */
            OldTSICalibration.u8TSIPS = (UINT8) ((TSS_GET_TSIL_REGISTER(CS1) & TSI_CS1_PS_MASK) >> TSI_CS1_PS_BITNUM);
            OldTSICalibration.u8TSIExtChrg = (UINT8) ((TSS_GET_TSIL_REGISTER(CS2) & TSI_CS2_EXTCHRG_MASK) >> TSI_CS2_EXTCHRG_BITNUM);
            /* Do Autocalibration */ 
            u8TSIPSTemp = TSS_TSIL_PS_LOW_LIMIT;
            FinalTSICalibration.u16Distance = 0xFFFFu;
            FinalTSICalibrationBelow.u16Distance = 0xFFFFu;
            u8FinalTSICalibrationFound = 0u;
            /* Set TSI registers for Single measurement */
            TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module */ 
            TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIIEN_MASK);    /* Disable Interrupts */
            TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_STM_MASK);    /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
            /* Check if all electrodes has proper Counter value */
            do {
              #if (TSS_TSIL_EXTCHRG_RANGE > 1)
                u8TSIExtChrgTemp = TSS_TSIL_EXTCHRG_LOW_LIMIT + (TSS_TSIL_EXTCHRG_RANGE / 2u);
              #else
                u8TSIExtChrgTemp = TSS_TSIL_EXTCHRG_LOW_LIMIT;
              #endif
              u8Iteration = 0u;        
              TempTSICalibration.u16Distance = 0xFFFFu;
              u8Found = 0u;
            #if (TSS_TSIL_EXTCHRG_RANGE > 1)            
              do {
            #endif
                /* Increase iteration level */
                u8Iteration += 1u;
                /* Check if all electrodes has proper Counter value */
                u8CalibrationComplete = 1u;
                u16CapSampleAverage = 0u;              
                /* Go through all enabled pins */
                for(u8ElCounter = 0u; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) 
                {
                  if (TSS_GET_MODULE_ID(TSS_TSIL_MAIN_MODULE_NAME) == ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ModuleID)
                  {
                    if (tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & ( 1u << (u8ElCounter & 0x07u)))
                    {
                      /* Configure TSIL */
                      TSS_GET_TSIL_REGISTER(CS1) &= ~((UINT8)TSI_CS1_PS_MASK);      /* Erase PS */
                      TSS_GET_TSIL_REGISTER(CS1) |= TSIL_CS1_PS_FIT(u8TSIPSTemp);    /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
                      TSS_GET_TSIL_REGISTER(CS2) &= ~((UINT8)TSI_CS2_EXTCHRG_MASK); /* Erase ExtChrg */
                      TSS_GET_TSIL_REGISTER(CS2) |= TSIL_CS2_EXTCHRG_FIT(u8TSIExtChrgTemp); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
                     
                      /* Read TSI Counter */
                      u16CapSampleTemp = tss_faSampleElectrodeLow[u8ElCounter]();             /* Samples one electrode */
                      if (u16CapSampleTemp < TSS_TSIL_RESOLUTION_VALUE) 
                      {
                        u8CalibrationComplete = 0u; /* Capacitance value is small */
                      }
                      if (u16CapSampleAverage == 0u)
                      {
                        u16CapSampleAverage = u16CapSampleTemp;
                      } else {
                        u16CapSampleAverage = (u16CapSampleAverage >> 1u) + (u16CapSampleTemp >> 1u);
                      }
                    }
                  } 
                }
                /* Evaluate Measurement - Reuse of u16CapSampleTemp */
                if(u16CapSampleAverage > TSS_TSIL_RESOLUTION_VALUE )
                {
                  u16CapSampleTemp = u16CapSampleAverage - TSS_TSIL_RESOLUTION_VALUE;
                } else {
                  u16CapSampleTemp = TSS_TSIL_RESOLUTION_VALUE - u16CapSampleAverage;
                }
                
                /* All samples > resolution AND (Average > resolution OR already found and tune it) */
                if ((u8CalibrationComplete == 1u ) && ((u16CapSampleAverage > TSS_TSIL_RESOLUTION_VALUE) || (u8Found && (TempTSICalibration.u16Distance >= u16CapSampleTemp)))) 
                {
                  TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                  TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                  TempTSICalibration.u16Distance = u16CapSampleTemp;
                  u8Found++; /* Match for set PS found */ 
                } else if ((TempTSICalibration.u16Distance >= u16CapSampleTemp) && (u8Found ==0))  
                {
                  TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                  TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                  TempTSICalibration.u16Distance = u16CapSampleTemp;
                }
            #if (TSS_TSIL_EXTCHRG_RANGE > 1)
                /* Change ExtCharge within the interval */
                if(u8CalibrationComplete == 1u)
                {
                  u8TSIExtChrgTemp += ((TSS_TSIL_EXTCHRG_RANGE / 2u) >> u8Iteration);
                }
                else
                {
                  u8TSIExtChrgTemp -= ((TSS_TSIL_EXTCHRG_RANGE / 2u) >> u8Iteration);
                }          
            #endif
              } while (((TSS_TSIL_EXTCHRG_RANGE / 2u) >> u8Iteration) > 0u);
                     
              /* The value only if a distance is lower and was found with sufficient resolution */
              if ((FinalTSICalibration.u16Distance >= TempTSICalibration.u16Distance) && (u8Found > 0))
              {
                FinalTSICalibration.u8TSIPS = TempTSICalibration.u8TSIPS;
                FinalTSICalibration.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
                FinalTSICalibration.u16Distance = TempTSICalibration.u16Distance;
                u8FinalTSICalibrationFound++;
              } else if ((FinalTSICalibrationBelow.u16Distance >= TempTSICalibration.u16Distance) && (u8FinalTSICalibrationFound == 0))
              {
                /* Calibration not sufficient to the set resolution */
                FinalTSICalibrationBelow.u8TSIPS = TempTSICalibration.u8TSIPS;
                FinalTSICalibrationBelow.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
                FinalTSICalibrationBelow.u16Distance = TempTSICalibration.u16Distance;
              }
            
              u8TSIPSTemp++; /* Increment PS current */
            } while (u8TSIPSTemp < (TSS_TSIL_PS_HIGH_LIMIT + 1u)); 
            
            /* Check if searching was succesful */
            if (u8FinalTSICalibrationFound)
            {  
              tsi_au16Resolution = TSS_TSIL_RESOLUTION_VALUE;
            } else {
              FinalTSICalibration.u8TSIPS = FinalTSICalibrationBelow.u8TSIPS;
              FinalTSICalibration.u8TSIExtChrg = FinalTSICalibrationBelow.u8TSIExtChrg;
              /* Reuse of u8Iteration & u16CapSampleTemp */
              u8Iteration = 0u;  
              u16CapSampleTemp = TSS_TSIL_RESOLUTION_VALUE - FinalTSICalibrationBelow.u16Distance;
              /* Determine TSS Resolution (highest bit set) */
              while (u16CapSampleTemp >> u8Iteration)
              {
                u8Iteration++;
              }
              /* Store the present resolution value */
              tsi_au16Resolution = (1u << (u8Iteration - 1u));  
            }
            
            /* Set Final Found values */                
            TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module */
            TSS_GET_TSIL_REGISTER(CS1) &= ~((UINT8)TSI_CS1_PS_MASK);        /* Erase PS */
            TSS_GET_TSIL_REGISTER(CS1) |= TSIL_CS1_PS_FIT(FinalTSICalibration.u8TSIPS); /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
            TSS_GET_TSIL_REGISTER(CS2) &= ~((UINT8)TSI_CS2_EXTCHRG_MASK);   /* Erase ExtChrg */
            TSS_GET_TSIL_REGISTER(CS2) |= TSIL_CS2_EXTCHRG_FIT(FinalTSICalibration.u8TSIExtChrg); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
            /* Indication of changed configuration */
            if ((OldTSICalibration.u8TSIPS != FinalTSICalibration.u8TSIPS) || (OldTSICalibration.u8TSIExtChrg != FinalTSICalibration.u8TSIExtChrg))
            {
              u8result |= TSS_INIT_STATUS_CALIBRATION_CHANGED;    
            }            
      
          return u8result;
          }
        #endif          
      #endif    
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSI Trigger Settings
      *
      * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
      *         psModuleStruct - Specification of TSI module
      *         *psMethodRAMDataStruct - Specificcation of RAMDATA Struct
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitTrigger(void)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        
        TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIEN_MASK); /* Turn OFF TSI Module */
        /* Setup TSI */       
        TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_STM_MASK);     /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
        TSS_GET_TSIL_REGISTER(CS0) &= ~((UINT8)TSI_CS0_TSIIEN_MASK);  /* TSI Interrupt Disable (0 = disabled, 1 = enabled) */
        
        u8Result |= TSS_INIT_STATUS_TRIGGER_SET;
  
        return u8Result;
      }
      
      /***************************************************************************//*!
      *
      * @brief  Initializes the modules for the sensing of the electrodes
      *
      * @param  UINT8 u8ElNum - Processed Electrode Number  
      *         UINT8 u8Command - Command intended to process
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_MethodControl(UINT8 u8Command)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;

        /************* Do TSIL Init *******************/
        if (u8Command == TSS_INIT_COMMAND_INIT_MODULES)
        {    
          u8Result |= TSIL_InitModule();
          u8Result |= TSIL_SetNSamples();
          u8Result |= TSIL_Recalibrate();  
          u8Result |= TSIL_InitTrigger(); 
        } 
        /************* Set NSamples ***************/
        else if (u8Command == TSS_INIT_COMMAND_SET_NSAMPLES)
        {
          u8Result |= TSIL_SetNSamples();
          u8Result |= TSIL_Recalibrate();
          u8Result |= TSIL_InitTrigger(); 
        }
        /*************** Do Auto calibration setting of TSIL EXTCHRG and TSIL PS **************/      
        else if (u8Command == TSS_INIT_COMMAND_RECALIBRATE)
        {
          u8Result |= TSIL_Recalibrate();
          u8Result |= TSIL_InitTrigger();        
        }      
        /************* Triggering Init ************/
        else if (u8Command == TSS_INIT_COMMAND_INIT_TRIGGER)
        {  
          u8Result |= TSIL_InitTrigger();
        } 
        
        /* Exit */                   
                       
        return u8Result;
      }
        
      /***************************************************************************//*!
      *
      * @brief  Initializes the modules for the sensing of the electrodes
      *
      * @param  Nothing
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_SensorInit(UINT8 u8Command)
      {
          UINT8 u8Result = TSS_INIT_STATUS_OK;
  
          u8Result = TSIL_MethodControl(u8Command);
          
          return u8Result;
      }              
      
      /***************************************************************************//*!
      *
      * @brief  Performs a valid reading of one electrode stores the timer values 
      *         and returns a status code
      *
      * @param  u8ElecNum Electrode number to be scanned
      *         u8Command Requested command
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_SampleElectrode(UINT8 u8ElecNum, UINT8 u8Command)
      {
        UINT8 u8ElCounter;
        UINT8 u8ModuleID;
        UINT8 u8ElectrodeStatus;  

        u8ModuleID = ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElecNum]))->tsil_cu8ModuleID;
        /* Module Control */
        if (u8Command == TSS_SAMPLE_COMMAND_RESTART) 
        {
          u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
        } else if (u8Command == TSS_SAMPLE_COMMAND_PROCESS) 
        {
        #ifdef _TSS_TEST
          _TSS_TSIGEN_ON;                              /* Start generator for test purpose */
        #endif
        	tss_u16CapSample = tss_faSampleElectrodeLow[u8ElecNum]();             /* Samples one electrode */
        #ifdef _TSS_TEST
          _TSS_TSIGEN_OFF;                              /* Stop generator for test purpose */
        #endif
          if (tss_u16CapSample > TSS_TSIL_CAP_HIGH_LIMIT(tsi_au16Resolution))
          {      
            u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;    /* Too High Capacity is detected */
          } else if (tss_u16CapSample > TSS_TSIL_RECALIBRATION_HIGH_THRESHOLD(tsi_au16Resolution))
          {      
            u8ElectrodeStatus = TSS_SAMPLE_RECALIB_REQUEST_HICAP;   /* Re-calibration is needed */
          }else if (tss_u16CapSample < TSS_TSIL_CAP_LOW_LIMIT(tsi_au16Resolution)) 
          {  
            u8ElectrodeStatus = TSS_SAMPLE_ERROR_SMALL_CAP;         /* Too Low Capacity is detected */
          } 
          else if (tss_u16CapSample < TSS_TSIL_RECALIBRATION_LOW_THRESHOLD(tsi_au16Resolution)) 
          {  
            u8ElectrodeStatus = TSS_SAMPLE_RECALIB_REQUEST_LOCAP;   /* Re-calibration is needed */
          } else {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
          }
  
        }
        else if (u8Command == TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE) 
        {
          /* Find the next electrode within the electrode module */
          u8ElCounter = u8ElecNum;
          #if TSS_N_ELECTRODES > 1          
            do {
              if (u8ElCounter < (TSS_N_ELECTRODES-1)) 
              {
                u8ElCounter++;
              } else {
                u8ElCounter = 0u;
              }  
            } while (u8ModuleID != ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ModuleID);
          #endif
          /* Return found electrode number */
          u8ElectrodeStatus = u8ElCounter;        
    
        } else if (u8Command == TSS_SAMPLE_COMMAND_RECALIB) 
        {
          u8ElectrodeStatus = TSIL_MethodControl(TSS_INIT_COMMAND_RECALIBRATE);
          /* Evaluate result */
          if (u8ElectrodeStatus & TSS_INIT_ERROR_RECALIB_FAULT) 
          {
            /* Fault happened, so disable actual electrode */
            u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;
          } else if (u8ElectrodeStatus & TSS_INIT_STATUS_CALIBRATION_CHANGED) 
          {
            /* Calibration changed */
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_CALIBRATION_CHANGED;
          } else 
          {
            /* Old calibration was correct */
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;  
          }
        }          
    
        return u8ElectrodeStatus;   /* Return status code */ 
        
      }
    
    #else /* TSS_USE_SIMPLE_LOW_LEVEL == 0 */
              
      /************************ Prototypes **************************/              
  
      UINT8 TSIL_MethodControl(UINT8 u8ElNum, UINT8 u8Command);
    
      /*******************  Modules definition **********************/
      #if TSS_DETECT_MODULE(TSIL)
        UINT16 TSS_TSIL_CHANNEL_COUNTER_BUFFER[16]; 
        const TSS_TSIL_METHOD_ROMDATA TSS_TSIL_METHOD_ROMDATA_CONTEXT = {TSIL_MethodControl, (UINT8*) &TSI_CS0, TSS_TSIL_CHANNEL_COUNTER_BUFFER};
        volatile TSS_TSIL_METHOD_RAMDATA TSS_TSIL_METHOD_RAMDATA_CONTEXT = {TSIL_EOSF_STATE_NONE, 0u, TSIL_SCNIP_STATE_NONE};
      #endif
      #if TSS_DETECT_MODULE(TSIL0)
        UINT16 TSS_TSIL0_CHANNEL_COUNTER_BUFFER[16];        
        const TSS_TSIL_METHOD_ROMDATA TSS_TSIL0_METHOD_ROMDATA_CONTEXT = {TSIL_MethodControl, (UINT8*) &TSI0_CS0, TSS_TSIL0_CHANNEL_COUNTER_BUFFER};    
        volatile TSS_TSIL_METHOD_RAMDATA TSS_TSIL0_METHOD_RAMDATA_CONTEXT = {TSIL_EOSF_STATE_NONE, 0u, TSIL_SCNIP_STATE_NONE};
      #endif    
      #if TSS_DETECT_MODULE(TSIL1)
        UINT16 TSS_TSIL1_CHANNEL_COUNTER_BUFFER[16];        
        const TSS_TSIL_METHOD_ROMDATA TSS_TSIL1_METHOD_ROMDATA_CONTEXT = {TSIL_MethodControl, (UINT8*) &TSI1_CS0, TSS_TSIL1_CHANNEL_COUNTER_BUFFER};    
        volatile TSS_TSIL_METHOD_RAMDATA TSS_TSIL1_METHOD_RAMDATA_CONTEXT = {TSIL_EOSF_STATE_NONE, 0u, TSIL_SCNIP_STATE_NONE};
      #endif
  
      /***************** Method Memory Data Decoding Macros **********/
          
      #define TSS_GET_TSIL_METHOD_DATA_CONTEXT_RESULT(memory,res)       TSS_##res##_METHOD_##memory##DATA_CONTEXT
      #define TSS_GET_TSIL_METHOD_DATA_CONTEXT_CONV(memory,text)        TSS_GET_TSIL_METHOD_DATA_CONTEXT_RESULT(memory,text)
      #define TSS_GET_TSIL_METHOD_DATA_CONTEXT_TYPE(memory,module)      TSS_GET_TSIL_METHOD_DATA_CONTEXT_CONV(memory,module)
    
      #define TSS_GET_TSIL_METHOD_DATA_CONTEXT(memory,el)               TSS_GET_TSIL_METHOD_DATA_CONTEXT_TYPE(memory, TSS_TSIL_EL_METHOD_MODULE_NAME(el))
        
      /***************** ROM & RAM Data definition *******************/
    
      #if TSS_N_ELECTRODES > 0
        #if TSS_DETECT_EL_METHOD(0,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,0), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,0), TSS_TSIL_EL_CHANNEL_NUM(0)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 1
        #if TSS_DETECT_EL_METHOD(1,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,1), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,1), TSS_TSIL_EL_CHANNEL_NUM(1)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 2
        #if TSS_DETECT_EL_METHOD(2,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,2), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,2), TSS_TSIL_EL_CHANNEL_NUM(2)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 3
        #if TSS_DETECT_EL_METHOD(3,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,3), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,3), TSS_TSIL_EL_CHANNEL_NUM(3)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 4
        #if TSS_DETECT_EL_METHOD(4,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,4), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,4), TSS_TSIL_EL_CHANNEL_NUM(4)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 5
        #if TSS_DETECT_EL_METHOD(5,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,5), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,5), TSS_TSIL_EL_CHANNEL_NUM(5)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 6
        #if TSS_DETECT_EL_METHOD(6,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,6), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,6), TSS_TSIL_EL_CHANNEL_NUM(6)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 7
        #if TSS_DETECT_EL_METHOD(7,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,7), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,7), TSS_TSIL_EL_CHANNEL_NUM(7)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 8
        #if TSS_DETECT_EL_METHOD(8,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,8), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,8), TSS_TSIL_EL_CHANNEL_NUM(8)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 9
        #if TSS_DETECT_EL_METHOD(9,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,9), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,9), TSS_TSIL_EL_CHANNEL_NUM(9)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 10
        #if TSS_DETECT_EL_METHOD(10,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,10), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,10), TSS_TSIL_EL_CHANNEL_NUM(10)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 11
        #if TSS_DETECT_EL_METHOD(11,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,11), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,11), TSS_TSIL_EL_CHANNEL_NUM(11)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 12
        #if TSS_DETECT_EL_METHOD(12,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,12), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,12), TSS_TSIL_EL_CHANNEL_NUM(12)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 13
        #if TSS_DETECT_EL_METHOD(13,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,13), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,13), TSS_TSIL_EL_CHANNEL_NUM(13)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 14
        #if TSS_DETECT_EL_METHOD(14,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,14), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,14), TSS_TSIL_EL_CHANNEL_NUM(14)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 15
        #if TSS_DETECT_EL_METHOD(15,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,15), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,15), TSS_TSIL_EL_CHANNEL_NUM(15)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 16
        #if TSS_DETECT_EL_METHOD(16,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,16), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,16), TSS_TSIL_EL_CHANNEL_NUM(16)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 17
        #if TSS_DETECT_EL_METHOD(17,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,17), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,17), TSS_TSIL_EL_CHANNEL_NUM(17)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 18
        #if TSS_DETECT_EL_METHOD(18,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,18), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,18), TSS_TSIL_EL_CHANNEL_NUM(18)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 19
        #if TSS_DETECT_EL_METHOD(19,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,19), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,19), TSS_TSIL_EL_CHANNEL_NUM(19)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 20
        #if TSS_DETECT_EL_METHOD(20,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,20), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,20), TSS_TSIL_EL_CHANNEL_NUM(20)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 21
        #if TSS_DETECT_EL_METHOD(21,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,21), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,21), TSS_TSIL_EL_CHANNEL_NUM(21)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 22
        #if TSS_DETECT_EL_METHOD(22,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,22), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,22), TSS_TSIL_EL_CHANNEL_NUM(22)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 23
        #if TSS_DETECT_EL_METHOD(23,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,23), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,23), TSS_TSIL_EL_CHANNEL_NUM(23)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 24
        #if TSS_DETECT_EL_METHOD(24,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,24), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,24), TSS_TSIL_EL_CHANNEL_NUM(24)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 25
        #if TSS_DETECT_EL_METHOD(25,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,25), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,25), TSS_TSIL_EL_CHANNEL_NUM(25)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 26
        #if TSS_DETECT_EL_METHOD(26,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,26), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,26), TSS_TSIL_EL_CHANNEL_NUM(26)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 27
        #if TSS_DETECT_EL_METHOD(27,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,27), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,27), TSS_TSIL_EL_CHANNEL_NUM(27)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 28
        #if TSS_DETECT_EL_METHOD(28,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,28), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,28), TSS_TSIL_EL_CHANNEL_NUM(28)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 29
        #if TSS_DETECT_EL_METHOD(29,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,29), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,29), TSS_TSIL_EL_CHANNEL_NUM(29)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 30
        #if TSS_DETECT_EL_METHOD(30,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,30), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,30), TSS_TSIL_EL_CHANNEL_NUM(30)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 31
        #if TSS_DETECT_EL_METHOD(31,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,31), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,31), TSS_TSIL_EL_CHANNEL_NUM(31)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 32
        #if TSS_DETECT_EL_METHOD(32,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,32), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,32), TSS_TSIL_EL_CHANNEL_NUM(32)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 33
        #if TSS_DETECT_EL_METHOD(33,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,33), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,33), TSS_TSIL_EL_CHANNEL_NUM(33)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 34
        #if TSS_DETECT_EL_METHOD(34,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,34), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,34), TSS_TSIL_EL_CHANNEL_NUM(34)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 35
        #if TSS_DETECT_EL_METHOD(35,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,35), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,35), TSS_TSIL_EL_CHANNEL_NUM(35)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 36
        #if TSS_DETECT_EL_METHOD(36,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,36), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,36), TSS_TSIL_EL_CHANNEL_NUM(36)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 37
        #if TSS_DETECT_EL_METHOD(37,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,37), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,37), TSS_TSIL_EL_CHANNEL_NUM(37)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 38
        #if TSS_DETECT_EL_METHOD(38,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,38), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,38), TSS_TSIL_EL_CHANNEL_NUM(38)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 39
        #if TSS_DETECT_EL_METHOD(39,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,39), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,39), TSS_TSIL_EL_CHANNEL_NUM(39)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 40
        #if TSS_DETECT_EL_METHOD(40,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,40), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,40), TSS_TSIL_EL_CHANNEL_NUM(40)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 41
        #if TSS_DETECT_EL_METHOD(41,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,41), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,41), TSS_TSIL_EL_CHANNEL_NUM(41)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 42
        #if TSS_DETECT_EL_METHOD(42,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,42), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,42), TSS_TSIL_EL_CHANNEL_NUM(42)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 43
        #if TSS_DETECT_EL_METHOD(43,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,43), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,43), TSS_TSIL_EL_CHANNEL_NUM(43)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 44
        #if TSS_DETECT_EL_METHOD(44,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,44), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,44), TSS_TSIL_EL_CHANNEL_NUM(44)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 45
        #if TSS_DETECT_EL_METHOD(45,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,45), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,45), TSS_TSIL_EL_CHANNEL_NUM(45)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 46
        #if TSS_DETECT_EL_METHOD(46,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,46), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,46), TSS_TSIL_EL_CHANNEL_NUM(46)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 47
        #if TSS_DETECT_EL_METHOD(47,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,47), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,47), TSS_TSIL_EL_CHANNEL_NUM(47)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 48
        #if TSS_DETECT_EL_METHOD(48,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,48), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,48), TSS_TSIL_EL_CHANNEL_NUM(48)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 49
        #if TSS_DETECT_EL_METHOD(49,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,49), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,49), TSS_TSIL_EL_CHANNEL_NUM(49)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 50
        #if TSS_DETECT_EL_METHOD(50,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,50), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,50), TSS_TSIL_EL_CHANNEL_NUM(50)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 51
        #if TSS_DETECT_EL_METHOD(51,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,51), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,51), TSS_TSIL_EL_CHANNEL_NUM(51)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 52
        #if TSS_DETECT_EL_METHOD(52,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,52), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,52), TSS_TSIL_EL_CHANNEL_NUM(52)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 53
        #if TSS_DETECT_EL_METHOD(53,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,53), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,53), TSS_TSIL_EL_CHANNEL_NUM(53)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 54
        #if TSS_DETECT_EL_METHOD(54,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,54), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,54), TSS_TSIL_EL_CHANNEL_NUM(54)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 55
        #if TSS_DETECT_EL_METHOD(55,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,55), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,55), TSS_TSIL_EL_CHANNEL_NUM(55)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 56
        #if TSS_DETECT_EL_METHOD(56,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,56), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,56), TSS_TSIL_EL_CHANNEL_NUM(56)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 57
        #if TSS_DETECT_EL_METHOD(57,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,57), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,57), TSS_TSIL_EL_CHANNEL_NUM(57)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 58
        #if TSS_DETECT_EL_METHOD(58,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,58), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,58), TSS_TSIL_EL_CHANNEL_NUM(58)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 59
        #if TSS_DETECT_EL_METHOD(59,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,59), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,59), TSS_TSIL_EL_CHANNEL_NUM(59)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 60
        #if TSS_DETECT_EL_METHOD(60,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,60), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,60), TSS_TSIL_EL_CHANNEL_NUM(60)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 61
        #if TSS_DETECT_EL_METHOD(61,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,61), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,61), TSS_TSIL_EL_CHANNEL_NUM(61)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 62
        #if TSS_DETECT_EL_METHOD(62,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,62), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,62), TSS_TSIL_EL_CHANNEL_NUM(62)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 63
        #if TSS_DETECT_EL_METHOD(63,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,63), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,63), TSS_TSIL_EL_CHANNEL_NUM(63)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      /***************************************************************************//*!
      *                                 Types 
      ****************************************************************************/
  
      /* TSIL Recalibration Struct */    
                  
      typedef struct {
        UINT8 u8TSIPS;
        UINT8 u8TSIExtChrg;          
        UINT16 u16Distance;
      } TSIL_CALIBRATION;
      
      static UINT16 tsi_au16Resolution; /* TSIL resolution */
  
      /************************** Prototypes ***************************/
  
      UINT8 TSIL_InitModule(TSS_TSIL_MemMapPtr psModuleStruct);
      UINT8 TSIL_SetNSamples(TSS_TSIL_MemMapPtr psModuleStruct);
      UINT8 TSIL_InitPEN(TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct);
      UINT8 TSIL_Recalibrate(TSS_TSIL_MemMapPtr psModuleStruct);
      UINT8 TSIL_InitTrigger(TSS_TSIL_MemMapPtr psModuleStruct, TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct);
      UINT8 TSIL_ReadCounter(TSS_TSIL_ELECTRODE_ROMDATA *psElectrodeROMDataStruct, TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct);
  
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL General Initialization
      *
      * @param  psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitModule(TSS_TSIL_MemMapPtr psModuleStruct)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
  
        /* TSI_CS0 Settings */
        psModuleStruct->CS0 = 0; /* Erase CS0 - Turn OFF TSI*/ 
        
        /* TSI_CS2 Settings */
        psModuleStruct->CS2 = 0; /* Erase CS2 */
        /* Both OSC settings */
        #if TSS_TSIL_DVOLT != 0
          psModuleStruct->CS2 |= TSIL_CS2_DVOLT_FIT(TSS_TSIL_DVOLT);         /* Delta Voltage settings for ElOSC and RefOSC 0 = 1.03 V, 3 = 0.29 V */
        #endif
        /* TSI RefOSC definitions */
        psModuleStruct->CS2 |= TSIL_CS2_REFCHRG_FIT(TSS_TSIL_REFCHRG);   /* Reference Oscillator Charge Current 0 = 500 nA, 7 = 64uA */ 
     
        return u8Result;
      }  
  
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Number of Samples Settings
      *
      * @param  psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_SetNSamples(TSS_TSIL_MemMapPtr psModuleStruct)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        UINT8 u8NSamples;
  
        psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module*/
        psModuleStruct->CS1 &= ~((UINT8)TSI_CS1_NSCN_MASK);      /* Erase NSCN */
        /* Number of Samples settings */
        u8NSamples = tss_CSSys.NSamples;
        psModuleStruct->CS1 |= TSIL_CS1_NSCN_FIT(u8NSamples-1u);  /* Number of Consecutive Scans per Electrode 0 = 1 scan, 31 = 32 scans*/
        
        return u8Result;
      }  
  
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Pin Enable Settings
      *
      * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitPEN(TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        UINT8 u8ElCounter;
        UINT8 u8ChannelNum;
        
        /* PEN Clearing */
        if (tss_CSSys.SystemConfig.ProximityEn || tss_CSSys.SystemConfig.LowPowerEn)
        {
          psModuleStruct->PEN.Word = 0u;
        } else {
          for(u8ElCounter = 0; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) /* Find all with the same module */
          {
            if (psMethodROMDataStruct == (TSS_TSIL_METHOD_ROMDATA *) (((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cpsMethodROMData)) 
            {
              /* Disable Electrode */
              if (!(tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter & 0x07u))))
              {  
                u8ChannelNum = ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ChannelNum;
                if ((psModuleStruct->PEN.Byte[u8ChannelNum >> 3u] & (1u << (u8ChannelNum & 0x07u))) != 0u)
                {  
                  psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK); /* Turn OFF TSI Module if TSI was enabled */     
                  /* If the Electrode is enabled then disable Electrode */ 
                  psModuleStruct->PEN.Byte[u8ChannelNum >> 3u] &= ~((UINT8)(1u << (u8ChannelNum & 0x07u)));
                }  
              }
            } 
          }
        }
        /* PEN Enabling - The loop must be performed twice because one PEN can be assigned to more TSS electrodes */
        for(u8ElCounter = 0; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) /* Find all with the same module */
        {
          if (psMethodROMDataStruct == (TSS_TSIL_METHOD_ROMDATA *) (((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cpsMethodROMData))
          {
            /* Enable Proximity & Low Power Electrode */
            if (tss_CSSys.SystemConfig.ProximityEn || tss_CSSys.SystemConfig.LowPowerEn)
            {
              if (u8ElCounter == tss_CSSys.LowPowerElectrode)
              {
                u8ChannelNum = ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ChannelNum;
                psModuleStruct->PEN.Byte[u8ChannelNum >> 3u] |= ((UINT8)(1u << (u8ChannelNum & 0x07u)));
              }
            } else {
              /* Enable Standard Electrode */
              if (tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter & 0x07u)))
              {
                u8ChannelNum = ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ChannelNum;
                if ((psModuleStruct->PEN.Byte[u8ChannelNum >> 3u] & (1u << (u8ChannelNum & 0x07u))) == 0u)
                {  
                  psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK); /* Turn OFF TSI Module if TSI was enabled */     
                  /* If the Electrode is enabled then disable Electrode */ 
                  psModuleStruct->PEN.Byte[u8ChannelNum >> 3u] |= ((UINT8)(1u << (u8ChannelNum & 0x07u)));
                }  
              }
            }
          } 
        }
        
        return u8Result;
      } 
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Recalibration
      *
      * @param  *psMethodROMDataStruct - Specification of ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      #if ((TSS_TSIL_EXTCHRG_RANGE == 1) || (TSS_TSIL_PS_RANGE == 1)) 
        UINT8 TSIL_Recalibrate(TSS_TSIL_MemMapPtr psModuleStruct)
        {
          UINT8 u8Result = TSS_INIT_STATUS_OK;
          
          psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module */
          psModuleStruct->CS1 &= ~((UINT8)TSI_CS1_PS_MASK);        /* Erase PS */
          psModuleStruct->CS1 |= TSIL_CS1_PS_FIT(TSS_TSIL_PS_LOW_LIMIT); /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
          psModuleStruct->CS2 &= ~((UINT8)TSI_CS2_EXTCHRG_MASK);   /* Erase ExtChrg */
          psModuleStruct->CS2 |= TSIL_CS2_EXTCHRG_FIT(TSS_TSIL_EXTCHRG_LOW_LIMIT); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
          
          tsi_au16Resolution = TSS_TSIL_RESOLUTION_VALUE; /* Store the resolution value */
          
          return u8Result;
        }  
      #else
        #ifdef TSS_ONPROXIMITY_CALLBACK
          UINT8 TSIL_Recalibrate(TSS_TSIL_MemMapPtr psModuleStruct)
          {
            TSIL_CALIBRATION FinalTSICalibration;
            TSIL_CALIBRATION FinalTSICalibrationBelow;
            TSIL_CALIBRATION TempTSICalibration;
            TSIL_CALIBRATION OldTSICalibration;
            UINT8 u8Result = TSS_INIT_STATUS_OK;
            UINT8 u8ElCounter;
            UINT8 u8TSIPSTemp;
            UINT8 u8TSIExtChrgTemp;
            UINT8 u8CalibrationComplete;
            UINT16 u16CapSampleTemp;
            UINT8 u8Iteration;
            UINT16 u16PENtemp;
            UINT16 u16CapSampleAverage;
            UINT8 u8FinalTSICalibrationFound;
            UINT16 u16ResolutionValue;
            UINT8 u8EXTCHRGRange;
            UINT8 u8PSHighLimit;            
            UINT8 u8Found;
            
            /* Save previous TSI Calibration */
            OldTSICalibration.u8TSIPS = (UINT8) ((psModuleStruct->CS1 & TSI_CS1_PS_MASK) >> TSI_CS1_PS_BITNUM);
            OldTSICalibration.u8TSIExtChrg = (UINT8) ((psModuleStruct->CS2 & TSI_CS2_EXTCHRG_MASK) >> TSI_CS2_EXTCHRG_BITNUM);
            /* Set Variables */
            if (tss_CSSys.SystemConfig.ProximityEn)
            {
              u16ResolutionValue = TSS_TSIL_PROX_RESOLUTION_VALUE;
              u8EXTCHRGRange = TSS_TSIL_PROX_EXTCHRG_RANGE;
              u8PSHighLimit = TSS_TSIL_PROX_PS_HIGH_LIMIT;        
              u8TSIPSTemp = TSS_TSIL_PROX_PS_LOW_LIMIT;
            }else{
              u16ResolutionValue = TSS_TSIL_RESOLUTION_VALUE;
              u8EXTCHRGRange = TSS_TSIL_EXTCHRG_RANGE;
              u8PSHighLimit = TSS_TSIL_PS_HIGH_LIMIT;
              u8TSIPSTemp = TSS_TSIL_PS_LOW_LIMIT;
            }            
            /* Do Autocalibration */ 
            FinalTSICalibration.u16Distance = 0xFFFFu;
            FinalTSICalibrationBelow.u16Distance = 0xFFFFu;
            u8FinalTSICalibrationFound = 0u;
            /* Set TSI registers for Single measurement */
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK);  /* Turn OFF TSI Module */ 
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIIEN_MASK); /* Disable Interrupts */
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_STM_MASK);    /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
            psModuleStruct->CS0 |= TSI_CS0_TSIEN_MASK;            /* Turn On TSI Module */
            /* Read enabled pins */
            u16PENtemp = ((((UINT16) psModuleStruct->PEN.Byte[1]) << 8u) | ((UINT16)psModuleStruct->PEN.Byte[0]));
            
            do {
              u8TSIExtChrgTemp = TSS_TSIL_EXTCHRG_LOW_LIMIT + (u8EXTCHRGRange / 2u);
              u8Iteration = 0u;        
              TempTSICalibration.u16Distance = 0xFFFFu;
              u8Found = 0u;
              do {
                /* Increase iteration level */
                u8Iteration += 1u;
                /* Check if all electrodes has proper Counter value */
                u8CalibrationComplete = 1u;
                u16CapSampleAverage = 0u;                
                /* Go through all enabled pins */
                for(u8ElCounter = 0u; u8ElCounter < 16u; u8ElCounter++) 
                {
                  if (u16PENtemp & (1u << u8ElCounter))
                  {
                    /* Configure TSIL */
                    psModuleStruct->CS1 &= ~((UINT8)TSI_CS1_PS_MASK);      /* Erase PS */
                    psModuleStruct->CS1 |= TSIL_CS1_PS_FIT(u8TSIPSTemp);    /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
                    psModuleStruct->CS2 &= ~((UINT8)TSI_CS2_EXTCHRG_MASK); /* Erase ExtChrg */
                    psModuleStruct->CS2 |= TSIL_CS2_EXTCHRG_FIT(u8TSIExtChrgTemp); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
                    /* Start Measurement */
                    psModuleStruct->CS3 &= ~((UINT8)TSI_CS3_TSICH_MASK);   /* Erase TSICH */
                    psModuleStruct->CS3 = TSIL_CS3_TSICH_FIT(u8ElCounter);  /* Set Channel */
                    psModuleStruct->CS0 |= TSI_CS0_SWTS_MASK;              /* Toggle SW trigger */
                    
                    #ifdef _TSS_TEST
                      _TSS_TSIGEN_ON;                                      /* Start generator for test purpose */
                    #endif
                    do {
                    /* Measurement Running */  
                    } while ((psModuleStruct->CS0 & TSI_CS0_EOSF_MASK) == 0u); /* If TSI End of Scan Flag is reported*/
                    #ifdef _TSS_TEST
                      _TSS_TSIGEN_OFF;                                     /* Stop generator */
                    #endif
                    /* Reset EOSF Flag */
                    psModuleStruct->CS0 |= TSI_CS0_EOSF_MASK;              /* Toggle EOSF flag */  
                    /* Wait for data ready */
                    #if defined(__ARMCC_VERSION)
                    __nop(); __nop();
                    #elif defined(__COSMIC_COMPILER)
                    _asm ("NOP\n"); _asm("NOP\n");
                    #else
                    asm ("NOP"); asm ("NOP");
                    #endif 
                    /* Read TSI Counter */
                    u16CapSampleTemp = psModuleStruct->CNT.Word;
                    if (u16CapSampleTemp < u16ResolutionValue) 
                    {
                      u8CalibrationComplete = 0u; /* Capacitance value is small */
                    }
                    if (u16CapSampleAverage == 0u)
                    {
                      u16CapSampleAverage = u16CapSampleTemp;
                    } else {
                      u16CapSampleAverage = (u16CapSampleAverage >> 1u) + (u16CapSampleTemp >> 1u);
                    }
                  } 
                }
              /* Evaluate Measurement - Reuse of u16ECounter */
                if(u16CapSampleAverage > u16ResolutionValue )
                {
                  u16CapSampleTemp = u16CapSampleAverage - u16ResolutionValue;
                } else {
                  u16CapSampleTemp = u16ResolutionValue - u16CapSampleAverage;
                }
                
                /* All samples > resolution AND (Average > resolution OR already found and tune it) */
                if ((u8CalibrationComplete == 1u ) && ((u16CapSampleAverage > u16ResolutionValue) || (u8Found && (TempTSICalibration.u16Distance >= u16CapSampleTemp)))) 
                {
                  TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                  TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                  TempTSICalibration.u16Distance = u16CapSampleTemp;
                  u8Found++; /* Match for set PS found */ 
                } else if (TempTSICalibration.u16Distance >= u16CapSampleTemp && (u8Found ==0))  
                {
                  TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                  TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                  TempTSICalibration.u16Distance = u16CapSampleTemp;
                }
                /* Change ExtCharge within the interval */
                if(u8CalibrationComplete == 1u)
                {
                  u8TSIExtChrgTemp += ((u8EXTCHRGRange / 2u) >> u8Iteration);
                }
                else
                {
                  u8TSIExtChrgTemp -= ((u8EXTCHRGRange / 2u) >> u8Iteration);
                }
              } while (((u8EXTCHRGRange / 2u) >> u8Iteration) > 0u);
              /* The value only if a distance is lower and was found with sufficient resolution */
              if ((FinalTSICalibration.u16Distance >= TempTSICalibration.u16Distance) && (u8Found > 0))
              {
                FinalTSICalibration.u8TSIPS = TempTSICalibration.u8TSIPS;
                FinalTSICalibration.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
                FinalTSICalibration.u16Distance = TempTSICalibration.u16Distance;
                u8FinalTSICalibrationFound++;
              } else if ((FinalTSICalibrationBelow.u16Distance >= TempTSICalibration.u16Distance) && (u8FinalTSICalibrationFound == 0))
              {
                /* Calibration not sufficient to the set resolution */
                FinalTSICalibrationBelow.u8TSIPS = TempTSICalibration.u8TSIPS;
                FinalTSICalibrationBelow.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
                FinalTSICalibrationBelow.u16Distance = TempTSICalibration.u16Distance;
              }
            
              u8TSIPSTemp++; /* Increment PS current */
            } while (u8TSIPSTemp < (u8PSHighLimit + 1u)); 
            
            /* Check if searching was succesful */
            if (u8FinalTSICalibrationFound)
            {  
              tsi_au16Resolution = u16ResolutionValue;  /* Store the resolution value */
            } else {
              FinalTSICalibration.u8TSIPS = FinalTSICalibrationBelow.u8TSIPS;
              FinalTSICalibration.u8TSIExtChrg = FinalTSICalibrationBelow.u8TSIExtChrg;
              /* Reuse of u8Iteration & u16CapSampleTemp */
              u8Iteration = 0u;  
              u16CapSampleTemp = u16ResolutionValue - FinalTSICalibrationBelow.u16Distance;
              /* Determine TSS Resolution (highest bit set) */
              while (u16CapSampleTemp >> u8Iteration)
              {
                u8Iteration++;
              }
              /* Store the present resolution value */
              tsi_au16Resolution = (1u << (UINT8)(u8Iteration - 1u));    
            }
            /* Set Final Found values */                
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module */
            psModuleStruct->CS1 &= ~((UINT8)TSI_CS1_PS_MASK);        /* Erase PS */
            psModuleStruct->CS1 |= TSIL_CS1_PS_FIT(FinalTSICalibration.u8TSIPS); /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
            psModuleStruct->CS2 &= ~((UINT8)TSI_CS2_EXTCHRG_MASK);   /* Erase ExtChrg */
            psModuleStruct->CS2 |= TSIL_CS2_EXTCHRG_FIT(FinalTSICalibration.u8TSIExtChrg); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
            /* Save Value for Proximity function */
            if (tss_CSSys.SystemConfig.ProximityEn)
            {
              tss_u16CapSample = FinalTSICalibration.u16Distance + u16ResolutionValue;
            }
            /* Indication of changed configuration */
            if ((OldTSICalibration.u8TSIPS != FinalTSICalibration.u8TSIPS) || (OldTSICalibration.u8TSIExtChrg != FinalTSICalibration.u8TSIExtChrg))
            {
              u8Result |= TSS_INIT_STATUS_CALIBRATION_CHANGED;    
            }

            return u8Result;
          }  
        #else
          UINT8 TSIL_Recalibrate(TSS_TSIL_MemMapPtr psModuleStruct)
          {
            TSIL_CALIBRATION FinalTSICalibration;
            TSIL_CALIBRATION FinalTSICalibrationBelow;
            TSIL_CALIBRATION TempTSICalibration;
            TSIL_CALIBRATION OldTSICalibration;
            UINT8 u8Result = TSS_INIT_STATUS_OK;
            UINT8 u8ElCounter;
            UINT8 u8TSIPSTemp;
            UINT8 u8TSIExtChrgTemp;
            UINT8 u8CalibrationComplete;
            UINT16 u16CapSampleTemp;
            UINT8 u8Iteration;
            UINT16 u16PENtemp;
            UINT16 u16CapSampleAverage;
            UINT8 u8FinalTSICalibrationFound;
            UINT8 u8Found;
            
            /* Save previous TSI Calibration */
            OldTSICalibration.u8TSIPS = (UINT8) ((psModuleStruct->CS1 & TSI_CS1_PS_MASK) >> TSI_CS1_PS_BITNUM);
            OldTSICalibration.u8TSIExtChrg = (UINT8) ((psModuleStruct->CS2 & TSI_CS2_EXTCHRG_MASK) >> TSI_CS2_EXTCHRG_BITNUM);
            /* Do Autocalibration */ 
            u8TSIPSTemp = TSS_TSIL_PS_LOW_LIMIT;
            FinalTSICalibration.u16Distance = 0xFFFFu;
            FinalTSICalibrationBelow.u16Distance = 0xFFFFu;
            u8FinalTSICalibrationFound = 0u;
            /* Set TSI registers for Single measurement */
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK);  /* Turn OFF TSI Module */ 
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIIEN_MASK); /* Disable Interrupts */
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_STM_MASK);    /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
            psModuleStruct->CS0 |= TSI_CS0_TSIEN_MASK;            /* Turn On TSI Module */
            /* Read enabled pins */
            u16PENtemp = ((((UINT16) psModuleStruct->PEN.Byte[1]) << 8u) | ((UINT16)psModuleStruct->PEN.Byte[0]));
            
            do {
              u8TSIExtChrgTemp = TSS_TSIL_EXTCHRG_LOW_LIMIT + (TSS_TSIL_EXTCHRG_RANGE / 2u);
              u8Iteration = 0u;        
              TempTSICalibration.u16Distance = 0xFFFFu;
              u8Found = 0u;
              do {

                /* Increase iteration level */
                u8Iteration += 1u;
                /* Check if all electrodes has proper Counter value */
                u8CalibrationComplete = 1u;
                u16CapSampleAverage = 0u;                
                /* Go through all enabled pins */
                for(u8ElCounter = 0u; u8ElCounter < 16u; u8ElCounter++) 
                {
                  if (u16PENtemp & (1u << u8ElCounter))
                  {
                    /* Configure TSIL */
                    psModuleStruct->CS1 &= ~((UINT8)TSI_CS1_PS_MASK);      /* Erase PS */
                    psModuleStruct->CS1 |= TSIL_CS1_PS_FIT(u8TSIPSTemp);    /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
                    psModuleStruct->CS2 &= ~((UINT8)TSI_CS2_EXTCHRG_MASK); /* Erase ExtChrg */
                    psModuleStruct->CS2 |= TSIL_CS2_EXTCHRG_FIT(u8TSIExtChrgTemp); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
                    /* Start Measurement */
                    psModuleStruct->CS3 &= ~((UINT8)TSI_CS3_TSICH_MASK);   /* Erase TSICH */
                    psModuleStruct->CS3 = TSIL_CS3_TSICH_FIT(u8ElCounter);  /* Set Channel */
                    psModuleStruct->CS0 |= TSI_CS0_SWTS_MASK;              /* Toggle SW trigger */
                    
                    #ifdef _TSS_TEST
                      _TSS_TSIGEN_ON;                                      /* Start generator for test purpose */
                    #endif
                    do {
                    /* Measurement Running */  
                    } while ((psModuleStruct->CS0 & TSI_CS0_EOSF_MASK) == 0u); /* If TSI End of Scan Flag is reported*/
                    #ifdef _TSS_TEST
                      _TSS_TSIGEN_OFF;                                     /* Stop generator */
                    #endif
                    /* Reset EOSF Flag */
                    psModuleStruct->CS0 |= TSI_CS0_EOSF_MASK;              /* Toggle EOSF flag */  
                    /* Wait for data ready */
                    #if defined(__ARMCC_VERSION)
                    __nop(); __nop();
                    #elif defined(__COSMIC_COMPILER)
                    _asm ("NOP\n"); _asm("NOP\n"); 
                    #else
                    asm ("NOP"); asm ("NOP");
                    #endif 
                    /* Read TSI Counter */
                    u16CapSampleTemp = psModuleStruct->CNT.Word;
                    if (u16CapSampleTemp < TSS_TSIL_RESOLUTION_VALUE) 
                    {
                      u8CalibrationComplete = 0u; /* Capacitance value is small */
                    }
                      if (u16CapSampleAverage == 0u)
                      {
                        u16CapSampleAverage = u16CapSampleTemp;
                      } else {
                        u16CapSampleAverage = (u16CapSampleAverage >> 1u) + (u16CapSampleTemp >> 1u);
                      }
                    
                  } 
                }
                /* Evaluate Measurement - Reuse of u16ECounter */
                if(u16CapSampleAverage > TSS_TSIL_RESOLUTION_VALUE )
                {
                  u16CapSampleTemp = u16CapSampleAverage - TSS_TSIL_RESOLUTION_VALUE;
                } else {
                  u16CapSampleTemp = TSS_TSIL_RESOLUTION_VALUE - u16CapSampleAverage;
                }
                
                /* All samples > resolution AND (Average > resolution OR already found and tune it) */
                if ((u8CalibrationComplete == 1u ) && ((u16CapSampleAverage > TSS_TSIL_RESOLUTION_VALUE) || (u8Found && (TempTSICalibration.u16Distance >= u16CapSampleTemp)))) 
                {
                  TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                  TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                  TempTSICalibration.u16Distance = u16CapSampleTemp;
                  u8Found++; /* Match for set PS found */ 
                } else if ((TempTSICalibration.u16Distance >= u16CapSampleTemp) && (u8Found ==0))  
                {
                  TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                  TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                  TempTSICalibration.u16Distance = u16CapSampleTemp;
                }
                /* Change ExtCharge within the interval */
                if(u8CalibrationComplete == 1u)
                {
                  u8TSIExtChrgTemp += ((TSS_TSIL_EXTCHRG_RANGE / 2u) >> u8Iteration);
                }
                else
                {
                  u8TSIExtChrgTemp -= ((TSS_TSIL_EXTCHRG_RANGE / 2u) >> u8Iteration);
                } 
              } while (((TSS_TSIL_EXTCHRG_RANGE / 2u) >> u8Iteration) > 0u);        
              /* The value only if a distance is lower and was found with sufficient resolution */
              if ((FinalTSICalibration.u16Distance >= TempTSICalibration.u16Distance) && (u8Found > 0))
              {
                FinalTSICalibration.u8TSIPS = TempTSICalibration.u8TSIPS;
                FinalTSICalibration.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
                FinalTSICalibration.u16Distance = TempTSICalibration.u16Distance;
                u8FinalTSICalibrationFound++;
              } else if ((FinalTSICalibrationBelow.u16Distance >= TempTSICalibration.u16Distance) && (u8FinalTSICalibrationFound == 0))
              {
                /* Calibration not sufficient to the set resolution */
                FinalTSICalibrationBelow.u8TSIPS = TempTSICalibration.u8TSIPS;
                FinalTSICalibrationBelow.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
                FinalTSICalibrationBelow.u16Distance = TempTSICalibration.u16Distance;
              }
            
              u8TSIPSTemp++; /* Increment PS current */
            } while (u8TSIPSTemp < (TSS_TSIL_PS_HIGH_LIMIT + 1u)); 
            
            /* Check if searching was succesful */
            if (u8FinalTSICalibrationFound)
            {  
              tsi_au16Resolution = TSS_TSIL_RESOLUTION_VALUE; /* Store the resolution value */
            } else {
              FinalTSICalibration.u8TSIPS = FinalTSICalibrationBelow.u8TSIPS;
              FinalTSICalibration.u8TSIExtChrg = FinalTSICalibrationBelow.u8TSIExtChrg;  
              /* Reuse of u8Iteration & u16CapSampleTemp */
              u8Iteration = 0u;  
              u16CapSampleTemp = TSS_TSIL_RESOLUTION_VALUE - FinalTSICalibrationBelow.u16Distance;
              /* Determine TSS Resolution (highest bit set) */
              while (u16CapSampleTemp >> u8Iteration)
              {
                u8Iteration++;
              }
              /* Store the present resolution value */
              tsi_au16Resolution = (1u << (UINT8) (u8Iteration - 1u));    
            }  
            /* Set Final Found values */                
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK);     /* Turn OFF TSI Module */
            psModuleStruct->CS1 &= ~((UINT8)TSI_CS1_PS_MASK);        /* Erase PS */
            psModuleStruct->CS1 |= TSIL_CS1_PS_FIT(FinalTSICalibration.u8TSIPS); /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
            psModuleStruct->CS2 &= ~((UINT8)TSI_CS2_EXTCHRG_MASK);   /* Erase ExtChrg */
            psModuleStruct->CS2 |= TSIL_CS2_EXTCHRG_FIT(FinalTSICalibration.u8TSIExtChrg); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
            /* Indication of changed configuration */
            if ((OldTSICalibration.u8TSIPS != FinalTSICalibration.u8TSIPS) || (OldTSICalibration.u8TSIExtChrg != FinalTSICalibration.u8TSIExtChrg))
            {
              u8Result |= TSS_INIT_STATUS_CALIBRATION_CHANGED;    
            }
            return u8Result;
          }  
        #endif
      #endif
       
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Trigger Settings
      *
      * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *         *psMethodRAMDataStruct - Specification of RAMDATA Struct
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitTrigger(TSS_TSIL_MemMapPtr psModuleStruct, TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        
        psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK); /* Turn OFF TSI Module */
        /* Setup TSI */       
        if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
        {
          psModuleStruct->CS0 |= TSI_CS0_STM_MASK;     /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
        } else /* Always & SW Mode */
        {
          psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_STM_MASK);     /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
        }
        psModuleStruct->CS0 |= TSI_CS0_TSIIEN_MASK;            /* TSI Interrupt Enable (0 = disabled, 1 = enabled) */
        psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_NONE;
        psMethodRAMDataStruct->tsil_eScanInProgressState = TSIL_SCNIP_STATE_NONE;
        
        u8Result |= TSS_INIT_STATUS_TRIGGER_SET;
  
        return u8Result;
      }  
      
      /***************************************************************************//*!
      *
      * @brief  Initializes the modules for the sensing of the electrodes
      *
      * @param  UINT8 u8ElNum - Processed Electrode Number  
      *         UINT8 u8Command - Command intended to process
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_MethodControl(UINT8 u8ElNum, UINT8 u8Command)
      {
          UINT8 u8Result = TSS_INIT_STATUS_OK;
          TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct;
          TSS_TSIL_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
          TSS_TSIL_MemMapPtr psModuleStruct;
          TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct;
  
          /* Pointers Decoding */      
          psElectrodeROMDataStruct = (TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElNum]);
          psMethodROMDataStruct = (TSS_TSIL_METHOD_ROMDATA *) (psElectrodeROMDataStruct->tsil_cpsMethodROMData);
          psModuleStruct = (TSS_TSIL_MemMapPtr) (psMethodROMDataStruct->tsil_cpsModule);
          psMethodRAMDataStruct = (TSS_TSIL_METHOD_RAMDATA *) (psElectrodeROMDataStruct->tsil_cpsMethodRAMData);
  
          /************* SWTrigger ************/
          if (u8Command == TSS_INIT_COMMAND_SW_TRIGGER)
          {  
            if (psMethodRAMDataStruct->tsil_eScanInProgressState == TSIL_SCNIP_STATE_WAIT)
            {
              psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_NONE; /* Reset EndOfScanState */
              psMethodRAMDataStruct->tsil_eScanInProgressState = TSIL_SCNIP_STATE_PROCESS; /* Set processing */
              psModuleStruct->CS0 |= TSI_CS0_SWTS_MASK; /* Toggle SW Trigger */
              u8Result |= TSS_INIT_STATUS_TRIGGER_SET;
              #ifdef _TSS_TEST
                _TSS_TSIGEN_ON;                         /* Start generator for test purpose */
              #endif
            }
          } 
          /************* Do TSIL Init *******************/
          else if (u8Command == TSS_INIT_COMMAND_INIT_MODULES)
          {    
            u8Result |= TSIL_InitModule(psModuleStruct);
            u8Result |= TSIL_SetNSamples(psModuleStruct);
            u8Result |= TSIL_InitPEN(psMethodROMDataStruct, psModuleStruct);
            u8Result |= TSIL_Recalibrate(psModuleStruct);  
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct); 
          } 
          /************* Set NSamples ***************/
          else if (u8Command == TSS_INIT_COMMAND_SET_NSAMPLES)
          {
            u8Result |= TSIL_SetNSamples(psModuleStruct);
            u8Result |= TSIL_Recalibrate(psModuleStruct);
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct); 
          }
          /*************** Do Auto calibration setting of TSIL EXTCHRG and TSIL PS **************/      
          else if (u8Command == TSS_INIT_COMMAND_RECALIBRATE)
          {
            u8Result |= TSIL_Recalibrate(psModuleStruct);
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct);        
          }      
          /************ Electrode Enablers *************/
          else if (u8Command == TSS_INIT_COMMAND_ENABLE_ELECTRODES)
          {  
            u8Result |= TSIL_InitPEN(psMethodROMDataStruct, psModuleStruct);
          }
          /************* Triggering Init ************/
          else if (u8Command == TSS_INIT_COMMAND_INIT_TRIGGER)
          {  
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct);
          } 
        
        /* Exit */                   
                       
        return u8Result;
      }
      
      /***************************************************************************//*!
      *
      * @brief  Reads TSIL capacitance counter and returns a status code
      *
      * @param  *psElectrodeROMDataStruct - Specificcation of electrode ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_ReadCounter(TSS_TSIL_ELECTRODE_ROMDATA *psElectrodeROMDataStruct, TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct)
      {
        UINT8 u8Result;  
  
        /* Read TSIL Counter */
        tss_u16CapSample = ((UINT16 *) (psMethodROMDataStruct->tsil_cpu16ChannelCounterBuffer))[psElectrodeROMDataStruct->tsil_cu8ChannelNum];
        /* Evaluation of the Measured Value */
        if (tss_u16CapSample > TSS_TSIL_CAP_HIGH_LIMIT(tsi_au16Resolution))
        {      
          u8Result = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;    /* Too High Capacity is detected */
        } else if (tss_u16CapSample > TSS_TSIL_RECALIBRATION_HIGH_THRESHOLD(tsi_au16Resolution))
        {      
          u8Result = TSS_SAMPLE_RECALIB_REQUEST_HICAP;   /* Re-calibration is needed */
        }else if (tss_u16CapSample < TSS_TSIL_CAP_LOW_LIMIT(tsi_au16Resolution)) 
        {  
          u8Result = TSS_SAMPLE_ERROR_SMALL_CAP;         /* Too Low Capacity is detected */
        } 
        else if (tss_u16CapSample < TSS_TSIL_RECALIBRATION_LOW_THRESHOLD(tsi_au16Resolution)) 
        {  
          u8Result = TSS_SAMPLE_RECALIB_REQUEST_LOCAP;   /* Re-calibration is needed */
        } else {
          u8Result = TSS_SAMPLE_STATUS_OK;
        }
        
        return u8Result;
      }
  
  
      /***************************************************************************//*!
      *
      * @brief  Performs and evalautes measurement 
      *
      * @param  *psMethodROMDataStruct - Specification of ROMDATA Struct
      *         *psMethodRAMDataStruct - Specification of RAMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_HandleMeasurement(TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct, UINT8 u8ElChannel)
      {
        UINT8 u8Result;
  
        /* Establish measurement */
        if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_ALWAYS)
        {
          if (psMethodRAMDataStruct->tsil_eEndOfScanState != TSIL_EOSF_STATE_REGULAR)
          {
            /* Init measurement */
            psMethodRAMDataStruct->tsil_u8StartElectrode = u8ElChannel;
            /* Start First Measurement */ 
            psModuleStruct->CS3 &= ~((UINT8)TSI_CS3_TSICH_MASK);   /* Erase TSICH */
            psModuleStruct->CS3 = TSIL_CS3_TSICH_FIT(u8ElChannel);  /* Set Channel */
            /* Set Status Flags */            
            psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_NONE; /* Reset EndOfScanState */
            psMethodRAMDataStruct->tsil_eScanInProgressState = TSIL_SCNIP_STATE_PROCESS; /* Set processing */
            psModuleStruct->CS0 |= TSI_CS0_SWTS_MASK;    /* Toggle SW trigger */
          } 
          u8Result = TSS_SAMPLE_STATUS_PROCESSING;
          
        } else {  /* If AUTO & SW Mode */

          /* Init measurement */
          psMethodRAMDataStruct->tsil_u8StartElectrode = u8ElChannel;
          psMethodRAMDataStruct->tsil_eScanInProgressState = TSIL_SCNIP_STATE_WAIT;
          /* Start First Measurement */ 
          psModuleStruct->CS3 &= ~((UINT8)TSI_CS3_TSICH_MASK);   /* Erase TSICH */
          psModuleStruct->CS3 = TSIL_CS3_TSICH_FIT(u8ElChannel);  /* Set Channel */
          
          if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
          {
            /* Evaluate Auto Trigger period */
            if (psMethodRAMDataStruct->tsil_eEndOfScanState == TSIL_EOSF_STATE_ERROR)
            {
              u8Result = TSS_SAMPLE_ERROR_SMALL_TRIGGER_PERIOD; /* Small TriggerModuloValue */
              psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_TSIEN_MASK); /* Disable whole TSS due triggering crash */
              #ifdef _TSS_TEST
                 _TSS_TSIGEN_OFF;                                  /* Stop generator for test purpose */
              #endif
            } else {
              u8Result = TSS_SAMPLE_STATUS_PROCESSING;
            }
            psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_NONE; /* Reset EndOfScanState */
          } else {
            u8Result = TSS_SAMPLE_STATUS_PROCESSING;
          }
        }
        #ifdef _TSS_TEST
          _TSS_TSIGEN_ON;                              /* Start generator for test purpose */
        #endif
  
        return u8Result;
      }
      
      /***************************************************************************//*!
      *
      * @brief  Performs a valid reading of one electrode stores the timer values 
      *         and returns a status code
      *
      * @param  u8ElecNum Electrode number to be scanned
      *         u8Command Requested command
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_SampleElectrode(UINT8 u8ElecNum, UINT8 u8Command)
      {
        UINT8 u8ElectrodeStatus;  
        UINT8 u8ElCounter;
        UINT8 u8ElChannel;
        
        TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct;
        TSS_TSIL_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
        TSS_TSIL_MemMapPtr psModuleStruct;
        TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct;
        
        /* Pointers decoding */
        psElectrodeROMDataStruct = (TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElecNum]);
        psMethodROMDataStruct = (TSS_TSIL_METHOD_ROMDATA *) (psElectrodeROMDataStruct->tsil_cpsMethodROMData);
        psModuleStruct = (TSS_TSIL_MemMapPtr) (psMethodROMDataStruct->tsil_cpsModule);
        psMethodRAMDataStruct = (TSS_TSIL_METHOD_RAMDATA *) (psElectrodeROMDataStruct->tsil_cpsMethodRAMData);
        u8ElChannel = psElectrodeROMDataStruct->tsil_cu8ChannelNum;
        
        /* Module Control */
        if (u8Command == TSS_SAMPLE_COMMAND_RESTART) 
        {
          /* If TSIL is disabled then enable */
          if ((psModuleStruct->CS0 & TSI_CS0_TSIEN_MASK) == 0u)
          {
            psModuleStruct->CS0 |= TSI_CS0_TSIEN_MASK;     /* Turn ON TSI Module */
          }
          /* Handle Measurement */
          if (psMethodRAMDataStruct->tsil_eScanInProgressState == TSIL_SCNIP_STATE_NONE)
          {
            u8ElectrodeStatus = TSIL_HandleMeasurement(psMethodRAMDataStruct, psModuleStruct, u8ElChannel);
          } else {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
          }
        }
        else if (u8Command == TSS_SAMPLE_COMMAND_PROCESS) 
        {
          /* If TSIL is disabled then enable */
          if ((psModuleStruct->CS0 & TSI_CS0_TSIEN_MASK) == 0u)
          {
            psModuleStruct->CS0 |= TSI_CS0_TSIEN_MASK;     /* Turn ON TSI Module */
          }
          /* Handle Auto Trigger Mode */
          if (psMethodRAMDataStruct->tsil_eScanInProgressState == TSIL_SCNIP_STATE_NONE) /* TSIL scanning is not in progress */
          {
            /* If TSI End of Scan Flag is reported */
            if (psMethodRAMDataStruct->tsil_eEndOfScanState >= TSIL_EOSF_STATE_REGULAR)
            {
              psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_PROCESS;
              #ifdef _TSS_TEST
                _TSS_TSIGEN_OFF;                                    /* Stop generator */
              #endif
              /* Read TSI Counter */
              u8ElectrodeStatus = TSIL_ReadCounter(psElectrodeROMDataStruct, psMethodROMDataStruct);
            }
            else 
            {
              u8ElectrodeStatus = TSIL_HandleMeasurement(psMethodRAMDataStruct, psModuleStruct, u8ElChannel);
            }
          } 
          else 
          {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
          }
        }
        else if (u8Command == TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE) 
        {
          /* Find the next electrode within the electrode module */
          u8ElCounter = u8ElecNum;
          #if TSS_N_ELECTRODES > 1
            do {
              if (u8ElCounter < (TSS_N_ELECTRODES-1)) 
              {
                u8ElCounter++;
              } else {
                u8ElCounter = 0u;
              }  
            } while (psMethodROMDataStruct != (TSS_TSIL_METHOD_ROMDATA *) (((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cpsMethodROMData));
          #endif          
          /* Return found electrode number */
          u8ElectrodeStatus = u8ElCounter;        
    
        } else if (u8Command == TSS_SAMPLE_COMMAND_RECALIB) 
        {
          u8ElectrodeStatus = TSIL_MethodControl(u8ElecNum, TSS_INIT_COMMAND_RECALIBRATE); 
    
          if (u8ElectrodeStatus & TSS_INIT_ERROR_RECALIB_FAULT) 
          {
            /* Fault happened, so disable actual electrode */
            u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;
          } else if (u8ElectrodeStatus & TSS_INIT_STATUS_CALIBRATION_CHANGED) 
          {
            /* Calibration changed */
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_CALIBRATION_CHANGED;
          } else 
          {
            /* Old calibration was correct */
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;  
          }
          
        } else if (u8Command == TSS_SAMPLE_COMMAND_ENABLE_ELECTRODE) 
        {
          u8ElectrodeStatus = TSIL_MethodControl(u8ElecNum, TSS_INIT_COMMAND_ENABLE_ELECTRODES); 
          
          u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
        } 
    
        return u8ElectrodeStatus;   /* Return status code */ 
        
      }
      
      /***************************************************************************//*!
      *
      * @brief  TSIL ISR routines
      *
      * @remarks
      *
      ****************************************************************************/
  
      #if TSS_DETECT_MODULE(TSIL)
       #if defined(__COSMIC_COMPILER)
        @interrupt
      #else
        interrupt        
        #if !TSS_USE_PE_COMPONENT
          VectorNumber_Vtsi
        #endif  
      #endif
        void TSS_TSIIsr(void)
        {
          TSS_TSIL_MemMapPtr psModuleStruct;
          UINT8 u8Channel; 
          UINT16 u16PEN;
          UINT8 u8Timeout;
  
          /* Pointers decoding */
          psModuleStruct = (TSS_TSIL_MemMapPtr) (TSS_TSIL_METHOD_ROMDATA_CONTEXT.tsil_cpsModule);
  
          /* Clear EOSF flag */                 
          psModuleStruct->CS0 |= TSI_CS0_EOSF_MASK;
          
          if (TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState == TSIL_EOSF_STATE_NONE)
          {
            /* Disable HW trigger */
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_STM_MASK);   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
            /* Save Actual channel */
            u8Channel = ((psModuleStruct->CS3 & TSI_CS3_TSICH_MASK) >> TSI_CS3_TSICH_BITNUM);        
            /* Read Counter */ 
            ((UINT16 *)(TSS_TSIL_METHOD_ROMDATA_CONTEXT.tsil_cpu16ChannelCounterBuffer))[u8Channel] = psModuleStruct->CNT.Word;
            /* Read PEN */
            u16PEN = ((((UINT16) psModuleStruct->PEN.Byte[1]) << 8u) | ((UINT16)psModuleStruct->PEN.Byte[0]));
            /* Find next electrode */
            u8Timeout = 18u;
            do {
              if (u8Channel < 15u)
              {
                u8Channel++;
              } else { 
                u8Channel = 0u;
              }
              u8Timeout--;
            } while (((u16PEN & (UINT16)(1u << u8Channel)) == 0u) && (u8Timeout > 0u));
            /* Evaluate */
            if (u8Channel == TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_u8StartElectrode)
            {
              #ifdef _TSS_TEST
                _TSS_TSIGEN_OFF;                                   /* Stop generator */
              #endif
              TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_REGULAR;
              TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_eScanInProgressState = TSIL_SCNIP_STATE_NONE;
              if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
              { 
                /* Enable HW trigger for period measurement in the case of AUTO trigger */
                psModuleStruct->CS0 |= TSI_CS0_STM_MASK;   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
              }
            } else {
              psModuleStruct->CS3 &= ~((UINT8)TSI_CS3_TSICH_MASK); /* Erase TSICH */
              psModuleStruct->CS3 = TSIL_CS3_TSICH_FIT(u8Channel); /* Set Channel */
              psModuleStruct->CS0 |= TSI_CS0_SWTS_MASK;            /* Toggle SW trigger */
            }
          } else {
            /* Indication of short autotrigger period */
            TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_ERROR;
          } 

          /* Set Sample Interrupted flag, because TSI measures at background and it can interrupt sampling of GPIO based methods */
          TSS_SET_SAMPLE_INTERRUPTED();
        } 
      #endif
        
      #if TSS_DETECT_MODULE(TSIL0)
       #if defined(__COSMIC_COMPILER)
        @interrupt
      #else
        interrupt        
        #if !TSS_USE_PE_COMPONENT
          VectorNumber_Vtsi0
        #endif  
      #endif
        void TSS_TSI0Isr(void)
        {
          TSS_TSIL_MemMapPtr psModuleStruct;
          UINT8 u8Channel; 
          UINT16 u16PEN;
          UINT8 u8Timeout;
          
          /* Pointers decoding */
          psModuleStruct = (TSS_TSIL_MemMapPtr) (TSS_TSIL0_METHOD_ROMDATA_CONTEXT.tsil_cpsModule);
      
          /* Clear EOSF flag */                 
          psModuleStruct->CS0 |= TSI_CS0_EOSF_MASK;
          
          if (TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState == TSIL_EOSF_STATE_NONE)
          {
            /* Disable HW trigger */
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_STM_MASK);   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
            /* Save Actual channel */
            u8Channel = ((psModuleStruct->CS3 & TSI_CS3_TSICH_MASK) >> TSI_CS3_TSICH_BITNUM);        
            /* Read Counter */ 
            ((UINT16 *)(TSS_TSIL0_METHOD_ROMDATA_CONTEXT.tsil_cpu16ChannelCounterBuffer))[u8Channel] = psModuleStruct->CNT.Word;
            /* Read PEN */
            u16PEN = ((((UINT16) psModuleStruct->PEN.Byte[1]) << 8u) | ((UINT16)psModuleStruct->PEN.Byte[0]));
            /* Find next electrode */        
            u8Timeout = 18u;
            do {
              if (u8Channel < 15u)
              {
                u8Channel++;
              } else { 
                u8Channel = 0u;
              }
              u8Timeout--;
            } while (((u16PEN & (UINT16)(1u << u8Channel)) == 0u) && (u8Timeout > 0u));
            /* Evaluate */
            if (u8Channel == TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_u8StartElectrode)
            {
              #ifdef _TSS_TEST
                _TSS_TSIGEN_OFF;                                   /* Stop generator */
              #endif
              TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_REGULAR;
              TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_eScanInProgressState = TSIL_SCNIP_STATE_NONE;
              if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
              { 
                /* Enable HW trigger for period measurement in the case of AUTO trigger */
                psModuleStruct->CS0 |= TSI_CS0_STM_MASK;   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
              }
            } else {
              psModuleStruct->CS3 &= ~((UINT8)TSI_CS3_TSICH_MASK); /* Erase TSICH */
              psModuleStruct->CS3 = TSIL_CS3_TSICH_FIT(u8Channel); /* Set Channel */
              psModuleStruct->CS0 |= TSI_CS0_SWTS_MASK;            /* Toggle SW trigger */
            }
          } else {
            /* Indication of short autotrigger period */
            TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_ERROR;
          } 
          /* Set Sample Interrupted flag, because TSIL measures at background and it can interrupt sampling of GPIO based methods */
          TSS_SET_SAMPLE_INTERRUPTED();
        } 
      #endif
        
      #if TSS_DETECT_MODULE(TSIL1)
       #if defined(__COSMIC_COMPILER)
        @interrupt
      #else
        interrupt        
        #if !TSS_USE_PE_COMPONENT
          VectorNumber_Vtsi1
        #endif  
      #endif
        void TSS_TSI1Isr(void)
        {
          TSI_MemMapPtr psModuleStruct;
          UINT8 u8Channel; 
          UINT16 u16PEN;
          UINT8 u8Timeout;
      
          /* Pointers decoding */
          psModuleStruct = (TSS_TSIL_MemMapPtr) (TSS_TSIL1_METHOD_ROMDATA_CONTEXT.tsil_cpsModule);
      
          /* Clear EOSF flag */                 
          psModuleStruct->CS0 |= TSI_CS0_EOSF_MASK;
          
          if (TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState == TSIL_EOSF_STATE_NONE)
          {
            /* Disable HW trigger */
            psModuleStruct->CS0 &= ~((UINT8)TSI_CS0_STM_MASK);   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
            /* Save Actual channel */
            u8Channel = ((psModuleStruct->CS3 & TSI_CS3_TSICH_MASK) >> TSI_CS3_TSICH_BITNUM);        
            /* Read Counter */ 
            ((UINT16 *)(TSS_TSIL1_METHOD_ROMDATA_CONTEXT.tsil_cpu16ChannelCounterBuffer))[u8Channel] = psModuleStruct->CNT.Word;
            /* Read PEN */
            u16PEN = ((((UINT16) psModuleStruct->PEN.Byte[1]) << 8u) | ((UINT16)psModuleStruct->PEN.Byte[0]));
            /* Find next electrode */        
            u8Timeout = 18u;
            do {
              if (u8Channel < 15u)
              {
                u8Channel++;
              } else { 
                u8Channel = 0u;
              }
              u8Timeout--;
            } while (((u16PEN & (UINT16)(1u << u8Channel)) == 0u) && (u8Timeout > 0u));
            /* Evaluate */
            if (u8Channel == TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_u8StartElectrode)
            {
              #ifdef _TSS_TEST
                _TSS_TSIGEN_OFF;                                   /* Stop generator */
              #endif
              TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_REGULAR;
              TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_eScanInProgressState = TSIL_SCNIP_STATE_NONE;
              if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
              { 
                /* Enable HW trigger for period measurement in the case of AUTO trigger */
                psModuleStruct->CS0 |= TSI_CS0_STM_MASK;   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
              }
            } else {
              psModuleStruct->CS3 &= ~((UINT8)TSI_CS3_TSICH_MASK); /* Erase TSICH */
              psModuleStruct->CS3 = TSIL_CS3_TSICH_FIT(u8Channel); /* Set Channel */
              psModuleStruct->CS0 |= TSI_CS0_SWTS_MASK;            /* Toggle SW trigger */
            }
          } else {
            /* Indication of short autotrigger period */
            TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_ERROR;
          } 
          /* Set Sample Interrupted flag, because TSI measures at background and it can interrupt sampling of GPIO based methods */
          TSS_SET_SAMPLE_INTERRUPTED();
        } 
      #endif
    #endif /* End of TSS_USE_SIMPLE_LOW_LEVEL == 0 */      

  #elif TSS_KINETIS_MCU || TSS_CFM_MCU

      /************************ Prototypes **************************/              
  
      UINT8 TSIL_MethodControl(UINT8 u8ElNum, UINT8 u8Command);
    
      /*******************  Modules definition **********************/
      #if TSS_DETECT_MODULE(TSIL)
        UINT16 TSS_TSIL_CHANNEL_COUNTER_BUFFER[16]; 
        const TSS_TSIL_METHOD_ROMDATA TSS_TSIL_METHOD_ROMDATA_CONTEXT = {TSIL_MethodControl, (UINT32*) TSI_BASE_PTR, TSS_TSIL_CHANNEL_COUNTER_BUFFER, INT_TSI-16, TSS_DETECT_LOWPOWER_USAGE(TSI)};
        volatile TSS_TSIL_METHOD_RAMDATA TSS_TSIL_METHOD_RAMDATA_CONTEXT = {TSIL_EOSF_STATE_NONE, 0u, TSIL_SCNIP_STATE_NONE, 0u};
      #endif
      #if TSS_DETECT_MODULE(TSIL0)
        UINT16 TSS_TSIL0_CHANNEL_COUNTER_BUFFER[16];        
        const TSS_TSIL_METHOD_ROMDATA TSS_TSIL0_METHOD_ROMDATA_CONTEXT = {TSIL_MethodControl, (UINT32*) TSI0_BASE_PTR, TSS_TSIL0_CHANNEL_COUNTER_BUFFER, INT_TSI0-16, TSS_DETECT_LOWPOWER_USAGE(TSI0)};    
        volatile TSS_TSIL_METHOD_RAMDATA TSS_TSIL0_METHOD_RAMDATA_CONTEXT = {TSIL_EOSF_STATE_NONE, 0u, TSIL_SCNIP_STATE_NONE, 0u};
      #endif    
      #if TSS_DETECT_MODULE(TSIL1)
        UINT16 TSS_TSIL1_CHANNEL_COUNTER_BUFFER[16];        
        const TSS_TSIL_METHOD_ROMDATA TSS_TSIL1_METHOD_ROMDATA_CONTEXT = {TSIL_MethodControl, (UINT32*) TSI1_BASE_PTR, TSS_TSIL1_CHANNEL_COUNTER_BUFFER, INT_TSI1-16, TSS_DETECT_LOWPOWER_USAGE(TSI1)};    
        volatile TSS_TSIL_METHOD_RAMDATA TSS_TSIL1_METHOD_RAMDATA_CONTEXT = {TSIL_EOSF_STATE_NONE, 0u, TSIL_SCNIP_STATE_NONE, 0u};
      #endif
  
      /***************** Method Memory Data Decoding Macros **********/
          
      #define TSS_GET_TSIL_METHOD_DATA_CONTEXT_RESULT(memory,res)       TSS_##res##_METHOD_##memory##DATA_CONTEXT
      #define TSS_GET_TSIL_METHOD_DATA_CONTEXT_CONV(memory,text)        TSS_GET_TSIL_METHOD_DATA_CONTEXT_RESULT(memory,text)
      #define TSS_GET_TSIL_METHOD_DATA_CONTEXT_TYPE(memory,module)      TSS_GET_TSIL_METHOD_DATA_CONTEXT_CONV(memory,module)
    
      #define TSS_GET_TSIL_METHOD_DATA_CONTEXT(memory,el)               TSS_GET_TSIL_METHOD_DATA_CONTEXT_TYPE(memory, TSS_TSIL_EL_METHOD_MODULE_NAME(el))
        
      /***************** ROM & RAM Data definition *******************/
    
      #if TSS_N_ELECTRODES > 0
        #if TSS_DETECT_EL_METHOD(0,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,0), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,0), TSS_TSIL_EL_CHANNEL_NUM(0)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 1
        #if TSS_DETECT_EL_METHOD(1,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,1), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,1), TSS_TSIL_EL_CHANNEL_NUM(1)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 2
        #if TSS_DETECT_EL_METHOD(2,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,2), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,2), TSS_TSIL_EL_CHANNEL_NUM(2)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 3
        #if TSS_DETECT_EL_METHOD(3,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,3), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,3), TSS_TSIL_EL_CHANNEL_NUM(3)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 4
        #if TSS_DETECT_EL_METHOD(4,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,4), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,4), TSS_TSIL_EL_CHANNEL_NUM(4)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 5
        #if TSS_DETECT_EL_METHOD(5,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,5), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,5), TSS_TSIL_EL_CHANNEL_NUM(5)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 6
        #if TSS_DETECT_EL_METHOD(6,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,6), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,6), TSS_TSIL_EL_CHANNEL_NUM(6)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 7
        #if TSS_DETECT_EL_METHOD(7,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,7), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,7), TSS_TSIL_EL_CHANNEL_NUM(7)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 8
        #if TSS_DETECT_EL_METHOD(8,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,8), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,8), TSS_TSIL_EL_CHANNEL_NUM(8)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 9
        #if TSS_DETECT_EL_METHOD(9,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,9), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,9), TSS_TSIL_EL_CHANNEL_NUM(9)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 10
        #if TSS_DETECT_EL_METHOD(10,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,10), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,10), TSS_TSIL_EL_CHANNEL_NUM(10)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 11
        #if TSS_DETECT_EL_METHOD(11,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,11), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,11), TSS_TSIL_EL_CHANNEL_NUM(11)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 12
        #if TSS_DETECT_EL_METHOD(12,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,12), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,12), TSS_TSIL_EL_CHANNEL_NUM(12)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 13
        #if TSS_DETECT_EL_METHOD(13,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,13), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,13), TSS_TSIL_EL_CHANNEL_NUM(13)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 14
        #if TSS_DETECT_EL_METHOD(14,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,14), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,14), TSS_TSIL_EL_CHANNEL_NUM(14)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 15
        #if TSS_DETECT_EL_METHOD(15,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,15), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,15), TSS_TSIL_EL_CHANNEL_NUM(15)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 16
        #if TSS_DETECT_EL_METHOD(16,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,16), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,16), TSS_TSIL_EL_CHANNEL_NUM(16)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 17
        #if TSS_DETECT_EL_METHOD(17,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,17), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,17), TSS_TSIL_EL_CHANNEL_NUM(17)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 18
        #if TSS_DETECT_EL_METHOD(18,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,18), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,18), TSS_TSIL_EL_CHANNEL_NUM(18)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 19
        #if TSS_DETECT_EL_METHOD(19,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,19), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,19), TSS_TSIL_EL_CHANNEL_NUM(19)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 20
        #if TSS_DETECT_EL_METHOD(20,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,20), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,20), TSS_TSIL_EL_CHANNEL_NUM(20)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 21
        #if TSS_DETECT_EL_METHOD(21,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,21), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,21), TSS_TSIL_EL_CHANNEL_NUM(21)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 22
        #if TSS_DETECT_EL_METHOD(22,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,22), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,22), TSS_TSIL_EL_CHANNEL_NUM(22)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 23
        #if TSS_DETECT_EL_METHOD(23,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,23), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,23), TSS_TSIL_EL_CHANNEL_NUM(23)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 24
        #if TSS_DETECT_EL_METHOD(24,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,24), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,24), TSS_TSIL_EL_CHANNEL_NUM(24)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 25
        #if TSS_DETECT_EL_METHOD(25,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,25), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,25), TSS_TSIL_EL_CHANNEL_NUM(25)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 26
        #if TSS_DETECT_EL_METHOD(26,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,26), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,26), TSS_TSIL_EL_CHANNEL_NUM(26)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 27
        #if TSS_DETECT_EL_METHOD(27,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,27), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,27), TSS_TSIL_EL_CHANNEL_NUM(27)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 28
        #if TSS_DETECT_EL_METHOD(28,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,28), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,28), TSS_TSIL_EL_CHANNEL_NUM(28)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 29
        #if TSS_DETECT_EL_METHOD(29,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,29), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,29), TSS_TSIL_EL_CHANNEL_NUM(29)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 30
        #if TSS_DETECT_EL_METHOD(30,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,30), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,30), TSS_TSIL_EL_CHANNEL_NUM(30)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 31
        #if TSS_DETECT_EL_METHOD(31,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,31), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,31), TSS_TSIL_EL_CHANNEL_NUM(31)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 32
        #if TSS_DETECT_EL_METHOD(32,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,32), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,32), TSS_TSIL_EL_CHANNEL_NUM(32)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 33
        #if TSS_DETECT_EL_METHOD(33,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,33), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,33), TSS_TSIL_EL_CHANNEL_NUM(33)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 34
        #if TSS_DETECT_EL_METHOD(34,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,34), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,34), TSS_TSIL_EL_CHANNEL_NUM(34)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 35
        #if TSS_DETECT_EL_METHOD(35,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,35), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,35), TSS_TSIL_EL_CHANNEL_NUM(35)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 36
        #if TSS_DETECT_EL_METHOD(36,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,36), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,36), TSS_TSIL_EL_CHANNEL_NUM(36)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 37
        #if TSS_DETECT_EL_METHOD(37,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,37), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,37), TSS_TSIL_EL_CHANNEL_NUM(37)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 38
        #if TSS_DETECT_EL_METHOD(38,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,38), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,38), TSS_TSIL_EL_CHANNEL_NUM(38)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 39
        #if TSS_DETECT_EL_METHOD(39,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,39), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,39), TSS_TSIL_EL_CHANNEL_NUM(39)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 40
        #if TSS_DETECT_EL_METHOD(40,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,40), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,40), TSS_TSIL_EL_CHANNEL_NUM(40)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 41
        #if TSS_DETECT_EL_METHOD(41,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,41), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,41), TSS_TSIL_EL_CHANNEL_NUM(41)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 42
        #if TSS_DETECT_EL_METHOD(42,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,42), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,42), TSS_TSIL_EL_CHANNEL_NUM(42)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 43
        #if TSS_DETECT_EL_METHOD(43,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,43), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,43), TSS_TSIL_EL_CHANNEL_NUM(43)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 44
        #if TSS_DETECT_EL_METHOD(44,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,44), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,44), TSS_TSIL_EL_CHANNEL_NUM(44)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 45
        #if TSS_DETECT_EL_METHOD(45,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,45), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,45), TSS_TSIL_EL_CHANNEL_NUM(45)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 46
        #if TSS_DETECT_EL_METHOD(46,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,46), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,46), TSS_TSIL_EL_CHANNEL_NUM(46)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 47
        #if TSS_DETECT_EL_METHOD(47,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,47), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,47), TSS_TSIL_EL_CHANNEL_NUM(47)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 48
        #if TSS_DETECT_EL_METHOD(48,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,48), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,48), TSS_TSIL_EL_CHANNEL_NUM(48)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 49
        #if TSS_DETECT_EL_METHOD(49,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,49), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,49), TSS_TSIL_EL_CHANNEL_NUM(49)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 50
        #if TSS_DETECT_EL_METHOD(50,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,50), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,50), TSS_TSIL_EL_CHANNEL_NUM(50)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 51
        #if TSS_DETECT_EL_METHOD(51,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,51), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,51), TSS_TSIL_EL_CHANNEL_NUM(51)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 52
        #if TSS_DETECT_EL_METHOD(52,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,52), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,52), TSS_TSIL_EL_CHANNEL_NUM(52)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 53
        #if TSS_DETECT_EL_METHOD(53,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,53), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,53), TSS_TSIL_EL_CHANNEL_NUM(53)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 54
        #if TSS_DETECT_EL_METHOD(54,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,54), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,54), TSS_TSIL_EL_CHANNEL_NUM(54)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 55
        #if TSS_DETECT_EL_METHOD(55,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,55), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,55), TSS_TSIL_EL_CHANNEL_NUM(55)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 56
        #if TSS_DETECT_EL_METHOD(56,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,56), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,56), TSS_TSIL_EL_CHANNEL_NUM(56)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 57
        #if TSS_DETECT_EL_METHOD(57,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,57), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,57), TSS_TSIL_EL_CHANNEL_NUM(57)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 58
        #if TSS_DETECT_EL_METHOD(58,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,58), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,58), TSS_TSIL_EL_CHANNEL_NUM(58)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 59
        #if TSS_DETECT_EL_METHOD(59,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,59), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,59), TSS_TSIL_EL_CHANNEL_NUM(59)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 60
        #if TSS_DETECT_EL_METHOD(60,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,60), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,60), TSS_TSIL_EL_CHANNEL_NUM(60)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 61
        #if TSS_DETECT_EL_METHOD(61,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,61), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,61), TSS_TSIL_EL_CHANNEL_NUM(61)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 62
        #if TSS_DETECT_EL_METHOD(62,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,62), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,62), TSS_TSIL_EL_CHANNEL_NUM(62)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 63
        #if TSS_DETECT_EL_METHOD(63,TSIL)
          const TSS_TSIL_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { &TSS_GET_TSIL_METHOD_DATA_CONTEXT(ROM,63), &TSS_GET_TSIL_METHOD_DATA_CONTEXT(RAM,63), TSS_TSIL_EL_CHANNEL_NUM(63)};
                TSS_TSIL_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      /***************************************************************************//*!
      *                                 Types 
      ****************************************************************************/
  
      /* TSIL Recalibration Struct */    
                  
      typedef struct {
        UINT8 u8TSIPS;
        UINT8 u8TSIExtChrg;          
        UINT16 u16Distance;
      } TSIL_CALIBRATION;
      
      #if ((TSS_TSI_EXTCHRG_RANGE != 1) || (TSS_TSI_PS_RANGE != 1) || defined(TSS_ONPROXIMITY_CALLBACK))
      static UINT16 tsi_au16Resolution; /* TSIL resolution */
      #endif
  
      /************************** Prototypes ***************************/
  
      UINT8 TSIL_InitModule(TSS_TSIL_MemMapPtr psModuleStruct);
      UINT8 TSIL_SetNSamples(TSS_TSIL_MemMapPtr psModuleStruct);
      UINT8 TSIL_InitLowPower(TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct);      
      UINT8 TSIL_InitPEN(TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct);
      UINT8 TSIL_Recalibrate(TSS_TSIL_MemMapPtr psModuleStruct, TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct);
      UINT8 TSIL_InitThresholds(TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct);      
      UINT8 TSIL_InitTrigger(TSS_TSIL_MemMapPtr psModuleStruct, TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct, TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct);
  
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL General Initialization
      *
      * @param  psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitModule(TSS_TSIL_MemMapPtr psModuleStruct)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
  
        /* TSI GENCS Settings */
        psModuleStruct->GENCS = 0u; /* Erase GENCS - Turn OFF TSI*/ 
        /* TSI DATA Settings */
        psModuleStruct->DATA = 0u; /* Erase DATA */
        /* Both OSC settings */
        #if TSS_TSIL_DVOLT != 0
          psModuleStruct->GENCS |= TSI_GENCS_DVOLT(TSS_TSIL_DVOLT);   /* Delta Voltage settings for ElOSC and RefOSC 0 = 1.03 V, 3 = 0.29 V */
        #endif
        /* TSI RefOSC definitions */
        psModuleStruct->GENCS |= TSI_GENCS_REFCHRG(TSS_TSIL_REFCHRG);   /* Reference Oscillator Charge Current 0 = 500 nA, 7 = 64uA */ 
     
        return u8Result;
      }  
  
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Number of Samples Settings
      *
      * @param  psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_SetNSamples(TSS_TSIL_MemMapPtr psModuleStruct)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        UINT8 u8NSamples;
  
        psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK);     /* Turn OFF TSI Module*/
        psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_NSCN_MASK);      /* Erase NSCN */
        /* Number of Samples settings */
        u8NSamples = tss_CSSys.NSamples;
        psModuleStruct->GENCS |= TSI_GENCS_NSCN(u8NSamples-1u);  /* Number of Consecutive Scans per Electrode 0 = 1 scan, 31 = 32 scans*/
        
        return u8Result;
      }  
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSI Low Power Settings
      *
      * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
      *         psModuleStruct - Specification of TSI module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitLowPower(TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct)
      {
        UINT8 u8result = TSS_INIT_STATUS_OK;
  
        psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK; /* Turn OFF TSI Module*/;
  
        if (psMethodROMDataStruct->tsil_u8LowPowerControlSource == 1u) /* This TSI module is Low Power Control source */
        {
          /* Low Power TSI definition */
          if (tss_CSSys.SystemConfig.LowPowerEn)
          {
            psModuleStruct->GENCS |= TSI_GENCS_STPE_MASK;     /* TSI Stop Enable while in Low Power Mode (0 = Disable TSI when in LPM, 1 = Allow run of TSI in LPM) */
          } else {
            psModuleStruct->GENCS &= ~TSI_GENCS_STPE_MASK;    /* TSI Stop Enable while in Low Power Mode (0 = Disable TSI when in LPM, 1 = Allow run of TSI in LPM) */
          }
          u8result |= TSS_INIT_STATUS_LOWPOWER_SET;           /* For Indication of state if LowPower was set */
        } else {
          /* Low Power TSI definition */
          psModuleStruct->GENCS &= ~TSI_GENCS_STPE_MASK;    /* TSI Stop Enable while in Low Power Mode (0 = Disable TSI when in LPM, 1 = Allow run of TSI in LPM) */
        }
  
        return u8result;
      }
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Pin Enable Settings
      *
      * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitPEN(TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        UINT8 u8ElCounter;
        UINT8 u8ChannelNum;
        
        /* PEN Clearing */
        if (tss_CSSys.SystemConfig.ProximityEn || tss_CSSys.SystemConfig.LowPowerEn)
        {
          psMethodRAMDataStruct->tsil_u16PEN = 0u;
        } else {
          for(u8ElCounter = 0; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) /* Find all with the same module */
          {
            if (psMethodROMDataStruct == (TSS_TSIL_METHOD_ROMDATA *) (((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cpsMethodROMData)) 
            {
              /* Disable Electrode */
              if (!(tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter & 0x07u))))
              {  
                u8ChannelNum = ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ChannelNum;
                if ((psMethodRAMDataStruct->tsil_u16PEN & (UINT16)(1u << u8ChannelNum )) != 0u)
                {  
                  psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK); /* Turn OFF TSI Module if TSI was enabled */     
                  /* If the Electrode is enabled then disable Electrode */
                  psMethodRAMDataStruct->tsil_u16PEN &= ~((UINT16)(1u << u8ChannelNum));
                }  
              }
            } 
          }
        }
        /* PEN Enabling - The loop must be performed twice because one PEN can be assigned to more TSS electrodes */
        for(u8ElCounter = 0; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) /* Find all with the same module */
        {
          if (psMethodROMDataStruct == (TSS_TSIL_METHOD_ROMDATA *) (((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cpsMethodROMData))
          {
            /* Enable Proximity & Low Power Electrode */
            if (tss_CSSys.SystemConfig.ProximityEn || tss_CSSys.SystemConfig.LowPowerEn)
            {
              if (u8ElCounter == tss_CSSys.LowPowerElectrode)
              {
                u8ChannelNum = ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ChannelNum;
                psMethodRAMDataStruct->tsil_u16PEN |= ((UINT16)(1u << u8ChannelNum));
              }
            } else {
              /* Enable Standard Electrode */
              if (tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter & 0x07u)))
              {
                u8ChannelNum = ((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cu8ChannelNum;
                if ((psMethodRAMDataStruct->tsil_u16PEN & (UINT16)(1u << u8ChannelNum )) == 0u)
                {  
                  psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK); /* Turn OFF TSI Module if TSI was enabled */     
                  /* If the Electrode is enabled then disable Electrode */ 
                  psMethodRAMDataStruct->tsil_u16PEN |= ((UINT16)(1u << u8ChannelNum));
                }  
              }
            }
          } 
        }
        
        return u8Result;
      } 
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Recalibration
      *
      * @param  *psMethodROMDataStruct - Specification of ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      #if ((TSS_TSI_EXTCHRG_RANGE != 1) || (TSS_TSI_PS_RANGE != 1) || defined(TSS_ONPROXIMITY_CALLBACK))
        UINT8 TSIL_Recalibrate(TSS_TSIL_MemMapPtr psModuleStruct, TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct)
        {
          TSIL_CALIBRATION FinalTSICalibration;
          TSIL_CALIBRATION FinalTSICalibrationBelow;
          TSIL_CALIBRATION TempTSICalibration;
          TSIL_CALIBRATION OldTSICalibration;
          UINT8 u8Result = TSS_INIT_STATUS_OK;
          UINT8 u8ElCounter;
          UINT8 u8TSIPSTemp;
          UINT8 u8TSIExtChrgTemp;
          UINT8 u8CalibrationComplete;
          UINT16 u16CapSampleTemp;
          UINT8 u8Iteration;
          UINT16 u16PENtemp;
          UINT16 u16CapSampleAverage;
          UINT8 u8FinalTSICalibrationFound;
          UINT16 u16ResolutionValue;
          UINT8 u8EXTCHRGRange;
          UINT8 u8PSHighLimit;            
          UINT8 u8Found;
          
          /* Save previous TSI Calibration */
          OldTSICalibration.u8TSIPS = (UINT8) ((psModuleStruct->GENCS & TSI_GENCS_PS_MASK) >> TSI_GENCS_PS_SHIFT);
          OldTSICalibration.u8TSIExtChrg = (UINT8) ((psModuleStruct->GENCS & TSI_GENCS_EXTCHRG_MASK) >> TSI_GENCS_EXTCHRG_SHIFT);
          /* Set Variables */
          if (tss_CSSys.SystemConfig.ProximityEn)
          {
            u16ResolutionValue = TSS_TSIL_PROX_RESOLUTION_VALUE;
            u8EXTCHRGRange = TSS_TSIL_PROX_EXTCHRG_RANGE;
            u8PSHighLimit = TSS_TSIL_PROX_PS_HIGH_LIMIT;        
            u8TSIPSTemp = TSS_TSIL_PROX_PS_LOW_LIMIT;
          }else{
            u16ResolutionValue = TSS_TSIL_RESOLUTION_VALUE;
            u8EXTCHRGRange = TSS_TSIL_EXTCHRG_RANGE;
            u8PSHighLimit = TSS_TSIL_PS_HIGH_LIMIT;
            u8TSIPSTemp = TSS_TSIL_PS_LOW_LIMIT;
          }            
          /* Do Autocalibration */ 
          FinalTSICalibration.u16Distance = 0xFFFFu;
          FinalTSICalibrationBelow.u16Distance = 0xFFFFu;
          u8FinalTSICalibrationFound = 0u;
          /* Set Universal Threshold Values for all electrodes */
          psModuleStruct->TSHD = TSI_TSHD_THRESH(TSS_TSIL_DEFAULT_HIGH_THRESHOLD ) | TSI_TSHD_THRESL(TSS_TSIL_DEFAULT_LOW_THRESHOLD );
          /* Set TSI registers for Single measurement */
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK);  /* Turn OFF TSI Module */ 
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIIEN_MASK); /* Disable Interrupts */
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_STM_MASK);    /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
          psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;            /* Turn On TSI Module */
          /* Read enabled pins */
          u16PENtemp = psMethodRAMDataStruct->tsil_u16PEN;
          /* Do Sensitivty autocalibration */
          do {
            u8TSIExtChrgTemp = TSS_TSIL_EXTCHRG_LOW_LIMIT + (u8EXTCHRGRange / 2u);
            u8Iteration = 0u;        
            TempTSICalibration.u16Distance = 0xFFFFu;
            u8Found = 0u;
            do {
              /* Increase iteration level */
              u8Iteration += 1u;
              /* Check if all electrodes has proper Counter value */
              u8CalibrationComplete = 1u;
              u16CapSampleAverage = 0u;                
              /* Go through all enabled pins */
              for(u8ElCounter = 0u; u8ElCounter < 16u; u8ElCounter++) 
              {
                if (u16PENtemp & (1u << u8ElCounter))
                {
                  /* Configure TSIL */
                  psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_PS_MASK);        /* Erase PS */
                  psModuleStruct->GENCS |= TSI_GENCS_PS(u8TSIPSTemp);    /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
                  psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_EXTCHRG_MASK);   /* Erase ExtChrg */
                  psModuleStruct->GENCS |= TSI_GENCS_EXTCHRG(u8TSIExtChrgTemp); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
                  /* Start Measurement */
                  psModuleStruct->DATA &= ~((UINT32)TSI_DATA_TSICH_MASK);  /* Erase TSICH */
                  psModuleStruct->DATA |= TSI_DATA_TSICH(u8ElCounter);      /* Set Channel */
                  psModuleStruct->DATA |= TSI_DATA_SWTS_MASK;              /* Toggle SW trigger */
                  
                  #ifdef _TSS_TEST
                    _TSS_TSIGEN_ON;                                      /* Start generator for test purpose */
                  #endif
                  do {
                  /* Measurement Running */  
                  } while ((psModuleStruct->GENCS & TSI_GENCS_EOSF_MASK) == 0u); /* If TSI End of Scan Flag is reported*/
                  #ifdef _TSS_TEST
                    _TSS_TSIGEN_OFF;                                     /* Stop generator */
                  #endif
                  /* Reset EOSF Flag */
                  psModuleStruct->GENCS |= TSI_GENCS_EOSF_MASK;              /* Toggle EOSF flag */  
                  /* Wait for data ready */
                  #if defined(__ARMCC_VERSION)
                  __nop(); __nop();
                  #else
                  asm ("NOP"); asm ("NOP");
                  #endif 
                  /* Read TSI Counter */
                  u16CapSampleTemp = (UINT16) (psModuleStruct->DATA & TSI_DATA_TSICNT_MASK);
                  if (u16CapSampleTemp < u16ResolutionValue) 
                  {
                    u8CalibrationComplete = 0u; /* Capacitance value is small */
                  }
                  if (u16CapSampleAverage == 0u)
                  {
                    u16CapSampleAverage = u16CapSampleTemp;
                  } else {
                    u16CapSampleAverage = (u16CapSampleAverage >> 1u) + (u16CapSampleTemp >> 1u);
                  }
                }
              } 
              
              /* Evaluate Measurement - Reuse of u16ECounter */
              if(u16CapSampleAverage > u16ResolutionValue )
              {
                u16CapSampleTemp = u16CapSampleAverage - u16ResolutionValue;
              } else {
                u16CapSampleTemp = u16ResolutionValue - u16CapSampleAverage;
              }
              
              /* All samples > resolution AND (Average > resolution OR already found and tune it) */
              if ((u8CalibrationComplete == 1u ) && ((u16CapSampleAverage > u16ResolutionValue) || (u8Found && (TempTSICalibration.u16Distance >= u16CapSampleTemp)))) 
              {
                TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                TempTSICalibration.u16Distance = u16CapSampleTemp;
                u8Found++; /* Match for set PS found */ 
              } else if (TempTSICalibration.u16Distance >= u16CapSampleTemp && (u8Found ==0))  
              {
                TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
                TempTSICalibration.u8TSIPS = u8TSIPSTemp;
                TempTSICalibration.u16Distance = u16CapSampleTemp;
              }
              /* Change ExtCharge within the interval */
              if(u8CalibrationComplete == 1u)
              {
                u8TSIExtChrgTemp += ((u8EXTCHRGRange / 2u) >> u8Iteration);
              }
              else
              {
                u8TSIExtChrgTemp -= ((u8EXTCHRGRange / 2u) >> u8Iteration);
              }
            } while (((u8EXTCHRGRange / 2u) >> u8Iteration) > 0u);
            /* The value only if a distance is lower and was found with sufficient resolution */
            if ((FinalTSICalibration.u16Distance >= TempTSICalibration.u16Distance) && (u8Found > 0))
            {
              FinalTSICalibration.u8TSIPS = TempTSICalibration.u8TSIPS;
              FinalTSICalibration.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
              FinalTSICalibration.u16Distance = TempTSICalibration.u16Distance;
              u8FinalTSICalibrationFound++;
            } else if ((FinalTSICalibrationBelow.u16Distance >= TempTSICalibration.u16Distance) && (u8FinalTSICalibrationFound == 0u))
            {
              /* Calibration not sufficient to the set resolution */
              FinalTSICalibrationBelow.u8TSIPS = TempTSICalibration.u8TSIPS;
              FinalTSICalibrationBelow.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
              FinalTSICalibrationBelow.u16Distance = TempTSICalibration.u16Distance;
            }
          
            u8TSIPSTemp++; /* Increment PS current */
          } while (u8TSIPSTemp < (u8PSHighLimit + 1u)); 
          
          /* Check if searching was succesful */
          if (u8FinalTSICalibrationFound)
          {
            psMethodRAMDataStruct->tsi_au16Resolution = u16ResolutionValue;  /* Store the resolution value */
          } else {
            FinalTSICalibration.u8TSIPS = FinalTSICalibrationBelow.u8TSIPS;
            FinalTSICalibration.u8TSIExtChrg = FinalTSICalibrationBelow.u8TSIExtChrg;
            /* Reuse of u8Iteration & u16CapSampleTemp */
            u8Iteration = 0u;  
            u16CapSampleTemp = u16ResolutionValue - FinalTSICalibrationBelow.u16Distance;
            /* Determine TSS Resolution (highest bit set) */
            while (u16CapSampleTemp >> u8Iteration)
            {
              u8Iteration++;
            }
            /* Store the present resolution value */
            psMethodRAMDataStruct->tsi_au16Resolution = (1u << (UINT8)(u8Iteration - 1u));    
          }
          /* Set Final Found values */                
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK);     /* Turn OFF TSI Module */
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_PS_MASK);        /* Erase PS */
          psModuleStruct->GENCS |= TSI_GENCS_PS(FinalTSICalibration.u8TSIPS); /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_EXTCHRG_MASK);   /* Erase ExtChrg */
          psModuleStruct->GENCS |= TSI_GENCS_EXTCHRG(FinalTSICalibration.u8TSIExtChrg); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
          /* Save Value for Proximity function */
          if (tss_CSSys.SystemConfig.ProximityEn)
          {
            tss_u16CapSample = FinalTSICalibration.u16Distance + u16ResolutionValue;
          }
          /* Indication of changed configuration */
          if ((OldTSICalibration.u8TSIPS != FinalTSICalibration.u8TSIPS) || (OldTSICalibration.u8TSIExtChrg != FinalTSICalibration.u8TSIExtChrg))
          {
            u8Result |= TSS_INIT_STATUS_CALIBRATION_CHANGED;    
          }
    
          return u8Result;
        }  
      #else
        UINT8 TSIL_Recalibrate(TSS_TSIL_MemMapPtr psModuleStruct)
        {
          UINT8 u8Result = TSS_INIT_STATUS_OK;
          
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK);     /* Turn OFF TSI Module */
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_PS_MASK);        /* Erase PS */
          psModuleStruct->GENCS |= TSI_GENCS_PS(TSS_TSIL_PS_LOW_LIMIT); /* Set Prescaler for Electrode OSC - Set by the user 0 = divide 1, 7 = divide 128 */
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_EXTCHRG_MASK);   /* Erase ExtChrg */
          psModuleStruct->GENCS |= TSI_GENCS_EXTCHRG(TSS_TSIL_EXTCHRG_LOW_LIMIT); /* External OSC Charge Current 0= 500nA, 7 = 64uA */
          
          tsi_au16Resolution = TSS_TSIL_RESOLUTION_VALUE; /* Store the resolution value */
          
          return u8Result;
        }  
      #endif

      /***************************************************************************//*!
      *
      * @brief  Control function for TSI Thresholds Settings
      *
      * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
      *         psModuleStruct - Specification of TSI module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitThresholds(TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct)
      {
        UINT8 u8result = TSS_INIT_STATUS_OK;
        UINT8 u8LowPowerEl;
        UINT16 u16CapSampleTemp;
        UINT8 u8LowPowerElectrodeSensitivity;
  
        psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK);  /* Turn OFF TSI Module */ 
        psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIIEN_MASK); /* Disable Interrupts */
        /* Set Universal Threshold Values for all electrodes */
        psModuleStruct->TSHD = TSI_TSHD_THRESH(TSS_TSIL_DEFAULT_HIGH_THRESHOLD ) | TSI_TSHD_THRESL(TSS_TSIL_DEFAULT_LOW_THRESHOLD );
        /* If Module is selected for Low Power Control do following */
        if (psMethodROMDataStruct->tsil_u8LowPowerControlSource == 1u) /* This TSI module is Low Power Control source */
        {
          u8LowPowerEl = tss_CSSys.LowPowerElectrode;
          /* Check if Low Power Electrode is not out of range */
          if (u8LowPowerEl < TSS_N_ELECTRODES)/* This electrode is selected as source for Low Power Control */
          {
            if ((TSS_GENERIC_METHOD_ROMDATA *) psMethodROMDataStruct == (TSS_GENERIC_METHOD_ROMDATA *)((TSS_GENERIC_ELECTRODE_ROMDATA *)tss_acp8ElectrodeROMData[u8LowPowerEl])->gen_cpsMethodROMData)
            {
                /******** Low Power Threshold Settings *********/
                /* Init TSI registers for measurement */
                psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_STM_MASK);  /* Set Scan Trigger Mode (0 = SW Trigger, 1 = Periodical Scan) */
                psModuleStruct->DATA &= ~((UINT32)TSI_DATA_TSICH_MASK);  /* Erase TSICH */
                psModuleStruct->DATA |= TSI_DATA_TSICH(((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8LowPowerEl]))->tsil_cu8ChannelNum);      /* Set Channel */
                psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;
                psModuleStruct->DATA |= TSI_DATA_SWTS_MASK;
                #ifdef _TSS_TEST
                  _TSS_TSIGEN_ON;                                      /* Start generator for test purpose */
                #endif
                do {
                /* Measurement Running */
                } while (!(psModuleStruct->GENCS & TSI_GENCS_EOSF_MASK)); /* If TSI End of Scan Flag is reported*/
                #ifdef _TSS_TEST
                  _TSS_TSIGEN_OFF;                                    /* Stop generator */
                #endif
                /* Wait for data ready */
                #if defined(__ARMCC_VERSION)
                __nop(); __nop();
                #else
                asm ("NOP"); asm ("NOP");
                #endif 
                /* Read TSI Counter */
                u16CapSampleTemp = (UINT16) (psModuleStruct->DATA & TSI_DATA_TSICNT_MASK);
                /* Calculation of Threshold values */
                u8LowPowerElectrodeSensitivity = tss_CSSys.LowPowerElectrodeSensitivity;
                /* Set Threshold for Low Power Wake up */
                psModuleStruct->TSHD = TSI_TSHD_THRESH(u16CapSampleTemp + u8LowPowerElectrodeSensitivity) | TSI_TSHD_THRESL(TSS_TSIL_DEFAULT_LOW_THRESHOLD );
                /* Result */
                u8result |= TSS_INIT_STATUS_LOWPOWER_ELEC_SET; /* For Indication of state if LowPower Electrode was found */
            }
          }
        }
  
        return u8result;
      }
      
      /***************************************************************************//*!
      *
      * @brief  Control function for TSIL Trigger Settings
      *
      * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *         *psMethodRAMDataStruct - Specification of RAMDATA Struct
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_InitTrigger(TSS_TSIL_MemMapPtr psModuleStruct, TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct, TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct)
      {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        UINT8 u8LowPowerEl;
        NVIC_MemMapPtr psNVICStruct = NVIC_BASE_PTR;

        psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK); /* Turn OFF TSI Module */
        /* Setup TSI */       
        if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
        {
          psModuleStruct->GENCS |= TSI_GENCS_STM_MASK;     /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
          /* Indication that AutoTrigger was set correctly */
          u8Result |= TSS_INIT_STATUS_AUTOTRIGGER_SET;          
        } else /* Always & SW Mode */
        {
          psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_STM_MASK);   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
          u8Result |= TSS_INIT_STATUS_TRIGGER_SET;          
        }
        psModuleStruct->GENCS |= TSI_GENCS_TSIIEN_MASK; /* TSI Interrupt Enable (0 = disabled, 1 = enabled) */
        psModuleStruct->GENCS |= TSI_GENCS_ESOR_MASK;   /* End-of-Scan|Out-of-Range Interrupt Selection (0 = Out-of-Range allow, 1 = End-of-Scan allow) */        
        /* Enable Interrupt */
        psNVICStruct->ICPR |= (1u << (psMethodROMDataStruct->tsil_u8ModuleIRQNum % 32u));
        psNVICStruct->ISER |= (1u << (psMethodROMDataStruct->tsil_u8ModuleIRQNum % 32u));
        /* Set Initial State */
        psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_NONE;
        psMethodRAMDataStruct->tsil_eScanInProgressState = TSIL_SCNIP_STATE_NONE;
        
        /* Setup Low Power */
        if ((tss_CSSys.SystemConfig.LowPowerEn) && (psMethodROMDataStruct->tsil_u8LowPowerControlSource == 1u))
        {
          /* Check if Low Power Threshold was succesfully set in the past */
          if ((psModuleStruct->TSHD & TSI_TSHD_THRESH_MASK) != TSI_TSHD_THRESH(TSS_TSIL_DEFAULT_HIGH_THRESHOLD))
          {
              /* Set Low Power electrode for measurement */
              psModuleStruct->DATA &= ~((UINT32)TSI_DATA_TSICH_MASK);  /* Erase TSICH */
              u8LowPowerEl = tss_CSSys.LowPowerElectrode;
              psModuleStruct->DATA |= TSI_DATA_TSICH(((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8LowPowerEl]))->tsil_cu8ChannelNum);      /* Set Channel */
          }
          /* Set periodic measurement mode */
          psModuleStruct->GENCS |= TSI_GENCS_STM_MASK;    /* Set Scan Trigger Mode (0 = SW Trigger, 1 = Periodical Scan) */
          /* Enable EOSF interrupt */
          psModuleStruct->GENCS &= ~TSI_GENCS_ESOR_MASK;  /* Set Out of Range interrupt (0 = Out-of-Range allow, 1 = End-of-Scan allow) */
          psModuleStruct->GENCS |= TSI_GENCS_TSIIEN_MASK;  /* TSI Interrupt Enable (0 = disabled, 1 = enabled) */
          /* TSI enable and start to periodic measurement */
          psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;  /* TSI Enable (0 = disabled, 1 = enabled) */
          /* Indication that LowPower was set correctly */
          u8Result |= TSS_INIT_STATUS_LOWPOWER_SET;       /* For Indication of state if LowPower was set */
          u8Result &= ~TSS_INIT_STATUS_TRIGGER_SET;       /* Remove status that Trigger was set correctly */
          u8Result &= ~TSS_INIT_STATUS_AUTOTRIGGER_SET;   /* Remove status that Auto Trigger was set correctly */
        }
        
        return u8Result;
      }  
      
      /***************************************************************************//*!
      *
      * @brief  Initializes the modules for the sensing of the electrodes
      *
      * @param  UINT8 u8ElNum - Processed Electrode Number  
      *         UINT8 u8Command - Command intended to process
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_MethodControl(UINT8 u8ElNum, UINT8 u8Command)
      {
          UINT8 u8Result = TSS_INIT_STATUS_OK;
          TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct;
          TSS_TSIL_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
          TSS_TSIL_MemMapPtr psModuleStruct;
          TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct;
  
          /* Pointers Decoding */      
          psElectrodeROMDataStruct = (TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElNum]);
          psMethodROMDataStruct = (TSS_TSIL_METHOD_ROMDATA *) (psElectrodeROMDataStruct->tsil_cpsMethodROMData);
          psModuleStruct = (TSS_TSIL_MemMapPtr) (psMethodROMDataStruct->tsil_cpsModule);
          psMethodRAMDataStruct = (TSS_TSIL_METHOD_RAMDATA *) (psElectrodeROMDataStruct->tsil_cpsMethodRAMData);
  
          /************* SWTrigger ************/
          if (u8Command == TSS_INIT_COMMAND_SW_TRIGGER)
          {  
            if (psMethodRAMDataStruct->tsil_eScanInProgressState == TSIL_SCNIP_STATE_WAIT)
            {
              psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_NONE; /* Reset EndOfScanState */
              psMethodRAMDataStruct->tsil_eScanInProgressState = TSIL_SCNIP_STATE_PROCESS; /* Set processing */
              psModuleStruct->DATA |= TSI_DATA_SWTS_MASK; /* Toggle SW Trigger */
              u8Result |= TSS_INIT_STATUS_TRIGGER_SET;
              #ifdef _TSS_TEST
                _TSS_TSIGEN_ON;                         /* Start generator for test purpose */
              #endif
            }
          } 
          /************* Do TSIL Init *******************/
          else if (u8Command == TSS_INIT_COMMAND_INIT_MODULES)
          {    
            u8Result |= TSIL_InitModule(psModuleStruct);
            u8Result |= TSIL_SetNSamples(psModuleStruct);
            u8Result |= TSIL_InitLowPower(psMethodROMDataStruct, psModuleStruct);            
            u8Result |= TSIL_InitPEN(psMethodROMDataStruct, psMethodRAMDataStruct, psModuleStruct);            
            u8Result |= TSIL_Recalibrate(psModuleStruct, psMethodROMDataStruct, psMethodRAMDataStruct);  
            u8Result |= TSIL_InitThresholds(psMethodROMDataStruct, psModuleStruct);            
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct, psMethodROMDataStruct); 
          } 
          /************* Set NSamples ***************/
          else if (u8Command == TSS_INIT_COMMAND_SET_NSAMPLES)
          {
            u8Result |= TSIL_SetNSamples(psModuleStruct);
            u8Result |= TSIL_Recalibrate(psModuleStruct, psMethodROMDataStruct, psMethodRAMDataStruct);
            u8Result |= TSIL_InitThresholds(psMethodROMDataStruct, psModuleStruct);                        
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct, psMethodROMDataStruct); 
          }
          /************ Low Power Init *************/
          else if (u8Command == TSS_INIT_COMMAND_INIT_LOWPOWER)
          {
            u8Result |= TSIL_InitLowPower(psMethodROMDataStruct, psModuleStruct);
            u8Result |= TSIL_InitThresholds(psMethodROMDataStruct, psModuleStruct);
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct, psMethodROMDataStruct); 
          }
          /************* Goto Low Power ************/
          else if (u8Command == TSS_INIT_COMMAND_GOTO_LOWPOWER)
          {
            u8Result |= TSIL_InitLowPower(psMethodROMDataStruct, psModuleStruct);
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct, psMethodROMDataStruct); 
          }
          /*************** Do Auto calibration setting of TSIL EXTCHRG and TSIL PS **************/      
          else if (u8Command == TSS_INIT_COMMAND_RECALIBRATE)
          {
            u8Result |= TSIL_Recalibrate(psModuleStruct, psMethodROMDataStruct, psMethodRAMDataStruct);
            u8Result |= TSIL_InitThresholds(psMethodROMDataStruct, psModuleStruct);            
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct, psMethodROMDataStruct);        
          }      
          /************ Electrode Enablers *************/
          else if (u8Command == TSS_INIT_COMMAND_ENABLE_ELECTRODES)
          {  
            u8Result |= TSIL_InitPEN(psMethodROMDataStruct, psMethodRAMDataStruct, psModuleStruct);
          }
          /************* Triggering Init ************/
          else if (u8Command == TSS_INIT_COMMAND_INIT_TRIGGER)
          {  
            u8Result |= TSIL_InitTrigger(psModuleStruct, psMethodRAMDataStruct, psMethodROMDataStruct);
          } 
        
        /* Exit */                   
                       
        return u8Result;
      }

      /***************************************************************************//*!
      *
      * @brief  Reads TSIL capacitance counter and returns a status code
      *
      * @param  *psElectrodeROMDataStruct - Specificcation of electrode ROMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_ReadCounter(TSS_TSIL_ELECTRODE_ROMDATA *psElectrodeROMDataStruct, TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct)
      {
        UINT8 u8Result;  
  
        /* Read TSIL Counter */
        tss_u16CapSample = ((UINT16 *) (psMethodROMDataStruct->tsil_cpu16ChannelCounterBuffer))[psElectrodeROMDataStruct->tsil_cu8ChannelNum];
        /* Evaluation of the Measured Value */
        if (tss_u16CapSample > TSS_TSIL_CAP_HIGH_LIMIT(tsi_au16Resolution))
        {      
          u8Result = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;    /* Too High Capacity is detected */
        } else if (tss_u16CapSample > TSS_TSIL_RECALIBRATION_HIGH_THRESHOLD(tsi_au16Resolution))
        {      
          u8Result = TSS_SAMPLE_RECALIB_REQUEST_HICAP;   /* Re-calibration is needed */
        }else if (tss_u16CapSample < TSS_TSIL_CAP_LOW_LIMIT(tsi_au16Resolution)) 
        {  
          u8Result = TSS_SAMPLE_ERROR_SMALL_CAP;         /* Too Low Capacity is detected */
        } 
        else if (tss_u16CapSample < TSS_TSIL_RECALIBRATION_LOW_THRESHOLD(tsi_au16Resolution)) 
        {  
          u8Result = TSS_SAMPLE_RECALIB_REQUEST_LOCAP;   /* Re-calibration is needed */
        } else {
          u8Result = TSS_SAMPLE_STATUS_OK;
        }
        
        return u8Result;
      }
  
  
      /***************************************************************************//*!
      *
      * @brief  Performs and evalautes measurement 
      *
      * @param  *psMethodROMDataStruct - Specification of ROMDATA Struct
      *         *psMethodRAMDataStruct - Specification of RAMDATA Struct
      *         psModuleStruct - Specification of TSIL module
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_HandleMeasurement(TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct, TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSIL_MemMapPtr psModuleStruct, UINT8 u8ElChannel)
      {
        UINT8 u8Result;
  
        /* Establish measurement */
        if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_ALWAYS)
        {
          if (psMethodRAMDataStruct->tsil_eEndOfScanState != TSIL_EOSF_STATE_REGULAR)
          {
            /* Init measurement */
            psMethodRAMDataStruct->tsil_u8StartElectrode = u8ElChannel;
            /* Start First Measurement */ 
            psModuleStruct->DATA &= ~((UINT32)TSI_DATA_TSICH_MASK);   /* Erase TSICH */
            psModuleStruct->DATA |= TSI_DATA_TSICH(u8ElChannel);  /* Set Channel */
            /* Set Status Flags */            
            psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_NONE; /* Reset EndOfScanState */
            psMethodRAMDataStruct->tsil_eScanInProgressState = TSIL_SCNIP_STATE_PROCESS; /* Set processing */
            psModuleStruct->DATA |= TSI_DATA_SWTS_MASK;    /* Toggle SW trigger */
          } 
          u8Result = TSS_SAMPLE_STATUS_PROCESSING;
          
        } else {  /* If AUTO & SW Mode */

          /* Init measurement */
          psMethodRAMDataStruct->tsil_u8StartElectrode = u8ElChannel;
          psMethodRAMDataStruct->tsil_eScanInProgressState = TSIL_SCNIP_STATE_WAIT;
          /* Start First Measurement */ 
          psModuleStruct->DATA &= ~((UINT32)TSI_DATA_TSICH_MASK);   /* Erase TSICH */
          psModuleStruct->DATA |= TSI_DATA_TSICH(u8ElChannel);  /* Set Channel */
          
          if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
          {
            /* Evaluate Auto Trigger period */
            if (psMethodRAMDataStruct->tsil_eEndOfScanState == TSIL_EOSF_STATE_ERROR)
            {
              u8Result = TSS_SAMPLE_ERROR_SMALL_TRIGGER_PERIOD; /* Small TriggerModuloValue */
              psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_TSIEN_MASK); /* Disable whole TSS due triggering crash */
              #ifdef _TSS_TEST
                 _TSS_TSIGEN_OFF;                                  /* Stop generator for test purpose */
              #endif
            } else {
              u8Result = TSS_SAMPLE_STATUS_PROCESSING;
            }
            psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_NONE; /* Reset EndOfScanState */
          } else {
            u8Result = TSS_SAMPLE_STATUS_PROCESSING;
          }
        }
        #ifdef _TSS_TEST
          _TSS_TSIGEN_ON;                              /* Start generator for test purpose */
        #endif
  
        return u8Result;
      }
      
      /***************************************************************************//*!
      *
      * @brief  Performs a valid reading of one electrode stores the timer values 
      *         and returns a status code
      *
      * @param  u8ElecNum Electrode number to be scanned
      *         u8Command Requested command
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 TSIL_SampleElectrode(UINT8 u8ElecNum, UINT8 u8Command)
      {
        UINT8 u8ElectrodeStatus;  
        UINT8 u8ElCounter;
        UINT8 u8ElChannel;
        
        TSS_TSIL_METHOD_ROMDATA *psMethodROMDataStruct;
        TSS_TSIL_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
        TSS_TSIL_MemMapPtr psModuleStruct;
        TSS_TSIL_METHOD_RAMDATA *psMethodRAMDataStruct;
        
        /* Pointers decoding */
        psElectrodeROMDataStruct = (TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElecNum]);
        psMethodROMDataStruct = (TSS_TSIL_METHOD_ROMDATA *) (psElectrodeROMDataStruct->tsil_cpsMethodROMData);
        psModuleStruct = (TSS_TSIL_MemMapPtr) (psMethodROMDataStruct->tsil_cpsModule);
        psMethodRAMDataStruct = (TSS_TSIL_METHOD_RAMDATA *) (psElectrodeROMDataStruct->tsil_cpsMethodRAMData);
        u8ElChannel = psElectrodeROMDataStruct->tsil_cu8ChannelNum;
        
        /* Module Control */
        if (u8Command == TSS_SAMPLE_COMMAND_RESTART) 
        {
          /* If TSIL is disabled then enable */
          if ((psModuleStruct->GENCS & TSI_GENCS_TSIEN_MASK) == 0u)
          {
            psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;     /* Turn ON TSI Module */
          }
          /* Handle Measurement */
          if (psMethodRAMDataStruct->tsil_eScanInProgressState == TSIL_SCNIP_STATE_NONE)
          {
            u8ElectrodeStatus = TSIL_HandleMeasurement(psMethodRAMDataStruct, psMethodROMDataStruct, psModuleStruct, u8ElChannel);
          } else {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
          }
        }
        else if (u8Command == TSS_SAMPLE_COMMAND_PROCESS) 
        {
          /* If TSIL is disabled then enable */
          if ((psModuleStruct->GENCS & TSI_GENCS_TSIEN_MASK) == 0u)
          {
            psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;     /* Turn ON TSI Module */
          }
          /* Handle Auto Trigger Mode */
          if (psMethodRAMDataStruct->tsil_eScanInProgressState == TSIL_SCNIP_STATE_NONE) /* TSIL scanning is not in progress */
          {
            /* If TSI End of Scan Flag is reported */
            if (psMethodRAMDataStruct->tsil_eEndOfScanState >= TSIL_EOSF_STATE_REGULAR)
            {
              psMethodRAMDataStruct->tsil_eEndOfScanState = TSIL_EOSF_STATE_PROCESS;
              #ifdef _TSS_TEST
                _TSS_TSIGEN_OFF;                                    /* Stop generator */
              #endif
              /* Read TSI Counter */
              u8ElectrodeStatus = TSIL_ReadCounter(psElectrodeROMDataStruct, psMethodROMDataStruct);
            }
            else 
            {
              u8ElectrodeStatus = TSIL_HandleMeasurement(psMethodRAMDataStruct, psMethodROMDataStruct, psModuleStruct, u8ElChannel);
            }
          } 
          else 
          {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
          }
        }
        else if (u8Command == TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE) 
        {
          /* Find the next electrode within the electrode module */
          u8ElCounter = u8ElecNum;
          #if TSS_N_ELECTRODES > 1
            do {
              if (u8ElCounter < (TSS_N_ELECTRODES-1)) 
              {
                u8ElCounter++;
              } else {
                u8ElCounter = 0u;
              }  
            } while (psMethodROMDataStruct != (TSS_TSIL_METHOD_ROMDATA *) (((TSS_TSIL_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsil_cpsMethodROMData));
          #endif          
          /* Return found electrode number */
          u8ElectrodeStatus = u8ElCounter;        
    
        } else if (u8Command == TSS_SAMPLE_COMMAND_RECALIB) 
        {
          u8ElectrodeStatus = TSIL_MethodControl(u8ElecNum, TSS_INIT_COMMAND_RECALIBRATE); 
    
          if (u8ElectrodeStatus & TSS_INIT_ERROR_RECALIB_FAULT) 
          {
            /* Fault happened, so disable actual electrode */
            u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;
          } else if (u8ElectrodeStatus & TSS_INIT_STATUS_CALIBRATION_CHANGED) 
          {
            /* Calibration changed */
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_CALIBRATION_CHANGED;
          } else 
          {
            /* Old calibration was correct */
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;  
          }
          
        } else if (u8Command == TSS_SAMPLE_COMMAND_ENABLE_ELECTRODE) 
        {
          u8ElectrodeStatus = TSIL_MethodControl(u8ElecNum, TSS_INIT_COMMAND_ENABLE_ELECTRODES); 
          
          u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
        } 
    
        return u8ElectrodeStatus;   /* Return status code */ 
        
      }
      
      /***************************************************************************//*!
      *
      * @brief  TSIL ISR routines
      *
      * @remarks
      *
      ****************************************************************************/
  
      #if TSS_DETECT_MODULE(TSIL)
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSIIsr to vector INT_TSI
        #endif
        void TSS_TSIIsr(
        #if TSS_USE_MQX
          void *_isrParameter
        #else
          void
        #endif
        )
        {
          TSS_TSIL_MemMapPtr psModuleStruct;
          UINT8 u8Channel; 
          UINT16 u16PEN;
          UINT8 u8Timeout;
  
          /* Pointers decoding */
          psModuleStruct = (TSS_TSIL_MemMapPtr) (TSS_TSIL_METHOD_ROMDATA_CONTEXT.tsil_cpsModule);
  
          if (tss_CSSys.SystemConfig.LowPowerEn)
          {
             psModuleStruct->GENCS |= TSI_GENCS_OUTRGF_MASK; /* Clear OUTFRG Flag */
             psModuleStruct->GENCS |= TSI_GENCS_ESOR_MASK;   /* End-of-Scan|Out-of-Range Interrupt Selection (0 = Out-of-Range allow, 1 = End-of-Scan allow) */
             psModuleStruct->GENCS &= ~TSI_GENCS_TSIIEN_MASK; /* Disable TSI Interrupt */
            /* Disables LowPower Wake Up */
            u16PEN = TSS_GetSystemConfig(System_SystemConfig_Register); /* Reuse of u16PEN for temp purpose */
            (void)TSS_SetSystemConfig(System_SystemConfig_Register,(u16PEN & ~TSS_LOWPOWER_EN_MASK));  
          } else {          
            /* Clear EOSF flag */                 
            psModuleStruct->GENCS |= TSI_GENCS_EOSF_MASK;
            
            if (TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState == TSIL_EOSF_STATE_NONE)
            {
              /* Disable HW trigger */
              psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_STM_MASK);   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */            
              /* Save Actual channel */
              u8Channel = ((psModuleStruct->DATA & TSI_DATA_TSICH_MASK) >> TSI_DATA_TSICH_SHIFT);        
              /* Read Counter */ 
              ((UINT16 *)(TSS_TSIL_METHOD_ROMDATA_CONTEXT.tsil_cpu16ChannelCounterBuffer))[u8Channel] = (UINT16) (psModuleStruct->DATA & TSI_DATA_TSICNT_MASK);
              /* Read PEN */
              u16PEN = TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_u16PEN;
              /* Find next electrode */
              u8Timeout = 18u;
              do {
                if (u8Channel < 15u)
                {
                  u8Channel++;
                } else { 
                  u8Channel = 0u;
                }
                u8Timeout--;
              } while (((u16PEN & (UINT16)(1u << u8Channel)) == 0u) && (u8Timeout > 0u));
              /* Evaluate */
              if (u8Channel == TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_u8StartElectrode)
              {
                #ifdef _TSS_TEST
                  _TSS_TSIGEN_OFF;                                   /* Stop generator */
                #endif
                TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_REGULAR;
                TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_eScanInProgressState = TSIL_SCNIP_STATE_NONE;
                if ((TSS_TSIL_METHOD_ROMDATA_CONTEXT.tsil_u8TriggerSource == 1u) && (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO))
                { 
                  /* Enable HW trigger for period measurement in the case of AUTO trigger */
                  psModuleStruct->GENCS |= TSI_GENCS_STM_MASK;   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
                }
              } else {
                psModuleStruct->DATA &= ~((UINT32)TSI_DATA_TSICH_MASK); /* Erase TSICH */
                psModuleStruct->DATA |= TSI_DATA_TSICH(u8Channel); /* Set Channel */
                psModuleStruct->DATA |= TSI_DATA_SWTS_MASK;            /* Toggle SW trigger */
              }
            } else {
              /* Indication of short autotrigger period */
              TSS_TSIL_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_ERROR;
            } 
          }

          /* Set Sample Interrupted flag, because TSI measures at background and it can interrupt sampling of GPIO based methods */
          TSS_SET_SAMPLE_INTERRUPTED();
        } 
      #endif
        
      #if TSS_DETECT_MODULE(TSIL0)
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSI0Isr to vector INT_TSI0
        #endif
        void TSS_TSI0Isr(
        #if TSS_USE_MQX
          void *_isrParameter
        #else
          void
        #endif
        )
        {
          TSS_TSIL_MemMapPtr psModuleStruct;
          UINT8 u8Channel; 
          UINT16 u16PEN;
          UINT8 u8Timeout;

          /* Pointers decoding */
          psModuleStruct = (TSS_TSIL_MemMapPtr) (TSS_TSIL0_METHOD_ROMDATA_CONTEXT.tsil_cpsModule);
          
          if (tss_CSSys.SystemConfig.LowPowerEn)
          {
             psModuleStruct->GENCS |= TSI_GENCS_OUTRGF_MASK; /* Clear OUTFRG Flag */
             psModuleStruct->GENCS |= TSI_GENCS_ESOR_MASK;   /* End-of-Scan|Out-of-Range Interrupt Selection (0 = Out-of-Range allow, 1 = End-of-Scan allow) */
             psModuleStruct->GENCS &= ~TSI_GENCS_TSIIEN_MASK; /* Disable TSI Interrupt */
            /* Disables LowPower Wake Up */
            u16PEN = TSS_GetSystemConfig(System_SystemConfig_Register); /* Reuse of u16PEN for temp purpose */
            (void)TSS_SetSystemConfig(System_SystemConfig_Register,(u16PEN & ~TSS_LOWPOWER_EN_MASK));  
          } else {
        
            /* Clear EOSF flag */                 
            psModuleStruct->GENCS |= TSI_GENCS_EOSF_MASK;
            
            if (TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState == TSIL_EOSF_STATE_NONE)
            {
              /* Disable HW trigger */
              psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_STM_MASK);   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
              /* Save Actual channel */
              u8Channel = ((psModuleStruct->DATA & TSI_DATA_TSICH_MASK) >> TSI_DATA_TSICH_SHIFT);        
              /* Read Counter */ 
              ((UINT16 *)(TSS_TSIL0_METHOD_ROMDATA_CONTEXT.tsil_cpu16ChannelCounterBuffer))[u8Channel] = (UINT16) (psModuleStruct->DATA & TSI_DATA_TSICNT_MASK);
              /* Read PEN */
              u16PEN = TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_u16PEN;
              /* Find next electrode */        
              u8Timeout = 18u;
              do {
                if (u8Channel < 15u)
                {
                  u8Channel++;
                } else { 
                  u8Channel = 0u;
                }
                u8Timeout--;
              } while (((u16PEN & (UINT16)(1u << u8Channel)) == 0u) && (u8Timeout > 0u));
              /* Evaluate */
              if (u8Channel == TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_u8StartElectrode)
              {
                #ifdef _TSS_TEST
                  _TSS_TSIGEN_OFF;                                   /* Stop generator */
                #endif
                TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_REGULAR;
                TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_eScanInProgressState = TSIL_SCNIP_STATE_NONE;
                if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
                { 
                  /* Enable HW trigger for period measurement in the case of AUTO trigger */
                  psModuleStruct->GENCS |= TSI_GENCS_STM_MASK;   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
                }
              } else {
                psModuleStruct->DATA &= ~((UINT32)TSI_DATA_TSICH_MASK); /* Erase TSICH */
                psModuleStruct->DATA |= TSI_DATA_TSICH(u8Channel);      /* Set Channel */
                psModuleStruct->DATA |= TSI_DATA_SWTS_MASK;             /* Toggle SW trigger */
              }
            } else {
              /* Indication of short autotrigger period */
              TSS_TSIL0_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_ERROR;
            } 
          }
          /* Set Sample Interrupted flag, because TSIL measures at background and it can interrupt sampling of GPIO based methods */
          TSS_SET_SAMPLE_INTERRUPTED();
        } 
      #endif
        
      #if TSS_DETECT_MODULE(TSIL1)
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSI1Isr to vector INT_TSI1
        #endif
        void TSS_TSI1Isr(
        #if TSS_USE_MQX
          void *_isrParameter
        #else
          void
        #endif
        )
        {
          TSI_MemMapPtr psModuleStruct;
          UINT8 u8Channel; 
          UINT16 u16PEN;
          UINT8 u8Timeout;
      
          /* Pointers decoding */
          psModuleStruct = (TSS_TSIL_MemMapPtr) (TSS_TSIL1_METHOD_ROMDATA_CONTEXT.tsil_cpsModule);
      
          if (tss_CSSys.SystemConfig.LowPowerEn)
          {
             psModuleStruct->GENCS |= TSI_GENCS_OUTRGF_MASK; /* Clear OUTFRG Flag */
             psModuleStruct->GENCS |= TSI_GENCS_ESOR_MASK;   /* End-of-Scan|Out-of-Range Interrupt Selection (0 = Out-of-Range allow, 1 = End-of-Scan allow) */
             psModuleStruct->GENCS &= ~TSI_GENCS_TSIIEN_MASK; /* Disable TSI Interrupt */
            /* Disables LowPower Wake Up */
            u16PEN = TSS_GetSystemConfig(System_SystemConfig_Register); /* Reuse of u16PEN for temp purpose */
            (void)TSS_SetSystemConfig(System_SystemConfig_Register,(u16PEN & ~TSS_LOWPOWER_EN_MASK));  
          } else {
            /* Clear EOSF flag */                 
            psModuleStruct->GENCS |= TSI_GENCS_EOSF_MASK;
            
            if (TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState == TSIL_EOSF_STATE_NONE)
            {
              /* Disable HW trigger */
              psModuleStruct->GENCS &= ~((UINT32)TSI_GENCS_STM_MASK);   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */            
              /* Save Actual channel */
              u8Channel = ((psModuleStruct->DATA & TSI_DATA_TSICH_MASK) >> TSI_DATA_TSICH_SHIFT);        
              /* Read Counter */ 
              ((UINT16 *)(TSS_TSIL1_METHOD_ROMDATA_CONTEXT.tsil_cpu16ChannelCounterBuffer))[u8Channel] = (UINT16) (psModuleStruct->DATA & TSI_DATA_TSICNT_MASK);
              /* Read PEN */
              u16PEN = TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_u16PEN;
              /* Find next electrode */        
              u8Timeout = 18u;
              do {
                if (u8Channel < 15u)
                {
                  u8Channel++;
                } else { 
                  u8Channel = 0u;
                }
                u8Timeout--;
              } while (((u16PEN & (UINT16)(1u << u8Channel)) == 0u) && (u8Timeout > 0u));
              /* Evaluate */
              if (u8Channel == TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_u8StartElectrode)
              {
                #ifdef _TSS_TEST
                  _TSS_TSIGEN_OFF;                                   /* Stop generator */
                #endif
                TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_REGULAR;
                TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_eScanInProgressState = TSIL_SCNIP_STATE_NONE;
                if ((TSS_TSIL1_METHOD_ROMDATA_CONTEXT.tsil_u8TriggerSource == 1u) && (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO))
                { 
                  /* Enable HW trigger for period measurement in the case of AUTO trigger */
                  psModuleStruct->GENCS |= TSI_GENCS_STM_MASK;   /* Set Scan Trigger Mode (0 = SW Trigger, 1 = HW Trigger) */
                }
              } else {
                psModuleStruct->DATA &= ~((UINT32)TSI_DATA_TSICH_MASK); /* Erase TSICH */
                psModuleStruct->DATA |= TSI_DATA_TSICH(u8Channel); /* Set Channel */
                psModuleStruct->DATA |= TSI_DATA_SWTS_MASK;            /* Toggle SW trigger */
              }
            } else {
              /* Indication of short autotrigger period */
              TSS_TSIL1_METHOD_RAMDATA_CONTEXT.tsil_eEndOfScanState = TSIL_EOSF_STATE_ERROR;
            } 
          }
          
          /* Set Sample Interrupted flag, because TSI measures at background and it can interrupt sampling of GPIO based methods */
          TSS_SET_SAMPLE_INTERRUPTED();
        } 
      #endif

  #else /* End of TSS_KINETIS_MCU || TSS_CFM_MCU */
    #error "TSS - Not supported MCU used"
  #endif

#endif /* End of TSS_DETECT_METHOD(TSIL) */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/timer_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_prv.h$
* $Version : 3.8.5.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   timer component's internal use.
*
*END************************************************************************/
#ifndef __timer_prv_h__
#define __timer_prv_h__ 1

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* The timer validity check value */
#define TIMER_VALID               (_mqx_uint)(0x74696d72)    /* "timr" */

/* The types of timers */
#define TIMER_TYPE_ONESHOT_AFTER  (0x1)
#define TIMER_TYPE_ONESHOT_AT     (0x2)
#define TIMER_TYPE_PERIODIC_EVERY (0x11)
#define TIMER_TYPE_PERIODIC_AT    (0x12)

#define IS_ONESHOT(x) (x <= TIMER_TYPE_ONESHOT_AT)

/*--------------------------------------------------------------------------*/
/*
 *                      QUEUE MANIPULATION MACROS
 */

/*
 *  CR171 & CR172
 *
 *  For a time delay queues we insert the task into the queue after
 *  all tasks of the same delay period.  We do not need to do this, we
 *  can just insert the task into the queue before the task waiting
 *  for the same time, as all tasks will be activated anyways.
 *  Running the queues takes a long time, and is done with interrupts
 *  disabled.  There will be a slight behavioural difference in that
 *  two tasks that delay for the same time at the same priority level,
 *  will not run in the order that they called delay.
 *
 *  Set the following define to 1 if you want the original FIFO
 *  behavior where tasks are activated from the time delay queue into
 *  the ready queue in FIFO order (longer enqueue search with
 *  interrupts disabled).
 */
#ifndef MQX_DELAY_ENQUEUE_FIFO_ORDER
#define MQX_DELAY_ENQUEUE_FIFO_ORDER    0  /* 0=LIFO, 1=FIFO */
#endif
#if MQX_DELAY_ENQUEUE_FIFO_ORDER
#define MQX_DELAY_ENQUEUE_POLICY(result)  (result > 0)  /* FIFO original */
#else
#define MQX_DELAY_ENQUEUE_POLICY(result)  (result >= 0) /* LIFO faster */
#endif

/*--------------------------------------------------------------------------*/
/*
 *                    TYPEDEFS FOR _CODE_PTR_ FUNCTIONS
 */
typedef void (_CODE_PTR_  TIMER_NOTIFICATION_FPTR)(void);

/*--------------------------------------------------------------------------*/
/*                       DATATYPE DEFINITIONS                               */

/*  TIMER ENTRY STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure defines what an entry in the timer table looks like.
 */
typedef struct timer_entry_struct
{

   /*! \brief Queue pointers. */
   QUEUE_ELEMENT_STRUCT QUEUE_ELEMENT;
   
   /*! \brief The requested timer frequency. */
   MQX_TICK_STRUCT      CYCLE;

   /*! \brief Where the expiry time is kept to know when next to fire the timer. */
   MQX_TICK_STRUCT      EXPIRATION_TIME;

   /*! \brief The function to call when the timer expires. */
   TIMER_NOTIFICATION_FPTR NOTIFICATION_FUNCTION;

   /*! \brief The data to pass as parameter 2 when calling the expiration function. */
   pointer              NOTIFICATION_DATA_PTR;
   
   /*! \brief Task requesting this service. */
   TD_STRUCT_PTR        TD_PTR;

   /*! \brief Validity field for this structure. */
   _mqx_uint            VALID;

   /*! \brief Set to true if using tick interface functions. */
   boolean              USES_TICKS;

   /*! \brief What type of timer is this. */
   uint_16              TIMER_TYPE;
   
   /*! \brief Time mode used. */
   uint_16              MODE;

   /*! \brief Timer ID. */
   _timer_id            ID;

} TIMER_ENTRY_STRUCT, _PTR_ TIMER_ENTRY_STRUCT_PTR;
/*! \endcond */

/* TIMER COMPONENT STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure contains the definitions used by the timer component.
 *  
 * The address of this structure is stored in the kernel data COMPONENT array.
 */
typedef struct timer_component_struct
{

   /*! \brief The queue of timers using the elapsed time. */
   QUEUE_STRUCT           ELAPSED_TIMER_ENTRIES;
   
   /*! \brief The queue of timers using the kernel time. */
   QUEUE_STRUCT           KERNEL_TIMER_ENTRIES;

   /*! \brief Mutual exclusion semaphore for the timer entries. */
   LWSEM_STRUCT           TIMER_ENTRIES_LWSEM;
  
   /*! \brief The timer validity field. */
   _mqx_uint              VALID;

   /*! \brief The task id of the timer task. */
   _task_id               TIMER_TID;
   
   /*! \brief The task descriptor of the timer task. */
   TD_STRUCT_PTR          TIMER_TD_PTR;
  
   /*! \brief Mutual exclusion semaphore for the timer ISR. */
   LWSEM_STRUCT           TIMER_ISR_LWSEM;

   /*! \brief Timer ID counter. */
   _mqx_uint              ID;

   /*! \brief The current timer entry being serviced. */
   TIMER_ENTRY_STRUCT_PTR ENTRY_PTR;

} TIMER_COMPONENT_STRUCT, _PTR_ TIMER_COMPONENT_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/*                       PROTOTYPE DEFINITIONS                              */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _timer_id              _timer_alloc_id_internal(
   TIMER_COMPONENT_STRUCT_PTR);
extern void                   _timer_cleanup(TD_STRUCT_PTR);
extern TIMER_ENTRY_STRUCT_PTR _timer_find_entry_internal(
   TIMER_COMPONENT_STRUCT_PTR, _timer_id);
extern void      _timer_insert_queue_internal(QUEUE_STRUCT_PTR, 
   TIMER_ENTRY_STRUCT_PTR);
extern void      _timer_isr(void);
extern _timer_id _timer_start_oneshot_after_internal(TIMER_NOTIFICATION_FPTR,
   pointer, _mqx_uint, MQX_TICK_STRUCT_PTR, boolean);
extern _timer_id _timer_start_oneshot_at_internal(TIMER_NOTIFICATION_FPTR, 
   pointer, _mqx_uint, MQX_TICK_STRUCT_PTR, boolean);
extern _timer_id _timer_start_periodic_at_internal(TIMER_NOTIFICATION_FPTR,
   pointer,  _mqx_uint, MQX_TICK_STRUCT_PTR, MQX_TICK_STRUCT_PTR, boolean);
extern _timer_id _timer_start_periodic_every_internal(TIMER_NOTIFICATION_FPTR,
   pointer, _mqx_uint, MQX_TICK_STRUCT_PTR, boolean);
extern void      _timer_task(uint_32);

#endif

#ifdef __cplusplus
}
#endif

#endif /* __timer_prv_h__ */
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/snmp/snmp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: snmp.c$
* $Version : 3.8.16.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains an implementation of an
*   SNMP{v1,v2c} agent.
*
*END************************************************************************/

#include <rtcs.h>
#include <rtcs_prv.h>

#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_UDP 
#if RTCSCFG_ENABLE_IP4

#include <string.h>
#include "snmpcfg.h"
#include "asn1.h"
#include "snmp.h"

typedef struct snmp_context  {
   uint_32     UDPSOCK;
} SNMP_CONTEXT, _PTR_ SNMP_CONTEXT_PTR;

_rtcs_taskid SNMP_task_id = 0;

#ifdef __MQX__ 
void SNMP_Exit_handler(void);
#endif


static uchar inbuf[SNMPCFG_BUFFER_SIZE];
static uchar outbuf[SNMPCFG_BUFFER_SIZE];

void SNMP_task (pointer, pointer);

/*
** This agent generates GetResponse PDUs to GetRequests,
** GetNextRequests and GetBulkRequests.  All GetResponses
** have the same format, specifically:
**
**    30 <len>
**       02 01 <00-01>
**       04 <len> <community>
**       A2 <len>
**          02 <len> <id>
**          02 01 00
**          02 01 00
**          30 <len>
**
**             30 <len>
**                06 <len> <object-id>
**                <tag> <len> <value>
**             30 <len>
**                06 <len> <object-id>
**                <tag> <len> <value>
**             30 <len>
**                06 <len> <object-id>
**                <tag> <len> <value>
**             ...
**
** Building this packet is a bit problematic.
**
** If we start from the top, we can't fill in the <len>
** fields, because
**    1) we don't yet know the length of the remainder
**       of the packet, and
**    2) since we don't know the length, we don't know
**       how many bytes the length field will occupy
**       (each <len> is 1 byte for lengths 00-7F,
**       2 bytes for lengths 80-FF, or 3 bytes for
**       lengths 0100-FFFF).
**
** We'd have to assume the worst case for each <len>
** and reserve 3 bytes for each, and make a second
** pass to fill them.
**
** If we start from the bottom, then building responses
** to GetBulkRequests becomes hard.
**
** So what do we do?  We start from the middle. :)
**
** We reserve space for the maximum header (the first eight
** lines above).  To do this, we make an assumption:  that
** no <len> ever gets a value larger than FFFF.  This is
** pretty safe, since SNMP packets have to fit inside IP
** datagrams, and IP datagrams only have 16-bit length
** fields.
**
** Then we make repeated MIB calls to fill in the
** VarBindList.
**
** Once the VarBindList is written, we write the header
** backwards.
**
*/


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_request
* Returned Value   :
* Comments  :  Parse a VarBindList in a PDU.
*
*END*-----------------------------------------------------------------*/

static boolean SNMP_request
   (
      SNMP_PARSE_PTR snmp,
      uchar_ptr      invarp,
      uint_32        invarlen,
      uchar_ptr      outvarp,
      uint_32        outvarlen,
      uint_32 _PTR_  writelen
   )
{ /* Body */

   IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_VAR_GETS++);
   snmp->errstat = RTCSMIB_request(snmp->pdutype, invarp, invarlen, outvarp, outvarlen, writelen);

   if (snmp->errstat == SNMP_ERROR_noError) {
      return TRUE;
   } /* Endif */

   if (snmp->errstat == SNMP_ERROR_PARSE) {
      snmp->errstat = SNMP_ERROR_noError;
      return FALSE;
   } /* Endif */

   if (snmp->version == 0) {
      switch (snmp->errstat) {
      case SNMP_ERROR_noSuchObject:
      case SNMP_ERROR_noSuchInstance:
      case SNMP_ERROR_endOfMibView:
      case SNMP_ERROR_notWritable:
         snmp->errstat = SNMP_ERROR_noSuchName;
         break;
      case SNMP_ERROR_noAccess:
      case SNMP_ERROR_wrongType:
      case SNMP_ERROR_wrongLength:
      case SNMP_ERROR_wrongEncoding:
      case SNMP_ERROR_wrongValue:
      case SNMP_ERROR_noCreation:
      case SNMP_ERROR_inconsistentValue:
      case SNMP_ERROR_resourceUnavailable:
         snmp->errstat = SNMP_ERROR_badValue;
         break;
      } /* Endswitch */
      return FALSE;
   } /* Endif */

   if ((snmp->version == 1) && (snmp->errstat >= 0x80)) {
      uint_32 oidlen, varlen, totlen;

      invarp++;
      if (*invarp < 0x80) {
         invarp++;
      } else {
         invarp += (*invarp & 0x7F) + 1;
      } /* Endif */

      invarp++;
      if (*invarp < 0x80) {
         oidlen = *invarp++;
      } else {
         uint_32 lenlen = *invarp++ & 0x7F;
         oidlen = 0;
         
         while (lenlen--) {
            oidlen <<= 8;
            oidlen += *invarp++;
         } /* Endwhile */
      } /* Endif */

      varlen = oidlen;
      if (varlen < 0x80) {
         varlen += 2;
      } else if (varlen < 0x100) {
         varlen += 3;
      } else {
         varlen += 4;
      } /* Endif */
      varlen += 2;

      totlen = varlen;
      if (totlen < 0x80) {
         totlen += 2;
      } else if (totlen < 0x100) {
         totlen += 3;
      } else {
         totlen += 4;
      } /* Endif */

      if (totlen > outvarlen) {
         snmp->errstat = SNMP_ERROR_tooBig;
         return FALSE;
      } /* Endif */

      *outvarp++ = ASN1_TYPE_SEQUENCE;
      if (varlen < 0x80) {
         *outvarp++ = varlen;
      } else if (varlen < 0x100) {
         *outvarp++ = 0x81;
         *outvarp++ = varlen;
      } else {
         *outvarp++ = 0x82;
         htons(outvarp, varlen);
         outvarp += 2;
      } /* Endif */

      *outvarp++ = ASN1_TYPE_OBJECT;
      if (oidlen < 0x80) {
         *outvarp++ = oidlen;
      } else if (oidlen < 0x100) {
         *outvarp++ = 0x81;
         *outvarp++ = oidlen;
      } else {
         *outvarp++ = 0x82;
         htons(outvarp, oidlen);
         outvarp += 2;
      } /* Endif */
      _mem_copy(invarp, outvarp, oidlen);
      outvarp += oidlen;

      *outvarp++ = snmp->errstat;
      *outvarp++ = 0;

      *writelen = totlen;
      return TRUE;
   } /* Endif */

   return FALSE;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_parse_varbindlist
* Returned Value   :
* Comments  :  Parse a VarBindList in a PDU.
*
*END*-----------------------------------------------------------------*/

static boolean SNMP_parse_varbindlist
   (
      SNMP_PARSE_PTR snmp,
      uint_32_ptr    writelen
   )
{ /* Body */
   uchar_ptr   outp, varp;
   uint_32     outlen, varlen, varcount, index;

   outp = snmp->outbuf;
   outlen = snmp->outlen;
   index = 0;
   *writelen = 0;

   /* 
   ** Set the value of non repeaters variable to zero 
   ** if it is less than zero
   */
   #if 0 // nonrep is unsigned  
   if(snmp->nonrep < 0) {      
      snmp->nonrep = 0;
   }
   #endif
   
   while (snmp->nonrep && snmp->inlen) {
      snmp->nonrep--;
      varp = snmp->inbuf;
      varlen = snmp->inlen;
      index++;
      if (!SNMP_request(snmp, varp, varlen, outp, outlen, &varlen)) {
         if (SNMP_ERROR_USEINDEX(snmp->errstat)) {
            snmp->errindex = index;
         } /* Endif */
         return FALSE;
      } /* Endif */
      outp += varlen;
      outlen -= varlen;
      *writelen += varlen;
      ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, varlen);
      ASN1_READ_IGNORE(snmp, varlen);
   } /* Endwhile */

   while (snmp->inlen) {
      varp = snmp->inbuf;
      varlen = snmp->inlen;
      index++;
      for (varcount = 0; varcount < snmp->reps; varcount++) {
         if (!SNMP_request(snmp, varp, varlen, outp, outlen, &varlen)) {
            if (SNMP_ERROR_USEINDEX(snmp->errstat)) {
               snmp->errindex = index;
            } /* Endif */
            return FALSE;
         } /* Endif */
         varp = outp;
         outp += varlen;
         outlen -= varlen;
         *writelen += varlen;
      } /* Endfor */
      ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, varlen);
      ASN1_READ_IGNORE(snmp, varlen);
   } /* Endwhile */

   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_parse_pduv1
* Returned Value   :
* Comments  :  Parse a {Get,GetNext,Set}Request PDU.
*
*END*-----------------------------------------------------------------*/

static boolean SNMP_parse_pduv1
   (
      SNMP_PARSE_PTR snmp
   )
{ /* Body */
   uint_32     typelen;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   if (typelen == 0) return FALSE;
   snmp->errstatp = snmp->inbuf + (typelen - 1);
   ASN1_READZERO_IGNORE(snmp, typelen);

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   if (typelen == 0) return FALSE;
   snmp->errindexp = snmp->inbuf + (typelen - 1);
   ASN1_READZERO_IGNORE(snmp, typelen);

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, typelen);
   snmp->inlen = typelen;

   /*
   ** We want nonrep to be (at least) the number of VarBinds in
   ** the VarBindList.  We pick typelen, because each VarBind is
   ** guaranteed to be at least one byte (in fact, they're guaranteed
   ** to be at least five bytes), so typelen is a guaranteed upper
   ** bound.  We pick reps = 1, because if ever nonrep weren't big
   ** enough (which will never happen), the remaining VarBinds will
   ** still be treated as non-repeaters.
   */
   snmp->nonrep = typelen;
   snmp->reps = 1;

   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_parse_awesome_pdubulk
* Returned Value   :
* Comments  :  Parse a GetBulkRequest PDU.
*
*END*-----------------------------------------------------------------*/

static boolean SNMP_parse_awesome_pdubulk
   (
      SNMP_PARSE_PTR snmp
   )
{ /* Body */
   uint_32     typelen;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   if (typelen == 0) return FALSE;
   snmp->errstatp = snmp->inbuf + (typelen - 1);
   ASN1_READZERO_INT(snmp, typelen, snmp->nonrep);

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   if (typelen == 0) return FALSE;
   snmp->errindexp = snmp->inbuf + (typelen - 1);
   ASN1_READZERO_INT(snmp, typelen, snmp->reps);

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, typelen);
   snmp->inlen = typelen;

   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_parse
* Returned Value   :
* Comments  :  Parse an SNMP packet.
*
*END*-----------------------------------------------------------------*/

static boolean SNMP_parse
   (
      SNMP_PARSE_PTR snmp,
      uint_32_ptr    writelen
   )
{ /* Body */
   uint_32     typelen, maxheadlen;
   uint_32     ctylen, idlen;
   uchar_ptr   ctyp,   idp,  pdup;
   volatile uint_8 tmp;

   maxheadlen = 0;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_SEQUENCE, typelen);
   maxheadlen += 4;
   snmp->inlen = typelen;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, typelen);
   ASN1_READ_INT(snmp, typelen, snmp->version);
   maxheadlen += 3;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_OCTET, ctylen);
   ctyp = snmp->inbuf;
   
   /* test for community string match */
   for (tmp=0; tmp < SNMPCFG_NUM_COMMUNITY; tmp++) {
      if (ctylen == snmp->communitylen[tmp]) {
         if( !memcmp(ctyp, snmp->community[tmp], ctylen) ) {
            break;
        }
      }
   } /* Endfor */
   
   /* if community string is bad, return */
   if(tmp == SNMPCFG_NUM_COMMUNITY) {
      IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_BAD_COMMUNITY++);
      /* Check before decrement, because SNMP_task will increment it */
      IF_SNMP_STATS_ENABLED(if(snmp->STATS.ST_RX_BAD_PARSE > 0) snmp->STATS.ST_RX_BAD_PARSE--);
      return FALSE;
   } /* Endif */
   
   ASN1_READ_IGNORE(snmp, ctylen);
   maxheadlen += ctylen + 4;

   pdup = snmp->inbuf;
   ASN1_READ_TYPELEN(snmp, snmp->pdutype, typelen);
   *pdup = ASN1_TYPE_PDU_RESPONSE;
   maxheadlen += 4;
   snmp->inlen = typelen;

   ASN1_READ_TYPELEN_EXPECT(snmp, ASN1_TYPE_INTEGER, idlen);
   idp = snmp->inbuf;
   ASN1_READ_IGNORE(snmp, idlen);
   maxheadlen += idlen + 4;

   maxheadlen += 10; /* two INTEGERs and a SEQUENCE */

   snmp->outbuf += maxheadlen;
   snmp->outlen -= maxheadlen;

#if RTCSCFG_ENABLE_SNMP_STATS
   switch (snmp->pdutype) {
   case ASN1_TYPE_PDU_GET:       snmp->STATS.ST_RX_GETREQ++;     break;
   case ASN1_TYPE_PDU_GETNEXT:   snmp->STATS.ST_RX_GETNEXTREQ++; break;
   case ASN1_TYPE_PDU_RESPONSE:  snmp->STATS.ST_RX_RESPONSE++;   break;
   case ASN1_TYPE_PDU_SET:       snmp->STATS.ST_RX_SETREQ++;     break;
   case ASN1_TYPE_PDU_TRAP:      snmp->STATS.ST_RX_TRAP++;       break;
   case ASN1_TYPE_PDU_GETBULK:   snmp->STATS.ST_RX_GETBULKREQ++; break;
   case ASN1_TYPE_PDU_INFORM:    snmp->STATS.ST_RX_INFORM++;     break;
   case ASN1_TYPE_PDU_TRAPV2:    snmp->STATS.ST_RX_V2TRAP++;     break;
   case ASN1_TYPE_PDU_REPORT:    snmp->STATS.ST_RX_REPORT++;     break;
   default:                      snmp->STATS.ST_RX_OTHER++;      break;
   } /* Endswitch */
#endif

   switch (snmp->pdutype) {
   case ASN1_TYPE_PDU_GET:
   case ASN1_TYPE_PDU_GETNEXT:
   case ASN1_TYPE_PDU_SET:
      if (snmp->version > 1) {
         IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_BAD_VERSION++);
         IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_BAD_PARSE--); /* because SNMP_task will increment it */
         return FALSE;
      } /* Endif */
      if (!SNMP_parse_pduv1(snmp)) return FALSE;
      break;
   case ASN1_TYPE_PDU_GETBULK:
      if (snmp->version != 1) {
         IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_BAD_VERSION++);
         IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_BAD_PARSE--); /* because SNMP_task will increment it */
         return FALSE;
      } /* Endif */
      if (!SNMP_parse_awesome_pdubulk(snmp)) return FALSE;
      snmp->pdutype = ASN1_TYPE_PDU_GETNEXT;
      break;
   default:
      IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_BAD_PDU++);
      IF_SNMP_STATS_ENABLED(snmp->STATS.ST_RX_BAD_PARSE--); /* because SNMP_task will increment it */
      return FALSE;
   } /* Endswitch */

   if (!SNMP_parse_varbindlist(snmp, &typelen)) return FALSE;

   ASN1_BKWRITE_TYPELEN       (snmp, typelen, ASN1_TYPE_SEQUENCE, typelen);
   ASN1_BKWRITE_TYPELEN_INT   (snmp, typelen, 0);
   ASN1_BKWRITE_TYPELEN_INT   (snmp, typelen, 0);
   ASN1_BKWRITE_TYPELEN_BYTES (snmp, typelen, ASN1_TYPE_INTEGER, idp, idlen);
   ASN1_BKWRITE_TYPELEN       (snmp, typelen, ASN1_TYPE_PDU_RESPONSE, typelen);
   ASN1_BKWRITE_TYPELEN_BYTES (snmp, typelen, ASN1_TYPE_OCTET, ctyp, ctylen);
   ASN1_BKWRITE_TYPELEN_INT   (snmp, typelen, snmp->version);
   ASN1_BKWRITE_TYPELEN       (snmp, typelen, ASN1_TYPE_SEQUENCE, typelen);

   *writelen = typelen;
   return TRUE;

} /* Endbody */





/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_init_with_traps
* Returned Value   : error code
* Comments  :  Start the SNMP agent.
*
*END*-----------------------------------------------------------------*/

uint_32 SNMP_init_with_traps
   (
      char_ptr name,
      uint_32  priority,
      uint_32  stacksize,
      /* Address to an array of IP addresses, NULL terminated */
      _ip_address _PTR_ traplist 
   )
{ /* Body */
   return RTCS_task_create(name, priority, stacksize, SNMP_task, traplist);
} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name    : SNMP_task
* Returned Value   : none
* Comments  :  SNMP agent.
*
*END*-----------------------------------------------------------------*/

void SNMP_task
   (
      pointer traps,
      pointer creator
   )
{ /* Body */
   SNMP_PARSE        snmp;
   sockaddr_in       addr;
   uint_32           sock, error, count;
   int_32            inlen, j;
   uint_32           outlen,time;
   uint_16           addrlen;
   uint_32           option;
   char_ptr          community_array[] = SNMPCFG_COMMUNITY_LIST;
   _ip_address _PTR_ trap_receiver_list_ptr = (_ip_address _PTR_)traps;

   SNMP_CONTEXT    snmp_context =  { 0 };

   SNMP_task_id = RTCS_task_getid();
#ifdef __MQX__ 
   /* Set up exit handler and context so that we can clean up if the SNMP agent is terminated */
   _task_set_environment( _task_get_id(), (pointer) &snmp_context );
   _task_set_exit_handler( _task_get_id(), SNMP_Exit_handler );
#endif 
  
   /* SNMP agent services port 161 */
   addr.sin_family      = AF_INET;
   addr.sin_port        = IPPORT_SNMP;
   addr.sin_addr.s_addr = INADDR_ANY;

   /* Bind to UDP port */
   snmp_context.UDPSOCK = socket(PF_INET, SOCK_DGRAM, 0);
   sock = snmp_context.UDPSOCK;
   
   if (sock == RTCS_SOCKET_ERROR) {
      RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
   } /* Endif */
   
   /* Begin ENGR00243356 */
   /* Set socket options to no wait */
   option = TRUE;
   setsockopt(sock, SOL_UDP, OPT_SEND_NOWAIT, &option, sizeof(option));
   /* End ENGR00243356 */  
   
   error = bind(sock, &addr, sizeof(addr));
   if (error) {
      RTCS_task_exit(creator, error);
   } /* Endif */

   IF_SNMP_STATS_ENABLED(_mem_zero(&snmp.STATS, sizeof(snmp.STATS)));
   snmp.trapsock     = sock;

   snmp.currentcommunity = 0;

   for (j = 0; j < SNMPCFG_NUM_COMMUNITY; j++) {
      snmp.community[j]   = community_array[j];
      snmp.communitylen[j]   = strlen((const char *)(community_array[j]));
   } /* Endfor */
   
   for (j = 0; j < SNMPCFG_MAX_TRAP_RECEIVERS; j++)
      snmp.trap_receiver_list[j] = 0;
   
   if(trap_receiver_list_ptr != NULL) {
      count = 0;
      while(*trap_receiver_list_ptr != 0 && count < SNMPCFG_MAX_TRAP_RECEIVERS) {
         snmp.trap_receiver_list[count] = *trap_receiver_list_ptr;
         trap_receiver_list_ptr++;
         count++;   
      } /* Endwhile */
   } /* Endif */
   
   SNMP_set_data(&snmp);

   RTCS_task_resume_creator(creator, RTCS_OK);

   /* Send some traps -- but only if the application has added some traps receivers */
   if (RTCS_count_trap_receivers_internal() != 0) {
      SNMP_trap_select_community(snmp.community[0]);
      time = RTCS_time_get();   
      if(time < 30) {
#ifdef SNMPCFG_SEND_V2_TRAPS
         SNMPv2_trap_coldStart();
#else
         SNMP_trap_coldStart();
#endif         
      } else {
#ifdef SNMPCFG_SEND_V2_TRAPS
         SNMPv2_trap_warmStart();
#else
         SNMP_trap_warmStart();
#endif         
      } /* Endif */
   } /* Endif */

   for (;;) {

      addrlen = sizeof(addr);
      inlen = recvfrom(sock, inbuf, SNMPCFG_BUFFER_SIZE, 0, &addr, &addrlen);
      IF_SNMP_STATS_ENABLED(snmp.STATS.COMMON.ST_RX_TOTAL++);

      snmp.inbuf = inbuf;
      snmp.inlen = inlen;
      snmp.outbuf = outbuf;
      snmp.outlen = SNMPCFG_BUFFER_SIZE;
      snmp.pdutype = 0; /* anything except ASN1_TYPE_PDU_SET */
      snmp.errstat = SNMP_ERROR_noError;
      snmp.errindex = 0;
      if (SNMP_parse(&snmp, &outlen)) {
         IF_SNMP_STATS_ENABLED(snmp.STATS.COMMON.ST_TX_TOTAL++);
         IF_SNMP_STATS_ENABLED(snmp.STATS.ST_TX_RESPONSE++);
         sendto(sock, snmp.outbuf, outlen, 0, &addr, addrlen);
      } else if (snmp.errstat || snmp.pdutype == ASN1_TYPE_PDU_SET) {
         if (snmp.errindex >= 0xFF) {
            snmp.errstat = SNMP_ERROR_tooBig;
            snmp.errindex = 0;
         } /* Endif */
         *snmp.errstatp  = snmp.errstat;
         *snmp.errindexp = snmp.errindex;
#if RTCSCFG_ENABLE_SNMP_STATS
         snmp.STATS.COMMON.ST_TX_TOTAL++;
         snmp.STATS.ST_TX_RESPONSE++;
         switch (snmp.errstat) {
         case SNMP_ERROR_noError:    break;
         case SNMP_ERROR_tooBig:     snmp.STATS.ST_TX_TOOBIG++;     break;
         case SNMP_ERROR_noSuchName: snmp.STATS.ST_TX_NOSUCHNAME++; break;
         case SNMP_ERROR_badValue:   snmp.STATS.ST_TX_BADVALUE++;   break;
         case SNMP_ERROR_readOnly:   snmp.STATS.ST_TX_READONLY++;   break;
         case SNMP_ERROR_genErr:     snmp.STATS.ST_TX_GENERR++;     break;
         default:                    snmp.STATS.ST_TX_OTHER++;      break;
         } /* Endswitch */
#endif
         sendto(sock, inbuf, inlen, 0, &addr, addrlen);
      } else {
         IF_SNMP_STATS_ENABLED(snmp.STATS.ST_RX_BAD_PARSE++);
         IF_SNMP_STATS_ENABLED(snmp.STATS.COMMON.ST_RX_DISCARDED++);
      } /* Endif */

   } /* Endfor */

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_Exit_handler
* Returned Value   : error code
* Comments  :  Start the EDS task.
*
*END*-----------------------------------------------------------------*/

void SNMP_Exit_handler( void )
{ /* Body */
   SNMP_CONTEXT_PTR    snmp_context_ptr;
   
   snmp_context_ptr = (SNMP_CONTEXT_PTR) _task_get_environment( _task_get_id() );
   if (snmp_context_ptr != NULL)  {
      if (snmp_context_ptr->UDPSOCK)  {
         shutdown(snmp_context_ptr->UDPSOCK, 0);
         snmp_context_ptr->UDPSOCK = 0;   
      }   
   }
   SNMP_task_id = 0;
} /* Endbody */


#endif /* RTCSCFG_ENABLE_IP4 */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_init
* Returned Value   : error code
* Comments  :  Start the SNMP agent.
*
*END*-----------------------------------------------------------------*/

uint_32 SNMP_init
   (
      char_ptr name,
      uint_32  priority,
      uint_32  stacksize
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4
   
   if (SNMP_task_id == 0)  {
      return RTCS_task_create(name, priority, stacksize, SNMP_task, NULL);
   } else  {
      return RTCSERR_SERVER_ALREADY_RUNNING;
   }
#else

    return RTCSERR_IP_IS_DISABLED; 

#endif /* RTCSCFG_ENABLE_IP4 */      
   
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNMP_stop
* Returned Value   : error code
* Comments  :  Start the EDS task.
*
*END*-----------------------------------------------------------------*/

uint_32 SNMP_stop( void )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   if (SNMP_task_id == 0)  {
      return RTCSERR_SERVER_NOT_RUNNING;
   }
   RTCS_task_abort(SNMP_task_id);
   SNMP_task_id = 0;
   return RTCS_OK;
   
#else

    return RTCSERR_IP_IS_DISABLED; 

#endif /* RTCSCFG_ENABLE_IP4 */ 
   
} /* Endbody */



#endif /* RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_UDP */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/resolver.c<|end_filename|>
/**HEADER*******************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: resolver.c$
* $Version : 172.16.17.32$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the Domain Name System resolver
*   functions for RTCS.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"

#if RTCSCFG_ENABLE_DNS | RTCSCFG_ENABLE_LWDNS

#include <ctype.h>
#include <string.h>
#include "dns.h"

#endif

#if RTCSCFG_ENABLE_DNS

/*

GCC compiler did not have ctype in libc.
Used these definitions to resolve the problem:

#define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)-'A'+'a' : (c))
#define isalpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
#define isdigit(c) ( (c) >= '0' && (c) <= '9' )
#define isalnum(c) (isalpha(c) || isdigit(c))

*/


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_get_query_id()
* Returned Value  : uint_16.
* Comments        : The function returns a unique value that
*                   is used by the resolver for queries and keeps track
*                   of the last query id used.
*
*END*-----------------------------------------------------------------*/

static uint_16 DNS_get_query_id
   (
   void
   )

{ /* Body */

   static uint_16 current_query_id = 0;

   /* The masking is required for TI machines to operate correctly */
   if ( current_query_id == 0 ) {
      current_query_id = RTCS_rand() & DNS_UINT_16_MASK;
      if ( current_query_id == 0 ) {
         current_query_id++;
      } /* Endif */
   } else  {
      current_query_id++;
      current_query_id &= DNS_UINT_16_MASK;
      if ( current_query_id == 0 ) {
         current_query_id++;
      } /* Endif */
   } /* Endif */
   return( current_query_id );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_update_TTL()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/


static void DNS_update_TTL
   (
   DNS_INTERNAL_QUERY_STRUCT _PTR_ query_ptr
   )

{ /* Body */

   TIME_STRUCT       time;
   int_32            difference;

   _time_get( &time );

   difference = time.SECONDS - query_ptr->LAST_TTL_CHECK;

   if ( query_ptr->TTL <= difference ) {
      query_ptr->TTL = 0;
   } else {
      query_ptr->TTL -= difference;
   } /* Endif */

   query_ptr->LAST_TTL_CHECK = time.SECONDS;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_free_internal_query()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

static void DNS_free_internal_query
   (
   DNS_INTERNAL_QUERY_STRUCT _PTR_  query
   )

{ /* Body */

   DNS_CNAME_STRUCT _PTR_    free_cname_ptr;
   DNS_CNAME_STRUCT _PTR_    next_cname_ptr;

   if ( query->QNAME_PTR != NULL ) {
      _mem_free( query->QNAME_PTR );
   } /* Endif */

   free_cname_ptr = query->CNAME;
   while ( free_cname_ptr != NULL ) {
      next_cname_ptr = free_cname_ptr->NEXT;
      _mem_free( free_cname_ptr->CNAME_PTR );
      RTCS_part_free( free_cname_ptr );
      free_cname_ptr = next_cname_ptr;
   } /* Endwhile */

   RTCS_part_free( query );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_Send_UDP_Query()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_Send_UDP_Query
   (
   DNS_CONTROL_STRUCT         _PTR_  control_ptr,
   DNS_INTERNAL_QUERY_STRUCT _PTR_  query_ptr,
   boolean                          cname_retry
   )

{ /* Body */

   DNS_MESSAGE_HEADER_STRUCT _PTR_   message_head_ptr;
   DNS_MESSAGE_TAIL_STRUCT   _PTR_   message_tail_ptr;
   DNS_CNAME_STRUCT          _PTR_   cname_ptr;
   sockaddr_in                       raddr;
   int_32                            error;
   uint_32                           buffer_size;
   uint_32                           name_size;
   uchar                     _PTR_   name_ptr;
   uchar                     _PTR_   temp_ptr;

   /* Remote address, Name Servers use port 53 */
   raddr.sin_family      = AF_INET;
   raddr.sin_port        = DNS_NAMESERVER_PORT;
   raddr.sin_addr.s_addr = query_ptr->SERVER_IPADDR;

   /* set up buffer for sending query.   */
   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)control_ptr->RES_BUFFER;

   htons(message_head_ptr->ID, query_ptr->QUERY_ID);
   htons(message_head_ptr->CONTROL, query_ptr->CONTROL);
   htons(message_head_ptr->QDCOUNT, DNS_SINGLE_QUERY);
   htons(message_head_ptr->ANCOUNT, 0);
   htons(message_head_ptr->NSCOUNT, 0);
   htons(message_head_ptr->ARCOUNT, 0);

   name_ptr  = control_ptr->RES_BUFFER + sizeof(DNS_MESSAGE_HEADER_STRUCT);
   if ( cname_retry == TRUE ) {
      cname_ptr = query_ptr->CNAME;
      while ( cname_ptr->NEXT != NULL ) {
         cname_ptr = cname_ptr->NEXT;
      } /* Endwhile */
      name_size = strlen((char _PTR_)cname_ptr->CNAME_PTR );
      temp_ptr  = cname_ptr->CNAME_PTR;
   } else {
      name_size = strlen((char _PTR_)query_ptr->QNAME_PTR );
      temp_ptr  = query_ptr->QNAME_PTR;
   } /* Endif */

   /* To include the terminating NULL char */
   name_size++;
   buffer_size = sizeof(DNS_MESSAGE_HEADER_STRUCT) +  name_size
                 + sizeof(DNS_MESSAGE_TAIL_STRUCT);

   while( name_size != 0 ) {
     htonc(name_ptr, *temp_ptr);
     name_ptr++;
     temp_ptr++;
     name_size--;
   } /* Endwhile */

   message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT _PTR_)name_ptr;
   htons(message_tail_ptr->QTYPE, query_ptr->QTYPE);
   htons(message_tail_ptr->QCLASS, query_ptr->QCLASS);


   error = sendto(control_ptr->RES_SOCKET, control_ptr->RES_BUFFER, buffer_size, 0,
                  &raddr, sizeof(raddr));
   if (error == RTCS_ERROR) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_SEND_QUERY, 1, 0, 0);
      error = RTCSERR_DNS_UNABLE_TO_SEND_QUERY;
   } else {
      error = DNS_OK;
   } /* Endif */

   return( error );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_return_UDP_response_to_query()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_return_UDP_response_to_query
   (
   DNS_INTERNAL_QUERY_STRUCT _PTR_ current_query_ptr,
   uchar _PTR_                     buffer_ptr,
   uint_32                         buffer_size,
   uint_32                         query_sock
   )

{ /* Body */

   int_32        error;

   error = sendto(query_sock, buffer_ptr, buffer_size, 0,
                  &current_query_ptr->CLIENT_SIN,
                  sizeof(current_query_ptr->CLIENT_SIN) );
   if (error == RTCS_ERROR) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_SEND_QUERY, 2, 0, 0);

      DNS_free_internal_query( current_query_ptr );
      return( RTCSERR_DNS_UNABLE_TO_SEND_QUERY );
   } /* Endif */

   DNS_free_internal_query( current_query_ptr );
   return( DNS_OK );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_free_resource_record()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/


static void DNS_free_resource_record
   (
   DNS_RR_HEADER_STRUCT _PTR_ list_ptr
   )

{ /* Body */

   DNS_ADDR_RECORD_STRUCT _PTR_ addr_rr_ptr;
   DNS_NAME_RECORD_STRUCT _PTR_ name_rr_ptr;

   switch ( list_ptr->TYPE ) {
      case DNS_A:
         addr_rr_ptr = (DNS_ADDR_RECORD_STRUCT _PTR_)((void _PTR_)list_ptr);
         RTCS_part_free( addr_rr_ptr );
         break;

      case DNS_PTR:
      case DNS_CNAME:
      case DNS_NS:
         name_rr_ptr = (DNS_NAME_RECORD_STRUCT _PTR_)((void _PTR_)list_ptr);
         if ( name_rr_ptr->ANS_NAME_PTR ) {
            _mem_free( name_rr_ptr->ANS_NAME_PTR );
         }/* Endif */
         RTCS_part_free( name_rr_ptr );
         break;

      default:
         /*
         ** If we reach here, there could be a potential memory leak.
         ** Depending upon the Resource Record type, it may not all
         ** be freed.
         */
         RTCS_part_free( list_ptr );
   } /* Endswitch */

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_free_slist_records()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/


static void DNS_free_slist_records
   (
   DNS_SLIST_STRUCT _PTR_ list_ptr
   )

{ /* Body */

/* NOT IMPLEMENTED */
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_get_best_name_server_for_query()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

/* Start CR 2424
   NOTE: This only works if DNS entries are added correctly into the linked
   list, with the last entry's NEXT == NULL.  This should be done using the
   API for adding DNS entries (CR 2257):
        {
          DNS_SLIST_STRUCT tmp_slist_entry;
          DNS_init_slist_entry(&tmp_slist_entry);
          return( DNS_add_slist_entry(&tmp_slist_entry));
        }
*/
#define PRIMARY_NAME_SERVER_TIMEOUT 300 // 5 minutes

static uint_32 DNS_get_best_name_server_for_query
   (
   DNS_INTERNAL_QUERY_STRUCT _PTR_ query_ptr,
   DNS_CONTROL_STRUCT         _PTR_ control_ptr
   )

{ /* Body */

   static DNS_SLIST_STRUCT _PTR_ best_ptr = NULL;
   TIME_STRUCT                   time;
   static uint_32                last_time;

   // Start with the Primary DNS Server
   if (best_ptr == NULL) {
      best_ptr = control_ptr->LOCAL_SLIST_PTR;
      query_ptr->SERVER_IPADDR = best_ptr->IPADDR;
      return( DNS_OK );
   }

   // Only change our notion of best server if this query has exhausted
   // its QUERY_RETRIES on our current best server.  If the query expired
   // on some other server, we cannot use that info to change our current
   // notion of best server, since our current best server may be fine.
   if (query_ptr->SERVER_IPADDR == best_ptr->IPADDR) {
      _time_get( &time );

      // Go back to the Primary every so often to see if it has returned.
      if (best_ptr != control_ptr->LOCAL_SLIST_PTR) {
         if ((time.SECONDS - last_time) >= PRIMARY_NAME_SERVER_TIMEOUT) {
            best_ptr = control_ptr->LOCAL_SLIST_PTR;
            query_ptr->SERVER_IPADDR = best_ptr->IPADDR;
            return( DNS_OK );
         }
      }

      // If the query has exhausted its retries, change our notion of best.
      // If that takes us back to the Primary, we can ignore the timeout.
      if (query_ptr->QUERY_RETRIES <= 0) {
         if (best_ptr->NEXT) {
            best_ptr = best_ptr->NEXT;
            last_time = time.SECONDS;
         }
         else {
            best_ptr = control_ptr->LOCAL_SLIST_PTR;
         }
      }
   }
   query_ptr->SERVER_IPADDR = best_ptr->IPADDR;
   return( DNS_OK );

} /* Endbody */
// End CR 2424


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_get_next_expired_query()
* Returned Value  : DNS_QUERY_ID_STRUCT _PTR_
* Comments        :
*
*END*-----------------------------------------------------------------*/


static  DNS_INTERNAL_QUERY_STRUCT _PTR_ DNS_get_next_expired_query
   (
   DNS_INTERNAL_QUERY_STRUCT _PTR_ _PTR_ query_head_ptr
   )

{ /* Body */

   DNS_INTERNAL_QUERY_STRUCT _PTR_ expired_query_ptr;


   if ( *query_head_ptr == NULL ) {
      return( NULL );
   } /* Endif */


   expired_query_ptr = *query_head_ptr;

   DNS_update_TTL( expired_query_ptr );

   if ( expired_query_ptr->TTL == 0 ) {
      *query_head_ptr = expired_query_ptr->NEXT;
      return( expired_query_ptr );
   } /* Endif */

   return( NULL );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_add_query_to_list()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_add_query_to_list
   (
   DNS_INTERNAL_QUERY_STRUCT _PTR_ _PTR_ query_head_ptr,
   DNS_INTERNAL_QUERY_STRUCT _PTR_       new_query_ptr
   )

{ /* Body */

   DNS_INTERNAL_QUERY_STRUCT _PTR_ previous_ptr = NULL;
   DNS_INTERNAL_QUERY_STRUCT _PTR_ temp_ptr;

   /*
   ** set the new_query_ptr->NEXT to be NULL, in case this is a query
   ** retry, the NEXT field may not be NULL. Just to be safe.
   */
   new_query_ptr->NEXT = NULL;

   /* first check to see if list is empty */
   if ( *query_head_ptr == NULL) {
      *query_head_ptr = new_query_ptr;
      return( DNS_OK );
   } /* Endif */

   temp_ptr  = *query_head_ptr;

   while ( temp_ptr != NULL ) {
      DNS_update_TTL( temp_ptr );

      if ( new_query_ptr->TTL < temp_ptr->TTL  ) {
         if ( previous_ptr ) {
            previous_ptr->NEXT  = new_query_ptr;
            new_query_ptr->NEXT = temp_ptr;
            return( DNS_OK );
         } else {
            new_query_ptr->NEXT = temp_ptr;
            *query_head_ptr     = new_query_ptr;
            return( DNS_OK );
         } /* Endif */
      } /* Endif */
      previous_ptr = temp_ptr;
      temp_ptr = temp_ptr->NEXT;
   } /* Endwhile */

   previous_ptr->NEXT = new_query_ptr;
   return( DNS_OK );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_send_no_query_error_response()
* Returned Value  : uint_32
* Comments        : This function is only used if DNS is unable to allocate
*                   or fill a DNS_INTERNAL_QUERY_STRUCT
*
*END*-----------------------------------------------------------------*/

static void DNS_send_no_query_error_response
   (
   DNS_CONTROL_STRUCT _PTR_ control_ptr,
   uint_16                 error_code,
   sockaddr_in       _PTR_ client_sin_ptr
   )

{ /* Body */

   DNS_MESSAGE_HEADER_STRUCT _PTR_  message_head_ptr;
   int_32                           error;
   uint_16                          pack_variable;

   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)control_ptr->RES_BUFFER;
   pack_variable = ntohs(message_head_ptr->CONTROL);
   htons(message_head_ptr->CONTROL,
         (pack_variable | DNS_RESPONSE | error_code));
   htons(message_head_ptr->ANCOUNT, DNS_NO_ANSWER);
   htons(message_head_ptr->ARCOUNT, 0);
   htons(message_head_ptr->NSCOUNT, 0);

   error = sendto(control_ptr->RES_SOCKET, control_ptr->RES_BUFFER,
                           control_ptr->RES_BUFFER_SIZE, 0,
                           client_sin_ptr, sizeof(*client_sin_ptr));
   if (error == RTCS_ERROR) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_SEND_QUERY, 3, 0, 0);
   } /* Endif */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_fill_generic_response_buffer()
* Returned Value  : uint-32
* Comments        : This function is used to fill the response buffer
*                   with information common to all queries
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_fill_generic_response_buffer
   (
   uchar                     _PTR_ buffer,
   DNS_INTERNAL_QUERY_STRUCT _PTR_ query_ptr,
   uint_16                         error_code
   )

{ /* Body */

   DNS_MESSAGE_HEADER_STRUCT _PTR_   message_head_ptr;
   DNS_MESSAGE_TAIL_STRUCT   _PTR_   message_tail_ptr;
   uchar                     _PTR_   name_ptr;
   uchar                     _PTR_   temp_ptr;
   uint_32                           name_size;
   uint_32                           buffer_size;

   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)buffer;

   name_size = strlen((char _PTR_)query_ptr->QNAME_PTR );
   /* To include the terminating NULL char */
   name_size++;

   buffer_size =   sizeof(DNS_MESSAGE_HEADER_STRUCT) + name_size
                 + sizeof(DNS_MESSAGE_TAIL_STRUCT);

   temp_ptr = buffer + sizeof(DNS_MESSAGE_HEADER_STRUCT)
                     + name_size;

   message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT _PTR_)temp_ptr;

   name_ptr  = buffer + sizeof(DNS_MESSAGE_HEADER_STRUCT);
   temp_ptr  = query_ptr->QNAME_PTR;

   htons(message_head_ptr->ID, query_ptr->QUERY_ID);
   htons(message_head_ptr->CONTROL,
        (query_ptr->CONTROL | error_code | DNS_RESPONSE));
   htons(message_head_ptr->ANCOUNT, DNS_NO_ANSWER);
   htons(message_head_ptr->QDCOUNT, DNS_SINGLE_QUERY);
   htons(message_head_ptr->NSCOUNT, DNS_NO_ANSWER);
   htons(message_head_ptr->ARCOUNT, DNS_NO_ANSWER);

   while ( name_size ) {
      htonc(name_ptr, *temp_ptr);
      name_ptr++;
      temp_ptr++;
      name_size--;
   } /* Endwhile */

   htons(message_tail_ptr->QTYPE, query_ptr->QTYPE);
   htons(message_tail_ptr->QCLASS, query_ptr->QCLASS);

   return( buffer_size );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_send_error_response()
* Returned Value  : void
* Comments        : This function is used if a DNS_INTERNAL_QUERY_STRUCT
*                   exists
*
*END*-----------------------------------------------------------------*/

static void DNS_send_error_response
   (
   uchar                     _PTR_ buffer,
   DNS_INTERNAL_QUERY_STRUCT _PTR_ query_ptr,
   uint_16                         error_code,
   uint_32                         query_sock,
   int_32                          actual_error
   )

{ /* Body */

   int_32                            error;
   uint_32                           buffer_size;

   if ( actual_error != DNS_OK ) {
      RTCS_log_error(ERROR_DNS, actual_error, 0, 0, 0);
   } /* Endif */

   buffer_size = DNS_fill_generic_response_buffer( buffer, query_ptr,
                                                   error_code );
   /* Send the response buffer to the client */
   error = sendto(query_sock, buffer, buffer_size, 0,
                  &query_ptr->CLIENT_SIN,
                  sizeof(query_ptr->CLIENT_SIN));
   if (error == RTCS_ERROR) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_SEND_QUERY, 4, 0, 0);
   } /* Endif */

   DNS_free_internal_query( query_ptr );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_check_outstanding_queries()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/


static void DNS_check_outstanding_queries
   (
   DNS_CONTROL_STRUCT _PTR_ control_ptr
   )

{ /* Body */

   DNS_INTERNAL_QUERY_STRUCT _PTR_   current_ptr;
   int_32                            error;

   current_ptr = DNS_get_next_expired_query( &control_ptr->RES_QUERY_HEAD_PTR );

      while ( current_ptr ) {
         /*
         ** cycle through all queries and retry with different server, or
         ** return "name server error" response to client
         */
         // Start CR 2424
         current_ptr->QUERY_RETRIES--;
         error = DNS_get_best_name_server_for_query( current_ptr, control_ptr );
         // End CR 2424

         if ( current_ptr->QUERY_RETRIES <= 0 ) {
            DNS_send_error_response( control_ptr->RES_BUFFER, current_ptr,
                                     DNS_QUERY_REFUSED,
                                     control_ptr->RES_SOCKET, DNS_OK );
            current_ptr = DNS_get_next_expired_query(
                             &control_ptr->RES_QUERY_HEAD_PTR );
            continue;
         } /* Endif */

         if ( error != DNS_OK ) {
            DNS_send_error_response( control_ptr->RES_BUFFER, current_ptr,
                                     DNS_SERVER_FAILURE, control_ptr->RES_SOCKET,
                                     error );
            current_ptr = DNS_get_next_expired_query(
                             &control_ptr->RES_QUERY_HEAD_PTR );
            continue;
         } /* Endif */

         current_ptr->TTL      = DNS_QUERY_RETRY_TIME;
         current_ptr->QUERY_ID = DNS_get_query_id();

         error = DNS_Send_UDP_Query( control_ptr, current_ptr, FALSE );
         if ( error == RTCS_ERROR ) {
            DNS_send_error_response( control_ptr->RES_BUFFER, current_ptr,
                                     DNS_QUERY_REFUSED, control_ptr->RES_SOCKET,
                                     error );
            current_ptr = DNS_get_next_expired_query(
                             &control_ptr->RES_QUERY_HEAD_PTR );
            continue;
         } /* Endif */

         DNS_add_query_to_list( &control_ptr->RES_QUERY_HEAD_PTR, current_ptr );
         current_ptr = DNS_get_next_expired_query(
                          &control_ptr->RES_QUERY_HEAD_PTR );
      } /* Endwhile */

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_update_cache()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

static void DNS_update_cache
   (
   DNS_CONTROL_STRUCT _PTR_ control_ptr
   )

{ /* Body */
   DNS_RR_LIST_STRUCT _PTR_ _PTR_ local_cache_ptr = &control_ptr->CACHE_PTR;
   DNS_RR_LIST_STRUCT       _PTR_ previous_cache_ptr = NULL;
   DNS_RR_LIST_STRUCT       _PTR_ next_cache_ptr;
   DNS_RR_LIST_STRUCT       _PTR_ free_cache_ptr;
   DNS_RR_HEADER_STRUCT     _PTR_ previous_rr_head_ptr;
   DNS_RR_HEADER_STRUCT     _PTR_ next_rr_head_ptr;
   DNS_RR_HEADER_STRUCT     _PTR_ free_rr_head_ptr;
   TIME_STRUCT                    time;
   uint_32                        difference;

   _time_get( &time);

   next_cache_ptr = *local_cache_ptr;

   while ( next_cache_ptr != NULL ) {
      next_rr_head_ptr = next_cache_ptr->RR_HEAD_PTR;
      previous_rr_head_ptr = NULL;
      while ( next_rr_head_ptr != NULL ) {
         difference = time.SECONDS - next_rr_head_ptr->LAST_TTL_CHECK;
         if ( next_rr_head_ptr->TTL <= difference ) {
            if ( previous_rr_head_ptr ) {
               previous_rr_head_ptr->NEXT = next_rr_head_ptr->NEXT;
               free_rr_head_ptr           = next_rr_head_ptr;
               next_rr_head_ptr           = next_rr_head_ptr->NEXT;
            } else {
               next_cache_ptr->RR_HEAD_PTR = next_rr_head_ptr->NEXT;
               free_rr_head_ptr            = next_rr_head_ptr;
               next_rr_head_ptr            = next_rr_head_ptr->NEXT;
            } /* Endif */

            DNS_free_resource_record( free_rr_head_ptr );
         } else {
            next_rr_head_ptr->LAST_TTL_CHECK = time.SECONDS;
            next_rr_head_ptr->TTL            =  next_rr_head_ptr->TTL
                                                - difference;
            previous_rr_head_ptr = next_rr_head_ptr;
            next_rr_head_ptr     = next_rr_head_ptr->NEXT;
         } /* Endif */
      } /* Endwhile */

      if ( next_cache_ptr->RR_HEAD_PTR == NULL ) {
         if ( previous_cache_ptr ) {
            previous_cache_ptr->NEXT = next_cache_ptr->NEXT;
            free_cache_ptr = next_cache_ptr;
            next_cache_ptr = next_cache_ptr->NEXT;
         } else {
            *local_cache_ptr = next_cache_ptr->NEXT;
            free_cache_ptr = next_cache_ptr;
            next_cache_ptr = next_cache_ptr->NEXT;
         } /* Endif */

         if (control_ptr->NUM_NAMES_CACHED > 0) {
            control_ptr->NUM_NAMES_CACHED--;
         }/* Endif */
         _mem_free( free_cache_ptr->NAME_PTR );
         RTCS_part_free( free_cache_ptr );
      } else {
         previous_cache_ptr = next_cache_ptr;
         next_cache_ptr     = next_cache_ptr->NEXT;
      } /* Endif */
   } /* Endwhile */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_check_packet_for_name()
* Returned Value  : uint_32
* Comments        : Crude, but it will do for now.
*                   We should check every lable for compression, not
*                   just whole names -- could reduce packet size.
*                   (See DNS_assign_answer_middle_ptr() for a more
*                    elegant solution idea)
*                   However, this doesn't violate RFC 1035.
*
*END*-----------------------------------------------------------------*/

static uint_16 DNS_check_packet_for_name
   (
   uchar _PTR_ buffer_ptr,
   uint_32     buffer_size,
   uchar _PTR_ name_ptr
   )
{ /* Body */
   DNS_MESSAGE_HEADER_STRUCT _PTR_ message_head =
      (DNS_MESSAGE_HEADER_STRUCT _PTR_)buffer_ptr;
   uchar _PTR_ temp_ptr = buffer_ptr + sizeof(DNS_MESSAGE_HEADER_STRUCT);
   DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_ response_ptr;
   uint_16 i, num_queries = ntohs(message_head->QDCOUNT);

   /* First, need to check the original queries. */
   for (i = 0; i < num_queries; i++) {
      if (strcmp((char _PTR_)temp_ptr, (char _PTR_)name_ptr) == 0) {
         return((uint_16)(temp_ptr - buffer_ptr));
      } /* Endif */
      if(ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK) {
         temp_ptr += sizeof(uint_16);
      } else {
         temp_ptr += strlen((char _PTR_)temp_ptr) + 1;
      } /* Endif */
      temp_ptr += sizeof(DNS_MESSAGE_TAIL_STRUCT);
   } /* Endfor */

   /* Now check the answer sections. */
   while (temp_ptr < buffer_ptr + buffer_size) {
      if (strcmp((char _PTR_)temp_ptr, (char _PTR_)name_ptr) == 0) {
         return((uint_16)(temp_ptr - buffer_ptr));
      } /* Endif */
      if(ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK) {
         temp_ptr += sizeof(uint_16);
      } else {
         temp_ptr += strlen((char _PTR_)temp_ptr) + 1;
      } /* Endif */
      response_ptr = (DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_)temp_ptr;
      temp_ptr += sizeof(DNS_RESPONSE_RR_MIDDLE_STRUCT);
      /* Checking the answer section for name as well. */
      if ((ntohs(response_ptr->TYPE) == DNS_PTR ||
           ntohs(response_ptr->TYPE) == DNS_CNAME ||
           ntohs(response_ptr->TYPE) == DNS_NS) &&
          (strcmp((char _PTR_)temp_ptr, (char _PTR_)name_ptr) == 0))
      {
          return((uint_16)(temp_ptr - buffer_ptr));
      } /* Endif */
      temp_ptr += ntohs(response_ptr->RDLENGTH);
   } /* Endwhile */
   return(0);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_fill_answer_section_of_buffer()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_fill_answer_section_of_buffer
   (
   DNS_CONTROL_STRUCT   _PTR_ control_ptr,
   DNS_RR_HEADER_STRUCT _PTR_ rr_ptr,
   uchar                _PTR_ buffer_ptr,
   int_32               _PTR_ buffer_size_ptr
   )

{ /* Body */

   DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_ response_ptr;
   uchar                         _PTR_ answer_ptr;
   uchar                         _PTR_ temp_ptr;
   uint_32                             new_buffer_size = *buffer_size_ptr;
   uint_32                             name_size;
   uint_16                             pack_variable, name_location;

   answer_ptr = buffer_ptr + *buffer_size_ptr;

   name_location = DNS_check_packet_for_name(buffer_ptr, *buffer_size_ptr,
      rr_ptr->DOMAIN_NAME_PTR);
   if(name_location) {
      /* Name is already in packet, use offset */
      pack_variable = (DNS_COMPRESSED_NAME_MASK << 8) | name_location;
      htons(answer_ptr, pack_variable);
      new_buffer_size += sizeof( uint_16 );
      answer_ptr      += sizeof( uint_16 );
   } else {
      /* Name doesn't exist in packet yet */
      temp_ptr  = rr_ptr->DOMAIN_NAME_PTR;
      name_size = strlen((char _PTR_)rr_ptr->DOMAIN_NAME_PTR );
      /* Need to include the last '\0' character as well */
      name_size++;
      new_buffer_size += name_size;
      while( name_size != 0 ) {
         htonc(answer_ptr, *temp_ptr);
         answer_ptr++;
         temp_ptr++;
         name_size--;
      } /* Endwhile */
   } /* Endif */

   response_ptr = (DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_)answer_ptr;

   htons(response_ptr->TYPE, rr_ptr->TYPE);
   htons(response_ptr->CLASS, rr_ptr->CLASS);
   htonl(response_ptr->TTL, rr_ptr->TTL);

   new_buffer_size += sizeof( DNS_RESPONSE_RR_MIDDLE_STRUCT );
   answer_ptr      += sizeof( DNS_RESPONSE_RR_MIDDLE_STRUCT );

   switch ( rr_ptr->TYPE ) {
      case DNS_A:
         htons(response_ptr->RDLENGTH, sizeof( _ip_address ));
         htonl(answer_ptr,
            ((DNS_ADDR_RECORD_STRUCT _PTR_)((void _PTR_)rr_ptr))->IPADDR);
         new_buffer_size += sizeof( _ip_address );
         break;

      case DNS_PTR:
      case DNS_CNAME:
      case DNS_NS:
         name_location = DNS_check_packet_for_name(buffer_ptr, *buffer_size_ptr,
            ((DNS_NAME_RECORD_STRUCT _PTR_)((void _PTR_)rr_ptr))->ANS_NAME_PTR);
         if(name_location) {
            /* Name is already in packet, use offset */
            pack_variable = (DNS_COMPRESSED_NAME_MASK << 8) | name_location;
            htons(answer_ptr, pack_variable);
            new_buffer_size += sizeof( uint_16 );
            answer_ptr      += sizeof( uint_16 );
         } else {
            temp_ptr = ((DNS_NAME_RECORD_STRUCT _PTR_)
               ((void _PTR_)rr_ptr))->ANS_NAME_PTR;
            name_size = strlen((char _PTR_)temp_ptr);
            name_size++; /* need the '\0' char */
            htons(response_ptr->RDLENGTH, name_size);
            new_buffer_size += name_size;
            while ( name_size != 0 ) {
               htonc(answer_ptr, *temp_ptr);
               answer_ptr++;
               temp_ptr++;
               name_size--;
            } /* Endwhile */
         } /* Endif */
         break;

      default:
      /*
      ** Unknown rr type, set new_buffer_size to 0, so cached data
      ** will not be used.
      */
      new_buffer_size = 0;
   } /* Endswitch */

   if (new_buffer_size) {
      *buffer_size_ptr = new_buffer_size;
   } /* Endif */

   return( new_buffer_size );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_fill_response_buffer_with_rr_data()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_fill_response_buffer_with_rr_data
   (
   DNS_CONTROL_STRUCT   _PTR_ control_ptr,
   DNS_RR_HEADER_STRUCT _PTR_ record_ptr,
   boolean                    all_data,
   boolean                    resolver_query
   )

{ /* Body */

   DNS_MESSAGE_HEADER_STRUCT _PTR_ message_head_ptr;
   DNS_RR_HEADER_STRUCT      _PTR_ temp_rr_ptr;
   int_32                    _PTR_ buffer_size_ptr;
   uchar                     _PTR_ buffer_ptr;
   uint_32                         buffer_size = 0;
   uint_16                         num_answers = 0;
   uint_16                         pack_variable;

   temp_rr_ptr = record_ptr;

   if ( resolver_query == TRUE ) {
      message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT_PTR)control_ptr->RES_BUFFER;
      buffer_size_ptr  = &control_ptr->RES_BUFFER_SIZE;
   } else {
      message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT_PTR)control_ptr->NS_BUFFER;
      buffer_size_ptr  = &control_ptr->NS_BUFFER_SIZE;
   } /* Endif */
   buffer_ptr = (uchar _PTR_)message_head_ptr;

   pack_variable    = ntohs( message_head_ptr->CONTROL );

   if ( all_data == TRUE ) {
      while ( temp_rr_ptr != NULL ) {
         num_answers++;
         buffer_size = DNS_fill_answer_section_of_buffer( control_ptr, temp_rr_ptr,
            buffer_ptr, buffer_size_ptr );
         temp_rr_ptr = temp_rr_ptr->NEXT;
      } /* Endwhile */
   } else {
      num_answers++;
      buffer_size = DNS_fill_answer_section_of_buffer( control_ptr, temp_rr_ptr, buffer_ptr,
         buffer_size_ptr );
   } /* Endif */

   /* insert return information here */
   htons(message_head_ptr->ANCOUNT, num_answers);
   pack_variable |= DNS_RESPONSE;
   htons(message_head_ptr->CONTROL, pack_variable);

   return( buffer_size );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_rr_canonical_data_exists()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_rr_canonical_data_exists
   (
   DNS_RECURSIVE_CACHE_STRUCT_PTR cache_ptr
   )
{ /* Body */
   uint_32                    buffer_size = 0;
   DNS_RR_LIST_STRUCT   _PTR_ new_list_ptr = cache_ptr->CACHE_HEAD;
   DNS_RR_HEADER_STRUCT _PTR_ record_ptr;

   if (++cache_ptr->NUM_TRIES >= DNS_MAX_NUM_CNAME_RETRIES ) {
      return 0;
   } /* Endif */

   while ( new_list_ptr != NULL ) {
      if( strcmp((char _PTR_)new_list_ptr->NAME_PTR,
                 (char _PTR_)cache_ptr->NAME_PTR) == 0 ) {
         /* The names match, see if the type of data requested exists */
         record_ptr = new_list_ptr->RR_HEAD_PTR;
         /* Search through the records for the data requested. */
         while ( record_ptr != NULL ) {
            if (( cache_ptr->NEW_QUERY_PTR->QTYPE == record_ptr->TYPE ) &&
                ( cache_ptr->NEW_QUERY_PTR->QCLASS == record_ptr->CLASS )) {
               /* We have a hit on data & class, fill buffer with info. */
               buffer_size =
                  DNS_fill_answer_section_of_buffer(cache_ptr->CONTROL_PTR,
                  record_ptr, cache_ptr->BUFFER_PTR,
                  cache_ptr->BUFFER_SIZE_PTR);
               break;
            } else if ( cache_ptr->NEW_QUERY_PTR->QCLASS == record_ptr->CLASS &&
                        record_ptr->TYPE == DNS_CNAME )
            {
               /*
               ** We have an alias, see if the data type exists for the
               ** Canonical Name.
               */
               cache_ptr->NAME_PTR  = ((DNS_NAME_RECORD_STRUCT _PTR_)
                  ((void _PTR_)record_ptr))->ANS_NAME_PTR;
               buffer_size = DNS_rr_canonical_data_exists(cache_ptr);
               if (buffer_size) {
                  /* We've had a hit, put alias hit in the buffer as well.*/
                  buffer_size =
                     DNS_fill_answer_section_of_buffer(cache_ptr->CONTROL_PTR,
                     record_ptr, cache_ptr->BUFFER_PTR,
                     cache_ptr->BUFFER_SIZE_PTR);
               } /* Endif */
               break;
            } else {
               record_ptr = record_ptr->NEXT;
            } /* Endif */
         } /* Endwhile */
         break;
      } else {
         new_list_ptr = new_list_ptr->NEXT;
      } /* Endif */
   } /* Endwhile */

   return(buffer_size);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_assign_answer_middle_ptr()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

static DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_ DNS_assign_answer_middle_ptr
   (
   uchar _PTR_ answer_head_ptr,
   uint_16     total_answers,
   uint_16     current_answer_num
   )

{ /* Body */

   DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_ rr_middle_ptr = NULL;
   uchar                         _PTR_ temp_ptr;
   uint_32                             name_size = 0;

   if ( total_answers - 1 > current_answer_num ) {
      temp_ptr = answer_head_ptr;

      while( (ntohc(temp_ptr) != '\0') &&
             name_size < DNS_MAX_CHARS_IN_NAME &&
             !(ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK)) {
            name_size += ntohc(temp_ptr);
            temp_ptr = temp_ptr + ntohc(temp_ptr) + 1;
      } /* Endwhile */

      if ( ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK ) {
         temp_ptr+= 2;
      } else {
         temp_ptr++;
      }/* Endif */

      rr_middle_ptr = (DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_)temp_ptr;
   } /* Endif */

   return( rr_middle_ptr );

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_assign_answer_pointers()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

static void DNS_assign_answer_pointers
   (
   uchar                               _PTR_ buffer,
   uchar                         _PTR_ _PTR_ answer_ptr,
   DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_ _PTR_ answer_middle_ptr
   )

{ /* Body */

   uchar _PTR_ temp_ptr;
   uint_32     name_size;

   temp_ptr = buffer + sizeof(DNS_MESSAGE_HEADER_STRUCT);
   name_size = strlen((char _PTR_)temp_ptr);
   name_size++;

   *answer_ptr = temp_ptr + name_size + sizeof(DNS_MESSAGE_TAIL_STRUCT);
   temp_ptr    = *answer_ptr;

   /* Passing this function two hard coded values to force the assignment */
   *answer_middle_ptr = DNS_assign_answer_middle_ptr( temp_ptr, 3, 0 );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_rr_data_exists()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/


static uint_32 DNS_rr_data_exists
   (
   DNS_INTERNAL_QUERY_STRUCT _PTR_ new_query_ptr,
   DNS_CONTROL_STRUCT        _PTR_ control_ptr,
   uchar                     _PTR_ buffer_ptr,
   int_32                    _PTR_ buffer_size_ptr,
   uint_32                         query_type
   )

{ /* Body */

   DNS_RR_LIST_STRUCT   _PTR_ new_list_ptr = NULL;
   DNS_RR_LIST_STRUCT   _PTR_ cache_head;
   DNS_RR_LIST_STRUCT   _PTR_ previous_ptr = NULL;
   DNS_RR_HEADER_STRUCT _PTR_ record_ptr;
   DNS_RECURSIVE_CACHE_STRUCT cache;
   DNS_MESSAGE_HEADER_STRUCT _PTR_   message_head_ptr;
   uint_16                    pack_variable;
   uint_32                    ans_count, i, buffer_size = 0;
   int_32                     cmp_result;
   DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_ answer_middle_ptr;
   uchar                _PTR_ answer_head_ptr;
   boolean                    resolver_query = FALSE;

   if ( query_type == DNS_NS_CACHE_DATA ) {
      new_list_ptr = control_ptr->CACHE_PTR;
      resolver_query = FALSE;
   } else if ( query_type == DNS_NS_AUTH_DATA ) {
      new_list_ptr = control_ptr->NS_ZONE_AUTH_LIST;
      resolver_query = FALSE;
   } else if (query_type == DNS_RES_CACHE_DATA ) {
      new_list_ptr = control_ptr->CACHE_PTR;
      resolver_query = TRUE;
   } /* Endif */
   cache_head = new_list_ptr;

   while ( new_list_ptr != NULL ) {
      cmp_result = strcmp((char _PTR_)new_list_ptr->NAME_PTR,
         (char _PTR_)new_query_ptr->QNAME_PTR );
      if ( cmp_result == 0 ) {
         /* The names match, see if the type of data requested exists */
         record_ptr = new_list_ptr->RR_HEAD_PTR;
         if ( new_query_ptr->QTYPE == DNS_ALL ) {
            buffer_size = DNS_fill_response_buffer_with_rr_data(
                                                            control_ptr,
                                                            record_ptr,
                                                            TRUE,
                                                            resolver_query );
         } else {
            /*
            ** We have a hit on the name, but we only want one specific record,
            ** search through the records for this name for the data requested.
            */
            while ( record_ptr != NULL ) {
               if (( new_query_ptr->QTYPE == record_ptr->TYPE ) &&
                   ( new_query_ptr->QCLASS == record_ptr->CLASS )) {
                  /* We have a hit on data & class, fill buffer with info. */
                  buffer_size = DNS_fill_response_buffer_with_rr_data(
                                                            control_ptr,
                                                            record_ptr,
                                                            FALSE,
                                                            resolver_query );
                  break;
               } else if ( new_query_ptr->QCLASS == record_ptr->CLASS &&
                           record_ptr->TYPE == DNS_CNAME )
               {
                  /*
                  ** We have an alias, see if the data type exists for the
                  ** Canonical Name.
                  */
                  ans_count = ntohs(((DNS_MESSAGE_HEADER_STRUCT _PTR_)buffer_ptr)->ANCOUNT );
                  if(ans_count != 0 ) {
                     /*
                     ** We are checking a response, not a new query, see if the
                     ** answer exists in the packet already.
                     */
                     DNS_assign_answer_pointers(buffer_ptr, &answer_head_ptr,
                        &answer_middle_ptr);
                     for (i = 0; (i <= ans_count) && answer_middle_ptr; i++) {
                         if ((new_query_ptr->QTYPE == ntohs(answer_middle_ptr->TYPE)) &&
                              (new_query_ptr->QCLASS == ntohs(answer_middle_ptr->CLASS)))
                         {
                            buffer_size = *buffer_size_ptr;
                            break;
                         } /* Endif */
                         answer_head_ptr = ((uchar _PTR_)(answer_middle_ptr + 1)) +
                            ntohs(answer_middle_ptr->RDLENGTH);
                         answer_middle_ptr = DNS_assign_answer_middle_ptr(
                            answer_head_ptr, ans_count, i);
                     } /* Endfor */
                     break;
                  } else {
                     cache.NEW_QUERY_PTR = new_query_ptr;
                     cache.CONTROL_PTR = control_ptr;
                     cache.CACHE_HEAD  = cache_head;
                     cache.NAME_PTR    = record_ptr->DOMAIN_NAME_PTR;
                     cache.BUFFER_PTR  = buffer_ptr;
                     cache.BUFFER_SIZE_PTR = buffer_size_ptr;
                     cache.NUM_TRIES       = 0;
                     buffer_size = DNS_rr_canonical_data_exists(&cache);
                     if (buffer_size) {
                        /* insert return information here */
                        message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)buffer_ptr;
                        htons(message_head_ptr->ANCOUNT, cache.NUM_TRIES);
                        pack_variable = ntohs(message_head_ptr->CONTROL);
                        pack_variable |= DNS_RESPONSE;
                        htons(message_head_ptr->CONTROL, pack_variable);
                     } /* Endif */
                     break;
                  } /* Endif */
               } else {
                  record_ptr = record_ptr->NEXT;
               } /* Endif */
            } /* Endwhile */
         } /* Endif */

         break;
      } else {
         previous_ptr = new_list_ptr;
         new_list_ptr = new_list_ptr->NEXT;
      } /* Endif */
   } /* Endwhile */

   if ( previous_ptr != NULL && new_list_ptr != NULL &&
        (query_type == DNS_NS_CACHE_DATA ||
         query_type == DNS_RES_CACHE_DATA)  ) {
      /*
      ** The most recently accessed data in the cache should always be at
      ** the head of the list.  If the new_list_ptr is NULL, cached
      ** data for the name doesn't exist in the list.
      */
      previous_ptr->NEXT    = new_list_ptr->NEXT;
      new_list_ptr->NEXT    = control_ptr->CACHE_PTR;
      control_ptr->CACHE_PTR = new_list_ptr;
   } /* Endif */

   return( buffer_size );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_is_valid_IP_addr()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_is_valid_IP_addr
   (
   uchar _PTR_       buffer_ptr,
   uchar _PTR_       domain_name,
   uchar _PTR_ _PTR_ local_addr_buffer
   )

{ /* Body */
   uchar _PTR_ check_ptr;
   uchar _PTR_ temp_ptr;
   uchar _PTR_ free_buffer;
   uchar       appended_name[] = "in-addr.arpa";
   uint_16     new_location;
   uint_16     label_size;
   int_32      byte_num;
   uint_32     digit_count;
   uint_32     total_size = 0;
   uint_32     i;
   uint_32     j;

   temp_ptr = (uchar _PTR_)RTCS_mem_alloc_zero( DNS_MAX_CHARS_IN_NAME );
   if ( temp_ptr == NULL ) {
      RTCS_log_error(ERROR_DNS, DNS_SERVER_FAILURE, 1, 0, 0);
      return( DNS_SERVER_FAILURE );
   } /* Endif */

   free_buffer = temp_ptr;

   /* first check to see if name is written in correct IP address format */

   check_ptr = domain_name;

   for ( i = 0; i < 4; i++) {
      label_size = ntohc(check_ptr);

      if ( label_size & DNS_COMPRESSED_NAME_MASK ) {
         new_location = ntohs(check_ptr) & DNS_COMPRESSED_LOCATION_MASK;
         check_ptr    = buffer_ptr + new_location;
         label_size   = ntohc(check_ptr);
      } /* Endif */

      /*
      ** Some IP addresses using "in-addr.arpa" do not always have four
      ** labels, if this is the case, break out of the loop.
      */
      if ( label_size == 7 ) {
         break;
      } /* Endif */

      *temp_ptr++ = label_size;
      check_ptr++;
      total_size++;
      digit_count = 0;

     if (( label_size < 1 ) || ( label_size > 3 )) {
         _mem_free( free_buffer );
         return( RTCSERR_DNS_INVALID_IP_ADDR );
      } /* Endif */

      for ( j = 0; j < label_size; j++ ) {
         if ( digit_count == 0 ) {
              byte_num = 0;
         } /* Endif */
         digit_count++;

         if ( isdigit(ntohc(check_ptr)) ) {
            /* number is in range */
            byte_num    = byte_num + ntohc(check_ptr) - '0';
            byte_num    = byte_num * 10;
            *temp_ptr++ = ntohc(check_ptr);
            check_ptr++;
            total_size++;
         } else {
            /* if the characters are not decimal digits it's invalid */
            _mem_free( free_buffer );
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         } /* Endif */
      } /* Endfor */

      byte_num = byte_num / 10; /* shift back */

      if ( (byte_num < 0 ) || (byte_num > 255) ) {
         /* if the number does fall within this range it's invalid */
            _mem_free( free_buffer );
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         } /* Endif */
   } /* Endfor */

   if ( ntohc(check_ptr) != 7 ) {
      if ( ntohc(check_ptr) & DNS_COMPRESSED_NAME_MASK ) {
         new_location = ntohs(check_ptr) & DNS_COMPRESSED_LOCATION_MASK;
         check_ptr     = buffer_ptr + new_location;
         if ( ntohc(check_ptr) != 7 ) {
            _mem_free( free_buffer );
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         } /* Endif */

      }else {
         _mem_free( free_buffer );
         return( RTCSERR_DNS_INVALID_IP_ADDR  );
      } /* Endif */
   } /* Endif */

   *temp_ptr++ = ntohc(check_ptr);
   check_ptr++;

   /* should be "in-addr" */
   for ( i = 0; i < 7;  i++) {
      if ( tolower(ntohc(check_ptr)) != appended_name[i] ) {
         _mem_free( free_buffer );
         return( RTCSERR_DNS_INVALID_IP_ADDR  );
      } /* Endif */
      *temp_ptr++ = appended_name[i];
      check_ptr++;
   } /* Endfor */

   if ( ntohc(check_ptr) != 4 ) {
      if ( ntohc(check_ptr) & DNS_COMPRESSED_NAME_MASK ) {
         new_location = ntohs(check_ptr) & DNS_COMPRESSED_LOCATION_MASK;
         check_ptr     = buffer_ptr + new_location;
         if ( ntohc(check_ptr) != 4 ) {
            _mem_free( free_buffer );
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         } /* Endif */

      }else {
         _mem_free( free_buffer );
         return( RTCSERR_DNS_INVALID_IP_ADDR  );
      } /* Endif */
   } /* Endif */

   *temp_ptr++ = ntohc(check_ptr);
   check_ptr++;
   i++;

   /* should be "arpa" */
   for ( ; i < 12;  i++) {
      if ( tolower(ntohc(check_ptr)) != appended_name[i] ) {
         _mem_free( free_buffer );
         return( RTCSERR_DNS_INVALID_IP_ADDR  );
      } /* Endif */
      *temp_ptr++ = appended_name[i];
      check_ptr++;
   } /* Endfor */

   /*
   ** If we got this far, it's a legal IP addr, get a buffer,
   ** fill it with the address.
   */

   /*
   ** Total size is the size of the IP address, 14 is the size of
   ** "in-addr.arpa" including all label length chars and the terminating
   ** '\0' character.
   */
   total_size += sizeof(appended_name) + 2;
   *local_addr_buffer = (uchar _PTR_)RTCS_mem_alloc_zero( total_size );
   if ( *local_addr_buffer == NULL ) {
      // START CR 2178
      _mem_free( free_buffer );
      // END CR 2178
      RTCS_log_error(ERROR_DNS, DNS_SERVER_FAILURE, 2, 0, 0);
      return( DNS_SERVER_FAILURE );
   } /* Endif */

   _mem_copy(free_buffer, *local_addr_buffer, total_size);
   _mem_free( free_buffer );

   return( DNS_OK );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_is_valid_domain_name()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/


uint_32 DNS_is_valid_domain_name
   (
   uchar _PTR_         buffer_ptr,
   uchar _PTR_         domain_name,
   uchar _PTR_  _PTR_  local_name_buffer
   )

{ /* Body */
   uchar _PTR_  fill_ptr;
   uchar _PTR_  free_ptr;
   uchar _PTR_  check_name;
   uint_16      new_location;
   uint_32      total_length = 0;
   uint_32      label_size;
   uint_32      error;
   uint_32      i;

   error = DNS_is_valid_IP_addr(buffer_ptr, domain_name, local_name_buffer);
   if ( error != DNS_OK ) {
       /* If the request is for the ROOT Domain Name */
      if ( ntohc(domain_name) == '\0' ) {
         *local_name_buffer = (uchar _PTR_)RTCS_mem_alloc_zero( 1 );
         if ( *local_name_buffer == NULL ) {
            RTCS_log_error(ERROR_DNS, DNS_SERVER_FAILURE, 3, 0, 0);
            return( DNS_SERVER_FAILURE );
         } /* Endif */

         (*local_name_buffer)[0] = '\0';
         return( DNS_OK );
      } /* Endif */

      fill_ptr = (uchar _PTR_)RTCS_mem_alloc_zero( DNS_MAX_CHARS_IN_NAME );
      if ( fill_ptr == NULL ) {
         RTCS_log_error(ERROR_DNS, DNS_SERVER_FAILURE, 4, 0, 0);
         return( DNS_SERVER_FAILURE );
      } /* Endif */

      free_ptr = fill_ptr;
      check_name = domain_name;
      while ( ntohc(check_name) != '\0' ) {
         if ( ntohc(check_name) & DNS_COMPRESSED_NAME_MASK ) {
              new_location = ntohs(check_name) & DNS_COMPRESSED_LOCATION_MASK;
              check_name   = buffer_ptr + new_location;
         } /* Endif */

         label_size  = ntohc(check_name);
         *fill_ptr++ = label_size;
         check_name++;
         total_length++;

         /*
         ** RFC 1035 says labels must start with a letter, but in practice
         ** some aren't
         */
         if ( isalnum(ntohc(check_name)) ) {
            *fill_ptr++ = ntohc(check_name);
            check_name++;
            total_length++;
         } else {
            _mem_free( free_ptr );
            return( RTCSERR_DNS_INVALID_NAME );
         } /* Endif */


         for ( i = 1; i < label_size; i++ ) {
            /* Domain Name characters can only be letters, hyphens, or numbers */
            if ((isalnum(ntohc(check_name)) || ntohc(check_name) == '-' ) &&
                total_length < DNS_MAX_CHARS_IN_NAME ) {
               *fill_ptr++ = ntohc(check_name);
               check_name++;
               total_length++;
            } else {
               _mem_free( free_ptr );
               return( RTCSERR_DNS_INVALID_NAME );
            } /* Endif */
         } /* Endfor */
      } /* Endwhile */

      /* This is to append the terminating '\0' character to the string */
      *fill_ptr = '\0';
      total_length++;

      *local_name_buffer = (uchar _PTR_)RTCS_mem_alloc_zero( total_length );
      if ( *local_name_buffer == NULL ) {
          /* START CR 2178 */
            _mem_free( free_ptr );
          /* END CR 2178 */
            RTCS_log_error(ERROR_DNS, DNS_SERVER_FAILURE, 5, 0, 0);
            return( DNS_SERVER_FAILURE );
      } /* Endif */

      _mem_copy(free_ptr, *local_name_buffer, total_length);
      _mem_free( free_ptr );
      error = DNS_OK;
   } /* Endif */

   return( error );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_handle_new_query()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

 static uint_32 DNS_handle_new_query
   (
   DNS_CONTROL_STRUCT _PTR_ control_ptr,
   sockaddr_in        _PTR_ client_sin_ptr
   )

{ /* Body */

   DNS_INTERNAL_QUERY_STRUCT _PTR_  new_query_ptr;
   DNS_MESSAGE_HEADER_STRUCT _PTR_  message_head_ptr;
   DNS_MESSAGE_TAIL_STRUCT   _PTR_  message_tail_ptr;
   uchar                     _PTR_  qname_ptr;
   uchar                     _PTR_  temp_ptr;
   TIME_STRUCT                      time;
   uint_32                          buffer_size;
   uint_32                          local_name_size;
/* Start CR 2171 */
   int_32                           error=DNS_OK;
/* End CR 2171 */

   _time_get( &time );

   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)control_ptr->RES_BUFFER;
   qname_ptr = control_ptr->RES_BUFFER + sizeof( DNS_MESSAGE_HEADER_STRUCT );


   new_query_ptr = (DNS_INTERNAL_QUERY_STRUCT _PTR_)
      RTCS_part_alloc_zero(control_ptr->INT_QUERY_PARTID);
   if ( new_query_ptr == NULL ) {
      RTCS_log_error( ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY, 0, 0, 0);
      DNS_send_no_query_error_response( control_ptr, DNS_SERVER_FAILURE,
                                        client_sin_ptr );
      return( DNS_SERVER_FAILURE );
   } /* Endif */

   temp_ptr = qname_ptr;

   local_name_size = 0;
   while( (ntohc(temp_ptr) != '\0') &&
          local_name_size < DNS_MAX_CHARS_IN_NAME ) {
      local_name_size = local_name_size + ntohc(temp_ptr) + 1;
      temp_ptr  = temp_ptr  + ntohc(temp_ptr) + 1;
   } /* Endwhile */

   /* to include the last NULL (or compressed pointer) char */
   temp_ptr++;
   message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT _PTR_)temp_ptr;

   switch ( ntohs(message_tail_ptr->QTYPE) ) {

      case DNS_A:
         error = DNS_is_valid_domain_name( control_ptr->RES_BUFFER, qname_ptr,
                                           &new_query_ptr->QNAME_PTR );
         break;

      case DNS_PTR:
         error = DNS_is_valid_IP_addr( control_ptr->RES_BUFFER, qname_ptr,
                                       &new_query_ptr->QNAME_PTR );
         break;

      default:
         // Start CR 2171
         DNS_free_internal_query( new_query_ptr );
         DNS_send_no_query_error_response(control_ptr, DNS_QUERY_NOT_IMPLEMENTED,
                                          client_sin_ptr );
         return DNS_OK;
         // End CR 2171
   } /* Endswitch */

   if ( error == RTCSERR_DNS_INVALID_NAME || error == RTCSERR_DNS_INVALID_IP_ADDR ) {
      DNS_free_internal_query( new_query_ptr );
      DNS_send_no_query_error_response( control_ptr, DNS_NAME_ERROR,
                                        client_sin_ptr );
      return( DNS_OK );
   } /* Endif */

   if ( error == DNS_SERVER_FAILURE ) {
      DNS_free_internal_query( new_query_ptr );
      DNS_send_no_query_error_response( control_ptr, DNS_SERVER_FAILURE,
                                        client_sin_ptr );
      return( DNS_OK );
   } /* Endif */

   new_query_ptr->QTYPE          = ntohs(message_tail_ptr->QTYPE);
   new_query_ptr->QCLASS         = ntohs(message_tail_ptr->QCLASS);
   new_query_ptr->CONTROL        = ntohs(message_head_ptr->CONTROL)
                                   | DNS_RECURSION_DESIRED;

   new_query_ptr->CLIENT_SIN.sin_family      = client_sin_ptr->sin_family;
   new_query_ptr->CLIENT_SIN.sin_port        = client_sin_ptr->sin_port;
   new_query_ptr->CLIENT_SIN.sin_addr.s_addr =
                                            client_sin_ptr->sin_addr.s_addr;
   /*
   ** Check to see if the information is in the local cache. If it is,
   ** return it to the client, otherwise, make the query to a name server
   */
   buffer_size = DNS_rr_data_exists( new_query_ptr, control_ptr,
      control_ptr->RES_BUFFER, &control_ptr->RES_BUFFER_SIZE,
      DNS_RES_CACHE_DATA );

   if ( buffer_size != 0 ) {
      error = DNS_return_UDP_response_to_query( new_query_ptr,
                                                control_ptr->RES_BUFFER,
                                                buffer_size,
                                                control_ptr->RES_SOCKET );
      return( DNS_OK );
   } /* Endif */

   new_query_ptr->TTL            = DNS_QUERY_RETRY_TIME;
   new_query_ptr->QUERY_ID       = DNS_get_query_id();
   new_query_ptr->QUERY_RETRIES  = DNS_MAX_NUMBER_OF_QUERY_TRIES;
   new_query_ptr->LAST_TTL_CHECK = time.SECONDS;
   new_query_ptr->NEXT           = NULL;
   new_query_ptr->SERVER_IPADDR  = 0;

   error = DNS_get_best_name_server_for_query( new_query_ptr,
                                               control_ptr );
   if ( error != DNS_OK ) {
      DNS_send_error_response( control_ptr->RES_BUFFER, new_query_ptr,
                               DNS_SERVER_FAILURE, control_ptr->RES_SOCKET,
                               error );
      return( RTCSERR_DNS_UNABLE_TO_SEND_QUERY );
   } /* Endif */

   error = DNS_Send_UDP_Query( control_ptr, new_query_ptr, FALSE );
   if ( error != DNS_OK ) {
      DNS_send_error_response( control_ptr->RES_BUFFER, new_query_ptr,
                               DNS_SERVER_FAILURE, control_ptr->RES_SOCKET,
                               error );
       return( RTCSERR_DNS_UNABLE_TO_SEND_QUERY );
   } /* Endif */

   error = DNS_add_query_to_list( &control_ptr->RES_QUERY_HEAD_PTR,
                                  new_query_ptr );
   if ( error != DNS_OK ) {
      DNS_send_error_response( control_ptr->RES_BUFFER, new_query_ptr,
                               DNS_SERVER_FAILURE, control_ptr->RES_SOCKET,
                               error );
   } /* Endif */

   return( error );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_retrieve_query()
* Returned Value  : DNS_INTERNAL_QUERY_STRUCT_PTR
* Comments        :
*
*END*-----------------------------------------------------------------*/


static DNS_INTERNAL_QUERY_STRUCT _PTR_ DNS_retrieve_query
   (
   uint_16                               id,
   DNS_INTERNAL_QUERY_STRUCT _PTR_ _PTR_ query_head_ptr
   )

{ /* Body */

   DNS_INTERNAL_QUERY_STRUCT _PTR_ previous_ptr = NULL;
   DNS_INTERNAL_QUERY_STRUCT _PTR_ next_query_ptr;

   next_query_ptr  = *query_head_ptr;

   while ( next_query_ptr != NULL ) {
      if ( next_query_ptr->QUERY_ID == id ) {
         if ( previous_ptr != NULL ) {
            previous_ptr->NEXT  = next_query_ptr->NEXT;
            break;
         } else {
            *query_head_ptr = next_query_ptr->NEXT;
            break;
         } /* Endif */
      } /* Endif */
      previous_ptr = next_query_ptr;
      next_query_ptr = next_query_ptr->NEXT;
   } /* Endwhile */

   return( next_query_ptr );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_remove_last_entry_from_cache
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/
static void DNS_remove_last_entry_from_cache
   (
   DNS_CONTROL_STRUCT _PTR_ control_ptr
   )
{ /* Body */
   DNS_RR_LIST_STRUCT _PTR_  _PTR_ rr_list_ptr = &control_ptr->CACHE_PTR;
   DNS_RR_HEADER_STRUCT      _PTR_ rr_ptr;
   DNS_RR_HEADER_STRUCT      _PTR_ free_ptr;


   if (*rr_list_ptr) {
      while ((*rr_list_ptr)->NEXT) {
         /* Run the list, we have to delete the last entry. */
         rr_list_ptr = &(*rr_list_ptr)->NEXT;
      } /* Endwhile */

      /* Delete the entry */
      if ( control_ptr->NUM_NAMES_CACHED > 0 ) {
         control_ptr->NUM_NAMES_CACHED--;
      }/* Endif */

      rr_ptr = (*rr_list_ptr)->RR_HEAD_PTR;
      while (rr_ptr) {
         free_ptr = rr_ptr;
         rr_ptr = rr_ptr->NEXT;
         DNS_free_resource_record(free_ptr);
      } /* Endwhile */

      _mem_free((*rr_list_ptr)->NAME_PTR);
      RTCS_part_free(*rr_list_ptr);
      *rr_list_ptr = NULL;
   }/* Endif */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_add_to_cache()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

static void DNS_add_to_cache
   (
   DNS_CONTROL_STRUCT _PTR_ control_ptr,
   uint_32                 module
   )

{ /* Body */

   DNS_MESSAGE_HEADER_STRUCT     _PTR_ message_head_ptr;
   DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_ answer_middle_ptr;
   DNS_RR_HEADER_STRUCT          _PTR_ rr_head_ptr;
   DNS_RR_HEADER_STRUCT          _PTR_ temp_cache_ptr;
   DNS_RR_HEADER_STRUCT          _PTR_ previous_cache_ptr = NULL;
   DNS_RR_LIST_STRUCT            _PTR_ rr_list_ptr;
   DNS_ADDR_RECORD_STRUCT        _PTR_ addr_rr_ptr;
   DNS_NAME_RECORD_STRUCT        _PTR_ name_rr_ptr;
   TIME_STRUCT                         time;
   uchar                         _PTR_ buffer_ptr = NULL;
   uchar                         _PTR_ answer_head_ptr;
   uchar                         _PTR_ temp_ptr;
   uint_16                             num_answers;
   uint_16                             control;
   uint_16                             answer_length;
   uint_32                             i;
   uint_32                             error;
   int_32                              cmp_val;
   int_32                              ttl;

   if ( module == DNS_NS_CACHE_DATA ) {
      buffer_ptr = control_ptr->NS_BUFFER;
   } /* Endif */

   if ( module == DNS_RES_CACHE_DATA ) {
      buffer_ptr = control_ptr->RES_BUFFER;
   } /* Endif */

   if ( buffer_ptr != NULL ) {
      DNS_assign_answer_pointers(buffer_ptr, &answer_head_ptr,
                                 &answer_middle_ptr );
      message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)buffer_ptr;
      num_answers = ntohs(message_head_ptr->ANCOUNT);

      control = ntohs(message_head_ptr->CONTROL);
      if ( (control & DNS_TRUNCATION) == 0 ) {
         /* If the truncation bit is not set, cache information */
         for ( i = 0; (i < num_answers) && answer_middle_ptr; i++ ) {
            ttl           = ntohl(answer_middle_ptr->TTL);
            answer_length = ntohs(answer_middle_ptr->RDLENGTH);
            temp_ptr      = (uchar _PTR_)answer_middle_ptr;
            temp_ptr      += sizeof(DNS_RESPONSE_RR_MIDDLE_STRUCT);

            if ( (ttl == 0) || (ttl > DNS_MAX_ALLOWED_TTL)) {

               /* bypass this answer, set the pointers for the next one */
               temp_ptr = temp_ptr + answer_length;
               answer_head_ptr = temp_ptr;
               answer_middle_ptr = DNS_assign_answer_middle_ptr(answer_head_ptr,
                                                                num_answers, i);
               continue;
            } /* Endif */

            if ((control & DNS_NAME_ERROR) != 0 ) {
               if ((control & DNS_AUTHORITATIVE_NAME_ERROR) !=
                   DNS_AUTHORITATIVE_NAME_ERROR ) {
                  /*
                  ** Don't cache this answer if the name error isn't
                  ** authoritative.
                  */
                  break;
               } /* Endif */
            } /* Endif */

            switch ( ntohs(answer_middle_ptr->TYPE) ) {
               case DNS_A:
                  addr_rr_ptr = (DNS_ADDR_RECORD_STRUCT _PTR_)
                     RTCS_part_alloc_zero(control_ptr->ADDR_RR_PARTID);
                  if (!addr_rr_ptr) {
                    RTCS_log_error(ERROR_DNS, DNS_SERVER_FAILURE, 5, 0, 0);
                    return;
                  }/* Endif */
                  addr_rr_ptr->IPADDR = ntohl((uchar_ptr)temp_ptr);
                  rr_head_ptr = (DNS_RR_HEADER_STRUCT _PTR_)
                     ((void _PTR_)addr_rr_ptr);
                  break;

               case DNS_PTR:
               case DNS_CNAME:
               case DNS_NS:
                  name_rr_ptr = (DNS_NAME_RECORD_STRUCT _PTR_)
                     RTCS_part_alloc_zero(control_ptr->NAME_RR_PARTID);
                  if (!name_rr_ptr) {
                    RTCS_log_error(ERROR_DNS, DNS_SERVER_FAILURE, 5, 0, 0);
                    return;
                  }/* Endif */
                  error = DNS_is_valid_domain_name(buffer_ptr, temp_ptr,
                                                &name_rr_ptr->ANS_NAME_PTR );
                  if ( error != DNS_OK ) {
                     RTCS_part_free(name_rr_ptr);
                     /* set pointers for next answer */
                     temp_ptr = temp_ptr + answer_length;
                     answer_head_ptr = temp_ptr;
                     answer_middle_ptr = DNS_assign_answer_middle_ptr(
                                                              answer_head_ptr,
                                                              num_answers, i );
                     continue;
                  } /* Endif */
                  rr_head_ptr = (DNS_RR_HEADER_STRUCT _PTR_)
                     ((void _PTR_)name_rr_ptr);
                  break;

               default:
                  /* Unknown type, don't cache */
                  /* set pointers for next answer */
                  temp_ptr = temp_ptr + answer_length;
                  answer_head_ptr = temp_ptr;
                  answer_middle_ptr = DNS_assign_answer_middle_ptr(
                                                              answer_head_ptr,
                                                              num_answers, i );
                  continue;
            } /* Endswitch */

            if ( (control & DNS_AUTHORITATIVE_NAME_ERROR) !=
                 DNS_AUTHORITATIVE_NAME_ERROR ) {
               rr_head_ptr->TTL = ttl;
            } else {
               rr_head_ptr->TTL = DNS_NAME_ERROR_TTL;
            } /* Endif */

            rr_head_ptr->CLASS = ntohs(answer_middle_ptr->CLASS);
            rr_head_ptr->TYPE  = ntohs(answer_middle_ptr->TYPE);
            rr_head_ptr->NEXT  = NULL;

            /*
            ** May have to check name format here. Answers may truncate
            ** differently when same answer name is used more than once.
            */
            error = DNS_is_valid_domain_name(buffer_ptr, answer_head_ptr,
                                             &rr_head_ptr->DOMAIN_NAME_PTR );
            if ( error != DNS_OK ) {
               DNS_free_resource_record( rr_head_ptr );
               /* set pointers for next answer */
               temp_ptr = temp_ptr + answer_length;
               answer_head_ptr = temp_ptr;
               answer_middle_ptr = DNS_assign_answer_middle_ptr(
                                                              answer_head_ptr,
                                                              num_answers, i );
               continue;
            } /* Endif */

            _time_get( &time );
            rr_head_ptr->LAST_TTL_CHECK = time.SECONDS;
            /*
            ** need exclusive access, both the Resolver and Name Server can
            ** modify the cache
            */
            RTCS_mutex_lock(&control_ptr->CACHE_MUTEX);
            rr_list_ptr = control_ptr->CACHE_PTR;

            while ( rr_list_ptr != NULL ) {
               cmp_val = strcmp((char _PTR_)rr_head_ptr->DOMAIN_NAME_PTR,
                                (char _PTR_)rr_list_ptr->NAME_PTR );
               if ( cmp_val == 0 ) {
                  /* The two are equal, cached data for this name exists. */
                  break;
               } /* Endif */
               rr_list_ptr = rr_list_ptr->NEXT;
            } /* Endwhile */

            if ( rr_list_ptr == NULL ) {
               /* We're either at the head or the tail of the list */
               rr_list_ptr = (DNS_RR_LIST_STRUCT _PTR_)
                  RTCS_part_alloc_zero(control_ptr->RR_LIST_PARTID);
               if ( rr_list_ptr == NULL ) {
                  RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY, 0, 0, 0);
                  _mem_free( rr_head_ptr->DOMAIN_NAME_PTR );
                  DNS_free_resource_record( rr_head_ptr );
                  /* set pointers for next answer */
                  temp_ptr = temp_ptr + answer_length;
                  answer_head_ptr = temp_ptr;
                  answer_middle_ptr = DNS_assign_answer_middle_ptr(
                                                              answer_head_ptr,
                                                              num_answers, i );
                  continue;
               } /* Endif */

               rr_list_ptr->NAME_PTR    = rr_head_ptr->DOMAIN_NAME_PTR;
               rr_list_ptr->RR_HEAD_PTR = rr_head_ptr;
               rr_list_ptr->NEXT        = control_ptr->CACHE_PTR;
               control_ptr->CACHE_PTR    = rr_list_ptr;
               control_ptr->NUM_NAMES_CACHED++;
            } else {
               /*
               ** Cached data using the same name exists, search the
               ** existing sub-list under the name for the same record type
               */
               temp_cache_ptr = rr_list_ptr->RR_HEAD_PTR;
               while ( temp_cache_ptr != NULL ) {
                  if ( temp_cache_ptr->TYPE == rr_head_ptr->TYPE ) {
                  /* cached data of this type exists, replace with new stuff */
                     break;
                  } /* Endif */
                  previous_cache_ptr = temp_cache_ptr;
                  temp_cache_ptr     = temp_cache_ptr->NEXT;
               } /* Endwhile */

               if ( temp_cache_ptr == NULL ) {
                  /* data of this type doesn't exist. Insert new stuff */
                  rr_head_ptr->NEXT        = rr_list_ptr->RR_HEAD_PTR;
               } else {
                  /* This data exists previously, replace it */
                  rr_head_ptr->NEXT = rr_list_ptr->RR_HEAD_PTR->NEXT;

                  if ( previous_cache_ptr == NULL ) {
                     /* We're at the head of the list */
                     DNS_free_resource_record( rr_list_ptr->RR_HEAD_PTR );
                  } else {
                     previous_cache_ptr->NEXT = temp_cache_ptr->NEXT;
                     DNS_free_resource_record( temp_cache_ptr );
                  } /* Endif */
               } /* Endif */
               rr_list_ptr->RR_HEAD_PTR = rr_head_ptr;
               /*
               ** We only keep one reference to the name for the resource
               ** records for any given name.  Since a node was pre-existing,
               ** just have this record refer to it's string, and free the
               ** one we allocated.
               */
               _mem_free(rr_head_ptr->DOMAIN_NAME_PTR);
               rr_head_ptr->DOMAIN_NAME_PTR = rr_list_ptr->NAME_PTR;
            } /* Endif */
            RTCS_mutex_unlock(&control_ptr->CACHE_MUTEX);
            temp_ptr = temp_ptr + answer_length;
            answer_head_ptr = temp_ptr;
            answer_middle_ptr = DNS_assign_answer_middle_ptr( answer_head_ptr,
                                                              num_answers, i );
         } /* Endfor */

         while(DNS_CACHE_NAME_LIMIT &&
            (control_ptr->NUM_NAMES_CACHED > DNS_CACHE_NAME_LIMIT) &&
            /* This is here as a paranoid check to break out of loop. */
            control_ptr->CACHE_PTR)
         {
            /*
            ** We're over the limit, delete the last entry in the cache until
            ** we're at the limit.
            */
            DNS_remove_last_entry_from_cache(control_ptr);
         }/* Endwhile */
      } /* Endif */
   } /* Endif */
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_retry_query_with_CNAME()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_retry_query_with_CNAME
   (
   DNS_CONTROL_STRUCT         _PTR_ control_ptr,
   DNS_INTERNAL_QUERY_STRUCT _PTR_ query_ptr,
   DNS_RESPONSE_RR_MIDDLE_STRUCT  _PTR_ answer_ptr
   )

{ /* Body */
   DNS_CNAME_STRUCT  _PTR_ _PTR_  previous_ptr;
   DNS_CNAME_STRUCT  _PTR_  temp_ptr;
   DNS_CNAME_STRUCT  _PTR_  new_cname_ptr;
   uchar             _PTR_  cname_ptr;
   int_32                   error;
   uint_32                  cname_retries = 0;
   int_32                   cmp_result;

   cname_ptr = (uchar _PTR_)answer_ptr;
   cname_ptr += sizeof( DNS_RESPONSE_RR_MIDDLE_STRUCT );

   new_cname_ptr = (DNS_CNAME_STRUCT _PTR_)
      RTCS_part_alloc_zero(control_ptr->CNAME_PARTID);
   if ( !new_cname_ptr ) {
      RTCS_log_error(ERROR_DNS, DNS_SERVER_FAILURE, 5, 0, 0);
      return( DNS_SERVER_FAILURE );
   }/* Endif */
   error = DNS_is_valid_domain_name( control_ptr->RES_BUFFER, cname_ptr,
                           (uchar _PTR_ _PTR_)&new_cname_ptr->CNAME_PTR );
   if ( error != DNS_OK ) {
      DNS_send_error_response( control_ptr->RES_BUFFER,
                               query_ptr, DNS_NAME_ERROR,
                               control_ptr->RES_SOCKET, DNS_OK );
   } /* Endif */

   previous_ptr = &query_ptr->CNAME;

   temp_ptr = *previous_ptr;

   while ( temp_ptr != NULL ) {
      cmp_result = strcmp((char _PTR_)new_cname_ptr->CNAME_PTR,
         (char _PTR_)temp_ptr->CNAME_PTR );
      if ( cmp_result == 0 ) {
         /* the names are equal, we have a CNAME loop, return error */
         _mem_free(new_cname_ptr->CNAME_PTR);
         RTCS_part_free(new_cname_ptr);
         DNS_send_error_response( control_ptr->RES_BUFFER,
                                  query_ptr, DNS_NAME_ERROR,
                                  control_ptr->RES_SOCKET, DNS_OK );
         error = DNS_NAME_ERROR;
         break;
      } /* Endif */
      cname_retries++;
      if ( cname_retries == DNS_MAX_NUM_CNAME_RETRIES ) {
         /* BIND only allows for 8 CNAME query retries */
         _mem_free(new_cname_ptr->CNAME_PTR);
         RTCS_part_free(new_cname_ptr);
         error = DNS_return_UDP_response_to_query( query_ptr,
                                                   control_ptr->RES_BUFFER,
                                                   control_ptr->RES_BUFFER_SIZE,
                                                   control_ptr->RES_SOCKET );
         error = DNS_NAME_ERROR;
         break;
      } /* Endif */
      previous_ptr = &(*previous_ptr)->NEXT;
      temp_ptr     = *previous_ptr;
   } /* Endwhile */

   if ( error == DNS_OK ) {
      *previous_ptr  = new_cname_ptr;
      new_cname_ptr->NEXT = NULL;
      query_ptr->QUERY_ID  = DNS_get_query_id();

      error = DNS_Send_UDP_Query( control_ptr, query_ptr, TRUE );
      if ( error == RTCS_ERROR ) {
         DNS_send_error_response( control_ptr->RES_BUFFER, query_ptr,
                                  DNS_SERVER_FAILURE, control_ptr->RES_SOCKET,
                                  error );
      } else {

      DNS_add_query_to_list( &control_ptr->RES_QUERY_HEAD_PTR, query_ptr );

      } /* Endif */
   } /* Endif */

   return( error );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_search_response_for_referral()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_search_response_for_referral
   (
   DNS_CONTROL_STRUCT         _PTR_ control_ptr,
   DNS_INTERNAL_QUERY_STRUCT _PTR_ query_ptr
   )

{ /* Body */

   /* NOT IMPLEMENTED */

   /* SPR P122-0258-01
   ** This is here to get the resolver to return quickly when a name
   ** that doesn't exist is queried for, since we only support queries
   ** to a single DNS Server for now. When multiple DNS Server support
   ** is added, remove this function call and allow for proper resend
   ** behaviour.
   */

   DNS_send_error_response( control_ptr->RES_BUFFER,
                            query_ptr, DNS_QUERY_NOT_IMPLEMENTED,
                            control_ptr->RES_SOCKET, DNS_OK );
   /* END SPR P122-0258-01 */

   return( DNS_OK );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_handle_internal_query()
* Returned Value  : DNS_INTERNAL_QUERY_STRUCT_PTR
* Comments        : This function is for the Name Server or Resolver to
*                   make queries for NS records to be used to make queries
*                   for authoritative data if the original query fails.
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_handle_internal_query
   (
   DNS_CONTROL_STRUCT         _PTR_ control_ptr,
   DNS_INTERNAL_QUERY_STRUCT _PTR_ query_ptr
   )

{ /* Body */
   return( DNS_OK );
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_Send_TCP_Query()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/



 static uint_32 DNS_Send_TCP_Query
    (
    DNS_CONTROL_STRUCT         _PTR_ control_ptr,
    DNS_INTERNAL_QUERY_STRUCT _PTR_ query_ptr
    )

{ /* Body */

   /* NOT IMPLEMENTED */
   DNS_send_error_response( control_ptr->RES_BUFFER,
                            query_ptr, DNS_QUERY_NOT_IMPLEMENTED,
                            control_ptr->RES_SOCKET, DNS_OK );

   return( DNS_OK );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_handle_UDP_response()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

 static uint_32 DNS_handle_UDP_response
   (
   DNS_CONTROL_STRUCT   _PTR_ control_ptr
   )

{ /* Body */

   DNS_MESSAGE_HEADER_STRUCT     _PTR_  message_head_ptr;
   DNS_MESSAGE_TAIL_STRUCT       _PTR_  message_tail_ptr;
   DNS_INTERNAL_QUERY_STRUCT     _PTR_  query_ptr;
   DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_  answer_middle_ptr;
   uchar                         _PTR_  answer_ptr;
   TIME_STRUCT                          time;
   uint_16                              answer_count;
   uint_16                              control;
   uint_16                              answer_type;
   int_32                               error = DNS_OK;

   _time_get( &time );
   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)control_ptr->RES_BUFFER;
   answer_count     = ntohs( message_head_ptr->ANCOUNT );
   control          = ntohs( message_head_ptr->CONTROL );
   query_ptr        = DNS_retrieve_query( ntohs(message_head_ptr->ID),
                                           &control_ptr->RES_QUERY_HEAD_PTR );
   if ( query_ptr != NULL ) {
      /* Query still exists, respond accordingly */

 /* Start CR 1965 */
         if ( query_ptr->INTERNAL_QUERY == TRUE ) {
            /* Name Server query was made by resolver, not for a client */
            error = DNS_handle_internal_query( control_ptr, query_ptr );
            if ( error != DNS_OK ) {
               DNS_send_error_response( control_ptr->RES_BUFFER,
                                        query_ptr, DNS_SERVER_FAILURE,
                                        control_ptr->RES_SOCKET, error );
            } /* Endif */
         } else {
            if ( answer_count != 0 ) {
               /* An answer was received, respond accordingly */
               /*
               ** Cache the response, so we don't have to request whatever was
               ** given to us in the future.
               */
               DNS_add_to_cache( control_ptr, DNS_RES_CACHE_DATA );
               DNS_assign_answer_pointers( control_ptr->RES_BUFFER, &answer_ptr,
                                           &answer_middle_ptr );
               if ( answer_middle_ptr ) {
                  message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT _PTR_)(answer_ptr
                     - sizeof(DNS_MESSAGE_TAIL_STRUCT));
                  answer_type = ntohs(answer_middle_ptr->TYPE);

                  if ( answer_type == ntohs(message_tail_ptr->QTYPE) ) {
                     /* Answer is what we wanted as a response, return to client */
                     error = DNS_return_UDP_response_to_query( query_ptr,
                        control_ptr->RES_BUFFER, control_ptr->RES_BUFFER_SIZE,
                        control_ptr->RES_SOCKET );
                  } else {
                     /*
                     ** An answer exists, but it's not what we want.  Check all
                     ** the answers to see if what we are looking for is in the
                     ** buffer at all.  If it is, return the buffer to the client,
                     ** if not, use the information received to make another query
                     */
                     if ( answer_type == DNS_CNAME ) {
                        if ( query_ptr->QUERY_RETRIES-- <= 0 ) {
                           DNS_send_error_response( control_ptr->RES_BUFFER,
                              query_ptr, DNS_QUERY_REFUSED,
                              control_ptr->RES_SOCKET, DNS_OK );
                        } else {
                           /*
                           ** If we get here, an answer exists, but doesn't
                           ** match query type, or there is more than one
                           ** answer, since we've cached the response, check
                           ** the cache again to see if the answer was in the
                           ** packet we received.  If it isn't there, retry the
                           ** query using the cannonical name reference.
                           */
                           if (DNS_rr_data_exists( query_ptr, control_ptr,
                               control_ptr->RES_BUFFER,
                               &control_ptr->RES_BUFFER_SIZE, DNS_RES_CACHE_DATA))
                           {
                              error = DNS_return_UDP_response_to_query(
                                 query_ptr, control_ptr->RES_BUFFER,
                                 control_ptr->RES_BUFFER_SIZE,
                                 control_ptr->RES_SOCKET );
                           } else {
                              error = DNS_retry_query_with_CNAME( control_ptr,
                                 query_ptr, answer_middle_ptr);
                           } /* Endif */
                        } /* Endif */
                     } /* Endif */
                  } /* Endif */
               } /* Endif */
            } else {
               /*
               ** No answer exists in the response.  Check Name Server records
               ** for referrals to retry query.  Also check additional records.
               ** and RCODE for clues to retry the query.
               */
               error = DNS_search_response_for_referral( control_ptr,
                  query_ptr );

               if ( control & DNS_TRUNCATION ) {
                  /* If the message was truncated, retry the query using TCP */
                  error = DNS_Send_TCP_Query( control_ptr, query_ptr );
            } /* Endif */
         } /* Endif */
      } /* Endif */
/* End CR 1965 */
/* Start CR 1119 */
#if 0
   } else {
      /*
      ** Query doesn't exist anymore.  Cache if answer is authoritative,
      ** otherwise, do nothing
      */
      if ( ((control & DNS_RCODE_MASK) == DNS_NO_ERROR ||
            (control & DNS_RCODE_MASK) == DNS_NAME_ERROR) &&
            (control & DNS_AUTHORITATIVE_ANSWER) ) {
         DNS_add_to_cache( control_ptr, DNS_RES_CACHE_DATA );
      } /* Endif */
#endif
/* End CR 1119 */
   } /* Endif */

   return( error );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_refresh_root_servers_task()
* Returned Value  :
* Comments        :
*
*END*-----------------------------------------------------------------*/

static void DNS_refresh_root_servers_task
   (
   uint_32 temp_ptr
   )
{ /* Body */

  /*NOT IMPLEMENTED */
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_refresh_root_servers()
* Returned Value  :
* Comments        :
*
*END*-----------------------------------------------------------------*/

 static uint_32 DNS_refresh_root_servers
   (
   DNS_CONTROL_STRUCT _PTR_ control_ptr
   )
{ /* Body */

  /* NOT IMPLEMENTED */
  return( DNS_OK );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_Resolver_task()
* Returned Value  :
* Comments        :
*
*END*-----------------------------------------------------------------*/

void DNS_Resolver_task
   (
   pointer new_control_ptr,
   pointer creator
   )
{ /* Body */

   DNS_CONTROL_STRUCT         _PTR_  control_ptr;
   DNS_MESSAGE_HEADER_STRUCT _PTR_  message_head_ptr;
   DNS_SLIST_STRUCT          _PTR_  first_root_ptr;
   sockaddr_in                      addr;
   TIME_STRUCT                      time;
   uint_32                          difference;
   uint_16                          rlen;
   int_32                           error;

   control_ptr = (DNS_CONTROL_STRUCT _PTR_)new_control_ptr;

   /*
   ** Root Server List updating is not yet implemented,
   ** remove "control_ptr->UPDATING = TRUE;" when it is coded.
   */
   control_ptr->UPDATING = TRUE;

   _mem_zero((uchar _PTR_) &addr, sizeof(addr));

   addr.sin_family      = AF_INET;
   addr.sin_port        = DNS_RESOLVER_PORT;
   addr.sin_addr.s_addr = INADDR_ANY;

   error = RTCS_attachsock( control_ptr->RES_SOCKET );
   if ( error == (int_32)RTCS_SOCKET_ERROR ) {
      RTCS_task_exit(creator, RTCSERR_DNS_INITIALIZATION_FAILURE);
   } /* Endif */

   error = bind(control_ptr->RES_SOCKET, &addr, sizeof(sockaddr_in));
   if ( error != RTCS_OK ) {
      RTCS_task_exit(creator, RTCSERR_DNS_INITIALIZATION_FAILURE);
   } /* Endif */
   RTCS_task_resume_creator(creator, RTCS_OK);

   while ( TRUE ) {

      _time_get ( &time );

      /*
      ** Check the TTL expiry time for root name servers, if expired
      ** call refresh function to update them
      */
      first_root_ptr = (DNS_SLIST_STRUCT _PTR_)control_ptr->ROOT_SLIST_PTR;
      difference = time.SECONDS - first_root_ptr->LAST_TTL_CHECK;
      first_root_ptr->LAST_TTL_CHECK = time.SECONDS;

      RTCS_mutex_lock(&control_ptr->CACHE_MUTEX);
      if (first_root_ptr->TTL <= difference
          && ( control_ptr->UPDATING == FALSE )) {
         RTCS_mutex_unlock(&control_ptr->CACHE_MUTEX);
         error = DNS_refresh_root_servers( control_ptr );
         if ( error != DNS_OK ) {
            RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_UPDATE_ROOT_SERVERS, 0, 0, 0);
         } /* Endif */
      } else {
         RTCS_mutex_unlock(&control_ptr->CACHE_MUTEX);
         first_root_ptr->TTL = first_root_ptr->TTL - difference;
      } /* Endif */

      DNS_check_outstanding_queries( control_ptr );

      if ( control_ptr->NS_BUFFER == NULL ) {
         /*
         ** If the Name Server task is running, it has the responsibility
         ** to update the cache(using the mutex!), if it isn't, let the
         ** resolver do it.
         */
         /*
         ** Don't need the mutex here, since the DNS Server doesn't exist on
         ** the target, the resolver will be the only task accessing it.
         */
         DNS_update_cache(control_ptr);
      } /* Endif */

      /*
      ** now wait for queries or responses, bypass rest of while loop
      ** if none are received
      */

      error = (uint_32)RTCS_selectset( &control_ptr->RES_SOCKET, 1,
                                       DNS_RESOLVER_RETRY_TIME );

      if (( error == (uint_32)NULL ) || ( error == RTCS_ERROR )) {
         continue;
      } /* Endif */


      /* Received a message, respond accordingly */
      rlen = sizeof(addr);
      control_ptr->RES_BUFFER_SIZE = recvfrom(control_ptr->RES_SOCKET,
                                             control_ptr->RES_BUFFER,
                                             DNS_MAX_UDP_MESSAGE_SIZE,
                                             0, &addr, &rlen);
      if (control_ptr->RES_BUFFER_SIZE == RTCS_ERROR) {
         RTCS_log_error(ERROR_DNS, RTCSERR_DNS_SOCKET_RECV_ERROR, 0, 0, 0);
         continue;
      } /* Endif */

/* Start CR 1119 */
      if (control_ptr->RES_BUFFER_SIZE < sizeof(DNS_MESSAGE_HEADER_STRUCT)) {
         RTCS_log_error(ERROR_DNS, RTCSERR_DNS_SHORT_MESSAGE_ERROR, 0, 0, 0);
         continue;
      } /* Endif */
/* End CR 1119 */

      message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT_PTR)control_ptr->RES_BUFFER;

      if ( ntohs(message_head_ptr->CONTROL) & DNS_RESPONSE ) {
         /* It's a response to a query, parse and return it to client */
         error = DNS_handle_UDP_response( control_ptr );
         if ( error != DNS_OK ) {
            RTCS_log_error( ERROR_DNS, error, 0, 0, 0);
         } /* Endif */
      } else {
         if (addr.sin_addr.s_addr == INADDR_LOOPBACK) {
            /* It's a new query */
            error = DNS_handle_new_query( control_ptr, &addr );
         } else {
            error = ERROR_DNS;
         } /* Endif */
         if ( error != DNS_OK ) {
            RTCS_log_error( ERROR_DNS, error, 0, 0, 0);
         } /* Endif */
      } /* Endif */
   } /* Endwhile */

} /* Endbody */

#endif



#if RTCSCFG_ENABLE_LWDNS

_ip_address LWDNS_server_ipaddr = 0;

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : LWDNS_Send_Query()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/


static uint_32 LWDNS_Send_Query
   (
   uint_32     sock,
   char_ptr    name_to_resolve,
   char_ptr    send_buffer,
   uint_32_ptr id_ptr
   )
{
   DNS_MESSAGE_HEADER_STRUCT_PTR    message_head_ptr;
   DNS_MESSAGE_TAIL_STRUCT_PTR      message_tail_ptr;
   int_32                           error;
   uint_32                          i;
   uint_32                          name_size;
   char_ptr                         name_ptr,len_ptr;
   uint_16                          id;
   uchar                            len;


   name_size = strlen((char _PTR_)name_to_resolve ) ; //To include the terminating NULL char

   /* set up buffer for sending query.   */
   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)send_buffer;
   name_ptr  = &send_buffer[sizeof(DNS_MESSAGE_HEADER_STRUCT)];
   id = RTCS_rand(); // TASK_NUMBER_FROM_TASKID(_task_get_id()) ;
   if (id_ptr) {
      *id_ptr = id;
   }
   htons(message_head_ptr->ID, id );
   htons(message_head_ptr->CONTROL, DNS_STANDARD_QUERY|DNS_RECURSION_DESIRED);
   htons(message_head_ptr->QDCOUNT, DNS_SINGLE_QUERY);
   htons(message_head_ptr->ANCOUNT, 0);
   htons(message_head_ptr->NSCOUNT, 0);
   htons(message_head_ptr->ARCOUNT, 0);

   len_ptr=name_ptr;
   len=0;
   if (*name_ptr != '.')
      name_ptr++;

   for (i=0;i<name_size;i++) {
      if (name_to_resolve[i] == '.') {
         *len_ptr = len;
         len = 0;
         len_ptr = name_ptr;
      } else {
         htonc(name_ptr, name_to_resolve[i]);
         len++;
      }
     name_ptr++;
   }
   *len_ptr = len;
    *name_ptr++ = 0;

   message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT _PTR_) name_ptr;
   name_ptr += sizeof(DNS_MESSAGE_TAIL_STRUCT);

   htons(message_tail_ptr->QTYPE, DNS_A);
   htons(message_tail_ptr->QCLASS, DNS_IN);


   error = send(sock, send_buffer, (name_ptr-send_buffer), 0);

   if (error == RTCS_ERROR) {
      error = RTCS_geterror(sock);
   } else {
      error = DNS_OK;
   }

   return( error );
}

static boolean domains_equal(char_ptr req_domain, char_ptr res_domain)
{
   uint_32  req_index=0,res_index=0,i;
   uchar    len, c;

   len = ntohc (res_domain + res_index);
   res_index++;
   do {
      if ( len & DNS_COMPRESSED_NAME_MASK ) {
         return FALSE;
      }
      for (i=0;i<len;i++) {
         if (req_domain[req_index++] != tolower(res_domain[res_index++])) {
            return FALSE;
         }
      }
      len = ntohc (res_domain + res_index);
      res_index++;
      c = ntohc (req_domain + req_index);
      req_index++;
   } while (len && (c == '.'));
   return (len ==0) && (c==0);
}

static boolean domain_name_extract(uint_32 start, char_ptr rx_buffer,char_ptr ipname,uint_32 ipnamesize)
{
   uint_32 s_index=start, d_index=0,i;
   uchar   b;

   do {
      b = ntohc (rx_buffer + s_index);
      if ( b & DNS_COMPRESSED_NAME_MASK ) {
          s_index = ntohs(rx_buffer + s_index) & DNS_COMPRESSED_LOCATION_MASK;
      } else {
         s_index++;
         for (i=0;i<b;i++) {
            if (d_index >= ipnamesize-1) break;
            ipname[d_index++] = rx_buffer[s_index++];
         }
         if (d_index >= ipnamesize-1) break;
         ipname[d_index++] = '.';
      }
   } while (rx_buffer[s_index]);

   if (d_index) {
      ipname[--d_index] = 0;
   } else {
      ipname[0] = 0;
   }

   return TRUE;
}

static uint_32 domain_name_fragment_length(uchar_ptr name)
{
   uint_32 i=0;

   while ( (name[i] != 0) && ((ntohc (name + i) & DNS_COMPRESSED_NAME_MASK) == 0)) {
      i++;
   }
   return (name[i]?i+2:i+1);
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : LWDNS_Get_Response()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

 static boolean LWDNS_Get_Response
   (
   uint_32           sock,
   char_ptr          name_to_resolve,
   char_ptr          rx_buffer,
   uint_32           req_id,
   _ip_address _PTR_ ipaddr_ptr,
   char_ptr          ipname,
   uint_32           ipnamesize
   )
{
   DNS_MESSAGE_HEADER_STRUCT_PTR       message_head_ptr;
   DNS_RESPONSE_RR_MIDDLE_STRUCT_PTR   answer_middle_ptr;
   uchar_ptr                           answer_ptr;
   uint_16                             answer_count,query_count;
   uint_16                             control, rdlength;
   uint_16                             answer_type;
   _ip_address                         ip_addr = INADDR_ANY;
   sockaddr_in                         addr;
   uint_16                             rlen,id;
   int_32                              response_size;
   char_ptr                           temp_ptr;
   _ip_address *                       ip_answer_ptr;
   uint_32                             i,offset;



   rlen = sizeof(addr);
   response_size = recv(sock,rx_buffer, DNS_MAX_UDP_MESSAGE_SIZE, 0);
   if ((response_size != RTCS_ERROR)   && (response_size >= sizeof(DNS_MESSAGE_HEADER_STRUCT))) {
      message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT_PTR) rx_buffer;
      id           = ntohs( message_head_ptr->ID );
      query_count  = ntohs( message_head_ptr->QDCOUNT );
      answer_count = ntohs( message_head_ptr->ANCOUNT );
      control      = ntohs( message_head_ptr->CONTROL );

      if ( (id == req_id ) && (query_count==1) && answer_count) {

         temp_ptr = &rx_buffer[sizeof(DNS_MESSAGE_HEADER_STRUCT)];


         if (domains_equal(name_to_resolve, temp_ptr)) {
            temp_ptr +=strlen(temp_ptr) + 1 + sizeof(DNS_MESSAGE_TAIL_STRUCT);

            for (i=0;i<answer_count;i++) {
               answer_ptr =  (uchar_ptr)temp_ptr;

               offset = domain_name_fragment_length(answer_ptr);

               answer_middle_ptr = (DNS_RESPONSE_RR_MIDDLE_STRUCT_PTR) &answer_ptr[offset];
               answer_type = ntohs( answer_middle_ptr->TYPE );
               rdlength = ntohs( answer_middle_ptr->RDLENGTH );
               if ( (answer_type == DNS_A ) && (rdlength == 4)) {
                  if (ipname != NULL) {
                     domain_name_extract(temp_ptr-rx_buffer,rx_buffer,ipname,ipnamesize);
                  }
                  ip_answer_ptr = (_ip_address *)  &answer_ptr[offset  + sizeof(DNS_RESPONSE_RR_MIDDLE_STRUCT)];
                  if (ipaddr_ptr != NULL) {
                     *ipaddr_ptr = ntohl ((uchar_ptr)ip_answer_ptr);
                  }
                  return TRUE;
               }


               temp_ptr += offset + sizeof(DNS_RESPONSE_RR_MIDDLE_STRUCT) + rdlength;
            }
         }
      }
   }

   return FALSE;
}



boolean LWDNS_resolve(
   char_ptr          name_to_resolve,
   _ip_address _PTR_ ipaddr_ptr,
   char_ptr          ipname,
   uint_32           ipnamesize
   )
{
   boolean           success=FALSE;
   sockaddr_in       laddr,raddr;
   uint_32           sock=0;
   char_ptr          buf=NULL;
   uint_32           result,id;
   int_32            error;

   *ipaddr_ptr = 0;
   if (LWDNS_server_ipaddr) {
      buf= RTCS_mem_alloc(DNS_MAX_UDP_MESSAGE_SIZE);
      if (buf) {
         _mem_set_type(buf,MEM_TYPE_DNS_UDP_MESSAGE);
         _mem_zero((uchar _PTR_) &laddr, sizeof(laddr));
         laddr.sin_family      = AF_INET;
         laddr.sin_port        = 0; // DNS_RESOLVER_PORT;
         laddr.sin_addr.s_addr = INADDR_ANY;

         _mem_zero((uchar _PTR_) &raddr, sizeof(raddr));
         /* Remote address, Name Servers use port 53 */
         raddr.sin_family      = AF_INET;
         raddr.sin_port        = DNS_NAMESERVER_PORT;
         raddr.sin_addr.s_addr = LWDNS_server_ipaddr;

#if RTCSCFG_ENABLE_UDP
         /* Bind to UDP port */
         sock = socket(PF_INET, SOCK_DGRAM, 0);
#else
         sock = socket(PF_INET, SOCK_STREAM, 0);
#endif
         if (sock) {
            error = bind(sock, (const sockaddr *)&laddr, sizeof(laddr));
            if ( error == RTCS_OK ) {
               error = connect(sock, (const sockaddr *)(&raddr), sizeof(raddr));
               if (error == RTCS_OK ) {
                  error = LWDNS_Send_Query(sock,  name_to_resolve, buf, &id);
                  if (error == RTCS_OK ) {
                     result = (uint_32)RTCS_selectset( &sock, 1, 3000 );

                     if (result==sock) {
                        success = LWDNS_Get_Response(sock, name_to_resolve, buf, id, ipaddr_ptr, ipname, ipnamesize);
                     }
                  }
               }
            }
            shutdown(sock,0);
         }
         _mem_free(buf);
      }
   }

   return success;
}

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_mat3.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_mat3.c$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*   This file contains the math functions.
*
*END************************************************************************/

#include "mqx_inc.h"


/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_add_element_to_array
* Returned Value   : uint_32 - 1 if overflow, 0 otherwise
* Comments         :
*    This function adds a single element to an array. r = a[] + val
*
*END*----------------------------------------------------------------------*/

uint_32 _psp_add_element_to_array
   (
      /* [IN] Pointer to the array to be added to */
      uint_32_ptr s1_ptr,

      /* [IN] The value to add the array */
      uint_32     val,

      /* [IN] The size of the array to add in long words */
      uint_32     size,

      /* [OUT] Pointer to where the result is to be stored */
      uint_32_ptr res_ptr

   )
{ /* Body */
   register uint_32 x, y, z, cy;
   register int_32  j;

#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
   x  = s1_ptr[0];
   y  = x + val;
   cy = (y < val);
   res_ptr[0] = y;
   for ( j = 1; j < size; j++) {
      z = s1_ptr[j];
      x = z + cy;
      res_ptr[j] = x;
      cy = (x < z);
   } /* Endfor */
#else
   x  = s1_ptr[size-1];
   y  = x + val;
   cy = (y < val);
   res_ptr[size-1] = y;
   for ( j = (size-2); j >= 0; j--) {
      z = s1_ptr[j];
      x = z + cy;
      res_ptr[j] = x;
      cy = (x < z);
   } /* Endfor */
#endif
   return cy;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/inet.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: inet.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains some Internet address manipulation
*   functions.
*
*END************************************************************************/

#include <ctype.h>
#include <rtcs.h>


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : inet_aton
* Returned Value  : -1 on success, 0 on error
* Comments  :  Converts a dotted-decimal into a binary in_addr
*
*END*-----------------------------------------------------------------*/

int_32 inet_aton
   (
      const char _PTR_  name,
         /* [IN] dotted decimal IP address */
      in_addr _PTR_     ipaddr_ptr
         /* [OUT] binary IP address */
   )
{ /* Body */
   boolean     ipok = FALSE;
   uint_32     dots;
   uint_32     byte;
   _ip_address addr;

   addr = 0;
   dots = 0;
   for (;;) {

      if (!isdigit(*name)) break;

      byte = 0;
      while (isdigit(*name)) {
         byte *= 10;
         byte += *name - '0';
         if (byte > 255) break;
         name++;
      } /* Endwhile */
      if (byte > 255) break;
      addr <<= 8;
      addr += byte;

      if (*name == '.') {
         dots++;
         if (dots > 3) break;
         name++;
         continue;
      } /* Endif */

      if ((*name == '\0') && (dots == 3)) {
         ipok = TRUE;
      } /* Endif */

      break;

   } /* Endfor */

   if (!ipok) {
      return 0;
   } /* Endif */

   if (ipaddr_ptr) {
      ipaddr_ptr->s_addr = addr;
   } /* Endif */

   return -1;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : inet_addr
* Returned Value  : a binary IP address, or -1 on error
* Comments  :  Converts a dotted-decimal into a binary in_addr
*
*END*-----------------------------------------------------------------*/

_ip_address inet_addr
   (
      const char _PTR_  name
         /* [IN] dotted decimal IP address */
   )
{ /* Body */
   in_addr  ipaddr;
   int_32   ipok;

   ipok = inet_aton(name, &ipaddr);
   if (!ipok) {
      return INADDR_BROADCAST;
   } /* Endif */
   return ipaddr.s_addr;

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/shell/sh_util.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_util.c$
* $Version : 3.8.17.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <shell.h>
#include <sh_prv.h>

#if SHELLCFG_USES_MFS
MQX_FILE_PTR Shell_default_fs = NULL;
char_ptr Shell_default_fs_name = NULL;

static void Shell_init_current_filesystem(pointer argv);
#endif //SHELLCFG_USES_MFS


int_32 Shell_parse_command_line( char_ptr command_line_ptr, char_ptr argv[] )
{
   char_ptr             sptr;
   uint_32              i;
   int_32               argc;

   sptr = command_line_ptr;
   argc = 0;
   for (i=0;i<SHELL_MAX_ARGS;i++)  {
      while (*sptr && !isgraph((uchar)*sptr)) sptr++;
      if (!*sptr) {
         argv[i] = NULL;
      } else {
         argc++;
         argv[i] = sptr;
         while (*sptr && isgraph(*sptr)) sptr++;
         if (*sptr) *sptr++ = '\0';
      }
   }
   return argc;
}



boolean Shell_parse_number( char_ptr arg, uint_32_ptr num_ptr)
{
   uint_32 i=0,j=0;

   if (num_ptr == NULL) return FALSE;
   while (isdigit(arg[i]))  {
      j = j*10 + (arg[i++]-'0');
   }
   if (arg[i]=='\0')
   {
      *num_ptr=j;
      return TRUE;
   }
   return FALSE;
}

boolean Shell_parse_uint_32( char_ptr arg, uint_32_ptr num_ptr)
{
   uint_32 i=0,j=0;

   if (num_ptr == NULL) return FALSE;
   while (isdigit(arg[i]))  {
      j = j*10 + (arg[i++]-'0');
   }
   if (arg[i]=='\0')
   {
      *num_ptr=j;
      return TRUE;
   }
   return FALSE;
}

boolean Shell_parse_uint_16( char_ptr arg, uint_16_ptr num_ptr)
{
   uint_32 i=0;
   uint_16 j=0;

   if (num_ptr == NULL) return FALSE;
   while (isdigit(arg[i]))  {
      j = j*10 + (arg[i++]-'0');
   }
   if (arg[i]=='\0')
   {
      *num_ptr=j;
      return TRUE;
   }
   return FALSE;
}

boolean Shell_parse_int_32( char_ptr arg, int_32_ptr num_ptr)
{
   uint_32 i=0;
   int_32 sign=1,j=0;

   if (num_ptr == NULL) return FALSE;
   if (arg[i]=='-')  {
      sign = -1;
      i++;
   }
   while (isdigit(arg[i]))  {
      j = j*10 + (arg[i++]-'0');
   }
   if (arg[i]=='\0')
   {
      *num_ptr=j * sign;
      return TRUE;
   }
   return FALSE;
}

boolean Shell_parse_hexnum( char_ptr arg, uint_32_ptr num_ptr)
{
   uint_32 i=2,j=0;

   if (num_ptr == NULL) return FALSE;

   for (i=0;i<=8;i++) {
      if (isdigit(arg[i])) {
         j = j*16 + (arg[i]-'0');
      } else if ((arg[i] >='a') && (arg[i] <='f') ) {
         j = j*16 + (arg[i]-'a'+10);
      } else if ((arg[i] >='A') && (arg[i] <='F') ) {
         j = j*16 + (arg[i]-'A'+10);
      } else if (arg[i]==0) {
         *num_ptr=j;
         return TRUE;
      } else {
         return FALSE;
      }
   }
   return FALSE;
}


boolean Shell_check_help_request(int_32 argc, char_ptr argv[], boolean _PTR_ short_ptr )
{
   if ((argc == 3) && (strcmp(argv[1], "help") == 0))  {
      *short_ptr = (strcmp(argv[2], "short")==0)?TRUE:FALSE;
      return TRUE;
   }
   return FALSE;
}


#if SHELLCFG_USES_MFS
void Shell_create_prefixed_filename( char_ptr new_ptr, char_ptr in_ptr,  pointer argv)
{
   _io_create_prefixed_filename(new_ptr,in_ptr,Shell_get_current_filesystem_name(argv));
}


MQX_FILE_PTR Shell_get_current_filesystem(pointer argv)
{
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );

   if(shell_ptr->CURRENT_DEVICE_FP == NULL)
   {
      // shell current filesystem is not initialized
      Shell_init_current_filesystem(argv);
      return shell_ptr->CURRENT_DEVICE_FP;
   }
   else if(!_io_is_fs_valid(shell_ptr->CURRENT_DEVICE_FP))
   {
      // current filesystem was closed
      Shell_init_current_filesystem(argv);
      return shell_ptr->CURRENT_DEVICE_FP;
   }
   else
   {
      // everything is ok, return stored filesystem ptr
      return shell_ptr->CURRENT_DEVICE_FP;
   }
}

char_ptr Shell_get_current_filesystem_name(pointer argv)
{
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );

   if(shell_ptr->CURRENT_DEVICE_FP == NULL)
   {
      // shell current filesystem is not initialized
      Shell_init_current_filesystem(argv);
      return shell_ptr->CURRENT_DEVICE_NAME;
   }
   else if(!_io_is_fs_valid(shell_ptr->CURRENT_DEVICE_FP))
   {
      // current filesystem was closed
      Shell_init_current_filesystem(argv);
      return shell_ptr->CURRENT_DEVICE_NAME;
   }
   else
   {
      // everything is ok, return stored device name
      return shell_ptr->CURRENT_DEVICE_NAME;
   }
}

int_32 Shell_set_current_filesystem(pointer argv, MQX_FILE_PTR fp)
{
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );

   if(fp == NULL)
   {
      shell_ptr->CURRENT_DEVICE_FP       = NULL;
      shell_ptr->CURRENT_DEVICE_NAME[0]  = '\0';
      strcpy(shell_ptr->CURRENT_DIR,"\\");
   }
   else if(_io_is_fs_valid(fp))
   {
      _io_get_fs_name(fp,shell_ptr->CURRENT_DEVICE_NAME,sizeof(shell_ptr->CURRENT_DEVICE_NAME));
      shell_ptr->CURRENT_DEVICE_FP = fp;
      strcpy(shell_ptr->CURRENT_DIR,"\\");
   }
   else
   {
      return MQX_INVALID_POINTER;
   }
   return MQX_OK;
}

int_32 Shell_set_current_filesystem_by_name(pointer argv, char_ptr dev_name)
{
   MQX_FILE_PTR         temp_fs;

   temp_fs = _io_get_fs_by_name(dev_name);
   // if valid filesystem entry is returned, fill in internal variables
   if(temp_fs != NULL)
   {
      Shell_set_current_filesystem(argv,temp_fs);
   }
   else
   {
      return MQX_INVALID_POINTER;
   }
   return MQX_OK;
}


static void Shell_init_current_filesystem(pointer argv)
{
   MQX_FILE_PTR         temp_fs;

   temp_fs   = _io_get_first_valid_fs();
   // if valid filesystem entry is returned, fill in internal variables
   // otherwise set default values
   Shell_set_current_filesystem(argv,temp_fs);
}
#endif //SHELLCFG_USES_MFS
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/soudp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: soudp.c$
* $Version : 3.0.4.0$
* $Date    : Mar-5-2009$
*
* Comments:
*
*   This file contains the implementation of getsockopt()
*   and setsockopt() at the SOL_UDP level.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "udp.h"

#if RTCSCFG_ENABLE_UDP

#define RTCS_ENTER(f,a) RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_UDP_ ## f, a)

#define RTCS_EXIT(f,a)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_UDP_ ## f, a); \
                        return a


uint_32 SOL_UDP_getsockopt  (uint_32, uint_32, uint_32, pointer, uint_32 _PTR_);
uint_32 SOL_UDP_setsockopt  (uint_32, uint_32, uint_32, pointer, uint_32);

const RTCS_SOCKOPT_CALL_STRUCT SOL_UDP_CALL = {
   SOL_UDP_getsockopt,
   SOL_UDP_setsockopt
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_UDP_getsockopt
* Returned Value  : error code
* Comments  :  Obtain the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_UDP_getsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] buffer for the current value of the option */
      uint_32  _PTR_ optlen
         /* [IN/OUT] length of the option value, in bytes */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;

   RTCS_ENTER(GETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   parms.ucb      = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
   parms.udpflags = optname;
   error = RTCSCMD_issue(parms, UDP_getopt);
   if (error) {
      RTCS_EXIT(GETSOCKOPT, error);
   } /* Endif */

   *(uint_32_ptr)optval = parms.udpword;
   RTCS_EXIT(GETSOCKOPT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_UDP_setsockopt
* Returned Value  : error code
* Comments  :  Modify the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_UDP_setsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] new value for the option */
      uint_32        optlen
         /* [IN] length of the option value, in bytes */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;

   RTCS_ENTER(SETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   parms.ucb      = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
   parms.udpflags = optname;
   parms.udpword  = *(uint_32_ptr)optval;
   error = RTCSCMD_issue(parms, UDP_setopt);
   if (error) {
      RTCS_EXIT(SETSOCKOPT, error);
   } /* Endif */

   RTCS_EXIT(SETSOCKOPT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_getopt
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] UCB
*     _ip_address       ipaddress   not used
*     uint_16           udpport     not used
*     uint_16           udpflags    [IN] option
*     uint_32           udpptr      not used
*     uint_32           udpword     [OUT] option value
*
* Comments        :
*     Retrieves the value of a UDP option.
*
*END*-----------------------------------------------------------------*/

void UDP_getopt
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   uint_32     error = RTCS_OK;

   switch (parms->udpflags) {

   /* Start CR 1145 */
   case RTCS_SO_UDP_NONBLOCK_TX:
      parms->udpword = parms->ucb->NONBLOCK_TX;
      break;

   case RTCS_SO_UDP_NONBLOCK_RX:
      parms->udpword = parms->ucb->NONBLOCK_RX;
      break;
   /* End CR 1145 */

   case RTCS_SO_UDP_NOCHKSUM:
      parms->udpword = parms->ucb->BYPASS_TX;
      break;

   default:
      error = RTCSERR_SOCK_INVALID_OPTION;
   } /* Endswitch */

   RTCSCMD_complete(parms, error);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_setopt
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] UCB
*     _ip_address       ipaddress   not used
*     uint_16           udpport     not used
*     uint_16           udpflags    [IN] option
*     uint_32           udpptr      not used
*     uint_32           udpword     [IN] option value
*
* Comments        :
*     Sets the value of a UDP option.
*
*END*-----------------------------------------------------------------*/

void UDP_setopt
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   uint_32     error = RTCS_OK;

   switch (parms->udpflags) {

   /* Start CR 1145 */
   case RTCS_SO_UDP_NONBLOCK_TX:
      parms->ucb->NONBLOCK_TX = parms->udpword ? TRUE : FALSE;
      break;

   case RTCS_SO_UDP_NONBLOCK_RX:
      parms->ucb->NONBLOCK_RX = parms->udpword ? TRUE : FALSE;
      break;
   /* End CR 1145 */

   case RTCS_SO_UDP_NOCHKSUM:
      parms->ucb->BYPASS_TX = parms->udpword ? TRUE : FALSE;
      break;

   default:
      error = RTCSERR_SOCK_INVALID_OPTION;
   } /* Endswitch */

   RTCSCMD_complete(parms, error);

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/partition_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: partition_prv.h$
* $Version : 3.8.4.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This file contains private definitions for the partition management
*   component
*
*END************************************************************************/
#ifndef __partition_prv_h__
#define __partition_prv_h__

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* The validation check for the partitions */
#define PARTITION_VALID      ((_mqx_uint)(0x70617274))  /* "part" */

/* Checksum macros */
#if MQX_CHECK_VALIDITY
#define CALC_PARTITION_CHECKSUM(block) \
   (block)->CHECKSUM = (_mqx_uint)((block)->LINK.PARTITION_PTR) + \
      (_mqx_uint)((block)->TASK_ID);
#else
#define CALC_PARTITION_CHECKSUM(block)
#endif

#if MQX_CHECK_VALIDITY
#define VALID_PARTITION_CHECKSUM(block) \
   ( (block)->CHECKSUM == ((_mqx_uint)((block)->LINK.PARTITION_PTR) + \
          (_mqx_uint)((block)->TASK_ID)) )
#else
#define VALID_PARTITION_CHECKSUM(block) TRUE
#endif

/* Parition created from MQX memory pool by _partition_create and can grow */
#define PARTITION_DYNAMIC         (0x2)

/* Parition created at a fixed location by _partition_create_at */
#define PARTITION_STATIC          (0x4)

/*----------------------------------------------------------------------------*/
/*                        DATA TYPE DEFINTIONS
 */

struct internal_partition_block_struct;

/* PARTPOOL BLOCK STRUCT */
/*! 
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure is used at the beginning of each memory area where 
 * blocks have been created for a partition.
 */
typedef struct partpool_block_struct
{                  
   /*! \brief The next memory area where blocks are for this partition. */
   struct partpool_block_struct _PTR_             NEXT_POOL_PTR;

   /*! \brief Validation stamp for pool. */
   _mqx_uint                                      VALID;

   /*! \brief Number of blocks in this memory area. */
   _mqx_uint                                      NUMBER_OF_BLOCKS;
   
   /*! \brief The address of the first internal block of the pool. */
   struct internal_partition_block_struct _PTR_   FIRST_IBLOCK_PTR;
   
} PARTPOOL_BLOCK_STRUCT, _PTR_ PARTPOOL_BLOCK_STRUCT_PTR;
/*! \endcond */

/* PARTPOOL_STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *   
 * \brief This structure defines what a partition pool looks like.
 *  
 * It overlays the beginning of the memory area used for a partition, when
 * the partition is created.
 * \n All of the partition pools in the kernel are linked together via the 
 * NEXT_PARITION_PTR field.
 * \n When a new memory area is added (to extend the partition), the new memory 
 * area begins with a PARTPOOL_BLOCK structure. All of these are linked together 
 * via the NEXT_POOL_PTR field of the partpool block struct.
 * \n All of the Partition Blocks are individually linked together onto a free list.      
 */
typedef struct partpool_struct
{
   /*! 
    * \brief Pointer to the next partition to maintain a list of partitions in
    * the kernel. 
    */   
   pointer                                       NEXT;
   /*! 
    * \brief Pointer to the previous partition to maintain a list of partitions 
    * in the kernel. 
    */
   pointer                                       PREV;

   /*! \brief The actual size each block in the partition. */
   _mem_size                                     BLOCK_SIZE;

   /*! \brief Number of blocks available in the partition. */
   _mem_size                                     AVAILABLE;

   /*! \brief The free list of available blocks. */
   struct internal_partition_block_struct _PTR_  FREE_LIST_PTR;

   /*! \brief The total number of blocks in the partition. */
   _mem_size                                     TOTAL_BLOCKS;
 
   /*! \brief The maximum number of blocks that have been in use at one time. */
   _mem_size                                     MAX_BLOCKS_USED;

   /*! \brief The number of blocks to grow the partition by if necessary. */
   _mem_size                                     GROW_BLOCKS;

   /*! \brief The maximum number of blocks to allow in the partition. */
   _mem_size                                     MAXIMUM_BLOCKS;

   /*! \brief The partition type, either DYNAMIC or STATIC. */
   _mqx_uint                                     PARTITION_TYPE;

   /*! \brief A context pointer used by the partition test function. */
   struct internal_partition_block_struct volatile _PTR_  TEST_FREE_PTR;
   
   /*! \brief The first set of blocks in the partition. */
   PARTPOOL_BLOCK_STRUCT                         POOL;
   
} PARTPOOL_STRUCT, _PTR_ PARTPOOL_STRUCT_PTR;
/*! \endcond */

/* INTERNAL PARTITION BLOCK STRUCT */
/*! 
 * \cond DOXYGEN_PRIVATE
 *   
 * \brief Each block in the partition has this structure overlaid onto the 
 * beginning of the block. 
 * 
 * The address provided to the application for the block is the memory address 
 * following this header.
 */
typedef struct internal_partition_block_struct
{
   /*! 
    * \brief When on the free list, this pointer links blocks together. When 
    * allocated, this field points back to the original partition.
    */
   union  {
      struct internal_partition_block_struct _PTR_ NEXT_BLOCK_PTR;
      PARTPOOL_STRUCT_PTR                          PARTITION_PTR;      
   } LINK;

   /*! \brief The block checksum. */
   _mqx_uint            CHECKSUM;

   /*! \brief The owner task ID. */
   _task_id             TASK_ID;

} INTERNAL_PARTITION_BLOCK_STRUCT, _PTR_ INTERNAL_PARTITION_BLOCK_STRUCT_PTR;
/*! \endcond */

/* PARTITION COMPONENT STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure is used to store information required for partition 
 * component.
 */
typedef struct partition_component_struct
{
   /*! \brief A queue of all created partitions. */
   QUEUE_STRUCT PARTITIONS;

   /*! \brief A validation field for partitions. */
   _mqx_uint    VALID;

} PARTITION_COMPONENT_STRUCT, _PTR_ PARTITION_COMPONENT_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/*                        Prototypes                                        */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _partition_create_internal(PARTPOOL_STRUCT_PTR, _mem_size, 
   _mqx_uint);
extern void      _partition_extend_internal(PARTPOOL_STRUCT_PTR, 
   PARTPOOL_BLOCK_STRUCT_PTR, _mqx_uint); 
extern pointer   _partition_alloc_internal(PARTPOOL_STRUCT_PTR, TD_STRUCT_PTR);
extern void      _partition_cleanup(TD_STRUCT_PTR);
#endif

#ifdef __cplusplus
}
#endif

#endif /* __partition_prv_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/kinetis_mpu.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: kinetis_mpu.c$
* $Version : 3.8.6.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains source for basic mpu settings.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "kinetis_mpu.h"

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _kinetis_mpu_disable
* Returned Value  : uint_32
*       Always return MQX_OK.
* Comments        :
* 	Disable MPU on cortex
*
*END*---------------------------------------------------------------------*/

_mqx_uint _kinetis_mpu_disable(void) {
    MPU_CESR &= ~MPU_CESR_VLD_MASK;

    return MQX_OK;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _kinetis_mpu_enable
* Returned Value  : uint_32
*       Always return MQX_OK.
* Comments        :
* 	Enable MPU on cortex
*
*END*---------------------------------------------------------------------*/

_mqx_uint _kinetis_mpu_enable(void) {
    MPU_CESR |= MPU_CESR_VLD_MASK;

    return MQX_OK;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _kinetis_mpu_init
* Returned Value  : uint_32
*       Always return MQX_OK.
* Comments        :
* 	Initialize MPU and clear all active records in MPU
*
*END*---------------------------------------------------------------------*/

_mqx_uint _kinetis_mpu_init(void) {
    _mqx_uint i;

    MPU_CESR &= ~MPU_CESR_VLD_MASK;

    for (i = 0; i < CORTEX_MPU_REC; i++) {
        MPU_WORD(i, 2) = 0;
    }

    return MQX_OK;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name     : _kinetis_mpu_add_region
* Returned Value    : uint_32
*       Always return MQX_OK.
* Comments          :
* 	Add new region to MPU
*
*END*---------------------------------------------------------------------*/

_mqx_uint _kinetis_mpu_add_region
    (
        // [IN] mpu region start address
        uchar_ptr start,
        // [IN] mpu region end address
        uchar_ptr end,
        // [IN] access rights, direct value - cortex mpu specific
        _mqx_uint flags
    )
{
    _mqx_uint i;
    _mqx_uint res = MQX_OK;

    for (i = 1; (i < CORTEX_MPU_REC) && (MPU_WORD(i, 3) & MPU_WORD_VLD_MASK); i++) {}

    if (i < CORTEX_MPU_REC) {
        MPU_WORD(i, 0) = (_mem_size)start & MPU_WORD_SRTADDR_MASK;
        MPU_WORD(i, 1) = (_mem_size)end & MPU_WORD_ENDADDR_MASK | 0x01f;
        MPU_WORD(i, 2) = flags;
        MPU_WORD(i, 3) = MPU_WORD_VLD_MASK;
    }
    else
        res = MQX_ERROR;

    return res;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name     : _kinetis_mpu_sw_check
* Returned Value    : uint_32
*       return non zero if any region in mpu contain required range with selected access rights
*       return 0 when mpu don't contain any ragion with requested range with selected access rights
* Comments          :
* 	Software check for memory access (check mpu regions) - this is crutch for ...
*
*END*---------------------------------------------------------------------*/

_mqx_uint _kinetis_mpu_sw_check
    (
        // [IN] cheked block start address
        uint_32 addr,
        // [IN] checked block size
        _mem_size size,
        // [IN] required access flags, direct value - cortex mpu specific
        uint_32 flags
    )
{
    _mqx_uint i, res = 0;

    for (i = 0; i < CORTEX_MPU_REC; i++) {
        if ((MPU_WORD(i, 3) & MPU_WORD_VLD_MASK) && ((addr >= MPU_WORD(i, 0) && addr <= MPU_WORD(i, 1)) || ((addr + size - 1) >= MPU_WORD(i, 0) && (addr + size - 1) <= MPU_WORD(i, 1)))) {
            // founded record, check flags

            // only for core access
            if ((MPU_WORD_M0UM(MPU_WORD(i, 2)) & flags) == flags) {
                res = 1;
                break;
            }
        }
    }

    return res;
}

_mqx_uint _kinetis_mpu_sw_check_mask
    (
        // [IN] cheked block start address
        uint_32 addr,
        // [IN] checked block size
        _mem_size size,
        // [IN] required access flags, direct value - cortex mpu specific
        uint_32 flags,
        uint_32 mask
    )
{
    _mqx_uint i, res = 0, state = 0;

    for (i = 0; i < CORTEX_MPU_REC; i++) {
        if ((MPU_WORD(i, 3) & MPU_WORD_VLD_MASK) && ((addr >= MPU_WORD(i, 0) && addr <= MPU_WORD(i, 1)) || ((addr + size - 1) >= MPU_WORD(i, 0) && (addr + size - 1) <= MPU_WORD(i, 1)))) {
            // founded record, check flags

            state |= MPU_WORD_M0UM(MPU_WORD(i, 2));
        }
    }

    // only for core access
    if ((state & mask) == flags) {
        res = 1;
    }

    return res;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_c90_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_c90_prv.h$
* $Version : 3.8.4.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*   The file contains function prototypes and defines for the internal 
*   flash driver.
*
*END************************************************************************/
#ifndef __flash_c90_prv_h__
#define __flash_c90_prv_h__


#include "flashx.h"
#include "flashxprv.h"


/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/* SPECIAL_TAG definitions */
#define C90_ASPACE_MASK     0x0000000f
#define C90_CONTROLLER_MASK 0x000000f0
#define C90_WIDTH_MASK      0x0000ff00
#define C90_ALIGN_MASK      0x000f0000

#define C90_ASPACE_SHIFT        (0)
#define C90_CONTROLLER_SHIFT    (4)
#define C90_WIDTH_SHIFT         (8)
#define C90_ALIGN_SHIFT         (16)

#define C90_CONTROLLER_0    0x00000010
#define C90_CONTROLLER_1    0x00000020
#define C90_INTERLEAVED     (C90_CONTROLLER_0|C90_CONTROLLER_1)

#define C90_WIDTH_32        (32<<C90_WIDTH_SHIFT)
#define C90_WIDTH_64        (64<<C90_WIDTH_SHIFT)
#define C90_WIDTH_128       (128<<C90_WIDTH_SHIFT)

#define C90_ALIGN_32        (4<<C90_ALIGN_SHIFT)
#define C90_ALIGN_64        (8<<C90_ALIGN_SHIFT)

#define C90_ASPACE(x)       ((x&C90_ASPACE_MASK)>>C90_ASPACE_SHIFT)
#define C90_WIDTH(x)        ((x&C90_WIDTH_MASK)>>C90_WIDTH_SHIFT)
#define C90_ALIGN(x)        ((x&C90_ALIGN_MASK)>>C90_ALIGN_SHIFT)


/* module control register */
#define C90_MCR_EHV  0x01
#define C90_MCR_ESUS 0x02
#define C90_MCR_ERS  0x04
#define C90_MCR_PSUS 0x08
#define C90_MCR_PGM  0x10
#define C90_MCR_PEG  0x0200
#define C90_MCR_DONE 0x0400
#define C90_MCR_PEAS 0x0800
#define C90_MCR_SBC  0x2000
#define C90_MCR_RWE  0x4000
#define C90_MCR_ERR  0x8000
#define C90_MCR_MAS  0x10000

#define C90_MCR_LAS_MASK   0x700000
#define C90_MCR_LAS_SHIFT  20
#define C90_MCR_LAS(x)     (((x) << C90_MCR_LAS_SHIFT) & C90_MCR_LAS_MASK)

#define C90_MCR_SIZE_MASK  0x07000000
#define C90_MCR_SIZE_SHIFT 24
#define C90_MCR_SIZE(x)    (((x) << C90_MCR_SIZE_SHIFT) & C90_MCR_SIZE_MASK)


/* LAS/MAS block locking register */
#define C90_LML_LME 0x80000000
#define C90_LML_SLOCK 0x100000

#define C90_LML_MLOCK_MASK  0x30000
#define C90_LML_MLOCK_SHIFT 16
#define C90_LML_MLOCK(x)    (((x) << C90_LML_MLOCK_SHIFT) & C90_LML_MLOCK_MASK)

#define C90_LML_LLOCK_MASK  0x3ff
#define C90_LML_LLOCK_SHIFT 0
#define C90_LML_LLOCK(x)    (((x) << C90_LML_LLOCK_SHIFT) & C90_LML_LLOCK_MASK)

#define C90_LML_PASSWORD    <PASSWORD>


/* HAS block locking register */
#define C90_HBL_HBE 0x80000000

#define C90_HBL_HLOCK_MASK  0x3f
#define C90_HBL_HLOCK_SHIFT 0
#define C90_HBL_HLOCK(x)    (((x) << C90_HBL_HLOCK_SHIFT) & C90_HBL_HLOCK_MASK)

#define C90_HBL_PASSWORD    <PASSWORD>


/* secondary LAS/MAS block locking register */
#define C90_SLL_SLE 0x80000000
#define C90_SLL_SSLOC 0x100000

#define C90_SLL_SMLOCK_MASK  0x30000
#define C90_SLL_SMLOCK_SHIFT 16
#define C90_SLL_SMLOCK(x)    (((x) << C90_SLL_SMLOCK_SHIFT) & C90_SLL_SMLOCK_MASK)

#define C90_SLL_SLLOCK_MASK  0x3ff
#define C90_SLL_SLLOCK_SHIFT 0
#define C90_SLL_SLLOCK(x)    (((x) << C90_SLL_SLLOCK_SHIFT) & C90_SLL_SLLOCK_MASK)

#define C90_SLL_PASSWORD    <PASSWORD>


/* LAS/MAS block select register */
#define C90_LMS_MSEL_MASK  0x30000
#define C90_LMS_MSEL_SHIFT 16
#define C90_LMS_MSEL(x)    (((x) << C90_LMS_MSEL_SHIFT) & C90_LMS_MSEL_MASK)

#define C90_LMS_LSEL_MASK  0x3ff
#define C90_LMS_LSEL_SHIFT 0
#define C90_LMS_LSEL(x)    (((x) << C90_LMS_LSEL_SHIFT) & C90_LMS_LSEL_MASK)


/* HAS block select register */
#define C90_HBS_HSEL_MASK  0x3f
#define C90_HBS_HSEL_SHIFT 0
#define C90_HBS_HSEL(x)    (((x) << C90_HBS_HSEL_SHIFT) & C90_HBS_HSEL_MASK)


#define C90_ASPACE_LAS 0
#define C90_ASPACE_MAS 1
#define C90_ASPACE_HAS 2
#define C90_ASPACE_SHADOW 3
#define C90_ASPACE_COUNT 4

/*----------------------------------------------------------------------*/
/*
**                    Structure Definitions
*/

/* Peripheral register access */
typedef struct c90_reg_struct {
    uint_32 MCR;
    uint_32 LML;
    uint_32 HBL;
    uint_32 SLL;
    uint_32 LMS;
    uint_32 HBS;
    uint_32 ADR;
    uint_32 PFCR0;
    uint_32 padding_20;
    uint_32 PFAPR;
    uint_32 padding_28;    
    uint_32 BIU4;
    uint_32 padding_30[3];    
    uint_32 UT0;
    uint_32 UT1;
    uint_32 UT2;
    uint_32 UM0;
    uint_32 UM1;
    uint_32 UM2;
    uint_32 UM3;
    uint_32 UM4;
} C90_REG_STRUCT, _PTR_ C90_REG_STRUCT_PTR;

typedef volatile struct c90_reg_struct * VC90_REG_STRUCT_PTR;


typedef struct c90_flash_internal_struct 
{
   VC90_REG_STRUCT_PTR reg_ptr;
   void (_CODE_PTR_ flash_exec)(VC90_REG_STRUCT_PTR);
   uint_32 aspace_sectors[C90_ASPACE_COUNT];
} C90_FLASH_INTERNAL_STRUCT, _PTR_ C90_FLASH_INTERNAL_STRUCT_PTR;


/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

boolean c90_flash_init (IO_FLASHX_STRUCT_PTR);
void    c90_flash_deinit (IO_FLASHX_STRUCT_PTR);
boolean c90_flash_sector_erase (IO_FLASHX_STRUCT_PTR, char_ptr, _mem_size);
boolean c90_flash_sector_program (IO_FLASHX_STRUCT_PTR, char_ptr, char_ptr, _mem_size);
boolean c90_flash_chip_erase (IO_FLASHX_STRUCT_PTR);
boolean c90_flash_write_protect(IO_FLASHX_STRUCT_PTR, _mqx_uint);

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/rtcsglob.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcsglob.c$
* $Version : 3.4.8.0$
* $Date    : Nov-19-2009$
*
* Comments:
*
*   Definitions of global variables required for RTCS.
*
*END************************************************************************/

#include <rtcs.h>


uint_32  _RTCSQUEUE_base = RTCSCFG_QUEUE_BASE;

/*
** Number of RTCSPCBs to allocate
*/
uint_32  _RTCSPCB_init = RTCSCFG_PCBS_INIT;
uint_32  _RTCSPCB_grow = RTCSCFG_PCBS_GROW;
uint_32  _RTCSPCB_max  = RTCSCFG_PCBS_MAX;

/*
** TCP/IP task priority and extra stack size
*/
uint_32  _RTCSTASK_priority   = 6;
uint_32  _RTCSTASK_stacksize  = RTCSCFG_STACK_SIZE;
boolean  _RTCS_initialized    = FALSE;

/*
** TCP-based RPC task priority and extra stack size
*/
uint_32  _SVCTCPTASK_priority    = 9;
uint_32  _SVCTCPTASK_stacksize   = 0;

/*
** Indicates whether or not IP should forward packets between interfaces
*/
boolean  _IP_forward = FALSE;

/*
** Indicates whether or not to bypass checksum checking
*/
boolean  _TCP_bypass_rx = FALSE;
boolean  _TCP_bypass_tx = FALSE;

/*
** The TCP retransmission timeout minimum
*/
uint_32  _TCP_rto_min;     /* initialized by TCP_Init() */

/*
** Maximum number of packets that will be enqueued
*/
uint_32  _UDP_max_queue_size  = RTCSCFG_UDP_MAX_QUEUE_SIZE;

/* 
** Use the dhcp broadcast flag, or dhcp unicast offers. 
*/
boolean _DHCP_broadcast = FALSE;

/*
** Pool that RTCS should allocate memory from. If 0, susyem pool will be used
*/
_mem_pool_id _RTCS_mem_pool = 0;


uint_32 _RTCS_msgpool_init  = RTCSCFG_MSGPOOL_INIT;
uint_32 _RTCS_msgpool_grow  = RTCSCFG_MSGPOOL_GROW;
uint_32 _RTCS_msgpool_max   = RTCSCFG_MSGPOOL_MAX;


uint_32 _RTCS_socket_part_init  = RTCSCFG_SOCKET_PART_INIT;
uint_32 _RTCS_socket_part_grow  = RTCSCFG_SOCKET_PART_GROW;
uint_32 _RTCS_socket_part_max   = RTCSCFG_SOCKET_PART_MAX;

/* 
** Use following dhcp termination timeout. 
*/
uint_32 _RTCS_dhcp_term_timeout = 60;

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/include/host_common.h<|end_filename|>
#ifndef __host_common_h__
#define __host_common_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_common.h$
* $Version : 3.8.24.0$
* $Date    : Sep-13-2012$
*
* Comments:
*
*   This file contains definitions for USB common utilities.
*
*END************************************************************************/
#include "usb_types.h"

/*------------------------------**
** Class / SubClass / Protocol  **
**------------------------------*/

#define  USB_CLASS_AUDIO            1
#define  USB_SUBCLASS_UNDEFINED     0
#define  USB_SUBCLASS_AUD_CONTROL   1
#define  USB_SUBCLASS_AUD_STREAMING 2
#define  USB_SUBCLASS_AUD_MIDI_STRM 3
#define  USB_PROTOCOL_UNDEFINED     0

#define  USB_CLASS_COMMUNICATION    2
#define  USB_SUBCLASS_COM_DIRECT    1
#define  USB_SUBCLASS_COM_ABSTRACT  2
#define  USB_SUBCLASS_COM_TELEPHONE 3
#define  USB_SUBCLASS_COM_MULTICHAN 4
#define  USB_SUBCLASS_COM_CAPI      5
#define  USB_SUBCLASS_COM_ETHERNET  6
#define  USB_SUBCLASS_COM_ATM_NET   7
#define  USB_PROTOCOL_COM_NOSPEC    0
#define  USB_PROTOCOL_COM_V25       1
#define  USB_PROTOCOL_COM_HAYES     1
#define  USB_PROTOCOL_COM_AT        1
#define  USB_PROTOCOL_COM_VENDOR    0xFF

#define  USB_CLASS_PRINTER          7
#define  USB_SUBCLASS_PRINTER       1
#define  USB_PROTOCOL_PRT_UNIDIR   1
#define  USB_PROTOCOL_PRT_BIDIR     2
#define  USB_PROTOCOL_PRT_1284      3

#define  USB_CLASS_MASS_STORAGE     8
#define  USB_SUBCLASS_MASS_RBC      1
#define  USB_SUBCLASS_MASS_ATAPI    2
#define  USB_SUBCLASS_MASS_QIC157   3
#define  USB_SUBCLASS_MASS_UFI      4
#define  USB_SUBCLASS_MASS_SFF8070I 5
#define  USB_SUBCLASS_MASS_SCSI     6
#define  USB_PROTOCOL_MASS_IRRPT    0
#define  USB_PROTOCOL_MASS_NOIRRPT  1
#define  USB_PROTOCOL_MASS_BULK     0x50

#define  USB_CLASS_HID              3
#define  USB_SUBCLASS_HID_NONE      0
#define  USB_SUBCLASS_HID_BOOT      1
#define  USB_PROTOCOL_HID_NONE      0
#define  USB_PROTOCOL_HID_KEYBOARD  1
#define  USB_PROTOCOL_HID_MOUSE     2

#define  USB_CLASS_HUB              9
#define  USB_SUBCLASS_HUB_NONE      0
#define  USB_PROTOCOL_HUB_LS        0
#define  USB_PROTOCOL_HUB_FS        0
#define  USB_PROTOCOL_HUB_HS_SINGLE 1
#define  USB_PROTOCOL_HUB_HS_MULTI  2
#define  USB_PROTOCOL_HUB_ALL       0xFF

#define  USB_CLASS_DATA             0x0A
   /* No data subclasses, set to 0 */
#define  USB_PROTOCOL_DATA_I430     0x30
#define  USB_PROTOCOL_DATA_HDLC     0x31
#define  USB_PROTOCOL_DATA_TRANS    0x32
#define  USB_PROTOCOL_DATA_Q921M    0x50
#define  USB_PROTOCOL_DATA_Q921     0x51
#define  USB_PROTOCOL_DATA_Q921TM   0x52
#define  USB_PROTOCOL_DATA_V42BIS   0x90
#define  USB_PROTOCOL_DATA_EUROISDN 0x91
#define  USB_PROTOCOL_DATA_V120     0x92
#define  USB_PROTOCOL_DATA_CAPI20   0x93
#define  USB_PROTOCOL_DATA_HOST     0xFE
#define  USB_PROTOCOL_DATA_CDC      0xFE
#define  USB_PROTOCOL_DATA_VENDOR   0xFF

/* Setup */
typedef struct
{
   uchar    BMREQUESTTYPE;
   uchar    BREQUEST;
   uint_8   WVALUE[2];
   uint_8   WINDEX[2];
   uint_8   WLENGTH[2];
} USB_SETUP, _PTR_ USB_SETUP_PTR;

/*-------------------------------------------------------------**
** Transaction callback parameters:                            **
**    pointer     pipe handle                                  **
**    pointer     parameter specified by higher level          **
**    uchar_ptr   pointer to buffer containing data (TX or RX) **
**    uint_32     length of data transferred                   **
**    USB_STATUS  status, preferably USB_OK or USB_DONE etc.   **
**-------------------------------------------------------------*/
typedef void  (_CODE_PTR_ tr_callback)(pointer, pointer, uchar_ptr, uint_32, USB_STATUS);

/*-------------------------------------------------------------------**
** Isochronous Transaction callback parameters:                      **
**    PIPE_DESCRIPTOR_STRUCT_PTR pipe handle                         **
**    TR_STRUCT_PTR              transaction handle                  **
**    USB_STATUS  status, preferably USB_OK or USB_DONE etc.         **
**-------------------------------------------------------------------*/
typedef void (_CODE_PTR_ iso_tr_callback)(struct pipe_struct _PTR_, struct tr_struct _PTR_, USB_STATUS);

/*---------------------------------------------------------**
** Attach/Detach callback parameters:                      **
**    _usb_device_instance_handle      new/removed device  **
**    _usb_interface_descriptor_handle matching class etc. **
**   uint_32                           code (attach etc.). **
**---------------------------------------------------------*/
typedef void (_CODE_PTR_ event_callback)(_usb_device_instance_handle, _usb_interface_descriptor_handle, uint_32);
    
typedef struct tr_struct
{
   struct tr_struct *NEXT;
   uint_32     STATUS;
   uint_32     TR_INDEX;           /* Transfer number on this pipe   */
   uchar_ptr   TX_BUFFER;          /* Address of buffer containing the data to be transmitted (including OUT data phase of control transfers) */
   uchar_ptr   RX_BUFFER;          /* Address of buffer to receive data */
   uint_32     TX_LENGTH;          /* Length of data to transmit. For control transfers, the length of data for the data phase */
   uint_32     RX_LENGTH;          /* Length of data to be received. For control transfers, this indicates the length of data for the data phase */
   tr_callback CALLBACK;           /* The callback function to be invoked when a transfer is completed or an error is to be reported */
   pointer     CALLBACK_PARAM;     /* The second parameter to be passed into the callback function when it is invoked */
   boolean SEND_PHASE;             /* Second phase of setup packet: Send/Receive */
   USB_SETUP  setup_packet;        /* Setup packet raw data */
} TR_STRUCT, _PTR_ TR_STRUCT_PTR;

typedef struct tr_init_param_struct
{
   TR_STRUCT   G;                  /* Generic transfer structure */
   uchar_ptr   DEV_REQ_PTR;        /* Address of buffer containing the setup packet to send. Relevant for control pipes only */
} TR_INIT_PARAM_STRUCT, _PTR_ TR_INIT_PARAM_STRUCT_PTR;

typedef struct pipe_struct
{
   struct pipe_struct *NEXT;
   pointer     DEV_INSTANCE;       /* Instance on list of all devices that own pipe. */
   uint_32     INTERVAL;           /* Interval for polling pipe for data transfer. */
   uint_32     NAK_COUNT;          /* The maximum number of NAK responses tolerated. MUST be zero for interrupt. */
                                   /* For USB 1.1, after count NAKs/frame,transaction is deferred to next frame. */
                                   /* For USB 2.0, the host controller will not execute transaction following this many NAKs. */
   uint_32     FIRST_FRAME;        /* The frame # to start xfer */
   uint_32     FIRST_UFRAME;       /* Microframe # to start xfer */
   uint_32     FLAGS;              /* After all data transferred, should we terminate the transfer with a zero length packet if the last packet size == MAX_PACKET_SIZE? */
   uint_16     MAX_PACKET_SIZE;    /* Pipe's maximum packet size for sending or receiving. */
   int_16      PIPE_ID;            /* Pipe's unique ID within host controller */
   uint_8      DEVICE_ADDRESS;     /* The device's address 1-127  */
   uint_8      ENDPOINT_NUMBER;    /* The endpoint number */
   uint_8      DIRECTION;          /* Input or Output */
   uint_8      PIPETYPE;           /* Control, interrupt, bulk or isochronous */
   uint_8      SPEED;              /* High/full/low */
   uint_8      TRS_PER_UFRAME;     /* Number of transaction per frame, only high-speed high-bandwidth pipes. */
   uint_8      OPEN;               /* Open flag */
   uint_8      NEXTDATA01;         /* Endpoint data toggling bit */
   TR_STRUCT_PTR    tr_list_ptr;   /* List of transactions scheduled on this pipe */
   uint_8      HUB_DEVICE_ADDR;    /* The address of hub to which the device instance is attached */
   uint_8      HUB_PORT_NUM;       /* The port of the hub to which the device instance is attached */
} PIPE_STRUCT, _PTR_ PIPE_STRUCT_PTR;

typedef struct pipe_init_param_struct
{
   struct pipe_struct G;
} PIPE_INIT_PARAM_STRUCT, _PTR_ PIPE_INIT_PARAM_STRUCT_PTR;

/* Class Callback function storage structure */
typedef struct device_class_info_struct {
   uint_8               CLASS_TYPE;
   uint_8               SUB_CLASS;
   uint_8               PROTOCOL;
} DEVICE_CLASS_INFO_STRUCT, _PTR_ DEVICE_CLASS_INFO_STRUCT_PTR;

/* Information for one class or device driver */
typedef struct driver_info
{
   uint_8         idVendor[2];      /* Vendor ID per USB-IF */
   uint_8         idProduct[2];     /* Product ID per manufacturer */
   uint_8         bDeviceClass;     /* Class code, 0xFF if any */
   uint_8         bDeviceSubClass;  /* Sub-Class code, 0xFF if any */
   uint_8         bDeviceProtocol;  /* Protocol, 0xFF if any */
   uint_8         reserved;         /* Alignment padding */
   event_callback attach_call;
} USB_HOST_DRIVER_INFO, _PTR_ USB_HOST_DRIVER_INFO_PTR;

/* Pipe bundle = device handle + interface handle + 
**                1..N pipe handles 
** NOTE: The pipe handles are for non-control pipes only, i.e.
**          pipes belonging strictly to this interface.
**       The control pipe belongs to the device, even if it
**          is being used by the device's interfaces.  Hence
**          a pointer to the device instance is provided.
**          Closing pipes for the interface does NOT close
**          the control pipe which may still be required to
**          set new configurations/interfaces etc. */
typedef struct pipe_bundle_struct
{
   _usb_device_instance_handle      dev_handle;
   _usb_interface_descriptor_handle intf_handle;
   _usb_pipe_handle                 pipe_handle[4];
} PIPE_BUNDLE_STRUCT, _PTR_ PIPE_BUNDLE_STRUCT_PTR;
                           
/* The following struct is for storing a class's validity-check
** code with the pointer to the data.  The address of one such
** struct is passed as a pointer to select-interface calls,
** where values for that interface get initialized.  Then the
** struct should be passed to class calls using the interface. */
typedef struct class_call_struct
{
   _usb_class_intf_handle         class_intf_handle;
   uint_32                        code_key;
   pointer                        next;   /* Used by class driver or app, usually pointer to next CLASS_CALL_STRUCT */
   pointer                        anchor; /* Used by class driver or app, usually pointer to first CLASS_CALL_STRUCT */
}  CLASS_CALL_STRUCT, _PTR_ CLASS_CALL_STRUCT_PTR;

/* Define function type for class device instance initialization */
typedef void (_CODE_PTR_ INTF_INIT_CALL) (PIPE_BUNDLE_STRUCT_PTR, CLASS_CALL_STRUCT_PTR);
/* Define function type for class device instance deinitialization, internal */
typedef void (_CODE_PTR_ INTF_DEINIT_CALL) (_usb_class_intf_handle);

/* The following define the internal mapping from interface
** class / sub-class / protocol to class drivers 
*/
typedef struct class_map
{
   INTF_INIT_CALL class_init;       /* class driver initialization- entry  of the class driver */
   uint_16        intf_struct_size; /* size of class's data struct  */
   uint_8         class_code;       /* interface descriptor class, */
   uint_8         sub_class_code;   /*   sub-class, and            */
   uint_8         protocol_code;    /*   protocol.                 */
   uint_8         class_code_mask;  /* masks ANDed with class etc. */
   uint_8         sub_code_mask;    /*   mask = 0x00 matches any   */
   uint_8         prot_code_mask;   /*   mask = 0xFF must be exact */
} CLASS_MAP, _PTR_ CLASS_MAP_PTR;
                              
/* The generalized heading can alias to any class-intf
** which defines its first four fields as follows: */
typedef struct general_class
{
   struct general_class _PTR_       next;    /* next list item */
   struct general_class _PTR_       anchor;  /* list start */
   _usb_device_instance_handle      dev_handle;
   _usb_interface_descriptor_handle intf_handle;
   _usb_host_handle                 host_handle;
   INTF_DEINIT_CALL                 class_deinit;
   uint_32                          key_code;
} GENERAL_CLASS, _PTR_ GENERAL_CLASS_PTR;

/* List of Function Prototypes */

#ifdef __cplusplus
extern "C" {
#endif

void  usb_hostdev_attach_detach(struct dev_instance _PTR_, uint_32);
USB_STATUS usb_hostdev_busy_check(_usb_device_instance_handle);
USB_STATUS usb_hostdev_validate(_usb_device_instance_handle);
USB_STATUS _usb_hostdev_get_buffer(_usb_device_instance_handle, uint_32, pointer _PTR_);
USB_STATUS _usb_hostdev_get_buffer_aligned(_usb_device_instance_handle, uint_32, uint_32, pointer _PTR_);
USB_STATUS _usb_hostdev_free_buffer(_usb_device_instance_handle, pointer);
USB_STATUS _usb_hostdev_get_descriptor(_usb_device_instance_handle, _usb_interface_descriptor_handle, descriptor_type, uint_8, uint_8, pointer _PTR_);
_usb_pipe_handle _usb_hostdev_find_pipe_handle(_usb_device_instance_handle, _usb_interface_descriptor_handle, uint_8, uint_8);
_usb_pipe_handle usb_hostdev_get_pipe_handle(PIPE_BUNDLE_STRUCT_PTR, uint_8, uint_8);
USB_STATUS usb_host_class_intf_init(PIPE_BUNDLE_STRUCT_PTR, pointer, pointer, INTF_DEINIT_CALL);
uint_32  usb_host_class_intf_validate(pointer);
USB_STATUS _usb_host_driver_info_register(_usb_host_handle, pointer);
USB_STATUS _usb_hostdev_select_config(_usb_device_instance_handle, uint_8);
void  usb_hostdev_delete_interface(struct dev_instance _PTR_, struct usb_interface_descriptor _PTR_);
USB_STATUS _usb_hostdev_select_interface(_usb_device_instance_handle, _usb_interface_descriptor_handle, pointer);
void usb_hostdev_tr_init(TR_INIT_PARAM_STRUCT_PTR, tr_callback, pointer);
void usb_hostdev_iso_tr_init(TR_INIT_PARAM_STRUCT_PTR, iso_tr_callback, pointer);
uint_32 _usb_hostdev_get_speed(_usb_device_instance_handle);
      
#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_pit.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_pit.h$
* $Version : 3.8.1.0$
* $Date    : May-11-2011$
*
* Comments:
*
*   This file contains definitions for the programmable interrupt timer
*   utility functions.
*
*END************************************************************************/

#ifndef __timer_pit_h__
#define __timer_pit_h__

#include <mqx.h>
#include <bsp.h>

#ifdef __cplusplus
extern "C" {
#endif


typedef struct pit_timer_init_struct {
   PSP_INTERRUPT_TABLE_INDEX  INTERRUPT;
   _int_level                 LEVEL;
   _int_priority              PRIORITY;
} PIT_TIMER_INIT_STRUCT, _PTR_ PIT_TIMER_INIT_STRUCT_PTR;


/*-----------------------------------------------------------------------*/
/*                      FUNCTION PROTOTYPES
*/

extern const PIT_TIMER_INIT_STRUCT _bsp_timers[];

pointer _bsp_get_pit_base_address (uint_8);
uint_32 _bsp_get_pit_vector (uint_8);

uint_32 _pit_init_freq(uint_8, uint_32, uint_32, boolean);
uint_32 _pit_get_hwticks(pointer);
void _pit_clear_int(uint_8);

#define _pit_unmask_int(timer)  _bsp_int_enable(_bsp_timers[(timer)].INTERRUPT)
#define _pit_mask_int(timer)   _bsp_int_disable(_bsp_timers[(timer)].INTERRUPT)

#ifdef __cplusplus
}
#endif

#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/mcf522xx/adc_mcf522xx_prv.h<|end_filename|>
#ifndef __adc_mcf52xx_prv_h__
#define __adc_mcf52xx_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_mcf522xx_prv.h$
* $Version : 3.6.13.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END************************************************************************/
#include "adc.h"
#include "adc_prv.h"
#include "adc_conf.h"

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

#define ADC_MAX_CHANNELS ADC_MAX_SW_CHANNELS

/* Structure holding ADC driver settings */
typedef struct adc {
   ADC_GENERIC           g; /* this must be included as the first item at the beginning of structure */
   /* below, CPU specific items are used */
   ADC_HW_CHANNEL_MASK   last_mask;
} ADC, _PTR_ ADC_PTR;

/* Structure holding ADC driver settings */
typedef struct adt {
   ADT_GENERIC           g; /* this must be included as the first item at the beginning of structure */
   /* below, CPU specific items are used */
   _mqx_int              shift; /* this is the radix we can shift to get from (prescaler+preset) scale to the lowest time */
   uint_32   time_to_next_adc; /* stores time needed to next AD conversion */
   uint_32   time_to_next_irq; /* stores time needed to next timer IRQ */
   uint_32   dispatch_time;    /* stores absolute time for dispatcher */
   boolean   dispatch_next;    /* informs if any data within channels_to_next_adc is valid */
} ADT, _PTR_ ADT_PTR;

/* Structure holding ADC driver channel settings, must be declared */
typedef struct adc_channel {
   ADC_CHANNEL_GENERIC   g; /* this must be included as the first member at the beginning of structure */
   /* below, CPU specific members are used */
} ADC_CHANNEL, _PTR_ ADC_CHANNEL_PTR;

/* Structure holding ADT driver channel settings, must be declared */
typedef struct adt_channel {
   ADT_CHANNEL_GENERIC   g; /* this must be included as the first member at the beginning of structure */
   /* below, CPU specific members are used */
} ADT_CHANNEL, _PTR_ ADT_CHANNEL_PTR;

/* ADC converter + trigger channel bundle structure */
typedef struct adc_channel_bundle {
   ADC_CHANNEL_PTR  adc_ch;
   ADT_CHANNEL_PTR  adt_ch;
   /* below, CPU specific members are used */
} ADC_CHANNEL_BUNDLE, _PTR_ ADC_CHANNEL_BUNDLE_PTR;

/* ADC converter + trigger bundle structure */
typedef struct adc_driver_bundle {
   ADC_PTR          adc;                      /* ADC driver status information (generic + HW specific) */
   ADT_PTR          adt;                      /* ADT driver status information (generic + HW specific) */
   ADC_CHANNEL_PTR  adc_ch[ADC_MAX_CHANNELS];
   ADT_CHANNEL_PTR  adt_ch[ADC_MAX_CHANNELS];
   uchar_ptr        adc_name[ADC_MAX_CHANNELS]; /* filename of channel(s) */
   /* below, CPU specific members are used */
   uint_32          last_mask; /* mask of ADC channels to perform ADC next time */
} ADC_DRIVER_BUNDLE, _PTR_ ADC_DRIVER_BUNDLE_PTR;

/* anything static can be shared within ADC and ADT */
/* typedef struct adc_bundle {
} ADC_BUNDLE, ADC_BUNDLE_PTR; */

_mqx_int _adc_hw_install(char_ptr, ADC_DRIVER_BUNDLE_PTR, pointer);
_mqx_int _adt_hw_install(char_ptr, ADC_DRIVER_BUNDLE_PTR, pointer);
_mqx_int _adc_hw_init(MQX_FILE_PTR, ADC_PTR);
_mqx_int _adt_hw_init(MQX_FILE_PTR, ADT_PTR);
_mqx_int _adc_hw_deinit(MQX_FILE_PTR, ADC_PTR);
_mqx_int _adt_hw_deinit(MQX_FILE_PTR, ADT_PTR);
_mqx_int _adc_hw_channel_init(MQX_FILE_PTR, ADC_CHANNEL_PTR);
_mqx_int _adt_hw_channel_init(MQX_FILE_PTR, ADT_CHANNEL_PTR);
_mqx_int _adc_hw_channel_deinit(MQX_FILE_PTR, ADC_CHANNEL_PTR);
_mqx_int _adt_hw_channel_deinit(MQX_FILE_PTR, ADT_CHANNEL_PTR);
_mqx_int _adc_hw_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);
_mqx_int _adt_hw_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);

void _adc_hw_measure(ADC_HW_CHANNEL_MASK);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/int/serl_int_mcf52xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_int_mcf52xx.c$
* $Version : 3.8.4.0$
* $Date    : Sep-15-2011$
*
* Comments:
*
*   This file contains the low level functions for the interrupt driven
*   serial I/O for the MCF52XX UART.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "io_prv.h"
#include "charq.h"
#include "fio_prv.h"
#include "serinprv.h"
#include "serl_mcf52xx.h"

/* Polled functions used */
extern uint_32 _mcf52xx_uart_serial_polled_init(MCF52XX_UART_SERIAL_INIT_STRUCT_PTR,
   pointer _PTR_, char _PTR_);
extern uint_32 _mcf52xx_uart_serial_polled_deinit(MCF52XX_UART_SERIAL_INIT_STRUCT_PTR,
   MCF52XX_UART_SERIAL_INFO_STRUCT_PTR);
extern uint_32 _mcf52xx_uart_serial_polled_ioctl(MCF52XX_UART_SERIAL_INFO_STRUCT_PTR, uint_32,
   uint_32_ptr);

/* Interrupt driver functions */

extern void    _mcf52xx_uart_serial_int_putc(IO_SERIAL_INT_DEVICE_STRUCT_PTR, char);

extern uint_32 _mcf52xx_uart_serial_int_init(IO_SERIAL_INT_DEVICE_STRUCT_PTR,
 char _PTR_);
extern uint_32 _mcf52xx_uart_serial_int_deinit(MCF52XX_UART_SERIAL_INIT_STRUCT_PTR,
   MCF52XX_UART_SERIAL_INFO_STRUCT_PTR);
extern uint_32 _mcf52xx_uart_serial_int_enable(MCF52XX_UART_SERIAL_INFO_STRUCT_PTR);
extern void    _mcf52xx_uart_serial_int_isr(pointer);


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mcf52xx_uart_serial_int_install
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    Install an interrupt driven uart serial device.
*
*END*----------------------------------------------------------------------*/

uint_32 _mcf52xx_uart_serial_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr identifier,

      /* [IN] The I/O init data pointer */
      MCF52XX_UART_SERIAL_INIT_STRUCT_CPTR  init_data_ptr,

      /* [IN] The I/O queue size to use */
      uint_32  queue_size
   )
{ /* Body */

   return _io_serial_int_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, char _PTR_))_mcf52xx_uart_serial_int_init,
      (uint_32 (_CODE_PTR_)(pointer))_mcf52xx_uart_serial_int_enable,
      (uint_32 (_CODE_PTR_)(pointer,pointer))_mcf52xx_uart_serial_int_deinit,
      (void    (_CODE_PTR_)(pointer, char))_mcf52xx_uart_serial_int_putc,
      (uint_32 (_CODE_PTR_)(pointer, uint_32, pointer))_mcf52xx_uart_serial_polled_ioctl,
      (pointer)init_data_ptr, queue_size);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_int_init
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function initializes the UART in interrupt mode.
*
*END*********************************************************************/

uint_32 _mcf52xx_uart_serial_int_init
   (
      /* [IN] the interrupt I/O initialization information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the rest of the name of the device opened */
      char _PTR_                      open_name_ptr
   )
{ /* Body */
   MCF52XX_UART_SERIAL_INFO_STRUCT_PTR uart_info_ptr;
   MCF52XX_UART_SERIAL_INIT_STRUCT_PTR uart_init_ptr;
   uint_32                             result;

   uart_init_ptr = int_io_dev_ptr->DEV_INIT_DATA_PTR;
   result = _mcf52xx_uart_serial_polled_init((pointer)uart_init_ptr,
      &int_io_dev_ptr->DEV_INFO_PTR, open_name_ptr);
   if (result != MQX_OK) {
      return(result);
   }/* Endif */

   uart_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   uart_info_ptr->OLD_ISR_DATA = _int_get_isr_data(uart_init_ptr->VECTOR);
   uart_info_ptr->OLD_ISR_EXCEPTION_HANDLER =
      _int_get_exception_handler(uart_init_ptr->VECTOR);

   uart_info_ptr->OLD_ISR =
      _int_install_isr(uart_init_ptr->VECTOR, _mcf52xx_uart_serial_int_isr,
      int_io_dev_ptr);

   return(MQX_OK);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_int_deinit
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function de-initializes the UART in interrupt mode.
*
*END*********************************************************************/

uint_32 _mcf52xx_uart_serial_int_deinit
   (
      /* [IN] the interrupt I/O initialization information */
      MCF52XX_UART_SERIAL_INIT_STRUCT_PTR io_init_ptr,

      /* [IN] the address of the device specific information */
      MCF52XX_UART_SERIAL_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   volatile MCF52XX_UART_STRUCT _PTR_ uart_ptr = io_info_ptr->UART_PTR;

   uart_ptr->WRITE.UIMR = 0; /* Disable all interrupts */
   _mcf52xx_uart_serial_polled_deinit(io_init_ptr, io_info_ptr);
   _int_install_isr(io_init_ptr->VECTOR, io_info_ptr->OLD_ISR,
      io_info_ptr->OLD_ISR_DATA);

   return(MQX_OK);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_int_enable
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function enables the UART interrupts mode.
*
*END*********************************************************************/

uint_32 _mcf52xx_uart_serial_int_enable
   (
      /* [IN] the address of the device specific information */
      MCF52XX_UART_SERIAL_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   uint_32 status;

/* Start CR 2087 */
   status = _mcf52xx_int_init((PSP_INTERRUPT_TABLE_INDEX)io_info_ptr->INIT.VECTOR,
      io_info_ptr->INIT.LEVEL, io_info_ptr->INIT.SUBLEVEL, TRUE);
/* End CR 2087 */      

   if (status == MQX_OK) {
//      volatile MCF52XX_STRUCT _PTR_      mcf52XX_ptr = io_info_ptr->MCF52XX_PTR;
      volatile MCF52XX_UART_STRUCT _PTR_ uart_ptr = io_info_ptr->UART_PTR;

      io_info_ptr->INT_ENABLE_BITS = MCF52XX_UART_UIMR_FFULL;
      uart_ptr->WRITE.UIMR = io_info_ptr->INT_ENABLE_BITS;
   } /* Endif */

   return status;

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_int_isr
* Returned Value   : none
* Comments         :
*   interrupt handler for the serial I/O interrupts.
*
*************************************************************************/

void _mcf52xx_uart_serial_int_isr
   (
      /* [IN] the address of the device specific information */
      pointer parameter
   )
{ /* Body */
   IO_SERIAL_INT_DEVICE_STRUCT_PTR        int_io_dev_ptr = parameter;
   MCF52XX_UART_SERIAL_INFO_STRUCT_PTR    uart_info_ptr;
   volatile MCF52XX_UART_STRUCT _PTR_     uart_ptr;
   int_32                                 c;
   uint_16                                stat;
   boolean                                work;

   uart_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   uart_ptr = uart_info_ptr->UART_PTR;

   ++uart_info_ptr->INTERRUPTS;

   /* Receive loop */
   work = TRUE;
   while (work) {
      work = FALSE;
      stat = uart_ptr->READ.USR;

      while (stat & MCF52XX_UART_USR_RXRDY) {
         c = uart_ptr->READ.URB;    /* this clears the status bit */

         if (stat & (MCF52XX_UART_USR_RB | MCF52XX_UART_USR_FE |
                     MCF52XX_UART_USR_PE | MCF52XX_UART_USR_OE))
         {
            if (stat & MCF52XX_UART_USR_RB) {
               ++uart_info_ptr->RX_BREAKS;
               c = uart_ptr->READ.URB;    /* read break character */
               uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_BREAK;
            } /* Endif */
            if (stat & MCF52XX_UART_USR_FE) {
               ++uart_info_ptr->RX_FRAMING_ERRORS;
            } /* Endif */
            if (stat & MCF52XX_UART_USR_PE) {
               ++uart_info_ptr->RX_PARITY_ERRORS;
            } /* Endif */
            if (stat & MCF52XX_UART_USR_OE) {
               ++uart_info_ptr->RX_OVERRUNS;
            } /* Endif */
            uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_ERROR;
         } /* Endif */

         uart_info_ptr->RX_CHARS++;
         work = TRUE;

         if (!_io_serial_int_addc(int_io_dev_ptr, c)) {
            uart_info_ptr->RX_DROPPED_INPUT++;
         } /* Endif */
         stat = uart_ptr->READ.USR;

      } /* Endwhile */

      while (stat & MCF52XX_UART_USR_TXRDY)  {

         c = _io_serial_int_nextc(int_io_dev_ptr);
         if (c >= 0) {
            work = TRUE;
            uart_ptr->WRITE.UTB = c;
            uart_info_ptr->INT_ENABLE_BITS |= MCF52XX_UART_UIMR_TXRDY;
            uart_ptr->WRITE.UIMR = uart_info_ptr->INT_ENABLE_BITS;
         } else {
            /* No output. Turn off transmit interrupt */
            uart_info_ptr->INT_ENABLE_BITS &= ~MCF52XX_UART_UIMR_TXRDY;
            uart_ptr->WRITE.UIMR = uart_info_ptr->INT_ENABLE_BITS;
            break;
         } /* Endif */

         stat = uart_ptr->READ.USR;
         uart_info_ptr->TX_CHARS++;

      } /* Endwhile */

   } /* Endwhile */

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_int_putc
* Returned Value   : none
* Comments         :
*   This function is called to write out the first character, when
* the output serial device and output ring buffers are empty.
*
*END*********************************************************************/

void _mcf52xx_uart_serial_int_putc
   (
      /* [IN] the address of the device specific information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the character to write out now */
      char                       c
   )
{ /* Body */
   MCF52XX_UART_SERIAL_INFO_STRUCT_PTR uart_info_ptr;
   volatile MCF52XX_UART_STRUCT _PTR_  uart_ptr;

   uart_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   uart_ptr = uart_info_ptr->UART_PTR;

   while (!(uart_ptr->READ.USR & MCF52XX_UART_USR_TXRDY)) {
   } /* Endwhile */
   uart_ptr->WRITE.UTB = c;
   uart_info_ptr->TX_CHARS++;

   /* Interrupt when character has been sent */
   uart_info_ptr->INT_ENABLE_BITS |= MCF52XX_UART_UIMR_TXRDY;
   uart_ptr->WRITE.UIMR = uart_info_ptr->INT_ENABLE_BITS;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_nandflash.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_nandflash.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the default initialization record for the NAND
*   flash.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "nfc.h"

extern NANDFLASH_INFO_STRUCT _MT29F2G16_organization_16bit[];

const NANDFLASH_INIT_STRUCT _bsp_nandflash_init =
{
   /* NAME                 */   "nandflash:",
   /* INIT                 */   nfc_init,
   /* DEINIT               */   nfc_deinit,
   /* CHIP_ERASE           */   nfc_erase_flash,
   /* BLOCK_ERASE          */   nfc_erase_block,
   /* PAGE_READ            */   nfc_read_page,
   /* PAGE_PROGRAM         */   nfc_write_page,
   /* WRITE_PROTECT        */   NULL,
   /* IS_BLOCK_BAD         */   nfc_check_block,
   /* MARK_BLOCK_AS_BAD    */   nfc_mark_block_as_bad,
   /* IOCTL                */   nfc_ioctl,
   /* NANDFLASH_INFO_PTR   */   _MT29F2G16_organization_16bit,
   /* VIRTUAL_PAGE_SIZE    */   0,
   /* NUM_VIRTUAL_PAGES    */   0,
   /* PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO */   
                                0,
   /* ECC_SIZE             */   0,
   /* WRITE_VERIFY         */   0,
   /* DEVICE_SPECIFIC_DATA */   0
};

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/app_types.h<|end_filename|>
#ifndef  __APP_TYPES
  #define  __APP_TYPES


#define     BIT(n) (1u << n)
#define     LSHIFT(v,n) (((unsigned int)(v) << n))



typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;                    /* Unsigned  8 bit quantity                           */
typedef signed   char  INT8S;                    /* Signed    8 bit quantity                           */
typedef unsigned short INT16U;                   /* Unsigned 16 bit quantity                           */
typedef signed   short INT16S;                   /* Signed   16 bit quantity                           */
typedef unsigned int   INT32U;                   /* Unsigned 32 bit quantity                           */
typedef signed   int   INT32S;                   /* Signed   32 bit quantity                           */
typedef unsigned long  INT64U;                   /* Unsigned 64 bit quantity                           */
typedef float          FP32;                     /* Single precision floating point                    */
typedef double         FP64;                     /* Double precision floating point                    */

typedef volatile unsigned long   VINT32U;
typedef volatile unsigned short  VINT16U;
typedef volatile unsigned char   VINT8U;



#endif


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/hub/usb_host_hub.h<|end_filename|>
#ifndef __usb_host_hub_h__
#define __usb_host_hub_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_hub.h$
* $Version : 3.8.11.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file defines a structure(s) for hub class driver.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"

#include "hostapi.h"

#define  USB_CLASS_HUB              9
#define  USB_SUBCLASS_HUB_NONE      0
#define  USB_PROTOCOL_HUB_LS        0
#define  USB_PROTOCOL_HUB_FS        0
#define  USB_PROTOCOL_HUB_HS_SINGLE 1
#define  USB_PROTOCOL_HUB_HS_MULTI  2
#define  USB_PROTOCOL_HUB_ALL       0xFF

/*
** HUB Class Interface structure. This structure will be passed to
** all commands to this class driver.
*/
typedef struct {
   /* Each class must start with a GENERAL_CLASS struct */
   GENERAL_CLASS                             G;
   /* application handle */
   CLASS_CALL_STRUCT_PTR                     APP;

   /* Pipes */
   _usb_pipe_handle                          P_CONTROL;
   _usb_pipe_handle                          P_INT_IN;
   /* Is command used? (only 1 command can be issued at one time) */
   boolean                                   IN_SETUP;
   /* Only 1 interrupt pipe can be opened at one time */
   boolean                                   INT_PIPE;

   /* Higher level callback and parameter */
   tr_callback                               CTRL_CALLBACK;
   pointer                                   CTRL_PARAM;

   /* Higher level callback and parameter */
   tr_callback                               INT_CALLBACK;
   pointer                                   INT_PARAM;

   uint_32                                   C_BUF_SIZE;
   uint_32                                   I_BUF_SIZE;
   /* control pipe buffer pointer, allocated in memlist */
   uint_8_ptr                                C_BUF;

   /* interrupt pipe buffer pointer, allocated in memlist */
   uint_8_ptr                                I_BUF;

} USB_HUB_CLASS_INTF_STRUCT, _PTR_ USB_HUB_CLASS_INTF_STRUCT_PTR;

/* Class specific functions exported by hub class driver */
#ifdef __cplusplus
extern "C" {
#endif

extern void usb_class_hub_init(PIPE_BUNDLE_STRUCT_PTR, CLASS_CALL_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/ehci/ehci_main.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_main.c$
* $Version : 3.8.43.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the main low-level Host API functions specific to 
*   the VUSB chip.
*
*END************************************************************************/
#include <mqx.h>
#include <bsp.h>

#include "usb.h"
#include "usb_prv.h"

#include "hostapi.h"
#include "host_dev_list.h"

#include "host_cnfg.h"
#include "ehci_main.h"
#include "ehci_prv.h"

#ifdef __USB_OTG__
#include "otgapi.h"
   extern USB_OTG_STATE_STRUCT_PTR usb_otg_state_struct_ptr;
#endif


/**************************************************************************
 Local Functions. Note intended to be called from outside this file 
**************************************************************************/

static void _usb_ehci_process_qh_list_tr_complete(
      _usb_host_handle                 handle,
      ACTIVE_QH_MGMT_STRUCT_PTR        active_list_member_ptr
   );

static void _usb_ehci_process_qh_interrupt_tr_complete(
      _usb_host_handle                 handle,
      ACTIVE_QH_MGMT_STRUCT_PTR        active_list_member_ptr
   );

static void _usb_ehci_process_itd_tr_complete
   (
      _usb_host_handle                 handle
   );
   
static void _usb_ehci_process_sitd_tr_complete
   (
      _usb_host_handle                 handle
   );
   
const USB_HOST_CALLBACK_FUNCTIONS_STRUCT _usb_ehci_host_callback_table = 
{
   /* The Host/Device init function */
   _usb_ehci_preinit,

   /* The Host/Device init function */
   _usb_ehci_init,

   /* The function to shutdown the host/device */
   _usb_ehci_shutdown,

   /* The function to send data */
   _usb_ehci_send_data,

   /* The function to send setup data */
   _usb_ehci_send_setup,

   /* The function to receive data */
   _usb_ehci_recv_data,
   
   /* The function to get the transfer status */
//   NULL,
   
   /* The function to cancel the transfer */
   _usb_ehci_cancel_transfer,
   
   /* The function to do USB sleep */
//   NULL,
   
   /* The function for USB bus control */
   _usb_ehci_bus_control,

   _usb_ehci_allocate_bandwidth,

   _usb_ehci_free_resources,
    
   _usb_ehci_get_frame_number,
   
   _usb_ehci_get_micro_frame_number,
   
   /* The function to open a pipe */
   _usb_ehci_open_pipe,
   
   /* The function to update the maximum packet size */
   NULL,
   
   /* The function to update the device address */
   _usb_ehci_update_dev_address
};

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_send_data
*  Returned Value : None
*  Comments       :
*        Send the data
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_ehci_send_data
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle              handle,

      /* [IN] The pipe descriptor to queue */            
      PIPE_STRUCT_PTR               pipe_descr_ptr,
      
      /* [IN] the transfer parameters struct */
      TR_STRUCT_PTR                 current_pipe_tr_struct_ptr
   )
{ /* Body */
   USB_STATUS status;
   
   status = _usb_ehci_queue_pkts(handle, (EHCI_PIPE_STRUCT_PTR) pipe_descr_ptr, (EHCI_TR_STRUCT_PTR) current_pipe_tr_struct_ptr);
   return status;
   
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_send_setup
*  Returned Value : USB_STATUS
*  Comments       :
*        Send Setup packet
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_ehci_send_setup
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle              handle,

      /* [IN] The pipe descriptor to queue */            
      PIPE_STRUCT_PTR               pipe_descr_ptr,
      
      /* [IN] the transfer parameters struct */
      TR_STRUCT_PTR                 current_pipe_tr_struct_ptr
   )
{ /* Body */
   USB_STATUS status;
   status = _usb_ehci_queue_pkts(handle, (EHCI_PIPE_STRUCT_PTR) pipe_descr_ptr, (EHCI_TR_STRUCT_PTR) current_pipe_tr_struct_ptr);
   return status;
   
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_recv_data
*  Returned Value : None
*  Comments       :
*        Receive data
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_ehci_recv_data
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle              handle,

      /* [IN] The pipe descriptor to queue */            
      PIPE_STRUCT_PTR               pipe_descr_ptr,
      
      /* [IN] the transfer parameters struct */
      TR_STRUCT_PTR                 current_pipe_tr_struct_ptr
   )
{ /* Body */
   USB_STATUS status;
   
   status = _usb_ehci_queue_pkts(handle, (EHCI_PIPE_STRUCT_PTR) pipe_descr_ptr, (EHCI_TR_STRUCT_PTR) current_pipe_tr_struct_ptr);
   
   return status;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_queue_pkts
*  Returned Value : status of the transfer queuing.
*  Comments       :
*        Queue the packet in the hardware
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_ehci_queue_pkts
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR            pipe_descr_ptr,
      
      /* [IN] the transfer parameters struct */
      EHCI_TR_STRUCT_PTR               current_pipe_tr_struct_ptr
   )
{ /* Body */
   USB_STATUS  status;

   /* Queue the packets */
   switch (pipe_descr_ptr->G.PIPETYPE) {
      case USB_ISOCHRONOUS_PIPE:
         status = _usb_ehci_add_isochronous_xfer_to_periodic_schedule_list(handle, pipe_descr_ptr, current_pipe_tr_struct_ptr);
         break;
      case USB_INTERRUPT_PIPE:
         status = _usb_ehci_add_interrupt_xfer_to_periodic_list(handle, pipe_descr_ptr, current_pipe_tr_struct_ptr);
         break;
      case USB_CONTROL_PIPE:
      case USB_BULK_PIPE:
         /* Queue it on the asynchronous schedule list */
         status = _usb_ehci_add_xfer_to_asynch_schedule_list(handle, pipe_descr_ptr, current_pipe_tr_struct_ptr);
         break;
      default:
         status = USB_STATUS_ERROR;
         break;
   } /* EndSwitch */
   
   return status;
   
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_init_Q_HEAD
*  Returned Value : None
*  Comments       :
*        Initialize the Queue Head. This routine initializes a queue head 
*  for interrupt/Bulk/Control transfers.
*END*-----------------------------------------------------------------*/
void _usb_ehci_init_Q_HEAD
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,
      
      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR             pipe_descr_ptr,
      
      /* [IN] the queue head to initialize */
      EHCI_QH_STRUCT_PTR               QH_ptr,
      
      /* [IN] the previous queue head to link to */
      EHCI_QH_STRUCT_PTR               prev_QH_ptr,
      
      /* [IN] the first QTD to queue for this Queue head */
      EHCI_QTD_STRUCT_PTR              first_QTD_ptr
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR     usb_host_ptr;
   uint_32                       control_ep_flag = 0, split_completion_mask = 0;
   uint_32                       interrupt_schedule_mask = 0; 
   uint_32                       data_toggle_control = 0, item_type = 0;
   uint_32                       time_for_xaction = 0, H_bit = 0, temp;
   uint_8                        mult = 1, period = 0;
  
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

/******************************************************************************
 PREPARE THE BASIC FIELDS OF A QUEUE HEAD DEPENDING UPON THE PIPE TYPE
*******************************************************************************/
#if PSP_HAS_DATA_CACHE    // TODO change to memzero and flush
   /********************************************************
   USB Memzero does not bypass the cache and hence explicit
   setting to zero is required in software
   ********************************************************/
   EHCI_MEM_WRITE(QH_ptr->HORIZ_LINK_PTR,0);
   EHCI_MEM_WRITE(QH_ptr->EP_CAPAB_CHARAC1,0);
   EHCI_MEM_WRITE(QH_ptr->EP_CAPAB_CHARAC2,0);
   EHCI_MEM_WRITE(QH_ptr->CURR_QTD_LINK_PTR,0);
   EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,0);
   EHCI_MEM_WRITE(QH_ptr->ALT_NEXT_QTD_LINK_PTR,0);
   EHCI_MEM_WRITE(QH_ptr->STATUS,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_0,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_1,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_2,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_3,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_4,0);
#else
      USB_mem_zero((void *)QH_ptr, 12*sizeof(uint_32));
#endif // PSP_HAS_DATA_CACHE

   switch (pipe_descr_ptr->G.PIPETYPE) 
   {
      case  USB_CONTROL_PIPE:
         if (pipe_descr_ptr->G.SPEED != USB_SPEED_HIGH) 
         {
            control_ep_flag = 1;
         }
         item_type = EHCI_FRAME_LIST_ELEMENT_TYPE_QH;
         H_bit = (uint_32) ((prev_QH_ptr == QH_ptr)? 1 : 0);
         data_toggle_control = 1; /* Data toggle in qTD */
         break;

      case  USB_INTERRUPT_PIPE:
         data_toggle_control = 0; /* Data toggle in QH */
           break;

      case  USB_BULK_PIPE:
         item_type = EHCI_FRAME_LIST_ELEMENT_TYPE_QH;
         H_bit = (uint_32) ((prev_QH_ptr == QH_ptr) ? 1 : 0);
#if USBCFG_EHCI_USE_SW_TOGGLING
         data_toggle_control = 1; /* Data toggle in qTD */
#else
         data_toggle_control = 0; /* Data toggle in QH */
#endif
       break;
   
   }  
   
   if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) 
   {
      mult = pipe_descr_ptr->G.TRS_PER_UFRAME;
   }  

/******************************************************************************
 PREPARE THE Fields that are same for all pipes.
*******************************************************************************/
   
   QH_ptr->PIPE_DESCR_FOR_THIS_QH = (pointer)pipe_descr_ptr;
   pipe_descr_ptr->QH_FOR_THIS_PIPE = (pointer)QH_ptr;
   
   EHCI_MEM_WRITE(QH_ptr->CURR_QTD_LINK_PTR,0);
   EHCI_MEM_WRITE(QH_ptr->ALT_NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
   EHCI_MEM_WRITE(QH_ptr->STATUS,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_0,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_1,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_2,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_3,0);
   EHCI_MEM_WRITE(QH_ptr->BUFFER_PTR_4,0);


/****************************************************************************
 copy the fields inside the QH
*****************************************************************************/


   /* Initialize the endpoint capabilities registers */   
   temp = (
          ((uint_32)pipe_descr_ptr->G.NAK_COUNT << EHCI_QH_NAK_COUNT_RL_BITS_POS) | 
          (control_ep_flag << EHCI_QH_EP_CTRL_FLAG_BIT_POS) | 
          (pipe_descr_ptr->G.MAX_PACKET_SIZE << EHCI_QH_MAX_PKT_SIZE_BITS_POS) |
          (H_bit << EHCI_QH_HEAD_RECLAMATION_BIT_POS) |
          (data_toggle_control << EHCI_QH_DTC_BIT_POS) | 
          (pipe_descr_ptr->G.SPEED << EHCI_QH_SPEED_BITS_POS) |
          ((uint_32)pipe_descr_ptr->G.ENDPOINT_NUMBER << EHCI_QH_EP_NUM_BITS_POS) | 
          pipe_descr_ptr->G.DEVICE_ADDRESS);
   EHCI_MEM_WRITE(QH_ptr->EP_CAPAB_CHARAC1, temp);

   temp = (
          (mult << EHCI_QH_HIGH_BW_MULT_BIT_POS) |
          (pipe_descr_ptr->G.HUB_PORT_NUM << EHCI_QH_HUB_PORT_NUM_BITS_POS) |
          (pipe_descr_ptr->G.HUB_DEVICE_ADDR << EHCI_QH_HUB_ADDR_BITS_POS) |
          (split_completion_mask << EHCI_QH_SPLIT_COMPLETION_MASK_BITS_POS) |
          interrupt_schedule_mask);
   EHCI_MEM_WRITE(QH_ptr->EP_CAPAB_CHARAC2,temp);
      
/****************************************************************************
 Queue the transfers now by updating the pointers
*****************************************************************************/      

  switch (pipe_descr_ptr->G.PIPETYPE) 
  {
      case  USB_CONTROL_PIPE:
         /* Link the new Queue Head to the previous Queue Head */
         EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,(uint_32)first_QTD_ptr);
         EHCI_MEM_WRITE(QH_ptr->HORIZ_LINK_PTR,EHCI_MEM_READ((uint_32)prev_QH_ptr->HORIZ_LINK_PTR));
         EHCI_MEM_WRITE(prev_QH_ptr->HORIZ_LINK_PTR,((uint_32)QH_ptr | (item_type << EHCI_QH_ELEMENT_TYPE_BIT_POS)));
      break;
      case  USB_BULK_PIPE:
         /* Link the new Queue Head to the previous Queue Head */
         EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,(uint_32)first_QTD_ptr);
         EHCI_MEM_WRITE(QH_ptr->HORIZ_LINK_PTR,EHCI_MEM_READ((uint_32)prev_QH_ptr->HORIZ_LINK_PTR));
         EHCI_MEM_WRITE(prev_QH_ptr->HORIZ_LINK_PTR,((uint_32)QH_ptr | (item_type << EHCI_QH_ELEMENT_TYPE_BIT_POS)));
      break;
      case  USB_INTERRUPT_PIPE:
         EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
         EHCI_MEM_WRITE(QH_ptr->HORIZ_LINK_PTR,EHCI_QUEUE_HEAD_POINTER_T_BIT);
      break;
  }
          
  return;

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_init_QTD
*  Returned Value : None
*  Comments       :
*        Initialize the QTD
*END*-----------------------------------------------------------------*/
void _usb_ehci_init_QTD
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* [IN] the address of the QTD to initialize */
      EHCI_QTD_STRUCT_PTR              QTD_ptr,
      

      /* The buffer start address for the QTD */            
      uchar_ptr                        buffer_start_address,

      /* The token value */
      uint_32                          token
   )
{ /* Body */

#if PSP_HAS_DATA_CACHE    // TODO change to memzero and flush
      /********************************************************
      USB Memzero does not bypass the cache and hence explicit
      setting to zero is required in software
      ********************************************************/
      EHCI_MEM_WRITE(QTD_ptr->NEXT_QTD_PTR,0);
      EHCI_MEM_WRITE(QTD_ptr->ALT_NEXT_QTD_PTR,0);
      EHCI_MEM_WRITE(QTD_ptr->TOKEN,0);
      EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_0,0);
      EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_1,0);
      EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_2,0);
      EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_3,0);
      EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_4,0);
#else
      /* Zero the QTD. Leave the scratch pointer */
      USB_mem_zero((void *)QTD_ptr, 8*sizeof(uint_32));
#endif // PSP_HAS_DATA_CACHE

   /* Initialize the QTD */
   QTD_ptr->SCRATCH_PTR = handle;

   /* Set the Terminate bit */
   EHCI_MEM_WRITE(QTD_ptr->NEXT_QTD_PTR,EHCI_QTD_T_BIT);
   
   /* Set the Terminate bit */
   EHCI_MEM_WRITE(QTD_ptr->ALT_NEXT_QTD_PTR ,EHCI_QTD_T_BIT);

   EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_0,(uint_32)buffer_start_address);
      
   /* 4K apart buffer page pointers */
   EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_1,(EHCI_MEM_READ(QTD_ptr->BUFFER_PTR_0) + 4096));
   EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_2,(EHCI_MEM_READ(QTD_ptr->BUFFER_PTR_1) + 4096));
   EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_3,(EHCI_MEM_READ(QTD_ptr->BUFFER_PTR_2) + 4096));
   EHCI_MEM_WRITE(QTD_ptr->BUFFER_PTR_4,(EHCI_MEM_READ(QTD_ptr->BUFFER_PTR_3) + 4096));

   EHCI_MEM_WRITE(QTD_ptr->TOKEN,token);

} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_init_Q_element
*  Returned Value : None
*  Comments       :
*        Initialize the Queue Element descriptor(s)
*END*-----------------------------------------------------------------*/
uint_32 _usb_ehci_init_Q_element
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,
      
      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR             pipe_descr_ptr,
      
      /* [IN] the transfer parameters struct */
      EHCI_TR_STRUCT_PTR               current_pipe_tr_struct_ptr
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR   usb_host_ptr;
   EHCI_QTD_STRUCT_PTR              QTD_ptr, prev_QTD_ptr, first_QTD_ptr;
   uint_32                          pid_code, data_toggle, token;
   int_32                           total_length, qtd_length, num_of_packets;
   uchar_ptr                        buff_ptr;
   #if PSP_HAS_DATA_CACHE
       uchar_ptr                        uncache_buff_ptr = NULL;
   #endif
   
   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   
   /* Get a QTD from the queue */   
   EHCI_QTD_QGET(usb_host_ptr->QTD_HEAD, usb_host_ptr->QTD_TAIL, QTD_ptr);
   
   if (!QTD_ptr) {
      return USB_STATUS_TRANSFER_IN_PROGRESS;
   } /* Endif */
   
   usb_host_ptr->QTD_ENTRIES--;
   
   /* The data 0/1 for this pipe */
   data_toggle = (uint_32)((pipe_descr_ptr->G.NEXTDATA01 << EHCI_QTD_DATA_TOGGLE_BIT_POS));

   /* The very first QTD */   
   prev_QTD_ptr = first_QTD_ptr = QTD_ptr;
   
   if (pipe_descr_ptr->G.PIPETYPE == USB_CONTROL_PIPE) {
      pid_code = EHCI_QTD_PID_SETUP;
      /* Setup packet is always 8 bytes */
      token = (((uint_32)8 << EHCI_QTD_LENGTH_BIT_POS) |
         data_toggle | pid_code | EHCI_QTD_STATUS_ACTIVE);
      
      /* Initialize a QTD for Setup phase */   
      #if PSP_HAS_DATA_CACHE
          uncache_buff_ptr = USB_mem_alloc_uncached_zero(8);
          if (!uncache_buff_ptr) {
              printf("%s,%d USB memory allocate failed ...\n",__FUNCTION__,__LINE__);
              return 0;
          }
          _mem_set_type(uncache_buff_ptr, MEM_TYPE_USB_HOST_DEVICE);
          USB_mem_copy((uchar_ptr)(&(current_pipe_tr_struct_ptr->G.setup_packet)),uncache_buff_ptr,8);
          _usb_ehci_init_QTD(handle, QTD_ptr,(uchar_ptr)uncache_buff_ptr,token);

          QTD_ptr->RESERVED[MEM_UNCACHE_INDEX] = (uint_32)uncache_buff_ptr;
          QTD_ptr->RESERVED[MEM_CACHE_INDEX] = (uint_32)(&(current_pipe_tr_struct_ptr->G.setup_packet));
      #else
          _usb_ehci_init_QTD(handle, QTD_ptr,
             (uchar_ptr)&current_pipe_tr_struct_ptr->setup_packet,
             token);
      #endif
      QTD_ptr->RESERVED[MEM_SIZE_INDEX] = 8;
      QTD_ptr->PIPE_DESCR_FOR_THIS_QTD = (pointer)pipe_descr_ptr;
      QTD_ptr->TR_FOR_THIS_QTD = (pointer)current_pipe_tr_struct_ptr;

      /* Get a QTD from the queue for the data phase or a status phase */
      EHCI_QTD_QGET(usb_host_ptr->QTD_HEAD, usb_host_ptr->QTD_TAIL, QTD_ptr);
   
      if (!QTD_ptr) {
         return USB_STATUS_TRANSFER_IN_PROGRESS;
      } /* Endif */
   
      usb_host_ptr->QTD_ENTRIES--;

      /* The data phase QTD chained to the Setup QTD */      
      EHCI_MEM_WRITE(prev_QTD_ptr->NEXT_QTD_PTR,(uint_32)QTD_ptr);
      data_toggle = EHCI_QTD_DATA_TOGGLE;

      if (current_pipe_tr_struct_ptr->G.SEND_PHASE) {
         /* Host to Device data phase */
         if (current_pipe_tr_struct_ptr->G.TX_LENGTH) {
            /* Anything to send ? */
            pid_code = EHCI_QTD_PID_OUT;
            token = ((current_pipe_tr_struct_ptr->G.TX_LENGTH << EHCI_QTD_LENGTH_BIT_POS) | data_toggle | pid_code | EHCI_QTD_STATUS_ACTIVE);

            /* Initialize the QTD for OUT data phase */            
          #if PSP_HAS_DATA_CACHE
              uncache_buff_ptr = USB_mem_alloc_uncached_zero(current_pipe_tr_struct_ptr->G.TX_LENGTH);
              if (!uncache_buff_ptr) {
                  printf("%s,%d USB memory allocate failed ...\n",__FUNCTION__,__LINE__);
                  return 0;
              }
              _mem_set_type(uncache_buff_ptr, MEM_TYPE_USB_HOST_DEVICE);
              USB_mem_copy(current_pipe_tr_struct_ptr->G.TX_BUFFER,
                           uncache_buff_ptr,
                           current_pipe_tr_struct_ptr->G.TX_LENGTH);
              _usb_ehci_init_QTD(handle, QTD_ptr, (uchar_ptr)uncache_buff_ptr,token);
              QTD_ptr->RESERVED[MEM_UNCACHE_INDEX] = (uint_32)uncache_buff_ptr;
              QTD_ptr->RESERVED[MEM_CACHE_INDEX] = (uint_32)(current_pipe_tr_struct_ptr->G.TX_BUFFER);
          #else
               _usb_ehci_init_QTD(handle, QTD_ptr, current_pipe_tr_struct_ptr->TX_BUFFER, token);
          #endif
            QTD_ptr->RESERVED[MEM_SIZE_INDEX] = current_pipe_tr_struct_ptr->G.TX_LENGTH;
            QTD_ptr->PIPE_DESCR_FOR_THIS_QTD = (pointer)pipe_descr_ptr;
            QTD_ptr->TR_FOR_THIS_QTD = (pointer)current_pipe_tr_struct_ptr;

            /* Use the QTD to chain the next QTD */         
            prev_QTD_ptr = QTD_ptr;

            /* Get a QTD from the queue for status phase */   
            EHCI_QTD_QGET(usb_host_ptr->QTD_HEAD, usb_host_ptr->QTD_TAIL, QTD_ptr);
   
            if (!QTD_ptr) {
               return USB_STATUS_TRANSFER_IN_PROGRESS;
            } /* Endif */
   
            usb_host_ptr->QTD_ENTRIES--;

            /* Chain the status phase QTD to the data phase QTD */         
            EHCI_MEM_WRITE(prev_QTD_ptr->NEXT_QTD_PTR,(uint_32)QTD_ptr);
         } /* Endif */
         /* Zero length IN */
         pid_code = EHCI_QTD_PID_IN;
      } else {
            
         if (current_pipe_tr_struct_ptr->G.RX_LENGTH) {
            pid_code = EHCI_QTD_PID_IN;
            token = ((current_pipe_tr_struct_ptr->G.RX_LENGTH << EHCI_QTD_LENGTH_BIT_POS) |
                data_toggle | pid_code | EHCI_QTD_STATUS_ACTIVE);
      
            /* Initialize the QTD for the IN data phase */         
          #if PSP_HAS_DATA_CACHE
              uncache_buff_ptr = USB_mem_alloc_uncached_zero(current_pipe_tr_struct_ptr->G.RX_LENGTH);
              if (!uncache_buff_ptr) {
                  printf("%s,%d USB memory allocate failed ...\n",__FUNCTION__,__LINE__);
                  return 0;
              }
              _mem_set_type(uncache_buff_ptr, MEM_TYPE_USB_HOST_DEVICE);
              _usb_ehci_init_QTD(handle, QTD_ptr, (uchar_ptr)uncache_buff_ptr,token);
              QTD_ptr->RESERVED[MEM_UNCACHE_INDEX] = (uint_32)uncache_buff_ptr;
              QTD_ptr->RESERVED[MEM_CACHE_INDEX] = (uint_32)(current_pipe_tr_struct_ptr->G.RX_BUFFER);
          #else
              _usb_ehci_init_QTD(handle, QTD_ptr, current_pipe_tr_struct_ptr->G.RX_BUFFER, token);
          #endif
            QTD_ptr->RESERVED[MEM_SIZE_INDEX] = current_pipe_tr_struct_ptr->G.RX_LENGTH;
            QTD_ptr->PIPE_DESCR_FOR_THIS_QTD = (pointer)pipe_descr_ptr;
            QTD_ptr->TR_FOR_THIS_QTD = (pointer)current_pipe_tr_struct_ptr;
            
            /* Use thie QTD to chain the next QTD */         
            prev_QTD_ptr = QTD_ptr;
               
            /* Get a QTD from the queue for status phase */
            EHCI_QTD_QGET(usb_host_ptr->QTD_HEAD, usb_host_ptr->QTD_TAIL, QTD_ptr);
   
            if (!QTD_ptr) {
               return USB_STATUS_TRANSFER_IN_PROGRESS;
            } /* Endif */
   
            usb_host_ptr->QTD_ENTRIES--;
            
            /* Chain the status phase QTD to the data phase QTD */         
            #if PSP_HAS_DATA_CACHE
                QTD_ptr->RESERVED[MEM_UNCACHE_INDEX] = 0x00;
                QTD_ptr->RESERVED[MEM_CACHE_INDEX] = 0x00;
            #endif
            QTD_ptr->RESERVED[MEM_SIZE_INDEX] = 0x00;
            EHCI_MEM_WRITE(prev_QTD_ptr->NEXT_QTD_PTR, (uint_32)QTD_ptr);
         } /* Endif */
         /* Zero-length OUT token */
         pid_code = EHCI_QTD_PID_OUT;
      } /* Endif */

      /* Already chained so add a qTD for status phase */
      /* Initialize the QTD for the status phase -- Zero length opposite 
      ** direction packet 
      */
      token = ((0 << EHCI_QTD_LENGTH_BIT_POS) |
            data_toggle | EHCI_QTD_IOC | pid_code | EHCI_QTD_STATUS_ACTIVE);
      _usb_ehci_init_QTD(handle, QTD_ptr, NULL, token);
      QTD_ptr->PIPE_DESCR_FOR_THIS_QTD = (pointer)pipe_descr_ptr;
      QTD_ptr->TR_FOR_THIS_QTD = (pointer)current_pipe_tr_struct_ptr;
   }
   else {
   
      /* Save the next data toggle based on the number of packets 
      ** for this transfer 
      */
      if (pipe_descr_ptr->G.DIRECTION) {
         total_length = current_pipe_tr_struct_ptr->G.TX_LENGTH;
         buff_ptr = current_pipe_tr_struct_ptr->G.TX_BUFFER;
         pid_code = EHCI_QTD_PID_OUT;
      } else {
         total_length = current_pipe_tr_struct_ptr->G.RX_LENGTH;
         buff_ptr = current_pipe_tr_struct_ptr->G.RX_BUFFER;
         pid_code = EHCI_QTD_PID_IN;
      } /* Endif */
   
      do {
      
#if USBCFG_EHCI_USE_SW_TOGGLING
         /* The data 0/1 for this pipe for next transaction */
         data_toggle = (uint_32)((pipe_descr_ptr->NEXTDATA01 << 
            EHCI_QTD_DATA_TOGGLE_BIT_POS));
#endif
         if (total_length > VUSB_EP_MAX_LENGTH_TRANSFER) {
            /* Split OUT transaction to more shorter transactions */
            token = ((VUSB_EP_MAX_LENGTH_TRANSFER  <<
               EHCI_QTD_LENGTH_BIT_POS) | data_toggle |
               pid_code | EHCI_QTD_DEFAULT_CERR_VALUE |
               EHCI_QTD_STATUS_ACTIVE);
            qtd_length = VUSB_EP_MAX_LENGTH_TRANSFER;
            total_length -= VUSB_EP_MAX_LENGTH_TRANSFER;
         } else {
            token = ((total_length << EHCI_QTD_LENGTH_BIT_POS) |
               data_toggle | EHCI_QTD_IOC | pid_code | 
               EHCI_QTD_DEFAULT_CERR_VALUE | EHCI_QTD_STATUS_ACTIVE);
            qtd_length = total_length;
            total_length = 0;
         } /* Endif */

#if USBCFG_EHCI_USE_SW_TOGGLING
         if (pipe_descr_ptr->DIRECTION) {
            /* for OUT transactions, compute DATA0 / DATA1 toggle bit */

            num_of_packets = 1 + (qtd_length - 1) / pipe_descr_ptr->MAX_PACKET_SIZE;
            
            pipe_descr_ptr->NEXTDATA01 ^= (num_of_packets & 0x1);
         }
         else
         {
            /* for IN transactions, the data toggle bit will be computed
               after transaction ends as we don't know how many packets
               will the device send.
            */
         }
#endif
         /* Initialize the QTD for the OUT data transaction */
         #if PSP_HAS_DATA_CACHE
             if( pipe_descr_ptr->G.PIPETYPE != USB_CONTROL_PIPE ) {
                 uncache_buff_ptr = USB_mem_alloc_uncached_zero(qtd_length);
                 if (!uncache_buff_ptr) {
                     printf("%s,%d USB memory allocate failed ...\n",__FUNCTION__,__LINE__);
                     return 0;
                 }
                 _mem_set_type(uncache_buff_ptr, MEM_TYPE_USB_HOST_DEVICE);
                 if (pipe_descr_ptr->G.DIRECTION) {
                     USB_mem_copy(buff_ptr,uncache_buff_ptr,qtd_length);
                 }
                 _usb_ehci_init_QTD(handle, QTD_ptr, uncache_buff_ptr, token);
                 QTD_ptr->RESERVED[MEM_UNCACHE_INDEX] = (uint_32)uncache_buff_ptr;
                 QTD_ptr->RESERVED[MEM_CACHE_INDEX] = (uint_32)(buff_ptr);
             } else {
                 _usb_ehci_init_QTD(handle, QTD_ptr, buff_ptr, token);
             }
         #else
             _usb_ehci_init_QTD(handle, QTD_ptr, buff_ptr, token);
         #endif
         QTD_ptr->RESERVED[MEM_SIZE_INDEX] = qtd_length;
         QTD_ptr->PIPE_DESCR_FOR_THIS_QTD = (pointer)pipe_descr_ptr;
         QTD_ptr->TR_FOR_THIS_QTD = (pointer)current_pipe_tr_struct_ptr;
         buff_ptr += qtd_length;
            
         if (total_length) {
         
            /* Use the QTD to chain the next QTD */         
            prev_QTD_ptr = QTD_ptr;

            /* Get a QTD from the queue for status phase */   
            EHCI_QTD_QGET(usb_host_ptr->QTD_HEAD, usb_host_ptr->QTD_TAIL, QTD_ptr);
   
            if (!QTD_ptr) {
               return USB_STATUS_TRANSFER_IN_PROGRESS;
            } /* Endif */
   
            usb_host_ptr->QTD_ENTRIES--;

            /* Chain the status phase QTD to the data phase QTD */         
            EHCI_MEM_WRITE(prev_QTD_ptr->NEXT_QTD_PTR,(uint_32) QTD_ptr);
         } /* Endif */
      } while (total_length); /* EndWhile */
   } /* Endif */
   
   return ((uint_32)first_QTD_ptr);
   
} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_add_xfer_to_asynch_schedule_list
*  Returned Value : USB Status
*  Comments       :
*        Queue the packet in the EHCI hardware Asynchronous schedule list
*END*-----------------------------------------------------------------*/
uint_32 _usb_ehci_add_xfer_to_asynch_schedule_list
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR             pipe_descr_ptr,
      
      /* [IN] the transfer parameters struct */
      EHCI_TR_STRUCT_PTR               current_pipe_tr_struct_ptr
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   EHCI_QH_STRUCT_PTR                           QH_ptr=NULL;
   EHCI_QH_STRUCT_PTR                           prev_QH_ptr=NULL;
   EHCI_QH_STRUCT_PTR                           first_QH_ptr;
   EHCI_QTD_STRUCT_PTR                          first_QTD_ptr, temp_QTD_ptr;
   EHCI_PIPE_STRUCT_PTR                         pipe_for_queue = NULL;
   ACTIVE_QH_MGMT_STRUCT_PTR                    active_list_member_ptr, temp_list_ptr;
   uint_32                                      cmd_val;
   boolean                                      init_async_list = FALSE;
   boolean                                      found_existing_q_head = FALSE;
   
   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->G.DEV_PTR;

   /* All Control and Bulk Transfers */
   /* First initialize all QTDs and then initialize the QHs */
   
   /* Initialize the QTDs for the Queue Head */
   first_QTD_ptr = (EHCI_QTD_STRUCT_PTR)_usb_ehci_init_Q_element(handle, 
      pipe_descr_ptr, current_pipe_tr_struct_ptr);

   current_pipe_tr_struct_ptr->SOFAR = 0; /* nothing was transferred yet */

   /* If the Asynch Schedule is disabled then initialize a new list */
   if ((!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD) & 
          EHCI_USBCMD_ASYNC_SCHED_ENABLE)) &&
       (!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS) & 
          EHCI_STS_ASYNCH_SCHEDULE)) || (!usb_host_ptr->ACTIVE_ASYNC_LIST_PTR)) {
      init_async_list = TRUE;
   } else {
      first_QH_ptr = QH_ptr = (EHCI_QH_STRUCT_PTR)
      ((uint_32)usb_host_ptr->ACTIVE_ASYNC_LIST_PTR->QH_PTR & 
         EHCI_QH_HORIZ_PHY_ADDRESS_MASK);

      while (QH_ptr) {
         pipe_for_queue = (EHCI_PIPE_STRUCT_PTR)QH_ptr->PIPE_DESCR_FOR_THIS_QH;

         if (pipe_for_queue == pipe_descr_ptr) {
            /* found an existing QHEAD for this endpoint */
            found_existing_q_head = TRUE;
            break;
         } else {
            prev_QH_ptr = QH_ptr;
            QH_ptr = (EHCI_QH_STRUCT_PTR)(EHCI_MEM_READ((uint_32)QH_ptr->HORIZ_LINK_PTR) & 
               EHCI_QH_HORIZ_PHY_ADDRESS_MASK);
            if (((uint_32)QH_ptr == (uint_32)first_QH_ptr)) {
               break;
            } /* Endif */
         } /* Endif */
      } /* Endwhile */
   } /* Endif */
   
   if (!found_existing_q_head) {

      active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) USB_mem_alloc_zero(sizeof(ACTIVE_QH_MGMT_STRUCT));
         
      if (!active_list_member_ptr) {
         return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
      } /* Endif */

      _mem_set_type((pointer)active_list_member_ptr, MEM_TYPE_USB_HOST_DEVICE);

      active_list_member_ptr->TIME = USBCFG_EHCI_PIPE_TIMEOUT;

      active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR = NULL;

      /* Get new QH from the free QH queue */
      EHCI_QH_QGET(usb_host_ptr->QH_HEAD, usb_host_ptr->QH_TAIL, QH_ptr);

      if (!QH_ptr) {
         USB_mem_free(active_list_member_ptr);
         return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
      } /* Endif */
      
      active_list_member_ptr->QH_PTR = (EHCI_QH_STRUCT_PTR)QH_ptr;

      usb_host_ptr->QH_ENTRIES--;

      /* printf("\nQH Get 0x%x, #entries=%d",QH_ptr,usb_host_ptr->QH_ENTRIES); */
      
      /* Not required, done by init Q head routine */
      /* pipe_descr_ptr->QH_FOR_THIS_PIPE = (pointer)QH_ptr; */

      if (init_async_list) {
         prev_QH_ptr = (EHCI_QH_STRUCT_PTR)QH_ptr;
         usb_host_ptr->ACTIVE_ASYNC_LIST_PTR = active_list_member_ptr;
      } else {
         temp_list_ptr = usb_host_ptr->ACTIVE_ASYNC_LIST_PTR;
         while (temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR) {
            temp_list_ptr = temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
         } /* EndWhile */
         temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR = active_list_member_ptr;
      } /* Endif */
      
      /* Initialize the Queue head */
      _usb_ehci_init_Q_HEAD(handle,pipe_descr_ptr,(EHCI_QH_STRUCT_PTR)QH_ptr, 
         (EHCI_QH_STRUCT_PTR)prev_QH_ptr, first_QTD_ptr);

      active_list_member_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR) first_QTD_ptr;

   } else {

      /* Get the pointer to the member of the active list */
      active_list_member_ptr = usb_host_ptr->ACTIVE_ASYNC_LIST_PTR;
      while ((active_list_member_ptr != NULL) && (active_list_member_ptr->QH_PTR != QH_ptr)) {
         active_list_member_ptr = active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
      } /* EndWhile */
      
      if (active_list_member_ptr == NULL) /* just for safe, should not occur */
         goto synchro_error;
      
      active_list_member_ptr->TIME = USBCFG_EHCI_PIPE_TIMEOUT;

      /* Disable Async Schedule. This is here because of accessing QH's overlay area.
      ** Se WARNING below.
      **/
      EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_USBCMD_ASYNC_SCHED_ENABLE);
      while (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS) & EHCI_STS_ASYNCH_SCHEDULE)
      {
      /* Wait To stop Async Schedule */
      }

      temp_QTD_ptr = (EHCI_QTD_STRUCT_PTR) active_list_member_ptr->FIRST_QTD_PTR;
      if (!((uint_32) temp_QTD_ptr & EHCI_QH_HORIZ_PHY_ADDRESS_MASK)) {
         active_list_member_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR) first_QTD_ptr;
      } else {
         /* Link the qTD to the end of queue */
         while (!(EHCI_MEM_READ(temp_QTD_ptr->NEXT_QTD_PTR) & EHCI_QTD_T_BIT)) {
            temp_QTD_ptr = (EHCI_QTD_STRUCT_PTR)(EHCI_MEM_READ(temp_QTD_ptr->NEXT_QTD_PTR) & ~EHCI_QTD_T_BIT);
         } /* EndWhile */
         EHCI_MEM_WRITE(temp_QTD_ptr->NEXT_QTD_PTR,(uint_32)first_QTD_ptr);
      } /* Endif */

      /* Don't forget to link active_list_member with new qTD list on QH */
      /* Queue head is already on the active list. Simply queue the transfer */
      /* Queue transfer onto relevant queue head */
      if (EHCI_MEM_READ(QH_ptr->NEXT_QTD_LINK_PTR) & EHCI_QTD_T_BIT) {
         volatile _mqx_uint dummy_value;
         /* No alternate descriptor */
         EHCI_MEM_SET_BITS(QH_ptr->ALT_NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
         /* WARNING! If this happens during overlay save, then we can lose information!
         ** SOLUTION: disable async schedule so this will not happen
         */
         EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,(uint_32)first_QTD_ptr);
      }

   } /* Endif */

    
   if (init_async_list) {
      /* Write the QH address to the Current Async List Address */
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.CURR_ASYNC_LIST_ADDR,(uint_32)QH_ptr);
   } /* Endif */

   /* Enable the Asynchronous schedule */
   EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_USBCMD_ASYNC_SCHED_ENABLE);

   return USB_OK;

synchro_error:
   return USB_log_error(__FILE__,__LINE__,USBERR_BAD_STATUS);
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_process_port_change
*  Returned Value : None
*  Comments       :
*        Process port change
*END*-----------------------------------------------------------------*/

boolean _usb_ehci_process_port_change
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR      usb_host_ptr;
   VUSB20_REG_STRUCT_PTR               dev_ptr;
   VUSB20_REG_STRUCT_PTR               cap_dev_ptr;
   uint_8                              i, total_port_numbers;
   uint_32                             port_control, status;
   USB_EHCI_HOST_INIT_STRUCT_PTR       param;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   
   param = (USB_EHCI_HOST_INIT_STRUCT_PTR) usb_host_ptr->G.INIT_PARAM;

   cap_dev_ptr = (VUSB20_REG_STRUCT_PTR) param->CAP_BASE_PTR;

   dev_ptr = usb_host_ptr->G.DEV_PTR;

   total_port_numbers = 
   (uint_8)(EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.HCS_PARAMS) & 
      EHCI_HCS_PARAMS_N_PORTS);
      

   for (i = 0; i < total_port_numbers; i++) {
      port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);

      if (port_control & EHCI_PORTSCX_CONNECT_STATUS_CHANGE) {
         /* Turn on the 125 usec uframe interrupt. This effectively 
         ** starts the timer to count 125 usecs 
         */
         EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR, EHCI_INTR_SOF_UFRAME_EN);
         do {
            if (port_control & EHCI_PORTSCX_CONNECT_STATUS_CHANGE) {
               usb_host_ptr->UFRAME_COUNT = 0;
               port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);
               port_control &= ~EHCI_PORTSCX_W1C_BITS;
               port_control |= EHCI_PORTSCX_CONNECT_STATUS_CHANGE;
               EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i],port_control);
            } /* Endif */
            status = (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS) & 
                      EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR));
            if (status & EHCI_STS_SOF_COUNT) {
               /* Increment the 125 usecs count */
               usb_host_ptr->UFRAME_COUNT++;
               EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS,status);
            } /* Endif */
            port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);
         } while (usb_host_ptr->UFRAME_COUNT != 2);
         /* Turn off the 125 usec uframe interrupt. This effectively 
         ** stops the timer to count 125 usecs 
         */
         EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR, EHCI_INTR_SOF_UFRAME_EN);

         port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);

         usb_host_ptr->UFRAME_COUNT = 0;

         /* We waited to check for stable current connect status */         
         if (port_control & EHCI_PORTSCX_CURRENT_CONNECT_STATUS) {
            /* Attach on port i */
            /* send change report to the hub-driver */
            /* The hub driver does GetPortStatus and identifies the new connect */
            /* usb_host_ptr->ROOT_HUB_DRIVER(handle, hub_num, GET_PORT_STATUS); */
            /* reset and enable the port */
            _usb_ehci_reset_and_enable_port(handle, i);
#if PSP_MQX_CPU_IS_VYBRID
            /*enable HS disconnect detection */
            port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);
            if(port_control & EHCI_PORTSCX_PORT_HIGH_SPEED) {
                _bsp_usb_hs_disconnect_detection_enable(usb_host_ptr);
            }
#endif
         } else {
            /* Detach on port i */
            /* send change report to the hub-driver */
            /* usb_host_ptr->ROOT_HUB_DRIVER(handle, hub_num, GET_PORT_STATUS); */

#if PSP_MQX_CPU_IS_VYBRID
            /* disable HS disconnect detection */
            _bsp_usb_hs_disconnect_detection_disable(usb_host_ptr);
#endif
            /* clear the connect status change */
            port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);
            port_control &= ~EHCI_PORTSCX_W1C_BITS;
            port_control |= EHCI_PORTSCX_CONNECT_STATUS_CHANGE;
            EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i],port_control);

            /* Disable the asynch and periodic schedules */
            EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,(EHCI_USBCMD_ASYNC_SCHED_ENABLE | EHCI_USBCMD_PERIODIC_SCHED_ENABLE));

            if ((_usb_host_check_service((pointer)usb_host_ptr, 
               USB_SERVICE_DETACH, 0)) == USB_OK) 
            {
               _usb_host_call_service(usb_host_ptr, USB_SERVICE_DETACH, 0);
            } else {
               /* call device detach (host pointer, speed, hub #, port #) */
               usb_dev_list_detach_device((pointer)usb_host_ptr, 0, (uint_8)((i + 1)));
            } /* Endif */ 
         
            if (!i) {
               return TRUE;
            } /* Endif */
         } /* Endif */
      } /* Endif */
      
      if (port_control & EHCI_PORTSCX_PORT_FORCE_RESUME) {
         port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);
         port_control &= ~EHCI_PORTSCX_W1C_BITS;
         port_control &= ~EHCI_PORTSCX_PORT_FORCE_RESUME;
         _usb_host_call_service((pointer)usb_host_ptr, USB_SERVICE_HOST_RESUME, 0);
      } /* Endif */
      
      if ((usb_host_ptr->IS_RESETTING != FALSE) && 
         (port_control & EHCI_PORTSCX_PORT_ENABLE))
      {
         usb_host_ptr->IS_RESETTING = FALSE;

         /* reset process complete */
         /* Report the change to the hub driver and enumerate */
         usb_host_ptr->G.SPEED = ((port_control & VUSBHS_SPEED_MASK) >> VUSBHS_SPEED_BIT_POS);
         //usb_host_ptr->SPEED = USB_SPEED_HIGH;
         usb_host_ptr->PORT_NUM = (uint_32)(i + 1);
         
         /* Now wait for reset recovery */
         usb_host_ptr->RESET_RECOVERY_TIMER = (USB_RESET_RECOVERY_DELAY*8);

         /* Turn on the 125 usec uframe interrupt. This effectively 
         ** starts the timer to count 125 usecs 
         */
         EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR, EHCI_INTR_SOF_UFRAME_EN);
      } /* Endif */
      
   } /* Endfor */

   return FALSE;

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_reset_and_enable_port
*  Returned Value : None
*  Comments       :
*        Reset and enabled the port
*END*-----------------------------------------------------------------*/

void _usb_ehci_reset_and_enable_port
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle,

      /* [IN] the port number */
      uint_8                  port_number
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR       usb_host_ptr;
   VUSB20_REG_STRUCT_PTR               dev_ptr;
   uint_32                             port_status_control;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr      = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->G.DEV_PTR;

   /* Check the line status bit in the PORTSC register */
   port_status_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[port_number]);

   port_status_control &= ~EHCI_PORTSCX_W1C_BITS;

   /* reset should wait for 100 Ms debouce period before starting*/
#ifdef __USB_OTG__
   if ((usb_otg_state_struct_ptr->STATE_STRUCT_PTR->STATE != A_SUSPEND) &&  
      (usb_otg_state_struct_ptr->STATE_STRUCT_PTR->STATE != B_WAIT_ACON))
#endif

   {
      _mqx_int i;
      
      for (i = 0; i < USB_DEBOUNCE_DELAY; i++) {
         _usb_host_delay(handle, 1);    //wait 1 msec
         
         /* Check the line status bit in the PORTSC register */
         if (!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[port_number]) & EHCI_PORTSCX_CURRENT_CONNECT_STATUS))
            break;
      } /* Endfor */
   }

   usb_host_ptr->IS_RESETTING = TRUE;
   
   /*
   ** Start the reset process
   */
   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[port_number] ,(port_status_control | EHCI_PORTSCX_PORT_RESET));

   /* Wait for Reset complete */
   do
   {
       port_status_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[port_number]);
   } while (port_status_control & EHCI_PORTSCX_PORT_RESET);
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_process_reset_recovery_done
*  Returned Value : None
*  Comments       :
*        Reset and enabled the port
*END*-----------------------------------------------------------------*/

void _usb_host_process_reset_recovery_done
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR      usb_host_ptr;
   VUSB20_REG_STRUCT_PTR               dev_ptr;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->G.DEV_PTR;

   /* call device attach (host pointer, speed, hub #, port #) */
   if ((_usb_host_check_service((pointer)usb_host_ptr, 
      USB_SERVICE_ATTACH, usb_host_ptr->G.SPEED)) == USB_OK) 
   {
      _usb_host_call_service(usb_host_ptr, USB_SERVICE_ATTACH, usb_host_ptr->G.SPEED);
   } else {
      usb_dev_list_attach_device((pointer)usb_host_ptr, 
         (uint_8)(usb_host_ptr->G.SPEED), 0, (uint_8)(usb_host_ptr->PORT_NUM));
   } /* Endif */ 
   /* Turn off the 125 usec uframe interrupt. This effectively 
   ** stops the timer to count 125 usecs 
   */
   EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR, EHCI_INTR_SOF_UFRAME_EN);
} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_isr
*  Returned Value : None
*  Comments       :
*        Service all the interrupts in the VUSB1.1 hardware
*END*-----------------------------------------------------------------*/

void _usb_ehci_isr
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR      usb_host_ptr;
   VUSB20_REG_STRUCT_PTR               dev_ptr;
   uint_32                             status;
   
   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;

   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->G.DEV_PTR;

   /* We use a while loop to process all the interrupts while we are in the 
   ** loop so that we don't miss any interrupts 
   */
   while (TRUE) {

      /* Check if any of the enabled interrupts are asserted */
      status = (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS) & 
                EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR));
         
      if (!status) {
         /* No more interrupts pending to be serviced */
         break;
      } /* Endif */

      /* Clear all enabled interrupts */
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS,status);

      if (status & EHCI_STS_SOF_COUNT) {
         /* Waiting for an interval of 10 ms for reset recovery */
         if (usb_host_ptr->RESET_RECOVERY_TIMER) {
            usb_host_ptr->RESET_RECOVERY_TIMER--;
            if (!usb_host_ptr->RESET_RECOVERY_TIMER) {
               _usb_host_process_reset_recovery_done((pointer)usb_host_ptr);
            } /* Endif */
         } /* Endif */
      } /* Endif */

      if (status & EHCI_STS_ASYNCH_ADVANCE) {
         /* Process the asynch advance */
      } /* Endif */

      if (status & EHCI_STS_HOST_SYS_ERROR) {
         /* Host system error. Controller halted. Inform the upper layers */
         _usb_host_call_service((pointer)usb_host_ptr, USB_SERVICE_SYSTEM_ERROR, 0);
      } /* Endif */

      if (status & EHCI_STS_FRAME_LIST_ROLLOVER) {
         /* Process frame list rollover */
      } /* Endif */

      if (status & EHCI_STS_RECLAIMATION) {
         /* Process reclaimation */
      } /* Endif */
      
      if (status & EHCI_STS_NAK) {
         _usb_ehci_process_tr_complete((pointer)usb_host_ptr);
      }

      if (status & EHCI_STS_PORT_CHANGE) {
         /* Process the port change detect */
         if (_usb_ehci_process_port_change((pointer)usb_host_ptr)) {
            /* There was a detach on port 0 so we should return */
            return;
         } /* Endif */
         /* Should return if there was a detach on OTG port */
      } /* Endif */

      if (status & (EHCI_STS_USB_INTERRUPT | EHCI_STS_USB_ERROR)) {
         /* Process the USB transaction completion and transaction error 
         ** interrupt 
         */
         _usb_ehci_process_tr_complete((pointer)usb_host_ptr);
         #ifdef DEBUG_INFO
            printf("TR completed\n");
         #endif

      } /* Endif */
      
      if (status & EHCI_STS_TIMER0) {
         _usb_ehci_process_timer((pointer)usb_host_ptr);
      }

   } /* EndWhile */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_preinit
*  Returned Value : error or USB_OK
*  Comments       :
*        Allocate the structures for EHCI
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_ehci_preinit(_usb_host_handle *handle) {
    USB_EHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR) USB_mem_alloc_zero(sizeof(USB_EHCI_HOST_STATE_STRUCT));
    EHCI_PIPE_STRUCT_PTR p, pp;
    int i;

    if (NULL != usb_host_ptr) {
        /* Allocate the USB Host Pipe Descriptors */
        usb_host_ptr->G.PIPE_DESCRIPTOR_BASE_PTR = (PIPE_STRUCT_PTR)USB_mem_alloc(sizeof(EHCI_PIPE_STRUCT) * USBCFG_MAX_PIPES);
        if (usb_host_ptr->G.PIPE_DESCRIPTOR_BASE_PTR == NULL) {
            USB_mem_free(usb_host_ptr);

            return USBERR_ALLOC;
        }
        USB_mem_zero(usb_host_ptr->G.PIPE_DESCRIPTOR_BASE_PTR, sizeof(EHCI_PIPE_STRUCT) * USBCFG_MAX_PIPES);

        p = (EHCI_PIPE_STRUCT_PTR) usb_host_ptr->G.PIPE_DESCRIPTOR_BASE_PTR;
        pp = NULL;
        for (i = 0; i < USBCFG_MAX_PIPES; i++) {
           if (pp != NULL) {
              pp->G.NEXT = (PIPE_STRUCT_PTR) p;
           }
           pp = p;
           p++;
        }

        usb_host_ptr->G.PIPE_SIZE = sizeof(EHCI_PIPE_STRUCT);
        usb_host_ptr->G.TR_SIZE = sizeof(EHCI_TR_STRUCT);

    } /* Endif */
    
    *handle = (_usb_host_handle) usb_host_ptr;
    return USB_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_init
*  Returned Value : error or USB_OK
*  Comments       :
*        Initialize the VUSB_HS controller
*END*-----------------------------------------------------------------*/

USB_STATUS  _usb_ehci_init
   (
      /* the USB Host State structure */
      _usb_host_handle     handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   USB_EHCI_HOST_INIT_STRUCT_PTR                param;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   VUSB20_REG_STRUCT_PTR                        cap_dev_ptr;
   VUSB20_REG_STRUCT_PTR                        timer_dev_ptr;
   EHCI_QH_STRUCT_PTR                           QH_ptr;
   EHCI_QTD_STRUCT_PTR                          QTD_ptr;   
   uint_8                                       vector;
   uint_32                                      i, frame_list_size_bits;
#ifndef __USB_OTG__
   uint_32                                      port_control[16];
   uint_8                                       portn = 0;
#endif
   uint_32_ptr                                  temp_periodic_list_ptr = NULL;
   pointer                                      total_mem_ptr = NULL;
   uint_32                                      total_non_periodic_memory = 0;
   pointer                                      non_periodic_mem_ptr = NULL;
   uint_32                                      total_periodic_memory = 0;
   pointer                                      periodic_mem_ptr = NULL;
   uint_32                                      endian;
   
   #if USBCFG_MEMORY_ENDIANNESS == MQX_LITTLE_ENDIAN
      endian = 0;
   #else
      endian = VUSBHS_MODE_BIG_ENDIAN;
   #endif  

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   param = (USB_EHCI_HOST_INIT_STRUCT_PTR) usb_host_ptr->G.INIT_PARAM;

   if (param == NULL)
       return USBERR_INIT_DATA;
   
   cap_dev_ptr  = (VUSB20_REG_STRUCT_PTR) param->CAP_BASE_PTR;

   timer_dev_ptr = (VUSB20_REG_STRUCT_PTR) param->TIMER_BASE_PTR;

   /* Get the base address of the VUSB_HS registers */
   usb_host_ptr->G.DEV_PTR = (pointer) ((uint_32)cap_dev_ptr + 
                                      (EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.CAPLENGTH_HCIVER) & 
                                       EHCI_CAP_LEN_MASK));

#ifndef __USB_OTG__
   switch (param->SPEED) {
      case BSP_EHCI_HS:
         usb_host_ptr->G.SPEED = USB_SPEED_HIGH;
         break;
      case BSP_EHCI_FS:
      default:
         usb_host_ptr->G.SPEED = USB_SPEED_FULL;
         break;
   }
#endif

   dev_ptr = usb_host_ptr->G.DEV_PTR;

   /* Stop the controller */
   EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_CMD_RUN_STOP);

   /* Configure the VUSBHS has a host controller */
   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_MODE,VUSBHS_MODE_CTRL_MODE_HOST);
   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_MODE,VUSBHS_MODE_CTRL_MODE_HOST | endian);

   /* Stop the controller */
   EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_CMD_RUN_STOP);
   
   /* Get the interrupt vector number for the VUSB_HS host */
   vector = param->VECTOR;

   portn = EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.HCS_PARAMS) & 0x0000000f;
   for (i = 0; i < portn; i++) 
   {
       port_control[i] = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);
   }
#ifndef __USB_OTG__

   if (!(USB_install_isr(vector, _usb_ehci_isr, (pointer)usb_host_ptr))) {
      return USB_log_error(__FILE__,__LINE__,USBERR_INSTALL_ISR);
   } /* Endbody */

#endif /* __USB_OTG__ */

   while (!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS) & EHCI_STS_HC_HALTED)) {
      /* Wait for the controller to stop */
   }
   
   /* Reset the controller to get default values */
   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_CMD_CTRL_RESET);

   while (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD) & EHCI_CMD_CTRL_RESET) {
      /* Wait for the controller reset to complete */
   } /* EndWhile */

   /* Configure the VUSBHS has a host controller */
   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_MODE,VUSBHS_MODE_CTRL_MODE_HOST | endian);

   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.CTRLDSSEGMENT,0);

   /*******************************************************************
    Set the size of frame list in CMD register
   *******************************************************************/
   if (param->FRAME_LIST_SIZE > 512)
   {
       usb_host_ptr->FRAME_LIST_SIZE = 1024;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_1024;
   }
   else if (param->FRAME_LIST_SIZE > 256)
   {
       usb_host_ptr->FRAME_LIST_SIZE = 512;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_512;
   }
   else if (param->FRAME_LIST_SIZE > 128)
   {
       usb_host_ptr->FRAME_LIST_SIZE = 256;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_256;
   }
   else if (param->FRAME_LIST_SIZE > 64)
   {
       usb_host_ptr->FRAME_LIST_SIZE = 128;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_128;
   }
   else if (param->FRAME_LIST_SIZE > 32)
   {
       usb_host_ptr->FRAME_LIST_SIZE = 64;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_64;
   }
   else if (param->FRAME_LIST_SIZE > 16)
   {
       usb_host_ptr->FRAME_LIST_SIZE = 32;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_32;
   }
   else if (param->FRAME_LIST_SIZE > 8)
   {
       usb_host_ptr->FRAME_LIST_SIZE = 16;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_16;
   }
   else if (param->FRAME_LIST_SIZE > 0)
   {
       usb_host_ptr->FRAME_LIST_SIZE = 8;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_8;
   }
   else
   {
       usb_host_ptr->FRAME_LIST_SIZE = 1024;
       frame_list_size_bits = EHCI_CMD_FRAME_SIZE_1024;
   }

   /*
   **   ALL CONTROLLER DRIVER MEMORY NEEDS are allocated here.
   */
   
   total_non_periodic_memory += (USBCFG_EHCI_MAX_QH_DESCRS * sizeof(EHCI_QH_STRUCT)) + 32;
   total_non_periodic_memory += (USBCFG_EHCI_MAX_QTD_DESCRS * sizeof(EHCI_QTD_STRUCT)) + 32;
   
   /* allocate space for uframe list bandwidth computation */
   total_periodic_memory += usb_host_ptr->FRAME_LIST_SIZE * 8 * sizeof(uint_8);
   total_periodic_memory += (sizeof(EHCI_FRAME_LIST_ELEMENT_POINTER)) * usb_host_ptr->FRAME_LIST_SIZE + 4096;
   
   /*memory required by high-speed Iso transfers */
   total_periodic_memory += (USBCFG_EHCI_MAX_ITD_DESCRS * sizeof(EHCI_ITD_STRUCT)) + 32;
   total_periodic_memory +=  sizeof(LIST_NODE_STRUCT) * USBCFG_EHCI_MAX_ITD_DESCRS;
   /*memory required by full-speed Iso transfers */   
   total_periodic_memory +=  (USBCFG_EHCI_MAX_SITD_DESCRS * sizeof(EHCI_SITD_STRUCT)) + 32;
   total_periodic_memory +=  sizeof(LIST_NODE_STRUCT) * USBCFG_EHCI_MAX_SITD_DESCRS;
   
   non_periodic_mem_ptr = USB_mem_alloc_uncached(total_non_periodic_memory);
   if (!non_periodic_mem_ptr) 
   {
      return (uint_8) USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
   }

   USB_mem_zero(non_periodic_mem_ptr, total_non_periodic_memory);
#if PSP_HAS_DATA_CACHE
   /* memzero the whole memory */
   USB_dcache_flush_mlines(non_periodic_mem_ptr, total_non_periodic_memory);
#endif
       
   /* store the memory block pointer in device handle */
   usb_host_ptr->CONTROLLER_MEMORY = non_periodic_mem_ptr;
   
   periodic_mem_ptr = USB_mem_alloc_uncached(total_periodic_memory);
   if (!periodic_mem_ptr)
   {
      return (uint_8) USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
   }

   USB_mem_zero(periodic_mem_ptr, total_periodic_memory);
#if PSP_HAS_DATA_CACHE
   /* memzero the whole memory */
   USB_dcache_flush_mlines(periodic_mem_ptr, total_periodic_memory);
#endif
       
   /*
   **   NON-PERIODIC MEMORY DISTRIBUTION STUFF
   */

   usb_host_ptr->ASYNC_LIST_BASE_ADDR = usb_host_ptr->QH_BASE_PTR =
   (pointer) non_periodic_mem_ptr;

   usb_host_ptr->ALIGNED_ASYNCLIST_ADDR = usb_host_ptr->QH_ALIGNED_BASE_PTR =
      (pointer)USB_MEM32_ALIGN((uint_32)usb_host_ptr->ASYNC_LIST_BASE_ADDR);

   non_periodic_mem_ptr =  (uint_8_ptr) non_periodic_mem_ptr + 
                           (USBCFG_EHCI_MAX_QH_DESCRS * sizeof(EHCI_QH_STRUCT)) + 32;
   usb_host_ptr->QTD_BASE_PTR = (EHCI_QTD_STRUCT_PTR) non_periodic_mem_ptr;

   /* Align the QTD base to 32 byte boundary */   
   usb_host_ptr->QTD_ALIGNED_BASE_PTR = (EHCI_QTD_STRUCT_PTR) 
               USB_MEM32_ALIGN((uint_32)usb_host_ptr->QTD_BASE_PTR);

   non_periodic_mem_ptr =  (uint_8_ptr) non_periodic_mem_ptr + 
   (USBCFG_EHCI_MAX_QTD_DESCRS * sizeof(EHCI_QTD_STRUCT)) + 32;
                                             
   QH_ptr = usb_host_ptr->QH_ALIGNED_BASE_PTR;

   for (i = 0; i < USBCFG_EHCI_MAX_QH_DESCRS; i++) {
      /* Set the dTD to be invalid */
      EHCI_MEM_WRITE(QH_ptr->HORIZ_LINK_PTR,EHCI_QUEUE_HEAD_POINTER_T_BIT);
      _usb_ehci_free_QH((pointer)usb_host_ptr, (pointer)QH_ptr);
      QH_ptr++;
   } /* Endfor */
   
   QTD_ptr = usb_host_ptr->QTD_ALIGNED_BASE_PTR;

   /* Enqueue all the QTDs */   
   for (i = 0; i < USBCFG_EHCI_MAX_QTD_DESCRS; i++) {
      /* Set the QTD to be invalid */
      EHCI_MEM_WRITE(QTD_ptr->NEXT_QTD_PTR,EHCI_QTD_T_BIT);
      _usb_ehci_free_QTD((pointer)usb_host_ptr, (pointer)QTD_ptr);
      QTD_ptr++;
   } /* Endfor */
   

   
   /*
   **   BANDWIDTH MEMORY DISTRIBUTION STUFF
   */

   /*********************************************************************
   Allocating the memory to store periodic bandwidth. A periodic BW list
   is a two dimensional array with dimension (frame list size x 8 u frames).
   
   Also note that the following could be a large allocation of memory
   The max value stored in a location will be 125 micro seconds and so we
   use uint_8
   *********************************************************************/
   
   usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR = (uint_8_ptr) periodic_mem_ptr;
   periodic_mem_ptr = (uint_8_ptr) periodic_mem_ptr + 
         usb_host_ptr->FRAME_LIST_SIZE * 8 * sizeof(uint_8);
  
   USB_mem_zero(usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR,
                   usb_host_ptr->FRAME_LIST_SIZE *  \
                   8 *            \
                   sizeof(uint_8)  \
                   );

   
   usb_host_ptr->PERIODIC_LIST_BASE_ADDR = periodic_mem_ptr;
   periodic_mem_ptr = (uint_8_ptr) periodic_mem_ptr + 
                      (sizeof(EHCI_FRAME_LIST_ELEMENT_POINTER)) * 
                        usb_host_ptr->FRAME_LIST_SIZE + 4096;
   usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR = 
      (pointer)USB_MEM4096_ALIGN((uint_32) usb_host_ptr->PERIODIC_LIST_BASE_ADDR);

    /*make sure that periodic list is uninitialized */   
    usb_host_ptr->PERIODIC_LIST_INITIALIZED = FALSE;  
     
    /* Initialize the list of active structures to NULL initially */
    usb_host_ptr->ACTIVE_ASYNC_LIST_PTR = NULL;
    usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR = NULL;
    
                   
   /*
   **  HIGH SPEED ISO TRANSFERS MEMORY ALLOCATION STUFF
   */
                           
   usb_host_ptr->ITD_BASE_PTR = (EHCI_ITD_STRUCT_PTR) periodic_mem_ptr;
   periodic_mem_ptr = (uint_8_ptr) periodic_mem_ptr + 
                      (USBCFG_EHCI_MAX_ITD_DESCRS * sizeof(EHCI_ITD_STRUCT)) + 32;
                         
   
   /* Align the ITD base to 32 byte boundary */   
   usb_host_ptr->ITD_ALIGNED_BASE_PTR = (EHCI_ITD_STRUCT_PTR)
      USB_MEM32_ALIGN((uint_32) usb_host_ptr->ITD_BASE_PTR);
      
      
   usb_host_ptr->ITD_LIST_INITIALIZED = FALSE;
                           
   /*****************************************************************************
     ITD QUEUING PREPARATION 
   *****************************************************************************/
   
   /* memory for doubly link list of nodes that keep active ITDs. Head and Tail point to
   same place when list is empty */
   usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR = periodic_mem_ptr;
   usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_TAIL_PTR = periodic_mem_ptr;
   USB_mem_zero(usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR,
                   sizeof(LIST_NODE_STRUCT) * USBCFG_EHCI_MAX_ITD_DESCRS);
                    
   periodic_mem_ptr = (uint_8_ptr) periodic_mem_ptr + 
                      sizeof(LIST_NODE_STRUCT) * USBCFG_EHCI_MAX_ITD_DESCRS;
   
   
   /*
   **   FULL SPEED ISO TRANSFERS MEMORY ALLOCATION STUFF
   */

   /* Allocate the Split-transactions Isochronous Transfer Descriptors: 
   ** 32 bytes aligned 
   */
   usb_host_ptr->SITD_BASE_PTR = (EHCI_SITD_STRUCT_PTR) periodic_mem_ptr;
   periodic_mem_ptr = (uint_8_ptr) periodic_mem_ptr + 
                      (USBCFG_EHCI_MAX_SITD_DESCRS * sizeof(EHCI_SITD_STRUCT)) + 32;  

   
   /* Align the SITD base to 32 byte boundary */   
   usb_host_ptr->SITD_ALIGNED_BASE_PTR = (EHCI_SITD_STRUCT_PTR)
      USB_MEM32_ALIGN((uint_32)usb_host_ptr->SITD_BASE_PTR);

   usb_host_ptr->SITD_LIST_INITIALIZED = FALSE;
   
   /*****************************************************************************
     SITD QUEUING PREPARATION 
   *****************************************************************************/
   
   /* memory for doubly link list of nodes that keep active SITDs. Head and Tail point to
   same place when list is empty */
   usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR = periodic_mem_ptr;
   usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_TAIL_PTR = periodic_mem_ptr;
   
   USB_mem_zero(usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR,
                   sizeof(LIST_NODE_STRUCT) * USBCFG_EHCI_MAX_SITD_DESCRS);

   periodic_mem_ptr = (uint_8_ptr) periodic_mem_ptr + 
                      sizeof(LIST_NODE_STRUCT) * USBCFG_EHCI_MAX_SITD_DESCRS;
   
   /*
   ** HARDWARE  REGISTERS INITIALIZATION STUFF
   */
   
   
   /* 4-Gigabyte segment where all of the  interface data structures are allocated. */
   /* If no 64-bit addressing capability then this is zero */
   if ((EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.HCC_PARAMS) & 
        EHCI_HCC_PARAMS_64_BIT_ADDR_CAP)) {
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.CTRLDSSEGMENT,0);
   } else {
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.CTRLDSSEGMENT,EHCI_DATA_STRUCTURE_BASE_ADDRESS);
   } /* Endif */

#ifndef __USB_OTG__
   if (EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.HCS_PARAMS) & 
       VUSB20_HCS_PARAMS_PORT_POWER_CONTROL_FLAG) {
       for (i = 0; i < portn; i++) 
       {
           port_control[i] &= ~EHCI_PORTSCX_W1C_BITS; //Do not accidentally clear w1c bits by writing 1 back
           if (usb_host_ptr->G.SPEED == USB_SPEED_FULL) {
               EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i],port_control[i] | EHCI_PORTSCX_PORT_POWER | VUSBHS_PORTSCX_PORT_PFSC);
           }
           else { //usb_host_ptr->G.SPEED == USB_SPEED_HIGH
               EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i],port_control[i] | EHCI_PORTSCX_PORT_POWER);
           }
       }
  } /* Endif */
#endif
      
   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR,VUSB20_HOST_INTR_EN_BITS);

   if (EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.HCC_PARAMS) & 
       EHCI_HCC_PARAMS_PGM_FRM_LIST_FLAG) {
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,(EHCI_INTR_NO_THRESHOLD_IMMEDIATE | frame_list_size_bits | EHCI_CMD_RUN_STOP));

   } else {
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,(EHCI_INTR_NO_THRESHOLD_IMMEDIATE | EHCI_CMD_RUN_STOP));
   } /* Endif */

   /* route all ports to the EHCI controller */
   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.CONFIG_FLAG,1);

   /* The GPTIMER was disabled. The idea was to use GPTIMER to cancel some transfers that were pending for data.
   ** Since the conception is not right, it was removed, but the code still remains here commented here
   ** for developer to persist backward compatibility. NOTE: GPTimer is not included in the EHCI standard.
   if (timer_dev_ptr) {
      EHCI_REG_WRITE(timer_dev_ptr->REGISTERS.TIMER_REGISTERS.GPTIMER0LD, 10000 - 1);
      EHCI_REG_WRITE(timer_dev_ptr->REGISTERS.TIMER_REGISTERS.GPTIMER0CTL, EHCIFSL_GTCTL_GPTIMER_REPEAT | EHCIFSL_GTCTL_GPTIMER_RESET | EHCIFSL_GTCTL_GPTIMER_RUN);
   }
   
   EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR,EHCI_INTR_TIMER0);
   */
   
   return USB_OK;
   
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_free_QTD
*  Returned Value : void
*  Comments       :
*        Enqueues an QTD onto the free QTD ring.
*
*END*-----------------------------------------------------------------*/

void _usb_ehci_free_QTD
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle,
      
      /* [IN] the QTD to enqueue */
      pointer                 QTD_ptr
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR              usb_host_ptr;
   
   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   USB_lock();

   EHCI_MEM_WRITE(((EHCI_QTD_STRUCT_PTR)QTD_ptr)->NEXT_QTD_PTR,EHCI_QTD_T_BIT);

   /*
   ** Add the QTD to the free QTD queue and increment the tail to the next descriptor
   */
   EHCI_QTD_QADD(usb_host_ptr->QTD_HEAD, usb_host_ptr->QTD_TAIL, 
      (EHCI_QTD_STRUCT_PTR)QTD_ptr);
   usb_host_ptr->QTD_ENTRIES++;
   
   USB_unlock();

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_free_QH
*  Returned Value : void
*  Comments       :
*        Enqueues a QH onto the free QH ring.
*
*END*-----------------------------------------------------------------*/

void _usb_ehci_free_QH
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle,
      
      /* [IN] the QH to enqueue */
      pointer                 QH_ptr
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR                    usb_host_ptr;
   
   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   USB_lock();

   /*
   ** Add the QH to the free QH queue and increment the tail to the next descriptor
   */

   EHCI_QH_QADD(usb_host_ptr->QH_HEAD, usb_host_ptr->QH_TAIL,
      (EHCI_QH_STRUCT_PTR) QH_ptr);
   usb_host_ptr->QH_ENTRIES++;
   
   // printf("\nQH Add 0x%x, #entries=%d",QH_ptr,usb_host_ptr->QH_ENTRIES);

   USB_unlock();

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_free_resources
*  Returned Value : none
*  Comments       :
*        Frees the controller specific resources for a given pipe
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_ehci_free_resources
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* The pipe descriptor to queue */            
      PIPE_STRUCT_PTR                  pipe_ptr
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   ACTIVE_QH_MGMT_STRUCT_PTR                    active_list_member_ptr;
   ACTIVE_QH_MGMT_STRUCT_PTR                    prev_ptr = NULL, next_ptr = NULL;
   EHCI_QH_STRUCT_PTR                           QH_ptr, temp_QH_ptr;
   EHCI_PIPE_STRUCT_PTR                         pipe_descr_ptr = (EHCI_PIPE_STRUCT_PTR) pipe_ptr;
   PIPE_STRUCT_PTR                              pipe_next_ptr = NULL;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->G.DEV_PTR;
   QH_ptr = pipe_descr_ptr->QH_FOR_THIS_PIPE;
   
   if ((pipe_descr_ptr->G.PIPETYPE == USB_CONTROL_PIPE) || (pipe_descr_ptr->G.PIPETYPE == USB_BULK_PIPE))
   {
      USB_lock();

      /************************************************************
      Close the pipe on Async transfers (Bulk and Control)   
      ************************************************************/
      /* Get the head of the active queue head */
      active_list_member_ptr = usb_host_ptr->ACTIVE_ASYNC_LIST_PTR;


      while (active_list_member_ptr) {

         temp_QH_ptr = (EHCI_QH_STRUCT_PTR)
            ((uint_32)active_list_member_ptr->QH_PTR & 
               EHCI_QH_HORIZ_PHY_ADDRESS_MASK);

         next_ptr = active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;

         if (temp_QH_ptr == QH_ptr) {
            /* Found it */

            if (prev_ptr) {
               /* If this is not the first struct in the queue */
               EHCI_MEM_WRITE(prev_ptr->QH_PTR->HORIZ_LINK_PTR, EHCI_MEM_READ(QH_ptr->HORIZ_LINK_PTR));
            
               USB_mem_free(active_list_member_ptr);
               prev_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR = next_ptr;
            } else {
               /* If this is the first struct in the queue */
               if (next_ptr == NULL) {
                  /* If the head is the only one in the queue, disable asynchronous queue */
                  EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_USBCMD_ASYNC_SCHED_ENABLE);
               } else {
                  /* we dont have previous pointer, so roll down to the end of list */
                  /* get last queue head */   
                  while ((EHCI_MEM_READ(temp_QH_ptr->HORIZ_LINK_PTR) & EHCI_QH_HORIZ_PHY_ADDRESS_MASK) != (uint_32) QH_ptr)
                     temp_QH_ptr = (pointer) (EHCI_MEM_READ(temp_QH_ptr->HORIZ_LINK_PTR) & EHCI_QH_HORIZ_PHY_ADDRESS_MASK);
                  
                  /* get next queue for last queue head */
                  next_ptr = active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
                  /* link queue heads in the controller */
                  EHCI_MEM_WRITE(temp_QH_ptr->HORIZ_LINK_PTR,EHCI_MEM_READ(QH_ptr->HORIZ_LINK_PTR));
               }
               
               USB_mem_free(active_list_member_ptr);
               usb_host_ptr->ACTIVE_ASYNC_LIST_PTR = next_ptr;
            } /* Endif */

            /* move it to free queue heads */
            _usb_ehci_free_QH(handle, (pointer) QH_ptr);

            break;
         } /* Endif */

         prev_ptr = active_list_member_ptr;
         active_list_member_ptr = next_ptr;

      } /* Endwhile */

      USB_unlock();

   }
   else if (pipe_descr_ptr->G.PIPETYPE == USB_INTERRUPT_PIPE)
   {
        _usb_ehci_close_interrupt_pipe(handle, pipe_descr_ptr);
        pipe_next_ptr = pipe_descr_ptr->G.NEXT;
        USB_mem_zero(pipe_descr_ptr, sizeof(EHCI_PIPE_STRUCT));
        pipe_descr_ptr->G.NEXT = pipe_next_ptr;
   }
   else if(pipe_descr_ptr->G.PIPETYPE == USB_ISOCHRONOUS_PIPE)
   {
        _usb_ehci_close_isochronous_pipe(handle,pipe_descr_ptr);
   }

   return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_process_tr_complete
*  Returned Value : None
*  Comments       :
*     Process the Transaction Done interrupt on the EHCI hardware. Note that this
*     routine should be improved later. It is needless to search all the lists
*     since interrupt will belong to only one of them at one time.
*
*END*-----------------------------------------------------------------*/

void _usb_ehci_process_tr_complete
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle           handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   ACTIVE_QH_MGMT_STRUCT_PTR                    active_list_member_ptr;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;

   /***************************************************************************
    SEARCH THE NON PERIODIC LIST FIRST
   ***************************************************************************/
      
   /* Get the head of the active queue head */
   active_list_member_ptr = usb_host_ptr->ACTIVE_ASYNC_LIST_PTR;
   if(active_list_member_ptr) 
   {
      _usb_ehci_process_qh_list_tr_complete(handle,active_list_member_ptr);
   }
   
   /***************************************************************************
    SEARCH THE INTERRUPT LIST
   ***************************************************************************/

   /* Get the head of the active structures for periodic list*/
   active_list_member_ptr = usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR;
   if(active_list_member_ptr) 
   {
      _usb_ehci_process_qh_interrupt_tr_complete(handle,active_list_member_ptr);
   }

   /***************************************************************************
    SEARCH THE HIGH SPEED ISOCHRONOUS LIST
   ***************************************************************************/
   if(usb_host_ptr->HIGH_SPEED_ISO_QUEUE_ACTIVE) 
   {
      _usb_ehci_process_itd_tr_complete(handle);
   }

   /***************************************************************************
    SEARCH THE FULL SPEED ISOCHRONOUS LIST
   ***************************************************************************/
   if(usb_host_ptr->FULL_SPEED_ISO_QUEUE_ACTIVE) 
   {
      _usb_ehci_process_sitd_tr_complete(handle);
   }

                                
} /* Endbody */
   
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_process_qh_list_tr_complete
*  Returned Value : None
*  Comments       :
*     Search the asynchronous or interrupt list to see which QTD had finished and 
*     Process the interrupt.
*
*END*-----------------------------------------------------------------*/

static void _usb_ehci_process_qh_list_tr_complete
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,
      
      ACTIVE_QH_MGMT_STRUCT_PTR        active_list_member_ptr
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR                    usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   EHCI_QH_STRUCT_PTR                           QH_ptr;
   EHCI_QTD_STRUCT_PTR                          QTD_ptr;
   EHCI_QTD_STRUCT_PTR                          temp_QTD_ptr;
   EHCI_PIPE_STRUCT_PTR                         pipe_descr_ptr = NULL;
   EHCI_TR_STRUCT_PTR                           pipe_tr_struct_ptr = NULL;
   boolean                                      first_phase = FALSE;
   uint_32                                      req_bytes = 0;
   uint_32                                      remaining_bytes = 0;
   uint_32                                      errors = 0, status = 0, active = 0, expired;
   uchar_ptr                                    buffer_ptr = NULL;
   #if PSP_HAS_DATA_CACHE
       uchar_ptr                                    uncache_buff_ptr = NULL;
       uchar_ptr                                    cache_buff_ptr = NULL;
       uint_32                                      uncache_size = 0;
   #endif

   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = usb_host_ptr->DEV_PTR;
     
   /* Check all transfer descriptors on all active queue heads */
   do {
         /* Get the queue head from the active list */
         QH_ptr = active_list_member_ptr->QH_PTR;
         /* Get the first QTD for this Queue head */
         QTD_ptr = active_list_member_ptr->FIRST_QTD_PTR;

#if PSP_HAS_DATA_CACHE
         USB_dcache_invalidate_mlines((void *)QH_ptr,sizeof(EHCI_QH_STRUCT));
         USB_dcache_invalidate_mlines((void *)QTD_ptr,sizeof(EHCI_QTD_STRUCT));
#endif

         if (!(active_list_member_ptr->TIME))
            expired = 1;
         else
            expired = 0;
         
         while (!(((uint_32)QTD_ptr) & EHCI_QTD_T_BIT)) 
         {
            /* This is a valid qTD */
            if (!(EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_STATUS_ACTIVE) || expired) {

#ifdef DEBUG_INFO
            uint_32 token = EHCI_MEM_READ(QTD_ptr->TOKEN);
            printf("QTD done Token=%x\n"
                   "  Status=%x,PID code=%x,error code=%x,page=%x,IOC=%x,Bytes=%x,Toggle=%x\n",
                   token,
                   ((token)&0xFF),
                   ((token) >> 8)&0x3,
                   ((token) >> 10) &0x3,
                   ((token) >> 12)&0x7,
                   ((token) >> 15)&0x1,
                   ((token) >> 16)&0x7FFF,
                   ((token)&EHCI_QTD_DATA_TOGGLE) >>31);
#endif

                     /* Get the pipe descriptor for this transfer */
                     pipe_descr_ptr = (EHCI_PIPE_STRUCT_PTR)QTD_ptr->PIPE_DESCR_FOR_THIS_QTD;
                     pipe_tr_struct_ptr = (EHCI_TR_STRUCT_PTR)QTD_ptr->TR_FOR_THIS_QTD;

                     /* Check for errors */
                     if (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_ERROR_BITS_MASK) {
                        errors |= (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_ERROR_BITS_MASK);
                        EHCI_MEM_CLEAR_BITS(QTD_ptr->TOKEN,EHCI_QTD_ERROR_BITS_MASK);
                        status = USBERR_TR_FAILED;
                     } /* Error */

                     /* Check if STALL or endpoint halted because of errors */
                     if (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_STATUS_HALTED) {
                        errors |= EHCI_QTD_STATUS_HALTED;
                        status = USBERR_ENDPOINT_STALLED;
                        EHCI_MEM_CLEAR_BITS(QTD_ptr->TOKEN,EHCI_QTD_STATUS_HALTED);
                        QH_ptr->STATUS = 0;
                     } /* Endif */

                     if (pipe_descr_ptr->G.PIPETYPE == USB_CONTROL_PIPE) 
                     {

                           if (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_PID_SETUP) 
                           {
                              first_phase = TRUE;
                              req_bytes = remaining_bytes = 0;
                           } 
                           else if (first_phase) 
                           {
                              first_phase = FALSE;
                              if (pipe_tr_struct_ptr->G.SEND_PHASE) 
                              {
                                 buffer_ptr = pipe_tr_struct_ptr->G.TX_BUFFER;
                                 pipe_tr_struct_ptr->G.SEND_PHASE = FALSE;
                              } 
                              else 
                              {
                                 buffer_ptr = pipe_tr_struct_ptr->G.RX_BUFFER;
                              } /* Endif */
                              
                              /* Increment the total number of bytes sent/received */
                              req_bytes = QTD_ptr->RESERVED[MEM_SIZE_INDEX];
                              remaining_bytes = ((EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_LENGTH_BIT_MASK) >> EHCI_QTD_LENGTH_BIT_POS);
                              #if PSP_HAS_DATA_CACHE
                                  /*if (remaining_bytes == 0)*/ {
                                      if ((pipe_tr_struct_ptr->G.RX_LENGTH != 0)||
                                          (pipe_tr_struct_ptr->G.TX_LENGTH != 0)) {
                                          uncache_buff_ptr = (uchar_ptr)(QTD_ptr->RESERVED[MEM_UNCACHE_INDEX]);
                                          cache_buff_ptr = (uchar_ptr)(QTD_ptr->RESERVED[MEM_CACHE_INDEX]);
                                          if (pipe_tr_struct_ptr->G.RX_LENGTH) {
                                              USB_mem_copy(uncache_buff_ptr,
                                                           cache_buff_ptr,
                                                           req_bytes - remaining_bytes);
                                          }
                                          USB_mem_free(uncache_buff_ptr);
                                      }
                                  }
                              #endif
                           }
                           else {
                        	   req_bytes = remaining_bytes = 0;
                           }
                     } 
                     else 
                     {
                           req_bytes = QTD_ptr->RESERVED[MEM_SIZE_INDEX];
                           remaining_bytes = ((EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_LENGTH_BIT_MASK) >> EHCI_QTD_LENGTH_BIT_POS);
                              
                           if (pipe_descr_ptr->G.DIRECTION) {
                              buffer_ptr = pipe_tr_struct_ptr->G.TX_BUFFER;
                           } else {
                              int_32 received, num_of_packets;

                              buffer_ptr = pipe_tr_struct_ptr->G.RX_BUFFER;

#if USBCFG_EHCI_USE_SW_TOGGLING
                              /* For IN transfers, compute pipe_descr_ptr->NEXTDATA01 value
                                 based on number of received packets */
                              received = req_bytes - remaining_bytes;

                              num_of_packets = 1 + received / pipe_descr_ptr->MAX_PACKET_SIZE;
                              /* If we received what we asked for and it is aligned for max. packet size, then
                                 the Zero-Length Packet was not received at the end of transfer */
                              if (req_bytes && received && (received % pipe_descr_ptr->MAX_PACKET_SIZE == 0))
                                    num_of_packets--;
                        
                              pipe_descr_ptr->NEXTDATA01 ^= (num_of_packets & 0x1);
#endif
                           } /* Endif */

                     } /* Endif */

                     pipe_tr_struct_ptr->SOFAR += (req_bytes - remaining_bytes);
                        #if  PSP_HAS_DATA_CACHE
                            if (pipe_descr_ptr->G.PIPETYPE != USB_CONTROL_PIPE) {
                                uncache_buff_ptr = (uchar_ptr)(QTD_ptr->RESERVED[MEM_UNCACHE_INDEX]);
                                cache_buff_ptr = (uchar_ptr)(QTD_ptr->RESERVED[MEM_CACHE_INDEX]);
                                if (pipe_tr_struct_ptr->G.RX_LENGTH) {
                                    USB_mem_copy(uncache_buff_ptr,
                                                 cache_buff_ptr,
                                                 req_bytes - remaining_bytes);
                                }
                                USB_mem_free(uncache_buff_ptr);
                            }
                        #endif
                            if (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_IOC) {
                               /* total number of bytes sent/received */
                               pipe_tr_struct_ptr->G.STATUS = USB_STATUS_IDLE;
                            }

                     temp_QTD_ptr = QTD_ptr;
                     QTD_ptr = (EHCI_QTD_STRUCT_PTR)EHCI_MEM_READ(QTD_ptr->NEXT_QTD_PTR);
                     
                     if (active_list_member_ptr->FIRST_QTD_PTR == temp_QTD_ptr)
                        active_list_member_ptr->FIRST_QTD_PTR = QTD_ptr;
                     

                     /* queue the transfer only if it is a valid transfer */

                     if (EHCI_MEM_READ(QH_ptr->NEXT_QTD_LINK_PTR) & EHCI_QTD_T_BIT) {
                        /* No alternate descriptor */
                        EHCI_MEM_SET_BITS(QH_ptr->ALT_NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
                     } /* Endif */

                     if (pipe_tr_struct_ptr->G.STATUS == USB_STATUS_IDLE) 
                     {
                        /* If there are remaining bytes, that means device returned less than expected.
                        ** We set USBERR_TR_FAILED, but still buffer_ptr is not NULL.
                        ** Application should check: if buffer_ptr is not NULL and status is USBERR_TR_FAILED,
                        ** then it means the transfer was done although not as expected (perhaps the last packet ?)
                        */
                        if ((pipe_tr_struct_ptr->SOFAR < (pipe_tr_struct_ptr->G.RX_LENGTH + pipe_tr_struct_ptr->G.TX_LENGTH) && (status == USB_OK)))
                           status = USBERR_TR_FAILED;

                        /* Transfer done. Call the callback function for this 
                        ** transaction if there is one (usually true). 
                        */
                        if (pipe_tr_struct_ptr->G.CALLBACK != NULL) 
                        {
                           #ifdef DEBUG_INFO
                           printf("_usb_ehci_process_qh_list_tr_complete: Callback\n");
                           #endif
                           pipe_tr_struct_ptr->G.CALLBACK((pointer)pipe_descr_ptr, 
                              pipe_tr_struct_ptr->G.CALLBACK_PARAM,
                              buffer_ptr,
                              pipe_tr_struct_ptr->SOFAR,
                              status);

                           /* If the application enqueued another request on this pipe 
                           ** in this callback context then it will be at the end of the list
                           */
                        } /* Endif */
                        errors = 0;
                        status = 0;
                     } /* Endif */

                     /* Dequeue the used QTD */
                     _usb_ehci_free_QTD(handle, (pointer)temp_QTD_ptr);
                     /* Now mark transaction as unused so that next request can use it */
                     pipe_tr_struct_ptr->G.TR_INDEX = 0;

                     active_list_member_ptr->TIME = USBCFG_EHCI_PIPE_TIMEOUT;
                     expired = 0;
         
            } /* Endif */
            else 
            {
               QTD_ptr = (EHCI_QTD_STRUCT_PTR)EHCI_MEM_READ(QTD_ptr->NEXT_QTD_PTR);
               active = 1;
            }
         
            USB_dcache_invalidate_mlines((void *)QTD_ptr,sizeof(EHCI_QTD_STRUCT));
                     
         } /* EndWhile */

         #ifdef DEBUG_INFO
            printf("_usb_ehci_process_qh_list_tr_complete: next active QH\n");
         #endif
                      
         if (expired)
            active_list_member_ptr->TIME = -1; /* it means that no QTD is in this QH */

         active_list_member_ptr = 
            active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
            
      } while (active_list_member_ptr);   /* While there are more queue heads in the active list */ 


} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_process_qh_interrupt_tr_complete
*  Returned Value : None
*  Comments       :
*     Search the interrupt list to see which QTD had finished and 
*     Process the interrupt.
*
*END*-----------------------------------------------------------------*/

static void _usb_ehci_process_qh_interrupt_tr_complete
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,
      
      ACTIVE_QH_MGMT_STRUCT_PTR        active_list_member_ptr
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR                    usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   EHCI_QH_STRUCT_PTR                           QH_ptr;
   EHCI_QTD_STRUCT_PTR                          QTD_ptr;
   EHCI_QTD_STRUCT_PTR                          temp_QTD_ptr;
   EHCI_PIPE_STRUCT_PTR                         pipe_descr_ptr = NULL;
   EHCI_TR_STRUCT_PTR                           pipe_tr_struct_ptr = NULL;
   uint_32                                      total_req_bytes = 0;
   uint_32                                      remaining_bytes = 0;
   uint_32                                      errors = 0, status = 0;
   uchar_ptr                                    buffer_ptr = NULL;
   #if PSP_HAS_DATA_CACHE
       uchar_ptr                                    uncache_buff_ptr = NULL;
       uchar_ptr                                    cache_buff_ptr = NULL;
   #endif

   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = usb_host_ptr->DEV_PTR;

   /* Check all transfer descriptors on all active queue heads */
   do {
         /* Get the queue head from the active list */
         QH_ptr = active_list_member_ptr->QH_PTR;
         /* Get the first QTD for this Queue head */
         QTD_ptr = active_list_member_ptr->FIRST_QTD_PTR;


         while ((!(((uint_32)QTD_ptr) & EHCI_QTD_T_BIT)) && (QTD_ptr != NULL))
         {
            /* This is a valid qTD */


      #ifdef DEBUG_INFO
                     uint_32 token = EHCI_MEM_READ(QTD_ptr->TOKEN);
                     printf("_usb_ehci_process_qh_interrupt_tr_complete: QTD =%x\n"
                              "  Status=%x,PID code=%x,error code=%x,page=%x,IOC=%x,Bytes=%x,Toggle=%x\n",
                     token,
                     (token&0xFF),
                     (token >> 8)&0x3,
                     (token >> 10) &0x3,
                     (token >> 12)&0x7,
                     (token >> 15)&0x1,
                     (token >> 16)&0x7FFF,
                     (token&EHCI_QTD_DATA_TOGGLE) >>31);
      #endif

         if (!(EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_STATUS_ACTIVE)) {

                     /* Get the pipe descriptor for this transfer */
                     pipe_descr_ptr = (EHCI_PIPE_STRUCT_PTR)QTD_ptr->PIPE_DESCR_FOR_THIS_QTD;
                     pipe_tr_struct_ptr = (EHCI_TR_STRUCT_PTR) QTD_ptr->TR_FOR_THIS_QTD;

                     /* Check for errors */
                    if (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_ERROR_BITS_MASK) {
                        errors |= (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_ERROR_BITS_MASK);
                        EHCI_MEM_CLEAR_BITS(QTD_ptr->TOKEN,EHCI_QTD_ERROR_BITS_MASK);
                        status = USBERR_TR_FAILED;
                     } /* Error */

                     /* Check if STALL or endpoint halted because of errors */
                     if (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_STATUS_HALTED) {
                        errors |= EHCI_QTD_STATUS_HALTED;
                        status = USBERR_ENDPOINT_STALLED;
                        EHCI_MEM_CLEAR_BITS(QTD_ptr->TOKEN,EHCI_QTD_STATUS_HALTED);
                        EHCI_MEM_WRITE(QH_ptr->STATUS,0);
                     } /* Endif */

                     if (pipe_descr_ptr->G.DIRECTION) {
                        total_req_bytes = pipe_tr_struct_ptr->G.TX_LENGTH;
                        buffer_ptr = pipe_tr_struct_ptr->G.TX_BUFFER;
                     } else {
                        total_req_bytes = pipe_tr_struct_ptr->G.RX_LENGTH;
                        buffer_ptr = pipe_tr_struct_ptr->G.RX_BUFFER;
                     } /* Endif */
                     remaining_bytes = ((EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_LENGTH_BIT_MASK) >> EHCI_QTD_LENGTH_BIT_POS);

                     #if PSP_HAS_DATA_CACHE
                        if ((pipe_descr_ptr->G.DIRECTION == USB_RECV) && (pipe_tr_struct_ptr->G.RX_LENGTH)) {
                           uncache_buff_ptr = (uchar_ptr)(QTD_ptr->RESERVED[MEM_UNCACHE_INDEX]);
                           cache_buff_ptr = (uchar_ptr)(QTD_ptr->RESERVED[MEM_CACHE_INDEX]);
                           USB_mem_copy(uncache_buff_ptr,
                              cache_buff_ptr,
                              total_req_bytes - remaining_bytes);
                        }
                        USB_mem_free(uncache_buff_ptr);
                     #endif
                  
   #ifdef DEBUG_INFO
                     printf("_usb_ehci_process_qh_interrupt_tr_complete: Requested Bytes = %d\
                     ,Remaining bytes = %d,",total_req_bytes,remaining_bytes);
   #endif
                        
                     if (EHCI_MEM_READ(QTD_ptr->TOKEN) & EHCI_QTD_IOC) {
                        /* total number of bytes sent/received */
                        pipe_tr_struct_ptr->G.STATUS = USB_STATUS_IDLE;
                     } /* Endif */

                     temp_QTD_ptr = QTD_ptr;
                     
                     QTD_ptr = (EHCI_QTD_STRUCT_PTR)EHCI_MEM_READ(QTD_ptr->NEXT_QTD_PTR);
                        
                     /* Queue the transfer onto the relevant queue head */
                     EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,(uint_32)QTD_ptr);
                     if (EHCI_MEM_READ(QH_ptr->NEXT_QTD_LINK_PTR) & EHCI_QTD_T_BIT) {
                        /* No alternate descriptor */
                        EHCI_MEM_SET_BITS(QH_ptr->ALT_NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
                     } /* Endif */


                        active_list_member_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR)QTD_ptr;
        
                     /* Dequeue the used QTD */
                     _usb_ehci_free_QTD(handle, (pointer)temp_QTD_ptr);
               
                     /* Now mark it as unused so that next request can use it */
                     pipe_tr_struct_ptr->G.TR_INDEX = 0;

                     if (pipe_tr_struct_ptr->G.STATUS == USB_STATUS_IDLE) 
                     {
                        /* Transfer done. Call the callback function for this 
                        ** transaction if there is one (usually true). 
                        */
                        if (pipe_tr_struct_ptr->G.CALLBACK != NULL) 
                        {
                           pipe_tr_struct_ptr->G.CALLBACK((pointer)pipe_descr_ptr, 
                              pipe_tr_struct_ptr->G.CALLBACK_PARAM,
                              buffer_ptr,
                              (total_req_bytes - remaining_bytes),
                              status);

                           /* If the application enqueued another request on this pipe 
                           ** in this callback context then it will be at the end of the list
                           */
                        } /* Endif */
                        errors = 0;
                        status = 0;
                     } /* Endif */
         
         
            } /* Endif */
            else 
            { /* Body */

               break;
            } /* Endbody */
         
         
         } /* EndWhile */

         active_list_member_ptr = 
            active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;

      } while (active_list_member_ptr);   /* While there are more queue 
                                       ** heads in the active list */ 


} /* Endbody */
   

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_delay
*  Returned Value : None
*  Comments       :
*        Delay for specified number of milliseconds.
*END*-----------------------------------------------------------------*/

void _usb_host_delay
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle,
      
      /* [IN] time to wait in ms */
      uint_32 delay
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR              usb_host_ptr;
   VUSB20_REG_STRUCT _PTR_                dev_ptr;
   uint_32                                start_frame=0,curr_frame=0,diff =0,i=0,j=0;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;   
   dev_ptr      = (VUSB20_REG_STRUCT _PTR_)usb_host_ptr->DEV_PTR;

   /* Get the frame number (not the uframe number */
   start_frame = _usb_ehci_get_frame_number(handle);
   
   /*wait till frame numer exceeds by delay mili seconds.*/
   do 
   {
      curr_frame = _usb_ehci_get_frame_number(handle);
      i++;
      if(curr_frame != start_frame)  
      {
         diff++;
         start_frame =  curr_frame;
         j++;
      }
      
   }while(diff < delay);   

#if 0      
   volatile uint_32              delay_count;
   OTG_STRUCT_PTR                otg_reg;
   uint_32                       otg_status;
   uint_32                       curr_toggle_bit =0;
   uint_32                       new_toggle_bit =0;
   volatile VUSB20_REG_STRUCT _PTR_       dev_ptr;
   uint_32     
   USB_OTG_STATE_STRUCT_PTR usb_otg_ptr = (USB_OTG_STATE_STRUCT_PTR)usb_otg_state_struct_ptr;
   int test1[101],test2[101];
   int i=0,j=0;
   otg_reg = usb_otg_ptr->OTG_REG_PTR;
   dev_ptr = usb_otg_ptr->USB_REG_PTR;
   delay_count = delay;
      j++;
      if (otg_status & VUSBHS_OTGSC_1MSIS) 
      {
         i++;
         test1[i] = otg_status;
         otg_status |=  VUSBHS_OTGSC_1MSIS;
         EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.OTGSC,otg_status);
         test2[i] = otg_status;
   }
#endif
} /* Endbody */
   
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_process_itd_tr_complete
*  Returned Value : None
*  Comments       :
*     Search the ITD list to see which ITD had finished and 
*     Process the interrupt.
*
*END*-----------------------------------------------------------------*/

static void _usb_ehci_process_itd_tr_complete
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   VUSB20_REG_STRUCT _PTR_                      dev_ptr;
   EHCI_ITD_STRUCT_PTR                          ITD_ptr;
   EHCI_PIPE_STRUCT_PTR                         pipe_descr_ptr = NULL;
   EHCI_TR_STRUCT_PTR                           pipe_tr_struct_ptr = NULL;
   uint_32                                      total_req_bytes = 0, no_of_scheduled_slots;
   uint_32                                      remaining_bytes = 0;
   uint_32                                      errors = 0, status = 0;
   uchar_ptr                                    buffer_ptr = NULL;
   LIST_NODE_STRUCT_PTR                         node_ptr,prev_node_ptr,next_node_ptr;
   uint_8                                       transaction_number,page_number;
   boolean                                      pending_transaction;
   uint_32                                      offset,length_transmitted;
   uint_32_ptr                                  prev_link_ptr=NULL,next_link_ptr=NULL;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = usb_host_ptr->G.DEV_PTR;
   length_transmitted = 0;
   

   /******************************************************************
   Search the ITD list starting from head till we find inactive nodes.
   Note that for Head there is no previous node so we can disntiguish
   it from rest of the list.
   ******************************************************************/
   prev_node_ptr = node_ptr =  usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR; 

   /* loop till current node is active or node is a head node*/
   while ((prev_node_ptr->next_active && (prev_node_ptr->next != NULL))
          || ((node_ptr->prev == NULL) && (node_ptr->member != NULL)))
   {
      
      ITD_ptr =  (EHCI_ITD_STRUCT_PTR) node_ptr->member;
       #ifdef  __USB_OTG__
       
         #ifdef HOST_TESTING
         /*
         usb_otg_state_struct_ptr->STATUS_STARTS[usb_otg_state_struct_ptr->LOG_ITD_COUNT]
                      = EHCI_MEM_READ(ITD_ptr->status);
         */            
         #endif
      #endif
           
      if (!ITD_ptr) {
         continue;
      }
      #if PSP_HAS_DATA_CACHE
      /* Before reading from USB accessed structure, invalidate cache lines. Not needed if ITD_ptr is in uncached memory area */
      //USB_dcache_invalidate_mlines((pointer)ITD_ptr, sizeof(*ITD_ptr));
      #endif
         
      pipe_tr_struct_ptr =  (EHCI_TR_STRUCT_PTR) ITD_ptr->PIPE_TR_DESCR_FOR_THIS_ITD;
      
      pipe_descr_ptr = (EHCI_PIPE_STRUCT_PTR) ITD_ptr->PIPE_DESCR_FOR_THIS_ITD;
      
      /* assume that no transactions are pending on this ITD */
      pending_transaction = FALSE;
      
      no_of_scheduled_slots = 0;
      
      /**************************************************************
      Check the status of every transaction inside the ITD.
      **************************************************************/
      for(transaction_number = 0; transaction_number < 8; transaction_number++)
      {

         /**************************************************************
         Note that each iteration of this loop checks the micro frame 
         number on which transaction is scheduled. If a micro frame was
         not allocated for this pipe, we don't need to check it. But
         caution is that, there could be a transaction that was too
         small and even though many bandwidth slots are available 
         but this transaction was finished only in 1 of the slots. Thus
         we also keep a check of how many transactions were allocated for
         this ITD.
         **************************************************************/
      
         if ((pipe_descr_ptr->BWIDTH_SLOTS[transaction_number]) &&
            (no_of_scheduled_slots < ITD_ptr->number_of_transactions))
         {

               
              no_of_scheduled_slots++;
               
              status = EHCI_MEM_READ(ITD_ptr->TR_STATUS_CTL_LIST[transaction_number]) & EHCI_ITD_STATUS;

            
               /* if transaction is not active and IOC was set we look in to it else we move on */
               if ((!(status & EHCI_ITD_STATUS_ACTIVE)) &&
                  (EHCI_MEM_READ(ITD_ptr->TR_STATUS_CTL_LIST[transaction_number]) & EHCI_ITD_IOC_BIT)) {

                  #if 0
                  /* send callback to app with the status*/
                  if (pipe_tr_struct_ptr->G.CALLBACK != NULL) 
                  {
                       uint_32 temp = EHCI_MEM_READ(ITD_ptr->TR_STATUS_CTL_LIST[transaction_number]);

                       offset =  temp & EHCI_ITD_BUFFER_OFFSET;
                                  
                       page_number =  (uint_8)((temp & EHCI_ITD_PAGE_NUMBER) >> EHCI_ITD_PG_SELECT_BIT_POS);

                       length_transmitted = (temp & EHCI_ITD_LENGTH_TRANSMITTED) >> EHCI_ITD_LENGTH_BIT_POS;
                                     
                        buffer_ptr = (uchar_ptr) ((EHCI_MEM_READ(ITD_ptr->BUFFER_PAGE_PTR_LIST[page_number]) &
                                                 EHCI_ITD_BUFFER_POINTER) >> EHCI_ITD_PG_SELECT_BIT_POS);
                                    
                                               
                        pipe_tr_struct_ptr->G.CALLBACK(
                                       (pointer)pipe_descr_ptr, 
                                       pipe_tr_struct_ptr->G.CALLBACK_PARAM,
                                       (buffer_ptr+offset),
                                       length_transmitted,
                                       status);
                  }
                  #endif
                  length_transmitted += (ITD_ptr->TR_STATUS_CTL_LIST[transaction_number] &
                                     EHCI_ITD_LENGTH_TRANSMITTED) >> EHCI_ITD_LENGTH_BIT_POS;
                                 
               }
               /* if IOC is set and status is active, we have a pending transaction */
               else if ((status & EHCI_ITD_STATUS_ACTIVE) &&
                     (EHCI_MEM_READ(ITD_ptr->TR_STATUS_CTL_LIST[transaction_number]) & EHCI_ITD_IOC_BIT)) {
                  /* This means that this ITD has a pending transaction */
                  pending_transaction = TRUE;
                  break;
               }
         
         }

      }

       /* If this ITD is done with all transactions, time to free it */
      if(!pending_transaction)
      {

            /* if we are freeing a head node, we move node_ptr to next head 
            or else we move normally*/
      
            if(node_ptr ==  usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR)
            {
               /*free this node */
               EHCI_QUEUE_FREE_NODE(usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR,
                                    usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_TAIL_PTR,
                                    node_ptr);

               prev_node_ptr = node_ptr = usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR;
            }
            else
            {
                 /*save next node */
                 next_node_ptr = node_ptr->next;
                 
                 /*free current node */
                 EHCI_QUEUE_FREE_NODE(usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR,
                                    usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_TAIL_PTR,
                                    node_ptr);

                 /*move to next node now */
                 node_ptr = next_node_ptr;                   
                 prev_node_ptr = node_ptr->prev;

            }

         /* EHCI_MEM_WRITE((*EHCI_MEM_READ(ITD_ptr->prev_data_struct_ptr)),EHCI_MEM_READ(ITD_ptr->next_data_struct_value));*/
           #ifdef  __USB_OTG__ 
              #ifdef HOST_TESTING
                        usb_otg_state_struct_ptr->STATUS[usb_otg_state_struct_ptr->LOG_ITD_COUNT]
                         = status;
                         
                        USB_mem_copy((uchar_ptr)ITD_ptr,
                                   &usb_otg_state_struct_ptr->LOG_INTERRUPT_ITDS[usb_otg_state_struct_ptr->LOG_ITD_COUNT]
                                     ,8);

                        usb_otg_state_struct_ptr->LOG_ITD_COUNT++;
                        if(usb_otg_state_struct_ptr->LOG_ITD_COUNT > HOST_LOG_MOD)
                        usb_otg_state_struct_ptr->LOG_ITD_COUNT = 0;
                     
               #endif
          #endif
            
            /*remove the ITD from periodic list */
            prev_link_ptr = next_link_ptr =  ITD_ptr->frame_list_ptr;
            /*iterate the list while we find valid pointers (1 means invalid pointer) */

            while(!((uint_32)next_link_ptr & EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT) && !(EHCI_MEM_READ(*next_link_ptr) & EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT))
            {
               /*if a pointer matches our ITD we remove it from list*/
               if((EHCI_MEM_READ(*next_link_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK) ==  (uint_32) ITD_ptr)
               {
                  EHCI_MEM_WRITE(*next_link_ptr, EHCI_MEM_READ((uint_32)ITD_ptr->NEXT_LINK_PTR));
                  break;
               }
               
               prev_link_ptr = next_link_ptr;
               next_link_ptr = (uint_32_ptr) (EHCI_MEM_READ(*next_link_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK);
            }



            /* subtract on how many ITDs are pending from this transfer */
            pipe_tr_struct_ptr->no_of_itds_sitds -= 1;
            
            /* if all ITDS are served free the TR INDEX */
            if(pipe_tr_struct_ptr->no_of_itds_sitds == 0)
            {
                 /* Mark TR as unused so that next request can use it */
                 pipe_tr_struct_ptr->G.TR_INDEX = 0;
                 
            }
         
          /* Get buffer ftom ITD, aligned */
          buffer_ptr = (uchar_ptr) (EHCI_MEM_READ(ITD_ptr->BUFFER_PAGE_PTR_LIST[0]) & EHCI_ITD_BUFFER_POINTER);
          /* Add offset of unaligned buffer */
          buffer_ptr += EHCI_MEM_READ(ITD_ptr->TR_STATUS_CTL_LIST[0]) & EHCI_ITD_BUFFER_OFFSET;

          /* free the ITD used */
          _usb_ehci_free_ITD((pointer)usb_host_ptr, (pointer)ITD_ptr);

          if (pipe_tr_struct_ptr->G.CALLBACK != NULL) 
          {
              pipe_tr_struct_ptr->G.CALLBACK((pointer)pipe_descr_ptr, 
                                                (TR_STRUCT_PTR)pipe_tr_struct_ptr,
                                                buffer_ptr,
                                                length_transmitted,
                                                status);
          }
         
      }
      else
      {
         /* move to next ITD in the list */      
         prev_node_ptr = node_ptr;
         node_ptr = node_ptr->next;

      }
      

     
   }/* end while loop */
   
   
} /* Endbody */
   
   

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_process_sitd_tr_complete
*  Returned Value : None
*  Comments       :
*     Search the SITD list to see which SITD had finished and 
*     Process the interrupt.
*
*END*-----------------------------------------------------------------*/

static void _usb_ehci_process_sitd_tr_complete
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   VUSB20_REG_STRUCT _PTR_                      dev_ptr;
   EHCI_SITD_STRUCT_PTR                         SITD_ptr;
   EHCI_PIPE_STRUCT_PTR                         pipe_descr_ptr = NULL;
   EHCI_TR_STRUCT_PTR                           pipe_tr_struct_ptr = NULL;
   uint_32                                      status = 0;
   uchar_ptr                                    buffer_ptr = NULL;
   LIST_NODE_STRUCT_PTR                         node_ptr,prev_node_ptr,next_node_ptr;
   uint_32                                      length_scheduled, length_remaining;
   uint_32_ptr                                  prev_link_ptr=NULL,next_link_ptr=NULL;


   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = usb_host_ptr->G.DEV_PTR;
   
   /******************************************************************
   Search the SITD list starting from head till we find inactive nodes.
   Note that for Head there is no previous node so we can disntiguish
   it from rest of the list.
   ******************************************************************/
   prev_node_ptr = node_ptr =  usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR; 
   
   /* loop till current node is active or node is a head node*/
   while ((prev_node_ptr->next_active && (prev_node_ptr->next != NULL))
          || ((node_ptr->prev == NULL) && (node_ptr->member != NULL)))
   {
      
      SITD_ptr =  (EHCI_SITD_STRUCT_PTR) node_ptr->member;
      #if PSP_HAS_DATA_CACHE
      /* Before reading from USB accessed structure, invalidate cache lines. Not needed if SITD_ptr is in uncached memory area */
      //USB_dcache_invalidate_mlines((pointer)SITD_ptr, sizeof(*SITD_ptr));
      #endif
      
      pipe_tr_struct_ptr = (EHCI_TR_STRUCT_PTR) SITD_ptr->PIPE_TR_DESCR_FOR_THIS_SITD;
      
      pipe_descr_ptr = (EHCI_PIPE_STRUCT_PTR) SITD_ptr->PIPE_DESCR_FOR_THIS_SITD;

      /*grab the status and check it */
      status = EHCI_MEM_READ(SITD_ptr->TRANSFER_STATE) & EHCI_SITD_STATUS;
               
      /* if transaction is not active we look in to it else we move on */
      if(!(status & EHCI_SITD_STATUS_ACTIVE))
      {
         
            /* send callback to app with the status*/
            if (pipe_tr_struct_ptr->G.CALLBACK != NULL) 
            {
                  length_scheduled = EHCI_MEM_READ(SITD_ptr->RESERVED[MEM_SIZE_INDEX]);
                  length_remaining =((EHCI_MEM_READ(SITD_ptr->TRANSFER_STATE) & EHCI_SITD_LENGTH_TRANSMITTED) >> 16);
                  buffer_ptr = (uchar_ptr) EHCI_MEM_READ(SITD_ptr->BUFFER_PTR_0);
                  buffer_ptr = buffer_ptr - (length_scheduled - length_remaining);

                  pipe_tr_struct_ptr->G.CALLBACK(
                                 (pointer)pipe_descr_ptr, 
                                 pipe_tr_struct_ptr->G.CALLBACK_PARAM,
                                 buffer_ptr,
                                 length_scheduled - length_remaining,
                                 status);
            }
            
            /*********************************************************************
             Since status is Non active for this SITD, time to delete it.           
            *********************************************************************/
            
            /* if we are freeing a head node, we move node_ptr to next head 
            or else we move normally */
      
            if(node_ptr ==  usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR)
            {
               /*free this node */
               EHCI_QUEUE_FREE_NODE(usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR,
                                    usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_TAIL_PTR,
                                    node_ptr);

               prev_node_ptr = node_ptr = usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR;
            }
            else
            {
                 /*save next node */
                 next_node_ptr = node_ptr->next;
                 
                 /*free current node */
                 EHCI_QUEUE_FREE_NODE(usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR,
                                    usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_TAIL_PTR,
                                    node_ptr);

                 /*move to next node now */
                 node_ptr = next_node_ptr;                   
                 prev_node_ptr = node_ptr->prev;

            }

           #ifdef  __USB_OTG__ 
 
              #ifdef HOST_TESTING
                        usb_otg_state_struct_ptr->STATUS[usb_otg_state_struct_ptr->LOG_SITD_COUNT]
                         = status;
                         
                        USB_mem_copy((uchar_ptr)SITD_ptr,
                                   &usb_otg_state_struct_ptr->LOG_INTERRUPT_SITDS[usb_otg_state_struct_ptr->LOG_SITD_COUNT]
                                     ,44);

                        usb_otg_state_struct_ptr->LOG_SITD_COUNT++;
                        if(usb_otg_state_struct_ptr->LOG_SITD_COUNT > HOST_LOG_MOD)
                        usb_otg_state_struct_ptr->LOG_SITD_COUNT = 0;
                     
               #endif
            #endif
                        
            /*remove the SITD from periodic list, TODO: remove prev_link_ptr variable */
            prev_link_ptr = next_link_ptr =  SITD_ptr->frame_list_ptr;
            /*iterate the list while we find valid pointers (1 means invalid pointer) */
            while(!((uint_32)next_link_ptr & EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT) && !(EHCI_MEM_READ(*next_link_ptr) & EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT))
            {
               /*if a pointer matches our SITD we remove it from list*/
               if((EHCI_MEM_READ(*next_link_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK) ==  (uint_32) SITD_ptr)
               {
                  EHCI_MEM_WRITE(*next_link_ptr, EHCI_MEM_READ((uint_32)SITD_ptr->NEXT_LINK_PTR));
                  break;
               }
               
               prev_link_ptr = next_link_ptr;
               next_link_ptr = (uint_32_ptr) (EHCI_MEM_READ(*next_link_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK);
            }



            /* free the SITD used */
            _usb_ehci_free_SITD((pointer)usb_host_ptr, (pointer)SITD_ptr);

            /* subtract on how many SITDs are pending from this transfer */
            pipe_tr_struct_ptr->no_of_itds_sitds -= 1;
            
            /* if all SITDS are served free the TR INDEX */
            if(pipe_tr_struct_ptr->no_of_itds_sitds == 0)
            {
                 /* Mark TR as unused so that next request can use it */
                 pipe_tr_struct_ptr->G.TR_INDEX = 0;
                 
            }
         

                           
      }
      /* else move on to the next node in the queue */
      else
      {
      
         prev_node_ptr = node_ptr;
         node_ptr = node_ptr->next;

      }


   #if 0            
      /* save the next node */
      next_node_ptr =  
   
      /*free this node */
      EHCI_QUEUE_FREE_NODE(usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR,
                           usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_TAIL_PTR,
                           node_ptr);
      
      /* subtract on how many ITDs are pending from this transfer */
      pipe_tr_struct_ptr->no_of_itds_sitds -= 1;
      
      /* if all ITDS are served free the TR INDEX */
      if(pipe_tr_struct_ptr->no_of_itds_sitds == 0)
      {
           /* Mark TR as unused so that next request can use it */
           pipe_tr_struct_ptr->TR_INDEX = 0;

      }
   
      /* if we just freed a head node, we must update our list head */
      if(node_ptr->prev == NULL)
      {
         prev_node_ptr = node_ptr = next_node_ptr;
      }
      else /* we freed some non head node so we move on normally*/
      {
          /* move to next ITD in the list */      
          node_ptr = next_node_ptr;
          prev_node_ptr = node_ptr->prev;

      }
               
   #endif
     
   }/* end while loop */
   
   
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_open_pipe
*  Returned Value : USB Status
*  Comments       :
*        When opening a pipe, this callback ensures for iso / int pipes
*        to allocate bandwidth.
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_ehci_open_pipe
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* The pipe descriptor to queue */            
      PIPE_STRUCT_PTR                  pipe_descr_ptr
   )
{ /* Body */
   USB_STATUS error;
   if ((pipe_descr_ptr->PIPETYPE == USB_INTERRUPT_PIPE) || ((pipe_descr_ptr->PIPETYPE == USB_ISOCHRONOUS_PIPE))) {
      /* Call the low-level routine to send a setup packet */
      error = _usb_host_alloc_bandwidth_call_interface (handle, pipe_descr_ptr);
      
      if (error != USB_OK){
         return USB_log_error(__FILE__,__LINE__,USBERR_BANDWIDTH_ALLOC_FAILED);
      } /* Endif */
   } /* Endif */
   return USB_OK;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_update_dev_address
*  Returned Value : USB Status
*  Comments       :
*        Update the queue in the EHCI hardware Asynchronous schedule list
*        to reflect new device address.
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_ehci_update_dev_address
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* The pipe descriptor to queue */            
      PIPE_STRUCT_PTR                  pipe_ptr
   )
{ /* Body */

   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   EHCI_QH_STRUCT_PTR                           QH_ptr = NULL, QH_prev_ptr = NULL;
   uint_32                                      saved_link;
   boolean                                      active_async;
   EHCI_PIPE_STRUCT_PTR                         pipe_descr_ptr = (EHCI_PIPE_STRUCT_PTR) pipe_ptr;

//   return _usb_ehci_free_resources(handle, pipe_descr_ptr);

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->G.DEV_PTR;

   /* Get the pointer to the member of the active list */
   if (usb_host_ptr->ACTIVE_ASYNC_LIST_PTR != NULL)
      QH_prev_ptr = QH_ptr = usb_host_ptr->ACTIVE_ASYNC_LIST_PTR->QH_PTR;
   else
      return USB_log_error(__FILE__,__LINE__,USBERR_BAD_STATUS);
      
   while (( EHCI_MEM_READ(QH_ptr->HORIZ_LINK_PTR) & EHCI_QH_HORIZ_PHY_ADDRESS_MASK) != (uint_32) usb_host_ptr->ACTIVE_ASYNC_LIST_PTR->QH_PTR) {
      QH_prev_ptr = QH_ptr;
      QH_ptr = (pointer) EHCI_MEM_READ((QH_ptr->HORIZ_LINK_PTR) & EHCI_QH_HORIZ_PHY_ADDRESS_MASK);
      if (QH_ptr == pipe_descr_ptr->QH_FOR_THIS_PIPE)
         break;
   } /* EndWhile */
   
   /* Queue head is already on the active list. Simply update the queue */
   active_async = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD) & EHCI_USBCMD_ASYNC_SCHED_ENABLE;
   /* stop async schedule */
   EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_USBCMD_ASYNC_SCHED_ENABLE);
   saved_link = EHCI_MEM_READ(QH_ptr->HORIZ_LINK_PTR);
//    EHCI_MEM_WRITE(QH_prev_ptr->HORIZ_LINK_PTR,EHCI_MEM_READ(QH_ptr->HORIZ_LINK_PTR)); /* unlink QH */
   _usb_ehci_init_Q_HEAD(handle, pipe_descr_ptr, QH_ptr, QH_prev_ptr, (pointer) EHCI_MEM_READ(QH_ptr->NEXT_QTD_LINK_PTR));
   EHCI_MEM_WRITE(QH_ptr->HORIZ_LINK_PTR,saved_link);
   
   if (active_async)
      EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_USBCMD_ASYNC_SCHED_ENABLE);
   
   return USB_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_process_timer
*  Returned Value : USB Status
*  Comments       :
*        Updates Asynchronous list QTDs timer information. Removes QTDs
*        with timeout.
*END*-----------------------------------------------------------------*/
void _usb_ehci_process_timer
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle
   )
{
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   ACTIVE_QH_MGMT_STRUCT_PTR                    active_list_member;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   
   for (active_list_member = usb_host_ptr->ACTIVE_ASYNC_LIST_PTR; active_list_member != NULL; active_list_member = active_list_member->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR)
   {
      if (active_list_member->TIME > 0)
         if (!--active_list_member->TIME)
            _usb_ehci_process_qh_list_tr_complete(handle, usb_host_ptr->ACTIVE_ASYNC_LIST_PTR);
   }
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_bsp.c<|end_filename|>
/**HEADER**********************************************************************
 *
 * Copyright (c) 2011 Freescale Semiconductor;
 * All Rights Reserved
 *
 ******************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 *
 * $FileName: init_bsp.c$
 * $Version : 3.8.3.0$
 * $Date    : Oct-1-2012$
 *
 * Comments:
 *   This file contains the source functions for functions required to
 *   specifically initialize the card.
 *
 *END*************************************************************************/

#include "mqx_inc.h"
#include "bsp.h"
#include "bsp_prv.h"
#include "io_rev.h"
#include "bsp_rev.h"

const char _PTR_ _mqx_bsp_revision = REAL_NUM_TO_STR(BSP_REVISION);
const char _PTR_ _mqx_io_revision  = REAL_NUM_TO_STR(IO_REVISION);
_mem_pool_id _BSP_sram_pool;

void _bsp_systick(pointer dummy);

/*FUNCTION*--------------------------------------------------------------------
 *
 * Function Name    : systick_config
 * Returned Value   : void
 * Comments         :
 *   Initialize system timer
 *
 *END*-----------------------------------------------------------------------*/

void systick_config
(
 uint32_t bsp_system_clock,
 uint32_t bsp_alarm_frequency
 )
{
  SYST_RVR = bsp_system_clock / bsp_alarm_frequency - 1;
}

/*FUNCTION*--------------------------------------------------------------------
 *
 * Function Name    : systick_init
 * Returned Value   : void
 * Comments         :
 *   Initialize system timer
 *
 *END*-----------------------------------------------------------------------*/

static void systick_init
(
 void
 )
{

  /* Get system clock for active clock configuration */
  uint32_t system_clock = _cm_get_clock(_cm_get_clock_configuration(), CM_CLOCK_SOURCE_CORE);

#if BSP_ALARM_FREQUENCY == 0
  #error Wrong definition of BSP_ALARM_FREQUENCY
#endif

  systick_config(system_clock, BSP_ALARM_FREQUENCY);

  SYST_CSR = 7;

  /* SVCall priority*/
  SCB_SHPR2 |= 0x10000000;
  /* SysTick priority*/
  SCB_SHPR3 |= SCB_SHPR3_PRI_15(CORTEX_PRIOR(BSP_TIMER_INTERRUPT_PRIORITY));
}


/*FUNCTION*--------------------------------------------------------------------
 *
 * Function Name    : _bsp_enable_card
 * Returned Value   : uint_32 result
 * Comments         :
 *   This function sets up operation of the card.
 *
 *END*-----------------------------------------------------------------------*/
uint_32 _bsp_enable_card(void)
{
  uint_32 result;
  KERNEL_DATA_STRUCT_PTR         kernel_data;

  /* Set the CPU type */
  _mqx_set_cpu_type(MQX_CPU);

#if MQX_EXIT_ENABLED
  /* Set the bsp exit handler, called by _mqx_exit */
  _mqx_set_exit_handler(_bsp_exit_handler);
#endif

  /* Memory splitter - prevent accessing both ram banks in one instruction */
  _mem_alloc_at(0, (void *)0x20000000);

  result = _psp_int_init(BSP_FIRST_INTERRUPT_VECTOR_USED, BSP_LAST_INTERRUPT_VECTOR_USED);
  if ( result != MQX_OK )
  {
    return result;
  }

  /* set possible new interrupt vector table - if MQX_ROM_VECTORS = 0 switch to
  ram interrupt table which was initialized in _psp_int_init) */
  _int_set_vector_table(BSP_INTERRUPT_VECTOR_TABLE);

  /* Store timer interrupt vector for debugger */
  _time_set_timer_vector(BSP_TIMER_INTERRUPT_VECTOR);

  /* Install Timer ISR. */
  if ( _int_install_isr(BSP_TIMER_INTERRUPT_VECTOR, _bsp_systick, NULL) == NULL )
  {
    return MQX_TIMER_ISR_INSTALL_FAIL;
  }

#if BSPCFG_HAS_SRAM_POOL
  /* When kernel data is placed outside of the SRAM memory create new _BSP_sram_pool in the SRAM,
     otherwise if kernel data points to SRAM, the _BSP_sram_pool points to system pool. */
  if ( (((uint_32)__INTERNAL_SRAM_BASE) < (uint_32)BSP_DEFAULT_START_OF_KERNEL_MEMORY) &&
       (((uint_32)BSP_DEFAULT_START_OF_KERNEL_MEMORY) < ((uint_32)__INTERNAL_SRAM_BASE + (uint_32)__INTERNAL_SRAM_SIZE)) )
  {
    _BSP_sram_pool  = _mem_get_system_pool_id();
  }
  else
  {
    _BSP_sram_pool = _mem_create_pool(__SRAM_POOL, (uint_32)__INTERNAL_SRAM_BASE + (uint_32)__INTERNAL_SRAM_SIZE - (uint_32)__SRAM_POOL);
  }
#endif

  /** bsp low level internal initialization. ***/
  _bsp_low_level_init();


  /*  System timer initialization */
  systick_init();

  /* MCG initialization and internal oscillators trimming */
  if ( CM_ERR_OK != _bsp_set_clock_configuration(BSP_CLOCK_CONFIGURATION_AUTOTRIM) )
  {
    return MQX_TIMER_ISR_INSTALL_FAIL;
  }

  if ( CM_ERR_OK != _bsp_osc_autotrim() )
  {
    return MQX_TIMER_ISR_INSTALL_FAIL;
  }

  /* Switch to startup clock configuration */
  if ( CM_ERR_OK != _bsp_set_clock_configuration(BSP_CLOCK_CONFIGURATION_STARTUP) )
  {
    return MQX_TIMER_ISR_INSTALL_FAIL;
  }

  /* Initialize the system ticks */
  _GET_KERNEL_DATA(kernel_data);
  kernel_data->TIMER_HW_REFERENCE = (BSP_SYSTEM_CLOCK / BSP_ALARM_FREQUENCY);
  _time_set_ticks_per_sec(BSP_ALARM_FREQUENCY);
  _time_set_hwticks_per_tick(kernel_data->TIMER_HW_REFERENCE);
  _time_set_hwtick_function(_bsp_get_hwticks, (pointer)NULL);

#if MQX_ENABLE_USER_MODE
  _kinetis_mpu_init();

  // supervisor full access, user no access for whole memory
  _kinetis_mpu_add_region(0, ((uchar_ptr)kernel_data->INIT.START_OF_USER_NO_MEMORY) - 1,\
                            MPU_WORD_M3SM(MPU_SM_RWX) | MPU_WORD_M3UM(MPU_UM_R | MPU_UM_X) |\
                            MPU_WORD_M2SM(MPU_SM_RWX) | MPU_WORD_M2UM(MPU_UM_R | MPU_UM_X) |\
                            MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_X) |\
                            MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_X));

  _kinetis_mpu_add_region(((uchar_ptr)kernel_data->INIT.END_OF_USER_NO_MEMORY) + 32, (uchar_ptr)0xffffffff,\
                            MPU_WORD_M3SM(MPU_SM_RWX) | MPU_WORD_M3UM(MPU_UM_R | MPU_UM_X) |\
                            MPU_WORD_M2SM(MPU_SM_RWX) | MPU_WORD_M2UM(MPU_UM_R | MPU_UM_X) |\
                            MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_X) |\
                            MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_X));

  // set access for user memory area
  #if MQX_DEFAULT_USER_ACCESS_RW
  // user .data RW
  _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_DEFAULT_MEMORY, ((uchar_ptr)kernel_data->INIT.END_OF_USER_DEFAULT_MEMORY) - 1,\
                            MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_W) |\
                            MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_W));


  #else
  // user RO - this is by default
  // user .data RO

  /*_kinetis_mpu_add_region(kernel_data->INIT.START_OF_KERNEL_AREA, kernel_data->INIT.END_OF_KERNEL_AREA, \
      MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R) | \
      MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R));
   */

  #endif // MQX_DEFAULT_USER_ACCESS_RW

  // set access for user memory area
  _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_HEAP, ((uchar_ptr)kernel_data->INIT.END_OF_USER_HEAP) - 1,\
                            MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_W) |\
                            MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_W));

  // set access for user read-write memory area
  _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_RW_MEMORY, ((uchar_ptr)kernel_data->INIT.END_OF_USER_RW_MEMORY) - 1,\
                            MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_W) |\
                            MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_W));

  // set access for user read-only memory area
  _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_RO_MEMORY, ((uchar_ptr)kernel_data->INIT.END_OF_USER_RO_MEMORY) - 1,\
                            MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R) |\
                            MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R));

  // set access for user no access memory area
  if ( kernel_data->INIT.START_OF_USER_NO_MEMORY && kernel_data->INIT.END_OF_USER_NO_MEMORY )
  {
    _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_NO_MEMORY, ((uchar_ptr)kernel_data->INIT.END_OF_USER_NO_MEMORY) - 1,\
                              MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(0) |\
                              MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(0));
  }

  _kinetis_mpu_enable();
#else
  _kinetis_mpu_disable();
#endif /* MQX_ENABLE_USER_MODE */

  /* Install low power support */
#if MQX_ENABLE_LOW_POWER
  _lpm_install(LPM_CPU_OPERATION_MODES, LPM_OPERATION_MODE_RUN);
#endif /* MQX_ENABLE_LOW_POWER */

#if BSPCFG_ENABLE_IO_SUBSYSTEM
  /* Initialize the I/O Sub-system */
  result = _io_init();
  if ( result != MQX_OK )
  {
    return result;
  }

  /* Initialize RTC and MQX time */
  #if BSPCFG_ENABLE_RTCDEV
  if ( MQX_OK == _bsp_rtc_io_init() )
  {
    _rtc_init(RTC_INIT_FLAG_ENABLE);
    _rtc_sync_with_mqx(TRUE);
  }
  #endif
  /** Cache settings **/
  /* Make sure that cache region settings has correct value(reset value).
  This value allow maximal perfomance settings for cache regions because of some regions are:
  non-cacheable ,non-cacheable and Write-through or non-cacheable and Write-throug or only Write_back*/
  LMEM_PSCRMR = 0xAA0FA000u;
  LMEM_PCCRMR = 0xAA0FA000u;
  /*folowed 2 functions enable caches (instruction and data cache) and invalidate caches*/
  _DCACHE_ENABLE(0);
  _ICACHE_ENABLE(0);
  /* Install device drivers */
  #if BSPCFG_ENABLE_TTYA
  _kuart_polled_install("ttya:", &_bsp_sci0_init, _bsp_sci0_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_ITTYA
  _kuart_int_install("ittya:", &_bsp_sci0_init, _bsp_sci0_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_TTYB
  _kuart_polled_install("ttyb:", &_bsp_sci1_init, _bsp_sci1_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_ITTYB
  _kuart_int_install("ittyb:", &_bsp_sci1_init, _bsp_sci1_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_TTYC
  _kuart_polled_install("ttyc:", &_bsp_sci2_init, _bsp_sci2_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_ITTYC
  _kuart_int_install("ittyc:", &_bsp_sci2_init, _bsp_sci2_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_TTYD
  _kuart_polled_install("ttyd:", &_bsp_sci3_init, _bsp_sci3_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_ITTYD
  _kuart_int_install("ittyd:", &_bsp_sci3_init, _bsp_sci3_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_TTYE
  _kuart_polled_install("ttye:", &_bsp_sci4_init, _bsp_sci4_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_ITTYE
  _kuart_int_install("ittye:", &_bsp_sci4_init, _bsp_sci4_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_TTYF
  _kuart_polled_install("ttyf:", &_bsp_sci5_init, _bsp_sci5_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_ITTYF
  _kuart_int_install("ittyf:", &_bsp_sci5_init, _bsp_sci5_init.QUEUE_SIZE);
  #endif

  #if BSPCFG_ENABLE_I2C0
  _ki2c_polled_install("i2c0:", &_bsp_i2c0_init);
  #endif
  #if BSPCFG_ENABLE_I2C1
  _ki2c_polled_install("i2c1:", &_bsp_i2c1_init);
  #endif
  #if BSPCFG_ENABLE_II2C0
  _ki2c_int_install("ii2c0:", &_bsp_i2c0_init);
  #endif
  #if BSPCFG_ENABLE_II2C1
  _ki2c_int_install("ii2c1:", &_bsp_i2c1_init);
  #endif

  #if BSPCFG_ENABLE_SPI0
  _io_spi_install("spi0:", &_bsp_spi0_init);
  #endif

  #if BSPCFG_ENABLE_SPI1
  _io_spi_install("spi1:", &_bsp_spi1_init);
  #endif

  #if BSPCFG_ENABLE_SPI2
  _io_spi_install("spi2:", &_bsp_spi2_init);
  #endif

  /* Install the GPIO driver */
  #if BSPCFG_ENABLE_GPIODEV
  _io_gpio_install("gpio:");
  #endif

  #if BSPCFG_ENABLE_ADC0
  _io_adc_install("adc0:", (pointer) & _bsp_adc0_init);
  #endif
  #if BSPCFG_ENABLE_ADC1
  _io_adc_install("adc1:", (pointer) & _bsp_adc1_init);
  #endif
  #if BSPCFG_ENABLE_ADC2
  _io_adc_install("adc2:", (pointer) & _bsp_adc2_init);
  #endif
  #if BSPCFG_ENABLE_ADC3
  _io_adc_install("adc3:", (pointer) & _bsp_adc3_init);
  #endif

  #if BSPCFG_ENABLE_ESDHC
  _esdhc_install("esdhc:", &_bsp_esdhc0_init);
  #endif

  /* Install the PCCard Flash drivers */
  #if BSPCFG_ENABLE_PCFLASH
  _io_pccardflexbus_install("pccarda:", (PCCARDFLEXBUS_INIT_STRUCT _PTR_)&_bsp_cfcard_init);
  _io_apcflash_install("pcflasha:");
  #endif

  #if BSPCFG_ENABLE_FLASHX
  _io_flashx_install("flashx:", &_bsp_flashx_init);
  #endif

  #if BSPCFG_ENABLE_IODEBUG
  _io_debug_install("iodebug:", &_bsp_iodebug_init);
  #endif
  #if BSPCFG_ENABLE_NANDFLASH
  result = _io_nandflash_install(&_bsp_nandflash_init);
  #endif

  /* Install the USB DCD driver */
  #if BSPCFG_ENABLE_USBDCD
  _kusb_dcd_polled_install("usbdcd:", &_bsp_usb_dcd_init);
  #endif

  /* Install the USB DCD driver */
  #if BSPCFG_ENABLE_IUSBDCD
  _kusb_dcd_int_install("usbdcd:", &_bsp_usb_dcd_init);
  #endif

  /* Install the CRC driver */
  #if BSPCFG_ENABLE_CRC
  CRC_init();
  #endif

  #if BSPCFG_ENABLE_SAI
  result = _io_sai_int_install(&_bsp_sai_init);
  #endif



  /* Initialize the default serial I/O */
  _io_serial_default_init();

#endif // BSPCFG_ENABLE_IO_SUBSYSTEM

  return MQX_OK;
}


/*FUNCTION*--------------------------------------------------------------------
 *
 * Function Name    : _bsp_exit_handler
 * Returned Value   : none
 * Comments         :
 *    This function is called when MQX exits
 *
 *END*-----------------------------------------------------------------------*/

void _bsp_exit_handler(void)
{
  _DCACHE_DISABLE();
  _ICACHE_DISABLE();
}

/*ISR*********************************************************************
 *
 * Function Name    : _bsp_timer_isr
 * Returned Value   : void
 * Comments         :
 *    The timer ISR is the interrupt handler for the clock tick.
 *
 *END**********************************************************************/

void _bsp_systick(pointer dummy)
{
  _time_notify_kernel();
}


/*FUNCTION*--------------------------------------------------------------------
 *
 * Function Name    : _bsp_get_hwticks
 * Returned Value   : none
 * Comments         :
 *    This function returns the number of hw ticks that have elapsed
 * since the last interrupt
 *
 *END*-----------------------------------------------------------------------*/

uint_32 _bsp_get_hwticks(pointer param)
{
  uint_32 modulo;
  uint_32 count;
  uint_32 overflow;

  overflow = 0;
  modulo = (SYST_RVR & SysTick_RVR_RELOAD_MASK) + 1;
  count = SYST_CVR & SysTick_CVR_CURRENT_MASK;

  if ( SCB_ICSR & SCB_ICSR_PENDSTSET_MASK )
  {
    /* Another full TICK period has expired... */
    count = SYST_CVR & SysTick_CVR_CURRENT_MASK;
    overflow = modulo;
  }

  /* interrupt flag is set upon 1->0 transition, not upon reload - wrap around */
  if ( count == 0 ) count = modulo;

  return (modulo - count + overflow);
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/mem_zero.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mem_zero.c$
* $Version : 3.8.4.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the functions for zeroing memory
*
*END************************************************************************/

#include "mqx_inc.h"


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _mem_zero
* Returned Value   : none
* Comments         :
*   This function zeros the specified number of bytes at the specified
* location.
*   The zeroing is optimized to avoid alignment problems, and attempts
* to zero 32bit numbers optimally
*
*END*----------------------------------------------------------------------*/

#if MQX_USE_MEM_ZERO

void _mem_zero
   (
      /* [IN] the address to start zeroing memory from */
      register pointer from_ptr,

      /* [IN] the number of bytes to zero */
      register _mem_size number_of_bytes
   )
{ /* Body */
#if MQX_USE_SMALL_MEM_ZERO
   register uint_8_ptr from8_ptr = (uint_8_ptr) from_ptr;

   if (number_of_bytes) {
      while (number_of_bytes--) {
         *from8_ptr++ = 0;
      } /* Endwhile */      
   } /* Endif */
#else
   uint_8_ptr from8_ptr = (uint_8_ptr) from_ptr;
   uint_16_ptr from16_ptr = (uint_16_ptr) from_ptr;
   register uint_32_ptr from32_ptr = (uint_32_ptr) from_ptr;
   register uint_32 loops;

   if (number_of_bytes > 3) {

      /* Try to align source on word */
      if ((uint_32)from_ptr & 1) {
         from8_ptr = (uint_8_ptr) from_ptr;
         *from8_ptr++ = 0;

         from_ptr = from8_ptr;
         --number_of_bytes;
      } /* Endif */

      /* Try to align source on longword */
      if ((uint_32)from_ptr & 2) {
         from16_ptr = (uint_16_ptr) from_ptr;

         *from16_ptr++ = 0;

         from_ptr = from16_ptr;
         number_of_bytes -= 2;
      } /* Endif */

      from32_ptr = (uint_32_ptr) from_ptr;
#if MQX_USE_BLOCK_MEM_ZERO
      /* 
      ** so lets copy longwords...
      ** to increase performance, we will do 64 bytes (16 * longwords) at once and after that jumping
      ** This consumes more RAM, more flash, but gets less instruction cycles.
      */
      for (loops = number_of_bytes >> 6; loops != 0; loops--) {
         /* copy 16 longwords */
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
         *from32_ptr++ = 0;
      } /* Endwhile */

      /* Now, write the rest of bytes */
      switch ((number_of_bytes >> 2) & 0xF) {
         case 15: *from32_ptr++ = 0;
         case 14: *from32_ptr++ = 0;
         case 13: *from32_ptr++ = 0;
         case 12: *from32_ptr++ = 0;
         case 11: *from32_ptr++ = 0;
         case 10: *from32_ptr++ = 0;
         case 9:  *from32_ptr++ = 0;
         case 8:  *from32_ptr++ = 0;
         case 7:  *from32_ptr++ = 0;
         case 6:  *from32_ptr++ = 0;
         case 5:  *from32_ptr++ = 0;
         case 4:  *from32_ptr++ = 0;
         case 3:  *from32_ptr++ = 0;
         case 2:  *from32_ptr++ = 0;
         case 1:  *from32_ptr++ = 0;
      } /* Endswitch */

#else /* MQX_USE_BLOCK_MEM_ZERO */
      for (loops = number_of_bytes >> 2; loops != 0; loops--) {
         *from32_ptr++ = 0;
      }
#endif /* MQX_USE_BLOCK_MEM_ZERO */
      from_ptr = from32_ptr;
   } /* Endif */

   /* Copy all remaining bytes */
   if (number_of_bytes & 2) {
      from16_ptr = (uint_16_ptr) from_ptr;

      *from16_ptr++ = 0;

      from_ptr = from16_ptr;
   } /* Endif */
   if (number_of_bytes & 1) {
      * (uint_8_ptr) from_ptr = 0;
   } /* Endif */
#endif
} /* Endbody */

#endif

/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_tchres.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_tchres.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definition for the baud rate for the TCHRES
*   channel
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"

#define FULL_SCALE  ((1 << 12) - 1) //12-bit ADC
#define IO_PIN_FUNC  1
#define ADC_FUNC     0

/* Initialization structure */
const TCHRES_INIT_STRUCT _bsp_tchscr_resisitve_init = {
    /* structure with pins connected to touch_screen detection */
    {
      BSP_LCD_TCHRES_X_PLUS,       /* x + gpio pin definition */
      BSP_LCD_TCHRES_X_MINUS,      /* x - gpio pin definition */
      BSP_LCD_TCHRES_Y_PLUS,       /* y + gpio pin definition */
      BSP_LCD_TCHRES_Y_MINUS,      /* y - gpio pin definition */
      {
         IO_PIN_FUNC,                 /* x + gpio mux index */
         ADC_FUNC,                    /* x + adc mux index */
         IO_PIN_FUNC,                 /* y + gpio mux index */
         ADC_FUNC,                    /* y + adc mux index */
         IO_PIN_FUNC,                 /* x - gpio mux index */
         IO_PIN_FUNC,                 /* y - gpio mux index */
      },
   },

   /* Adc limits struct */
   {
        FULL_SCALE,             /* FULL_SCALE */
        FULL_SCALE / 8,         /* X_TOUCH_MIN */
        FULL_SCALE / 8,         /* Y_TOUCH_MIN  */
       (FULL_SCALE / 8) * 7,    /* X_TOUCH_OFFSET_MAX */
       (FULL_SCALE / 8) * 7,    /* Y_TOUCH_OFFSET_MAX */
   },

   /* Touch screen adc channel X setting structure */
    BSP_LCD_X_PLUS_ADC_CHANNEL,  /* physical ADC channel */
    BSP_TCHRES_X_TRIGGER,        /* logical trigger ID that starts this ADC channel */

   /* Touch screen adc channel Y setting structure */
    BSP_LCD_Y_PLUS_ADC_CHANNEL,  /* physical ADC channel */
    BSP_TCHRES_Y_TRIGGER,        /* logical trigger ID that starts this ADC channel */
};
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_fat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_fat.c$
* $Version : 3.8.16.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   This file contains the functions that are used to modify and update
*   the FAT table on the disk.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Flush_fat_cache
* Returned Value   :  MFS error code
* Comments  :
*   Always write the FAT buffer back to the disk. Assumes the semaphore is 
*   already locked.  This function is identical to MFS_Write_back_fat, except it 
*   always works, whether or not the write cache is on.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Flush_fat_cache
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr   /*[IN] the drive on which to operate */
    )
{
#if MFSCFG_READ_ONLY
    return MFS_NO_ERROR;
#else
    _mfs_error  error_code;
    uint_32     fat_size,fat,i;

    error_code = MFS_NO_ERROR;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return error_code;
    }
#endif

    if ( drive_ptr->FAT_CACHE_DIRTY )
    {
        if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
        {
            fat_size = drive_ptr->BPB32.FAT_SIZE;
        }
        else
        {
            fat_size = drive_ptr->BPB.SECTORS_PER_FAT;
        }  

        /* Backup all copies of fat */
        for ( fat=0; (fat<drive_ptr->BPB.NUMBER_OF_FAT) && (error_code==MFS_NO_ERROR); fat++ )
        {
            for ( i=0; (i<drive_ptr->FAT_CACHE_SIZE) && (error_code==MFS_NO_ERROR); i++ )
            {
                error_code = MFS_Write_device_sector(drive_ptr, 
                    drive_ptr->FAT_START_SECTOR + drive_ptr->FAT_CACHE_START + i + (fat * fat_size), 
                    (pointer) &drive_ptr->FAT_CACHE_PTR[drive_ptr->BPB.SECTOR_SIZE*i]);
            }
        }  

        if ( error_code == MFS_NO_ERROR )
        {
            drive_ptr->FAT_CACHE_DIRTY = FALSE;
        }
    }

    return(error_code);
#endif
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Write_back_fat
* Returned Value   :  MFS error code
* Comments  :
*   Write the FAT buffer back to the disk. Assumes the semaphore is already
*   locked.
*
*END*---------------------------------------------------------------------*/
#if !MFSCFG_READ_ONLY

_mfs_error MFS_Write_back_fat
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr
    )
{

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    if ( drive_ptr->FAT_CACHE_POLICY == MFS_WRITE_THROUGH_CACHE )
    {
        return( MFS_Flush_fat_cache(drive_ptr) );
    }
    else
    {
        return( MFS_NO_ERROR );
    } 
}  

#endif

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Read_fat
* Returned Value   :  MFS error code
* Comments  :
*   Read FAT into the FAT buffer. Assumes the semaphore to be locked.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Read_fat
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32                 offset      /*[IN] the offset byte in the FAT that we are looking for */
    )
{
    uint_32     needed_sector,needed_end_sector,i;
    _mfs_error  error_code;

    error_code = MFS_NO_ERROR;
    needed_sector = offset / drive_ptr->BPB.SECTOR_SIZE;

    MFS_LOG(printf("\nRead fat: Offset = %d\n", offset));

    if ( drive_ptr->FAT_TYPE == MFS_FAT12 ) 
    {
       needed_end_sector = (offset+1)/ drive_ptr->BPB.SECTOR_SIZE;
    } 
    else 
    {
       needed_end_sector = needed_sector;
    }


    /*
    ** If the FAT fragment that we already have in memory is requested, do
    ** not update or re-read it.
    */
    if ( (needed_sector < drive_ptr->FAT_CACHE_START) || (needed_end_sector  > drive_ptr->FAT_CACHE_START + drive_ptr->FAT_CACHE_SIZE - 1) )
    {
        error_code = MFS_Flush_fat_cache(drive_ptr);
        if ( error_code )
        {
            return(error_code);
        }

        if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
        {
            if ( needed_sector > (drive_ptr->BPB32.FAT_SIZE - drive_ptr->FAT_CACHE_SIZE) )
            {
                needed_sector = drive_ptr->BPB32.FAT_SIZE - drive_ptr->FAT_CACHE_SIZE;
            }
        }
        else
        {
            if ( needed_sector > (drive_ptr->BPB.SECTORS_PER_FAT - drive_ptr->FAT_CACHE_SIZE) )
            {
                needed_sector = drive_ptr->BPB.SECTORS_PER_FAT -  drive_ptr->FAT_CACHE_SIZE;
            }
        }

        for ( i=0;i<(drive_ptr->FAT_CACHE_SIZE) && (error_code==MFS_NO_ERROR);i++ )
        {
            error_code = MFS_Read_device_sector (drive_ptr, drive_ptr->FAT_START_SECTOR + needed_sector + i,
                (pointer) &drive_ptr->FAT_CACHE_PTR[drive_ptr->BPB.SECTOR_SIZE*i]);
        }

        if ( error_code == MFS_NO_ERROR )
        {
            drive_ptr->FAT_CACHE_START = needed_sector;
            drive_ptr->FAT_CACHE_DIRTY = FALSE;
        }
    }

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_get_cluster_from_fat
* Returned Value   :  cluster number in the specified fat entry
* Comments  :
*      Get the cluster number from the FAT stored in the buffer pointed
*      to by the FAT buffer. Assumes FAT in sync and sem obtained.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_get_cluster_from_fat
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32        fat_entry,           /*[IN] FAT entry index */
    uint_32_ptr    cluster_number_ptr   /* [OUT] Error code pointer */
    )
{
    _mfs_error       error;
    uint_32          cluster_number = CLUSTER_EOF; 
    uint_32_ptr      fat_ptr;
    uchar_ptr        fat_12;
    uint_32          offset;

    if ( fat_entry > drive_ptr->LAST_CLUSTER )
    {
        error = MFS_INVALID_CLUSTER_NUMBER;
    }
    else if ( fat_entry < CLUSTER_MIN_GOOD )
    {
        error = MFS_INVALID_CLUSTER_NUMBER;
    }
    else
    {
        if ( drive_ptr->FAT_TYPE == MFS_FAT16 )
        {
            offset = fat_entry << 1;
        }
        else if ( drive_ptr->FAT_TYPE == MFS_FAT12 )
        {
            offset = fat_entry + (fat_entry >> 1);
        }
        else
        {
            offset = fat_entry << 2; 
        }  

        error = MFS_Read_fat(drive_ptr, offset);

        if ( error == MFS_NO_ERROR )
        {
            fat_ptr = (uint_32_ptr)(drive_ptr->FAT_CACHE_PTR + offset - 
                      (drive_ptr->FAT_CACHE_START*drive_ptr->BPB.SECTOR_SIZE ));

            /* Now we know where the relevant info is. (uP independent) */

            /* If it was 12-bit, MASK and shift, so
            ** we can't tell from outside this function if we're dealing w/12, 16
            ** or 32 bits. This helps speed up error checking.
            */
            if ( drive_ptr->FAT_TYPE == MFS_FAT12 )
            {
                fat_12 = (uchar_ptr) fat_ptr;

                if ( (fat_entry & 0x0001) == 0 )
                {
                    /*
                    ** For an even cluster number (on byte boundary), the lower 12
                    ** bits are the relevant ones.
                    */
                    cluster_number = ftoh0(fat_12);
                }
                else
                {
                    /*
                    ** For an odd cluster number (not on byte boundary), the
                    ** higher 12 bits are the relevant ones.
                    */
                    cluster_number = ftoh1(fat_12);
                }  

                /*
                ** Counting of clusters start with zero and the last
                ** valid cluster is CLUSTER_MAX - 1.
                */
                if ( cluster_number >= CLUSTER_MAX_12 )
                {
                    cluster_number = CLUSTER_EOF;
                }
            }
            else if ( drive_ptr->FAT_TYPE == MFS_FAT16 )
            {
                cluster_number = dtohs((uchar_ptr)fat_ptr);
                if ( cluster_number >= CLUSTER_MAX_16 )
                {
                    cluster_number = CLUSTER_EOF;
                }
                /*
                ** After reading it;
                ** If it is a 16 bit fat, the cluster number register
                ** will look like HHLL Little endian or LLHH Big endian
                */
            }
            else
            {
                cluster_number = dtohl((uchar_ptr)fat_ptr);
                if ( cluster_number >= CLUSTER_MAX_32 )
                {
                    cluster_number = CLUSTER_EOF;
                }
            }  
        }
    } 

    *cluster_number_ptr = (cluster_number & 0x0FFFFFFF);

    return error;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Put_fat
* Returned Value   :  error_code
* Comments  :
*      Write a cluster number in the specified slot of the FAT.
*      Assume FAT in sync and locked semaphore.
*END*---------------------------------------------------------------------*/

#if !MFSCFG_READ_ONLY

_mfs_error MFS_Put_fat
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32                 fat_entry,  /*[IN] FAT entry index */
    uint_32                 code        /*[IN] code to write into the FAT index */
    )
{
    uint_32_ptr      fat_ptr;
    uchar_ptr        fat_12;
    _mfs_error       error_code;
    uint_32          offset;
    uint_32          code_prev;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_NO_ERROR;

    MFS_LOG(printf("\nPut fat: Cluster = %d, code = %d\n",fat_entry,code));

    if ( fat_entry > drive_ptr->LAST_CLUSTER )
    {
        error_code = MFS_INVALID_CLUSTER_NUMBER;
    }
    else if ( fat_entry < CLUSTER_MIN_GOOD )
    {
        error_code = MFS_INVALID_CLUSTER_NUMBER;
    }
    else
    {

        if ( drive_ptr->FAT_TYPE == MFS_FAT16 )
        {
            offset = fat_entry << 1;
        }
        else if ( drive_ptr->FAT_TYPE == MFS_FAT12 )
        {
            offset = fat_entry + (fat_entry >> 1);
        }
        else
        {
            offset = fat_entry <<2;
        } 

        error_code = MFS_Read_fat(drive_ptr, offset);
        if ( error_code )
        {
            return(error_code);
        }

        fat_ptr = (uint_32_ptr)(drive_ptr->FAT_CACHE_PTR + offset - 
                  (drive_ptr->FAT_CACHE_START*drive_ptr->BPB.SECTOR_SIZE ));
        // Mark FAT cache dirty, as it is about to be changed
        drive_ptr->FAT_CACHE_DIRTY = TRUE;

        /* Now we know where the relevant info is. (uP independent) */

        /* If it was 12-bit, MASK and shift, then keeping the nibble that is
        ** not part of our code, add the relevant nibbles.
        */
        if ( drive_ptr->FAT_TYPE == MFS_FAT12 )
        {
            fat_12 = (uchar_ptr) fat_ptr;

            /*
            ** After reading it;
            ** If it is a 12 bit FAT it will look like:
            ** 0HLL (Little endian, even)  HLL0 (Little endian, odd) OR:
            ** LL0H (Big endian,  even)  L0HL (Big endian,  odd)
            ** Before transformation of the 12 bit entries, we need to swap
            ** endian if Big endian.
            */

            if ( (fat_entry & 0x0001) == 0 )
            {
                /*
                ** For an even cluster number (on byte boundary), the lower 12
                ** bits are the relevant ones.
                */
                code_prev = ftoh0(fat_12);
                htof0(fat_12,code);
            }
            else
            {
                /*
                ** For an odd cluster number (not on byte boundary), the
                ** higher 12 bits are the relevant ones.
                */
                code_prev = ftoh1(fat_12);
                htof1(fat_12,code);
            }  
        }
        else if ( drive_ptr->FAT_TYPE == MFS_FAT16 )
        {
            code_prev = dtohs((uchar_ptr)fat_ptr);
            htods((uchar_ptr)fat_ptr, code);
        }
        else
        {
            code_prev = dtohl((uchar_ptr)fat_ptr);
            htof32((uchar_ptr)fat_ptr, code);
        }

        /* Update free cluster counter */
        if ( code == CLUSTER_UNUSED && code_prev != CLUSTER_UNUSED )
        {
            /* Previously used cluster was marked as free */
            MFS_Increment_free_clusters(drive_ptr);
        }
        else if ( code != CLUSTER_UNUSED && code_prev == CLUSTER_UNUSED ) 
        {
            /* Previously unused cluster was marked as allocated */
            MFS_Decrement_free_clusters(drive_ptr);
        }          
    }  

    return(error_code);
}  

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/ftpc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpc.c$
* $Version : 3.0.5.0$
* $Date    : Apr-14-2009$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <rtcs.h>
#include <fio.h>
#include <ftpc.h>

#define FTPC_MAX_ARGS 8
extern  const FTPc_COMMAND_STRUCT FTPc_commands[];

static int_32 FTP_parse_command_line( char_ptr command_line_ptr, char_ptr argv[] )
{
   char_ptr             sptr;
   uint_32              i;
   int_32               argc;

   sptr = command_line_ptr;
   argc = 0;
   for (i=0;i<FTPC_MAX_ARGS;i++)  {
      while (*sptr && !isgraph((uchar)*sptr)) sptr++;
      if (!*sptr) {
         argv[i] = NULL;
      } else {
         argc++;
         argv[i] = sptr;
         while (*sptr && isgraph(*sptr)) sptr++;
         if (*sptr) *sptr++ = '\0';
      } 
   }
   return argc;
}

_mqx_int FTP_client(char_ptr dest)
{
   FTPc_CONTEXT_PTR  ftpc_context_ptr;
   uint_32           i;
   _mqx_int          response;

   ftpc_context_ptr = _mem_alloc_zero( sizeof( FTPc_CONTEXT_STRUCT ));
   if (ftpc_context_ptr == NULL)  {
      printf("Error, unable to allocate memory for FTP client.\n");
      return IO_ERROR;
   }

   _mem_set_type(ftpc_context_ptr, MEM_TYPE_FTPc_CONTEXT_STRUCT);

   printf("\nRTCS v%d.%02d.%02d FTP client\n",
          RTCS_VERSION_MAJOR, RTCS_VERSION_MINOR, RTCS_VERSION_REV);

   if (dest) {
      ftpc_context_ptr->ARGC = 2;
      ftpc_context_ptr->ARGV[0] = "open";
      ftpc_context_ptr->ARGV[1] = dest;
   } else  {
      ftpc_context_ptr->ARGC = 0;
   }
   
   while (!ftpc_context_ptr->EXIT) {
      if (ftpc_context_ptr->ARGC > 0) { 
         _io_strtolower(ftpc_context_ptr->ARGV[0]); 
         for (i=0; FTPc_commands[i].COMMAND;i++) { 
            if (strcmp(ftpc_context_ptr->ARGV[0], FTPc_commands[i].COMMAND) == 0)  {
               response = (*FTPc_commands[i].FTPc_FUNC)(ftpc_context_ptr, 
                  ftpc_context_ptr->ARGC, ftpc_context_ptr->ARGV);
               if (response == RTCS_ERROR)  {
                  printf("FTP connection closed.\n");
                  response = 0;
                  ftpc_context_ptr->HOSTADDR = 0;
                  ftpc_context_ptr->HANDLE = NULL;   
               } else  {
                   while ((response >= 100) && (response < 200))   {
                     response = FTP_receive_message(ftpc_context_ptr->HANDLE,stdout);
                   }
               }   
               break;   
            }
         } /* Endwhile */
   
         if (FTPc_commands[i].COMMAND == NULL)  {
           printf("Invalid command.  Type 'help' for a list of commands.\n");
         } /* Endif */
      } /* Endif */

      if( ftpc_context_ptr->EXIT)  {
         break;
      }
      
      if (ftpc_context_ptr->HOSTADDR)  {
         printf("ftp [%s]> ", ftpc_context_ptr->HOSTNAME);
      } else  {
         printf("ftp> ");
      }

      if (!fgets(ftpc_context_ptr->CMD_LINE, sizeof(ftpc_context_ptr->CMD_LINE), stdin)) {
         break;
      } /* Endif */

      if (strcmp(ftpc_context_ptr->CMD_LINE, "!") == 0)  {
         strncpy(ftpc_context_ptr->CMD_LINE,ftpc_context_ptr->HISTORY,sizeof(ftpc_context_ptr->CMD_LINE));
      } else  {
         strncpy(ftpc_context_ptr->HISTORY,ftpc_context_ptr->CMD_LINE,sizeof(ftpc_context_ptr->HISTORY));
      }

      ftpc_context_ptr->ARGC = FTP_parse_command_line(ftpc_context_ptr->CMD_LINE, &ftpc_context_ptr->ARGV[0] );

   } /* Endwhile */
   printf("FTP terminated\n");
   _mem_free(ftpc_context_ptr);

   return MQX_OK;
}
   



 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_instx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_instx.c$
* $Version : 3.6.7.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the function for installing a dynamic device
*   driver.
*
*END************************************************************************/

#include <string.h>
#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

#if MQX_USE_IO

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dev_install_ext
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a device dynamically, so tasks can fopen to it. Different from
* _io_dev_install since this function also installs an unstall function.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_dev_install_ext
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr          identifier,
  
      /* [IN] The I/O open function */
      IO_OPEN_FPTR      io_open,

      /* [IN] The I/O close function */
      IO_CLOSE_FPTR     io_close,

      /* [IN] The I/O read function */
      IO_READ_FPTR      io_read,

      /* [IN] The I/O write function */
      IO_WRITE_FPTR     io_write,

      /* [IN] The I/O ioctl function */
      IO_IOCTL_FPTR     io_ioctl,

      /* [IN] The I/O un-install function */
      IO_UNINSTALL_FPTR io_uninstall,

      /* [IN] The I/O initialization data */
      pointer           io_init_data_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   IO_DEVICE_STRUCT_PTR   dev_ptr;
#if MQX_CHECK_ERRORS
   _mqx_uint              i;
   _mqx_uint              found = 0;
#endif

   _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
   if ((io_open == NULL) || (io_close == NULL)){
      return(MQX_INVALID_PARAMETER);
   } /* Endif */

   /* Search for delimiter */
   for (i = 0; i < IO_MAXIMUM_NAME_LENGTH; i++) {
      if (identifier[i] == IO_DEV_DELIMITER) {
         found++;
      } else if (identifier[i] == '\0') {
         break;
      } /* Endif */
   } /* Endfor */
      
   /* 
   ** Return an error if more than 1 delimiter found, no delimiter was found
   ** or the identifier was composed of a single delimiter only.
   */
   if ((found != 1) || (i == 1)) {
      return(MQX_INVALID_PARAMETER);
   } /* Endif */
#endif

   _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);

#if MQX_CHECK_ERRORS
   /* Check to see if device already installed */
   dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)kernel_data->IO_DEVICES.NEXT);
   while (dev_ptr != (pointer)&kernel_data->IO_DEVICES.NEXT) {
      if (!strncmp(identifier, dev_ptr->IDENTIFIER, IO_MAXIMUM_NAME_LENGTH)) {
         _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
         return(IO_DEVICE_EXISTS);
      } /* Endif */
      dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)dev_ptr->QUEUE_ELEMENT.NEXT);
   } /* Endwhile */
#endif
   
   dev_ptr = (IO_DEVICE_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(IO_DEVICE_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL) {
      _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
      return(MQX_OUT_OF_MEMORY);
   }/* Endif */
#endif
   _mem_set_type(dev_ptr, MEM_TYPE_IO_DEVICE);
      
   dev_ptr->IDENTIFIER      = identifier;
   dev_ptr->IO_OPEN         = io_open;
   dev_ptr->IO_CLOSE        = io_close;
   dev_ptr->IO_READ         = io_read;
   dev_ptr->IO_WRITE        = io_write;
   dev_ptr->IO_IOCTL        = io_ioctl;
   dev_ptr->IO_UNINSTALL    = io_uninstall;
   dev_ptr->DRIVER_INIT_PTR = io_init_data_ptr;

   _QUEUE_ENQUEUE(&kernel_data->IO_DEVICES, dev_ptr);

   _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   return MQX_OK;

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd_poll.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd_poll.c$
* $Version : 3.7.1.0$
* $Date    : Mar-9-2011$
*
* Comments:
*
*   HTTPD os specific part implementation.
*
*END************************************************************************/

#include "httpd_mqx.h"
#include "httpd.h"
#include "httpd_prv.h"

#if HTTPDCFG_POLL_MODE

#include <select.h>



/** initialize httpd server with default configuration
 * \param root_dir < root directory structure
 * \param index_page < pointer to index page with absolut path
 * \return pointer to created server structure
 */
HTTPD_STRUCT* httpd_server_init(HTTPD_ROOT_DIR_STRUCT *root_dir, const char *index_page) {
    HTTPD_STRUCT *server = NULL;
    HTTPD_PARAMS_STRUCT *params;
    
    HTTPD_ASSERT(root_dir && index_page);
    
    params = httpd_default_params(NULL);
    if (params) {
        params->root_dir = root_dir;
        params->index_page = (char*)index_page;
        server = httpd_init(params);
    }
    
    return server;
}

/** httpd server poll
 * Main function for HTTPD which provide server functionality. This function is 
 * called from httpd task (in infinity loop) or user can call it periodicaly 
 * from user application.
 * \param server < pointer to server structure
 * \param to < timeout for poll (max time for waiting event)
 */
void httpd_server_poll(HTTPD_STRUCT *server, _mqx_int to) {
    HTTPD_SESSION_STRUCT **session;
    int si, res;
    fd_set read_set, write_set;
    struct timeval tm;
    
    HTTPD_ASSERT(server);

    if (!server)
        return;
    
    session = server->session;

    FD_ZERO(&read_set);
    FD_ZERO(&write_set);
        
    for (si = 0; si < server->params->max_ses; si++) {
        if (session[si]->valid == HTTPD_SESSION_VALID) {
            FD_SET(session[si]->sock, &read_set);
            FD_SET(session[si]->sock, &write_set);
        }
    }
    
    if (read_set.COUNT < server->params->max_ses)       // set listen socket if some session is not used
        FD_SET(server->sock, &read_set);

    tm.tv_sec = (to == -1) ? 0 : to;
    tm.tv_usec = 0;
        
    res = select(server->sock + 1, &read_set, &write_set, NULL, (to == 0) ? NULL : &tm);
        
    if (res > 0) {
        if (FD_ISSET(server->sock, &read_set)) {
            // new connection
            
            for (si = 0; si < server->params->max_ses; si++) {
                if (session[si] && session[si]->valid != HTTPD_SESSION_VALID) {
                    httpd_ses_poll(server, session[si]);
                    break;
                }
            }
        }
            
        for (si = 0; si < server->params->max_ses; si++) {
            if ((FD_ISSET(session[si]->sock, &read_set) || FD_ISSET(session[si]->sock, &write_set)) &&
                session[si]->valid == HTTPD_SESSION_VALID) {
                    
                httpd_ses_poll(server, session[si]);
            }
        }
    }
}

/** server task - httpd run in one task and poll each session
 */
static void httpd_server_task(pointer init_ptr, pointer creator) {
    HTTPD_STRUCT *server = (HTTPD_STRUCT*)init_ptr;
    
    HTTPD_ASSERT(server);
    
    if (!server)
        goto ERROR;
        
    RTCS_task_resume_creator(creator, RTCS_OK);

    while (1) {
        httpd_server_poll(server, 1);
    }
    
ERROR:
    RTCS_task_resume_creator(creator, (uint_32)RTCS_ERROR);
}

/** create httpd server task - poll mode
 * \param server < pointer to server structure
 * \return
 */
static uint_32 httpd_server_task_create(HTTPD_STRUCT *server) {
    uint_32 stack;

    HTTPD_ASSERT(server);
    
    return RTCS_task_create("httpd server", server->params->server_prio, server->params->server_stack, httpd_server_task, server);
}

/** run httpd server in poll mode
 * \param server < pointer to server structure
 * \return zero if success
 */
_mqx_int httpd_server_run(HTTPD_STRUCT *server) {
    HTTPD_ASSERT(server);
    
    if (server && httpd_server_task_create(server) == RTCS_OK)
        return 0;
    
    return -1;
}

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_SensorTSI.c<|end_filename|>
/***********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
*********************************************************************************************************************//*!
*
* @file   TSS_SensorTSI.c
*
* @brief  Contains functions to Perform the sensing to the electrodes and set the status for each electrode
*
* @version 1.0.81.0
*
* @date Sep-20-2012
*
*
***********************************************************************************************************************/

#include "TSS_SensorTSI.h"

#if TSS_DETECT_METHOD(TSI)

  #if TSS_HCS08_MCU || TSS_CFV1_MCU

    /***************** ROM & RAM Data definition *******************/

    #if TSS_N_ELECTRODES > 0
      #if TSS_DETECT_EL_METHOD(0,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(0) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 1
      #if TSS_DETECT_EL_METHOD(1,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(1) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 2
      #if TSS_DETECT_EL_METHOD(2,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(2) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 3
      #if TSS_DETECT_EL_METHOD(3,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(3) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 4
      #if TSS_DETECT_EL_METHOD(4,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(4) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 5
      #if TSS_DETECT_EL_METHOD(5,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(5) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 6
      #if TSS_DETECT_EL_METHOD(6,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(6) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 7
      #if TSS_DETECT_EL_METHOD(7,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(7) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 8
      #if TSS_DETECT_EL_METHOD(8,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(8) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 9
      #if TSS_DETECT_EL_METHOD(9,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(9) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 10
      #if TSS_DETECT_EL_METHOD(10,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(10) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 11
      #if TSS_DETECT_EL_METHOD(11,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(11) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 12
      #if TSS_DETECT_EL_METHOD(12,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(12) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 13
      #if TSS_DETECT_EL_METHOD(13,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(13) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 14
      #if TSS_DETECT_EL_METHOD(14,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(14) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 15
      #if TSS_DETECT_EL_METHOD(15,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(15) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 16
      #if TSS_DETECT_EL_METHOD(16,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(16) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 17
      #if TSS_DETECT_EL_METHOD(17,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(17) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 18
      #if TSS_DETECT_EL_METHOD(18,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(18) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 19
      #if TSS_DETECT_EL_METHOD(19,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(19) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 20
      #if TSS_DETECT_EL_METHOD(20,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(20) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 21
      #if TSS_DETECT_EL_METHOD(21,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(21) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 22
      #if TSS_DETECT_EL_METHOD(22,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(22) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 23
      #if TSS_DETECT_EL_METHOD(23,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(23) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 24
      #if TSS_DETECT_EL_METHOD(24,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(24) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 25
      #if TSS_DETECT_EL_METHOD(25,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(25) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 26
      #if TSS_DETECT_EL_METHOD(26,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(26) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 27
      #if TSS_DETECT_EL_METHOD(27,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(27) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 28
      #if TSS_DETECT_EL_METHOD(28,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(28) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 29
      #if TSS_DETECT_EL_METHOD(29,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(29) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 30
      #if TSS_DETECT_EL_METHOD(30,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(30) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 31
      #if TSS_DETECT_EL_METHOD(31,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(31) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 32
      #if TSS_DETECT_EL_METHOD(32,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(32) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 33
      #if TSS_DETECT_EL_METHOD(33,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(33) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 34
      #if TSS_DETECT_EL_METHOD(34,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(34) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 35
      #if TSS_DETECT_EL_METHOD(35,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(35) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 36
      #if TSS_DETECT_EL_METHOD(36,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(36) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 37
      #if TSS_DETECT_EL_METHOD(37,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(37) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 38
      #if TSS_DETECT_EL_METHOD(38,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(38) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 39
      #if TSS_DETECT_EL_METHOD(39,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(39) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 40
      #if TSS_DETECT_EL_METHOD(40,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(40) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 41
      #if TSS_DETECT_EL_METHOD(41,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(41) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 42
      #if TSS_DETECT_EL_METHOD(42,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(42) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 43
      #if TSS_DETECT_EL_METHOD(43,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(43) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 44
      #if TSS_DETECT_EL_METHOD(44,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(44) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 45
      #if TSS_DETECT_EL_METHOD(45,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(45) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 46
      #if TSS_DETECT_EL_METHOD(46,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(46) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 47
      #if TSS_DETECT_EL_METHOD(47,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(47) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 48
      #if TSS_DETECT_EL_METHOD(48,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(48) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 49
      #if TSS_DETECT_EL_METHOD(49,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(49) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 50
      #if TSS_DETECT_EL_METHOD(50,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(50) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 51
      #if TSS_DETECT_EL_METHOD(51,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(51) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 52
      #if TSS_DETECT_EL_METHOD(52,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(52) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 53
      #if TSS_DETECT_EL_METHOD(53,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(53) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 54
      #if TSS_DETECT_EL_METHOD(54,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(54) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 55
      #if TSS_DETECT_EL_METHOD(55,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(55) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 56
      #if TSS_DETECT_EL_METHOD(56,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(56) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 57
      #if TSS_DETECT_EL_METHOD(57,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(57) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 58
      #if TSS_DETECT_EL_METHOD(58,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(58) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 59
      #if TSS_DETECT_EL_METHOD(59,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(59) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 60
      #if TSS_DETECT_EL_METHOD(60,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(60) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 61
      #if TSS_DETECT_EL_METHOD(61,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(61) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 62
      #if TSS_DETECT_EL_METHOD(62,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(62) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 63
      #if TSS_DETECT_EL_METHOD(63,TSI)
          const TSS_TSI_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(63) };
              TSS_TSI_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

  #elif TSS_KINETIS_MCU || TSS_CFM_MCU

    /************************ Prototypes **************************/

    UINT8 TSI_MethodControl(UINT8 u8ElNum, UINT8 u8Command);

    /*******************  Modules definition **********************/

    #if TSS_DETECT_MODULE(TSI)
      #if TSS_KINETIS_MCU
        const TSS_TSI_METHOD_ROMDATA TSS_TSI_METHOD_ROMDATA_CONTEXT = {TSI_MethodControl, (UINT32*) TSI_BASE_PTR, INT_TSI-16, TSS_DETECT_AUTOTRIGGER_SOURCE_USAGE(TSI), TSS_DETECT_LOWPOWER_USAGE(TSI)}; 
      #elif TSS_CFM_MCU
        const TSS_TSI_METHOD_ROMDATA TSS_TSI_METHOD_ROMDATA_CONTEXT = {TSI_MethodControl, (UINT32*) TSI_BASE_PTR, Vtsi-16, TSS_DETECT_AUTOTRIGGER_SOURCE_USAGE(TSI), TSS_DETECT_LOWPOWER_USAGE(TSI)};
      #endif
      volatile TSS_TSI_METHOD_RAMDATA TSS_TSI_METHOD_RAMDATA_CONTEXT = {TSI_EOSF_STATE_NONE};
    #endif
    #if TSS_DETECT_MODULE(TSI0)
      #if TSS_KINETIS_MCU
        const TSS_TSI_METHOD_ROMDATA TSS_TSI0_METHOD_ROMDATA_CONTEXT = {TSI_MethodControl, (UINT32*) TSI0_BASE_PTR, INT_TSI0-16, TSS_DETECT_AUTOTRIGGER_SOURCE_USAGE(TSI0), TSS_DETECT_LOWPOWER_USAGE(TSI0)};    
      #elif TSS_CFM_MCU
        const TSS_TSI_METHOD_ROMDATA TSS_TSI0_METHOD_ROMDATA_CONTEXT = {TSI_MethodControl, (UINT32*) TSI0_BASE_PTR, Vtsi0-16, TSS_DETECT_AUTOTRIGGER_SOURCE_USAGE(TSI0), TSS_DETECT_LOWPOWER_USAGE(TSI0)};    
      #endif
      volatile TSS_TSI_METHOD_RAMDATA TSS_TSI0_METHOD_RAMDATA_CONTEXT = {TSI_EOSF_STATE_NONE};
    #endif
    #if TSS_DETECT_MODULE(TSI1)
      #if TSS_KINETIS_MCU
        const TSS_TSI_METHOD_ROMDATA TSS_TSI1_METHOD_ROMDATA_CONTEXT = {TSI_MethodControl, (UINT32*) TSI1_BASE_PTR, INT_TSI1-16, TSS_DETECT_AUTOTRIGGER_SOURCE_USAGE(TSI1), TSS_DETECT_LOWPOWER_USAGE(TSI1)};        
      #elif TSS_CFM_MCU
        const TSS_TSI_METHOD_ROMDATA TSS_TSI1_METHOD_ROMDATA_CONTEXT = {TSI_MethodControl, (UINT32*) TSI1_BASE_PTR, Vtsi1-16, TSS_DETECT_AUTOTRIGGER_SOURCE_USAGE(TSI1), TSS_DETECT_LOWPOWER_USAGE(TSI1)};    
      #endif
      volatile TSS_TSI_METHOD_RAMDATA TSS_TSI1_METHOD_RAMDATA_CONTEXT = {TSI_EOSF_STATE_NONE};
    #endif

    /***************** Method Memory Data Decoding Macros **********/

    #define TSS_GET_TSI_METHOD_DATA_CONTEXT_RESULT(memory,res)       TSS_##res##_METHOD_##memory##DATA_CONTEXT
    #define TSS_GET_TSI_METHOD_DATA_CONTEXT_CONV(memory,text)        TSS_GET_TSI_METHOD_DATA_CONTEXT_RESULT(memory,text)
    #define TSS_GET_TSI_METHOD_DATA_CONTEXT_TYPE(memory,module)      TSS_GET_TSI_METHOD_DATA_CONTEXT_CONV(memory,module)

    #define TSS_GET_TSI_METHOD_DATA_CONTEXT(memory,el)               TSS_GET_TSI_METHOD_DATA_CONTEXT_TYPE(memory, TSS_TSI_EL_MODULE_NAME(el))

    /***************** ROM & RAM Data definition *******************/

    #if TSS_N_ELECTRODES > 0
      #if TSS_DETECT_EL_METHOD(0,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,0), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,0), TSS_TSI_EL_CHANNEL_NUM(0)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 1
      #if TSS_DETECT_EL_METHOD(1,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,1), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,1), TSS_TSI_EL_CHANNEL_NUM(1)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 2
      #if TSS_DETECT_EL_METHOD(2,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,2), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,2), TSS_TSI_EL_CHANNEL_NUM(2)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 3
      #if TSS_DETECT_EL_METHOD(3,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,3), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,3), TSS_TSI_EL_CHANNEL_NUM(3)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 4
      #if TSS_DETECT_EL_METHOD(4,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,4), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,4), TSS_TSI_EL_CHANNEL_NUM(4)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 5
      #if TSS_DETECT_EL_METHOD(5,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,5), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,5), TSS_TSI_EL_CHANNEL_NUM(5)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 6
      #if TSS_DETECT_EL_METHOD(6,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,6), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,6), TSS_TSI_EL_CHANNEL_NUM(6)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 7
      #if TSS_DETECT_EL_METHOD(7,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,7), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,7), TSS_TSI_EL_CHANNEL_NUM(7)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 8
      #if TSS_DETECT_EL_METHOD(8,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,8), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,8), TSS_TSI_EL_CHANNEL_NUM(8)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 9
      #if TSS_DETECT_EL_METHOD(9,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,9), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,9), TSS_TSI_EL_CHANNEL_NUM(9)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 10
      #if TSS_DETECT_EL_METHOD(10,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,10), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,10), TSS_TSI_EL_CHANNEL_NUM(10)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 11
      #if TSS_DETECT_EL_METHOD(11,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,11), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,11), TSS_TSI_EL_CHANNEL_NUM(11)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 12
      #if TSS_DETECT_EL_METHOD(12,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,12), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,12), TSS_TSI_EL_CHANNEL_NUM(12)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 13
      #if TSS_DETECT_EL_METHOD(13,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,13), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,13), TSS_TSI_EL_CHANNEL_NUM(13)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 14
      #if TSS_DETECT_EL_METHOD(14,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,14), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,14), TSS_TSI_EL_CHANNEL_NUM(14)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 15
      #if TSS_DETECT_EL_METHOD(15,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,15), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,15), TSS_TSI_EL_CHANNEL_NUM(15)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 16
      #if TSS_DETECT_EL_METHOD(16,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,16), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,16), TSS_TSI_EL_CHANNEL_NUM(16)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 17
      #if TSS_DETECT_EL_METHOD(17,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,17), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,17), TSS_TSI_EL_CHANNEL_NUM(17)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 18
      #if TSS_DETECT_EL_METHOD(18,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,18), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,18), TSS_TSI_EL_CHANNEL_NUM(18)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 19
      #if TSS_DETECT_EL_METHOD(19,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,19), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,19), TSS_TSI_EL_CHANNEL_NUM(19)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 20
      #if TSS_DETECT_EL_METHOD(20,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,20), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,20), TSS_TSI_EL_CHANNEL_NUM(20)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 21
      #if TSS_DETECT_EL_METHOD(21,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,21), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,21), TSS_TSI_EL_CHANNEL_NUM(21)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 22
      #if TSS_DETECT_EL_METHOD(22,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,22), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,22), TSS_TSI_EL_CHANNEL_NUM(22)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 23
      #if TSS_DETECT_EL_METHOD(23,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,23), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,23), TSS_TSI_EL_CHANNEL_NUM(23)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 24
      #if TSS_DETECT_EL_METHOD(24,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,24), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,24), TSS_TSI_EL_CHANNEL_NUM(24)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 25
      #if TSS_DETECT_EL_METHOD(25,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,25), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,25), TSS_TSI_EL_CHANNEL_NUM(25)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 26
      #if TSS_DETECT_EL_METHOD(26,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,26), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,26), TSS_TSI_EL_CHANNEL_NUM(26)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 27
      #if TSS_DETECT_EL_METHOD(27,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,27), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,27), TSS_TSI_EL_CHANNEL_NUM(27)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 28
      #if TSS_DETECT_EL_METHOD(28,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,28), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,28), TSS_TSI_EL_CHANNEL_NUM(28)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 29
      #if TSS_DETECT_EL_METHOD(29,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,29), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,29), TSS_TSI_EL_CHANNEL_NUM(29)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 30
      #if TSS_DETECT_EL_METHOD(30,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,30), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,30), TSS_TSI_EL_CHANNEL_NUM(30)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 31
      #if TSS_DETECT_EL_METHOD(31,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,31), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,31), TSS_TSI_EL_CHANNEL_NUM(31)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 32
      #if TSS_DETECT_EL_METHOD(32,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,32), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,32), TSS_TSI_EL_CHANNEL_NUM(32)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 33
      #if TSS_DETECT_EL_METHOD(33,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,33), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,33), TSS_TSI_EL_CHANNEL_NUM(33)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 34
      #if TSS_DETECT_EL_METHOD(34,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,34), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,34), TSS_TSI_EL_CHANNEL_NUM(34)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 35
      #if TSS_DETECT_EL_METHOD(35,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,35), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,35), TSS_TSI_EL_CHANNEL_NUM(35)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 36
      #if TSS_DETECT_EL_METHOD(36,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,36), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,36), TSS_TSI_EL_CHANNEL_NUM(36)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 37
      #if TSS_DETECT_EL_METHOD(37,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,37), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,37), TSS_TSI_EL_CHANNEL_NUM(37)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 38
      #if TSS_DETECT_EL_METHOD(38,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,38), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,38), TSS_TSI_EL_CHANNEL_NUM(38)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 39
      #if TSS_DETECT_EL_METHOD(39,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,39), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,39), TSS_TSI_EL_CHANNEL_NUM(39)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 40
      #if TSS_DETECT_EL_METHOD(40,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,40), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,40), TSS_TSI_EL_CHANNEL_NUM(40)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 41
      #if TSS_DETECT_EL_METHOD(41,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,41), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,41), TSS_TSI_EL_CHANNEL_NUM(41)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 42
      #if TSS_DETECT_EL_METHOD(42,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,42), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,42), TSS_TSI_EL_CHANNEL_NUM(42)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 43
      #if TSS_DETECT_EL_METHOD(43,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,43), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,43), TSS_TSI_EL_CHANNEL_NUM(43)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 44
      #if TSS_DETECT_EL_METHOD(44,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,44), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,44), TSS_TSI_EL_CHANNEL_NUM(44)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 45
      #if TSS_DETECT_EL_METHOD(45,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,45), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,45), TSS_TSI_EL_CHANNEL_NUM(45)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 46
      #if TSS_DETECT_EL_METHOD(46,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,46), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,46), TSS_TSI_EL_CHANNEL_NUM(46)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 47
      #if TSS_DETECT_EL_METHOD(47,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,47), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,47), TSS_TSI_EL_CHANNEL_NUM(47)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 48
      #if TSS_DETECT_EL_METHOD(48,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,48), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,48), TSS_TSI_EL_CHANNEL_NUM(48)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 49
      #if TSS_DETECT_EL_METHOD(49,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,49), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,49), TSS_TSI_EL_CHANNEL_NUM(49)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 50
      #if TSS_DETECT_EL_METHOD(50,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,50), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,50), TSS_TSI_EL_CHANNEL_NUM(50)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 51
      #if TSS_DETECT_EL_METHOD(51,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,51), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,51), TSS_TSI_EL_CHANNEL_NUM(51)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 52
      #if TSS_DETECT_EL_METHOD(52,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,52), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,52), TSS_TSI_EL_CHANNEL_NUM(52)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 53
      #if TSS_DETECT_EL_METHOD(53,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,53), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,53), TSS_TSI_EL_CHANNEL_NUM(53)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 54
      #if TSS_DETECT_EL_METHOD(54,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,54), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,54), TSS_TSI_EL_CHANNEL_NUM(54)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 55
      #if TSS_DETECT_EL_METHOD(55,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,55), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,55), TSS_TSI_EL_CHANNEL_NUM(55)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 56
      #if TSS_DETECT_EL_METHOD(56,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,56), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,56), TSS_TSI_EL_CHANNEL_NUM(56)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 57
      #if TSS_DETECT_EL_METHOD(57,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,57), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,57), TSS_TSI_EL_CHANNEL_NUM(57)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 58
      #if TSS_DETECT_EL_METHOD(58,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,58), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,58), TSS_TSI_EL_CHANNEL_NUM(58)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 59
      #if TSS_DETECT_EL_METHOD(59,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,59), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,59), TSS_TSI_EL_CHANNEL_NUM(59)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 60
      #if TSS_DETECT_EL_METHOD(60,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,60), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,60), TSS_TSI_EL_CHANNEL_NUM(60)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 61
      #if TSS_DETECT_EL_METHOD(61,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,61), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,61), TSS_TSI_EL_CHANNEL_NUM(61)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 62
      #if TSS_DETECT_EL_METHOD(62,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,62), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,62), TSS_TSI_EL_CHANNEL_NUM(62)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    #if TSS_N_ELECTRODES > 63
      #if TSS_DETECT_EL_METHOD(63,TSI)
        const TSS_TSI_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { &TSS_GET_TSI_METHOD_DATA_CONTEXT(ROM,63), &TSS_GET_TSI_METHOD_DATA_CONTEXT(RAM,63), TSS_TSI_EL_CHANNEL_NUM(63)};
              TSS_TSI_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    /***************************************************************************//*!
    *                                 Types
    ****************************************************************************/

    /* TSI Recalibration Struct */

    typedef struct {
      UINT8 u8TSIPS;
      UINT8 u8TSIExtChrg;
      UINT16 u16Distance;
    } TSI_CALIBRATION;
    
    /***************************************************************************//*!
    *        Table for calculation of Internal Reference OSC Current
    ****************************************************************************/
     #if (TSS_TSI_VERSION == 1)
    const UINT8 u8RefChrgCalcTable[8][8] = {
      {10, 15, 20, 25, 30, 40, 50, 60},
      {12, 18, 24, 30, 36, 48, 60, 72},
      {14, 21, 28, 35, 42, 56, 70, 84},
      {16, 24, 32, 40, 48, 64, 80, 96},
      {18, 27, 36, 45, 54, 72, 90, 108},
      {20, 30, 40, 50, 60, 80, 100, 120},
      {22, 33, 44, 55, 66, 88, 110, 132},
      {24, 36, 48, 60, 72, 96, 120, 144}
    };
    #endif
    /************************** Prototypes ***************************/

    UINT8 TSI_InitModule(TSS_TSI_MemMapPtr psModuleStruct);
    UINT8 TSI_SetNSamples(TSS_TSI_MemMapPtr psModuleStruct);
    UINT8 TSI_InitLowPower(TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct);
    UINT8 TSI_InitPEN(TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct);
    UINT8 TSI_Recalibrate(TSS_TSI_MemMapPtr psModuleStruct, TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct);
    UINT8 TSI_InitThresholds(TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct);
    UINT8 TSI_InitTrigger(TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct, TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct);
    UINT8 TSI_ReadCounter(TSS_TSI_ELECTRODE_ROMDATA *psElectrodeROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct, TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct);

    /***************************************************************************//*!
    *
    * @brief  Control function for TSI General Initialization
    *
    * @param  psModuleStruct - Specification of TSI module
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_InitModule(TSS_TSI_MemMapPtr psModuleStruct)
    {
      UINT8 u8result = TSS_INIT_STATUS_OK;

      /* GENCS Settings */
      psModuleStruct->GENCS = 0; /* Erase GENCS - Turn OFF TSI*/
      /* Low Power TSI definition */
#if (TSS_TSI_VERSION==1) || (TSS_TSI_VERSION==2)
      psModuleStruct->GENCS |= TSI_GENCS_LPCLKS(TSS_TSI_LPCLKS);        /* Set Low Power Mode Clock Source 0 = LPOCLK, 1 = VLPOSCCLK */
#endif
      /* SCANC Settings */
      psModuleStruct->SCANC = 0; /* Erase SCANC */
      /* Active Mode Clock Settings */
      psModuleStruct->SCANC |= TSI_SCANC_AMCLKS(TSS_TSI_AMCLKS);        /* Set Input Active Mode Clock Source - Set by the user 0 = BUSclk, 1 = MCGIRCLK, 2 = OSCERCLK, 3 - NA */ 
      psModuleStruct->SCANC |= TSI_SCANC_AMPSC(TSS_TSI_AMPSC);          /* Set Input Active Mode Clock Prescaler - Set by the user 1 = divide 1, 7 = divide 128 */
    #if (TSS_TSI_VERSION==1)
      psModuleStruct->SCANC |= TSI_SCANC_AMCLKDIV(TSS_TSI_AMCLKDIV);    /* Set Input Active Mode Clock Divider - Set by the user 0 = divide 1, 1 = divide 2048 */
      /* Both OSC settings */
      psModuleStruct->SCANC |= TSI_SCANC_DELVOL(TSS_TSI_DELVOL);        /* Delta Voltage  settings for ElOSC and RefOSC 0 = 100mV, 7 = 600mV */
      /* TSI RefOSC definitions */
      psModuleStruct->SCANC |= TSI_SCANC_CAPTRM(TSS_TSI_SCANC_CAPTRM);        /* Internal Capacitance Trim value 0=0.5pF,7=1.2pF */
    #endif
    #if (TSS_TSI_VERSION==2)
      psModuleStruct->SCANC |= TSI_SCANC_REFCHRG(TSS_TSI_SCANC_REFCHRG); /* Internal Ref OSC Charge Current 0= 1uA, 16 = 32uA */
    #elif (TSS_TSI_VERSION==3)
      psModuleStruct->SCANC |= TSI_SCANC_REFCHRG(TSS_TSI_SCANC_REFCHRG); /* Internal Ref OSC Charge Current 0= 0.5uA, 7 = 64uA */
      psModuleStruct->SCANC |= TSI_SCANC_DVOLT(TSS_TSI_DVOLT);           /* Voltage Rails */
    #elif (TSS_TSI_VERSION==1)
      psModuleStruct->SCANC |= TSI_SCANC_REFCHRG(TSS_CALC_TSI_REFCHRG_TABLE); /* Internal Ref OSC Charge Current 0= 1uA, 31 = 32uA */ 
    #endif
      return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Control function for TSI Number of Samples Settings
    *
    * @param  psModuleStruct - Specification of TSI module
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_SetNSamples(TSS_TSI_MemMapPtr psModuleStruct)
    {
      UINT8 u8result = TSS_INIT_STATUS_OK;
      UINT8 u8NSamples;

      psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK;          /* Turn OFF TSI Module*/;
      psModuleStruct->GENCS &= ~TSI_GENCS_NSCN_MASK;           /* Erase NSCN */
      /* Number of Samples settings */
      u8NSamples = tss_CSSys.NSamples;
      psModuleStruct->GENCS |= TSI_GENCS_NSCN(u8NSamples-1u);  /* Number of Consecutive Scans per Electrode 0 = 1 scan, 32 = 32 scans*/

      return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Control function for TSI Low Power Settings
    *
    * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
    *         psModuleStruct - Specification of TSI module
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_InitLowPower(TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct)
    {
      UINT8 u8result = TSS_INIT_STATUS_OK;
      UINT8 u8LowPowerScanPeriod;

      psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK; /* Turn OFF TSI Module*/;
#if (TSS_TSI_VERSION==1) || (TSS_TSI_VERSION==2)
      psModuleStruct->GENCS &= ~TSI_GENCS_LPSCNITV_MASK; /* Erase LPSCNITV */
#endif
      if (psMethodROMDataStruct->tsi_u8LowPowerControlSource == 1u) /* This TSI module is Low Power Control source */
      {
        /* Low Power TSI definition */
        u8LowPowerScanPeriod = tss_CSSys.LowPowerScanPeriod;
#if (TSS_TSI_VERSION==1) || (TSS_TSI_VERSION==2) 
        psModuleStruct->GENCS |= TSI_GENCS_LPSCNITV(u8LowPowerScanPeriod);   /* Setup TSI Low Power Mode Scan Interval 0 = 1ms - 15 = 500 ms */
#endif
        if (tss_CSSys.SystemConfig.LowPowerEn)
        {
          psModuleStruct->GENCS |= TSI_GENCS_STPE_MASK;     /* TSI Stop Enable while in Low Power Mode (0 = Disable TSI when in LPM, 1 = Allow run of TSI in LPM) */
        } else {
          psModuleStruct->GENCS &= ~TSI_GENCS_STPE_MASK;    /* TSI Stop Enable while in Low Power Mode (0 = Disable TSI when in LPM, 1 = Allow run of TSI in LPM) */
        }
        u8result |= TSS_INIT_STATUS_LOWPOWER_SET;           /* For Indication of state if LowPower was set */
      } else {
        /* Low Power TSI definition */
#if (TSS_TSI_VERSION==1) || (TSS_TSI_VERSION==2)        
    	psModuleStruct->GENCS |= TSI_GENCS_LPSCNITV(0u);   /* Setup TSI Low Power Mode Scan Interval 0 = 1ms - 15 = 500 ms */
#endif
    	psModuleStruct->GENCS &= ~TSI_GENCS_STPE_MASK;    /* TSI Stop Enable while in Low Power Mode (0 = Disable TSI when in LPM, 1 = Allow run of TSI in LPM) */
      }

      return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Control function for TSI Pin Enable Settings
    *
    * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
    *         psModuleStruct - Specification of TSI module
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_InitPEN(TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct)
    {
      UINT8 u8result = TSS_INIT_STATUS_OK;
      UINT8 u8ElCounter;
      UINT16 u16Temp;

	  psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK; /* Turn OFF TSI Module if TSI was enabled */
	
      /* PEN Clearing */
      if (tss_CSSys.SystemConfig.ProximityEn || tss_CSSys.SystemConfig.LowPowerEn)
      {
        u16Temp = (1u << ((TSS_TSI_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[tss_CSSys.LowPowerElectrode]))->tsi_cu32ChannelNum);
        psModuleStruct->PEN &= (TSI_PEN_LPSP_MASK | u16Temp);
      } else {
        for(u8ElCounter = 0u; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) /* Find all with the same module */
        {
          if ((TSS_GENERIC_METHOD_ROMDATA*) psMethodROMDataStruct == (TSS_GENERIC_METHOD_ROMDATA *)((TSS_GENERIC_ELECTRODE_ROMDATA *)tss_acp8ElectrodeROMData[u8ElCounter])->gen_cpsMethodROMData)
          {
            /* Disable Standard Electrode */
            if (!(tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter % 8u))))
            {
              if ((psModuleStruct->PEN & (1u << ((TSS_TSI_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsi_cu32ChannelNum)) != 0u)
              {                
                /* If the Electrode is enabled then disable Electrode */
                psModuleStruct->PEN &= ~(1u << ((TSS_TSI_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsi_cu32ChannelNum);
              }
            }
          }
        }
      }
      /* PEN Enabling - The loop must be performed twice because one PEN can be assigned to more TSS electrodes */
      for(u8ElCounter = 0u; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) /* Find all with the same module */
      {
    	if ((TSS_GENERIC_METHOD_ROMDATA*) psMethodROMDataStruct == (TSS_GENERIC_METHOD_ROMDATA *)((TSS_GENERIC_ELECTRODE_ROMDATA *)tss_acp8ElectrodeROMData[u8ElCounter])->gen_cpsMethodROMData)
        {
            /* Enable Standard Electrode */
            if (tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter % 8u)))
            {
              if ((psModuleStruct->PEN & (1u << ((TSS_TSI_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsi_cu32ChannelNum)) == 0u)
              {
                /* If the Electrode is disabled then Enable  Electrode */
                psModuleStruct->PEN |= (1u << ((TSS_TSI_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->tsi_cu32ChannelNum);
              }
            }
          }
        }
	  
    psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK; /* Turn ON TSI Module if TSI was disabled */   
    
	return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Control function for TSI Recalibration
    *
    * @param  psModuleStruct - Specification of TSI module
	*         *psMethodRAMDataStruct - Specificcation of RAMDATA Struct
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    #if ((TSS_TSI_EXTCHRG_RANGE != 1) || (TSS_TSI_PS_RANGE != 1) || defined(TSS_ONPROXIMITY_CALLBACK))
    UINT8 TSI_Recalibrate(TSS_TSI_MemMapPtr psModuleStruct, TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct)
    {
      TSI_CALIBRATION FinalTSICalibration;
      TSI_CALIBRATION FinalTSICalibrationBelow;
      TSI_CALIBRATION TempTSICalibration;
      TSI_CALIBRATION OldTSICalibration;
      
      UINT8 u8result = TSS_INIT_STATUS_OK;
      UINT16 u16ElCounter;
      UINT8 u8Counter;
      UINT8 u8TSIPSTemp;
      UINT8 u8TSIExtChrgTemp;
      UINT8 u8CalibrationComplete;
      UINT16 u16CapSampleTemp;
      UINT8 u8Iteration;
      UINT16 u16ResolutionValue;
      UINT8 u8EXTCHRGRange;
      UINT8 u8PSHighLimit;
      UINT16 u16CapSampleAverage;
      UINT8 u8FinalTSICalibrationFound;
      UINT8 u8Found;
      
      /* Save previous TSI Calibration */
      OldTSICalibration.u8TSIPS = (UINT8) ((psModuleStruct->GENCS & TSI_GENCS_PS_MASK) >> TSI_GENCS_PS_SHIFT);
      OldTSICalibration.u8TSIExtChrg = (UINT8) ((psModuleStruct->SCANC & TSI_SCANC_EXTCHRG_MASK) >> TSI_SCANC_EXTCHRG_SHIFT);
      /* Init TSI for Auto calibration */
      psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK; /* Turn OFF TSI Module */
      psModuleStruct->GENCS &= ~TSI_GENCS_TSIIE_MASK; /* Disable Interrupts */
      #if (TSS_TSI_VERSION==1)
        /* Set Default Thresholds on all electrodes */
        for(u16ElCounter = 0u; u16ElCounter < 16u; u16ElCounter++) /* Find all with the same module */
        {
          /* Set Universal Threshold Values for all electrodes */
          psModuleStruct->THRESHOLD[u16ElCounter] = TSI_THRESHOLD_HTHH(TSS_TSI_DEFAULT_HIGH_THRESHOLD) | TSI_THRESHOLD_LTHH(TSS_TSI_DEFAULT_LOW_THRESHOLD);
        }
      #elif (TSS_TSI_VERSION==2) || (TSS_TSI_VERSION==3)
        /* Set Universal Threshold Values for all electrodes */
        psModuleStruct->THRESHOLD = TSI_THRESHOLD_HTHH(TSS_TSI_DEFAULT_HIGH_THRESHOLD ) | TSI_THRESHOLD_LTHH(TSS_TSI_DEFAULT_LOW_THRESHOLD );
      #endif
  
        /* Set Variables */
        if (tss_CSSys.SystemConfig.ProximityEn)
        {
          u16ResolutionValue = TSS_TSI_PROX_RESOLUTION_VALUE;
          u8EXTCHRGRange = TSS_TSI_PROX_EXTCHRG_RANGE;
          u8PSHighLimit = TSS_TSI_PROX_PS_HIGH_LIMIT;        
          u8TSIPSTemp = TSS_TSI_PROX_PS_LOW_LIMIT;
        }else{
          u16ResolutionValue = TSS_TSI_RESOLUTION_VALUE;
          u8EXTCHRGRange = TSS_TSI_EXTCHRG_RANGE;
          u8PSHighLimit = TSS_TSI_PS_HIGH_LIMIT;
          u8TSIPSTemp = TSS_TSI_PS_LOW_LIMIT;
        }
  
        /* Do Autocalibration */
        FinalTSICalibration.u16Distance = 0xFFFFu;
        FinalTSICalibrationBelow.u16Distance = 0xFFFFu;
        u8FinalTSICalibrationFound = 0u;
        do {
          /* Set initial EXTHCRG */
          u8TSIExtChrgTemp = TSS_TSI_EXTCHRG_LOW_LIMIT + (TSS_TSI_EXTCHRG_RANGE / 2u);        
          u8Iteration = 0u;
          TempTSICalibration.u16Distance = 0xFFFFu; 
          u8Found = 0u;
          do {
            /* Increase iteration level */
            u8Iteration += 1u;

            /* Set TSI registers for Single measurement */
            psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK;      /* Disable TSI */
            psModuleStruct->GENCS &= ~TSI_GENCS_PS_MASK;         /* Erase PS */
            psModuleStruct->GENCS |= TSI_GENCS_PS(u8TSIPSTemp);  /* Set Prescaler for Electrode OSC - Set by the user 1 = divide 1, 7 = divide 128 */
            psModuleStruct->SCANC &= ~TSI_SCANC_EXTCHRG_MASK;    /* Erase ExtChrg */
            psModuleStruct->SCANC |= TSI_SCANC_EXTCHRG(u8TSIExtChrgTemp); /* External OSC Charge Current 0= 1uA, 31 = 32uA */
            /* Start Measurement */
            psModuleStruct->GENCS &= ~TSI_GENCS_STM_MASK;  /* Set Scan Trigger Mode (0 = SW Trigger, 1 = Periodical Scan) */
            psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;
            psModuleStruct->GENCS |= TSI_GENCS_SWTS_MASK;
            #ifdef _TSS_TEST
              _TSS_TSIGEN_ON;                                       /* Start generator for test purpose */
            #endif
            do {
            /* Measurement Running */
            } while (!(psModuleStruct->GENCS & TSI_GENCS_EOSF_MASK)); /* If TSI End of Scan Flag is reported*/
            #ifdef _TSS_TEST
              _TSS_TSIGEN_OFF;                                      /* Stop generator */
            #endif
            /* Wait for data ready */
            for(u8Counter = 0u; u8Counter < 20u; u8Counter++)        /* Delay */
            {
              #if defined(__ARMCC_VERSION)
                __nop();
              #else
                asm ("NOP");
              #endif 
            }
            #if (TSS_TSI_VERSION==1)
              /* Erase all Fault Flags for sure */
              psModuleStruct->STATUS = 0xFFFFFFFFu;
            #elif (TSS_TSI_VERSION==2) || (TSS_TSI_VERSION==3)
              psModuleStruct->GENCS |= TSI_GENCS_EXTERF_MASK;
            #endif
            /* Check if all electrodes has proper Counter value */
            u8CalibrationComplete = 1u;
            u16CapSampleAverage = 0u;
            for(u16ElCounter = 0u; u16ElCounter < 16u; u16ElCounter++) /* Go through all enabled pins */
            {
                /* Consider just enabled electrodes */
                if (psModuleStruct->PEN & (1u << u16ElCounter))
                {
                  /* Read TSI Counter */
                #if TSS_KINETIS_MCU   
                  u16CapSampleTemp = (psModuleStruct->tsi_u16Counter[u16ElCounter]);
                #elif TSS_CFM_MCU
                  u16CapSampleTemp = (psModuleStruct->tsi_u16Counter[(u16ElCounter % 2) ? u16ElCounter-1u : u16ElCounter+1u]);   /* Big endian */
                #endif
                
                   if (u16CapSampleTemp < u16ResolutionValue)
                   {
                     u8CalibrationComplete = 0u; /* Capacitance value is small */
                   }
                   if (u16CapSampleAverage == 0u)
                   {
                     u16CapSampleAverage = u16CapSampleTemp;
                   } else {
                     u16CapSampleAverage = (u16CapSampleAverage >> 1u) + (u16CapSampleTemp >> 1u);
                   }
                }
            }

            /* Evaluate Measurement - Reuse of u16ECounter */
            if(u16CapSampleAverage > u16ResolutionValue )
            {
              u16ElCounter = u16CapSampleAverage - u16ResolutionValue;
            } else {
              u16ElCounter = u16ResolutionValue - u16CapSampleAverage;
            }
            
            /* All samples > resolution AND (Avarage > resolution OR already found and tune it) */
            if ((u8CalibrationComplete == 1u ) && ((u16CapSampleAverage > u16ResolutionValue) || (u8Found && (TempTSICalibration.u16Distance >= u16ElCounter)))) 
            {
              TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
              TempTSICalibration.u8TSIPS = u8TSIPSTemp;
              TempTSICalibration.u16Distance = u16ElCounter;
              u8Found++; /* Match for set PS found */ 
            } else if (TempTSICalibration.u16Distance >= u16ElCounter && (u8Found ==0))  
            {
              TempTSICalibration.u8TSIExtChrg = u8TSIExtChrgTemp;
              TempTSICalibration.u8TSIPS = u8TSIPSTemp;
              TempTSICalibration.u16Distance = u16ElCounter;
            }
            /* Change ExtCharge within the interval */
            if(u8CalibrationComplete == 1u)
            {
              u8TSIExtChrgTemp += ((u8EXTCHRGRange / 2u) >> u8Iteration);
            }
            else
            {
              u8TSIExtChrgTemp -= ((u8EXTCHRGRange / 2u) >> u8Iteration);
            }
          } while (((u8EXTCHRGRange / 2u) >> u8Iteration) > 0u);           
          /* The value only if distance is lower and was found with sufficient resolution */
          if ((FinalTSICalibration.u16Distance >= TempTSICalibration.u16Distance) && (u8Found > 0))
          {
            FinalTSICalibration.u8TSIPS = TempTSICalibration.u8TSIPS;
            FinalTSICalibration.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
            FinalTSICalibration.u16Distance = TempTSICalibration.u16Distance;
            u8FinalTSICalibrationFound++;
          } else if ((FinalTSICalibrationBelow.u16Distance >= TempTSICalibration.u16Distance) && (u8FinalTSICalibrationFound == 0))
          {
            /* Calibration not sufficient to the set resolution */
            FinalTSICalibrationBelow.u8TSIPS = TempTSICalibration.u8TSIPS;
            FinalTSICalibrationBelow.u8TSIExtChrg = TempTSICalibration.u8TSIExtChrg;
            FinalTSICalibrationBelow.u16Distance = TempTSICalibration.u16Distance;
          }
            
          u8TSIPSTemp++; /* Increment PS current */
        } while (u8TSIPSTemp < (u8PSHighLimit + 1u)); 
  
        /* Check if searching was succesful */
        if (u8FinalTSICalibrationFound)
        {
          psMethodRAMDataStruct->tsi_au16Resolution = u16ResolutionValue;
        } else {
          FinalTSICalibration.u8TSIPS = FinalTSICalibrationBelow.u8TSIPS;
          FinalTSICalibration.u8TSIExtChrg = FinalTSICalibrationBelow.u8TSIExtChrg;
          /* Reuse of u8Counter & u16ElCounter */
          u8Counter = 0u;  
          u16ElCounter = u16ResolutionValue - FinalTSICalibrationBelow.u16Distance;
          /* Determine TSS Resolution (highest bit set) */
          while (u16ElCounter >> u8Counter)
          {
            u8Counter++;
          }
          /* Store the present resolution value */    
          psMethodRAMDataStruct->tsi_au16Resolution = (1u << (u8Counter - 1u));
        }
        /* Set Final Found values */
        psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK;   /* Disable TSI */
        psModuleStruct->GENCS &= ~TSI_GENCS_PS_MASK;      /* Erase PS */
        psModuleStruct->GENCS |= TSI_GENCS_PS(FinalTSICalibration.u8TSIPS);       /* Set Prescaler for Electrode OSC - Set by the user 1 = divide 1, 7 = divide 128 */
        psModuleStruct->SCANC &= ~TSI_SCANC_EXTCHRG_MASK; /* Erase ExtChrg */
        psModuleStruct->SCANC |= TSI_SCANC_EXTCHRG(FinalTSICalibration.u8TSIExtChrg);  /* External OSC Charge Current 0= 1uA, 31 = 32uA */
        /* Save Value for Proximity function */
      #ifdef TSS_ONPROXIMITY_CALLBACK
        if (tss_CSSys.SystemConfig.ProximityEn)
        {
          tss_u16CapSample = FinalTSICalibration.u16Distance + u16ResolutionValue;
        }
      #endif  
        /* Indication of changed configuration */
        if ((OldTSICalibration.u8TSIPS != FinalTSICalibration.u8TSIPS) || (OldTSICalibration.u8TSIExtChrg != FinalTSICalibration.u8TSIExtChrg))
        {
          /* Save result */  
          u8result |= TSS_INIT_STATUS_CALIBRATION_CHANGED;
        }

        return u8result;
    }
    #else
    UINT8 TSI_Recalibrate(TSS_TSI_MemMapPtr psModuleStruct, TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct)
    {
         UINT8 u8result = TSS_INIT_STATUS_OK;
        
         /* Set Final Found values */
         psModuleStruct->STATUS = 0xFFFFFFFFu;
         psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK;   /* Disable TSI */
         psModuleStruct->GENCS &= ~TSI_GENCS_PS_MASK;      /* Erase PS */
         psModuleStruct->SCANC &= ~TSI_SCANC_EXTCHRG_MASK; /* Erase ExtChrg */
         /* Set configuration directly */
         psModuleStruct->GENCS |= TSI_GENCS_PS(TSS_TSI_PS_HIGH_LIMIT);       /* Set Prescaler for Electrode OSC - Set by the user 1 = divide 1, 7 = divide 128 */
         psModuleStruct->SCANC |= TSI_SCANC_EXTCHRG(TSS_TSI_EXTCHRG_HIGH_LIMIT);  /* External OSC Charge Current 0= 1uA, 31 = 32uA */
         
         psMethodRAMDataStruct->tsi_au16Resolution = TSS_TSI_RESOLUTION_VALUE;  /* Store the resolution value */ 
         
         return u8result;
    }
    #endif

    /***************************************************************************//*!
    *
    * @brief  Control function for TSI Thresholds Settings
    *
    * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
    *         psModuleStruct - Specification of TSI module
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_InitThresholds(TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct)
    {
      UINT8 u8result = TSS_INIT_STATUS_OK;
      UINT8 u8LowPowerEl;
      UINT8 u8Counter;
      UINT16 u16CapSampleTemp;
      UINT8 u8LowPowerElectrodeSensitivity;
      UINT8 u8ChannelNum;

      psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK; /* Turn OFF TSI Module */
      psModuleStruct->GENCS &= ~TSI_GENCS_TSIIE_MASK; /* Disable Interrupts */
      #if (TSS_TSI_VERSION == 1)
        /*** Set Default Low Power Thresholds for all electrodes within module***/
        for(u8Counter = 0u; u8Counter < 16u; u8Counter++) /* Find all within the same module */
        {
          /* Set Universal Threshold Values for all electrodes */
          psModuleStruct->THRESHOLD[u8Counter] = TSI_THRESHOLD_HTHH(TSS_TSI_DEFAULT_HIGH_THRESHOLD) | TSI_THRESHOLD_LTHH(TSS_TSI_DEFAULT_LOW_THRESHOLD);
        }
      #elif (TSS_TSI_VERSION == 2) || (TSS_TSI_VERSION==3)
        /* Set Universal Threshold Values for all electrodes */
        psModuleStruct->THRESHOLD = TSI_THRESHOLD_HTHH(TSS_TSI_DEFAULT_HIGH_THRESHOLD ) | TSI_THRESHOLD_LTHH(TSS_TSI_DEFAULT_LOW_THRESHOLD );
      #endif
      /* If Module is selected for Low Power Control do following */
      if (psMethodROMDataStruct->tsi_u8LowPowerControlSource == 1u) /* This TSI module is Low Power Control source */
      {
        u8LowPowerEl = tss_CSSys.LowPowerElectrode;
        /* Check if Low Power Electrode is not out of range */        
        if (u8LowPowerEl < TSS_N_ELECTRODES)/* This electrode is selected as source for Low Power Control */
        {
          /* Check if low power electrode is member of the module */
          if ((TSS_GENERIC_METHOD_ROMDATA *) psMethodROMDataStruct == (TSS_GENERIC_METHOD_ROMDATA *)((TSS_GENERIC_ELECTRODE_ROMDATA *)tss_acp8ElectrodeROMData[u8LowPowerEl])->gen_cpsMethodROMData)
          {
            /* Get Channel Num */
            u8ChannelNum = (UINT8) (((TSS_TSI_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8LowPowerEl]))->tsi_cu32ChannelNum);
            /* Check if PEN is enabled */                                      
            if (psModuleStruct->PEN & (1u << u8ChannelNum))
            {
              /******** Low Power Threshold Settings *********/
              /* Init TSI registers for measurement */
              psModuleStruct->GENCS &= ~TSI_GENCS_STM_MASK;  /* Set Scan Trigger Mode (0 = SW Trigger, 1 = Periodical Scan) */
              psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;
              psModuleStruct->GENCS |= TSI_GENCS_SWTS_MASK;
              #ifdef _TSS_TEST
                _TSS_TSIGEN_ON;                                      /* Start generator for test purpose */
              #endif
              do {
              /* Measurement Running */
              } while (!(psModuleStruct->GENCS & TSI_GENCS_EOSF_MASK)); /* If TSI End of Scan Flag is reported*/
              #ifdef _TSS_TEST
                _TSS_TSIGEN_OFF;                                    /* Stop generator */
              #endif
              /* Wait for data ready */
              for(u8Counter = 0u; u8Counter < 20u; u8Counter++) /* Delay */
              {
                #if defined(__ARMCC_VERSION)
                  __nop();
                #else
                  asm ("NOP");
                #endif
              }
              #if (TSS_TSI_VERSION == 1)
                /* Erase all Fault Flags for sure */
                psModuleStruct->STATUS = 0xFFFFFFFFu;
              #elif (TSS_TSI_VERSION == 2) || (TSS_TSI_VERSION == 3)
                psModuleStruct->GENCS |= TSI_GENCS_EXTERF_MASK;
              #endif
              /* Read TSI Counter */
              #if TSS_KINETIS_MCU
                u16CapSampleTemp = (psModuleStruct->tsi_u16Counter[u8ChannelNum]);
              #elif TSS_CFM_MCU
                u16CapSampleTemp = (psModuleStruct->tsi_u16Counter[(u8ChannelNum % 2) ? u8ChannelNum-1u : u8ChannelNum+1u]); /* Big endian */
              #endif
              /* Calculation of Threshold values */
              u8LowPowerElectrodeSensitivity = tss_CSSys.LowPowerElectrodeSensitivity;
              #if (TSS_TSI_VERSION == 1)
                /* Set Threshold for Low Power Wake up */
                psModuleStruct->THRESHOLD[u8ChannelNum] = TSI_THRESHOLD_HTHH(u16CapSampleTemp + u8LowPowerElectrodeSensitivity) | TSI_THRESHOLD_LTHH(TSS_TSI_DEFAULT_LOW_THRESHOLD);
              #elif (TSS_TSI_VERSION == 2) || (TSS_TSI_VERSION == 3)
                psModuleStruct->THRESHOLD = TSI_THRESHOLD_HTHH(u16CapSampleTemp + u8LowPowerElectrodeSensitivity) | TSI_THRESHOLD_LTHH(TSS_TSI_DEFAULT_LOW_THRESHOLD);
              #endif
              /*** Set Active Electrode for Low Power Mode ***/
              psModuleStruct->PEN &= ~TSI_PEN_LPSP_MASK;
              psModuleStruct->PEN |= TSI_PEN_LPSP(u8ChannelNum);
              u8result |= TSS_INIT_STATUS_LOWPOWER_ELEC_SET; /* For Indication of state if LowPower Electrode was found */
            }
          }
        }
      }

      return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Control function for TSI Trigger Settings
    *
    * @param  *psMethodROMDataStruct - Specificcation of ROMDATA Struct
    *         psModuleStruct - Specification of TSI module
    *         *psMethodRAMDataStruct - Specificcation of RAMDATA Struct
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_InitTrigger(TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct, TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct)
    {
      UINT8 u8result = TSS_INIT_STATUS_OK;
      UINT8 u8AutoTriggerModuloValue;
      #if TSS_KINETIS_MCU
        NVIC_MemMapPtr psNVICStruct = NVIC_BASE_PTR;
      #endif

      psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK; /* Turn OFF TSI Module*/;
      psModuleStruct->SCANC &= ~TSI_SCANC_SMOD_MASK;  /* Erase SMOD */
      #if (TSS_TSI_VERSION == 1)
        /* Erase all Fault Flags for sure */
        psModuleStruct->STATUS = 0xFFFFFFFFu;
      #elif (TSS_TSI_VERSION == 2) || (TSS_TSI_VERSION == 3)
        psModuleStruct->GENCS |= TSI_GENCS_EXTERF_MASK;
      #endif
      /* Trigger Setting */
      if ((psMethodROMDataStruct->tsi_u8TriggerSource == 1u) && (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)) /* This TSI module is Trigger source & Auto mode*/
      {
        /* This TSI module is Trigger source & Auto mode*/
        /* Active Mode Periodic Scan */
        u8AutoTriggerModuloValue = tss_CSSys.AutoTriggerModuloValue;
        psModuleStruct->SCANC |= TSI_SCANC_SMOD(u8AutoTriggerModuloValue); /* Active mode periodic scan period module 0 = Continue scan, Other = scan module */
        psModuleStruct->GENCS |= TSI_GENCS_STM_MASK;                       /* Set Scan Trigger Mode (0 = SW Trigger, 1 = Periodical Scan) */
        /* Indication that AutoTrigger was set correctly */
        u8result |= TSS_INIT_STATUS_AUTOTRIGGER_SET;
      } else { /* Other & ALWAYS & SW mode */
        /* Active Mode Periodic Scan */
        psModuleStruct->SCANC |= TSI_SCANC_SMOD(0u);      /* Active mode periodic scan period module 0 = Continue scan, Other = scan module */
        psModuleStruct->GENCS &= ~TSI_GENCS_STM_MASK;    /* Set Scan Trigger Mode (0 = SW Trigger, 1 = Periodical Scan) */
        u8result |= TSS_INIT_STATUS_TRIGGER_SET;          
      }
      /* Enable EOSF interrupt */
      psModuleStruct->GENCS &= ~TSI_GENCS_ERIE_MASK;  /* Error (Short&Overrun) Interrupt Enable (0 = disabled, 1 = enabled) */
      psModuleStruct->GENCS |= TSI_GENCS_ESOR_MASK;   /* End-of-Scan|Out-of-Range Interrupt Selection (0 = Out-of-Range allow, 1 = End-of-Scan allow) */
      psModuleStruct->GENCS |= TSI_GENCS_TSIIE_MASK;  /* TSI Interrupt Enable (0 = disabled, 1 = enabled) */
      #if TSS_KINETIS_MCU
        /* Enable TSI Interrupt */
        psNVICStruct->ISER[psMethodROMDataStruct->tsi_u8ModuleIRQNum >> 5u] = (1u << (psMethodROMDataStruct->tsi_u8ModuleIRQNum % 32u));
      #endif
      psMethodRAMDataStruct->tsi_eEndOfScanState = TSI_EOSF_STATE_NONE; /* Reset EndOfScanState */

      /* Setup Low Power */
      if ((tss_CSSys.SystemConfig.LowPowerEn) && (psMethodROMDataStruct->tsi_u8LowPowerControlSource == 1u))
      {
        /* Set periodic measurement mode */
        psModuleStruct->GENCS |= TSI_GENCS_STM_MASK;    /* Set Scan Trigger Mode (0 = SW Trigger, 1 = Periodical Scan) */
        /* Enable EOSF interrupt */
        psModuleStruct->GENCS &= ~TSI_GENCS_ERIE_MASK;  /* Error (Short&Overrun) Interrupt Enable (0 = disabled, 1 = enabled) */
        psModuleStruct->GENCS &= ~TSI_GENCS_ESOR_MASK;  /* Set Out of Range interrupt (0 = Out-of-Range allow, 1 = End-of-Scan allow) */
        psModuleStruct->GENCS |= TSI_GENCS_TSIIE_MASK;  /* TSI Interrupt Disable (0 = disabled, 1 = enabled) */
        #if TSS_KINETIS_MCU
          /* Enable TSI Interrupt */
          psNVICStruct->ISER[psMethodROMDataStruct->tsi_u8ModuleIRQNum >> 5u] = (1u << (psMethodROMDataStruct->tsi_u8ModuleIRQNum % 32u));
        #endif
        /* TSI enable and start to periodic measurement */
        psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;  /* TSI Enable (0 = disabled, 1 = enabled) */
        /* Indication that LowPower was set correctly */
        u8result |= TSS_INIT_STATUS_LOWPOWER_SET;       /* For Indication of state if LowPower was set */
        u8result &= ~TSS_INIT_STATUS_TRIGGER_SET;       /* Remove status that Trigger was set correctly */
        u8result &= ~TSS_INIT_STATUS_AUTOTRIGGER_SET;   /* Remove status that Auto Trigger was set correctly */
      }

      return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Initializes the modules for the sensing of the electrodes
    *
    * @param  UINT8 u8ElNum - Processed Electrode Number
    *         UINT8 u8Command - Command intended to process
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_MethodControl(UINT8 u8ElNum, UINT8 u8Command)
    {
        UINT8 u8result = TSS_INIT_STATUS_OK;
        TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct;
        TSS_TSI_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
        TSS_TSI_MemMapPtr psModuleStruct;
        TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct;

        /* Pointers Decoding */
        psElectrodeROMDataStruct = (TSS_TSI_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElNum]);
        psMethodROMDataStruct = (TSS_TSI_METHOD_ROMDATA *) (psElectrodeROMDataStruct->tsi_cpsu32MethodROMData);
        psModuleStruct = (TSS_TSI_MemMapPtr) (psMethodROMDataStruct->tsi_cpsu32Module);
        psMethodRAMDataStruct = (TSS_TSI_METHOD_RAMDATA *) (psElectrodeROMDataStruct->tsi_u8MethodRAMData);

        /************* Do TSI Init *******************/
        if (u8Command == TSS_INIT_COMMAND_INIT_MODULES)
        {
          u8result |= TSI_InitModule(psModuleStruct);
          u8result |= TSI_SetNSamples(psModuleStruct);
          u8result |= TSI_InitLowPower(psMethodROMDataStruct, psModuleStruct);
          u8result |= TSI_InitPEN(psMethodROMDataStruct, psModuleStruct);
          u8result |= TSI_Recalibrate(psModuleStruct, psMethodRAMDataStruct);
          u8result |= TSI_InitThresholds(psMethodROMDataStruct, psModuleStruct);
          u8result |= TSI_InitTrigger(psMethodROMDataStruct, psModuleStruct, psMethodRAMDataStruct);
        }
        /************* Set NSamples ***************/
        else if (u8Command == TSS_INIT_COMMAND_SET_NSAMPLES)
        {
          u8result |= TSI_SetNSamples(psModuleStruct);
          u8result |= TSI_Recalibrate(psModuleStruct, psMethodRAMDataStruct);
          u8result |= TSI_InitThresholds(psMethodROMDataStruct, psModuleStruct);
          u8result |= TSI_InitTrigger(psMethodROMDataStruct, psModuleStruct, psMethodRAMDataStruct);
        }
        /************ Low Power Init *************/
        else if (u8Command == TSS_INIT_COMMAND_INIT_LOWPOWER)
        {
          u8result |= TSI_InitLowPower(psMethodROMDataStruct, psModuleStruct);
          u8result |= TSI_InitThresholds(psMethodROMDataStruct, psModuleStruct);
          u8result |= TSI_InitTrigger(psMethodROMDataStruct, psModuleStruct, psMethodRAMDataStruct);
        }
        /************* Goto Low Power ************/
        else if (u8Command == TSS_INIT_COMMAND_GOTO_LOWPOWER)
        {
          u8result |= TSI_InitLowPower(psMethodROMDataStruct, psModuleStruct);
          u8result |= TSI_InitTrigger(psMethodROMDataStruct, psModuleStruct, psMethodRAMDataStruct);
        }
        /*************** Do Auto calibration setting of TSI EXTCHRG and TSI PS **************/
        else if (u8Command == TSS_INIT_COMMAND_RECALIBRATE)
        {
          u8result |= TSI_Recalibrate(psModuleStruct, psMethodRAMDataStruct);
          u8result |= TSI_InitThresholds(psMethodROMDataStruct, psModuleStruct);
          u8result |= TSI_InitTrigger(psMethodROMDataStruct, psModuleStruct, psMethodRAMDataStruct);
        }
        /************ Electrode Enablers & Low Power Thresholds & Low Power Electrode Specification *************/
        else if (u8Command == TSS_INIT_COMMAND_ENABLE_ELECTRODES)
        {
          u8result |= TSI_InitPEN(psMethodROMDataStruct, psModuleStruct);
        }
        /************* Triggering Init ************/
        else if (u8Command == TSS_INIT_COMMAND_INIT_TRIGGER)
        {
          u8result |= TSI_InitTrigger(psMethodROMDataStruct, psModuleStruct, psMethodRAMDataStruct);
        }
        /************* SWTrigger ************/
        if (u8Command == TSS_INIT_COMMAND_SW_TRIGGER)
        {
            psMethodRAMDataStruct->tsi_eEndOfScanState = TSI_EOSF_STATE_NONE; /* Reset EndOfScanState */
            psModuleStruct->GENCS |= TSI_GENCS_SWTS_MASK; /* Toggle SW Trigger */
            u8result |= TSS_INIT_STATUS_TRIGGER_SET;
            #ifdef _TSS_TEST
              _TSS_TSIGEN_ON;                                 /* Start generator for test purpose */
            #endif
          }

      /* Exit */

      return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Reads TSI capacitance counter and returns a status code
    *
    * @param  *psElectrodeROMDataStruct - Specificcation of electrode ROMDATA Struct
    *         psModuleStruct - Specification of TSI module
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_ReadCounter(TSS_TSI_ELECTRODE_ROMDATA *psElectrodeROMDataStruct, TSS_TSI_MemMapPtr psModuleStruct, TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct)
    {
      UINT8 u8result;

      #if (TSS_TSI_VERSION == 1)
      /* Read Status register */
      u8result = (UINT8) ((psModuleStruct->STATUS & ((1u << psElectrodeROMDataStruct->tsi_cu32ChannelNum) << 16u)) >> (psElectrodeROMDataStruct->tsi_cu32ChannelNum + 16u));
      #elif (TSS_TSI_VERSION == 2) || (TSS_TSI_VERSION == 3)
       u8result = (UINT8) (psModuleStruct->GENCS & TSI_GENCS_EXTERF_MASK);
      #endif
      /* Evaluate Status */
      if (u8result != 0u)
      {
        #if (TSS_TSI_VERSION == 1)
        psModuleStruct->STATUS |= ((1u << psElectrodeROMDataStruct->tsi_cu32ChannelNum) << 16u); /* Erase Fault Flag */
        #elif (TSS_TSI_VERSION == 2) || (TSS_TSI_VERSION == 3)
        psModuleStruct->GENCS |= TSI_GENCS_EXTERF_MASK;
        #endif
        u8result = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;
      }
      else
      {
        /* Read TSI Counter */
        #if TSS_KINETIS_MCU                
          tss_u16CapSample = (psModuleStruct->tsi_u16Counter[psElectrodeROMDataStruct->tsi_cu32ChannelNum]); /* Read TSI Counter */
        #elif TSS_CFM_MCU
          tss_u16CapSample = (psModuleStruct->tsi_u16Counter[(psElectrodeROMDataStruct->tsi_cu32ChannelNum % 2u) ? psElectrodeROMDataStruct->tsi_cu32ChannelNum-1u : psElectrodeROMDataStruct->tsi_cu32ChannelNum+1u]); /* Read TSI Counter, Big endian*/
        #endif
        /* Evaluation of the Measured Value */
        if (tss_u16CapSample > TSS_TSI_CAP_HIGH_LIMIT(psMethodRAMDataStruct->tsi_au16Resolution))
        {
          u8result = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;    /* Too High Capacity is detected */
        } else if (tss_u16CapSample > TSS_TSI_RECALIBRATION_HIGH_THRESHOLD(psMethodRAMDataStruct->tsi_au16Resolution))
        {
          u8result = TSS_SAMPLE_RECALIB_REQUEST_HICAP;   /* Re-calibration is needed */
        }else if (tss_u16CapSample < TSS_TSI_CAP_LOW_LIMIT(psMethodRAMDataStruct->tsi_au16Resolution)) 
        {  
          u8result = TSS_SAMPLE_ERROR_SMALL_CAP;         /* Too Low Capacity is detected */
        } 
        else if (tss_u16CapSample < TSS_TSI_RECALIBRATION_LOW_THRESHOLD(psMethodRAMDataStruct->tsi_au16Resolution)) 
        {  
          u8result = TSS_SAMPLE_RECALIB_REQUEST_LOCAP;   /* Re-calibration is needed */
        } else {
          u8result = TSS_SAMPLE_STATUS_OK;
        }
      }

      return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Performs a valid reading of one electrode stores the timer values
    *         and returns a status code
    *
    * @param  u8ElecNum Electrode number to be scanned
    *         u8Command Requested command
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSI_SampleElectrode(UINT8 u8ElecNum, UINT8 u8Command)
    {
      UINT8 u8ElectrodeStatus;
      UINT8 u8ElCounter;

      TSS_TSI_METHOD_ROMDATA *psMethodROMDataStruct;
      TSS_TSI_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
      TSS_TSI_METHOD_RAMDATA *psMethodRAMDataStruct;
      TSS_TSI_MemMapPtr psModuleStruct;

      /* Pointers decoding */
      psElectrodeROMDataStruct = (TSS_TSI_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElecNum]);
      psMethodROMDataStruct = (TSS_TSI_METHOD_ROMDATA *) (psElectrodeROMDataStruct->tsi_cpsu32MethodROMData);
      psModuleStruct = (TSS_TSI_MemMapPtr) (psMethodROMDataStruct->tsi_cpsu32Module);
      psMethodRAMDataStruct = (TSS_TSI_METHOD_RAMDATA *) (psElectrodeROMDataStruct->tsi_u8MethodRAMData);

      /* Module Control */
      if (u8Command == TSS_SAMPLE_COMMAND_RESTART)
      {
        /* Do TSI init */
        if (!(psModuleStruct->GENCS & TSI_GENCS_TSIEN_MASK)) /* If TSI is disabled then enable */
        {
          psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;
        }
        /* Evaluate status */ 
        if ( tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
        {
          if (psMethodRAMDataStruct->tsi_eEndOfScanState == TSI_EOSF_STATE_ERROR)
          {
            u8ElectrodeStatus = TSS_SAMPLE_ERROR_SMALL_TRIGGER_PERIOD; /* Small TriggerModuloValue */
            psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK;           /* Disable whole TSS due triggering crash */
            #ifdef _TSS_TEST
               _TSS_TSIGEN_OFF;           /* Stop generator for test purpose */
            #endif
          } else {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
          }
          psMethodRAMDataStruct->tsi_eEndOfScanState = TSI_EOSF_STATE_NONE; /* Reset EndOfScanState */
        } else { /* If Always & SW Mode */
          /* If Always Mode restart TSI measurement by SW Trigger Toggle */
          if ( tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_ALWAYS)
          {
            /* TSI scanning is in progress or one TSI measurement done */
            if (( psModuleStruct->GENCS & TSI_GENCS_SCNIP_MASK ) || (psMethodRAMDataStruct->tsi_eEndOfScanState == TSI_EOSF_STATE_REGULAR))
            {
              /* Nothing */
            } else {
              psMethodRAMDataStruct->tsi_eEndOfScanState = TSI_EOSF_STATE_NONE; /* Reset EndOfScanState */
              psModuleStruct->GENCS |= TSI_GENCS_SWTS_MASK;  /* Toggle SW Trigger */
              #ifdef _TSS_TEST
                _TSS_TSIGEN_ON;          /* Start generator for test purpose */
              #endif
            }
          }
          u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
        }
      }
      else if (u8Command == TSS_SAMPLE_COMMAND_PROCESS)
      {
        /* If TSI is disabled then enable */
        if (!(psModuleStruct->GENCS & TSI_GENCS_TSIEN_MASK))
        {
          psModuleStruct->GENCS |= TSI_GENCS_TSIEN_MASK;
        }
        /* Evaluate status */
        if ( tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_AUTO)
        {
          #ifdef _TSS_TEST
            _TSS_TSIGEN_ON;              /* Start generator for test purpose */
          #endif
          if ((psMethodRAMDataStruct->tsi_eEndOfScanState == TSI_EOSF_STATE_NONE) || ((psMethodRAMDataStruct->tsi_eEndOfScanState == TSI_EOSF_STATE_REGULAR) && (!(psModuleStruct->GENCS & TSI_GENCS_SCNIP_MASK))))
          {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
          } else if ( (psMethodRAMDataStruct->tsi_eEndOfScanState == TSI_EOSF_STATE_EXCESS) || ((psMethodRAMDataStruct->tsi_eEndOfScanState == TSI_EOSF_STATE_REGULAR) && (psModuleStruct->GENCS & TSI_GENCS_SCNIP_MASK)))
          {
            /* Read TSI Counter */
            u8ElectrodeStatus = TSI_ReadCounter(psElectrodeROMDataStruct, psModuleStruct, psMethodRAMDataStruct);
          }
          else
          {
            u8ElectrodeStatus = TSS_SAMPLE_ERROR_SMALL_TRIGGER_PERIOD; /* Small TriggerModuloValue */
            psModuleStruct->GENCS &= ~TSI_GENCS_TSIEN_MASK;            /* Disable whole TSS due triggering crash */
            psMethodRAMDataStruct->tsi_eEndOfScanState = TSI_EOSF_STATE_NONE; /* Reset EndOfScanState */
            #ifdef _TSS_TEST
              _TSS_TSIGEN_OFF;           /* Stop generator for test purpose */
            #endif
          }
        } else {  /* Always & SW Mode */
          if (psModuleStruct->GENCS & TSI_GENCS_SCNIP_MASK) /* TSI scanning is in progress */
          {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
          }
          else
          {
            /* If TSI End of Scan Flag is reported */
            if (psMethodRAMDataStruct->tsi_eEndOfScanState >= TSI_EOSF_STATE_REGULAR)
            {
              psMethodRAMDataStruct->tsi_eEndOfScanState = TSI_EOSF_STATE_PROCESS;
              #ifdef _TSS_TEST
                _TSS_TSIGEN_OFF;         /* Stop generator */
              #endif
              /* Read TSI Counter */
              u8ElectrodeStatus = TSI_ReadCounter(psElectrodeROMDataStruct, psModuleStruct, psMethodRAMDataStruct);
            }
            else
            {
              /* Toggle TSI SW Trigger again if process was interrupted for sure */
              if (tss_CSSys.SystemTrigger.TriggerMode == TSS_TRIGGER_MODE_ALWAYS)
              {
                psMethodRAMDataStruct->tsi_eEndOfScanState = TSI_EOSF_STATE_NONE; /* Reset EndOfScanState */
                psModuleStruct->GENCS |= TSI_GENCS_SWTS_MASK;  
              }
              #ifdef _TSS_TEST
                _TSS_TSIGEN_ON;          /* Start generator for test purpose */
              #endif
              u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;
            }
          }
        }
      }
      else if (u8Command == TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE)
      {
        /* Find the next electrode within the electrode module */
        u8ElCounter = u8ElecNum;
        do {
          if (u8ElCounter < (TSS_N_ELECTRODES - 1u))
          {
            u8ElCounter++;
          } else {
            u8ElCounter = 0u;
          }
        } while ((TSS_GENERIC_METHOD_ROMDATA*) psMethodROMDataStruct != (TSS_GENERIC_METHOD_ROMDATA *)((TSS_GENERIC_ELECTRODE_ROMDATA *)tss_acp8ElectrodeROMData[u8ElCounter])->gen_cpsMethodROMData);
        /* Return found electrode number */
        u8ElectrodeStatus = u8ElCounter;

      } else if (u8Command == TSS_SAMPLE_COMMAND_RECALIB)
      {
        u8ElectrodeStatus = TSI_MethodControl(u8ElecNum, TSS_INIT_COMMAND_RECALIBRATE);

        if (u8ElectrodeStatus & TSS_INIT_ERROR_RECALIB_FAULT)
        {
          /* Fault happened, so disable actual electrode */
          u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT;
        } else if (u8ElectrodeStatus & TSS_INIT_STATUS_CALIBRATION_CHANGED)
        {
          /* Calibration changed */
          u8ElectrodeStatus = TSS_SAMPLE_STATUS_CALIBRATION_CHANGED;
        } else
        {
          /* Old calibration was correct */
          u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
        }

      } else if (u8Command == TSS_SAMPLE_COMMAND_ENABLE_ELECTRODE)
      {
        u8ElectrodeStatus = TSI_MethodControl(u8ElecNum, TSS_INIT_COMMAND_ENABLE_ELECTRODES);

        u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
      }

      return u8ElectrodeStatus;   /* Return status code */

    }

    /***************************************************************************//*!
    *
    * @brief  TSI ISR routines
    *
    * @remarks
    *
    ****************************************************************************/
    #if TSS_DETECT_MODULE(TSI)
      #if TSS_KINETIS_MCU
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSIIsr to vector INT_TSI
        #endif
      #elif TSS_CFM_MCU
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSIIsr to vector Vtsi
        #endif
        #if !TSS_USE_MQX
          interrupt
        #endif
      #endif
      void TSS_TSIIsr(
        #if TSS_USE_MQX
          void *_isrParameter
        #else
          void
        #endif
        )
      {
        UINT16 u16temp;
        
        ((TSS_TSI_MemMapPtr) (TSS_TSI_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_TSIEN_MASK; /* Due to 0M33Z maskset (unfreeze after restart) */
        if (tss_CSSys.SystemConfig.LowPowerEn)
        {
          #if (TSS_TSI_VERSION==1)
          ((TSS_TSI_MemMapPtr) (TSS_TSI_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->STATUS = 0xFFFFFFFFu;  /* Clear OUTFRG Status Flag */
          #endif            
          ((TSS_TSI_MemMapPtr) (TSS_TSI_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_OUTRGF_MASK; /* Clear OUTFRG Flag */
          ((TSS_TSI_MemMapPtr) (TSS_TSI_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS &= ~TSI_GENCS_TSIIE_MASK; /* Disable TSI Interrupt */
          /* Disables LowPower Wake Up */
          u16temp = TSS_GetSystemConfig(System_SystemConfig_Register);
          (void)TSS_SetSystemConfig(System_SystemConfig_Register,(u16temp & ~TSS_LOWPOWER_EN_MASK));  
        } else {
          ((TSS_TSI_MemMapPtr) (TSS_TSI_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_EOSF_MASK;  /* Clear Flag */
          #ifdef _TSS_TEST
            _TSS_TSIGEN_OFF;         /* Stop generator */
          #endif
          if (TSS_TSI_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState != TSI_EOSF_STATE_ERROR)
          {
            /* Increment tsi_u8EndOfScanState */
            TSS_TSI_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState = (TSS_TSI_EOSF_STATES) ((UINT8)TSS_TSI_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState + 1u);
          }
        }
        /* Set Sample Interrupted flag, because TSI measures at background and it can interrupt sampling of GPIO based methods */
        TSS_SET_SAMPLE_INTERRUPTED();
      }
    #endif
    #if TSS_DETECT_MODULE(TSI0)
      #if TSS_KINETIS_MCU
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSI0Isr to vector INT_TSI0
        #endif
      #elif TSS_CFM_MCU
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSI0Isr to vector Vtsi0
        #endif
        #if !TSS_USE_MQX
          interrupt
        #endif
      #endif
      void TSS_TSI0Isr(
        #if TSS_USE_MQX
          void *_isrParameter
        #else
          void
        #endif
        ) 
      {
        UINT16 u16temp;
        
        ((TSS_TSI_MemMapPtr) (TSS_TSI0_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_TSIEN_MASK; /* Due to 0M33Z maskset (unfreeze after restart) */
        if (tss_CSSys.SystemConfig.LowPowerEn)
        {
          #if (TSS_TSI_VERSION==1)
          ((TSS_TSI_MemMapPtr) (TSS_TSI0_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->STATUS = 0xFFFFFFFFu;  /* Clear OUTFRG Status Flag */
          #endif
          ((TSS_TSI_MemMapPtr) (TSS_TSI0_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_OUTRGF_MASK; /* Clear OUTFRG Flag */
          ((TSS_TSI_MemMapPtr) (TSS_TSI0_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS &= ~TSI_GENCS_TSIIE_MASK; /* Disable TSI Interrupt */
          /* Disables LowPower Wake Up */
          u16temp = TSS_GetSystemConfig(System_SystemConfig_Register);
          (void)TSS_SetSystemConfig(System_SystemConfig_Register,(u16temp & ~TSS_LOWPOWER_EN_MASK));  
        } else {
          ((TSS_TSI_MemMapPtr) (TSS_TSI0_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_EOSF_MASK;  /* Clear Flag */
          #ifdef _TSS_TEST
            _TSS_TSIGEN_OFF;         /* Stop generator */
          #endif
          if (TSS_TSI0_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState != TSI_EOSF_STATE_ERROR)
          {
            /* Increment tsi_u8EndOfScanState */
            TSS_TSI0_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState = (TSS_TSI_EOSF_STATES) ((UINT8)TSS_TSI0_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState + 1u);
          }
        }
        /* Set Sample Interrupted flag, because TSI measures at background and it can interrupt sampling of GPIO based methods */
        TSS_SET_SAMPLE_INTERRUPTED();
      }
    #endif
    #if TSS_DETECT_MODULE(TSI1)
      #if TSS_KINETIS_MCU
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSI1Isr to vector INT_TSI1
        #endif
      #elif TSS_CFM_MCU
        #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
          #warning TSS - Please assign ISR function TSS_TSI1Isr to vector Vtsi1
        #endif
        #if !TSS_USE_MQX
          interrupt
        #endif
      #endif
      void TSS_TSI1Isr(
        #if TSS_USE_MQX
          void *_isrParameter
        #else
          void
        #endif
        ) 
      {
        UINT16 u16temp;
        
        ((TSS_TSI_MemMapPtr) (TSS_TSI1_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_TSIEN_MASK; /* Due to 0M33Z maskset (unfreeze after restart) */
        if (tss_CSSys.SystemConfig.LowPowerEn)
        {
          #if (TSS_TSI_VERSION==1)          
          ((TSS_TSI_MemMapPtr) (TSS_TSI1_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->STATUS = 0xFFFFFFFFu;  /* Clear OUTFRG Status Flag */
          #endif          
          ((TSS_TSI_MemMapPtr) (TSS_TSI1_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_OUTRGF_MASK; /* Clear OUTFRG Flag */
          ((TSS_TSI_MemMapPtr) (TSS_TSI1_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS &= ~TSI_GENCS_TSIIE_MASK; /* Disable TSI Interrupt */
          /* Disables LowPower Wake Up */
          u16temp = TSS_GetSystemConfig(System_SystemConfig_Register);
          (void)TSS_SetSystemConfig(System_SystemConfig_Register,(u16temp & ~TSS_LOWPOWER_EN_MASK));  
        } else {
          ((TSS_TSI_MemMapPtr) (TSS_TSI1_METHOD_ROMDATA_CONTEXT.tsi_cpsu32Module))->GENCS |= TSI_GENCS_EOSF_MASK;  /* Clear Flag */
          #ifdef _TSS_TEST
            _TSS_TSIGEN_OFF;         /* Stop generator */
          #endif
          if (TSS_TSI1_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState != TSI_EOSF_STATE_ERROR)
          {
            /* Increment tsi_u8EndOfScanState */
            TSS_TSI1_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState = (TSS_TSI_EOSF_STATES) ((UINT8)TSS_TSI1_METHOD_RAMDATA_CONTEXT.tsi_eEndOfScanState + 1u);
          }
        }
        /* Set Sample Interrupted flag, because TSI measures at background and it can interrupt sampling of GPIO based methods */
        TSS_SET_SAMPLE_INTERRUPTED();
      }
    #endif

  #else /* End of TSS_KINETIS_MCU || TSS_CFM_MCU */
    #error "TSS - Not supported MCU used"
  #endif

#endif /* End of TSS_DETECT_METHOD(TSI) */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/shmem/pcbshmv.h<|end_filename|>
#ifndef __pcbshmv_h__
#define __pcbshmv_h__
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pcbshmv.h$
* $Version : 3.0.4.0$
* $Date    : Oct-5-2011$
*
* Comments:
*
*   This file contains the private definitions for the MQX packet format
*   PCB packet drivers operating on shared memory drivers.
*
*END************************************************************************/

#include "pcb_shm.h"

/*--------------------------------------------------------------------------*/
/*
**                          CONSTANT DECLARATIONS
*/

#define IO_PCB_mqxa_STACK_SIZE   (750 * sizeof(_mem_size))

/* SHARED MEMORY PROTOCOL DEFINITIONS */

/*  Interrupts bit definitions */
#define IO_PCB_SHM_ALL_INTS                           (0)

/* Buffer descriptors bits definition */
#define IO_PCB_SHM_BUFFER_OWN                (0x00000001)
#define IO_PCB_SHM_BUFFER_ALOCATED           (0x00000002)
#define IO_PCB_SHM_BUFFER_RELEASED           (0x00000004)

/* Shared memory Errors */
#define MQX_IO_PCB_SHM_INSTALL_ISR_FAILLED   (0x00000001)

#define NEXT_BD(x,y)         (x+y)
#define NEXT_INDEX(x,y)      ((++x == y)? x : 0)

/* Macro for aligning the Ring start address */
#define SHM_DESCR_ALIGN(n)   ((n) + (-(n) & 31))

/*--------------------------------------------------------------------------*/
/*
**                          DATATYPE DECLARATIONS
*/


/*
** IO_PCB_SHM_BUFFER_STRUCT
** This structure contains the initialization information for the
** shared memory buffers
**
*/
typedef struct io_pcb_shm_buffer_struct
{
   /* pcb_ptr pointer */
   pointer     PACKET_PTR;

   /* Control bits */
   uint_32     CONTROL;

   /* Cache alignment so bd is 32 bytes long */
   uint_32     RESERVED[6];

} IO_PCB_SHM_BUFFER_STRUCT, _PTR_ IO_PCB_SHM_BUFFER_STRUCT_PTR;

/*
** IO_PCB_SHM_INFO_STRUCT
** This structure contains standard Bspio protocol information
**
*/
typedef struct io_pcb_shm_info_struct
{
   /*  INPUT DEFINITIONS */
   LWSEM_STRUCT           READ_LWSEM;
   QUEUE_STRUCT           READ_QUEUE;
   void       (_CODE_PTR_ READ_CALLBACK_FUNCTION)(FILE_DEVICE_STRUCT_PTR,  IO_PCB_STRUCT_PTR);
   _io_pcb_pool_id        READ_PCB_POOL;
   IO_PCB_SHM_BUFFER_STRUCT_PTR  RX_RING_PTR;
   FILE_DEVICE_STRUCT_PTR FD;
   uint_32                RXENTRIES;
   uint_32                RXNEXT;
   uint_32                RXLAST;
   uint_32                RX_LENGTH;

   /* OUTPUT DEFINITIONS */
   LWSEM_STRUCT           WRITE_LWSEM;
   QUEUE_STRUCT           WRITE_QUEUE;
   IO_PCB_SHM_BUFFER_STRUCT_PTR  TX_RING_PTR;
   uint_32                TXENTRIES;
   uint_32                TXNEXT;
   uint_32                TXLAST;
   uint_32                TX_LENGTH;

   /* STATISTICAL INFORMATION */
   _mqx_uint              RX_PACKETS;
   _mqx_uint              TX_PACKETS;
   _mqx_uint              TX_BD_RUNOVER;
   _mqx_uint              RX_BD_RUNOVER;

   /* A copy of the initialization info */
   IO_PCB_SHM_INIT_STRUCT INIT;

   /* Interrupts definitions */
   void      (_CODE_PTR_ RX_OLDISR_PTR)(pointer);
   pointer               RX_OLDISR_DATA;
   void      (_CODE_PTR_ TX_OLDISR_PTR)(pointer);
   pointer               TX_OLDISR_DATA;

} IO_PCB_SHM_INFO_STRUCT, _PTR_ IO_PCB_SHM_INFO_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                          C PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_pcb_shm_open(FILE_DEVICE_STRUCT_PTR, char _PTR_, char _PTR_);
extern _mqx_int _io_pcb_shm_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_pcb_shm_read(FILE_DEVICE_STRUCT_PTR, IO_PCB_STRUCT_PTR _PTR_);
extern _mqx_int _io_pcb_shm_write(FILE_DEVICE_STRUCT_PTR, IO_PCB_STRUCT_PTR);
extern _mqx_int _io_pcb_shm_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);
extern _mqx_int _io_pcb_shm_uninstall(IO_PCB_DEVICE_STRUCT_PTR);
extern void     _io_pcb_shm_tx(pointer);
extern void     _io_pcb_shm_rx_isr(pointer);
extern void     _io_pcb_shm_tx_isr(pointer);

#if BSPCFG_IO_PCB_SHM_SUPPORT
extern _mqx_uint _bsp_io_pcb_shm_int_install(IO_PCB_SHM_INIT_STRUCT_PTR init_ptr,IO_PCB_SHM_INFO_STRUCT_PTR info_ptr);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2s/i2s_audio.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2s_audio.h$
* $Version : 3.8.5.0$
* $Date    : Jul-17-2012$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the I2S I/O functions.
*
*END************************************************************************/


#ifndef _i2s_audio_h_
#define _i2s_audio_h_ 1
#include <mqx.h>

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/*
** IOCTL calls specific to audio devices
*/
#define IO_TYPE_AUDIO                           0x16
#define IO_IOCTL_AUDIO_SET_IO_DATA_FORMAT _IO   (IO_TYPE_AUDIO, 0x01)
#define IO_IOCTL_AUDIO_GET_IO_DATA_FORMAT _IO   (IO_TYPE_AUDIO, 0x02)

/*
** Audio deformat defaults
*/
#define AUDIO_DEFAULT_ENDIAN        AUDIO_BIG_ENDIAN
#define AUDIO_DEFAULT_ALIGNMENT     AUDIO_ALIGNMENT_RIGHT
#define AUDIO_DEFAULT_BITS          AUDIO_BIT_SIZE_MAX

/*
** Audio data aligment
*/
#define AUDIO_ALIGNMENT_RIGHT   0x00
#define AUDIO_ALIGNMENT_LEFT    0x01

/*
** Audio data endianity
*/
#define AUDIO_BIG_ENDIAN    MQX_BIG_ENDIAN
#define AUDIO_LITTLE_ENDIAN MQX_LITTLE_ENDIAN

/*
** Data bit size limits
*/
#define AUDIO_BIT_SIZE_MIN 8
#define AUDIO_BIT_SIZE_MAX 32

/*
** Audio error codes
*/
#define AUDIO_ERROR_BASE                (DRIVER_ERROR_BASE | 0x1000)
#define AUDIO_ERROR_INVALID_IO_FORMAT   (AUDIO_ERROR_BASE | 0x01)
/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

typedef struct audio_data_format
{
    /* Endian of input data */
    uint_8 ENDIAN;

    /* Aligment of input data */
    uint_8 ALIGNMENT;

    /* Bit size of input data */
    uint_8 BITS;

    /* Sample size in bytes */
    uint_8 SIZE;

    /* Number of channels */
    uint_8 CHANNELS;

} AUDIO_DATA_FORMAT, _PTR_ AUDIO_DATA_FORMAT_PTR;

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/ipcrtprv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcrtprv.h$
* $Version : 3.0.4.0$
* $Date    : Oct-5-2011$
*
* Comments:
*
*   This file contains the definitions private to the router used to route
*   IPC messages.
*
*END************************************************************************/
#ifndef __ipcrtprv_h__
#define __ipcrtprv_h__ 1

/*--------------------------------------------------------------------------*/
/*
 *                          CONSTANT DECLARATIONS
 */

/*--------------------------------------------------------------------------*/
/*
 *                    TYPEDEFS FOR _CODE_PTR_ FUNCTIONS
 */ 
typedef boolean (_CODE_PTR_ IPC_MSGROUTER_FPTR)( _processor_number, pointer, boolean);
 
/*--------------------------------------------------------------------------*/
/*
 *                          DATATYPE DECLARATIONS
 */

/* IPC MSG ROUTING STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure contains info for a particular route.
 */
typedef struct ipc_msg_routing_struct
{

   /*! \brief Used to link all routing structures together. */
   QUEUE_ELEMENT_STRUCT  LINK;

   /*! \brief The minimum processor number in the range. */
   _processor_number     MIN_PROC_NUMBER;

   /*! \brief The maximum processor number in the range. */
   _processor_number     MAX_PROC_NUMBER;

   /*! \brief The queue to use if the processor number is in the above range. */
   _queue_number         QUEUE;

} IPC_MSG_ROUTING_STRUCT, _PTR_ IPC_MSG_ROUTING_STRUCT_PTR;
/*! \endcond */


/* IPC MSG ROUTING COMPONENT STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief The structure kept in the kernel data by the message routing component.
 */
typedef struct ipc_msg_routing_component_struct 
{
   /*! \brief Linked list of routes installed. */
   QUEUE_STRUCT         ROUTING_LIST;
   /*! \brief Message router function. */
   IPC_MSGROUTER_FPTR 	MSG_ROUTER;
   
} IPC_MSG_ROUTING_COMPONENT_STRUCT, _PTR_ IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/*
 *                          C PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _ipc_msg_route_init_internal( const IPC_ROUTING_STRUCT * route_ptr );
/*! \private */
extern _mqx_uint _ipc_msg_route_internal(_processor_number, pointer, boolean);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/fpio_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: fpio_prv.h$
* $Version : 3.8.6.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains definitions required for floating point 
*   formatted I/O.
*
*END************************************************************************/
#ifndef __fpio_prv_h__
#define __fpio_prv_h__

/*----------------------------------------------------------------------*/
/*
 *                          CONSTANT DEFINITIONS
 */

/* Floating point Default PRECision Value.  */
#define FDPRECV         (6)

/* Number of decimal digits to the left of an e format output. */
#define LEFTOFE         (1)

/* 
 * Number of decimal digits to the left 
 * of an f format output.  This is 
 * presumably a reasonable maximum.   
 */
#define LEFTOFF         (308)

/* 
 * IEEE 754 single-precision binary floating-point format
 * The maximum number of chars in string that can represent any IEE 754 floating number is determined.
 * The sign is one bit and represents max. one char '+' / '-' or nothing
 * The exponent has 8 bits and its meaning is the floating point multiplication from E = 2^(-127) to 2^(+128),
 * The fraction has 23 bits and it can take maximum 23 chars, when the last bit of fraction is set:
 *   2^(-1) = 0.5 (first decimal place set)
 *   2^(-2) = 0.25 (second decimal place set)
 *   2^(-23) = 0.xxxxx5 (23rd decimal place set)\
 *   so the fraction is from (0.xxx...xxx5 to 1.yyy...yyy5)
 *  The exponent can only multiplicate the fraction:
 *    in the case of negative E we will get more decimal places than in the case of positive E
 *    the smallest negative E value is -127.
 *   2^(-127) = 0.zzzzz5 (127th place is set to 5)
 *  So the maximum number of chars needed to display IEEE 754 value is:
 *  max(S) + max('0') + max('.') + max(E) + max(F) = 1 + 1 + 1 + 127 + 23 = 153
 *  and add zero-ending string space (1B)
 */

#define NDIG            (154)
#define MAX_PRECISION   (17)

#define FP_WORDSIZE     (16)
#define FP_NUMWORDS     (4)
#define FP_FLT          (0)
#define FP_DBL          (1)
#define BIAS            (1023)
#define MAX_EXP         (2046)
#define MIN_EXP         (-51)
#define FMAX_EXP        (254)
#define FMIN_EXP        (-22)

#ifndef DBL_MAX_10_EXP
#define DBL_MAX_10_EXP  (308)
#endif

#ifndef HUGE_VAL
#define HUGE_VAL         99.e999
#endif

#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
#define HIGH              (1)
#define LOW               (0)
#else
#define HIGH              (0)
#define LOW               (1)
#endif

#define BYTES_PER_DOUBLE  (8)
#define MANT_BITS         (52)
#define NON_MANT_BITS     (12)
#define EXP_BIAS          (1023)

/*--------------------------------------------------------------------------*/
/*
 *                            MACRO DEFINTIONS
 */

#define EXP_MASK        (0x7ff00000L)
#define FEXP_MASK       (0x7f800000L)

#define SIGN_MASK       (0x80000000L)

#define MAXEXP_MASK     (0x000007ffL)
#define FMAXEXP_MASK    (0x000000ffL)

#define MANT_MASK       (0x000fffffL)
#define FMANT_MASK      (0x007fffffL)

#define HIDDEN_MASK     (0x00100000L)
#define FHIDDEN_MASK    (0x00800000L)

/* macros for a, where a is the address of 64 bits of ieee double */
#define EXPOF(a)        (((a)[HIGH] & EXP_MASK) >> 20)
#define FEXPOF(a)       (((a) & FEXP_MASK) >> 23)

#define SIGNOF(a)       (((a)[HIGH] & SIGN_MASK) != 0)
#define FSIGNOF(a)      (((a) & SIGN_MASK) != 0)

#define ISZERO(a)       ( !( ((a)[HIGH] & ~SIGN_MASK) | ((a)[LOW])) )
#define FISZERO(a)      (((a) & 0x7fffffffL) == 0)

#define MANTZERO(a)     ( !( ((a)[HIGH] &  MANT_MASK) | ((a)[LOW])) )
#define FMANTZERO(a)    (((a) &  FMANT_MASK) == 0)

#define ISINFINITY(a)   ((EXPOF(a) == MAXEXP_MASK) &&  MANTZERO(a))
#define FISINFINITY(a)  ((FEXPOF(a) == FMAXEXP_MASK) &&  FMANTZERO(a))

#define ISNAN(a)        ((EXPOF(a) == MAXEXP_MASK) && !(MANTZERO(a)))
#define FISNAN(a)       ((FEXPOF(a) == FMAXEXP_MASK) && !(FMANTZERO(a)))


/*--------------------------------------------------------------------------*/
/*
 *                            DATATYPE DECLARATIONS
 */

/*!  
 * \cond DOXYGEN_PRIVATE
 *  
 * /brief This union is used so that we can access the fp number as bytes, 
 * longwords, or as a floating point number.    
 */
typedef union fp_union {
    /*! \brief Double data type. */
    double      DOUBLE;
    /*! \brief Long data type. */
    uint_32     LONG[2];
    /*! \brief Byte data type. */
    uint_8      BYTE[8];
} FP_UNION, _PTR_ FP_UNION_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/*
 *                            FUNCTION PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern char _PTR_ _io_cvt(double, int_32, int_32_ptr, char _PTR_, char, char _PTR_,char type);
extern int_32     _io_dtoa(int_32, char _PTR_);
extern int_32     _io_dtoe(char _PTR_, double, char _PTR_, char, char, char, int_32,
   char);        
extern int_32     _io_dtof(char _PTR_, double, char _PTR_, char, char, char, int_32,
   char);        
extern int_32     _io_dtog(char _PTR_, double, char _PTR_, char, char, char, int_32,
   char);        
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_lpm.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: init_lpm.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   Low Power Manager initialization definitions.
*
*END************************************************************************/

#ifndef __init_lpm_h__
    #define __init_lpm_h__

/*-------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

typedef enum 
{
    LPM_OPERATION_MODE_RUN = 0,
    LPM_OPERATION_MODE_WAIT,
    LPM_OPERATION_MODE_SLEEP,
    LPM_OPERATION_MODE_STOP,
    LPM_OPERATION_MODES          /* Number of operation modes available */
} LPM_OPERATION_MODE;


/*-------------------------------------------------------------------------*/
/*
**                            MACRO DECLARATIONS
*/


/*-------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/


/*-------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/


#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif


#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psptypes.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2010-2011 Freescale Semiconductor
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psptypes.h$
* $Version : 3.8.10.0$
* $Date    : Oct-3-2012$
*
* Comments:
*   This file contains the definitions of the basic MQX types.
*
*END************************************************************************/
#ifndef __psptypes_h__
#define __psptypes_h__


/*--------------------------------------------------------------------------*/
/*
**                            STANDARD TYPES
*/

/*
**  The following typedefs allow us to minimize portability problems
**  due to the various C compilers (even for the same processor) not
**  agreeing on the sizes of "int"s and "short int"s and "longs".
*/

#define _PTR_      *
#define _CODE_PTR_ *

typedef char _PTR_                    char_ptr;    /* signed character       */
typedef unsigned char  uchar, _PTR_   uchar_ptr;   /* unsigned character     */
typedef volatile char _PTR_                    vchar_ptr;    /* signed character       */
typedef volatile unsigned char  vuchar, _PTR_   vuchar_ptr;   /* unsigned character     */

typedef signed   char   int_8, _PTR_   int_8_ptr;   /* 8-bit signed integer   */
typedef unsigned char  uint_8, _PTR_  uint_8_ptr;  /* 8-bit signed integer   */
typedef volatile signed   char   vint_8, _PTR_   vint_8_ptr;   /* 8-bit volatile signed integer   */
typedef volatile unsigned char  vuint_8, _PTR_  vuint_8_ptr;  /* 8-bit volatile signed integer   */

typedef          short int_16, _PTR_  int_16_ptr;  /* 16-bit signed integer  */
typedef unsigned short uint_16, _PTR_ uint_16_ptr; /* 16-bit unsigned integer*/
typedef volatile          short vint_16, _PTR_  vint_16_ptr;  /* 16-bit volatile signed integer  */
typedef volatile unsigned short vuint_16, _PTR_ vuint_16_ptr; /* 16-bit volatile unsigned integer*/

typedef          long  int_32, _PTR_  int_32_ptr;  /* 32-bit signed integer  */

#ifdef __IAR_IDE__
typedef unsigned long  mqx_uint_32, _PTR_ uint_32_ptr; /* 32-bit unsigned integer*/
#define uint_32 mqx_uint_32
#else
typedef unsigned long  uint_32, _PTR_ uint_32_ptr; /* 32-bit unsigned integer*/
#endif

typedef volatile          long  vint_32, _PTR_  vint_32_ptr;  /* 32-bit signed integer  */
typedef volatile unsigned long  vuint_32, _PTR_ vuint_32_ptr; /* 32-bit unsigned integer*/

typedef    long  long  int_64, _PTR_  int_64_ptr;       /* 64-bit signed   */
typedef unsigned long long  uint_64, _PTR_ uint_64_ptr; /* 64-bit unsigned */
typedef volatile   long  long  vint_64, _PTR_  vint_64_ptr;       /* 64-bit signed   */
typedef volatile unsigned long long  vuint_64, _PTR_ vuint_64_ptr; /* 64-bit unsigned */

#ifdef __IAR_IDE__
typedef unsigned long  _mqx_boolean;  /* Machine representation of a boolean */
#else
typedef unsigned long  boolean;  /* Machine representation of a boolean */
#endif

typedef void _PTR_     pointer;  /* Machine representation of a pointer */

/* IEEE single precision floating point number (32 bits, 8 exponent bits) */
typedef float          ieee_single;

/* IEEE double precision floating point number (64 bits, 11 exponent bits) */
typedef double         ieee_double;

#ifndef USE_32BIT_TYPES
/* Type for the CPU's natural size */
typedef uint_32  _mqx_uint, _PTR_ _mqx_uint_ptr;
typedef int_32   _mqx_int,  _PTR_ _mqx_int_ptr;

/* How big a data pointer is on this processor */
typedef uint_32  _psp_data_addr, _PTR_ _psp_data_addr_ptr;

/* How big a code pointer is on this processor */
typedef uint_32  _psp_code_addr, _PTR_ _psp_code_addr_ptr;

/* Maximum type */
typedef uint_32  _mqx_max_type, _PTR_ _mqx_max_type_ptr;

/* _mem_size is equated to the a type that can hold the maximum data address */
typedef uint_32 _mem_size, _PTR_ _mem_size_ptr;

/* Used for file sizes. */
typedef uint_32       _file_size;
typedef int_32        _file_offset;

#else
#define _mqx_uint      uint_32
#define _mqx_uint_ptr  uint_32_ptr
#define _mqx_int       int_32
#define _mqx_int_ptr   int_32_ptr
#define _psp_data_addr uint_32
#define _psp_code_addr uint_32
#define _mqx_max_type  uint_32
#define _mem_size      uint_32
#endif

/*--------------------------------------------------------------------------*/
/*
**                         DATATYPE VALUE RANGES
*/

#define MAX_CHAR      (0x7F)
#define MAX_UCHAR     (0xFF)
#define MAX_INT_8     (0x7F)
#define MAX_UINT_8    (0xFF)
#define MAX_INT_16    (0x7FFF)
#define MAX_UINT_16   (0xFFFF)
#define MAX_INT_32    (0x7FFFFFFFL)
#define MAX_UINT_32   (0xFFFFFFFFUL)
#define MAX_INT_64    (0x7FFFFFFFFFFFFFFFLL)
#define MAX_UINT_64   (0xFFFFFFFFFFFFFFFFULL)

#define MIN_FLOAT     (8.43E-37)
#define MAX_FLOAT     (3.37E+38)

#define MIN_DOUBLE    (2.225074E-308)
#define MAX_DOUBLE    (1.797693E+308)

#define MAX_MQX_UINT         (MAX_UINT_32)
#define MAX_MQX_INT          (MAX_INT_32)
#define MAX_FILE_SIZE        (MAX_UINT_32)
#define MAX_MEM_SIZE         (MAX_UINT_32)
#define MAX_MQX_MAX_TYPE     (MAX_UINT_32)
#define MQX_INT_SIZE_IN_BITS (32)


#endif /* __psptypes_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio_vgpio.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio_vgpio.h$
* $Version : 3.8.1.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/
#ifndef __lwgpio_vgpio_h__
#define __lwgpio_vgpio_h__ 1

#define LWGPIO_PIN_VALID (0x80000000) /* Note: this is for backwards compatibility with GPIO driver only */

/* Pin field definitions */
#define LWGPIO_PIN_SHIFT (0)
#define LWGPIO_PIN_MASK (0x1F << LWGPIO_PIN_SHIFT)

#define LWGPIO_PIN(x) (((x) << LWGPIO_PIN_SHIFT) & LWGPIO_PIN_MASK)

/* Pin attributes */
#define LWGPIO_ATTR_BASE            (0x100)
#define LWGPIO_ATTR_SLEW_RATE       (LWGPIO_ATTR_BASE+1)
#define LWGPIO_ATTR_FILTER          (LWGPIO_ATTR_BASE+2)
#define LWGPIO_ATTR_DRIVE_STRENGTH  (LWGPIO_ATTR_BASE+3)

/*attributes value*/
#define LWGPIO_AVAL_SLEW_RATE_FAST          (0)
#define LWGPIO_AVAL_SLEW_RATE_SLOW          (1)
#define LWGPIO_AVAL_DRIVE_STRENGTH_HIGH     (1)
#define LWGPIO_AVAL_DRIVE_STRENGTH_LOW      (0)

/* Port field definitions */
#define LWGPIO_PORT_SHIFT (5)
#define LWGPIO_PORT_MASK (0xFF << LWGPIO_PORT_SHIFT)
#define LWGPIO_PORT(x) (((x) << LWGPIO_PORT_SHIFT) & LWGPIO_PORT_MASK)
#define LWGPIO_PORT_A (LWGPIO_PORT(0) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_B (LWGPIO_PORT(1) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_C (LWGPIO_PORT(2) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_D (LWGPIO_PORT(3) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_E (LWGPIO_PORT(4) | LWGPIO_PIN_VALID)

#define LWGPIO_PIN0   (0)
#define LWGPIO_PIN1   (1)
#define LWGPIO_PIN2   (2)
#define LWGPIO_PIN3   (3)
#define LWGPIO_PIN4   (4)
#define LWGPIO_PIN5   (5)
#define LWGPIO_PIN6   (6)
#define LWGPIO_PIN7   (7)
#define LWGPIO_PIN8   (8)
#define LWGPIO_PIN9   (9)
#define LWGPIO_PIN10  (10)
#define LWGPIO_PIN11  (11)
#define LWGPIO_PIN12  (12)
#define LWGPIO_PIN13  (13)
#define LWGPIO_PIN14  (14)
#define LWGPIO_PIN15  (15)
#define LWGPIO_PIN16  (16)
#define LWGPIO_PIN17  (17)
#define LWGPIO_PIN18  (18)
#define LWGPIO_PIN19  (19)
#define LWGPIO_PIN20  (20)
#define LWGPIO_PIN21  (21)
#define LWGPIO_PIN22  (22)
#define LWGPIO_PIN23  (23)
#define LWGPIO_PIN24  (24)
#define LWGPIO_PIN25  (25)
#define LWGPIO_PIN26  (26)
#define LWGPIO_PIN27  (27)
#define LWGPIO_PIN28  (28)
#define LWGPIO_PIN29  (29)
#define LWGPIO_PIN30  (30)
#define LWGPIO_PIN31  (31)

typedef struct {
    uint_32_ptr     pcr_reg;
    uint_32_ptr     iomuxc_reg;
    GPIO_MemMapPtr  gpio_ptr;
    uint_32 pinmask; /* since struct holds one pin, pinmask will have only one bit set */
    uint_32 flags;
} LWGPIO_STRUCT, _PTR_ LWGPIO_STRUCT_PTR;

#define LWGPIO_MUX_A0_GPIO  (0)
#define LWGPIO_MUX_A1_GPIO  (0)
#define LWGPIO_MUX_A2_GPIO  (0)
#define LWGPIO_MUX_A3_GPIO  (0)
#define LWGPIO_MUX_A4_GPIO  (0)
#define LWGPIO_MUX_A5_GPIO  (0)
#define LWGPIO_MUX_A6_GPIO  (0)
#define LWGPIO_MUX_A7_GPIO  (0)
#define LWGPIO_MUX_A8_GPIO  (0)
#define LWGPIO_MUX_A9_GPIO  (0)
#define LWGPIO_MUX_A10_GPIO (0)
#define LWGPIO_MUX_A11_GPIO (0)
#define LWGPIO_MUX_A12_GPIO (0)
#define LWGPIO_MUX_A13_GPIO (0)
#define LWGPIO_MUX_A14_GPIO (0)
#define LWGPIO_MUX_A15_GPIO (0)
#define LWGPIO_MUX_A16_GPIO (0)
#define LWGPIO_MUX_A17_GPIO (0)
#define LWGPIO_MUX_A18_GPIO (0)
#define LWGPIO_MUX_A19_GPIO (0)
#define LWGPIO_MUX_A20_GPIO (0)
#define LWGPIO_MUX_A21_GPIO (0)
#define LWGPIO_MUX_A22_GPIO (0)
#define LWGPIO_MUX_A23_GPIO (0)
#define LWGPIO_MUX_A24_GPIO (0)
#define LWGPIO_MUX_A25_GPIO (0)
#define LWGPIO_MUX_A26_GPIO (0)
#define LWGPIO_MUX_A27_GPIO (0)
#define LWGPIO_MUX_A28_GPIO (0)
#define LWGPIO_MUX_A29_GPIO (0)
#define LWGPIO_MUX_A30_GPIO (0)
#define LWGPIO_MUX_A31_GPIO (0)

#define LWGPIO_MUX_B0_GPIO  (0)
#define LWGPIO_MUX_B1_GPIO  (0)
#define LWGPIO_MUX_B2_GPIO  (0)
#define LWGPIO_MUX_B3_GPIO  (0)
#define LWGPIO_MUX_B4_GPIO  (0)
#define LWGPIO_MUX_B5_GPIO  (0)
#define LWGPIO_MUX_B6_GPIO  (0)
#define LWGPIO_MUX_B7_GPIO  (0)
#define LWGPIO_MUX_B8_GPIO  (0)
#define LWGPIO_MUX_B9_GPIO  (0)
#define LWGPIO_MUX_B10_GPIO (0)
#define LWGPIO_MUX_B11_GPIO (0)
#define LWGPIO_MUX_B12_GPIO (0)
#define LWGPIO_MUX_B13_GPIO (0)
#define LWGPIO_MUX_B14_GPIO (0)
#define LWGPIO_MUX_B15_GPIO (0)
#define LWGPIO_MUX_B16_GPIO (0)
#define LWGPIO_MUX_B17_GPIO (0)
#define LWGPIO_MUX_B18_GPIO (0)
#define LWGPIO_MUX_B19_GPIO (0)
#define LWGPIO_MUX_B20_GPIO (0)
#define LWGPIO_MUX_B21_GPIO (0)
#define LWGPIO_MUX_B22_GPIO (0)
#define LWGPIO_MUX_B23_GPIO (0)
#define LWGPIO_MUX_B24_GPIO (0)
#define LWGPIO_MUX_B25_GPIO (0)
#define LWGPIO_MUX_B26_GPIO (0)
#define LWGPIO_MUX_B27_GPIO (0)
#define LWGPIO_MUX_B28_GPIO (0)
#define LWGPIO_MUX_B29_GPIO (0)
#define LWGPIO_MUX_B30_GPIO (0)
#define LWGPIO_MUX_B31_GPIO (0)

#define LWGPIO_MUX_C0_GPIO  (0)
#define LWGPIO_MUX_C1_GPIO  (0)
#define LWGPIO_MUX_C2_GPIO  (0)
#define LWGPIO_MUX_C3_GPIO  (0)
#define LWGPIO_MUX_C4_GPIO  (0)
#define LWGPIO_MUX_C5_GPIO  (0)
#define LWGPIO_MUX_C6_GPIO  (0)
#define LWGPIO_MUX_C7_GPIO  (0)
#define LWGPIO_MUX_C8_GPIO  (0)
#define LWGPIO_MUX_C9_GPIO  (0)
#define LWGPIO_MUX_C10_GPIO (0)
#define LWGPIO_MUX_C11_GPIO (0)
#define LWGPIO_MUX_C12_GPIO (0)
#define LWGPIO_MUX_C13_GPIO (0)
#define LWGPIO_MUX_C14_GPIO (0)
#define LWGPIO_MUX_C15_GPIO (0)
#define LWGPIO_MUX_C16_GPIO (0)
#define LWGPIO_MUX_C17_GPIO (0)
#define LWGPIO_MUX_C18_GPIO (0)
#define LWGPIO_MUX_C19_GPIO (0)
#define LWGPIO_MUX_C20_GPIO (0)
#define LWGPIO_MUX_C21_GPIO (0)
#define LWGPIO_MUX_C22_GPIO (0)
#define LWGPIO_MUX_C23_GPIO (0)
#define LWGPIO_MUX_C24_GPIO (0)
#define LWGPIO_MUX_C25_GPIO (0)
#define LWGPIO_MUX_C26_GPIO (0)
#define LWGPIO_MUX_C27_GPIO (0)
#define LWGPIO_MUX_C28_GPIO (0)
#define LWGPIO_MUX_C29_GPIO (0)
#define LWGPIO_MUX_C30_GPIO (0)
#define LWGPIO_MUX_C31_GPIO (0)

#define LWGPIO_MUX_D0_GPIO  (0)
#define LWGPIO_MUX_D1_GPIO  (0)
#define LWGPIO_MUX_D2_GPIO  (0)
#define LWGPIO_MUX_D3_GPIO  (0)
#define LWGPIO_MUX_D4_GPIO  (0)
#define LWGPIO_MUX_D5_GPIO  (0)
#define LWGPIO_MUX_D6_GPIO  (0)
#define LWGPIO_MUX_D7_GPIO  (0)
#define LWGPIO_MUX_D8_GPIO  (0)
#define LWGPIO_MUX_D9_GPIO  (0)
#define LWGPIO_MUX_D10_GPIO (0)
#define LWGPIO_MUX_D11_GPIO (0)
#define LWGPIO_MUX_D12_GPIO (0)
#define LWGPIO_MUX_D13_GPIO (0)
#define LWGPIO_MUX_D14_GPIO (0)
#define LWGPIO_MUX_D15_GPIO (0)
#define LWGPIO_MUX_D16_GPIO (0)
#define LWGPIO_MUX_D17_GPIO (0)
#define LWGPIO_MUX_D18_GPIO (0)
#define LWGPIO_MUX_D19_GPIO (0)
#define LWGPIO_MUX_D20_GPIO (0)
#define LWGPIO_MUX_D21_GPIO (0)
#define LWGPIO_MUX_D22_GPIO (0)
#define LWGPIO_MUX_D23_GPIO (0)
#define LWGPIO_MUX_D24_GPIO (0)
#define LWGPIO_MUX_D25_GPIO (0)
#define LWGPIO_MUX_D26_GPIO (0)
#define LWGPIO_MUX_D27_GPIO (0)
#define LWGPIO_MUX_D28_GPIO (0)
#define LWGPIO_MUX_D29_GPIO (0)
#define LWGPIO_MUX_D30_GPIO (0)
#define LWGPIO_MUX_D31_GPIO (0)

#define LWGPIO_MUX_E0_GPIO  (0)
#define LWGPIO_MUX_E1_GPIO  (0)
#define LWGPIO_MUX_E2_GPIO  (0)
#define LWGPIO_MUX_E3_GPIO  (0)
#define LWGPIO_MUX_E4_GPIO  (0)
#define LWGPIO_MUX_E5_GPIO  (0)
#define LWGPIO_MUX_E6_GPIO  (0)
#define LWGPIO_MUX_E7_GPIO  (0)
#define LWGPIO_MUX_E8_GPIO  (0)
#define LWGPIO_MUX_E9_GPIO  (0)
#define LWGPIO_MUX_E10_GPIO (0)
#define LWGPIO_MUX_E11_GPIO (0)
#define LWGPIO_MUX_E12_GPIO (0)
#define LWGPIO_MUX_E13_GPIO (0)
#define LWGPIO_MUX_E14_GPIO (0)
#define LWGPIO_MUX_E15_GPIO (0)
#define LWGPIO_MUX_E16_GPIO (0)
#define LWGPIO_MUX_E17_GPIO (0)
#define LWGPIO_MUX_E18_GPIO (0)
#define LWGPIO_MUX_E19_GPIO (0)
#define LWGPIO_MUX_E20_GPIO (0)
#define LWGPIO_MUX_E21_GPIO (0)
#define LWGPIO_MUX_E22_GPIO (0)
#define LWGPIO_MUX_E23_GPIO (0)
#define LWGPIO_MUX_E24_GPIO (0)
#define LWGPIO_MUX_E25_GPIO (0)
#define LWGPIO_MUX_E26_GPIO (0)
#define LWGPIO_MUX_E27_GPIO (0)
#define LWGPIO_MUX_E28_GPIO (0)
#define LWGPIO_MUX_E29_GPIO (0)
#define LWGPIO_MUX_E30_GPIO (0)
#define LWGPIO_MUX_E31_GPIO (0)

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mcf52xx_prv.h<|end_filename|>
#ifndef __INT_FLASH_MCF52XX_PRV_H__
#define __INT_FLASH_MCF52XX_PRV_H__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mcf52xx_prv.h$
* $Version : 3.8.1.0$
* $Date    : Oct-4-2011$
*
* Comments:
*
*   The file contains functions prototype, defines for the internal 
*   flash driver
*
*END************************************************************************/

#define CFM_IPS_FLASH_ADDR              0x44000000

/* address in memory map to write in FLASH */
#define FLASH_START_ADDRESS  CFM_IPS_FLASH_ADDR

/* End address for region of flash */
#define FLASH_END_ADDRESS   (vuint32)&__FLASH_SIZE+0x44000000

typedef struct internal_52xx_struct 
{
    vchar_ptr  cfm_ptr;  /* pointer to CFM structure */
    char_ptr   flash_execute_code_ptr; /* pointer to flash write and erase code */
        
} MCF52XX_FLASH_INTERNAL_STRUCT, _PTR_ MCF52XX_FLASH_INTERNAL_STRUCT_PTR;

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/
#ifdef __cplusplus
extern "C" {
#endif

void    _mcf52xx_set_cfmclkd();

boolean mcf52xx_flash_init(IO_FLASHX_STRUCT_PTR);
void mcf52xx_flash_deinit(IO_FLASHX_STRUCT_PTR);
boolean mcf52xx_flash_erase_sector(IO_FLASHX_STRUCT_PTR, char_ptr, _mem_size);
boolean mcf52xx_flash_write_sector(IO_FLASHX_STRUCT_PTR, char_ptr, char_ptr, _mem_size);

#ifdef __cplusplus
}
#endif

#endif /* __INT_FLASH_MCF52XX_PRV_H__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_kinetis.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_kinetis.c$
* $Version : 3.8.3.0$
* $Date    : Aug-21-2012$
*
* Comments:
*
*   This file contains board-specific LPT initialization functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "timer_qpit.h"

PSP_INTERRUPT_TABLE_INDEX _qpit_vectors[] =
{
	INT_PIT0,  
	INT_PIT1,
	INT_PIT2,
	INT_PIT3
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_qpit_base_address
* Returned Value   : none
* Comments         :
*    Get base address of qpit
*
*END*------------------------------------------------------------------------*/

VQPIT_REG_STRUCT_PTR _bsp_get_qpit_base_address
    (
        /* [IN] PIT index */
    	uint_32 timer  	
    )
{
    if (timer != 0) 
    	return NULL;
    
    return (VQPIT_REG_STRUCT_PTR)PIT_BASE_PTR;	 
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_qpit_vector
* Returned Value   : Vector number upon success, 0 upon failure
* Comments         :
*    This function returns desired interrupt vector number for specified PIT
*
*END*----------------------------------------------------------------------*/

PSP_INTERRUPT_TABLE_INDEX _bsp_get_qpit_vector
    (
        uint_32 timer,
        uint_32 channel
    )
{
	if (timer != 0)
		return INT_Initial_Stack_Pointer; //we return in fact 0 to inform that error occured
	
    return (PSP_INTERRUPT_TABLE_INDEX) _qpit_vectors[channel];  
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_qpit_clk_en
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function enables clock to corresponding MTIM
*
*END*----------------------------------------------------------------------*/
void _bsp_qpit_clk_en (uint_32 timer)
{
    switch (timer) {
        case 0:
        	SIM_SCGC6 |= SIM_SCGC6_PIT_MASK; // Enable PIT Module Clock
          break;
    }
}



<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/host_close.c<|end_filename|>

/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_close.c$
* $Version : 3.8.14.0$
* $Date    : Aug-31-2012$
*
* Comments:
*
*   This file contains the USB Host API specific functions to close pipe(s).
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_main.h"
#include "host_close.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_close_pipe
*  Returned Value : None
*  Comments       :
*        _usb_host_close_pipe routine removes the pipe from the open pipe list
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_close_pipe
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle     handle,
      
      /* [IN] the pipe (handle) to close */
      _usb_pipe_handle     pipe_handle
   )
{ /* Body */
   USB_STATUS error;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   PIPE_STRUCT_PTR pipe_ptr = (PIPE_STRUCT_PTR)pipe_handle;
   PIPE_STRUCT_PTR pipe_bkp_ptr;
   TR_STRUCT_PTR tr_ptr, tr_ptr_next;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_close_pipe");
   #endif

   if (pipe_ptr->PIPE_ID > USBCFG_MAX_PIPES) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_close_pipe invalid pipe");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_PIPE_HANDLE);
   } /* Endif */

   USB_lock();

   /* Call the low-level routine to free the controller specific resources */
   error = _usb_host_close_pipe_call_interface (handle, pipe_ptr);
   if (error != USB_OK)
   {
      USB_unlock();

      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_close_pipe FAILED");
      #endif
         
      return USB_log_error(__FILE__,__LINE__,error);
   }

   /* before cleaning pipe_ptr struct we need to deallocate structures in the circullar list */
   if (pipe_ptr->tr_list_ptr != NULL) {
      tr_ptr = pipe_ptr->tr_list_ptr;
      do {
         tr_ptr_next = tr_ptr->NEXT;	 
         /* free transaction belonging to this pipe */
         USB_mem_free(tr_ptr);
         tr_ptr = tr_ptr_next;
      } while (tr_ptr != pipe_ptr->tr_list_ptr);  

      //pipe_ptr->tr_list_ptr = NULL; //this will be done later by zeroing pipe_ptr
   }

   /* de-initialise the pipe descriptor, but preserve the chain */
   pipe_bkp_ptr = pipe_ptr->NEXT;

   USB_mem_zero(pipe_ptr, sizeof(PIPE_STRUCT));
   /* restore the chain */
   pipe_ptr->NEXT = pipe_bkp_ptr;

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_close_pipe SUCCESSFUL");
   #endif

   return USB_OK;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_close_all_pipes
*  Returned Value : None
*  Comments       :
*  _usb_host_close_all_pipes routine removes the pipe from the open pipe list
*
*END*-----------------------------------------------------------------*/
void  _usb_host_close_all_pipes
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle  handle
   )
{ /* Body */
   int_16 i;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr;
   PIPE_STRUCT_PTR pipe_ptr, pipe_bkp_ptr;
   TR_STRUCT_PTR tr_ptr, tr_ptr_next;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_close_all_pipes");
   #endif

   USB_lock();

   for (pipe_ptr = usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR; pipe_ptr != NULL; pipe_ptr = pipe_ptr->NEXT) {
      if (pipe_ptr->OPEN) {
         /* Call the low-level routine to free the controller specific resources for this pipe */
         _usb_host_close_pipe_call_interface (handle, pipe_ptr);

         /* before cleaning pipe_ptr struct we need to deallocate structures in the circullar list */
         if (pipe_ptr->tr_list_ptr != NULL) {
      	    tr_ptr = pipe_ptr->tr_list_ptr;
            do {
      	       tr_ptr_next = tr_ptr->NEXT;
               /* free transaction belonging to this pipe */
               USB_mem_free(tr_ptr);
               tr_ptr = tr_ptr_next;
            } while (tr_ptr != pipe_ptr->tr_list_ptr);  

            //pipe_ptr->tr_list_ptr = NULL; //this will be done later by zeroing pipe_ptr
         }

         /* de-initialise the pipe descriptor, but prevent the chain */
         pipe_bkp_ptr = pipe_ptr->NEXT;

         USB_mem_zero(pipe_ptr, sizeof(PIPE_STRUCT));
         /* restore the chain */
         pipe_ptr->NEXT = pipe_bkp_ptr;
      } /* Endif */
   } /* Endfor */
   
   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_close_all_pipes SUCCESSFUL");
   #endif
   
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/include/dev_main.h<|end_filename|>
#ifndef __dev_main_h__
#define __dev_main_h__ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dev_main.h$
* $Version : 3.8.1.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*  This file contains the declarations specific to the USB Device API
*
*END*********************************************************************/
#include "mqx_dev.h"

typedef struct xd_struct 
{
   uchar          EP_NUM;           /* Endpoint number */
   uchar          BDIRECTION;       /* Direction : Send/Receive */
   uint_8         EP_TYPE;          /* Type of the endpoint: Ctrl, Isoch, Bulk, Int */
   uchar          BSTATUS;          /* Current transfer status */
   uint_8_ptr     WSTARTADDRESS;    /* Address of first byte */
   uint_32        WTOTALLENGTH;     /* Number of bytes to send/recv */
   uint_32        WSOFAR;           /* Number of bytes recv'd so far */
   uint_16        WMAXPACKETSIZE;   /* Max Packet size */
   boolean        DONT_ZERO_TERMINATE;
   SCRATCH_STRUCT_PTR SCRATCH_PTR;
} XD_STRUCT, _PTR_ XD_STRUCT_PTR;

typedef struct usb_dev_state_struct {
   pointer                          INIT_PARAM;          /* Device controller init parameters */
   pointer                          DEV_PTR;             /* Device Controller Register base address */
   const USB_DEV_CALLBACK_FUNCTIONS_STRUCT * CALLBACK_STRUCT_PTR;
   SCRATCH_STRUCT_PTR               XD_SCRATCH_STRUCT_BASE;
   SCRATCH_STRUCT_PTR               SCRATCH_STRUCT_BASE;
   
   SERVICE_STRUCT_PTR               SERVICE_HEAD_PTR;    /* Head struct address of registered services */
   struct xd_struct               * TEMP_XD_PTR;         /* Temp xd for ep init */
   struct xd_struct               * XD_BASE;
   struct xd_struct               * XD_HEAD;             /* Head Transaction descriptors */
   struct xd_struct               * XD_TAIL;             /* Tail Transaction descriptors */
   struct xd_struct               * PENDING_XD_PTR;      /* pending transfer */
   uint_32                          XD_ENTRIES;

   /* These fields are kept only for USB_shutdown() */
   uint_16                          USB_STATE;
   uint_16                          USB_DEVICE_STATE;
   uint_16                          USB_SOF_COUNT;
   uint_16                          ERRORS;
   uint_16                          USB_DEV_STATE_B4_SUSPEND;
   uint_8                           DEV_NUM;             /* Deprecated, avoid usage; USB device number on the board */
   uint_8                           DEV_VEC;             /* Interrupt vector number for USB OTG */
   uint_8                           SPEED;               /* Low Speed, High Speed, Full Speed */
   uint_8                           MAX_ENDPOINTS;       /* Max endpoints supported by this device */
                                                         
   uint_16                          USB_CURR_CONFIG;                                                         
   uint_8                           DEVICE_ADDRESS;
} USB_DEV_STATE_STRUCT, _PTR_ USB_DEV_STATE_STRUCT_PTR;

#define USB_XD_QADD(head,tail,XD)      \
   if ((head) == NULL) {         \
      (head) = (XD);            \
   } else {                      \
      (tail)->SCRATCH_PTR->PRIVATE = (XD);   \
   } /* Endif */                 \
   (tail) = (XD);               \
   (XD)->SCRATCH_PTR->PRIVATE = NULL
   
#define USB_XD_QGET(head,tail,XD)      \
   (XD) = (head);               \
   if (head) {                   \
      (head) = (XD_STRUCT_PTR)((head)->SCRATCH_PTR->PRIVATE);  \
      if ((head) == NULL) {      \
         (tail) = NULL;          \
      } /* Endif */              \
   } /* Endif */

#ifdef __cplusplus
{
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/istrata/istrataprv.h<|end_filename|>
#ifndef _istrataprv_h_
#define _istrataprv_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: istrataprv.h$
* $Version : 3.8.8.0$
* $Date    : Oct-4-2011$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions specific for the Intel strataflash devices
*
*END************************************************************************/


/*----------------------------------------------------------------------*/
/*
**                   HARDWARE DEFINITIONS
*/
#define ISTRATA_WRITE_CMD_8X1   (0x40)
#define ISTRATA_WRITE_CMD_8X2   (0x4040)
#define ISTRATA_WRITE_CMD_8X4   (0x40404040)
#define ISTRATA_WRITE_CMD_16X1  (0x0040)
#define ISTRATA_WRITE_CMD_16X2  (0x00400040)
#define ISTRATA_WRITE_CMD_32X1  (0x00000040)

#define ISTRATA_READ_MODE_CMD_8X1   (0xFF)
#define ISTRATA_READ_MODE_CMD_8X2   (0xFFFF)
#define ISTRATA_READ_MODE_CMD_8X4   (0xFFFFFFFF)
#define ISTRATA_READ_MODE_CMD_16X1  (0x00FF)
#define ISTRATA_READ_MODE_CMD_16X2  (0x00FF00FF)
#define ISTRATA_READ_MODE_CMD_32X1  (0x000000FF)

#define ISTRATA_ERASE_CMD1_8X1      (0x20)
#define ISTRATA_ERASE_CMD2_8X1      (0xD0)
#define ISTRATA_ERASE_CMD1_8X2      (0x2020)
#define ISTRATA_ERASE_CMD2_8X2      (0xD0D0)
#define ISTRATA_ERASE_CMD1_8X4      (0x20202020)
#define ISTRATA_ERASE_CMD2_8X4      (0xD0D0D0D0)
#define ISTRATA_ERASE_CMD1_16X1     (0x0020)
#define ISTRATA_ERASE_CMD2_16X1     (0x00D0)
#define ISTRATA_ERASE_CMD1_16X2     (0x00200020)
#define ISTRATA_ERASE_CMD2_16X2     (0x00D000D0)
#define ISTRATA_ERASE_CMD1_32X1     (0x00000020)
#define ISTRATA_ERASE_CMD2_32X1     (0x000000D0)

/* Start CR 871 */
#define ISTRATA_CLEAR_CMD1_8X1      (0x60)
#define ISTRATA_CLEAR_CMD2_8X1      (0xD0)
#define ISTRATA_CLEAR_CMD1_8X2      (0x6060)
#define ISTRATA_CLEAR_CMD2_8X2      (0xD0D0)
#define ISTRATA_CLEAR_CMD1_8X4      (0x60606060)
#define ISTRATA_CLEAR_CMD2_8X4      (0xD0D0D0D0)
#define ISTRATA_CLEAR_CMD1_16X1     (0x0060)
#define ISTRATA_CLEAR_CMD2_16X1     (0x00D0)
#define ISTRATA_CLEAR_CMD1_16X2     (0x00600060)
#define ISTRATA_CLEAR_CMD2_16X2     (0x00D000D0)
#define ISTRATA_CLEAR_CMD1_32X1     (0x00000060)
#define ISTRATA_CLEAR_CMD2_32X1     (0x000000D0)
/* End CR 871 */

#define ISTRATA_SET_CMD1_8X1        (0x60)
#define ISTRATA_SET_CMD2_8X1        (0x01)
#define ISTRATA_SET_CMD1_8X2        (0x6060)
#define ISTRATA_SET_CMD2_8X2        (0x0101)
#define ISTRATA_SET_CMD1_8X4        (0x60606060)
#define ISTRATA_SET_CMD2_8X4        (0x01010101)
#define ISTRATA_SET_CMD1_16X1       (0x0060)
#define ISTRATA_SET_CMD2_16X1       (0x0001)
#define ISTRATA_SET_CMD1_16X2       (0x00600060)
#define ISTRATA_SET_CMD2_16X2       (0x00010001)
#define ISTRATA_SET_CMD1_32X1       (0x00000060)
#define ISTRATA_SET_CMD2_32X1       (0x00000001)

#define ISTRATA_STATUS_BUSY_8X1     (0x80)
#define ISTRATA_STATUS_BUSY_8X2     (0x8080)
#define ISTRATA_STATUS_BUSY_8X4     (0x80808080)
#define ISTRATA_STATUS_BUSY_16X1    (0x0080)
#define ISTRATA_STATUS_BUSY_16X2    (0x00800080)
#define ISTRATA_STATUS_BUSY_32X1    (0x00000080)

/* Start CR 2077 */
#define ISTRATA_READ_ID_MODE_CMD_16X1   (0x0090)
/* End CR 2077 */

#define ISTRATA_WRITE_BUFFER_SIZE   (32)

/* Programming timing definitions in microseconds */
/* Start CR 2077 */
#ifdef I28FXXXC3
/*
** Define the macro in Flash device specific driver file. 
** e.g. mqx2.50\source\bsp\mcfzsdk5329\i28f160c3.c
*/
#define ISTRATA_PROGRAM_WORD_TIME_MAX    200
#else
/*     I28FXXXJ3 */
#define ISTRATA_PROGRAM_WORD_TIME_MAX    630
#endif
/* End CR 2077 */

/* Erase timing definitions in seconds */
#define ISTRATA_PROGRAM_ERASE_TIME_MAX   5

/* Timing definitions in ticks */
#define ISTRATA_PROGRAM_WORD_TICKS_MAX  \
(((ISTRATA_PROGRAM_WORD_TIME_MAX * BSP_ALARM_FREQUENCY) / 1000000) + 3)
   
#define ISTRATA_PROGRAM_ERASE_TICKS_MAX  \
   (ISTRATA_PROGRAM_ERASE_TIME_MAX * BSP_ALARM_FREQUENCY)

/* Start CR 871 */
#define ISTRATA_PROGRAM_CLEAR_TICKS_MAX  ISTRATA_PROGRAM_ERASE_TICKS_MAX
/* End CR 871 */


/*----------------------------------------------------------------------*/
/*
**                   MACROS
*/

/* Macro to do the programming algorithm */
#define ISTRATA_PROGRAM(read_cmd, write_cmd, busy_cmd)                     \
   /* We only have to start where the source and destination diverged */   \
   for ( j = offset; ((j < size) && success); j++ ) {                      \
      tmp = *src_ptr++;     /* data to write */                            \
      *dest_ptr = read_cmd; /* put into read mode to compare */            \
      if (tmp != *dest_ptr) {                                              \
         *dest_ptr = write_cmd;   /* set to write mode */                  \
         *dest_ptr = tmp;         /* write the data    */                  \
         _time_get_elapsed_ticks(&start_ticks);                            \
         timeout = FALSE;                                                  \
         while (!timeout) {                                                \
            /* Read the status register */                                 \
            status = *dest_ptr;                                            \
            if ((status & busy_cmd) == busy_cmd) {                         \
               /* Program complete */                                      \
               break;                                                      \
            } /* Endif */                                                  \
            timeout = _intel_strata_check_timeout(&start_ticks,            \
               ISTRATA_PROGRAM_WORD_TICKS_MAX);                            \
         } /* Endwhile */                                                  \
         /* Start CR 874 */                                                \
         /* success = !timeout || status; */                               \
         success = !timeout;                                               \
         /* End CR 874 */                                                  \
      } /* Endif */                                                        \
      dest_ptr++;                                                          \
   } /* Endfor */                                                          \
   /* Place the device back in read mode */                                \
   dest_ptr--;                                                             \
   *dest_ptr = read_cmd

/* Macro to do the sector erase algorithm */
#define ISTRATA_ERASE(read_cmd, erase_cmd1, erase_cmd2, busy_cmd, erase_pattern) \
      /* erase sequence */                                                 \
      *dest_ptr = erase_cmd1;                                              \
      *dest_ptr = erase_cmd2;                                              \
      _time_get_elapsed_ticks(start_ticks_ptr);                            \
      timeout = FALSE;                                                     \
      while (!timeout) {                                                   \
         status = *dest_ptr;                                               \
         if ((status & busy_cmd) == busy_cmd) {                            \
            /* erase complete */                                           \
            break;                                                         \
         } /* Endif */                                                     \
         timeout = _intel_strata_check_timeout(start_ticks_ptr,            \
            ISTRATA_PROGRAM_ERASE_TICKS_MAX);                              \
      } /* Endwhile */                                                     \
      *dest_ptr = read_cmd;                                                \
      /* success = !timeout || status; */                                  \
      success = !timeout;                                                  \
      _time_get_elapsed_ticks(start_ticks_ptr);                            \
      timeout = FALSE;                                                     \
      while (!timeout) {                                                   \
        if(*dest_ptr == erase_pattern){                                    \
            break;                                                         \
        }                                                                  \
        timeout = _intel_strata_check_timeout(start_ticks_ptr,             \
            ISTRATA_PROGRAM_ERASE_TICKS_MAX);                              \
      }                                                                    \
      success = !timeout;

/* 
** We don't have to erase if bits don't change or they transition from a 1
** to a 0
*/
#define ISTRATA_ERASE_UNIT(unit_in_flash, unit_in_ram) \
   ((((unit_in_flash) ^ (unit_in_ram)) & (unit_in_ram)) != 0)

/* Start CR 871 */
/* Macro to clear the lock bits */
#define ISTRATA_CLEAR_LOCKBITS(read_cmd, clear_cmd1, clear_cmd2, busy_cmd) \
      /* clear lock bits sequence */                                       \
      *dest_ptr = clear_cmd1;                                              \
      *dest_ptr = clear_cmd2;                                              \
      _time_get_elapsed_ticks(start_ticks_ptr);                            \
      timeout = FALSE;                                                     \
      while (!timeout) {                                                   \
         status = *dest_ptr;                                               \
         if ((status & busy_cmd) == busy_cmd) {                            \
            /* clear complete */                                           \
            break;                                                         \
         } /* Endif */                                                     \
         timeout = _intel_strata_check_timeout(start_ticks_ptr,            \
            ISTRATA_PROGRAM_CLEAR_TICKS_MAX);                              \
      } /* Endwhile */                                                     \
      success = !timeout;                                                  \
      *dest_ptr = read_cmd;
/* End CR 871 */

/* Macro to set the lock bits */
#define ISTRATA_SET_LOCKBITS(read_cmd, clear_cmd1, clear_cmd2, busy_cmd) \
      /* set lock bits sequence */                                       \
      *dest_ptr = clear_cmd1;                                              \
      *dest_ptr = clear_cmd2;                                              \
      _time_get_elapsed_ticks(start_ticks_ptr);                            \
      timeout = FALSE;                                                     \
      while (!timeout) {                                                   \
         status = *dest_ptr;                                               \
         if ((status & busy_cmd) == busy_cmd) {                            \
            /* set complete */                                           \
            break;                                                         \
         } /* Endif */                                                     \
         timeout = _intel_strata_check_timeout(start_ticks_ptr,            \
            ISTRATA_PROGRAM_CLEAR_TICKS_MAX);                              \
      } /* Endwhile */                                                     \
      success = !timeout;                                                  \
      *dest_ptr = read_cmd;

/* Start CR 2077 */
/* Macro to read the lock status of the block */
#define ISTRATA_READ_LOCK_STATUS(read_cmd, readid_cmd, busy_cmd) \
      /* set lock bits sequence */                                         \
      *dest_ptr = readid_cmd;                                              \
      status = *((uint_16_ptr)dest_ptr+0x00002);                                           \
      *dest_ptr = read_cmd;
/* End CR 2077 */

/*----------------------------------------------------------------------*/
/*
**                     FUNCTION PROTOTYPES
*/
#ifdef __cplusplus
extern "C" {
#endif

/* Top level functions visible to the generic flashx driver */
boolean _intel_strata_program(IO_FLASHX_STRUCT_PTR, char_ptr, char_ptr, _mem_size);
boolean _intel_strata_erase(IO_FLASHX_STRUCT_PTR, char_ptr, _mem_size);
boolean _intel_strata_write_protect(IO_FLASHX_STRUCT_PTR , _mqx_uint);
_mqx_int _io_intel_strata_ioctl(IO_FLASHX_STRUCT_PTR, _mqx_uint, pointer);

/* lower level functions private to the strata flash driver */
boolean _intel_strata_clear_lock_bits(IO_FLASHX_STRUCT_PTR);
boolean _intel_strata_set_lock_bits(IO_FLASHX_STRUCT_PTR);

boolean _intel_strata_check_timeout(MQX_TICK_STRUCT_PTR, _mqx_uint);
boolean _intel_strata_program_1byte(IO_FLASHX_STRUCT_PTR, char_ptr, char_ptr, _mem_size, _mqx_uint);
boolean _intel_strata_erase_1byte(IO_FLASHX_STRUCT_PTR, char_ptr, _mem_size, MQX_TICK_STRUCT_PTR);
boolean _intel_strata_program_2byte(IO_FLASHX_STRUCT_PTR, uint_16_ptr, uint_16_ptr, _mem_size, _mqx_uint);
boolean _intel_strata_erase_2byte(IO_FLASHX_STRUCT_PTR, uint_16_ptr, _mem_size, MQX_TICK_STRUCT_PTR);
boolean _intel_strata_program_4byte(IO_FLASHX_STRUCT_PTR, uint_32_ptr, uint_32_ptr, _mem_size, _mqx_uint);
boolean _intel_strata_erase_4byte(IO_FLASHX_STRUCT_PTR, uint_32_ptr, _mem_size, MQX_TICK_STRUCT_PTR);
boolean _intel_strata_init(IO_FLASHX_STRUCT_PTR);

boolean _intel_strata_clearlockbits_1byte(IO_FLASHX_STRUCT_PTR, MQX_TICK_STRUCT_PTR);
boolean _intel_strata_clearlockbits_2byte(IO_FLASHX_STRUCT_PTR, MQX_TICK_STRUCT_PTR);
boolean _intel_strata_clearlockbits_4byte(IO_FLASHX_STRUCT_PTR, MQX_TICK_STRUCT_PTR);

boolean _intel_strata_setlockbits_1byte(IO_FLASHX_STRUCT_PTR, MQX_TICK_STRUCT_PTR);
boolean _intel_strata_setlockbits_2byte(IO_FLASHX_STRUCT_PTR, MQX_TICK_STRUCT_PTR);
boolean _intel_strata_setlockbits_4byte(IO_FLASHX_STRUCT_PTR, MQX_TICK_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/BSP/GPIO.h<|end_filename|>
#ifndef __INIT_PINS
  #define __INIT_PINS

int Init_pins(void);
void Led_control(int led_num, int state);
int  Led_state(int led_num);
void LCD_RST(int state);
void LCD_SCL(int state);
void LCD_SI(int state);
void LCD_RS(int state);
void LCD_SCB(int state);

#endif

<|start_filename|>Firmware/Inverter_bootloader/BSP/PE/PE_Error.h<|end_filename|>
#ifndef __PE_Error_H
  #define __PE_Error_H

  #define ERR_OK                          0x00U /*!< OK */
  #define ERR_SPEED                       0x01U /*!< This device does not work in the active speed mode. */
  #define ERR_RANGE                       0x02U /*!< Parameter out of range. */
  #define ERR_VALUE                       0x03U /*!< Parameter of incorrect value. */
  #define ERR_OVERFLOW                    0x04U /*!< Timer overflow. */
  #define ERR_MATH                        0x05U /*!< Overflow during evaluation. */
  #define ERR_ENABLED                     0x06U /*!< Device is enabled. */
  #define ERR_DISABLED                    0x07U /*!< Device is disabled. */
  #define ERR_BUSY                        0x08U /*!< Device is busy. */
  #define ERR_NOTAVAIL                    0x09U /*!< Requested value or method not available. */
  #define ERR_RXEMPTY                     0x0AU /*!< No data in receiver. */
  #define ERR_TXFULL                      0x0BU /*!< Transmitter is full. */
  #define ERR_BUSOFF                      0x0CU /*!< Bus not available. */
  #define ERR_OVERRUN                     0x0DU /*!< Overrun error is detected. */
  #define ERR_FRAMING                     0x0EU /*!< Framing error is detected. */
  #define ERR_PARITY                      0x0FU /*!< Parity error is detected. */
  #define ERR_NOISE                       0x10U /*!< Noise error is detected. */
  #define ERR_IDLE                        0x11U /*!< Idle error is detected. */
  #define ERR_FAULT                       0x12U /*!< Fault error is detected. */
  #define ERR_BREAK                       0x13U /*!< Break char is received during communication. */
  #define ERR_CRC                         0x14U /*!< CRC error is detected. */
  #define ERR_ARBITR                      0x15U /*!< A node losts arbitration. This error occurs if two nodes start transmission at the same time. */
  #define ERR_PROTECT                     0x16U /*!< Protection error is detected. */
  #define ERR_UNDERFLOW                   0x17U /*!< Underflow error is detected. */
  #define ERR_UNDERRUN                    0x18U /*!< Underrun error is detected. */
  #define ERR_COMMON                      0x19U /*!< Common error of a device. */
  #define ERR_LINSYNC                     0x1AU /*!< LIN synchronization error is detected. */
  #define ERR_FAILED                      0x1BU /*!< Requested functionality or process failed. */
  #define ERR_QFULL                       0x1CU /*!< Queue is full. */
  #define ERR_PARAM_MASK                  0x80U /*!< Invalid mask. */
  #define ERR_PARAM_MODE                  0x81U /*!< Invalid mode. */
  #define ERR_PARAM_INDEX                 0x82U /*!< Invalid index. */
  #define ERR_PARAM_DATA                  0x83U /*!< Invalid data. */
  #define ERR_PARAM_SIZE                  0x84U /*!< Invalid size. */
  #define ERR_PARAM_VALUE                 0x85U /*!< Invalid value. */
  #define ERR_PARAM_RANGE                 0x86U /*!< Invalid parameter's range or parameters' combination. */
  #define ERR_PARAM_LOW_VALUE             0x87U /*!< Invalid value (LOW part). */
  #define ERR_PARAM_HIGH_VALUE            0x88U /*!< Invalid value (HIGH part). */
  #define ERR_PARAM_ADDRESS               0x89U /*!< Invalid address. */
  #define ERR_PARAM_PARITY                0x8AU /*!< Invalid parity. */
  #define ERR_PARAM_WIDTH                 0x8BU /*!< Invalid width. */
  #define ERR_PARAM_LENGTH                0x8CU /*!< Invalid length. */
  #define ERR_PARAM_ADDRESS_TYPE          0x8DU /*!< Invalid address type. */
  #define ERR_PARAM_COMMAND_TYPE          0x8EU /*!< Invalid command type. */
  #define ERR_PARAM_COMMAND               0x8FU /*!< Invalid command. */
  #define ERR_PARAM_RECIPIENT             0x90U /*!< Invalid recipient. */
  #define ERR_PARAM_BUFFER_COUNT          0x91U /*!< Invalid buffer count. */
  #define ERR_PARAM_ID                    0x92U /*!< Invalid ID. */
  #define ERR_PARAM_GROUP                 0x93U /*!< Invalid group. */
  #define ERR_PARAM_CHIP_SELECT           0x94U /*!< Invalid chip select. */
  #define ERR_PARAM_ATTRIBUTE_SET         0x95U /*!< Invalid set of attributes. */
  #define ERR_PARAM_SAMPLE_COUNT          0x96U /*!< Invalid sample count. */
  #define ERR_PARAM_CONDITION             0x97U /*!< Invalid condition. */
  #define ERR_PARAM_TICKS                 0x98U /*!< Invalid ticks parameter. */

#endif /* __PE_Error_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/mqxa/pcb_mqxa.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pcb_mqxa.c$
* $Version : 3.8.8.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the code which implements a PCB driver
*   that sends MQX format packets over an asynchronous serial driver.
*
*END************************************************************************/

#include "mqx_inc.h"

#if MQX_USE_IPC

#include "fio.h"
#include "io.h"
#include "io_prv.h"
#include "serial.h"
#include "io_pcb.h"
#include "iopcbprv.h"
#include "pcb_mqxa.h"
#include "pcbmqxav.h"


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_mqxa_install
* Returned Value  : _mqx_uint result   MQX_OK or an error code.
* Comments        :
*     This function is use to install the I/O device.
*
*END*---------------------------------------------------------------------*/

_mqx_uint _io_pcb_mqxa_install
   (
      /* [IN] the name of this device */
      char_ptr    device_name_ptr,
      
      /* [IN] the initialization record for this device */
      pointer     init_ptr
   )
{ /* Body */
   IO_PCB_MQXA_INFO_STRUCT_PTR info_ptr;

   info_ptr = _mem_alloc_system_zero(sizeof(IO_PCB_MQXA_INFO_STRUCT));
   if (info_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   }/* Endif */
   info_ptr->INIT = *((IO_PCB_MQXA_INIT_STRUCT_PTR)init_ptr);

   return (_io_pcb_dev_install(device_name_ptr,
      _io_pcb_mqxa_open,
      _io_pcb_mqxa_close,
      _io_pcb_mqxa_read,
      _io_pcb_mqxa_write, 
      _io_pcb_mqxa_ioctl,
      _io_pcb_mqxa_uninstall,
      (pointer)info_ptr)); 
   
} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_mqxa_open
* Returned Value  : _mqx_int result MQX_OK or an error code.
* Comments        :
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_mqxa_open
   (
      /* [IN] the file handle */
      FILE_DEVICE_STRUCT_PTR fd_ptr, 

      /* [IN] the rest of the filename used to open the device */
      char _PTR_             open_name_ptr,

      /* [IN] the open flags for this device */
      char _PTR_             open_mode_flags
   )
{ /* Body */
   IO_PCB_MQXA_INFO_STRUCT_PTR info_ptr;
   IO_PCB_DEVICE_STRUCT_PTR    dev_ptr;
   _mqx_uint                   flags;

   dev_ptr = (IO_PCB_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   fd_ptr->DEV_DATA_PTR = dev_ptr->DRIVER_INIT_PTR;
   info_ptr = (IO_PCB_MQXA_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;
   if (info_ptr->FD) {
      fd_ptr->ERROR = IO_PCB_MQXA_DEVICE_ALREADY_OPEN;
      return(IO_ERROR);
   }/* Endif */
   info_ptr->FD = fopen(info_ptr->INIT.IO_PORT_NAME, (char_ptr)0);
   if (info_ptr->FD == NULL) {
      fd_ptr->ERROR = IO_PCB_MQXA_INCORRECT_SERIAL_DEVICE;
      return(IO_ERROR);
   } /* Endif */

   /* Set the baud rate on the serial device, if a non zero value for baud is supplied. Otherwise, used default rate */
   if (info_ptr->INIT.BAUD_RATE) {
       if (ioctl(info_ptr->FD, IO_IOCTL_SERIAL_SET_BAUD,
          (pointer)&info_ptr->INIT.BAUD_RATE) != MQX_OK)
       {
          fclose(info_ptr->FD);
          info_ptr->FD = NULL;
          fd_ptr->ERROR = IO_PCB_MQXA_INCORRECT_SERIAL_DEVICE;
          return(IO_ERROR);
       }
   }

   /* Turn off xon/xoff, translation and echo on the serial device */
   ioctl(info_ptr->FD, IO_IOCTL_SERIAL_GET_FLAGS, (pointer)&flags);
   flags &= ~(IO_SERIAL_XON_XOFF | IO_SERIAL_TRANSLATION | IO_SERIAL_ECHO);
   ioctl(info_ptr->FD, IO_IOCTL_SERIAL_SET_FLAGS, &flags);

   fd_ptr->DEV_DATA_PTR = info_ptr;
   fd_ptr->FLAGS       |= IO_FLAG_IS_PCB_DEVICE;
   
   info_ptr->READ_CALLBACK_FUNCTION = NULL;
   _lwsem_create(&info_ptr->READ_LWSEM, 0);
   _lwsem_create(&info_ptr->WRITE_LWSEM, 0);
   _queue_init(&info_ptr->READ_QUEUE, 0);
   _queue_init(&info_ptr->WRITE_QUEUE, 0);

   return(MQX_OK);
   
} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_mqxa_close
* Returned Value  : _mqx_int result   MQX_OK or an error code.
* Comments        :
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_mqxa_close
   (
      /* [IN] the file handle */
      FILE_DEVICE_STRUCT_PTR fd_ptr
   )
{ /* Body */
   IO_PCB_MQXA_INFO_STRUCT_PTR info_ptr;
   IO_PCB_STRUCT_PTR           pcb_ptr;

#if MQX_CHECK_ERRORS
   if (!(fd_ptr->FLAGS & IO_FLAG_IS_PCB_DEVICE)) {
      fd_ptr->ERROR = IO_PCB_NOT_A_PCB_DEVICE;
      return(IO_ERROR);
   }/* Endif */
#endif
   info_ptr = (IO_PCB_MQXA_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;
   if (info_ptr->FD) {
      fclose(info_ptr->FD);
      info_ptr->FD = NULL;
   }/* Endif */
   if (info_ptr->INPUT_TASK) {
#if MQX_TASK_DESTRUCTION   
      _task_destroy(info_ptr->INPUT_TASK);
#endif      
      info_ptr->INPUT_TASK = 0;
   }/* Endif */
   if (info_ptr->OUTPUT_TASK ) {
#if MQX_TASK_DESTRUCTION   
      _task_destroy(info_ptr->OUTPUT_TASK);
#endif
      info_ptr->OUTPUT_TASK = 0;
   }/* Endif */
   _lwsem_destroy(&info_ptr->READ_LWSEM);
   _lwsem_destroy(&info_ptr->WRITE_LWSEM);

   while (_queue_get_size(&info_ptr->WRITE_QUEUE)) {
      pcb_ptr = (IO_PCB_STRUCT_PTR)
         ((pointer)_queue_dequeue(&info_ptr->WRITE_QUEUE));
      _io_pcb_free(pcb_ptr);
   } /* Endwhile */

   while (_queue_get_size(&info_ptr->READ_QUEUE)) {
      pcb_ptr = (IO_PCB_STRUCT_PTR)
         ((pointer)_queue_dequeue(&info_ptr->READ_QUEUE));
      _io_pcb_free(pcb_ptr);
   } /* Endwhile */

   return(MQX_OK);
   
} /* Endbody */


/*READ*---------------------------------------------------------------------
*
* Function Name   : _io_pcb_mqxa_read
* Returned Value  : _mqx_int result MQX_OK or an error code.
* Comments        :
*     This function reads a packet directly 
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_mqxa_read
   (
      /* [IN] the file descriptor */
      FILE_DEVICE_STRUCT_PTR  fd_ptr,
      
      /* [IN] the pcb address from which to write data */
      IO_PCB_STRUCT_PTR _PTR_ pcb_ptr
   )
{ /* Body */
   IO_PCB_MQXA_INFO_STRUCT_PTR info_ptr;

   info_ptr = fd_ptr->DEV_DATA_PTR;
   if (info_ptr->FD) {
      _int_disable();
      /* 
      ** Start CR 383
      ** if (info_ptr->FD->FLAGS & IO_O_NONBLOCK) {
      */
      if (fd_ptr->FLAGS & IO_O_NONBLOCK) {
      /* End CR 383 */
         if (! _queue_get_size(&info_ptr->READ_QUEUE)) {
            *pcb_ptr = NULL;
            _int_enable();
            /* 
            ** Start CR 384
            ** return(0);
            */
            return MQX_OK;
            /* End CR 384 */
         } /* Endif */
      } /* Endif */
      _lwsem_wait(&info_ptr->READ_LWSEM);
      *pcb_ptr = (IO_PCB_STRUCT_PTR)
         ((pointer)_queue_dequeue(&info_ptr->READ_QUEUE));
      _int_enable();
      /* 
      ** Start CR 384
      ** return(0);
      */
      return MQX_OK;
      /* End CR 384 */
   }/* Endif */
   return(IO_ERROR);

} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_mqxa_write
* Returned Value  : _mqx_uint result   MQX_OK or an error code.
* Comments        :
*     This function sends the pcb to the pcb output task.
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_mqxa_write
   (
      /* [IN] the file descriptor */
      FILE_DEVICE_STRUCT_PTR  fd_ptr,
      
      /* [IN] the pcb address from which to write data */
      IO_PCB_STRUCT_PTR       pcb_ptr
   )
{ /* Body */
   IO_PCB_MQXA_INFO_STRUCT_PTR info_ptr;

   info_ptr = fd_ptr->DEV_DATA_PTR;
   if (info_ptr->FD) {
      _queue_enqueue((QUEUE_STRUCT_PTR)((pointer)&info_ptr->WRITE_QUEUE), 
         (QUEUE_ELEMENT_STRUCT_PTR)((pointer)&pcb_ptr->QUEUE));
      _lwsem_post(&info_ptr->WRITE_LWSEM);
      /* 
      ** Start CR 384
      ** return(0);
      */
      return MQX_OK;
      /* End CR 384 */
   }/* Endif */
   return(IO_ERROR);
   
} /* Endbody */


/*TASK*---------------------------------------------------------------------
*
* Task Name       : _io_pcb_mqxa_read_task
* Comments        :
*     This task reads a packet from the async serial device.
*  The packet is in MQX Asynchronous Packet format.
*
*END*---------------------------------------------------------------------*/

void _io_pcb_mqxa_read_task
   (
      /* [IN] the device info */
      uint_32 parameter
   )
{ /* Body */
   IO_PCB_MQXA_INFO_STRUCT_PTR info_ptr;
   IO_PCB_STRUCT_PTR           pcb_ptr;
   uchar_ptr                   input_ptr;
   uchar_ptr                   input_init_ptr;
   boolean                     got_length = 0;
   _mem_size                   input_length = 0;
   _mem_size                   max_length = 0;
   _mem_size                   count = 0;
   _mqx_uint                   state = 0;
   _mqx_uint                   next_state = 0;
   uchar                       crc0 = 0;
   uchar                       crc1 = 0;
   uchar                       packet_crc0 = 0;
   uchar                       packet_crc1 = 0;
   uchar                       tmp;
   uchar                       c;

   info_ptr = (IO_PCB_MQXA_INFO_STRUCT_PTR)parameter;

   /* Get a PCB */
   pcb_ptr = _io_pcb_alloc(info_ptr->READ_PCB_POOL, FALSE);
#if MQX_CHECK_ERRORS
   if (pcb_ptr == NULL) {
      _task_block();
   } /* Endif */
#endif
   max_length     = info_ptr->INIT.INPUT_MAX_LENGTH;
   input_init_ptr = pcb_ptr->FRAGMENTS[0].FRAGMENT;

   state      = AP_STATE_SYNC; /* Waiting for sync */
   next_state = AP_STATE_SYNC; /* Waiting for sync */

   while (TRUE) {

      if (info_ptr->INIT.IS_POLLED) {
         while (!fstatus(info_ptr->FD)) {
            _time_delay_ticks(1);
         } /* Endwhile */
      } /* Endif */
      c = (uchar)fgetc(info_ptr->FD);

      switch (state) {

         case AP_STATE_SYNC:
            if (c == AP_SYNC) {
               /* Sync detected. Start packet reception. */
               state      = AP_STATE_READING;
               next_state = AP_STATE_SYNC;
               count      = 0;
               input_ptr  = input_init_ptr;
               crc0       = 0x7e;
               crc1       = 0x7e;
               got_length = FALSE;
            } /* Endif */
            break;

         case AP_STATE_SYNC_SKIP:
            if (c != AP_SYNC) {
               /* Single sync detected. Restart message reception. */
               count      = 0;
               input_ptr  = input_init_ptr;
               crc0       = 0x7e;
               crc1       = 0x7e;
               got_length = FALSE;
               *input_ptr++ = c;
               ++count;
               AP_CHECKSUM(c, crc0, crc1);
               state = AP_STATE_READING;
            } else {
               state = next_state;
            } /* Endif */
            break;

         case AP_STATE_READING:
            *input_ptr++ = c;
            ++count;
            AP_CHECKSUM(c, crc0, crc1);

            if (got_length ) {
               if (count >= input_length){
                  state = AP_STATE_CS0;
               } /* Endif */
            } else {
               if ( count > MQXA_MSG_CONTROL_OFFSET) {
                  /* The complete packet header has been read in */
                  input_length = GET_LENGTH(input_init_ptr);
                  if (input_length > max_length) {
                     next_state = AP_STATE_SYNC;
                     ++info_ptr->RX_PACKETS_TOO_LONG;
                  } else {
                     got_length = TRUE;
                     if (count >= input_length) {
                        state = AP_STATE_CS0;
                     } /* Endif */
                 } /* Endif */
               } /* Endif */
            } /* Endif */

            if (c == AP_SYNC) {
               next_state = state;
               state      = AP_STATE_SYNC_SKIP;
            } /* Endif */
            break;

         case AP_STATE_CS0:
            packet_crc0 = c;
            state = AP_STATE_CS1;
            if (c == AP_SYNC) {
               next_state = state;
               state      = AP_STATE_SYNC_SKIP;
            } /* Endif */
            break;

         case AP_STATE_CS1:
            packet_crc1 = c;
            state = AP_STATE_DONE;
            if (c == AP_SYNC) {
               next_state = state;
               state      = AP_STATE_SYNC_SKIP;
            } /* Endif */
            break;

         default:
            state = AP_STATE_SYNC;
            break;

      } /* Endswitch */

      if ( state == AP_STATE_DONE ) {
         /* Calculate the CRCs */
         crc1  = (crc1 + 2 * crc0) & 0xFF;
         tmp   = crc0 - crc1;
         crc1  = (crc1 - (crc0 * 2)) & 0xFF;
         crc0  = tmp & 0xFF;

         if ((crc0 == packet_crc0) && (crc1 == packet_crc1)) {
            ++info_ptr->RX_PACKETS;
            pcb_ptr->FRAGMENTS[0].LENGTH = input_length;
            if (info_ptr->READ_CALLBACK_FUNCTION) {
               /* Start CR 398 */
               (*info_ptr->READ_CALLBACK_FUNCTION)(info_ptr->CALLBACK_FD, pcb_ptr);
               /* End CR */
            } else {
               _queue_enqueue((QUEUE_STRUCT_PTR)&info_ptr->READ_QUEUE,
                  (QUEUE_ELEMENT_STRUCT_PTR)&pcb_ptr->QUEUE);
               _lwsem_post(&info_ptr->READ_LWSEM);
            }/* Endif */
            pcb_ptr = _io_pcb_alloc(info_ptr->READ_PCB_POOL, TRUE);
            /* Start CR 385 */
            if (pcb_ptr == NULL) {
               /* Start CR 399 */
               while (pcb_ptr == NULL) {
                  _time_delay_ticks(2);
                  pcb_ptr = _io_pcb_alloc(info_ptr->READ_PCB_POOL, TRUE);
               } /* Endwhile */
               /* End CR 399 */
            } /* Endif */
            /* End CR 385 */
            input_init_ptr = pcb_ptr->FRAGMENTS[0].FRAGMENT;
         } else {
            ++info_ptr->RX_PACKETS_BAD_CRC;
         } /* Endif */
         state = AP_STATE_SYNC;
      } /* Endif */

   } /* Endwhile */

} /* Endbody */


/*TASK*---------------------------------------------------------------------
*
* Task Name       : _io_pcb_mqxa_write_task
* Comments        :
*     This task writes a packet to the async serial device.
*  The packet is in MQX Asynchronous Packet format.
*
*END*---------------------------------------------------------------------*/

void _io_pcb_mqxa_write_task
   (
      /* [IN] the device info */
      uint_32 parameter
   )
{ /* Body */
   IO_PCB_MQXA_INFO_STRUCT_PTR  info_ptr;
   IO_PCB_STRUCT_PTR            pcb_ptr;
   MQX_FILE_PTR                 fd;
   char _PTR_                   output_ptr;
   _mem_size                    count;
   _mqx_uint                    i;
   uchar                        crc0;
   uchar                        crc1;
   uchar                        tmp;
   uchar                        c;

   info_ptr = (IO_PCB_MQXA_INFO_STRUCT_PTR)parameter;
   fd = info_ptr->FD;

   while (1) {
   
      _lwsem_wait(&info_ptr->WRITE_LWSEM);
      pcb_ptr = (IO_PCB_STRUCT_PTR)((pointer)
         _queue_dequeue(&info_ptr->WRITE_QUEUE));

      crc0   = 0x7e;
      crc1   = 0x7e;
      fputc(AP_SYNC, fd);

      for (i = 0; i < pcb_ptr->NUMBER_OF_FRAGMENTS; i++) {
         count      = pcb_ptr->FRAGMENTS[i].LENGTH + 1;
         output_ptr = (char _PTR_)pcb_ptr->FRAGMENTS[i].FRAGMENT;
         while (--count) {
            c = *output_ptr++;
            fputc(c, fd);
            if ( c == AP_SYNC ) {
               fputc(AP_SYNC, fd);
            } /* Endif */
            AP_CHECKSUM(c, crc0, crc1);
         } /* Endwhile */
      } /* Endfor */
      
      /* Calculate the CRCs */
      crc1  = (crc1 + 2 * crc0) & 0xFF;
      tmp   = crc0 - crc1;
      crc1  = (crc1 - (crc0 * 2)) & 0xFF;
      crc0  = tmp  & 0xFF;

      fputc(crc0, fd);
      if ( crc0 == AP_SYNC ) {
         fputc(AP_SYNC, fd);
      } /* Endif */

      /* One more crc character to output */
      fputc(crc1, fd);
      if ( crc1 == AP_SYNC ) {
         fputc(AP_SYNC, fd);
      } /* Endif */

      info_ptr->TX_PACKETS++;
      _io_pcb_free(pcb_ptr);
      
    } /* Endwhile */

} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_mqxa_ioctl
* Returned Value  : _mqx_uint result   MQX_OK or an error code.
* Comments        :
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_mqxa_ioctl
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint              cmd,

      /* [IN] the ioctl parameters */
      pointer                param_ptr
   )
{ /* Body */
   TASK_TEMPLATE_STRUCT input_tt = 
      { 0, _io_pcb_mqxa_read_task,  IO_PCB_MQXA_STACK_SIZE, 0,
         "io_pcb_mqxa_read_task",  0, 0, 0};
   TASK_TEMPLATE_STRUCT output_tt =
      { 0, _io_pcb_mqxa_write_task, IO_PCB_MQXA_STACK_SIZE, 0,
      "io_pcb_mqxa_write_task", 0, 0, 0};
   IO_PCB_MQXA_INFO_STRUCT_PTR info_ptr;
   IO_PCB_STRUCT_PTR           pcb_ptr;
   _mqx_uint                   result = MQX_OK;
   _psp_code_addr              old_value;
   _psp_code_addr_ptr          pc_ptr = (_psp_code_addr_ptr)param_ptr;
   _psp_data_addr_ptr          pd_ptr = (_psp_data_addr_ptr)param_ptr;
   boolean _PTR_               bool_param_ptr;

   info_ptr = (IO_PCB_MQXA_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;

   switch (cmd) {

      case IO_PCB_IOCTL_ENQUEUE_READQ:
         pcb_ptr = (IO_PCB_STRUCT_PTR)*pd_ptr;
         _queue_enqueue((QUEUE_STRUCT_PTR)&info_ptr->READ_QUEUE, 
            (QUEUE_ELEMENT_STRUCT_PTR)&pcb_ptr->QUEUE);
         _lwsem_post(&info_ptr->READ_LWSEM);
         break;
         
      case IO_PCB_IOCTL_READ_CALLBACK_SET:
         old_value = (_psp_code_addr)info_ptr->READ_CALLBACK_FUNCTION;
         /* Start CR 398 */
         info_ptr->CALLBACK_FD = fd_ptr;
         /* End CR */
         info_ptr->READ_CALLBACK_FUNCTION = (void (_CODE_PTR_)(
            FILE_DEVICE_STRUCT_PTR, IO_PCB_STRUCT_PTR))*pc_ptr;
         *pc_ptr = old_value;
         break;
      
      case IO_PCB_IOCTL_SET_INPUT_POOL:
         old_value = (_psp_code_addr)info_ptr->READ_PCB_POOL;
         info_ptr->READ_PCB_POOL = (_io_pcb_pool_id)*pc_ptr;
         *pc_ptr = old_value;
         break;

      case IO_PCB_IOCTL_START:
         if (info_ptr->INPUT_TASK == MQX_NULL_TASK_ID) {
            input_tt.TASK_PRIORITY  = info_ptr->INIT.INPUT_TASK_PRIORITY;
            input_tt.CREATION_PARAMETER  = (uint_32)info_ptr;

            output_tt.TASK_PRIORITY = info_ptr->INIT.OUTPUT_TASK_PRIORITY;
            output_tt.CREATION_PARAMETER = (uint_32)info_ptr;
   
            info_ptr->INPUT_TASK = _task_create(0, 0, (uint_32)&input_tt);
            if (info_ptr->INPUT_TASK == MQX_NULL_TASK_ID){
               return(_task_get_error());
            } /* Endif */

            info_ptr->OUTPUT_TASK = _task_create(0, 0, (uint_32)&output_tt);
            if (info_ptr->OUTPUT_TASK == MQX_NULL_TASK_ID){
               return(_task_get_error());
            } /* Endif */
         }/* Endif */
         break;
         
      case IO_PCB_IOCTL_UNPACKED_ONLY:
         bool_param_ptr = (boolean _PTR_)param_ptr;
         *bool_param_ptr = TRUE;
         break;

      default:
            result = _io_ioctl(info_ptr->FD, cmd, param_ptr);
         break;

   } /* Endswitch */
   return result;

} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_mqxa_uninstall
* Returned Value  : _mqx_uint result   MQX_OK or an error code.
* Comments        :
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_mqxa_uninstall
   (
      IO_PCB_DEVICE_STRUCT_PTR dev_ptr
   )
{ /* Body */
   IO_PCB_MQXA_INFO_STRUCT_PTR info_ptr;
   _mqx_int                    result = MQX_OK;
   
   info_ptr = (IO_PCB_MQXA_INFO_STRUCT_PTR)dev_ptr->DRIVER_INIT_PTR;
   if (info_ptr->FD) {
       return IO_ERROR_DEVICE_BUSY;
   }/* Endif */
   _mem_free(info_ptr);

    return result;
       
} /* Endbody */

#endif // MQX_USE_IPC


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/ipc_pcbv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipc_pcbv.h$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the private definitions for the IO PCB
*   interprocessor drivers.
*
*END************************************************************************/
#ifndef __ipc_pcbv_h__
#define __ipc_pcbv_h__ 1

/*--------------------------------------------------------------------------*/
/*
 *                          CONSTANT DECLARATIONS
 */

/* Stack sizes */
#define IPC_PCB_STACK_SIZE IPC_DEFAULT_STACK_SIZE

/*--------------------------------------------------------------------------*/
/*
 *                          DATATYPE DECLARATIONS
 */



/* IPC_PCB_INFO_STRUCT */
/*!
 * \brief This structure contains protocol information for the IPC over PCBs.
 */
typedef struct ipc_pcb_info_struct
{
   /*! \brief Queue headers for keeping track of driver. */
   QUEUE_ELEMENT_STRUCT QUEUE;

   /*! \brief The IO PCB device to use. */
   MQX_FILE_PTR         FD;

   /*! \brief PCB input pool. */
   _io_pcb_pool_id      PCB_INPUT_POOL;
   /*! \brief Message input pool. */
   _pool_id             MSG_INPUT_POOL;
 
   /*! \brief PCB output pool. */
   _io_pcb_pool_id      PCB_OUTPUT_POOL;
   /*! \brief Message output pool. */
   _queue_id            OUT_MSG_QID;
   
   /*! \brief Number of sent messages. */
   _mqx_uint            OUTPUT_MESSAGE_COUNT;
   /*! \brief Number of received messages. */
   _mqx_uint            INPUT_MESSAGE_COUNT;

} IPC_PCB_INFO_STRUCT, _PTR_ IPC_PCB_INFO_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
 *                          C PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _ipc_pcb_free(IO_PCB_STRUCT_PTR);
extern IO_PCB_STRUCT_PTR _ipc_pcb_alloc(IO_PCB_STRUCT_PTR, pointer);
extern void _ipc_pcb_output_notification(pointer);
extern void _ipc_pcb_input_notification(MQX_FILE_PTR, IO_PCB_STRUCT_PTR);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/hmi_tss_provider.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hmi_tss_provider.h$
* $Version : 3.8.2.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This header file is for HMI lwgpio provider. It contains  defines,
*   structures.
*
*END************************************************************************/
#ifndef __hmi_tss_provider_h__
#define __hmi_tss_provider_h__

#include "hmi_provider.h"
#include "hmi_client.h"

typedef struct hmi_tss_init_struct
{
    uint_32     UID;                                /* usage id */
    uint_8      FLAG;                               /* flag */
}HMI_TSS_INIT_STRUCT, _PTR_ HMI_TSS_INIT_STRUCT_PTR;


typedef struct hmi_tss_context_struct
{
    HMI_TSS_INIT_STRUCT_PTR    TSS_TABLE;           /* TSS element table */
    uint_8                     TSS_COUNT;           /* TSS count number */
    uint_8                     CONTROL_NUMBER;      /* control type*/
    HMI_CLIENT_STRUCT_PTR      CLIENT_HANDLE;       /* client handle */
}HMI_TSS_CONTEXT_STRUCT, _PTR_ HMI_TSS_CONTEXT_STRUCT_PTR;

typedef struct hmi_tss_system_control_struct
{
    uint_16        SYSTEM_CONFIG;                   /* TSS system config */
    uint_8         SYSTEM_TRIGGER;                  /* TSS trigger */
    uint_8         NUMBER_OF_SAMPLES;               /* number of samples */
    const uint_8 _PTR_    SENSITIVITY_VALUES;       /* pointer to sensitivity values array */
}HMI_TSS_SYSTEM_CONTROL_STRUCT, _PTR_ HMI_TSS_SYSTEM_CONTROL_STRUCT_PTR;

#ifdef __cplusplus
extern "C" {
#endif
HMI_PROVIDER_STRUCT_PTR hmi_tss_keypad_provider_init(const HMI_TSS_INIT_STRUCT _PTR_, uint_8);
HMI_PROVIDER_STRUCT_PTR hmi_tss_rotary_provider_init(const HMI_TSS_INIT_STRUCT _PTR_, uint_8);
HMI_PROVIDER_STRUCT_PTR hmi_tss_slider_provider_init(const HMI_TSS_INIT_STRUCT _PTR_, uint_8);
uint_32 hmi_tss_provider_deinit(HMI_PROVIDER_STRUCT_PTR provider);
void hmi_tss_init(const HMI_TSS_SYSTEM_CONTROL_STRUCT system_control);
void hmi_tss_on_fault(uint_8);
void hmi_tss_empty_function(void);
#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_bootloader/USB_CLASS/usb_dfu.h<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/ /*!
  *
  * @file usb_dfu.h
  *
  * @author
  *
  * @version
  *
  * @date 
  *
  * @brief The file contains USB stack DFU class layer API header function.
  *
  *****************************************************************************/

#ifndef _USB_DFU_H
  #define _USB_DFU_H


  #include "usb_descriptor.h"
  #include "usb_class.h"

  #define MAX_QUEUE_ELEMS     (4)

/* class specific requests */
  #define USB_DFU_DETACH      (0)
  #define USB_DFU_DNLOAD      (1)
  #define USB_DFU_UPLOAD      (2)
  #define USB_DFU_GETSTATUS   (3)
  #define USB_DFU_CLRSTATUS   (4)
  #define USB_DFU_GETSTATE    (5)
  #define USB_DFU_ABORT       (6)
  #define DFU_ENDPOINT        (0x00)

/* for class specific requests */
  #define HIGH_BYTE_SHIFT                 (8)
  #define MSB_MASK                        (0xFF00)
  #define USB_DFU_REQUEST_DIR_MASK        (0x08)
  #define USB_DFU_REQUEST_TYPE_MASK       (0x01)
  #define REPORT_SIZE                     (4)
  #define CLASS_REQ_DATA_SIZE             (0x01)

/* define status for request */
  #define USB_OK                      (0x00)
  #define USB_ERR_TARGET              (0x01)
  #define USB_ERR_FILE                (0x02)
  #define USB_ERR_WRITE               (0x03)
  #define USB_ERR_ERASE               (0x04)
  #define USB_ERR_CHECK_ERASE         (0x05)
  #define USB_ERR_PROG                (0x06)
  #define USB_ERR_VERIFY              (0x07)
  #define USB_ERR_ADDRESS             (0x08)
  #define USB_ERR_NOTDONE             (0x09)
  #define USB_ERR_FIRMWARE            (0x0A)
  #define USB_ERR_VENDOR              (0x0B)
  #define USB_ERR_USBR                (0x0C)
  #define USB_ERR_POR                 (0x0D)
  #define USB_ERR_UNKNOWN             (0x0E)
  #define USB_ERR_STALLEDPKT          (0x0F)

/* define state for request */
  #define USB_APP_IDLE                (0x00) // Device is running its normal application.
  #define USB_APP_DETACH              (0x01) // Device is running its normal application, has received the DFU_DETACH request, and is waiting for a USB reset.
  #define USB_DFU_IDLE                (0x02) // Device is operating in the DFU mode and is waiting for requests.
  #define USB_DFU_DNLOAD_SYNC         (0x03) // Device has received a block and is waiting for the host to solicit the status via DFU_GETSTATUS.
  #define USB_DFU_DNBUSY              (0x04) // Device is programming a control-write block into its nonvolatile memories.
  #define USB_DFU_DNLOAD_IDLE         (0x05) // Device is processing a download operation. Expecting DFU_DNLOAD requests.
  #define USB_DFU_MANIFEST_SYNC       (0x06) // Device has received the final block of firmware from the host and is waiting for receipt of DFU_GETSTATUS to begin the 
                                             // Manifestation phase; or device has completed the Manifestation phase and is waiting for receipt of DFU_GETSTATUS. 
  #define USB_DFU_MANIFEST            (0x07) // Device is in the Manifestation phase. (Not all devices will be able to respond to DFU_GETSTATUS when in this state.)
  #define USB_DFU_MANIFEST_WAIT_RESET (0x08) // Device has programmed its memories and is waiting for a USB reset or a power on reset.
  #define USB_DFU_UPLOAD_IDLE         (0x09) // The device is processing an upload operation. Expecting DFU_UPLOAD requests.
  #define USB_DFU_ERROR               (0x0a) // An error has occurred. Awaiting the DFU_CLRSTATUS request 

/* define index of fields in dfu_status buff  */
  #define BSTATUS                     (0x00)
  #define BWPOLLTIMEOUT               (0x01)
  #define BSTATE                      (0x04)
  #define ISTRING                     (0x05)

  #define POLLTIMEOUT                 (0x64)  // Значение по умолчаниб для поля BWPOLLTIMEOUT в dfu_status


/* DFU define request */
  #define GETSTATUS_DATA_SIZE         (0x06)
  #define SET_DNLOAD_DATA_SIZE        (0x08)
  #define GET_UPLOAD_DATA_SIZE        (0x08)
  #define GETSTATE_DATA_SIZE          (0x01)
  #define RUNTIME_MODE                (1)
  #define DFU_MODE                    (2)

/******************************************************************************
 * Types
 *****************************************************************************/

/* structure to hold a request in the endpoint queue */
typedef struct _usb_class_dfu_queue
{
  INT8U controller_ID;   /* Controller ID*/
  INT8U channel;         /* Endpoint number */
  INT8U_ptr app_buff;    /* Buffer to send */
  INT16U size;   /* Size of the transfer */
}USB_CLASS_DFU_QUEUE, *PTR_USB_CLASS_DFU_QUEUE;

/******************************************************************************
 * Global Functions
 *****************************************************************************/
extern INT8U USB_Class_DFU_Init(
                                INT8U                          controller_ID,
                                USB_CLASS_CALLBACK              dfu_class_callback,
                                USB_REQ_FUNC                    vendor_req_callback,
                                USB_CLASS_SPECIFIC_HANDLER_FUNC param_callback
                                );

extern INT8U USB_Class_DFU_DeInit(INT8U controller_ID);
/*****************************************************************************/
extern void USB_Class_DFU_App_SetIdle(void);
extern void USB_Class_DFU_App_SetDetach(void);
extern void USB_Class_DFU_App_Set_Usbreset(void);
extern INT8U USB_Class_DFU_App_Getstate(void);
extern void USB_Class_DFU_App_Set_Flag_Manifest(void);
extern INT8U USB_Class_DFU_App_Get_Flag_Manifest(void);
extern void USB_Class_DFU_App_Reset_Flag_Manifest(void);

#endif


<|start_filename|>Firmware/Inverter_firmware/Main/Temperature_control.h<|end_filename|>
#ifndef __TEMPERATURE_CONTROL
  #define __TEMPERATURE_CONTROL

_mqx_int TempCtrl_init_drivers(void);
_mqx_int TempCtrl_read_IGBT_temperature(float *temp_ptr);

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/hdlcio2.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hdlcio2.c$
* $Version : 3.8.9.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the HDLC device functions needed
*   for communication.
*
*END************************************************************************/

#include <rtcshdlc.h>
#include <rtcs_in.h>
#include <rtcs.h>
#include <io_pcb.h>
#include <rtcspcb.h>


typedef struct hdlcio2_struct {
   struct _iopcb_table PCB_TABLE;
   HDLCIO_STATS        STATS;
   _io_pcb_pool_id     TX_ID;
   _io_pcb_pool_id     RX_ID;
   _rtcs_part          PART_ID;
   MQX_FILE_PTR        DEVICE;
   void (_CODE_PTR_    UP)(pointer);
   void (_CODE_PTR_    DOWN)(pointer);
   pointer             PARAM;

} HDLCIO2_STRUCT, _PTR_ HDLCIO2_STRUCT_PTR;

#define RTCS_HDLCIO_TX_INIT_PCB    16
#define RTCS_HDLCIO_TX_GROW_PCB    0
#define RTCS_HDLCIO_TX_MAX_PCB     16
#define RTCS_HDLCIO_RX_INIT_PCB    16
#define RTCS_HDLCIO_RX_GROW_PCB    0
#define RTCS_HDLCIO_RX_MAX_PCB     16
#define RTCS_HDCLIO_RX_BUF_SIZE   256

static uint_32 _iopcb_hdlcio_open  (_iopcb_handle, void (_CODE_PTR_)(pointer), void (_CODE_PTR_)(pointer), pointer);
static uint_32 _iopcb_hdlcio_close (_iopcb_handle);
static void    _iopcb_hdlcio_write (_iopcb_handle, PCB_PTR, uint_32);
static PCB_PTR _iopcb_hdlcio_read  (_iopcb_handle, uint_32);
static uint_32 _iopcb_hdlcio_ioctl (_iopcb_handle, uint_32, pointer);


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_free_rx
*  Returned Value :
*  Comments       :
*      Frees the inner PCB and then frees the IO_PCB
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void _iopcb_hdlcio_free_rx
   (
      PCB_PTR    pcb
   )
{ /* Body */
   IO_PCB_STRUCT_PTR       iopcb_ptr = pcb->PRIVATE;

   RTCS_part_free(pcb);
   _io_pcb_free(iopcb_ptr);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_free_tx
*  Returned Value :
*  Comments       :
*      Frees the inner PCB and then frees the IO_PCB
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_hdlcio_free_tx
   (
      IO_PCB_STRUCT_PTR    iopcb
   )
{ /* Body */
   PCB_PTR                 pcb_ptr = iopcb->OWNER_PRIVATE;

   pcb_ptr->FREE(pcb_ptr);
   return _io_pcb_free_internal(iopcb);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_rcv_unblock
*  Returned Value : void
*  Comments       : Unblocks the PPP rx task when a messge is received
*
*
*END*-----------------------------------------------------------------*/

void _iopcb_hdlcio_rcv_unblock
   (
      pointer param
      /* [IN] The semaphore to unblock when the message arrives */
   )
{  /* Body */

#if RTCSCFG_ENABLE_IP4

   LWSEM_STRUCT _PTR_ sem = (LWSEM_STRUCT _PTR_)param;
   PPP_mutex_unlock(sem);

#endif /* RTCSCFG_ENABLE_IP4 */

}  /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_init
*  Returned Value : a HANDLE to be used by other functions
*  Comments       :
*      Sets some of the values of the hdlc structure and
*  returns the handle of the structure.
*
*END*-----------------------------------------------------------------*/

_iopcb_handle _iopcb_hdlcio_init
   (
      /* [IN] The lower level device */
      MQX_FILE_PTR      device
   )
{  /* Body */

#if RTCSCFG_ENABLE_IP4

   HDLCIO2_STRUCT_PTR   hdlcio_ptr;
   int_32               error;

   hdlcio_ptr = RTCS_memalloc(sizeof(HDLCIO2_STRUCT));
   if (!hdlcio_ptr) {
      return NULL;
   } /* Endif */

   /*
   ** Create IO PCB transmit pool
   **
   ** The first parameter (number of frags) is the same number as found in an
   ** RTCSPCB to allow the RTCSPCB->IOPCB conversion, plus one extra to allow 2
   ** address/control bytes to be prepended and one extra to set to LENGTH 0 to
   ** mark end of array. The second parameter is the extra data size needed for
   ** for adddress/control bytes
   */
   hdlcio_ptr->TX_ID = _io_pcb_create_pool(
      RTCSPCB_FRAG_MAX + 2, 2,
      RTCS_HDLCIO_TX_INIT_PCB,
      RTCS_HDLCIO_TX_GROW_PCB,
      RTCS_HDLCIO_TX_MAX_PCB,
      NULL, NULL, NULL, NULL);
   if (hdlcio_ptr->TX_ID == IO_PCB_NULL_POOL_ID) {
      goto errorlevel1;
   } /* Endif */

   /*
   ** Create IO PCB receive_pool
   **
   ** The first parameter (number of frags) is 1, as the lower level receives
   ** everyting as one fragment. No extra data space is needed.
   */
   hdlcio_ptr->RX_ID = _io_pcb_create_pool(
      1, RTCS_HDLC_MESSAGE_SIZE + 2,
      RTCS_HDLCIO_RX_INIT_PCB,
      RTCS_HDLCIO_RX_GROW_PCB,
      RTCS_HDLCIO_RX_MAX_PCB,
      NULL, NULL, NULL, NULL);
   if (hdlcio_ptr->RX_ID == IO_PCB_NULL_POOL_ID) {
      goto errorlevel2;
   } /* Endif */

   /*
   ** Create a partition of PCB + 1 FRAG structs. The FRAG inside the PCB will
   ** point to the data received by the lower level, and the second FRAG outside
   ** the PCB will have a LENGTH of 0 to mark it as the last fragment.
   */
   hdlcio_ptr->PART_ID = RTCS_part_create(
      sizeof(PCB) + sizeof(PCB_FRAGMENT),
      RTCS_HDLCIO_RX_INIT_PCB,
      RTCS_HDLCIO_RX_GROW_PCB,
      RTCS_HDLCIO_RX_MAX_PCB,
      NULL, NULL);
   if (!hdlcio_ptr->PART_ID) {
      goto errorlevel3;
   } /* Endif */

   /* Set the input pool for incoming data */
   error = _io_ioctl(device, IO_PCB_IOCTL_SET_INPUT_POOL, (pointer)&hdlcio_ptr->RX_ID);
   if (error != MQX_OK) {
      goto errorlevel4;
   } /* Endif */

   hdlcio_ptr->DEVICE          = device;
   hdlcio_ptr->PCB_TABLE.OPEN  = _iopcb_hdlcio_open;
   hdlcio_ptr->PCB_TABLE.CLOSE = _iopcb_hdlcio_close;
   hdlcio_ptr->PCB_TABLE.READ  = _iopcb_hdlcio_read;
   hdlcio_ptr->PCB_TABLE.WRITE = _iopcb_hdlcio_write;
   hdlcio_ptr->PCB_TABLE.IOCTL = _iopcb_hdlcio_ioctl;

   /* Everthing OK */
   return &hdlcio_ptr->PCB_TABLE;

   /* Error occured, jump to errorlevel needed to cleanup */
errorlevel4: RTCS_part_destroy(hdlcio_ptr->PART_ID);
errorlevel3: _io_pcb_destroy_pool(hdlcio_ptr->RX_ID);
errorlevel2: _io_pcb_destroy_pool(hdlcio_ptr->TX_ID);
errorlevel1: RTCS_memfree(hdlcio_ptr);

#endif /* RTCSCFG_ENABLE_IP4 */

   return NULL;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_open
*  Returned Value : uint_32, an ERROR code
*  Comments       :
*      Sets some of the values of the hdlc structure and opens the link.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_hdlcio_open
   (
      _iopcb_handle       handle,
         /* [IN] - the IO handle*/
      void (_CODE_PTR_    up)(pointer),
         /* [IN] - function to put the link up */
      void (_CODE_PTR_    down)(pointer),
         /* [IN] - function to put the link down */
      pointer             param
         /* [IN] - for the up/down functions */
   )
{  /* Body */
   HDLCIO2_STRUCT_PTR hdlcio_ptr = (HDLCIO2_STRUCT_PTR)handle;

   hdlcio_ptr->UP      = up;
   hdlcio_ptr->DOWN    = down;
   hdlcio_ptr->PARAM   = param;

   /* signal the PPP layer that the connection is open */
   if (hdlcio_ptr->UP) {
      up(param);
   } /* Endif */

   return HDLCIO_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_write
*  Returned Value :
*  Comments       :
*      Transmits the data
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void _iopcb_hdlcio_write
   (
      _iopcb_handle      handle,
      /* [IN] - the handle */
      PCB_PTR            pcb_ptr,
      /* [IN] - the packet */
      uint_32            flags
      /* [IN] - the flags */
   )
{ /* Body */
   HDLCIO2_STRUCT_PTR   hdlcio_ptr = (HDLCIO2_STRUCT_PTR)handle;
   IO_PCB_STRUCT_PTR    send_pcb_ptr;
   int_32               error;
   uint_32              i, dlen, j;

   /* Allocate an IO_PCB to send data */
   send_pcb_ptr = _io_pcb_alloc(hdlcio_ptr->TX_ID, FALSE);
   if (send_pcb_ptr == NULL) {
      /* Free the PCB and return */
      hdlcio_ptr->STATS.COMMON.ST_TX_MISSED++;
      PCB_free(pcb_ptr);
      return;
   } /* Endif */

   /* Setup the IO_PCB */
   send_pcb_ptr->OWNER_PRIVATE = pcb_ptr;
   send_pcb_ptr->FREE_PCB_FUNCTION_PTR = _iopcb_hdlcio_free_tx;

   for (i = 0, dlen = 0; i <= RTCSPCB_FRAG_MAX; i++) {
      send_pcb_ptr->FRAGMENTS[i + 1].LENGTH = pcb_ptr->FRAG[i].LENGTH;
      send_pcb_ptr->FRAGMENTS[i + 1].FRAGMENT = pcb_ptr->FRAG[i].FRAGMENT;
      if (!pcb_ptr->FRAG[i].LENGTH) break;
      dlen += pcb_ptr->FRAG[i].LENGTH;
   } /* Endfor */
   send_pcb_ptr->NUMBER_OF_FRAGMENTS = i;

   if (dlen > RTCS_HDLC_MESSAGE_SIZE) {
      hdlcio_ptr->STATS.COMMON.ST_TX_ERRORS++;
      _io_pcb_free(send_pcb_ptr);
      return;
   }/* Endif */

   /* Add address and control bytes */
   send_pcb_ptr->FRAGMENTS[0].LENGTH = 2;
   send_pcb_ptr->FRAGMENTS[0].FRAGMENT[0] = 0xFF;
   send_pcb_ptr->FRAGMENTS[0].FRAGMENT[1] = 0x03;

   i = 0;
   j = 0;
   while (i < send_pcb_ptr->NUMBER_OF_FRAGMENTS) {
      j += send_pcb_ptr->FRAGMENTS[i].LENGTH;
      i++;
   } /* Endwhile */

   /* Write it to the lower level */
   error = _io_pcb_write(hdlcio_ptr->DEVICE, send_pcb_ptr);
   if (error) {
      _io_pcb_free(send_pcb_ptr);
      hdlcio_ptr->STATS.COMMON.ST_TX_ERRORS++;
      return;
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_read
*  Returned Value : PCB_PTR
*  Comments       :
*      Receives the data
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static PCB_PTR _iopcb_hdlcio_read
   (
      _iopcb_handle    handle,
         /* [IN] - the structure handle */
      uint_32          flags
         /* [IN] - flags */
   )
{  /* Body */
   HDLCIO2_STRUCT_PTR   hdlcio_ptr = (HDLCIO2_STRUCT_PTR)handle;
   IO_PCB_STRUCT_PTR    recv_pcb_ptr;
   PCB_FRAGMENT_PTR     frag_ptr;
   PCB_PTR              pcb;
   int_32               error;

   while (TRUE) {
      /* Read from the lower level. Block until we get data */
      error = _io_pcb_read(hdlcio_ptr->DEVICE, &recv_pcb_ptr);
      if (error) {
         _task_block();
         hdlcio_ptr->STATS.COMMON.ST_TX_ERRORS++;
         continue;
      } /* Endif */

      /* Error checking */
      if (recv_pcb_ptr->FRAGMENTS[0].LENGTH > RTCS_HDLC_MESSAGE_SIZE ) {
         hdlcio_ptr->STATS.ST_RX_GIANT++;
         _io_pcb_free(recv_pcb_ptr);
         continue;
      } else if (recv_pcb_ptr->FRAGMENTS[0].LENGTH < 2) {
         hdlcio_ptr->STATS.ST_RX_RUNT++;
         _io_pcb_free(recv_pcb_ptr);
         continue;
      } /* Endif */

      /* Allocate a simple PCB for it */
      pcb = RTCS_part_alloc(hdlcio_ptr->PART_ID);
      if (!pcb) {
         hdlcio_ptr->STATS.COMMON.ST_RX_MISSED++;
         _io_pcb_free(recv_pcb_ptr);
         continue;
      } /* Endif */

      /* All checks passed */
      break;
   } /* Endwhile */

   /* Convert IO_PCB to simple PCB */
   pcb->FREE = _iopcb_hdlcio_free_rx;
   pcb->PRIVATE = recv_pcb_ptr;
   /* Skip address and control bytes */
   frag_ptr = pcb->FRAG;
   frag_ptr->FRAGMENT = recv_pcb_ptr->FRAGMENTS[0].FRAGMENT + 2;
   frag_ptr->LENGTH = recv_pcb_ptr->FRAGMENTS[0].LENGTH - 2;
   frag_ptr++;
   frag_ptr->FRAGMENT = NULL;
   frag_ptr->LENGTH = 0;
   return pcb;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_close
*  Returned Value : uint_32, an ERROR code
*  Comments       :
*     Close link and free memory
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_hdlcio_close
   (
      _iopcb_handle  handle
         /* [IN] - the structure handle */
   )
{  /* Body */
   HDLCIO2_STRUCT_PTR hdlcio_ptr = (HDLCIO2_STRUCT_PTR)((void _PTR_)handle);

   /* close connection */
   if (hdlcio_ptr->DOWN) {
      hdlcio_ptr->DOWN(hdlcio_ptr->PARAM);
   } /* Endif */

   /* Free memory */
   RTCS_part_destroy(hdlcio_ptr->PART_ID);
   _io_pcb_destroy_pool(hdlcio_ptr->TX_ID);
   _io_pcb_destroy_pool(hdlcio_ptr->RX_ID);
   RTCS_memfree(hdlcio_ptr);

   return HDLCIO_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlcio_ioctl
*  Returned Value : an ERROR code
*  Comments       :
*      Store and set the options
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_hdlcio_ioctl
   (
      _iopcb_handle    handle,
         /* [IN] - the structure handle */
      uint_32          option,
         /* [IN] - options */
      pointer          value
         /* [IN] - option value */
   )
{  /* Body */
   uint_32 result = HDLCIO_OK;

   switch(option)  {
      case IOPCB_IOCTL_S_ACCM:
         break;
      case IOPCB_IOCTL_R_ACCM:
         break;
      case IOPCB_IOCTL_S_PFC:
         break;
      case IOPCB_IOCTL_R_PFC:
         break;
      case IOPCB_IOCTL_S_ACFC:
         break;
      case IOPCB_IOCTL_R_ACFC:
         break;
      case IOPCB_IOCTL_GET_IFTYPE:
         *(uint_32_ptr)value = IPIFTYPE_HDLC;
          break;
      default:
         result = IO_ERROR_INVALID_IOCTL_CMD;
         break;
   } /* Endswitch */

   return result;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/I2S_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type I2S
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(I2S_PDD_H_)
#define I2S_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error I2S PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10DZ10) /* I2S0 */ && \
      !defined(MCU_MK20DZ10) /* I2S0 */ && \
      !defined(MCU_MK30DZ10) /* I2S0 */ && \
      !defined(MCU_MK40DZ10) /* I2S0 */ && \
      !defined(MCU_MK40X256VMD100) /* I2S0 */ && \
      !defined(MCU_MK50DZ10) /* I2S0 */ && \
      !defined(MCU_MK51DZ10) /* I2S0 */ && \
      !defined(MCU_MK52DZ10) /* I2S0 */ && \
      !defined(MCU_MK53DZ10) /* I2S0 */ && \
      !defined(MCU_MK60DZ10) /* I2S0 */ && \
      !defined(MCU_MK60N512VMD100) /* I2S0 */
  // Unsupported MCU is active
  #error I2S PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Receive and transmit section masks. */
#define I2S_PDD_RECEIVER    I2S_CR_RE_MASK       /**< Receive section mask. */
#define I2S_PDD_TRANSMITTER I2S_CR_TE_MASK       /**< Transmit section mask. */

/* Frame clock disable masks. */
#define I2S_PDD_RX_FRAME_CLOCK_DISABLE I2S_CR_RFRCLKDIS_MASK /**< Receive frame clock mask. */
#define I2S_PDD_TX_FRAME_CLOCK_DISABLE I2S_CR_TFRCLKDIS_MASK /**< Transmit frame clock mask. */

/* Interrupt masks for EnableDmasInterrupts, DisableDmasInterrupts, some of them
   for GetInterruptFlag, some of them for ClearInterruptFlags */
#define I2S_PDD_RX_FRAME_COMPLETE_INT      I2S_ISR_RFRC_MASK /**< Receive frame complete */
#define I2S_PDD_TX_FRAME_COMPLETE_INT      I2S_ISR_TRFC_MASK /**< Transmit frame complete */
#define I2S_PDD_RX_DMA_ENABLE              I2S_IER_RDMAE_MASK /**< Receive DMA enable, unusable for GetInterruptFlags nor ClearInterruptFlags */
#define I2S_PDD_RECEIVER_INT               I2S_IER_RIE_MASK /**< Receive interrupt enable, unusable for GetInterruptFlags nor ClearInterruptFlags */
#define I2S_PDD_TX_DMA_ENABLE              I2S_IER_TDMAE_MASK /**< Transmit DMA enable, unusable for GetInterruptFlags nor ClearInterruptFlags */
#define I2S_PDD_TRANSMITTER_INT            I2S_IER_TIE_MASK /**< Transmit interrupt enable, unusable for GetInterruptFlags nor ClearInterruptFlags */
#define I2S_PDD_COMMAND_ADDRESS_UPDATE_INT I2S_ISR_CMDAU_MASK /**< Command address update, unusable for ClearInterruptFlags */
#define I2S_PDD_COMMAND_DATA_UPDATE_INT    I2S_ISR_CMDDU_MASK /**< Command data update, unusable for ClearInterruptFlags */
#define I2S_PDD_RX_TAG_UPDATE_INT          I2S_ISR_RXT_MASK /**< Receive tag update, unusable for ClearInterruptFlags */
#define I2S_PDD_RX_DATA_READY_1_INT        I2S_ISR_RDR1_MASK /**< Receive data ready 1, unusable for ClearInterruptFlags */
#define I2S_PDD_RX_DATA_READY_0_INT        I2S_ISR_RDR0_MASK /**< Receive data ready 0, unusable for ClearInterruptFlags */
#define I2S_PDD_TX_DATA_EMPTY_1_INT        I2S_ISR_TDE1_MASK /**< Transmit data empty 1, unusable for ClearInterruptFlags */
#define I2S_PDD_TX_DATA_EMPTY_0_INT        I2S_ISR_TDE0_MASK /**< Transmit data empty 0, unusable for ClearInterruptFlags */
#define I2S_PDD_RX_OVERRUN_1_INT           I2S_ISR_ROE1_MASK /**< Receive overrun 1 */
#define I2S_PDD_RX_OVERRUN_0_INT           I2S_ISR_ROE0_MASK /**< Receive overrun 0 */
#define I2S_PDD_TX_UNDERRUN_1_INT          I2S_ISR_TUE1_MASK /**< Transmit underrun 1 */
#define I2S_PDD_TX_UNDERRUN_0_INT          I2S_ISR_TUE0_MASK /**< Transmit underrun 0 */
#define I2S_PDD_TX_FRAME_SYNC_INT          I2S_ISR_TFS_MASK /**< Transmit frame sync, unusable for ClearInterruptFlags */
#define I2S_PDD_RX_FRAME_SYNC_INT          I2S_ISR_RFS_MASK /**< Recieve frame sync, unusable for ClearInterruptFlags */
#define I2S_PDD_TX_LAST_TIME_SLOT_INT      I2S_ISR_TLS_MASK /**< Transmit last time slot, unusable for ClearInterruptFlags */
#define I2S_PDD_RX_LAST_TIME_SLOT_INT      I2S_ISR_RLS_MASK /**< Receive last time slot, unusable for ClearInterruptFlags */
#define I2S_PDD_RX_FIFO_FULL_1_INT         I2S_ISR_RFF1_MASK /**< Receive FIFO full 1, unusable for ClearInterruptFlags */
#define I2S_PDD_RX_FIFO_FULL_0_INT         I2S_ISR_RFF0_MASK /**< Receive FIFO full 0, unusable for ClearInterruptFlags */
#define I2S_PDD_TX_FIFO_EMPTY_1_INT        I2S_ISR_TFE1_MASK /**< Transmit FIFO empty 1, unusable for ClearInterruptFlags */
#define I2S_PDD_TX_FIFO_EMPTY_0_INT        I2S_ISR_TFE0_MASK /**< Transmit FIFO empty 0, unusable for ClearInterruptFlags */
#define I2S_PDD_ALL_INT                    0x1AFFFFFU /**< All interrupt flags, unusable for ClearInterruptFlags */

/* Slot masks for EnableAC97Channels, DisableAC97Channels,
   GetAC97ChannelStatusMask */
#define I2S_PDD_AC97_DATA_SLOT_3  0x1U           /**< The 3rd data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_4  0x2U           /**< The 4th data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_5  0x4U           /**< The 5th data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_6  0x8U           /**< The 6th data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_7  0x10U          /**< The 7th data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_8  0x20U          /**< The 8th data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_9  0x40U          /**< The 9th data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_10 0x80U          /**< The 10th data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_11 0x100U         /**< The 11th data channel mask. */
#define I2S_PDD_AC97_DATA_SLOT_12 0x200U         /**< The 12th data channel mask. */

/* Clock source constants for SetClockSource. */
#define I2S_PDD_DIVIDED_CORE_SYSTEM_CLOCK 0U     /**< Divided core system clock source. */
#define I2S_PDD_DIVIDED_PLL_FLL_CLOCK     0x1U   /**< Divided PLL or FLL clock source. */
#define I2S_PDD_EXTAL_CLOCK               0x2U   /**< Extal clock source. */
#define I2S_PDD_EXTERNAL_CLOCK            0x3U   /**< External clock source. */

/* AC97 command constant. */
#define I2S_PDD_AC97_WRITE_COMMAND 0x10U         /**< AC97 write command. */
#define I2S_PDD_AC97_READ_COMMAND  0x8U          /**< AC97 read command. */


/* ----------------------------------------------------------------------------
   -- WriteTxData0Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Tx Data 0 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the Data0 register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_TX0.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteTxData0Reg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteTxData0Reg(PeripheralBase, Value) ( \
    I2S_TX0_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteTxData1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Tx Data 1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the Data1 register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_TX1.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteTxData1Reg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteTxData1Reg(PeripheralBase, Value) ( \
    I2S_TX1_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadRxData0Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the Rx Data 0 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_RX0.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadRxData0Reg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadRxData0Reg(PeripheralBase) ( \
    I2S_RX0_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadRxData1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the Rx Data 1 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_RX1.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadRxData1Reg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadRxData1Reg(PeripheralBase) ( \
    I2S_RX1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- EnableReceiver
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the receive section.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of receive section. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_CR.
 * @par Example:
 *      @code
 *      I2S_PDD_EnableReceiver(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define I2S_PDD_EnableReceiver(PeripheralBase, State) ( \
    I2S_CR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_CR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)I2S_CR_RE_MASK))) | ( \
      (uint32_t)((uint32_t)(State) << I2S_CR_RE_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableTransmitter
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the transmit section.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of transmit section. This parameter is of
 *        "Global enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_CR.
 * @par Example:
 *      @code
 *      I2S_PDD_EnableTransmitter(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define I2S_PDD_EnableTransmitter(PeripheralBase, State) ( \
    I2S_CR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_CR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)I2S_CR_TE_MASK))) | ( \
      (uint32_t)((uint32_t)(State) << I2S_CR_TE_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableRxTx
   ---------------------------------------------------------------------------- */

/**
 * @brief Allows to enable receive and transmit section.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of receive and transmit section to enable. Use constants
 *        from group "Receive and transmit section masks.". This parameter is 32
 *        bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_CR.
 * @par Example:
 *      @code
 *      I2S_PDD_EnableRxTx(deviceID, I2S_PDD_RECEIVER);
 *      @endcode
 */
#define I2S_PDD_EnableRxTx(PeripheralBase, Mask) ( \
    I2S_CR_REG(PeripheralBase) |= \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- DisableRxTx
   ---------------------------------------------------------------------------- */

/**
 * @brief Allows to disable receive and transmit section.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of receive and transmit section to enable. Use constants
 *        from group "Receive and transmit section masks.". This parameter is 32
 *        bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_CR.
 * @par Example:
 *      @code
 *      I2S_PDD_DisableRxTx(deviceID, I2S_PDD_RECEIVER);
 *      @endcode
 */
#define I2S_PDD_DisableRxTx(PeripheralBase, Mask) ( \
    I2S_CR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- EnableDevice
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the device.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of device. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE and
 *        PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_CR.
 * @par Example:
 *      @code
 *      I2S_PDD_EnableDevice(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define I2S_PDD_EnableDevice(PeripheralBase, State) ( \
    I2S_CR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_CR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)I2S_CR_I2SEN_MASK))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the control register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_CR.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteControlReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteControlReg(PeripheralBase, Value) ( \
    I2S_CR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the Control register.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "Frame clock disable masks." for processing
 *         return value.
 * @remarks The macro accesses the following registers: I2S0_CR.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadControlReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadControlReg(PeripheralBase) ( \
    I2S_CR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetInterruptFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt flag bits.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "Interrupt masks for EnableDmasInterrupts,
 *         DisableDmasInterrupts, some of them for GetInterruptFlag, some of them
 *         for ClearInterruptFlags" for processing return value.
 * @remarks The macro accesses the following registers: I2S0_ISR.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_GetInterruptFlags(deviceID);
 *      @endcode
 */
#define I2S_PDD_GetInterruptFlags(PeripheralBase) ( \
    I2S_ISR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ClearInterruptFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears interrupt flag bits defined by mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of interrupt flags to clear. Use constants from group
 *        "Interrupt masks for EnableDmasInterrupts, DisableDmasInterrupts, some of
 *        them for GetInterruptFlag, some of them for ClearInterruptFlags". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ISR.
 * @par Example:
 *      @code
 *      I2S_PDD_ClearInterruptFlags(deviceID, I2S_PDD_RX_FRAME_COMPLETE_INT);
 *      @endcode
 */
#define I2S_PDD_ClearInterruptFlags(PeripheralBase, Mask) ( \
    I2S_ISR_REG(PeripheralBase) = \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- EnableDmasInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables DMAs and interrupts defined by mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of DMAs and interrupts. Use constants from group "Interrupt
 *        masks for EnableDmasInterrupts, DisableDmasInterrupts, some of them for
 *        GetInterruptFlag, some of them for ClearInterruptFlags". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_IER.
 * @par Example:
 *      @code
 *      I2S_PDD_EnableDmasInterrupts(deviceID, I2S_PDD_RX_FRAME_COMPLETE_INT);
 *      @endcode
 */
#define I2S_PDD_EnableDmasInterrupts(PeripheralBase, Mask) ( \
    I2S_IER_REG(PeripheralBase) |= \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- DisableDmasInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables DMAs and interrupts defined by mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of DMAs and interrupts. Use constants from group "Interrupt
 *        masks for EnableDmasInterrupts, DisableDmasInterrupts, some of them for
 *        GetInterruptFlag, some of them for ClearInterruptFlags". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_IER.
 * @par Example:
 *      @code
 *      I2S_PDD_DisableDmasInterrupts(deviceID, I2S_PDD_RX_FRAME_COMPLETE_INT);
 *      @endcode
 */
#define I2S_PDD_DisableDmasInterrupts(PeripheralBase, Mask) ( \
    I2S_IER_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- WriteInterruptEnableReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Interrupt enable register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the interrupt enable register. This parameter is
 *        a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_IER.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteInterruptEnableReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteInterruptEnableReg(PeripheralBase, Value) ( \
    I2S_IER_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadInterruptEnableReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the Interrupt enable register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_IER.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadInterruptEnableReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadInterruptEnableReg(PeripheralBase) ( \
    I2S_IER_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteTransmitConfigurationReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Transmit configuration register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the transmit configuration register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_TCR.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteTransmitConfigurationReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteTransmitConfigurationReg(PeripheralBase, Value) ( \
    I2S_TCR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadTransmitConfigurationReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the Transmit configuration register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_TCR.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadTransmitConfigurationReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadTransmitConfigurationReg(PeripheralBase) ( \
    I2S_TCR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteReceiveConfigurationReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Receive configuration register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the receive configuration register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_RCR.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteReceiveConfigurationReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteReceiveConfigurationReg(PeripheralBase, Value) ( \
    I2S_RCR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadReceiveConfigurationReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the Receive configuration register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_RCR.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadReceiveConfigurationReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadReceiveConfigurationReg(PeripheralBase) ( \
    I2S_RCR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteTransmitClockControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Transmit clock control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the transmit clock control register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_TCCR.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteTransmitClockControlReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteTransmitClockControlReg(PeripheralBase, Value) ( \
    I2S_TCCR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadTransmitClockControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the Transmit clock control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_TCCR.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadTransmitClockControlReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadTransmitClockControlReg(PeripheralBase) ( \
    I2S_TCCR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteReceiveClockControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Receive clock control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the receive clock control register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_RCCR.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteReceiveClockControlReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteReceiveClockControlReg(PeripheralBase, Value) ( \
    I2S_RCCR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadReceiveClockControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the Receive clock control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_RCCR.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadReceiveClockControlReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadReceiveClockControlReg(PeripheralBase) ( \
    I2S_RCCR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetRxFIFOCounter1
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns receive FIFO counter 1.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 4-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      uint8_t result = I2S_PDD_GetRxFIFOCounter1(deviceID);
 *      @endcode
 */
#define I2S_PDD_GetRxFIFOCounter1(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(I2S_FCSR_REG(PeripheralBase) & I2S_FCSR_RFCNT1_MASK)) >> ( \
     I2S_FCSR_RFCNT1_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- GetRxFIFOCounter0
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns receive FIFO counter 0.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 4-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      uint8_t result = I2S_PDD_GetRxFIFOCounter0(deviceID);
 *      @endcode
 */
#define I2S_PDD_GetRxFIFOCounter0(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(I2S_FCSR_REG(PeripheralBase) & I2S_FCSR_RFCNT0_MASK)) >> ( \
     I2S_FCSR_RFCNT0_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- GetTxFIFOCounter1
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns transmit FIFO counter 1.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 4-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      uint8_t result = I2S_PDD_GetTxFIFOCounter1(deviceID);
 *      @endcode
 */
#define I2S_PDD_GetTxFIFOCounter1(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(I2S_FCSR_REG(PeripheralBase) & I2S_FCSR_TFCNT1_MASK)) >> ( \
     I2S_FCSR_TFCNT1_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- GetTxFIFOCounter0
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns transmit FIFO counter 0.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 4-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      uint8_t result = I2S_PDD_GetTxFIFOCounter0(deviceID);
 *      @endcode
 */
#define I2S_PDD_GetTxFIFOCounter0(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(I2S_FCSR_REG(PeripheralBase) & I2S_FCSR_TFCNT0_MASK)) >> ( \
     I2S_FCSR_TFCNT0_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- SetRxFIFOFullWatermark1
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets receive FIFO full watermark 1.
 * @param PeripheralBase Peripheral base address.
 * @param Value Parameter specifying new value. This parameter is a 4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      I2S_PDD_SetRxFIFOFullWatermark1(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_SetRxFIFOFullWatermark1(PeripheralBase, Value) ( \
    I2S_FCSR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_FCSR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)I2S_FCSR_RFWM1_MASK))) | ( \
      (uint32_t)((uint32_t)(Value) << I2S_FCSR_RFWM1_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetRxFIFOFullWatermark0
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets receive FIFO full watermark 0.
 * @param PeripheralBase Peripheral base address.
 * @param Value Parameter specifying new value. This parameter is a 4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      I2S_PDD_SetRxFIFOFullWatermark0(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_SetRxFIFOFullWatermark0(PeripheralBase, Value) ( \
    I2S_FCSR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_FCSR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)I2S_FCSR_RFWM0_MASK))) | ( \
      (uint32_t)((uint32_t)(Value) << I2S_FCSR_RFWM0_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetTxFIFOFullWatermark1
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets transmit FIFO full watermark 1.
 * @param PeripheralBase Peripheral base address.
 * @param Value Parameter specifying new value. Value 0 is reserved. This
 *        parameter is a 4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      I2S_PDD_SetTxFIFOFullWatermark1(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_SetTxFIFOFullWatermark1(PeripheralBase, Value) ( \
    I2S_FCSR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_FCSR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)I2S_FCSR_TFWM1_MASK))) | ( \
      (uint32_t)((uint32_t)(Value) << I2S_FCSR_TFWM1_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetTxFIFOFullWatermark0
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets transmit FIFO full watermark 0.
 * @param PeripheralBase Peripheral base address.
 * @param Value Parameter specifying new value. Value 0 is reserved. This
 *        parameter is a 4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      I2S_PDD_SetTxFIFOFullWatermark0(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_SetTxFIFOFullWatermark0(PeripheralBase, Value) ( \
    I2S_FCSR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_FCSR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)I2S_FCSR_TFWM0_MASK))) | ( \
      (uint32_t)(Value))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFIFOControlStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the FIFO control status register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the FIFO control status register. This parameter
 *        is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteFIFOControlStatusReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteFIFOControlStatusReg(PeripheralBase, Value) ( \
    I2S_FCSR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFIFOControlStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the FIFO control status register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_FCSR.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadFIFOControlStatusReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadFIFOControlStatusReg(PeripheralBase) ( \
    I2S_FCSR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteTxTimeSlotMaskReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the transmit time slot mask register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the transmit time slot mask register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_TMSK.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteTxTimeSlotMaskReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteTxTimeSlotMaskReg(PeripheralBase, Value) ( \
    I2S_TMSK_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadTxTimeSlotMaskReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the transmit time slot register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_TMSK.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadTxTimeSlotMaskReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadTxTimeSlotMaskReg(PeripheralBase) ( \
    I2S_TMSK_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteRxTimeSlotMaskReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the receive time slot mask register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the receive time slot mask register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_RMSK.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteRxTimeSlotMaskReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteRxTimeSlotMaskReg(PeripheralBase, Value) ( \
    I2S_RMSK_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadRxTimeSlotMaskReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the receive time slot register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_RMSK.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadRxTimeSlotMaskReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadRxTimeSlotMaskReg(PeripheralBase) ( \
    I2S_RMSK_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- EnableAC97Mode
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the AC97 mode.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of AC97 mode. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACNT.
 * @par Example:
 *      @code
 *      I2S_PDD_EnableAC97Mode(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define I2S_PDD_EnableAC97Mode(PeripheralBase, State) ( \
    I2S_ACNT_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_ACNT_REG(PeripheralBase) & (uint32_t)(~(uint32_t)I2S_ACNT_AC97EN_MASK))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- SetAC97Command
   ---------------------------------------------------------------------------- */

/**
 * @brief Selects AC97 command.
 * @param PeripheralBase Peripheral base address.
 * @param Command Parameter specifying AC97 command. This parameter is of "AC97
 *        command constant." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACNT.
 * @par Example:
 *      @code
 *      I2S_PDD_SetAC97Command(deviceID, I2S_PDD_AC97_WRITE_COMMAND);
 *      @endcode
 */
#define I2S_PDD_SetAC97Command(PeripheralBase, Command) ( \
    I2S_ACNT_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(I2S_ACNT_REG(PeripheralBase) & (uint32_t)(~(uint32_t)((uint32_t)0x3U << 3U)))) | ( \
      (uint32_t)(Command))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteAC97ControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the AC97 control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the AC97 control register. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACNT.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteAC97ControlReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteAC97ControlReg(PeripheralBase, Value) ( \
    I2S_ACNT_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadAC97ControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the AC97 control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_ACNT.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadAC97ControlReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadAC97ControlReg(PeripheralBase) ( \
    I2S_ACNT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteAC97CommandAddressReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the AC97 command address register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the AC97 command address register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACADD.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteAC97CommandAddressReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteAC97CommandAddressReg(PeripheralBase, Value) ( \
    I2S_ACADD_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadAC97CommandAddressReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the AC97 command address register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_ACADD.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadAC97CommandAddressReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadAC97CommandAddressReg(PeripheralBase) ( \
    I2S_ACADD_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteAC97CommandDataReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the AC97 command data register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the AC97 command data register. This parameter
 *        is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACDAT.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteAC97CommandDataReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteAC97CommandDataReg(PeripheralBase, Value) ( \
    I2S_ACDAT_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadAC97CommandDataReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the AC97 command data register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_ACDAT.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadAC97CommandDataReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadAC97CommandDataReg(PeripheralBase) ( \
    I2S_ACDAT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteAC97TagReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the AC97 tag register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the AC97 tag register. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ATAG.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteAC97TagReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteAC97TagReg(PeripheralBase, Value) ( \
    I2S_ATAG_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadAC97TagReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the AC97 tag register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_ATAG.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadAC97TagReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadAC97TagReg(PeripheralBase) ( \
    I2S_ATAG_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- EnableAC97Channels
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables AC97 channels.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of AC97 channels. Use constants from group "Slot masks for
 *        EnableAC97Channels, DisableAC97Channels, GetAC97ChannelStatusMask". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACCEN.
 * @par Example:
 *      @code
 *      I2S_PDD_EnableAC97Channels(deviceID, I2S_PDD_AC97_DATA_SLOT_3);
 *      @endcode
 */
#define I2S_PDD_EnableAC97Channels(PeripheralBase, Mask) ( \
    I2S_ACCEN_REG(PeripheralBase) = \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- WriteAC97ChannelEnableReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the AC97 channel enable register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the AC97 channel enable register. This parameter
 *        is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACCEN.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteAC97ChannelEnableReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteAC97ChannelEnableReg(PeripheralBase, Value) ( \
    I2S_ACCEN_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- DisableAC97Channels
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables AC97 channels.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of AC97 channels. Use constants from group "Slot masks for
 *        EnableAC97Channels, DisableAC97Channels, GetAC97ChannelStatusMask". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACCDIS.
 * @par Example:
 *      @code
 *      I2S_PDD_DisableAC97Channels(deviceID, I2S_PDD_AC97_DATA_SLOT_3);
 *      @endcode
 */
#define I2S_PDD_DisableAC97Channels(PeripheralBase, Mask) ( \
    I2S_ACCDIS_REG(PeripheralBase) = \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- WriteAC97ChannelDisableReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the AC97 channel disable register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value stored to the AC97 chanel disable register. This parameter
 *        is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: I2S0_ACCDIS.
 * @par Example:
 *      @code
 *      I2S_PDD_WriteAC97ChannelDisableReg(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_WriteAC97ChannelDisableReg(PeripheralBase, Value) ( \
    I2S_ACCDIS_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- GetAC97ChannelStatusMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns AC97 channel enable bits.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "Slot masks for EnableAC97Channels,
 *         DisableAC97Channels, GetAC97ChannelStatusMask" for processing return value.
 * @remarks The macro accesses the following registers: I2S0_ACCST.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_GetAC97ChannelStatusMask(deviceID);
 *      @endcode
 */
#define I2S_PDD_GetAC97ChannelStatusMask(PeripheralBase) ( \
    I2S_ACCST_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadAC97ChannelStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the AC97 channel status register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: I2S0_ACCST.
 * @par Example:
 *      @code
 *      uint32_t result = I2S_PDD_ReadAC97ChannelStatusReg(deviceID);
 *      @endcode
 */
#define I2S_PDD_ReadAC97ChannelStatusReg(PeripheralBase) ( \
    I2S_ACCST_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- SetClockSource
   ---------------------------------------------------------------------------- */

/**
 * @brief Selects clock source (in SIM module).
 * @param PeripheralBase Peripheral base address.
 * @param Source Requested state of clock source. Use constants from group
 *        "Clock source constants for SetClockSource.". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @par Example:
 *      @code
 *      I2S_PDD_SetClockSource(deviceID, I2S_PDD_DIVIDED_CORE_SYSTEM_CLOCK);
 *      @endcode
 */
#define I2S_PDD_SetClockSource(PeripheralBase, Source) ( \
    SIM_SOPT2_REG(SIM_BASE_PTR) = \
     (( \
      (uint32_t)(SIM_SOPT2_REG(SIM_BASE_PTR) & (uint32_t)(~(uint32_t)SIM_SOPT2_I2SSRC_MASK))) | ( \
      (uint32_t)((uint32_t)(Source) << SIM_SOPT2_I2SSRC_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetClockDivider
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets clock divider (in SIM module).
 * @param PeripheralBase Peripheral base address.
 * @param Value Value specifying division. This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @par Example:
 *      @code
 *      I2S_PDD_SetClockDivider(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_SetClockDivider(PeripheralBase, Value) ( \
    SIM_CLKDIV2_REG(SIM_BASE_PTR) = \
     (( \
      (uint32_t)(SIM_CLKDIV2_REG(SIM_BASE_PTR) & (uint32_t)(~(uint32_t)SIM_CLKDIV2_I2SDIV_MASK))) | ( \
      (uint32_t)((uint32_t)(Value) << SIM_CLKDIV2_I2SDIV_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetClockMultiplier
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets clock multiplier (in SIM module).
 * @param PeripheralBase Peripheral base address.
 * @param Value Value specifying multiplication. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @par Example:
 *      @code
 *      I2S_PDD_SetClockMultiplier(deviceID, 1);
 *      @endcode
 */
#define I2S_PDD_SetClockMultiplier(PeripheralBase, Value) ( \
    SIM_CLKDIV2_REG(SIM_BASE_PTR) = \
     (( \
      (uint32_t)(SIM_CLKDIV2_REG(SIM_BASE_PTR) & (uint32_t)(~(uint32_t)SIM_CLKDIV2_I2SFRAC_MASK))) | ( \
      (uint32_t)((uint32_t)(Value) << SIM_CLKDIV2_I2SFRAC_SHIFT))) \
  )
#endif  /* #if defined(I2S_PDD_H_) */

/* I2S_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/nat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nat.c$
* $Version : 3.8.6.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   This file contains the NAT implementation.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_init_internal2
* Parameters      :
*
*     _ip_address    IP_PRV    [IN] The private network address 
*     _ip_address    IP_MASK   [IN] The private network mask
*
* Returned Value  : void 
* Comments        :
*        Starts and initializes NAT.
*
*END*-----------------------------------------------------------------*/

static uint_32 NAT_init_internal2
   (
      NAT_PARM_PTR   parm_ptr   /* [IN] Initialization parameters */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   uint_32                 error;

   /* 
   ** Make sure the netmask is valid. We use the fact that 
   ** (x & x+1) == 0 <=> x = 2^n-1.
   */
   if (~parm_ptr->IP_MASK & (~parm_ptr->IP_MASK + 1)) {
      return RTCSERR_INVALID_PARAMETER;
   } /* Endif */

   /* Make sure other parameters have been supplied */
   if (!parm_ptr->IP_PRV) {
      return RTCSERR_INVALID_PARAMETER;
   } /* Endif */


   /*
   ** If the configuration structure has already been allocated, 
   ** just add another private network and return 
   */
   if (nat_cfg_ptr) {
      error = NAT_add_private_network(&nat_cfg_ptr->PRIVATE_NETWORKS, parm_ptr->IP_PRV, parm_ptr->IP_MASK);
      if (error == RTCS_OK) {
         nat_cfg_ptr->NAT_EXEC = NAT_apply;
      }
      return error;
   } /* Endif */
   

   // First time through the initialization,
   // Allocate the NAT configuration structure
   nat_cfg_ptr = _mem_alloc_system_zero(sizeof(NAT_CFG_STRUCT));
   if (nat_cfg_ptr == NULL) {
      return RTCSERR_OUT_OF_MEMORY;
   } /* Endif */
   
   /* Record the private network information */
   error = NAT_add_private_network(&nat_cfg_ptr->PRIVATE_NETWORKS, parm_ptr->IP_PRV, parm_ptr->IP_MASK);

   if (error == RTCS_OK) {
      nat_cfg_ptr->NAT_EXEC = NAT_apply;
         
      nat_cfg_ptr->INITIAL_PRV_NET  = parm_ptr->IP_PRV;
      nat_cfg_ptr->INITIAL_PRV_MASK = parm_ptr->IP_MASK;

      nat_cfg_ptr->TCP_TOUT.PRIVATE = &nat_cfg_ptr->TCP_HEAD;
      nat_cfg_ptr->UDP_TOUT.PRIVATE = &nat_cfg_ptr->UDP_HEAD;
      nat_cfg_ptr->FIN_TOUT.PRIVATE = &nat_cfg_ptr->FIN_HEAD;
      nat_cfg_ptr->ICMP_TOUT.PRIVATE = &nat_cfg_ptr->ICMP_HEAD;
      
      /* Initialize radix trees */
      IPRADIX_init(&nat_cfg_ptr->ROOT_IN);
      IPRADIX_init(&nat_cfg_ptr->ROOT_OUT);
      
      /* Initialize timeout functions */
      nat_cfg_ptr->UDP_TOUT.EVENT = NAT_expire;
      nat_cfg_ptr->TCP_TOUT.EVENT = NAT_expire;
      nat_cfg_ptr->FIN_TOUT.EVENT = NAT_expire;
      nat_cfg_ptr->ICMP_TOUT.EVENT = NAT_expire;
      nat_cfg_ptr->TIMEOUT_TCP = NAT_DEFAULT_TIMEOUT_TCP;
      nat_cfg_ptr->TIMEOUT_UDP = NAT_DEFAULT_TIMEOUT_UDP;
      nat_cfg_ptr->TIMEOUT_FIN = NAT_DEFAULT_TIMEOUT_FIN;
      nat_cfg_ptr->TIMEOUT_ICMP = NAT_DEFAULT_TIMEOUT_ICMP;
      
      /* Initialize last used port numbers */
      nat_cfg_ptr->TCP_PORT = NAT_DEFAULT_PORT_MIN;
      nat_cfg_ptr->UDP_PORT = NAT_DEFAULT_PORT_MIN;
      nat_cfg_ptr->ICMP_ID = NAT_DEFAULT_PORT_MIN;
      nat_cfg_ptr->PORT_MAX = NAT_DEFAULT_PORT_MAX;
      nat_cfg_ptr->PORT_MIN = NAT_DEFAULT_PORT_MIN;

      /* Inititalize ALGs */
      error = NAT_init_algs(nat_cfg_ptr);
   }

   /* Allocate partitions */
   if (error == RTCS_OK)  {
      nat_cfg_ptr->SESSION_PART = RTCS_part_create(sizeof(NAT_SESSION_STRUCT),
         NAT_SESSION_INITIAL_COUNT, NAT_SESSION_GROW_COUNT, NAT_SESSION_MAX,
         NULL, NULL);
      if (nat_cfg_ptr->SESSION_PART == NULL) {
         error = RTCSERR_OUT_OF_MEMORY;
      } /* Endif */
   } /* Endif */

   if (error == RTCS_OK)  {
      nat_cfg_ptr->RADIX_IN = RTCS_part_create(sizeof(IPRADIX_NODE), 
         NAT_SESSION_INITIAL_COUNT, NAT_SESSION_GROW_COUNT, NAT_SESSION_MAX,
         NULL, NULL);
      if (nat_cfg_ptr->RADIX_IN == NULL) {
         error = RTCSERR_OUT_OF_MEMORY;
      } /* Endif */
   } /* Endif */


   if (error == RTCS_OK)  {
      nat_cfg_ptr->RADIX_OUT = RTCS_part_create(sizeof(IPRADIX_NODE), 
         NAT_SESSION_INITIAL_COUNT, NAT_SESSION_GROW_COUNT, NAT_SESSION_MAX,
         NULL, NULL);
      if (nat_cfg_ptr->RADIX_OUT == NULL) {
         error = RTCSERR_OUT_OF_MEMORY;
      } /* Endif */
   } /* Endif */

   if (error == RTCS_OK)  {
      // Initialize queue of DNAT Rules
      _queue_init( &nat_cfg_ptr->RULE_QUEUE, 0 );
         
      RTCS_setcfg(NAT, nat_cfg_ptr);

   } else {
      if (nat_cfg_ptr != NULL) {
         if (nat_cfg_ptr->RADIX_IN != NULL) RTCS_part_destroy(nat_cfg_ptr->RADIX_IN);
         if (nat_cfg_ptr->RADIX_OUT != NULL) RTCS_part_destroy(nat_cfg_ptr->RADIX_OUT);
         if (nat_cfg_ptr->SESSION_PART != NULL) RTCS_part_destroy(nat_cfg_ptr->SESSION_PART);
         _mem_free(nat_cfg_ptr);
      }
   } /* Endif */

   return error;                     
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_init_internal
* Parameters      :
*
*     _ip_address    IP_PRV    [IN] The private network address 
*     _ip_address    IP_MASK   [IN] The private network mask
*
* Returned Value  : void 
* Comments        :
*        Starts and initializes NAT.
*
*END*-----------------------------------------------------------------*/

void NAT_init_internal
   (
      NAT_PARM_PTR   parm_ptr   /* [IN] Initialization parameters */
   )
{
   RTCSCMD_complete(parm_ptr, NAT_init_internal2(parm_ptr));      
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_add_network_internal
* Returned Value  : void 
* Comments        :
*        Add a new private network.
*
*END*-----------------------------------------------------------------*/

void NAT_add_network_internal
   (
      NAT_PARM_PTR   parm_ptr   /* [IN] Initialization parameters */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   uint_32                 error;

   // Make sure NAT is already up
   if (nat_cfg_ptr == NULL) {
      error = RTCSERR_NAT_NOT_INITIALIZED;
 
   /* 
   ** Make sure the netmask is valid. We use the fact that 
   ** (x & x+1) == 0 <=> x = 2^n-1.
   */
   } else if (~parm_ptr->IP_MASK & (~parm_ptr->IP_MASK + 1)) {
      error = RTCSERR_INVALID_PARAMETER;

   /* Make sure other parameters have been supplied */
   } else if (!parm_ptr->IP_PRV) {
      error = RTCSERR_INVALID_PARAMETER;

   } else {
      error = NAT_add_private_network(&nat_cfg_ptr->PRIVATE_NETWORKS, parm_ptr->IP_PRV, parm_ptr->IP_MASK);
   }

   RTCSCMD_complete(parm_ptr, error);      
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_remove_network_internal
* Returned Value  : void 
* Comments        :
*        Remove a private network.
*
*END*-----------------------------------------------------------------*/

void NAT_remove_network_internal
   (
      NAT_PARM_PTR   parm_ptr   /* [IN] Initialization parameters */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   uint_32                 error;

   // Make sure NAT is already up
   if (nat_cfg_ptr == NULL) {
      error = RTCSERR_NAT_NOT_INITIALIZED;

   /* 
   ** Make sure the netmask is valid. We use the fact that 
   ** (x & x+1) == 0 <=> x = 2^n-1.
   */
   } else if (~parm_ptr->IP_MASK & (~parm_ptr->IP_MASK + 1)) {
      error = RTCSERR_INVALID_PARAMETER;

   /* Make sure other parameters have been supplied */
   } else if (!parm_ptr->IP_PRV) {
      error = RTCSERR_INVALID_PARAMETER;

   } else {
      // Try to remove the private network
      error=NAT_remove_private_network(&nat_cfg_ptr->PRIVATE_NETWORKS, parm_ptr->IP_PRV, parm_ptr->IP_MASK);
   }

   RTCSCMD_complete(parm_ptr, error);      

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_close_internal
* Returned Value  : void 
* Comments        :
*        Stops NAT.
*
*END*-----------------------------------------------------------------*/

void NAT_close_internal
   (
      NAT_PARM_PTR   parm_ptr    /* [IN] Unused */         
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   uint_32                 error;
   
   if (nat_cfg_ptr == NULL) {
      error = RTCSERR_NAT_NOT_INITIALIZED;
   } else {
      nat_cfg_ptr->NAT_EXEC = NULL;
      error = RTCS_OK;
   }

   RTCSCMD_complete(parm_ptr, error);         
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_config_timeouts
* Returned Value  : RTCS_OK or uint_32 error code 
* Comments        :
*     Dynamically updates NAT timeouts
*
*END*-----------------------------------------------------------------*/

void NAT_config_timeouts
   (
      NAT_TIMEOUTS_STRUCT_PTR   nat_timeouts_ptr   /* [IN] New values for timeouts */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR   nat_cfg_ptr = RTCS_getcfg(NAT);

   if (nat_timeouts_ptr->timeout_tcp) {
      nat_cfg_ptr->TIMEOUT_TCP = nat_timeouts_ptr->timeout_tcp;
      NAT_tout_max(&nat_cfg_ptr->TCP_TOUT, nat_cfg_ptr->TIMEOUT_TCP);
   } /* Endif */

   if (nat_timeouts_ptr->timeout_fin) {
      nat_cfg_ptr->TIMEOUT_FIN = nat_timeouts_ptr->timeout_fin;
      NAT_tout_max(&nat_cfg_ptr->FIN_TOUT, nat_cfg_ptr->TIMEOUT_FIN);
   } /* Endif */

   if (nat_timeouts_ptr->timeout_udp) {
      nat_cfg_ptr->TIMEOUT_UDP = nat_timeouts_ptr->timeout_udp;
      NAT_tout_max(&nat_cfg_ptr->UDP_TOUT, nat_cfg_ptr->TIMEOUT_UDP);
   } /* Endif */

   if (nat_timeouts_ptr->timeout_icmp) {
      nat_cfg_ptr->TIMEOUT_ICMP = nat_timeouts_ptr->timeout_icmp;
      NAT_tout_max(&nat_cfg_ptr->ICMP_TOUT, nat_cfg_ptr->TIMEOUT_ICMP);
   } /* Endif */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_config_ports
* Returned Value  : RTCS_OK or uint_32 error code 
* Comments        :
*     Dynamically updates NAT minimum and maximum port numbers
*
*END*-----------------------------------------------------------------*/

void NAT_config_ports
   (
      NAT_PORTS_STRUCT_PTR   nat_ports_ptr   /* [IN] New values for port ranges */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR   nat_cfg_ptr = RTCS_getcfg(NAT);

   if (nat_ports_ptr->port_min) {
      if (nat_ports_ptr->port_min > nat_cfg_ptr->PORT_MAX) {
         nat_cfg_ptr->PORT_MIN = nat_cfg_ptr->PORT_MAX;
      } else {
         nat_cfg_ptr->PORT_MIN = nat_ports_ptr->port_min;
      } /* Endif */
   } /* Endif */
   
   if (nat_ports_ptr->port_max) {
      if (nat_ports_ptr->port_max < nat_cfg_ptr->PORT_MIN) {
         nat_cfg_ptr->PORT_MAX = nat_cfg_ptr->PORT_MIN;
      } else {
         nat_cfg_ptr->PORT_MAX = nat_ports_ptr->port_max;
      } /* Endif */

      /* Fix the last used port numbers so that they don't exceed max */
      nat_cfg_ptr->TCP_PORT = nat_cfg_ptr->PORT_MIN;
      nat_cfg_ptr->UDP_PORT = nat_cfg_ptr->PORT_MIN;
      nat_cfg_ptr->ICMP_ID  = nat_cfg_ptr->PORT_MIN;
   } /* Endif */

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_is_private_addr
* Returned Value  : TRUE if ipaddr is within one of the private networks
* Comments        :
*
*END*-----------------------------------------------------------------*/

boolean NAT_is_private_addr(NAT_NETWORK_STRUCT_PTR nat_network_ptr, _ip_address ipaddr)
{
   uint_32  i;
   
   for (i=0;i<nat_network_ptr->NUM_PRV_NETS;i++) {
      if ((ipaddr & nat_network_ptr->PRV_MASK[i]) == nat_network_ptr->PRV_NET[i]) {
         return TRUE;
      }
   }
   return FALSE;
}
      
      
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_add_private_network
* Returned Value  : RTCS_OK if ipaddr is added as a private network
* Comments        :
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_add_private_network(NAT_NETWORK_STRUCT_PTR nat_network_ptr, _ip_address netaddr, _ip_address netmask)
{
   _ip_address    new_netaddr = netaddr & netmask;
   uint_32        i;
   
   // First, check to see if it is already installed
   for (i=0;i<nat_network_ptr->NUM_PRV_NETS;i++) {
      if ((new_netaddr == nat_network_ptr->PRV_NET[i]) && (netmask == nat_network_ptr->PRV_MASK[i])) {
         // It is, return OK
         return RTCS_OK;
      }
   }

   // It isn't -  is there room for one more?
   if (nat_network_ptr->NUM_PRV_NETS >= NAT_MAX_PRIVATE_NETWORKS) {
      // No, there is not
      return RTCSERR_NAT_MAX_PRIVATE_NETWORKS;
   }
   
   // Yes there is, so add it
   nat_network_ptr->PRV_NET[nat_network_ptr->NUM_PRV_NETS] = new_netaddr;
   nat_network_ptr->PRV_MASK[nat_network_ptr->NUM_PRV_NETS] = netmask;
   nat_network_ptr->NUM_PRV_NETS++;
   
   return RTCS_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_remove_private_network
* Returned Value  : 
* Comments        :
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_remove_private_network(NAT_NETWORK_STRUCT_PTR nat_network_ptr, _ip_address netaddr, _ip_address netmask)
{
   uint_32  i;
   _ip_address new_netaddr = netaddr & netmask;
   
   // First, check to see if it is already installed
   for (i=0;i<nat_network_ptr->NUM_PRV_NETS;i++) {
      if ((new_netaddr == nat_network_ptr->PRV_NET[i]) && (netmask == nat_network_ptr->PRV_MASK[i])) {
         // It is, delete it
         nat_network_ptr->NUM_PRV_NETS--;
         nat_network_ptr->PRV_NET[i] = nat_network_ptr->PRV_NET[nat_network_ptr->NUM_PRV_NETS];
         nat_network_ptr->PRV_MASK[i] = nat_network_ptr->PRV_MASK[nat_network_ptr->NUM_PRV_NETS];
         nat_network_ptr->PRV_NET[nat_network_ptr->NUM_PRV_NETS] = 0;
         nat_network_ptr->PRV_MASK[nat_network_ptr->NUM_PRV_NETS] = 0;
         return RTCS_OK;
      }
   }

   return RTCSERR_NAT_INVALID_PRIVATE_NETWORK;
}
 
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/khci/khci_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: khci_prv.h$
* $Version : 3.8.18.0$
* $Date    : Jun-22-2012$
*
* Comments:
*
*   This file contains the macros, function prototypes and data structure
*   definitions required by the KHCI USB device driver.
*
*END************************************************************************/
#ifndef __khci_prv_h__
#define __khci_prv_h__

#include <mqx.h>
#include <lwevent.h>
#include <lwmsgq.h>

#include <bsp.h>

#include "host_cnfg.h"
#include "hostapi.h"    /* needed for USB_SERVICE_STRUCT_PTR */
#include "host_main.h"

enum {
    TR_CTRL,
    TR_IN,
    TR_OUT,
    TR_OUT_HNDSK,
    TR_IN_HNDSK
};

typedef struct khci_tr_struct {
   struct tr_struct G;
   uint_32  status;
} KHCI_TR_STRUCT, _PTR_ KHCI_TR_STRUCT_PTR;

typedef struct khci_pipe_struct
{
   /* Fields common to both pipe descriptors and the structures used to
    * initialize new pipe instances.
    */
   PIPE_STRUCT         G;
} KHCI_PIPE_STRUCT, _PTR_ KHCI_PIPE_STRUCT_PTR;

/* Transaction type */
typedef enum {
    TR_MSG_UNKNOWN,     // unknow - not used
    TR_MSG_SETUP,       // setup transaction
    TR_MSG_SEND,        // send trnasaction
    TR_MSG_RECV         // receive transaction
} TR_MSG_TYPE;


/* Transaction message */
typedef struct {
    TR_MSG_TYPE type;                       // transaction type
    KHCI_PIPE_STRUCT_PTR pipe_desc;         // pointer to pipe descriptor
    KHCI_TR_STRUCT_PTR pipe_tr;             // pointer to transaction
} TR_MSG_STRUCT;

/* Interrupt transaction message queue */
typedef struct tr_int_que_itm_struct {
    TIME_STRUCT   time;         /* next time to fire interrupt */
    _mqx_uint     period;       /* period in [ms] for interrupt endpoint */
    TR_MSG_STRUCT msg;          /* atom transaction message */
} TR_INT_QUE_ITM_STRUCT, _PTR_ TR_INT_QUE_ITM_STRUCT_PTR;

#define BDT_BASE                ((uint_32*)(bdt))
#define BD_PTR(ep, rxtx, odd)   (((uint_32)BDT_BASE) & 0xfffffe00 | ((ep & 0x0f) << 5) | ((rxtx & 1) << 4) | ((odd & 1) << 3))

#define BD_CTRL(ep,rxtx,odd)    (*((uint_32*)BD_PTR(ep, rxtx, odd)))
#define BD_CTRL_RX(ep, odd)     (*((uint_32*)BD_PTR(ep, 0, odd)))
#define BD_CTRL_TX(ep, odd)     (*((uint_32*)BD_PTR(ep, 1, odd)))

#define BD_ADDR(ep,rxtx,odd)    (*((uint_32*)BD_PTR(ep, rxtx, odd) + 1))
#define BD_ADDR_RX(ep, odd)     (*((uint_32*)BD_PTR(ep, 0, odd) + 1))
#define BD_ADDR_TX(ep, odd)     (*((uint_32*)BD_PTR(ep, 1, odd) + 1))

/* Define USB buffer descriptor definitions in case of their lack */
#ifndef USB_BD_BC
#   define USB_BD_BC(n)                 ((n & 0x3ff) << 16)
#   define USB_BD_OWN                   0x80
#   define USB_BD_DATA01(n)             ((n & 1) << 6)
#   define USB_BD_DATA0                 USB_BD_DATA01(0)
#   define USB_BD_DATA1                 USB_BD_DATA01(1)
#   define USB_BD_KEEP                  0x20
#   define USB_BD_NINC                  0x10
#   define USB_BD_DTS                   0x08
#   define USB_BD_STALL                 0x04
#   define USB_BD_PID(n)                ((n & 0x0f) << 2)
#endif

#ifndef USB_TOKEN_TOKENPID_SETUP
#   define USB_TOKEN_TOKENPID_OUT                   USB_TOKEN_TOKENPID(0x1)
#   define USB_TOKEN_TOKENPID_IN                    USB_TOKEN_TOKENPID(0x9)
#   define USB_TOKEN_TOKENPID_SETUP                 USB_TOKEN_TOKENPID(0xD)
#endif

/* Alignement of buffer for DMA transfer, needed in some cases,
** USB DMA bus could not possibly be intializes properly and 
** first data transfered is the one aligned at 4-byte boundary
*/
#define USB_MEM4_ALIGN(n)               ((n) + (-(n) & 3))
#define USB_DMA_ALIGN(n)                USB_MEM4_ALIGN(n)


typedef struct usb_khci_host_state_struct
{
   USB_HOST_STATE_STRUCT               G; /* generic host state */
   /* Driver-specific fields */
   uint_32                             vector;
   boolean                             endian_swap;
   /* RX/TX buffer descriptor toggle bits */
   uint_8                              rx_bd;
   uint_8                              tx_bd;
   /* event from KHCI peripheral */
   LWEVENT_STRUCT                      khci_event;
   /* Pipe, that had latest NAK respond, usefull to cut bandwidth for interrupt pipes sending no data */
   KHCI_PIPE_STRUCT_PTR                last_to_pipe;
   /* Interrupt transactions */
   TR_INT_QUE_ITM_STRUCT               tr_int_que[USBCFG_KHCI_MAX_INT_TR];
   _mqx_max_type                       tr_que[(sizeof(LWMSGQ_STRUCT) + USBCFG_KHCI_TR_QUE_MSG_CNT * sizeof(TR_MSG_STRUCT)) / sizeof(_mqx_max_type) + 1];
} USB_KHCI_HOST_STATE_STRUCT, _PTR_ USB_KHCI_HOST_STATE_STRUCT_PTR;

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GMCLIB/GMCLIB_Park.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GMCLIB_Park.h
*
* @author    <NAME>
*
* @version   1.0.1.0
*
* @date      Dec-6-2012
*
* @brief     Header file for Park Transformation.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GMCLIB_PARK_H_
#define _GMCLIB_PARK_H_

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif

/************************************************************************
| defines and macros (scope: module-local)
|-----------------------------------------------------------------------*/
/*! Function alias for the #GMCLIB_ParkANSIC function.*/
#define GMCLIB_Park(pOut,pInAngle,pIn) GMCLIB_ParkANSIC(pOut,pInAngle,pIn)

/************************************************************************
| typedefs and structures (scope: module-local)
|-----------------------------------------------------------------------*/

/************************************************************************
| exported variables
|-----------------------------------------------------------------------*/

/************************************************************************
| exported function prototypes
|-----------------------------------------------------------------------*/
/*!
* @ingroup GMCLIB_GROUP
*/
extern void GMCLIB_ParkANSIC(MCLIB_2_COOR_SYST_D_Q_T *pOut,
                      const MCLIB_ANGLE_T *const pInAngle,
                      const MCLIB_2_COOR_SYST_ALPHA_BETA_T *const pIn);

#ifdef __cplusplus
}
#endif
#endif /* _GMCLIB_PARK_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_iodebug.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_iodebug.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the initialization definition for debug driver
*
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"


#if defined(__CC_ARM)
/* ITM - KEIL default*/
const IODEBUG_INIT_STRUCT _bsp_iodebug_init = { 
    IODEBUG_MODE_ITM,       /* Driver mode */ 
    0,                      /* Length of buffered data */ 
    '\n'                    /* Default flush character */
};


#else
/* SEMIHOST - CW, IAR */
const IODEBUG_INIT_STRUCT _bsp_iodebug_init = { 
    IODEBUG_MODE_SEMIHOST,  /* Driver mode */ 
    127,                    /* Length of buffered data */ 
    '\n'                    /* Default flush character */
};
#endif 

/*
** CW : If semihost used, data length should be less/eq than 1023
** IAR: If semihost used, data length should be less/eq than 127
*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/charq.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: charq.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file includes the definitions for a character queue data
*   structure.
*
*END************************************************************************/
#ifndef __charq_h__
#define __charq_h__

/*--------------------------------------------------------------------------*/
/*
 *                            MACRO DEFINITIONS
 */


/* Initialize the character queue */
#define _CHARQ_INIT(cq,max_size) \
   (cq)->MAX_SIZE = max_size; \
   (cq)->CURRENT_SIZE = 0; \
   (cq)->HEAD         = 0; \
   (cq)->TAIL         = 0;


/* 
 * Remove a character to the TAIL of the queue 
 * (Normal writing location for the queue)
 */
#define _CHARQ_ENQUEUE(cq,c) \
   if ( (cq)->CURRENT_SIZE < (cq)->MAX_SIZE ) { \
      (cq)->QUEUE[(cq)->TAIL++] = (char)(c); \
      if ( (cq)->TAIL == (cq)->MAX_SIZE ) { \
         (cq)->TAIL = 0; \
      } /* Endif */ \
      ++(cq)->CURRENT_SIZE; \
   } /* Endif */ 


/* 
 * Add a character from the HEAD of the queue 
 * (Reading location)
 */
#define _CHARQ_ENQUEUE_HEAD(cq,c) \
   if ( (cq)->CURRENT_SIZE < (cq)->MAX_SIZE ) { \
      if ((cq)->HEAD == 0) { \
        (cq)->HEAD = (cq)->MAX_SIZE; \
      } /* Endif */ \
      --(cq)->HEAD; \
     (cq)->QUEUE[(cq)->HEAD] = c; \
     (cq)->CURRENT_SIZE++; \
   } /* Endif */

   
/* 
 * Remove a character from the HEAD of the queue 
 * (Normal reading location for the queue)
 */
#define _CHARQ_DEQUEUE(cq,c) \
   if ( (cq)->CURRENT_SIZE ) { \
      --(cq)->CURRENT_SIZE; \
      c = (cq)->QUEUE[((cq)->HEAD++)]; \
      if ( (cq)->HEAD == (cq)->MAX_SIZE ) { \
         (cq)->HEAD = 0; \
      } /* Endif */ \
   } /* Endif */


/* 
 * Remove a character from the TAIL of the queue 
 * (Writing location)
 */
#define _CHARQ_DEQUEUE_TAIL(cq,c) \
   if ( (cq)->CURRENT_SIZE ) { \
      --(cq)->CURRENT_SIZE; \
      if ( (cq)->TAIL == 0 ) { \
         (cq)->TAIL = (cq)->MAX_SIZE; \
      } /* Endif */ \
      c = (cq)->QUEUE[--(cq)->TAIL]; \
   } /* Endif */


/* Return the current size of the queue */
#define _CHARQ_SIZE(cq) ((cq)->CURRENT_SIZE)


/* Return whether the queue is empty */
#define _CHARQ_EMPTY(cq) ((cq)->CURRENT_SIZE == 0)


/* Return whether the queue is full */
#define _CHARQ_FULL(q) ((q)->CURRENT_SIZE >= (q)->MAX_SIZE)


/* Return whether the queue is NOT full */
#define _CHARQ_NOT_FULL(q) ((q)->CURRENT_SIZE < (q)->MAX_SIZE)


/*--------------------------------------------------------------------------*/
/*
 *                            DATATYPE DECLARATIONS
 */

/*---------------------------------------------------------------------
 *
 * CHARQ STRUCTURE
 */
 
/*! 
 * \brief This structure used to store a circular character queue.
 *  
 * The structure must be the LAST if it is included into another data structure, 
 * as the character queue falls off of the end of this structure.
 */
typedef struct charq_struct
{
   
   /*! 
    * \brief The maximum number of characters for the queue, as specified in
    * initialization of the queue.
    */
   _mqx_uint  MAX_SIZE;   

   /*! \brief The current number of characters in the queue. */
   _mqx_uint  CURRENT_SIZE;  

   /*! \brief Index of the first character in queue. */
   _mqx_uint  HEAD;          

   /*! \brief Index of the last character in queue. */
   _mqx_uint  TAIL;          

   /*! \brief The character queue itself. */
   char      QUEUE[4];

} CHARQ_STRUCT, _PTR_ CHARQ_STRUCT_PTR;

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_ControllerPIp.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_ControllerPIp.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_ControllerPIp function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_CONTROLLER_PIP_H
#define _GFLIB_CONTROLLER_PIP_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif

/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GFLIB_ControllerPIpANSIC function.*/
#define GFLIB_ControllerPIp(f32InErr,pParam) GFLIB_ControllerPIpANSIC(f32InErr, pParam)

/*! Macro containing default values of the parallel PI controller structure.*/
#define GFLIB_CONTROLLER_PI_P_DEFAULT   {0,0,0,0,0,0}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_CONTROLLER_PI_P_T "\GFLIB_ControllerPIp.h"

@brief  Structure containing parameters and states of the the parallel form PI controller.
*//*-------------------------------------------------------------------------*/
typedef struct {
  Frac32   f32PropGain;        /*!< Proportional Gain, fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ */
  Frac32   f32IntegGain;       /*!< Integral Gain, fractional format normalized to fit into  \f$\left[-2^{31},2^{31}-1\right)\f$ */
  Word16      w16PropGainShift;   /*!< Proportional Gain Shift, integer format \f$\left[-31,31\right]\f$ */
  Word16      w16IntegGainShift;  /*!< Integral Gain Shift, integer format \f$\left[-31,31\right]\f$ */
  Frac32   f32IntegPartK_1;    /*!< State variable integral part at step k-1*/
  Frac32   f32InK_1;           /*!< State variable input error at step k-1*/
} GFLIB_CONTROLLER_PI_P_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*!
* @ingroup GFLIB_GROUP
*/

extern Frac32 GFLIB_ControllerPIpANSIC(Frac32 f32InErr,
                                        GFLIB_CONTROLLER_PI_P_T *pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GFLIB_CONTROLLER_PIP_H */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/snmp/traps.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: traps.c$
* $Version : 3.8.12.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   
*
*END************************************************************************/
#include <string.h>
#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>
#include "tcpip.h"
#include "ip_prv.h"
#include "snmpcfg.h"
#include "asn1.h"
#include "snmp.h"

#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4

/* This node is defined in mib.c */
extern RTCSMIB_NODE MIBNODE_enterprises;
extern RTCSMIB_NODE MIBNODE_snmpModules;

/* These nodes are defined as part of MIB-II (RFC 1213) and is found in 1213.c */
extern RTCSMIB_NODE MIBNODE_snmp;
extern RTCSMIB_NODE MIBNODE_sysUpTime;
extern RTCSMIB_NODE MIBNODE_ifIndex;

/* The following are defined in this file */
extern RTCSMIB_NODE MIBNODE_snmpTrapEnterprise;
extern RTCSMIB_NODE MIBNODE_snmpMIBObjects;
extern RTCSMIB_NODE MIBNODE_snmpTrapOID;
extern RTCSMIB_NODE MIBNODE_snmpTraps;
extern RTCSMIB_NODE MIBNODE_snmpTrap;
extern RTCSMIB_NODE MIBNODE_snmpMIB;

/* functions from 1213.c */
extern boolean MIB_find_ifEntry(uint_32, pointer, pointer _PTR_);
extern uint_32 MIB_get_ifIndex (pointer interface);
extern uint_32 MIB_get_sysUpTime(pointer);

RTCSMIB_VALUE MIBVALUE_snmpTrapEnterprise = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

RTCSMIB_VALUE MIBVALUE_snmpMIBObjects = {
    0,
    NULL
};

RTCSMIB_VALUE MIBVALUE_snmpTrapOID = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

RTCSMIB_VALUE MIBVALUE_snmpTraps = {
    0,
    NULL
};

RTCSMIB_VALUE MIBVALUE_snmpTrap = {
    0,
    NULL
};

RTCSMIB_VALUE MIBVALUE_snmpMIB = {
    0,
    NULL
};

RTCSMIB_NODE MIBNODE_snmpTrapEnterprise = {
   3,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpTrap,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OBJECT,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpTrapEnterprise,
   NULL
};

RTCSMIB_NODE MIBNODE_snmpMIBObjects = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpTrap,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpMIB,

   0,
   NULL,
   NULL, 0, 
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpMIBObjects, 
   NULL
};

RTCSMIB_NODE MIBNODE_snmpTrapOID = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpTrapEnterprise,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpTrap,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OBJECT,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpTrapOID,
   NULL
};

RTCSMIB_NODE MIBNODE_snmpTraps = {
   5,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpMIBObjects,

   0,
   NULL,
   NULL, 0, 
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpTraps, 
   NULL
};

RTCSMIB_NODE MIBNODE_snmpTrap = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpTraps,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpTrapOID,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpMIBObjects,

   0,
   NULL,
   NULL, 0, 
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpTrap, 
   NULL
};

RTCSMIB_NODE MIBNODE_snmpMIB = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpMIBObjects,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpModules,

   0,
   NULL,
   NULL, 0, 
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpMIB, 
   NULL
};


boolean SNMP_trap_select_community
   (
      char_ptr   community
   )
{ /* Body */
   SNMP_PARSE_PTR   snmpcfg = SNMP_get_data();
   uint_32          i;
   boolean          result = FALSE;
   
   /* Check to see SNMP is initialized */
   if(snmpcfg == NULL)
      return (result);

   for(i=0; i < SNMPCFG_NUM_COMMUNITY; i++) {
      if(!strcmp(community, snmpcfg->community[i]))
      {
         snmpcfg->currentcommunity = i;
         result = TRUE;
         break;
      } /* Endif */               
   } /* Endfor */
        
   return (result);
        
} /* Endbody */


void SNMP_trap_warmStart
   (
      void
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen;
   RTCSMIB_NODE_PTR  node;
   uint_32           i;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc, ipaddr;
   sockaddr_in       addr;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, traplen, ASN1_TYPE_TimeTicks, i);
   /* specific-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* generic-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 1);
   /* skip agent-addr */
   traplen     += 4;
   snmp.outlen -= 4;
   snmp.outbuf -= 4;
   ipsrcp = snmp.outbuf;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_IpAddress, 4);

   /* enterprise */
   node = &MIBNODE_snmp;
   oidlen = 0;
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen;

   /* complete Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAP, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 0=v1 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         ipaddr = snmpcfg->trap_receiver_list[i];
         ipsrc = IP_route_find(ipaddr, 0);
         htonl(ipsrcp, ipsrc);
         addr.sin_addr.s_addr = ipaddr;
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMP_trap_coldStart
   (
      void
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen;
   RTCSMIB_NODE_PTR  node;
   uint_32           i;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc, ipaddr;
   sockaddr_in       addr;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, traplen, ASN1_TYPE_TimeTicks, i);
   /* specific-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* generic-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* skip agent-addr */
   traplen     += 4;
   snmp.outlen -= 4;
   snmp.outbuf -= 4;
   ipsrcp = snmp.outbuf;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_IpAddress, 4);

   /* enterprise */
   node = &MIBNODE_snmp;
   oidlen = 0;
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen;

   /* complete Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAP, traplen);
   /* community */  
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);      
   /* version, 0=v1 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         ipaddr = snmpcfg->trap_receiver_list[i];
         ipsrc = IP_route_find(ipaddr, 0);
         htonl(ipsrcp, ipsrc);
         addr.sin_addr.s_addr = ipaddr;
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMP_trap_authenticationFailure
   (
      void
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen;
   RTCSMIB_NODE_PTR  node;
   uint_32           i;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc, ipaddr;
   sockaddr_in       addr;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, traplen, ASN1_TYPE_TimeTicks, i);
   /* specific-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* generic-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 4);
   /* skip agent-addr */
   traplen     += 4;
   snmp.outlen -= 4;
   snmp.outbuf -= 4;
   ipsrcp = snmp.outbuf;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_IpAddress, 4);

   /* enterprise */
   node = &MIBNODE_snmp;
   oidlen = 0;
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen;

   /* complete Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAP, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 0=v1 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         ipaddr = snmpcfg->trap_receiver_list[i];
         ipsrc = IP_route_find(ipaddr, 0);
         htonl(ipsrcp, ipsrc);
         addr.sin_addr.s_addr = ipaddr;
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */

void SNMP_trap_linkDown
   (
      pointer  ihandle
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node = NULL;
   pointer           instance;
   uint_32           i, temp;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc, ipaddr;
   sockaddr_in       addr;
   
   RTCSMIB_VALUE_PTR mib_val;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for ifIndex */

   varlen = 0;
   node = &MIBNODE_ifIndex;
   mib_val = (pointer)node->GET;
   temp = MIB_get_ifIndex(ihandle);
   MIB_find_ifEntry(RTCSMIB_OP_GET, &temp, &instance);

   { /* Scope */
      int_32   sinteger = 0;
      uint_32  uinteger = 0;
#if SNMPCFG_HAVE_INT64
      int_64   sinteger64 = 0;
      uint_64  uinteger64 = 0;
#endif

    switch (mib_val->TYPE) {
    case RTCSMIB_NODETYPE_INT_CONST:
        sinteger = (int_32)(mib_val->PARAM);
        break; 
    case RTCSMIB_NODETYPE_INT_PTR:   
        sinteger = *(int_32 *)(mib_val->PARAM);
        break;
    case RTCSMIB_NODETYPE_INT_FN: 
        sinteger = ((RTCSMIB_INT_FN_PTR)mib_val->PARAM)(instance);      
        break;
    case RTCSMIB_NODETYPE_UINT_CONST:
        uinteger = (uint_32)(mib_val->PARAM); 
        break; 
    case RTCSMIB_NODETYPE_UINT_PTR: 
        uinteger = *(uint_32 *)(mib_val->PARAM); 
        break;
    case RTCSMIB_NODETYPE_UINT_FN:      
        uinteger = ((RTCSMIB_UINT_FN_PTR)mib_val->PARAM)(instance);
        break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:  sinteger64 = node->GET.INT64_CONST; break;
      case RTCSMIB_NODETYPE_INT64_PTR:    sinteger64 = *node->GET.INT64_PTR; break;
      case RTCSMIB_NODETYPE_INT64_FN:     sinteger64 = node->GET.INT64_FN(instance); break;
      case RTCSMIB_NODETYPE_UINT64_CONST: uinteger64 = node->GET.UINT64_CONST; break;
      case RTCSMIB_NODETYPE_UINT64_PTR:   uinteger64 = *node->GET.UINT64_PTR; break;
      case RTCSMIB_NODETYPE_UINT64_FN:    uinteger64 = node->GET.UINT64_FN(instance); break;
#endif
      } /* Endswitch */

      switch (mib_val->TYPE) {
      case RTCSMIB_NODETYPE_INT_CONST:
      case RTCSMIB_NODETYPE_INT_PTR:
      case RTCSMIB_NODETYPE_INT_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger);
         break;
      case RTCSMIB_NODETYPE_UINT_CONST:
      case RTCSMIB_NODETYPE_UINT_PTR:
      case RTCSMIB_NODETYPE_UINT_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger);
         break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:
      case RTCSMIB_NODETYPE_INT64_PTR:
      case RTCSMIB_NODETYPE_INT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger64);
         break;
      case RTCSMIB_NODETYPE_UINT64_CONST:
      case RTCSMIB_NODETYPE_UINT64_PTR:
      case RTCSMIB_NODETYPE_UINT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger64);
         break;
#endif
      } /* Endswitch */
   } /* Endscope */

   oidlen = 0;

   { /* Scope */
      struct {
         uint_32 ifIndex;
      } _PTR_ index = (pointer)&temp;
      ASN1_BKWRITE_ID(&snmp, oidlen, index->ifIndex);
   } /* Endscope */
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, traplen, ASN1_TYPE_TimeTicks, i);
   /* specific-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* generic-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 2);
   /* skip agent-addr */
   traplen     += 4;
   snmp.outlen -= 4;
   snmp.outbuf -= 4;
   ipsrcp = snmp.outbuf;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_IpAddress, 4);

   /* enterprise */
   node = &MIBNODE_snmp;
   oidlen = 0;
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen;

   /* complete Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAP, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 0=v1 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i=0; i<SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         ipaddr = snmpcfg->trap_receiver_list[i];
         ipsrc = IP_route_find(ipaddr, 0);
         htonl(ipsrcp, ipsrc);
         addr.sin_addr.s_addr = ipaddr;
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMP_trap_myLinkDown
   (
     pointer  ihandle
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   pointer           instance;
   uint_32           i, temp;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc, ipaddr;
   sockaddr_in       addr;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   RTCSMIB_VALUE_PTR    mib_val;    
   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for ifIndex */
   varlen = 0;
   node = &MIBNODE_ifIndex;
   mib_val = (pointer)node->GET;
   temp = MIB_get_ifIndex(ihandle);
   MIB_find_ifEntry(RTCSMIB_OP_GET, &temp, &instance);

   { /* Scope */
      int_32   sinteger = 0;
      uint_32  uinteger = 0;
#if SNMPCFG_HAVE_INT64
      int_64   sinteger64 = 0;
      uint_64  uinteger64 = 0;
#endif

    switch (mib_val->TYPE) {
    case RTCSMIB_NODETYPE_INT_CONST:
        sinteger = (int_32)(mib_val->PARAM); 
        break;    
    case RTCSMIB_NODETYPE_INT_PTR:       
        sinteger = *(int_32 *)(mib_val->PARAM); 
        break;
    case RTCSMIB_NODETYPE_INT_FN:       
        sinteger = ((RTCSMIB_INT_FN_PTR)mib_val->PARAM)(instance);
        break;
    case RTCSMIB_NODETYPE_UINT_CONST:
        uinteger = (uint_32)(mib_val->PARAM);
        break;
    case RTCSMIB_NODETYPE_UINT_PTR:   
        uinteger = *(uint_32 *)(mib_val->PARAM);
        break;
    case RTCSMIB_NODETYPE_UINT_FN:      
        uinteger = ((RTCSMIB_UINT_FN_PTR)mib_val->PARAM)(instance);
        break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:  sinteger64 = node->GET.INT64_CONST; break;
      case RTCSMIB_NODETYPE_INT64_PTR:    sinteger64 = *node->GET.INT64_PTR; break;
      case RTCSMIB_NODETYPE_INT64_FN:     sinteger64 = node->GET.INT64_FN(instance); break;
      case RTCSMIB_NODETYPE_UINT64_CONST: uinteger64 = node->GET.UINT64_CONST; break;
      case RTCSMIB_NODETYPE_UINT64_PTR:   uinteger64 = *node->GET.UINT64_PTR; break;
      case RTCSMIB_NODETYPE_UINT64_FN:    uinteger64 = node->GET.UINT64_FN(instance); break;
#endif
      } /* Endswitch */

      switch (mib_val->TYPE) {
      case RTCSMIB_NODETYPE_INT_CONST:
      case RTCSMIB_NODETYPE_INT_PTR:
      case RTCSMIB_NODETYPE_INT_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger);
         break;
      case RTCSMIB_NODETYPE_UINT_CONST:
      case RTCSMIB_NODETYPE_UINT_PTR:
      case RTCSMIB_NODETYPE_UINT_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger);
         break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:
      case RTCSMIB_NODETYPE_INT64_PTR:
      case RTCSMIB_NODETYPE_INT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger64);
         break;
      case RTCSMIB_NODETYPE_UINT64_CONST:
      case RTCSMIB_NODETYPE_UINT64_PTR:
      case RTCSMIB_NODETYPE_UINT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger64);
         break;
#endif
      } /* Endswitch */
   } /* Endscope */

   oidlen = 0;

   { /* Scope */
      struct {
         uint_32 ifIndex;
      } _PTR_ index = (pointer)&temp;//index_ifIndex;
      ASN1_BKWRITE_ID(&snmp, oidlen, index->ifIndex);
   } /* Endscope */
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, traplen, ASN1_TYPE_TimeTicks, i);
   /* specific-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 2);
   /* generic-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 6);
   /* skip agent-addr */
   traplen     += 4;
   snmp.outlen -= 4;
   snmp.outbuf -= 4;
   ipsrcp = snmp.outbuf;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_IpAddress, 4);

   /* enterprise */
   node = &MIBNODE_snmpTrapEnterprise;
   oidlen = 0;
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen;

   /* complete Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAP, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 0=v1 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i=0; i<SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         ipaddr = snmpcfg->trap_receiver_list[i];
         ipsrc = IP_route_find(ipaddr, 0);
         htonl(ipsrcp, ipsrc);
         addr.sin_addr.s_addr = ipaddr;
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMP_trap_linkUp
   (
      pointer ihandle
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   pointer           instance;
   uint_32           i, temp;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc, ipaddr;
   sockaddr_in       addr;
   RTCSMIB_VALUE_PTR mib_val;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for ifIndex */
   varlen = 0;
   node = &MIBNODE_ifIndex;
   mib_val = (pointer)node->GET;
   temp = MIB_get_ifIndex(ihandle);
   MIB_find_ifEntry(RTCSMIB_OP_GET, &temp, &instance);

   { /* Scope */
      int_32   sinteger = 0;
      uint_32  uinteger = 0;
#if SNMPCFG_HAVE_INT64
      int_64   sinteger64 = 0;
      uint_64  uinteger64 = 0;
#endif

    switch (mib_val->TYPE) {
    case RTCSMIB_NODETYPE_INT_CONST:
        sinteger = (int_32)(mib_val->TYPE); 
        break;
    case RTCSMIB_NODETYPE_INT_PTR:    
        sinteger = *(int_32 *)(mib_val->TYPE); 
        break;
    case RTCSMIB_NODETYPE_INT_FN: 
        sinteger = ((RTCSMIB_INT_FN_PTR)mib_val->PARAM)(instance);      
        break;
    case RTCSMIB_NODETYPE_UINT_CONST:
        uinteger = (uint_32)(mib_val->TYPE); 
        break; 
    case RTCSMIB_NODETYPE_UINT_PTR:  
        uinteger = *(uint_32 *)(mib_val->TYPE); 
        break;
    case RTCSMIB_NODETYPE_UINT_FN: 
        uinteger = ((RTCSMIB_UINT_FN_PTR)mib_val->PARAM)(instance);    
        break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:  sinteger64 = node->GET.INT64_CONST; break;
      case RTCSMIB_NODETYPE_INT64_PTR:    sinteger64 = *node->GET.INT64_PTR; break;
      case RTCSMIB_NODETYPE_INT64_FN:     sinteger64 = node->GET.INT64_FN(instance); break;
      case RTCSMIB_NODETYPE_UINT64_CONST: uinteger64 = node->GET.UINT64_CONST; break;
      case RTCSMIB_NODETYPE_UINT64_PTR:   uinteger64 = *node->GET.UINT64_PTR; break;
      case RTCSMIB_NODETYPE_UINT64_FN:    uinteger64 = node->GET.UINT64_FN(instance); break;
#endif
      } /* Endswitch */

      switch (mib_val->TYPE) {
      case RTCSMIB_NODETYPE_INT_CONST:
      case RTCSMIB_NODETYPE_INT_PTR:
      case RTCSMIB_NODETYPE_INT_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger);
         break;
      case RTCSMIB_NODETYPE_UINT_CONST:
      case RTCSMIB_NODETYPE_UINT_PTR:
      case RTCSMIB_NODETYPE_UINT_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger);
         break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:
      case RTCSMIB_NODETYPE_INT64_PTR:
      case RTCSMIB_NODETYPE_INT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger64);
         break;
      case RTCSMIB_NODETYPE_UINT64_CONST:
      case RTCSMIB_NODETYPE_UINT64_PTR:
      case RTCSMIB_NODETYPE_UINT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger64);
         break;
#endif
      } /* Endswitch */
   } /* Endscope */

   oidlen = 0;

   { /* Scope */
      struct {
         uint_32 ifIndex;
      } _PTR_ index = (pointer)&temp;//index_ifIndex;
      ASN1_BKWRITE_ID(&snmp, oidlen, index->ifIndex);
   } /* Endscope */
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, traplen, ASN1_TYPE_TimeTicks, i);
   /* specific-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* generic-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 3);
   /* skip agent-addr */
   traplen     += 4;
   snmp.outlen -= 4;
   snmp.outbuf -= 4;
   ipsrcp = snmp.outbuf;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_IpAddress, 4);

   /* enterprise */
   node = &MIBNODE_snmp;
   oidlen = 0;
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen;

   /* complete Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAP, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 0=v1 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i=0; i<SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         ipaddr = snmpcfg->trap_receiver_list[i];
         ipsrc = IP_route_find(ipaddr, 0);
         htonl(ipsrcp, ipsrc);
         addr.sin_addr.s_addr = ipaddr;
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */

void SNMPv2_trap_warmStart
   (
      void
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   //pointer           instance;
   uint_32           i;
   sockaddr_in       addr;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for snmpTrapOID */

   varlen = 0;
   node = &MIBNODE_snmpTraps;
   ASN1_BKWRITE_ID(&snmp, varlen, 2);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, varlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, varlen, ASN1_TYPE_OBJECT, varlen);

   oidlen = 0;
   node = &MIBNODE_snmpTrapOID;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* VarBind for sysUpTime */

   varlen = 0;
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_TimeTicks, i);

   oidlen = 0;
   node = &MIBNODE_sysUpTime;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* error-index */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* error-status */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* request-id */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);

   /* complete SNMPv2-Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAPV2, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 1=v2 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 1);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         addr.sin_addr.s_addr = snmpcfg->trap_receiver_list[i];
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMPv2_trap_coldStart
   (
      void
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   //pointer           instance;
   uint_32           i;
   sockaddr_in       addr;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for snmpTrapOID */

   varlen = 0;
   node = &MIBNODE_snmpTraps;
   ASN1_BKWRITE_ID(&snmp, varlen, 1);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, varlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, varlen, ASN1_TYPE_OBJECT, varlen);

   oidlen = 0;
   node = &MIBNODE_snmpTrapOID;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* VarBind for sysUpTime */

   varlen = 0;
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_TimeTicks, i);

   oidlen = 0;
   node = &MIBNODE_sysUpTime;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* error-index */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* error-status */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* request-id */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);

   /* complete SNMPv2-Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAPV2, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 1=v2 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 1);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         addr.sin_addr.s_addr = snmpcfg->trap_receiver_list[i];
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMPv2_trap_authenticationFailure
   (
      void
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   //pointer           instance;
   uint_32           i;
   sockaddr_in       addr;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for snmpTrapOID */

   varlen = 0;
   node = &MIBNODE_snmpTraps;
   ASN1_BKWRITE_ID(&snmp, varlen, 5);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, varlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, varlen, ASN1_TYPE_OBJECT, varlen);

   oidlen = 0;
   node = &MIBNODE_snmpTrapOID;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* VarBind for sysUpTime */

   varlen = 0;
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_TimeTicks, i);

   oidlen = 0;
   node = &MIBNODE_sysUpTime;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* error-index */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* error-status */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* request-id */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);

   /* complete SNMPv2-Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAPV2, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 1=v2 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 1);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         addr.sin_addr.s_addr = snmpcfg->trap_receiver_list[i];
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMPv2_trap_linkDown
   (
      pointer ihandle
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   pointer           instance;
   uint_32           i, temp;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc;
   sockaddr_in       addr;
   
   RTCSMIB_VALUE_PTR mib_val;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for snmpTrapOID */
   
   varlen = 0;
   node = &MIBNODE_snmpTraps;
   ASN1_BKWRITE_ID(&snmp, varlen, 3);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, varlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, varlen, ASN1_TYPE_OBJECT, varlen);

   oidlen = 0;
   node = &MIBNODE_snmpTrapOID;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* VarBind for ifIndex */
   
   varlen = 0;
   node = &MIBNODE_ifIndex;
   mib_val = (pointer)node->GET;
   temp = MIB_get_ifIndex(ihandle);
   MIB_find_ifEntry(RTCSMIB_OP_GET, &temp, &instance);

   { /* Scope */
      int_32   sinteger = 0;
      uint_32  uinteger = 0;
#if SNMPCFG_HAVE_INT64
      int_64   sinteger64 = 0;
      uint_64  uinteger64 = 0;
#endif

    switch (mib_val->TYPE) {
    case RTCSMIB_NODETYPE_INT_CONST:
        sinteger = (int_32)(mib_val->TYPE);
        break; 
    case RTCSMIB_NODETYPE_INT_PTR:    
        sinteger = *(int_32 *)(mib_val->TYPE);
        break;
    case RTCSMIB_NODETYPE_INT_FN:       
        sinteger = ((RTCSMIB_INT_FN_PTR)mib_val->PARAM)(instance);  
        break;
    case RTCSMIB_NODETYPE_UINT_CONST:
        uinteger = (uint_32)(mib_val->TYPE);
        break;   
    case RTCSMIB_NODETYPE_UINT_PTR:
        uinteger = *(uint_32 *)(mib_val->TYPE);
        break;
    case RTCSMIB_NODETYPE_UINT_FN:      
        uinteger = ((RTCSMIB_UINT_FN_PTR)mib_val->PARAM)(instance);
        break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:  sinteger64 = node->GET.INT64_CONST; break;
      case RTCSMIB_NODETYPE_INT64_PTR:    sinteger64 = *node->GET.INT64_PTR; break;
      case RTCSMIB_NODETYPE_INT64_FN:     sinteger64 = node->GET.INT64_FN(instance); break;
      case RTCSMIB_NODETYPE_UINT64_CONST: uinteger64 = node->GET.UINT64_CONST; break;
      case RTCSMIB_NODETYPE_UINT64_PTR:   uinteger64 = *node->GET.UINT64_PTR; break;
      case RTCSMIB_NODETYPE_UINT64_FN:    uinteger64 = node->GET.UINT64_FN(instance); break;
#endif
      } /* Endswitch */

      switch (mib_val->TYPE) {
      case RTCSMIB_NODETYPE_INT_CONST:
      case RTCSMIB_NODETYPE_INT_PTR:
      case RTCSMIB_NODETYPE_INT_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger);
         break;
      case RTCSMIB_NODETYPE_UINT_CONST:
      case RTCSMIB_NODETYPE_UINT_PTR:
      case RTCSMIB_NODETYPE_UINT_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger);
         break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:
      case RTCSMIB_NODETYPE_INT64_PTR:
      case RTCSMIB_NODETYPE_INT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger64);
         break;
      case RTCSMIB_NODETYPE_UINT64_CONST:
      case RTCSMIB_NODETYPE_UINT64_PTR:
      case RTCSMIB_NODETYPE_UINT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger64);
         break;
#endif
      } /* Endswitch */
   } /* Endscope */

   oidlen = 0;

   { /* Scope */
      struct {
         uint_32 ifIndex;
      } _PTR_ index = (pointer)&temp;
      ASN1_BKWRITE_ID(&snmp, oidlen, index->ifIndex);
   } /* Endscope */
   
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   varlen = 0;
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_TimeTicks, i);
   
   oidlen = 0;
   node = &MIBNODE_sysUpTime;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   /* error-index */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* error-status */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* request-id */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);

   /* complete SANMPv2-Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAPV2, traplen);

   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 1=v2 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 1);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i=0; i<SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         addr.sin_addr.s_addr = snmpcfg->trap_receiver_list[i];
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMPv2_trap_linkUp
   (
      pointer   ihandle
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   pointer           instance;
   uint_32           i, temp;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc, ipaddr;
   sockaddr_in       addr;

   RTCSMIB_VALUE_PTR mib_val;
    
   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for snmpTrapOID */

   varlen = 0;
   node = &MIBNODE_snmpTraps;
   ASN1_BKWRITE_ID(&snmp, varlen, 4);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, varlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, varlen, ASN1_TYPE_OBJECT, varlen);

   oidlen = 0;
   node = &MIBNODE_snmpTrapOID;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* VarBind for ifIndex */
   varlen = 0;
   node = &MIBNODE_ifIndex;
   mib_val = (pointer)node->GET;
   temp = MIB_get_ifIndex(ihandle);
   MIB_find_ifEntry(RTCSMIB_OP_GET, &temp, &instance);

   { /* Scope */
      int_32   sinteger = 0;
      uint_32  uinteger = 0;
#if SNMPCFG_HAVE_INT64
      int_64   sinteger64 = 0;
      uint_64  uinteger64 = 0;
#endif

    switch (mib_val->TYPE) {
    case RTCSMIB_NODETYPE_INT_CONST:
        sinteger = (int_32)(mib_val->PARAM);
        break;
    case RTCSMIB_NODETYPE_INT_PTR:    
        sinteger = *(int_32 *)(mib_val->PARAM);
        break;
    case RTCSMIB_NODETYPE_INT_FN:       
        sinteger = ((RTCSMIB_INT_FN_PTR)mib_val->PARAM)(instance);  
        break;
    case RTCSMIB_NODETYPE_UINT_CONST:
        uinteger = (uint_32)(mib_val->PARAM);
        break; 
    case RTCSMIB_NODETYPE_UINT_PTR:  
        uinteger = *(uint_32 *)(mib_val->PARAM);
        break;
    case RTCSMIB_NODETYPE_UINT_FN:      
        uinteger = ((RTCSMIB_UINT_FN_PTR)mib_val->PARAM)(instance);
        break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:  sinteger64 = node->GET.INT64_CONST; break;
      case RTCSMIB_NODETYPE_INT64_PTR:    sinteger64 = *node->GET.INT64_PTR; break;
      case RTCSMIB_NODETYPE_INT64_FN:     sinteger64 = node->GET.INT64_FN(instance); break;
      case RTCSMIB_NODETYPE_UINT64_CONST: uinteger64 = node->GET.UINT64_CONST; break;
      case RTCSMIB_NODETYPE_UINT64_PTR:   uinteger64 = *node->GET.UINT64_PTR; break;
      case RTCSMIB_NODETYPE_UINT64_FN:    uinteger64 = node->GET.UINT64_FN(instance); break;
#endif
      } /* Endswitch */

      switch (mib_val->TYPE) {
      case RTCSMIB_NODETYPE_INT_CONST:
      case RTCSMIB_NODETYPE_INT_PTR:
      case RTCSMIB_NODETYPE_INT_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger);
         break;
      case RTCSMIB_NODETYPE_UINT_CONST:
      case RTCSMIB_NODETYPE_UINT_PTR:
      case RTCSMIB_NODETYPE_UINT_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger);
         break;
#if SNMPCFG_HAVE_INT64
      case RTCSMIB_NODETYPE_INT64_CONST:
      case RTCSMIB_NODETYPE_INT64_PTR:
      case RTCSMIB_NODETYPE_INT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGINT(&snmp, varlen, node->ASN1_TYPE, sinteger64);
         break;
      case RTCSMIB_NODETYPE_UINT64_CONST:
      case RTCSMIB_NODETYPE_UINT64_PTR:
      case RTCSMIB_NODETYPE_UINT64_FN:
         ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, node->ASN1_TYPE, uinteger64);
         break;
#endif
      } /* Endswitch */
   } /* Endscope */

   oidlen = 0;
   
   { /* Scope */
      struct {
         uint_32 ifIndex;
      } _PTR_ index = (pointer)&temp;
      ASN1_BKWRITE_ID(&snmp, oidlen, index->ifIndex);
   } /* Endscope */
   
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   
   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   varlen = 0;
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_TimeTicks, i);

   oidlen = 0;
   node = &MIBNODE_sysUpTime;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while(node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   
   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   
   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   
   /* error-index */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);

   /* error-status */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   
   /* request-id */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);

   /* complete SNMPv2_Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAPV2, traplen);
   
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 1=v2 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 1);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i=0; i<SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         addr.sin_addr.s_addr = snmpcfg->trap_receiver_list[i];
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */


void SNMPv2_trap_userSpec
   (
      RTCSMIB_NODE_PTR trap_node
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   pointer           instance;
   uint_32           uinteger;
   int_32            sinteger, i;
   sockaddr_in       addr;

   RTCSMIB_VALUE_PTR mib_val;

   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;
      
   traplen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* VarBind for snmpTrapOID */
    varlen = 0;
    mib_val = (pointer)trap_node->GET;

    switch (mib_val->TYPE) {
        case RTCSMIB_NODETYPE_INT_CONST:
            sinteger = (int_32)(mib_val->PARAM);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, sinteger);
            break;
        case RTCSMIB_NODETYPE_INT_PTR:
            sinteger = *(int_32 *)(mib_val->PARAM);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, sinteger);
            break;
        case RTCSMIB_NODETYPE_INT_FN:
            sinteger = ((RTCSMIB_INT_FN_PTR)mib_val->PARAM)(NULL);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, sinteger)
            break;
        case RTCSMIB_NODETYPE_UINT_CONST:
            uinteger = (uint_32)(mib_val->PARAM);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, uinteger);
            break;
        case RTCSMIB_NODETYPE_UINT_PTR:
            uinteger = *(uint_32 *)(mib_val->PARAM);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, uinteger);
            break;
        case RTCSMIB_NODETYPE_UINT_FN:
            uinteger = ((RTCSMIB_UINT_FN_PTR)mib_val->PARAM)(NULL);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, uinteger);
            break;
        case RTCSMIB_NODETYPE_DISPSTR_PTR:
            ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                mib_val->PARAM, strlen(mib_val->PARAM));
            break;
        case RTCSMIB_NODETYPE_DISPSTR_FN:
            ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                ((RTCSMIB_DISPSTR_FN_PTR)mib_val->PARAM)(NULL),
                strlen( (const char *)((RTCSMIB_DISPSTR_FN_PTR)mib_val->PARAM)(NULL) ) ) ;
            break;                      
        default:
            ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                "Not supported", 13 ) ;
            break;
    } 
   
   oidlen = 0;
   node = trap_node;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   /* VarBind for snmpTrapOID2 */

   varlen = 0;
   node = &MIBNODE_snmpTraps;
   ASN1_BKWRITE_ID(&snmp, varlen, 6);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, varlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, varlen, ASN1_TYPE_OBJECT, varlen);

   oidlen = 0;
   node = &MIBNODE_snmpTrapOID;
   ASN1_BKWRITE_ID(&snmp, oidlen, 1);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* VarBind for sysUpTime */

   varlen = 0;
   sinteger = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_TimeTicks, sinteger);

   oidlen = 0;
   node = &MIBNODE_sysUpTime;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);

   traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, oidlen+varlen);

   /* complete variable-bindings */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   /* error-index */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* error-status */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* request-id */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);

   /* complete SNMPv2-Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAPV2, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 1=v2 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 1);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         addr.sin_addr.s_addr = snmpcfg->trap_receiver_list[i];
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */

void SNMP_trap_userSpec
   (
      RTCSMIB_NODE_PTR trap_node, uint_32 spec_trap, RTCSMIB_NODE_PTR enterprises
   )
{ /* Body */
   SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   uint_32           traplen, oidlen, varlen;
   RTCSMIB_NODE_PTR  node;
   uint_32           i;
   uchar_ptr         ipsrcp;
   _ip_address       ipsrc, ipaddr;
   sockaddr_in       addr;
      uint_32        uinteger;
   int_32            sinteger;
   
   RTCSMIB_VALUE_PTR mib_val;
   
   uchar outbuf[SNMPCFG_BUFFER_SIZE];
   struct {
      uint_32     outlen;
      uchar_ptr   outbuf;
   } snmp;

   traplen = 0;
   oidlen = 0;
   snmp.outlen = sizeof(outbuf);
   snmp.outbuf = outbuf + sizeof(outbuf);

   /* complete variable-bindings */
    varlen  = 0;
    mib_val = (pointer)trap_node->GET;

    switch (mib_val->TYPE) {
        case RTCSMIB_NODETYPE_INT_CONST:
            sinteger = (int_32)(mib_val->PARAM);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, sinteger);
            break;
        case RTCSMIB_NODETYPE_INT_PTR:
            sinteger = *(int_32 *)(mib_val->PARAM);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, sinteger);
            break;
        case RTCSMIB_NODETYPE_INT_FN:
            sinteger = ((RTCSMIB_INT_FN_PTR)mib_val->PARAM)(NULL);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, sinteger)
            break;
        case RTCSMIB_NODETYPE_UINT_CONST:
            uinteger = (uint_32)(mib_val->PARAM);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, uinteger);
            break;
        case RTCSMIB_NODETYPE_UINT_PTR:
            uinteger = *(uint_32 *)(mib_val->PARAM);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, uinteger);
            break;
        case RTCSMIB_NODETYPE_UINT_FN:
            uinteger = ((RTCSMIB_UINT_FN_PTR)mib_val->PARAM)(NULL);
            ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, varlen, ASN1_TYPE_INTEGER, uinteger);
            break;
        case RTCSMIB_NODETYPE_DISPSTR_PTR:
            ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                mib_val->PARAM, strlen(mib_val->PARAM));
            break;
        case RTCSMIB_NODETYPE_DISPSTR_FN:
            ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                ((RTCSMIB_DISPSTR_FN_PTR)mib_val->PARAM)(NULL),
                strlen( (const char *)((RTCSMIB_DISPSTR_FN_PTR)mib_val->PARAM)(NULL) ) ) ;
            break;                      
        default:
            ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                "Not supported", 13 ) ;
            break;
    } 

   oidlen = 0;
   node = trap_node;
   ASN1_BKWRITE_ID(&snmp, oidlen, 0);
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } 
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
    
    traplen += oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);   
   /* variable-bindings items */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);
   
   /* time-stamp */
   i = MIB_get_sysUpTime(NULL);
   ASN1_BKWRITE_TYPELEN_BIGUINT(&snmp, traplen, ASN1_TYPE_TimeTicks, i);
   /* specific-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, spec_trap);
   /* generic-trap */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 6);
   /* skip agent-addr */
   traplen     += 4;
   snmp.outlen -= 4;
   snmp.outbuf -= 4;
   ipsrcp = snmp.outbuf;
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_IpAddress, 4);

   /* enterprise */
   node = enterprises;
   oidlen = 0;
   while (node) {
      ASN1_BKWRITE_ID(&snmp, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(&snmp, oidlen, ASN1_TYPE_OBJECT, oidlen);
   traplen += oidlen;

   /* complete Trap-PDU */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_PDU_TRAP, traplen);
   /* community */
   ASN1_BKWRITE_TYPELEN_BYTES(&snmp, traplen, ASN1_TYPE_OCTET, 
                              snmpcfg->community[snmpcfg->currentcommunity], 
                              snmpcfg->communitylen[snmpcfg->currentcommunity]);   
   /* version, 0=v1 */
   ASN1_BKWRITE_TYPELEN_INT(&snmp, traplen, 0);
   /* complete Message */
   ASN1_BKWRITE_TYPELEN(&snmp, traplen, ASN1_TYPE_SEQUENCE, traplen);

   addr.sin_family = AF_INET;
   addr.sin_port   = IPPORT_SNMPTRAP;
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] != 0) {
         ipaddr = snmpcfg->trap_receiver_list[i];
         ipsrc = IP_route_find(ipaddr, 0);
         htonl(ipsrcp, ipsrc);
         addr.sin_addr.s_addr = ipaddr;
         sendto(snmpcfg->trapsock, snmp.outbuf, traplen, 0, &addr, sizeof(addr));
      } /* Endif */
   } /* Endfor */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4 */
 
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enclose.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enclose.c$
* $Version : 3.5.7.0$
* $Date    : Nov-24-2009$
*
* Comments:
*
*   This file contains the Ethernet close
*   interface function.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_close
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Unregisters a protocol type on an Ethernet channel.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_close
   (
      /* [IN] the Ethernet state structure */
      _enet_handle      handle,

      /* [IN] the protocol */
      uint_16           type
   )
{ 
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;
   ENET_ECB_STRUCT_PTR     ecb_ptr, _PTR_ search_ptr;
   ENET_MCB_STRUCT_PTR     mcb_ptr, next_ptr;

   #if BSPCFG_ENABLE_ENET_MULTICAST
      #ifdef ENET_ALLMCAST
            uint_32        mcount;
            boolean        needrejoin;
      #endif
   #endif

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself, ENET_open(), ENET_join(), ENET_leave(),
   ** and ENET_ISR().
   */
   ENET_lock_context(enet_ptr);

   // Search for an existing entry for type
   for (search_ptr = (ENET_ECB_STRUCT_PTR _PTR_)&enet_ptr->ECB_HEAD;
       *search_ptr; search_ptr = &(*search_ptr)->NEXT) 
   {

      if ((*search_ptr)->TYPE == type) {
         // Found an existing entry -- delete it
         break;
      }  
   } 

   if (!*search_ptr) {
      // No existing entry found
      ENET_unlock_context(enet_ptr);
      return ENETERR_CLOSE_PROT;
   } 

   ecb_ptr = *search_ptr;
   *search_ptr = ecb_ptr->NEXT;

   #if BSPCFG_ENABLE_ENET_MULTICAST
      #ifdef ENET_ALLMCAST
         mcb_ptr = ecb_ptr->MCB_HEAD;
         mcount = 0;
         while (mcb_ptr) {
            mcount++;
            mcb_ptr = mcb_ptr->NEXT;
         } 
         enet_ptr->MCOUNT -= mcount;
         needrejoin = mcount && (enet_ptr->MCOUNT < ENET_ALLMCAST);
      #endif
   #endif

   ENET_unlock_context(enet_ptr);

   mcb_ptr = ecb_ptr->MCB_HEAD;
   _mem_free(ecb_ptr);
   while (mcb_ptr) {
      next_ptr = mcb_ptr->NEXT;
      _mem_free(mcb_ptr);
      mcb_ptr = next_ptr;
   } 

   #if BSPCFG_ENABLE_ENET_MULTICAST
      #ifdef ENET_ALLMCAST
         if (needrejoin) {
      #endif
            ENET_lock_context(enet_ptr);
            (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->REJOIN)(handle);
            ENET_unlock_context(enet_ptr);
      #ifdef ENET_ALLMCAST
         }
      #endif
   #endif

   return ENET_OK;

}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/ehci/ehci.h<|end_filename|>
#ifndef __ehci_h__
#define __ehci_h__ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci.h$
* $Version : 3.8.15.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the defines, externs and
*   data structure definitions required by the VUSB_HS Device
*   driver.
*
*END************************************************************************/
#include <psp.h> //for _PSP_SYNC()
#include <bsp.h> //for endianess specification

#include "ehci_cache.h"

#if (MQX_USE_UNCACHED_MEM == 0) && PSP_CPU_HAS_DATA_CACHE
#   error Cannot compile EHCI driver when PSP does not support uncached memory.
#endif

/* VUSBHS specific defines */
#define  VUSBHS_MAX_PORTS                          (8)
#define  EHCI_CAP_LEN_MASK                         (0x000000FF)
#define  EHCI_DATA_STRUCTURE_BASE_ADDRESS          (0)

/* Command Register Bit Masks */
#define  EHCI_CMD_RUN_STOP                         (0x00000001)
#define  EHCI_CMD_CTRL_RESET                       (0x00000002)
#define  EHCI_CMD_SETUP_TRIPWIRE_SET               (0x00002000)
#define  EHCI_CMD_SETUP_TRIPWIRE_CLEAR             ~EHCI_CMD_SETUP_TRIPWIRE_SET

#define  EHCI_CMD_ATDTW_TRIPWIRE_SET               (0x00001000)
#define  EHCI_CMD_ATDTW_TRIPWIRE_CLEAR             ~EHCI_CMD_SETUP_TRIPWIRE_CLEAR

  /*bit 15,3,2 are for frame list size */
  #define  EHCI_CMD_FRAME_SIZE_1024                  (0x00000000) /* 000 */
  #define  EHCI_CMD_FRAME_SIZE_512                   (0x00000004) /* 001 */
  #define  EHCI_CMD_FRAME_SIZE_256                   (0x00000008) /* 010 */
  #define  EHCI_CMD_FRAME_SIZE_128                   (0x0000000C) /* 011 */
  #define  EHCI_CMD_FRAME_SIZE_64                    (0x00008000) /* 100 */
  #define  EHCI_CMD_FRAME_SIZE_32                    (0x00008004) /* 101 */
  #define  EHCI_CMD_FRAME_SIZE_16                    (0x00008008) /* 110 */
  #define  EHCI_CMD_FRAME_SIZE_8                     (0x0000800C) /* 111 */

                                             
/* Mode Register Bit Masks */
#define  VUSBHS_MODE_CTRL_MODE_IDLE                (0x00000000)
#define  VUSBHS_MODE_CTRL_MODE_DEV                 (0x00000002)
#define  VUSBHS_MODE_CTRL_MODE_HOST                (0x00000003)
#define  VUSBHS_MODE_BIG_ENDIAN                    (0x00000004)
#define  VUSBHS_MODE_SETUP_LOCK_DISABLE            (0x00000008)
                                                
/* Interrupt Enable Register Bit Masks */
#define  EHCI_INTR_INT_EN                          (0x00000001)
#define  EHCI_INTR_ERR_INT_EN                      (0x00000002)
#define  EHCI_INTR_PORT_CHANGE_DETECT_EN           (0x00000004)

#define  EHCI_INTR_ASYNC_ADV_AAE                   (0x00000020)
         #define  EHCI_INTR_ASYNC_ADV_AAE_ENABLE   (0x00000020) /* | with this to enable */
         #define  EHCI_INTR_ASYNC_ADV_AAE_DISABLE  (0xFFFFFFDF) /* & with this to disable */

#define  EHCI_INTR_UAI_EN                          (0x00040000)

#define  EHCI_INTR_RESET_EN                        (0x00000040)
#define  EHCI_INTR_SOF_UFRAME_EN                   (0x00000080)
#define  EHCI_INTR_DEVICE_SUSPEND                  (0x00000100)
#define  EHCI_INTR_TIMER0                          (0x01000000)
#define  EHCI_INTR_TIMER1                          (0x02000000)

/* Interrupt Status Register Masks */
#define  EHCI_STS_SOF                              (0x00000080)
#define  EHCI_STS_RESET                            (0x00000040)
#define  EHCI_STS_PORT_CHANGE                      (0x00000004)
#define  EHCI_STS_ERR                              (0x00000002)
#define  EHCI_STS_INT                              (0x00000001)
#define  EHCI_STS_SUSPEND                          (0x00000100)
#define  EHCI_STS_HC_HALTED                        (0x00001000)
#define  EHCI_STS_TIMER0                           (0x01000000)
#define  EHCI_STS_TIMER1                           (0x02000000)

/* Endpoint Queue Head Bit Masks */
#define  VUSB_EP_QUEUE_HEAD_IOS                    (0x00008000)
#define  VUSB_EP_QUEUE_HEAD_IOC                    (0x00008000)
#define  VUSB_EP_QUEUE_HEAD_INT                    (0x00000100)
#define  VUSB_EP_QUEUE_HEAD_NEXT_TERMINATE         (0x00000001)
#define  VUSB_EP_QUEUE_HEAD_MAX_PKT_LEN_POS        (16)
#define  VUSB_EP_QUEUE_HEAD_ZERO_LEN_TER_SEL       (0x20000000)
#define  VUSB_EP_QUEUE_HEAD_MULT_POS               (30)
#define  VUSB_EP_MAX_LENGTH_TRANSFER               (0x4000)

#define  VUSB_EP_QUEUE_HEAD_STATUS_ACTIVE          (0x00000080)

#define  VUSBHS_TD_NEXT_TERMINATE                  (0x00000001)
#define  VUSBHS_TD_IOC                             (0x00008000)
#define  VUSBHS_TD_STATUS_ACTIVE                   (0x00000080)
#define  VUSBHS_TD_STATUS_HALTED                   (0x00000040)
#define  VUSBHS_TD_RESERVED_FIELDS                 (0x00007F00)
#define  VUSBHS_TD_ERROR_MASK                      (0x68)
#define  VUSBHS_TD_ADDR_MASK                       (0xFFFFFFE0)
#define  VUSBHS_TD_LENGTH_BIT_POS                  (16)

#define  EHCI_EPCTRL_TX_DATA_TOGGLE_RST            (0x00400000)
#define  EHCI_EPCTRL_TX_EP_STALL                   (0x00010000)
#define  EHCI_EPCTRL_RX_EP_STALL                   (0x00000001)
#define  EHCI_EPCTRL_RX_DATA_TOGGLE_RST            (0x00000040)
#define  EHCI_EPCTRL_RX_ENABLE                     (0x00000080)
#define  EHCI_EPCTRL_TX_ENABLE                     (0x00800000)
#define  EHCI_EPCTRL_CONTROL                       (0x00000000)
#define  EHCI_EPCTRL_ISOCHRONOUS                   (0x00040000)
#define  EHCI_EPCTRL_BULK                          (0x00080000)
#define  EHCI_EPCTRL_INT                           (0x000C0000)
#define  EHCI_EPCTRL_TX_TYPE                       (0x000C0000)
#define  EHCI_EPCTRL_RX_TYPE                       (0x0000000C)
#define  EHCI_EPCTRL_DATA_TOGGLE_INHIBIT           (0x00000020)
#define  EHCI_EPCTRL_TX_EP_TYPE_SHIFT              (18)
#define  EHCI_EPCTRL_RX_EP_TYPE_SHIFT              (2)

#define  EHCI_PORTSCX_PORT_POWER                   (0x00001000)
#define  EHCI_PORTSCX_LINE_STATUS_BITS             (0x00000C00)
#define  EHCI_PORTSCX_LINE_STATUS_SE0              (0x00000000)
#define  EHCI_PORTSCX_LINE_STATUS_KSTATE           (0x00000400)
#define  EHCI_PORTSCX_LINE_STATUS_JSTATE           (0x00000800)
#define  EHCI_PORTSCX_PORT_HIGH_SPEED              (0x00000200)
#define  EHCI_PORTSCX_PORT_RESET                   (0x00000100)
#define  EHCI_PORTSCX_PORT_SUSPEND                 (0x00000080)
#define  EHCI_PORTSCX_PORT_FORCE_RESUME            (0x00000040)
#define  EHCI_PORTSCX_PORT_EN_DIS_CHANGE           (0x00000008)
#define  EHCI_PORTSCX_PORT_ENABLE                  (0x00000004)
#define  EHCI_PORTSCX_CONNECT_STATUS_CHANGE        (0x00000002)
#define  EHCI_PORTSCX_CURRENT_CONNECT_STATUS       (0x00000001)

#define  VUSBHS_PORTSCX_PORT_PFSC                  (0x01000000)

#define  VUSBHS_PORTSCX_PORT_SPEED_FULL            (0x00000000)
#define  VUSBHS_PORTSCX_PORT_SPEED_LOW             (0x04000000)
#define  VUSBHS_PORTSCX_PORT_SPEED_HIGH            (0x08000000)
#define  VUSBHS_SPEED_MASK                         (0x0C000000)
#define  VUSBHS_SPEED_BIT_POS                      (26)

#define  EHCI_PORTSCX_W1C_BITS                     (0x2A)

#define  VUSB_EP_TR_PACKET_SIZE                    (0x7FFF0000)

#define  VUSBHS_FRINDEX_MS_MASK                    (0xFFFFFFF8)
#define  VUSBHS_ADDRESS_BIT_SHIFT                  (25)

#define  VUSB20_MAX_ENDPTS_SUPPORTED               (0x1F)
#define  EHCI_HCC_PARAMS_64_BIT_ADDR_CAP           (0x01)
#define  EHCI_HCC_PARAMS_PGM_FRM_LIST_FLAG         (0x02)
#define  EHCI_HCC_PARAMS_ASYNC_PARK_CAP            (0x04)
#define  EHCI_HCC_PARAMS_ISOCH_SCHED_THRESHOLD     (0xF0)
#define  EHCI_HCC_PARAMS_ISOCH_FRAME_CACHED        (0x80)

#define  VUSB20_HCS_PARAMS_PORT_POWER_CONTROL_FLAG (0x10)

#define  VUSB20_HOST_INTR_EN_BITS                  (0x37)

#define  VUSB20_DEFAULT_PERIODIC_FRAME_LIST_SIZE   (1024)
#define  VUSB20_NEW_PERIODIC_FRAME_LIST_BITS       (2)
#define  EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT     (0x01)
#define  EHCI_ITD_T_BIT                            (0x01)
#define  EHCI_SITD_T_BIT                           (0x01)
#define  EHCI_QUEUE_HEAD_POINTER_T_BIT             (0x01)


/************************************************************
Split transatcions specific defines
************************************************************/
#define  EHCI_START_SPLIT_MAX_BUDGET               188

#define  EHCI_ELEMENT_TYPE_ITD                     (0x00)
#define  EHCI_ELEMENT_TYPE_QH                      (0x02)
#define  EHCI_ELEMENT_TYPE_SITD                    (0x04)
#define  EHCI_ELEMENT_TYPE_FSTN                    (0x06)
#define  EHCI_ELEMENT_TYPE_MASK                    (0x06)

#define  EHCI_FRAME_LIST_ELEMENT_TYPE_ITD          (0x00)
#define  EHCI_FRAME_LIST_ELEMENT_TYPE_QH           (0x01)
#define  EHCI_FRAME_LIST_ELEMENT_TYPE_SITD         (0x02)
#define  EHCI_FRAME_LIST_ELEMENT_TYPE_FSTN         (0x03)
#define  EHCI_FRAME_LIST_ELEMENT_TYPE_BIT_POS      (1)


#define  EHCI_QH_ELEMENT_TYPE_ITD                  (0x00)
#define  EHCI_QH_ELEMENT_TYPE_QH                   (0x01)
#define  EHCI_QH_ELEMENT_TYPE_SITD                 (0x02)
#define  EHCI_QH_ELEMENT_TYPE_FSTN                 (0x03)

#define  EHCI_QH_ELEMENT_TYPE_BIT_POS              (1)

#define  EHCI_QTD_PID_OUT_TOKEN                    (0x000)
#define  EHCI_QTD_PID_IN_TOKEN                     (0x100)
#define  EHCI_QTD_PID_SETUP_TOKEN                  (0x200)
#define  EHCI_QTD_IOC                              (0x8000)
#define  EHCI_QTD_STATUS_ACTIVE                    (0x0080)
#define  EHCI_QTD_STATUS_HALTED                    (0x0040)
#define  EHCI_QTD_PID_SETUP                        (0x0200)
#define  EHCI_QTD_PID_IN                           (0x0100)
#define  EHCI_QTD_PID_OUT                          (0x0000)
#define  EHCI_QTD_LENGTH_BIT_POS                   (16)
#define  EHCI_QTD_DATA_TOGGLE                      (0x80000000)
#define  EHCI_QTD_DATA_TOGGLE_BIT_POS              (31)
#define  EHCI_QTD_LENGTH_BIT_MASK                  (0x7FFF0000)
#define  EHCI_QTD_ERROR_BITS_MASK                  (0x0000003E)
#define  EHCI_QTD_DEFAULT_CERR_VALUE               (0xC00)

#define  EHCI_SETUP_TOKEN                          (2)
#define  EHCI_OUT_TOKEN                            (0)
#define  EHCI_IN_TOKEN                             (1)

#define  EHCI_QTD_T_BIT                            (0x01)

#define  EHCI_QH_ENDPOINT_SPEED_FULL               (0x00)
#define  EHCI_QH_ENDPOINT_SPEED_LOW                (0x01)
#define  EHCI_QH_ENDPOINT_SPEED_HIGH               (0x02)
#define  EHCI_QH_ENDPOINT_SPEED_RESERVED           (0x03)

#define  EHCI_ITD_LENGTH_BIT_POS                   (16)
#define  EHCI_ITD_IOC_BIT                          (0x00008000)
#define  EHCI_ITD_ACTIVE_BIT                       (0x80000000)
#define  EHCI_ITD_PG_SELECT_BIT_POS                (12)
#define  EHCI_ITD_DIRECTION_BIT_POS                (11)
#define  EHCI_ITD_EP_BIT_POS                       (8)
#define  EHCI_ITD_STATUS                           (0xF0000000)
#define  EHCI_ITD_STATUS_ACTIVE                    (0x80000000) /*bit 4 = 1000*/
#define  EHCI_ITD_STATUS_DATA_BUFFER_ERR           (0x40000000) /*bit 3 = 0100*/
#define  EHCI_ITD_STATUS_BABBLE_ERROR              (0x20000000) /*bit 2 = 0010*/
#define  EHCI_ITD_STATUS_TRANSACTION_ERR           (0x10000000) /*bit 4 = 0001*/

#define  EHCI_ITD_LENGTH_TRANSMITTED               (0x0FFF0000)
#define  EHCI_ITD_BUFFER_OFFSET                    (0x00000FFF)
#define  EHCI_ITD_PAGE_NUMBER                      (0x00007000)
#define  EHCI_ITD_BUFFER_POINTER                   (0xFFFFF000)
#define  EHCI_ITD_MULTI_TRANSACTION_BITS           (0x00000003)

          

/* SITD position bits */
#define  EHCI_SITD_DIRECTION_BIT_POS                (31)
#define  EHCI_SITD_PORT_NUMBER_BIT_POS              (24)
#define  EHCI_SITD_HUB_ADDR_BIT_POS                 (16)
#define  EHCI_SITD_EP_ADDR_BIT_POS                  (8)

#define  EHCI_SITD_COMPLETE_SPLIT_MASK_BIT_POS      (8)

#define  EHCI_SITD_IOC_BIT_SET                      (0x80000000)
#define  EHCI_SITD_PAGE_SELECT_BIT_POS              (30)
#define  EHCI_SITD_TRANSFER_LENGTH_BIT_POS          (16)
#define  EHCI_SITD_STATUS_ACTIVE                    (0x80)

#define  EHCI_SITD_STATUS                           (0xFF)
#define  EHCI_SITD_LENGTH_TRANSMITTED               (0x03FF0000)
#define  EHCI_SITD_BUFFER_OFFSET                    (0x00000FFF)
#define  EHCI_SITD_PAGE_NUMBER                      (0x40000000)
#define  EHCI_SITD_BUFFER_POINTER                   (0xFFFFF000)



#define  EHCI_SITD_BUFFER_PTR_BIT_POS                 (12)
#define  EHCI_SITD_TP_BIT_POS                         (3)
#define  EHCI_SITD_TP_ALL                             (0)
#define  EHCI_SITD_TP_BEGIN                           (1)
#define  EHCI_SITD_TP_MID                             (2)
#define  EHCI_SITD_TP_END                             (3)



/* Interrupt enable bit masks */
#define  EHCI_IER_ASYNCH_ADVANCE                   (0x00000020)
#define  EHCI_IER_HOST_SYS_ERROR                   (0x00000010)
#define  EHCI_IER_FRAME_LIST_ROLLOVER              (0x00000008)
#define  EHCI_IER_PORT_CHANGE                      (0x00000004)
#define  EHCI_IER_USB_ERROR                        (0x00000002)
#define  EHCI_IER_USB_INTERRUPT                    (0x00000001)

/* Interrupt status bit masks */
#define  EHCI_STS_NAK                              (0x00010000)
#define  EHCI_STS_RECLAIMATION                     (0x00002000)
#define  EHCI_STS_SOF_COUNT                        (0x00000080)
#define  EHCI_STS_ASYNCH_ADVANCE                   (0x00000020)
#define  EHCI_STS_HOST_SYS_ERROR                   (0x00000010)
#define  EHCI_STS_FRAME_LIST_ROLLOVER              (0x00000008)
#define  EHCI_STS_PORT_CHANGE                      (0x00000004)
#define  EHCI_STS_USB_ERROR                        (0x00000002)
#define  EHCI_STS_USB_INTERRUPT                    (0x00000001)

/* Status bit masks */
#define  EHCI_STS_ASYNCH_SCHEDULE                  (0x00008000)
#define  EHCI_STS_PERIODIC_SCHEDULE                (0x00004000)
#define  EHCI_STS_RECLAMATION                      (0x00002000)
#define  EHCI_STS_HC_HALTED                        (0x00001000)

/* USB command bit masks */
#define  EHCI_USBCMD_ASYNC_SCHED_ENABLE            (0x00000020)
#define  EHCI_USBCMD_PERIODIC_SCHED_ENABLE         (0x00000010)

#define  EHCI_HCS_PARAMS_N_PORTS                   (0x0F)

#define  VUSB_HS_DELAY                             (3500)

#define  EHCI_QH_EP_NUM_MASK                       (0x0F00)
#define  EHCI_QH_EP_NUM_BITS_POS                   (8)
#define  EHCI_QH_DEVICE_ADDRESS_MASK               (0x7F)
#define  EHCI_QH_SPEED_BITS_POS                    (12)
#define  EHCI_QH_MAX_PKT_SIZE_BITS_POS             (16)
#define  EHCI_QH_NAK_COUNT_RL_BITS_POS             (28)
#define  EHCI_QH_EP_CTRL_FLAG_BIT_POS              (27)
#define  EHCI_QH_HEAD_RECLAMATION_BIT_POS          (15)
#define  EHCI_QH_DTC_BIT_POS                       (14)
#define  EHCI_QH_HIGH_BW_MULT_BIT_POS              (30)
#define  EHCI_QH_HUB_PORT_NUM_BITS_POS             (23)
#define  EHCI_QH_HUB_ADDR_BITS_POS                 (16)
#define  EHCI_QH_SPLIT_COMPLETION_MASK_BITS_POS    (8)
#define  EHCI_QH_SPLIT_COMPLETION_MASK             (0xFF00)
#define  EHCI_QH_INTR_SCHED_MASK                   (0xFF)
#define  EHCI_QH_INACTIVATE_NEXT_TR_BIT_POS        (7)
#define  EHCI_QH_HORIZ_PHY_ADDRESS_MASK            (0xFFFFFFE0)
#define  EHCI_QH_TR_OVERLAY_DT_BIT                 (0x80000000)

#define  EHCI_SITD_SPLIT_COMPLETION_MASK_BITS_POS  (8)

#define  EHCI_INTR_NO_THRESHOLD_IMMEDIATE          (0x00010000)
#define  EHCI_NEW_PERIODIC_FRAME_LIST_SIZE         (1024)
#define  EHCI_FRAME_LIST_SIZE_BITS_POS             (2)
#define  EHCI_HORIZ_PHY_ADDRESS_MASK               (0xFFFFFFE0)

#define  EHCIFSL_GTCTL_GPTIMER_REPEAT              (0x01000000)
#define  EHCIFSL_GTCTL_GPTIMER_RESET               (0x40000000)
#define  EHCIFSL_GTCTL_GPTIMER_RUN                 (0x80000000)

/* OTG Status and control register bit masks */

/* OTG interrupt enable bit masks */
#define  VUSBHS_OTGSC_INTERRUPT_ENABLE_BITS_MASK   (0x5F000000)
#define  VUSBHS_OTGSC_DPIE                         (0x40000000)   /* Data-line pulsing IE */
#define  VUSBHS_OTGSC_1MSIE                        (0x20000000)
#define  VUSBHS_OTGSC_BSEIE                        (0x10000000)   /* B-session end IE */
#define  VUSBHS_OTGSC_BSVIE                        (0x08000000)   /* B-session valid IE */
#define  VUSBHS_OTGSC_ASVIE                        (0x04000000)   /* A-session valid IE */
#define  VUSBHS_OTGSC_AVVIE                        (0x02000000)   /* A-V-bus valid IE */
#define  VUSBHS_OTGSC_IDIE                         (0x01000000)   /* OTG ID IE */

/* OTG interrupt status bit masks */
#define  VUSBHS_OTGSC_INTERRUPT_STATUS_BITS_MASK   (0x005F0000)
#define  VUSBHS_OTGSC_DPIS                         (0x00400000)   /* Data-line pulsing IS */
#define  VUSBHS_OTGSC_1MSIS                        (0x00200000)
#define  VUSBHS_OTGSC_BSEIS                        (0x00100000)   /* B-session end IS */
#define  VUSBHS_OTGSC_BSVIS                        (0x00080000)   /* B-session valid IS */
#define  VUSBHS_OTGSC_ASVIS                        (0x00040000)   /* A-session valid IS */
#define  VUSBHS_OTGSC_AVVIS                        (0x00020000)   /* A-Vbus valid IS */
#define  VUSBHS_OTGSC_IDIS                         (0x00010000)   /* OTG ID IS */

/* OTG status bit masks */
#define  VUSBHS_OTGSC_DPS                          (0x00004000)
#define  VUSBHS_OTGSC_BSE                          (0x00001000)   /* B-session end */
#define  VUSBHS_OTGSC_BSV                          (0x00000800)   /* B-session valid */
#define  VUSBHS_OTGSC_ASV                          (0x00000400)   /* A-session valid */
#define  VUSBHS_OTGSC_AVV                          (0x00000200)   /* A-Vbus Valid */
#define  VUSBHS_OTGSC_ID                           (0x00000100)   /* OTG ID */

/* OTG control bit masks */
#define  VUSBHS_OTGSC_CTL_BITS                     (0x2F)
#define  VUSBHS_OTGSC_B_HOST_EN                    (0x00000020)   /* B_host_enable */
#define  VUSBHS_OTGSC_DP                           (0x00000010)   /* Data-pulsing */
#define  VUSBHS_OTGSC_OT                           (0x00000008)   /* OTG termination */
#define  VUSBHS_OTGSC_VO                           (0x00000004)   /* Vbus on */
#define  VUSBHS_OTGSC_VC                           (0x00000002)   /* Vbus charge */
#define  VUSBHS_OTGSC_VD                           (0x00000001)   /* Vbus discharge */

typedef  uint_32  USB_REGISTER, _PTR_ USB_REGISTER_PTR;


#if USBCFG_REGISTER_ENDIANNESS==MQX_BIG_ENDIAN
   #define ehci_reg_read(r,n)           LONG_BE_TO_HOST((uint_32)r)
   #define ehci_reg_write(r,v,n)       {r=HOST_TO_BE_LONG(v);_PSP_SYNC();}
#else
   #define ehci_reg_read(r,n)           LONG_LE_TO_HOST((uint_32)r)
   #define ehci_reg_write(r,v,n)       {r=HOST_TO_LE_LONG(v);_PSP_SYNC();}
#endif

#if USBCFG_MEMORY_ENDIANNESS==MQX_BIG_ENDIAN
   #define ehci_mem_read(r,n)           LONG_BE_TO_HOST((uint_32)r)
   #define ehci_mem_write(r,v,n)       {r=HOST_TO_BE_LONG(v);_PSP_SYNC();}
#else
   #define ehci_mem_read(r,n)           LONG_LE_TO_HOST((uint_32)r)
   #define ehci_mem_write(r,v,n)       {r=HOST_TO_LE_LONG(v);_PSP_SYNC();}
#endif

#define ehci_reg_clear_bits(r,v,n)  ehci_reg_write(r, ehci_reg_read(r,n) & ~v,n)
#define ehci_reg_set_bits(r,v,n)    ehci_reg_write(r, ehci_reg_read(r,n) | v,n)
#define ehci_mem_clear_bits(r,v,n)  ehci_mem_write(r, ehci_mem_read(r,n) & ~v,n)
#define ehci_mem_set_bits(r,v,n)    ehci_mem_write(r, ehci_mem_read(r,n) | v,n)

#define EHCI_REG_READ(r)            ehci_reg_read(r,#r)
#define EHCI_REG_WRITE(r,v)         ehci_reg_write(r,v,#r)
#define EHCI_REG_CLEAR_BITS(r,v)    ehci_reg_clear_bits(r,v,#r)
#define EHCI_REG_SET_BITS(r,v)      ehci_reg_set_bits(r,v,#r)

#define EHCI_MEM_READ(r)            ehci_mem_read(r,#r)
#define EHCI_MEM_WRITE(r,v)         ehci_mem_write(r,v,#r)
#define EHCI_MEM_CLEAR_BITS(r,v)    ehci_mem_clear_bits(r,v,#r)
#define EHCI_MEM_SET_BITS(r,v)      ehci_mem_set_bits(r,v,#r)

#define  MEM_UNCACHE_INDEX (0)
#define  MEM_CACHE_INDEX   (1)
#define  MEM_SIZE_INDEX    (2)
#define  SITD_ITD_UNCACHE_MEM_HEAD (3)

/* The VUSB register structure */
typedef USB_Uncached struct {
   union  {
      struct  {
         USB_REGISTER   CAPLENGTH_HCIVER;
         USB_REGISTER   HCS_PARAMS;       /* HC structural parameters */
         USB_REGISTER   HCC_PARAMS;       /* HC Capability Parameters*/
         USB_REGISTER   RESERVED1[5];
         USB_REGISTER   DCI_VERSION;      /* DC version number and reserved 16 bits */
         USB_REGISTER   DCC_PARAMS;       /* DC Capability Parameters */
      } CAPABILITY_REGISTERS;

      struct  {
         USB_REGISTER   GPTIMER0LD;
         USB_REGISTER   GPTIMER0CTL;
         USB_REGISTER   GPTIMER1LD;
         USB_REGISTER   GPTIMER1CTL;
      } TIMER_REGISTERS;
      
      struct  {
         USB_REGISTER   USB_CMD;                   /* Command register */
         USB_REGISTER   USB_STS;                   /* Status register */
         USB_REGISTER   USB_INTR;                  /* Interrupt enable */
         USB_REGISTER   USB_FRINDEX;               /* Frame index */
         USB_REGISTER   CTRLDSSEGMENT;             /* 4G segment selector */
         USB_REGISTER   DEVICE_ADDR;               /* Device Address */
         USB_REGISTER   EP_LIST_ADDR;              /* Endpoint List Address */
         USB_REGISTER   RESERVED0[9];
         USB_REGISTER   CONFIG_FLAG;               /* Configured Flag register */
         USB_REGISTER   PORTSCX[VUSBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */
         USB_REGISTER   OTGSC;
         USB_REGISTER   USB_MODE;                  /* USB Host/Device mode */
         USB_REGISTER   ENDPT_SETUP_STAT;          /* Endpoint Setup Status */
         USB_REGISTER   ENDPTPRIME;                /* Endpoint Initialize */
         USB_REGISTER   ENDPTFLUSH;                /* Endpoint De-initialize */
         USB_REGISTER   ENDPTSTATUS;               /* Endpoint Status */
         USB_REGISTER   ENDPTCOMPLETE;             /* Endpoint Interrupt On Complete */
         USB_REGISTER   ENDPTCTRLX[16];            /* Endpoint Control, where x = 0.. 15 */
      } OPERATIONAL_DEVICE_REGISTERS;
      
      struct  {
         USB_REGISTER   USB_CMD;                   /* Command register */
         USB_REGISTER   USB_STS;                   /* Status register */
         USB_REGISTER   USB_INTR;                  /* Interrupt enable */
         USB_REGISTER   USB_FRINDEX;               /* Frame index */
         USB_REGISTER   CTRLDSSEGMENT;             /* 4G segment selector */
         USB_REGISTER   PERIODIC_LIST_BASE_ADDR;   /* Periodic schedule list */
         USB_REGISTER   CURR_ASYNC_LIST_ADDR;      /* Current Asynch schedule list */
         USB_REGISTER   ASYNCTTSTS;                /* Async buffer in embedded TT control */
         USB_REGISTER   RESERVED0[4];
         USB_REGISTER   ULPIVIEWPORT;
         USB_REGISTER   RESERVED1[3];
         USB_REGISTER   CONFIG_FLAG;               /* Configured Flag register */
         USB_REGISTER   PORTSCX[VUSBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */
         USB_REGISTER   OTGSC;                     /* OTG status and control register */
         USB_REGISTER   USB_MODE;                  /* USB Host/Device mode */
      } OPERATIONAL_HOST_REGISTERS;
   } REGISTERS;
} VUSB20_REG_STRUCT, _PTR_ VUSB20_REG_STRUCT_PTR;

#if 0
typedef USB_Uncached struct {
   uint_32   MAX_PKT_LENGTH;      /* Bits 16..26 Bit 15 is Interrupt 
                                          ** On Setup 
                                          */
   uint_32   CURR_DTD_PTR;        /* Current dTD Pointer */
   uint_32   NEXT_DTD_PTR;        /* Next dTD Pointer */
   uint_32   SIZE_IOC_INT_STS;    /* Total bytes (16..30), IOC (15), 
                                          ** INT (8), STS (0-7) 
                                          */
   uint_32   BUFF_PTR0;           /* Buffer pointer Page 0 (12-31) */
   uint_32   BUFF_PTR1;           /* Buffer pointer Page 1 (12-31) */
   uint_32   BUFF_PTR2;           /* Buffer pointer Page 2 (12-31) */
   uint_32   BUFF_PTR3;           /* Buffer pointer Page 3 (12-31) */
   uint_32   BUFF_PTR4;           /* Buffer pointer Page 4 (12-31) */
   uint_32   RESERVED1;
   uchar     SETUP_BUFFER[8];     /* 8 bytes of setup data that follows 
                                  ** the Setup PID 
                                  */
   uint_32   RESERVED2[4];
} VUSB20_EP_QUEUE_HEAD_STRUCT, _PTR_ VUSB20_EP_QUEUE_HEAD_STRUCT_PTR;

typedef USB_Uncached struct ep_tr_struct {
   uint_32      NEXT_TR_ELEM_PTR; /* Memory address of next 
                                          ** dTD to be processed (5-31)
                                          ** and the T (bit 0) indicating 
                                          ** pointer validity
                                          */
   uint_32      SIZE_IOC_STS;     /* total bytes (16-30), 
                                          ** IOC (15), Status (0-7) 
                                          */
   uint_32      BUFF_PTR0;        /* Buffer pointer Page 0 */
   uint_32      BUFF_PTR1;        /* Buffer pointer Page 1 */
   uint_32      BUFF_PTR2;        /* Buffer pointer Page 2 */
   uint_32      BUFF_PTR3;        /* Buffer pointer Page 3 */
   uint_32      BUFF_PTR4;        /* Buffer pointer Page 4 */
   pointer      SCRATCH_PTR;
} VUSB20_EP_TR_STRUCT, _PTR_ VUSB20_EP_TR_STRUCT_PTR;
#endif

typedef USB_Uncached struct {
   // EHCI Defined
   // These should be accessed via macros                                           
   uint_32      NEXT_LINK_PTR;    /* (5-31) Memory address of 
                                          ** next schedule data structure 
                                          ** item Type (1..2 ) and the 
                                          ** T (bit 0) indicating pointer 
                                          ** validity
                                          */
   uint_32      TR_STATUS_CTL_LIST[8];  /* bits 31-28: Status,
                                                ** bits 27-16: Tr X length
                                                ** bit 15: Int on complete
                                                ** bits 14-12: Page Select
                                                ** bits 11-0: Tr X offset
                                                */
   uint_32      BUFFER_PAGE_PTR_LIST[7];  /* bits 31-12 4K aligned pointer 
                                                ** to physical memory 
                                                ** bits 11-8 endpoint no.
                                                ** bit 7: reserved
                                                ** bits 6-0 device address*/
                                                
   // USB Host Stack specific extensions (not read by controller)  
   // These can be accessed directly                                           
   pointer      SCRATCH_PTR;
   pointer      PIPE_DESCR_FOR_THIS_ITD;
   pointer      PIPE_TR_DESCR_FOR_THIS_ITD;
   uint_32_ptr  frame_list_ptr;
   uint_32      number_of_transactions;
   /* 32-byte aligned structures */
   uint_32      RESERVED[11];
} EHCI_ITD_STRUCT, _PTR_ EHCI_ITD_STRUCT_PTR;

typedef USB_Uncached struct {
   // EHCI Defined
   // These should be accessed via macros                                           
   uint_32      NEXT_LINK_PTR;    /* (5-31) Memory address of 
                                          ** next schedule data structure 
                                          ** item Type (1..2 ) and the 
                                          ** T (bit 0) indicating pointer 
                                          ** validity
                                          */
   uint_32      EP_CAPAB_CHARAC;  /* bits 31: Direction (I/O),
                                          ** bits 30-24: Port number
                                          ** bit 23: reserved
                                          ** bits 22-16: Hub address
                                          ** bits 15-12: Reserved
                                          ** bits 11-8: Endpoint number
                                          ** bit 7: reserved
                                          ** bits 6-0: device address
                                          */
   uint_32      UFRAME_SCHED_CTL; /* bits 31-16: reserved 
                                          ** bits 15-8: Split completion mask
                                          ** bits 7-0: Split start mask
                                          */
   uint_32      TRANSFER_STATE;   /* bit 31: int on complete
                                          ** bit 30: Page Select
                                          ** bits 29-26: Reserved
                                          ** bits 25-16: total bytes to 
                                          ** transfer
                                          ** bits 15-8: uframe 
                                          ** complete-split progress mask
                                          ** bits 7-0: status
                                          */
   uint_32      BUFFER_PTR_0;     /* bits 31-12: 4K aligned pointer 
                                          ** to physical memory 
                                          ** bits 11-0: Current offset
                                          */
   uint_32      BUFFER_PTR_1;     /* bits 31-12: 4K aligned pointer 
                                          ** to physical memory 
                                          ** bits 11-5 reserved
                                          ** bits 4-3 tr position
                                          ** bits 2-0 tr count
                                          */
   uint_32      BACK_LINK_PTR;    /* bits 31-5 back pointer points to sITD 
                                          ** bits 4-1: reserved
                                          ** bit 0: terminate
                                          */
   // USB Host Stack specific extensions (not read by controller)  
   // These can be accessed directly                                           
    pointer      SCRATCH_PTR;
   pointer      PIPE_DESCR_FOR_THIS_SITD;
   pointer      PIPE_TR_DESCR_FOR_THIS_SITD;
   uint_32_ptr  frame_list_ptr;

   /* align to 16 word boundry */
   uint_32      RESERVED[5];

} EHCI_SITD_STRUCT, _PTR_ EHCI_SITD_STRUCT_PTR;

typedef USB_Uncached struct {
   // EHCI Defined
   // These should be accessed via macros                                           
   uint_32      NEXT_QTD_PTR;     /* (5-31) Memory address of 
                                          ** next qTD to be processed
                                          ** (4..1) reserved 
                                          ** T (bit 0) indicating pointer 
                                          ** validity
                                          */
   uint_32      ALT_NEXT_QTD_PTR; /* bits 31-5: alternate next 
                                          ** qTD if the above one encounters 
                                          ** a short packet
                                          ** (4..1) reserved 
                                          ** T (bit 0) indicating pointer 
                                          ** validity
                                          */
   uint_32      TOKEN;            /* bits 31: data toggle 
                                          ** bits 30-16: Total bytes to transfer
                                          ** bit 15: Interrupt on Complete
                                          ** bits 14-12: Current page
                                          ** bits 11-10: Error Counter
                                          ** bits 9-8: PID code
                                          ** bits 7-0: status
                                          */
   uint_32      BUFFER_PTR_0;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 11-0: Current Offset
                                          */
   uint_32      BUFFER_PTR_1;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 11-0: reserved
                                          */
   uint_32      BUFFER_PTR_2;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 11-0: reserved
                                          */
   uint_32      BUFFER_PTR_3;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 11-0: reserved
                                          */
   uint_32      BUFFER_PTR_4;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 11-0: reserved
                                          */
   // USB Host Stack specific extensions (not read by controller)  
   // These can be accessed directly                                           
    pointer     SCRATCH_PTR;
   pointer     PIPE_DESCR_FOR_THIS_QTD;
   pointer     TR_FOR_THIS_QTD;
   uint_32     RESERVED[5];
} EHCI_QTD_STRUCT, _PTR_ EHCI_QTD_STRUCT_PTR;

typedef USB_Uncached struct {
   // EHCI Defined
   // These should be accessed via macros                                           
   uint_32      HORIZ_LINK_PTR;   /* (5-31) Memory address of 
                                          ** next data object to be processed
                                          ** (4..3) reserved 
                                          ** (2..1) type of the item
                                          ** T (bit 0) indicating pointer 
                                          ** validity
                                          */
   uint_32      EP_CAPAB_CHARAC1; /* bits 31-28: NAK count reload,
                                          ** bit 27: Control endpoint flag
                                          ** bit 26-16: Maximum packet length
                                          ** bit 15: Head of reclamation 
                                          ** list flag
                                          ** bit 14: data toggle control
                                          ** bits 13-12: endpoint speed
                                          ** bit 11-8: endpoint number
                                          ** bits 7: Inactivate on next tr
                                          ** bits 6-0: Device address
                                          */
   uint_32      EP_CAPAB_CHARAC2; /* bits 31-30: High-BW pipe 
                                          ** Multiplier, 
                                          ** bit 29-23: Port number
                                          ** bit 22-16: Hub address
                                          ** bit 15-8: Split completion mask
                                          ** bit 7-0: Interrupt schedule mask
                                          */
   uint_32      CURR_QTD_LINK_PTR;/* bits 31-5: physical memory address
                                          ** of the current xaction processed
                                          */
   uint_32      NEXT_QTD_LINK_PTR;/* bits 31-5: physical memory address
                                          ** of the current xaction processed
                                          ** bit 0: Terminate bit
                                          */
   uint_32      ALT_NEXT_QTD_LINK_PTR;  /* bits 31-5: physical memory address
                                                ** of the current xaction processed
                                                ** bits 4-1: NAK counter
                                                ** bit 0: Terminate bit
                                                */
   uint_32      STATUS;           /* bit 31: data-toggle
                                          ** bits 30-16: total bytes to transfer
                                          ** bit 15: Interrupt on complete
                                          ** bits 11-10: Error counter
                                          ** bit 0: Ping state/Err
                                          ** physical memory address
                                          ** bit 11-0: reserved
                                          */
   uint_32      BUFFER_PTR_0;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 11-0: reserved
                                          */
   uint_32      BUFFER_PTR_1;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 7-0: Split-transaction, 
                                          ** complete-split progress
                                          */
   uint_32      BUFFER_PTR_2;     /* bits 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bits 11-5: S-bytes
                                          ** bits 4-0: Split-transaction 
                                          ** frame tag
                                          */
   uint_32      BUFFER_PTR_3;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 11-0: reserved
                                          */
   uint_32      BUFFER_PTR_4;     /* bit 31-12: 4K-page aligned 
                                          ** physical memory address
                                          ** bit 11-0: reserved
                                          */
   // USB Host Stack specific extensions (not read by controller)  
   // These can be accessed directly                                           
    pointer     SCRATCH_PTR;
   pointer     PIPE_DESCR_FOR_THIS_QH;
   uint_32     RESERVED[18];
} EHCI_QH_STRUCT, _PTR_ EHCI_QH_STRUCT_PTR;

typedef USB_Uncached struct {
   // EHCI Defined
   // These should be accessed via macros                                           
   uint_32      NORMAL_PATH_LINK_PTR;   /* (5-31) Memory address of 
                                                ** next data object to be processed
                                                ** in the periodic list
                                                ** bits 4-3: reserved 
                                                ** (2..1) type of the item
                                                ** T (bit 0) indicating pointer 
                                                ** validity
                                                */
   uint_32      BACK_PATH_LINK_PTR;     /* bits 31-5: Memory address of 
                                                ** the queue head,
                                                ** bit 4-3: reserved
                                                ** (2..1) type of the item
                                                ** T (bit 0) indicating pointer 
                                                ** validity
                                                */
   // USB Host Stack specific extensions (not read by controller)  
   // These can be accessed directly                                           
    pointer      SCRATCH_PTR;
   /* 32-bytes aligned */
   uint_32              RESERVED[6];
} EHCI_FSTN_STRUCT, _PTR_ EHCI_FSTN_STRUCT_PTR;

typedef uint_32   EHCI_FRAME_LIST_ELEMENT_POINTER;

typedef struct {
   // EHCI Defined
   // This should be accessed via macros                                           
   uint_32  ALLOCATED_BW;  /* Allocated bandwidth for this frame/uframe */
} FRAME_BW_STRUCT, _PTR_ FRAME_BW_STRUCT_PTR;

#endif // __ehci_h__


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwadc/lwadc_vadc_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2011 Embedded Access Inc
* All Rights Reserved
*
**************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwadc_vadc_prv.h$
* $Version : 3.8.1.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   CPU specific LWADC driver header file
*
*END************************************************************************/

#ifndef __lwadc_vadc_prv_h__
#define __lwadc_vadc_prv_h__

#ifdef __cplusplus
extern "C" {
#endif



#define LWADC_CFG_AVGS_4                ADC_CFG_AVGS(0x00)
#define LWADC_CFG_AVGS_8                ADC_CFG_AVGS(0x01)
#define LWADC_CFG_AVGS_16               ADC_CFG_AVGS(0x02)
#define LWADC_CFG_AVGS_32               ADC_CFG_AVGS(0x03)
#define LWADC_CFG_AVGE                  ADC_CFG_AVGS(0x04)
#define LWADC_CFG_ADCO                  ADC_CFG_AVGS(0x08)
#define LWADC_CFG_CALF                  ADC_CFG_AVGS(0x40)
#define LWADC_CFG_CAL                   ADC_CFG_AVGS(0x80)

#define LWADC_CFG_ADIV_1                ADC_CFG_ADIV(0x00)
#define LWADC_CFG_ADIV_2                ADC_CFG_ADIV(0x01)
#define LWADC_CFG_ADIV_4                ADC_CFG_ADIV(0x02)
#define LWADC_CFG_ADIV_8                ADC_CFG_ADIV(0x03)

#define LWADC_CFG_ADICLK_BUSCLK         ADC_CFG_ADICLK(0x00)
#define LWADC_CFG_ADICLK_BUSCLK2        ADC_CFG_ADICLK(0x01)
#define LWADC_CFG_ADICLK_ALTCLK         ADC_CFG_ADICLK(0x02)
#define LWADC_CFG_ADICLK_ADACK          ADC_CFG_ADICLK(0x03)

extern pointer  _bsp_get_adc_base_address(uint_8);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_getroute.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_getroute.c$
* $Version : 3.8.11.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   Shell RTCS_get_route implementation.
*
*END************************************************************************/

#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h"



/*TASK*-----------------------------------------------------------------
*
* Function Name  : Shell_getroute
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/

int_32 Shell_getroute(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;

   _ip_address       gate_ipaddr = 0;
   _ip_address       ipaddr = 0;
   _ip_address       ipmask = 0;
  
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if ((argc < 2) || (argc > 3)) {
         return_code = SHELL_EXIT_ERROR;
         print_usage = TRUE;
      } else  {
         if (! Shell_parse_ip_address( argv[1], &ipaddr  ))  {
            printf("Error, invalid ip address\n");
            return_code = SHELL_EXIT_ERROR;
         } else if (argc == 3)  {
            if (! Shell_parse_ip_address( argv[2], &ipmask  ))  {
               printf("Error, invalid ip mask\n");
               return_code = SHELL_EXIT_ERROR;
            }
         }          
      }          
         
         
      if (return_code == SHELL_EXIT_SUCCESS)  {
         gate_ipaddr = RTCS_get_route(ipaddr, ipmask);
         printf("The route to ip address: %d.%d.%d.%d, netmask: %d.%d.%d.%d is gateway %d.%d.%d.%d\n",
            IPBYTES(ipaddr),IPBYTES(ipmask),IPBYTES(gate_ipaddr));
      } 
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <ipaddr> <netmask>\n", argv[0]);
      } else  {
         printf("Usage: %s <ipaddr> <netmask>\n", argv[0]);
         printf("   <ipaddr>  = IP address \n");
         printf("   <netmask> = Network mask\n");
      }
   }

   return return_code;
} /* Endbody */

/*TASK*-----------------------------------------------------------------
*
* Function Name  : Shell_getroute
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/

int_32 Shell_walkroute(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc >1)  {
         return_code = SHELL_EXIT_ERROR;
         print_usage = TRUE;
      }          
         
         
      if (return_code == SHELL_EXIT_SUCCESS)  {
         RTCS_walk_route();
      } 
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s\n", argv[0]);
      } else  {
         printf("Usage: %s\n", argv[0]);
      }
   }

   return return_code;
} /* Endbody */

#endif /* SHELLCFG_USES_RTCS */

/* EOF */



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ticker.h<|end_filename|>
#ifndef __ticker_h__
#define __ticker_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ticker.h$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   Timer interface definitions for the TCP layer.
*
*END************************************************************************/


/************************************************************************/
/* Constants                                                            */
/************************************************************************/

#if 0
#ifdef _MSDOS_
#define TICK_LENGTH   55   /* in milliseconds */
#else
#define TICK_LENGTH   5    /* in milliseconds */
#endif
#endif
#define TICK_LENGTH _time_get_resolution()


/************************************************************************/
/* Macros                                                               */
/************************************************************************/

#define TimerInit(timeq_ptr)  (_Zeromem((void _PTR_)(timeq_ptr), sizeof(TimeQ)))

/************************************************************************/
/* Typedefs                                                             */
/************************************************************************/

/*  The following structure is used for delays (where client blocks),
 *   oneshot timers, and cyclic timers, i.e. all items scheduled by
 *   the TickerServer.
 */
typedef struct TimeQ {

    struct TimeQ  _PTR_ next;
    struct TimeQ  _PTR_ prev;

    struct TimeQ  _PTR_ _PTR_ donelist;
                              /* where to put completed oneshots */

    struct TimeQ  _PTR_ _PTR_ curlist;
                              /* the list which currently holds the
                              ** timer (usually &qhead or donelist),
                              ** 0 if none */

    uint_16       RESERVED;
    uint_16       count;      /* nb of timeouts (ignored for delay) */
    int_32        delay;      /* time delta before this node done */
    uint_32       abs_to;     /* time at which this node should timeout */
    int_32        reload;     /* <0==delay, 0==oneshot, >0==cyclic
                              ** timer's repeated delay */

/*  task_id       client; */  /* task to Signal() (timers) or
                                 Reply() to (delays); cleared when
                                 oneshot or delay has expired;
                                 if set, this means this timer is
                                 active, and in the schedule list
                                 (`qhead', see ticker.c) */

} TimeQ;

/************************************************************************/
/* Functions                                                            */
/************************************************************************/

void TCP_Timer_schedule
(
   TimeQ _PTR_       ,        /* IN/OUT - The timer to schedule */
   TimeQ _PTR_ _PTR_          /* IN/OUT - The head of the timer queue */
);

void  TCP_Timer_expire
(
   TimeQ _PTR_                /* IN/OUT - The expired timer */
);

void  TCP_Timer_remove
(
   TimeQ _PTR_                /* IN/OUT - The timer to remove */
);

int_32 TCP_Timer_stop
(
   TimeQ _PTR_       ,        /* The timer to stop */
   TimeQ _PTR_ _PTR_          /* The timer queue head */
);

int_32 TCP_Timer_start
(
   TimeQ _PTR_       ,        /* IN/OUT - The timer */
   int_32            ,        /* IN     - No. msec until timeout */
   int_32            ,        /* IN     - No. msec to dly after 1st to */
   TimeQ _PTR_ _PTR_          /* IN/OUT - Head of timer queue */
);

int_32 TCP_Timer_advance
(
   TimeQ _PTR_       ,        /* IN/OUT - timer to reschedule */
   int_32            ,        /* IN     - no. msec to increment timeout */
   TimeQ _PTR_ _PTR_          /* IN/OUT - timer queue head */
);

int_32 TCP_Timer_oneshot_max
(
   TimeQ _PTR_       ,        /* IN/OUT - timer to start */
   int_32            ,        /* IN     - timeout */
   TimeQ _PTR_ _PTR_          /* IN/OUT - timer queue head */
);

uint_32 TCP_Tick_server
(
   void
);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pipe/io_pipe.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_pipe.c$
* $Version : 3.8.6.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the driver functions for the Pipe device.
*
*END************************************************************************/

/* suppress warning if mutex component is not enabled in MQX */
#define MQX_DISABLE_CONFIG_CHECK 1

#include "mqx_inc.h"                         
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "charq.h"
#include "mutex.h"
#include "pipe_prv.h"
#include "io_pipe.h"


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_pipe_install
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    Install an interrupt driven serial device.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_pipe_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr            identifier,
      
      /* [IN] The pipe queue size to use */
      uint_32             queue_size,

      /* [IN] Currently not used */
      uint_32             flags

   )
{ /* Body */
   IO_PIPE_INIT_STRUCT_PTR  io_pipe_init_ptr;

   /* Allocate an Pipe installation structure */
   io_pipe_init_ptr = _mem_alloc_system_zero(
      (uint_32)sizeof(IO_PIPE_INIT_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (io_pipe_init_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif

   /* Set queue size for Pipe */
   io_pipe_init_ptr->QUEUE_SIZE = queue_size;

   /* Copy flags field */
   io_pipe_init_ptr->FLAGS      = flags;

   /* Install device */
   return (_io_dev_install_ext(identifier,
      _io_pipe_open, _io_pipe_close,
      _io_pipe_read, _io_pipe_write,
      _io_pipe_ioctl, _io_pipe_uninstall,
      (pointer)io_pipe_init_ptr)); 

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_pipe_uninstall
* Returned Value   : _mqx_int a task error code or MQX_OK
* Comments         :
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_pipe_uninstall
   (
      /* [IN] The devices context */
      IO_DEVICE_STRUCT_PTR  io_dev_ptr
   )
{ /* Body */
  
   if (io_dev_ptr->DRIVER_INIT_PTR) {
      _mem_free(io_dev_ptr->DRIVER_INIT_PTR);
   }/* Endif */

   return(MQX_OK);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_pipe_open
* Returned Value   : int_32 task error code or MQX_OK
* Comments         :
*    This routine opens an instance of a Pipe. It acquires
*    memory, then stores information into it about the Pipe.
*    This memory is returned as a FILE 'handle' to be used for 
*    all other pipe functions by any task. 
*
* 
*END**********************************************************************/

_mqx_int _io_pipe_open
   (
      /* [IN] the file handle for the device being opened */
      FILE_DEVICE_STRUCT_PTR fd_ptr,
       
      /* [IN] the remaining portion of the name of the device */
      char             _PTR_ open_name_ptr,

      /* [IN] the flags to be used during operation:
      ** echo, translation, xon/xoff
      */
      char             _PTR_ flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR          io_dev_ptr = fd_ptr->DEV_PTR;
   IO_PIPE_INIT_STRUCT_PTR       io_pipe_init_ptr;
   IO_PIPE_INFO_STRUCT_PTR       io_pipe_info_ptr;
   MUTEX_ATTR_STRUCT             mutex_attr;
   uint_32                       result = MQX_OK;

   /* Allocate a Pipe information structure */
   io_pipe_info_ptr = _mem_alloc_system_zero(
      (uint_32)sizeof(IO_PIPE_INFO_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (io_pipe_info_ptr == NULL){
      return(MQX_OUT_OF_MEMORY);
   }/* Endif */
#endif 

   fd_ptr->DEV_DATA_PTR = io_pipe_info_ptr;
   io_pipe_init_ptr = (IO_PIPE_INIT_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   
   io_pipe_info_ptr->QUEUE_SIZE = io_pipe_init_ptr->QUEUE_SIZE;

   /* Initialize mutexes */
   result = _mutatr_init(&mutex_attr); 
   
#if MQX_CHECK_ERRORS
   if (result != MQX_EOK) {
      _mem_free(io_pipe_info_ptr);
      return (result);
   } /* Endif */
#endif 

   _mutatr_set_wait_protocol(&mutex_attr, MUTEX_PRIORITY_QUEUEING);
   _mutatr_set_sched_protocol(&mutex_attr, MUTEX_PRIO_INHERIT);

   result = _mutex_init(&io_pipe_info_ptr->READ_MUTEX, &mutex_attr);
#if MQX_CHECK_ERRORS
   if (result != MQX_EOK) {
      _mem_free(io_pipe_info_ptr);
      return (result);
   } /* Endif */
#endif 
   
   result = _mutex_init(&io_pipe_info_ptr->WRITE_MUTEX, &mutex_attr);
#if MQX_CHECK_ERRORS
   if (result != MQX_EOK) {
      _mem_free(io_pipe_info_ptr);
      return (result);
   } /* Endif */
#endif 

   result = _mutex_init(&io_pipe_info_ptr->ACCESS_MUTEX, &mutex_attr);
#if MQX_CHECK_ERRORS
   if (result != MQX_EOK) {
      _mem_free(io_pipe_info_ptr);
      return (result);
   } /* Endif */
#endif 

   /* Initialize semaphores */

   result = _lwsem_create(&io_pipe_info_ptr->FULL_SEM, 0);
#if MQX_CHECK_ERRORS
   if (result != MQX_OK) {
      _mem_free(io_pipe_info_ptr);
      return (result);
   } /* Endif */
#endif 

   result = _lwsem_create(&io_pipe_info_ptr->EMPTY_SEM, 0);
#if MQX_CHECK_ERRORS
   if (result != MQX_OK) {
      _mem_free(io_pipe_info_ptr);
      return (result);
   } /* Endif */
#endif 
                          
   /* Allocate queue structure for pipe char queue */
   io_pipe_info_ptr->QUEUE = (pointer)_mem_alloc_system(
      sizeof(CHARQ_STRUCT) - (4 * sizeof(char)) + io_pipe_info_ptr->QUEUE_SIZE);

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (io_pipe_info_ptr->QUEUE == NULL){
      _mem_free(io_pipe_info_ptr);
      return(MQX_OUT_OF_MEMORY);
   }/* Endif */
#endif            

   /* Initialize Pipe queue */
   _CHARQ_INIT(io_pipe_info_ptr->QUEUE, io_pipe_init_ptr->QUEUE_SIZE);
   
   return(result);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_pipe_close
* Returned Value   : int_32 error code
* Comments         :
*    This routine closes the Pipe and free the datastructures.
* 
*END**********************************************************************/

_mqx_int _io_pipe_close
   (
      /* [IN] the file handle for the device being closed */
      FILE_DEVICE_STRUCT_PTR fd_ptr
   )
{ /* Body */
   IO_PIPE_INFO_STRUCT_PTR         io_pipe_info_ptr;
   int_32                          result = MQX_OK;

   io_pipe_info_ptr = fd_ptr->DEV_DATA_PTR;

   /* Destroy the mutexes - doesn't free memory*/

    _mutex_destroy(&io_pipe_info_ptr->READ_MUTEX);
    _mutex_destroy(&io_pipe_info_ptr->WRITE_MUTEX);
    _mutex_destroy(&io_pipe_info_ptr->ACCESS_MUTEX);
                                 
   /* Start CR 2237 */
   /* Derstroy the lightweight semaphores */
   _lwsem_destroy(&io_pipe_info_ptr->FULL_SEM);
   _lwsem_destroy(&io_pipe_info_ptr->EMPTY_SEM);
   /* End CR 2237 */

   /* Free Pipe data structures */
   _mem_free(io_pipe_info_ptr->QUEUE);
   _mem_free(io_pipe_info_ptr);

   return(result);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_pipe_read
* Returned Value   : int_32 number of characters read
* Comments         :
*    This routine reads characters from the Pipe queue.
*    This function block a task if there are no characters in the
*    Pipe queue.
*
*END*********************************************************************/

_mqx_int _io_pipe_read
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] where the characters are to be stored */
      char             _PTR_ data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int               num
      
   )
{ /* Body */      
   volatile IO_PIPE_INFO_STRUCT_PTR       io_pipe_info_ptr;
   uchar                                  c = 0;
   uint_32                                i = num + 1;
   volatile CHARQ_STRUCT _PTR_            pipe_queue;
   uint_32                                error;

   io_pipe_info_ptr = fd_ptr->DEV_DATA_PTR;

   pipe_queue = io_pipe_info_ptr->QUEUE;

   /* Turn off pipe abort flags */
   io_pipe_info_ptr->KM_ABORT_READ = FALSE;
   
   /* Lock out other reading tasks */       
   error = _mutex_lock(&io_pipe_info_ptr->READ_MUTEX);

#if MQX_CHECK_ERRORS
   if ( error != MQX_EOK ) {
      return (-1);
   } /* Endif */
#endif
     
   /* Lock out access of a writer task to the pipe data structures */
   error = _mutex_lock(&io_pipe_info_ptr->ACCESS_MUTEX);
#if MQX_CHECK_ERRORS
   if ( error != MQX_EOK ) {
      return (-1);
   } /* Endif */
#endif   
   
   /* Start reading characters from the pipe*/
   while ( --i ) {

     /* If the pipe is empty, wait until the pipe is not empty */                            
      while (_CHARQ_EMPTY(pipe_queue)) {


         error = _mutex_unlock(&io_pipe_info_ptr->ACCESS_MUTEX);
      #if MQX_CHECK_ERRORS
         if ( error != MQX_EOK ) {
            return (-1);
         } /* Endif */
      #endif   

         error = _lwsem_post(&io_pipe_info_ptr->FULL_SEM);
      #if MQX_CHECK_ERRORS
         if ( error != MQX_OK ) {
            return (-1);
         } /* Endif */
      #endif   
         
         error = _lwsem_wait(&io_pipe_info_ptr->EMPTY_SEM);
      #if MQX_CHECK_ERRORS
         if ( error != MQX_OK ) {
            return (-1);
         } /* Endif */
      #endif   
         
       if(io_pipe_info_ptr->KM_ABORT_READ)
       {
		   error = _mutex_unlock(&io_pipe_info_ptr->READ_MUTEX);
		#if MQX_CHECK_ERRORS
		   if ( error != MQX_EOK ) {
		      return (-1);
		   } /* Endif */
		#endif
       	
       		return num - i;	
       }
       
       
         /* Lock out access of a writer task to the pipe data structures */
         error = _mutex_lock(&io_pipe_info_ptr->ACCESS_MUTEX);
      #if MQX_CHECK_ERRORS
         if ( error != MQX_EOK ) {
            return (-1);
         } /* Endif */
      #endif   

      } /* Endwhile */

      /* Read char from pipe */
      _CHARQ_DEQUEUE(pipe_queue,c);

      /* Copy data to the returned buffer */
      *data_ptr++ = c;
                
   } /* Endwhile */

   error = _lwsem_post(&io_pipe_info_ptr->FULL_SEM);
#if MQX_CHECK_ERRORS
   if ( error != MQX_OK ) {
      return (-1);
   } /* Endif */
#endif   

   /* Unlock access access mutex and read mutex */
   error = _mutex_unlock(&io_pipe_info_ptr->ACCESS_MUTEX);

#if MQX_CHECK_ERRORS
   if ( error != MQX_EOK ) {
      return (-1);
   } /* Endif */
#endif

   error = _mutex_unlock(&io_pipe_info_ptr->READ_MUTEX);

#if MQX_CHECK_ERRORS
   if ( error != MQX_EOK ) {
      return (-1);
   } /* Endif */
#endif
   
   return num;

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_pipe_write
* Returned Value   : void
* Comments         :
*    This routine writes characters to the Pipe.  It will block the task 
**   if the Pipe is full.
*
*END**********************************************************************/

_mqx_int _io_pipe_write
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] where the characters to write out are */
      char             _PTR_ data_ptr,

      /* [IN] the number of characters to write */
      _mqx_int               num
   )
{ /* Body */
   volatile IO_PIPE_INFO_STRUCT_PTR         io_pipe_info_ptr;
   uint_32                                  i = num + 1;
   uchar                                    c;
   volatile CHARQ_STRUCT _PTR_              pipe_queue;
   uint_32                                  error;


   io_pipe_info_ptr = fd_ptr->DEV_DATA_PTR;

   pipe_queue = io_pipe_info_ptr->QUEUE;

   /* Turn off pipe abort flags */
   io_pipe_info_ptr->KM_ABORT_WRITE = FALSE;
   
   /* Lock out other reading tasks */       
   error = _mutex_lock(&io_pipe_info_ptr->WRITE_MUTEX);
#if MQX_CHECK_ERRORS
   if ( error != MQX_EOK ) {
      return (-1);
   } /* Endif */
#endif

   /* Lock out access of a writer task to the pipe data structures */
   error = _mutex_lock(&io_pipe_info_ptr->ACCESS_MUTEX);
#if MQX_CHECK_ERRORS
   if ( error != MQX_EOK ) {
      return (-1);
   } /* Endif */
#endif
   
   /* Start writing characters to the pipe */
   while ( --i ) {
                               
      /* If the pipe is full, wait until the pipe is not full */
      while ( _CHARQ_FULL(pipe_queue) ) {

       
         error = _mutex_unlock(&io_pipe_info_ptr->ACCESS_MUTEX);
      #if MQX_CHECK_ERRORS
         if ( error != MQX_EOK ) {
            return (-1);
         } /* Endif */
      #endif   

         error = _lwsem_post(&io_pipe_info_ptr->EMPTY_SEM);
      #if MQX_CHECK_ERRORS
         if ( error != MQX_OK ) {
            return (-1);
         } /* Endif */
      #endif   
         
         error = _lwsem_wait(&io_pipe_info_ptr->FULL_SEM);
      #if MQX_CHECK_ERRORS
         if ( error != MQX_OK ) {
            return (-1);
         } /* Endif */
      #endif   
         
       if(io_pipe_info_ptr->KM_ABORT_WRITE)
       {
       	   io_pipe_info_ptr->KM_ABORT_WRITE = FALSE;
		   error = _mutex_unlock(&io_pipe_info_ptr->WRITE_MUTEX);
		#if MQX_CHECK_ERRORS
		   if ( error != MQX_EOK ) {
		      return (-1);
		   } /* Endif */
		#endif
       	
       		return num - i;	
       }
         /* Lock out access of a writer task to the pipe data structures */
         error = _mutex_lock(&io_pipe_info_ptr->ACCESS_MUTEX);
      #if MQX_CHECK_ERRORS
         if ( error != MQX_EOK ) {
            return (-1);
         } /* Endif */
      #endif   

      } /* Endwhile */

      c = *data_ptr++;

      /* Write the next char into the pipe */
      _CHARQ_ENQUEUE(pipe_queue,c);

   } /* Endwhile */

   error = _lwsem_post(&io_pipe_info_ptr->EMPTY_SEM);
#if MQX_CHECK_ERRORS
   if ( error != MQX_OK ) {
      return (-1);
   } /* Endif */
#endif   

   /* Unlock access mutex and write mutex */
   error = _mutex_unlock(&io_pipe_info_ptr->ACCESS_MUTEX);
#if MQX_CHECK_ERRORS
   if ( error != MQX_EOK ) {
      return (-1);
   } /* Endif */
#endif

   error = _mutex_unlock(&io_pipe_info_ptr->WRITE_MUTEX);

#if MQX_CHECK_ERRORS
   if ( error != MQX_EOK ) {
      return (-1);
   } /* Endif */
#endif


   return num;
   
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_pipe_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_pipe_ioctl
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] the ioctl command */
      uint_32                cmd,

      /* [IN] the ioctl parameters */
      pointer                param_ptr
   )
{ /* Body */
   IO_PIPE_INFO_STRUCT_PTR  io_pipe_info_ptr;
   uint_32                  result = MQX_OK;
   _mqx_uint_ptr            uparam_ptr = param_ptr;

   io_pipe_info_ptr = fd_ptr->DEV_DATA_PTR;

   result = _mutex_lock(&io_pipe_info_ptr->ACCESS_MUTEX);
#if MQX_CHECK_ERRORS
   if ( result != MQX_OK ) {
      return (result);
   } /* Endif */
#endif

   switch (cmd) {

      case PIPE_IOCTL_CHAR_AVAIL:
         if ( !_CHARQ_EMPTY(io_pipe_info_ptr->QUEUE) ) {
           *uparam_ptr = (uint_32)TRUE;
         } else {
           *uparam_ptr = (uint_32)FALSE;
         } /* Endif */
      break;

      case PIPE_IOCTL_GET_SIZE:
         *uparam_ptr =  io_pipe_info_ptr->QUEUE_SIZE;
      break;

      case PIPE_IOCTL_FULL:
         if ( _CHARQ_FULL(io_pipe_info_ptr->QUEUE) ) {
            *uparam_ptr = (uint_32)TRUE;
         } else {
            *uparam_ptr = (uint_32)FALSE;
         } /* Endif */
      break;
   
      case PIPE_IOCTL_EMPTY:
         if ( _CHARQ_EMPTY(io_pipe_info_ptr->QUEUE) ) {
            *uparam_ptr = (uint_32)TRUE;
         } else {
            *uparam_ptr = (uint_32)FALSE;
         } /* Endif */
      break;

      case PIPE_IOCTL_RE_INIT:
           _CHARQ_INIT(io_pipe_info_ptr->QUEUE, io_pipe_info_ptr->QUEUE_SIZE)
           io_pipe_info_ptr->KM_ABORT_READ = TRUE;
           io_pipe_info_ptr->KM_ABORT_WRITE = TRUE;
		
           result = _lwsem_post(&io_pipe_info_ptr->EMPTY_SEM);
      #if MQX_CHECK_ERRORS
         if ( result != MQX_OK ) {
            return (-1);
         } /* Endif */
      #endif   
		   result = _lwsem_post(&io_pipe_info_ptr->FULL_SEM);
    	   #if MQX_CHECK_ERRORS
	         if ( result != MQX_OK ) {
           	    return (-1);
         	 } /* Endif */
     	   #endif  	      	   
      break;
          
      case PIPE_IOCTL_NUM_CHARS_FULL:
           *uparam_ptr = _CHARQ_SIZE(io_pipe_info_ptr->QUEUE);
      break;

      case PIPE_IOCTL_NUM_CHARS_FREE:
           *uparam_ptr = io_pipe_info_ptr->QUEUE_SIZE -
              _CHARQ_SIZE(io_pipe_info_ptr->QUEUE);
      break;
      
      default:
                      
      break;
   } /* Endswitch */

   result = _mutex_unlock(&io_pipe_info_ptr->ACCESS_MUTEX);
#if MQX_CHECK_ERRORS
   if ( result != MQX_OK ) {
      return (result);
   } /* Endif */
#endif
               
   return result;

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/bootcomm.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: bootcomm.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the
*   functions common to BOOTP and DHCP clients.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_IP4

#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"


extern uint_32          BOOT_count;
extern UCB_STRUCT_PTR   BOOT_port;


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : BOOT_open
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Opens the BOOTP/DHCP client port.
*
*END*-----------------------------------------------------------------*/

uint_32 BOOT_open
   (
      void (_CODE_PTR_ service)(RTCSPCB_PTR, UCB_STRUCT_PTR)
   )
{ /* Body */
   uint_32 error;

   if (BOOT_count == 0) {
      error = UDP_openbind_internal(IPPORT_BOOTPC, service, &BOOT_port);
      if (error) {
         return error;
      } /* Endif */
   } /* Endif */

   BOOT_count++;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : BOOT_close
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Closes the BOOTP/DHCP client port.
*
*END*-----------------------------------------------------------------*/

uint_32 BOOT_close
   (
      void
   )
{ /* Body */
   uint_32 error = RTCS_OK;

   BOOT_count--;

   if (BOOT_count == 0) {
      error = UDP_close_internal(BOOT_port);
      BOOT_port = NULL;
   } /* Endif */

   return error;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : BOOT_send
*  Returned Value : void
*  Comments       :
*        Sends a BOOTP/DHCP packet.
*
*END*-----------------------------------------------------------------*/

uint_32 BOOT_send
   (
      RTCSPCB_PTR    rtcs_pcb,         /* [IN]     outgoing packet  */
      pointer        if_ptr            /* [IN]     target interface */
   )
{ /* Body */

   return UDP_send_IF(BOOT_port, if_ptr, IPPORT_BOOTPS, rtcs_pcb);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : BOOT_service
*  Returned Value : void
*  Comments       :
*        Services a BOOTP/DHCP packet.
*
*END*-----------------------------------------------------------------*/

void BOOT_service
   (
      RTCSPCB_PTR    rtcs_pcb,         /* [IN/OUT] incoming packet  */
      UCB_STRUCT_PTR ucb_ptr           /* [IN]     target UCB       */
   )
{ /* Body */
   IP_IF_PTR if_ptr = (IP_IF_PTR)rtcs_pcb->IFSRC;

   if (if_ptr->BOOTFN) {
      (*if_ptr->BOOTFN)(rtcs_pcb);
   } else {
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
      RTCSPCB_free(rtcs_pcb);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GMCLIB/GMCLIB_SvmStd.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GMCLIB_SvmStd.h
*
* @author   B04459
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GMCLIB_SvmStd function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GMCLIB_SVMSTD_H
#define _GMCLIB_SVMSTD_H

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GMCLIB_SvmStdANSIC function.*/
#define GMCLIB_SvmStd(pOutput,pInput)     GMCLIB_SvmStdANSIC(pOutput,pInput)


/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*! 
* @ingroup GMCLIB_GROUP 
*/ 
extern UWord32 GMCLIB_SvmStdANSIC(MCLIB_3_COOR_SYST_T *pOut,
							   const MCLIB_2_COOR_SYST_ALPHA_BETA_T *const pIn);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GMCLIB_SVMSTD_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/WDOG_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type WDOG
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(WDOG_PDD_H_)
#define WDOG_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error WDOG PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* WDOG */ && \
      !defined(MCU_MK10D5) /* WDOG */ && \
      !defined(MCU_MK10D7) /* WDOG */ && \
      !defined(MCU_MK10F12) /* WDOG */ && \
      !defined(MCU_MK10DZ10) /* WDOG */ && \
      !defined(MCU_MK11D5) /* WDOG */ && \
      !defined(MCU_MK11D5WS) /* WDOG */ && \
      !defined(MCU_MK12D5) /* WDOG */ && \
      !defined(MCU_MK20D10) /* WDOG */ && \
      !defined(MCU_MK20D5) /* WDOG */ && \
      !defined(MCU_MK20D7) /* WDOG */ && \
      !defined(MCU_MK20F12) /* WDOG */ && \
      !defined(MCU_MK20DZ10) /* WDOG */ && \
      !defined(MCU_MK21D5) /* WDOG */ && \
      !defined(MCU_MK21D5WS) /* WDOG */ && \
      !defined(MCU_MK22D5) /* WDOG */ && \
      !defined(MCU_MK30D10) /* WDOG */ && \
      !defined(MCU_MK30D7) /* WDOG */ && \
      !defined(MCU_MK30DZ10) /* WDOG */ && \
      !defined(MCU_MK40D10) /* WDOG */ && \
      !defined(MCU_MK40D7) /* WDOG */ && \
      !defined(MCU_MK40DZ10) /* WDOG */ && \
      !defined(MCU_MK40X256VMD100) /* WDOG */ && \
      !defined(MCU_MK50D10) /* WDOG */ && \
      !defined(MCU_MK50D7) /* WDOG */ && \
      !defined(MCU_MK50DZ10) /* WDOG */ && \
      !defined(MCU_MK51D10) /* WDOG */ && \
      !defined(MCU_MK51D7) /* WDOG */ && \
      !defined(MCU_MK51DZ10) /* WDOG */ && \
      !defined(MCU_MK52D10) /* WDOG */ && \
      !defined(MCU_MK52DZ10) /* WDOG */ && \
      !defined(MCU_MK53D10) /* WDOG */ && \
      !defined(MCU_MK53DZ10) /* WDOG */ && \
      !defined(MCU_MK60D10) /* WDOG */ && \
      !defined(MCU_MK60F12) /* WDOG */ && \
      !defined(MCU_MK60F15) /* WDOG */ && \
      !defined(MCU_MK60DZ10) /* WDOG */ && \
      !defined(MCU_MK60N512VMD100) /* WDOG */ && \
      !defined(MCU_MK61F12) /* WDOG */ && \
      !defined(MCU_MK61F15) /* WDOG */ && \
      !defined(MCU_MK61F12WS) /* WDOG */ && \
      !defined(MCU_MK61F15WS) /* WDOG */ && \
      !defined(MCU_MK70F12) /* WDOG */ && \
      !defined(MCU_MK70F15) /* WDOG */ && \
      !defined(MCU_MK70F12WS) /* WDOG */ && \
      !defined(MCU_MK70F15WS) /* WDOG */ && \
      !defined(MCU_PCK20L4) /* WDOG */
  // Unsupported MCU is active
  #error WDOG PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Windowing mode constants */
#define WDOG_PDD_WINDOWING_DISABLED 0U           /**< Disabled */
#define WDOG_PDD_WINDOWING_ENABLED  WDOG_STCTRLH_WINEN_MASK /**< Enabled */

/* Clock source constants. */
#define WDOG_PDD_SOURCE_DEDICATED 0U             /**< Dedicated */
#define WDOG_PDD_SOURCE_ALTERNATE WDOG_STCTRLH_CLKSRC_MASK /**< Alternate */

/* Refresh constants */
#define WDOG_PDD_KEY_1 0xA602U                   /**< First key */
#define WDOG_PDD_KEY_2 0xB480U                   /**< Second key */

/* Unlock constants */
#define WDOG_PDD_UNLOCK_1 0xC520U                /**< First key */
#define WDOG_PDD_UNLOCK_2 0xD928U                /**< Second key */

/* Prescaler constants */
#define WDOG_PDD_DIVIDE_1 0U                     /**< 1 */
#define WDOG_PDD_DIVIDE_2 0x1U                   /**< 2 */
#define WDOG_PDD_DIVIDE_3 0x2U                   /**< 3 */
#define WDOG_PDD_DIVIDE_4 0x3U                   /**< 4 */
#define WDOG_PDD_DIVIDE_5 0x4U                   /**< 5 */
#define WDOG_PDD_DIVIDE_6 0x5U                   /**< 6 */
#define WDOG_PDD_DIVIDE_7 0x6U                   /**< 7 */
#define WDOG_PDD_DIVIDE_8 0x7U                   /**< 8 */


/* ----------------------------------------------------------------------------
   -- GetAllowUpdateStatus
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns non-zero if watchdog registers can be unlocked.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 16-bit value.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      uint16_t result = WDOG_PDD_GetAllowUpdateStatus(deviceID);
 *      @endcode
 */
#define WDOG_PDD_GetAllowUpdateStatus(PeripheralBase) ( \
    (uint16_t)(WDOG_STCTRLH_REG(PeripheralBase) & WDOG_STCTRLH_ALLOWUPDATE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- DisableUpdate
   ---------------------------------------------------------------------------- */

/**
 * @brief No further updates allowed to WDOG write once registers.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      WDOG_PDD_DisableUpdate(deviceID);
 *      @endcode
 */
#define WDOG_PDD_DisableUpdate(PeripheralBase) ( \
    WDOG_STCTRLH_REG(PeripheralBase) &= \
     (uint16_t)(~(uint16_t)WDOG_STCTRLH_ALLOWUPDATE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetWindowingMode
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures the windowing mode operation.
 * @param PeripheralBase Peripheral base address.
 * @param Mode New value of the mode. Use constants from group "Windowing mode
 *        constants". This parameter is 16 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      WDOG_PDD_SetWindowingMode(deviceID, WDOG_PDD_WINDOWING_DISABLED);
 *      @endcode
 */
#define WDOG_PDD_SetWindowingMode(PeripheralBase, Mode) ( \
    WDOG_STCTRLH_REG(PeripheralBase) = \
     (uint16_t)(( \
      (uint16_t)(( \
       WDOG_STCTRLH_REG(PeripheralBase)) & ( \
       (uint16_t)(~(uint16_t)WDOG_STCTRLH_WINEN_MASK)))) | ( \
      (uint16_t)(Mode))) \
  )

/* ----------------------------------------------------------------------------
   -- GetInterruptMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt mask.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 16-bit value.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      uint16_t result = WDOG_PDD_GetInterruptMask(deviceID);
 *      @endcode
 */
#define WDOG_PDD_GetInterruptMask(PeripheralBase) ( \
    (uint16_t)(WDOG_STCTRLH_REG(PeripheralBase) & WDOG_STCTRLH_IRQRSTEN_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the WDOG interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      WDOG_PDD_EnableInterrupt(deviceID);
 *      @endcode
 */
#define WDOG_PDD_EnableInterrupt(PeripheralBase) ( \
    WDOG_STCTRLH_REG(PeripheralBase) |= \
     WDOG_STCTRLH_IRQRSTEN_MASK \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the WDOG interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      WDOG_PDD_DisableInterrupt(deviceID);
 *      @endcode
 */
#define WDOG_PDD_DisableInterrupt(PeripheralBase) ( \
    WDOG_STCTRLH_REG(PeripheralBase) &= \
     (uint16_t)(~(uint16_t)WDOG_STCTRLH_IRQRSTEN_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SelectClockSource
   ---------------------------------------------------------------------------- */

/**
 * @brief Selects clock source.
 * @param PeripheralBase Peripheral base address.
 * @param Source New value of the source. Use constants from group "Clock source
 *        constants.". This parameter is 16 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      WDOG_PDD_SelectClockSource(deviceID, WDOG_PDD_SOURCE_DEDICATED);
 *      @endcode
 */
#define WDOG_PDD_SelectClockSource(PeripheralBase, Source) ( \
    WDOG_STCTRLH_REG(PeripheralBase) = \
     (uint16_t)(( \
      (uint16_t)(( \
       WDOG_STCTRLH_REG(PeripheralBase)) & ( \
       (uint16_t)(~(uint16_t)WDOG_STCTRLH_CLKSRC_MASK)))) | ( \
      (uint16_t)(Source))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableDevice
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the WDOG device.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of WDOG device. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      WDOG_PDD_EnableDevice(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define WDOG_PDD_EnableDevice(PeripheralBase, State) ( \
    WDOG_STCTRLH_REG(PeripheralBase) = \
     (uint16_t)(( \
      (uint16_t)(( \
       WDOG_STCTRLH_REG(PeripheralBase)) & ( \
       (uint16_t)(~(uint16_t)WDOG_STCTRLH_WDOGEN_MASK)))) | ( \
      (uint16_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetEnableDeviceStatus
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns current state of WDOG device.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 16-bit value.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      uint16_t result = WDOG_PDD_GetEnableDeviceStatus(deviceID);
 *      @endcode
 */
#define WDOG_PDD_GetEnableDeviceStatus(PeripheralBase) ( \
    (uint16_t)(WDOG_STCTRLH_REG(PeripheralBase) & WDOG_STCTRLH_WDOGEN_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- WriteControlHighReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the watchdog status and control register high.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the watchdog status and control register high.
 *        This parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      WDOG_PDD_WriteControlHighReg(deviceID, 1);
 *      @endcode
 */
#define WDOG_PDD_WriteControlHighReg(PeripheralBase, Value) ( \
    WDOG_STCTRLH_REG(PeripheralBase) = \
     (uint16_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadControlHighReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the watchdog status and control register high.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 16-bit value.
 * @remarks The macro accesses the following registers: WDOG_STCTRLH.
 * @par Example:
 *      @code
 *      uint16_t result = WDOG_PDD_ReadControlHighReg(deviceID);
 *      @endcode
 */
#define WDOG_PDD_ReadControlHighReg(PeripheralBase) ( \
    WDOG_STCTRLH_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt flag bit.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 16-bit value.
 * @remarks The macro accesses the following registers: WDOG_STCTRLL.
 * @par Example:
 *      @code
 *      uint16_t result = WDOG_PDD_GetInterruptFlag(deviceID);
 *      @endcode
 */
#define WDOG_PDD_GetInterruptFlag(PeripheralBase) ( \
    (uint16_t)(WDOG_STCTRLL_REG(PeripheralBase) & WDOG_STCTRLL_INTFLG_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClearInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_STCTRLL.
 * @par Example:
 *      @code
 *      WDOG_PDD_ClearInterruptFlag(deviceID);
 *      @endcode
 */
#define WDOG_PDD_ClearInterruptFlag(PeripheralBase) ( \
    WDOG_STCTRLL_REG(PeripheralBase) = \
     (uint16_t)(WDOG_STCTRLL_INTFLG_MASK | 0x1U) \
  )

/* ----------------------------------------------------------------------------
   -- WriteTimeOutHighReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the watchdog time-out value register high.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the watchdog time-out value register high. This
 *        parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_TOVALH.
 * @par Example:
 *      @code
 *      WDOG_PDD_WriteTimeOutHighReg(deviceID, 1);
 *      @endcode
 */
#define WDOG_PDD_WriteTimeOutHighReg(PeripheralBase, Value) ( \
    WDOG_TOVALH_REG(PeripheralBase) = \
     (uint16_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteTimeOutLowReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the watchdog time-out value register low.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the watchdog time-out value register low. This
 *        parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_TOVALL.
 * @par Example:
 *      @code
 *      WDOG_PDD_WriteTimeOutLowReg(deviceID, 1);
 *      @endcode
 */
#define WDOG_PDD_WriteTimeOutLowReg(PeripheralBase, Value) ( \
    WDOG_TOVALL_REG(PeripheralBase) = \
     (uint16_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteWindowHighReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the watchdog window register high.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the watchdog window register high. This parameter
 *        is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_WINH.
 * @par Example:
 *      @code
 *      WDOG_PDD_WriteWindowHighReg(deviceID, 1);
 *      @endcode
 */
#define WDOG_PDD_WriteWindowHighReg(PeripheralBase, Value) ( \
    WDOG_WINH_REG(PeripheralBase) = \
     (uint16_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteWindowLowReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the watchdog window register low.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the watchdog window register low. This parameter
 *        is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_WINL.
 * @par Example:
 *      @code
 *      WDOG_PDD_WriteWindowLowReg(deviceID, 1);
 *      @endcode
 */
#define WDOG_PDD_WriteWindowLowReg(PeripheralBase, Value) ( \
    WDOG_WINL_REG(PeripheralBase) = \
     (uint16_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteRefreshReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the watchdog refresh register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Service constant. Use constants from group "Refresh constants".
 *        This parameter is 16 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_REFRESH.
 * @par Example:
 *      @code
 *      WDOG_PDD_WriteRefreshReg(deviceID, WDOG_PDD_KEY_1);
 *      @endcode
 */
#define WDOG_PDD_WriteRefreshReg(PeripheralBase, Value) ( \
    WDOG_REFRESH_REG(PeripheralBase) = \
     (uint16_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteUnlockReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the watchdog unlock register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Unlock constant. Use constants from group "Unlock constants".
 *        This parameter is 16 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_UNLOCK.
 * @par Example:
 *      @code
 *      WDOG_PDD_WriteUnlockReg(deviceID, WDOG_PDD_UNLOCK_1);
 *      @endcode
 */
#define WDOG_PDD_WriteUnlockReg(PeripheralBase, Value) ( \
    WDOG_UNLOCK_REG(PeripheralBase) = \
     (uint16_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- SetPrescaler
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets prescale value.
 * @param PeripheralBase Peripheral base address.
 * @param Prescaler New value of the prescaler. Use constants from group
 *        "Prescaler constants". This parameter is 3 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WDOG_PRESC.
 * @par Example:
 *      @code
 *      WDOG_PDD_SetPrescaler(deviceID, WDOG_PDD_DIVIDE_1);
 *      @endcode
 */
#define WDOG_PDD_SetPrescaler(PeripheralBase, Prescaler) ( \
    WDOG_PRESC_REG(PeripheralBase) = \
     (uint16_t)((uint16_t)(Prescaler) << WDOG_PRESC_PRESCVAL_SHIFT) \
  )
#endif  /* #if defined(WDOG_PDD_H_) */

/* WDOG_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_bootloader/APP/USB_task.h<|end_filename|>
#ifndef _DFU_MOUSE_H
  #define _DFU_MOUSE_H



  #define  CONTROLLER_ID   (0)   /* ID to identify USB CONTROLLER */

/* #define UP_LEFT   This macro enables up and left mouse movement via PTG2-3*/
  #ifdef UP_LEFT
    #define SHIFT_VAL  (0xF8)    /* send -8 for up and left movement */
  #else
    #define SHIFT_VAL  (0x08)    /* send +8 for down and right movement */
  #endif

  #define  MOUSE_BUFF_SIZE   (4)    /* report buffer size */
  #define  REQ_DATA_SIZE     (1)
  #define  KBI_STAT_MASK     (0x0F)
  #define  LEFT_CLICK        (0x01) /* Left click */
  #define  RIGHT_CLICK       (0x02) /* Right click */
  #define  MOVE_LEFT_RIGHT   (0x04) /* Left-Right movement*/
  #define  MOVE_UP_DOWN      (0x08) /* Up-Down movement*/

extern INT8U g_dfu_mode;
extern void USB_App_init(void);
extern void USB_Class_DFU_task(void);
extern unsigned long *manifest_address;
#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/sem.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: sem.c$
 * $Version : 3.8.2.0$
 * $Date    : Jun-25-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Semaphore component.
 *
 *END************************************************************************/

#include <string.h>
#include "mqx_inc.h"
#if MQX_USE_SEMAPHORES
#include "name.h"
#include "name_prv.h"
#include "sem.h"
#include "sem_prv.h"
#include "mqx_str.h"

/*!
 * \brief Closes the connection to the semaphore.
 * 
 * \param[in] users_sem_ptr Semaphore handle from _sem_open() or _sem_open_fast().
 * 
 * \return MQX_OK 
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return SEM_INVALID_SEMAPHORE_HANDLE (Semaphore is no longer valid or sem_handle 
 * is not a valid semaphore connection)
 * \return Error from _mem_free() (Task is not the one that opened the connection.)
 * 
 * \warning If the semaphore is strict, posts the appropriate number of times to 
 * the semaphore for this connection.
 * \warning Might dispatch tasks that are waiting for the semaphore.
 * \warning Cannot be called from an ISR.
 * 
 * \see _sem_destroy
 * \see _sem_destroy_fast
 * \see _sem_open
 * \see _sem_open_fast 
 */ 
_mqx_uint _sem_close
(
    pointer users_sem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR    kernel_data;
    SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_sem_close, users_sem_ptr);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_sem_close, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)users_sem_ptr;
#if MQX_CHECK_ERRORS
    if (sem_connection_ptr->TD_PTR != kernel_data->ACTIVE_PTR)
    {
        _KLOGX2(KLOG_sem_close, SEM_INVALID_SEMAPHORE_HANDLE);
        return(SEM_INVALID_SEMAPHORE_HANDLE);
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (sem_connection_ptr->VALID != SEM_VALID)
    {
        _KLOGX2(KLOG_sem_close, SEM_INVALID_SEMAPHORE_HANDLE);
        return(SEM_INVALID_SEMAPHORE_HANDLE);
    } /* Endif */
#endif

    if (sem_connection_ptr->SEM_PTR->VALID)
    {
        /* Release all held semaphores */
        while (sem_connection_ptr->POST_STATE > 0)
        {
            _sem_post(sem_connection_ptr);
        } /* Endwhile */
    } /* Endif */

    sem_connection_ptr->VALID = 0;

    if (_mem_free(sem_connection_ptr) != MQX_OK)
    {
        _KLOGX2(KLOG_sem_close, kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
        return(kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
    }
    else
    {
        _KLOGX2(KLOG_sem_close, MQX_OK);
        return(MQX_OK);
    } /* Endif */

} /* Endbody */

/*!
 * \brief Creates the semaphore component.
 * 
 * If an application previously called the function and maximum_number is greater 
 * that what was specified, MQX changes the maximum number of semaphores to 
 * maximum_number.
 * \n If an application does not explicitly create the semaphore component, MQX 
 * does so with the following default values the first time that a task calls 
 * _sem_create() or _sem_create_fast().
 * \n Parameter default values:
 * \li Initial_number = 8(default)
 * \li Grow_number = 8(default)
 * \li Maximum_number = 0(unlimited)  
 * 
 * \param[in] initial_number Initial number of semaphores that can be created.
 * \param[in] grow_number    Number of semaphores to be added when the initial 
 * number have been created.
 * \param[in] maximum_number If grow_number is not 0, one of:
 * \li Maximum number of semaphores that can be created.
 * \li 0 (Unlimited number.)
 * 
 * \return MQX_OK (success)
 * \return MQX_OUT_OF_MEMORY (Failure: MQX cannot allocate memory for semaphore 
 * component data.) 
 * 
 * \warning On failure, the task error code might be set.
 * 
 * \see _sem_create
 * \see _sem_create_fast
 * \see _sem_open
 * \see _sem_open_fast
 * \see _task_set_error
 */ 
_mqx_uint _sem_create_component
(
    _mqx_uint initial_number,
    _mqx_uint grow_number,
    _mqx_uint maximum_number
)
{ /* Body */
    SEM_COMPONENT_STRUCT_PTR sem_component_ptr;
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    _mqx_uint                result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_sem_create_component, initial_number, grow_number, maximum_number);

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
    if (sem_component_ptr != NULL)
    {
        if (maximum_number > sem_component_ptr->MAXIMUM_NUMBER)
        {
            sem_component_ptr->MAXIMUM_NUMBER = maximum_number;
        } /* Endif */
        _KLOGX2(KLOG_sem_create_component, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    _mem_alloc_system_zero((_mem_size)sizeof(SEM_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (sem_component_ptr == NULL)
    {
        _KLOGX2(KLOG_sem_create_component, MQX_OUT_OF_MEMORY);
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(sem_component_ptr, MEM_TYPE_SEMAPHORE_COMPONENT);

    result = _name_create_handle_internal(&sem_component_ptr->NAME_TABLE_HANDLE,
                    initial_number, grow_number, maximum_number, initial_number);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (result != MQX_OK)
    {
        _mem_free(sem_component_ptr);
        _KLOGX2(KLOG_sem_create_component, result);
        return(result);
    } /* Endif */
#endif

    sem_component_ptr->GROW_NUMBER = grow_number;
    if (maximum_number == 0)
    {
        sem_component_ptr->MAXIMUM_NUMBER = MAX_MQX_UINT;
    }
    else if (maximum_number < initial_number)
    {
        sem_component_ptr->MAXIMUM_NUMBER = initial_number;
    }
    else
    {
        sem_component_ptr->MAXIMUM_NUMBER = maximum_number;
    } /* Endif */
    sem_component_ptr->VALID = SEM_VALID;

    _int_disable();
#if MQX_CHECK_ERRORS
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES] != NULL)
    {
        SEM_COMPONENT_STRUCT_PTR new_sem_component_ptr;

        new_sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
        if (maximum_number > new_sem_component_ptr->MAXIMUM_NUMBER)
        {
            new_sem_component_ptr->MAXIMUM_NUMBER = maximum_number;
        } /* Endif */
        _int_enable();
        _name_destroy_handle_internal(sem_component_ptr->NAME_TABLE_HANDLE);
        _mem_free(sem_component_ptr);
        _KLOGX2(KLOG_sem_create_component, MQX_OK);
        return(MQX_OK);
    } /* Endif */
#endif
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES] = sem_component_ptr;

#if MQX_COMPONENT_DESTRUCTION
    kernel_data->COMPONENT_CLEANUP[KERNEL_SEMAPHORES] = _sem_cleanup;
#endif

    _int_enable();

    _KLOGX2(KLOG_sem_create_component, MQX_OK);
    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Creates a named semaphore.
 * 
 * After the semaphore is created, tasks open a connection to it with _sem_open() 
 * and close the connection with _sem_close(). A named semaphore is destroyed 
 * with _sem_destroy().
 * <table>
 *   <tr>
 *     <td><b>Bit flag</b></td>
 *     <td><b>Set</b></td>
 *     <td><b>Not set</b></td>  
 *   </tr>
 *   <tr>
 *     <td><b>SEM_PRIORITY_INHERITANCE</b>(<b>SEM_STRICT</b> must also be set)</td>
 *     <td>If a task that waits for the semaphore has a higher priority than a 
 *     task that owns the semaphore, MQX boosts the priority of one of the owning 
 *     tasks to the priority of the waiting task. When the boosted task posts its 
 *     semaphore, MQX returns its priorities to its original values.</td>
 *     <td>MQX does not boost priorities</td>  
 *   </tr>
 *   <tr>
 *     <td><b>SEM_PRIORITY_QUEUEING</b></td>
 *     <td>Task that waits for the semaphore is queued according to the task's 
 *     priority. Within a priority, tasks are in FIFO order.</td>
 *     <td>Task that waits for the semaphore is queued in FIFO order.</td>  
 *   </tr>
 *   <tr>
 *     <td><b>SEM_STRICT</b></td>
 *     <td>Task must wait for the semaphore before it can post the semaphore.</td>
 *     <td>Task need not wait before posting.</td>  
 *   </tr>
 *   <tr>
 *     <td><b>SEM_STRICT</b></td>
 *     <td>Sem_count must be greater than or equal to 1.</td>
 *     <td>Sem_count must be greater than or equal to 0.</td>  
 *   </tr>     
 * </table> 
 * 
 * \param[in] name_ptr      Name by which to identify the semaphore.
 * \param[in] initial_count Number of requests that can concurrently have the 
 * semaphore.
 * \param[in] flags         Bit flags: 0 or as in Description.
 * 
 * \return MQX_OK (success)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Semaphore component was not created and 
 * cannot be created.)
 * \return MQX_INVALID_COMPONENT_BASE (Semaphore component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the semaphore.)  
 * \return SEM_INCORRECT_INITIAL_COUNT (sem_count cannot be 0 if SEM_STRICT is set.)
 * \return SEM_INVALID_POLICY (SEM_STRICT must be set if SEM_PRIORITY_INHERITANCE 
 * is set.)
 * \return SEM_SEMAPHORE_EXISTS (Semaphore with the name exists.)
 * \return SEM_SEMAPHORE_TABLE_FULL (Semaphore names database is full and cannot 
 * be expanded.)
 * 
 * \warning Creates the semaphore component with default values if it was not 
 * previously created.
 * \warning Cannot be called from an ISR.
 * \warning On failure, the task error code might be set.
 * 
 * \see _sem_create_component
 * \see _sem_destroy
 * \see _sem_destroy_fast
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_close
 * \see _task_set_error          
 */ 
_mqx_uint _sem_create
(
    char_ptr  name_ptr,
    _mqx_uint initial_count,
    _mqx_uint flags
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR            kernel_data;
    register SEM_COMPONENT_STRUCT_PTR sem_component_ptr;
    register SEM_STRUCT_PTR           sem_ptr;
    _mqx_uint                         result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_sem_create, name_ptr, initial_count, flags);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_sem_create, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (flags & SEM_STRICT)
    {
        if (initial_count == 0)
        {
            _KLOGX2(KLOG_sem_create, SEM_INCORRECT_INITIAL_COUNT);
            return(SEM_INCORRECT_INITIAL_COUNT);
        }/* Endif */
    }
    else
    {
        if (flags & SEM_PRIORITY_INHERITANCE)
        {
            _KLOGX2(KLOG_sem_create, SEM_INVALID_POLICY);
            return(SEM_INVALID_POLICY);
        } /* Endif */
    }/* Endif */
#endif

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
    if (sem_component_ptr == NULL)
    {
        result = _sem_create_component(SEM_DEFAULT_INITIAL_NUMBER,
                        SEM_DEFAULT_GROW_NUMBER, SEM_DEFAULT_MAXIMUM_NUMBER);
        sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (sem_component_ptr == NULL)
        {
            _KLOGX2(KLOG_sem_create, result);
            return(result);
        } /* Endif */
#endif
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (sem_component_ptr->VALID != SEM_VALID)
    {
        _KLOGX2(KLOG_sem_create, MQX_INVALID_COMPONENT_BASE);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    sem_ptr = (SEM_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(SEM_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (sem_ptr == NULL)
    {
        _KLOGX2(KLOG_sem_create, MQX_OUT_OF_MEMORY);
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(sem_ptr, MEM_TYPE_SEMAPHORE);

    sem_ptr->POLICY = flags;
    sem_ptr->COUNT = initial_count;
    if (flags & SEM_STRICT)
    {
        sem_ptr->MAX_COUNT = initial_count;
    }
    else
    {
        sem_ptr->MAX_COUNT = MAX_MQX_UINT;
    }/* Endif */
    _QUEUE_INIT(&sem_ptr->WAITING_TASKS, SEM_MAX_WAITING_TASKS);
    _QUEUE_INIT(&sem_ptr->OWNING_TASKS, SEM_MAX_WAITING_TASKS);

    result = _name_add_internal(sem_component_ptr->NAME_TABLE_HANDLE, name_ptr,
                    (_mqx_uint)sem_ptr);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        _mem_free(sem_ptr);
        if (result == NAME_EXISTS)
        {
            _KLOGX2(KLOG_sem_create, SEM_SEMAPHORE_EXISTS);
            return(SEM_SEMAPHORE_EXISTS);
        }
        else if (result == NAME_TABLE_FULL)
        {
            _KLOGX2(KLOG_sem_create, SEM_SEMAPHORE_TABLE_FULL);
            return(SEM_SEMAPHORE_TABLE_FULL);
        } /* Endif */
        _KLOGX2(KLOG_sem_create, result);
        return(result);
    } /* Endif */
#endif

    strncpy(sem_ptr->NAME, name_ptr, (_mqx_uint)NAME_MAX_NAME_SIZE-1);
    sem_ptr->NAME[NAME_MAX_NAME_SIZE-1] = '\0';

    sem_ptr->VALID = SEM_VALID;

    _KLOGX2(KLOG_sem_create, result);
    return(result);

} /* Endbody */

/*!
 * \brief Destroys the named semaphore.
 * 
 * <table>
 *   <tr>
 *     <td><b>force_destroy is TRUE</b></td>
 *     <td><b>force_destroy is FALSE</b></td> 
 *   </tr>
 *   <tr>
 *     <td> \li Tasks that are waiting for the semaphore are made ready.
 *     \li Semaphore is destroyed after all the owners post the semaphore.</td>
 *     <td> \li Semaphore is destroyed after the last waiting task gets and posts 
 *     the semaphore.
 *     \li This is the action if the semaphore is strict.</td> 
 *   </tr>  
 * </table>  
 * 
 * \param[in] name_ptr      Name of the semaphore to destroy, created using 
 * _sem_create().
 * \param[in] force_destroy A boolean flag, see Description.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Semaphore component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Semaphore component data is not valid.)
 * \return SEM_SEMAPHORE_NOT_FOUND (Name_ptr is not in the semaphore names database.)
 * \return SEM_INVALID_SEMAPHORE (Semaphore data that is associated with name or index is not valid.)
 * _name_find_internal
 * \return NAME_TOO_SHORT (Name is 0 lenght string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.) 
 * 
 * \warning Cannot be called from an ISR.
 *    
 * \see _sem_destroy_fast
 * \see _sem_close
 * \see _sem_create
 * \see _sem_create_fast 
 */ 
_mqx_uint _sem_destroy
(
    char_ptr name_ptr,
    boolean  force_destroy
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR            kernel_data;
    register SEM_COMPONENT_STRUCT_PTR sem_component_ptr;
    SEM_STRUCT_PTR                    sem_ptr;
    SEM_CONNECTION_STRUCT_PTR         sem_connection_ptr;
    QUEUE_STRUCT_PTR                  queue_ptr;
    TD_STRUCT_PTR                     td_ptr;
    _mqx_max_type                     tmp;
    _mqx_uint                         result;
    _mqx_uint                         i;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_sem_destroy, name_ptr, force_destroy);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_sem_destroy, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES] == NULL)
    {
        _KLOGX2(KLOG_sem_destroy, MQX_COMPONENT_DOES_NOT_EXIST);
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
#if MQX_CHECK_VALIDITY
    if (sem_component_ptr->VALID != SEM_VALID)
    {
        _KLOGX2(KLOG_sem_destroy, MQX_INVALID_COMPONENT_BASE);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    result = _name_find_internal(sem_component_ptr->NAME_TABLE_HANDLE,
                    name_ptr, &tmp);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        if (result == NAME_NOT_FOUND)
        {
            _KLOGX2(KLOG_sem_destroy, SEM_SEMAPHORE_NOT_FOUND);
            return(SEM_SEMAPHORE_NOT_FOUND);
        } /* Endif */
        _KLOGX2(KLOG_sem_destroy, result);
        return(result);
    } /* Endif */
#endif

    sem_ptr = (SEM_STRUCT_PTR)tmp;

    _int_disable();

#if MQX_CHECK_VALIDITY
    if (sem_ptr->VALID != SEM_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_sem_destroy, SEM_INVALID_SEMAPHORE);
        return(SEM_INVALID_SEMAPHORE);
    } /* Endif */
#endif

    queue_ptr = &sem_ptr->WAITING_TASKS;
    if (force_destroy)
    {
        /* Get rid of all waiting tasks */
        i = _QUEUE_GET_SIZE(queue_ptr) + 1;
        while (--i)
        {
            sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
            ((pointer)queue_ptr->NEXT);
            td_ptr = sem_connection_ptr->TD_PTR;
            if ((td_ptr->STATE & STATE_MASK)== SEM_BLOCKED)
            {
                _TIME_DEQUEUE(td_ptr,kernel_data);
                _task_set_error_td_internal(td_ptr,SEM_SEMAPHORE_DELETED);
                _TASK_READY(td_ptr,kernel_data);
            } /* Endif */
        } /* Endwhile */
    } /* Endif */

    if (
        ( (sem_ptr->POLICY & SEM_STRICT) &&
          (sem_ptr->COUNT == sem_ptr->MAX_COUNT) &&
          (_QUEUE_GET_SIZE(queue_ptr) == 0))
        ||
        ( (!(sem_ptr->POLICY & SEM_STRICT)) &&
          (_QUEUE_GET_SIZE(queue_ptr) == 0)))
    {
        /* Destroy the semaphore */
        sem_ptr->VALID = 0;

        _int_enable();

        /* May need to let higher priority task run */
        _CHECK_RUN_SCHEDULER();

        result = _name_delete_internal(sem_component_ptr->NAME_TABLE_HANDLE,
                        name_ptr);
        if (result == NAME_NOT_FOUND)
        {
            result = SEM_SEMAPHORE_NOT_FOUND;
        } /* Endif */
        _mem_free(sem_ptr);
    }
    else
    {
        sem_ptr->DELAYED_DESTROY = TRUE;

        _int_enable();

        /* May need to let higher priority task run */
        _CHECK_RUN_SCHEDULER();
    } /* Endif */

    _KLOGX2(KLOG_sem_destroy, result);
    return(result);

} /* Endbody */

/*!
 * \brief Creates the fast semaphore.
 * 
 * After the semaphore is created, tasks open a connection to it with 
 * _sem_open_fast() and close the connection with _sem_close(). A fast semaphore 
 * is destroyed with _sem_destroy_fast().
 * \n _sem_create_fast() access the semaphore via an index number rather than a 
 * name.
 * 
 * \param[in] sem_index     Number by which to identify the semaphore.
 * \param[in] initial_count Number of tasks that can concurrently have the semaphore.
 * \param[in] flags         Bit flags, as described for _sem_create().
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Semaphore component was not created and 
 * cannot be created.)
 * \return MQX_INVALID_COMPONENT_BASE (Semaphore component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the semaphore.)
 * \return SEM_SEMAPHORE_TABLE_FULL (Semaphore names database is full and cannot 
 * be expanded.)
 * \return SEM_SEMAPHORE_EXISTS (Semaphore with the name exists.)
 * \return SEM_INCORRECT_INITIAL_COUNT (Sem_count cannot be 0 if SEM_STRICT is set.)
 * \return SEM_INVALID_POLICY (SEM_STRICT must be set if SEM_PRIORITY_INHERITANCE 
 * is set.)  
 * 
 * \warning Creates the semaphore component with default values if it was not 
 * previously created.
 * \warning Cannot be called from an ISR.
 * \warning On failure, the task error code might be set.
 * 
 * \see _sem_create_component
 * \see _sem_destroy
 * \see _sem_destroy_fast
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_close
 * \see _sem_create 
 *         
 */ 
_mqx_uint _sem_create_fast
(
    _mqx_uint sem_index,
    _mqx_uint initial_count,
    _mqx_uint flags
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR            kernel_data;
    register SEM_COMPONENT_STRUCT_PTR sem_component_ptr;
    register SEM_STRUCT_PTR           sem_ptr;
    _mqx_uint                         result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_sem_create_fast, sem_index, initial_count, flags);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_sem_create_fast, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (flags & SEM_STRICT)
    {
        if (initial_count == 0)
        {
            _KLOGX2(KLOG_sem_create_fast, SEM_INCORRECT_INITIAL_COUNT);
            return(SEM_INCORRECT_INITIAL_COUNT);
        }/* Endif */
    }
    else
    {
        if (flags & SEM_PRIORITY_INHERITANCE)
        {
            _KLOGX2(KLOG_sem_create_fast, SEM_INVALID_POLICY);
            return(SEM_INVALID_POLICY);
        } /* Endif */
    }/* Endif */
#endif

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
    if (sem_component_ptr == NULL)
    {
        result = _sem_create_component(SEM_DEFAULT_INITIAL_NUMBER,
                        SEM_DEFAULT_GROW_NUMBER, SEM_DEFAULT_MAXIMUM_NUMBER);
        sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (sem_component_ptr == NULL)
        {
            _KLOGX2(KLOG_sem_create_fast, result);
            return(result);
        } /* Endif */
#endif
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (sem_component_ptr->VALID != SEM_VALID)
    {
        _KLOGX2(KLOG_sem_create_fast, MQX_INVALID_COMPONENT_BASE);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    sem_ptr = (SEM_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(SEM_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (sem_ptr == NULL)
    {
        _KLOGX2(KLOG_sem_create_fast, MQX_OUT_OF_MEMORY);
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(sem_ptr, MEM_TYPE_SEMAPHORE);

    sem_ptr->POLICY = flags;
    sem_ptr->COUNT = initial_count;
    if (flags & SEM_STRICT)
    {
        sem_ptr->MAX_COUNT = initial_count;
    }
    else
    {
        sem_ptr->MAX_COUNT = MAX_MQX_UINT;
    }/* Endif */
    _QUEUE_INIT(&sem_ptr->WAITING_TASKS, SEM_MAX_WAITING_TASKS);
    _QUEUE_INIT(&sem_ptr->OWNING_TASKS, SEM_MAX_WAITING_TASKS);

    _str_mqx_uint_to_hex_string(sem_index, sem_ptr->NAME);

    result = _name_add_internal_by_index(sem_component_ptr->NAME_TABLE_HANDLE,
                    sem_ptr->NAME, (_mqx_uint)sem_ptr, sem_index);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        _mem_free(sem_ptr);
        if (result == NAME_EXISTS)
        {
            _KLOGX2(KLOG_sem_create_fast, SEM_SEMAPHORE_EXISTS);
            return(SEM_SEMAPHORE_EXISTS);
        }
        else if (result == NAME_TABLE_FULL)
        {
            _KLOGX2(KLOG_sem_create_fast, SEM_SEMAPHORE_TABLE_FULL);
            return(SEM_SEMAPHORE_TABLE_FULL);
        } /* Endif */
        _KLOGX2(KLOG_sem_create_fast, result);
        return(result);
    } /* Endif */
#endif

    sem_ptr->VALID = SEM_VALID;

    _KLOGX2(KLOG_sem_create_fast, result);
    return(result);

} /* Endbody */

/*!
 * \brief Destroys the fast semaphore.
 * 
 * <table>
 *   <tr>
 *     <td><b>force_destroy is TRUE</b></td>
 *     <td><b>force_destroy is FALSE</b></td> 
 *   </tr>
 *   <tr>
 *     <td> \li Tasks that are waiting for the semaphore are made ready.
 *     \li Semaphore is destroyed after all the owners post the semaphore.</td>
 *     <td> \li Semaphore is destroyed after the last waiting task gets and posts 
 *     the semaphore.
 *     \li This is the action if the semaphore is strict.</td> 
 *   </tr>  
 * </table>  
 * 
 * \param[in] sem_index     Number that identifies the semaphore to destroy, 
 * created using _sem_create_fast().
 * \param[in] force_destroy A boolean flag, see Description.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Semaphore component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Semaphore component data is not valid.)
 * \return SEM_SEMAPHORE_NOT_FOUND (Name_ptr is not in the semaphore names database.)
 * \return SEM_INVALID_SEMAPHORE (Semaphore data that is associated with name or index is not valid.)
 * _name_find_internal_by_index
 * \return NAME_TOO_SHORT (Name is 0 lenght string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.) 
 * 
 * \warning Cannot be called from an ISR. 
 * 
 * \see _sem_destroy
 * \see _sem_close
 * \see _sem_create
 * \see _sem_create_fast
 */ 
_mqx_uint _sem_destroy_fast
(
    _mqx_uint sem_index,
    boolean   force_destroy
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR            kernel_data;
    register SEM_COMPONENT_STRUCT_PTR sem_component_ptr;
    SEM_STRUCT_PTR                    sem_ptr;
    SEM_CONNECTION_STRUCT_PTR         sem_connection_ptr;
    QUEUE_STRUCT_PTR                  queue_ptr;
    TD_STRUCT_PTR                     td_ptr;
    _mqx_max_type                     tmp;
    _mqx_uint                         result;
    _mqx_uint                         i;
#if MQX_CHECK_ERRORS
    char                              name[9];
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_sem_destroy_fast, sem_index, force_destroy);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_sem_destroy_fast, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES] == NULL)
    {
        _KLOGX2(KLOG_sem_destroy_fast, MQX_COMPONENT_DOES_NOT_EXIST);
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
#if MQX_CHECK_VALIDITY
    if (sem_component_ptr->VALID != SEM_VALID)
    {
        _KLOGX2(KLOG_sem_destroy_fast, MQX_INVALID_COMPONENT_BASE);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    result = _name_find_internal_by_index(sem_component_ptr->NAME_TABLE_HANDLE,
                    sem_index, &tmp);
    sem_ptr = (SEM_STRUCT_PTR)tmp;

#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        if (result == NAME_NOT_FOUND)
        {
            _KLOGX2(KLOG_sem_destroy_fast, SEM_SEMAPHORE_NOT_FOUND);
            return(SEM_SEMAPHORE_NOT_FOUND);
        } /* Endif */
        _KLOGX2(KLOG_sem_destroy_fast, result);
        return(result);
    } /* Endif */

    _str_mqx_uint_to_hex_string(sem_index, name);
    if (strncmp(name, sem_ptr->NAME, 8))
    {
        /* Name does not match */
        _KLOGX2(KLOG_sem_destroy_fast, SEM_SEMAPHORE_NOT_FOUND);
        return(SEM_SEMAPHORE_NOT_FOUND);
    } /* Endif */
#endif

    _int_disable();

#if MQX_CHECK_VALIDITY
    if (sem_ptr->VALID != SEM_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_sem_destroy_fast, SEM_INVALID_SEMAPHORE);
        return(SEM_INVALID_SEMAPHORE);
    } /* Endif */
#endif

    queue_ptr = &sem_ptr->WAITING_TASKS;

    if (force_destroy)
    {
        /* Get rid of all waiting tasks */
        i = _QUEUE_GET_SIZE(queue_ptr) + 1;
        while (--i)
        {
            sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
            ((pointer)queue_ptr->NEXT);
            td_ptr = sem_connection_ptr->TD_PTR;
            if ((td_ptr->STATE & STATE_MASK)== SEM_BLOCKED)
            {
                _TIME_DEQUEUE(td_ptr,kernel_data);
                _task_set_error_td_internal(td_ptr,SEM_SEMAPHORE_DELETED);
                _TASK_READY(td_ptr,kernel_data);
            } /* Endif */
        } /* Endwhile */
    } /* Endif */

    if (
        ( (sem_ptr->POLICY & SEM_STRICT) &&
          (sem_ptr->COUNT == sem_ptr->MAX_COUNT) &&
          (_QUEUE_GET_SIZE(queue_ptr) == 0))
        ||
        ( (!(sem_ptr->POLICY & SEM_STRICT)) &&
          (_QUEUE_GET_SIZE(queue_ptr) == 0)))
    {
        /* Destroy the semaphore */
        sem_ptr->VALID = 0;

        _int_enable();

        /* May need to let higher priority task run */
        _CHECK_RUN_SCHEDULER();

        result = _name_delete_internal_by_index(sem_component_ptr->NAME_TABLE_HANDLE,
                        sem_index);
        if (result == NAME_NOT_FOUND)
        {
            result = SEM_SEMAPHORE_NOT_FOUND;
        } /* Endif */
        _mem_free(sem_ptr);
    }
    else
    {
        sem_ptr->DELAYED_DESTROY = TRUE;

        _int_enable();

        /* May need to let higher priority task run */
        _CHECK_RUN_SCHEDULER();

    } /* Endif */

    _KLOGX2(KLOG_sem_destroy_fast, result);
    return(result);

} /* Endbody */

/*!
 * \brief Opens a connection to the fast semaphore.
 * 
 * \param[in]  sem_index        Number that identifies the semaphore that was 
 * created using _sem_create_fast().
 * \param[out] returned_sem_ptr Pointer to the semaphore handle, which is a 
 * connection to the semaphore.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Semaphore component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Semaphore component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the connection.)
 * \return SEM_SEMAPHORE_NOT_FOUND (Name is not in the semaphore names database.)
 * \return SEM_INVALID_SEMAPHORE (Data that is associated with the semaphore is 
 * not valid.)
 * \return SEM_SEMAPHORE_DELETED (Semaphore is in the process of being destroyed.)
 *   
 * \see _sem_open
 * \see _sem_close
 * \see _sem_create
 * \see _sem_post
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until
 */ 
_mqx_uint _sem_open_fast
(
    _mqx_uint     sem_index,
    pointer _PTR_ returned_sem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR             kernel_data;
    register SEM_COMPONENT_STRUCT_PTR  sem_component_ptr;
    SEM_STRUCT_PTR                     sem_ptr;
    register SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
    _mqx_uint                          result;
    _mqx_max_type                      tmp;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_sem_open_fast, sem_index, returned_sem_ptr);

    *returned_sem_ptr = NULL;

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
#if MQX_CHECK_ERRORS
    if (sem_component_ptr == NULL)
    {
        _KLOGX3(KLOG_sem_open_fast, MQX_COMPONENT_DOES_NOT_EXIST, 0);
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (sem_component_ptr->VALID != SEM_VALID)
    {
        _KLOGX3(KLOG_sem_open_fast, MQX_INVALID_COMPONENT_BASE, 0);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    result = _name_find_internal_by_index(sem_component_ptr->NAME_TABLE_HANDLE,
                    sem_index, &tmp);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        if (result == NAME_NOT_FOUND)
        {
            _KLOGX3(KLOG_sem_open_fast, SEM_SEMAPHORE_NOT_FOUND, 0);
            return(SEM_SEMAPHORE_NOT_FOUND);
        } /* Endif */
        _KLOGX3(KLOG_sem_open_fast, result, 0);
        return(result);
    } /* Endif */
#endif

    sem_ptr = (SEM_STRUCT_PTR)tmp;

#if MQX_CHECK_ERRORS
    if (sem_ptr->VALID != SEM_VALID)
    {
        /* Semaphore not valid */
        _KLOGX3(KLOG_sem_open_fast, SEM_INVALID_SEMAPHORE, 0);
        return(SEM_INVALID_SEMAPHORE);
    } /* Endif */
#endif

#if MQX_COMPONENT_DESTRUCTION
    if (sem_ptr->DELAYED_DESTROY)
    {
        /* Semaphore in delayed destroy state */
        _KLOGX3(KLOG_sem_open_fast, SEM_SEMAPHORE_DELETED, 0);
        return(SEM_SEMAPHORE_DELETED);
    } /* Endif */
#endif

    sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)_mem_alloc_zero(
                    (_mem_size)sizeof(SEM_CONNECTION_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (sem_connection_ptr == NULL)
    {
        _KLOGX3(KLOG_sem_open_fast, MQX_OUT_OF_MEMORY, 0);
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(sem_connection_ptr, MEM_TYPE_SEMAPHORE_CONNECTION);

    sem_connection_ptr->SEM_PTR = sem_ptr;
    sem_connection_ptr->VALID = SEM_VALID;
    sem_connection_ptr->TD_PTR = kernel_data->ACTIVE_PTR;

    *returned_sem_ptr = (pointer)sem_connection_ptr;

    _KLOGX3(KLOG_sem_open_fast, MQX_OK, sem_connection_ptr);
    return(MQX_OK);

} /* Endbody */

/*!
 * \private
 * 
 * \brief This function inserts a connection pointer by priority onto a queue.
 * 
 * \param[in] queue_ptr          The queue to insert the member into.
 * \param[in] sem_connection_ptr The connection pointer to insert into the queue. 
 */ 
void _sem_insert_priority_internal
(
    QUEUE_STRUCT_PTR          queue_ptr,
    SEM_CONNECTION_STRUCT_PTR sem_connection_ptr
)
{ /* Body */
    SEM_CONNECTION_STRUCT_PTR conn2_ptr;
    SEM_CONNECTION_STRUCT_PTR conn_prev_ptr;
    _mqx_uint                 count;
    _mqx_uint                 priority;

    conn_prev_ptr = (SEM_CONNECTION_STRUCT_PTR)((pointer)queue_ptr);
    conn2_ptr = (SEM_CONNECTION_STRUCT_PTR)((pointer)queue_ptr->NEXT);
    count = _QUEUE_GET_SIZE(queue_ptr) + 1;
    priority = sem_connection_ptr->TD_PTR->MY_QUEUE->PRIORITY;
    while (--count)
    {
        if (conn2_ptr->TD_PTR->MY_QUEUE->PRIORITY > priority)
        {
            break;
        } /* Endif */
        conn_prev_ptr = conn2_ptr;
        conn2_ptr = (SEM_CONNECTION_STRUCT_PTR)conn2_ptr->NEXT;
    } /* Endwhile */
    _QUEUE_INSERT(queue_ptr, conn_prev_ptr, sem_connection_ptr);

} /* Endbody */

/*!
 * \brief Opens a connection to the named semaphore.
 * 
 * \param[in]  name_ptr         Name that identifies the semaphore that was created 
 * using _sem_create().
 * \param[out] returned_sem_ptr Pointer to the semaphore handle, which is a 
 * connection to the semaphore.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Semaphore component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Semaphore component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the connection.)
 * \return SEM_SEMAPHORE_NOT_FOUND (Name is not in the semaphore names database.)
 * \return SEM_INVALID_SEMAPHORE (Data that is associated with the semaphore is 
 * not valid.)
 * \return SEM_SEMAPHORE_DELETED (Semaphore is in the process of being destroyed.)
 *   
 * \see _sem_open_fast
 * \see _sem_close
 * \see _sem_create
 * \see _sem_post
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until
 */
_mqx_uint _sem_open
(
    char_ptr      name_ptr,
    pointer _PTR_ returned_sem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR             kernel_data;
    register SEM_COMPONENT_STRUCT_PTR  sem_component_ptr;
    SEM_STRUCT_PTR                     sem_ptr;
    register SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
    _mqx_max_type                      tmp;
    _mqx_uint                          result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_sem_open, name_ptr, returned_sem_ptr);

    *returned_sem_ptr = NULL;

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
#if MQX_CHECK_ERRORS
    if (sem_component_ptr == NULL)
    {
        _KLOGX3(KLOG_sem_open, MQX_COMPONENT_DOES_NOT_EXIST, 0);
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (sem_component_ptr->VALID != SEM_VALID)
    {
        _KLOGX3(KLOG_sem_open, MQX_INVALID_COMPONENT_BASE, 0);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    result = _name_find_internal(sem_component_ptr->NAME_TABLE_HANDLE,
                    name_ptr, &tmp);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        if (result == NAME_NOT_FOUND)
        {
            _KLOGX3(KLOG_sem_open, SEM_SEMAPHORE_NOT_FOUND, NULL);
            return(SEM_SEMAPHORE_NOT_FOUND);
        } /* Endif */
        _KLOGX3(KLOG_sem_open, result, 0);
        return(result);
    } /* Endif */
#endif

    sem_ptr = (SEM_STRUCT_PTR)tmp;

#if MQX_CHECK_VALIDITY
    if (sem_ptr->VALID != SEM_VALID)
    {
        /* Semaphore not valid */
        _KLOGX2(KLOG_sem_open, SEM_INVALID_SEMAPHORE);
        return(SEM_INVALID_SEMAPHORE);
    } /* Endif */
#endif

#if MQX_COMPONENT_DESTRUCTION
    if (sem_ptr->DELAYED_DESTROY)
    {
        /* Semaphore in delayed destroy state */
        _KLOGX3(KLOG_sem_open, SEM_SEMAPHORE_DELETED, 0);
        return(SEM_SEMAPHORE_DELETED);
    } /* Endif */
#endif

    sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
    _mem_alloc_zero((_mem_size)sizeof(SEM_CONNECTION_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (sem_connection_ptr == NULL)
    {
        _KLOGX3(KLOG_sem_open, MQX_OUT_OF_MEMORY, 0);
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(sem_connection_ptr, MEM_TYPE_SEMAPHORE_CONNECTION);

    sem_connection_ptr->SEM_PTR = sem_ptr;
    sem_connection_ptr->VALID = SEM_VALID;
    sem_connection_ptr->TD_PTR = kernel_data->ACTIVE_PTR;

    *returned_sem_ptr = (pointer)sem_connection_ptr;

    _KLOGX3(KLOG_sem_open, MQX_OK, sem_connection_ptr);
    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Returns a semaphore to the semaphore, so another task may use it.
 * 
 * MQX gives the semaphore to the first waiting task and puts the task in the 
 * task's ready queue.
 * 
 * \param[in] users_sem_ptr Semaphore handle from _sem_open() or _sem_open_fast().
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return SEM_INVALID_SEMAPHORE_HANDLE (One of the following:
 * \li Sem_handle is not a valid semaphore handle.
 * \li Semaphore is strict and sem_handle was obtained byanother task.)
 * \return SEM_CANNOT_POST (Semaphore is strict and the task has not first waited 
 * for the semaphore.)
 * \return SEM_INVALID_SEMAPHORE (Sem_handle represents a semaphore that is no 
 * longer valid.)
 * \return SEM_INVALID_SEMAPHORE_COUNT (Semaphore data are corrupted.)
 * 
 * \warning Might put a task in its ready queue.
 * \warning For a strict semaphore, cannot be called from an ISR (ISR can call 
 * the function for a non-strict semaphore).
 * 
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_get_wait_count
 * \see _sem_get_value
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until      
 */ 
_mqx_uint _sem_post
(
    pointer users_sem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR    kernel_data;
    SEM_STRUCT_PTR            sem_ptr;
#if MQX_COMPONENT_DESTRUCTION
    SEM_COMPONENT_STRUCT_PTR  sem_component_ptr;
#endif
    SEM_CONNECTION_STRUCT_PTR new_sem_connection_ptr;
    SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
    TD_STRUCT_PTR             new_td_ptr;
    boolean                   task_added = FALSE;
    boolean                   destroying_semaphore = FALSE;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_sem_post, users_sem_ptr);

    sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)users_sem_ptr;

#if MQX_CHECK_VALIDITY
    if (sem_connection_ptr->VALID != SEM_VALID)
    {
        _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_HANDLE);
        return(SEM_INVALID_SEMAPHORE_HANDLE);
    } /* Endif */
#endif

    sem_ptr = sem_connection_ptr->SEM_PTR;

#if MQX_CHECK_ERRORS
    if (sem_ptr->POLICY & SEM_STRICT)
    {
        if (kernel_data->IN_ISR)
        {
            _KLOGX2(KLOG_sem_post, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
            return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        } /* Endif */

        if (sem_connection_ptr->TD_PTR != kernel_data->ACTIVE_PTR)
        {
            /* ONLY OPENING task can use the semaphore */
            _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_HANDLE);
            return(SEM_INVALID_SEMAPHORE_HANDLE);
        } /* Endif */

        if (sem_connection_ptr->POST_STATE == 0)
        {
            _KLOGX2(KLOG_sem_post, SEM_CANNOT_POST);
            return(SEM_CANNOT_POST);
        } /* Endif */
    } /* Endif */
#endif

    _INT_DISABLE();

#if MQX_CHECK_VALIDITY
    if (sem_ptr->VALID != SEM_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE);
        return(SEM_INVALID_SEMAPHORE);
    } /* Endif */
#endif

    if (sem_ptr->POLICY & SEM_STRICT)
    {
#if MQX_CHECK_ERRORS
        if (sem_ptr->COUNT > sem_ptr->MAX_COUNT)
        {
            /* Corruption somewhere */
            _int_enable();
            _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_COUNT);
            return(SEM_INVALID_SEMAPHORE_COUNT);
        } /* Endif */
#endif

        --sem_connection_ptr->POST_STATE;
        if (sem_connection_ptr->POST_STATE == 0)
        {
            _QUEUE_REMOVE(&sem_ptr->OWNING_TASKS, sem_connection_ptr);
        } /* Endif */
    } /* Endif */

    if (_QUEUE_GET_SIZE(&sem_ptr->WAITING_TASKS))
    {
        /* Schedule a waiting task to run */

        new_sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
        ((pointer)sem_ptr->WAITING_TASKS.NEXT);
        while (new_sem_connection_ptr != (pointer)&sem_ptr->WAITING_TASKS)
        {
            new_td_ptr = new_sem_connection_ptr->TD_PTR;
            if ((new_td_ptr->STATE & STATE_MASK) == SEM_BLOCKED)
            {
                _TIME_DEQUEUE(new_td_ptr, kernel_data);
                _TASK_READY(new_td_ptr, kernel_data);
                new_td_ptr->INFO = SEM_AVAILABLE;
                task_added = TRUE;
                break;
            } /* Endif */
            new_sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
            new_sem_connection_ptr->NEXT;
        } /* Endwhile */

    } /* Endif */

    if (!task_added)
    {

        ++sem_ptr->COUNT;

#if MQX_COMPONENT_DESTRUCTION
        if ( sem_ptr->DELAYED_DESTROY )
        {
            if ( ( (sem_ptr->POLICY & SEM_STRICT) &&
                   (sem_ptr->COUNT == sem_ptr->MAX_COUNT) ) ||
                 ( !(sem_ptr->POLICY & SEM_STRICT) ) )
            {
                /* Destroy the semaphore name */
                sem_ptr->VALID = 0;
                destroying_semaphore = TRUE;
            } /* Endif */
        } /* Endif */
#endif
    } /* Endif */

    if (sem_connection_ptr->BOOSTED && (sem_connection_ptr->POST_STATE == 0))
    {
        /* This task was boosted by a waiting task */
        _sched_unboost_priority_internal(kernel_data->ACTIVE_PTR,
                        sem_connection_ptr->BOOSTED);
        sem_connection_ptr->BOOSTED = 0;
    } /* Endif */

    _INT_ENABLE();

    /* Let higher priority task run */
    _CHECK_RUN_SCHEDULER();

#if MQX_COMPONENT_DESTRUCTION
    if (destroying_semaphore)
    {
        sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
        if (sem_component_ptr != NULL)
        {
            _name_delete_internal(sem_component_ptr->NAME_TABLE_HANDLE,
                                  sem_ptr->NAME);
        } /* Endif */
        _mem_free(sem_ptr);
    } /* Endif */
#endif

    _KLOGX2(KLOG_sem_post, MQX_OK);
    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Used during task destruction to free up any semaphore resources owned 
 * by this task.
 * 
 * \param[in] td_ptr The task being destroyed. 
 */ 
void _sem_cleanup
(
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
    SEM_CONNECTION_STRUCT_PTR connection_ptr;
    SEM_STRUCT_PTR            sem_ptr;

    connection_ptr = _mem_get_next_block_internal(td_ptr, NULL);
    while (connection_ptr)
    {
        if ((connection_ptr->VALID == SEM_VALID) &&
                        (connection_ptr->TD_PTR == td_ptr) )
        {
            sem_ptr = connection_ptr->SEM_PTR;
            if (sem_ptr->VALID == SEM_VALID)
            {
                /* Check if the connection is on the queue */
                _int_disable();
                sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
                ((pointer)sem_ptr->WAITING_TASKS.NEXT);
                while (sem_connection_ptr != (pointer)&sem_ptr->WAITING_TASKS.NEXT)
                {
                    if (sem_connection_ptr == connection_ptr)
                    {
                        /* Connection is queued, so dequeue it */
                        _QUEUE_REMOVE(&sem_ptr->WAITING_TASKS, connection_ptr);
                        break;
                    }/* Endif */
                    sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
                    sem_connection_ptr->NEXT;
                } /* Endwhile */
                if (sem_ptr->POLICY & SEM_STRICT)
                {
                    while (connection_ptr->POST_STATE)
                    {
                        _sem_post(connection_ptr);
                    } /* Endwhile */
                }/* Endif */
                _int_enable();
            }/* Endif */
        } /* Endif */
        connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
        _mem_get_next_block_internal(td_ptr, connection_ptr);
    } /* Endwhile */

} /* Endbody */

/*!
 * \brief Tests the semaphore component for validity and consistency.
 * 
 * The function does the following:
 * \li Verifies semaphore component data.
 * \li Verifies the integrity of the entries in the semaphore names database.
 * \li For each semaphore, checks: validity of data (VALID field), integrity of 
 * the queue of waiting tasks and integrity of the queue of tasks that have the 
 * semaphore.
 * 
 * \param[out] sem_error_ptr Pointer to the semaphore that has an error (NULL if 
 * no errors are found).
 * 
 * \return MQX_OK (No errors were found.)
 * \return MQX_CORRUPT_QUEUE (Error was found in a semaphore queue.) 
 * \return MQX_INVALID_COMPONENT_BASE (Error was found in semaphore component data.)
 * \return SEM_INVALID_SEMAPHORE (Error was found in semaphore data.)
 * 
 * \warning Disables and enables interrupts.
 * 
 * \see _sem_close
 * \see _sem_create
 * \see _sem_create_fast
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_post
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until 
 */ 
_mqx_uint _sem_test
(
    pointer _PTR_ sem_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    SEM_COMPONENT_STRUCT_PTR sem_component_ptr;
    SEM_STRUCT_PTR           sem_ptr;
    pointer                  table_ptr;
    _mqx_max_type            data;
    _mqx_uint                result;
    _mqx_uint                i;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_sem_test, sem_error_ptr);

    *sem_error_ptr = NULL;

    sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
    if (sem_component_ptr == NULL)
    {
        _KLOGX3(KLOG_sem_test, MQX_OK, 0);
        return(MQX_OK);
    } /* Endif */

    if (sem_component_ptr->VALID != SEM_VALID)
    {
        _KLOGX3(KLOG_sem_test, MQX_INVALID_COMPONENT_BASE, 0);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    _int_disable();
    /* Test the semaphore name table */
    result = _name_test_internal((NAME_COMPONENT_STRUCT_PTR)
                    sem_component_ptr->NAME_TABLE_HANDLE, &table_ptr, sem_error_ptr);
    _int_enable();
    if (result != MQX_OK)
    {
        _KLOGX3(KLOG_sem_test, MQX_INVALID_COMPONENT_BASE, *sem_error_ptr);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    i = 0;
    while (TRUE)
    {
        _int_disable();
        result = _name_find_internal_by_index(
                        sem_component_ptr->NAME_TABLE_HANDLE, i++, &data);
        if (result != MQX_OK)
        {
            result = MQX_OK;
            break;
        } /* Endif */

        sem_ptr = (SEM_STRUCT_PTR)data;
        if (sem_ptr->VALID != SEM_VALID)
        {
            result = SEM_INVALID_SEMAPHORE;
            break;
        } /* Endif */
        result = _queue_test(&sem_ptr->WAITING_TASKS, sem_error_ptr);
        if (result != MQX_OK)
        {
            break;
        } /* Endif */
        result = _queue_test(&sem_ptr->OWNING_TASKS, sem_error_ptr);
        if (result != MQX_OK)
        {
            break;
        } /* Endif */
        _int_enable();

    } /* Endwhile */

    _int_enable();

    _KLOGX3(KLOG_sem_test, result, *sem_error_ptr);
    return(result);

} /* Endbody */

/*!
 * \brief Gets the value of the semaphore counter; that is, the number of 
 * subsequent requests that can get the semaphore without waiting.
 * 
 * \param[in] users_sem_ptr Semaphore handle from _sem_open() or _sem_open_fast().
 * 
 * \return Current value of the semaphore counter (success).
 * \return MAX_MQX_UINT (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li SEM_INVALID_SEMAPHORE_HANDLE (Sem_ptr is not a valid semaphore handle.)
 * \li SEM_INVALID_SEMAPHORE (Sem_ptr does not point to a valid semaphore.)
 * 
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_post
 * \see _sem_get_wait_count
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until 
 * \see _task_set_error
 */ 
_mqx_uint _sem_get_value
(
    pointer users_sem_ptr
)
{ /* Body */
    register SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
    register SEM_STRUCT_PTR            sem_ptr;

    sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)users_sem_ptr;
#if MQX_CHECK_VALIDITY
    if (sem_connection_ptr->VALID != SEM_VALID)
    {
        _task_set_error(SEM_INVALID_SEMAPHORE_HANDLE);
        return(MAX_MQX_UINT);
    } /* Endif */
#endif

    sem_ptr = sem_connection_ptr->SEM_PTR;
#if MQX_CHECK_VALIDITY
    if (sem_ptr->VALID != SEM_VALID)
    {
        _task_set_error(SEM_INVALID_SEMAPHORE);
        return(MAX_MQX_UINT);
    } /* Endif */
#endif

    return(sem_ptr->COUNT);

} /* Endbody */

/*!
 * \brief Gets the number of tasks that are waiting for the semaphore.
 * 
 * \param[in] users_sem_ptr Semaphore handle from _sem_open() or _sem_open_fast().
 * 
 * \return Number of tasks waiting for the semaphore (success).
 * \return MAX_MQX_UINT (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the task error codes 
 * described for _sem_get_value().
 *               
 * \see _sem_get_value 
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_post
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until 
 * \see _task_set_error  
 */ 
_mqx_uint _sem_get_wait_count
(
    pointer users_sem_ptr
)
{ /* Body */
    register SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
    register SEM_STRUCT_PTR            sem_ptr;

    sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)users_sem_ptr;
#if MQX_CHECK_VALIDITY
    if (sem_connection_ptr->VALID != SEM_VALID)
    {
        _task_set_error(SEM_INVALID_SEMAPHORE_HANDLE);
        return(MAX_MQX_UINT);
    } /* Endif */
#endif

    sem_ptr = sem_connection_ptr->SEM_PTR;
#if MQX_CHECK_VALIDITY
    if (sem_ptr->VALID != SEM_VALID)
    {
        _task_set_error(SEM_INVALID_SEMAPHORE);
        return(MAX_MQX_UINT);
    } /* Endif */
#endif

    return(_QUEUE_GET_SIZE(&(sem_ptr->WAITING_TASKS)));

} /* Endbody */

/*!
 * \private
 * 
 * \brief This function waits for a semaphore to become available. If one is not
 * the task is queued according to the queueing policy for this semaphore.
 *   
 * \param[in] users_sem_ptr      Semaphore handle from _sem_open() or 
 * _sem_open_fast().
 * \param[in] tick_ptr           One of the following:
 * \li Pointer to the maximum number of ticks to wait.
 * \li NULL (Unlimited wait.)
 * \param[in] ticks_are_absolute Specifies whether the wait time specified in 
 * ticks represents absolute or relative time.
 *  
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_EDEADLK (Function was aborted to prevent deadlock: the task has 
 * all the semaphore locks and, since the semaphore is strict, the task cannot 
 * post to "wake" itself.)
 * \return SEM_INVALID_SEMAPHORE_HANDLE (One of the following:
 * \li Sem_handle is not a valid semaphore handle.
 * \li Sem_handle was obtained by another task.)
 * \return SEM_INVALID_SEMAPHORE (Sem_handle is for a semaphore that is no longer 
 * valid.)
 * \return SEM_SEMAPHORE_DELETED (MQX is in the process of destroying the semaphore.)
 * \return SEM_WAIT_TIMEOUT (Timeout expired before the task can get the semaphore.)
 */ 
_mqx_uint _sem_wait_internal
(
    pointer             users_sem_ptr,
    MQX_TICK_STRUCT_PTR tick_ptr,
    boolean             ticks_are_absolute

)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR             kernel_data;
    TD_STRUCT_PTR                      td_ptr;
    SEM_STRUCT_PTR                     sem_ptr;
    register SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
    register SEM_CONNECTION_STRUCT_PTR list_connection_ptr;
    SEM_CONNECTION_STRUCT_PTR          saved_connection_ptr;
    _mqx_uint                          priority;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)users_sem_ptr;

#if MQX_CHECK_VALIDITY
    if (sem_connection_ptr->VALID != SEM_VALID)
    {
        return(SEM_INVALID_SEMAPHORE_HANDLE);
    } /* Endif */
#endif

    sem_ptr = sem_connection_ptr->SEM_PTR;
    td_ptr = kernel_data->ACTIVE_PTR;

#if MQX_CHECK_ERRORS
    if (sem_connection_ptr->TD_PTR != td_ptr)
    {
        /* Only OPENING task can wait on the semaphore */
        return(SEM_INVALID_SEMAPHORE_HANDLE);
    } /* Endif */
#endif

    _INT_DISABLE();

#if MQX_CHECK_VALIDITY
    if (sem_ptr->VALID != SEM_VALID)
    {
        _int_enable();
        return(SEM_INVALID_SEMAPHORE);
    } /* Endif */
#endif

    if (sem_ptr->COUNT == 0)
    {

        /* Must wait for a semaphore to become available */
        if (sem_ptr->POLICY & SEM_STRICT)
        {

            /* 
             * First check for deadlock... See if this task already
             * owns all the semaphores, thus cannot post to wake itself up
             */
            if (sem_connection_ptr->POST_STATE == sem_ptr->MAX_COUNT)
            {
                _int_enable();
                return(MQX_EDEADLK);
            } /* Endif */

            /* 
             * May need to raise priorities of one task with semaphore,
             * If the current task has a higher priority.
             */
            if ((sem_ptr->POLICY & SEM_PRIORITY_INHERITANCE) &&
                            (_QUEUE_GET_SIZE(&sem_ptr->OWNING_TASKS) > 0))
            {

                /* Find owning task with highest priority */
                list_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
                ((pointer)sem_ptr->OWNING_TASKS.NEXT);
                saved_connection_ptr = list_connection_ptr;
                priority = kernel_data->LOWEST_TASK_PRIORITY;
                while ((pointer)list_connection_ptr !=
                                (pointer)&sem_ptr->OWNING_TASKS)
                {
                    if (list_connection_ptr->TD_PTR->MY_QUEUE->PRIORITY < priority)
                    {
                        priority = list_connection_ptr->TD_PTR->MY_QUEUE->PRIORITY;
                        saved_connection_ptr = list_connection_ptr;
                    } /* Endif */
                    list_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
                    list_connection_ptr->NEXT;
                } /* Endwhile */

                if (priority > td_ptr->HOME_QUEUE->PRIORITY)
                {
                    if (priority > td_ptr->MY_QUEUE->PRIORITY)
                    {
                        /* Not high enough, boost the tasks priority */
                        _sched_boost_priority_internal(saved_connection_ptr->TD_PTR,
                                        (_mqx_uint)td_ptr->MY_QUEUE->PRIORITY);
                    } /* Endif */
                    saved_connection_ptr->BOOSTED++;
                } /* Endif */
            } /* Endif */
        } /* Endif */

        if (sem_ptr->POLICY & SEM_PRIORITY_QUEUEING)
        {
            /* 
             * We must insert the waiting task into the waiting list in order
             * of the priority of the waiting task.
             */
            _sem_insert_priority_internal(&sem_ptr->WAITING_TASKS, sem_connection_ptr);
        }
        else
        {
            /* Enqueue at end */
            _QUEUE_ENQUEUE(&sem_ptr->WAITING_TASKS, sem_connection_ptr);
        } /* Endif */

        /* Now put the task to sleep */
        td_ptr->STATE = SEM_BLOCKED;
        td_ptr->INFO = SEM_WANT_SEMAPHORE;
        /* Indicate wanting semaphore */

        if (tick_ptr)
        {

            if (ticks_are_absolute)
            {
                _time_delay_until(tick_ptr);
            }
            else
            {
                _time_delay_for(tick_ptr);
            } /* Endif */

#if MQX_COMPONENT_DESTRUCTION
            if (sem_ptr->VALID != SEM_VALID)
            {
                _int_enable();
                return(SEM_SEMAPHORE_DELETED);
            } /* Endif */
#endif

            _QUEUE_REMOVE(&sem_ptr->WAITING_TASKS, sem_connection_ptr);

            if (td_ptr->INFO != SEM_AVAILABLE)
            {
                td_ptr->INFO = 0;
                _INT_ENABLE();
                return(SEM_WAIT_TIMEOUT);
            } /* Endif */

        }
        else
        {

            _task_block();

#if MQX_COMPONENT_DESTRUCTION
            if (sem_ptr->VALID != SEM_VALID)
            {
                _int_enable();
                return(SEM_SEMAPHORE_DELETED);
            } /* Endif */
#endif
            _QUEUE_REMOVE(&sem_ptr->WAITING_TASKS, sem_connection_ptr);

#if MQX_COMPONENT_DESTRUCTION
            if (td_ptr->INFO != SEM_AVAILABLE)
            {
                td_ptr->INFO = 0;
                _INT_ENABLE();
                return(SEM_SEMAPHORE_DELETED);
            } /* Endif */
#endif

        } /* Endif */

    }
    else
    {
        --sem_ptr->COUNT;
    } /* Endif */

    if (sem_ptr->POLICY & SEM_STRICT)
    {
        if (sem_connection_ptr->POST_STATE == 0)
        {
            _QUEUE_ENQUEUE(&sem_ptr->OWNING_TASKS, sem_connection_ptr);
        } /* Endif */
        sem_connection_ptr->POST_STATE++; /* # of posts allowed to do */
    } /* Endif */

    _INT_ENABLE();

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Wait for the semaphore for the specified number of milliseconds.
 * 
 * If the task cannot get the semaphore, MQX queues the task according to the 
 * semaphore's queuing policy, which is set when the semaphore is created.
 * 
 * \param[in] users_sem_ptr Semaphore handle from _sem_open() or _sem_open_fast().
 * \param[in] timeout       One of the following:
 * \li Maximum number of milliseconds to wait.
 * \li 0 (Unlimited wait.)
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_EDEADLK (Function was aborted to prevent deadlock: the task has 
 * all the semaphore locks and, since the semaphore is strict, the task cannot 
 * post to  "wake" itself.)
 * \return SEM_INVALID_SEMAPHORE_HANDLE (One of the following:
 * \li Sem_handle is not a valid semaphore handle.
 * \li Sem_handle was obtained by another task.)
 * \return SEM_INVALID_SEMAPHORE (Sem_handle is for a semaphore that is no longer 
 * valid.)
 * \return SEM_SEMAPHORE_DELETED (MQX is in the process of destroying the semaphore.)
 * \return SEM_WAIT_TIMEOUT (Timeout expired before the task can get the semaphore.)
 * 
 * \warning Might block the calling task.
 * \warning Cannot be called from an ISR.
 * 
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_post
 * \see _sem_get_wait_count
 * \see _sem_get_value
 * \see _sem_create
 * \see _sem_create_fast
 * \see MQX_TICK_STRUCT
 */ 
_mqx_uint _sem_wait
(
    pointer users_sem_ptr,
    uint_32 timeout
)
{ /* Body */
    /* TIME_STRUCT                 time; */
    MQX_TICK_STRUCT ticks;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE3(KLOG_sem_wait, users_sem_ptr, timeout);

    if (timeout)
    {
        /* Convert milliseconds to ticks */
        /* time.MILLISECONDS = timeout % 1000; */
        /* time.SECONDS      = timeout / 1000; */
        /*                                     */
        /* PSP_TIME_TO_TICKS(&time, &ticks);   */
        PSP_MILLISECONDS_TO_TICKS_QUICK(timeout, &ticks);

        result = _sem_wait_internal(users_sem_ptr, &ticks, FALSE);
    }
    else
    {
        result = _sem_wait_internal(users_sem_ptr, NULL, FALSE);
    } /* Endif */

    _KLOGX2(KLOG_sem_wait, result);
    return(result);

} /* Endbody */

/*!
 * \brief Wait for the semaphore for the specified number of ticks (in tick time).
 * 
 * If the task cannot get the semaphore, MQX queues the task according to the 
 * semaphore's queuing policy, which is set when the semaphore is created.
 * 
 * \param[in] users_sem_ptr Semaphore handle from _sem_open() or _sem_open_fast().
 * \param[in] tick_ptr      One of the following:
 * \li Pointer to the maximum number of ticks to wait.
 * \li NULL (Unlimited wait.)
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_EDEADLK (Function was aborted to prevent deadlock: the task has 
 * all the semaphore locks and, since the semaphore is strict, the task cannot 
 * post to  "wake" itself.)
 * \return SEM_INVALID_SEMAPHORE_HANDLE (One of the following:
 * \li Sem_handle is not a valid semaphore handle.
 * \li Sem_handle was obtained by another task.)
 * \return SEM_INVALID_SEMAPHORE (Sem_handle is for a semaphore that is no longer 
 * valid.)
 * \return SEM_SEMAPHORE_DELETED (MQX is in the process of destroying the semaphore.)
 * \return SEM_WAIT_TIMEOUT (Timeout expired before the task can get the semaphore.)
 * 
 * \warning Might block the calling task.
 * \warning Cannot be called from an ISR.
 * 
 * \see _sem_wait
 * \see _sem_wait_ticks
 * \see _sem_wait_until
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_post
 * \see _sem_get_wait_count
 * \see _sem_get_value
 * \see _sem_create
 * \see _sem_create_fast
 * \see MQX_TICK_STRUCT
 */ 
_mqx_uint _sem_wait_for
(
    pointer             users_sem_ptr,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE3(KLOG_sem_wait_for, users_sem_ptr, tick_ptr);

    result = _sem_wait_internal(users_sem_ptr, tick_ptr, FALSE);

    _KLOGX2(KLOG_sem_wait_for, result);
    return(result);

} /* Endbody */

/*!
 * \brief Wait for the semaphore for the specified number of ticks.
 * 
 * If the task cannot get the semaphore, MQX queues the task according to the 
 * semaphore's queuing policy, which is set when the semaphore is created.
 * 
 * \param[in] users_sem_ptr    Semaphore handle from _sem_open() or _sem_open_fast().
 * \param[in] timeout_in_ticks One of the following:
 * \li Maximum number of ticks to wait.
 * \li 0 (Unlimited wait.)
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_EDEADLK (Function was aborted to prevent deadlock: the task has 
 * all the semaphore locks and, since the semaphore is strict, the task cannot 
 * post to  "wake" itself.)
 * \return SEM_INVALID_SEMAPHORE_HANDLE (One of the following:
 * \li Sem_handle is not a valid semaphore handle.
 * \li Sem_handle was obtained by another task.)
 * \return SEM_INVALID_SEMAPHORE (Sem_handle is for a semaphore that is no longer 
 * valid.)
 * \return SEM_SEMAPHORE_DELETED (MQX is in the process of destroying the semaphore.)
 * \return SEM_WAIT_TIMEOUT (Timeout expired before the task can get the semaphore.)
 * 
 * \warning Might block the calling task.
 * \warning Cannot be called from an ISR.
 * 
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_until
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_post
 * \see _sem_get_wait_count
 * \see _sem_get_value
 * \see _sem_create
 * \see _sem_create_fast
 * \see MQX_TICK_STRUCT
 */
_mqx_uint _sem_wait_ticks
(
    pointer   users_sem_ptr,
    _mqx_uint timeout_in_ticks
)
{ /* Body */
    MQX_TICK_STRUCT ticks;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE3(KLOG_sem_wait_ticks, users_sem_ptr, timeout_in_ticks);

    if (timeout_in_ticks)
    {
        ticks = _mqx_zero_tick_struct;

        PSP_GET_ELEMENT_FROM_TICK_STRUCT(&ticks, 0) = timeout_in_ticks;
        result = _sem_wait_internal(users_sem_ptr, &ticks, FALSE);
    }
    else
    {
        result = _sem_wait_internal(users_sem_ptr, NULL, FALSE);
    } /* Endif */

    _KLOGX2(KLOG_sem_wait_ticks, result);
    return(result);

} /* Endbody */

/*!
 * \brief Wait for the semaphore until the specified time (in tick time).
 * 
 * If the task cannot get the semaphore, MQX queues the task according to the 
 * semaphore's queuing policy, which is set when the semaphore is created.
 * 
 * \param[in] users_sem_ptr Semaphore handle from _sem_open() or _sem_open_fast().
 * \param[in] tick_ptr      One of the following:
 * \li Pointer to the time (in tick time) until which to wait.
 * \li NULL (Unlimited wait.)
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_EDEADLK (Function was aborted to prevent deadlock: the task has 
 * all the semaphore locks and, since the semaphore is strict, the task cannot 
 * post to  "wake" itself.)
 * \return SEM_INVALID_SEMAPHORE_HANDLE (One of the following:
 * \li Sem_handle is not a valid semaphore handle.
 * \li Sem_handle was obtained by another task.)
 * \return SEM_INVALID_SEMAPHORE (Sem_handle is for a semaphore that is no longer 
 * valid.)
 * \return SEM_SEMAPHORE_DELETED (MQX is in the process of destroying the semaphore.)
 * \return SEM_WAIT_TIMEOUT (Timeout expired before the task can get the semaphore.)
 * 
 * \warning Might block the calling task.
 * \warning Cannot be called from an ISR.
 * 
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_open
 * \see _sem_open_fast
 * \see _sem_post
 * \see _sem_get_wait_count
 * \see _sem_get_value
 * \see _sem_create
 * \see _sem_create_fast
 * \see MQX_TICK_STRUCT
 */ 
_mqx_uint _sem_wait_until
(
    pointer             users_sem_ptr,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE3(KLOG_sem_wait_until, users_sem_ptr, tick_ptr);

    result = _sem_wait_internal(users_sem_ptr, tick_ptr, TRUE);

    _KLOGX2(KLOG_sem_wait_until, result);
    return(result);

} /* Endbody */

#endif /* MQX_USE_SEMAPHORES */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/cache.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: cache.c$
* $Version : 3.8.3.0$
* $Date    : Jul-30-2012$
*
* Comments:
*
*   This file contains functions for use with the cortex caches.
*
*END************************************************************************/
#include "mqx_inc.h"

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _dcache_enable
* Returned Value   : none
* Comments         :
*   This function enables the data cache
*
*END*----------------------------------------------------------------------*/
void _dcache_enable()
{
    /* Enable cache, enable write buffer, invalidate cache */
    LMEM_PSCCR = (LMEM_PSCCR_GO_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_ENWRBUF_MASK | LMEM_PSCCR_ENCACHE_MASK);
    /* wait until the command completes */
    while (LMEM_PSCCR & LMEM_PSCCR_GO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
* Function Name    : _dcache_disable
* Returned Value   : none
* Comments         :
*   This function disables the data cache
*
*END*----------------------------------------------------------------------*/
void _dcache_disable()
{
    LMEM_PSCCR &= ~(LMEM_PSCCR | LMEM_PSCCR_ENWRBUF_MASK | LMEM_PSCCR_ENCACHE_MASK);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _dcache_invalidate
* Returned Value   : none
* Comments         :
*   This function invalidates the entire data cache
*
*END*----------------------------------------------------------------------*/
void _dcache_invalidate()
{
    LMEM_PSCCR |= LMEM_PSCCR_GO_MASK | LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK;
    /* wait until the command completes */
    while (LMEM_PSCCR & LMEM_PSCCR_GO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _dcache_invalidate_line
* Comments         :
*    This function is called to invalidate a line
*    out of the data cache.
*
*END*------------------------------------------------------------------------*/
void _dcache_invalidate_line(pointer addr)
{
    /* Invalidate by physical address */
    LMEM_PSCLCR = LMEM_PSCLCR_LADSEL_MASK | (0x1u << LMEM_PSCLCR_LCMD_SHIFT);
    /* Set physical address and activate command */
    LMEM_PSCSAR = ((uint_32)addr & ~0x03u) | LMEM_PSCSAR_LGO_MASK;
    /* wait until the command completes */
    while (LMEM_PSCSAR & LMEM_PSCSAR_LGO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _dcache_invalidate_mlines
* Returned Value   : none
* Comments         :
*
*  This function is called to Invalidate the data cache.
*
*END*-----------------------------------------------------------------------*/
void _dcache_invalidate_mlines(pointer addr, _mem_size length)
{
    pointer end_addr = (pointer)((uint_32)addr + length);
    addr = (pointer) ((uint_32)addr & ~(PSP_CACHE_LINE_SIZE - 1));
    do
    {
        _dcache_invalidate_line(addr);
        addr = (pointer) ((uint_32)addr + PSP_CACHE_LINE_SIZE);
    } while (addr < end_addr);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _dcache_flush
* Returned Value   : none
* Comments         :
*   This function enables the data cache
*
*END*----------------------------------------------------------------------*/
void _dcache_flush()
{
    LMEM_PSCCR |= LMEM_PSCCR_GO_MASK |  LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK ;
    /* wait until the command completes */
    while (LMEM_PSCCR & LMEM_PSCCR_GO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _dcache_flush_line
* Comments         :
*   This function is called to push (flush and invalidate) a line
*   out of the data cache.
*
*END*------------------------------------------------------------------------*/
void _dcache_flush_line(pointer addr)
{
    /* Invalidate by physical address */
    LMEM_PSCLCR = LMEM_PSCLCR_LADSEL_MASK | (0x2u << LMEM_PSCLCR_LCMD_SHIFT);
    /* Set physical address and activate command */
    LMEM_PSCSAR = ((uint_32)addr & ~0x03u) | LMEM_PSCSAR_LGO_MASK;
    /* wait until the command completes */
    while (LMEM_PSCSAR & LMEM_PSCSAR_LGO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _dcache_flush_mlines
* Returned Value   : none
* Comments         :
*
*  This function is called to flush the data cache by performing cache
*  copybacks.  It must determine how many cache lines need to be copied
*  back and then perform the copybacks.
*
*END*-----------------------------------------------------------------------*/
void _dcache_flush_mlines(pointer addr, _mem_size length)
{
    pointer end_addr = (pointer)((uint_32)addr + length);
    addr = (pointer) ((uint_32)addr & ~(PSP_CACHE_LINE_SIZE - 1));
    do
    {
        _dcache_flush_line(addr);
        addr = (pointer) ((uint_32)addr + PSP_CACHE_LINE_SIZE);
    } while (addr < end_addr);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _icache_enable
* Returned Value   : none
* Comments         :
*   This function enables the data cache
*
*END*----------------------------------------------------------------------*/
void _icache_enable()
{
    /* Enable cache, enable write buffer, invalidate cache */
    LMEM_PCCCR = (LMEM_PCCCR_GO_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
    /* wait until the command completes */
    while (LMEM_PCCCR & LMEM_PCCCR_GO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _icache_disable
* Returned Value   : none
* Comments         :
*   This function disables the data cache
*
*END*----------------------------------------------------------------------*/
void _icache_disable()
{
    LMEM_PCCCR &= ~(LMEM_PCCCR | LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _icache_invalidate
* Returned Value   : none
* Comments         :
*   This function enables the data cache
*
*END*----------------------------------------------------------------------*/
void _icache_invalidate()
{
    LMEM_PCCCR |= LMEM_PCCCR_GO_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK;
    /* wait until the command completes */
    while (LMEM_PCCCR & LMEM_PCCCR_GO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _icache_invalidate_line
* Comments         :
*   This function is called to invalidate a line
*   out of the code cache.
*
*END*------------------------------------------------------------------------*/
void _icache_invalidate_line(pointer addr)
{
    /* Invalidate by physical address */
    LMEM_PCCLCR = LMEM_PCCLCR_LADSEL_MASK | (0x1u << LMEM_PCCLCR_LCMD_SHIFT);
    /* Set physical address and activate command */
    LMEM_PCCSAR = ((uint_32)addr & ~0x03u) | LMEM_PCCSAR_LGO_MASK;
    /* wait until the command completes */
    while (LMEM_PCCSAR & LMEM_PCCSAR_LGO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _icache_invalidate_mlines
* Comments         :
*
*  This function is responsible for performing an instruction cache
*  invalidate.  It must determine how many cache lines need to be invalidated
*  and then perform the invalidation.
*
*END*----------------------------------------------------------------------*/
void _icache_invalidate_mlines(pointer addr, _mem_size length)
{
    pointer end_addr = (pointer)((uint_32)addr + length);
    addr = (pointer) ((uint_32)addr & ~(PSP_CACHE_LINE_SIZE - 1));
    do
    {
        _icache_invalidate_line(addr);
        addr = (pointer) ((uint_32)addr + PSP_CACHE_LINE_SIZE);
    } while (addr < end_addr);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _icache_flush
* Returned Value   : none
* Comments         :
*   This function flushes the data cache
*
*END*----------------------------------------------------------------------*/
void _icache_flush()
{
    LMEM_PCCCR |= LMEM_PCCCR_GO_MASK | LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK;
    /* wait until the command completes */
    while (LMEM_PCCCR & LMEM_PCCCR_GO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _icache_flush_line
* Comments         :
*   This function is called to push (flush and invalidate) a line
*   out of the instruction cache.
*
*END*------------------------------------------------------------------------*/
void _icache_flush_line(pointer addr)
{
    /* Invalidate by physical address */
    LMEM_PCCLCR = LMEM_PCCLCR_LADSEL_MASK | (0x2u << LMEM_PCCLCR_LCMD_SHIFT);
    /* Set physical address and activate command */
    LMEM_PCCSAR = ((uint_32)addr & ~0x03u) | LMEM_PCCSAR_LGO_MASK;
    /* wait until the command completes */
    while (LMEM_PCCSAR & LMEM_PCCSAR_LGO_MASK)
    {}
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _icache_flush_mlines
* Returned Value   : none
* Comments         :
*
*  This function is called to flush the data cache by performing cache
*  copybacks.  It must determine how many cache lines need to be copied
*  back and then perform the copybacks.
*
*END*-----------------------------------------------------------------------*/
void _icache_flush_mlines(pointer addr, _mem_size length)
{
    pointer end_addr = (pointer)((uint_32)addr + length);
    addr = (pointer) ((uint_32)addr & ~(PSP_CACHE_LINE_SIZE - 1));
    do
    {
        _icache_flush_line(addr);
        addr = (pointer) ((uint_32)addr + PSP_CACHE_LINE_SIZE);
    } while (addr < end_addr);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/compiler/iar/comp.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: comp.c$
* $Version : 3.8.4.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This file contains runtime support for the IAR Compiler.
*
*END************************************************************************/

#include "mqx.h"


/* IAR EWARM init function prototypes */
int __low_level_init(void);


pointer malloc(_mem_size);
pointer calloc(_mem_size, _mem_size);
void    free(pointer);
int     exit(int);


extern void init_hardware(void);

#if MQX_ENABLE_CPP || BSPCFG_ENABLE_CPP
extern void __cexit_call_dtors(void);
#endif /* MQX_ENABLE_CPP || BSPCFG_ENABLE_CPP */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : __low_level_init
* Returned Value   : void
* Comments         :
*   Call function init_hardware() in BSP libraty to initialize CPU registers
*
*END*----------------------------------------------------------------------*/

int __low_level_init(void)
{
    /* Initialize device. */
    init_hardware();
    return (1);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : malloc
* Returned Value   : pointer
* Comments         :
*   Override C/C++ runtime heap allocation function in IAR's DLIB
*
*END*----------------------------------------------------------------------*/

pointer malloc(_mem_size bytes)
{
    return _mem_alloc_system(bytes);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : calloc
* Returned Value   : pointer
* Comments         :
*   Override C/C++ runtime heap allocation function in IAR's DLIB
*
*END*----------------------------------------------------------------------*/

pointer calloc(_mem_size n, _mem_size z)
{
    return _mem_alloc_system_zero(n*z);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : free
* Returned Value   : void
* Comments         :
*   Override C/C++ runtime heap deallocation function in IAR's DLIB
*
*END*----------------------------------------------------------------------*/

void free(pointer p)
{
    _mem_free(p);
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : exit
* Returned Value   : should not return
* Comments         :
*   Replacement for Codewarrior's exit function
*
*END*----------------------------------------------------------------------*/
#if MQX_EXIT_ENABLED
int exit(int status)
{
#if MQX_ENABLE_CPP || BSPCFG_ENABLE_CPP
    /* Destroy all constructed global objects */
    __cexit_call_dtors();
#endif /* MQX_ENABLE_CPP || BSPCFG_ENABLE_CPP */

    /*
    ** Change for whatever is appropriate for your board
    ** and application.  Perhaps a software reset or
    ** some kind of trap/call to the kernel soft re-boot.
    */
    while (TRUE) {
    }

    return(0);
}

#else  /* MQX_EXIT_ENABLED */

/* int exit(int) is supplied by IAR's DLIB */

#endif /* MQX_EXIT_ENABLED */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/natdata.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: natdata.c$
* $Version : 3.8.4.0$
* $Date    : Aug-29-2011$
*
* Comments:
*
*   This file contains the NAT data strucutre interface functions.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_insert
* Returned Value  : NAT_SESSION_STRUCT_PTR or NULL if error
* Comments        :
*        Creates a new session. Will create a new session for ICMP error
*     messages, but won't link them into the IP_RADIX trees.
*
*END*-----------------------------------------------------------------*/

static void NAT_insert_find_unused
   (
      pointer _PTR_  node_ptr_ptr,
      pointer        data_ptr
   )
{ /* Body */
    boolean _PTR_    found_ptr = data_ptr;

   /* TRUE if there is something there, FALSE if not */
   *found_ptr = (*node_ptr_ptr != NULL);

} /* Endbody */



static void NAT_insert_insert
   (
      pointer _PTR_  node_ptr_ptr,
      pointer        data_ptr
   )
{ /* Body */
   IPRADIX_NODE_PTR        node_ptr = (pointer) node_ptr_ptr;
   NAT_SESSION_STRUCT_PTR  nat_session_ptr = data_ptr;

   /* Link according to incoming or outgoing */
   if ((nat_session_ptr->STATE & NAT_STATE_INSERT_IN) == NAT_STATE_INSERT_IN) {
      nat_session_ptr->NEXT_IN = node_ptr->DATA;
   } else {
      nat_session_ptr->NEXT_OUT = node_ptr->DATA;
   } /* Endif */

   nat_session_ptr->STATE &= ~NAT_STATE_INS_ERR;
   node_ptr->DATA = nat_session_ptr;

} /* Endbody */


NAT_SESSION_STRUCT_PTR NAT_insert
   (
      IP_HEADER_PTR     ip_header_ptr, /* [IN] Pointer to the IP datagram */
      uint_32_ptr       error_ptr      /* [OUT] Reason for returning NULL */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   NAT_SESSION_STRUCT_PTR  new_nat_session_ptr;
   uint_16_ptr             last_used_port_ptr;
   TRANSPORT_UNION         transport;
   uint_32                 key;
   uint_16                 icmp_type, port;
   boolean                 used = FALSE;
   boolean                 route_exists;
   
   /* Get a pointer to the upper level protocol */
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);

   /* Allocate memory */
   new_nat_session_ptr = RTCS_part_alloc_zero(nat_cfg_ptr->SESSION_PART);

   if (new_nat_session_ptr==NULL) {
      *error_ptr = RTCSERR_OUT_OF_MEMORY;
      return NULL;
   } /* Endid */

   /* Setup event information */
   new_nat_session_ptr->TIMEOUT.SESSION_PTR = new_nat_session_ptr;

   /* Copy information (works for all protocols) */
   new_nat_session_ptr->PRV_HST = ntohl(ip_header_ptr->SOURCE);
   new_nat_session_ptr->PUB_HST = ntohl(ip_header_ptr->DEST);

   /* Choose a NAT host IP. */
   new_nat_session_ptr->NAT_HST = IP_route_find(new_nat_session_ptr->PUB_HST, 0);
   route_exists = new_nat_session_ptr->NAT_HST != INADDR_ANY;

   new_nat_session_ptr->IP_PROT = ntohc(ip_header_ptr->PROTOCOL);
   new_nat_session_ptr->SNAT_OR_DNAT = SNAT;


   /* No route to host available */
   if (!route_exists) {
      RTCS_part_free(new_nat_session_ptr);
      *error_ptr = RTCSERR_IP_UNREACH;
      return NULL;
   } /* Endif */

   /* Do protocol specific initialization */
   switch (new_nat_session_ptr->IP_PROT) {
      case IPPROTO_ICMP:
         icmp_type = ntohc(transport.ICMP_PTR->TYPE);
         if (icmp_type == ICMPTYPE_ECHO_REQ     ||
             icmp_type == ICMPTYPE_TIME_REQ     ||
             icmp_type == ICMPTYPE_INFO_REQ     ||
             icmp_type == ICMPTYPE_AM_REQ)
         {
            new_nat_session_ptr->PRV_PORT = ntohs(transport.ECHO_PTR->SEQ);     
            last_used_port_ptr = &nat_cfg_ptr->ICMP_ID;
         } else {
            if (ICMPTYPE_ISQUERY(icmp_type)) {
               /* This means a reply without a request. Should not happen */
               RTCS_part_free(new_nat_session_ptr);
               *error_ptr = RTCSERR_NAT_UNEXPECTED;
               new_nat_session_ptr = NULL;
            } else {
               /* We will be deleting the session, so don't store it */
               *error_ptr = RTCS_OK;
            } /* Endif*/
            return new_nat_session_ptr;
         } /* Endif */

         new_nat_session_ptr->TIMEOUT.TIME = nat_cfg_ptr->TIMEOUT_ICMP;
         break;

      case IPPROTO_TCP:
         new_nat_session_ptr->PRV_PORT = ntohs(transport.TCP_PTR->source_port);
         new_nat_session_ptr->PUB_PORT = ntohs(transport.TCP_PTR->dest_port);           
         last_used_port_ptr = &nat_cfg_ptr->TCP_PORT;
         new_nat_session_ptr->TIMEOUT.TIME = nat_cfg_ptr->TIMEOUT_TCP;
         break;

      case IPPROTO_UDP:
         new_nat_session_ptr->PRV_PORT = ntohs(transport.UDP_PTR->SRC_PORT);
         new_nat_session_ptr->PUB_PORT = ntohs(transport.UDP_PTR->DEST_PORT);
         last_used_port_ptr = &nat_cfg_ptr->UDP_PORT;
         new_nat_session_ptr->TIMEOUT.TIME = nat_cfg_ptr->TIMEOUT_UDP;
         break;

      default:    /* Should never get here */
         RTCS_part_free(new_nat_session_ptr);
         // CR-TBD no error returned
         *error_ptr = RTCSERR_NAT_UNEXPECTED;
         return NULL;
   } /* Enswitch */


   /*
   ** Reserve a port or query id.
   ** Take the last used number from the last_used_num pointer, and
   ** decrement by 1. Search radix tree to see if used, and
   ** continue until an unused number is found. When the #define
   ** minimum NAT port is reached wrap up to the maximum port.
   ** If we return to the *last_used_num, they are
   ** all reserved, so we free the session and return NULL.
   */   
   
   port = NAT_NEXT_PORT(nat_cfg_ptr,*last_used_port_ptr);

   while (port != *last_used_port_ptr) {

      /* Search tree for port/id number */
      key = NAT_KEY(new_nat_session_ptr->IP_PROT,port);
      IPRADIX_insert(&nat_cfg_ptr->ROOT_IN, key, 0xFFFFFFFF, 0, NAT_insert_find_unused, &used);

      if (used == FALSE) {          /* We found a free port/id number */
            new_nat_session_ptr->NAT_PORT = port;
         *last_used_port_ptr = port;
      } else {                      /* Port/id is used, keep looking */
         used = FALSE;
         port=NAT_NEXT_PORT(nat_cfg_ptr,port);
      }/* Endif */
   }/* Endwhile */
   
      if (port != new_nat_session_ptr->NAT_PORT) {
         *error_ptr = RTCSERR_NAT_NO_SESSION;
         RTCS_part_free(new_nat_session_ptr);
      return NULL;
   }/* Endif */

   /* Update STATS */
   nat_cfg_ptr->STATS.ST_SESSIONS++;
   nat_cfg_ptr->STATS.ST_SESSIONS_SNAT++;
   nat_cfg_ptr->STATS.ST_SESSIONS_OPEN++;
   if (nat_cfg_ptr->STATS.ST_SESSIONS_OPEN > nat_cfg_ptr->STATS.ST_SESSIONS_OPEN_MAX) {
      nat_cfg_ptr->STATS.ST_SESSIONS_OPEN_MAX = nat_cfg_ptr->STATS.ST_SESSIONS_OPEN;
   } /* Endif */

   /*
   ** Call IPRADIX_insert on each radix tree. Pass in a function that will
   ** link the session struct onto a linked list starting at the node.
   ** If last_used_port_ptr == NULL, we are routing a one time ICMP message and
   ** there is no need to save the session.
   */
   /* Insert into incoming packet tree */
   new_nat_session_ptr->STATE = NAT_STATE_INSERT_IN | NAT_STATE_INS_ERR;
   IPRADIX_insert(&nat_cfg_ptr->ROOT_IN, key, 0xFFFFFFFF, nat_cfg_ptr->RADIX_IN,
      NAT_insert_insert, new_nat_session_ptr);

   /* If the insert failed, we free the session struct */
   if (new_nat_session_ptr->STATE & NAT_STATE_INS_ERR) {
      NAT_delete(new_nat_session_ptr);
      *error_ptr = RTCSERR_OUT_OF_MEMORY;
      return NULL;
   } /* Endif */

   /* insert into outgoing packet tree */
   key = NAT_KEY(new_nat_session_ptr->IP_PROT,new_nat_session_ptr->PRV_PORT);
   new_nat_session_ptr->STATE = NAT_STATE_INSERT_OUT | NAT_STATE_INS_ERR;;

   IPRADIX_insert(&nat_cfg_ptr->ROOT_OUT, key, 0xFFFFFFFF, nat_cfg_ptr->RADIX_OUT,
      NAT_insert_insert, new_nat_session_ptr);

   /* If the insert failed, we free the session struct */
   if (new_nat_session_ptr->STATE & NAT_STATE_INS_ERR) {
      NAT_delete(new_nat_session_ptr);
      *error_ptr = RTCSERR_OUT_OF_MEMORY;
      return NULL;
   } /* Endif */

   /* Return a pointer to the new structure */
   return new_nat_session_ptr;

} /* Endbody */


NAT_SESSION_STRUCT_PTR NAT_insert_dnat
   (
      IP_HEADER_PTR        ip_header_ptr, /* [IN] Pointer to the IP datagram */
      DNAT_RULE_STRUCT_PTR dnat_rule_ptr,
      uint_32_ptr          error_ptr      /* [OUT] Reason for returning NULL */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   NAT_SESSION_STRUCT_PTR  new_nat_session_ptr;
   TRANSPORT_UNION         transport;
   uint_32                 key;
   boolean                 used = FALSE;

   /* Get a pointer to the upper level protocol */
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);

   /* Allocate memory */
   new_nat_session_ptr = RTCS_part_alloc_zero(nat_cfg_ptr->SESSION_PART);

   if (new_nat_session_ptr==NULL) {
      *error_ptr = RTCSERR_OUT_OF_MEMORY;
      return NULL;
   } /* Endid */

   /* Setup event information */
   new_nat_session_ptr->TIMEOUT.SESSION_PTR = new_nat_session_ptr;

   /* Copy information (works for all protocols) */
   new_nat_session_ptr->PRV_HST = dnat_rule_ptr->PRIVATE_IP; 
   new_nat_session_ptr->PUB_HST = ntohl(ip_header_ptr->SOURCE);
   new_nat_session_ptr->NAT_HST = ntohl(ip_header_ptr->DEST);
   new_nat_session_ptr->IP_PROT = dnat_rule_ptr->IP_PROTOCOL;
   new_nat_session_ptr->SNAT_OR_DNAT = DNAT;

   /* Do protocol specific initialization */
   switch (new_nat_session_ptr->IP_PROT) {
 
      case IPPROTO_TCP:
         new_nat_session_ptr->PUB_PORT = ntohs(transport.TCP_PTR->source_port);             
         new_nat_session_ptr->NAT_PORT = ntohs(transport.TCP_PTR->dest_port);
         new_nat_session_ptr->PRV_PORT = new_nat_session_ptr->NAT_PORT - 
            dnat_rule_ptr->PUBLIC_START_PORT + dnat_rule_ptr->PRIVATE_START_PORT;
         if (dnat_rule_ptr->TIMEOUT) {
            new_nat_session_ptr->TIMEOUT.TIME = dnat_rule_ptr->TIMEOUT;
         } else {            
            new_nat_session_ptr->TIMEOUT.TIME = nat_cfg_ptr->TIMEOUT_TCP;
         }
         break;

      case IPPROTO_UDP:
         new_nat_session_ptr->PUB_PORT = ntohs(transport.UDP_PTR->SRC_PORT);
         new_nat_session_ptr->NAT_PORT = ntohs(transport.UDP_PTR->DEST_PORT);
         new_nat_session_ptr->PRV_PORT = new_nat_session_ptr->NAT_PORT -
           dnat_rule_ptr->PUBLIC_START_PORT + dnat_rule_ptr->PRIVATE_START_PORT;
          if (dnat_rule_ptr->TIMEOUT) {
            new_nat_session_ptr->TIMEOUT.TIME = dnat_rule_ptr->TIMEOUT;
         } else {            
            new_nat_session_ptr->TIMEOUT.TIME = nat_cfg_ptr->TIMEOUT_UDP;
         }
         break;

      default:    /* Should never get here */
         RTCS_part_free(new_nat_session_ptr);
         *error_ptr = RTCSERR_NAT_UNEXPECTED;
         return NULL;
   } /* Enswitch */


 

   /* Update STATS */
   nat_cfg_ptr->STATS.ST_SESSIONS++;
   nat_cfg_ptr->STATS.ST_SESSIONS_DNAT++;
   nat_cfg_ptr->STATS.ST_SESSIONS_OPEN++;
   if (nat_cfg_ptr->STATS.ST_SESSIONS_OPEN > nat_cfg_ptr->STATS.ST_SESSIONS_OPEN_MAX) {
      nat_cfg_ptr->STATS.ST_SESSIONS_OPEN_MAX = nat_cfg_ptr->STATS.ST_SESSIONS_OPEN;
   } /* Endif */

   /*
   ** Call IPRADIX_insert on each radix tree. Pass in a function that will
   ** link the session struct onto a linked list starting at the node.
   ** If last_used_port_ptr == NULL, we are routing a one time ICMP message and
   ** there is no need to save the session.
   */
   /* Insert into incoming packet tree */
   key = NAT_KEY(new_nat_session_ptr->IP_PROT,new_nat_session_ptr->NAT_PORT);
   new_nat_session_ptr->STATE = NAT_STATE_INSERT_IN | NAT_STATE_INS_ERR;
   IPRADIX_insert(&nat_cfg_ptr->ROOT_IN, key, 0xFFFFFFFF, nat_cfg_ptr->RADIX_IN,
      NAT_insert_insert, new_nat_session_ptr);

   /* If the insert failed, we free the session struct */
   if (new_nat_session_ptr->STATE & NAT_STATE_INS_ERR) {
      NAT_delete(new_nat_session_ptr);
      *error_ptr = RTCSERR_OUT_OF_MEMORY;
      return NULL;
   } /* Endif */

   /* insert into outgoing packet tree */
   key = NAT_KEY(new_nat_session_ptr->IP_PROT,new_nat_session_ptr->PRV_PORT);
   new_nat_session_ptr->STATE = NAT_STATE_INSERT_OUT | NAT_STATE_INS_ERR;;

   IPRADIX_insert(&nat_cfg_ptr->ROOT_OUT, key, 0xFFFFFFFF, nat_cfg_ptr->RADIX_OUT,
      NAT_insert_insert, new_nat_session_ptr);

   /* If the insert failed, we free the session struct */
   if (new_nat_session_ptr->STATE & NAT_STATE_INS_ERR) {
      NAT_delete(new_nat_session_ptr);
      *error_ptr = RTCSERR_OUT_OF_MEMORY;
      return NULL;
   } /* Endif */

   /* Return a pointer to the new structure */
   return new_nat_session_ptr;

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_lookup
* Returned Value  : NAT_SESSION_STRUCT_PTR or NULL no session found
* Comments        :
*        Returns a pointer to a session, if it exists.
*
*END*-----------------------------------------------------------------*/

struct nat_lookup {
   NAT_SESSION_STRUCT_PTR  NAT_SESSION_PTR;
   _ip_address             SRC;
   _ip_address             DEST;
   boolean                 TO_PRV_NET;
   uint_16                 PORT;
} ;

static void NAT_lookup_func
   (
      pointer _PTR_  node_ptr_ptr,
      pointer        data_ptr
      
   )
{ /* Body */
   NAT_SESSION_STRUCT_PTR  nat_session_ptr = *node_ptr_ptr;
   struct nat_lookup _PTR_ testdata = data_ptr;
   
   /* Go through linked list of NAT_SESSION_STRUCTs */
   while (nat_session_ptr) {
      if (testdata->TO_PRV_NET) {   
         /* From public network to private network */
         if ((testdata->SRC == nat_session_ptr->PUB_HST) &&
             (testdata->DEST == nat_session_ptr->NAT_HST) && 
             (testdata->PORT == nat_session_ptr->PUB_PORT) ) 
         {
            testdata->NAT_SESSION_PTR = nat_session_ptr;
            break;
         } /* Endif */

         /* Go to next node */
         nat_session_ptr = nat_session_ptr->NEXT_IN;

      } else {                      
         /* From private network to public network */
         if ((testdata->SRC == nat_session_ptr->PRV_HST) &&
             (testdata->DEST == nat_session_ptr->PUB_HST) && 
             (testdata->PORT == nat_session_ptr->PUB_PORT)) 
         {
            testdata->NAT_SESSION_PTR = nat_session_ptr;
            break;
         } /* Endif */

         /* Go to next node */
         nat_session_ptr = nat_session_ptr->NEXT_OUT;

      } /* Endif */
   } /* Endwhile */
} /* Endbody */

static void NAT_lookup_func_lax
   (
      pointer _PTR_  node_ptr_ptr,
      pointer        data_ptr
   )
{ /* Body */
   NAT_SESSION_STRUCT_PTR  nat_session_ptr = *node_ptr_ptr;
   struct nat_lookup _PTR_ testdata = data_ptr;

   /* Go through linked list of NAT_SESSION_STRUCTs */
   while (nat_session_ptr) {
      if (testdata->TO_PRV_NET) {   /* From public network to private network */
         if (testdata->SRC == nat_session_ptr->PUB_HST    &&
             testdata->DEST == nat_session_ptr->NAT_HST)
         {
            testdata->NAT_SESSION_PTR = nat_session_ptr;
            break;
         } /* Endif */

         /* Go to next node */
         nat_session_ptr = nat_session_ptr->NEXT_IN;
      } else {                      /* From private network to public network */
         if (testdata->SRC == nat_session_ptr->PRV_HST    &&
             testdata->DEST == nat_session_ptr->PUB_HST)
         {
            testdata->NAT_SESSION_PTR = nat_session_ptr;
            break;
         } /* Endif */

         /* Go to next node */
         nat_session_ptr = nat_session_ptr->NEXT_OUT;
      } /* Endif */
   } /* Endwhile */
} /* Endbody */


NAT_SESSION_STRUCT_PTR NAT_lookup
   (
      IP_HEADER_PTR ip_header_ptr,  /* [IN] Pointer to the IP datagram */
      boolean       icmp_err,       /* [IN] Is the lookup for an icmp error? */
      boolean       lax,            /* [IN] Non-strict lookup used by ALGs */
      uint_32_ptr   error_ptr
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR   nat_cfg_ptr = RTCS_getcfg(NAT);
   uint_32              key, ip_protocol = ntohc(ip_header_ptr->PROTOCOL);
   TRANSPORT_UNION     transport;
   struct nat_lookup    data;
   IPRADIX_NODE_PTR     root_ptr;
   boolean              pub_to_prv;
   DNAT_RULE_STRUCT_PTR dnat_rule_ptr;

   /* Get a pointer to the upper level protocol */
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);

   data.NAT_SESSION_PTR = NULL;
   data.PORT = 0;

   if (icmp_err) { /* Do a reverse lookup for ICMP errors */
      data.SRC = ntohl(ip_header_ptr->DEST);
      data.DEST = ntohl(ip_header_ptr->SOURCE);
   } else {
      data.SRC = ntohl(ip_header_ptr->SOURCE);
      data.DEST = ntohl(ip_header_ptr->DEST);
   } /* Endif */

   key = (ip_protocol & 0xFF) << 16;

   /* Find out if the packet is entering or exiting the private network */
   if (NAT_is_private_addr(&nat_cfg_ptr->PRIVATE_NETWORKS,data.SRC)) {
      data.TO_PRV_NET = FALSE;
      root_ptr = &nat_cfg_ptr->ROOT_OUT;
   } else {
      data.TO_PRV_NET = TRUE;
      root_ptr = &nat_cfg_ptr->ROOT_IN;
   } /* Endif */

   /*
   ** If we have received an ICMP error, we are search for the session
   ** corresponding to the embedded header, so we do a reverse lookup
   */
   if (icmp_err) {
      pub_to_prv = data.TO_PRV_NET?FALSE:TRUE;
   } else {
      pub_to_prv = data.TO_PRV_NET;
   } /* Endif */

   if (ip_protocol == IPPROTO_ICMP) {
      key = NAT_KEY(ip_protocol,ntohs(transport.ECHO_PTR->SEQ));
   } else {
      /* If the incoming packet is not an ICMP error, then the source is private */
      if (pub_to_prv) {
         /* It's TCP or UDP, and both have ports in same header position */
         key = NAT_KEY(ip_protocol,ntohs(transport.UDP_PTR->DEST_PORT));
         data.PORT = ntohs(transport.UDP_PTR->SRC_PORT);            
      } else {
         /* It's TCP or UDP, and both have ports in same header position */
         key = NAT_KEY(ip_protocol,ntohs(transport.UDP_PTR->SRC_PORT));
         data.PORT = ntohs(transport.UDP_PTR->DEST_PORT);           
      }/* Endif */
   } /* Endif */

   /* Search for an exact match on key */
   if (lax) {
      /* Non strict lookup used by ALGs */
      IPRADIX_insert(root_ptr, key, 0xFFFFFFFF, 0, NAT_lookup_func_lax, &data);
   } else {
      IPRADIX_insert(root_ptr, key, 0xFFFFFFFF, 0, NAT_lookup_func, &data);
   } /* Endif */


   if ((data.NAT_SESSION_PTR==NULL) && pub_to_prv) {
      // Maybe the header matches a DNAT rule
      dnat_rule_ptr = DNAT_lookup_rule(nat_cfg_ptr, ip_header_ptr, pub_to_prv);
      if (dnat_rule_ptr!=NULL) {
         // insert a new DNAT session here   
         data.NAT_SESSION_PTR = NAT_insert_dnat(ip_header_ptr, dnat_rule_ptr, error_ptr );
      }
   }

   return data.NAT_SESSION_PTR;

} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_delete
* Returned Value  : void
* Comments        :
*        Deletes a NAT session.
*
*END*-----------------------------------------------------------------*/

struct nat_delete {
   _ip_address             SRC;
   _ip_address             DEST;
   boolean                 TO_PRV_NET;
   uint_16                 PORT;
} ;

static void NAT_delete_func
   (
      pointer _PTR_  node_ptr_ptr,
      pointer        data_ptr
   )
{ /* Body */
   NAT_SESSION_STRUCT_PTR _PTR_ search_ptr_ptr = (NAT_SESSION_STRUCT_PTR _PTR_)node_ptr_ptr;
   struct nat_delete _PTR_      testdata = data_ptr;

  
   /* Search through list */
   while (*search_ptr_ptr) {
      if (testdata->TO_PRV_NET) {   /* Searching the IN tree */
         if ((*search_ptr_ptr)->PUB_HST == testdata->SRC      &&
             (*search_ptr_ptr)->NAT_HST == testdata->DEST     &&
             (*search_ptr_ptr)->PUB_PORT == testdata->PORT)
         {
            *search_ptr_ptr = (*search_ptr_ptr)->NEXT_IN;
            break;
         } /* Endif */
         search_ptr_ptr = &(*search_ptr_ptr)->NEXT_IN;
      } else {
         if ((*search_ptr_ptr)->PRV_HST == testdata->SRC      &&
            (*search_ptr_ptr)->PUB_HST == testdata->DEST     &&
            (*search_ptr_ptr)->PUB_PORT == testdata->PORT)
         {
            *search_ptr_ptr = (*search_ptr_ptr)->NEXT_OUT;
            break;
         } /* Endif */
         search_ptr_ptr = &(*search_ptr_ptr)->NEXT_OUT;
      } /* Endif */
   } /* Endwhile */

} /* Endbody */

void NAT_delete
   (
      NAT_SESSION_STRUCT_PTR   nat_session_ptr       /* [IN] Session to delete */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR         nat_cfg_ptr = RTCS_getcfg(NAT);
   NAT_SESSION_EXT_STRUCT_PTR nat_session_ext_ptr, next_nat_session_ext_ptr;
   struct nat_delete          data;
   uint_32                    key;

   /* Remove session from IN tree */
   key = NAT_KEY(nat_session_ptr->IP_PROT,nat_session_ptr->NAT_PORT);
   
   data.SRC = nat_session_ptr->PUB_HST;
   data.DEST = nat_session_ptr->NAT_HST;
   data.PORT = nat_session_ptr->PUB_PORT;
   data.TO_PRV_NET = TRUE;

   IPRADIX_insert(&nat_cfg_ptr->ROOT_IN, key, 0xFFFFFFFF, 0, NAT_delete_func,
      &data);

   /* Remove session from OUT tree */
   key = NAT_KEY(nat_session_ptr->IP_PROT, nat_session_ptr->PRV_PORT);

   data.SRC = nat_session_ptr->PRV_HST;
   data.DEST = nat_session_ptr->PUB_HST;
   data.PORT = nat_session_ptr->PUB_PORT;
   data.TO_PRV_NET = FALSE;

   IPRADIX_insert(&nat_cfg_ptr->ROOT_OUT, key, 0xFFFFFFFF, 0, NAT_delete_func,
      &data);

   nat_session_ext_ptr = nat_session_ptr->ALG_INFO_PTR;
   while (nat_session_ext_ptr)  {
      next_nat_session_ext_ptr = nat_session_ext_ptr->NEXT;
      if (NAT_alg_free_func_table[nat_session_ext_ptr->ALG_TYPE])  {
         NAT_alg_free_func_table[nat_session_ext_ptr->ALG_TYPE](nat_session_ext_ptr);
      } /* Endif */
      nat_session_ext_ptr = next_nat_session_ext_ptr;
   } /* Endwhile */

   nat_cfg_ptr->STATS.ST_SESSIONS_OPEN--;
   RTCS_part_free(nat_session_ptr);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_find_next_session
* Returned Value  : void
* Comments        :
*        FInds the next NAT session.
*
*END*-----------------------------------------------------------------*/

struct nat_find_next_session {
   NAT_SESSION_STRUCT_PTR  LAST_SESSION_PTR;
   NAT_SESSION_STRUCT_PTR  NEXT_SESSION_PTR;
   boolean                 FOUND_LAST;
   boolean                 FOUND_NEXT;
   uint_32                 TREE;
};

static boolean NAT_find_next_session_test(  
   uint_32  key,
   uint_32  mask,
   pointer  node_pointer,
   pointer  data_pointer
)
{ 
   NAT_SESSION_STRUCT_PTR  nat_session_ptr = node_pointer;
   struct nat_find_next_session _PTR_ data_ptr = data_pointer;

   if (node_pointer== NULL) {
      return FALSE;
   }

   while (nat_session_ptr != NULL) {
      if (data_ptr->FOUND_LAST || (data_ptr->LAST_SESSION_PTR ==NULL )) {
         data_ptr->NEXT_SESSION_PTR = nat_session_ptr;
         data_ptr->FOUND_NEXT = TRUE;
         return TRUE;
      } else {
         if (data_ptr->LAST_SESSION_PTR == nat_session_ptr) {
            data_ptr->FOUND_LAST = TRUE;
         }
      }
      if (data_ptr->TREE) {
         nat_session_ptr = nat_session_ptr->NEXT_IN;
      } else {
         nat_session_ptr = nat_session_ptr->NEXT_OUT;
      }
   }
   return FALSE;
}

void NAT_find_next_session_internal
   (
      NAT_PARM_PTR           parm_ptr 
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR   nat_cfg_ptr = RTCS_getcfg(NAT);
    struct nat_find_next_session    data;
   IPRADIX_NODE_PTR     root_ptr;
	

   if(nat_cfg_ptr == NULL)
   {
       parm_ptr->CONFIG = NULL;  
       RTCSCMD_complete(parm_ptr, (uint_32)RTCS_ERROR);
       return;
   }  
   
   
   
   data.LAST_SESSION_PTR = parm_ptr->CONFIG;
   data.NEXT_SESSION_PTR = NULL;
   data.FOUND_LAST = FALSE;
   data.FOUND_NEXT = FALSE;
   data.TREE = parm_ptr->OPTION;

   /* Find out if the packet is entering or exiting the private network */
   if (data.TREE) {
      root_ptr = &nat_cfg_ptr->ROOT_IN;
   } else {
      root_ptr = &nat_cfg_ptr->ROOT_OUT;
   } /* Endif */


   IPRADIX_walk(root_ptr, NAT_find_next_session_test, &data);
   if (data.FOUND_NEXT) {
      parm_ptr->CONFIG = data.NEXT_SESSION_PTR;
   } else {
      parm_ptr->CONFIG = NULL;
   }

   RTCSCMD_complete(parm_ptr, RTCS_OK);
} /* Endbody */

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/esdhc/esdhc.h<|end_filename|>
#ifndef __esdhc_h__
#define __esdhc_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: esdhc.h$
* $Version : 3.8.6.0$
* $Date    : Jul-19-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the eSDHC driver
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                    CONSTANT DEFINITIONS
*/

/* 
** IOCTL calls specific to eSDHC
*/
#define IO_IOCTL_ESDHC_INIT                  _IO(IO_TYPE_ESDHC,0x01)
#define IO_IOCTL_ESDHC_SEND_COMMAND          _IO(IO_TYPE_ESDHC,0x02)
#define IO_IOCTL_ESDHC_GET_CARD              _IO(IO_TYPE_ESDHC,0x03)
#define IO_IOCTL_ESDHC_GET_BAUDRATE          _IO(IO_TYPE_ESDHC,0x04)
#define IO_IOCTL_ESDHC_SET_BAUDRATE          _IO(IO_TYPE_ESDHC,0x05)
#define IO_IOCTL_ESDHC_GET_BUS_WIDTH         _IO(IO_TYPE_ESDHC,0x06)
#define IO_IOCTL_ESDHC_SET_BUS_WIDTH         _IO(IO_TYPE_ESDHC,0x07)

/* ESDHC error codes */
#define ESDHC_OK                             (0x00)
#define ESDHC_ERROR_INIT_FAILED              (ESDHC_ERROR_BASE | 0x01)
#define ESDHC_ERROR_COMMAND_FAILED           (ESDHC_ERROR_BASE | 0x02)
#define ESDHC_ERROR_COMMAND_TIMEOUT          (ESDHC_ERROR_BASE | 0x03)
#define ESDHC_ERROR_DATA_TRANSFER            (ESDHC_ERROR_BASE | 0x04)
#define ESDHC_ERROR_INVALID_BUS_WIDTH        (ESDHC_ERROR_BASE | 0x05)

/* ESDHC bus widths */
#define ESDHC_BUS_WIDTH_1BIT                 (0x00)
#define ESDHC_BUS_WIDTH_4BIT                 (0x01)
#define ESDHC_BUS_WIDTH_8BIT                 (0x02)

/* ESDHC card types */
#define ESDHC_CARD_NONE                      (0x00)
#define ESDHC_CARD_UNKNOWN                   (0x01)
#define ESDHC_CARD_SD                        (0x02)
#define ESDHC_CARD_SDHC                      (0x03)
#define ESDHC_CARD_SDIO                      (0x04)
#define ESDHC_CARD_SDCOMBO                   (0x05)
#define ESDHC_CARD_SDHCCOMBO                 (0x06)
#define ESDHC_CARD_MMC                       (0x07)
#define ESDHC_CARD_CEATA                     (0x08)

/* ESDHC command types */
#define ESDHC_XFERTYP_CMDTYP_NORMAL          (0x00)
#define ESDHC_XFERTYP_CMDTYP_SUSPEND         (0x01)
#define ESDHC_XFERTYP_CMDTYP_RESUME          (0x02)
#define ESDHC_XFERTYP_CMDTYP_ABORT           (0x03)

/* ESDHC response types */
#define ESDHC_XFERTYP_RSPTYP_NO              (0x00)
#define ESDHC_XFERTYP_RSPTYP_136             (0x01)
#define ESDHC_XFERTYP_RSPTYP_48              (0x02)
#define ESDHC_XFERTYP_RSPTYP_48BUSY          (0x03)

/* ESDHC commands */
#define ESDHC_CMD0   (SDHC_XFERTYP_CMDINX(0)  | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_NO))
#define ESDHC_CMD1   (SDHC_XFERTYP_CMDINX(1)  | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_NO))
#define ESDHC_CMD2   (SDHC_XFERTYP_CMDINX(2)  | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_136))
#define ESDHC_CMD3   (SDHC_XFERTYP_CMDINX(3)  | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD4   (SDHC_XFERTYP_CMDINX(4)  | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_NO))
#define ESDHC_CMD5   (SDHC_XFERTYP_CMDINX(5)  | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD6   (SDHC_XFERTYP_CMDINX(6)  | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_ACMD6  (SDHC_XFERTYP_CMDINX(6)  | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD7   (SDHC_XFERTYP_CMDINX(7)  | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_CMD8   (SDHC_XFERTYP_CMDINX(8)  | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD9   (SDHC_XFERTYP_CMDINX(9)  | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_136))
#define ESDHC_CMD10  (SDHC_XFERTYP_CMDINX(10) | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_136))
#define ESDHC_CMD11  (SDHC_XFERTYP_CMDINX(11) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD12  (SDHC_XFERTYP_CMDINX(12) | SDHC_XFERTYP_CMDTYP(ESDHC_XFERTYP_CMDTYP_ABORT) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_CMD13  (SDHC_XFERTYP_CMDINX(13) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_ACMD13 (SDHC_XFERTYP_CMDINX(13) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD15  (SDHC_XFERTYP_CMDINX(15) | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_NO))
#define ESDHC_CMD16  (SDHC_XFERTYP_CMDINX(16) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD17  (SDHC_XFERTYP_CMDINX(17) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48) | SDHC_XFERTYP_DTDSEL_MASK)
#define ESDHC_CMD18  (SDHC_XFERTYP_CMDINX(18) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48) | SDHC_XFERTYP_DTDSEL_MASK |SDHC_XFERTYP_MSBSEL_MASK | SDHC_XFERTYP_AC12EN_MASK)
#define ESDHC_CMD20  (SDHC_XFERTYP_CMDINX(20) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_ACMD22 (SDHC_XFERTYP_CMDINX(22) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48) | SDHC_XFERTYP_DTDSEL_MASK)
#define ESDHC_ACMD23 (SDHC_XFERTYP_CMDINX(23) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD24  (SDHC_XFERTYP_CMDINX(24) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD25  (SDHC_XFERTYP_CMDINX(25) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48) | SDHC_XFERTYP_MSBSEL_MASK | SDHC_XFERTYP_AC12EN_MASK)
#define ESDHC_CMD26  (SDHC_XFERTYP_CMDINX(26) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD27  (SDHC_XFERTYP_CMDINX(27) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD28  (SDHC_XFERTYP_CMDINX(28) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_CMD29  (SDHC_XFERTYP_CMDINX(29) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_CMD30  (SDHC_XFERTYP_CMDINX(30) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD32  (SDHC_XFERTYP_CMDINX(32) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD33  (SDHC_XFERTYP_CMDINX(33) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD34  (SDHC_XFERTYP_CMDINX(34) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD35  (SDHC_XFERTYP_CMDINX(35) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD36  (SDHC_XFERTYP_CMDINX(36) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD37  (SDHC_XFERTYP_CMDINX(37) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD38  (SDHC_XFERTYP_CMDINX(38) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_CMD39  (SDHC_XFERTYP_CMDINX(39) | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD40  (SDHC_XFERTYP_CMDINX(40) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_ACMD41 (SDHC_XFERTYP_CMDINX(41) | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD42  (SDHC_XFERTYP_CMDINX(42) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_ACMD42 (SDHC_XFERTYP_CMDINX(42) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_ACMD51 (SDHC_XFERTYP_CMDINX(51) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD52  (SDHC_XFERTYP_CMDINX(52) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD53  (SDHC_XFERTYP_CMDINX(53) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD55  (SDHC_XFERTYP_CMDINX(55) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48))
#define ESDHC_CMD56  (SDHC_XFERTYP_CMDINX(56) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_CMD60  (SDHC_XFERTYP_CMDINX(60) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))
#define ESDHC_CMD61  (SDHC_XFERTYP_CMDINX(61) | SDHC_XFERTYP_CICEN_MASK | SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_48BUSY))

/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

typedef struct esdhc_command_struct
{
    uint_32 COMMAND;
    uint_32 ARGUMENT;
    uint_32 BLOCKS;
    uint_32 BLOCKSIZE;
    uint_32 RESPONSE[4];
    
} ESDHC_COMMAND_STRUCT, _PTR_ ESDHC_COMMAND_STRUCT_PTR;



/*
** ESDHC_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a esdhc driver is initialized.
*/
typedef struct esdhc_init_struct
{
    /* The device number */
    uint_32 CHANNEL;

    /* The communication baud rate */
    uint_32 BAUD_RATE;

    /* The module input clock */
    uint_32 CLOCK_SPEED;
   
} ESDHC_INIT_STRUCT, _PTR_ ESDHC_INIT_STRUCT_PTR;

typedef const ESDHC_INIT_STRUCT _PTR_ ESDHC_INIT_STRUCT_CPTR;

/*--------------------------------------------------------------------------*/
/* 
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif


extern pointer _bsp_get_esdhc_base_address(uint_8);
extern uint_32 _bsp_get_esdhc_vector(uint_8);
extern _mqx_int _esdhc_install(char_ptr,ESDHC_INIT_STRUCT_CPTR);


#ifdef __cplusplus
}
#endif


#endif 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/ipif_add.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipif_add.c$
* $Version : 3.8.12.0$
* $Date    : Sep-19-2012$
*
* Comments:
*
*   This file contains the implementation of the
*   packet driver interface.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "route.h"
#include <arp.h>

IP_IF_PTR         IF_FREE =  NULL;        /* linked list of free IP_IFs */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_add
*  Parameters     :
*
*     pointer              mhandle     [IN] the packet driver handle
*     _rtcs_if_handle      ihandle     [OUT] the IP interface handle
*     RTCS_IF_STRUCT_PTR   if_ptr      [IN] the call table
*     _ip_address          address     not used
*     _ip_address          locmask     not used
*     _ip_address          network     not used
*     _ip_address          netmask     not used
*
*  Comments       :
*        Registers a hardware interface with RTCS.
*
*END*-----------------------------------------------------------------*/

void IPIF_add
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */
   IP_CFG_STRUCT_PTR IP_cfg_ptr;
   IP_IF_PTR         ipif;
   uint_32           i, error;

   IP_cfg_ptr = RTCS_getcfg(IP);

   /* Allocate a block of entries if none are left */
   if (!IF_FREE) {
      ipif = RTCS_mem_alloc_zero(IPIFALLOC_SIZE * sizeof(IP_IF));
      if (ipif) {
         _mem_set_type(ipif, MEM_TYPE_IP_IF);

         for (i = 0; i < IPIFALLOC_SIZE; i++) {
            ipif->HANDLE = IF_FREE;
            IF_FREE = ipif;
            ipif++;
         } /* Endfor */
      } /* Endif */
   } /* Endif */

   /* Dequeue a free entry */
   ipif = IF_FREE;
   if (!ipif) {
      RTCSCMD_complete(parms, RTCSERR_IP_IF_ALLOC);
      return;
   } /* Endif */

   /* Initialize the interface */
   IF_FREE = ipif->HANDLE;
   ipif->HANDLE = parms->mhandle;
   ipif->DEVICE = *parms->if_ptr;
   ipif->ARP    = NULL;
   ipif->BOOTFN = NULL;
   ipif->MTU_FN = NULL;
   error = ipif->DEVICE.OPEN(ipif);
   if (error) {
      ipif->HANDLE = IF_FREE;
      IF_FREE = ipif;
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */

#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   /* If IGMP_ipif_add fails, it isn't sufficient reason to abort IPIF_add */
   IGMP_ipif_add(ipif);
#endif

   parms->ihandle = (_rtcs_if_handle)ipif;
   RTCSCMD_complete(parms, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_bind
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     [IN] the IP interface handle
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     [IN] the local address
*     _ip_address          locmask     not used
*     _ip_address          network     not used
*     _ip_address          netmask     [IN] the network address mask
*
*  Comments       :
*        Starts bind of an IP address and network to a hardware interface.
*
*END*-----------------------------------------------------------------*/

void IPIF_bind
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   _ip_address       address, netmask;
   uint_32           error = RTCS_OK;

   /* Start CR 2303 */
   if (parms->ihandle==NULL) {
      RTCSCMD_complete(parms, RTCSERR_INVALID_PARAMETER);
      return;
   } /* Endif */
   /* End CR 2303 */

   address = parms->address;
   netmask = parms->netmask;

   /*
   ** Make sure the netmask is valid.  We use the fact that
   ** (x & x+1) == 0  <=>  x = 2^n-1.
   */
   if (~netmask & (~netmask + 1)) {
      RTCSCMD_complete(parms, RTCSERR_IP_BIND_MASK);
      return;
   } /* Endif */

   /*
   ** Make sure the address is valid.
   */
   if (((address & ~netmask) == 0)
    || ((address & ~netmask) == ~netmask)) {
      RTCSCMD_complete(parms, RTCSERR_IP_BIND_ADDR);
      return;
   } /* Endif */

   if (parms->probe) {
      // probe IP address here, set error if in use
      if (ARP_request(parms->ihandle, address, address ) != RTCS_OK) {
         error = RTCSERR_SEND_FAILED;
      }
      RTCSCMD_complete(parms, error);
   }
   else
   {
      IPIF_bind_finish (parms);
   }
#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);

#endif /* RTCSCFG_ENABLE_IP4 */
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_bind_finish
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     [IN] the IP interface handle
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     [IN] the local address
*     _ip_address          locmask     not used
*     _ip_address          network     not used
*     _ip_address          netmask     [IN] the network address mask
*
*  Comments       :
*        Finishes bind of an IP address and network to a hardware interface.
*
*END*-----------------------------------------------------------------*/

void IPIF_bind_finish
   (
      IPIF_PARM_PTR  parms
   )
{
#if RTCSCFG_ENABLE_IP4   
    IP_CFG_STRUCT_PTR IP_cfg_ptr;
   uint_32           error = RTCS_OK;
   
   IP_cfg_ptr = RTCS_getcfg(IP);
   
   if (parms->probe)
   {
      if (ARP_is_complete (parms->ihandle, parms->address)) {
         error = RTCSERR_TCP_ADDR_IN_USE;
      }
   }
   if (!error) {
      /* Create the route entry for the directly connected network */
      error = IP_route_add_direct(parms->address, parms->netmask, (IP_IF_PTR)parms->ihandle,
         (IP_IF_PTR)parms->ihandle);
   }
   /* Add the IP and the LOCALHOST interface into the routing table */
   if (!error) {
      error = IP_route_add_direct(parms->address, 0xFFFFFFFF, (IP_IF_PTR)parms->ihandle,
         RTCS_IF_LOCALHOST_PRV);
   } /* Endif */

   if (error) {
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */

#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   /* IGMP_ipif_bind failure isn't sufficient reason to abort IPIF_bind */
   IGMP_ipif_bind((IP_IF_PTR)parms->ihandle, parms->address);
#endif

   RTCSCMD_complete(parms, error);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);

#endif /* RTCSCFG_ENABLE_IP4 */
   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_bind_ppp
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     [IN] the IP interface handle
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     [IN] the local address
*     _ip_address          locmask     not used
*     _ip_address          network     [IN] the peer address
*     _ip_address          netmask     not used
*
*  Comments       :
*        Binds an IP address and network to a hardware interface.
*
*END*-----------------------------------------------------------------*/

void IPIF_bind_ppp
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   IP_CFG_STRUCT_PTR IP_cfg_ptr;
   _ip_address       address, peer;
   uint_32           error;

   IP_cfg_ptr = RTCS_getcfg(IP);

   address = parms->address;
   peer    = parms->network;
   
   /* Create the route entry for the directly connected peer */
   error = IP_route_add_virtual(peer, 0xFFFFFFFF, address,
      INADDR_ANY, INADDR_ANY, parms->ihandle, NULL);

   /* Add the IP and the LOCALHOST interface into the routing table */
   if (!error) {
      error = IP_route_add_direct(address, 0xFFFFFFFF, parms->ihandle, RTCS_IF_LOCALHOST_PRV);
   } /* Endif */

   if (error) {
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */

#if RTCSCFG_ENABLE_IGMP
   /* IGMP_ipif_bind failure isn't sufficient reason to abort IPIF_bind */
   IGMP_ipif_bind((IP_IF_PTR)parms->ihandle, address);
#endif

   RTCSCMD_complete(parms, RTCS_OK);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);

#endif /* RTCSCFG_ENABLE_IP4 */
   

} /* Endbody */

#if RTCSCFG_ENABLE_GATEWAYS
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_gate_add
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     not used
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     [IN] the gateway address
*     _ip_address          locmask     [IN] the gateway metric
*     _ip_address          network     [IN] the network address
*     _ip_address          netmask     [IN] the network address mask
*
*  Comments       :
*        Adds a gateway to the routing table.
*
*END*-----------------------------------------------------------------*/

void IPIF_gate_add
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   _ip_address          netmask = parms->netmask;
   uint_32              error;

   /*
   ** Make sure the netmask is valid.  We use the fact that
   ** (x & x+1) == 0  <=>  x = 2^n-1.
   */
   if (~netmask & (~netmask + 1)) {
      RTCSCMD_complete(parms, RTCSERR_IP_BIND_MASK);
      return;
   } /* Endif */

   /* Start CR 1133 */
   error = IP_route_add_indirect(parms->address, netmask, parms->network, RTF_STATIC, parms->locmask);
   /* End CR 1133 */

   RTCSCMD_complete(parms, error);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);

#endif /* RTCSCFG_ENABLE_IP4 */   

} /* Endbody */

/* Start CR 1016 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_gate_add_redirect
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     not used
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     [IN] the gateway address
*     _ip_address          locmask     [IN] the gateway metric
*     _ip_address          network     [IN] the network address
*     _ip_address          netmask     [IN] the network address mask
*
*  Comments       :
*        Adds a gateway to the routing table with the REDIRECT flag set.
*
*END*-----------------------------------------------------------------*/

void IPIF_gate_add_redirect
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   _ip_address          netmask = parms->netmask;
   uint_32              error;

   /*
   ** Make sure the netmask is valid.  We use the fact that
   ** (x & x+1) == 0  <=>  x = 2^n-1.
   */
   if (~netmask & (~netmask + 1)) {
      RTCSCMD_complete(parms, RTCSERR_IP_BIND_MASK);
      return;
   } /* Endif */

   /* Start CR 1133 */
   error = IP_route_add_indirect(parms->address, netmask, parms->network, RTF_REDIRECT, parms->locmask);
   /* End CR 1133 */

   RTCSCMD_complete(parms, error);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);

#endif /* RTCSCFG_ENABLE_IP4 */    

} /* Endbody */

/* End CR 1016 */
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/pppfsm.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pppfsm.c$
* $Version : 3.8.7.0$
* $Date    : Aug-22-2012$
*
* Comments:
*
*   This file contains the implementation for the
*   {Link, IP} Control Protocol Finite State Machine.
*
*END************************************************************************/

/*
** fsm.c - {Link, IP} Control Protocol Finite State Machine.
**
** Copyright (c) 1989 Carnegie Mellon University.
** All rights reserved.
**
** Redistribution and use in source and binary forms are permitted
** provided that the above copyright notice and this paragraph are
** duplicated in all such forms and that any documentation,
** advertising materials, and other materials related to such
** distribution and use acknowledge that the software was developed
** by Carnegie Mellon University.  The name of the
** University may not be used to endorse or promote products derived
** from this software without specific prior written permission.
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
** WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

#include <ppp.h>
#include "ppp_prv.h"


static void PPPFSM_buildheader(PPPFSM_CFG_PTR, PCB_PTR, uchar, boolean, uint_32);

static void PPPFSM_timeout(pointer, PCB_PTR, boolean);

static void PPPFSM_recvconfreq(PPPFSM_CFG_PTR, _ppp_handle);
static void PPPFSM_recvconfack(PPPFSM_CFG_PTR);
static void PPPFSM_recvconfnak(PPPFSM_CFG_PTR, boolean(_CODE_PTR_)(PPPFSM_CFG_PTR));
static void PPPFSM_recvtermreq(PPPFSM_CFG_PTR);
static void PPPFSM_recvtermack(PPPFSM_CFG_PTR);
static void PPPFSM_recvcoderej(PPPFSM_CFG_PTR);

static void PPPFSM_sendconfrep(PPPFSM_CFG_PTR, uint_32);
static void PPPFSM_sendtermack(PPPFSM_CFG_PTR, boolean);
static void PPPFSM_sendcoderej(PPPFSM_CFG_PTR);

static void PPPFSM_sendconfreq(PPPFSM_CFG_PTR, PCB_PTR);
static void PPPFSM_sendtermreq(PPPFSM_CFG_PTR, PCB_PTR);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_init
* Returned Value  :  error code
* Comments        :
*     Called by application.  Initializes the Finite State Machine.
*
*END*-----------------------------------------------------------------*/

uint_32 PPPFSM_init
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      _ppp_handle       handle,
            /* [IN] - the PPP state structure */
      PPPFSM_CALL_PTR   call_ptr,
            /* [IN] - Protocol-specific call table */
      pointer           param
            /* [IN] - Parameter for protocol-specific calls */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_memzero(fsm, sizeof(PPPFSM_CFG));
   fsm->HANDLE  = handle;
   fsm->CALL    = call_ptr;
   fsm->PRIVATE = param;
   fsm->STATE   = PPP_STATE_INITIAL;
   fsm->CURID   = RTCS_rand() & 0xFF;

   /* Initialize the mutex */
   if (PPP_mutex_init(&fsm->MUTEX)) {
      return RTCSERR_PPP_INIT_MUTEX_FAILED;
   } /* Endif */

   return PPP_OK;
   
#else   

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4  */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_destroy
* Returned Value  :  error code
* Comments        :
*     Called by application.  Destroys the Finite State Machine.
*     Assumes the Finite State Machine has been initialized.
*
*END*-----------------------------------------------------------------*/

uint_32 PPPFSM_destroy
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN/OUT] - State Machine */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   uint_32 error = PPP_OK;

   PPP_mutex_lock(&fsm->MUTEX);
   if (fsm->STATE > PPP_STATE_CLOSED) {
      error = RTCSERR_PPP_FSM_ACTIVE;
   } else {
      fsm->STATE = PPP_STATE_INITIAL;
   } /* Endif */
   PPP_mutex_unlock(&fsm->MUTEX);
   if (!error) {
      PPP_mutex_destroy(&fsm->MUTEX);
   } /* Endif */
   return error;

#else   

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4  */   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_lowerup
* Returned Value  :  void
* Comments        :
*    Lower layer is up.
*
*END*-----------------------------------------------------------------*/

void PPPFSM_lowerup
   (
      PPPFSM_CFG_PTR    fsm
         /* [IN/OUT] - State Machine */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_mutex_lock(&fsm->MUTEX);

   switch(fsm->STATE) {
   case PPP_STATE_INITIAL:
      fsm->STATE = PPP_STATE_CLOSED;
      break;

   case PPP_STATE_STARTING:
      if (fsm->OPTIONS & PPP_OPT_SILENT) {
         fsm->STATE = PPP_STATE_STOPPED;
      } else {
         PPPFSM_sendconfreq(fsm, NULL);
         fsm->STATE = PPP_STATE_REQ_SENT;
      }/* Endif */
      break;
   }  /* Endswitch */

   PPP_mutex_unlock(&fsm->MUTEX);

#endif /* RTCSCFG_ENABLE_IP4 */
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_lowerdown
* Returned Value  :  void
* Comments        :
*    Cancel all timeouts and inform upper layers.  Lower layer is
*    down.
*
*END*-----------------------------------------------------------------*/

void PPPFSM_lowerdown
   (
      PPPFSM_CFG_PTR    fsm
         /* [IN/OUT] - State Machine */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR    ppp_ptr = fsm->HANDLE;

   PPP_mutex_lock(&fsm->MUTEX);

   switch(fsm->STATE)  {
   case PPP_STATE_CLOSED:
      fsm->STATE = PPP_STATE_INITIAL;
      break;

   case PPP_STATE_STOPPED:
      fsm->STATE = PPP_STATE_STARTING;
      break;

   case PPP_STATE_CLOSING:
      fsm->STATE = PPP_STATE_INITIAL;
      PPP_send_stop(ppp_ptr, fsm->CALL->PROTOCOL);
      break;

   case PPP_STATE_STOPPING:
   case PPP_STATE_REQ_SENT:
   case PPP_STATE_ACK_RCVD:
   case PPP_STATE_ACK_SENT:
      fsm->STATE = PPP_STATE_STARTING;
      PPP_send_stop(ppp_ptr, fsm->CALL->PROTOCOL);
      break;

   case PPP_STATE_OPENED:
      if (fsm->CALL->linkdown) {
         fsm->CALL->linkdown(fsm);
      } /* Endif */
      fsm->STATE = PPP_STATE_STARTING;
      break;
   } /* Endswitch */

   PPP_mutex_unlock(&fsm->MUTEX);

#endif /* RTCSCFG_ENABLE_IP4 */
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_open
* Returned Value  :  void
* Comments        :
*     Called by application.  Begin negotiating the link.
*
*END*-----------------------------------------------------------------*/

void PPPFSM_open
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      uint_32           options
            /* [IN] - Startup options */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_mutex_lock(&fsm->MUTEX);
   fsm->OPTIONS = options;

   switch (fsm->STATE) {
   case PPP_STATE_INITIAL:
      fsm->STATE = PPP_STATE_STARTING;
      break;

   case PPP_STATE_CLOSED:
      if (options & PPP_OPT_SILENT) {
         fsm->STATE = PPP_STATE_STOPPED;
      } else {
         /* Send an initial Configure-Request */
         PPPFSM_sendconfreq(fsm, NULL);
         fsm->STATE = PPP_STATE_REQ_SENT;
      } /* Endif */
      break;

   case PPP_STATE_CLOSING:
      fsm->STATE = PPP_STATE_STOPPING;
      /* fall through */
   case PPP_STATE_STOPPING:
   case PPP_STATE_STOPPED:
      if (options & PPP_OPT_RESTART) {
         PPPFSM_sendconfreq(fsm, NULL);
         fsm->STATE = PPP_STATE_REQ_SENT;
      } /* Endif */
      break;

   case PPP_STATE_OPENED:
      if (options & PPP_OPT_RESTART) {
         if (fsm->CALL->linkdown) {
            fsm->CALL->linkdown(fsm);
         } /* Endif */
         PPPFSM_sendconfreq(fsm, NULL);
         fsm->STATE = PPP_STATE_REQ_SENT;
      } /* Endif */
      break;
   } /* Endswitch */

   PPP_mutex_unlock(&fsm->MUTEX);

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_close
* Returned Value  :  void
* Comments        :
*     Called by application.  Begin closing the link.
*
*END*-----------------------------------------------------------------*/

void PPPFSM_close
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN/OUT] - State Machine */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_mutex_lock(&fsm->MUTEX);
   switch (fsm->STATE) {
   case PPP_STATE_STARTING:
      fsm->STATE = PPP_STATE_INITIAL;
      break;
   case PPP_STATE_STOPPED:
      fsm->STATE = PPP_STATE_CLOSED;
      break;
   case PPP_STATE_STOPPING:
      fsm->STATE = PPP_STATE_CLOSING;
      break;

   case PPP_STATE_OPENED:
      if (fsm->CALL->linkdown) {
         fsm->CALL->linkdown(fsm);
      } /* Endif */
      /* fall through */
   case PPP_STATE_REQ_SENT:
   case PPP_STATE_ACK_RCVD:
   case PPP_STATE_ACK_SENT:
      PPPFSM_sendtermreq(fsm, NULL);
      fsm->STATE = PPP_STATE_CLOSING;
      break;
   } /* Endswitch */
   PPP_mutex_unlock(&fsm->MUTEX);

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_timeout
* Returned Value  :  void
* Comments        :
*     Called by PPP_tx_task.  Timeout expired.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_timeout
   (
      pointer        fsm_ptr,
            /* [IN/OUT] - State Machine */
      PCB_PTR        packet,
            /* [IN] - expired packet */
      boolean        hard
            /* [IN] - TRUE if this is a hard timeout (TO- event) */
   )
{ /* Body */
   PPPFSM_CFG_PTR    fsm = fsm_ptr;

   PPP_mutex_lock(&fsm->MUTEX);
   switch (fsm->STATE) {
   case PPP_STATE_CLOSING:
   case PPP_STATE_STOPPING:
      if (hard) {
         /* We've waited for an ack long enough */
         fsm->STATE -= 2;  /* Stopping/Closing -> Stopped/Closed */
      } /* Endif */
      break;

   case PPP_STATE_REQ_SENT:
   case PPP_STATE_ACK_RCVD:
   case PPP_STATE_ACK_SENT:
      if (hard) {
         fsm->STATE = PPP_STATE_STOPPED;
      } else if (fsm->STATE == PPP_STATE_ACK_RCVD) {
         fsm->STATE = PPP_STATE_REQ_SENT;
      } /* Endif */
      break;
   } /* Endswitch */
   PPP_mutex_unlock(&fsm->MUTEX);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_input
* Returned Value  :  void
* Comments        :
*     Called by PPP_rx_task.  Parses a xCP packet.
* Side effects    :
*     Consumes (sends or frees) the packet.
*
*END*-----------------------------------------------------------------*/

void PPPFSM_input
   (
      PCB_PTR        pcb,
            /* [IN] - xCP packet */
      pointer        fsm_data
            /* [IN/OUT] - State Machine */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPPFSM_CFG_PTR fsm = fsm_data;
   uint_32_ptr    stat;
   uchar_ptr      inp;
   uint_16        pcblen, len;

   /*
   ** Parse header (code, id and length).
   ** If packet is too short, drop it.
   */

   stat = NULL;
   fsm->PACKET = pcb;
   inp    = pcb->FRAG[0].FRAGMENT + 2; /* skip the protocol field */
   pcblen = pcb->FRAG[0].LENGTH - 2;

   PPP_mutex_lock(&fsm->MUTEX);
   if (pcblen < CP_HDR_LEN) {
      stat = &fsm->ST_CP_SHORT;
   } else {
      fsm->CODE = *inp++;
      fsm->ID = *inp++;
      len = *inp++ << 8;
      len += *inp++;
      if (len < CP_HDR_LEN) {
         stat = &fsm->ST_CP_SHORT;
      } else if (len > pcblen) {
         stat = &fsm->ST_CP_SHORT;
      } else if (fsm->STATE < PPP_STATE_CLOSED) {
         stat = &fsm->ST_CP_DOWN;
      } /* Endif */
   } /* Endif */

   if (stat) {
      PPP_mutex_unlock(&fsm->MUTEX);
      ++*stat;
      PCB_free(pcb);
      return;
   } /* Endif */

   fsm->LENGTH = len - CP_HDR_LEN;
   fsm->DATA   = inp;
   /*
   ** Action depends on code.
   */
   switch (fsm->CODE) {
   case CP_CODE_CONF_REQ:
      PPPFSM_recvconfreq(fsm, fsm->HANDLE);
      break;

   case CP_CODE_CONF_ACK:
      PPPFSM_recvconfack(fsm);
      break;

   case CP_CODE_CONF_NAK:
      PPPFSM_recvconfnak(fsm, fsm->CALL->recvnak);
      break;

   case CP_CODE_CONF_REJ:
      PPPFSM_recvconfnak(fsm, fsm->CALL->recvrej);
      break;

   case CP_CODE_TERM_REQ:
      PPPFSM_recvtermreq(fsm);
      break;

   case CP_CODE_TERM_ACK:
      PPPFSM_recvtermack(fsm);
      break;

   case CP_CODE_CODE_REJ:
      PPPFSM_recvcoderej(fsm);
      break;

   default:
      if (!fsm->CALL->recvcode || !fsm->CALL->recvcode(fsm)) {
         PPPFSM_sendcoderej(fsm);
      } /* Endif */
      break;
   } /* Endswitch */
   PPP_mutex_unlock(&fsm->MUTEX);

#else

    PCB_free(pcb);

#endif /* RTCSCFG_ENABLE_IP4   */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_buildheader
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_send*.  Builds the CP header before sending
*     a packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_buildheader
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN] - State Machine */
      PCB_PTR           pcb,
            /* [IN] - packet */
      uchar             code,
            /* [IN] - packet code, 0 means use fsm->CODE */
      boolean           keepid,
            /* [IN] - packet id, FALSE mean use fsm->ID */
      uint_32           size
            /* [IN] - length of packet data */
   )
{ /* Body */
   uchar_ptr outp = pcb->FRAG[0].FRAGMENT + 2;

   if (!code) code = fsm->CODE;
   *outp++ = code;

   if (!keepid) {
      *outp = fsm->CURID;
      fsm->CURID = (fsm->CURID + 1) & 0xFF;
   } /* Endif */
   outp++;

   size += CP_HDR_LEN;
   *outp++ = (size >> 8) & 0xFF;
   *outp++ =  size       & 0xFF;

   pcb->FRAG[0].LENGTH = size + 2;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_recvconfreq
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_Input.  Parses a Configure-Request packet.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends or frees) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_recvconfreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      _ppp_handle       handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */
   PPP_CFG_PTR    ppp_ptr = handle;
   uint_32        size;

   switch (fsm->STATE) {
   case PPP_STATE_CLOSED:
      PPPFSM_sendtermack(fsm, FALSE);
      return;
   case PPP_STATE_CLOSING:
   case PPP_STATE_STOPPING:
      PCB_free(fsm->PACKET);
      return;

   case PPP_STATE_OPENED:
      /* Go down and restart negotiation */
      if (fsm->CALL->linkdown) {
         fsm->CALL->linkdown(fsm);
      } /* Endif */
      PPPFSM_sendconfreq(fsm, NULL);
      fsm->STATE = PPP_STATE_REQ_SENT;
      break;

   case PPP_STATE_STOPPED:
      /* Negotiation started by our peer */
      PPPFSM_sendconfreq(fsm, NULL);
      fsm->STATE = PPP_STATE_REQ_SENT;
      break;
   } /* Endswitch */

   /*
   ** Pass the requested configuration options
   ** to protocol-specific code for checking.
   **
   ** !! Packet consumed here !!
   */
   if (fsm->CALL->recvreq) {    /* Check CI */
      size = fsm->CALL->recvreq(fsm, fsm->NAKS >= _PPP_MAX_CONF_NAKS);
      PPPFSM_buildheader(fsm, fsm->PACKET, 0, TRUE, size);
      PPP_send_one(ppp_ptr, fsm->CALL->PROTOCOL, fsm->PACKET);
   } else if (fsm->LENGTH) {
      PPPFSM_sendconfrep(fsm, CP_CODE_CONF_REJ);
   } else {
      PPPFSM_sendconfrep(fsm, CP_CODE_CONF_ACK);
   } /* Endif */

   if (fsm->CODE == CP_CODE_CONF_ACK) {
      if (fsm->STATE == PPP_STATE_ACK_RCVD) {
         /* Inform upper layers */
         if (fsm->CALL->linkup) {
            if (!fsm->CALL->linkup(fsm)) {
               PPPFSM_sendtermreq(fsm, NULL);
               fsm->STATE = PPP_STATE_CLOSING;
               return;
            } /* Endif */
         } /* Endif */
         fsm->STATE = PPP_STATE_OPENED;
         PPP_send_stop(ppp_ptr, fsm->CALL->PROTOCOL);
      } else {
         fsm->STATE = PPP_STATE_ACK_SENT;
      } /* Endif */
      fsm->NAKS = 0;

   } else { /* We sent a NAK or a REJ */
      if (fsm->STATE != PPP_STATE_ACK_RCVD) {
         fsm->STATE = PPP_STATE_REQ_SENT;
      } /* Endif */
      if (fsm->CODE == CP_CODE_CONF_NAK ) {
         ++fsm->NAKS;
      } /* Endif */
   } /* Endif */
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_recvconfack
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Parses a Configure-Ack packet.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends or frees) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_recvconfack
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN/OUT] - State Machine */
   )
{ /* Body */

   /* Verify the packet */
   if (fsm->ID != fsm->REQID) {
      PCB_free(fsm->PACKET);
      return;
   } else if (fsm->CALL->recvack) {
      if (!fsm->CALL->recvack(fsm)) {
         ++fsm->ST_CP_BAD_ACK;
         PCB_free(fsm->PACKET);
         return;
      } /* Endif */
   } else if (fsm->LENGTH) {
      ++fsm->ST_CP_BAD_ACK;
      PCB_free(fsm->PACKET);
      return;
   } /* Endif */

   /*
   ** !! Packet consumed here !!
   */
   switch (fsm->STATE) {
   case PPP_STATE_CLOSED:
   case PPP_STATE_STOPPED:
      
      PPPFSM_sendtermack(fsm, FALSE);
      break;

   case PPP_STATE_REQ_SENT:
      /* Restart retransmissions */
      fsm->STATE = PPP_STATE_ACK_RCVD;
      PCB_free(fsm->PACKET);
      PPP_send_restart(fsm->HANDLE, fsm->CALL->PROTOCOL);
      break;

   case PPP_STATE_ACK_RCVD:
      PPPFSM_sendconfreq(fsm, fsm->PACKET);
      fsm->STATE = PPP_STATE_REQ_SENT;
      break;

   case PPP_STATE_ACK_SENT:
      /* Inform upper layers */
      if (fsm->CALL->linkup) {
         if (!fsm->CALL->linkup(fsm)) {
            PPPFSM_sendtermreq(fsm, fsm->PACKET);
            fsm->STATE = PPP_STATE_CLOSING;
            return;
         } /* Endif */
      } /* Endif */
      fsm->STATE = PPP_STATE_OPENED;
      PCB_free(fsm->PACKET);
      PPP_send_stop(fsm->HANDLE, fsm->CALL->PROTOCOL);
      break;

   case PPP_STATE_OPENED:
      /* Restart negotiation */
      if (fsm->CALL->linkdown) {
         fsm->CALL->linkdown(fsm);
      } /* Endif */
      PPPFSM_sendconfreq(fsm, fsm->PACKET);
      fsm->STATE = PPP_STATE_REQ_SENT;
      break;

   default:
      PCB_free(fsm->PACKET);
      break;
   } /* Endswitch */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_recvconfnak
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Parses a Configure-Nak or
*     Configure-Reject packet.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends or frees) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_recvconfnak
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      boolean (_CODE_PTR_ call)(PPPFSM_CFG_PTR)
            /* [IN] - Protocol-specific callback for this packet */
   )
{ /* Body */

   /* Verify the packet */
   if (fsm->ID != fsm->REQID) {
      PCB_free(fsm->PACKET);
      return;

   } else if (!call || !call(fsm)) {
      if (fsm->CODE == CP_CODE_CONF_NAK) {
         ++fsm->ST_CP_BAD_NAK;
      } else {
         ++fsm->ST_CP_BAD_REJ;
      } /* Endif */
      PCB_free(fsm->PACKET);
      return;
   } /* Endif */

   /*
   ** !! Packet consumed here !!
   */
   switch (fsm->STATE) {
   case PPP_STATE_CLOSED:
   case PPP_STATE_STOPPED:
      PPPFSM_sendtermack(fsm, FALSE);
      break;

   case PPP_STATE_REQ_SENT:
   case PPP_STATE_ACK_SENT:
      /* They didn't agree -- try another request */
      PPPFSM_sendconfreq(fsm, fsm->PACKET);
      break;

   case PPP_STATE_ACK_RCVD:
      PPPFSM_sendconfreq(fsm, fsm->PACKET);
      fsm->STATE = PPP_STATE_REQ_SENT;
      break;

   case PPP_STATE_OPENED:
      /* Restart negotiation */
      if (fsm->CALL->linkdown) {
         fsm->CALL->linkdown(fsm);
      } /* Endif */
      PPPFSM_sendconfreq(fsm, fsm->PACKET);
      fsm->STATE = PPP_STATE_REQ_SENT;
      break;

   default:
      PCB_free(fsm->PACKET);
      break;
   } /* Endswitch */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_recvtermreq
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Parses a Terminate-Request packet.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_recvtermreq
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN/OUT] - State Machine */
   )
{ /* Body */

   /*
   ** !! Packet consumed here !!
   */
   switch (fsm->STATE) {
   case PPP_STATE_ACK_RCVD:
   case PPP_STATE_ACK_SENT:
      fsm->STATE = PPP_STATE_REQ_SENT;
      PPPFSM_sendtermack(fsm, FALSE);
      break;

   case PPP_STATE_OPENED:
      /* Restart negotiation */
      if (fsm->CALL->linkdown) {
         fsm->CALL->linkdown(fsm);
      } /* Endif */
      PPPFSM_sendtermack(fsm, TRUE);
      fsm->STATE = PPP_STATE_STOPPING;
      break;

   default:
      PPPFSM_sendtermack(fsm, FALSE);
      break;
   } /* Endswitch */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_recvtermack
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Parses a Terminate-Ack packet.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends or frees) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_recvtermack
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN/OUT] - State Machine */
   )
{ /* Body */

   switch (fsm->STATE) {
   case PPP_STATE_CLOSING:
   case PPP_STATE_STOPPING:
      PCB_free(fsm->PACKET);
      PPP_send_stop(fsm->HANDLE, fsm->CALL->PROTOCOL);
      fsm->STATE -= 2;  /* Stopping/Closing -> Stopped/Closed */
      break;

   case PPP_STATE_ACK_RCVD:
      PCB_free(fsm->PACKET);
      fsm->STATE = PPP_STATE_REQ_SENT;
      break;

   case PPP_STATE_OPENED:
      if (fsm->CALL->linkdown) {
         fsm->CALL->linkdown(fsm);
      } /* Endif */
      PPPFSM_sendconfreq(fsm, fsm->PACKET);
      fsm->STATE = PPP_STATE_REQ_SENT;
      break;

   default:
      PCB_free(fsm->PACKET);
      break;
   } /* Endswitch */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_recvcoderej
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Parses a Code-Reject packet.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends or frees) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_recvcoderej
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN/OUT] - State Machine */
   )
{ /* Body */

   if (fsm->LENGTH < CP_HDR_LEN) {
      ++fsm->ST_CP_SHORT;
      PCB_free(fsm->PACKET);
      return;
   } /* Endif */

   /*
   ** Check if Code-Reject is catastrophic
   **
   ** !! Packet consumed here !!
   */
   if (!fsm->CALL->testcode || !fsm->CALL->testcode(fsm)) {
      if (fsm->STATE == PPP_STATE_ACK_RCVD) {
         fsm->STATE = PPP_STATE_REQ_SENT;
      } /* Endif */
      PCB_free(fsm->PACKET);

   } else {

      switch (fsm->STATE) {
      case PPP_STATE_CLOSING:
         PCB_free(fsm->PACKET);
         PPP_send_stop(fsm->HANDLE, fsm->CALL->PROTOCOL);
         fsm->STATE = PPP_STATE_CLOSED;
         break;

      case PPP_STATE_STOPPING:
      case PPP_STATE_REQ_SENT:
      case PPP_STATE_ACK_RCVD:
      case PPP_STATE_ACK_SENT:
         PCB_free(fsm->PACKET);
         PPP_send_stop(fsm->HANDLE, fsm->CALL->PROTOCOL);
         fsm->STATE = PPP_STATE_STOPPED;
         break;

      case PPP_STATE_OPENED:
         if (fsm->CALL->linkdown) {
            fsm->CALL->linkdown(fsm);
         } /* Endif */
         PPPFSM_sendtermreq(fsm, fsm->PACKET);
         fsm->STATE = PPP_STATE_STOPPING;
         break;

      default:
         PCB_free(fsm->PACKET);
         break;
      } /* Endswitch */
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_sendconfrep
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Builds a 'code' packet from
*     the packet in fsm, and sends it.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends) it.
*     Sets fsm->CODE to 'code'.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_sendconfrep
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      uint_32           code
            /* [IN] - packet code for reply */
   )
{ /* Body */

   fsm->CODE = fsm->PACKET->FRAG[0].FRAGMENT[2] = code;

   PPP_send_one(fsm->HANDLE, fsm->CALL->PROTOCOL, fsm->PACKET);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_sendtermack
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Builds a Terminate-Ack packet from
*     the packet in fsm, and sends it.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_sendtermack
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      boolean           delay
            /* [IN] - whether or not to Zero-Restart-Counter */
   )
{ /* Body */

   PPPFSM_buildheader(fsm, fsm->PACKET, CP_CODE_TERM_ACK, TRUE, 0);

   if (delay) {
      PPP_send_rexmit(fsm->HANDLE, fsm->CALL->PROTOCOL, fsm->PACKET,
                      1, PPPFSM_timeout, fsm);
   } else {
      PPP_send_one(fsm->HANDLE, fsm->CALL->PROTOCOL, fsm->PACKET);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_sendcoderej
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Builds a Code-Reject packet from
*     the packet in fsm, and sends it.
* Side effects    :
*     Assumes fsm->PACKET is valid, and consumes (sends) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_sendcoderej
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN/OUT] - State Machine */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = fsm->HANDLE;
   uchar_ptr   packet, src, dst;
   uint_16     length = fsm->PACKET->FRAG[0].LENGTH - 2;
   uint_16     size = ppp_ptr->SEND_OPTIONS->MRU - CP_HDR_LEN;

   /* Truncate the packet if necessary, so as not to exceed the MTU */
   if (length > size) {
      length = size;
   } /* Endif */

   /* Make room for a Code-Reject header */
   size = length;

   /* Copy the received packet to the data portion of the Code-Reject */
   packet = fsm->PACKET->FRAG[0].FRAGMENT + 2;
   src = packet + length;
   dst = src + CP_HDR_LEN;
   while (length--) *--dst = *--src;

   /* Build a Code-Reject header */
   PPPFSM_buildheader(fsm, fsm->PACKET, CP_CODE_CODE_REJ, FALSE, size);

   PPP_send_one(ppp_ptr, fsm->CALL->PROTOCOL, fsm->PACKET);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_sendconfreq
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Builds a Configure-Request packet
*     and sends it.
* Side effects    :
*     Starts the retransmission timer with the new
*        Configure-Request packet.
*     If 'packet' is non-NULL, assumes it's valid, and consumes
*        (sends) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_sendconfreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      PCB_PTR           packet
            /* [IN] - free packet */
   )
{ /* Body */
   PPP_CFG_PTR    ppp_ptr = fsm->HANDLE;
   uchar_ptr      outp;
   uint_32        size;

   if (fsm->STATE <= PPP_STATE_STOPPING || fsm->STATE >= PPP_STATE_OPENED) {
      /* Not currently negotiating -- reset options */
      if (fsm->CALL->resetreq) {
         fsm->CALL->resetreq(fsm);
      } /* Endif */
      fsm->NAKS = 0;
   } /* Endif */

   /* Stop the retransmission timer if necessary */
   if (fsm->STATE > PPP_STATE_STOPPED && fsm->STATE < PPP_STATE_OPENED) {
      PPP_send_stop(ppp_ptr, fsm->CALL->PROTOCOL);
   } /* Endif */

   /* Allocate a packet if necessary */
   if (!packet) {
      packet = PPP_pcballoc(fsm->CALL->PROTOCOL, ppp_ptr->SEND_OPTIONS->MRU);
      if (!packet) {
         ++fsm->ST_CP_NOBUFS;    /* Nonfatal error */
         return;
      } /* Endif */
   } /* Endif */

   /* Build the request packet */
   outp = packet->FRAG[0].FRAGMENT + 2;
   size = packet->FRAG[0].LENGTH - 2 - CP_HDR_LEN;

   if (fsm->CALL->buildreq) {
      size = fsm->CALL->buildreq(fsm, outp + CP_HDR_LEN, size);
   } /* Endif */

   fsm->REQID = fsm->CURID;
   PPPFSM_buildheader(fsm, packet, CP_CODE_CONF_REQ, FALSE, size);

   /* Send the request */
   PPP_send_rexmit(ppp_ptr, fsm->CALL->PROTOCOL, packet,
                   _PPP_MAX_CONF_RETRIES, PPPFSM_timeout, fsm);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPFSM_sendtermreq
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_input.  Builds a Terminate-Request packet from
*     the packet in fsm, and sends it.
* Side effects    :
*     Starts the retransmission timer with the Terminate-Request
*        packet.
*     If 'packet' is non-NULL, assumes it's valid, and consumes
*        (sends) it.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPFSM_sendtermreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN/OUT] - State Machine */
      PCB_PTR           packet
            /* [IN] - free packet */
   )
{ /* Body */
   PPP_CFG_PTR    ppp_ptr = fsm->HANDLE;

   /* Stop the retransmission timer if necessary */
   if (fsm->STATE > PPP_STATE_STOPPED && fsm->STATE < PPP_STATE_OPENED) {
      PPP_send_stop(ppp_ptr, fsm->CALL->PROTOCOL);
   } /* Endif */

   /* Allocate a packet if necessary */
   if (!packet) {
      packet = PPP_pcballoc(fsm->CALL->PROTOCOL, CP_HDR_LEN);
      if (!packet) {
         ++fsm->ST_CP_NOBUFS;    /* Nonfatal error */
         return;
      } /* Endif */
   } /* Endif */

   PPPFSM_buildheader(fsm, packet, CP_CODE_TERM_REQ, FALSE, 0);

   PPP_send_rexmit(ppp_ptr, fsm->CALL->PROTOCOL, packet,
                   _PPP_MAX_TERM_RETRIES, PPPFSM_timeout, fsm);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/dev_send.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dev_send.c$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*  This file contains USB device API specific function to send data.
*                                                               
*END*********************************************************************/
#include <mqx.h>

#include "usb.h"     //common public
#include "usb_prv.h" //common private

#include "dev_cnfg.h"
#include "devapi.h"  //device public
#include "dev_main.h" //device private

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_send_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Sends data on a specified endpoint.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_send_data
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] buffer to send */
      uint_8_ptr                  buff_ptr,
            
      /* [IN] length of the transfer */
      uint_32                    size
   )
{ /* Body */
   USB_STATUS                       error;
   XD_STRUCT_PTR                    xd_ptr;
   volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;
   
    if (handle == NULL)
    {
        #if _DEBUG
            printf("_usb_device_send_data: handle is NULL\n");
        #endif  
        return USBERR_ERROR;
    }

    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   
    #if PSP_HAS_DATA_CACHE
        /********************************************************
        If system has a data cache, it is assumed that buffer
        passed to this routine will be aligned on a cache line
        boundry. The following code will flush the
        buffer before passing it to hardware driver.   
        ********************************************************/
        USB_dcache_flush_mlines((pointer)buff_ptr,size); 
    #endif
     
    USB_lock();

    if (!usb_dev_ptr->XD_ENTRIES) 
    {
        USB_unlock();
        return USB_STATUS_TRANSFER_IN_PROGRESS;
    }

    /* Get a transfer descriptor */
    USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);
    usb_dev_ptr->XD_ENTRIES--;

    /* Initialize the new transfer descriptor */      
    xd_ptr->EP_NUM = ep_num;
    xd_ptr->BDIRECTION = USB_SEND;
    xd_ptr->WTOTALLENGTH = size;
    xd_ptr->WSTARTADDRESS = buff_ptr;
    xd_ptr->WSOFAR = 0;
   
    xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED;
    
    if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
        usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SEND != NULL)
    {
        error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
            usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SEND(handle, xd_ptr);    
    }
    else
    {
        #if _DEBUG
            printf("_usb_device_send_data: DEV_SEND is NULL\n");
        #endif  
        return USBERR_ERROR;
    }

    USB_unlock();
   
    if (error) 
    {
        #if _DEBUG
            printf("_usb_device_send_data, transfer failed\n");
        #endif  
        return USBERR_TX_FAILED;
    }
    return error;
} 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/sem_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sem_prv.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   semaphore component.
*
*END************************************************************************/
#ifndef __sem_prv_h__
#define __sem_prv_h__ 1

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* Used to mark a block of memory as belonging to the semaphore component */
#define SEM_VALID                     ((_mqx_uint)(0x73656d20))   /* "sem " */

#define SEM_MAX_WAITING_TASKS         ((uint_16)0)  /* Unlimited */

/* Flag bits for the connection */
#define SEM_WANT_SEMAPHORE            (0x1001)
#define SEM_AVAILABLE                 (0x1002)


/*--------------------------------------------------------------------------*/
/*                      DATA STRUCTURE DEFINITIONS                          */

/* SEM COMPONENT STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This is the base semaphore structure pointed to by the kernel data
 * structure COMPONENT field for semaphores
 */
typedef struct sem_component_struct
{

   /*! \brief The maximum number of semaphores allowed. */
   _mqx_uint        MAXIMUM_NUMBER;

   /*! \brief The number of semaphores to grow by when table full. */
   _mqx_uint        GROW_NUMBER;

   /*! \brief A validation stamp allowing for checking of memory overwrite. */
   _mqx_uint        VALID;

   /*! \brief The handle to the name table for semaphores. */
   pointer          NAME_TABLE_HANDLE;

} SEM_COMPONENT_STRUCT, _PTR_ SEM_COMPONENT_STRUCT_PTR;
/*! \endcond */

/* SEM STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This is the structure of an instance of a semaphore. 
 * 
 * The address is kept in the semaphore name table, associated with the name.
 */
typedef struct sem_struct
{

   /*! 
    * \brief This semaphore will be destroyed when all waiting tasks relinquish
    * their semaphore. Other tasks may not wait any more.
    */
   boolean         DELAYED_DESTROY;

   /*! 
    * \brief Policy settings. Specifies whether this semaphore has 
    * PRIORITY_QUEUEING, and/or PRIORITY_INHERITANCE.
    */
   _mqx_uint       POLICY;

   /*! 
    * \brief This is the queue of waiting tasks.  
    * 
    * This queue may be sorted in order of task priority it INHERITANCE is 
    * enabled. What is queued is the address of the handle provided to the user 
    * (SEM_COMPONENT_STRUCT).
    */
   QUEUE_STRUCT    WAITING_TASKS;

   /*! \brief The queue of tasks; each of which owns a semaphore. */
   QUEUE_STRUCT    OWNING_TASKS;

   /*! \brief The current count of the semaphore. */
   _mqx_uint       COUNT;

   /*! 
    * \brief The maximum count allowed for this semaphore.
    *     
    * Only used when SEM_STRICT is TRUE.
    */
   _mqx_uint       MAX_COUNT;

   /*! \brief A validation stamp for the semaphore. */
   _mqx_uint       VALID;
   
   /*! \brief The string name of the semaphore, includes NULL. */
   char            NAME[NAME_MAX_NAME_SIZE];

} SEM_STRUCT, _PTR_ SEM_STRUCT_PTR;
/*! \endcond */

/* SEM CONNECTION STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE   
 * 
 * \brief This is the struture whose address is returned to the user as a 
 * semaphore handle.
 */
typedef struct sem_connection_struct
{

   /*! \brief Pointer to the next item in WAITING TASK queue of the semaphore. */ 
   pointer         NEXT;
   /*! \brief Pointer to the previous item in WAITING TASK queue of the semaphore. */
   pointer         PREV;

   /*! \brief A validation stamp for the data structure. */
   _mqx_uint       VALID;

   /*! \brief The number of times this task has been priority boosted. */
   _mqx_uint       BOOSTED;

   /* A reserved field */
   /* Start SPR P171-0009-01     */
   /* _mqx_uint        RESERVED; */
   /* End SPR P171-0009-01       */

   /*! 
    * \brief This field is only used for STRICT semaphores.
    *     
    * A count of the number of semaphores owned by this task.
    * \n This is incremented by _sem_wait, and decremented by _sem_post.
    * \n A semaphore may be posted only if a wait has previously succeeded.
    */
   /* Start SPR P171-0010-01 */
   /* int        POST_STATE; */
   _mqx_int        POST_STATE;
   /* End SPR P171-0010-01   */
   
   /*! \brief The address of the task descriptor that owns this connection. */
   TD_STRUCT_PTR   TD_PTR;

   /*! 
    * \brief The address of the semaphore structure associated with this
    * connection. 
    */
   SEM_STRUCT_PTR  SEM_PTR;

    
} SEM_CONNECTION_STRUCT, _PTR_ SEM_CONNECTION_STRUCT_PTR;
/*! \endcond */

/* ANSI C prototypes */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern void      _sem_insert_priority_internal(QUEUE_STRUCT_PTR, 
   SEM_CONNECTION_STRUCT_PTR);
extern void      _sem_cleanup(TD_STRUCT_PTR);
extern _mqx_uint _sem_wait_internal(pointer, MQX_TICK_STRUCT_PTR, boolean);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/USB_timer.h<|end_filename|>
#ifndef _RTC_HEADER_H
  #define _RTC_HEADER_H
/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/
  #define ERR_SUCCESS             0
  #define ERR_INVALID_PARAM       -1
  #define ERR_TIMER_QUEUE_FULL	-2
  #define INVALID_TIME_COUNT		0xFFFFFFFF
/******************************************************************************
 * Types
 *****************************************************************************/

/* Timer Callback Function Prototype */
  #ifdef TIMER_CALLBACK_ARG
typedef void (*PFNTIMER_CALLBACK)(void *arg);
  #else
typedef void (*PFNTIMER_CALLBACK)(void);
  #endif
/* Timer Object Structure */
typedef struct _timer_object
{
  int msCount;                /* msec Timeout Value */
  PFNTIMER_CALLBACK pfnTimerCallback; /* Callback Function */
  #ifdef TIMER_CALLBACK_ARG
  void *arg;                          /* Callback Function Argument */
  #endif
} TIMER_OBJECT, *PTIMER_OBJECT;

/*****************************************************************************
 * Global Functions Prototypes
 *****************************************************************************/
extern void Init_periodic_app_timer(void);
extern INT8U Add_periodic_callback(PTIMER_OBJECT pTimerObject);
extern INT8U Remove_periodic_callback(INT8U index);

#endif /* _RTC_HEADER_H */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/log_prv.h<|end_filename|>
/*HEADER**********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* $FileName: log_prv.h$
* $Version : 3.8.4.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   Log component.
*
*END*************************************************************************/

#ifndef __log_prv_h__
#define __log_prv_h__ 1


/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

#define LOG_VALID           ((_mqx_uint)(0x6c6f6720))   /* "log " */

/* Control bits in the control flags */
#define LOG_ENABLED         (0x1000)


/*--------------------------------------------------------------------------*/
/*                      DATA STRUCTURE DEFINITIONS                          */

/*  LOG HEADER STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure is stored at the front of each log to provide information
 * about the current state of the log.
 */
typedef struct log_header_struct
{
    /*! \brief Control flags for the log. */
    uint_32       FLAGS;

    /*! \brief The sequence number for next write. */
    _mqx_uint     NUMBER;

    /*! \brief Where next log is to be written. */
    _mqx_uint_ptr LOG_WRITE;

    /*! \brief Where first log is to be read. */
    _mqx_uint_ptr LOG_READ;

    /*! \brief Where last log was written. */
    _mqx_uint_ptr LAST_LOG;

    /*! \brief Starting address of data. */
    _mqx_uint_ptr LOG_START;

    /*! \brief Ending address of data. */
    _mqx_uint_ptr LOG_END;

    /*! \brief The next log to read. */
    _mqx_uint_ptr LOG_NEXT;

    /*! \brief Current size of data. */
    _mqx_uint     SIZE;

    /*! \brief Maximum size of data. */
    _mqx_uint     MAX;

    /*! \brief Variable array of data. */
    _mqx_uint     DATA[1];

} LOG_HEADER_STRUCT, _PTR_ LOG_HEADER_STRUCT_PTR;
/*! \endcond */


/*  LOG COMPONENT STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief  This structure is used to store information required for log retrieval.
 * 
 * Its address is stored in the kernel component field of the kernel data structure.
 */
typedef struct log_component_struct
{
    /*! \brief A validation stamp to verify handle correctness. */
    _mqx_uint             VALID;

    /*! \brief The address of the log headers. */
    LOG_HEADER_STRUCT_PTR LOGS[LOG_MAXIMUM_NUMBER];

} LOG_COMPONENT_STRUCT, _PTR_ LOG_COMPONENT_STRUCT_PTR;
/*! \endcond */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fp.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fp.c$
* $Version : 3.8.12.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the functions for the formatting of
*   output for floating point numbers
*
*END************************************************************************/

#include <math.h>
#include <ctype.h>
#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "fpio_prv.h"


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_strtod
* Returned Value   : double the number obtained from the string
* Comments         :
*   this function converts a string to a double.
*
*END*-------------------------------------------------------------------------*/

static volatile double tmp_d1, tmp_d2; 

#ifdef NEED_STRTOD
/* The compiler does not provide a good strtod */


static const double _io_strtod_powers_of_ten[] = {
    1.0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9
};
static const double _io_strtod_inverse_powers_of_ten[] = {
    1.0, 1.0e-1, 1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6, 1.0e-7, 1.0e-8, 1.0e-9
};
/*!
 * \brief Converts a string to a double.
 * 
 * \param[in]     nptr   The string containing the number.
 * \param[in,out] endptr The string address after the number.
 * 
 * \return Converted string.
 * \return 0.0 (Failure.) 
 */ 
double _io_strtod
   (
      register char _PTR_ nptr, 
      char _PTR_ _PTR_    endptr
   )
{
   register int_32 x;       /* Partial result */
   register int_32 exp;     /* Power of 10 for the result */
   register double result;
   register _mqx_int ne;     /* Number of digits seen so far */
   register _mqx_int nx;     /* Number of didits used so far */
   register int_32 eminus, minus;
   register char _PTR_ p;

   /* skip leading white space */
   p = (char _PTR_)nptr;
   while (isspace(*p)) {
      ++p;
   } /* Endwhile */

   /* consume the leading '+' or '-' */
   minus = 0;
   if (*p == '+') {
      ++p;
   } else if (*p == '-') {
      ++p;
      minus = 1;
   } /* Endif */

   if ((*p != '.') && (!isdigit(*p))) {
      /* no conversion possible: return initial nptr value */
      if (endptr) {
         *endptr = (char _PTR_)nptr;
      } /* Endif */
      return (0.0);
   } /* Endif */

   /* skip leading zeros */
   while (*p == '0') {
      ++p;
   } /* Endwhile */

   result = 0;
   nx = 0;
   ne = 0;
   exp = 0;

   /* read the integer part */
   for (x = 0; isdigit(*p); ++p) {
      if (ne < MAX_PRECISION) {
         if (nx == 9) {
            if (ne == 9) {
               result = (double)x; /* d was still zero */
            } else {
               result = result * _io_strtod_powers_of_ten[9] + (double)x;
            } /* Endif */
            x = nx = 0;
         } /* Endif */
         x = 10 * x + (*p - '0');
         ++ne;
         ++nx;
      } else { /* ignore digits after max precision */
         ++exp;
      } /* Endif */
   } /* Endfor */

   /* read the fractional part */
   if (*p == '.') {
      for (++p; isdigit(*p); ++p) {
         if (ne == 0 && *p == '0') {
            --exp; /* skip leading zeros if no digits yet */
         } else if (ne < MAX_PRECISION) {
            --exp;
            if (nx == 9) {
               if (ne == 9) {
                  result = (double)x; /* d was still zero */
               } else {
                  result = result * _io_strtod_powers_of_ten[9] + (double)x;
               } /* Endif */
               x = 0, nx = 0;
            } /* Endif */
            x = 10 * x + (*p - '0'); 
            ++ne;
            ++nx;
         } /* Endif */
      } /* Endif */
   } /* Endfor */

   /* pick up the pending product in x */
   if (nx != 0) {
      if (x == 0) {
         exp += nx;
      } else {
         if (ne == 9) {
            result = (double)x; /* d was still zero */
         } else {
            result = result * _io_strtod_powers_of_ten[nx] + (double)x;
         } /* Endif */
      } /* Endif */
   } /* Endfor */

   /* read the exponent */
   if (*p == 'e' || *p == 'E') {
      ++p;
      eminus = 0;
      if (*p == '+') {
         ++p;
      } else if (*p == '-') {
         ++p;
         eminus = 1;
      } /* Endif */

      for (x = 0; isdigit(*p); ++p) {
         x = 10 * x + (*p - '0');
         /* watch for overflow and underflow */
         if (eminus) {
            /* check for underflow */
            if ((exp - x) < -324) {
               exp = 0;
               x = 999;
            } /* Endif */
         } else {
            /* check for overflow */
            if ((exp + x) > DBL_MAX_10_EXP) {
               exp = 0;
               x = 999;
            } /* Endif */
         } /* Endif */
      } /* Endfor */
      if (eminus) {
         if (x == 999) { /* underflow */
            _task_errno = MQX_ERANGE;
            if (endptr) {
               *endptr = p;
            } /* Endif */
            return (0.0);
         } /* Endif */
         exp -= x;
      } else {
         if (x == 999) { /* overflow */
            _task_errno = MQX_ERANGE;
            if (endptr) {
               *endptr = p;
            } /* Endif */
            return (minus ? -HUGE_VAL : HUGE_VAL);
         } /* Endif */
         exp += x;
      } /* Endif */
   } /* Endif */

   /* multiply in the exponent */
   if (exp != 0) {
      while (9 <= exp) {
         result *= _io_strtod_powers_of_ten[9];
         exp -= 9;
      } /* Endwhile */
      while (exp <= -9) {
         result *= _io_strtod_inverse_powers_of_ten[9];
         exp += 9;
      } /* Endwhile */
      /* now exp is between -8 and +8 */
      if (0 < exp) {
         result *= _io_strtod_powers_of_ten[exp];
      } else if (exp < 0) {
         result *= _io_strtod_inverse_powers_of_ten[-exp];
      } /* Endif */
   } /* Endif */

   if (endptr) {
      *endptr = (char *)p;
   } /* Endif */
   return (minus ? -result : result);

} /* Endbody */
#else
#ifndef strtod

extern double strtod(const char _PTR_, char _PTR_ _PTR_);
#endif

/*!
 * \brief Converts a string to a double.
 * 
 * \param[in]     nptr   Pointer to the string containing the number.
 * \param[in,out] endptr Pointer to the string address after the number.
 * 
 * \return Converted string.
 * \return 0.0 (Failure.) 
 */
double _io_strtod
   (
      char _PTR_ nptr, 
      char _PTR_ _PTR_ endptr
   )
{ /* Body */

   return strtod(nptr, endptr);

} /* Endbody */
#endif


#ifdef NEED_MODF
/* The compiler does not provide a good strtod */

static const uchar _io_modf_masktable[9] =
    { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
/*!
 * \brief Gets the fractional part.
 * 
 * \param[in]  input_dbl   The number to split.
 * \param[out] intpart_ptr Where to write the integral part of the double.
 * 
 * \return Fractional part of number.
 * \return 0 if exponent is larger than mantissa     
 */ 
double _io_modf
   (
      double input_dbl, 
      double _PTR_ intpart_ptr
   )
{ /* Body */
    FP_UNION  num;
    FP_UNION  intpart;
    int_32    i;
    int_32    exponent;
    int_32    numbits;
    int_32    numbytes;
#if defined(PSP_TMS32030) || defined(PSP_TMS32040)
    uint_32   temp32;
#endif

    intpart.DOUBLE = input_dbl;
    num.DOUBLE     = input_dbl;

    /*----------------------------------------------------------------*/
    /* exponent will have number of bits of the mantissa we want to   */
    /* save.  if less than zero save none, greater than total         */
    /* number of bits of mantissa then save it all.                   */
    /*----------------------------------------------------------------*/

   exponent = EXPOF(num.LONG);
   exponent = exponent - EXP_BIAS;
   if (exponent < 0 ) {
      *intpart_ptr = 0;
      return(input_dbl);
   } else if (exponent >= MANT_BITS) {
      *intpart_ptr = input_dbl;
      return(0);
   } /* Endif */
   
   exponent += NON_MANT_BITS;
   numbytes = exponent / 8;
   numbits  = exponent - (numbytes * 8);
#if defined(PSP_TMS32030) || defined(PSP_TMS32040)
   /* Must swap TI longwords */
   temp32 = intpart->LONG[1];
   intpart.LONG[1] = intpart.LONG[0];
   intpart.LONG[0] = temp32;
#endif
#if PSP_ENDIAN == MQX_BIG_ENDIAN
   for (i = numbytes + 1; i < BYTES_PER_DOUBLE; i++) {
      intpart.BYTE[i] = 0;
   } /* Endfor */
   intpart.BYTE[numbytes] = intpart.BYTE[numbytes] & _io_modf_masktable[numbits];
#else
   for (i = 0; i < (BYTES_PER_DOUBLE-1) - numbytes; i++) {
      intpart.BYTE[i] = 0;
   } /* Endfor */
   /* i has the index to the byte with some significant mantissa */
   intpart.BYTE[i] = intpart.BYTE[i] & _io_modf_masktable[numbits];
#endif
#if defined(PSP_TMS32030) || defined(PSP_TMS32040)
   /* Swap back */
   temp32 = intpart.LONG[1];
   intpart.LONG[1] = intpart.LONG[0];
   intpart.LONG[0] = temp32;
#endif

   num.DOUBLE = num.DOUBLE - intpart.DOUBLE;
   *intpart_ptr = intpart.DOUBLE;

   return(num.DOUBLE);

} /* Endbody */
#else
/*!
 * \brief Gets the fractional part.
 * 
 * \param[in]  input_dbl   The number to split.
 * \param[out] intpart_ptr Where to write the integral part of the double.
 * 
 * \return Fractional part of number.
 * \return 0 if exponent is larger than mantissa     
 */
double _io_modf
   (
      double input_dbl, 
      double _PTR_ intpart_ptr
   )
{ /* Body */
   return modf(input_dbl, intpart_ptr);
}
#endif

/*!
 * \brief Converts argument to ASCII string.
 * 
 * \param[in]  arg     The number to be converted.
 * \param[in]  ndigits The maximal width of the field.
 * \param[out] decpt   Where the decimal place should be.
 * \param[out] sign    The sign of the number.
 * \param[in]  eflag   Is this an E format number.
 * \param[out] buf     The character string of digits for the number.
 * \param[in]  type    Use lower or upper case. 
 * 
 * \return ASCII string. 
 */ 
char _PTR_ _io_cvt
   (
      double     arg,
      int_32    ndigits,
      int_32_ptr decpt,
      char _PTR_ sign,
      char       eflag,
      char _PTR_ buf,
      char       type
   )
{ /* Body */
    register int_32      r2;
             double      intpart;
             double      tmpintpart; 
             double      fracpart;
    register char _PTR_  p;
    register char _PTR_  p1;
             uint_32      i;
             int_32      tmp = 0;

   if (ndigits < 0) {
      ndigits = 0;
   } /* Endif */
   if (ndigits >= NDIG-1) {
      ndigits = NDIG-2;
   } /* Endif */
   r2 = 0;
   p = &buf[0];
   if (SIGNOF((unsigned long _PTR_)((pointer)&arg)))
   {
        *sign = (char)TRUE;
        arg = -arg;
   }
   else
   {
        *sign = (char)FALSE;
   }
   if (ISINFINITY((unsigned long _PTR_)((pointer)&arg)))
   {
      buf[0] = 'i';
      return(buf);
   }
   if (ISNAN((unsigned long _PTR_)((pointer)&arg)))
   {
      *sign = (char)FALSE;
      buf[0] = 'n';
      return(buf);
   }
   if (ISZERO((unsigned long _PTR_)((pointer)&arg)))
   {
      if (( type == 'e') || (type == 'E'))
      {
        *decpt = 1; /* avoid e_or_E type create string 0.000e-1 */
      }
      else
      {
        *decpt = 0;
      }
      for(i = 0; i < ndigits; i++)
      {
        buf[i] = '0';
      }
      buf[ndigits] = '\0';
      return(buf);
   }

   tmp_d1 = arg;
   /* modf return fraction part and set integer part */
   arg = modf(arg, (double _PTR_)(&intpart));

   /*
    * arg has decimal part, intpart has integer part.            
    * take the inparts digits one by one and stick them into the end
    * of the buffer then move them to the beginning of it.         
    */
   if (intpart != 0) {
      p1 = &buf[NDIG];
      while (intpart != 0) {
            /*
             * It's possible that inaccuracy will cause the division  
             * by 10 to come out a little bit low.  In C, conversions 
             * from floating point to integer are done by truncation. 
             * We add in .03 so that temp will be rounded up when it  
             * is converted to the nearest number of tenths, as done  
             * by the call to modf and the assignment to i.           
             */
         tmpintpart = (intpart / 10) + 0.03;
         tmpintpart = modf(tmpintpart, (double _PTR_)(&intpart));
         tmpintpart = tmpintpart * 10.0;
         *--p1 = (char)((uint_32)tmpintpart + '0');
         r2++;
      } /* Endwhile */
      while (p1 < &buf[NDIG]) {
         *p++ = *p1++;
      } /* Endwhile */
   } else {

      /*
       * if the intpart was zero, then get the decimal part so that it
       * does not have any zero directly to the right of the decimal  
       * point.  with each shift left of the decimal number adjust the
       * exponent.                       
       */
      if (arg > 0) {
        double temp;
        while (1 > (temp = arg*10))
        {
            arg = temp;
            r2--;
         } /* Endwhile */
      } /* Endif */

   } /* Endif */

   p1 = &buf[ndigits];
   if (eflag == 0) {
      tmp = r2;
      /*
       * Loop around adjusting the pointer up or down in the buffer.   
       * We must be careful not to move the pointer out of the range   
       * of the buffer.  If the pointer goes outside that range and    
       * the buffer is in very low or very high memory, the pointer    
       * value could "wrap" and cause later pointer comparisons to fail.
       */
      if (tmp > 0) {
         while (tmp && p1 < &buf[NDIG-1]) {
            p1++;
            tmp--;
         } /* Endwhile */
      } else {
         while (tmp && p1 > buf) {
            p1--;
            tmp++;
         } /* Endwhile */
         if (tmp < 0) {      /* pointer would have underflowed buffer */
            for (i = 0; i < ndigits; i++)
            {
                buf[i] = '0';
            }
            *decpt = 0;
            buf[ndigits] = '\0';
               /*
                * This indicates that the number is     
                * smaller than the precision they've    
                * given us.  The result will be 0.0.... 
                */
            return(buf);
         } /* Endif */
      } /* Endif */
   } /* Endif */
   *decpt = r2;

   /*
    * we now stick the fractional part in digit by digit regardless  
    * of whether there was a non-zero integer part            
    */
   while (p <= p1) {
      tmpintpart = arg * 10;
      tmpintpart = modf(tmpintpart, (double _PTR_)(&intpart));
      arg = tmpintpart;
      *p++ = (char)((int_32)intpart + '0');
   } /* Endwhile */
   if (!eflag && tmp) {
      /* precision is too large.   */
      /* return with what we have. */
      buf[NDIG-1] = '0';
      return(buf);
   } /* Endif */

   /*
    * round the number 
    */
   p = p1;
   *p1 += 5;
   while (*p1 > '9') {
      *p1 = '0';
      if (p1 > buf) {
         p1--;
         *p1 += 1;
      } else {
         *p1 = '1';
         (*decpt)++;
         if (eflag == 0) {
            if (p > buf) {
               *p = '0';
            } /* Endif */
            p++;
         } /* Endif eflag == 0 */
      } /* Endif */
   } /* Endwhile */
   *p = '\0';
   return(buf);

} /* Endbody */

/*!
 * \brief Make string Not A Number, and INFinite.
 * 
 * \param[out] bp          Where to put the number.
 * \param[in]  numstr      'i' for Infinite, 'n' for NAN, 'z' for ZERO.
 * \param[in]  printsign   Should the sign be printed.
 * \param[in]  printprefix Should a prefix be printed.
 * \param[in]  sign        The sign of the number.
 * \param[in]  type        Type of number for upper or lower case.  
 */ 
static void _io_inf_or_nan
    (
      char _PTR_ bp,
      char _PTR_ numstr,
      char       printsign,
      char       printprefix,
      char       sign,
      char       type
    )
{
    char shift = 'a' - 'A'; /* for lovercase */
    /* Conversion gave 0, infinity, or NAN, use f or F format for output */
     if (sign) 
     {
        *bp++ =  '-';
     } 
     else if (printsign) 
     {
        *bp++ =  '+';
     } 
     else if (printprefix) 
     {
        *bp++ =  ' ';
     }
    /* for uppercase */
    if (type == 'G' || type == 'E' || type == 'F')
    {
        shift = (char)0;
    }
    /* Infinity */
    if ( *numstr == 'i')
    {
    *bp++ = 'I' + shift;
    *bp++ = 'N' + shift;
    *bp++ = 'F' + shift;
    }
    /* NAN */
    else if (*numstr == 'n')
    {
    *bp++ = 'N' + shift;
    *bp++ = 'A' + shift;
    *bp++ = 'N' + shift;
    }
    *bp = '\0';
}

/*!
 * \brief Convert a number (exponent) to ASCII
 * 
 * \param[in] number The number to convert.
 * \param[in] str_ptr Where to store the converted number.
 * 
 * \return ASCII number. 
 */ 
int_32 _io_dtoa
   ( 
      int_32     number,
      char _PTR_ str_ptr
   )
{ /* Body */
   int_32   frac;
   char     i;
   int_32   digits;

   if (number < 0) {
      number = -number;
   }
   if (number > 99) {
      digits = 3;
   } else {
      digits = 2;
   }
   for (i = 1; i <= digits; i++) {
      frac = number % 10;
      number = number / 10;
      str_ptr[digits-i] = (char)(frac + '0');
   }
    return (digits);

} /* Endbody */

/*!
 * \brief Converts a double to E format output.
 * 
 * \param[out] buf         Where to put the number.
 * \param[in]  arg         The number to convert.
 * \param[in]  fillchar    The fill character to use.
 * \param[in]  printsign   Should the sign be printed.
 * \param[in]  printprefix Should a prefix be printed.
 * \param[in]  altformat   Makes sure that output is printed out as floating.
 * \param[in]  precision   What preicision to use.
 * \param[in]  e_or_E      Use lower or uppercase E.
 * 
 * \return Number in E format. 
 */ 
int_32 _io_dtoe
   ( 
      char _PTR_ buf,
      double     arg,
      char _PTR_ fillchar,
      char       printsign,
      char       printprefix,
      char       altformat,
      int_32     precision,
      char       e_or_E
   )
{ /* Body */
   char       sign;
   int_32     decpt;
   char _PTR_ numstr;
   char _PTR_ bp;
   char       cvtbuf[NDIG];

   numstr = _io_cvt(arg, precision + 1, &decpt, &sign, 1, cvtbuf, e_or_E);
   bp = buf;
   if ((*numstr == 'i') || (*numstr == 'n'))
   {
      /* infinity, or NAN */
        _io_inf_or_nan(bp, numstr, printsign, printprefix, sign, e_or_E);
        *fillchar = ' ';
   } else {

      if (sign) {
         *bp++ =  '-';
      } else if (printsign) {
         *bp++ =  '+';
      }
      else if (printprefix) {
         *bp++ =  ' ';
      } /* Endif */
      *bp++ = *numstr++;
      if ((*numstr != '\0') || altformat) {
         *bp++ = '.';
      } /* Endif */
      while (*numstr != '\0') {
        
         *bp++ = *numstr++;
      } /* Endwhile */
      *bp++ = e_or_E;
      if (decpt -1 >= 0) {
         *bp++ = '+';
      } else {
         *bp++ = '-';
      } /* Endif */
      /* update bp after putting in exp */
      bp += _io_dtoa(decpt - 1, bp);
      *bp = '\0';
   } /* Endif */

   return (int)(bp - buf);

} /* Endbody */


/*!
 * \brief Converts a double to F format output
 *
 * \param[out] buf         Where to put the number.
 * \param[in]  arg         The number to convert.
 * \param[in]  fillchar    The fill character to use.
 * \param[in]  printsign   Should the sign be printed.
 * \param[in]  printprefix Should a prefix be printed.
 * \param[in]  altformat   Makes sure that output is printed out as floating.
 * \param[in]  precision   What preicision to use.
 * \param[in]  f_or_F      Use lower or uppercase F. 
 * 
 * \return Number in F format.   
 */ 
int_32 _io_dtof
   (
      char _PTR_  buf,
      double      arg,
      char _PTR_  fillchar,
      char        printsign,
      char        printprefix,
      char        altformat,
      int_32      precision,
      char       f_or_F
   )
{ /* Body */
   char       sign;
   int_32     decpt;
   char _PTR_ numstr;
   char _PTR_ bp;
   char       cvtbuf[NDIG];

   bp = buf;
   if (precision > NDIG) {
      precision = NDIG;
   }

   numstr = _io_cvt(arg, precision, &decpt, &sign, 0, cvtbuf, f_or_F);

   if ((*numstr == 'i') || (*numstr == 'n'))
   {
        _io_inf_or_nan(bp, numstr,printsign , printprefix, sign, f_or_F);
        *fillchar = ' ';
   } else {
      if (sign) {
         *bp++ =  '-';
      } else if (printsign) {
         *bp++ =  '+';
      }
      else if (printprefix) {
         *bp++ =  ' ';
      } /* Endif */
      if (decpt <= 0) {
         *bp++ = '0';
         *bp++ = '.';
         while (decpt++ < 0) {
            *bp++ = '0';
         } /* Endwhile */
         while ((*bp++ = *numstr++) != 0) {
         } /* Endwhile */
         --bp; /* bump bp back to point to the null */
      } else {
         while ((*numstr != '\0') && (decpt-- != 0)) {
            *bp++ = *numstr++;
         } /* Endwhile */
         if ((*numstr != '\0') || altformat) {
            *bp++ = '.';
         } /* Endif */
         if (*numstr != '\0') {
            while ((*bp++ = *numstr++) != 0) { ;
            } /* Endwhile */
            --bp; /* bump bp back to point to the null */
         } else {
            *bp = '\0';
         } /* Endif */
      } /* Endif */
   } /* Endif */

   return (int)(bp - buf); /* same as strlen(buf) */

} /* Endbody */

/*!
 * \brief Converts a double to G format output
 *  
 * \param[out] buf         Where to put the number.
 * \param[in]  arg         The number to convert.
 * \param[in]  fillchar    The fill character to use.
 * \param[in]  printsign   Should the sign be printed.
 * \param[in]  printprefix Should a prefix be printed.
 * \param[in]  altformat   Makes sure that output is printed out as floating.
 * \param[in]  precision   What preicision to use.
 * \param[in]  g_or_G      Use lower or uppercase G. 
 * 
 * \return Number in G format.
 */ 
int_32 _io_dtog
   ( 
      char _PTR_ buf,
      double     arg,
      char _PTR_ fillchar,
      char       printsign,
      char       printprefix,
      char       altformat,
      int_32     precision,
      char       g_or_G
   )
{
   char          sign;
   int_32        decpt, i;
   char _PTR_    numstr;
   char _PTR_    bp;
   char          cvtbuf[NDIG];

   /* First get e or E format */
   g_or_G -= 2;
   numstr = _io_cvt(arg, precision + 1, &decpt, &sign, 1, cvtbuf, g_or_G);
   bp = buf;
   
   if ((*numstr == 'i') || (*numstr == 'n'))
   {
        _io_inf_or_nan(bp, numstr, printsign , printprefix, sign, g_or_G);
        *fillchar = ' ';
   } 
   else 
   {
      /* Check whether f format is more suitable */
      if ((decpt - 1 >= -4) && (decpt - 1 < precision))
      {
         if (precision > NDIG) 
         {
            precision = NDIG;
         }
         numstr = _io_cvt(arg, precision, &decpt, &sign, 0, cvtbuf, (g_or_G - 2));
         g_or_G += 1;
      }
      
      /* Remove trailing zeros */
      if (! altformat)
      {
         for (i = 0; numstr[i] != 0; i++) 
         { ; 
         }
         for (--i; i >= 0; i--)
         {
            if ((numstr[i] != '0') || (i == decpt)) break;
         }
         if ((i >= 0) && (numstr[i] == '0')) 
         {
            i--;
         }
         if (i == -1) 
         {
            if ((g_or_G == 'e') || (g_or_G == 'E'))
            {
               numstr[0] = '0';
               i = 0;
            }
         }
         else if ((numstr[i] < '0') || (numstr[i] > '9'))
         {
            numstr[++i] = '0';
         }
         numstr[i + 1] = '\0';
      }
      
      if ((g_or_G == 'e') || (g_or_G == 'E'))
      {
         /* Output in e, E format */
         if (sign) 
         {
            *bp++ =  '-';
         } 
         else if (printsign) 
         {
            *bp++ =  '+';
         } 
         else if (printprefix) 
         {
            *bp++ =  ' ';
         }
         *bp++ = *numstr++;
         if ((*numstr != '\0') || altformat) 
         {
            *bp++ = '.';
         }
         while (*numstr != '\0') 
         {
            *bp++ = *numstr++;
         }
         *bp++ = g_or_G;
         if (decpt -1 >= 0) 
         {
            *bp++ = '+';
         } 
         else 
         {
            *bp++ = '-';
         }
         /* update bp after putting in exp */
         bp += _io_dtoa(decpt - 1, bp);
         *bp = '\0';
      }
      else
      {
         /* Output in f format */
         if (sign) 
         {
            *bp++ =  '-';
         } 
         else if (printsign) 
         {
            *bp++ =  '+';
         } 
         else if (printprefix) 
         {
            *bp++ =  ' ';
         }
         if (decpt <= 0) 
         {
            *bp++ = '0';
            if(*numstr != 0)
            {
                *bp++ = '.';
            }
            while (decpt++ < 0) 
            {
               *bp++ = '0';
            }
            while ((*bp++ = *numstr++) != 0) 
            {
            }
            --bp; /* bump bp back to point to the null */
         } 
         else 
         {
            while ((*numstr != '\0') && (decpt-- != 0)) 
            {
               *bp++ = *numstr++;
            }
            if ((*numstr != '\0') || altformat) 
            {
               *bp++ = '.';
            }
            if (*numstr != '\0') 
            {
               while ((*bp++ = *numstr++) != 0) 
               { ;
               }
               --bp; /* bump bp back to point to the null */
            } 
            else 
            {
               *bp = '\0';
            }
         }
      }
   }

   return (int)(bp - buf);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Sqrt.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Sqrt.h
*
* @author   r29302
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_Sqrt function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_SQRT_H
#define _GFLIB_SQRT_H

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif
/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*! Function alias for the #GFLIB_SqrtANSIC function.*/

#define GFLIB_Sqrt(f32In) GFLIB_SqrtANSIC(f32In)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/

/******************************************************************************
* Exported Variables
******************************************************************************/

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*!
* @ingroup GFLIB_GROUP
*/
extern Frac32 GFLIB_SqrtANSIC(Frac32 f32In);

/******************************************************************************
* Inline functions
******************************************************************************/

#endif /* _GFLIB_SQRT_H */


<|start_filename|>Firmware/Inverter_firmware/shell/source/mqx/sh_kill.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_kill.c$
* $Version : 3.0.5.0$
* $Date    : Jan-7-2009$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include <fio.h>
#include "shell.h"





/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_Kill
*  Returned Value:  none
*  Comments  :  SHELL utility to TFTP to or from a host
*  Usage:  tftp host get source [destination] [mode] 
*
*END*-----------------------------------------------------------------*/

int_32  Shell_kill(int_32 argc, char_ptr argv[] )
{
   _task_id task_id;
   uint_32  result;
   boolean  print_usage, shorthelp = FALSE;
   int_32   return_code = SHELL_EXIT_SUCCESS;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc == 2)  {
         task_id = _task_get_id_from_name( argv[1] );
         if (task_id == MQX_NULL_TASK_ID)  {
            printf("No task named %s running.\n",argv[1]);
            return_code = SHELL_EXIT_ERROR;
         } else  {
            result = _task_destroy(task_id);
            if (result == MQX_OK)  {  
               printf("Task %s killed.\n",argv[1]);
            } else  {
               printf("Unable to kill task %s.\n",argv[1]);
               return_code = SHELL_EXIT_ERROR;
            }
         }
      } else  {
         printf("Error, %s invoked with incorrect number of arguments\n", argv[0]);
         print_usage = TRUE;
      }
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <taskid>\n", argv[0]);
      } else  {
         printf("Usage: %s <taskname>\n", argv[0]);
         printf("   <taskname> = MQX Task name\n");
      }
   }
   return return_code;
} /* Endbody */
   


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5225_fec.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5225_fec.c$
* $Version : 3.6.2.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   Processor family specific file needed for enet module.
*   Revision History:
*   Date             Version  Changes
*   ---------        -------  -------
*   Sep 26/08        2.50     Initial version
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <enet.h>
#include <enetprv.h>
#include <mcf5xxx_fec_prv.h>


const uint_32 MCF5XXX_FEC_vectors[MCF5XXX_FEC_DEVICE_COUNT][MCF5XXX_FEC_NUM_INTS] = {
    {
        MCF5225_INT_FEC_X_INTF,
        MCF5225_INT_FEC_X_INTB,
        MCF5225_INT_FEC_X_UN,
        MCF5225_INT_FEC_RL,
        MCF5225_INT_FEC_R_INTF,
        MCF5225_INT_FEC_R_INTB,
        MCF5225_INT_FEC_MII,
        MCF5225_INT_FEC_LC,
        MCF5225_INT_FEC_HBERR,
        MCF5225_INT_FEC_GRA,
        MCF5225_INT_FEC_EBERR,
        MCF5225_INT_FEC_BABT,
        MCF5225_INT_FEC_BABR
    }
};

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : MCF5XXX_FEC_get_base_address  
* Returned Value   : Pointer to desired enem device or NULL if not present
* Comments         :
*    This function returns pointer to base address of address space of the 
*    desired enet device. Returns NULL otherwise.
*
*END*----------------------------------------------------------------------*/

pointer MCF5XXX_FEC_get_base_address( uint_32   device )
{ 
    if (device >= MCF5XXX_FEC_DEVICE_COUNT) return NULL;
    return (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->FEC);
}


 
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : MCF5XXX_FEC_io_init
* Returned Value   : none
* Comments         :
*    This function performs BSP-specific initialization related to ENET
*
*END*----------------------------------------------------------------------*/

void MCF5XXX_FEC_io_init( uint_32   device )
{

   if (device >= MCF5XXX_FEC_DEVICE_COUNT) 
      return;

   _bsp_enet_io_init(device);
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ipcp.h<|end_filename|>
#ifndef __ipcp_h__
#define __ipcp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcp.h$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the defines and data structure
*   definitions required by IPCP.
*
*END************************************************************************/

/*
** ipcp.h - IP Control Protocol definitions.
**
** Copyright (c) 1989 Carnegie Mellon University.
** All rights reserved.
**
** Redistribution and use in source and binary forms are permitted
** provided that the above copyright notice and this paragraph are
** duplicated in all such forms and that any documentation,
** advertising materials, and other materials related to such
** distribution and use acknowledge that the software was developed
** by Carnegie Mellon University.  The name of the
** University may not be used to endorse or promote products derived
** from this software without specific prior written permission.
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
** WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

#include <ppp.h>
#include "pppfsm.h"

#include "ip_prv.h"


/***************************************
**
** Constants
**
*/

/*
** PPP Protocol Numbers
*/

#define PPP_PROT_IP     0x0021
#define PPP_PROT_IPCP   0x8021


/*
** IPCP Configuration Options
*/

#define IPCP_CI_ADDR    3     /* IP Address */
#define IPCP_CI_DNS     129   /* Primary DNS server */


/***************************************
**
** Macros
**
*/

/*
** PPP error code -> RTCS error code conversion
*/

#define PPP_TO_RTCS_ERROR(x) ((x)?((x)|0x2000):(x))


/***************************************
**
** Type definitions
**
*/

/*
** The IPCP Options state used during negotiation
*/

typedef struct ipcp_neg {
   unsigned    NEG_ADDRS : 1;    /* Not used */
   unsigned    NEG_CP    : 1;    /* Not used */
   unsigned    NEG_ADDR  : 1;
   unsigned    NEG_DNS   : 1;
   unsigned              : 0;
   _ip_address ADDR;
   _ip_address DNS;
} IPCP_NEG, _PTR_ IPCP_NEG_PTR;

typedef struct ipcp_init {

   unsigned    NEG_LOCAL_DNS      : 1;
   unsigned    NEG_REMOTE_DNS     : 1;

   unsigned    ACCEPT_LOCAL_ADDR  : 1;
   unsigned    ACCEPT_REMOTE_ADDR : 1;
   unsigned    ACCEPT_LOCAL_DNS   : 1;
   unsigned    ACCEPT_REMOTE_DNS  : 1;

   unsigned    DEFAULT_NETMASK    : 1;
   unsigned    DEFAULT_ROUTE      : 1;

   unsigned                       : 0;

   _ip_address LOCAL_ADDR;
   _ip_address REMOTE_ADDR;
   _ip_address NETMASK;
   _ip_address LOCAL_DNS;
   _ip_address REMOTE_DNS;

} IPCP_INIT, _PTR_ IPCP_INIT_PTR;

typedef struct ipcp_opt {
   _ip_address ADDR;    /* Negotiated IP address */
   _ip_address DNS;     /* Negotiated DNS server address */
} IPCP_OPT, _PTR_ IPCP_OPT_PTR;

/*
** The IPCP Configuration structure
*/

typedef struct ipcp_cfg_struct {
   _ppp_handle       HANDLE;        /* PPP channel */
   void (_CODE_PTR_  CALLUP)(pointer);    /* previous PPP_LINK_UP callback */
   pointer           PARAMUP;             /* previous PPP_LINK_UP parameter */
   void (_CODE_PTR_  CALLDOWN)(pointer);  /* previous PPP_LINK_DOWN callback */
   pointer           PARAMDOWN;           /* previous PPP_LINK_DOWN parameter */
   void (_CODE_PTR_  IP_UP)   (pointer);  /* application UP callback */
   void (_CODE_PTR_  IP_DOWN) (pointer);  /* application DOWN callback */
   pointer           IP_PARAM;            /* parameter to IP_UP and IP_DOWN */
   IPCP_INIT         INIT;          /* Initial values provided by application */
   IPCP_NEG          NEG;           /* Options under negotiation */
   IPCP_OPT          LOPT;          /* Negotiated local options */
   IPCP_OPT          POPT;          /* Negotiated peer options */
   IPIF_PARM         BIND_PARMS;    /* Parameters to IPIF_[un]bind */
   IPIF_PARM         GATE_PARMS;    /* Parameters to IPIF_gate_{add,remove} */
   PPPFSM_CFG        FSM;           /* IPCP automaton state */
} IPCP_CFG_STRUCT, _PTR_ IPCP_CFG_STRUCT_PTR;


/***************************************
**
** Function-specific type definitions
**
*/

/* IPCP_bind() */
typedef struct tcpip_parm_ipcp {
   TCPIP_PARM              COMMON;
   _rtcs_if_handle         handle;  /* [IN] the RTCS interface state structure */
   IPCP_DATA_STRUCT_PTR    data;    /* [IN] IPCP parameters */
} TCPIP_PARM_IPCP;


/***************************************
**
** Global variables
**
*/

extern PPPFSM_CALL IPCP_FSM_CALL;


/***************************************
**
** Prototypes
**
*/

uint_32 IPCP_init    (IP_IF_PTR);
uint_32 IPCP_destroy (IP_IF_PTR);
uint_32 IPCP_send    (IP_IF_PTR, RTCSPCB_PTR, _ip_address, _ip_address, pointer);
void IPCP_recv(PCB_PTR, pointer);

void IPCP_bind(TCPIP_PARM_IPCP _PTR_);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/getnameinfo.c<|end_filename|>
/**HEADER*******************************************************************************
* 
* Copyright (c) 2011 , Freescale Semiconductor;
* All Rights Reserved                      
*
**************************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************************/
/*
 * Portions Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
 * Portions Copyright (C) 1999-2001, 2003  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
 
#include <string.h>
#include <ctype.h>
#include <rtcs.h>
#include <addrinfo.h>

#define SUCCESS 0

/*% afd structure definition */
static struct afd {
	int a_af;
	unsigned int a_addrlen;
	unsigned int a_socklen;
} afdl [] = {
	/*!
	 * First entry is linked last...
	 */
	{ AF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in) },
	{ AF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6) },
	{0, 0, 0},
};

#define ENI_NOSERVNAME	1
#define ENI_NOHOSTNAME	2
#define ENI_MEMORY	3
#define ENI_SYSTEM	4
#define ENI_FAMILY	5
#define ENI_SALEN	6
#define ENI_NOSOCKET 	7

/*!
 * The test against 0 is there to keep the Solaris compiler
 * from complaining about "end-of-loop code not reached".
 */
#define ERR(code) \
	do { result = (code);			\
		if (result != 0) goto cleanup;	\
	} while (0)


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : getnameinfo()
* Returned Value  : RTCS_OK or error code
* Comments        :
*     Lightweight resolver socket address structure to hostname and service name.
*
*END*-----------------------------------------------------------------*/


int_32 getnameinfo
(
    const struct sockaddr  *sa, 
    unsigned int            salen, 
    char                   *host,
	unsigned int            hostlen, 
	char                   *serv, 
	unsigned int            servlen, 
	int                     flags
)
{

	struct afd *afd;
	struct servent *sp = NULL;
	unsigned short port;
#ifdef LWRES_PLATFORM_HAVESALEN
	unsigned int len;
#endif
	int family, i;
	const void *addr;
	char *p;
#if 0
	unsigned long v4a;
	unsigned char pfx;
#endif
#if 0
	char numserv[sizeof("65000")];
#endif
	char numaddr[sizeof("abcd:abcd:abcd:abcd:abcd:abcd:255.255.255.255")
		    + 1 + sizeof("4294967295")];
	const char *proto;
	uint_32 lwf = 0;
	lwres_context_t *lwrctx = NULL;
	lwres_gnbaresponse_t *by = NULL;
	int result = SUCCESS;
	int n;

	if (sa == NULL)
		ERR(ENI_NOSOCKET);

#ifdef LWRES_PLATFORM_HAVESALEN
	len = sa->sa_len;
	if (len != salen)
		ERR(ENI_SALEN);
#endif

	/*family = sa->sa_family;*/
	family = sa->sa_family;
	
	for (i = 0; afdl[i].a_af; i++)
		if (afdl[i].a_af == family) {
			afd = &afdl[i];
			goto found;
		}
	ERR(ENI_FAMILY);

 found:
	if (salen != afd->a_socklen)
		ERR(ENI_SALEN);

	switch (family) {
	case AF_INET:
		port = ((const struct sockaddr_in *)sa)->sin_port;
		addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr;
		break;

	case AF_INET6:
		port = ((const struct sockaddr_in6 *)sa)->sin6_port;
		addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
		break;

	default:
		port = 0;
		addr = NULL;
	//	INSIST(0);//#define INSIST(x)		assert(x)
	}
	proto = (flags & NI_DGRAM) ? "udp" : "tcp";

	if (serv == NULL || servlen == 0U) {
		/*
		 * Caller does not want service.
		 */
	#if 0 /*We do not support getservbyport function */ 
	    }
		else if ((flags & NI_NUMERICSERV) != 0 ||(sp = getservbyport(port, proto)) == NULL) 
	{
		snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
		if ((strlen(numserv) + 1) > servlen)
		{	
			ERR(ENI_MEMORY);
		}
		strcpy(serv, numserv);
	} 
	#endif
	}else {
		if ((strlen(sp->s_name) + 1) > servlen)
		{
			ERR(ENI_MEMORY);
		}
		strcpy(serv, sp->s_name);
	}

	if (host == NULL || hostlen == 0U) {
		/*
		 * What should we do?
		 */
	} else if (flags & NI_NUMERICHOST) {
		if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL)
		{
			ERR(ENI_SYSTEM);
		}
		if (afd->a_af == AF_INET6 && ((const struct sockaddr_in6 *)sa)->sin6_scope_id) 
		{
			char *p = numaddr + strlen(numaddr);
			const char *stringscope = NULL;
#if 0
			if ((flags & NI_NUMERICSCOPE) == 0) {
				/*
				 * Vendors may want to add support for
				 * non-numeric scope identifier.
				 */
				stringscope = foo;
			}
#endif
			if (stringscope == NULL) 
			{
			  //snprintf(p, sizeof(numaddr) - (p - numaddr),"%%%u",((const struct sockaddr_in6 *)sa)->sin6_scope_id);
				sprintf(p,"%%%u",((const struct sockaddr_in6 *)sa)->sin6_scope_id);
			} else {
			  //snprintf(p, sizeof(numaddr) - (p - numaddr),"%%%s", stringscope);
				sprintf(p,"%%%s", stringscope);
			}
		}
//#endif
		if (strlen(numaddr) + 1 > hostlen)
			ERR(ENI_MEMORY);
		strcpy(host, numaddr);
	} else {
		switch (family) {
		case AF_INET:
			lwf = LWRES_ADDRTYPE_V4;
			break;
		case AF_INET6:
			lwf = LWRES_ADDRTYPE_V6;
			break;
		default:
			return (ENI_FAMILY);
		}

		n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
		if (n == 0)
		{	
			//(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
		}
		if (n == 0)
		{	
			//n = lwres_getnamebyaddr(lwrctx, lwf, (lwres_uint16_t)afd->a_addrlen,addr, &by);
		}
		if (n == 0) 
		{
			if (flags & NI_NOFQDN) 
			{
				p = strchr(by->realname, '.');
				if (p)
				{
					*p = '\0';
				}
			}
			if ((strlen(by->realname) + 1) > hostlen)
			{
				ERR(ENI_MEMORY);
			}
			strcpy(host, by->realname);
		} else {
			if (flags & NI_NAMEREQD)
			{
				ERR(ENI_NOHOSTNAME);
			}
			if (inet_ntop(afd->a_af, addr, numaddr,sizeof(numaddr))== NULL)
			{
				ERR(ENI_NOHOSTNAME);
			}
			if ((strlen(numaddr) + 1) > hostlen)
			{
				ERR(ENI_MEMORY);
			}
			strcpy(host, numaddr);
		}
	}
	result = SUCCESS;
 cleanup:
	if (by != NULL)
		lwres_gnbaresponse_free(lwrctx, &by);
	if (lwrctx != NULL) {
		lwres_conf_clear(lwrctx);
		lwres_context_destroy(&lwrctx);
	}
	return (result);
}




/*%
 * Creates a #lwres_context_t structure for use in
 *  lightweight resolver operations.
 */
uint_32 lwres_context_create
(
	lwres_context_t 	  **contextp, 
	void 				   *arg,
	lwres_malloc_t 			malloc_function,
	lwres_free_t 			free_function,
	unsigned int 			flags
)
{
	lwres_context_t *ctx;

	//REQUIRE(contextp != NULL && *contextp == NULL);

	/*
	 * If we were not given anything special to use, use our own
	 * functions.  These are just wrappers around malloc() and free().
	 */
	if (malloc_function == NULL || free_function == NULL) {
	//	REQUIRE(malloc_function == NULL);
	//	REQUIRE(free_function == NULL);
		malloc_function = lwres_malloc;
		free_function = lwres_free;
	}

	ctx = malloc_function(arg, sizeof(lwres_context_t));
	if (ctx == NULL)
		return (LWRES_R_NOMEMORY);

	/*
	 * Set up the context.
	 */
	ctx->malloc = malloc_function;
	ctx->free = free_function;
	ctx->arg = arg;
	ctx->sock = -1;

	ctx->r_timeout = LWRES_DEFAULT_TIMEOUT;
//b23362
	//ctx->serial = time(NULL); /* XXXMLG or BEW */

	ctx->use_ipv4 = 1;
	ctx->use_ipv6 = 1;
	if ((flags & (LWRES_CONTEXT_USEIPV4 | LWRES_CONTEXT_USEIPV6)) ==
	    LWRES_CONTEXT_USEIPV6) {
		ctx->use_ipv4 = 0;
	}
	if ((flags & (LWRES_CONTEXT_USEIPV4 | LWRES_CONTEXT_USEIPV6)) ==
	    LWRES_CONTEXT_USEIPV4) {
		ctx->use_ipv6 = 0;
	}

	/*
	 * Init resolv.conf bits.
	 */
	lwres_conf_init(ctx);

	*contextp = ctx;
	return (LWRES_R_SUCCESS);
}

/*% Release the memory in resolver context ctx that was allocated to the lwres_gnbaresponse_t. */
void lwres_gnbaresponse_free
(
	lwres_context_t *ctx, 
	lwres_gnbaresponse_t **structp
)
{
	lwres_gnbaresponse_t *gnba;

	//REQUIRE(ctx != NULL);
	//REQUIRE(structp != NULL && *structp != NULL);

	gnba = *structp;
	*structp = NULL;

	if (gnba->naliases > 0) {
		CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);
		CTXFREE(gnba->aliaslen,
			sizeof(uint_16) * gnba->naliases);
	}
	if (gnba->base != NULL)
		CTXFREE(gnba->base, gnba->baselen);
	CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
}


/*% Frees up all the internal memory used by the config data structure, returning it to the lwres_context_t. */
void lwres_conf_clear
(
	lwres_context_t *ctx
) 
{
	int i;
	lwres_conf_t *confdata;

	//REQUIRE(ctx != NULL);
	confdata = &ctx->confdata;

	for (i = 0; i < confdata->nsnext; i++)
		lwres_resetaddr(&confdata->nameservers[i]);

	if (confdata->domainname != NULL) {
		CTXFREE(confdata->domainname,
			strlen(confdata->domainname) + 1);
		confdata->domainname = NULL;
	}

	for (i = 0; i < confdata->searchnxt; i++) {
		if (confdata->search[i] != NULL) {
			CTXFREE(confdata->search[i],
				strlen(confdata->search[i]) + 1);
			confdata->search[i] = NULL;
		}
	}

	for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
		lwres_resetaddr(&confdata->sortlist[i].addr);
		lwres_resetaddr(&confdata->sortlist[i].mask);
	}

	confdata->nsnext = 0;
	confdata->lwnext = 0;
	confdata->domainname = NULL;
	confdata->searchnxt = 0;
	confdata->sortlistnxt = 0;
	confdata->resdebug = 0;
	confdata->ndots = 1;
	confdata->no_tld_query = 0;
}


/*%
Destroys a #lwres_context_t, closing its socket.
contextp is a pointer to a pointer to the context that is
to be destroyed. The pointer will be set to NULL
when the context has been destroyed.
 */
void lwres_context_destroy
(
	lwres_context_t **contextp
) 
{
	lwres_context_t *ctx;

//	REQUIRE(contextp != NULL && *contextp != NULL);

	ctx = *contextp;
	*contextp = NULL;

//b23362
//	if (ctx->sock != -1) {
//
//		(void)close(ctx->sock);
//		ctx->sock = -1;
//	}

	CTXFREE(ctx, sizeof(lwres_context_t));
}


void *lwres_malloc
(
	void 	*arg, 
	unsigned int 	len
) 
{
	void *mem;
	//UNUSED(arg);

	mem =  RTCS_mem_alloc_system((_mem_size) len);
	//mem = malloc(len);
	if (mem == NULL)
		return (NULL);

	memset(mem, 0xe5, len);

	return (mem);
}

void lwres_free
(
	void *arg, 
	void *mem, 
	unsigned int len
) 
{
//	UNUSED(arg);

	memset(mem, 0xa9, len);
	_mem_free(mem);
}

/*% intializes data structure for subsequent config parsing. */
void lwres_conf_init
(
	lwres_context_t *ctx
) 
{
	int i;
	lwres_conf_t *confdata;

//	REQUIRE(ctx != NULL);
	confdata = &ctx->confdata;

	confdata->nsnext = 0;
	confdata->lwnext = 0;
	confdata->domainname = NULL;
	confdata->searchnxt = 0;
	confdata->sortlistnxt = 0;
	confdata->resdebug = 0;
	confdata->ndots = 1;
	confdata->no_tld_query = 0;

	for (i = 0; i < LWRES_CONFMAXNAMESERVERS; i++)
		lwres_resetaddr(&confdata->nameservers[i]);

	for (i = 0; i < LWRES_CONFMAXSEARCH; i++)
		confdata->search[i] = NULL;

	for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
		lwres_resetaddr(&confdata->sortlist[i].addr);
		lwres_resetaddr(&confdata->sortlist[i].mask);
	}
}


void lwres_resetaddr
(
	lwres_addr_t *addr
) 
{
//	REQUIRE(addr != NULL);

	memset(addr->address, 0, LWRES_ADDR_MAXLEN);
	addr->family = 0;
	addr->length = 0;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/FTFA_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type FTFA
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(FTFA_PDD_H_)
#define FTFA_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error FTFA PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MKL02Z4) /* FTFA */ && \
      !defined(MCU_MKL04Z4) /* FTFA */ && \
      !defined(MCU_MKL05Z4) /* FTFA */ && \
      !defined(MCU_MKL14Z4) /* FTFA */ && \
      !defined(MCU_MKL15Z4) /* FTFA */ && \
      !defined(MCU_MKL16Z4) /* FTFA */ && \
      !defined(MCU_MKL24Z4) /* FTFA */ && \
      !defined(MCU_MKL25Z4) /* FTFA */ && \
      !defined(MCU_MKL26Z4) /* FTFA */ && \
      !defined(MCU_MKL34Z4) /* FTFA */ && \
      !defined(MCU_MKL36Z4) /* FTFA */ && \
      !defined(MCU_MKL46Z4) /* FTFA */
  // Unsupported MCU is active
  #error FTFA PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* ClearFlags constants */
#define FTFA_PDD_COMMAND_COMPLETE          FTFA_FSTAT_CCIF_MASK /**< Command complete flag mask */
#define FTFA_PDD_READ_COLLISION_ERROR      FTFA_FSTAT_RDCOLERR_MASK /**< Read collision error flag mask */
#define FTFA_PDD_ACCESS_ERROR              FTFA_FSTAT_ACCERR_MASK /**< Access error flag mask */
#define FTFA_PDD_PROTECTION_VIOLATION      FTFA_FSTAT_FPVIOL_MASK /**< Protection violation flag mask */
#define FTFA_PDD_COMMAND_COMPLETION_STATUS FTFA_FSTAT_MGSTAT0_MASK /**< Command completion ststus flag mask */

/* EnableInterrupts, DisableInterrupts constants */
#define FTFA_PDD_COMMAND_COMPLETE_INT     FTFA_FCNFG_CCIE_MASK /**< Command complete interrupt mask */
#define FTFA_PDD_READ_COLLISION_ERROR_INT FTFA_FCNFG_RDCOLLIE_MASK /**< Read collision error interrupt mask */

/* SetFCCOBCommand constants */
#define FTFA_PDD_READ_1S_SECTION            0x1U /**< Read 1s Section command value */
#define FTFA_PDD_PROGRAM_CHECK              0x2U /**< Program Check command value */
#define FTFA_PDD_READ_RESOURCE              0x3U /**< Read Resource command value */
#define FTFA_PDD_PROGRAM_LONGWORD           0x6U /**< Program Longword command value */
#define FTFA_PDD_ERASE_FLASH_SECTOR         0x9U /**< Erase Flash Sector command value */
#define FTFA_PDD_READ_1S_ALL_BLOCKS         0x40U /**< Read 1s All Blocks command value */
#define FTFA_PDD_PDD_READ_ONCE              0x41U /**< Read Once command value */
#define FTFA_PDD_PROGRAM_ONCE               0x43U /**< Program Once command value */
#define FTFA_PDD_ERASE_ALL_BLOCKS           0x44U /**< Erase All Blocks command value */
#define FTFA_PDD_VERIFY_BACKDOOR_ACCESS_KEY 0x45U /**< Verify Backdoor Access Key command value */

/* BackDoorKey constants */
#define FTFA_PDD_BACKDOOR_KEY_ENABLED  0U        /**< Backdoor key enable constant */
#define FTFA_PDD_BACKDOOR_KEY_DISABLED 0x1U      /**< Backdoor key disable constant */

/* Security state constants */
#define FTFA_PDD_UNSECURED 0U                    /**< Unsecure constant */
#define FTFA_PDD_SECURED   0x1U                  /**< Secure constant */

/* FlashProtection constants */
#define FTFA_PDD_UNPROTECTED 0U                  /**< Unprotect constant */
#define FTFA_PDD_PROTECTED   0x1U                /**< Protect constant */


/* ----------------------------------------------------------------------------
   -- ReadStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "ClearFlags constants" for processing return
 *         value.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadStatusReg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadStatusReg(PeripheralBase) ( \
    FTFA_FSTAT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the Flash status register. Use constants from
 *        group "ClearFlags constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteStatusReg(deviceID, FTFA_PDD_COMMAND_COMPLETE);
 *      @endcode
 */
#define FTFA_PDD_WriteStatusReg(PeripheralBase, Value) ( \
    FTFA_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ClearCommandCompleteFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Command complete flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      FTFA_PDD_ClearCommandCompleteFlag(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ClearCommandCompleteFlag(PeripheralBase) ( \
    FTFA_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFA_FSTAT_REG(PeripheralBase) | FTFA_FSTAT_CCIF_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_ACCERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_RDCOLERR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearReadCollisionErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Read collision error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      FTFA_PDD_ClearReadCollisionErrorFlag(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ClearReadCollisionErrorFlag(PeripheralBase) ( \
    FTFA_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFA_FSTAT_REG(PeripheralBase) | FTFA_FSTAT_RDCOLERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_ACCERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearAccessErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Access error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      FTFA_PDD_ClearAccessErrorFlag(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ClearAccessErrorFlag(PeripheralBase) ( \
    FTFA_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFA_FSTAT_REG(PeripheralBase) | FTFA_FSTAT_ACCERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_RDCOLERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearProtectionViolationErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Protection violation error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      FTFA_PDD_ClearProtectionViolationErrorFlag(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ClearProtectionViolationErrorFlag(PeripheralBase) ( \
    FTFA_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFA_FSTAT_REG(PeripheralBase) | FTFA_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_ACCERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_RDCOLERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFA_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- LaunchCommand
   ---------------------------------------------------------------------------- */

/**
 * @brief Starts new command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      FTFA_PDD_LaunchCommand(deviceID);
 *      @endcode
 */
#define FTFA_PDD_LaunchCommand(PeripheralBase) ( \
    FTFA_FSTAT_REG(PeripheralBase) = \
     0x80U \
  )

/* ----------------------------------------------------------------------------
   -- ClearFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @param Flags Interrupt mask. This parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      FTFA_PDD_ClearFlags(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_ClearFlags(PeripheralBase, Flags) ( \
    FTFA_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(Flags) \
  )

/* ----------------------------------------------------------------------------
   -- GetFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FSTAT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_GetFlags(deviceID);
 *      @endcode
 */
#define FTFA_PDD_GetFlags(PeripheralBase) ( \
    FTFA_FSTAT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadConfigReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash configuration register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCNFG.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadConfigReg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadConfigReg(PeripheralBase) ( \
    FTFA_FCNFG_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteConfigReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash configuration register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the Flash configuration register. This
 *        parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCNFG.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteConfigReg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteConfigReg(PeripheralBase, Value) ( \
    FTFA_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables Command commplete end Read collision error interrupts.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "EnableInterrupts,
 *        DisableInterrupts constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCNFG.
 * @par Example:
 *      @code
 *      FTFA_PDD_EnableInterrupts(deviceID, FTFA_PDD_COMMAND_COMPLETE_INT);
 *      @endcode
 */
#define FTFA_PDD_EnableInterrupts(PeripheralBase, Mask) ( \
    FTFA_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(( \
       FTFA_FCNFG_REG(PeripheralBase)) & ( \
       (uint8_t)(~(uint8_t)(FTFA_FCNFG_CCIE_MASK | FTFA_FCNFG_RDCOLLIE_MASK))))) | ( \
      (uint8_t)(Mask))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables Command commplete end Read collision error interrupts.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "EnableInterrupts,
 *        DisableInterrupts constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCNFG.
 * @par Example:
 *      @code
 *      FTFA_PDD_DisableInterrupts(deviceID, FTFA_PDD_COMMAND_COMPLETE_INT);
 *      @endcode
 */
#define FTFA_PDD_DisableInterrupts(PeripheralBase, Mask) ( \
    FTFA_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(( \
       FTFA_FCNFG_REG(PeripheralBase)) & ( \
       (uint8_t)(~(uint8_t)(FTFA_FCNFG_CCIE_MASK | FTFA_FCNFG_RDCOLLIE_MASK))))) | ( \
      (uint8_t)(( \
       (uint8_t)(~(uint8_t)(Mask))) & ( \
       (uint8_t)(FTFA_FCNFG_CCIE_MASK | FTFA_FCNFG_RDCOLLIE_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- SuspendErasing
   ---------------------------------------------------------------------------- */

/**
 * @brief Suspends the current Erase Flash Sector command execution.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCNFG.
 * @par Example:
 *      @code
 *      FTFA_PDD_SuspendErasing(deviceID);
 *      @endcode
 */
#define FTFA_PDD_SuspendErasing(PeripheralBase) ( \
    FTFA_FCNFG_REG(PeripheralBase) |= \
     FTFA_FCNFG_ERSSUSP_MASK \
  )

/* ----------------------------------------------------------------------------
   -- ReadSecurityReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Security register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FSEC.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadSecurityReg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadSecurityReg(PeripheralBase) ( \
    FTFA_FSEC_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetBackdoorEnable
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the constant FTFL_PDD_BACKDOOR_KEY_ENABLED if backdoor key
 * access is enabled else returns the FTFL_PDD_BACKDOOR_KEY_DISABLED constant.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of "BackDoorKey constants" type. The value is cast to
 *         "uint16_t".
 * @remarks The macro accesses the following registers: FTFA_FSEC.
 * @par Example:
 *      @code
 *      uint16_t result = FTFA_PDD_GetBackdoorEnable(deviceID);
 *      @endcode
 */
#define FTFA_PDD_GetBackdoorEnable(PeripheralBase) ( \
    (( \
      (uint8_t)(( \
       (uint8_t)(FTFA_FSEC_REG(PeripheralBase) & FTFA_FSEC_KEYEN_MASK)) >> ( \
       FTFA_FSEC_KEYEN_SHIFT))) == ( \
      0x2U)) ? ( \
      FTFA_PDD_BACKDOOR_KEY_ENABLED) : ( \
      FTFA_PDD_BACKDOOR_KEY_DISABLED) \
  )

/* ----------------------------------------------------------------------------
   -- GetSecurityState
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the constant FTFL_PDD_SECURED if MCU is in secure state else
 * returns the FTFL_PDD_UNSECURED constant.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of "Security state constants" type. The value is cast
 *         to "uint16_t".
 * @remarks The macro accesses the following registers: FTFA_FSEC.
 * @par Example:
 *      @code
 *      uint16_t result = FTFA_PDD_GetSecurityState(deviceID);
 *      @endcode
 */
#define FTFA_PDD_GetSecurityState(PeripheralBase) ( \
    ((uint8_t)(FTFA_FSEC_REG(PeripheralBase) & FTFA_FSEC_SEC_MASK) == 0x2U) ? ( \
      FTFA_PDD_UNSECURED) : ( \
      FTFA_PDD_SECURED) \
  )

/* ----------------------------------------------------------------------------
   -- ReadOptionReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Optional register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FOPT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadOptionReg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadOptionReg(PeripheralBase) ( \
    FTFA_FOPT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB0Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 0.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB0.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB0Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB0Reg(PeripheralBase) ( \
    FTFA_FCCOB0_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 1.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB1.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB1Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB1Reg(PeripheralBase) ( \
    FTFA_FCCOB1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 2.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB2.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB2Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB2Reg(PeripheralBase) ( \
    FTFA_FCCOB2_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB3Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 3.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB3.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB3Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB3Reg(PeripheralBase) ( \
    FTFA_FCCOB3_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB4Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 4.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB4.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB4Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB4Reg(PeripheralBase) ( \
    FTFA_FCCOB4_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB5Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 5.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB5.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB5Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB5Reg(PeripheralBase) ( \
    FTFA_FCCOB5_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB6Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 6.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB6.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB6Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB6Reg(PeripheralBase) ( \
    FTFA_FCCOB6_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB7Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 7.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB7.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB7Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB7Reg(PeripheralBase) ( \
    FTFA_FCCOB7_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB8Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 8.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB8.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB8Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB8Reg(PeripheralBase) ( \
    FTFA_FCCOB8_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB9Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 9.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOB9.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOB9Reg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOB9Reg(PeripheralBase) ( \
    FTFA_FCCOB9_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOBAReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register A.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOBA.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOBAReg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOBAReg(PeripheralBase) ( \
    FTFA_FCCOBA_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOBBReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register B.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFA_FCCOBB.
 * @par Example:
 *      @code
 *      uint8_t result = FTFA_PDD_ReadFCCOBBReg(deviceID);
 *      @endcode
 */
#define FTFA_PDD_ReadFCCOBBReg(PeripheralBase) ( \
    FTFA_FCCOBB_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB0Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB0 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB0 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB0.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB0Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB0Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB0_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB1 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB1.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB1Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB1Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB1_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB2 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB2 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB2.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB2Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB2Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB2_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB3Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB3register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB3 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB3.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB3Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB3Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB3_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB4Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB4 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB4 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB4.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB4Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB4Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB5Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB5 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB5 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB5.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB5Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB5Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB6Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB6 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB6 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB6.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB6Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB6Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB7Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB7 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB7 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB7.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB7Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB7Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB8Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB8 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB8 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB8.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB8Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB8Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB9Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB9 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB9 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB9.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOB9Reg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOB9Reg(PeripheralBase, Value) ( \
    FTFA_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBAReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOBA register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOBA register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOBA.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBAReg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBAReg(PeripheralBase, Value) ( \
    FTFA_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBBReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOBB register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOBB register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOBB.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBBReg(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBBReg(PeripheralBase, Value) ( \
    FTFA_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- SetFCCOBCommand
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB Command register.
 * @param PeripheralBase Peripheral base address.
 * @param Command Value written to the FCCOB Command register. This parameter is
 *        a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB0.
 * @par Example:
 *      @code
 *      FTFA_PDD_SetFCCOBCommand(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_SetFCCOBCommand(PeripheralBase, Command) ( \
    FTFA_FCCOB0_REG(PeripheralBase) = \
     (uint8_t)(Command) \
  )

/* ----------------------------------------------------------------------------
   -- SetFCCOBAddress
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB Address register.
 * @param PeripheralBase Peripheral base address.
 * @param Address Value written to the FCCOB Address register. This parameter is
 *        a 24-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB3,
 *          FTFA_FCCOB2, FTFA_FCCOB1 (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFA_PDD_SetFCCOBAddress(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_SetFCCOBAddress(PeripheralBase, Address) ( \
    (FTFA_FCCOB3_REG(PeripheralBase) = \
     (uint8_t)(Address)), \
    ((FTFA_FCCOB2_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Address) >> 8U)), \
    (FTFA_FCCOB1_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Address) >> 16U))) \
  )

/* ----------------------------------------------------------------------------
   -- SetFCCOBDataSize
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB size register.
 * @param PeripheralBase Peripheral base address.
 * @param Address Value written to the FCCOB Size register. This parameter is a
 *        16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB5, FTFA_FCCOB4
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFA_PDD_SetFCCOBDataSize(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_SetFCCOBDataSize(PeripheralBase, Address) ( \
    (FTFA_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)(Address)), \
    (FTFA_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)((uint16_t)(Address) >> 8U)) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData0
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 0.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 0 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB4.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBData0(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBData0(PeripheralBase, Data) ( \
    FTFA_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData1
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 1.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 1 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB5.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBData1(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBData1(PeripheralBase, Data) ( \
    FTFA_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData2
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 2.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 2 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB6.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBData2(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBData2(PeripheralBase, Data) ( \
    FTFA_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData3
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 3.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 3 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB7.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBData3(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBData3(PeripheralBase, Data) ( \
    FTFA_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData4
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 4.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 4 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB8.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBData4(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBData4(PeripheralBase, Data) ( \
    FTFA_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData5
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 5.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 5 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB9.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBData5(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBData5(PeripheralBase, Data) ( \
    FTFA_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData6
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 6.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 6 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOBA.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBData6(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBData6(PeripheralBase, Data) ( \
    FTFA_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData7
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 7.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 7 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOBB.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBData7(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBData7(PeripheralBase, Data) ( \
    FTFA_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB7.
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBLongWordData(PeripheralBase, Data) ( \
    *(uint32_t*)(void*)&FTFA_FCCOB7_REG(PeripheralBase) = Data \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBFirstLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets first longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB4,
 *          FTFA_FCCOB5, FTFA_FCCOB6, FTFA_FCCOB7 (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBFirstLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBFirstLongWordData(PeripheralBase, Data) ( \
    (FTFA_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 24U)), \
    ((FTFA_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 16U)), \
    ((FTFA_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 8U)), \
    (FTFA_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Data)))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBSecondLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets second longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FCCOB8,
 *          FTFA_FCCOB9, FTFA_FCCOBA, FTFA_FCCOBB (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFA_PDD_WriteFCCOBSecondLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFA_PDD_WriteFCCOBSecondLongWordData(PeripheralBase, Data) ( \
    (FTFA_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 24U)), \
    ((FTFA_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 16U)), \
    ((FTFA_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 8U)), \
    (FTFA_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Data)))) \
  )

/* ----------------------------------------------------------------------------
   -- SetPFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets program Flash protection state.
 * @param PeripheralBase Peripheral base address.
 * @param Regions Protected regions. This parameter is a 32-bit value.
 * @param State Requested state. This parameter is of "FlashProtection
 *        constants" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFA_FPROT3.
 * @par Example:
 *      @code
 *      FTFA_PDD_SetPFlashProtectionState(deviceID, 1, FTFA_PDD_UNPROTECTED);
 *      @endcode
 */
#define FTFA_PDD_SetPFlashProtectionState(PeripheralBase, Regions, State) ( \
    ((State) == FTFA_PDD_UNPROTECTED) ? ( \
      *(uint32_t *)(void *)&(FTFA_FPROT3_REG(PeripheralBase)) |= \
      (uint32_t)(Regions)) : ( \
      *(uint32_t *)(void *)&(FTFA_FPROT3_REG(PeripheralBase)) &= \
      (uint32_t)(~(uint32_t)(Regions))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns program falsh protection state.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTFA_FPROT3.
 * @par Example:
 *      @code
 *      uint32_t result = FTFA_PDD_GetPFlashProtectionState(deviceID);
 *      @endcode
 */
#define FTFA_PDD_GetPFlashProtectionState(PeripheralBase) ( \
    (uint32_t)(~(*(uint32_t *)(void *)&(FTFA_FPROT3_REG(PeripheralBase)))) \
  )
#endif  /* #if defined(FTFA_PDD_H_) */

/* FTFA_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/Main/ADC_control.h<|end_filename|>
#ifndef __ADC_CONTROL
  #define __ADC_CONTROL



#define SIG_II_W_CHANNEL     16 // ADC0 16
#define SIG_V_BUS_CHANNEL    17 // ADC0 17

#define SIG_II_V_CHANNEL     16 // ADC1 16
#define SIG_TEMPER_CHANNEL   26 // ADC1 26 Температура кристала

#define SIG_II_U_CHANNEL     16 // ADC2 16
#define SIG_V_U_CHANNEL      12 // ADC2 12

#define SIG_15V_MEAS_CHANNEL  7 // ADC3 7a (после тюнинга на плате ver. 1.0)
#define SIG_5V_MEAS_CHANNEL   5 // ADC3 5a (после тюнинга на плате ver. 1.0)


#define TST_SMPLS_ARR_SZ  (800*2) //  Общее время выборки всех сэмплов 50 мс


#define ADC_AVER_4   1
#define ADC_AVER_8   2
#define ADC_AVER_16  3
#define ADC_AVER_32  4





typedef struct
{

  // Результаты калибровки модулей ADC
  int adc0_cal_res;
  int adc1_cal_res;
  int adc2_cal_res;
  int adc3_cal_res;

} T_ADC_state;


typedef struct
{
  int    maxv;
  int    minv;
  int    averv;
  int long long    rmsv;
} T_meas_stat;


typedef struct
{
  float  favr;
  float  fmin;
  float  fmax;
  float  frms;
} T_meas_results;

#define  FILTR_AVER_SZ  16

typedef struct
{
  unsigned short smpl_ii_w   ; // Текущий отсчет сигнала
  unsigned short smpl_v_bus  ; // Текущий отсчет сигнала
  unsigned short smpl_ii_v   ; // Текущий отсчет сигнала
  unsigned short smpl_temper ; // Текущий отсчет сигнала
  unsigned short smpl_ii_u   ; // Текущий отсчет сигнала
  unsigned short smpl_v_u    ; // Текущий отсчет сигнала
  unsigned short smpl_15v    ; // Текущий отсчет сигнала
  unsigned short smpl_5v     ; // Текущий отсчет сигнала

  int ii_w_offs; // Накопленное смещение
  int ii_v_offs; // Накопленное смещение
  int ii_u_offs; // Накопленное смещение

  int ii_w; // Отфильтрованный от постоянной составляющей сигнал  ii_w
  int ii_v; // Отфильтрованный от постоянной составляющей сигнал  ii_v
  int ii_u; // Отфильтрованный от постоянной составляющей сигнал  ii_u

  unsigned short v_bus_arr[FILTR_AVER_SZ];
  int            v_bus_acc;
  unsigned short v15v_arr[FILTR_AVER_SZ];
  int            v15v_acc;
  unsigned short v5v_arr[FILTR_AVER_SZ];
  int            v5v_acc;
  unsigned int   aai;

  int            v_bus; // Отфильтрованное значение сигнала v_bus;

} T_ADC_res;

typedef struct
{
  const char   *name;
  float        (*int_converter)(int);
  float        (*flt_converter)(float);

} T_vals_scaling;

void ADCs_prepare(void);
void ADC_switch_on_all(void);
void ADC_init(ADC_MemMapPtr ADC);
void ADC_set_channel(ADC_MemMapPtr ADC,int ch, int diff, int reg);
void ADC_activate_hrdw_trig(ADC_MemMapPtr ADC);
void ADC_activate_soft_trig(ADC_MemMapPtr ADC);
void ADC_print_regs(ADC_MemMapPtr ADC);
int  ADC_calibrating(ADC_MemMapPtr ADC);
signed short   ADC_get_sample(ADC_MemMapPtr ADC, INT32U channel, INT32U diff, INT32U aver);

void PDB_configure_ADC_triggers(void);
void PDB_activate_ADC_triggers(void);
void PDB_deactivate_ADC_triggers(void);
void PDB_set_delays(int delay1, int delay2);

//void ADC_reset_smpl_arr_pos(void);
int  ADC_is_smpl_arr_ready(void);
void ADC_get_arr_smp(unsigned int indx, signed short *arr);
void ADC_get_smpl_arr(signed short **ptr);
T_ADC_state *ADC_get_state(void);

void Get_copy_meas_results(T_meas_results * mres);
#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/fio.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: fio.h$
* $Version : 3.8.20.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file is the header file for the standard formatted I/O library 
*   provided with mqx.
*
*END************************************************************************/
#ifndef __fio_h__
#define __fio_h__

/* Include for variable length argument functions */
#include <stdarg.h>

/*--------------------------------------------------------------------------*/
/*
 *                            CONSTANT DEFINITIONS
 */

/* Maximum line size for scanf */
#define IO_MAXLINE  (256)

/* Definitions for filesystem table */
#define FS_MAX_DEVLEN         (8)
#define MAX_FS_INSTANCES      (4)
/* map function names to mqx function names */
#if !defined(MQX_SUPPRESS_STDIO_MACROS) || MQX_SUPPRESS_STDIO_MACROS == 0 
   #define  clearerr   _io_clearerr
   #define  fclose     _io_fclose
   #define  feof       _io_feof
   #define  ferror     _io_ferror
   #define  fflush     _io_fflush
   #define  fgetc      _io_fgetc
   #define  fgetline   _io_fgetline
   #define  fgets      _io_fgets
   #define  fopen      _io_fopen
   #define  fprintf    _io_fprintf
   #define  fputc      _io_fputc
   #define  fputs      _io_fputs
   #define  fscanf     _io_fscanf
   #define  fseek      _io_fseek
   #define  fstatus    _io_fstatus
   #define  ftell      _io_ftell
   #define  fungetc    _io_fungetc
   #define  ioctl      _io_ioctl 
   #define  printf     _io_printf
   #define  putc       _io_fputc
   #define  read       _io_read
   #define  scanf      _io_scanf
   #define  sprintf    _io_sprintf
   #define  snprintf   _io_snprintf
   #define  sscanf     _io_sscanf
   #define  vprintf    _io_vprintf
   #define  vfprintf   _io_vfprintf
   #define  vsprintf   _io_vsprintf
   #define  vsnprintf  _io_vsnprintf
   #define  write      _io_write
   /* fread and fwrite do not read/write chars but objects */
   #define  fread(ptr,so,no,f)  (_io_read(f,ptr,(so)*(no))/(so))
   #define  fwrite(ptr,so,no,f) (_io_write(f,ptr,(so)*(no))/(so))
#endif

#if !defined(MQX_SUPPRESS_STRINGH_MACROS) || MQX_SUPPRESS_STRINGH_MACROS == 0 
   #define  strcasecmp  _io_strcasecmp
   #define  strncasecmp _io_strncasecmp
#endif

/*--------------------------------------------------------------------------*/
/*
 *                        MACRO DECLARATIONS
 */
#if !defined(MQX_SUPPRESS_STDIO_MACROS) || MQX_SUPPRESS_STDIO_MACROS == 0 

#define stdin     (MQX_FILE_PTR)_io_get_handle(IO_STDIN)
#define stdout    (MQX_FILE_PTR)_io_get_handle(IO_STDOUT)
#define stderr    (MQX_FILE_PTR)_io_get_handle(IO_STDERR)

#define getchar()    _io_fgetc(stdin)
#define getline(x,y) _io_fgetline(stdin, (x), (y))
#define gets(x)      _io_fgets((x), 0, stdin)
#define putchar(c)   _io_fputc((c), stdout)
#define puts(s)      _io_fputs((s), stdout)
#define status()     _io_fstatus(stdin)
#define ungetc(c)    _io_fungetc(c, stdin)
#endif /* MQX_SUPPRESS_STDIO_MACROS */

 
/*--------------------------------------------------------------------------*/
/*
 *                            DATATYPE DECLARATIONS
 */


/* FILE STRUCTURE */
 
/*!
 * \brief This structure defines the information kept in order to implement ANSI 
 * 'C' standard I/O stream.
 */
typedef struct mqx_file
{
    
    /*! \brief The address of the Device for this stream. */
    struct io_device_struct _PTR_ DEV_PTR;

    /*! \brief Device Driver specific information. */
    pointer       DEV_DATA_PTR;

    /*! \brief General control flags for this stream. */
    _mqx_uint     FLAGS;
    
    /*! \brief The current error for this stream. */
    _mqx_uint     ERROR;

    /*! \brief The current position in the stream. */
    _file_size    LOCATION;

    /*! \brief The current size of the file. */
    _file_size    SIZE;

    /*! \brief Undelete implementation. */
    boolean       HAVE_UNGOT_CHARACTER;
    /*! \brief Undelete implementation. */
    _mqx_int      UNGOT_CHARACTER;

} MQX_FILE, _PTR_ MQX_FILE_PTR;

/* FILE and MQX_FILE_PTR types are deprecated, but still available for backward compatibility */
#if !defined(MQX_SUPPRESS_FILE_DEF) || MQX_SUPPRESS_FILE_DEF == 0
typedef struct mqx_file file_struct;
typedef MQX_FILE FILE;
typedef MQX_FILE_PTR FILE_PTR;
#endif
 
typedef _mqx_int (_CODE_PTR_ IO_PUTCHAR_FPTR)( _mqx_int, MQX_FILE_PTR);

/*!
 * \brief File system table entry structure.
 */ 
typedef struct 
{
   /*! \brief File system name. */
   char         FS_NAME[FS_MAX_DEVLEN];
   /*! \brief Pointer MQX File. */
   MQX_FILE_PTR FS_PTR;
} FS_TABLE_ENTRY, _PTR_ FS_TABLE_ENTRY_PTR; 

/*--------------------------------------------------------------------------*/
/*
 *                      FUNCTION PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
/* ANSI 'C' library function prototypes */
extern void        _io_clearerr(MQX_FILE_PTR);
extern _mqx_int    _io_fclose(MQX_FILE_PTR);
extern _mqx_int    _io_feof(MQX_FILE_PTR);
extern _mqx_int    _io_ferror(MQX_FILE_PTR);
extern _mqx_int    _io_fflush(MQX_FILE_PTR);
extern _mqx_int    _io_fgetc(MQX_FILE_PTR);
extern _mqx_int    _io_fgetline(MQX_FILE_PTR, char _PTR_, _mqx_int);
extern char _PTR_  _io_fgets(char _PTR_, _mqx_int, MQX_FILE_PTR);
extern MQX_FILE_PTR _io_fopen(const char _PTR_, const char _PTR_);
extern _mqx_int    _io_fprintf(MQX_FILE_PTR, const char _PTR_, ... );
extern _mqx_int    _io_fputc(_mqx_int, MQX_FILE_PTR);
extern _mqx_int    _io_fputs(const char _PTR_, MQX_FILE_PTR);
extern _mqx_int    _io_fscanf(MQX_FILE_PTR, const char _PTR_, ... );
extern _mqx_int    _io_fseek(MQX_FILE_PTR, _file_offset, _mqx_uint);
extern boolean     _io_fstatus(MQX_FILE_PTR);
extern _mqx_int    _io_ftell(MQX_FILE_PTR);
extern _mqx_int    _io_fungetc(_mqx_int, MQX_FILE_PTR);
extern _mqx_int    _io_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);
extern double      _io_modf(double, double _PTR_);
extern _mqx_int    _io_printf(const char _PTR_ , ... );
extern _mqx_int    _io_read(MQX_FILE_PTR, pointer, _mqx_int);
extern _mqx_int    _io_scanf(const char _PTR_ , ... );
extern _mqx_int    _io_sprintf(char _PTR_ , const char _PTR_ , ... );
extern _mqx_int    _io_snprintf(char _PTR_, _mqx_int, const char _PTR_, ...);
extern _mqx_int    _io_sscanf(char _PTR_ , const char _PTR_ , ... );
extern _mqx_int    _io_strcasecmp(const char *s1, const char *s2);
extern _mqx_int    _io_strncasecmp(const char *s1, const char *s2, uint_32 n);
extern double      _io_strtod(char _PTR_, char _PTR_ _PTR_);
extern _mqx_int    _io_vprintf(const char _PTR_, va_list);
extern _mqx_int    _io_vfprintf(MQX_FILE_PTR, const char _PTR_, va_list);
extern _mqx_int    _io_vsprintf(char _PTR_, const char _PTR_, va_list);
extern _mqx_int    _io_vsnprintf(char _PTR_, _mqx_int, const char _PTR_, va_list);
extern _mqx_int    _io_write(MQX_FILE_PTR, pointer, _mqx_int);
extern _mqx_int    _io_atoi(const char *str);


/* 
 * functions mapped out as macros in 'C' but provided for assembler functions
 */
extern _mqx_int    _io_getchar(void);
extern _mqx_int    _io_getline(char _PTR_, _mqx_int);
extern char _PTR_  _io_gets(char _PTR_);
extern _mqx_int    _io_putchar(_mqx_int);
extern _mqx_int    _io_puts(char _PTR_);
extern boolean     _io_status(void);
extern _mqx_int    _io_ungetc(_mqx_int);


extern boolean     _io_strtolower( char_ptr arg);
extern char_ptr    _io_find_filename(char_ptr arg);  
extern boolean     _io_validate_device(char_ptr arg);  
extern void        _io_create_prefixed_filename(char_ptr new_ptr, char_ptr in_ptr,  char_ptr dev_ptr);
extern int_32      _io_rel2abs(char_ptr result, char_ptr curdir, char_ptr inputpath, int_32 len, char_ptr cur_dev);
extern int_32      _io_get_dev_for_path(char_ptr out_dev, boolean * is_dev_in_path, int_32 dev_len, char_ptr input_path, char_ptr cur_dev);

extern MQX_FILE_PTR _io_get_first_valid_fs(void);
extern MQX_FILE_PTR _io_get_fs_by_name(char_ptr fs_name);
extern int_32      _io_get_fs_name(MQX_FILE_PTR fs_ptr, char_ptr fs_name, int_32 fs_name_len);
extern boolean     _io_is_fs_valid(MQX_FILE_PTR fs_ptr);

extern uint_32     _io_unregister_file_system(MQX_FILE_PTR fd_ptr);
extern uint_32     _io_register_file_system(MQX_FILE_PTR fd_ptr,char_ptr name_ptr);

#endif

/*==========================================================================*/

#ifdef __cplusplus
}
#endif

/* Include for I/O sub-system */
#include <io.h>

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/BSP/PIT.h<|end_filename|>
#ifndef PIT_H_
  #define PIT_H_

void PIT0_init(unsigned int period);
void PIT0_int_enable(void);
void PIT0_int_disable(void);
void PIT1_init(unsigned int period );

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/ppphdlc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ppphdlc.c$
* $Version : 3.8.21.0$
* $Date    : Sep-27-2012$
*
* Comments:
*
*   This file contains the PPPHDLC device functions needed
*   for communication.
*
*END************************************************************************/

#include <ppphdlc.h>
#include <fio.h>
#include <rtcs_in.h>
#include "fcs16.h"

PPPHDLC_OPT PPPHDLC_DEFAULT_OPTIONS = {
/* ACCM[]   */   {0xFFFFFFFFl, 0x00000000l, 0x00000000l, 0x60000000l,
                  0x00000000l, 0x00000000l, 0x00000000l, 0x00000000l},
/* PFC      */   FALSE,
/* ACFC     */   FALSE
};

/*
** A macro to test whether a character is flagged in the ACCM
*/

#define ACCM_ISSET(c,accm) ((accm)[(c)/PPPHDLC_BITS_IN_UINT32] & \
                           (1UL << ((c)%PPPHDLC_BITS_IN_UINT32)))

static uint_32 _iopcb_ppphdlc_open  (_iopcb_handle, void (_CODE_PTR_)(pointer), void (_CODE_PTR_)(pointer), pointer);
static uint_32 _iopcb_ppphdlc_close (_iopcb_handle);
static void    _iopcb_ppphdlc_write (_iopcb_handle, PCB_PTR, uint_32);
static PCB_PTR _iopcb_ppphdlc_read  (_iopcb_handle, uint_32);
static uint_32 _iopcb_ppphdlc_ioctl (_iopcb_handle, uint_32, pointer);
static void  PPPHDLC_putc (PPPHDLC_STRUCT_PTR, uchar, PPPHDLC_OPT_PTR);
static uchar PPPHDLC_getc (PPPHDLC_STRUCT_PTR, uint_32_ptr, uint_32_ptr, PPPHDLC_OPT_PTR,uint_32_ptr);
static void    PPPHDLC_CCITT16_start (uint_16_ptr);
static void    PPPHDLC_CCITT16_calc  (uint_16_ptr, uchar);
static void    PPPHDLC_CCITT16_send  (PPPHDLC_STRUCT_PTR, PPPHDLC_OPT_PTR);
static boolean PPPHDLC_CCITT16_check (uint_16_ptr);


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_ppphdlc_init
*  Returned Value : a HANDLE to be used by other functions
*  Comments       :
*      Sets some of the values of the ppphdlc structure and
*  returns the handle of the structure.
*
*END*-----------------------------------------------------------------*/

_iopcb_handle _iopcb_ppphdlc_init
   (
      MQX_FILE_PTR device
         /* [IN] - the IO handle*/
   )
{  /* Body */

#if RTCSCFG_ENABLE_IP4

   PPPHDLC_STRUCT_PTR ppphdlc_ptr;
   _ppphdlc_partid    part_id;

   ppphdlc_ptr = PPPHDLC_memalloc(sizeof(PPPHDLC_STRUCT));
   if (!ppphdlc_ptr) {
      return NULL;
   } /* Endif */

   part_id = PPPHDLC_partcreate(sizeof(PCB)
                              + sizeof(PCB_FRAGMENT)
                              + PPPHDLC_FRAMESIZE_MAXDATA
                              + PPPHDLC_FRAMESIZE_FCS,
                                PPPHDLC_INIT, PPPHDLC_GROW, PPPHDLC_MAX, NULL, NULL);
   if (!part_id) {
      return NULL;
   } /* Endif */

   if (PPPHDLC_mutex_init(&ppphdlc_ptr->MUTEX) != PPPHDLC_OK) {
      return NULL;
   } /* Endif */

   PPPHDLC_memcopy(&PPPHDLC_DEFAULT_OPTIONS, &ppphdlc_ptr->SEND_OPT, sizeof(PPPHDLC_OPT));
   PPPHDLC_memcopy(&PPPHDLC_DEFAULT_OPTIONS, &ppphdlc_ptr->RECV_OPT, sizeof(PPPHDLC_OPT));

   ppphdlc_ptr->DEVICE  = device;
   ppphdlc_ptr->PART_ID = part_id;

   ppphdlc_ptr->PCB_TABLE.OPEN  = _iopcb_ppphdlc_open;
   ppphdlc_ptr->PCB_TABLE.CLOSE = _iopcb_ppphdlc_close;
   ppphdlc_ptr->PCB_TABLE.READ  = _iopcb_ppphdlc_read;
   ppphdlc_ptr->PCB_TABLE.WRITE = _iopcb_ppphdlc_write;
   ppphdlc_ptr->PCB_TABLE.IOCTL = _iopcb_ppphdlc_ioctl;

   return &ppphdlc_ptr->PCB_TABLE;

#else

    return NULL;

#endif /* RTCSCFG_ENABLE_IP4  */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_ppphdlc_open
*  Returned Value : uint_32, an ERROR code
*  Comments       :
*      Sets some of the values of the ppphdlc structure and opens the link.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_ppphdlc_open
   (
      _iopcb_handle       handle,
         /* [IN] - the IO handle*/
      void (_CODE_PTR_    up)(pointer),
         /* [IN] - function to put the link up */
      void (_CODE_PTR_    down)(pointer),
         /* [IN] - function to put the link down */
      pointer             param
         /* [IN] - for the up/down functions */
   )
{  /* Body */
   PPPHDLC_STRUCT_PTR ppphdlc_ptr = (PPPHDLC_STRUCT_PTR)((void _PTR_)handle);

   ppphdlc_ptr->UP      = up;
   ppphdlc_ptr->DOWN    = down;
   ppphdlc_ptr->PARAM   = param;

   /* open connection */
   if (ppphdlc_ptr->UP) {
      up(param);
   } /* Endif */

   return PPPHDLC_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_ppphdlc_write
*  Returned Value :
*  Comments       :
*      Transmits the data
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void _iopcb_ppphdlc_write
   (
      _iopcb_handle      handle,
         /* [IN] - the handle */
      PCB_PTR            pcb_ptr,
         /* [IN] - the packet */
      uint_32            flags
         /* [IN] - the flags */
   )
{ /* Body */
   PPPHDLC_STRUCT_PTR ppphdlc_ptr = (PPPHDLC_STRUCT_PTR)((void _PTR_)handle);
   PPPHDLC_OPT        ppphdlc_opt, _PTR_ ppphdlc_opt_ptr;
   uint_32            length;
   uchar_ptr          fragment;
   uint_32            i = 0;

   PPPHDLC_mutex_lock(&ppphdlc_ptr->MUTEX);
   ppphdlc_opt = ppphdlc_ptr->SEND_OPT;
   PPPHDLC_mutex_unlock(&ppphdlc_ptr->MUTEX);

   if (flags & 1) {
      ppphdlc_opt_ptr = &PPPHDLC_DEFAULT_OPTIONS;
   } else {
      ppphdlc_opt_ptr = &ppphdlc_opt;
   } /* Endif */

   /* Send the HDLC flag sequence */
   fputc(PPPHDLC_FLAG, ppphdlc_ptr->DEVICE);
   PPPHDLC_CCITT16_start(&ppphdlc_ptr->FCS_SEND);

   /* Send the header */
   if (!ppphdlc_opt_ptr->ACFC) {
      PPPHDLC_putc(ppphdlc_ptr, PPPHDLC_ADDR, ppphdlc_opt_ptr);
      PPPHDLC_putc(ppphdlc_ptr, PPPHDLC_CTRL, ppphdlc_opt_ptr);
   } /* Endif */

   /* Send the packet */
   length = pcb_ptr->FRAG[i].LENGTH;
   fragment = pcb_ptr->FRAG[i].FRAGMENT;

   /* Compress the protocol field if possible */
   if (!ppphdlc_opt_ptr->PFC || *fragment) {
      PPPHDLC_putc(ppphdlc_ptr, *fragment, ppphdlc_opt_ptr);
   } /* Endif */
   fragment++;
   length--;

   while (length != 0)  {
      while (length != 0) {
         PPPHDLC_putc(ppphdlc_ptr, *fragment++, ppphdlc_opt_ptr);
         length--;
      } /* Endwhile */
      i++;
      length = pcb_ptr->FRAG[i].LENGTH;
      fragment = pcb_ptr->FRAG[i].FRAGMENT;
   } /* Endwhile */

   /* Send the checksum */
   PPPHDLC_CCITT16_send(ppphdlc_ptr, ppphdlc_opt_ptr);
   ppphdlc_ptr->STATS.COMMON.ST_TX_TOTAL++;

   /* Verify the checksum */
   if (!PPPHDLC_CCITT16_check(&ppphdlc_ptr->FCS_SEND))  {
      ppphdlc_ptr->STATS.COMMON.ST_TX_MISSED++;
   } /* Endif */

   fputc(PPPHDLC_FLAG, ppphdlc_ptr->DEVICE);
   PCB_free(pcb_ptr);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_ppphdlc_read
*  Returned Value : PCB_PTR
*  Comments       :
*      Receives the data
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static PCB_PTR _iopcb_ppphdlc_read
   (
      _iopcb_handle    handle,
         /* [IN] - the structure handle */
      uint_32          flags
         /* [IN] - flags */
   )
{  /* Body */
   PPPHDLC_STRUCT_PTR ppphdlc_ptr = (PPPHDLC_STRUCT_PTR)((void _PTR_)handle);
   PCB_FRAGMENT _PTR_ pcb_frag_ptr;
   PPPHDLC_OPT        ppphdlc_opt;
   PCB_PTR            pcb;
   uint_32            err;
   uint_32            retry,wait;
   uint_32           *rx_stop_ptr;     
   uchar_ptr          p;
   uint_16            data_len;
   register uchar     c;
   
   /* 
    * If device does not have any data it has not sense to create PCB and wait for data. 
    * It take less resources.
    */
   if(!fstatus(ppphdlc_ptr->DEVICE))  
   {  
        return NULL;  
   }
   rx_stop_ptr = (uint_32 *)flags;
   PPPHDLC_mutex_lock(&ppphdlc_ptr->MUTEX);
   ppphdlc_opt = ppphdlc_ptr->RECV_OPT;
   PPPHDLC_mutex_unlock(&ppphdlc_ptr->MUTEX);

   retry = 20;
   pcb = NULL;
   while (!pcb) 
   {
      pcb = PPPHDLC_partalloc(ppphdlc_ptr->PART_ID);
      if (!pcb) 
      {
         ppphdlc_ptr->STATS.COMMON.ST_RX_DISCARDED++;
         PPPHDLC_delay(1);
         return NULL;
      } /* Endif */
   } /* Endwhile */

   pcb->FREE = (void (_CODE_PTR_)(PCB_PTR))PPPHDLC_partfree;
   pcb->PRIVATE = pcb;
   pcb_frag_ptr = pcb->FRAG;
   pcb_frag_ptr->FRAGMENT = (uchar_ptr)pcb + sizeof(PCB) + sizeof(PCB_FRAGMENT);
   pcb_frag_ptr++;
   pcb_frag_ptr->LENGTH = 0;
   pcb_frag_ptr->FRAGMENT = NULL;

restart:
   retry--;  
   if(!retry)  
   {  
   /* if we cannot take right packet we are returning 0 pcb */
     pcb->FRAG[0].LENGTH = 0;  
     return pcb;  
   }   
   
   p = pcb->FRAG[0].FRAGMENT;
   /* zerou's check summ  */
   PPPHDLC_CCITT16_start(&ppphdlc_ptr->FCS_RECV);

   c = PPPHDLC_getc(ppphdlc_ptr, &err, NULL, &ppphdlc_opt,rx_stop_ptr);
   if (err)
   {  
      goto restart;
   }
   /* Receive the frame header */
   /* 
      ACFC -Address-and-Control-Field-Compression. 
      So, if it is not compressed and it is not 0xFF 
      start wait 200 times for start of PPP packet 0x7E
   */
   if (!ppphdlc_opt.ACFC && (c != PPPHDLC_ADDR)) 
   {
      ppphdlc_ptr->STATS.ST_RX_BAD_ADDR++;
      wait = 200;
      while(wait) 
      {
          while(!fstatus(ppphdlc_ptr->DEVICE))
          {
          /* checking if RX_STOP is 1, it means that task aborted */
            if(*rx_stop_ptr)
            {
                if(pcb != NULL)  
                {
                    PCB_free(pcb);
                }   
              return(0);  
            }
            _time_delay(1);
          }
          if(fgetc(ppphdlc_ptr->DEVICE) == PPPHDLC_FLAG)
          {
            wait=0;
          }
 	  wait--;
      }  
      goto restart;
   } /* Endif */

   /* If we got one, wait for control byte */
   /*
      If we reach here  it means that we received 0xFF (PPPHDLC_ADDR , and before it 0x7E ,start PPP)
      So , now we are reading for 0x03 (PPPHDLC_CTRL) 
   */
   if (c == PPPHDLC_ADDR) 
   {
      c = PPPHDLC_getc(ppphdlc_ptr, &err, &ppphdlc_ptr->STATS.ST_RX_RUNT, &ppphdlc_opt,rx_stop_ptr);
      if (err) goto restart;

      if (c != PPPHDLC_CTRL) 
      {
        ppphdlc_ptr->STATS.ST_RX_BAD_CTRL++;
         
        /* new fix */
        wait = 200; 
        while(wait) 
 	{
          while(!fstatus(ppphdlc_ptr->DEVICE))
          {
            /* checking if RX_STOP is 1, it means that task aborted */
            if(*rx_stop_ptr)
            {
                if(pcb != NULL)  
                {
                    PCB_free(pcb);
                }   
              return(0);  
            }
            _time_delay(1);
          }
          if(fgetc(ppphdlc_ptr->DEVICE) == PPPHDLC_FLAG)
          {
            wait=0;
          }
 	  wait--;
        }  
        goto restart;
      } /* Endif */
      c = PPPHDLC_getc(ppphdlc_ptr, &err, &ppphdlc_ptr->STATS.ST_RX_RUNT, &ppphdlc_opt,rx_stop_ptr);
      if (err) goto restart;
   } /* Endif */

   data_len = 0;

   /* Decompress the protocol field if necessary */
   if (c & 1) 
   {
      *p++ = 0;
      ++data_len;
   } /* Endif */

   /* We must recieve at least a frame check sequence */
   while (data_len < PPPHDLC_FRAMESIZE_FCS) 
   {
      *p++ = c;
      ++data_len;
      c = PPPHDLC_getc(ppphdlc_ptr, &err, &ppphdlc_ptr->STATS.ST_RX_RUNT, &ppphdlc_opt,rx_stop_ptr);
      if (err) goto restart;
   } /* Endwhile */

   /* Receive data */
   for (;;) 
   {
 
      *p++ = c;
      ++data_len;
      c = PPPHDLC_getc(ppphdlc_ptr, &err, NULL, &ppphdlc_opt,rx_stop_ptr);


      if (err == PPPHDLC_END)
      { 
        break;
      }  
      if (err == PPPHDLC_ABORT)
      { 
        goto restart;
      }  
      /*
        If data_len >= maximum packet size - it means some error happend or some unsupported packet come.
        So, we start to wait for another valid packet waiting 200 times for  0x7E (PPPHDLC_FLAG - start of PPP packet)
      */
      if (data_len >= (PPPHDLC_FRAMESIZE_MAXDATA + PPPHDLC_FRAMESIZE_FCS)) 
      {
         ppphdlc_ptr->STATS.ST_RX_GIANT++;

         wait = 200; 
         while(wait) 
 	 {
            while(!fstatus(ppphdlc_ptr->DEVICE))
            {
             /* checking if RX_STOP is 1, it means that task aborted */
                 if(*rx_stop_ptr)
                 {
                     if(pcb != NULL)  
                     {
                         PCB_free(pcb);
                     }   
                     return(0);  
                 }
                 _time_delay(1);
            }
            if(fgetc(ppphdlc_ptr->DEVICE) == PPPHDLC_FLAG)
            {
                 wait=0;
            }
 	    wait--;
 	}          

        goto restart;
      } /* Endif */
   } /* Endfor */

   /* Validate the FCS */
   /*
      checking controll summ here (last 2 bytes)
   */
   if (!PPPHDLC_CCITT16_check(&ppphdlc_ptr->FCS_RECV))  
   {
      ppphdlc_ptr->STATS.ST_RX_BAD_FCS++;
      goto restart;
   } /* Endif */
   pcb->FRAG[0].LENGTH = data_len - PPPHDLC_FRAMESIZE_FCS;
   return pcb;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_ppphdlc_close
*  Returned Value : uint_32, an ERROR code
*  Comments       :
*     Close link and free memory
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_ppphdlc_close
   (
      _iopcb_handle  handle
         /* [IN] - the structure handle */
   )
{  /* Body */
   PPPHDLC_STRUCT_PTR ppphdlc_ptr = (PPPHDLC_STRUCT_PTR)((void _PTR_)handle);

   /* close connection */
   if (ppphdlc_ptr->DOWN) {
      ppphdlc_ptr->DOWN(ppphdlc_ptr->PARAM);
   } /* Endif */

   /* Free memory */
   /*Free memory block by block. */
   PPPHDLC_partdestroy(ppphdlc_ptr->PART_ID);
   PPPHDLC_mutex_destroy(&ppphdlc_ptr->MUTEX);
   PPPHDLC_memfree(ppphdlc_ptr);

   return PPPHDLC_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_ppphdlc_ioctl
*  Returned Value : an ERROR code
*  Comments       :
*      Store and set the options
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_ppphdlc_ioctl
   (
      _iopcb_handle    handle,
         /* [IN] - the structure handle */
      uint_32          option,
         /* [IN] - options */
      pointer          value
         /* [IN] - option value */
   )
{  /* Body */
   PPPHDLC_STRUCT_PTR ppphdlc_ptr = (PPPHDLC_STRUCT_PTR)((void _PTR_)handle);

   PPPHDLC_mutex_lock(&ppphdlc_ptr->MUTEX);

   switch(option)  {
      case IOPCB_IOCTL_S_ACCM:
         ppphdlc_ptr->SEND_OPT.ACCM[0] = *(uint_32 _PTR_)value;
         break;
      case IOPCB_IOCTL_R_ACCM:
         ppphdlc_ptr->RECV_OPT.ACCM[0] = *(uint_32 _PTR_)value;
         break;
      case IOPCB_IOCTL_S_PFC:
         ppphdlc_ptr->SEND_OPT.PFC = *(boolean _PTR_)value;
         break;
      case IOPCB_IOCTL_R_PFC:
         ppphdlc_ptr->RECV_OPT.PFC = *(boolean _PTR_)value;
         break;
      case IOPCB_IOCTL_S_ACFC:
         ppphdlc_ptr->SEND_OPT.ACFC = *(boolean _PTR_)value;
         break;
      case IOPCB_IOCTL_R_ACFC:
         ppphdlc_ptr->RECV_OPT.ACFC = *(boolean _PTR_)value;
         break;
      case IOPCB_IOCTL_GET_IFTYPE:
         *(uint_32_ptr)value = IPIFTYPE_RS232;
         break;
   } /* Endswitch */

   PPPHDLC_mutex_unlock(&ppphdlc_ptr->MUTEX);

   return PPPHDLC_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPHDLC_putc
* Returned Value  :  None
* Comments        :
*     Outputs one character, escaped if necessary, and updates
*     the FCS.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPHDLC_putc
   (
      PPPHDLC_STRUCT_PTR  handle,
            /* [IN] - the ppphdlc structure */
      uchar               c,
            /* [IN] - character to send */
      PPPHDLC_OPT_PTR     opt
            /* [IN] - the options */
   )
{ /* Body */
   
   if (ACCM_ISSET(c, opt->ACCM)) {
      fputc(PPPHDLC_ESC, handle->DEVICE);
      fputc((char)c ^ 0x20, handle->DEVICE);
   } else {
      fputc((char)c, handle->DEVICE);
   } /* Endif */

   PPPHDLC_CCITT16_calc(&handle->FCS_SEND, c);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPHDLC_getc
* Returned Value  :  character
* Comments        :
*     Retrieves one character and updates the FCS.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uchar PPPHDLC_getc
   (
      PPPHDLC_STRUCT_PTR  handle,
            /* [IN] - the handle of the ppphdlc structure */
      uint_32_ptr         error,
            /* [OUT] - end of frame condition */
      uint_32_ptr         stat,
            /* [IN] - statistics counter to increment on flag character */
      PPPHDLC_OPT_PTR     opt,
            /* [IN] - the options */
      uint_32_ptr         rx_stop_ptr      
   )
{ /* Body */
   uchar c;
   boolean esc = FALSE;

   for (;;) 
   {
   
        /* We will read from device only if it has any data*/
        /*TBD read with timeout or with abort should be used here. But not implemented yet in MQX. */
        while(!fstatus(handle->DEVICE))
        {
        /* checking if RX_STOP is 1 it means that task aborted */
            if(*rx_stop_ptr)
            {
                *error = PPPHDLC_ABORT; 
                return(0);  
            }
            _time_delay(1);
        }   
 
        c = (uchar)fgetc(handle->DEVICE);

         /* The flag sequence ends a frame */
      if (c == PPPHDLC_FLAG) 
      {
         if (esc) 
         {
            handle->STATS.ST_RX_ABORTED++;
            *error = PPPHDLC_ABORT;
         } 
         else 
         {
            if (stat) (*stat)++;
            *error = PPPHDLC_END;
         } /* Endif */
         return 0;
      } /* Endif */

      /* Toss all flagged control characters */
      if (c < 0x20 && ACCM_ISSET(c, opt->ACCM)) 
      {
         continue;
      } /* Endif */

      /* Escaped characters get bit 5 toggled */
      if (esc) 
      {
         c ^= 0x20;
      } 
      else if (c == PPPHDLC_ESC) 
      {
         esc = TRUE;
         continue;
      } /* Endif */

      PPPHDLC_CCITT16_calc(&handle->FCS_RECV, c);
      *error = PPPHDLC_OK;
      return c;
   } /* Endfor */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPHDLC_CCITT16_start
* Returned Value  :  None
* Comments        :
*     Initializes the FCS_DATA for a CRC calculation.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPHDLC_CCITT16_start
   (
      uint_16_ptr        fcs
            /* [IN] -  fcs information */
   )
{ /* Body */
   *fcs = 0xFFFF;
} /* Endbody */

#endif 

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPHDLC_CCITT16_calc
* Returned Value  :  None
* Comments        :
*     Updates the CRC calculation given a new character.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPHDLC_CCITT16_calc
   (
      uint_16_ptr    fcs,
            /* [IN] - FCS information */
      uchar          c
            /* [IN] - character */
   )
{ /* Body */
   uint_16 crc = *fcs;

   crc = (crc >> 8) ^ fcstab[(crc ^ c) & 0xFF];
   *fcs = crc;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPHDLC_CCITT16_send
* Returned Value  :  None
* Comments        :
*     Sends a CRC.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PPPHDLC_CCITT16_send
   (
      PPPHDLC_STRUCT_PTR   ppphdlc_ptr,
            /* [IN] - the handle of the ppphdlc structure */
      PPPHDLC_OPT_PTR      opt
            /* [IN] - the options */
   )
{ /* Body */
   uint_16 crc = ~ppphdlc_ptr->FCS_SEND & 0xFFFF;
   PPPHDLC_putc(ppphdlc_ptr,  crc      & 0xFF, opt);
   PPPHDLC_putc(ppphdlc_ptr, (crc>>=8) & 0xFF, opt);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPPHDLC_CCITT16_check
* Returned Value  :  TRUE if CRC is correct
* Comments        :
*     Validates a CRC calculation.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean PPPHDLC_CCITT16_check
   (
      uint_16_ptr   fcs
            /* [IN] - FCS information */
   )
{ /* Body */

   return (*fcs == 0xF0B8);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */


/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/BSP/GPIO.c<|end_filename|>
#include "app_types.h"
#include <MK60F15.h>

typedef struct
{
  GPIO_MemMapPtr gpio;
  PORT_MemMapPtr port;
  unsigned char  pin_num;
  unsigned char  irqc; //  Interrupt Configuration
                       //  0000 Interrupt/DMA Request disabled.
                       //  0001 DMA Request on rising edge.
                       //  0010 DMA Request on falling edge.
                       //  0011 DMA Request on either edge.
                       //  0100 Reserved.
                       //  1000 Interrupt when logic zero.
                       //  1001 Interrupt on rising edge.
                       //  1010 Interrupt on falling edge.
                       //  1011 Interrupt on either edge.
                       //  1100 Interrupt when logic one.
  unsigned char  lock; //  if 1 Pin Control Register bits [15:0] are locked and cannot be updated until the next System Reset.
  unsigned char  mux;  //  Pin Mux Control
                       //  000 Pin Disabled (Analog).
                       //  001 Alternative 1 (GPIO).
                       //  010 Alternative 2 (chip specific).
                       //  011 Alternative 3 (chip specific).
                       //  100 Alternative 4 (chip specific).
                       //  101 Alternative 5 (chip specific).
                       //  110 Alternative 6 (chip specific).
                       //  111 Alternative 7 (chip specific / JTAG / NMI).
  unsigned char  DSE; // 0 Low drive strength is configured on the corresponding pin, if pin is configured as a digital output.
                      // 1 High drive strength is configured on the corresponding pin, if pin is configured as a digital output.
  unsigned char  SRE;  // 0 Fast slew rate is configured on the corresponding pin, if pin is configured as a digital output.
                       // 1 Slow slew rate is configured on the corresponding pin, if pin is configured as a digital output.
  unsigned char  ODE;  // 0 Open Drain output is disabled on the corresponding pin.
                       // 1 Open Drain output is enabled on the corresponding pin, provided pin is configured as a digital output.
  unsigned char  PFE;  // 0 Passive Input Filter is disabled on the corresponding pin.
                       // 1 Passive Input Filter is enabled on the corresponding pin.
  unsigned char  PUPD; // 00 Internal pull-up or pull-down resistor is not enabled on the corresponding pin.
                       // 10 Internal pull-down resistor is enabled on the corresponding pin, if the corresponding Port Pull Enable Register bit is set.
                       // 11 Internal pull-up resistor is enabled on the corresponding pin, if the corresponding Port Pull Enable Register bit is set.
  unsigned char  dir;  // 0 Pin is configured as general purpose input, if configured for the GPIO function
                       // 1 Pin is configured for general purpose output, if configured for the GPIO function
  unsigned char  init; // Init state

} T_IO_pins_configuration;

#define   ANAL          0
#define   GPIO          1
#define   ALT2          2
#define   ALT3          3
#define   ALT4          4
#define   ALT5          5
#define   ALT6          6
#define   ALT7          7

#define   DSE_LO        0
#define   DSE_HI        1

#define   OD_DIS        0
#define   OD__EN        1

#define   PFE_DIS       0
#define   PFE__EN       1

#define   FAST_SLEW     0
#define   SLOW_SLEW     1


#define   PUPD_DIS      0
#define   PULL__DN      2
#define   PULL__UP      3

#define   GP_INP        0
#define   GP_OUT        1


const T_IO_pins_configuration gen_pins_conf[] =
{
// gpio          port            num  irqc  lock  mux   DSE     SRE        ODE     PFE      PUPD      dir     init
  { PTA_BASE_PTR, PORTA_BASE_PTR,   0,   0,   1,   ALT7, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // JTAG_TCLK
  { PTA_BASE_PTR, PORTA_BASE_PTR,   1,   0,   1,   ALT7, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // JTAG_TDI
  { PTA_BASE_PTR, PORTA_BASE_PTR,   2,   0,   1,   ALT7, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // JTAG_TDO
  { PTA_BASE_PTR, PORTA_BASE_PTR,   3,   0,   1,   ALT7, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // JTAG_TMS
  { PTA_BASE_PTR, PORTA_BASE_PTR,   4,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTA_BASE_PTR, PORTA_BASE_PTR,   5,   0,   1,   ALT7, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // JTAG_TRST
  { PTA_BASE_PTR, PORTA_BASE_PTR,   6,   0,   1,   ALT5, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // CLKOUT - тестовый выход
//  { PTA_BASE_PTR, PORTA_BASE_PTR,   6,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_OUT,   1 }, // CLKOUT - тестовый выход
  { PTA_BASE_PTR, PORTA_BASE_PTR,   7,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTA_BASE_PTR, PORTA_BASE_PTR,   8,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ZCROSS
  { PTA_BASE_PTR, PORTA_BASE_PTR,   9,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTA_BASE_PTR, PORTA_BASE_PTR,  10,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // ENC1, вход энкодера
  { PTA_BASE_PTR, PORTA_BASE_PTR,  11,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // ENC2, вход энкодера
  { PTA_BASE_PTR, PORTA_BASE_PTR,  12,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // PWM_OE, вход наблюдателя за блокировкой PWM
  { PTA_BASE_PTR, PORTA_BASE_PTR,  13,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_OUT,   1 }, // PWM_EN, выход разрешения PWM (1-запрещает, 0-разрешает)
  { PTA_BASE_PTR, PORTA_BASE_PTR,  14,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // OUT2
  { PTA_BASE_PTR, PORTA_BASE_PTR,  15,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // OUT3
  { PTA_BASE_PTR, PORTA_BASE_PTR,  16,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // OUT1
  { PTA_BASE_PTR, PORTA_BASE_PTR,  17,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PUPD_DIS, GP_INP,   0 }, // IN1
  // Нельзя трогать выводы осциллятора иначе чип перестает работать с JTAG программироваться из IAR
  // { PTA_BASE_PTR, PORTA_BASE_PTR,  18,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // EXTAL
  // { PTA_BASE_PTR, PORTA_BASE_PTR,  19,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // XTAL
  { PTA_BASE_PTR, PORTA_BASE_PTR,  24,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD__EN, PFE_DIS, PULL__UP, GP_OUT,   0 }, // LED1. Включается от лог.0
  { PTA_BASE_PTR, PORTA_BASE_PTR,  25,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD__EN, PFE_DIS, PULL__UP, GP_OUT,   1 }, // LED2. Включается от лог.0
  { PTA_BASE_PTR, PORTA_BASE_PTR,  26,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD__EN, PFE_DIS, PULL__UP, GP_OUT,   1 }, // LED3. Включается от лог.0
  { PTA_BASE_PTR, PORTA_BASE_PTR,  27,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTA_BASE_PTR, PORTA_BASE_PTR,  28,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTA_BASE_PTR, PORTA_BASE_PTR,  29,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // V_U. Измерение напряжение на выходе M1

  { PTB_BASE_PTR, PORTB_BASE_PTR,   0,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTB_BASE_PTR, PORTB_BASE_PTR,   1,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTB_BASE_PTR, PORTB_BASE_PTR,   2,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // V_W. Измерение напряжение на выходе M3
  { PTB_BASE_PTR, PORTB_BASE_PTR,   3,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // VFO. Оповещение от драйвера FSBB30CH60CT
  { PTB_BASE_PTR, PORTB_BASE_PTR,   4,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTB_BASE_PTR, PORTB_BASE_PTR,   5,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTB_BASE_PTR, PORTB_BASE_PTR,   6,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // V_V. Измерение напряжение на выходе M2
  { PTB_BASE_PTR, PORTB_BASE_PTR,   7,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTB_BASE_PTR, PORTB_BASE_PTR,   8,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTB_BASE_PTR, PORTB_BASE_PTR,   9,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTB_BASE_PTR, PORTB_BASE_PTR,  10,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // TOS1. Оповещение от измерителя температуры IGBT модуля
  { PTB_BASE_PTR, PORTB_BASE_PTR,  11,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---

  { PTB_BASE_PTR, PORTB_BASE_PTR,  16,   0,   0,   ALT3, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // UART_RX
  { PTB_BASE_PTR, PORTB_BASE_PTR,  17,   0,   0,   ALT3, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // UART_TX
  { PTB_BASE_PTR, PORTB_BASE_PTR,  18,   0,   0,   ALT2, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // CAN_TX
  { PTB_BASE_PTR, PORTB_BASE_PTR,  19,   0,   0,   ALT2, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // CAN_RX
  { PTB_BASE_PTR, PORTB_BASE_PTR,  20,   0,   0,   ALT2, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SPI2_CS.   SPI Flash
  { PTB_BASE_PTR, PORTB_BASE_PTR,  21,   0,   0,   ALT2, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SPI2_CLK.  SPI Flash
  { PTB_BASE_PTR, PORTB_BASE_PTR,  22,   0,   0,   ALT2, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SPI2_SOUT. SPI Flash
  { PTB_BASE_PTR, PORTB_BASE_PTR,  23,   0,   0,   ALT2, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SPI2_SIN.  SPI Flash

  { PTC_BASE_PTR, PORTC_BASE_PTR,   0,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // SPI_RES. Сброс SPI Flash
  { PTC_BASE_PTR, PORTC_BASE_PTR,   1,   0,   0,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__DN, GP_INP,   0 }, // T0C0. PWM канал 0
  { PTC_BASE_PTR, PORTC_BASE_PTR,   2,   0,   0,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__DN, GP_INP,   0 }, // T0C1. PWM канал 1
  { PTC_BASE_PTR, PORTC_BASE_PTR,   3,   0,   0,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__DN, GP_INP,   0 }, // T0C2. PWM канал 2
  { PTC_BASE_PTR, PORTC_BASE_PTR,   4,   0,   0,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__DN, GP_INP,   0 }, // T0C3. PWM канал 3
  { PTC_BASE_PTR, PORTC_BASE_PTR,   5,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTC_BASE_PTR, PORTC_BASE_PTR,   6,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTC_BASE_PTR, PORTC_BASE_PTR,   7,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTC_BASE_PTR, PORTC_BASE_PTR,   8,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTC_BASE_PTR, PORTC_BASE_PTR,   9,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTC_BASE_PTR, PORTC_BASE_PTR,  10,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTC_BASE_PTR, PORTC_BASE_PTR,  11,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTC_BASE_PTR, PORTC_BASE_PTR,  12,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // CAN_SENS
  { PTC_BASE_PTR, PORTC_BASE_PTR,  13,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // NTC_BYPASS
  { PTC_BASE_PTR, PORTC_BASE_PTR,  14,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   1 }, // USBCTRL
  { PTC_BASE_PTR, PORTC_BASE_PTR,  15,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTC_BASE_PTR, PORTC_BASE_PTR,  16,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // DIP SW 1
  { PTC_BASE_PTR, PORTC_BASE_PTR,  17,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // DIP SW 2
  { PTC_BASE_PTR, PORTC_BASE_PTR,  18,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // DIP SW 3
  { PTC_BASE_PTR, PORTC_BASE_PTR,  19,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // DIP SW 4

  { PTD_BASE_PTR, PORTD_BASE_PTR,   0,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // ---
  { PTD_BASE_PTR, PORTD_BASE_PTR,   1,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // ---
  { PTD_BASE_PTR, PORTD_BASE_PTR,   2,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTD_BASE_PTR, PORTD_BASE_PTR,   3,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // ---
  { PTD_BASE_PTR, PORTD_BASE_PTR,   4,   0,   0,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__DN, GP_INP,   0 }, // T0C4. PWM канал 4
  { PTD_BASE_PTR, PORTD_BASE_PTR,   5,   0,   0,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__DN, GP_INP,   0 }, // T0C5. PWM канал 5
  { PTD_BASE_PTR, PORTD_BASE_PTR,   6,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // BR_ON
  { PTD_BASE_PTR, PORTD_BASE_PTR,   7,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTD_BASE_PTR, PORTD_BASE_PTR,   8,   0,   0,   ALT2, DSE_HI, FAST_SLEW, OD_DIS, PFE__EN, PULL__UP, GP_INP,   0 }, // SCL
  { PTD_BASE_PTR, PORTD_BASE_PTR,   9,   0,   0,   ALT2, DSE_HI, FAST_SLEW, OD_DIS, PFE__EN, PULL__UP, GP_INP,   0 }, // SDA
  { PTD_BASE_PTR, PORTD_BASE_PTR,  10,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTD_BASE_PTR, PORTD_BASE_PTR,  11,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // DSPL_RST
  { PTD_BASE_PTR, PORTD_BASE_PTR,  12,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // DSPL_SCL
  { PTD_BASE_PTR, PORTD_BASE_PTR,  13,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // DSPL_SI
  { PTD_BASE_PTR, PORTD_BASE_PTR,  14,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // DSPL_RS
  { PTD_BASE_PTR, PORTD_BASE_PTR,  15,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // DSPL_SCB

  { PTE_BASE_PTR, PORTE_BASE_PTR,   0,   0,   1,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SD_D1
  { PTE_BASE_PTR, PORTE_BASE_PTR,   1,   0,   1,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SD_D0
  { PTE_BASE_PTR, PORTE_BASE_PTR,   2,   0,   1,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SD_CLK
  { PTE_BASE_PTR, PORTE_BASE_PTR,   3,   0,   1,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SD_CMD
  { PTE_BASE_PTR, PORTE_BASE_PTR,   4,   0,   1,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SD_D3
  { PTE_BASE_PTR, PORTE_BASE_PTR,   5,   0,   1,   ALT4, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // SD_D2
  { PTE_BASE_PTR, PORTE_BASE_PTR,   6,   0,   0,   ALT6, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // BUZZ
  { PTE_BASE_PTR, PORTE_BASE_PTR,   7,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_OUT,   0 }, // COOLER_ON
  { PTE_BASE_PTR, PORTE_BASE_PTR,   8,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // I_U
  { PTE_BASE_PTR, PORTE_BASE_PTR,   9,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTE_BASE_PTR, PORTE_BASE_PTR,  10,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTE_BASE_PTR, PORTE_BASE_PTR,  11,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTE_BASE_PTR, PORTE_BASE_PTR,  12,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---

  { PTE_BASE_PTR, PORTE_BASE_PTR,  24,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // V_BUS
  { PTE_BASE_PTR, PORTE_BASE_PTR,  25,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, //
  { PTE_BASE_PTR, PORTE_BASE_PTR,  26,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // 5V_MEAS
  { PTE_BASE_PTR, PORTE_BASE_PTR,  27,   0,   0,   GPIO, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // ---
  { PTE_BASE_PTR, PORTE_BASE_PTR,  28,   0,   0,   ANAL, DSE_HI, FAST_SLEW, OD_DIS, PFE_DIS, PULL__UP, GP_INP,   0 }, // 15V_MEAS

};


/*------------------------------------------------------------------------------
 
 ------------------------------------------------------------------------------*/
static void Config_pin(const T_IO_pins_configuration pinc)
{
  pinc.port->PCR[pinc.pin_num] = LSHIFT(pinc.irqc, 16) |
                                 LSHIFT(pinc.lock, 15) |
                                 LSHIFT(pinc.mux, 8) |
                                 LSHIFT(pinc.DSE, 6) |
                                 LSHIFT(pinc.ODE, 5) |
                                 LSHIFT(pinc.PFE, 4) |
                                 LSHIFT(pinc.SRE, 2) |
                                 LSHIFT(pinc.PUPD, 0);

  if ( pinc.init == 0 ) pinc.gpio->PCOR = LSHIFT(1, pinc.pin_num);
  else pinc.gpio->PSOR = LSHIFT(1, pinc.pin_num);
  pinc.gpio->PDDR = (pinc.gpio->PDDR & ~LSHIFT(1, pinc.pin_num)) | LSHIFT(pinc.dir, pinc.pin_num);
}


/*------------------------------------------------------------------------------
 
 ------------------------------------------------------------------------------*/
int Init_pins(void)
{
  int i;

  // Включаем тактирование на всех портах
  SIM_SCGC5 |=   SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTF_MASK;

  for (i = 0; i < (sizeof(gen_pins_conf) / sizeof(gen_pins_conf[0])); i++)
  {
    Config_pin(gen_pins_conf[i]);
  }

  // Конфигурируем цифровой фильтр для I2C
  // Без фильтра происходит зависание контроллера I2C в схеме инвертора версии 2
  PORTD_DFWR = 0x1F;
  PORTD_DFER = BIT(8) + BIT(9);
  return 0;
}


/*-------------------------------------------------------------------------------------------------------------
  Установка состояния светодиодов
  led_num - номер светодиода (1...3)
  state   - состояние ( 1 - включен, 0 - выключен)
-------------------------------------------------------------------------------------------------------------*/
void Led_control(int led_num, int state)
{
  switch (led_num)
  {
  case 1:
    if ( (state & BIT(0)) != 0 ) PTA_BASE_PTR->PCOR = LSHIFT(1, 24);
    else PTA_BASE_PTR->PSOR = LSHIFT(1, 24);
    break;
  case 2:
    if ( (state & BIT(0)) != 0 ) PTA_BASE_PTR->PCOR = LSHIFT(1, 25);
    else PTA_BASE_PTR->PSOR = LSHIFT(1, 25);
    break;
  case 3:
    if ( (state & BIT(0)) != 0 ) PTA_BASE_PTR->PCOR = LSHIFT(1, 26);
    else PTA_BASE_PTR->PSOR = LSHIFT(1, 26);
    break;
  }
}

/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
int Led_state(int led_num)
{
  switch (led_num)
  {
  case 1:
    return (PTA_BASE_PTR->PDOR>>24)&1;
    break;
  case 2:
    return (PTA_BASE_PTR->PDOR>>25)&1;
    break;
  case 3:
    return (PTA_BASE_PTR->PDOR>>26)&1;
    break;
  }
  return 0;
}
/*-------------------------------------------------------------------------------------------------------------
  Active LOW Reset Signal
-------------------------------------------------------------------------------------------------------------*/
void LCD_RST(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 11);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 11);
}

/*-------------------------------------------------------------------------------------------------------------
  Serial clock
-------------------------------------------------------------------------------------------------------------*/
void LCD_SCL(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 12);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 12);
}
/*-------------------------------------------------------------------------------------------------------------
  Input data
-------------------------------------------------------------------------------------------------------------*/
void LCD_SI(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 13);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 13);
}
/*-------------------------------------------------------------------------------------------------------------
  Register Select Signal. RS=0: instruction; RS=1: data
-------------------------------------------------------------------------------------------------------------*/
void LCD_RS(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 14);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 14);
}
/*-------------------------------------------------------------------------------------------------------------
  Active LOW Chip Select signal
-------------------------------------------------------------------------------------------------------------*/
void LCD_SCB(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 15);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 15);
}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enleave.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enleave.c$
* $Version : 3.5.7.0$
* $Date    : Nov-24-2009$
*
* Comments:
*
*   This file contains the Ethernet multicasting
*   interface functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

#if BSPCFG_ENABLE_ENET_MULTICAST

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_leave
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Leaves a multicast group on an Ethernet channel.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_leave
   (
      /* [IN] the Ethernet state structure */
      _enet_handle      handle,

      /* [IN] the protocol */
      uint_16           type,

      /* [IN] the multicast group */
      _enet_address     address
   )
{ 
   ENET_CONTEXT_STRUCT_PTR  enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;
   ENET_ECB_STRUCT_PTR  ecb_ptr;
   ENET_MCB_STRUCT_PTR  mcb_ptr, _PTR_ search_ptr;
   #ifdef ENET_ALLMCAST
      boolean  needrejoin;
   #endif

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself and with ENET_Join.
   */
   ENET_lock_context(enet_ptr);

   // Make sure it's an open protocol
   for (ecb_ptr = enet_ptr->ECB_HEAD;ecb_ptr;ecb_ptr = ecb_ptr->NEXT) {
      if (ecb_ptr->TYPE == type) {
         /* Found an existing entry */
         break;
      } 
   } 

   // No existing entry found
   if (!ecb_ptr) {
      ENET_unlock_context(enet_ptr);
      return ENETERR_CLOSE_PROT;
   } 

   // Make sure it's a joined group
   for (search_ptr = &ecb_ptr->MCB_HEAD;
       *search_ptr;
        search_ptr = &(*search_ptr)->NEXT) {

      if (((*search_ptr)->GROUP[0] == address[0])
       && ((*search_ptr)->GROUP[1] == address[1])
       && ((*search_ptr)->GROUP[2] == address[2])
       && ((*search_ptr)->GROUP[3] == address[3])
       && ((*search_ptr)->GROUP[4] == address[4])
       && ((*search_ptr)->GROUP[5] == address[5])) {
         /* Found the entry -- delete it */
         break;
      } 
   } 

   if (!*search_ptr) {
      ENET_unlock_context(enet_ptr);
      return ENETERR_LEAVE_GROUP;
   } 

   mcb_ptr = *search_ptr;
   *search_ptr = mcb_ptr->NEXT;

   #ifdef ENET_ALLMCAST
      enet_ptr->MCOUNT--;
      needrejoin = enet_ptr->MCOUNT < ENET_ALLMCAST;

      if (needrejoin) {
   #endif
         (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->REJOIN)(handle);
   #ifdef ENET_ALLMCAST
      } 
   #endif

   ENET_unlock_context(enet_ptr);

   _mem_free(mcb_ptr);

   return ENET_OK;
} 

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_load.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_load.c$
* $Version : 3.7.6.0$
* $Date    : Feb-24-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h"


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_load
*  Returned Value:  none
*  Comments  :  SHELL utility to load an executable file
*
*END*-----------------------------------------------------------------*/

int_32  Shell_load(int_32 argc, char_ptr argv[] )
{ /* Body */
   _ip_address          hostaddr;
   char                 hostname[MAX_HOSTNAMESIZE];
   char_ptr             host_ptr, file_ptr, format_ptr;

   boolean              print_usage, shorthelp = FALSE;
   int_32               error = 0, return_code = SHELL_EXIT_SUCCESS;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc > 4 )  {
         printf("Error, %s invoked with incorrect number of arguments\n", argv[0]);
         print_usage = TRUE;
         return_code = SHELL_EXIT_ERROR;
      } else  {
         if (argc > 1)  {
            file_ptr = argv[1];
            if (argc > 2)  {
               host_ptr = argv[2];
               if (argc>3)  {
                  format_ptr = argv[3];
               } else  {
                  format_ptr = "srec";
               }
            } else  {
               printf("Error, no TFTP Server specified.\n");
               print_usage = TRUE;
               return_code = SHELL_EXIT_ERROR;
            }
         } else  {
            printf("Error, no bootfile specified.\n");
            print_usage = TRUE;
            return_code = SHELL_EXIT_ERROR;
         }
      }
      
      
      if (return_code != SHELL_EXIT_ERROR)  {
         RTCS_resolve_ip_address( host_ptr, &hostaddr, hostname, MAX_HOSTNAMESIZE ); 

         if (hostaddr)  {
            printf("Loading %s from %s [%ld.%ld.%ld.%ld]:\n", file_ptr, hostname, IPBYTES(hostaddr));
            if (strcmp(format_ptr, "srec") == 0)  {
               error = RTCS_load_TFTP_SREC(hostaddr, file_ptr);
            } else if (strcmp(format_ptr, "coff") == 0)  {
               error = RTCS_load_TFTP_BIN(hostaddr, file_ptr, NULL);
            } else {
               printf("Error, invalid format %s\n", format_ptr);
               print_usage = TRUE;
               return_code = SHELL_EXIT_ERROR;
            }
            if (error)  {
               printf("RTCS_load_TFTP_%s returned with error code = %x\n",format_ptr, error);
               return_code = SHELL_EXIT_ERROR;
            }
         } else  {
            printf("Unable to resolve host\n");
            return_code = SHELL_EXIT_ERROR;
         }
      }         
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <file> <host> <format>\n", argv[0]);
      } else  {
         printf("Usage: %s <file> <host> <format>\n", argv[0]);
         printf("   <file>   = filename\n");
         printf("   <host>   = TFTP Server ip address or name\n");
         printf("   <format> = file format, one of coff or srec\n");
      }
   }
   return return_code;
} /* Endbody */

#endif /* SHELLCFG_USES_RTCS */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_tiol.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_tiol.c$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*   This file contains the functions for converting from time to ticks.
*
*END************************************************************************/

#include "mqx_inc.h"

/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_time_to_ticks
* Returned Value   : void
* Comments         :
*    This function converts the time struct format into ticks
*
*END*----------------------------------------------------------------------*/

void _psp_time_to_ticks
   (
      TIME_STRUCT_PTR     time_ptr,
      PSP_TICK_STRUCT_PTR tick_ptr
   )
{ /* Body */
   PSP_TICK_STRUCT tick1;
   PSP_TICK_STRUCT tick2;

   _psp_seconds_to_ticks(time_ptr->SECONDS, &tick1);
   _psp_msecs_to_ticks(time_ptr->MILLISECONDS, &tick2);

   _psp_add_ticks(&tick1, &tick2, tick_ptr);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enopen.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enopen.c$
* $Version : 3.8.11.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   This file contains the Ethernet open interface function.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_open
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Registers a protocol type on an Ethernet channel.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_open
   (
      /* [IN] the Ethernet state structure */
      _enet_handle      handle,

      /* [IN] the protocol */
      uint_16           type,

      /* [IN] the callback function */
      void (_CODE_PTR_  service)(PCB_PTR, pointer),

      /* [IN] private data for the callback */
      pointer           prv
   )
{ 
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;
   ENET_ECB_STRUCT_PTR     ecb_ptr, _PTR_ search_ptr;

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself, ENET_close(), and ENET_ISR().
   */
   ENET_lock_context(enet_ptr);

   // Search for an existing entry for type
   for (search_ptr = (ENET_ECB_STRUCT_PTR _PTR_)&enet_ptr->ECB_HEAD; *search_ptr; search_ptr = &(*search_ptr)->NEXT) {
      if ((*search_ptr)->TYPE == type) {
         /* Found an existing entry */
         ENET_unlock_context(enet_ptr);
         return ENETERR_OPEN_PROT;
      } 
   } 

   // No existing entry found -- create a new one
   ecb_ptr = (ENET_ECB_STRUCT_PTR)_mem_alloc_system_zero(sizeof(ENET_ECB_STRUCT));
   if (!ecb_ptr) {
      ENET_unlock_context(enet_ptr);
      return ENETERR_ALLOC_ECB;
   } 
   _mem_set_type(ecb_ptr, MEM_TYPE_IO_ENET_ECB);
   
   ecb_ptr->TYPE     = type;
   ecb_ptr->SERVICE  = service;
   ecb_ptr->MCB_HEAD = NULL;
   ecb_ptr->PRIVATE  = prv;
   ecb_ptr->NEXT     = NULL;
   *search_ptr       = ecb_ptr;

   ENET_unlock_context(enet_ptr);
   return ENET_OK;

}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/tchres/tchres_prv.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tchres_prv.h$
* $Version : 3.8.7.0$
* $Date    : Sep-22-2011$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the SPI driver
*
*END************************************************************************/
#ifndef __tchres_prv_h__
#define __tchres_prv_h__

#ifdef __cplusplus
extern "C" {
#endif

#if 0
/* for later use */
typedef struct tchres_calib_struct
{
  uint_16   X_RESOLUTION;
  uint_16   Y_RESOLUTION;
  int_16    K_X;
  int_16    Q_X;
  int_16    K_Y;
  int_16    Q_Y;
} TCHRES_CALIB_STRUCT, _PTR_ TCHRES_CALIB_STRUCT_PTR ;
#endif

typedef struct tchres_struct
{
    /* pin information */
    LWGPIO_STRUCT X_PLUS_PIN;
    LWGPIO_STRUCT Y_PLUS_PIN;
    LWGPIO_STRUCT X_MINUS_PIN;
    LWGPIO_STRUCT Y_MINUS_PIN;

    /* every pin can have another mux mask */
    TCHRES_PIN_FUNCT_STRUCT PIN_FUNCT;

   /* adc limits structure */
   TCHRES_ADC_LIMITS_STRUCT   ADC_LIMITS;
   /* open file counter */
   uchar    COUNT;

   /* ADC device info */
   char_ptr   ADC_XPLUS_DEVICE;
   char_ptr   ADC_YPLUS_DEVICE;
   MQX_FILE_PTR   ADC_CHANNEL_X;
   MQX_FILE_PTR   ADC_CHANNEL_Y;
   ADC_INIT_CHANNEL_STRUCT_PTR   ADC_CHANNEL_X_STRUCT;
   ADC_INIT_CHANNEL_STRUCT_PTR   ADC_CHANNEL_Y_STRUCT;
   LWEVENT_STRUCT TCH_EVENT;

#if 0
    /* callibration data */
    uchar    NUMBER_OF_CALIB_POINTS;
    /* pointer to TCHRES_CALLIBRATION_STRUCT array */
   TCHRES_CALLIBRATION_STRUCT_PTR  CALLIB_POINTS_STRUCT_PTR;
   /* calibration data */
   TCHRES_CALIB_METHOD CALIBRATION_METHOD;
   TCHRES_CALIB_STRUCT        CALIB_DATA;
#endif

} TCHRES_DEVICE_STRUCT, _PTR_ TCHRES_DEVICE_STRUCT_PTR;

typedef enum
{
   X_PLUS,
   X_MINUS,
   Y_PLUS,
   Y_MINUS
} TCHRES_PIN_SELECT_ENUM, _PTR_ TCHRES_PIN_SELECT_ENUM_PTR ;

typedef enum
{
    FULL_SCALE,
    X_TOUCH_MIN,
    Y_TOUCH_MIN,
    X_TOUCH_MAX,
    Y_TOUCH_MAX
} TCHRES_LIMITS_ENUM, _PTR_ TCHRES_LIMITS_ENUM_PTR;

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/os/mqx25x/rtcsdate.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcsdate.c$
* $Version : 3.6.3.0$
* $Date    : Aug-27-2010$
*
* Comments:
*
*   This file contains the interface to the RTOS
*   date services.
*
*END************************************************************************/

#include <rtcsrtos.h>


/* Factor to convert milliseconds into fraction of a second */
#define SECOND_FRACTION_TO_MILLISECONDS     (0xFFFFFFFF / 1000)

/*
** Time, in secondes, between Jan 1 0h 1900, and Jan 1 0h 1970:
**
** 17 leap years: 17 days + 365 days * 70 years = 25567 days
** 25567 days * 24 hours/day * 60 minutes/hour * 60 seconds/minute
** = 2208988800 seconds
*/
#define SECONDS_1900_1970  2208988800u


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : RTCS_date_get
* Returned Value   : void
* Comments  :  Gets the current date in seconds and fraction of seconds
*     since 0h Jan 1 1900
*
*END*-----------------------------------------------------------------*/

void RTCS_date_get
   (
      uint_32 _PTR_ seconds,
      /* [OUT] Elapsed seconds since 0h Jan 1 1900 */
      uint_32 _PTR_ fraction
      /* [OUT] Second fraction in 2^-32 second units */
   )
{ /* Body */
   TIME_STRUCT time;

   _time_get(&time);
   *seconds = time.SECONDS + SECONDS_1900_1970;
   *fraction = time.MILLISECONDS * SECOND_FRACTION_TO_MILLISECONDS;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : RTCS_date_set
* Returned Value   : void
* Comments  :  Sets the current date in seconds and fraction of seconds
*     since 0h Jan 1 1900
*
*END*-----------------------------------------------------------------*/

void RTCS_date_set
   (
      uint_32  seconds,
      /* [IN] Elapsed seconds since 0h Jan 1 1900 */
      uint_32  fraction
      /* [IN] Fraction of a second in 2^-32 second units */
   )
{ /* Body */
   TIME_STRUCT time;

   time.SECONDS = seconds - SECONDS_1900_1970;
   time.MILLISECONDS = fraction / SECOND_FRACTION_TO_MILLISECONDS;
   _time_set(&time);
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/media/ip6-e.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip6-e.c$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the interface between IPv6 and
*   the Ethernet packet driver.
*
*END************************************************************************/

#include <string.h>
#include <rtcs.h>

#if RTCSCFG_ENABLE_IP6

#include <ethernet.h>
#include <enet.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "arp.h"
#include "ip-e.h"
#include "ip6_trace.h"

/************************************************************************
 * Ethernet Multicast Address, for IPv6.
 ***********************************************************************/
#define IP6E_ADDR_MC(eth_addr,ip6)              \
            (eth_addr)[0] = 0x33,               \
            (eth_addr)[1] = 0x33,               \
            (eth_addr)[2] = ip6->s6_addr[12],   \
            (eth_addr)[3] = ip6->s6_addr[13],   \
            (eth_addr)[4] = ip6->s6_addr[14],   \
            (eth_addr)[5] = ip6->s6_addr[15]

/************************************************************************
* NAME: IP6E_open
*
* DESCRIPTION: Registers IPv6 with an Ethernet packet driver, 
*              Generates & Assign Link-local Address.
*************************************************************************/
uint_32 IP6E_open (IP_IF_PTR if_ptr )
{
    uint_32  error;

    /* Register IP6.
     */
    error = ENET_open(if_ptr->HANDLE, ENETPROT_IP6, IP6E_recv_IP, if_ptr);
    if (error) 
    {
        goto OPEN_FAILED_1;
    } 
    
  
    /* Init Neighbor Discovery.*/
    error = nd6_open(if_ptr);
    if (error) 
    {
        goto OPEN_FAILED_2;
    }
    
    /* Add to IF list.*/ //TBD make it common for all interfaces.
    ip6_if_add(if_ptr);

    /* RFC4861 6.3.3: The host joins the all-nodes multicast address on all 
     * multicastcapable interfaces.
     */
    ip6_if_join (if_ptr, &in6addr_linklocal_allnodes);

    /* To speed the autoconfiguration process, a host may generate its linklocal
     * address (and verify its uniqueness) in parallel with waiting
     * for a Router Advertisement. Because a router may delay responding to
     * a Router Solicitation for a few seconds, the total time needed to
     * complete autoconfiguration can be significantly longer if the two
     * steps are done serially.
     */


    /* Link-Local Address Generation/Auto configuration.
     * It comprises of '1111111010' as the first ten bits followed by 54 zeroes 
     * and a 64 bit interface identifier.
     * For all autoconfiguration types, a link-local address is always configured. 
     */
    ip6_if_bind_addr (if_ptr, (in6_addr *)&in6addr_any, IP6_ADDR_TYPE_AUTOCONFIGURABLE, IP6_IF_ADDRESS_LIFETIME_INFINITE, ND6_PREFIX_LENGTH_DEFAULT);     

    /* RFC4862: The next phase of autoconfiguration involves obtaining a Router
     * Advertisement or determining that no routers are present.  If routers
     * are present, they will send Router Advertisements that specify what
     * sort of autoconfiguration a host can do.
     * To obtain an advertisement quickly, a host sends one or more Router
     * Solicitations to the all-routers multicast group.
     */ 
    nd6_rd_start(if_ptr);
    
    return RTCS_OK;
    
    /* Error handler.
     */
OPEN_FAILED_2:
    ENET_close(if_ptr->HANDLE, ENETPROT_IP6);  
OPEN_FAILED_1:
    return error;
}

/************************************************************************
* NAME: IP6E_close
*
* DESCRIPTION: Deregisters IPv6 from an Ethernet packet driver, 
*              etc.
*************************************************************************/
uint_32 IP6E_close (IP_IF_PTR if_ptr )
{
    uint_32 error;
    int     i;

    /* Delete from IF list.*/ //TBD make it common for all interfaces.
    ip6_if_del(if_ptr);
    
    /* Relaese ND for this interface.
     */
    nd6_close(if_ptr);    
    
    /* Unbind all addresses. 
     */
    for(i = 0; i < IP6_IF_ADDRESSES_MAX; i++)
    {
        ip6_if_unbind_addr (if_ptr, &if_ptr->IP6_IF.address[i]); 
    }
    
    /* Leaves the all-nodes multicast address.
     */
    ip6_if_leave (if_ptr, &in6addr_linklocal_allnodes);
      
    /* Deregister IP6.
     */
    error = ENET_close(if_ptr->HANDLE, ENETPROT_IP6);
     
    return error;
}

/************************************************************************
* NAME: IP6E_recv_IP
* RETURNS : RTCS_OK or error code
* DESCRIPTION: Services an IPv6 packet.
*************************************************************************/
void IP6E_recv_IP ( PCB_PTR  pcb    /* [IN] the received packet */,
                    pointer  handle /* [IN] the IP interface structure */)
{ 
   RTCSLOG_FNE3(RTCSLOG_FN_IP6E_recv_IP, pcb, handle);
   IPE_recv(pcb, handle, IP6_service);
   RTCSLOG_FNX1(RTCSLOG_FN_IP6E_recv_IP);
}

/************************************************************************
* NAME: IP6E_join
* RETURNS : RTCS_OK or error code
* DESCRIPTION: Joins an IPv6 multicast group..
*************************************************************************/
uint_32 IP6E_join ( IP_IF_PTR if_ptr        /* [IN] the IP interface structure */,
                    const in6_addr *group   /* [IN] the multicast group */)
{
   uchar    enetgroup[6];

   IP6E_ADDR_MC(enetgroup, group);
   return ENET_join(if_ptr->HANDLE, ENETPROT_IP6, enetgroup);
}

/************************************************************************
* NAME: IP6E_leave
* RETURNS : RTCS_OK or error code
* DESCRIPTION: Leaves an IPv6 multicast group.
*************************************************************************/
uint_32 IP6E_leave( IP_IF_PTR if_ptr        /* [IN] the IP interface structure */, 
                    const in6_addr *group   /* [IN] the multicast group */)
{
   uchar    enetgroup[6];

   IP6E_ADDR_MC(enetgroup, group);
   return ENET_leave(if_ptr->HANDLE, ENETPROT_IP6, enetgroup);
}

/************************************************************************
* NAME: IP6E_send
* RETURNS : RTCS_OK or error code.
* DESCRIPTION: Sends an IPv6 packet.
*************************************************************************/
uint_32 IP6E_send( IP_IF_PTR if_ptr     /* [IN] the IP interface structure */,
                   RTCSPCB_PTR rtcs_pcb /* [IN] the packet to send */,
                   in6_addr *src        /* [IN] the next-hop source address */,
                   in6_addr *dest       /* [IN] the next-hop destination address */)
{ 
    uchar       enetdest[6];
    uint_32     error;
    uchar       *enetdest_ptr;
   

    IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_TOTAL++);
    
    /********************************************
     * Multicast.
     ********************************************/
    if (IN6_IS_ADDR_MULTICAST(dest))  
    {
        IP6E_ADDR_MC(enetdest, dest);
        
        enetdest_ptr = (uchar *)enetdest;
        
        IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_MULTICAST++);
    } 
    /********************************************
     * Unicast.
     ********************************************/
    else 
    {
        ND6_NEIGHBOR_ENTRY_PTR neighbor;
        
        /* Possible redirection.*/
        nd6_redirect_addr(if_ptr, &dest);

        /* Check Neigbor cache.*/
        neighbor = nd6_neighbor_cache_get(if_ptr, dest);
           
        /* RFC4861 7.2.2: When a node has a unicast packet to send to a neighbor, but does not
         * know the neighbor’s link-layer address, it performs address resolution.
         * For multicast-capable interfaces, this entails creating a 
         * Neighbor Cache entry in the INCOMPLETE state and transmitting a
         * Neighbor Solicitation message targeted at the neighbor. The
         * solicitation is sent to the solicited-node multicast address
         * corresponding to the target address.
         */
        if(neighbor == NULL)
        {
            /* RFC4861 7.2.Address resolution is performed only on addresses that are determined to be
             * on-link and for which the sender does not know the corresponding link-layer address.
             * Address resolution is never performed on multicast addresses.*/
             
            if(nd6_addr_is_onlink(if_ptr, dest) == TRUE)
            /* Destimnation is ON local-link.*/
            {
                /* Creating a Neighbor Cache entry in the INCOMPLETE state. */
                neighbor =  nd6_neighbor_cache_add(if_ptr, dest, NULL, ND6_NEIGHBOR_STATE_INCOMPLETE);
                
                neighbor->state_time = RTCS_time_get();
                neighbor->solicitation_send_counter = 0;
                IN6_ADDR_COPY(src, &neighbor->solicitation_src_ip_addr); /* Save src address for later usage.*/
                
                /* AR: Transmitting a Neighbor Solicitation message targeted at the neighbor.*/
                nd6_neighbor_solicitation_send(if_ptr, src, NULL /* NULL for AR */, dest);
            }
            /* Destination is OFF local-link.*/
            else
            {
                /* Try to use the router, if exists.*/
                neighbor = nd6_default_router_get(if_ptr);

                if(neighbor == NULL)
                /* No Router exists.*/
                {
                #if RTCSCFG_DEBUG_MSG
                    printf("ETH6:Nor Router - DROP\n");
                #endif    
                    
                    IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_DISCARDED++);
                    RTCSPCB_free(rtcs_pcb);
                    return RTCSERR_IP_UNREACH;   
                }

                dest = &neighbor->ip_addr;   /* Chage destination address to the router one */                
            }
        }

        /* Link -layer address is not initialized.*/
        if((neighbor->state != ND6_NEIGHBOR_STATE_INCOMPLETE) 
            && (neighbor->ll_addr[0]==0) && (neighbor->ll_addr[1]==0) && (neighbor->ll_addr[2]==0)
            && (neighbor->ll_addr[3]==0) && (neighbor->ll_addr[4]==0) && (neighbor->ll_addr[5]==0) )
        {
            neighbor->state = ND6_NEIGHBOR_STATE_INCOMPLETE;
            neighbor->state_time = RTCS_time_get();
            neighbor->solicitation_send_counter = 0;
            IN6_ADDR_COPY(src, &neighbor->solicitation_src_ip_addr); /* Save src address for later usage.*/
            /* AR: Transmitting a Neighbor Solicitation message targeted at the neighbor.*/
            nd6_neighbor_solicitation_send(if_ptr, src, NULL /* NULL for AR */, dest);
        }
        
        if(neighbor->state == ND6_NEIGHBOR_STATE_INCOMPLETE)
        /* Queue packet for later transmit.
         */
        {
            nd6_neighbor_enqueue_waiting_pcb(neighbor, rtcs_pcb);
            
            return RTCS_OK;
        }
        
        if(neighbor->state == ND6_NEIGHBOR_STATE_STALE)
        /* RFC4861 7.3.3: The first time a node sends a packet to a neighbor whose entry is
         * STALE, the sender changes the state to DELAY and sets a timer to
         * expire in DELAY_FIRST_PROBE_TIME seconds.
         */
        {
            neighbor->state = ND6_NEIGHBOR_STATE_DELAY;
            neighbor->state_time = RTCS_time_get();
        }
        
        /* Get destination MAC/HW address.*/
        enetdest_ptr = (uchar *)neighbor->ll_addr;
        
        IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_UNICAST++);
    }
    
    /* Send message via Ethernet.
     */
    error = IPE_send(if_ptr, rtcs_pcb, ENETPROT_IP6, enetdest_ptr);
    RTCSLOG_FNX2(RTCSLOG_FN_IPE_send_IP, error);
 
    return error;
}

#endif /* RTCSCFG_ENABLE_IP6 */




<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/ipc_pcb.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipc_pcb.h$
* $Version : 3.0.4.0$
* $Date    : Oct-5-2011$
*
* Comments:
*
*   This file contains the definitions for the 
*   interprocessor drivers that work over IO PCB devices.
*
*END************************************************************************/
#ifndef __ipc_pcb_h__
#define __ipc_pcb_h__ 1

/*--------------------------------------------------------------------------*/
/*
 *                          CONSTANT DECLARATIONS
 */

/*
 * Initialization errors
 */
#define IPC_PCB_PACKET_POOL_CREATE_FAILED     (IPC_PCB_ERROR_BASE|0x31)
#define IPC_PCB_INVALID_QUEUE                 (IPC_PCB_ERROR_BASE|0x32)
#define IPC_PCB_DEVICE_OPEN_FAILED            (IPC_PCB_ERROR_BASE|0x33)
#define IPC_PCB_OUTPUT_PCB_POOL_CREATE_FAILED (IPC_PCB_ERROR_BASE|0x34)
#define IPC_PCB_INPUT_PCB_POOL_CREATE_FAILED  (IPC_PCB_ERROR_BASE|0x35)

/*--------------------------------------------------------------------------*/
/*
 *                    TYPEDEFS FOR _CODE_PTR_ FUNCTIONS
 */
typedef _mqx_uint (_CODE_PTR_ IPC_PCB_DEVINSTALL_FPTR)( char_ptr, pointer);
  

/*--------------------------------------------------------------------------*/
/*
 *                          DATATYPE DECLARATIONS
 */

/* IPC_PCB_INIT_STRUCT */
/*! 
 * \brief Initialization structure for IPCs over PCB devices.
 *
 * \see _ipc_pcb_init
 */
typedef struct ipc_pcb_init_struct
{
   /*! \brief The String name of the PCB device driver to be opened by the IPC. */
   char _PTR_            IO_PCB_DEVICE_NAME;

   /*!
    * \brief The function to call to install the IO Device (optional). If null, 
    * the device is not installed.
    */
   IPC_PCB_DEVINSTALL_FPTR DEVICE_INSTALL;

   /*! \brief The parameter to pass to the IO Device installation function. */
   pointer               DEVICE_INSTALL_PARAMETER;
   
   /*! \brief Maximum size of all messages arriving at the IPC. */
   uint_16               IN_MESSAGES_MAX_SIZE;
   /*! \brief Initial number of input messages to allocate. */
   uint_16               IN_MESSAGES_TO_ALLOCATE;
   /*! 
    * \brief Number of input messages to add to the pool when messages are all 
    * in use. 
    */
   uint_16               IN_MESSAGES_TO_GROW;
   /*! \brief Maximum number of messages in the input message pool. */
   uint_16               IN_MESSAGES_MAX_ALLOCATE;

   /*! \brief Initial number of PCBs in the output PCB pool. */
   uint_16               OUT_PCBS_INITIAL;
   /*! 
    * \brief Number of PCBs to add to the output PCB pool when all the PCBs are 
    * in use.
    */
   uint_16               OUT_PCBS_TO_GROW;
   /*! \brief Maximum number of PCBs in the output PCB pool. */
   uint_16               OUT_PCBS_MAX;

} IPC_PCB_INIT_STRUCT, _PTR_ IPC_PCB_INIT_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
 *                          C PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _ipc_pcb_init(const IPC_PROTOCOL_INIT_STRUCT *, pointer);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5xxx_fec_mii.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5xxx_fec_mii.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the MCF5xxx Ethernet MII Interface functions
*   functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "mcf5xxx_fec_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_mii_enabled
*  Returned Value : boolean
*  Comments       :
*    We can only read the PHY registers if the PHY is enabled
*
*END*-----------------------------------------------------------------*/

static boolean MCF5XXX_FEC_mii_enabled
   (
      VMCF5XXX_FEC_STRUCT_PTR fec_ptr
   )
{  
   return (fec_ptr->MSCR & 0x7E) != 0;
} 

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_read_write_mii
*  Returned Value : TRUE and MII Data register value, FALSE if timeout
*  Comments       :
*    Return entire MII data register value
*
*END*-----------------------------------------------------------------*/

static boolean MCF5XXX_FEC_read_write_mii
   (
      VMCF5XXX_FEC_STRUCT_PTR    fec_ptr,
      uchar                      phy_addr,
      uint_32                    reg_index,
      uint_32                    op,
      uint_32                    write_data,
      uint_32_ptr                read_data_ptr,
      uint_32                    timeout
   )
{
   uint_32                    tm;
    
   if (fec_ptr == NULL) 
      return FALSE;
   
   if (!MCF5XXX_FEC_mii_enabled(fec_ptr))
        return FALSE;
    
   // Clear the MII interrupt bit 
   fec_ptr->EIR = MCF5XXX_FEC_EIR_MII;

   // Kick-off the MII read or write operation 
   fec_ptr->MMFR = (vuint_32)(0 
      | MCF5XXX_FEC_MII_START_OF_FRAME
      | op
      | MCF5XXX_FEC_MII_PA(phy_addr)
      | MCF5XXX_FEC_MII_RA(reg_index)
      | MCF5XXX_FEC_MII_TURNAROUND
      | (write_data & 0xffff));

    // Poll for MII complete
   for (tm = 0; tm < timeout; tm++)
   {
      if(fec_ptr->EIR & MCF5XXX_FEC_EIR_MII)
         break;
      _time_delay(0);
   }

   if (tm != timeout) 
      if (read_data_ptr) 
         *read_data_ptr = MCF5XXX_FEC_MII_DATA(fec_ptr->MMFR);

   // Clear the MII interrupt bit 
   fec_ptr->EIR = MCF5XXX_FEC_EIR_MII;

   return (tm != timeout);
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_read_mii
*  Returned Value : TRUE and MII Data register value, FALSE if timeout
*  Comments       :
*    Return entire MII data register value
*
*END*-----------------------------------------------------------------*/

boolean MCF5XXX_FEC_read_mii
    (
        ENET_CONTEXT_STRUCT_PTR enet_ptr,
        uint_32 reg_index,
        uint_32_ptr data,
        uint_32 timeout
    )
{
    MCF5XXX_FEC_CONTEXT_STRUCT_PTR fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR)enet_ptr->MAC_CONTEXT_PTR;

    return MCF5XXX_FEC_read_write_mii(fec_context_ptr->PHY_PTR, enet_ptr->PHY_ADDRESS, reg_index, MCF5XXX_FEC_MII_OPCODE_READ, 0, data, timeout);
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_write_mii
*  Returned Value : TRUE if success, FALSE if timeout
*  Comments       :
*    Write MII data register value
*
*END*-----------------------------------------------------------------*/

boolean MCF5XXX_FEC_write_mii
    (
        ENET_CONTEXT_STRUCT_PTR enet_ptr,
        uint_32 reg_index,
        uint_32 data,
        uint_32 timeout
    )
{
    MCF5XXX_FEC_CONTEXT_STRUCT_PTR fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR)enet_ptr->MAC_CONTEXT_PTR;

    return MCF5XXX_FEC_read_write_mii(fec_context_ptr->PHY_PTR, enet_ptr->PHY_ADDRESS, reg_index, MCF5XXX_FEC_MII_OPCODE_WRITE, data, NULL, timeout);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hwtimer/hwtimer.c<|end_filename|>
/*HEADER********************************************************************
 *
 * Copyright (c) 2013 Freescale Semiconductor;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: hwtimer.c$
 * $Version : 4.0.1$
 * $Date : Jan-18-2013$
 *
 * Comments:
 *
 *   This file contains functions of the hwtimer component.
 *
 *END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "hwtimer.h"

/*!
 * \brief Initializes caller allocated structure according to given parameters.
 *
 * The device interface pointer determines low layer driver to be used.
 * Device interface structure is exported by each low layer driver and is opaque to the applications.
 * Please refer to chapter concerning low layer driver below for details.
 * Meaning of the numerical identifier varies depending on low layer driver used.
 * Typically, it identifies particular timer channel to initialize.
 * The initialization function has to be called prior using any other API function.
 *
 * \param hwtimer[out] Returns initialized hwtimer structure handle.
 * \param devif[in]    Structure determines low layer driver to be used.
 * \param id[in]       Numerical identifier of the timer.
 *
 * \return MQX_OK or an error code Returned from low level SET_DIV function.
 * \return MQX_INVALID_PARAMETER   When input parameter hwtimer or his device structure are NULL pointers. This value is also returned when the period parameter is 0.
 * \return MQX_INVALID_POINTER     When low level SET_DIV function point to NULL.
 *
 * \warning The initialization function has to be called prior using any other API function.
 *
 * \see hwtimer_deinit
 * \see hwtimer_start
 * \see hwtimer_stop
 */
_mqx_int hwtimer_init(HWTIMER_PTR hwtimer, const HWTIMER_DEVIF_STRUCT * devif, uint_32 id, uint_32 isr_prior)
 {
    #if MQX_CHECK_ERRORS
    if ((hwtimer == NULL) || (devif == NULL))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (devif->INIT == NULL)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    hwtimer->devif      = devif;
    hwtimer->ticks      = 0;
    hwtimer->divider    = 0;
    hwtimer->clock_id   = 0;
    hwtimer->modulo     = 0;
    hwtimer->callback_func = NULL;
    hwtimer->callback_data = NULL;
    hwtimer->callback_pending = 0;
    hwtimer->callback_blocked = 0;
    return hwtimer->devif->INIT(hwtimer, id, isr_prior);
 }

/*!
 * \brief De-initialization of hwtimer.
 *
 * Calls lower layer de-initialization function and afterwards invalidates hwtimer structure by clearing it.
 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 *
 * \return MQX_OK or an error code Returned from low level DEINIT function.
 * \return MQX_INVALID_PARAMETER   When input parameter hwtimer or his device structure are NULL pointers.
 * \return MQX_INVALID_POINTER     When low level DEINIT function point to NULL.
 *
 * \see hwtimer_init
 * \see hwtimer_start
 * \see hwtimer_stop
 */
_mqx_int hwtimer_deinit(HWTIMER_PTR hwtimer)
 {
    #if MQX_CHECK_ERRORS
    if ((NULL == hwtimer) || (NULL == hwtimer->devif))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (NULL == hwtimer->devif->DEINIT)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    hwtimer->devif->DEINIT(hwtimer);

    hwtimer->devif      = NULL;
    hwtimer->ticks      = 0;
    hwtimer->clock_id   = 0;
    hwtimer->divider    = 0;
    hwtimer->modulo     = 0;
    hwtimer->callback_func = NULL;
    hwtimer->callback_data = NULL;
    hwtimer->callback_pending = 0;
    hwtimer->callback_blocked = 0;

    return MQX_OK;
 }

/*!
 * \brief The function configures timer to tick at frequency as close as possible to the requested one.
 *
 * Actual accuracy depends on the timer module.
 * The function gets the value of the base frequency of the timer via clock manager, calculates required divider ratio and calls low layer driver to setup the timer accordingly.
 * Call to this function might be expensive as it may require complex calculation to choose the best configuration of dividers. The actual complexity depends on timer module implementation.
 * If there is only single divider or counter preload value (typical case) then there is no significant overhead.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 * \param clock_id[in]  Clock identifier used for obtaining timer's source clock.
 * \param freq[in]      Required frequency of timer in Hz.
 *
 * \return MQX_OK or an error code Returned from low level SETDIV function.
 * \return MQX_INVALID_PARAMETER   When input parameter hwtimer or his device structure are NULL pointers.
 * \return MQX_INVALID_POINTER     When low level SETDIV function point to NULL.
 *
 * \see hwtimer_get_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
_mqx_int hwtimer_set_freq(HWTIMER_PTR hwtimer, uint_32 clock_id, uint_32 freq)
{
    uint_32 clock_freq;
    uint_32 divider;
    #if MQX_CHECK_ERRORS
    if ((NULL == hwtimer) || (NULL == hwtimer->devif) || (0 == freq))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (NULL == hwtimer->devif->SET_DIV)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    /* Store clock_id in struct*/
    hwtimer->clock_id = clock_id;
    /* Find out input frequency*/
    clock_freq = _bsp_get_clock(_bsp_get_clock_configuration(), (CM_CLOCK_SOURCE)clock_id);
    divider = clock_freq / freq;
    /* If Reqired frequency is higher than input clock frequency, we set divider 1 (for setting highest possible frequency)*/
    if (0 == divider)
    {
        divider = 1;
    }
    return hwtimer->devif->SET_DIV(hwtimer, divider);
}

/*!
 * \brief Set period of hwtimer.
 *
 * The function provides an alternate way to setup the timer to desired period specified in microseconds rather than to frequency in Hz.
 * The function gets the value of the base frequency of the timer via clock manager, calculates required divider ratio and calls low layer driver to setup the timer accordingly.
 * Call to this function might be expensive as it may require complex calculation to choose the best configuration of dividers.
 * The actual complexity depends on timer module implementation.
 * If there is only single divider or counter preload value (typical case) then there is no significant overhead.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 * \param clock_id[in]  Clock identifier used for obtaining timer's source clock.
 * \param period[in]    Required period of timer in micro seconds.
 *
 * \return MQX_OK or an error code Returned from low level SETDIV function.
 * \return MQX_INVALID_PARAMETER   When input parameter hwtimer or his device structure are NULL pointers.
 * \return MQX_INVALID_POINTER     When low level SETDIV function point to NULL.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_get_freq
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
_mqx_int hwtimer_set_period(HWTIMER_PTR hwtimer, uint_32 clock_id, uint_32 period)
{
    uint_32 clock_freq;
    uint_64 divider;
    #if MQX_CHECK_ERRORS
    if ((NULL == hwtimer) || (NULL == hwtimer->devif) || (0 == period))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (NULL == hwtimer->devif->SET_DIV)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    /* Store clock_id in struct*/
    hwtimer->clock_id = clock_id;
    /* Find out input frequency*/
    clock_freq = _bsp_get_clock(_bsp_get_clock_configuration(), (CM_CLOCK_SOURCE)clock_id);
    divider = (((uint_64)clock_freq * period)) / 1000000 ;
    /* If Reqired frequency is higher than input clock frequency, we set divider 1 (for setting highest possible frequency)*/
    if (0 == divider)
    {
        divider = 1;
    }
    /* if divider is greater than 32b value we set divider to max 32b value*/
    else if (divider & 0xFFFFFFFF00000000)
    {
        divider = 0xFFFFFFFF;
    }
    return hwtimer->devif->SET_DIV(hwtimer, (uint_32)divider);
}

/*!
 * \brief Get frequency of hwtimer.
 *
 * The function returns current frequency of the timer calculated from the base frequency and actual divider settings of the timer or zero in case of an error.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 *
 * \return frequency    Already set frequency of hwtimer
 * \return 0            When input parameter hwtimer is NULL pointer or his divider member is zero.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
uint_32 hwtimer_get_freq(HWTIMER_PTR hwtimer)
{
    uint_32 clock_freq;
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return 0;   //MQX_INVALID_PARAMETER;
    }
    /* Uninitialized hwtimer contains value of 0 for divider*/
    if (0 == hwtimer->divider)
    {
        return 0;   //MQX_INVALID_POINTER
    }
    #endif
    clock_freq = _bsp_get_clock(_bsp_get_clock_configuration(), (CM_CLOCK_SOURCE)hwtimer->clock_id);
    return clock_freq / hwtimer->divider;
}

/*!
 * \brief Get period of hwtimer.
 *
 * The function returns current period of the timer in microseconds calculated from the base frequency and actual divider settings of the timer.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 *
 * \return period       Already set period of hwtimer.
 * \return 0            Input parameter hwtimer is NULL pointer.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_get_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
uint_32 hwtimer_get_period(HWTIMER_PTR hwtimer)
{
    uint_32 clock_freq;
    uint_32 period;
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return 0;   //MQX_INVALID_PARAMETER;
    }
    #endif
    clock_freq = _bsp_get_clock(_bsp_get_clock_configuration(), (CM_CLOCK_SOURCE)hwtimer->clock_id);
    /* The result is always less than UINT32_MAX */
    period = ((uint_64)1000000 * hwtimer->divider) / clock_freq;
    return period;
}

/*!
 * \brief Enables the timer and leaves it running.
 *
 * The timer starts counting a new period generating interrupts every time the timer rolls over.
 *
 * \param hwtimer[in] Returns initialized hwtimer structure handle.
 *
 * \return MQX_OK or an error code Returned from low level START function.
 * \return MQX_INVALID_PARAMETER   When input parameter hwtimer or his device structure are NULL pointers.
 * \return MQX_INVALID_POINTER     When low level START function point to NULL.
 *
 * \see hwtimer_init
 * \see hwtimer_deinit
 * \see hwtimer_stop
 */
_mqx_int hwtimer_start(HWTIMER_PTR hwtimer)
{
    #if MQX_CHECK_ERRORS
    if ((NULL == hwtimer) || (NULL == hwtimer->devif))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (NULL == hwtimer->devif->START)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    return hwtimer->devif->START(hwtimer);
}

/*!
 * \brief The timer stops counting after this function is called.
 *
 * Pending interrupts and callbacks are canceled.
 *
 * \param hwtimer[in] Returns initialized hwtimer structure handle.
 *
 * \return MQX_OK or an error code Returned from low level STOP function.
 * \return MQX_INVALID_PARAMETER   When input parameter hwtimer or his device structure are NULL pointers.
 * \return MQX_INVALID_POINTER     When low level STOP function point to NULL.
 *
 * \see hwtimer_init
 * \see hwtimer_deinit
 * \see hwtimer_start
 */
_mqx_int hwtimer_stop(HWTIMER_PTR hwtimer)
{
    _mqx_int result;
    #if MQX_CHECK_ERRORS
    if ((NULL == hwtimer) || (NULL == hwtimer->devif))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (NULL == hwtimer->devif->STOP)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    result = hwtimer->devif->STOP(hwtimer);
    hwtimer->callback_pending = 0;
    return result;
}

/*!
 * \brief The function returns period of the timer in sub-ticks.
 *
 * It is typically called after hwtimer_set_freq() or hwtimer_set_period() to obtain actual resolution of the timer in the current configuration.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 *
 * \return modulo       resolution of hwtimer.
 * \return 0            Input parameter hwtimer is NULL pointer.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_get_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_period
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
uint_32 hwtimer_get_modulo(HWTIMER_PTR hwtimer)
{
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return 0;   //MQX_INVALID_PARAMETER;
    }
    #endif
    return hwtimer->modulo;
}

/*!
 * \brief The function reads the current value of the hwtimer
 *
 * Elapsed periods(ticks) and current value of the timer counter (sub-ticks) are filled into the HWTIMER_TIME structure.
 * The sub-ticks number always counts up and is reset to zero when the timer overflows regardless of the counting direction of the underlying device.
 * The returned value corresponds with lower 32 bits of elapsed periods (ticks).
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 * \param time[out]     Pointer to time structure. This value is filled with current value of the timer.
 *
 * \return _OK or an error code     Returned from low level GET_TIME function.
 * \return MQX_INVALID_PARAMETER    When input parameter hwtimer, his device structure or input parameter time are NULL pointers.
 * \return MQX_INVALID_POINTER      When low level GET_TIME function point to NULL.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_get_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_ticks
 */
_mqx_int hwtimer_get_time(HWTIMER_PTR hwtimer, HWTIMER_TIME_PTR time)
{
    #if MQX_CHECK_ERRORS
    if ((NULL == hwtimer) || (NULL == hwtimer->devif) || (NULL == time))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (NULL == hwtimer->devif->GET_TIME)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    return hwtimer->devif->GET_TIME(hwtimer, time);
}

/*!
 * \brief The function reads the current value of the hwtimer
 *
 * The function returns lower 32 bits of elapsed periods (ticks).
 * The value is guaranteed to be obtained atomically without necessity to mask timer interrupt.
 * Lower layer driver is not involved at all, thus call to this function is considerably faster than hwtimer_get_time.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 *
 * \return Low 32 bits of 64 bit tick value.
 * \return 0  When input parameter is NULL pointer.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_get_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 */
uint_32 hwtimer_get_ticks(HWTIMER_PTR hwtimer)
{
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return 0;//MQX_INVALID_PARAMETER;
    }
    #endif
    /* return low 32b of 64 bit value */
    return (uint_32)hwtimer->ticks;
}

/*!
 * \brief Registers function to be called when the timer expires.
 *
 * The callback_data is arbitrary pointer passed as parameter to the callback function.
 *
 *
 * \param hwtimer[in]        Pointer to hwtimer structure.
 * \param callback_func [in] Function pointer to be called when the timer expires.
 * \param callback_data [in] Data pointer for the function callback_func.
 *
 * \return MQX_INVALID_PARAMETER When input parameter hwtimer is NULL pointer.
 * \return MQX_OK                When registration callback succeed.
 *
 * \warning This function must not be called from a callback routine.
 *
 * \see hwtimer_callback_block
 * \see hwtimer_callback_unblock
 * \see hwtimer_callback_cancel
 */
_mqx_int hwtimer_callback_reg(HWTIMER_PTR hwtimer, HWTIMER_CALLBACK_FPTR callback_func, pointer callback_data)
{
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return MQX_INVALID_PARAMETER;
    }
    #endif
    hwtimer->callback_func = NULL;
    hwtimer->callback_pending = 0;
    hwtimer->callback_data = callback_data;
    hwtimer->callback_func = callback_func;
    return MQX_OK;

}

/*!
 * \brief The function is used to block callbacks in circumstances when execution of the callback function is undesired.
 *
 * If the timer overflows when callbacks are blocked the callback becomes pending.
 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 *
 * \return MQX_INVALID_PARAMETER When input parameter hwtimer is NULL pointer.
 * \return MQX_OK                When callback block succeed.
 *
 * \warning This function must not be called from a callback routine.
 *
 * \see hwtimer_callback_reg
 * \see hwtimer_callback_unblock
 * \see hwtimer_callback_cancel
 */
_mqx_int hwtimer_callback_block(HWTIMER_PTR hwtimer)
{
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return MQX_INVALID_PARAMETER;
    }
    #endif
    hwtimer->callback_blocked = 1;
    return MQX_OK;
}

/*!
 * \brief The function is used to unblock previously blocked callbacks.
 *
 * If there is a callback pending, it gets immediately executed.
 * This function must not be called from a callback routine (it does not make sense to do so anyway as callback function never gets executed while callbacks are blocked).
 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 *
 * \return MQX_INVALID_PARAMETER When input parameter hwtimer is NULL pointer.
 * \return MQX_OK                When callback unblock succeed.
 *
 * \warning This function must not be called from a callback routine.
 *
 * \see hwtimer_callback_reg
 * \see hwtimer_callback_block
 * \see hwtimer_callback_cancel
 */
_mqx_int hwtimer_callback_unblock(HWTIMER_PTR hwtimer)
{
    HWTIMER_CALLBACK_FPTR callback_func;
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return MQX_INVALID_PARAMETER;
    }
    #endif
    /* Unblock callbacks in ISR. No more pending request could arrive after this. */
    hwtimer->callback_blocked = 0;
    /* Check for any previously set pending requests during blocked state */
    if (hwtimer->callback_pending)
    {
        callback_func = hwtimer->callback_func;
        if (NULL != callback_func)
        {
            /* Prevent invocation of callback from ISR (callback may not be reentrant) */
            hwtimer->callback_func = NULL;
            callback_func(hwtimer->callback_data);
            /* Allow invocation of callback from ISR */
            hwtimer->callback_func = callback_func;
        }
        /* Clear pending flag, callback just serviced */
        hwtimer->callback_pending = 0;
    }
    return MQX_OK;
}

/*!
 * \brief The function cancels pending callback, if any.
 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 *
 * \return MQX_INVALID_PARAMETER When input parameter hwtimer is NULL pointer.
 * \return MQX_OK                When callback cancel succeed.
 *
 * \warning This function must not be called from a callback routine (it does not make sense to do so anyway as callback function never gets executed while callbacks are blocked).
 *
 * \see hwtimer_callback_reg
 * \see hwtimer_callback_block
 * \see hwtimer_callback_unblock
 */
_mqx_int hwtimer_callback_cancel(HWTIMER_PTR hwtimer)
{
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return MQX_INVALID_PARAMETER;
    }
    #endif
    hwtimer->callback_pending = 0;
    return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_mcf5225.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_mcf5225.c$
* $Version : 3.8.1.0$
* $Date    : May-11-2011$
*
* Comments:
*
*   This file contains timer functions for use with a MCF5208.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "timer_pit.h"


const PIT_TIMER_INIT_STRUCT _bsp_timers[MCF5225_NUM_TIMERS] = {
   {MCF5225_INT_PIT0, BSP_PIT0_INT_LEVEL, BSP_PIT0_INT_SUBLEVEL},
   {MCF5225_INT_PIT1, BSP_PIT1_INT_LEVEL, BSP_PIT1_INT_SUBLEVEL}
};


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_pit_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding PIT
*
*END*----------------------------------------------------------------------*/

pointer _bsp_get_pit_base_address (uint_8 timer)
{
  volatile MCF5225_STRUCT _PTR_ reg_ptr = _PSP_GET_IPSBAR();
  if (timer >= MCF5225_NUM_TIMERS) return NULL;
  return (pointer)&reg_ptr->PIT[timer];
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_pit_vector
* Returned Value   : Vector number upon success, 0 upon failure
* Comments         :
*    This function returns desired interrupt vector number for specified PIT
*
*END*----------------------------------------------------------------------*/

uint_32 _bsp_get_pit_vector (uint_8 timer)
{
  if (timer >= MCF5225_NUM_TIMERS) return 0;
  return _bsp_timers[timer].INTERRUPT;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ifrem.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifrem.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the interface functions to the
*   packet driver interface.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_remove
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Unregister a hardware interface with RTCS.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_remove
   (
      _rtcs_if_handle   handle
         /* [IN] the RTCS interface state structure */
   )
{ /* Body */
   IPIF_PARM   parms;

   parms.ihandle = handle;

   return RTCSCMD_issue(parms, IPIF_remove);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_unbind
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Unbind an IP address from a registered hardware interface.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_unbind
   (
      _rtcs_if_handle   handle,
         /* [IN] the RTCS interface state structure */
      _ip_address       address
         /* [IN] the IP address for the interface */
   )
{ /* Body */
   IPIF_PARM   parms;

   parms.ihandle = handle;
   parms.address = address;

   return RTCSCMD_issue(parms, IPIF_unbind);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_gate_remove
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Register a gateway with RTCS.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_gate_remove
   (
      _ip_address       gateway,
         /* [IN] the IP address of the gateway */
      _ip_address       network,
         /* [IN] the IP (sub)network to route */
      _ip_address       netmask
         /* [IN] the IP (sub)network mask to route */
   )
{ /* Body */
#if RTCSCFG_ENABLE_GATEWAYS
   IPIF_PARM   parms;

   parms.address = gateway;
   parms.network = network;
   parms.netmask = netmask;
   /* Start CR 1133 */
   parms.locmask = 0;
   /* End CR 1133 */

   return RTCSCMD_issue(parms, IPIF_gate_remove);
#else
   return RTCSERR_FEATURE_NOT_ENABLED;
#endif
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_gate_remove_metric
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Removes a gateway from RTCS if the metric matches the route.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_gate_remove_metric
   (
      _ip_address       gateway,
         /* [IN] the IP address of the gateway */
      _ip_address       network,
         /* [IN] the IP (sub)network to route */
      _ip_address       netmask,
         /* [IN] the IP (sub)network mask to route */
      uint_16           metric
         /* [IN] the metric of the gateway */
   )
{ /* Body */
#if RTCSCFG_ENABLE_GATEWAYS
   IPIF_PARM   parms;

   parms.address = gateway;
   parms.network = network;
   parms.netmask = netmask;
   parms.locmask = metric;

   return RTCSCMD_issue(parms, IPIF_gate_remove);
#else
   return RTCSERR_FEATURE_NOT_ENABLED;
#endif
} /* Endbody */

#if RTCSCFG_ENABLE_IP6
/************************************************************************
* NAME: RTCS6_if_unbind_addr
* RETURNS : RTCS_OK or error code
* DESCRIPTION: Unbind an IPv6 address from a registered hardware interface.
*************************************************************************/
uint_32 RTCS6_if_unbind_addr ( _rtcs_if_handle handle   /* [IN] the RTCS interface state structure */,
                               in6_addr ip_addr         /* [IN] the IP address for the interface */)
{
   IP6_IF_PARM   parms;

   parms.ihandle = handle;
   parms.ip_addr = ip_addr;

   return RTCSCMD_issue(parms, IP6_IF_unbind_addr);
}
#endif /* RTCSCFG_ENABLE_IP6 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enrecv.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enrecv.c$
* $Version : 3.0.4.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   This file contains the Ethernet receive
*   support function.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_find_receiver
*  Returned Value : ECB for received packet, or NULL.
*  Comments       :
*        Finds an application for a received packet.
*
*END*-----------------------------------------------------------------*/

ENET_ECB_STRUCT_PTR ENET_find_receiver
   (
      /* [IN] the Ethernet state structure */
      ENET_CONTEXT_STRUCT_PTR  enet_ptr,

      /* [IN] the received packet */
      ENET_HEADER_PTR      packet_ptr,
      
      uint_32_ptr          length_ptr
   )
{ 
   ENET_ECB_STRUCT_PTR  ecb_ptr;
   ENET_MCB_STRUCT_PTR  mcb_ptr;
   uchar_ptr            type_ptr;
   uint_32              hdrlen;
   _enet_address        dest;
   uint_16              type;


   hdrlen = sizeof(ENET_HEADER);
   type_ptr = packet_ptr->TYPE;
   type = ntohs(type_ptr);

   if (type == ENETPROT_8021Q) {
      ENET_8021QTAG_HEADER_PTR tag_ptr = (ENET_8021QTAG_HEADER_PTR)(type_ptr+2);
      hdrlen += sizeof(ENET_8021QTAG_HEADER);
      type_ptr = tag_ptr->TYPE;
      type = ntohs(type_ptr);
   } 

   if (type <= ENETPROT_LENGTH_TYPE_BOUNDARY) {               
      ENET_8022_HEADER_PTR llc_ptr = (ENET_8022_HEADER_PTR)(type_ptr+2);
      if ((ntohc(llc_ptr->DSAP) != 0xAA)
       || (ntohc(llc_ptr->SSAP) != 0xAA)) {
         return NULL;
      } 
      if (*length_ptr < hdrlen + type) {
         return NULL;
      } 
      *length_ptr = hdrlen + type;
      type_ptr = llc_ptr->TYPE;
      type = ntohs(type_ptr);
   } 

   for (ecb_ptr = enet_ptr->ECB_HEAD; ecb_ptr; ecb_ptr = ecb_ptr->NEXT) {
      if (ecb_ptr->TYPE == type) {

         ntohe(packet_ptr->DEST, dest);
         if ((dest[0] & 1) && !((dest[0] == 0xFF)
                             && (dest[1] == 0xFF)
                             && (dest[2] == 0xFF)
                             && (dest[3] == 0xFF)
                             && (dest[4] == 0xFF)
                             && (dest[5] == 0xFF))) {

            /*
            ** The destination is a multicast address.
            ** Check the joined mulicast groups.
            */
            for (mcb_ptr = ecb_ptr->MCB_HEAD; mcb_ptr; mcb_ptr = mcb_ptr->NEXT) {
               if ((dest[0] == mcb_ptr->GROUP[0])
                && (dest[1] == mcb_ptr->GROUP[1])
                && (dest[2] == mcb_ptr->GROUP[2])
                && (dest[3] == mcb_ptr->GROUP[3])
                && (dest[4] == mcb_ptr->GROUP[4])
                && (dest[5] == mcb_ptr->GROUP[5])) {
                  break;
               } 
            } 

            if (!mcb_ptr) {
               /*
               ** We received a packet multicasted to a group we
               ** haven't joined.  Break out of the big for loop
               ** and discard the packet.  We don't continue the
               ** big for loop because there is only one ECB per
               ** type and we already found it.
               */
               ecb_ptr = NULL;
            } 
         } 

         break;
      } 
   } 

   return ecb_ptr;

} 


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/polled/i2c_pol_ki2c.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_pol_ki2c.c$
* $Version : 3.8.11.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains low level functions for the I2C polled device driver
*   for Kinetis family.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "i2c.h"
#include "i2c_pol_prv.h"
#include "i2c_ki2c_prv.h"

static uint_32 _ki2c_set_baudrate (uint_32, uint_32);
extern uint_32 _ki2c_polled_init (KI2C_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _ki2c_polled_deinit (IO_I2C_POLLED_DEVICE_STRUCT_PTR, VKI2C_INFO_STRUCT_PTR);
extern uint_32 _ki2c_polled_rx (IO_I2C_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _ki2c_polled_tx (IO_I2C_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _ki2c_polled_ioctl (VKI2C_INFO_STRUCT_PTR, uint_32, uint_32_ptr);
static uint_32 _ki2c_polled_rx_tx (I2C_MemMapPtr, VKI2C_INFO_STRUCT_PTR, uchar_ptr, uint_32);


static const uint_32 BAUDRATE_MULT[] = { 1, 2, 4 };
static const uint_32 BAUDRATE_ICR[]= {  20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 
    36, 40, 44, 48, 56, 68, 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, 112, 128,
    144, 160, 192, 240, 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 
    512, 576, 640, 768, 960, 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 
    1536, 1792, 2048, 2304, 2560, 3072, 2840 };

/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_set_baudrate
* Returned Value   : uint_32 divider register setting
* Comments         :
*    Find closest setting of divider register for given baudrate.
*
*END*********************************************************************/

static uint_32 _ki2c_set_baudrate 
    (
        /* [IN] Module input clock in Hz */
        uint_32 clock, 
        
        /* [IN] Desired baudrate in Hz */
        uint_32 baudrate
    ) 
{
    #define MAX_ICR 64
    uint_32 mult, icr, min, minmult = 0, minicr = 0;
    int_32  val;
    
    min = (uint_32)-1;
    /* We will find the nearest smallest diference in desired and real baudrate.
    ** This is transformed to find smallest clock diference.
    ** IIC baud rate = bus speed (Hz)/(mul * SCL divider) =>
    ** IIC baud rate * mul * SCL divider <= clock
    */
    for (mult = 0; mult < 3; mult++) 
    {
        for (icr = 0; icr < MAX_ICR; icr++) 
        {
            val = BAUDRATE_MULT[mult] * BAUDRATE_ICR[icr] * baudrate - clock;
            if (val < 0) val = -val;
            if (min > val) 
            {
                min = val;
                minmult = mult;
                minicr = icr;
            }
        }
    }
    return I2C_F_MULT(minmult) | I2C_F_ICR(minicr);
}


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_polled_install
* Returned Value   : MQX error code
* Comments         :
*    Install an I2C device.
*
*END*********************************************************************/

uint_32 _ki2c_polled_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr              identifier,
  
      /* [IN] The I/O init data pointer */
      KI2C_INIT_STRUCT_CPTR init_data_ptr
   )
{ /* Body */

   
#if PE_LDD_VERSION
   if (PE_PeripheralUsed((uint_32)_bsp_get_i2c_base_address(init_data_ptr->CHANNEL)))
   {
      /* IO Device used by PE Component*/
      return IO_DEVICE_EXISTS;
   }
#endif

   
   return _io_i2c_polled_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, pointer _PTR_, char_ptr))_ki2c_polled_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_ki2c_polled_deinit,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_ki2c_polled_rx,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_ki2c_polled_tx,
      (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_ki2c_polled_ioctl, 
      (pointer)init_data_ptr);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_polled_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an I2C device.
*
*END*********************************************************************/

uint_32 _ki2c_polled_init
   (
      /* [IN] Initialization information for the device being opened */
      KI2C_INIT_STRUCT_PTR io_init_ptr,

      /* [OUT] Address to store device specific information */
      pointer _PTR_        io_info_ptr_ptr,
       
      /* [IN] The rest of the name of the device opened */
      char_ptr             open_name_ptr

   )
{ /* Body */
   I2C_MemMapPtr           i2c_ptr;
   VKI2C_INFO_STRUCT_PTR   io_info_ptr;

   i2c_ptr = _bsp_get_i2c_base_address (io_init_ptr->CHANNEL);
   if (NULL == i2c_ptr)
   {
        return I2C_ERROR_CHANNEL_INVALID;
   }
  
   io_info_ptr = (VKI2C_INFO_STRUCT_PTR)_mem_alloc_system_zero ((uint_32)sizeof (KI2C_INFO_STRUCT));
   if (NULL == io_info_ptr) 
   {
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type ((pointer)io_info_ptr, MEM_TYPE_IO_I2C_INFO_STRUCT);

   /* I2C board specific initialization */
   _bsp_i2c_io_init (io_init_ptr->CHANNEL);

   *io_info_ptr_ptr                              = (pointer)io_info_ptr;
   io_info_ptr->INIT                             = *io_init_ptr;
   io_info_ptr->I2C_PTR                          = i2c_ptr;
   io_info_ptr->OLD_ISR                          = NULL;
   io_info_ptr->OLD_ISR_DATA                     = NULL;
   io_info_ptr->VECTOR                           = 0;
   io_info_ptr->MODE                             = io_init_ptr->MODE;
   io_info_ptr->STATE                            = I2C_STATE_READY;
   io_info_ptr->ADDRESSEE                        = 0;
   io_info_ptr->OPERATION                        = 0;
   io_info_ptr->RX_REQUEST                       = 0;
   io_info_ptr->RX_BUFFER                        = NULL;
   io_info_ptr->RX_IN                            = 0;
   io_info_ptr->RX_OUT                           = 0;
   io_info_ptr->TX_BUFFER                        = NULL;
   io_info_ptr->TX_IN                            = 0;
   io_info_ptr->TX_OUT                           = 0;
   io_info_ptr->STATISTICS.INTERRUPTS            = 0;
   io_info_ptr->STATISTICS.RX_PACKETS            = 0;
   io_info_ptr->STATISTICS.TX_PACKETS            = 0;
   io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS  = 0;
   io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE = 0;
   io_info_ptr->STATISTICS.TX_NAKS               = 0;

   /* Disable and clear I2C before initializing it */
   i2c_ptr->C1 = 0x00;
  
   /* Clear out all I2C events */
   i2c_ptr->S = 0x00;

   /* Set the station address for SLAVE receive operations */      
   i2c_ptr->A1 = io_init_ptr->STATION_ADDRESS << 1;
   
   /* Set the frequency divider for the nearest found baud rate */
   i2c_ptr->F = _ki2c_set_baudrate( BSP_I2C_CLOCK, io_init_ptr->BAUD_RATE ); 
   
   /* Enable I2C */
   i2c_ptr->C1 |= I2C_C1_IICEN_MASK;

   return I2C_OK;
   
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_polled_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an I2C device.
*
*END*********************************************************************/

uint_32 _ki2c_polled_deinit
   (
      /* [IN] the initialization information for the device being opened */
      IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] the address of the device specific information */
      VKI2C_INFO_STRUCT_PTR           io_info_ptr
   )
{ /* Body */
   I2C_MemMapPtr                      i2c_ptr;

   if ((NULL == io_info_ptr) || (NULL == pol_io_dev_ptr)) 
   {
      return I2C_ERROR_INVALID_PARAMETER;
   }
      
   i2c_ptr = io_info_ptr->I2C_PTR;
   if (i2c_ptr->S & I2C_S_BUSY_MASK) 
   {
      return I2C_ERROR_DEVICE_BUSY;
   }
   
   /* Disable the I2C */
   i2c_ptr->C1 = 0x00;

   /* Clear the I2C events */
   i2c_ptr->S = 0xFF; 
 
   /* Free info struct */
   _mem_free (pol_io_dev_ptr->DEV_INFO_PTR);
   pol_io_dev_ptr->DEV_INFO_PTR = NULL;

   return MQX_OK;

} /* Endbody */

 
/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_polled_ioctl
* Returned Value   : MQX error code.
* Comments         : 
*    This function performs miscellaneous services for
*    the I2C I/O device.  
*
*END*********************************************************************/

uint_32 _ki2c_polled_ioctl
   (
      /* [IN] the address of the device specific information */
      VKI2C_INFO_STRUCT_PTR io_info_ptr,

      /* [IN] The command to perform */
      uint_32               cmd,

      /* [IN] Parameters for the command */
      uint_32_ptr           param_ptr
   )
{ /* Body */
   I2C_MemMapPtr            i2c_ptr;
   uint_32                  result = MQX_OK;
   volatile uint_8          tmp, state;
   uint_32                  icr, mult;
  
   i2c_ptr = io_info_ptr->I2C_PTR;
   
   switch (cmd) 
   {
      case IO_IOCTL_FLUSH_OUTPUT:
         do 
         {
            for (tmp = 0; tmp < 0xFF; tmp++) 
               { };
            tmp = i2c_ptr->S;
         } while ((i2c_ptr->C1 & I2C_C1_TX_MASK) && ((I2C_S_BUSY_MASK == (tmp & (I2C_S_TCF_MASK | I2C_S_BUSY_MASK))) || (io_info_ptr->TX_IN != io_info_ptr->TX_OUT)));
         io_info_ptr->TX_IN = io_info_ptr->TX_OUT;
         if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (tmp & I2C_S_BUSY_MASK)))
         {
             io_info_ptr->OPERATION = 0;
             io_info_ptr->RX_REQUEST = 0;
             io_info_ptr->STATE = I2C_STATE_FINISHED;
         }
         if (NULL != param_ptr) 
         {
            *param_ptr = tmp & I2C_S_RXAK_MASK;
         }
         break;
      case IO_IOCTL_I2C_REPEATED_START:
         result = I2C_ERROR_DEVICE_BUSY;
         if (i2c_ptr->C1 & I2C_C1_MST_MASK)
         {
            if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) && (io_info_ptr->TX_IN == io_info_ptr->TX_OUT))
               || ((I2C_STATE_RECEIVE == io_info_ptr->STATE) && (0 == io_info_ptr->RX_REQUEST))
               || (I2C_STATE_FINISHED == io_info_ptr->STATE))
            {
               io_info_ptr->STATE = I2C_STATE_REPEATED_START;
               result = MQX_OK;
            }
         }
         break;
      case IO_IOCTL_I2C_STOP:
         i2c_ptr->C1 &= (~ (I2C_C1_TX_MASK | I2C_C1_TXAK_MASK));
         i2c_ptr->S |= (I2C_S_ARBL_MASK | I2C_S_IICIF_MASK);
         io_info_ptr->RX_REQUEST = 0;
         io_info_ptr->OPERATION = 0;
         io_info_ptr->STATE = I2C_STATE_READY;
         io_info_ptr->RX_OUT = io_info_ptr->RX_IN;

         if (! (i2c_ptr->C1 & I2C_C1_MST_MASK))
         {
            /* As slave, release the bus */
            tmp = (uint_8)i2c_ptr->D;
         }
         else
         {
            /* As master, send STOP condition */ 
            i2c_ptr->C1 &= (~ I2C_C1_MST_MASK);           
         }
         for (tmp = 0; tmp < 0xFF; tmp++) 
            { };

         /* Wait for bus idle */
         tmp = i2c_ptr->S;
         while (tmp & I2C_S_BUSY_MASK)
         { 
            if (tmp & I2C_S_IICIF_MASK)
            {
               i2c_ptr->S |= I2C_S_IICIF_MASK;
               tmp = (uint_8)i2c_ptr->D;
            }
            tmp = i2c_ptr->S;
         }
         break;
      case IO_IOCTL_I2C_SET_RX_REQUEST:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            io_info_ptr->RX_REQUEST = *param_ptr;
         }
         break;
      case IO_IOCTL_I2C_DISABLE_DEVICE:
         i2c_ptr->C1 &= (~ I2C_C1_IICEN_MASK);
         break;
      case IO_IOCTL_I2C_ENABLE_DEVICE:
         i2c_ptr->C1 |= I2C_C1_IICEN_MASK;
         break;
      case IO_IOCTL_I2C_SET_MASTER_MODE:
         if (I2C_STATE_READY != io_info_ptr->STATE) 
         {
            result = I2C_ERROR_DEVICE_BUSY;
         } 
         else 
         {
            io_info_ptr->MODE = I2C_MODE_MASTER;
         }
         break;
      case IO_IOCTL_I2C_SET_SLAVE_MODE:
         if (I2C_STATE_READY != io_info_ptr->STATE) 
         {
            result = I2C_ERROR_DEVICE_BUSY;
         } 
         else 
         {
            io_info_ptr->MODE = I2C_MODE_SLAVE;
         }
         break;
      case IO_IOCTL_I2C_GET_MODE:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = io_info_ptr->MODE;
         }
         break;
      case IO_IOCTL_I2C_SET_BAUD:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else if (i2c_ptr->S & I2C_S_BUSY_MASK) 
         {
            result = I2C_ERROR_DEVICE_BUSY;
         } 
         else 
         {
           i2c_ptr->F = _ki2c_set_baudrate( BSP_I2C_CLOCK, *param_ptr );
         }
         break;
      case IO_IOCTL_I2C_GET_BAUD:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            mult = BAUDRATE_MULT[(( i2c_ptr->F & I2C_F_MULT_MASK ) >> I2C_F_MULT_SHIFT)];
            icr = BAUDRATE_ICR[( i2c_ptr->F & I2C_F_ICR_MASK )];
            *param_ptr = (uint_32)((BSP_I2C_CLOCK) / (mult * icr));
         }
         break;
      case IO_IOCTL_I2C_SET_DESTINATION_ADDRESS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            io_info_ptr->ADDRESSEE = *param_ptr;
         }
         break;
      case IO_IOCTL_I2C_GET_DESTINATION_ADDRESS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = io_info_ptr->ADDRESSEE;
         }
         break;
      case IO_IOCTL_I2C_SET_STATION_ADDRESS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            i2c_ptr->A1 = I2C_A1_AD(*param_ptr);
         }
         break;
      case IO_IOCTL_I2C_GET_STATION_ADDRESS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = ( i2c_ptr->A1 & I2C_A1_AD_MASK ) >> I2C_A1_AD_SHIFT;
         }
         break;
      case IO_IOCTL_I2C_GET_STATE:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = io_info_ptr->STATE;
         }
         break;
      case IO_IOCTL_I2C_GET_STATISTICS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *((I2C_STATISTICS_STRUCT_PTR)param_ptr) = io_info_ptr->STATISTICS;
         }
         break;         
      case IO_IOCTL_I2C_CLEAR_STATISTICS:
         io_info_ptr->STATISTICS.INTERRUPTS = 0;
         io_info_ptr->STATISTICS.RX_PACKETS = 0;
         io_info_ptr->STATISTICS.TX_PACKETS = 0;
         io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS = 0;
         io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE = 0;
         io_info_ptr->STATISTICS.TX_NAKS = 0;
         break;
      case IO_IOCTL_I2C_GET_BUS_AVAILABILITY:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            if (i2c_ptr->S & I2C_S_BUSY_MASK) 
            {
                *param_ptr = I2C_BUS_BUSY;
            } 
            else 
            {
                *param_ptr = I2C_BUS_IDLE;
            }
         }
         break;
      default:
         break;
   }
   return result;
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_polled_rx
* Returned Value   : number of bytes read
* Comments         : 
*   Returns the number of bytes received.
*   Reads the data into provided array when data is available.
*
*END*********************************************************************/

uint_32 _ki2c_polled_rx
   (
      /* [IN] the address of the device specific information */
      IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] The array to copy data into */
      uchar_ptr                       buffer,
      
      /* [IN] number of bytes to read */
      uint_32                         length
   )
{ /* Body */
   VKI2C_INFO_STRUCT_PTR              io_info_ptr;
   I2C_MemMapPtr                      i2c_ptr;   
   uint_8                             tmp;
         
   io_info_ptr = pol_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;

   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION |= I2C_OPERATION_READ;
   tmp = io_info_ptr->STATE;
   if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
   {
      io_info_ptr->STATE = I2C_STATE_RECEIVE;
      if (I2C_MODE_MASTER == io_info_ptr->MODE)
      {
         i2c_ptr->C1 |= I2C_C1_TX_MASK;
         i2c_ptr->S |= I2C_S_IICIF_MASK;
         if (I2C_STATE_REPEATED_START == tmp)
         {
            i2c_ptr->C1 |= I2C_C1_RSTA_MASK;
         }
         else
         {
            i2c_ptr->C1 |= I2C_C1_MST_MASK;
         }
         io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
         i2c_ptr->D = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_READ;
         io_info_ptr->STATISTICS.TX_PACKETS++;
         while (0 == (i2c_ptr->S & I2C_S_IICIF_MASK))
            { };   /* wait for address transferred */
      }
   }

   return _ki2c_polled_rx_tx (i2c_ptr, io_info_ptr, buffer, length);
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_polled_tx
* Returned Value   : number of bytes transmitted
* Comments         : 
*   Writes the provided data buffer and loops until transmission complete.
*
*END*********************************************************************/

uint_32 _ki2c_polled_tx
   (
      /* [IN] the address of the device specific information */
      IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] The array characters are to be read from */
      uchar_ptr                       buffer,
      
      /* [IN] number of bytes to output */
      uint_32                         length
   )
{ /* Body */
   VKI2C_INFO_STRUCT_PTR              io_info_ptr;
   I2C_MemMapPtr                      i2c_ptr;   
   uint_8                             tmp;
   
   io_info_ptr  = pol_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;

   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION &= (~ I2C_OPERATION_READ);
   tmp = io_info_ptr->STATE;
   if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
   {
      io_info_ptr->STATE = I2C_STATE_TRANSMIT;
      if (I2C_MODE_MASTER == io_info_ptr->MODE)
      {
         i2c_ptr->C1 |= I2C_C1_TX_MASK;
         i2c_ptr->S |= I2C_S_IICIF_MASK;
         if (I2C_STATE_REPEATED_START == tmp)
         {
            i2c_ptr->C1 |= I2C_C1_RSTA_MASK;
         }
         else
         {
            i2c_ptr->C1 |= I2C_C1_MST_MASK;
         }
         io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
         i2c_ptr->D = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_WRITE;
         io_info_ptr->STATISTICS.TX_PACKETS++;
         while (0 == (i2c_ptr->S & I2C_S_IICIF_MASK))
            { };   /* wait for address transferred */
      }
   }

   return _ki2c_polled_rx_tx (i2c_ptr, io_info_ptr, buffer, length);
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_polled_rx_tx
* Returned Value   : number of bytes processed
* Comments         : 
*   Actual data transfer on I2C bus.
*
*END*********************************************************************/

static uint_32 _ki2c_polled_rx_tx
   (
      /* [IN] I2C register structure */
      I2C_MemMapPtr         i2c_ptr,

      /* [IN] I2C state structure */
      VKI2C_INFO_STRUCT_PTR io_info_ptr,
      
      /* [IN] The buffer for IO operation */
      uchar_ptr             buffer,
      
      /* [IN] Number of bytes in buffer */
      uint_32               length
   )
{ /* Body */
   uint_32                  i;
   uint_8                   i2csr;
   volatile uint_8          tmp;

   for (i = 0; i <= length; i++)
   {
      do 
      {
         i2csr = i2c_ptr->S;
         if (0 == (i2c_ptr->C1 & I2C_C1_MST_MASK))
         {
            if (i == length)
            {
               return i;
            }
            if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2csr & I2C_S_BUSY_MASK)))
            {
               io_info_ptr->OPERATION = 0;
               io_info_ptr->RX_REQUEST = 0;
               io_info_ptr->STATE = I2C_STATE_FINISHED;
               return i;
            }
         }
      } while (0 == (i2csr & I2C_S_IICIF_MASK));

      io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
   
      /* Master */
      if (i2c_ptr->C1 & I2C_C1_MST_MASK)
      {
         /* Transmit */
         if (i2c_ptr->C1 & I2C_C1_TX_MASK)
         {
            /* Not ack */
            if (i2csr & I2C_S_RXAK_MASK)
            {
               i2c_ptr->S |= I2C_S_IICIF_MASK;
               io_info_ptr->STATE = I2C_STATE_FINISHED;
               io_info_ptr->STATISTICS.TX_NAKS++;
               length = i;
            }
            /* Ack */
            else
            {
               /* Transmit requested */
               if (I2C_STATE_TRANSMIT == io_info_ptr->STATE)
               {
                  if (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ))
                  {
                     /* Anything to transmit? */
                     if (i < length)
                     {
                        i2c_ptr->S |= I2C_S_IICIF_MASK;
                        i2c_ptr->D = *buffer++;   /* transmit data */
                        io_info_ptr->STATISTICS.TX_PACKETS++;
                     }
                  }
                  else
                  {
                     length = i;
                  }
               }
               /* Receive requested */
               else if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
               {
                  if (0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ))
                  {
                     i2c_ptr->C1 &= (~ I2C_C1_TX_MASK);
                     if (1 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
                     }
                     else
                     {
                        i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
                     }
                     i2c_ptr->S |= I2C_S_IICIF_MASK;
                     if (0 == io_info_ptr->RX_REQUEST)
                     {
                        io_info_ptr->STATE = I2C_STATE_FINISHED;
                        length = i;
                     }
                     else
                     {
                        tmp = i2c_ptr->D;   /* dummy read to clock in 1st byte */
                        i--;
                     }
                  }
                  else
                  {
                     length = i;
                  }
               }
               /* Others are unwanted/not handled states */
               else
               {
                  length = i;
               }
            }
         }
         /* Receive */
         else
         {
            /* Receive requested */
            if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
            {
               if ((0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (0 != io_info_ptr->RX_REQUEST))
               {
                  if (i < length)
                  {
                     i2c_ptr->S |= I2C_S_IICIF_MASK;
                     io_info_ptr->RX_REQUEST--;
                     if (1 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
                     }
                     else
                     {
                        i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
                     }
                     if (0 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->C1 |= I2C_C1_TX_MASK;   /* no more reading */
                     }
                     *buffer++ = i2c_ptr->D;   /* receive data */
                     if (0 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->C1 &= (~ I2C_C1_TX_MASK);
                        io_info_ptr->STATE = I2C_STATE_FINISHED;
                        length = i + 1;
                        i = length;
                     }
                     io_info_ptr->STATISTICS.RX_PACKETS++;
                  }
               }
               else
               {
                  length = i;
               }
            }
            /* Others are unwanted/not handled states */
            else 
            {
               length = i;
            }
         }
      }
      /* Slave */
      else
      {
         /* Master arbitration lost */
         if (i2csr & I2C_S_ARBL_MASK)
         {
            i2c_ptr->S |=  I2C_S_ARBL_MASK;
            io_info_ptr->STATE = I2C_STATE_LOST_ARBITRATION;
            io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS++;
            length = i;
         }
         /* Addressed as slave */
         if (i2csr & I2C_S_IAAS_MASK)
         {
            if (I2C_MODE_MASTER == io_info_ptr->MODE)
            {
               io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE++;
            }
            /* Transmit requested */
            if (i2csr & I2C_S_SRW_MASK)
            {  
               io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_TX;
               if (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ))
               {
                  if (i < length)
                  {
                     i2c_ptr->C1 |= I2C_C1_TX_MASK;
                     i2c_ptr->S |= I2C_S_IICIF_MASK;
                     i2c_ptr->D = *buffer++;   /* transmit data */
                     io_info_ptr->STATISTICS.TX_PACKETS++;
                  }
               }
               else
               {
                  length = i;
               }
            }
            /* Receive requested */
            else
            {
               io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_RX;
               if ((0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (i == 0) && (0 != io_info_ptr->RX_REQUEST))
               {
                  i2c_ptr->C1 &= (~ I2C_C1_TX_MASK);
                  i2c_ptr->S |= I2C_S_IICIF_MASK;
                  if (1 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
                  }
                  else
                  {
                     i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
                  }
                  tmp = i2c_ptr->D;   /* dummy read to release bus */
                  i--;
               }
               else
               {
                  length = i;
               }
            }
         }
         /* Normal slave operation */
         else
         {
            /* No master arbitration lost */
            if (! (i2csr & I2C_S_ARBL_MASK))
            {
               /* Transmit */
               if (i2c_ptr->C1 & I2C_C1_TX_MASK)
               {
                  /* Not ack */
                  if (i2csr & I2C_S_RXAK_MASK)
                  {
                     i2c_ptr->S |= I2C_S_IICIF_MASK;
                     io_info_ptr->STATE = I2C_STATE_FINISHED;
                     io_info_ptr->STATISTICS.TX_NAKS++;
                     length = i;
                  }
                  /* Ack */
                  else
                  {
                     /* Transmit requested */
                     if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_TX == io_info_ptr->STATE))
                        && (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ)))
                     {
                        if (i < length)
                        {
                           i2c_ptr->S |= I2C_S_IICIF_MASK;
                           i2c_ptr->D = *buffer++;   /* transmit data */
                           io_info_ptr->STATISTICS.TX_PACKETS++;
                        }
                     }
                     else
                     {
                        length = i;
                     }
                  }
               }
               /* Receive */
               else
               {
                  /* Receive requested */
                  if (((I2C_STATE_RECEIVE == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_RX == io_info_ptr->STATE))
                     && (0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (0 != io_info_ptr->RX_REQUEST))
                  {
                     if (i < length)
                     {
                        i2c_ptr->S |= I2C_S_IICIF_MASK;
                        io_info_ptr->RX_REQUEST--;
                        if (1 == io_info_ptr->RX_REQUEST)
                        {
                           i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
                        }
                        else
                        {
                           i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
                        }
                        if (0 == io_info_ptr->RX_REQUEST)
                        {
                           io_info_ptr->STATE = I2C_STATE_FINISHED;
                        }
                        *buffer++ = i2c_ptr->D;   /* receive data */
                        io_info_ptr->STATISTICS.RX_PACKETS++;
                     }
                  }
                  else
                  {
                     length = i;
                  }
               }
            }
            else
            {
               length = i;
            }
         }
      }
   }
   return length;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/snmpcfg.h<|end_filename|>
#ifndef __snmpcfg_h__
#define __snmpcfg_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: snmpcfg.h$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the definitions for configuring
*   optional features in SNMP.
*   SNMP is delivered as follows:
*   SNMPCFG_BUFFER_SIZE            512
*   SNMPCFG_NUM_COMMUNITY           2
*   SNMPCFG_COMMUNITY_LIST         "public" , "private"
*   SNMPCFG_MAX_TRAP_RECEIVERS      6
*   SNMPCFG_SEND_V2_TRAPS           NOT DEFINE
*   SNMPCFG_SYSDESCR               "RTCS version <version>"
*   SNMPCFG_SYSSERVICES            8 (end-to-end)
*   SNMPCFG_HAVE_INT64             0
*
*END************************************************************************/

/*
** SNMP has two static buffers (one for receiving and one for generating
** responses), each of size SNMPCFG_BUFFER_SIZE.  RFCs 1157 and 1906 require
** this number to be at least 484.
*/
#ifndef SNMPCFG_BUFFER_SIZE
#define SNMPCFG_BUFFER_SIZE   512
#endif

/*
** The number of communities, used in both SNMPv1 and SNMPv2c.
*/
#ifndef SNMPCFG_NUM_COMMUNITY
#define SNMPCFG_NUM_COMMUNITY 2
#endif


/* 
** The string of communities, used in both SNMPv1 and SNMPv2c.
** Communities can be added to the list at compile time
*/
#ifndef SNMPCFG_COMMUNITY_LIST
#define SNMPCFG_COMMUNITY_LIST {"public", "private"} 
#endif

/* 
** Size of TRAP Receivers table - increase if sending traps to more than 6 nodes 
*/
#ifndef SNMPCFG_MAX_TRAP_RECEIVERS
#define SNMPCFG_MAX_TRAP_RECEIVERS 6
#endif

/* 
** Send v2 traps?  If not defined, send v1 traps instead 
*/
#define SNMPCFG_SEND_V2_TRAPS

/*
** The value of the system.sysDescr variable.
*/
#ifndef SNMPCFG_SYSDESCR
#define SNMPCFG_NUMTOSTR(x)   #x
#define SNMPCFG_NUMTOSTR2(x)  SNMPCFG_NUMTOSTR(x)
#define SNMPCFG_SYSDESCR      "RTCS version " SNMPCFG_NUMTOSTR2(RTCS_VERSION_MAJOR) \
                              "." SNMPCFG_NUMTOSTR2(RTCS_VERSION_MINOR) \
                              "." SNMPCFG_NUMTOSTR2(RTCS_VERSION_REV)
#endif

/*
** The value of the system.sysServices variable.
*/
#ifndef SNMPCFG_SYSSERVICES
#define SNMPCFG_SYSSERVICES   8
#endif

/*
** SNMPCFG_HAVE_INT64 enables support for 64-bit integers.
*/
#ifndef SNMPCFG_HAVE_INT64
#define SNMPCFG_HAVE_INT64    0
#endif

/* To traverse the MIB in the SNMP task instead
   of the RTCS task, uncomment the line below.  */
// #define TRAVERSE_MIB_IN_SNMP_TASK 1
#ifdef TRAVERSE_MIB_IN_SNMP_TASK
#warning Do not access RTCS OIDs when traversing MIB in snmp task
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ftpd_msg.h<|end_filename|>
#ifndef __ftpd_msg_h__
#define __ftpd_msg_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpd_msg.h$
* $Version : 3.8.6.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/
extern const char ftpmsg_sending[];   
extern const char ftpmsg_typeok[];    
extern const char ftpmsg_portok[];    
extern const char ftpmsg_banner[];    
extern const char ftpmsg_bye[];       
extern const char ftpmsg_rxok[];      
extern const char ftpmsg_txok[];      
extern const char ftpmsg_logged[];    
extern const char ftpmsg_pass[];      
extern const char ftpmsg_noconn[];    
extern const char ftpmsg_writefail[]; 
extern const char ftpmsg_writeeof[];  
extern const char ftpmsg_badcmd[];    
extern const char ftpmsg_badtype[];   
extern const char ftpmsg_badport[];   
extern const char ftpmsg_badsyntax[]; 
extern const char ftpmsg_unimp[];     
extern const char ftpmsg_cantopen[];  

extern const char ftpmsg_size[];            
extern const char ftpmsg_syntax_error[];    
extern const char ftpmsg_need_password[];   
extern const char ftpmsg_not_logged[];      
extern const char ftpmsg_goodbye[];         
extern const char ftpmsg_no_fs[];           
extern const char ftpmsg_pasv_mode[];       
extern const char ftpmsg_site_info[];       
extern const char ftpmsg_bad_option[];      
extern const char ftpmsg_syst[];            
extern const char ftpmsg_help_start[];      
extern const char ftpmsg_help_end[];        
extern const char ftpmsg_pwd_error[];       
extern const char ftpmsg_cd_error[];        
extern const char ftpmsg_rmdir_error[];     
extern const char ftpmsg_delete_error[];    
extern const char ftpmsg_mkdir_error[];     
extern const char ftpmsg_ok[];              
extern const char ftpmsg_type_ascii[];      
extern const char ftpmsg_type_image[];      
extern const char ftpmsg_type_unknown[];    
extern const char ftpmsg_no_file[];         
extern const char ftpmsg_opening_datacon[]; 
extern const char ftpmsg_tx_complete[];     
extern const char ftpmsg_no_datacon[];      
extern const char ftpmsg_no_memory[];

#endif
/*EOF*/


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_rename.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_rename.c$
* $Version : 3.8.6.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the file specific interface functions
*   of MFS which need a filename as an input parameter.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"




/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Rename_file
* Returned Value   : error_code
* Comments  :   Rename an existing file.
*
*END*---------------------------------------------------------------------*/
#if !MFSCFG_READ_ONLY

_mfs_error  MFS_Rename_file
    (
    MQX_FILE_PTR            mfs_fd_ptr,     /*[IN] the MFS device on which to operate */
    char_ptr                old_pathname,   /*[IN] directory and file name of file to be renamed */
    char_ptr                new_pathname    /*[IN] directory and file name to be given to the file */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_DIR_ENTRY_PTR       source_entry, dest_entry;
    MFS_DIR_ENTRY           temp_dir_entry;
    char_ptr                dir_name, new_filename, old_filename;
    uint_32                 source_dir, /* 1st cluster of the source dir      */
                            dest_dir,   /* 1st cluster of the destination dir */
                            source_dir_bak,
                            dest_dir_bak;
    uint_32                 dir_index,dir_index_bak;    
    _mfs_error              error_code;
    char                    temp_filename[SFILENAME_SIZE+1];  
    uint_32                 dest_prev_cluster = CLUSTER_INVALID, source_prev_cluster = CLUSTER_INVALID; 

    if ( old_pathname == NULL || *old_pathname == '\0' || new_pathname == NULL || *new_pathname == '\0' )
    {
        return MFS_INVALID_PARAMETER;
    }

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif    

    error_code = MFS_alloc_path(&dir_name);
    if ( error_code != MFS_NO_ERROR )
    {
        return( error_code );
    }
    error_code = MFS_alloc_2paths(&new_filename,&old_filename);
    if ( error_code != MFS_NO_ERROR )
    {
        MFS_free_path(dir_name);
        return( error_code );
    }

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        goto error_free_paths;
    }

    /*
    ** Find the destination directory
    */
    MFS_Parse_pathname (dir_name, new_filename, new_pathname);
    dest_dir = MFS_Find_directory(drive_ptr, dir_name, drive_ptr->CUR_DIR_CLUSTER);
    if ( dest_dir == CLUSTER_INVALID )
    {
        error_code = MFS_PATH_NOT_FOUND;
        goto error_unlock_and_free_paths;
    }

    /*
    ** Find the source directory
    */
    MFS_Parse_pathname (dir_name, old_filename, old_pathname);
    source_dir =  MFS_Find_directory(drive_ptr, dir_name, drive_ptr->CUR_DIR_CLUSTER);
    if ( source_dir == CLUSTER_INVALID )
    {
        error_code = MFS_PATH_NOT_FOUND;
        goto error_unlock_and_free_paths;
    }

    /*
    ** Find the source file
    */
    if ( *new_filename != '.' && *old_filename != '.' )
    {
        dir_index = 0;
        dest_dir_bak = dest_dir;
        dest_entry = MFS_Find_directory_entry(drive_ptr, new_filename, &dest_dir_bak, &dir_index, &dest_prev_cluster, MFS_ATTR_ANY, &error_code); 
        if ( dest_entry == NULL && !error_code )
        {
            dir_index = 0;
            dir_index_bak = dir_index;
            source_dir_bak = source_dir;
            source_entry = MFS_Find_directory_entry(drive_ptr, old_filename, &source_dir_bak, &dir_index, &source_prev_cluster, MFS_ATTR_ANY, &error_code); 
            if ( source_entry != NULL && !error_code )
            {
                if ( !(dtohc(source_entry->ATTRIBUTE) & MFS_ATTR_VOLUME_NAME) )
                {
                    _mem_copy(source_entry, &temp_dir_entry, sizeof (MFS_DIR_ENTRY));
                    if ( source_dir != dest_dir )
                    {
                        /*
                        ** Moving the file into different directory
                        */
                        if ( !(dtohc(source_entry->ATTRIBUTE) & 
                            MFS_ATTR_READ_ONLY) )
                        {
                            dest_entry = MFS_Create_directory_entry (drive_ptr, new_filename, dtohc(source_entry->ATTRIBUTE), 
                                &dest_dir, &dir_index, &error_code);

                            if ( error_code == MFS_NO_ERROR )
                            {
                                strcpy(temp_filename,dest_entry->NAME);
                                _mem_copy (&temp_dir_entry, dest_entry,sizeof (MFS_DIR_ENTRY));
                                strcpy(dest_entry->NAME,temp_filename);
                                drive_ptr->DIR_SECTOR_DIRTY = TRUE;

                                //        error_code = MFS_Write_back_directory_sector_buffer(drive_ptr);
                                //        if (error_code == MFS_NO_ERROR) {
                                source_entry = MFS_Find_directory_entry(drive_ptr,
                                    old_filename, &source_dir,&dir_index_bak, &source_prev_cluster, MFS_ATTR_ANY, &error_code);
                                if ( error_code )
                                {
                                    goto error_unlock_and_free_paths;
                                }
                                *source_entry->NAME = MFS_DEL_FILE;
                                drive_ptr->DIR_SECTOR_DIRTY = TRUE;

                                error_code = MFS_remove_lfn_entries(drive_ptr, source_dir, dir_index_bak, source_prev_cluster); 
                            }
                        }
                        else
                        {
                            error_code = MFS_ACCESS_DENIED;
                        } 
                    }
                    else
                    {
                        /*
                        ** Renaming the file in the same directory
                        */
                        *source_entry->NAME = MFS_DEL_FILE;
                        drive_ptr->DIR_SECTOR_DIRTY = TRUE;

                        error_code = MFS_remove_lfn_entries(drive_ptr,source_dir,dir_index, source_prev_cluster); 
                        if ( error_code )
                        {
                            goto error_unlock_and_free_paths;
                        }
                        dest_entry = MFS_Create_directory_entry (drive_ptr, new_filename, dtohc(temp_dir_entry.ATTRIBUTE), 
                            &source_dir_bak, &dir_index, &error_code);

                        *(dest_entry->ATTRIBUTE) = *(temp_dir_entry.ATTRIBUTE);
                        htodl(dest_entry->FILE_SIZE, dtohl(temp_dir_entry.FILE_SIZE));                  
                        htods(dest_entry->HFIRST_CLUSTER, dtohs(temp_dir_entry.HFIRST_CLUSTER));                  
                        htods(dest_entry->LFIRST_CLUSTER, dtohs(temp_dir_entry.LFIRST_CLUSTER));                  
                    }  
                }
                else
                {
                    error_code = MFS_WRITE_FAULT;
                }  
            }
            else if ( source_entry == NULL && !error_code )
            {
                error_code = MFS_FILE_NOT_FOUND;
            }
        }
        else if ( dest_entry != NULL && !error_code )
        {
            error_code = MFS_FILE_EXISTS;
        }
    }
    else
    {
        error_code = MFS_INVALID_PARAMETER;
    }  


    error_unlock_and_free_paths:   
    MFS_unlock(drive_ptr,TRUE);
    error_free_paths:   
    MFS_free_path(dir_name);
    MFS_free_path(new_filename);
    MFS_free_path(old_filename);

    return(error_code);
}  
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mcf52xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mcf52xx.c$
* $Version : 3.8.21.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions for internal flash read, write, erase 
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "flash_mcf52xx_prv.h"
#include "flash_mcf52xx.h"
   
/* Internal function definitions */
static void mcf52xx_ram_function(volatile char_ptr ); 
static void mcf52xx_ram_function_end(void);
static char_ptr mcf52xx_init_ram_function(void);

const FLASHX_BLOCK_INFO_STRUCT _flashx_mcf52xx_block_map[] =  {
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE, (uint_32) BSP_INTERNAL_FLASH_BASE, BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { 0, 0, 0 }
};

const FLASHX_DEVICE_IF_STRUCT _flashx_mcf52xx_if = {
    mcf52xx_flash_erase_sector,
    mcf52xx_flash_write_sector,
    NULL,
    NULL,
    mcf52xx_flash_init,
    mcf52xx_flash_deinit,
    NULL,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mcf52xx_set_cfmclkd
* Returned Value   : none
* Comments         :
*    Set the CFMCLKD register.
*
*END*----------------------------------------------------------------------*/
void _mcf52xx_set_cfmclkd()
{
    #define PRDIV8_LIMIT_FREQ   12800000L // limit freq. for using PRDIV8_PRSC
    #define FLASH_FREQ          200000L   // 200 kHz program frequency
    #define PRDIV8_PRSC         8         // prescaller 8
    
    VMCF52XX_CFM_STRUCT_PTR  cfm_ptr;
    
    cfm_ptr = _bsp_get_cfm_address();
    
    if(BSP_BUS_CLOCK > PRDIV8_LIMIT_FREQ)
    {
        cfm_ptr->CFMCLKD = MCF52XX_CFM_CFMCLKD_PRDIV8 | MCF52XX_CFM_CFMCLKD_DIV((BSP_BUS_CLOCK+PRDIV8_PRSC*FLASH_FREQ-1) / (PRDIV8_PRSC * FLASH_FREQ) -1);
    }
    else
    {
        cfm_ptr->CFMCLKD = MCF52XX_CFM_CFMCLKD_DIV((BSP_BUS_CLOCK+FLASH_FREQ-1) / FLASH_FREQ -1);
    }       
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf_52xx_flash_init
* Returned Value   : 
* Comments         :
*   Erase a flash memory block  
*
*END*----------------------------------------------------------------------*/
boolean mcf52xx_flash_init
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    MCF52XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
#ifdef PSP_HAS_DUAL_FLASH
    uint_8 array;
#endif //PSP_HAS_DUAL_FLASH

    VMCF52XX_CFM_STRUCT_PTR     cfm_ptr;

    dev_spec_ptr = _mem_alloc(sizeof(MCF52XX_FLASH_INTERNAL_STRUCT));
#if MQX_CHECK_FOR_MEMORY_ALLOCATION_ERRORS
    /* test for correct memory allocation */
    if( dev_spec_ptr == NULL){
        return FALSE;
    }
#endif //MQX_CHECK_FOR_MEMORY_ALLOCATION_ERRORS
        
    /* get the pointer to cfm registers structure */
    cfm_ptr = _bsp_get_cfm_address();
    dev_spec_ptr->cfm_ptr = (vchar_ptr)cfm_ptr;
    dev_ptr->DEVICE_SPECIFIC_DATA = dev_spec_ptr;
    
    /* save pointer to function in ram */
    dev_spec_ptr->flash_execute_code_ptr = mcf52xx_init_ram_function();
    
    /* set correct clocking for CFM module */
    _mcf52xx_set_cfmclkd();

    return TRUE;    
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf52xx_flash_deinit
* Returned Value   : 
* Comments         :
*     
*
*END*----------------------------------------------------------------------*/
void mcf52xx_flash_deinit
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    MCF52XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (MCF52XX_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    
    /* de-allocate the ram function buffer */
    if(dev_spec_ptr->flash_execute_code_ptr){
        _mem_free(dev_spec_ptr->flash_execute_code_ptr);
    }
    dev_spec_ptr->flash_execute_code_ptr = NULL;
    /* de-allocate device specific structure */
    _mem_free(dev_ptr->DEVICE_SPECIFIC_DATA);
    dev_ptr->DEVICE_SPECIFIC_DATA = NULL; 
}   

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf52xx_init_ram_function
* Returned Value   : pointer to allocated RAM function
* Comments         :
*   allocate and copy flash RAM function  
*
*END*----------------------------------------------------------------------*/
static char_ptr mcf52xx_init_ram_function
(
    void
)
{
    char_ptr ram_code_ptr;
    
    /* Allocate space on stack to run flash command out of SRAM */
    ram_code_ptr = _mem_alloc((char_ptr)mcf52xx_ram_function_end  - (char_ptr)mcf52xx_ram_function);
    /* copy code to RAM buffer */
    _mem_copy ((char_ptr)mcf52xx_ram_function, ram_code_ptr, (char_ptr)mcf52xx_ram_function_end  - (char_ptr)mcf52xx_ram_function);

    return ram_code_ptr;               
}
    
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf52xx_erase_sector
* Returned Value   : true if success, or false
* Comments         :
*   Erase a flash memory block  
*
*END*----------------------------------------------------------------------*/
boolean mcf52xx_flash_erase_sector
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr, 

    /* [IN] Erased sector address */
    char_ptr             from_ptr,

    /* [IN] Erased sector size */
    _mem_size            size
)
{
    MCF52XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (MCF52XX_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    VMCF52XX_CFM_STRUCT_PTR cfm_ptr;
    int (*RunInRAM)(char_ptr);
    uint_32 temp;

    /* select the proper ramcode function */
    RunInRAM = (int(*)(char_ptr))dev_spec_ptr->flash_execute_code_ptr;
    
    /* get the pointer to cfm registers structure */
    cfm_ptr = (VMCF52XX_CFM_STRUCT_PTR)dev_spec_ptr->cfm_ptr;
    
    _int_disable();
    /* prepare flash write operation, clear flags and wait for ready state */
    cfm_ptr->CFMUSTAT = (MCF52XX_CFM_CFMUSTAT_PVIOL | MCF52XX_CFM_CFMUSTAT_ACCERR);
    while (!(cfm_ptr->CFMUSTAT & MCF52XX_CFM_CFMUSTAT_CBEIF)){
        /* wait */
    };

    /* latch address in Flash */
    (*(volatile vuint_32 *)(FLASH_START_ADDRESS + from_ptr)) = (vuint_32)-1;  
    
    /* issue erase command */
    cfm_ptr->CFMCMD = MCF52XX_CFM_CFMCMD_PAGE_ERASE;
    
    /* run command and wait for it to finish (must execute from RAM) */ 
    temp = _psp_get_sr();
    _psp_set_sr(temp | 0x0700);
    RunInRAM((char_ptr) &cfm_ptr->CFMUSTAT);
    _psp_set_sr(temp);  
    
    if (cfm_ptr->CFMUSTAT & (MCF52XX_CFM_CFMUSTAT_ACCERR | MCF52XX_CFM_CFMUSTAT_PVIOL)) {
        _int_enable();
        return FALSE;
    }
    
    _int_enable();
    return(TRUE);   

}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf52xx_write_sector
* Returned Value   : true if success, or false
* Comments         :
*   Performs a write into flash memory  
*
*END*----------------------------------------------------------------------*/
boolean mcf52xx_flash_write_sector
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr, 

    /* [IN] Source address */
    char_ptr             from_ptr,

    /* [IN] Destination address */
    char_ptr             to_ptr,

    /* [IN] Number of bytes to write */
    _mem_size            size
) 
{
    MCF52XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (MCF52XX_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    VMCF52XX_CFM_STRUCT_PTR  cfm_ptr;
    int (*RunInRAM)(char_ptr);
    uint_32  temp, temp_data = 0xFFFFFFFF;
    char_ptr temp_data_ptr;
    uchar byte_data_counter = 0;

    #define BYTES_IN_WORD   4
    #define WRITED_BYTES    4

    /* get the offset in write word */
    uint_32 offset = (uint_32)to_ptr & 0x00000003;;

    temp_data_ptr = (char_ptr)&temp_data;
    /* select the proper ramcode function */
    RunInRAM = (int (*)(char_ptr)) dev_spec_ptr->flash_execute_code_ptr;

    /* get the pointer to cfm registers structure */
    cfm_ptr = (VMCF52XX_CFM_STRUCT_PTR) dev_spec_ptr->cfm_ptr;
    /* Clear any errors */
    _int_disable();
    cfm_ptr->CFMUSTAT = (MCF52XX_CFM_CFMUSTAT_PVIOL | MCF52XX_CFM_CFMUSTAT_ACCERR); 
    
    /* if the start address !=  doesn't correspond with hardware, prepare
       variables for 1st word write */
    if(offset){
        /* Align pointer to writable address */
        to_ptr -= offset;
        /* jump over old data */
        byte_data_counter = offset; 
    }
    /* while are some data to write */
    while(size){
        /* move data to write word */       
        while( byte_data_counter < BYTES_IN_WORD && size ){
            *(uchar_ptr)(temp_data_ptr+byte_data_counter) = *from_ptr++;
            byte_data_counter++;
            size--;
        }
        /* move write data to register */
        (*(volatile vuint_32 *)(FLASH_START_ADDRESS + (uint_32)to_ptr)) = temp_data;
        /* init variables for next loop */
        to_ptr += WRITED_BYTES;
        byte_data_counter = 0;
        temp_data = 0xFFFFFFFF;
        /* write command to CFMCMD */
        cfm_ptr->CFMCMD = MCF52XX_CFM_CFMCMD_WORD_PROGRAM;
        
        /* run command and wait for it to finish (must execute from RAM) */     
        temp = _psp_get_sr();
        _psp_set_sr(temp | 0x0700);
        RunInRAM((char_ptr)&cfm_ptr->CFMUSTAT);                           
        _psp_set_sr(temp);
        
        /* Check for Errors */
        if (cfm_ptr->CFMUSTAT & (MCF52XX_CFM_CFMUSTAT_PVIOL | MCF52XX_CFM_CFMUSTAT_ACCERR)) {
            _int_enable();
            return (FALSE);
        }
    }
    _int_enable();
    return (TRUE);  
}


/********************************************************************/
/*
 *  Code required to run in SRAM to perform flash commands. 
 *  All else can be run in flash.
 *  In p_reg we need address of CFMUSTAT register.
 *
 ********************************************************************/ 
static void mcf52xx_ram_function
(
    /* [IN] Flash info structure */
    volatile char_ptr cfmustat_ptr
)
{
      /* start flash write */
      *cfmustat_ptr |= MCF52XX_CFM_CFMUSTAT_CBEIF;   
      /* wait until execution complete */
      while (!( *cfmustat_ptr & MCF52XX_CFM_CFMUSTAT_CCIF)){
      };
}
       
          
static void mcf52xx_ram_function_end(void)
{}


<|start_filename|>Firmware/Inverter_bootloader/APP/flash_FTFL.c<|end_filename|>
/********************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
**************************************************************************/ /*!
  *
  * @file flash_FTFL.c
  *
  * @author
  *
  * @version
  *
  * @date
  *
  * @brief The file includes flash routines
  *
  *****************************************************************************/


#include "app_cfg.h"
#include <flash_FTFL.h> /* include flash driver header file */


/*******************************************************************************
 * Function:        Flash_Init
 *
 * Description:     Set the flash clock
 *
 * Returns:         none
 *
 * Notes:
 *
 *******************************************************************************/
void Flash_Init(void)
{

  /* checking access error */
  if ( FTFL_FSTAT & (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK | FTFL_FSTAT_RDCOLERR_MASK) )
  {
    /* clear error flag */
    FTFL_FSTAT |= (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK | FTFL_FSTAT_RDCOLERR_MASK);
  }
}

/*******************************************************************************
 * Function:        Flash_SectorErase
 *
 * Description:     erase a sector of the flash
 *
 * Returns:         Error Code
 *
 * Notes:
 *
 *******************************************************************************/
unsigned char Flash_SectorErase(INT32U addr)
{
  unsigned char ret = Flash_OK;

  /* Allocate space on stack to run flash command out of SRAM */
  /* wait till CCIF is set*/
  while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF_MASK))
  {;}

  /* Write command to FCCOB registers */
  FTFL_FCCOB0 = FLASH_CMD_SECTOR_ERASE;
  FTFL_FCCOB1 = (INT8U)(addr >> 16);
  FTFL_FCCOB2 = (INT8U)((addr >> 8) & 0xFF);
  FTFL_FCCOB3 = (INT8U)(addr & 0xFF);

  /* Launch command */
  SpSub();
  /* checking access error */
  if ( FTFL_FSTAT & FTFL_FSTAT_ACCERR_MASK )
  {
    /* clear error flag */
    FTFL_FSTAT |= FTFL_FSTAT_ACCERR_MASK;

    /* update return value*/
    ret |= Flash_FACCERR;
  }
  /* checking protection error */
  else if ( FTFL_FSTAT & FTFL_FSTAT_FPVIOL_MASK )
  {
    /* clear error flag */
    FTFL_FSTAT |= FTFL_FSTAT_FPVIOL_MASK;

    /* update return value*/
    ret |= Flash_FPVIOL;
  }
  else if ( FTFL_FSTAT & FTFL_FSTAT_RDCOLERR_MASK )
  {
    /* clear error flag */
    FTFL_FSTAT |= FTFL_FSTAT_RDCOLERR_MASK;

    /* update return value*/
    ret |= Flash_RDCOLERR;
  }
  /* checking MGSTAT0 non-correctable error */
  else if ( FTFL_FSTAT & FTFL_FSTAT_MGSTAT0_MASK )
  {
    ret |= Flash_MGSTAT0;
  }
  /* function return */
  return  ret;
}

/*******************************************************************************
 * Function:        Flash_ByteProgram
 *
 * Description:     byte program the flash
 *
 * Returns:         Error Code
 *
 * Notes:
 *
 *******************************************************************************/
unsigned char Flash_ByteProgram(INT32U addr, INT8U *buff, INT32U sz)
{
  unsigned char res = Flash_OK;
 
  INT32U size_buffer;

  if ( sz == 0 )
  {
    return Flash_CONTENTERR;
  }
  else
  {
    size_buffer = (sz - 1) / 4 + 1;
  }
  
  while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF_MASK))  /* wait till CCIF is set*/
  {;}

  while ((size_buffer) && (res == Flash_OK))
  {
    /*FSL: for FTFL, 4-byte aligned, for FTFE, 8 byte aligned!*/

    /* Write command to FCCOB registers */
    FTFL_FCCOB0 = FLASH_CMD_PROGR_LWORD;
    FTFL_FCCOB1 = (INT8U)(addr >> 16);
    FTFL_FCCOB2 = (INT8U)((addr >> 8) & 0xFF);
    FTFL_FCCOB3 = (INT8U)(addr & 0xFF);
    FTFL_FCCOB4 = (INT8U)(*(buff + 3));
    FTFL_FCCOB5 = (INT8U)(*(buff + 2));
    FTFL_FCCOB6 = (INT8U)(*(buff + 1));
    FTFL_FCCOB7 = (INT8U)(*(buff + 0));
    FTFE_FCCOB8 = (INT8U)(*(buff + 7));
    FTFE_FCCOB9 = (INT8U)(*(buff + 6));
    FTFE_FCCOBA = (INT8U)(*(buff + 5));
    FTFE_FCCOBB = (INT8U)(*(buff + 4));
    SpSub(); /* Launch command */

    
    if ( FTFL_FSTAT & FTFL_FSTAT_ACCERR_MASK )       /* checking access error */
    {
      FTFL_FSTAT |= FTFL_FSTAT_ACCERR_MASK;          /* clear error flag */
      res |= Flash_FACCERR;                          /* update return value*/
    }
    else if ( FTFL_FSTAT & FTFL_FSTAT_FPVIOL_MASK )  /* checking protection error */
    {
      FTFL_FSTAT |= FTFL_FSTAT_FPVIOL_MASK;          /* clear error flag */
      res |= Flash_FPVIOL;                           /* update return value*/
    }
    else if ( FTFL_FSTAT & FTFL_FSTAT_RDCOLERR_MASK )
    {
      FTFL_FSTAT |= FTFL_FSTAT_RDCOLERR_MASK;        /* clear error flag */
      res |= Flash_RDCOLERR;                         /* update return value*/
    }
    else if ( FTFL_FSTAT & FTFL_FSTAT_MGSTAT0_MASK ) /* checking MGSTAT0 non-correctable error */
    {
      res |= Flash_MGSTAT0;
    }
    
    size_buffer -= 2;  /* decrement byte count */
    buff += 8;
    addr += 8;
  }
  /* function return */
  return  res;
}

/*******************************************************************************
 * Function:        SpSub
 *
 * Description:     Execute the Flash write while running out of SRAM
 *
 * Returns:         none
 *
 * Notes:
 *
 *******************************************************************************/
__ramfunc void SpSub(void)
{
  /* Launch command */
  FTFL_FSTAT |= FTFL_FSTAT_CCIF_MASK;
  /* wait for command completion */
  while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF_MASK))
  {};
}



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/natevent.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: natevent.c$
* $Version : 3.6.3.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the NAT event management functions.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_event_add
* Returned Value  : void
* Comments        :
*     Insert a nat event into a nat event queue.
*
*END*-----------------------------------------------------------------*/

void NAT_event_add
   (
      TCPIP_EVENT_PTR         tcpip_event_ptr,         /* [IN] Controller event */
      NAT_EVENT_STRUCT_PTR    nat_event_ptr      /* [IN] NAT event to add */
   )
{ /* Body */
   NAT_EVENT_HEAD_PTR      nat_event_head_ptr = tcpip_event_ptr->PRIVATE;
   
   NAT_event_tick(tcpip_event_ptr, FALSE);
      
   /* We know the event will be placed at the end of the list */
   nat_event_ptr->TIME -= nat_event_head_ptr->TIMEDELTA;       
   nat_event_head_ptr->TIMEDELTA += nat_event_ptr->TIME;
   nat_event_ptr->NEXT = NULL;
   
   if (nat_event_head_ptr->FIRST) {      /* If there are already elements in list .. */
      nat_event_ptr->PREV = nat_event_head_ptr->LAST;
      nat_event_ptr->PREV->NEXT = nat_event_ptr;
      nat_event_head_ptr->LAST = nat_event_ptr;
      
   } else {
      nat_event_head_ptr->FIRST = nat_event_ptr;
      nat_event_head_ptr->LAST = nat_event_ptr;
      nat_event_ptr->PREV = NULL;
      tcpip_event_ptr->TIME = nat_event_ptr->TIME;
      TCPIP_Event_add(tcpip_event_ptr);
   } /* Endif */

   nat_event_ptr->EVENT = tcpip_event_ptr;
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_event_del
* Returned Value  : void
* Comments        :
*     Removes a nat event from its event queue.
*
*END*-----------------------------------------------------------------*/

void NAT_event_del
   (
      NAT_EVENT_STRUCT_PTR    nat_event_ptr   /* [IN] NAT event to del */
   )
{ /* Body */
   TCPIP_EVENT_PTR      tcpip_event_ptr = nat_event_ptr->EVENT;
   NAT_EVENT_HEAD_PTR   nat_event_head_ptr;
   
   if (tcpip_event_ptr == NULL) {  /* If the event isn't in any queue, return */
      return;
   } /* Endif */ 
   
   /* If event is already deleted return */
   if ((nat_event_ptr->NEXT == NULL) && (nat_event_ptr->PREV == NULL) && (nat_event_ptr->EVENT == NULL))
   {
	   return;
   }
   NAT_event_tick(tcpip_event_ptr, FALSE);
   nat_event_head_ptr = tcpip_event_ptr->PRIVATE;   
   
   if (nat_event_ptr == nat_event_head_ptr->FIRST) {        /* 1st in the queue */
      TCPIP_Event_cancel(tcpip_event_ptr);
      nat_event_head_ptr->FIRST = nat_event_ptr->NEXT;
      if (nat_event_head_ptr->FIRST != NULL) {          /* If there are other nodes */
         nat_event_head_ptr->FIRST->TIME += nat_event_ptr->TIME;
         tcpip_event_ptr->TIME = nat_event_head_ptr->FIRST->TIME;
         nat_event_head_ptr->FIRST->PREV = NULL;
         TCPIP_Event_add(tcpip_event_ptr);
      } else { 
         nat_event_head_ptr->TIMEDELTA = 0;
         nat_event_head_ptr->LAST = NULL;
      } /* Endif */
   } else {                                  /* Not first in the queue */
      
      if (nat_event_head_ptr->LAST != nat_event_ptr) {                 /* Not last in the queue */
         nat_event_ptr->NEXT->TIME += nat_event_ptr->TIME;
         nat_event_ptr->NEXT->PREV = nat_event_ptr->PREV;
      } else { 
         nat_event_head_ptr->TIMEDELTA -= nat_event_ptr->TIME;
         nat_event_head_ptr->LAST = nat_event_ptr->PREV;
      } /* Endif */
      
      nat_event_ptr->PREV->NEXT = nat_event_ptr->NEXT;
      
   } /* Endif */   
   
   nat_event_ptr->NEXT = NULL;
   nat_event_ptr->PREV = NULL;
   nat_event_ptr->EVENT = NULL;
 
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_expire
* Returned Value  : TRUE if more events are left on the queue, FALSE otherwise
* Comments        :
*        Frees the memory associated with a session.
*
*END*-----------------------------------------------------------------*/

boolean NAT_expire
   (
      TCPIP_EVENT_PTR   tcpip_event_ptr      /* [IN] Points to the event that expired */
   ) 
{ /* Body */
   NAT_EVENT_HEAD_PTR      nat_event_head_ptr = tcpip_event_ptr->PRIVATE;
   NAT_EVENT_STRUCT_PTR    tmp_nat_event_ptr, nat_event_ptr = nat_event_head_ptr->FIRST;
      
   NAT_event_tick(tcpip_event_ptr, TRUE);
   
   while (nat_event_ptr && nat_event_ptr->TIME == 0) {
      tmp_nat_event_ptr = nat_event_ptr->NEXT;
      
      /* De-thread node and delete session corresponding to node */
      if (tmp_nat_event_ptr) { 
         tmp_nat_event_ptr->PREV = NULL; 
      } /* Endbody */
      
      NAT_delete(nat_event_ptr->SESSION_PTR);
      
      nat_event_ptr = tmp_nat_event_ptr;
   } /* Endwhile */
   
   nat_event_head_ptr->FIRST = tmp_nat_event_ptr;
   
   if (tmp_nat_event_ptr) {
      tcpip_event_ptr->TIME = tmp_nat_event_ptr->TIME;
      return TRUE;
   } else {
      nat_event_head_ptr->LAST = NULL;
   } /* Endif */
   
   return FALSE;
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_event_tick
* Returned Value  : void
* Comments        :
*     Advances time. 
*
*END*-----------------------------------------------------------------*/

void NAT_event_tick
   (
      TCPIP_EVENT_PTR   tcpip_event_ptr,   /* [IN] Controlling event           */
      boolean           force    /* [IN] Force expiry of first event */
   )
{ /* Body */
   NAT_EVENT_HEAD_PTR   nat_event_head_ptr = tcpip_event_ptr->PRIVATE;
   uint_32              msec, elapsed;

   msec = RTCS_time_get();
   
   if (nat_event_head_ptr->FIRST) {
   
      if (force) {
         elapsed = nat_event_head_ptr->FIRST->TIME;   
      } else {
         elapsed = RTCS_timer_get_interval(nat_event_head_ptr->TIMESTAMP, msec); 
      } /* Endif */

      if (nat_event_head_ptr->FIRST->TIME <= elapsed) {
         nat_event_head_ptr->FIRST->TIME = 0;
      } else { 
         nat_event_head_ptr->FIRST->TIME -= elapsed;
      } /* Endif */
      
      if (nat_event_head_ptr->TIMEDELTA <= elapsed) {
         nat_event_head_ptr->TIMEDELTA = 0;
      } else { 
         nat_event_head_ptr->TIMEDELTA -= elapsed;
      } /* Endif */
      
   } /* Endif */
   
   nat_event_head_ptr->TIMESTAMP = msec;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_tout_max
* Returned Value  : void 
* Comments        :
*     Sets a maximum timeout for the NAT events in the specified queue. 
*     Any timeouts greater than the maximum will be set to the maximum.
*
*END*-----------------------------------------------------------------*/

void NAT_tout_max
   (
      TCPIP_EVENT_PTR   tcpip_event_ptr,    /* [IN] Event queue to update */
      uint_32           max      /* [IN] New maximum timeout for events in queue */
   )
{ /* Body */
   NAT_EVENT_HEAD_PTR   nat_event_head_ptr = tcpip_event_ptr->PRIVATE;
   NAT_EVENT_STRUCT_PTR nat_event_ptr;
   uint_32              total = 0;
   
   nat_event_ptr = nat_event_head_ptr->FIRST;
   
   /* If the queue is empty or does not exceed max, do nothing */
   if ((nat_event_ptr==NULL) || (nat_event_head_ptr->TIMEDELTA <= max)) {  
      return;
   } /* Endif */
   
   /* The time for the whole queue must be max or less */
   nat_event_head_ptr->TIMEDELTA = max;
   
   /* Do not modify events expiring in less than max */
   while (nat_event_ptr && total <= max) {
      total += nat_event_ptr->TIME;
      nat_event_ptr = nat_event_ptr->NEXT;
   } /* Endwhile */

   /* The event's timeout (if it exists) exceeds max. Fix it */
   if (nat_event_ptr) {
      nat_event_ptr->TIME -= (total - max);
      nat_event_ptr = nat_event_ptr->NEXT;
   } /* Endif */

   /* Set the remaining timeouts to 0, which is equal to a timeout of max */
   while (nat_event_ptr) { 
      nat_event_ptr->TIME = 0;
      nat_event_ptr = nat_event_ptr->NEXT;
   } /* Endwhile */
      
} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcscfg.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcscfg.h$
* $Version : 3.8.54.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   This file contains the definitions for configuring
*   optional features in RTCS.
*   RTCS is delivered as follows:
*   RTCSCFG_CHECK_ERRORS                   1
*   RTCSCFG_CHECK_MEMORY_ALLOCATION_ERRORS 1
*   RTCSCFG_CHECK_VALIDITY                 1
*   RTCSCFG_CHECK_ADDRSIZE                 1
*   RTCSCFG_IP_DISABLE_DIRECTED_BROADCAST  0
*   RTCSCFG_BOOTP_RETURN_YIADDR            0
*   RTCSCFG_UDP_ENABLE_LBOUND_MULTICAST    0  
*   RTCSCFG_LOG_SOCKET_API                 1
*   RTCSCFG_LOG_PCB                        1
*   RTCSCFG_LINKOPT_8023                   0
*   RTCSCFG_LINKOPT_8021Q_PRIO             0
*   RTCSCFG_DISCARD_SELF_BCASTS            1
*
*   RTCSCFG_LOGGING                        0
*
*END************************************************************************/

#ifndef __rtcscfg_h__
#define __rtcscfg_h__

/***************************************************************************
**
** Code and Data configuration options
** MGCT: <category name="Protocol and Features Options">
**
*/

/* 
** IPv6 Protocol
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IP6
   #define RTCSCFG_ENABLE_IP6		0
#endif

/* 
** IPv4 Protocol
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IP4
   #define RTCSCFG_ENABLE_IP4		1
#endif


/*
** Global setting to reduce RTCS memory requirements. This affects lot of
** other settings.
**
** MGCT: <option type="bool"/>
*/
#ifndef RTCS_MINIMUM_FOOTPRINT
    #define RTCS_MINIMUM_FOOTPRINT 0
#endif

/* 
** ICMPv4 Protocol
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_ICMP
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_ICMP 0
    #else
        #define RTCSCFG_ENABLE_ICMP 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IGMP
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_IGMP 0
    #else
        #define RTCSCFG_ENABLE_IGMP 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_NAT
   #define RTCSCFG_ENABLE_NAT  0 
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_DNS
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_DNS 0
    #else
        #define RTCSCFG_ENABLE_DNS 1
    #endif
#endif

#if RTCSCFG_ENABLE_DNS == 1
    #ifdef RTCSCFG_ENABLE_LOOPBACK
        #undef  RTCSCFG_ENABLE_LOOPBACK      
    #endif
    #define RTCSCFG_ENABLE_LOOPBACK 1
    #ifdef RTCSCFG_ENABLE_LWDNS
        #undef  RTCSCFG_ENABLE_LWDNS
    #endif
    #define RTCSCFG_ENABLE_LWDNS 0
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_LWDNS
   #define RTCSCFG_ENABLE_LWDNS  1 
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IPSEC
   #define RTCSCFG_ENABLE_IPSEC 0
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IPIP
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_IPIP 0
    #else
        #define RTCSCFG_ENABLE_IPIP 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_RIP
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_RIP  0
    #else
        #define RTCSCFG_ENABLE_RIP  1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_OSPF
   #define RTCSCFG_ENABLE_OSPF 0
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_SNMP
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_SNMP 0
    #else
        #define RTCSCFG_ENABLE_SNMP 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IP_REASSEMBLY
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_IP_REASSEMBLY 0
    #else
        #define RTCSCFG_ENABLE_IP_REASSEMBLY 1
    #endif 
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_LOOPBACK
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_LOOPBACK 0
    #else
        #define RTCSCFG_ENABLE_LOOPBACK 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_UDP
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_UDP 0
    #else
        #define RTCSCFG_ENABLE_UDP 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_TCP
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_TCP 0
    #else
        #define RTCSCFG_ENABLE_TCP 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_STATS
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_STATS 0
    #else
        #define RTCSCFG_ENABLE_STATS 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_GATEWAYS
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_GATEWAYS 0
    #else
        #define RTCSCFG_ENABLE_GATEWAYS 1
    #endif
#endif

/*
** Note: must be true for PPP or tunneling
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_VIRTUAL_ROUTES
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_ENABLE_VIRTUAL_ROUTES 0
    #else
        #define RTCSCFG_ENABLE_VIRTUAL_ROUTES 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_USE_KISS_RNG 
   #define RTCSCFG_USE_KISS_RNG 0
#endif

/* MGCT: </category> */

/***************************************************************************
**
** Error Checking options
** 
** MGCT: <category name="Error Checking Options">
**
****************************************************************************/

/*
** When RTCSCFG_CHECK_ERRORS is 1, RTCS API functions will perform
** error checking on its input parameters and also some other.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_CHECK_ERRORS
   #define RTCSCFG_CHECK_ERRORS 1
#endif

/*
** When RTCSCFG_CHECK_MEMORY_ALLOCATION_ERRORS is 1, RTCS API functions
** will perform error checking on memory allocation.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_CHECK_MEMORY_ALLOCATION_ERRORS
   #define RTCSCFG_CHECK_MEMORY_ALLOCATION_ERRORS 1
#endif

/*
** When RTCSCFG_CHECK_VALIDITY is 1, RTCS will check the VALID field
** in internal structures before accessing them.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_CHECK_VALIDITY
   #define RTCSCFG_CHECK_VALIDITY 1
#endif

/*
** When RTCSCFG_CHECK_ADDRSIZE is 1, RTCS will check whether addrlen
** is at least sizeof(sockaddr_in) in functions that take a struct
** sockaddr _PTR_ parameter.  If not, RTCS returns an error (for bind(),
** connect() and sendto()) or does a partial copy (for accept(),
** getsockname(), getpeername() and recvfrom()).
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_CHECK_ADDRSIZE
   #define RTCSCFG_CHECK_ADDRSIZE 1
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** PCB Configuration options
**
** MGCT: <category name="PCB Configuration Options">
**
*/

/*
** Override in application by setting _RTCSPCB_max
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_PCBS_INIT
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_PCBS_INIT 4
   #else
      #define RTCSCFG_PCBS_INIT 32
   #endif
#endif

/*
** Override in application by setting _RTCSPCB_max
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_PCBS_GROW
   #define RTCSCFG_PCBS_GROW 0 
#endif

/*
** Override in application by setting _RTCSPCB_max
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef RTCSCFG_PCBS_MAX
   #define RTCSCFG_PCBS_MAX RTCSCFG_PCBS_INIT 
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** Socket Configuration options
**
** MGCT: <category name="Socket Configuration Options">
**
*/

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_SOCKET_OWNERSHIP
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_SOCKET_OWNERSHIP 0
    #else
        #define RTCSCFG_SOCKET_OWNERSHIP 1
    #endif
#endif

/*
** Number of blocks allocated for sockets
** Override in application by setting _RTCS_socket_part_init
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_SOCKET_PART_INIT
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_SOCKET_PART_INIT 3 
   #else
      #define RTCSCFG_SOCKET_PART_INIT 20
   #endif
#endif

/*
** Override in application by setting _RTCS_socket_part_grow
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_SOCKET_PART_GROW
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_SOCKET_PART_GROW 0 
   #else
      #define RTCSCFG_SOCKET_PART_GROW 20
   #endif
#endif

/*
** Override in application by setting _RTCS_socket_part_limit
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef RTCSCFG_SOCKET_PART_MAX
   #define RTCSCFG_SOCKET_PART_MAX RTCSCFG_SOCKET_PART_INIT 
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** RTCS Message Configuration options
**
** MGCT: <category name="RTCS Task and Message Options">
**
*/

/*
** Override in application by setting _RTCS_msgpool_init
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_MSGPOOL_INIT
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_MSGPOOL_INIT 8 
   #else
      #define RTCSCFG_MSGPOOL_INIT 32
   #endif
#endif

/*
** Override in application by setting _RTCS_msgpool_grow
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_MSGPOOL_GROW
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_MSGPOOL_GROW 2 
   #else
      #define RTCSCFG_MSGPOOL_GROW 16
   #endif
#endif

/*
** Override in application by setting _RTCS_msgpool_limit
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef RTCSCFG_MSGPOOL_MAX
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_MSGPOOL_MAX RTCSCFG_MSGPOOL_INIT 
   #else
      #define RTCSCFG_MSGPOOL_MAX 160
   #endif
#endif

/* MGCT: </category> */

/***************************************************************************
**
** Link Layer options
**
** MGCT: <category name="Link Layer Options">
**
*/

/*
** RTCSCFG_LINKOPT_8023 enables support for sending and receiving
** 802.3 frames.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_LINKOPT_8023
   #define RTCSCFG_LINKOPT_8023 0
#endif

/*
** RTCSCFG_LINKOPT_8021Q_PRIO enables support for sending and receiving
** 802.1Q priority tags.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_LINKOPT_8021Q_PRIO
   #define RTCSCFG_LINKOPT_8021Q_PRIO 0
#endif

/* 
** RTCSCFG_DISCARD_SELF_BCASTS controls whether or not to discard all 
** broadcast pkts that we sent, as they are likely echoes from older 
** hubs
** MGCT: <option type="bool"/>
*/ 
#ifndef RTCSCFG_DISCARD_SELF_BCASTS
   #define RTCSCFG_DISCARD_SELF_BCASTS 1
#endif

/* MGCT: </category> */


/***************************************************************************
** 
** ARP Configuration options
**
** MGCT: <category name="ARP Configuration Options">
**
*/

/*
** ARP cache hash table size
** MGCT: <option type="number"/>
*/
#ifndef ARPCACHE_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define ARPCACHE_SIZE 2
   #else
      #define ARPCACHE_SIZE 16
   #endif
#endif

/*
** Allocation blocks for ARP cache entries
** MGCT: <option type="number"/>
*/
#ifndef ARPALLOC_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define ARPALLOC_SIZE 2 
   #else
      #define ARPALLOC_SIZE 16
   #endif
#endif

/*
** ARP cache entry longevity (in milliseconds)
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_ARPTIME_RESEND_MIN
    #define RTCSCFG_ARPTIME_RESEND_MIN             5000     /*  5 sec */
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_ARPTIME_RESEND_MAX  
    #define RTCSCFG_ARPTIME_RESEND_MAX            30000     /* 30 sec */
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_ARPTIME_EXPIRE_INCOMPLETE
    #define RTCSCFG_ARPTIME_EXPIRE_INCOMPLETE    180000L    /*  3 min */
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_ARPTIME_EXPIRE_COMPLETE
    #define RTCSCFG_ARPTIME_EXPIRE_COMPLETE     1200000L    /* 20 min */
#endif

/*
** Number of PCBs queued on an outstanding ARP
** Per RFC, Minimum recommended is 1.
** When sending large UDP packets, which will result 
** in IP fragmentations, set to at least the largest number of 
** fragments
** MGCT: <option type="number"/>
*/
#ifndef ARP_ENTRY_MAX_QUEUED_PCBS
    #define ARP_ENTRY_MAX_QUEUED_PCBS 1 
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_ARP_STATS
    #if RTCSCFG_ENABLE_STATS
        #define RTCSCFG_ENABLE_ARP_STATS 1
    #else
        #define RTCSCFG_ENABLE_ARP_STATS 0
    #endif
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** IPv4 Configuration options
**
** MGCT: <category name="IPv4 Configuration Options">
**
*/

/*
** MGCT: <option type="number"/>
*/
#ifndef IPIFALLOC_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define IPIFALLOC_SIZE 2 
   #else
      #define IPIFALLOC_SIZE 4
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef IPROUTEALLOC_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define IPROUTEALLOC_SIZE 2 
   #else
      #define IPROUTEALLOC_SIZE 4
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef IPGATEALLOC_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define IPGATEALLOC_SIZE 1 
   #else
      #define IPGATEALLOC_SIZE 4
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef IPMCBALLOC_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define IPMCBALLOC_SIZE 1 
   #else
      #define IPMCBALLOC_SIZE 4
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef RADIXALLOC_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define RADIXALLOC_SIZE 2 
   #else
      #define RADIXALLOC_SIZE 4
   #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IP_STATS
    #if RTCSCFG_ENABLE_STATS
        #define RTCSCFG_ENABLE_IP_STATS 1
    #else
        #define RTCSCFG_ENABLE_IP_STATS 0
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_ICMP_STATS
    #if (RTCSCFG_ENABLE_STATS & RTCSCFG_ENABLE_ICMP)
        #define RTCSCFG_ENABLE_ICMP_STATS 1
    #else
        #define RTCSCFG_ENABLE_ICMP_STATS 0
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IPIF_STATS
    #if RTCSCFG_ENABLE_STATS
        #define RTCSCFG_ENABLE_IPIF_STATS 1
    #else
        #define RTCSCFG_ENABLE_IPIF_STATS 0
    #endif
#endif

#ifndef RTCSCFG_ENABLE_ICMP6_STATS
   #define RTCSCFG_ENABLE_ICMP6_STATS RTCSCFG_ENABLE_STATS
#endif

/* MGCT: </category> */


/***************************************************************************
** 
** IGMP Configuration options
**
** MGCT: <category name="IGMP Configuration Options">
**
*/

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IGMP_STATS
    #if (RTCSCFG_ENABLE_STATS & RTCSCFG_ENABLE_IGMP)
        #define RTCSCFG_ENABLE_IGMP_STATS 1
    #else
        #define RTCSCFG_ENABLE_IGMP_STATS 0
    #endif
#endif

#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   #ifdef BSP_ENET_DEVICE_COUNT
   #if  (BSP_ENET_DEVICE_COUNT > 0) 
      #if !(BSPCFG_ENABLE_ENET_MULTICAST)
         #error RTCS IGMP uses ENET Multicast.  Enable BSPCFG_ENABLE_ENET_MULTICAST or disable RTCSCFG_ENABLE_IGMP in user_config.h
      #endif
   #endif
   #endif
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** UDP Configuration options
**
** MGCT: <category name="UDP Configuration Options">
**
*/

/*
** Override in application by setting _UDP_max_queue_size
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef RTCSCFG_UDP_MAX_QUEUE_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_UDP_MAX_QUEUE_SIZE 1 
   #else
      #define RTCSCFG_UDP_MAX_QUEUE_SIZE (RTCSCFG_PCBS_MAX/2)
   #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_UDP_STATS
    #if (RTCSCFG_ENABLE_STATS & RTCSCFG_ENABLE_UDP)
        #define RTCSCFG_ENABLE_UDP_STATS 1
    #else
        #define RTCSCFG_ENABLE_UDP_STATS 0
    #endif
#endif


/* MGCT: </category> */

/***************************************************************************
** 
** TCP Configuration options
**
** MGCT: <category name="TCP Configuration Options">
**
*/

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_TCP_STATS
    #if (RTCSCFG_ENABLE_STATS & RTCSCFG_ENABLE_TCP)
        #define RTCSCFG_ENABLE_TCP_STATS 1
    #else
        #define RTCSCFG_ENABLE_TCP_STATS 0
    #endif
#endif

/*
** Maximum number of simultaneous connections allowed.  Define as 0 for no limit.
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_TCP_MAX_CONNECTIONS
   #define RTCSCFG_TCP_MAX_CONNECTIONS      0  
#endif

/*
** Maximum number of simultaneoushalf open connections allowed.
** Define as 0 to disable the SYN attack recovery feature. 
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_TCP_MAX_HALF_OPEN
   #define RTCSCFG_TCP_MAX_HALF_OPEN        0  
#endif

#ifndef RTCSCFG_TCP_ACKDELAY
    #define TCP_ACKDELAY                    1 
#else
    #if RTCSCFG_TCP_ACKDELAY > 500   /* Max ack delay, as per RFC1122 */
        #define TCP_ACKDELAY                500
    #else
        #define TCP_ACKDELAY                RTCSCFG_TCP_ACKDELAY
    #endif
#endif

/* MGCT: </category> */


/***************************************************************************
** 
** RIP Configuration options
**
** MGCT: <category name="RIP Configuration options">
**
*/

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_RIP_STATS
    #if RTCSCFG_ENABLE_STATS
        #define RTCSCFG_ENABLE_RIP_STATS 1
    #else
        #define RTCSCFG_ENABLE_RIP_STATS 0
    #endif
#endif

#if RTCSCFG_ENABLE_RIP
   #if !(RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4) 
      #error RIP uses IGMP.  Enable RTCSCFG_ENABLE_IGMP or disable RTCSCFG_ENABLE_RIP in user_config.h
   #endif
#endif

/* MGCT: </category> */

/***************************************************************************
**
** Protocol behaviour options
**
** MGCT: <category name="Protocol Behaviour Options">
**
*/

/*
** RTCSCFG_IP_DISABLE_DIRECTED_BROADCAST disables the reception and
** forwarding of directed broadcast datagrams.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_IP_DISABLE_DIRECTED_BROADCAST
   #define RTCSCFG_IP_DISABLE_DIRECTED_BROADCAST 1
#endif

/*
** When RTCSCFG_BOOTP_RETURN_YIADDR is 1, the BOOTP_DATA_STRUCT has
** an additional field, which will be filled in with the YIADDR field
** of the BOOTREPLY.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_BOOTP_RETURN_YIADDR
   #define RTCSCFG_BOOTP_RETURN_YIADDR 0
#endif

/*
** When RTCSCFG_UDP_ENABLE_LBOUND_MULTICAST is 1, locally bound sockets
** that are members of multicast groups will be able to receive messages
** sent to both their unicast and multicast addresses.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_UDP_ENABLE_LBOUND_MULTICAST
   #define RTCSCFG_UDP_ENABLE_LBOUND_MULTICAST 0
#endif

/* MGCT: </category> */


/***************************************************************************
** 
** RTCS Configuration options
**
** MGCT: <category name="RTCS Configuration Options">
**
*/

/*
** Using a lower queue base requires fewer MQX resources
** Override in application by setting _RTCSQUEUE_base
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_QUEUE_BASE
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_QUEUE_BASE 2 
   #else
      #define RTCSCFG_QUEUE_BASE 0x10
   #endif
#endif

/*
** Override in application by setting _RTCSTASK_stacksize
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef RTCSCFG_STACK_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define RTCSCFG_STACK_SIZE (750*sizeof(uint_32)) 
   #else
      #define RTCSCFG_STACK_SIZE (1000*sizeof(uint_32))
   #endif
#endif

/* MGCT: </category> */

/***************************************************************************
**
** Logging options
**
** MGCT: <category name="Logging Options">
**
*/

/*
** Enable RTCS logging functionality
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_LOGGING
    #define RTCSCFG_LOGGING 0
#endif

/*
** When RTCSCFG_LOG_SOCKET_API is 1, RTCS will call RTCS_log() on
** every socket API entry and exit.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_LOG_SOCKET_API
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_LOG_SOCKET_API 0
    #else
        #define RTCSCFG_LOG_SOCKET_API 1
    #endif
#endif

/*
** When RTCSCFG_LOG_PCB is 1, RTCS will call RTCS_log() every time
** a PCB is allocated, freed, or passed between two layers.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_LOG_PCB
    #if RTCS_MINIMUM_FOOTPRINT
        #define RTCSCFG_LOG_PCB 0
    #else
        #define RTCSCFG_LOG_PCB 1
    #endif
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** IPCFG Configuration options
**
** MGCT: <category name="IPCFG API Configuration Options">
**
*/

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_IPCFG_ENABLE_DNS
    #if (RTCSCFG_ENABLE_DNS & RTCSCFG_ENABLE_UDP) | (RTCSCFG_ENABLE_LWDNS)
        #define RTCSCFG_IPCFG_ENABLE_DNS 1
    #else
        #define RTCSCFG_IPCFG_ENABLE_DNS 0
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_IPCFG_ENABLE_DHCP
    #if RTCSCFG_ENABLE_UDP
        #define RTCSCFG_IPCFG_ENABLE_DHCP 1
    #else
        #define RTCSCFG_IPCFG_ENABLE_DHCP 0
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_IPCFG_ENABLE_BOOT
    #define RTCSCFG_IPCFG_ENABLE_BOOT 0
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_USE_MQX_PARTITIONS
    #define RTCSCFG_USE_MQX_PARTITIONS 1
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_USE_INTERNAL_PARTITIONS
    #if RTCSCFG_USE_MQX_PARTITIONS
        #define RTCSCFG_USE_INTERNAL_PARTITIONS 0
    #else
        #define RTCSCFG_USE_INTERNAL_PARTITIONS 1
    #endif
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** FTP Client Configuration options
**
** MGCT: <category name="FTP Client Configuration Options">
**
*/

/*
** Enabled means better performance for files less than 4MB
** MGCT: <option type="bool"/>
*/
#ifndef FTPCCFG_SMALL_FILE_PERFORMANCE_ENHANCEMENT
   #define FTPCCFG_SMALL_FILE_PERFORMANCE_ENHANCEMENT 1 
#endif

/*
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#define FTPCCFG_BUFFER_SIZE 256

/*
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef FTPCCFG_WINDOW_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define FTPCCFG_WINDOW_SIZE 536 
   #else
      #define FTPCCFG_WINDOW_SIZE (3*1460)  
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef FTPCCFG_TIMEWAIT_TIMEOUT
   #define FTPCCFG_TIMEWAIT_TIMEOUT 1000
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** FTP Server Configuration options
**
** MGCT: <category name="FTP Server Configuration Options">
**
*/

/*
** must be one of FLAG_ABORT_CONNECTION or FLAG_CLOSE_TX
** MGCT: <option type="list">
** <item name="FLAG_ABORT_CONNECTION" value="FLAG_ABORT_CONNECTION"/>
** <item name="FLAG_CLOSE_TX" value="FLAG_CLOSE_TX"/>
** </option>
*/
#ifndef FTPDCFG_SHUTDOWN_OPTION
   #define FTPDCFG_SHUTDOWN_OPTION FLAG_ABORT_CONNECTION  
#endif

/*
** MGCT: <option type="list">
** <item name="FLAG_ABORT_CONNECTION" value="FLAG_ABORT_CONNECTION"/>
** <item name="FLAG_CLOSE_TX" value="FLAG_CLOSE_TX"/>
** </option>
*/
#ifndef FTPDCFG_DATA_SHUTDOWN_OPTION
   #define FTPDCFG_DATA_SHUTDOWN_OPTION FLAG_CLOSE_TX  
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef FTPDCFG_USES_MFS
   #if RTCS_MINIMUM_FOOTPRINT
      #define FTPDCFG_USES_MFS 0 
   #else
      #define FTPDCFG_USES_MFS 1
   #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef FTPDCFG_ENABLE_MULTIPLE_CLIENTS
    #if RTCS_MINIMUM_FOOTPRINT
        #define FTPDCFG_ENABLE_MULTIPLE_CLIENTS 0
    #else
        #define FTPDCFG_ENABLE_MULTIPLE_CLIENTS 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
    #if RTCS_MINIMUM_FOOTPRINT
        #define FTPDCFG_ENABLE_USERNAME_AND_PASSWORD 0
    #else
        #define FTPDCFG_ENABLE_USERNAME_AND_PASSWORD 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef FTPDCFG_ENABLE_RENAME
   #define FTPDCFG_ENABLE_RENAME 1//!RTCS_MINIMUM_FOOTPRINT 
#endif

/*
** Should be a multiple of maximum packet size
** Override in application by setting FTPd_window_size
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef FTPDCFG_WINDOW_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define FTPDCFG_WINDOW_SIZE 536 
   #else
      #define FTPDCFG_WINDOW_SIZE (6*1460)  
   #endif
#endif

/*
** Should be a multiple of sector size
** Override in application by setting FTPd_buffer_size
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef FTPDCFG_BUFFER_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define FTPDCFG_BUFFER_SIZE 512 
   #else
      #define FTPDCFG_BUFFER_SIZE 2048  
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef FTPDCFG_CONNECT_TIMEOUT
   #define FTPDCFG_CONNECT_TIMEOUT 1000 
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef FTPDCFG_SEND_TIMEOUT
   #define FTPDCFG_SEND_TIMEOUT 5000 
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef FTPDCFG_TIMEWAIT_TIMEOUT
   #define FTPDCFG_TIMEWAIT_TIMEOUT 500 
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** Telnet Configuration options
**
** MGCT: <category name="Telnet Configuration Options">
**
*/

/*
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef TELNETDCFG_BUFFER_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define TELNETDCFG_BUFFER_SIZE 256 
   #else
      #define TELNETDCFG_BUFFER_SIZE (3*1460)  
   #endif
#endif

/*
** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/>
*/
#ifndef TELNETDCFG_NOWAIT
   #define TELNETDCFG_NOWAIT FALSE 
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef TELNETDCFG_ENABLE_MULTIPLE_CLIENTS
    #if RTCS_MINIMUM_FOOTPRINT
        #define TELNETDCFG_ENABLE_MULTIPLE_CLIENTS 0
    #else
        #define TELNETDCFG_ENABLE_MULTIPLE_CLIENTS 1
    #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef TELENETDCFG_CONNECT_TIMEOUT
   #define TELENETDCFG_CONNECT_TIMEOUT 1000 
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef TELENETDCFG_SEND_TIMEOUT
   #define TELENETDCFG_SEND_TIMEOUT 5000 
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef TELENETDCFG_TIMEWAIT_TIMEOUT
   #define TELENETDCFG_TIMEWAIT_TIMEOUT 1000 
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** SNMP Configuration options
**
** MGCT: <category name="SNMP Configuration Options">
**
*/

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_SNMP_STATS
    #if RTCSCFG_ENABLE_STATS
        #define RTCSCFG_ENABLE_SNMP_STATS 1
    #else
        #define RTCSCFG_ENABLE_SNMP_STATS 0
    #endif
#endif

/* MGCT: </category> */

/***************************************************************************
** 
** PPPHDLC Message Configuration options
**
** MGCT: <category name="PPPHDLC Message Configuration Options">
**
*/

/*
** MGCT: <option type="number"/>
*/
#ifndef PPPHDLC_INIT
   #if RTCS_MINIMUM_FOOTPRINT
      #define PPPHDLC_INIT 1 
   #else
      #define PPPHDLC_INIT 8
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef PPPHDLC_GROW
   #if RTCS_MINIMUM_FOOTPRINT
      #define PPPHDLC_GROW 1 
   #else
      #define PPPHDLC_GROW 0
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef PPPHDLC_MAX
   #if RTCS_MINIMUM_FOOTPRINT
      #define PPPHDLC_MAX 6 //2
   #else
      #define PPPHDLC_MAX 8
   #endif
#endif


/* MGCT: </category> */

/*
** MGCT: <category name="HTTPD Configuration Options">
*/

/*
** MGCT: <option type="bool"/>
*/
#ifndef HTTPDCFG_POLL_MODE
    #if RTCS_MINIMUM_FOOTPRINT
        #define HTTPDCFG_POLL_MODE              1
    #else
        #define HTTPDCFG_POLL_MODE              0
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef HTTPDCFG_STATIC_TASKS
#define HTTPDCFG_STATIC_TASKS           0
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef HTTPDCFG_DYNAMIC_TASKS
    #if RTCS_MINIMUM_FOOTPRINT
        #define HTTPDCFG_DYNAMIC_TASKS          0
    #else
        #define HTTPDCFG_DYNAMIC_TASKS          1
    #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_DEF_SERVER_PRIO
#define HTTPDCFG_DEF_SERVER_PRIO    (8)
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_DEF_SESSION_PRIO
#define HTTPDCFG_DEF_SESSION_PRIO   (8)
#endif

/*
** Default listen address
** MGCT: <option type="string"/>
*/
#ifndef HTTPDCFG_DEF_ADDR
#define HTTPDCFG_DEF_ADDR               INADDR_ANY
#endif

/*
** Default listen port
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_DEF_PORT
#define HTTPDCFG_DEF_PORT               80
#endif

/*
** MGCT: <option type="string" quoted="true"/>
*/
#ifndef HTTPDCFG_DEF_INDEX_PAGE
#define HTTPDCFG_DEF_INDEX_PAGE         "index.htm"
#endif

/*
** Default sessions count
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_DEF_SES_CNT
#define HTTPDCFG_DEF_SES_CNT            2 
#endif

/*
** Maximal URL length
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_DEF_URL_LEN
#define HTTPDCFG_DEF_URL_LEN            128 
#endif

/*
** Maximal length for auth data
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_DEF_AUTH_LEN
#define HTTPDCFG_DEF_AUTH_LEN           16
#endif

/*
** Maximal send data size in one step
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_MAX_BYTES_TO_SEND
#define HTTPDCFG_MAX_BYTES_TO_SEND      (512)
#endif

/*
** Maximal length for script line
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_MAX_SCRIPT_LN
#define HTTPDCFG_MAX_SCRIPT_LN          16
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_RECV_BUF_LEN
#define HTTPDCFG_RECV_BUF_LEN           32
#endif

/* 
** Default buffer configuration
** MGCT: <option type="number"/>
*/
#ifndef HTTPD_MAX_LEN
#define HTTPD_MAX_LEN                   128
#endif

/*
** Maximal length for http header
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_MAX_HEADER_LEN
#define HTTPDCFG_MAX_HEADER_LEN         256
#endif

/*
** Session timeout in milliseconds
** MGCT: <option type="number"/>
*/
#ifndef HTTPDCFG_SES_TO
#define HTTPDCFG_SES_TO                 (20000)
#endif

/*
** Request Timeout in milliseconds
** MGCT: <option type="number"/>
*/
#ifndef HTTPD_TIMEOUT_REQ_MS
#define HTTPD_TIMEOUT_REQ_MS            (4000)
#endif

/*
** Send Timeout in milliseconds
** MGCT: <option type="number"/>
*/
#ifndef HTTPD_TIMEOUT_SEND_MS
#define HTTPD_TIMEOUT_SEND_MS           (8000)
#endif

/* 
** Socket settings
** MGCT: <option type="string"/>
*/
#ifndef HTTPCFG_TX_WINDOW_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define HTTPCFG_TX_WINDOW_SIZE    (1460) 
   #else
      #define HTTPCFG_TX_WINDOW_SIZE    (3*1460) 
   #endif
#endif

/* 
** Socket settings
** MGCT: <option type="string"/>
*/
#ifndef HTTPCFG_RX_WINDOW_SIZE
   #if RTCS_MINIMUM_FOOTPRINT
      #define HTTPCFG_RX_WINDOW_SIZE    (1460) 
   #else
      #define HTTPCFG_RX_WINDOW_SIZE    (3*1460) 
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef HTTPCFG_TIMEWAIT_TIMEOUT
   #define HTTPCFG_TIMEWAIT_TIMEOUT     1000 
#endif

/* 
** Default inet family configuration
** MGCT: <option type="string"/>
*/
#ifndef HTTPDCFG_AF
   #define HTTPDCFG_AF        			AF_INET
#endif


/* MGCT: </category> */
#endif


/*
** MGCT: <category name="IPv6 Specific Options">
*/

/* Multicast MUST be enabled for IPv6.*/
#if RTCSCFG_ENABLE_IP6
   #undef BSPCFG_ENABLE_ENET_MULTICAST
   #define BSPCFG_ENABLE_ENET_MULTICAST            (1)
#endif //RTCSCFG_ENABLE_IP6

/*
** Maximum number of entries in neighbor cache.
** NOTE: A small cache may result in an
** excessive number of Neighbor Discovery messages if entries are
** discarded and rebuilt in quick succession.
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_ND6_NEIGHBOR_CACHE_SIZE
   #define RTCSCFG_ND6_NEIGHBOR_CACHE_SIZE      (5) 
#endif

/*
** Maximum number of entries in the Prefix list (per interface).
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_ND6_PREFIX_LIST_SIZE
    #define RTCSCFG_ND6_PREFIX_LIST_SIZE        (4) 
#endif


/*
** Maximum number of entries in the Default Router list (per interface).
** RFC4861: A host MUST retain at least two router
** addresses and SHOULD retain more.
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_ND6_ROUTER_LIST_SIZE
    #define RTCSCFG_ND6_ROUTER_LIST_SIZE        (2)
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_ENABLE_IP6_REASSEMBLY
   #define RTCSCFG_ENABLE_IP6_REASSEMBLY        1 
#endif

/*
** Maximum number of IPv6 addresses per interface.
** MGCT: <option type="number"/>
*/
#define RTCSCFG_IP6_IF_ADDRESSES_MAX            (5) 

#if RTCSCFG_IP6_IF_ADDRESSES_MAX < 2                                                 
    #undef RTCSCFG_IP6_IF_ADDRESSES_MAX
    #define RTCSCFG_IP6_IF_ADDRESSES_MAX        (2)
#endif

/*
** Loopback of own multicast packets.
** MGCT: <option type="bool"/>
*/
#ifndef RTCSCFG_IP6_LOOPBACK_MULTICAST
    #define RTCSCFG_IP6_LOOPBACK_MULTICAST      (0)
#endif


/* Check minimum values.*/
#if RTCSCFG_ND6_ROUTER_LIST_SIZE < 1 
    #error RTCSCFG_ND6_ROUTER_LIST_SIZE should be > 0
#endif
#if RTCSCFG_ND6_NEIGHBOR_CACHE_SIZE  < 1
    #error RTCSCFG_ND6_NEIGHBOR_CACHE_SIZE should be > 0
#endif
#if RTCSCFG_ND6_PREFIX_LIST_SIZE < 1 
    #error RTCSCFG_ND6_PREFIX_LIST_SIZE should be > 0
#endif

/*
** The number of consecutive Neighbor
** Solicitation messages sent while performing Duplicate Address
** Detection on a tentative address. A value of zero indicates that
** Duplicate Address Detection is not performed on tentative
** addresses. A value of one indicates a single transmission with no
** follow-up retransmissions.
** MGCT: <option type="number"/>
*/
#ifndef RTCSCFG_ND6_DAD_TRANSMITS 
    #define RTCSCFG_ND6_DAD_TRANSMITS           (1) /* If RTCSCFG_ND6_DAD_TRANSMITS = 0, the DAD is disabled.*/
#endif    


/* For Debug usage only.*/
#ifndef RTCSCFG_DEBUG_TRACE_ETH
   #define RTCSCFG_DEBUG_TRACE_ETH              (0)
#endif
#ifndef RTCSCFG_DEBUG_TRACE_IP6
   #define RTCSCFG_DEBUG_TRACE_IP6              (0)
#endif
#ifndef RTCSCFG_DEBUG_TRACE_ICMP6
   #define RTCSCFG_DEBUG_TRACE_ICMP6            (0)
#endif
#ifndef RTCSCFG_DEBUG_MSG
   #define RTCSCFG_DEBUG_MSG                    (0)
#endif

/* MGCT: </category> */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/tcpip.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcpip.c$
* $Version : 3.8.10.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   This is the main task for the TCP/IP protocol suite.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "ticker.h"
#include "tcpip.h"
#include "arp.h"


uint_32 (_CODE_PTR_ TCP_tick)(void);

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCPIP_fake_tick
* Returned Value  : 0
* Comments        :
*
*  The fake TCP_Tick_server(), used when TCP is not installed.
*
*END*-----------------------------------------------------------------*/

static uint_32 TCPIP_fake_tick
   (
      void
   )
{ /* Body */
   return 0;
} /* Endbody */

/*TASK*------------------------------------------------------------------
*
* Task Name      :   TCPIP_task
* Comments       :
*     This task services requests from the socket layer and the
*     application, and services incoming packets from the link layer(s).
*
*END*------------------------------------------------------------------*/

void TCPIP_task
   (
      pointer  dummy,
      pointer  creator
   )
{ /* Body */
   TCPIP_CFG_STRUCT           TCPIP_cfg;
   RTCS_DATA_PTR              RTCS_data_ptr;
   uint_32                    i;
   TCPIP_MESSAGE_PTR          tcpip_msg;
   uint_32                    timeout = 1, timebefore, timeafter, timedelta;
   uint_32                    status;           /* Return status */
   _queue_id                  tcpip_qid;
   
    RTCSLOG_FNE2(RTCSLOG_FN_TCPIP_task, creator);

   RTCS_data_ptr = RTCS_get_data();
   RTCS_setcfg(TCPIP, &TCPIP_cfg);

   TCPIP_cfg.status = RTCS_OK;

   tcpip_qid = RTCS_msgq_open(TCPIP_QUEUE, 0);
   if (tcpip_qid == 0) {
      RTCS_task_exit(creator, RTCSERR_OPEN_QUEUE_FAILED);
   } /* Endif */

   RTCS_data_ptr->TCPIP_TASKID = RTCS_task_getid();

   /*
   ** Initialize the Time Service
   */
   TCP_tick = TCPIP_fake_tick;
   TCPIP_Event_init();
   timebefore = RTCS_time_get();

   /*
   ** Allocate a block of PCBs
   */
   status = RTCSPCB_init();
   if (status != RTCS_OK) {
      RTCS_task_exit(creator, status);
   } /* Endif */
    
    IF_FREE       = NULL;
    
   /*
   ** Initialize the protocols
   */
   
#if RTCSCFG_ENABLE_IP4
    /*********************************************
    *   Initialize IPv4
    **********************************************/
    status = IP_init();
    if (status)
    {
        RTCS_task_exit(creator, status);
    } 

#if RTCSCFG_ENABLE_ICMP

    status = ICMP_init();
    if (status)
    {
        RTCS_task_exit(creator, status);
    }
   
#endif /* RTCSCFG_ENABLE_ICMP */

    ARP_init();
    
    BOOT_init();

#endif /* RTCSCFG_ENABLE_IP4 */

#if RTCSCFG_ENABLE_IP6

    /*********************************************
    *   Initialize IPv6
    **********************************************/
    status = IP6_init();
    if (status)
    {
      RTCS_task_exit(creator, status);
    } 

    /* Init ICMP6. */ 
    status = ICMP6_init(); //TBD Add it to RTCS6_protocol_table
    if (status)
    {
        RTCS_task_exit(creator, status);
    } 
    
#endif /* RTCSCFG_ENABLE_IP6*/

#if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) || (RTCSCFG_ENABLE_IP6_REASSEMBLY && RTCSCFG_ENABLE_IP6)
    /* Initialize the reassembler */
    status = IP_reasm_init();
    if (status)
    {
        RTCS_task_exit(creator, status);
    } 
#endif

    /* Add loopback interface.*/
    status = IPLOCAL_init ();    
    if (status)
    {
        RTCS_task_exit(creator, status);
    };

   for (i = 0; RTCS_protocol_table[i]; i++) {
      status = (*RTCS_protocol_table[i])();
      if (status) {
         RTCS_task_exit(creator, status);
      } /* Endif */
   } /* Endfor */

   _RTCS_initialized= TRUE;
   RTCS_task_resume_creator(creator, RTCS_OK);

   while (1) {
      /*
      ** Update any option that can be changed
      */
#if 0
      RTCS_data_ptr->IP_FORWARD_COPY =    _IP_forward;
      RTCS_data_ptr->TCP_BYPASS_RX_COPY = _TCP_bypass_rx;
      RTCS_data_ptr->TCP_BYPASS_TX_COPY = _TCP_bypass_tx;
      RTCS_data_ptr->TCP_RTO_MIN_COPY =   _TCP_rto_min;
#endif

#if 0
      /*
      ** Process TCP events
      */
      timeout = TCP_tick();

      /*
      ** Set up the timeout to hit at exactly the time of the next timeout.
      */
      timeafter = RTCS_time_get();
      timedelta = timeafter - timebefore;
      timebefore = timeafter;
      timedelta = TCPIP_Event_time(timedelta);

      if (timedelta != 0) {
         if ((timedelta < timeout) || (timeout == 0)) {
            timeout = timedelta;
         } /* Endif */
      } /* Endif */
#endif

      tcpip_msg = (TCPIP_MESSAGE_PTR)RTCS_msgq_receive(tcpip_qid, timeout, RTCS_data_ptr->TCPIP_msg_pool);

      if (tcpip_msg) {
         if (NULL != tcpip_msg->COMMAND)
            tcpip_msg->COMMAND(tcpip_msg->DATA);
         
         RTCS_msg_free(tcpip_msg);
      }
      
      timeout = TCP_tick();

      timeafter = RTCS_time_get();
      timedelta = RTCS_timer_get_interval(timebefore, timeafter); 
      timebefore = timeafter;
      timedelta = TCPIP_Event_time(timedelta);
      
      if (timedelta != 0) {
        if ((timedelta < timeout) || (timeout == 0)) {
            timeout = timedelta;
         }
      }

   } /* Endwhile */
} /* Endbody */

#if 0
void TCP_Transmit_msg(pointer data) {
    TCP_CFG_STRUCT_PTR   tcp_cfg;
    TCB_STRUCT_PTR       tcb = data;
    
    tcp_cfg = RTCS_getcfg(TCP);
    TCP_Transmit(data, tcp_cfg, FALSE, TRUE);
    
         /*
         ** If sender idle, restart keep-alive timer
         */
         if ( tcb->sndlen == 0 && tcb->keepaliveto != 0 ) {
            TCP_Send_keepalive(tcb,tcp_cfg);
         } /* Endif */
}
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_spi.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_spi.c$
* $Version : 3.8.2.0$
* $Date    : Oct-1-2012$
*
* Comments:
*
*   This file contains the initialization definition for DSPI driver
*
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>


/*
** Parameters for SPI initialization
*/

static const DSPI_INIT_STRUCT _bsp_dspi0_init = {
    0,                            /* SPI channel */
    CM_CLOCK_SOURCE_BUS           /* Relevant module clock source */
};

const SPI_INIT_STRUCT _bsp_spi0_init = {
    &_spi_dspi_devif,             /* Low level driver interface */
    &_bsp_dspi0_init,             /* Low level driver init data */
    {                             /* Default parameters: */
        10000000,                     /* Baudrate */
        SPI_CLK_POL_PHA_MODE0,        /* Mode */
        8,                            /* Frame size */
        1,                            /* Chip select */
        DSPI_ATTR_USE_ISR,            /* Attributes */
        0xFFFFFFFF                    /* Dummy pattern */
    }
};


static const DSPI_INIT_STRUCT _bsp_dspi1_init = {
    1,                            /* SPI channel */
    CM_CLOCK_SOURCE_BUS           /* Relevant module clock source */
};

const SPI_INIT_STRUCT _bsp_spi1_init = {
    &_spi_dspi_devif,             /* Low level driver interface */
    &_bsp_dspi1_init,             /* Low level driver init data */
    {                             /* Default parameters: */
        10000000,                     /* Baudrate */
        SPI_CLK_POL_PHA_MODE0,        /* Mode */
        8,                            /* Frame size */
        1,                            /* Chip select */
        DSPI_ATTR_USE_ISR,            /* Attributes */
        0xFFFFFFFF                    /* Dummy pattern */
    }
};


static const DSPI_INIT_STRUCT _bsp_dspi2_init = {
    2,                            /* SPI channel */
    CM_CLOCK_SOURCE_BUS           /* Relevant module clock source */
};

const SPI_INIT_STRUCT _bsp_spi2_init = {
    &_spi_dspi_devif,             /* Low level driver interface */
    &_bsp_dspi2_init,             /* Low level driver init data */
    {                             /* Default parameters: */
        10000000,                     /* Baudrate */
        SPI_CLK_POL_PHA_MODE0,        /* Mode */
        8,                            /* Frame size */
        1,                            /* Chip select */
        DSPI_ATTR_USE_ISR,            /* Attributes */
        0xFFFFFFFF                    /* Dummy pattern */
    }
};


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/timer.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   TCP/IP internal Time Service implementation
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcstime.h"

TCPIP_EVENT_PTR TCPIP_Event_head;


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : TCPIP_Event_init
*  Returned Value : void
*  Comments       :
*        Initializes the timer queue.
*
*END*-----------------------------------------------------------------*/

void TCPIP_Event_init
   (
      void
   )
{ /* Body */

   TCPIP_Event_head = NULL;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : TCPIP_Event_add
*  Returned Value : void
*  Comments       :
*        Adds an event to the timer queue.
*
*END*-----------------------------------------------------------------*/

void TCPIP_Event_add
   (
      TCPIP_EVENT_PTR   event
         /* [IN] the event */
   )
{ /* Body */
   TCPIP_EVENT_PTR _PTR_   search_ptr;

   for (search_ptr = &TCPIP_Event_head;;
        search_ptr = &(*search_ptr)->NEXT) {

      /* Append to tail of list */
      if (*search_ptr == NULL) {
         event->NEXT = NULL;
         *search_ptr = event;
         break;
      } /* Endif */

      /* Insert in middle (or head) of list */
      if ((*search_ptr)->TIME > event->TIME) {
         (*search_ptr)->TIME -= event->TIME;
         event->NEXT = *search_ptr;
         *search_ptr = event;
         break;
      } /* Endif */

      event->TIME -= (*search_ptr)->TIME;

   } /* Endfor */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : TCPIP_Event_cancel
*  Returned Value : void
*  Comments       :
*        Removes an event from the timer queue.
*
*END*-----------------------------------------------------------------*/

void TCPIP_Event_cancel
   (
      TCPIP_EVENT_PTR   event
         /* [IN] the event */
   )
{ /* Body */
   TCPIP_EVENT_PTR _PTR_   search_ptr;

   for (search_ptr = &TCPIP_Event_head;
       *search_ptr;
        search_ptr = &(*search_ptr)->NEXT) {

      /* Found it */
      if (*search_ptr == event) {
         if (event->NEXT) {
            event->NEXT->TIME += event->TIME;
         } /* Endif */
         *search_ptr = event->NEXT;
         break;
      } /* Endif */

   } /* Endfor */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : TCPIP_Event_expire
*  Returned Value : time until event expires, 0 if event is not started
*  Comments       :
*        Calculates the time until an event expires.
*
*END*-----------------------------------------------------------------*/

uint_32 TCPIP_Event_expire
   (
      TCPIP_EVENT_PTR   event
         /* [IN] the event */
   )
{ /* Body */
   TCPIP_EVENT_PTR   search;
   uint_32           time = 0;

   for (search = TCPIP_Event_head;
        search;
        search = search->NEXT) {

      time += search->TIME;

      /* Found it */
      if (search == event) {
         return time;
      } /* Endif */

   } /* Endfor */

   /* Event is not in list */
   return 0;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : TCPIP_Event_time
*  Returned Value : time until next event (0 if none)
*  Comments       :
*        Notifies the time server of elapsed time.
*
*END*-----------------------------------------------------------------*/

uint_32 TCPIP_Event_time
   (
      uint_32  time
         /* [IN] time elapsed */
   )
{ /* Body */
   TCPIP_EVENT_PTR   event;

   while (TCPIP_Event_head) {

      /* Check if the head of the timer queue had expired */
      if (TCPIP_Event_head->TIME > time) {
         TCPIP_Event_head->TIME -= time;
         return TCPIP_Event_head->TIME;
      } /* Endif */

      /* The head has expired -- dequeue it */
      event = TCPIP_Event_head;
      TCPIP_Event_head = event->NEXT;
      time -= event->TIME;

      /* Now trigger it */
      if ((*event->EVENT)(event)) {
         event->TIME += time;
         TCPIP_Event_add(event);
      } /* Endif */

   } /* Endwhile */

   /* Timer queue is empty */
   return 0;

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/tftpacc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tftpacc.c$
* $Version : 3.0.5.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the TFTP access control function.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include "tftp.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_service_request
* Returned Value  : TRUE if the requested transaction is to be
*                   allowed, FALSE if it is to be rejected
* Comments        : The default behaviour for this function is to allow
*                   read requests on all devices and reject all write
*                   requests.
*
*END*-----------------------------------------------------------------*/

boolean TFTPSRV_access
   (
      char_ptr    string_ptr,
         /* [IN] The requested device */
      uint_16     request_type
         /* [IN] The type of access requested */
   )
{ /* Body */
   return (TRUE);
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_Freemaster.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved                       
*
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: TSS_Freemaster.c$
* $Version : 3.8.2.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This file contains FreeMASTER interface for TSS variables.
*
*END************************************************************************/

#include "TSS_API.h"

#if TSS_USE_FREEMASTER_GUI  
  #include "freemaster.h"

  typedef struct {
    UINT32 indexdata;
    UINT32 flagreg;
  } FMSTR_WRITE_STRUCT;
  
  FMSTR_WRITE_STRUCT fmstr_write = {0xffffffff, 0xff};  
  
  typedef struct {
      UINT8 low_bit            :1;
      UINT8 low_bit1           :1;
      UINT8 low_bit2           :1;
      UINT8 low_bit3           :1;
      UINT8 low_bit4           :1;
      UINT8 low_bit5           :1;
      UINT8 low_bit6           :1;
      UINT8 low_bit7           :1;
  } FMSTR_BIT_STRUCT;

  typedef struct{
   UINT8             ptr_size;
   FMSTR_BIT_STRUCT  low_bit_mask;
  } FMSTR_CONFIG_STRUCT;

  volatile FMSTR_CONFIG_STRUCT fmstr_config = {sizeof(const UINT8 *), {1,0,0,0,0,0,0,0}};

  /////////////////////////////////////////////////////////////////////////
  
  extern UINT16 tss_au16ElecBaseline[TSS_N_ELECTRODES];
  extern UINT8 tss_cu8NumElecs;
  extern const UINT8 tss_cu8NumCtrls;
  extern const UINT16 tss_cu16Version;
#if TSS_N_CONTROLS > 0
  extern const UINT8 * const tss_acpsCSStructs[TSS_N_CONTROLS];
  extern const UINT8 * const tss_acpsDecContext[TSS_N_CONTROLS];
#endif
  void TSS_FmstrCall(void);
  void TSS_FmstrIsrCallback(void);
 
 #if FMSTR_USE_TSA 
  /* FreeMASTER TSA table for TSS variables */
  FMSTR_TSA_TABLE_BEGIN(TSS_Table)
      //FreeMASTER interface to write
      FMSTR_TSA_RW_VAR(fmstr_write,                         FMSTR_TSA_USERTYPE(FMSTR_WRITE_STRUCT))
      FMSTR_TSA_STRUCT(FMSTR_WRITE_STRUCT)
      FMSTR_TSA_MEMBER(FMSTR_WRITE_STRUCT, indexdata,       FMSTR_TSA_UINT32)
      FMSTR_TSA_MEMBER(FMSTR_WRITE_STRUCT, flagreg,         FMSTR_TSA_UINT32)

      FMSTR_TSA_RW_VAR(fmstr_config,                        FMSTR_TSA_USERTYPE(FMSTR_CONFIG_STRUCT))
      FMSTR_TSA_STRUCT(FMSTR_CONFIG_STRUCT)
  	  FMSTR_TSA_MEMBER(FMSTR_CONFIG_STRUCT, ptr_size,       FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(FMSTR_CONFIG_STRUCT, low_bit_mask,   FMSTR_TSA_UINT8)
      
      //TSS system config menu
      FMSTR_TSA_RW_VAR(tss_CSSys,                                  FMSTR_TSA_USERTYPE(TSS_CSSystem))
      FMSTR_TSA_STRUCT(TSS_CSSystem)
      FMSTR_TSA_MEMBER(TSS_CSSystem, Faults,                       FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, SystemConfig,                 FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, NSamples,                     FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, DCTrackerRate,                FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, ResponseTime,                 FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, StuckKeyTimeout,              FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, LowPowerScanPeriod,           FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, LowPowerElectrode,            FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, LowPowerElectrodeSensitivity, FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, SystemTrigger,                FMSTR_TSA_UINT8)
      FMSTR_TSA_MEMBER(TSS_CSSystem, AutoTriggerModuloValue,       FMSTR_TSA_UINT8)
  
      //electrodes config menu
  #if TSS_USE_DELTA_LOG
      FMSTR_TSA_RO_VAR(tss_ai8InstantDelta,     FMSTR_TSA_UINT8)
  #endif
  #if TSS_USE_SIGNAL_LOG
      FMSTR_TSA_RO_VAR(tss_au16InstantSignal,   FMSTR_TSA_UINT16)
  #endif
      FMSTR_TSA_RO_VAR(tss_au16ElecBaseline,    FMSTR_TSA_UINT16)
      FMSTR_TSA_RO_VAR(tss_au8ElectrodeStatus,  FMSTR_TSA_UINT8)
      FMSTR_TSA_RW_VAR(tss_au8Sensitivity,      FMSTR_TSA_UINT8)
      FMSTR_TSA_RW_VAR(tss_au8ElectrodeEnablers,FMSTR_TSA_UINT8) 
      FMSTR_TSA_RO_VAR(tss_cu8NumElecs,         FMSTR_TSA_UINT8)
        
      //controls menu
      FMSTR_TSA_RO_VAR(tss_cu8NumCtrls,         FMSTR_TSA_UINT8)
#if TSS_N_CONTROLS > 0
      FMSTR_TSA_RO_VAR(tss_acpsCSStructs,       FMSTR_TSA_UINT32)
      FMSTR_TSA_RO_VAR(tss_acpsDecContext,      FMSTR_TSA_UINT32)
#endif
      // TSS version information
      FMSTR_TSA_RO_VAR(tss_cu16Version,         FMSTR_TSA_UINT16)
  FMSTR_TSA_TABLE_END()
#endif

  /* 
   * FreeMASTER interface to write configure TSS feature over FreeMASTER
   */
  void TSS_FmstrCall(void)
  {
    UINT16 u16DummyVersion;
    FMSTR_CONFIG_STRUCT temp = fmstr_config;
    TSS_CONTROL_ID controlID;
    
    if (fmstr_write.flagreg != 0xff)
    {
      UINT8 type = (UINT8) (fmstr_write.indexdata>>24);
      UINT8 index = (UINT8) ((fmstr_write.indexdata>>16)&0xff);
      UINT16 data = (UINT16) ((fmstr_write.indexdata)&0xffff);
        
      *((UINT8*)&controlID)  = (UINT8) ((fmstr_write.indexdata>>8)&0xff);
        switch (type)
        {
        case 0:
          TSS_SetSystemConfig(index, data);
          break;
        case 1:
          TSS_SetKeypadConfig(controlID, index, (UINT8)(data&0xff));
          break;
        case 2:
          TSS_SetSliderConfig(controlID, index, (UINT8)(data&0xff));
          break;
        case 3:
          TSS_SetRotaryConfig(controlID, index, (UINT8)(data&0xff));
          break;
        }
        fmstr_write.flagreg = 0xff;
    }
    /* Dummy usage of tss_cu16Version to avoid remove from the memory */
    u16DummyVersion = tss_cu16Version;
    u16DummyVersion++;
    
  }
  
  /* 
   * User callback called from FMSTR_Isr() handler
   */
  void TSS_FmstrIsrCallback(void)
  {
    /* Set Sample Interrupted flag, because SCI measures at background and it can interrupt sampling of GPIO based methods */
    TSS_SET_SAMPLE_INTERRUPTED();
  }
#else
    void TSS_FmstrIsrCallback(void)
    {
    
    }
#endif /* End of TSS_USE_FREEMASTER_GUI */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_data_sector.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_data_sector.c$
* $Version : 3.8.11.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the functions that are used to read and write to the 
*   device under MFS. 
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"
#include "part_mgr.h"



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Flush_data_sector_buffer
* Returned Value   :  error_code
* Comments  :
*     Writes the cached sector back to disk if dirty.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Flush_data_sector_buffer
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr     /*[IN] the drive on which to operate */
    )
{
#if MFSCFG_READ_ONLY
    return MFS_NO_ERROR;
#else
    _mfs_error   error_code = MFS_NO_ERROR;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return error_code;
    }
#endif

    if ( drive_ptr->DATA_SECTOR_DIRTY )
    {
        error_code = MFS_Write_device_sector(drive_ptr,drive_ptr->DATA_SECTOR_NUMBER,drive_ptr->DATA_SECTOR_PTR);

        if ( error_code == MFS_NO_ERROR )
        {
            drive_ptr->DATA_SECTOR_DIRTY=FALSE;
        }
    }

    return error_code;
#endif
}  



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Invalidate_data_sector
* Returned Value   :  error_code
* Comments  :
*     Invalidates the cached sector.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Invalidate_data_sector
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr   /*[IN] the drive on which to operate */
    )
{
#if MFSCFG_READ_ONLY
    return MFS_NO_ERROR;
#else

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_NO_ERROR;
    }
#endif

    drive_ptr->DATA_SECTOR_NUMBER = MAX_UINT_32;
    drive_ptr->DATA_SECTOR_DIRTY=FALSE;
    return MFS_NO_ERROR;
#endif
}  



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Read_data_sector
* Returned Value   :  error_code
* Comments  :
*     Readsone sector into the DATA_SECTOR buffer
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Read_data_sector
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    MFS_HANDLE_PTR          handle,         /*[IN]  handle of the file for which we are doing the read/write  */
    uint_32                 sector_number,  /*[IN] sector number to read/write from/to file system medium */
    boolean                 hw_read         /*[IN] if read of a sector is needed or just validation of a new one */
    )
{
    _mfs_error error;

    error = MFS_NO_ERROR;

    if ( sector_number != drive_ptr->DATA_SECTOR_NUMBER )
    {
        MFS_Flush_data_sector_buffer(drive_ptr);
        MFS_Invalidate_data_sector(drive_ptr);

        if (hw_read)
        {
            error = MFS_Read_device_sector(drive_ptr,sector_number,drive_ptr->DATA_SECTOR_PTR);
        }
        else
        {
            error = MFS_NO_ERROR;
        }

        if ( error == MFS_NO_ERROR )
        {
            drive_ptr->DATA_SECTOR_NUMBER =  sector_number;
        }
    }

    return(error);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5xxx_fec_send.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5xxx_fec_send.c$
* $Version : 3.5.5.0$
* $Date    : Nov-24-2009$
*
* Comments:
*
*   This file contains the MCF5xxx Ethernet send
*   support function.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "mcf5xxx_fec_prv.h"          



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_send
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Sends a packet.
*
*END*-----------------------------------------------------------------*/

uint_32 MCF5XXX_FEC_send
   (
      ENET_CONTEXT_STRUCT_PTR  enet_ptr,
         /* [IN] the Ethernet state structure */
      PCB_PTR              packet,
         /* [IN] the packet to send */
      uint_32              size,
         /* [IN] total size of the packet */
      uint_32              frags,
         /* [IN] total fragments in the packet */
      uint_32              flags
         /* [IN] optional flags, zero = default */
   )
{ 
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR    fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   VMCF5XXX_FEC_STRUCT_PTR           fec_ptr= fec_context_ptr->FEC_ADDRESS;
   PCB_FRAGMENT_PTR                  frag_ptr;
   VMCF5XXX_FEC_BD_STRUCT_PTR        tx_bd_ptr;
   uint_32                           len,totlen,frag;
   uchar_ptr                         txmem;
   boolean                           aligned;
   uint_32                           err = ENET_OK;

   if (fec_ptr == NULL) 
      return ENETERR_INVALID_DEVICE;
   
   FEC_int_disable();
   
   /*
   ** Make sure there aren't too many fragments.  (We really should check
   ** this every time through the previous loop, but it is extremely
   ** unlikely that the fragment counter overflowed -- there would have
   ** to be over 2^32 fragments.)
   */
   if (fec_context_ptr->AvailableTxBDs < 1) {
      ENET_INC_STATS(COMMON.ST_TX_MISSED);
   
      err = ENETERR_SEND_FULL;      
      goto END;
   } 

   #if BSPCFG_ENABLE_ENET_HISTOGRAM
   {
      uint_32 index = size>> ENET_HISTOGRAM_SHIFT;
      
      if (index < ENET_HISTOGRAM_ENTRIES) {
         ENET_INC_STATS(TX_HISTOGRAM[index]);
      }
   }
   #endif
   
   aligned = TRUE;
   for (frag_ptr = packet->FRAG; frag_ptr->LENGTH; frag_ptr++) {
      if (MCF5XXX_FEC_TX_ALIGN((uint_32)frag_ptr->FRAGMENT)!= (uint_32)frag_ptr->FRAGMENT)
         aligned = FALSE;
   } 
   if (aligned) {
      ENET_INC_STATS(TX_ALL_ALIGNED);
   }
   
   /*
   ** Enqueue the packet on the transmit ring.  Don't set the ready
   ** bit in the first descriptor until all descriptors are enqueued.
   */
   tx_bd_ptr = &fec_context_ptr->FEC_TX_RING_PTR[fec_context_ptr->NextTxBD];

   frag_ptr = packet->FRAG;
   frag = (uint_32) frag_ptr->FRAGMENT;
   if (frags > 1 || (MCF5XXX_FEC_TX_ALIGN(frag)!= frag)) {
      // Packet is fragmented and/or it is misaligned, needs to be copied
      txmem = NULL;
      // See if it fits in a small buffer
      if (size <= MCF5XXX_SMALL_PACKET_SIZE) {
         // it does
         txmem = ENET_Dequeue_Buffer((pointer *) &fec_context_ptr->SMALL_BUFFERS);
      }
      // If it didn't fit, or the small alloc failed, try for a large buffer
      if (txmem) {
         // signal buffer is to be deallocated.
         fec_context_ptr->FREE_TX_SMALL |= (1<<fec_context_ptr->NextTxBD);
         ENET_INC_STATS(ST_TX_COPY_SMALL);

      } else { 
         if (size <=  fec_context_ptr->AlignedTxBufferSize) {

            txmem = ENET_Dequeue_Buffer((pointer *) &fec_context_ptr->TX_BUFFERS);
         }
         if (txmem) {
            // signal buffer is to be deallocated.
            fec_context_ptr->FREE_TX |= (1<<fec_context_ptr->NextTxBD);
         } else {
            ENET_INC_STATS(COMMON.ST_TX_MISSED);
            
            err = ENETERR_NO_TX_BUFFER;      
            goto END;
         }
         
      }
      totlen = 0;
      
      for (len = frag_ptr->LENGTH; len != 0; len = frag_ptr->LENGTH) {
         _mem_copy(frag_ptr->FRAGMENT, txmem + totlen, len);
         totlen += len;
         frag_ptr++;
      } 

   } else {
      // Packet is not fragmented and it is not misaligned
      totlen = frag_ptr->LENGTH;
      txmem  = frag_ptr->FRAGMENT;
      ENET_INC_STATS(TX_ALIGNED);
   } 

   // Flush the buffer from cache
   _DCACHE_FLUSH_MBYTES(txmem, totlen);  

   // Invalidate the bd from cache
   _DCACHE_INVALIDATE_MBYTES((pointer)tx_bd_ptr, sizeof(MCF5XXX_FEC_BD_STRUCT));  

   // set up the tx bd
   tx_bd_ptr->CONTROL &= MCF5XXX_FEC_BD_ETHER_TX_WRAP;
   tx_bd_ptr->BUFFER = txmem;
   tx_bd_ptr->LENGTH = totlen;
   tx_bd_ptr->CONTROL |= (MCF5XXX_FEC_BD_ETHER_TX_LAST | MCF5XXX_FEC_BD_ETHER_TX_SEND_CRC | MCF5XXX_FEC_BD_ETHER_TX_READY);
   
   // Flush the tx bd from cache
   _DCACHE_FLUSH_MBYTES((pointer)tx_bd_ptr, sizeof(MCF5XXX_FEC_BD_STRUCT));  

   fec_context_ptr->TxPCBS_PTR[fec_context_ptr->NextTxBD] = packet;
   
   fec_context_ptr->AvailableTxBDs--;
   BD_INC(fec_context_ptr->NextTxBD,fec_context_ptr->NumTxBDs);

   fec_ptr->TDAR = MCF5XXX_FEC_TDAR_ACTIVE;
   
END:
   FEC_int_enable();
      
   return err;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_process_tx_bds
*  Returned Value : void
*  Comments       :
*        Processes transmitted packets.
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_process_tx_bds
   (
         /* [IN] the Ethernet state structure */
      ENET_CONTEXT_STRUCT_PTR  enet_ptr
   )
{ 
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   uint_16                          tx_status;
   

   /* Dequeue all transmitted frames */
   while (fec_context_ptr->AvailableTxBDs < fec_context_ptr->NumTxBDs) {
      VMCF5XXX_FEC_BD_STRUCT_PTR bd_ptr = &fec_context_ptr->FEC_TX_RING_PTR[fec_context_ptr->LastTxBD];

      _DCACHE_INVALIDATE_MBYTES((pointer)bd_ptr, sizeof(MCF5XXX_FEC_BD_STRUCT));  

      if (bd_ptr->CONTROL & MCF5XXX_FEC_BD_ETHER_TX_READY) {
         break;
      } /* Endif */

      fec_context_ptr->TxErrors |= bd_ptr->CONTROL;
      tx_status = fec_context_ptr->TxErrors;

      /* Record statistics for each frame (not each buffer) */
      if (tx_status & MCF5XXX_FEC_BD_ETHER_TX_LAST) {
         PCB_PTR pcb_ptr;
         fec_context_ptr->TxErrors = 0;

         ENET_INC_STATS(COMMON.ST_TX_TOTAL);

         pcb_ptr = fec_context_ptr->TxPCBS_PTR[fec_context_ptr->LastTxBD];
         PCB_free(pcb_ptr);
      } 

      if (fec_context_ptr->FREE_TX_SMALL & (1<<fec_context_ptr->LastTxBD)) {
         ENET_Enqueue_Buffer((pointer *) &fec_context_ptr->SMALL_BUFFERS,bd_ptr->BUFFER);
         fec_context_ptr->FREE_TX_SMALL &= ~(1<<fec_context_ptr->LastTxBD);
      } else if (fec_context_ptr->FREE_TX & (1<<fec_context_ptr->LastTxBD)) {
         ENET_Enqueue_Buffer((pointer *) &fec_context_ptr->TX_BUFFERS,bd_ptr->BUFFER);
         fec_context_ptr->FREE_TX &= ~(1<<fec_context_ptr->LastTxBD);
      }      
      BD_INC(fec_context_ptr->LastTxBD,fec_context_ptr->NumTxBDs);
      fec_context_ptr->AvailableTxBDs++;

   } 
} 


/*NOTIFIER*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_TX_ISR
*  Returned Value : void
*  Comments       :
*        Interrupt service routine for Tx.
*
*END*-----------------------------------------------------------------*/

void MCF5XXX_FEC_TX_ISR 
   (
         /* [IN] the Ethernet state structure */
      pointer  enet
   )
{    
   ENET_CONTEXT_STRUCT_PTR          enet_ptr = (ENET_CONTEXT_STRUCT_PTR)enet;
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   VMCF5XXX_FEC_STRUCT_PTR          fec_ptr= fec_context_ptr->FEC_ADDRESS;
   uint_32                 events;

   if (fec_ptr == NULL) return;
   
   events = fec_ptr->EIR;
   while (events & MCF5XXX_FEC_EIR_TXB) {

      /* clear the interrupt */
      fec_ptr->EIR = MCF5XXX_FEC_EIR_TXB;
      MCF5XXX_FEC_process_tx_bds(enet_ptr);

      events = fec_ptr->EIR;
   } 
} 




/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/nandflash/nfc/nfc.c<|end_filename|>
/**HEADER***********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
********************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************
*
* $FileName: nfc.c$
* $Version : 3.8.16.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions to interface NAND Flash Controller module.
*
*END***************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "nandflash.h"
#include "nandflashprv.h"
#include "nfc.h"

/* NFC ECC status word */
#define NFC_ECC_STATUS_CORFAIL       (0x80)
#define NFC_ECC_STATUS_ERROR_COUNT   (0x3F)
#define NFC_ECC_STATUS_OFFSET        (0x0C)

uint_32 nfc_swap_addr1, nfc_swap_addr2;

/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : nfc_init
* Returned Value   : NANDFLASHERR_NO_ERROR or
*                    NANDFLASHERR_IMPROPER_ECC_SIZE
*                    NANDFLASHERR_INFO_STRUC_MISSING
*                    MQX_OUT_OF_MEMORY
* Comments         :
*    This function initializes the driver.
*
*END*-------------------------------------------------------------------------*/

uint_32 nfc_init
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr
   )
{ /* Body */

   uint_32 result = NANDFLASHERR_NO_ERROR;
   NFC_MemMapPtr nfc_ptr;
   uint_32 nand_id, block_size_kB, density, num_ecc_bytes;
   NANDFLASH_INFO_STRUCT_PTR nand_info_ptr;

   /* Initialize NFC I/O Pins */
   nfc_io_init();

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   /* Create NANDFLASH_INFO_STRUCT based on NAND ID read from the NAND Flash,
      if not defined before manually */
   if((nandflash_ptr->NANDFLASH_INFO_PTR) == NULL)
   {
       nand_info_ptr = (NANDFLASH_INFO_STRUCT_PTR)_mem_alloc_system_zero(
                       (_mem_size)sizeof(NANDFLASH_INFO_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
       if(nand_info_ptr == NULL)
       {
          return((uint_32)MQX_OUT_OF_MEMORY);
       } /* Endif */
#endif

       if (((*nandflash_ptr->IOCTL)(nandflash_ptr,NANDFLASH_IOCTL_GET_ID,&nand_id)) == NANDFLASHERR_NO_ERROR)
       {
           nand_info_ptr->PHY_PAGE_SIZE =
             (_mem_size)(((nand_id & NANDFLASH_ID_PAGE_SIZE_MASK) + 1)*1024);

           if((nand_id & NANDFLASH_ID_SPARE_BYTES_NUM_MASK)>>2 == 1)
           {
               nand_info_ptr->SPARE_AREA_SIZE = (_mem_size)64;
           }

           if(nand_id & NANDFLASH_ID_BLOCK_SIZE_MASK)
           {
               nand_info_ptr->BLOCK_SIZE =
                 (_mem_size)((nand_id & NANDFLASH_ID_BLOCK_SIZE_MASK)*8192);
           }
           else
           {
               nand_info_ptr->BLOCK_SIZE = 65536;
           }

           block_size_kB = (nand_info_ptr->BLOCK_SIZE)/1024;
           density = (nand_id & NANDFLASH_ID_DENSITY_MASK)>>16;
           switch(density)
           {
               case NANDFLASH_DENSITY_1Gb:
                   /* nand_info_ptr->NUM_BLOCKS = 1024/8*1024/block_size_kB; */
                   nand_info_ptr->NUM_BLOCKS = 131072/block_size_kB;
                   break;

               case NANDFLASH_DENSITY_2Gb:
                   nand_info_ptr->NUM_BLOCKS = 2*131072/block_size_kB;
                   break;

               case NANDFLASH_DENSITY_4Gb:
                   nand_info_ptr->NUM_BLOCKS = 4*131072/block_size_kB;
                   break;

               case NANDFLASH_DENSITY_8Gb:
                   nand_info_ptr->NUM_BLOCKS = 8*131072/block_size_kB;
                   break;

               case NANDFLASH_DENSITY_16Gb:
                   nand_info_ptr->NUM_BLOCKS = 16*131072/block_size_kB;
                   break;

               default:
                   break;
           }

           nand_info_ptr->WIDTH =
             (_mqx_uint)(8 + ((nand_id & NANDFLASH_ID_WIDTH_MASK)>>3));

           nandflash_ptr->NANDFLASH_INFO_PTR = nand_info_ptr;
           nandflash_ptr->NUM_VIRTUAL_PAGES  =
             ((nand_info_ptr->BLOCK_SIZE)/(nandflash_ptr->VIRTUAL_PAGE_SIZE))*(nand_info_ptr->NUM_BLOCKS);
           nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO =
             (nand_info_ptr->PHY_PAGE_SIZE)/(nandflash_ptr->VIRTUAL_PAGE_SIZE);
       }
       else
       {
           return ((uint_32)NANDFLASHERR_INFO_STRUC_MISSING);
       }
   }

   /* Set the CFG register */
   nfc_ptr->CFG  = NFC_CFG_STOPWERR_MASK |
                   NFC_CFG_ECCAD((nandflash_ptr->VIRTUAL_PAGE_SIZE / 8) + 1) |
                   NFC_CFG_ECCSRAM_MASK |
                   NFC_CFG_IDCNT(5) |
                   NFC_CFG_TIMEOUT(6) |
                   NFC_CFG_PAGECNT(1);

   if((nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH) == 16)
       nfc_ptr->CFG |= NFC_CFG_BITWIDTH_MASK;
   else if((nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH) == 8)
       nfc_ptr->CFG &= ~NFC_CFG_BITWIDTH_MASK;

   switch(nandflash_ptr->ECC_SIZE)
   {
       case 0:
          nfc_ptr->CFG |= NFC_CFG_ECCMODE(0);
          break;
       case 4:
          nfc_ptr->CFG |= NFC_CFG_ECCMODE(1);
          break;
       case 6:
          nfc_ptr->CFG |= NFC_CFG_ECCMODE(2);
          break;
       case 8:
          nfc_ptr->CFG |= NFC_CFG_ECCMODE(3);
          break;
       case 12:
          nfc_ptr->CFG |= NFC_CFG_ECCMODE(4);
          break;
       case 16:
          nfc_ptr->CFG |= NFC_CFG_ECCMODE(5);
          break;
       case 24:
          nfc_ptr->CFG |= NFC_CFG_ECCMODE(6);
          break;
       case 32:
          nfc_ptr->CFG |= NFC_CFG_ECCMODE(7);
          break;
       default:
          result = NANDFLASHERR_IMPROPER_ECC_SIZE;
          break;
   }

   /* Auto-increment of row address is not enabled */
   nfc_ptr->RAI  = 0;

   /* Set both addresses in the SWAP register to the same value equal to
      the possition of the bad block marker within the physical page, mapped
      to the virtual page */
   num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(nandflash_ptr->ECC_SIZE);
   nfc_swap_addr1 = ((nandflash_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE)-
                     ((nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO - 1) *
                     (nandflash_ptr->VIRTUAL_PAGE_SIZE + num_ecc_bytes)))/8;
   nfc_swap_addr2 = (nandflash_ptr->VIRTUAL_PAGE_SIZE)/8;

   return(result);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_deinit
* Returned Value   :
* Comments         :
*    This function de-initializes the driver.
*
*END*----------------------------------------------------------------------*/

void nfc_deinit
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr
   )
{ /* Body */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_erase_flash
* Returned Value   : NANDFLASHERR_NO_ERROR or
*                    NANDFLASHERR_ERASE_FAILED
* Comments         :
*    This function erases the whole NAND Flash using the NFC module.
*
*END*----------------------------------------------------------------------*/

uint_32 nfc_erase_flash
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr
   )
{ /* Body */

   uint_32 count;

   for (count = 0; count < (nandflash_ptr->NANDFLASH_INFO_PTR->NUM_BLOCKS); count++)
   {
       if (NANDFLASHERR_NO_ERROR != nfc_erase_block(nandflash_ptr, count, FALSE))
           return NANDFLASHERR_ERASE_FAILED;
   }
   return NANDFLASHERR_NO_ERROR;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_erase_block
* Returned Value   : NANDFLASHERR_NO_ERROR or
*                    NANDFLASHERR_ERASE_FAILED or
*                    NANDFLASHERR_TIMEOUT
* Comments         :
*    This function erases the defined block of NAND Flash
*    using the NFC module.
*
*END*----------------------------------------------------------------------*/

uint_32 nfc_erase_block
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr,

      /* [IN] the block to erase */
      uint_32                 block_number,

      /* [IN] TRUE = force block erase in case the block is marked as bad */
      boolean                 force_flag
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count;

   NFC_MemMapPtr  nfc_ptr;

   /* Do not erase block if force_flag is zero and the block is marked as bad */
   if((!force_flag) &&
      (NANDFLASHERR_BLOCK_NOT_BAD != nfc_check_block(nandflash_ptr, block_number)))
   {
       return NANDFLASHERR_ERASE_FAILED;
   }

   if (nandflash_ptr->WRITE_PROTECT) {
      (*nandflash_ptr->WRITE_PROTECT)(nandflash_ptr, FALSE);
   }/* Endif */

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   nfc_ptr->CMD1  = NFC_CMD1_BYTE2(NANDFLASH_CMD_BLOCK_ERASE_CYCLE2) |
                    NFC_CMD1_BYTE3(NANDFLASH_CMD_READ_STATUS);
   nfc_ptr->CMD2  = NFC_CMD2_BYTE1(NANDFLASH_CMD_BLOCK_ERASE_CYCLE1) |
                    NFC_CMD2_CODE(0x4ED8);
   nfc_ptr->RAR   = NFC_RAR_CS0_MASK |
                    NFC_RAR_RB0_MASK |
                    ((nandflash_ptr->NANDFLASH_INFO_PTR->BLOCK_SIZE /
                      nandflash_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE * block_number) & 0xFFFFFF);
   nfc_ptr->ISR  |= (NFC_ISR_IDLECLR_MASK | NFC_ISR_IDLEEN_MASK |
                     NFC_ISR_DONECLR_MASK | NFC_ISR_DONEEN_MASK);

   /* Start command execution */
   nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

   for (count = 0; count <= MAX_WAIT_COMMAND; count++)
   {
       if (nfc_ptr->ISR & NFC_ISR_DONE_MASK)
       {
           if (nfc_ptr->SR2 & NANDFLASH_STATUS_ERR)
               result = NANDFLASHERR_ERASE_FAILED;
           else
               result = NANDFLASHERR_NO_ERROR;
           break;
       }
   }

   if (nandflash_ptr->WRITE_PROTECT) {
      (*nandflash_ptr->WRITE_PROTECT)(nandflash_ptr, TRUE);
   }/* Endif */
   return(result);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_read_page
* Returned Value   : NANDFLASHERR_NO_ERROR or
*                    NANDFLASHERR_ECC_FAILED or
*                    NANDFLASHERR_ECC_CORRECTED or
*                    NANDFLASHERR_TIMEOUT
* Comments         :
*    This function reads one or several pages of NAND Flash
*    using the NFC module.
*
*END*----------------------------------------------------------------------*/

uint_32 nfc_read_page
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr,

      /* [OUT} where to copy data to */
      uchar_ptr               to_ptr,

      /* [IN] the page to read */
      uint_32                 page_number,

      /* [IN] the amount of pages to read */
      uint_32                 page_count
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count1, count2, count3;
   uint_32 output_offset = 0;
   boolean ecc_corrected = FALSE, swap = FALSE;
   uint_32 row, col, num_ecc_bytes;

   NFC_MemMapPtr  nfc_ptr;

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   for (count1 = page_number; count1 < (page_number + page_count); count1++)
   {
     num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(nandflash_ptr->ECC_SIZE);
     row = count1/nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO;
     col = (count1 - (row * nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO))*
           (nandflash_ptr->VIRTUAL_PAGE_SIZE + num_ecc_bytes);
     /* Is the bad block byte(s) about to be re-written? */
     count2 = count1 % ((nandflash_ptr->NANDFLASH_INFO_PTR->BLOCK_SIZE / nandflash_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE) * nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO);
     swap = ((count2 == (nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO - 1)) ||
             (count2 == (2*nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO - 1)));

     if(nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH == 16)
        col = col/2;

     nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_READ_CYCLE2);
     nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_READ_CYCLE1) |
                     NFC_CMD2_CODE(0x7EE0) |
                     NFC_CMD2_BUFNO(1);
     nfc_ptr->CAR  = col & 0xFFFF;
     nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                     NFC_RAR_RB0_MASK |
                     (row & 0xFFFFFF);
     nfc_ptr->SECSZ  = (nandflash_ptr->VIRTUAL_PAGE_SIZE)+num_ecc_bytes;

     /* For 16-bit data width flash devices, only odd SIZE is supported */
     if((nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH == 16) && !(nfc_ptr->SECSZ % 2))
       nfc_ptr->SECSZ  += 1;

     /* If the last virtual page of the first or the second physical page
        is about to be read the virtual page needs to be enlarged
        by 8 bytes and swapping switched on due to the bad block marking */
     if(swap)
     {
       nfc_ptr->SWAP  = NFC_SWAP_ADDR1(nfc_swap_addr1) |
                        NFC_SWAP_ADDR2(nfc_swap_addr2);
       nfc_ptr->SECSZ  += 8;
     }
     else
     {
       nfc_ptr->SWAP  = NFC_SWAP_ADDR1(0x7FF) |
                        NFC_SWAP_ADDR2(0x7FF);
     }

     nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK |
                       NFC_ISR_DONEEN_MASK |
                       NFC_ISR_IDLECLR_MASK |
                       NFC_ISR_IDLEEN_MASK);

     /* Start command execution */
     nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

     for (count2 = 0; count2 <= MAX_WAIT_COMMAND; count2++)
     {
       if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
       {

         if ( nandflash_ptr->ECC_SIZE == 0)
         {
           if (nfc_ptr->SR2 & NANDFLASH_STATUS_ERR)
           {
             return(NANDFLASHERR_ECC_FAILED);
           }
         }
         else
         {
           /* Check ECC status word */
           if (*(uint_32*)&NFC_SRAM_B1_REG(nfc_ptr, nandflash_ptr->VIRTUAL_PAGE_SIZE + NFC_ECC_STATUS_OFFSET) & NFC_ECC_STATUS_CORFAIL)
           {
             return(NANDFLASHERR_ECC_FAILED);
           }
           else
           {
             if (*(uint_32*)&NFC_SRAM_B1_REG(nfc_ptr, nandflash_ptr->VIRTUAL_PAGE_SIZE + NFC_ECC_STATUS_OFFSET) & NFC_ECC_STATUS_ERROR_COUNT)
             {
               ecc_corrected = TRUE;
             }
           }
         }

         for(count3 = 0; count3 < (nandflash_ptr->VIRTUAL_PAGE_SIZE); count3++)
         {
            *(to_ptr + output_offset) = NFC_SRAM_B1_REG(nfc_ptr, count3);
            output_offset++;
         }
         result = NANDFLASHERR_NO_ERROR;
         break;
       }
     }
   }
   if(ecc_corrected)
      result = NANDFLASHERR_ECC_CORRECTED;
   return(result);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_write_page
* Returned Value   : NANDFLASHERR_NO_ERROR or
*                    NANDFLASHERR_WRITE_FAILED or
*                    NANDFLASHERR_TIMEOUT
* Comments         :
*    This function writes one or several pages of NAND Flash
*    using the NFC module.
*
*END*----------------------------------------------------------------------*/

uint_32 nfc_write_page
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr,

      /* [IN] where to copy data from */
      uchar_ptr               from_ptr,

      /* [IN] the first page to write */
      uint_32                 page_number,

      /* [IN] the amount of pages to write */
      uint_32                 page_count
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count1, count2;
   uint_32 row, col, num_ecc_bytes;
   boolean swap = FALSE;

   NFC_MemMapPtr  nfc_ptr;

   if (nandflash_ptr->WRITE_PROTECT) {
      (*nandflash_ptr->WRITE_PROTECT)(nandflash_ptr, FALSE);
   }/* Endif */

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   for (count1 = page_number; count1 < (page_number + page_count); count1++)
   {
     num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(nandflash_ptr->ECC_SIZE);
     row = count1/nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO;
     col = (count1 - (row * nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO))*
           (nandflash_ptr->VIRTUAL_PAGE_SIZE + num_ecc_bytes);

     /* If the last virtual page of the first or the second physical page
        is about to be written the swapping needs to be switched on due
        to the bad block marking */
     count2 = count1 % ((nandflash_ptr->NANDFLASH_INFO_PTR->BLOCK_SIZE / nandflash_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE) * nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO);
     swap = ((count2 == (nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO - 1)) ||
             (count2 == (2*nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO - 1)));
     if(swap)
     {
       nfc_ptr->SWAP  = NFC_SWAP_ADDR1(nfc_swap_addr1) |
                        NFC_SWAP_ADDR2(nfc_swap_addr2);
     }
     else
     {
       nfc_ptr->SWAP  = NFC_SWAP_ADDR1(0x7FF) |
                        NFC_SWAP_ADDR2(0x7FF);
     }

     if(nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH == 16)
        col = col/2;

     /* Copy one virtual page into the SRAM buffer #0 */
     for ( count2 = 0; count2 < (nandflash_ptr->VIRTUAL_PAGE_SIZE); count2++ )
     {
        NFC_SRAM_B0_REG(nfc_ptr, count2) = *(from_ptr + count2);
     }

     nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_PROGRAM_CYCLE2) |
                     NFC_CMD1_BYTE3(NANDFLASH_CMD_READ_STATUS);
     nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_PROGRAM_CYCLE1) |
                     NFC_CMD2_CODE(0x7FD8) |
                     NFC_CMD2_BUFNO(0);
     nfc_ptr->CAR  = col & 0xFFFF;
     nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                     NFC_RAR_RB0_MASK |
                     (row & 0xFFFFFF);
     nfc_ptr->SECSZ  = (nandflash_ptr->VIRTUAL_PAGE_SIZE)+num_ecc_bytes;

     /* For 16-bit data width flash devices, only odd SIZE is supported */
     if((nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH == 16) && !(nfc_ptr->SECSZ % 2))
       nfc_ptr->SECSZ  += 1;

     /* If the last virtual page of the first or the second physical page
        is about to be written the bad block marking (negative) has to be
        inserted and the virtual page needs to be enlarged by 8 bytes */
     if(swap)
     {
       *(uint_32*)&NFC_SRAM_B0_REG(nfc_ptr, (nfc_swap_addr2 * 8)) = 0xFFFF0000;
       nfc_ptr->SECSZ  += 8;
     }

     nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK |
                       NFC_ISR_DONEEN_MASK  |
                       NFC_ISR_IDLECLR_MASK |
                       NFC_ISR_IDLEEN_MASK);

     /* Start command execution */
     nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

     for (count2 = 0; count2 <= MAX_WAIT_COMMAND; count2++)
     {
       if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
       {
          if (nfc_ptr->SR2 & NANDFLASH_STATUS_ERR)
          {
             result = NANDFLASHERR_WRITE_FAILED;
             goto exit;
          }
          else
          {
             result = NANDFLASHERR_NO_ERROR;
          }
          break;
       }
     }
     from_ptr += nandflash_ptr->VIRTUAL_PAGE_SIZE;
   }

exit:
   if (nandflash_ptr->WRITE_PROTECT) {
      (*nandflash_ptr->WRITE_PROTECT)(nandflash_ptr, TRUE);
   }/* Endif */
   return(result);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_reset
* Returned Value   : NANDFLASHERR_NO_ERROR or
*                    NANDFLASHERR_TIMEOUT
* Comments         :
*    This function resets the NAND Flash using the NFC module.
*
*END*----------------------------------------------------------------------*/

uint_32 nfc_reset
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr
   )
{ /* Body */

   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count;
   NFC_MemMapPtr  nfc_ptr;

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   nfc_ptr->CMD2  =  NFC_CMD2_BYTE1(NANDFLASH_CMD_RESET) |
                     NFC_CMD2_CODE(0x4002);
   nfc_ptr->ISR  |= (NFC_ISR_IDLECLR_MASK | NFC_ISR_IDLEEN_MASK |
                     NFC_ISR_DONECLR_MASK | NFC_ISR_DONEEN_MASK);

   /* Start command execution */
   nfc_ptr->CMD2 |=  NFC_CMD2_BUSY_START_MASK;

   for (count = 0; count <= MAX_WAIT_COMMAND; count++)
   {
       if (nfc_ptr->ISR & NFC_ISR_DONE_MASK)
       {
           result = NANDFLASHERR_NO_ERROR;
           break;
       }
   }
   return result;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_check_block
* Returned Value   : NANDFLASHERR_BLOCK_NOT_BAD or
*                    NANDFLASHERR_BLOCK_BAD or
*                    NANDFLASHERR_TIMEOUT
* Comments         :
*    This function checks if the defined NAND Flash block is bad or not
*    using the NFC module.
*
*END*----------------------------------------------------------------------*/

uint_32 nfc_check_block
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr,

      /* [IN] block to check */
      uint_32                 block_number
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count, cfg_bck, col;

   NFC_MemMapPtr  nfc_ptr;

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   /* Set the ECCMODE to 0 - ECC bypass */
   cfg_bck = nfc_ptr->CFG;
   nfc_ptr->CFG &= ~(NFC_CFG_ECCMODE(7));

   /* Reset the swap register */
   nfc_ptr->SWAP  = NFC_SWAP_ADDR1(0x7FF) |
                    NFC_SWAP_ADDR2(0x7FF);

   col = nandflash_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE;
   if(nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH == 16)
      col = col/2;

   nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_READ_CYCLE2);
   nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_READ_CYCLE1) |
                   NFC_CMD2_CODE(0x7EE0) |
                   NFC_CMD2_BUFNO(1);
   nfc_ptr->CAR  = col & 0xFFFF;
   nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                   NFC_RAR_RB0_MASK |
                   ((nandflash_ptr->NANDFLASH_INFO_PTR->BLOCK_SIZE /
                     nandflash_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE * block_number) & 0xFFFFFF);
   nfc_ptr->SECSZ  = 3;
   nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK |
                     NFC_ISR_DONEEN_MASK  |
                     NFC_ISR_IDLECLR_MASK |
                     NFC_ISR_IDLEEN_MASK);

   /* Start command execution */
   nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

   for (count = 0; count <= MAX_WAIT_COMMAND; count++)
   {
     if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
     {
       if(!( (*(uint_32 *)&(NFC_SRAM_B1_REG(nfc_ptr, 0)) & 0xFF000000)))
       {
         result = NANDFLASHERR_BLOCK_BAD;
       }
       else
       {
         if(  (nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH == 16)
            &&(!(*(uint_32 *)&NFC_SRAM_B1_REG(nfc_ptr, 0) & 0x00FF0000))
         )
         {
           result = NANDFLASHERR_BLOCK_BAD;
         }
         else
         {
           result = NANDFLASHERR_BLOCK_NOT_BAD;
         }
       }
       break;
     }
   }

   /* Set the ECCMODE back */
   nfc_ptr->CFG = cfg_bck;

   return(result);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_mark_block_as_bad
* Returned Value   : NANDFLASHERR_NO_ERROR or
*                    NANDFLASHERR_WRITE_FAILED or
*                    NANDFLASHERR_TIMEOUT
* Comments         :
*    This function marks the defined NAND Flash block as bad
*    using the NFC module (writing 0x00 to the first spare area byte).
*
*END*----------------------------------------------------------------------*/

uint_32 nfc_mark_block_as_bad
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr,

      /* [IN] block to mark as bad */
      uint_32                 block_number
   )
{ /* Body */

   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count, cfg_bck, col;

   NFC_MemMapPtr  nfc_ptr;

   nfc_erase_block(nandflash_ptr, block_number, FALSE);

   if (nandflash_ptr->WRITE_PROTECT) {
      (*nandflash_ptr->WRITE_PROTECT)(nandflash_ptr, FALSE);
   }/* Endif */

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   /* Set the ECCMODE to 0 - ECC bypass */
   cfg_bck = nfc_ptr->CFG;
   nfc_ptr->CFG &= ~(NFC_CFG_ECCMODE(7));

   col = nandflash_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE;
   if(nandflash_ptr->NANDFLASH_INFO_PTR->WIDTH == 16)
      col = col/2;

   /* Reset the swap register */
   nfc_ptr->SWAP  = NFC_SWAP_ADDR1(0x7FF) |
                    NFC_SWAP_ADDR2(0x7FF);

   /* Prepare bad block bytes in the SRAM buffer #0,
      no matter if the NAND Flash width is 8 or 16 */
   *(uint_32 *)&NFC_SRAM_B0_REG(nfc_ptr, 0) = 0;

   nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_PROGRAM_CYCLE2) |
                   NFC_CMD1_BYTE3(NANDFLASH_CMD_READ_STATUS);
   nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_PROGRAM_CYCLE1) |
                   NFC_CMD2_CODE(0x7FD8) |
                   NFC_CMD2_BUFNO(0);
   nfc_ptr->CAR  = col & 0xFFFF;
   nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                   NFC_RAR_RB0_MASK |
                   ((nandflash_ptr->NANDFLASH_INFO_PTR->BLOCK_SIZE /
                     nandflash_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE * block_number) & 0xFFFFFF);
   nfc_ptr->SECSZ  = 3;

   nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK |
                     NFC_ISR_DONEEN_MASK  |
                     NFC_ISR_IDLECLR_MASK |
                     NFC_ISR_IDLEEN_MASK);

   /* Start command execution */
   nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

   for (count = 0; count <= MAX_WAIT_COMMAND; count++)
   {
     if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
     {
        if (nfc_ptr->SR2 & NANDFLASH_STATUS_ERR)
        {
           result = NANDFLASHERR_WRITE_FAILED;
        }
        else
        {
           result = NANDFLASHERR_NO_ERROR;
        }
        break;
     }
   }

   if (nandflash_ptr->WRITE_PROTECT) {
      (*nandflash_ptr->WRITE_PROTECT)(nandflash_ptr, TRUE);
   }/* Endif */

   /* Set the ECCMODE back */
   nfc_ptr->CFG = cfg_bck;

   return(result);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_read_ID
* Returned Value   : NANDFLASHERR_NO_ERROR or
*                    NANDFLASHERR_TIMEOUT
* Comments         :
*    This function reads the ID from the NAND Flash
*    using the NFC module.
*
*END*----------------------------------------------------------------------*/

uint_32 nfc_read_ID
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr,

      /* [IN] where to store ID */
      uchar_ptr               to_ptr,

      /* [IN] the amount of ID bytes */
      _mem_size               size
   )
{ /* Body */

   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count1, count2;
   NFC_MemMapPtr  nfc_ptr;

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   nfc_ptr->CMD2  =  NFC_CMD2_BYTE1(NANDFLASH_CMD_READ_ID) |
                     NFC_CMD2_CODE(0x4804);
   nfc_ptr->ISR  |= (NFC_ISR_IDLECLR_MASK | NFC_ISR_IDLEEN_MASK |
                     NFC_ISR_DONECLR_MASK | NFC_ISR_DONEEN_MASK);

   /* Start command execution */
   nfc_ptr->CMD2 |=  NFC_CMD2_BUSY_START_MASK;

   for (count1 = 0; count1 <= MAX_WAIT_COMMAND; count1++)
   {
       if (nfc_ptr->ISR & NFC_ISR_DONE_MASK)
       {
           for (count2 = 0; count2 < size; count2++)
           {
             to_ptr[count2] = *(uchar_ptr)((uint_32)&nfc_ptr->SR1 + count2);
           }
           result = NANDFLASHERR_NO_ERROR;
           break;
       }
   }
   return result;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : nfc_ioctl
* Returned Value   : TRUE if successful
* Comments         :
*    nfc ioctl function
*
*END*----------------------------------------------------------------------*/
_mqx_int nfc_ioctl
   (
      /* [IN] the handle returned from _fopen */
      IO_NANDFLASH_STRUCT_PTR handle_ptr,

      /* [IN] the ioctl command */
      _mqx_uint               cmd,

      /* [IN] the ioctl parameters */
      pointer                 param_ptr
   )
{ /* Body */
    _mqx_uint result = MQX_OK;
    switch(cmd) {
        case NANDFLASH_IOCTL_GET_ID:
            /* Get the NAND Flash ID */
            if ((nfc_read_ID(handle_ptr, param_ptr, 4)) == NANDFLASHERR_NO_ERROR)
            {
                result = MQX_OK;
            }
            else
            {
                result = IO_ERROR_INVALID_IOCTL_CMD;
            }
            break;
        default:
            break;
    }
    return result;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_stop.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_stop.c$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the MACNET shutdown functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "macnet_prv.h"          

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_shutdown
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Stops the chip.
*
*END*-----------------------------------------------------------------*/

uint_32 MACNET_shutdown
   (
      ENET_CONTEXT_STRUCT_PTR  enet_ptr
         /* [IN] the Ethernet state structure */
   )
{ /* Body */
   MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   ENET_MemMapPtr              macnet_ptr= macnet_context_ptr->MACNET_ADDRESS;

   if (macnet_ptr == NULL) return ENETERR_INVALID_DEVICE;

   /* Stop the chip */
   macnet_ptr->ECR = ENET_ECR_RESET_MASK;

   /* Disable all MACNET interrupts */
   macnet_ptr->EIMR = 0;

   /* clear any pending interrpts */
   macnet_ptr->EIR = ENET_EIR_ALL_PENDING;

   /* Stop the MACNET from interrupting the core */
    MACNET_mask_interrupts( enet_ptr );

   #if BSPCFG_ENET_RESTORE
      /* Restore old ISRs */
      MACNET_uninstall_all_isrs( enet_ptr );
   #endif

    /*
    ** Make sure all PCBs are free
    */
    if (macnet_context_ptr->ActiveRxBDs != macnet_context_ptr->NumRxBDs) {
       return ENETERR_FREE_PCB;
    } 

   MACNET_free_context(macnet_context_ptr);
   return ENET_OK;

} 


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/polled/serl_pol.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_pol.c$
* $Version : 3.8.12.0$
* $Date    : Aug-29-2011$
*
* Comments:
*
*   This file contains the driver functions for the polled serial
*   asynchronous character I/O.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "serial.h"
#include "charq.h"
#include "bsp.h"        /* BSP_SERIAL_POLLED_WRAPPER */
#include "bsp_prv.h"    /* BSP_SERIAL_POLLED_WRAPPER */
#include "serplprv.h"


#if MQX_ENABLE_LOW_POWER

extern LPM_NOTIFICATION_RESULT _io_serial_polled_clock_configuration_callback (LPM_NOTIFICATION_STRUCT_PTR, pointer);
extern LPM_NOTIFICATION_RESULT _io_serial_polled_operation_mode_callback (LPM_NOTIFICATION_STRUCT_PTR, pointer);

#endif


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_serial_polled_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a polled serial device.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_serial_polled_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr             identifier,

      /* [IN] The I/O init function */
      _mqx_uint (_CODE_PTR_ init)(pointer, pointer _PTR_, char _PTR_),

      /* [IN] The I/O de-init function */
      _mqx_uint (_CODE_PTR_ deinit)(pointer, pointer),

      /* [IN] The input function */
      char     (_CODE_PTR_ getc)(pointer),

      /* [IN] The output function */
      void     (_CODE_PTR_ putc)(pointer, char),

      /* [IN] The char available (status) function */
      boolean  (_CODE_PTR_ status)(pointer),

      /* [IN] The I/O ioctl function */
      _mqx_uint (_CODE_PTR_ ioctl)(pointer, _mqx_uint, pointer),

      /* [IN] The I/O init data pointer */
      pointer              init_data_ptr,

      /* [IN] The I/O queue size to use */
      _mqx_uint             queue_size
   )
{ /* Body */
   IO_SERIAL_POLLED_DEVICE_STRUCT_PTR dev_ptr;
   _mqx_uint result;

   dev_ptr = _mem_alloc_system_zero((_mem_size)
      sizeof(IO_SERIAL_POLLED_DEVICE_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(dev_ptr,MEM_TYPE_IO_SERIAL_POLLED_DEVICE_STRUCT); 
   dev_ptr->DEV_INIT          = init;
   dev_ptr->DEV_DEINIT        = deinit;
   dev_ptr->DEV_GETC          = getc;
   dev_ptr->DEV_PUTC          = putc;
   dev_ptr->DEV_STATUS        = status;
   dev_ptr->DEV_IOCTL         = ioctl;
   dev_ptr->DEV_INIT_DATA_PTR = init_data_ptr;
   dev_ptr->QUEUE_SIZE        = queue_size;

#ifdef BSP_SERIAL_POLLED_WRAPPER
   /*
   ** Allow the BSP to wrap the I/O functions with a composite
   ** object that delivers the characters to a debugger window
   */
   BSP_SERIAL_POLLED_WRAPPER(dev_ptr);
#endif

   result = _io_dev_install(identifier,
   _io_serial_polled_open, _io_serial_polled_close,
   _io_serial_polled_read, _io_serial_polled_write,
   _io_serial_polled_ioctl,
   (pointer)dev_ptr);
   
#if MQX_ENABLE_LOW_POWER
   if (MQX_OK == result)
   {
      LPM_REGISTRATION_STRUCT registration;
      registration.CLOCK_CONFIGURATION_CALLBACK = _io_serial_polled_clock_configuration_callback;
      registration.OPERATION_MODE_CALLBACK = _io_serial_polled_operation_mode_callback;
      registration.DEPENDENCY_LEVEL = BSP_LPM_DEPENDENCY_LEVEL_SERIAL_POLLED;          
      result = _lpm_register_driver (&registration, dev_ptr, &(dev_ptr->LPM_INFO.REGISTRATION_HANDLE));
      if (MQX_OK == result)
      {
         _lwsem_create (&(dev_ptr->LPM_INFO.LOCK), 1);
         dev_ptr->LPM_INFO.FLAGS = 0;
      }
   }
#endif
   
   return result;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_serial_polled_uninstall
* Returned Value   : _mqx_int a task error code or MQX_OK
* Comments         :
*    Un-Install a polled serial device.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_serial_polled_uninstall
   (
      /* [IN] The IO device structure for the device */
      IO_DEVICE_STRUCT_PTR   io_dev_ptr
   )
{ /* Body */
   IO_SERIAL_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

   if (polled_dev_ptr->COUNT == 0) {
      if (polled_dev_ptr->DEV_DEINIT) {

#if MQX_ENABLE_LOW_POWER          
         _lwsem_wait (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
         (*polled_dev_ptr->DEV_DEINIT)(polled_dev_ptr->DEV_INIT_DATA_PTR,
            polled_dev_ptr->DEV_INFO_PTR);
#if MQX_ENABLE_LOW_POWER          
         _lwsem_post (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
          
      } /* Endif */
      if (polled_dev_ptr->CHARQ) {
         _mem_free(polled_dev_ptr->CHARQ);
      } /* Endif */
      polled_dev_ptr->CHARQ = NULL;
      
#if MQX_ENABLE_LOW_POWER
      _lpm_unregister_driver (polled_dev_ptr->LPM_INFO.REGISTRATION_HANDLE);
      _lwsem_destroy (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
   
      _mem_free(polled_dev_ptr);
      io_dev_ptr->DRIVER_INIT_PTR = NULL;  
      return(IO_OK);
   } else {
      return(IO_ERROR_DEVICE_BUSY);
   } /* Endif */

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _io_serial_polled_open
* Returned Value   : _mqx_int error code
* Comments         :
*    This routine initializes a polled serial I/O channel. It acquires
*    memory, then stores information into it about the channel.
*    It then calls the hardware interface function to initialize the channel.
*
*END**********************************************************************/

_mqx_int _io_serial_polled_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the remaining portion of the name of the device */
      char       _PTR_ open_name_ptr,

      /* [IN] the flags to be used during operation:
      ** echo, translation, xon/xoff, encoded into a pointer.
      */
      char       _PTR_ flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR               io_dev_ptr;
   IO_SERIAL_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;
   _mqx_uint                          result = MQX_OK;
   _mqx_uint                          ioctl_val;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   if (polled_dev_ptr->COUNT) {
      /* Device is already opened */
      polled_dev_ptr->COUNT++;
      fd_ptr->FLAGS = polled_dev_ptr->FLAGS;
      return(result);
   } /* Endif */

   polled_dev_ptr->CHARQ = (CHARQ_STRUCT_PTR)_mem_alloc_system((_mem_size)(
      sizeof(CHARQ_STRUCT) - (4 * sizeof(char)) + polled_dev_ptr->QUEUE_SIZE));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (polled_dev_ptr->CHARQ == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(polled_dev_ptr->CHARQ,MEM_TYPE_IO_SERIAL_CHARQ);    
         
   _CHARQ_INIT(polled_dev_ptr->CHARQ, polled_dev_ptr->QUEUE_SIZE);
   polled_dev_ptr->FLAGS = (_mqx_uint)flags;
   fd_ptr->FLAGS = (_mqx_uint)flags;

#if MQX_ENABLE_LOW_POWER          
   _lwsem_wait (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
   result = (*polled_dev_ptr->DEV_INIT)(polled_dev_ptr->DEV_INIT_DATA_PTR,
      &polled_dev_ptr->DEV_INFO_PTR, open_name_ptr);
#if MQX_ENABLE_LOW_POWER          
   _lwsem_post (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif

   if (result == MQX_OK) {
      if ((polled_dev_ptr->DEV_IOCTL) != NULL) {
         ioctl_val = (_mqx_uint)flags;
         (*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_SET_FLAGS, &ioctl_val);
      }
      if ((_mqx_uint)flags & IO_SERIAL_NON_BLOCKING) {
         if ((_mqx_uint)flags & (IO_SERIAL_TRANSLATION | IO_SERIAL_ECHO | IO_SERIAL_XON_XOFF)) {
            result = MQX_INVALID_PARAMETER;
         } else {
            if ((polled_dev_ptr->DEV_IOCTL) != NULL) {
               result = (*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_CAN_TRANSMIT, &ioctl_val);      
            }
         }
      }
   }   
   
   if (result != MQX_OK) {
      _mem_free(polled_dev_ptr->CHARQ);
      return(result);
   } /* Endif */
   polled_dev_ptr->COUNT    = 1;

   return(result);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _io_serial_polled_close
* Returned Value   : _mqx_int error code
* Comments         :
*    This routine closes the polled serial I/O channel.
*
*END**********************************************************************/

_mqx_int _io_serial_polled_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR               io_dev_ptr;
   IO_SERIAL_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;
   _mqx_int                            result = MQX_OK;

   io_dev_ptr = fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   if (--polled_dev_ptr->COUNT == 0) {
      /* Device is ready to be closed */
      if (polled_dev_ptr->DEV_DEINIT) {
          
#if MQX_ENABLE_LOW_POWER          
         _lwsem_wait (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
         result = (*polled_dev_ptr->DEV_DEINIT)(polled_dev_ptr->DEV_INIT_DATA_PTR,
            polled_dev_ptr->DEV_INFO_PTR);
#if MQX_ENABLE_LOW_POWER          
         _lwsem_post (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
          
      } /* Endif */
      _mem_free(polled_dev_ptr->CHARQ);
      polled_dev_ptr->CHARQ = NULL;
   } /* Endif */
   return(result);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _io_serial_polled_read
* Returned Value   : _mqx_int number of characters read
* Comments         :
*    This routine reads characters from the serial I/O channel
*    device, converting carriage return ('\r') characters to newlines,
*    and then echoing the input characters.
*
*END*********************************************************************/

_mqx_int _io_serial_polled_read
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the characters are to be stored */
      char_ptr   data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int   num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR               io_dev_ptr;
   IO_SERIAL_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;
   uchar                              character;
   _mqx_uint                          flags;
   _mqx_uint                          i = num;
   pointer                            info_ptr;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
   flags          = polled_dev_ptr->FLAGS;
   info_ptr       = polled_dev_ptr->DEV_INFO_PTR;

   while ( i ) {

      if (flags & IO_SERIAL_XON_XOFF) {
         while ((! _CHARQ_FULL(polled_dev_ptr->CHARQ)) &&
            (*polled_dev_ptr->DEV_STATUS)(info_ptr))
         {
            character = (*polled_dev_ptr->DEV_GETC)(info_ptr);
            if (character == CNTL_S) {
               while (character != CNTL_Q) {
                  character = (uchar)(*polled_dev_ptr->DEV_GETC)(info_ptr);
                  if (character != CNTL_Q) {
                     _CHARQ_ENQUEUE(polled_dev_ptr->CHARQ, character);
                  } /* Endif */
               } /* Endwhile */
            } else {
               _CHARQ_ENQUEUE(polled_dev_ptr->CHARQ, character);
            } /* Endif */
         } /* Endwhile */
      } else {
         while ((! _CHARQ_FULL(polled_dev_ptr->CHARQ)) &&
                (*polled_dev_ptr->DEV_STATUS)(info_ptr))
         {
            character = (uchar)(*polled_dev_ptr->DEV_GETC)(info_ptr);
            _CHARQ_ENQUEUE(polled_dev_ptr->CHARQ, character);
         } /* Endwhile */
      } /* Endif */

      if ( _CHARQ_SIZE(polled_dev_ptr->CHARQ) ) {
         _CHARQ_DEQUEUE(polled_dev_ptr->CHARQ, character);
         if (flags & IO_SERIAL_TRANSLATION) {
            if (character == '\r') {
               if (flags & IO_SERIAL_ECHO) {
                  (*polled_dev_ptr->DEV_PUTC)(info_ptr, (char)'\r');
               } /* Endif */
               character = '\n';
            } else if ( (character == '\b') && (flags & IO_SERIAL_ECHO) ) {
               (*polled_dev_ptr->DEV_PUTC)(info_ptr, (char)'\b');
               (*polled_dev_ptr->DEV_PUTC)(info_ptr, (char)' ');
            } /* Endif */
         } /* Endif */
         if (flags & IO_SERIAL_ECHO) {
            (*polled_dev_ptr->DEV_PUTC)(info_ptr, (char)character);
         } /* Endif */
         *data_ptr++ = character;
         --i;
      } else {
         if (flags & IO_SERIAL_NON_BLOCKING) {
            num -= i;
            break;  
         } /* Endif */
      } /* Endif */
   } /* Endwhile */
   return num;

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _io_serial_polled_write
* Returned Value   : _mqx_int number of characters written
* Comments         :
*    This routine writes characters to the serial I/O channel.
*    It monitors for input of ^S and ^Q (XON, XOFF protocol)
*    It also converts the C '\n' into '\n\r'.
*
*END**********************************************************************/

_mqx_int _io_serial_polled_write
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the characters are */
      char_ptr  data_ptr,

      /* [IN] the number of characters to output */
      _mqx_int  num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR               io_dev_ptr;
   IO_SERIAL_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;
   uchar                              character;
   _mqx_uint                           flags;
   _mqx_uint                           i = num + 1;
   pointer                            info_ptr;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
   flags          = polled_dev_ptr->FLAGS;
   info_ptr       = polled_dev_ptr->DEV_INFO_PTR;

#if MQX_ENABLE_LOW_POWER          
   _lwsem_wait (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
            
   while (--i) {

      if (flags & IO_SERIAL_XON_XOFF) {
         while ((! _CHARQ_FULL(polled_dev_ptr->CHARQ)) &&
                (*polled_dev_ptr->DEV_STATUS)(info_ptr))
         {
            character = (uchar)(*polled_dev_ptr->DEV_GETC)(info_ptr);
            if (character == CNTL_S) {
               while ( character != CNTL_Q ) {
                  character = (uchar)(*polled_dev_ptr->DEV_GETC)(info_ptr);
                  if (character != CNTL_Q) {
                     _CHARQ_ENQUEUE(polled_dev_ptr->CHARQ, character);
                  } /* Endif */
               } /* Endwhile */
            } else {
               _CHARQ_ENQUEUE(polled_dev_ptr->CHARQ,character);
            } /* Endif */
         } /* Endwhile */
      } /* Endif */

      if (flags & IO_SERIAL_TRANSLATION) {
         if (*data_ptr == '\n') {
            (*polled_dev_ptr->DEV_PUTC)(info_ptr, '\r');
         } /* Endif */
      } /* Endif */
      
      if(flags & IO_SERIAL_NON_BLOCKING){
         if ((polled_dev_ptr->DEV_IOCTL) != NULL){
            uint_32 txflags;
            if ((*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR,IO_IOCTL_SERIAL_CAN_TRANSMIT, &txflags) == MQX_OK){
               if (!txflags) {
                  num-=i;
                  break;
               } /* Endif */
            } /* Endif */
         } /* Endif */
      } /* Endif */
      (*polled_dev_ptr->DEV_PUTC)(polled_dev_ptr->DEV_INFO_PTR, *data_ptr++);
   } /* Endwhile */

#if MQX_ENABLE_LOW_POWER          
   _lwsem_post (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
            
   return num;

} /* Endbody */


/*FUNCTION*****************************************************************
*
* Function Name    : _io_serial_polled_ioctl
* Returned Value   : _mqx_int
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_serial_polled_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR   fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint      cmd,

      /* [IN] the ioctl parameters */
      pointer        param_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR               io_dev_ptr;
   IO_SERIAL_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;
   _mqx_uint                          result = MQX_OK;
   boolean _PTR_                      bparam_ptr;
   _mqx_uint_ptr                      pparam_ptr;
   _mqx_uint_ptr                      uparam_ptr = (_mqx_uint_ptr)param_ptr;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   switch (cmd) {
      case IO_IOCTL_CHAR_AVAIL:
         bparam_ptr = (boolean _PTR_)param_ptr;
         if ( _CHARQ_SIZE(polled_dev_ptr->CHARQ) ) {
           *bparam_ptr = TRUE;
         } else {
           *bparam_ptr = (*polled_dev_ptr->DEV_STATUS)(
              polled_dev_ptr->DEV_INFO_PTR);
         } /* Endif */
         break;

      case IO_IOCTL_SERIAL_GET_FLAGS:
         pparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *pparam_ptr = polled_dev_ptr->FLAGS;
         break;

      case IO_IOCTL_SERIAL_SET_FLAGS:
         pparam_ptr  = (_mqx_uint_ptr)param_ptr;
         polled_dev_ptr->FLAGS = *pparam_ptr;
         fd_ptr->FLAGS = *pparam_ptr;
         if (polled_dev_ptr->DEV_IOCTL != NULL) {
            result = (*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR,
               cmd, param_ptr);
         } /* Endif */
         break;

      case IO_IOCTL_UNINSTALL:
      
      case IO_IOCTL_DEVICE_IDENTIFY :
         /* return the device identify */
         uparam_ptr[0] = IO_DEV_TYPE_PHYS_SERIAL_POLLED;
         uparam_ptr[1] = 0;
         uparam_ptr[2] = IO_DEV_ATTR_POLL | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
         result = MQX_OK;   
         break;

      default:
         if (polled_dev_ptr->DEV_IOCTL != NULL) {
            result = (*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR,
               cmd, param_ptr);
         } /* Endif */
         break;
   } /* Endswitch */
   return result;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio_mcf5225.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio_mcf5225.h$
* $Version : 3.8.9.1$
* $Date    : Aug-1-2012$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/
#ifndef __lwgpio_mcf5225_h__
#define __lwgpio_mcf5225_h__ 1

#define LWGPIO_PIN_VALID (0x80000000) /* Note: this is for backwards compatibility with GPIO driver only */

/* Pin field definitions */
#define LWGPIO_PIN_SHIFT (0)
#define LWGPIO_PIN_MASK (0x7 << LWGPIO_PIN_SHIFT)

#define LWGPIO_PIN(x) (((x) << LWGPIO_PIN_SHIFT) & LWGPIO_PIN_MASK)

/* Pin attributes */
#define LWGPIO_ATTR_BASE            (0x100)
#define LWGPIO_ATTR_SLEW_RATE       (LWGPIO_ATTR_BASE+1)
#define LWGPIO_ATTR_DRIVE_STRENGTH  (LWGPIO_ATTR_BASE+2)

/*attributes value*/
#define LWGPIO_AVAL_SLEW_RATE_FAST        (0)
#define LWGPIO_AVAL_SLEW_RATE_SLOW        (1)
#define LWGPIO_AVAL_DRIVE_STRENGTH_HIGH   (1)
#define LWGPIO_AVAL_DRIVE_STRENGTH_LOW    (0)

/* Port field definitions */
#define LWGPIO_PORT_SHIFT (3)
#define LWGPIO_PORT_MASK (0xFF << LWGPIO_PORT_SHIFT)
#define LWGPIO_PORT(x) (((x) << LWGPIO_PORT_SHIFT) & LWGPIO_PORT_MASK)
#define LWGPIO_PORT_TE (LWGPIO_PORT(0) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_TF (LWGPIO_PORT(1) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_TG (LWGPIO_PORT(2) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_TH (LWGPIO_PORT(3) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_TI (LWGPIO_PORT(4) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_TJ (LWGPIO_PORT(6) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_NQ (LWGPIO_PORT(8) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_AN (LWGPIO_PORT(10) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_AS (LWGPIO_PORT(11) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_QS (LWGPIO_PORT(12) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_TA (LWGPIO_PORT(14) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_TC (LWGPIO_PORT(15) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_UA (LWGPIO_PORT(17) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_UB (LWGPIO_PORT(18) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_UC (LWGPIO_PORT(19) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_DD (LWGPIO_PORT(20) | LWGPIO_PIN_VALID)

#define LWGPIO_PIN0   (0)
#define LWGPIO_PIN1   (1)
#define LWGPIO_PIN2   (2)
#define LWGPIO_PIN3   (3)
#define LWGPIO_PIN4   (4)
#define LWGPIO_PIN5   (5)
#define LWGPIO_PIN6   (6)
#define LWGPIO_PIN7   (7)

typedef struct {
    uint_8  port_idx;
    uint_8  pinmask; /* since struct holds one pin, pinmask will have only one bit set */
    uint_32 flags;
} LWGPIO_STRUCT, _PTR_ LWGPIO_STRUCT_PTR;

#define LWGPIO_MUX_DD0_GPIO  (0)
#define LWGPIO_MUX_DD1_GPIO  (0)
#define LWGPIO_MUX_DD2_GPIO  (0)
#define LWGPIO_MUX_DD3_GPIO  (0)
#define LWGPIO_MUX_DD4_GPIO  (0)
#define LWGPIO_MUX_DD5_GPIO  (0)
#define LWGPIO_MUX_DD6_GPIO  (0)
#define LWGPIO_MUX_DD7_GPIO  (0)

#define LWGPIO_MUX_AN0_GPIO  (0)
#define LWGPIO_MUX_AN1_GPIO  (0)
#define LWGPIO_MUX_AN2_GPIO  (0)
#define LWGPIO_MUX_AN3_GPIO  (0)
#define LWGPIO_MUX_AN4_GPIO  (0)
#define LWGPIO_MUX_AN5_GPIO  (0)
#define LWGPIO_MUX_AN6_GPIO  (0)
#define LWGPIO_MUX_AN7_GPIO  (0)

#define LWGPIO_MUX_TE0_GPIO  (0)
#define LWGPIO_MUX_TE1_GPIO  (0)
#define LWGPIO_MUX_TE2_GPIO  (0)
#define LWGPIO_MUX_TE3_GPIO  (0)
#define LWGPIO_MUX_TE4_GPIO  (0)
#define LWGPIO_MUX_TE5_GPIO  (0)
#define LWGPIO_MUX_TE6_GPIO  (0)
#define LWGPIO_MUX_TE7_GPIO  (0)

#define LWGPIO_MUX_TF0_GPIO  (0)
#define LWGPIO_MUX_TF1_GPIO  (0)
#define LWGPIO_MUX_TF2_GPIO  (0)
#define LWGPIO_MUX_TF3_GPIO  (0)
#define LWGPIO_MUX_TF4_GPIO  (0)
#define LWGPIO_MUX_TF5_GPIO  (0)
#define LWGPIO_MUX_TF6_GPIO  (0)
#define LWGPIO_MUX_TF7_GPIO  (0)

#define LWGPIO_MUX_TG0_GPIO  (0)
#define LWGPIO_MUX_TG1_GPIO  (0)
#define LWGPIO_MUX_TG2_GPIO  (0)
#define LWGPIO_MUX_TG3_GPIO  (0)
#define LWGPIO_MUX_TG4_GPIO  (0)
#define LWGPIO_MUX_TG5_GPIO  (0)
#define LWGPIO_MUX_TG6_GPIO  (0)
#define LWGPIO_MUX_TG7_GPIO  (0)

#define LWGPIO_MUX_TI0_GPIO  (0)
#define LWGPIO_MUX_TI1_GPIO  (0)
#define LWGPIO_MUX_TI2_GPIO  (0)
#define LWGPIO_MUX_TI3_GPIO  (0)
#define LWGPIO_MUX_TI4_GPIO  (0)
#define LWGPIO_MUX_TI5_GPIO  (0)
#define LWGPIO_MUX_TI6_GPIO  (0)
#define LWGPIO_MUX_TI7_GPIO  (0)

#define LWGPIO_MUX_TJ0_GPIO  (0)
#define LWGPIO_MUX_TJ1_GPIO  (0)
#define LWGPIO_MUX_TJ2_GPIO  (0)
#define LWGPIO_MUX_TJ3_GPIO  (0)
#define LWGPIO_MUX_TJ4_GPIO  (0)
#define LWGPIO_MUX_TJ5_GPIO  (0)
#define LWGPIO_MUX_TJ6_GPIO  (0)
#define LWGPIO_MUX_TJ7_GPIO  (0)

#define LWGPIO_MUX_UC0_GPIO  (0)
#define LWGPIO_MUX_UC1_GPIO  (0)
#define LWGPIO_MUX_UC2_GPIO  (0)
#define LWGPIO_MUX_UC3_GPIO  (0)

#define LWGPIO_MUX_QS0_GPIO  (0)
#define LWGPIO_MUX_QS1_GPIO  (0)
#define LWGPIO_MUX_QS2_GPIO  (0)
#define LWGPIO_MUX_QS3_GPIO  (0)
#define LWGPIO_MUX_QS5_GPIO  (0)
#define LWGPIO_MUX_QS6_GPIO  (0)

#define LWGPIO_MUX_TH0_GPIO  (0)
#define LWGPIO_MUX_TH1_GPIO  (0)
#define LWGPIO_MUX_TH2_GPIO  (0)
#define LWGPIO_MUX_TH3_GPIO  (0)
#define LWGPIO_MUX_TH4_GPIO  (0)
#define LWGPIO_MUX_TH5_GPIO  (0)
#define LWGPIO_MUX_TH6_GPIO  (0)
#define LWGPIO_MUX_TH7_GPIO  (0)

#define LWGPIO_MUX_AS0_GPIO  (0)
#define LWGPIO_MUX_AS1_GPIO  (0)
#define LWGPIO_MUX_AS2_GPIO  (0)

#define LWGPIO_MUX_TA0_GPIO  (0)
#define LWGPIO_MUX_TA1_GPIO  (0)
#define LWGPIO_MUX_TA2_GPIO  (0)
#define LWGPIO_MUX_TA3_GPIO  (0)

#define LWGPIO_MUX_TC0_GPIO  (0)
#define LWGPIO_MUX_TC1_GPIO  (0)
#define LWGPIO_MUX_TC2_GPIO  (0)
#define LWGPIO_MUX_TC3_GPIO  (0)

#define LWGPIO_MUX_UA0_GPIO  (0)
#define LWGPIO_MUX_UA1_GPIO  (0)
#define LWGPIO_MUX_UA2_GPIO  (0)
#define LWGPIO_MUX_UA3_GPIO  (0)

#define LWGPIO_MUX_UB0_GPIO  (0)
#define LWGPIO_MUX_UB1_GPIO  (0)
#define LWGPIO_MUX_UB2_GPIO  (0)
#define LWGPIO_MUX_UB3_GPIO  (0)

#define LWGPIO_MUX_UC0_GPIO  (0)
#define LWGPIO_MUX_UC1_GPIO  (0)
#define LWGPIO_MUX_UC2_GPIO  (0)
#define LWGPIO_MUX_UC3_GPIO  (0)

#define LWGPIO_MUX_NQ1_GPIO  (0)
#define LWGPIO_MUX_NQ3_GPIO  (0)
#define LWGPIO_MUX_NQ5_GPIO  (0)
#define LWGPIO_MUX_NQ7_GPIO  (0)

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcs_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcs_prv.h$
* $Version : 3.8.13.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the include files for the
*   RTCS Communication Library.
*
*END************************************************************************/

#ifndef __rtcs_prv_h__
#define __rtcs_prv_h__

#include "rtcspcb.h"

/*
** RTCS queue numbers
*/
#define TCPIP_QUEUE     _RTCSQUEUE_base


/*
** Maximum number of protocols that can be logged
*/
#define RTCSLOG_PROT_MAX   16


/*
** Macro definitions for manipulating common data structures
*/

   /*
   ** RTCS_QUEUE: a singly-linked FIFO list
   **
   ** - requires a head and a tail
   ** - each element requires a field called NEXT
   */

#define RTCS_QUEUE_INIT(head,tail)              \
      (head) = NULL

#define RTCS_QUEUE_PEEK(head,tail,elem)         \
      (elem) = (head)

#define RTCS_QUEUE_INS(head,tail,elem)          \
      (elem)->NEXT = NULL;                      \
      if (head) {                               \
         (tail)->NEXT = (elem);                 \
         (tail) = (elem);                       \
      } else {                                  \
         (head) = (elem);                       \
         (tail) = (elem);                       \
      }

#define RTCS_QUEUE_DEL(head,tail)               \
      if (head) {                               \
         (head) = (head)->NEXT;                 \
      }

#define RTCS_QUEUE_DEL_NONEMPTY(head,tail)      \
      (head) = (head)->NEXT

#define RTCS_QUEUE_DELALL(head,tail,elem,temp)  \
      for ((elem)=(head);                       \
           (elem)?(temp)=(elem)->NEXT:0,        \
           (elem);                              \
           (elem)=(temp))

   /*
   ** RTCS_LIST: a singly-linked list
   **
   ** - requires a head
   ** - each element requires a field called NEXT
   */

#define RTCS_LIST_INIT(head)                    \
      (head) = NULL

#define RTCS_LIST_INS(head,elem)                \
      (elem)->NEXT = (head);                    \
      (head) = (elem)

#define RTCS_LIST_INS_END(head,elem,tempp)      \
      for ((tempp)=&(head);                     \
            *(tempp);                           \
            (tempp)=&(*(tempp))->NEXT) ;        \
      *(tempp) = (elem);                        \
      (elem)->NEXT = NULL

#define RTCS_LIST_PEEK(head,elem)               \
      (elem) = (head)

#define RTCS_LIST_SEARCH(head,elem)             \
      for ((elem)=(head);                       \
           (elem);                              \
           (elem)=(elem)->NEXT)

#define RTCS_LIST_DEL(head,elemp)               \
      *(elemp) = (*(elemp))->NEXT

#define RTCS_LIST_SEARCHMOD(head,elemp)         \
      for ((elemp)=&(head);                     \
           *(elemp);                            \
           (elemp)=&(*(elemp))->NEXT)

#define RTCS_LIST_SEARCHMOD_NOHEAD(head,elemp)  \
      for ((elemp)=&(head)->NEXT;               \
           *(elemp);                            \
           (elemp)=&(*(elemp))->NEXT)

   /*
   ** RTCS_DLIST: a doubly-linked list
   **
   ** - requires a head
   ** - each element requires fields called NEXT and PREV
   */

#define RTCS_DLIST_INIT(head)                   \
      (head) = NULL

#define RTCS_DLIST_INS(head,elem)               \
      (elem)->NEXT = (head);                    \
      (elem)->PREV = &(head);                   \
      if (head) {                               \
         (head)->PREV = &(elem)->NEXT;          \
      }                                         \
      (head) = (elem)

#define RTCS_DLIST_PEEK(head,elem)              \
      (elem) = (head)

#define RTCS_DLIST_SEARCH(head,elem)            \
      for ((elem)=(head);                       \
           (elem);                              \
           (elem)=(elem)->NEXT)

#define RTCS_DLIST_SEARCH_REST(head,elem)       \
      for ((elem)=(elem)->NEXT;                 \
           (elem);                              \
           (elem)=(elem)->NEXT)

#define RTCS_DLIST_DEL(head,elem)               \
      if ((elem)->NEXT) {                       \
         (elem)->NEXT->PREV = (elem)->PREV;     \
      }                                         \
      *(elem)->PREV = (elem)->NEXT


/*
** Macro definitions for RTCS
*/

#define RTCSCMD_issue(parm,cmd)      RTCS_cmd_issue(&(parm).COMMON, (void(_CODE_PTR_)(pointer))(cmd))
#define RTCSCMD_internal(parm,cmd)   RTCS_cmd_internal(&(parm).COMMON, (void(_CODE_PTR_)(pointer))(cmd))
#define RTCSCMD_smartissue(parm,cmd) RTCS_cmd_smartissue(&(parm).COMMON, (void(_CODE_PTR_)(pointer))(cmd))
#define RTCSCMD_service(pcb,cmd)     RTCS_cmd_service(pcb, (void(_CODE_PTR_)(pointer))(cmd))
#define RTCSCMD_complete(parm,err)   RTCS_cmd_complete(&(parm)->COMMON, err)

#define RTCS_getcfg(prot)        ((RTCS_DATA_PTR)RTCS_get_data())-> prot ## _CFG
#define RTCS_setcfg(prot,cfg)    ((RTCS_DATA_PTR)RTCS_get_data())-> prot ## _CFG = (cfg)

typedef struct rtcs_data {
   uint_32        VERSION;

   pointer        TCPIP_CFG;
   pointer        SOCKET_CFG;
   pointer        IP_CFG;
   pointer        ICMP_CFG;
   pointer        UDP_CFG;
   pointer        TCP_CFG;

   _pool_id       TCPIP_msg_pool;
   _queue_id      TCPIP_qid;
   _rtcs_part     RTCS_PCB_partition;
   _rtcs_part     RTCS_socket_partition;

#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   pointer        IGMP_CFG;
#endif
#if RTCSCFG_ENABLE_RIP && RTCSCFG_ENABLE_IP4 
   pointer        RIP_CFG;
#endif
#if RTCSCFG_ENABLE_OSPF
   pointer        OSPF_CFG;
#endif

   _rtcs_taskid   TCPIP_TASKID;

#if RTCSCFG_LOG_SOCKET_API || RTCSCFG_LOG_PCB || RTCSCFG_LOGGING
   uint_32        RTCS_LOG_CONTROL;
   uint_32        RTCS_LOG_PROTCOUNT;
   uint_16        RTCS_LOG_PCB[RTCSLOG_PROT_MAX];
   uint_16        RTCS_LOG_TIMER[RTCSLOG_PROT_MAX];
#endif

#if RTCSCFG_ENABLE_NAT
   pointer        NAT_CFG;
#endif
#if RTCSCFG_ENABLE_IPSEC
   pointer        IPSHIELD_CFG;
#endif
#if RTCSCFG_ENABLE_IPIP && RTCSCFG_ENABLE_IP4
   pointer        IPIP_CFG;
#endif
#if RTCSCFG_ENABLE_DNS
   /* Start CR 2170 */
   pointer        DNS_CFG;
   /* End CR 2170 */
#endif

#if RTCSCFG_ENABLE_IP6 //FSL AB
    pointer        IP6_CFG;
    pointer        ICMP6_CFG;
#endif

} RTCS_DATA, _PTR_ RTCS_DATA_PTR;

/*
** externs for RTCS utility procedures
*/

extern void RTCS_seterror
(
   RTCS_ERROR_STRUCT_PTR   errptr,
   uint_32                 errcode,
   uint_32                 errparm
);

extern void RTCS_setsockerror
(
   uint_32     sock,
   uint_32     error
);

extern uint_32 RTCS_cmd_issue      (TCPIP_PARM_PTR, void(_CODE_PTR_)(pointer));
extern uint_32 RTCS_cmd_internal   (TCPIP_PARM_PTR, void(_CODE_PTR_)(pointer));
extern uint_32 RTCS_cmd_smartissue (TCPIP_PARM_PTR, void(_CODE_PTR_)(pointer));
extern boolean RTCS_cmd_service    (RTCSPCB_PTR,    void(_CODE_PTR_)(pointer));
extern void    RTCS_cmd_complete   (TCPIP_PARM_PTR, uint_32);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_disect.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_disect.c$
* $Version : 3.8.9.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <shell.h>
#include <mfs.h>
#include <sh_mfs.h>

#define SECTOR_SIZE 512


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_disect
* Returned Value   :  int_32 error code
* Comments  :  Reads from a file .
*
*END*---------------------------------------------------------------------*/


int_32  Shell_disect(int_32 argc, char_ptr argv[] )
{ /* Body */
   int_32            return_code = SHELL_EXIT_SUCCESS;
   boolean           print_usage, shorthelp = FALSE;
   uint_32           sector,num_sectors;
   int_32            offset=0;
   MQX_FILE_PTR      fd, fs;
   uint_32           e,i;
   uchar_ptr         buffer;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if ((argc < 2) || (argc > 5)) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else if ( !Shell_parse_uint_32(argv[1], (uint_32_ptr) &offset ))  {
         printf("Error, invalid length\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else {
         num_sectors = 1;
         
         if (argc >= 3) {
            if ( !Shell_parse_uint_32(argv[2], (uint_32_ptr) &num_sectors )) {
               num_sectors = 1;
            }
         }      
         if (argc >= 4) {
            fd = fopen(argv[3], "r");
            if (!fd) { 
               printf("Error, unable to open file %s.\n", argv[1] );
               return_code = SHELL_EXIT_ERROR;
            }
         } else {
            fs = Shell_get_current_filesystem(argv);
            _io_ioctl(fs, IO_IOCTL_GET_DEVICE_HANDLE, &fd);
         }
         
         if (fd)  {
            buffer = _mem_alloc(SECTOR_SIZE);
            if (buffer) {
               for(sector=0;sector<num_sectors;sector++) {
                  if (fseek(fd, offset+sector, IO_SEEK_SET) == IO_ERROR)  {
                     printf("Error, unable to seek to sector %s.\n", argv[1] );
                     return_code = SHELL_EXIT_ERROR;
                  } else if (_io_read(fd, (char_ptr) buffer, 1) != 1) {
                     printf("Error, unable to read sector %s.\n", argv[1] );
                     return_code = SHELL_EXIT_ERROR;
                  } else { 
                     printf("\nSector # %d\n",offset+sector);
                     for (e=0;e<16;e++)  {
                        for (i=0;i<32;i++) {
                           printf("%02x ",(uint_32) buffer[e*32+i]);
                        }
                        printf("\n");
                     }
                  }
               }
               _mem_free(buffer);
            }
         }
         printf("\n");
         if (argc >= 4) {
            fclose(fd);
         }
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <sector> [<device>]\n", argv[0]);
      } else  {
         printf("Usage: %s <sector> [<device>]\n", argv[0]);
         printf("   <sector>     = sector number\n");
         printf("   <device>     = low level device\n");
      }
   }
   
   return return_code;
} /* Endbody */

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/ehci/ehci_shut.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_shut.c$
* $Version : 3.8.10.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the low-level Host API functions specific to the VUSB 
*   chip for shutting down the host controller.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "hostapi.h"
#include "ehci_prv.h"

#include "ehci_shut.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_shutdown
*  Returned Value : None
*  Comments       :
*     Shutdown and de-initialize the VUSB1.1 hardware
*
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_ehci_shutdown
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR    usb_host_ptr;
   VUSB20_REG_STRUCT_PTR             dev_ptr;
   ACTIVE_QH_MGMT_STRUCT_PTR         active_list_member_ptr, temp_ptr = NULL;
   
   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   
   dev_ptr      = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->G.DEV_PTR;
   
   /* Disable interrupts */
   EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR,VUSB20_HOST_INTR_EN_BITS);
      
   /* Stop the controller */
   EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_CMD_RUN_STOP);
   
   /* Reset the controller to get default values */
   EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_CMD_CTRL_RESET);
   
   /**********************************************************
   ensure that periodic list in uninitilized.
   **********************************************************/
   usb_host_ptr->ITD_LIST_INITIALIZED = FALSE;
   usb_host_ptr->SITD_LIST_INITIALIZED = FALSE;
   usb_host_ptr->PERIODIC_LIST_INITIALIZED = FALSE;
   usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR = NULL;
   
   /**********************************************************
   Free all memory occupied by active transfers   
   **********************************************************/
   active_list_member_ptr = usb_host_ptr->ACTIVE_ASYNC_LIST_PTR;
   while(active_list_member_ptr) 
   {
      temp_ptr =  active_list_member_ptr;
      active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR)active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
      USB_mem_free(temp_ptr);
   }

   active_list_member_ptr = usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR;
   while(active_list_member_ptr) 
   {
      temp_ptr =  active_list_member_ptr;
      active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \
                              active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
      USB_mem_free(temp_ptr);
      
   }

   /* Free all controller non-periodic specific memory */
   USB_mem_free((pointer)usb_host_ptr->CONTROLLER_MEMORY);

   /* Free all controller periodic specific memory */
   USB_mem_free((pointer)usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR);

#if 0      
   /* Free all controller specific memory, this is now merged into two sections */
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->ASYNC_LIST_BASE_ADDR);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->ITD_BASE_PTR);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->ITD_SCRATCH_STRUCT_BASE);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->SITD_BASE_PTR);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->QTD_BASE_PTR);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->QTD_SCRATCH_STRUCT_BASE);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->SITD_SCRATCH_STRUCT_BASE);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->PERIODIC_LIST_BASE_ADDR);
   USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->QH_SCRATCH_STRUCT_BASE);
#endif

   return USB_OK;
   
} /* EndBody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_DataTypes.h<|end_filename|>
/**********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
********************************************************************************************************************//*!
*
* @file   TSS_DataTypes.h
*
* @brief  Header file that define Types, Structs Types and Constants of the TSS library
*
* @version 1.0.28.0
* 
* @date Sep-20-2012
* 
* These Types, Structs Types and Constants are used by the User Application Level and also internally in the Library
*
***********************************************************************************************************************/


#ifndef TSS_DATATYPES_H
  #define TSS_DATATYPES_H

  /********************************************************************************/
  /* Standard Definitions:                                                        */
  /* These defines allow for easier porting to other compilers. if porting change */
  /* these defines to the required values for the chosen compiler.                */
  /********************************************************************************/

  typedef unsigned char   UINT8;      /* unsigned 8 bit definition */
  typedef unsigned short  UINT16;     /* unsigned 16 bit definition */
  typedef unsigned long   UINT32;     /* unsigned 32 bit definition */
  typedef signed char     INT8;       /* signed 8 bit definition */
  typedef short           INT16;      /* signed 16 bit definition */
  typedef long int        INT32;      /* signed 32 bit definition */

  #ifndef NULL
    #define NULL          ((void *)0) /* NULL as a generic pointer */
  #endif
  
  #ifdef __HCS08__
    #pragma MESSAGE DISABLE C1106       /* WARNING C1106: Non-standard bitfield type */
  #endif

  /************************************************************************/
  /******************* Data Type structures definitions *******************/
  /************************************************************************/

  typedef struct {                    /* Struct for KeyPad Decoder */
                                      /* This struct is for bit-fields only */
      UINT8 ControlNumber     :4;
      UINT8 ControlType       :4;
  } TSS_CONTROL_ID;

  typedef struct {                    /* Struct for KeyPad Decoder */
      UINT8 IdleScanRate      :5;     /* This struct is for bit-fields only */
      UINT8 IdleEnabler       :1;
      UINT8 CallbackEn        :1;
      UINT8 ControlEn         :1;
  } TSS_KEYPAD_CONTCONF;

  typedef struct {                    /* Struct for KeyPad Decoder */
      UINT8 TouchEventEn      :1;     /* This struct is for bit-fields only */
      UINT8 ReleaseEventEn    :1;
      UINT8 AutoRepeatEventEn :1;
      UINT8 BufferFullOvfEn   :1;
      UINT8 KeysExceededEn    :1;
      UINT8                   :1;
      UINT8 BufferOvfFlag     :1;
      UINT8 MaxKeysFlag       :1;
  } TSS_KEYPAD_EVENTS;

  typedef struct {                    /* Struct for Slider Decoder */
      UINT8 IdleScanRate      :5;     /* This struct is for bit-fields only */
      UINT8 IdleEnabler       :1;
      UINT8 CallbackEnabler   :1;
      UINT8 ControlEnabler    :1;
  } TSS_SLIDER_CONTROL;

  typedef struct {                    /* Struct for Slider Decoder */
      UINT8 Displacement      :4;     /* This struct is for bit-fields only */
      UINT8                   :1;
      UINT8                   :1;
      UINT8 Direction         :1;
      UINT8 Movement          :1;
  } TSS_SLIDER_DYN;

  typedef struct {                    /* Struct for Slider Decoder */
      UINT8 Position          :5;     /* This struct is for bit-fields only */
      UINT8                   :1;
      UINT8 InvalidPos        :1;
      UINT8 Touch             :1;
  } TSS_SLIDER_STAT;

  typedef struct{                     /* Struct for Slider Decoder */
      UINT8 InitialTouchEn    :1;     /* This struct is for bit-fields only */
      UINT8 MovementEn        :1;
      UINT8 HoldEn            :1;
      UINT8 AutoRepeatEn      :1;
      UINT8 ReleaseEnabler    :1;
      UINT8                   :1;
      UINT8                   :1;
      UINT8                   :1;
  } TSS_SLIDER_EVENTS;

  typedef struct {                    /* Struct for Analog Slider Decoder */
      UINT8 IdleScanRate      :5;     /* This struct is for bit-fields only */
      UINT8 IdleEnabler       :1;
      UINT8 CallbackEnabler   :1;
      UINT8 ControlEnabler    :1;
  } TSS_ASLIDER_CONTROL;

  typedef struct {                    /* Struct for Analog Slider Decoder */
      UINT8 Displacement      :6;     /* This struct is for bit-fields only */
      UINT8 Direction         :1;
      UINT8 Movement          :1;
  } TSS_ASLIDER_DYN;

  typedef struct{                     /* Struct for Analog Slider Decoder */
      UINT8 InitialTouchEn    :1;     /* This struct is for bit-fields only */
      UINT8 MovementEn        :1;
      UINT8 HoldEn            :1;
      UINT8 AutoRepeatEn      :1;
      UINT8 ReleaseEnabler    :1;
      UINT8                   :1;
      UINT8 InvalidPos        :1;
      UINT8 Touch             :1;            
  } TSS_ASLIDER_EVENTS;

  typedef struct {                    /* Struct for Matrix Decoder */
      UINT8 IdleScanRate      :5;     /* This struct is for bit-fields only */
      UINT8 IdleEnabler       :1;
      UINT8 CallbackEnabler   :1;
      UINT8 ControlEnabler    :1;
  } TSS_MATRIX_CONTROL;

  typedef struct {                    /* Struct for Matrix Decoder */
      UINT8 Displacement      :6;     /* This struct is for bit-fields only */
      UINT8 Direction         :1;      
      UINT8 Movement          :1;
  } TSS_MATRIX_DYN;

  typedef struct {                    /* Struct for Matrix Decoder */
      UINT8 InitialTouchEn    :1;     /* This struct is for bit-fields only */
      UINT8 MovementEn        :1;
      UINT8 HoldEn            :1;
      UINT8 AutoRepeatEn      :1;
      UINT8 ReleaseEnabler    :1;
      UINT8 GesturesEn        :1;
      UINT8 Gesture           :1;            
      UINT8 Touch             :1;
  } TSS_MATRIX_EVENTS;
  
  typedef struct {                    /* Struct for System Setup */
      UINT8 ChargeTimeout      :1;    /* This struct is for bit-fields only */
      UINT8 SmallCapacitor     :1;
      UINT8 DataCorruption     :1;
      UINT8 SmallTriggerPeriod :1;
      UINT8                    :1;
      UINT8                    :1;
      UINT8                    :1;
      UINT8                    :1;
  } TSS_SYSTEM_FAULTS;

 /* LSB first in the structure else MSB first */
#if defined(__BITFIELD_LSBIT_FIRST__)
    typedef struct {                   /* Struct for System Setup */
      UINT16 WaterToleranceEn  :1;      
      UINT16                   :1;
      UINT16                   :1;
      UINT16                   :1;            
      UINT16 StuckKeyEn        :1;
      UINT16 DCTrackerEn       :1;
      UINT16 SWIEn             :1;
      UINT16 SystemEn          :1; 
      UINT16 ManRecalStarter   :1;    /* This struct is for bit-fields only */
      UINT16 SystemReset       :1;
      UINT16 HWRecalStarter    :1;
      UINT16                   :1;
      UINT16                   :1;
      UINT16                   :1;
      UINT16 LowPowerEn        :1;
      UINT16 ProximityEn       :1;
 } TSS_SYSTEM_SYSCONF;
#else
 typedef struct {                     /* Struct for System Setup */
      UINT16 ManRecalStarter   :1;    /* This struct is for bit-fields only */
      UINT16 SystemReset       :1;
      UINT16 HWRecalStarter    :1;
      UINT16                   :1;
      UINT16                   :1;
      UINT16                   :1;
      UINT16 LowPowerEn        :1;
      UINT16 ProximityEn       :1;
      UINT16 WaterToleranceEn  :1;      
      UINT16                   :1;
      UINT16                   :1;
      UINT16                   :1;            
      UINT16 StuckKeyEn        :1;
      UINT16 DCTrackerEn       :1;
      UINT16 SWIEn             :1;
      UINT16 SystemEn          :1; 
 } TSS_SYSTEM_SYSCONF;
#endif

  typedef struct {                  /* Struct for Triggering setup */
      UINT8 TriggerMode       :2;
      UINT8 SWTrigger         :1;
      UINT8 Reserved          :5;
  } TSS_SYSTEM_TRIGGER;  

  /******************************************************************/
  /****** Definition of control's context data for each decoder *****/
  /******************************************************************/

  typedef struct {                     /* Struct for Keypad Buffer */
      UINT16 u16TouchFlag; 
      UINT16 u16SignalChange;
  } TSS_KeydetectorBuffer;
  
  /* Structs for the context of a KeyPad Context*/
  
  typedef struct {                     
      UINT16 u16LastSignalChange; 
      const UINT16 *u16KeyGroup;
      INT8  i8KeyCount;
      UINT8 u8LastTouch;
      const UINT8 u8NumberOfKeys;
  } TSS_KeypadContext;
  
  /* Structs for the context of a ASlider Context*/ 
  
  typedef struct {
      UINT16 u16PrevPosition;
  } TSS_ASliderPosFilterContext;

  typedef struct {
      UINT8 u8BufferCounter;  
  } TSS_ASliderDelayContext;
  
  typedef struct {
      UINT8 u8BufferCounter;  
      INT8 i8PrevDelta1;
      INT8 i8PrevDelta2;
  } TSS_ASliderTrendContext;
  
  typedef struct {
      const TSS_ASliderPosFilterContext *psPosFilterContext;
      const TSS_ASliderDelayContext *psDelayContext;
      const TSS_ASliderTrendContext *psTrendContext;
      const UINT8 *pu8DelayBuffer;
      const INT8 *pi8TrendBuffer;      
  } TSS_ASliderContext;

  /* Structs for the context of a Matrix Context*/ 
  
  typedef struct {
      UINT8 u8MaxPosX;
      UINT8 u8MinPosX;      
      UINT8 u8MaxPosY;
      UINT8 u8MinPosY;      
  } TSS_MatrixTouchContext;

  typedef struct {
      UINT16 u16PrevPositionX;
      UINT16 u16PrevPositionY;
  } TSS_MatrixPosIIRFilterContext;
  
  typedef struct {
      const UINT8 cu8ElectrodesX;
      const UINT8 cu8ElectrodesY;      
      const TSS_MatrixTouchContext *cpsTouchData;
      const TSS_MatrixPosIIRFilterContext *psPosIIRFilterContext;
  } TSS_MatrixContext;  
  
  /* Struct for a single dummy variable */
  
  typedef struct {
      UINT8 u8SingleVal;
  } TSS_SingleContext;

  /******************************************************************/
  /*************** Sensitivity Auto Calibration Data ****************/
  /******************************************************************/
  
  typedef struct {
    UINT8 u8FallNoiseAmplitudeCounter;
    INT8 i8FallDestinationDelta;
    UINT8 u8FallDestinationDeltaCounter;      
  } TSS_AutoSensCalibrationData;  
  
  typedef struct {
    INT8 i8AverageNoiseAmplitude;
    UINT8 u8NoiseAnalysisCounter;
  } TSS_DeltaNoiseAnalysisBufferData;  

  typedef struct {
    INT8 i8InstantNoiseAmplitude;
    INT16 i16PrevIIRDeltaValue1;
    INT16 i16PrevIIRDeltaValue2;
  } TSS_DeltaNoiseAnalysisIIRData;
  
  typedef struct {
    const INT8 ci8NoiseLevelMinimum;
    const UINT8 cu8NoiseLevelFallTimeout;              /* Max 255 */
    const UINT8 cu8MaxDeltaFallUpdateRate;             /* Max 255 */
    const INT8 ci8MaxDeltaFallDivider;
    const INT8 ci8ThresholdToNoiseRatio;               /* Thrshld Level / Noise */
    const UINT8 cu8ThresholdToDeltaRatio;              /* Delta / Threshold Level */
  } TSS_AutoSensCalibContext;
  
  /********************************************************************/

#endif /* TSS_DATATYPES_H */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ip_prv.h<|end_filename|>
#ifndef __ip_prv_h__
#define __ip_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip_prv.h$
* $Version : 3.8.12.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   Internal definitions for the Internet Protocol layer.
*
*END************************************************************************/

 
    #include "ip6_prv.h"
    #include "ip6_if.h"     


/***************************************
**
** Constants
**
*/

/*
** Fragment field bits
*/
#define IP_FRAG_DF               0x4000   /* If true, do not fragment datagram */
#define IP_FRAG_MF               0x2000   /* If true, this is not last fragment */
#define IP_FRAG_MASK             0x1FFF   /* for offset (/8) of frag in dgram */

#define IP_FRAG_SHIFT            3
#define IP_FRAG_MIN              (1<<IP_FRAG_SHIFT)

/*
** IP option kinds                        length (dec) incl. opt+len bytes
*/
#define IPOPT_COPIED_MASK        0x80     /* set if should be copied on fragm. */
#define IPOPT_CLASS_MASK         0x60
#define IPOPT_CLASS_CONTROL      0x00
#define IPOPT_CLASS_DEBUG_MEASUR 0x40
#define IPOPT_SECURITY           0x02     /*  11                        */
#define IPOPT_LOOSE_ROUTE        0x03     /* var                        */
#define IPOPT_TIMESTAMP          0x44     /* var                        */
#define IPOPT_RECORD_ROUTE       0x07     /* var                        */
#define IPOPT_STREAM_ID          0x08     /*   4 (must not be used )    */
#define IPOPT_STRICT_ROUTE       0x09     /* var                        */

/* Time to live of a datagram awaiting reassembly (no relation to the IP TTL) */
#define IPREASM_TTL              60000       /* 60 secs */


/*
** Options for IP_route
*/

/*
** When we send a packet, first we check all directly connected networks
** for the destination.  If the destination is not directly connected, we
** scan the gateway table for a match.  If we find a match, we once again
** scan all directly connected networks, this time for the gateway.
**
** However, if the gateway fails this test, we do NOT recursively scan the
** gateway table for another gateway to reach the gateway.  IP_route()
** internally uses IPROUTEOPT_GATE to control the level of recursion.
*/
#define IPROUTEOPT_GATE       0x40

/*
** IPROUTEOPT_NOVIRTUAL instructs IP_route() to skip the virtual route
** check when routing a packet.  It's used by IPIP_send() to avoid
** tunneling loops.
*/
#define IPROUTEOPT_NOVIRTUAL  0x80

/*
** When we forward a packet, sometimes we want to make sure it doesn't
** go out the interface it was received on.  This occurs with PPP --
** we never forward a PPP packet back to the peer, because the peer has
** already seen the packet.  (If we did, directed broadcasts on a PPP
** link would bounce between the peers until the TTL expired.)
**
** IP_service() sets IPROUTEOPT_RECVIF in the call to IP_route() when
** it wants to indicate that the received PCB has already been seen
** by all hosts on pcb->IFSRC.  As a result, if IP_route() decides that
** the packet should go out pcb->IFSRC, it will return RTCS_OK without
** sending it (because the next hop has already seen it).
*/
#define IPROUTEOPT_RECVIF     RTCS_MSG_NOLOOP


/***************************************
**
** Code macros
**
*/

/*
** For IP_send[_IF]
*/
#define IPPROTO_GET(i)  ( (i)        & 0xFF)
#define IPTTL_GET(i)    (((i) >>  8) & 0xFF)
#define IPTOS_GET(i)    (((i) >> 16) & 0xFF)
#define IPDFRAG_GET(i)  (((i) >> 24) & 0x01)

#if RTCSCFG_ENABLE_IP_STATS
#define IF_IP_STATS_ENABLED(x) x
#else
#define IF_IP_STATS_ENABLED(x)
#endif


/***************************************
**
** Type definitions
**
*/

/*
** IP packet header
*/
typedef struct IP_HEADER {

   uchar    VERSLEN[1];    /* hi-nybble=Version, lo-nybble=header len/4 */
   uchar    TOS[1];        /* Type of service (see TOS_... #define's) */
   uchar    LENGTH[2];     /* Length of packet (header+data) in bytes */

   uchar    ID[2];         /* Packet identification */
   uchar    FRAGMENT[2];   /* Fragment offset & flags */

   uchar    TTL[1];        /* Time to live, in secs or hops */
   uchar    PROTOCOL[1];   /* Protocol */
   uchar    CHECKSUM[2];   /* IP_checksum */

   uchar    SOURCE[4];     /* sender of packet */
   uchar    DEST[4];       /* destination of packet */

} IP_HEADER, _PTR_ IP_HEADER_PTR;

/*
** IP v6 packet header
*/
typedef struct ip_v6_header {

   uchar    VERSPRIO[1];    /* hi-nybble=Version, lo-nybble=priority */
   uchar    FLOW_LABEL[3];        /* Flow Label  */
   uchar    LENGTH[2];      /* Length of the rest of the packet following the
                              IPv6 header, in octets */
   uchar    NEXT_HEADER[1]; /* Identifies the protocol immediately following
                               the IPv6 header */
   uchar    HOP_LIMIT[1];   /* Number of hops allowed for the packet */
   uchar    SOURCE[16];     /* sender of packet */
   uchar    DEST[16];       /* destination of packet */

} IP_V6_HEADER, _PTR_ IP_V6_HEADER_PTR;

typedef struct ip_v6_min_option_header {
   uchar NEXT_HEADER[1]; /* Identifies the option header immediately following
                            this option. */
   uchar HDR_EXT_LEN[1]; /* Length of the option, excluding the first octet. */
} IP_V6_MIN_OPTION_HEADER, _PTR_ IP_V6_MIN_OPTION_HEADER_PTR;

#define BIGGEST_IP_HEADER  (15*4)
#define IPH_LEN(iph)       ((ntohc((iph)->VERSLEN) & 0xF) << 2)

#if RTCSCFG_ENABLE_IPIF_STATS
#define IF_IPIF_STATS_ENABLED(x) x
#else
#define IF_IPIF_STATS_ENABLED(x)
#endif


/*
** The IP interface
**
** This structure contains enough information to allow IP to
** send packets through a packet driver.
*/
typedef struct ip_if {
#if RTCSCFG_ENABLE_IPIF_STATS
   IPIF_STATS        STATS;
#endif
   pointer           HANDLE;
   RTCS_IF_STRUCT    DEVICE;
   uint_32           MTU;
   pointer           ARP;

   /* fields for BOOTP/DHCP */
   void (_CODE_PTR_  BOOTFN)(RTCSPCB_PTR);
   pointer           BOOT;

   /* fields for ARP/BOOTP/DHCP */
   uint_32           DEV_TYPE;
   uint_32           DEV_ADDRLEN;
   uchar             DEV_ADDR[16];


#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   /* fields for IGMP */
   struct mc_member _PTR_     IGMP_MEMBER;
   uint_32 (_CODE_PTR_  IGMP_UNBIND)(struct ip_if _PTR_, _ip_address);
#ifdef IGMP_V2
   boolean              IGMP_V1_ROUTER_FLAG;
   uint_32              IGMP_V1_ROUTER_TIMEOUT;
#endif
#endif

#if RTCSCFG_ENABLE_IPSEC
   /* fields for IPsec */
   uint_32           DEFAULT_IPSEC_POLICY;
#endif
#if RTCSCFG_ENABLE_OSPF
   /* fields for Virata OSPF */
   pointer           IFO_ID;
#endif
#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4
   /* fields for SNMP */
   uint_32           SNMP_IF_TYPE;
#endif

   /* Calculates MTU. Needs DATA pointer from IP_ROUTE_VIRTUAL struct */
   uint_32 (_CODE_PTR_  MTU_FN)(pointer);
   
   
#if RTCSCFG_ENABLE_IP6 //FSL AB TBD 
    IP6_IF_STRUCT  IP6_IF;     
#endif //FSL AB
   
   
} IP_IF, _PTR_ IP_IF_PTR;

/* the different types of interface. IP_IF.TYPE. (from ospf rfc2328.9) */
#define IP_IFT_POINT2POINT    0x01
#define IP_IFT_BROADCAST      0x02
#define IP_IFT_NBMA           0x03
#define IP_IFT_POINT2MULTI    0x04
#define IP_IFT_VIRTUALLINK    0x05

#if RTCSCFG_ENABLE_RIP && RTCSCFG_ENABLE_IP4 
#include "rip_prv.h" /* included here because it requires IP_IF_PTR */
#endif

/*
** The IP routing table entry
*/

typedef struct ip_route_direct {
   struct ip_route_direct _PTR_  NEXT;
   _ip_address                   ADDRESS;
   IP_IF_PTR                     NETIF;
#if RTCSCFG_ENABLE_RIP && RTCSCFG_ENABLE_IP4 
   RIP_INFO                      RIP;
#endif
   uint_32                       FLAGS;
   IP_IF_PTR                     DESTIF;
} IP_ROUTE_DIRECT, _PTR_ IP_ROUTE_DIRECT_PTR;

typedef struct ip_route_virtual {
   struct ip_route_virtual _PTR_ NEXT;       /* --\                          */
   _ip_address                   ADDRESS;    /* ---\  All of these fields    */
   IP_IF_PTR                     IS_DIRECT;  /* ----\ have the same location */
#if RTCSCFG_ENABLE_RIP && RTCSCFG_ENABLE_IP4 
   RIP_INFO                      RIP;        /* ----/ as in IP_ROUTE_DIRECT. */
#endif
   uint_32                       FLAGS;      /* ---/  This must not change   */
   IP_IF_PTR                     DESTIF;     /* --/                          */
   _ip_address                   SOURCE_NET;
   _ip_address                   SOURCE_MASK;
   pointer                       DATA;
} IP_ROUTE_VIRTUAL, _PTR_ IP_ROUTE_VIRTUAL_PTR;

typedef struct ip_route_indirect {
   struct ip_route_indirect _PTR_   NEXT;        /* Aligned with IP_ROUTE_DIRECT.NEXT    */
   _ip_address                      GATEWAY;     /* Aligned with IP_ROUTE_DIRECT.ADDRESS */
   pointer                          IS_DIRECT;   /* Aligned with IP_ROUTE_DIRECT.NETIF   */
#if RTCSCFG_ENABLE_RIP && RTCSCFG_ENABLE_IP4 
   RIP_INFO                         RIP;         /* Aligned with IP_ROUTE_DIRECT.RIP     */
#endif
   uint_32                          FLAGS;       /* Aligned with IP_ROUTE_DIRECT.FLAGS   */
   /* Start CR 1133 */
   uint_16                          METRIC;
   /* End CR */
} IP_ROUTE_INDIRECT, _PTR_ IP_ROUTE_INDIRECT_PTR;

/*
** This struct relies on the fact that all the different route types start
** start with a NEXT pointer
*/
typedef struct ip_route_prv {
   IPRADIX_NODE              NODE;
   IP_ROUTE_DIRECT_PTR       ROUTETYPE[3];
} IP_ROUTE_PRV, _PTR_ IP_ROUTE_PRV_PTR;

typedef struct ip_route {
   IPRADIX_NODE            NODE;
   IP_ROUTE_DIRECT_PTR     DIRECT;
   IP_ROUTE_INDIRECT_PTR   INDIRECT;
   IP_ROUTE_VIRTUAL_PTR    VIRTUAL;
} IP_ROUTE, _PTR_ IP_ROUTE_PTR;


/* IP_ROUTE_INDIRECT.FLAGS = RTF_* */
#define RTF_UP          0x0001      /* !UP => unreachable */
#define RTF_STATIC      0x0002      /* created by IPIF_(bind|gate) */
#define RTF_REDIRECT    0x0004      /* created for a ICMP redirect */

/*
** IP routing extensions
*/
typedef struct ip_route_fn {
   struct ip_route_fn _PTR_ NEXT;
   void (_CODE_PTR_ INIT_IF)(IP_ROUTE_DIRECT_PTR);
   void (_CODE_PTR_ INIT_RT)(IP_ROUTE_INDIRECT_PTR, uint_16);
   void (_CODE_PTR_ REM_RT)(IP_ROUTE_INDIRECT_PTR);
} IP_ROUTE_FN, _PTR_ IP_ROUTE_FN_PTR;

typedef uint_32 (_CODE_PTR_ IPSEC_FN_PTR)(pointer, pointer, RTCSPCB_PTR _PTR_, _ip_address, _ip_address);

/*
** IP Configuration.  This information is persistent for the IP layer.
*/
typedef struct ip_cfg_struct {
#if RTCSCFG_ENABLE_IP_STATS
   IP_STATS          STATS;
#endif

   ICB_STRUCT_PTR    ICB_HEAD;      /* Head of open ICBs */
   uint_16           NEXT_ID;       /* next packet identifier */
   uint_16           DEFAULT_TTL;   /* default TTL */
   _rtcs_part        ROUTE_PARTID;  /* the partition descriptor of IP_ROUTEs */
#if RTCSCFG_ENABLE_GATEWAYS
   _rtcs_part        GATE_PARTID;   /* the descriptor of IP_ROUTE_INDIRECTS */
#endif
   IP_ROUTE_FN_PTR   ROUTE_FN;      /* function hook for routing protocols */

#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   _rtcs_part        MCB_PARTID;    /* the partition descriptor of MCBs */
#endif

   _rtcs_part        RADIX_PARTID;
   IP_ROUTE          ROUTE_ROOT;

#if RTCSCFG_ENABLE_IPSEC
   IPSEC_FN_PTR      SEC_SERVICE_FN;
   IPSEC_FN_PTR      SEC_SEND_FN;
   pointer           SEC_FN_ARG;
#endif
#if RTCSCFG_ENABLE_VIRTUAL_ROUTES
   _rtcs_part        VIRTUAL_PARTID;   /* parition for virtual routes */
#endif

} IP_CFG_STRUCT, _PTR_ IP_CFG_STRUCT_PTR;


/***************************************
**
** Prototypes
**
*/

/*
** the IP router
*/

void IP_route_init
(
   IP_ROUTE_PTR   head        /* Pointer to the head of the IPRADIX tree */
);

uint_32 IP_route_add_direct
(
   _ip_address    address,    /* Address or network address of destif   */
   _ip_address    netmask,    /* Mask for the address parameter         */
   IP_IF_PTR      netif,      /* Interface for incomming packets        */
   IP_IF_PTR      destif      /* Interface for outgoing packets         */
);

void IP_route_remove_direct
(
   _ip_address    address,    /* IP address of route to remove    */
   _ip_address    netmask,    /* IP netmask of route to remove    */
   IP_IF_PTR      netif       /* pointer to the route interface   */
);

uint_32 IP_route_add_indirect
(
   _ip_address    address,    /* Gateway address */
   _ip_address    netmask,    /* Network mask    */
   _ip_address    network,    /* Network address */
   uint_32        flag,       /* [IN] RTF_* */
   uint_16        metric      /* [IN] the route metric [0,65535] */
);

void IP_route_remove_indirect
(
   _ip_address    gateway,    /* Gateway address   */
   _ip_address    netmask,    /* Network mask      */
   /* Start CR 1133 */
   _ip_address    network,    /* Network address   */
   uint_32        flag,       /* [IN] RTF_* */
   uint_16        metric      /* [IN] the route metric [0,65535] */
   /* End CR */
);

uint_32 IP_route_add_virtual
(
   _ip_address   address,        /* Destination address              */
   _ip_address   netmask,        /* Mask for the address parameter   */
   _ip_address   source,         /* Interface source address         */
   _ip_address   source_net,     /* Allowed source network           */
   _ip_address   source_mask,    /* Allowed source network mask      */
   IP_IF_PTR     destif,         /* Interface for outgoing packets   */
   pointer       data            /* Route information                */
);

void IP_route_remove_virtual
(
   _ip_address    address,       /* IP address of route to remove    */
   _ip_address    netmask,       /* IP netmask of route to remove    */
   _ip_address    source,        /* IP of interface                  */
   _ip_address    source_net,    /* Allowed source network           */
   _ip_address    source_mask,   /* Allowed source source netmak     */
   IP_IF_PTR      netif          /* pointer to the route interface   */
);

uint_32 IP_complete_send
(
   pointer           ifdest,
         /* [IN] the destination interface */
   RTCSPCB_PTR _PTR_ pcb,
         /* [IN] the packet to send */
   _ip_address       hopsrc,
         /* [IN] the destination interface */
   _ip_address       ipdest,
         /* [IN] the ultimate dest */
   uint_32           protocol
         /* [IN] the transport layer protocol */

);

uint_32 IP_complete_recv
(
   pointer           ifdest,
         /* [IN] the destination interface */
   RTCSPCB_PTR _PTR_ pcb,
         /* [IN] the packet to send */
   _ip_address       hopsrc,
         /* [IN] the destination interface */
   _ip_address       ipdest,
         /* [IN] the ultimate dest */
   uint_32           protocol
         /* [IN] the transport layer protocol */

);

boolean IP_is_local
(
   IP_IF_PTR      iflocal,
         /* [IN] the local interface */
   _ip_address    iplocal
         /* [IN] the IP address to test */
);

boolean IP_is_direct
   (
      IP_IF_PTR      iflocal,
            /* [IN] the local interface */
      _ip_address    iplocal
            /* [IN] the IP address to test */
   );

boolean IP_is_gate
(
   _ip_address    gateway,
         /* [IN] the gateway */
   _ip_address    ipremote
         /* [IN] the IP address to test */
);

boolean IP_get_netmask
(
   _rtcs_if_handle   ihandle,    /* [IN] Interface */
   _ip_address       address,    /* [IN] IP address */
   _ip_address _PTR_ mask_ptr    /* [OUT] netwask for the IP and interface */
) ;

_ip_address IP_get_ipif_addr
(
   IP_IF_PTR      ipif        /* [IN] the local interface */
);

IP_ROUTE_PTR IP_ipif_get_iproute
(
   IP_IF_PTR      ipif        /* [IN] the local interface */
);

uint_32 IP_MTU
(
   _ip_address    iplocal,
         /* [IN] the local IP address */
   _ip_address    ipremote
         /* [IN] the remote IP address to test */
);

IP_IF_PTR IP_find_if
(
   _ip_address    iplocal
         /* [IN] the IP address to test */
);

_ip_address IP_route_find
(
   _ip_address    ipdest,
         /* [IN] the ultimate destination */
   uint_32        flags
         /* [IN] optional flags */
);

uint_32 IP_route_local
(
   RTCSPCB_PTR    pcb,
         /* [IN] the packet to send */
   _ip_address    ipdest
         /* [IN] the ultimate destination */
);

uint_32 IP_route_multi
(
   RTCSPCB_PTR    pcb,
         /* [IN] the packet to send */
   uint_32        protocol,
            /* [IN] the transport layer protocol */
   _ip_address    ipsrc,
         /* [IN] the destination interface (0 = any) */
   _ip_address    ipdest,
         /* [IN] the ultimate destination */
   uint_32        flags
         /* [IN] optional flags */
);

uint_32 IP_route
(
   RTCSPCB_PTR    pcb,
         /* [IN] the packet to send */
   uint_32        protocol,
         /* [IN] the transport layer protocol */
   _ip_address    hopsrc,
         /* [IN] the destination interface (0 = any) */
   _ip_address    ipsrc,
         /* [IN] the ultimate source */
   _ip_address    ipdest,
         /* [IN] the ultimate destination */
   uint_32        flags
         /* [IN] optional flags */
);

uint_32 IP_send_dgram
(
   IP_IF_PTR      ifdest,     /* [IN] the outgoing interface */
   RTCSPCB_PTR    inpcb,      /* [IN] the packet to send */
   _ip_address    hopsrc,     /* [IN] the hop src */
   _ip_address    hopdest,    /* [IN] the hop dest */
   _ip_address    ipdest,     /* [IN] the ultimate dest */
   uint_32        protocol,   /* [IN] the transport layer protocol */
   pointer        data        /* [IN] routing entry data */
);

/*
** the interface manager
*/

extern IP_IF_PTR            IF_FREE;       /* linked list of free IP_IFs */

extern void IPIF_add         (IPIF_PARM_PTR);
extern void IPIF_bind        (IPIF_PARM_PTR);
extern void IPIF_bind_finish (IPIF_PARM_PTR);
extern void IPIF_bind_ppp    (IPIF_PARM_PTR);
extern void IPIF_gate_add    (IPIF_PARM_PTR);
/* Start CR 1016 */
extern void IPIF_gate_add_redirect(IPIF_PARM_PTR);
/* End CR 1016 */
extern void IPIF_remove      (IPIF_PARM_PTR);
extern void IPIF_unbind      (IPIF_PARM_PTR);
extern void IPIF_unbind_ppp  (IPIF_PARM_PTR);
extern void IPIF_gate_remove (IPIF_PARM_PTR);


/* Local Host Interface.*/
extern IP_IF_PTR   RTCS_IF_LOCALHOST_PRV;

/*
** The local host interface
*/

uint_32 IPLOCAL_open
(
   IP_IF_PTR   if_ptr      /* [IN] the IP interface structure */
);

uint_32 IPLOCAL_close
(
   IP_IF_PTR   if_ptr      /* [IN] the IP interface structure */
);

uint_32 IPLOCAL_send
(
   IP_IF_PTR   if_ptr   ,  /* [IN] the IP interface structure */
   RTCSPCB_PTR pcb      ,  /* [IN] the packet to send */
   _ip_address src      ,  /* [IN] the next-hop source address */
   _ip_address dest     ,  /* [IN] the next-hop destination address */
   pointer     data        /* [IN] unused */
);

uint_32 IPLOCAL_service
(
   RTCSPCB_PTR pcb         /* [IN] the packet to deliver */
);

uint_32 IPLOCAL_init (void);

#if RTCSCFG_ENABLE_IP6
    void IP6LOCAL_open ( IP_IF_PTR if_ptr );
    uint_32 IP6LOCAL_send(  IP_IF_PTR if_ptr     /* [IN] the IP interface structure */,
                            RTCSPCB_PTR rtcs_pcb /* [IN] the packet to send */,
                            in6_addr *src        /* [IN] the next-hop source address */,
                            in6_addr *dest       /* [IN] the next-hop destination address */);
#endif /* RTCSCFG_ENABLE_IP6 */

/*
** the reassembler
*/

/*
** Datagrams awaiting reassembly are stored in sets of 256-byte
** blocks.  We allocate a partition of memory blocks; each block
** can be used in one of three ways:
**
**    1) It can store up to 256 data bytes from the datagram.
**       This is an IPREASM_BLK, called a 'direct block'.
**       This block also has 32-bit bitfield indicating which
**       part(s) of the direct block contain(s) valid data.
**       Each bit represents 8 bytes, so (32 bits) * (8 bytes/bit)
**       = 256 bytes.
**
**    2) It can be used as an array of pointers to IPREASM_BLKs
**       This is an IPREASM_INDIDX, called an 'indirect block'.
**       The indirect block could hold up to 65 direct block
**       pointers (257 in 32-bit wide memory), but we only
**       store 64 (or 256) to simplify the math.  i.e.
**       IPREASM_IND_SIZE could be
**          sizeof(IPREASM_BLK)/sizeof(IPREASM_BLK_PTR),
**       but we only set it to
**          IPREASM_BLK_SIZE/sizeof(IPREASM_BLK_PTR),
**
**    3) It can hold state information about an IP datagram, an
**       IP_DGRAM structure.  In particular, it has the datagram
**       'key' (the IP source, dest, protocol and ID), and as
**       many pointers to indirect blocks as it needs to address
**       a maximum sized datagram (256 direct blocks), i.e. 4
**       (or 1).  However, the IP_DGRAM structure is quite a
**       bit smaller than an IPREASM_BLK, so difference is
**       filled with pointers to direct blocks -- as many as
**       will fit without exceeding the size of an IPREASM_BLK.
**       When allocating blocks for incoming IP datagram fragments,
**       the direct block pointers in the IP_DGRAM are used first,
**       followed by the indirect block pointers.
*/


/* The size of the IP reassembly partition */
#define IPREASM_PART_MAXSIZE     (40*1024)
#define IPREASM_PART_GROW        32          /* 8 KB */
#define IPREASM_PART_MAX         (IPREASM_PART_MAXSIZE / sizeof(IPREASM_BLK))


/* Size of a block in octets */
#define IPREASM_BLK_SIZE         256
#define IPREASM_BLK_NUM(offset)  ((offset) / IPREASM_BLK_SIZE)
#define IPREASM_BLK_OFS(offset)  ((offset) % IPREASM_BLK_SIZE)
#define IPREASM_NB_BLK           (0x10000 / IPREASM_BLK_SIZE)

/* Number of direct block pointers that will fit in an IP_DGRAM */
#define IPREASM_NB_DIRECT        ((sizeof(IPREASM_BLK)-offsetof(IP_DGRAM,DIRECT)) \
                                  / sizeof(IPREASM_BLK_PTR))
#define IPREASM_IS_DIRECT(block) ((block) < IPREASM_NB_DIRECT)

/* Number of direct block pointers in each indirect block */
#define IPREASM_IND_SIZE         (IPREASM_BLK_SIZE / sizeof(IPREASM_BLK_PTR))
#define IPREASM_IND_NUM(block)   (((block)-IPREASM_NB_DIRECT) / IPREASM_IND_SIZE)
#define IPREASM_IND_OFS(block)   (((block)-IPREASM_NB_DIRECT) % IPREASM_IND_SIZE)
#define IPREASM_NB_IND           (IPREASM_NB_BLK / IPREASM_IND_SIZE)

#define IPREASM_IP_OPTIONS_SIZE     (60) 

typedef struct ipreasm_blk {
   uint_32  BUSYINT; /* the bitfield, 1 bit set = 8 bytes copied */
                     /* the LSB is DATA[0-7] */
                     /* the MSB is DATA[249-256] */
   uchar    DATA[IPREASM_BLK_SIZE];
} IPREASM_BLK, _PTR_ IPREASM_BLK_PTR;

/* the structure of an indirect block */
typedef struct ipreasm_indidx {
   IPREASM_BLK_PTR   DIRECT[IPREASM_IND_SIZE];
} IPREASM_INDIDX, _PTR_ IPREASM_INDIDX_PTR;

typedef struct ip_dgram
{
    /* the "key" of the dgram.  rfc815.7 */
    union
    {
    #if RTCSCFG_ENABLE_IP4        
        struct
        {
            _ip_address IPSRC;
            _ip_address IPDST;
            uint_8      PROTO;
            uint_16     ID;
            /* the IP header of the complete datagram */
            IP_HEADER   IPH;
             /* leave rooms for the ip options. MUST follow the IPH field */
            uchar       IP_OPTIONS[60 - sizeof(IP_HEADER)];
            uchar       ICMP_DATA[8];
        }IP4;
    #endif
    #if RTCSCFG_ENABLE_IP6
        struct
        {
            in6_addr    IPSRC;
            in6_addr    IPDST;
            uint_8      PROTO;
            uint_32     ID;
            /* the IP header of the complete datagram */
            IP6_HEADER  IPH;
            uchar       IP_OPTIONS[60];
            uint_32     IPH_OPT_LENGTH;
        }IP6;
    #endif
    }header;
    uint_16     family;    /* AF_INET6/AF_INET */

    /* move-to-front list of IP_DGRAMs */
    struct ip_dgram _PTR_       NEXT;
    struct ip_dgram _PTR_ _PTR_ PREV;

    /* Information from the PCB with the first fragment */
    uint_32              TYPE;
    pointer              IFSRC;
    RTCS_LINKOPT_STRUCT  LINKOPT;

    uint_32    TOTLEN; /* the data of the complete ip datagram payload */
    uint_32    CURLEN; /* the current data size */
    uint_32    MAXLEN; /* the last fragment seen */

    TCPIP_EVENT TIMER; /* the timer to handle datagram expiry */

    IPREASM_INDIDX_PTR   INDIR[IPREASM_NB_IND];
    IPREASM_BLK_PTR      DIRECT[1];
} IP_DGRAM, _PTR_ IP_DGRAM_PTR;

extern IP_DGRAM_PTR  IPREASM_head;  /* list of all IP_DGRAMs */
extern _rtcs_part    IPREASM_part;  /* the partition id for the buffer */

IPREASM_BLK_PTR IPREASM_blk_get      (IP_DGRAM_PTR, uint_32);
uint_32         IPREASM_blk_write    (IP_DGRAM_PTR, IPREASM_BLK_PTR, uint_32, uchar_ptr, uint_32);
void            IPREASM_blk_read_all (IP_DGRAM_PTR, uchar_ptr, uint_32);
void            IPREASM_blk_del_all  (IP_DGRAM_PTR);
void            IPREASM_del_dgram   (IP_DGRAM_PTR);

uint_32 IP_reasm_init (void);
uint_32 IP_reasm      (RTCSPCB_PTR, RTCSPCB_PTR _PTR_);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/include/usb_audio.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_audio.h$
* $Version : 
* $Date    : 
*
* Comments:
*
* @brief The file contains USB stack AUDIO class layer api header function.
*
*****************************************************************************/

#ifndef _USB_AUDIO_H
#define _USB_AUDIO_H 1

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_class.h"

/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
#define AUDIO_MAX_QUEUE_ELEMS  (4)

/* Code of bmRequest Type */
#define SET_REQUEST_ITF                 (0x21)
#define SET_REQUEST_EP                  (0x22)
#define GET_REQUEST_EP                  (0xA2)
#define GET_REQUEST_ITF                 (0xA1) 
 
 /* class specific requests */
#define AUDIO_CONTROL_INPUT_TERMINAL      (0x02)
#define AUDIO_CONTROL_OUTPUT_TERMINAL     (0x03)
#define AUDIO_CONTROL_FEATURE_UNIT        (0x06)

/* Audio Class Specific Request Codes */
#define REQUEST_CODE_UNDEFINED		   (0x00)
#define SET_CUR						   (0x01)
#define SET_MIN						   (0x02)
#define SET_MAX						   (0x03)
#define SET_RES						   (0x04)
#define SET_MEM						   (0x05)

#define GET_CUR						   (0x81)
#define GET_MIN						   (0x82)
#define GET_MAX						   (0x83)
#define GET_RES						   (0x84)
#define GET_MEM						   (0x85)
#define GET_STAT					   (0xFF)


/* Terminal control selector codes */
#define TE_CONTROL_UNDEFINED		   (0x00)
#define COPY_PROTECT_CONTROL		   (0x01)

/* feature unit control selector codes */
#define FU_CONTROL_UNDEFINED		   (0x00)
/* Feature Unit Control Selector codes */
#define MUTE_CONTROL                     (0x01)
#define VOLUME_CONTROL                   (0x02)
#define BASS_CONTROL                     (0x03)
#define MID_CONTROL                      (0x04)
#define TREBLE_CONTROL                   (0x05)
#define GRAPHIC_EQUALIZER_CONTROL        (0x06)
#define AUTOMATIC_GAIN_CONTROL           (0x07)
#define DELAY_CONTROL                    (0x08)
#define BASS_BOOST_CONTROL               (0x09)
#define LOUDNESS_CONTROL                 (0x0A)

/* Endpoint control selector codes */
#define EP_CONTROL_DEFINED			   (0x00)
#define SAMPLING_FREQ_CONTROL		   (0x01)
#define PITCH_CONTROL		   		   (0x02)

#define MAX_AUDIO_DEVICE                 (0x01)

/* command */
/* GET CUR COMMAND */
#define GET_CUR_MUTE_CONTROL						(0x8101)
#define GET_CUR_VOLUME_CONTROL						(0x8102)
#define GET_CUR_BASS_CONTROL						(0x8103)
#define GET_CUR_MID_CONTROL							(0x8104)
#define GET_CUR_TREBLE_CONTROL						(0x8105)
#define GET_CUR_GRAPHIC_EQUALIZER_CONTROL			(0x8106)
#define GET_CUR_AUTOMATIC_GAIN_CONTROL				(0x8107)
#define GET_CUR_DELAY_CONTROL						(0x8108)
#define GET_CUR_BASS_BOOST_CONTROL					(0x8109)
#define GET_CUR_LOUDNESS_CONTROL					(0x810A)

/* GET MIN COMMAND */
#define GET_MIN_VOLUME_CONTROL						(0x8202)
#define GET_MIN_BASS_CONTROL						(0x8203)
#define GET_MIN_MID_CONTROL							(0x8204)
#define GET_MIN_TREBLE_CONTROL						(0x8205)
#define GET_MIN_GRAPHIC_EQUALIZER_CONTROL			(0x8206)
#define GET_MIN_DELAY_CONTROL						(0x8208)

/* GET MAX COMMAND */
#define GET_MAX_VOLUME_CONTROL						(0x8302)
#define GET_MAX_BASS_CONTROL						(0x8303)
#define GET_MAX_MID_CONTROL							(0x8304)
#define GET_MAX_TREBLE_CONTROL						(0x8305)
#define GET_MAX_GRAPHIC_EQUALIZER_CONTROL			(0x8306)
#define GET_MAX_DELAY_CONTROL						(0x8308)

/* GET RES COMMAND */
#define GET_RES_VOLUME_CONTROL						(0x8402)
#define GET_RES_BASS_CONTROL						(0x8403)
#define GET_RES_MID_CONTROL							(0x8404)
#define GET_RES_TREBLE_CONTROL						(0x8405)
#define GET_RES_GRAPHIC_EQUALIZER_CONTROL			(0x8406)
#define GET_RES_DELAY_CONTROL						(0x8408)

/* SET CUR COMMAND */
#define SET_CUR_MUTE_CONTROL						(0x0101)
#define SET_CUR_VOLUME_CONTROL						(0x0102)
#define SET_CUR_BASS_CONTROL						(0x0103)
#define SET_CUR_MID_CONTROL							(0x0104)
#define SET_CUR_TREBLE_CONTROL						(0x0105)
#define SET_CUR_GRAPHIC_EQUALIZER_CONTROL			(0x0106)
#define SET_CUR_AUTOMATIC_GAIN_CONTROL				(0x0107)
#define SET_CUR_DELAY_CONTROL						(0x0108)
#define SET_CUR_BASS_BOOST_CONTROL					(0x0109)
#define SET_CUR_LOUDNESS_CONTROL					(0x010A)

/* SET MIN COMMAND */
#define SET_MIN_VOLUME_CONTROL						(0x0202)
#define SET_MIN_BASS_CONTROL						(0x0203)
#define SET_MIN_MID_CONTROL							(0x0204)
#define SET_MIN_TREBLE_CONTROL						(0x0205)
#define SET_MIN_GRAPHIC_EQUALIZER_CONTROL			(0x0206)
#define SET_MIN_DELAY_CONTROL						(0x0208)

/* SET MAX COMMAND */
#define SET_MAX_VOLUME_CONTROL						(0x0302)
#define SET_MAX_BASS_CONTROL						(0x0303)
#define SET_MAX_MID_CONTROL							(0x0304)
#define SET_MAX_TREBLE_CONTROL						(0x0305)
#define SET_MAX_GRAPHIC_EQUALIZER_CONTROL			(0x0306)
#define SET_MAX_DELAY_CONTROL						(0x0308)

/* SET RES COMMAND */
#define SET_RES_VOLUME_CONTROL						(0x0402)
#define SET_RES_BASS_CONTROL						(0x0403)
#define SET_RES_MID_CONTROL							(0x0404)
#define SET_RES_TREBLE_CONTROL						(0x0405)
#define SET_RES_GRAPHIC_EQUALIZER_CONTROL			(0x0406)
#define SET_RES_DELAY_CONTROL						(0x0408)

#define GET_CUR_COPY_PROTECT_CONTROL				(0x810B)

#define GET_CUR_SAMPLING_FREQ_CONTROL				(0x810C)
#define GET_MIN_SAMPLING_FREQ_CONTROL				(0x820C)
#define GET_MAX_SAMPLING_FREQ_CONTROL				(0x830C)
#define GET_RES_SAMPLING_FREQ_CONTROL				(0x840C)

#define GET_CUR_PITCH_CONTROL						(0x810D)
#define GET_MIN_PITCH_CONTROL						(0x820D)
#define GET_MAX_PITCH_CONTROL						(0x830D)
#define GET_RES_PITCH_CONTROL						(0x840D)

#define SET_CUR_COPY_PROTECT_CONTROL				(0x010B)

#define SET_CUR_SAMPLING_FREQ_CONTROL				(0x010C)
#define SET_MIN_SAMPLING_FREQ_CONTROL				(0x020C)
#define SET_MAX_SAMPLING_FREQ_CONTROL				(0x030C)
#define SET_RES_SAMPLING_FREQ_CONTROL				(0x040C)

#define SET_CUR_PITCH_CONTROL						(0x010D)


/*****************************************************************************
 * Local Functions
 *****************************************************************************/

 /******************************************************************************
 * Types
 *****************************************************************************/
 typedef uint_32 AUDIO_HANDLE;
 
 typedef struct _USB_AUDIO_UT_STRUCT
{
  uint_8          unit_id;      /* endpoint number         */
  uint_8          type;        /* type of endpoint        */
}USB_UT_STRUCT, *USB_UT_STRUCT_PTR;

typedef const struct _USB_AUDIO_UNITS 
{
   /* Number of terminal or Ferture Unit End point */
   uint_8         count;
   /* Array of terminal or Feature Unit */
   USB_UT_STRUCT  *epp;
}USB_AUDIO_UNITS; 
 
 typedef struct _app_data_struct 
{
    uint_8_ptr      data_ptr;         /* pointer to buffer       */            
    uint_32 data_size;                /* buffer size of endpoint */
}APP_DATA_STRUCT;
 
 /* structure to hold a request in the endpoint queue */
typedef struct _usb_class_audio_queue 
{
    _usb_device_handle handle;
    uint_8 channel;       
	APP_DATA_STRUCT app_data;
}USB_CLASS_AUDIO_QUEUE, *PTR_USB_CLASS_AUDIO_QUEUE;
 
/* USB class audio endpoint data */
  
typedef struct _usb_class_audio_endpoint 
{
    uint_8 endpoint; /* endpoint num */                    
    uint_8 type;     /* type of endpoint (interrupt, bulk or isochronous) */   
    uint_8 bin_consumer;/* the num of queued elements */
    uint_8 bin_producer;/* the num of de-queued elements */
    uint_8 queue_num;	/* the num of queue */
    USB_CLASS_AUDIO_QUEUE queue[AUDIO_MAX_QUEUE_ELEMS]; /* queue data */  
}USB_CLASS_AUDIO_ENDPOINT;

/* contains the endpoint data for non control endpoints */
typedef struct _usb_class_audio_endpoint_data 
{    
    uint_8 count;  /* num of non control endpoints */  
    /* contains the endpoint info */
    /*Allocate Memory In App Layer*/    
    USB_CLASS_AUDIO_ENDPOINT *ep;       
}USB_CLASS_AUDIO_ENDPOINT_DATA, *PTR_USB_CLASS_AUDIO_ENDPOINT_DATA;
 
 /* Strucutre holding AUDIO class state information*/
 typedef struct audio_device_struct
 {
   AUDIO_HANDLE audio_handle;
   USB_CLASS_HANDLE class_handle;
   _usb_device_handle controller_handle;
   uint_8 current_interface;
   USB_ENDPOINTS *usb_ep_data;
   USB_AUDIO_UNITS *usb_ut_data;
   USB_CLASS_AUDIO_ENDPOINT *ep;
   USB_CLASS_CALLBACK_STRUCT     audio_class_callback;
   USB_REQ_CALLBACK_STRUCT       vendor_req_callback;
   USB_CLASS_SPECIFIC_HANDLER_CALLBACK_STRUCT mem_param_callback;
   USB_CLASS_CALLBACK_STRUCT     param_callback;
 }AUDIO_DEVICE_STRUCT, _PTR_ AUDIO_DEVICE_STRUCT_PTR;
 
 /* Structure used to configure Audio class by APP*/
 typedef struct audio_config_struct
 {
    uint_32 desc_endpoint_cnt;
    USB_ENDPOINTS *usb_ep_data;
    USB_AUDIO_UNITS *usb_ut_data;
    USB_CLASS_AUDIO_ENDPOINT *ep; 
    USB_CLASS_CALLBACK_STRUCT audio_class_callback;
    USB_REQ_CALLBACK_STRUCT       vendor_req_callback;
    USB_CLASS_SPECIFIC_HANDLER_CALLBACK_STRUCT mem_param_callback;
    USB_CLASS_CALLBACK_STRUCT param_callback;
    DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr; 
 }AUDIO_CONFIG_STRUCT,_PTR_ AUDIO_CONFIG_STRUCT_PTR;
/******************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Class_Audio_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param *handle: handle pointer to Identify the controller
 * @param hid_class_callback:   event callback      
 * @param vendor_req_callback:  vendor specific class request callback      
 * @param param_callback:       application params callback      
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the Audio Class layer and layers it is dependent on 
 *
 *****************************************************************************/
extern AUDIO_HANDLE USB_Class_Audio_Init(AUDIO_CONFIG_STRUCT_PTR audio_config_ptr /*[IN]*/);

/**************************************************************************//*!
 *
 * @name  USB_Class_Audio_Send_Data
 *
 * @brief This function is used to send data to the host
 *
 * @param handle          :   handle returned by USB_Class_Audio_Send_Data
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
extern uint_8 USB_Class_Audio_Send_Data
(
    AUDIO_HANDLE         handle,        /* [IN]*/
    uint_8             ep_num,        /* [IN]*/
    uint_8_ptr         buff_ptr,      /* [IN] buffer to send */      
    uint_32            size           /* [IN] length of the transfer */
);

/**************************************************************************//*!
 *
 * @name  USB_Class_Audio_Recv_Data
 *
 * @brief This function receives Data from Host.
 *
 * @param handle          :   handle returned by USB_Class_Audio_Recv_Data
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
extern uint_8 USB_Class_Audio_Recv_Data
(
    AUDIO_HANDLE          audio_handle,
    uint_8              ep_num,
    uint_8_ptr          buff_ptr,      /* [IN] buffer to recv */      
    uint_32             size           /* [IN] length of the transfer */
);

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/config/common/small_ram_config.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: small_ram_config.h$
* $Version : 3.8.17.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   MQX configuration set: for small-RAM devices
*
*END************************************************************************/

#ifndef __small_ram_config_h__
  #define __small_ram_config_h__

/* Disable heavy weight components */

  #ifndef MQX_USE_IPC
    #define MQX_USE_IPC                         0
  #endif

  #ifndef MQX_USE_LOGS
    #define MQX_USE_LOGS                        0
  #endif

  #ifndef MQX_USE_SEMAPHORES
    #define MQX_USE_SEMAPHORES                  1
  #endif

  #ifndef MQX_USE_SW_WATCHDOGS
    #define MQX_USE_SW_WATCHDOGS                0
  #endif

  #ifndef MQX_USE_TIMER
    #define MQX_USE_TIMER                       1
  #endif

/* Other configuration */

  #ifndef MQX_DEFAULT_TIME_SLICE_IN_TICKS
    #define MQX_DEFAULT_TIME_SLICE_IN_TICKS     1
  #endif

  #ifndef MQX_LWLOG_TIME_STAMP_IN_TICKS
    #define MQX_LWLOG_TIME_STAMP_IN_TICKS       1
  #endif

  #ifndef MQX_TIMER_USES_TICKS_ONLY
    #define MQX_TIMER_USES_TICKS_ONLY           1
  #endif

  #ifndef MQX_EXTRA_TASK_STACK_ENABLE
    #define MQX_EXTRA_TASK_STACK_ENABLE         0
  #endif

  #ifndef MQX_IS_MULTI_PROCESSOR
    #define MQX_IS_MULTI_PROCESSOR              0
  #endif

  #ifndef MQX_MUTEX_HAS_POLLING
    #define MQX_MUTEX_HAS_POLLING               0
  #endif

  #ifndef MQX_USE_INLINE_MACROS
    #define MQX_USE_INLINE_MACROS               0
  #endif

  #ifndef MQX_USE_LWMEM_ALLOCATOR
    #define MQX_USE_LWMEM_ALLOCATOR             1
  #endif

  #ifndef MQX_ROM_VECTORS
    #define MQX_ROM_VECTORS                     0
  #endif

  #ifndef MQX_USE_IDLE_TASK
    #define MQX_USE_IDLE_TASK                   1
  #endif

  #ifndef MQX_HAS_TIME_SLICE
    #define MQX_HAS_TIME_SLICE                  1
  #endif


  #ifndef MQX_KERNEL_LOGGING
    #define MQX_KERNEL_LOGGING                  0
  #endif

  #ifndef MQX_SPARSE_ISR_TABLE
    #define MQX_SPARSE_ISR_TABLE                0

    #ifndef MQX_SPARSE_ISR_SHIFT
      #define MQX_SPARSE_ISR_SHIFT              3
    #endif

  #endif /* MQX_SPARSE_ISR_TABLE */


  #ifndef MQX_TASK_DESTRUCTION
    #define MQX_TASK_DESTRUCTION                0
  #endif

  #ifndef MQX_EXIT_ENABLED
    #define MQX_EXIT_ENABLED                    0
  #endif

/*
** MFS settings
*/

  #ifndef MFSCFG_MINIMUM_FOOTPRINT
    #define MFSCFG_MINIMUM_FOOTPRINT            1
  #endif

/*
** RTCS settings
*/

  #ifndef RTCS_MINIMUM_FOOTPRINT
    #define RTCS_MINIMUM_FOOTPRINT              1
  #endif

  #ifndef RTCSCFG_ENABLE_LWDNS
    #define RTCSCFG_ENABLE_LWDNS                1
  #endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/tcp_rcv.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcp_rcv.c$
* $Version : 3.6.10.0$
* $Date    : Dec-1-2010$
*
* Comments:
*
*   Receive Buffer Space:
*   |----+------------|               (circular)
*   rcvbuf            rcvbuf
*   +rcvpos           +rcvpos
*   :              +rcvlen (w/wrap-around)
*   :                 :
*   :                 :
*   Receive Sequence Space:   :                 :
*   :                 :
*   rcvbufseq      rcvbufseq+rcvlen
*   :                 :
*   : rcvuna          :
*   :  :              :
*   :  :              :
*   |-- - -       - ------+--+-|----------|-+--------
*   rcvirs            1     :     2    :     3
*   rcvnxt   rcvwndedge
*   +----+ 1a       +-+ 3a
*   +-+ 1b
*   1 - old sequence numbers which have been acknowledged
*   1a - seq #s acked but not yet returned to client, because
*   there is no receive client (if there is one, as much data
*   as possible (up to rcvnxt) is put in its buffer);
*   1b - seq #s between rcvuna and rcvnxt have not been ACKed (this is
*   for delayed ACKs), but rcvuna catches up quickly with rcvnxt.
*   2 - sequence numbers allowed for new reception
*   3 - future sequence numbers which are not yet allowed
*   3a - seq #s at the right of the advertised window but within the
*   receive buffer are accepted anyway
*   Note: due to receiver SWS-avoidance algorithm (Silly Window Syndrome),
*   rcvwndedge doesn't strictly follow rcvbufseq+rcvlen but only
*   advances in reasonable increments (a full packet or half the
*   buffer space, whichever is smaller).
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "ticker.h"     /* for timer definitions */
#include "tcpip.h"      /* for error codes */
#include "tcp_prv.h"    /* for TCP internal definitions */
#include "socket.h"     /* for TCP internal definitions */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Must_send_ack
* Returned Values : None.
* Comments        :
*
*  Called when it is determined that an ACK (or anything) must be sent;
*   the ACK isn't necessarily sent immediately...
*
*END*-----------------------------------------------------------------*/

void  TCP_Must_send_ack
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP layer context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN     - TCP layer data */
   )
{ /* Body */
   /*
   ** Ack if two full packets received, or TCP_ACKDELAY ms have elapsed...
   **
   ** Note that we don't transmit immediately since we may be able to
   **    ACK with new data to be sent.
   **
   ** Note that the wrap possibility is taken
   ** care of because we're using uint_32's.
   **
   ** e.g. if tcb->rcvuna   = FFFFFA23
   **     and tcb->rcvnxt   = C00
   **     and tcb->rcv2full = 9FB
   **    then diff          = -11DD
   **    but should be 5DD + C00 = 11DD
   **    but -11DD becomes 11DD as uint_32.
   */
   RTCSLOG_FNE4(RTCSLOG_FN_TCP_Must_send_ack, tcb->rcvuna, tcb->status, tcb->state);
    
   tcb->keepalive = FALSE;

#if 0
   /*DEBUGTCP(*/printf("\nTCP_Must_send_ack: 0x%x ", tcb->status)/*)*/;
   /*DEBUGTCP(*/printf("rcvuna:0x%x acktq:0x%x n:0x%x p:0x%x *curlist:0x%x *donelist:0x%x ", tcb->rcvuna, tcp_cfg->acktq, tcb->sndacktq.t.next, 
                   tcb->sndacktq.t.prev, *tcb->sndacktq.t.curlist, *tcb->sndacktq.t.donelist)/*)*/;
#endif

   if ((uint_32)(tcb->rcvnxt - tcb->rcvuna) >= tcb->rcv2full/* || tcb->status & TCPS_RPUSH*/) {
#if 0
      TCP_Transmit(tcb, tcp_cfg, FALSE, TRUE);
      TCP_Timer_remove(&tcb->sndacktq.t);
#else
      (void)TCP_Timer_oneshot_max(&tcb->sndacktq.t,     /* the timer */
                                  1,                    /* smallest timeout value */
                                  tcp_cfg->qhead );     /* the timer queue head */
#endif
   } else {
        (void)TCP_Timer_oneshot_max(&tcb->sndacktq.t,   /* the timer */
                                    (tcb->state & LAST_ACK) ? 1 : tcb->delayackto,     /* the timeout value */
                                    tcp_cfg->qhead );   /* the timer queue head */
   }

   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Must_send_ack, tcb);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Advance_receive_user
* Returned Values : None.
* Comments        :
*
*  `size' received bytes have been given to the user; advance appropriate
*   receive pointers (rcvbufseq and rcvpos)
*
*END*-----------------------------------------------------------------*/

void TCP_Advance_receive_user
   (
      TCB_STRUCT_PTR tcb,  /* IN/OUT - TCP context */
      int_32         size  /* IN     - no. of bytes given to user */
   )
{ /* Body */

    tcb->rcvpos = (tcb->rcvpos + size) % tcb->rcvlen;
    DEBUGTCP(printf(" Update rcvbufseq by %d from %X to ", size, tcb->rcvbufseq));
    tcb->rcvbufseq += size;
    DEBUGTCP(printf(" %X ", tcb->rcvbufseq));

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Truncate_receive_chunks
* Returned Values : None.
* Comments        :
*
*  Removes `datalen' bytes from the beginning of the receive buffer's chunk
*   list.
*
*  TCP_Advance_receive_user(tcb,datalen) should also be called, unless the connection
*   is being closed and all chunks have been removed.
*
*END*-----------------------------------------------------------------*/

void TCP_Truncate_receive_chunks
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg, /* IN/OUT - TCP layer data */
      int_32               datalen  /* IN     - length of data to remove */
   )
{ /* Body */
   Rchunk _PTR_   chunk;

   /*
   ** Remove 'datalen' bytes from receive buffer (rcvchunks...)
   */
   chunk = tcb->rcvchunks;
   while ( chunk != NULL ) {

      /*
      ** Shift chunk by datalen bytes, towards beginning of rcvbuf
      */
      chunk->used -= datalen;
      if ( chunk->used < 0 ) {

         /*
         ** This chunk started somewhere within the data section removed
         **    from the ring buffer, so remove it if the entire chunk
         **    was within the data section removed, or truncate it if not.
         **
         ** Note the chunk was necessarily at the head of the chunk list.
         */
         chunk->size -= -chunk->used;
         if ( chunk->size <= 0 ) {

            /*  Remove chunk */
            tcb->rcvchunks = chunk->next;
            _mem_free(chunk);
            chunk = tcb->rcvchunks;

         } else {
            chunk->used = 0;
            chunk = chunk->next;

         } /* Endif */

      } else {
         chunk = chunk->next;

      } /* Endif */

   } /* Endwhile */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Advertise_receive_window
* Returned Values : None.
* Comments        :
*
*  This is called when the real receive window (bytes available in receive
*   buffer) may have changed; update the advertised receive window if
*   necessary, taking into account the SWS-avoidance algorithm
*   (RFC1122 4.2.3.3 page 97).
*
*END*-----------------------------------------------------------------*/

void TCP_Advertise_receive_window
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP layer context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   uint_32  newedge;
   uint_32  maxedge;
   uint_32  increment;
   
   RTCSLOG_FNE2(RTCSLOG_FN_TCP_Advertise_receive_window, tcb);

   if ( (tcb->status & TCPS_FINRECV) != 0 ) {  /* window should be zero; do nothing */
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Advertise_receive_window, tcb);
      return;
   } /* Endif */

   increment = (tcb->rcvlen >> 1);
   if ( increment > (uint_32)tcb->sndmax ) {
      increment = (uint_32)tcb->sndmax;
   } /* Endif */

   /*
   ** We are prepared to accept data in the range from
   **   rcvbufseq to rcvbufseq+rcvlen.
   */
   newedge = tcb->rcvbufseq + tcb->rcvlen;

   maxedge = tcb->rcvbufseq + tcb->rcvwndmax;

   if ( GT32(newedge,maxedge) ) {
      newedge = maxedge;
   } /* Endif */

   /*
   ** If two increments or more are possible, go directly to maximum edge,
   **   else advance only by one increment.
   **
   ** From RFC 793 3.7 (page 43):
   **
   **   One suggestion for avoiding small windows is for the receiver to
   **   defer updating a window until the additional allocation is at
   **   least X percent of the maximum allocation possible for the
   **   connection (where X might be 20 to 40).
   **
   ** Note that the wrap possibility is taken
   ** care of because we're using uint_32's.
   **
   ** e.g. if tcb->rcvbufseq           = FFFFFA23
   **     and tcb->rcvwndedge          = FFFFFC00
   **     and tcb->rcvlen              = D800
   **    then newedge                  = D223
   **    and  newedge-tcb->rcvwndedge  = -D623
   **    but should be 400 + D223      = D623
   **    but -D623 becomes D623 as uint_32.
   */
   if ( (uint_32)(newedge - tcb->rcvwndedge) >= (increment << 1) ) {
      tcb->rcvwndedge = newedge;
      TCP_Must_send_ack(tcb, tcp_cfg);

   } else if ( (uint_32)(newedge - tcb->rcvwndedge) >= increment ) {
      tcb->rcvwndedge += increment;
      TCP_Must_send_ack(tcb, tcp_cfg);

   } /* Endif */
   
   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Advertise_receive_window, tcb);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Start_receiving
* Returned Values : None.
* Comments        :
*
*  Called when we start receiving anything on a connection...
*
*  Changes TCB state to SYN_RECEIVED.
*
*END*-----------------------------------------------------------------*/

void TCP_Start_receiving
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP layer context */
      uint_32              irs,     /* IN     - initial receive sequence */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
    RTCSLOG_FNE2(RTCSLOG_FN_TCP_Start_receiving, tcb);

   /*  The IRS (Initial Receive Sequence) is given by the remote side
    *   of the connection.
    */
   tcb->rcvirs = irs;
   tcb->rcvnxt = irs + 1;
   tcb->rcvuna = irs + 1;
   tcb->rcvbufseq  = irs + 1;
   tcb->rcvwndedge = irs + 1;
   DEBUGTCP(printf("\nTCP_StrtRcv: Call to AdRcvwnd: rcvwndedge = %X, rcvnxt = %X ",
                     tcb->rcvwndedge, tcb->rcvnxt));
   TCP_Advertise_receive_window(tcb, tcp_cfg);
   tcb->sndwl1 = irs;
   tcb->state  = SYN_RECEIVED;
   
   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Start_receiving, tcb);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Reply_receive
* Returned Values : None.
* Comments        :
*
*  Remove 'datalen' bytes from the receive buffer, and returns them
*   to the  client, with error condition 'errnum'.
*
*  Assumes there is a Receive() request pending, and that 'datalen' bytes
*   are indeed available at the head of the receive buffer (i.e.,
*   tcb->rcvnxt - tcb->rcvbufseq >= datalen).
*
*END*-----------------------------------------------------------------*/

void TCP_Reply_receive
   (
      TCB_STRUCT_PTR          tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR      tcp_cfg, /* IN/OUT - TCP layer data */
      int_32                  errnum   /* IN     - error code to return */
   )
{ /* Body */
   register TCP_PARM_PTR   req;     /* the Receive request */
            uint_32        status = RTCS_OK;

   /*
   ** If we were using user buffer directly, copy any extraneous receive
   **   data from user buffer to ring buffer, and truncate chunk list if
   **   necessary:
   */
   if ( tcb->rcvbuf == tcb->rcvuserbuf ) {
      status = TCP_Use_ringbuffer(tcb, tcp_cfg);
   } /* Endif */

   req = tcb->rcvHead;

   if ( errnum == RTCS_OK && status != RTCS_OK ) {
      req->ERROR_CODE = status;
   } else {
      req->ERROR_CODE = errnum;
   } /* Endif */
   req->BUFF_LENG  = tcb->rcvusernxt;
   req->STATUS     = tcb->status;
   req->URGENT     = 0;

   tcb->rcvuserbuf = NULL; /* buffer is returned to user */
/* tcb->rcvuserlen = 0; */

   /*
   ** Is there urgent data?
   */
   if ( (tcb->status & TCPS_RURGENT) != 0 ) {

      /*
      ** (rcvbufseq - rcvusernxt) is seq # of 1st data byte returned to user
      */
      req->URGENT = tcb->rcvup - (tcb->rcvbufseq - tcb->rcvusernxt);

      if ( GT32(req->URGENT, tcb->rcvup )) {  /* shouldn't happen, but check anyway */
         RTCS_log_error( ERROR_TCP,
                              RTCSERR_TCP_URGENT_DATA_PROB,
                              (uint_32)tcb,
                              (uint_32)req,
                              req->URGENT );
         req->URGENT = 0;
      } /* Endif */

      if ( GE32(tcb->rcvbufseq, tcb->rcvup) ) {
         tcb->status &= ~TCPS_RURGENT;
      } /* Endif */

   } /* Endif */

   if ( (tcb->status & TCPS_RPUSH) != 0 &&
      GE32(tcb->rcvbufseq,tcb->rcvpush))
   {
      tcb->status &= ~TCPS_RPUSH;
   } /* Endif */

   /*
   ** Cancel receive timeout if one is active
   */
   (void)TCP_Timer_stop(&tcb->rcvtq.t, tcp_cfg->qhead);

   /* Unlink the current request */
   tcb->rcvHead = req->NEXT;
   if ( tcb->rcvHead == NULL ) {
      tcb->rcvTail = NULL;
   } /* Endif */
   req->NEXT = NULL;

   /*
   ** Return the request
   */
   RTCSCMD_complete(req, req->ERROR_CODE);

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Test_done_receive
* Returned Values : None.
* Comments        :
*
*  Test to see if a receive request has been completed, and if so,
*   complete it.
*
*  Returns TRUE if request was left on rcvHead queue.
*
*END*-----------------------------------------------------------------*/

boolean TCP_Test_done_receive
   (
      TCB_STRUCT_PTR          tcb,     /* IN/OUT - TCP context */
      uint_32                 status,  /* IN     - error code  */
      TCP_CFG_STRUCT_PTR      tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   boolean  ret_state = TRUE; /* Default return status to TRUE */

   if ( tcb->rcvHead != NULL ) {

      /*
      ** Reply if buffer full, or (if return on PSH option specified)
      **   a PSH was received and data is ready to return.
      */
      if ( tcb->rcvusernxt == tcb->rcvuserlen  ||    /* user buffer full */
         ((tcb->rcvevents & TCPO_PUSH) != 0  &&   /* must push data */
          tcb->rcvusernxt > 0                &&   /* at least one byte */
           GE32(tcb->rcvnxt, tcb->rcvpush )   &&   /* rcvd all pushed data */
          (tcb->status & TCPS_RPUSH) != 0))       /* received a push */
      {

         TCP_Reply_receive( tcb, tcp_cfg, status );
         ret_state = FALSE;

      } /* Endif */

   } else {
      ret_state = FALSE;

   } /* Endif */

   return ret_state;

} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Setup_receive
* Returned Values : boolean
* Comments        :
*
*  Process next receive request.  Sets up the TCB receive section
*  for the next request on the rcvHead queue.
*
*  Assumes that the receive request has been linked into rcvHead
*  at the start (i.e. rcvHead EQ this request).  The request may
*  be immediately returned.  If so, it is unlinked from the rcvHead
*  queue.
*
*  Returns FALSE if receive was unlinked (i.e. the request was returned).
*
*END*-----------------------------------------------------------------*/

boolean  TCP_Setup_receive
   (
      TCP_PARM_PTR         req,     /* IN/OUT - the Receive request */
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   int_32   n;                /* no. of received bytes available */
   boolean  ret_state = TRUE; /* Default return status to TRUE */
   int_32   result = RTCS_OK;

   n = tcb->rcvnxt - tcb->rcvbufseq;   /* Seq #'s acked but not yet
                                          given to upper layer */
   switch ( tcb->state ) {

      default:

         n--;     /* Don't count the FIN */

         if ( n == 0 ) {

            /*
            ** All data given to upper layer
            */

            req->ERROR_CODE = (tcb->state == CLOSED) ?
                                 RTCSERR_TCP_NOT_CONN : RTCSERR_TCP_CONN_CLOSING;
            req->BUFF_LENG = 0;

            /* Unlink the request */
            tcb->rcvHead = req->NEXT;
            if ( tcb->rcvHead == NULL ) {
               tcb->rcvTail = NULL;
            } /* Endif */

            RTCSCMD_complete(req, req->ERROR_CODE);

            ret_state = FALSE;
            break;

         } /* Endif */

         /*
         ** Can't wait, because we received a FIN:
         */
         req->OPTIONS |= TCPO_NOWAIT;

         /*FALLTHROUGH*/

      case LISTEN:
      case SYN_SENT:
      case SYN_RECEIVED:

         /*FALLTHROUGH*/

      case ESTABLISHED:
      case FINWAIT_1:
      case FINWAIT_2:

         tcb->rcvuserbuf = req->BUFFER_PTR;
         tcb->rcvuserlen = req->BUFF_LENG;
         tcb->rcvevents  = req->OPTIONS;
         DEBUGTCP(printf("\nTCP_SetpRcv: Got RECEIVE of size %d ", req->BUFF_LENG));

         /*
         ** Copy any available (contiguous) data to the client's buffer
         */
         if ( n != 0 ) {

            if ( n > tcb->rcvuserlen ) {
               n = tcb->rcvuserlen;
            } /* Endif */
            result = TCP_Copy_from_ring(  tcb->rcvuserbuf,   /* destination */
                                    n,                 /* size */
                                    tcb->rcvpos,       /* offset in ringbuf */
                                    tcb->rcvringbuf,
                                    tcb->rcvringlen);

            TCP_Truncate_receive_chunks(tcb, tcp_cfg, n);

            /*
            ** Move both rcvpos and rcvbufseq forward by the amount of data
            **    copied from the ring buffer to the user buffer.  Note
            **    we should also call AdvertiseRcvWnd...
            */
            DEBUGTCP(printf("\nTCP_SetpRcv: Calls AdvRcvU: "));
            TCP_Advance_receive_user(tcb, n);

         } /* Endif */
         tcb->rcvusernxt = n;

         /*
         ** If client is polling, return after updating receive window.
         **  also return if an error occurred.
         */
         if ( (result != RTCS_OK) ||
            (req->OPTIONS & TCPO_NOWAIT) != 0)
         {
            TCP_Reply_receive(tcb, tcp_cfg, result);
            ret_state = FALSE;
            if (result != RTCS_OK) {
               break;
            } /* Endif */
         } else {

            /*
            ** Otherwise we might return anyway
            **   (will go to next Receive if request completed)
            */
            ret_state = TCP_Test_done_receive(tcb, result, tcp_cfg);
         } /* Endif */

         if ( ret_state ) { /* we still have the receive request */

            /*
            ** If user buffer is bigger than the ring buffer,
            **  use the user buffer instead, so we can give out a bigger
            **  receive window to the peer TCP;
            **
            ** Note that we can't use the user's buffer if we are to
            **  return upon PSH or timeout, because on receipt of either
            **  we'll have to fall back on the ring buffer and possibly
            **  *reduce* our receive window, which is very
            **  improper (translate: unacceptable) TCP behaviour.
            **
            ** We should only switch if the user buffer is significantly
            **  bigger than the ring (by TCP_SWITCH_THRESHOLD), to avoid
            **  needless switching;
            **  the 'switch' feature is really to support things like
            **  downloading 1Meg images in one block, so that we can offer
            **  a full 64k window without having to allocate such buffers...
            */

            DEBUGTCP(printf("\nTCP_SetpRcv: tcb->options = %X ", tcb->options));
            DEBUGTCP(printf("\n           : req->TIMEOUT = %d ", req->TIMEOUT));
            DEBUGTCP(printf("\n           : tcb->rcvuserlen (%d) - n (%d) = %d, rcvringlen + THRESH = %d ",
                     tcb->rcvuserlen, n, tcb->rcvuserlen-n, tcb->rcvringlen+TCP_SWITCH_THRESHOLD));
            DEBUGTCP(printf("\n           : tcb->rcvevents = %X ", tcb->rcvevents));

            if ( (tcb->options & TCPO_NOSWITCH) == 0       &&
               req->TIMEOUT == 0                         &&
               (tcb->rcvuserlen - n) >
                  (tcb->rcvringlen + TCP_SWITCH_THRESHOLD) &&
               (tcb->rcvevents & TCPO_PUSH) == 0)
            {

               Rchunk _PTR_   chunk;

               /*
               ** Copy from ring to user buffer (out-of-order chunks).
               */
               if ( result == RTCS_OK ) {

                  for ( chunk = tcb->rcvchunks;
                      chunk != NULL;
                      chunk = chunk->next)
                  {
                     result =
                        TCP_Copy_from_ring(  tcb->rcvuserbuf + n + chunk->used, /* dest */
                                       chunk->size,                       /* size */
                                       tcb->rcvpos + chunk->used,         /* offset */
                                       tcb->rcvringbuf,
                                       tcb->rcvringlen);

                     if ( result != RTCS_OK ) {
                        break;
                     } /* Endif */
                  } /* Endfor */

               } /* Endif */

               /*
               ** Add leading chunk, which we know is not contiguous with
               **    any other chunks
               */

               if ( tcp_cfg->Rchunkfree != NULL ) {
                  chunk = tcp_cfg->Rchunkfree;
                  tcp_cfg->Rchunkfree = chunk->next;
               } else {
                  chunk = (Rchunk _PTR_)RTCS_mem_alloc_zero(sizeof(Rchunk));
               } /* Endif */

               if ( chunk == NULL ) {
                  IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_MISSED++);
                  RTCS_log_error( ERROR_TCP, RTCSERR_TCP_PR_OUT_OF_MEM, (uint_32)tcb, 0, 0 );
                  break;

               } else {
                  _mem_set_type(chunk, MEM_TYPE_Rchunk);

                  chunk->size = n;
                  chunk->used = 0;
                  chunk->next = tcb->rcvchunks;
                  tcb->rcvchunks = chunk;

                  /*
                  ** Now use user buffer instead of ring
                  */
                  DEBUGTCP(printf("\nTCP_SetpRcv: Switching to User Buffer "));
                  tcb->rcvpos = 0;
                  tcb->rcvbuf = tcb->rcvuserbuf;
                  tcb->rcvlen = tcb->rcvuserlen;

                  /*
                  ** Note that the data that was sitting at the start
                  ** of the ring-buffer (n bytes, to be precise) got
                  ** copied to the user-buffer; in doing so, the start
                  ** of the ring-buffer was incremented by n, since these
                  ** n bytes are now in the user-buffer (hence,
                  ** tcb->rcvbufseq was incremented by n in the call to
                  ** TCP_Advance_receive_user(tcb,n)).  Since the main receive
                  ** buffer is now being set to the user-buffer instead of
                  ** the ring-buffer, these n bytes return to the main
                  ** buffer, and so rcvbufseq must be set back by n.
                  ** The net effect in this particular call to
                  ** TCP_Setup_receive() is that tcb->rcvbufseq hasn't changed.
                  */
                  tcb->rcvbufseq -= n;


               } /* Endif */   /* chunk EQ NULL */

            } else {
               DEBUGTCP(printf("\nTCP_SetpRcv: Couldn't switch "));
            } /* Endif */

            /*
            ** Return the request if we had an error.
            */
            if ( result != RTCS_OK ) {

               TCP_Reply_receive(tcb, tcp_cfg, result);
               ret_state = FALSE;
               break;

            } else {

               /*
               ** Initiate a receive timeout if requested
               */
               if ( req->TIMEOUT != 0 ) {
                  result =
                     TCP_Timer_start( &tcb->rcvtq.t,    /* the timer */
                                 req->TIMEOUT,     /* the timeout value */
                                 0,                /* no reload */
                                 tcp_cfg->qhead ); /* the timer queue head */
                  if ( result != RTCS_OK ) {
                     RTCS_log_error( ERROR_TCP,
                                          RTCSERR_TCP_TIMER_FAILURE,
                                          (uint_32)result,
                                          (uint_32)tcb,
                                          12 );
                  } /* Endif */
               } /* Endif */

            } /* Endif */

         } /* Endif */   /* ret_state */

         /*
         ** Update receive window if rcvbufseq and/or rcvlen has changed
         */
         DEBUGTCP(printf("\nTCP_SetpRcv: Call to AdRcvwnd: rcvwndedge = %X, rcvnxt = %X, wind = %d, rbs = %X ",
            tcb->rcvwndedge, tcb->rcvnxt,
            tcb->rcvwndedge-tcb->rcvnxt, tcb->rcvbufseq));
         TCP_Advertise_receive_window(tcb, tcp_cfg);

         break;

   } /* End Switch */

   return ret_state;

} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_receive
* Returned Values : None.
* Comments        :
*
*  Process TcpReceive() requests, within TCP server.
*
*END*-----------------------------------------------------------------*/

void TCP_Process_receive
   (
      TCP_PARM_PTR      tcp_req      /* IN/OUT - upper layer Send request */
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;    /* TCP layer data */
   TCB_STRUCT_PTR       tcb;

   tcp_cfg = RTCS_getcfg(TCP);
   tcb = tcp_req->TCB_PTR;

   if ( tcb == NULL ) { 
      tcp_req->BUFF_LENG = 0; 
      RTCSCMD_complete(tcp_req, RTCSERR_TCP_CONN_RLSD);
      return; 
   } 
   
   if ( tcb->VALID != TCB_VALID_ID ) {
      tcp_req->BUFF_LENG  = 0;
      RTCSCMD_complete(tcp_req, RTCSERR_TCP_NOT_CONN);

   } else if ( tcb->state == CLOSED ) {
      tcp_req->BUFF_LENG  = 0;
      RTCSCMD_complete(tcp_req, RTCSERR_TCP_CONN_ABORTED);

   } else {

      /*
      ** Ensure the upper layer did not request both wait and
      **    no-wait.
      */
      if ( (tcp_req->OPTIONS & (TCPO_WAIT | TCPO_NOWAIT)) ==
         (TCPO_WAIT | TCPO_NOWAIT))
      {
         tcp_req->BUFF_LENG  = 0;
         RTCSCMD_complete(tcp_req, RTCSERR_TCPIP_INVALID_ARGUMENT);

      /*
      ** If there is already a receive active, just
      ** add this one to the end of the list.
      */
      } else if ( tcb->rcvHead != NULL ) {

         /*
         ** If no wait was specified, then this is a weird
         ** request, so just return the request.
         */
         if ( (tcp_req->OPTIONS & TCPO_NOWAIT) != 0 ) {
            tcp_req->BUFF_LENG  = 0;
            RTCSCMD_complete(tcp_req, RTCSERR_TCP_IN_PROGRESS);
         } else {
            tcp_req->NEXT      = NULL;
            tcb->rcvTail->NEXT = tcp_req;
            tcb->rcvTail       = tcp_req;
         } /* Endif */

      } else {
         /*
         ** Set up this receive
         */
         tcb->rcvHead = tcb->rcvTail = tcp_req;
         tcp_req->NEXT    = NULL;
         TCP_Setup_receive(tcp_req, tcb, tcp_cfg);

      } /* Endif */ /* request ok */

   } /* Endif */ /* tcb valid */

   return;

} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_data
* Returned Values : None.
* Comments        :
*
*  Process incoming text (data) segment.  At this point the current
*     buffer may be a user (Receive) buffer or the ring buffer.  In
*     any case it should be able to handle any data we receive because
*     we've advertised our receive window based on it.
*
*  Assumes that PcbData(pcb) and pcb->size are start and size of data,
*   respectively.
*
*  Returns after all data that could be received was buffered.
*
*END*-----------------------------------------------------------------*/

void TCP_Process_data
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg, /* IN/OUT - TCP layer data */
      TCP_HEADER _PTR_     seg,     /* IN     - TCP packet */
      RTCSPCB_PTR          pcb      /* IN     - the packet */
   )
{ /* Body */
   uint_32     dataseq,       /* seq # of first byte of good data */
               bufoffset;     /* offset in buffer to put good data */
   int_32      sizeallowed,   /* maximum size available in current buffer */
               size,          /* size left to copy */
               truncate,      /* no. of rexmtted bytes in data */
               n;             /* no. of bytes avail at head of buffer */
   uchar_ptr   data;          /* pointer to good data */
   uint_32     status     = RTCS_OK;
   uint_32     mid_status = RTCS_OK;
   uint_32     use_status = RTCS_OK;
   PCB_FRAGMENT _PTR_ pcb_frag_ptr;
   
   RTCSLOG_FNE2(RTCSLOG_FN_TCP_Process_data, tcb);
       
   /*
   ** Get seq # of 1st byte of data
   */
   dataseq = ntohl(seg->seq);
   if ( ntohs(seg->flags) & SYN ) {       /* first byte is the SYN */
      dataseq++;
   } /* Endif */

   /*
   ** Discard unused beginning of data (i.e. retransmitted data)
   */
   size = RTCSPCB_SIZE(pcb);
   truncate = tcb->rcvbufseq - dataseq;   /* bytes to remove at begin. */

   if ( truncate < 0 ) {                  /* dataseq GT rcvbufseq so all */
      truncate = 0;                       /*   data is new */
   } /* Endif */
   if ( truncate >= size ) {              /* no data to process, quit */
      if (size > 0) {
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_DATA_DUP++);
      } /* Endif */
      
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Process_data, tcb);

      return;
   } /* Endif */

   /*
   ** Keep track of maximum sized packets received, so we know when we get
   **   full-sized packets (because we send an ACK upon two full packets,
   **   or rather, after 1.75 packets to allow for unexpected variations...)
   */
   if ( size > tcb->rcvmax ) {
      tcb->rcvmax = size;
      tcb->rcv2full = size + (size >> 1) + (size >> 2);  /* 1.75 * size */
   } /* Endif */

   /*
   ** Step over retransmitted data
   */
   size     -= truncate;
   dataseq  += truncate;
   if (pcb->HEADER_FRAG_USED) {
      data   = RTCSPCB_DATA(pcb) + truncate;   /* pointer to new data */
   } else {
      pcb_frag_ptr = pcb->PCBPTR->FRAG;
      pcb_frag_ptr++;
      /* pointer to new data */
      data  = pcb_frag_ptr->FRAGMENT + truncate;
   } /* Endif */
   DEBUGTCP(printf("\nTCP_ProcDta: Got %d bytes of new data ", size));

   /*
   ** Discard unused end of data (i.e. stuff we can't buffer).
   **    Any discarded here means that the remote host has sent
   **    beyond the window that we advertised.
   */
   bufoffset = dataseq - tcb->rcvbufseq;     /* position within receive buf
                                                of 1st byte of new data */
   sizeallowed = tcb->rcvlen - bufoffset;

   if ( sizeallowed <= 0 ) {                  /* data too far ahead, quit */
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_DATA++);
      TCP_Must_send_ack(tcb, tcp_cfg);
      
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Process_data, tcb);

      return;
   } /* Endif */

   if ( size > sizeallowed ) {               /* we have to truncate some */
      size = sizeallowed;                    /*   of the data */
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_DISCARDED++);
      DEBUGTCP(printf("\nTCP_ProcDta: Truncated new data to %d bytes (sizeallowed) ", size));
   } /* Endif */

   if ( ntohs(seg->flags) & (PSH | FIN) ) {
      if ( (tcb->status & TCPS_RPUSH) == 0 ||
         GT32(dataseq + size, tcb->rcvpush))
      {
         tcb->rcvpush = dataseq + size;
         TCP_Event(tcb, TCPS_RPUSH);
      } /* Endif */
   } /* Endif */

   /*
   ** If we weren't already using the user buffer, can we put the data
   **    (or some of it) directly into the user buffer?  Note we
   **    enforce that user buffer only contains contiguous data
   **    in this case where we are normally using the ring buffer.
   */
   if ( bufoffset == 0          &&     /* data goes at start of current buffer */
      tcb->rcvuserbuf != NULL &&       /* we have a user buffer */
      tcb->rcvuserbuf != tcb->rcvbuf)  /* not already using user buffer */
   {

      /*
      ** Yes; how much can we put?
      */
      sizeallowed = tcb->rcvuserlen - tcb->rcvusernxt;
      if ( sizeallowed > size ) {      /* can move all data from packet */
         sizeallowed = size;
      } /* Endif */

      _mem_copy(data, tcb->rcvuserbuf+tcb->rcvusernxt, sizeallowed);

      /*
      ** Update the number of bytes in the user buffer.
      */
      tcb->rcvusernxt += sizeallowed;
      size            -= sizeallowed;
      data            += sizeallowed;

      /*
      ** Have given 'sizeallowed' bytes to the user, so the ring
      **    buffer pointers should be moved forward the equivalent
      **    amount (i.e. ring buffer bufseq should always be
      **    beyond the last byte given to the user).
      **
      ** Move both rcvpos and rcvbufseq forward by the amount of data
      **    copied from the ring buffer to the user buffer.
      */
      DEBUGTCP(printf("\nTCP_ProcDta: Calls AdvRcvU: "));
      TCP_Advance_receive_user(tcb, sizeallowed);

      /*
      ** Now fix the RcvChunk list to match the data 'removed'
      **    from the ring buffer.
      */
      TCP_Truncate_receive_chunks(tcb, tcp_cfg, sizeallowed);

      /*
      ** See if we can move some data from later in the stream
      **    (that we received too early) from the ring buffer
      **    to the user buffer.  We can move only enough to
      **    fill up the user buffer (i.e. rcvuserlen - rcvusernxt).
      **
      ** Note that we only have to check the first RcvChunk
      **    because if there are more than one they cannot be
      **    contiguous.
      */

      if ( size <= 0 ) {

         { /* Scope */

            Rchunk _PTR_   chunk;

            /*
            ** We were able to copy the entire packet to user buffer.
            **    Note that size should never be 'less than' here, it
            **    should always equal 0.
            */
            chunk = tcb->rcvchunks;
            if ( chunk != NULL ) {

               if ( chunk->used == 0 ) {   /* Can only move if contiguous */
                  n = chunk->size;

                  /*
                  ** Copy as much of the (contiguous) data to the user buffer
                  **    as possible.
                  */
                  if ( n > (tcb->rcvuserlen - tcb->rcvusernxt) ) {
                     n = tcb->rcvuserlen - tcb->rcvusernxt;
                  } /* Endif */

                  mid_status =
                     TCP_Copy_from_ring(  tcb->rcvuserbuf + tcb->rcvusernxt,
                                                      /* destination */
                                    n,                /* size */
                                    tcb->rcvpos,      /* offset in ringbuf */
                                    tcb->rcvringbuf,
                                    tcb->rcvringlen);

                  /*
                  ** Update the number of bytes in the user buffer.
                  */
                  tcb->rcvusernxt += n;

                  /*
                  ** Now fix the RcvChunk list to match the data removed.
                  */
                  TCP_Truncate_receive_chunks(tcb, tcp_cfg, n);

                  /*
                  ** Move both rcvpos and rcvbufseq (ring ptrs) forward by the
                  **    amount of data copied from the ring buffer to the user
                  **    buffer.
                  */
                  DEBUGTCP(printf("\nTCP_ProcDta: Calls AdvRcvU: "));
                  TCP_Advance_receive_user(tcb, n);

               } /* Endif */

            } /* Endif */

         } /* Endscope */

      } /* Endif */

   } /* Endif */

   /*
   ** If there any valid data left, we must copy it to the current
   **    buffer, which may be either the ring buffer or the user
   **    buffer.
   **
   ** Note that if the user buffer was used above, then the current
   **    buffer must be the ring buffer.  If the current buffer is
   **    the user buffer, then we're just using it as if it was
   **    the ring buffer.  The eventual call to TCP_Use_ringbuffer will
   **    reset everything properly (e.g. rcvbufseq).
   */
   if ( size != 0 ) { /* data still available */

      /*
      ** Note that we know that 'size' bytes are available in the
      ** ring (or user) buffer at this point because we truncated
      ** un-bufferable data at the start of the procedure.
      */
      status = TCP_Copy_to_Rbuffer( tcb,  /* TCP context */
                           bufoffset,     /* dest offset from rcvpos in rcv buf */
                           data,          /* source buffer */
                           size,          /* size to copy */
                           tcb->rcvbuf,   /* start of rcv buf */
                           tcb->rcvlen,   /* total len of rcv buf */
                           tcb->rcvpos,   /* current offset in rcv buf */
                           tcp_cfg );     /* TCP layer data */

   } /* Endif */

   /*
   ** Compute nb of bytes of good data available at head of receive buffer.
   **    i.e. 'n' will be the number of contiguous data bytes from the
   **    start of the current buffer.
   */
   n = 0;
   if ( tcb->rcvchunks != NULL && tcb->rcvchunks->used == 0 ) {
      n = tcb->rcvchunks->size;
   } /* Endif */

   /*
   ** Switch from user to ring buffer if there is now more space available
   **    in the ring buffer.
   */
   if ( tcb->rcvuserbuf == tcb->rcvbuf &&     /* using user buffer  */
      tcb->rcvuserlen - n < tcb->rcvringlen) /* ring has more room */
   {

      DEBUGTCP(printf("\nTCP_ProcDta: Switching to Ring Buffer "));
      use_status = TCP_Use_ringbuffer(tcb, tcp_cfg);

      /* Now either ring is empty or it has only non-contiguous data. */
      n = 0;

   } /* Endif */

   /*
   ** Advance rcvnxt and update receive window if necessary.
   */
   if ( GT32(tcb->rcvbufseq + n, tcb->rcvnxt) ) { /* rcvd new contiguous data */

      DEBUGTCP(printf("\nTCP_ProcDta: Update rcvnxt by n=%d from %X ",n,tcb->rcvnxt));
      tcb->rcvnxt = tcb->rcvbufseq + n;
      DEBUGTCP(printf("to %X ", tcb->rcvnxt));

      DEBUGTCP(printf("\nTCP_ProcDta: Call to AdRcvwnd: rcvwndedge = %X, rcvnxt = %X, wind = %d, rbs = %X ",
                     tcb->rcvwndedge, tcb->rcvnxt,
                     tcb->rcvwndedge - tcb->rcvnxt, tcb->rcvbufseq));
      TCP_Advertise_receive_window(tcb, tcp_cfg);
      TCP_Must_send_ack(tcb, tcp_cfg);

   }
   else if ( LT32(dataseq, tcb->rcvnxt) ) { /* first byte past rcvnxt */

      /*
      ** Just acknowledge data received.  If first byte was past rcvnxt,
      **    (i.e. received out of order) then the data is
      **    unacknowledgeable.
      */
      TCP_Must_send_ack(tcb, tcp_cfg);

   } /* Endif */

   /*
   ** Check if we can return a Receive request.
   */
   if ( tcb->rcvHead != NULL ) {

      boolean need_rcv = FALSE;

      if ( status != RTCS_OK ) {
         TCP_Reply_receive( tcb, tcp_cfg, status );
         need_rcv = TRUE;

      } else if ( mid_status != RTCS_OK ) {
         TCP_Reply_receive( tcb, tcp_cfg, mid_status );
         need_rcv = TRUE;

      } else if ( use_status != RTCS_OK ) {
         TCP_Reply_receive( tcb, tcp_cfg, use_status );
         need_rcv = TRUE;

      } else {

         /*
         ** Check to see if the user buffer is full.  Note that TCP_Test_done_receive
         **    will handle switching back to the ring buffer.
         */
         if ( ! TCP_Test_done_receive(tcb, status, tcp_cfg) ) { /* receive was returned */
            need_rcv = TRUE;
         } /* Endif */

      } /* Endif */

      if ( need_rcv ) {

         /*
         ** Setup the next Receive.  Note that TCP_Setup_receive will switch back
         **   to the user buffer if possible.
         */
         while ( tcb->rcvHead != NULL &&
               ! TCP_Setup_receive(tcb->rcvHead, tcb, tcp_cfg)
         ) {
         } /* Endwhile */

      } /* Endif */

   } /* Endif */

   /*
   ** Notify socket layer in case some task is blocked on select()
   ** waiting for this data.
   */
   
   if (GT32(tcb->rcvnxt, tcb->rcvbufseq)) {
      SOCK_select_signal(tcb->SOCKET, tcb->state);
   } /* Endif */
   
    RTCSLOG_FNX2(RTCSLOG_FN_TCP_Process_data, tcb);
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pccard/apccard.h<|end_filename|>
#ifndef _apccard_h_
#define _apccard_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: apccard.h$
* $Version : 3.8.8.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   The file contains the structure definitions
*   public to the PC Card drivers
*
*END************************************************************************/

#include "ioctl.h"

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/* Error codes */
#define APCCARD_OK                   0
#define APCCARD_INVALID_HANDLE       1
#define APCCARD_INVALID_SLOT         2
#define APCCARD_INVALID_VOLTAGE      3

/* Slot definitions */
#define APCCARD_SLOT_A         0x100
#define APCCARD_SLOT_B         0x101

/* Voltage levels */
#define APCCARD_VOLTAGE_HI_Z   0x1000
#define APCCARD_VOLTAGE_12V    0x1001
#define APCCARD_VOLTAGE_5V     0x1002
#define APCCARD_VOLTAGE_33V    0x1003
#define APCCARD_VOLTAGE_0V     0x1004

/* Address space specifiers */
#define APCCARD_ATTRIB_SPACE   0x200
#define APCCARD_COMMON_SPACE   0x201
#define APCCARD_IO_SPACE       0x202

/* IOCTL Commands */
#define APCCARD_IOCTL_IS_CARD_INSERTED          _IO(IO_TYPE_APCCARD,0x01)
#define APCCARD_IOCTL_SET_CRD_INSERT_CALLBACK   _IO(IO_TYPE_APCCARD,0x02)
#define APCCARD_IOCTL_SET_CRD_REMOVE_CALLBACK   _IO(IO_TYPE_APCCARD,0x03)
#define APCCARD_IOCTL_GET_ADDR_SPACE            _IO(IO_TYPE_APCCARD,0x06)
#define APCCARD_IOCTL_FREE_ADDR_SPACE           _IO(IO_TYPE_APCCARD,0x07)
#define APCCARD_IOCTL_SENSE_VOLTAGE             _IO(IO_TYPE_APCCARD,0x08)
#define APCCARD_IOCTL_VCC_ENABLE                _IO(IO_TYPE_APCCARD,0x09)
#define APCCARD_IOCTL_VPP_ENABLE                _IO(IO_TYPE_APCCARD,0x0A)
#define APCCARD_IOCTL_RESET                     _IO(IO_TYPE_APCCARD,0x0B)
#define APCCARD_IOCTL_VCC_DISABLE               _IO(IO_TYPE_APCCARD,0x0C)
#define APCCARD_IOCTL_VPP_DISABLE               _IO(IO_TYPE_APCCARD,0x0D)
#define APCCARD_IOCTL_IDENTIFY                  _IO(IO_TYPE_APCCARD,0x0E)
#define APCCARD_IOCTL_POWERUP_CARD              _IO(IO_TYPE_APCCARD,0x0F)
#define APCCARD_IOCTL_POWERDOWN_CARD            _IO(IO_TYPE_APCCARD,0x10)
#define APCCARD_IOCTL_WAIT_TILL_READY           _IO(IO_TYPE_APCCARD,0x11)
#define APCCARD_IOCTL_CARD_READY                _IO(IO_TYPE_APCCARD,0x12)
#define APCCARD_IOCTL_READ_TUPLE                _IO(IO_TYPE_APCCARD,0x13)

/* CIS offsets */
#define IO_APCCARD_TUPLE_CODE_CIS_OFFSET        0x00
#define IO_APCCARD_TUPLE_LINK_CIS_OFFSET        0x02
#define IO_APCCARD_TUPLE_DATA_CIS_OFFSET        0x04

/* Some tuple codes */
#define IO_APCCARD_TUPLE_CISTPL_NULL            0x00
#define IO_APCCARD_TUPLE_CISTPL_DEVICE          0x01
#define IO_APCCARD_TUPLE_CISTPL_FUNCID          0x21
#define IO_APCCARD_TUPLE_CISTPL_FUNCE           0x22
#define IO_APCCARD_TUPLE_CISTPL_CFTABLE_ENTRY   0x1B
#define IO_APCCARD_TUPLE_END_OF_CIS             0xFF

/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/

/* This structure is used in the ioctl command APCCARD_IOCTL_GET_ADDR_SPACE */
typedef struct apccard_addr_info_struct
{
   uint_32 OFFSET;      /* Offset from PCMCIA base               */
   uint_32 TYPE;        /* Address type: Attrib, common, io      */
   uint_32 BANK_SIZE;   /* bank size from 1 to 64 megabytes      */
   uint_32 PORT_SIZE;   /* Port size: 8 or 16                    */
   pointer ADDRESS;     /* Filled in by driver. Absolute address */
} APCCARD_ADDR_INFO_STRUCT, _PTR_ APCCARD_ADDR_INFO_STRUCT_PTR;


/*-----------------------------------------------------------------------
**                      FUNCTION PROTOTYPES
*/
#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_ftfe.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_ftfe.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions for internal flash read, write, erase 
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "flash_ftfe_prv.h"
#include "flash_ftfe.h"

static void ftfe_ram_function(volatile uint_8 *); 
static void ftfe_ram_function_end(void);
static uint_32 ftfe_flash_command_sequence(FTFE_FLASH_INTERNAL_STRUCT_PTR, uint_8_ptr, uint_8);
static char_ptr ftfe_init_ram_function(void);
static _mqx_int ftfe_deinit_ram_function(char_ptr);

/* Note: bank1-3 reading are made from another addresses than bank1 writing. Therefore we add next parameter as base for writing */
const FLASHX_BLOCK_INFO_STRUCT _flashx_kinetisN_block_map[] = {
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE / 4, (uint_32) BSP_INTERNAL_FLASH_BASE,              BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE / 4, (uint_32) BSP_INTERNAL_FLASH_BASE + 1 * BSP_INTERNAL_FLASH_SIZE / 4, BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE / 4, (uint_32) BSP_INTERNAL_FLASH_BASE + 2 * BSP_INTERNAL_FLASH_SIZE / 4, BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE / 4, (uint_32) BSP_INTERNAL_FLASH_BASE + 3 * BSP_INTERNAL_FLASH_SIZE / 4, BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { 0, 0, 0 }
};

const FLASHX_BLOCK_INFO_STRUCT _flashx_kinetisX_block_map[] = {
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE / 2, (uint_32) BSP_INTERNAL_FLASH_BASE,              BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE / 2, (uint_32) BSP_INTERNAL_FLASH_BASE + 1 * BSP_INTERNAL_FLASH_SIZE / 2, BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { 0, 0, 0 }
};

const FLASHX_DEVICE_IF_STRUCT _flashx_ftfe_if = {
    ftfe_flash_erase_sector,
    ftfe_flash_write_sector,
    NULL,
    NULL,
    ftfe_flash_init,
    ftfe_flash_deinit,
    NULL,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfe_flash_command_sequence
* Returned Value   : uint_32 an error code
* Comments         :
*    Run command in FTFE device.
*
*END*----------------------------------------------------------------------*/
static uint_32 ftfe_flash_command_sequence
(                                                
    /* [IN] Flash specific structure */
    FTFE_FLASH_INTERNAL_STRUCT_PTR     dev_spec_ptr,
   
    /* [IN] Command byte array */
    uint_8_ptr                         command_array,
      
    /* [IN] Number of values in the array */
    uint_8                             count
)
{
    uint_8  fstat;
    uint_32 result, temp;
    void (* RunInRAM)(volatile uint_8 *);
    FTFE_MemMapPtr ftfe_ptr;
    
    ftfe_ptr = (FTFE_MemMapPtr)dev_spec_ptr->ftfe_ptr;

    /* get pointer to RunInRAM function */
    RunInRAM = (void(*)(volatile uint_8 *))(dev_spec_ptr->flash_execute_code_ptr);
    
    /* set the default return as FTFE_OK */
    result = FTFE_OK;
    
    /* check CCIF bit of the flash status register */
    while (0 == (ftfe_ptr->FSTAT & FTFE_FSTAT_CCIF_MASK))
        { };
    
    /* clear RDCOLERR & ACCERR & FPVIOL error flags in flash status register */
    if (ftfe_ptr->FSTAT & FTFE_FSTAT_RDCOLERR_MASK) 
    {
        ftfe_ptr->FSTAT |= FTFE_FSTAT_RDCOLERR_MASK;
    }
    if (ftfe_ptr->FSTAT & FTFE_FSTAT_ACCERR_MASK) 
    {
        ftfe_ptr->FSTAT |= FTFE_FSTAT_ACCERR_MASK;
    }
    if (ftfe_ptr->FSTAT & FTFE_FSTAT_FPVIOL_MASK) 
    {
        ftfe_ptr->FSTAT |= FTFE_FSTAT_FPVIOL_MASK;
    }
    
    switch (count)
    {
        case 12: ftfe_ptr->FCCOBB = command_array[--count];
        case 11: ftfe_ptr->FCCOBA = command_array[--count];
        case 10: ftfe_ptr->FCCOB9 = command_array[--count];
        case 9: ftfe_ptr->FCCOB8 = command_array[--count];
        case 8: ftfe_ptr->FCCOB7 = command_array[--count];
        case 7: ftfe_ptr->FCCOB6 = command_array[--count];
        case 6: ftfe_ptr->FCCOB5 = command_array[--count];
        case 5: ftfe_ptr->FCCOB4 = command_array[--count];
        case 4: ftfe_ptr->FCCOB3 = command_array[--count];
        case 3: ftfe_ptr->FCCOB2 = command_array[--count];
        case 2: ftfe_ptr->FCCOB1 = command_array[--count];
        case 1: ftfe_ptr->FCCOB0 = command_array[--count];
        default: break;
    }
    
#if PSP_MQX_CPU_IS_COLDFIRE
    temp = _psp_get_sr();
    _psp_set_sr(temp | 0x0700);
#elif PSP_MQX_CPU_IS_KINETIS
    __disable_interrupt ();
#endif //PSP_MQX_CPU_IS_KINETIS

    /* run command and wait for it to finish (must execute from RAM) */ 
    RunInRAM(&ftfe_ptr->FSTAT);

#if PSP_MQX_CPU_IS_COLDFIRE
    _psp_set_sr(temp);
#elif PSP_MQX_CPU_IS_KINETIS
    __enable_interrupt ();    
#endif //PSP_MQX_CPU_IS_KINETIS
    
    /* get flash status register value */
    fstat = ftfe_ptr->FSTAT;

#if PSP_MQX_CPU_IS_KINETIS
    /* invalidate flash cache to expose flash changes */
    kinetis_flash_invalidate_cache(FLASHX_INVALIDATE_CACHE_ALL);
#endif
   
    /* checking access error */
    if (0 != (fstat & FTFE_FSTAT_ACCERR_MASK))
    {
        /* return an error code FTFE_ERR_ACCERR */
        result = FTFE_ERR_ACCERR;
    }
    /* checking protection error */
    else if (0 != (fstat & FTFE_FSTAT_FPVIOL_MASK))
    {
        /* return an error code FTFE_ERR_PVIOL */
        result = FTFE_ERR_PVIOL;
    }
    /* checking MGSTAT0 non-correctable error */
    else if (0 != (fstat & FTFE_FSTAT_MGSTAT0_MASK))
    {
        /* return an error code FTFE_ERR_MGSTAT0 */
        result = FTFE_ERR_MGSTAT0;
    }
    
    return result;
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : ftfe_flash_init
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Initialize flash specific information.
*
*END*----------------------------------------------------------------------*/
boolean ftfe_flash_init 
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    FTFE_FLASH_INTERNAL_STRUCT_PTR    dev_spec_ptr;
    FTFE_MemMapPtr                    ftfe_ptr;

    if (_bsp_ftfx_io_init(0)) {
        /* Cannot initialize FTF module */
        return FALSE;
    }

    /* allocate internal structure */
    dev_spec_ptr = _mem_alloc(sizeof(FTFE_FLASH_INTERNAL_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (dev_spec_ptr == NULL)
    {
        return FALSE;
    }
#endif
    dev_ptr->DEVICE_SPECIFIC_DATA = dev_spec_ptr;
        
    /* get the pointer to ftfe registers structure */
    ftfe_ptr = _bsp_get_ftfe_address();
    dev_spec_ptr->ftfe_ptr = (vchar_ptr)ftfe_ptr;
    
    /* save pointer to function in ram */
    dev_spec_ptr->flash_execute_code_ptr = ftfe_init_ram_function();

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (dev_spec_ptr->flash_execute_code_ptr == NULL)
    {
        return FALSE;
    }
#endif
        
    return TRUE;    
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : ftfe_flash_deinit
* Returned Value   : none
* Comments         :
*   Release flash specific information.  
*
*END*----------------------------------------------------------------------*/
void ftfe_flash_deinit 
( 
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    FTFE_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFE_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    
    /* de-allocate the ram function buffer */
    ftfe_deinit_ram_function(dev_spec_ptr->flash_execute_code_ptr);

    /* de-allocate the device specific structure */
    _mem_free(dev_spec_ptr);

    dev_ptr->DEVICE_SPECIFIC_DATA = NULL;
}   

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : ftfe_init_ram_function
* Returned Value   : pointer to allocated RAM function
* Comments         :
*   Allocate and copy flash RAM function.
*
*END*----------------------------------------------------------------------*/
char_ptr ftfe_init_ram_function
(
    void
)
{
    char_ptr ram_code_ptr;
    _mem_size ftfe_ram_function_start;

    /* remove thumb2 flag from the address and align to word size */
    ftfe_ram_function_start = (_mem_size)ftfe_ram_function & ~3;

    /* allocate space to run flash command out of RAM */
    ram_code_ptr = _mem_alloc_align((char_ptr)ftfe_ram_function_end - (char_ptr)ftfe_ram_function_start, 4);

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (ram_code_ptr == NULL)
    {
        return NULL;
    }
#endif

    /* copy code to RAM buffer */
    _mem_copy ((char_ptr)ftfe_ram_function_start, ram_code_ptr, (char_ptr)ftfe_ram_function_end - (char_ptr)ftfe_ram_function_start);
    
    /* adjust address with respect to the original alignment */
    ram_code_ptr = (char_ptr)((_mem_size)ram_code_ptr | ((_mem_size)ftfe_ram_function & 3));

    return ram_code_ptr;
}
    
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfe_deinit_ram_function
* Returned Value   : MQX_OK or an error code 
* Comments         :
*   Free up flash RAM function, if any.
*
*END*-----------------------------------------------------------------------*/
_mqx_int ftfe_deinit_ram_function
(
    char_ptr ram_code_ptr
)
{
    if (NULL != ram_code_ptr)
    {
        return _mem_free((pointer)((_mem_size)ram_code_ptr & ~3));
    }

    return MQX_OK;
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : ftfe_flash_erase_sector
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Erase a flash memory block.
*
*END*----------------------------------------------------------------------*/
boolean ftfe_flash_erase_sector
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr,

    /* [IN] Erased sector address */
    char_ptr             from_ptr,

    /* [IN] Erased sector size */
    _mem_size            size
)
{
    FTFE_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFE_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    FTFE_MemMapPtr                    ftfe_ptr;
    _mqx_uint                         i;
    _mem_size                         write_addr;
    uint_8                            command_array[4];

    /* get the pointer to ftfe registers structure */
    ftfe_ptr = (FTFE_MemMapPtr)dev_spec_ptr->ftfe_ptr;

    for (i = 0; dev_ptr->HW_BLOCK[i].NUM_SECTORS != 0; i++)
    {
        if (((uint_32)from_ptr >= dev_ptr->HW_BLOCK[i].START_ADDR) &&
            ((uint_32)from_ptr <= dev_ptr->HW_BLOCK[i].START_ADDR + dev_ptr->HW_BLOCK[i].SECTOR_SIZE * dev_ptr->HW_BLOCK[i].NUM_SECTORS)) {
             /* check if the from_ptr is sector aligned or not */
             if ((uint_32)from_ptr % dev_ptr->HW_BLOCK[i].SECTOR_SIZE)
                return FALSE;
             /* check if the size is sector aligned or not */
             if ((uint_32)size % dev_ptr->HW_BLOCK[i].SECTOR_SIZE)
                return FALSE;
             break;
        }
    }
 
    write_addr = (_mem_size) from_ptr;

    /* preparing passing parameter to erase a flash block */
    command_array[0] = FTFE_ERASE_SECTOR;
    command_array[1] = (uint_8)(write_addr >> 16);
    command_array[2] = (uint_8)((write_addr >> 8) & 0xFF);
    command_array[3] = (uint_8)(write_addr & 0xFF);

    /* call flash command sequence function to execute the command */
    if (FTFE_OK != ftfe_flash_command_sequence (dev_spec_ptr, command_array, 4))
    {
        return FALSE;
    }

    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : ftfe_flash_write_sector
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Performs a write into flash memory.
*
*END*----------------------------------------------------------------------*/
boolean ftfe_flash_write_sector
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr,

    /* [IN] Source address */
    char_ptr             from_ptr,

    /* [IN] Destination address */
    char_ptr             to_ptr,

    /* [IN] Number of bytes to write */
    _mem_size            size
) 
{
    FTFE_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFE_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    FTFE_MemMapPtr                    ftfe_ptr;
    _mqx_uint                         i;
    _mem_size                         write_addr = 0;
    uint_8                            command_array[4 + FTFE_PHRASE_SIZE];
    char                              temp_data[FTFE_PHRASE_SIZE];
    uchar                             byte_data_counter = 0;
    uint_32                           offset = ((uint_32)to_ptr) & 0x00000007;

    dev_spec_ptr = dev_ptr->DEVICE_SPECIFIC_DATA;

    /* get the pointer to ftfe registers structure */
    ftfe_ptr = (FTFE_MemMapPtr)dev_spec_ptr->ftfe_ptr;    

    /* write to address mod 8 correction */
    if (offset)
    {
        /* align pointer to writable address */
        to_ptr -= offset;
        
        /* jump over old data */
        byte_data_counter = offset; 
    }

    write_addr = (_mem_size) to_ptr;

    /* heading space should be 0xFF */
    for (i = 0; i < offset; i++)
        temp_data[i] = 0xFF;

    while (size)
    {
        /* move data to temporary char array */       
        while ((byte_data_counter < FTFE_PHRASE_SIZE) && size)
        {
            temp_data[byte_data_counter++] = *from_ptr++;
            size--;
        }
        
        /* remaining space should be 0xFF */
        while (byte_data_counter < FTFE_PHRASE_SIZE) {
            temp_data[byte_data_counter++] = 0xFF;
        }

        /* prepare parameters to program the flash block */
        command_array[0] = FTFE_PROGRAM_PHRASE;
        command_array[1] = (uint_8)(write_addr >> 16);
        command_array[2] = (uint_8)((write_addr >> 8) & 0xFF);
        command_array[3] = (uint_8)(write_addr & 0xFF);
        
        command_array[4] = temp_data[3];
        command_array[5] = temp_data[2];
        command_array[6] = temp_data[1];
        command_array[7] = temp_data[0];

        command_array[8] = temp_data[7];
        command_array[9] = temp_data[6];
        command_array[10] = temp_data[5];
        command_array[11] = temp_data[4];
                
        /* call flash command sequence function to execute the command */
        if (FTFE_OK != ftfe_flash_command_sequence (dev_spec_ptr, command_array, 4 + FTFE_PHRASE_SIZE))
        {
            return FALSE;
        }
               
        /* update destination address for next iteration */
        write_addr += FTFE_PHRASE_SIZE;
        /* init variables for next loop */
        byte_data_counter = 0;
    }
    
    return TRUE;
}

/********************************************************************
*
*  Code required to run in SRAM to perform flash commands. 
*  All else can be run in flash.
*  Parameter is an address of flash status register.
*
********************************************************************/ 
static void ftfe_ram_function
( 
    /* [IN] Flash info structure */
    volatile uint_8 *ftfe_fstat_ptr
) 
{
    /* start flash write */
    *ftfe_fstat_ptr |= FTFE_FSTAT_CCIF_MASK;
    
    /* wait until execution complete */
    while (0 == ((*ftfe_fstat_ptr) & FTFE_FSTAT_CCIF_MASK))
        { };
}
         
static void ftfe_ram_function_end(void)
{}


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/khci/khci.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: khci.h$
* $Version : 3.8.13.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains KHCI-specific implementations of USB interfaces
*
*END************************************************************************/

#ifndef __khci_h__
#define __khci_h__

/* Basic scheduling packets algorithm, schedules next packet to the beginning of next frame
*/
//#define KHCICFG_BASIC_SCHEDULING

/* Scheduling based on internal "deadtime" register THSLD; you can choose additional value passed to the register
** Note that the register value depends on delay on line from host to device and is experimentally set to 0x65,
** which should be enough for the absolute majority of cases.
*/
#define KHCICFG_THSLD_DELAY 0x65

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/i2c_mcf52xx_prv.h<|end_filename|>
#ifndef _i2c_mcf52xx_prv_h
#define _i2c_mcf52xx_prv_h 
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_mcf52xx_prv.h$
* $Version : 3.8.8.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the I2C drivers for 52XX Coldfire family.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** MCF52XX_I2C_INFO_STRUCT
** Run time state information for each serial channel
*/
typedef struct mcf52xx_i2c_info_struct
{  
   /* Current initialized values */
   MCF52XX_I2C_INIT_STRUCT           INIT;
   
   VMCF52XX_I2C_STRUCT_PTR           I2C_PTR;
   
   /* The previous interrupt handler and data */
   void                  (_CODE_PTR_ OLD_ISR)(pointer);
   pointer                           OLD_ISR_DATA;

   /* Interrupt vector */
   uint_32                           VECTOR;
   
   /* Actual baudrate table index */
   uint_8                            BAUD_INDEX;

   /* Actual mode */
   uint_8                            MODE;

   /* Actual state */
   uint_8                            STATE;

   /* Destination address */
   uint_8                            ADDRESSEE;
   
   /* Operation flags */
   uint_8                            OPERATION;
   
   /* Number of bytes requested for receive */
   uint_32                           RX_REQUEST;

   /* Pointer to the buffer to use for Tx/Rx data */
   uchar_ptr                         RX_BUFFER;

   /* Rx write index */
   uint_32                           RX_IN;

   /* Rx read index */
   uint_32                           RX_OUT;

   /* Pointer to the buffer to use for current Tx data */
   uchar_ptr                         TX_BUFFER;

   /* Tx write index */
   uint_32                           TX_IN;

   /* Tx read index */
   uint_32                           TX_OUT;

   /* Statistical information */
   I2C_STATISTICS_STRUCT             STATISTICS;

} MCF52XX_I2C_INFO_STRUCT, _PTR_ MCF52XX_I2C_INFO_STRUCT_PTR; 

typedef volatile struct mcf52xx_i2c_info_struct * VMCF52XX_I2C_INFO_STRUCT_PTR; 

/*
** MCF52XX_I2C_BAUDRATE_STRUCT
*/
typedef struct mcf52xx_i2c_baudrate_struct
{  
   /* Baudrate */
   uint_32                           BAUD_RATE;
   
   /* Divider */
   uint_8                            IC;   
   
} MCF52XX_I2C_BAUDRATE_STRUCT, _PTR_ MCF52XX_I2C_BAUDRATE_STRUCT_PTR; 

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcs_in.h<|end_filename|>
#ifndef __rtcs_in_h__
#define __rtcs_in_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcs_in.h$
* $Version : 3.0.6.0$
* $Date    : Apr-24-2009$
*
* Comments:
*
*   Definitions for the Internet protocol layer.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

/*
** IP protocol types
*/
#define IPPROTO_HOPOPTS    0        /* IPv6 hop-by-hop options            */
#define IPPROTO_ICMP       1        /* Internet Control Message Protocol  */
#define IPPROTO_IGMP       2        /* Internet Group Management Protocol */
#define IPPROTO_IP         4        /* IP-in-IP encapsulation             */
#define IPPROTO_IPIP       4        /* IP-in-IP encapsulation             */
#define IPPROTO_TCP        6        /* Transmission Control Protocol      */
#define IPPROTO_UDP        17       /* User Datagram Protocol             */
#define IPPROTO_IPV6       41       /* IPv6-in-IP encapsulation           */
#define IPPROTO_ROUTING    43       /* IPv6 routing header                */
#define IPPROTO_FRAGMENT   44       /* IPv6 fragmentation header          */
#define IPPROTO_ESP        50       /* Encapsulating Security Payload     */
#define IPPROTO_AH         51       /* Authentication Header              */
#define IPPROTO_ICMPV6     58       /* ICMPv6                             */
#define IPPROTO_NONE       59       /* IPv6 no next header                */
#define IPPROTO_DSTOPTS    60       /* IPv6 destination options           */
#define IPPROTO_OSPF       89       /* Open Shortest Path Protocol        */
#define IPPROTO_COMP       108      /* IP compression                     */

/*
** Standard port assignments
*/
#define IPPORT_SPR_ITUNES  0
#define IPPORT_TCPMUX      1
#define IPPORT_COMPRESSNET 2
#define IPPORT_RJE         5
#define IPPORT_ECHO        7
#define IPPORT_DISCARD     9
#define IPPORT_SYSSTAT     11
#define IPPORT_DAYTIME     13
#define IPPORT_NETSTAT     15
#define IPPORT_QOTD        17
#define IPPORT_MSP         18
#define IPPORT_CHARGEN     19
#define IPPORT_FTPDATA     20
#define IPPORT_FTP         21
#define IPPORT_SSH         22
#define IPPORT_TELNET      23
#define IPPORT_SMTP        25
#define IPPORT_NEWS_FE     27
#define IPPORT_MSG_ICP     29
#define IPPORT_MSG_AUTH    31
#define IPPORT_DSP         33
#define IPPORT_TIME        37
#define IPPORT_RLP         39
#define IPPORT_GRAPHICS    41
#define IPPORT_NAME        42

#define IPPORT_BOOTPS      67
#define IPPORT_BOOTPC      68
#define IPPORT_TFTP        69
#define IPPORT_HTTP        80
#define IPPORT_NTP         123
#define IPPORT_SNMP        161
#define IPPORT_SNMPTRAP    162
#define IPPORT_ISAKMP      500
#define IPPORT_WHO         513
#define IPPORT_RIP         520
#define IPPORT_ESPUDP      4500

/*
** IANA ifTypes
*/
#define IPIFTYPE_OTHER           1
#define IPIFTYPE_ETHERNET        6
#define IPIFTYPE_PPP             23
#define IPIFTYPE_LOOPBACK        24
#define IPIFTYPE_RS232           33
#define IPIFTYPE_FASTETHERNET    62
#define IPIFTYPE_GIGABITETHERNET 117
#define IPIFTYPE_HDLC            118
#define IPIFTYPE_TUNNEL          131

/*
** IANA ARP hardware types
*/
#define ARPLINK_NONE       0
#define ARPLINK_ETHERNET   1
#define ARPLINK_SERIAL     20

/*
** Special IP addresses
*/
#define INADDR_ANY               0
#define INADDR_LOOPBACK          0x7F000001L
#define INADDR_ALLHOSTS_GROUP    0xE0000001L
#define INADDR_ALLROUTERS_GROUP  0xE0000002L
#define INADDR_RIP_GROUP         0xE0000009L
#define INADDR_NTP_GROUP         0xE0000101L
#define INADDR_BROADCAST         0xFFFFFFFFL


/***************************************
**
** Code macros
**
*/

/*
** Macros to classify IP addresses:
*/
#define IN_ZERONET(a)         (((a) & 0xFF000000L) == 0x00000000L)
#define IN_LOOPBACK(a)        (((a) & 0xFF000000L) == 0x7F000000L)
#define IN_MULTICAST(a)       (((a) & 0xF0000000L) == 0xE0000000L)
#define IN_LOCAL_MULTICAST(a) (((a) & 0xFFFFFF00L) == 0xE0000000L)
#define IN_EXPERIMENTAL(a)    (((a) & 0xF0000000L) == 0xF0000000L)

#define IN_CLASSA(a)          (((a) & 0x80000000L) == 0x00000000L)
#define IN_CLASSA_NET         0xFF000000L
#define IN_CLASSB(a)          (((a) & 0xC0000000L) == 0x80000000L)
#define IN_CLASSB_NET         0xFFFF0000L
#define IN_CLASSC(a)          (((a) & 0xE0000000L) == 0xC0000000L)
#define IN_CLASSC_NET         0xFFFFFF00L

#define IN_DEFAULT_NET(a)  ((a) == INADDR_ANY ? INADDR_ANY : \
                            (IN_CLASSA(a) ? IN_CLASSA_NET :  \
                            (IN_CLASSB(a) ? IN_CLASSB_NET :  \
                            (               IN_CLASSC_NET))))


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sai/int/sai_int.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sai_int.c$
* $Version : 3.8.3.0$
* $Date    : Aug-23-2012$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the SAI I/O functions.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>
#include <io.h>
#include "sai.h"
#include "sai_int_prv.h"

/*FUNCTION****************************************************************
*
* Function Name    : _io_sai_int_install
* Returned Value   : MQX error code
* Comments         :
*    Install the SAI device.
*
*END**********************************************************************/

_mqx_uint _io_sai_int_install
(
    /* [IN] The initialization structure for the device */
    SAI_INIT_STRUCT_CPTR init_ptr
)
{ /* Body */
    IO_SAI_DEVICE_STRUCT_PTR io_dev_ptr = NULL;    

    io_dev_ptr = (IO_SAI_DEVICE_STRUCT_PTR) _mem_alloc_system_zero(sizeof (IO_SAI_DEVICE_STRUCT));
    
    if (io_dev_ptr == NULL)
    {
        return MQX_OUT_OF_MEMORY;
    }

    io_dev_ptr->DEV_INIT            = init_ptr->INIT;
    io_dev_ptr->DEV_DEINIT          = init_ptr->DEINIT;
    io_dev_ptr->DEV_READ            = init_ptr->RX;
    io_dev_ptr->DEV_WRITE           = init_ptr->TX;
    io_dev_ptr->DEV_IOCTL           = init_ptr->IOCTL;
    io_dev_ptr->DEV_INIT_DATA_PTR   = init_ptr->INIT_DATA_PTR;
    
    _lwsem_create(&io_dev_ptr->LWSEM, 1);
    
    return (_io_dev_install_ext(
        init_ptr->ID_PTR,
        _io_sai_int_open,
        _io_sai_int_close,
        _io_sai_int_read,
        _io_sai_int_write,
        _io_sai_int_ioctl,
        _io_sai_int_uninstall,
        (pointer)io_dev_ptr));

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _io_sai_int_uninstall
* Returned Value   : MQX error code
* Comments         :
*    UnInstall interrupt SAI device.
*
*END**********************************************************************/

_mqx_int _io_sai_int_uninstall
(
    /* [IN] The IO device structure for the device */
    IO_DEVICE_STRUCT_PTR    io_dev_ptr
)
{ /* Body */
    IO_SAI_DEVICE_STRUCT_PTR io_sai_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

    if ((io_sai_dev_ptr->READ_COUNT == 0) && (io_sai_dev_ptr->WRITE_COUNT == 0))
    {
        if (io_sai_dev_ptr->DEV_DEINIT)
        {
            (*io_sai_dev_ptr->DEV_DEINIT)(io_sai_dev_ptr, io_sai_dev_ptr->DEV_INFO_PTR);
        }
        _lwsem_destroy(&io_sai_dev_ptr->LWSEM);
        _mem_free (io_sai_dev_ptr);
        io_dev_ptr->DRIVER_INIT_PTR = NULL;
        return IO_OK;
    } else {
        return IO_ERROR_DEVICE_BUSY;
    }
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _io_sai_int_open
* Returned Value   : MQX error code
* Comments         :
*    This routine initializes the SAI I/O channel. It acquires
*    memory, then stores information into it about the channel.
*    It then calls the hardware interface function to initialize the channel.
*
*END**********************************************************************/

_mqx_int _io_sai_int_open
(
    /* [IN] the file handle for the device being opened */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] the remaining portion of the name of the device */
    char_ptr        open_name_ptr,

    /* [IN] the flags to be used during operation */
    char_ptr        flags
)
{ /* Body */
    IO_DEVICE_STRUCT_PTR        io_dev_ptr;
    IO_SAI_DEVICE_STRUCT_PTR    io_sai_dev_ptr;
    _mqx_int result = MQX_OK;
    uint_32 i = 0;
    boolean read_open = FALSE;
    boolean write_open = FALSE;
    
    io_dev_ptr = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_sai_dev_ptr = (pointer)(io_dev_ptr->DRIVER_INIT_PTR);

 
    io_sai_dev_ptr->FLAGS = 0;
    
    if (flags == NULL)
    {
        flags = "rw";
    }
    while (flags[i] != '\0')
    {
        if (flags[i] == 'r') // open device for reading
        {
            read_open = TRUE;
        }
        if (flags[i++] == 'w') // open device for writing
        {
            write_open = TRUE;
        }
    }
    /* If we want to open device for reading */
    if (read_open)
    {
        _int_disable ();
        if (io_sai_dev_ptr->READ_COUNT)
        {
            /* Device is already opened for reading */
            _int_enable ();
            return MQX_IO_OPERATION_NOT_AVAILABLE;
        }
        _int_enable ();
        io_sai_dev_ptr->FLAGS |= I2S_IO_READ;
    }
    /* If we want to open device for writing */
    if (write_open)
    {
        _int_disable ();
        if (io_sai_dev_ptr->WRITE_COUNT)
        {
            /* Device is already opened for reading */
            _int_enable ();
            return MQX_IO_OPERATION_NOT_AVAILABLE;
        }
        _int_enable ();
        io_sai_dev_ptr->FLAGS |= I2S_IO_WRITE;
    }

    fd_ptr->FLAGS         = (_mqx_uint)flags;

    result = (*io_sai_dev_ptr->DEV_INIT)(io_sai_dev_ptr);
    if (result == MQX_OK)
    {
        if (read_open)
        {
            io_sai_dev_ptr->READ_COUNT = 1;
        }
        if (write_open)
        {
            io_sai_dev_ptr->WRITE_COUNT = 1;
        }
    }
    return result;
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _io_sai_int_close
* Returned Value   : MQX error code
* Comments         :
*    This routine closes the SAI I/O channel.
*
*END**********************************************************************/

_mqx_int _io_sai_int_close
(
    /* [IN] the file handle for the device being closed */
    MQX_FILE_PTR    fd_ptr
)
{ /* Body */
    IO_DEVICE_STRUCT_PTR        io_dev_ptr;
    IO_SAI_DEVICE_STRUCT_PTR    io_sai_dev_ptr;
    _mqx_int result = MQX_OK;

    io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_sai_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

    _int_disable();
    if (io_sai_dev_ptr->READ_COUNT > 0)
    {
        io_sai_dev_ptr->READ_COUNT--;
    }
    if (io_sai_dev_ptr->WRITE_COUNT > 0)
    {
        io_sai_dev_ptr->WRITE_COUNT--;
    }
    if ((io_sai_dev_ptr->READ_COUNT == 0) && (io_sai_dev_ptr->WRITE_COUNT == 0))
    {
        if (io_sai_dev_ptr->DEV_DEINIT)
        {
            result = (*io_sai_dev_ptr->DEV_DEINIT)(io_sai_dev_ptr, io_sai_dev_ptr->DEV_INFO_PTR);
        }
    }
    _int_enable();

    return result;
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _io_sai_int_read
* Returned Value   : number of bytes read
* Comments         :
*    Reads bytes into array from SAI input buffers.
*    Returns number of bytes received.
*
*END*********************************************************************/

_mqx_int _io_sai_int_read
(
    /* [IN] the handle returned from _fopen */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] where the data are to be stored */
    char_ptr        data_ptr,

    /* [IN] the number of bytes to read */
    _mqx_int        n
)
{  /* Body */
    IO_DEVICE_STRUCT_PTR        io_dev_ptr;
    IO_SAI_DEVICE_STRUCT_PTR    io_sai_dev_ptr;
    uint_32 result;

    io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_sai_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
    
    _lwsem_wait(&io_sai_dev_ptr->LWSEM);

    result = (*io_sai_dev_ptr->DEV_READ)(io_sai_dev_ptr, data_ptr, n);

    _lwsem_post(&io_sai_dev_ptr->LWSEM);

    return result;
}  /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _io_sai_int_write
* Returned Value   : number of bytes written
* Comments         :
*    This routine calls the appropriate write routine.
*
*END**********************************************************************/

_mqx_int _io_sai_int_write
(
    /* [IN] the handle returned from _fopen */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] where the data are to be stored */
    char_ptr        data_ptr,

    /* [IN] the number of bytes to read */
    _mqx_int        n
)
{  /* Body */
    IO_DEVICE_STRUCT_PTR         io_dev_ptr;
    IO_SAI_DEVICE_STRUCT_PTR io_sai_dev_ptr;
    uint_32 result;

    io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_sai_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
    
    _lwsem_wait(&io_sai_dev_ptr->LWSEM);

    result = (*io_sai_dev_ptr->DEV_WRITE)(io_sai_dev_ptr, data_ptr, n);
    
    _lwsem_post(&io_sai_dev_ptr->LWSEM);
    
    return result;

}  /* Endbody */

/*FUNCTION*****************************************************************
*
* Function Name    : _io_sai_int_ioctl
* Returned Value   : MQX error code
* Comments         :
*    Returns result of SAI ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_sai_int_ioctl
(
    /* [IN] the file handle for the device */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] the ioctl command */
    _mqx_uint       cmd,

    /* [IN] the ioctl parameters */
    pointer         input_param_ptr
)
{ /* Body */
    IO_DEVICE_STRUCT_PTR        io_dev_ptr;
    IO_SAI_DEVICE_STRUCT_PTR    io_sai_dev_ptr;
    _mqx_int                    result = MQX_OK;
    _mqx_uint_ptr               param_ptr = (_mqx_uint_ptr)input_param_ptr;

    io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_sai_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

    switch (cmd) {
        case IO_IOCTL_DEVICE_IDENTIFY :
            /* return the device identify */
            param_ptr[0] = 0;
            param_ptr[1] = 0;
            param_ptr[2] = IO_DEV_ATTR_INTERRUPT | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
            result = MQX_OK;
            break;
        default:
            if (io_sai_dev_ptr->DEV_IOCTL != NULL)
            {
                result = (*io_sai_dev_ptr->DEV_IOCTL)(io_sai_dev_ptr->DEV_INFO_PTR, cmd, param_ptr);
            }
    }

    return result;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/PE_Const.h<|end_filename|>
/* ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : PE_Const.h
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : PE_Const
**     Version     : Driver 01.00
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-08, 17:46, # CodeGen: 1
**     Abstract    :
**         This component "PE_Const" contains internal definitions
**         of the constants.
**     Settings    :
**     Contents    :
**         No public methods
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file PE_Const.h
** @version 01.00
** @brief
**         This component "PE_Const" contains internal definitions
**         of the constants.
*/         
/*!
**  @addtogroup PE_Const_module PE_Const module documentation
**  @{
*/         

#ifndef __PE_Const_H
#define __PE_Const_H


/* Reset cause constants */
#define RSTSRC_WAKEUP     0x01U        /*!< LLWU module wakeup reset */
#define RSTSRC_LVD        0x02U        /*!< Low-voltage detect reset */
#define RSTSRC_LOC        0x04U        /*!< Loss-of-clock reset      */
#define RSTSRC_COP        0x20U        /*!< Watchdog reset           */
#define RSTSRC_WDOG       0x20U        /*!< Watchdog reset           */
#define RSTSRC_PIN        0x40U        /*!< External pin reset       */
#define RSTSRC_POR        0x80U        /*!< Power-on reset          */
#define RSTSRC_JTAG       0x0100U      /*!< JTAG reset pin          */
#define RSTSRC_LOCKUP     0x0200U      /*!< Core Lock-up reset      */
#define RSTSRC_SW         0x0400U      /*!< Software reset          */
#define RSTSRC_MDM_AP     0x0800U      /*!< Reset caused by host debugger system   */
#define RSTSRC_EZPT       0x1000U      /*!< EzPort reset            */
#define RSTSRC_SACKERR    0x2000U      /*!< Stop Mode Acknowledge Error Reset      */


/* Low voltage interrupt cause constants */
#define LVDSRC_LVD        0x01U        /*!< Low voltage detect       */
#define LVDSRC_LVW        0x02U        /*!< Low-voltage warning      */

#endif /* _PE_Const_H */
/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/ticker.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ticker.c$
* $Version : 3.6.5.0$
* $Date    : Dec-2-2010$
*
* Comments:
*
*   Timer server and interface for the TCP layer.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "ticker.h"     /* for timer definitions */
#include "tcpip.h"      /* for error definitions */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Timer_schedule
* Returned Values : None.
* Comments        :
*
*  Insert node `timeq' into schedule queue;
*   if other TimeQ's are scheduled for the same time,
*   `timeq' will be inserted *after* them.
*
*  Fields of `timeq' which must defined prior to call:
*      timeq->delay
*      timeq->reload
*      timeq->donelist
*      timeq->client
*      timeq->count
*
*  Also assumes `timeq' is not in any list (timeq->curlist == 0).
*
*  This may be called by any task, not necessarily by the TCP_Tick_server;
*   however the calling task must have lower priority than the TCP_Tick_server
*   (which is normally the case).
*
*END*-----------------------------------------------------------------*/

void TCP_Timer_schedule
   (
      TimeQ _PTR_       timeq,      /* IN/OUT - The timer to schedule */
      TimeQ _PTR_ _PTR_ qhead_ptr   /* IN/OUT - The head of the timer queue */
   )
{ /* Body */
   TimeQ    _PTR_ scan,
            _PTR_ last;
   int_32   delta;
   
   RTCSLOG_FNE3(RTCSLOG_FN_TCP_Timer_schedule, timeq, qhead_ptr);

   /* Check assumption */
   if ( timeq->curlist != NULL ) {
      RTCS_log_error( ERROR_TCPIP,
                           RTCSERR_TCPIP_TIMER_CORRUPT,
                           (uint_32)timeq,
                           0, 0 );
      timeq->curlist = NULL;
   } /* Endif */

   /*  Find insertion point into 'schedule' queue
    */
   for ( last=NULL, scan=*qhead_ptr, delta=timeq->delay;
       scan != NULL && delta >= scan->delay;
       last=scan, scan=scan->next)
   {
      if ( last == scan ) { /* Corrupt list */
         RTCS_log_error( ERROR_TCPIP,
                              RTCSERR_TCPIP_TIMER_CORRUPT,
                              (uint_32)timeq,
                              1, 0 );
         scan = NULL;
      } else {
         delta -= scan->delay;
      } /* Endif */
   } /* Endfor */

   /*  Queue request (insert in queue)
    */
   timeq->delay = delta;
   timeq->next = scan;
   timeq->prev = last;
   timeq->curlist = qhead_ptr;

   if ( last != NULL ) {
      last->next = timeq;
   } else {
      *qhead_ptr = timeq;
   } /* Endif */

   if ( scan != NULL ) {
      scan->prev = timeq;
      scan->delay -= delta;      /* adjust next delta */
   } /* Endif */
   
   RTCSLOG_FNX1(RTCSLOG_FN_TCP_Timer_schedule);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Timer_expire
* Returned Values : None.
* Comments        :
*
*  For oneshot timers only; assumes `timeq' is not in any list.
*  Counts timeout, generates signal, and puts timeq in its donelist (if any).
*
*END*-----------------------------------------------------------------*/

   
void  TCP_Timer_expire
   (
      TimeQ _PTR_ timeq          /* IN/OUT - The expired timer */
   )
{ /* Body */
   TimeQ _PTR_ _PTR_ dlist;
   RTCSLOG_FNE2(RTCSLOG_FN_TCP_Timer_expire, timeq);
   
   timeq->count++;            /* count timeouts */

   dlist = timeq->donelist;

   /*
   ** Link onto front of donelist
   */
   if ( dlist != NULL ) {
      timeq->next = *dlist;
      if ( timeq->next != NULL ) {
         timeq->next->prev = timeq;
      } /* Endif */
      *dlist = timeq;
   } else {
      timeq->next = NULL;
   } /* Endif */
   timeq->prev = NULL;
   timeq->curlist = dlist;
   
   RTCSLOG_FNX1(RTCSLOG_FN_TCP_Timer_expire);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Timer_remove
* Returned Values : None.
* Comments        :
*
*  Removes a timer from the list which contains it.
*
*  Assumes timer is not active (i.e. assumes timeq->curlist != &qhead),
*   because it doesn't properly remove timer from qhead list
*   (use TCP_Timer_stop() for that).
*
*END*-----------------------------------------------------------------*/

void  TCP_Timer_remove
   (
      TimeQ _PTR_ timeq    /* IN/OUT - The timer to remove */
   )
{ /* Body */
   TimeQ _PTR_ next;
   
   RTCSLOG_FNE2(RTCSLOG_FN_TCP_Timer_remove, timeq);

   if ( timeq->curlist == NULL ) {   /* Not active and not on a donelist */
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_remove, -1);
      return;
   } /* Endif */

   next = timeq->next;
   if ( next != NULL ) {             /* unlink from next */
      next->prev = timeq->prev;
      timeq->next = NULL;
   } /* Endif */

   if ( timeq->prev != NULL ) {      /* unlink from prev */
      timeq->prev->next = next;
      timeq->prev = NULL;

   } else if ( timeq == *timeq->curlist ) { /* remove from list head */
      *timeq->curlist = next;

   } else {
      RTCS_log_error( ERROR_TCPIP,
                           RTCSERR_TCPIP_TIMER_CORRUPT,
                           (uint_32)timeq,
                           2, 0 );
   } /* Endif */

   timeq->curlist = NULL;
   
   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_remove, 0);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Timer_stop
* Returned Values : Positive error number.
* Comments        :
*
*  Stop a oneshot or cyclic timer; cannot be used to stop delays.
*
*  If the timer is active, it is *not* inserted into its `donelist' after
*   being stopped; if the timer is expired/idle, it is removed from its
*   `donelist' if present.
*
*  Returns OK, or RTCSERR_TCP_TIMED_OUT if timer was expired/idle.
*
*END*-----------------------------------------------------------------*/

int_32 TCP_Timer_stop
   (
      TimeQ _PTR_       timeq,      /* The timer to stop */
      TimeQ _PTR_ _PTR_ qhead_ptr   /* The timer queue head */
   )
{ /* Body */
   RTCSLOG_FNE3(RTCSLOG_FN_TCP_Timer_stop, timeq, qhead_ptr);

   /*  check to see if already timed out
    */
   if ( timeq->curlist != qhead_ptr ) { /* not active */
      TCP_Timer_remove(timeq);
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_stop, RTCSERR_TCP_TIMED_OUT);
      return RTCSERR_TCP_TIMED_OUT;
   } /* Endif */

   /*  Stop timer - remove from queue
    */
   if ( timeq->next != NULL ) {   /* adjust next delta */
      timeq->next->delay += timeq->delay;
      timeq->next->prev = timeq->prev;
   } /* Endif */

   if ( timeq->prev != NULL ) {
      timeq->prev->next = timeq->next;

   } else {
      *qhead_ptr = timeq->next;

   } /* Endif */

   timeq->prev = NULL;
   timeq->next = NULL;
   timeq->curlist = NULL;
   
   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_stop, RTCS_OK);
   return RTCS_OK;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Timer_start
* Returned Values : Positive error value.
* Comments        :
*
*  Start a oneshot or cyclic timer (timeq);
*
*  The timer must have been initialized at some point prior to calling this
*   function, with TimerInit() (or cleared will all zeroes, which is what
*   TimerInit() does); it donelist however may be set.
*
*  If the timer is currently active, it is stopped before proceeding
*   (logically; this may be optimized, e.g. incremented directly to requested
*    delay).
*
*  If the timer is a oneshot (reload == 0), and timeq->donelist is non-zero,
*   then upon timer expiry the timer will be inserted at the head of this
*   (*timeq->donelist) list.
*
*  If the timer is cyclic (reload != 0), then the timer will tick after
*   `delay' msecs, and thereafter every `reload' msecs.
*
*  If the timer was in a list (e.g., its donelist) before calling TCP_Timer_start(),
*   it is first removed.
*
*  Maximum delay or reload is 0x7fffffff (2^31-1), or 24 days+20:31:23.647;
*   negative delay is interpreted as zero;
*   a zero delay for a cyclic timer (reload != 0) maps to a delay = reload;
*   else a zero delay immediately expires the timer and puts it in its donelist
*    (if any), in which case TCP_Timer_start() returns RTCSERR_TCP_TIMED_OUT;
*   a negative reload is invalid.
*
*  Initially timeq->count is cleared.
*
*  Upon oneshot timer expiry, and upon every tick of a cyclic timer,
*   timeq->count is incremented.
*
*  Returns OK, RTCSERR_TCPIP_INVALID_ARGUMENT if reload < 0,
*   or RTCSERR_TCP_TIMED_OUT (for zero delays).
*
*END*-----------------------------------------------------------------*/

int_32 TCP_Timer_start
   (
      TimeQ _PTR_       timeq,      /* IN/OUT - The timer */
      int_32            delay,      /* IN     - No. msec until timeout */
      int_32            reload,     /* IN     - No. msec to dly after 1st to */
      TimeQ _PTR_ _PTR_ qhead_ptr   /* IN/OUT - Head of timer queue */
   )
{ /* Body */
   int_32   delta;
   uint_32  newtime;
   int_32 error;
   
   RTCSLOG_FNE5(RTCSLOG_FN_TCP_Timer_start, timeq, delay, reload, qhead_ptr);

   if ( reload < 0 ) {  /* i.e. delay attempted */
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_start, RTCSERR_TCPIP_INVALID_ARGUMENT);
      return RTCSERR_TCPIP_INVALID_ARGUMENT;
   } /* Endif */

   newtime = RTCS_time_get();
   if ( timeq->curlist == qhead_ptr ) { /* currently active timer */

      delta = timeq->abs_to - newtime;
      if ( delay > delta ) {           /* Longer delay requested */
         timeq->reload = reload;
         timeq->count = 0;
         error = TCP_Timer_advance(timeq, delay - timeq->delay, qhead_ptr);
         RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_start, error);
         return error;

      } else if ( delay < delta ) {       /* shorter delay requested */
         TCP_Timer_stop(timeq, qhead_ptr);

      } else {                             /* No change, so return */
         RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_start, RTCS_OK);
         return RTCS_OK;

      } /* Endif */

   } else {
      TCP_Timer_remove(timeq);

   } /* Endif */

   timeq->reload = reload;
   timeq->count = 0;
   if ( delay <= 0 ) {

      delay = reload;
      if ( delay == 0 ) {      /* zero delay, put timeq in donelist */
         TCP_Timer_expire(timeq);
         RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_start, RTCSERR_TCP_TIMED_OUT);
         return RTCSERR_TCP_TIMED_OUT;
      } /* Endif */

   } /* Endif */

   timeq->delay = delay;
   timeq->abs_to = newtime + delay;
   TCP_Timer_schedule(timeq, qhead_ptr);

   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_start, RTCS_OK);
   return RTCS_OK;

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Timer_advance
* Returned Values : Positive error number.
* Comments        :
*
*  Reschedule timer 'timeq' delta milliseconds into the future;
*   this is implemented mainly for TCP, since its retransmit timers must
*   be rescheduled each time new data is ACKed, and rescheduling by delta
*   should be faster than stopping and restarting the timer.
*
*  Assumes delta >= 0 !
*
*  This may also be called by (almost, see above) any task...
*
*END*-----------------------------------------------------------------*/

int_32 TCP_Timer_advance
   (
      TimeQ _PTR_       timeq,      /* IN/OUT - timer to reschedule */
      int_32            delta,      /* IN     - no. msec to increment timeout */
      TimeQ _PTR_ _PTR_ qhead_ptr   /* IN/OUT - timer queue head */
   )
{ /* Body */
   TimeQ _PTR_ next,
         _PTR_ prev;
   int_32 error;

   RTCSLOG_FNE4(RTCSLOG_FN_TCP_Timer_advance, timeq, delta, qhead_ptr);
   
   /*
   ** If timer has already expired, simply restart it with delay 'delta'
   */
   if ( timeq->curlist != qhead_ptr ) {
      error = TCP_Timer_start(timeq, delta, 0, qhead_ptr);
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_advance, error);
      return error;
   } /* Endif */

   /*
   ** Simple cases...
   */
   next = timeq->next;
   if ( next == NULL ) {             /* We are last timer in list */
      timeq->delay += delta;
      timeq->abs_to += delta;
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_advance, RTCS_OK);
      return RTCS_OK;
   } /* Endif */

   if ( delta <= next->delay ) {     /* New t/o is still less than the next */
      next->delay -= delta;
      timeq->delay += delta;
      timeq->abs_to += delta;
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_advance, RTCS_OK);
      return RTCS_OK;
   } /* Endif */

   /*
   ** Remove timer from its position in the queue, so we can advance it...
   */
   delta -= next->delay;
   next->delay += timeq->delay;
   next->prev = timeq->prev;
   if ( timeq->prev != NULL ) {
      timeq->prev->next = next;
   } else {
      *qhead_ptr = next;
   } /* Endif */

   /*
   ** Advance to proper insertion point into 'schedule' queue
   */
   while (1) {

      prev = next;
      next = next->next;
      if ( next == NULL ) {
         goto nonext;
      } /* Endif */

      if ( delta < next->delay ) {
         break;
      } /* Endif */
      delta -= next->delay;

   } /* Endwhile */

   /*
   ** If loop breaks here, next != 0
   */
   next->prev = timeq;
   next->delay -= delta;      /* adjust next delta */

   nonext:
      /*
      ** Reinsert timer in queue
      */
      timeq->delay = delta;
      timeq->abs_to = prev->abs_to + delta;
      timeq->next = next;
      timeq->prev = prev;
      prev->next = timeq;

      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_advance, RTCS_OK);
      return RTCS_OK;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Timer_oneshot_max
* Returned Values : Positive error number.
* Comments        :
*
*  Make timer `timeq' expire in at most `delay' msecs:
*
*   if already active at more than `delay' ms, reschedule to `delay' ms;
*
*   if already active at less than `delay', leave as is;
*
*   if expired (idle) but is in its donelist, i.e. if
*    (timeq->curlist EQ timeq->donelist AND timeq->curlist NE NULL),
*    then leave timer as is (usually it was not "processed"...);
*
*   if expired (idle) and not in its donelist, then simply start the timer
*    for `delay' msecs.
*
*  In the special case where `delay' is zero or negative, and the timer is
*   active, the timer is stopped and removed from its donelist (and remains
*   "read"), and OK is returned.
*
*  Before calling TCP_Timer_oneshot_max() for the first time, the timer should be
*   cleared to all zeroes (and its donelist possibly set; if it is, the timer
*   is automatically inserted into the donelist when it expires, and removed
*   from it (if present) when restarted).
*
*  This function is used, for example, in TCP's delayed ack timer
*
*  Return values:
*   0:                  timer started or was already in progress
*   RTCSERR_TCP_TIMED_OUT:  timer expired and in its donelist; not restarted.
*
*END*-----------------------------------------------------------------*/

int_32 TCP_Timer_oneshot_max
   (
      TimeQ _PTR_       timeq,      /* IN/OUT - timer to start */
      int_32            delay,      /* IN     - timeout */
      TimeQ _PTR_ _PTR_ qhead_ptr   /* IN/OUT - timer queue head */
   )
{ /* Body */
   int_32 error;
    
   RTCSLOG_FNE4(RTCSLOG_FN_TCP_Timer_oneshot_max, timeq, delay, qhead_ptr);

   if ( timeq->curlist != NULL ) {            /* may be active */

      if ( timeq->curlist == timeq->donelist ) { /* in its donelist */
         RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_oneshot_max, RTCSERR_TCP_TIMED_OUT);
         return RTCSERR_TCP_TIMED_OUT;
      } /* Endif */

      if ( timeq->curlist == qhead_ptr ) {    /* active... */
         if ( timeq->abs_to <= (RTCS_time_get()+delay) ) {
            /* Will expire earlier, so leave as is */
            RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_oneshot_max, RTCS_OK);
            return RTCS_OK;
         } /* Endif */
         TCP_Timer_stop(timeq, qhead_ptr);        /* too far, stop bfr rstrting */

      } else {
         TCP_Timer_remove(timeq);
      } /* Endif */

   } /* Endif */
   
   error = TCP_Timer_start(timeq, delay, 0, qhead_ptr);
   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Timer_oneshot_max, error);
   return error;

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Tick_server
* Returned Value  : time delay until next event
* Comments        :
*
*  This was the Tick Server task, now just a function.
*
*END*-----------------------------------------------------------------*/

uint_32 TCP_Tick_server
   (
      void
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;
   TimeQ _PTR_ _PTR_    qhead_ptr;
   register int_32      reload;
   uint_32              elapsed;
   TimeQ _PTR_          expired;
   boolean              reply;
   uint_32              newtime;

   RTCSLOG_FNE1(RTCSLOG_FN_TCP_Tick_server);
       
   tcp_cfg = RTCS_getcfg(TCP);
   qhead_ptr = tcp_cfg->qhead;
   reply = FALSE; /* assume no timeout */

   newtime = RTCS_time_get();
   elapsed = RTCS_timer_get_interval(tcp_cfg->lasttime, newtime); /* get elapsed msecs... */
   tcp_cfg->lasttime = newtime;

   /*  Update schedule queue
    */
   while ( *qhead_ptr != NULL ) {

      if (elapsed < (*qhead_ptr)->delay) {
         (*qhead_ptr)->delay -= elapsed;
         break;
      } else {
         reply = TRUE;  /* At least *qhead has expired */

      } /* Endif */
      elapsed -= (*qhead_ptr)->delay;

      /*  Timeout/delay expired - process and remove
       *   (reinsert afterwards if cyclic)
       *
       *  Here we assume we are running at higher priority than any
       *   task using timers, so we don't disable interrupts while
       *   processing expiration.
       */

      /* remove from front of queue... */
      expired = *qhead_ptr;
      *qhead_ptr = (*qhead_ptr)->next;
      if ( *qhead_ptr != NULL ) {
         (*qhead_ptr)->prev = NULL;
      } /* Endif */

      if ( expired->prev != NULL ) {
         RTCS_log_error( ERROR_TCPIP,
                              RTCSERR_TCPIP_TIMER_CORRUPT,
                              (uint_32)expired,
                              3,
                              (uint_32)expired->prev );
         expired->prev = NULL;
      } /* Endif */
      expired->next = NULL;
      expired->curlist = NULL;
      reload = expired->reload;

      if ( reload < 0 ) {           /* delay expired */

         RTCS_log_error( ERROR_TCPIP,
                              RTCSERR_TCPIP_DELAY_REQUESTED,
                              1,
                              0, 0 );


      } else if ( reload > 0 ) {       /* cyclic timeout */

         expired->count++;          /* count timeouts */

         /* Signal(expired->client); */

         expired->delay = reload;   /* reschedule... */
         expired->abs_to = newtime + reload;
         TCP_Timer_schedule(expired, qhead_ptr);

      } else {
         TCP_Timer_expire(expired);      /* oneshot */

      } /* Endif */

   } /* Endwhile */

   if (reply) {
      TCP_Process_signal();
   } /* Endif */

   if (!*qhead_ptr) {
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Tick_server, 0);
      return 0;
   } else if ((signed)((*qhead_ptr)->abs_to - newtime) <= 0) {
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Tick_server, 1);
      return 1;
   } else {
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Tick_server, (*qhead_ptr)->abs_to - newtime);
      return (*qhead_ptr)->abs_to - newtime;
   } /* Endif */

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/MonitorVT100.h<|end_filename|>
#ifndef __MONITORVT100
  #define __MONITORVT100

  #define COLCOUNT 80
  #define ROWCOUNT 24

/* cursor motion */
  #define VT100_CURSOR_DN   "\033D"  //
  #define VT100_CURSOR_DN_L "\033E"
  #define VT100_CURSOR_UP   "\033M"
  #define VT100_CURSOR_HOME "\033[H"
  #define VT100_CURSOR_N_UP "\033[%dA"  /* printf argument: lines */
  #define VT100_CURSOR_N_RT "\033[%dC"  /* printf argument: cols  */
  #define VT100_CURSOR_N_LT "\033[%dD"  /* printf argument: cols  */
  #define VT100_CURSOR_N_DN "\033[%dB"  /* printf argument: lines */
  #define VT100_CURSOR_SET  "\033[%d;%dH" /* printf arguments: row, col */

/* erasing the screen */
  #define VT100_CLR_FM_CRSR "\033[J"
  #define VT100_CLR_TO_CRSR "\033[1J"
  #define VT100_CLR_SCREEN  "\033[2J"

/* erasing current line */
  #define VT100_CLL_FM_CRSR "\033[K"
  #define VT100_CLL_TO_CRSR "\033[1K"
  #define VT100_CLR_LINE    "\033[2K"

/* inserting and deleting */
  #define VT100_INS_CHARS   "\033[%d"   /* printf argument: cols */
  #define VT100_DEL_CHARS   "\033[%dP"  /* printf argument: cols */
  #define VT100_INS_LINES   "\033[%dL"  /* printf argument: cols */
  #define VT100_DEL_LINES   "\033[%dM"  /* printf argument: cols */

/* character attributes */
  #define VT100_NORMAL      "\033[m"
  #define VT100_ALL_OFF     "\033[0m"
  #define VT100_BOLD_ON     "\033[1m"
  #define VT100_BOLD_OFF    "\033[22m"
  #define VT100_UNDERL_ON   "\033[4m"
  #define VT100_UNDERL_OFF  "\033[24m"
  #define VT100_BLINK_ON    "\033[5m"
  #define VT100_BLINK_OFF   "\033[25m"
  #define VT100_REVERSE_ON  "\033[7m"
  #define VT100_REVERSE_OFF "\033[27m"
  #define VT100_INVIS_ON    "\033[8m"
  #define VT100_INVIS_OFF   "\033[28m"

/* screen attributes */
  #define VT100_ECHO_ON     "\033[12l"
  #define VT100_ECHO_OFF    "\033[12h"
  #define VT100_WRAP_ON     "\033[?7l"
  #define VT100_WRAP_OFF    "\033[?7h"
  #define VT100_CURSOR_ON   "\033[?25h"
  #define VT100_CURSOR_OFF  "\033[?25l"
  #define VT100_ENQ_SIZE    "\033[?92l" /* response: "\033[?%d,%dc" rows, cols */

  #define VT100_CLEAR_AND_HOME "\033[2J\033[H\033[m\033[?25l"


  #define DASH_LINE "--------------------------------------------------------------------------------"
  #define SCR_ITEMS_VERT_OFFS 8
  #define SCR_ITEMS_HOR_OFFS  1


typedef void (*T_menu_func)(INT8U  keycode);

typedef struct
{
  INT8U but;             // Кнопка нажатие которой вызывает данный пункт
  T_menu_func func;      // Функция вызываемая данным пунктом меню
  void *psubmenu;        // Аргумент. Для подменю указатель на запись подменю
} T_VT100_Menu_item;

typedef struct
{
  const INT8U *menu_header;           // Заголовок вверху экрана посередине
  const INT8U *menu_body;          // Содержание меню
  const T_VT100_Menu_item *menu_items;       // Массив структур с аттрибутами пунктов меню
  const INT16S menu_items_cnt;        // Количество пунктов меню

} T_VT100_Menu;

  #define MENU_MAX_DEPTH 20
typedef struct
{
  void           *ptr;
  //NU_TASK         tsk;
  //NU_DRIVER      *driver;
  T_VT100_Menu   *menu_trace[MENU_MAX_DEPTH];
  INT32U          menu_nesting;
  INT8U           curr_pos;                      // Текущая позиция в области редактирования
  INT8U           beg_pos;                       // Начальная позиция области редактирования
                                                 //RTC_DATE        date;
                                                 //RTC_TIME        tim;
  void            (*Monitor_func)(unsigned char);

  volatile INT8U  current_param_category;
  volatile INT8U  current_categories_count;      // Количество подуровней в текущем меню
  volatile INT8U  current_category_items_count;  // Общее количество пунктов в текущем меню
  volatile int    par_indx;                      // Индекс редактируемого параметра
  INT8U           param_str[512];
  INT8U           firstrow;                      // Позиция первой  строки области редактирования переменной
  INT8U           rowcount;                      // Количество строк в области редактирования
  INT8U           current_row;
  INT8U           current_col;
  INT8U           current_pos;

} T_VT100_cb;


void         VT100_task(uint_32 initial_data);

void         VT100_clr_screen(void);
void         VT100_send_str_to_pos(INT8U *str, INT8U row, INT8U col);
INT8U        Find_str_center(INT8U *str);
void         VT100_send_str_to_pos(INT8U *str, INT8U row, INT8U col);

void         VT100_set_cursor_pos(INT8U row, INT8U col);

void         Set_monitor_func(void (*func)(unsigned char));
void         Goto_main_menu(void);
void         Return_to_prev_menu(void);
void         Execute_menu_func(INT8U b);
void         Display_menu(void);

INT32S       Mon_input_line(char *buf, int buf_len, int row, char *instr);

INT32S       Mon_send_buf(INT8U *buf, INT32U len);
INT32S       Mon_wait_byte(INT8U *b, INT32U timeout);

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2s/int/i2s_int_ki2s.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2s_int_ki2s.c$
* $Version : 3.8.8.0$
* $Date    : Aug-20-2012$
*
* Comments:
*
*   This file contains low level functions for the I2S interrupt device driver
*   for Kinetis family.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "i2s.h"
#include "i2s_int_prv.h"
#include "i2s_ki2s_prv.h"

uint_32 _ki2s_int_init (IO_I2S_DEVICE_STRUCT_PTR, char_ptr);
uint_32 _ki2s_int_deinit (IO_I2S_DEVICE_STRUCT_PTR, KI2S_INFO_STRUCT_PTR);
uint_32 _ki2s_int_rx (IO_I2S_DEVICE_STRUCT_PTR, char_ptr, uint_32);
uint_32 _ki2s_int_tx (IO_I2S_DEVICE_STRUCT_PTR, char_ptr, uint_32);
uint_32 _ki2s_int_ioctl (KI2S_INFO_STRUCT_PTR io_info_ptr, uint_32 cmd, pointer param_ptr);
static void _ki2s_int_isr (pointer);
static uint_32 _ki2s_format_in_data(char_ptr input, AUDIO_DATA_FORMAT_PTR format);
static void _ki2s_format_out_data(uint_32 input, char_ptr output, AUDIO_DATA_FORMAT_PTR format);
static uint_32 _ki2s_sine_wave(uint_32 fs, uint_32 freq, int_16_ptr* output);
static _mqx_int _ki2s_hw_init(KI2S_INIT_STRUCT_PTR, I2S_MemMapPtr);
static uint_32 _ki2s_get_mclk_value(KI2S_INFO_STRUCT_PTR io_info_ptr);
static _mqx_int _ki2s_set_mclk_value(KI2S_INFO_STRUCT_PTR io_info_ptr, uint_32 frequency);
static _mqx_int _ki2s_set_fs_value(KI2S_INFO_STRUCT_PTR io_info_ptr, uint_32 frequency);
/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_int_install
* Returned Value   : MQX error code
* Comments         :
*    Install an I2S device.
*
*END*********************************************************************/

uint_32 _ki2s_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr           identifier,

      /* [IN] The I/O init data pointer */
      KI2S_INIT_STRUCT_CPTR  init_data_ptr
   )
{ /* Body */

   return _io_i2s_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, char_ptr))_ki2s_int_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_ki2s_int_deinit,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_ki2s_int_rx,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_ki2s_int_tx,
      (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_ki2s_int_ioctl,
      (pointer)init_data_ptr);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_int_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an I2S device.
*
*END*********************************************************************/

uint_32 _ki2s_int_init
   (
      /* [IN] Initialization information for the device being opened */
      IO_I2S_DEVICE_STRUCT_PTR  io_i2s_dev_ptr,

      /* [IN] The rest of the name of the device opened */
      char_ptr                      open_name_ptr

   )
{ /* Body */
   I2S_MemMapPtr        i2s_ptr;
   KI2S_INIT_STRUCT_PTR i2s_init_ptr;
   KI2S_INFO_STRUCT_PTR io_info_ptr;
   uint_8               channel, mode, data_bits, clk_source, endianity, aligment, bits, size, channels;
   _mqx_uint            vector, buffer_size;
   _mqx_uint            result = 0;

   /*Variables initialization*/
   i2s_init_ptr = (KI2S_INIT_STRUCT_PTR)(io_i2s_dev_ptr->DEV_INIT_DATA_PTR);
   if (i2s_init_ptr == NULL)
   {
      #ifdef I2S_DEBUG
       printf("_i2s_init: Error - Invalid init struct pointer.\n");
      #endif
      return(I2S_ERROR_INVALID_PARAMETER);
   }
   else
   {
      channel = i2s_init_ptr->CHANNEL;
      mode = i2s_init_ptr->MODE;
      data_bits = i2s_init_ptr->DATA_BITS;
      clk_source = i2s_init_ptr->CLOCK_SOURCE;
      buffer_size = i2s_init_ptr->BUFFER_SIZE;
      endianity = i2s_init_ptr->IO_FORMAT->ENDIAN;
      aligment = i2s_init_ptr->IO_FORMAT->ALIGNMENT;
      bits = i2s_init_ptr->IO_FORMAT->BITS;
      size = i2s_init_ptr->IO_FORMAT->SIZE;
      channels = i2s_init_ptr->IO_FORMAT->CHANNELS;
   }

   if ((data_bits < 8) || (data_bits > 24) || (data_bits == 14) || (data_bits % 2))
   {
      #ifdef I2S_DEBUG
       printf("_i2s_init: Error - Unsupported data word length.\n");
      #endif
      return (I2S_ERROR_WORD_LENGTH_UNSUPPORTED);
   }

   if ((channel > 1) || (channel < 0))
   {
      #ifdef I2S_DEBUG
       printf("_i2s_init: Error - Invalid I2S channel.\n");
      #endif
      return(I2S_ERROR_CHANNEL_INVALID);
   }

   if (mode > I2S_MODE_SLAVE)
   {
      #ifdef I2S_DEBUG
       printf("_i2s_init: Error - Invalid I2S mode.\n");
      #endif
      return(I2S_ERROR_MODE_INVALID);
   }
   if (clk_source > I2S_CLK_EXT)
   {
      #ifdef I2S_DEBUG
       printf("_i2s_init: Error - Invalid I2S clock source.\n");
      #endif
      return(I2S_ERROR_CLK_INVALID);
   }
   if (buffer_size < 2)
   {
      #ifdef I2S_DEBUG
       printf("_i2s_init: Error - I2S transmit buffer size too small.\n");
      #endif
      return(I2S_ERROR_BUFFER_SMALL);
   }
   if ((aligment > AUDIO_ALIGNMENT_LEFT) || (bits < AUDIO_BIT_SIZE_MIN) ||
      (bits > AUDIO_BIT_SIZE_MAX) || (endianity > AUDIO_LITTLE_ENDIAN) ||
      (size * I2S_CHAR_BIT < bits) || (channels > 2) || (channels == 0))
   {
      #ifdef I2S_DEBUG
        printf("_i2s_init: Error - Invalid I/O data format.\n");
      #endif
      return(AUDIO_ERROR_INVALID_IO_FORMAT);
   }
   i2s_ptr = _bsp_get_i2s_base_address(channel);
   io_info_ptr = (KI2S_INFO_STRUCT_PTR) _mem_alloc_system_zero ((uint_32)sizeof (KI2S_INFO_STRUCT));
   if (NULL == io_info_ptr)
   {
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type (io_info_ptr, MEM_TYPE_IO_I2S_INFO_STRUCT);

   /* I2S board specific IO pins initialization */
   if (_bsp_i2s_io_init(channel) != MQX_OK)
   {
     #ifdef I2S_DEBUG
      printf("_i2s_init: Error - I/O init failed.\n");
     #endif
     return(I2S_ERROR_IO_INIT_FAILED);
   }
   /* I2S board specific registers initialization */
   _ki2s_hw_init(i2s_init_ptr, i2s_ptr);

   /*Info struct setup*/
   io_info_ptr->INIT = *i2s_init_ptr;
   io_info_ptr->I2S_PTR = i2s_ptr;
   io_info_ptr->MODE = i2s_init_ptr->MODE;
   io_info_ptr->DATA_BITS = i2s_init_ptr->DATA_BITS;
   io_info_ptr->CLOCK_SOURCE = i2s_init_ptr->CLOCK_SOURCE;
   io_info_ptr->IO_FORMAT.ENDIAN = endianity;
   io_info_ptr->IO_FORMAT.BITS = bits;
   io_info_ptr->IO_FORMAT.ALIGNMENT = aligment;
   io_info_ptr->IO_FORMAT.SIZE = size;
   io_info_ptr->IO_FORMAT.CHANNELS = channels;
   
   if (io_info_ptr->CLOCK_SOURCE == I2S_CLK_INT)
   {
      io_info_ptr->MCLK_FREQ = _ki2s_get_mclk_value(io_info_ptr);
      io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / 4;
      /* DIV2 = 1 in default and 2 is inner division */
      io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * io_info_ptr->IO_FORMAT.CHANNELS);
   }
   else
   {
      io_info_ptr->MCLK_FREQ = 0;
      io_info_ptr->BCLK_FREQ = 0;
      io_info_ptr->FS_FREQ = 0;
   }
   io_info_ptr->MCLK_DIV = SSIDIV_MIN;
   io_info_ptr->BCLK_DIV = 4;
   io_info_ptr->TX_DUMMY = i2s_init_ptr->TX_DUMMY;
   io_info_ptr->ONTHEWAY = FALSE;
   io_info_ptr->DATA_L = NULL;
   io_info_ptr->DATA_R = NULL;
   /* Set up interrupts mask */
   if (channels == 1)
   {
       io_info_ptr->TX_INT_MASK = (I2S_IER_TFE0EN_MASK);
       io_info_ptr->RX_INT_MASK = (I2S_IER_RFF0EN_MASK);
   }
   else
   {
       io_info_ptr->TX_INT_MASK = (I2S_IER_TFE0EN_MASK | I2S_IER_TFE1EN_MASK);
       io_info_ptr->RX_INT_MASK = (I2S_IER_RFF0EN_MASK | I2S_IER_RFF1EN_MASK);
   }
   result = _lwsem_create(&(io_info_ptr->EVENT_IO_FINISHED), 0);
   if (result != MQX_OK) {
      #ifdef I2S_DEBUG
      printf("i2s_init - Error: Unable to create event_int_done.\n");
      #endif
      _task_set_error(result);
   }
   io_info_ptr->CLK_ALWAYS_ON = TRUE;
   io_info_ptr->FIRST_IO = TRUE;

   /* Buffers allocation */
   io_info_ptr->BUFFER_L.DATA = (uint_32_ptr) _mem_alloc_system(buffer_size * sizeof(uint_32));
   if (io_info_ptr->BUFFER_L.DATA == NULL)
   {
      #ifdef I2S_DEBUG
      printf("i2s_init - Error: Unable to allocate buffer memory.\n");
      #endif
      return MQX_OUT_OF_MEMORY;
   }
   io_info_ptr->BUFFER_L.SPACE = buffer_size;
   io_info_ptr->BUFFER_L.SIZE = buffer_size;

   io_info_ptr->BUFFER_R.DATA = (uint_32_ptr) _mem_alloc_system(buffer_size * sizeof(uint_32));
   if (io_info_ptr->BUFFER_R.DATA == NULL)
   {
      uint_32 errcode = _mem_free(io_info_ptr->BUFFER_L.DATA);
      if (errcode != MQX_OK)
      {
         return errcode;
      }
      io_info_ptr->BUFFER_L.DATA = NULL;
      io_info_ptr->BUFFER_L.SPACE = 0;
      io_info_ptr->BUFFER_L.SIZE = 0;
      #ifdef I2S_DEBUG
      printf("i2s_init - Error: Unable to allocate buffer memory.\n");
      #endif
      return MQX_OUT_OF_MEMORY;
   }
   io_info_ptr->BUFFER_R.SPACE = buffer_size;
   io_info_ptr->BUFFER_R.SIZE = buffer_size;

   _mem_set_type (io_info_ptr->BUFFER_L.DATA, MEM_TYPE_IO_I2S_LEFT_BUFFER);
   _mem_set_type (io_info_ptr->BUFFER_R.DATA, MEM_TYPE_IO_I2S_RIGHT_BUFFER);

   io_i2s_dev_ptr->DEV_INFO_PTR = io_info_ptr;

   /*Interrupt vector setup*/
   vector = _bsp_get_i2s_vector(channel);
   io_info_ptr->OLD_ISR_DATA = _int_get_isr_data (vector);
   io_info_ptr->OLD_ISR = _int_install_isr (vector, _ki2s_int_isr, io_info_ptr);
   _bsp_int_init((IRQInterruptIndex)_bsp_get_i2s_vector(channel), io_info_ptr->INIT.LEVEL, 0, TRUE);

   return(I2S_OK);
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_int_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an I2S device.
*
*END*********************************************************************/

uint_32 _ki2s_int_deinit
   (
      /* [IN] the initialization information for the device being opened */
      IO_I2S_DEVICE_STRUCT_PTR  io_i2s_dev_ptr,

      /* [IN] the address of the device specific information */
      KI2S_INFO_STRUCT_PTR   io_info_ptr
   )
{ /* Body */
   I2S_MemMapPtr          i2s_ptr;
   KI2S_INIT_STRUCT_PTR   i2s_init_ptr;
   _mqx_uint              errcode;
   _mqx_uint              result = 0;

   if ((NULL == io_info_ptr) || (NULL == io_i2s_dev_ptr))
   {
      return I2S_ERROR_INVALID_PARAMETER;
   }

   i2s_ptr = io_info_ptr->I2S_PTR;

   /*SSI disable*/
   i2s_ptr->CR &= ~(I2S_CR_I2SEN_MASK);

   /* Clear the SSI events */
   i2s_ptr->ISR = 0x00;

   /* Install original vectors */
   i2s_init_ptr = (KI2S_INIT_STRUCT_PTR)(io_i2s_dev_ptr->DEV_INIT_DATA_PTR);
   _bsp_int_init((IRQInterruptIndex)_bsp_get_i2s_vector(i2s_init_ptr->CHANNEL), i2s_init_ptr->LEVEL, 0, TRUE);
   _int_install_isr (_bsp_get_i2s_vector (i2s_init_ptr->CHANNEL), io_info_ptr->OLD_ISR, io_info_ptr->OLD_ISR_DATA);
   /* Destroy event */
   result = _lwsem_destroy(&(io_info_ptr->EVENT_IO_FINISHED));
   if (result != MQX_OK)
   {
      #ifdef I2S_DEBUG
      printf("i2s_rx - Error: unable to destroy event_int_done.\n");
      #endif
      _task_set_error(result);
   }
   /* Free buffers and info struct */
   errcode = _mem_free (io_info_ptr->BUFFER_L.DATA);
   if (errcode != MQX_OK)
   {
      return errcode;
   }
   io_info_ptr->BUFFER_L.IN = 0;
   io_info_ptr->BUFFER_L.OUT = 0;
   io_info_ptr->BUFFER_L.DATA = NULL;
   io_info_ptr->BUFFER_L.SPACE = 0;
   io_info_ptr->BUFFER_L.SIZE = 0;

   errcode = _mem_free (io_info_ptr->BUFFER_R.DATA);
   if (errcode != MQX_OK)
   {
      return errcode;
   }
   io_info_ptr->BUFFER_R.IN = 0;
   io_info_ptr->BUFFER_R.OUT = 0;
   io_info_ptr->BUFFER_R.DATA = NULL;
   io_info_ptr->BUFFER_R.SPACE = 0;
   io_info_ptr->BUFFER_R.SIZE = 0;

   if (io_info_ptr->TX_DUMMY)
   {
      errcode = _mem_free (io_info_ptr->DUMMY.DATA);
      if (errcode != MQX_OK)
      {
         return errcode;
      }
      io_info_ptr->DUMMY.DATA = NULL;
   }

   errcode = _mem_free (io_i2s_dev_ptr->DEV_INFO_PTR);
   if (errcode != MQX_OK)
   {
      return errcode;
   }
   io_i2s_dev_ptr->DEV_INFO_PTR = NULL;
   return I2S_OK;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_int_rx
* Returned Value   : number of bytes read
* Comments         :
*   Returns the number of bytes received.
*   Reads the data into provided array when data is available.
*
*END*********************************************************************/

uint_32 _ki2s_int_rx
   (
      /* [IN] the address of the device specific information */
      IO_I2S_DEVICE_STRUCT_PTR   io_i2s_dev_ptr,

      /* [IN] The array to copy data into */
      char_ptr                      buffer,

    /* [IN] number of bytes to read */
      uint_32                       length
   )
{ /* Body */
   KI2S_INFO_STRUCT_PTR             io_info_ptr   = io_i2s_dev_ptr->DEV_INFO_PTR;
   I2S_MemMapPtr                    i2s_ptr = io_info_ptr->I2S_PTR;
   KI2S_BUFFER_PTR                  buffer_l = &(io_info_ptr->BUFFER_L);
   KI2S_BUFFER_PTR                  buffer_r = &(io_info_ptr->BUFFER_R);
   I2S_STATISTICS_STRUCT_PRV_PTR    stats = &(io_info_ptr->STATS);
   AUDIO_DATA_FORMAT_PTR            io_format = &(io_info_ptr->IO_FORMAT);
   LWSEM_STRUCT_PTR                 event_int_done = &(io_info_ptr->EVENT_IO_FINISHED);
   _mqx_uint                        result = MQX_OK;
   uint_32                          i = 0;

   /* disable interrupts */
   i2s_ptr->IER &= ~(
      I2S_IER_TUE0EN_MASK | /* Transmit underrun error 0*/
      I2S_IER_TFE0EN_MASK | /* Transmit FIFO0 empty */
      I2S_IER_TUE1EN_MASK | /* Transmit underrun error 1*/
      I2S_IER_TFE1EN_MASK   /* Transmit FIFO1 empty */
      );

   io_info_ptr->IO_MODE = I2S_IO_READ;
   /* Init stats and buffers to default values */
    stats->PACKETS_REQUESTED_L += length/(io_format->CHANNELS * io_format->SIZE);
    switch (io_format->CHANNELS)
   {
      case 1:
         io_info_ptr->DATA_L = buffer;
         io_info_ptr->DATA_R = buffer;
         /* One channel only - enable only interrupts of FIFO0 */
         i2s_ptr->IER |= (I2S_IER_RFF0EN_MASK | I2S_IER_ROE0EN_MASK);
      break;

      default:
          io_info_ptr->DATA_L = buffer;
          io_info_ptr->DATA_R = buffer + io_format->SIZE;
          i2s_ptr->IER |= (
              I2S_IER_ROE0EN_MASK | /* Receive overrun error 0*/
              I2S_IER_RFF0EN_MASK | /* Receive FIFO0 full */
              I2S_IER_ROE1EN_MASK | /* Receive overrun error 1*/
              I2S_IER_RFF1EN_MASK   /* Receive FIFO1 full */
              );
          stats->PACKETS_REQUESTED_R += length/(io_format->CHANNELS * io_format->SIZE);
      break;
   }

   io_info_ptr->ONTHEWAY = TRUE;

   while(io_info_ptr->ONTHEWAY)
   {
      if (io_info_ptr->FIRST_IO) /* enable receiver and interrupts in a case of first run to get some data */
      {
         io_info_ptr->FIRST_IO = FALSE;
         i2s_ptr->IER |= (I2S_IER_RIE_MASK); /* Receive interrupts enable */
         i2s_ptr->CR |= (I2S_CR_RE_MASK); /* Enable receiver */
      }
      /* Wait for a receive completition */
      result = _lwsem_wait(event_int_done);
      if (result != MQX_OK)
      {
         #ifdef I2S_DEBUG
          printf("i2s_rx - Error: Wait for event_int_done failed.\n");
         #endif
         _task_set_error(result);
      }
      /* All data received, disable receiver */
      if ((stats->PACKETS_QUEUED_L >= stats->PACKETS_REQUESTED_L) &&
          (stats->PACKETS_QUEUED_R >= stats->PACKETS_REQUESTED_R))
      {
          io_info_ptr->ONTHEWAY = FALSE;
      }
      while ((stats->PACKETS_PROCESSED_L < stats->PACKETS_QUEUED_L) &&
             (stats->PACKETS_PROCESSED_L < stats->PACKETS_REQUESTED_L))
      {
         /* Critical Section - disable interrupts with access to buffer */
         i2s_ptr->IER &= ~(io_info_ptr->RX_INT_MASK);
         _ki2s_format_out_data(buffer_l->DATA[buffer_l->OUT], io_info_ptr->DATA_L, io_format);
         stats->PACKETS_PROCESSED_L++;
         buffer_l->SPACE++;
         (++buffer_l->OUT >= buffer_l->SIZE) ? (buffer_l->OUT = 0) : (0);
         /* End of critical section*/
         i2s_ptr->IER |= (io_info_ptr->RX_INT_MASK);
         io_info_ptr->DATA_L += io_format->CHANNELS * io_format->SIZE;
      }

      while ((stats->PACKETS_PROCESSED_R < stats->PACKETS_QUEUED_R) &&
             (stats->PACKETS_PROCESSED_R < stats->PACKETS_REQUESTED_R))
      {
         /* Critical Section - disable interrupts with access to buffer */
         i2s_ptr->IER &= ~(io_info_ptr->RX_INT_MASK);
         *(io_info_ptr->DATA_R) = buffer_r->DATA[buffer_r->OUT];
         _ki2s_format_out_data(buffer_r->DATA[buffer_r->OUT], io_info_ptr->DATA_R, io_format);
         stats->PACKETS_PROCESSED_R++;
         buffer_r->SPACE++;
         (++buffer_r->OUT >= buffer_r->SIZE) ? (buffer_r->OUT = 0) : (0);
         /* End of critical section*/
         i2s_ptr->IER |= (io_info_ptr->RX_INT_MASK);
         io_info_ptr->DATA_R += io_format->CHANNELS * io_format->SIZE;
      }
   }
   return(length);
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_int_tx
* Returned Value   : number of bytes written
* Comments         :
*   Returns the number of bytes written.
*   Writes the data provided into transmition buffer if available.
*
*END*********************************************************************/

uint_32 _ki2s_int_tx
   (
      /* [IN] the address of the device specific information */
      IO_I2S_DEVICE_STRUCT_PTR    io_i2s_dev_ptr,

      /* [IN] The array to be read from */
      char_ptr                       buffer,

      /* [IN] number of packets to output */
      uint_32                         length
   )
{ /* Body */
   KI2S_INFO_STRUCT_PTR          io_info_ptr = io_i2s_dev_ptr->DEV_INFO_PTR;
   I2S_MemMapPtr                 i2s_ptr = io_info_ptr->I2S_PTR;
   KI2S_BUFFER_PTR               buffer_l = &(io_info_ptr->BUFFER_L);
   KI2S_BUFFER_PTR               buffer_r = &(io_info_ptr->BUFFER_R);
   I2S_STATISTICS_STRUCT_PRV_PTR stats = &(io_info_ptr->STATS);
   AUDIO_DATA_FORMAT_PTR         io_format = &(io_info_ptr->IO_FORMAT);
   LWSEM_STRUCT_PTR              event_int_done = &(io_info_ptr->EVENT_IO_FINISHED);
   _mqx_uint                     result = MQX_OK;

   

   i2s_ptr->IER &= ~(
         I2S_IER_ROE0EN_MASK | /* Receive overrun error 0*/
         I2S_IER_RFF0EN_MASK | /* Receive FIFO0 full */
         I2S_IER_ROE1EN_MASK | /* Receive overrun error 0*/
         I2S_IER_RFF1EN_MASK   /* Receive FIFO0 full */
         );
   
   stats->PACKETS_REQUESTED_L += length/(io_format->CHANNELS * io_format->SIZE);
   
   if ((buffer == NULL) && !(io_info_ptr->TX_DUMMY))
   {
      _task_set_error(I2S_ERROR_INVALID_PARAMETER);
      return (0);
   }
   else
   {
      switch (io_format->CHANNELS)
      {
         case 1:
            io_info_ptr->DATA_L = buffer;
            io_info_ptr->DATA_R = buffer;
            /* One channel only - enable only interrupts of FIFO0 */
            i2s_ptr->IER |= (I2S_IER_TUE0EN_MASK | I2S_IER_TFE0EN_MASK);
         break;

         default:
            io_info_ptr->DATA_L = buffer;
            io_info_ptr->DATA_R = buffer + io_format->SIZE;
            i2s_ptr->IER |= (
               I2S_IER_TUE0EN_MASK | /* Transmit underrun error 0*/
               I2S_IER_TFE0EN_MASK | /* Transmit FIFO0 empty */
               I2S_IER_TUE1EN_MASK | /* Transmit underrun error 0*/
               I2S_IER_TFE1EN_MASK   /* Transmit FIFO0 empty */
               );
            stats->PACKETS_REQUESTED_R += length/(io_format->CHANNELS * io_format->SIZE);
         break;
      }
   }

   io_info_ptr->IO_MODE = I2S_IO_WRITE;
   
   if (io_info_ptr->TX_DUMMY)
   {
      stats->PACKETS_QUEUED_L = stats->PACKETS_REQUESTED_L;
      stats->PACKETS_QUEUED_R = stats->PACKETS_REQUESTED_R;
   }

   io_info_ptr->ONTHEWAY = TRUE;
    
   while(io_info_ptr->ONTHEWAY)
   {
      if (!(io_info_ptr->TX_DUMMY))
      {
         /* Copy data from input to left channel buffer */
         while ((buffer_l->SPACE > 0) && (stats->PACKETS_QUEUED_L < stats->PACKETS_REQUESTED_L))
         {
            /* buffer access, critical section - disable interrupts with buffer access */
            i2s_ptr->IER &= ~(io_info_ptr->TX_INT_MASK);
            buffer_l->DATA[buffer_l->IN] = _ki2s_format_in_data(io_info_ptr->DATA_L, io_format);
            buffer_l->SPACE--;
            stats->PACKETS_QUEUED_L++;
            /* buffer only even samples */
            io_info_ptr->DATA_L += io_format->CHANNELS * io_format->SIZE;
            /* increase and check input index of left cyclic buffer */
            (++buffer_l->IN >= buffer_l->SIZE) ? (buffer_l->IN = 0) : (0);
            /* critical section end - enable interrupt */
            i2s_ptr->IER |= (io_info_ptr->TX_INT_MASK);
         }

         /* Copy data from input to right channel buffer */
         while ((buffer_r->SPACE > 0) && (stats->PACKETS_QUEUED_R < stats->PACKETS_REQUESTED_R))
         {
            /* buffer access, critical section - disable interrupts with buffer access */
            i2s_ptr->IER &= ~(io_info_ptr->TX_INT_MASK);
            buffer_r->DATA[buffer_r->IN] = _ki2s_format_in_data(io_info_ptr->DATA_R, io_format);
            buffer_r->SPACE--;
            stats->PACKETS_QUEUED_R++;
            /* buffer only odd samples */
            io_info_ptr->DATA_R += io_format->CHANNELS * io_format->SIZE;
            /* increase and check input index of right cyclic buffer */
            (++buffer_r->IN >= buffer_r->SIZE) ? (buffer_r->IN = 0) : (0);
            /* critical section end - enable interrupt */
            i2s_ptr->IER |= (io_info_ptr->TX_INT_MASK);
         }
      }
      if (io_info_ptr->FIRST_IO)
      {
         io_info_ptr->FIRST_IO = FALSE;
         i2s_ptr->IER |= (I2S_IER_TIE_MASK); /* Transmit interrupts enable*/
         i2s_ptr->CR |= (I2S_CR_TE_MASK); /* Enable transmitter */
      }

      /* If all requested packets are queued, break and return from function */
      if ((stats->PACKETS_QUEUED_L == stats->PACKETS_REQUESTED_L) && (stats->PACKETS_QUEUED_R == stats->PACKETS_REQUESTED_R))
      {
         break;
      }

      /* Wait for transmit finish and make current task blocked */
      result = _lwsem_wait(event_int_done);

      if (result != MQX_OK)
      {
         #ifdef I2S_DEBUG
          printf("i2s_tx - Error: Wait for event_int_done failed.\n");
         #endif
         _task_set_error(result);
      }
   }
   /* return number of processed data */
   return(length);
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    :_ki2s_int_isr
* Returned Value   : none
*
*END*********************************************************************/
static void _ki2s_int_isr
   (
      pointer                  parameter
   )
{ /* Body */
   KI2S_INFO_STRUCT_PTR          io_info_ptr = parameter;
   I2S_MemMapPtr                 i2s_ptr = io_info_ptr->I2S_PTR;
   KI2S_BUFFER_PTR               buffer_l = &(io_info_ptr->BUFFER_L);
   KI2S_BUFFER_PTR               buffer_r = &(io_info_ptr->BUFFER_R);
   I2S_STATISTICS_STRUCT_PRV_PTR stats = &(io_info_ptr->STATS);
   KI2S_DUMMY_DATA_PTR           dummy = &(io_info_ptr->DUMMY);

   stats->INTERRUPTS++;

   if (io_info_ptr->IO_MODE == I2S_IO_READ)
   {
      /* One of receive FIFOs full */
      if ((i2s_ptr->ISR & I2S_ISR_RFF0_MASK) || (i2s_ptr->ISR & I2S_ISR_RFF1_MASK))
      {
         uint_8 i, data_n;
         /* Read value of Receive FIFO Counter0 */
         data_n = ((i2s_ptr->FCSR >> 12) & 0xF);
         /* calculate quantity of data to read */
         if (data_n > buffer_l->SPACE)
         {
            data_n = buffer_l->SPACE;
         }
         /* Copy data from left channel FIFO to left buffer */
         for (i = 0; i < data_n; i++)
         {
            buffer_l->DATA[buffer_l->IN] = i2s_ptr->RX0;
            (++buffer_l->IN >= buffer_l->SIZE) ? (buffer_l->IN = 0) : (0);
         }
         stats->RX_PACKETS += data_n;
         stats->PACKETS_QUEUED_L += data_n;
         buffer_l->SPACE -= data_n;
         
         /* Read value of Receive FIFO Counter1 */
         data_n = ((i2s_ptr->FCSR >> 28) & 0xF);
         
         if (data_n > buffer_r->SPACE)
         {
            data_n = buffer_r->SPACE;
         }
         /* Copy data from right channel FIFO to buffer */
         for (i = 0; i < data_n; i++)
         {      
            buffer_r->DATA[buffer_r->IN] = i2s_ptr->RX1;
            (++buffer_r->IN >= buffer_r->SIZE) ? (buffer_r->IN = 0) : (0);
         }
         stats->RX_PACKETS += data_n;
         stats->PACKETS_QUEUED_R += data_n;
         buffer_r->SPACE -= data_n;
      }

      /* Check receiver overrun error 0 */
      if ((i2s_ptr->IER & I2S_IER_ROE0EN_MASK) && (i2s_ptr->ISR & I2S_ISR_ROE0_MASK))
      {
         stats->OVERRUNS_L++;
         /* Clear error flag */
         i2s_ptr->ISR |= (I2S_ISR_ROE0_MASK);
      }

      /* Check receiver overrun error 1 */
      if ((i2s_ptr->IER & I2S_IER_ROE1EN_MASK) && (i2s_ptr->ISR & I2S_ISR_ROE1_MASK))
      {
         stats->OVERRUNS_R++;
         /* Clear error flag */
         i2s_ptr->ISR |= (I2S_ISR_ROE1_MASK);
      }
   }
   else
   {
      /* All data transmitted, disable transmitter */
      if ((stats->PACKETS_PROCESSED_L >= stats->PACKETS_REQUESTED_L) &&
          (stats->PACKETS_PROCESSED_R >= stats->PACKETS_REQUESTED_R) &&
          (i2s_ptr->ISR & I2S_ISR_TFE0_MASK) &&
          (i2s_ptr->ISR & I2S_ISR_TFE1_MASK))
      {
         i2s_ptr->CR &= ~(I2S_CR_TE_MASK);
         /* disable transmitter interrupts */
         i2s_ptr->IER &= ~(I2S_IER_TIE_MASK);
         io_info_ptr->ONTHEWAY = FALSE;
         io_info_ptr->FIRST_IO = TRUE;
      }

      /* Transmit FIFO empty - need more data */
      if ((i2s_ptr->ISR & I2S_ISR_TFE0_MASK) || (i2s_ptr->ISR & I2S_ISR_TFE1_MASK))
      {
         uint_8 i, space;
         /* Read value of Transmit FIFO Counter0 */
         space = FIFO_WATERMARK_MAX - ((i2s_ptr->FCSR >> I2S_CHAR_BIT) & 0xF);
         /* Copy data from buffer to left channel FIFO */
         for (i = 0; ((i < space) && (stats->PACKETS_PROCESSED_L < stats->PACKETS_QUEUED_L)); i++)
         {
            if (io_info_ptr->TX_DUMMY)
            {
               i2s_ptr->TX0 = (*(dummy->DATA + dummy->INDEX_L)) & 0xFFFFFFFF;
               (++dummy->INDEX_L >= dummy->LENGTH) ? (dummy->INDEX_L = 0) : (0);
            }
            else
            {
               i2s_ptr->TX0 = buffer_l->DATA[buffer_l->OUT];
               (++buffer_l->OUT >=  buffer_l->SIZE) ? (buffer_l->OUT = 0) : (0);
            }
            stats->PACKETS_PROCESSED_L++;
         }
         stats->TX_PACKETS += i;
         buffer_l->SPACE += i;

         /* Read value of Transmit FIFO Counter1 */
         space = FIFO_WATERMARK_MAX - ((i2s_ptr->FCSR >> (I2S_CHAR_BIT * 3)) & 0xF);

         /* Copy data from buffer to right channel FIFO */
         for (i = 0; ((i < space) && (stats->PACKETS_PROCESSED_R < stats->PACKETS_QUEUED_R)); i++)
         {
            if (io_info_ptr->TX_DUMMY)
            {
               i2s_ptr->TX1 = (*(dummy->DATA + dummy->INDEX_R)) & 0xFFFFFFFF;
               (++dummy->INDEX_R >= dummy->LENGTH) ? (dummy->INDEX_R = 0) : (0);
            }
            else
            {
               i2s_ptr->TX1 = buffer_r->DATA[buffer_r->OUT];
              (++buffer_r->OUT >=  buffer_r->SIZE) ? (buffer_r->OUT = 0) : (0); 
            }
            stats->PACKETS_PROCESSED_R++;
         }
         stats->TX_PACKETS += i;
         buffer_r->SPACE += i;
      }
      
      if (stats->PACKETS_PROCESSED_L >= stats->PACKETS_REQUESTED_L)
      {
          i2s_ptr->IER &= ~(I2S_IER_TFE0EN_MASK);
      }
      if (stats->PACKETS_PROCESSED_R >= stats->PACKETS_REQUESTED_R)
      {
          i2s_ptr->IER &= ~(I2S_IER_TFE1EN_MASK);
      }
      
      /* Check for transmit underrun error 0 */
      if ((i2s_ptr->IER & I2S_IER_TUE0EN_MASK) && (i2s_ptr->ISR & I2S_ISR_TUE0_MASK))
      {
         stats->UNDERRUNS_L++;
         /* Clear error flag */
         i2s_ptr->ISR |= (I2S_ISR_TUE0_MASK);
      }

      /* Check for transmit underrun error 1 */
      if ((i2s_ptr->IER & I2S_IER_TUE1EN_MASK) && (i2s_ptr->ISR & I2S_ISR_TUE1_MASK))
      {
         stats->UNDERRUNS_R++;
         /* Clear error flag */
         i2s_ptr->ISR |= (I2S_ISR_TUE1_MASK);
      }
   }
   if (_lwsem_post(&(io_info_ptr->EVENT_IO_FINISHED)) != MQX_OK)
   {
      #ifdef I2S_DEBUG
      printf("i2s_isr - Error: Unable to set EVENT_IO_FINISHED.\n");
      #endif
   }
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_int_ioctl
* Returned Value   : MQX error code.
* Comments         :
*    This function performs miscellaneous services for
*    the I2S I/O device.
*
*END*********************************************************************/

uint_32 _ki2s_int_ioctl
   (
      /* [IN] the address of the device specific information */
      KI2S_INFO_STRUCT_PTR io_info_ptr,

      /* [IN] The command to perform */
      uint_32                     cmd,

      /* [IN] Parameters for the command */
      pointer                 param_ptr
   )
{ /* Body */
   uint_32              result = MQX_OK;
   I2S_MemMapPtr        i2s_ptr = io_info_ptr->I2S_PTR;
   uint_8               watermark = 0;
   KI2S_DUMMY_DATA_PTR  dummy = &io_info_ptr->DUMMY;
   SIM_MemMapPtr        sim = SIM_BASE_PTR;

   switch(cmd)
   {
      case IO_IOCTL_I2S_SET_MODE_MASTER:
         if(io_info_ptr->ONTHEWAY)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_MODE_MASTER: Error - Cannot chnage I2S mode while I/O actions are in progress.\n");
            #endif
            result = I2S_ERROR_DEVICE_BUSY;
            break;
         }
         i2s_ptr->CR &= ~(I2S_CR_I2SEN_MASK);
         i2s_ptr->CR &= ~(I2S_CR_I2SMODE_MASK);
         i2s_ptr->CR |= (I2S_CR_I2SMODE(0x01)); /* Master mode */

         if (io_info_ptr->CLOCK_SOURCE == I2S_CLK_EXT)
         {
            i2s_ptr->CR &= ~(I2S_CR_SYSCLKEN_MASK); /* Internal master clock disable */
         }
         else if (io_info_ptr->CLOCK_SOURCE == I2S_CLK_INT)
         {
            i2s_ptr->CR |= (I2S_CR_SYSCLKEN_MASK); /* Master clock enable */
            io_info_ptr->MCLK_FREQ = _ki2s_get_mclk_value(io_info_ptr);
            io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_DIV;
            /* The word length is fixed to 32 in I2S master mode and DC is 1
            ** thus frame sync frequency is always BCLK_FREQ/64
            */
            io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / 64;
         }

         i2s_ptr->TCR |= (
            I2S_TCR_TXDIR_MASK | /* Transmit bit clock generated internally */
            I2S_TCR_TFDIR_MASK    /* Transmit frame sync generated internally */
            );
         i2s_ptr->CR |= (I2S_CR_I2SEN_MASK);
         io_info_ptr->MODE = I2S_MODE_MASTER;
         break;

      case IO_IOCTL_I2S_SET_MODE_SLAVE:
         if(io_info_ptr->ONTHEWAY)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_MODE_SLAVE: Error - Cannot chnage I2S mode while I/O actions are in progress.\n");
            #endif
            result = I2S_ERROR_DEVICE_BUSY;
            break;
         }
         i2s_ptr->CR &= ~(I2S_CR_I2SEN_MASK);
         i2s_ptr->CR &= ~(I2S_CR_I2SMODE_MASK);
         i2s_ptr->CR |= (I2S_CR_I2SMODE(0x02)); /* I2S Slave mode */
         i2s_ptr->CR &= ~(I2S_CR_SYSCLKEN_MASK);  /* Master clock disabled */
         i2s_ptr->TCR &= ~(
            I2S_TCR_TXDIR_MASK |  /* Transmit bit clock generated externally */
            I2S_TCR_TFDIR_MASK    /* Transmit frame sync generated externally */
            );
         i2s_ptr->CR |= (I2S_CR_I2SEN_MASK);
         io_info_ptr->MODE = I2S_MODE_SLAVE;
         break;

      case IO_IOCTL_I2S_SET_CLOCK_SOURCE_INT:
         if(io_info_ptr->ONTHEWAY)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_CLOCK_SOURCE_INT: Error - Cannot chnage I2S clock source while I/O actions are in progress.\n");
            #endif
            result = I2S_ERROR_DEVICE_BUSY;
            break;
         }
         /* You should not change clock source, when in slave mode */
         if (io_info_ptr->MODE == I2S_MODE_SLAVE)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_CLOCK_SOURCE_INT: Error - Cannot chnage I2S clock source while in slave mode.\n");
            #endif
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
         }

         i2s_ptr->CR &= ~(I2S_CR_I2SEN_MASK); /* disable SSI - see table at top of this file */
         i2s_ptr->CR |= (I2S_CR_SYSCLKEN_MASK); /* Internal master clock enable */
         i2s_ptr->CR |= (I2S_CR_I2SEN_MASK);

         if (io_info_ptr->CHANNEL == 0)
         {
        	 SIM_SOPT2 |= SIM_SOPT2_I2SSRC(0);
         }
         io_info_ptr->CLOCK_SOURCE = I2S_CLK_INT;
         io_info_ptr->MCLK_FREQ = _ki2s_get_mclk_value(io_info_ptr);
         io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_DIV;
         io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * io_info_ptr->IO_FORMAT.CHANNELS);
         break;

      case IO_IOCTL_I2S_SET_CLOCK_SOURCE_EXT:
         if(io_info_ptr->ONTHEWAY)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_CLOCK_SOURCE_EXT: Error - Cannot chnage I2S clock source while I/O actions are in progress.\n");
            #endif
            result = I2S_ERROR_DEVICE_BUSY;
            break;
         }
         if (io_info_ptr->MODE == I2S_MODE_SLAVE)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_CLOCK_SOURCE_EXT: Error - Cannot change I2S clock source while in slave mode.\n");
            #endif
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
         }
         /*enable pin to receive external CLK signal*/
         i2s_ptr->CR &= ~(I2S_CR_I2SEN_MASK); /* disable I2S - see table at top of this file */
         i2s_ptr->CR &= ~(I2S_CR_SYSCLKEN_MASK); /* Internal master clock disable */
         i2s_ptr->CR |= (I2S_CR_I2SEN_MASK);

         if (io_info_ptr->CHANNEL == 0)
         {
        	 SIM_SOPT2 |= SIM_SOPT2_I2SSRC(3); //I2S0 clock source = I2S_CLKIN pin
         }
         io_info_ptr->CLOCK_SOURCE = I2S_CLK_EXT;
         break;

      case IO_IOCTL_I2S_SET_DATA_BITS:
         if(io_info_ptr->ONTHEWAY)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_DATA_BITS: Error - Cannot chnage I2S data bit length while I/O actions are in progress.\n");
            #endif
            result = I2S_ERROR_DEVICE_BUSY;
            break;
         }
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
         }
         else
         {
            uint_8 data_bits =  *((uint_8_ptr) param_ptr);
            if ((data_bits < 8) || (data_bits > 24) || (data_bits == 14) || (data_bits % 2))
            {
               #ifdef I2S_DEBUG
                printf("_i2s_ioctl - IO_IOCTL_I2S_SET_DATA_BITS: Error - Unsupported data word length.\n");
               #endif
               result = I2S_ERROR_WORD_LENGTH_UNSUPPORTED;
               break;
            }
            data_bits = (data_bits/2) - 1;
            i2s_ptr->CR &= ~(I2S_CR_I2SEN_MASK);
            i2s_ptr->TCCR &= ~(I2S_TCCR_WL_MASK);
            i2s_ptr->TCCR |= (I2S_TCCR_WL((uint_32) data_bits));
            i2s_ptr->RCCR &= ~(I2S_RCCR_WL_MASK);
            i2s_ptr->RCCR |= (I2S_RCCR_WL((uint_32) data_bits));
            i2s_ptr->CR |= (I2S_CR_I2SEN_MASK);
            io_info_ptr->DATA_BITS = *((uint_8_ptr) param_ptr);
            io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * io_info_ptr->IO_FORMAT.CHANNELS);
         }
         break;

      case IO_IOCTL_I2S_DISABLE_DEVICE:
         i2s_ptr->IER &= ~(
              I2S_IER_TUE0EN_MASK | /* Transmit underrun error 0*/
              I2S_IER_TFE0EN_MASK | /* Transmit FIFO0 empty */
              I2S_IER_ROE0EN_MASK | /* Receive overrun error 0*/
              I2S_IER_RFF0EN_MASK | /* Receive FIFO0 full */
              I2S_IER_TUE1EN_MASK | /* Transmit underrun error 1*/
              I2S_IER_TFE1EN_MASK | /* Transmit FIFO1 empty */
              I2S_IER_ROE1EN_MASK | /* Receive overrun error 1*/
              I2S_IER_RFF1EN_MASK | /* Receive FIFO1 full */
              I2S_IER_TIE_MASK    | /* Transmit interrupts disable */
              I2S_IER_RIE_MASK      /* Receive interrupts disable */
              );
         i2s_ptr->CR &= ~(I2S_CR_I2SEN_MASK); /*I2S disable*/
         break;

      case IO_IOCTL_I2S_ENABLE_DEVICE:
         i2s_ptr->IER |= (
                          I2S_IER_TIE_MASK | /* Transmit interrupts enable */
                          I2S_IER_RIE_MASK   /* Receive interrupts enable */
                          );
         i2s_ptr->CR |= (I2S_CR_I2SEN_MASK); /*I2S enable*/
         break;

      case IO_IOCTL_I2S_SET_MCLK_FREQ:
         if (io_info_ptr->ONTHEWAY)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_MCLK_FREQ: Error - Cannot chnage I2S master clock frequency while I/O actions are in progress.\n");
            #endif
            result = I2S_ERROR_DEVICE_BUSY;
            break;
         }
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         _ki2s_set_mclk_value(io_info_ptr, *((uint_32_ptr) param_ptr));
         break;

      case IO_IOCTL_I2S_SET_FS_FREQ:
         if(io_info_ptr->ONTHEWAY)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_FS_FREQ: Error - Cannot chnage I2S sampling frequency while I/O actions are in progress.\n");
            #endif
            result = I2S_ERROR_DEVICE_BUSY;
            break;
         }
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         _ki2s_set_fs_value(io_info_ptr, *((uint_32_ptr) param_ptr));
         break;

      case IO_IOCTL_AUDIO_SET_IO_DATA_FORMAT:
         if(io_info_ptr->ONTHEWAY)
         {
            #ifdef I2S_DEBUG
             printf("_i2s_ioctl - IO_IOCTL_I2S_SET_IO_DATA_FORMAT: Error - Cannot change I/O data format while I/O actions are in progress.\n");
            #endif
            result = I2S_ERROR_DEVICE_BUSY;
            break;
         }
         if (param_ptr == NULL)
         {
            result = I2S_ERROR_INVALID_PARAMETER;
            break;
         }
         else
         {
            uint_8 aligment, endianity, bits, channels, size;
            endianity = ((AUDIO_DATA_FORMAT_PTR) param_ptr)->ENDIAN;
            bits = ((AUDIO_DATA_FORMAT_PTR) param_ptr)->BITS;
            aligment = ((AUDIO_DATA_FORMAT_PTR) param_ptr)->ALIGNMENT;
            channels = ((AUDIO_DATA_FORMAT_PTR) param_ptr)->CHANNELS;
            size = ((AUDIO_DATA_FORMAT_PTR) param_ptr)->SIZE;
            if ((aligment > AUDIO_ALIGNMENT_LEFT) || (bits < AUDIO_BIT_SIZE_MIN) ||
               (bits > AUDIO_BIT_SIZE_MAX) || (endianity > AUDIO_LITTLE_ENDIAN) ||
               (channels > 2) || (channels == 0))
            {
               #ifdef I2S_DEBUG
                printf("_i2s_ioctl - IO_IOCTL_I2S_SET_IO_DATA_FORMAT: Error - Invalid I/O data format.\n");
               #endif
               result = AUDIO_ERROR_INVALID_IO_FORMAT;
               break;
            }
            io_info_ptr->IO_FORMAT.ENDIAN = endianity;
            io_info_ptr->IO_FORMAT.BITS = bits;
            io_info_ptr->IO_FORMAT.ALIGNMENT = aligment;
            io_info_ptr->IO_FORMAT.CHANNELS = channels;
            io_info_ptr->IO_FORMAT.SIZE = size;
          
            /* If only one channel is going to be used disable FIFO1 and its interrupts */
            if (channels == 1)
            {
                io_info_ptr->TX_INT_MASK = (I2S_IER_TFE0EN_MASK);
                io_info_ptr->RX_INT_MASK = (I2S_IER_RFF0EN_MASK);
                i2s_ptr->RCR &= ~(I2S_RCR_RFEN1_MASK);
                i2s_ptr->TCR &= ~(I2S_TCR_TFEN1_MASK);
            }
            else
            {
                io_info_ptr->TX_INT_MASK = (I2S_IER_TFE0EN_MASK | I2S_IER_TFE1EN_MASK);
                io_info_ptr->RX_INT_MASK = (I2S_IER_RFF0EN_MASK | I2S_IER_RFF1EN_MASK);
                i2s_ptr->RCR |= (I2S_RCR_RFEN1_MASK);
                i2s_ptr->TCR |= (I2S_TCR_TFEN1_MASK);
            }
         }
         break;

      case IO_IOCTL_I2S_SET_TXFIFO_WATERMARK:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         watermark = *((uint_8_ptr) param_ptr);
         if (watermark > FIFO_WATERMARK_MAX)
         {
            result = I2S_ERROR_PARAM_OUT_OF_RANGE;
            break;
         }
         i2s_ptr->FCSR &= ~(
            I2S_FCSR_TFWM0_MASK |
            I2S_FCSR_TFWM1_MASK
            );
         i2s_ptr->FCSR |= (
            I2S_FCSR_TFWM0(watermark) | /* Set transmit FIFO0 watermark */
            I2S_FCSR_TFWM1(watermark)  /* Set transmit FIFO1 watermark */
         );
         break;

      case IO_IOCTL_I2S_SET_RXFIFO_WATERMARK:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         watermark = *((uint_8_ptr) param_ptr);
         if (watermark > FIFO_WATERMARK_MAX)
         {
            result = I2S_ERROR_PARAM_OUT_OF_RANGE;
            break;
         }
         i2s_ptr->FCSR &= ~(
            I2S_FCSR_RFWM0_MASK |
            I2S_FCSR_RFWM1_MASK
            );
         i2s_ptr->FCSR |= (
            I2S_FCSR_RFWM0(watermark) | /* Set receive FIFO0 watermark */
            I2S_FCSR_RFWM1(watermark)   /* Set reveive FIFO1 watermark */
            );
         break;

      case IO_IOCTL_I2S_TX_DUMMY_ON:
         if (io_info_ptr->TX_DUMMY == FALSE)
         {
            io_info_ptr->TX_DUMMY = TRUE;
            dummy->LENGTH = _ki2s_sine_wave(io_info_ptr->FS_FREQ, 440, &(dummy->DATA));
            dummy->INDEX_L = 0;
            dummy->INDEX_R = 0;
         }
         break;

      case IO_IOCTL_I2S_TX_DUMMY_OFF:
         if (io_info_ptr->TX_DUMMY == TRUE)
         {
            io_info_ptr->TX_DUMMY = FALSE;
            result = _mem_free(dummy->DATA);
            if (result == MQX_OK)
            {
               dummy->LENGTH = 0;
               dummy->DATA = NULL;
            }
         dummy->INDEX_L = 0;
         dummy->INDEX_R = 0;
         }
         break;

      case IO_IOCTL_I2S_GET_MODE:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         *((uint_8_ptr) param_ptr) = io_info_ptr->MODE;
         break;

      case IO_IOCTL_I2S_GET_CLOCK_SOURCE:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         *((uint_8_ptr) param_ptr) = io_info_ptr->CLOCK_SOURCE;
          break;

      case IO_IOCTL_I2S_GET_DATA_BITS:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         *((uint_8_ptr) param_ptr) = io_info_ptr->DATA_BITS;
         break;

      case IO_IOCTL_I2S_GET_MCLK_FREQ:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         *((uint_32_ptr) param_ptr) = io_info_ptr->MCLK_FREQ;
         break;

      case IO_IOCTL_I2S_GET_BCLK_FREQ:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         *((uint_32_ptr) param_ptr) = io_info_ptr->BCLK_FREQ;
         break;

      case IO_IOCTL_I2S_GET_TX_DUMMY:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         *((boolean*) param_ptr) = io_info_ptr->TX_DUMMY;
         break;

      case IO_IOCTL_I2S_GET_FS_FREQ:
         if (param_ptr == NULL)
         {
              result = I2S_ERROR_INVALID_PARAMETER;
              break;
         }
         *((uint_32_ptr) param_ptr) = io_info_ptr->FS_FREQ;
         break;

      case IO_IOCTL_I2S_GET_STATISTICS:
         if (param_ptr == NULL)
         {
            result = I2S_ERROR_INVALID_PARAMETER;
            break;
         }
         else
         {
             I2S_STATISTICS_STRUCT_PTR stats_out = (I2S_STATISTICS_STRUCT_PTR) param_ptr;
             I2S_STATISTICS_STRUCT_PRV_PTR stats_in = &(io_info_ptr->STATS);
             
             stats_out->INTERRUPTS = stats_in->INTERRUPTS;
             stats_out->FIFO_ERROR = stats_in->UNDERRUNS_L + stats_in->UNDERRUNS_R + stats_in->OVERRUNS_L +stats_in->OVERRUNS_R;
             stats_out->BUFFER_ERROR = 0;
             stats_out->RX_PACKETS = stats_in->RX_PACKETS;
             stats_out->TX_PACKETS = stats_in->TX_PACKETS;
             stats_out->PACKETS_PROCESSED = stats_in->PACKETS_PROCESSED_L + stats_in->PACKETS_PROCESSED_R;
             stats_out->PACKETS_QUEUED = stats_in->PACKETS_QUEUED_L + stats_in->PACKETS_QUEUED_R;
             stats_out->PACKETS_REQUESTED = stats_in->PACKETS_REQUESTED_L + stats_in->PACKETS_REQUESTED_R;
         }
         break;

      case IO_IOCTL_AUDIO_GET_IO_DATA_FORMAT:
         if (param_ptr == NULL)
         {
            result = I2S_ERROR_INVALID_PARAMETER;
            break;
         }
         ((AUDIO_DATA_FORMAT_PTR) param_ptr)->ENDIAN = io_info_ptr->IO_FORMAT.ENDIAN;
         ((AUDIO_DATA_FORMAT_PTR) param_ptr)->BITS = io_info_ptr->IO_FORMAT.BITS;
         ((AUDIO_DATA_FORMAT_PTR) param_ptr)->ALIGNMENT = io_info_ptr->IO_FORMAT.ALIGNMENT;
         ((AUDIO_DATA_FORMAT_PTR) param_ptr)->CHANNELS = io_info_ptr->IO_FORMAT.CHANNELS;
         break;

      case IO_IOCTL_I2S_GET_TXFIFO_WATERMARK:
         if (param_ptr == NULL)
         {
            result = I2S_ERROR_INVALID_PARAMETER;
            break;
         }
         *((uint_8_ptr) param_ptr) = i2s_ptr->FCSR & I2S_FCSR_TFWM0_MASK;
         break;

      case IO_IOCTL_I2S_GET_RXFIFO_WATERMARK:
         if (param_ptr == NULL)
         {
            result = I2S_ERROR_INVALID_PARAMETER;
            break;
         }
         *((uint_8_ptr) param_ptr) = (i2s_ptr->FCSR & I2S_FCSR_RFWM0_MASK) >> 8;
         break;

      case IO_IOCTL_I2S_SET_CLK_ALWAYS_ENABLED_ON:
         i2s_ptr->CR &= ~(I2S_CR_RFRCLKDIS_MASK); /* Enable receiving clocks after receiver is disabled */
         i2s_ptr->CR &= ~(I2S_CR_TFRCLKDIS_MASK); /* Enable transmitting clocks after transmitter is disabled */
         io_info_ptr->CLK_ALWAYS_ON = TRUE;
         break;

      case IO_IOCTL_I2S_SET_CLK_ALWAYS_ENABLED_OFF:
         i2s_ptr->CR |= (I2S_CR_RFRCLKDIS_MASK); /* Disable receiving clocks after receiver is disabled */
         i2s_ptr->CR |= (I2S_CR_TFRCLKDIS_MASK); /* Disable transmitting clocks after transmitter is disabled */
         io_info_ptr->CLK_ALWAYS_ON = FALSE;
         break;

      case IO_IOCTL_I2S_GET_CLK_ALWAYS_ENABLED:
         if (param_ptr == NULL)
         {
            result = I2S_ERROR_INVALID_PARAMETER;
            break;
         }
         *((boolean*) param_ptr) = io_info_ptr->CLK_ALWAYS_ON;
         break;

      case IO_IOCTL_I2S_CLEAR_STATISTICS:
         _mem_zero(&(io_info_ptr->STATS), sizeof(io_info_ptr->STATS));
         break;
         
      case IO_IOCTL_FLUSH_OUTPUT:
          while (io_info_ptr->ONTHEWAY)
          {
              uint_32 time = 0;
              time = ((io_info_ptr->BUFFER_L.SIZE - io_info_ptr->BUFFER_L.SPACE) +
                      (io_info_ptr->BUFFER_R.SIZE - io_info_ptr->BUFFER_R.SPACE)) *
                      (1000 / io_info_ptr->FS_FREQ) + 1;
              _time_delay(time);
          }
          break;
      
      default:
         result = IO_ERROR_INVALID_IOCTL_CMD;
         break;
   }
   return result;
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_format_in_data
* Returned Value   : formatted input data
* Comments         : Function performs I2S input data formatting
*
*END*********************************************************************/
static uint_32 _ki2s_format_in_data
   (
    /* [IN] data to format */
    char_ptr input,

    /* [IN] Requested format */
    AUDIO_DATA_FORMAT_PTR format
    )
{/* Body */
   uint_32 retval = 0;
   uint_8 i;
   
   if (format->ENDIAN == AUDIO_BIG_ENDIAN)
   {
      for (i = 0; i < format->SIZE; i++)
      {
          retval |= ((((uint_32) *(input + i)) << (format->SIZE - 1 - i) * 8) & (0xFF) << (format->SIZE - 1 - i) * 8);
      }
      if ((format->ALIGNMENT == AUDIO_ALIGNMENT_RIGHT) && (format->BITS < (format->SIZE * 8)))
      {
         retval >>= (format->SIZE * I2S_CHAR_BIT) - format->BITS;
      }
   }
   else
   {
      for (i = 0; i < format->SIZE; i++)
      {
          retval |= ((uint_32) *(input + i) << i * 8);
      }
   }
   return(~retval);
}/* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_format_out_data
* Returned Value   : none
* Comments         : Function performs I2S output data formatting
*
*END*********************************************************************/
static void _ki2s_format_out_data
   (
    /* [IN] data to format */
    uint_32 input,

    /* [OUT] location for output */
    char_ptr output,

    /* [IN] Requested output data format */
    AUDIO_DATA_FORMAT_PTR format
    )
{
   uint_8 i;
   input = ~input;
   
   if (format->ENDIAN == AUDIO_BIG_ENDIAN)
   {
     for(i = 0; i < format->SIZE; i++)
     {
       output[i] = (input >> I2S_CHAR_BIT * (format->SIZE - i - 1) & 0xFF);
     }
     if ((format->ALIGNMENT == AUDIO_ALIGNMENT_LEFT) && (format->BITS < (format->SIZE * 8)))
     {
       input <<= (format->SIZE * I2S_CHAR_BIT) - format->BITS;
     }
   }
   else
   {
     for(i = 0; i < format->SIZE; i++)
     {
       output[i] = (char) (input  >> (i * I2S_CHAR_BIT)); 
     }
   }

   return;
}

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_sine_wave
* Returned Value   : samples number if successful, 0 otherwise
* Comments         :
*    This function generate a sine wave.
*
*END*********************************************************************/

uint_32 _ki2s_sine_wave(uint_32 fs, uint_32 freq, int_16_ptr* output)
{
    uint_32 samples, i;
    boolean over180 = 0;
    ieee_single period, step, angle = 0.0;
    period = 1 / (ieee_single) freq;
    samples = fs * (uint_32)period;
    if (samples == 0)
    {
      return(0);
    }
    *output = (int_16_ptr) _mem_alloc(sizeof(int_16) * samples);
    if (*output == NULL)
    {
       return(0);
    }
    step = 360.0 / (ieee_single) samples;
    for(i = 0; i < samples; i++)
    {
        if (angle > 180)
        {
            angle = angle - 180;
            over180 = TRUE;
        }
        *((*output) + i) =  BIT16_MAX * (4*(uint_32)angle*(180 - (uint_32)angle))/(40500 - (uint_32)angle * (180 - (uint_32)angle));
        if (over180)
        {
           *((*output) + i) = -(*((*output) + i));
        }
        angle += step;
    }
    return(samples);
}


/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_hw_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an I2S hardware control registers.
*
*END*********************************************************************/

static _mqx_int _ki2s_hw_init
(
   KI2S_INIT_STRUCT_PTR i2s_init_ptr,
   I2S_MemMapPtr i2s_ptr
)
{
   /* variables */
   uint_8 data_bits = i2s_init_ptr->DATA_BITS;
   uint_8 i2s_mode = i2s_init_ptr->MODE;
   uint_8 clk_source = i2s_init_ptr->CLOCK_SOURCE;
   uint_8 channel = i2s_init_ptr->CHANNEL;
   uint_8 channels = i2s_init_ptr->IO_FORMAT->CHANNELS;
   boolean tx_empty = i2s_init_ptr->TX_DUMMY;
   SIM_MemMapPtr   sim = SIM_BASE_PTR;

   data_bits = (data_bits/2) - 1;
   i2s_ptr->CR &= ~(I2S_CR_I2SEN_MASK); /* I2S disable */
   i2s_ptr->CR |= (
      I2S_CR_SYN_MASK   |    /* Set synchronous mode */
      I2S_CR_TCHEN_MASK      /* Turn dual channel mode ON */
      );
   i2s_ptr->TCR &= ~(I2S_TCR_TSHFD_MASK); /* Data transmitted MSB first */
   i2s_ptr->RCR &= ~(I2S_RCR_RSHFD_MASK); /* Data received MSB first */
   i2s_ptr->TCR |= (
      I2S_TCR_TSCKP_MASK | /* Data clocked out on falling edge of bit clock */
      I2S_TCR_TFSI_MASK  | /* Transmit frame sync is active low */
      I2S_TCR_TEFS_MASK  | /* Transmit frame sync is initiated one bit before the data transmits */
      I2S_TCR_TFEN0_MASK | /* Transmit FIFO0 enable */
      I2S_TCR_TFEN1_MASK   /* Transmit FIFO1 enable */
      );
   i2s_ptr->FCSR &= ~(
      I2S_FCSR_TFWM0_MASK |
      I2S_FCSR_TFWM1_MASK | 
      I2S_FCSR_RFWM0_MASK |
      I2S_FCSR_RFWM1_MASK 
      );
   i2s_ptr->FCSR |= (
      I2S_FCSR_TFWM0(0xA) | /* Set transmit FIFO0 watermark to 10 */
      I2S_FCSR_TFWM1(0xA) | /* Set transmit FIFO1 watermark to 10 */
      I2S_FCSR_RFWM0(0x3) | /* Set receive FIFO0 watermark to 3   */
      I2S_FCSR_RFWM1(0x3)   /* Set receive FIFO1 watermark to 3   */
      );
   i2s_ptr->RCR |= (
      I2S_RCR_RSCKP_MASK | /* Data latched on rising edge of bit clock */
      I2S_RCR_RFSI_MASK  | /* Receive frame sync is active low */
      I2S_RCR_REFS_MASK  | /* Receive frame sync is initiated one bit before the data is received */
      I2S_RCR_RFEN0_MASK | /* Receive FIFO0 enable */
      I2S_RCR_RFEN1_MASK   /* Receive FIFO1 enable */
      );
   /* Interrupts setup */
   /* If only one channel is going to be used disable FIFO1 and its interrupts */
   if (channels == 1)
   {
       i2s_ptr->RCR &= ~(I2S_RCR_RFEN1_MASK);
       i2s_ptr->TCR &= ~(I2S_TCR_TFEN1_MASK);
       i2s_ptr->IER |= (
          I2S_IER_ROE0EN_MASK | /* Receive overrun error 0 */
          I2S_IER_RFF0EN_MASK | /* Receive FIFO1 full */
          I2S_IER_TUE0EN_MASK | /* Transmit underrun error 0 */
          I2S_IER_TFE0EN_MASK   /* Transmit FIFO0 empty */
          );
   }
   else
   {
       i2s_ptr->IER |= (
          I2S_IER_TUE0EN_MASK | /* Transmit underrun error 0*/
          I2S_IER_TFE0EN_MASK | /* Transmit FIFO0 empty */
          I2S_IER_ROE0EN_MASK | /* Receive overrun error 0*/
          I2S_IER_RFF0EN_MASK | /* Receive FIFO0 full */
          I2S_IER_TUE1EN_MASK | /* Transmit underrun error 1*/
          I2S_IER_TFE1EN_MASK | /* Transmit FIFO1 empty */
          I2S_IER_ROE1EN_MASK | /* Receive overrun error 1*/
          I2S_IER_RFF1EN_MASK   /* Receive FIFO1 full */
          );
   }
   
   i2s_ptr->IER &= ~(
      I2S_IER_RDR0EN_MASK | /* Receiver data ready 0 */
      I2S_IER_RDR1EN_MASK | /* Receiver data ready 1 */
      I2S_IER_TDE0EN_MASK | /* Transmit data empty 0 */
      I2S_IER_TDE1EN_MASK | /* Transmit data empty 1 */
      I2S_IER_RIE_MASK    | /* Receiver disable interrupts */
      I2S_IER_TIE_MASK      /* Transmitter disable interrupts */
      );
   
   /* clock source specific */
   switch (clk_source)
   {
      case I2S_CLK_INT:
         if (channel == 0)
         {
             /* At first Disable system clock to the I2S module */
             sim->SCGC6 &= ~(SIM_SCGC6_I2S_MASK);
             /* I2S clock source is system clock */
             sim->SOPT2 &= ~(SIM_SOPT2_I2SSRC_MASK);
             sim->SOPT2 |= SIM_SOPT2_I2SSRC(0);
             /* Divide to get the 12.2880 MHz from 96MHz (96* (16/125)) */
             sim->CLKDIV2 &= ~(SIM_CLKDIV2_I2SDIV_MASK | SIM_CLKDIV2_I2SFRAC_MASK);
             sim->CLKDIV2 |= SIM_CLKDIV2_I2SDIV(124) | SIM_CLKDIV2_I2SFRAC(15);
             sim->SCGC6 |= SIM_SCGC6_I2S_MASK;
         }
         break;
      case I2S_CLK_EXT:
         if (channel == 0)
         {
            /* At first Disable system clock to the I2S module */
            sim->SCGC6 &= ~(SIM_SCGC6_I2S_MASK);
            sim->SOPT2 &= ~(SIM_SOPT2_I2SSRC_MASK);
            sim->SOPT2 |= SIM_SOPT2_I2SSRC(3);
            /* Divide to get the 12.2880 MHz from 96MHz (96* (16/125)) */
            sim->CLKDIV2 &= ~(SIM_CLKDIV2_I2SDIV_MASK | SIM_CLKDIV2_I2SFRAC_MASK);
            sim->CLKDIV2 |= SIM_CLKDIV2_I2SDIV(124) | SIM_CLKDIV2_I2SFRAC(15);
            sim->SCGC6 |= SIM_SCGC6_I2S_MASK;
         }
         break;
      default:
         break;
   }
   /* mode specific */
   switch(i2s_mode)
   {
      case I2S_MODE_MASTER:
         i2s_ptr->CR &= ~(I2S_CR_I2SMODE_MASK);
         i2s_ptr->CR |= (I2S_CR_I2SMODE(0x01));
         if (clk_source == I2S_CLK_EXT)
         {
            i2s_ptr->CR &= ~(I2S_CR_SYSCLKEN_MASK); /* Master clock disable */
         }
         else
         {
            i2s_ptr->CR |= (I2S_CR_SYSCLKEN_MASK);  /* Master clock enable */
         }
         i2s_ptr->TCR |= (
            I2S_TCR_TXDIR_MASK | /* Transmit bit clock generated internally */
            I2S_TCR_TFDIR_MASK   /* Transmit frame sync generated internally */
            );
         break;
      case I2S_MODE_SLAVE:
         i2s_ptr->CR &= ~(I2S_CR_I2SMODE_MASK);
         i2s_ptr->CR |= (I2S_CR_I2SMODE(0x02));
         i2s_ptr->CR &= ~(I2S_CR_SYSCLKEN_MASK); /* Master clock disabled */
         i2s_ptr->TCR &= ~(
            I2S_TCR_TXDIR_MASK | /* Transmit bit clock generated externally */
            I2S_TCR_TFDIR_MASK   /* Transmit frame sync generated externally */
            );
         break;
      default:
         break;
   }

   /* Set word length (valid data bits) */
   i2s_ptr->TCCR = (I2S_TCCR_WL((uint_32) data_bits));
   /* set frame rate 48 kHz*/
   i2s_ptr->TCCR &= ~(I2S_TCCR_DC_MASK);
   i2s_ptr->TCCR |= (I2S_TCCR_DC(0x01));
   i2s_ptr->TCCR &= ~(I2S_TCCR_PM_MASK);
   i2s_ptr->TCCR |= (I2S_TCCR_PM(0x80));
   /* Set word length (valid data bits) */
   i2s_ptr->RCCR = (I2S_RCCR_WL((uint_32) data_bits));
   i2s_ptr->RCCR &= ~(I2S_RCCR_DC_MASK);
   i2s_ptr->RCCR |= (I2S_RCCR_DC(0x01));
   i2s_ptr->RCCR &= ~(I2S_RCCR_PM_MASK);
   i2s_ptr->RCCR |= (I2S_RCCR_PM(0x80));

   /* Enable receiving clocks after receiver is disabled */
   i2s_ptr->CR &= ~(I2S_CR_RFRCLKDIS_MASK);
   /* Enable transmitting clocks after transmitter is disabled */
   i2s_ptr->CR &= ~(I2S_CR_TFRCLKDIS_MASK);
   /* I2S enable */
   i2s_ptr->CR |= (I2S_CR_I2SEN_MASK);

   return (MQX_OK);
}

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_get_mclk_value
* Returned Value   : Master clock frequency
* Comments         :
*    This function computes master clock value.
*
*END*********************************************************************/

static uint_32 _ki2s_get_mclk_value
(
   KI2S_INFO_STRUCT_PTR io_info_ptr
)
{
    SIM_MemMapPtr   sim = SIM_BASE_PTR;
    uint_32 fract = 0;
    uint_32 div = 0;
    fract = (sim->CLKDIV2 & SIM_CLKDIV2_I2SFRAC_MASK) >> SIM_CLKDIV2_I2SFRAC_SHIFT;
    div = (sim->CLKDIV2 & SIM_CLKDIV2_I2SDIV_MASK) >> SIM_CLKDIV2_I2SDIV_SHIFT;
    return ((BSP_SYSTEM_CLOCK / (div + 1)) * (fract + 1));
}

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_set_mclk_value
* Returned Value   : MQX_OK if everything is OK, error macro value in case 
*                    of error.
* Comments         :
*    This function sets up master clock (called from ioctl)
*
*END*********************************************************************/
_mqx_int _ki2s_set_mclk_value
(
    KI2S_INFO_STRUCT_PTR io_info_ptr,
    uint_32 frequency
)
{
    uint_8 divider;
    boolean found;
    _mqx_int result = MQX_OK;
    SIM_MemMapPtr sim = SIM_BASE_PTR;
    
    if (io_info_ptr->CLOCK_SOURCE == I2S_CLK_INT)
    {
        uint_32 fract, temp_fract, divide, temp_div, closest_mclk, iter_mclk;
        found = FALSE;
        closest_mclk = 0;
        iter_mclk = 0;
        divider =(uint_8) (BSP_SYSTEM_CLOCK / frequency);
        
        if ((divider < SSIDIV_MIN) || (divider > SSIDIV_MAX))
        {
            #ifdef I2S_DEBUG
            printf("_i2s_ioctl - IO_IOCTL_I2S_SET_MCLK_FREQ: Error - System clock divider value out of range.\n");
            #endif
            result = I2S_ERROR_DIVIDER_VALUE_INVALID;
            return (result);
        }
        for (fract = 1; fract < 256; fract++)
        {
            for(divide = 1; divide < 4096; divide++)
            {
                iter_mclk = (BSP_SYSTEM_CLOCK / divide) * fract;
                if (iter_mclk < frequency) break;
                if ((iter_mclk - frequency) == 0)
                {
                    found = TRUE;
                    break;
                }              
                else if ((closest_mclk == 0) || ((iter_mclk % frequency) < (closest_mclk % frequency)))
                {
                    temp_fract = fract;
                    temp_div = divide;
                    closest_mclk = iter_mclk;
                }
            }
            if (found) break;
        }
        if (found == FALSE)
        {
            frequency = closest_mclk;
            fract = temp_fract;
            divide = temp_div;
        }
        if (io_info_ptr->CHANNEL == 0)
        {
            sim->SCGC6 &= ~(SIM_SCGC6_I2S_MASK);
            sim->CLKDIV2 &= ~SIM_CLKDIV2_I2SDIV_MASK;
            sim->CLKDIV2 &= ~SIM_CLKDIV2_I2SFRAC_MASK;
            sim->CLKDIV2 |= SIM_CLKDIV2_I2SDIV(divide-1) | SIM_CLKDIV2_I2SFRAC(fract-1);
            sim->SCGC6 |= SIM_SCGC6_I2S_MASK;
        }
        io_info_ptr->MCLK_FREQ = frequency;
        io_info_ptr->MCLK_DIV = divider;
    }
    else
    {
        io_info_ptr->MCLK_FREQ = frequency;
    }
    if (io_info_ptr->MODE == I2S_MODE_MASTER)
    {
        io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / 64;
    }
    else
    {
        io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * io_info_ptr->IO_FORMAT.CHANNELS);
    }
    io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_DIV;
    return(MQX_OK);
}

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_set_fs_value
* Returned Value   : MQX_OK if everything is OK, error macro value in case 
*                    of error.
* Comments         :
*    This function sets up frame sync (sampling) frequency (called from ioctl)
*
*END*********************************************************************/
_mqx_int _ki2s_set_fs_value
(
    KI2S_INFO_STRUCT_PTR io_info_ptr,
    uint_32 frequency
)
{
    uint_32 bclk_frequency;
    uint_16 divider;
    _mqx_int result = MQX_OK;
    I2S_MemMapPtr i2s_ptr;
    
    i2s_ptr = io_info_ptr->I2S_PTR;
    if (io_info_ptr->MODE == I2S_MODE_SLAVE)
    {
        bclk_frequency = frequency * io_info_ptr->DATA_BITS * 2;
        if ((bclk_frequency > (io_info_ptr->MCLK_FREQ / 2)) || (bclk_frequency > (BSP_BUS_CLOCK / 5)))
        {
            #ifdef I2S_DEBUG
            printf("_i2s_ioctl - IO_IOCTL_I2S_SET_FS_FREQ: Error - BCLK_FREQ > MCLK_FREQ/2 or BCLK_FREQ > BUS_CLOCK/5.\n");
            #endif
            result = I2S_ERROR_FREQUENCY_INVALID;
            return(result);
        }
        io_info_ptr->BCLK_FREQ = bclk_frequency;
        io_info_ptr->FS_FREQ = frequency;
        return(result);
    }

    bclk_frequency = frequency * 64;
    divider = io_info_ptr->MCLK_FREQ / (bclk_frequency * 2);
    /*
    ** valid divider values are:
    ** 1-256 in step of 1
    ** 257-512 in step of 2
    ** 513-2048 in step of 8
    ** 2049-4096 in step of 16
    */
    if ((divider < BCLK_DIV_MIN) || (divider > BCLK_DIV_MAX)   ||
        (divider > 256) && (divider < 513) && (divider % 2)    ||
        (divider > 512) && (divider < 2049) && (divider % 8)   ||
        (divider > 2048) && (divider < BCLK_DIV_MAX+1) && (divider % 16))
    {
        #ifdef I2S_DEBUG
         printf("_i2s_ioctl - IO_IOCTL_I2S_SET_FS_FREQ: Error - Invalid BCLK divider value.\n");
        #endif
        result = I2S_ERROR_DIVIDER_VALUE_INVALID;
        return(result);
    }
    else
    {
        if (divider < 257)
        {
            /* According to reference manual values of DIV2, PSR and PM must
            ** not be changed simultaneously */
            i2s_ptr->TCCR &= ~(I2S_TCCR_PM_MASK);
            i2s_ptr->TCCR |= (I2S_TCCR_PM(divider - 1));
            i2s_ptr->TCCR &= ~(I2S_TCCR_PSR_MASK);
            i2s_ptr->TCCR &= ~(I2S_TCCR_DIV2_MASK);
            /* Set receiver clock */
            i2s_ptr->RCCR &= ~(I2S_RCCR_PM_MASK);
            i2s_ptr->RCCR |= (I2S_RCCR_PM(divider - 1));
            i2s_ptr->RCCR &= ~(I2S_RCCR_PSR_MASK);
            i2s_ptr->RCCR &= ~(I2S_RCCR_DIV2_MASK);
        }
        else if ((divider > 256) && (divider < 513))
        {
            divider = divider/2;
            i2s_ptr->TCCR &= ~(I2S_TCCR_PM_MASK);
            i2s_ptr->TCCR |= (I2S_TCCR_PM(divider - 1));
            i2s_ptr->TCCR &= ~(I2S_TCCR_PSR_MASK);
            i2s_ptr->TCCR |= (I2S_TCCR_DIV2_MASK);
            /* Set receiver clock */
            i2s_ptr->RCCR &= ~(I2S_RCCR_PM_MASK);
            i2s_ptr->RCCR |= (I2S_RCCR_PM(divider - 1));
            i2s_ptr->RCCR &= ~(I2S_RCCR_PSR_MASK);
            i2s_ptr->RCCR |= (I2S_RCCR_DIV2_MASK);
        }
        else if ((divider > 512) && (divider < 2049))
        {
            divider = divider/8;
            i2s_ptr->TCCR &= ~(I2S_TCCR_PM_MASK);
            i2s_ptr->TCCR |= (I2S_TCCR_PM(divider - 1));
            i2s_ptr->TCCR |= (I2S_TCCR_PSR_MASK);
            i2s_ptr->TCCR &= ~(I2S_TCCR_DIV2_MASK);
            /* Set receiver clock */
            i2s_ptr->RCCR &= ~(I2S_RCCR_PM_MASK);
            i2s_ptr->RCCR |= (I2S_RCCR_PM(divider - 1));
            i2s_ptr->RCCR |= (I2S_RCCR_PSR_MASK);
            i2s_ptr->RCCR &= ~(I2S_RCCR_DIV2_MASK);
         }
         else if (divider > 2048)
         {
            divider = divider/16;
            i2s_ptr->TCCR &= ~(I2S_TCCR_PM_MASK);
            i2s_ptr->TCCR |= (I2S_TCCR_PM(divider - 1));
            i2s_ptr->TCCR |= (I2S_TCCR_PSR_MASK);
            i2s_ptr->TCCR |= (I2S_TCCR_DIV2_MASK);
            /* Set receiver clock */
            i2s_ptr->RCCR &= ~(I2S_RCCR_PM_MASK);
            i2s_ptr->RCCR |= (I2S_RCCR_PM(divider - 1));
            i2s_ptr->RCCR |= (I2S_RCCR_PSR_MASK);
            i2s_ptr->RCCR |= (I2S_RCCR_DIV2_MASK);
         }
         io_info_ptr->BCLK_DIV = divider * 2;
         io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_DIV;
         /* The word length is fixed to 32 in I2S master mode and DC is 1
         ** thus frame sync frequency is always BCLK_FREQ/64
         */
         io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / 64;
    }
    return(MQX_OK);
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/queue.h<|end_filename|>
/*HEADER**********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *****************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************
 *
 * $FileName: queue.h$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains the queue functions.
  *
 *END************************************************************************/

#ifndef __queue_h__
#define __queue_h__ 1

/*--------------------------------------------------------------------------*/
/*                     DATA STRUCTURE DEFINITIONS                           */



/*--------------------------------------------------------------------------*/
/* QUEUE ELEMENT STRUCTURE */
/*!
 * \brief Header for a queue element.
 *  
 * This structure is required in each queue element.
 * The address of this structure is used to enqueue, dequeue elements.
 * 
 * \see _queue_dequeue
 * \see _queue_enqueue
 * \see _queue_init
 * \see QUEUE_STRUCT
 */
typedef struct queue_element_struct
{

    /*! \brief Pointer to the next element in the queue. */
    struct queue_element_struct _PTR_ NEXT;
    
    /*! \brief Pointer to the previous element in the queue. */
    struct queue_element_struct _PTR_ PREV;

} QUEUE_ELEMENT_STRUCT, _PTR_ QUEUE_ELEMENT_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/* QUEUE STRUCTURE */
/*!
 * \brief Queue of any type of element that has a header of type 
 * QUEUE_ELEMENT_STRUCT.
 *   
 * This structure represents a generic queue head structure. Each queue element 
 * is made up of a data structure consisting of a NEXT pointer followed by a 
 * PREV pointer. Thus any type of element may be queued onto this queue.
 * 
 * \see _queue_init 
 * \see QUEUE_ELEMENT_STRUCT
 */
typedef struct queue_struct
{
    /*! 
     * \brief Pointer to the next element in the queue. If there are no elements
     * in the queue, the field is a pointer to the structure itself. 
     */
    struct queue_element_struct _PTR_ NEXT;
    
    /*
     * \brief Pointer to the last element in the queue. If there are no elements
     * in the queue, the field is a pointer to the structure itself. 
     */
    struct queue_element_struct _PTR_ PREV;
    
    /*! \brief Number of elements in the queue. */
    uint_16                           SIZE;
    
    /*! 
     * \brief Maximum number of elements that the queue can hold. If the field
     * is 0, the number is unlimited. 
     */
    uint_16                           MAX;

} QUEUE_STRUCT, _PTR_ QUEUE_STRUCT_PTR;



/*--------------------------------------------------------------------------*/
/*                       EXTERNAL DECLARATIONS                              */

#ifdef __cplusplus
extern "C" {
#endif

extern QUEUE_ELEMENT_STRUCT_PTR _queue_dequeue  (QUEUE_STRUCT_PTR);
extern boolean                  _queue_enqueue  (QUEUE_STRUCT_PTR, 
                                                 QUEUE_ELEMENT_STRUCT_PTR);
extern _mqx_uint                _queue_get_size (QUEUE_STRUCT_PTR);
extern void                     _queue_init     (QUEUE_STRUCT_PTR, uint_16);
extern boolean                  _queue_insert   (QUEUE_STRUCT_PTR, 
                                                 QUEUE_ELEMENT_STRUCT_PTR, 
                                                 QUEUE_ELEMENT_STRUCT_PTR);
extern boolean                  _queue_is_empty (QUEUE_STRUCT_PTR);
extern QUEUE_ELEMENT_STRUCT_PTR _queue_head     (QUEUE_STRUCT_PTR);
extern QUEUE_ELEMENT_STRUCT_PTR _queue_next     (QUEUE_STRUCT_PTR, 
                                                 QUEUE_ELEMENT_STRUCT_PTR);
extern void                     _queue_unlink   (QUEUE_STRUCT_PTR,
                                                 QUEUE_ELEMENT_STRUCT_PTR);
extern _mqx_uint                _queue_test     (QUEUE_STRUCT_PTR, 
                                                 pointer _PTR_);

#ifdef __cplusplus
}
#endif

#endif  /* __lwtimer_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/mqx_init.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mqx_init.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the source for the default MQX INITIALIZATION
*   STRUCTURE
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"

extern TASK_TEMPLATE_STRUCT MQX_template_list[];

const MQX_INITIALIZATION_STRUCT  MQX_init_struct =
{
   /* PROCESSOR_NUMBER                */  BSP_DEFAULT_PROCESSOR_NUMBER,
   /* START_OF_KERNEL_MEMORY          */  BSP_DEFAULT_START_OF_KERNEL_MEMORY,
   /* END_OF_KERNEL_MEMORY            */  BSP_DEFAULT_END_OF_KERNEL_MEMORY,
   /* INTERRUPT_STACK_SIZE            */  BSP_DEFAULT_INTERRUPT_STACK_SIZE,
   /* TASK_TEMPLATE_LIST              */  MQX_template_list,
   /* MQX_HARDWARE_INTERRUPT_LEVEL_MAX*/  BSP_DEFAULT_MQX_HARDWARE_INTERRUPT_LEVEL_MAX,
   /* MAX_MSGPOOLS                    */  BSP_DEFAULT_MAX_MSGPOOLS,
   /* MAX_MSGQS                       */  BSP_DEFAULT_MAX_MSGQS,
   /* IO_CHANNEL                      */  BSP_DEFAULT_IO_CHANNEL,
   /* IO_OPEN_MODE                    */  BSP_DEFAULT_IO_OPEN_MODE,
   0,
   0,
#if MQX_ENABLE_USER_MODE   
   BSP_DEFAULT_START_OF_KERNEL_AREA,
   BSP_DEFAULT_END_OF_KERNEL_AREA,
   
   BSP_DEFAULT_START_OF_USER_DEFAULT_MEMORY,
   BSP_DEFAULT_END_OF_USER_DEFAULT_MEMORY,
   
   BSP_DEFAULT_START_OF_USER_HEAP,
   BSP_DEFAULT_END_OF_USER_HEAP,
   
   BSP_DEFAULT_START_OF_USER_RW_MEMORY,
   BSP_DEFAULT_END_OF_USER_RW_MEMORY,
   
   BSP_DEFAULT_START_OF_USER_RO_MEMORY,
   BSP_DEFAULT_END_OF_USER_RO_MEMORY,
   
   BSP_DEFAULT_START_OF_USER_NO_MEMORY,
   BSP_DEFAULT_END_OF_USER_NO_MEMORY,

   BSP_DEFAULT_MAX_USER_TASK_PRIORITY,
   BSP_DEFAULT_MAX_USER_TASK_COUNT,
#endif
};

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/tcp.h<|end_filename|>
#ifndef __tcp_h__
#define __tcp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcp.h$
* $Version : 3.8.10.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Definitions for the Transmission Control Protocol layer.
*
*END************************************************************************/


/*
** References
**
** [1] "Congestion Avoidance and Control", <NAME>, ACM SIGCOMM-88,
**      August 1988 (1988 ACM 0-89791-279-9/88/008/0314)
** [2] "Round Trip Time Estimation" (not full title),
**      <NAME> & <NAME>, ACM SIGCOMM-87, August 1987
** RFC 793
** RFC 1122
** RFC 896
*/
#include "ip.h"
#include "ticker.h"

/************************************************************************/
/* Constants                                                            */
/************************************************************************/

/*
 *  Useful TCP assigned port numbers (see RFC 1010) (as in /etc/services)
 */
#define TCPPORT_ECHO       7   /* see RFC862; returns what was sent */
#define TCPPORT_DISCARD    9   /* see RFC863; returns nothing */
#define TCPPORT_TELNET    23   /* see RFC854, RFC855, ... */
#define TCPPORT_EXEC     512   /* `exec' service; see man rexecd(8C) */
#define TCPPORT_LOGIN    513   /* `login' service; see man rlogind(8C) */
#define TCPPORT_SHELL    514   /* `cmd' service; see man rshd(8C) */

/*  Options bits for TCB, also used in send and open calls
 */
#define TCPO_ACTIVE    0x0001  /* open/option: actively start connection */
#define TCPO_NONAGLE   0x0002  /* open/option: disable Nagle algorithm */
#define TCPO_NOSWITCH  0x0004  /* open/option: disable using user rcv buffer */
#define TCPO_NOWAIT    0x0010  /* send/rcv: return immediately */
#define TCPO_PUSH      0x0020  /* send/rcv: push data          */
#define TCPO_URGENT    0x0040  /* send/rcv: send bytes as urgent data */
#define TCPO_WAIT      0x0080  /* send/rcv: always block       */
                               /*    (wait for ack of data)    */

/*  Status bits for TCB, also used as event bits in wait and receive calls:
 */
#define TCPS_DUMMY     0x0000  /* Dummy event to TCP_Event */
#define TCPS_STARTED   0x0001  /* set once ESTABLISHED (or in any state in
                                  TCPSTATE_STARTED(state)), never cleared */
#define TCPS_FINACKED  0x0002  /* see TCPSTATE_FINACKED(state) */
#define TCPS_FINRECV   0x0004  /* see TCPSTATE_FINRECV(state) */
#define TCPS_FINDONE   0x0008  /* both FINACKED and FINRECV (not either) */
#define TCPS_FINTOSEND 0x2000  /* Close requested, FIN not necessarily sent */
#define TCPS_TPUSH     0x0010  /* PSH being sent, tcb->sndpush is valid */
#define TCPS_RPUSH     0x0020  /* PSH received, tcb->rcvpush is valid */
#define TCPS_TURGENT   0x0040  /* URG being sent, tcb->sndup is valid */
#define TCPS_RURGENT   0x0080  /* URG received, tcb->rcvup is valid */

/* transients */
#define TCPS_TREADY    0x0100  /* more data can be transmitted; set when send
                                  buffer becomes less than half full, cleared
                                  when send buffer becomes full */
#define TCPS_TACKED    0x0200  /* set when all sent data was acked; cleared if
                                  any more data is sent */
#define TCPS_TIMEOUT   0x0400  /* transmit timeout (transmission not ack'ed)*/
#define TCPS_SOFTERROR 0x0800  /* non-fatal ("soft") errors */
#define TCPS_NOWAIT    0x1000  /* return immediately */
#define TCPS_DEFER     0x4000  /* receive: asynchronous receive into reader's
                                  buffer; or, reader's buffer has been
                                  (asynchronously) filled */

#define TCB_VALID_ID   0x4b454720L
#define TCB_INVALID_ID 0x20544159L

/************************************************************************/
/* Macros                                                               */
/************************************************************************/
#if RTCSCFG_ENABLE_TCP_STATS
#define IF_TCP_STATS_ENABLED(x) x
#else
#define IF_TCP_STATS_ENABLED(x)
#endif

/************************************************************************/
/* Typedefs                                                             */
/************************************************************************/

/*
** TCP options set by upper layer
*/
typedef struct tcp_options_struct  {

   /*
   ** TCP_Transmit buffer size (use 0 to disable TCP buffer i.e. alway block on send,
   ** use -1 to default)
   */
   int_32      tbsize;

   int_32      rbsize;        /* Receive buffer size (use 0 to enforce
                                 that a user receive must be available, use
                                 -1 to default) */

   int_32      utimeout;      /* User timeout (msec) - TCP R1 period */
   int_32      timeout;       /* Connection timeout (msec) - TCP R2 period
                                 (use 0 to default) */
   int_32      rto;           /* Initial retransmission timeout (use 0 to
                                 default) */
   int_32      maxrto;        /* Max. retransmission timeout (use 0 to
                                 default) */
   uint_32     maxrcvwnd;     /* Max. receive window size (use 0 to
                                 default) */

   uchar       RESERVED2;
   uchar       ttl;           /* Time to live (use 0 to default) */
   uchar       tos;           /* Specify Internet type of service (use 0
                                 to default) */
   uchar       precede;       /* Specify precedence (0 to 7) (overrides
                                 precedence set in "tos" field) (use 0xFF
                                 to default) */

   _ip_address lochost;       /* Local host IP address (use IP_ZERO to
                                 default) */
   _ip_address remhost;       /* Remote host to call or wait for (may be
                                 IP_ZERO if can accept from any host) */

  #if RTCSCFG_ENABLE_IP6 
   in6_addr lochost_ipv6;       /* Local host IPv6 address (use in6addr_any to
                                 default) */
   in6_addr remhost_ipv6;       /* Remote host to call or wait for (may be
                                 in6addr_any if can accept from any host) */
  #endif
                                 

   uint_16     locport;       /* Local TCP port - use 0 to have one
                                 assigned */
   uint_16     remport;       /* Remote port to call or wait for (may be
                                 0 if can accept from any host port) */

   int_32      keepalive;     /* "Keepalive" timeout (0 to disable) */

   boolean     active;        /* True when originating connection, false
                                 to listen */
   boolean     nowait;        /* Return requests immediately to upper layer
                                 without waiting for completion */
   boolean     nonagle;       /* Disable the Nagle algorithm */
   boolean     noswrbuf;      /* Disable switching to user receive buffer */

   boolean     bypass_rx_chksum;  /* TRUE to bypass checksum check on Rx */
   boolean     bypass_tx_chksum;  /* TRUE to bypass checksum calc. on Tx */

   int_32     timewaitto;     /* TIME_WAIT timeout (use 0 for 2*MSL) */
   boolean     tcpsecuredraft0; /* draft-ietf-tcpm-tcpsecure-00.txt */
   uint_32 delayackto;   /* delay ack timeout */
} TCP_OPTIONS_STRUCT, _PTR_ TCP_OPTIONS_PTR;

/*
** TCP parameters
*/
typedef struct tcb_parm {
   TCPIP_PARM              COMMON;
   struct tcb_parm _PTR_   NEXT;

   uint_32        OPCODE;        /* Command to TCP */
   uint_32        ERROR_CODE;    /* Error code returned */

   struct tcb_struct _PTR_ TCB_PTR;     /* TCP Context (TCB) */
   TCP_OPTIONS_PTR  OPTIONS_PTR; /* TcpOpen options */

   _ip_address    IP_ADDR;

#if RTCSCFG_ENABLE_IP6 
    in6_addr      IPV6_ADDR;     /* IPv6 address     */
    uint_32       IF_SCOPE_ID;   /* Interface number */
#endif
    uint_16        AF;           /* Inet family      */  

   uint_16        TCP_PORT;
   uint_16        RESERVED1;

   pointer        BUFFER_PTR;    /* Send or receive buffer */
   uint_32        BUFF_LENG;     /* Send or receive buffer length */
   int_32         TIMEOUT;       /* Send or receive timeout */

   uint_16        OPTIONS;       /* Send or receive flags */
   uint_16        STATUS;        /* TCP connection status */

   uint_32        URGENT;        /* Length of urgent data in buffer */
   int_32         SOFTERROR;     /* Last error code in TCP context */

   uint_32        SOCKET;        /* Upper layer socket structure */

} TCP_PARM, _PTR_ TCP_PARM_PTR;

typedef struct tcp_message_struct
{
   MESSAGE_HEADER_STRUCT   HEADER;
   TCP_PARM                TCP_REQUEST;
} TCP_MESSAGE_STRUCT, _PTR_ TCP_MESSAGE_STRUCT_PTR;


/*  Send buffer chain, describes contents of transmit buffer; some parts
 *   of it may be in the TCB's `sndringbuf', other parts may be from the
 *   clients' buffers themselves.
 */
typedef struct SbufNode {

   struct SbufNode _PTR_ next;/* next buffer in this output stream */

   uchar _PTR_          data; /* if use_cbuf is TRUE, this is ptr to client
                                 Send buffer; else (client is FALSE), this is
                                 the offset (by casting to (uint_32)) in the
                                 TCB's `sndringbuf' of a piece of data to be
                                 sent (may wrap around the ring buffer) */

   int_32               size; /* nb of bytes (in client buf or in ring) */

   TCP_PARM_PTR         req;  /* pointer to Send request, or NULL */

   boolean              use_cbuf;
                              /* TRUE if the Send request buffer is
                                 being used to transmit, FALSE if
                                 transmitting from transmit ring buffer */

} SbufNode;

/*  An array of these is in each TCB (sndclks), to record transmit times for
 *   packets (segments)...
 */
typedef struct sndclock {

    uint_32   seq;      /* 1st seq # past last byte transmitted */
    int_32    time;     /* time (INFO(Time)) when packet transmitted */

} SndClock;

/*  These are used for all timers within TCB's; since expired TimeQ's can
 *   be automatically put in lists, the `tcb' field indicates in which TCB
 *   the expired TimeQ's are located.
 */
typedef struct tcbtimeq {

    TimeQ            t;     /* timer (see ticker.h); *must be 1st element**/
    struct tcb_struct _PTR_ tcb;   /* TCB which contains this timer */

} TcbTimeQ;

/*  Describes portions of the receive buffer which have been filled (received)
 */
typedef struct Rchunk {

    struct Rchunk _PTR_ next;
    int_32              used; /* offset from beginning of receive buffer */
    int_32              size; /* chunk size in bytes */

} Rchunk;

/*  Transmission Control Block (TCB)
 *  This is TCP's central data structure; one TCB is allocated to each
 *   TCP connection.
 */
typedef struct tcb_struct {
   struct tcb_struct _PTR_    next;             /* TCP server maintained list of TCB's */

   uint_32  SOCKET;           /* Upper layer socket structure */
   uint_32  VALID;            /* this TCB is valid if = TCB_VALID_ID */
                                                /* and validly closed if = TCB_INVALID_ID */
   boolean  bypass_rx_chksum; /* TRUE to bypass checksum check on Rx */
   boolean  bypass_tx_chksum; /* TRUE to bypass checksum calc. on Tx */

#if 0
   TCP_PARM_PTR         oclient;
                             /* current OPEN/CLOSE?/WAIT request
                                or NULL if no control request
                                is pending; only one such non-I/O request
                                can be done at a time. */

   uint_16   RESERVED1655;
   uint_16   oevents;        /* event(s) oclient is waiting for... */
#endif

   uint_16   state;          /* state of connection */

   uint_16   status;         /* bit-wise status of connection (TCPS_*) */
   uint_16   options;        /* TcpOpen() options (TCPO_*) */

   uchar     RESERVED3;
   uchar     tos;            /* IP type-of-service (includes precedence) */

   int_32    lasterror;      /* last error code on IP_Send(), or last soft
                                error; cleared when read by oclient */

   uint_32   send_error;     /* last error on sending data  */

   _ip_address  local_host;    /* local host; may be INADDR_ANY in LISTEN state */
   _ip_address  remote_host;   /* remote host; may be INADDR_ANY in LISTEN state */

#if RTCSCFG_ENABLE_IP6
   in6_addr  local_ipv6_host;  /* local IPv6  host; may be INADDR_ANY in LISTEN state */
   in6_addr  remote_ipv6_host; /* remote IPv6 host; may be INADDR_ANY in LISTEN state */
   uint_32   if_scope_id;      /* interface number, scope_id */
#endif
   uint_16   af;               /* inet family */ 


   uint_16   local_port;     /* local TCP port [...] */
   uint_16   remote_port;    /* remote TCP port, may be 0 in LISTEN state */

#if 0
   /*  the following four are used to return to LISTEN state...  */
   _ip_address  i_local_host;   /* initial local_host */
   _ip_address  i_remote_host;  /* initial remote_host */
   uint_16   i_local_port;   /* initial local_port */
   uint_16   i_remote_port;  /* initial remote_port */
#endif

   /* receive section */

   Rchunk _PTR_ rcvchunks;   /* portions of receive buffer which we have
                                (since we keep out-of-order packets' data)*/
   uchar _PTR_ rcvbuf;       /* current receive buffer (equals rcvringbuf or
                                rcvuserbuf); it is a circular buffer,
                                except when it equals rcvuserbuf ... */
   uint_32     rcvlen;       /* size of receive buffer */
   uint_32     rcvpos;       /* position within rcvbuf (0..rcvlen-1)
                                of next byte to be received by client;
                                always zero if rcvbuf==rcvuserbuf */
   uchar _PTR_ rcvringbuf;   /* default circular receive buffer */
   uint_32     rcvringlen;   /* total size of rcvringbuf */
   uchar _PTR_ rcvuserbuf;   /* (user) buffer of Receive client, if any */
   uint_32     rcvuserlen;   /* total size of rcvuserbuf */


   uint_32   rcvusernxt;     /* nb of data bytes in rcvuserbuf; undefined in
                                the special case when rcvuserbuf==rcvbuf;
                                otherwise, if rcvuserbuf!=0 then the
                                implementation insures that whatever
                                contiguous data is available at the head
                                of the receive buffer has been put in the
                                user buffer, which implies that either the
                                data in rcvbuf is non-contiguous with that
                                in rcvuserbuf, or that rcvuserbuf is full */

   TCP_PARM_PTR   rcvHead;   /* First receive currently active */
   TCP_PARM_PTR   rcvTail;   /* Last receive currently active */

   uint_16   conn_pending;   /* 1 = conn established but not accepted */
   uint_16   rcvevents;      /* options as specified in TcpReceive();
                                may contain TCPS_RPUSH, ? */

   int_32    rcvto;          /* user Receive() timeout (msecs) or 0 */
   uint_32   rcvbufseq;      /* sequence # of 1st byte in rcvbuf */
                             /* The quantity  rcvbufseq + rcvlen  should
                                always increase monotonically (to avoid the
                                `shrinking window' misbehaviour) */
   uint_32   rcvnxt;         /* next (contiguous) sequence # to receive */
   uint_32   rcvwndedge;     /* right edge of advertised receive window
                                (bytes available in receive buffer for peer
                                TCP); left edge is rcvnxt, so size of
                                advertised rcv. wnd. is rcvwndedge - rcvnxt;
                                this size may be less than the real receive
                                window (because of SWS-avoidance and the
                                0xffff and rcvwndmax limits), which is
                                always rcvbufseq + rcvlen - rcvnxt */
   uint_32   rcvwndmax;      /* maximum window to advertise; usually 0xffff,
                                but may be made 0x7fff for peer TCP's which
                                don't properly handle large advertised
                                windows, or be made the size of a packet
                                to avoid being sent back to back packets
                                */


   uint_32   rcvup;          /* 1st seq # following received urgent data;
                                valid if (options & TCPS_RURGENT) != 0) */
   uint_32   rcvpush;        /* 1st seq # following last received PSH;
                                valid if (options & TCPS_RPUSH) != 0) */
   uint_32   rcvirs;         /* initial receive sequence # */

   uint_32   rcvuna;         /* (1st) sequence # unacknowledged; used for
                                delayed ACKs (TCP_ACKDELAY_DEFAULT ms or
                                until rcv2full bytes) */


   TcbTimeQ  rcvtq;          /* user timer, for receive timeout */


   uint_16   RESERVED5;
   uint_16   rcvmss;         /* maximum segment size for receiving (mss_r);
                                any IP or TCP options must be subtracted
                                from this value; computed at connection
                                setup and doesn't change */

   uint_32   rcvmax;         /* biggest segment received (data only), but at
                                most rcvmss; used to compute rcv2full */
   uint_32   rcv2full;       /* 1.75 times rcvmax, this is the amount of
                                data received which always triggers sending
                                an ACK; initially 1, it is computed from
                                rcvmax when the latter changes */

   /* send section */

   SbufNode _PTR_ sndbuf;    /* head of send buffer chain (0 if empty) */


   SbufNode _PTR_ sndbuftail;/* tail of send buffer chain (0 if empty) */
   uint_32   sndlen;         /* total size of send buffers */

   uchar _PTR_ sndringbuf;   /* default circular transmit buffer */
   uint_32   sndringlen;     /* length of sndringbuf */
   uint_32   sndringhead;    /* next avail. byte within sndringbuf */
   uint_32   sndringtail;    /* follows last avail. byte within sndringbuf */
   uint_32   sndringavail;   /* nb of bytes available in sndringbuf */
   uint_32   sndbufseq;      /* sequence # of 1st byte of sndbuf */
                             /* The quantity  sndbufseq + sndlen  should
                                always increase monotonically */

   uint_32   snduna;         /* (1st) sequence # unacknowledged */
   uint_32   sndxmit;        /* sequence # next to (re)transmit */
   int_32    sndrto;         /* retransmission timeout (RTO) in msecs */
                             /* ^ expon. backed off by 2's... */
   int_32    sndrtomax;      /* maximum value (clamp) for sndrto */
   int_32    sndprobeto;     /* retransmission timeout for 0-window probes */
   int_32    sndprobetomax;  /* maximum value (clamp) for sndproberto */
   int_32    sndrtta;        /* RTT average estimate; scaled by 2^3 */
   int_32    sndrttd;        /* RTT deviation estimate; scaled by 2^2 */

   TcbTimeQ  sndxmittq;      /* retransmit timer, for next packet to rexmit;
                                also used for TIME_WAIT delay, and for
                                probe retransmits (see sndxmitwhat) */

   uint_16   keepalive;      /* when nonzero, next call to TCP_Transmit()
                                must send a keepalive probe */
   char      RESERVED7;
   char      sndxmitwhat;    /* xmit: 0==idle/timewait, 1==probe, 2==xmit */
   boolean   sndtohard;      /* true if sndtq active on sndto_2, that is,
                                soft timeout expired, hard timeout coming*/
   int_32    timewaitto;     /* TIME_WAIT timeout (msecs) */
   int_32    keepaliveto;    /* keepalive period (msecs), or 0 if none */
   
   uint_32   delayackto;     /* DELAY_ACK timeout (msec) */

   TcbTimeQ  sndacktq;       /* transmit timer for delayed ACKs; actually,
                                this is generally used (TCP_Timer_oneshot_max())
                                when "something must be sent"
                                within perhaps a certain amount of time */

   int_32    sndto_1;        /* user (soft) timeout value to use for sndtq,
                                0 if none */
   int_32    sndto_2;        /* hard timeout value for sndtq, or 0 if none;
                                this timeout is started after sndtq expires
                                on sndto_1, so it is a delta from sndto_1;
                                if sndto_1 is zero, sndto_2 is also zero */
   TcbTimeQ  sndtq;          /* timer for timeout on ack of transmissions */

   SndClock _PTR_ sndclk;    /* packet transmission times, used for
                                calculating RTT (round trip time) */
   SndClock _PTR_ sndclkend; /* sndclk + sndclks */
   SndClock _PTR_ sndclkhead;/* circular queue of entries in sndclk[]... */
   SndClock _PTR_ sndclktail;/*    "    */
   int_16    sndclks;        /* size of sndclk[] (nb of entries) */
   int_16    sndclkavail;    /* nb of available entries in sndclk[] queue */

   uint_32   sndnxt;         /* 1st sequence # of unsent data (next new data
                                to send) */
   uint_32   sndwnd;         /* window allowed to send (from snduna) */

   int_32    sndcwnd;        /* congestion window, in bytes, for Jacobson's
                                combined `slow-start' and congestion
                                avoidance (see [1]) */
   int_32    sndstresh;      /* window size threshold for switching between
                                `slow-start' and congestion avoidance
                                (again, see [1]) */
   uint_32   sndwl1;         /* sequence # of last seg. to update sndwnd */
   uint_32   sndwl2;         /* ack # of last seg. to update sndwnd */

   uint_16   sndmss;         /* maximum segment size for sending (mss_s);
                                the length of any IP or TCP options sent
                                (but not headers) must be subtracted from
                                this value */
   uint_16   sndmax;         /* maximum data bytes to send in a segment;
                                this is sndmss - (length of IP and TCP
                                options sent with data) */
   uint_32   sndup;          /* urgent pointer sequence # (1st byte after);
                                valid if (options & TCPS_TURGENT) != 0) */
   uint_32   sndpush;        /* seq # of 1st byte after last PSH to send;
                                valid if (options & TCPS_TPUSH) != 0) */
   uint_32   sndiss;         /* initial send sequence # */

   /* statistics */
   uint_32   sndwndmax;      /* max value of sndwnd during connection */
   uint_32   sndcwndmax;     /* max value of sndcwnd during connection */
   uint_32   rexmts;         /* number of retransmissions */
   uint_32   sndtmouts;      /* number of send timeouts */

   struct tcb_struct _PTR_     LISTEN_TCB;  /* The listening TCB which was cloned */
   struct tcb_struct _PTR_     NOSOCK_NEXT; /* A linked list of TCBs spawned from
                                        listening TCB */
   uint_32   tcb_spawn_time; /* keep the time when tcb is created */

   RTCS_LINKOPT_STRUCT        TX;
   boolean   tcpsecuredraft0; /* invoke draft-ietf-tcpm-tcpsecure-00.txt processing */
   int_32    ackmodifier;     /* used by tcpsecure (above) processing to sometimes decriment value being ack'ed */
} TCB_STRUCT, _PTR_ TCB_STRUCT_PTR;

/*
** TCP Configuration
**    This information is persistent for the TCP layer.
*/
typedef struct tcp_cfg_struct {
#if RTCSCFG_ENABLE_TCP_STATS
   TCP_STATS      STATS;         /* Statistics */
#endif

   TCB_STRUCT_PTR TCBhead;       /* List of active TCBs */
   Rchunk _PTR_   Rchunkhead;    /* List of active Rchunks */
   Rchunk _PTR_   Rchunkfree;    /* List of free Rchunks */
   SbufNode _PTR_ SbufNodehead;  /* List of active SbufNodes */
   SbufNode _PTR_ SbufNodefree;  /* List of free SbufNodes */

   uint_32        nextno;        /* for TCB->no */
   ICB_STRUCT_PTR icb;           /* IP "connection" for TCP protocol */

   uint_16        RESERVED1;
   uint_16        next_port;     /* next port to assign
                                    for TcpOpen with localport==0 */

   TimeQ _PTR_    qh;            /* the timeout queue head */
   uint_32        lasttime;      /* time TCP_Tick_server() was last called */

   TimeQ _PTR_ _PTR_ qhead;      /* Address of the timeout queue head */

   TcbTimeQ _PTR_ acktq;         /* expired delayed-ACK timers */
   TcbTimeQ _PTR_ xmittq;        /* expired rexmit/probe/timewait timers*/
   TcbTimeQ _PTR_ sndtq;         /* expired ack-of-transmission timers */
   TcbTimeQ _PTR_ rcvtq;         /* expired receive timeout timers */

   TCP_PARM_PTR   OPENS;         /* pending open requests */
   TCPIP_EVENT    EVENT_TO_DEQUEUE_PCB; /*
                                           This event is used to
                                           dequeue an enqueued PCB
                                           (for simultaneos SYN problem)
                                           if it remains on the queue for
                                           more than 1 second
                                        */

   RTCSPCB_PTR       DEFER_HEAD;
   RTCSPCB_PTR _PTR_ DEFER_TAIL;

   uint_32        CONN_COUNT;    /* current connection count */

   uint_32        DEFER_COUNT;   /* number of deferred PCBs */

   TCB_STRUCT_PTR NOSOCK_TCB;    /* List of TCBs spawned from listening TCB */

   uint_32         HALF_OPEN_TCB_COUNT;   /* current half open TCB count */
#if RTCSCFG_TCP_MAX_HALF_OPEN
   TCB_STRUCT_PTR  HALF_OPEN_TCB_LIST[RTCSCFG_TCP_MAX_HALF_OPEN];
                                 /* array of half open TCBs */
#endif

} TCP_CFG_STRUCT, _PTR_ TCP_CFG_STRUCT_PTR;

/************************************************************************/
/* Functions                                                            */
/************************************************************************/

extern uint_32 TCP_Init (void);

extern void TCP_Process_create  (TCP_PARM_PTR);
extern void TCP_Process_bind    (TCP_PARM_PTR);

extern void TCP_Process_open    (TCP_PARM_PTR);

extern void TCP_Process_accept  (TCP_PARM_PTR);

extern void TCP_Process_send    (TCP_PARM_PTR);
extern void TCP_Process_receive (TCP_PARM_PTR);

extern void TCP_Process_close   (TCP_PARM_PTR);
extern void TCP_Process_abort   (TCP_PARM_PTR);

extern void TCP_Process_signal  (void);

extern void TCP_Service_packet
(
   RTCSPCB_PTR          ,        /* IN/OUT - the receive packet */
   pointer                       /* IN/OUT - TCP layer constants */
);
extern void TCP6_Service_packet
   (
      RTCSPCB_PTR    pcb,     /* IN/OUT - the receive packet */
      void _PTR_     cfg      /* IN/OUT - TCP layer constants */
   );
extern void TCP4_Service_packet
   (
      RTCSPCB_PTR    pcb,     /* IN/OUT - the receive packet */
      void _PTR_     cfg      /* IN/OUT - TCP layer constants */
   ); 
   
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd.h$
* $Version : 172.16.58.3$
* $Date    : Aug-31-2012$
*
* Comments:
*
*   Header for HTTPD.
*
*END************************************************************************/

#ifndef HTTPD_H_
#define HTTPD_H_

#include <rtcs.h>
#include "httpd_types.h"
#include "httpd_supp.h"


#define HTTPD_SET_PARAM_PORT(server, val)           HTTPD_SET_PARAM(server, port, val)
#define HTTPD_SET_PARAM_ROOT_DIR(server, val)       HTTPD_SET_PARAM(server, root_dir, val)
#define HTTPD_SET_PARAM_INDEX_PAGE(server, val)     HTTPD_SET_PARAM(server, index_page, val)
#define HTTPD_SET_PARAM_FN_TBL(server, val)         HTTPD_SET_PARAM(server, fn_lnk_tbl, val)
#define HTTPD_SET_PARAM_CGI_TBL(server, val)        HTTPD_SET_PARAM(server, cgi_lnk_tbl, val)
#define HTTPD_SET_PARAM_AUTH_FN(server, val)        HTTPD_SET_PARAM(server, auth_fn, val)

#define HTTPD_SET_PARAM(server, pname, val)             \
{                                                       \
    HTTPD_ASSERT(server && server->params);             \
    if (server && server->params) {                     \
        server->params->pname = val;                    \
    }                                                   \
}
/* Waiting time in miliseconds for RTCS_selectall() function for waiting input connection.*/ 
#define HTTPD_SELLECTALL_WAITING_TIME 3000 

/* It is timeout (in milliseconds) for keep-alive mode */
#ifndef HTTPD_RECEIVE_TIMEOUT
#define HTTPD_RECEIVE_TIMEOUT 50
#endif


/** Set default parameters for server. Function initialize parameters structure to default value.
 * If calling parameter params is NULL, function allocate parameters in memory - don't forget release it
 * when close/realease HTTPD.
 * \param params < pointer to parameters structure which will be set to default values
 * \return pointer to parameters structure.
 */
HTTPD_PARAMS_STRUCT* httpd_default_params(HTTPD_PARAMS_STRUCT *params);

/** Set index page for httpd.
 * \param server < pointer to server
 * \param index_page < pointer to index page filename (can be with relative path to root_dir)
 * \return zero when success
 */
_mqx_int httpd_set_index_page(HTTPD_STRUCT *server, char *index_page);

/** Initialize HTTP server.
 * \param server < pointer to server data structure
 * \return zero when success
 */
HTTPD_STRUCT* httpd_init(HTTPD_PARAMS_STRUCT *params);

/** Release HTTP server.
 * \param server < pointer to server data structure
 * \return 0 when success
 */
_mqx_int httpd_release(HTTPD_STRUCT *server);

/** Initialize HTTP server.
 * \param root_dir < pointer to root directory structure
 * \param index_page < index page relative path
 * \return pointer to server
 */
#if RTCSCFG_ENABLE_IP4 
    HTTPD_STRUCT* httpd_server_init(HTTPD_ROOT_DIR_STRUCT *root_dir, const char *index_page);
#endif
/** Initialize HTTP server.
 * \param root_dir < pointer to root directory structure
 * \param index_page < index page relative path
 * \return pointer to server
 *  parameter af_inet-family define IP4 or IP6 mode of server will be used
 */
HTTPD_STRUCT* httpd_server_init_af(HTTPD_ROOT_DIR_STRUCT *root_dir, const char *index_page, uint_32 af_inet_family);


/** Run HTTP server.
 * \param server < pointer to server structure
 * \return non zero when success
 */
_mqx_int httpd_server_run(HTTPD_STRUCT *server);

/** HTTP server polling fn
 * \param server < pointer to server structure
 * \param to < timeout for poll fn
 */
void httpd_server_poll(HTTPD_STRUCT *server, _mqx_int to);

/** stop httpd server
 * \param server < pointer to server structure
 * \return zero if success
 */
_mqx_int httpd_server_stop(HTTPD_STRUCT *server);

#endif /* HTTP_H_ */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/md5.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: md5.h$
* $Version : 3.0.5.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   The MD5 Lookup Table
*
*END************************************************************************/

static uint_32 mdtab[] = {
   0xD76AA478l, 0xE8C7B756l, 0x242070DBl, 0xC1BDCEEEl,
   0xF57C0FAFl, 0x4787C62Al, 0xA8304613l, 0xFD469501l,
   0x698098D8l, 0x8B44F7AFl, 0xFFFF5BB1l, 0x895CD7BEl,
   0x6B901122l, 0xFD987193l, 0xA679438El, 0x49B40821l,
   0xF61E2562l, 0xC040B340l, 0x265E5A51l, 0xE9B6C7AAl,
   0xD62F105Dl, 0x02441453l, 0xD8A1E681l, 0xE7D3FBC8l,
   0x21E1CDE6l, 0xC33707D6l, 0xF4D50D87l, 0x455A14EDl,
   0xA9E3E905l, 0xFCEFA3F8l, 0x676F02D9l, 0x8D2A4C8Al,
   0xFFFA3942l, 0x8771F681l, 0x6D9D6122l, 0xFDE5380Cl,
   0xA4BEEA44l, 0x4BDECFA9l, 0xF6BB4B60l, 0xBEBFBC70l,
   0x289B7EC6l, 0xEAA127FAl, 0xD4EF3085l, 0x04881D05l,
   0xD9D4D039l, 0xE6DB99E5l, 0x1FA27CF8l, 0xC4AC5665l,
   0xF4292244l, 0x432AFF97l, 0xAB9423A7l, 0xFC93A039l,
   0x655B59C3l, 0x8F0CCC92l, 0xFFEFF47Dl, 0x85845DD1l,
   0x6FA87E4Fl, 0xFE2CE6E0l, 0xA3014314l, 0x4E0811A1l,
   0xF7537E82l, 0xBD3AF235l, 0x2AD7D2BBl, 0xEB86D391l
};



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb_dcd/polled/usb_dcd_pol.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_dcd_pol.c$
* $Version : 3.8.1.0$
* $Date    : Jul-27-2011$
*
* Comments:
*
*   This file contains the USB DCD polled I/O driver functions.
*
*END************************************************************************/


#include <mqx_inc.h>
#include <fio.h>
#include <fio_prv.h>
#include <io.h>
#include <io_prv.h>
#include "usb_dcd.h"
#include "usb_dcd_pol_prv.h"


/*FUNCTION****************************************************************
* 
* Function Name    : _io_usb_dcd_polled_install
* Returned Value   : MQX error code
* Comments         :
*    Install the USB_DCD device.
*
*END**********************************************************************/

_mqx_uint _io_usb_dcd_polled_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr               identifier,
  
      /* [IN] The I/O init function */
      _mqx_uint (_CODE_PTR_ init)(pointer, pointer _PTR_, char_ptr),
      
      /* [IN] The I/O de-init function */
      _mqx_uint (_CODE_PTR_ deinit)(pointer, pointer),
      
      /* [IN] The input function */
      _mqx_int  (_CODE_PTR_ recv)(pointer, char_ptr, _mqx_int),
     
      /* [IN] The output function */
      _mqx_int  (_CODE_PTR_ xmit)(pointer, char_ptr, _mqx_int),

      /* [IN] The I/O ioctl function */
      _mqx_int  (_CODE_PTR_ ioctl)(pointer, _mqx_uint, _mqx_uint_ptr),

      /* [IN] The I/O init data pointer */
      pointer               init_data_ptr
      
   )

{ /* Body */
   IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr;

   pol_io_dev_ptr = (IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR)_mem_alloc_system_zero ((_mem_size)sizeof (IO_USB_DCD_POLLED_DEVICE_STRUCT));
   if (pol_io_dev_ptr == NULL) 
   {
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type (pol_io_dev_ptr, MEM_TYPE_IO_USB_DCD_POLLED_DEVICE_STRUCT);            

   pol_io_dev_ptr->DEV_INIT          = init;
   pol_io_dev_ptr->DEV_DEINIT        = deinit;
   pol_io_dev_ptr->DEV_READ          = recv;
   pol_io_dev_ptr->DEV_WRITE         = xmit;
   pol_io_dev_ptr->DEV_IOCTL         = ioctl;
   pol_io_dev_ptr->DEV_INIT_DATA_PTR = init_data_ptr;
   
   return (_io_dev_install_ext (identifier,
      _io_usb_dcd_polled_open,  _io_usb_dcd_polled_close,
      _io_usb_dcd_polled_read,  _io_usb_dcd_polled_write,
      _io_usb_dcd_polled_ioctl, _io_usb_dcd_polled_uninstall,
      (pointer)pol_io_dev_ptr));

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _io_usb_dcd_polled_uninstall
* Returned Value   : MQX error code
* Comments         :
*    Uninstall a polled USB DCD device.
*
*END**********************************************************************/

_mqx_int _io_usb_dcd_polled_uninstall
   (
      /* [IN] The IO device structure for the device */
      IO_DEVICE_STRUCT_PTR   io_dev_ptr
   )
{ /* Body */
   IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

   if (pol_io_dev_ptr->COUNT == 0) 
   {
      if (pol_io_dev_ptr->DEV_DEINIT) 
      {
         (*pol_io_dev_ptr->DEV_DEINIT)(pol_io_dev_ptr->DEV_INIT_DATA_PTR,pol_io_dev_ptr->DEV_INFO_PTR);
      }
      _mem_free (pol_io_dev_ptr);
      io_dev_ptr->DRIVER_INIT_PTR = NULL;
      return IO_OK;
   } else {
      return IO_ERROR_DEVICE_BUSY;
   }

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_usb_dcd_polled_open
* Returned Value   : MQX error code
* Comments         :
*    This routine initializes the USB DCD I/O channel. It acquires
*    memory, then stores information into it about the channel.
*    It then calls the hardware interface function to initialize the channel.
* 
*END**********************************************************************/

_mqx_int _io_usb_dcd_polled_open
   (
      /* [IN] the file handle for the device being opened */
      FILE_DEVICE_STRUCT_PTR          fd_ptr,
       
      /* [IN] the remaining portion of the name of the device */
      char_ptr                        open_name_ptr,

      /* [IN] the flags to be used during operation */
      char_ptr                        flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR                   io_dev_ptr;
   IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR    pol_io_dev_ptr;
   _mqx_int                               result = MQX_OK;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   pol_io_dev_ptr = (pointer)(io_dev_ptr->DRIVER_INIT_PTR);
   
   _int_disable ();
   if (pol_io_dev_ptr->COUNT) 
   {
      /* Device is already opened */
      _int_enable ();
      return MQX_IO_OPERATION_NOT_AVAILABLE;
   }
   pol_io_dev_ptr->COUNT = 1;
   _int_enable ();
      
   pol_io_dev_ptr->FLAGS = (_mqx_uint)flags;
   fd_ptr->FLAGS         = (_mqx_uint)flags;
            
   result = (*pol_io_dev_ptr->DEV_INIT)((pointer)pol_io_dev_ptr->DEV_INIT_DATA_PTR, &pol_io_dev_ptr->DEV_INFO_PTR, open_name_ptr);
   if (result != MQX_OK) 
   {
      pol_io_dev_ptr->COUNT = 0;
   }
   
   return result;

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_usb_dcd_polled_close
* Returned Value   : MQX error code
* Comments         :
*    This routine closes the USB DCD I/O channel.
* 
*END**********************************************************************/

_mqx_int _io_usb_dcd_polled_close
   (
      /* [IN] the file handle for the device being closed */
      FILE_DEVICE_STRUCT_PTR       fd_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR                  io_dev_ptr;
   IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR   pol_io_dev_ptr;
   _mqx_int                              result = MQX_OK;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   pol_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   _int_disable ();
   if (--pol_io_dev_ptr->COUNT == 0) 
   {
      if (pol_io_dev_ptr->DEV_DEINIT) 
      {
         result = (*pol_io_dev_ptr->DEV_DEINIT)(pol_io_dev_ptr,pol_io_dev_ptr->DEV_INFO_PTR);
      }
   }
   _int_enable ();
   return result;

} /* Endbody */

  
/*FUNCTION****************************************************************
* 
* Function Name    : _io_usb_dcd_polled_read
* Returned Value   : MQX_OK
* Comments         :
*    This routine calls the appropriate read routine.
*
*END*********************************************************************/

_mqx_int _io_usb_dcd_polled_read
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR       fd_ptr,

      /* [IN] where the characters are to be stored */
      char_ptr                     data_ptr,

      /* [IN] the number of bytes to read */
      _mqx_int                     n
   )
{  /* Body */

   IO_DEVICE_STRUCT_PTR                  io_dev_ptr;
   IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR   pol_io_dev_ptr;
   
   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   pol_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   return (*pol_io_dev_ptr->DEV_READ)(pol_io_dev_ptr, data_ptr, n);

}  /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_usb_dcd_polled_write
* Returned Value   : number of bytes written
* Comments         :
*    This routine calls the appropriate write routine.
*
*END**********************************************************************/

_mqx_int _io_usb_dcd_polled_write
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR       fd_ptr,

      /* [IN] where the bytes are stored */
      char_ptr                     data_ptr,

      /* [IN] the number of bytes to output */
      _mqx_int                     n
   )
{  /* Body */
   IO_DEVICE_STRUCT_PTR			            	io_dev_ptr;
   IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR		 	pol_io_dev_ptr;
   
   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   pol_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
               
   return (*pol_io_dev_ptr->DEV_WRITE)(pol_io_dev_ptr, data_ptr, n);
              
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_usb_dcd_polled_ioctl
* Returned Value   : MQX error code
* Comments         :
*    Returns result of USB_DCD ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_usb_dcd_polled_ioctl
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR       fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint                    cmd,

      /* [IN] the ioctl parameters */
      pointer                      input_param_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR  		          io_dev_ptr;
   IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR  pol_io_dev_ptr;
   _mqx_int                        		 result = MQX_OK;
   _mqx_uint_ptr                   		 param_ptr = (_mqx_uint_ptr)input_param_ptr;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   pol_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

    switch (cmd) {
        case IO_IOCTL_DEVICE_IDENTIFY :
            /* return the device identify */
            param_ptr[0] = IO_DEV_TYPE_PHYS_USB_DCD_POLLED;
            param_ptr[1] = 0;
            param_ptr[2] = IO_DEV_ATTR_POLL | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
            result = MQX_OK;    
            break;
        default:
            if (pol_io_dev_ptr->DEV_IOCTL != NULL) {
                result = (*pol_io_dev_ptr->DEV_IOCTL)(pol_io_dev_ptr->DEV_INFO_PTR, cmd, param_ptr);
            }
    }
   
   return result;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sdcard/sdcard_esdhc/sdcard_esdhc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sdcard_esdhc.c$
* $Version : 3.8.11.0$
* $Date    : Jul-19-2012$
*
* Comments:
*
*   This file contains the SD card driver functions.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <sdcard.h>
#include <sdcard_prv.h>
#include <sdcard_esdhc.h>
#include <esdhc.h>


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_sdcard_esdhc_r2_format
* Returned Value   : 
* Comments         :
*    Reformats R2 (CID,CSD) as read from ESDHC registers to a byte array.
*
*END*----------------------------------------------------------------------*/

static void _io_sdcard_esdhc_r2_format(uint_32 r[4], uint_8 r2[16])
{
    int i;
    uint_32 tmp = 0; /* initialization required to avoid compilation warning */

    i=15;
    while (i)
    {
        if ((i%4) == 3)
        {
            tmp = r[3-i/4];
        }
        r2[--i] = tmp & 0xff;
        tmp >>= 8;  
    }
    r2[15] = 0;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_sdcard_esdhc_init
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    Initializes ESDHC communication, SD card itself and reads its parameters.
*
*END*----------------------------------------------------------------------*/

boolean _io_sdcard_esdhc_init 
(
    /* [IN/OUT] SD card file descriptor */
    MQX_FILE_PTR fd_ptr
)
{
    uint_32              baudrate, param, c_size, c_size_mult, read_bl_len;
    ESDHC_COMMAND_STRUCT command;
    IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
    SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
    uint_8               buffer[64];
    uint_8               csd[16];
    
    /* Check parameters */
    if ((NULL == sdcard_ptr) || (NULL == sdcard_ptr->COM_DEVICE) || (NULL == sdcard_ptr->INIT))
    {
        return FALSE;
    }

    sdcard_ptr->TIMEOUT = 0;
    sdcard_ptr->NUM_BLOCKS = 0;
    sdcard_ptr->ADDRESS = 0;
    sdcard_ptr->SDHC = FALSE;
    sdcard_ptr->VERSION2 = FALSE;
    
    /* Initialize and detect card */
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_INIT, NULL))
    {
        return FALSE;
    }

    /* Set low baudrate for card setup */
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_GET_BAUDRATE, &baudrate))
    {
        return FALSE;
    }
    param = 400000;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SET_BAUDRATE, &param))
    {
        return FALSE;
    }
    
    /* SDHC check */
    param = 0;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_GET_CARD, &param))
    {
        return FALSE;
    }
    if ((ESDHC_CARD_SD == param) || (ESDHC_CARD_SDHC == param) || (ESDHC_CARD_SDCOMBO == param) || (ESDHC_CARD_SDHCCOMBO == param))
    {
        if ((ESDHC_CARD_SDHC == param) || (ESDHC_CARD_SDHCCOMBO == param))
        {
            sdcard_ptr->SDHC = TRUE;
        }
    }
    else
    {
        return FALSE;
    }

    /* Card identify */
    command.COMMAND = ESDHC_CMD2;
    command.ARGUMENT = 0;
    command.BLOCKS = 0;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
    {
        return FALSE;
    }

    /* Get card address */
    command.COMMAND = ESDHC_CMD3;
    command.ARGUMENT = 0;
    command.BLOCKS = 0;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
    {
        return FALSE;
    }
    sdcard_ptr->ADDRESS = command.RESPONSE[0] & 0xFFFF0000;
    
    /* Get card parameters */
    command.COMMAND = ESDHC_CMD9;
    command.ARGUMENT = sdcard_ptr->ADDRESS;
    command.BLOCKS = 0;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
    {
        return FALSE;
    }

    _io_sdcard_esdhc_r2_format(command.RESPONSE, csd);
    sdcard_ptr->NUM_BLOCKS = _io_sdcard_csd_capacity(csd);

    param = _io_sdcard_csd_baudrate(csd);      
    if (param > baudrate)
    {
        param = baudrate;
    }
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SET_BAUDRATE, &param))
    {
        return FALSE;
    }

    /* Select card */
    command.COMMAND = ESDHC_CMD7;
    command.ARGUMENT = sdcard_ptr->ADDRESS;
    command.BLOCKS = 0;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
    {
        return FALSE;
    }

    /* Set block size to 512 */
    command.COMMAND = ESDHC_CMD16;
    command.ARGUMENT = IO_SDCARD_BLOCK_SIZE;
    command.BLOCKS = 0;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
    {
        return FALSE;
    }

    if (ESDHC_BUS_WIDTH_4BIT == sdcard_ptr->INIT->SIGNALS)
    {
        /* Application specific command */
        command.COMMAND = ESDHC_CMD55;
        command.ARGUMENT = sdcard_ptr->ADDRESS;
        command.BLOCKS = 0;
        if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
        {
            return FALSE;
        }

        /* Set bus width == 4 */
        command.COMMAND = ESDHC_ACMD6;
        command.ARGUMENT = 2;
        command.BLOCKS = 0;
        if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
        {
            return FALSE;
        }

        param = ESDHC_BUS_WIDTH_4BIT;
        if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SET_BUS_WIDTH, &param))
        {
            return FALSE;
        }
    }

    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_sdcard_esdhc_read_block
* Returned Value   : number of ssuccessfully processed blocks or IO_ERROR
* Comments         :
*    Reads sectors from SD card starting with given index into given buffer.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_esdhc_read_block
(
    /* [IN] SD card info */
    MQX_FILE_PTR fd_ptr, 

    /* [OUT] Buffer to fill with read 512 bytes */
    uchar_ptr buffer, 

    /* [IN] Index of first sector to read */
    uint_32   index,
    
    /* [IN] Number of sectors to read read */
    uint_32   num
)
{
    ESDHC_COMMAND_STRUCT command;
    IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
    SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
    int                  count;
    
    /* Check parameters */
    if ((NULL == sdcard_ptr) || (NULL == sdcard_ptr->COM_DEVICE) || (NULL == sdcard_ptr->INIT) || (NULL == buffer))
    {
        return IO_ERROR;
    }

    /* SD card data address adjustment */
    if (! sdcard_ptr->SDHC)
    {
        index <<= IO_SDCARD_BLOCK_SIZE_POWER;
    }

    /* Read block(s) command */
    if (num > 1)
    {
        command.COMMAND = ESDHC_CMD18;
    }   
    else
    {
        command.COMMAND = ESDHC_CMD17;
    }

    command.ARGUMENT = index;
    command.BLOCKS = num;
    command.BLOCKSIZE = IO_SDCARD_BLOCK_SIZE;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
    {
        return IO_ERROR;
    }

    /* Read data */
    for (count = 0; count < num; count++)
    {
        if (IO_SDCARD_BLOCK_SIZE != fread (buffer, 1, IO_SDCARD_BLOCK_SIZE, sdcard_ptr->COM_DEVICE))
        {
            return IO_ERROR;
        }
        buffer += IO_SDCARD_BLOCK_SIZE;
    }

    /* Wait for transfer complete */
    if (ESDHC_OK != fflush (sdcard_ptr->COM_DEVICE))
    {
        return IO_ERROR;
    }
    
    return count;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_sdcard_esdhc_write_block
* Returned Value   : number of ssuccessfully processed blocks or IO_ERROR
* Comments         :
*    Writes sectors starting with given index to SD card from given buffer.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_esdhc_write_block 
(
    /* [IN] SD card file descriptor */
    MQX_FILE_PTR fd_ptr, 

    /* [IN] Buffer with data to write */
    uchar_ptr buffer, 

    /* [IN] Index of first sector to write */
    uint_32   index,
    
    /* [IN] Number of sectors to be written */
    uint_32   num
)
{
    ESDHC_COMMAND_STRUCT command;
    IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
    SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
    uint_8               tmp[4];
    _mqx_int             count;
    
    /* Check parameters */
    if ((NULL == sdcard_ptr) || (NULL == sdcard_ptr->COM_DEVICE) || (NULL == sdcard_ptr->INIT) || (NULL == buffer))
    {
        return IO_ERROR;
    }

    /* SD card data address adjustment */
    if (! sdcard_ptr->SDHC)
    {
        index <<= IO_SDCARD_BLOCK_SIZE_POWER;
    }

    /* Write block(s) command */
    if (num > 1)
    {
        command.COMMAND = ESDHC_CMD25;
    }
    else
    {
        command.COMMAND = ESDHC_CMD24;
    }

    command.ARGUMENT = index;
    command.BLOCKS = num;
    command.BLOCKSIZE = IO_SDCARD_BLOCK_SIZE;
    if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
    {
        return IO_ERROR;
    }
    
    /* Write data */
    for (count = 0; count < num; count++)
    {
        if (IO_SDCARD_BLOCK_SIZE != fwrite (buffer, 1, IO_SDCARD_BLOCK_SIZE, sdcard_ptr->COM_DEVICE))
        {
            return IO_ERROR;
        }
        buffer += IO_SDCARD_BLOCK_SIZE;
    }

    /* Wait for transfer complete */
    if (ESDHC_OK != fflush (sdcard_ptr->COM_DEVICE))
    {
        return IO_ERROR;
    }
    
    /* Wait for card ready / transaction state */
    do
    {
        command.COMMAND = ESDHC_CMD13;
        command.ARGUMENT = sdcard_ptr->ADDRESS;
        command.BLOCKS = 0;
        if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
        {
            return IO_ERROR;
        }

        /* Card status error check */
        if (command.RESPONSE[0] & 0xFFD98008)
        {
            count = 0; /* necessary to get real number of written blocks */
            break;
        }

    } while (0x000000900 != (command.RESPONSE[0] & 0x00001F00));

    if (count != num)
    {
        /* Application specific command */
        command.COMMAND = ESDHC_CMD55;
        command.ARGUMENT = sdcard_ptr->ADDRESS;
        command.BLOCKS = 0;
        if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
        {
            return IO_ERROR;
        }
                
        /* use ACMD22 to get number of written sectors */
        command.COMMAND = ESDHC_ACMD22;
        command.ARGUMENT = 0;
        command.BLOCKS = 1;
        command.BLOCKSIZE = 4;
        if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))
        {
            return IO_ERROR;
        }
        
        if (4 != fread (tmp, 1, 4, sdcard_ptr->COM_DEVICE))
        {
            return IO_ERROR;
            
        }

        if (ESDHC_OK != fflush (sdcard_ptr->COM_DEVICE))
        {
            return IO_ERROR;
        }

        count = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3];
        if ((count < 0) || (count > num))
            return IO_ERROR;
    }
    
    return count;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/mqxa/pcb_mqxa.h<|end_filename|>
#ifndef __pcb_mqxa_h__
#define __pcb_mqxa_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pcb_mqxa.h$
* $Version : 3.8.4.0$
* $Date    : Oct-11-2011$
*
* Comments:
*
*   This file contains the definitions for the PCB device driver that
*   sends and receives packets over a asynchrnous serial device.  The
*   packets are in MQX IPC async packet format.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                          CONSTANT DECLARATIONS
*/

/*
** Initialization errors
*/
#define IO_PCB_MQXA_DEVICE_ALREADY_OPEN         (IO_PCB_ERROR_BASE|0x90)
#define IO_PCB_MQXA_INCORRECT_SERIAL_DEVICE     (IO_PCB_ERROR_BASE|0x91)

/*
**             PACKET STRUCTURE CONTROL FIELD BIT DEFINITIONS
*/

#define IO_PCB_MQXA_HDR_LITTLE_ENDIAN           (0x40)
#define IO_PCB_MQXA_DATA_LITTLE_ENDIAN          (0x20)

#define IO_PCB_MQXA_HDR_BIG_ENDIAN              (0x00)
#define IO_PCB_MQXA_DATA_BIG_ENDIAN             (0x00)

/*
** ENDIAN
** Indicates in control field of packet the endianness of the packet
*/
#define IO_PCB_MQXA_HDR_ENDIAN_MASK             (0x40)
#define IO_PCB_MQXA_DATA_ENDIAN_MASK            (0x20)

#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
#define IO_PCB_MQXA_HDR_ENDIAN   IO_PCB_MQXA_HDR_LITTLE_ENDIAN
#define IO_PCB_MQXA_DATA_ENDIAN  IO_PCB_MQXA_DATA_LITTLE_ENDIAN
#else
#define IO_PCB_MQXA_HDR_ENDIAN   IO_PCB_MQXA_HDR_BIG_ENDIAN
#define IO_PCB_MQXA_DATA_ENDIAN  IO_PCB_MQXA_DATA_BIG_ENDIAN
#endif

#define IO_PCB_MQX_MUST_CONVERT_HDR_ENDIAN(ctrl) \
   (((ctrl) & IO_PCB_MQXA_HDR_ENDIAN_MASK) != IO_PCB_MQXA_HDR_ENDIAN)

#define IO_PCB_MQX_MUST_CONVERT_DATA_ENDIAN(ctrl) \
   (((ctrl) & IO_PCB_MQXA_DATA_ENDIAN_MASK) != IO_PCB_MQXA_DATA_ENDIAN)

/*--------------------------------------------------------------------------*/
/*
**                          DATATYPE DECLARATIONS
*/

/*
** IO_PCB_MQXA_PACKET_HEADER_STRUCT
** This structure defines what a packet header looks like for this
** MQX protocol.
*/
typedef struct io_pcb_mqxa_packet_header_struct
{
   uint_16 LENGTH;
#ifdef MQX_USE_32BIT_MESSAGE_QIDS
   uint_16 PADD;
   uint_32 ADDR1;
   uint_32 ADDR2;
#else
   uint_16 ADDR;
   uint_16 ADDR2;
#endif
   uchar CONTROL;
#ifdef MQX_USE_32BIT_MESSAGE_QIDS
   uchar RESERVED[3];
#else
   uchar RESERVED[1];
#endif
} IO_PCB_MQXA_PACKET_HEADER_STRUCT, _PTR_ IO_PCB_MQXA_PACKET_HEADER_STRUCT_PTR;

/*
** IO_PCB_MQXA_INIT_STRUCT
** This structure contains the initialization information for the
** async_serial protocol
**
*/
typedef struct io_pcb_mqxa_init_struct
{

   /* The serial interrupt device to use */
   char _PTR_ IO_PORT_NAME;

   /* What baud rate to use */
   uint_32    BAUD_RATE;

   /* Is the IO port polled? */
   boolean    IS_POLLED;

   /* Maximum size of input packet */
   _mem_size  INPUT_MAX_LENGTH;

   /* What priority the tasks are to run at */
   _mqx_uint  INPUT_TASK_PRIORITY;
   _mqx_uint  OUTPUT_TASK_PRIORITY;

} IO_PCB_MQXA_INIT_STRUCT, _PTR_ IO_PCB_MQXA_INIT_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                          C PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _io_pcb_mqxa_install(char _PTR_, pointer);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/CMT_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type CMT
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(CMT_PDD_H_)
#define CMT_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error CMT PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* CMT */ && \
      !defined(MCU_MK10D5) /* CMT */ && \
      !defined(MCU_MK10D7) /* CMT */ && \
      !defined(MCU_MK10F12) /* CMT */ && \
      !defined(MCU_MK10DZ10) /* CMT */ && \
      !defined(MCU_MK11D5) /* CMT */ && \
      !defined(MCU_MK11D5WS) /* CMT */ && \
      !defined(MCU_MK12D5) /* CMT */ && \
      !defined(MCU_MK20D10) /* CMT */ && \
      !defined(MCU_MK20D5) /* CMT */ && \
      !defined(MCU_MK20D7) /* CMT */ && \
      !defined(MCU_MK20F12) /* CMT */ && \
      !defined(MCU_MK20DZ10) /* CMT */ && \
      !defined(MCU_MK21D5) /* CMT */ && \
      !defined(MCU_MK21D5WS) /* CMT */ && \
      !defined(MCU_MK22D5) /* CMT */ && \
      !defined(MCU_MK30D10) /* CMT */ && \
      !defined(MCU_MK30D7) /* CMT */ && \
      !defined(MCU_MK30DZ10) /* CMT */ && \
      !defined(MCU_MK40D10) /* CMT */ && \
      !defined(MCU_MK40D7) /* CMT */ && \
      !defined(MCU_MK40DZ10) /* CMT */ && \
      !defined(MCU_MK40X256VMD100) /* CMT */ && \
      !defined(MCU_MK50D10) /* CMT */ && \
      !defined(MCU_MK50D7) /* CMT */ && \
      !defined(MCU_MK50DZ10) /* CMT */ && \
      !defined(MCU_MK51D10) /* CMT */ && \
      !defined(MCU_MK51D7) /* CMT */ && \
      !defined(MCU_MK51DZ10) /* CMT */ && \
      !defined(MCU_MK52D10) /* CMT */ && \
      !defined(MCU_MK52DZ10) /* CMT */ && \
      !defined(MCU_MK53D10) /* CMT */ && \
      !defined(MCU_MK53DZ10) /* CMT */ && \
      !defined(MCU_MK60D10) /* CMT */ && \
      !defined(MCU_MK60F12) /* CMT */ && \
      !defined(MCU_MK60F15) /* CMT */ && \
      !defined(MCU_MK60DZ10) /* CMT */ && \
      !defined(MCU_MK60N512VMD100) /* CMT */ && \
      !defined(MCU_MK61F12) /* CMT */ && \
      !defined(MCU_MK61F15) /* CMT */ && \
      !defined(MCU_MK61F12WS) /* CMT */ && \
      !defined(MCU_MK61F15WS) /* CMT */ && \
      !defined(MCU_MK70F12) /* CMT */ && \
      !defined(MCU_MK70F15) /* CMT */ && \
      !defined(MCU_MK70F12WS) /* CMT */ && \
      !defined(MCU_MK70F15WS) /* CMT */ && \
      !defined(MCU_PCK20L4) /* CMT */
  // Unsupported MCU is active
  #error CMT PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Enable baseband constants */
#define CMT_PDD_BASEBAND_DISABLED 0U             /**< Disabled */
#define CMT_PDD_BASEBAND_ENABLED  CMT_MSC_BASE_MASK /**< Enabled */

/* Enable FSK constants */
#define CMT_PDD_MODE_TIME_BASEBAND 0U            /**< Time baseband */
#define CMT_PDD_MODE_FSK           CMT_MSC_FSK_MASK /**< FSK */

/* Divider constants */
#define CMT_PDD_DIVIDER_1 0U                     /**< 1 */
#define CMT_PDD_DIVIDER_2 0x1U                   /**< 2 */
#define CMT_PDD_DIVIDER_4 0x2U                   /**< 4 */
#define CMT_PDD_DIVIDER_8 0x3U                   /**< 8 */

/* Prescaler constants */
#define CMT_PDD_PRESCALER_1  0U                  /**< 1 */
#define CMT_PDD_PRESCALER_2  0x1U                /**< 2 */
#define CMT_PDD_PRESCALER_3  0x2U                /**< 3 */
#define CMT_PDD_PRESCALER_4  0x3U                /**< 4 */
#define CMT_PDD_PRESCALER_5  0x4U                /**< 5 */
#define CMT_PDD_PRESCALER_6  0x5U                /**< 6 */
#define CMT_PDD_PRESCALER_7  0x6U                /**< 7 */
#define CMT_PDD_PRESCALER_8  0x7U                /**< 8 */
#define CMT_PDD_PRESCALER_9  0x8U                /**< 9 */
#define CMT_PDD_PRESCALER_10 0x9U                /**< 10 */
#define CMT_PDD_PRESCALER_11 0xAU                /**< 11 */
#define CMT_PDD_PRESCALER_12 0xBU                /**< 12 */
#define CMT_PDD_PRESCALER_13 0xCU                /**< 13 */
#define CMT_PDD_PRESCALER_14 0xDU                /**< 14 */
#define CMT_PDD_PRESCALER_15 0xEU                /**< 15 */
#define CMT_PDD_PRESCALER_16 0xFU                /**< 16 */

/* IRO pin constants */
#define CMT_PDD_PIN_DISABLED 0U                  /**< Disabled */
#define CMT_PDD_PIN_ENABLED  CMT_OC_IROPEN_MASK  /**< Enabled */

/* CMT output polarity constants */
#define CMT_PDD_POLARITY_LOW  0U                 /**< Low */
#define CMT_PDD_POLARITY_HIGH CMT_OC_CMTPOL_MASK /**< High */

/* IRO latch constants */
#define CMT_PDD_LATCH_LOW  0U                    /**< Low */
#define CMT_PDD_LATCH_HIGH CMT_OC_IROL_MASK      /**< High */


/* ----------------------------------------------------------------------------
   -- GetInterruptMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt mask.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      uint8_t result = CMT_PDD_GetInterruptMask(deviceID);
 *      @endcode
 */
#define CMT_PDD_GetInterruptMask(PeripheralBase) ( \
    (uint8_t)(CMT_MSC_REG(PeripheralBase) & CMT_MSC_EOCIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt flag bit.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      uint8_t result = CMT_PDD_GetInterruptFlag(deviceID);
 *      @endcode
 */
#define CMT_PDD_GetInterruptFlag(PeripheralBase) ( \
    (uint8_t)(CMT_MSC_REG(PeripheralBase) & CMT_MSC_EOCF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the CMT interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      CMT_PDD_EnableInterrupt(deviceID);
 *      @endcode
 */
#define CMT_PDD_EnableInterrupt(PeripheralBase) ( \
    CMT_MSC_REG(PeripheralBase) |= \
     CMT_MSC_EOCIE_MASK \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the CMT interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      CMT_PDD_DisableInterrupt(deviceID);
 *      @endcode
 */
#define CMT_PDD_DisableInterrupt(PeripheralBase) ( \
    CMT_MSC_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)CMT_MSC_EOCIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClearInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears CMT interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_MSC, CMT_CMD2
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      CMT_PDD_ClearInterruptFlag(deviceID);
 *      @endcode
 */
#define CMT_PDD_ClearInterruptFlag(PeripheralBase) ( \
    (void)CMT_MSC_REG(PeripheralBase), \
    (void)CMT_CMD2_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- EnableBaseband
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures the freerun mode.
 * @param PeripheralBase Peripheral base address.
 * @param Baseband New value of the baseband. Use constants from group "Enable
 *        baseband constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      CMT_PDD_EnableBaseband(deviceID, CMT_PDD_BASEBAND_DISABLED);
 *      @endcode
 */
#define CMT_PDD_EnableBaseband(PeripheralBase, Baseband) ( \
    CMT_MSC_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(CMT_MSC_REG(PeripheralBase) & (uint8_t)(~(uint8_t)CMT_MSC_BASE_MASK))) | ( \
      (uint8_t)(Baseband))) \
  )

/* ----------------------------------------------------------------------------
   -- SelectFskMode
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures the mode operation.
 * @param PeripheralBase Peripheral base address.
 * @param Mode New value of the mode. Use constants from group "Enable FSK
 *        constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      CMT_PDD_SelectFskMode(deviceID, CMT_PDD_MODE_TIME_BASEBAND);
 *      @endcode
 */
#define CMT_PDD_SelectFskMode(PeripheralBase, Mode) ( \
    CMT_MSC_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(CMT_MSC_REG(PeripheralBase) & (uint8_t)(~(uint8_t)CMT_MSC_FSK_MASK))) | ( \
      (uint8_t)(Mode))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableExtendedSpace
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures extended space.
 * @param PeripheralBase Peripheral base address.
 * @param Extended Extended space enabled/disabled. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      CMT_PDD_EnableExtendedSpace(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define CMT_PDD_EnableExtendedSpace(PeripheralBase, Extended) ( \
    CMT_MSC_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(CMT_MSC_REG(PeripheralBase) & (uint8_t)(~(uint8_t)CMT_MSC_EXSPC_MASK))) | ( \
      (uint8_t)((uint8_t)(Extended) << CMT_MSC_EXSPC_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableDevice
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the CMT device.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of CMT device. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      CMT_PDD_EnableDevice(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define CMT_PDD_EnableDevice(PeripheralBase, State) ( \
    CMT_MSC_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(CMT_MSC_REG(PeripheralBase) & (uint8_t)(~(uint8_t)CMT_MSC_MCGEN_MASK))) | ( \
      (uint8_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetEnableDeviceStatus
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns current state of CMT device.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      uint8_t result = CMT_PDD_GetEnableDeviceStatus(deviceID);
 *      @endcode
 */
#define CMT_PDD_GetEnableDeviceStatus(PeripheralBase) ( \
    (uint8_t)(CMT_MSC_REG(PeripheralBase) & CMT_MSC_MCGEN_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetDivider
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets clock divide prescale value.
 * @param PeripheralBase Peripheral base address.
 * @param Divider New value of the divider. Use constants from group "Divider
 *        constants". This parameter is 2 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_MSC.
 * @par Example:
 *      @code
 *      CMT_PDD_SetDivider(deviceID, CMT_PDD_DIVIDER_1);
 *      @endcode
 */
#define CMT_PDD_SetDivider(PeripheralBase, Divider) ( \
    CMT_MSC_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(CMT_MSC_REG(PeripheralBase) & (uint8_t)(~(uint8_t)CMT_MSC_CMTDIV_MASK))) | ( \
      (uint8_t)((uint8_t)(Divider) << CMT_MSC_CMTDIV_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetPrescaler
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets primary prescale value.
 * @param PeripheralBase Peripheral base address.
 * @param Prescaler New value of the prescaler. Use constants from group
 *        "Prescaler constants". This parameter is 4 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_PPS.
 * @par Example:
 *      @code
 *      CMT_PDD_SetPrescaler(deviceID, CMT_PDD_PRESCALER_1);
 *      @endcode
 */
#define CMT_PDD_SetPrescaler(PeripheralBase, Prescaler) ( \
    CMT_PPS_REG(PeripheralBase) = \
     (uint8_t)(Prescaler) \
  )

/* ----------------------------------------------------------------------------
   -- EnableIroPin
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables IRO signal.
 * @param PeripheralBase Peripheral base address.
 * @param Pin New value of the IROpin. Use constants from group "IRO pin
 *        constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_OC.
 * @par Example:
 *      @code
 *      CMT_PDD_EnableIroPin(deviceID, CMT_PDD_PIN_DISABLED);
 *      @endcode
 */
#define CMT_PDD_EnableIroPin(PeripheralBase, Pin) ( \
    CMT_OC_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(CMT_OC_REG(PeripheralBase) & (uint8_t)(~(uint8_t)CMT_OC_IROPEN_MASK))) | ( \
      (uint8_t)(Pin))) \
  )

/* ----------------------------------------------------------------------------
   -- SetPolarity
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures CMT output polarity.
 * @param PeripheralBase Peripheral base address.
 * @param Polarity New value of the polarity. Use constants from group "CMT
 *        output polarity constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_OC.
 * @par Example:
 *      @code
 *      CMT_PDD_SetPolarity(deviceID, CMT_PDD_POLARITY_LOW);
 *      @endcode
 */
#define CMT_PDD_SetPolarity(PeripheralBase, Polarity) ( \
    CMT_OC_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(CMT_OC_REG(PeripheralBase) & (uint8_t)(~(uint8_t)CMT_OC_CMTPOL_MASK))) | ( \
      (uint8_t)(Polarity))) \
  )

/* ----------------------------------------------------------------------------
   -- SetLatch
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures IRO latch.
 * @param PeripheralBase Peripheral base address.
 * @param State New value of the latch. Use constants from group "IRO latch
 *        constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_OC.
 * @par Example:
 *      @code
 *      CMT_PDD_SetLatch(deviceID, CMT_PDD_LATCH_LOW);
 *      @endcode
 */
#define CMT_PDD_SetLatch(PeripheralBase, State) ( \
    CMT_OC_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(CMT_OC_REG(PeripheralBase) & (uint8_t)(~(uint8_t)CMT_OC_IROL_MASK))) | ( \
      (uint8_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteHighData1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the CGH1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the CGH1 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_CGH1.
 * @par Example:
 *      @code
 *      CMT_PDD_WriteHighData1Reg(deviceID, 1);
 *      @endcode
 */
#define CMT_PDD_WriteHighData1Reg(PeripheralBase, Value) ( \
    CMT_CGH1_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadHighData1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the CGH1 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: CMT_CGH1.
 * @par Example:
 *      @code
 *      uint8_t result = CMT_PDD_ReadHighData1Reg(deviceID);
 *      @endcode
 */
#define CMT_PDD_ReadHighData1Reg(PeripheralBase) ( \
    CMT_CGH1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteLowData1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the CGL1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the CGL1 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_CGL1.
 * @par Example:
 *      @code
 *      CMT_PDD_WriteLowData1Reg(deviceID, 1);
 *      @endcode
 */
#define CMT_PDD_WriteLowData1Reg(PeripheralBase, Value) ( \
    CMT_CGL1_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadLowData1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the CGL1 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: CMT_CGL1.
 * @par Example:
 *      @code
 *      uint8_t result = CMT_PDD_ReadLowData1Reg(deviceID);
 *      @endcode
 */
#define CMT_PDD_ReadLowData1Reg(PeripheralBase) ( \
    CMT_CGL1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteHighData2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the CGH2 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the CGH2 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_CGH2.
 * @par Example:
 *      @code
 *      CMT_PDD_WriteHighData2Reg(deviceID, 1);
 *      @endcode
 */
#define CMT_PDD_WriteHighData2Reg(PeripheralBase, Value) ( \
    CMT_CGH2_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadHighData2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the CGH2 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: CMT_CGH2.
 * @par Example:
 *      @code
 *      uint8_t result = CMT_PDD_ReadHighData2Reg(deviceID);
 *      @endcode
 */
#define CMT_PDD_ReadHighData2Reg(PeripheralBase) ( \
    CMT_CGH2_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteLowData2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the CGL2 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the CGL2 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_CGL2.
 * @par Example:
 *      @code
 *      CMT_PDD_WriteLowData2Reg(deviceID, 1);
 *      @endcode
 */
#define CMT_PDD_WriteLowData2Reg(PeripheralBase, Value) ( \
    CMT_CGL2_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadLowData2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the CGL2 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: CMT_CGL2.
 * @par Example:
 *      @code
 *      uint8_t result = CMT_PDD_ReadLowData2Reg(deviceID);
 *      @endcode
 */
#define CMT_PDD_ReadLowData2Reg(PeripheralBase) ( \
    CMT_CGL2_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteMarkHighReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the CMD1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the CMD1 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_CMD1.
 * @par Example:
 *      @code
 *      CMT_PDD_WriteMarkHighReg(deviceID, 1);
 *      @endcode
 */
#define CMT_PDD_WriteMarkHighReg(PeripheralBase, Value) ( \
    CMT_CMD1_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteMarkLowReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the CMD2 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the CMD2 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_CMD2.
 * @par Example:
 *      @code
 *      CMT_PDD_WriteMarkLowReg(deviceID, 1);
 *      @endcode
 */
#define CMT_PDD_WriteMarkLowReg(PeripheralBase, Value) ( \
    CMT_CMD2_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteSpaceHighReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the CMD3 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the CMD3 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_CMD3.
 * @par Example:
 *      @code
 *      CMT_PDD_WriteSpaceHighReg(deviceID, 1);
 *      @endcode
 */
#define CMT_PDD_WriteSpaceHighReg(PeripheralBase, Value) ( \
    CMT_CMD3_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteSpaceLowReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the CMD4 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the CMD4 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CMT_CMD4.
 * @par Example:
 *      @code
 *      CMT_PDD_WriteSpaceLowReg(deviceID, 1);
 *      @endcode
 */
#define CMT_PDD_WriteSpaceLowReg(PeripheralBase, Value) ( \
    CMT_CMD4_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )
#endif  /* #if defined(CMT_PDD_H_) */

/* CMT_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi/spi_prv.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_prv.h$
* $Version : 3.8.1.0$
* $Date    : Sep-25-2012$
*
* Comments:
*
*   This file contains definitions private to the SPI driver.
*
*END************************************************************************/

#ifndef __spi_prv_h__
#define __spi_prv_h__

#include "spi.h"


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** Run time state information for SPI driver (shared for all fds)
*/
typedef struct spi_driver_data_struct
{
    /* LWSEM for locking for concurrent access from several tasks */
    LWSEM_STRUCT          BUS_LOCK;

    /* Pointer to low level driver */
    SPI_DEVIF_STRUCT_CPTR DEVIF;

    /* Pointer to runtime data specific for low level driver */
    pointer               DEVIF_DATA;

    /* Default transfer parameters for low level driver */
    SPI_PARAM_STRUCT      PARAMS;

    /* Callback function for external CS handling */
    SPI_CS_CALLBACK       CS_CALLBACK;

    /* Context passed to CS callback function */
    pointer               CS_USERDATA;

} SPI_DRIVER_DATA_STRUCT, _PTR_ SPI_DRIVER_DATA_STRUCT_PTR;


/*
** Context information for open fd
*/
typedef struct spi_dev_data_struct
{
    /* Inidicates that BUS_LOCK is being held by this fd */
    boolean               BUS_OWNER;

    /* Transfer parameters for low level driver */
    SPI_PARAM_STRUCT      PARAMS;

    /* Indicates necessity to re-set parameters before transfer */
    boolean               PARAMS_DIRTY;

    /* Open flags for this channel */
    uint_32               FLAGS;

#if BSPCFG_ENABLE_SPI_STATS
    /* Statistical information */
    SPI_STATISTICS_STRUCT STATS;
#endif

} SPI_DEV_DATA_STRUCT, _PTR_ SPI_DEV_DATA_STRUCT_PTR;


#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mpxs20.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mpxs20.c$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the default initialization record for the
*   flash device. The 8313e-rdb uses a Spansion 29lv640 The
*   8323e-rdb uses a Intel Strata 28f128j3.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "flashx.h"
#include "flash_c90.h"
#include "flash_c90_prv.h"


const FLASHX_BLOCK_INFO_STRUCT _mpxs20_block_map[] =
{
    /* count, address, size */

    /* LAS */
    { 1,        0,  0x4000, C90_ASPACE_LAS|C90_WIDTH_128|C90_ALIGN_64 }, /* L0       16 KB */
    { 2,  0x04000,  0xC000, C90_ASPACE_LAS|C90_WIDTH_128|C90_ALIGN_64 }, /* L1..L2 2*48 KB */
    { 1,  0x1C000,  0x4000, C90_ASPACE_LAS|C90_WIDTH_128|C90_ALIGN_64 }, /* L3       16 KB */
    { 2,  0x20000, 0x10000, C90_ASPACE_LAS|C90_WIDTH_128|C90_ALIGN_64 }, /* L4..L5 2*64 KB */

    /* MAS */
    { 2,  0x40000, 0x20000, C90_ASPACE_MAS|C90_WIDTH_128|C90_ALIGN_64 }, /* M0..M1 2*128 KB */

    /* HAS */
    { 2,  0x80000, 0x40000, C90_ASPACE_HAS|C90_WIDTH_128|C90_ALIGN_64 }, /* H0..H1 2*256 KB */

    /* Shadow row */
    { 1, 0xF00000,  0x4000, C90_ASPACE_SHADOW|C90_WIDTH_128|C90_ALIGN_64 }, /* shadow row, 16 KB */

    { 0, 0, 0 }
};


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_c90_address
* Returned Value   : Address upon success
* Comments         :
*    This function returns the base register address of the C90 flash controller.
*
*END*----------------------------------------------------------------------*/

pointer _bsp_get_c90_address (uint_32 base_addr)
{
    return (pointer)MPXS20_FLASH0_BASE;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcs.h<|end_filename|>
#ifndef __rtcs_h__
#define __rtcs_h__
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcs.h$
* $Version : 3.8.42.0$
* $Date    : Oct-1-2012$
*
* Comments:
*
*   This file contains the defines, externs and data
*   structure definitions required by application
*   programs in order to use the RTCS Communication Library.
*
*END************************************************************************/

#include <rtcsvers.h>
#include <rtcsrtos.h>
#include <rtcslog.h>
#include <rtcs_in.h>
#include <string.h>

/*
** Constants
*/

/*
** Protocols for the RTCS_protocol_table[]
*/
#define RTCSPROT_IGMP   IGMP_init
#define RTCSPROT_UDP    UDP_init
#define RTCSPROT_TCP    TCP_Init
#define RTCSPROT_RIP    RIP_init
#define RTCSPROT_OSPF   OSPF_init
#define RTCSPROT_IPIP   IPIP_init

/*
** Protocol and Address families
*/
#define PF_INET         1
#define AF_UNSPEC       0
#define AF_INET         1

#define AF_INET6         28         /* IPv6 */
#define PF_INET6         AF_INET6   /* Same as the address family. */

/*
 * Flag values for getaddrinfo()
 */
#define	AI_PASSIVE	    0x00000001 /* get address to use bind() */
#define	AI_CANONNAME	0x00000002 /* fill ai_canonname */
#define	AI_NUMERICHOST	0x00000004 /* prevent host name resolution */

/*
** Socket types
*/
#define SOCK_DGRAM      ((uint_32)&SOCK_DGRAM_CALL)
#define SOCK_STREAM     ((uint_32)&SOCK_STREAM_CALL)

/*
** Validity check for socket structures
*/
#define SOCKET_VALID       0x52544353  /* "rtcs" */

/*
** Default number of tasks that can simultaneously own a socket
*/
#define SOCKET_NUMOWNERS   8

/*
** protocol level at which option resides
*/
#define SOL_SOCKET      ((uint_32)&SOL_SOCKET_CALL)
#define SOL_IP          ((uint_32)&SOL_IP_CALL)
#define SOL_UDP         ((uint_32)&SOL_UDP_CALL)
#define SOL_TCP         ((uint_32)&SOL_TCP_CALL)
#define SOL_IGMP        ((uint_32)&SOL_IGMP_CALL)
#define SOL_LINK        ((uint_32)&SOL_LINK_CALL)
#define SOL_NAT         ((uint_32)&SOL_NAT_CALL)



/*
**   socket option ids
*/
#define OPT_CONNECT_TIMEOUT            (0x01)
#define OPT_RETRANSMISSION_TIMEOUT     (0x02)
#define OPT_SEND_TIMEOUT               (0x03)
#define OPT_RECEIVE_TIMEOUT            (0x04)
#define OPT_RECEIVE_PUSH               (0x05)
#define OPT_SEND_NOWAIT                (0x06)
#define OPT_SEND_WAIT_OBSOLETE         (0x07) /* obsolete */
#define OPT_SEND_PUSH                  (0x08)
#define OPT_RECEIVE_NOWAIT             (0x09)
#define OPT_CHECKSUM_BYPASS            (0x0A)
#define OPT_ACTIVE                     (0x0B)
#define OPT_TBSIZE                     (0x0C)
#define OPT_RBSIZE                     (0x0D)
#define OPT_MAXRTO                     (0x0E)
#define OPT_MAXRCV_WND                 (0x0F)
#define OPT_KEEPALIVE                  (0x10)
#define OPT_NOWAIT                     (0x11)
#define OPT_NO_NAGLE_ALGORITHM         (0x12)
#define OPT_NOSWRBUF                   (0x13)
#define OPT_CALL_BACK_OBSOLETE         (0x14) /* obsolete */
#define OPT_SOCKET_TYPE                (0x15)
#define OPT_CALLBACK                   (0x16)
#define OPT_TIMEWAIT_TIMEOUT           (0x17)
#define OPT_TCPSECUREDRAFT_0           (0x18)
#define OPT_DELAY_ACK                  (0x19)

#define OPT_SOCKET_ERROR               (0x1c)

/*
**   default option values
*/
#define DEFAULT_CONNECT_TIMEOUT        (480000L)   /* 8 mins */
#define DEFAULT_RETRANSMISSION_TIMEOUT (3000)      /* 3 sec  */
#define DEFAULT_SEND_TIMEOUT           (DEFAULT_CONNECT_TIMEOUT/2)
#define DEFAULT_RECEIVE_TIMEOUT        (0)         /* no timeout */
#define DEFAULT_NOWAIT                 FALSE
#define DEFAULT_SEND_NOWAIT            FALSE
#define DEFAULT_SEND_WAIT              FALSE
#define DEFAULT_RECEIVE_NOWAIT         FALSE
#define DEFAULT_WAIT                   FALSE       /* don't wait for ack */
#define DEFAULT_PUSH                   TRUE        /* push */
#define DEFAULT_CHECKSUM_BYPASS        FALSE       /* perform checksum */
#define DEFAULT_ACTIVE                 TRUE
#define DEFAULT_TBSIZE                 (-1)
#define DEFAULT_RBSIZE                 (-1)
#define DEFAULT_MAXRTO                 (0)
#define DEFAULT_MAXRCV_WND             (0)
#define DEFAULT_KEEPALIVE              (0)
#define DEFAULT_NO_NAGLE_ALGORITHM     FALSE
#define DEFAULT_NOSWRBUF               FALSE
#define DEFAULT_CALL_BACK              NULL
#define DEFAULT_CALLBACK               NULL
#define DEFAULT_TIMEWAIT_TIMEOUT       (2*1000) /* msec */ /* 0 = default 4 mins.*/
#define DEFAULT_TCPSECUREDRAFT_0       FALSE
#define DEFAULT_DELAY_ACK               (TCP_ACKDELAY)


/*
** Socket options
*/
#define RTCS_SO_TYPE                   OPT_SOCKET_TYPE
#define RTCS_SO_ERROR                  OPT_SOCKET_ERROR

#define RTCS_SO_IGMP_ADD_MEMBERSHIP    0
#define RTCS_SO_IGMP_DROP_MEMBERSHIP   1
#define RTCS_SO_IGMP_GET_MEMBERSHIP    2

#define RTCS_SO_IP_RX_DEST             0
#define RTCS_SO_IP_RX_TTL              1
#define RTCS_SO_IP_RX_TOS              2
#define RTCS_SO_IP_TX_TTL              3
#define RTCS_SO_IP_LOCAL_ADDR          4
#define RTCS_SO_IP_TX_TOS              5

#define RTCS_SO_LINK_TX_8023           0
#define RTCS_SO_LINK_TX_8021Q_PRIO     1
#define RTCS_SO_LINK_RX_8023           2
#define RTCS_SO_LINK_RX_8021Q_PRIO     3

#define RTCS_SO_UDP_NONBLOCK           OPT_SEND_NOWAIT
#define RTCS_SO_UDP_NONBLOCK_TX        OPT_SEND_NOWAIT
#define RTCS_SO_UDP_NONBLOCK_RX        OPT_RECEIVE_NOWAIT
#define RTCS_SO_UDP_NOCHKSUM           OPT_CHECKSUM_BYPASS

#define RTCS_SO_NAT_TIMEOUTS           0
#define RTCS_SO_NAT_PORTS              1

/*
** Flags for send[to]/recv[from]
*/
#define RTCS_MSG_O_NONBLOCK   0x0001
#define RTCS_MSG_S_NONBLOCK   0x0002
#define RTCS_MSG_BLOCK        (RTCS_MSG_O_NONBLOCK)
#define RTCS_MSG_NONBLOCK     (RTCS_MSG_O_NONBLOCK | RTCS_MSG_S_NONBLOCK)
#define RTCS_MSG_O_NOCHKSUM   0x0004
#define RTCS_MSG_S_NOCHKSUM   0x0008
#define RTCS_MSG_CHKSUM       (RTCS_MSG_O_NOCHKSUM)
#define RTCS_MSG_NOCHKSUM     (RTCS_MSG_O_NOCHKSUM | RTCS_MSG_S_NOCHKSUM)
#define RTCS_MSG_PEEK         0x0010
#define RTCS_MSG_NOLOOP       0x0020

/*
** Flags for logging
*/
#define RTCS_LOGCTRL_FUNCTION    0x00000001
#define RTCS_LOGCTRL_PCB         0x00000002
#define RTCS_LOGCTRL_TIMER       0x00000004
#define RTCS_LOGCTRL_ALL         0x00000007

#define RTCS_LOGCTRL_IFTYPE(p)   ((p) & 0x3FF)
#define RTCS_LOGCTRL_ARP(p)      ((p) & 0x3FF | 0x4000)
#define RTCS_LOGCTRL_PROTO(p)    ((p) & 0x3FF | 0x8000)
#define RTCS_LOGCTRL_PORT(p)     ((p) & 0x3FF | 0xC000)

/*
** Close methods for shutdown()
*/
#define FLAG_ABORT_CONNECTION       (0x0010)
#define FLAG_CLOSE_TX               (0x0001)


/*
** Options for RTCS_load()
*/
#define RTCSLOADOPT_EXEC      0x01


/*
** Modes for the FTP client
*/
#define FTPMODE_DEFAULT 1
#define FTPMODE_PORT    2
#define FTPMODE_PASV    3
#define FTPDIR_RECV     0
#define FTPDIR_SEND     4


/*
** Successful return code.  No errors.
*/
#define RTCS_OK                     0
#define RTCS_ERROR                  (-1)
#define RTCS_HANDLE_ERROR           (0xffffffffL)
#define RTCS_SOCKET_ERROR           (0xffffffffL)


/*
** RTCS Error Code Definitions
*/

/*
** Generic Error codes
*/
#define RTCSERR_OUT_OF_MEMORY           (RTCS_ERROR_BASE|0x102)
#define RTCSERR_TIMEOUT                 (RTCS_ERROR_BASE|0x103)
#define RTCSERR_INVALID_ADDRESS         (RTCS_ERROR_BASE|0x104)
#define RTCSERR_INVALID_PARAMETER       (RTCS_ERROR_BASE|0x105)
#define RTCSERR_READ_ABORTED            (RTCS_ERROR_BASE|0x11f)
#define RTCSERR_OUT_OF_BUFFERS          (RTCS_ERROR_BASE|0x120)
#define RTCSERR_CREATE_PARTITION_FAILED (RTCS_ERROR_BASE|0x121)
#define RTCSERR_OUT_OF_SOCKETS          (RTCS_ERROR_BASE|0x122)
#define RTCSERR_FOPEN_FAILED            (RTCS_ERROR_BASE|0x123)
#define RTCSERR_FEATURE_NOT_ENABLED     (RTCS_ERROR_BASE|0x124)
#define RTCSERR_SEND_FAILED             (RTCS_ERROR_BASE|0x132)
#define RTCSERR_CREATE_POOL_FAILED      (RTCS_ERROR_BASE|0x135)
#define RTCSERR_OPEN_QUEUE_FAILED       (RTCS_ERROR_BASE|0x136)
#define RTCSERR_CREATE_FAILED           (RTCS_ERROR_BASE|0x137)
#define RTCSERR_RECEIVE_FAILED          (RTCS_ERROR_BASE|0x138)
#define RTCSERR_DEALLOC_FAILED          (RTCS_ERROR_BASE|0x139)
#define RTCSERR_SERVER_ALREADY_RUNNING  (RTCS_ERROR_BASE|0x140)
#define RTCSERR_SERVER_NOT_RUNNING      (RTCS_ERROR_BASE|0x141)

/*
** PPP error codes
*/
#define PPP_OK                                RTCS_OK
#define RTCSERR_PPP_ALLOC_FAILED              (RTCS_ERROR_BASE|0x200)
#define RTCSERR_PPP_INIT_MUTEX_FAILED         (RTCS_ERROR_BASE|0x201)
#define RTCSERR_PPP_CREATE_CTRL_POOL_FAILED   (RTCS_ERROR_BASE|0x202)
#define RTCSERR_PPP_CREATE_PKT_POOL_FAILED    (RTCS_ERROR_BASE|0x203)
#define RTCSERR_PPP_CREATE_RX_FAILED          (RTCS_ERROR_BASE|0x204)
#define RTCSERR_PPP_CREATE_TX_FAILED          (RTCS_ERROR_BASE|0x205)
#define RTCSERR_PPP_INVALID_CALLBACK          (RTCS_ERROR_BASE|0x206)
#define RTCSERR_PPP_INVALID_HANDLE            (RTCS_ERROR_BASE|0x240)
#define RTCSERR_PPP_LINK_NOT_OPEN             (RTCS_ERROR_BASE|0x241)
#define RTCSERR_PPP_PACKET_TOO_SHORT          (RTCS_ERROR_BASE|0x242)
#define RTCSERR_PPP_PACKET_TOO_LONG           (RTCS_ERROR_BASE|0x243)
#define RTCSERR_PPP_OUT_OF_BUFFERS            (RTCS_ERROR_BASE|0x244)
#define RTCSERR_PPP_INVALID_PROTOCOL          (RTCS_ERROR_BASE|0x245)
#define RTCSERR_PPP_ALLOC_CALL_FAILED         (RTCS_ERROR_BASE|0x246)
#define RTCSERR_PPP_PROT_NOT_FOUND            (RTCS_ERROR_BASE|0x247)
#define RTCSERR_PPP_FSM_ACTIVE                (RTCS_ERROR_BASE|0x280)
#define RTCSERR_PPP_OPEN_QUEUE_FAILED         (RTCS_ERROR_BASE|0x2C0)

/*
** Initialization failures
*/
#define RTCSERR_INITIALIZED      (RTCS_ERROR_BASE|0x300)    /* RTCS already initialized */

/*
** PCB module errors
*/
#define RTCSERR_PCB_ALLOC        (RTCS_ERROR_BASE|0x310)    /* couldn't allocate PCBs         */
#define RTCSERR_PCB_FORK         (RTCS_ERROR_BASE|0x311)    /* PCB already forked             */
#define RTCSERR_PCB_LAYER        (RTCS_ERROR_BASE|0x312)    /* too few PCB layers             */
#define RTCSERR_PCB_BUFFER       (RTCS_ERROR_BASE|0x313)    /* PCB buffer too small           */
#define RTCSERR_PCB_FRAG         (RTCS_ERROR_BASE|0x314)    /* too few PCB fragments          */
#define RTCSERR_PCB_NOFRAG       (RTCS_ERROR_BASE|0x315)    /* can't add fragment (must fork) */
#define RTCSERR_PCB_DEPEND       (RTCS_ERROR_BASE|0x316)    /* can't create dependency        */

/*
** ARP errors
*/
#define RTCSERR_ARP_CFG          (RTCS_ERROR_BASE|0x400)    /* couldn't allocate state       */
#define RTCSERR_ARP_CACHE        (RTCS_ERROR_BASE|0x401)    /* couldn't allocate cache entry */
#define RTCSERR_ARP_CANT_RESOLVE (RTCS_ERROR_BASE|0x402)    /* couldn't resolve address      */
#define RTCSERR_ARP_BAD_HEADER   (RTCS_ERROR_BASE|0x403)    /* error in header               */

/*
** IPCP errors
*/
#define RTCSERR_IPCP_CFG         (RTCS_ERROR_BASE|0x410)    /* couldn't allocate state */

/*
** IP errors
*/
#define RTCSERR_IP_ICB_ALLOC     (RTCS_ERROR_BASE|0x500)    /* couldn't allocate ICB       */
#define RTCSERR_IP_PROT_OPEN     (RTCS_ERROR_BASE|0x501)    /* protocol already open       */
#define RTCSERR_IP_IF_ALLOC      (RTCS_ERROR_BASE|0x502)    /* couldn't allocate interface */
#define RTCSERR_IP_ROUTE_ALLOC   (RTCS_ERROR_BASE|0x503)    /* couldn't allocate route     */
#define RTCSERR_IP_GATE_ALLOC    (RTCS_ERROR_BASE|0x504)    /* couldn't allocate gateway   */
#define RTCSERR_IP_BIND_ADDR     (RTCS_ERROR_BASE|0x505)    /* invalid local address       */
#define RTCSERR_IP_BIND_MASK     (RTCS_ERROR_BASE|0x506)    /* invalid network mask        */
#define RTCSERR_IP_SEC_ALLOC     (RTCS_ERROR_BASE|0x507)    /* couldn't allocate SPD node   */
#define RTCSERR_IP_VIRTUAL_ALLOC (RTCS_ERROR_BASE|0x508)    /* couldn't alloc virtual route */

/*
** IP datagram processing failures
*/
#define RTCSERR_IP_UNREACH       (RTCS_ERROR_BASE|0x510)    /* no route to host            */
#define RTCSERR_IP_TTL           (RTCS_ERROR_BASE|0x511)    /* TTL expired                 */
#define RTCSERR_IP_SMALLMTU      (RTCS_ERROR_BASE|0x512)    /* packet exceeds MTU          */
#define RTCSERR_IP_CANTFRAG      (RTCS_ERROR_BASE|0x513)    /* need to fragment but DF set */
#define RTCSERR_IP_BAD_HEADER    (RTCS_ERROR_BASE|0x514)    /* error in header             */
#define RTCSERR_IP_BAD_ADDRESS   (RTCS_ERROR_BASE|0x515)    /* illegal source or dest      */
#define RTCSERR_IP_BAD_CHECKSUM  (RTCS_ERROR_BASE|0x516)    /* invalid checksum            */

/*
** IPIP errors
*/
#define RTCSERR_IPIP_NOT_INITIALIZED   (RTCS_ERROR_BASE|0x550)   /* IPIP not initialized      */
#define RTCSERR_IPIP_LOOP              (RTCS_ERROR_BASE|0x551)   /* received a packet we sent */

/*
** ICMP errors
*/
#define RTCSERR_ICMP_ECHO_TIMEOUT   (RTCS_ERROR_BASE|0x580) /* timed out waiting for echo reply */
#define RTCSERR_ICMP_BAD_HEADER     (RTCS_ERROR_BASE|0x581) /* error in header                  */
#define RTCSERR_ICMP_BAD_CHECKSUM   (RTCS_ERROR_BASE|0x582) /* invalid checksum                 */

/*
** IGMP errors
*/
#define RTCSERR_IGMP_CFG            (RTCS_ERROR_BASE|0x5C0) /* couldn't allocate state        */
#define RTCSERR_IGMP_GROUP_ALLOC    (RTCS_ERROR_BASE|0x5C1) /* couldn't allocate MCB          */
#define RTCSERR_IGMP_GROUP_FREE     (RTCS_ERROR_BASE|0x5C2) /* couldn't free MCB              */
#define RTCSERR_IGMP_INVALID_IP     (RTCS_ERROR_BASE|0x5C3) /* can't join group (nonlocal IP) */
#define RTCSERR_IGMP_NOT_JOINED     (RTCS_ERROR_BASE|0x5C4) /* can't leave group (not joined) */
#define RTCSERR_IGMP_BAD_HEADER     (RTCS_ERROR_BASE|0x5C5) /* error in header                */
#define RTCSERR_IGMP_BAD_CHECKSUM   (RTCS_ERROR_BASE|0x5C6 )/* invalid checksum               */

/*
** UDP errors
*/
#define RTCSERR_UDP_UCB_ALLOC    (RTCS_ERROR_BASE|0x660)    /* couldn't allocate UCB */
#define RTCSERR_UDP_UCB_FREE     (RTCS_ERROR_BASE|0x661)    /* couldn't free UCB     */
#define RTCSERR_UDP_UCB_CLOSE    (RTCS_ERROR_BASE|0x662)    /* UCB not open          */
#define RTCSERR_UDP_PORT_OPEN    (RTCS_ERROR_BASE|0x663)    /* port already open     */
#define RTCSERR_UDP_PORT_ALLOC   (RTCS_ERROR_BASE|0x664)    /* no more ports         */
#define RTCSERR_UDP_PORT_ZERO    (RTCS_ERROR_BASE|0x665)    /* can't send to port 0  */
#define RTCSERR_UDP_BAD_HEADER   (RTCS_ERROR_BASE|0x666)    /* error in header       */
#define RTCSERR_UDP_BAD_CHECKSUM (RTCS_ERROR_BASE|0x667)    /* invalid checksum      */
#define RTCSERR_UDP_SOCKET_CLOSE (RTCS_ERROR_BASE|0x668)    /* socket closed by tasks other than waiting task */


/*
** TCPIP error codes
*/
#define RTCSERR_TCPIP_INVALID_ARGUMENT  (RTCS_ERROR_BASE|0x610)  /* Invalid argument            */
#define RTCSERR_TCPIP_DESTADDR_REQUIRED (RTCS_ERROR_BASE|0x611)  /* Destination address         */
                                                                 /*    required                 */
#define RTCSERR_TCPIP_NO_BUFFS          (RTCS_ERROR_BASE|0x612)  /* No buffer space available   */
#define RTCSERR_TCPIP_DELAY_REQUESTED   (RTCS_ERROR_BASE|0x613)  /* TCP_Delay() called, but not */
                                                                 /*    supported                */
#define RTCSERR_TCPIP_TIMER_CORRUPT     (RTCS_ERROR_BASE|0x614)  /* Corrupt timer pointers      */

/*
** TCP error codes
*/
#define RTCSERR_TCP_OPEN_FAILED         (RTCS_ERROR_BASE|0x630)  /* TcpOpen failed              */
#define RTCSERR_TCP_INVALID_OPTION      (RTCS_ERROR_BASE|0x631)  /* Option was invalid          */
#define RTCSERR_TCP_IN_PROGRESS         (RTCS_ERROR_BASE|0x632)  /* Operation already in        */
                                                                 /*    progress                 */
#define RTCSERR_TCP_ADDR_IN_USE         (RTCS_ERROR_BASE|0x633)  /* Address already in use      */
#define RTCSERR_TCP_ADDR_NA             (RTCS_ERROR_BASE|0x634)  /* Can't assign requested      */
                                                                 /*    address                  */
#define RTCSERR_TCP_CONN_ABORTED        (RTCS_ERROR_BASE|0x635)  /* Software caused connection  */
                                                                 /*    abort                    */
#define RTCSERR_TCP_CONN_RESET          (RTCS_ERROR_BASE|0x636)  /* Connection reset by peer    */
#define RTCSERR_TCP_HOST_DOWN           (RTCS_ERROR_BASE|0x637)  /* Host is down                */
#define RTCSERR_TCP_CONN_CLOSING        (RTCS_ERROR_BASE|0x638)  /* Connection closing          */
#define RTCSERR_TCP_CONN_RLSD           (RTCS_ERROR_BASE|0x639)  /* Connection/TCB released     */
#define RTCSERR_TCP_MISSING_OPEN        (RTCS_ERROR_BASE|0x63A)  /* TCB exists in LISTEN state  */
                                                                 /*    with no associated Listn */
                                                                 /*    request from upper layer */
#define RTCSERR_TCP_CTR_ZERO_RSIZE      (RTCS_ERROR_BASE|0x63B)  /* TCP_Copy_to_ring got 0      */
                                                                 /*    ring buf size            */
#define RTCSERR_TCP_SP_BAD_SEND_STATE   (RTCS_ERROR_BASE|0x63C)  /* Attempted to TCP_Send_packet*/
                                                                 /*    in invalid state         */
#define RTCSERR_TCP_SP_OUT_OF_PCBS      (RTCS_ERROR_BASE|0x63D)  /* Could not get a PCB in      */
                                                                 /*    TCP_Send_packet          */
#define RTCSERR_TCP_SRR_OUT_OF_PCBS     (RTCS_ERROR_BASE|0x63E)  /* Could not get a PCB in      */
                                                                 /*    TCP_Send_reply_reset     */
#define RTCSERR_TCP_SR_OUT_OF_PCBS      (RTCS_ERROR_BASE|0x63F)  /* Could not get a PCB in      */
                                                                 /*    TCP_Send_reset           */
#define RTCSERR_TCP_SHRINKER_HOST       (RTCS_ERROR_BASE|0x640)  /* TCP detected a 'shrinker'   */
                                                                 /*    peer host                */
#define RTCSERR_TCP_PA_BUFF_CORRUPT     (RTCS_ERROR_BASE|0x642)  /* TCP send buffer corruption  */
                                                                 /*    detected in TCP_Process_ack   */
#define RTCSERR_TCP_PS_FAILED_GET_SBUF  (RTCS_ERROR_BASE|0x643)  /* Could not get an SbufNode   */
                                                                 /*    in TCP_Process_send      */
#define RTCSERR_TCP_PR_OUT_OF_MEM       (RTCS_ERROR_BASE|0x644)  /* Could not get a Rcvchunk    */
                                                                 /*    buffer in Setup Receive  */
#define RTCSERR_TCP_PP_OUT_OF_MEM       (RTCS_ERROR_BASE|0x645)  /* Could not add a host IpList */
                                                                 /*    node in TCP_Process_packet    */
#define RTCSERR_TCP_TIMER_FAILURE       (RTCS_ERROR_BASE|0x646)  /* Could not start a TCP timer */
#define RTCSERR_TCP_NOT_CONN            (RTCS_ERROR_BASE|0x647)  /* Socket is not connected     */
#define RTCSERR_TCP_SHUTDOWN            (RTCS_ERROR_BASE|0x648)  /* Can't send after socket     */
                                                                 /*    shutdown                 */
#define RTCSERR_TCP_TIMED_OUT           (RTCS_ERROR_BASE|0x649)  /* Connection timed out        */
#define RTCSERR_TCP_CONN_REFUSED        (RTCS_ERROR_BASE|0x64A)  /* Connection refused          */
#define RTCSERR_TCP_NO_MORE_PORTS       (RTCS_ERROR_BASE|0x64B)  /* No more ports available     */
                                                                 /*    for connections          */
#define RTCSERR_TCP_BAD_STATE_FOR_CLOSE (RTCS_ERROR_BASE|0x64C)  /* Attempted to call           */
                                                                 /*    TCP_Process_effective_close or */
                                                                 /*    TCP_Process_close in invalid  */
                                                                 /*    state                    */
#define RTCSERR_TCP_BAD_STATE_FOR_REL   (RTCS_ERROR_BASE|0x64D)  /* Attempted to release a TCB  */
                                                                 /*    in an invalid state      */
#define RTCSERR_TCP_REXMIT_PROBLEM      (RTCS_ERROR_BASE|0x64E)  /* A retransmission timer      */
                                                                 /*    timed out while in IDLE  */
                                                                 /*    mode (i.e. invalid)      */
#define RTCSERR_TCP_URGENT_DATA_PROB    (RTCS_ERROR_BASE|0x64F)  /* Urgent data pointer         */
                                                                 /*    was corrupted in the tcb */
#define RTCSERR_TCP_DEALLOC_FAILED      (RTCS_ERROR_BASE|0x650)  /* A call to release memory failed   */
#define RTCSERR_TCP_HOST_UNREACH        (RTCS_ERROR_BASE|0x651)  /* No route to host            */
#define RTCSERR_TCP_BAD_HEADER          (RTCS_ERROR_BASE|0x652)  /* error in header             */
#define RTCSERR_TCP_BAD_CHECKSUM        (RTCS_ERROR_BASE|0x653)  /* invalid checksum            */

/*
** Socket error codes
*/
#define RTCSERR_SOCK_INVALID        (RTCS_ERROR_BASE|0x704)
#define RTCSERR_SOCK_INVALID_AF     (RTCS_ERROR_BASE|0x702)
#define RTCSERR_SOCK_SHORT_ADDRESS  (RTCS_ERROR_BASE|0x706)
#define RTCSERR_SOCK_NOT_SUPPORTED  (RTCS_ERROR_BASE|0x719)
#define RTCSERR_SOCK_INVALID_OPTION (RTCS_ERROR_BASE|0x71A)
#define RTCSERR_SOCK_SHORT_OPTION   (RTCS_ERROR_BASE|0x71B)
#define RTCSERR_SOCK_NOT_BOUND      (RTCS_ERROR_BASE|0x709)
#define RTCSERR_SOCK_IS_BOUND       (RTCS_ERROR_BASE|0x705)
#define RTCSERR_SOCK_NOT_LISTENING  (RTCS_ERROR_BASE|0x70C)
#define RTCSERR_SOCK_IS_LISTENING   (RTCS_ERROR_BASE|0x70B)
#define RTCSERR_SOCK_NOT_CONNECTED  (RTCS_ERROR_BASE|0x70D)
#define RTCSERR_SOCK_IS_CONNECTED   (RTCS_ERROR_BASE|0x70A)
#define RTCSERR_SOCK_NOT_OWNER      (RTCS_ERROR_BASE|0x70E)
#define RTCSERR_SOCK_CLOSED         (RTCS_ERROR_BASE|0x70F)

/*
** RTCS_load() TFTP errors
*/
#define RTCSERR_TFTP_SOCKET         (RTCS_ERROR_BASE|0x800)
#define RTCSERR_TFTP_BIND           (RTCS_ERROR_BASE|0x801)
#define RTCSERR_TFTP_RRQ_ALLOC      (RTCS_ERROR_BASE|0x802)
#define RTCSERR_TFTP_RRQ_SEND       (RTCS_ERROR_BASE|0x803)
#define RTCSERR_TFTP_TIMEOUT        (RTCS_ERROR_BASE|0x804)
#define RTCSERR_TFTP_ERROR          (RTCS_ERROR_BASE|0x810)

/*
** RTCS_load() decoder errors
*/

#define RTCSERR_SREC_CHAR           (RTCS_ERROR_BASE|0x880)
#define RTCSERR_SREC_RECORD         (RTCS_ERROR_BASE|0x881)
#define RTCSERR_SREC_SHORT          (RTCS_ERROR_BASE|0x882)
#define RTCSERR_SREC_CHECKSUM       (RTCS_ERROR_BASE|0x883)
#define RTCSERR_SREC_START          (RTCS_ERROR_BASE|0x884)
#define RTCSERR_SREC_END            (RTCS_ERROR_BASE|0x885)
#define RTCSERR_SREC_EOF            (RTCS_ERROR_BASE|0x886)
#define RTCSERR_SREC_ERROR          (RTCS_ERROR_BASE|0x887)

#define RTCSERR_COFF_BAD_MAGIC      (RTCS_ERROR_BASE|0x890)
#define RTCSERR_COFF_ALLOC_FAILED   (RTCS_ERROR_BASE|0x891)
#define RTCSERR_COFF_TRUNCATED      (RTCS_ERROR_BASE|0x892)
#define RTCSERR_COFF_ERROR          (RTCS_ERROR_BASE|0x893)

/*
** SNMP TRAP Interface Error Codes
*/
#define RTCSERR_TRAP_INSERT_FAILED      (RTCS_ERROR_BASE|0x901)  /* TRAP Insertion failed     */
#define RTCSERR_TRAP_REMOVE_FAILED      (RTCS_ERROR_BASE|0x902)  /* TRAP Insertion failed     */

/*
** DHCP error codes
*/
#define RTCSERR_DHCP_ALREADY_INIT           (RTCS_ERROR_BASE|0xA01)
#define RTCSERR_DHCP_MESSAGE_OPTION_MISSING (RTCS_ERROR_BASE|0xA02)
#define RTCSERR_DHCP_SERVER_OPTION_MISSING  (RTCS_ERROR_BASE|0xA03)
#define RTCSERR_DHCP_ADDR_IN_USE            (RTCS_ERROR_BASE|0xA04)
#define RTCSERR_DHCP_PACKET_ERROR           (RTCS_ERROR_BASE|0xA81)
#define RTCSERR_DHCPCLNT_ERROR_DECLINED     (RTCS_ERROR_BASE|0xA82)
#define RTCSERR_DHCPCLNT_XID_MISMATCH       (RTCS_ERROR_BASE|0xA83)
#define RTCSERR_DHCPCLNT_PACKET_SIZE_ERROR  (RTCS_ERROR_BASE|0xA84)

/*
** DNS error codes
*/
#define DNS_OK                                      RTCS_OK
#define RTCSERR_DNS_QUERY_OK                        (RTCS_ERROR_BASE|0xB00)
#define RTCSERR_DNS_NO_NAME_SERVER_RESPONSE         (RTCS_ERROR_BASE|0xB01)
#define RTCSERR_DNS_UNABLE_TO_OPEN_SOCKET           (RTCS_ERROR_BASE|0xB02)
#define RTCSERR_DNS_UNABLE_TO_BIND_SOCKET           (RTCS_ERROR_BASE|0xB03)
#define RTCSERR_DNS_UNABLE_TO_UPDATE_ROOT_SERVERS   (RTCS_ERROR_BASE|0xB04)
#define RTCSERR_DNS_SOCKET_RECV_ERROR               (RTCS_ERROR_BASE|0xB05)
#define RTCSERR_DNS_UNABLE_TO_SEND_QUERY            (RTCS_ERROR_BASE|0xB06)
#define RTCSERR_DNS_NO_RESPONSE_FROM_RESOLVER       (RTCS_ERROR_BASE|0xB07)
#define RTCSERR_DNS_PACKET_RECEPTION_ERROR          (RTCS_ERROR_BASE|0xB08)
#define RTCSERR_DNS_INVALID_NAME                    (RTCS_ERROR_BASE|0xB09)
#define RTCSERR_DNS_INVALID_IP_ADDR                 (RTCS_ERROR_BASE|0xB0A)
#define RTCSERR_DNS_ALL_SERVERS_QUERIED             (RTCS_ERROR_BASE|0xB0B)
#define RTCSERR_DNS_INVALID_LOCAL_NAME              (RTCS_ERROR_BASE|0xB0C)
#define RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY       (RTCS_ERROR_BASE|0xB0D)
#define RTCSERR_DNS_UNABLE_TO_FREE_SOCKET           (RTCS_ERROR_BASE|0xB0E)
#define RTCSERR_DNS_VALID_IP_ADDR                   (RTCS_ERROR_BASE|0xB0F)
#define RTCSERR_DNS_INITIALIZATION_FAILURE          (RTCS_ERROR_BASE|0xB10)
#define RTCSERR_DNS_NOT_IMPLEMENTED                 (RTCS_ERROR_BASE|0xB11)
#define RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION      (RTCS_ERROR_BASE|0xB12)
#define RTCSERR_DNS_SHORT_MESSAGE_ERROR             (RTCS_ERROR_BASE|0xB13)

/*
** NAT error codes
*/
#define RTCSERR_NAT_NO_SESSION                   (RTCS_ERROR_BASE|0xC00)
#define RTCSERR_NAT_UNSUPPORTED_PROTOCOL         (RTCS_ERROR_BASE|0xC01)
#define RTCSERR_NAT_INITIALIZED                  (RTCS_ERROR_BASE|0xC02)
#define RTCSERR_NAT_UNEXPECTED                   (RTCS_ERROR_BASE|0xC03)
#define RTCSERR_NAT_NOT_INITIALIZED              (RTCS_ERROR_BASE|0xC04)
#define RTCSERR_NAT_INVALID_RULE                 (RTCS_ERROR_BASE|0xC05)
#define RTCSERR_NAT_INVALID_PRIVATE_NETWORK      (RTCS_ERROR_BASE|0xC07)
#define RTCSERR_NAT_MAX_PRIVATE_NETWORKS         (RTCS_ERROR_BASE|0xC08)
#define RTCSERR_NAT_DUPLICATE_PRIORITY           (RTCS_ERROR_BASE|0xC09)
#define RTCSERR_NAT_END_OF_RULES                 (RTCS_ERROR_BASE|0xC0A)
#define RTCSERR_NAT_INVALID_PRIVATE_ADDRESS      (RTCS_ERROR_BASE|0xC0B)

/*
** IPCFG error codes
*/
#define IPCFG_OK                        RTCS_OK
#define RTCSERR_IPCFG_BUSY              (RTCS_ERROR_BASE|0xD01)
#define RTCSERR_IPCFG_DEVICE_NUMBER     (RTCS_ERROR_BASE|0xD02)
#define RTCSERR_IPCFG_INIT              (RTCS_ERROR_BASE|0xD03)
#define RTCSERR_IPCFG_BIND              (RTCS_ERROR_BASE|0xD04)
#define RTCSERR_IPCFG_NOT_INIT          (RTCS_ERROR_BASE|0xD05)


    /****************************************************************
    * Additional RTCS IPv6 error codes .
    *****************************************************************/
    #define RTCSERR_IP6_IF_NO_ADDRESS_SPACE      (RTCS_ERROR_BASE|0xE01)
    #define RTCSERR_ND6_CFG                      (RTCS_ERROR_BASE|0xE02)
    #define RTCSERR_IP_IS_DISABLED               (RTCS_ERROR_BASE|0xE03)


/*
** Protocol layer definitions.  These are used by RTCS_[non]fatal_error().
*/
#define ERROR_RTCS                  (0x1)
#define ERROR_SOCKET                (0x2)
#define ERROR_TCPIP                 (0x3)
#define ERROR_TCP                   (0x4)
#define ERROR_UDP                   (0x5)
#define ERROR_RPC                   (0x6)
#define ERROR_ECHO                  (0x7)
#define ERROR_EDS                   (0x8)
#define ERROR_TELNET                (0x9)
#define ERROR_DHCPSRV               (0xA)
#define ERROR_DNS                   (0xB)
#define ERROR_IGMP                  (0xC)




#define RTCS_BOOTFILE_LEN       (128)
#define RTCS_SNAME_LEN          (64)
#define RTCS_BOOTOPT_LEN        (64)

#define MEM_TYPE_RTCS_BASE                   ( (IO_RTCS_COMPONENT) << (MEM_TYPE_COMPONENT_SHIFT))
#define MEM_TYPE_RTCS_DATA                      (MEM_TYPE_RTCS_BASE+1)
#define MEM_TYPE_ARP_CFG                        (MEM_TYPE_RTCS_BASE+2)
#define MEM_TYPE_ARP_ENTRY                      (MEM_TYPE_RTCS_BASE+3)
#define MEM_TYPE_DHCP_CLNT_STRUCT               (MEM_TYPE_RTCS_BASE+4)
#define MEM_TYPE_DHCPSRV_OPTIONS_STRUCT         (MEM_TYPE_RTCS_BASE+5)
#define MEM_TYPE_FTPd_SESSION_PTR               (MEM_TYPE_RTCS_BASE+6)
#define MEM_TYPE_FTPd_DATA_BUFFER               (MEM_TYPE_RTCS_BASE+7)
#define MEM_TYPE_ICMP_CFG_STRUCT                (MEM_TYPE_RTCS_BASE+8)
#define MEM_TYPE_ICMP_DATA                      (MEM_TYPE_RTCS_BASE+9)
#define MEM_TYPE_IP_CFG_STRUCT                  (MEM_TYPE_RTCS_BASE+10)
#define MEM_TYPE_IP_DATA                        (MEM_TYPE_RTCS_BASE+11)
#define MEM_TYPE_ICB                            (MEM_TYPE_RTCS_BASE+12)
#define MEM_TYPE_IP_IF                          (MEM_TYPE_RTCS_BASE+13)
#define MEM_TYPE_SOCKET_CONFIG_STRUCT           (MEM_TYPE_RTCS_BASE+14)
#define MEM_TYPE_RTCS_PARTITION                 (MEM_TYPE_RTCS_BASE+15)
#define MEM_TYPE_IO_SOCKET                      (MEM_TYPE_RTCS_BASE+16)
#define MEM_TYPE_SOCKET_OWNER_STRUCT            (MEM_TYPE_RTCS_BASE+17)
#define MEM_TYPE_TCP_CFG_STRUCT                 (MEM_TYPE_RTCS_BASE+18)
#define MEM_TYPE_TCB                            (MEM_TYPE_RTCS_BASE+19)
#define MEM_TYPE_TCP_TX_WINDOW                  (MEM_TYPE_RTCS_BASE+20)
#define MEM_TYPE_TCP_RX_WINDOW                  (MEM_TYPE_RTCS_BASE+21)
#define MEM_TYPE_TCP_SEND_CLOCK                 (MEM_TYPE_RTCS_BASE+22)
#define MEM_TYPE_UDP_CFG_STRUCT                 (MEM_TYPE_RTCS_BASE+23)
#define MEM_TYPE_UCB_STRUCT                     (MEM_TYPE_RTCS_BASE+24)
#define MEM_TYPE_UDP_BUFFER                     (MEM_TYPE_RTCS_BASE+25)
#define MEM_TYPE_IO_TELNET                      (MEM_TYPE_RTCS_BASE+26)
#define MEM_TYPE_SbufNode                       (MEM_TYPE_RTCS_BASE+27)
#define MEM_TYPE_Rchunk                         (MEM_TYPE_RTCS_BASE+28)
#define MEM_TYPE_FTPc_CONTEXT_STRUCT            (MEM_TYPE_RTCS_BASE+29)
#define MEM_TYPE_DHCPSRV_ADDR_STRUCT            (MEM_TYPE_RTCS_BASE+30)
#define MEM_TYPE_DHCPSRV_CID                    (MEM_TYPE_RTCS_BASE+31)
#define MEM_TYPE_DNS_CONTROL_STRUCT             (MEM_TYPE_RTCS_BASE+32)
#define MEM_TYPE_DNS_UDP_MESSAGE                (MEM_TYPE_RTCS_BASE+33)
#define MEM_TYPE_FTPc_RX_BUFFER                 (MEM_TYPE_RTCS_BASE+34)
#define MEM_TYPE_FTPc_COMMAND_BUFFER            (MEM_TYPE_RTCS_BASE+35)
#define MEM_TYPE_HOSTENT_STRUCT                 (MEM_TYPE_RTCS_BASE+36)
#define MEM_TYPE_TFTP_PACKET                    (MEM_TYPE_RTCS_BASE+37)
#define MEM_TYPE_TFTP_TRANS_STRUCT              (MEM_TYPE_RTCS_BASE+38)

#define MEM_TYPE_HTTPD_STRUCT                   (MEM_TYPE_RTCS_BASE+40)
#define MEM_TYPE_HTTPD_PARAMS                   (MEM_TYPE_RTCS_BASE+41)
#define MEM_TYPE_HTTPD_SESSION_STRUCT           (MEM_TYPE_RTCS_BASE+42)
#define MEM_TYPE_HTTPD_URI                      (MEM_TYPE_RTCS_BASE+43)
#define MEM_TYPE_HTTPD_AUTH                     (MEM_TYPE_RTCS_BASE+44)
#define MEM_TYPE_HTTPD_LINE                     (MEM_TYPE_RTCS_BASE+45)


#define MEM_TYPE_ICMP6_CFG_STRUCT               (MEM_TYPE_RTCS_BASE+50)
#define MEM_TYPE_ND6_CFG                        (MEM_TYPE_RTCS_BASE+51)
#define MEM_TYPE_IP6_CFG_STRUCT                 (MEM_TYPE_RTCS_BASE+52)


/* Helpful macros.*/
#define IPBYTES(a)            (((a)>>24)&0xFF),(((a)>>16)&0xFF),(((a)>> 8)&0xFF),((a)&0xFF)
#define IPADDR(a,b,c,d)       (((uint_32)(a)&0xFF)<<24)|(((uint_32)(b)&0xFF)<<16)|(((uint_32)(c)&0xFF)<<8)|((uint_32)(d)&0xFF)

/*
** Configurable globals
*/
extern uint_32 _RTCSTASK_priority;     /* TCP/IP task priority  */
extern uint_32 _RTCSTASK_stacksize;    /* additional stack size */

extern uint_32 _RTCSQUEUE_base;        /* RTCS queue numbers to use  */
extern uint_32 _RTCSPCB_init;           /* maximum RTCSPCBs available */
extern uint_32 _RTCSPCB_grow;           /* maximum RTCSPCBs available */
extern uint_32 _RTCSPCB_max;           /* maximum RTCSPCBs available */

extern boolean _IP_forward;            /* IP forwarding */

extern boolean _TCP_bypass_rx;         /* TCP checksum bypass (recv) */
extern boolean _TCP_bypass_tx;         /* TCP checksum bypass (send) */
extern uint_32 _TCP_rto_min;           /* minimum TCP resend timeout */
extern boolean _RTCS_initialized;      /* RTCS initialized */
extern uint_32 _UDP_max_queue_size;    /* maximum length of UDP queue */
extern boolean _DHCP_broadcast;        /* DHCP broadcast or unicast offers */

extern _mem_pool_id _RTCS_mem_pool;

extern uint_32 _RTCS_msgpool_init;
extern uint_32 _RTCS_msgpool_grow;
extern uint_32 _RTCS_msgpool_max;

extern uint_32 _RTCS_socket_part_init;
extern uint_32 _RTCS_socket_part_grow;
extern uint_32 _RTCS_socket_part_max;

extern uint_32 _RTCS_dhcp_term_timeout;

/*
** Type definitions
*/

/*
** IP address definition
*/
typedef uint_32 _ip_address;

typedef struct in_addr {
   _ip_address s_addr;
} in_addr;

/*
** IP multicast group
*/
typedef struct ip_mreq {
   in_addr  imr_multiaddr;
   in_addr  imr_interface;
} ip_mreq;

/*
** Socket Address Structure
*/
typedef struct sockaddr_in {
   uint_16  sin_family;
   uint_16  sin_port;
   in_addr  sin_addr;
} sockaddr_in;


#if RTCSCFG_ENABLE_IP6
    typedef struct sockaddr
    {
        uint_16		sa_family;
        char 		sa_data[22];
    } sockaddr;
#else
    #if RTCSCFG_ENABLE_IP4
        #define sockaddr   sockaddr_in
        #define sa_family   sin_family
    #endif
#endif

/****************************************************************
* IPv6 address definition (BSD-like).
*****************************************************************/
typedef struct in6_addr
{
    union
    {
        uint_8      __u6_addr8[16];
        uint_16     __u6_addr16[8];
        uint_32 	__u6_addr32[4];
    } __u6_addr;			/* 128-bit IP6 address */
}in6_addr;
#define s6_addr   __u6_addr.__u6_addr8
/* Not RFC */
#define s6_addr8  __u6_addr.__u6_addr8
#define s6_addr16 __u6_addr.__u6_addr16
#define s6_addr32 __u6_addr.__u6_addr32

/****************************************************************
* Socket address for IPv6 (BSD-like).
*****************************************************************/
typedef struct sockaddr_in6
{
    uint_16     sin6_family;    /* AF_INET6 */
    uint_16     sin6_port;      /* Transport layer port # */
    in6_addr	sin6_addr;      /* IP6 address */
    uint_32     sin6_scope_id;  /* scope zone index */
}sockaddr_in6;

/****************************************************************
*
* Helpful macros.
*
*****************************************************************/
#define IN6ADDR(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16) \
    	    { (a1), (a2), (a3), (a4), (a5), (a6), (a7), (a8),       \
            (a9), (a10), (a11), (a12), (a13), (a14), (a15), (a16) }

/*
 * Construct an IPv6 address from eight 16-bit words.
*/
#define in6addr(a, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)    \
                         {                                                                  \
                            (a)->s6_addr[0] = a0;                                           \
                            (a)->s6_addr[1] = a1;                                           \
                            (a)->s6_addr[2] = a2;                                           \
                            (a)->s6_addr[3] = a3;                                           \
                            (a)->s6_addr[4] = a4;                                           \
                            (a)->s6_addr[5] = a5;                                           \
                            (a)->s6_addr[6] = a6;                                           \
                            (a)->s6_addr[7] = a7;                                           \
                            (a)->s6_addr[8] = a8;                                           \
                            (a)->s6_addr[9] = a9;                                           \
                            (a)->s6_addr[10] = a10;                                         \
                            (a)->s6_addr[11] = a11;                                         \
                            (a)->s6_addr[12] = a12;                                         \
                            (a)->s6_addr[13] = a13;                                         \
                            (a)->s6_addr[14] = a14;                                         \
                            (a)->s6_addr[15] = a15;                                         \
                        }

/*
* Definition of some useful macros to handle IP6 addresses (BSD-like)
*/
#define IN6ADDR_ANY_INIT                                    \
    {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     \
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
#define IN6ADDR_LOOPBACK_INIT                               \
    {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     \
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
#define IN6ADDR_NODELOCAL_ALLNODES_INIT                     \
    {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     \
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
#define IN6ADDR_INTFACELOCAL_ALLNODES_INIT                  \
    {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     \
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
#define IN6ADDR_LINKLOCAL_ALLNODES_INIT                     \
    {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     \
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT                   \
    {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     \
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
#define IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT                 \
    {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     \
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16 }}}

extern const struct in6_addr in6addr_any;
extern const struct in6_addr in6addr_loopback;
extern const struct in6_addr in6addr_nodelocal_allnodes;
extern const struct in6_addr in6addr_linklocal_allnodes;
extern const struct in6_addr in6addr_linklocal_allrouters;
extern const struct in6_addr in6addr_linklocal_allv2routers;

/*
* Equality (BSD-like)
*/
#define IN6_ARE_ADDR_EQUAL(a, b)			\
        (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)

/*
* Copying address
*/
extern void IN6_ADDR_COPY(in6_addr *from_addr, in6_addr *to_addr);


/*
 * Unspecified (BSD-like)
 */
#define IN6_IS_ADDR_UNSPECIFIED(a)	                                \
    ((*(const uint_32 *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
    (*(const uint_32 *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
    (*(const uint_32 *)(const void *)(&(a)->s6_addr[8]) == 0) &&	\
    (*(const uint_32 *)(const void *)(&(a)->s6_addr[12]) == 0))

/*
 * Loopback (BSD-like)
 */
#define IN6_IS_ADDR_LOOPBACK(a)	                                	\
    ((*(const uint_32 *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
    (*(const uint_32 *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
    (*(const uint_32 *)(const void *)(&(a)->s6_addr[8]) == 0) &&	\
    (*(const uint_32 *)(const void *)(&(a)->s6_addr[12]) == ntohl(1)))

/*
 * Multicast (BSD-like)
 */
#define IN6_IS_ADDR_MULTICAST(a)	((a)->s6_addr[0] == 0xff)

/*
 * Unicast Scope (BSD-like)
 * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373).
 */
#define IN6_IS_ADDR_LINKLOCAL(a)	\
    	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
#define IN6_IS_ADDR_SITELOCAL(a)	\
    	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))

/*
 * How the address was acquired.
 */
typedef enum
{
    IP6_ADDR_TYPE_MANUAL = 0,           /* Manually.*/
    IP6_ADDR_TYPE_AUTOCONFIGURABLE = 1  /* Autoconfigurable address. */
} ip6_if_addr_type;

/**********************************************************************
 * Link-layer address.
 * For example, Ethernet interafce uses the address with size set to 6.
***********************************************************************/
typedef uchar ll_addr_t[16];
/*
 * Copying Link-layer address.
 */
#define LL_ADDR_COPY(from_addr, to_addr, ll_size)   \
        (_mem_copy(&from_addr[0], &to_addr[0], ll_size))

/*
 * Equality.
 */
#define LL_ADDR_ARE_EQUAL(a, b, size)               \
        (memcmp(&a[0], &b[0], size) == 0)


/*
** The protocol table
*/
extern uint_32 (_CODE_PTR_ const RTCS_protocol_table[])(void);


/*
** Protocol statistics
*/


/*
** Common statistics kept across all protocols.
*/
typedef struct rtcs_stats_struct {
   uint_32  ST_RX_TOTAL;
   uint_32  ST_RX_MISSED;
   uint_32  ST_RX_DISCARDED;
   uint_32  ST_RX_ERRORS;

   uint_32  ST_TX_TOTAL;
   uint_32  ST_TX_MISSED;
   uint_32  ST_TX_DISCARDED;
   uint_32  ST_TX_ERRORS;
} RTCS_STATS_STRUCT, _PTR_ RTCS_STATS_STRUCT_PTR;

/*
** The error structure embedded in statistics structures
*/
typedef struct rtcs_error_struct {
   uint_32     ERROR;
   uint_32     PARM;
   _task_id    TASK_ID;
   uint_32     TASKCODE;
   pointer     MEMPTR;
   boolean     STACK;
} RTCS_ERROR_STRUCT, _PTR_ RTCS_ERROR_STRUCT_PTR;



/*
** In the structures below, the following four fields are common:
**
** [RT]X_TOTAL      is the total number of packets sent/received
** [RT]X_MISSED     is the number of packets discarded due to lack of resources
** [RT]X_DISCARDED  is the number of packets discarded for all other reasons
** [RT]X_ERRORS     is the number of times an internal error occurred
**
** Internal errors are errors that should _never_ happen.  However,
** if one does occur, information is recorded in ERR_[RT]X.
*/
#if RTCSCFG_ENABLE_IPIF_STATS
typedef struct ipif_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   uint_32  ST_RX_OCTETS;           /* total bytes received       */
   uint_32  ST_RX_UNICAST;          /* unicast packets received   */
   uint_32  ST_RX_MULTICAST;        /* multicast packets received */
   uint_32  ST_RX_BROADCAST;        /* broadcast packets received */

   uint_32  ST_TX_OCTETS;           /* total bytes sent           */
   uint_32  ST_TX_UNICAST;          /* unicast packets sent       */
   uint_32  ST_TX_MULTICAST;        /* multicast packets sent     */
   uint_32  ST_TX_BROADCAST;        /* broadcast packets sent     */

} IPIF_STATS, _PTR_ IPIF_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_ARP_STATS
typedef struct arp_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   uint_32  ST_RX_REQUESTS;         /* valid ARP requests received */
   uint_32  ST_RX_REPLIES;          /* valid ARP replies received  */

   uint_32  ST_TX_REQUESTS;         /* ARP requests sent           */
   uint_32  ST_TX_REPLIES;          /* ARP replies received        */

   uint_32  ST_ALLOCS_FAILED;       /* ARP_alloc returned NULL     */
   uint_32  ST_CACHE_HITS;          /* ARP cache hits              */
   uint_32  ST_CACHE_MISSES;        /* ARP cache misses            */
   uint_32  ST_PKT_DISCARDS;        /* data packets discarded due  */
                                    /*    to missing ARP entry     */

} ARP_STATS, _PTR_ ARP_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_IP_STATS
typedef struct ip_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   uint_32  ST_RX_HDR_ERRORS;       /* Discarded -- error in IP header    */
   uint_32  ST_RX_ADDR_ERRORS;      /* Discarded -- illegal destination   */
   uint_32  ST_RX_NO_PROTO;         /* Discarded -- unrecognized protocol */
   uint_32  ST_RX_DELIVERED;        /* Datagrams delivered to upper layer */
   uint_32  ST_RX_FORWARDED;        /* Datagrams forwarded                */

   /* These are included in ST_RX_DISCARDED and ST_RX_HDR_ERRORS */
   uint_32  ST_RX_BAD_VERSION;      /* Datagrams with version != 4        */
   uint_32  ST_RX_BAD_CHECKSUM;     /* Datagrams with invalid checksum    */
   uint_32  ST_RX_BAD_SOURCE;       /* Datagrams with invalid src address */
   uint_32  ST_RX_SMALL_HDR;        /* Datagrams with header too small    */
   uint_32  ST_RX_SMALL_DGRAM;      /* Datagrams smaller than header      */
   uint_32  ST_RX_SMALL_PKT;        /* Datagrams larger than frame        */
   uint_32  ST_RX_TTL_EXCEEDED;     /* Datagrams to route with TTL = 0    */

   uint_32  ST_RX_FRAG_RECVD;       /* Number of received IP fragments    */
   uint_32  ST_RX_FRAG_REASMD;      /* Number of reassembled datagrams    */
   uint_32  ST_RX_FRAG_DISCARDED;   /* Number of discarded fragments      */

   uint_32  ST_TX_FRAG_SENT;        /* Number of sent fragments           */
   uint_32  ST_TX_FRAG_FRAGD;       /* Number of fragmented datagrams     */
   uint_32  ST_TX_FRAG_DISCARDED;   /* Number of fragmentation failures   */

} IP_STATS, _PTR_ IP_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_IP6_STATS
typedef struct ip6_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   uint_32  ST_RX_HDR_ERRORS;       /* Discarded -- error in IP header    */
   uint_32  ST_RX_ADDR_ERRORS;      /* Discarded -- illegal destination   */
   uint_32  ST_RX_NO_PROTO;         /* Discarded -- unrecognized protocol */
   uint_32  ST_RX_DELIVERED;        /* Datagrams delivered to upper layer */
   uint_32  ST_RX_FORWARDED;        /* Datagrams forwarded                */

   /* These are included in ST_RX_DISCARDED and ST_RX_HDR_ERRORS */
   uint_32  ST_RX_BAD_VERSION;      /* Datagrams with version != 4        */
   uint_32  ST_RX_BAD_SOURCE;       /* Datagrams with invalid src address */
   uint_32  ST_RX_SMALL_PKT;        /* Datagrams larger than frame        */
   uint_32  ST_RX_TTL_EXCEEDED;     /* Datagrams to route with TTL = 0    */

   uint_32  ST_RX_FRAG_RECVD;       /* Number of received IP fragments    */
   uint_32  ST_RX_FRAG_REASMD;      /* Number of reassembled datagrams    */
   uint_32  ST_RX_FRAG_DISCARDED;   /* Number of discarded fragments      */

   uint_32  ST_TX_FRAG_SENT;        /* Number of sent fragments           */
   uint_32  ST_TX_FRAG_FRAGD;       /* Number of fragmented datagrams     */
   uint_32  ST_TX_FRAG_DISCARDED;   /* Number of fragmentation failures   */

} IP6_STATS, _PTR_ IP6_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_ICMP_STATS
typedef struct icmp_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   /* These are included in ST_RX_DISCARDED */
   uint_32  ST_RX_BAD_CODE;         /* Datagrams with unrecognized code     */
   uint_32  ST_RX_BAD_CHECKSUM;     /* Datagrams with invalid checksum      */
   uint_32  ST_RX_SMALL_DGRAM;      /* Datagrams smaller than header        */
   uint_32  ST_RX_RD_NOTGATE;       /* Redirects received from non-gateway  */

   /* Statistics on each ICMP type */
   uint_32  ST_RX_DESTUNREACH;      /* Received Destination Unreachables    */
   uint_32  ST_RX_TIMEEXCEED;       /* Received Time Exceededs              */
   uint_32  ST_RX_PARMPROB;         /* Received Parameter Problems          */
   uint_32  ST_RX_SRCQUENCH;        /* Received Source Quenches             */

   uint_32  ST_RX_REDIRECT;         /* Received Redirects                   */
   uint_32  ST_RX_ECHO_REQ;         /* Received Echo Requests               */
   uint_32  ST_RX_ECHO_REPLY;       /* Received Echo Replys                 */
   uint_32  ST_RX_TIME_REQ;         /* Received Timestamp Requests          */

   uint_32  ST_RX_TIME_REPLY;       /* Received Timestamp Replys            */
   uint_32  ST_RX_INFO_REQ;         /* Received Information Requests        */
   uint_32  ST_RX_INFO_REPLY;       /* Received Information Replys          */
   uint_32  ST_RX_OTHER;            /* All other types                      */

   uint_32  ST_TX_DESTUNREACH;      /* Transmitted Destination Unreachables */
   uint_32  ST_TX_TIMEEXCEED;       /* Transmitted Time Exceededs           */
   uint_32  ST_TX_PARMPROB;         /* Transmitted Parameter Problems       */
   uint_32  ST_TX_SRCQUENCH;        /* Transmitted Source Quenches          */

   uint_32  ST_TX_REDIRECT;         /* Transmitted Redirects                */
   uint_32  ST_TX_ECHO_REQ;         /* Transmitted Echo Requests            */
   uint_32  ST_TX_ECHO_REPLY;       /* Transmitted Echo Replys              */
   uint_32  ST_TX_TIME_REQ;         /* Transmitted Timestamp Requests       */

   uint_32  ST_TX_TIME_REPLY;       /* Transmitted Timestamp Replys         */
   uint_32  ST_TX_INFO_REQ;         /* Transmitted Information Requests     */
   uint_32  ST_TX_INFO_REPLY;       /* Transmitted Information Replys       */
   uint_32  ST_TX_OTHER;            /* All other types                      */

} ICMP_STATS, _PTR_ ICMP_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_ICMP6_STATS
typedef struct icmp6_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   /* These are included in ST_RX_DISCARDED */
   uint_32  ST_RX_BAD_CHECKSUM;     /* Datagrams with invalid checksum      */
   uint_32  ST_RX_SMALL_DGRAM;      /* Datagrams smaller than header        */

   /* Statistics on each ICMP type */
   uint_32  ST_RX_DESTUNREACH;      /* Received Destination Unreachables    */
   uint_32  ST_RX_TIMEEXCEED;       /* Received Time Exceededs              */
   uint_32  ST_RX_PARMPROB;         /* Received Parameter Problems          */
   uint_32  ST_RX_REDIRECT;         /* Received Redirects                   */
   uint_32  ST_RX_ECHO_REQ;         /* Received Echo Requests               */
   uint_32  ST_RX_ECHO_REPLY;       /* Received Echo Replys                 */
   uint_32  ST_RX_OTHER;            /* All other types                      */
   uint_32  ST_TX_DESTUNREACH;      /* Transmitted Destination Unreachables */
   uint_32  ST_TX_TIMEEXCEED;       /* Transmitted Time Exceededs           */
   uint_32  ST_TX_PARMPROB;         /* Transmitted Parameter Problems       */
   uint_32  ST_TX_REDIRECT;         /* Transmitted Redirects                */
   uint_32  ST_TX_ECHO_REQ;         /* Transmitted Echo Requests            */
   uint_32  ST_TX_ECHO_REPLY;       /* Transmitted Echo Replys              */
   uint_32  ST_TX_OTHER;            /* All other types                      */

} ICMP6_STATS, _PTR_ ICMP6_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_IGMP_STATS
typedef struct igmp_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   uint_32  ST_RX_BAD_TYPE;         /* Datagrams with unrecognized code     */
   uint_32  ST_RX_BAD_CHECKSUM;     /* Datagrams with invalid checksum      */
   uint_32  ST_RX_SMALL_DGRAM;      /* Datagrams smaller than header        */

   uint_32  ST_RX_QUERY;            /* Received Queries                     */
   uint_32  ST_RX_REPORT;           /* Received Reports                     */

   uint_32  ST_TX_QUERY;            /* Transmitted Queries                  */
   uint_32  ST_TX_REPORT;           /* Transmitted Reports                  */

} IGMP_STATS, _PTR_ IGMP_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_UDP_STATS
typedef struct udp_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   /* These are all included in ST_RX_DISCARDED */
   uint_32  ST_RX_BAD_PORT;         /* Datagrams with dest port zero   */
   uint_32  ST_RX_BAD_CHECKSUM;     /* Datagrams with invalid checksum */
   uint_32  ST_RX_SMALL_DGRAM;      /* Datagrams smaller than header   */
   uint_32  ST_RX_SMALL_PKT;        /* Datagrams larger than frame     */
   uint_32  ST_RX_NO_PORT;          /* Datagrams for a closed port     */

} UDP_STATS, _PTR_ UDP_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_TCP_STATS
typedef struct tcp_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   /* These are all included in ST_RX_DISCARDED */
   uint_32  ST_RX_BAD_PORT;         /* Segments with dest port zero   */
   uint_32  ST_RX_BAD_CHECKSUM;     /* Segments with invalid checksum */
   uint_32  ST_RX_BAD_OPTION;       /* Segments with invalid options  */
   uint_32  ST_RX_BAD_SOURCE;       /* Segments with invalid source   */
   uint_32  ST_RX_SMALL_HDR;        /* Segments with header too small */
   uint_32  ST_RX_SMALL_DGRAM;      /* Segments smaller than header   */
   uint_32  ST_RX_SMALL_PKT;        /* Segments larger than frame     */
   uint_32  ST_RX_BAD_ACK;          /* Received ack for unsent data   */
   uint_32  ST_RX_BAD_DATA;         /* Received data outside window   */
   uint_32  ST_RX_LATE_DATA;        /* Received data after close      */
   uint_32  ST_RX_OPT_MSS;          /* Segments with MSS option set   */
   uint_32  ST_RX_OPT_OTHER;        /* Segments with other options    */

   uint_32  ST_RX_DATA;             /* Data segments received         */
   uint_32  ST_RX_DATA_DUP;         /* Duplicate data received        */
   uint_32  ST_RX_ACK;              /* Acks received                  */
   uint_32  ST_RX_ACK_DUP;          /* Duplicate acks received        */
   uint_32  ST_RX_RESET;            /* RST segments received          */
   uint_32  ST_RX_PROBE;            /* Window probes received         */
   uint_32  ST_RX_WINDOW;           /* Window updates received        */

   uint_32  ST_RX_SYN_EXPECTED;     /* Expected SYN, not received     */
   uint_32  ST_RX_ACK_EXPECTED;     /* Expected ACK, not received     */
   uint_32  ST_RX_SYN_NOT_EXPECTED; /* Received SYN, not expected     */
   uint_32  ST_RX_MULTICASTS;       /* Multicast packets              */


   uint_32  ST_TX_DATA;             /* Data segments sent             */
   uint_32  ST_TX_DATA_DUP;         /* Data segments retransmitted    */
   uint_32  ST_TX_ACK;              /* Ack-only segments sent         */
   uint_32  ST_TX_ACK_DELAYED;      /* Delayed acks sent              */
   uint_32  ST_TX_RESET;            /* RST segments sent              */
   uint_32  ST_TX_PROBE;            /* Window probes sent             */
   uint_32  ST_TX_WINDOW;           /* Window updates sent            */

   uint_32  ST_CONN_ACTIVE;         /* Active opens                   */
   uint_32  ST_CONN_PASSIVE;        /* Passive opens                  */
   uint_32  ST_CONN_OPEN;           /* Established connections        */
   uint_32  ST_CONN_CLOSED;         /* Graceful shutdowns             */
   uint_32  ST_CONN_RESET;          /* Ungraceful shutdowns           */
   uint_32  ST_CONN_FAILED;         /* Failed opens                   */
   uint_32  ST_CONN_ABORTS;         /* Aborts                         */

} TCP_STATS, _PTR_ TCP_STATS_PTR;
#endif

#if RTCSCFG_ENABLE_RIP_STATS
typedef struct rip_stats {
   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

} RIP_STATS, _PTR_ RIP_STATS_PTR;
#endif


/*
** Type definitions for RTCS_if_XXX()
*/

typedef pointer _rtcs_if_handle;
struct ip_if;
struct rtcspcb;

struct in6_addr; //Forward declaration.

typedef struct  rtcs_if_struct {
   uint_32 (_CODE_PTR_  OPEN) (struct ip_if _PTR_);
   uint_32 (_CODE_PTR_  CLOSE)(struct ip_if _PTR_);
#if RTCSCFG_ENABLE_IP4
   uint_32 (_CODE_PTR_  SEND) (struct ip_if _PTR_, struct rtcspcb _PTR_, _ip_address, _ip_address, pointer);
#if RTCSCFG_ENABLE_IGMP && BSPCFG_ENABLE_ENET_MULTICAST
   uint_32 (_CODE_PTR_  JOIN) (struct ip_if _PTR_, _ip_address);
   uint_32 (_CODE_PTR_  LEAVE)(struct ip_if _PTR_, _ip_address);
#endif /* RTCSCFG_ENABLE_IGMP */
#endif /* RTCSCFG_ENABLE_IP4 */

#if RTCSCFG_ENABLE_IP6
   uint_32 (_CODE_PTR_  SEND6) (struct ip_if _PTR_, struct rtcspcb _PTR_, struct in6_addr _PTR_, struct in6_addr _PTR_);
   uint_32 (_CODE_PTR_  JOIN6) (struct ip_if _PTR_, const struct in6_addr _PTR_);
   uint_32 (_CODE_PTR_  LEAVE6)(struct ip_if _PTR_, const struct in6_addr _PTR_);
#endif

} RTCS_IF_STRUCT, _PTR_ RTCS_IF_STRUCT_PTR;

extern const RTCS_IF_STRUCT_PTR  RTCS_IF_LOCALHOST;
extern const RTCS_IF_STRUCT_PTR  RTCS_IF_ENET;
extern const RTCS_IF_STRUCT_PTR  RTCS_IF_PPP;



/*
** Required when booting with BOOTP
*/
typedef struct bootp_data_struct {
   _ip_address SADDR;
#if RTCSCFG_BOOTP_RETURN_YIADDR
   _ip_address CLIENTADDR;
#endif
   uchar       SNAME[RTCS_SNAME_LEN];
   uchar       BOOTFILE[RTCS_BOOTFILE_LEN];
   uchar       OPTIONS[RTCS_BOOTOPT_LEN];
} BOOTP_DATA_STRUCT, _PTR_ BOOTP_DATA_STRUCT_PTR;

/*
** Required when using PPP
*/
typedef struct ipcp_data_struct {
   void (_CODE_PTR_  IP_UP)   (pointer);
   void (_CODE_PTR_  IP_DOWN) (pointer);
   pointer           IP_PARAM;

   unsigned ACCEPT_LOCAL_ADDR  : 1;
   unsigned ACCEPT_REMOTE_ADDR : 1;
   unsigned DEFAULT_NETMASK    : 1; /* obsolete */
   unsigned DEFAULT_ROUTE      : 1;
   unsigned NEG_LOCAL_DNS      : 1;
   unsigned NEG_REMOTE_DNS     : 1;
   unsigned ACCEPT_LOCAL_DNS   : 1; /* ignored if NEG_LOCAL_DNS  == 0 */
   unsigned ACCEPT_REMOTE_DNS  : 1; /* ignored if NEG_REMOTE_DNS == 0 */
   unsigned                    : 0;

   _ip_address LOCAL_ADDR;
   _ip_address REMOTE_ADDR;
   _ip_address NETMASK;     /* obsolete */
   _ip_address LOCAL_DNS;   /* ignored if NEG_LOCAL_DNS   == 0 */
   _ip_address REMOTE_DNS;  /* ignored if NEG_REMOTE_DNS  == 0 */

} IPCP_DATA_STRUCT, _PTR_ IPCP_DATA_STRUCT_PTR;


/*
** Type definitions for socket()
*/

typedef struct rtcs_socket_call_struct {
   uint_32 (_CODE_PTR_ SOCK_SOCKET)      (uint_32);
   uint_32 (_CODE_PTR_ SOCK_BIND)        (uint_32, const sockaddr _PTR_ , uint_16);
   uint_32 (_CODE_PTR_ SOCK_CONNECT)     (uint_32, const sockaddr _PTR_, uint_16);
   uint_32 (_CODE_PTR_ SOCK_LISTEN)      (uint_32, uint_32);
   uint_32 (_CODE_PTR_ SOCK_ACCEPT)      (uint_32, sockaddr _PTR_, uint_16 _PTR_);
   uint_32 (_CODE_PTR_ SOCK_GETSOCKNAME) (uint_32, sockaddr _PTR_, uint_16 _PTR_);
   uint_32 (_CODE_PTR_ SOCK_GETPEERNAME) (uint_32, sockaddr _PTR_, uint_16 _PTR_);
    int_32 (_CODE_PTR_ SOCK_RECV)        (uint_32, pointer, uint_32, uint_32);
    int_32 (_CODE_PTR_ SOCK_RECVFROM)    (uint_32, pointer, uint_32, uint_32, sockaddr _PTR_, uint_16 _PTR_);
    int_32 (_CODE_PTR_ SOCK_RECVMSG)     (uint_32, pointer, uint_32);
    int_32 (_CODE_PTR_ SOCK_SEND)        (uint_32, pointer, uint_32, uint_32);
    int_32 (_CODE_PTR_ SOCK_SENDTO)      (uint_32, pointer, uint_32, uint_32, sockaddr _PTR_, uint_16);
    int_32 (_CODE_PTR_ SOCK_SENDMSG)     (uint_32, pointer, uint_32);
   uint_32 (_CODE_PTR_ SOCK_SOCKATMARK)  (uint_32);
   uint_32 (_CODE_PTR_ SOCK_SHUTDOWN)    (uint_32, uint_32);
} RTCS_SOCKET_CALL_STRUCT, _PTR_ RTCS_SOCKET_CALL_STRUCT_PTR;

extern const RTCS_SOCKET_CALL_STRUCT  SOCK_DGRAM_CALL;
extern const RTCS_SOCKET_CALL_STRUCT  SOCK_STREAM_CALL;

/*
** Type definitions for [gs]etsockopt()
*/

typedef struct rtcs_sockopt_call_struct  {
   uint_32 (_CODE_PTR_ SOCK_GETSOCKOPT)  (uint_32, uint_32, uint_32, pointer, uint_32 _PTR_);
   uint_32 (_CODE_PTR_ SOCK_SETSOCKOPT)  (uint_32, uint_32, uint_32, pointer, uint_32);
} RTCS_SOCKOPT_CALL_STRUCT, _PTR_ RTCS_SOCKOPT_CALL_STRUCT_PTR;

extern const RTCS_SOCKOPT_CALL_STRUCT  SOL_SOCKET_CALL;
extern const RTCS_SOCKOPT_CALL_STRUCT  SOL_IP_CALL;
extern const RTCS_SOCKOPT_CALL_STRUCT  SOL_UDP_CALL;
extern const RTCS_SOCKOPT_CALL_STRUCT  SOL_TCP_CALL;
extern const RTCS_SOCKOPT_CALL_STRUCT  SOL_IGMP_CALL;
extern const RTCS_SOCKOPT_CALL_STRUCT  SOL_LINK_CALL;

/*
** The socket state structure
*/

typedef struct rtcs_linkopt_struct {
   unsigned    OPT_8023 : 1;
   unsigned    OPT_PRIO : 1;
   unsigned             : 0;
   _ip_address DEST;
   uchar       TTL;
   uchar       TOS;
   uchar       RESERVED[2];
#if RTCSCFG_LINKOPT_8021Q_PRIO
   uint_32     PRIO;
#endif
} RTCS_LINKOPT_STRUCT, _PTR_ RTCS_LINKOPT_STRUCT_PTR;

typedef struct socket_owner_struct {
   struct socket_owner_struct  _PTR_   NEXT;
   _rtcs_taskid                        TASK[SOCKET_NUMOWNERS];
} SOCKET_OWNER_STRUCT, _PTR_ SOCKET_OWNER_STRUCT_PTR;

struct mc_member;
struct ucb_struct;
struct tcb_struct;

typedef struct socket_struct {

   struct   socket_struct _PTR_  NEXT;
   struct   socket_struct _PTR_  PREV;

   uint_32                       VALID;

   uint_16                       LOCAL_PORT;          /* not used */
   uint_16                       REMOTE_PORT;         /* not used */
   _ip_address                   LOCAL_IPADDRESS;     /* not used */
   _ip_address                   REMOTE_IPADDRESS;    /* not used */

   /*TBD later we need make only one variable for IPv4 adn IPv6 */
#if RTCSCFG_ENABLE_IP6
   in6_addr                      LOCAL_IPV6ADDRESS;  /*it will be used for*/
   in6_addr                      REMOTE_IPV6ADDRESS; /*IPv6 version of socket */
#endif
   uint_16                       STATE;
   uint_16                       AF;
   RTCS_SOCKET_CALL_STRUCT_PTR   PROTOCOL;

   /*
   ** Socket options.
   **
   **  The order of these options must match the order of the option ids
   **  defined above, and CONNECT_TIMEOUT must be the first one.
   */
   uint_32                       CONNECT_TIMEOUT;
   uint_32                       RETRANSMISSION_TIMEOUT;
   uint_32                       SEND_TIMEOUT;
   uint_32                       RECEIVE_TIMEOUT;
   uint_32                       RECEIVE_PUSH;
   uint_32                       SEND_NOWAIT;
   uint_32                       SEND_WAIT;
   uint_32                       SEND_PUSH;
   uint_32                       RECEIVE_NOWAIT;
   boolean                       CHECKSUM_BYPASS;
   boolean                       ACTIVE;
   int_32                        TBSIZE;
   int_32                        RBSIZE;
   int_32                        MAXRTO;
   uint_32                       MAXRCV_WND;
   int_32                        KEEPALIVE;
   boolean                       NOWAIT;
   boolean                       NO_NAGLE_ALGORITHM;
   boolean                       NOSWRBUF;
   void _CODE_PTR_               CALL_BACK; /* obsolete */
   uint_32                       TYPE_MIRROR;
   void (_CODE_PTR_              APPLICATION_CALLBACK)(int_32);
   uint_32                       TIMEWAIT_TIMEOUT;
   boolean                       TCPSECUREDRAFT_0;
   uint_32                       DELAY_ACK;     /* last option */

   struct tcb_struct _PTR_       TCB_PTR;
   struct ucb_struct _PTR_       UCB_PTR;

   uint_32                       ERROR_CODE;
#if RTCSCFG_SOCKET_OWNERSHIP
   SOCKET_OWNER_STRUCT           OWNERS;
#endif

   struct mc_member _PTR_ _PTR_  MCB_PTR;
   uint_32 (_CODE_PTR_ _PTR_     IGMP_LEAVEALL)(struct mc_member _PTR_ _PTR_);

   struct {
      RTCS_LINKOPT_STRUCT        RX;
      RTCS_LINKOPT_STRUCT        TX;
   }                             LINK_OPTIONS;
} SOCKET_STRUCT, _PTR_ SOCKET_STRUCT_PTR;


/*
** Type definitions for the Telnet server
*/

typedef struct rtcs_task {
   char_ptr          NAME;
   uint_32           PRIORITY;
   uint_32           STACKSIZE;
   void (_CODE_PTR_  START)(pointer);
   pointer           ARG;
} RTCS_TASK, _PTR_ RTCS_TASK_PTR;


/*
** Type definitions for RTCS_load()
*/

/*
** File Transfer information structure
*/
typedef struct ft_call_struct {
   uint_32     (_CODE_PTR_ OPEN)    (pointer ft_data);
   uchar_ptr   (_CODE_PTR_ READ)    (uint_32_ptr size);
   boolean     (_CODE_PTR_ EOFT)    (void);
   uint_32     (_CODE_PTR_ CLOSE)   (void);
} FT_CALL_STRUCT, _PTR_ FT_CALL_STRUCT_PTR;

extern const FT_CALL_STRUCT_PTR FT_TFTP;
extern const FT_CALL_STRUCT_PTR FT_FTP;      /* not implemented */

/*
** TFTP data structure
*/
typedef struct tftp_data_struct {
   _ip_address SERVER;
   char_ptr    FILENAME;
   char_ptr    FILEMODE;
} TFTP_DATA_STRUCT, _PTR_ TFTP_DATA_STRUCT_PTR;

/*
** File Format information structure
*/
typedef struct ff_call_struct {
   uint_32     (_CODE_PTR_ START)   (pointer ff_data);
   uint_32     (_CODE_PTR_ DECODE)  (uint_32 size, uchar_ptr data);
   uint_32     (_CODE_PTR_ EOFD)    (void);
   void        (_CODE_PTR_ EXEC)    (void);
} FF_CALL_STRUCT, _PTR_ FF_CALL_STRUCT_PTR;

extern const FF_CALL_STRUCT_PTR FF_BIN;
extern const FF_CALL_STRUCT_PTR FF_BIN32;    /* not implemented */
extern const FF_CALL_STRUCT_PTR FF_SREC;
extern const FF_CALL_STRUCT_PTR FF_SREC32;
extern const FF_CALL_STRUCT_PTR FF_COFF;

/*
** Binary file data structure
*/
typedef struct binfile_data_struct {
   uchar_ptr   DOWNLOAD_ADDR;
   uchar_ptr   EXEC_ADDR;
} BINFILE_DATA_STRUCT, _PTR_ BINFILE_DATA_STRUCT_PTR;


/*
** Initialization for the DHCP server
*/
typedef struct dhcpsrv_data_struct {

   _ip_address SERVERID;
   uint_32     LEASE;
   _ip_address MASK;

   _ip_address SADDR;
   uchar       SNAME[RTCS_SNAME_LEN];
   uchar       FILE[RTCS_BOOTFILE_LEN];

} DHCPSRV_DATA_STRUCT, _PTR_ DHCPSRV_DATA_STRUCT_PTR;


/*
** Type definitions for gethostbyname()
*/

/*
** Host name information structure
*/
#define MAX_HOST_ALIASES     16
#define MAX_HOST_ADDRESSES   16

typedef struct hostent_struct
{
   char_ptr          h_name;
   char_ptr _PTR_    h_aliases;
   int_16            h_addrtype;
   int_16            h_length;
   char_ptr _PTR_    h_addr_list;

} HOSTENT_STRUCT, _PTR_ HOSTENT_STRUCT_PTR;

/* For 4.2BSD compatability */
#define h_addr h_addr_list[0]

/*
** Host entry structure - a ram version of the hosts file
*/
typedef struct host_entry_struct
{
   uint_32        ip_address;
   char_ptr       host_name;
   char_ptr       aliases[MAX_HOST_ALIASES+1];
} HOST_ENTRY_STRUCT;

/*
* extern struct to input host list into
*/
extern const HOST_ENTRY_STRUCT RTCS_Hosts_list[];

typedef struct internal_hostent_struct
{
   HOSTENT_STRUCT   HOSTENT;
   char_ptr         ALIASES[MAX_HOST_ALIASES+1];
   uint_32_ptr      ADDRESSES[MAX_HOST_ADDRESSES+1];
   uint_32          IP_address;
} INTERNAL_HOSTENT_STRUCT, _PTR_ INTERNAL_HOSTENT_STRUCT_PTR;

/*
** Structure to synchronize between applications and
** the TCP/IP task.
*/

typedef struct tcpip_parm {
   pointer        SYNC;       /* for synchronization with application */
   uint_32        ERROR;      /* [OUT] error code */
} TCPIP_PARM, _PTR_ TCPIP_PARM_PTR;

#ifdef __cplusplus
extern "C" {
#endif


/*
** Prototypes for the RTCS_protocol_table[]
*/

extern uint_32 IGMP_init  (void);
extern uint_32 UDP_init   (void);
extern uint_32 TCP_Init   (void);
extern uint_32 RIP_init   (void);
extern uint_32 OSPF_init  (void);
extern uint_32 IPIP_init  (void);


/*
** BSD prototypes
*/

extern uint_32  RTCS_socket
(
   uint_32              ,  /* [IN] protocol family */
   uint_32              ,  /* [IN] type of communication */
   uint_32                 /* [IN] select a specific protocol */
);
extern uint_32  RTCS_shutdown
(
   uint_32              ,  /* [IN] socket handle */
   uint_32                 /* [IN] shutdown method */
);

extern int_32        inet_aton (const char _PTR_, in_addr _PTR_);
extern _ip_address   inet_addr (const char _PTR_);


#if RTCSCFG_ENABLE_DNS

extern HOSTENT_STRUCT _PTR_ DNS_gethostbyname
(
   char _PTR_  name_ptr
);

extern HOSTENT_STRUCT _PTR_ DNS_gethostbyaddr
(
   char _PTR_ addr_ptr,
   uint_32    len,
   uint_32    type
);

extern void DNS_free_HOSTENT_STRUCT
(
   HOSTENT_STRUCT _PTR_ host_ptr
);

extern HOSTENT_STRUCT_PTR RTCS_gethostbyname
(
   char _PTR_    hostname    /* [IN] name of host to search for */
);

#endif


#if RTCSCFG_CHECK_ERRORS

   #define RTCS_CHECKSOCK(s,err) \
                       ((s) == 0) || ((uint_32)(s) == RTCS_SOCKET_ERROR) \
                     ? (err) \
                     :

   #define RTCS_CHECKAPI(f,s,err) \
                       ((SOCKET_STRUCT_PTR)(s))->PROTOCOL->SOCK_ ## f == NULL \
                     ? (err) \
                     :

   #define RTCS_CHECKLEVEL(v,err) \
                       (v) == 0 \
                     ? (err) \
                     :

#else

   #define RTCS_CHECKSOCK(s,err)
   #define RTCS_CHECKAPI(f,s,err)
   #define RTCS_CHECKLEVEL(v,err)

#endif

#if RTCSCFG_CHECK_VALIDITY

   #define RTCS_CHECKVALID(s,err) \
                       ((SOCKET_STRUCT_PTR)(s))->VALID != SOCKET_VALID \
                     ? (err) \
                     :

#else

   #define RTCS_CHECKVALID(s,err)

#endif

#define RTCS_API(f,s,p)             RTCS_CHECKSOCK(s,RTCSERR_SOCK_INVALID) \
                                    RTCS_CHECKVALID(s,RTCSERR_SOCK_INVALID) \
                                    RTCS_CHECKAPI(f,s,RTCSERR_SOCK_NOT_SUPPORTED) \
                                    ((SOCKET_STRUCT_PTR)(s))->PROTOCOL->SOCK_ ## f p

#define RTCS_API_SOCK(f,s,p)        RTCS_CHECKSOCK(s,RTCS_SOCKET_ERROR) \
                                    RTCS_CHECKVALID(s,RTCS_SOCKET_ERROR) \
                                    RTCS_CHECKAPI(f,s,RTCS_SOCKET_ERROR) \
                                    ((SOCKET_STRUCT_PTR)(s))->PROTOCOL->SOCK_ ## f p

#define RTCS_API_SENDRECV(f,s,p)    RTCS_CHECKSOCK(s,RTCS_ERROR) \
                                    RTCS_CHECKVALID(s,RTCS_ERROR) \
                                    RTCS_CHECKAPI(f,s,RTCS_ERROR) \
                                    ((SOCKET_STRUCT_PTR)(s))->PROTOCOL->SOCK_ ## f p

#define RTCS_API_SOCKOPT(f,s,v,p)   RTCS_CHECKLEVEL(v,RTCSERR_SOCK_INVALID_OPTION) \
                                    ((RTCS_SOCKOPT_CALL_STRUCT_PTR)(v))->SOCK_ ## f p

#define bind(s,ap,al)            (RTCS_API(BIND,        s, (s,(const sockaddr *)(ap),al)))
#define connect(s,ap,al)         (RTCS_API(CONNECT,     s, (s,(sockaddr *)(ap),al)))
#define listen(s,f)              (RTCS_API(LISTEN,      s, (s,f)))
#define getsockname(s,ap,al)     (RTCS_API(GETSOCKNAME, s, (s,(sockaddr *)(ap),al)))
#define getpeername(s,ap,al)     (RTCS_API(GETPEERNAME, s, (s,(sockaddr *)(ap),al)))
#define accept(s,ap,al)          (RTCS_API_SOCK(ACCEPT, s, (s,(sockaddr *)(ap),al)))
#define send(s,p,l,f)            (RTCS_API_SENDRECV(SEND,      s, (s,p,l,f)))
#define sendto(s,p,l,f,ap,al)    (RTCS_API_SENDRECV(SENDTO,    s, (s,p,l,f,(sockaddr *)(ap),al)))
#define recv(s,p,l,f)            (RTCS_API_SENDRECV(RECV,      s, (s,p,l,f)))
#define recvfrom(s,p,l,f,ap,al)  (RTCS_API_SENDRECV(RECVFROM,  s, (s,p,l,f,(sockaddr *)(ap),al)))
#define getsockopt(s,v,on,op,ol) (RTCS_API_SOCKOPT(GETSOCKOPT, s, v, (s,v,on,op,ol)))
#define setsockopt(s,v,on,op,ol) (RTCS_API_SOCKOPT(SETSOCKOPT, s, v, (s,v,on,op,ol)))

#define socket          RTCS_socket
#define shutdown        RTCS_shutdown


#if RTCSCFG_ENABLE_DNS

#define gethostbyname   DNS_gethostbyname
#define gethostbyaddr   DNS_gethostbyaddr

#endif

/*
** RTCS (non-BSD) prototypes
*/

extern uint_32  RTCS_attachsock
(
   uint_32                       /* [IN] socket handle */
);
extern uint_32  RTCS_detachsock
(
   uint_32                       /* [IN] socket handle */
);
extern uint_32  RTCS_transfersock
(
   uint_32     in_sock,          /*[IN] specifies the handle of the existing socket */
   _task_id    new_owner
);
extern uint_32  RTCS_selectall
(
   uint_32                       /* [IN] time to wait for data, in milliseconds */
);

#define RTCS_selectset(sockset, size, timeout)  _RTCS_selectset(sockset, size, timeout)

extern uint_32  _RTCS_select
(
   pointer                    ,  /* [IN] set of read sockets to block on */
   uint_32                    ,  /* [IN] size of read socket set */
   pointer                    ,  /* [IN] set of write sockets to block on */
   uint_32                    ,  /* [IN] size of write socket set */
   uint_32                       /* [IN] time to wait for data, in milliseconds */
);

extern uint_32 _RTCS_selectset
(
   pointer sockset,
   uint_32 size,
   uint_32 timeout
);

extern uint_32  RTCS_geterror
(
   uint_32                       /* [IN] socket handle */
);

extern uint_32 RTCS_load
(
   FT_CALL_STRUCT_PTR         ,  /* [IN] file transfer protocol to use */
   pointer                    ,  /* [IN] file transfer data */
   FF_CALL_STRUCT_PTR         ,  /* [IN] file format to decode */
   pointer                    ,  /* [IN] file format data */
   uint_32                       /* [IN] optional flags */
);

extern uint_32 RTCS_load_TFTP_BIN
(
   _ip_address                ,  /* [IN] address of the TFTP server */
   char_ptr                   ,  /* [IN] file to retrieve */
   uchar_ptr                     /* [IN] download start address */
);

extern uint_32 RTCS_exec_TFTP_BIN
(
   _ip_address                ,  /* [IN] address of the TFTP server */
   char_ptr                   ,  /* [IN] file to retrieve */
   uchar_ptr                  ,  /* [IN] download start address */
   uchar_ptr                     /* [IN] execution start address */
);

extern uint_32 RTCS_load_TFTP_SREC
(
   _ip_address                ,  /* [IN] address of the TFTP server */
   char_ptr                      /* [IN] file to retrieve */
);

extern uint_32 RTCS_exec_TFTP_SREC
(
   _ip_address                ,  /* [IN] address of the TFTP server */
   char_ptr                      /* [IN] file to retrieve */
);

extern uint_32 RTCS_load_TFTP_COFF
(
   _ip_address                ,  /* [IN] address of the TFTP server */
   char_ptr                      /* [IN] file to retrieve */
);

extern uint_32 RTCS_exec_TFTP_COFF
(
   _ip_address                ,  /* [IN] address of the TFTP server */
   char_ptr                      /* [IN] file to retrieve */
);

#if RTCSCFG_ENABLE_IP_STATS
extern IP_STATS_PTR   IP_stats   (void);
#endif
#if RTCSCFG_ENABLE_ICMP_STATS
extern ICMP_STATS_PTR ICMP_stats (void);
#endif
#if RTCSCFG_ENABLE_UDP_STATS
extern UDP_STATS_PTR  UDP_stats  (void);
#endif
#if RTCSCFG_ENABLE_TCP_STATS
extern TCP_STATS_PTR  TCP_stats  (void);
#endif
#if RTCSCFG_ENABLE_IPIF_STATS
extern IPIF_STATS_PTR IPIF_stats (_rtcs_if_handle);
#endif
#if RTCSCFG_ENABLE_ARP_STATS
extern ARP_STATS_PTR  ARP_stats  (_rtcs_if_handle);
#endif
#if RTCSCFG_ENABLE_IP6_STATS
extern IP6_STATS_PTR   IP6_stats (void);
#endif
#if RTCSCFG_ENABLE_ICMP6_STATS
extern ICMP6_STATS_PTR ICMP6_stats  (void);
#endif

extern uint_32 ECHOSRV_init       (char_ptr, uint_32, uint_32);
extern uint_32 TELNETSRV_run     ( RTCS_TASK_PTR );

extern uint_32 TELNETSRV_init     (char_ptr, uint_32, uint_32, RTCS_TASK_PTR);
extern uint_32 TELNETSRV_sockinit (char_ptr, uint_32, uint_32, RTCS_TASK_PTR, uint_32);
extern uint_32 DHCPSRV_init       (char_ptr, uint_32, uint_32);
extern uint_32 TFTPSRV_init       (char_ptr, uint_32, uint_32);
extern uint_32 SNTP_init          (char_ptr, uint_32, uint_32, _ip_address, uint_32);
extern uint_32 SNMP_init          (char_ptr, uint_32, uint_32);

extern uint_32 SNMP_init_with_traps (char_ptr, uint_32, uint_32, _ip_address _PTR_);

extern uint_32 EDS_init           (char_ptr, uint_32, uint_32);

extern uint_32 EDS_stop           (void);
extern uint_32 ECHOSRV_stop       (void);
extern uint_32 SNMP_stop          (void);
extern uint_32 TFTPSRV_stop       (void);
extern uint_32 TELNETSRV_stop     (void);

extern boolean TFTPSRV_access (char_ptr, uint_16);

extern void    RTCS_delay (uint_32);
extern void    RTCS_shell (void);
extern uint_32 RTCS_ping  (_ip_address, uint_32_ptr timeout, uint_16 id, uint_8  hop_limit, pointer data_buffer, uint_32 data_buffer_size);


extern uint_32 TELNET_connect   (_ip_address);

extern uint_32 SNTP_oneshot     (_ip_address, uint_32);

extern void MIB1213_init (void);
extern void MIBMQX_init  (void);

/* Obsolete -- provided for compatility */
extern void RTCS_netstat_task (uint_32);
extern void ECHO_task         (uint_32);
extern void TELNET_server     (uint_32);
extern void EDS_task          (uint_32);
#define TELNET_client RTCS_netstat_task

/*
** RTCS initialization prototypes
*/

extern uint_32 RTCS_create
(
   void
);

extern uint_32 RTCS_if_add
(
   pointer                    ,  /* [IN] the packet driver handle */
   RTCS_IF_STRUCT_PTR         ,  /* [IN] call table for the interface */
   _rtcs_if_handle _PTR_         /* [OUT] the RTCS interface state structure */
);
extern uint_32 RTCS_if_remove
(
   _rtcs_if_handle               /* [IN] the RTCS interface state structure */
);
extern uint_32 RTCS_if_bind
(
   _rtcs_if_handle   handle   ,  /* [IN] the RTCS interface state structure */
   _ip_address       address  ,  /* [IN] the IP address for the interface */
   _ip_address       netmask     /* [IN] the IP (sub)network mask for the interface */
);
extern uint_32 RTCS_if_probe_and_bind
(
   _rtcs_if_handle   handle   ,  /* [IN] the RTCS interface state structure */
   _ip_address       address  ,  /* [IN] the IP address for the interface */
   _ip_address       netmask     /* [IN] the IP (sub)network mask for the interface */
);
extern uint_32 RTCS_if_bind_BOOTP
(
   _rtcs_if_handle            ,
   BOOTP_DATA_STRUCT_PTR
);
extern uint_32 RTCS_if_bind_IPCP
(
   _rtcs_if_handle            ,
   IPCP_DATA_STRUCT_PTR
);

extern uint_32 RTCS_arp_add
(
   _rtcs_if_handle _PTR_   ihandle,  /* [IN] the RTCS interface state structure */
   _ip_address              paddr,   /* [IN] the address to add */
   char           laddr[6]
);
extern uint_32 RTCS_arp_delete
(
   _rtcs_if_handle _PTR_   ihandle,  /* [IN] the RTCS interface state structure */
   _ip_address                paddr  /* [IN] the address to add */
);

extern uint_32 RTCS_if_unbind
(
   _rtcs_if_handle   handle   ,  /* [IN] the RTCS interface state structure */
   _ip_address       address     /* [IN] the IP address for the interface */
);
extern uint_32 RTCS_gate_add
(
   _ip_address       gateway  ,  /* [IN] the IP address of the gateway */
   _ip_address       network  ,  /* [IN] the IP (sub)network to route */
   _ip_address       netmask     /* [IN] the IP (sub)network mask to route */
);

extern uint_32 RTCS_gate_add_metric
(
   _ip_address       gateway  ,  /* [IN] the IP address of the gateway */
   _ip_address       network  ,  /* [IN] the IP (sub)network to route */
   _ip_address       netmask  ,  /* [IN] the IP (sub)network mask to route */
   uint_16           metric      /* [IN] the metric of the gateway */
);

extern uint_32 RTCS_gate_remove
(
   _ip_address       gateway  ,  /* [IN] the IP address of the gateway */
   _ip_address       network  ,  /* [IN] the IP (sub)network to route */
   _ip_address       netmask     /* [IN] the IP (sub)network mask to route */
);

extern uint_32 RTCS_gate_remove_metric
(
   _ip_address       gateway  ,  /* [IN] the IP address of the gateway */
   _ip_address       network  ,  /* [IN] the IP (sub)network to route */
   _ip_address       netmask  ,  /* [IN] the IP (sub)network mask to route */
   uint_16           metric      /* [IN] the metric of the gateway */
);

extern _ip_address RTCS_get_route
(
   _ip_address netaddr, /* [IN] the network address */
   _ip_address netmask  /* [IN] the network mask */
);
extern void RTCS_walk_route( void );

extern uint_32 RTCS_trap_target_add
(
   _ip_address       ip_addr     /* [IN] the IP address to send the trap to */
);

extern uint_32 RTCS_trap_target_remove
(
   _ip_address       ip_addr     /* [IN] removes this IP address from the trap list */
);


extern _ip_address  IPCP_get_local_addr( _rtcs_if_handle );
extern _ip_address  IPCP_get_peer_addr( _rtcs_if_handle );


#if RTCSCFG_ENABLE_DNS

extern uint_32 DNS_init
(
   void
);

#endif

#if RTCSCFG_ENABLE_LWDNS

boolean LWDNS_resolve(
   char_ptr          name_to_resolve,
   _ip_address _PTR_ ipaddr_ptr,
   char_ptr          ipname,
   uint_32           ipnamesize
   );

extern _ip_address LWDNS_server_ipaddr;

#endif

extern boolean RTCS_resolve_ip_address( char_ptr arg, _ip_address _PTR_ ipaddr_ptr, char_ptr ipname, uint_32 ipnamesize);


extern void  RTCS_log_error
(
   uint_32  module,
   uint_32  error,
   uint_32  p1,
   uint_32  p2,
   uint_32  p3
);


#include <dhcp.h>

/*
** The DHCP server
*/

#define DHCPSRV_option_int8     DHCP_option_int8
#define DHCPSRV_option_int16    DHCP_option_int16
#define DHCPSRV_option_int32    DHCP_option_int32
#define DHCPSRV_option_addr     DHCP_option_addr
#define DHCPSRV_option_addrlist DHCP_option_addrlist
#define DHCPSRV_option_string   DHCP_option_string

extern uint_32 DHCPSRV_ippool_add
(
   _ip_address             ipstart,
   uint_32                 ipnum,
   DHCPSRV_DATA_STRUCT_PTR params,
   uchar_ptr               optptr,
   uint_32                 optlen
);

/*
** The IPIP device
*/

extern uint_32 RTCS_tunnel_add
(
   _ip_address  inner_source_addr,     /* [IN] Inner IP header source        */
   _ip_address  inner_source_netmask,  /* [IN] Inner IP header source mask   */
   _ip_address  inner_dest_addr,       /* [IN] Inner IP header dest          */
   _ip_address  inner_dest_netmask,    /* [IN] Inner IP header dest mask     */
   _ip_address  outer_source_addr,     /* [IN] Outer IP header source        */
   _ip_address  outer_dest_addr,       /* [IN] Outer IP header dest          */
   uint_32 flags                       /* [IN] Flags to set tunnel behaviour */
);

extern uint_32 RTCS_tunnel_remove
(
   _ip_address  inner_source_addr,     /* [IN] Inner IP header source        */
   _ip_address  inner_source_netmask,  /* [IN] Inner IP header source mask   */
   _ip_address  inner_dest_addr,       /* [IN] Inner IP header dest          */
   _ip_address  inner_dest_netmask,    /* [IN] Inner IP header dest mask     */
   _ip_address  outer_source_addr,     /* [IN] Outer IP header source        */
   _ip_address  outer_dest_addr,       /* [IN] Outer IP header dest          */
   uint_32 flags                       /* [IN] Flags to set tunnel behaviour */
);

/*
** Util function
*/

extern pointer RTCS_get_enet_handle
(
   _rtcs_if_handle   ihandle           /* [IN] Interface */
);


extern uint_32 RTCS6_if_bind_addr (_rtcs_if_handle handle, in6_addr ip_addr, ip6_if_addr_type ip_addr_type);
extern uint_32 RTCS6_if_unbind_addr (_rtcs_if_handle  handle, in6_addr ip_addr);
extern uint_32 RTCS6_ping(sockaddr *ip_addr, uint_32_ptr timeout, uint_16 id, uint_8  hop_limit, pointer ping_data_buffer, uint_32 ping_data_len);

#ifdef __cplusplus
}
#endif

/*
** IPv6 address definition (BSD-like)
*/
//  TBD:
//  To avoid optimisation problem, size of sockaddr_in6 can be different
//  so, we can try to declare sa_data[22] like:
//  sa_data[sifeoff(sockaddr_in6) - sizeof(sockaddr_in6.sin6_family)]
//  typedef struct sockaddr {
//  	uint_16		sa_family;
//  	char 		sa_data[22];
//  } sockaddr;

typedef struct addrinfo {
	uint_16		    ai_flags			;	/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
	uint_16  	    ai_family			;	/* AF_INET, AF_INET6						*/
	uint_32		    ai_socktype			;	/* SOCK_STREAM, SOCK_DGRAM					*/
	uint_16		    ai_protocol			;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 		*/
	unsigned int 	ai_addrlen			;	/* length of ai_addr 						*/
	char	        *ai_canonname		;	/* canonical name for hostname 				*/
	struct		    sockaddr *ai_addr	;	/* binary address 							*/
	struct		    addrinfo *ai_next	;	/* next structure in linked list 			*/
} addrinfo;

/* user api functions */

extern int_32 inet_pton
(
    int_32 		  af, 	    /* af - address family (AF_INET or AF_INET6)				    */
    const char 	  *src, 	    /* textual presentation of an address,example:"192.0.2.12" 	    */
    void 		  *dst,       /* pointer to a in_addr or in6-addr binary form of an address   */
    unsigned int  sizeof_dst  /* size of dst buffer                                           */
);

extern char *inet_ntop
(
	int_32 			af, 		/* af - address family (AF_INET or AF_INET6)				*/
	const void 		*src, 		/* pointer to a binary form of an address					*/
	char 			*dst, 		/* pointer to a textual presentation of an address			*/
	unsigned int	size		/* max. size of the textual presentation of an address		*/
);

extern unsigned int strlcpy
(
	char 				   *dst, 		/* pointer to destination buffer 					*/
	const char 			   *src, 		/* pointer to source string		 					*/
	unsigned int	       siz			/* size of the destination buffer					*/
);

extern void freeaddrinfo
(
	struct addrinfo 	   *ai			/* addr info structure 								*/
);

extern int_32 getnameinfo
(
	const struct sockaddr   *sa		,	/* socket address structure 						*/
	unsigned int            salen	, 	/* size of socket address structure 				*/
	char 				    *host	,	/* pointer to host name 							*/
	unsigned int            hostlen	, 	/* size of host 									*/
	char       			    *serv	, 	/* pointer to service 								*/
	unsigned int            servlen	, 	/* size of serv 									*/
	int                     flags		/* flags 											*/
	/*
        NI_NUMERICHOST Return the address in numeric form.
	*/
);

extern int_32 getaddrinfo
(
	const char 				*hostname, 	/* host name or IP or NULL							*/
	const char 				*servname,	/* service name or port number						*/
	const struct addrinfo 	*hints,		/* set flags										*/
	struct addrinfo 		**res		/* [OUT]list of address structures					*/
);

#endif


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ipc_udp.h<|end_filename|>
#ifndef __ipc_udp_h__
#define __ipc_udp_h__ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipc_udp.h$
* $Version : 3.8.2.0$
* $Date    : Oct-11-2011$
*
* Comments:
*
*   This file contains the definitions for the 
*   interprocessor drivers that work over Ethernet/UDP.
*
*END************************************************************************/

#include <rtcs.h>

/*--------------------------------------------------------------------------*/
/*
**                          DATATYPE DECLARATIONS
*/

/*
** IPC_UDP_INIT
** This structure contains the initialization information for Ethernet/UDP
** based communication
**
*/
typedef struct ipc_udp_init
{
   /* 
   ** The following are parameters used to create two tasks of the
   ** IPC/UDP driver for handling incomming and outcomming messages
   */
   char_ptr    NAME;
   uint_32     STACK_SIZE;
   uint_32     PRIORITY;

   /* Maximum size of the message queue created by the IPC/UDP driver */
   uint_32     MAX_MSG_SIZE;

   /* UDP port number for receiving */
   uint_32     SOURCE_PORT;

   /* UDP port number for sending */
   uint_32     DEST_PORT;

   /* IP address of the device the IPC/UDP driver sends messages to */
   _ip_address DEST;
} IPC_UDP_INIT, * IPC_UDP_INIT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                          C PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint IPC_UDP_Init( const IPC_PROTOCOL_INIT_STRUCT * ipc_init_ptr, pointer ipc_info_ptr);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enaddr.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enaddr.c$
* $Version : 3.0.6.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   This file contains the ENET_get_address utility
*   function.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_address
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Retrieves the Ethernet address of an initialized device.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_get_address
   (
      /* [IN] the Ethernet state structure */
      _enet_handle   handle,

      /* [OUT] the local Ethernet address */
      _enet_address  address
   )
{  
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

   eaddrcpy(address, enet_ptr->ADDRESS);

   return ENET_OK;

} 

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_mac_address
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Retrieves the Ethernet address of a device.
*
*
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_get_mac_address
   (
      uint_32        device,
      uint_32        value,
      _enet_address  address
   )

{
   return _bsp_get_mac_address(device,value,address);
} 


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/INV1_K60F120.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: INV1_K60F120.h$
* $Version : 3.8.5.0$
* $Date    : Oct-8-2012$
*
* Comments:
*
*   This include file is used to provide information needed by
*   an application program using the kernel running on the
*   Freescale TWR-K70F120M Evaluation board.
*
*END************************************************************************/

#ifndef _INV1_K60F120_h_
  #define _INV1_K60F120_h_  1


/*----------------------------------------------------------------------
**                  HARDWARE INITIALIZATION DEFINITIONS
*/

/*
** Define the board type
*/
  #define BSP_TWR_K60F120M                     1

/*
** PROCESSOR MEMORY BOUNDS
*/
  #define BSP_PERIPH_BASE                     (CORTEX_PERIPH_BASE)

typedef void (*vector_entry)(void);

  #define BSP_INTERNAL_FLASH_BASE    0x00000000
  #define BSP_INTERNAL_FLASH_SIZE    0x00100000
  #define BSP_INTERNAL_FLASH_SECTOR_SIZE 0x1000

  #ifdef __CC_ARM
/* Keil compiler */
    #define __EXTERNAL_MRAM_ROM_BASE 0x70000000
    #define __EXTERNAL_MRAM_ROM_SIZE 0x00000000
    #define __EXTERNAL_MRAM_RAM_BASE 0x70000000
    #define __EXTERNAL_MRAM_RAM_SIZE 0x00080000
    #define __EXTERNAL_LCD_BASE      0x60010000
    #define __EXTERNAL_LCD_SIZE      0x0001FFFF
    #define __EXTERNAL_LCD_DC_BASE   0x60000000

/* This define MUST match the limit set in the linker file.
   The internal flash starts at 0x00000000, and ends at 0x00100000
   1/2 of the internal flash is set aside for user flash.  Change as needed.
   MAKE SURE THE START ADDRESS IS ALIGNED (is a multiple of) __FLASHX_SECT_SIZE
 */
    #define __FLASHX_START_ADDR     0x00080000
    #define __FLASHX_END_ADDR       0x00100000

    #define __INTERNAL_SRAM_BASE    0x1FFF0000
    #define __INTERNAL_SRAM_SIZE    0x00020000
    #define __SRAM_POOL             (pointer)0x1FFF0000

/* Uncached area is maped to sram */
    #define __UNCACHED_DATA_START_DEF   0x1FFF0000
    #define __UNCACHED_DATA_SIZE_DEF    0x00020000
    #define __UNCACHED_DATA_END_DEF     0x2000FFF0

    #define __DEFAULT_PROCESSOR_NUMBER     0
    #define __DEFAULT_INTERRUPT_STACK_SIZE 1024

    #define __VECTOR_TABLE_ROM_START 0x00000000
    #define __VECTOR_TABLE_RAM_START 0x1FFF0000 /* where .vectors_ram is placed. Check linker command file. */

  #else /* __CC_ARM */

extern uchar __EXTERNAL_MRAM_ROM_BASE[],    __EXTERNAL_MRAM_ROM_SIZE[];
extern uchar __EXTERNAL_MRAM_RAM_BASE[],    __EXTERNAL_MRAM_RAM_SIZE[];

extern uchar __EXTERNAL_LCD_BASE[],         __EXTERNAL_LCD_SIZE[];
extern uchar __EXTERNAL_LCD_DC_BASE[];
extern const uchar __FLASHX_START_ADDR[];
extern const uchar __FLASHX_END_ADDR[];
extern const uchar __FLASHX_SECT_SIZE[];

extern uchar __INTERNAL_SRAM_BASE[],        __INTERNAL_SRAM_SIZE[];

extern uchar __UNCACHED_DATA_START[],       __UNCACHED_DATA_SIZE[],     __UNCACHED_DATA_END[];

extern unsigned long __SRAM_POOL[];

extern uchar __INTERNAL_FLEXNVM_BASE[];
extern uchar __INTERNAL_FLEXNVM_SIZE[];

extern vector_entry __VECTOR_TABLE_RAM_START[]; /* defined in linker command file */
extern vector_entry __VECTOR_TABLE_ROM_START[]; /* defined in linker command file */

extern uchar __DEFAULT_PROCESSOR_NUMBER[];
extern uchar __DEFAULT_INTERRUPT_STACK_SIZE[];

  #endif /* __CC_ARM */
  #define BSP_EXTERNAL_MRAM_ROM_BASE          ((pointer)__EXTERNAL_MRAM_ROM_BASE)
  #define BSP_EXTERNAL_MRAM_ROM_SIZE          ((uint_32)__EXTERNAL_MRAM_ROM_SIZE)
  #define BSP_EXTERNAL_MRAM_RAM_BASE          ((pointer)__EXTERNAL_MRAM_RAM_BASE)
  #define BSP_EXTERNAL_MRAM_RAM_SIZE          ((uint_32)__EXTERNAL_MRAM_RAM_SIZE)


/* NAND Flash driver related macros */
  #define BSP_VIRTUAL_PAGE_SIZE               (512)
  #define BSP_ECC_SIZE                        (4) /* 4-error correction bits (8 ECC bytes) */

  #define BSP_EXTERNAL_LCD_BASE               ((pointer)__EXTERNAL_LCD_BASE)
  #define BSP_EXTERNAL_LCD_SIZE               ((uint_32)__EXTERNAL_LCD_SIZE)
  #define BSP_EXTERNAL_LCD_DC                 ((pointer)__EXTERNAL_LCD_DC_BASE)

/* Compact Flash card base address */
  #define BSP_CFCARD_BASE                     ((pointer)0xA0010000)

/* Enable modification of flash configuration bytes during loading for flash targets */
  #ifndef BSPCFG_ENABLE_CFMPROTECT
    #define BSPCFG_ENABLE_CFMPROTECT        1
  #endif
  #if !BSPCFG_ENABLE_CFMPROTECT && defined(__ICCARM__)
    #error Cannot disable CFMPROTECT field on IAR compiler. Please define BSPCFG_ENABLE_CFMPROTECT to 1.
  #endif

  #ifndef BSP_CLOCK_CONFIGURATION_STARTUP
    #define BSP_CLOCK_CONFIGURATION_STARTUP (BSP_CLOCK_CONFIGURATION_120MHZ)
  #endif

/* Init startup clock configuration is CPU_CLOCK_CONFIG_0 */
  #define BSP_CLOCK_SRC                   (CPU_XTAL_CLK_HZ)
  #define BSP_CORE_CLOCK                  (CPU_CORE_CLK_HZ_CONFIG_0)
  #define BSP_SYSTEM_CLOCK                (CPU_CORE_CLK_HZ_CONFIG_0)
  #define BSP_CLOCK                       (CPU_BUS_CLK_HZ_CONFIG_0)
  #define BSP_BUS_CLOCK                   (CPU_BUS_CLK_HZ_CONFIG_0)
  #define BSP_FLEXBUS_CLOCK               (CPU_FLEXBUS_CLK_HZ_CONFIG_0)
  #define BSP_FLASH_CLOCK                 (CPU_FLASH_CLK_HZ_CONFIG_0)

/** MGCT: <category name="BSP Hardware Options"> */

/*
** The clock tick rate in miliseconds - be cautious to keep this value such
** that it divides 1000 well
**
** MGCT: <option type="number" min="1" max="1000"/>
*/
  #ifndef BSP_ALARM_FREQUENCY
    #define BSP_ALARM_FREQUENCY             (200)
  #endif

/** MGCT: </category> */

/*
** Old clock rate definition in MS per tick, kept for compatibility
*/
  #define BSP_ALARM_RESOLUTION                (1000 / BSP_ALARM_FREQUENCY)

/*
** Define the location of the hardware interrupt vector table
*/
  #if MQX_ROM_VECTORS
    #define BSP_INTERRUPT_VECTOR_TABLE              ((uint_32)__VECTOR_TABLE_ROM_START)
  #else
    #define BSP_INTERRUPT_VECTOR_TABLE              ((uint_32)__VECTOR_TABLE_RAM_START)
  #endif

  #ifndef BSP_FIRST_INTERRUPT_VECTOR_USED
    #define BSP_FIRST_INTERRUPT_VECTOR_USED     (0)
  #endif

  #ifndef BSP_LAST_INTERRUPT_VECTOR_USED
    #define BSP_LAST_INTERRUPT_VECTOR_USED      (250)
  #endif

  #define BSP_TIMER_INTERRUPT_VECTOR              INT_SysTick
  #define BSP_TIMER_INTERRUPT_PRIORITY            2

/*
** RTC interrupt level
*/
  #define BSP_RTC_INT_LEVEL                      (4)

/*
** LPM related
*/
  #define BSP_LPM_DEPENDENCY_LEVEL_SERIAL_POLLED (30)
  #define BSP_LPM_DEPENDENCY_LEVEL_SERIAL_INT    (31)

/*
** GPIO board specifications
*/
  #define BSP_LED1                    (GPIO_PORT_A | GPIO_PIN11)
  #define BSP_LED2                    (GPIO_PORT_A | GPIO_PIN28)
  #define BSP_LED3                    (GPIO_PORT_A | GPIO_PIN29)
  #define BSP_LED4                    (GPIO_PORT_A | GPIO_PIN10)

  #define BSP_SW1                     (GPIO_PORT_A | GPIO_PIN19)
  #define BSP_SW2                     (GPIO_PORT_E | GPIO_PIN26)
  #define BSP_ACCEL_IRQ               (GPIO_PORT_B | GPIO_PIN4) /* onboard accelerometer IRQ pin */

  #define BSP_LED1_MUX_GPIO           (LWGPIO_MUX_A11_GPIO)
  #define BSP_LED2_MUX_GPIO           (LWGPIO_MUX_A28_GPIO)
  #define BSP_LED3_MUX_GPIO           (LWGPIO_MUX_A29_GPIO)
  #define BSP_LED4_MUX_GPIO           (LWGPIO_MUX_A10_GPIO)
  #define BSP_SW1_MUX_GPIO            (LWGPIO_MUX_A19_GPIO)
  #define BSP_SW2_MUX_GPIO            (LWGPIO_MUX_E26_GPIO)
  #define BSP_ACCEL_MUX_GPIO          (LWGPIO_MUX_B4_GPIO)

/* definitions for user applications */
  #define BSP_BUTTON1                 BSP_SW1
  #define BSP_BUTTON2                 BSP_SW2

  #define BSP_BUTTON1_MUX_GPIO        BSP_SW1_MUX_GPIO
  #define BSP_BUTTON1_MUX_IRQ         BSP_SW1_MUX_GPIO
  #define BSP_BUTTON2_MUX_GPIO        BSP_SW2_MUX_GPIO

/* HWTIMER definitions for user applications */
  #define BSP_HWTIMER1_DEV        pit_devif
  #define BSP_HWTIMER1_SOURCE_CLK (CM_CLOCK_SOURCE_BUS)
  #define BSP_HWTIMER1_ID         (0)

  #define BSP_HWTIMER2_DEV        pit_devif
  #define BSP_HWTIMER2_SOURCE_CLK (CM_CLOCK_SOURCE_BUS)
  #define BSP_HWTIMER2_ID         (1)

/* Port IRQ levels */
  #define BSP_PORTA_INT_LEVEL         (3)
  #define BSP_PORTB_INT_LEVEL         (3)
  #define BSP_PORTC_INT_LEVEL         (3)
  #define BSP_PORTD_INT_LEVEL         (3)
  #define BSP_PORTE_INT_LEVEL         (3)

/* LCD board settings */
  #define BSP_LCD_DC                  (GPIO_PORT_B | GPIO_PIN17) /* open J3 13-14 */
  #define BSP_LCD_DC_FN               1                          /* Functionality for LCD DC pin */

/* GPIO settings for resistive touch screen on LCD board */
  #define BSP_LCD_TCHRES_X_PLUS       (GPIO_PORT_B | GPIO_PIN4)
  #define BSP_LCD_TCHRES_X_MINUS      (GPIO_PORT_B | GPIO_PIN6)
  #define BSP_LCD_TCHRES_Y_PLUS       (GPIO_PORT_B | GPIO_PIN7)
  #define BSP_LCD_TCHRES_Y_MINUS      (GPIO_PORT_B | GPIO_PIN5)

  #define BSP_LCD_SPI_CHANNEL         "spi2:"

  #define BSP_LCD_X_PLUS_ADC_CHANNEL  (ADC1_SOURCE_AD10)
  #define BSP_LCD_Y_PLUS_ADC_CHANNEL  (ADC1_SOURCE_AD13)

/* ADC tchres device init struct */
  #define BSP_TCHRES_ADC_DEVICE "adc1:"
  #define BSP_TCHRES_X_TRIGGER ADC_PDB_TRIGGER
  #define BSP_TCHRES_Y_TRIGGER ADC_PDB_TRIGGER

/*-----------------------------------------------------------------------------
**                      Ethernet Info
*/
  #define BSP_ENET_DEVICE_COUNT                  MACNET_DEVICE_COUNT

/*
** MACNET interrupt levels and vectors
*/
  #define BSP_MACNET0_INT_TX_LEVEL           (4)
  #define BSP_MACNET0_INT_RX_LEVEL           (4)

  #define BSP_DEFAULT_ENET_DEVICE             0
  #define BSP_DEFAULT_ENET_OUI                { 0x00, 0x00, 0x5E, 0, 0, 0 }

/*
** The Ethernet PHY device number 0..31
*/
  #ifndef BSP_ENET0_PHY_ADDR
    #define BSP_ENET0_PHY_ADDR                 0
  #endif

/*
** PHY MII Speed (MDC - Management Data Clock)
*/
  #define BSP_ENET0_PHY_MII_SPEED             (2500000L)

/** MGCT: <category name="BSP Ethernet Options"> */

/*
** Number of receive BD's.
** MGCT: <option type="number"/>
*/
  #ifndef BSPCFG_RX_RING_LEN
    #define BSPCFG_RX_RING_LEN              8
  #endif

/*
** Number of transmit BD's.
** MGCT: <option type="number"/>
*/
  #ifndef BSPCFG_TX_RING_LEN
    #define BSPCFG_TX_RING_LEN              4
  #endif

/*
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ENET_MULTICAST
    #define BSPCFG_ENABLE_ENET_MULTICAST    1
  #endif

/*
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ENET_STATS
    #define BSPCFG_ENABLE_ENET_STATS        1
  #endif

/*
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENET_RESTORE
    #define BSPCFG_ENET_RESTORE             1
  #endif

/*
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENET_SRAM_BUF
    #define BSPCFG_ENET_SRAM_BUF            1
  #endif

/*
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_CPP
    #define BSPCFG_ENABLE_CPP               0
  #endif

/** MGCT: </category> */

/*-----------------------------------------------------------------------------
**                      DSPI
*/

  #define BSP_DSPI_INT_LEVEL               (4)
  #define BSP_SPI_MEMORY_CHANNEL           2

/*-----------------------------------------------------------------------------
**                      ESDHC
*/

  #define BSP_SDCARD_ESDHC_CHANNEL            "esdhc:"
  #define BSP_SDCARD_GPIO_DETECT              (GPIO_PORT_E | GPIO_PIN28)
  #define BSP_SDCARD_DETECT_MUX_GPIO          (LWGPIO_MUX_E28_GPIO)
  #define BSP_SDCARD_PROTECT_MUX_GPIO         (LWGPIO_MUX_E27_GPIO)

/*-----------------------------------------------------------------------------
**                      I2C
*/
  #define BSP_I2C_CLOCK                       (BSP_BUS_CLOCK)
  #define BSP_I2C0_ADDRESS                    (0x6E)
  #define BSP_I2C1_ADDRESS                    (0x6F)
  #define BSP_I2C0_BAUD_RATE                  (100000)
  #define BSP_I2C1_BAUD_RATE                  (100000)
  #define BSP_I2C0_MODE                       (I2C_MODE_MASTER)
  #define BSP_I2C1_MODE                       (I2C_MODE_MASTER)
  #define BSP_I2C0_INT_LEVEL                  (5)
  #define BSP_I2C1_INT_LEVEL                  (5)
  #define BSP_I2C0_RX_BUFFER_SIZE             (64)
  #define BSP_I2C0_TX_BUFFER_SIZE             (64)
  #define BSP_I2C1_RX_BUFFER_SIZE             (64)
  #define BSP_I2C1_TX_BUFFER_SIZE             (64)

/*-----------------------------------------------------------------------------
**                      ADC
*/
  #define ADC_MAX_MODULES                 (4)

  #define BSP_ADC_CH_POT                  (ADC1_SOURCE_AD20)

  #define BSP_ADC0_VECTOR_PRIORITY        (3)
  #define BSP_ADC1_VECTOR_PRIORITY        (3)
  #define BSP_ADC2_VECTOR_PRIORITY        (3)
  #define BSP_ADC3_VECTOR_PRIORITY        (3)

  #define BSP_PDB_VECTOR_PRIORITY         (3)


/*-----------------------------------------------------------------------------
**                      USB
*/
  #define USBCFG_MAX_DRIVERS               (2)

  #define BSP_USB_INT_LEVEL                (4)
  #define BSP_USB_TWR_SER2                 (0) /* set to 1 if TWR-SER2 (2 eth) board used (only host) */

/* USB host controler for K70x processors */
  #define USBCFG_KHCI                       1
  #define USBCFG_EHCI                       1

  #define USBCFG_DEFAULT_HOST_CONTROLLER    (&_bsp_usb_host_khci0_if)
  #define USBCFG_DEFAULT_DEVICE_CONTROLLER  (&_bsp_usb_dev_khci0_if)

/* This will be removed in the future and runtime option in the initialization struct will be used */
  #define USBCFG_REGISTER_ENDIANNESS        MQX_LITTLE_ENDIAN
  #define USBCFG_MEMORY_ENDIANNESS          MQX_LITTLE_ENDIAN

/*-----------------------------------------------------------------------------
**                  IO DEVICE DRIVERS CONFIGURATION
*/

/** MGCT: <category name="I/O Subsystem"> */

/*
** Enable I/O subsystem features in MQX. No I/O drivers and file I/O will be 
** possible without this feature.
** 
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_IO_SUBSYSTEM
    #define BSPCFG_ENABLE_IO_SUBSYSTEM      1
  #endif

/** MGCT: </category> */

/** MGCT: <category name="Default Driver Installation in BSP startup"> */

/** MGCT: <category name="UART0 Settings"> */

/*
** Polled TTY device (UART0) 
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_TTYA
    #define BSPCFG_ENABLE_TTYA              0
  #endif

/*
** Interrupt-driven TTY device (UART0)
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ITTYA
    #define BSPCFG_ENABLE_ITTYA             0
  #endif

/*
** TTYA and ITTYA baud rate
** MGCT: <option type="number" min="0" max="115200"/>
*/
  #ifndef BSPCFG_SCI0_BAUD_RATE
    #define BSPCFG_SCI0_BAUD_RATE             921600//115200
  #endif

/*
** TTYA and ITTYA buffer size
** MGCT: <option type="number" min="0" max="256"/>
*/
  #ifndef BSPCFG_SCI0_QUEUE_SIZE
    #define BSPCFG_SCI0_QUEUE_SIZE             64
  #endif

/** MGCT: </category> */

/** MGCT: <category name="UART1 Settings"> */

/*
** Polled TTY device (UART1) 
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_TTYB
    #define BSPCFG_ENABLE_TTYB              0
  #endif

/*
** Interrupt-driven TTY device (UART1)
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ITTYB
    #define BSPCFG_ENABLE_ITTYB             0
  #endif

/*
** TTYB and ITTYB baud rate
** MGCT: <option type="number" min="0" max="115200"/>
*/
  #ifndef BSPCFG_SCI1_BAUD_RATE
    #define BSPCFG_SCI1_BAUD_RATE             115200
  #endif

/*
** TTYB and ITTYB buffer size
** MGCT: <option type="number" min="0" max="256"/>
*/
  #ifndef BSPCFG_SCI1_QUEUE_SIZE
    #define BSPCFG_SCI1_QUEUE_SIZE             64
  #endif

/** MGCT: </category> */

/** MGCT: <category name="UART2 Settings"> */

/*
** Polled TTY device (UART2) 
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_TTYC
    #define BSPCFG_ENABLE_TTYC              0
  #endif

/*
** Interrupt-driven TTY device (UART2)
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ITTYC
    #define BSPCFG_ENABLE_ITTYC             0
  #endif

/*
** TTYC and ITTYC baud rate
** MGCT: <option type="number" min="0" max="115200"/>
*/
  #ifndef BSPCFG_SCI2_BAUD_RATE
    #define BSPCFG_SCI2_BAUD_RATE             115200
  #endif

/*
** TTYC and ITTYC buffer size
** MGCT: <option type="number" min="0" max="256"/>
*/
  #ifndef BSPCFG_SCI2_QUEUE_SIZE
    #define BSPCFG_SCI2_QUEUE_SIZE             64
  #endif

/** MGCT: </category> */

/** MGCT: <category name="UART3 Settings"> */

/*
** Polled TTY device (UART3) 
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_TTYD
    #define BSPCFG_ENABLE_TTYD              0
  #endif

/*
** Interrupt-driven TTY device (UART3)
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ITTYD
    #define BSPCFG_ENABLE_ITTYD             0
  #endif

/*
** TTYD and ITTYD baud rate
** MGCT: <option type="number" min="0" max="115200"/>
*/
  #ifndef BSPCFG_SCI3_BAUD_RATE
    #define BSPCFG_SCI3_BAUD_RATE             115200
  #endif

/*
** TTYD and ITTYD buffer size
** MGCT: <option type="number" min="0" max="256"/>
*/
  #ifndef BSPCFG_SCI3_QUEUE_SIZE
    #define BSPCFG_SCI3_QUEUE_SIZE             64
  #endif

/** MGCT: </category> */

/** MGCT: <category name="UART4 Settings"> */

/*
** Polled TTY device (UART4) 
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_TTYE
    #define BSPCFG_ENABLE_TTYE              0
  #endif

/*
** Interrupt-driven TTY device (UART4)
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ITTYE
    #define BSPCFG_ENABLE_ITTYE             0
  #endif

/*
** TTYE and ITTYE baud rate
** MGCT: <option type="number" min="0" max="115200"/>
*/
  #ifndef BSPCFG_SCI4_BAUD_RATE
    #define BSPCFG_SCI4_BAUD_RATE             115200
  #endif

/*
** TTYE and ITTYE buffer size
** MGCT: <option type="number" min="0" max="256"/>
*/
  #ifndef BSPCFG_SCI4_QUEUE_SIZE
    #define BSPCFG_SCI4_QUEUE_SIZE             64
  #endif

/** MGCT: </category> */

/** MGCT: <category name="UART5 Settings"> */

/*
** Polled TTY device (UART5) 
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_TTYF
    #define BSPCFG_ENABLE_TTYF              0
  #endif

/*
** Interrupt-driven TTY device (UART5)
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ITTYF
    #define BSPCFG_ENABLE_ITTYF             0
  #endif

/*
** TTY device HW signals (UART5).
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_TTYF_HW_SIGNALS
    #define BSPCFG_ENABLE_TTYF_HW_SIGNALS   0
  #endif

/*
** TTYF and ITTYF baud rate
** MGCT: <option type="number" min="0" max="115200"/>
*/
  #ifndef BSPCFG_SCI5_BAUD_RATE
    #define BSPCFG_SCI5_BAUD_RATE             115200
  #endif

/*
** TTYF and ITTYF buffer size
** MGCT: <option type="number" min="0" max="256"/>
*/
  #ifndef BSPCFG_SCI5_QUEUE_SIZE
    #define BSPCFG_SCI5_QUEUE_SIZE             64
  #endif

/** MGCT: </category> */

/*
** Polled I2C0 device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_I2C0
    #define BSPCFG_ENABLE_I2C0                  1
  #endif

/*
** Polled I2C1 device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_I2C1
    #define BSPCFG_ENABLE_I2C1                  0
  #endif

/*
** Interrupt-driven I2C0 device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_II2C0
    #define BSPCFG_ENABLE_II2C0                 0
  #endif

/*
** Interrupt-driven I2C1 device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_II2C1
    #define BSPCFG_ENABLE_II2C1                 0
  #endif

/* GPIO device */
  #ifdef BSPCFG_ENABLE_GPIODEV
    #if BSPCFG_ENABLE_GPIODEV
      #error The GPIO driver was replaced by faster and smaller LWGPIO - see <MQX_INST_DIR>\mqx\examples\lwgpio\lwgpio.c example application
    #endif
  #endif

/*
** RTC device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_RTCDEV
    #define BSPCFG_ENABLE_RTCDEV                0
  #endif

/*
** PCFLASH device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_PCFLASH
    #define BSPCFG_ENABLE_PCFLASH               0
  #endif

/*
** Polled SPI0
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_SPI0
    #define BSPCFG_ENABLE_SPI0                  0
  #endif

/*
** Interrupt-driven SPI0
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ISPI0
    #define BSPCFG_ENABLE_ISPI0                 0
  #endif

/*
** Polled SPI1
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_SPI1
    #define BSPCFG_ENABLE_SPI1                  0
  #endif

/*
** Interrupt-driven SPI1
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ISPI1
    #define BSPCFG_ENABLE_ISPI1                 0
  #endif

/*
** Polled SPI2
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_SPI2
    #define BSPCFG_ENABLE_SPI2                  0
  #endif

/*
** Interrupt-driven SPI2
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ISPI2
    #define BSPCFG_ENABLE_ISPI2                 0
  #endif

/*
** ADC0
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ADC0
    #define BSPCFG_ENABLE_ADC0                  0
  #endif

/*
** ADC1
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ADC1
    #define BSPCFG_ENABLE_ADC1                  0
  #endif

/*
** ADC2
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ADC2
    #define BSPCFG_ENABLE_ADC2                  0
  #endif

/*
** ADC3
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ADC3
    #define BSPCFG_ENABLE_ADC3                  0
  #endif

/*
** FTFL
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_FLASHX
    #define BSPCFG_ENABLE_FLASHX                0
  #endif

/*
** ESDHC device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_ESDHC
    #define BSPCFG_ENABLE_ESDHC                 0
  #endif

/*
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_NANDFLASH
    #define BSPCFG_ENABLE_NANDFLASH             0
  #endif

/*
** USB DCD device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_USBDCD
    #define BSPCFG_ENABLE_USBDCD               0
  #endif

/*
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_CRC
    #define BSPCFG_ENABLE_CRC                   0
  #endif

/*
** IODEBUG device
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_IODEBUG
    #define BSPCFG_ENABLE_IODEBUG               1
  #endif

/*
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_HAS_SRAM_POOL
    #define BSPCFG_HAS_SRAM_POOL                1
  #endif

/*
** SAI device 
** MGCT: <option type="bool"/>
*/
  #ifndef BSPCFG_ENABLE_SAI
    #define BSPCFG_ENABLE_SAI                   0
  #endif
/** MGCT: </category> */

/*----------------------------------------------------------------------
**                  DEFAULT MQX INITIALIZATION DEFINITIONS
** MGCT: <category name="Default MQX initialization parameters"> 
*/

/* Defined in link.xxx */
extern uchar __KERNEL_DATA_START[];
extern uchar __KERNEL_DATA_END[];


  #if MQX_ENABLE_USER_MODE
extern uchar __KERNEL_AREA_START[];
extern uchar __KERNEL_AREA_END[];
extern uchar __USER_AREA_START[];
extern uchar __USER_AREA_END[];

    #if __IAR_SYSTEMS_ICC__
      #pragma section="USER_RW_MEMORY"
      #pragma section="USER_RO_MEMORY"
      #pragma section="USER_NO_MEMORY"
      #pragma section="USER_HEAP"
      #pragma section="USER_DEFAULT_MEMORY"
    #else
      #error MQX_ENABLE_USER_MODE is only supported on IAR tool in this MQX version
    #endif

    #define BSP_DEFAULT_START_OF_KERNEL_AREA                    ((pointer)__KERNEL_AREA_START)
    #define BSP_DEFAULT_END_OF_KERNEL_AREA                      ((pointer)__KERNEL_AREA_END)

    #define BSP_DEFAULT_START_OF_USER_DEFAULT_MEMORY            ((pointer)__sfb("USER_DEFAULT_MEMORY"))
    #define BSP_DEFAULT_END_OF_USER_DEFAULT_MEMORY              ((pointer)__sfe("USER_DEFAULT_MEMORY"))

    #define BSP_DEFAULT_START_OF_USER_HEAP                      ((pointer)__sfb("USER_HEAP"))
    #define BSP_DEFAULT_END_OF_USER_HEAP                        ((pointer)__USER_AREA_END)

    #define BSP_DEFAULT_START_OF_USER_RW_MEMORY                 ((pointer)__sfb("USER_RW_MEMORY"))
    #define BSP_DEFAULT_END_OF_USER_RW_MEMORY                   ((pointer)__sfe("USER_RW_MEMORY"))

    #define BSP_DEFAULT_START_OF_USER_RO_MEMORY                 ((pointer)__sfb("USER_RO_MEMORY"))
    #define BSP_DEFAULT_END_OF_USER_RO_MEMORY                   ((pointer)__sfe("USER_RO_MEMORY"))

    #define BSP_DEFAULT_START_OF_USER_NO_MEMORY                 ((pointer)__sfb("USER_NO_MEMORY"))
    #define BSP_DEFAULT_END_OF_USER_NO_MEMORY                   ((pointer)__sfe("USER_NO_MEMORY"))

    #define BSP_DEFAULT_MAX_USER_TASK_PRIORITY                  (0)
    #define BSP_DEFAULT_MAX_USER_TASK_COUNT                     (0)

  #endif // MQX_ENABLE_USER_MODE

  #define BSP_DEFAULT_START_OF_KERNEL_MEMORY                    ((pointer)__KERNEL_DATA_START)
  #define BSP_DEFAULT_END_OF_KERNEL_MEMORY                      ((pointer)__KERNEL_DATA_END)
  #define BSP_DEFAULT_PROCESSOR_NUMBER                          ((uint_32)__DEFAULT_PROCESSOR_NUMBER)

/* MGCT: <option type="string" quoted="false" allowempty="false"/> */
  #ifndef BSP_DEFAULT_INTERRUPT_STACK_SIZE
    #define BSP_DEFAULT_INTERRUPT_STACK_SIZE                  ((uint_32)__DEFAULT_INTERRUPT_STACK_SIZE)
  #endif

/* MGCT: <option type="list">
** <item name="1 (all levels disabled)" value="(1L)"/>
** <item name="2" value="(2L)"/>
** <item name="3" value="(3L)"/>
** <item name="4" value="(4L)"/>
** <item name="5" value="(5L)"/>
** <item name="6" value="(6L)"/>
** <item name="7" value="(7L)"/>
** </option>
*/
  #ifndef BSP_DEFAULT_MQX_HARDWARE_INTERRUPT_LEVEL_MAX
    #define BSP_DEFAULT_MQX_HARDWARE_INTERRUPT_LEVEL_MAX      (2L)
  #endif

/*
** MGCT: <option type="number"/>
*/
  #ifndef BSP_DEFAULT_MAX_MSGPOOLS
    #define BSP_DEFAULT_MAX_MSGPOOLS                          (2L)
  #endif

/*
** MGCT: <option type="number"/>
*/
  #ifndef BSP_DEFAULT_MAX_MSGQS
    #define BSP_DEFAULT_MAX_MSGQS                             (16L)
  #endif

/*
 * Other Serial console options:(do not forget to enable BSPCFG_ENABLE_TTY define if changed)
 *      "ttyf:"      OSJTAG-COM, TWR_SER  polled mode
 *      "ittyf:"     TWR-SER     interrupt mode
 *      "iodebug:"   IDE debug console
 ** MGCT: <option type="string" maxsize="256" quoted="false" allowempty="false"/> 
 */
  #ifndef BSP_DEFAULT_IO_CHANNEL
    #if BSPCFG_ENABLE_TTYA
      #define BSP_DEFAULT_IO_CHANNEL                        "ttya:"
      #define BSP_DEFAULT_IO_CHANNEL_DEFINED
    #else
      #define BSP_DEFAULT_IO_CHANNEL                        NULL
    #endif
  #else
/* undef is for backward compatibility with user_configh.h files which have already had it defined */
    #undef  BSP_DEFAULT_IO_CHANNEL_DEFINED
    #define BSP_DEFAULT_IO_CHANNEL_DEFINED
  #endif

/*
** MGCT: <option type="string" maxsize="1024" quoted="false" allowempty="false"/>  
*/
  #ifndef BSP_DEFAULT_IO_OPEN_MODE
//    #define BSP_DEFAULT_IO_OPEN_MODE                          (pointer) (IO_SERIAL_XON_XOFF | IO_SERIAL_TRANSLATION | IO_SERIAL_ECHO)
    #define BSP_DEFAULT_IO_OPEN_MODE                          (pointer) (IO_SERIAL_XON_XOFF  )
  #endif

/*
** FLASHX flash memory pool minimum size
** MGCT: <option type="string" maxsize="1024" quoted="false" allowempty="false"/>  
*/
  #if BSPCFG_ENABLE_FLASHX
    #ifndef BSPCFG_FLASHX_SIZE
      #define BSPCFG_FLASHX_SIZE      0x4000
    #endif
  #else
    #undef  BSPCFG_FLASHX_SIZE
    #define BSPCFG_FLASHX_SIZE      0x0
  #endif

/** MGCT: </category> */
#endif /* _INV1_K60F120_h_  */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/nandflash/nandflashprv.h<|end_filename|>
#ifndef _nandflashprv_h_
#define _nandflashprv_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nandflashprv.h$
* $Version : 3.6.2.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions private to the NAND flash driver.
*
*END************************************************************************/


/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/


/* Properties of device */
#define IO_NANDFLASH_ATTRIBS  (IO_DEV_ATTR_READ  | IO_DEV_ATTR_SEEK | \
                               IO_DEV_ATTR_WRITE | IO_DEV_ATTR_BLOCK_MODE)


/*----------------------------------------------------------------------*/
/*
**                    Structure Definitions
*/



/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

/* These are from nandflash.c */
extern _mqx_int  _io_nandflash_open(MQX_FILE_PTR, char_ptr, char_ptr);
extern _mqx_int  _io_nandflash_close(MQX_FILE_PTR);
extern _mqx_int  _io_nandflash_read (MQX_FILE_PTR, char_ptr, _mqx_int);
extern _mqx_int  _io_nandflash_write(MQX_FILE_PTR, char_ptr, _mqx_int);
extern _mqx_int  _io_nandflash_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_scanf.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_scanf.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the function scanf.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief This function performs similarly to the scanf function found in 'C'.
 * 
 * \param[in] fmt_ptr The format string to scan with.
 * 
 * \return The number of input items converted and assigned.
 * \return IO_EOF (Failure.) 
 */ 
_mqx_int _io_scanf
   ( 
      const char _PTR_ fmt_ptr, 
      ...
   )
{ /* Body */
   char    temp_buf[IO_MAXLINE];
   va_list ap;
   _mqx_int result;
   
   va_start(ap, fmt_ptr);
   temp_buf[0] = '\0';
   if (_io_fgetline(stdin, temp_buf, IO_MAXLINE) == IO_EOF) {
      return(IO_EOF);
   } /* Endif */
   result = _io_scanline(temp_buf, (char _PTR_)fmt_ptr, ap);
   va_end(ap);
   return result;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enutil.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enutil.c$
* $Version : 3.8.11.0$
* $Date    : Oct-2-2012$
*
* Comments:
*
*   This file contains misc. ENET driver utility functions
*   function.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"


#if 0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_device_number
*  Returned Value : device number or -1
*  Comments       :
*        Retrieves the Ethernet device number of an initialized device.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_get_device_number
   (
      /* [IN] the Ethernet state structure */
      _enet_handle   handle
   )
{
    ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

    if (enet_ptr != NULL)
    {
        return enet_ptr->DEVICE;
    }
    return (uint_32)-1;
}
#endif

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_Enqueue_Buffer
*  Returned Value :
*  Comments       :
*
*
*END*-----------------------------------------------------------------*/

void ENET_Enqueue_Buffer( pointer * q, pointer b)
{
   *((pointer *)b) = *q;
   *q = b;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_Dequeue_Buffer
*  Returned Value :
*  Comments       :
*
*
*END*-----------------------------------------------------------------*/

pointer ENET_Dequeue_Buffer( pointer * q)
{
   pointer b = *q;

   if (b) {
      *q = *((pointer *)b);
   }
   return b;
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_link_status
*  Returned Value : TRUE if link active, FALSE otherwise
*  Comments       : Get actual link status.
*
*END*-----------------------------------------------------------------*/

boolean ENET_link_status(_enet_handle   handle)
{
    ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

   return (*enet_ptr->PARAM_PTR->ENET_IF->PHY_IF->STATUS)(enet_ptr);
}



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_speed
*  Returned Value : 10 or 100
*  Comments       : For Backward compatibility of old BSPs.
*        Get the negoiated speed.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_get_speed
   (
      /* [IN] the Ethernet state structure */
      _enet_handle   handle
   )
{
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

   return (*enet_ptr->PARAM_PTR->ENET_IF->PHY_IF->SPEED)(enet_ptr);
}



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_max_framesize
*  Returned Value :
*  Comments       :
*
*     Calculate maximum frame size based on user parameters.
*  If the user specifies large buffers, then the max will be the largest
*  frame size (based on vlan).
*
*
*END*-----------------------------------------------------------------*/

uint_16 ENET_max_framesize(uint_16 best_buffer_size, uint_16 num_large_buffers, boolean vlan)
{

  if (num_large_buffers || (best_buffer_size==0)) {
      if (vlan) {
         return ENET_FRAMESIZE_VLAN;
      } else {
         return ENET_FRAMESIZE;
      }
   } else {
      return best_buffer_size;
   }
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_MTU
*  Returned Value : mtu
*  Comments       :
*        Get the MTU.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_get_MTU
   (
      /* [IN] the Ethernet state structure */
      _enet_handle   handle
   )
{
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;
   uint_32  mtu = enet_ptr->PARAM_PTR->TX_BUFFER_SIZE;

   if (!mtu) {
      return ENET_FRAMESIZE_MAXDATA;  // The same regardless of whether VLAN is enabled.
   }

   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_VLAN) {
      return(mtu - ENET_FRAMESIZE_HEAD_VLAN - ENET_FRAMESIZE_TAIL);
   } else {
      return(mtu - ENET_FRAMESIZE_HEAD - ENET_FRAMESIZE_TAIL);
   }
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_read_mii
*  Returned Value : TRUE and MII Data register value, FALSE if timeout
*  Comments       :
*    Returns entire MII data register value.
*
*END*-----------------------------------------------------------------*/

boolean ENET_read_mii
    (
        /* [IN] the Ethernet state structure */
        _enet_handle handle,
        uint_32 reg_index,
        uint_32_ptr data,
        uint_32 timeout
    )
{
    ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

    return (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, reg_index, data, timeout);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_write_mii
*  Returned Value : TRUE if succeeded, FALSE if timeout
*    Writes entire MII data register.
*
*END*-----------------------------------------------------------------*/

boolean ENET_write_mii
    (
        /* [IN] the Ethernet state structure */
        _enet_handle handle,
        uint_32 reg_index,
        uint_32 data,
        uint_32 timeout
    )
{
    ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

    return (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_WRITE)(enet_ptr, reg_index, data, timeout);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_phy_addr
*  Returned Value : phy address or -1
*  Comments       :
*        Retrieves the PHY address of an initialized device.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_get_phy_addr
    (
        /* [IN] the Ethernet state structure */
        _enet_handle handle
    )
{
    ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

    if (enet_ptr != NULL)
    {
        return (uint_32)(enet_ptr->PHY_ADDRESS);
    }
    return (uint_32)-1;
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_phy_registers
*  Returned Value : phy registers
*  Comments       :
*        Retrieves the PHY registers.
*
*END*-----------------------------------------------------------------*/

boolean ENET_phy_registers
   (
      _enet_handle handle,
      uint_32      num_regs,
      uint_32_ptr  regs_ptr
   )
{
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;
   uint_32  i;
   boolean  all_read=TRUE;
   for (i=0;i<num_regs;i++) {
      *regs_ptr=0;
      if (!(*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, i, regs_ptr, 0x1000))
      {
         all_read=FALSE;
      }
      regs_ptr++;
   }
   return all_read;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_device_handle
*  Returned Value : device_handle
*  Comments       :
*        Retrieves the device_handle
*
*END*-----------------------------------------------------------------*/

_enet_handle ENET_get_device_handle(uint_32 mac_number)
{
   ENET_CONTEXT_STRUCT_PTR enet_ptr = NULL;
   uint_32                 result;
   boolean                 vlan;
   
   enet_ptr = _mqx_get_io_component_handle(IO_ENET_COMPONENT);
   
   while (enet_ptr) {
      if (enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER == mac_number)
         return enet_ptr;
      
      enet_ptr = enet_ptr->NEXT;
   }
   
  return NULL;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_next_device_handle
*  Returned Value : device_handle
*  Comments       :
*        Retrieves the next device_handle
*
*END*-----------------------------------------------------------------*/
_enet_handle ENET_get_next_device_handle(_enet_handle handle)
{
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR) handle;
   
   if (enet_ptr != NULL) {
       return enet_ptr->NEXT;
   }
   return NULL;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/istrata/istrata1.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: istrata1.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions to program Intel's StrataFlash 
*   devices
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "istrata.h"
#include "istrataprv.h"

                                          
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_program_1byte
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs a sector of flash for 8 bit devices
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_program_1byte
   (  
      /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR  handle_ptr,

      /* [IN] where to copy data from */
      char_ptr              from_ptr,
      
      /* [OUT} where to copy data to */
      char_ptr              to_ptr,

      /* [IN] the sector size to copy */
      _mem_size             sector_size,

      /* [IN] the offset to start at */
      _mem_size             offset
   )
{ /* Body */
   boolean                 erase;
   boolean                 success;
   boolean                 timeout;
   _mqx_uint               j;
   MQX_TICK_STRUCT         start_ticks;

   /* First make sure we actually need to program the sector */
   erase = FALSE;

   for (j = offset; !erase && (j < sector_size); j++) {
      erase = ISTRATA_ERASE_UNIT(to_ptr[j], from_ptr[j]);
   } /* Endfor */

   if (erase) {
      success = _intel_strata_erase_1byte(handle_ptr, to_ptr, 
         sector_size, &start_ticks);
      if (!success) {
         return success;
      } /* Endif */
      /* 
      ** We erased the whole sector so we must program from the beginning of
      ** the sector
      */
      offset = 0;
   } else {
      success = TRUE;
   } /* Endif */

   if (handle_ptr->DEVICES == 1) {
      volatile uchar _PTR_  dest_ptr = (volatile uchar _PTR_)to_ptr;
      uchar _PTR_           src_ptr  = (uchar _PTR_)from_ptr;
      _mem_size             size = sector_size;
      uchar                 tmp, status;

      dest_ptr = dest_ptr + offset;
      src_ptr  = src_ptr  + offset;

      ISTRATA_PROGRAM(ISTRATA_READ_MODE_CMD_8X1, ISTRATA_WRITE_CMD_8X1, 
         ISTRATA_STATUS_BUSY_8X1);
   } else if (handle_ptr->DEVICES == 2) {
      volatile uint_16 _PTR_  dest_ptr = (volatile uint_16 _PTR_)((pointer)to_ptr);
      uint_16 _PTR_           src_ptr  = (uint_16 _PTR_)((pointer)from_ptr);
      _mem_size               size;
      uint_16                 tmp, status;

      size = sector_size >> 1;
      offset >>= 1;
      dest_ptr = dest_ptr + offset;
      src_ptr  = src_ptr  + offset;

      ISTRATA_PROGRAM(ISTRATA_READ_MODE_CMD_8X2, ISTRATA_WRITE_CMD_8X2, 
         ISTRATA_STATUS_BUSY_8X2);
   } else if (handle_ptr->DEVICES == 4) {
      volatile uint_32 _PTR_  dest_ptr = (volatile uint_32 _PTR_)((pointer)to_ptr);
      uint_32 _PTR_           src_ptr  = (uint_32 _PTR_)((pointer)from_ptr);
      _mem_size               size;
      uint_32                 tmp, status;

      size = sector_size >> 2;
      offset >>= 2;
      dest_ptr = dest_ptr + offset;
      src_ptr  = src_ptr  + offset;

      ISTRATA_PROGRAM(ISTRATA_READ_MODE_CMD_8X4, ISTRATA_WRITE_CMD_8X4, 
         ISTRATA_STATUS_BUSY_8X4);
   } else {
      /* Unsupported configuration */
      return FALSE;
   } /* Endif */

   if (success) {
      /* Verify sector is written correctly */
      for( j = 0; j < sector_size; j++ ) {
         if ( from_ptr[j] != to_ptr[j] ) {
            success = FALSE;
            break;
         } /* Endif */
      } /* Endfor */
   } /* Endif */

   return success;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_erase_1byte
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases a sector
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_erase_1byte
   (
      /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR handle_ptr,

      /* [IN] the sector to erase */
      char_ptr             input_sect_ptr,

      /* [IN] the size of the sector */
      _mem_size            sect_size,

      /* [IN/OUT] place to store start time */
      MQX_TICK_STRUCT_PTR  start_ticks_ptr
   )
{ /* Body */
   boolean timeout = FALSE;
   boolean success = TRUE;

   if (handle_ptr->DEVICES == 1) {
      volatile uchar _PTR_    dest_ptr = (volatile uchar _PTR_)input_sect_ptr;
      uchar                   status;

      ISTRATA_ERASE(ISTRATA_READ_MODE_CMD_8X1, ISTRATA_ERASE_CMD1_8X1, 
         ISTRATA_ERASE_CMD2_8X1, ISTRATA_STATUS_BUSY_8X1, 0xFF);

   } else if (handle_ptr->DEVICES == 2) {
      volatile uint_16 _PTR_  dest_ptr = (volatile uint_16 _PTR_)input_sect_ptr;
      uint_16                 status;

      ISTRATA_ERASE(ISTRATA_READ_MODE_CMD_8X2, ISTRATA_ERASE_CMD1_8X2, 
         ISTRATA_ERASE_CMD2_8X2, ISTRATA_STATUS_BUSY_8X2, 0xFFFF);

   } else if (handle_ptr->DEVICES == 4) {
      volatile uint_32 _PTR_  dest_ptr = (volatile uint_32 _PTR_)input_sect_ptr;
      uint_32                 status;

      ISTRATA_ERASE(ISTRATA_READ_MODE_CMD_8X4, ISTRATA_ERASE_CMD1_8X4, 
         ISTRATA_ERASE_CMD2_8X4, ISTRATA_STATUS_BUSY_8X4, 0xFFFFFFFF);

   } else {
      success = FALSE;
   } /* Endif */

   return success;

} /* Endbody */


/* Start CR 871 */
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_clearlockbits_1byte
* Returned Value   : TRUE if successful
* Comments         : 
*    This function unlocks all sectors
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_clearlockbits_1byte
   (
      /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR handle_ptr,

      /* [IN/OUT] place to store start time */
      MQX_TICK_STRUCT_PTR  start_ticks_ptr
   )
{ /* Body */
   uint_32 block_size;
   uint_32 num_blocks;
   uint_32 i;
   boolean timeout = FALSE;
   boolean success = TRUE;

   num_blocks = handle_ptr->HW_BLOCK->NUM_SECTORS; /* sector == block */
   block_size = handle_ptr->HW_BLOCK->SECTOR_SIZE;

   /*
   ** All blocks default to the locked state after initial power-up or reset.
   ** The blocks are unlocked individually.
   */
   if (handle_ptr->DEVICES == 1) {
      volatile uchar _PTR_    dest_ptr;
      uchar                   status;

      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uchar _PTR_)(handle_ptr->BASE_ADDR + handle_ptr->HW_BLOCK[0].START_ADDR + i * block_size);
         
         ISTRATA_CLEAR_LOCKBITS(ISTRATA_READ_MODE_CMD_8X1, ISTRATA_CLEAR_CMD1_8X1, 
            ISTRATA_CLEAR_CMD2_8X1, ISTRATA_STATUS_BUSY_8X1);
      } /* Endfor */
      
   } else if (handle_ptr->DEVICES == 2) {
      volatile uint_16 _PTR_  dest_ptr;
      uint_16                 status;

      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uint_16 _PTR_)(handle_ptr->BASE_ADDR + handle_ptr->HW_BLOCK[0].START_ADDR + i * block_size);
         
         ISTRATA_CLEAR_LOCKBITS(ISTRATA_READ_MODE_CMD_8X2, ISTRATA_CLEAR_CMD1_8X2, 
            ISTRATA_CLEAR_CMD2_8X2, ISTRATA_STATUS_BUSY_8X2);
      } /* Endfor */
      
   } else if (handle_ptr->DEVICES == 4) {
      volatile uint_32 _PTR_  dest_ptr;
      uint_32                 status;

      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uint_32 _PTR_)(handle_ptr->BASE_ADDR + handle_ptr->HW_BLOCK[0].START_ADDR + i * block_size);
         
         ISTRATA_CLEAR_LOCKBITS(ISTRATA_READ_MODE_CMD_8X4, ISTRATA_CLEAR_CMD1_8X4, 
            ISTRATA_CLEAR_CMD2_8X4, ISTRATA_STATUS_BUSY_8X4);
      } /* Endfor */
      
   } else {
      success = FALSE;
   } /* Endif */

   return success;

} /* Endbody */
/* End CR 871 */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_setlockbits_1byte
* Returned Value   : TRUE if successful
* Comments         : 
*    This function locks all sectors
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_setlockbits_1byte
   (
      /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR handle_ptr,

      /* [IN/OUT] place to store start time */
      MQX_TICK_STRUCT_PTR  start_ticks_ptr
   )
{ /* Body */
   uint_32 block_size;
   uint_32 num_blocks;
   uint_32 i;
   boolean timeout = FALSE;
   boolean success = TRUE;

   num_blocks = handle_ptr->HW_BLOCK->NUM_SECTORS; /* sector == block */
   block_size = handle_ptr->HW_BLOCK->SECTOR_SIZE;

   /*
   ** The blocks are locked individually.
   */
   if (handle_ptr->DEVICES == 1) {
      volatile uchar _PTR_    dest_ptr;
      uchar                   status;

      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uchar _PTR_)(handle_ptr->BASE_ADDR + handle_ptr->HW_BLOCK[0].START_ADDR + i * block_size);
         
         ISTRATA_SET_LOCKBITS(ISTRATA_READ_MODE_CMD_8X1, ISTRATA_SET_CMD1_8X1, 
            ISTRATA_SET_CMD2_8X1, ISTRATA_STATUS_BUSY_8X1);
      } /* Endfor */
      
   } else if (handle_ptr->DEVICES == 2) {
      volatile uint_16 _PTR_  dest_ptr;
      uint_16                 status;

      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uint_16 _PTR_)(handle_ptr->BASE_ADDR + handle_ptr->HW_BLOCK[0].START_ADDR + i * block_size);
         
         ISTRATA_SET_LOCKBITS(ISTRATA_READ_MODE_CMD_8X2, ISTRATA_SET_CMD1_8X2, 
            ISTRATA_SET_CMD2_8X2, ISTRATA_STATUS_BUSY_8X2);
      } /* Endfor */
      
   } else if (handle_ptr->DEVICES == 4) {
      volatile uint_32 _PTR_  dest_ptr;
      uint_32                 status;

      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uint_32 _PTR_)(handle_ptr->BASE_ADDR + handle_ptr->HW_BLOCK[0].START_ADDR + i * block_size);
         
         ISTRATA_SET_LOCKBITS(ISTRATA_READ_MODE_CMD_8X4, ISTRATA_SET_CMD1_8X4, 
            ISTRATA_SET_CMD2_8X4, ISTRATA_STATUS_BUSY_8X4);
      } /* Endfor */
      
   } else {
      success = FALSE;
   } /* Endif */

   return success;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_rtcs.c<|end_filename|>

/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_rtcs.c$
* $Version : 3.8.6.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   Example using RTCS Library.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS
#include <rtcs.h>
#include "sh_rtcs.h" 


boolean Shell_parse_ip_address( char_ptr arg, _ip_address _PTR_ ipaddr_ptr)
{
   uint_32      num[4] =  { 0 };
   uint_32      i, index = 0;
   uint_32      temp = 0;
   
   if (ipaddr_ptr == NULL) return FALSE;
   
   for (i=0; arg[i] && (i<16) && (index<4); i++)  {
      if (isdigit(arg[i]))  {
         num[index] = num[index]*10 + arg[i]-'0';
      } else if (arg[i] == '.') {
         index++; 
      } else  {
         return FALSE;
      }
   }
   
   if ((arg[i] == '\0') && (index==3))  {
      for (i=0;i<4;i++)  {
         if (num[i] > 255)  {
            return FALSE;
         } else  {
            temp = (temp << 8) | num[i];
         }
      } 
   } 

   *ipaddr_ptr = temp;
   return TRUE;
}

boolean Shell_parse_netmask( char_ptr arg, _ip_address _PTR_ ipaddr_ptr)
{
   uint_32  i, mask;
   boolean  ones = FALSE;
   
   if ( ipaddr_ptr == NULL) return FALSE;
   
   if (!Shell_parse_ip_address(arg, ipaddr_ptr))  return FALSE;

   
   for (i=0;i<32;i++)  {
      mask = *ipaddr_ptr & (1<<i); 
      if (!ones)  {
         if (mask)  {
            ones = TRUE;
         }
      } else {
         if  (! mask)  {
            return FALSE;   
         }  
      } 
   }   
   return TRUE;
}

#endif /* SHELLCFG_USES_RTCS */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/pktrx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pktrx.c$
* $Version : 3.8.13.0$
* $Date    : Sep-25-2012$
*
* Comments:
*
*   This file contains the implementation of the PPP Rx
*   task.
*
*END************************************************************************/

#include <ppp.h>
#include "ppp_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_findprot
* Returned Value  :  TRUE if protocol is registered
* Comments        :
*     Finds a protocol callback.  If found, the callback is
*     moved to the head of the list.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean PPP_findprot
   (
      PPP_CFG_PTR    ppp_ptr,
            /* [IN] - the PPP state structure */
      uint_16        protocol
            /* [IN] - protocol */
   )
{ /* Body */
   PROT_CALL_PTR _PTR_  search_ptr;
   boolean              found;

   for (search_ptr = &ppp_ptr->PROT_CALLS;;
        search_ptr = &(*search_ptr)->NEXT) {
      if (*search_ptr == NULL) {
         found = FALSE;
         break;
      } else if ((*search_ptr)->PROTOCOL == protocol) {
         found = TRUE;
         break;
      } /* Endif */
   } /* Endfor */

   if (found) {
      PROT_CALL_PTR prot_ptr = *search_ptr;
      *search_ptr = prot_ptr->NEXT;
      prot_ptr->NEXT = ppp_ptr->PROT_CALLS;
      ppp_ptr->PROT_CALLS = prot_ptr;
   } /* Endif */

   return found;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_register
* Returned Value  :  error code
* Comments        :
*     Registers a callback function for a protocol.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_register
   (
      _ppp_handle         handle,
            /* [IN] - the PPP state structure */
      uint_16             protocol,
            /* [IN] - protocol */
      void (_CODE_PTR_    callback)(PCB_PTR, pointer),
            /* [IN] - callback function */
      pointer             parameter
            /* [IN] - first parameter for callback function */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR    ppp_ptr = handle;
   PROT_CALL_PTR  prot_ptr;

   /* Do some error checking */
   if (ppp_ptr->VALID != PPP_VALID) {
      return RTCSERR_PPP_INVALID_HANDLE;
   } else if (!(protocol&1) || (protocol&0x100)) {
      return RTCSERR_PPP_INVALID_PROTOCOL;
   } /* Endif */

   /* Allocate a callback structure */
   prot_ptr = _mem_alloc_system_zero(sizeof(PROT_CALL));
   if (prot_ptr == NULL) {
      return RTCSERR_PPP_ALLOC_CALL_FAILED;
   } /* Endif */
   protocol &= 0xFFFF;
   prot_ptr->PROTOCOL = protocol;
   prot_ptr->CALLBACK = callback;
   prot_ptr->PARAM    = parameter;

   PPP_mutex_lock(&ppp_ptr->MUTEX);

   if (PPP_findprot(ppp_ptr, protocol)) {
      ppp_ptr->PROT_CALLS->CALLBACK = callback;
      ppp_ptr->PROT_CALLS->PARAM    = parameter;
   } else {
      prot_ptr->NEXT      = ppp_ptr->PROT_CALLS;
      ppp_ptr->PROT_CALLS = prot_ptr;
      prot_ptr = NULL;
   } /* Endif */

   PPP_mutex_unlock(&ppp_ptr->MUTEX);

   if (prot_ptr) {
      _mem_free(prot_ptr);
   } /* Endif */

   return PPP_OK;

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */      

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_unregister
* Returned Value  :  error code
* Comments        :
*     Unregisters a callback function for a protocol.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_unregister
   (
      _ppp_handle         handle,
            /* [IN] - the PPP state structure */
      uint_16             protocol
            /* [IN] - protocol */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR    ppp_ptr = handle;
   PROT_CALL_PTR  prot_ptr;
   uint_32        error;

   /* Do some error checking */
   if (ppp_ptr->VALID != PPP_VALID) {
      return RTCSERR_PPP_INVALID_HANDLE;
   } else if (!(protocol&1) || (protocol&0x100)) {
      return RTCSERR_PPP_INVALID_PROTOCOL;
   } else if (!(~protocol & 0xC000)) {
      /* Don't allow unregistering LCP */
      return RTCSERR_PPP_INVALID_PROTOCOL;
   } /* Endif */

   /* Remove structure from list */
   protocol &= 0xFFFF;
   prot_ptr = NULL;
   error = RTCSERR_PPP_PROT_NOT_FOUND;
   PPP_mutex_lock(&ppp_ptr->MUTEX);

   if (PPP_findprot(ppp_ptr, protocol)) {
      prot_ptr = ppp_ptr->PROT_CALLS;
      ppp_ptr->PROT_CALLS = prot_ptr->NEXT;
      error = PPP_OK;
   } /* Endif */

   PPP_mutex_unlock(&ppp_ptr->MUTEX);

   if (prot_ptr) {
      _mem_free(prot_ptr);
   } /* Endif */

   return error;

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */  

} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Task Name       :   PPP_rx_task
* Comments        :
*     This task receives and forwards incoming packets.
*
*END*-----------------------------------------------------------------*/

void PPP_rx_task
   (
      pointer     handle,
            /* [IN] - the PPP state structure */
      pointer     creator
            /* [IN] - the task create information */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR          ppp_ptr = handle;
   PCB_PTR              pcb;
   boolean              linkstate, linkauth;
   PPP_OPT              opt;
   uint_16              protocol, len;
   void (_CODE_PTR_     callback)(PCB_PTR, pointer);
   pointer              param;


    ppp_ptr->RX_TASKID = RTCS_task_getid();
    RTCS_task_resume_creator(creator, PPP_OK);

      /* Wait for incoming packets */
    for (;;) 
    {
        /* check if app shutdown (STOP_RX == TRUE) */                
        if(ppp_ptr->STOP_RX)
        {
               break;
        }     
      /**********************************************************
      **
      **    Wait for a frame
      **
      ***********************************************************/

        /* Read a frame */
        /*Lets use flag for send pointer to ppp_ptr->STOP_RX */
        pcb = _iopcb_read(ppp_ptr->DEVICE, (uint_32)&(ppp_ptr->STOP_RX));  

        if(NULL == pcb)  
        {  
 	        _time_delay(1);  
            continue;  
        }  
      len = pcb->FRAG[0].LENGTH;
      if (len < 2) 
      {
         PCB_free(pcb);
         ppp_ptr->ST_RX_RUNT++;
         continue;
      } /* Endif */
      protocol = ntohs(pcb->FRAG[0].FRAGMENT);

      /* Read the negotiated Receive options */
      PPP_mutex_lock(&ppp_ptr->MUTEX);
      linkstate = ppp_ptr->LINK_STATE;
      linkauth  = ppp_ptr->LINK_AUTH;
      opt = *ppp_ptr->RECV_OPTIONS;
      PPP_mutex_unlock(&ppp_ptr->MUTEX);

      /* Discard all non-LCP packets until the link is opened */
      if (protocol != PPP_PROT_LCP) {
         if (!linkstate) {
            PCB_free(pcb);
            ppp_ptr->ST_RX_DISCARDED++;
            continue;
         } /* Endif */
         /* and all non-AP packets until the link is authenticated */
         if (protocol != opt.AP) {
            if (!linkauth) {
               PCB_free(pcb);
               ppp_ptr->ST_RX_DISCARDED++;
               continue;
            } /* Endif */
         } /* Endif */
      } /* Endif */

      /* Decompress the packet if compression was negotiated */
      if ((protocol == PPP_PROT_CP) && opt.CP) {
         pcb = opt.CP->CP_decomp(&ppp_ptr->CCP_STATE.RECV_DATA, pcb, ppp_ptr, &opt);
         protocol = ntohs(pcb->FRAG[0].FRAGMENT);
      } /* Endif */

      /**********************************************************
      **
      **    Forward the packet to higher-level protocol
      **
      */

      /* Find out where to send the packet */
      ppp_ptr->ST_RX_RECEIVED++;


      /*
      ** We could put the known protocols in the PROT_CALLS
      ** list, but we don't because we always want them to
      ** work, even if someone tries to PPP_unregister() them.
      */
      switch (protocol) {

         /* Got an LCP packet */
      case PPP_PROT_LCP:
         LCP_input(pcb, &ppp_ptr->LCP_FSM);
         break;

         /* Got a CCP packet */
      case PPP_PROT_CCP:
         CCP_input(pcb, &ppp_ptr->CCP_FSM);
         break;

         /* Got a PAP packet */
      case PPP_PROT_PAP:
         PAP_input(pcb, ppp_ptr);
         break;

         /* Got a CHAP packet */
      case PPP_PROT_CHAP:
         CHAP_input(pcb, ppp_ptr);
         break;

      default:
         callback = NULL;
         PPP_mutex_lock(&ppp_ptr->MUTEX);
         if (PPP_findprot(ppp_ptr, protocol)) {
            callback = ppp_ptr->PROT_CALLS->CALLBACK;
            param    = ppp_ptr->PROT_CALLS->PARAM;
         } /* Endif */
         PPP_mutex_unlock(&ppp_ptr->MUTEX);

         if (callback) {
            callback(pcb, param);
         } else {
            /* No callback found -- Send Protocol-Reject */
            LCP_sendprotrej(pcb, &ppp_ptr->LCP_FSM);
         } /* Endif */
         break;
      } /* Endswitch */

   } /* Endfor */
   /* We can start task again. (STOP_RX == FALSE) */
   ppp_ptr->STOP_RX = FALSE; 
#endif /* RTCSCFG_ENABLE_IP4 */


} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/string/strnlen.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: strnlen.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the function for calculating the length of a 
*   string, length limited.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "mqx_str.h"

/*!
 * \brief Gets the length of the length-limited string.
 * 
 * \param[in] string_ptr The address of the string.
 * \param[in] max_len    Maximum number of characters in the string.
 * 
 * \return The number of characters in the string.
 * 
 * \see _str_mqx_uint_to_hex_string 
 */ 
_mqx_uint _strnlen
   (
      register char_ptr  string_ptr,
      register _mqx_uint max_len
   )
{ /* Body */
   register _mqx_uint i = 0;

   
   while (*string_ptr++ && max_len--) {
      ++i;
   } /* Endwhile */

   return(i);
   
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/can/flexcan/flexcan_mcf5225.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flexcan_mcf5225.c$
* $Version : 3.6.7.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   Processor family specific file needed for flexcan module.
*   Revision History:
*   Date             Version  Changes
*   ---------        -------  -------
*   Sep 26/08        2.50     Initial version
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <flexcan.h>

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_flexcan_base_address  
* Returned Value   : Pointer to desired CAN device or NULL if not present
* Comments         :
*    This function returns pointer to base address of address space of the 
*    desired CAN device. Returns NULL otherwise.
*
*END*********************************************************************/
pointer _bsp_get_flexcan_base_address
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{ /* Body */
    if (dev_num != 0)
    {
        return NULL;
    }
   
    return (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->FCAN);
} /* EndBody */

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_flexcan_vector
* Returned Value   : MQX vector number for specified interrupt
* Comments         :
*    This function returns index into MQX interrupt vector table for
*    specified flexcan interrupt. If not known, returns 0.
*
*END*********************************************************************/
PSP_INTERRUPT_TABLE_INDEX _bsp_get_flexcan_vector 
(
   /* [IN] FlexCAN device number */
    uint_8 dev_num,
   /* [IN] FlexCAN interrupt vector type */
    uint_8 vector_type,
   /* [IN] FlexCAN interrupt vector index */
    uint_32 vector_index
)
{ /* Body */
   volatile PSP_INTERRUPT_TABLE_INDEX index = (PSP_INTERRUPT_TABLE_INDEX) 0;
   
   if (dev_num != 0) 
      return index;
   
   switch (vector_type)
   {
      case FLEXCAN_INT_BUF:
           switch (vector_index)
           {
               case (0):
                  index = MCF5225_INT_FLEXCAN_BUF0;
                  break;
               case (1):
                  index = MCF5225_INT_FLEXCAN_BUF1;
                  break;
               case (2):
                  index = MCF5225_INT_FLEXCAN_BUF2;
                  break;
               case (3):
                  index = MCF5225_INT_FLEXCAN_BUF3;
                  break;
               case (4):
                  index = MCF5225_INT_FLEXCAN_BUF4;
                  break;
               case (5):
                  index = MCF5225_INT_FLEXCAN_BUF5;
                  break;
               case (6):
                  index = MCF5225_INT_FLEXCAN_BUF6;
                  break;
               case (7):
                  index = MCF5225_INT_FLEXCAN_BUF7;
                  break;
               case (8):
                  index = MCF5225_INT_FLEXCAN_BUF8;
                  break;
               case (9):
                  index = MCF5225_INT_FLEXCAN_BUF9;
                  break;
               case (10):
                  index = MCF5225_INT_FLEXCAN_BUF10;
                  break;
               case (11):
                  index = MCF5225_INT_FLEXCAN_BUF11;
                  break;
               case (12):
                  index = MCF5225_INT_FLEXCAN_BUF12;
                  break;
               case (13):
                  index = MCF5225_INT_FLEXCAN_BUF13;
                  break;
               case (14):
                  index = MCF5225_INT_FLEXCAN_BUF14;
                  break;
               case (15):
                  index = MCF5225_INT_FLEXCAN_BUF15;
                  break;
               default:
                  break;
           }
           break;
      case FLEXCAN_INT_ERR:
           index = MCF5225_INT_FLEXCAN_ERR_INT;
           break;
      case FLEXCAN_INT_BOFF:
           index = MCF5225_INT_FLEXCAN_BOFF_INT;
           break;
      default:
           break;
   }
   return index;
} /* EndBody */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enerr.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enerr.c$
* $Version : 3.8.7.0$
* $Date    : Sep-20-2012$
*
* Comments:
*
*   This file contains the Ethernet error reporting
*   functions.
*
*END************************************************************************/

#include <mqx.h>
#include "enet.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_strerror
*  Returned Value : pointer to error string
*  Comments       :
*        Returns a string describing an error code
*
*END*-----------------------------------------------------------------*/

static const char_ptr ENET_errlist[ENETERR_MAX - ENETERR_MIN + 1] = {
   "Invalid device number",                           /* ENETERR_INVALID_DEVICE     */
   "Device already initialized",                      /* ENETERR_INIT_DEVICE        */
   "Couldn't allocate state (out of memory)",         /* ENETERR_ALLOC_CFG          */
   "Couldn't allocate PCBs (out of memory)",          /* ENETERR_ALLOC_PCB          */
   "Couldn't allocate buffer descriptors",            /* ENETERR_ALLOC_BD           */
   "Couldn't install Ethernet notifier",              /* ENETERR_INSTALL_ISR        */
   "Some PCBs are still in use",                      /* ENETERR_FREE_PCB           */
   "Out of memory",                                   /* ENETERR_ALLOC_ECB          */
   "Protocol already open",                           /* ENETERR_OPEN_PROT          */
   "Not an open protocol",                            /* ENETERR_CLOSE_PROT         */
   "Packet too short",                                /* ENETERR_SEND_SHORT         */
   "Packet too long",                                 /* ENETERR_SEND_LONG          */
   "Not a multicast address",                         /* ENETERR_JOIN_MULTICAST     */
   "Out of memory",                                   /* ENETERR_ALLOC_MCB          */
   "Not a joined group",                              /* ENETERR_LEAVE_GROUP        */
   "Tranmit ring full",                               /* ENETERR_SEND_FULL          */
   "IP Table full of IP pairs",                       /* ENETERR_IP_TABLE_FULL      */
   "Generic alloc failed",                            /* ENETERR_ALLOC              */
   "Device failed to initialize",                     /* ENETERR_INIT_FAILED        */
   "Device read or write timeout",                    /* ENETERR_DEVICE_TIMEOUT     */
   "Couldn't allocate buffers (out of memory)",       /* ENETERR_ALLOC_BUFFERS      */
   "Couldn't allocate MAC context (out of memory)",   /* ENETERR_ALLOC_MAC_CONTEXT  */
   "Couldn't allocate TX buffer (out of memory)",     /* ENETERR_NO_TX_BUFFER       */
   "Invalid initialization parameter",                /* ENETERR_INVALID_INIT_PARAM */
   "Shutdown failed, device in use",                  /* ENETERR_DEVICE_IN_USE      */
   "Device already initialized",                      /* ENETERR_INITIALIZED_DEVICE */
   "Setting of ESSID in progress",                    /* ENETERR_INPROGRESS         */
   "1588 driver lwevent creation failed",             /* ENETERR_1588_LWEVENT       */
   "Invalid mode for this ethernet driver",           /* ENETERR_INVALID_MODE       */
   "Invalid option for this ethernet driver"          /* ENETERR_INVALID_OPTION     */
};



const char * ENET_strerror
   (
      /* [IN] the ENET error code */
      _mqx_uint  error
   )
{ 
   if (error == ENET_OK) {
      return "OK";
   } 
   if ((error < ENETERR_MIN) || (error > ENETERR_MAX)) {
      return "Unknown error";
   } 
   return ENET_errlist[error - ENETERR_MIN];
}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_ghand.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_ghand.c$
* $Version : 3.5.4.0$
* $Date    : Dec-8-2009$
*
* Comments:
*
*   This file contains the function for returning the current I/O handler
*   in the kernel data structure, or in a task.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "io.h"

#if MQX_USE_IO
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_get_handle
* Returned Value   : pointer
* Comments         : 
*
*    This function returns the address of a default standard I/O FILE.
*    If an incorrect type is given, or the file_ptr has not been specified,
*    the function will return NULL.
* 
*END*----------------------------------------------------------------------*/

pointer _io_get_handle
   (
      /* [IN] which I/O handle to return */
      _mqx_uint stdio_type
   )
{ /* Body */
   register KERNEL_DATA_STRUCT_PTR  kernel_data;

   _GET_KERNEL_DATA(kernel_data);
   switch ( (uint_16)stdio_type ) {

      case IO_PROC_STDIN:
         return kernel_data->PROCESSOR_STDIN;

      case IO_PROC_STDOUT:
         return kernel_data->PROCESSOR_STDOUT;

      case IO_PROC_STDERR:
         return kernel_data->PROCESSOR_STDERR;

      case IO_STDIN:
         return kernel_data->ACTIVE_PTR->STDIN_STREAM;

      case IO_STDOUT:
         return kernel_data->ACTIVE_PTR->STDOUT_STREAM;

      case IO_STDERR:
         return kernel_data->ACTIVE_PTR->STDERR_STREAM;

      default:
         return (pointer) NULL;

   } /* Endswitch */

} /* Endbody */
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/rtc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtc.c$
* $Version : 3.6.18.0$
* $Date    : Nov-2-2010$
*
* Comments:
*           Kinetis RTC driver header
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>                    

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_time_to_mqx_time
* Returned Value   : none
* Comments         :
*    This function transforms RTC time format to MQX time format.
*    RTC time range is wider (65536 days vs. 49710 days), overflow is not checked,
*    miliseconds are set to 0.
*
*END*********************************************************************/
void _rtc_time_to_mqx_time 
(
    /* [IN] RTC time representation */
    RTC_TIME_STRUCT_PTR rtc_time, 
    /* [OUT] MQX time representation */
    TIME_STRUCT_PTR mqx_time
)
{
    mqx_time->MILLISECONDS = 0;
    mqx_time->SECONDS = rtc_time->seconds + (rtc_time->minutes * 60L) + (rtc_time->hours * 3600L) + (rtc_time->days * 86400L);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_time_from_mqx_time
* Returned Value   : none
* Comments         :
*    This function transforms MQX time format to RTC time format.
*    MQX time range is shorter (49710 days vs. 65536 days), miliseconds are ignored.
*
*END*********************************************************************/

void _rtc_time_from_mqx_time
(
    /* [IN] MQX time representation */
    TIME_STRUCT_PTR mqx_time, 
    /* [OUT] RTC time representation */
    RTC_TIME_STRUCT_PTR rtc_time
)
{
    register uint_32 div, mod;
    
    mod  = mqx_time->SECONDS;
    div  = mod / 86400;
    mod -= div * 86400;
    rtc_time->days = (uint_16)div;
    div  = mod / 3600;
    mod -= div * 3600;
    rtc_time->hours = (uint_8)div;
    div  = mod / 60;
    mod -= div * 60;
    rtc_time->minutes = (uint_8)div;
    rtc_time->seconds = (uint_8)mod;
}


/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_sync_with_mqx
* Returned Value   : none
* Comments         :
*    This function synchronizes RTC time with MQX time.
*
*END*********************************************************************/
_mqx_int _rtc_sync_with_mqx 
(
    /* [IN] whether to update MQX time (source is RTC) or RTC time (source is MQX) */
    boolean update_mqx
)
{
    RTC_TIME_STRUCT rtc_time;
    TIME_STRUCT mqx_time;
    
    if (update_mqx) 
    {
        _rtc_get_time (&rtc_time);
        _rtc_time_to_mqx_time (&rtc_time, &mqx_time);
        _time_set (&mqx_time);
    }
    else
    {
        _time_get (&mqx_time);
        _rtc_time_from_mqx_time (&mqx_time, &rtc_time);
        _rtc_set_time (&rtc_time);
    }
    return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb/usb_mcf5225.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_mcf5225.c$
* $Version : 3.8.15.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains board-specific USB initialization functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"

struct usb_host_if_struct _bsp_usb_host_khci0_if = {
    &_usb_khci_host_callback_table,
    (pointer) &_khci0_host_init_param,
    NULL
};

_mqx_int _bsp_usb_init(pointer param);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_usb_init
* Returned Value   : 0 for success, -1 for failure
* Comments         :
*    This function performs BSP-specific initialization related to USB
*
*END*----------------------------------------------------------------------*/
_mqx_int _bsp_usb_init(pointer param)
{
    uint_32 status;

    _bsp_usb_io_init();

    // setup interrupt
    status = _bsp_int_init(MCF5225_INT_USB, 3, 0, TRUE);

    if (status != MQX_OK)
    {
        return -1;
    }

    return MQX_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_usb_host_init
* Returned Value   : 0 for success, -1 for failure
* Comments         :
*    This function performs BSP-specific initialization related to USB host
*
*END*----------------------------------------------------------------------*/
_mqx_int _bsp_usb_host_init(struct usb_host_if_struct *usb_if)
{
    return _bsp_usb_init(NULL);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_usb_capability_register_base
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the address of the VUSBHS Capability Registers
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_usb_base(uint_8 dev_num)
{
   if (dev_num != 0)
   {
      return NULL;
   }
   
   return (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->USBOTG);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_usb_vector
* Returned Value   : Vector Number upon success, 0 upon failure
* Comments         :
*    This function returns the vector number of the VUSBHS Host Module
*
*END*----------------------------------------------------------------------*/
uint_8 _bsp_get_usb_vector
(
   uint_8 dev_num
)
{
   if (dev_num != 0)
   {
      return 0;
   }
   
   return MCF5225_INT_USB;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/linflexd.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: linflexd.h$
* $Version :  3.8.3.0$
* $Date    :  Sep-26-2012$
*
* Comments:
*   This include file provides the register defintons for the LinFlexd Uart.
*
*
*END************************************************************************/

#ifndef __linflexd_h__
#define __linflexd_h__ 1


/*--------------------------------------------------------------------------*/
/*
**                    CONSTANT DEFINITIONS
*/

#define LINFLEXD_LINCR1_INIT        (1<<0)

#define LINFLEXD_LINIER_SZIE        (1<<15)
#define LINFLEXD_LINIER_OCIE        (1<<14)
#define LINFLEXD_LINIER_BEIE        (1<<13)
#define LINFLEXD_LINIER_CEIE        (1<<12)
#define LINFLEXD_LINIER_HEIE        (1<<11)
#define LINFLEXD_LINIER_FEIE        (1<<8)
#define LINFLEXD_LINIER_BOIE        (1<<7)
#define LINFLEXD_LINIER_LSIE        (1<<6)
#define LINFLEXD_LINIER_WUIE        (1<<5)
#define LINFLEXD_LINIER_DBFIE       (1<<4)
#define LINFLEXD_LINIER_DBEIETOIE   (1<<3)
#define LINFLEXD_LINIER_DRIE        (1<<2)
#define LINFLEXD_LINIER_DTIE        (1<<1)
#define LINFLEXD_LINIER_HRIE        (1<<0)

#if defined(PSP_MPXD10)
#define LINFLEXD_UARTCR_TDFLTFC_MASK 0x6000
#define LINFLEXD_UARTCR_RDFLRFC_MASK 0xc00
#else
#define LINFLEXD_UARTCR_TDFLTFC_MASK 0xe000
#define LINFLEXD_UARTCR_RDFLRFC_MASK 0x1c00
#endif

#define LINFLEXD_UARTCR_TDFLTFC_SHIFT 13
#define LINFLEXD_UARTCR_RDFLRFC_SHIFT 10

#if defined(PSP_MPXD10)
  #define LINFLEXD_UARTCR_RESERVED_25    (1<<9)
  #define LINFLEXD_UARTCR_RESERVED_24    (1<<8)
  #define LINFLEXD_UARTCR_RESERVED_23    (1<<7)
  #define LINFLEXD_UARTCR_RESERVED_22    (1<<6)
#else /* PXD10 doesn't support these bits */
#define LINFLEXD_UARTCR_RFBM    (1<<9)
#define LINFLEXD_UARTCR_TFBM    (1<<8)
#define LINFLEXD_UARTCR_WL1     (1<<7)
#define LINFLEXD_UARTCR_PC1     (1<<6)
#endif

#define LINFLEXD_UARTCR_RXEN    (1<<5)
#define LINFLEXD_UARTCR_TXEN    (1<<4)
#if defined(PSP_MPXD10)
#define LINFLEXD_UARTCR_OP     (1<<3)
#else
#define LINFLEXD_UARTCR_PC0     (1<<3)
#endif

#define LINFLEXD_UARTCR_PCE     (1<<2)
#define LINFLEXD_UARTCR_WL0     (1<<1)
#define LINFLEXD_UARTCR_UART    (1<<0)

#define LINFLEXD_UARTSR_SZF     (1<<15)
#define LINFLEXD_UARTSR_OCF     (1<<14)
#define LINFLEXD_UARTSR_PE3     (1<<13)
#define LINFLEXD_UARTSR_PE2     (1<<12)
#define LINFLEXD_UARTSR_PE1     (1<<11)
#define LINFLEXD_UARTSR_PE0     (1<<10)
#define LINFLEXD_UARTSR_RMB     (1<<9)
#define LINFLEXD_UARTSR_FEF     (1<<8)
#define LINFLEXD_UARTSR_BOF     (1<<7)
#define LINFLEXD_UARTSR_RPS     (1<<6)
#define LINFLEXD_UARTSR_WUF     (1<<5)
#define LINFLEXD_UARTSR_4       (1<<4)
  
#if defined(PSP_MPXD10)
#define LINFLEXD_UARTSR_RESERVED_28 (1<<3)
#else
#define LINFLEXD_UARTSR_TO      (1<<3)
#endif
  
#define LINFLEXD_UARTSR_DRFRFE  (1<<2)
#define LINFLEXD_UARTSR_DTFTFF  (1<<1)
#define LINFLEXD_UARTSR_NF      (1<<0)
#define LINFLEXD_UARTSR_PE      (LINFLEXD_UARTSR_PE0|LINFLEXD_UARTSR_PE1|LINFLEXD_UARTSR_PE2|LINFLEXD_UARTSR_PE3)


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

typedef volatile struct linflexd_reg_struct
{
    uint_32   LINCR1;  // 0x0000 LIN control register 1
    uint_32   LINIER;  // 0x0004 LIN interrupt enable register
    uint_32   LINSR;   // 0x0008 LIN status register
    uint_32   LINESR;  // 0x000C LIN error status register
    uint_32   UARTCR;  // 0x0010 UART mode control register
    uint_32   UARTSR;  // 0x0014 UART mode status register
    uint_32   LINTCSR; // 0x0018 LIN timeout control status register
    uint_32   LINOCR;  // 0x001C LIN output compare register
    uint_32   LINTOCR; // 0x0020 LIN timeout control register
    uint_32   LINFBRR; // 0x0024 LIN fractional baud rate register
    uint_32   LINIBRR; // 0x0028 LIN integer baud rate register
    uint_32   LINCFR;  // 0x002C LIN checksum field register
    uint_32   LINCR2;  // 0x0030 LIN control register 2
    uint_32   BIDR;    // 0x0034 Buffer identifier register
    uchar     BDRL[4]; // 0x0038 Buffer data register least significant
    uchar     BDRM[4]; // 0x003C Buffer data register most significant
    uint_32   IFER;    // 0x0040 Identifier filter enable register
    uint_32   IFMI;    // 0x0044 Identifier filter match index
    uint_32   IFMR;    // 0x0048 Identifier filter mode register
    uint_32   IFCR0;   // 0x004C Identifier filter control register 0
    uint_32   IFCR1;   // 0x0050 Identifier filter control register 1
    uint_32   IFCR2;   // 0x0054 Identifier filter control register 2
    uint_32   IFCR3;   // 0x0058 Identifier filter control register 3
    uint_32   IFCR4;   // 0x005C Identifier filter control register 4
    uint_32   IFCR5;   // 0x0060 Identifier filter control register 5
    uint_32   IFCR6;   // 0x0064 Identifier filter control register 6
    uint_32   IFCR7;   // 0x0068 Identifier filter control register 7
    uint_32   IFCR8;   // 0x006C Identifier filter control register 8
    uint_32   IFCR9;   // 0x0070 Identifier filter control register 9
    uint_32   IFCR10;  // 0x0074 Identifier filter control register 10
    uint_32   IFCR11;  // 0x0078 Identifier filter control register 11
    uint_32   IFCR12;  // 0x007C Identifier filter control register 12
    uint_32   IFCR13;  // 0x0080 Identifier filter control register 13
    uint_32   IFCR14;  // 0x0084 Identifier filter control register 14
    uint_32   IFCR15;  // 0x0088 Identifier filter control register 15
    uint_32   GCR;     // 0x008C Global control register
    uint_32   UARTPTO; // 0x0090 UART preset timeout register
    uint_32   UARTCTO; // 0x0094 UART current timeout register
    uint_32   DMATXE;  // 0x0098 DMA Tx enable register
    uint_32   DMARXE;  // 0x009C DMAx enable register

} LINFLEXD_REG_STRUCT;

typedef volatile struct linflexd_reg_struct *VLINFLEXD_REG_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

VLINFLEXD_REG_STRUCT_PTR _bsp_get_linflexd_base_address(uint_32 channel);

#ifdef __cplusplus
}
#endif

#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5xxx_fec_stop.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5xxx_fec_stop.c$
* $Version : 3.0.1.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   This file contains the MCF5xxx Ethernet shutdown
*   functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "mcf5xxx_fec_prv.h"          

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_shutdown
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Stops the chip.
*
*END*-----------------------------------------------------------------*/

uint_32 MCF5XXX_FEC_shutdown
   (
      ENET_CONTEXT_STRUCT_PTR  enet_ptr
         /* [IN] the Ethernet state structure */
   )
{ /* Body */
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR    fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   VMCF5XXX_FEC_STRUCT_PTR           fec_ptr= fec_context_ptr->FEC_ADDRESS;

   if (fec_ptr == NULL) return ENETERR_INVALID_DEVICE;

   /* Stop the chip */
   fec_ptr->ECR = MCF5XXX_FEC_ECR_RESET;

   /* Disable all FEC interrupts */
   fec_ptr->EIMR = 0;

   /* clear any pending interrpts */
   fec_ptr->EIR = MCF5XXX_FEC_EIR_ALL_PENDING;

   /* Stop the FEC from interrupting the core */
    MCF5XXX_FEC_mask_interrupts( enet_ptr );

   #if BSPCFG_ENET_RESTORE
      /* Restore old ISRs */
      MCF5XXX_FEC_uninstall_all_isrs( enet_ptr );
   #endif

    /*
    ** Make sure all PCBs are free
    */
    if (fec_context_ptr->ActiveRxBDs != fec_context_ptr->NumRxBDs) {
       return ENETERR_FREE_PCB;
    } 

   MCF5XXX_FEC_free_context(fec_context_ptr);
   return ENET_OK;

} 


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/md5.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: md5.c$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the implementation of the MD5
*   message digest algorithm described in RFC 1321.
*
*END************************************************************************/

#include <stdarg.h>
#include <ppp.h>
#include "ppp_prv.h"
#include "md5.h"



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_MD5
* Returned Value  :  void
* Comments        :
*     Computes the MD5 hash of a sequence of bytes.
*
*     The prototype is:
*        PPP_MD5(digest, len1, msg1, len2, msg2, ..., lenk, msgk, 0);
*
* Limitations     :
*     This function returns an incorrect hash if the complete byte
*     sequence exceeds 512MB in length.
*
*END*-----------------------------------------------------------------*/

void PPP_MD5
   (
      uchar_ptr digest,
            /* [OUT] - the MD5 message digest */
      ...
            /* [IN] - (uint_32, uchar_ptr) pairs */
   )
{ /* Body */
   va_list   ap;
   uint_32   block[16];
   uint_32   context[4];
   uint_32   temp;
   uint_32   bcount = 0, wcount = 0;
   uint_32   lenmsg = 0;
   uint_32   lenfrag;
   uchar_ptr msgfrag;

   va_start(ap, digest);

   context[0] = 0x67452301l;
   context[1] = 0xEFCDAB89l;
   context[2] = 0x98BADCFEl;
   context[3] = 0x10325476l;

   PPP_memzero(block, sizeof(block));

      /* Loop for each message fragment */
   for (;;) {

         /* Get the next message fragment */
      lenfrag = va_arg(ap, uint_32);
      if (lenfrag == 0) break;
      lenmsg += lenfrag;
      msgfrag = va_arg(ap, uchar_ptr);

         /* Copy bytes from the fragment to the block */
      while (lenfrag--) {
         temp = *msgfrag++ & 0xFF;
         block[wcount] >>= 8;
         block[wcount] |= temp << 24;
         if (++bcount == 4) {
            bcount = 0;
            if (++wcount == 16) {
               wcount = 0;
               PPP_MD5_block(context, block, mdtab);
            } /* Endif */
         } /* Endif */
      } /* Endwhile */

   } /* Endfor */

      /* Now append 0x80 */
   block[wcount] >>= 8;
   block[wcount] |= 0x80000000l;
   if (++bcount == 4) {
      bcount = 0;
      if (++wcount == 16) {
         wcount = 0;
         PPP_MD5_block(context, block, mdtab);
      } /* Endif */
   } /* Endif */

      /* Pad with 0 until wcount==14 */
   if (bcount > 0) {
      block[wcount++] >>= 8*(4-bcount);
      /* bcount henceforth ignored */
   } /* Endif */
   if (wcount > 14) {
      while (wcount < 16) block[wcount++] = 0;
      PPP_MD5_block(context, block, mdtab);
      wcount = 14;   /* PPP_MD5_task_block zeroes block */
   } /* Endif */
   while (wcount < 14) block[wcount++] = 0;

      /* Finally, append the pre-pad length */
   lenmsg <<= 3;     /* length must be in bits */
   block[14] = lenmsg;
   block[15] = 0;
   PPP_MD5_block(context, block, mdtab);

      /* Write the hash out to digest while destroying context */
   for (wcount = 0; wcount < 4; wcount++) {
      for (bcount = 0; bcount < 4; bcount++) {
         *digest++ = context[wcount] & 0xFF;
         context[wcount] >>= 8;
      } /* Endfor */
   } /* Endfor */

   va_end(ap);

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GMCLIB/GMCLIB_ParkInv.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GMCLIB_ParkInv.h
*
*
* @author    <NAME>
*
* @version   1.0.1.0
*
* @date      Dec-6-2012
*
* @brief     Header file for Inverse Park Transformation algorithm.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GMCLIB_PARK_INV_H_
#define _GMCLIB_PARK_INV_H_

#ifdef __cplusplus
extern "C" {
#endif


#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif

/************************************************************************
| defines and macros (scope: module-local)
|-----------------------------------------------------------------------*/
/*! Function alias for the #GMCLIB_ParkInvANSIC function.*/
#define GMCLIB_ParkInv(pOut, pInAngle, pIn) GMCLIB_ParkInvANSIC(pOut, pInAngle, pIn)

/************************************************************************
| typedefs and structures (scope: module-local)
|-----------------------------------------------------------------------*/

/************************************************************************
| exported function prototypes
|-----------------------------------------------------------------------*/
/*!
* @ingroup GMCLIB_GROUP
*/
extern void GMCLIB_ParkInvANSIC (MCLIB_2_COOR_SYST_ALPHA_BETA_T *pOut,
                          const MCLIB_ANGLE_T *const pInAngle,
                          const MCLIB_2_COOR_SYST_D_Q_T  *const pIn);

#ifdef __cplusplus
}
#endif
#endif /* _GMCLIB_PARK_INV_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/FTFL_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type FTFL
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(FTFL_PDD_H_)
#define FTFL_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error FTFL PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* FTFL */ && \
      !defined(MCU_MK10D5) /* FTFL */ && \
      !defined(MCU_MK10D7) /* FTFL */ && \
      !defined(MCU_MK10DZ10) /* FTFL */ && \
      !defined(MCU_MK11D5) /* FTFL */ && \
      !defined(MCU_MK11D5WS) /* FTFL */ && \
      !defined(MCU_MK12D5) /* FTFL */ && \
      !defined(MCU_MK20D10) /* FTFL */ && \
      !defined(MCU_MK20D5) /* FTFL */ && \
      !defined(MCU_MK20D7) /* FTFL */ && \
      !defined(MCU_MK20DZ10) /* FTFL */ && \
      !defined(MCU_MK21D5) /* FTFL */ && \
      !defined(MCU_MK21D5WS) /* FTFL */ && \
      !defined(MCU_MK22D5) /* FTFL */ && \
      !defined(MCU_MK30D10) /* FTFL */ && \
      !defined(MCU_MK30D7) /* FTFL */ && \
      !defined(MCU_MK30DZ10) /* FTFL */ && \
      !defined(MCU_MK40D10) /* FTFL */ && \
      !defined(MCU_MK40D7) /* FTFL */ && \
      !defined(MCU_MK40DZ10) /* FTFL */ && \
      !defined(MCU_MK40X256VMD100) /* FTFL */ && \
      !defined(MCU_MK50D10) /* FTFL */ && \
      !defined(MCU_MK50D7) /* FTFL */ && \
      !defined(MCU_MK50DZ10) /* FTFL */ && \
      !defined(MCU_MK51D10) /* FTFL */ && \
      !defined(MCU_MK51D7) /* FTFL */ && \
      !defined(MCU_MK51DZ10) /* FTFL */ && \
      !defined(MCU_MK52D10) /* FTFL */ && \
      !defined(MCU_MK52DZ10) /* FTFL */ && \
      !defined(MCU_MK53D10) /* FTFL */ && \
      !defined(MCU_MK53DZ10) /* FTFL */ && \
      !defined(MCU_MK60D10) /* FTFL */ && \
      !defined(MCU_MK60DZ10) /* FTFL */ && \
      !defined(MCU_MK60N512VMD100) /* FTFL */ && \
      !defined(MCU_PCK20L4) /* FTFL */
  // Unsupported MCU is active
  #error FTFL PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* ClearFlags constants */
#define FTFL_PDD_COMMAND_COMPLETE          FTFL_FSTAT_CCIF_MASK /**< Command complete flag mask */
#define FTFL_PDD_READ_COLLISION_ERROR      FTFL_FSTAT_RDCOLERR_MASK /**< Read collision error flag mask */
#define FTFL_PDD_ACCESS_ERROR              FTFL_FSTAT_ACCERR_MASK /**< Access error flag mask */
#define FTFL_PDD_PROTECTION_VIOLATION      FTFL_FSTAT_FPVIOL_MASK /**< Protection violation flag mask */
#define FTFL_PDD_COMMAND_COMPLETION_STATUS FTFL_FSTAT_MGSTAT0_MASK /**< Command completion ststus flag mask */

/* EnableInterrupts, DisableInterrupts constants */
#define FTFL_PDD_COMMAND_COMPLETE_INT     FTFL_FCNFG_CCIE_MASK /**< Command complete interrupt mask */
#define FTFL_PDD_READ_COLLISION_ERROR_INT FTFL_FCNFG_RDCOLLIE_MASK /**< Read collision error interrupt mask */

/* SetFCCOBCommand constants */
#define FTFL_PDD_READ_1S_BLOCK              0U   /**< Read 1s Block command value */
#define FTFL_PDD_READ_1S_SECTION            0x1U /**< Read 1s Section command value */
#define FTFL_PDD_PROGRAM_CHECK              0x2U /**< Program Check command value */
#define FTFL_PDD_READ_RESOURCE              0x3U /**< Read Resource command value */
#define FTFL_PDD_PROGRAM_LONGWORD           0x6U /**< Program Longword command value */
#define FTFL_PDD_ERASE_FLASH_BLOCK          0x8U /**< Erase Flash Block command value */
#define FTFL_PDD_ERASE_FLASH_SECTOR         0x9U /**< Erase Flash Sector command value */
#define FTFL_PDD_PROGRAM_SECTION            0xBU /**< Program Section command value */
#define FTFL_PDD_READ_1S_ALL_BLOCKS         0x40U /**< Read 1s All Blocks command value */
#define FTFL_PDD_PDD_READ_ONCE              0x41U /**< Read Once command value */
#define FTFL_PDD_PROGRAM_ONCE               0x43U /**< Program Once command value */
#define FTFL_PDD_ERASE_ALL_BLOCKS           0x44U /**< Erase All Blocks command value */
#define FTFL_PDD_VERIFY_BACKDOOR_ACCESS_KEY 0x45U /**< Verify Backdoor Access Key command value */
#define FTFL_PDD_PROGRAM_PARTITION          0x80U /**< Program Partition command value */
#define FTFL_PDD_SET_EERAM_FUCTION          0x81U /**< Set FlexRAM Function command value */

/* BackDoorKey constants */
#define FTFL_PDD_BACKDOOR_KEY_ENABLED  0U        /**< Backdoor key enable constant */
#define FTFL_PDD_BACKDOOR_KEY_DISABLED 0x1U      /**< Backdoor key disable constant */

/* Security state constants */
#define FTFL_PDD_UNSECURED 0U                    /**< Unsecure constant */
#define FTFL_PDD_SECURED   0x1U                  /**< Secure constant */

/* FlashProtection constants */
#define FTFL_PDD_UNPROTECTED 0U                  /**< Unprotect constant */
#define FTFL_PDD_PROTECTED   0x1U                /**< Protect constant */


/* ----------------------------------------------------------------------------
   -- ReadStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "ClearFlags constants" for processing return
 *         value.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadStatusReg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadStatusReg(PeripheralBase) ( \
    FTFL_FSTAT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the Flash status register. Use constants from
 *        group "ClearFlags constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteStatusReg(deviceID, FTFL_PDD_COMMAND_COMPLETE);
 *      @endcode
 */
#define FTFL_PDD_WriteStatusReg(PeripheralBase, Value) ( \
    FTFL_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ClearCommandCompleteFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Command complete flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      FTFL_PDD_ClearCommandCompleteFlag(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ClearCommandCompleteFlag(PeripheralBase) ( \
    FTFL_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFL_FSTAT_REG(PeripheralBase) | FTFL_FSTAT_CCIF_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_ACCERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_RDCOLERR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearReadCollisionErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Read collision error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      FTFL_PDD_ClearReadCollisionErrorFlag(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ClearReadCollisionErrorFlag(PeripheralBase) ( \
    FTFL_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFL_FSTAT_REG(PeripheralBase) | FTFL_FSTAT_RDCOLERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_ACCERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearAccessErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Access error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      FTFL_PDD_ClearAccessErrorFlag(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ClearAccessErrorFlag(PeripheralBase) ( \
    FTFL_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFL_FSTAT_REG(PeripheralBase) | FTFL_FSTAT_ACCERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_RDCOLERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearProtectionViolationErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Protection violation error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      FTFL_PDD_ClearProtectionViolationErrorFlag(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ClearProtectionViolationErrorFlag(PeripheralBase) ( \
    FTFL_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFL_FSTAT_REG(PeripheralBase) | FTFL_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_ACCERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_RDCOLERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFL_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- LaunchCommand
   ---------------------------------------------------------------------------- */

/**
 * @brief Starts new command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      FTFL_PDD_LaunchCommand(deviceID);
 *      @endcode
 */
#define FTFL_PDD_LaunchCommand(PeripheralBase) ( \
    FTFL_FSTAT_REG(PeripheralBase) = \
     0x80U \
  )

/* ----------------------------------------------------------------------------
   -- ClearFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @param Flags Interrupt mask. This parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      FTFL_PDD_ClearFlags(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_ClearFlags(PeripheralBase, Flags) ( \
    FTFL_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(Flags) \
  )

/* ----------------------------------------------------------------------------
   -- GetFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FSTAT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_GetFlags(deviceID);
 *      @endcode
 */
#define FTFL_PDD_GetFlags(PeripheralBase) ( \
    FTFL_FSTAT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadConfigReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash configuration register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCNFG.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadConfigReg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadConfigReg(PeripheralBase) ( \
    FTFL_FCNFG_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteConfigReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash configuration register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the Flash configuration register. This
 *        parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCNFG.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteConfigReg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteConfigReg(PeripheralBase, Value) ( \
    FTFL_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables Command commplete end Read collision error interrupts.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "EnableInterrupts,
 *        DisableInterrupts constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCNFG.
 * @par Example:
 *      @code
 *      FTFL_PDD_EnableInterrupts(deviceID, FTFL_PDD_COMMAND_COMPLETE_INT);
 *      @endcode
 */
#define FTFL_PDD_EnableInterrupts(PeripheralBase, Mask) ( \
    FTFL_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(( \
       FTFL_FCNFG_REG(PeripheralBase)) & ( \
       (uint8_t)(~(uint8_t)(FTFL_FCNFG_CCIE_MASK | FTFL_FCNFG_RDCOLLIE_MASK))))) | ( \
      (uint8_t)(Mask))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables Command commplete end Read collision error interrupts.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "EnableInterrupts,
 *        DisableInterrupts constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCNFG.
 * @par Example:
 *      @code
 *      FTFL_PDD_DisableInterrupts(deviceID, FTFL_PDD_COMMAND_COMPLETE_INT);
 *      @endcode
 */
#define FTFL_PDD_DisableInterrupts(PeripheralBase, Mask) ( \
    FTFL_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(( \
       FTFL_FCNFG_REG(PeripheralBase)) & ( \
       (uint8_t)(~(uint8_t)(FTFL_FCNFG_CCIE_MASK | FTFL_FCNFG_RDCOLLIE_MASK))))) | ( \
      (uint8_t)(( \
       (uint8_t)(~(uint8_t)(Mask))) & ( \
       (uint8_t)(FTFL_FCNFG_CCIE_MASK | FTFL_FCNFG_RDCOLLIE_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- SuspendErasing
   ---------------------------------------------------------------------------- */

/**
 * @brief Suspends the current Erase Flash Sector command execution.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCNFG.
 * @par Example:
 *      @code
 *      FTFL_PDD_SuspendErasing(deviceID);
 *      @endcode
 */
#define FTFL_PDD_SuspendErasing(PeripheralBase) ( \
    FTFL_FCNFG_REG(PeripheralBase) |= \
     FTFL_FCNFG_ERSSUSP_MASK \
  )

/* ----------------------------------------------------------------------------
   -- GetRAMReady
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Ram ready bit.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCNFG.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_GetRAMReady(deviceID);
 *      @endcode
 */
#define FTFL_PDD_GetRAMReady(PeripheralBase) ( \
    (uint8_t)(FTFL_FCNFG_REG(PeripheralBase) & FTFL_FCNFG_RAMRDY_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetEEEReady
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the EEE ready bit.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCNFG.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_GetEEEReady(deviceID);
 *      @endcode
 */
#define FTFL_PDD_GetEEEReady(PeripheralBase) ( \
    (uint8_t)(FTFL_FCNFG_REG(PeripheralBase) & FTFL_FCNFG_EEERDY_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSecurityReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Security register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FSEC.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadSecurityReg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadSecurityReg(PeripheralBase) ( \
    FTFL_FSEC_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetBackdoorEnable
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the constant FTFL_PDD_BACKDOOR_KEY_ENABLED if backdoor key
 * access is enabled else returns the FTFL_PDD_BACKDOOR_KEY_DISABLED constant.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of "BackDoorKey constants" type. The value is cast to
 *         "uint16_t".
 * @remarks The macro accesses the following registers: FTFL_FSEC.
 * @par Example:
 *      @code
 *      uint16_t result = FTFL_PDD_GetBackdoorEnable(deviceID);
 *      @endcode
 */
#define FTFL_PDD_GetBackdoorEnable(PeripheralBase) ( \
    (( \
      (uint8_t)(( \
       (uint8_t)(FTFL_FSEC_REG(PeripheralBase) & FTFL_FSEC_KEYEN_MASK)) >> ( \
       FTFL_FSEC_KEYEN_SHIFT))) == ( \
      0x2U)) ? ( \
      FTFL_PDD_BACKDOOR_KEY_ENABLED) : ( \
      FTFL_PDD_BACKDOOR_KEY_DISABLED) \
  )

/* ----------------------------------------------------------------------------
   -- GetSecurityState
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the constant FTFL_PDD_SECURED if MCU is in secure state else
 * returns the FTFL_PDD_UNSECURED constant.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of "Security state constants" type. The value is cast
 *         to "uint16_t".
 * @remarks The macro accesses the following registers: FTFL_FSEC.
 * @par Example:
 *      @code
 *      uint16_t result = FTFL_PDD_GetSecurityState(deviceID);
 *      @endcode
 */
#define FTFL_PDD_GetSecurityState(PeripheralBase) ( \
    ((uint8_t)(FTFL_FSEC_REG(PeripheralBase) & FTFL_FSEC_SEC_MASK) == 0x2U) ? ( \
      FTFL_PDD_UNSECURED) : ( \
      FTFL_PDD_SECURED) \
  )

/* ----------------------------------------------------------------------------
   -- ReadOptionReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Optional register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FOPT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadOptionReg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadOptionReg(PeripheralBase) ( \
    FTFL_FOPT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB0Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 0.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB0.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB0Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB0Reg(PeripheralBase) ( \
    FTFL_FCCOB0_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 1.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB1.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB1Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB1Reg(PeripheralBase) ( \
    FTFL_FCCOB1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 2.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB2.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB2Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB2Reg(PeripheralBase) ( \
    FTFL_FCCOB2_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB3Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 3.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB3.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB3Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB3Reg(PeripheralBase) ( \
    FTFL_FCCOB3_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB4Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 4.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB4.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB4Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB4Reg(PeripheralBase) ( \
    FTFL_FCCOB4_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB5Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 5.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB5.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB5Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB5Reg(PeripheralBase) ( \
    FTFL_FCCOB5_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB6Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 6.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB6.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB6Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB6Reg(PeripheralBase) ( \
    FTFL_FCCOB6_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB7Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 7.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB7.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB7Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB7Reg(PeripheralBase) ( \
    FTFL_FCCOB7_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB8Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 8.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB8.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB8Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB8Reg(PeripheralBase) ( \
    FTFL_FCCOB8_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB9Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 9.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOB9.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOB9Reg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOB9Reg(PeripheralBase) ( \
    FTFL_FCCOB9_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOBAReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register A.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOBA.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOBAReg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOBAReg(PeripheralBase) ( \
    FTFL_FCCOBA_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOBBReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register B.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FCCOBB.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_ReadFCCOBBReg(deviceID);
 *      @endcode
 */
#define FTFL_PDD_ReadFCCOBBReg(PeripheralBase) ( \
    FTFL_FCCOBB_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB0Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB0 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB0 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB0.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB0Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB0Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB0_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB1 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB1.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB1Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB1Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB1_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB2 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB2 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB2.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB2Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB2Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB2_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB3Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB3register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB3 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB3.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB3Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB3Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB3_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB4Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB4 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB4 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB4.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB4Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB4Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB5Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB5 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB5 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB5.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB5Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB5Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB6Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB6 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB6 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB6.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB6Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB6Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB7Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB7 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB7 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB7.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB7Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB7Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB8Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB8 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB8 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB8.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB8Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB8Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB9Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB9 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB9 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB9.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOB9Reg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOB9Reg(PeripheralBase, Value) ( \
    FTFL_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBAReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOBA register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOBA register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOBA.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBAReg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBAReg(PeripheralBase, Value) ( \
    FTFL_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBBReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOBB register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOBB register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOBB.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBBReg(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBBReg(PeripheralBase, Value) ( \
    FTFL_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- SetFCCOBCommand
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB Command register.
 * @param PeripheralBase Peripheral base address.
 * @param Command Value written to the FCCOB Command register. This parameter is
 *        a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB0.
 * @par Example:
 *      @code
 *      FTFL_PDD_SetFCCOBCommand(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_SetFCCOBCommand(PeripheralBase, Command) ( \
    FTFL_FCCOB0_REG(PeripheralBase) = \
     (uint8_t)(Command) \
  )

/* ----------------------------------------------------------------------------
   -- SetFCCOBAddress
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB Address register.
 * @param PeripheralBase Peripheral base address.
 * @param Address Value written to the FCCOB Address register. This parameter is
 *        a 24-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB3,
 *          FTFL_FCCOB2, FTFL_FCCOB1 (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFL_PDD_SetFCCOBAddress(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_SetFCCOBAddress(PeripheralBase, Address) ( \
    (FTFL_FCCOB3_REG(PeripheralBase) = \
     (uint8_t)(Address)), \
    ((FTFL_FCCOB2_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Address) >> 8U)), \
    (FTFL_FCCOB1_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Address) >> 16U))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData0
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 0.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 0 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB4.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBData0(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBData0(PeripheralBase, Data) ( \
    FTFL_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData1
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 1.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 1 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB5.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBData1(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBData1(PeripheralBase, Data) ( \
    FTFL_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData2
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 2.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 2 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB6.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBData2(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBData2(PeripheralBase, Data) ( \
    FTFL_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData3
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 3.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 3 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB7.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBData3(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBData3(PeripheralBase, Data) ( \
    FTFL_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData4
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 4.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 4 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB8.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBData4(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBData4(PeripheralBase, Data) ( \
    FTFL_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData5
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 5.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 5 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB9.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBData5(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBData5(PeripheralBase, Data) ( \
    FTFL_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData6
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 6.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 6 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOBA.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBData6(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBData6(PeripheralBase, Data) ( \
    FTFL_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData7
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 7.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 7 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOBB.
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBData7(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBData7(PeripheralBase, Data) ( \
    FTFL_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB4,
 *          FTFL_FCCOB5, FTFL_FCCOB6, FTFL_FCCOB7 (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBLongWordData(PeripheralBase, Data) ( \
    (FTFL_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 24U)), \
    ((FTFL_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 16U)), \
    ((FTFL_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 8U)), \
    (FTFL_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Data)))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBFirstLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets first longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB4,
 *          FTFL_FCCOB5, FTFL_FCCOB6, FTFL_FCCOB7 (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBFirstLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBFirstLongWordData(PeripheralBase, Data) ( \
    (FTFL_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 24U)), \
    ((FTFL_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 16U)), \
    ((FTFL_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 8U)), \
    (FTFL_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Data)))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBSecondLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets second longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FCCOB8,
 *          FTFL_FCCOB9, FTFL_FCCOBA, FTFL_FCCOBB (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFL_PDD_WriteFCCOBSecondLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFL_PDD_WriteFCCOBSecondLongWordData(PeripheralBase, Data) ( \
    (FTFL_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 24U)), \
    ((FTFL_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 16U)), \
    ((FTFL_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 8U)), \
    (FTFL_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Data)))) \
  )

/* ----------------------------------------------------------------------------
   -- SetPFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets program Flash protection state.
 * @param PeripheralBase Peripheral base address.
 * @param Regions Protected regions. This parameter is a 32-bit value.
 * @param State Requested state. This parameter is of "FlashProtection
 *        constants" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FPROT3.
 * @par Example:
 *      @code
 *      FTFL_PDD_SetPFlashProtectionState(deviceID, 1, FTFL_PDD_UNPROTECTED);
 *      @endcode
 */
#define FTFL_PDD_SetPFlashProtectionState(PeripheralBase, Regions, State) ( \
    ((State) == FTFL_PDD_UNPROTECTED) ? ( \
      *(uint32_t *)(void *)&(FTFL_FPROT3_REG(PeripheralBase)) |= \
      (uint32_t)(Regions)) : ( \
      *(uint32_t *)(void *)&(FTFL_FPROT3_REG(PeripheralBase)) &= \
      (uint32_t)(~(uint32_t)(Regions))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns program falsh protection state.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTFL_FPROT3.
 * @par Example:
 *      @code
 *      uint32_t result = FTFL_PDD_GetPFlashProtectionState(deviceID);
 *      @endcode
 */
#define FTFL_PDD_GetPFlashProtectionState(PeripheralBase) ( \
    (uint32_t)(~(*(uint32_t *)(void *)&(FTFL_FPROT3_REG(PeripheralBase)))) \
  )

/* ----------------------------------------------------------------------------
   -- SetDFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets data Flash protection state.
 * @param PeripheralBase Peripheral base address.
 * @param Regions FTFL_PDD_PROTECTED or FTFL_PDD_UNPROTECTED. This parameter is
 *        a 8-bit value.
 * @param State Requested state. This parameter is of "FlashProtection
 *        constants" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FDPROT.
 * @par Example:
 *      @code
 *      FTFL_PDD_SetDFlashProtectionState(deviceID, 1, FTFL_PDD_UNPROTECTED);
 *      @endcode
 */
#define FTFL_PDD_SetDFlashProtectionState(PeripheralBase, Regions, State) ( \
    ((State) == FTFL_PDD_UNPROTECTED) ? ( \
      FTFL_FDPROT_REG(PeripheralBase) |= \
       (uint8_t)(Regions)) : ( \
      FTFL_FDPROT_REG(PeripheralBase) &= \
       (uint8_t)(~(uint8_t)(Regions))) \
  )

/* ----------------------------------------------------------------------------
   -- GetDFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Each bit of the returned value represent 1/8 of the Data FLASH memory.
 * If the bit is set the region is protected else the region is unprotected.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FDPROT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_GetDFlashProtectionState(deviceID);
 *      @endcode
 */
#define FTFL_PDD_GetDFlashProtectionState(PeripheralBase) ( \
    (uint8_t)(~(uint8_t)FTFL_FDPROT_REG(PeripheralBase)) \
  )

/* ----------------------------------------------------------------------------
   -- SetEERAMProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Each bit of the Region parameter represent 1/8 of the EERPROM memory.
 * To change the protection state of the region(s) select requested regions
 * (Region param) and set new state (State param).
 * @param PeripheralBase Peripheral base address.
 * @param Regions Protected regions. This parameter is a 8-bit value.
 * @param State Requested state. This parameter is of "FlashProtection
 *        constants" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFL_FEPROT.
 * @par Example:
 *      @code
 *      FTFL_PDD_SetEERAMProtectionState(deviceID, 1, FTFL_PDD_UNPROTECTED);
 *      @endcode
 */
#define FTFL_PDD_SetEERAMProtectionState(PeripheralBase, Regions, State) ( \
    ((State) == FTFL_PDD_UNPROTECTED) ? ( \
      FTFL_FEPROT_REG(PeripheralBase) |= \
       (uint8_t)(Regions)) : ( \
      FTFL_FEPROT_REG(PeripheralBase) &= \
       (uint8_t)(~(uint8_t)(Regions))) \
  )

/* ----------------------------------------------------------------------------
   -- GetEERAMProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Each bit of the returned value represent 1/8 of the EERPROM memory. If
 * the bit is set the region is protected else the region is unprotected.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFL_FEPROT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFL_PDD_GetEERAMProtectionState(deviceID);
 *      @endcode
 */
#define FTFL_PDD_GetEERAMProtectionState(PeripheralBase) ( \
    (uint8_t)(~(uint8_t)FTFL_FEPROT_REG(PeripheralBase)) \
  )
#endif  /* #if defined(FTFL_PDD_H_) */

/* FTFL_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/vectors.c<|end_filename|>
/**HEADER**********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* $FileName: vectors.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*    This file contains the exception vector table and flash configuration.
*
*END***************************************************************************/

#include "mqx_inc.h"
#include "bsp.h" 

extern unsigned long __BOOT_STACK_ADDRESS[];

/* Configuration values for flash controller */
#define CONFIG_1        (uint_32)0xffffffff
#define CONFIG_2        (uint_32)0xffffffff
#define CONFIG_3        (uint_32)0xffffffff
#define CONFIG_4        (uint_32)0xfffffffe

#define BOOT_START __boot
    
extern void __boot(void);

#ifndef __CC_ARM
extern vector_entry __VECTOR_TABLE_ROM_START[]; /* defined in linker command file */
extern vector_entry __VECTOR_TABLE_RAM_START[]; /* defined in linker command file */
#endif

void _svc_handler(void);
void _pend_svc(void);

#ifdef __ICCARM__
    #pragma language = extended
    #pragma segment  = "CSTACK"
    
    #pragma location = ".flashx"
    #pragma segment  = ".flashx"
    /* Workaround to define __FLASHX_START_ADDR at the beginning of .flashx */
    const uchar __FLASHX_START_ADDR[1];
    /* Here you can put anything to your flashx area */
    
    #if BSPCFG_ENABLE_CFMPROTECT
        #pragma location = ".cfmconfig"
        #pragma segment  = ".cfmconfig"
        const uint_32 _cfm[4] = {
            CONFIG_1,
            CONFIG_2,
            CONFIG_3,
            CONFIG_4
        };
    #endif /* BSPCFG_ENABLE_CFMPROTECT */
#elif defined(__CC_ARM) || defined(__GNUC__)
    /* flashx location defined in io/flashx/freescale/flash_mk60.h for KEIL */
    __attribute__((section(".cfmconfig"))) const uint_32 _cfm[4] __attribute__((used)) = {
        CONFIG_1,
        CONFIG_2,
        CONFIG_3,
        CONFIG_4
    };
#else /* CodeWarrior compiler assumed */
    #pragma define_section flashx    ".flashx" ".flashx" ".flashx"  far_abs R
    /* Here you can put anything to your flashx area */
        
    #if BSPCFG_ENABLE_CFMPROTECT
        /* Pragma to place the flash configuration field on correct location defined in linker file. */
        #pragma define_section cfmconfig ".cfmconfig" ".cfmconfig" ".cfmconfig" far_abs R
        #pragma explicit_zero_data on
        __declspec(cfmconfig)  uint_32 _cfm[4] = {
            CONFIG_1,
            CONFIG_2,
            CONFIG_3,
            CONFIG_4
        };
    #endif /* BSPCFG_ENABLE_CFMPROTECT */
#endif /* CodeWarrior compiler assumed */

typedef union { vector_entry __fun; void * __ptr; } intvec_elem;

#if MQX_ROM_VECTORS
    #define DEFAULT_VECTOR  _int_kernel_isr
#else
    static void __boot_exception(void) {
        while(1);
    }
    
    #define DEFAULT_VECTOR  __boot_exception
    
    #if   defined(__ICCARM__)
        #pragma language = extended
        #pragma location = ".vectors_ram"
        #pragma segment  = ".vectors_ram"
        intvec_elem ram_vector[256] @ ".vectors_ram" =
    #elif defined(__CC_ARM) || defined(__GNUC__)
        __attribute__((section(".vectors_ram"))) vector_entry ram_vector[256] __attribute__((used)) =
    #else /* CodeWarrior compiler assumed */
        #pragma  define_section vectors_ram ".vectors_ram" far_abs RW
        /* 
         * Array for exception vectors in ram + space (6 words)
         * for CW (when CW debugger handles exceptions, using(rewrite)
         * VBR+0x408 address
         */
        __declspec(vectors_ram) vector_entry ram_vector[256 + 6] = 
    #endif /* CodeWarrior compiler assumed */
    {
        (vector_entry)__BOOT_STACK_ADDRESS,
        BOOT_START,         /* 0x01  0x00000004   -   ivINT_Initial_Program_Counter     */
        _int_kernel_isr,    /* 0x02  0x00000008   -   ivINT_NMI                         */
        _int_kernel_isr,    /* 0x03  0x0000000C   -   ivINT_Hard_Fault                  */
        _int_kernel_isr,    /* 0x04  0x00000010   -   ivINT_Mem_Manage_Fault            */
        _int_kernel_isr,    /* 0x05  0x00000014   -   ivINT_Bus_Fault                   */
        _int_kernel_isr,    /* 0x06  0x00000018   -   ivINT_Usage_Fault                 */
        0,                  /* 0x07  0x0000001C   -   ivINT_Reserved7                   */
        0,                  /* 0x08  0x00000020   -   ivINT_Reserved8                   */
        0,                  /* 0x09  0x00000024   -   ivINT_Reserved9                   */
        0,                  /* 0x0A  0x00000028   -   ivINT_Reserved10                  */
        _svc_handler,       /* 0x0B  0x0000002C   -   ivINT_SVCall                      */
        _int_kernel_isr,    /* 0x0C  0x00000030   -   ivINT_DebugMonitor                */
        0,                  /* 0x0D  0x00000034   -   ivINT_Reserved13                  */
        _pend_svc,          /* 0x0E  0x00000038   -   ivINT_PendableSrvReq              */
        _int_kernel_isr     /* 0x0F  0x0000003C   -   ivINT_SysTick                     */
    };
#endif
/*
** exception vector table - this table is really used
*/
#ifdef __ICCARM__
    #pragma language = extended
    #pragma segment  = "CSTACK"

    #pragma location = ".intvec"
    #pragma segment  = ".intvec"
    const intvec_elem __vector_table[] =
#elif defined(__CC_ARM) || defined(__GNUC__)
    __attribute__((section(".vectors_rom"))) const vector_entry __vector_table[256] __attribute__((used)) =
#else /* CodeWarrior compiler assumed */
    #pragma  define_section vectors_rom ".vectors_rom" ".vectors_rom" ".vectors_rom" far_abs R
    __declspec(vectors_rom) vector_entry rom_vector[] = 
#endif /* CodeWarrior compiler assumed */
{
    (vector_entry)__BOOT_STACK_ADDRESS,
    BOOT_START,             /* 0x01  0x00000004   -   ivINT_Initial_Program_Counter     */
    DEFAULT_VECTOR,         /* 0x02  0x00000008   -   ivINT_NMI                         */
    DEFAULT_VECTOR,         /* 0x03  0x0000000C   -   ivINT_Hard_Fault                  */
    DEFAULT_VECTOR,         /* 0x04  0x00000010   -   ivINT_Mem_Manage_Fault            */
    DEFAULT_VECTOR,         /* 0x05  0x00000014   -   ivINT_Bus_Fault                   */
    DEFAULT_VECTOR,         /* 0x06  0x00000018   -   ivINT_Usage_Fault                 */
    0,                      /* 0x07  0x0000001C   -   ivINT_Reserved7                   */
    0,                      /* 0x08  0x00000020   -   ivINT_Reserved8                   */
    0,                      /* 0x09  0x00000024   -   ivINT_Reserved9                   */
    0,                      /* 0x0A  0x00000028   -   ivINT_Reserved10                  */
    _svc_handler,           /* 0x0B  0x0000002C   -   ivINT_SVCall                      */
    DEFAULT_VECTOR,         /* 0x0C  0x00000030   -   ivINT_DebugMonitor                */
    0,                      /* 0x0D  0x00000034   -   ivINT_Reserved13                  */
    _pend_svc,              /* 0x0E  0x00000038   -   ivINT_PendableSrvReq              */
    DEFAULT_VECTOR,         /* 0x0F  0x0000003C   -   ivINT_SysTick                     */
    /* Cortex external interrupt vectors                                                */
    DEFAULT_VECTOR,         /* 0x10  0x00000040   -   ivINT_DMA0                        */
    DEFAULT_VECTOR,         /* 0x11  0x00000044   -   ivINT_DMA1                        */
    DEFAULT_VECTOR,         /* 0x12  0x00000048   -   ivINT_DMA2                        */
    DEFAULT_VECTOR,         /* 0x13  0x0000004C   -   ivINT_DMA3                        */
    DEFAULT_VECTOR,         /* 0x14  0x00000050   -   ivINT_DMA4                        */
    DEFAULT_VECTOR,         /* 0x15  0x00000054   -   ivINT_DMA5                        */
    DEFAULT_VECTOR,         /* 0x16  0x00000058   -   ivINT_DMA6                        */
    DEFAULT_VECTOR,         /* 0x17  0x0000005C   -   ivINT_DMA7                        */
    DEFAULT_VECTOR,         /* 0x18  0x00000060   -   ivINT_DMA8                        */
    DEFAULT_VECTOR,         /* 0x19  0x00000064   -   ivINT_DMA9                        */
    DEFAULT_VECTOR,         /* 0x1A  0x00000068   -   ivINT_DMA10                       */
    DEFAULT_VECTOR,         /* 0x1B  0x0000006C   -   ivINT_DMA11                       */
    DEFAULT_VECTOR,         /* 0x1C  0x00000070   -   ivINT_DMA12                       */
    DEFAULT_VECTOR,         /* 0x1D  0x00000074   -   ivINT_DMA13                       */
    DEFAULT_VECTOR,         /* 0x1E  0x00000078   -   ivINT_DMA14                       */
    DEFAULT_VECTOR,         /* 0x1F  0x0000007C   -   ivINT_DMA15                       */
    DEFAULT_VECTOR,         /* 0x20  0x00000080   -   ivINT_DMA_Error                   */
    DEFAULT_VECTOR,         /* 0x21  0x00000084   -   ivINT_MCM                         */
    DEFAULT_VECTOR,         /* 0x22  0x00000088   -   ivINT_FTFL                        */
    DEFAULT_VECTOR,         /* 0x23  0x0000008C   -   ivINT_Read_Collision              */
    DEFAULT_VECTOR,         /* 0x24  0x00000090   -   ivINT_LVD_LVW                     */
    DEFAULT_VECTOR,         /* 0x25  0x00000094   -   ivINT_LLW                         */
    DEFAULT_VECTOR,         /* 0x26  0x00000098   -   ivINT_Watchdog                    */
    DEFAULT_VECTOR,         /* 0x27  0x0000009C   -   ivINT_RNG                         */
    DEFAULT_VECTOR,         /* 0x28  0x000000A0   -   ivINT_I2C0                        */
    DEFAULT_VECTOR,         /* 0x29  0x000000A4   -   ivINT_I2C1                        */
    DEFAULT_VECTOR,         /* 0x2A  0x000000A8   -   ivINT_SPI0                        */
    DEFAULT_VECTOR,         /* 0x2B  0x000000AC   -   ivINT_SPI1                        */
    DEFAULT_VECTOR,         /* 0x2C  0x000000B0   -   ivINT_SPI2                        */
    DEFAULT_VECTOR,         /* 0x2D  0x000000B4   -   ivINT_CAN0_ORed_Message_buffer    */
    DEFAULT_VECTOR,         /* 0x2E  0x000000B8   -   ivINT_CAN0_Bus_Off                */
    DEFAULT_VECTOR,         /* 0x2F  0x000000BC   -   ivINT_CAN0_Error                  */
    DEFAULT_VECTOR,         /* 0x30  0x000000C0   -   ivINT_CAN0_Tx_Warning             */
    DEFAULT_VECTOR,         /* 0x31  0x000000C4   -   ivINT_CAN0_Rx_Warning             */
    DEFAULT_VECTOR,         /* 0x32  0x000000C8   -   ivINT_CAN0_Wake_Up                */
    DEFAULT_VECTOR,         /* 0x33  0x000000CC   -   ivINT_Reserved51                  */
    DEFAULT_VECTOR,         /* 0x34  0x000000D0   -   ivINT_Reserved52                  */
    DEFAULT_VECTOR,         /* 0x35  0x000000D4   -   ivINT_CAN1_ORed_Message_buffer    */
    DEFAULT_VECTOR,         /* 0x36  0x000000D8   -   ivINT_CAN1_Bus_Off                */
    DEFAULT_VECTOR,         /* 0x37  0x000000DC   -   ivINT_CAN1_Error                  */
    DEFAULT_VECTOR,         /* 0x38  0x000000E0   -   ivINT_CAN1_Tx_Warning             */
    DEFAULT_VECTOR,         /* 0x39  0x000000E4   -   ivINT_CAN1_Rx_Warning             */
    DEFAULT_VECTOR,         /* 0x3A  0x000000E8   -   ivINT_CAN1_Wake_Up                */
    DEFAULT_VECTOR,         /* 0x3B  0x000000EC   -   ivINT_Reserved59                  */
    DEFAULT_VECTOR,         /* 0x3C  0x000000F0   -   ivINT_Reserved60                  */
    DEFAULT_VECTOR,         /* 0x3D  0x000000F4   -   ivINT_UART0_RX_TX                 */
    DEFAULT_VECTOR,         /* 0x3E  0x000000F8   -   ivINT_UART0_ERR                   */
    DEFAULT_VECTOR,         /* 0x3F  0x000000FC   -   ivINT_UART1_RX_TX                 */
    DEFAULT_VECTOR,         /* 0x40  0x00000100   -   ivINT_UART1_ERR                   */
    DEFAULT_VECTOR,         /* 0x41  0x00000104   -   ivINT_UART2_RX_TX                 */
    DEFAULT_VECTOR,         /* 0x42  0x00000108   -   ivINT_UART2_ERR                   */
    DEFAULT_VECTOR,         /* 0x43  0x0000010C   -   ivINT_UART3_RX_TX                 */
    DEFAULT_VECTOR,         /* 0x44  0x00000110   -   ivINT_UART3_ERR                   */
    DEFAULT_VECTOR,         /* 0x45  0x00000114   -   ivINT_UART4_RX_TX                 */
    DEFAULT_VECTOR,         /* 0x46  0x00000118   -   ivINT_UART4_ERR                   */
    DEFAULT_VECTOR,         /* 0x47  0x0000011C   -   ivINT_UART5_RX_TX                 */
    DEFAULT_VECTOR,         /* 0x48  0x00000120   -   ivINT_UART5_ERR                   */
    DEFAULT_VECTOR,         /* 0x49  0x00000124   -   ivINT_ADC0                        */
    DEFAULT_VECTOR,         /* 0x4A  0x00000128   -   ivINT_ADC1                        */
    DEFAULT_VECTOR,         /* 0x4B  0x0000012C   -   ivINT_CMP0                        */
    DEFAULT_VECTOR,         /* 0x4C  0x00000130   -   ivINT_CMP1                        */
    DEFAULT_VECTOR,         /* 0x4D  0x00000134   -   ivINT_CMP2                        */
    DEFAULT_VECTOR,         /* 0x4E  0x00000138   -   ivINT_FTM0                        */
    DEFAULT_VECTOR,         /* 0x4F  0x0000013C   -   ivINT_FTM1                        */
    DEFAULT_VECTOR,         /* 0x50  0x00000140   -   ivINT_FTM2                        */
    DEFAULT_VECTOR,         /* 0x51  0x00000144   -   ivINT_CMT                         */
    DEFAULT_VECTOR,         /* 0x52  0x00000148   -   ivINT_RTC                         */
    DEFAULT_VECTOR,         /* 0x53  0x0000014C   -   ivINT_Reserved83                  */
    DEFAULT_VECTOR,         /* 0x54  0x00000150   -   ivINT_PIT0                        */
    DEFAULT_VECTOR,         /* 0x55  0x00000154   -   ivINT_PIT1                        */
    DEFAULT_VECTOR,         /* 0x56  0x00000158   -   ivINT_PIT2                        */
    DEFAULT_VECTOR,         /* 0x57  0x0000015C   -   ivINT_PIT3                        */
    DEFAULT_VECTOR,         /* 0x58  0x00000160   -   ivINT_PDB0                        */
    DEFAULT_VECTOR,         /* 0x59  0x00000164   -   ivINT_USB0                        */
    DEFAULT_VECTOR,         /* 0x5A  0x00000168   -   ivINT_USBDCD                      */
    DEFAULT_VECTOR,         /* 0x5B  0x0000016C   -   ivINT_ENET_1588_Timer             */
    DEFAULT_VECTOR,         /* 0x5C  0x00000170   -   ivINT_ENET_Transmit               */
    DEFAULT_VECTOR,         /* 0x5D  0x00000174   -   ivINT_ENET_Receive                */
    DEFAULT_VECTOR,         /* 0x5E  0x00000178   -   ivINT_ENET_Error                  */
    DEFAULT_VECTOR,         /* 0x5F  0x0000017C   -   ivINT_I2S0                        */
    DEFAULT_VECTOR,         /* 0x60  0x00000180   -   ivINT_SDHC                        */
    DEFAULT_VECTOR,         /* 0x61  0x00000184   -   ivINT_DAC0                        */
    DEFAULT_VECTOR,         /* 0x62  0x00000188   -   ivINT_DAC1                        */
    DEFAULT_VECTOR,         /* 0x63  0x0000018C   -   ivINT_TSI0                        */
    DEFAULT_VECTOR,         /* 0x64  0x00000190   -   ivINT_MCG                         */
    DEFAULT_VECTOR,         /* 0x65  0x00000194   -   ivINT_LPTimer                     */
    DEFAULT_VECTOR,         /* 0x66  0x00000198   -   ivINT_Reserved102                 */
    DEFAULT_VECTOR,         /* 0x67  0x0000019C   -   ivINT_PORTA                       */
    DEFAULT_VECTOR,         /* 0x68  0x000001A0   -   ivINT_PORTB                       */
    DEFAULT_VECTOR,         /* 0x69  0x000001A4   -   ivINT_PORTC                       */
    DEFAULT_VECTOR,         /* 0x6A  0x000001A8   -   ivINT_PORTD                       */
    DEFAULT_VECTOR,         /* 0x6B  0x000001AC   -   ivINT_PORTE                       */
    DEFAULT_VECTOR,         /* 0x6C  0x000001B0   -   ivINT_Reserved108                 */
    DEFAULT_VECTOR,         /* 0x6D  0x000001B4   -   ivINT_Reserved109                 */
    DEFAULT_VECTOR,         /* 0x6E  0x000001B8   -   ivINT_Reserved110                 */
    DEFAULT_VECTOR,         /* 0x6F  0x000001BC   -   ivINT_Reserved111                 */
    DEFAULT_VECTOR,         /* 0x70  0x000001C0   -   ivINT_Reserved112                 */
    DEFAULT_VECTOR,         /* 0x71  0x000001C4   -   ivINT_Reserved113                 */
    DEFAULT_VECTOR,         /* 0x72  0x000001C8   -   ivINT_Reserved114                 */
    DEFAULT_VECTOR,         /* 0x73  0x000001CC   -   ivINT_Reserved115                 */
    DEFAULT_VECTOR,         /* 0x74  0x000001D0   -   ivINT_Reserved116                 */
    DEFAULT_VECTOR,         /* 0x75  0x000001D4   -   ivINT_Reserved117                 */
    DEFAULT_VECTOR,         /* 0x76  0x000001D8   -   ivINT_Reserved118                 */
    DEFAULT_VECTOR,         /* 0x77  0x000001DC   -   ivINT_Reserved119                 */
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR,
    DEFAULT_VECTOR
};


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/igmp.h<|end_filename|>
#ifndef __igmp_h__
#define __igmp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: igmp.h$
* $Version : 3.8.8.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the Internet Group Mangement protocol
*   User Datagram Protocol definitions.
*   For more details, refer to RFC1112 and RFC2236.
*
*END************************************************************************/


#if 0
#  define IGMP_V2      /* to define if the host has to support IGMPv2 */
#endif

#if RTCSCFG_ENABLE_IGMP & RTCSCFG_ENABLE_IP4

/***************************************
**
** Constants
**
*/

/* IGMP packet types */
#define IGMPTYPE_QUERY        0x11
#define IGMPTYPE_V1_REPORT    0x12
#define IGMPTYPE_V2_REPORT    0x16
#define IGMPTYPE_LEAVE        0x17

/* IGMP constants */
#define IGMP_V1_ROUTER_TIMEOUT_VALUE     (400*1000)
#define IGMP_V1_QUERY_RESPONSE_INTERVAL  ( 10*1000)   /* default max_resp_time in 1/1000 sec fro IGMPv1 */
#define IGMP_UNSOLICITED_REPORT_INTERVAL ( 10*1000)
#define IGMP_UNSOLICITED_REPORT_COUNT    2      /* number of repetition. if == 2, 3 reports will be sent */


/***************************************
**
** Code macros
**
*/

#if RTCSCFG_ENABLE_IGMP_STATS
#define IF_IGMP_STATS_ENABLED(x) x
#else
#define IF_IGMP_STATS_ENABLED(x)
#endif

/***************************************
**
** Type definitions
**
*/

/*
** IGMP parameters for [gs]etsockopt
*/
typedef struct igmp_parm {
   TCPIP_PARM              COMMON;
   struct igmp_parm _PTR_  NEXT;
   SOCKET_STRUCT_PTR       sock;
   uint_32                 option;
   pointer                 optptr;
   uint_32                 optlen;
} IGMP_PARM, _PTR_ IGMP_PARM_PTR;

/*
** IGMP Configuration.  This information is persistent for the IGMP layer.
*/
typedef struct igmp_cfg_struct {
#if RTCSCFG_ENABLE_IGMP_STATS
   IGMP_STATS     STATS;         /* the statistic for IGMP */
#else
   uchar          Reserved;
#endif
} IGMP_CFG_STRUCT, _PTR_ IGMP_CFG_STRUCT_PTR;

typedef struct igmp_header {
   uchar    TYPE[1];
   uchar    MAX_RESP_TIME[1];
   uchar    CHECKSUM[2];
   uchar    GROUP_ADDRESS[4];
} IGMP_HEADER, _PTR_ IGMP_HEADER_PTR;


/***************************************
**
** Prototypes
**
*/

struct ip_if;

extern uint_32 IGMP_init (void);
extern boolean IGMP_send_report (ip_mreq _PTR_, uint_16);

extern uint_32 IGMP_filter_add (struct ip_if _PTR_, _ip_address);
extern uint_32 IGMP_filter_rm  (struct ip_if _PTR_, _ip_address);

extern MC_MEMBER_PTR _PTR_ IGMP_member_find   (MC_MEMBER_PTR _PTR_, ip_mreq _PTR_);
extern MC_MEMBER_PTR _PTR_ IGMP_member_create (MC_MEMBER_PTR _PTR_, ip_mreq _PTR_);
extern uint_32             IGMP_member_delete (MC_MEMBER_PTR _PTR_);

extern void IGMP_init_timer   (MC_MEMBER_PTR);
extern void IGMP_launch_timer (MC_MEMBER_PTR, uint_32);
extern void IGMP_stop_timer   (MC_MEMBER_PTR);

extern uint_32 IGMP_ipif_add  (struct ip_if _PTR_);
extern uint_32 IGMP_ipif_bind (struct ip_if _PTR_, _ip_address);

extern boolean IGMP_is_member
(
   MC_MEMBER_PTR _PTR_  phead,      /* [IN] head of the MCB list */
   struct ip_if _PTR_   ipif,       /* [IN] the incoming interface */
   _ip_address          multiaddr   /* [IN] the multicast ip */
);

extern uint_32 IGMP_join_group  (MC_MEMBER_PTR _PTR_, ip_mreq _PTR_, uint_32 (_CODE_PTR_ _PTR_)(MC_MEMBER_PTR _PTR_));
extern uint_32 IGMP_leave_group (MC_MEMBER_PTR _PTR_, ip_mreq _PTR_, uint_32 (_CODE_PTR_ _PTR_)(MC_MEMBER_PTR _PTR_));

#endif
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/serial.h<|end_filename|>
#ifndef __serial_h__
#define __serial_h__ 1
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serial.h$
* $Version : 3.8.12.0$
* $Date    : Sep-1-2011$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the serial I/O functions.
*
*END************************************************************************/

#include "ioctl.h"

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/* Incoming and outgoing data not processed */
#define IO_SERIAL_RAW_IO             (0)

/* Perform xon/xoff processing */
#define IO_SERIAL_XON_XOFF           (0x01)

/*
** Perform translation :
**    outgoing \n to CR\LF
**    incoming CR to \n
**    incoming backspace erases previous character
*/
#define IO_SERIAL_TRANSLATION        (0x02)

/* echo incoming characters */
#define IO_SERIAL_ECHO               (0x04)

/* Perform hardware flow control processing */
#define IO_SERIAL_HW_FLOW_CONTROL    (0x08)

/*  */
#define IO_SERIAL_NON_BLOCKING       (0x10)

/* RS485 flags */
#define IO_SERIAL_HW_485_FLOW_CONTROL (0x20)

/* Serial I/O IOCTL commands */
#define IO_IOCTL_SERIAL_GET_FLAGS        _IO(IO_TYPE_SERIAL,0x01)
#define IO_IOCTL_SERIAL_SET_FLAGS        _IO(IO_TYPE_SERIAL,0x02)
#define IO_IOCTL_SERIAL_GET_BAUD         _IO(IO_TYPE_SERIAL,0x03)
#define IO_IOCTL_SERIAL_SET_BAUD         _IO(IO_TYPE_SERIAL,0x04)
#define IO_IOCTL_SERIAL_GET_STATS        _IO(IO_TYPE_SERIAL,0x05)
#define IO_IOCTL_SERIAL_CLEAR_STATS      _IO(IO_TYPE_SERIAL,0x06)
#define IO_IOCTL_SERIAL_TRANSMIT_DONE    _IO(IO_TYPE_SERIAL,0x07)
#define IO_IOCTL_SERIAL_GET_CONFIG       _IO(IO_TYPE_SERIAL,0x08)

#define IO_IOCTL_SERIAL_GET_HW_SIGNAL    _IO(IO_TYPE_SERIAL,0x09)
#define IO_IOCTL_SERIAL_SET_HW_SIGNAL    _IO(IO_TYPE_SERIAL,0x0A)
#define IO_IOCTL_SERIAL_CLEAR_HW_SIGNAL  _IO(IO_TYPE_SERIAL,0x0B)
/* Standard HW signal names used with GET/SET/CLEAR HW SIGNAL */
#define IO_SERIAL_CTS                    (1)
#define IO_SERIAL_RTS                    (2)
#define IO_SERIAL_DTR                    (4)
#define IO_SERIAL_DSR                    (8)
#define IO_SERIAL_DCD                    (0x10)
#define IO_SERIAL_RI                     (0x20)
#define IO_SERIAL_BRK                    (0x40)

#define IO_IOCTL_SERIAL_SET_DATA_BITS    _IO(IO_TYPE_SERIAL,0x0C)
#define IO_IOCTL_SERIAL_GET_DATA_BITS    _IO(IO_TYPE_SERIAL,0x0D)
/* Value used with SET DATA BITS is just the integer number of bits */

#define IO_IOCTL_SERIAL_SET_STOP_BITS    _IO(IO_TYPE_SERIAL,0x0E)
#define IO_IOCTL_SERIAL_GET_STOP_BITS    _IO(IO_TYPE_SERIAL,0x0F)
/* Standard names used with SET STOP BITS */
#define IO_SERIAL_STOP_BITS_1            (1)
#define IO_SERIAL_STOP_BITS_1_5          (2)
#define IO_SERIAL_STOP_BITS_2            (3)

#define IO_IOCTL_SERIAL_SET_PARITY       _IO(IO_TYPE_SERIAL,0x10)
#define IO_IOCTL_SERIAL_GET_PARITY       _IO(IO_TYPE_SERIAL,0x11)
/* Standard parity names used with SET PARITY */
#define IO_SERIAL_PARITY_NONE            (1)
#define IO_SERIAL_PARITY_ODD             (2)
#define IO_SERIAL_PARITY_EVEN            (3)
#define IO_SERIAL_PARITY_FORCE           (4)
#define IO_SERIAL_PARITY_MARK            (5)
#define IO_SERIAL_PARITY_SPACE           (6)

#define IO_IOCTL_SERIAL_START_BREAK      _IO(IO_TYPE_SERIAL,0x12)
#define IO_IOCTL_SERIAL_STOP_BREAK       _IO(IO_TYPE_SERIAL,0x13)
#define IO_IOCTL_SERIAL_TX_DRAINED       _IO(IO_TYPE_SERIAL,0x14)

#define IO_IOCTL_SERIAL_CAN_TRANSMIT     _IO(IO_TYPE_SERIAL,0x15)
#define IO_IOCTL_SERIAL_CAN_RECEIVE      _IO(IO_TYPE_SERIAL,0x16)

#define IO_IOCTL_SERIAL_DISABLE_RX       _IO(IO_TYPE_SERIAL,0x17)
#define IO_IOCTL_SERIAL_WAIT_FOR_TC      _IO(IO_TYPE_SERIAL,0x18)

#define IO_IOCTL_SERIAL_SET_RTL          _IO(IO_TYPE_SERIAL,0x19)
#define IO_IOCTL_SERIAL_GET_RTL          _IO(IO_TYPE_SERIAL,0x1A)


/*--------------------------------------------------------------------------*/
/*
**                      FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern void    _io_serial_default_init(void);

extern _mqx_uint _io_serial_polled_install(
      char_ptr,
      _mqx_uint (_CODE_PTR_)(pointer, pointer _PTR_, char _PTR_),
      _mqx_uint (_CODE_PTR_)(pointer, pointer),
      char    (_CODE_PTR_)(pointer),
      void    (_CODE_PTR_)(pointer, char),
      boolean (_CODE_PTR_)(pointer),
      _mqx_uint (_CODE_PTR_)(pointer, _mqx_uint, pointer),
      pointer, _mqx_uint);

extern _mqx_uint _io_serial_int_install(
      char_ptr,
      _mqx_uint (_CODE_PTR_)(pointer, char _PTR_),
      _mqx_uint (_CODE_PTR_)(pointer),
      _mqx_uint (_CODE_PTR_)(pointer, pointer),
      void     (_CODE_PTR_)(pointer, char),
      _mqx_uint (_CODE_PTR_)(pointer, _mqx_uint, pointer),
      pointer, _mqx_uint);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/sntp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sntp.c$
* $Version : 3.8.7.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains an implementation of an
*   SNTP client.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_UDP

/* SNTP client version */
#define SNTP_VERSION    0x04

/* Start CR 1052 */
/* Accepts version 3 or higher */
#define SNTP_VER_MIN   0x03
/* End CR */

/* Mode field in the SNTP header */
#define SNTP_MODE_CLIENT     0x03
#define SNTP_MODE_SERVER     0x04
#define SNTP_MODE_BROADCAST  0x05

/* Used to mask out fields in the LI_VN_MODE SNTP header field */
#define SNTP_MASK_MODE  0x07
#define SNTP_MASK_VN    0x38
#define SNTP_MASK_LI    0xC0

/* If this is set in the LI field, the timestamp is invalid */
#define SNTP_LI_ALARM   0x03

/* Minimum and maximum values accepted for the STRATUM field */
#define SNTP_STRATUM_MIN   0x01
#define SNTP_STRATUM_MAX   0x0E

/* Maximum value (in seconds) accepted for the poll interval */
#define SNTP_MAX_POLL      4294967


/* A SNTP header */
typedef struct sntp_header  {
   /*
   ** bits 0-1: Leap Indicator
   ** bits 2-4: Version Number
   ** bits 5-7: Mode
   */
   uchar    LI_VN_MODE[1];
   uchar    STRATUM[1];
   uchar    POLL[1];
   uchar    PRECISION[1];
   uchar    ROOT_DELAY[4];
   uchar    ROOT_DISPERSION[4];
   uchar    ROOT_IDENTIFIER[4];
   uchar    REFERENCE_TIMESTAMP1[4];
   uchar    REFERENCE_TIMESTAMP2[4];
   uchar    ORIGINATE_TIMESTAMP1[4];
   uchar    ORIGINATE_TIMESTAMP2[4];
   uchar    RECEIVE_TIMESTAMP1[4];
   uchar    RECEIVE_TIMESTAMP2[4];
   uchar    TRANSMIT_TIMESTAMP1[4];
   uchar    TRANSMIT_TIMESTAMP2[4];
} SNTP_HEADER, _PTR_ SNTP_HEADER_PTR;

struct sntpclnt_init {
   uint_32        poll;
   _ip_address    dest;
};

/* Function prototype */
static void    SNTP_task(pointer, pointer creator);
static boolean SNTP_valid_header(SNTP_HEADER_PTR);
static void    SNTP_build_header(SNTP_HEADER_PTR, uint_32_ptr, uint_32_ptr);
static void    SNTP_set_time(SNTP_HEADER_PTR, uint_32, uint_32);
static uint_32 SNTP_setup(uint_32_ptr, _ip_address, uint_32);
static uint_32 SNTP_timed_send_recv(uint_32 sock, _ip_address _PTR_,
   uint_32_ptr);

static void SNTP_add96(uint_32_ptr, uint_32_ptr, uint_32_ptr);
static void SNTP_sub96(uint_32_ptr, uint_32_ptr, uint_32_ptr);
static void SNTP_shiftr96(uint_32_ptr, uint_32_ptr);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_init
* Returned Value   : error code
* Comments  :  Start the SNTP client.
*
*END*-----------------------------------------------------------------*/

uint_32 SNTP_init
   (
      char_ptr          name,
      uint_32           priority,
      uint_32           stacksize,
      _ip_address       destination,
      uint_32           poll
   )
{ /* Body */
   struct sntpclnt_init init;

   init.poll = poll;
   init.dest = destination;
   return RTCS_task_create(name, priority, stacksize, SNTP_task, &init);
} /* Endbody */



/*TASK*----------------------------------------------------------------
*
* Function Name   : SNTP_task
* Returned Value  : void
* Comments        : This task requests the current time from a time server.
*                   Once the time server replies with the current time, the
*                   system time is set and the task ends.
*
*END*-----------------------------------------------------------------*/

static void SNTP_task
   (
      pointer init_ptr,
      pointer creator
   )
{ /* Body */

   struct sntpclnt_init    init = *(struct sntpclnt_init *)init_ptr;
   uint_32                 sock, error_code, timeout;

   /* Setup socket and check parameters */
   error_code = SNTP_setup(&sock, init.dest, init.poll);

   if (error_code != RTCS_OK) {
      RTCS_task_exit(creator, error_code);
   } else  {
      RTCS_task_resume_creator(creator, RTCS_OK);
   } /* Endif */

   /*
   ** Start an infinite loop and poll for time at regular intervals.
   */
   while (TRUE) {
      timeout = init.poll * 1000;
      error_code = SNTP_timed_send_recv(sock, &init.dest, &timeout);
      RTCS_delay(timeout);
   } /* Endwhile */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_oneshot
* Returned Value   : uint_32 error code
* Comments  :  Blocking function call that gets the time from a NTP/SNTP
*     server and sets the local time accordingly. If the NTP/SNTP server does
*     not reply within a certain timeout, function returns an error.
*
*END*-----------------------------------------------------------------*/

uint_32 SNTP_oneshot
   (
      _ip_address destination,
         /*[IN] Destination IP address */
      uint_32     timeout
         /*[IN] Maximum time (in milliseconds) to keep trying to get time */
   )
{ /* Body */
   uint_32  sock, error_code;

   /* Setup socket and check parameters */
   error_code = SNTP_setup(&sock, destination, 1);

   if (error_code != RTCS_OK) {
      return error_code;
   } /* Endif */

   error_code = SNTP_timed_send_recv(sock, &destination, &timeout);

   shutdown(sock, FLAG_CLOSE_TX);
   return error_code;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_valid_header
* Returned Value   : boolean
* Comments  :  Checks to see if the packet is a valid SNTP/NTP reply for a
*     ANYCAST or UNICAST client. (Will not work with a MULTICAST client packet)
*
*END*-----------------------------------------------------------------*/

static boolean SNTP_valid_header
   (
      SNTP_HEADER_PTR   header_ptr
         /*[IN] pointer to a SNTP header struct */
   )
{ /* Body */
   /* Reply shoud be in server mode */
   /* Version should be same as in original message */
   /* LI field should be between 0 and 2 */
   /* Stratum should be between 1 and 14 */
   /* Originate timestamp must be non zero */
   /* Receive timestamp must be non zero */
   /* Transmit timestamp must be non-zero */
   return(
      ((ntohc(header_ptr->LI_VN_MODE) & SNTP_MASK_MODE) == SNTP_MODE_SERVER) &&
      /* Start CR 1052 */
      ((ntohc(header_ptr->LI_VN_MODE) & SNTP_MASK_VN) >> 3 >= SNTP_VER_MIN) &&
      /* End CR */
      ((ntohc(header_ptr->LI_VN_MODE) & SNTP_MASK_LI) >> 6 != SNTP_LI_ALARM) &&
      ( ntohc(header_ptr->STRATUM) >= SNTP_STRATUM_MIN) &&
      ( ntohc(header_ptr->STRATUM) <= SNTP_STRATUM_MAX) &&
      ((ntohl(header_ptr->RECEIVE_TIMESTAMP1)  != 0)    ||
      ( ntohl(header_ptr->RECEIVE_TIMESTAMP2)  != 0))   &&
      ((ntohl(header_ptr->TRANSMIT_TIMESTAMP1) != 0)    ||
      ( ntohl(header_ptr->TRANSMIT_TIMESTAMP2) != 0))
    );
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_build_header
* Returned Value   : void
* Comments  :  Builds a sntp header for to be transmitted by a sntp client and
*     returns the originate timestamp
*
*END*-----------------------------------------------------------------*/

static void SNTP_build_header
   (
      SNTP_HEADER_PTR   header_ptr,
         /*[OUT] a build SNTP header */
      uint_32_ptr       orig_sec_ptr,
         /*[OUT] the orignate time in seconds */
      uint_32_ptr       orig_fract_ptr
         /*[OUT] the orignate fraction of seconds */
   )
{ /* Body */
   _mem_zero(header_ptr, sizeof(SNTP_HEADER));

   /* Set the version */
   htonc(header_ptr->LI_VN_MODE, (SNTP_VERSION << 3));

   /* Set the mode */
   htonc(header_ptr->LI_VN_MODE,
      SNTP_MODE_CLIENT | ntohc(header_ptr->LI_VN_MODE));

   /* Set the Transmit timestamp */
   RTCS_date_get(orig_sec_ptr, orig_fract_ptr);
   htonl(header_ptr->TRANSMIT_TIMESTAMP1, *orig_sec_ptr);
   htonl(header_ptr->TRANSMIT_TIMESTAMP2, *orig_fract_ptr);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_set_time
* Returned Value   : void
* Comments  :  Takes a valid sntp header and uses it to set the local clock
*
* RFC2030: Calculate the time offset:
*    T1: ORIGINATE (local time at which client sent request)
*    T2: RECEIVE (the time at which server received request)
*    T3: TRANSMIT (the time sent be the server)
*    T4: DESTINATION (the local time at which client received request)
*
*    Time offset = ((T2 - T1) + (T3 - T4)) / 2
*
*END*-----------------------------------------------------------------*/

static void SNTP_set_time
   (
      /*[IN] valid sntp header */
      SNTP_HEADER_PTR   header_ptr,
      /*[IN] seconds from timestamp when header was received */
      uint_32 calc_sec,
      /*[IN] fraction of seconds from timestamp when header was received */
      uint_32 calc_fract
   )
{ /* Body */
   uint_32 t1[3], t2[3], t3[3], t4[3], temp1[3], temp2[3];

   t1[1] = ntohl(header_ptr->ORIGINATE_TIMESTAMP1);
   t1[2] = ntohl(header_ptr->ORIGINATE_TIMESTAMP2);
   t2[1] = ntohl(header_ptr->RECEIVE_TIMESTAMP1);
   t2[2] = ntohl(header_ptr->RECEIVE_TIMESTAMP2);
   t3[1] = ntohl(header_ptr->TRANSMIT_TIMESTAMP1);
   t3[2] = ntohl(header_ptr->TRANSMIT_TIMESTAMP2);
   t4[1] = calc_sec;
   t4[2] = calc_fract;

   t1[0] = 0;
   t2[0] = 0;

   /* If t4 is smaller than t1, set top bit to 1 */
   if (t4[1] < t1[1] || (t4[1] == t1[1] && t4[2] < t1[2]))
      t4[0] = 1;
   else
      t4[0] = 0;

   /* If t3 is smaller than t2, set top bit to 1 */
   if (t3[1] < t2[1] || (t3[1] == t2[1] && t3[2] < t2[2]))
      t3[0] = 1;
   else
      t3[0] = 0;

   SNTP_sub96(t2, t1, temp1);
   SNTP_sub96(t3, t4, temp2);
   SNTP_add96(temp1, temp2, t4);
   SNTP_shiftr96(t4, temp2);

   /*
   ** Now the time offset is added to the local time.
   */
   temp1[0] = 0;
   RTCS_date_get(temp1 + 1, temp1 + 2);
   SNTP_add96(temp1, temp2, t4);

   RTCS_date_set(t4[1], t4[2]);

} /* Body */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_setup
* Returned Value   : uint_32 error code
* Comments  :  Checks the parameters for invalid values and tries to create and
*     bind a socket.
*
*END*-----------------------------------------------------------------*/

static uint_32  SNTP_setup
   (
      uint_32_ptr    sock_ptr,
        /*[OUT] pointer to the new socket */
      _ip_address    destination,
         /*[IN] the destination address */
      uint_32        poll
         /*[IN] the polling interval */
   )
{ /* Body */
   sockaddr_in    addr;
   uint_32        error_code = RTCS_OK;

   /* Check input parameters */
   if (poll == 0 || poll > SNTP_MAX_POLL || destination == 0) {
      return RTCSERR_INVALID_PARAMETER;
   } /* Endif */

   /* Create a socket for the communication */
   if ((*sock_ptr = socket(PF_INET, SOCK_DGRAM, 0)) == RTCS_SOCKET_ERROR)  {
      return RTCS_SOCKET_ERROR;
   } /* Endif */

   /* Local address */
   addr.sin_family      = AF_INET;
   addr.sin_port        = IPPORT_NTP;
   addr.sin_addr.s_addr = INADDR_ANY;

   error_code = bind(*sock_ptr, (const sockaddr *)&addr, sizeof(addr));
   if (error_code) {
      shutdown(*sock_ptr, FLAG_ABORT_CONNECTION);
   } /* Endif */

   return error_code;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_timed_send_recv
* Returned Value   : uint_32 error code
* Comments  :  Tries to send and receive a SNTP packet. Also sets the system
*     time if a valid SNTP packet is received.
*
*END*-----------------------------------------------------------------*/

static uint_32  SNTP_timed_send_recv
   (

      uint_32 sock,
         /*[IN] socket */
      _ip_address _PTR_ destination,
         /*[IN] remote IP NTP service */
      uint_32_ptr  msec_count_ptr
         /*[IN] millisecond timeout value */
   )
{ /* Body */
   SNTP_HEADER    header;
   sockaddr_in    addr;
   uint_16        remote_len = sizeof(sockaddr_in);
   int_32         error;
   uint_32        timeout, msec_base, diff, error_code, sec, sec_fract,
                  orig_sec, orig_msec, msec_count = *msec_count_ptr;

   /* Setup destination IP */
   addr.sin_family      = AF_INET;
   addr.sin_addr.s_addr = *destination;
   addr.sin_port        = IPPORT_NTP;

   /* Build a packet for unicast/anycast mode and send it  */
   SNTP_build_header(&header, &orig_sec, &orig_msec);

   /* Send packet */
   error = sendto(sock, (char_ptr)&header, sizeof(SNTP_HEADER), 0, (sockaddr *)&addr,
      sizeof(sockaddr_in));

   /* Get reply only if request was sent */
   if (error != sizeof(SNTP_HEADER)) {
      return RTCS_geterror(sock);
   } /* Endif */

   /* Accept only correct replies */
   do  {
      msec_base = RTCS_time_get();
      if (msec_count == 0)  {
         timeout = (uint_32)-1;
      } else  {
         timeout = msec_count;
      } /* Endif */

      error_code = RTCS_selectset(&sock, 1, timeout);

      /* Calculate elapsed time */
      diff = RTCS_timer_get_interval(msec_base, RTCS_time_get());
      if (diff > msec_count)  {
         msec_count = 0;
      } else  {
         msec_count -= diff;
      } /* Endif */

      if (error_code == sock) { /* If there is activity */
         error = recvfrom(sock, (char_ptr)&header, sizeof(SNTP_HEADER), 0, (sockaddr *)&addr, &remote_len);

         /* If error is critical, quit */
         if (error == RTCS_ERROR) {
            return RTCS_geterror(sock);
         } /* Endif */

         /* If non-critical error, try again */
         if (error != sizeof(SNTP_HEADER) || addr.sin_port != IPPORT_NTP) {
            continue;
         } /* Endif */

         /* If the message is not from the specified server, try again */
         if (!IN_MULTICAST(*destination) && *destination != INADDR_BROADCAST &&
            *destination != addr.sin_addr.s_addr) {
            continue;
         } /* Endif */

         /* Take a timestamp of time received */
         RTCS_date_get(&sec, &sec_fract);

         /* Make sure the reply is not an old duplicate */
         if (ntohl(header.ORIGINATE_TIMESTAMP1) != orig_sec &&
             ntohl(header.ORIGINATE_TIMESTAMP2) != orig_msec)  {
            continue;
         } /* Endif */

         /* If the message is valid, then break from the recv loop */
         if (SNTP_valid_header(&header)) {
            SNTP_set_time(&header, sec, sec_fract);
            /* UNICAST/ANYCAST client becomes UNICAST */
            *destination = addr.sin_addr.s_addr;
            break;
         } /* Endif */
      } /* Endif */
   } while (msec_count > 0);

   *msec_count_ptr = msec_count;
   if (error_code == 0) {
      error_code = RTCSERR_TIMEOUT;
   } else  {
      error_code = RTCS_OK;
   } /* Endif */

   return error_code;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_add96
* Returned Value   : void
* Comments  :  Adds the 96 bit numbers x and y, and stores the result in z
*
*END*-----------------------------------------------------------------*/

static void SNTP_add96
   (
      uint_32_ptr x,
         /* 96 bit number: x0x1x2 */
      uint_32_ptr y,
         /* 96 bit number: y0y1y2 */
      uint_32_ptr z
         /* 96 bit number: z0z1z2 */
   )
{ /* Body */
   boolean carry;

   /* Add the fraction of seconds */
   z[2] = x[2] + y[2];

   /* Check for carry */
   carry = (z[2] < x[2]);

   /* Add the seconds together, and the carry if it exists */
   z[1] = x[1] + y[1] + (carry?1:0);

   /* Start CR 1051 */
   /* Check for a new carry. Make sure z[1] is not 0 before we sub 1 */
   if (!carry) {
      carry = (z[1] < x[1]);
   } else if (z[1]) {
      carry = (z[1] - 1 < x[1]);
   } /* Endif */
   /* End CR */

   /* Add the high words together and add the carry if it exists */
   z[0] = x[0] + y[0] + (carry?1:0);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_sub96
* Returned Value   : void
* Comments  :  Subtract 96 bit numbers y from x, and stores the result in z
*
*END*-----------------------------------------------------------------*/

static void SNTP_sub96
   (
      uint_32_ptr x,
         /* 96 bit number: x0x1x2 */
      uint_32_ptr y,
         /* 96 bit number: y0y1y2 */
      uint_32_ptr z
         /* 96 bit number: z0z1z2 */
   )
{ /* Body */
   boolean carry;

   /* Subtract the fraction of seconds */
   z[2] = x[2] - y[2];

   /* Check for a carry */
   carry = (x[2] < y[2]);

   /* Subtract the seconds, along with carry if it exists */
   z[1] = x[1] - y[1] - (carry?1:0);

   /* Start CR 1051 */
   /* Check for a new carry. Make sure x[1] is not 0 before we sub 1 */
   if (!carry) {
      carry = (x[1] < y[1]);
   } else if (x[1]) {
      carry = (x[1] - 1 < y[1]);
   } /* Endif */
   /* End CR */

   /* Subtract the high words, along with carry if it exists */
   z[0] = x[0] - y[0] - (carry?1:0);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SNTP_shiftr96
* Returned Value   : void
* Comments  :  Unsigned right shift on x. Result stores in z
*
*END*-----------------------------------------------------------------*/

static void SNTP_shiftr96
   (
      uint_32_ptr x,
         /* 96 bit number: x0x1x2 */
      uint_32_ptr z
         /* 96 bit number: z0z1z2 */
   )
{ /* Body */

   z[0] = x[0] >> 1;

   z[1] = (x[0] << 31) | (x[1] >> 1);

   z[2] = (x[1] << 31) | (x[2] >> 1);

} /* Endbody */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_pit.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_pit.c$
* $Version : 3.8.1.0$
* $Date    : May-11-2011$
*
* Comments:
*
*   This file contains timer functions for use with a PIT.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "timer_pit.h"


#define PIT_PCSR_PRESCALE_SHIFT 8
#define PIT_PCSR_DOZE           (1<<6)
#define PIT_PCSR_HALTED         (1<<5)
#define PIT_PCSR_OVW            (1<<4)
#define PIT_PCSR_PIE            (1<<3)
#define PIT_PCSR_PIF            (1<<2)
#define PIT_PCSR_RLD            (1<<1)
#define PIT_PCSR_EN             (1<<0)


typedef struct pit_struct
{
    uint_16 PCSR;   /* PIT control and status register */
    uint_16 PMR;    /* PIT modulus register */
    uint_16 PCNTR;  /* PIT counter register */
} PIT_STRUCT, _PTR_ PIT_STRUCT_PTR;


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _pit_init_freq
* Returned Value  : hw ticks per tick
* Comments        :
*   this function will set up a timer to interrupt
*
*END*---------------------------------------------------------------------*/

uint_32 _pit_init_freq
    (
        /* [IN] the timer to initialize */
        uint_8    timer,

        /* [IN] ticks per second */
        uint_32   tickfreq,

        /* [IN] input clock speed in Hz */
        uint_32   clk,

        /* [IN] unmask the timer after initializing */
        boolean   unmask_timer
    )
{
    uint_32 rate, prescale = 0;

    volatile PIT_STRUCT _PTR_  pit_ptr;

    pit_ptr = _bsp_get_pit_base_address(timer);
    if (pit_ptr == NULL) return 0;

    _bsp_int_init(_bsp_timers[timer].INTERRUPT, _bsp_timers[timer].LEVEL, _bsp_timers[timer].PRIORITY, FALSE);

    rate = (clk / tickfreq);
    while (rate > (0xFFFF+1)) {
        prescale += 1;  /* divides clock in half */
        clk >>= 1;
        rate = (clk / tickfreq);
    }

    pit_ptr->PCSR = (prescale << PIT_PCSR_PRESCALE_SHIFT)
        | PIT_PCSR_HALTED             /* stop timer when halted */
        | PIT_PCSR_PIF                /* Clear interrupt if present */
        | PIT_PCSR_OVW                /* Overwrite count with PMR when written */
        | PIT_PCSR_OVW                /* Enables writing to PMR */
        | PIT_PCSR_PIE                /* PIT interrupt Enable */
        | PIT_PCSR_RLD;               /* Enabled Reload bit */

    /* Set counter reload value and counter value */
    pit_ptr->PMR = (uint_16)(rate-1);

    if (unmask_timer) {
        _bsp_int_enable(_bsp_timers[timer].INTERRUPT);
    }

    /* Enable the timer */
    pit_ptr->PCSR |= PIT_PCSR_EN;

    /* return number of hw-ticks per MQX tick */
    return rate;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _pit_get_hwticks
* Returned Value  : Number of ticks
* Comments        :
*   This function will return the number of ticks elapsed since the last
* timer tick.
*
*END*---------------------------------------------------------------------*/

uint_32 _pit_get_hwticks
    (
        /* [IN] the timer to use */
        pointer parameter
    )
{
    uint_16 pmr;
    uint_32 ticks;
    
    volatile PIT_STRUCT _PTR_  pit_ptr;

    pit_ptr = _bsp_get_pit_base_address((uint_8)parameter);
    if (pit_ptr == NULL) return 0;

    pmr   = pit_ptr->PMR;
    ticks = pmr - pit_ptr->PCNTR;

    if ((pit_ptr->PCSR & PIT_PCSR_PIF) != 0) {
        /* Another full TICK period has expired since we handled the last timer interrupt.
        We need to read the counter again, since the wrap may have
        occurred between the previous read and the checking of the overflow bit. */
        ticks = pmr + (pmr-pit_ptr->PCNTR) + 1;
    }
   
    return ticks;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _pit_clear_int
* Returned Value  :
* Comments        :
*   This function will clear interrupt flag of given timer
*
*END*---------------------------------------------------------------------*/

void _pit_clear_int
    (
        /* [IN] the timer to use */
        uint_8    timer
    )
{
    volatile uint_8 *pcsr_low;
    volatile PIT_STRUCT _PTR_  pit_ptr;

    pit_ptr = _bsp_get_pit_base_address(timer);
    if (pit_ptr == NULL) return;

#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
    pcsr_low = ((uint_8 *)(&pit_ptr->PCSR)) + 1;
#else
    pcsr_low = ((uint_8 *)(&pit_ptr->PCSR));
#endif

    *pcsr_low |= PIT_PCSR_PIF;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/phy/phy_ksz8041.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: phy_ksz8041.h$
* $Version : 3.0.3.0$
* $Date    : Jul-8-2009$
*
* Comments:
*
*   This file contains definitions that belongs to the PHY chip
*   ksz8041.
*
*END************************************************************************/
#ifndef _phy_ksz8041_h_
#define _phy_ksz8041_h_ 1

#ifdef __cplusplus
extern "C" {
#endif

/*
** Register definitions for the PHY.
*/

enum phy_reg {
   PHY_MII_REG_CR       = 0,  // Control Register
   PHY_MII_REG_SR       = 1,  // Status Register
   PHY_MII_REG_PHYIR1   = 2,  // PHY Identification Register 1
   PHY_MII_REG_PHYIR2   = 3,  // PHY Identification Register 2
   PHY_MII_REG_ANAR     = 4,  // A-N Advertisement Register
   PHY_MII_REG_ANLPAR   = 5,  // A-N Link Partner Ability Register
   PHY_MII_REG_ANER     = 6,  // A-N Expansion Register
   PHY_MII_REG_ANNPTR   = 7,  // A-N Next Page Transmit Register
   PHY_MII_REG_ANLPRNPR = 8,  // A-N Link Partner Received Next Page Reg.

   PHY_MII_REG_RXER     = 0x15,  // RX Error counter 
   PHY_MII_REG_ICS      = 0x1b,  //  Interrupt Control Status Register 
   PHY_MII_REG_PHYC1    = 0x1e,  // Phy control 1
   PHY_MII_REG_PHYC2    = 0x1f   // Phy control 2
};


// values for PHY_MII_REG_CR Status Register

#define PHY_MII_REG_CR_AN_ENABLE   0x1000
#define PHY_MII_REG_CR_LOOP        0x4000
#define PHY_MII_REG_CR_RESET       0x8000


// values for PHY_MII_REG_SR Status Register

#define PHY_MII_REG_SR_EXTCAP        0x0001
#define PHY_MII_REG_SR_JABBER        0x0002
#define PHY_MII_REG_SR_LINK_STATUS   0x0004
#define PHY_MII_REG_SR_AN_ABLE       0x0008 // Auto-negotiate ability
#define PHY_MII_REG_SR_REMOTE_FAULT  0x0010
#define PHY_MII_REG_SR_AN_COMPLETE   0x0020 // Auto-negotiate completed


// values for PHY_MII_REG_SR2 Status Register

#define PHY_MII_REG_PHYC2_OP_MODE_MASK    0x001c 
#define PHY_MII_REG_PHYC2_OP_MODE_AN      0x0000 
#define PHY_MII_REG_PHYC2_OP_MODE_10_HD   0x0004 
#define PHY_MII_REG_PHYC2_OP_MODE_100_HD  0x0008 
#define PHY_MII_REG_PHYC2_OP_MODE_10_FD   0x0014 
#define PHY_MII_REG_PHYC2_OP_MODE_100_FD  0x0018 


extern const ENET_PHY_IF_STRUCT phy_ksz8041_IF;
 
#define MII_TIMEOUT                     (0x10000)

#ifdef __cplusplus
}
#endif

#endif /* _phy_ksz8041_h_ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/serl_mcf52xx.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_mcf52xx.h$
* $Version : 3.6.4.0$
* $Date    : Dec-3-2010$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the serial drivers for the MCF5223
*
*END************************************************************************/
#ifndef _serial_mcf52xx_h
#define _serial_mcf52xx_h 1

#include "mcf52xx_uart.h"

#ifdef __cplusplus
extern "C" {
#endif

/*--------------------------------------------------------------------------*/
/*
**                    CONSTANT DEFINITIONS
*/

/*
** I/O Initialization error codes
*/
#define MCF52XX_IO_INVALID_CHANNEL        (0x10000)

/* Initialization values for the DEVICE field of the IO_INIT_STRUCT */
/* Channel number for Serial port 1 */
#define MCF52XX_IO_UART0                  (0)
/* Channel number for Serial port 2 */
#define MCF52XX_IO_UART1                  (1)
/* Channel number for Serial port 3 */
#define MCF52XX_IO_UART2                  (2)



/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** MCF52XX_UART_SERIAL_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a serial port is initialized.
*/
typedef struct mcf52XX_uart_serial_init_struct
{

   /* The size of the queues to buffer incoming/outgoing data */
   uint_32 QUEUE_SIZE;

   /* The device to initialize */
   uint_32 DEVICE;

   /* The clock speed of cpu */
   uint_32 CLOCK_SPEED;

   /* The interrupt vector to use if interrupt driven */
   uint_32 VECTOR;

   /* The interrupt level to use if interrupt driven */
   _int_level LEVEL;

   /* The sub-level within the interrupt level to use if interrupt driven */
   _int_priority SUBLEVEL;

   /* The value for the UMR 1 register */
   uint_32 UMR1_VALUE;

   /* The value for the UMR 2 register */
   uint_32 UMR2_VALUE;

   /* The baud rate for the channel */
   uint_32 BAUD_RATE;

} MCF52XX_UART_SERIAL_INIT_STRUCT, _PTR_ MCF52XX_UART_SERIAL_INIT_STRUCT_PTR;

typedef const MCF52XX_UART_SERIAL_INIT_STRUCT _PTR_ MCF52XX_UART_SERIAL_INIT_STRUCT_CPTR;

/*
** MCF52XX_UART_SERIAL_INFO_STRUCT
** Run time state information for each serial channel
*/
typedef struct mcf52XX_uart_serial_info_struct
{
   /* The current init values for this port */
   MCF52XX_UART_SERIAL_INIT_STRUCT   INIT;

   /* The serial device register */
   MCF52XX_UART_STRUCT_PTR           UART_PTR;

   uint_32                           INT_ENABLE_BITS;

   uint_32                           INT_BITS;
   
   uint_32                           CONTROL_BITS;

   /* The previous interrupt handler and data */
   void       (_CODE_PTR_ OLD_ISR)(pointer);
   void       (_CODE_PTR_ OLD_ISR_EXCEPTION_HANDLER)(uint_32, uint_32, pointer,
               pointer);
   pointer                           OLD_ISR_DATA;

   /* Statistical information */
   uint_32                           INTERRUPTS;
   uint_32                           RX_CHARS;
   uint_32                           TX_CHARS;
   uint_32                           RX_BREAKS;
   uint_32                           RX_PARITY_ERRORS;
   uint_32                           RX_FRAMING_ERRORS;
   uint_32                           RX_OVERRUNS;
   uint_32                           RX_DROPPED_INPUT;
} MCF52XX_UART_SERIAL_INFO_STRUCT, _PTR_ MCF52XX_UART_SERIAL_INFO_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

extern uint_32 _mcf52xx_uart_serial_polled_init(MCF52XX_UART_SERIAL_INIT_STRUCT_PTR,pointer _PTR_,char _PTR_);
extern uint_32 _mcf52xx_uart_serial_polled_install(char_ptr, MCF52XX_UART_SERIAL_INIT_STRUCT_CPTR , uint_32);
extern uint_32 _mcf52xx_uart_serial_int_install(char_ptr, MCF52XX_UART_SERIAL_INIT_STRUCT_CPTR , uint_32);
extern pointer _bsp_get_serial_base_address (uint_8);
PSP_INTERRUPT_TABLE_INDEX _bsp_get_serial_vector (uint_8);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_nstat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_nstat.c$
* $Version : 3.8.7.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS
#include <rtcs.h>
#include <enet.h>
#include "sh_rtcs.h"



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_netstat
*  Returned Value:  none
*  Comments  :  The shell function to print RTCS netstats
*
*END*-----------------------------------------------------------------*/

int_32 Shell_netstat(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean              print_usage, shorthelp = FALSE;

#if RTCSCFG_ENABLE_IP_STATS
   IP_STATS_PTR         ip   = IP_stats();
#endif
#if RTCSCFG_ENABLE_ICMP_STATS
   ICMP_STATS_PTR       icmp = ICMP_stats();
#endif
#if RTCSCFG_ENABLE_UDP_STATS
   UDP_STATS_PTR        udp  = UDP_stats();
#endif
#if RTCSCFG_ENABLE_TCP_STATS
   TCP_STATS_PTR        tcp  = TCP_stats();
#endif
#if  BSPCFG_ENABLE_ENET_STATS
   _enet_handle         handle;
   ENET_STATS_PTR       enet = NULL;
#endif
   
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );
   
   if (!print_usage)  {
#if BSPCFG_ENABLE_ENET_STATS
       handle = _mqx_get_io_component_handle(IO_ENET_COMPONENT);
       while (handle) {
           #if BSP_ENET_DEVICE_COUNT > 0
           enet = ENET_get_stats(handle);
           printf("\nENET %x:\n",handle );
           printf("\t%ld packets received\n",               enet->COMMON.ST_RX_TOTAL);
           printf("\t%ld rx packets missed\n",              enet->COMMON.ST_RX_MISSED);
           printf("\t%ld rx packets discarded\n",           enet->COMMON.ST_RX_DISCARDED);
           printf("\t%ld rx packets with error\n",          enet->COMMON.ST_RX_ERRORS);
           
           printf("\t%ld packets received\n",               enet->COMMON.ST_TX_TOTAL);
           printf("\t%ld tx packets missed\n",              enet->COMMON.ST_TX_MISSED);
           printf("\t%ld tx packets discarded\n",           enet->COMMON.ST_TX_DISCARDED);
           printf("\t%ld tx packets received with error\n", enet->COMMON.ST_TX_ERRORS);

        /* Following stats are physical errors/conditions */
           printf("\t%ld rx align error\n",        enet->ST_RX_ALIGN);
           printf("\t%ld rx fcs error\n",          enet->ST_RX_FCS);
           printf("\t%ld rx runt error\n",         enet->ST_RX_RUNT);
           printf("\t%ld rx giant error\n",        enet->ST_RX_GIANT);
           printf("\t%ld rx latecoll error\n",     enet->ST_RX_LATECOLL);
           printf("\t%ld rx overrun error\n",      enet->ST_RX_OVERRUN);

           printf("\t%ld tx SQE\n",                enet->ST_TX_SQE);
           printf("\t%ld tx deferred\n",           enet->ST_TX_DEFERRED);
           printf("\t%ld tx late collision\n",     enet->ST_TX_LATECOLL);
           printf("\t%ld tx excessive collision\n",enet->ST_TX_EXCESSCOLL);
           printf("\t%ld tx carrier\n",            enet->ST_TX_CARRIER);
           printf("\t%ld tx unerrun error\n",      enet->ST_TX_UNDERRUN);

          handle = ENET_get_next_device_handle(handle);
          #endif /* BSP_ENET_DEVICE_COUNT > 0 */
       }
       
#endif

#if RTCSCFG_ENABLE_IP_STATS
      printf("\nIP:\n");
      printf("\t%ld packets received\n",                  ip->COMMON.ST_RX_TOTAL);
      printf("\t%ld packets delivered\n",                 ip->ST_RX_DELIVERED);
      printf("\t%ld packets forwarded\n",                 ip->ST_RX_FORWARDED);
      printf("\t%ld discarded for lack of resources\n",   ip->COMMON.ST_RX_MISSED);
      printf("\t%ld discarded due to internal errors\n",  ip->COMMON.ST_RX_ERRORS);
      printf("\t%ld discarded for other reasons:\n",      ip->COMMON.ST_RX_DISCARDED);
      printf("\t\t%ld with header errors\n",              ip->ST_RX_HDR_ERRORS);
      printf("\t\t%ld with an illegal destination\n",     ip->ST_RX_ADDR_ERRORS);
      printf("\t\t%ld with unknown protocols\n",          ip->ST_RX_NO_PROTO);
      printf("\t%ld fragments received\n",                ip->ST_RX_FRAG_RECVD);
      printf("\t%ld fragments reassembled\n",             ip->ST_RX_FRAG_REASMD);
      printf("\t%ld fragments discarded\n",               ip->ST_RX_FRAG_DISCARDED);
      printf("\t%ld packets sent\n",                      ip->COMMON.ST_TX_TOTAL);
      printf("\t%ld unsent for lack of resources\n",      ip->COMMON.ST_TX_MISSED);
      printf("\t%ld unsent due to internal errors\n",     ip->COMMON.ST_TX_ERRORS);
      printf("\t%ld destinations found unreachable\n",    ip->COMMON.ST_TX_DISCARDED);
      printf("\t%ld packets fragmented\n",                ip->ST_TX_FRAG_FRAGD);
      printf("\t%ld fragments sent\n",                    ip->ST_TX_FRAG_SENT);
      printf("\t%ld fragmentation failures\n",            ip->ST_TX_FRAG_DISCARDED);
      printf("-- More --"); getchar();
#endif

#if RTCSCFG_ENABLE_ICMP_STATS
      printf("\nICMP:\n");
      printf("\t%ld packets received\n",                  icmp->COMMON.ST_RX_TOTAL);
      printf("\t%ld discarded for lack of resources\n",   icmp->COMMON.ST_RX_MISSED);
      printf("\t%ld discarded due to internal errors\n",  icmp->COMMON.ST_RX_ERRORS);
      printf("\t%ld discarded for other reasons:\n",      icmp->COMMON.ST_RX_DISCARDED);
      printf("\t\t%ld with header errors\n",              icmp->ST_RX_BAD_CHECKSUM + icmp->ST_RX_SMALL_DGRAM);
      printf("\t\t%ld unrecognized codes\n",              icmp->ST_RX_BAD_CODE);
      printf("\t\t%ld redirects from non-gateways\n",     icmp->ST_RX_RD_NOTGATE);
      printf("\t%ld packets sent\n",                      icmp->COMMON.ST_TX_TOTAL);
      printf("\t%ld discarded for lack of resources\n",   icmp->COMMON.ST_TX_MISSED);
      printf("\t%ld discarded due to internal errors\n",  icmp->COMMON.ST_TX_ERRORS);
      printf("\t%ld with illegal type or code\n",         icmp->COMMON.ST_TX_DISCARDED);
      printf("\tInput histogram:\n");
      if (icmp->ST_RX_DESTUNREACH) printf("\t\t%ld Destination Unreachables\n", icmp->ST_RX_DESTUNREACH);
      if (icmp->ST_RX_TIMEEXCEED)  printf("\t\t%ld Time Exceededs\n",           icmp->ST_RX_TIMEEXCEED);
      if (icmp->ST_RX_PARMPROB)    printf("\t\t%ld Parameter Problems\n",       icmp->ST_RX_PARMPROB);
      if (icmp->ST_RX_SRCQUENCH)   printf("\t\t%ld Source Quenches\n",          icmp->ST_RX_SRCQUENCH);
      if (icmp->ST_RX_REDIRECT)    printf("\t\t%ld Redirects\n",                icmp->ST_RX_REDIRECT);
      if (icmp->ST_RX_ECHO_REQ)    printf("\t\t%ld Echo Requests\n",            icmp->ST_RX_ECHO_REQ);
      if (icmp->ST_RX_ECHO_REPLY)  printf("\t\t%ld Echo Replies\n",             icmp->ST_RX_ECHO_REPLY);
      if (icmp->ST_RX_TIME_REQ)    printf("\t\t%ld Timestamp Requests\n",       icmp->ST_RX_TIME_REQ);
      if (icmp->ST_RX_TIME_REPLY)  printf("\t\t%ld Timestamp Replies\n",        icmp->ST_RX_TIME_REPLY);
      if (icmp->ST_RX_INFO_REQ)    printf("\t\t%ld Information Requests\n",     icmp->ST_RX_INFO_REQ);
      if (icmp->ST_RX_INFO_REPLY)  printf("\t\t%ld Information Replies\n",      icmp->ST_RX_INFO_REPLY);
      if (icmp->ST_RX_OTHER)       printf("\t\t%ld Unknown\n",                  icmp->ST_RX_OTHER);
      printf("\tOutput histogram:\n");
      if (icmp->ST_TX_DESTUNREACH) printf("\t\t%ld Destination Unreachables\n", icmp->ST_TX_DESTUNREACH);
      if (icmp->ST_TX_TIMEEXCEED)  printf("\t\t%ld Time Exceededs\n",           icmp->ST_TX_TIMEEXCEED);
      if (icmp->ST_TX_PARMPROB)    printf("\t\t%ld Parameter Problems\n",       icmp->ST_TX_PARMPROB);
      if (icmp->ST_TX_SRCQUENCH)   printf("\t\t%ld Source Quenches\n",          icmp->ST_TX_SRCQUENCH);
      if (icmp->ST_TX_REDIRECT)    printf("\t\t%ld Redirects\n",                icmp->ST_TX_REDIRECT);
      if (icmp->ST_TX_ECHO_REQ)    printf("\t\t%ld Echo Requests\n",            icmp->ST_TX_ECHO_REQ);
      if (icmp->ST_TX_ECHO_REPLY)  printf("\t\t%ld Echo Replies\n",             icmp->ST_TX_ECHO_REPLY);
      if (icmp->ST_TX_TIME_REQ)    printf("\t\t%ld Timestamp Requests\n",       icmp->ST_TX_TIME_REQ);
      if (icmp->ST_TX_TIME_REPLY)  printf("\t\t%ld Timestamp Replies\n",        icmp->ST_TX_TIME_REPLY);
      if (icmp->ST_TX_INFO_REQ)    printf("\t\t%ld Information Requests\n",     icmp->ST_TX_INFO_REQ);
      if (icmp->ST_TX_INFO_REPLY)  printf("\t\t%ld Information Replies\n",      icmp->ST_TX_INFO_REPLY);
      if (icmp->ST_TX_OTHER)       printf("\t\t%ld Unknown\n",                  icmp->ST_TX_OTHER);
      printf("-- More --"); getchar();
#endif

#if RTCSCFG_ENABLE_UDP_STATS
      printf("\nUDP:\n");
      printf("\t%ld packets received\n",                  udp->COMMON.ST_RX_TOTAL);
      printf("\t%ld discarded for lack of resources\n",   udp->COMMON.ST_RX_MISSED);
      printf("\t%ld discarded due to internal errors\n",  udp->COMMON.ST_RX_ERRORS);
      printf("\t%ld discarded for other reasons:\n",      udp->COMMON.ST_RX_DISCARDED);
      printf("\t\t%ld with header errors\n",              udp->ST_RX_BAD_PORT + udp->ST_RX_BAD_CHECKSUM + udp->ST_RX_SMALL_DGRAM + udp->ST_RX_SMALL_PKT);
      printf("\t\t%ld with unknown ports\n",              udp->ST_RX_NO_PORT);
      printf("\t%ld packets sent\n",                      udp->COMMON.ST_TX_TOTAL);
      printf("\t%ld unsent for lack of resources\n",      udp->COMMON.ST_TX_MISSED);
      printf("\t%ld unsent due to internal errors\n",     udp->COMMON.ST_TX_ERRORS);
      printf("\t%ld with illegal destination port\n",     udp->COMMON.ST_TX_DISCARDED);
      printf("-- More --"); getchar();
#endif

#if RTCSCFG_ENABLE_TCP_STATS
      printf("\nTCP:\n");
      printf("\t%ld packets received\n",                  tcp->COMMON.ST_RX_TOTAL);
      printf("\t%ld discarded for lack of resources\n",   tcp->COMMON.ST_RX_MISSED);
      printf("\t%ld discarded due to internal errors\n",  tcp->COMMON.ST_RX_ERRORS);
      printf("\t%ld discarded for other reasons:\n",      tcp->COMMON.ST_RX_DISCARDED);
      printf("\t\t%ld with header errors\n",              tcp->ST_RX_BAD_PORT + tcp->ST_RX_BAD_CHECKSUM + tcp->ST_RX_SMALL_HDR + tcp->ST_RX_SMALL_DGRAM + tcp->ST_RX_SMALL_PKT);
      printf("\t\t%ld acks for unsent data\n",            tcp->ST_RX_BAD_ACK);
      printf("\t\t%ld with data outside window\n",        tcp->ST_RX_BAD_DATA);
      printf("\t\t%ld with data after close\n",           tcp->ST_RX_LATE_DATA);
      printf("\t%ld segments with data\n",                tcp->ST_RX_DATA);
      printf("\t%ld segments with duplicate data\n",      tcp->ST_RX_DATA_DUP);
      printf("\t%ld segments with only an ACK\n",         tcp->ST_RX_ACK);
      printf("\t%ld segments with a duplicate ACK\n",     tcp->ST_RX_ACK_DUP);
      printf("\t%ld segments with a RST\n",               tcp->ST_RX_RESET);
      printf("\t%ld window probes\n",                     tcp->ST_RX_PROBE);
      printf("\t%ld window updates\n",                    tcp->ST_RX_WINDOW);
      printf("-- More --"); getchar();
      printf("\t%ld packets sent\n",                      tcp->COMMON.ST_TX_TOTAL);
      printf("\t%ld discarded for lack of resources\n",   tcp->COMMON.ST_TX_MISSED);
      printf("\t%ld discarded due to internal errors\n",  tcp->COMMON.ST_TX_ERRORS);
      printf("\t%ld with illegal destination port\n",     tcp->COMMON.ST_TX_DISCARDED);
      printf("\t%ld segments with data\n",                tcp->ST_TX_DATA);
      printf("\t%ld segments with retransmitted data\n",  tcp->ST_TX_DATA_DUP);
      printf("\t%ld segments with only an ACK\n",         tcp->ST_TX_ACK);
      printf("\t%ld segments with a delayed ACK\n",       tcp->ST_TX_ACK_DELAYED);
      printf("\t%ld segments with a RST\n",               tcp->ST_TX_RESET);
      printf("\t%ld window probes\n",                     tcp->ST_TX_PROBE);
      printf("\t%ld window updates\n",                    tcp->ST_TX_WINDOW);
      printf("\t%ld active opens\n",                      tcp->ST_CONN_ACTIVE);
      printf("\t%ld passive opens\n",                     tcp->ST_CONN_PASSIVE);
      printf("\t%ld connections currently established\n", tcp->ST_CONN_OPEN);
      printf("\t%ld connections gracefully closed\n",     tcp->ST_CONN_CLOSED);
      printf("\t%ld connections aborted\n",               tcp->ST_CONN_RESET);
      printf("\t%ld failed connection attempts\n",        tcp->ST_CONN_FAILED);
#endif
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s\n", argv[0]);
      } else  {
         printf("Usage: %s\n", argv[0]);
      }
   }
   return SHELL_EXIT_SUCCESS;
} /* Endbody */

#endif /* SHELLCFG_USES_RTCS */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_e200dec.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_e200dec.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*    This file contains definitions for the PPC e300 core decrementer
*    timer utility functions.
*
*END***********************************************************************/


#include <mqx.h>
#include <bsp.h>
#include "timer_e200dec.h"


/*ISR*********************************************************************
*
* Function Name    : _e200_decrementer_null_isr
* Returned Value   : void
* Comments         :
*    The decrementer ISR.  Needed because the decrementer WILL interrupt
*
*END**********************************************************************/

static void _e200_decrementer_null_isr(pointer dummy)
{
   _PSP_SPR_SET(E200CORE_TSR, E200CORE_TSR_DIS);

}


/*ISR*********************************************************************
*
* Function Name    : _e200_decrementer_kernel_isr
* Returned Value   : void
* Comments         :
*    The decrementer ISR.  Needed because the decrementer WILL interrupt
*
*END**********************************************************************/

static void _e200_decrementer_kernel_isr(pointer dummy)
{
   _PSP_SPR_SET(E200CORE_TSR, E200CORE_TSR_DIS);

   _time_notify_kernel();
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _e200_decrementer_get_hwticks
* Returned Value   : MQX_OK if successful or else MQX Error
* Comments         :
*
*
*END*----------------------------------------------------------------------*/

static uint_32 _e200_decrementer_get_hwticks(pointer p)
{
   uint_32 result, tsr, period = (uint_32)p;

   _PSP_SPR_GET(result,E200CORE_DEC);
   _PSP_SPR_GET(tsr,E200CORE_TSR);

   result = period - result;

   if ((tsr & E200CORE_TSR_DIS) != 0) {
      _PSP_SPR_GET(result,E200CORE_DEC);
      result = period - result;
      result += period;
   }

   return result;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _e200_decrementer_timer_init
* Returned Value   : MQX_OK if successful or else MQX Error
* Comments         :
*    Initilizes the Decrementer Timer to generate MQX BSP ticks
*
*END*----------------------------------------------------------------------*/

static uint_32 _e200_decrementer_timer_init
   (
      /* [IN] the tick rate wanted */
      uint_32 tickfreq,

      /* [IN] Input clock frequency */
      uint_32 clk
   )
{
   uint_32 period;
   uint_32 tmp;

   _PSP_SPR_SET(E200CORE_DEC, 0);

   period = (uint_32)( ((clk << 1)/tickfreq + 1) >> 1 );

   _PSP_SPR_GET(tmp, E200CORE_TCR);
   tmp |= E200CORE_TCR_DIE | E200CORE_TCR_ARE; /* interrupt + Auto-reload enable */
   _PSP_SPR_SET(E200CORE_TCR, tmp);

   /* preload value is one less than period */
   _PSP_SPR_SET(E200CORE_DEC, period-1);
   _PSP_SPR_SET(E200CORE_DECAR, period-1);     /* decrementer auto-reload */

   /* enable clocks for TimeBase - this applies also to decrementer */
   _PSP_SPR_GET(tmp, E200CORE_HID0);
   tmp |= E200CORE_HID0_TBEN;
   _PSP_SPR_SET(E200CORE_HID0, tmp);

   return period;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _e200_decrementer_timer_install
* Returned Value   : MQX_OK if successful or else MQX Error
* Comments         :
*    Initilizes the Decrementer Timer to generate MQX BSP ticks
*
*END*----------------------------------------------------------------------*/

uint_32 _e200_decrementer_timer_install
   (
      /* [IN] the tick rate wanted */
      uint_32 tickfreq,

      /* [IN] Input clock frequency */
      uint_32 clk
   )
{
    uint_32 period;

    /* Set up tick timer */
    period = _e200_decrementer_timer_init(tickfreq, clk);
    if (period == 0) {
        return MQX_TIMER_ISR_INSTALL_FAIL;
    }

    /* Install the decrementer interrupt handler */
    if (_int_install_isr(PSP_EXCPT_DECREMENTER, _e200_decrementer_kernel_isr, NULL) == NULL)
    {
        return _task_get_error();
    }

    /* Initialize the timer interrupt */
    _time_set_timer_vector(PSP_EXCPT_DECREMENTER);
    _time_set_hwtick_function(_e200_decrementer_get_hwticks, (pointer)period);
    _time_set_hwticks_per_tick(period);
    _time_set_ticks_per_sec(tickfreq);

    return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _e200_decrementer_null_install
* Returned Value   : MQX_OK if successful or else MQX Error
* Comments         :
*
*
*END*----------------------------------------------------------------------*/

uint_32 _e200_decrementer_null_install(void)
{
   /* Install the decrementer interrupt handler */
   if (_int_install_isr(PSP_EXCPT_DECREMENTER,_e200_decrementer_null_isr, NULL) == NULL)
   {
      return _task_get_error();
   }

   return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio_siul.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio_siul.h$
* $Version : 3.8.7.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/
#ifndef __lwgpio_siul_h__
#define __lwgpio_siul_h__ 1


#define SIUL_PCR_SMC_MASK ((uint_16)(1<<14))
#define SIUL_PCR_APC_MASK ((uint_16)(1<<13))
#define SIUL_PCR_PA_SHIFT 10
#define SIUL_PCR_PA_MASK  ((uint_16)(3<<SIUL_PCR_PA_SHIFT))
#define SIUL_PCR_OBE_MASK ((uint_16)(1<<9))
#define SIUL_PCR_IBE_MASK ((uint_16)(1<<8))
#define SIUL_PCR_DIR_MASK (SIUL_PCR_IBE_MASK | SIUL_PCR_OBE_MASK)
#define SIUL_PCR_ODE_MASK ((uint_16)(1<<5))
#define SIUL_PCR_SRC_MASK ((uint_16)(7<<2))
#define SIUL_PCR_WPE_MASK ((uint_16)(1<<1))
#define SIUL_PCR_WPS_MASK ((uint_16)(1<<0))


/* register access structure */
typedef struct siul_reg_struct {
    uint_32 padding_0;

    uint_32 MIDR1;
    uint_32 MIDR2;

    uint_32 reserved_0C;
    uint_32 reserved_10;

    uint_32 ISR;
    uint_32 IRER;

    uint_32 reserved_1C;
    uint_32 reserved_20;
    uint_32 reserved_24;

    uint_32 IREER;
    uint_32 IFEER;
    uint_32 IFER;

    uint_32 reserved_34;
    uint_32 reserved_38;
    uint_32 reserved_3C;

    /*
    arrays fill whole available space,
    including reserved area following acually implemented registers
    (possible expansion)
    */

    /* access to individual pins */
    uint_16 PCR[608];   
    uint_8  PSMI[256];
    uint_8  GPDO[512];
    uint_8  GPDI[1024];

    /* parallel access */
    uint_32 PGPDO[16];
    uint_32 PGPDI[16];
    uint_32 MPGPDO[224];

    /* interrupt filtering */
    uint_32 IFMC[32];
    uint_32 IFCP;

} SIUL_REG_STRUCT, * SIUL_REG_STRUCT_PTR;

typedef volatile struct siul_reg_struct * VSIUL_REG_STRUCT_PTR;


typedef struct {
    VSIUL_REG_STRUCT_PTR siul_ptr; /* pointer to peripheral registers */
    uint_32 id; /* pin ID */
    int_8 eirq; /* EIRQ assigned to this pin */
} LWGPIO_STRUCT, _PTR_ LWGPIO_STRUCT_PTR;

/* Pin attributes */
#define LWGPIO_ATTR_BASE            (0x100)
#define LWGPIO_ATTR_SLEW_RATE       (LWGPIO_ATTR_BASE+1)

/*attributes value*/
#define LWGPIO_AVAL_SLEW_RATE_FAST      (1)
#define LWGPIO_AVAL_SLEW_RATE_SLOW      (0)

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

pointer _bsp_get_gpio_base_address(void);
boolean _bsp_lwgpio_enable_access(uint_32 device);

int _bsp_siul_pin_to_eirq(uint_32 id);
int _bsp_siul_int_get_vector(uint_32 eirq);

#ifdef __cplusplus
}
#endif

#endif //__lwgpio_siul_h__


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_dirent.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_dirent.c$
* $Version : 3.8.12.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <shell.h>
#include <ctype.h>
#include <mfs.h>
#include <sh_mfs.h>

#define SECTOR_SIZE MFS_DEFAULT_SECTOR_SIZE
#define DIRENTS_PER_SECTOR (SECTOR_SIZE/sizeof(MFS_DIR_ENTRY))

static boolean is_zero(uchar_ptr buffer, uint_32 size) 
{
   uint_32 i;

   for (i=0;i<size;i++) {
      if (buffer[i]) {
         return FALSE;
      }
   }
   return TRUE;
}
   


static void print_dirent(MFS_DIR_ENTRY_PTR dirent)
{
   boolean     skip;
   uint_32     i;
   uchar_ptr   lfn = (uchar_ptr) dirent;
   
   skip = FALSE;

   if (dirent->ATTRIBUTE[0] == MFS_ATTR_LFN) {
      
      printf("\nLFN: %02d%c ",dirent->NAME[0]&0x3f, (dirent->NAME[0]&0x40)?'*':'+');
      for (i=0;i<5;i++) {
         printf("%c",lfn[i*2+1]!=0xff?lfn[i*2+1]:' ');
      }
      for (i=0;i<6;i++) {
         printf("%c",lfn[i*2+15]!=0xff?lfn[i*2+14]:' ');
      }
      for (i=0;i<2;i++) {
         printf("%c",lfn[i*2+29]!=0xff?lfn[i*2+28]:' ');
      }
   } else {
      printf("\nSFN: ");
      if (dirent->NAME[0] == 0) {
         printf(" Unused             ");
      } else if ((uchar)dirent->NAME[0] == 0xe5) {
         printf("Deleted             ");
      } else {
         for (i=0;i<8;i++) {
            printf("%c",(isgraph(dirent->NAME[i])?dirent->NAME[i]:' '));
         }
         printf(".");
         for (i=0;i<3;i++) {
            printf("%c",(dirent->TYPE[i]?dirent->TYPE[i]:' '));
         }

         printf(" %c%c%c%c%c%c ",
            (dirent->ATTRIBUTE[0] & MFS_ATTR_READ_ONLY)?'R':' ',
            (dirent->ATTRIBUTE[0] & MFS_ATTR_HIDDEN_FILE)?'H':' ',
            (dirent->ATTRIBUTE[0] & MFS_ATTR_SYSTEM_FILE)?'S':' ',
            (dirent->ATTRIBUTE[0] & MFS_ATTR_VOLUME_NAME)?'V':' ',
            (dirent->ATTRIBUTE[0] & MFS_ATTR_DIR_NAME)?'D':' ',
            (dirent->ATTRIBUTE[0] & MFS_ATTR_ARCHIVE)?'A':' ');
         printf("FClust %02x%02x%02x%02x",dirent->HFIRST_CLUSTER[1] ,dirent->HFIRST_CLUSTER[0],
            dirent->LFIRST_CLUSTER[1] ,dirent->LFIRST_CLUSTER[0] );
         printf(", Size %02x%02x%02x%02x",dirent->FILE_SIZE[3] ,dirent->FILE_SIZE[2], dirent->FILE_SIZE[1] ,dirent->FILE_SIZE[0] );
         skip = TRUE;
      }
   }

   if (!skip) {
      for (i=0;i<sizeof(MFS_DIR_ENTRY);i++) {
         printf("%02x ",(uint_32) lfn[i]);
      }
   }
}



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_dirent
* Returned Value   :  int_32 error code
* Comments  :  Reads from a file .
*
*END*---------------------------------------------------------------------*/

int_32  Shell_dirent(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   uint_32           sector,num_sectors;
   int_32            offset;
   MQX_FILE_PTR      fd, fs;
   uint_32           e;
   uchar_ptr         buffer;
   MFS_DIR_ENTRY_PTR dirents;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if ((argc < 2) || (argc > 4)) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else if ( !Shell_parse_uint_32(argv[1], (uint_32_ptr) &offset ))  {
         printf("Error, invalid length\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else {
         num_sectors = 1;
         
         if (argc >= 3) {
            if ( !Shell_parse_uint_32(argv[2], (uint_32_ptr) &num_sectors )) {
               num_sectors = 1;
            }
         }      
         if (argc == 4) {
            fd = fopen(argv[3], "r");
            if (!fd) { 
               printf("Error, unable to open file %s.\n", argv[1] );
               return_code = SHELL_EXIT_ERROR;
            }
         } else {
            fs = Shell_get_current_filesystem(argv);
            _io_ioctl(fs, IO_IOCTL_GET_DEVICE_HANDLE, &fd);
         }

         if (fd)  {
            buffer = _mem_alloc(SECTOR_SIZE);
            if (buffer) {
               for(sector=0;sector<num_sectors;sector++) {
                  if (fseek(fd, offset+sector, IO_SEEK_SET) == IO_ERROR)  {
                     printf("Error, unable to seek to sector %s.\n", argv[1] );
                     return_code = SHELL_EXIT_ERROR;
                  } else  if (_io_read(fd, (char_ptr) buffer, 1) !=1) {
                     printf("Error, unable to read sector %s.\n", argv[1] );
                     return_code = SHELL_EXIT_ERROR;
                  } else if (!is_zero(buffer, SECTOR_SIZE)) {
                     printf("\nEntry # %d",offset+sector);
                     dirents = (MFS_DIR_ENTRY_PTR) buffer;

                     for (e=0;e<DIRENTS_PER_SECTOR;e++)  {
                        print_dirent(&dirents[e]);
                     }
                     printf("\n");
                  }
               }
               _mem_free(buffer);
            } else {
               printf("Error, unable to allocate sector buffer.\n" );
               return_code = SHELL_EXIT_ERROR;
            }
            if (argc >= 4) {
               fclose(fd);
            }
         }
      }
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <sector> [<device>]\n", argv[0]);
      } else  {
         printf("Usage: %s <sector> [<device>]\n", argv[0]);
         printf("   <sector>     = sector number\n");
         printf("   <device>     = low level device\n");
      }
   }
   return return_code;
} /* Endbody */

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_write.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_write.c$
* $Version : 3.8.13.0$
* $Date    : Jun-27-2012$
*
* Comments:
*
*   This file contains the file specific interface functions
*   of the MFS.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"



#if !MFSCFG_READ_ONLY

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Write
* Returned Value   : number of bytes writen
* Comments  :   Write a specific number of bytes to an open file.
*
*END*---------------------------------------------------------------------*/

uint_32  MFS_Write
    (
    MQX_FILE_PTR            fd_ptr,         /*[IN] handle to the open file */
    uint_32                 num_bytes,      /*[IN] number of bytes to be written */
    char_ptr                buffer_address, /*[IN/OUT] bytes are written from this buffer */
    _mfs_error_ptr          error_ptr       /*[IN/OUT] error code is written to this address */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_HANDLE_PTR          handle_ptr;
    uint_32                 bytes_written;
    uint_32                 copy_size;
    uint_32                 cluster_offset;
    uint_32                 sector_number, sector_index;
    uint_32                 sector_offset;
    uint_32                 whole_sectors;
    uint_32                 cont_sectors;
    uint_32                 proc_sectors;
    _mfs_error              error, temp_error;
    uint_32                 file_size;
    uint_32                 next_cluster;
    boolean                 need_hwread;
    uint_32                 location;
    uint_32                 num_zeros;
    uint_32                 zeros_written;
    uint_32                 zero_size;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (fd_ptr, NULL))
    {
        MFS_set_error_and_return(error_ptr,MFS_DISK_IS_WRITE_PROTECTED,0);
    }
#endif

    if ( buffer_address == NULL )
    {
        MFS_set_error_and_return(error_ptr,MFS_INVALID_PARAMETER,0);
    }

    if ( num_bytes == 0 )
    {
        MFS_set_error_and_return(error_ptr,MFS_NO_ERROR,0);
    }

    error = MFS_lock_handle( fd_ptr, &drive_ptr, &handle_ptr );
    if ( error != MFS_NO_ERROR )
    {
        MFS_set_error_and_return(error_ptr,error,0);
    }

    if ( handle_ptr->ACCESS == MFS_ACCESS_READ_ONLY )
    {
        MFS_unlock(drive_ptr,FALSE);
        MFS_set_error_and_return(error_ptr,MFS_ACCESS_DENIED,0);
    }

    /*
    ** Setup the current cluster. If this is the first time writing to the file, a cluster needs to be added.
    */
    if ( handle_ptr->CURRENT_CLUSTER == 0 )
    {
        handle_ptr->PREVIOUS_CLUSTER = 0;
        handle_ptr->CURRENT_CLUSTER = clustoh(handle_ptr->DIR_ENTRY.HFIRST_CLUSTER, handle_ptr->DIR_ENTRY.LFIRST_CLUSTER);
        if ( handle_ptr->CURRENT_CLUSTER==0 )
        {
            next_cluster = MFS_Find_unused_cluster_from(drive_ptr,drive_ptr->NEXT_FREE_CLUSTER);
            if ( next_cluster != CLUSTER_INVALID )
            {
                clustod(handle_ptr->DIR_ENTRY.HFIRST_CLUSTER, handle_ptr->DIR_ENTRY.LFIRST_CLUSTER, next_cluster);
                handle_ptr->TOUCHED = 1;

                error = MFS_Put_fat(drive_ptr, next_cluster, CLUSTER_EOF);
                if ( error == MFS_NO_ERROR )
                {
                    handle_ptr->CURRENT_CLUSTER = next_cluster;
                }
                else
                {
                    MFS_unlock(drive_ptr,FALSE);
                    MFS_set_error_and_return(error_ptr,error,0);
                }
            }
            else
            {
                MFS_unlock(drive_ptr,FALSE);
                MFS_set_error_and_return(error_ptr,MFS_DISK_FULL,0);
            }
        }
    }
    else if ( handle_ptr->CURRENT_CLUSTER == CLUSTER_EOF )
    {
        error = MFS_Add_cluster_to_chain(drive_ptr, handle_ptr->PREVIOUS_CLUSTER, &handle_ptr->CURRENT_CLUSTER);
        if ( MFS_NO_ERROR != error )
        {
            MFS_unlock(drive_ptr,FALSE);
            MFS_set_error_and_return(error_ptr,error,0);
        }
    }
    else if ( handle_ptr->CURRENT_CLUSTER > drive_ptr->LAST_CLUSTER )
    {
        MFS_unlock(drive_ptr,FALSE);
        MFS_set_error_and_return(error_ptr,MFS_DISK_FULL,0);
    }

    /* Make sure location (local variable) never points behind the end of file */
    file_size = dtohl(handle_ptr->DIR_ENTRY.FILE_SIZE);
    location = (fd_ptr->LOCATION > file_size) ? file_size : fd_ptr->LOCATION;

    /* Calculate sector number and offsets within cluster and sector */
    cluster_offset = OFFSET_WITHIN_CLUSTER(location);
    sector_index = CLUSTER_OFFSET_TO_SECTOR(cluster_offset);
    sector_number = CLUSTER_TO_SECTOR(handle_ptr->CURRENT_CLUSTER) + sector_index;
    sector_offset = OFFSET_WITHIN_SECTOR(location);

    /* Calculate possible gap to fill in by zeros if writing behind the end of file */
    num_zeros = fd_ptr->LOCATION - location;

    zeros_written = 0;
    bytes_written = 0;

    /* Write zeros to fill in gap if LOCATION points behind the end of file */
    while (zeros_written < num_zeros)
    {
        /* If offset is non-zero, then reading the data is required */
        error = MFS_Read_data_sector(drive_ptr, handle_ptr, sector_number, sector_offset != 0);
        if ( error != MFS_NO_ERROR )
            break;

        /* Zero the buffer  */
        zero_size = min(num_zeros-zeros_written, drive_ptr->BPB.SECTOR_SIZE-sector_offset);
        _mem_zero(&drive_ptr->DATA_SECTOR_PTR[sector_offset], zero_size);
        drive_ptr->DATA_SECTOR_DIRTY = TRUE;

        if ( drive_ptr->WRITE_CACHE_POLICY == MFS_WRITE_THROUGH_CACHE )
        {
            error = MFS_Flush_data_sector_buffer(drive_ptr);
            if ( error != MFS_NO_ERROR )
                break;
        }

        zeros_written += zero_size;
        sector_offset += zero_size;

        /*
        ** Check to see if we need to advance to the next sector, which has
        ** the side effect of increasing the cluster number if required.
        */
        if ( sector_offset >= drive_ptr->BPB.SECTOR_SIZE )
        {
            temp_error = MFS_next_data_sector(drive_ptr, handle_ptr, &sector_index, &sector_number);
            if (temp_error == MFS_EOF)
            {
                /* Always allocate new cluster, there is something to be written for sure */
                error = MFS_Add_cluster_to_chain(drive_ptr, handle_ptr->PREVIOUS_CLUSTER, &handle_ptr->CURRENT_CLUSTER);
                if ( MFS_NO_ERROR == error )
                {
                    sector_number = CLUSTER_TO_SECTOR(handle_ptr->CURRENT_CLUSTER);
                    sector_index = 0;
                }

            }
            else
            {
                error = temp_error;
            }
            sector_offset = 0;
        }
    }

    /* Write partial sector if sector_offset is non-zero */
    if ( (sector_offset != 0) && (error == MFS_NO_ERROR) )
    {
        /* Offset is non-zero, reading the data is required */
        error = MFS_Read_data_sector(drive_ptr, handle_ptr, sector_number, TRUE);

        if ( error == MFS_NO_ERROR )
        {
            /* The requested lenght of data may span the sector to it's end  */
            copy_size = min(num_bytes, drive_ptr->BPB.SECTOR_SIZE-sector_offset);

            _mem_copy(buffer_address, &drive_ptr->DATA_SECTOR_PTR[sector_offset], copy_size);
            drive_ptr->DATA_SECTOR_DIRTY = TRUE;

            if ( drive_ptr->WRITE_CACHE_POLICY == MFS_WRITE_THROUGH_CACHE )
            {
                error = MFS_Flush_data_sector_buffer(drive_ptr);
            }

            if ( error == MFS_NO_ERROR )
            {
                bytes_written = copy_size;

                /*
                ** Check to see if we need to advance to the next sector, which has
                ** the side effect of increasing the cluster number if required.
                */
                if ( (sector_offset + bytes_written) >= drive_ptr->BPB.SECTOR_SIZE )
                {
                    temp_error = MFS_next_data_sector(drive_ptr, handle_ptr, &sector_index, &sector_number);
                    /* Only an error if we are not done writing and can't extend the chain */
                    if (bytes_written < num_bytes)
                    {
                        if (temp_error == MFS_EOF)
                        {
                            /* Allocate new cluster */
                            error = MFS_Add_cluster_to_chain(drive_ptr, handle_ptr->PREVIOUS_CLUSTER, &handle_ptr->CURRENT_CLUSTER);
                            if ( MFS_NO_ERROR == error )
                            {
                                sector_number = CLUSTER_TO_SECTOR(handle_ptr->CURRENT_CLUSTER);
                                sector_index = 0;
                            }
                        }
                        else
                        {
                            error = temp_error;
                        }
                    }
                }
            }
        }
    }

    whole_sectors = (num_bytes - bytes_written) >> drive_ptr->SECTOR_POWER;
    while ( (whole_sectors > 0) && (error == MFS_NO_ERROR) )
    {
        cont_sectors = drive_ptr->BPB.SECTORS_PER_CLUSTER - sector_index;
        if (cont_sectors > whole_sectors)
            cont_sectors = whole_sectors;

        error = MFS_Write_device_sectors(drive_ptr, sector_number, cont_sectors, MFSCFG_MAX_WRITE_RETRIES, buffer_address+bytes_written, &proc_sectors);

        if ( proc_sectors > 0 )
        {
            bytes_written += proc_sectors * drive_ptr->BPB.SECTOR_SIZE;
            whole_sectors -= proc_sectors;
            sector_index += proc_sectors - 1;
            temp_error = MFS_next_data_sector(drive_ptr, handle_ptr, &sector_index, &sector_number);
            /* Go on only if we are not done writing */
            if ( (error == MFS_NO_ERROR) && (bytes_written < num_bytes) )
            {
                if ( temp_error == MFS_EOF )
                {
                    /* Allocate new cluster */
                    error = MFS_Add_cluster_to_chain(drive_ptr, handle_ptr->PREVIOUS_CLUSTER, &handle_ptr->CURRENT_CLUSTER);
                    if ( MFS_NO_ERROR == error )
                    {
                        sector_number = CLUSTER_TO_SECTOR(handle_ptr->CURRENT_CLUSTER);
                        sector_index = 0;
                    }
                }
                else
                {
                    error = temp_error;
                }
            }
        }
    }

    /* write last missing data */
    if ( (bytes_written < num_bytes) && (error == MFS_NO_ERROR) )
    {
        /* reading of data required only if we are not going to overwrite the file to the end */
        need_hwread = (fd_ptr->LOCATION + num_bytes) < file_size;
        error = MFS_Read_data_sector(drive_ptr, handle_ptr, sector_number, need_hwread);

        if ( error == MFS_NO_ERROR )
        {
            _mem_copy(buffer_address+bytes_written, &drive_ptr->DATA_SECTOR_PTR[0], num_bytes-bytes_written);
            bytes_written = num_bytes;
            drive_ptr->DATA_SECTOR_DIRTY = TRUE;
            if ( drive_ptr->WRITE_CACHE_POLICY == MFS_WRITE_THROUGH_CACHE )
            {
                error = MFS_Flush_data_sector_buffer(drive_ptr);
            }
        }
    }

    if ( zeros_written || bytes_written )
    {
        handle_ptr->TOUCHED = 1;
    }

    location += zeros_written + bytes_written;
    ((MFS_HANDLE_PTR)fd_ptr->DEV_DATA_PTR)->SAVED_POSITION = location;

    if ( location > file_size )
    {
        fd_ptr->SIZE = location;
        htodl(handle_ptr->DIR_ENTRY.FILE_SIZE, fd_ptr->SIZE);
        if ( (drive_ptr->WRITE_CACHE_POLICY == MFS_WRITE_THROUGH_CACHE) && (error == MFS_NO_ERROR) )
        {
            error = MFS_Update_entry(drive_ptr, handle_ptr);
        }
    }

    /* LOCATION moves forward only by actual data written, the zero fill does not count */
    fd_ptr->LOCATION += bytes_written;

    temp_error = MFS_unlock(drive_ptr, FALSE);
    if (error == MFS_NO_ERROR)
        error = temp_error;

    MFS_set_error_and_return(error_ptr, error, bytes_written);
}

#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/debug/iodebug.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: debug.c$
* $Version : 3.8.3.0$
* $Date    : Sep-16-2011$
*
* Comments:
*
*   This file contains the debug driver functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "iodebug.h"
#include "io_prv.h"
#include "iodebug_prv.h"




/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name     : _io_debug_install
* Returned Value    : _mqx_uint a task error code or MQX_OK
* Comments          :
*    Install a debug driver.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_debug_install 
    ( 
        /* [IN] A string that identifies the device for fopen */ 
        char_ptr                    identifier, 

        /* [IN] pointer to init structure */ 
        IODEBUG_INIT_STRUCT_CPTR    init_ptr 
    ) 
{ /* Body */
    _mqx_int                        result = IO_OK; 
    IO_DEBUG_DEVICE_STRUCT_PTR      dev_ptr;
    
    dev_ptr = _mem_alloc_system_zero((_mem_size)sizeof(IO_DEBUG_DEVICE_STRUCT));
    
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if(dev_ptr == NULL) {
        return(MQX_OUT_OF_MEMORY); 
    } /* Endif */
#endif

    dev_ptr->BUFFER_PTR = NULL;
    dev_ptr->BUFFER_POS = 0;
    dev_ptr->COUNT = 0;
    dev_ptr->DEV_INIT_DATA_PTR = (IODEBUG_INIT_STRUCT_PTR)init_ptr;
    dev_ptr->FLUSH_CHAR = init_ptr->FLUSH_CHAR; 
    _lwsem_create(&dev_ptr->LWSEM, 1);
    result = _io_dev_install_ext(identifier,
        _io_debug_open,
        _io_debug_close,
        _io_debug_read,
        _io_debug_write,
        _io_debug_ioctl,
        _io_debug_uninstall,
        dev_ptr); 
    
    return result; 
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_uninstall
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Uninstall a debug driver.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_debug_uninstall 
    ( 
        /* [IN] The devices context */
        IO_DEVICE_STRUCT_PTR  io_dev_ptr
    )
{ /* Body */
    IO_DEBUG_DEVICE_STRUCT_PTR      dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;
    
    if(dev_ptr->COUNT == 0) { 
        if(dev_ptr->BUFFER_PTR != NULL) { 
            _mem_free(dev_ptr->BUFFER_PTR); 
        } /* Endif */
        _lwsem_destroy(&dev_ptr->LWSEM);
        _mem_free(dev_ptr);
        return(IO_OK); 
    } else { 
        return(IO_ERROR_DEVICE_BUSY); 
    } /* Endif */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_open
* Returned Value   : error code
* Comments         : 
*    Opens and initializes driver.
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_debug_open
    (
        /* [IN] the file handle for the device being opened */
        MQX_FILE_PTR    fd_ptr,
        
        /* [IN] the remaining portion of the name of the device */
        char_ptr        open_name_ptr,
        
        /* [IN] the flags to be used during operation: */
        char_ptr        flags
    )
{ /* Body */
    _mqx_uint                       result = MQX_OK; 
    IO_DEBUG_DEVICE_STRUCT_PTR      dev_ptr = fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IODEBUG_INIT_STRUCT_PTR         init_ptr = dev_ptr->DEV_INIT_DATA_PTR;
    
    _lwsem_wait(&dev_ptr->LWSEM);
    /* 
    ** First file open && buffer required 
    */  
    if(dev_ptr->COUNT == 0 && init_ptr->MODE == IODEBUG_MODE_SEMIHOST  && 
        init_ptr->DATA_LENGTH) {
        dev_ptr->BUFFER_PTR = _mem_alloc_system_zero( 
            (_mem_size)(sizeof(char) * (init_ptr->DATA_LENGTH + 1)) 
        ); 
        #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS 
        if(dev_ptr->BUFFER_PTR == NULL) { 
            return(MQX_OUT_OF_MEMORY); 
        } /* Endif */
        #endif 
        dev_ptr->COUNT = 1;
    }
    else {
        dev_ptr->COUNT++;
    } /* Endif */
    _lwsem_post(&dev_ptr->LWSEM);
    
    return result; 
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_close
* Returned Value   : error code
* Comments         : 
*    Closes debug driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_debug_close
    (
        /* [IN] the file handle for the device being closed */
        MQX_FILE_PTR    fd_ptr
    )
{ /* Body */
    IO_DEBUG_DEVICE_STRUCT_PTR      dev_ptr = fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IODEBUG_INIT_STRUCT_PTR         init_ptr = dev_ptr->DEV_INIT_DATA_PTR;
    
    _lwsem_wait(&dev_ptr->LWSEM);
    if(dev_ptr->COUNT == 1 && dev_ptr->BUFFER_PTR != NULL) { 
        _io_debug_buffer_flush(dev_ptr);
        _mem_free(dev_ptr->BUFFER_PTR); 
        dev_ptr->BUFFER_PTR = NULL; 
    } /* Endif */
    dev_ptr->COUNT--; 
    _lwsem_post(&dev_ptr->LWSEM);
    
    return(MQX_OK);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_read
* Returned Value   : number of characters read
* Comments         : 
*    Reads data from debug device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_debug_read
(
    /* [IN] the file handle for the device */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] where the characters are to be stored */
    char_ptr        data_ptr,

    /* [IN] the number of characters to input */
    _mqx_int        num
)
{ /* Body */
    IO_DEBUG_DEVICE_STRUCT_PTR      dev_ptr = fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IODEBUG_INIT_STRUCT_PTR         init_ptr = dev_ptr->DEV_INIT_DATA_PTR;
    uint_32                         i = 0;
    
    _lwsem_wait(&dev_ptr->LWSEM);
    /* File not open */
    if(dev_ptr->COUNT <= 0) {
        return IO_ERROR; 
    } /* Endif */
    
    switch(init_ptr->MODE){
        case IODEBUG_MODE_SEMIHOST :
            for(i = 0; i < num; i++) {
                data_ptr[i] = _io_debug_semi_read_char();
            } /* Endfor */
            break;
        default:
            num = IO_ERROR;
            break;
    }/* Endswitch */
    _lwsem_post(&dev_ptr->LWSEM);
    
    return(num);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_write
* Returned Value   : number of characters written
* Comments         : \
*    Writes data to the debug device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_debug_write
(
    /* [IN] the file handle for the device */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] where the characters are */
    char_ptr        data_ptr,

    /* [IN] the number of characters to output */
    _mqx_int        num
)
{ /* Body */
    IO_DEBUG_DEVICE_STRUCT_PTR      dev_ptr = fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IODEBUG_INIT_STRUCT_PTR         init_ptr = dev_ptr->DEV_INIT_DATA_PTR;
    int_32                          i = 0; 
    int_32                          num_success = num; 
    
    _lwsem_wait(&dev_ptr->LWSEM);
    /* File not open */
    if(dev_ptr->COUNT <= 0) {
        return IO_ERROR; 
    } /* Endif */
    
    switch(init_ptr->MODE) {
        case IODEBUG_MODE_ITM:
            for(i = 0; i < num; i++) { 
                if(_io_debug_itm_write_char(&data_ptr[i]) == FALSE) {
                    num_success--;
                } /* Endif */
            } /* Endfor */
            break;
        case IODEBUG_MODE_SEMIHOST :
            if(init_ptr->DATA_LENGTH) {
                for(i = 0; i < num; i++) { 
                    _io_debug_semi_buffer_write(dev_ptr, &data_ptr[i]);
                } /* Endfor */
            } else {
                for(i = 0; i < num; i++) { 
                    _io_debug_semi_write_char(&data_ptr[i]);
                } /* Endfor */
            } /* Endif */
            break;
        default:
            num_success = IO_ERROR;
            break;
    } /* Endswitch */
    _lwsem_post(&dev_ptr->LWSEM);
    
    return(num_success); 
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_debug_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_debug_ioctl
(
    /* [IN] the file handle for the device */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] the ioctl command */
    _mqx_uint       cmd,

    /* [IN] the ioctl parameters */
    pointer         param_ptr
)
{ /* Body */
    IO_DEBUG_DEVICE_STRUCT_PTR      dev_ptr = fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IODEBUG_INIT_STRUCT_PTR         init_ptr = dev_ptr->DEV_INIT_DATA_PTR;
    _mqx_int                        result = MQX_OK;
    
    _lwsem_wait(&dev_ptr->LWSEM);
    switch(cmd) { 
    case IO_IOCTL_FLUSH_OUTPUT: 
        _io_debug_buffer_flush(dev_ptr);
        break; 
    case IO_IOCTL_IODEBUG_SET_FLUSH_CHAR:
        dev_ptr->FLUSH_CHAR = (*(char*)param_ptr);
        break;
    default: 
        result = IO_ERROR_INVALID_IOCTL_CMD; 
    } /* Endswitch */
    _lwsem_post(&dev_ptr->LWSEM);
    
    return result; 
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_buffer_flush
* Returned Value   : none
* Comments         : 
*    Write character to buffer.
* 
*END*----------------------------------------------------------------------*/

void _io_debug_buffer_flush
    (
        /* [IN] the file handle for the device */
        IO_DEBUG_DEVICE_STRUCT_PTR  dev_ptr
    )
{
    IODEBUG_INIT_STRUCT_PTR     init_ptr = dev_ptr->DEV_INIT_DATA_PTR;
    
    if(dev_ptr->COUNT && init_ptr->MODE == IODEBUG_MODE_SEMIHOST  && 
        init_ptr->DATA_LENGTH) {
        _io_debug_semi_buffer_flush(dev_ptr);
    } /* Endif */
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_semi_buffer_flush
* Returned Value   : none
* Comments         : 
*    Flushs semihost buffer. In current position writes '\0', 
*    call _io_debug_semi_write_string and resets buffer position.
* 
*END*----------------------------------------------------------------------*/

void _io_debug_semi_buffer_flush
    (
        /* [IN] the file handle for the device */
        IO_DEBUG_DEVICE_STRUCT_PTR  dev_ptr
    )
{
    /* IAR will crash down message is "\0" */
    if (dev_ptr->BUFFER_POS) {
        dev_ptr->BUFFER_PTR[dev_ptr->BUFFER_POS] = '\0';
        _io_debug_semi_write_string(dev_ptr->BUFFER_PTR);
        dev_ptr->BUFFER_POS = 0;
    }
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_semi_buffer_write
* Returned Value   : none
* Comments         : 
*    Write character to buffer.
* 
*END*----------------------------------------------------------------------*/

void _io_debug_semi_buffer_write
    (
        /* [IN] the file handle for the device */
        IO_DEBUG_DEVICE_STRUCT_PTR  dev_ptr,

        /* [IN] character to write */
        char_ptr                     character_ptr
    )
{
    IODEBUG_INIT_STRUCT_PTR     init_ptr = dev_ptr->DEV_INIT_DATA_PTR;
    
    dev_ptr->BUFFER_PTR[dev_ptr->BUFFER_POS] = *character_ptr;
    dev_ptr->BUFFER_POS++;
    if((init_ptr->DATA_LENGTH <= dev_ptr->BUFFER_POS) || ( 
        dev_ptr->BUFFER_PTR[dev_ptr->BUFFER_POS - 1] == dev_ptr->FLUSH_CHAR && 
        dev_ptr->FLUSH_CHAR != IODEBUG_NOFLUSH_CHAR 
    )){
        _io_debug_semi_buffer_flush(dev_ptr);
    } /* Endif */
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_debug_itm_write_char
* Returned Value   : returns TRUE on success else FALSE
* Comments         : 
*    Sends character to ITM channel 0.
* 
*END*----------------------------------------------------------------------*/

boolean _io_debug_itm_write_char
    (
        /* [IN] character to write */
        char_ptr                    character_ptr
    )
{
    if(
        (DEMCR & (1 << 24)) &&          /* TRCENA reg on - trace system enable*/
        (ITM_BASE_PTR->TER & 0x1)       /* TER channel 0 - channel 0 enable */
    ) {
        while(!ITM_BASE_PTR->STIM_WRITE[0]) {
            _ASM_NOP();
        }
        ITM_BASE_PTR->STIM_WRITE[0] = *character_ptr;
        return TRUE;
    }
    return FALSE;
}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/host_snd.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_snd.c$
* $Version : 3.8.14.0$
* $Date    : Sep-6-2012$
*
* Comments:
*
*   This file contains the USB Host API specific functions to send data.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_main.h"
#include "host_snd.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_get_frame_number
*  Returned Value : frame number
*  Comments       :
* This function can be used to inquire the current frame number.
*
*END*-----------------------------------------------------------------*/
uint_32 _usb_host_get_frame_number
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle  handle
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr;
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_get_frame_number");
   #endif

      /* Call the low-level send routine */      
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_get_frame_number OS mode SUCCESSFUL");
   #endif
  
    return((USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR)->HOST_GET_FRAME_NUM(handle);
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_get_micro_frame_number
*  Returned Value : frame number
*  Comments       :
* This function can be used to inquire the current micro frame number.
*
*END*-----------------------------------------------------------------*/
uint_32 _usb_host_get_micro_frame_number
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle  handle
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr;
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_get_micro_frame_number");
   #endif

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_get_micro_frame_number OS mode SUCCESSFUL");
   #endif

      /* Call the low-level send routine */      
    return((USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR)->HOST_GET_MICRO_FRAME_NUM(handle);
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_send_data
*  Returned Value : error or status of the transfer
*  Comments       :
* The Send Data routine is non-blocking routine that causes a block of data 
* to be made available for transmission to the USB host.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_send_data
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle           handle, 

      /* [IN] the pipe handle */
      _usb_pipe_handle           pipe_handle,

      /* [IN] transfer parameters */
      TR_INIT_PARAM_STRUCT_PTR   tr_params_ptr
   )
{ /* Body */
   PIPE_STRUCT_PTR            pipe_ptr;
   TR_STRUCT_PTR              tr_ptr;
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
   uint_32  return_code;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_send_data");
   #endif

   USB_lock();
   return_code = _usb_host_set_up_tr(pipe_handle, tr_params_ptr, &tr_ptr);
   if (return_code != USB_STATUS_TRANSFER_QUEUED) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_send_data failed to queue transfer");
      #endif

      return USB_log_error(__FILE__,__LINE__,return_code);
   } /* Endif */
      
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   pipe_ptr = (PIPE_STRUCT_PTR)pipe_handle;

#if PSP_HAS_DATA_CACHE      // TODO check - maybe uncached allocation used/can be used
  /*Must Flush and Invalidate the buffer before sending
   /receiving the data in it */
   USB_dcache_flush_mlines((void *)tr_ptr->TX_BUFFER, tr_ptr->TX_LENGTH);
#endif // PSP_HAS_DATA_CACHE

   /* We have obtained the current TR on the Pipe's TR list 
   ** from _usb_host_set_up_tr
   */

   /* Call the low-level send routine */      
   return_code = _usb_host_send_call_interface (handle, pipe_ptr, tr_ptr);

   if (return_code != USB_OK) {
      /* mark the transaction as unused */
      tr_ptr->TR_INDEX = 0;
   }

   USB_unlock();
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_send_data SUCCESSFUL");
   #endif

   if(return_code == USB_OK)
   {
      return USB_STATUS_TRANSFER_QUEUED;
   }
   else
   {
      return USB_log_error(__FILE__,__LINE__,return_code);
   }

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_send_setup
*  Returned Value : None
*  Comments       :
*  Sends a Setup packet. Internally, following the SendSetup call
*  this takes care of the whole transaction (including receiving or sending 
*  any data to or from the device.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_send_setup
   (
      /* [IN] the USB Host state structure   */
      _usb_host_handle           handle, 

      /* [IN] the pipe handle */
      _usb_pipe_handle           pipe_handle,

      /* [IN] transfer parameters */
      TR_INIT_PARAM_STRUCT_PTR   tr_params_ptr
   )
{ /* Body */
   TR_STRUCT_PTR              tr_ptr;
   PIPE_STRUCT_PTR            pipe_ptr;
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
   uint_32                    return_code;   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_send_setup");
   #endif

   USB_lock();

   /* Initialize a TR and link it into the pipe's TR list */
   return_code = _usb_host_set_up_tr(pipe_handle, tr_params_ptr, &tr_ptr);
   
   if (return_code != USB_STATUS_TRANSFER_QUEUED) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_send_setup error status");
      #endif

      return return_code;
   } /* Endif */
      
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   pipe_ptr = (PIPE_STRUCT_PTR)pipe_handle;

   pipe_ptr->NEXTDATA01 = 0;       /* reset DATA0/1 */

   /* We have obtained the current TR on the Pipe's TR list 
   ** from _usb_host_set_up_tr
   */
   /* true if this setup packet will have a send data phase */
   tr_ptr->SEND_PHASE = (boolean)!(tr_ptr->setup_packet.BMREQUESTTYPE & USB_SETUP_DATA_XFER_DIRECTION);
      
   /***************************************************************
   For data caching it is important that we update the memory
   with the intended contents.
   ***************************************************************/
#if PSP_HAS_DATA_CACHE
    USB_dcache_flush_mlines((void *)&tr_ptr->setup_packet, 1);
         
    if (tr_ptr->TX_LENGTH > 0)
    {
        /* We do flush the buffer first before used by DMA */
        USB_dcache_flush_mlines((void *)tr_ptr->TX_BUFFER, tr_ptr->TX_LENGTH);
    }
    else if (tr_ptr->RX_LENGTH > 0)
    {
        /* We will do soon cache invalidation of buffer. This can have an impact to the
        ** data that sit in the same cache line, but are not part of the buffer. In order
        ** not to invalidate their cached values, we do first flushing those data.
        */
        USB_dcache_flush_mlines((void *)tr_ptr->RX_BUFFER, tr_ptr->RX_LENGTH);
        /* To ensure that the USB DMA transfer will work on a buffer that is not cached,
        ** we invalidate buffer cache lines.
        */
        USB_dcache_invalidate_mlines((void *)tr_ptr->RX_BUFFER, tr_ptr->RX_LENGTH);
    }
    
#endif // PSP_HAS_DATA_CACHE
      

   /* Call the low-level routine to send a setup packet */
   return_code = _usb_host_send_setup_call_interface (handle, pipe_ptr, tr_ptr);

   USB_unlock();

   if (return_code == USB_OK)
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_send_setup SUCCESSFUL");
      #endif

      return USB_STATUS_TRANSFER_QUEUED;
   }
   else
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_send_setup FAILED");
      #endif

      return USB_log_error(__FILE__,__LINE__,return_code);
   }

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/include/sh_mfs.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_mfs.h$
* $Version : 3.8.10.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#ifndef __sh_mfs_h__
#define __sh_mfs_h__

/*
** Function prototypes 
*/
#ifdef __cplusplus
extern "C" {
#endif

extern int_32 Shell_cache(int_32 argc, char_ptr argv[] );
extern int_32 Shell_compare(int_32 argc, char_ptr argv[] );
extern int_32 Shell_create(int_32 argc, char_ptr argv[] );
extern int_32 Shell_flush_cache(int_32 argc, char_ptr argv[] );
extern int_32 Shell_cd(int_32 argc, char_ptr argv[] );
extern int_32 Shell_copy(int_32 argc, char_ptr argv[] );
extern int_32 Shell_del(int_32 argc, char_ptr argv[] );
extern int_32 Shell_df(int_32 argc, char_ptr argv[] );
extern int_32 Shell_di(int_32 argc, char_ptr argv[] );
extern int_32 Shell_dir(int_32 argc, char_ptr argv[] );
extern int_32 Shell_dirent(int_32 argc, char_ptr argv[] );
extern int_32 Shell_disect(int_32 argc, char_ptr argv[] );
extern int_32 Shell_format(int_32 argc, char_ptr argv[] );
extern int_32 Shell_mkdir(int_32 argc, char_ptr argv[] );
extern int_32 Shell_pwd(int_32 argc, char_ptr argv[] );
extern int_32 Shell_read(int_32 argc, char_ptr argv[] );
extern int_32 Shell_rename(int_32 argc, char_ptr argv[] );
extern int_32 Shell_rmdir(int_32 argc, char_ptr argv[] );
extern int_32 Shell_type(int_32 argc, char_ptr argv[] ); 
extern int_32 Shell_use(int_32 argc, char_ptr argv[] );
extern int_32 Shell_write(int_32 argc, char_ptr argv[] );
extern int_32 Shell_write_test(int_32 argc, char_ptr argv[] );
extern int_32 Shell_read_test(int_32 argc, char_ptr argv[] );
extern int_32 Shell_append_test(int_32 argc, char_ptr argv[] );

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/kinetis.h<|end_filename|>
/**HEADER***********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
********************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************
*
* $FileName: kinetis.h$
* $Version : 3.8.26.0$
* $Date    : Sep-21-2012$
*
* Comments:
*
*   This file contains the type definitions for the Kinetis microcontrollers.
*
*END***************************************************************************/

#ifndef __kinetis_h__
#define __kinetis_h__

#define __kinetis_h__version "$Version:3.8.26.0$"
#define __kinetis_h__date    "$Date:Sep-21-2012$"
#ifndef __ASM__

/* Include header file for specific Kinetis platform */
#if     (MQX_CPU == PSP_CPU_MK10DX128Z) || \
        (MQX_CPU == PSP_CPU_MK10DX256Z) || \
        (MQX_CPU == PSP_CPU_MK10DN512Z)
    #include "MK10DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK10F12)
    #include "MK10F12.h"
#elif   (MQX_CPU == PSP_CPU_MK20D50M)
    #include "MK20D5.h"
#elif   (MQX_CPU == PSP_CPU_MK20DX256)
    #include "MK20D7.h"
#elif   (MQX_CPU == PSP_CPU_MK20DX256Z) || \
        (MQX_CPU == PSP_CPU_MK20DN512Z)
    #include "MK20DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK20F12)
    #include "MK20F12.h"
#elif   (MQX_CPU == PSP_CPU_MK21DN512)
    #include "MK21D5.h"
#elif   (MQX_CPU == PSP_CPU_MK30DX128Z) || \
        (MQX_CPU == PSP_CPU_MK30DX256Z) || \
        (MQX_CPU == PSP_CPU_MK30DN512Z)
    #include "MK30DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK40DX128Z) || \
        (MQX_CPU == PSP_CPU_MK40DX256Z) || \
        (MQX_CPU == PSP_CPU_MK40DN512Z)
    #include "MK40DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK40DX128) || \
        (MQX_CPU == PSP_CPU_MK40DX256) || \
        (MQX_CPU == PSP_CPU_MK40D100M)
    #include "MK40D10.h"
#elif   (MQX_CPU == PSP_CPU_MK50DX256Z) || \
        (MQX_CPU == PSP_CPU_MK50DN512Z)
    #include "MK50DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK51DX256Z) || \
        (MQX_CPU == PSP_CPU_MK51DN256Z) || \
        (MQX_CPU == PSP_CPU_MK51DN512Z)
    #include "MK51DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK52DN512Z)
    #include "MK52DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK53DX256Z) || \
        (MQX_CPU == PSP_CPU_MK53DN512Z)
    #include "MK53DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK60DX256Z) || \
        (MQX_CPU == PSP_CPU_MK60DN256Z) || \
        (MQX_CPU == PSP_CPU_MK60DN512Z)
    #include "MK60DZ10.h"
#elif   (MQX_CPU == PSP_CPU_MK60D100M)
    #include "MK60D10.h"
#elif   (MQX_CPU == PSP_CPU_MK60DF120M)
    #include "MK60F15.h"
#elif   (MQX_CPU == PSP_CPU_MK70F120M)
    #include "MK70F12.h"
#elif   (MQX_CPU == PSP_CPU_MK70F150M)
    #include "MK70F15.h"
#else
    #error "Wrong CPU definition"
#endif

    #include "nvic.h"
    #include "kinetis_mpu.h"

#endif /* __ASM__ */

#ifdef __cplusplus
extern "C" {
#endif


/*
*******************************************************************************
**
**                  CONSTANT DEFINITIONS
**
*******************************************************************************
*/

#if   (MQX_CPU == PSP_CPU_MK70F120M)
    /* enable FPU for this platform */
    #define PSP_HAS_CODE_CACHE                      1
    #define PSP_HAS_DATA_CACHE                      1
    #define PSP_HAS_FPU                             1
#elif   (MQX_CPU == PSP_CPU_MK70F150M)
    /* enable FPU for this platform */
    #define PSP_HAS_CODE_CACHE                      1
    #define PSP_HAS_DATA_CACHE                      1
    #define PSP_HAS_FPU                             1
#elif   (MQX_CPU == PSP_CPU_MK60DF120M)
    /* enable FPU for this platform */
    #define PSP_HAS_CODE_CACHE                      1
    #define PSP_HAS_DATA_CACHE                      1
    #define PSP_HAS_FPU                             1
#endif


/* Cache and MMU definition values */
#ifndef PSP_HAS_MMU
#define PSP_HAS_MMU                             0
#endif

#ifndef PSP_HAS_CODE_CACHE
#define PSP_HAS_CODE_CACHE                      0
#endif

#ifndef PSP_HAS_DATA_CACHE
#define PSP_HAS_DATA_CACHE                      0
#endif

#ifndef PSP_HAS_FPU
#define PSP_HAS_FPU                             0
#endif

#define PSP_CACHE_LINE_SIZE                     (0x10)

#ifndef __ASM__

/* Standard cache macros */
#if PSP_HAS_DATA_CACHE
#define _DCACHE_ENABLE(n)               _dcache_enable()
#define _DCACHE_DISABLE()               _dcache_disable()
#define _DCACHE_FLUSH()                 _dcache_flush()
#define _DCACHE_FLUSH_LINE(p)           _dcache_flush_line(p)
#define _DCACHE_FLUSH_MLINES(p, m)      _dcache_flush_mlines(p,m)
#define _DCACHE_INVALIDATE()            _dcache_invalidate()
#define _DCACHE_INVALIDATE_LINE(p)      _dcache_invalidate_line(p)
#define _DCACHE_INVALIDATE_MLINES(p, m) _dcache_invalidate_mlines(p, m)

#define _DCACHE_FLUSH_MBYTES(p, m)             _DCACHE_FLUSH_MLINES(p, m)
#define _DCACHE_INVALIDATE_MBYTES(p, m)        _DCACHE_INVALIDATE_MLINES(p, m)

#else
#define _DCACHE_ENABLE(n)
#define _DCACHE_DISABLE()
#define _DCACHE_FLUSH()
#define _DCACHE_FLUSH_LINE(p)
#define _DCACHE_FLUSH_MLINES(p, m)
#define _DCACHE_INVALIDATE()
#define _DCACHE_INVALIDATE_LINE(p)
#define _DCACHE_INVALIDATE_MLINES(p, m)

#define _DCACHE_FLUSH_MBYTES(p, m)
#define _DCACHE_INVALIDATE_MBYTES(p, m)
#endif

#if PSP_HAS_CODE_CACHE
#define _ICACHE_ENABLE(n)                   _icache_enable()
#define _ICACHE_DISABLE()                   _icache_disable()
#define _ICACHE_INVALIDATE()                _icache_invalidate()
#define _ICACHE_INVALIDATE_LINE(p)          _icache_invalidate_line(p)
#define _ICACHE_INVALIDATE_MLINES(p, m)     _icache_invalidate_mlines(p, m)
#else
#define _ICACHE_ENABLE(n)
#define _ICACHE_DISABLE()
#define _ICACHE_FLUSH()
#define _ICACHE_FLUSH_LINE(p)
#define _ICACHE_FLUSH_MLINES(p, m)
#define _ICACHE_INVALIDATE()
#define _ICACHE_INVALIDATE_LINE(p)
#define _ICACHE_INVALIDATE_MLINES(p, m)
#endif


#define PSP_INTERRUPT_TABLE_INDEX               IRQInterruptIndex

/*
*******************************************************************************
**
**                  TYPE DEFINITIONS
**
*******************************************************************************
*/



/*
*******************************************************************************
**
**              FUNCTION PROTOTYPES AND GLOBAL EXTERNS
**
*******************************************************************************
*/

#define _psp_mem_check_access(addr, size, flags)    \
                    _kinetis_mpu_sw_check(addr, size, flags)

#define _psp_mem_check_access_mask(addr, size, flags, mask) \
                    _kinetis_mpu_sw_check_mask(addr, size, flags, mask)

#define _psp_mpu_add_region(start, end, flags)  \
                    _kinetis_mpu_add_region(start, end, flags)

/* PSP Cache prototypes */
void _dcache_enable(void);
void _dcache_disable(void);
void _dcache_flush(void);
void _dcache_flush_line(pointer);
void _dcache_flush_mlines(pointer, uint_32);
void _dcache_invalidate(void);
void _dcache_invalidate_line(pointer);
void _dcache_invalidate_mlines(pointer, uint_32);

void _icache_enable(void);
void _icache_disable(void);
void _icache_flush(void);
void _icache_flush_line(pointer);
void _icache_flush_mlines(pointer, uint_32);
void _icache_invalidate(void);
void _icache_invalidate_line(pointer);
void _icache_invalidate_mlines(pointer, uint_32);

#endif /* __ASM__ */

#ifdef __cplusplus
}
#endif

#endif /* __kinetis_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mcf51je.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mcf51je.c$
* $Version : 3.8.5.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions for internal flash read, write, erase 
*
*END************************************************************************/
#include "mqx.h"
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "flash_mcf51xx.h"
#include "flash_mcf51xx_prv.h"
#include "flash_mcf51je.h"

static void mcf51je_swap_flash_ram_end(void);
static void mcf51je_swap_flash_ram(VMCF51JE_SIM_STRUCT_PTR sim_ptr);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_cfm_address
* Returned Value   : Address upon success
* Comments         :
*    This function returns the base register address of the CFM
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_cfm_address(uchar module)
{
   VMCF51JE_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); 
   VMCF51XX_FTSR_STRUCT_PTR ftsr_ptr;
   switch (module)
   {
      case MEMORY_ARRAY_STD: 
      case MEMORY_ARRAY_1: 
               ftsr_ptr = (VMCF51XX_FTSR_STRUCT_PTR)&reg_ptr->FTSR1;
               break;
      case MEMORY_ARRAY_2: 
               ftsr_ptr = (VMCF51XX_FTSR_STRUCT_PTR)&reg_ptr->FTSR2;
               break;
      default: ftsr_ptr = NULL;
               break;          
   }
   return (pointer)ftsr_ptr;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_pmc_address
* Returned Value   : Address upon success
* Comments         :
*    This function returns the base register address of the PMC
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_pmc_address()
{
   VMCF51JE_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); 
   uint_8_ptr pmc_ptr = (uint_8_ptr)&reg_ptr->PMC;
   return (pointer)pmc_ptr;   
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mcf51mm_get_rtc_cfg_state
* Returned Value   : Value of bit ARRAYSEL
* Comments         :
*    This function returns the value of ARRAYSEL.
*    There is stored information which flash bank is addressed from 0
*
*END*----------------------------------------------------------------------*/
uint_32 _mcf51_get_rtc_cfg_state()
{
    uint_32 result;
    
    if ( ( ((VMCF51JE_STRUCT_PTR)BSP_IPSBAR)->SIM.SOPT3 ) & MCF51XX_SOPT3_ARRAYSEL_MASK ){    
        result = 1;
    } else {
        result = 0;
    }
    return result;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mcf51_swap_flash_and_reset
* Returned Value   : none
* Comments         :
*    Swap the flash adresses and restart device.
*
*END*----------------------------------------------------------------------*/
void _mcf51_swap_flash_and_reset()
{
    
    uchar_ptr ramcode_ptr = NULL;
    int_32 (*RunInRAM)( VMCF51JE_RTC_STRUCT_PTR );
    VMCF51JE_SIM_STRUCT_PTR sim_ptr = &(((VMCF51JE_STRUCT_PTR)BSP_IPSBAR)->SIM);
    
    /* Allocate space on stack to run flash command out of SRAM */
    ramcode_ptr = _mem_alloc((char*)mcf51je_swap_flash_ram_end - (char*)mcf51je_swap_flash_ram); 
    /* copy code to RAM buffer */
    _mem_copy((void*)mcf51je_swap_flash_ram, ramcode_ptr, (char*)mcf51je_swap_flash_ram_end  - (char*)mcf51je_swap_flash_ram);
    *RunInRAM = (int_32(*)( VMCF51JE_SIM_STRUCT_PTR ))ramcode_ptr;   

    /* Run the code from RAM */
    RunInRAM( sim_ptr );
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : mcf51je_swap_flash_ram
* Returned Value   : none
* Comments         :
*    Finish the swap of flash adresses and restart device. This function is
*    copied to RAM
*
*    WARNING! This code doesn't run correctly from debuger. If debuger is used,
*    instead reset jump to exception occured.
*
*END*----------------------------------------------------------------------*/
static void mcf51je_swap_flash_ram(VMCF51JE_SIM_STRUCT_PTR sim_ptr) 
{
    void (_CODE_PTR_ jump_to_address)(void);
    uint_32 temp;

    /* disable flash speculation */
    _psp_set_cpucr(0x02000000);
    
    /* disable all interrupts */
    temp = _psp_get_sr();
    _psp_set_sr(temp | 0x0700);

    /* swap banks */
    sim_ptr->SOPT3 ^= MCF51XX_SOPT3_ARRAYSEL_MASK;
    
    /* wait after write to ARRAYSEL */
    _ASM_NOP();
    _ASM_NOP();
    _ASM_NOP();

    /* The processor generates a reset if CPUCR[ARD] = 0 */
    _psp_set_cpucr(0);
    
    /* reset using illegal address jump */
    jump_to_address = (void (_CODE_PTR_)(void))0x00804001;
    jump_to_address();

}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : mcf51je_swap_flash_ram_end
* Returned Value   : none
* Comments         :
*    End-mark function
*
*END*----------------------------------------------------------------------*/
static void mcf51je_swap_flash_ram_end(void) {}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_dir_entry.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_dir_entry.c$
* $Version : 3.8.12.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the functions that are used to manipulate FAT directory
*   entries.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"

#if !MFSCFG_READ_ONLY


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Create_directory_entry
* Returned Value   :  Pointer to the directory entry
* Comments  :
*   Try to create a new file.  Search for an unused directory entry, setup the
*   entry and write back the directory.
*END*---------------------------------------------------------------------*/

MFS_DIR_ENTRY_PTR MFS_Create_directory_entry
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,  /*[IN] the drive on which to operate */
    char_ptr        filename_ptr,       /*[IN] pointer to the file's name */
    char            attribute,          /*[IN] attribute to be assigned to the file */
    uint_32_ptr     dir_cluster_ptr,    /*[IN/OUT] indicates cluster in which the entry was put.*/
    uint_32_ptr     dir_index_ptr,      /*[IN/OUT] index of the location of new file within the directory */
    uint_32_ptr     error_ptr           /*[IN/OUT] error_return_address */
    )
{
    MFS_DIR_ENTRY_PTR     dir_entry_ptr, dir_entry_ptr1;
    MFS_DIR_ENTRY_PTR     temp_entry_ptr;
    TIME_STRUCT           time;
    DATE_STRUCT           clk_time;
    uint_32               dir_index, saved_index, temp_index;
    uint_32               entry_cluster, saved_cluster, temp_cluster;
    uint_32               needed_entries, i;
    int_32                length;
    boolean               found_all = FALSE;
    char                  temp_name[SFILENAME_SIZE+1], short_name[SFILENAME_SIZE+1];  
    uchar                 checksum = 0;
    uint_32               prev_cluster= CLUSTER_INVALID, saved_prev_cluster, temp_prev_cluster; 

    dir_entry_ptr = NULL;
    entry_cluster = *dir_cluster_ptr;
    dir_index = 0;

    /*
    ** Check for duplicate file
    */
    if ( filename_ptr == NULL )
    {
        *error_ptr = MFS_INVALID_PARAMETER;
    }
    else if ( *filename_ptr == '\0' )
    {
        *error_ptr = MFS_FILE_NOT_FOUND;
    }
#if MFSCFG_READ_ONLY_CHECK
    else if (MFS_is_read_only (NULL, drive_ptr))
    {
        *error_ptr = MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif
    else if ( (dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, filename_ptr,
        &entry_cluster, &dir_index, &prev_cluster, MFS_ATTR_ANY, error_ptr)) != NULL )
    {
        *error_ptr = MFS_FILE_EXISTS;
    }
    else
    {
        /*
        ** Search for an empty slot
        */

        dir_index = 0;
        dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, attribute, error_ptr); 


        if ( MFS_Dirname_valid(filename_ptr) )
        {
            found_all = TRUE;
        }

        if ( dir_entry_ptr ==  NULL && !*error_ptr )
        {
            found_all = TRUE;
        }

        /* 
        ** Save it now because we might not go into the while loop
        ** If we don't go into while, we lose original values when these 
        ** variables are restored after the while loop
        */
        saved_cluster = entry_cluster;
        saved_index = dir_index;

        while ( !found_all )
        {
            /* Calculate the amount of extra entries needed for LFN's */
            saved_cluster = entry_cluster;
            saved_index = dir_index;

            for ( needed_entries = (strlen(filename_ptr) + 12) / 13;  needed_entries >= 1 && !found_all; needed_entries-- )
            {
                *error_ptr = MFS_Increment_dir_index(drive_ptr, &entry_cluster, &dir_index, NULL);  
                if ( entry_cluster == CLUSTER_EOF && !*error_ptr )
                {
                    /* This means the LFN will span a cluster. */
                    found_all = TRUE;
                    break;
                }
                temp_index = dir_index;
                temp_cluster = entry_cluster;
                temp_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, MFS_ATTR_ANY,error_ptr); 
                if ( *error_ptr )
                {
                    return NULL;
                }
                if ( !temp_entry_ptr )
                {
                    found_all = TRUE;
                    dir_entry_ptr = NULL;
                    break;
                }
                else if ( dir_index == temp_index && temp_cluster == entry_cluster )
                {
                    continue;
                }
                else
                {
                    break;
                }        
            }  

            if ( needed_entries == 0 )
            {
                found_all = TRUE;
            }

            if ( found_all )
            {
                dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &saved_cluster, &saved_index, &saved_prev_cluster, MFS_ATTR_ANY,error_ptr); 
            }
        }  

        entry_cluster = saved_cluster;
        dir_index = saved_index;


        if ( dir_entry_ptr ==  NULL && !*error_ptr )
        {
            /*
            ** Empty spot not found... get a new cluster and use the first entry.
            */
            dir_index = 0;
            if ( entry_cluster == 0 )
            {
                *error_ptr = MFS_ROOT_DIR_FULL;
                return(NULL);
            }
            else
            {
                *error_ptr = MFS_Add_cluster_to_chain(drive_ptr, entry_cluster, &entry_cluster);
                if ( *error_ptr == MFS_NO_ERROR )
                {
                    *error_ptr = MFS_Clear_cluster(drive_ptr, entry_cluster);
                    if ( *error_ptr )
                    {
                        return(NULL);
                    }
                    dir_entry_ptr = (pointer) drive_ptr->DIR_SECTOR_PTR;
                    *error_ptr = MFS_Write_back_fat(drive_ptr);
                    if ( *error_ptr )
                    {
                        return(NULL);
                    }
                }
            }  
        }
    }  

    if ( *error_ptr == MFS_NO_ERROR )
    {
        /* At this point we have one of the following cases 
        **
        ** 1. We have a normal 8.3 filename and an empty slot for it
        ** 2. We have a LFN, and a slot which has enough consecutive free slots
        **    to store the LFN, followed by the actual entry
        */

        /* If the file is a normal 8.3 file */
        if ( MFS_Dirname_valid(filename_ptr) )
        {
            _mem_zero(dir_entry_ptr, sizeof (MFS_DIR_ENTRY));            
            htodc(dir_entry_ptr->ATTRIBUTE, attribute);
            MFS_Expand_dotfile(filename_ptr, dir_entry_ptr->NAME);

            _time_get(&time);
            _time_to_date(&time, &clk_time);
            NORMALIZE_DATE(&clk_time);
            htods(dir_entry_ptr->TIME, PACK_TIME(clk_time));
            htods(dir_entry_ptr->DATE, PACK_DATE(clk_time));   
            drive_ptr->DIR_SECTOR_DIRTY = TRUE;
        }
        else
        {
            /* Case where the file is a LFN */   
            length = strlen(filename_ptr);

            /* Get the 8.3 name and calculate the checksum */
            temp_index = 0;
            temp_cluster = *dir_cluster_ptr;
            *error_ptr = MFS_lfn_to_sfn(filename_ptr, temp_name);

            if ( !*error_ptr )
            {
                do
                {
                    dir_entry_ptr1 = MFS_Find_directory_entry(drive_ptr, temp_name, &temp_cluster, &temp_index, &temp_prev_cluster, MFS_ATTR_ANY, error_ptr); 
                    if ( !*error_ptr && dir_entry_ptr1 != NULL )
                    {
                        MFS_increment_lfn(temp_name);
                        temp_index = 0;       
                    }
                } while ( !*error_ptr && dir_entry_ptr1 != NULL );
                dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, attribute, error_ptr); 

                /*
                ** The memory should be cleared after finding the directory entry.
                */
                _mem_zero(dir_entry_ptr, sizeof (MFS_DIR_ENTRY));

                /* Setup the final slot */
                ((MFS_LNAME_ENTRY_PTR) dir_entry_ptr)->ID |= MFS_LFN_END;
                drive_ptr->DIR_SECTOR_DIRTY = TRUE;

                MFS_Expand_dotfile(temp_name,short_name);
                checksum = MFS_lfn_checksum(short_name);
            }

            while ( length && !*error_ptr )
            {
                i = length - ((length -1) % 13 + 1);
                *error_ptr = MFS_lfn_name_to_entry(filename_ptr + i, (MFS_LNAME_ENTRY_PTR) dir_entry_ptr);

                /* Set the entry number, the checksum value and the attribute */
                ((MFS_LNAME_ENTRY_PTR) dir_entry_ptr)->ID |= (length + 12) / 13;
                ((MFS_LNAME_ENTRY_PTR) dir_entry_ptr)->ALIAS_CHECKSUM= checksum;
                ((MFS_LNAME_ENTRY_PTR) dir_entry_ptr)->ATTR = MFS_ATTR_LFN;
                drive_ptr->DIR_SECTOR_DIRTY = TRUE;

                length -= (length - i);
                if ( length < 0 )
                {
                    length = 0;
                }

                if ( length && !*error_ptr )
                {

                    dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, attribute, error_ptr); 
                    if ( dir_entry_ptr ==  NULL && !*error_ptr )
                    {
                        /* No empty spots... We need to get a new cluster */
                        dir_index = 0; 
                        if ( entry_cluster == 0 )
                        {
                            *error_ptr = MFS_ROOT_DIR_FULL; 
                            return(NULL); 
                        }
                        else
                        {
                            *error_ptr = MFS_Add_cluster_to_chain( drive_ptr, entry_cluster, &entry_cluster); 
                            if ( *error_ptr == MFS_NO_ERROR )
                            {
                                *error_ptr = MFS_Clear_cluster(drive_ptr, entry_cluster); 
                                if ( *error_ptr )
                                {
                                    return(NULL); 
                                }
                                dir_entry_ptr = (pointer) drive_ptr->DIR_SECTOR_PTR; 
                                *error_ptr = MFS_Write_back_fat(drive_ptr); 
                                if ( *error_ptr )
                                {
                                    return(NULL); 
                                }
                            }
                        }   
                    }
                    _mem_zero(dir_entry_ptr, sizeof (MFS_DIR_ENTRY));
                    drive_ptr->DIR_SECTOR_DIRTY = TRUE;
                }
            }  

            /* LFN is written, so write the actual entry */
            if ( !*error_ptr )
            {
                dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, attribute, error_ptr); 
                if ( dir_entry_ptr == NULL && !*error_ptr )
                {
                    dir_index = 0; 
                    if ( entry_cluster == 0 )
                    {
                        *error_ptr = MFS_ROOT_DIR_FULL; 
                        return(NULL); 
                    }
                    else
                    {
                        *error_ptr = MFS_Add_cluster_to_chain( drive_ptr, entry_cluster, &entry_cluster); 
                        if ( *error_ptr == MFS_NO_ERROR )
                        {
                            *error_ptr =  MFS_Clear_cluster(drive_ptr, entry_cluster); 
                            if ( *error_ptr )
                            {
                                return(NULL); 
                            }
                            dir_entry_ptr = (pointer) drive_ptr->DIR_SECTOR_PTR; 
                            *error_ptr = MFS_Write_back_fat(drive_ptr); 
                            if ( *error_ptr )
                            {
                                return(NULL); 
                            }
                        }
                    }   
                }

                _mem_zero(dir_entry_ptr, sizeof (MFS_DIR_ENTRY));
                htodc(dir_entry_ptr->ATTRIBUTE, attribute);
                MFS_Expand_dotfile(temp_name, dir_entry_ptr->NAME);

                _time_get(&time);
                _time_to_date(&time, &clk_time);
                NORMALIZE_DATE(&clk_time);
                htods(dir_entry_ptr->TIME, PACK_TIME(clk_time));
                htods(dir_entry_ptr->DATE, PACK_DATE(clk_time));   
                drive_ptr->DIR_SECTOR_DIRTY = TRUE;
            }
        }  

        if ( *error_ptr )
        {
            return(NULL);
        }
    }

    *dir_cluster_ptr = entry_cluster;
    *dir_index_ptr = dir_index;
    return(dir_entry_ptr);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Update_entry
* Returned Value   : error_code
* Comments  :  Put the copy of the entry in the buffer, then update disk
*              image.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Update_entry
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,  /*[IN] the drive on which to operate */
    MFS_HANDLE_PTR          handle      /*[IN] Update this file */
    )
{
    uint_32              dir_index;
    uint_32              dir_cluster;
    _mfs_error           error_code = MFS_NO_ERROR;
    MFS_DIR_ENTRY_PTR    dir_entry_ptr;
    uint_32              prev_cluster; 

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    if ( handle == NULL )
    {
        error_code = MFS_INVALID_HANDLE;
    }
    else
    {
        dir_cluster =  handle->DIR_CLUSTER;
        dir_index   =  handle->DIR_INDEX;

        dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &dir_cluster, &dir_index, &prev_cluster, MFS_ATTR_ANY, &error_code); 
        if ( dir_entry_ptr == NULL && !error_code )
        {
            error_code = MFS_FILE_NOT_FOUND;
        }
        else
        {
            _mem_copy(&handle->DIR_ENTRY, dir_entry_ptr, sizeof(MFS_DIR_ENTRY));
            drive_ptr->DIR_SECTOR_DIRTY = TRUE;
        }  

    }  

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Create_entry_slave
* Returned Value   : DIR_ENTRY_PTR to the buffer on disk
* Comments  :
*      Create a file. If a file exists, and the Overwrite flag is FALSE,
*      NULL is returned.
*      When an entry is found and overwritten, the error is set to
*      MFS_FILE_EXISTS, but the returned PTR points to a valid location.
*      If error is NO_ERROR, a new entry has been created.
*      The attr of the new entry has to be compatible with the old one,
*      or WRITE_FAULT is returned.
*      If the old one is Read only, ACCESS_DENIED is returned.
*      The semaphore is assumed locked and the fat up to date
*
*END*---------------------------------------------------------------------*/

MFS_DIR_ENTRY_PTR MFS_Create_entry_slave
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,      /*[IN] the drive on which to operate */
    uchar                    attr,          /*[IN] attribute to be given to the new file */
    char_ptr                 pathname,      /*[IN] directory and file name to be given to the new file */
    uint_32_ptr              cluster_ptr,   /*[OUT] cluster # in the directory where the entry was created */
    uint_32_ptr              index_ptr,     /*[OUT] index # in the directory where the entry was created*/
    _mfs_error_ptr           error_ptr,     /*[IN/OUT] error code is written to this address */
    boolean                  overwrite      /*[IN]  if TRUE, we will overwrite an existing entry w/the same name */
    )
{
    MFS_DIR_ENTRY_PTR   dir_entry_ptr;
    char_ptr            temp_dirname;
    char_ptr            temp_filename;
    uchar               at;
    uint_32             dir_cluster;
    uint_32             dir_index;
    uint_32             vol_cluster,
        vol_index;
    _mfs_error          error_code;
    uint_32             prev_cluster; 

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        if ( error_ptr )
        {
            *error_ptr = MFS_DISK_IS_WRITE_PROTECTED;
        }
        return NULL;
    }
#endif

    dir_index   = 0;
    dir_cluster = drive_ptr->CUR_DIR_CLUSTER;
    dir_entry_ptr = NULL;

    error_code = MFS_alloc_2paths(&temp_dirname,&temp_filename);
    if ( error_code )
    {
        return( NULL );
    }

    error_code = MFS_Parse_pathname(temp_dirname, temp_filename, pathname);
    if ( error_code == MFS_NO_ERROR )
    {
        dir_cluster = MFS_Find_directory(drive_ptr, temp_dirname, dir_cluster);

        if ( dir_cluster == CLUSTER_INVALID )
        {
            error_code = MFS_PATH_NOT_FOUND;
        }
        else
        {
            if ( MFS_is_valid_lfn(temp_filename) )
            {
                if ( attr & MFS_ATTR_VOLUME_NAME )
                {
                    /*
                    ** If creating a volume label, it must be in the root
                    ** directory.
                    */
                    if ( dir_cluster == 0 )
                    {
                        vol_cluster = 0;
                        vol_index   = 0;
                        dir_entry_ptr =  MFS_Find_directory_entry(drive_ptr, NULL, &vol_cluster, 
                            &vol_index, &prev_cluster, MFS_ATTR_VOLUME_NAME, &error_code); 
                        if ( dir_entry_ptr )
                        {
                            error_code = MFS_ALREADY_ASSIGNED;
                        }
                    }
                    else
                    {
                        error_code = MFS_ACCESS_DENIED;
                    }  
                }

                if ( error_code == MFS_NO_ERROR )
                {
                    dir_entry_ptr = MFS_Create_directory_entry(drive_ptr, temp_filename, attr, &dir_cluster, &dir_index, &error_code);

                    /* if dir_entry_ptr == NULL
                    ** we couldn't create a new entry. 
                    ** if not NULL, it may be a brand new entry (MFS_NO_ERROR) or
                    ** an old one (MFS_FILE_EXISTS)
                    */

                    if ( dir_entry_ptr != NULL )
                    {
                        at = dtohc(dir_entry_ptr->ATTRIBUTE);

                        if ( (error_code != MFS_NO_ERROR) && (overwrite == FALSE) )
                        {
                            dir_entry_ptr = NULL;
                        }
                        else if ( (error_code == MFS_FILE_EXISTS) && ((at & MFS_ATTR_DIR_NAME) != (attr & MFS_ATTR_DIR_NAME)) 
                            || ((at & MFS_ATTR_VOLUME_NAME) !=  (attr & MFS_ATTR_VOLUME_NAME)) )
                        {
                            error_code = MFS_WRITE_FAULT;
                            dir_entry_ptr = NULL;
                        }
                        else if ( at & MFS_ATTR_READ_ONLY && error_code != 
                            MFS_NO_ERROR )
                        {
                            /*
                            ** If not freshly created
                            */
                            error_code = MFS_ACCESS_DENIED;
                            dir_entry_ptr = NULL;
                        }
                    }
                    *cluster_ptr = dir_cluster;
                    *index_ptr   = dir_index;
                }
            }
            else
            {
                error_code = MFS_INVALID_PARAMETER;
                dir_entry_ptr = NULL;
            }  
        }  
    }

    if ( error_ptr )
    {
        *error_ptr = error_code;
    }

    MFS_free_path(temp_filename);
    MFS_free_path(temp_dirname);

    return(dir_entry_ptr);
}  

#endif


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Increment_dir_index
* Returned Value   :  uint_32 error_code
* Comments  :
*END*---------------------------------------------------------------------*/

_mfs_error  MFS_Increment_dir_index
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,  /*[IN] the drive on which to operate */
    uint_32_ptr    cluster_ptr,         /*[IN/OUT]  the initial/next cluster # */
    uint_32_ptr    index_ptr,           /*[IN/OUT]  the initial/next index */
    uint_32_ptr    prev_cluster_ptr     /*[IN/OUT]  the prev cluster # */
    )
{
    uint_32        index;
    uint_32        cluster;
    _mfs_error     error_code;

    error_code = MFS_NO_ERROR;
    index   = *index_ptr;
    cluster = *cluster_ptr;

    index++;

    if ( !(index & (drive_ptr->ENTRIES_PER_SECTOR-1)) )
    {
        /*
        ** if the index count LSB's wrapped to 0 (new sector)
        */
        if ( cluster != 0 )
        {
            if ( INDEX_TO_SECTOR (index) >= drive_ptr->BPB.SECTORS_PER_CLUSTER )
            {
                /*
                ** If we are over the size of a cluster
                */

                error_code = MFS_get_cluster_from_fat(drive_ptr,cluster, &cluster);
                if ( error_code == MFS_NO_ERROR )
                {
                    index = 0;
                }
            }
        }
        else
        {
            if ( index >= drive_ptr->BPB.ROOT_ENTRIES )
            {
                index = 0;
                cluster = CLUSTER_INVALID;
            }
        }  
    }

    if ( (cluster != *cluster_ptr) && (cluster != CLUSTER_INVALID) )
    {
        if ( prev_cluster_ptr != NULL )
        {
            *prev_cluster_ptr = *cluster_ptr;
        }
    }

    *index_ptr   = index;
    *cluster_ptr = cluster;

    return(error_code);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/nvic.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: cortexa5.h$
* $Version : 3.8.7.0$
* $Date    : Oct-2-2012$
*
* Comments:
* ARM Nested Vectored Interrupt Controller (NVIC)
*
*END************************************************************************/

#ifndef __nvic_h__
#define __nvic_h__

#ifdef __cplusplus
extern "C" {
#endif

#include <mqx.h>

/* Initialization of interrupt vector in GIC (vector, priority, enable/disable) */
_mqx_uint _nvic_int_init(_mqx_uint irq, _mqx_uint prior, boolean enable);

/* Enable interrupt for given vector */
_mqx_uint _nvic_int_enable(_mqx_uint irq);

/* Disable interrupt for given vector */
_mqx_uint _nvic_int_disable(_mqx_uint irq);

#ifdef __cplusplus
}
#endif

#endif // __nvic_h__


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/arp.h<|end_filename|>
#ifndef __arp_h__
#define __arp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: arp.h$
* $Version : 3.0.5.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   Address Resolution Protocol definitions.
*
*END************************************************************************/

#include "ip_prv.h"


/***************************************
**
** Prototypes
**
*/

extern uint_32 ARP_init
(
   void
);

extern uint_32 ARP_open
(
   IP_IF_PTR      if_ptr      /* [IN] IP interface structure */
);

extern uint_32 ARP_close
(
   IP_IF_PTR      if_ptr      /* [IN] IP interface structure */
);

extern void ARP_service
(
   RTCSPCB_PTR    rtcs_pcb    /* [IN] received packet */
);

extern uint_32 ARP_resolve
(
   IP_IF_PTR      if_ptr,     /* [IN] IP interface structure */
   RTCSPCB_PTR    rtcs_pcb,   /* [IN] packet to send */
   _ip_address    isrc,       /* [IN] source address */
   _ip_address    idest       /* [IN] destination address */
);

extern uint_32 ARP_request
(
   IP_IF_PTR      if_ptr,
   _ip_address    isrc,
   _ip_address    idest
);

extern boolean ARP_do_proxy
(
   IP_IF_PTR      iflocal,    /* [IN] the local interface */
   _ip_address    iplocal     /* [IN] the IP address to test */
);

extern boolean ARP_is_complete
(
  IP_IF_PTR      if_ptr,      /* [IN] IP interface structure */
  _ip_address    addr         /* [IN] the IP address to search for */
);

extern boolean  ARP_kill_entry
(
  IP_IF_PTR      if_ptr,       /* [IN] IP interface structure */
  _ip_address    addr          /* [IN] the IP address to remove from arp Q */
        
);

extern  RTCSPCB_PTR ARP_find_waiting
(
  IP_IF_PTR      if_ptr,       /* [IN] IP interface structure */
  _ip_address    addr          /* [IN] the IP address to remove from */
);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/shell/sh_cmdlist.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_cmdlist.c$
* $Version : 3.8.4.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include "shell.h"
#include "sh_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_command_list
*  Returned Value:  none
*  Comments  :  SHELL utility to load and execute an executable file
*
*END*-----------------------------------------------------------------*/

int_32  Shell_command_list(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv ); 
   SHELL_COMMAND_PTR    command_ptr;
   uint_32              i; 

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc==1)  {
         for (i=0,command_ptr = shell_ptr->COMMAND_LIST_PTR; 
              command_ptr->COMMAND != NULL; 
              i++,command_ptr++)  
          {
            printf("%-8s ", command_ptr->COMMAND);
            if ((i&7)==7) printf("\n");
         } /* Endwhile */
         if ((i&7)!=0) printf("\n");        
      } else {  
         print_usage = TRUE;
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s\n", argv[0]);
      } else  {
         printf("Usage: %s\n", argv[0]);
      }
   }
   return return_code;
} /* Endbody */
/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_arpdisp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_arpdisp.c$
* $Version : 3.8.8.0$
* $Date    : Sep-26-2012$
*
* Comments:
*
*   Example using RTCS Library.
*
*END************************************************************************/

#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS
#include <rtcs.h>
#include <enet.h>
#include <ipcfg.h>
#include "sh_rtcs.h"
#include "sh_enet.h"

#ifdef BSP_ENET_DEVICE_COUNT
#if  (BSP_ENET_DEVICE_COUNT > 0) 


extern void ARP_display_if_table(_rtcs_if_handle   ihandle);
extern uint_32 RTCS_arp_delete (_rtcs_if_handle _PTR_   ihandle,_ip_address paddr );

/*TASK*-----------------------------------------------------------------
*
* Function Name  : Shell_arpdisp
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/

int_32 Shell_arpdisp(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   _rtcs_if_handle   ihandle = ipcfg_get_ihandle (BSP_DEFAULT_ENET_DEVICE);
  
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

    if (!print_usage)  {
      if (argc > 1)  {
         return_code = SHELL_EXIT_ERROR;
         print_usage = TRUE;
      } else  { 
        ARP_display_if_table(ihandle);
      }
    }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s \n", argv[0]);
      } else  {
         printf("Usage: %s \n", argv[0]);
      }
   }

   return return_code;
} /* Endbody */

/*TASK*-----------------------------------------------------------------
*
* Function Name  : Shell_arpdel
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/

int_32 Shell_arpdel(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   _ip_address       ipaddr;
   _rtcs_if_handle   ihandle = ipcfg_get_ihandle (BSP_DEFAULT_ENET_DEVICE);
  
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc != 2)  {
         return_code = SHELL_EXIT_ERROR;
         print_usage = TRUE;
      } else  if (! Shell_parse_ip_address( argv[1], &ipaddr))  {
          printf("Error, invalid ip address\n");
          return_code = SHELL_EXIT_ERROR;
      }
      if (return_code == SHELL_EXIT_SUCCESS) {
          RTCS_arp_delete(ihandle,ipaddr);
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <ip_address>\n", argv[0]);
      } else  {
         printf("Usage: %s <ip_address> \n", argv[0]);
         printf("   <ip_address>  = IP Address\n");
      }
   }

   return return_code;
} /* Endbody */

/*TASK*-----------------------------------------------------------------
*
* Function Name  : Shell_arpadd
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/
int_32 Shell_arpadd(int_32 argc, char_ptr argv[] )
{
    boolean         print_usage, shorthelp = FALSE;
    int_32          return_code = SHELL_EXIT_SUCCESS;
    _enet_address   mac;
    _ip_address     ipaddr;    

    _rtcs_if_handle   ihandle = ipcfg_get_ihandle (BSP_DEFAULT_ENET_DEVICE);
  
    print_usage = Shell_check_help_request(argc, argv, &shorthelp );

    if (!print_usage)
    {
        if ((argc != 4)&&(argc != 3))
        {
            return_code = SHELL_EXIT_ERROR;
            print_usage = TRUE;
        }
        else  if (! Shell_parse_ip_address( argv[1], &ipaddr))
        {
            printf("Error, invalid ip address\n");
            return_code = SHELL_EXIT_ERROR;
        }
        else if (! Shell_parse_enet_address(argv[2], mac))
        {
            printf("Invalid MAC address!\n");
            return_code = SHELL_EXIT_ERROR;
        }
        else
        {
            RTCS_arp_add(ihandle, ipaddr, (char*)mac);
            ARP_display_if_table(ihandle);
        }
    }
  
   
    if (print_usage)
    {
        if (shorthelp)
        {
            printf("%s <ip_address> <mac>\n", argv[0]);
        }
        else
        {
            printf("Usage: %s <ip_address> <mac>\n", argv[0]);
            printf("   <ip_address>  = IP Address\n");
            printf("   <mac>      = Ethernet MAC address\n"  );         
        }
    }

    return return_code;
} 

#else /* (BSP_ENET_DEVICE_COUNT > 0) */
int_32 Shell_arpadd(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;
}
int_32 Shell_arpdel(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;   
}
int_32 Shell_arpdisp(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;   
}
#endif /* (BSP_ENET_DEVICE_COUNT > 0) */

#else /* BSP_ENET_DEVICE_COUNT */
int_32 Shell_arpadd(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;   
}
int_32 Shell_arpdel(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;   
}
int_32 Shell_arpdisp(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;   
}
#endif /* BSP_ENET_DEVICE_COUNT */
#endif /* SHELLCFG_USES_RTCS */

/* EOF */



<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/hid/usb_host_hid.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_hid.c$
* $Version : 3.8.6.0$
* $Date    : Sep-13-2012$
*
* Comments:
*
*   This file Contains the implementation of class driver for HID devices.
*
*END************************************************************************/

#include "usb_host_hid.h"


static USB_HID_CLASS_INTF_STRUCT_PTR hid_anchor = NULL;


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hid_mass_init
* Returned Value : None
* Comments       :
*     This function is called by common class to initialize the class driver. It
*     is called in response to a select interface call by application
*
*END*--------------------------------------------------------------------*/

void usb_class_hid_init
   (
      /* [IN]  structure with USB pipe information on the interface */
      PIPE_BUNDLE_STRUCT_PTR      pbs_ptr,

      /* [IN] printer call struct pointer */
      CLASS_CALL_STRUCT_PTR       ccs_ptr
   )
{ /* Body */
   USB_HID_CLASS_INTF_STRUCT_PTR if_ptr = ccs_ptr->class_intf_handle;
   USB_STATUS                    status;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_init");
   #endif
   

   /* Make sure the device is still attached */
   USB_lock(); //not needed as init is called from "already locked" function

   status = usb_host_class_intf_init(pbs_ptr, if_ptr, &hid_anchor, NULL);
   if (status == USB_OK) {
      /*
      ** We generate a code_key based on the attached device. This is used to
      ** verify that the device has not been detached and replaced with another.
      */
      ccs_ptr->code_key = 0;
      ccs_ptr->code_key = usb_host_class_intf_validate(ccs_ptr);

//      if_ptr->IFNUM =
//         ((INTERFACE_DESCRIPTOR_PTR)if_ptr->G.intf_handle)->bInterfaceNumber;

//      if_ptr->P_CONTROL = usb_hostdev_get_pipe_handle(pbs_ptr, USB_CONTROL_PIPE,
//         0);
//      if_ptr->P_INT_IN = usb_hostdev_get_pipe_handle(pbs_ptr,
//         USB_INTERRUPT_PIPE, USB_RECV);
   } /* Endif */

   /* Signal that an error has occured by setting the "code_key" to 0 */
//   if (status || !if_ptr->P_INT_IN || !if_ptr->P_CONTROL) {
//      ccs_ptr->code_key = 0;
//   } /* Endif */

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_init, SUCCESSFUL");
   #endif
   
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hid_cntrl_callback
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This is the callback used when HID information is sent or received
*
*END*--------------------------------------------------------------------*/

static void usb_class_hid_cntrl_callback
   (
      /* [IN] Unused */
      pointer     pipe,
      /* [IN] Pointer to the class interface instance */
      pointer     param,
      /* [IN] Data buffer */
      uchar_ptr   buffer,
      /* [IN] Length of buffer */
      uint_32     len,
      /* [IN] Error code (if any) */
      USB_STATUS  status
   )
{ /* Body */
   USB_HID_CLASS_INTF_STRUCT_PTR      if_ptr;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_cntrl_callback");
   #endif

   /*
   ** There is need for USB_lock in the callback function, and there is also no
   ** need to check if the device is still attached (otherwise this callback
   ** would never have been called!
   */

   /* Get class interface handle, reset IN_SETUP and call callback */
   if_ptr = (USB_HID_CLASS_INTF_STRUCT_PTR)param;

   if_ptr->IN_SETUP = FALSE;

   if (if_ptr->USER_CALLBACK) {
      if_ptr->USER_CALLBACK(pipe, if_ptr->USER_PARAM, buffer, len, status);
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_cntrl_callback, SUCCESSFUL");
   #endif
   
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hid_cntrl_common
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is used to send a control request
*
*END*--------------------------------------------------------------------*/

static USB_STATUS usb_class_hid_cntrl_common
   (
      /* [IN] The communication device common command structure */
      HID_COMMAND_PTR         com_ptr,
      /* [IN] Bitmask of the request type */
      uint_8                  bmrequesttype,
      /* [IN] Request code */
      uint_8                  brequest,
      /* [IN] Value to copy into WVALUE field of the REQUEST */
      uint_16                 wvalue,
      /* [IN] Length of the data associated with REQUEST */
      uint_16                 wlength,
      /* [IN] Pointer to data buffer used to send/recv */
      uchar_ptr               data
   )
{ /* Body */
   USB_HID_CLASS_INTF_STRUCT_PTR    if_ptr;
   USB_SETUP                        req;
   USB_STATUS                       status = USBERR_NO_INTERFACE;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_cntrl_common");
   #endif
   
   USB_lock();
   /* Validity checking */
   if (usb_host_class_intf_validate(com_ptr->CLASS_PTR)) {
      if_ptr =
         (USB_HID_CLASS_INTF_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
      status = usb_hostdev_validate(if_ptr->G.dev_handle);
   } /* Endif */

   if (!status && if_ptr->IN_SETUP) {
      status = USBERR_TRANSFER_IN_PROGRESS;
   } /* Endif */

   if (!status) {
      /* Save the higher level callback and ID */
      if_ptr->USER_CALLBACK = com_ptr->CALLBACK_FN;
      if_ptr->USER_PARAM = com_ptr->CALLBACK_PARAM;

      /* Setup the request */
      req.BMREQUESTTYPE = bmrequesttype;
      req.BREQUEST = brequest;
      *(uint_16*)req.WVALUE = HOST_TO_LE_SHORT(wvalue);
      *(uint_16*)req.WINDEX = HOST_TO_LE_SHORT(((INTERFACE_DESCRIPTOR_PTR)if_ptr->G.intf_handle)->bInterfaceNumber);
      *(uint_16*)req.WLENGTH = HOST_TO_LE_SHORT(wlength);
      status = _usb_hostdev_cntrl_request(if_ptr->G.dev_handle, &req, data,
         usb_class_hid_cntrl_callback, if_ptr);
      if (status == USB_STATUS_TRANSFER_QUEUED) {
         if_ptr->IN_SETUP = TRUE;
      } /* Endif */
   } /* Endif */
   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_cntrl_common, SUCCESSFUL");
   #endif
   return status;
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hid_get_report
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is called by the application to get a report from the HID
*     device
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hid_get_report
   (
      /* [IN] Class Interface structure pointer */
      HID_COMMAND_PTR            com_ptr,

      /* [IN] Report ID (see HID specification) */
      uint_8                     rid,

      /* [IN] Report type (see HID specification) */
      uint_8                     rtype,

      /* [IN] Buffer to receive report data */
      pointer                    buf,

      /* [IN] length of the Buffer */
      uint_16                    blen
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_get_report, SUCCESSFUL");
   #endif

   return usb_class_hid_cntrl_common(com_ptr,
      REQ_TYPE_IN | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE,
      GET_REPORT, (uint_16)((rtype << 8) | rid), blen, buf);

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hid_set_report
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to send a report to the HID
*     device
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hid_set_report
   (
      /* [IN] Class Interface structure pointer */
      HID_COMMAND_PTR            com_ptr,

      /* [IN] Report ID (see HID specification) */
      uint_8                     rid,

      /* [IN] Report type (see HID specification) */
      uint_8                     rtype,

      /* [IN] Buffer to receive report data */
      pointer                    buf,

      /* [IN] length of the Buffer */
      uint_16                    blen
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_set_report, SUCCESSFUL");
   #endif

   return usb_class_hid_cntrl_common(com_ptr,
      REQ_TYPE_OUT | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE,
      SET_REPORT, (uint_16)((rtype << 8) | rid), blen, buf);

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hid_get_idle
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is called by the application to read the idle rate of a
*     particular HID device report
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hid_get_idle
   (
      /* [IN] Class Interface structure pointer */
      HID_COMMAND_PTR            com_ptr,

      /* [IN] Report ID (see HID specification) */
      uint_8                     rid,

      /* [OUT] idle rate of this report */
      uint_8_ptr                 idle_rate
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_set_report, SUCCESSFUL");
   #endif

   return usb_class_hid_cntrl_common(com_ptr,
      REQ_TYPE_IN | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE,
      GET_IDLE, rid, 1, idle_rate);

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hid_set_idle
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to silence a particular report
*     on interrupt In pipe until a new event occurs or specified  time elapses
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hid_set_idle
   (
      /* [IN] Class Interface structure pointer */
      HID_COMMAND_PTR            com_ptr,

      /* [IN] Report ID (see HID specification) */
      uint_8   rid,

      /*[IN] Idle rate */
      uint_8   duration
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_set_idle, SUCCESSFUL");
   #endif

   return usb_class_hid_cntrl_common(com_ptr,
      REQ_TYPE_OUT | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE,
      SET_IDLE, (uint_16)((duration << 8) | rid), 0, NULL);

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hid_get_protocol
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     Reads the active protocol (boot protocol or report protocol)
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hid_get_protocol
   (
      /* [IN] Class Interface structure pointer */
      HID_COMMAND_PTR            com_ptr,

      /* [IN] Protocol (1 byte, 0 = Boot Protocol or 1 = Report Protocol */
      uchar_ptr                  protocol
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_get_protocol, SUCCESSFUL");
   #endif

   return usb_class_hid_cntrl_common(com_ptr,
      REQ_TYPE_IN | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE,
      GET_PROTOCOL, 0, 1, protocol);

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hid_set_protocol
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     Switches between the boot protocol and the report protocol (or vice versa)
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hid_set_protocol
   (
      /* [IN] Class Interface structure pointer */
      HID_COMMAND_PTR            com_ptr,

      /* [IN] The protocol (0 = Boot, 1 = Report) */
      uint_8                     protocol
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hid_set_protocol, SUCCESSFUL");
   #endif

   return usb_class_hid_cntrl_common(com_ptr,
      REQ_TYPE_OUT | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE,
      SET_PROTOCOL, protocol, 0, NULL);

} /* Endbody */


/* EOF */



<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/hid/usb_hid.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_hid.c$
* $Version : 3.8.6.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
* @brief The file contains USB stack HID layer implimentation.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_stack_config.h"

#if HID_CONFIG
 
#include "usb_hid.h"

/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/


/****************************************************************************
 * Global Variables
 ****************************************************************************/
 HID_DEVICE_STRUCT    *device_array[MAX_HID_DEVICE];          
/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
uint_8 USB_HID_Other_Requests(USB_SETUP_STRUCT * setup_packet, 
                          uint_8_ptr *data, 
                          uint_32 *size,pointer arg);
static uint_8 HID_USB_Map_Ep_To_Struct_Index(HID_DEVICE_STRUCT_PTR devicePtr, 
                          uint_8 ep_num
                          );                          
                          
/*****************************************************************************
 * Local Variables - None
 *****************************************************************************/
 
 
/*****************************************************************************
 * Local Functions
 *****************************************************************************/
 /*************************************************************************//*!
 *
 * @name  USB_Hid_Allocate_Handle
 *
 * @brief The funtion reserves entry in device array and returns the index.
 *
 * @param none.
 * @return returns the reserved handle or if no entry found device busy.      
 *
 *****************************************************************************/
static HID_HANDLE  USB_Hid_Allocate_Handle()
{
    uint_32 cnt = 0;
    for (;cnt< MAX_HID_DEVICE;cnt++)
    {
       if (device_array[cnt] == NULL)
        return cnt;
    }
    return USBERR_DEVICE_BUSY;
}
 /*************************************************************************//*!
 *
 * @name  USB_Hid_Free_Handle
 *
 * @brief The funtion releases entry in device array .
 *
 * @param handle  index in device array to be released..
 * @return returns and error code or USB_OK.      
 *
 *****************************************************************************/

static int_32 USB_Hid_Free_Handle(HID_HANDLE handle)
{
    if (/*(handle < 0) || */ (handle > MAX_HID_DEVICE))
        return USBERR_ERROR;
    
    USB_mem_free((void *)device_array[handle]);
    device_array[handle] = NULL;
    return USB_OK;
}
 /*************************************************************************//*!
 *
 * @name  USB_Hid_Get_Device_Ptr
 *
 * @brief The funtion gets the device pointer from device array .
 *
 * @param handle  index in device array.
 * @return returns returns pointer to HID device structure..      
 *
 *****************************************************************************/
static HID_DEVICE_STRUCT_PTR USB_Hid_Get_Device_Ptr(HID_HANDLE handle)
{
     return device_array[handle]; 
}
 /*************************************************************************//*!
 *
 * @name  HID_USB_Map_Ep_To_Struct_Index
 *
 * @brief The funtion maps the endpoint num to the index of the ep data 
 *           structure
 *
 * @param handle          handle to identify the controller
 * @param ep_num          endpoint num
 *
 * @return index          mapped index       
 *
 *****************************************************************************/
static uint_8 HID_USB_Map_Ep_To_Struct_Index(HID_DEVICE_STRUCT_PTR devicePtr,
uint_8 ep_num
) 
{
    uint_8 count = 0;
    
    USB_ENDPOINTS *ep_desc_data = devicePtr->ep_desc_data;
    /* map the endpoint num to the index of the endpoint structure */
    for(count = 0; count < ep_desc_data->count; count++) 
    {
        if(ep_desc_data->ep[count].ep_num == ep_num)
            break;
    }
    
    return count; 
    
}
 
/**************************************************************************//*!
 *
 * @name  USB_Service_Hid
 *
 * @brief The funtion ic callback function of HID endpoint 
 *
 * @param event
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Service_Hid(PTR_USB_EVENT_STRUCT event,pointer arg)
{
    uint_8 index;
    uint_8 producer, consumer;
    HID_DEVICE_STRUCT_PTR  devicePtr;
    USB_ENDPOINTS *ep_desc_data;
    
    devicePtr = (HID_DEVICE_STRUCT_PTR)arg;
    
    ep_desc_data = devicePtr->ep_desc_data; 

     /* map the endpoint num to the index of the endpoint structure */
    index = HID_USB_Map_Ep_To_Struct_Index(devicePtr, event->ep_num); 
                                               
    producer = devicePtr->hid_endpoint_data.ep[index].bin_producer;    
        
    /* if there are no errors de-queue the queue and decrement the no. of 
     transfers left, else send the same data again */
     /* de-queue if the send is complete with no error */
   devicePtr->hid_endpoint_data.ep[index].bin_consumer++;  
        
    consumer = devicePtr->hid_endpoint_data.ep[index].bin_consumer;
        
    if(consumer != producer) 
    {/*if bin is not empty */
        
        USB_CLASS_HID_QUEUE queue;    
        /* send the next packet in queue */                
        queue = devicePtr->hid_endpoint_data.ep[index].
                                         queue[consumer % HID_MAX_QUEUE_ELEMS];
                        
        (void)USB_Class_Send_Data(devicePtr->class_handle, queue.channel, 
                                      queue.app_buff, queue.size);                                                                                                
    }        
    
    /* notify the app of the send complete */
    devicePtr->hid_class_callback.callback(USB_APP_SEND_COMPLETE, 0,
    devicePtr->hid_class_callback.arg); 
}

/**************************************************************************//*!
 *
 * @name  USB_Class_Hid_Event
 *
 * @brief The funtion initializes HID endpoint 
 *
 * @param handle          handle to Identify the controller
 * @param event           pointer to event structure
 * @param val             gives the configuration value 
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Class_Hid_Event(uint_8 event, void* val,void * arg) 
{
    uint_8 index;
    
    USB_EP_STRUCT_PTR ep_struct_ptr;
    
    HID_DEVICE_STRUCT_PTR  devicePtr;
    
    devicePtr = (HID_DEVICE_STRUCT_PTR)arg;
    
    if(event == USB_APP_ENUM_COMPLETE) 
    {
        uint_8 count = 0;
        uint_8 component;

        /* get the endpoints from the descriptor module */            
        USB_ENDPOINTS *ep_desc_data = devicePtr->ep_desc_data; 
        
        /* intialize all non control endpoints */            
        while(count < ep_desc_data->count) 
        {
            ep_struct_ptr= (USB_EP_STRUCT*) &ep_desc_data->ep[count];
            component = (uint_8)(ep_struct_ptr->ep_num | 
                (ep_struct_ptr->direction << COMPONENT_PREPARE_SHIFT));
            (void)_usb_device_init_endpoint(devicePtr->handle, ep_struct_ptr, TRUE);
        
            /* register callback service for endpoint 1 */
            (void)_usb_device_register_service(devicePtr->handle,
                (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num), 
                USB_Service_Hid, arg);
            /* set the EndPoint Status as Idle in the device layer */
            /* (no need to specify direction for this case) */
            (void)_usb_device_set_status(devicePtr->handle,
                  (uint_8)(USB_STATUS_ENDPOINT|component),
                  (uint_16)USB_STATUS_IDLE);                                                                                                         
            count++;                                                    
        }    
    }
    else if(event == USB_APP_BUS_RESET) 
    {
        /* clear producer and consumer */        
        for(index = 0; index < devicePtr->hid_endpoint_data.count; index++) 
        {                  
            devicePtr->hid_endpoint_data.ep[index].bin_consumer = 0x00;         
            devicePtr->hid_endpoint_data.ep[index].bin_producer = 0x00;        
        }
    }
        
    if(devicePtr->hid_class_callback.callback != NULL)
    {
        devicePtr->hid_class_callback.callback(event,val,
        devicePtr->hid_class_callback.arg);
    }
}

/**************************************************************************//*!
 *
 * @name  USB_HID_Other_Requests
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param handle:
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_HID_Other_Requests(USB_SETUP_STRUCT * setup_packet, 
                          uint_8_ptr *data, 
                          uint_32 *size,
                          pointer arg) 
{    
    uint_8 index;
    uint_8 error = USBERR_INVALID_REQ_TYPE;
    HID_DEVICE_STRUCT_PTR  devicePtr;
    /* buffer to send in case of get report req */
    uint_8 rpt_buf[REPORT_SIZE];
    
    *((uint_32_ptr)rpt_buf) = 0;
    
    /*Get the device pointer to which this callback corresponds.*/
    devicePtr = (HID_DEVICE_STRUCT_PTR)arg;
    
    if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
                                                      USB_REQUEST_CLASS_CLASS) 
    {  
       /* class request so handle it here */
       /* index == 0 for get/set idle, index == 1 for get/set protocol */      
        index = (uint_8)((setup_packet->request - 2) & (USB_HID_REQUEST_TYPE_MASK)); 
       
        error = USB_OK;
        
        /* point to the data which comes after the setup packet */
        *data = ((uint_8*)setup_packet) + USB_SETUP_PKT_SIZE;
        *size = 0;
        /* handle the class request */                                                                                                                                                         
        switch(setup_packet->request) 
        {
            case USB_HID_GET_REPORT_REQUEST :
                /*set the data pointer to the buffer to send */            
                *data = &rpt_buf[0];
                if(*size > REPORT_SIZE) *size = REPORT_SIZE;
                break;                                        
            
            case USB_HID_SET_REPORT_REQUEST :
                for(index = 0; index < REPORT_SIZE; index++) 
                {   /* copy the data sent by host in the buffer */          
                    rpt_buf[index] = *(*data + index);
                }                        
                break;
                
            case USB_HID_GET_IDLE_REQUEST :
                /* point to the current idle rate */
                *data = &devicePtr->class_request_params[index];
                *size = CLASS_REQ_DATA_SIZE;
                break;
                
            case USB_HID_SET_IDLE_REQUEST :
                /* set the idle rate sent by the host */
                devicePtr->class_request_params[index] =
                (uint_8)((setup_packet->value & MSB_MASK) >> HIGH_BYTE_SHIFT);
                break;
                
            case USB_HID_GET_PROTOCOL_REQUEST :
                /* point to the current protocol code 
                   0 = Boot Protocol
                   1 = Report Protocol*/
                *data = &devicePtr->class_request_params[index];
                *size = CLASS_REQ_DATA_SIZE;
                break;
                
            case USB_HID_SET_PROTOCOL_REQUEST :
                /* set the protocol sent by the host 
                  0 = Boot Protocol
                  1 = Report Protocol*/
                devicePtr->class_request_params[index] = 
                (uint_8)(setup_packet->value);              
                break;
        }
        if(devicePtr->param_callback.callback != NULL) 
        {  
          /* handle callback if the application has supplied it */
          /* set the size of the transfer from the setup packet */  
            *size = setup_packet->length; 
                
          /* notify the application of the class request.*/
          /* give control to the application */
           error = devicePtr->param_callback.callback(
                                      /* request type */ 
                                      setup_packet->request,
                                      setup_packet->value, 
                                      /* pointer to the data */      
                                      data,
                                      /* size of the transfer */                                    
                                      size,devicePtr->param_callback.arg);
        }
    } 
    else if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
                                                     USB_REQUEST_CLASS_VENDOR) 
    {   /* vendor specific request  */    
        if(devicePtr->vendor_req_callback.callback != NULL) 
        {
            error = devicePtr->vendor_req_callback.callback(setup_packet,
            data,size,devicePtr->vendor_req_callback.arg);
        }
    } 
 
    return error;
}

/*****************************************************************************
 * Global Functions
 *****************************************************************************/


/**************************************************************************//*!
 *
 * @name  USB_Class_HID_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param *handle: handle pointer to Identify the controller
 * @param hid_class_callback:   event callback      
 * @param vendor_req_callback:  vendor specific class request callback      
 * @param param_callback:       application params callback      
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the HID Class layer and layers it is dependent on 
 *
 *****************************************************************************/
HID_HANDLE USB_Class_HID_Init(
   HID_CONFIG_STRUCT_PTR hid_config_ptr                               
) 
{
    uint_8 index;
    uint_8 error;
    HID_HANDLE           hidHandle;
    HID_DEVICE_STRUCT_PTR  devicePtr = NULL;
    
    if (NULL == hid_config_ptr)
    {
        return USBERR_ERROR;    
    }
    
    
    devicePtr = (HID_DEVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(HID_DEVICE_STRUCT));
    if (NULL == devicePtr)
    {
        #if _DEBUG
            printf("USB_Class_HID_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }

    hidHandle = USB_Hid_Allocate_Handle();
    if (USBERR_DEVICE_BUSY == hidHandle) 
    {
        USB_mem_free(devicePtr);
        devicePtr = NULL;
        return USBERR_INIT_FAILED;
    }
 
    /* Initialize the device layer*/
    error = _usb_device_init(USBCFG_DEFAULT_DEVICE_CONTROLLER, &(devicePtr->handle), 
        (uint_8)(hid_config_ptr->ep_desc_data->count+1));
    if(error != USB_OK)
    {
      goto error1;  
    }

   hid_config_ptr->desc_callback_ptr->handle = hidHandle;
   /* Initialize the generic class functions */
   devicePtr->class_handle = USB_Class_Init(devicePtr->handle,
   USB_Class_Hid_Event,USB_HID_Other_Requests,(void *)devicePtr,
                             hid_config_ptr->desc_callback_ptr);
   if(error != USB_OK)
   {
      goto error2;  
   }
                                                        
   devicePtr->ep_desc_data =  hid_config_ptr->ep_desc_data;
   devicePtr->hid_endpoint_data.count = hid_config_ptr->ep_desc_data->count;
   devicePtr->hid_endpoint_data.ep = hid_config_ptr->ep;
        
   for(index = 0; index < hid_config_ptr->ep_desc_data->count; index++) 
   {            
      devicePtr->hid_endpoint_data.ep[index].endpoint = 
                                 hid_config_ptr->ep_desc_data->ep[index].ep_num;                                          
      devicePtr->hid_endpoint_data.ep[index].type = 
                                  hid_config_ptr->ep_desc_data->ep[index].type;
      devicePtr->hid_endpoint_data.ep[index].bin_consumer = 0x00;         
      devicePtr->hid_endpoint_data.ep[index].bin_producer = 0x00;        
    }
        
  /* save the callback pointer */
  USB_mem_copy(&hid_config_ptr->hid_class_callback,
  &devicePtr->hid_class_callback,sizeof(USB_CLASS_CALLBACK_STRUCT));           

  /* save the callback pointer */
  USB_mem_copy(&hid_config_ptr->vendor_req_callback,
  &devicePtr->vendor_req_callback,sizeof(USB_REQ_CALLBACK_STRUCT));        
  
  /* Save the callback to ask application for class specific params*/
  USB_mem_copy(&hid_config_ptr->param_callback,
  &devicePtr->param_callback.callback ,sizeof(USB_REQ_CALLBACK_STRUCT));                    
  
  
  devicePtr->user_handle = hidHandle;       
  device_array[hidHandle] = devicePtr;
  
  return USB_OK;
  
  error2:
     /* TBD:Implement _usb_device_deinit and call here*/
  error1: 
     USB_Hid_Free_Handle(hidHandle);
     USB_mem_free(devicePtr);
     devicePtr = NULL;
  return error;     
}

/**************************************************************************//*!
 *
 * @name  USB_Class_HID_Send_Data
 *
 * @brief 
 *
 * @param handle          :   handle returned by USB_Class_HID_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
uint_8 USB_Class_HID_Send_Data(
                                HID_HANDLE handle,/*[IN]*/
                                uint_8 ep_num,/*[IN]*/
                                uint_8_ptr app_buff,/*[IN]*/
                                uint_32 size /*[IN]*/
                               ) 
{
    uint_8 index;
    uint_8 producer, consumer;
    uint_8 error = USB_OK;
    HID_DEVICE_STRUCT_PTR  devicePtr;
    USB_ENDPOINTS *ep_desc_data;    
       
    if (/*(handle < 0) || */ (handle > MAX_HID_DEVICE))
        return USBERR_ERROR;
        
    devicePtr = USB_Hid_Get_Device_Ptr(handle);
    if (NULL == devicePtr)
    {
        return USBERR_NO_DEVICE_CLASS;
    }
    ep_desc_data = devicePtr->ep_desc_data; 
    
     /* map the endpoint num to the index of the endpoint structure */
    index = HID_USB_Map_Ep_To_Struct_Index(devicePtr, ep_num); 
   
    producer = devicePtr->hid_endpoint_data.ep[index].bin_producer;
    consumer = devicePtr->hid_endpoint_data.ep[index].bin_consumer;

    if((uint_8)(producer - consumer) != (uint_8)(HID_MAX_QUEUE_ELEMS))  
    {/* the bin is not full*/
    
        uint_8 queue_num = (uint_8)(producer % HID_MAX_QUEUE_ELEMS);
        /* put all send request parameters in the endpoint data structure */
        devicePtr->hid_endpoint_data.ep[index].queue[queue_num].channel = ep_num;
        devicePtr->hid_endpoint_data.ep[index].queue[queue_num].app_buff = app_buff;
        devicePtr->hid_endpoint_data.ep[index].queue[queue_num].size = size; 
        devicePtr->hid_endpoint_data.ep[index].queue[queue_num].handle = devicePtr->handle;
   
        /* increment producer bin by 1*/       
        devicePtr->hid_endpoint_data.ep[index].bin_producer++;
        producer++;
             
        if((uint_8)(producer - consumer) == (uint_8)1)         
        {   
            /*send the IO if there is only one element in the queue */          
            error = USB_Class_Send_Data(devicePtr->class_handle, ep_num, app_buff,size);
        }        
    }
    else /* bin is full */
    {
        error = USBERR_DEVICE_BUSY; 
    }
    
    return error;
}
#endif /*HID_CONFIG*/
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/mqx_inc.h<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* $FileName: mqx_inc.h$
* $Version : 3.8.6.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains include statements for all header files
*   required when compiling the kernel.
*
*END*************************************************************************/

#ifndef __mqx_inc_h__
#define __mqx_inc_h__

#ifdef MQX_REDUCE_DEBUG /* CR1446 & CR1434 */
#if defined(__HIGHC__) && !defined(MQX_CRIPPLED_EVALUATION)
   /* Minimize symbolic debug info when MetaWare compiler */
#  pragma on(nodebug)
# endif
#endif

/*
** These are the 'MQX' include files
*/
#include "mqx.h"
#include "mqx_ioc.h"
#include "psp.h"
#include <psp_comp.h>
#include "mem_prv.h"
#include "mqx_prv.h"
#include "psp_prv.h"
#include "psp_abi.h"

#ifdef MQX_REDUCE_DEBUG /* CR1446 & CR1434 */
# if defined(__HIGHC__) && !defined(MQX_CRIPPLED_EVALUATION)
   /* Minimize symbolic debug info when MetaWare compiler */
#  pragma pop(nodebug)
# endif
#endif

#if MQX_KERNEL_LOGGING
#include "lwlog.h"
#include "klog.h"
#endif
#if MQX_USE_LWMEM_ALLOCATOR
#ifndef __MEMORY_MANAGER_COMPILE__
#include "lwmem_prv.h"
#endif
#endif

#endif /* __mqx_inc_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/kadc/adc_kadc.c<|end_filename|>
/**HEADER***********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
********************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************
*
* $FileName: adc_kadc.c$
* $Version : 3.8.15.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the ADC driver CPU specific functions
*
*END***************************************************************************/

#include <mqx.h>

#include <bsp.h>
#include "adc_conf.h"
#include "adc_prv.h"
#include "adc_kadc_prv.h"

/* Declarations of IRQ handlers */
static void adc_complete_isr(pointer);

/* static variables for ADC driver */
static struct {
    /* Mask for used channels- each ADC module reserves ADC_CHANNELS_PER_ADC bits
    ** in this 32-bits longword, starting with least significant bits reserved
    ** for ADC0.
    */
    uint_32  used_channel;  /* mask of used channels */
    ADC_CHANNEL_BUNDLE_PTR open_channels[ADC_CHANNELS_PER_ADC][ADC_MAX_MODULES];
} adc_internal = { 0 };

ADC_BUNDLE adc_bundle;

static _mqx_int adc_set_calibration_data(_mqx_int adc_num, KADC_CALIB_STRUCT_PTR calib_ptr);
static _mqx_int adc_get_calibration_data(_mqx_int adc_num, KADC_CALIB_STRUCT_PTR calib_ptr);
static _mqx_int adc_calibrate(_mqx_int adc_num);
static void adc_process_data(_mqx_int adc_num, _mqx_int ch_num);

/*FUNCTION**********************************************************************
*
* Function Name    : _adc_hw_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END***************************************************************************/
_mqx_int _adc_hw_ioctl(MQX_FILE_PTR f, _mqx_uint cmd, pointer param_ptr)
{
    ADC_MemMapPtr adc_ptr;
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    _mqx_int adc_num = adc_d_bundle->init->ADC_NUMBER;
    volatile uint32_t *status_reg;

    switch (cmd)
    {
        case ADC_IOCTL_CALIBRATE:
            /* calibrate ADC autonomously */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* cannot run calibration on channel */
            if ((adc_internal.used_channel >> (ADC_MAX_CHANNELS * adc_num)) & ((1 << ADC_MAX_CHANNELS) - 1))
                return ADC_ERROR_NONEMPTY; /* calibration can be run only if no channel of ADC is opened */
            return adc_calibrate(adc_num);

        case ADC_IOCTL_SET_CALIBRATION:
            /* set calibration values to ADC without performing calibration */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* cannot set calibration data on channel */
            return adc_set_calibration_data(adc_num, (KADC_CALIB_STRUCT_PTR) param_ptr);

        case ADC_IOCTL_GET_CALIBRATION:
            /* gets calibrated value */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* cannot get calibration data on channel */
            return adc_get_calibration_data(adc_num, (KADC_CALIB_STRUCT_PTR) param_ptr);

        case ADC_IOCTL_SET_LONG_SAMPLE:
            /* sets sampling time for ADC module for long; param_ptr = (uint_32) cycles - see ADLSMP in Reference Manual */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* long sample must be set on device file, not on channel file */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);

            adc_ptr->CFG2 &= ~ADC_CFG2_ADLSTS_MASK;
            if ((uint_32) param_ptr == 20)
                adc_ptr->CFG2 |= ADC_CFG2_ADLSTS_20;
            else if ((uint_32) param_ptr == 12)
                adc_ptr->CFG2 |= ADC_CFG2_ADLSTS_12;
            else if ((uint_32) param_ptr == 6)
                adc_ptr->CFG2 |= ADC_CFG2_ADLSTS_6;
            else if ((uint_32) param_ptr == 2)
                adc_ptr->CFG2 |= ADC_CFG2_ADLSTS_2;
            else
                return ADC_ERROR_BAD_PARAM; /* invalid parameter for ioctl command */

            adc_ptr->CFG1 |= ADC_CFG1_ADLSMP_MASK;
            break;

        case ADC_IOCTL_SET_SHORT_SAMPLE:
            /* sets sampling time for ADC module for short - see ADLSMP in Reference Manual */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* long sample must be set on device file, not on channel file */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);

            adc_ptr->CFG1 &= ~ADC_CFG1_ADLSMP_MASK;
            break;

        case ADC_IOCTL_SET_HIGH_SPEED:
            /* sets high speed ADC module - see ADHSC bit in Reference Manual */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* high speed must be set on device file, not on channel file */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);

            adc_ptr->CFG2 |= ADC_CFG2_ADHSC_MASK;
            break;

        case ADC_IOCTL_SET_LOW_SPEED:
            /* sets low speed ADC module - see ADHSC bit in Reference Manual */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* low speed must be set on device file, not on channel file */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);

            adc_ptr->CFG2 &= ~ADC_CFG2_ADHSC_MASK;
            break;

        case ADC_IOCTL_SET_HW_AVERAGING:
            /* sets sample averaging by hardware; param_ptr = (uint_32) cycles - see AVGE bit in Reference Manual */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* averaging must be set on device file, not on channel file */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);

            if ((uint_32) param_ptr == 0)
                adc_ptr->SC3 &= ~ADC_SC3_AVGE_MASK; /* if zero cycles, disable averaging */
            else {
                adc_ptr->SC3 &= ~ADC_SC3_AVGS_MASK;
                if ((uint_32) param_ptr == 32)
                    adc_ptr->SC3 |= ADC_SC3_AVGS_32 | ADC_SC3_AVGE_MASK | ADC_SC3_ADCO_MASK;
                else if ((uint_32) param_ptr == 16)
                    adc_ptr->SC3 |= ADC_SC3_AVGS_16 | ADC_SC3_AVGE_MASK | ADC_SC3_ADCO_MASK;
                else if ((uint_32) param_ptr == 8)
                    adc_ptr->SC3 |= ADC_SC3_AVGS_8 | ADC_SC3_AVGE_MASK | ADC_SC3_ADCO_MASK;
                else if ((uint_32) param_ptr == 4)
                    adc_ptr->SC3 |= ADC_SC3_AVGS_4 | ADC_SC3_AVGE_MASK | ADC_SC3_ADCO_MASK;
                else
                    return ADC_ERROR_BAD_PARAM; /* invalid parameter for ioctl command */
            }
            break;

        case ADC_IOCTL_SET_IDELAY_PROCESS:
            /* Postpones channel data processing */
            if (adc_ch_bundle == NULL)
                return ADC_ERROR_ONLY_CHANNEL; /* data processing can be postponed only on channel files */

            _int_disable();
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            status_reg = &adc_ptr->SC1[adc_ch_bundle->ch_num];
            /* Before writing to register to disable COCO channel :) interrupt, we have to check COCO bit;
            ** this is needed as any write to register will clear COCO bit.
            ** Question: what if COCO bit is set after it was checked for? Answer: no other way, we lose one sample...
            */
            while (*status_reg & ADC_SC1_COCO_MASK) {
                /* COCO bit is set, we have to read data before disabling interrupts */
                adc_process_data(adc_num, adc_ch_bundle->ch_num);
            }
            *status_reg &= ~ADC_SC1_AIEN_MASK; /* disable interrupts, this also clears COCO bit */
            adc_bundle.late_process |= (1 << (ADC_MAX_CHANNELS * adc_num + adc_ch_bundle->ch_num));
            _int_enable();
            break;

        case ADC_IOCTL_SET_INT_PROCESS:
            /* Postpones channel data processing */
            if (adc_ch_bundle == NULL)
                return ADC_ERROR_ONLY_CHANNEL; /* data processing can be postponed only on channel files */

            _int_disable();
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            status_reg = &adc_ptr->SC1[adc_ch_bundle->ch_num];
            /* Before writing to register to disable COCO channel :) interrupt, we have to check COCO bit;
            ** this is needed as any write to register will clear COCO bit.
            ** Question: what if COCO bit is set after it was checked for? Answer: no other way, we lose one sample...
            */
            while (*status_reg & ADC_SC1_COCO_MASK) {
                /* COCO bit is set, we have to read data before disabling interrupts */
                adc_process_data(adc_num, adc_ch_bundle->ch_num);
            }
            *status_reg |= ADC_SC1_AIEN_MASK; /* enable interrupts, this also clears COCO bit */
            adc_bundle.late_process &= ~(1 << (ADC_MAX_CHANNELS * adc_num + adc_ch_bundle->ch_num));
            _int_enable();
            break;

        case ADC_IOCTL_SET_OFFSET: {
            uint_32 uparam_32 = (uint_32) param_ptr;
            uint_16 uparam_16 = (uint_16) uparam_32;

            /* Set offset for ADC module */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* Offset cannot be set on channel files */
            if (uparam_32 > MAX_UINT_16)
                return ADC_ERROR_BAD_PARAM; /* Cannot set offset that exceeds 16 bits */

            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            adc_ptr->OFS = uparam_16;
            break;
        }

        case ADC_IOCTL_SET_PLUS_GAIN: {
            uint_32 uparam_32 = (uint_32) param_ptr;
            uint_16 uparam_16 = (uint_16) uparam_32;

            /* Set offset for ADC module */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* Gain cannot be set on channel files */
            if (uparam_32 > MAX_UINT_16)
                return ADC_ERROR_BAD_PARAM; /* Cannot set gain that exceeds 16 bits */

            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            adc_ptr->PG = uparam_16;
            break;
        }
#if ADC_HAS_DIFFERENTIAL_CHANNELS
        case ADC_IOCTL_SET_MINUS_GAIN: {
            uint_32 uparam_32 = (uint_32) param_ptr;
            uint_16 uparam_16 = (uint_16) uparam_32;

            /* Set offset for ADC module */
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* Gain cannot be set on channel files */
            if (uparam_32 > MAX_UINT_16)
                return ADC_ERROR_BAD_PARAM; /* Cannot set gain that exceeds 16 bits */

            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            adc_ptr->MG = uparam_16;
            break;
        }
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */
        case ADC_IOCTL_SET_REFERENCE: {
            if (adc_ch_bundle != NULL)
                return ADC_ERROR_ONLY_DEVICE; /* Gain cannot be set on channel files */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            adc_ptr->SC2 &= ~ADC_SC2_REFSEL_MASK;
            if ((uint_32) param_ptr == ADC_REF_VREF)
                adc_ptr->SC2 |= ADC_SC2_REFSEL_VREF;
            else if ((uint_32) param_ptr == ADC_REF_VALT)
                adc_ptr->SC2 |= ADC_SC2_REFSEL_VALT;
            else if ((uint_32) param_ptr == ADC_REF_VBG)
                adc_ptr->SC2 |= ADC_SC2_REFSEL_VBG;
            else
                return ADC_ERROR_BAD_PARAM; /* Cannot set any other reference */
            break;
        }
#if ADC_HAS_PGA
        case ADC_IOCTL_SET_PGA_GAIN:
            if (adc_ch_bundle == NULL)
                return ADC_ERROR_ONLY_CHANNEL; /* Gain cannot be set on device files */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            if (ADC_GET_CHANNEL(adc_ch_bundle->adc_ch->g.source) != ADC_SOURCE_CHANNEL(2))
                return ADC_ERROR_NOT_SUPPORTED;
            adc_ptr->PGA &= ~ADC_PGA_PGAG_MASK; /* zero the PGAG field */
            adc_ptr->PGA |= (uint_32) param_ptr | 0x00100000 | ADC_PGA_PGAEN_MASK; /* ADC_PGA_PGALP_MASK parameter follows register structure, enable PGA */
            break;

        case ADC_IOCTL_GET_PGA_GAIN: {
            uint_32 *param32_ptr = param_ptr;

            if (param32_ptr == NULL)
                return ADC_ERROR_PARAM; /* Missing pointer parameter where to store result */
            if (adc_ch_bundle == NULL)
                return ADC_ERROR_ONLY_CHANNEL; /* Gain cannot be set on device files */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            if (ADC_GET_CHANNEL(adc_ch_bundle->adc_ch->g.source) != ADC_SOURCE_CHANNEL(2))
                return ADC_ERROR_NOT_SUPPORTED;
            *param32_ptr = adc_ptr->PGA & ADC_PGA_PGAG_MASK;
            break;
        }

        case ADC_IOCTL_ENABLE_CHOPPING:
            if (adc_ch_bundle == NULL)
                return ADC_ERROR_ONLY_CHANNEL; /* Gain cannot be set on device files */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            if (ADC_GET_CHANNEL(adc_ch_bundle->adc_ch->g.source) != ADC_SOURCE_CHANNEL(2))
                return ADC_ERROR_NOT_SUPPORTED;
            adc_ptr->PGA |= 0x00200000; //ADC_PGA_PGACHP_MASK; /* enable chopping on PGA */
            break;

        case ADC_IOCTL_DISABLE_CHOPPING:
            if (adc_ch_bundle == NULL)
                return ADC_ERROR_ONLY_CHANNEL; /* Gain cannot be set on device files */
            adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
            if (ADC_GET_CHANNEL(adc_ch_bundle->adc_ch->g.source) != ADC_SOURCE_CHANNEL(2))
                return ADC_ERROR_NOT_SUPPORTED;
            adc_ptr->PGA &= ~0x00200000; //~ADC_PGA_PGACHP_MASK; /* enable chopping on PGA */
            break;
#endif /* ADC_HAS_PGA */

        default:
            return IO_ERROR_INVALID_IOCTL_CMD;
    }

    return ADC_OK;
}

/*FUNCTION**********************************************************************
*
* Function Name    : _adc_hw_install
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific initialization for ADC driver
*
*END***************************************************************************/
_mqx_int _adc_hw_install(char_ptr identifier, ADC_DRIVER_BUNDLE_PTR adc_d_bundle, pointer init)
{
    adc_d_bundle->init = (KADC_INIT_STRUCT_PTR) init;

#if PE_LDD_VERSION
    if (PE_PeripheralUsed((uint_32)_bsp_get_adc_base_address(adc_d_bundle->init->ADC_NUMBER)))
    {
        return IO_ERROR;
    }
#endif

    return ADC_OK;
}

/*FUNCTION**********************************************************************
*
* Function Name    : _adc_hw_init
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific initialization for ADC driver
*
*END***************************************************************************/
_mqx_int _adc_hw_init(MQX_FILE_PTR f, ADC_PTR adc_d)
{
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    _mqx_int adc_num = adc_d_bundle->init->ADC_NUMBER;
    ADC_MemMapPtr adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
    uint_32 adc_max_frq;
    uint_8  adc_max_frq_index;

    /* This table is made from datasheet values for ADC module in Kinetis */
    const static uint_32 adc_max_frq_table[] = {
        2500000,  /* 2.5 MHz  for low power,    normal speed, 16b resolution */
        5000000,  /* 5.0 MHz  for low power,    normal speed, lower resolution */
        5000000,  /* 5.0 MHz  for low power,    high speed,   16b resolution */
        8000000,  /* 8.0 MHz  for low power,    high speed,   lower resolution */
        8000000,  /* 8.0 MHz  for normal power, normal speed, 16b resolution */
        12000000, /* 12.0 MHz for normal power, normal speed, lower resolution */
        12000000, /* 12.0 MHz for normal power, high speed,   16b resolution */
        18000000, /* 18.0 MHz for normal power, high speed,   lower resolution */
    };

    if (adc_ptr == NULL) {
        return IO_ERROR; /* Cannot find specific ADC module */
    }

    /* First, use 3 bit mask to create index to the max. frq. table */
    adc_max_frq_index = 0;
    switch (adc_d->g.resolution) {
        case ADC_RESOLUTION_16BIT:
            break;
        case ADC_RESOLUTION_12BIT:
        case ADC_RESOLUTION_10BIT:
        case ADC_RESOLUTION_8BIT:
            adc_max_frq_index |= 0x01;
            break;
        default:
            return ADC_ERROR_BAD_PARAM; /* bad resolution set */
    }
    if (adc_d_bundle->init->SPEED == ADC_HSC_HIGH)
        adc_max_frq_index |= 0x02;
    if (adc_d_bundle->init->POWER == ADC_LPC_NORMAL)
        adc_max_frq_index |= 0x04;
    adc_max_frq = adc_max_frq_table[adc_max_frq_index];

    (void) _bsp_adc_io_init(adc_num);

    /* set AD clock to be as fast as possible */
    switch (adc_d_bundle->init->CLOCK_SOURCE) {
        case ADC_CLK_BUSCLK_ANY:
            if (adc_d_bundle->init->CLOCK_DIV == ADC_DIV_ANY) {
                if(BSP_BUS_CLOCK <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_1 | ADC_CFG1_ADICLK_BUSCLK;
                else if ((BSP_BUS_CLOCK / 2) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_2 | ADC_CFG1_ADICLK_BUSCLK;
                else if ((BSP_BUS_CLOCK / 4) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_4 | ADC_CFG1_ADICLK_BUSCLK;
                else if ((BSP_BUS_CLOCK / 8) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_8 | ADC_CFG1_ADICLK_BUSCLK;
                else if ((BSP_BUS_CLOCK / 16) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_8 | ADC_CFG1_ADICLK_BUSCLK2;
                else
                    return ADC_ERROR_BAD_PARAM; /* cannot set ADC clock to be less than adc_max_frq */
            }
            else {
                if ((BSP_BUS_CLOCK / (1 << adc_d_bundle->init->CLOCK_DIV)) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV(adc_d_bundle->init->CLOCK_DIV) | ADC_CFG1_ADICLK_BUSCLK;
                else if ((BSP_BUS_CLOCK / 2 / (1 << adc_d_bundle->init->CLOCK_DIV)) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV(adc_d_bundle->init->CLOCK_DIV) | ADC_CFG1_ADICLK_BUSCLK2;
                else
                    return ADC_ERROR_BAD_PARAM; /* such clock combination is too fast for ADC */
            }
            break;

        case ADC_CLK_BUSCLK:
            if (adc_d_bundle->init->CLOCK_DIV == ADC_DIV_ANY) {
                if (BSP_BUS_CLOCK <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_1 | ADC_CFG1_ADICLK_BUSCLK;
                else if ((BSP_BUS_CLOCK / 2) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_2 | ADC_CFG1_ADICLK_BUSCLK;
                else if ((BSP_BUS_CLOCK / 4) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_4 | ADC_CFG1_ADICLK_BUSCLK;
                else if ((BSP_BUS_CLOCK / 8) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_8 | ADC_CFG1_ADICLK_BUSCLK;
                else
                    return ADC_ERROR_BAD_PARAM; /* cannot set ADC clock to be less than ADC max. frequency */
            }
            else if ((BSP_BUS_CLOCK / (1 << adc_d_bundle->init->CLOCK_DIV)) <= adc_max_frq)
                adc_ptr->CFG1 = ADC_CFG1_ADIV(adc_d_bundle->init->CLOCK_DIV) | ADC_CFG1_ADICLK_BUSCLK;
            else
                return ADC_ERROR_BAD_PARAM; /* such clock combination is too fast for ADC */
            break;

        case ADC_CLK_BUSCLK2:
            if (adc_d_bundle->init->CLOCK_DIV == ADC_DIV_ANY) {
                if ((BSP_BUS_CLOCK / 16) <= adc_max_frq)
                    adc_ptr->CFG1 = ADC_CFG1_ADIV_8 | ADC_CFG1_ADICLK_BUSCLK2;
                if ((BSP_BUS_CLOCK / 16) <= adc_max_frq)
                    return ADC_ERROR_BAD_PARAM; /* cannot set ADC clock to be less than ADC max. frequency */
            }
            else if ((BSP_BUS_CLOCK / 2 / (1 << adc_d_bundle->init->CLOCK_DIV)) <= adc_max_frq)
                adc_ptr->CFG1 = ADC_CFG1_ADIV(adc_d_bundle->init->CLOCK_DIV) | ADC_CFG1_ADICLK_BUSCLK2;
            else
                return ADC_ERROR_BAD_PARAM; /* such clock combination is too fast for ADC */
            break;

        case ADC_CLK_ALTERNATE:
            if (adc_d_bundle->init->CLOCK_DIV == ADC_DIV_ANY)
                return ADC_ERROR_BAD_PARAM; /* alternate clock + any division is not supported now */
            adc_ptr->CFG1 = ADC_CFG1_ADIV(adc_d_bundle->init->CLOCK_DIV) | ADC_CFG1_ADICLK_ALTCLK;
            break;

        case ADC_CLK_ASYNC:
            if (adc_d_bundle->init->CLOCK_DIV == ADC_DIV_ANY)
                return ADC_ERROR_BAD_PARAM; /* async clock + any division is not supported now */
            adc_ptr->CFG1 = ADC_CFG1_ADIV(adc_d_bundle->init->CLOCK_DIV) | ADC_CFG1_ADICLK_ADACK;
            break;

        default:
            return ADC_ERROR_BAD_PARAM; /* invalid clock source */
    }

    adc_ptr->CFG1 |= adc_d->g.resolution;

    adc_ptr->SC2 |= ADC_SC2_ADTRG_MASK; /* set HW trigger */

    adc_d->old_isr_data = (pointer) _int_get_isr_data(adc_d_bundle->init->ADC_VECTOR);
    adc_d->old_isr = _int_install_isr(adc_d_bundle->init->ADC_VECTOR, adc_complete_isr, f);
    /* Enable interrupt in NVIC */
    _bsp_int_init(adc_d_bundle->init->ADC_VECTOR, adc_d_bundle->init->ADC_PRIORITY, 0, TRUE);

    return ADC_OK;
}

/*FUNCTION**********************************************************************
*
* Function Name    : _adc_hw_deinit
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific deinitialization for ADC driver
*
*END***************************************************************************/
_mqx_int _adc_hw_deinit(MQX_FILE_PTR f, ADC_PTR adc_d)
{
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;

    _int_install_isr(adc_d_bundle->init->ADC_VECTOR, adc_d->old_isr, adc_d->old_isr_data);

    return ADC_OK;
}

/*FUNCTION**********************************************************************
*
* Function Name    : _adc_cpu_channel_init
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END***************************************************************************/
_mqx_int _adc_hw_channel_init(MQX_FILE_PTR f, ADC_CHANNEL_PTR adc_ch)
{
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    _mqx_int adc_num = adc_d_bundle->init->ADC_NUMBER;
    _mqx_int ch_num;
    ADC_MemMapPtr adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);
    _mqx_uint used_ch = adc_internal.used_channel >> (ADC_MAX_CHANNELS * adc_num);
    uint32_t source_reg;

    adc_ch->b = adc_ch_bundle;

    source_reg = (uint32_t) ADC_GET_CHANNEL(adc_ch->g.source);
#if ADC_HAS_DIFFERENTIAL_CHANNELS
    if (ADC_GET_DIFF(adc_ch->g.source))
        source_reg |= ADC_SC1_DIFF_MASK;
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */
    source_reg |= ADC_SC1_AIEN_MASK;

    for (ch_num = 0; ch_num < ADC_CHANNELS_PER_ADC; ch_num++)
        if (!(used_ch & (1 << ch_num)))
            /* channel is free, use it */
            break;
    if (ch_num == ADC_CHANNELS_PER_ADC)
        return ADC_ERROR_FULL; /* all channels are used, no more allowed; shouldn't happen */

    adc_ptr->SC1[ch_num] = source_reg;

    adc_ch_bundle->adc_num = adc_num;
    adc_ch_bundle->ch_num = ch_num;
    adc_internal.used_channel |= 0x01 << (ADC_MAX_CHANNELS * adc_num + ch_num);

    adc_internal.open_channels[ch_num][adc_num] = adc_ch_bundle;

    /* Test if needed module for this source is the one opened */
    if ((ADC_SOURCE_MODULE_ANY != (ADC_GET_MODULE(adc_ch->g.source) >> ADC_SOURCE_MODULE_SHIFT)) \
        && ((adc_num + 1) != (ADC_GET_MODULE(adc_ch->g.source) >> ADC_SOURCE_MODULE_SHIFT)))
        return IO_ERROR; /* cannot assign the source to this ADC module */

    /* Test if muxsel was not selected yet or is the same as selected */
    if ((0 == adc_d_bundle->adc->muxsel) \
        || (ADC_GET_MUXSEL(adc_ch->g.source) == ((uint_16) adc_d_bundle->adc->muxsel << ADC_SOURCE_MUXSEL_SHIFT)))
    {
        _mqx_int status = _bsp_adc_channel_io_init(adc_ch->g.source);
        if (IO_OK == status) {
            if (0 == adc_d_bundle->adc->muxsel)
                adc_d_bundle->adc->muxsel = ADC_GET_MUXSEL(adc_ch->g.source) >> ADC_SOURCE_MUXSEL_SHIFT;
#if PSP_MQX_CPU_IS_KINETIS
            if (1 == adc_d_bundle->adc->muxsel) {
                /* channel A selected */
                adc_ptr->CFG2 &= ~ADC_CFG2_MUXSEL_MASK;
            }
            else if (2 == adc_d_bundle->adc->muxsel) {
                /* channel B selected */
                adc_ptr->CFG2 |= ADC_CFG2_MUXSEL_MASK;
            }
#endif /* PSP_CPU_IS_KINETIS */
#if ADC_HAS_PGA
            if (2 == ADC_GET_CHANNEL(adc_ch->g.source))
                adc_ptr->PGA = (uint_32) ADC_PGA_PGAG(0) | 0x00100000 | ADC_PGA_PGAEN_MASK; /* on channel 2, switch on PGA */
#endif /* ADC_HAS_PGA */
        }
        return status;
    }
    else
        return IO_ERROR; /* cannot set this multiplexer as opposite A/B muxsel was already selected on module */
}

/*FUNCTION**********************************************************************
*
* Function Name    : _adc_hw_channel_deinit
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific deinitialization for ADC channel
*
*END***************************************************************************/
_mqx_int _adc_hw_channel_deinit(MQX_FILE_PTR f, ADC_CHANNEL_PTR adc_ch)
{
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    _mqx_int adc_num = adc_ch_bundle->adc_num;
    _mqx_int ch_num = adc_ch_bundle->ch_num;
    ADC_MemMapPtr adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);

    /* deinit channel */
    _int_disable();
    adc_ptr->SC1[ch_num] = ADC_SC1_ADCH_DISABLED;
    adc_bundle.late_process &= ~(0x01 << (ADC_MAX_CHANNELS * adc_num + ch_num));
    _int_enable();

    adc_internal.used_channel &= ~(0x01 << (ADC_MAX_CHANNELS * adc_num + ch_num));
    adc_internal.open_channels[ch_num][adc_num] = NULL;

    return ADC_OK;
}

/*FUNCTION**********************************************************************
*
* Function Name    : adc_process_data
* Returned Value   : void
* Comments         : Process data result for specific channel
*
*END***************************************************************************/
static void adc_process_data(_mqx_int adc_num, _mqx_int ch_num)
{
    ADC_CHANNEL_PTR        adc_ch;
    ADT_CHANNEL_PTR        adt_ch;
    ADC_MemMapPtr adc_ptr;
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle;

    adc_ptr = (ADC_MemMapPtr) _bsp_get_adc_base_address(adc_num);

    if (!(adc_ptr->SC1[ch_num] & ADC_SC1_COCO_MASK))
        return; /* conversion was not completed on this channel */

    adc_ch_bundle = adc_internal.open_channels[ch_num][adc_num];
    adc_ch = adc_ch_bundle->adc_ch;

    if (adc_ch_bundle->periods != 0) {
        volatile uint_32 dummy_read;
        /* dummy read to clear interrupt flag */
        dummy_read = adc_ptr->R[ch_num];
        adc_ch_bundle->periods--;
    } else {
        adc_ch_bundle->periods = adc_ch_bundle->periods_preset - 1;

        if (adc_ch->g.init_flags & ADC_CHANNEL_ACCUMULATE)
            /* if the channel has ADC_CHANNEL_ACCUMULATE, then accumulate result */
            adc_ch->g.buffer_driver->result += adc_ptr->R[ch_num];
        else
            /* else copy the result to the channel buffer */
            adc_ch->g.buffer_driver->result = adc_ptr->R[ch_num];

        adt_ch = adc_ch_bundle->adt_ch;
        if (!(adc_ch->g.init_flags & ADC_CHANNEL_ACCUMULATE) || !(adt_ch->g.samples)) {
            /* move driver pointer to next index, circularly */
            if (++adc_ch->g.buffer_driver >= adc_ch->g.buffer_end)
                adc_ch->g.buffer_driver = adc_ch->g.buffer_start;
            /* if new value should overwrite old value in ring buffer, move read pointer to next value */
            if (adc_ch->g.buffer_driver == adc_ch->g.buffer_task) {
                if (++adc_ch->g.buffer_task >= adc_ch->g.buffer_end)
                    adc_ch->g.buffer_task = adc_ch->g.buffer_start;
            }
        }
        _adt_process_data(adc_ch_bundle);
    }
}

/*FUNCTION**********************************************************************
*
* Function Name    : adc_process_all_data
* Returned Value   : void
* Comments         : Look at all channels and finds
*
*END***************************************************************************/
void adc_process_all_data(void)
{
    _mqx_int adc_num, ch_num;

    /* conversion done, but which channel? */
    for (adc_num = 0; adc_num < ADC_MAX_MODULES; adc_num++) {
        for (ch_num = 0; ch_num < ADC_MAX_CHANNELS; ch_num++) {
            if (adc_internal.open_channels[ch_num][adc_num] == NULL)
                continue;
            adc_process_data(adc_num, ch_num);
        }
    }
}

/*FUNCTION**********************************************************************
*
* Function Name    : adc_complete_isr
* Returned Value   : void
* Comments         : IRQ handler for completed AD conversion(s)
*
*END***************************************************************************/
void adc_complete_isr
(
      /* [IN] the file pointer */
      pointer param
)
{ /* Body */
    MQX_FILE_PTR f = (MQX_FILE_PTR) param;
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    _mqx_int adc_num = adc_d_bundle->init->ADC_NUMBER;
    _mqx_int ch_num;

    for (ch_num = 0; ch_num < ADC_MAX_CHANNELS; ch_num++) {
        adc_process_data(adc_num, ch_num);
    }
}

/*FUNCTION**********************************************************************
*
* Function Name    : adc_calibrate
* Returned Value   : ADC_OK or ADC_ERROR
* Comments         : Calibrates the ADC module
*
*END***************************************************************************/
static _mqx_int adc_calibrate(_mqx_int adc_index)
{
    uint_16 cal_var;
    ADC_MemMapPtr adc_ptr = _bsp_get_adc_base_address(adc_index);
    struct {
        uint_8  SC2;
        uint_8  SC3;
    } saved_regs;

    if (adc_ptr == NULL)
        return ADC_ERROR_BAD_PARAM; /* no such ADC peripheral exists */

    saved_regs.SC2 = adc_ptr->SC2;
    saved_regs.SC3 = adc_ptr->SC3;

    /* Enable Software Conversion Trigger for Calibration Process */
    adc_ptr->SC2 &= ~ADC_SC2_ADTRG_MASK;

    /* Initiate calibration */
    adc_ptr->SC3 |= ADC_SC3_CAL;

    /* Wait for conversion to complete */
    while (adc_ptr->SC2 & ADC_SC2_ADACT_MASK){}

    /* Check if calibration failed */
    if (adc_ptr->SC3 & ADC_SC3_CALF_MASK)  {
        /* Clear calibration failed flag */
        adc_ptr->SC3 |= ADC_SC3_CALF_MASK;

        /* calibration failed */
        return -1;
    }

    /* Calculate plus-side calibration values according
     * to Calibration function described in reference manual.   */
    /* 1. Initialize (clear) a 16b variable in RAM */
    cal_var  = 0x0000;
    /* 2. Add the following plus-side calibration results CLP0, CLP1,
     *    CLP2, CLP3, CLP4 and CLPS to the variable. */
    cal_var +=  adc_ptr->CLP0;
    cal_var +=  adc_ptr->CLP1;
    cal_var +=  adc_ptr->CLP2;
    cal_var +=  adc_ptr->CLP3;
    cal_var +=  adc_ptr->CLP4;
    cal_var +=  adc_ptr->CLPS;

    /* 3. Divide the variable by two. */
    cal_var = cal_var / 2;

    /* 4. Set the MSB of the variable. */
    cal_var += 0x8000;

    /* 5. Store the value in the plus-side gain calibration registers ADCPGH and ADCPGL. */
    adc_ptr->PG = cal_var;
#if ADC_HAS_DIFFERENTIAL_CHANNELS
    /* Repeat procedure for the minus-side gain calibration value. */
    /* 1. Initialize (clear) a 16b variable in RAM */
    cal_var  = 0x0000;

    /* 2. Add the following plus-side calibration results CLM0, CLM1,
     *    CLM2, CLM3, CLM4 and CLMS to the variable. */
    cal_var  = 0x0000;
    cal_var += adc_ptr->CLM0;
    cal_var += adc_ptr->CLM1;
    cal_var += adc_ptr->CLM2;
    cal_var += adc_ptr->CLM3;
    cal_var += adc_ptr->CLM4;
    cal_var += adc_ptr->CLMS;

    /* 3. Divide the variable by two. */
    cal_var = cal_var / 2;

    /* 4. Set the MSB of the variable. */
    cal_var += 0x8000;

    /* 5. Store the value in the minus-side gain calibration registers ADCMGH and ADCMGL. */
    adc_ptr->MG = cal_var;
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */
    /* Clear CAL bit */
    adc_ptr->SC3 = saved_regs.SC3;
    adc_ptr->SC2 = saved_regs.SC2;

    return ADC_OK;
}

/*FUNCTION**********************************************************************
*
* Function Name    : adc_get_calibration_data
* Returned Value   : ADC_OK or ADC_ERROR
* Comments         : Calibrates the ADC.
*    Gets (copies) calibrated data from ADC registers to memory
*
*END***************************************************************************/
static _mqx_int adc_get_calibration_data
(    /* ADC module index */
    _mqx_int                       adc_index,
    /* pointer to structure to read the calibration data */
    KADC_CALIB_STRUCT_PTR          calib_ptr
)
{
    ADC_MemMapPtr adc_ptr = _bsp_get_adc_base_address(adc_index);

    if (calib_ptr == NULL)
        return ADC_ERROR_PARAM; /* pointer to store calibration data to is NULL */
    if (adc_ptr == NULL)
        return ADC_ERROR_BAD_PARAM; /* no such ADC peripheral exists */

    calib_ptr->OFS  = adc_ptr->OFS;
#if ADC_HAS_DIFFERENTIAL_CHANNELS
    calib_ptr->PG   = adc_ptr->PG;
    calib_ptr->MG   = adc_ptr->MG;
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */
    calib_ptr->CLPD = adc_ptr->CLPD;
    calib_ptr->CLPS = adc_ptr->CLPS;
    calib_ptr->CLP4 = adc_ptr->CLP4;
    calib_ptr->CLP3 = adc_ptr->CLP3;
    calib_ptr->CLP2 = adc_ptr->CLP2;
    calib_ptr->CLP1 = adc_ptr->CLP1;
    calib_ptr->CLP0 = adc_ptr->CLP0;
#if ADC_HAS_DIFFERENTIAL_CHANNELS
    calib_ptr->CLMD = adc_ptr->CLMD;
    calib_ptr->CLMS = adc_ptr->CLMS;
    calib_ptr->CLM4 = adc_ptr->CLM4;
    calib_ptr->CLM3 = adc_ptr->CLM3;
    calib_ptr->CLM2 = adc_ptr->CLM2;
    calib_ptr->CLM1 = adc_ptr->CLM1;
    calib_ptr->CLM0 = adc_ptr->CLM0;
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */
    return ADC_OK;
}

/*FUNCTION**********************************************************************
*
* Function Name    : adc_set_calibration_data
* Returned Value   : ADC_OK or ADC_ERROR
* Comments         : Calibrates the ADC.
*    Sets directly calibration data to calibration registers
*
*END***************************************************************************/
static _mqx_int adc_set_calibration_data
(    /* ADC module index */
    _mqx_int                       adc_index,
    /* pointer to structure to read the calibration data */
    KADC_CALIB_STRUCT_PTR          calib_ptr
)
{
    ADC_MemMapPtr adc_ptr = _bsp_get_adc_base_address(adc_index);

    if (calib_ptr == NULL)
        return ADC_ERROR_PARAM; /* pointer to store calibration data to is NULL */
    if (adc_ptr == NULL)
        return ADC_ERROR_BAD_PARAM; /* no such ADC peripheral exists */

    adc_ptr->OFS  = calib_ptr->OFS;
#if ADC_HAS_DIFFERENTIAL_CHANNELS
    adc_ptr->PG   = calib_ptr->PG;
    adc_ptr->MG   = calib_ptr->MG;
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */
    adc_ptr->CLPD = calib_ptr->CLPD;
    adc_ptr->CLPS = calib_ptr->CLPS;
    adc_ptr->CLP4 = calib_ptr->CLP4;
    adc_ptr->CLP3 = calib_ptr->CLP3;
    adc_ptr->CLP2 = calib_ptr->CLP2;
    adc_ptr->CLP1 = calib_ptr->CLP1;
    adc_ptr->CLP0 = calib_ptr->CLP0;
#if ADC_HAS_DIFFERENTIAL_CHANNELS
    adc_ptr->CLMD = calib_ptr->CLMD;
    adc_ptr->CLMS = calib_ptr->CLMS;
    adc_ptr->CLM4 = calib_ptr->CLM4;
    adc_ptr->CLM3 = calib_ptr->CLM3;
    adc_ptr->CLM2 = calib_ptr->CLM2;
    adc_ptr->CLM1 = calib_ptr->CLM1;
    adc_ptr->CLM0 = calib_ptr->CLM0;
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */

    return ADC_OK;
}



<|start_filename|>Firmware/Inverter_firmware/shell/source/include/sh_rtcs.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_rtcs.h$
* $Version : 3.8.11.0$
* $Date    : Oct-1-2012$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#ifndef __sh_rtcs_h__
#define __sh_rtcs_h__

#include "ppp.h"

#define MAX_HOSTNAMESIZE     64


#define eaddrassign(p,x)   ((p)[0] = (x)[0], \
                            (p)[1] = (x)[1], \
                            (p)[2] = (x)[2], \
                            (p)[3] = (x)[3], \
                            (p)[4] = (x)[4], \
                            (p)[5] = (x)[5]  \
                           )

#define eaddriszero(p)   ( ((p)[0] == 0) && \
                           ((p)[1] == 0) && \
                           ((p)[2] == 0) && \
                           ((p)[3] == 0) && \
                           ((p)[4] == 0) && \
                           ((p)[5] == 0)    \
                          )

/*
** Function prototypes 
*/
#ifdef __cplusplus
extern "C" {
#endif

typedef struct shell_ppp_link { 
   char*           PPP_CONNECTION_DEVICE;   /* system device name, like "ittyd:" */
   MQX_FILE_PTR    PPP_CON_DEV_HANDLE;      /* Open serial device. */
   MQX_FILE_PTR    PPP_DEV_HANDLE;          /* Open our ppp driver on p_dev_file connection device. */
  _ppp_handle      PPP_HANDLE;              /* PPP connection handle. */
  _rtcs_if_handle  PPP_IF_HANDLE;           /* PPP interface. */
  _iopcb_handle    PPP_IO_DRIVER_HANDLE;    /* An iopcb driver. */
  _ip_address      PPP_LOCAL_ADDRESS;       /* Address will be assigned by remote host for client mode. */
  _ip_address      PPP_REMOTE_ADDRESS;      /* Address will be assigned by remote host for client mode. */
  _ip_address      PPP_GATE_ADDR;
   char*           LOCAL_NAME;              /* Board as client login name. */
   char*           LOCAL_PASSWORD;          /* Board as client password.  */
   char*           REMOTE_NAME;             /* Board as server connect login name. */
   char*           REMOTE_PASSWORD;         /* Board as server connecr password. */
   PPP_SECRET      rsecrets[2];             /* Save here PAP information. */
   LWSEM_STRUCT    PPP_SEM;                 /* PPP semafor. */
   uint_32         SERVER_FLAG;             /* Set it to "1" if we start PPP like server or "0" if we start PPP like client. */
} SHELL_PPP_LINK, _PTR_ SHELL_PPP_LINK_PTR;


   

extern boolean Shell_parse_ip_address( char_ptr arg, _ip_address _PTR_ ipaddr_ptr);
extern boolean Shell_parse_netmask( char_ptr arg, _ip_address _PTR_ ipaddr_ptr);

extern int_32 Shell_netstat(int_32 argc, char_ptr argv[] );
extern int_32 Shell_EDS(int_32 argc, char_ptr argv[] ); 
extern int_32 Shell_ping(int_32 argc, char_ptr argv[] ); 
extern int_32 Shell_Telnet_client(int_32 argc, char_ptr argv[] );
extern int_32 Shell_FTP_client(int_32 argc, char_ptr argv[] );
extern int_32 Shell_TFTP_client(int_32 argc, char_ptr argv[] );
extern int_32 Shell_get_host_by_name(int_32 argc, char_ptr argv[] ); 
extern int_32 Shell_Telnetd(int_32 argc, char_ptr argv[] );
extern int_32 Shell_Echod(int_32 argc, char_ptr argv[] );
extern int_32 Shell_SNMPd(int_32 argc, char_ptr argv[] );
extern int_32 Shell_FTPd(int_32 argc, char_ptr argv[] );
extern int_32 Shell_TFTPd(int_32 argc, char_ptr argv[] );
extern int_32 Shell_type(int_32 argc, char_ptr argv[] );
extern int_32 Shell_exec(int_32 argc, char_ptr argv[] );
extern int_32 Shell_load(int_32 argc, char_ptr argv[] );
extern int_32 Shell_walkroute(int_32 argc, char_ptr argv[] );
extern int_32 Shell_gate(int_32 argc, char_ptr argv[] ); 
extern int_32 Shell_getroute(int_32 argc, char_ptr argv[] );


extern int_32 Shell_arpdisp(int_32 argc, char_ptr argv[] );
extern int_32 Shell_arpadd(int_32 argc, char_ptr argv[] );
extern int_32 Shell_arpdel(int_32 argc, char_ptr argv[] );
extern int_32 Shell_sendto(int_32 argc, char_ptr argv[] );



extern int_32 Shell_nat(int_32 argc, char_ptr argv[] );
extern int_32 Shell_dnat(int_32 argc, char_ptr argv[] );
extern int_32 Shell_natinfo(int_32 argc, char_ptr argv[] );
extern int_32 Shell_natinit(int_32 argc, char_ptr argv[] );
extern int_32 Shell_dnat_delet_rule(int_32 argc, char_ptr argv[] );
extern int_32 Shell_dhcptest(int_32 argc, char_ptr argv[] );

extern int_32 Shell_Clock_server_start(int_32 argc, char_ptr argv[] );

extern int_32 Shell_ipconfig(int_32 argc, char_ptr argv[] );
extern int_32 Shell_iwconfig(int_32 argc, char_ptr argv[] );

/* PPP related shell commands. */
extern int_32 Shell_ppp(int_32 argc, char_ptr argv[] );


#ifdef __cplusplus
}
#endif

#endif
/*EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/kadc/adt_kpdb.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adt_kpdb.c$
* $Version : 3.8.16.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the ADC driver CPU specific functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "adc_conf.h"
#include "adc_prv.h"
#include "adc_kadc_prv.h"

static volatile struct {
    int_8    prescaler;
} pdb_external = {
    -1 /* not configured yet */
};

/* static variables for ADT driver */
static volatile struct {
    uint_32  period;
    PDB_INT_FCN idelay_fcn;
    pointer old_idelay_isr;
    pointer old_idelay_isr_data;
    _mqx_int old_isr_valid; /* which of interrupts handlers above are valid */
    uint_32 used_channel[ADC_MAX_MODULES];  /* mask of used channels */
    uint_32 delayA[ADC_MAX_MODULES]; /* if a channel A is paused, the original value of delay stored here */
} pdb_internal = { 0 };

/* Following remembers last delay value and then writes DLY for ChA behind accessible boundary */
#define DISABLE_CH0_PROCESSING(adc_num, adc_ch_bundle) \
    do { \
    pdb_internal.delayA[adc_num] = PDB0_BASE_PTR->CH[adc_num].DLY[0]; \
        if (PDB0_BASE_PTR->MOD == PDB_MOD_MOD_MASK) { \
            PDB0_BASE_PTR->CH[adc_num].DLY[0] = PDB_MOD_MOD_MASK; \
        } \
        else { \
            PDB0_BASE_PTR->CH[adc_num].DLY[0] = PDB0_BASE_PTR->MOD + 1; \
        } \
    PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK; \
        adc_ch_bundle->waste_channel = 1; \
    } while(0);

/* Following reuses last delay value and then stops wasting AD channel */
#define ENABLE_CH0_PROCESSING(adc_num, adc_ch_bundle) \
    do { \
    PDB0_BASE_PTR->CH[adc_num].DLY[0] = pdb_internal.delayA[adc_num]; \
    PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK; \
        adc_ch_bundle->waste_channel = 0; \
    } while(0);

#if PSP_MQX_CPU_IS_KINETIS
    #define PDB_CH_EN(adc_num)\
        * (uint_8_ptr) (&PDB0_BASE_PTR->CH[adc_num].C1)
#else
    #define PDB_CH_EN(adc_num)\
        *(uint_8_ptr)((uint_32)&PDB0_BASE_PTR->CH[adc_num].C1 + 3)
#endif
extern ADC_BUNDLE adc_bundle;

static _mqx_int adt_period_prescaler(uint_32 period);
static void adt_idelay_isr(pointer param);

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_hw_ioctl
* Returned Value   : _mqx_int
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/
_mqx_int _adt_hw_ioctl
(
    /* [IN] the file handle for the device */
    MQX_FILE_PTR f,

    /* [IN] the ioctl command */
    _mqx_uint  cmd,

    /* [IN] the ioctl parameters */
    pointer    param_ptr
)
{
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    _mqx_uint adc_num = 0;
    uint_32 d, pdb_period;

    if (adc_ch_bundle != NULL)
        adc_num = adc_ch_bundle->adc_num;

    switch (cmd)
    {
        case ADC_IOCTL_SET_IDELAY:
            /* sets offset for interrupt in PDB module - see IDELAY register in Reference Manual */
            pdb_period = pdb_internal.period;
            if (pdb_period == 0)
                return ADC_ERROR_PERIOD; /* cannot set idelay if period was not set before */
            d = ((uint_64) param_ptr * PDB0_BASE_PTR->MOD) / pdb_period;
            if (d > MAX_UINT_16)
                return ADC_ERROR_BAD_PARAM; /* cannot set such offset */
            PDB0_BASE_PTR->IDLY = (uint32_t) d;
            break;

        case ADC_IOCTL_SET_IDELAYREG:
            /* sets offset for interrupt in PDB module - see IDELAY register in Reference Manual */
            if ((uint_32) param_ptr > MAX_UINT_16)
                return ADC_ERROR_BAD_PARAM; /* cannot set such idelay */
            PDB0_BASE_PTR->IDLY = (uint32_t) param_ptr;
            break;

        case ADC_IOCTL_SET_IDELAY_FCN:
            /* sets callback for interrupt in PDB module */
            pdb_internal.idelay_fcn = (PDB_INT_FCN) param_ptr;
            break;

        case ADC_IOCTL_SET_BASE_PERIOD:
            /* Correction of PDB period, delays are not checked against shortened period value */
            pdb_period = pdb_internal.period;
            if (pdb_period == 0) { /* period was not set yet? */
                return adt_period_prescaler((uint_32) param_ptr);
            }
            else { /* trim period if possible */
                d = (uint_32) ((uint_64) param_ptr * PDB0_BASE_PTR->MOD) / pdb_period - 1;
                if (d > MAX_UINT_16)
                    return ADC_ERROR_BAD_PARAM; /* cannot set such period */
                PDB0_BASE_PTR->MOD = (uint_16) d;
            }
            if ((adc_d_bundle->adt_ch[0] == NULL) || adc_d_bundle->adt_ch[0]->b->waste_channel)
                PDB0_BASE_PTR->CH[adc_num].DLY[0] = (PDB0_BASE_PTR->MOD == PDB_MOD_MOD_MASK ? PDB_MOD_MOD_MASK : PDB0_BASE_PTR->MOD + 1); /* move ChA behind accessible boundary */
            PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK; /* write DLY value */
            break;

        case ADC_IOCTL_TRIM_BASE_PERIOD:
            /* Correction of PDB period, delays are not checked against shortened period value */
            if ((uint_32) param_ptr > MAX_UINT_16)
                return ADC_ERROR_BAD_PARAM; /* cannot set such period */
            PDB0_BASE_PTR->MOD = (uint32_t) param_ptr;
            if ((adc_d_bundle->adt_ch[0] == NULL) || adc_d_bundle->adt_ch[0]->b->waste_channel)
                PDB0_BASE_PTR->CH[adc_num].DLY[0] = (PDB0_BASE_PTR->MOD == PDB_MOD_MOD_MASK ? PDB_MOD_MOD_MASK : PDB0_BASE_PTR->MOD + 1); /* move ChA behind accessible boundary */
            PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK; /* write MOD value */
            break;

        case ADC_IOCTL_SET_DELAYREG:
            /* Correction of delay registers */
            if (adc_ch_bundle == NULL)
                return ADC_ERROR_ONLY_CHANNEL; /* delays can be set only on channel files */
            if ((uint_32) param_ptr > MAX_UINT_16)
                return ADC_ERROR_PARAM; /* cannot set such delay */
            PDB0_BASE_PTR->CH[adc_num].DLY[adc_ch_bundle->ch_num] = (uint32_t) param_ptr;

            if (adc_ch_bundle->ch_num == 0)
                pdb_internal.delayA[adc_num] = PDB0_BASE_PTR->CH[adc_num].DLY[0]; /* remember last delay value */

            PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK; /* write DLY value */
            break;

        case ADC_IOCTL_SET_TRIGGER:
            /* Set HW triggering options */
            PDB0_BASE_PTR->SC = (PDB0_BASE_PTR->SC & ~PDB_SC_TRGSEL_MASK) | PDB_SC_TRGSEL(param_ptr);
            break;

        default:
            return IO_ERROR_INVALID_IOCTL_CMD;
    }

    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_hw_install
* Returned Value   : IO_OK
* Comments         :
*    Performs CPU specific initialization for ADC driver
*
*END*********************************************************************/
_mqx_int _adt_hw_install(char_ptr adc_name, ADC_DRIVER_BUNDLE_PTR adc_d_bundle, pointer p)
{
    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_hw_init
* Returned Value   : IO_OK
* Comments         :
*    Performs CPU specific initialization for ADC driver
*
*END*********************************************************************/
_mqx_int _adt_hw_init(MQX_FILE_PTR f, ADT_PTR adt_d)
{ /* Body */
    SIM_MemMapPtr sim_ptr = SIM_BASE_PTR;
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    _mqx_int adc_num = adc_d_bundle->init->ADC_NUMBER;
#if PSP_MQX_CPU_IS_KINETIS
    sim_ptr->SCGC6 |= SIM_SCGC6_PDB_MASK; /* enable PDB module clocking */
#else
    sim_ptr->SCGC3 |= SIM_SCGC3_PDB_MASK; /* enable PDB module clocking */
#endif /* PSP_MQX_CPU_IS_KINETIS*/

    PDB0_BASE_PTR->SC |= PDB_SC_PDBEN_MASK; /* enable PDB module, so we can write o registers with LDOK */

    if (!(pdb_internal.old_isr_valid & 0x01)) {
        pdb_internal.old_idelay_isr_data = (pointer) _int_get_isr_data(adc_d_bundle->init->PDB_INIT->IDELAY_VECTOR);
        pdb_internal.old_idelay_isr = (pointer) _int_install_isr(adc_d_bundle->init->PDB_INIT->IDELAY_VECTOR, adt_idelay_isr, f);
        /* Enable interrupt in NVIC */
        _bsp_int_init(adc_d_bundle->init->PDB_INIT->IDELAY_VECTOR, adc_d_bundle->init->PDB_INIT->IDELAY_PRIORITY, 0, TRUE);

        pdb_internal.old_isr_valid |= 0x01;
    }

    PDB0_BASE_PTR->SC &= ~PDB_SC_PDBIF_MASK; /* clear PDB interrupts */

    PDB0_BASE_PTR->SC &= ~PDB_SC_LDMOD_MASK;
    PDB0_BASE_PTR->SC |= PDB_SC_LDMOD(0x00); /* write to MOD and DLY registers immediately */

    PDB_CH_EN(adc_num) = 0; /* no channel enabled yet */
    PDB0_BASE_PTR->CH[adc_num].C1 |= PDB_C1_TOS_MASK; /* select pre-trigger as a function of delay for all channels */
    PDB0_BASE_PTR->CH[adc_num].C1 &= ~PDB_C1_BB_MASK; /* don't use back-to-back mode, use delayed channel conversions instead */

#if PSP_MQX_CPU_IS_KINETIS
    if (adc_num == 0) {
        sim_ptr->SOPT7 &= ~SIM_SOPT7_ADC0ALTTRGEN_MASK; /* set PDB to be source for ADC conversion start */
    }
#if defined(SIM_SOPT7_ADC1ALTTRGEN_MASK)
    else {
        sim_ptr->SOPT7 &= ~SIM_SOPT7_ADC1ALTTRGEN_MASK; /* set PDB to be source for ADC conversion start */
    }
#endif
#else
    if (adc_num == 0) {
        sim_ptr->SOPT7 &= ~SIM_SOPT7_ADTRGS_MASK; /* set PDB to be source for ADC conversion start */
    }
#endif /* PSP_MQX_CPU_IS_KINETIS*/

    return ADC_OK;
} /* Endbody */

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_hw_deinit
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific deinitialization for ADC driver
*
*END*********************************************************************/
_mqx_int _adt_hw_deinit(MQX_FILE_PTR f, ADT_PTR adt) {
    pdb_external.prescaler = -1;
    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : adt_period_prescaler
* Returned Value   : IO_OK or IO_ERROR
* Comments         :
*    Finds the best prescaler for given period
*
*END*********************************************************************/
static _mqx_int adt_period_prescaler(uint_32 period)
{
    volatile uint_32 pdb_prescaler1, pdb_prescaler, pdb_period1, pdb_period = 0, pdb_period_test;
    uint_8 mult = 0; /* assume that we will not use MULT field */

    /* In the first step, we want to find for given a prescaler, which meets following criteria:
    ** considering MOD field = 65535 and, find a combination of (found_prescaler, found_period), in which found_period
    ** is minimal (so the found_prescaler is also lowest possible one), but found_period must be still higher
    ** than given period.
    ** We compute for 2 cases: MULT field is 0 and MULT field is not 0 and after that we compare those 2 results and we
    ** choose the better one (the one with valid lower found_period).
    ** At the end, we reduce MOD, to set given period for PDB. With this approach, MOD field gets the highest possible value.
    */
#define PDB_MAX_PERIOD1 (uint_32) ((uint_64) 8388608000000L / BSP_BUS_CLOCK)   /*  1 * 128 * 65536 * 1000000 = 8388608000000 */
#define PDB_MAX_PERIOD  (uint_32) ((uint_64) 335544320000000L / BSP_BUS_CLOCK) /* 40 * 128 * 65536 * 1000000 = 335544320000000 */

    /* PDB was not run till yet... so setup period */
    if (pdb_external.prescaler == -1) {
        /* PDB prescaler was not set yet */

        pdb_period_test = PDB_MAX_PERIOD1;
        pdb_prescaler1 = 7;
        while ((pdb_prescaler1 != (uint_32)-1) && (period < pdb_period_test)) {
            pdb_prescaler1--;
            pdb_period1 = pdb_period_test;
            pdb_period_test >>= 1;
        }
        pdb_prescaler1++;

        /* now, in pdb_prescaler1, we have prescaler as if there was
        ** no additional division factor (MULT field equivalent to 1) and in
        ** pdb_period1 we have related period in microseconds
        */

        pdb_period_test = PDB_MAX_PERIOD;
        pdb_prescaler = 9; /* we got 2 next bits from MULT field, because MULT can have values of 10, 20, 40 */
        while ((pdb_prescaler != (uint_32)-1) && (period < pdb_period_test)) {
            pdb_prescaler--;
            pdb_period = pdb_period_test;
            pdb_period_test >>= 1;
        }
        pdb_prescaler++;

        /* now, in pdb_prescaler, we have prescaler as if there was
        ** additional division factor (MULT field equivalent to 10) and in
        ** pdb_period we have related period in microseconds
        */

        if ((pdb_prescaler1 == 8) && (pdb_prescaler == 10)) {
                /* cannot set period with pdb_prescaler */
                return ADC_ERROR_BAD_PARAM;
        }
        /* Compare both values of pdb_period1 and pdb_period - the smaller one wins */
        if ((pdb_period1 < pdb_period) && (pdb_prescaler1 != 8)) {
            /* use values of pdb_period1 => copy them to the result; MULT field remains zero */
            pdb_period = pdb_period1;
            pdb_prescaler = pdb_prescaler1;
        }
        else {
            /* compute pdb_period and pdb_prescaler plus compute MULT field */
            if (pdb_prescaler > 7) {
                /* move additional bits from pdb_prescaler to MULT field */
                mult = pdb_prescaler - 6;
                /* and saturate pdb_prescaler to maximum */
                pdb_prescaler = 7;
            }
            else
                mult = 1;
        }

        pdb_external.prescaler = (int_8) pdb_prescaler;
    }
    else {
        /* compute PDB period with prescaler already set */
        switch (PDB0_BASE_PTR->SC & PDB_SC_MULT_MASK) {
            case PDB_SC_MULT(0): /* 0 in the mask means that divider is 1 */
                pdb_period = PDB_MAX_PERIOD1 >> (7 - pdb_external.prescaler);
                mult = 0;
                break;
            case PDB_SC_MULT(1): /* 1 in the mask means that divider is 10 */
                pdb_period = PDB_MAX_PERIOD >> (7 - pdb_external.prescaler + 2);
                mult = 1;
                break;
            case PDB_SC_MULT(2): /* 2 in the mask means that divider is 20 */
                pdb_period = PDB_MAX_PERIOD >> (7 - pdb_external.prescaler + 1);
                mult = 2;
                break;
            case PDB_SC_MULT(3): /* 3 in the mask means that divider is 40 */
                pdb_period = PDB_MAX_PERIOD >> (7 - pdb_external.prescaler + 0);
                mult = 3;
                break;
        }

        if (period > pdb_period)
            return ADC_ERROR_BAD_PARAM; /* cannot set period */
    }


    pdb_period1 = ((uint_64) period << 16) / pdb_period;
    if (pdb_period1 > 0xFFFF)
        return ADC_ERROR_BAD_PARAM; /* cannot set period */
    PDB0_BASE_PTR->MOD =  pdb_period1 - 1;
    PDB0_BASE_PTR->SC &= ~PDB_SC_MULT_MASK;
    PDB0_BASE_PTR->SC |= PDB_SC_MULT(mult);
    PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK;
    pdb_internal.period = period;

    /* set prescaler and enable module with interrupts */
    PDB0_BASE_PTR->SC &= ~PDB_SC_PRESCALER_MASK;
    PDB0_BASE_PTR->SC |= (pdb_prescaler << PDB_SC_PRESCALER_SHIFT);
    PDB0_BASE_PTR->SC |= PDB_SC_PDBIE_MASK | PDB_SC_CONT_MASK | PDB_SC_LDOK_MASK;

    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_hw_channel_init
* Returned Value   : IO_OK or IO_ERROR
* Comments         :
*    Returns result of HW channel initialization
*
*END*********************************************************************/
_mqx_int _adt_hw_channel_init(MQX_FILE_PTR f, ADT_CHANNEL_PTR adt_ch)
{
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    uint_32  pdb_period;
    _mqx_uint adc_num = adc_ch_bundle->adc_num;
    _mqx_int ch_num;
    _mqx_int status;

    if ((adt_ch->g.trigger & ADC_PDB_TRIGGER) != ADC_PDB_TRIGGER)
        return ADC_ERROR_HWTRIGGER; /* the channel can be run only from HW trigger */

    if (pdb_internal.period != 0) {
        _mqx_int N;
        N = adt_ch->g.period / pdb_internal.period;
        if (N * pdb_internal.period != adt_ch->g.period)
            return ADC_ERROR_BAD_PARAM; /* it's only allowed to have periods as multiple of basic period */
        adc_ch_bundle->periods_preset = N;
        adc_ch_bundle->periods = 0;
    }
    else {
        adc_ch_bundle->periods_preset = 1;
        adc_ch_bundle->periods = 0;

        status = adt_period_prescaler(adt_ch->g.period);
        if (status != ADC_OK)
            return status;
    }
    PDB0_BASE_PTR->SC |= PDB_SC_TRGSEL_SWTRIG; /* set to software trigger by default */

    ch_num = adc_ch_bundle->ch_num;

    pdb_period = pdb_internal.period; /* <err001>: DON'T REMOVE THIS LINE! CW 6.2 COMPILER ERROR WITH DIVIDING OCCURS OTHERWISE */

    PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK; /* write new MOD value */
    if (ch_num == 0) { /* temporary, we will make running channel A not actively, first trigger will move it to area within accesible boundary */
        pdb_internal.delayA[adc_num] = ((uint_64) adt_ch->g.offset * PDB0_BASE_PTR->MOD) / pdb_period;/* <err001>: we must use pdb_period */
        PDB0_BASE_PTR->CH[adc_num].DLY[0] = (PDB0_BASE_PTR->MOD == PDB_MOD_MOD_MASK ? PDB_MOD_MOD_MASK : PDB0_BASE_PTR->MOD + 1); /* move ChA behind accessible boundary */
        adc_ch_bundle->waste_channel = 1;
    }
    else
        PDB0_BASE_PTR->CH[adc_num].DLY[ch_num] = ((uint_64) adt_ch->g.offset * PDB0_BASE_PTR->MOD) / pdb_period;/* <err001>: we must use pdb_period */
    PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK; /* write new DLY value */

    pdb_internal.used_channel[adc_num] |= 0x01 << ch_num;

    adt_ch->g.samples = adt_ch->g.samples_preset;
    adt_ch->b = adc_ch_bundle;

    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_hw_channel_deinit
* Returned Value   : IO_OK or IO_ERROR
* Comments         :
*    Performs CPU specific deinitialization for ADC channel
*
*END*********************************************************************/
_mqx_int _adt_hw_channel_deinit(MQX_FILE_PTR f, ADT_CHANNEL_PTR adt_ch)
{
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    _mqx_uint adc_num = adc_ch_bundle->adc_num;
    _mqx_int ch_num;
    _mqx_uint i;

    ch_num = adc_ch_bundle->ch_num;

    if (ch_num == 0) {
        if (PDB0_BASE_PTR->MOD == PDB_MOD_MOD_MASK)
        {
            PDB0_BASE_PTR->CH[adc_num].DLY[0] = PDB_MOD_MOD_MASK;
        }
        else
        {
            PDB0_BASE_PTR->CH[adc_num].DLY[0] = PDB0_BASE_PTR->MOD + 1;
        }
        PDB0_BASE_PTR->SC |= PDB_SC_LDOK_MASK; /* write DLY value */
        /* Following line is not usable anymore as adc_ch_bundle is about to be mem_freed */
        // adc_ch_bundle->waste_channel = 1; /* in the case of interrupt, waste channel */
    }
    else
        PDB_CH_EN(adc_num) &= ~(1 << ch_num);

    pdb_internal.used_channel[adc_num] &= ~(0x01 << ch_num);

    if (pdb_internal.used_channel[adc_num] == 0) {
        PDB_CH_EN(adc_num) = 0; /* disable also channel A */
    }
    for (i = 0; i < ADC_MAX_MODULES; i++) {
        if (pdb_internal.used_channel[adc_num] != 0)
            goto _adt_hw_channel_deinit_ok;
    }

    /* If we reached this code, it means, that no PDB channels are running anymore */
    PDB0_BASE_PTR->SC &= ~PDB_SC_PDBEN_MASK;
    pdb_internal.period = 0;
    pdb_external.prescaler = -1;

_adt_hw_channel_deinit_ok:
    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_trigger
* Returned Value   : IO_OK or IO_ERROR
* Comments         : Starts channel measurement or more channels defined
*                    by trigger mask
*
*END*********************************************************************/
_mqx_int _adt_trigger(MQX_FILE_PTR f, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask)
{
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    _mqx_uint adc_num = adc_d_bundle->init->ADC_NUMBER;

    if (mask & ~ADC_PDB_TRIGGER)
        return ADC_ERROR_HWTRIGGER; /* cannot trigger SW-triggers */

    if (adc_ch_bundle == NULL) {
        PDB_CH_EN(adc_num) = (pdb_internal.used_channel[adc_num] | 0x01); /* enable all used channels */
        if (pdb_internal.used_channel[adc_num] & 0x01) {
            ENABLE_CH0_PROCESSING(adc_num, adc_d_bundle->adc_ch[0]->b);
        }
    }
    else {
        if (adc_ch_bundle->ch_num == 0)
            ENABLE_CH0_PROCESSING(adc_num, adc_ch_bundle);
        PDB_CH_EN(adc_num) |= (1 << adc_ch_bundle->ch_num) | 0x01; /* ChA must run all the time */
    }

    PDB0_BASE_PTR->SC |= PDB_SC_PDBEN_MASK | PDB_SC_SWTRIG_MASK; /* enable PDB module and trigger it */

    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_pause
* Returned Value   : IO_OK
* Comments         : Pauses measurement of single channel, or more channels
*                    defined by trigger mask
*
*END*********************************************************************/
_mqx_int _adt_pause(MQX_FILE_PTR f, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask)
{
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    _mqx_uint adc_num = adc_d_bundle->init->ADC_NUMBER;

    if (mask & ~ADC_PDB_TRIGGER)
        return ADC_ERROR_HWTRIGGER; /* cannot pause SW-triggers */

    if (adc_ch_bundle == NULL)
        PDB0_BASE_PTR->CH[adc_num].C1 &= ~PDB_C1_EN_MASK;
    else if (adc_ch_bundle->ch_num > 0)
        PDB0_BASE_PTR->CH[adc_num].C1 &= ~PDB_C1_EN(1 << adc_ch_bundle->ch_num);
    else {
        DISABLE_CH0_PROCESSING(adc_num, adc_ch_bundle);
    }

    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_resume
* Returned Value   : IO_OK
* Comments         : Resumes measurement of single paused channel, or more
*                    channels defined by trigger mask
*
*END*********************************************************************/
_mqx_int _adt_resume(MQX_FILE_PTR f, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask)
{
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    _mqx_uint adc_num = adc_d_bundle->init->ADC_NUMBER;

    if (mask & ~ADC_PDB_TRIGGER)
        return ADC_ERROR_HWTRIGGER; /* cannot resume SW-triggers */

    if (adc_ch_bundle == NULL) {
        PDB_CH_EN(adc_num) = (pdb_internal.used_channel[adc_num] | 0x01); /* enable all used channels */
        if (pdb_internal.used_channel[adc_num] & 0x01) {
            ENABLE_CH0_PROCESSING(adc_num, adc_d_bundle->adc_ch[0]->b);
        }
    }
    else if (adc_ch_bundle->ch_num > 0)
        PDB_CH_EN(adc_num) |= (1 << adc_ch_bundle->ch_num);
    else {
        ENABLE_CH0_PROCESSING(adc_num, adc_ch_bundle);
    }

    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _adt_stop
* Returned Value   : IO_OK or IO_ERROR
* Comments         : Stops (resets) measurement of single channel, or more
*                    channels defined by trigger mask
*
*END*********************************************************************/
_mqx_int _adt_stop(MQX_FILE_PTR f, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask)
{
    ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    _mqx_uint adc_num = adc_d_bundle->init->ADC_NUMBER;

    if (mask & ~ADC_PDB_TRIGGER)
        return ADC_ERROR_HWTRIGGER; /* cannot stop SW-triggers */

    if (adc_ch_bundle == NULL)
        PDB_CH_EN(adc_num) = 0;
    else if (adc_ch_bundle->ch_num > 0)
        PDB_CH_EN(adc_num) |= (1 << adc_ch_bundle->ch_num);
    else {
        DISABLE_CH0_PROCESSING(adc_num, adc_ch_bundle);
    }

    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : adt_process_data
* Returned Value   : void
* Comments         : called from adc_process_all_data
*
*END*********************************************************************/
_mqx_int _adt_process_data(ADC_CHANNEL_BUNDLE_PTR adc_ch_bundle)
{ /* Body */
    ADT_CHANNEL_PTR adt_ch = adc_ch_bundle->adt_ch;
    _mqx_uint adc_num = adc_ch_bundle->adc_num;

    if (adt_ch->g.samples)
        adt_ch->g.samples--;
    else {
        if (adt_ch->g.init_flags & ADC_CHANNEL_MEASURE_ONCE) {
            if (adc_ch_bundle->ch_num > 0)
                PDB_CH_EN(adc_num) &= ~(1 << adc_ch_bundle->ch_num);
            else {
                DISABLE_CH0_PROCESSING(adc_num, adc_ch_bundle);
            }
        }
#if MQX_USE_LWEVENTS
        if (adt_ch->g.complete_event != NULL)
            _lwevent_set(adt_ch->g.complete_event, adt_ch->g.event_mask); /* set completion event */
#endif
        adt_ch->g.samples = adt_ch->g.samples_preset;
    }

    return ADC_OK;
}

/*FUNCTION*****************************************************************
*
* Function Name    : adt_idelay_isr
* Returned Value   : IO_OK
* Comments         : PDB's delay isr
*
*END*********************************************************************/

static void adt_idelay_isr(pointer param)
{
#if PSP_MQX_CPU_IS_KINETIS
    _mqx_uint i;
    /* clear ERR flags */
    for (i = 0; i < ADC_MAX_MODULES; i++) {
        PDB0_BASE_PTR->CH[i].S = 0x0F;
    }
#endif /* PSP_MQX_CPU_IS_KINETIS */
    /* we should perform data readout for channels, that were supposed to perform late process data processing */
    if (adc_bundle.late_process)
         /* if at least one channel is late processed, then do late processing */
        adc_process_all_data();

    if (pdb_internal.idelay_fcn != NULL)
        pdb_internal.idelay_fcn();
    PDB0_BASE_PTR->SC &= ~PDB_SC_PDBIF_MASK; /* clear interrupt flag */
}


/*FUNCTION****************************************************************
*
* Function Name    : _bsp_get_pdb_base_address
* Returned Value   : pointer to base of ADC registers
* Comments         :
*    This function returns base address of ADC related register space.
*
*END*********************************************************************/
pointer _bsp_get_pdb_base_address()
{
    return (pointer) PDB0_BASE_PTR;
}

/*FUNCTION*****************************************************************
*
* Function Name    : pdb_get_prescaler
* Returned Value   : none
* Comments         : Gets PDB raw value or -1 if prescaler was not set yet
*
*END*********************************************************************/
int_16 _pdb_get_prescaler()
{
    if (pdb_external.prescaler == 0)
        return -1;
    else
        return pdb_external.prescaler;
}

/*FUNCTION*****************************************************************
*
* Function Name    : pdb_set_prescaler
* Returned Value   : none
* Comments         : Sets PDB prescaler value
*
*END*********************************************************************/
_mqx_int _pdb_set_prescaler(int_16 prescaler, int_16 multiplier)
{
    if ((prescaler < 0) || (prescaler > (PDB_SC_PRESCALER_MASK >> PDB_SC_PRESCALER_SHIFT)))
        return IO_ERROR; /* cannot set such prescaler */

    /* set prescaler */
    PDB0_BASE_PTR->SC &= ~PDB_SC_PRESCALER_MASK;
    PDB0_BASE_PTR->SC = prescaler << PDB_SC_PRESCALER_SHIFT;

    pdb_external.prescaler = prescaler;

    return IO_OK;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/include/mfs_prv.h<|end_filename|>
#ifndef __mfs_prv_h__
#define __mfs_prv_h__
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_prv.h$
* $Version : 3.8.26.0$
* $Date    : Aug-23-2012$
*
* Comments:
*
*   This file contains the structure definitions and constants
*   that are internal to the Embedded MS-DOS File System (MFS)
*
*END************************************************************************/

#include <partition.h>

/*
** Defines specific to MFS
*/

#define BOOT_SECTOR           0
#define FSINFO_SECTOR         1     /* FAT32 only */
#define BKBOOT_SECTOR         6     /* FAT32 only */

#define MFS_SECTOR_READ       5
#define MFS_SECTOR_WRITE      10

#define MFS_DOS30_JMP         0xEB /* 2 byte jmp 80x86 opcode */
#define MFS_DOS30_B           0xE9 /* 2 byte b 80x86 opcode */
#define MFS_DEL_FILE          0xE5 /* DOS byte used for a deleted file */

/* FAT 32 Filesystem info signatures */
#define FSI_LEADSIG           0x41615252UL
#define FSI_STRUCTSIG         0x61417272UL
#define FSI_TRAILSIG          0xAA550000UL
#define FSI_UNKNOWN           0xFFFFFFFFUL

/* This is the vesion of tfe FAT32 driver */
#define MFS_FAT32_VER         0x0000


#define MFS_LFN_END           0x40

#define ATTR_EXCLUSIVE        0x40
#define MFS_ATTR_ANY          0x80

/* defines used in FAT   */
#define CLUSTER_INVALID       0x00000001L
#define CLUSTER_UNUSED        0x00000000L
#define CLUSTER_MIN_GOOD      0x00000002L
#define CLUSTER_MAX_GOOD      0xFFFFFEFUL
#define CLUSTER_MIN_RESERVED  0xFFFFFF0UL
#define CLUSTER_MAX_RESERVED  0xFFFFFF6UL
#define CLUSTER_BAD           0xFFFFFF7UL
#define CLUSTER_MIN_LAST      0xFFFFFF8UL
#define CLUSTER_EOF           0xFFFFFFFUL
#define CLUSTER_MAX_12        0x0000FF8UL
#define CLUSTER_MAX_16        0x000FFF8UL
#define CLUSTER_MAX_32        0xFFFFFF8UL

#define MFS_VALID             0x4d465356UL

#ifndef min
    #define min(a,b) ((a<b)?a:b)
#endif

#define MFS_set_error_and_return(error_ptr, error, retval) { if (error_ptr != NULL) { *error_ptr = error;} return(retval ); }
#define ROOT_CLUSTER(drive_ptr) (drive_ptr->FAT_TYPE == MFS_FAT32 ? drive_ptr->BPB32.ROOT_CLUSTER : 0)
#define MFS_LOG(x)  // puts(x);


/* structure of a long file name slot */
typedef struct mfs_lname_enty
{
    uchar    ID;
    uchar    NAME0_4[10];
    uchar    ATTR;
    uchar    RESERVE;
    uchar    ALIAS_CHECKSUM;
    uchar    NAME5_10[12];
    uchar    START[2];
    uchar    NAME11_12[4];
} MFS_LNAME_ENTRY, _PTR_ MFS_LNAME_ENTRY_PTR;



/* structure of the BIOS Parameter Block maintained in the
** boot sector as stored in drive.
*/
typedef struct bios_param_struct
{
    char     RESERVED[11];
    uchar    RESERVED2;
    uint_16  SECTOR_SIZE;
    uchar    SECTORS_PER_CLUSTER;
    uchar    RESERVED3;
    uint_16  RESERVED_SECTORS;
    uchar    NUMBER_OF_FAT;
    uchar    RESERVED4;
    uint_16  ROOT_ENTRIES;
    uint_16  NUMBER_SECTORS;
    uchar    MEDIA_TYPE;
    uchar    RESERVED5;
    uint_16  SECTORS_PER_FAT;
    uint_16  SECTORS_PER_TRACK;
    uint_16  NUM_HEADS;
    uint_32  HIDDEN_SECTORS;
    uint_32  MEGA_SECTORS;
} BIOS_PARAM_STRUCT, _PTR_ BIOS_PARAM_STRUCT_PTR;

/* structure of the BIOS Parameter Block maintained in the
** boot sector as read off the disk
*/
typedef struct bios_param_struct_disk
{
    char     RESERVED[11];
    uchar    SECTOR_SIZE[2];
    uchar    SECTORS_PER_CLUSTER[1];
    uchar    RESERVED_SECTORS[2];
    uchar    NUMBER_OF_FAT[1];
    uchar    ROOT_ENTRIES[2];
    uchar    NUMBER_SECTORS[2];
    uchar    MEDIA_TYPE[1];
    uchar    SECTORS_PER_FAT[2];
    uchar    SECTORS_PER_TRACK[2];
    uchar    NUM_HEADS[2];
    uchar    HIDDEN_SECTORS[4];
    uchar    MEGA_SECTORS[4];
} BIOS_PARAM_STRUCT_DISK, _PTR_ BIOS_PARAM_STRUCT_DISK_PTR;

/* structure of the BIOS Parameter Block maintained in the
** boot sector as read off the disk (FAT32 extension)
*/
typedef struct bios_param32_struct_disk
{
    uchar    FAT_SIZE[4];
    uchar    EXT_FLAGS[2];
    uchar    FS_VER[2];
    uchar    ROOT_CLUSTER[4];
    uchar    FS_INFO[2];
    uchar    BK_BOOT_SEC[2];
    uchar    RESERVED[12];
} BIOS_PARAM32_STRUCT_DISK, _PTR_ BIOS_PARAM32_STRUCT_DISK_PTR;


typedef struct bios_param32_struct
{
    uint_32  FAT_SIZE;
    uint_16  EXT_FLAGS;
    uint_16  FS_VER;
    uint_32  ROOT_CLUSTER;
    uint_16  FS_INFO;
    uint_16  BK_BOOT_SEC;
    uchar    RESERVED[12];
} BIOS_PARAM32_STRUCT, _PTR_ BIOS_PARAM32_STRUCT_PTR;


/* The file system info struct. For FAT32 only */
typedef struct filesystem_info_disk
{
    uchar    LEAD_SIG[4];
    uchar    RESERVED1[480];
    uchar    STRUCT_SIG[4];
    uchar    FREE_COUNT[4];
    uchar    NEXT_FREE[4];
    uchar    RESERVED2[12];
    uchar    TRAIL_SIG[4];
} FILESYSTEM_INFO_DISK, _PTR_ FILESYSTEM_INFO_DISK_PTR;

typedef struct filesystem_info
{
    uint_32  FREE_COUNT;
    uint_32  NEXT_FREE;
} FILESYSTEM_INFO, FILESYSTEM_INFO_PTR;

/* configuration data for the MFS */
typedef struct mfs_drive_struct
{
    uint_32                    DRV_NUM;
    BIOS_PARAM_STRUCT          BPB;
    BIOS_PARAM32_STRUCT        BPB32;

    _mfs_cache_policy          WRITE_CACHE_POLICY;
    boolean                    DOS_DISK;
    boolean                    BLOCK_MODE;
    boolean                    READ_ONLY;

    uint_16                    SECTOR_POWER;
    uint_32                    CLUSTER_SIZE_BYTES;

    uint_16                    CLUSTER_POWER_BYTES;
    uint_16                    CLUSTER_POWER_SECTORS;

    uint_16                    RESERVED;
    uint_16                    ENTRIES_PER_SECTOR;

    uint_32                    FAT_START_SECTOR;
    uint_32                    ROOT_START_SECTOR;
    uint_32                    DATA_START_SECTOR;
    QUEUE_STRUCT               HANDLE_LIST;
    uint_32                    FAT_TYPE;
    uint_32                    CUR_DIR_CLUSTER;
    uint_32                    LAST_CLUSTER;
    char                       CURRENT_DIR[PATHNAME_SIZE + 1];
    uchar                      RESERVED2[3];
    LWSEM_STRUCT               SEM;
    _partition_id              HANDLE_PARTITION;
    MQX_FILE_PTR               DEV_FILE_PTR;
    MQX_FILE_PTR               MFS_FILE_PTR;

    boolean                    DIR_SECTOR_DIRTY;
    uint_32                    DIR_SECTOR_NUMBER;
    char_ptr                   DIR_SECTOR_PTR;

    _mfs_cache_policy          FAT_CACHE_POLICY;
    uint_32                    FAT_CACHE_START;
    uint_32                    FAT_CACHE_DIRTY;
    char_ptr                   FAT_CACHE_PTR;
    uint_32                    FAT_CACHE_SIZE;

    boolean                    DATA_SECTOR_DIRTY;
    uint_32                    DATA_SECTOR_NUMBER;
    char_ptr                   DATA_SECTOR_PTR;

    /* Count of free clusters. 0xFFFFFFFF means unknown. Must be recalculated */
    uint_32                    FREE_COUNT;
    /* Is set to the last allocated cluster. If = 0xFFFFFFF start search at 2 */
    uint_32                    NEXT_FREE_CLUSTER;

    boolean                    VERIFY_WRITES;
    uchar_ptr                  READBACK_SECTOR_PTR;

} MFS_DRIVE_STRUCT, _PTR_ MFS_DRIVE_STRUCT_PTR;

/*
** MFS Macro code
*/



/*
** CLUSTER_BOUNDARY ... takes a file offset and resets it to point to the
**                      first byte within the same cluster.
**       All this by masking off the least significant bits.
*/
#define  CLUSTER_BOUNDARY(x)   ((x) & (~(drive_ptr->CLUSTER_SIZE_BYTES - 1)))

/*
** The offset within the cluster is obtained by masking off the MSB's
*/
#define  OFFSET_WITHIN_CLUSTER(x)  ((x) & (drive_ptr->CLUSTER_SIZE_BYTES - 1))
#define  CLUSTER_OFFSET_TO_SECTOR(x)  (x>>drive_ptr->SECTOR_POWER)

#define  OFFSET_WITHIN_SECTOR(x)  ((x) & (drive_ptr->BPB.SECTOR_SIZE - 1))

/*
**  Returns the # of the first sector in the cluster.
*/
#define  CLUSTER_TO_SECTOR(x) ((x - CLUSTER_MIN_GOOD) *\
   drive_ptr->BPB.SECTORS_PER_CLUSTER + drive_ptr->DATA_START_SECTOR)

/*
** INDEX_TO_SECTOR converts an entry_index within the cluster or directory
** to the sector # in which that entry is found.
*/
#define INDEX_TO_SECTOR(x)  ((x) / drive_ptr->ENTRIES_PER_SECTOR)


/* Used to fix bug in date calculation */
#define NORMALIZE_DATE(c_ptr) \
   if ((c_ptr)->YEAR < 1980) (c_ptr)->YEAR = 1980

/* Macros for byte exchanges between host and disk */

/*
** This set of macros will always work on all processors.
** The sets of macros above are just optimizations for
** specific architectures.
*/
#if (PSP_MEMORY_ADDRESSING_CAPABILITY == 8)

    #define htodl(p,x) ((p)[3] = (uchar) ((x) >> 24) , \
                    (p)[2] = (uchar)((x) >> 16) , \
                    (p)[1] = (uchar)((x) >>  8) , \
                    (p)[0] = (uchar)((x)      )  \
                   )

    #define htods(p,x) ((p)[1] = (uchar) ((x) >>  8) , \
                    (p)[0] = (uchar) ((x)      )   \
                   )
    #define htodc(p,x) ((p)[0] = ((x)      )  \
                   )

    #define dtohl(p)   ((((uint_32)(p)[3] ) << 24) | \
                    (((uint_32)(p)[2] ) << 16) | \
                    (((uint_32)(p)[1] ) <<  8) | \
                    (((uint_32)(p)[0] )      ))

    #define dtohs(p)   ((((uint_16)(p)[1] ) <<  8) | \
                    (((uint_16)(p)[0] )      ))

    #define dtohc(p)   ((((  uchar)(p)[0] )      ))



/* Special Macros for reading and writing the FAT */
    #define htof0(p,x)    ((p)[0]  = (uchar) (x)        , \
                       (p)[1] &=              0x000000F0L, \
                       (p)[1] |= (uchar)((x) >> 8) & 0x0000000FL  \
                      )

    #define htof1(p,x)    ((p)[0] &=               0x0000000FL, \
                       (p)[0] |= (uchar)((x) <<  4) & 0x000000F0L, \
                       (p)[1]  =(uchar) ((x) >>  4)   \
                      )

    #define ftoh0(p)      (((uint_32)((p)[0]       )       ) | \
                       ((uint_32)((p)[1] & 0x0F) <<  8 ))

    #define ftoh1(p)      (((uint_32)((p)[0] & 0xF0) >>  4 ) | \
                       ((uint_32)((p)[1]       ) <<  4 ))

    #define htof32(p,x)   ((p)[3] = (uchar)(((p)[3] & 0xF0) | (((x) >> 24) & 0x0F)), \
                       (p)[2] = (uchar)((x) >> 16) , \
                       (p)[1] = (uchar)((x) >>  8) , \
                       (p)[0] = (uchar)((x)      ) )
#else
/*
** This set of macros will always work on all processors.
** The sets of macros above are just optimizations for
** specific architectures.
*/
    #define htodl(p,x) ((p)[3] = ((x) >> 24) & 0xFF, \
                    (p)[2] = ((x) >> 16) & 0xFF, \
                    (p)[1] = ((x) >>  8) & 0xFF, \
                    (p)[0] = ((x)      ) & 0xFF  \
                   )

    #define htods(p,x) ((p)[1] = ((x) >>  8) & 0xFF, \
                    (p)[0] = ((x)      ) & 0xFF  \
                   )

    #define htodc(p,x) ((p)[0] = ((x)      ) & 0xFF \
                   )

    #define dtohl(p)   ((((uint_32)(p)[3] & 0xFF) << 24) | \
                    (((uint_32)(p)[2] & 0xFF) << 16) | \
                    (((uint_32)(p)[1] & 0xFF) <<  8) | \
                    (((uint_32)(p)[0] & 0xFF)      ))

    #define dtohs(p)   ((((uint_16)(p)[1] & 0xFF) <<  8) | \
                    (((uint_16)(p)[0] & 0xFF)      ))

    #define dtohc(p)   ((((  uchar)(p)[0] & 0xFF)      ))



/* Special Macros for reading and writing the FAT */

    #define htof0(p,x)    ((p)[0]  = (x)        & 0x000000FFL, \
                       (p)[1] &=              0x000000F0L, \
                       (p)[1] |= ((x) >> 8) & 0x0000000FL  \
                      )

    #define htof1(p,x)    ((p)[0] &=               0x0000000FL, \
                       (p)[0] |= ((x) <<  4) & 0x000000F0L, \
                       (p)[1]  = ((x) >>  4) & 0x000000FFL  \
                      )

    #define ftoh0(p)      (((uint_32)((p)[0]       )       & 0x000000FFL) | \
                       ((uint_32)((p)[1] & 0x0F) <<  8 & 0x0000FF00L))

    #define ftoh1(p)      (((uint_32)((p)[0] & 0xF0) >>  4 & 0x000000FFL) | \
                       ((uint_32)((p)[1]       ) <<  4 & 0x00000FF0L))

    #define htof32(p,x)   ((p)[3] = ((p)[3] & 0xF0) | (((x) >> 24) & 0x0F), \
                       (p)[2] = ((x) >> 16) & 0xFF, \
                       (p)[1] = ((x) >>  8) & 0xFF, \
                       (p)[0] = ((x)      ) & 0xFF)
#endif


/*
** Macros for getting/setting cluster, using a sperate high and low word
*/
#if (PSP_MEMORY_ADDRESSING_CAPABILITY == 8)

    #define clustoh(high,low) \
  (((((uint_32)(low)[0]  )      )  | \
    (((uint_32)(low)[1]  ) <<  8)  | \
    (((uint_32)(high)[0] ) << 16)  | \
    (((uint_32)(high)[1] ) << 24)) & \
   ((drive_ptr->FAT_TYPE == MFS_FAT32) ? 0xFFFFFFFF : 0x0000FFFF))

    #define clustod(high,low,x)   \
   ((low)[0]  = (uchar) ((x)      ) , \
    (low)[1]  = (uchar) ((x) >>  8) , \
    (high)[0] = (uchar) ((x) >> 16) , \
    (high)[1] = (uchar) ((x) >> 24))
#else

    #define clustoh(high,low) \
  (((((uint_32)(low)[0]  & 0xFF)      )  | \
    (((uint_32)(low)[1]  & 0xFF) <<  8)  | \
    (((uint_32)(high)[0] & 0xFF) << 16)  | \
    (((uint_32)(high)[1] & 0xFF) << 24)) & \
   ((drive_ptr->FAT_TYPE == MFS_FAT32) ? 0xFFFFFFFF : 0x0000FFFF))

    #define clustod(high,low,x)   \
   ((low)[0]  = ((x)      ) & 0xFF, \
    (low)[1]  = ((x) >>  8) & 0xFF, \
    (high)[0] = ((x) >> 16) & 0xFF, \
    (high)[1] = ((x) >> 24) & 0xFF)
#endif


/*
** extern statements for MFS
*/
#ifdef __cplusplus
extern "C" {
#endif

#ifndef _mqx_str_h_
    extern uint_32 _strnlen(char_ptr, uint_32);
#endif

extern uint_32                _mfs_partition_destroy(_partition_id);
extern _mfs_error             _mfs_validate_device(MQX_FILE_PTR, uint_32_ptr, boolean _PTR_);
extern _mfs_error             MFS_Add_cluster_to_chain(MFS_DRIVE_STRUCT_PTR, uint_32, uint_32_ptr);
extern boolean                MFS_Attribute_match(uchar, uchar);
extern uint_32                MFS_Bad_clusters(MQX_FILE_PTR);
extern uint_32                MFS_Change_current_dir(MQX_FILE_PTR, char_ptr);
extern uint_32                MFS_Check_dir_exist(MQX_FILE_PTR, char_ptr);
extern boolean                MFS_Check_search_string_for_8dot3(char_ptr);
extern boolean                MFS_Check_search_string_for_all(char_ptr);
extern uint_32                MFS_Clear_cluster(MFS_DRIVE_STRUCT_PTR, uint_32);
extern int_32                 MFS_Close_Device(MQX_FILE_PTR);
extern int_32                 MFS_Close_file(MQX_FILE_PTR);
extern void                   MFS_Compress_nondotfile(char_ptr, char_ptr);
extern MFS_DIR_ENTRY_PTR      MFS_Create_directory_entry(MFS_DRIVE_STRUCT_PTR, char_ptr, char, uint_32_ptr, uint_32_ptr, uint_32_ptr);
extern MFS_DIR_ENTRY_PTR      MFS_Create_entry_slave(MFS_DRIVE_STRUCT_PTR, uchar, char_ptr, uint_32_ptr, uint_32_ptr, uint_32_ptr, boolean);
extern pointer                MFS_Create_file(MQX_FILE_PTR, uchar, char_ptr, uint_32_ptr);
extern pointer                MFS_Create_new_file(MQX_FILE_PTR, uchar, char_ptr, uint_32_ptr);
extern uint_32                MFS_Create_subdir(MQX_FILE_PTR, char_ptr);
extern pointer                MFS_Create_temp_file(MQX_FILE_PTR, uchar, char_ptr, uint_32_ptr);
extern void                   MFS_Decrement_free_clusters(MFS_DRIVE_STRUCT_PTR);
extern _mfs_error             MFS_Default_Format(MQX_FILE_PTR);
extern uint_32                MFS_Delete_file(MQX_FILE_PTR, char_ptr);
extern int_32                 MFS_device_write_internal(MFS_DRIVE_STRUCT_PTR, uint_32, char_ptr, int_32_ptr, char_ptr _PTR_, int_32);
extern boolean                MFS_Dirname_valid(char_ptr);
extern void                   MFS_Expand_dotfile(char_ptr, char_ptr);
extern void                   MFS_Expand_wildcard(char_ptr, char_ptr);
extern _mfs_error             MFS_Extend_chain(MFS_DRIVE_STRUCT_PTR, uint_32, uint_32, uint_32_ptr);
extern boolean                MFS_Filename_valid(char_ptr);
extern uint_32                MFS_Find_directory(MFS_DRIVE_STRUCT_PTR, char_ptr, uint_32);
extern MFS_DIR_ENTRY_PTR      MFS_Find_directory_entry(MFS_DRIVE_STRUCT_PTR, char_ptr, uint_32_ptr, uint_32_ptr, uint_32_ptr, uchar, uint_32_ptr);
extern MFS_DIR_ENTRY_PTR      MFS_Find_entry_on_disk(MFS_DRIVE_STRUCT_PTR, char_ptr, uint_32_ptr, uint_32_ptr, uint_32_ptr, uint_32_ptr);
extern uint_32                MFS_Find_first_file(MQX_FILE_PTR, uchar, char_ptr, MFS_SEARCH_DATA_PTR);
extern MFS_HANDLE_PTR         MFS_Find_handle(MFS_DRIVE_STRUCT_PTR, uint_32, uint_32);
extern uint_32                MFS_Find_next_file(MQX_FILE_PTR, MFS_SEARCH_DATA_PTR);
extern uint_32                MFS_Find_next_slave(MFS_DRIVE_STRUCT_PTR, pointer);
extern uint_32                MFS_Find_unused_cluster_from(MFS_DRIVE_STRUCT_PTR, uint_32);
extern _mfs_error             MFS_Flush_caches(MFS_DRIVE_STRUCT_PTR);
extern uint_32                MFS_Flush_data_sector_buffer(MFS_DRIVE_STRUCT_PTR);
extern uint_32                MFS_Flush_directory_sector_buffer(MFS_DRIVE_STRUCT_PTR);
extern uint_32                MFS_Flush_fat_cache(MFS_DRIVE_STRUCT_PTR);
extern uint_32                MFS_Format(MQX_FILE_PTR, MFS_FORMAT_DATA_PTR);
extern uint_32                MFS_Format_and_test(MQX_FILE_PTR, MFS_FORMAT_DATA_PTR, uint_32_ptr);
extern void                   MFS_Free_handle(MFS_DRIVE_STRUCT_PTR, MFS_HANDLE_PTR);
extern _mfs_error             MFS_get_cluster_from_fat(MFS_DRIVE_STRUCT_PTR, uint_32, uint_32_ptr);
extern uint_32                MFS_Get_current_dir(MQX_FILE_PTR, char_ptr);
extern uint_32                MFS_Get_date_time(MQX_FILE_PTR, uint_16_ptr, uint_16_ptr);
extern uint_64                MFS_Get_disk_free_space(MQX_FILE_PTR);
extern uint_32                MFS_Get_disk_free_space_internal(MFS_DRIVE_STRUCT_PTR, uint_32_ptr);
extern uint_32                MFS_Get_file_attributes(MQX_FILE_PTR, char_ptr, uchar_ptr);
extern MFS_HANDLE_PTR         MFS_Get_handle(MFS_DRIVE_STRUCT_PTR, MFS_DIR_ENTRY_PTR);
extern uint_32                MFS_get_lfn(MFS_DRIVE_STRUCT_PTR, char_ptr, char_ptr);
extern uint_32                MFS_get_lfn_dir_cluster(MFS_DRIVE_STRUCT_PTR, pointer, char_ptr, char_ptr);
extern _mfs_error             MFS_get_lfn_of_entry(MFS_DRIVE_STRUCT_PTR, MFS_DIR_ENTRY_PTR, uint_32, uint_32, uint_32, char_ptr);
extern uint_32                MFS_get_prev_cluster(MFS_DRIVE_STRUCT_PTR, uint_32_ptr, uint_32);
extern uint_32                MFS_Get_volume(MQX_FILE_PTR, char_ptr);
extern uint_32                MFS_Increment_dir_index(MFS_DRIVE_STRUCT_PTR, uint_32_ptr, uint_32_ptr, uint_32_ptr);
extern void                   MFS_Increment_free_clusters(MFS_DRIVE_STRUCT_PTR);
extern void                   MFS_increment_lfn(char_ptr);
extern _mfs_error             MFS_Invalidate_data_sector(MFS_DRIVE_STRUCT_PTR);
extern _mfs_error             MFS_Invalidate_directory_sector(MFS_DRIVE_STRUCT_PTR);
extern uint_16                MFS_Is_dot_directory(char_ptr);
extern boolean                MFS_is_valid_lfn(char_ptr);
extern uint_32                MFS_Last_cluster(MQX_FILE_PTR);
extern uchar                  MFS_lfn_checksum(char_ptr);
extern boolean                MFS_lfn_dirname_valid(char_ptr);
extern void                   MFS_lfn_extract(MFS_LNAME_ENTRY_PTR, char_ptr);
extern boolean                MFS_lfn_match(char_ptr, char_ptr, uint_32) ;
extern uint_32                MFS_lfn_name_to_entry(char_ptr, MFS_LNAME_ENTRY_PTR);
extern uint_32                MFS_lfn_to_sfn(char_ptr, char_ptr);
extern uint_32                MFS_lock(MQX_FILE_PTR, MFS_DRIVE_STRUCT_PTR _PTR_);
extern uint_32                MFS_lock_dos_disk(MQX_FILE_PTR, MFS_DRIVE_STRUCT_PTR _PTR_);
extern uint_32                MFS_lock_handle(MQX_FILE_PTR, MFS_DRIVE_STRUCT_PTR _PTR_, MFS_HANDLE_PTR _PTR_);
extern uint_32                MFS_Mount_drive_internal(MFS_DRIVE_STRUCT_PTR);
extern uint_32                MFS_Move_file_pointer(MQX_FILE_PTR, uint_32_ptr);
extern _mfs_error             MFS_next_data_sector(MFS_DRIVE_STRUCT_PTR, MFS_HANDLE_PTR, uint_32_ptr, uint_32_ptr);
extern int_32                 MFS_Open_Device(MQX_FILE_PTR, MFS_DRIVE_STRUCT_PTR);
extern pointer                MFS_Open_file(MQX_FILE_PTR, char_ptr, uchar, uint_32_ptr);
extern char_ptr               MFS_Parse_next_filename(char_ptr, char_ptr);
extern char_ptr               MFS_Parse_Out_Device_Name(char_ptr);
extern uint_32                MFS_Parse_pathname(char_ptr, char_ptr, char_ptr);
extern uint_32                MFS_Put_fat(MFS_DRIVE_STRUCT_PTR, uint_32, uint_32);
extern uint_32                MFS_Read(MQX_FILE_PTR, uint_32, char_ptr, uint_32_ptr);
extern _mfs_error             MFS_Read_data_sector(MFS_DRIVE_STRUCT_PTR, MFS_HANDLE_PTR, uint_32, boolean);
extern _mfs_error             MFS_Read_device_sectors(MFS_DRIVE_STRUCT_PTR, uint_32, uint_32, uint_32, char_ptr, uint_32_ptr);
extern _mfs_error             MFS_Read_device_sector(MFS_DRIVE_STRUCT_PTR, uint_32, char_ptr);
extern pointer                MFS_Read_directory_sector(MFS_DRIVE_STRUCT_PTR, uint_32, uint_16, uint_32_ptr);
extern uint_32                MFS_Read_fat(MFS_DRIVE_STRUCT_PTR, uint_32);
extern _mfs_error             MFS_Release_chain(MFS_DRIVE_STRUCT_PTR, uint_32);
extern uint_32                MFS_remove_lfn_entries(MFS_DRIVE_STRUCT_PTR, uint_32, uint_32, uint_32);
extern uint_32                MFS_Remove_subdir(MQX_FILE_PTR, char_ptr);
extern uint_32                MFS_Rename_file(MQX_FILE_PTR, char_ptr, char_ptr);
extern uint_32                MFS_Set_date_time(MQX_FILE_PTR, uint_16_ptr, uint_16_ptr);
extern uint_32                MFS_Set_file_attributes(MQX_FILE_PTR, char_ptr, uchar_ptr);
extern uint_32                MFS_Set_volume(MQX_FILE_PTR, char_ptr);
extern boolean                MFS_strcmp(char_ptr, char_ptr, uint_32);
extern void                   MFS_strupr(char_ptr);
extern uint_32                MFS_Test_unused_clusters(MQX_FILE_PTR, uint_32_ptr);

_mfs_error MFS_unlock(MFS_DRIVE_STRUCT_PTR, boolean);

extern uint_32                MFS_Update_entry(MFS_DRIVE_STRUCT_PTR, MFS_HANDLE_PTR);
extern boolean                MFS_Wildcard_match(char_ptr, char_ptr);
extern uint_32                MFS_Write(MQX_FILE_PTR, uint_32, char_ptr, uint_32_ptr);
extern _mfs_error             MFS_Write_back_fat(MFS_DRIVE_STRUCT_PTR);
extern uint_32                MFS_Write_back_fat(MFS_DRIVE_STRUCT_PTR);
extern _mfs_error             MFS_Write_device_sectors(MFS_DRIVE_STRUCT_PTR, uint_32, uint_32, uint_32, char_ptr, uint_32_ptr);
extern _mfs_error             MFS_Write_device_sector(MFS_DRIVE_STRUCT_PTR, uint_32, char_ptr);
extern boolean                MFS_is_read_only(MQX_FILE_PTR, MFS_DRIVE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_read.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_read.c$
* $Version : 3.8.13.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_prv.h>

#if SHELLCFG_USES_MFS

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_read
* Returned Value   :  int_32 error code
* Comments  :  Reads from a file .
*
*END*---------------------------------------------------------------------*/

int_32  Shell_read(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   uint_32           count, bytes;
   int_32            offset;
   int_32         seek_mode;
   MQX_FILE_PTR      fd = NULL;
   char_ptr          abs_path;   
   _mqx_int          c;      
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   int_32               error = 0;   

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if ((argc < 2) || (argc > 5)) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else  {
         count = 0;
         offset = 0;
         seek_mode = IO_SEEK_CUR; 
         if (argc >= 3)  {
            if ( !Shell_parse_uint_32(argv[2], &count ))  {
               printf("Error, invalid length\n");
               return_code = SHELL_EXIT_ERROR;
               print_usage=TRUE;
            } 
            /* check if filesystem is mounted */ 
            else if (NULL == Shell_get_current_filesystem(argv))  
            {
               printf("Error, file system not mounted\n");
               return_code = SHELL_EXIT_ERROR;
            }            
            else  {
               if (argc >= 5)  {
                  if (strcmp(argv[3], "begin") == 0) {
                     seek_mode = IO_SEEK_SET;
                  } else if (strcmp(argv[3], "end") == 0) { 
                     seek_mode = IO_SEEK_END;
                  } else if (strcmp(argv[3], "current") == 0) { 
                     seek_mode = IO_SEEK_CUR;
                  } else { 
                     printf("Error, invalid seek type\n");
                     return_code = SHELL_EXIT_ERROR;
                     print_usage=TRUE;
                  }
                  
                  if (return_code == SHELL_EXIT_SUCCESS)  {
                     if (! Shell_parse_int_32(argv[4], &offset ))  {
                        printf("Error, invalid seek value\n");
                        return_code = SHELL_EXIT_ERROR;
                        print_usage=TRUE;
                     }
                  }
               }
            }
         }

         if (return_code == SHELL_EXIT_SUCCESS)  {
            if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
               printf("Error, unable to allocate memory for paths\n" );
               return_code = SHELL_EXIT_ERROR;
            } else {
               error = _io_rel2abs(abs_path,shell_ptr->CURRENT_DIR,(char *) argv[1],PATHNAME_SIZE,shell_ptr->CURRENT_DEVICE_NAME);
               if(!error)
               {
                  fd = fopen(abs_path, "r");
               }
               MFS_free_path(abs_path);
               if (fd && !error)  {
                  bytes = 0;
                  if (fseek(fd, offset, seek_mode) != IO_ERROR)  {
                     printf("Reading from %s:\n", argv[1]);
                     while ((c=fgetc(fd))>=0) {
                        fputc(c, stdout);
                        if (++bytes == count) break;
                     } 
                     printf("\nDone.\n");
                     fclose(fd);
                  } else  {
                     printf("Error, unable to seek file %s.\n", argv[1] );
                     return_code = SHELL_EXIT_ERROR;
                  }
               } else  {
                  printf("Error, unable to open file %s.\n", argv[1] );
                  return_code = SHELL_EXIT_ERROR;
               }
            }
         }
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <filename> <bytes> [<seek_mode>] [<offset>]\n", argv[0]);
      } else  {
         printf("Usage: %s <filename> <bytes> [<seek_mode>] [<offset>]\n", argv[0]);
         printf("   <filename>   = filename to display\n");
         printf("   <bytes>      = number of bytes to read\n");
         printf("   <seek_mode>  = one of: begin, end or current\n");
         printf("   <offset>     = seek offset\n");
      }
   }
   return return_code;
} /* Endbody */

#endif //SHELLCFG_USES_MFS

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/polled/serl_pol_linflexd.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_pol_linflexd.c$
* $Version : 3.8.7.0$
* $Date    : Sep-26-2012$
*
* Comments:
*
*   This file contains the driver functions for the LINFLEXD
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "io_prv.h"
#include "charq.h"
#include "fio_prv.h"
#include "serplprv.h"

#include "serl_linflexd.h"


/* Polled driver functions */
extern _mqx_uint _linflexd_serial_polled_init(LINFLEXD_SERIAL_INIT_STRUCT_CPTR, pointer _PTR_, char_ptr);
extern _mqx_uint _linflexd_serial_polled_deinit(LINFLEXD_SERIAL_INIT_STRUCT_PTR, LINFLEXD_SERIAL_INFO_STRUCT_PTR );
static char      _linflexd_serial_polled_getc(LINFLEXD_SERIAL_INFO_STRUCT_PTR);
static void      _linflexd_serial_polled_putc(LINFLEXD_SERIAL_INFO_STRUCT_PTR, char);
static boolean   _linflexd_serial_polled_status(LINFLEXD_SERIAL_INFO_STRUCT_PTR);
extern _mqx_uint _linflexd_serial_polled_ioctl(LINFLEXD_SERIAL_INFO_STRUCT_PTR, _mqx_uint, pointer);
extern uint_32   _linflexd_uart_serial_int_enable(LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr);


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _linflexd_serial_polled_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a polled linflexd_ptr serial device.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _linflexd_serial_polled_install
    (
        /* [IN] A string that identifies the device for fopen */
        char_ptr           identifier,

        /* [IN] The I/O init data pointer */
        LINFLEXD_SERIAL_INIT_STRUCT_CPTR  init_data_ptr
    )
{
    return _io_serial_polled_install(identifier,
        (_mqx_uint (_CODE_PTR_)(pointer, pointer _PTR_, char _PTR_)) _linflexd_serial_polled_init,
        (_mqx_uint (_CODE_PTR_)(pointer, pointer))  _linflexd_serial_polled_deinit,
        (char (_CODE_PTR_)(pointer)) _linflexd_serial_polled_getc,
        (void (_CODE_PTR_)(pointer, char)) _linflexd_serial_polled_putc,
        (boolean (_CODE_PTR_)(pointer)) _linflexd_serial_polled_status,
        (_mqx_uint (_CODE_PTR_)(pointer, _mqx_uint, pointer)) _linflexd_serial_polled_ioctl,
        (pointer)init_data_ptr, init_data_ptr->QUEUE_SIZE);
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _linflexd_serial_reconfigure
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*
*
*END*----------------------------------------------------------------------*/

static uint_32 _linflexd_serial_reconfigure
    (
        LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr
    )
{
    VLINFLEXD_REG_STRUCT_PTR linflexd_ptr;
    uint_32 uartcr;
    uint_32 lfdiv;
    uint_32 linier;


    if (io_info_ptr->INIT.STOP_BITS != IO_SERIAL_STOP_BITS_1) {
        return MQX_INVALID_PARAMETER;
    }

    uartcr = LINFLEXD_UARTCR_UART;
    
#if !defined(PSP_MPXD10) /*PXD10 doesn't support*/
    if (io_info_ptr->CONTROL_BITS & LINFLEXD_FIFO_MODE) {
         // Use FIFOs in polled mode, buffers in interrupt mode
         // Setup in fifo mode with max fifo size.
         uartcr |=  LINFLEXD_UARTCR_TFBM |  LINFLEXD_UARTCR_RFBM;
    }
#endif    

    switch (io_info_ptr->INIT.PARITY) {
        case IO_SERIAL_PARITY_EVEN:
            uartcr |= LINFLEXD_UARTCR_PCE;
            break;
        case IO_SERIAL_PARITY_ODD:
#if defined(PSP_MPXD10)
            uartcr |= LINFLEXD_UARTCR_PCE | LINFLEXD_UARTCR_OP;
#else
            uartcr |= LINFLEXD_UARTCR_PCE | LINFLEXD_UARTCR_PC0;            
#endif            
            break;
            
#if defined(PSP_MPXD10)
            /* MPC5606S does not support IO_SERIAL_PARITY_SPACE & IO_SERIAL_PARITY_MARK */
#else
            
        case IO_SERIAL_PARITY_SPACE:
            uartcr |= LINFLEXD_UARTCR_PCE | LINFLEXD_UARTCR_PC1;
            break;

        case IO_SERIAL_PARITY_MARK:
            uartcr |= LINFLEXD_UARTCR_PCE | LINFLEXD_UARTCR_PC1 | LINFLEXD_UARTCR_PC0;
            break;
#endif                        
        case IO_SERIAL_PARITY_NONE:
            if (io_info_ptr->INIT.BITS_PER_CHARACTER==7) {
                return MQX_INVALID_PARAMETER;
            }
            break;

        default:
            return MQX_INVALID_PARAMETER;
            break;
    }

    switch (io_info_ptr->INIT.BITS_PER_CHARACTER) {
        case 7:
            break;
        case 8:
            uartcr |= LINFLEXD_UARTCR_WL0;
            break;
        default:
            return MQX_INVALID_PARAMETER;
            break;
    }

    // TODO: Turn on linflexd clock if required..

    linflexd_ptr = (VLINFLEXD_REG_STRUCT_PTR)io_info_ptr->LINFLEXD_PTR;

    /* Save interrupt enable state - reconfigure may be done from polled or interrupt mode driver */
    linier = linflexd_ptr->LINIER;

    /* Go into init mode */
    linflexd_ptr->LINCR1 = LINFLEXD_LINCR1_INIT;
    linflexd_ptr->LINCR1 = LINFLEXD_LINCR1_INIT;

    /* Select UART mode and set parameters */
    linflexd_ptr->UARTCR = LINFLEXD_UARTCR_UART;
    linflexd_ptr->UARTCR = uartcr;

    /* Calculate baud rate */
    lfdiv =  (io_info_ptr->INIT.CLOCK_SPEED*2/io_info_ptr->INIT.BAUD_RATE + 1)/2;
    linflexd_ptr->LINFBRR = lfdiv & 0xf;
    linflexd_ptr->LINIBRR = lfdiv>>4;

    /* Disable interrupts */
    linflexd_ptr->LINIER = 0;

    /* Enable Tx and Rx */
    uartcr |= LINFLEXD_UARTCR_RXEN | LINFLEXD_UARTCR_TXEN;
    linflexd_ptr->UARTCR = uartcr;

    /* Leave init mode */
    linflexd_ptr->LINCR1 &= ~LINFLEXD_LINCR1_INIT;

    /* Restore interrupt enable state */
    linflexd_ptr->LINIER = linier;

    return MQX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_init
* Returned Value   : MQX_OK or a MQX error code.
* Comments         :
*    This function initializes LINFlexD in UART mode
*
*END*********************************************************************/

uint_32 _linflexd_serial_init
    (
        /* [IN] the initialization information for the device being opened */
        LINFLEXD_SERIAL_INIT_STRUCT_CPTR    io_init_ptr,

        /* [OUT] the address to store device specific information */
        pointer _PTR_                       io_info_ptr_ptr,

        /* [IN] the rest of the name of the device opened */
        char _PTR_                          open_name_ptr,

        /* [IN] the uart mode to use */
        uint_32                             mode
    )
{
    VLINFLEXD_REG_STRUCT_PTR         linflexd_ptr;
    LINFLEXD_SERIAL_INFO_STRUCT_PTR  io_info_ptr;
    uint_32                          channel;
    uint_32                          result;

    /* Get peripheral address */
    channel = io_init_ptr->DEVICE;

    #if PSP_HAS_DEVICE_PROTECTION
    if (!_bsp_linflexd_enable_access(channel)) {
        return MQX_INVALID_IO_CHANNEL;
    }
    #endif

    linflexd_ptr = _bsp_get_linflexd_base_address(channel);
    if (linflexd_ptr == NULL) {
        return MQX_INVALID_IO_CHANNEL;
    }

    io_info_ptr = (LINFLEXD_SERIAL_INFO_STRUCT_PTR)_mem_alloc_system_zero(
        (_mem_size)sizeof(LINFLEXD_SERIAL_INFO_STRUCT));

    #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (io_info_ptr == NULL) {
        return MQX_OUT_OF_MEMORY;
    }
    #endif

    /* Save initialization values and base address */
    io_info_ptr->INIT = *io_init_ptr;

    /* Polled driver uses fifo mode, int driver uses buffered mode */
    io_info_ptr->CONTROL_BITS = mode;

    /* Store pointer to linflexd registers */
    io_info_ptr->LINFLEXD_PTR = linflexd_ptr;

    /* Disable interrupts*/
    linflexd_ptr->LINIER = 0;

    /* init GPIO and clock GATING */
    _bsp_serial_io_init(channel);

    result = _linflexd_serial_reconfigure(io_info_ptr);
    if (result!=MQX_OK) {
        _mem_free(io_info_ptr);
        io_info_ptr = NULL;
    }
    *io_info_ptr_ptr = io_info_ptr;

    return result;
} 

/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_polled_init
* Returned Value   : MQX_OK or a MQX error code.
* Comments         :
*    This function initializes LINFlexD in UART mode
*
*END*********************************************************************/

uint_32 _linflexd_serial_polled_init
    (
        /* [IN] the initialization information for the device being opened */
        LINFLEXD_SERIAL_INIT_STRUCT_CPTR    io_init_ptr,

        /* [OUT] the address to store device specific information */
        pointer _PTR_                       io_info_ptr_ptr,

        /* [IN] the rest of the name of the device opened */
        char _PTR_                          open_name_ptr
    )
{
    return _linflexd_serial_init(io_init_ptr, io_info_ptr_ptr, open_name_ptr, LINFLEXD_FIFO_MODE);
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_polled_deinit
* Returned Value   : MQX_OK or a mqx error code.
* Comments         :
*    This function de-initializes the UART
*
*END*********************************************************************/

_mqx_uint _linflexd_serial_polled_deinit
    (
        /* [IN] the initialization information for the device being opened */
        LINFLEXD_SERIAL_INIT_STRUCT_PTR io_init_ptr,

        /* [IN] the address of the device specific information */
        LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr
    )
{
    _mem_free((pointer)io_info_ptr);

    return MQX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_polled_getc
* Returned Value   : char
* Comments         :
*   Return a character when it is available.
*   This function polls the device for input.
*
*************************************************************************/

static char _linflexd_serial_polled_getc
    (
        /* [IN] the address of the device specific information */
        LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr
    )
{
    VLINFLEXD_REG_STRUCT_PTR linflexd_ptr = io_info_ptr->LINFLEXD_PTR;
    uchar data;
#if defined(PSP_MPXD10)
    while ((linflexd_ptr->UARTSR & LINFLEXD_UARTSR_DRFRFE) == 0)
         ;
    linflexd_ptr->UARTSR = LINFLEXD_UARTSR_DRFRFE;    
#else
    while ((linflexd_ptr->UARTCR&LINFLEXD_UARTCR_RDFLRFC_MASK) == 0)
         ; /* Wait until there is a character available */
#endif		 

    data = linflexd_ptr->BDRM[3];

    io_info_ptr->STATS.RX_CHARS++;
 
    return (char)data;
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_polled_putc
* Returned Value   : void
* Comments         :
*   Writes the provided character.
*
*END*********************************************************************/

static void _linflexd_serial_polled_putc
    (
        /* [IN] the address of the device specific information */
        LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr,

        /* [IN] the character to write */
        char                           c
    )
{
    VLINFLEXD_REG_STRUCT_PTR linflexd_ptr = io_info_ptr->LINFLEXD_PTR;
#ifndef PSP_MPXD10
    while (((linflexd_ptr->UARTCR&LINFLEXD_UARTCR_TDFLTFC_MASK)>>LINFLEXD_UARTCR_TDFLTFC_SHIFT) >= 4)
      ; /* Wait until there is a room for a character (less than 4 FIFO positions occupied) */
    linflexd_ptr->BDRL[3] = c;
#else
     /* Clear DTF bit first*/
    linflexd_ptr->UARTSR = LINFLEXD_UARTSR_DTFTFF;    
    linflexd_ptr->BDRL[3] = c;
    
    /* Wait until data is transmitted */
    while (!(linflexd_ptr->UARTSR & LINFLEXD_UARTSR_DTFTFF))
                     	;
#endif


   io_info_ptr->STATS.TX_CHARS++;   
        
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_polled_status
* Returned Value   : boolean
* Comments         :
*            This function returns TRUE if a character is available
*            on the on I/O device, otherwise it returns FALSE.
*
*END*********************************************************************/

static boolean _linflexd_serial_polled_status
    (
        /* [IN] the address of the device specific information */
        LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr
    )
{
    VLINFLEXD_REG_STRUCT_PTR linflexd_ptr = io_info_ptr->LINFLEXD_PTR;
#ifndef PSP_MPXD10
    if ((linflexd_ptr->UARTCR&LINFLEXD_UARTCR_RDFLRFC_MASK)!=0)
#else
    if ( linflexd_ptr->UARTSR & LINFLEXD_UARTSR_DRFRFE )
#endif	
         return TRUE;
    else
         return FALSE;
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_polled_ioctl
* Returned Value   : uint_32 MQX_OK or a mqx error code.
* Comments         :
*    This function performs miscellaneous services for
*    the I/O device.
*
*END*********************************************************************/

uint_32 _linflexd_serial_polled_ioctl
    (
        /* [IN] the address of the device specific information */
        LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr,

        /* [IN] The command to perform */
        _mqx_uint                      cmd,

        /* [IN] Parameters for the command */
        pointer                        param_ptr
    )
{
    uint_32_ptr u32_ptr = (uint_32_ptr)param_ptr;

    switch (cmd) {

    case IO_IOCTL_SERIAL_GET_STOP_BITS:
        *u32_ptr = io_info_ptr->INIT.STOP_BITS;
        return MQX_OK;

    case IO_IOCTL_SERIAL_SET_STOP_BITS:
        if (*u32_ptr != IO_SERIAL_STOP_BITS_1)
            return MQX_INVALID_PARAMETER;

    case IO_IOCTL_SERIAL_GET_DATA_BITS:
        *u32_ptr = io_info_ptr->INIT.BITS_PER_CHARACTER;
        break;

    case IO_IOCTL_SERIAL_SET_DATA_BITS:
        io_info_ptr->INIT.BITS_PER_CHARACTER = *u32_ptr;
        return _linflexd_serial_reconfigure(io_info_ptr);

    case IO_IOCTL_SERIAL_GET_BAUD:
        *u32_ptr = io_info_ptr->INIT.BAUD_RATE;
        break;

    case IO_IOCTL_SERIAL_SET_BAUD:
        io_info_ptr->INIT.BAUD_RATE = *u32_ptr;
        return _linflexd_serial_reconfigure(io_info_ptr);

    case IO_IOCTL_SERIAL_GET_STATS:
        {
            LINFLEXD_STATS_STRUCT_PTR stats_ptr = (LINFLEXD_STATS_STRUCT_PTR)param_ptr;
            *stats_ptr = io_info_ptr->STATS;
        }
        break;

    case IO_IOCTL_SERIAL_CLEAR_STATS:
        _mem_zero((pointer) &io_info_ptr->STATS, sizeof(io_info_ptr->STATS));
        break;

    case IO_IOCTL_SERIAL_GET_CONFIG:
        {
            LINFLEXD_SERIAL_INIT_STRUCT_PTR io_init_ptr = (LINFLEXD_SERIAL_INIT_STRUCT_PTR)param_ptr;
            *io_init_ptr = io_info_ptr->INIT;
        }
        break;

    case IO_IOCTL_SERIAL_GET_PARITY:
        *(uint_32_ptr)param_ptr = io_info_ptr->INIT.PARITY;
        break;
        
    case IO_IOCTL_SERIAL_SET_PARITY:
        switch (*(uint_32_ptr)param_ptr) {
            case IO_SERIAL_PARITY_NONE:
            case IO_SERIAL_PARITY_ODD:
            case IO_SERIAL_PARITY_EVEN:
            case IO_SERIAL_PARITY_MARK:
            case IO_SERIAL_PARITY_SPACE:
                break;
            default:
                return MQX_INVALID_PARAMETER;
        }
        io_info_ptr->INIT.PARITY = *(uint_32_ptr)param_ptr;
        return _linflexd_serial_reconfigure(io_info_ptr);

    default:
        return IO_ERROR_INVALID_IOCTL_CMD;
    }

    return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sdcard/sdcard.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sdcard.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the sd card driver functions.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>
#include <io_prv.h>
#include <sdcard_prv.h>
#include <sdcard.h>

static _mqx_int _io_sdcard_uninstall(IO_DEVICE_STRUCT_PTR);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_install
* Returned Value   : MQX error code
* Comments         :
*    Install a SDCARD driver.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr               identifier,

      /* [IN] SD card initialization parameters */
      SDCARD_INIT_STRUCT_PTR init,

      /* [IN] Already opened communication descriptor */
      MQX_FILE_PTR           com_device
   )
{
   SDCARD_STRUCT_PTR sdcard_ptr;

   if ((NULL == init) || (NULL == com_device))
   {
      return MQX_INVALID_PARAMETER;
   }

   sdcard_ptr = (SDCARD_STRUCT_PTR)
      _mem_alloc_system_zero((_mem_size)sizeof(SDCARD_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (sdcard_ptr == NULL)
   {
      return MQX_OUT_OF_MEMORY;
   }
#endif

   _mem_set_type(sdcard_ptr, MEM_TYPE_IO_SDCARD_STRUCT);

   sdcard_ptr->INIT = init;

   sdcard_ptr->COM_DEVICE = com_device;

   _lwsem_create(&sdcard_ptr->LWSEM, 1);

   return (_io_dev_install_ext(identifier,
      _io_sdcard_open,
      _io_sdcard_close,
      _io_sdcard_read_blocks,
      _io_sdcard_write_blocks,
      _io_sdcard_ioctl,
      _io_sdcard_uninstall,
      (pointer)sdcard_ptr));
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_uninstall
* Returned Value   : MQX error code
* Comments         :
*    Install a SDCARD driver.
*
*END*----------------------------------------------------------------------*/

static _mqx_int _io_sdcard_uninstall
   (
      /* [IN] The devices context */
      IO_DEVICE_STRUCT_PTR io_dev_ptr
   )
{
   SDCARD_STRUCT_PTR sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   _lwsem_destroy(&sdcard_ptr->LWSEM);

   _mem_free(sdcard_ptr);

   return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_open
* Returned Value   : MQX error code
* Comments         : Opens and initializes SDCARD driver.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the remaining portion of the name of the device */
      char_ptr open_name_ptr,

      /* [IN] the flags to be used during operation */
      char_ptr flags
   )
{
   IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
   SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   _mqx_int             result = MQX_OK;

   if (NULL != sdcard_ptr->INIT->INIT_FUNC)
   {
      _lwsem_wait(&sdcard_ptr->LWSEM);
      if (! sdcard_ptr->INIT->INIT_FUNC (fd_ptr))
      {
         result = MQX_IO_OPERATION_NOT_AVAILABLE;
      }
      _lwsem_post(&sdcard_ptr->LWSEM);
   }

   return result;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_close
* Returned Value   : MQX error code
* Comments         : Closes SDCARD driver
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR fd_ptr
   )
{
   return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_ioctl
* Returned Value   : MQX error code
* Comments         :
*    Returns result of ioctl operation.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint cmd,

      /* [IN] the ioctl parameters */
      pointer   param_ptr
   )
{
   IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
   SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   _mem_size_ptr        mparam_ptr;
   _mqx_uint_ptr        uparam_ptr;
   uint_32_ptr          u32param_ptr;
   _mqx_int             result = MQX_OK;

   switch (cmd)
   {
      case IO_IOCTL_SET_BLOCK_MODE:
         break;
      case IO_IOCTL_GET_BLOCK_SIZE:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = IO_SDCARD_BLOCK_SIZE;
         break;
      case IO_IOCTL_GET_NUM_SECTORS:
         mparam_ptr = (_mem_size_ptr)param_ptr;
         *mparam_ptr = (_mem_size)sdcard_ptr->NUM_BLOCKS;
         break;
      case IO_IOCTL_DEVICE_IDENTIFY:
         u32param_ptr  = (uint_32_ptr)param_ptr;
         u32param_ptr[IO_IOCTL_ID_PHY_ELEMENT]  = IO_DEV_TYPE_PHYS_SDCARD;
         u32param_ptr[IO_IOCTL_ID_LOG_ELEMENT]  = IO_DEV_TYPE_LOGICAL_MFS;
         u32param_ptr[IO_IOCTL_ID_ATTR_ELEMENT] = IO_SDCARD_ATTRIBS;
         if (fd_ptr->FLAGS & IO_O_RDONLY)
         {
             u32param_ptr[IO_IOCTL_ID_ATTR_ELEMENT] &= (~ IO_DEV_ATTR_WRITE);
         }
         break;
      default:
         result = IO_ERROR_INVALID_IOCTL_CMD;
         break;
   }

   return result;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_read_blocks
* Returned Value   : number of blocks read
* Comments         : Reads data from SDCARD driver
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_read_blocks
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the blocks are to be stored */
      char_ptr data_ptr,

      /* [IN] the number of blocks to input */
      _mqx_int num
   )
{
    IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
    SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
    _mqx_int             res;

    fd_ptr->ERROR = IO_OK;
    if (NULL == sdcard_ptr->INIT->READ_FUNC)
    {
        fd_ptr->ERROR = IO_ERROR_READ;
        return IO_ERROR;
    }

    if ((fd_ptr->LOCATION + num) > sdcard_ptr->NUM_BLOCKS)
    {
        fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
        num = sdcard_ptr->NUM_BLOCKS - fd_ptr->LOCATION;
    }

    _lwsem_wait(&sdcard_ptr->LWSEM);
    res = sdcard_ptr->INIT->READ_FUNC (fd_ptr, (uchar_ptr)data_ptr, fd_ptr->LOCATION, num);

    if (res > 0)
    {
        fd_ptr->LOCATION += res;
    }

    if (res != num)
    {
        fd_ptr->ERROR = IO_ERROR_READ;
    }

    _lwsem_post(&sdcard_ptr->LWSEM);
    return res;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_write_blocks
* Returned Value   : number of blocks written
* Comments         : Writes data to SDCARD driver
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_write_blocks
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the blocks are stored */
      char_ptr data_ptr,

      /* [IN] the number of blocks to output */
      _mqx_int num
   )
{
    IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
    SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
    _mqx_int             res;

    fd_ptr->ERROR = IO_OK;
    if ((NULL == sdcard_ptr->INIT->WRITE_FUNC) || (fd_ptr->FLAGS & IO_O_RDONLY))
    {
        fd_ptr->ERROR = IO_ERROR_WRITE_PROTECTED;
        return IO_ERROR;
    }

    if ((fd_ptr->LOCATION + num) > sdcard_ptr->NUM_BLOCKS)
    {
        fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
        num = sdcard_ptr->NUM_BLOCKS - fd_ptr->LOCATION;
    }

    _lwsem_wait(&sdcard_ptr->LWSEM);
    res = sdcard_ptr->INIT->WRITE_FUNC (fd_ptr, (uchar_ptr)data_ptr, fd_ptr->LOCATION, num);

    if (res > 0)
    {
        fd_ptr->LOCATION += res;
    }

    if (res != num)
    {
        fd_ptr->ERROR = IO_ERROR_WRITE;
    }

    _lwsem_post(&sdcard_ptr->LWSEM);
    return res;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_csd_capacity
* Returned Value   : Capacity of storage device in 512B blocks
* Comments         :
*    Extracts capacity information from CSD.
*
*END*----------------------------------------------------------------------*/
uint_32 _io_sdcard_csd_capacity
(
    /* [IN] pointer to CSD */
    uint_8 *csd
)
{
    uint_32 capacity, c_size, c_size_mult, read_bl_len;

    /* check CSD version */
    if (0 == (csd[0] & 0xC0))
    {
        read_bl_len = csd[5] & 0x0F;
        c_size = csd[6] & 0x03;
        c_size = (c_size << 8) | csd[7];
        c_size = (c_size << 2) | (csd[8] >> 6);
        c_size_mult = ((csd[9] & 0x03) << 1) | (csd[10] >> 7);
        capacity = (c_size + 1) * (1 << (c_size_mult + 2)) * (1 << (read_bl_len - 9));
    }
    else
    {
        c_size = csd[7] & 0x3F;
        c_size = (c_size << 8) | csd[8];
        c_size = (c_size << 8) | csd[9];
        capacity = (c_size + 1) << 10;
    }

    return capacity;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_csd_baudrate
* Returned Value   : Maximum supported data transfer rate
* Comments         :
*    Extracts maximum supported data transfer rate over single line from CSD.
*
*END*----------------------------------------------------------------------*/
uint_32 _io_sdcard_csd_baudrate
(
    /* [IN] pointer to CSD */
    uint_8 *csd
)
{
    static const uint_32 unit_tab[] = { 10000, 100000, 1000000, 10000000 };
    static const uint_8 value_tab[] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };

    uint_32 value, unit;

    unit = (csd[3] & 0x07);
    value = (csd[3] & 0x78) >> 3;

    if (unit > 3) return 0; /* undefined */

    return value_tab[value] * unit_tab[unit];
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/rip.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rip.c$
* $Version : 3.8.12.0$
* $Date    : Sep-19-2012$
*
* Comments:
*
*   This file contains the implementation of RIPv1 and v2,
*   the Routing Information Protocol.  For more details,
*   refer to RFC2453.
*   KNOWN BUGS:
*   - just after the shutdown advertise all the routes with an max (no infinite)
*   metric aka 15. thus the other routers doesnt have to wait for the end of
*   the timeout. question: how do i know when the board shutdown?
*   it seems impossible :( perhaps with a network call... snmp set
*   - how to do the router administration ? etc.. snmp set? and the security ?
*   - how to advertize particular route such as default. currently i dont
*   adertize it.
*   - passwd and md5 authentification extensions are not handled.
*   - i missed something in the nexthop field and the reverse poison, the
*   metric must be advertized with a infinite metric on the interface
*   from which it has been learned.
*   ok BUT only if this route has been learned with RIP. not if it is a external
*   route/no static route (because there is not source interface).
*   and perhaps other cases... like on demand circuit.
*   > > in which case the nexthop field is usefull ?
*   >
*   > One obvious case -- exporting from a foreign routing protocol (like
*   > OSPF or BGP).
*   >
*   > Another very useful case for the next hop field in RIPv2 is to allow
*   > for better handling of routes on demand circuits.  In the Annex, we
*   > put the next hop into the advertisement even if it wasn't directly
*   > reachable on that same subnet.  I think Gary wrote an applicability
*   > statement concerning this use afterwards.
*   >
*   > Suppose you have nodes A and B which can both dial into C on demand.
*   > A dials in and learns a number of routes from C and advertises them on
*   > a local network that B sees.  A hangs up from C and then B dials in.
*   >
*   > When B learns routes from C, it advertises C as the next hop.  When A
*   > sees this, it immediately sets its local copies of those routes to
*   > infinity and purges them from the world by doing a triggered
*   > advertisement.  That way, other hosts don't have to wait for A's old
*   > routes to age out and B's to become preferred.
*   TODO:
*   - the icmp/redirect route must be modified to.
*   - handle the case of removing the interface or the device.
*   - must handle several route for a given destination with the same metric.
*   - check response validity.
*   - if a route metric reaches the max, the route is down.
*   - the debian routed send the packet to the network broadcast and not
*   the limited broadcast, what is the proper behaviour ? gated routed do
*   the same. DONE i have decided it was the good one.
*   - if an static route is removed, start the deletion process. dont simply
*   remove it. thus the route is advertized with an infinite metric.
*   - implement the POLL unofficial/gated command. i.e. a response
*   without splithorizon/reverse poison.
*   - DONE send/received multicast for ripv2 (and ospf) (change igmp to do
*   it without socket. directly in ucb) seb said ok
*
*END************************************************************************/


/* local include */
#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "udp_prv.h"
#include "rip.h"
#include "route.h"
#if RTCSCFG_ENABLE_RIP && RTCSCFG_ENABLE_IP4 

#define RND_RANGE(min,max) ((min) + RTCS_rand()%(((max)-(min))?((max)-(min)):1))
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif

#define RIP_PKT_MAXLEN      500 /* find the right number */
#define RIP_AF_INET     2   /* MUST be 2. rtcs AF_INET is 1! */
#define DEFAULT_ROUTE_TAG       0
#define NETWORK_COST            1   /* must be at least 1 */
#define SPLIT_HORIZON_WITHOUT_POISONNED_REVERSE 0
#define ADV_VERSION     RIP_V2


static void RIP_trig_upd(void);
static boolean RIP_expire_periodic(TCPIP_EVENT_PTR);
static uint_32 RIP_send_req(void);
void RIP_service(RTCSPCB_PTR, UCB_STRUCT_PTR);

IP_ROUTE_FN RIP_routefn = {
   NULL,
   RIP_new_bindif,
   RIP_init_static_rt,
   RIP_remove_rt
};

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_init
* Returned Values : uint_32
* Comments        : Initialize the RIP layer.
*
*END*-----------------------------------------------------------------*/

uint_32 RIP_init (void)
{ /* Body */
    RIP_CFG_STRUCT_PTR  cfg = RTCS_getcfg(RIP);
    uint_32 err;

    if (RTCS_getcfg(RIP)) return RTCS_OK;
    /* allocate the memory */
    cfg = RTCS_mem_alloc_zero(sizeof(*cfg));
    if (!cfg)  return RTCSERR_OUT_OF_MEMORY;
    /* bind the udp port */
    err = UDP_openbind_internal(IPPORT_RIP, RIP_service, &cfg->UCB);
    if (err){
        _mem_free(cfg);
        return err;
    }

    RTCS_setcfg(RIP, cfg);
    ROUTE_register(&RIP_routefn);

    /* Start the retransmission timer to start sending immediately */
    cfg->TIMER_PERIODIC.TIME    = 0;
    cfg->TIMER_PERIODIC.EVENT   = RIP_expire_periodic;
    cfg->TIMER_PERIODIC.PRIVATE = NULL;
    TCPIP_Event_add(&cfg->TIMER_PERIODIC);

    /* probe all the interfaces now to build the route table faster */
    err = RIP_send_req();

    return RTCS_OK;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_cpu_metric
* Returned Values :
* Comments        : rfc2453.3.9.2
*
*END*-----------------------------------------------------------------*/

static uint_32 RIP_cpu_metric(
    RTCSPCB_PTR     pcb,          /* [IN] incoming packet */
    uint_32     oldmetric
)
{ /* Body */
    uint_32 metric = NETWORK_COST + oldmetric;
/* if a cost per interface is required, do that here. But before that,
** think about the unit problem between the routing protocols.
*/
    return min(metric, RIP_MAX_METRIC);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_build_header
* Returned Values : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static void RIP_build_header(
    uchar_ptr   buf,        /* [OUT] the rip header */
    uint_8      cmd,        /* [IN] the commande */
    uint_8      version     /* [IN] the version */
)
{ /* Body */
    RIP_HEADER_PTR  hd = (RIP_HEADER_PTR)buf;
    _mem_zero(buf, sizeof(RIP_HEADER));
    htonc(hd->COMMAND, cmd);
    htonc(hd->VERSION, version);
    htons(hd->MBZ, 0);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_build_rte
* Returned Values : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static void RIP_build_rte(
    uchar_ptr   buf,    /* [OUT] the route entry */
    uint_16     family,
    uint_16     rt_tag,
    _ip_address net_addr,
    _ip_address net_mask,
    _ip_address next_hop,
    uint_32     metric,
    uint_32     rip_vers
)
{ /* Body */
    RIP_ENTRY_PTR   rte = (RIP_ENTRY_PTR)buf;
    if (rip_vers == RIP_V2){
        htons(rte->RT_TAG, rt_tag);
        htonl(rte->NETMASK, net_mask);
        htonl(rte->NEXTHOP, next_hop);
    }else{
        _mem_zero(buf, sizeof(RIP_ENTRY));
    }
    htons(rte->FAMILY, family);
    htonl(rte->NETADDR, net_addr);
    htonl(rte->METRIC, metric);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_send_pkt
* Returned Values :
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 RIP_send_pkt(
   IP_IF_PTR   ipif,   /* [IN] the outgoing interface */
   _ip_address ipdst,  /* [IN] the destination ip */
   uint_16     portdst,/* [IN] the destination port */
   uchar_ptr   data,   /* [IN] the data to send */
   uint_32     len /* [IN] the length of data to send */
)
{ /* Body */
   RTCSPCB_PTR         pcb;
   RIP_CFG_STRUCT_PTR  ripcfg = RTCS_getcfg(RIP);
   RIP_HEADER_PTR  hd = (RIP_HEADER_PTR)data;
   uint_32         err;
   _ip_address     ipsrc = IP_get_ipif_addr(ipif);

   if (ipsrc == INADDR_ANY) {
       _mem_free(data);
       return RTCS_OK;
   } /* Endif */

   /* Allocate a PCB */
   pcb = RTCSPCB_alloc_send();
   if (pcb == NULL) {
       _mem_free(data);
       return RTCSERR_PCB_ALLOC;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb);

   /* add my data in the pcb */
   err = RTCSPCB_append_fragment_autofree(pcb, len, data);
   if (err) {
       _mem_free(data);
       RTCSLOG_PCB_FREE(pcb, err);
       RTCSPCB_free(pcb);
       return err;
   } /* Endif */

   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PORT(IPPORT_RIP), ntohc(hd->VERSION));

   /* dont advertize in limited broadcast but in ip broadcast */
   if (ipdst == INADDR_BROADCAST){
       _ip_address  netmask;

       ipdst = IP_get_ipif_addr(ipif);        /* Get IP address of interface */
       IP_get_netmask(ipif, ipdst, &netmask); /* Get netmask */

       ipdst = ipdst | ~netmask;
   } /* Endif */

   /* send it */
   /* use a flag to prevent the broadcast/multicast packet from
   ** looping back to us.
   */
   return UDP_send_internal(ripcfg->UCB, ipsrc, ipdst, portdst, pcb, RTCS_MSG_NOLOOP);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_is_valid_rte
* Returned Values :
* Comments        : rfc2453.3.9.2
*
*END*-----------------------------------------------------------------*/

static uint_32 RIP_is_valid_rte(
    RIP_ENTRY_PTR   rte
)
{ /* Body */
    uint_32 metric = ntohl(rte->METRIC);
    _ip_address netaddr = ntohl(rte->NETADDR);
    if (ntohs(rte->FAMILY) != RIP_AF_INET) return 0;
    if (metric > RIP_MAX_METRIC || metric < RIP_MIN_METRIC) return 0;
    if (IN_MULTICAST(netaddr) || IN_EXPERIMENTAL(netaddr)) return 0;
    if (IN_LOOPBACK(netaddr))  return 0;

    {
      _ip_address   nexthop = ntohl(rte->NEXTHOP);
      
      if (nexthop!= 0) {
         if (IP_is_local(NULL, nexthop)) {
            return 0;
         }
      }
    }

    return 1;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_is_valid_resp
* Returned Values :
* Comments        : rfc2453.3.9.2
*
*END*-----------------------------------------------------------------*/

static uint_32 RIP_is_valid_resp(
      RTCSPCB_PTR    pcb          /* [IN/OUT] incoming packet */
)
{ /* Body */
   uint_32 ipsrc = IP_source(pcb);
   uint_16 srcport = UDP_source(pcb);
   /*
   ** check the source port is IPPORT_ROUTE, just a weak security.
   ** On BSD-like network stack, accessing to the ports < 1024
   ** requires privileges.
   */
   if (srcport != IPPORT_RIP) return FALSE;
   /*
   ** if the ipsrc is NOT on a directly connected network which
   ** received the packet, it is not valid
   */
   if (IP_is_direct(pcb->IFSRC,ipsrc) == FALSE) return FALSE;
   /*
   ** If this packet is one of mine, it is not valid.
   ** It can happen in case of more than one interfaces are
   ** directly connected to the same network.
   */
   if (IP_is_local(NULL,ipsrc) == TRUE) return FALSE;
   return 1;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_send_resp_ipif
* Returned Values : boolean
* Comments        :
*
*END*-----------------------------------------------------------------*/

struct RIP_send_resp_ipif_struct  {
   IP_IF_PTR      ipif;
    _ip_address   ipdest;
    uint_32       rip_vers;
    uint_32       onlyChangeF;
    uchar_ptr     pkt;
    uchar_ptr     curs;
    uint_16       portdst;
};

static boolean RIP_send_resp_ipif_test
   (
      _ip_address node_ip,
      _ip_address node_mask,
      pointer     node_data,
      pointer     data
   )
{ /* Body */
   struct RIP_send_resp_ipif_struct _PTR_ testdata = data;
   IP_ROUTE_PTR                           route = node_data;
   IP_ROUTE_INDIRECT_PTR                  gate, end;
   _ip_address                            nexthop, iplist[2];
   uint_32                                metric, rtype, vcount;
   boolean                                complete = FALSE;
   pointer                                rstart[3];

   /* If this node has no entries, return */
   if (!route) {
      return FALSE;
   } /* Endif */

   rstart[0] = route->DIRECT;
   rstart[1] = route->VIRTUAL;
   rstart[2] = route->INDIRECT;

   /*
   ** If there are no connected networks, return. If the node_mask is other than
   ** 255.255.255.255 there is a connected network. There can be a virutal
   ** network even when all the netmask bits are set if the node_ip is different
   ** than the VIRTUAL ADDRESS (like in the case of PPP)
   */
   if (!~node_mask) {
      if (!(route->VIRTUAL && node_ip != route->VIRTUAL->ADDRESS)) {
         return FALSE;
      } /* Endif */

      /* Only check the VIRTUAL routes */
      rstart[0] = NULL;
      rstart[2] = NULL;
   } /* Endif */

   for (rtype = 0, gate = NULL; rtype <= 2 && !gate; rtype++) {
      gate = rstart[rtype];
   } /* Endfor */

   if (!gate) {
      return FALSE;
   } /* Endif */

   end = gate;
   iplist[1] = node_ip;
   do {
      do {
         vcount = 2;
         do {
            /* Don't gather information about tunnels */
            if (gate == rstart[1] && !route->VIRTUAL->ADDRESS) {
               break;
            } /* Endif */

            if (vcount == 1) {
               iplist[0] = route->VIRTUAL->ADDRESS;
            } /* Endif */

            /* allocate the packet memory */
            if (!testdata->pkt)  {
               testdata->pkt = testdata->curs = RTCS_mem_alloc_system(RIP_MAX_PKTLEN);
               if (!testdata->pkt) return RTCSERR_OUT_OF_MEMORY;

               /* build the header */
               RIP_build_header(testdata->curs, RIPCMD_RESPONSE, testdata->rip_vers);
               testdata->curs += sizeof(RIP_HEADER);
            } /* Endif */

            if (testdata->onlyChangeF && !gate->RIP.CHANGED_F) {
               break;
            } /* Endif */

            /* dont advertize the icmp redirect route */
            if (gate->FLAGS & RTF_REDIRECT)  {
               break;
            } /* Endif */

            metric = gate->RIP.METRIC;

#if SPLIT_HORIZON_WITHOUT_POISONNED_REVERSE
            /* split horizon. rfc2453.3.4.3.
            ** DONT advertize a route on the interface on
            ** which you received it.
            */
            if (gate->RIP.IPIFSRC == testdata->ipif)  {
               break;
            } /* Endif */
#else
            /* split horizon with poisoned reverse. rfc2453.3.4.3
            ** DO advertize a route on the interface on
            ** which you received it BUT with a infinit metric.
            */
            if (gate->RIP.IPIFSRC == testdata->ipif)  {
                metric = RIP_MAX_METRIC;
            } /* Endif */
#endif
            /* the outgoing nexthop. rfc2453.4.4. */
            nexthop = 0;
            if (IP_is_direct(testdata->ipif, gate->GATEWAY)) {
               if (end == route->INDIRECT) {
                  nexthop = gate->GATEWAY;
               } /* Endif */
            } /* Endif */


            /* build the route entry */
            RIP_build_rte(testdata->curs, RIP_AF_INET, gate->RIP.RT_TAG
                    , iplist[vcount - 1], node_mask
                    , nexthop, metric, testdata->rip_vers);

            /* check if it is valid before sending it */
            if (!RIP_is_valid_rte((RIP_ENTRY_PTR)testdata->curs)) {
               break;
            } /* Endif */


            testdata->curs += sizeof(RIP_ENTRY);

            /* if the packet is full, send it and come back later */
            if (testdata->curs-testdata->pkt >= sizeof(RIP_HEADER)+RIP_MAX_PKTLEN) {
               RIP_send_pkt(testdata->ipif, testdata->ipdest, testdata->portdst,
                  testdata->pkt, testdata->curs-testdata->pkt);
               /* pkt is freed, reset pointer to NULL */
               testdata->pkt = NULL;
            } /* Endif */
            vcount--;
         } while (end && end == (pointer)route->VIRTUAL && vcount);
         gate = gate->NEXT;
      } while (gate != end);

      for (gate = NULL; rtype <= 2 && !gate; rtype++) {
         gate = rstart[rtype];
      } /* Endfor */
      end = gate;
   } while(gate);
   return FALSE;
} /* Endbody */

static uint_32 RIP_send_resp_ipif (
    IP_IF_PTR   ipif,    /* [IN] the destination interface  */
    _ip_address ipdest,  /* [IN] the destination ip address */
    uint_16     portdst, /* [IN] the destination port */
    uint_32     rip_vers,/* [IN] the rip version */
    uint_32     onlyChangeF /* [IN] TRUE if only the changed routes are sent */
)
{ /* Body */
   IP_CFG_STRUCT_PTR                IP_cfg_ptr = RTCS_getcfg(IP);
   struct RIP_send_resp_ipif_struct testdata;

   testdata.ipif = ipif;
   testdata.ipdest = ipdest;
   testdata.portdst = portdst;
   testdata.onlyChangeF = onlyChangeF;
   testdata.rip_vers = rip_vers;
   testdata.pkt = NULL;
   testdata.curs = NULL;

   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, RIP_send_resp_ipif_test, &testdata);

   /* if the packet is empty, dont send it */
   if (testdata.curs-testdata.pkt == sizeof(RIP_HEADER)){
       _mem_free(testdata.pkt);
   } else  {
      /* send the packet */
      RIP_send_pkt(ipif, ipdest, portdst, testdata.pkt,
         testdata.curs - testdata.pkt);
   } /* Endif */

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_send_resp
* Returned Values : boolean
* Comments        :
*
*END*-----------------------------------------------------------------*/
struct RIP_send_resp_struct  {
   IP_IF_PTR   localhost;
   uint_32     onlyChangeF;
   _ip_address ipdest;
   uint_32     rip_vers;
   uint_32     nb_try;
   uint_32     nb_fail;
};

static boolean RIP_send_resp_test
   (
      _ip_address node_ip,
      _ip_address node_mask,
      pointer     node_data,
      pointer     data
   )
{ /* Body */
   IP_ROUTE_PTR                        route = node_data;
   struct RIP_send_resp_struct _PTR_   testdata = data;
   uint_32                             error;

   if (route && route->DIRECT) {
      /* Don't advertise on local interface */
      if (route->DIRECT->DESTIF != testdata->localhost)  {
         testdata->nb_try++;
         error = RIP_send_resp_ipif(route->DIRECT->DESTIF, testdata->ipdest,
            IPPORT_RIP, testdata->rip_vers, testdata->onlyChangeF);
         if (error != RTCS_OK)  {
            testdata->nb_fail++;
         } /* Endif */
      } /* Endif */
   } /* Endif */

   if (route && route->VIRTUAL && route->VIRTUAL->ADDRESS) {
      /* Don't advertise on local interface */
      if (route->VIRTUAL->DESTIF != testdata->localhost)  {
         testdata->nb_try++;
         error = RIP_send_resp_ipif(route->VIRTUAL->DESTIF, testdata->ipdest,
            IPPORT_RIP, testdata->rip_vers, testdata->onlyChangeF);
         if (error != RTCS_OK)  {
            testdata->nb_fail++;
         } /* Endif */
      } /* Endif */
   } /* Endif */

   return FALSE;
} /* Endbody */

static boolean RIP_send_resp_test2
   (
      _ip_address node_ip,
      _ip_address node_mask,
      pointer     node_data,
      pointer     data
   )
{ /* Body */
   IP_ROUTE_PTR                        route = node_data;
   IP_ROUTE_INDIRECT_PTR               indirect;
   pointer                             p[3];
   uint_32                             i;

   if (!route) {
      return FALSE;
   } /* Endif */

   p[0] = route->DIRECT;
   p[1] = route->INDIRECT;
   p[2] = route->VIRTUAL;

   for (i = 0; i <= 2; i++) {
      if (!p[i]) {
         continue;
      } /* Endif */

      indirect = p[i];
      do {
         indirect->RIP.CHANGED_F = FALSE;
         indirect = indirect->NEXT;
      } while(indirect != p[i]);
   } /* Endfor */

   return FALSE;
} /* Endbody */

static uint_32 RIP_send_resp(
    uint_32 rip_vers,   /* [IN] the rip version */
    uint_32 onlyChangeF /* [IN] TRUE if only the changed routes are sent */
)
{ /* Body */
   RIP_CFG_STRUCT_PTR           ripcfg = RTCS_getcfg(RIP);
   IP_CFG_STRUCT_PTR            IP_cfg_ptr = RTCS_getcfg(IP);
   struct RIP_send_resp_struct  testdata;

   testdata.nb_try = 0;
   testdata.nb_fail = 0;
   testdata.localhost = RTCS_IF_LOCALHOST_PRV;
   testdata.rip_vers = rip_vers;
   testdata.onlyChangeF = onlyChangeF;

   if (rip_vers == RIP_V1) testdata.ipdest = INADDR_BROADCAST;
   else                    testdata.ipdest = INADDR_RIP_GROUP;

   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, RIP_send_resp_test, &testdata);

   /* test if the routes has been all advertized (nbFail==0 && nbTry > 0)*/
   if (testdata.nb_fail)        return (uint_32)RTCS_ERROR;
   if (testdata.nb_try == 0)    return RTCS_OK;

   /* clear the flags only if required */
   if (ripcfg->RT_CHANGED_F == FALSE) return RTCS_OK;

   /* update the flag */
   ripcfg->RT_CHANGED_F = FALSE;

   /* clear the flag in all changed route entries */
   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, RIP_send_resp_test2, NULL);

   return RTCS_OK;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_process_inreq
* Returned Values : void
* Comments        : check only the header
*
*END*-----------------------------------------------------------------*/

static uint_32 RIP_process_inreq(
      RTCSPCB_PTR    pcb          /* [IN/OUT] incoming packet */
)
{ /* Body */
   RIP_HEADER_PTR  hd = (RIP_HEADER_PTR)RTCSPCB_DATA(pcb);
   RIP_ENTRY_PTR   rte = (RIP_ENTRY_PTR)((uchar_ptr)hd
                   + sizeof(RIP_HEADER));
   uint_32     pktlen = RTCSPCB_SIZE(pcb);
   uint_32     err = RTCS_OK;

   /* handle the general query. rfc2453.3.9.1 */
   if (pktlen == sizeof(RIP_ENTRY) + sizeof(RIP_HEADER)
         && ntohs(rte->FAMILY) == 0
         && ntohl(rte->METRIC) == RIP_MAX_METRIC){
      _ip_address ipsrc = IP_source(pcb);
      uint_16     srcport = UDP_source(pcb);
      uint_8      version = ntohc(hd->VERSION);
      return RIP_send_resp_ipif (pcb->IFSRC,ipsrc,srcport,version,0);
   }
/* WORK: here handle particular routes request */

   return err;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_expire_gc
* Returned Values : boolean
* Comments        : rfc2453.3.8
*
*END*-----------------------------------------------------------------*/

static boolean RIP_expire_gc(
      TCPIP_EVENT_PTR   event      /* [IN/OUT] the resend event */
)
{ /* Body */
    IP_ROUTE_INDIRECT_PTR     gate = event->PRIVATE;

    if (!gate->IS_DIRECT) {
       ROUTE_remove(gate);
    } /* Endif */

    return FALSE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_expire_rte
* Returned Values : boolean
* Comments        : rfc2453.3.8
*
*END*-----------------------------------------------------------------*/

static boolean RIP_expire_rte(
      TCPIP_EVENT_PTR   event      /* [IN/OUT] the resend event */
)
{ /* Body */
    RIP_CFG_STRUCT_PTR     ripcfg = RTCS_getcfg(RIP);
    IP_ROUTE_INDIRECT_PTR  gate = event->PRIVATE;

    /* update the route entry */
    gate->FLAGS &= ~RTF_UP;
    gate->RIP.METRIC = RIP_MAX_METRIC;
    ripcfg->RT_CHANGED_F = gate->RIP.CHANGED_F = TRUE;

    RIP_trig_upd();

    /* start the garbage collector timer. */
    gate->RIP.TIMEOUT.TIME    = RIP_TIMEOUT_GC;
    gate->RIP.TIMEOUT.EVENT   = RIP_expire_gc;
    return TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_init_timer
* Returned Values :
* Comments        : rfc2453.3.9.2
*
*END*-----------------------------------------------------------------*/

static void RIP_init_timer(
    IP_ROUTE_INDIRECT_PTR     gate,
    uint_32                   metric
)
{ /* Body */

    if (metric < RIP_MAX_METRIC){  /* init the timeout */
        gate->RIP.TIMEOUT.TIME    = RIP_TIMEOUT_DEL;
        gate->RIP.TIMEOUT.EVENT   = RIP_expire_rte;
    }else{  /* init the garbage collection */
        gate->RIP.TIMEOUT.TIME    = RIP_TIMEOUT_GC;
        gate->RIP.TIMEOUT.EVENT   = RIP_expire_gc;
    }
    gate->RIP.TIMEOUT.PRIVATE = gate;
    TCPIP_Event_add(&gate->RIP.TIMEOUT);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_adopt_rt
* Returned Values :
* Comments        : rfc2453.3.9.2
*
*END*-----------------------------------------------------------------*/

static void RIP_adopt_rt(
    RTCSPCB_PTR            pcb,          /* [IN] incoming packet */
    IP_ROUTE_INDIRECT_PTR  gate,
    RIP_ENTRY_PTR          rte,
    uint_32                metric,
    _ip_address _PTR_      network_ptr,
    _ip_address _PTR_      netmask_ptr
)
{ /* Body */
   RIP_HEADER_PTR  hd = (RIP_HEADER_PTR)RTCSPCB_DATA(pcb);
   uint_16     rip_vers = ntohc(hd->VERSION);
   _ip_address ipsrc = IP_source(pcb);

   /* init the common part */
   *network_ptr = ntohl(rte->NETADDR);
   gate->GATEWAY = ipsrc;
   if (rip_vers == RIP_V2){
      _ip_address nexthop = ntohl(rte->NEXTHOP);
      *netmask_ptr = ntohl(rte->NETMASK);
      /* incoming nexthop. rfc2453.4.4 */
      if (nexthop && IP_is_direct(pcb->IFSRC, nexthop))
         gate->GATEWAY = nexthop;
   }else{
      *netmask_ptr = IN_DEFAULT_NET(*network_ptr);
   }

   /* if the metric is >= than the RIP_MAX_METRIC, the ourte is down */
   if (metric < RIP_MAX_METRIC) {
      gate->FLAGS |= RTF_UP;
   } else {
      gate->FLAGS &= ~RTF_UP;
   } /* Endif */

   /* init the RIP part */
   gate->RIP.METRIC = metric;
   gate->RIP.RT_TAG = ntohs(rte->RT_TAG);

   gate->RIP.CHANGED_F = TRUE;

   gate->RIP.IPIFSRC = pcb->IFSRC;

   RIP_init_timer(gate, gate->RIP.METRIC);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_update_rt
* Returned Values :
* Comments        : rfc2453.3.9.2
*
*END*-----------------------------------------------------------------*/

static void RIP_update_rt(
    IP_ROUTE_INDIRECT_PTR     gate,
    RTCSPCB_PTR               pcb,          /* [IN] incoming packet */
    RIP_ENTRY_PTR             rte
)
{ /* Body */
   RIP_CFG_STRUCT_PTR  ripcfg = RTCS_getcfg(RIP);
   uint_32         nmetric= RIP_cpu_metric(pcb,ntohl(rte->METRIC));
   _ip_address     ipsrc = IP_source(pcb);


   /* dont modify a static route */
   if (gate->FLAGS & RTF_STATIC)
      return;

   /*
   ** if the source isnt "authoritative" (i.e. not the current
   ** gateway) and have a bigger metric, ignore the route.
   */
   if (ipsrc != gate->GATEWAY && nmetric > gate->RIP.METRIC)
      return;

   /*
   ** if the source isnt "authoritative" (i.e. not the current
   ** gateway) and have a equal metric and will "soon" timed out,
   ** update the route entry.
   */
   if (ipsrc != gate->GATEWAY && nmetric == gate->RIP.METRIC){
      uint_32 timeout = TCPIP_Event_expire(&gate->RIP.TIMEOUT);
      /* if the both metrics are infinite, dont update the route. */
      if (nmetric >= RIP_MAX_METRIC)     return;
      if (timeout > RIP_ALMOST_EXPIRED_TIME) return;
   }

   /* cancel the timeout/gc timer */
   TCPIP_Event_cancel(&gate->RIP.TIMEOUT);

   /* If the sources and the metrics are equal, just reinit the timer. */
   if (ipsrc == gate->GATEWAY && gate->RIP.METRIC == nmetric){
      if (nmetric < RIP_MAX_METRIC){
         RIP_init_timer(gate, gate->RIP.METRIC);
      }
      return;
   }

   /*
   ** Reinit the route and the timer. ipsrc no longer needed, just used
   ** to fill all of the function parameters
   */
   RIP_adopt_rt(pcb, gate, rte, nmetric, &ipsrc, &ipsrc);

   /* flag it as changed */
   ripcfg->RT_CHANGED_F = TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_create_rt
* Returned Values :
* Comments        : rfc2453.3.9.2
*
*END*-----------------------------------------------------------------*/

static void RIP_create_rt(
    RTCSPCB_PTR    pcb,          /* [IN] incoming packet */
    RIP_ENTRY_PTR   rte,
    uint_8      rip_vers
)
{ /* Body */
    uint_32                nmetric= RIP_cpu_metric(pcb,ntohl(rte->METRIC));
    RIP_CFG_STRUCT_PTR     ripcfg = RTCS_getcfg(RIP);
    IP_CFG_STRUCT_PTR      IP_cfg_ptr = RTCS_getcfg(IP);
    IP_ROUTE_INDIRECT_PTR  gate;
    _ip_address            network, netmask;

    gate = RTCS_part_alloc(IP_cfg_ptr->GATE_PARTID);
    if (!gate)  return;
    _mem_zero(gate, sizeof(*gate));

    /* init the route */
    RIP_adopt_rt(pcb, gate, rte, nmetric, &network, &netmask);

    /* insert it in the table */
    ROUTE_insert(gate, network, netmask);

    /* flag it as changed */
    ripcfg->RT_CHANGED_F = TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_process_inresp
* Returned Values :
* Comments        : rfc2453.3.9.2
*
*END*-----------------------------------------------------------------*/

static void RIP_process_inresp(
      RTCSPCB_PTR    pcb          /* [IN/OUT] incoming packet */
)
{ /* Body */
    RIP_CFG_STRUCT_PTR     ripcfg = RTCS_getcfg(RIP);
    uchar_ptr              pkt = RTCSPCB_DATA(pcb);
    RIP_HEADER_PTR         hd = (RIP_HEADER_PTR)RTCSPCB_DATA(pcb);
    RIP_ENTRY_PTR          rte = (RIP_ENTRY_PTR)(pkt + sizeof(RIP_HEADER));
    uint_32                pktlen = RTCSPCB_SIZE(pcb);
    uint_16                rip_vers = ntohc(hd->VERSION);
    IP_ROUTE_INDIRECT_PTR  gate;
    _ip_address            netaddr, netmask;

    if (pktlen < sizeof(RIP_HEADER)) {
        return;
    } /* Endif */

    pktlen -= sizeof(RIP_HEADER);

    if (RIP_is_valid_resp(pcb) == FALSE){
        return;
    } /* Endif */

    for (; pktlen >= sizeof(RIP_ENTRY); pktlen -= sizeof(RIP_ENTRY), rte++){
        if (!RIP_is_valid_rte(rte))
            continue;
        netaddr = ntohl(rte->NETADDR);
        if (rip_vers == RIP_V2) netmask = ntohl(rte->NETMASK);
        else            netmask = IN_DEFAULT_NET(netaddr);
        gate = ROUTE_get(netaddr, netmask);
        if (!gate) RIP_create_rt(pcb, rte, rip_vers);
        else        RIP_update_rt(gate, pcb, rte);
    }
    /* if this incoming response has changed routes, do a triggered update*/
    if (ripcfg->RT_CHANGED_F)
        RIP_trig_upd();

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_service
* Returned Values : void
* Comments        : Process incoming RIP packets.  Called from UDP
*
*END*-----------------------------------------------------------------*/

void RIP_service(
      RTCSPCB_PTR    pcb,        /* [IN/OUT] incoming packet */
      UCB_STRUCT_PTR ucb_ptr     /* [IN]     target UCB      */
)
{ /* Body */
   RIP_HEADER_PTR  hd = (RIP_HEADER_PTR)RTCSPCB_DATA(pcb);


   /* check the version number */
   if (ntohc(hd->VERSION) != RIP_V1 && ntohc(hd->VERSION) != RIP_V2) {
      RTCSLOG_PCB_FREE(pcb, RTCS_OK);
      RTCSPCB_free(pcb);
   } /* Endif */

   RTCSLOG_PCB_READ(pcb, RTCS_LOGCTRL_PORT(IPPORT_RIP), ntohc(hd->VERSION));

   switch (ntohc(hd->COMMAND)) {
   case RIPCMD_REQUEST:
      RIP_process_inreq(pcb);
      break;
   case RIPCMD_RESPONSE:
      RIP_process_inresp(pcb);
      break;
   default:
      break;
   } /* Endswitch */

   RTCSLOG_PCB_FREE(pcb, RTCS_OK);
   RTCSPCB_free(pcb);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_send_req_ipif
* Returned Values : boolean
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 RIP_send_req_ipif (
    IP_IF_PTR   ipif
)
{ /* Body */
    uchar_ptr   pkt;
    uint_32     err;
    _ip_address ipdest;

    /* allocate the packet memory */
    pkt = RTCS_mem_alloc_system(RIP_MAX_PKTLEN);
    if (!pkt) return RTCSERR_OUT_OF_MEMORY;

    /* build the header */
    RIP_build_header(pkt, RIPCMD_REQUEST, ADV_VERSION);

    /* build handle the general query. rfc2453.3.9.1 */
    RIP_build_rte(pkt+sizeof(RIP_HEADER), 0, DEFAULT_ROUTE_TAG, INADDR_ANY
                , INADDR_ANY,INADDR_ANY, RIP_MAX_METRIC
                , ADV_VERSION);

    if (ADV_VERSION == RIP_V1) ipdest = INADDR_BROADCAST;
    else                       ipdest = INADDR_RIP_GROUP;

    /* send the packet */
    err = RIP_send_pkt(ipif, ipdest, IPPORT_RIP, pkt
                , sizeof(RIP_HEADER) + sizeof(RIP_ENTRY));
    if (err != RTCS_OK){
        return err;
    }
    return RTCS_OK;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_send_req
* Returned Values : boolean
* Comments        :
*
*END*-----------------------------------------------------------------*/
struct RIP_send_req_struct  {
   IP_IF_PTR   localhost;
};

static boolean RIP_send_req_test
   (
      _ip_address node_ip,
      _ip_address node_mask,
      pointer     node_data,
      pointer     data
   )
{ /* Body */
   IP_ROUTE_PTR                     route = node_data;
   struct RIP_send_req_struct _PTR_ testdata = data;

   if (route && route->DIRECT && !~node_mask) {
      /* Don't advertise on local interface */
      if (route->DIRECT->DESTIF != testdata->localhost)  {
         RIP_send_req_ipif(route->DIRECT->DESTIF);
      } /* Endif */
   } else if (route && route->VIRTUAL && route->VIRTUAL->ADDRESS) {
      /* Don't advertise on local interface */
      if (route->VIRTUAL->DESTIF != testdata->localhost)  {
         RIP_send_req_ipif(route->VIRTUAL->DESTIF);
      } /* Endif */
      
   } /* Endif */

   return FALSE;
} /* Endbody */

static uint_32 RIP_send_req(
    void
)
{ /* Body */
   IP_CFG_STRUCT_PTR            IP_cfg_ptr = RTCS_getcfg(IP);
   struct RIP_send_req_struct   testdata;

   testdata.localhost = RTCS_IF_LOCALHOST_PRV;
   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, RIP_send_req_test, &testdata);

   return RTCS_OK;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_expire_periodic
* Returned Values : boolean
* Comments        :
*
*END*-----------------------------------------------------------------*/

static boolean RIP_expire_periodic(
      TCPIP_EVENT_PTR   event      /* [IN/OUT] the resend event */
)
{ /* Body */

    RIP_send_resp(ADV_VERSION, FALSE);

    event->TIME = RND_RANGE(RIP_TIME_MIN_PERIODIC,
                    RIP_TIME_MAX_PERIODIC);
    return TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_expire_trig_upd
* Returned Values : boolean
* Comments        :
*
*END*-----------------------------------------------------------------*/

static boolean RIP_expire_trig_upd(
      TCPIP_EVENT_PTR   event      /* [IN/OUT] the resend event */
)
{ /* Body */
    RIP_CFG_STRUCT_PTR       ripcfg = event->PRIVATE;

    /* if no route has been during the timer run, just leave */
    if (ripcfg->RT_CHANGED_F == FALSE) {
        /* update the internal flag to know if the timer is running or not */
        ripcfg->TIMER_TRIG_UPD.PRIVATE = NULL;
        return FALSE;
    }

    /* send the changed routes */
    RIP_send_resp(ADV_VERSION, TRUE);

    /* restart the timer */
    event->TIME = RND_RANGE(RIP_TIME_MIN_TRIG_UPD, RIP_TIME_MAX_TRIG_UPD);
    return TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_trig_udp
* Returned Values : boolean
* Comments        :
*
*END*-----------------------------------------------------------------*/

static void RIP_trig_upd(
    void
)
{ /* Body */
    RIP_CFG_STRUCT_PTR     ripcfg = RTCS_getcfg(RIP);

    if (RTCS_getcfg(RIP) == NULL) return;

    /* if the timer is currently running, dont send the data */
    if (ripcfg->TIMER_TRIG_UPD.PRIVATE)
        return;

    /* send the changed routes */
    RIP_send_resp(ADV_VERSION, TRUE);

    /* start the timer */
    ripcfg->TIMER_TRIG_UPD.TIME = RND_RANGE(RIP_TIME_MIN_TRIG_UPD,
                        RIP_TIME_MAX_TRIG_UPD);
    ripcfg->TIMER_TRIG_UPD.EVENT = RIP_expire_trig_upd;
    ripcfg->TIMER_TRIG_UPD.PRIVATE = ripcfg;
    TCPIP_Event_add(&ripcfg->TIMER_TRIG_UPD);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RIP_new_bindif
*  Parameters     :
*  Comments       :
*                 : - can be called before RIP_init
*
*END*-----------------------------------------------------------------*/

void RIP_new_bindif (
    IP_ROUTE_DIRECT_PTR bindif /* [IN] the outgoing binded interface */
)
{ /* Body */
    RIP_CFG_STRUCT_PTR  cfg = RTCS_getcfg(RIP);
    IP_CFG_STRUCT_PTR   IP_cfg_ptr = RTCS_getcfg(IP);
    ip_mreq         mreq;

    if (!cfg) {
       return;
    } /* Endif */

    /* do not init the routing on the local interface */
    if (bindif->NETIF == RTCS_IF_LOCALHOST_PRV) {
       return;
    } /* Endif */

    /* init the multicast group */
    mreq.imr_multiaddr.s_addr = INADDR_RIP_GROUP;
    mreq.imr_interface.s_addr = bindif->ADDRESS;
    IGMP_join_group(&cfg->UCB->MCB_PTR, &mreq, &cfg->UCB->IGMP_LEAVEALL);

    if (bindif->NETIF) {
       RIP_send_req_ipif(bindif->NETIF);
    } else {
       RIP_send_req_ipif(bindif->DESTIF);
    } /* Endif */
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_init_static_rt
* Returned Values : void
* Comments        : - called to init the RIP part of a static route
*                     created by ipif_add()
*                 : - can be called before RIP_init
*
*END*-----------------------------------------------------------------*/

void RIP_init_static_rt
(
    IP_ROUTE_INDIRECT_PTR gate,   /* [IN] the route to init */
    uint_16 metric                /* [IN] metric of this route. [0,65535] */
)
{ /* Body */
    RIP_CFG_STRUCT_PTR  ripcfg = RTCS_getcfg(RIP);

    _mem_zero(&gate->RIP, sizeof(gate->RIP));
    gate->RIP.METRIC = metric / 4096;
    /* sanity check */
    if (gate->RIP.METRIC < RIP_MIN_METRIC) {
        gate->RIP.METRIC = RIP_MIN_METRIC;
    } /* Endif */
    if (gate->RIP.METRIC > RIP_MAX_METRIC) {
        gate->RIP.METRIC = RIP_MAX_METRIC;
    } /* Endif */
    /* no src interface for a static route */
    gate->RIP.IPIFSRC = NULL;
    gate->RIP.CHANGED_F = TRUE;
    if (ripcfg){
        ripcfg->RT_CHANGED_F = TRUE;
        RIP_trig_upd();
    }
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RIP_remove_rt
* Returned Values : void
* Comments        : - called to close the RIP part of a route
*                     created by ROUTE_remove()
*
*END*-----------------------------------------------------------------*/

void RIP_remove_rt(IP_ROUTE_INDIRECT_PTR gate)
{ /* Body */
    /* cancel the timeout/gc timer */
    TCPIP_Event_cancel(&gate->RIP.TIMEOUT);
    _mem_zero(&gate->RIP, sizeof(gate->RIP));
} /* Endbody */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/build/bat/usbd_INV1_K60F120.bat<|end_filename|>
@echo off

rem convert path to backslash format
set MQXROOTDIR=%1
set MQXROOTDIR=%MQXROOTDIR:/=\%
set OUTPUTDIR=%2
set OUTPUTDIR=%OUTPUTDIR:/=\%
set TOOL=%3


rem copy common files
IF NOT EXIST %OUTPUTDIR% mkdir %OUTPUTDIR%
copy %MQXROOTDIR%\usb\common\include\usb.h %OUTPUTDIR%\usb.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_debug.h %OUTPUTDIR%\usb_debug.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_desc.h %OUTPUTDIR%\usb_desc.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_error.h %OUTPUTDIR%\usb_error.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_misc.h %OUTPUTDIR%\usb_misc.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_misc_prv.h %OUTPUTDIR%\usb_misc_prv.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_prv.h %OUTPUTDIR%\usb_prv.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_types.h %OUTPUTDIR%\usb_types.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_audio.h %OUTPUTDIR%\usb_audio.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_cdc.h %OUTPUTDIR%\usb_cdc.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_cdc_pstn.h %OUTPUTDIR%\usb_cdc_pstn.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_class.h %OUTPUTDIR%\usb_class.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_framework.h %OUTPUTDIR%\usb_framework.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_hid.h %OUTPUTDIR%\usb_hid.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_msc.h %OUTPUTDIR%\usb_msc.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_msc_scsi.h %OUTPUTDIR%\usb_msc_scsi.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_phdc.h %OUTPUTDIR%\usb_phdc.h /Y
copy %MQXROOTDIR%\usb\device\source\classes\include\usb_stack_config.h %OUTPUTDIR%\usb_stack_config.h /Y
copy %MQXROOTDIR%\usb\device\source\include\dev_cnfg.h %OUTPUTDIR%\dev_cnfg.h /Y
copy %MQXROOTDIR%\usb\device\source\include\dev_main.h %OUTPUTDIR%\dev_main.h /Y
copy %MQXROOTDIR%\usb\device\source\include\devapi.h %OUTPUTDIR%\devapi.h /Y
copy %MQXROOTDIR%\usb\device\source\include\ehci\ehci_dev_main.h %OUTPUTDIR%\ehci_dev_main.h /Y
copy %MQXROOTDIR%\usb\device\source\include\khci\khci_dev_main.h %OUTPUTDIR%\khci_dev_main.h /Y
copy %MQXROOTDIR%\usb\device\source\include\rtos\mqx_dev.h %OUTPUTDIR%\mqx_dev.h /Y
copy %MQXROOTDIR%\usb\host\source\host\khci\khci_prv.h %OUTPUTDIR%\khci_prv.h /Y


goto tool_%TOOL%

rem cw10 files
:tool_cw10
goto copy_end

rem iar files
:tool_iar
goto copy_end

rem cw10gcc files
:tool_cw10gcc
goto copy_end

rem uv4 files
:tool_uv4
goto copy_end

:copy_end



<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_misc.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_misc.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the functions that normally would not appear
*   since the fio.h file generates macros that replace them.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Returns the next character as an unsigned char (converted to an int). 
 * 
 * \return Character in char (int).
 * \return IO_EOF (End of file of error.)  
 */ 
_mqx_int _io_getchar
   (
      void
   )
{ /* Body */

   return(_io_fgetc(stdin));

} /* Endbody */

/*!
 * \brief Returns the number of characters read into the input line.
 * 
 * Terminating '\n' is stripped.
 * 
 * \param[in,out] str_ptr   Where to store the input characters.
 * \param[in]     max_count Maximum number of characters to store.
 * 
 * \return Number of characters. 
 */ 
_mqx_int _io_getline
   (
      char _PTR_ str_ptr,
      _mqx_int   max_count
   )
{ /* Body */

   return(_io_fgetline(stdin, str_ptr, max_count));

} /* Endbody */

/*!
 * \brief Reads the next input line into the character array.
 * 
 * The terminating newline is replaced with '\0'.
 * 
 * \param[in,out] tty_line_ptr Where to store the input string.
 * 
 * \return Input string.
 * \return NULL (End of file or error.)   
 */ 
char _PTR_ _io_gets
   (
      char _PTR_ tty_line_ptr
   )
{ /* Body */

   return(_io_fgets(tty_line_ptr, 0, stdin));

} /* Endbody */

/*!
 * \brief Writes the character (converted to an unsigned char).
 * 
 * \param[in] c Character to print out.
 * 
 * \return Written character.
 * |return IO_EOF (Failure.)  
 */ 
_mqx_int _io_putchar
   (
      _mqx_int c
   )
{ /* Body */

   return(_io_fputc(c, stdout));

} /* Endbody */

/*!
 * \brief Writes the sting.
 * 
 * \param[in] string_ptr The string to print out.
 * 
 * \return 0 (Succes.)
 * \return MQX_EOF (Failure.)  
 */ 
_mqx_int _io_puts
   (
      char _PTR_ string_ptr
   )
{ /* Body */

   return(_io_fputs(string_ptr, stdout));

} /* Endbody */

/*!
 * \brief Determines whether a character is available.
 * 
 * \return TRUE (Character is available.), FALSE (Character is not available.) 
 */ 
boolean _io_status
   (
      void
   )
{ /* Body */

   return(_io_fstatus(stdin));

} /* Endbody */

/*!
 * \brief Pushes back a character.
 *  
 * Pushed character will be returned on next read. Only 1 pushback character is
 * allowed.
 * 
 * \param[in] character The character to return to the current input stream.
 * 
 * \return Pushed back character.
 * \return IO_EOF (Failure.)  
 */
_mqx_int _io_ungetc
   (
      _mqx_int character
   )
{ /* Body */

   return(_io_fungetc(character, stdin));

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/int/i2c_int_mcf52xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_int_mcf52xx.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains low level functions for the I2C interrupt device driver
*   for 52XX Coldfire family.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "i2c.h"
#include "i2c_int_prv.h"
#include "i2c_mcf52xx_prv.h"


extern uint_32 _mcf52xx_i2c_polled_init (MCF52XX_I2C_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _mcf52xx_i2c_polled_ioctl (VMCF52XX_I2C_INFO_STRUCT_PTR, uint_32, uint_32_ptr);

extern uint_32 _mcf52xx_i2c_int_init (IO_I2C_INT_DEVICE_STRUCT_PTR, char_ptr);
extern uint_32 _mcf52xx_i2c_int_deinit (IO_I2C_INT_DEVICE_STRUCT_PTR, VMCF52XX_I2C_INFO_STRUCT_PTR);
extern uint_32 _mcf52xx_i2c_int_rx (IO_I2C_INT_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _mcf52xx_i2c_int_tx (IO_I2C_INT_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
static void    _mcf52xx_i2c_isr (pointer);


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_int_install
* Returned Value   : MQX error code
* Comments         :
*    Install an I2C device.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr                     identifier,
  
      /* [IN] The I/O init data pointer */
      MCF52XX_I2C_INIT_STRUCT_CPTR init_data_ptr
   )
{ /* Body */

   return _io_i2c_int_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, char_ptr))_mcf52xx_i2c_int_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_mcf52xx_i2c_int_deinit,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_mcf52xx_i2c_int_rx,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_mcf52xx_i2c_int_tx,
      (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_mcf52xx_i2c_polled_ioctl, 
      (pointer)init_data_ptr);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_int_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an I2C device.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_int_init
   (
      /* [IN] Initialization information for the device being opened */
      IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The rest of the name of the device opened */
      char_ptr                     open_name_ptr

   )
{ /* Body */
   VMCF52XX_I2C_STRUCT_PTR         i2c_ptr;
   VMCF52XX_I2C_INFO_STRUCT_PTR    io_info_ptr;
   MCF52XX_I2C_INIT_STRUCT_PTR     i2c_init_ptr;
   uint_32                         vector, result;

   i2c_init_ptr = (MCF52XX_I2C_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
   result = _mcf52xx_i2c_polled_init (i2c_init_ptr,
                                     &(int_io_dev_ptr->DEV_INFO_PTR),
                                     open_name_ptr);
   if (result)
   {
      return result;
   }
   
   io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;
   vector = _bsp_get_i2c_vector (i2c_init_ptr->CHANNEL);
   if (0 == vector)
   {
      return I2C_ERROR_CHANNEL_INVALID;
   }
   io_info_ptr->VECTOR = vector;

   /* Allocate buffers */
   io_info_ptr->RX_BUFFER = (pointer)_mem_alloc_system (i2c_init_ptr->RX_BUFFER_SIZE);
   if (NULL == io_info_ptr->RX_BUFFER) 
   {
      return MQX_OUT_OF_MEMORY;
   }
   io_info_ptr->TX_BUFFER = (pointer)_mem_alloc_system (i2c_init_ptr->TX_BUFFER_SIZE);
   if (NULL == io_info_ptr->TX_BUFFER) 
   {
      _mem_free (io_info_ptr->RX_BUFFER);
      io_info_ptr->RX_BUFFER = NULL;
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type (io_info_ptr->RX_BUFFER, MEM_TYPE_IO_I2C_IN_BUFFER);       
   _mem_set_type (io_info_ptr->TX_BUFFER, MEM_TYPE_IO_I2C_OUT_BUFFER);       

   /* Install new vectors and backup the old ones */
   io_info_ptr->OLD_ISR_DATA = _int_get_isr_data (vector);
   io_info_ptr->OLD_ISR = _int_install_isr (vector, _mcf52xx_i2c_isr, (pointer)io_info_ptr);
   _mcf52xx_int_init((PSP_INTERRUPT_TABLE_INDEX)vector, i2c_init_ptr->LEVEL, i2c_init_ptr->SUBLEVEL, TRUE);

   /* Enable I2C interrupts */
   i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_IIEN;

   return result;
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_int_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an I2C device.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_int_deinit
   (
      /* [IN] the initialization information for the device being opened */
      IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the address of the device specific information */
      VMCF52XX_I2C_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   VMCF52XX_I2C_STRUCT_PTR         i2c_ptr;
   MCF52XX_I2C_INIT_STRUCT_PTR     i2c_init_ptr;
      
   if ((NULL == io_info_ptr) || (NULL == int_io_dev_ptr)) 
   {
      return I2C_ERROR_INVALID_PARAMETER;
   }

   i2c_ptr = io_info_ptr->I2C_PTR;
   if (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IBB) 
   {
      return I2C_ERROR_DEVICE_BUSY;
   }
   
   /* Disable the I2C */
   i2c_ptr->I2CR    = 0x00;

   /* Clear the I2C events */
   i2c_ptr->I2SR    = 0x00; 
 
   /* Install original vectors */
   i2c_init_ptr = (MCF52XX_I2C_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
   _mcf52xx_int_init(io_info_ptr->VECTOR, i2c_init_ptr->LEVEL, i2c_init_ptr->SUBLEVEL, FALSE);
   _int_install_isr (io_info_ptr->VECTOR, io_info_ptr->OLD_ISR, io_info_ptr->OLD_ISR_DATA);
   
   /* Free buffers and info struct */
   _mem_free (int_io_dev_ptr->DEV_INFO_PTR);
   int_io_dev_ptr->DEV_INFO_PTR = NULL;
   _mem_free (io_info_ptr->RX_BUFFER);
   io_info_ptr->RX_BUFFER = NULL;
   _mem_free (io_info_ptr->TX_BUFFER);
   io_info_ptr->TX_BUFFER = NULL;

   return I2C_OK;
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_int_rx
* Returned Value   : number of bytes read
* Comments         : 
*   Returns the number of bytes received.
*   Reads the data into provided array when data is available.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_int_rx
   (
      /* [IN] the address of the device specific information */
      IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The array to copy data into */
      uchar_ptr                    buffer,
      
      /* [IN] number of bytes to read */
      uint_32                      length
   )
{ /* Body */
   VMCF52XX_I2C_INFO_STRUCT_PTR    io_info_ptr;
   VMCF52XX_I2C_STRUCT_PTR         i2c_ptr;   
   uint_32                         num;
   volatile uint_8                 tmp;
         
   io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;

   /* Critical section + avoiding spurious interrupt */
   _int_disable ();
   _bsp_int_disable (io_info_ptr->VECTOR);
   _int_enable ();

   /* Get data from input buffer */
   for (num = 0; num < length; num++)
   {
      if (io_info_ptr->RX_OUT == io_info_ptr->RX_IN) break;
      *buffer++ = io_info_ptr->RX_BUFFER[io_info_ptr->RX_OUT++];
      if (io_info_ptr->RX_OUT >= io_info_ptr->INIT.RX_BUFFER_SIZE) io_info_ptr->RX_OUT = 0;
   }

   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION |= I2C_OPERATION_READ;
   tmp = io_info_ptr->STATE;
   if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
   {
      io_info_ptr->STATE = I2C_STATE_RECEIVE;
      if (I2C_MODE_MASTER == io_info_ptr->MODE)
      {
         i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MTX;
         i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
         if (I2C_STATE_REPEATED_START == tmp)
         {
            i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_RSTA;
         }
         else
         {
            i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MSTA;
         }
         io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
         i2c_ptr->I2DR = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_READ;
         io_info_ptr->STATISTICS.TX_PACKETS++;
         while (0 == (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IIF)) 
            { };   /* wait for address transferred */
      }
   }
   
   /* Check for bus idle in slave mode */
   if (0 == (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MSTA))
   {
      if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IBB)))
      {
         io_info_ptr->OPERATION = 0;
         io_info_ptr->RX_REQUEST = 0;
         io_info_ptr->STATE = I2C_STATE_FINISHED;
      }
   }
   
   /* Interrupt enable - end of critical section */
   _bsp_int_enable (io_info_ptr->VECTOR);
      
   return num;
   
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_int_tx
* Returned Value   : number of bytes written
* Comments         : 
*   Returns the number of bytes written.
*   Writes the data provided into transmition buffer if available.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_int_tx
   (
      /* [IN] the address of the device specific information */
      IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The array characters are to be read from */
      uchar_ptr                    buffer,
      
      /* [IN] number of bytes to output */
      uint_32                      length
   )
{ /* Body */
   VMCF52XX_I2C_INFO_STRUCT_PTR    io_info_ptr;
   VMCF52XX_I2C_STRUCT_PTR         i2c_ptr;   
   uint_32                         num, tmp;
   
   io_info_ptr  = int_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;

   /* Critical section + avoiding spurious interrupt */
   _int_disable ();
   _bsp_int_disable (io_info_ptr->VECTOR);
   _int_enable ();

   /* Fill in the output buffer  */
   for (num = 0; num < length; num++)
   {
      tmp = io_info_ptr->TX_IN + 1;
      if (tmp >= io_info_ptr->INIT.TX_BUFFER_SIZE) tmp = 0;
      if (tmp == io_info_ptr->TX_OUT) break;
      io_info_ptr->TX_BUFFER[io_info_ptr->TX_IN] = *buffer++;
      io_info_ptr->TX_IN = tmp;
   }
   
   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION &= (~ I2C_OPERATION_READ);
   tmp = io_info_ptr->STATE;
   if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
   {
      io_info_ptr->STATE = I2C_STATE_TRANSMIT;
      if (I2C_MODE_MASTER == io_info_ptr->MODE)
      {
         i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MTX;
         i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
         if (I2C_STATE_REPEATED_START == tmp)
         {
            i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_RSTA;
         }
         else
         {
            i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MSTA;
         }
         io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
         i2c_ptr->I2DR = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_WRITE;
         io_info_ptr->STATISTICS.TX_PACKETS++;
         while (0 == (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IIF))
            { };    /* wait for address transferred */
      }
   }

   /* Check for bus idle in slave mode */
   if (0 == (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MSTA))
   {
      if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IBB)))
      {
         io_info_ptr->OPERATION = 0;
         io_info_ptr->RX_REQUEST = 0;
         io_info_ptr->STATE = I2C_STATE_FINISHED;
      }
   }
   
   /* Interrupt enable - end of critical section */
   _bsp_int_enable (io_info_ptr->VECTOR);

   return num;

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    :_mcf52xx_i2c_isr
* Returned Value   : none   
*
*END*********************************************************************/
static void _mcf52xx_i2c_isr
   (
      pointer                   parameter
   )
{ /* Body */
   VMCF52XX_I2C_INFO_STRUCT_PTR io_info_ptr = parameter;
   VMCF52XX_I2C_STRUCT_PTR      i2c_ptr = io_info_ptr->I2C_PTR;
   uint_8                       i2csr;
   volatile uint_8              tmp;

   i2csr = i2c_ptr->I2SR;
   io_info_ptr->STATISTICS.INTERRUPTS++;
   
   /* Master */
   if (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MSTA)
   {
      /* Transmit */
      if (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MTX)
      {
         /* Not ack */
         if (i2csr & MCF52XX_I2C_I2SR_RXAK)
         {
            i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
            io_info_ptr->TX_OUT = io_info_ptr->TX_IN;
            io_info_ptr->STATE = I2C_STATE_FINISHED;
            io_info_ptr->STATISTICS.TX_NAKS++;
         }
         /* Ack */
         else
         {
            /* Transmit requested */
            if (I2C_STATE_TRANSMIT == io_info_ptr->STATE)
            {
               /* Anything to transmit? */
               if ((io_info_ptr->TX_IN != io_info_ptr->TX_OUT) && (I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))))
               {
                  i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                  i2c_ptr->I2DR = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /* transmit data */
                  if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
                  io_info_ptr->STATISTICS.TX_PACKETS++;
               }
               else
               {
                  _bsp_int_disable (io_info_ptr->VECTOR);
               }
            }
            /* Receive requested */
            else if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
            {
               if ((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED)))
               {
                  i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_MTX);
                  if (1 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_TXAK;
                  }
                  else
                  {
                     i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_TXAK);
                  }
                  i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                  if (0 == io_info_ptr->RX_REQUEST)
                  {
                     io_info_ptr->STATE = I2C_STATE_FINISHED;
                  }
                  else
                  {
                     tmp = i2c_ptr->I2DR;   /* dummy read to clock in 1st byte */
                  }
               }
               else
               {
                  _bsp_int_disable (io_info_ptr->VECTOR);
               }
            }
            /* Others are unwanted/not handled states */
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
            }
         }
      }
      /* Receive */
      else
      {
         /* Receive requested */
         if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
         {
            if (((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (0 != io_info_ptr->RX_REQUEST))
            {
               tmp = io_info_ptr->RX_IN + 1;
               if (tmp >= io_info_ptr->INIT.RX_BUFFER_SIZE) tmp = 0;
               
               /* Buffer full */
               if (tmp == io_info_ptr->RX_OUT)
               {
                  _bsp_int_disable (io_info_ptr->VECTOR);
               }
               /* Buffer not full */
               else
               {
                  i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                  io_info_ptr->RX_REQUEST--;
                  if (1 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_TXAK;
                  }
                  else
                  {
                     i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_TXAK);
                  }
                  if (0 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MTX;  /* no more reading */
                  }
                  io_info_ptr->RX_BUFFER[io_info_ptr->RX_IN] = i2c_ptr->I2DR;   /* receive data */
                  io_info_ptr->RX_IN = tmp;
                  if (0 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_MTX);
                     io_info_ptr->STATE = I2C_STATE_FINISHED;
                  }
                  io_info_ptr->STATISTICS.RX_PACKETS++;
               }
            }
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
            }
         }
         /* Others are unwanted/not handled states */
         else
         {
            _bsp_int_disable (io_info_ptr->VECTOR);
         }
      }
   }
   /* Slave */
   else
   {
      /* Master arbitration lost */
      if (i2csr & MCF52XX_I2C_I2SR_IAL)
      {
         i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IAL);
         io_info_ptr->STATE = I2C_STATE_LOST_ARBITRATION;
         io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS++;
      }
      /* Addressed as slave */
      if (i2csr & MCF52XX_I2C_I2SR_IAAS)
      {
         if (I2C_MODE_MASTER == io_info_ptr->MODE)
         {
            io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE++;
         }
         /* Transmit requested */
         if (i2csr & MCF52XX_I2C_I2SR_SRW)
         {
            io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_TX;
            if ((I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (io_info_ptr->TX_IN != io_info_ptr->TX_OUT))
            {
               i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MTX;
               i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
               i2c_ptr->I2DR = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /* transmit data */
               if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
               io_info_ptr->STATISTICS.TX_PACKETS++;
            }
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
            }
         }
         /* Receive requested */
         else
         {
            io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_RX;
            if (((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (io_info_ptr->RX_OUT == io_info_ptr->RX_IN) && (0 != io_info_ptr->RX_REQUEST))
            {
               i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_MTX);
               i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
               if (1 == io_info_ptr->RX_REQUEST)
               {
                  i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_TXAK;
               }
               else
               {
                  i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_TXAK);
               }
               tmp = i2c_ptr->I2DR;   /* dummy read to release bus */
            }
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
            }
         }
      }
      /* Normal slave operation */
      else
      {
         /* No master arbitration lost */
         if (! (i2csr & MCF52XX_I2C_I2SR_IAL))
         {
            /* Transmit */
            if (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MTX)
            {
               /* Not ack */
               if (i2csr & MCF52XX_I2C_I2SR_RXAK)
               {
                  i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                  io_info_ptr->TX_OUT = io_info_ptr->TX_IN;
                  io_info_ptr->STATE = I2C_STATE_FINISHED;
                  io_info_ptr->STATISTICS.TX_NAKS++;
               }
               /* Ack */
               else
               {
                  /* Transmit requested */
                  if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_TX == io_info_ptr->STATE)) 
                     && (io_info_ptr->TX_IN != io_info_ptr->TX_OUT) && (I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))))
                  {
                     i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                     i2c_ptr->I2DR = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /* transmit data */
                     if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
                     io_info_ptr->STATISTICS.TX_PACKETS++;
                  }
                  else
                  {
                     _bsp_int_disable (io_info_ptr->VECTOR);
                  }
               }
            }
            /* Receive */
            else
            {
               /* Receive requested */
               if (((I2C_STATE_RECEIVE == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_RX == io_info_ptr->STATE)) 
                  && ((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (0 != io_info_ptr->RX_REQUEST))
               {
                  tmp = io_info_ptr->RX_IN + 1;
                  if (tmp >= io_info_ptr->INIT.RX_BUFFER_SIZE) tmp = 0;
                  if (tmp == io_info_ptr->RX_OUT)
                  {
                     _bsp_int_disable (io_info_ptr->VECTOR);
                  }
                  else
                  {
                     i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                     io_info_ptr->RX_REQUEST--;
                     if (1 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_TXAK;
                     }
                     else
                     {
                        i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_TXAK);
                     }
                     if (0 == io_info_ptr->RX_REQUEST)
                     {
                        io_info_ptr->STATE = I2C_STATE_FINISHED;
                     }
                     io_info_ptr->RX_BUFFER[io_info_ptr->RX_IN] = i2c_ptr->I2DR;   /* receive data */
                     io_info_ptr->RX_IN = tmp;
                     io_info_ptr->STATISTICS.RX_PACKETS++;
                  }
               }
               else
               {
                  _bsp_int_disable (io_info_ptr->VECTOR);
               }
            }
         }
         else
         {
            _bsp_int_disable (io_info_ptr->VECTOR);
         }
      }
   }
   io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/tcp_send.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcp_send.c$
* $Version : 3.8.14.0$
* $Date    : Sep-3-2012$
*
* Comments:
*
*   Send Buffer Space:
*   |----+----------+-- - - - |
*   sndbuf                     sndbuf
*   :                       +sndlen
*   :
*   :
*   :
*   Send Sequence Space:     :
*   :
*   0  : 1       2          3          4
*   |-- - -       - -----+----|----------|----------|----------
*   sndiss                 :  snduna     sndnxt     snduna
*   sndbufseq                   +sndwnd
*   0  - very old sequence numbers, acknowledged and "returned" to client(s)
*   1  - old sequence numbers which have been acknowledged
*   2  - sequence numbers of unacknowledged data (may be resent)
*   3  - sequence numbers allowed for new data transmission
*   4  - future sequence numbers which are not yet allowed
*   Notes:
*   - the send buffer may end (sndbuf+sndlen) in section 3 or 4;
*   - the send buffer space is not a contiguous area of memory, but
*   rather a chain of buffer segments, some of which are in the
*   `send' circular ring buffer, some of which are owned by sender
*   clients;
*   - some seq #'s and related values, e.g., sndxmit, sndcwnd, sndstresh,
*   etc., are not shown
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"      /* for error codes */
#include "tcp_prv.h"    /* for TCP internal definitions */


///////////////
#include "ip_prv.h"
///////////////


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Update_send_window
* Returned Values : None.
* Comments        :
*
*  Update the nb of bytes we can send.  This should usually increase,
*   not decrease, unless the peer TCP is broken...
*
*END*-----------------------------------------------------------------*/

void TCP_Update_send_window
   (
      TCB_STRUCT_PTR    tcb,  /* IN/OUT - TCP context */
      TCP_HEADER _PTR_  seg   /* IN     - the incoming ACK packet */
   )
{ /* Body */
   uint_32  ack;
   uint_16  win;

   ack = ntohl(seg->ack);
   win = ntohs(seg->window);

   if ( LT32( ack + win, tcb->snduna + tcb->sndwnd ) ) {

      switch ( tcb->state ) {
         case SYN_SENT:
         case SYN_RECEIVED:
         case ESTABLISHED:
         case CLOSE_WAIT:

            /* Aargh!  Window shrink! */
            RTCS_log_error( ERROR_TCP,
                                 RTCSERR_TCP_SHRINKER_HOST,
                                 (uint_32)tcb->remote_host,
                                 0, 0 );
            break;

         default:
            break;

      } /* End Switch */

      tcb->sndprobeto = tcb->sndrto;      /* in case window becomes 0 */

      /*  We may have to decrease sndnxt, this a dubious thing to do,
       *   but then again we're taking recovery measures because of a
       *   misbehaving host.
       *  Assume seg->ack+seg->window won't actually be less than snduna
       */
      if ( GT32(tcb->sndnxt, ack + win) ) {
         tcb->sndnxt = ack + win;
      } /* Endif */

   } /* Endif */

   tcb->sndwnd = win;
   tcb->sndwl1 = ntohl(seg->seq);
   tcb->sndwl2 = ack;
   if ( tcb->sndwnd > tcb->sndwndmax ) {
      tcb->sndwndmax = tcb->sndwnd;
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_RTT_measure
* Returned Values : SndClock *
* Comments        :
*
*  We just received a packet which ack'ed something we sent;
*   given the timestamp of receipt, look for the latest transmission
*   timestamp which got ack'ed (if any) and use it for a measure M of
*   RTT (Round Trip Time), to compute new RTT estimates (average and variance)
*   and RTO (Retransmission TimeOut);
*
*  There shouldn't be any transmission timestamps stored for retransmitted
*   segments, so that we know what we have is a valid measure, without
*   retransmission ambiguity.
*
*  Returns pointer to first remaining transmission timestamp entry if any,
*   or 0 if none (this is for efficiency's sake, since this is readily
*   available here, and possibly needed by caller)
*
*END*-----------------------------------------------------------------*/

SndClock _PTR_ TCP_Process_RTT_measure
   (
      TCB_STRUCT_PTR tcb,     /* IN/OUT - TCP context */
      int_32         rcvtime  /* IN     - time packet was received */
   )
{ /* Body */
   SndClock _PTR_ tail;
   int_32         M;

   /*  If xmit timestamp queue is empty, or its first entry is beyond all
    *   ack'ed segments, quit
    */
   tail = tcb->sndclktail;

   if ( tail == tcb->sndclkhead && tcb->sndclkavail > 0 ) {
      /* No timestamps active */
      return NULL;
   } /* Endif */

   if ( GT32(tail->seq, tcb->snduna) ) {
      /* Last seq # of earliest timestamp not yet acknowledged */
      return tail;
   } /* Endif */

   /*  Get latest ack'ed xmit timestamp (remove it and all previous ones)
    */
   do {
      M = tail->time;      /* xmit timestamp */
      tcb->sndclkavail++;
      if ( ++tail >= tcb->sndclkend ) {
         tail = tcb->sndclk;
      } /* Endif */
   } while (tail != tcb->sndclkhead && LE32(tail->seq, tcb->snduna));

   tcb->sndclktail = tail;
   M = rcvtime - M;        /* RTT measure */

   /* This is from <NAME>'s algorithm.
    * Note that sndrtta is the average xmt time scaled up by a
    * factor of 8, and sndrttd is the average xmt time deviation
    * scaled up by a factor of 4 (explaining the shifting going on).
    */
   M -= (tcb->sndrtta >> 3);
   tcb->sndrtta += M;

   if ( M < 0 ) {
      M = -M;
   } /* Endif */
   M -= (tcb->sndrttd >> 2);
   tcb->sndrttd += M;
   /*2.02 */
   tcb->sndrto = (((tcb->sndrtta >> 2) + tcb->sndrttd) >> 1) + TICK_LENGTH;

   if ( tcb->sndrto < _TCP_rto_min ) {
      tcb->sndrto = _TCP_rto_min;
   } /* Endif */

   if ( tcb->sndrto > tcb->sndrtomax ) {
      tcb->sndrto = tcb->sndrtomax;
   } /* Endif */

   return tail;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP6_Send_IP_packet
* Returned Values : int_32
* Comments        :
*
*  Compute checksum and send packet to IP layer;
*   all packets are sent through here.
*
*  Returns RTCS_OK if packet accepted.
*
*  If an error is returned, the PCB is gone (freed by IP_send)
*   but the request still must be returned.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6 
uint_32 TCP6_Send_IP_packet
   (
      RTCSPCB_PTR          pcb,         /* IN/OUT - packet to send */
      in6_addr            *srchost,    /* IN     - IPv6 source address */
      in6_addr            *desthost,   /* IN     - IPv6 dest address */
      boolean              bypass      /* IN     - TRUE to bypass checksum */
   )
{ /* Body */
   TCP_HEADER _PTR_  seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   int_32            err;

   /*
   ** Finish things up, checksum, etc
   */
   if ( ! bypass ) {

      /*
      ** Calculate the checksum for the packet now, and let IP
      ** add the IP pseudo checksum later.
      */
      pcb->IP_SUM     = IP_Sum_PCB(RTCSPCB_SIZE(pcb), pcb);
      pcb->IP_SUM_PTR = seg->checksum;

   } /* Endif */

   err = IP6_send(pcb, IPPROTO_TCP, srchost, desthost,pcb->IFSRC, 0);

   if ( err != RTCS_OK ) {

      DEBUGTCP(printf("\nTCP: TCP_Send_IP_packet: errno %x on IP_send.", err));

   /* error will be recorded in TCB by caller... */

   } /* Endif */

   return err;

} /* Endbody */
#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Send_IP_packet
* Returned Values : int_32
* Comments        :
*
*  Compute checksum and send packet to IP layer;
*   all packets are sent through here.
*
*  Returns RTCS_OK if packet accepted.
*
*  If an error is returned, the PCB is gone (freed by IP_send)
*   but the request still must be returned.
*
*END*-----------------------------------------------------------------*/

uint_32 TCP_Send_IP_packet
   (
      RTCSPCB_PTR          pcb,         /* IN/OUT - packet to send */
      _ip_address          srchost,    /* IN     - source address */
      _ip_address          desthost,   /* IN     - dest address */
      boolean              bypass      /* IN     - TRUE to bypass checksum */
   )
{ /* Body */
   TCP_HEADER _PTR_  seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   int_32            err;

   /*
   ** Finish things up, checksum, etc
   */
   if ( ! bypass ) {

      /*
      ** Calculate the checksum for the packet now, and let IP
      ** add the IP pseudo checksum later.
      */
      pcb->IP_SUM     = IP_Sum_PCB(RTCSPCB_SIZE(pcb), pcb);
      pcb->IP_SUM_PTR = seg->checksum;

   } /* Endif */

   err = IP_send(pcb, IPPROTO_TCP, srchost, desthost, 0);

   if ( err != RTCS_OK ) {

      DEBUGTCP(printf("\nTCP: TCP_Send_IP_packet: errno %x on IP_send.", err));

   /* error will be recorded in TCB by caller... */

   } /* Endif */

   return err;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Send_packet
* Returned Values : None.
* Comments        :
*
*  Send a packet, starting at data sequence `seq';
*
*  Returns OK or error code (RTCSERR_TCP_NOT_CONN, RTCSERR_OUT_OF_MEMORY or
*   IP_send() error)  (return value ignored at this time).
*
*  If error returned, the upper layer request will have been
*   returned to the upper layer and the PCB will have been freed.
*
*  Called by TCP_Transmit() only.
*
*END*-----------------------------------------------------------------*/

void TCP_Send_packet
   (
      TCB_STRUCT_PTR          tcb,     /* IN/OUT - TCP layer context */
      uint_32                 seq,     /* IN     - data sequence number */
      TCP_CFG_STRUCT_PTR      tcp_cfg  /* IN/OUT - TCP layer constants */
   )
{ /* Body */
   TCP_HEADER _PTR_  seg;
   RTCSPCB_PTR       pcb;
   uchar_ptr         data;
   uint_32           sent;
   int_32            window,
                     err;
   boolean           allowdata;     /* true if data can be sent in packet */
   uint_16           size;          /* size of TCP portion of packet */
   uint_16           flags = 0;
   uint_32           dataseq = seq; /* seq # of 1st data byte sent */
   uint_32           dataendseq;    /* seq # of 1st byte after data sent */
   uint_32           rexmit_endseq;
   uint_32           old_sndnxt;    /* stores original sndnxt */
   
   RTCSLOG_FNE4(RTCSLOG_FN_TCP_Send_packet, tcb, seq, tcp_cfg);

   switch ( tcb->state ) {      /* can we put data in the packet? */

      case ESTABLISHED:
      case FINWAIT_1:
      case CLOSING:
      case CLOSE_WAIT:
      case LAST_ACK:
         allowdata = TRUE;
         break;

      case SYN_SENT:
      case SYN_RECEIVED:
         if ( seq == tcb->sndiss ) {
            flags |= SYN;
            dataseq++;
         } /* Endif */
         allowdata = FALSE;
         break;

      case FINWAIT_2:
      case TIME_WAIT:
         /*
         ** This should only occur in TIME_WAIT state for the
         ** ACK of the FIN that transitted us from FIN_WAIT_2
         ** to TIME_WAIT state.
         */
         allowdata = FALSE;
         break;

      case LISTEN:
      case CLOSED:
      default:

         /* This shouldn't normally happen */
         /* Can't send in LISTEN or CLOSED state */
         RTCS_log_error( ERROR_TCP, RTCSERR_TCP_SP_BAD_SEND_STATE, (uint_32)tcb, 0, 0 );
         RTCSLOG_FNX2(RTCSLOG_FN_TCP_Send_packet, -1);
         return;

   } /* End Switch */

   pcb = RTCSPCB_alloc_send(); /* get a packet */
   if ( pcb == NULL ) {

      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_MISSED++);
      RTCS_log_error( ERROR_TCP,
                           RTCSERR_TCP_SP_OUT_OF_PCBS,
                           (uint_32)tcb, 0, 0);
      
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Send_packet, -2);
      return;

   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb);

   /*
   ** Determine the size of the TCP header.  Warning: this calculation
   ** has to be consistent with the algorithm below.
   */
   size = sizeof(TCP_HEADER);
   if ((flags & SYN) != 0 && tcb->rcvmss != TCP_MSS_DEFAULT) {
      size += 4;
   } /* Endif */

   /*
   ** Skip packet's lower-level header(s), fill TCP header;
   **  We should allow space for IP options, if we ever add any...
   */
   RTCSPCB_insert_header(pcb, size);
   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   RTCSPCB_DATA_TRANSPORT(pcb) = RTCSPCB_DATA(pcb);
   htons(seg->source_port, tcb->local_port);
   htons(seg->dest_port, tcb->remote_port);
   htonl(seg->seq, seq);
   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_TCP), 0);

   /*
   ** These aren't done in ESTABLISHED state
   */

   if ( tcb->state == SYN_SENT ) {
      htonl(seg->ack, 0);
   } else {
      flags     |= ACK;
      
       /* draft-ietf-tcpm-tcpsecure-00.txt section 3.2 */
      if(tcb->tcpsecuredraft0) {
        htonl(seg->ack, tcb->rcvnxt - tcb->ackmodifier);
      }
      else
      {
        htonl(seg->ack, tcb->rcvnxt);
      }
      
      tcb->ackmodifier = 0;
   } /* Endif */

   tcb->rcvuna = tcb->rcvnxt;
   htons(seg->window, tcb->rcvwndedge - tcb->rcvnxt);

   if ( (tcb->status & TCPS_TURGENT) != 0 ) {

      { /* Scope */

         int_32 urgentptr = tcb->sndup - seq - 1;

         if ( urgentptr >= 0 ) {

            if ( urgentptr > 0xffff ) {
               htons(seg->urgent, 0xffff);
            } else {
               htons(seg->urgent, urgentptr);
            } /* Endif */
            flags |= URG;

         } else {
            htons(seg->urgent, 0);
         } /* Endif */

      } /* Endscope */

   } else {
      htons(seg->urgent, 0);
   } /* Endif */

   size = sizeof(TCP_HEADER);
   data = (uchar_ptr)seg + size;

   /*
   ** Add options - always send mss (with SYN)
   */
   if ( (flags & SYN) != 0 && tcb->rcvmss != TCP_MSS_DEFAULT ) {

      /* See RFC1122 4.2.2.6 */
      htonc(data, OPT_MSS);
      data++;
      htonc(data, 4);
      data++;
      htons(data, tcb->rcvmss);
      data++;
      data++;
      size += 4;

   } /* Endif */


   flags |= size << (DATAOFS_SHIFT-2); /* -2 to give 32 bit multiples */

   /*
   ** Add data if there is any to send.
   */
   if ( allowdata ) {

      /*
      ** Compute amount of data to send
      */
      sent = tcb->sndbufseq + tcb->sndlen - dataseq;  /* amnt available */
      window = tcb->snduna + tcb->sndwnd - dataseq;
      if ( (int_32)sent > window ) {

         sent = window;

         /* If the send window is closed, send a probe byte */
         if (tcb->sndwnd == 0) {
            sent = 1;
         } /* Endif */

      } /* Endif */

      /*
      ** I'm not counting SYN,FIN; (we only send MSS option with SYN,
      ** where we don't send data):
      */
      if ( (int_32)sent > tcb->sndmax ) {
         sent = tcb->sndmax;
      } /* Endif */

      /*
      ** Don't chop-off sent data at tcb->sndpush even if there
      ** is a PUSH in the middle of the data to send
      */

      /*
      ** Copy data to send into the PCB.
      */

      if ( (int_32)sent > 0 ) {
         tcb->send_error =
            TCP_Copy_from_buffer(tcb,  /* TCP context */
                        data,          /* dest buffer */
                        &sent,         /* no. of bytes to copy */
                        dataseq - tcb->sndbufseq,
                                       /* offset from start of xmit buf */
                        pcb            /* the PCB in use */
                     );
         size += sent;

      } else {
         sent = 0;      /* sent was negative or 0, clamp to 0 */
      } /* Endif */

   } else {
      sent = 0;
   } /* Endif */

   /*
   ** Seq # of 1st byte past data being sent
   */
   dataendseq = dataseq + sent;

   /* advance (re)transmission ptr (but not past FIN) */
   tcb->sndxmit = dataendseq;

   /*
   ** Have we sent all data for the connection, so that we can send FIN?
   */
   if ( GT32(dataendseq, tcb->sndnxt)     &&   /* not retxmt */
      (tcb->status & TCPS_FINTOSEND) != 0 &&   /* client wants to close */
      dataendseq == (tcb->sndbufseq + tcb->sndlen))       /* sent all data */
   {

      TCP_Process_effective_close(tcb, tcp_cfg);

   } /* Endif */

   /*
   ** When in one of these 'closing' states, the end of the send buffer
   **   (sndbufseq + sndlen) is the FIN's sequence #, so check to add FIN
   */
   if ( tcb->state != ESTABLISHED ) {   /* save a little time in mainline */

      switch ( tcb->state ) {
         case FINWAIT_1:
         case FINWAIT_2:
         case CLOSING:
         case TIME_WAIT:
         case LAST_ACK:
            if ( dataendseq == (tcb->sndbufseq + tcb->sndlen) ) {
               flags |= FIN;
               dataendseq++;   /* count FIN */
            } /* Endif */
            break;

         default:
            break;

      } /* End Switch */

   } /* Endif */

   /*
   ** Advance sndnxt as necessary
   */
   old_sndnxt = tcb->sndnxt;        /* save old ending sequence # */
   if ( GT32(dataendseq, tcb->sndnxt) ) {

      /*
      ** New data is being sent
      */
      rexmit_endseq = tcb->sndnxt;   /* after last rexmitted byte */
      tcb->sndnxt   = dataendseq;

      /*
      ** Timestamp segment being sent, for rtt measurement.
      **    Note that new clks go on the ring head, not tail.
      */
      if ( tcb->sndclkavail > 0 ) {

         { /* Scope */

            SndClock _PTR_ clk = tcb->sndclkhead;

            clk->time = RTCS_time_get();
            clk->seq  = dataendseq;
            if ( ++clk >= tcb->sndclkend ) {
               clk = tcb->sndclk;
            } /* Endif */
            tcb->sndclkhead = clk;
            tcb->sndclkavail--;

         } /* Endscope */

      } /* Endif */

   } else {
      rexmit_endseq = dataendseq;   /* after last would-be rexmitted byte */
                                    /*   (if we are retransmitting) */
   } /* Endif */

   /*
   ** If part of the packet is a retransmission, then everything before
   **   rexmit_endseq is a retransmission, so invalidate all timestamps
   **   up to rexmit_endseq.
   **   (can't use a timestamp if round-trip-time becomes ambiguous by
   **    retransmission)
   */
   if ( LT32(seq, old_sndnxt) ) {

      { /* Scope */

         SndClock _PTR_ tail = tcb->sndclktail;

         if ( tail != tcb->sndclkhead || tcb->sndclkavail == 0 ) {

            while ( LE32(tail->seq, rexmit_endseq) ) {

               /*  Remove timestamp...
                */
               tcb->sndclkavail++;
               if ( ++tail >= tcb->sndclkend ) {
                  tail = tcb->sndclk;
               } /* Endif */
               if ( tail == tcb->sndclkhead ) {
                  break;
               } /* Endif */

            } /* Endwhile */
            tcb->sndclktail = tail;

         } /* Endif */

      } /* Endscope */

   } /* Endif */

   /*
   ** Send a PSH only if this is the last segment (packet) of data to
   **   be pushed
   */
   if ( ((tcb->status & TCPS_TPUSH) != 0  &&
       GE32(tcb->sndpush, dataseq)      &&
       LE32(tcb->sndpush,dataseq+sent)) ||
      (flags & FIN))
   {
      flags |= PSH;
   } /* Endif */

   /*
   ** Finish things up (clearing the RESERVED field)
   */
   flags = flags & TCP_RSRV_FIELD_MASK;
   htons(seg->flags, flags);
   htons(seg->checksum, 0);

   /* Just get the TX option from the TCB, as it is always stored there now */
   pcb->LINK_OPTIONS.TX = tcb->TX;

   DEBUGTCP(printf("\nTCP_SendPkt: sport=%d, dport=%d, seq=%X, ack=%X, flags=%X, wndw=%d ",
      ntohs(seg->source_port), ntohs(seg->dest_port), ntohl(seg->seq), ntohl(seg->ack),
      ntohs(seg->flags), ntohs(seg->window)));
      
     
#if RTCSCFG_ENABLE_IP6     
   if(tcb->af == AF_INET6)
   { 
       /* Set pcb interface in according with scope_id
        * Scope_id was taken from 
        *   1) remoute scope_id(if not NULL), 
        *   2) local scope_id(if not NULL)
        */
        if(tcb->if_scope_id)
        {
            pcb->IFSRC = ip6_if_get_by_scope_id(tcb->if_scope_id);
        }
        else
        {   /* if scope_id was not setted let use local address interface */
            pcb->IFSRC = ip6_if_get_by_addr(&tcb->local_ipv6_host);
        }

        err = TCP6_Send_IP_packet(   pcb,                   /* packet to send */
                                    &tcb->local_ipv6_host,       /* local address */
                                    &tcb->remote_ipv6_host,      /* dest address */
                                    tcb->bypass_tx_chksum  /* bypass checksum? */
                                 );
   }
   else if( (tcb->af == AF_INET ) ||(tcb->af == AF_UNSPEC))
   {
#endif   
        err = TCP_Send_IP_packet(   pcb,                   /* packet to send */
                                    tcb->local_host,       /* local address */
                                    tcb->remote_host,      /* dest address */
                                    tcb->bypass_tx_chksum  /* bypass checksum? */
                                );
#if RTCSCFG_ENABLE_IP6 
   } 
#endif   

   
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_TOTAL++);
   if ( err != RTCS_OK ) {
      tcb->lasterror = err;
      TCP_Event(tcb, TCPS_SOFTERROR);
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_MISSED++);
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_DISCARDED++);
   } /* Endif */
   
   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Send_packet, 0);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP6_Send_reply_reset
* Returned Values : None.
* Comments        :
*
*  Send a RST segment as a reply to some erroneous/unwanted segment.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6

void TCP6_Send_reply_reset
   (
      /* Need access to TX options */
      TCB_STRUCT_PTR       tcb,        /* IN/OUT - TCP context */
      in6_addr             *source,    /* IN     - destination for reset */
      TCP_HEADER _PTR_     received,   /* IN     - received TCP packet */
      uint_16              rlen,       /* IN     - length of received packet */
      TCP_CFG_STRUCT_PTR   tcp_cfg,    /* IN/OUT - TCP layer constants */
      boolean              bypass_chk  /* IN     - TRUE to bypass checksum */
   )
{ /* Body */
   TCP_HEADER _PTR_  seg;
   RTCSPCB_PTR       pcb;
   uint_32           len;
   uint_16           port;

   pcb = RTCSPCB_alloc_send(); /* get the packet */
   if ( pcb == NULL ) {
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_MISSED++);
      RTCS_log_error( ERROR_TCP,
                           RTCSERR_TCP_SRR_OUT_OF_PCBS,
                           (uint_32)source,
                           (uint_32)received,
                           0 );
      return;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb);
   RTCSPCB_insert_header(pcb, sizeof(TCP_HEADER));
   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_TCP), 0);

   /*  Fill header...  no data, no complications, very short & sweet
    */
   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   RTCSPCB_DATA_TRANSPORT(pcb) = RTCSPCB_DATA(pcb);
   port = ntohs(received->dest_port);
   htons(seg->source_port, port);
   port = ntohs(received->source_port);
   htons(seg->dest_port, port);

   /*
   **  The following (found all over the RFC, where appropriate), is a way to
   **  make our ACK acceptable to the connection we are resetting:
   */
   if ( ntohs(received->flags) & ACK ) {
      len = ntohl(received->ack);
      htonl(seg->seq, len);
      htonl(seg->ack, 0);
      htons(seg->flags, RST | ( sizeof(TCP_HEADER) << (DATAOFS_SHIFT-2) ));
   } else {
      len = ntohl(received->seq) + rlen;
      htonl(seg->seq, 0);
      htonl(seg->ack, len);
      htons(seg->flags, RST | ACK | ( sizeof(TCP_HEADER) << (DATAOFS_SHIFT-2) ));
   } /* Endif */

   htons(seg->window,   0);
   htons(seg->checksum, 0);
   htons(seg->urgent,   0);

   if (tcb!=NULL) {
      pcb->LINK_OPTIONS.TX = tcb->TX;
   }
   
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_TOTAL++);
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
   TCP6_Send_IP_packet(
                        pcb,                                /* packet to send */
                        (in6_addr*)(&(in6addr_any)),        /* local address */
                        source,                             /* dest address */
                        bypass_chk                          /* bypass checksum? */
                      );

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP6 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Send_reply_reset
* Returned Values : None.
* Comments        :
*
*  Send a RST segment as a reply to some erroneous/unwanted segment.
*
*END*-----------------------------------------------------------------*/

void TCP_Send_reply_reset
   (
      /* Need access to TX options */
      TCB_STRUCT_PTR       tcb,        /* IN/OUT - TCP context */
      _ip_address          source,     /* IN     - destination for reset */
      TCP_HEADER _PTR_     received,   /* IN     - received TCP packet */
      uint_16              rlen,       /* IN     - length of received packet */
      TCP_CFG_STRUCT_PTR   tcp_cfg,    /* IN/OUT - TCP layer constants */
      boolean              bypass_chk  /* IN     - TRUE to bypass checksum */
   )
{ /* Body */
   TCP_HEADER _PTR_  seg;
   RTCSPCB_PTR       pcb;
   uint_32           len;
   uint_16           port;

   pcb = RTCSPCB_alloc_send(); /* get the packet */
   if ( pcb == NULL ) {
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_MISSED++);
      RTCS_log_error( ERROR_TCP,
                           RTCSERR_TCP_SRR_OUT_OF_PCBS,
                           (uint_32)source,
                           (uint_32)received,
                           0 );
      return;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb);
   RTCSPCB_insert_header(pcb, sizeof(TCP_HEADER));
   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_TCP), 0);

   /*  Fill header...  no data, no complications, very short & sweet
    */
   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   RTCSPCB_DATA_TRANSPORT(pcb) = RTCSPCB_DATA(pcb);
   port = ntohs(received->dest_port);
   htons(seg->source_port, port);
   port = ntohs(received->source_port);
   htons(seg->dest_port, port);

   /*
   **  The following (found all over the RFC, where appropriate), is a way to
   **  make our ACK acceptable to the connection we are resetting:
   */
   if ( ntohs(received->flags) & ACK ) {
      len = ntohl(received->ack);
      htonl(seg->seq, len);
      htonl(seg->ack, 0);
      htons(seg->flags, RST | ( sizeof(TCP_HEADER) << (DATAOFS_SHIFT-2) ));
   } else {
      len = ntohl(received->seq) + rlen;
      htonl(seg->seq, 0);
      htonl(seg->ack, len);
      htons(seg->flags, RST | ACK | ( sizeof(TCP_HEADER) << (DATAOFS_SHIFT-2) ));
   } /* Endif */

   htons(seg->window,   0);
   htons(seg->checksum, 0);
   htons(seg->urgent,   0);

   if (tcb!=NULL) {
      pcb->LINK_OPTIONS.TX = tcb->TX;
   }
   
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_TOTAL++);
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
   TCP_Send_IP_packet(pcb,             /* packet to send */
                      INADDR_ANY,      /* local address */
                      source,          /* dest address */
                      bypass_chk       /* bypass checksum? */
                     );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Send_reset
* Returned Values : None.
* Comments        :
*
*  Send an unsolicited reset (RST) segment.
*
*END*-----------------------------------------------------------------*/

void TCP_Send_reset
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer constants */
   )
{ /* Body */
   TCP_HEADER _PTR_  seg;
   RTCSPCB_PTR       pcb;
   uint_32           err;

   pcb = RTCSPCB_alloc_send(); /* get the packet */
   if ( pcb == NULL ) {
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_MISSED++);
      RTCS_log_error( ERROR_TCP,
                           RTCSERR_TCP_SR_OUT_OF_PCBS,
                           (uint_32)tcb,
                           0, 0 );
      return;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb);
   RTCSPCB_insert_header(pcb, sizeof(TCP_HEADER));
   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_TCP), 0);

   /*  Fill header...  even simpler than TCP_Send_reply_reset()...
    */
   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   RTCSPCB_DATA_TRANSPORT(pcb) = RTCSPCB_DATA(pcb);
   htons(seg->source_port, tcb->local_port);
   htons(seg->dest_port,   tcb->remote_port);
   htons(seg->flags,       RST | ( (sizeof(TCP_HEADER)>>2) << DATAOFS_SHIFT ));
   htonl(seg->seq,         tcb->sndnxt);
   htonl(seg->ack,         0);
   htons(seg->window,      0);
   htons(seg->checksum,    0);
   htons(seg->urgent,      0);

   /* Just get the TX option from the TCB, as it is always stored there now */
   pcb->LINK_OPTIONS.TX = tcb->TX;

   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_TX_RESET++);
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_TOTAL++);
   
   
   
  // err = TCP_Send_IP_packet(pcb,                   /* packet to send */
  //                          tcb->local_host,       /* local address */
  //                          tcb->remote_host,      /* dest address */
  //                          tcb->bypass_tx_chksum  /* bypass checksum? */
  //                         );
   
#if RTCSCFG_ENABLE_IP6     
   if(tcb->af == AF_INET6)
   { 
        err = TCP6_Send_IP_packet(   pcb,                   /* packet to send */
                                    &tcb->local_ipv6_host,       /* local address */
                                    &tcb->remote_ipv6_host,      /* dest address */
                                    tcb->bypass_tx_chksum  /* bypass checksum? */
                                 );
   }
   else if(tcb->af == AF_INET)
   {
#endif   
        err = TCP_Send_IP_packet(   pcb,                   /* packet to send */
                                    tcb->local_host,       /* local address */
                                    tcb->remote_host,      /* dest address */
                                    tcb->bypass_tx_chksum  /* bypass checksum? */
                                );
#if RTCSCFG_ENABLE_IP6 
   } 
#endif 
   
   
   if ( err != RTCS_OK ) {
      /* Note that the PCB would have already been freed */
      tcb->lasterror = err;
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_DISCARDED++);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Send_keepalive
* Returned Values : None.
* Comments        :
*     Send a keepalive probe.
*
*END*-----------------------------------------------------------------*/

void TCP_Send_keepalive
   (
      TCB_STRUCT_PTR       tcb,     /* IN - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN - TCP layer data */
   )
{ /* Body */

   int_32  result;

   tcb->keepalive = TRUE;
   TCP_Timer_oneshot_max(  &tcb->sndacktq.t, /* the timer */
                           tcb->keepaliveto, /* the timeout value */
                           tcp_cfg->qhead ); /* the timer queue head */

   if (!tcb->sndtohard) {

      TCP_Timer_stop(&tcb->sndtq.t, tcp_cfg->qhead);       /* ACK timeout */


      if ( tcb->sndto_2 != 0 ) {        /* start hard timeout... */
         result =
            TCP_Timer_start( &tcb->sndtq.t,/* the timer */
                        (tcb->sndto_2+tcb->sndto_1),     /* the timeout value */
                        0,                /* no reload */
                        tcp_cfg->qhead ); /* the timer queue head */
         if ( result != RTCS_OK ) {
            RTCS_log_error( ERROR_TCP, RTCSERR_TCP_TIMER_FAILURE,
               (uint_32)result, (uint_32)tcb, 1 );
         } /* Endif */
         tcb->sndtohard = TRUE;
      } /* Endif */

   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Transmit
* Returned Values : None.
* Comments        :
*
*  See if we can transmit anything, if so, transmit as much as we are
*   allowed.
*
*  The Send request will be returned to the upper layer
*   if the packet cannot be sent.  The PCB would also be freed.  If the
*   packet was passed to ENET, the Send request should be returned on
*   receipt of the ACK in TCP_Process_ack.
*
*  If `retransmit' is true, the (re)transmission pointer is reset to the
*   beginning of unacknowledged data in the send buffer, so that it will
*   get retransmitted (if we send any data);
*
*  Guarantees to send at least one packet if `force' is TRUE.
*
*END*-----------------------------------------------------------------*/

void TCP_Transmit
   (
      TCB_STRUCT_PTR       tcb,        /* IN/OUT - TCP layer context */
      TCP_CFG_STRUCT_PTR   tcp_cfg,    /* IN/OUT - TCP layer constants */
      boolean              retransmit, /* IN     - Should reset trans. ptr? */
      boolean              force       /* IN     - Guarantee send? */
   )
{ /* Body */
   uint_32  xmit;
   int_32   window,
            cansend,
            tosend;
   boolean  sent = FALSE, probe;
   int_32   result;
   
   RTCSLOG_FNE5(RTCSLOG_FN_TCP_Transmit, tcb, tcp_cfg, retransmit, force);

   switch ( tcb->state ) {   /* don't transmit in these states */
      case LISTEN:
      case CLOSED:
         RTCSLOG_FNX2(RTCSLOG_FN_TCP_Transmit, -1);
         return;

      default:
         break;
   } /* End Switch */

   probe = (tcb->sndwnd == 0        &&
            tcb->state != FINWAIT_1 &&
            tcb->state != FINWAIT_2 &&
            tcb->state != TIME_WAIT &&
            tcb->state != CLOSING   &&
            tcb->state != LAST_ACK);
   if (probe) {
      retransmit = TRUE;
   } /* Endif */

   /*  Where to start transmitting...
    */
   if ( retransmit || GT32(tcb->snduna, tcb->sndxmit) ) {
      tcb->sndxmit = tcb->snduna;
   } /* Endif */

   /*  Compute effective send window; note that tcb->sndcwnd >= tcb->sndwnd
    */
   window = tcb->sndcwnd;
   if ( window > tcb->sndwnd ) {
      window = tcb->sndwnd;
   } /* Endif */

   while (1) {

      xmit = tcb->sndxmit;

      /*
      ** Check if we should be sending data now.  Send if we have a full
      **    packet or if there is PUSHed data to send.  If not, break out
      **    of the loop.
      **
      ** Also check if we are waiting to send a FIN, in which case all
      **      the data must go when possible.
      */
      tosend = tcb->sndbufseq + tcb->sndlen - xmit;
      if ( tosend < tcb->sndmax               &&  /* not full packet AND */
         ((tcb->status & TCPS_TPUSH) == 0 ||      /* (not pushing OR     */
          LE32(tcb->sndpush, xmit))           &&  /*  pushed data already sent) AND */
         (tcb->status & TCPS_FINTOSEND) == 0)     /* not waiting to send FIN */
      {
        
         break;
      } /* Endif */


      /*
      ** Check to see if we should be probing.  Note that
      **    the same time queue is used in TIME_WAIT state,
      **    so ensure we don't start this xmit timer if
      **    we're in TIME_WAIT state (happens when ACK is
      **    sent for received FIN).
      */
      if (probe)
      {   /* probing */
         if ( tcb->sndxmitwhat != TCP_PROBE ) {

            tcb->sndxmitwhat = TCP_PROBE;
            tcb->sndprobeto = tcb->sndrto;
            result =
               TCP_Timer_start( &tcb->sndxmittq.t,   /* the timer */
                           tcb->sndprobeto,     /* the timeout value */
                           0,                   /* no reload */
                           tcp_cfg->qhead );    /* the timer queue head */
            if ( result != RTCS_OK ) {
               RTCS_log_error( ERROR_TCP,
                                    RTCSERR_TCP_TIMER_FAILURE,
                                    (uint_32)result,
                                    (uint_32)tcb,
                                    4 );
            } /* Endif */

            /* start user timeout timer */
            tcb->sndtohard = FALSE;
            result =
               TCP_Timer_start( &tcb->sndtq.t,       /* the timer */
                           tcb->sndto_1,        /* the timeout value */
                           0,                   /* no reload */
                           tcp_cfg->qhead );    /* the timer queue head */
            if ( result != RTCS_OK ) {
               RTCS_log_error( ERROR_TCP,
                                    RTCSERR_TCP_TIMER_FAILURE,
                                    (uint_32)result,
                                    (uint_32)tcb,
                                    5 );
            } /* Endif */

         } /* Endif */
         break;
      } /* Endif */
      
       if (tcb->sndlen <= 0) {                   /* nothing to send */
         break;
      } /* Endif */

      cansend = tcb->snduna + window - xmit;
      if ( cansend <= 0 ) { /* nothing to send */
         break;
      } /* Endif */

      if ( tosend < cansend ) {  /* can't send more than we have */
         cansend = tosend;
      } /* Endif */

      /*
      ** See RFC1122 4.2.3.4, Page 99
      */

      if ( cansend < tcb->sndmax ) {   /* not a full packet... */

         /*  If Nagle algorithm is in effect, only send less-than-full
          *   packet when there is no sent data outstanding:
          */
         if ( (tcb->options & TCPO_NONAGLE) == 0 &&
            tcb->sndnxt != tcb->snduna)
         {
            break;
         } /* Endif */

         /*
         ** If we can't send everything, nor send half the biggest send
         **   window we ever had, delay before sending; this
         **   is for sender SWS (Silly Window Syndrome) avoidance.
         */
         if ( tosend > cansend                &&
            cansend < (tcb->sndwndmax >> 1) &&
            ! force)
         {

            tcb->keepalive = FALSE;
            TCP_Timer_oneshot_max(  &tcb->sndacktq.t, /* the timer */
                              TCP_SWSDELAY,     /* the timeout */
                              tcp_cfg->qhead ); /* the timer queue head */
            sent = FALSE;   /* avoid stopping sndacktq */
            break;

         } /* Endif */

      } /* Endif */

      TCP_Send_packet(tcb, xmit, tcp_cfg);
      sent = TRUE;

      if ( tcb->sndxmit == xmit ) {
         break;
      } /* Endif */

   } /* Endwhile */

   /* Send a packet anyway if we must... */
   if ( force && ! sent ) {

      if ((tcb->sndlen == 0) && tcb->keepalive && (tcb->state == ESTABLISHED)) {
         /* decrement sequence number for keepalive probes */
         TCP_Send_packet(tcb, tcb->sndxmit-1, tcp_cfg);
      } else {
         TCP_Send_packet(tcb, tcb->sndxmit, tcp_cfg);
      } /* Endif */
      sent = TRUE;
   } /* Endif */

   if ( sent ) {

      /*  If packet sent, cancel sndacktq (no need to send ack, we sent it),
       *   or restart keepalive timeout if there is one...
       */
      (void)TCP_Timer_stop(&tcb->sndacktq.t, tcp_cfg->qhead);
      if ( tcb->keepaliveto != 0 ) {
         TCP_Send_keepalive(tcb, tcp_cfg);
      } /* Endif */

      /*  Also, if we are probing and a packet was sent, we can restart
       *   the probe timer...
       */
      if ( tcb->sndxmitwhat == TCP_PROBE &&
         tcb->state != TIME_WAIT)
      {
         result =
            TCP_Timer_start( &tcb->sndxmittq.t,   /* the timer */
                        tcb->sndprobeto,     /* the timeout value */
                        0,                   /* no reload */
                        tcp_cfg->qhead );    /* the timer queue head */
         if ( result != RTCS_OK ) {
            RTCS_log_error( ERROR_TCP,
                                 RTCSERR_TCP_TIMER_FAILURE,
                                 (uint_32)result,
                                 (uint_32)tcb,
                                 6 );
         } /* Endif */
      } /* Endif */

   } /* Endif */

   /* Now transmitting; if rto timer not started, start it */
   if ( tcb->sndnxt != tcb->snduna    &&
      tcb->sndxmitwhat != TCP_XMIT  &&
      tcb->state != TIME_WAIT)
   {

      tcb->sndxmitwhat = TCP_XMIT;
      result =
         TCP_Timer_start( &tcb->sndxmittq.t,   /* the timer */
                     tcb->sndrto,         /* the timeout value */
                     0,                   /* no reload */
                     tcp_cfg->qhead );    /* the timer queue head */
      if ( result != RTCS_OK ) {
         RTCS_log_error( ERROR_TCP,
                              RTCSERR_TCP_TIMER_FAILURE,
                              (uint_32)result,
                              (uint_32)tcb,
                              7 );
      } /* Endif */

      /* start user timeout timer */
      tcb->sndtohard = FALSE;
      result =
         TCP_Timer_start( &tcb->sndtq.t,       /* the timer */
                     tcb->sndto_1,        /* the timeout value */
                     0,                   /* no reload */
                     tcp_cfg->qhead );    /* the timer queue head */
      if ( result != RTCS_OK ) {
         RTCS_log_error( ERROR_TCP,
                              RTCSERR_TCP_TIMER_FAILURE,
                              (uint_32)result,
                              (uint_32)tcb,
                              8 );
      } /* Endif */

   } /* Endif */
   
   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Transmit, 0);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Start_sending
* Returned Values : None.
* Comments        :
*
*  Called when we start sending anything on a connection...
*
*END*-----------------------------------------------------------------*/

void TCP_Start_sending
   (
      TCB_STRUCT_PTR          tcb,     /* IN/OUT - TCP layer context */
      TCP_CFG_STRUCT_PTR      tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   uint_32 iss;

   /*  Select an ISN (Initial send Sequence Number)
   **
   ** RFC 1122, section 4.2.2.9 requires TCP to have an ISN bound to a
   ** 32-bit (pseudo-)clock which is incremented every 4 microseconds.
   **
   ** However, this makes TCP vulnerable to ISN-prediction attacks.
   ** Instead, we pick a random ISN.
   **
   */

   iss = RTCS_rand();

   tcb->sndringtail = 0;
   tcb->sndringhead = 0;
   tcb->sndringavail = tcb->sndringlen;

   tcb->sndiss    = iss;
   tcb->snduna    = iss;
   tcb->sndnxt    = iss + 1;
   tcb->sndxmit   = iss;
   tcb->sndbufseq = iss + 1;
   tcb->sndwl2    = iss;
   tcb->sndxmitwhat = TCP_IDLE;
   TCP_Transmit(tcb, tcp_cfg, FALSE, TRUE);    /* Send SYN segment... */

} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_send
* Returned Values : None.
* Comments        :
*
*  Process TcpSend() requests.
*
*END*-----------------------------------------------------------------*/
void TCP_Process_send
   (
      TCP_PARM_PTR      req      /* IN/OUT - upper layer Send request */
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;    /* TCP layer data */
   TCB_STRUCT_PTR       tcb;        /* TCP connection */
   SbufNode _PTR_       buf;
   boolean              block = FALSE; /* will client block? */
   uint_32              reply_buflen;
   int_32               result;
   uint_32              status;

   tcp_cfg = RTCS_getcfg(TCP);
   tcb = req->TCB_PTR;
   reply_buflen = 0;

   if ( tcb == NULL ) { 
      TCP_PS_REPLY(RTCSERR_TCP_CONN_RLSD); 
   } 

   /* if ( tcb->VALID != TCB_VALID_ID || tcb->usecount <= 0 ) { */
   if ( tcb->VALID != TCB_VALID_ID ) {
      TCP_PS_REPLY(RTCSERR_TCP_CONN_RLSD);
   } /* Endif */

   if ( (tcb->status & TCPS_FINTOSEND) != 0 ) {
      TCP_PS_REPLY(RTCSERR_TCP_CONN_CLOSING);
   } /* Endif */

   switch ( tcb->state ) {

      case LISTEN:
      case SYN_SENT:
      case SYN_RECEIVED:
      case ESTABLISHED:
      case CLOSE_WAIT:

         DEBUGTCP(printf("\nTCP: PrcSnd: sending, flags = %x, sndringavail = %d",req->OPTIONS,tcb->sndringavail));

         if ( (req->OPTIONS & (TCPO_WAIT | TCPO_NOWAIT)) ==
            (TCPO_WAIT | TCPO_NOWAIT))
         {
            TCP_PS_REPLY(RTCSERR_TCPIP_INVALID_ARGUMENT);
         } /* Endif */

         result = RTCS_OK;

         if ( req->BUFF_LENG != 0 )
         {
            /*  Send requester has 3 options:
             *   - block until all data sent & ack'ed (TCPO_WAIT)
             *   - buffer the data and return immediately, or
             *      block if buffer not large enough (until all data
             *      are buffered) (default)
             *   - buffer as much data as possible and return
             *      immediately without blocking (TCPO_NOWAIT)
             */
            
            /*  Block if no available buffer space:
             */
            if ( (req->OPTIONS & TCPO_WAIT) != 0 )
            {
               block = TRUE;
            }
            else
            { 
               /*  Just queue as much data as possible without blocking...
                */
                if ( req->BUFF_LENG > tcb->sndringavail )
                {
                    req->BUFF_LENG = tcb->sndringavail;
                    if ( req->BUFF_LENG == 0 )
                    {
                        goto emptysend;
                    } 
                    DEBUGTCP(printf("\nTCP: PrcSnd: sending only %d bytes",req->BUFF_LENG));
                } 
            } 

            /*  We now have unacknowledged data being sent
             */
            tcb->status &= ~TCPS_TACKED;

            if ( tcp_cfg->SbufNodefree != NULL )
            {
                buf = tcp_cfg->SbufNodefree;
                tcp_cfg->SbufNodefree = buf->next;
            } 
            else
            {
                buf = (SbufNode _PTR_)_mem_alloc_zero(sizeof(SbufNode));
            }

            if ( buf == NULL )
            {
                     RTCS_log_error( ERROR_TCP,
                                          RTCSERR_TCP_PS_FAILED_GET_SBUF,
                                          (uint_32)tcb,
                                          0, 0);
                     TCP_PS_REPLY(RTCSERR_OUT_OF_MEMORY); /* return */ 
            } 
            
            _mem_set_type(buf, MEM_TYPE_SbufNode);

            buf->next     = NULL;
                  
            if ( block ) 
            {
                buf->data      = req->BUFFER_PTR;
                buf->size      = req->BUFF_LENG;
                buf->req       = req;
                buf->use_cbuf  = TRUE;

                DEBUGTCP(printf("\nTCP: PrcSnd: [blocking] new node of size %d at %x.", buf->size, buf->data));                  
            }
            else
            {                    
                buf->data     = (uchar _PTR_) tcb->sndringhead;
                buf->size     = req->BUFF_LENG;
                buf->req      = NULL;
                buf->use_cbuf = FALSE;

                DEBUGTCP(printf("\nTCP: PrcSnd: [non-blk] new node of size %d at %x.", buf->size, buf->data));

                /*
                ** Copy client data to send buffer
                */
                status = TCP_Copy_to_ring( req->BUFFER_PTR,  /* source data buffer */
                                    req->BUFF_LENG,   /* data length */
                                    tcb->sndringhead, /* where in ring to put data */
                                    tcb->sndringbuf,  /* start of ring buffer */
                                    tcb->sndringlen );/* total length of ring buff */

                if ( status != RTCS_OK )
                {
                  TCP_PS_REPLY( status );
                }

                tcb->sndringhead = (tcb->sndringhead + req->BUFF_LENG) %
                                   tcb->sndringlen;

                tcb->sndringavail -= req->BUFF_LENG;
                if ( tcb->sndringavail == 0 )
                {
                    tcb->status &= ~TCPS_TREADY;
                    DEBUGTCP(printf("\nTCP: PrcSnd: sndringavail is 0."));
                }

                reply_buflen = req->BUFF_LENG;

            }  /* blocking or non-blocking */
            
            
            
            /*
            ** If new node, insert it into send buffer
            */
            if ( buf != NULL ) {
               if ( tcb->sndbuftail != NULL ) {
                  tcb->sndbuftail->next = buf;
               } else {
                  tcb->sndbuf = buf;
               } /* Endif */
               tcb->sndbuftail = buf;
            } /* Endif */

            tcb->sndlen += req->BUFF_LENG;

         } /* buff len NE 0 */

   emptysend:

         DEBUGTCP(printf("\nTCP: PrcSnd: at emptysend"));
         if ( (req->OPTIONS & TCPO_URGENT) != 0 ) {
            tcb->sndup = tcb->sndbufseq + tcb->sndlen;
            TCP_Event(tcb, TCPS_TURGENT);
         } /* Endif */

         if ( (req->OPTIONS & TCPO_PUSH) != 0 ) {
            tcb->sndpush = tcb->sndbufseq + tcb->sndlen;
            TCP_Event(tcb, TCPS_TPUSH);
         } /* Endif */

         TCP_Transmit(tcb, tcp_cfg, FALSE, FALSE); /* Returns request if error */

         /*
         ** NORMAL CASE RETURN
         */
         if ( block ) {
            return;
         } /* Endif */

         TCP_PS_REPLY(RTCS_OK);

      case FINWAIT_1:
      case FINWAIT_2:
      case CLOSING:
      case LAST_ACK:
      case TIME_WAIT:
         TCP_PS_REPLY(RTCSERR_TCP_SHUTDOWN);

      case CLOSED:
         TCP_PS_REPLY(RTCSERR_TCP_CONN_ABORTED);

      default:
         TCP_PS_REPLY(RTCSERR_TCP_NOT_CONN);

   } /* End Switch */

   /*
   ** TCP_PS_REPLY sends you here.
   */
   reply_send:

      /*
      ** Update number of bytes sent
      */
      req->BUFF_LENG = reply_buflen;
      RTCSCMD_complete(req, result);
      return;

}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_ack
* Returned Values : None.
* Comments        :
*
*  Process an ACK;
*   assumes that the given segment indeed contains a valid ACK,
*   and that seg->ack >= tcb->snduna
*
*END*-----------------------------------------------------------------*/

void TCP_Process_ack
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_HEADER _PTR_     seg,     /* IN     - packet header */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   SbufNode _PTR_ buf;
   SndClock _PTR_ clk;
   int_32         result;
   uint_32        ack;
   uint_32        curr_time;

   ack = ntohl(seg->ack);

   /* Return if no new data is acked */
   if ( ack == tcb->snduna ) {

      /* But if we are zero-window probing, restart send timeout */
      if ( tcb->sndwnd == 0 && tcb->sndlen > 0 ) {
         tcb->sndtohard = FALSE;
         result =
            TCP_Timer_start( &tcb->sndtq.t,       /* the timer */
                        tcb->sndto_1,        /* the timeout value */
                        0,                   /* no reload */
                        tcp_cfg->qhead );    /* the timer queue head */
         if ( result != RTCS_OK ) {
            RTCS_log_error( ERROR_TCP,
                                 RTCSERR_TCP_TIMER_FAILURE,
                                 (uint_32)result,
                                 (uint_32)tcb,
                                 9 );
         } /* Endif */

      /* If there is no data in transit, stop the hard timeout */
      } else if (tcb->sndnxt == tcb->snduna) {

         tcb->sndtohard = FALSE;
         TCP_Timer_stop(&tcb->sndtq.t, tcp_cfg->qhead);

      } /* Endif */
      return;

   } /* Endif */


   /*  Thing are getting through; positive advice to IP layer
   ** IP_Advise_delivery_problem( 1, tcb->icb, tcb->rem_host, tcb->tos );
   */

   /*  Update congestion window re: Jacobson slow-start/cong. avoidance
    */
   if ( tcb->sndcwnd < tcb->sndstresh ) {
      /*  slow-start: open window exponentially
       */
      tcb->sndcwnd += tcb->sndmax;

   } else {
      /*  congestion avoidance: open window linearly;
       */
      if (tcb->sndcwnd == 0) {
         tcb->sndcwnd =1;
      } else if (tcb->sndcwnd > 0xffff) {
         tcb->sndcwnd += ( tcb->sndmax * tcb->sndmax ) /  0xffff;
      } else { 
         tcb->sndcwnd += ( tcb->sndmax * tcb->sndmax ) /
                         (uint_16)tcb->sndcwnd;
      }
      
      /* Keep it within 16 bits */
      if ( tcb->sndcwnd > TCP_WINDOW_MAX ) {
         tcb->sndcwnd = TCP_WINDOW_MAX;
      } /* Endif */

   } /* Endif */

   /* Keep track of maximum for debugging */
   if ( tcb->sndcwnd > tcb->sndcwndmax ) {
      tcb->sndcwndmax = tcb->sndcwnd;
   } /* Endif */

   /*  New data is acked
    */
   tcb->snduna = ack;

   /*  Remove all send buffers thus acknowledged;
    *   return to client if necessary
    */
   buf = tcb->sndbuf;
   while ( buf != NULL &&
         (GE32(ack, tcb->sndbufseq + buf->size)))
   {

      tcb->sndbufseq += buf->size;
      tcb->sndlen    -= buf->size;
      tcb->sndbuf     = buf->next;
      if ( tcb->sndbuf == NULL ) {
         tcb->sndbuftail = NULL;
      } /* Endif */

      if ( buf->use_cbuf ) {

         /*
         ** Return to client, all its data was sent successfully
         */
         if ( buf->req != NULL ) {

            buf->req->BUFF_LENG  = buf->size;
            RTCSCMD_complete(buf->req, tcb->send_error);

            /*
            ** Clear the last global send error,
            */
            tcb->send_error = RTCS_OK;

         } /* Endif */

      } else {

         { /* Scope */
               register int_32   new_avail,
                              len_thresh;

            /*
            ** No client, so the data comes from the circular send buffer;
            **   return storage to buffer.
            **  Assuming buf->data EQ tcb->sndringbuf + tcb->sndringtail
            **   because storage is returned in the same order it was taken.
            */
            if ( (buf->size + tcb->sndringavail) > tcb->sndringlen ) {

               /*
               ** This should never happen. Try to recover by setting
               **    the entire buffer free.
               */
               buf->size = tcb->sndringlen - tcb->sndringavail;
               RTCS_log_error( ERROR_TCP,
                                    RTCSERR_TCP_PA_BUFF_CORRUPT,
                                    buf->size,
                                    tcb->sndringavail,
                                    (uint_32)tcb );

            } /* Endif */

            tcb->sndringtail = (tcb->sndringtail + buf->size) %
                                 tcb->sndringlen;
            new_avail  = tcb->sndringavail + buf->size;
            len_thresh = tcb->sndringlen >> 1;

            /*  If at least half of the send buffer becomes available,
             *   signal the client that it can send more data;
             *   the event is only triggered when a certain buffer-size
             *   threshold (half sndringlen) is crossed.
             */
            if ( tcb->sndringavail < len_thresh &&
               new_avail >= len_thresh
            ) {
               TCP_Event(tcb, TCPS_TREADY);
            } /* Endif */
            tcb->sndringavail = new_avail;

         } /* Endscope */

      } /* Endif */

      _mem_free(buf);

      if ( tcb->sndlen == 0 ) {
         /*
         ** Notify socket layer in case some task is blocked on select()
         ** waiting for this data.
         */
         _SOCK_select_signal(tcb->SOCKET, tcb->state, 1);
        
         TCP_Event(tcb, TCPS_TACKED);   /* all data to send got acked */
      } /* Endif */

      buf = tcb->sndbuf;

   } /* Endwhile */

   /*  Update pointers to things being sent, if they got ACKed
    */
   if ( (tcb->status & TCPS_TURGENT) && GE32(ack, tcb->sndup) ) {
      tcb->status &= ~TCPS_TURGENT;
   } /* Endif */

   if ( (tcb->status & TCPS_TPUSH) && GE32(ack, tcb->sndpush) ) {
      tcb->status &= ~TCPS_TPUSH;
   } /* Endif */

   /*  New data was acked, we may be able to do a round-trip-time measurement:
    */
   curr_time = RTCS_time_get();
   clk = TCP_Process_RTT_measure( tcb, (int_32)curr_time);

   /*  Adjust/restart xmittq and sndtq timers...
    */
   if ( GT32( tcb->sndnxt, tcb->snduna) ) {   /* data in transit remaining */

 

         int_32   to;

         /* restart send timeout */
         tcb->sndtohard = FALSE;
         result =
            TCP_Timer_start( &tcb->sndtq.t,       /* the timer */
                        tcb->sndto_1,        /* the timeout value */
                        0,                   /* no reload */
                        tcp_cfg->qhead );    /* the timer queue head */
         if ( result != RTCS_OK ) {
            RTCS_log_error( ERROR_TCP,
                                 RTCSERR_TCP_TIMER_FAILURE,
                                 (uint_32)result,
                                 (uint_32)tcb,
                                 10 );
         } 

         /*  Advance retransmission timeout, as if it had been started
          *   when earliest unacked packet was sent; if no transmission time
          *   is available for any previously sent (unacked) packet, just
          *   restart the rto as if we had just transmitted a packet...
          */
         to = tcb->sndrto;
         if ( clk != NULL ) {
            to += clk->time - (int_32)curr_time;
            if ( to <= 0 ) {
               to = TICK_LENGTH;          /* minimum timeout */
            } /* Endif */
         } /* Endif */
         result =
            TCP_Timer_start( &tcb->sndxmittq.t,   /* the timer */
                        to,                  /* the timeout value */
                        0,                   /* no reload */
                        tcp_cfg->qhead );    /* the timer queue head */
         if ( result != RTCS_OK ) {
            RTCS_log_error( ERROR_TCP,
                                 RTCSERR_TCP_TIMER_FAILURE,
                                 (uint_32)result,
                                 (uint_32)tcb,
                                 11 );
         }



   } else {  /* no more data in transit */

      tcb->sndtohard = FALSE;
      (void)TCP_Timer_stop(&tcb->sndtq.t, tcp_cfg->qhead);       /* ACK timeout */

      (void)TCP_Timer_stop(&tcb->sndxmittq.t, tcp_cfg->qhead);   /* Rexmt timeout */
      tcb->sndxmitwhat = TCP_IDLE;

   } /* Endif */

   /*  There may be more data to transmit;
    *   also, windows may have increased, we may be able to transmit more data;
    *   so transmit what we can...
    */
   TCP_Transmit(tcb, tcp_cfg, FALSE, (tcb->sndbufseq + tcb->sndlen - tcb->sndxmit) > 0);


}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/serl_linflexd.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_linflexd.h$
* $Version : 3.8.3.0$
* $Date    : Oct-5-2011$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the linflexd drivers for the px56xx
*
*END************************************************************************/

#ifndef _serial_linflexd_h_
#define _serial_linflexd_h_

#ifdef __cplusplus
extern "C" {
#endif


#define LINFLEXD_BUFFER_MODE    0
#define LINFLEXD_FIFO_MODE      0x80000000 /* used as CONTROL_BITS flag */

#define LINFLEXD_NUM_VECTORS 3
#define LINFLEXD_RX_VECTOR_INDEX 0
#define LINFLEXD_TX_VECTOR_INDEX 1
#define LINFLEXD_ERR_VECTOR_INDEX 2


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** LINFLEXD_SERIAL_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a serial port is initialized.
*/
typedef struct linflexd_serial_init_struct
{
    // The device to initialize
    uint_32     DEVICE;

    // The serial I/O queue size to use to buffer Rx/Tx data.
    _mqx_uint   QUEUE_SIZE;

    // The input clock speed
    uint_32     CLOCK_SPEED;

    // The baud rate for the channel
    uint_32     BAUD_RATE;

    // The number of bits in a character
    _mqx_uint   BITS_PER_CHARACTER;

    // The parity to initialize the channel to
    _mqx_uint   PARITY;

    // The number of stop bits
    _mqx_uint   STOP_BITS;

    // Interrupt priority */
    uint_32    PRIORITY;
} LINFLEXD_SERIAL_INIT_STRUCT, _PTR_ LINFLEXD_SERIAL_INIT_STRUCT_PTR;

typedef const LINFLEXD_SERIAL_INIT_STRUCT _PTR_ LINFLEXD_SERIAL_INIT_STRUCT_CPTR;


/*
** LINFLEXD_STATS_STRUCT
** Run time state information for each serial channel
*/
typedef struct linflexd_serial_stats_struct {
    /* Statistical information */
    uint_32                        INTERRUPTS;
    uint_32                        RX_DROPPED_INPUT;
    uint_32                        RX_GOOD_CHARS;
    uint_32                        RX_CHARS;
    uint_32                        TX_CHARS;
    uint_32                        RX_PARITY_ERRORS;
    uint_32                        RX_FRAMING_ERRORS;
    uint_32                        RX_OVERRUNS;
    uint_32                        RX_BREAKS;
    uint_32                        RX_NOISE_ERRORS;
} LINFLEXD_STATS_STRUCT, _PTR_ LINFLEXD_STATS_STRUCT_PTR;


/*
** LINFLEXD_INFO_STRUCT
** Run time state information for each serial channel
*/
typedef struct linflexd_serial_info_struct
{
    /* The current init values for this port */
    LINFLEXD_SERIAL_INIT_STRUCT    INIT;

    /* The device registers */
    VLINFLEXD_REG_STRUCT_PTR       LINFLEXD_PTR;

    /* Internal driver interrupt state */
    uint_32                        NUM_VECTORS;
    const uint_32 _PTR_            VECTORS;
    /* The previous interrupt handler and data */
    void               (_CODE_PTR_ OLD_ISR[LINFLEXD_NUM_VECTORS])(pointer);
    pointer                        OLD_ISR_DATA[LINFLEXD_NUM_VECTORS];

    uint_32                        CONTROL_BITS;

    /* Statistical information */
    LINFLEXD_STATS_STRUCT          STATS;
} LINFLEXD_SERIAL_INFO_STRUCT, _PTR_ LINFLEXD_SERIAL_INFO_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

/* Polled driver functions */
extern uint_32 _linflexd_serial_polled_install(char_ptr, LINFLEXD_SERIAL_INIT_STRUCT_CPTR);

/* Polled driver functions */
extern uint_32 _linflexd_serial_int_install(char_ptr, LINFLEXD_SERIAL_INIT_STRUCT_CPTR);

extern VLINFLEXD_REG_STRUCT_PTR _bsp_get_linflexd_base_address(uint_32 channel);
extern boolean _bsp_linflexd_enable_access(uint_32 device);
extern uint_32 _bsp_get_linflexd_vectors(uint_32 device, const uint_32 _PTR_ _PTR_ vectors_ptr);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/msd/usb_msc_scsi.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_msc_scsi.c$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
* @brief The file contains USB Mass Storage SCSI command set.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_stack_config.h"

#if MSD_CONFIG 
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "usb_msc.h"
#include "usb_msc_scsi.h"

/*****************************************************************************
* Constant and Macro's
*****************************************************************************/
INQUIRY_DATA_STRUCT inquiry_info = /* constant */
{
   (PERIPHERAL_QUALIFIER << PERIPHERAL_QUALIFIER_SHIFT)|PERIPHERAL_DEVICE_TYPE,
   (uint_8)REMOVABLE_MEDIUM_BIT << REMOVABLE_MEDIUM_BIT_SHIFT,
   SPC_VERSION, 0x02, ADDITIONAL_LENGTH, 0x00,0x00,0x00,
   {'F', 'S', 'L', ' ', 'S', 'E', 'M', 'I'},
   {'F','S','L',' ','M','A','S','S',' ','S','T','O','R','A','G','E'},
   {'0', '0', '0', '1'}
};

/*****************************************************************************
 * Global Functions Prototypes
 *****************************************************************************/
/****************************************************************************
 * Global Variables
 ****************************************************************************/
/* Add all the variables needed for usb_msc.c to this structure */
/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
 uint_8 msc_thirteen_cases_check(MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,PTR_MSC_THIRTEEN_CASE_STRUCT msc_check_event);
/*****************************************************************************
 * Local Variables
 *****************************************************************************/

 /*****************************************************************************
 * Local Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  msc_thirteen_cases_check
 *
 * @brief The funtion checks for thirteen error case of MSC and takes action 
 *        appropriately
 *
 * @param scsi_ptr->thirteen_case_ptr: structure containing all necesaary parameter to 
 *        evalute error scenarios
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_thirteen_cases_check(MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
PTR_MSC_THIRTEEN_CASE_STRUCT msc_check_event
)
{
    uint_8 error;
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    if(!msc_check_event->host_expected_data_len)
    {   /* host expects no data transfer */
        *(msc_check_event->csw_residue_ptr) = 0;
        
        if(!msc_check_event->device_expected_data_len)
        {   /* CASE 1: Device intends no data transfer : Thin Diagonal Case*/
            *(msc_check_event->csw_status_ptr) = COMMAND_PASSED;
        }
        else 
        {   /* if(msc_check_event->device_expected_direction) :
                CASE 2: Device intends to send data to host
               else
                CASE 3: Device intends to receive data from host */        
            *(msc_check_event->csw_status_ptr) = PHASE_ERROR;
        }       
    }
    else if(msc_check_event->host_expected_direction)
    {   /* host expects to receive data from device (USB_SEND direction)*/
        if(!msc_check_event->device_expected_data_len)
        {   /* CASE 4:  Device intends no data transfer */
            *(msc_check_event->csw_residue_ptr) = 
                msc_check_event->host_expected_data_len - 
                msc_check_event->device_expected_data_len;
            /* sending zero bytes of data */
            error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle,
                msc_check_event->buffer_ptr,
                msc_check_event->device_expected_data_len); 
            
            if(error == USB_OK)
            {
                *(msc_check_event->csw_status_ptr) = COMMAND_PASSED;    
            }
            else
            {
                *(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
                scsi_ptr->request_sense.sense_key = MEDIUM_ERROR;
                scsi_ptr->request_sense.add_sense_code = UNRECOVERED_READ_ERROR;
            }
            
            /* BULK IN PIPE TO BE STALLED for status phase */
            error = USBERR_ENDPOINT_STALLED;    
        }
        else if(msc_check_event->device_expected_direction)
        {   /* device intends to send data to host */
            if(msc_check_event->host_expected_data_len > 
                msc_check_event->device_expected_data_len)
            {   /* CASE 5: Host intends more data to receive than device 
                           intends to send*/
                *(msc_check_event->csw_residue_ptr) = 
                msc_check_event->host_expected_data_len - 
                msc_check_event->device_expected_data_len;
                
                if(scsi_ptr->thirteen_case_ptr->lba_txrx_select == TRUE)    
                {
                    error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_SEND,
                        &msc_check_event->lba_info);
                }
                else
                {
                    error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle,
                        msc_check_event->buffer_ptr,
                        msc_check_event->device_expected_data_len); 
                }

                if(msc_check_event->device_expected_data_len%
                    msc_obj_ptr->bulk_in_endpoint_packet_size == 0)
                {   /* need to send zero bytes of data to tell host that device
                       does not have any more data. This is needed only if the 
                       bytes send to host are integral multiple of max packet 
                       size of Bulk In endpoint */
                    error |= USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle,
                        msc_check_event->buffer_ptr,0);                                 
                }
                
                if(error == USB_OK)
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_PASSED;    
                }
                else
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
                    scsi_ptr->request_sense.sense_key = MEDIUM_ERROR;
                    scsi_ptr->request_sense.add_sense_code = UNRECOVERED_READ_ERROR;
                }
            }
            else if(msc_check_event->host_expected_data_len == 
                msc_check_event->device_expected_data_len)
            {   /* CASE 6: Host intends exact amount of data to receive 
                           as device intends to send : Thin Diagonal Case*/
                *(msc_check_event->csw_residue_ptr) = 0;
                
                if(scsi_ptr->thirteen_case_ptr->lba_txrx_select == TRUE)    
                {
                    error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_SEND,
                        &msc_check_event->lba_info);
                }
                else
                {
                    error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle,
                        msc_check_event->buffer_ptr,
                        msc_check_event->device_expected_data_len);                     
                }

                if(error == USB_OK)
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_PASSED;    
                }
                else
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
                    scsi_ptr->request_sense.sense_key = MEDIUM_ERROR;
                    scsi_ptr->request_sense.add_sense_code = UNRECOVERED_READ_ERROR;
                }
            }
            else
            {
                /* CASE 7: Host intends less data to receive than device 
                           intends to send*/
                *(msc_check_event->csw_residue_ptr) = 0;
                
                if(scsi_ptr->thirteen_case_ptr->lba_txrx_select == TRUE)    
                {
                    error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_SEND,
                        &msc_check_event->lba_info);
                }
                else
                {
                    error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle,
                        msc_check_event->buffer_ptr,
                        msc_check_event->host_expected_data_len);                   
                }

                if(error == USB_OK)
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_PASSED;    
                }
                else
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
                    scsi_ptr->request_sense.sense_key = MEDIUM_ERROR;
                    scsi_ptr->request_sense.add_sense_code = UNRECOVERED_READ_ERROR;
                }
            }                               
        }
        else
        {   /* CASE 8: Device intends to receive data from host */
            *(msc_check_event->csw_residue_ptr) = 
                msc_check_event->host_expected_data_len;
            /* device has no data to send */
            error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle,
                msc_check_event->buffer_ptr,0);
            *(msc_check_event->csw_status_ptr) = PHASE_ERROR;
            /* BULK IN PIPE TO BE STALLED for status phase */
            error = USBERR_ENDPOINT_STALLED;                                                                               
        }
    }
    else
    {   /* host expects to send data to device (USB_RECV direction)*/
        if(!msc_check_event->device_expected_data_len)
        {   /* CASE 9:  Device intends no data transfer */
            uint_8 component = (uint_8)(msc_obj_ptr->bulk_out_endpoint | 
                (USB_RECV<<COMPONENT_PREPARE_SHIFT));           
            (void)_usb_device_set_status(msc_obj_ptr->controller_handle,
                (uint_8)(component|USB_STATUS_ENDPOINT),
                (uint_16)USB_STATUS_STALLED);
            *(msc_check_event->csw_residue_ptr) = 
                msc_check_event->host_expected_data_len;
            *(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
            /* BULK OUT PIPE STALLED */
            error = USBERR_ENDPOINT_STALLED;                    
        }
        else if(msc_check_event->device_expected_direction)
        {   /*CASE10: device intends to send data to host */        
            uint_8 component = (uint_8)(msc_obj_ptr->bulk_out_endpoint | 
                (uint_8)(USB_RECV<<COMPONENT_PREPARE_SHIFT));
            /* now, stalling the status phase - CASE 5th of THIRTEEN CASES*/           
            (void)_usb_device_set_status(msc_obj_ptr->controller_handle,
                (uint_8)(component|USB_STATUS_ENDPOINT),
                (uint_16)USB_STATUS_STALLED);
            *(msc_check_event->csw_residue_ptr) = 
                msc_check_event->host_expected_data_len;
            *(msc_check_event->csw_status_ptr) = PHASE_ERROR;
            /* BULK OUT PIPE STALLED */
            error = USBERR_ENDPOINT_STALLED;
        }
        else
        {   /*Device intends to receive data from host */
            if(msc_check_event->host_expected_data_len > 
                msc_check_event->device_expected_data_len)
            {   /* CASE 11: Host intends more data to send than device 
                            intends to receive*/
                *(msc_check_event->csw_residue_ptr) = 
                    msc_check_event->host_expected_data_len - 
                    msc_check_event->device_expected_data_len;

                if(scsi_ptr->thirteen_case_ptr->lba_txrx_select == TRUE)    
                {
                    error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_RECV,
                        &msc_check_event->lba_info);
                }
                else
                {
                    error = USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle,
                        msc_check_event->buffer_ptr,
                        msc_check_event->device_expected_data_len);                                     
                }               

                if(error == USB_OK)
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_PASSED;    
                }
                else
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
                    scsi_ptr->request_sense.sense_key = MEDIUM_ERROR;
                    scsi_ptr->request_sense.add_sense_code = WRITE_FAULT;
                }
                /* BULK OUT PIPE TO BE STALLED for status phase */
                error = USBERR_ENDPOINT_STALLED;                    
            }
            else if(msc_check_event->host_expected_data_len == 
                msc_check_event->device_expected_data_len)
            {   /* CASE 12: Host intends exact amount of data to send 
                            as device intends to receive : Thin Diagonal Case*/
                *(msc_check_event->csw_residue_ptr) = 0;                
                
                if(scsi_ptr->thirteen_case_ptr->lba_txrx_select == TRUE)    
                {
                    error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_RECV,
                        &msc_check_event->lba_info);
                }
                else
                {
                    error = USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle,
                        msc_check_event->buffer_ptr,
                        msc_check_event->device_expected_data_len); 
                }

                if(error == USB_OK)
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_PASSED;    
                }
                else
                {
                    *(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
                    scsi_ptr->request_sense.sense_key = MEDIUM_ERROR;
                    scsi_ptr->request_sense.add_sense_code = WRITE_FAULT;
                }
            }
            else
            {
                /* CASE 13: Host intends less data to send than device 
                            intends to receive*/
                *(msc_check_event->csw_residue_ptr) = 0;

                if(scsi_ptr->thirteen_case_ptr->lba_txrx_select == TRUE)    
                {
                    msc_check_event->lba_info.lba_transfer_num = 
                      msc_check_event->host_expected_data_len / 
                        scsi_ptr->length_of_each_lab;   
                    error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_RECV,
                        &msc_check_event->lba_info);
                }
                else
                {
                    error = USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle,
                        msc_check_event->buffer_ptr,
                        msc_check_event->host_expected_data_len);
                }

                if(error != USB_OK)
                {
                    scsi_ptr->request_sense.sense_key = MEDIUM_ERROR;
                    scsi_ptr->request_sense.add_sense_code = WRITE_FAULT;
                }
                *(msc_check_event->csw_status_ptr) = PHASE_ERROR;                           
            }                               
        }       
    }
    return error;
}

/*****************************************************************************
 * Global Functions
 *****************************************************************************/

 /**************************************************************************//*!
 *
 * @name  USB_MSC_SCSI_Init
 *
 * @brief The funtion initializes the SCSI parameters and callbacks
 *
 * @param msc_obj_ptr         MSD class object pointer.
 * @param cb:                 event callback
 * @param device_info_ptr   : Contains MSD device info like number of LBA, etc
 * @return status
 *         USB_OK           : When Successfull
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_MSC_SCSI_Init
(
     MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
     USB_CLASS_CALLBACK_STRUCT_PTR cb,
     PTR_DEVICE_LBA_INFO_STRUCT device_info_ptr,     
     uint_32 implementing_disk_drive     
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr = NULL;
    /* initialize the Global Variable Structure */
    scsi_ptr  = (MSC_SCSI_STRUCT_PTR)USB_mem_alloc_zero(sizeof(MSC_SCSI_STRUCT));
    if (NULL == scsi_ptr)
    {
        #if _DEBUG
            printf("1: USB_MSC_SCSI_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }
      
    /* save input parameters */
    scsi_ptr->scsi_callback.callback = cb->callback;
    scsi_ptr->scsi_callback.arg = cb->arg;
    scsi_ptr->total_logical_add_block = 
        device_info_ptr->total_lba_device_supports;
    scsi_ptr->length_of_each_lab = 
        device_info_ptr->length_of_each_lab_of_device;
    scsi_ptr->implementing_disk_drive = implementing_disk_drive;
    
    /* no need to initialize other structure fields as g_resquest_sense has
       been declared as static */
    scsi_ptr->request_sense.valid_error_code = REQ_SENSE_VALID_ERROR_CODE;
    scsi_ptr->request_sense.add_sense_len = REQ_SENSE_ADDITIONAL_SENSE_LEN;
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;
    scsi_ptr->thirteen_case_ptr = NULL; /* Initialize */
    
    scsi_ptr->thirteen_case_ptr = (PTR_MSC_THIRTEEN_CASE_STRUCT)USB_mem_alloc_zero(
        sizeof(MSC_THIRTEEN_CASE_STRUCT));
    if (NULL == scsi_ptr->thirteen_case_ptr)
    {
        #if _DEBUG
            printf("2: USB_MSC_SCSI_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }
        
    msc_obj_ptr->scsi_object_ptr = scsi_ptr;
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  msc_request_sense_command
 *
 * @brief command instructs the Device to transfer sense data to host computer
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return NONE
 *
 *****************************************************************************/
uint_8 msc_request_sense_command 
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    uint_8 error; 
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
       
    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = REQ_SENSE_DATA_LENGTH;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = (uint_8_ptr)&scsi_ptr->request_sense;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr, scsi_ptr->thirteen_case_ptr);
    
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_inquiry_command
 *
 * @brief It requests that information regarding parameters of the Device be
 *        sent to the Host Computer
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_inquiry_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_8 error = USBERR_TX_FAILED;
    PTR_INQUIRY_COMMAND_STRUCT inquiry_cmd_ptr =
        (PTR_INQUIRY_COMMAND_STRUCT)(cbw_ptr->command_block);
        
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;
    
    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = INQUIRY_ALLOCATION_LENGTH;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = (uint_8_ptr)&inquiry_info;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);
    
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_read_command
 *
 * @brief command requests that device transfer data to the host computer
 *        (read (10) command)
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_read_command 
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_32 lba = 0;
    uint_32 num_lba_tx = 0;
    uint_8 error = USBERR_TX_FAILED;

    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;
    
    lba  = ((uint_32)cbw_ptr->command_block[2] << 24);
    lba |= ((uint_32)cbw_ptr->command_block[3] << 16);
    lba |= ((uint_32)cbw_ptr->command_block[4] << 8);
    lba |= ((uint_32)cbw_ptr->command_block[5]);

    if(cbw_ptr->command_block[0] == READ_10_COMMAND)
    {
        num_lba_tx = (uint_16)((uint_16)cbw_ptr->command_block[7] << 8);
        num_lba_tx |= (uint_16)cbw_ptr->command_block[8];
    }
    else if(cbw_ptr->command_block[0] == READ_12_COMMAND)
    {
        num_lba_tx  = ((uint_32)cbw_ptr->command_block[6] << 24);
        num_lba_tx |= ((uint_32)cbw_ptr->command_block[7] << 16);
        num_lba_tx |= ((uint_32)cbw_ptr->command_block[8] << 8);
        num_lba_tx |= ((uint_32)cbw_ptr->command_block[9]);
    }
    
    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;    

    scsi_ptr->thirteen_case_ptr->device_expected_data_len = 
        scsi_ptr->length_of_each_lab * num_lba_tx;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = NULL;

    scsi_ptr->thirteen_case_ptr->lba_txrx_select = TRUE;
    scsi_ptr->thirteen_case_ptr->lba_info.starting_lba = lba;
    scsi_ptr->thirteen_case_ptr->lba_info.lba_transfer_num = num_lba_tx;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_write_command
 *
 * @brief command requests that the Device write the data transferred by the
 *        Host Computer to the medium.
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_write_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_32 lba = 0;
    uint_32 num_lba_rx = 0;
    uint_8 error = USBERR_RX_FAILED;

    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    lba  = ((uint_32)cbw_ptr->command_block[2] << 24);
    lba |= ((uint_32)cbw_ptr->command_block[3] << 16);
    lba |= ((uint_32)cbw_ptr->command_block[4] << 8);
    lba |= ((uint_32)cbw_ptr->command_block[5]);


    if(cbw_ptr->command_block[0] == WRITE_10_COMMAND)
    {
        num_lba_rx = (uint_16)((uint_16)cbw_ptr->command_block[7] << 8);
        num_lba_rx |= (uint_16)cbw_ptr->command_block[8];
    }
    else if(cbw_ptr->command_block[0] == WRITE_12_COMMAND)
    {
        num_lba_rx  = ((uint_32)cbw_ptr->command_block[6] << 24);
        num_lba_rx |= ((uint_32)cbw_ptr->command_block[7] << 16);
        num_lba_rx |= ((uint_32)cbw_ptr->command_block[8] << 8);
        num_lba_rx |= ((uint_32)cbw_ptr->command_block[9]);
    }
        
    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;    
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_RECV;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;

    scsi_ptr->thirteen_case_ptr->buffer_ptr = NULL;

    if(_usb_device_get_transfer_status(msc_obj_ptr->controller_handle,
        BULK_OUT_ENDPOINT, USB_RECV) != USB_STATUS_IDLE)
    {
        (void)_usb_device_cancel_transfer(msc_obj_ptr->controller_handle,BULK_OUT_ENDPOINT,
            USB_RECV);
    }
    
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = 
        scsi_ptr->length_of_each_lab * num_lba_rx;
    
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = TRUE;
    scsi_ptr->thirteen_case_ptr->lba_info.starting_lba = lba;
    scsi_ptr->thirteen_case_ptr->lba_info.lba_transfer_num = num_lba_rx;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);
    
    return error;    
}

/**************************************************************************//*!
 *
 * @name  msc_test_unit_ready_command
 *
 * @brief It provides a means to check if the device is ready
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_test_unit_ready_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_8 error;
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;    
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = 0;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = NULL;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);
                                                                          
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_verify_command
 *
 * @brief requests that device verifies the data on medium
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_verify_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_8 error;
    /* Our Device has no mechanism to verify the blocks, 
       so just returning success status to host*/
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;    
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = 0;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = NULL;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;

    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);
                                                                          
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_mode_sense_command
 *
 * @brief command provides a means for a Device to report parameters to Host
 *        Computer.It is a complementary command to the MODE SELECT command.
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_mode_sense_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_8 error = USBERR_TX_FAILED;
    
    MODE_PARAMETER_HEADER_STRUCT mode_param_header =
    {
      0x0000,/*no followng data available because of reason given below*/
      0x00,/* 0x00 indicates current/default medium */
      0x00,/* for write_protect and DPOFUA - no write protection available*/
      0x00,0x00,0x00,0x00 /* reserved bytes are always to be set to zero */
    };
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    /* irrespective of DBD(Disable block descriptor) bit in Command Block
       Wrapper we are not returning any block descriptors in the returned mode
       sense data.Presently, we are just returning Mode Parameter Header */

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = sizeof(mode_param_header);
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = (uint_8_ptr)&mode_param_header;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);

    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_mode_select_command
 *
 * @brief command provides a means for a Device to report parameters to Host
 *        Computer.It is a complementary command to the MODE SENSE command.
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_mode_select_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_8 error = USBERR_TX_FAILED;
    
    
    
    MODE_PARAMETER_HEADER_STRUCT mode_param_header =
    {
      0x0000,/*mode data length for mode select command is always zero*/
      0x00,/* 0x00 indicates current/default medium */
      0x00,/* for write_protect and DPOFUA*/
      0x00,0x00,0x00,0x00 /* reserved bytes are always to be set to zero */
    };

    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
                                      
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = sizeof(mode_param_header);
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = (uint_8_ptr)&mode_param_header;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);
   
    if(cbw_ptr->command_block[1] & 0x01)/* checking Save Pages Bit in command*/
    {
        scsi_ptr->request_sense.sense_key = ILLEGAL_REQUEST;
        scsi_ptr->request_sense.add_sense_code = INVALID_FIELD_IN_COMMAND_PKT;
        /*logical unit does not implement save mode pages in our case*/
    }
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_read_capacity_command
 *
 * @brief command provides a means for the host computer to request information
 *        regarding the capacity of the installed medium of the device.
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_read_capacity_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    READ_CAPACITY_DATA_STRUCT read_capacity;
    uint_8 error = USBERR_TX_FAILED;

    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    read_capacity.last_logical_block_address = LONG_BE_TO_HOST(scsi_ptr->total_logical_add_block -1);
    read_capacity.block_size = LONG_BE_TO_HOST((uint_32) scsi_ptr->length_of_each_lab);

    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
                                      
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = READ_CAPACITY_DATA_LENGTH;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = (uint_8_ptr)&read_capacity;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);

    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_read_format_capacity_command
 *
 * @brief allows the host to request a list of the possible capacities that
 *        can be formatted on the currently installed medium
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_read_format_capacity_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr ;
    uint_8 num_formattable_cap_desc ;
    uint_16 allocation_length;
    /* pointer to data to be sent in data phase for this command*/
    uint_8_ptr response_data_ptr = NULL;
     /* size of data to be sent in data phase for this command*/
    uint_32 response_size;
    /* general variable for counting in loop */
    uint_8 i; 
    CURR_MAX_CAPACITY_DESC_STRUCT curr_max_cap_header;
    uint_8 desc_code;
    FORMATTABLE_CAP_DESC formattable_cap_descriptor;
    CAPACITY_LIST_HEADER_STRUCT capacity_list_header= {0x00,0x00,0x00,0x00};
    uint_8 error = USBERR_TX_FAILED;
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    allocation_length = (uint_16)((cbw_ptr->command_block[7] << 8) |
        cbw_ptr->command_block[8]);
    
    num_formattable_cap_desc = (uint_8)(scsi_ptr->formatted_disk ?
        (scsi_ptr->implementing_disk_drive?0x02:0x03):0x00);
    /*
     * gives the number of Formattable Capacity Descriptor to be sent by device
     * in response to read format capacities command
     */
     
     /* 
      * 0x03 is number of formattable capcity desc for HD while for DD its 2 if
      * formatted drive is there
      */

    formattable_cap_descriptor.num_blocks = scsi_ptr->total_logical_add_block;
    formattable_cap_descriptor.block_len = scsi_ptr->length_of_each_lab;
    //{scsi_ptr->total_logical_add_block,scsi_ptr->length_of_each_lab};

    desc_code = (uint_8)(scsi_ptr->formatted_disk?FORMATTED_MEDIA:UNFORMATTED_MEDIA);
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;
                                      
    capacity_list_header.capacity_list_len = (uint_8)(num_formattable_cap_desc * 8);
    curr_max_cap_header.num_blocks = scsi_ptr->total_logical_add_block;
    curr_max_cap_header.desc_code_and_block_len = (desc_code << 24)|
                                                          scsi_ptr->length_of_each_lab;
    response_size = sizeof(capacity_list_header) + sizeof(curr_max_cap_header)+
        sizeof(formattable_cap_descriptor) * num_formattable_cap_desc;

    if(response_size > allocation_length)
    {   /* comapring the length of data available with allocation length value
          sent in CBW which indicates the length of buffer host has reserved
          for data phase of this command */
        response_size = allocation_length;
    }

    /* reserving memory for response data */
    response_data_ptr = (uint_8_ptr)USB_mem_alloc_uncached(response_size);
    if (NULL == response_data_ptr)
    {
        #if _DEBUG
            printf("msc_read_format_capacity_command: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }
    _mem_zero(response_data_ptr, response_size);
    
    USB_mem_copy(&capacity_list_header, response_data_ptr,
        sizeof(capacity_list_header));
    USB_mem_copy(&curr_max_cap_header, response_data_ptr +
        sizeof(capacity_list_header),sizeof(curr_max_cap_header));

    if(scsi_ptr->formatted_disk)
    {
        for(i = 0; i < num_formattable_cap_desc; i++)
        {
            USB_mem_copy(&formattable_cap_descriptor, response_data_ptr +
                sizeof(capacity_list_header) + sizeof(curr_max_cap_header)+
                sizeof(formattable_cap_descriptor) * i,
                sizeof(formattable_cap_descriptor));
        }
    }
    
    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = response_size;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = response_data_ptr;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);

    /* free the reserved memory */
    if(response_data_ptr != NULL)
    {
        USB_mem_free(response_data_ptr);
        response_data_ptr = NULL;
    }

    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_format_unit_command
 *
 * @brief host sends the FORMAT UNIT command to physically format a diskette
 *        according to selected options
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_format_unit_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_8 error;
    *csw_residue_ptr = 0;
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;    
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = 0;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = NULL;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);
    
    if(*csw_status_ptr != PHASE_ERROR)
    {
        /* FmtData = 1, CmpList = 0, Defect List Format = 7 */
        if((cbw_ptr->command_block[1] & 0x1F) == 0x17)
        {
            *csw_status_ptr = COMMAND_PASSED;
        }
        else
        {
            *csw_status_ptr = COMMAND_FAILED;
            scsi_ptr->request_sense.sense_key = ILLEGAL_REQUEST;
            scsi_ptr->request_sense.add_sense_code = INVALID_FIELD_IN_COMMAND_PKT;
        }       
    }
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_prevent_allow_medium_removal
 *
 * @brief command tells the UFI device to enable or disable the removal of the
 *        medium in the logical unit.
 *
 * @param handle 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_prevent_allow_medium_removal
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_8 error;
    uint_8 prevent_removal = 0;
    /* masking to obtain value of last bit */
    prevent_removal = (uint_8)(cbw_ptr->command_block[4] &
        PREVENT_ALLOW_REMOVAL_MASK);
        
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;    
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);      
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = 0;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = NULL;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);

    if(*csw_status_ptr != PHASE_ERROR)
    {
        if((!SUPPORT_DISK_LOCKING_MECHANISM)&&(prevent_removal))
        {/*there is no support for disk locking and removal of medium is disabled*/
            scsi_ptr->request_sense.sense_key = ILLEGAL_REQUEST;
            scsi_ptr->request_sense.add_sense_code = INVALID_FIELD_IN_COMMAND_PKT;
            *csw_status_ptr = COMMAND_FAILED;
        }
    }
    
    if(scsi_ptr->scsi_callback.callback != NULL)
    {
        scsi_ptr->scsi_callback.callback(USB_MSC_DEVICE_REMOVAL_REQUEST, 
            (void*)&prevent_removal, scsi_ptr->scsi_callback.arg);
    }

    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_send_diagnostic_command
 *
 * @brief requests the device to perform self test
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_send_diagnostic_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    /* No Self Test Procedure available */
    uint_8 error;
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); 
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = 0;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = NULL;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;

    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);
   
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_start_stop_unit_command
 *
 * @brief command instructs device to enable or disable media access operations
 *
 * @param msc_obj_ptr:    
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_start_stop_unit_command
(
    MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    uint_8 error;
    uint_8 load_eject_start;
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    /* masking to obtain value of last bit */
    load_eject_start = (uint_8)(cbw_ptr->command_block[4] &
        LOAD_EJECT_START_MASK);
    /* initialize sense code values */
    scsi_ptr->request_sense.sense_key = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code = NO_SENSE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    scsi_ptr->thirteen_case_ptr->handle = msc_obj_ptr->controller_handle;
    scsi_ptr->thirteen_case_ptr->host_expected_data_len = cbw_ptr->data_length;
    scsi_ptr->thirteen_case_ptr->host_expected_direction = 
        (uint_8)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT);      
    scsi_ptr->thirteen_case_ptr->device_expected_data_len = 0;
    scsi_ptr->thirteen_case_ptr->device_expected_direction = USB_SEND;
    scsi_ptr->thirteen_case_ptr->csw_status_ptr = csw_status_ptr;
    scsi_ptr->thirteen_case_ptr->csw_residue_ptr = csw_residue_ptr;
    scsi_ptr->thirteen_case_ptr->buffer_ptr = NULL;
    scsi_ptr->thirteen_case_ptr->lba_txrx_select = FALSE;
    
    error = msc_thirteen_cases_check(msc_obj_ptr,scsi_ptr->thirteen_case_ptr);

    if(*csw_status_ptr != PHASE_ERROR)
    {
        if(scsi_ptr->scsi_callback.callback != NULL)
        {
            scsi_ptr->scsi_callback.callback(USB_MSC_START_STOP_EJECT_MEDIA, 
                (void*)&load_eject_start, scsi_ptr->scsi_callback.arg);
        }
    }
    return error;
}

/**************************************************************************//*!
 *
 * @name  msc_unsupported_command
 *
 * @brief Responds appropriately to unsupported commands
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 msc_unsupported_command
(
    MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
)
{
    MSC_SCSI_STRUCT_PTR scsi_ptr;
    
    UNUSED_ARGUMENT(cbw_ptr)   
    
    scsi_ptr = (MSC_SCSI_STRUCT_PTR)msc_obj_ptr->scsi_object_ptr;
    
    *csw_residue_ptr = 0;
    *csw_status_ptr = COMMAND_FAILED;
                                                                          
    scsi_ptr->request_sense.sense_key = ILLEGAL_REQUEST;
    scsi_ptr->request_sense.add_sense_code = INVALID_COMMAND_OPCODE;
    scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE;

    return USB_OK;
}
#endif /*MSD_CONFIG*/
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mpc5675k.h<|end_filename|>
#include "flash_mpxs30.h"


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/Events.h<|end_filename|>
/* ###################################################################
**     Filename    : Events.h
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : Events
**     Version     : Driver 01.00
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-08, 17:27, # CodeGen: 0
**     Abstract    :
**         This is user's event module.
**         Put your event handler code here.
**     Settings    :
**     Contents    :
**         Cpu_OnNMIINT - void Cpu_OnNMIINT(void);
**
** ###################################################################*/
/*!
** @file Events.h
** @version 01.00
** @brief
**         This is user's event module.
**         Put your event handler code here.
*/         
/*!
**  @addtogroup Events_module Events module documentation
**  @{
*/         

#ifndef __Events_H
#define __Events_H
/* MODULE Events */

#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
#include "MQX1.h"
#include "UART0.h"
#include "FTM0.h"

#ifdef __cplusplus
extern "C" {
#endif 

/*
** ===================================================================
**     Event       :  Cpu_OnNMIINT (module Events)
**
**     Component   :  Cpu [MK61FN1M0MJ15]
**     Description :
**         This event is called when the Non maskable interrupt had
**         occurred. This event is automatically enabled when the <NMI
**         interrupt> property is set to 'Enabled'.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_OnNMIINT(void);


/*
** ===================================================================
**     Event       :  Cpu_OnLLSWakeUpINT (module Events)
**
**     Component   :  Cpu [MK60FN1M0LQ15]
**     Description :
**         This event is called when Low Leakage WakeUp interrupt
**         occurs. LLWU flags indicating source of the wakeup can be
**         obtained by calling the <GetLLSWakeUpFlags> method. Flags
**         indicating the external pin wakeup source are automatically
**         cleared after this event is executed. It is responsibility
**         of user to clear flags corresponding to internal modules.
**         This event is automatically enabled when <LLWU settings> are
**         enabled.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_OnLLSWakeUpINT(void);

/* END Events */

#ifdef __cplusplus
}  /* extern "C" */
#endif 

#endif 
/* ifndef __Events_H*/
/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/rtc_mcf52xx.h<|end_filename|>

/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtc_mcf52xx.h$
* $Version : 3.8.4.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the type definitions for the mcf52xx RTC module.
*
*END************************************************************************/

#ifndef __rtc_mcf52xx_h__
#define __rtc_mcf52xx_h__

#ifdef __cplusplus
extern "C" {
#endif


#define DEVSPEC_RTC_RTCISR_SW   MCF52XX_RTC_RTCISR_SW
#define DEVSPEC_RTC_RTCISR_ALM  MCF52XX_RTC_RTCISR_ALM
#define DEVSPEC_RTC_RTCIENR_SW  MCF52XX_RTC_RTCISR_SW
#define DEVSPEC_RTC_RTCIENR_ALM MCF52XX_RTC_RTCISR_ALM

typedef struct rtc_time_struct
{
    uint_8      seconds;
    uint_8      minutes;
    uint_8      hours;
    uint_16     days;
} RTC_TIME_STRUCT, _PTR_ RTC_TIME_STRUCT_PTR;

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enstat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enstat.c$
* $Version : 3.0.5.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   This file contains the ENET_get_stats utility
*   function.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

#if BSPCFG_ENABLE_ENET_STATS
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_get_stats
*  Returned Value : pointer to the statistics structure
*  Comments       :
*        Retrieves the Ethernet statistics for an initialized device.
*
*END*-----------------------------------------------------------------*/

ENET_STATS_PTR ENET_get_stats
   (
      /* [IN] the Ethernet state structure */
      _enet_handle   handle
   )
{
   return (ENET_STATS_PTR)&((ENET_CONTEXT_STRUCT_PTR)handle)->STATS;
} 

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/dhcputil.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dhcputil.c$
* $Version : 3.8.4.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the utility functions for use by both the
*   DHCP Client and DHCP Server
*   For more information, refer to:
*   RFC 1541 (DHCP)
*   RPC 1533 (DHCP Options).
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_IP4


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_find_option
* Returned Value  : uchar_ptr
* Comments        : This function searches through the OPTIONS section
*                   of a DHCP message to find a specific option type.
*                   If it is found, a pointer to the specific option
*                   field is returned, If no option of the specified
*                   type exists, NULL is returned.
*
*END*-----------------------------------------------------------------*/

uchar_ptr DHCPCLNT_find_option
   (
      uchar_ptr   msgptr,
      uint_32     msglen,
      uchar       option
   )
{ /* Body */



return( DHCP_find_option((msgptr + sizeof(DHCP_HEADER) + 4),
                         ((msglen - sizeof(DHCP_HEADER)) - 4),
                         option));

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCP_find_option
* Returned Value  : uchar_ptr
* Comments        : This function searches through the OPTIONS section
*                   of a DHCP message to find a specific option type.
*                   If it is found, a pointer to the specific option
*                   field is returned, If no option of the specified
*                   type exists, NULL is returned.
*
*END*-----------------------------------------------------------------*/

uchar_ptr DHCP_find_option
   (
      uchar_ptr   msgptr,
      uint_32     msglen,
      uchar       option
   )
{ /* Body */
   uchar optype;
   uchar oplen;

   for (;;) {

      /* Get the next option code */
      if (msglen == 0) {
         return NULL;
      } /* Endif */
      optype = ntohc(msgptr);
      msgptr++;
      msglen--;

      if (optype == DHCPOPT_END) {
         return NULL;
      } /* Endif */
      if (optype == DHCPOPT_PAD) {
         continue;
      } /* Endif */

      /* Get the option length */
      if (msglen == 0) {
         return NULL;
      } /* Endif */
      oplen = ntohc(msgptr);
      msgptr++;
      msglen--;

      if (msglen < oplen) {
         return NULL;
      } /* Endif */

      if (optype == option) {
         return msgptr-2;
      } /* Endif */

      msgptr += oplen;
      msglen -= oplen;

   } /* Endfor */
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCP_option_int8
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments        : This function writes out an 8-bit option
*                   to the optptr buffer.
*
*END*-----------------------------------------------------------------*/

boolean DHCP_option_int8
   (
      uchar_ptr   _PTR_ optptr,
      uint_32     _PTR_ optlen,
      uchar             opttype,
      uchar             optval
   )
{ /* Body */
   uchar_ptr opt = *optptr;

   if ((*optlen) < 3) return FALSE;

   htonc(opt, opttype); opt++;
   htonc(opt, 1);       opt++;
   htonc(opt, optval);  opt++;

   *optlen -= 3;
   *optptr = opt;
   return TRUE;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCP_option_int16
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments        : This function writes out a 16-bit option
*                   to the optptr buffer.
*
*END*-----------------------------------------------------------------*/

boolean DHCP_option_int16
   (
      uchar_ptr   _PTR_ optptr,
      uint_32     _PTR_ optlen,
      uchar             opttype,
      uint_16           optval
   )
{ /* Body */
   uchar_ptr opt = *optptr;

   if ((*optlen) < 4) return FALSE;

   htonc(opt, opttype); opt++;
   htonc(opt, 2);       opt++;
   htons(opt, optval);  opt += 2;

   *optlen -= 4;
   *optptr = opt;
   return TRUE;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCP_option_int32
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments        : This function writes out a 32-bit option
*                   to the optptr buffer.
*
*END*-----------------------------------------------------------------*/

boolean DHCP_option_int32
   (
      uchar_ptr   _PTR_ optptr,
      uint_32     _PTR_ optlen,
      uchar             opttype,
      uint_32           optval
   )
{ /* Body */
   uchar_ptr opt = *optptr;

   if ((*optlen) < 6) return FALSE;

   htonc(opt, opttype); opt++;
   htonc(opt, 4);       opt++;
   htonl(opt, optval);  opt += 4;

   *optlen -= 6;
   *optptr = opt;
   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCP_option_variable
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments        : This function writes out a variable size request option
*                   to the optptr buffer.
*
*END*-----------------------------------------------------------------*/

boolean DHCP_option_variable
   (
      uchar_ptr   _PTR_ optptr,
      uint_32     _PTR_ optlen,
      uchar             opttype,
      uchar       _PTR_ options,
      uint_32           num_options
   )
{ /* Body */
   uint_32   i;
   uchar_ptr opt = *optptr;

   if ((*optlen) < (num_options + 2)) return FALSE;

   htonc(opt, opttype); opt++;
   htonc(opt, (uchar)num_options); opt++;

   for ( i = 0; i < num_options; i++ ) {
      htonc(opt, options[i]); opt++;
   } /* Endfor */

   *optlen -= (num_options +  2);
   *optptr = opt;
   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCP_option_addr
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments        : This function writes out an IP address option
*                   to the optptr buffer.
*
*END*-----------------------------------------------------------------*/

boolean DHCP_option_addr
   (
      uchar_ptr   _PTR_ optptr,
      uint_32     _PTR_ optlen,
      uchar             opttype,
      _ip_address       addr
   )
{ /* Body */
   uchar_ptr opt = *optptr;

   if ((*optlen) < 6) return FALSE;

   htonc(opt, opttype); opt++;
   htonc(opt, 4);       opt++;
   htonl(opt, addr);    opt += 4;

   *optlen -= 6;
   *optptr = opt;
   return TRUE;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCP_option_addrlist
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments        : This function writes out an IP address list option
*                   to the optptr buffer.
*
*END*-----------------------------------------------------------------*/

boolean DHCP_option_addrlist
   (
      uchar_ptr   _PTR_ optptr,
      uint_32     _PTR_ optlen,
      uchar             opttype,
      _ip_address _PTR_ addrptr,
      uint_32           addrcount
   )
{ /* Body */
   uchar_ptr   opt = *optptr;
   _ip_address addr;

   if ((*optlen) < 4*addrcount+2) return FALSE;

   htonc(opt, opttype);     opt++;
   htonc(opt, 4*addrcount); opt++;
   while (addrcount--) {
      addr = *addrptr++;
      htonl(opt, addr);     opt += 4;
   } /* Endwhile */

   *optlen -= 4*addrcount+2;
   *optptr = opt;
   return TRUE;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCP_option_string
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments        : This function writes out a variable-length option
*                   to the optptr buffer.
*
*END*-----------------------------------------------------------------*/

boolean DHCP_option_string
   (
      uchar_ptr   _PTR_ optptr,
      uint_32     _PTR_ optlen,
      uchar             opttype,
      char_ptr          optval
   )
{ /* Body */
   uint_32   slen = 0;
   uchar_ptr opt;

   opt = (uchar_ptr)optval;
   while (*opt++) slen++;

   if ((*optlen) < slen+2) return FALSE;
   opt = *optptr;

   htonc(opt, opttype); opt++;
   htonc(opt, slen);    opt++;
   _mem_copy(optval, opt, slen); opt += slen;

   *optlen -= slen+2;
   *optptr = opt;
   return TRUE;

} /* Endbody */


#endif /* RTCSCFG_ENABLE_IP4 */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/srecord.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: srecord.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the S-Record decoder for the
*   Exec function of the RTCS Communication Library.
*
*END************************************************************************/

#include <rtcs.h>


/* The S-Record decoder information to pass to RTCS_load() */
uint_32 SREC_start  (pointer ff_data);
uint_32 SREC_decode (uint_32 size, uchar_ptr data);
uint_32 SREC_eod    (void);
void    SREC_exec   (void);

static FF_CALL_STRUCT ff_srec = {
   SREC_start,
   SREC_decode,
   SREC_eod,
   SREC_exec
};

const FF_CALL_STRUCT_PTR FF_SREC = &ff_srec;


#define NEXT_STATE_BREAK(s)  \
      SREC_config.state = s; \
      break;

#define NEXT_STATE_FALLTHROUGH(s) \
      if (!size) {                \
         SREC_config.state = s;   \
         break;                   \
      } /* Endif */               \
      size--;                     \
      c = ntohc(data);            \
      data++;


#define SREC_HI_CHAR(c,n) \
           if ((c >= '0') && (c <= '9')) n = (c-'0'+ 0) << 4; \
      else if ((c >= 'A') && (c <= 'F')) n = (c-'A'+10) << 4; \
      else if ((c >= 'a') && (c <= 'f')) n = (c-'a'+10) << 4; \
      else return RTCSERR_SREC_CHAR;

#define SREC_LO_CHAR(c,n) \
           if ((c >= '0') && (c <= '9')) n += (c-'0'+ 0); \
      else if ((c >= 'A') && (c <= 'F')) n += (c-'A'+10); \
      else if ((c >= 'a') && (c <= 'f')) n += (c-'a'+10); \
      else return RTCSERR_SREC_CHAR;


/*
** The state diagram is:
**
**      -------------------------
**     (                       ) \
**  -----> s -> l -> a ---> d -   )
**                      \        /
**                       -> i -----> end
**
** S0,S5    records follow s-l-a-i-s
** S1,S2,S3 records follow s-l-a-d-s
** S7,S8,S9 records follow s-l-a-i-end
**
*/
typedef enum {
   hex_shi, hex_slo, hex_lhi, hex_llo, hex_ahi, hex_alo,
   hex_dhi, hex_dlo, hex_ihi, hex_ilo, hex_end
} SREC_state;


/* S-Record decoder state information */
static struct {
   SREC_state     state;   /* the current state */
   SREC_state     dstate;  /* the state that follows a */
   SREC_state     estate;  /* the state that follows d or i */
   uint_32        addr;    /* the address field */
   uchar          data;    /* one data byte */
   uchar          sum;     /* one's complement checksum */
   uchar          alen;    /* size of the address field */
   uchar          dlen;    /* length of the S-Record */
} SREC_config;


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SREC_start
* Returned Value   : error code
* Comments  :  Routine to begin decoding a HEX file.
*
*END*-----------------------------------------------------------------*/

uint_32 SREC_start
   (
      pointer  ff_data
   )
{ /* Body */

   SREC_config.state = hex_shi;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SREC_decode
* Returned Value   : error code
* Comments  :  Routine to decode S-Records.
*
*  SREC_decode is implemented as a finite state machine.
*
*  All S-Records begin at state hex_shi.  Once a 'S' is parsed we
*  go to state hex_slo.
*
*  In state hex_slo we determine which type of S-Record we have,
*  and we set the following fields in SREC_config:
*
*   - alen is the size of the address field:  4 for S3 and S7,
*     3 for S2 and S8, and 2 for all others.
*
*   - dstate is the state to go to after the address and length
*     fields are parsed.  S1,S2,S3 go to state hex_dhi/hex_dlo
*     (which reads bytes and writes them to memory).  All other
*     record types go to state hex_ihi/hex_ilo (which validates
*     the checksum, but otherwise ignores all data bytes).
*
*   - estate is the state to go to after all data is parsed and
*     the checksum is validated.  S7,S8,S9 go to state hex_end.
*     All other record types return to state hex_shi/hex_slo to
*     parse another S-Record.
*
*  State hex_slo is followed by hex_lhi and hex_llo, which read
*  the one-byte length field of the S-Record, and store it in
*  the dlen field of SREC_config.
*
*  States hex_ahi and hex_alo are then repeated alen times to
*  read the address field of the S-Record.  The address gets
*  stored in the addr field of SREC_config.  Additionally, dlen
*  is decremented by alen, since dlen includes the address field.
*
*  Next, control is passed either to hex_dhi/hex_dlo or to hex_ihi/
*  hex_ilo, depending on the contents of dstate determined in state
*  hex_slo.  The dstate pair (hex_dhi/hex_dlo or hex_ihi/hex_ilo)
*  will be repeated dlen times.  On the last time through (when
*  dlen == 1), the checksum is validated by comparing it to 0xFF.
*  (The checksum is actually incremented and compared to 0.)
*
*  Once the checksum is validated, control is passed either to
*  hex_shi or to hex_end, depending on the contents of estate
*  determined in state hex_slo.  hex_shi, of course, returns to
*  the beginning of the state machine and parses the next S-Record.
*  In the case of a S7, S8 or S9 record, though, control goes to
*  state hex_end.
*
*  State hex_end accepts only whitespace, since no other S-Records
*  are expected, and this state must be reached in order for the
*  decoding to be successful.
*
*
*  Four code macros are used throughout this function.
*
*     SREC_HI_CHAR converts an ASCII character to the high
*     nybble of a byte.
*
*     SREC_LO_CHAR converts an ASCII character to the low
*     nybble of a byte.
*
*     NEXT_STATE_FALLTHROUGH is used whenever one state is always
*     succeeded by the same state.  It allows control to be passed
*     to the next state without breaking out of the switch statement,
*     testing the while condition, and branching back into the switch
*     statement.
*
*     When NEXT_STATE_FALLTHROUGH cannot be used, NEXT_STATE_BREAK is
*     used to change states.  It uses the more conventional method,
*     i.e. a break statement.
*
*END*-----------------------------------------------------------------*/

uint_32 SREC_decode
   (
      uint_32 size,
         /* [IN] number of bytes to decode */
      uchar_ptr data
         /* [IN] bytes to decode */
   )
{ /* Body */
   uchar c;

   while (size--) {
      c = ntohc(data);
      data++;
      switch (SREC_config.state) {
         /*
         ** Parse 'S' followed by an ASCII digit.
         */
      case hex_shi:
         if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n') || (c == '\0')) break;
         if ((c != 'S') && (c != 's')) return RTCSERR_SREC_CHAR;
         NEXT_STATE_FALLTHROUGH(hex_slo)

      case hex_slo:
         switch (c) {

         case '0':
         case '5':
            SREC_config.alen   = 2;
            SREC_config.dstate = hex_ihi;
            SREC_config.estate = hex_shi;
            break;

         case '1':
         case '2':
         case '3':
            SREC_config.alen   = c-'1'+2;
            SREC_config.dstate = hex_dhi;
            SREC_config.estate = hex_shi;
            break;

         case '7':
         case '8':
         case '9':
            SREC_config.alen   = 2+'9'-c;
            SREC_config.dstate = hex_ihi;
            SREC_config.estate = hex_end;
            break;

         default:
            return RTCSERR_SREC_RECORD;
         } /* Endswitch */
         NEXT_STATE_FALLTHROUGH(hex_lhi)

         /*
         ** Parse the length and address fields.
         */
      case hex_lhi:
         SREC_HI_CHAR(c,SREC_config.dlen)
         NEXT_STATE_FALLTHROUGH(hex_llo)

      case hex_llo:
         SREC_LO_CHAR(c,SREC_config.dlen)
         if (SREC_config.dlen <= SREC_config.alen) return RTCSERR_SREC_SHORT;
         SREC_config.addr  = 0;
         SREC_config.sum   = SREC_config.dlen;
         SREC_config.dlen -= SREC_config.alen;
         NEXT_STATE_FALLTHROUGH(hex_ahi)

      case hex_ahi:
         SREC_HI_CHAR(c,SREC_config.data)
         NEXT_STATE_FALLTHROUGH(hex_alo)

      case hex_alo:
         SREC_LO_CHAR(c,SREC_config.data)
         SREC_config.addr <<= 8;
         SREC_config.addr  += SREC_config.data;
         SREC_config.sum   += SREC_config.data;
         if (--SREC_config.alen) {
            NEXT_STATE_BREAK(hex_ahi)
         } else {
            NEXT_STATE_BREAK(SREC_config.dstate)
         } /* Endif */

         /*
         ** Parse S1,S2,S3 data:
         ** write data bytes to memory, and verify the checksum.
         */
      case hex_dhi:
         SREC_HI_CHAR(c,SREC_config.data)
         NEXT_STATE_FALLTHROUGH(hex_dlo)

      case hex_dlo:
         SREC_LO_CHAR(c,SREC_config.data)
         SREC_config.sum += SREC_config.data;
         if (!--SREC_config.dlen) {
            if (++SREC_config.sum & 0xFF) return RTCSERR_SREC_CHECKSUM;
            NEXT_STATE_BREAK(SREC_config.estate)
         } /* Endif */
         *(uchar_ptr)SREC_config.addr = SREC_config.data;
         SREC_config.addr++;
         NEXT_STATE_BREAK(hex_dhi)

         /*
         ** Parse S0,S5,S7,S8,S9 data:
         ** ignore data bytes, but verify the checksum.
         */
      case hex_ihi:
         SREC_HI_CHAR(c,SREC_config.data)
         NEXT_STATE_FALLTHROUGH(hex_ilo)

      case hex_ilo:
         SREC_LO_CHAR(c,SREC_config.data)
         SREC_config.sum += SREC_config.data;
         if (--SREC_config.dlen) {
            NEXT_STATE_BREAK(hex_ihi)
         } else {
            if (++SREC_config.sum & 0xFF) return RTCSERR_SREC_CHECKSUM;
            NEXT_STATE_BREAK(SREC_config.estate)
         } /* Endif */

         /*
         ** After S7,S8,S9 records, accept only whitespace.
         */
      case hex_end:
         if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n') || (c == '\0')) break;
         return RTCSERR_SREC_CHAR;

         /*
         ** Should never get here.
         */
      default:
         return RTCSERR_SREC_ERROR;
      } /* Endswitch */
   } /* Endwhile */
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SREC_eod
* Returned Value   : error code
* Comments  :  Routine to end decoding a HEX file.
*
*END*-----------------------------------------------------------------*/

uint_32 SREC_eod
   (
      void
   )
{ /* Body */

   switch (SREC_config.state) {
   case hex_end:
      return RTCS_OK;
   case hex_shi:
      return RTCSERR_SREC_END;
   default:
      return RTCSERR_SREC_EOF;
   } /* Endswitch */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : SREC_exec
* Returned Value   : none
* Comments  :  Routine to execute a decoded HEX file.
*
*END*-----------------------------------------------------------------*/

void SREC_exec
   (
      void
   )
{ /* Body */

   /* 
   ** Start P122-0270-01
   ** Disable interrupts before executing new image 
   */
   _int_disable();
   /* END SPR P122-0270-01 */
   (*(void(_CODE_PTR_)(void))(SREC_config.addr))();

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/socket.h<|end_filename|>
#ifndef __socket_h__
#define __socket_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: socket.h$
* $Version : 3.5.4.0$
* $Date    : Dec-8-2009$
*
* Comments:
*
*   Constants and prototype declarations which are internal
*   to the SOCKET module.
*
*END************************************************************************/


/*
** Connectionless-mode socket states
*/
#define SOCKSTATE_DGRAM_GROUND      0
#define SOCKSTATE_DGRAM_BOUND       1
#define SOCKSTATE_DGRAM_OPEN        2

/*
** Connection-mode socket states
*/
#define SOCKSTATE_STREAM_GROUND     0
#define SOCKSTATE_STREAM_BOUND      1
#define SOCKSTATE_STREAM_LISTENING  2
#define SOCKSTATE_STREAM_CONNECTED  3


/*
**  socket-specific structures
*/
struct sockselect_parm;
typedef struct socket_config_struct {

   boolean                       INITIALIZED;
   uint_32                       CURRENT_SOCKETS;
   pointer                       SOCKET_HEAD;
   pointer                       SOCKET_TAIL;
   struct sockselect_parm _PTR_  SELECT_HEAD;
   pointer                       SELECT_TIME_HEAD;    /* not used */
   _rtcs_mutex                   SOCK_MUTEX;

} SOCKET_CONFIG_STRUCT, _PTR_ SOCKET_CONFIG_STRUCT_PTR;


/****************************************************
** extern statements for socket procedures          *
*****************************************************/

extern SOCKET_STRUCT_PTR   SOCK_Get_sock_struct
(
   RTCS_SOCKET_CALL_STRUCT_PTR   type,
   _rtcs_taskid                  owner
);
extern void SOCK_Free_sock_struct
(
   SOCKET_STRUCT_PTR          socket_ptr
);

extern boolean SOCK_Remove_owner( SOCKET_STRUCT_PTR, pointer );
extern boolean SOCK_Is_owner( SOCKET_STRUCT_PTR, pointer );
extern boolean SOCK_Add_owner( SOCKET_STRUCT_PTR, pointer );


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/int/i2c_int_ki2c.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_int_ki2c.c$
* $Version : 3.8.10.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains low level functions for the I2C interrupt device driver
*   for Kinetis family.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "i2c.h"
#include "i2c_int_prv.h"
#include "i2c_ki2c_prv.h"


extern uint_32 _ki2c_polled_init (KI2C_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _ki2c_polled_ioctl (VKI2C_INFO_STRUCT_PTR, uint_32, uint_32_ptr);

extern uint_32 _ki2c_int_init (IO_I2C_INT_DEVICE_STRUCT_PTR, char_ptr);
extern uint_32 _ki2c_int_deinit (IO_I2C_INT_DEVICE_STRUCT_PTR, VKI2C_INFO_STRUCT_PTR);
extern uint_32 _ki2c_int_rx (IO_I2C_INT_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _ki2c_int_tx (IO_I2C_INT_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
static void    _ki2c_isr (pointer);


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_int_install
* Returned Value   : MQX error code
* Comments         :
*    Install an I2C device.
*
*END*********************************************************************/

uint_32 _ki2c_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr              identifier,
  
      /* [IN] The I/O init data pointer */
      KI2C_INIT_STRUCT_CPTR init_data_ptr
   )
{ /* Body */

   return _io_i2c_int_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, char_ptr))_ki2c_int_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_ki2c_int_deinit,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_ki2c_int_rx,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_ki2c_int_tx,
      (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_ki2c_polled_ioctl, 
      (pointer)init_data_ptr);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_int_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an I2C device.
*
*END*********************************************************************/

uint_32 _ki2c_int_init
   (
      /* [IN] Initialization information for the device being opened */
      IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The rest of the name of the device opened */
      char_ptr                     open_name_ptr

   )
{ /* Body */
   I2C_MemMapPtr                   i2c_ptr;
   VKI2C_INFO_STRUCT_PTR           io_info_ptr;
   KI2C_INIT_STRUCT_PTR            i2c_init_ptr;
   uint_32                         vector, result;

   i2c_init_ptr = (KI2C_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
   result = _ki2c_polled_init (i2c_init_ptr,
                                     &(int_io_dev_ptr->DEV_INFO_PTR),
                                     open_name_ptr);
   if (result)
   {
      return result;
   }
   
   io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;
   vector = _bsp_get_i2c_vector (i2c_init_ptr->CHANNEL);
   if (0 == vector)
   {
      return I2C_ERROR_CHANNEL_INVALID;
   }
   io_info_ptr->VECTOR = vector;

   /* Allocate buffers */
   io_info_ptr->RX_BUFFER = (pointer)_mem_alloc_system (i2c_init_ptr->RX_BUFFER_SIZE);
   if (NULL == io_info_ptr->RX_BUFFER) 
   {
      return MQX_OUT_OF_MEMORY;
   }
   io_info_ptr->TX_BUFFER = (pointer)_mem_alloc_system (i2c_init_ptr->TX_BUFFER_SIZE);
   if (NULL == io_info_ptr->TX_BUFFER) 
   {
      _mem_free (io_info_ptr->RX_BUFFER);
      io_info_ptr->RX_BUFFER = NULL;
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type (io_info_ptr->RX_BUFFER, MEM_TYPE_IO_I2C_IN_BUFFER);       
   _mem_set_type (io_info_ptr->TX_BUFFER, MEM_TYPE_IO_I2C_OUT_BUFFER);       

   /* Install new vectors and backup the old ones */
   io_info_ptr->OLD_ISR_DATA = _int_get_isr_data (vector);
   io_info_ptr->OLD_ISR = _int_install_isr (vector, _ki2c_isr, (pointer)io_info_ptr);

   /* Enable I2C interrupts */
   _bsp_int_init((IRQInterruptIndex)vector, i2c_init_ptr->LEVEL, i2c_init_ptr->SUBLEVEL, TRUE);
   
   i2c_ptr->C1 |= I2C_C1_IICIE_MASK;

   return result;
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_int_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an I2C device.
*
*END*********************************************************************/

uint_32 _ki2c_int_deinit
   (
      /* [IN] the initialization information for the device being opened */
      IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the address of the device specific information */
      VKI2C_INFO_STRUCT_PTR        io_info_ptr
   )
{ /* Body */
   I2C_MemMapPtr                   i2c_ptr;
   KI2C_INIT_STRUCT_PTR            i2c_init_ptr;
      
   if ((NULL == io_info_ptr) || (NULL == int_io_dev_ptr)) 
   {
      return I2C_ERROR_INVALID_PARAMETER;
   }

   i2c_ptr = io_info_ptr->I2C_PTR;
   if (i2c_ptr->S & I2C_S_BUSY_MASK) 
   {
      return I2C_ERROR_DEVICE_BUSY;
   }
   
   /* Disable the I2C */
   i2c_ptr->C1 = 0x00;

   /* Clear the I2C events */
   i2c_ptr->S = 0xFF; 
 
   /* Install original vectors */
   i2c_init_ptr = (KI2C_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
   _int_install_isr (io_info_ptr->VECTOR, io_info_ptr->OLD_ISR, io_info_ptr->OLD_ISR_DATA);
   
   /* Free buffers and info struct */
   _mem_free (int_io_dev_ptr->DEV_INFO_PTR);
   int_io_dev_ptr->DEV_INFO_PTR = NULL;
   _mem_free (io_info_ptr->RX_BUFFER);
   io_info_ptr->RX_BUFFER = NULL;
   _mem_free (io_info_ptr->TX_BUFFER);
   io_info_ptr->TX_BUFFER = NULL;

   return I2C_OK;
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_int_rx
* Returned Value   : number of bytes read
* Comments         : 
*   Returns the number of bytes received.
*   Reads the data into provided array when data is available.
*
*END*********************************************************************/

uint_32 _ki2c_int_rx
   (
      /* [IN] the address of the device specific information */
      IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The array to copy data into */
      uchar_ptr                    buffer,
      
      /* [IN] number of bytes to read */
      uint_32                      length
   )
{ /* Body */
   VKI2C_INFO_STRUCT_PTR           io_info_ptr;
   I2C_MemMapPtr                   i2c_ptr;   
   uint_32                         num;
   volatile uint_8                 tmp;
         
   io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;

   /* Critical section + avoiding spurious interrupt */
   _int_disable ();
   _bsp_int_disable (io_info_ptr->VECTOR);
   _int_enable ();

   /* Get data from input buffer */
   for (num = 0; num < length; num++)
   {
      if (io_info_ptr->RX_OUT == io_info_ptr->RX_IN) break;
      *buffer++ = io_info_ptr->RX_BUFFER[io_info_ptr->RX_OUT++];
      if (io_info_ptr->RX_OUT >= io_info_ptr->INIT.RX_BUFFER_SIZE) io_info_ptr->RX_OUT = 0;
   }

   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION |= I2C_OPERATION_READ;
   tmp = io_info_ptr->STATE;
   if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
   {
      io_info_ptr->STATE = I2C_STATE_RECEIVE;
      if (I2C_MODE_MASTER == io_info_ptr->MODE)
      {
         i2c_ptr->C1 |= I2C_C1_TX_MASK;
         i2c_ptr->S |= I2C_S_IICIF_MASK;
         if (I2C_STATE_REPEATED_START == tmp)
         {
            i2c_ptr->C1 |= I2C_C1_RSTA_MASK;
         }
         else
         {
            i2c_ptr->C1 |= I2C_C1_MST_MASK;
         }
         io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
         i2c_ptr->D = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_READ;
         io_info_ptr->STATISTICS.TX_PACKETS++;
         while (0 == (i2c_ptr->S & I2C_S_IICIF_MASK))
            { };   /* wait for address transferred */
      }
   }
   
   /* Check for bus idle in slave mode */
   if (0 == (i2c_ptr->C1 & I2C_C1_MST_MASK))
   {
      if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2c_ptr->S & I2C_S_BUSY_MASK)))
      {
         io_info_ptr->OPERATION = 0;
         io_info_ptr->RX_REQUEST = 0;
         io_info_ptr->STATE = I2C_STATE_FINISHED;
      }
   }
   
   /* Interrupt enable - end of critical section */
   _bsp_int_enable (io_info_ptr->VECTOR);

   return num;
   
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _ki2c_int_tx
* Returned Value   : number of bytes written
* Comments         : 
*   Returns the number of bytes written.
*   Writes the data provided into transmition buffer if available.
*
*END*********************************************************************/

uint_32 _ki2c_int_tx
   (
      /* [IN] the address of the device specific information */
      IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The array characters are to be read from */
      uchar_ptr                    buffer,
      
      /* [IN] number of bytes to output */
      uint_32                      length
   )
{ /* Body */
   VKI2C_INFO_STRUCT_PTR           io_info_ptr;
   I2C_MemMapPtr                   i2c_ptr;   
   uint_32                         num, tmp;
   
   io_info_ptr  = int_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;

   /* Critical section + avoiding spurious interrupt */
   _int_disable ();
   _bsp_int_disable (io_info_ptr->VECTOR);
   _int_enable ();

   /* Fill in the output buffer  */
   for (num = 0; num < length; num++)
   {
      tmp = io_info_ptr->TX_IN + 1;
      if (tmp >= io_info_ptr->INIT.TX_BUFFER_SIZE) tmp = 0;
      if (tmp == io_info_ptr->TX_OUT) break;
      io_info_ptr->TX_BUFFER[io_info_ptr->TX_IN] = *buffer++;
      io_info_ptr->TX_IN = tmp;
   }
   
   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION &= (~ I2C_OPERATION_READ);
   tmp = io_info_ptr->STATE;
   if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
   {
      io_info_ptr->STATE = I2C_STATE_TRANSMIT;
      if (I2C_MODE_MASTER == io_info_ptr->MODE)
      {
         i2c_ptr->C1 |= I2C_C1_TX_MASK;
         i2c_ptr->S |= I2C_S_IICIF_MASK;
         if (I2C_STATE_REPEATED_START == tmp)
         {
            i2c_ptr->C1 |= I2C_C1_RSTA_MASK;
         }
         else
         {
            i2c_ptr->C1 |= I2C_C1_MST_MASK;
         }
         io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
         i2c_ptr->D = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_WRITE;
         io_info_ptr->STATISTICS.TX_PACKETS++;
         while (0 == (i2c_ptr->S & I2C_S_IICIF_MASK))
            { };    /* wait for address transferred */
      }
   }

   /* Check for bus idle in slave mode */
   if (0 == (i2c_ptr->C1 & I2C_C1_MST_MASK))
   {
      if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2c_ptr->S & I2C_S_BUSY_MASK)))
      {
         io_info_ptr->OPERATION = 0;
         io_info_ptr->RX_REQUEST = 0;
         io_info_ptr->STATE = I2C_STATE_FINISHED;
      }
   }
   
   /* Interrupt enable - end of critical section */
   _bsp_int_enable (io_info_ptr->VECTOR);

   return num;

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    :_ki2c_isr
* Returned Value   : none   
*
*END*********************************************************************/
static void _ki2c_isr
   (
      pointer            parameter
   )
{ /* Body */
   VKI2C_INFO_STRUCT_PTR io_info_ptr = parameter;
   I2C_MemMapPtr         i2c_ptr = io_info_ptr->I2C_PTR;
   uint_8                i2csr;
   volatile uint_8       tmp;

   i2csr = i2c_ptr->S;
   io_info_ptr->STATISTICS.INTERRUPTS++;
   
   /* Master */
   if (i2c_ptr->C1 & I2C_C1_MST_MASK)
   {
      /* Transmit */
      if (i2c_ptr->C1 & I2C_C1_TX_MASK)
      {
         /* Not ack */
         if (i2csr & I2C_S_RXAK_MASK)
         {
            i2c_ptr->S |= I2C_S_IICIF_MASK;
            io_info_ptr->TX_OUT = io_info_ptr->TX_IN;
            io_info_ptr->STATE = I2C_STATE_FINISHED;
            io_info_ptr->STATISTICS.TX_NAKS++;
         }
         /* Ack */
         else
         {
            /* Transmit requested */
            if (I2C_STATE_TRANSMIT == io_info_ptr->STATE)
            {
               /* Anything to transmit? */
               if ((io_info_ptr->TX_IN != io_info_ptr->TX_OUT) && (I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))))
               {
                  i2c_ptr->S |= I2C_S_IICIF_MASK;
                  i2c_ptr->D = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /*  transmit data */
                  if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
                  io_info_ptr->STATISTICS.TX_PACKETS++;
               }
               else
               {
                  _bsp_int_disable (io_info_ptr->VECTOR);
               }
            }
            /* Receive requested */
            else if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
            {
               if ((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED)))
               {
                  i2c_ptr->C1 &= (~ I2C_C1_TX_MASK);
                  if (1 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
                  }
                  else
                  {
                     i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
                  }
                  i2c_ptr->S |= I2C_S_IICIF_MASK;
                  if (0 == io_info_ptr->RX_REQUEST)
                  {
                     io_info_ptr->STATE = I2C_STATE_FINISHED;
                  }
                  else
                  {
                     tmp = i2c_ptr->D;   /* dummy read to clock in 1st byte */
                  }
               }
               else
               {
                  _bsp_int_disable (io_info_ptr->VECTOR);
               }
            }
            /* Others are unwanted/not handled states */
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
            }
         }
      }
      /* Receive */
      else
      {
         /* Receive requested */
         if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
         {
            if (((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (0 != io_info_ptr->RX_REQUEST))
            {
               tmp = io_info_ptr->RX_IN + 1;
               if (tmp >= io_info_ptr->INIT.RX_BUFFER_SIZE) tmp = 0;
               
               /* Buffer full */
               if (tmp == io_info_ptr->RX_OUT)
               {
                  _bsp_int_disable (io_info_ptr->VECTOR);
               }
               /* Buffer not full */
               else
               {
                  i2c_ptr->S |= I2C_S_IICIF_MASK;
                  io_info_ptr->RX_REQUEST--;
                  if (1 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
                  }
                  else
                  {
                     i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
                  }
                  if (0 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->C1 |= I2C_C1_TX_MASK;   /* no more reading */
                  }
                  io_info_ptr->RX_BUFFER[io_info_ptr->RX_IN] = i2c_ptr->D;   /*  receive data */
                  io_info_ptr->RX_IN = tmp;
                  if (0 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->C1 &= (~ I2C_C1_TX_MASK);
                     io_info_ptr->STATE = I2C_STATE_FINISHED;
                  }
                  io_info_ptr->STATISTICS.RX_PACKETS++;
               }
            }
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
            }
         }
         /* Others are unwanted/not handled states */
         else
         {
            _bsp_int_disable (io_info_ptr->VECTOR);
         }
      }
   }
   /* Slave */
   else
   {
      /* Master arbitration lost */
      if (i2csr & I2C_S_ARBL_MASK)
      {
         i2c_ptr->S |= I2C_S_ARBL_MASK;
         io_info_ptr->STATE = I2C_STATE_LOST_ARBITRATION;
         io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS++;
      }
      /* Addressed as slave */
      if (i2csr & I2C_S_IAAS_MASK)
      {
         if (I2C_MODE_MASTER == io_info_ptr->MODE)
         {
            io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE++;
         }
         /* Transmit requested */
         if (i2csr & I2C_S_SRW_MASK)
         {
            io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_TX;
            if ((I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (io_info_ptr->TX_IN != io_info_ptr->TX_OUT))
            {
               i2c_ptr->C1 |= I2C_C1_TX_MASK;
               i2c_ptr->S |= I2C_S_IICIF_MASK;
               i2c_ptr->D = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /* transmit data */
               if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
               io_info_ptr->STATISTICS.TX_PACKETS++;
            }
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
            }
         }
         /* Receive requested */
         else
         {
            io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_RX;
            if (((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (io_info_ptr->RX_OUT == io_info_ptr->RX_IN) && (0 != io_info_ptr->RX_REQUEST))
            {
               i2c_ptr->C1 &= (~ I2C_C1_TX_MASK);
               i2c_ptr->S |= I2C_S_IICIF_MASK;
               if (1 == io_info_ptr->RX_REQUEST)
               {
                  i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
               }
               else
               {
                  i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
               }
               tmp = i2c_ptr->D;   /* dummy read to release bus */
            }
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
            }
         }
      }
      /* Normal slave operation */
      else
      {
         /* No master arbitration lost */
         if (! (i2csr & I2C_S_ARBL_MASK))
         {
            /* Transmit */
            if (i2c_ptr->C1 & I2C_C1_TX_MASK)
            {
               /* Not ack */
               if (i2csr & I2C_S_RXAK_MASK)
               {
                  i2c_ptr->S |= I2C_S_IICIF_MASK;
                  io_info_ptr->TX_OUT = io_info_ptr->TX_IN;
                  io_info_ptr->STATE = I2C_STATE_FINISHED;
                  io_info_ptr->STATISTICS.TX_NAKS++;
               }
               /* Ack */
               else
               {
                  /* Transmit requested */
                  if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_TX == io_info_ptr->STATE)) 
                     && (io_info_ptr->TX_IN != io_info_ptr->TX_OUT) && (I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))))
                  {
                     i2c_ptr->S |= I2C_S_IICIF_MASK;
                     i2c_ptr->D = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /*  transmit data */
                     if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
                     io_info_ptr->STATISTICS.TX_PACKETS++;
                  }
                  else
                  {
                     _bsp_int_disable (io_info_ptr->VECTOR);
                  }
               }
            }
            /* Receive */
            else
            {
               /* Receive requested */
               if (((I2C_STATE_RECEIVE == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_RX == io_info_ptr->STATE)) 
                  && ((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (0 != io_info_ptr->RX_REQUEST))
               {
                  tmp = io_info_ptr->RX_IN + 1;
                  if (tmp >= io_info_ptr->INIT.RX_BUFFER_SIZE) tmp = 0;
                  if (tmp == io_info_ptr->RX_OUT)
                  {
                     _bsp_int_disable (io_info_ptr->VECTOR);
                  }
                  else
                  {
                     i2c_ptr->S |= I2C_S_IICIF_MASK; 
                     io_info_ptr->RX_REQUEST--;
                     if (1 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
                     }
                     else
                     {
                        i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
                     }
                     if (0 == io_info_ptr->RX_REQUEST)
                     {
                        io_info_ptr->STATE = I2C_STATE_FINISHED;
                     }
                     io_info_ptr->RX_BUFFER[io_info_ptr->RX_IN] = i2c_ptr->D;   /* receive data */
                     io_info_ptr->RX_IN = tmp;
                     io_info_ptr->STATISTICS.RX_PACKETS++;
                  }
               }
               else
               {
                  _bsp_int_disable (io_info_ptr->VECTOR);
               }
            }
         }
         else
         {
            _bsp_int_disable (io_info_ptr->VECTOR);
         }
      }
   }
   io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/krtc.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: krtc.c$
* $Version : 3.8.18.0$
* $Date    : Oct-7-2011$
*
* Comments:
*            Kinetis RTC driver functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

static RTC_TIME_STRUCT alarm_time,
                       sw_time;
static uint_32 user_enables = 0;
static uint_32 user_requests = 0;

INT_ISR_FPTR user_isr = (INT_ISR_FPTR)NULL;
static void _rtc_update_TAR( uint_32 );

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_wait_ms
* Returned Value   :
* Comments         :
*
* wait at least ms_delay ms
*
*END*********************************************************************/
static void _rtc_wait_ms( uint_32 ms_delay )
{

   uint_32 us = ms_delay * 1000;
   uint_32 inst_per_us = BSP_SYSTEM_CLOCK / 1000000;
   uint_32 inst_to_exec = us * inst_per_us;

   for (; inst_to_exec != 0; inst_to_exec--) {
       _ASM_NOP();
   } /* Endfor */
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_init
* Returned Value   : MQX error code
* Comments         :
*    This function (re)initializes/clears/enables RTC module.
*    If cleared, alarm happens after RTC overflow, stopwatch happens next minute.
*    Reset disables and clears all interrupts and stopwatch (even if cleared).
*
*END*********************************************************************/
uint_32 _rtc_init
(
    /* [IN] flags identifying init operations */
    uint_32 flags
)
{
    uint_32 result = MQX_OK;
    RTC_MemMapPtr rtc = RTC_BASE_PTR;

    /* Clear time, alarm and stopwatch, if requested */
    if (flags & RTC_INIT_FLAG_CLEAR)
    {
        _int_disable();
        /* Resets all RTC registers except for SWR bit. */
        rtc->CR |= RTC_CR_SWR_MASK;
        alarm_time.seconds = 0;
        sw_time.seconds = 0;
        user_enables = 0;
        user_requests = 0;
        rtc->CR &= ~RTC_CR_SWR_MASK;
        rtc->TAR = 0xFFFFFFFF; /* e2574: RTC: Writing RTC_TAR[TAR] = 0 does not disable RTC alarm */
        rtc->TSR = 1;
        _int_enable();
    }
    /* reset current user interrupt state and callback, if requested */
    if (flags & RTC_INIT_FLAG_RESET)
    {
        _int_disable();
        /* Resets all RTC registers except for SWR bit. */
        rtc->CR |= RTC_CR_SWR_MASK;
        rtc->CR &= ~RTC_CR_SWR_MASK;
        rtc->TSR = 1;
        user_enables = 0;
        user_requests = 0;
        _int_enable();
    }

    /* install HW interrupt and run the RTC, if requested */
    if (flags & RTC_INIT_FLAG_ENABLE)
    {
        /* disable reset RTC */
        if( rtc->CR & RTC_CR_SWR_MASK )
        {
            rtc->CR &= ~RTC_CR_SWR_MASK;
        }

        if (NULL == _int_install_isr (INT_RTC, _rtc_isr, (pointer)rtc))
        {
            result = _task_get_error ();
        }

        if (MQX_OK == result)
        {
            if( !(rtc->SR & RTC_SR_TCE_MASK) || !(rtc->CR & RTC_CR_OSCE_MASK) )
            {
                rtc->CR |= RTC_CR_OSCE_MASK;
                /* recommended 125 ms delay for oscillator start */
                _rtc_wait_ms(125);
                rtc->SR |= RTC_SR_TCE_MASK;
            }
            _bsp_int_init(INT_RTC, BSP_RTC_INT_LEVEL, 0, TRUE);

        }
    }
    
#if PSP_MQX_CPU_IS_KINETIS_K70
    /* Enable monotonic counter */
    RTC_MER = RTC_MER_MCE_MASK;
#if 0
    /* Enable Tamper */
    RTC_TER =   (RTC_TER_TME_MASK | \
                 RTC_TER_VTE_MASK | \
                 RTC_TER_CTE_MASK | \
                 RTC_TER_TTE_MASK | \
                 RTC_TER_FSE_MASK | \
                 RTC_TER_TME_MASK);

#else    
    /* Disable all tampers */
    RTC_TER = 0;
#endif
        
        
#endif    
    
    return result;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_isr
* Returned Value   : none
* Comments         :
*    This is ISR for RTC module, triggered each second.
*
*END*********************************************************************/
void _rtc_isr
(
    /* [IN] rtc module pointer passed to interrupt */
    pointer ptr
)
{
    RTC_MemMapPtr rtc = RTC_BASE_PTR;
    uint_32 tsr_reg, status;
    uint_32 time_alarm;
    boolean alarm_fault = TRUE;

    status = rtc->SR;

    /* Time Invalid Flag, Time Overflow Flag */
    if (status & (RTC_SR_TIF_MASK | RTC_SR_TOF_MASK))
    {
        rtc->SR &= ~RTC_SR_TCE_MASK;    /* disable rtc timer - enable write access */
        rtc->TAR = 0xFFFFFFFF; /* e2574: RTC: Writing RTC_TAR[TAR] = 0 does not disable RTC alarm */
        /* if TIF or TOF flag is set, reading TSR return zero and we must set TSR to one */
        rtc->TSR = 1;                   /* this clear SR flags TIF, TOF */
        rtc->SR |= RTC_SR_TCE_MASK;

        user_requests |= ((status & RTC_SR_TIF_MASK) ? RTC_ISR_TIF : 0) | ((status & RTC_SR_TOF_MASK) ? RTC_ISR_TOF : 0);
    }

    /* Time Alarm Flag */
    if (status & RTC_SR_TAF_MASK)
    {
        /* TAR can be changed, store register to variable */
        time_alarm = rtc->TAR;
        if( time_alarm == alarm_time.seconds )
        {
            user_requests |= RTC_ISR_ALARM;
            _rtc_update_TAR( user_enables & ~RTC_ISR_ALARM );
            alarm_fault = FALSE;
        }
        if( time_alarm == sw_time.seconds )
        {
            user_requests |= RTC_ISR_STOPWATCH;
            _rtc_update_TAR( user_enables & ~RTC_ISR_STOPWATCH);
            alarm_fault = FALSE;
        }
        if( alarm_fault == TRUE )
        {
            _rtc_update_TAR( user_enables & ~( RTC_ISR_STOPWATCH | RTC_ISR_ALARM) );
        }
    }
    /* user callback */
    if (((INT_ISR_FPTR)NULL != user_isr) && (user_requests & user_enables))
    {
        user_isr ((pointer)rtc);
    }
}



/*FUNCTION****************************************************************
*
* Function Name    : _rtc_int_install
* Returned Value   : MQX error code
* Comments         :
*    This function installs given user callback for RTC module.
*
*END*********************************************************************/
uint_32 _rtc_int_install
(
    /* [IN] pointer to user ISR code */
    INT_ISR_FPTR isr
)
{
    if( isr == NULL )
    {
        return MQX_INVALID_POINTER;
    }
    user_isr = isr;
    return MQX_OK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_int_enable
* Returned Value   : bitmask of new int enable state
* Comments         :
*    This function enables/disables RTC interrupts according to specified bitmask.
*
*END*********************************************************************/
uint_32 _rtc_int_enable
(
    /* [IN] whether to enable or disable interrupts */
    boolean enable,
    /* [IN] bitmask of affected interrupts */
    uint_32 bitmask
)
{
    if( enable == TRUE )
    {
        user_enables |= bitmask;
    }
    else
    {
        user_enables &= ~bitmask;
    }
    _bsp_int_init(INT_RTC, BSP_RTC_INT_LEVEL, 0, enable);
    return user_enables;
}


/*FUNCTION****************************************************************
*
* Function Name    : _rtc_clear_requests
* Returned Value   : none
* Comments         :
*    This function clears RTC interrupt requests according to given bitmask.
*
*END*********************************************************************/
void _rtc_clear_requests
(
    /* [IN] bitmask of affected interrupts */
    uint_32 bitmask
)
{
    user_requests &= ~bitmask;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_get_status
* Returned Value   : bitmask of actual RTC interrupt requests + RTC enabled bit
* Comments         :
*    This function returns bitmask of pending RTC interrupt requests along
*    with RTC enabled bit (bit MCF51XX_RTC_RTCISR_EN).
*
*END*********************************************************************/
uint_32 _rtc_get_status
(
    void
)
{
    RTC_MemMapPtr rtc = RTC_BASE_PTR;

    return ((rtc->SR & RTC_SR_TCE_MASK) ? user_requests : 0);
}

/*FUNCTION****************************************************************
*
* Function Name    : _is_leap_year
* Returned Value   : none
* Comments         :
*    This function returns 1 if year is leaf.
*
*END*********************************************************************/
static uint_32 _is_leap_year( uint_16 year )
{
    uint_32 result = 0;

    if( year % 4 == 0 )
    {
        /* leap year, add day */
        result = 1;
        if( year % 100 == 0)
        {
            /* is not leap year, substract day*/
            result = 0;
        }
        if( year % 400 == 0)
        {
            /* finally is leap year, get back one more day */
            result = 1;
        }
    }
    return result;
}

/*FUNCTION****************************************************************
*
* Function Name    : _real_time_to_sec
* Returned Value   : none
* Comments         :
*    This function convert date to secs since 1.1.1970 0:0:0".
*
*END*********************************************************************/
static uint_32 _date_to_sec( DATE_STRUCT_PTR time )
{
    #define SEC_IN_MIN  60
    #define SEC_IN_HOUR 3600
    #define SEC_IN_DAY  86400
    #define FEBRUARY    2
    #define ZERO_YEAR   1970

    static const uint_16 days_no_table[]= { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    uint_32 days = 0;
    uint_32 month;
    uint_32 year;

    days = 365 * (time->YEAR - ZERO_YEAR);
    /* get leap year */
    for( year = ZERO_YEAR; year < time->YEAR; year++)
    {
        days += _is_leap_year( year );
    }

    for( month = 1; month < time->MONTH; month++)
    {
        days+= days_no_table[month - 1];
        /* is leap year? */
        if( month == FEBRUARY )
        {
            days+= _is_leap_year( time->YEAR );
        }
    }

    days += time->DAY-1;
    return days*SEC_IN_DAY + time->HOUR*SEC_IN_HOUR + time->MINUTE*SEC_IN_MIN + time->SECOND;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_set_time
* Returned Value   : none
* Comments         :
*    This function sets the RTC time according to given time struct.
*
*END*********************************************************************/
void _rtc_set_time
(
    /* [IN] given time to be set as RTC time */
    RTC_TIME_STRUCT_PTR time
)
{
    RTC_MemMapPtr rtc = RTC_BASE_PTR;

    /* disable RTC */
    rtc->SR &= ~RTC_SR_TCE_MASK;
    /* set new time */
    rtc->TSR = time->seconds;
    /* enable RTC */
    rtc->SR |= RTC_SR_TCE_MASK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_get_time
* Returned Value   : none
* Comments         :
*    This function gets the RTC time and stores it in given time struct.
*
*END*********************************************************************/
void _rtc_get_time
(
    /* [OUT] this parameter gets actual RTC time */
    RTC_TIME_STRUCT_PTR time
)
{
    RTC_MemMapPtr rtc = RTC_BASE_PTR;

    time->seconds = rtc->TSR;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_update_TAR
* Returned Value   : none
* Comments         :
*    This function set stopwatch or alarm time to TAR register.
*
*END*********************************************************************/
static void _rtc_update_TAR( uint_32 user_enables_private )
{
    RTC_MemMapPtr rtc = RTC_BASE_PTR;
    uint_32 user_enables_tmp = user_enables_private & (RTC_ISR_STOPWATCH | RTC_ISR_ALARM);

    /* all disabled, no action */
    if(user_enables_tmp  == 0)
    {
        rtc->TAR = 0xFFFFFFFF; /* e2574: RTC: Writing RTC_TAR[TAR] = 0 does not disable RTC alarm */

        return;
    }

    if(user_enables_tmp == (RTC_ISR_STOPWATCH | RTC_ISR_ALARM))
    {
        user_enables_tmp = rtc->TSR;
        rtc->TAR = (alarm_time.seconds - user_enables_tmp <= sw_time.seconds - user_enables_tmp) ? alarm_time.seconds : sw_time.seconds;
    }
    else
    {
        rtc->TAR = (user_enables_private & RTC_ISR_ALARM) ? alarm_time.seconds : sw_time.seconds;
    }
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_set_alarm
* Returned Value   : none
* Comments         :
*    This function sets RTC alarm time according to given time struct.
*    Alarm happens immediately after match.
*
*END*********************************************************************/
void _rtc_set_alarm
(
    /* [IN] time to be set as RTC alarm time */
    RTC_TIME_STRUCT_PTR time
)
{
    alarm_time.seconds = time->seconds;
    user_enables |= RTC_ISR_ALARM;
    _rtc_update_TAR (user_enables);
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_get_alarm
* Returned Value   : none
* Comments         :
*    This function gets the RTC alarm time and stores it in given time struct.
*
*END*********************************************************************/
void _rtc_get_alarm
(
    /* [OUT] this parameter gets the RTC alarm time */
    RTC_TIME_STRUCT_PTR time
)
{
    time->seconds = 0;
    if( user_enables & RTC_ISR_ALARM )
    {
        time->seconds = alarm_time.seconds;
    }
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_set_stopwatch
* Returned Value   : none
* Comments         :
*    This function sets the RTC stopwatch decrementer value (minutes).
*    Stopwatch decrements each new RTC minute and stops (disables) at -1.
*
*END*********************************************************************/
void _rtc_set_stopwatch
(
    /* [IN] number of minutes to countdown */
    uint_32 minutes
)
{
    uint_32 stopwatch_time;
    RTC_MemMapPtr rtc = RTC_BASE_PTR;

    if( (int_32)minutes == -1)
    {
        user_enables &= ~RTC_ISR_STOPWATCH;
    }
    else
    {
        /* minutes to seconds */
        stopwatch_time = (minutes * 60) + rtc->TSR;
        sw_time.seconds = stopwatch_time;
        /* set stopwatch enable flag */
        user_enables |= RTC_ISR_STOPWATCH;
    }
    _rtc_update_TAR( user_enables );

}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_get_stopwatch
* Returned Value   : actual RTC minute stopwatch counter value
* Comments         :
*    This function returns the actual value of RTC stopwatch decrementer.
*
*END*********************************************************************/
uint_32 _rtc_get_stopwatch
(
    void
)
{
    uint_32 stopwatch_time;
    RTC_MemMapPtr rtc = RTC_BASE_PTR;

    if( user_enables & RTC_ISR_STOPWATCH )
    {
        if( sw_time.seconds >= rtc->TSR)
        {
            stopwatch_time = sw_time.seconds - rtc->TSR;
            return stopwatch_time / 60;
        }
    }
    return STOPWATCH_OFF;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_set_time_mqxd
* Returned Value   : actual RTC minute stopwatch counter value
* Comments         :
*    This function sets the RTC time according to mqx DATE_STRUCT.
*
*END*********************************************************************/

_mqx_int _rtc_set_time_mqxd (DATE_STRUCT_PTR time)
{
    RTC_TIME_STRUCT rtc_time;

    /* convert MQX_DATE to seconds */
    rtc_time.seconds = _date_to_sec( time );
    _rtc_set_time( &rtc_time );
    return MQX_OK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_get_time_mqxd
* Returned Value   : actual RTC minute stopwatch counter value
* Comments         :
*    This function returns rtc time to DATE_STRUCT.
*
*END*********************************************************************/

void _rtc_get_time_mqxd (DATE_STRUCT_PTR time)
{
    RTC_MemMapPtr rtc = RTC_BASE_PTR;
    TIME_STRUCT         rtc_time;

    rtc_time.SECONDS = rtc->TSR;
    rtc_time.MILLISECONDS=0;

    _time_to_date( &rtc_time, time );
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_set_alarm_mqxd
* Returned Value   : none
* Comments         :
*    This function sets RTC alarm time.
*    Alarm happens immediately after match.
*
*END*********************************************************************/

_mqx_int _rtc_set_alarm_mqxd (DATE_STRUCT_PTR time)
{
    RTC_TIME_STRUCT rtc_alarm;

    /* convert MQX_DATE to seconds */
    rtc_alarm.seconds = _date_to_sec( time );
    _rtc_set_alarm( &rtc_alarm );
    return MQX_OK;

}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_get_alarm_mqxd
* Returned Value   : none
* Comments         :
*    This function gets the RTC alarm time and stores it in DATE_STRUCT.
*
*END*********************************************************************/

void _rtc_get_alarm_mqxd (DATE_STRUCT_PTR time)
{
    TIME_STRUCT         rtc_time;

    rtc_time.SECONDS = alarm_time.seconds;
    rtc_time.MILLISECONDS=0;

    _time_to_date( &rtc_time, time );
}


/*FUNCTION****************************************************************
*
* Function Name    : _rtc_time_to_mqx_date
* Returned Value   : none
* Comments         :
*    This function transforms RTC time format to MQX date format.
*    Miliseconds are set to 0.
*
*END*********************************************************************/

void _rtc_time_to_mqx_date
(
    /* [IN] RTC time representation */
    RTC_TIME_STRUCT_PTR rtc_time,
    /* [OUT] MQX date representation */
    DATE_STRUCT_PTR     mqx_date
)
{
    TIME_STRUCT         time;

    time.SECONDS = rtc_time->seconds;
    time.MILLISECONDS=0;

    _time_to_date( &time, mqx_date );

}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_time_from_mqx_date
* Returned Value   : none
* Comments         :
*    This function transforms MQX date format to RTC time format.
*    Miliseconds are ignored.
*
*END*********************************************************************/

void _rtc_time_from_mqx_date
(
    /* [IN] MQX date representation */
    DATE_STRUCT_PTR     mqx_date,
    /* [OUT] RTC time representation */
    RTC_TIME_STRUCT_PTR rtc_time
)
{
    rtc_time->seconds = _date_to_sec( mqx_date );
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_sync_with_mqx
* Returned Value   : none
* Comments         :
*    This function synchronizes RTC time with MQX date.
*
*END*********************************************************************/

_mqx_int _rtc_sync_with_mqx
(
    /* [IN] whether to update MQX time (source is RTC) or RTC time (source is MQX) */
    boolean update_mqx
)
{
    RTC_TIME_STRUCT rtc_time;
    DATE_STRUCT     mqx_date;
    TIME_STRUCT     mqx_time;

    if (update_mqx == TRUE)
    {
        _rtc_get_time(&rtc_time);
        _rtc_time_to_mqx_date(&rtc_time, &mqx_date);
        _time_from_date(&mqx_date, &mqx_time);
        _time_set(&mqx_time);
    }
    else
    {
        _time_get(&mqx_time);
        _time_to_date(&mqx_time, &mqx_date);
        _rtc_time_from_mqx_date (&mqx_date, &rtc_time);
        _rtc_set_time (&rtc_time);
    }
    return MQX_OK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_time_to_mqx_time
* Returned Value   : none
* Comments         :
*    This function transforms RTC time format to MQX time format.
*    RTC time range is wider (65536 days vs. 49710 days), overflow is not checked,
*    miliseconds are set to 0.
*
*END*********************************************************************/

void _rtc_time_to_mqx_time
(
    /* [IN] RTC time representation */
    RTC_TIME_STRUCT_PTR rtc_time,
    /* [OUT] MQX time representation */
    TIME_STRUCT_PTR     mqx_time
)
{
    mqx_time->SECONDS = rtc_time->seconds;
    mqx_time->MILLISECONDS = 0;
}

/*FUNCTION****************************************************************
*
* Function Name    : _rtc_time_from_mqx_time
* Returned Value   : none
* Comments         :
*    This function transforms MQX time format to RTC time format.
*    MQX time range is shorter (49710 days vs. 65536 days), miliseconds are ignored.
*
*END*********************************************************************/

void _rtc_time_from_mqx_time
(
    /* [IN] MQX time representation */
    TIME_STRUCT_PTR     mqx_time,
    /* [OUT] RTC time representation */
    RTC_TIME_STRUCT_PTR rtc_time
)
{
     rtc_time->seconds = mqx_time->SECONDS;
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fseek.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fseek.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the function for setting the current location
*   in a file.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief This function sets the current file position.
 * 
 * \param[in] file_ptr The stream to use.
 * \param[in] offset   The offset for the seek.
 * \param[in] mode     Mode to determine where to start the seek from.
 * 
 * \return MQX_OK
 * \return IO_ERROR (Failure.) 
 */ 
_mqx_int _io_fseek
   (
      MQX_FILE_PTR file_ptr,
      _file_offset  offset,
      _mqx_uint  mode
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR dev_ptr;
   _mqx_int             result;

#if MQX_CHECK_ERRORS
    if (file_ptr == NULL) {
        return (IO_ERROR);
    } /* Endif */
#endif

    switch (mode) {
    case IO_SEEK_SET:
        if (offset < 0) {
            return IO_ERROR;
        }
        file_ptr->LOCATION = offset;
        break;
    case IO_SEEK_CUR:
        /* Adjust possibly fake location before relative seek */
        if (file_ptr->HAVE_UNGOT_CHARACTER && (file_ptr->LOCATION > 0)) {
            offset--;
        }
        if (offset < 0 && (file_ptr->LOCATION < (_file_size) (-offset))) {
            return IO_ERROR;
        }
        file_ptr->LOCATION += offset;
        break;
    case IO_SEEK_END:
        if (offset < 0 && (file_ptr->SIZE < (_file_size) (-offset))) {
            return IO_ERROR;
        }
        file_ptr->LOCATION = file_ptr->SIZE + offset;
        break;
#if MQX_CHECK_ERRORS
    default:
        return (IO_ERROR);
#endif
    } /* Endswitch */

    /* Empty ungetc buffer */
    if (file_ptr->HAVE_UNGOT_CHARACTER) {
        file_ptr->HAVE_UNGOT_CHARACTER = FALSE;
    }

    /* Clear EOF flag */
    file_ptr->FLAGS &= ~((_mqx_uint) IO_FLAG_AT_EOF);

    dev_ptr = file_ptr->DEV_PTR;
    if (dev_ptr->IO_IOCTL != NULL) {
        result = (*dev_ptr->IO_IOCTL)(file_ptr, IO_IOCTL_SEEK, NULL);
        if (result != IO_ERROR_INVALID_IOCTL_CMD)
            return result;
    } /* Endif */

    return (MQX_OK);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/kadc/adc_kadc.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_kadc.h$
* $Version : 3.8.11.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END************************************************************************/

#ifndef __adc_kadc_h__
#define __adc_kadc_h__

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

/* NOTE:
** For 13 bit differential mode use ADC_RESOLUTION_12BIT
** For 11 bit differential mode use ADC_RESOLUTION_10BIT
** For 9 bit differential mode use ADC_RESOLUTION_8BIT
*/
#define ADC_RESOLUTION_16BIT    ADC_CFG1_MODE(0x03)
#define ADC_RESOLUTION_12BIT    ADC_CFG1_MODE(0x01)
#define ADC_RESOLUTION_10BIT    ADC_CFG1_MODE(0x02)
#define ADC_RESOLUTION_8BIT     ADC_CFG1_MODE(0x00)
#define ADC_RESOLUTION_DEFAULT (ADC_RESOLUTION_16BIT)

#define ADC_SOURCE_CHANNEL(x)   (x)
#define ADC_SOURCE_MUXSEL_SHIFT (9)
#define ADC_SOURCE_MUXSEL_X     (0x0000) /* none of A / B is forced to use */
#define ADC_SOURCE_MUXSEL_A     (0x0200) /* the A pair is forced to use */
#define ADC_SOURCE_MUXSEL_B     (0x0400) /* the B pair is forced to use */
#define ADC_SOURCE_DIFF         (0x0800)
#define ADC_SOURCE_MODULE_SHIFT (12)
#define ADC_SOURCE_MODULE(x)    (x << ADC_SOURCE_MODULE_SHIFT)
#define ADC_SOURCE_MODULE_ANY   ADC_SOURCE_MODULE(0x00)

#define ADC_GET_CHANNEL(x)  ((x) & 0x001F)
#define ADC_GET_MUXSEL(x)   ((x) & 0x0600)
#define ADC_GET_DIFF(x)     ((x) & 0x0800)
#define ADC_GET_MODULE(x)   ((x) & 0xF000)


#define ADC_PDB_TRIGGER           (0x10000) /* HW specific trigger(s) must be controlled by hardware */

/*
**  IOCTL ADC16 hardware specific commands used in driver
*/
#define ADC_IOCTL_CALIBRATE          _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 0)
#define ADC_IOCTL_SET_CALIBRATION    _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 1)
#define ADC_IOCTL_GET_CALIBRATION    _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 2)
#define ADC_IOCTL_SET_LONG_SAMPLE    _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 3)
#define ADC_IOCTL_SET_SHORT_SAMPLE   _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 4)
#define ADC_IOCTL_SET_HIGH_SPEED     _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 5)
#define ADC_IOCTL_SET_LOW_SPEED      _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 6)
#define ADC_IOCTL_SET_HW_AVERAGING   _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 7)
#define ADC_IOCTL_SET_IDELAY         _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 8)
#define ADC_IOCTL_SET_IDELAYREG      _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 9)
#define ADC_IOCTL_SET_IDELAY_FCN     _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 10)
#define ADC_IOCTL_SET_ERROR_FCN      _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 11)
#define ADC_IOCTL_SET_IDELAY_PROCESS _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 12)
#define ADC_IOCTL_SET_INT_PROCESS    _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 13)
#define ADC_IOCTL_SET_BASE_PERIOD    _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 14)
#define ADC_IOCTL_TRIM_BASE_PERIOD   _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 15)
#define ADC_IOCTL_SET_OFFSET         _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 16)
#define ADC_IOCTL_SET_PLUS_GAIN      _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 17)
#define ADC_IOCTL_SET_MINUS_GAIN     _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 18)
#define ADC_IOCTL_SET_THOLD          _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 19)
#define ADC_IOCTL_SET_THOLD_FCN      _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 20)
#define ADC_IOCTL_SET_DELAYREG       _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 21)
#define ADC_IOCTL_SET_TRIGGER        _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 22)
#define ADC_IOCTL_SET_REFERENCE      _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 23)
#define ADC_IOCTL_SET_PGA_GAIN       _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 24)
#define ADC_IOCTL_GET_PGA_GAIN       _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 25)
#define ADC_IOCTL_ENABLE_CHOPPING    _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 26)
#define ADC_IOCTL_DISABLE_CHOPPING   _IO(IO_TYPE_ADC, ADC_IOCTL_HW_SPECIFIC + 27)

/*
**  ADC16 hardware specific errors
*/
#define ADC_ERROR_PERIOD             (ADC_ERROR_BASE | (ADC_ERROR_HW_SPECIFIC + 0x00)) /* cannot run if basic period was not set */
#define ADC_ERROR_HWTRIGGER          (ADC_ERROR_BASE | (ADC_ERROR_HW_SPECIFIC + 0x01)) /* only HW trigger is supported */
#define ADC_ERROR_NOT_SUPPORTED      (ADC_ERROR_BASE | (ADC_ERROR_HW_SPECIFIC + 0x02)) /* the operation is not supported because of HW limitations */

/*
** kadc16_calib_struct
** Structure used to store ADC16 calibration data
*/
typedef struct kadc_calib_struct
{
    uint_16 OFS;     /*** Offset Correction Register                        ***/
    uint_16 PG;      /*** Plus-Side Gain Register                           ***/
#if ADC_HAS_DIFFERENTIAL_CHANNELS
    uint_16 MG;      /*** Minus-Side Gain Register                          ***/
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */
    uchar   CLPD;    /*** Plus-Side General Calibration Value Register D    ***/
    uchar   CLPS;    /*** Plus-Side General Calibration Value Register S    ***/
    uint_16 CLP4;    /*** Plus-Side General Calibration Value Register 4    ***/
    uint_16 CLP3;    /*** Plus-Side General Calibration Value Register 3    ***/
    uchar   CLP2;    /*** Plus-Side General Calibration Value Register 2    ***/
    uchar   CLP1;    /*** Plus-Side General Calibration Value Register 1    ***/
    uchar   CLP0;    /*** Plus-Side General Calibration Value Register 0    ***/
#if ADC_HAS_DIFFERENTIAL_CHANNELS
    uchar   CLMD;    /*** Minus-Side General Calibration Value Register D   ***/
    uchar   CLMS;    /*** Minus-Side General Calibration Value Register S   ***/
    uint_16 CLM4;    /*** Minus-Side General Calibration Value Register 4   ***/
    uint_16 CLM3;    /*** Minus-Side General Calibration Value Register 3   ***/
    uchar   CLM2;    /*** Minus-Side General Calibration Value Register 2   ***/
    uchar   CLM1;    /*** Minus-Side General Calibration Value Register 1   ***/
    uchar   CLM0;    /*** Minus-Side General Calibration Value Register 0   ***/
#endif /* ADC_HAS_DIFFERENTIAL_CHANNELS */
} KADC_CALIB_STRUCT;
typedef volatile struct kadc_calib_struct _PTR_ KADC_CALIB_STRUCT_PTR;

typedef enum {
    ADC_CLK_BUSCLK,     /* selects BUSCLK */
    ADC_CLK_BUSCLK2,    /* selects BUSCLK/2 */
    ADC_CLK_BUSCLK_ANY, /* selects BUSCLK or BUSCLK/2 */
    ADC_CLK_ALTERNATE,
    ADC_CLK_ASYNC
} ADC_CLOCK_SOURCE;

typedef enum {
    ADC_DIV_1 = 0,
    ADC_DIV_2 = 1,
    ADC_DIV_4 = 2,
    ADC_DIV_8 = 3,
    ADC_DIV_ANY = -1 /* selects automatically the fastest one */
} ADC_CLOCK_DIV;

typedef enum {
    ADC_LPC_LOW =    ADC_CFG1_ADLPC_MASK, /* use low power of ADC (reduces max. ADCCLK frequency) */
    ADC_LPC_NORMAL = 0                    /* use normal power of ADC */
} ADC_LPC;

typedef enum {
    ADC_HSC_NORMAL = ADC_CFG2_ADHSC_MASK, /* use normal speed */
    ADC_HSC_HIGH = 0                      /* use high speed */
} ADC_HSC;

typedef enum {
    ADC_PDB_COMP1OUT = 0,   /* Comparator 1 output trigger */
    ADC_PDB_COMP2OUT = 4,   /* Comparator 2 output trigger */
    ADC_PDB_EXTRIG   = 16,  /* External event trigger */
    ADC_PDB_SWTRIG   = 28   /* Software trigger */
} ADC_PDB_TRIGSEL;

typedef enum {
    ADC_REF_VREF, /* internal voltage reference */
    ADC_REF_VALT, /* alternate voltage reference */
    ADC_REF_VBG   /* internal bandgap Vbgh and Vbgl */
} ADC_REFERENCE;

#if ADC_HAS_PGA
typedef enum {
    ADC_PGA_GAIN_1   = ADC_PGA_PGAG(0),
    ADC_PGA_GAIN_2   = ADC_PGA_PGAG(1),
    ADC_PGA_GAIN_4   = ADC_PGA_PGAG(2),
    ADC_PGA_GAIN_8   = ADC_PGA_PGAG(3),
    ADC_PGA_GAIN_16  = ADC_PGA_PGAG(4),
    ADC_PGA_GAIN_32  = ADC_PGA_PGAG(5),
    ADC_PGA_GAIN_64  = ADC_PGA_PGAG(6)
} ADC_PGA_GAIN;
#endif /* ADC_HAS_PGA */
/*
** PDB INSTALL_STRUCT
**
** This structure defines the initialization parameters to be used
** for PDB initialization within ADC init
*/
typedef struct kpdb_install_struct
{
    /* PDB interrupt vector */
    uint_32 IDELAY_VECTOR;

    /* PDB interrupt priority */
    uint_32 IDELAY_PRIORITY;

    /* PDB race condition interrupt vector */
    uint_32 ERROR_VECTOR;

    /* PDB race condition interrupt priority */
    uint_32 ERROR_PRIORITY;

} KPDB_INIT_STRUCT, _PTR_ KPDB_INIT_STRUCT_PTR;

/*
** ADC_INSTALL_STRUCT
**
** This structure defines the initialization parameters to be used
** when ADC driver is  port is installed.
*/
typedef struct kadc_install_struct
{
    /* The number of ADC peripheral, use adc_t enum from PSP */
    uint_8 ADC_NUMBER;

    /* The clock source */
    ADC_CLOCK_SOURCE CLOCK_SOURCE;

    /* The clock divisor for ADC */
    ADC_CLOCK_DIV CLOCK_DIV;

    /* ADC high speed control, see ADC_HSC enum */
    ADC_HSC SPEED;

    /* ADC low power control, see ADC_LPC enum */
    ADC_LPC POWER;

    /* The calibration data pointer */
    uint_8_ptr CALIBRATION_DATA_PTR;

    /* ADC interrupt vector */
    uint_32 ADC_VECTOR;

    /* ADC interrupt vector */
    uint_32 ADC_PRIORITY;

    /* KPDB init structure */
    const KPDB_INIT_STRUCT * PDB_INIT;

} KADC_INIT_STRUCT, _PTR_ KADC_INIT_STRUCT_PTR;

typedef void (_CODE_PTR_ PDB_INT_FCN)(void);

pointer  _bsp_get_adc_base_address(_mqx_uint);
pointer  _bsp_get_pdb_base_address(void);
int_16   _pdb_get_prescaler(void);
_mqx_int _pdb_set_prescaler(int_16 prescaler, int_16 multiplier);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/Diagnostic_print.h<|end_filename|>
#ifndef __DIAGNOSTIC_PRINT_H
  #define __DIAGNOSTIC_PRINT_H

void Print_reset_source(void);
void Print_Flash_identify(void);
void Print_CPU_identify(void);
void Print_USB_FS_regs(void);


#endif


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/SWLIBS_Inlines.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     SWLIBS_Inlines.h
*
* @author   <NAME>, <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Basic inline functions definition file.
*
*******************************************************************************
* This file shall be included only after inclusion of SWLIBS_Typedefs.h
******************************************************************************/
#ifndef _SWLIBS_INLINES_H
#define _SWLIBS_INLINES_H

#ifdef __cplusplus
extern "C" {
#endif
	
#include "SWLIBS_Defines.h"

#if defined(__CWCC__)
	#include "intrinsic_cw.h"
	#undef __STATIC_INLINE
	#define __STATIC_INLINE static inline	
#elif defined(__IAR_SYSTEMS_ICC__)
	#include <intrinsics.h>
	#undef __STATIC_INLINE
	#define __STATIC_INLINE static inline
#elif defined(__CC_ARM)	
	#include "MK40N512MD100.h"		//has to be here, without this include it does not work - it is device dependent - should be change
#endif	

	
/******************************************************************************
| defines and macros            (scope: module-local)
|----------------------------------------------------------------------------*/


/******************************************************************************
| Typedefs and structures       (scope: module-local)
|----------------------------------------------------------------------------*/

/******************************************************************************
| Exported variables
|----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
|----------------------------------------------------------------------------*/

/******************************************************************************
| Inline functions
|----------------------------------------------------------------------------*/

/*------------------------------------------------------------------------*//*!

@brief      Absolute value of 16-bit fractional type.

@return     Absolute value of the input argument.

@note       Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16 F16Abs(register Frac16 x)
{
    return (Frac16) ((x<0) ? -(x):(x));
}

/*------------------------------------------------------------------------*//*!

@brief      Absolute value with overflow control of 16-bit fractional
            number.

@return     Absolute value of the input argument.

@note       Overflow is detected and the function saturates if the result
            does not fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16AbsSat(register Frac16 x)
{
    register Word32 y;

    y = (F16TOINT32(x)<0) ? -F16TOINT32(x):F16TOINT32(x);
    y = (y == -(Word32) INT16_MIN) ? (Word32) INT16_MAX:y;

    return INT32TOF16(y);
}

/*------------------------------------------------------------------------*//*!

@brief       Negative value of 16-bit fraction type.

@return      Negative value of the input argument.

@note        Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Neg(register Frac16 x)
{
    return (Frac16) (-x);
}

/*------------------------------------------------------------------------*//*!

@brief       Negative value with overflow control of 16-bit fraction type.

@return      Negative value of the input argument.

@note        Overflow is detected and the function saturates if the result
             cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16NegSat(register Frac16 x)
{
    register Word32 y;

    y = -F16TOINT32(x);
    y = (y == -(Word32) INT16_MIN) ? (Word32) INT16_MAX:y;

    return INT32TOF16(y);
}

/*------------------------------------------------------------------------*//*!

@brief        Add two fractional 16-bit values.

@return       Sum of the input arguments.

@note         Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Add(register Frac16 x, register Frac16 y)
{
    return (Frac16) (x + y);
}

/*------------------------------------------------------------------------*//*!

@brief        Add with overflow control two fractional 16-bit values.

@return       Sum of the input arguments.

@note         Overflow is detected. The function saturates the return
              value if it cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16AddSat(register Frac16 x, register Frac16 y)
{
    return __QADD16(x,y);
}

/*------------------------------------------------------------------------*//*!

@brief        Subtraction of two fractional 16-bit values. The second
              argument is subtracted from the first one.

@return       The subtraction of the second argument from the first argument.

@note         Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Sub(register Frac16 x, register Frac16 y)
{
    return (Frac16) (x - y);
}

/*------------------------------------------------------------------------*//*!

@brief        Subtraction with overflow control of two fractional 16-bit
              numbers. The second argument is subtracted from the first one.

@return       The subtraction of the second argument from the first argument.

@note         Overflow is detected. The function saturates the return
              value if it cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16SubSat(register Frac16 x, register Frac16 y)
{
        return __QSUB16(x,y);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional multiplication of two fractional 16-bit values.

@return       16 most significant bits of fractional multiplication of the
              input arguments. The extra bits beyond the 16-bit boundary
              are discarded.

@note         Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Mul(register Frac16 x, register Frac16 y)
{
	return INT32TOF16((F16TOINT32(x)*F16TOINT32(y))>>15);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional multiplication of two fractional 16-bit values.

@return       16 most significant bits of fractional multiplication of the
              input arguments. The extra bits beyond the 16-bit boundary
              are discarded.

@note         Overflow is detected. The functions saturates the return
              value if it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16MulSat(register Frac16 x, register Frac16 y)
{
	register Word32 z;

	z = (Word32) (((Word32) x)*((Word32) y)>>15);

	z = (z > (Word32) INT16_MAX) ? (Word32) INT16_MAX:z;

	return INT32TOF16(z);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional division of two 16-bit numbers. The first argument
              is the numerator and the second one is the denominator.

@return       15 most significant bits of fractional division of the first
              by the second argument. The extra bits beyond the 15-bit boundary
              are discarded.

@note         Overflow is not detected. The first argument must be lower
              in magnitude than the second argument, otherwise the result
              is undefined.

              If the return value cannot be represented by the 16-bit
              fractional format due to finite resolution, the return value is
              rounded toward zero.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Div(register Frac16 x, register Frac16 y)
{
	register Word32 n;
	register Word32 d;
	register Word32 q;

	n = F16TOINT32(x)<<15;
	d = F16TOINT32(y);
	q = n/d;

	return INT32TOF16(q);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional division of a 32-bit by a 16-bit numbers. The first
              32-bit argument is the numerator and the second 16-bit argument
              is the denominator.

@return       15 most significant bits of fractional division of the first
              by the second argument. The extra bits beyond the 15-bit boundary
              are discarded.

@note         Overflow is not detected. The first argument must be lower
              in magnitude than the second argument, otherwise the result
              is undefined.

              If the return value cannot be represented by the 16-bit
              fractional format due to finite resolution, the return value is
              rounded down (so called rounding toward minus infinity). It should
              be noticed that the used rounding mode is different from the
              rounding mode used in the integer division (rounding toward zero).
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16DivF32F16(register Frac32 x, register Frac16 y)
{
	register Word32 n;
	register Word32 d;
	register Word32 q;

	n = F32TOINT32(x);
	d = F16TOINT32(y);
	q = n/d;
	q >>= 1;

	return INT32TOF16(q);
}

/*------------------------------------------------------------------------*//*!

@brief        Right, bidirectional shift of 16-bit fractional value (x)
              by the specified shift amount (s).

@return       16-bit fractional value shifted by the shift amount, right
              is the positive direction. The bits beyond the 16-bit
              boundary of the results are discarded.

@note         Overflow is not detected.

              The shift amount cannot exceed in magnitude the bit-width of
              the shift value, that means must be within the range -16...16.
              Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Shr(register Frac16 x, register Word16 s)
{
    return (Frac16) ((s<0) ? x<<(-s):x>>s);
}

/*------------------------------------------------------------------------*//*!

@brief        Right, bidirectional shift of 16-bit fractional value with
              overflow control.

@return       16-bit fractional value shifted by the shift amount, right is
              the positive direction. The bits beyond the 16-bit boundary
              are discarded.

@note         Overflow is detected and the function saturates if the return
              value cannot fit into the return type.

              The shift amount cannot exceed in magnitude the bit-width of
              the shift value, that means must be within the range -16...16.
              Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16ShrSat(register Frac16 x, register Word16 s)
{
    register Word32 xl;

    xl = F16TOINT32(x);
    if ( s < 0 )
    {
        xl = xl << (-s);
        xl = (xl < (Word32) INT16_MIN) ? (Word32) INT16_MIN:xl;
        xl = (xl > (Word32) INT16_MAX) ? (Word32) INT16_MAX:xl;
    }
    else
    {
        xl = xl >> s;
    }

    return INT32TOF16(xl);
}

/*------------------------------------------------------------------------*//*!

@brief        Left, bidirectional shift of 16-bit fractional value.

@return       16-bit fractional value shifted by the shift amount, left is
              the positive direction. The bits beyond the 16-bit boundary
              are discarded.

@note         Overflow is not detected.

              The shift amount cannot exceed in magnitude the bit-width of
              the shift value, that means must be within the range -16...16.
              Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Shl(register Frac16 x, register Word16 s)
{
    return INT32TOF16((s<0) ? F16TOINT32(x)>>(-s):F16TOINT32(x)<<s);
}

/*------------------------------------------------------------------------*//*!

@brief        Left, bidirectional shift of 16-bit fractional value with
              overflow control.

@return       16-bit fractional value shifted by the shift amount, left is
              the positive direction. The bits beyond the 16-bit boundary
              are discarded.

@note         Overflow is detected. The function returns a saturated
              fractional value if the return value cannot fit into the return
              type.

              The shift amount cannot exceed in magnitude the bit-width of
              the shift value, that means must be within the range -16...16.
              Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16ShlSat(register Frac16 x, register Word16 s)
{
    register Word32 xl;

    xl = F16TOINT32(x);
    if ( s < 0 )
    {
        xl = xl >> (-s);
    }
    else
    {
        xl = xl << s;
        xl = (xl < (Word32) INT16_MIN) ? (Word32) INT16_MIN:xl;
        xl = (xl > (Word32) INT16_MAX) ? (Word32) INT16_MAX:xl;
    }

    return INT32TOF16(xl);
}

/*------------------------------------------------------------------------*//*!

@brief        Right, unidirectional shift of 16-bit fractional value (x) by
              the specified shift amount (s).

@return       16-bit fractional value shifted right by the shift amount.
              The bits beyond the 16-bit boundary of the result are discarded.

@note         This is the unidirectional right shift.

              The shift amount cannot exceed in magnitude the bit-width of
              the shifted value, that means it must be within the range 0...15.
              Otherwise the result of the function is undefined.

@warning      This function is target dependent.  The shift result for the
              negative value to be shifted may be undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Shruni(register Frac16 x, register UWord16 s)
{
    return (Frac16) (x>>s);
}

/*------------------------------------------------------------------------*//*!

@brief        Counts the number of left shift needed for normalization of
              the input 16-bit fractional value

@return       The number of left shift needed to normalize the argument.
              For the input 0 returns 0.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Word16
F16Norm(register Frac16 x)
{
	register Word32 sham;
	register Word32 shdel;
	register Word32 xlsh;
	register Word32 xl;
	register Word32 b;

	if ( x == 0)
	{
		return 0;
	}

	b = (x >= 0) ? 0x00007fff:0x00008000;

	sham = 0;
	shdel = 8;
	xl = (x<0) ? -F16TOINT32(x):F16TOINT32(x);

	do
	{
		sham = sham + shdel;
		xlsh = xl << sham;
		sham = (xlsh > b) ? sham - shdel:sham;
		shdel >>= 1;
	} while ( shdel > 0 );

	return (Word16) sham;
}

/*------------------------------------------------------------------------*//*!

@brief        Rounds the input 32-bit fractional value to 16-bit fractional
              value.

@return       Round to 16-bit fractional value.

@note         Rounding is performed by adding 0x00008000 to the 32-bit
              argument (round to nearest). Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Roundton(register Frac32 x)
{
return INT32TOF16((F32TOINT32(x) + 0x00008000)>>16);
}

/*------------------------------------------------------------------------*//*!

@brief        Rounds the input 32-bit fractional value to 16-bit fractional
              value.

@return       Round to 16-bit fractional value.

@note         Rounding is performed by adding 0x00008000 to the 32-bit
              argument (round to nearest). Overflow is detected. The function
              saturates. if the return value does not fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16RoundtonSat(register Frac32 x)
{
	register Word32 y;

	y = F32TOINT32(x) + 0x00008000;
	y = (F32TOINT32(x) >= 0x7fff8000) ? F32TOINT32(x):y;

	return INT32TOF16(y>>16);
}

/*------------------------------------------------------------------------*//*!

@brief      Absolute value of 32-bit fractional type.

@return     Absolute value of the input argument.

@note       Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Abs(register Frac32 x)
{
    return (x<0) ? -x:x;
}

/*------------------------------------------------------------------------*//*!

@brief      Absolute value with overflow control of 32-bit fractional type.

@return     Absolute value of the input argument.

@note       Overflow is detected and the function saturates the result if
            it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32AbsSat(register Frac32 x)
{
    register Word32 y;

    y = (F32TOINT32(x)<0) ? -F32TOINT32(x):F32TOINT32(x);
    y = (y == INT32_MIN) ? INT32_MAX:y;

    return INT32TOF32(y);
}

/*------------------------------------------------------------------------*//*!

@brief       Negative value of 32-bit fraction type.

@return      Negative value of the input argument.

@note        Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Neg(register Frac32 x)
{
    return -x;
}

/*------------------------------------------------------------------------*//*!

@brief       Negative value with overflow control of 32-bit fraction type.

@return      Negative value of the input argument.

@note        Overflow is detected and the function saturates if the result
             cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32NegSat(register Frac32 x)
{
    register Word32 y;

    y = -F32TOINT32(x);
    y = (y == INT32_MIN) ? INT32_MAX:y;

    return INT32TOF32(y);
}

/*------------------------------------------------------------------------*//*!

@brief        Add two fractional 32-bit values.

@return       Sum of the input arguments.

@note         Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Add(register Frac32 x, register Frac32 y)
{
 return x + y;
}

/*------------------------------------------------------------------------*//*!

@brief        Add with overflow control two fractional 32-bit values.

@return       Sum of the input arguments.

@note         Overflow is detected. The function saturates the return
              value if it cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32AddSat(register Frac32 x, register Frac32 y)
{
    return __QADD(x,y);
}

/*------------------------------------------------------------------------*//*!

@brief        Subtraction of two fractional 32-bit values. The second
              argument is subtracted from the first one.

@return       The subtraction of the second argument from the first argument.

@note         Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Sub(register Frac32 x, register Frac32 y)
{
 return x - y;
}

/*------------------------------------------------------------------------*//*!

@brief        Subtraction with overflow control of two fractional 32-bit
              numbers. The second argument is subtracted from the first one.

@return       The subtraction of the second argument from the first argument.

@note         Overflow is detected. The function saturates the return
              value if it cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32SubSat(register Frac32 x, register Frac32 y)
{
    return __QSUB (x,y);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional multiplication of two fractional 16-bit values.

@return       All 32 bits of fractional multiplication of the two 16-bit
              input arguments.

@note         Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MulF16F16(register Frac16 x, register Frac16 y)
{
	return INT32TOF32((F16TOINT32(x)*F16TOINT32(y))<<1);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional multiplication of two fractional 16-bit values with
              overflow detection.

@return       All 32 bits of fractional multiplication of the two 16-bit
              input arguments.

@note         Overflow is detected. The functions saturates the return
              value if it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MulSatF16F16(register Frac16 x, register Frac16 y)
{
	register Word32 m;

	m = (F16TOINT32(x)*F16TOINT32(y))<<1;
	m = (m == INT32_MIN) ? INT32_MAX:m;

	return INT32TOF32(m);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional multiplication of two fractional 32-bit values.

@return       32 most significant bits of fractional multiplication of the
              input arguments.

@note         Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Mul(register Frac32 x, register Frac32 y)
{
	return INT32TOF32((Word32) ((F32TOINT64(x)*F32TOINT64(y))>>31));
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional multiplication of two fractional 32-bit values.

@return       32 most significant bits of fractional multiplication of the
              input arguments.

@note         Overflow is detected. The functions saturates the return
              value if it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MulSat(register Frac32 x, register Frac32 y)
{
	register Word32 z;

	z = (Word32) ((F32TOINT64(x)*F32TOINT64(y))>>31);
	z = (z == INT32_MIN) ? INT32_MAX:z;

	return INT32TOF32(z);
}

/*------------------------------------------------------------------------*//*!

@brief        Multiply two 16-bit fractional values and accumulate with
              a 32-bit fractional value.

@return       All bits of the multiply-and-accumulate operation.

@note         Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MacF16F16(register Frac32 a, register Frac16 x, register Frac16 y)
{
	return INT32TOF32((F32TOINT32(a) + (Word32) ((F32TOINT16(x)*F32TOINT16(y))<<1)));
}

/*------------------------------------------------------------------------*//*!

@brief        Multiply two 16-bit fractional values and accumulate with
              a 32-bit fractional value. Perform overflow control.

@return       All bits of the multiply-and-accumulate operation.

@note         Overflow is detected. The functions saturates the return
              value if it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MacSatF16F16(register Frac32 a, register Frac16 x, register Frac16 y)
{
	register Word32 m;

	m = F32TOINT32(x)*F32TOINT32(y);
	m <<=1;

	return __QADD(a,m);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional division of two 32-bit values. The first argument is
              the numerator and the second one is the denominator.

@return       31 most significant bits of the result of the fractional
              division of the first by the second argument. The extra bits
              beyond the 31-bit boundary are discarded.

@note         Overflow is not detected. The first argument must be lower in
              magnitude than the second argument, otherwise the result is
              undefined.

              If the return value cannot be represented by the 32-bit
              fractional format due to finite resolution, the return value is
              rounded toward zero.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Word32 F32DivNorm(register UWord32 x)
{
    register Word32 b;
    register Word32 m;
    register Word32 mm;
    register Word32 mmp;
    register Word32 mmn;

    m = 15;

    mmp = 8;
    mmn = -8;
    b = 1<<m;
    mm = (x >= b) ? mmp:mmn;
    m += mm;

    mmp = 4;
    mmn = -4;
    b = 1<<m;
    mm = (x >= b) ? mmp:mmn;
    m += mm;

    mmp = 2;
    mmn = -2;
    b = 1<<m;
    mm = (x >= b) ? mmp:mmn;
    m += mm;

    mmp = 1;
    mmn = -1;
    b = 1<<m;
    mm = (x >= b) ? mmp:mmn;
    m += mm;

    mmp = 0;
    b = 1<<m;
    mm = (x >= b) ? mmp:mmn;
    m += mm;

    m = 30 - m;

    return m;
}

__STATIC_INLINE Frac32
F32Div(register Frac32 x, register Frac32 y)
{
    register UWord32 dh;
    register UWord32 dl;
    register Word32 q;
    register UWord32 n;
    register UWord32 nlsb;
    register UWord32 d;
    register UWord32 qh;
    register UWord32 ql;
    register UWord32 r1;
    register UWord32 r2;
    register Word64 r;
    register Word32 sign;
    register Word32 m;

    /* Special case for denominator at minimum.
     */
    if ( y == 0x80000000 )
    {
        return -x;
    }

    /* Record the sign and make argument absolute */
    sign = x^y;
    n = (UWord32) ((F32TOINT32(x) < 0) ? -F32TOINT32(x):F32TOINT32(x));
    d = (UWord32) ((F32TOINT32(y) < 0) ? -F32TOINT32(y):F32TOINT32(y));

    /* Normalize denominator and numerator*/
    m = F32DivNorm(d);
    d <<= m;
    n <<= m;

    /* Record lsb of n*/
    nlsb = (n & 0x00000001)<<15;

    dh = d>>16;
    dl = 0x0000ffff & d;

    /* Compute tentative 15 higher bits of the quotient */
    qh = n/dh;

    /* Limit the quotient to avoid overflow */
    qh = (qh > 0x0000ffff) ? 0x0000ffff:qh;

    /* Shift down to avoid overflow, lsb of n is discarded */
    qh >>= 1;
    n >>= 1;

    /* Compute the first remainder */
    r1 = qh*dh;
    r2 = qh*dl;
    r1 = n-r1;
    r = ((Word64) r1)<<16;
    r = r - r2;

    /* Retrieve lsb of n */
    r += nlsb;

    /* Make appropriate correction */
    if ( r < 0 )
    {
	r = r + d;
	qh = qh - 1;
    }

    if ( r < 0 )
    {
	r = r + d;
	qh = qh - 1;
    }

    /* Compute tentative 16 lower bits of the quotient */
    n = (UWord32) r;
    ql = n/dh;

    /* Limit the quotient to avoid overflow */
    ql = (ql > 0x0000ffff) ? 0x0000ffff:ql;

    /* Compute the second remainder */
    r1 = ql*dh;
    r2 = ql*dl;
    r1 = n-r1;
    r = ((Word64) r1)<<16;
    r = r - r2;

    /* Make appropriate correction */
    if ( r < 0 )
    {
	ql = ql - 1;
	r = r + d;
    }
    if ( r < 0 )
    {
	ql = ql - 1;
	r = r + d;
    }
    if ( r < 0 )
    {
	ql = ql - 1;
	r = r + d;
    }
    if ( r < 0 )
    {
	ql = ql - 1;
	r = r + d;
    }

    /* Combine the higer and lower bits of the quotient */
    q = (Word32) ((qh<<16) | ql);

    /* Correct sign */
    q = (sign < 0) ? -q:q;

    return INT32TOF32(q);
}

/*------------------------------------------------------------------------*//*!

@brief        Fractional division of a 32-bit by a 16-bit numbers. The first
              32-bit argument is the numerator and the second 16-bit argument
              is the denominator.

@return       31 most significant bits of the fractional division of the first
              by the second argument. The extra bits beyond the 31-bit boundary
              are discarded.

@note         Overflow is not detected. The first argument must be lower
              in magnitude than the second argument, otherwise the result
              is undefined.

              If the return value cannot be represented by the 32-bit
              fractional format due to finite resolution, the return value
              is rounded toward zero.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32DivF32F16(register Frac32 x, register Frac16 y)
{
    register UWord32 n;
    register UWord32 d;
    register Word32 r;
    register Word32 q;
    register UWord32 qh;
    register UWord32 ql;
    register Word32 sign;

    n = (UWord32) ((x < 0) ? -F32TOINT32(x):F32TOINT32(x));
    d = (UWord32) ((y < 0) ? -F16TOINT32(y):F16TOINT32(y));
    sign = x^(y<<16);
    qh = n/d;
    r = (Word32) (n - qh*d);
    r <<= 16;
    ql = r/d;
    ql >>= 1;
    qh <<=15;
    q = (Word32) (qh | ql);
    q = (sign < 0) ? -q:q;

    return INT32TOF32(q);
}

/*------------------------------------------------------------------------*//*!

@brief        Right, bidirectional shift of 32-bit fractional value (x) by
              the specified shift amount (s).

@return       32-bit fractional value shifted by the shift amount, right is
              the positive direction. The bits beyond the 32-bit boundary
              of the results are discarded.

@note         Overflow is not detected.

              The shift amount cannot exceed in magnitude the bit-width of
              the shift value, that means must be within the range -32...32.
              Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Shr(register Frac32 x, register Word32 s)
{
    return (s<0) ? x<<(-s):x>>s;
}

/*------------------------------------------------------------------------*//*!

@brief        Right, bidirectional shift of 32-bit fractional value with
              overflow control.

@return       32-bit fractional value shifted by the shift amount, right is
              the positive direction. The bits beyond the 32-bit boundary
              are discarded.

@note         Overflow is detected and the function saturates if the return
              value cannot fit into the return type.

              The shift amount cannot exceed in magnitude the bit-width of
              the shift value, that means must be within the range -32...32
              Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32ShrSat(register Frac32 x, register Word32 s)
{
    register Word32 y;
    register Word32 xmax;
    register Word32 xmin;

    if(s < 0)
    {
        s = -s;
        xmax = INT32_MAX >> s;
        xmin = INT32_MIN >> s;

        y = x << s;
        y = (x > xmax) ? INT32_MAX:y;
        y = (x <= xmin) ? INT32_MIN:y;
    }
    else
    {
        y = x >> s;
    }

    return INT32TOF32(y);
}

/*------------------------------------------------------------------------*//*!

@brief        Left, bidirectional shift of 32-bit fractional value.

@return       32-bit fractional value shifted by the shift amount, left is
              the positive direction. The bits beyond the 32-bit boundary
              are discarded.

@note         Overflow is not detected.

              The shift amount cannot exceed in magnitude the bit-width of
              the shift value, that means must be within the range -32...32.
              Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Shl(register Frac32 x, register Word32 s)
{
    return (s<0) ? x>>(-s):x<<s;
}

/*------------------------------------------------------------------------*//*!

@brief        Left, bidirectional shift of 32-bit fractional value with
              overflow control.

@return       32-bit fractional value shifted by the shift amount, left is
              the positive direction. The bits beyond the 32-bit boundary
              are discarded.

@note         Overflow is detected. The function returns a saturated
              fractional value if the return value cannot fit into the return
              type.

              The shift amount cannot exceed in magnitude the bit-width of
              the shift value, that means must be within the range -32...32.
              Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32ShlSat(register Frac32 x, register Word32 s)
{
    register Word32 y;
    register Word32 xmax;
    register Word32 xmin;

    if(s > 0)
    {
        xmax = INT32_MAX >> s;
        xmin = INT32_MIN >> s;

        y = x << s;
        y = (x > xmax) ? INT32_MAX:y;
        y = (x <= xmin) ? INT32_MIN:y;
    }
    else
    {
        y = x >> (-s);
    }

    return INT32TOF32(y);
}

/*------------------------------------------------------------------------*//*!

@brief        Right, unidirectional shift of 32-bit fractional value (x) by
              the specified shift amount (s).

@return       32-bit fractional value shifted right by the shift amount.
              The bits beyond the 32-bit boundary of the result are discarded.

@note         This is the unidirectional right shift.

              The shift amount cannot exceed in magnitude the bit-width of
              the shifted value, that means it must be within the range 0...31.
              Otherwise the result of the function is undefined.

@warning      This function is target dependent.  The shift result for the
              negative value to be shifted may be undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Shruni(register Frac32 x, register UWord32 s)
{
    return x>>s;
}

/*------------------------------------------------------------------------*//*!

@brief        Counts the number of left shift needed for normalization of
              the input 32-bit fractional value

@return       The number of left shift needed to normalize the argument.
              For the input 0 returns 0.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Word32
F32Norm(register Frac32 x)
{
    register Word32 sham;
    register Word32 shamd;
    register Word32 shamp;
    register Word32 shamn;
    register Word32 shcorr;
    register Word32 b;
    register Word32 one;

    if(x == 0)
    {
        return 0;
    }

    if(x == 0x80000000)
    {
        return 0;
    }

    shcorr = (x<0) ? 1:0;

    x = (x<0) ? (-x):x;

    one = 1;
    sham = 15;
    shamp = 8;
    shamn = -8;
    do
    {
         b = one<<sham;
         shamd = (x>= b) ? shamp:shamn;
         sham += shamd;
         shamp >>= 1;
         shamn >>= 1;
    } while(shamp > 0);

    shamn = -1;
    b = one<<sham;
    shamd = ( x>= b) ? shamp:shamn;
    sham += shamd;

    sham = 30 - sham + shcorr;

    return sham;
}

/* NOTE:
 *   The next two functions are commented out because lcc (matlab compiler
 *   is unable to compile them).  See also the note at the start of the
 *   file.
 */

#endif /* _SWLIBS_INLINES_H_ */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/nat_prv.h<|end_filename|>
#ifndef __nat_prv_h__
#define __nat_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nat_prv.h$
* $Version : 3.8.7.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   Private Network Address Translator definitions.
*
*END************************************************************************/

 
#include <tcpip.h>
#include <ip.h>
#include <ip_prv.h>
#include <icmp_prv.h>
#include <tcp_prv.h>
#include <udp_prv.h>
#include "nat_session.h"


/****************************************************
**
** CONSTANTS
*/

#define NAT_SESSION_INITIAL_COUNT   16
#define NAT_SESSION_GROW_COUNT      16
#define NAT_SESSION_MAX             0 

#define NAT_STATE_NORMAL            0x00
#define NAT_STATE_INSERT_IN         0x01
#define NAT_STATE_INSERT_OUT        0x02
#define NAT_STATE_FIN_ONE           0x04
#define NAT_STATE_FIN_TWO           0x08
#define NAT_STATE_ICMP_DEL          0x10
#define NAT_STATE_INS_ERR           0x20

#define NAT_ALG_TFTP_TYPE           0x0000
#define NAT_ALG_FTP_TYPE            0x0001

#define NAT_IS_PRIVATE   0x01
#define NAT_IS_LOCAL   0x02

#define NAT_PUBLIC         (0)
#define NAT_PRIVATE        (NAT_IS_PRIVATE)
#define NAT_PUBLIC_LOCAL   (NAT_IS_LOCAL)
#define NAT_PRIVATE_LOCAL  (NAT_IS_PRIVATE|NAT_IS_LOCAL)

#define NAT_DIRECTION(s,d) ((s<<2)|d)

#define NAT_PUBLIC_TO_PUBLIC                 NAT_DIRECTION(NAT_PUBLIC,NAT_PUBLIC)
#define NAT_PUBLIC_TO_PRIVATE                NAT_DIRECTION(NAT_PUBLIC,NAT_PRIVATE)
#define NAT_PUBLIC_TO_PUBLIC_LOCAL           NAT_DIRECTION(NAT_PUBLIC,NAT_PUBLIC_LOCAL)
#define NAT_PUBLIC_TO_PRIVATE_LOCAL          NAT_DIRECTION(NAT_PUBLIC,NAT_PRIVATE_LOCAL)

#define NAT_PRIVATE_TO_PUBLIC                NAT_DIRECTION(NAT_PRIVATE,NAT_PUBLIC)
#define NAT_PRIVATE_TO_PRIVATE               NAT_DIRECTION(NAT_PRIVATE,NAT_PRIVATE)
#define NAT_PRIVATE_TO_PUBLIC_LOCAL          NAT_DIRECTION(NAT_PRIVATE,NAT_PUBLIC_LOCAL)
#define NAT_PRIVATE_TO_PRIVATE_LOCAL         NAT_DIRECTION(NAT_PRIVATE,NAT_PRIVATE_LOCAL)

#define NAT_PUBLIC_LOCAL_TO_PUBLIC           NAT_DIRECTION(NAT_PUBLIC_LOCAL,NAT_PUBLIC)
#define NAT_PUBLIC_LOCAL_TO_PRIVATE          NAT_DIRECTION(NAT_PUBLIC_LOCAL,NAT_PRIVATE)
#define NAT_PUBLIC_LOCAL_TO_PUBLIC_LOCAL     NAT_DIRECTION(NAT_PUBLIC_LOCAL,NAT_PUBLIC_LOCAL)
#define NAT_PUBLIC_LOCAL_TO_PRIVATE_LOCAL    NAT_DIRECTION(NAT_PUBLIC_LOCAL,NAT_PRIVATE_LOCAL)

#define NAT_PRIVATE_LOCAL_TO_PUBLIC          NAT_DIRECTION(NAT_PRIVATE_LOCAL,NAT_PUBLIC)
#define NAT_PRIVATE_LOCAL_TO_PRIVATE         NAT_DIRECTION(NAT_PRIVATE_LOCAL,NAT_PRIVATE)
#define NAT_PRIVATE_LOCAL_TO_PUBLIC_LOCAL    NAT_DIRECTION(NAT_PRIVATE_LOCAL,NAT_PUBLIC_LOCAL)
#define NAT_PRIVATE_LOCAL_TO_PRIVATE_LOCAL   NAT_DIRECTION(NAT_PRIVATE_LOCAL,NAT_PRIVATE_LOCAL)



/***************************************
**
** MACROS
*/
#define TRANSPORT_PTR(ip_header_ptr)  ((uchar_ptr)ip_header_ptr) + IPH_LEN(ip_header_ptr);
#define NAT_KEY(prot,port)  (prot & 0xFF) << 16 | (port & 0xFFFF)
#define NAT_NEXT_PORT(c,p) ((p<=c->PORT_MIN?c->PORT_MAX:p-1))

#define NAT_UPDATE_ERR_STATS(c,priv)    if (priv) c->STATS.ST_PACKETS_PRV_PUB_ERR++; else c->STATS.ST_PACKETS_PUB_PRV_ERR++


/* 
** NAT_PARM:
**    NAT initialisation parameters.
*/
typedef struct nat_parm {
   TCPIP_PARM        COMMON;
   _ip_address       IP_PRV;
   _ip_address       IP_MASK;
   uint_32_ptr       LEN_PTR;
   uint_32           OPTION;
   pointer           CONFIG;
} NAT_PARM, _PTR_ NAT_PARM_PTR;


/*
** NAT_EVENT_HEAD:
**    Holds information about a NAT event queue
*/
typedef struct nat_event_head {
   NAT_EVENT_STRUCT_PTR    FIRST;         /* Points to first node in list */
   NAT_EVENT_STRUCT_PTR    LAST;          /* Points to last node in list */
   uint_32                 TIMEDELTA;     /* Time for last node to expire */
   uint_32                 TIMESTAMP;     /* Last modification time       */
} NAT_EVENT_HEAD, _PTR_ NAT_EVENT_HEAD_PTR;

/*
** NAT_ALG_CFG_STRUCT:
**    Holds NAT ALG specific information. 
*/
typedef uint_32 (_CODE_PTR_ NAT_ALG_APPLY_FUNC)(RTCSPCB_PTR _PTR_, boolean, 
   pointer, pointer _PTR_);

typedef struct nat_alg_cfg_struct {
   pointer              NEXT;
   uint_32              ALG_TYPE;
   NAT_ALG_APPLY_FUNC   ALG_EXEC;
} NAT_ALG_CFG_STRUCT, _PTR_ NAT_ALG_CFG_STRUCT_PTR;



/*
** DNAT_RULE_STRUCT:
**    DNAT rule information.
*/
typedef struct dnat_rule_struct {
   uint_32           PRIORITY;
   _ip_address       PRIVATE_IP;
   uint_16           IP_PROTOCOL;
   uint_16           PUBLIC_START_PORT;
   uint_16           PUBLIC_END_PORT;
   uint_16           PRIVATE_START_PORT;
   uint_16           PRIVATE_END_PORT;
   uint_16           RESERVED;
   uint_32         TIMEOUT;              
} DNAT_RULE_STRUCT, _PTR_ DNAT_RULE_STRUCT_PTR;

/*
** DNAT_PARM:
**    DNAT initialisation parameters.
*/
typedef struct dnat_parm {
   TCPIP_PARM          COMMON;
   DNAT_RULE_STRUCT  RULE;
} DNAT_PARM, _PTR_ DNAT_PARM_PTR;

/*
** DNAT_ELEMENT_STRUCT:
**    DNAT rule list element.
*/
typedef struct dnat_element_struct {
   QUEUE_ELEMENT_STRUCT    ELEMENT;
   DNAT_RULE_STRUCT         RULE;
} DNAT_ELEMENT_STRUCT, _PTR_ DNAT_ELEMENT_STRUCT_PTR;


/*
** NAT_CFG_STRUCT:
**    Holds NAT configuration information. 
*/
typedef struct nat_cfg_struct {
   uint_32 (_CODE_PTR_     NAT_EXEC)(RTCSPCB_PTR _PTR_); /* PCB with packet */
   _ip_address             INITIAL_PRV_NET;          /* initial private network - for EDS compatibility */
   _ip_address             INITIAL_PRV_MASK;         /* initial private network mask - for EDS compatibility */
   IPRADIX_NODE            ROOT_IN;                  /* incoming packet tree     */
   IPRADIX_NODE            ROOT_OUT;                 /* outgoing packet tree     */
   _rtcs_part              SESSION_PART;             /* session partition        */
   _rtcs_part              RADIX_IN;                 /* for incoming packets     */
   _rtcs_part              RADIX_OUT;                /* for outgoing packets     */
   NAT_ALG_CFG_STRUCT_PTR  ALG_INFO_PTR;             /* ALG specific config      */
   uint_16                 TCP_PORT;                 /* last used TCP port #     */
   uint_16                 UDP_PORT;                 /* last used UDP port #     */   
   uint_16                 ICMP_ID;                  /* last used ICMP ID        */   
   uint_16                 GLOBAL_PORT;             
   TCPIP_EVENT             TCP_TOUT;                 /* TCP timeout event        */
   TCPIP_EVENT             UDP_TOUT;                 /* UDP timeout event        */
   TCPIP_EVENT             FIN_TOUT;                 /* FIN timeout event        */
   NAT_EVENT_HEAD          TCP_HEAD;                 /* TCP Timeout event heads  */
   NAT_EVENT_HEAD          UDP_HEAD;                 /* UDP Timeout event heads  */
   NAT_EVENT_HEAD          FIN_HEAD;                 /* FIN Timeout event heads  */
   NAT_STATS               STATS;                    /* NAT stats                */
   uint_32                 TIMEOUT_TCP;              /* TCP session tout         */
   uint_32                 TIMEOUT_UDP;              /* UDP session tout         */
   uint_32                 TIMEOUT_FIN;              /* FIN-RST session tout     */
   uint_16                 PORT_MIN;                 /* Min used port number     */
   uint_16                 PORT_MAX;                 /* Max used port number     */

   TCPIP_EVENT             ICMP_TOUT;                /* ICMP timeout event       */
   uint_32                 TIMEOUT_ICMP;             /* ICMP session tout        */
   NAT_EVENT_HEAD          ICMP_HEAD;                /* ICMP Timeout event heads */
   QUEUE_STRUCT            RULE_QUEUE;
   NAT_NETWORK_STRUCT      PRIVATE_NETWORKS;         /* The private networks     */
} NAT_CFG_STRUCT, _PTR_ NAT_CFG_STRUCT_PTR;


/*
** TRANSPORT_UNION:
**    To reference the various possible transport payloads. 
*/
typedef union {
   pointer                 PTR;
   TCP_HEADER_PTR          TCP_PTR;
   UDP_HEADER_PTR          UDP_PTR;
   ICMP_HEADER_PTR         ICMP_PTR;
   ICMP_ECHO_HEADER_PTR    ECHO_PTR;
   ICMP_ERR_HEADER_PTR     ERR_PTR;
   uchar_ptr               DATA_OFFSET;
} TRANSPORT_UNION; 




/***************************************
**
** Function definitions
**
*/
extern void NAT_init_internal
(
   NAT_PARM_PTR      /* [IN] Initialization parameters */
);

void NAT_add_network_internal
(
   NAT_PARM_PTR      /* [IN] Network parameters */
);

void NAT_remove_network_internal
(
   NAT_PARM_PTR      /* [IN] Network parameters */
);

extern void NAT_close_internal
(
   NAT_PARM_PTR
);

extern NAT_SESSION_STRUCT_PTR NAT_lookup
(
   IP_HEADER_PTR,          /* [IN] The IP datagram */
   boolean,                /* [IN] Is it for an icmp error? */
   boolean,                /* [IN] Non strict lookup ? */
   uint_32_ptr             /* [OUT] Reason for returning NULL */
);
   
extern NAT_SESSION_STRUCT_PTR NAT_insert
(
   IP_HEADER_PTR,          /* [IN] Pointer to the IP datagram */
   uint_32_ptr             /* [OUT] Reason for returning NULL */
);

extern NAT_SESSION_STRUCT_PTR NAT_insert_dnat
(
   IP_HEADER_PTR,          /* [IN] Pointer to the IP datagram */
   DNAT_RULE_STRUCT_PTR,   /* [IN} DNAT Rule                  */
   uint_32_ptr             /* [OUT] Reason for returning NULL */
);

extern void NAT_delete
(
   NAT_SESSION_STRUCT_PTR  /* [IN] The session structure */
);
   
extern void NAT_find_next_session_internal
(
   NAT_PARM_PTR
);

extern uint_32 NAT_apply
(
   RTCSPCB_PTR _PTR_       /* [IN/OUT] PCB containing the packet */
 );

extern boolean NAT_expire
(
   TCPIP_EVENT_PTR         /* [IN] Points to the event that expired */
);

extern void NAT_event_add
(
   TCPIP_EVENT_PTR,        /* [IN] Controller event */
   NAT_EVENT_STRUCT_PTR    /* [IN] NAT event to add */
);

extern void NAT_event_del
(
   NAT_EVENT_STRUCT_PTR    /* [IN] NAT event to del */
);


extern void NAT_event_tick
(
   TCPIP_EVENT_PTR,        /* [IN] Controlling event           */
   boolean                 /* [IN] Force expiry of first event */
);

extern void NAT_tout_max
(
   TCPIP_EVENT_PTR,        /* [IN] Event queue to update */
   uint_32                 /* [IN] New maximum timeout for events in queue */
);

extern uint_16 NAT_chksum_mod
(
   uint_16  oldchk,        /* [IN] The old checksum */
   uint_16  old16,         /* [IN] The old data being replaced */
   uint_16  new16          /* [IN] The new replacement data */
);

extern void NAT_mod_ip
(
   IP_HEADER_PTR,          /* [IN/OUT] IP datagram */
   NAT_SESSION_STRUCT_PTR, /* [IN]     NAT session */
   boolean                 /* [IN]     Direction   */
);

extern void NAT_mod_tcpudp
(
   TRANSPORT_UNION,        /* [IN/OUT] Transport protocol header */ 
   NAT_SESSION_STRUCT_PTR, /* [IN] The session struct            */
   boolean,                /* [IN] Direction of packet           */
   boolean                 /* [IN] Will it go on the FINRST Q?   */
);

extern uint_32 NAT_mod_icmp
(
   IP_HEADER_PTR,                /* [IN/OUT] IP datagram       */
   NAT_SESSION_STRUCT_PTR _PTR_, /* [IN]     NAT session       */
   boolean,                      /* [IN]     Direction         */
   boolean _PTR_                 /* [OUT] DEST is NAT router?  */
);

extern void NAT_config_timeouts
(
   nat_timeouts _PTR_ config     /* [IN] New timeouts */
);

extern void NAT_config_ports
(
   nat_ports _PTR_ config        /* [IN] New port range */
);

extern void NAT_getopt  
(
   NAT_PARM_PTR                  /* [IN/OUT] options */
);

extern void NAT_setopt  
(
   NAT_PARM_PTR                  /* [IN/OUT] options */
);

extern boolean NAT_is_private_addr
(
   NAT_NETWORK_STRUCT_PTR, 
   _ip_address
);

extern uint_32 NAT_add_private_network
(
   NAT_NETWORK_STRUCT_PTR, 
   _ip_address, 
   _ip_address
);

extern uint_32 NAT_remove_private_network(
   NAT_NETWORK_STRUCT_PTR, 
   _ip_address, 
   _ip_address
);

/***************************************
**
** Function definitions for DNAT
**
*/

extern DNAT_RULE_STRUCT_PTR DNAT_lookup_rule
(
   NAT_CFG_STRUCT_PTR,
   IP_HEADER_PTR,              /* [IN] The IP datagram */
   boolean
);

extern void DNAT_add_rule_internal
(
   DNAT_PARM_PTR                   /* [IN] DNAT rule parameters */
);

extern void DNAT_delete_rule_internal
(
   DNAT_PARM_PTR                   /* [IN] DNAT rule priority */ 
);

extern void DNAT_get_next_rule_internal
(
   DNAT_PARM_PTR                   /* [IN] DNAT rule priority */ 
);


/***********************
**
** NAT ALG prototypes
*/

typedef void (_CODE_PTR_ NAT_ALG_FREE_FUNC)
(
   pointer
);

extern NAT_ALG_FREE_FUNC NAT_alg_free_func_table[];

extern uint_32 NAT_init_algs
(
   NAT_CFG_STRUCT_PTR
);

extern void NAT_ALG_TCP_checksum
(
   IP_HEADER_PTR
);

extern uint_32 NAT_ALG_tftp
(
   pointer
);

extern uint_32 NAT_ALG_tftp_apply
(
   RTCSPCB_PTR _PTR_, 
   boolean, 
   pointer, 
   pointer _PTR_
);

extern boolean NAT_ALG_tftp_lookup
(
   RTCSPCB_PTR _PTR_
);

extern uint_32 NAT_ALG_ftp
(
   pointer
);

extern uint_32 NAT_ALG_ftp_apply
(
   RTCSPCB_PTR _PTR_, 
   boolean, 
   pointer, 
   pointer _PTR_
);

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ping.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ping.c$
* $Version : 3.8.11.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of a minimal
*   ICMP echo request.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_ICMP 
#include "rtcs_prv.h"
#include "tcpip.h"
#include "icmp_prv.h"
#include "arp.h"


boolean ICMP_expire_echo (TCPIP_EVENT_PTR);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_ping
* Returned Value  : error code
* Comments  :  Send an ICMP echo request, and wait for a reply.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_ping(  _ip_address ipaddress,      /* [IN] remote IP address */
                    uint_32_ptr timeout,        /* [IN]  Maximum time to wait for reply */
                                                /* [OUT] Round trip time */
                    uint_16        id,          /* [IN] user id for the ping request */
                    uint_8  hop_limit,          /* [IN] Hope limit or TTL (optional)            */ 
                    pointer data_buffer,        /* [IN] pointer to ping data buffer (optional) */
                    uint_32 data_buffer_size    /* [IN] size of a ping data buffer (optional)  */ 
                )

{

#if RTCSCFG_ENABLE_IP4
   
    ICMP_PARM   parms;
    uint_32     error;

    parms.ipaddress = ipaddress;
    parms.id        = id;
    parms.timeout   = *timeout;
    parms.hop_limit = hop_limit;
    parms.data_buffer  = data_buffer;           /* Pointer to a buffer. */
    parms.data_buffer_size = data_buffer_size;  /* Size of a buffer.    */

    error = RTCSCMD_issue(parms, ICMP_send_echo);
    if (error) 
        return error;

   *timeout = parms.timeout;
   return RTCS_OK;
   
#else
    
    return RTCSERR_IP_IS_DISABLED;
    
#endif /* RTCSCFG_ENABLE_IP4 */
   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ICMP_expire_echo
* Returned Values :
* Comments  :
*     Called by the Timer.  Expire a ICMP echo request.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

boolean ICMP_expire_echo
   (
      TCPIP_EVENT_PTR   event
   )
{ /* Body */
   ICMP_PARM_PTR         parms = event->PRIVATE;
   _ip_address           src_addr, dest_addr, kill_addr = parms->ipaddress;
   IP_IF_PTR             if_ptr;
   RTCSPCB_PTR           waiting_ptr, tmp_ptr;
   IP_HEADER_PTR         iphead;
   uint_16               protocol, test_id, test_seq;
   ICMP_ECHO_HEADER_PTR  icmphead;
   uchar                 type, hdrlen;
  
   /* kill the (possible) arp cache entry if it matches our ping request */
   src_addr = IP_route_find(kill_addr, 1);
   if_ptr = IP_find_if (src_addr);
    
   if (if_ptr && if_ptr->ARP) {
      waiting_ptr = (RTCSPCB_PTR)ARP_find_waiting(if_ptr, kill_addr);
      while (waiting_ptr) {
         tmp_ptr = waiting_ptr;
         if (src_addr == IP_source(waiting_ptr)) {
            dest_addr   = IP_dest(waiting_ptr);
            iphead = (IP_HEADER_PTR)RTCSPCB_DATA_NETWORK(waiting_ptr);
            hdrlen = (ntohc(iphead->VERSLEN) & 0x0F) << 2;
            protocol = RTCSPCB_TRANSPORT_PROTL(waiting_ptr);
            if ( protocol == IPPROTO_ICMP ) {
               icmphead = (ICMP_ECHO_HEADER_PTR)RTCSPCB_DATA_TRANSPORT(waiting_ptr);
               type = icmphead->HEAD.TYPE[0];
               if ( ICMPTYPE_ISQUERY(type)) {
                  test_id  = ntohs(icmphead->ID);  
                  test_seq = ntohs(icmphead->SEQ);
                  /* found it */
                  if (test_id  == parms->id  &&
                     test_seq == parms->seq &&
                     kill_addr == dest_addr) {
                     /* kill it */
                     ARP_kill_entry (if_ptr, kill_addr);
                  } /* Endif */
               } /* Endif */
            } /* Endif */
         } /* Endif */
         waiting_ptr = (RTCSPCB_PTR)ARP_find_waiting(if_ptr, kill_addr);
         if (waiting_ptr == tmp_ptr) 
             waiting_ptr = NULL;
      } /* While */
   } /* Endif */

   /* inform the application of timeout */
   if (parms->NEXT) {
      parms->NEXT->PREV = parms->PREV;
   } /* Endif */
   *parms->PREV = parms->NEXT;



   RTCSCMD_complete(parms, RTCSERR_ICMP_ECHO_TIMEOUT);

   return FALSE;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ICMP_send_echo
* Parameters      :
*
*     _ip_address       ipaddress   [IN] destination IP address
*     uint_32           timeout     [IN/OUT] timeout/rtt
*     uint_16           id          [IN] identification for echo message.
*     uint_16           seq         not used
*
* Comments        :
*     Send an ICMP Echo Request packet.
*
*END*-----------------------------------------------------------------*/

void ICMP_send_echo
   (
      ICMP_PARM_PTR     parms
   )
{ 

#if RTCSCFG_ENABLE_IP4

   ICMP_CFG_STRUCT_PTR     ICMP_cfg_ptr = RTCS_getcfg(ICMP);
   RTCSPCB_PTR             pcb;
   ICMP_ECHO_HEADER_PTR    packet;
   uint_16                 chksum;
   uint_32                 error;

   IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
   parms->seq = ICMP_cfg_ptr->ECHO_SEQ++;

   pcb = RTCSPCB_alloc_send();
   if (pcb == NULL) {
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      RTCSCMD_complete(parms, RTCSERR_PCB_ALLOC);
      return;
   }

    if(parms->data_buffer && parms->data_buffer_size)
    {
        error = RTCSPCB_append_fragment(pcb, parms->data_buffer_size, parms->data_buffer);
        if (error) 
        {
            IF_ICMP6_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_ERRORS++);
            RTCSLOG_PCB_FREE(pcb, error);
            RTCSPCB_free(pcb);
            RTCSCMD_complete(parms, error);
            return;
        }
   }

   //RTCSLOG_PCB_ALLOC(pcb);

   error = RTCSPCB_insert_header(pcb, sizeof(ICMP_ECHO_HEADER));
   if (error) {
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_ERRORS++);
      IF_ICMP_STATS_ENABLED(RTCS_seterror(&ICMP_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb));
      RTCSLOG_PCB_FREE(pcb, error);
      RTCSPCB_free(pcb);
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */

   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_ICMP), 0);

   packet = (ICMP_ECHO_HEADER_PTR)RTCSPCB_DATA(pcb);
   pcb->TRANSPORT_LAYER = (uchar_ptr)packet;
   htonc(packet->HEAD.TYPE, ICMPTYPE_ECHO_REQ);
   htonc(packet->HEAD.CODE, 0);
   htons(packet->HEAD.CHECKSUM, 0);
   htons(packet->ID,  parms->id);
   htons(packet->SEQ, parms->seq);

   chksum = IP_Sum_PCB(0, pcb);
   chksum = IP_Sum_invert(chksum);
   htons(packet->HEAD.CHECKSUM, chksum);
   pcb->IP_SUM_PTR = NULL;

   parms->EXPIRE.TIME    = parms->timeout;
   parms->EXPIRE.EVENT   = ICMP_expire_echo;
   parms->EXPIRE.PRIVATE = parms;
   parms->timeout = RTCS_time_get();   /* get timestamp */

   error = IP_send(pcb, IPPROTO_ICMP|IPTTL(parms->hop_limit), INADDR_ANY, parms->ipaddress, 0);

   if (error != RTCS_OK) {
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */

   /*
   ** If there is no error add the parm struct to config struct
   ** and initiate the event timer
   */

   IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.ST_TX_ECHO_REQ++);

   /* add the prameter structure to ICMP  cfg */
   parms->NEXT = ICMP_cfg_ptr->ECHO_PARM_HEAD;
   if (parms->NEXT) {
      parms->NEXT->PREV = &parms->NEXT;
   } /* Endif */
   ICMP_cfg_ptr->ECHO_PARM_HEAD = parms;
   parms->PREV = &ICMP_cfg_ptr->ECHO_PARM_HEAD;

   TCPIP_Event_add(&parms->EXPIRE);
   
#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);
    return;

#endif /* RTCSCFG_ENABLE_IP4 */   

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lpm/lpm.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*****************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: lpm.c$
* $Version : 3.8.5.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains Low Power Manager functionality.
*
*END************************************************************************/


#include "mqx_inc.h"
#include "bsp.h"
#include "lpm_prv.h"
#include "cm.h"


#if MQX_ENABLE_LOW_POWER


/* Global LPM state */
static LPM_STATE_STRUCT lpm_state_struct = {0}; 


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_restart_idle_task
* Returned Value   : MQX error code
* Comments         :
*    This function restarts idle task if idle sleep settings have changed.
*    Restart matrix description:
*    
*    sleep enabled      idle task parameter    sleep available    idle task_restart
*    0                  0                      0                  no (2)
*    0                  0                      1                  no (2)
*    0                  1                      0                  yes (parameter = 0)
*    0                  1                      1                  yes (parameter = 0)
*    1                  0                      0                  no (2)
*    1                  0                      1                  yes (parameter = 1)
*    1                  1                      0                  yes (parameter = 0)
*    1                  1                      1                  no (2)
*
*END*----------------------------------------------------------------------*/

static _mqx_uint _lpm_restart_idle_task 
    (
        /* [IN] Low power operation mode identifier */
        LPM_OPERATION_MODE target_mode,
          
        /* [IN] Idle sleep enable flag */
        boolean            enabled
    )
{
    _mqx_uint              parameter, result = MQX_OK;
    _task_id               idle_task_id;
    boolean                available;
    static const char      lpm_idle_task_restart_matrix[2][2][2] = {
        {{2, 2}, {0, 0}},
        {{2, 1}, {0, 2}}
    };
    
    idle_task_id = _task_get_id_from_name (MQX_IDLE_TASK_NAME);
    if (MQX_NULL_TASK_ID == idle_task_id)
    {
        result = MQX_INVALID_TASK_ID;
    }
    else
    {
        parameter = _task_get_parameter_for (idle_task_id);
        available = _lpm_idle_sleep_check ();
        parameter = lpm_idle_task_restart_matrix[enabled][parameter][available];
        if (parameter <= 1)
        {
            result = _task_restart (idle_task_id, &parameter, FALSE);
        }
    }
    return result;
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_install
* Returned Value   : MQX error code
* Comments         :
*    This function installs LPM into MQX.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _lpm_install
    ( 
        /* [IN] Specification of CPU core low power operation modes available */
        const LPM_CPU_OPERATION_MODE _PTR_ cpu_operation_modes,

        /* [IN] Default low power operation mode identifier */
        LPM_OPERATION_MODE                 default_mode
    )
{
    _mqx_uint result;
    
    /* Check parameters */
    if ((NULL == cpu_operation_modes) || (LPM_OPERATION_MODES <= (_mqx_uint)default_mode))
    {
        return MQX_INVALID_PARAMETER;
    }
    
    /* Check if LPM not installed and initialize */
    if (LWSEM_VALID == lpm_state_struct.SEMAPHORE.VALID)
    {
        return MQX_COMPONENT_EXISTS;
    }
    result = _lwsem_create (&(lpm_state_struct.SEMAPHORE), 1);
    if (MQX_OK != result)
    {
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    
    /* LPM state setup */
    lpm_state_struct.CPU_OPERATION_MODES = cpu_operation_modes;
    lpm_state_struct.OPERATION_MODE = default_mode;
    lpm_state_struct.DRIVER_ENTRIES = NULL;
    lpm_state_struct.COUNTER = 0;
    lpm_state_struct.IDLE_SLEEP = FALSE;
    _lpm_restart_idle_task (default_mode, lpm_state_struct.IDLE_SLEEP);
    
    return MQX_OK;    
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_uninstall
* Returned Value   : MQX error code
* Comments         :
*    This function uninstalls LPM from MQX.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _lpm_uninstall
    ( 
    )
{
    LPM_DRIVER_ENTRY_STRUCT_PTR entry_ptr, tmp_ptr;
    _mqx_uint                   result;
    
    /* Check if LPM installed and lock */
    result = _lwsem_wait (&(lpm_state_struct.SEMAPHORE));
    if (MQX_OK != result)
    {
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    
    /* Final restart of idle task to disable sleep feature */
    lpm_state_struct.IDLE_SLEEP = FALSE;
    _lpm_restart_idle_task (lpm_state_struct.OPERATION_MODE, lpm_state_struct.IDLE_SLEEP);
    
    /* De-initialize global LPM state and unlock */
    lpm_state_struct.CPU_OPERATION_MODES = NULL;
    lpm_state_struct.OPERATION_MODE = (LPM_OPERATION_MODE)0;
    lpm_state_struct.COUNTER = 0;
    for (entry_ptr = lpm_state_struct.DRIVER_ENTRIES; NULL != entry_ptr; )
    {
        tmp_ptr = entry_ptr->NEXT;
        _mem_free (entry_ptr);
        entry_ptr = tmp_ptr;
    }
    _lwsem_destroy (&(lpm_state_struct.SEMAPHORE));
    
    return MQX_OK;    
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_register_driver 
* Returned Value   : MQX error code and driver registration handle
* Comments         :
*    This function registers driver into LPM.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _lpm_register_driver 
    ( 
        /* [IN] Driver low power callbacks specification */
        const LPM_REGISTRATION_STRUCT_PTR driver_registration_ptr,
        
        /* [IN] Driver specific data */
        const pointer                     driver_specific_data_ptr,
        
        /* [OUT] Unique driver registration handle */
        _mqx_uint_ptr                     registration_handle_ptr
    )
{
    LPM_DRIVER_ENTRY_STRUCT_PTR           entry_ptr, tmp_ptr;
    _mqx_uint                             result;
    
    /* Check parameters */
    if ((NULL == driver_registration_ptr) || (NULL == registration_handle_ptr))
    {
        return MQX_INVALID_PARAMETER;
    }
    
    /* Check if LPM installed and lock */
    result = _lwsem_wait (&(lpm_state_struct.SEMAPHORE));
    if (MQX_OK != result)
    {
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    
    /* Allocate new registration record */
    entry_ptr = (LPM_DRIVER_ENTRY_STRUCT_PTR)_mem_alloc_system_zero ((_mem_size) sizeof (LPM_DRIVER_ENTRY_STRUCT));
    if (NULL == entry_ptr) 
    {
        _lwsem_post (&(lpm_state_struct.SEMAPHORE));
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type (entry_ptr, MEM_TYPE_IO_LPM_DRIVER_ENTRY);
    
    /* Get new unique identifier */
    while (0 == (++lpm_state_struct.COUNTER))
    {
        ;
    }
    
    /* File new registration record (sort by dependency level) */
    entry_ptr->PREVIOUS = NULL;
    entry_ptr->NEXT = NULL;
    _mem_copy (driver_registration_ptr, &(entry_ptr->REGISTRATION), sizeof (entry_ptr->REGISTRATION));
    entry_ptr->DATA = driver_specific_data_ptr;
    entry_ptr->ID = lpm_state_struct.COUNTER;
    for (tmp_ptr = lpm_state_struct.DRIVER_ENTRIES; NULL != tmp_ptr; tmp_ptr = tmp_ptr->NEXT)
    {
        if (entry_ptr->REGISTRATION.DEPENDENCY_LEVEL < tmp_ptr->REGISTRATION.DEPENDENCY_LEVEL)
        {
            entry_ptr->NEXT = tmp_ptr;
            if (NULL != tmp_ptr->PREVIOUS)
            {
                tmp_ptr->PREVIOUS->NEXT = entry_ptr;
                entry_ptr->PREVIOUS = tmp_ptr->PREVIOUS;
            }
            tmp_ptr->PREVIOUS = entry_ptr;
            break;
        }
        if (NULL == tmp_ptr->NEXT)
        {
            tmp_ptr->NEXT = entry_ptr;
            entry_ptr->PREVIOUS = tmp_ptr;
            break;
        }        
    }
    if (NULL == entry_ptr->PREVIOUS)
    {
        lpm_state_struct.DRIVER_ENTRIES = entry_ptr;
    } 
    
    /* Return driver registration handle */
    *registration_handle_ptr = entry_ptr->ID;
    
    /* Unlock LPM */
    _lwsem_post (&(lpm_state_struct.SEMAPHORE));
    
    return MQX_OK;
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_unregister_driver 
* Returned Value   : MQX error code
* Comments         :
*    This function unregisters driver from LPM.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _lpm_unregister_driver 
    ( 
        /* [IN] Driver registration handle returned by LPM registration function */
        _mqx_uint               registration_handle
    )
{
    LPM_DRIVER_ENTRY_STRUCT_PTR entry_ptr;
    _mqx_uint                   result;
    
    /* Check parameters */
    if (0 == registration_handle)
    {
        return MQX_INVALID_PARAMETER;
    }
    
    /* Check if LPM installed and lock */
    result = _lwsem_wait (&(lpm_state_struct.SEMAPHORE));
    if (MQX_OK != result)
    {
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    
    /* Find driver registration record according to given handle and remove it from the list */
    for (entry_ptr = lpm_state_struct.DRIVER_ENTRIES; NULL != entry_ptr; entry_ptr = entry_ptr->NEXT)
    {
        if (registration_handle == entry_ptr->ID)
        {
            if (NULL == entry_ptr->PREVIOUS)
            {
                if (NULL != entry_ptr->NEXT)
                {
                    entry_ptr->NEXT->PREVIOUS = NULL;
                }
                lpm_state_struct.DRIVER_ENTRIES = entry_ptr->NEXT;
            }
            else
            {
                if (NULL != entry_ptr->NEXT)
                {
                    entry_ptr->NEXT->PREVIOUS = entry_ptr->PREVIOUS;
                }
                entry_ptr->PREVIOUS->NEXT = entry_ptr->NEXT;
            }
            break;
        }
    }
    if (NULL == entry_ptr)
    {
        _lwsem_post (&(lpm_state_struct.SEMAPHORE));
        return MQX_INVALID_HANDLE;
    }
    
    /* Release the record found */
    _mem_free (entry_ptr);
    
    /* Unlock LPM */
    _lwsem_post (&(lpm_state_struct.SEMAPHORE));
    
    return MQX_OK;    
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_set_clock_configuration
* Returned Value   : MQX error code
* Comments         :
*    This function changes low power clock configuration.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _lpm_set_clock_configuration
    ( 
        /* [IN] Low power clock configuration identifier */
        BSP_CLOCK_CONFIGURATION clock_configuration
    )
{
    LPM_DRIVER_ENTRY_STRUCT_PTR entry_ptr;
    LPM_NOTIFICATION_STRUCT     notification;
    _mqx_uint                   result;
    
    /* Check parameters */
    if (BSP_CLOCK_CONFIGURATIONS <= (_mqx_uint)clock_configuration)
    {
        return MQX_INVALID_PARAMETER;
    }
    
    /* Check if LPM installed and lock */
    result = _lwsem_wait (&(lpm_state_struct.SEMAPHORE));
    if (MQX_OK != result)
    {
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    
    /* Phase 1 - send pre-notifications before clock configuration change */
    for (entry_ptr = lpm_state_struct.DRIVER_ENTRIES; NULL != entry_ptr; entry_ptr = entry_ptr->NEXT)
    {
        if (NULL != entry_ptr->REGISTRATION.CLOCK_CONFIGURATION_CALLBACK)
        {
            notification.NOTIFICATION_TYPE = LPM_NOTIFICATION_TYPE_PRE;
            notification.CLOCK_CONFIGURATION = clock_configuration;
            notification.OPERATION_MODE = lpm_state_struct.OPERATION_MODE;
            if (LPM_NOTIFICATION_RESULT_OK != ((*(entry_ptr->REGISTRATION.CLOCK_CONFIGURATION_CALLBACK)) (&notification, entry_ptr->DATA)))
            {
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                entry_ptr = entry_ptr->PREVIOUS;
                break;
            }
        }
        if (NULL == entry_ptr->NEXT)
        {
            break;
        }
    }

    /* Phase 2 - change clock configuration if all pre-notifications passed */
    if (MQX_OK == result)
    {
        result = _cm_set_clock_configuration (clock_configuration);
    }

    /* Phase 3 - send post-notifications after clock configuration change or failure */
    clock_configuration = _cm_get_clock_configuration();
    for ( ; NULL != entry_ptr; entry_ptr = entry_ptr->PREVIOUS)
    {
        if (NULL != entry_ptr->REGISTRATION.CLOCK_CONFIGURATION_CALLBACK)
        {
            notification.NOTIFICATION_TYPE = LPM_NOTIFICATION_TYPE_POST;
            notification.CLOCK_CONFIGURATION = clock_configuration;
            notification.OPERATION_MODE = lpm_state_struct.OPERATION_MODE;
            (*(entry_ptr->REGISTRATION.CLOCK_CONFIGURATION_CALLBACK)) (&notification, entry_ptr->DATA);
        }
    }

    /* Unlock LPM */
    _lwsem_post (&(lpm_state_struct.SEMAPHORE));

    return result;    
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_get_clock_configuration 
* Returned Value   : Current low power clock configuration identifier
* Comments         :
*    This function returns current low power clock configuration identifier.
*
*END*----------------------------------------------------------------------*/

BSP_CLOCK_CONFIGURATION _lpm_get_clock_configuration 
    ( 
    )
{
    BSP_CLOCK_CONFIGURATION clock_configuration;
    _mqx_uint               result;
    
    /* Check if LPM installed and lock */
    result = _lwsem_wait (&(lpm_state_struct.SEMAPHORE));
    if (MQX_OK != result)
    {
        return (BSP_CLOCK_CONFIGURATION)-1;
    }
    
    /* Get current clock configuration */
    clock_configuration = _cm_get_clock_configuration();

    /* Unlock LPM */
    _lwsem_post (&(lpm_state_struct.SEMAPHORE));

    return clock_configuration;
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_set_operation_mode 
* Returned Value   : MQX error code
* Comments         :
*    This function changes low power operation mode. It may also restart idle task.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _lpm_set_operation_mode 
    ( 
        /* [IN] Low power operation mode identifier */
        LPM_OPERATION_MODE      operation_mode
    )
{
    LPM_DRIVER_ENTRY_STRUCT_PTR entry_ptr;
    LPM_NOTIFICATION_STRUCT     notification;
    BSP_CLOCK_CONFIGURATION     clock_configuration;
    _mqx_uint                   result;
    
    /* Check parameters */
    if (LPM_OPERATION_MODES <= (_mqx_uint)operation_mode)
    {
        return MQX_INVALID_PARAMETER;
    }
    
    /* Check if LPM installed and lock */
    result = _lwsem_wait (&(lpm_state_struct.SEMAPHORE));
    if (MQX_OK != result)
    {
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    
    /* Phase 1 - send pre-notifications before operation mode change */
    clock_configuration = _cm_get_clock_configuration();
    for (entry_ptr = lpm_state_struct.DRIVER_ENTRIES; NULL != entry_ptr; entry_ptr = entry_ptr->NEXT)
    {
        if (NULL != entry_ptr->REGISTRATION.OPERATION_MODE_CALLBACK)
        {
            notification.NOTIFICATION_TYPE = LPM_NOTIFICATION_TYPE_PRE;
            notification.CLOCK_CONFIGURATION = clock_configuration;
            notification.OPERATION_MODE = operation_mode;
            if (LPM_NOTIFICATION_RESULT_OK != ((*(entry_ptr->REGISTRATION.OPERATION_MODE_CALLBACK)) (&notification, entry_ptr->DATA)))
            {
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                entry_ptr = entry_ptr->PREVIOUS;
                break;
            }
        }
        if (NULL == entry_ptr->NEXT)
        {
            break;
        }
    }

    /* Phase 2 - change CPU operation mode if all pre-notifications passed */
    if (MQX_OK == result)
    {
        result =_lpm_set_cpu_operation_mode (lpm_state_struct.CPU_OPERATION_MODES, operation_mode);
        if (MQX_OK == result)
        {
            lpm_state_struct.OPERATION_MODE = operation_mode;
            _lpm_restart_idle_task (lpm_state_struct.OPERATION_MODE, lpm_state_struct.IDLE_SLEEP);
        }
    }
    
    /* Roll back in case of failure */
    if (MQX_OK != result)
    {
        for ( ; NULL != entry_ptr; entry_ptr = entry_ptr->PREVIOUS)
        {
            if (NULL != entry_ptr->REGISTRATION.OPERATION_MODE_CALLBACK)
            {
                notification.NOTIFICATION_TYPE = LPM_NOTIFICATION_TYPE_PRE;
                notification.CLOCK_CONFIGURATION = clock_configuration;
                notification.OPERATION_MODE = lpm_state_struct.OPERATION_MODE;
                (*(entry_ptr->REGISTRATION.OPERATION_MODE_CALLBACK)) (&notification, entry_ptr->DATA);
            }
        }
    }

    /* Unlock LPM */
    _lwsem_post (&(lpm_state_struct.SEMAPHORE));
    
    return result;    
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_get_operation_mode 
* Returned Value   : Current low power operation mode identifier
* Comments         :
*    This function returns current low power operation mode identifier.
*
*END*----------------------------------------------------------------------*/

LPM_OPERATION_MODE _lpm_get_operation_mode 
    ( 
    )
{
    LPM_OPERATION_MODE operation_mode;
    _mqx_uint          result;
    
    /* Check if LPM installed and lock */
    result = _lwsem_wait (&(lpm_state_struct.SEMAPHORE));
    if (MQX_OK != result)
    {
        return (LPM_OPERATION_MODE)-1;
    }
    
    /* Get current operation mode */
    operation_mode = lpm_state_struct.OPERATION_MODE;

    /* Unlock LPM */
    _lwsem_post (&(lpm_state_struct.SEMAPHORE));
    
    return operation_mode;    
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_idle_sleep_setup 
* Returned Value   : MQX error code
* Comments         :
*    This function turns on/off the idle sleep feature. It may restart idle task.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _lpm_idle_sleep_setup 
    (
        /* [IN] Whether to turn on/off the idle sleep feature */
        boolean idle_sleep
    )
{
    _mqx_uint   result;
    
    /* Check if LPM installed and lock */
    result = _lwsem_wait (&(lpm_state_struct.SEMAPHORE));
    if (MQX_OK != result)
    {
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    
    /* Change idle sleep settings and optionally restart idle task */
    if (idle_sleep != lpm_state_struct.IDLE_SLEEP)
    {
        result = _lpm_restart_idle_task (lpm_state_struct.OPERATION_MODE, idle_sleep);
        if (MQX_OK == result)
        {
            lpm_state_struct.IDLE_SLEEP = idle_sleep;
        }
    }

    /* Unlock LPM */
    _lwsem_post (&(lpm_state_struct.SEMAPHORE));

    return result;
}


#endif


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/log.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: log.c$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Log component.
 *
 *END************************************************************************/

#include <stdarg.h>
#include "mqx_inc.h"
#if MQX_USE_LOGS
#include "log.h"
#include "log_prv.h"

/*!
 * \brief Creates a kernel component providing a general log service for all 
 * user tasks.
 * 
 * The log component provides a maximum of 16 separately configurable user logs 
 * (log numbers 0 through 15).
 * \n An application subsequently creates user logs with _log_create().
 * 
 * \return MQX_OK
 * \return MQX_OUT_OF_MEMORY (Failure.)
 * 
 * \warning Disables and enables interrupts.
 * 
 * \see _log_create   
 */ 
_mqx_uint _log_create_component(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;

    _GET_KERNEL_DATA(kernel_data);

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    _mem_alloc_system_zero((_mem_size)sizeof(LOG_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (log_component_ptr == NULL)
    {
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(log_component_ptr, MEM_TYPE_LOG_COMPONENT);

    /* We must exclude all ISRs at this point */
    _int_disable();

#if MQX_CHECK_ERRORS
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] != NULL)
    {
        _int_enable();
        _mem_free(log_component_ptr);
        return(MQX_OK);
    } /* Endif */
#endif

    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] = log_component_ptr;
    log_component_ptr->VALID = LOG_VALID;
    _int_enable();

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Destroys an existing log.
 * 
 * \param[in] log_number The number of a log to be destroyed.
 * 
 * \return MQX_OK  
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not previously created.)  
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * 
 * \see _log_create
 * \see _log_create_component             
 */  
_mqx_uint _log_destroy
(
    _mqx_uint log_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _int_disable();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_component_ptr->LOGS[log_number] = NULL;
    _int_enable();

    _mem_free(log_header_ptr);

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Stops logging to the specified log.
 * 
 * A task can enable a log that has been disabled.
 * 
 * \param[in] log_number Log number of a previously created log.
 * 
 * \return MQX_OK
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)     
 * 
 * \see _log_enable
 * \see _log_read
 * \see _log_reset
 * \see _log_write
 */
_mqx_uint _log_disable
(
    _mqx_uint log_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _int_disable();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_header_ptr->FLAGS &= ~LOG_ENABLED;
    _int_enable();

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Starts logging to the specified log.
 * 
 * A task can enable a log that has been disabled.
 * 
 * \param[in] log_number Log number of a previously created log.
 * 
 * \return MQX_OK
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)     
 * 
 * \see _log_disable
 * \see _log_read
 * \see _log_reset
 * \see _log_write
 */
_mqx_uint _log_enable
(
    _mqx_uint log_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _int_disable();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_header_ptr->FLAGS |= LOG_ENABLED;
    _int_enable();

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Creates a new log.
 * 
 * Each entry in the log contains application-specified data, a timestamp (in 
 * absolute time), and a sequence number.
 * 
 * \param[in] log_number Log number to create (0 through 15).
 * \param[in] max_size   Maximum size of the data to be stored in _mqx_uints 
 * (includes LOG_ENTRY_STRUCT headers).
 * \param[in] flags      One of the following:
 * \li LOG_OVERWRITE (When the log is full, write new entries over oldest ones.)
 * \li 0 (When the log is full, do not write entries.)
 * 
 * \return MQX_OK
 * \return LOG_INVALID (Log_number exceeds 15)
 * \return MQX_INVALID_COMPONENT_BASE (Component is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * \return LOG_EXISTS (Log log_number has already been created.)
 * 
 * \warning Creates the log component if it was not created.
 * 
 * \see _log_create_component
 * \see _log_destroy
 * \see _log_read
 * \see _log_write
 * \see LOG_ENTRY_STRUCT 
 */ 
_mqx_uint _log_create
(
    _mqx_uint log_number,
    _mqx_uint max_size,
    uint_32   flags
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;
    _mqx_uint                result;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];
    if (log_component_ptr == NULL)
    {
        result = _log_create_component();
        log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (log_component_ptr == NULL)
        {
            return(result);
        } /* Endif */
#endif
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    log_header_ptr = (LOG_HEADER_STRUCT_PTR)
    _mem_alloc_system((_mem_size)(sizeof(LOG_HEADER_STRUCT) + max_size *
                                    sizeof(_mqx_uint)));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (log_header_ptr == NULL)
    {
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(log_header_ptr, MEM_TYPE_LOG);

    log_header_ptr->FLAGS = flags;
    log_header_ptr->FLAGS |= LOG_ENABLED;
    log_header_ptr->NUMBER = 1;
    log_header_ptr->MAX = max_size;
    log_header_ptr->SIZE = 0;
    log_header_ptr->LOG_WRITE = &log_header_ptr->DATA[0];
    log_header_ptr->LOG_READ = log_header_ptr->LOG_WRITE;
    log_header_ptr->LAST_LOG = log_header_ptr->LOG_WRITE;
    log_header_ptr->LOG_START = log_header_ptr->LOG_WRITE;
    log_header_ptr->LOG_END = &log_header_ptr->DATA[max_size];
    log_header_ptr->LOG_NEXT = NULL;

    _int_disable();
#if MQX_CHECK_ERRORS
    if (log_component_ptr->LOGS[log_number] != NULL)
    {
        _int_enable();
        _mem_free(log_header_ptr);
        return(LOG_EXISTS);
    } /* Endif */
#endif
    log_component_ptr->LOGS[log_number] = log_header_ptr;
    _int_enable();

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Reads the data from the log.
 * 
 * <table>
 *   <tr>
 *     <td><b>read_type</b></td>
 *     <td><b>Returns this entry in the log:</b></td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEWEST</td>
 *     <td>Newest.</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEXT</td>
 *     <td>Next one after the previous one read (must be used with LOG_READ_OLDEST).</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST</td>
 *     <td>Oldest.</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST_AND_DELETE</td>
 *     <td>Oldest and deletes it.</td> 
 *   </tr>     
 * </table>
 * 
 * \param[in] log_number   Log number of a previously created log.
 * \param[in] read_type    Type of read operation (see Description).
 * \param[in] size_to_read Maximum number of _mqx_uints (not including the entry 
 * header) to be read from an entry.
 * \param[in] entry_ptr    Where to write the log entry (any structure that 
 * starts with LOG_STRUCT or LOG_ENTRY_STRUCT).
 * 
 * \return MQX_OK
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_ENTRY_NOT_AVAILABLE (Log entry is not available.)
 * \return LOG_INVALID_READ_TYPE (Read_type is not valid.) 
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_POINTER (Entry_ptr is NULL.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * 
 * \see _log_create
 * \see _log_write
 * \see LOG_STRUCT
 * \see LOG_ENTRY_STRUCT        
 */ 
_mqx_uint _log_read
(
    _mqx_uint            log_number,
    _mqx_uint            read_type,
    _mqx_uint            size_to_read,
    LOG_ENTRY_STRUCT_PTR entry_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;
    LOG_ENTRY_STRUCT_PTR     log_ptr;
    _mqx_uint_ptr            data_ptr;
    _mqx_uint_ptr            next_ptr;
    _mqx_uint_ptr            user_ptr;
    _mqx_uint                size;
    uint_16                  milliseconds;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
    if (entry_ptr == NULL)
    {
        return(MQX_INVALID_POINTER);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _INT_DISABLE();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    if (log_header_ptr->SIZE == 0)
    {
        /* No data available */
        _INT_ENABLE();
        return(LOG_ENTRY_NOT_AVAILABLE);
    } /* Endif */

    if (read_type == LOG_READ_OLDEST_AND_DELETE)
    {
        data_ptr = log_header_ptr->LOG_READ;
    }
    else if (read_type == LOG_READ_NEXT)
    {
        data_ptr = log_header_ptr->LOG_NEXT;
        if (data_ptr == NULL)
        {
            _INT_ENABLE();
            return(LOG_ENTRY_NOT_AVAILABLE);
        } /* Endif */
    }
    else if (read_type == LOG_READ_OLDEST)
    {
        data_ptr = log_header_ptr->LOG_READ;
    }
    else if (read_type == LOG_READ_NEWEST)
    {
        data_ptr = log_header_ptr->LAST_LOG;
#if MQX_CHECK_ERRORS
    }
    else
    {
        _int_enable();
        return(LOG_INVALID_READ_TYPE);
#endif
    } /* Endif */

    size = *data_ptr;
    next_ptr = data_ptr + size;

#if 0
    if (next_ptr >= log_header_ptr->LOG_END)
    {
        next_ptr = log_header_ptr->LOG_START +
        (next_ptr - log_header_ptr->LOG_END);
    } /* Endif */
#else
    if (log_header_ptr->LOG_READ < log_header_ptr->LOG_WRITE)
    {
        /* R < W */
        if (next_ptr >= log_header_ptr->LOG_WRITE)
        {
            next_ptr = log_header_ptr->LOG_READ;
        } /* Endif */
    }
    else
    {
        /* R > W */
        if (next_ptr >= log_header_ptr->LOG_END)
        {
            next_ptr = log_header_ptr->LOG_START +
            (next_ptr - log_header_ptr->LOG_END);
        } /* Endif */
        if (next_ptr == log_header_ptr->LOG_WRITE)
        {
            next_ptr = log_header_ptr->LOG_READ;
        } /* Endif */
    } /* Endif */
#endif

    if (read_type == LOG_READ_OLDEST_AND_DELETE)
    {
        log_header_ptr->LOG_READ += size;
        log_header_ptr->SIZE -= size;
        if (log_header_ptr->LOG_READ >= log_header_ptr->LOG_END)
        {
            log_header_ptr->LOG_READ = log_header_ptr->LOG_START +
            (log_header_ptr->LOG_READ - log_header_ptr->LOG_END);
        } /* Endif */
    } /* Endif */

    if (size > (size_to_read + (_mqx_uint)sizeof(LOG_ENTRY_STRUCT)/sizeof(_mqx_uint)))
    {
        size = (size_to_read + (_mqx_uint)sizeof(LOG_ENTRY_STRUCT)/sizeof(_mqx_uint));
    } /* Endif */

    ++size;
    user_ptr = (_mqx_uint_ptr)((pointer)entry_ptr);
    while (--size)
    {
        *user_ptr++ = *data_ptr++;
        if (data_ptr == log_header_ptr->LOG_END)
        {
            data_ptr = log_header_ptr->LOG_START;
        } /* Endif */
    } /* Endwhile */
    log_ptr = entry_ptr;
    if (log_ptr->MICROSECONDS > MICROSECS_IN_MILLISECOND)
    {
        milliseconds = log_ptr->MICROSECONDS / (uint_16)MICROSECS_IN_MILLISECOND;
        log_ptr->MILLISECONDS += milliseconds;
        log_ptr->MICROSECONDS -= (milliseconds * (uint_16)MICROSECS_IN_MILLISECOND);
    } /* Endif */

    if (read_type == LOG_READ_NEXT)
    {
        log_header_ptr->LOG_NEXT = next_ptr;
    }
    else if (read_type == LOG_READ_OLDEST)
    {
        log_header_ptr->LOG_NEXT = next_ptr;
    }
    else
    {
        log_header_ptr->LOG_NEXT = NULL;
    } /* Endif */
    _INT_ENABLE();

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Resets the log to its initial state (remove all entries).
 * 
 * \param[in] log_number Log number of a previously created log.
 * 
 * \return MQX_OK
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.) 
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * 
 * \see _log_disable
 * \see _log_enable   
 */  
_mqx_uint _log_reset
(
    _mqx_uint log_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _int_disable();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_header_ptr->SIZE = 0;
    log_header_ptr->NUMBER = 1;
    log_header_ptr->LOG_WRITE = &log_header_ptr->DATA[0];
    log_header_ptr->LOG_READ = log_header_ptr->LOG_WRITE;
    log_header_ptr->LAST_LOG = log_header_ptr->LOG_WRITE;
    _int_enable();

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Tests the log component for consistency.
 * 
 * \param[out] log_error_ptr Pointer to the log in error (NULL if no error is 
 * found).
 * 
 * \return MQX_OK Log component data is valid (*Log_error_ptr is 0.).
 * \return LOG_INVALID Information for a specific log is not valid 
 * (*log_error_ptr contains a log number of the first invalid log.). 
 * \return MQX_INVALID_COMPONENT_BASE Log component data is not valid 
 * (*log_error_ptr is NULL.). 
 * 
 * \warning Disables and enables interrupts
 * 
 * \see _log_create_component
 * \see _log_create
 */ 
_mqx_uint _log_test
(
    _mqx_uint _PTR_ log_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_ptr;
    _mqx_uint                i;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_log_test, log_error_ptr);

    *log_error_ptr = 0;
    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];
    if (log_component_ptr == NULL)
    {
        _KLOGX2(KLOG_log_test, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    if (log_component_ptr->VALID != LOG_VALID)
    {
        _KLOGX2(KLOG_log_test, MQX_INVALID_COMPONENT_BASE);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    _int_disable();
    for (i = 0; i < LOG_MAXIMUM_NUMBER; i++)
    {
        log_ptr = log_component_ptr->LOGS[i];
        if (log_ptr != NULL)
        {
            /* Verify the log pointers */
            if ((log_ptr->LOG_END != &log_ptr->DATA[log_ptr->MAX]) ||
                            (log_ptr->LOG_START != &log_ptr->DATA[0]))
            {
                break;
            } /* Endif */

            if ((log_ptr->LOG_WRITE > log_ptr->LOG_END) ||
                            (log_ptr->LOG_NEXT > log_ptr->LOG_END) ||
                            (log_ptr->LOG_READ > log_ptr->LOG_END) ||
                            (log_ptr->LAST_LOG > log_ptr->LOG_END))
            {
                break;
            } /* Endif */
            if ((log_ptr->LOG_WRITE < log_ptr->LOG_START) ||
                            (log_ptr->LOG_READ < log_ptr->LOG_START) ||
                            (log_ptr->LAST_LOG < log_ptr->LOG_START))
            {
                break;
            } /* Endif */
            if ((log_ptr->LOG_NEXT != NULL) &&
                            (log_ptr->LOG_NEXT < log_ptr->LOG_START))
            {
                break;
            } /* Endif */
        } /* Endif */
    } /* Endfor */
    _int_enable();

    if (i == LOG_MAXIMUM_NUMBER)
    {
        _KLOGX2(KLOG_log_test, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    *log_error_ptr = i;
    _KLOGX3(KLOG_log_test, LOG_INVALID, i);
    return(LOG_INVALID);

} /* Endbody */

/*!
 * \brief Writes data to the log.
 * 
 * The function writes the log entry only if it returns MQX_OK.
 * 
 * \param[in] log_number           Log number of a previously created log.
 * \param[in] number_of_parameters Number of parameters to write.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_DISABLED (Log is disabled.)
 * \return LOG_FULL (Log is full and LOG_OVERWRITE is not set.)      
 */ 
_mqx_uint _log_write
(
    _mqx_uint log_number,
    _mqx_uint number_of_parameters,

    ...
)
{ /* Body */
    MQX_TICK_STRUCT          ticks;
    TIME_STRUCT              time;
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;
    _mqx_uint_ptr            data_ptr;
    va_list                  param_ptr;
    _mqx_uint                us;
    _mqx_uint                i;
    _mqx_uint                size;
    _mqx_uint                old_size;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
#endif

    log_header_ptr = log_component_ptr->LOGS[log_number];

#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    if (! (log_header_ptr->FLAGS & LOG_ENABLED))
    {
        return(LOG_DISABLED);
    } /* Endif */

    size = sizeof(LOG_ENTRY_STRUCT)/sizeof(_mqx_uint) + number_of_parameters;
#if MQX_CHECK_ERRORS
    if (size > log_header_ptr->MAX)
    {
        /* 
         * The request is to log an entry larger than the
         * entire log. Reject this.
         */
        return(LOG_FULL);
    } /* Endif */
#endif

    va_start(param_ptr, number_of_parameters);

    i = number_of_parameters + 1;

    _INT_DISABLE();
    if ((log_header_ptr->SIZE + size) > log_header_ptr->MAX)
    {
        if (log_header_ptr->FLAGS & LOG_OVERWRITE)
        {
            /* Remove leading elements until it can fit */
            while ((log_header_ptr->SIZE + size) > log_header_ptr->MAX)
            {
                data_ptr = log_header_ptr->LOG_READ;
                old_size = *data_ptr;
                log_header_ptr->SIZE -= old_size;
                data_ptr += old_size;
                if (data_ptr >= log_header_ptr->LOG_END)
                {
                    data_ptr = log_header_ptr->LOG_START +
                    (data_ptr - log_header_ptr->LOG_END);
                } /* Endif */
                if (log_header_ptr->LOG_NEXT == log_header_ptr->LOG_READ)
                {
                    /* Move up the next read pointer */
                    log_header_ptr->LOG_NEXT = data_ptr;
                } /* Endif */
                log_header_ptr->LOG_READ = data_ptr;
            } /* Endwhile */
        }
        else
        {
            _INT_ENABLE();
            va_end(param_ptr);
            return(LOG_FULL);
        } /* Endif */
    } /* Endif */

    log_header_ptr->SIZE += size;

    data_ptr = log_header_ptr->LOG_WRITE;
    log_header_ptr->LAST_LOG = data_ptr;

    *data_ptr++ = size;
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */

    *data_ptr++ = log_header_ptr->NUMBER++;
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */

    us = (_mqx_uint)_time_get_microseconds();
    PSP_ADD_TICKS(&kernel_data->TIME, &kernel_data->TIME_OFFSET, &ticks);
    PSP_TICKS_TO_TIME(&ticks, &time);

#if MQX_INT_SIZE_IN_BITS >= 32
    *data_ptr++ = (_mqx_uint)time.SECONDS;
#else
#if PSP_ENDIAN == MQX_BIG_ENDIAN
    *data_ptr++ = (_mqx_uint)((time.SECONDS >> MQX_INT_SIZE_IN_BITS) &
                    MAX_MQX_UINT);
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */
    *data_ptr++ = (_mqx_uint)(time.SECONDS & MAX_MQX_UINT);
#else
    *data_ptr++ = (_mqx_uint)(time.SECONDS & MAX_MQX_UINT);
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */
    *data_ptr++ = (_mqx_uint)((time.SECONDS >> MQX_INT_SIZE_IN_BITS) &
                    MAX_MQX_UINT);
#endif
#endif

    if (data_ptr >= log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */

#if PSP_MEMORY_ADDRESSING_CAPABILITY >= 32
    *data_ptr++ = time.MILLISECONDS;
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */
    *data_ptr++ = us;
#elif MQX_INT_SIZE_IN_BITS == 32
#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
    *data_ptr++ = time.MILLISECONDS | (us << 16);
#else
    *data_ptr++ = us | (time.MILLISECONDS << 16);
#endif
#else
    *data_ptr++ = (_mqx_uint)time.MILLISECONDS;
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */
    *data_ptr++ = us;
#endif

    if (data_ptr >= log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */

    while (--i)
    {
        *data_ptr++ = (_mqx_uint)va_arg(param_ptr, _mqx_uint);
        if (data_ptr == log_header_ptr->LOG_END)
        {
            data_ptr = log_header_ptr->LOG_START;
        } /* Endif */
    } /* Endwhile */

    log_header_ptr->LOG_WRITE = data_ptr;
    _INT_ENABLE();

    va_end(param_ptr);

    return(MQX_OK);

} /* Endbody */

#endif /* MQX_USE_LOGS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/soselset.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: soselset.c$
* $Version : 3.8.11.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the RTCS_select() implementation.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "socket.h"
#include "tcpip.h"

#include "select.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_select
* Returned Value  : socket handle
* Comments  :  Wait for data or connection requests on any socket
*      in a specified set.
*
*END*-----------------------------------------------------------------*/

uint_32 _RTCS_select
   (
      pointer     readset,
         /* [IN] set of sockets to block on */
      uint_32     read_size,
         /* [IN] size of sockset */

      pointer     writeset,
         /* [IN] set of sockets to block on */
      uint_32     write_size,
         /* [IN] size of sockset */

      uint_32     timeout
         /* [IN] specifies the maximum amount of time to wait for data */
   )
{ /* Body */
   SOCKSELECT_PARM   parms;
   uint_32           error;

   parms.sock_ptr   = readset;
   parms.sock_count = read_size;

   parms.writesock_ptr   = writeset;
   parms.writesock_count = write_size;

   parms.timeout    = timeout;
   error = RTCSCMD_issue(parms, SOCK_select);
   if (error) return RTCS_SOCKET_ERROR;

   return parms.sock;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : _RTCS_selectset
* Returned Value  : socket handle
* Comments  :  Wait for data or connection requests on any socket
*      in a specified set.  This code copies the sockset, and calls
*      _RTCS_select with the copy.  This is because SOCK_select_signal
*      zeros out the entries that are not active as part of a change
*      for the unix-like RTCS_select.  This corrupted the sockset in
*      legacy code.  Now only the copy is modified, maintaining backward
*      compatibility.
*
*END*-----------------------------------------------------------------*/

uint_32 _RTCS_selectset
   (
      pointer sockset,
      uint_32 size,
      uint_32 timeout
   )
{
   int i;
   int k = 0;
   uint_32 copy_sockset[RTCS_SELECT_MAX_FDS];

   if ((size <= 0) || (size > RTCS_SELECT_MAX_FDS) || (sockset == NULL))
      return (uint_32) RTCS_SELECT_ERROR;

   for (i=0; i<size; i++)
   {
	   if (((uint_32 *)sockset)[i] != 0)
		   copy_sockset[k++] = ((uint_32 *)sockset)[i];
   }

   return (uint_32)_RTCS_select(copy_sockset, k, NULL, 0, timeout);
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_select
* Parameters      :
*
*     _rtcs_taskid      owner            not used
*     uint_32 _PTR_     sock_ptr         [IN] array of socket handles
*     uint_32           sock_count       [IN] size of socket array
*     uint_32 _PTR_     writesock_ptr    [IN] array of write socket handles
*     uint_32           writesock_count  [IN] size of write socket array
*     uint_32           timeout          [IN] timeout, 0=forever, -1=none
*     uint_32           sock             [OUT] socket with activity
*
* Comments  :  Wait for data or connection requests on any socket
*      owned by this task.
*
*END*-----------------------------------------------------------------*/

void SOCK_select
   (
      SOCKSELECT_PARM_PTR  parms
   )
{ /* Body */
   int i, i2;
   uint_32 fds[RTCS_SELECT_MAX_FDS];
   int active = FALSE;

   // param check
   if ((parms->sock_count != 0 && parms->sock_ptr == NULL) || (parms->writesock_count != 0 && parms->writesock_ptr == NULL)) {
      RTCSCMD_complete(parms, RTCSERR_INVALID_PARAMETER);
      return;
   }

   // read fds - check every socket in the supplied array
   if (parms->sock_count) {
      _mem_zero(fds, parms->sock_count * sizeof(uint_32));
      for (i = 0, i2 = 0; i < parms->sock_count; i++) {
         if (SOCK_select_activity((SOCKET_STRUCT_PTR)parms->sock_ptr[i], 0)) {
            fds[i2++] = parms->sock_ptr[i];
         }
      }

      // update socket array - only active sockets
      if (i2) {
         _mem_zero(parms->sock_ptr, parms->sock_count * sizeof(uint_32));
         _mem_copy(fds, parms->sock_ptr, i2 * sizeof(uint_32));
         parms->sock_count = i2;
         parms->sock = fds[0];

         active = TRUE;
      }
   }

   // write fds - check every socket in the supplied array
   if (parms->writesock_count) {
      _mem_zero(fds, parms->writesock_count * sizeof(uint_32));
      for (i = 0, i2 = 0; i < parms->writesock_count; i++) {
         if (SOCK_select_activity((SOCKET_STRUCT_PTR)parms->writesock_ptr[i], 1)) {
            fds[i2++] = parms->writesock_ptr[i];
         }
      }

      // update socket array - only active sockets
      if (i2) {
         _mem_zero(parms->writesock_ptr, parms->writesock_count * sizeof(uint_32));
         _mem_copy(fds, parms->writesock_ptr, i2 * sizeof(uint_32));
         parms->writesock_count = i2;

         if (active == FALSE) {
            // write fds active but read fds no - set read fds to zero
            _mem_zero(parms->sock_ptr, parms->sock_count * sizeof(uint_32));
            parms->sock_count = 0;
            parms->sock = fds[0];
         }

         active = TRUE;
      }
      else if (active == TRUE) {
         // read fds active but write fds no - set write fds to zero
         _mem_zero(parms->writesock_ptr, parms->writesock_count * sizeof(uint_32));
         parms->writesock_count = 0;
      }
   }

   if (active == TRUE) {
      // some fds active
      RTCSCMD_complete(parms, RTCS_OK);
      return;
   }

   if (parms->timeout == (uint_32)-1) {
      parms->sock = 0;
      RTCSCMD_complete(parms, RTCS_OK);
      return;
   } /* Endif */

   parms->owner = 0;
   SOCK_select_block(parms);

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/int/serl_int.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_int.c$
* $Version : 3.8.19.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the driver functions for the interrupt driven
*   serial asynchronous character I/O.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "serial.h"
#include "charq.h"
#include "bsp.h"
#include "serinprv.h"


#if MQX_ENABLE_LOW_POWER

extern LPM_NOTIFICATION_RESULT _io_serial_int_clock_configuration_callback (LPM_NOTIFICATION_STRUCT_PTR, pointer);
extern LPM_NOTIFICATION_RESULT _io_serial_int_operation_mode_callback (LPM_NOTIFICATION_STRUCT_PTR, pointer);

#endif


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_serial_int_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install an interrupt driven serial device.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_serial_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr             identifier,
  
      /* [IN] The I/O init function */
      _mqx_uint (_CODE_PTR_ init)(pointer, char _PTR_),

      /* [IN] The enable interrupts function */
      _mqx_uint (_CODE_PTR_ enable_ints)(pointer),

      /* [IN] The I/O de-init function */
      _mqx_uint (_CODE_PTR_ deinit)(pointer, pointer),

      /* [IN] The output function */
      void    (_CODE_PTR_  putc)(pointer, char),

      /* [IN] The I/O ioctl function */
      _mqx_uint (_CODE_PTR_ ioctl)(pointer, _mqx_uint, pointer),

      /* [IN] The I/O init data pointer */
      pointer              init_data_ptr,
      
      /* [IN] The I/O queue size to use */
      _mqx_uint             queue_size
   )
{ /* Body */
   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr;
   uint_32                         result;

   int_io_dev_ptr = _mem_alloc_system_zero(
      (_mem_size)sizeof(IO_SERIAL_INT_DEVICE_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (int_io_dev_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(int_io_dev_ptr,MEM_TYPE_IO_SERIAL_INT_DEVICE_STRUCT);    

   int_io_dev_ptr->DEV_INIT          = init;
   int_io_dev_ptr->DEV_ENABLE_INTS   = enable_ints;
   int_io_dev_ptr->DEV_DEINIT        = deinit;
   int_io_dev_ptr->DEV_PUTC          = putc;
   int_io_dev_ptr->DEV_IOCTL         = ioctl;
   int_io_dev_ptr->DEV_INIT_DATA_PTR = init_data_ptr;
   int_io_dev_ptr->QUEUE_SIZE        = queue_size;
   
   result = _io_dev_install(identifier,
      _io_serial_int_open, _io_serial_int_close,
      _io_serial_int_read, _io_serial_int_write,
      _io_serial_int_ioctl,
      (pointer)int_io_dev_ptr); 
   
#if MQX_ENABLE_LOW_POWER
   if (MQX_OK == result)
   {
      LPM_REGISTRATION_STRUCT registration;
      registration.CLOCK_CONFIGURATION_CALLBACK = _io_serial_int_clock_configuration_callback;
      registration.OPERATION_MODE_CALLBACK = _io_serial_int_operation_mode_callback;
      registration.DEPENDENCY_LEVEL = BSP_LPM_DEPENDENCY_LEVEL_SERIAL_INT;          
      result = _lpm_register_driver (&registration, int_io_dev_ptr, &(int_io_dev_ptr->LPM_INFO.REGISTRATION_HANDLE));
      if (MQX_OK == result)
      {
         _lwsem_create (&(int_io_dev_ptr->LPM_INFO.LOCK), 1);
         int_io_dev_ptr->LPM_INFO.FLAGS = 0;
      }
   }
#endif
   
   return result;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_serial_int_uninstall
* Returned Value   : _mqx_int a task error code or MQX_OK
* Comments         :
*    Un-Install a interrupt driven async serial device.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_serial_int_uninstall
   (
      /* [IN] The IO device structure for the device */
      IO_DEVICE_STRUCT_PTR   io_dev_ptr
   )
{ /* Body */
   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

   if (int_dev_ptr->COUNT == 0) {
      if (int_dev_ptr->DEV_DEINIT) {

#if MQX_ENABLE_LOW_POWER          
         _lwsem_wait (&(int_dev_ptr->LPM_INFO.LOCK));
#endif
         (*int_dev_ptr->DEV_DEINIT)(int_dev_ptr->DEV_INIT_DATA_PTR,
            int_dev_ptr->DEV_INFO_PTR);
#if MQX_ENABLE_LOW_POWER          
         _lwsem_post (&(int_dev_ptr->LPM_INFO.LOCK));
#endif
          
      } /* Endif */
      _mem_free(int_dev_ptr->IN_QUEUE);
      _mem_free(int_dev_ptr->OUT_QUEUE);
      _taskq_destroy(int_dev_ptr->IN_WAITING_TASKS);
      _taskq_destroy(int_dev_ptr->OUT_WAITING_TASKS);
      
#if MQX_ENABLE_LOW_POWER
      _lpm_unregister_driver (int_dev_ptr->LPM_INFO.REGISTRATION_HANDLE);
      _lwsem_destroy (&(int_dev_ptr->LPM_INFO.LOCK));
#endif
      
      _mem_free(int_dev_ptr);
      return(IO_OK);
   } else {
      return(IO_ERROR_DEVICE_BUSY);
   } /* Endif */

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_serial_int_open
* Returned Value   : _mqx_int task error code
* Comments         :
*    This routine initializes an interrupt I/O channel. It acquires
*    memory, then stores information into it about the channel.
*    This memory is returned as a 'handle' to be used for all other 
*    interrupt I/O functions.
*
* 
*END**********************************************************************/

_mqx_int _io_serial_int_open
   (
      /* [IN] the file handle for the device being opened */
      FILE_DEVICE_STRUCT_PTR fd_ptr,
       
      /* [IN] the remaining portion of the name of the device */
      char             _PTR_ open_name_ptr,

      /* [IN] the flags to be used during operation:
      ** echo, translation, xon/xoff
      */
      char             _PTR_ flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR            io_dev_ptr;
   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr;
   _mqx_uint                       result = MQX_OK;
   _mqx_uint                       ioctl_val;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   int_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
   
   if (int_io_dev_ptr->COUNT) {
      /* Device is already opened */
      int_io_dev_ptr->COUNT++;
      fd_ptr->FLAGS = int_io_dev_ptr->FLAGS;
      return(result);
   } /* Endif */

   int_io_dev_ptr->IN_WAITING_TASKS  = _taskq_create(MQX_TASK_QUEUE_FIFO);
   int_io_dev_ptr->OUT_WAITING_TASKS = _taskq_create(MQX_TASK_QUEUE_FIFO);

   int_io_dev_ptr->IN_QUEUE = (pointer)_mem_alloc_system(
      sizeof(CHARQ_STRUCT) - (4 * sizeof(char)) + int_io_dev_ptr->QUEUE_SIZE);
   int_io_dev_ptr->OUT_QUEUE = (pointer)_mem_alloc_system(
      sizeof(CHARQ_STRUCT) - (4 * sizeof(char)) + int_io_dev_ptr->QUEUE_SIZE);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if ((int_io_dev_ptr->IN_QUEUE == NULL) || 
       (int_io_dev_ptr->OUT_QUEUE == NULL) ||
       (int_io_dev_ptr->IN_WAITING_TASKS == NULL) ||
       (int_io_dev_ptr->OUT_WAITING_TASKS == NULL))
   {
      if (int_io_dev_ptr->IN_QUEUE != NULL){
         _mem_free(int_io_dev_ptr->IN_QUEUE);
      } /* Endif */
      if (int_io_dev_ptr->OUT_QUEUE != NULL){
         _mem_free(int_io_dev_ptr->OUT_QUEUE);
      } /* Endif */
      if (int_io_dev_ptr->IN_WAITING_TASKS != NULL) {
         _taskq_destroy(int_io_dev_ptr->IN_WAITING_TASKS);
      }/* Endif */
      if (int_io_dev_ptr->OUT_WAITING_TASKS != NULL) {
         _taskq_destroy(int_io_dev_ptr->OUT_WAITING_TASKS);
      }/* Endif */
      return(MQX_OUT_OF_MEMORY);
   }/* Endif */
#endif            
   _mem_set_type(int_io_dev_ptr->IN_QUEUE,MEM_TYPE_IO_SERIAL_IN_QUEUE);       
   _mem_set_type(int_io_dev_ptr->OUT_QUEUE,MEM_TYPE_IO_SERIAL_OUT_QUEUE);      

   _CHARQ_INIT(int_io_dev_ptr->IN_QUEUE, int_io_dev_ptr->QUEUE_SIZE);
   _CHARQ_INIT(int_io_dev_ptr->OUT_QUEUE, int_io_dev_ptr->QUEUE_SIZE);
   int_io_dev_ptr->INPUT_HIGH_WATER_MARK = int_io_dev_ptr->QUEUE_SIZE -
      int_io_dev_ptr->QUEUE_SIZE/8;
   int_io_dev_ptr->INPUT_LOW_WATER_MARK  = int_io_dev_ptr->QUEUE_SIZE/2;
   int_io_dev_ptr->FLAGS = (_mqx_uint)flags;
   fd_ptr->FLAGS      = (_mqx_uint)flags;

#if MQX_ENABLE_LOW_POWER          
   _lwsem_wait (&(int_io_dev_ptr->LPM_INFO.LOCK));
#endif
   result = (*int_io_dev_ptr->DEV_INIT)(int_io_dev_ptr, open_name_ptr);
#if MQX_ENABLE_LOW_POWER          
   _lwsem_post (&(int_io_dev_ptr->LPM_INFO.LOCK));
#endif
   
   if (result == MQX_OK) {
       
#if MQX_ENABLE_LOW_POWER          
      _lwsem_wait (&(int_io_dev_ptr->LPM_INFO.LOCK));
#endif
      result = (*int_io_dev_ptr->DEV_ENABLE_INTS)(int_io_dev_ptr->DEV_INFO_PTR);
#if MQX_ENABLE_LOW_POWER          
      _lwsem_post (&(int_io_dev_ptr->LPM_INFO.LOCK));
#endif
      
      if (int_io_dev_ptr->DEV_IOCTL != NULL) {
         if ((_mqx_uint)flags & IO_SERIAL_HW_FLOW_CONTROL) {
            ioctl_val = IO_SERIAL_RTS;
            (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_SET_HW_SIGNAL, &ioctl_val);
         } /* Endif */
         ioctl_val = (_mqx_uint)flags;
         (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_SET_FLAGS, &ioctl_val);
      }
      if (result == MQX_OK && ((_mqx_uint)flags & IO_SERIAL_NON_BLOCKING) 
         && (_mqx_uint)flags & (IO_SERIAL_TRANSLATION | IO_SERIAL_ECHO | IO_SERIAL_XON_XOFF)) {
         result = MQX_INVALID_PARAMETER;
      } /* Endif */
   } /* Endif */
   
   if (result != MQX_OK) {
      _mem_free(int_io_dev_ptr->IN_QUEUE);
      _mem_free(int_io_dev_ptr->OUT_QUEUE);
      _taskq_destroy(int_io_dev_ptr->IN_WAITING_TASKS);
      _taskq_destroy(int_io_dev_ptr->OUT_WAITING_TASKS);
   }
   int_io_dev_ptr->COUNT = 1;
   return(result);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_serial_int_close
* Returned Value   : _mqx_int error code
* Comments         :
*    This routine closes the serial I/O channel.
* 
*END**********************************************************************/

_mqx_int _io_serial_int_close
   (
      /* [IN] the file handle for the device being closed */
      FILE_DEVICE_STRUCT_PTR fd_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR            io_dev_ptr;
   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr;
   _mqx_int                        result = MQX_OK;
   _mqx_int                        ioctl_val;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   int_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   if (--int_io_dev_ptr->COUNT == 0) {

      if (int_io_dev_ptr->DEV_IOCTL != NULL) {
         if (fd_ptr->FLAGS & IO_SERIAL_HW_FLOW_CONTROL) {
            ioctl_val = IO_SERIAL_RTS;
            (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_CLEAR_HW_SIGNAL, &ioctl_val);
         }
      }
      if (int_io_dev_ptr->DEV_DEINIT) {
          
#if MQX_ENABLE_LOW_POWER          
         _lwsem_wait (&(int_io_dev_ptr->LPM_INFO.LOCK));
#endif
         result = (*int_io_dev_ptr->DEV_DEINIT)(int_io_dev_ptr->DEV_INIT_DATA_PTR,
            int_io_dev_ptr->DEV_INFO_PTR);
#if MQX_ENABLE_LOW_POWER          
         _lwsem_post (&(int_io_dev_ptr->LPM_INFO.LOCK));
#endif
          
      } /* Endif */
      _mem_free(int_io_dev_ptr->IN_QUEUE);
      _mem_free(int_io_dev_ptr->OUT_QUEUE);
      _taskq_destroy(int_io_dev_ptr->IN_WAITING_TASKS);
      _taskq_destroy(int_io_dev_ptr->OUT_WAITING_TASKS);
   } /* Endif */
   return(result);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_serial_int_read
* Returned Value   : _mqx_int number of characters read
* Comments         :
*    This routine reads characters from the input ring buffer,
*    converting carriage return ('\r') characters to newlines,
*    and then echoing the input characters.
*
*END*********************************************************************/

_mqx_int _io_serial_int_read
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] where the characters are to be stored */
      char             _PTR_ data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int               num
      
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR            io_dev_ptr;
   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr;
   _mqx_int                        ioctl_val;
   uchar                           c = 0;
   _mqx_uint                       flags;
   _mqx_int                        i = num;
   volatile CHARQ_STRUCT _PTR_     in_queue;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   int_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
   flags          = fd_ptr->FLAGS;

   while ( i ) {

      in_queue = int_io_dev_ptr->IN_QUEUE;
      _int_disable();
      if(flags & IO_SERIAL_NON_BLOCKING) {
          if (_CHARQ_SIZE(in_queue) == 0) {
              num -= i;
              _int_enable();
              break;
          } /* Endif */
      } else {
          while (_CHARQ_SIZE(in_queue) == 0) {
             _taskq_suspend(int_io_dev_ptr->IN_WAITING_TASKS);
          } /* Endwhile */  
      } /* Endif */
      _CHARQ_DEQUEUE(in_queue,c);

      if (int_io_dev_ptr->HAVE_STOPPED_INPUT) {
         if (_CHARQ_SIZE(in_queue) < int_io_dev_ptr->INPUT_LOW_WATER_MARK) {
            if (flags & IO_SERIAL_HW_FLOW_CONTROL) {
               if (int_io_dev_ptr->DEV_IOCTL != NULL) {
                  ioctl_val = IO_SERIAL_RTS;
                  (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_SET_HW_SIGNAL, &ioctl_val);
               }
               int_io_dev_ptr->HAVE_STOPPED_INPUT = FALSE;
            } else {
               if (int_io_dev_ptr->OUTPUT_ENABLED && !int_io_dev_ptr->HAVE_STOPPED_OUTPUT) {
                  int_io_dev_ptr->MUST_START_INPUT = TRUE;
               } else {
                  int_io_dev_ptr->HAVE_STOPPED_INPUT = FALSE;
                  int_io_dev_ptr->OUTPUT_ENABLED = TRUE;
                  (*int_io_dev_ptr->DEV_PUTC)(int_io_dev_ptr, CNTL_Q);
               } /* Endif */
            } /* Endif */
         } /* Endif */
      } /* Endif */
      _int_enable();

      if (flags & IO_SERIAL_TRANSLATION) {
         if (c == '\r') {
            /* Start CR 387 */
            if (flags & IO_SERIAL_ECHO) {
               _io_serial_int_putc_internal(int_io_dev_ptr, (char)c, 0);
            } /* Endif */
            /* End CR 387 */
            c = '\n';
         } else if ((c == '\b') && (flags & IO_SERIAL_ECHO)) {
            _io_serial_int_putc_internal(int_io_dev_ptr, (char)'\b', 0);
            _io_serial_int_putc_internal(int_io_dev_ptr, (char)' ', 0);
         } /* Endif */
      } /* Endif */

      if (flags & IO_SERIAL_ECHO) {
         _io_serial_int_putc_internal(int_io_dev_ptr, (char)c, 0);
      } /* Endif */

      *data_ptr++ = c;
      --i;
      
   } /* Endwhile */

   return num;

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_serial_int_write
* Returned Value   : _mqx_int
* Comments         :
*    This routine writes the character to the device.
*    It also converts the C '\n' into '\n\r', if required.
*
*END**********************************************************************/

_mqx_int _io_serial_int_write
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] where the characters to print out are */
      char             _PTR_ data_ptr,

      /* [IN] the number of characters to output */
      _mqx_int               num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR            io_dev_ptr;
   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr;
   _mqx_uint                       flags;
   _mqx_int                        i = num;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   int_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
   flags          = fd_ptr->FLAGS;

#if MQX_ENABLE_LOW_POWER          
   _lwsem_wait (&(int_io_dev_ptr->LPM_INFO.LOCK));
#endif

   while ( i != 0 ) {
      if (flags & IO_SERIAL_TRANSLATION) {
         if (*data_ptr == '\n') {
            (void)_io_serial_int_putc_internal(int_io_dev_ptr, '\r', 0);
         } /* Endif */
      } /* Endif */
      if (_io_serial_int_putc_internal(int_io_dev_ptr, *data_ptr, flags)){
          data_ptr++;
          i--;
      } else {
         num -= i;
         break;
      } /* Endif */
      
   } /* Endwhile */
   
#if MQX_ENABLE_LOW_POWER          
   _lwsem_post (&(int_io_dev_ptr->LPM_INFO.LOCK));
#endif
   
   return num;
   
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_serial_int_ioctl
* Returned Value   : _mqx_int
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_serial_int_ioctl
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint              cmd,

      /* [IN] the ioctl parameters */
      pointer                param_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR            io_dev_ptr;
   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr;
   _mqx_uint                       result = MQX_OK;
   _mqx_uint_ptr                   uparam_ptr = (_mqx_uint_ptr)param_ptr;

   io_dev_ptr     = fd_ptr->DEV_PTR;
   int_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   switch (cmd) {
      case IO_IOCTL_CHAR_AVAIL:
         if ( _CHARQ_SIZE(int_io_dev_ptr->IN_QUEUE) ) {
           *((boolean _PTR_)param_ptr) = TRUE;
         } else {
           *((boolean _PTR_)param_ptr) = FALSE;
         } /* Endif */
      break;

      case IO_IOCTL_SERIAL_GET_FLAGS:
         *((_mqx_uint_ptr)param_ptr) = int_io_dev_ptr->FLAGS;
         break;

      case IO_IOCTL_SERIAL_SET_FLAGS:
         int_io_dev_ptr->FLAGS = *((_mqx_uint_ptr)param_ptr);
         fd_ptr->FLAGS = *((_mqx_uint_ptr)param_ptr);
         if (int_io_dev_ptr->DEV_IOCTL != NULL) {
            result = (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR,
               cmd, param_ptr);
         } /* Endif */
         break;

      case IO_IOCTL_SERIAL_TRANSMIT_DONE:
         *((boolean _PTR_)param_ptr) = !(int_io_dev_ptr->OUTPUT_ENABLED);
         break;
      
      case IO_IOCTL_FLUSH_OUTPUT:
         /* Disable interrupts to avoid situation that last TX interrupt comes after successfull !_CHARQ_EMPTY() */
         _int_disable();
         while(!_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) {
            /* wait untill all chars are sent from output queue */
            _taskq_suspend(int_io_dev_ptr->OUT_WAITING_TASKS); 
         };
         _int_enable();
         break;
      
      case IO_IOCTL_DEVICE_IDENTIFY:
         /* return the device identify */
         uparam_ptr[0] = IO_DEV_TYPE_PHYS_SERIAL_INTERRUPT;
         uparam_ptr[1] = 0;
         uparam_ptr[2] = IO_DEV_ATTR_INTERRUPT | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
         result = MQX_OK;   
         break;

      case IO_IOCTL_SERIAL_CAN_TRANSMIT:
         *uparam_ptr = (int_io_dev_ptr->OUT_QUEUE->MAX_SIZE - int_io_dev_ptr->OUT_QUEUE->CURRENT_SIZE);
         result = MQX_OK;   
         break;

      case IO_IOCTL_SERIAL_CAN_RECEIVE:
         *uparam_ptr = (int_io_dev_ptr->IN_QUEUE->MAX_SIZE - int_io_dev_ptr->IN_QUEUE->CURRENT_SIZE);
         result = MQX_OK;   
         break;
            
      default:
         if (int_io_dev_ptr->DEV_IOCTL != NULL) {
            result = (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR,
               cmd, param_ptr);
         } /* Endif */
      break;
   } /* Endswitch */
   return result;

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_serial_int_putc_internal
* Returned Value   : void
* Comments         : 
*   This function writes out the character to the device if the queue
* is empty, or it writes it to the device.  If the queue is full, this
* function will suspend the writing task.
*
*END*********************************************************************/

boolean _io_serial_int_putc_internal
   (
      /* [IN] the interrupt io device information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the character to print out */
      char                     c, 
      _mqx_uint                flags
   )
{ /* Body */
   volatile CHARQ_STRUCT _PTR_ out_queue;

   /* Start CR 388 */
#if (PSP_MEMORY_ADDRESSING_CAPABILITY > 8 )
   c &= 0xFF;
#endif
   /* End CR 388 */

   out_queue = int_io_dev_ptr->OUT_QUEUE;
   _int_disable();
   if(flags & IO_SERIAL_NON_BLOCKING) {
      if (_CHARQ_FULL(out_queue)) {
          _int_enable();
          return FALSE;
      } /* Endif */
   } else {
      while (_CHARQ_FULL(out_queue)) {
         /* Lets wait */
         _taskq_suspend(int_io_dev_ptr->OUT_WAITING_TASKS);
      } /* Endif */
   } /* Endif */


   if (int_io_dev_ptr->OUTPUT_ENABLED || int_io_dev_ptr->HAVE_STOPPED_OUTPUT) {
      _CHARQ_ENQUEUE(out_queue,c);
   } else {
      int_io_dev_ptr->OUTPUT_ENABLED = TRUE;
      (*int_io_dev_ptr->DEV_PUTC)(int_io_dev_ptr, c);
   } /* Endif */
   _int_enable();
   return TRUE;

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_serial_int_addc
* Returned Value   : none
* Comments         :
*    This function is called by the device io interrupt handler, to add
* a character to the input queue.
*
*END*********************************************************************/

boolean _io_serial_int_addc
   (
      /* [IN] the interrupt I/O context information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the character to add to the input queue */
      char                            c
   )
{ /* Body */
   CHARQ_STRUCT_PTR in_queue;
   _mqx_uint       ioctl_val;

   if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) {
      if (int_io_dev_ptr->HAVE_STOPPED_OUTPUT) {
         if (c == CNTL_Q) {
            int_io_dev_ptr->HAVE_STOPPED_OUTPUT = FALSE;
            return TRUE;
         } /* Endif */
      } else {
         if (c == CNTL_S) {
            int_io_dev_ptr->HAVE_STOPPED_OUTPUT = TRUE;
            return TRUE;
         } /* Endif */
      } /* Endif */
   } /* Endif */

   in_queue = int_io_dev_ptr->IN_QUEUE;
   if (_CHARQ_NOT_FULL(in_queue)) {
      _CHARQ_ENQUEUE(in_queue,c);

      if (int_io_dev_ptr->FLAGS & (IO_SERIAL_XON_XOFF |
         IO_SERIAL_HW_FLOW_CONTROL))
      {
         if (_CHARQ_SIZE(in_queue) > int_io_dev_ptr->INPUT_HIGH_WATER_MARK) {
            if (!int_io_dev_ptr->HAVE_STOPPED_INPUT) {
               if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) {
                  int_io_dev_ptr->MUST_STOP_INPUT = TRUE;
               } else {
                  if (int_io_dev_ptr->DEV_IOCTL != NULL) {
                     ioctl_val = IO_SERIAL_RTS;
                     (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_CLEAR_HW_SIGNAL, &ioctl_val);
                  }
                  int_io_dev_ptr->HAVE_STOPPED_INPUT = TRUE;
               } /* Endif */
            } /* Endif */
         } else if (_CHARQ_SIZE(in_queue) < int_io_dev_ptr->INPUT_LOW_WATER_MARK) {
            if (int_io_dev_ptr->HAVE_STOPPED_INPUT) {
               if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) {
                  int_io_dev_ptr->MUST_START_INPUT = TRUE;
               } else {
                  if (int_io_dev_ptr->DEV_IOCTL != NULL) {
                     ioctl_val = IO_SERIAL_RTS;
                     (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_SET_HW_SIGNAL, &ioctl_val);
                  }
                  int_io_dev_ptr->HAVE_STOPPED_INPUT = FALSE;
               } /* Endif */
            } /* Endif */
         } /* Endif */
      } /* Endif */
   } else {
      /* indicate that tossed the character */
      return FALSE;
   } /* Endif */

   if (_QUEUE_GET_SIZE(int_io_dev_ptr->IN_WAITING_TASKS)) {
      _taskq_resume(int_io_dev_ptr->IN_WAITING_TASKS, TRUE);
   } /* Endif */
   return TRUE;
   
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _io_serial_int_nextc
* Returned Value   : _mqx_int, the next character to write out.
* Comments         :
*    This function returns the next character to send out, or -1 if
* no more output characters are available
*
*END*********************************************************************/

_mqx_int _io_serial_int_nextc
   (
      /* [IN] the interrupt I/O context information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr
   )
{ /* Body */
   uchar c;

   if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) {
      if (int_io_dev_ptr->MUST_STOP_INPUT) {
         int_io_dev_ptr->MUST_STOP_INPUT    = FALSE;
         int_io_dev_ptr->HAVE_STOPPED_INPUT = TRUE;
        return((int_32)CNTL_S);
      } else if (int_io_dev_ptr->MUST_START_INPUT) {
         int_io_dev_ptr->MUST_START_INPUT   = FALSE;
         int_io_dev_ptr->HAVE_STOPPED_INPUT = FALSE;
         return((int_32)CNTL_Q);
      } /* Endif */
   } /* Endif */

   if (int_io_dev_ptr->HAVE_STOPPED_OUTPUT
      || (! int_io_dev_ptr->OUTPUT_ENABLED))
   {
      return(-1);
   } /* Endif */

   if (_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) {
      /* No output */
      int_io_dev_ptr->OUTPUT_ENABLED = FALSE;
      if (_QUEUE_GET_SIZE(int_io_dev_ptr->OUT_WAITING_TASKS)) {
         _taskq_resume(int_io_dev_ptr->OUT_WAITING_TASKS, TRUE);
      } /* Endif */
      return(-1);
   }/* Endif */

   _CHARQ_DEQUEUE(int_io_dev_ptr->OUT_QUEUE, c);
   return((_mqx_int)c);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sai/int/sai_int_prv.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sai_int_prv.h$
* $Version : 3.8.2.0$
* $Date    : Aug-20-2012$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the SAI I/O functions.
*
*END************************************************************************/

#ifndef __SAI_INT_PRV_H__
#define __SAI_INT_PRV_H__

/* 
** TYPE DECLARATION 
*/

typedef struct io_sai_device_struct
{

    /* The I/O init function */
    _mqx_int (_CODE_PTR_ DEV_INIT)(pointer);

    /* The I/O deinit function */
    _mqx_int (_CODE_PTR_ DEV_DEINIT)(pointer, pointer);

    /* [IN] The READ function */
    _mqx_int (_CODE_PTR_ DEV_READ)(pointer, char_ptr, uint_32);

    /* [IN] The WRITE function */
    _mqx_int (_CODE_PTR_ DEV_WRITE)(pointer, char_ptr, uint_32);

    /* The ioctl function, (change bauds etc) */
    _mqx_int (_CODE_PTR_ DEV_IOCTL)(pointer, _mqx_int, pointer);

    /* The I/O channel initialization data */
    pointer DEV_INIT_DATA_PTR;

    /* Device specific information */
    pointer DEV_INFO_PTR;

    /* Open count for number of accessing file descriptor for reading */
    _mqx_int READ_COUNT;
    
    /* Open count for number of accessing file descriptor for writing */
    _mqx_int WRITE_COUNT;
    
    /* Open flags for this channel */
    _mqx_int FLAGS;
    
    LWSEM_STRUCT LWSEM;

} IO_SAI_DEVICE_STRUCT, _PTR_ IO_SAI_DEVICE_STRUCT_PTR;

/*
** FUNCTION PROTOTYPE
*/

#ifdef __cplusplus
extern "C" 
{
#endif

    _mqx_int _io_sai_int_open(MQX_FILE_PTR fd_ptr, char_ptr open_name_ptr, char_ptr flags);
    _mqx_int _io_sai_int_close(MQX_FILE_PTR fd_ptr);
    _mqx_int _io_sai_int_read(MQX_FILE_PTR fd_ptr, char_ptr data_ptr, _mqx_int n);
    _mqx_int _io_sai_int_write(MQX_FILE_PTR fd_ptr, char_ptr data_ptr, _mqx_int n);
    _mqx_int _io_sai_int_ioctl(MQX_FILE_PTR fd_ptr, _mqx_uint cmd, pointer input_param_ptr);
    _mqx_int _io_sai_int_uninstall(IO_DEVICE_STRUCT_PTR io_dev_ptr);

#ifdef __cplusplus
}
#endif

#endif /* __SAI_INT_PRV_H__ */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Tan.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Tan.h
*
* @author   B04459
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_Tan function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef GFLIB_TAN_H_
#define GFLIB_TAN_H_

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*! Function alias for the #GFLIB_TanANSIC function.*/
#define GFLIB_Tan(f32In) GFLIB_TanANSIC(f32In, &gflibTanCoef)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_TAN_TAYLOR_COEF_T "\GFLIB_Tan.h"

@brief      Structure containing four polynomial coefficients for one sub-interval.

@details    Output of \f$\tan\left(\pi\cdot \mbox{f32In}\right)\f$ for
            interval \f$\left[0,\frac{\pi}{4}\right)\f$ of the input angles is divided
            into eight sub-sectors. Polynomial approximation is done using a 4th
            order polynomial, for each sub-sector respectively. Four coefficients
            for a single sub-interval are stored in this (#GFLIB_TAN_TAYLOR_COEF_T)
            structure.
*//*-------------------------------------------------------------------------*/
typedef struct
{
	Frac32  f32A[4];          /*!< Array of four 32-bit elements for storing the polynomial
                                    coefficients for one sub-interval. */
}GFLIB_TAN_TAYLOR_COEF_T;

/*------------------------------------------------------------------------*//*!
@struct GFLIB_TANTLR_T "\GFLIB_Tan.h"

@brief      Structure containing eight sub-structures with polynomial coefficients
            to cover all sub-intervals.

@details    Output of \f$\tan\left(\pi\cdot \mbox{f32In}\right)\f$ for
            interval \f$\left[0,\frac{\pi}{4}\right)\f$ of the input angles is divided
            into eight sub-sectors. Polynomial approximation is done using a 4th
            order polynomial, for each sub-sector respectively. Eight arrays,
            each including four polynomial coefficients for each sub-interval,
            are stored in this (#GFLIB_TANTLR_T) structure.

            \par
            By calling the function alias #GFLIB_Tan, default values of the coefficients
            are used. Polynomial coefficients can be modified by the user
            and in such a case the full function call shall be used, i.e. #GFLIB_TanANSIC.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    GFLIB_TAN_TAYLOR_COEF_T  GFLIB_TAN_SECTOR[8]; /*!< Array of eight elements for
                                                       storing eight sub-arrays
                                                       (each sub-array contains four
                                                       32-bit coefficients)
                                                       for all sub-intervals.*/
}GFLIB_TANTLR_T;

/******************************************************************************
* Exported Variables
******************************************************************************/
extern const GFLIB_TANTLR_T gflibTanCoef;

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*!
* @ingroup GFLIB_GROUP
*/
extern Frac32 GFLIB_TanANSIC(Frac32 f32In, const GFLIB_TANTLR_T * const pParam);

/******************************************************************************
* Inline functions
******************************************************************************/

#endif /*GFLIB_TAN_H_*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/debug/iodebug.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: debug.h$
* $Version : 3.8.3.0$
* $Date    : Sep-16-2011$
*
* Comments:
*
*   The file contains public functions prototype, defines, structure 
*   definitions private to the debug driver
*
*END************************************************************************/
#ifndef __iodebug_h__
#define __iodebug_h__


/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/
/* IOCLT flag - change flush character */
#define IO_IOCTL_IODEBUG_SET_FLUSH_CHAR         _IO(IO_TYPE_IODEBUG,0x01)
/* No flush character */
#define IODEBUG_NOFLUSH_CHAR                    '\0' 
#define IODEBUG_MODE_SEMIHOST                   0
#define IODEBUG_MODE_ITM                        1

/*--------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/

typedef struct { 
    uint_32 MODE;
    uint_32 DATA_LENGTH;
    char    FLUSH_CHAR;
} IODEBUG_INIT_STRUCT, _PTR_ IODEBUG_INIT_STRUCT_PTR;

typedef const IODEBUG_INIT_STRUCT _PTR_ IODEBUG_INIT_STRUCT_CPTR;


/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_debug_install(char_ptr, IODEBUG_INIT_STRUCT_CPTR);
extern _mqx_int _io_debug_uninstall(IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_qpit.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_qpit.c$
* $Version : 3.8.13.0$
* $Date    : Sep-13-2012$
*
* Comments:
*
*    This file contains definitions for the Qoriwa PIT timer driver.
*
*END***********************************************************************/


#include "mqx_inc.h"
#include <bsp.h>
#include "bsp_prv.h"

#include "timer_qpit.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qpit_get_hwticks
* Returned Value   : Number of hwticks elapsed since last interrupt
* Comments         :
*
*
*END*----------------------------------------------------------------------*/

static uint_32 _qpit_get_hwticks(pointer p)
{
    uint_32 ticks;
    uint_32 ref;

    VQPIT_TIMER_REG_STRUCT_PTR qpit_timer_ptr = (VQPIT_TIMER_REG_STRUCT_PTR)p;

    ref = qpit_timer_ptr->LDVAL;
    ticks = ref - qpit_timer_ptr->CVAL;

    if (qpit_timer_ptr->TFLG & QPIT_TFLG_TIF)
    {
       /* Need to re-read CVAL as it may have rolled between first read and read of TFLG */
       ticks = ref + (ref-qpit_timer_ptr->CVAL) + 1;
    }

    return ticks;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qpit_get_period
* Returned Value   : Number of hwticks per tick
* Comments         : Initilizes QPIT
*
*
*END*----------------------------------------------------------------------*/

static uint_32 _qpit_get_period
    (
        /* [IN] the device to initialize */
        VQPIT_REG_STRUCT_PTR  qpit_ptr,

        /* [IN] the channel to initialize */
        uint_32   channel
    )
{
   return qpit_ptr->TIMERS[channel].LDVAL + 1;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qpit_timer_init
* Returned Value   : Number of hwticks per tick
* Comments         : Initilizes QPIT
*
*
*END*----------------------------------------------------------------------*/

static uint_32 _qpit_timer_init
    (
        /* [IN] the device to initialize */
        VQPIT_REG_STRUCT_PTR  qpit_ptr,

        /* [IN] the channel to initialize */
        uint_32   channel,

        /* [IN] ticks per second */
        uint_32   tickfreq,

        /* [IN] input clock speed in Hz */
        uint_32   clk
    )
{
   uint_32 period;

   
   
   period = (uint_32)(((clk << 1)/tickfreq + 1) >> 1);

   /* Enable PIT module, disable count on breakpoint */
   qpit_ptr->MCR = QPIT_MCR_FRZ;

   /* Disable timer and interrupt */
   qpit_ptr->TIMERS[channel].TCTRL = 0;

   qpit_ptr->TIMERS[channel].LDVAL = period-1;

   /* Clear any pending interrupt */
   qpit_ptr->TIMERS[channel].TFLG = QPIT_TFLG_TIF;

   /* Enable timer and interrupt */
   qpit_ptr->TIMERS[channel].TCTRL = (QPIT_TCTRL_TIE|QPIT_TCTRL_TEN);

   return period;
}


/*ISR*********************************************************************
*
* Function Name    : _qpit_kernel_isr
* Returned Value   : void
* Comments         :
*
*
*END**********************************************************************/

static void _qpit_kernel_isr( pointer p )
{
    VQPIT_TIMER_REG_STRUCT_PTR qpit_timer_ptr = (VQPIT_TIMER_REG_STRUCT_PTR) p;

    qpit_timer_ptr->TFLG = QPIT_TFLG_TIF;

    _time_notify_kernel();
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qpit_timer_install
* Returned Value   : MQX_OK if successful or else MQX Error
* Comments         :
*    Initilizes the Timer and installs isr to provide kernel ticks
*
*END*----------------------------------------------------------------------*/

uint_32 _qpit_timer_install
    (
        /* [IN] the PIT device to initialize */
        uint_32   device,

        /* [IN] the channel to initialize */
        uint_32   channel,

        /* [IN] ticks per second */
        uint_32   tickfreq,

        /* [IN] input clock speed in Hz */
        uint_32   clk,

        /* [IN] interrupt priority */
        uint_32 priority,

        void (_CODE_PTR_ isr_ptr)(void *)

    )
{
    VQPIT_REG_STRUCT_PTR         qpit_ptr;
    PSP_INTERRUPT_TABLE_INDEX    vector;
    uint_32 period;

    #if PSP_HAS_DEVICE_PROTECTION
    if (!_bsp_qpit_enable_access(device)) {
        return MQX_INVALID_DEVICE;
    }
    #endif

    qpit_ptr = _bsp_get_qpit_base_address(device);
    vector   = _bsp_get_qpit_vector(device, channel);
    if (qpit_ptr == NULL ||  vector == 0) {
        return MQX_INVALID_DEVICE;
    }

    _bsp_int_disable(vector);

    /* Set up tick timer */
    period = _qpit_timer_init(qpit_ptr, channel, tickfreq, clk);
    if (period == 0) {
        return MQX_TIMER_ISR_INSTALL_FAIL;
    }

    /* Install the timer interrupt handler */
    if (_int_install_isr(vector, isr_ptr, (pointer)&qpit_ptr->TIMERS[channel]) == NULL) {
        return _task_get_error();
    }

    _bsp_int_init(vector, priority, 0, TRUE);

    return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qpit_timer_install_kernel
* Returned Value   : MQX_OK if successful or else MQX Error
* Comments         :
*    Initilizes the Timer and installs isr to provide kernel ticks
*
*END*----------------------------------------------------------------------*/

uint_32 _qpit_timer_install_kernel
    (
        /* [IN] the PIT device to initialize */
        uint_32   device,

        /* [IN] the channel to initialize */
        uint_32   channel,

        /* [IN] ticks per second */
        uint_32   tickfreq,

        /* [IN] input clock speed in Hz */
        uint_32   clk,

        /* [IN] interrupt priority */
        uint_32   priority
    )
{
    VQPIT_REG_STRUCT_PTR         qpit_ptr = _bsp_get_qpit_base_address(device);
    PSP_INTERRUPT_TABLE_INDEX    vector   = _bsp_get_qpit_vector(device, channel);
    uint_32 result;

    if (vector == 0)
    {
        return MQX_INVALID_DEVICE;
    }

    result = _qpit_timer_install(device,channel,tickfreq,clk,priority, _qpit_kernel_isr);
    if (result != MQX_OK)
    {
        return result;
    }

    /* Initialize the timer interrupt */
    _time_set_timer_vector(vector);
    _time_set_hwtick_function(_qpit_get_hwticks, (pointer)&qpit_ptr->TIMERS[channel]);
    _time_set_hwticks_per_tick(_qpit_get_period(qpit_ptr, channel));
    _time_set_ticks_per_sec(tickfreq);

    return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qpit_timer_stop
* Returned Value   : MQX_OK if successful or else MQX Error
* Comments         :
*    Stops the Timer.
*
*END*----------------------------------------------------------------------*/

uint_32 _qpit_timer_stop
    (
        /* [IN] the PIT device to stop */
        uint_32   device,

        /* [IN] the channel to stop */
        uint_32   channel
    )
{
    VQPIT_REG_STRUCT_PTR         qpit_ptr;
    PSP_INTERRUPT_TABLE_INDEX    vector;

    qpit_ptr = _bsp_get_qpit_base_address(device);
    vector   = _bsp_get_qpit_vector(device, channel);
    if (qpit_ptr == NULL ||  vector == 0) {
        return MQX_INVALID_DEVICE;
    }

    _bsp_int_disable(vector);

    /* Disable timer and interrupt */
    qpit_ptr->TIMERS[channel].TCTRL = 0;

    return MQX_OK;
}





/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _qpit_init_freq
* Returned Value  : hw ticks per tick
* Comments        :
*   this function will set up a timer to interrupt
*
*END*---------------------------------------------------------------------*/

uint_32 _qpit_init_freq
    (
        /* [IN] the timer to initialize */
    	uint_32    timer,
        
        /* [IN] the channel to initialize */
        uint_32   channel,

        /* [IN] ticks per second */
        uint_32   tickfreq,

        /* [IN] input clock speed in Hz */
        uint_32   clk,

        /* [IN] unmask the timer after initializing */
        boolean   unmask_timer
    )
{
		 	    
		VQPIT_REG_STRUCT_PTR  qpit_ptr;
		uint_32 rate;
	 
		qpit_ptr = _bsp_get_qpit_base_address(timer);	 
		if (qpit_ptr == NULL) 
			return 0;
			
		_bsp_qpit_clk_en(timer);
		
		/* return number of hw-ticks per MQX tick */
		rate = _qpit_timer_init (qpit_ptr, channel, tickfreq, clk); //Initializes QPIT
		
		if (unmask_timer) {
    	_qpit_unmask_int(timer,channel);
		}
		
		return rate;
	
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _qpit_clear_int
* Returned Value  :
* Comments        :
*   This function will clear interrupt flag of given timer
*
*END*---------------------------------------------------------------------*/

void _qpit_clear_int
    (
        /* [IN] the timer to use */
    	uint_32    timer,
        
        /* [IN] the channel to initialize */
        uint_32   channel
    )
{	
    volatile VQPIT_REG_STRUCT_PTR qpit_ptr;
    
    qpit_ptr = _bsp_get_qpit_base_address(timer);
    
    if (qpit_ptr == NULL) 
    	return;
    
    qpit_ptr->TIMERS[channel].TFLG |= QPIT_TFLG_TIF;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _qpit_unmask_int
* Returned Value  :
* Comments        :
*   This function will unmask interrupt flag of given timer
*
*END*---------------------------------------------------------------------*/

void _qpit_unmask_int
    (
        /* [IN] the timer to use */
    	uint_32    timer,
        
        /* [IN] the channel to initialize */
        uint_32   channel
    )
{
		volatile VQPIT_REG_STRUCT_PTR  qpit_ptr;
		
	    qpit_ptr = _bsp_get_qpit_base_address(timer);
	    
	    if (qpit_ptr == NULL)
	    	return;
	    
		qpit_ptr->TIMERS[channel].TCTRL |= QPIT_TCTRL_TIE;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _qpit_mask_int
* Returned Value  :
* Comments        :
*   This function will mask interrupt flag of given timer
*
*END*---------------------------------------------------------------------*/

void _qpit_mask_int
    (
        /* [IN] the timer to use */
    	uint_32    timer,
        
        /* [IN] the channel to initialize */
        uint_32   channel
    )
{
	    volatile VQPIT_REG_STRUCT_PTR   qpit_ptr;
	    
	    qpit_ptr = _bsp_get_qpit_base_address(timer);
	    
	    if (qpit_ptr == NULL) 
	    	return;
	    
		qpit_ptr->TIMERS[channel].TCTRL &=~ QPIT_TCTRL_TIE;
}


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_flush.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_flush.c$
* $Version : 3.8.4.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_flush_cache
* Returned Value   :  int_32 error code
* Comments  :  flush the write cache.
*
* Usage:  flush [filesys:]
*
*END*---------------------------------------------------------------------*/

int_32  Shell_flush_cache(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean                    print_usage, shorthelp = FALSE;
   int_32                     return_code = SHELL_EXIT_SUCCESS;
   MQX_FILE_PTR               fs_ptr;
   char_ptr                   name_ptr = NULL;

   
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc > 2) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else {
         if (argc==2) {
            name_ptr = argv[1];
         } else {
            name_ptr = Shell_get_current_filesystem_name(argv);
         }
 
         if (_io_validate_device(name_ptr)) {
            fs_ptr = fopen(name_ptr,0);
            if (fs_ptr == NULL )  {
               printf("Error, unable to access file system\n" );
               return_code = SHELL_EXIT_ERROR;
            } else  {
               ioctl(fs_ptr, IO_IOCTL_FLUSH_OUTPUT, NULL);
               fclose(fs_ptr);   
            } 
         } 
      } 
   } 
      
      
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <filesys:>\n", argv[0]);
      } else  {
         printf("Usage: %s <filesys:>\n", argv[0]);
         printf("   filesys: = name of MFS file system\n");
      }
   } 
   return return_code;
} /* Endbody */


/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/name_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: name_prv.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   name component.
*
*END************************************************************************/
#ifndef __name_prv_h__
#define __name_prv_h__ 1

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* Queue FIFO */
#define NAME_TASK_QUEUE_POLICY  (0)

#define NAME_VALID              (_mqx_uint)(0x6e616d65)   /* "name" */

/*--------------------------------------------------------------------------*/
/*                      DATA STRUCTURE DEFINITIONS                          */

/* NAME STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *   
 * \brief An individual pair of name/number.
 */
typedef struct name_struct
{
   /*! \brief The number associated with the name. */
   _mqx_max_type NUMBER;

   /*! \brief The string name stored in the table, includes null. */
   char      NAME[NAME_MAX_NAME_SIZE];

} NAME_STRUCT, _PTR_ NAME_STRUCT_PTR;
/*! \endcond */

/* NAME COMPONENT STRUCT */
/*!
 *\cond DOXYGEN_PRIVATE 
 * 
 * \brief This structure is used to store information required for name retrieval.
 * 
 * An initial structure is created and when pool growth is required, duplicate 
 * copies of this structure are created and linked via the NEXT_TABLE field.
 */
typedef struct name_component_struct
{

   /*! \brief The maximum number of names allowed in the entire pool. */
   _mqx_uint      MAX_NUMBER;

   /*! \brief The total number of names allocated in the entire pool so far. */
   _mqx_uint      TOTAL_NUMBER;

   /*! \brief The number of names allowed in this block. */   
   _mqx_uint      NUMBER_IN_BLOCK;

   /*! \brief The number of names allowed to be created in the next block. */
   _mqx_uint      GROW_NUMBER;

   /*! \brief The number of names used in the name component. */
   _mqx_uint      NUMBER;

   /*! \brief Lightweight semaphore for protecting the name component. */
   LWSEM_STRUCT   SEM;

   /*! \brief A validation stamp to verify handle correctness. */
   _mqx_uint      VALID;

   /*! \brief The address of the next block of names. */
   struct  name_component_struct _PTR_ NEXT_TABLE;

   /*! \brief A variable sized array of name/number pairs. */
   NAME_STRUCT    NAMES[1];
   
} NAME_COMPONENT_STRUCT, _PTR_ NAME_COMPONENT_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _name_add_internal(pointer, char_ptr, _mqx_max_type);
extern _mqx_uint _name_add_internal_by_index(pointer, char_ptr, _mqx_max_type, 
   _mqx_uint);
extern _mqx_uint _name_create_handle_internal(pointer _PTR_, _mqx_uint, _mqx_uint, 
   _mqx_uint, _mqx_uint);
extern _mqx_uint _name_destroy_handle_internal(pointer);
extern _mqx_uint _name_delete_internal(pointer, char_ptr);
extern _mqx_uint _name_delete_internal_by_index(pointer, _mqx_uint);
extern _mqx_uint _name_find_internal(pointer, char_ptr, _mqx_max_type_ptr);
extern _mqx_uint _name_find_name_internal(pointer, _mqx_max_type, char_ptr);
extern _mqx_uint _name_find_internal_by_index(pointer, _mqx_uint, _mqx_max_type_ptr);
extern _mqx_uint _name_init_internal(pointer _PTR_, _mqx_uint, _mqx_uint, _mqx_uint,
   _mqx_uint);
extern _mqx_uint _name_test_internal(NAME_COMPONENT_STRUCT_PTR, pointer _PTR_, 
   pointer _PTR_);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/hmi_client.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2011 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hmi_client.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines, structure
*   definitions of HMI client
*
*END************************************************************************/
#ifndef __hmi_client_h__
#define __hmi_client_h__ 1

#include "psptypes.h"
#include "hmi_provider.h"
#include "mqx.h"

#define HMI_VALUE_ON     0
#define HMI_VALUE_OFF    1

#define HMI_VALUE_RELEASE      0
#define HMI_VALUE_PUSH         1
#define HMI_VALUE_MOVEMENT     2

typedef struct hmi_client_struct
{
    void ( _CODE_PTR_ ON_CHANGE)(pointer, uint_32, uint_32);/* function to call on change */
    HMI_PROVIDER_STRUCT_PTR     _PTR_ PROVIDER_TABLE;       /* array of pointers */
    uint_32                     MAX_PROVIDER_COUNT;         /* max provider number */
    pointer                     CONTEXT_PTR;                /* pointer to context */
} HMI_CLIENT_STRUCT, _PTR_ HMI_CLIENT_STRUCT_PTR;

#ifdef __cplusplus
extern "C" {
#endif
boolean hmi_add_provider(HMI_CLIENT_STRUCT_PTR, HMI_PROVIDER_STRUCT_PTR);
boolean hmi_remove_provider(HMI_CLIENT_STRUCT_PTR, HMI_PROVIDER_STRUCT_PTR);
HMI_CLIENT_STRUCT_PTR hmi_client_init(void);
#ifdef __cplusplus
}
#endif

#endif



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/telnet.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: telnet.c$
* $Version : 3.8.7.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the Telnet client implementation.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include "telnet.h"


/*TASK*-----------------------------------------------------------------
*
* Function Name  : TELNET_connect
* Returned Value : error code
* Comments       : A TCP/IP based Telnet Client
*
*END------------------------------------------------------------------*/

uint_32 TELNET_connect
   (
      _ip_address    ipaddress
   )
{ /* Body */
   MQX_FILE_PTR   sockfd, telnetfd;
   sockaddr_in    addr;
   uint_32        sock;
   uint_32        error;
   boolean        work;
   int_32         c;

   /*
   ** Install device driver for socket and telnet
   */
   _io_socket_install("socket:");
   _io_telnet_install("telnet:");

   sock = socket(PF_INET, SOCK_STREAM, 0);
   if (sock == RTCS_SOCKET_ERROR) {
      return RTCSERR_OUT_OF_SOCKETS;
   } /* Endif */

   addr.sin_family      = AF_INET;
   addr.sin_port        = 0;
   addr.sin_addr.s_addr = INADDR_ANY;
   error = bind(sock,(const sockaddr *)&addr, sizeof(addr));
   if (error != RTCS_OK) {
      return error;
   } /* Endif */

   addr.sin_port        = IPPORT_TELNET;
   addr.sin_addr.s_addr = ipaddress;

   error = connect(sock, (const sockaddr *)(&addr), sizeof(addr));
   if (error != RTCS_OK) {
      shutdown(sock, FLAG_ABORT_CONNECTION);
      return error;
   } /* Endif */

   sockfd = fopen("socket:", (char_ptr)sock);
   if (sockfd == NULL) {
      shutdown(sock, FLAG_ABORT_CONNECTION);
      return RTCSERR_FOPEN_FAILED;
   } /* Endif */

   telnetfd = fopen("telnet:", (char_ptr)sockfd);
   if (telnetfd == NULL) {
      fclose(sockfd);
      shutdown(sock, FLAG_ABORT_CONNECTION);
      return RTCSERR_FOPEN_FAILED;
   } /* Endif */

   /* Set the console stream to the client  */
   ioctl(telnetfd, IO_IOCTL_SET_STREAM, (uint_32_ptr)((void _PTR_)stdin));
   while (TRUE) {

      work = FALSE;
      if (fstatus(stdin)) {
         work = TRUE;
         c = (int_32)fgetc(stdin);
         if (fputc(c & 0x7F, telnetfd) == IO_EOF)  {
            break;   
         }
      } /* Endif */

      if (fstatus(telnetfd)) {
         work = TRUE;
         c = (int_32)fgetc(telnetfd);
         if (c == IO_EOF) {
            break;
         }/* Endif */
         fputc(c & 0x7F, stdout);
      } /* Endif */

      /* Let another task run if there is no I/O */
      if (!work) {
         RTCS_time_delay(1);
      } /* Endif */

   } /* Endwhile */

   fclose(telnetfd);
   fclose(sockfd);
   shutdown(sock, FLAG_CLOSE_TX);

   return RTCS_OK;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/khci/khci.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: khci.c$
* $Version : 3.8.86.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains KHCI-specific implementations of USB interfaces
*
*END************************************************************************/
#include <mqx.h>
#include <lwevent.h>
#include <lwmsgq.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_dev_list.h"


#include "mqx_host.h"
#include "khci.h"
#include "khci_prv.h"

#ifdef KHCI_DEBUG
struct debug_messaging {
  char inout;
  TR_MSG_TYPE type;
  uint_8 ep;
  uint_16 size;
};
volatile static uint_16 dm_index = 0;
volatile static struct debug_messaging dm[1024] = { 0 }; /* note, the array is for 1024 records only */
#   define KHCI_DEBUG_LOG(a, b, c, d) \
  { \
    dm[dm_index].inout = a; \
      dm[dm_index].type = b; \
      dm[dm_index].ep = c; \
      dm[dm_index].size = d; \
      dm_index++; \
  }
#else
#   define KHCI_DEBUG_LOG(a, b, c, d) {}
#endif

// KHCI task parameters
#define USB_KHCI_TASK_NUM_MESSAGES         16
#define USB_KHCI_TASK_TEMPLATE_INDEX       0
#define USB_KHCI_TASK_ADDRESS              _usb_khci_task
#define USB_KHCI_TASK_STACKSIZE            1600
#define USB_KHCI_TASK_NAME                 "KHCI Task"
#define USB_KHCI_TASK_ATTRIBUTES           0
#define USB_KHCI_TASK_CREATION_PARAMETER   0
#define USB_KHCI_TASK_DEFAULT_TIME_SLICE   0

// atom transaction error results
#define KHCI_ATOM_TR_PID_ERROR  (-1)
#define KHCI_ATOM_TR_EOF_ERROR  (-2)
#define KHCI_ATOM_TR_CRC_ERROR  (-4)
#define KHCI_ATOM_TR_TO         (-16)
#define KHCI_ATOM_TR_DMA_ERROR  (-32)
#define KHCI_ATOM_TR_BTS_ERROR  (-128)
#define KHCI_ATOM_TR_NAK        (-256)
#define KHCI_ATOM_TR_DATA_ERROR (-512)
#define KHCI_ATOM_TR_STALL      (-1024)
#define KHCI_ATOM_TR_RESET      (-2048)

#if defined( __ICCCF__ ) || defined( __ICCARM__ )
    #pragma segment="USB_BDT_Z"
    #pragma data_alignment=512
    __no_init static uint_8 bdt[512] @ "USB_BDT_Z";
#elif defined (__CC_ARM) || defined(__GNUC__)
    __attribute__((section(".usb_bdt"),unused)) static uint_8 bdt[512] = { 1 };
#else
  #pragma define_section usb_bdt ".usb_bdt" RW
  __declspec(usb_bdt) static uint_8 bdt[512] = { 1 };    // DO NOT REMOVE INITIALIZATION !!! bug in CW (cw 7.1) - generate wrong binary code, data
#endif  

/* Prototypes of functions */
static USB_STATUS _usb_khci_preinit(_usb_host_handle *handle);
static USB_STATUS _usb_khci_init(_usb_host_handle handle);
static USB_STATUS _usb_khci_shutdown(_usb_host_handle handle);
static USB_STATUS _usb_khci_send(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, TR_STRUCT_PTR tr_ptr);
static USB_STATUS _usb_khci_send_setup(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, TR_STRUCT_PTR tr_ptr);
static USB_STATUS _usb_khci_recv(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, TR_STRUCT_PTR tr_ptr);
static USB_STATUS _usb_khci_cancel(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, TR_STRUCT_PTR tr_ptr);
static USB_STATUS _usb_khci_bus_control(_usb_host_handle handle, uint_8 bus_control);
static uint_32 _usb_khci_get_frame_number(_usb_host_handle handle);

static USB_STATUS _usb_khci_host_close_pipe(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr);

static void _usb_khci_process_tr_complete(KHCI_PIPE_STRUCT_PTR pipe_ptr, KHCI_TR_STRUCT_PTR tr_ptr, uint_32 required, uint_32 remain, int_32 err);
static int_32 _usb_khci_atom_tr(USB_KHCI_HOST_STATE_STRUCT_PTR host_ptr, uint_32 type, KHCI_PIPE_STRUCT_PTR pipe_desc_ptr, uint_8 *buf, uint_32 len);

const struct usb_host_callback_functions_struct _usb_khci_host_callback_table = {
   /* The Host/Device preinit function */
   _usb_khci_preinit,

  /* The Host/Device init function */
   _usb_khci_init,

   /* The function to shutdown the host/device */
   _usb_khci_shutdown,

   /* The function to send data */
   _usb_khci_send,

   /* The function to send setup data */
   _usb_khci_send_setup,

   /* The function to receive data */
   _usb_khci_recv,
   
   /* The function to cancel the transfer */
   _usb_khci_cancel,
   
   /* The function for USB bus control */
   _usb_khci_bus_control,

   NULL,

   /* The function to close pipe */
   _usb_khci_host_close_pipe,
    
   /* Get frame number function */
   _usb_khci_get_frame_number,

   /* Get microframe number function - not applicable on FS */
   NULL,
   
   /* Open pipe function */
   NULL,
   
   NULL,
   
   NULL
};

// KHCI event bits
#define KHCI_EVENT_ATTACH       0x01
#define KHCI_EVENT_RESET        0x02
#define KHCI_EVENT_TOK_DONE     0x04
#define KHCI_EVENT_SOF_TOK      0x08
#define KHCI_EVENT_DETACH       0x10
#define KHCI_EVENT_MASK         0x1f

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_isr
*  Returned Value : None
*  Comments       :
*        Service all the interrupts in the kirin usb hardware
*END*-----------------------------------------------------------------*/
static void _usb_khci_isr(_usb_host_handle handle) {
    USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR)handle;
    USB_MemMapPtr usb_ptr = (USB_MemMapPtr) usb_host_ptr->G.DEV_PTR;
    uchar status;

    while (1)
    {
        status = (uint_8)(usb_ptr->ISTAT & usb_ptr->INTEN);

        if (!status)
            break;
        
        usb_ptr->ISTAT = status;
    
        if (status & USB_ISTAT_ATTACH_MASK)
        {
            /* USB device is (being) attached */
            usb_ptr->INTEN &= ~USB_INTEN_ATTACHEN_MASK;
            _lwevent_set(&usb_host_ptr->khci_event, KHCI_EVENT_ATTACH);
        }
        
        if (status & USB_ISTAT_TOKDNE_MASK)
        {
            // atom transaction done - token done
            
            _lwevent_set(&usb_host_ptr->khci_event, KHCI_EVENT_TOK_DONE);
        }
        
        if (status & USB_ISTAT_USBRST_MASK)
        {
            // usb reset
            _lwevent_set(&usb_host_ptr->khci_event, KHCI_EVENT_RESET);
        }
    }
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_init_int_tr
*  Returned Value : None
*  Comments       :
*        Initialize interrupt transaction que
*END*-----------------------------------------------------------------*/
static void _usb_khci_init_int_tr(USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr) {
    _mqx_int i;
    TR_INT_QUE_ITM_STRUCT_PTR tr = usb_host_ptr->tr_int_que;
    
    for (i = 0; i < USBCFG_KHCI_MAX_INT_TR; i++, tr++) {
        tr->msg.type = TR_MSG_UNKNOWN;
    }
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_add_int_tr
*  Returned Value : -1 que is full
*  Comments       :
*        Add new interrupt transaction to que
*END*-----------------------------------------------------------------*/
static int _usb_khci_add_int_tr(USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr, TR_MSG_STRUCT *msg, _mqx_uint period) {
    _mqx_int i = 0;
    TR_INT_QUE_ITM_STRUCT_PTR tr = usb_host_ptr->tr_int_que;
    TIME_STRUCT tm;
    
    // find free position
    for (i = 0; i < USBCFG_KHCI_MAX_INT_TR; i++, tr++)
    {
        if (tr->msg.type == TR_MSG_UNKNOWN)
        {
            tr->period = period;

            _time_get(&tm);
            tr->time.SECONDS = tm.SECONDS;
            tr->time.MILLISECONDS = tm.MILLISECONDS + period;

            tr->time.SECONDS += tr->time.MILLISECONDS / 1000;
            tr->time.MILLISECONDS %= 1000;

            USB_mem_copy(msg, &tr->msg, sizeof(TR_MSG_STRUCT));
            
            break;
        }
    }
    
    return (i < USBCFG_KHCI_MAX_INT_TR) ? i : -1;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_rm_int_tr
*  Returned Value : 0 successful
*  Comments       :
*        Remove interrupt transaction from que
*END*-----------------------------------------------------------------*/
static int _usb_khci_rm_int_tr(USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr, TR_MSG_STRUCT *msg) {
    _mqx_int i = 0;
    TR_INT_QUE_ITM_STRUCT_PTR tr = usb_host_ptr->tr_int_que;
    
    // find record
    for (i = 0; i < USBCFG_KHCI_MAX_INT_TR; i++, tr++)
    {
        if (tr->msg.pipe_desc == msg->pipe_desc && tr->msg.pipe_tr == msg->pipe_tr)
        {
            //USB_mem_zero(tr, sizeof(TR_INT_QUE_ITM_STRUCT));
            tr->msg.type = TR_MSG_UNKNOWN;    
            return 0;
        }
    }
    
    return -1;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_get_hot_int_tr
*  Returned Value : 0 successful
*  Comments       :
*        Make a message copy for transaction which need evaluation
*END*-----------------------------------------------------------------*/
static int _usb_khci_get_hot_int_tr(USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr, TR_MSG_STRUCT *msg) {
    _mqx_int i, res = -1;
    register TIME_STRUCT hot_time;
    TR_INT_QUE_ITM_STRUCT_PTR tr = usb_host_ptr->tr_int_que;
    TR_INT_QUE_ITM_STRUCT_PTR hot_tr = NULL;
    TIME_STRUCT tm;
    
    hot_time.SECONDS = hot_time.MILLISECONDS = 0xFFFFFFFF;

    /* find hottest transaction */
    for (i = 0; i < USBCFG_KHCI_MAX_INT_TR; i++, tr++) {
        if (tr->msg.type != TR_MSG_UNKNOWN) {
            if (hot_time.SECONDS > tr->time.SECONDS) {
                hot_time.SECONDS = tr->time.SECONDS;
                hot_time.MILLISECONDS = tr->time.MILLISECONDS;
                hot_tr = tr;
            }
            else if ((hot_time.SECONDS == tr->time.SECONDS) && (hot_time.MILLISECONDS > tr->time.MILLISECONDS)) {
                hot_time.MILLISECONDS = tr->time.MILLISECONDS;
                hot_tr = tr;
            }
        }
    }
    
    if (hot_tr) {
        /* test if hottest transaction was the last one with timeout - if yes, don't allow to block USB transfers with this interrupt */
        if (usb_host_ptr->last_to_pipe == hot_tr->msg.pipe_desc) {
            usb_host_ptr->last_to_pipe = NULL; //it is allowed to perform this interupt next time, but not now
            return res;
        }
        
        /* test if hottest transaction is enough hot to fire */
        _time_get(&tm);
            
        if ((hot_time.SECONDS < tm.SECONDS) || ((hot_time.SECONDS == tm.SECONDS) && (hot_time.MILLISECONDS < tm.MILLISECONDS))) {
            /* update time to next fire = now + period */
            hot_tr->time.SECONDS = tm.SECONDS;
            hot_tr->time.MILLISECONDS = tm.MILLISECONDS + hot_tr->period;

            hot_tr->time.SECONDS += hot_tr->time.MILLISECONDS / 1000;
            hot_tr->time.MILLISECONDS %= 1000;

            USB_mem_copy(&hot_tr->msg, msg, sizeof(TR_MSG_STRUCT));
            res = 0;
        }
    }
    
    return res;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_attach
*  Returned Value : none
*  Comments       :
*        KHCI attach event
*END*-----------------------------------------------------------------*/
static void _usb_khci_attach(USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr) {
    USB_MemMapPtr usb_ptr = (USB_MemMapPtr) usb_host_ptr->G.DEV_PTR;

    usb_ptr->ADDR = 0;
    _time_delay(100);

    // speed check, set
    usb_host_ptr->G.SPEED = (uint_8)((usb_ptr->CTL & USB_CTL_JSTATE_MASK) ? USB_SPEED_FULL : USB_SPEED_LOW);
    if (usb_host_ptr->G.SPEED == USB_SPEED_FULL)
	{
        usb_ptr->ADDR &= ~USB_ADDR_LSEN_MASK;
	}
    usb_ptr->ISTAT = 0xff;   // clean each int flags
    usb_ptr->INTEN = \
        USB_INTEN_TOKDNEEN_MASK |
        USB_INTEN_USBRSTEN_MASK;

    // bus reset
    usb_ptr->CTL |= USB_CTL_RESET_MASK;
    _time_delay(30); //wait for 30 milliseconds (2.5 is minimum for reset, 10 recommended)
    usb_ptr->CTL &= ~USB_CTL_RESET_MASK;

    // Delay after reset was provided to be sure about speed- HS / FS. Since the KHCI does not run HS, the delay is redundant.
    // Some kinetis devices cannot recover after the delay, so it is better not to have delayed speed detection and SOF packet generation 
    // This is potentional risk as any high priority task will get CPU now, the host will not begin the enumeration process.
    //_time_delay(10);

    // enable SOF sending
    usb_ptr->CTL |= USB_CTL_USBENSOFEN_MASK;

    _time_delay(100);

    usb_ptr->INTEN = \
        USB_INTEN_TOKDNEEN_MASK |
        USB_INTEN_USBRSTEN_MASK;

    usb_dev_list_attach_device((pointer)usb_host_ptr, (uint_8)(usb_host_ptr->G.SPEED), 0, 0);

      _lwevent_clear(&usb_host_ptr->khci_event, KHCI_EVENT_ATTACH);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_reset
*  Returned Value : none
*  Comments       :
*        KHCI reset event
*END*-----------------------------------------------------------------*/
static void _usb_khci_reset(USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr) {
    USB_MemMapPtr usb_ptr = (USB_MemMapPtr) usb_host_ptr->G.DEV_PTR;

    // clear attach flag
    usb_ptr->ISTAT |= USB_ISTAT_ATTACH_MASK;

    /* Test the presence of USB device */
    if (usb_ptr->ISTAT & USB_ISTAT_ATTACH_MASK) {
        /* device attached, so really normal reset was performed */
        usb_ptr->ADDR = 0;
        usb_ptr->ENDPOINT[0].ENDPT |= USB_ENDPT_HOSTWOHUB_MASK;
    }
    else {
        /* device was detached, the reset event is false- nevermind, notify about detach */
        _lwevent_set(&usb_host_ptr->khci_event, KHCI_EVENT_DETACH);
    }

    _lwevent_clear(&usb_host_ptr->khci_event, KHCI_EVENT_RESET | KHCI_EVENT_TOK_DONE);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_detach
*  Returned Value : none
*  Comments       :
*        KHCI detach event
*END*-----------------------------------------------------------------*/
static void _usb_khci_detach(USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr) {
    USB_MemMapPtr usb_ptr = (USB_MemMapPtr) usb_host_ptr->G.DEV_PTR;

    usb_dev_list_detach_device((pointer)usb_host_ptr, 0, 0);

    /* Cleaning interrupt transaction queue from device is done
    ** by calling _usb_khci_host_close_pipe from upper layer
    */
    
    /* Now, disable bus control for any events, disable SOFs,
    ** just prepare for attach in host mode.
    */
    usb_ptr->CTL = USB_CTL_HOSTMODEEN_MASK;
    /* This will clear all pending interrupts... In fact, there shouldnt be any
    ** after detaching a device.
    */
    usb_ptr->ISTAT = 0xFF;
    /* Now, enable only USB interrupt attach for host mode */
    usb_ptr->INTEN = USB_INTEN_ATTACHEN_MASK;

    _lwevent_clear(&usb_host_ptr->khci_event, KHCI_EVENT_DETACH);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_task
*  Returned Value : none
*  Comments       :
*        KHCI task
*END*-----------------------------------------------------------------*/
static void _usb_khci_task(uint_32 dev_inst_ptr) {
    USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR) dev_inst_ptr;
    _mqx_uint seq_ints = 10;    
    TR_MSG_STRUCT msg;
    uint_32 remain = 0;
    uint_32 required = 0;
    _mqx_int res;
    uint_8 *buf;
    
    /* The _lwmsgq_init accepts the size of TR_MSG_STRUCT as a multiplier of sizeof(_mqx_max_type) */
#define MSG_SIZE_IN_MAX_TYPE (1 + (sizeof(TR_MSG_STRUCT) - 1) / sizeof(_mqx_max_type))
    if (_lwmsgq_init(usb_host_ptr->tr_que, USBCFG_KHCI_TR_QUE_MSG_CNT, MSG_SIZE_IN_MAX_TYPE) != MQX_OK) {
        // lwmsgq_init failed
        _mqx_exit(0);
    }
    
    _usb_khci_init_int_tr(usb_host_ptr);
    
    while (1) {
        if (usb_host_ptr->G.DEVICE_LIST_PTR) {

            msg.type = TR_MSG_UNKNOWN;
        
            // look for interrupt transaction
            if ((_usb_khci_get_hot_int_tr(usb_host_ptr, &msg) != 0) || (!seq_ints--)) {
                seq_ints = 10;
                if (_lwmsgq_receive(usb_host_ptr->tr_que, (uint_32 *) &msg, LWMSGQ_RECEIVE_BLOCK_ON_EMPTY, USBCFG_KHCI_WAIT_TICK, 0) == MQX_OK)
                    if (msg.pipe_desc->G.PIPETYPE == USB_INTERRUPT_PIPE)
                        _usb_khci_add_int_tr(usb_host_ptr, &msg, msg.pipe_desc->G.INTERVAL);
            }
            
            if (msg.type != TR_MSG_UNKNOWN) {
                // evaluate message
                             
                switch (msg.type) {
                    case TR_MSG_SETUP:
//                        msg.pipe_desc->G.NEXTDATA01 = 0; done in upper layer
                        _usb_khci_atom_tr(usb_host_ptr, TR_CTRL, msg.pipe_desc, (uint_8 *) &msg.pipe_tr->G.setup_packet, 8);
                    
                        // send next token
                        if (msg.pipe_tr->G.RX_LENGTH) {
                            buf = msg.pipe_tr->G.RX_BUFFER;
                            required = remain = msg.pipe_tr->G.RX_LENGTH;
                            KHCI_DEBUG_LOG('p', msg.type, msg.pipe_desc->G.ENDPOINT_NUMBER, required)
                        
                            while (remain > 0) {
                                res = _usb_khci_atom_tr(usb_host_ptr, TR_IN, msg.pipe_desc, buf, remain);
                                
                                if (res < 0)
                                    break;
                            
                                buf += res;
                                remain -=res; 
                            }
                        
                            msg.pipe_desc->G.NEXTDATA01 = 1;
                            res = _usb_khci_atom_tr(usb_host_ptr, TR_OUT, msg.pipe_desc, 0, 0);
                        }
                        else if (msg.pipe_tr->G.TX_LENGTH) {
                            buf = msg.pipe_tr->G.TX_BUFFER;
                            required = remain = msg.pipe_tr->G.TX_LENGTH;
                            KHCI_DEBUG_LOG('p', msg.type, msg.pipe_desc->G.ENDPOINT_NUMBER, required)
                        
                            while (remain > 0) {
                                res = _usb_khci_atom_tr(usb_host_ptr, TR_OUT, msg.pipe_desc, buf, remain);
                        
                                if (res < 0)
                                    break;
                            
                                buf += res;
                                remain -=res;
                            }

                            msg.pipe_desc->G.NEXTDATA01 = 1;
                            res = _usb_khci_atom_tr(usb_host_ptr, TR_IN, msg.pipe_desc, 0, 0);
                        }
                        else {
                            msg.pipe_desc->G.NEXTDATA01 = 1;
                            res = _usb_khci_atom_tr(usb_host_ptr, TR_IN, msg.pipe_desc, 0, 0);
                            remain = 0;
                        }
                        break;

                    case TR_MSG_RECV:
                        buf = msg.pipe_tr->G.RX_BUFFER;
                        required = remain = msg.pipe_tr->G.RX_LENGTH;
                        KHCI_DEBUG_LOG('p', msg.type, msg.pipe_desc->G.ENDPOINT_NUMBER, required);

                        do {
                            res = _usb_khci_atom_tr(usb_host_ptr, TR_IN, msg.pipe_desc, buf, remain);
                                
                            if (res < 0) 
                                break;

                            buf += res;
                            remain -=res;
                            
                            if ((remain == 0) || (res < msg.pipe_desc->G.MAX_PACKET_SIZE)) 
                            {
                                res = remain;
                                break;
                            }
                        
                        } while (1);
                        break;

                    case TR_MSG_SEND:
                        buf = msg.pipe_tr->G.TX_BUFFER;
                        required = remain = msg.pipe_tr->G.TX_LENGTH;
                        KHCI_DEBUG_LOG('p', msg.type, msg.pipe_desc->G.ENDPOINT_NUMBER, required)
                    
                        do {
                            res = _usb_khci_atom_tr(usb_host_ptr, TR_OUT, msg.pipe_desc, buf, remain);
                        
                            if (res < 0)
                                break;
                        
                            buf += res;
                            remain -=res;
                            
                            if ((remain == 0) || (res < msg.pipe_desc->G.MAX_PACKET_SIZE)) 
                            {
                                res = remain;
                                break;
                            }
                            
                        } while (1);
                        break;

                    default:
                       break;
                }
        
                if (msg.pipe_desc->G.PIPETYPE == USB_INTERRUPT_PIPE) {
                    /* for interrupt pipes, callback only if some data was received or serious error occured */
                    if ((required != remain) || (res != KHCI_ATOM_TR_NAK)) {
                        _usb_khci_process_tr_complete(msg.pipe_desc, msg.pipe_tr, required, remain, res);
                        _usb_khci_rm_int_tr(usb_host_ptr, &msg);
                    }
                }
                else {
                    _usb_khci_process_tr_complete(msg.pipe_desc, msg.pipe_tr, required, remain, res);
                }
            }
        }
        else {
            // wait for event if device is not attached
            _lwevent_wait_ticks(&usb_host_ptr->khci_event, KHCI_EVENT_MASK, FALSE, 0);
        }
        
        if (usb_host_ptr->khci_event.VALUE & KHCI_EVENT_MASK) {
            if (usb_host_ptr->khci_event.VALUE & KHCI_EVENT_ATTACH)
                _usb_khci_attach(usb_host_ptr);

            if (usb_host_ptr->khci_event.VALUE & KHCI_EVENT_RESET)
                _usb_khci_reset(usb_host_ptr);

            if (usb_host_ptr->khci_event.VALUE & KHCI_EVENT_DETACH)
                _usb_khci_detach(usb_host_ptr);
        }
    }
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_task_create
*  Returned Value : error or USB_OK
*  Comments       :
*        Create KHCI task
*END*-----------------------------------------------------------------*/
static USB_STATUS _usb_khci_task_create(_usb_host_handle handle) {
    //USB_STATUS status;
    _task_id task_id;
    TASK_TEMPLATE_STRUCT task_template;
    
    // check wait time for events - must be > 0
    if (USBCFG_KHCI_WAIT_TICK < 1)
        return USBERR_UNKNOWN_ERROR;

    /* create task for processing interrupt deferred work */
    task_template.TASK_TEMPLATE_INDEX = USB_KHCI_TASK_TEMPLATE_INDEX;
    task_template.TASK_ADDRESS = USB_KHCI_TASK_ADDRESS;
    task_template.TASK_STACKSIZE = USB_KHCI_TASK_STACKSIZE;
    task_template.TASK_PRIORITY = USBCFG_KHCI_TASK_PRIORITY;
    task_template.TASK_NAME = USB_KHCI_TASK_NAME;
    task_template.TASK_ATTRIBUTES = USB_KHCI_TASK_ATTRIBUTES;
    task_template.CREATION_PARAMETER = (uint_32)handle;   //USB_KHCI_TASK_CREATION_PARAMETER;
    task_template.DEFAULT_TIME_SLICE = USB_KHCI_TASK_DEFAULT_TIME_SLICE;

    task_id = _task_create_blocked(0, 0, (uint_32)&task_template);
    
    if (task_id == 0) {
        return USBERR_UNKNOWN_ERROR;
    }
    
    _task_ready(_task_get_td(task_id));

    return USB_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_preinit
*  Returned Value : error or USB_OK
*  Comments       :
*        Allocate the structures for KHCI
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_preinit(_usb_host_handle *handle) {
    USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR) USB_mem_alloc_zero(sizeof(USB_KHCI_HOST_STATE_STRUCT));
    KHCI_PIPE_STRUCT_PTR p, pp;
    int i;

    if (NULL != usb_host_ptr) {
        /* Allocate the USB Host Pipe Descriptors */
        usb_host_ptr->G.PIPE_DESCRIPTOR_BASE_PTR = (PIPE_STRUCT_PTR)USB_mem_alloc(sizeof(KHCI_PIPE_STRUCT) * USBCFG_MAX_PIPES);
        if (usb_host_ptr->G.PIPE_DESCRIPTOR_BASE_PTR == NULL) {
            USB_mem_free(usb_host_ptr);

            return USBERR_ALLOC;
        }
        USB_mem_zero(usb_host_ptr->G.PIPE_DESCRIPTOR_BASE_PTR, sizeof(KHCI_PIPE_STRUCT) * USBCFG_MAX_PIPES);

        p = (KHCI_PIPE_STRUCT_PTR) usb_host_ptr->G.PIPE_DESCRIPTOR_BASE_PTR;
        pp = NULL;
        for (i = 0; i < USBCFG_MAX_PIPES; i++) {
           if (pp != NULL) {
              pp->G.NEXT = (PIPE_STRUCT_PTR) p;
           }
           pp = p;
           p++;
        }

        usb_host_ptr->G.PIPE_SIZE = sizeof(KHCI_PIPE_STRUCT);
        usb_host_ptr->G.TR_SIZE = sizeof(KHCI_TR_STRUCT);

    } /* Endif */
    
    *handle = (_usb_host_handle) usb_host_ptr;
    return USB_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_init
*  Returned Value : error or USB_OK
*  Comments       :
*        Initialize the kirin HCI controller
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_init(_usb_host_handle handle) {
    USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR)handle;
    USB_KHCI_HOST_INIT_STRUCT_PTR param = (USB_KHCI_HOST_INIT_STRUCT_PTR) usb_host_ptr->G.INIT_PARAM;
    USB_MemMapPtr           usb_ptr;
    USB_STATUS              status = USB_OK;

    /* create lwevent group */
    if (_lwevent_create(&usb_host_ptr->khci_event, 0) != MQX_OK) {
        return USBERR_GET_MEMORY_FAILED;
    }

   if (param == NULL)
       return USBERR_INIT_DATA;

    usb_ptr = (USB_MemMapPtr) param->BASE_PTR;
    usb_host_ptr->G.DEV_PTR = (USB_HOST_STATE_STRUCT_PTR) usb_ptr;
   
    _usb_khci_task_create(usb_host_ptr);
    
    // install isr
    if (!(USB_install_isr(param->VECTOR, _usb_khci_isr, (pointer)usb_host_ptr)))
        return USBERR_INSTALL_ISR;
    
    usb_ptr->ISTAT = 0xFF;
    /* Enable week pull-downs, usefull for detecting detach (effectivelly bus discharge) */
    usb_ptr->USBCTRL |= USB_USBCTRL_PDE_MASK;
    /* Remove suspend state */
    usb_ptr->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;


    usb_ptr->CTL |= USB_CTL_ODDRST_MASK;
    
    usb_ptr->BDTPAGE1 = (uint_8)((uint_32)BDT_BASE >> 8);
    usb_ptr->BDTPAGE2 = (uint_8)((uint_32)BDT_BASE >> 16);
    usb_ptr->BDTPAGE3 = (uint_8)((uint_32)BDT_BASE >> 24);
    
    /* Set SOF threshold */
    usb_ptr->SOFTHLD = 1;
    
    usb_ptr->CTL = USB_CTL_HOSTMODEEN_MASK;

    /* Following is for OTG control instead of internal bus control */
//    usb_ptr->OTGCTL = USB_OTGCTL_DMLOW_MASK | USB_OTGCTL_DPLOW_MASK | USB_OTGCTL_OTGEN_MASK;

    /* Wait for attach interrupt */
    usb_ptr->INTEN = USB_INTEN_ATTACHEN_MASK;
        
    return status;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_shutdown - NOT IMPLEMENT YET
*  Returned Value : error or USB_OK
*  Comments       :
*        The function to shutdown the host
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_shutdown(_usb_host_handle handle) {
    return USB_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_send
*  Returned Value : error or USB_OK
*  Comments       :
*        The function to send data
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_send(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, TR_STRUCT_PTR tr_ptr) {
    USB_STATUS status = USB_OK;
    USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR) handle;
    TR_MSG_STRUCT msg;

    msg.type = TR_MSG_SEND;
    msg.pipe_desc = (KHCI_PIPE_STRUCT_PTR) pipe_ptr;
    msg.pipe_tr = (KHCI_TR_STRUCT_PTR) tr_ptr;
    
    KHCI_DEBUG_LOG('i', msg.type, msg.pipe_desc->G.ENDPOINT_NUMBER, msg.pipe_tr->G.TX_LENGTH)
    if (MQX_OK != _lwmsgq_send(usb_host_ptr->tr_que, (uint_32 *) &msg, 0)) {
        status = USBERR_TR_FAILED;
    }
    
    return status;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_send_setup
*  Returned Value : error or USB_OK
*  Comments       :
*        The function to send setup data
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_send_setup(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, TR_STRUCT_PTR tr_ptr) {
    USB_STATUS status = USB_OK;
    USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR) handle;
    TR_MSG_STRUCT msg;

    msg.type = TR_MSG_SETUP;
    msg.pipe_desc = (KHCI_PIPE_STRUCT_PTR) pipe_ptr;
    msg.pipe_tr = (KHCI_TR_STRUCT_PTR) tr_ptr;

    if (msg.pipe_tr->G.RX_LENGTH)
      KHCI_DEBUG_LOG('i', msg.type, msg.pipe_desc->G.ENDPOINT_NUMBER, msg.pipe_tr->G.RX_LENGTH)
    else
      KHCI_DEBUG_LOG('i', msg.type, msg.pipe_desc->G.ENDPOINT_NUMBER, msg.pipe_tr->G.TX_LENGTH)

    if (MQX_OK != _lwmsgq_send(usb_host_ptr->tr_que, (uint_32 *) &msg, 0)) {
        status = USBERR_TR_FAILED;
    }

    return status;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_recv
*  Returned Value : error or USB_OK
*  Comments       :
*        The function to receive data
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_recv(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, TR_STRUCT_PTR tr_ptr) {
    USB_STATUS status = USB_OK;
    USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR) handle;
    TR_MSG_STRUCT msg;

    msg.type = TR_MSG_RECV;
    msg.pipe_desc = (KHCI_PIPE_STRUCT_PTR) pipe_ptr;
    msg.pipe_tr = (KHCI_TR_STRUCT_PTR) tr_ptr;
    
    KHCI_DEBUG_LOG('i', msg.type, msg.pipe_desc->G.ENDPOINT_NUMBER, msg.pipe_tr->G.RX_LENGTH)
    if (MQX_OK != _lwmsgq_send(usb_host_ptr->tr_que, (uint_32 *) &msg, 0)) {
        status = USBERR_TR_FAILED;
    }
    
    return status;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_cancel
*  Returned Value : error or USB_OK
*  Comments       :
*        The function to cancel the transfer
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_cancel(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, TR_STRUCT_PTR tr_ptr) {
    USB_KHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR) handle;
    TR_MSG_STRUCT msg;
    
    // remove messages from KHCI msg que
    while (_lwmsgq_receive(usb_host_ptr->tr_que, (uint_32 *) &msg, 0, 0, 0) == MQX_OK)
    { /* void */ }
    
    return USB_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_bus_control
*  Returned Value : error or USB_OK
*  Comments       :
*        The function for USB bus control
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_bus_control(_usb_host_handle handle, uint_8 bus_control) {

    return USB_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_get_frame_number
*  Returned Value : frame number
*  Comments       :
*        The function to get frame number
*END*-----------------------------------------------------------------*/
uint_32 _usb_khci_get_frame_number(_usb_host_handle handle) {
    USB_HOST_STATE_STRUCT_PTR  usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR) handle;
    USB_MemMapPtr usb_ptr = (USB_MemMapPtr) usb_host_ptr->DEV_PTR;

    return (usb_ptr->FRMNUMH << 8 | usb_ptr->FRMNUML);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_process_tr_complete
*  Returned Value : none
*  Comments       :
*        Transaction complete
*END*-----------------------------------------------------------------*/
static void _usb_khci_process_tr_complete(
    KHCI_PIPE_STRUCT_PTR       pipe_desc_ptr,
    KHCI_TR_STRUCT_PTR         pipe_tr_ptr,
    uint_32                    required,
    uint_32                    remaining,
    int_32                     err
)
{
    uchar_ptr buffer_ptr = NULL;
    uint_32 status = 0;
    
    KHCI_DEBUG_LOG('o', TR_MSG_UNKNOWN, pipe_desc_ptr->G.ENDPOINT_NUMBER, err)

    if (err == KHCI_ATOM_TR_STALL) {
        status = USBERR_ENDPOINT_STALLED;
    }
    else if ((err == KHCI_ATOM_TR_NAK) || (err >= 0)) {
        status = USB_OK;
        
        if ((remaining > 0) || (err == KHCI_ATOM_TR_NAK)) //remaining bytes
            status = USBERR_TR_FAILED;

        if (pipe_desc_ptr->G.PIPETYPE == USB_CONTROL_PIPE) {
            if (pipe_tr_ptr->G.SEND_PHASE) {
                buffer_ptr = pipe_tr_ptr->G.TX_BUFFER;
                pipe_tr_ptr->G.SEND_PHASE = FALSE;
            }
            else {
                buffer_ptr = pipe_tr_ptr->G.RX_BUFFER;
            }
        }
        else {
            if (pipe_desc_ptr->G.DIRECTION) {
                buffer_ptr = pipe_tr_ptr->G.TX_BUFFER;
            }
            else {
                buffer_ptr = pipe_tr_ptr->G.RX_BUFFER;
            }
        }
    }
    else if (err < 0)
        status = USBERR_TR_FAILED;
    
    pipe_tr_ptr->status = USB_STATUS_IDLE;
    
    if (pipe_tr_ptr->status == USB_STATUS_IDLE) {
        /* Transfer done. Call the callback function for this 
        ** transaction if there is one (usually true). 
        */
        if (pipe_tr_ptr->G.CALLBACK != NULL) {
            pipe_tr_ptr->G.CALLBACK((pointer)pipe_desc_ptr, pipe_tr_ptr->G.CALLBACK_PARAM,
                buffer_ptr, required - remaining, status);
                
            /* If the application enqueued another request on this pipe 
            ** in this callback context then it will be at the end of the list
            */
        }
    }

    /* don't use pipe anymore */
    pipe_tr_ptr->G.TR_INDEX = 0;

}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_atom_tr
*  Returned Value : 
*  Comments       :
*        Atomic transaction
*END*-----------------------------------------------------------------*/
static int_32 _usb_khci_atom_tr(
    USB_KHCI_HOST_STATE_STRUCT_PTR  usb_host_ptr,
    uint_32                    type,
    KHCI_PIPE_STRUCT_PTR       pipe_desc_ptr,
    uint_8                     *buf,
    uint_32                    len
)
{
    USB_MemMapPtr usb_ptr = (USB_MemMapPtr) usb_host_ptr->G.DEV_PTR;
    uint_32 bd;
    uint_32 *bd_ptr = NULL;
    int_32 res;
    _mqx_int retry;
    _mqx_int delay_const = 10;
    usb_host_ptr->last_to_pipe = NULL; // at the beginning, consider that there was not timeout
    
    len = (len > pipe_desc_ptr->G.MAX_PACKET_SIZE) ? pipe_desc_ptr->G.MAX_PACKET_SIZE : len;
    
    /* ADDR must be written before ENDPT0 (undocumented behavior) for to generate PRE packet */
    usb_ptr->ADDR = (uint_8)((pipe_desc_ptr->G.SPEED == USB_SPEED_FULL) ? USB_ADDR_ADDR(pipe_desc_ptr->G.DEVICE_ADDRESS) : USB_ADDR_LSEN_MASK | USB_ADDR_ADDR(pipe_desc_ptr->G.DEVICE_ADDRESS));
    
    if((pipe_desc_ptr->G.PIPETYPE != USB_ISOCHRONOUS_PIPE))
    {
        usb_ptr->ENDPOINT[0].ENDPT =
            (usb_host_ptr->G.SPEED == USB_SPEED_LOW ? USB_ENDPT_HOSTWOHUB_MASK : 0) | USB_ENDPT_RETRYDIS_MASK |
            USB_ENDPT_EPTXEN_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPHSHK_MASK;
    }
    else
    {
        usb_ptr->ENDPOINT[0].ENDPT =
            (usb_host_ptr->G.SPEED == USB_SPEED_LOW ? USB_ENDPT_HOSTWOHUB_MASK : 0) | USB_ENDPT_RETRYDIS_MASK |
            USB_ENDPT_EPTXEN_MASK | USB_ENDPT_EPRXEN_MASK;
    }

    switch (pipe_desc_ptr->G.PIPETYPE) {
        case USB_INTERRUPT_PIPE:
        case USB_ISOCHRONOUS_PIPE:
            retry = 0;
            break;
        default:
            retry = pipe_desc_ptr->G.NAK_COUNT; // set retry count - do not retry interrupt transaction
            break;
    }
    
    do {
        res = 0;
        
        // wait for USB ready, but with timeout
        while (usb_ptr->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) {
            if (_lwevent_wait_ticks(&usb_host_ptr->khci_event, KHCI_EVENT_MASK, FALSE, 1) == MQX_OK) {
                res = KHCI_ATOM_TR_RESET;
                
                break;
            }
        }
        
        if (!res) {
          // all is ok, do transaction

#if defined(KHCICFG_BASIC_SCHEDULING)
          usb_ptr->ISTAT |= USB_ISTAT_SOFTOK_MASK; //clear SOF
          while (!(usb_ptr->ISTAT & USB_ISTAT_SOFTOK_MASK))
                 /* wait for next SOF */;

          usb_ptr->SOFTHLD = 0;
#else
          if (pipe_desc_ptr->G.SPEED == USB_SPEED_FULL)
              usb_ptr->SOFTHLD = len * 7 / 6 + KHCICFG_THSLD_DELAY;
          else
              usb_ptr->SOFTHLD = len * 12 * 7 / 6 + KHCICFG_THSLD_DELAY;
#endif          
          usb_ptr->ISTAT |= USB_ISTAT_SOFTOK_MASK; //clear SOF
          usb_ptr->ERRSTAT = 0xff; //clear error status

          switch (type) {
            case TR_CTRL:    
                bd_ptr = (uint_32*) BD_PTR(0, 1, usb_host_ptr->tx_bd);
                *(bd_ptr + 1) = HOST_TO_LE_LONG((uint_32)buf);
                *bd_ptr = HOST_TO_LE_LONG(USB_BD_BC(len) | USB_BD_OWN);
                usb_ptr->TOKEN = (uint_8)(USB_TOKEN_TOKENENDPT((uint_8)pipe_desc_ptr->G.ENDPOINT_NUMBER) | USB_TOKEN_TOKENPID_SETUP);
                usb_host_ptr->tx_bd ^= 1;
                break;
            case TR_IN:
                bd_ptr = (uint_32*) BD_PTR(0, 0, usb_host_ptr->rx_bd);
                *(bd_ptr + 1) = HOST_TO_LE_LONG((uint_32)buf);
                *bd_ptr = HOST_TO_LE_LONG(USB_BD_BC(len) | USB_BD_OWN | USB_BD_DATA01(pipe_desc_ptr->G.NEXTDATA01));
                usb_ptr->TOKEN = (uint_8)(USB_TOKEN_TOKENENDPT(pipe_desc_ptr->G.ENDPOINT_NUMBER) | USB_TOKEN_TOKENPID_IN);
                usb_host_ptr->rx_bd ^= 1;
                break;
            case TR_OUT:
                bd_ptr = (uint_32*) BD_PTR(0, 1, usb_host_ptr->tx_bd);
                *(bd_ptr + 1) = HOST_TO_LE_LONG((uint_32)buf);
                *bd_ptr = HOST_TO_LE_LONG(USB_BD_BC(len) | USB_BD_OWN | USB_BD_DATA01(pipe_desc_ptr->G.NEXTDATA01));
                usb_ptr->TOKEN = (uint_8)(USB_TOKEN_TOKENENDPT(pipe_desc_ptr->G.ENDPOINT_NUMBER) | USB_TOKEN_TOKENPID_OUT);
                usb_host_ptr->tx_bd ^= 1;
                break;                
            default:
                bd_ptr = NULL;
          }
          
          // wait for end of transaction or other event, max. 100 msec
          if (LWEVENT_WAIT_TIMEOUT == _lwevent_wait_ticks(&usb_host_ptr->khci_event, KHCI_EVENT_MASK, FALSE, USBCFG_KHCI_WAIT_TICK))
          {
                res = KHCI_ATOM_TR_TO;
                usb_host_ptr->last_to_pipe = pipe_desc_ptr; // remember this pipe as it had timeout last time
                continue;
          }
        }
        
try_again:
        // check for reset event (detach)
        if (usb_host_ptr->khci_event.VALUE & KHCI_EVENT_RESET) {
            res = KHCI_ATOM_TR_RESET;
            break;
        }
    
        if (bd_ptr != NULL && (usb_host_ptr->khci_event.VALUE & KHCI_EVENT_TOK_DONE)) {
            // transaction finished
            _lwevent_clear(&usb_host_ptr->khci_event, KHCI_EVENT_TOK_DONE);

            // check result
            bd = LONG_LE_TO_HOST(*bd_ptr);
            
            if (usb_ptr->ERRSTAT & (
                    USB_ERREN_PIDERREN_MASK |
#if defined(KHCICFG_BASIC_SCHEDULING)
                    USB_ERREN_CRC5EOFEN_MASK |
#endif                   
                    USB_ERREN_CRC16EN_MASK |
                    USB_ERREN_DFN8EN_MASK |
//                    USB_ERREN_BTO_ERR_EN_MASK | //timeout tested elsewhere
                    USB_ERREN_DMAERREN_MASK |
                    USB_ERREN_BTSERREN_MASK))
            {
#if defined(KHCICFG_BASIC_SCHEDULING)
                if (usb_ptr->ERRSTAT & USB_ERREN_CRC5EOFEN_MASK)
                    retry = 0;
#endif                   
                res = -usb_ptr->ERRSTAT;
                break;
            }
            else 
            {
                switch (bd >> 2 & 0xf) {
                    case 0x03:  // DATA0
                    case 0x0b:  // DATA1
                    case 0x02:  // ACK
                        retry = 0;
                        res = (bd >> 16) & 0x3ff;
                        pipe_desc_ptr->G.NEXTDATA01 ^= 1;     // switch data toggle
                        break;

                    case 0x0e:  // STALL
                        res = KHCI_ATOM_TR_STALL;
                        retry = 0;
                        break;

                    case 0x0a:  // NAK
                        res = KHCI_ATOM_TR_NAK;
                        if (retry)
                            _time_delay(delay_const * (pipe_desc_ptr->G.NAK_COUNT - retry));
                        break;

                    case 0x00:  // bus timeout
                        if((pipe_desc_ptr->G.PIPETYPE != USB_ISOCHRONOUS_PIPE))
                        {
                            //wait a bit, but not too much, perhaps some error occurs on the bus
                            if (LWEVENT_WAIT_TIMEOUT == _lwevent_wait_ticks(&usb_host_ptr->khci_event, KHCI_EVENT_MASK, FALSE, delay_const)) 
                            {
                                res = KHCI_ATOM_TR_TO;
                                usb_host_ptr->last_to_pipe = pipe_desc_ptr; // remember this pipe as it had timeout last time
                                if (retry)
                                    _time_delay(delay_const * (pipe_desc_ptr->G.NAK_COUNT - retry));
                            }
                            else
                                goto try_again;
                        }
                        else
                        {
                            retry = 0;
                            res = (bd >> 16) & 0x3ff;
                            pipe_desc_ptr->G.NEXTDATA01 ^= 1;     /* switch data toggle */                        
                        }
                        break;

                    case 0x0f:  // data error
                        //if this event happens during enumeration, then return means not finished enumeration
                        res = KHCI_ATOM_TR_DATA_ERROR;
                        _time_delay(delay_const * (pipe_desc_ptr->G.NAK_COUNT - retry));
                        break;
                        
                    default:
                        break;
                }
            }
        }
    } while (retry--);
    
    return res;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_khci_host_close_pipe
*  Returned Value : error or USB_OK
*  Comments       :
*        The function to close pipe
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_khci_host_close_pipe(_usb_host_handle handle, PIPE_STRUCT_PTR pipe_desc_ptr) {
    USB_KHCI_HOST_STATE_STRUCT_PTR  usb_host_ptr = (USB_KHCI_HOST_STATE_STRUCT_PTR)handle;

    if (pipe_desc_ptr->PIPETYPE == USB_INTERRUPT_PIPE) {
        _mqx_int i;
        TR_INT_QUE_ITM_STRUCT_PTR tr = usb_host_ptr->tr_int_que;

        // find record
        for (i = 0; i < USBCFG_KHCI_MAX_INT_TR; i++, tr++) {
            if (tr->msg.pipe_desc == (KHCI_PIPE_STRUCT_PTR) pipe_desc_ptr)
                tr->msg.type = TR_MSG_UNKNOWN;    
        }
    }
    else {
        /* Now, we should check whether there is a transfer in the message pool */
    }
    return USB_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enetprv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enetprv.h$
* $Version : 3.8.5.0$
* $Date    : Aug-7-2012$
*
* Comments:
*
*   This file contains the private defines, externs and
*   data structure definitions required by the Ethernet
*   packet driver.
*
*END************************************************************************/
#ifndef __enetprv_h__
#define __enetprv_h__


#ifdef __cplusplus
extern "C" {
#endif


/***************************************
**
** Code macros
**
*/
#define ENET_ALIGN(x,pow)        (((x) + ((pow)-1)) & ~((pow)-1))

//#define ENET_lock_context()      _int_disable()
#define ENET_lock_context(enet_ptr)      \
    {   \
        _lwsem_wait(&enet_ptr->CONTEXT_LOCK);    \
    }


//#define ENET_unlock_context()    _int_enable()
#define ENET_unlock_context(enet_ptr)   \
    {   \
        _lwsem_post(&enet_ptr->CONTEXT_LOCK);    \
    }

#define QADD(head,tail,pcb)      \
   if ((head) == NULL) {         \
      (head) = (pcb);            \
   } else {                      \
      (tail)->PRIVATE = (pcb);   \
   }                             \
   (tail) = (pcb);               \
   (pcb)->PRIVATE = NULL

#define QGET(head,tail,pcb)      \
   (pcb) = (head);               \
   if (head) {                   \
      (head) = (head)->PRIVATE;  \
      if ((head) == NULL) {      \
         (tail) = NULL;          \
      }                          \
   }             


/***************************************
**
** Data structures
**
*/


/* Joined multicast groups */
typedef struct enet_mcb_struct {
   _enet_address        GROUP;
   uint_32              HASH;
   struct enet_mcb_struct _PTR_     NEXT;
} ENET_MCB_STRUCT, _PTR_ ENET_MCB_STRUCT_PTR;

/* Registered protocol numbers */
typedef struct enet_ecb_struct {
   uint_16              TYPE;
   void (_CODE_PTR_     SERVICE)(PCB_PTR, pointer);
   ENET_MCB_STRUCT_PTR  MCB_HEAD;
   pointer              PRIVATE;
   struct enet_ecb_struct _PTR_     NEXT;
} ENET_ECB_STRUCT, _PTR_ ENET_ECB_STRUCT_PTR;

/* The Ethernet state structure */
struct enet_context_struct;

typedef struct enet_context_struct {
   struct enet_context_struct *  NEXT;
   ENET_ECB_STRUCT_PTR           ECB_HEAD;
   const ENET_PARAM_STRUCT *     PARAM_PTR;
   _enet_address                 ADDRESS;
   uchar                         PHY_ADDRESS;         // Note, keep adjacent to ADDRESS for alignment
   uint_16                       MaxRxFrameSize;
   uint_16                       MaxTxFrameSize;
   pointer                       MAC_CONTEXT_PTR;   
#if BSPCFG_ENABLE_ENET_STATS
   ENET_STATS                    STATS;      
#endif

   LWSEM_STRUCT                  CONTEXT_LOCK;
} ENET_CONTEXT_STRUCT, _PTR_ ENET_CONTEXT_STRUCT_PTR;


/***************************************
**
** Prototypes
**
*/

extern ENET_ECB_STRUCT_PTR ENET_find_receiver(ENET_CONTEXT_STRUCT_PTR, ENET_HEADER_PTR, uint_32_ptr);

extern uint_16 ENET_max_framesize(uint_16, uint_16, boolean );

extern void    ENET_Enqueue_Buffer( pointer * q, pointer b) ; 
extern pointer ENET_Dequeue_Buffer( pointer * q);

#ifdef __cplusplus
}
#endif

#endif /* __enetprv_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/host_cnl.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_cnl.c$
* $Version : 3.8.12.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the USB Host API specific functions to cancel 
*   a transfer.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_main.h"
#include "host_cnl.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_cancel_transfer
*  Returned Value : error or status of the transfer before cancellation
*  Comments       :
* _usb_host_cancel_transfer is a non-blocking routine that causes a transfer to 
* be terminated. 
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_cancel_transfer
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle     handle,

      /* [IN] the pipe handle */
      _usb_pipe_handle     pipe_handle,

      /* [IN] the transfer numnber for this pipe */
      uint_32              tr_number
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   PIPE_STRUCT_PTR            pipe_descr_ptr = (PIPE_STRUCT_PTR)pipe_handle;
   TR_STRUCT_PTR              pipe_tr_ptr;
   USB_STATUS error;
   uint_32  bRet;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_cancel_transfer");
   #endif

   USB_lock();

   /* Check if valid pipe id */
   if (pipe_descr_ptr->PIPE_ID > USBCFG_MAX_PIPES) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_cancel_transfer, invalid pipe");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_PIPE_HANDLE);
   } /* Endif */

   pipe_tr_ptr = pipe_descr_ptr->tr_list_ptr;
   while (pipe_tr_ptr->TR_INDEX != tr_number)  {
      /* If unused TR found, or end of list, exit with bad status */
      if ((pipe_tr_ptr->TR_INDEX == 0) ||
         (pipe_tr_ptr->NEXT== pipe_descr_ptr->tr_list_ptr))
      {
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_cancel_transfer, invalid pipe");
         #endif
         return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_PIPE_HANDLE);
      } /* EndIf */
      pipe_tr_ptr = pipe_tr_ptr->NEXT;   
   } /* EndWhile */

   /* Get the current status */
   bRet = pipe_tr_ptr->STATUS;

   /* Cancel the transfer at low-level */
   error = _usb_host_cancel_call_interface (handle, pipe_descr_ptr, pipe_tr_ptr);
   
   if (error != USB_OK)
   {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_cancel_transfer, FAILED");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   }

   /* Indicate that the pipe is idle */
   pipe_tr_ptr->STATUS = USB_STATUS_IDLE;

   if (pipe_tr_ptr->CALLBACK != NULL) {
      pipe_tr_ptr->CALLBACK((pointer)pipe_descr_ptr,
         pipe_tr_ptr->CALLBACK_PARAM,
         NULL,
         0,
         USBERR_SHUTDOWN);
   } /* Endif */

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_cancel_transfer,SUCCESSFUL");
   #endif

   /* Return the status prior to the transfer cancellation */
   return bRet;

} /* Endbody */
 
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/can/flexcan/flexcan_int.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flexcan_int.c$
* $Version : 3.8.10.0$
* $Date    : Sep-1-2011$
*
* Comments:
*
*   Revision History:
*   Date             Version  Changes
*   ---------        -------  -------
*   Jan.20/04        2.50     Initial version
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <flexcan.h>

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_int_enable
* Returned Value   : uint_32 
* Comments         :
*    This function enables interrupt for requested mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Int_enable
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number
)
{
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   volatile PSP_INTERRUPT_TABLE_INDEX     index;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }
   
   if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB (0xFFFFFFFF)) ) 
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }
   
   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BUF, mailbox_number);
   if (0 == index)
   {
      return (FLEXCAN_INT_ENABLE_FAILED);
   }
         
   if (_flexcan_int_init (index, FLEXCAN_MESSBUF_INT_LEVEL, FLEXCAN_MESSBUF_INT_SUBLEVEL, TRUE) != MQX_OK)
   {
      return (FLEXCAN_INT_ENABLE_FAILED);
   }
   
   /* IMASK, unmask the message buffer */
   (can_reg_ptr->IMASK)  |= (0x1 << mailbox_number);

   return( FLEXCAN_OK );
}

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Error_int_enable
* Returned Value   : uint_32 
* Comments         :
*    This function unmasks (enables) error, wake up & Bus off interrupts.
*
*
*END*********************************************************************/
uint_32 FLEXCAN_Error_int_enable
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   volatile PSP_INTERRUPT_TABLE_INDEX     index;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_ERR, 0);
   if (0 == index)
   {
      return (FLEXCAN_INT_ENABLE_FAILED);
   }

   if (_flexcan_int_init (index, FLEXCAN_ERROR_INT_LEVEL, FLEXCAN_ERROR_INT_SUBLEVEL, TRUE) != MQX_OK)
   {
      return (FLEXCAN_INT_ENABLE_FAILED);
   }

   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BOFF, 0);
   if (0 == index)
   {
      return (FLEXCAN_INT_ENABLE_FAILED);
   }

   if (_flexcan_int_init (index, FLEXCAN_BUSOFF_INT_LEVEL, FLEXCAN_BUSOFF_INT_SUBLEVEL, TRUE) != MQX_OK)
   {
      return (FLEXCAN_INT_ENABLE_FAILED);
   }
                        
    /* BOFFMSK = 0x1, ERRMSK = 0x1 */
   can_reg_ptr->CANCTRL |= (FLEXCAN_CANCTRL_BOFFMSK | FLEXCAN_CANCTRL_ERRMSK);

   return ( FLEXCAN_OK );
}

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_int_disable
* Returned Value   : uint_32 
* Comments         :
*    This function masks (disables) interrupt for requested mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Int_disable
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number
)
{
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   volatile PSP_INTERRUPT_TABLE_INDEX     index;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB (0xFFFFFFFF)) ) 
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   /* Start CR# 1750 */
   can_reg_ptr->IMASK  &= ~(0x1 << mailbox_number);
   /* End CR# 1750 */

   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BUF, mailbox_number);
   if (0 == index)
   {
      return (FLEXCAN_INT_DISABLE_FAILED);
   }

   /* Disable the interrupt */
   if (_flexcan_int_init (index, FLEXCAN_MESSBUF_INT_LEVEL, FLEXCAN_MESSBUF_INT_SUBLEVEL, FALSE) != MQX_OK)
   {
      return (FLEXCAN_INT_DISABLE_FAILED);
   }
      
   return (FLEXCAN_OK);
}

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Error_int_disable
* Returned Value   : uint_32 
* Comments         :
*    This function masks (disables) error, wake up & Bus off interrupts 
*
*END*********************************************************************/
uint_32 FLEXCAN_Error_int_disable
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   volatile PSP_INTERRUPT_TABLE_INDEX     index;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

    /* BOFFMSK = 0x1, ERRMSK = 0x1 */
   can_reg_ptr->CANCTRL &= ~(FLEXCAN_CANCTRL_BOFFMSK | FLEXCAN_CANCTRL_ERRMSK);

   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_ERR, 0);
   if (0 == index)
   {
      return (FLEXCAN_INT_DISABLE_FAILED);
   }

   if (_flexcan_int_init (index, FLEXCAN_ERROR_INT_LEVEL, FLEXCAN_ERROR_INT_SUBLEVEL, FALSE) != MQX_OK)
   {
      return (FLEXCAN_INT_DISABLE_FAILED);
   }

   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BOFF, 0);
   if (0 == index)
   {
      return (FLEXCAN_INT_DISABLE_FAILED);
   }

   if (_flexcan_int_init (index, FLEXCAN_BUSOFF_INT_LEVEL, FLEXCAN_BUSOFF_INT_SUBLEVEL, FALSE) != MQX_OK)
   {
      return (FLEXCAN_INT_DISABLE_FAILED);
   }

   return ( FLEXCAN_OK );
}

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Install_isr_ex
* Returned Value   : uint_32 
* Comments         :
*    This function installs interrupt handler for requested mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Install_isr_ex
(
   /* [IN] FlexCAN device number */
   uint_8       dev_num,
   /* [IN] mailbox number */
   uint_32      mailbox_number,
   /* [IN] Interrupt service routine */
   INT_ISR_FPTR isr,
   /* [IN] Interrupt service routine */
   pointer      isr_data
)
{
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   uint_32   return_code = FLEXCAN_OK;
   INT_ISR_FPTR result;
   volatile PSP_INTERRUPT_TABLE_INDEX     index;
   
   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB (0xFFFFFFFF)) ) 
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }
   
   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BUF, mailbox_number);
   if (0 == index)
   {
      return (FLEXCAN_INT_INSTALL_FAILED);
   }

   /* Install ISR */
   result = _int_install_isr (index, isr, (pointer)isr_data);
   if(result == (INT_ISR_FPTR)NULL)
   {
      return_code = _task_get_error();
   }

   return return_code;
}
/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Install_isr
* Returned Value   : uint_32 
* Comments         :
*    This function installs interrupt handler for requested mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Install_isr
(
   /* [IN] FlexCAN device number */
   uint_8       dev_num,
   /* [IN] mailbox number */
   uint_32      mailbox_number,
   /* [IN] Interrupt service routine */
   INT_ISR_FPTR isr
)
{
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
  
   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   return FLEXCAN_Install_isr_ex(dev_num, mailbox_number, isr, (pointer) can_reg_ptr);
}

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Install_isr_err_int
* Returned Value   : uint_32 
* Comments         :
*    This function installs interrupt handler for a flexcan error
*
*END*********************************************************************/
uint_32 FLEXCAN_Install_isr_err_int
(
   /* [IN] FlexCAN device number */
   uint_8       dev_num,
   /* [IN] Interrupt service routine */
   INT_ISR_FPTR isr
)
{
   uint_32   return_code = FLEXCAN_OK;
   INT_ISR_FPTR result;
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   volatile PSP_INTERRUPT_TABLE_INDEX     index;
   
   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }
 
   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_ERR, 0);
   if (0 == index)
   {
      return (FLEXCAN_INT_INSTALL_FAILED);
   }

   result = _int_install_isr (index, isr, (pointer)can_reg_ptr); 
   if(result == (INT_ISR_FPTR)NULL)
   {
      return_code = _task_get_error();
   }

   return return_code;
}
 
/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Install_isr_boff_int
* Returned Value   : uint_32 
* Comments         :
*    This function installs interrupt handler for a flexcan bus off
*
*END*********************************************************************/
uint_32 FLEXCAN_Install_isr_boff_int
(
   /* [IN] FlexCAN device number */
   uint_8       dev_num,
   /* [IN] Interrupt service routine */
   INT_ISR_FPTR isr
)
{
   uint_32   return_code = FLEXCAN_OK;
   INT_ISR_FPTR result;
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   volatile PSP_INTERRUPT_TABLE_INDEX     index;
   
   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BOFF, 0);
   if (0 == index)
   {
      return (FLEXCAN_INT_INSTALL_FAILED);
   }

   result = _int_install_isr (index, isr, (pointer)can_reg_ptr); 
   if(result == (INT_ISR_FPTR)NULL)
   {
      return_code = _task_get_error();
   }

   return return_code;
}

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Install_isr_wake_int
* Returned Value   : uint_32 
* Comments         :
*    This function installs interrupt handler for a flexcan wake-up
*
*END*********************************************************************/
uint_32 FLEXCAN_Install_isr_wake_int
(
   /* [IN] FlexCAN device number */
   uint_8       dev_num,
   /* [IN] Interrupt service routine */
   INT_ISR_FPTR isr
)
{
   uint_32   return_code = FLEXCAN_OK;
   INT_ISR_FPTR result;
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   volatile PSP_INTERRUPT_TABLE_INDEX     index;
  
   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_WAKEUP, 0);
   if (0 == index)
   {
      return (FLEXCAN_INT_INSTALL_FAILED);
   }

   result = _int_install_isr (index, isr, (pointer)can_reg_ptr); 
   if(result == (INT_ISR_FPTR)NULL)
   {
      return_code = _task_get_error();
   }
    
   return return_code;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _FLEXCAN_ISR
* Returned Value   : uint_32 
* Comments         :
*    This function services FlexCAN interrupt routine. 
*
*END*********************************************************************/
void _FLEXCAN_ISR
(
   /* [IN] FlexCAN base address */
   pointer can_ptr
)
{
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   vuint_32                               tmp_reg;
   vuint_32                               temp;
      
   can_reg_ptr = (FLEXCAN_REG_STRUCT_PTR)can_ptr;

   /* get the interrupt flag */
   tmp_reg = (can_reg_ptr->IFLAG & FLEXCAN_IMASK_VALUE);
   // check Tx/Rx interrupt flag and clear the interrupt
   if(tmp_reg)
   {
      /* clear the interrupt and unlock message buffer */
      /* Start CR# 1751 */
      can_reg_ptr->IFLAG |= tmp_reg;
      /* End CR# 1751 */
      temp = can_reg_ptr->TIMER;
   }/* Endif */

   // Clear all other interrupts in ERRSTAT register (Error, Busoff, Wakeup)
   tmp_reg = (can_reg_ptr->ERRSTAT & FLEXCAN_ALL_INT);
   if(tmp_reg)
   {
      /* Start CR# 1751 */
      can_reg_ptr->ERRSTAT |= tmp_reg;
      /* End CR# 1751 */
   } /* Endif */
      
   return;
}
   
/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_int_status
* Returned Value   : uint_32 
* Comments         :
*    This function gets the FlexCAN interrupt status. 
*
*END*********************************************************************/
uint_32 FLEXCAN_Int_status
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
   vuint_32                               tmp_reg;
   
   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)  
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   // check Tx/Rx interrupt flag
   tmp_reg = (can_reg_ptr->IFLAG & FLEXCAN_IMASK_VALUE);
   if(tmp_reg)
   {
      return (FLEXCAN_TX_RX_INT);
   } /*Endif*/

   // check error interrupt
   tmp_reg = (can_reg_ptr->ERRSTAT & FLEXCAN_ERROR_INT);
   if(tmp_reg)
   {
      return (FLEXCAN_ERROR_INT);   
   } /*Endif*/

   // check busoff interrupt
   tmp_reg = (can_reg_ptr->ERRSTAT & FLEXCAN_BUSOFF_INT);
   if(tmp_reg)
   {
      return (FLEXCAN_BUSOFF_INT);   
   } /*Endif*/

   // check busoff interrupt
   tmp_reg = (can_reg_ptr->ERRSTAT & FLEXCAN_WAKEUP_INT);
   if(tmp_reg)
   {
      return (FLEXCAN_WAKEUP_INT);   
   } /*Endif*/
   
   return (FLEXCAN_OK);
}


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_format.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_format.c$
* $Version : 3.7.14.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_prv.h>

static const char_ptr BYTE_SIZES[] = { "bytes", "kB", "MB", "GB", "TB" };

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_format
* Returned Value   :  int_32 error code
* Comments  :  mount a filesystem on a device.
*
* Usage:  format <drive:> [<volume label>]
*
*END*---------------------------------------------------------------------*/

int_32  Shell_format(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean                    print_usage, shorthelp = FALSE;
   int_32                     return_code = SHELL_EXIT_SUCCESS;
   int_32                     error_code = IO_ERROR;
   MQX_FILE_PTR               fs_ptr = NULL;
   char_ptr                   volume_ptr[SFILENAME_SIZE];
   uint_64                    big_number;
   uint_32                    small_number;
   
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc < 2 || argc >  3) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else  {
         if (argc == 3)  {
            memcpy (volume_ptr, argv[2], SFILENAME_SIZE);
         } else  {
            volume_ptr[0] = 0;
         }
         fs_ptr = _io_get_fs_by_name(argv[1]);
         if (fs_ptr == NULL)  {
            printf("Error, file system %s not found\n", argv[1] );
            return_code = SHELL_EXIT_ERROR;
         } else {
            printf("\nFormating...\n");
            error_code = ioctl(fs_ptr, IO_IOCTL_DEFAULT_FORMAT,  NULL);
            if ( !error_code && (*volume_ptr)) {
               error_code = ioctl(fs_ptr, IO_IOCTL_SET_VOLUME,  (pointer) volume_ptr);
            }       
            if (error_code) {
               printf("Error while formatting: 0x%x\n", error_code);
            } else  {
               /* print disk information */
               error_code = ioctl(fs_ptr, IO_IOCTL_GET_VOLUME, (uint_32_ptr) volume_ptr);
               printf("Done. Volume name is %s\nFree disk space: ", volume_ptr);
               ioctl(fs_ptr, IO_IOCTL_GET_CLUSTER_SIZE, &small_number);
               big_number = (uint_64)ioctl(fs_ptr, IO_IOCTL_FREE_CLUSTERS, NULL) * small_number;
               for (small_number = 0; big_number > MAX_UINT_32; big_number >>= 10) small_number++;
               printf ("%lu %s\n", (uint_32)big_number, BYTE_SIZES[small_number]);
            } 
         }
      }
   }
      
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <drive:> [<volume label>]\n", argv[0]);
      } else  {
         printf("Usage: %s <drive:> [<volume label>]\n", argv[0]);
         printf("   <drive:> = specifies the drive name (followed by a colon)\n");
         printf("   <volume label>  = specifies the volume label\n");
      }
   }
   return return_code;
}


/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi_legacy/polled/spi_pol_mcf5xxx_qspi.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_pol_mcf5xxx_qspi.c$
* $Version : 3.8.22.0$
* $Date    : Jun-22-2012$
*
* Comments:
*
*   The file contains low level SPI driver functions for 51xx Coldfire family.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "spi.h"
#include "spi_pol_prv.h"
#include "spi_mcf5xxx_qspi_prv.h"

uint_32 _mcf5xxx_qspi_polled_init(MCF5XXX_QSPI_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
uint_32 _mcf5xxx_qspi_polled_ioctl(MCF5XXX_QSPI_INFO_STRUCT_PTR, uint_32, uint_32_ptr, uint_32);

static uint_32 _mcf5xxx_qspi_polled_deinit(IO_SPI_POLLED_DEVICE_STRUCT_PTR, MCF5XXX_QSPI_INFO_STRUCT_PTR);
static uint_32 _mcf5xxx_qspi_polled_rx(IO_SPI_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
static uint_32 _mcf5xxx_qspi_polled_tx(IO_SPI_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
static uint_32 _mcf5xxx_qspi_polled_tx_rx(MCF5XXX_QSPI_INFO_STRUCT_PTR, uint_8_ptr, uint_8_ptr, uint_32, uint_16);

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_find_baudrate
* Returned Value   : uint_8 divider register setting
* Comments         :
*    Find closest setting of divider register for given baudrate.
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_find_baudrate 
    (
        /* [IN] Module input clock in Hz */
        uint_32 clock, 
        
        /* [IN] Desired baudrate in Hz */
        uint_32 baudrate
    ) 
{
    uint_32 div = 0;
    
    if (0 != baudrate)
    {
        div = (clock + baudrate) / (baudrate << 1);
        if (div < 2) div = 2;
        if (div > 255) div = 255;
    }
    return MCF5XXX_QSPI_QMR_BAUD(div);
}
    
/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_polled_install
* Returned Value   : MQX error code
* Comments         :
*    Install an SPI device.
*
*END*********************************************************************/
uint_32 _mcf5xxx_qspi_polled_install
    (
        /* [IN] A string that identifies the device for fopen */
        char_ptr           identifier,
        
        /* [IN] The I/O init data pointer */
        MCF5XXX_QSPI_INIT_STRUCT_CPTR   init_data_ptr
    )
{ 
    return _io_spi_polled_install(identifier,
    (uint_32 (_CODE_PTR_)(pointer, pointer _PTR_, char_ptr))_mcf5xxx_qspi_polled_init,
    (uint_32 (_CODE_PTR_)(pointer, pointer))_mcf5xxx_qspi_polled_deinit,
    (_mqx_int (_CODE_PTR_)(pointer, char_ptr, int_32))_mcf5xxx_qspi_polled_rx,
    (_mqx_int (_CODE_PTR_)(pointer, char_ptr, int_32))_mcf5xxx_qspi_polled_tx,
    (_mqx_int (_CODE_PTR_)(pointer, uint_32, _mqx_uint_ptr, uint_32))_mcf5xxx_qspi_polled_ioctl, 
    (pointer)init_data_ptr);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_polled_init  
* Returned Value   : MQX error code
* Comments         :
*    This function initializes the SPI module 
*
*END*********************************************************************/
uint_32 _mcf5xxx_qspi_polled_init
    (
        /* [IN] The initialization information for the device being opened */
        MCF5XXX_QSPI_INIT_STRUCT_PTR  qspi_init_ptr,
        
        /* [OUT] The address to store device specific information */
        pointer _PTR_                 io_info_ptr_ptr,  
        
        /* [IN] The rest of the name of the device opened */
        char_ptr                      open_name_ptr
    )
{
    VMCF5XXX_QSPI_STRUCT_PTR          qspi_ptr;
    MCF5XXX_QSPI_INFO_STRUCT_PTR      io_info_ptr;
    uint_32                           i;
    
    /* Check channel */
    qspi_ptr = _bsp_get_qspi_base_address (qspi_init_ptr->CHANNEL);
    if (NULL == qspi_ptr)
    {
        return SPI_ERROR_CHANNEL_INVALID;
    }

    if (_bsp_qspi_io_init (qspi_init_ptr->CHANNEL) == -1)
    {
        return SPI_ERROR_CHANNEL_INVALID;
    }

    /* Disable and clear SPI */
    qspi_ptr->QIR = MCF5XXX_QSPI_QIR_WCEF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_SPIF;
    qspi_ptr->QWR = MCF5XXX_QSPI_QWR_HALT | MCF5XXX_QSPI_QWR_CSIV | MCF5XXX_QSPI_QWR_NEWQP(0) | MCF5XXX_QSPI_QWR_ENDQP(0);
    while (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE) 
       {};
    qspi_ptr->QIR = MCF5XXX_QSPI_QIR_WCEF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_SPIF;
    
    /* Initialize internal data */
    io_info_ptr = (MCF5XXX_QSPI_INFO_STRUCT_PTR)_mem_alloc_system_zero((uint_32)sizeof(MCF5XXX_QSPI_INFO_STRUCT));
    if (io_info_ptr == NULL) 
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type (io_info_ptr,MEM_TYPE_IO_SPI_INFO_STRUCT);
    
    *io_info_ptr_ptr = io_info_ptr;
    
    io_info_ptr->QSPI_PTR           = qspi_ptr;
    io_info_ptr->INIT               = *qspi_init_ptr;
    io_info_ptr->RECEIVING          = 0;
    io_info_ptr->ONTHEWAY           = 0;
    io_info_ptr->RX_REQUEST         = 0;
    io_info_ptr->RX_BUFFER          = NULL;
    io_info_ptr->RX_IN              = 0;
    io_info_ptr->RX_OUT             = 0;
    io_info_ptr->TX_BUFFER          = NULL;
    io_info_ptr->TX_IN              = 0;
    io_info_ptr->TX_OUT             = 0;
    io_info_ptr->STATS.INTERRUPTS   = 0;
    io_info_ptr->STATS.RX_PACKETS   = 0;
    io_info_ptr->STATS.RX_OVERFLOWS = 0;
    io_info_ptr->STATS.TX_PACKETS   = 0;
    io_info_ptr->STATS.TX_ABORTS    = 0;
    io_info_ptr->STATS.TX_UNDERFLOWS= 0;
    io_info_ptr->CS                 = qspi_init_ptr->CS;
    io_info_ptr->CS_ACTIVE          = 0;
    io_info_ptr->CSIV_ACTIVE        = TRUE;
    for (i = 0; i < MCF5XXX_QSPI_CS_COUNT; i++)
    {
        io_info_ptr->CS_CALLBACK[i] = NULL;
        io_info_ptr->CS_USERDATA[i] = NULL;
    }
    
    /* Set the SPI clock baud rate divider */
    qspi_ptr->QMR = _mcf5xxx_qspi_find_baudrate (qspi_init_ptr->CLOCK_SPEED, qspi_init_ptr->BAUD_RATE) | MCF5XXX_QSPI_QMR_BITS_SET(8);

    /* Set up SPI clock polarity and phase */
    switch (qspi_init_ptr->CLOCK_POL_PHASE)
    {
        case (SPI_CLK_POL_PHA_MODE0):
            /* Inactive state of SPI_CLK = logic 0 */
            qspi_ptr->QMR &= (~ MCF5XXX_QSPI_QMR_CPOL);
            /* SPI_CLK transitions middle of bit timing */
            qspi_ptr->QMR &= (~ MCF5XXX_QSPI_QMR_CPHA);
            break;
        case (SPI_CLK_POL_PHA_MODE1):
            /* Inactive state of SPI_CLK = logic 0 */
            qspi_ptr->QMR &= (~ MCF5XXX_QSPI_QMR_CPOL);
            /* SPI_CLK transitions begining of bit timing */
            qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_CPHA;
            break;
        case (SPI_CLK_POL_PHA_MODE2):
            /* Inactive state of SPI_CLK = logic 1 */
            qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_CPOL;
            /* SPI_CLK transitions middle of bit timing */
            qspi_ptr->QMR &= (~ MCF5XXX_QSPI_QMR_CPHA);
            break;
        case (SPI_CLK_POL_PHA_MODE3):
            /* Inactive state of SPI_CLK = logic 1 */
            qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_CPOL;
            /* SPI_CLK transitions begining of bit timing */
            qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_CPHA;
            break;
        default:
            return SPI_ERROR_MODE_INVALID;       
    }
    /* Set transfer mode */
    if (qspi_init_ptr->TRANSFER_MODE == SPI_DEVICE_MASTER_MODE)
    {
        qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_MSTR;
    }
    else
    {
        _mem_free (*io_info_ptr_ptr);
        *io_info_ptr_ptr = NULL;
        return SPI_ERROR_TRANSFER_MODE_INVALID;
    }

    /* Enable SPI (clear HALT) */
    qspi_ptr->QWR &= (~ MCF5XXX_QSPI_QWR_HALT);
    
    return SPI_OK;
}
    
/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_polled_deinit  
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes the SPI module 
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_polled_deinit
    (
        /* [IN] the initialization information for the device being opened */
        IO_SPI_POLLED_DEVICE_STRUCT_PTR io_dev_ptr,
        
        /* [IN] the address of the device specific information */
        MCF5XXX_QSPI_INFO_STRUCT_PTR    io_info_ptr
    )
{
    VMCF5XXX_QSPI_STRUCT_PTR            qspi_ptr;
    uint_32                             index;
    
    if ((NULL == io_info_ptr) || (NULL == io_dev_ptr)) 
    {
        return SPI_ERROR_DEINIT_FAILED;
    }
    
    /* Disable and clear SPI */
    qspi_ptr = io_info_ptr->QSPI_PTR;
    qspi_ptr->QIR = MCF5XXX_QSPI_QIR_WCEF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_SPIF;
    qspi_ptr->QWR |= MCF5XXX_QSPI_QWR_HALT | MCF5XXX_QSPI_QWR_CSIV;
    while (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE) 
       {};
    qspi_ptr->QIR = MCF5XXX_QSPI_QIR_WCEF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_SPIF;

    /* Disable all chip selects */
    for (index = 0; index < MCF5XXX_QSPI_CS_COUNT; index++)
    {
        if ((NULL != io_info_ptr->CS_CALLBACK[index]) && (0 != (io_info_ptr->CS_ACTIVE & (1 << index))))
        {
            io_info_ptr->CS_CALLBACK[index] (1 << index, 1, io_info_ptr->CS_USERDATA[index]);
        }
    }
    io_info_ptr->CS_ACTIVE = 0;

    /* Release buffers */
    _mem_free(io_dev_ptr->DEV_INFO_PTR);
    io_dev_ptr->DEV_INFO_PTR = NULL;
    return SPI_OK;
}
    
/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_polled_ioctl
* Returned Value   : MQX error code
* Comments         : 
*    This function performs miscellaneous services for
*    the SPI I/O device.  
*
*END*********************************************************************/
uint_32 _mcf5xxx_qspi_polled_ioctl
    (
        /* [IN] The address of the device specific information */
        MCF5XXX_QSPI_INFO_STRUCT_PTR io_info_ptr,
        
        /* [IN] The command to perform */
        uint_32                      cmd,
        
        /* [IN] Parameters for the command */
        uint_32_ptr                  param_ptr,

        /* [IN] Opening flags */
        uint_32                      flags
    )
{
    VMCF5XXX_QSPI_STRUCT_PTR         qspi_ptr;
    uint_32                          val, num, size, command;
    uint_32                          result = SPI_OK;
    SPI_READ_WRITE_STRUCT_PTR        rw_ptr;
    uchar_ptr                        input, output;
    SPI_CS_CALLBACK_STRUCT_PTR       callbacks;
    
    qspi_ptr = io_info_ptr->QSPI_PTR;
    
    switch (cmd) 
    {
        case IO_IOCTL_SPI_GET_BAUD:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                val = MCF5XXX_QSPI_QMR_BAUD(qspi_ptr->QMR) << 1;
                if (0 == val) *param_ptr = val; 
                else *param_ptr = (uint_32)((io_info_ptr->INIT.CLOCK_SPEED) / val);
            }
            break;
        case IO_IOCTL_SPI_SET_BAUD:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else if (0 == (*param_ptr)) 
            {
                result = SPI_ERROR_BAUD_RATE_INVALID;
            } 
            else 
            {
                if (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE)
                {
                    result = IO_ERROR_DEVICE_BUSY;
                }
                else
                {
                    /* Set the frequency divider */
                    val = _mcf5xxx_qspi_find_baudrate (io_info_ptr->INIT.CLOCK_SPEED, *param_ptr);
                    qspi_ptr->QMR = (qspi_ptr->QMR & (~ (MCF5XXX_QSPI_QMR_BAUD(0xFF)))) | MCF5XXX_QSPI_QMR_BAUD(val);
                }
            }
            break;
        case IO_IOCTL_SPI_DEVICE_DISABLE:
            qspi_ptr->QIR |= MCF5XXX_QSPI_QIR_WCEF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_SPIF;
            qspi_ptr->QWR |= MCF5XXX_QSPI_QWR_HALT;
            while (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE) 
               {};
            qspi_ptr->QIR |= MCF5XXX_QSPI_QIR_WCEF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_SPIF;
            break;
        case IO_IOCTL_SPI_DEVICE_ENABLE:
            qspi_ptr->QWR &= (~ MCF5XXX_QSPI_QWR_HALT);
            break;
        case IO_IOCTL_SPI_GET_MODE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else
            {
                if (qspi_ptr->QMR & MCF5XXX_QSPI_QMR_CPOL)
                {
                    if (qspi_ptr->QMR & MCF5XXX_QSPI_QMR_CPHA)
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE3;
                    }
                    else
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE2;
                    }
                }
                else
                {
                    if (qspi_ptr->QMR & MCF5XXX_QSPI_QMR_CPHA)
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE1;
                    }
                    else
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE0;
                    }
                }
            }
            break;
        case IO_IOCTL_SPI_SET_MODE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else
            {       
                if (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE)
                {
                    result = IO_ERROR_DEVICE_BUSY;
                }
                else
                {
                    /* Set up SPI clock polarity and phase */
                    switch (*param_ptr)
                    {
                        case (SPI_CLK_POL_PHA_MODE0):
                            /* Inactive state of SPI_CLK = logic 0 */
                            qspi_ptr->QMR &= (~ MCF5XXX_QSPI_QMR_CPOL);
                            /* SPI_CLK transitions middle of bit timing */
                            qspi_ptr->QMR &= (~ MCF5XXX_QSPI_QMR_CPHA);
                            break;
                        case (SPI_CLK_POL_PHA_MODE1):
                            /* Inactive state of SPI_CLK = logic 0 */
                            qspi_ptr->QMR &= (~ MCF5XXX_QSPI_QMR_CPOL);
                            /* SPI_CLK transitions begining of bit timing */
                            qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_CPHA;
                            break;
                        case (SPI_CLK_POL_PHA_MODE2):
                            /* Inactive state of SPI_CLK = logic 1 */
                            qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_CPOL;
                            /* SPI_CLK transitions middle of bit timing */
                            qspi_ptr->QMR &= (~ MCF5XXX_QSPI_QMR_CPHA);
                            break;
                        case (SPI_CLK_POL_PHA_MODE3):
                            /* Inactive state of SPI_CLK = logic 1 */
                            qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_CPOL;
                            /* SPI_CLK transitions begining of bit timing */
                            qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_CPHA;
                            break;
                        default:
                            return SPI_ERROR_MODE_INVALID;       
                    }
                }
            }
            break;
        case IO_IOCTL_SPI_GET_TRANSFER_MODE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else
            {
                *param_ptr = SPI_DEVICE_MASTER_MODE;
            }
            break;
        case IO_IOCTL_SPI_SET_TRANSFER_MODE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else
            {
                if (*param_ptr == SPI_DEVICE_MASTER_MODE)
                {
                    qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_MSTR;
                }
                else
                {
                    result = SPI_ERROR_TRANSFER_MODE_INVALID;
                }
            }
            break;
        case IO_IOCTL_SPI_GET_ENDIAN:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            *param_ptr = SPI_DEVICE_BIG_ENDIAN; 
            break;
        case IO_IOCTL_SPI_SET_ENDIAN:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else if (*param_ptr != SPI_DEVICE_BIG_ENDIAN)
            {
                result = SPI_ERROR_ENDIAN_INVALID;
            }
            break;
        case IO_IOCTL_SPI_GET_STATS:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                *((SPI_STATISTICS_STRUCT_PTR)param_ptr) = io_info_ptr->STATS;
            }
            break;
        case IO_IOCTL_SPI_CLEAR_STATS:
            io_info_ptr->STATS.INTERRUPTS   = 0;
            io_info_ptr->STATS.RX_PACKETS   = 0;
            io_info_ptr->STATS.RX_OVERFLOWS = 0;
            io_info_ptr->STATS.TX_PACKETS   = 0;
            io_info_ptr->STATS.TX_ABORTS    = 0;
            io_info_ptr->STATS.TX_UNDERFLOWS= 0;
            break;
        case IO_IOCTL_FLUSH_OUTPUT:
        case IO_IOCTL_SPI_FLUSH_DEASSERT_CS:
            while ((0 != io_info_ptr->RECEIVING) || (0 != io_info_ptr->ONTHEWAY) || (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE)) 
               {};  /* Waiting for completion */
            if ((0 == (flags & SPI_FLAG_NO_DEASSERT_ON_FLUSH)) || (IO_IOCTL_SPI_FLUSH_DEASSERT_CS == cmd))
            {
                /* Deassert all chip selects */
                for (num = 0; num < MCF5XXX_QSPI_CS_COUNT; num++)
                {
                    if ((NULL != io_info_ptr->CS_CALLBACK[num]) && (0 != (io_info_ptr->CS_ACTIVE & (1 << num))))
                    {
                        io_info_ptr->CS_CALLBACK[num] (1 << num, 1, io_info_ptr->CS_USERDATA[num]);
                    }                
                }
                io_info_ptr->CS_ACTIVE = 0;
                qspi_ptr->QWR |= MCF5XXX_QSPI_QWR_CSIV;
            }
            break;
        case IO_IOCTL_SPI_GET_FRAMESIZE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                *param_ptr = MCF5XXX_QSPI_QMR_BITS_GET(qspi_ptr->QMR);
                if (0 == *param_ptr) *param_ptr = 16;
            }
            break;
        case IO_IOCTL_SPI_SET_FRAMESIZE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                if (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE)
                {
                    result = IO_ERROR_DEVICE_BUSY;
                }
                else
                {
                    qspi_ptr->QMR &= (~ (MCF5XXX_QSPI_QMR_BITS_SET(0x0F)));
                    qspi_ptr->QMR |= MCF5XXX_QSPI_QMR_BITS_SET(*param_ptr);
                }
            }
            break;
        case IO_IOCTL_SPI_GET_CS:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                *param_ptr = io_info_ptr->CS;
            }
            break;
        case IO_IOCTL_SPI_SET_CS:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                io_info_ptr->CS = *param_ptr;
            }
            break;
        case IO_IOCTL_SPI_ENABLE_MODF:
            result = MQX_IO_OPERATION_NOT_AVAILABLE;
            break;
        case IO_IOCTL_SPI_DISABLE_MODF:
            break;
        case IO_IOCTL_SPI_SET_CS_CALLBACK:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                callbacks = (SPI_CS_CALLBACK_STRUCT_PTR)(param_ptr);
                for (num = 0; num < MCF5XXX_QSPI_CS_COUNT; num++)
                {
                    if (0 != (callbacks->MASK & (1 << num)))
                    {
                        io_info_ptr->CS_CALLBACK[num] = callbacks->CALLBACK;
                        io_info_ptr->CS_USERDATA[num] = callbacks->USERDATA;
                    }                
                }
            }
            break;
        case IO_IOCTL_SPI_READ_WRITE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                rw_ptr = (SPI_READ_WRITE_STRUCT_PTR)param_ptr;
                command = MCF5XXX_QSPI_QDR_CONT | MCF5XXX_QSPI_QDR_BITSE | MCF5XXX_QSPI_QDR_CS(~ io_info_ptr->CS) | MCF5XXX_QSPI_QDR_TX | MCF5XXX_QSPI_QDR_RX;
                size = rw_ptr->BUFFER_LENGTH;
                input = (uchar_ptr)rw_ptr->WRITE_BUFFER;
                output = (uchar_ptr)rw_ptr->READ_BUFFER;
                for (num = 0; size > 0; )
                {
                    val = _mcf5xxx_qspi_polled_tx_rx (io_info_ptr, input, output, size, command);
                    if (0 == val) break;
                    num += val;
                    input += val;
                    output += val;
                    size -= val;
                }
            }
            break;
        case IO_IOCTL_SPI_KEEP_QSPI_CS_ACTIVE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                if (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE)
                {
                    result = IO_ERROR_DEVICE_BUSY;
                }
                else
                {
                    io_info_ptr->CSIV_ACTIVE = ((*param_ptr) != 0);
                }
            }
            break;
        default:
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }
    return result;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_polled_tx_rx
* Returned Value   : byte received   
* Comments         : 
*   Actual transmit and receive function.
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_polled_tx_rx 
    (
        /* [IN] The address of the device registers */
        MCF5XXX_QSPI_INFO_STRUCT_PTR io_info_ptr,
        
        /* [IN] Input buffer */
        uint_8_ptr                   buffer_in,

        /* [OUT] Output buffer */
        uint_8_ptr                   buffer_out,

        /* [IN] Buffer length */
        uint_32                      size,

        /* [IN] Command */
        uint_16                      command
    )
{
    uint_16                          data;
    uint_32                          num, bytes;
    VMCF5XXX_QSPI_STRUCT_PTR         qspi_ptr = io_info_ptr->QSPI_PTR;
    uint_16                          tmp;

    /* Set transfer size */
    bytes = 1;
    if (MCF5XXX_QSPI_QMR_BITS_GET(qspi_ptr->QMR) != 8) bytes++;
    if (size > (16 << (bytes - 1))) size = (16 << (bytes - 1));
    if (bytes > size) return 0;

    /* Assert actual chip select */ 
    if (io_info_ptr->CS ^ io_info_ptr->CS_ACTIVE)
    {
        for (num = 0; num < MCF5XXX_QSPI_CS_COUNT; num++)
        {
            if ((0 != ((io_info_ptr->CS ^ io_info_ptr->CS_ACTIVE) & (1 << num))) && (NULL != io_info_ptr->CS_CALLBACK[num]))
            {
                io_info_ptr->CS_CALLBACK[num] (1 << num, (io_info_ptr->CS_ACTIVE >> num) & 1, io_info_ptr->CS_USERDATA[num]);
            }
        }
        io_info_ptr->CS_ACTIVE = io_info_ptr->CS;
    }

    /* Write commands */
    qspi_ptr->QAR = 0x0020;
    data = command & 0xFF00;
    for (num = 0; num < size; num += bytes)
    {
        qspi_ptr->QDR = data;
    }

    /* Write data */
    qspi_ptr->QAR = 0x0000;
    if (bytes > 1)
    {
        for (num = 0; num < size; num += bytes)
        {
            data = *buffer_in++;
            data = (data << 8) | *buffer_in++;
            qspi_ptr->QDR = data;
        }
        data = (size >> 1);
    }
    else
    {
        for (num = 0; num < size; num += bytes)
        {
            data = *buffer_in++;
            qspi_ptr->QDR = data;
        }
        data = size;
    }

    /* Setup queue */
    tmp = qspi_ptr->QWR & (~ (MCF5XXX_QSPI_QWR_NEWQP(0xF) | MCF5XXX_QSPI_QWR_ENDQP(0xF)));
    qspi_ptr->QWR = tmp | MCF5XXX_QSPI_QWR_NEWQP(0) | MCF5XXX_QSPI_QWR_ENDQP(data - 1);

    /* Initiate transmission */
    qspi_ptr->QDLYR |= MCF5XXX_QSPI_QDLYR_SPE;

    /* If keeping CS low is needed between transfers */
    if (io_info_ptr->CSIV_ACTIVE)
    {
        /* CS inactive low for tranfers longer than 16 frames */
        qspi_ptr->QWR &= (~ MCF5XXX_QSPI_QWR_CSIV);
    }

    /* Wait transmission end */
    while (! (qspi_ptr->QIR & MCF5XXX_QSPI_QIR_SPIF)) 
        { };
    qspi_ptr->QIR |= MCF5XXX_QSPI_QIR_SPIF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_WCEF;

    if (command & MCF5XXX_QSPI_QDR_TX)
    {
        io_info_ptr->STATS.TX_PACKETS += data;
    }
        
    if (command & MCF5XXX_QSPI_QDR_RX)
    {
        /* Read data */
        io_info_ptr->STATS.RX_PACKETS += data;
        qspi_ptr->QAR = 0x0010;
        if (bytes > 1)
        {
            for (num = 0; num < size; num += bytes)
            {
                data = qspi_ptr->QDR;
                *buffer_out++ = (uint_8)(data >> 8);
                *buffer_out++ = (uint_8)data;
            }
        }
        else
        {
            for (num = 0; num < size; num += bytes)
            {
                data = qspi_ptr->QDR;
                *buffer_out++ = (uint_8)data;
            }
        }
    }

    return num;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_polled_rx
* Returned Value   : Returns the number of bytes received
* Comments         : 
*   Reads the data into provided array.
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_polled_rx
    (
        /* [IN] The address of the device specific information */
        IO_SPI_POLLED_DEVICE_STRUCT_PTR io_dev_ptr,
        
        /* [IN] The array the characters are written to */
        uchar_ptr                       buffer,
        
        /* [IN] Number of transfers to receive */
        uint_32                         size
    )
{
    MCF5XXX_QSPI_INFO_STRUCT_PTR        io_info_ptr;
        uint_16                             command;
    uint_32                             num, tmp;
    
    io_info_ptr  = io_dev_ptr->DEV_INFO_PTR;

    command = MCF5XXX_QSPI_QDR_CONT | MCF5XXX_QSPI_QDR_BITSE | MCF5XXX_QSPI_QDR_CS(~ io_info_ptr->CS) | MCF5XXX_QSPI_QDR_RX;
    if (io_dev_ptr->FLAGS & SPI_FLAG_FULL_DUPLEX)
    {
        command |= MCF5XXX_QSPI_QDR_TX;
    }
    
    for (num = 0; size > 0; )
    {
        tmp = _mcf5xxx_qspi_polled_tx_rx (io_info_ptr, buffer, buffer, size, command);
        if (0 == tmp) break;
        num += tmp;
        buffer += tmp;
        size -= tmp;
    }
    return num;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52_qspi_polled_tx
* Returned Value   : return number of byte transmitted
* Comments         : 
*   Writes the provided data buffer and loops until transmission complete
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_polled_tx
    (
        /* [IN] The address of the device specific information */
        IO_SPI_POLLED_DEVICE_STRUCT_PTR io_dev_ptr,
        
        /* [IN] The array to store data */
        uchar_ptr                       buffer,
        
        /* [IN] Number of char's to transmit */
        uint_32                         size
    )
{
    MCF5XXX_QSPI_INFO_STRUCT_PTR        io_info_ptr;
    uint_16                             command;
    uint_32                             num, tmp;
    
    io_info_ptr  = io_dev_ptr->DEV_INFO_PTR;

    command = MCF5XXX_QSPI_QDR_CONT | MCF5XXX_QSPI_QDR_BITSE | MCF5XXX_QSPI_QDR_CS(~ io_info_ptr->CS) | MCF5XXX_QSPI_QDR_TX;

    for (num = 0; size > 0; )
    {
        tmp = _mcf5xxx_qspi_polled_tx_rx (io_info_ptr, buffer, buffer, size, command);
        if (0 == tmp) break;
        num += tmp;
        buffer += tmp;
        size -= tmp;
    }
    return num;
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_read.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_read.c$
* $Version : 3.8.10.0$
* $Date    : Jun-27-2012$
*
* Comments:
*
*   This file contains the file specific interface functions
*   of the MFS.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_next_data_sector
* Returned Value   :
* Comments  :  
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_next_data_sector(
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    MFS_HANDLE_PTR          handle,
    uint_32_ptr             sector_index_ptr,
    uint_32_ptr             sector_number_ptr
    )
{
    _mfs_error  error = MFS_NO_ERROR;
    uint_32     next_cluster;

    if ( handle->CURRENT_CLUSTER != CLUSTER_EOF )
    {
        (*sector_index_ptr)++;
        if ( *sector_index_ptr >= drive_ptr->BPB.SECTORS_PER_CLUSTER )
        {
            // New cluster
            error = MFS_get_cluster_from_fat(drive_ptr, handle->CURRENT_CLUSTER, &next_cluster);
            if ( error == MFS_NO_ERROR )
            {
                handle->PREVIOUS_CLUSTER = handle->CURRENT_CLUSTER;
                handle->CURRENT_CLUSTER = next_cluster;
                *sector_index_ptr = 0;

                if ( next_cluster == CLUSTER_EOF )
                {
                    error = MFS_EOF;
                }
            }
        }

        if ( error == MFS_NO_ERROR )
        {
            *sector_number_ptr = CLUSTER_TO_SECTOR(handle->CURRENT_CLUSTER) + *sector_index_ptr;
        }
    }
    else
    {
        error = MFS_EOF;
    }
    return error;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Read
* Returned Value   : number of bytes read
* Comments  :   Read a specific number of bytes from an open file.
*
*END*---------------------------------------------------------------------*/


uint_32  MFS_Read
    (
    MQX_FILE_PTR            fd_ptr,         /*[IN] handle to the open file */
    uint_32                 num_bytes,      /*[IN] number of bytes to be read */
    char_ptr                buffer_address, /*[IN/OUT] bytes are read into this buffer */
    _mfs_error_ptr          error_ptr       /*[IN/OUT] error code is written to this address */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_HANDLE_PTR          handle;
    uint_32                 location;
    uint_32                 bytes_read;
    uint_32                 bytes_left_in_file;
    uint_32                 copy_size;
    uint_32                 cluster_offset;
    uint_32                 sector_number, sector_index;
    uint_32                 sector_offset;
    uint_32                 whole_sectors;
    uint_32                 cont_sectors;
    uint_32                 proc_sectors;
    _mfs_error              error, temp_error;
    boolean                 eof_reached;
    uint_32                 file_size;

    if ( num_bytes == 0 )
    {
        MFS_set_error_and_return(error_ptr,MFS_NO_ERROR,0);
    }

    if ( buffer_address == NULL )
    {
        MFS_set_error_and_return(error_ptr,MFS_INVALID_PARAMETER,0);
    }

    error = MFS_lock_handle( fd_ptr, &drive_ptr, &handle );
    if ( error != MFS_NO_ERROR )
    {
        MFS_set_error_and_return(error_ptr,error,0);
    }

    if ( handle->ACCESS != MFS_ACCESS_READ_ONLY &&
        handle->ACCESS != MFS_ACCESS_READ_WRITE )
    {
        MFS_unlock(drive_ptr,FALSE);
        MFS_set_error_and_return(error_ptr,MFS_ACCESS_DENIED,0);
    }


    if ( handle->CURRENT_CLUSTER == 0 )
    {
        handle->PREVIOUS_CLUSTER = 0;
        handle->CURRENT_CLUSTER = clustoh(handle->DIR_ENTRY.HFIRST_CLUSTER, handle->DIR_ENTRY.LFIRST_CLUSTER);
    }
    else if ( handle->CURRENT_CLUSTER == CLUSTER_EOF )
    {
        MFS_unlock(drive_ptr,FALSE);
        MFS_set_error_and_return(error_ptr,MFS_EOF,0);
    }


    bytes_read = 0;
    eof_reached = FALSE;
    location = fd_ptr->LOCATION;

    /*
    ** Can't read past file size
    */
    file_size = dtohl(handle->DIR_ENTRY.FILE_SIZE);
    if ( location > file_size )
    {
        location = file_size;
    }
    bytes_left_in_file = file_size - location;
    if ( num_bytes > bytes_left_in_file )
    {
        eof_reached = TRUE;
        num_bytes = bytes_left_in_file;
    }

    if ( bytes_left_in_file )
    {
        /*   
        ** Read the number of bytes from the current file   
        ** position to the end of the current cluster   
        */   
        cluster_offset = OFFSET_WITHIN_CLUSTER(location);
        sector_index = CLUSTER_OFFSET_TO_SECTOR(cluster_offset);
        sector_number = CLUSTER_TO_SECTOR(handle->CURRENT_CLUSTER) + sector_index;
        sector_offset = OFFSET_WITHIN_SECTOR(location);

        /* Read partial sector if sector_offet is non-zero */
        if (sector_offset != 0)
        {
            error = MFS_Read_data_sector(drive_ptr, handle, sector_number, TRUE);
            if ( error == MFS_NO_ERROR )
            {
                /* The requested lenght of data may span the sector to it's end  */
                copy_size = min(num_bytes, drive_ptr->BPB.SECTOR_SIZE-sector_offset);

                _mem_copy(&drive_ptr->DATA_SECTOR_PTR[sector_offset], buffer_address, copy_size);
                bytes_read=copy_size;

                /*
                ** Check to see if we need to advance to the next sector, which has
                ** the side effect of increasing the cluster number if required.
                */
                if ( (sector_offset+bytes_read) >= drive_ptr->BPB.SECTOR_SIZE )
                {
                    temp_error = MFS_next_data_sector(drive_ptr, handle, &sector_index, &sector_number);
                    /* Only an error if we are not done reading */
                    if ( bytes_read<num_bytes )
                    {
                        error = temp_error;
                    }
                }
            }
        }

        whole_sectors = (num_bytes - bytes_read) >> drive_ptr->SECTOR_POWER;
        while ((whole_sectors > 0) && (error == MFS_NO_ERROR))
        {
            cont_sectors = drive_ptr->BPB.SECTORS_PER_CLUSTER - sector_index;
            if (cont_sectors > whole_sectors)
                cont_sectors = whole_sectors;

            error = MFS_Read_device_sectors(drive_ptr, sector_number, cont_sectors, MFSCFG_MAX_READ_RETRIES, buffer_address+bytes_read, &proc_sectors);

            if ( proc_sectors > 0 )
            {
                bytes_read += proc_sectors * drive_ptr->BPB.SECTOR_SIZE;
                whole_sectors -= proc_sectors;
                sector_index += proc_sectors - 1;
                temp_error = MFS_next_data_sector(drive_ptr, handle, &sector_index, &sector_number);
                /* Only an error if we are not done reading */
                if ( (error==MFS_NO_ERROR) && (bytes_read<num_bytes) )
                {
                    error = temp_error;
                }
            }
        }
           
        if ( (bytes_read < num_bytes) && (error == MFS_NO_ERROR) )
        {
            error = MFS_Read_data_sector(drive_ptr, handle, sector_number, TRUE);
            if ( error == MQX_OK )
            {
                _mem_copy(&drive_ptr->DATA_SECTOR_PTR[0], buffer_address+bytes_read, num_bytes-bytes_read);
                bytes_read = num_bytes;
            }
        }

        fd_ptr->LOCATION = location + bytes_read;
        ((MFS_HANDLE_PTR)fd_ptr->DEV_DATA_PTR)->SAVED_POSITION = fd_ptr->LOCATION;
    }

    error = MFS_unlock(drive_ptr, FALSE);

    if ((error == MFS_NO_ERROR) && eof_reached)
    {
        error = MFS_EOF;
    }

    MFS_set_error_and_return(error_ptr,error,bytes_read);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_vpr.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_vpr.c$
* $Version : 3.8.5.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the functions for vprintf, vfprintf and vsprintf.
*   These functions are equivalent to the corresponding printf functions,
*   except that the variable argument list is replaced by one argument,
*   which has been initialized by the va_start macro.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief This function is equivalent to the corresponding printf function, except 
 * that the variable argument list is replaced by one argument, which has been 
 * initialized by the va_start macro.
 * 
 * \param[in] fmt_ptr The format string.
 * \param[in] arg     The arguments.
 * 
 * \return Number of characters
 * \return IO_EOF (End Of File found.)   
 */ 
_mqx_int _io_vprintf
   (
      const char _PTR_ fmt_ptr, 
      va_list          arg
   )
{ /* Body */
   _mqx_int result;
   
   result = _io_doprint(stdout, _io_fputc, -1, (char _PTR_)fmt_ptr, arg);

   return result;

} /* Endbody */

/*!
 * \brief This function is equivalent to the corresponding printf function, except 
 * that the variable argument list is replaced by one argument, which has been 
 * initialized by the va_start macro.
 * 
 * \param[in] file_ptr The stream to print upon.
 * \param[in] fmt_ptr  The format string to use for printing.
 * \param[in] arg      The argument list to print.
 * 
 * \return Number of characters
 * \return IO_EOF (End Of File found.)   
 */ 
_mqx_int _io_vfprintf
   (
      MQX_FILE_PTR     file_ptr,
      const char _PTR_ fmt_ptr,
      va_list          arg
   )
{ /* Body */
   _mqx_int result;
   
   result = 0;
   if ( file_ptr ) {
      result = _io_doprint(file_ptr, _io_fputc, -1, (char _PTR_)fmt_ptr, arg);
   } /* Endif */
   return result;

} /* Endbody */

/*!
 * \brief This function is quivalent to the corresponding printf function, except 
 * that the variable argument list is replaced by one argument, which has been 
 * initialized by the va_start macro.
 * 
 * \param[in] str_ptr The string to print into.
 * \param[in] fmt_ptr The format string.
 * \param[in] arg     The arguments.
 * 
 * \return Number of characters
 * \return IO_EOF (End Of File found.)   
 */ 
_mqx_int _io_vsprintf
   ( 
      char        _PTR_ str_ptr,
      const char  _PTR_ fmt_ptr,
      va_list           arg
   )
{ /* Body */
   _mqx_int result;
   
   result = _io_doprint((MQX_FILE_PTR)((pointer)&str_ptr), _io_sputc, -1, (char _PTR_)fmt_ptr, arg);
   *str_ptr = '\0';
   return result;

} /* Endbody */

/*!
 * \brief This function is equivalent to the corresponding printf function, except 
 * that the variable argument list is replaced by one argument, which has been 
 * initialized by the va_start macro.
 * 
 * \param[in] str_ptr The string to print into.
 * \param[in] max_count The maximal size of string.
 * \param[in] fmt_ptr   The format specifier.
 * \param[in] arg       The arguments.
 * 
 * \return Number of characters
 * \return IO_EOF (End Of File found.)  
 */ 
_mqx_int _io_vsnprintf
   (
      char          _PTR_ str_ptr,
      _mqx_int            max_count,
      const char    _PTR_ fmt_ptr,
      va_list             arg
   )
{
    _mqx_int result;

    result = _io_doprint((MQX_FILE_PTR)((pointer)&str_ptr), _io_sputc, max_count, (char _PTR_)fmt_ptr, arg);
    
    if (0 != max_count)
    {
        *str_ptr = '\0';
    }
    
    return result;

}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_parse.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_parse.c$
* $Version : 3.8.16.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains functions to parse and manipulate filenames.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_strupr
* Returned Value   :  void
* Comments  :
*      Take a string and convert it to uppercase
*END*---------------------------------------------------------------------*/

void MFS_strupr
    (
    char_ptr string /*[IN]  the string to be converted.*/
    )
{
    while ( *string != '\0' )
    {
        if ( *string >= 'a' &&  *string <= 'z' )
        {
            *string -= 32;
        }
        string++;
    }   
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Parse_pathname
* Returned Value   :  error code
* Comments  :
*      Take a pathname and convert it into its directory name and
*      filename components.
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Parse_pathname
    (
    char_ptr        dirname_ptr,    /*[IN/OUT] pointer to buffer where directory is to be written */
    char_ptr        filename_ptr,   /*[IN/OUT] pointer to buffer where filename is to be written */
    char_ptr        pathname_ptr    /*[IN] pathname include '\', not including drive specification */
    )
{
    _mfs_error error_code;
    char_ptr   src, p, temp;

    if ( pathname_ptr )
    {
        error_code = MFS_alloc_path(&temp);
        if ( error_code!=MFS_NO_ERROR )
        {
            return( error_code );
        }

        src           = pathname_ptr;
        *filename_ptr = '\0';
        temp[0]       = '\0';
        error_code    = MFS_NO_ERROR;

        if ( *src == '\\' || *src == '/' )
        {
            *dirname_ptr++ = '\\';
            src++;
        }

        *dirname_ptr = '\0';
        p = dirname_ptr;

        while ( *src )
        {
            src = MFS_Parse_next_filename (src, temp);
            if ( src == NULL )
            {
                /*
                ** if the next filename was not a valid filename
                */
                error_code = MFS_PATH_NOT_FOUND;
                break;
            }
            else if ( *src )
            {
                if ( *dirname_ptr )
                {
                    /*
                    ** if this is not the first filename in the path,
                    */
                    strcat (dirname_ptr, "\\");
                }
                p = p + strlen(p);
                strcat (dirname_ptr, temp);
                /*
                ** If any of the directory_names is invalid, return.
                */
                if ( MFS_lfn_dirname_valid(p) == FALSE )
                {
                    src = NULL;
                    error_code = MFS_PATH_NOT_FOUND;
                    break;
                }
            }
        }  

        /*
        ** last read word shall be a filename
        */
        if ( src )
        {
            strcpy(filename_ptr, temp);
        }
        MFS_free_path(temp);      
    }
    else
    {
        error_code = MFS_INVALID_PARAMETER;
    }  

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Wildcard_match
* Returned Value   : boolean ... true if the filename matches the wildcard
* Comments  :   Checks if a filename matches a given wildcard. 
*               (8.3 filenames only)
*
*END*---------------------------------------------------------------------*/

boolean MFS_Wildcard_match
    (
    char_ptr              wildcard_ptr, /*[IN] the wildcard (expanded to 11 characters, no dot) */
    char_ptr              filename_ptr  /*[IN] the filename (expanded to 11 characters, no dot) */
    )
{
    uint_16        k;
    register char  c;
    boolean        found;

    found = TRUE;

    for ( k = 0; k < 11; k++ )
    {
        c = *wildcard_ptr;
        if ( (c != *filename_ptr) && (c != '?') )
        {
            found = FALSE;
            break;
        }
        wildcard_ptr++;
        filename_ptr++;
    }  

    return(found);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Expand_wildcard
* Returned Value   : void
* Comments  :   Expands a wildcard (AB*.WK?) to a 11 char string dotless,
*         and NOT '\0' TERMINATED.
*
*END*---------------------------------------------------------------------*/

void MFS_Expand_wildcard
    (
    char_ptr     wildcard_ptr,         /*[IN] the wildcard (dos filename, no spaces 1..12 chars) */
    char_ptr     expanded_filename_ptr /*[IN] the filename (expanded to 11 characters, no dot) */
    )
{
    uint_16     k;
    uchar       cw;

    for ( k = 0; k < 8; k++ )
    {
        cw = *wildcard_ptr;
        if ( cw == '*' )
        {
            *expanded_filename_ptr = '?';
        }
        else if ( (cw == '.') || (cw == '\0') )
        {
            *expanded_filename_ptr = ' ';
        }
        else
        {
            cw = CAPITALIZE(cw);
            *expanded_filename_ptr = cw;
            wildcard_ptr++;
        }  
        expanded_filename_ptr++;
    }  

    /*
    ** Skip everything else, up to the dot or end of wildcard.
    */
    while ( *wildcard_ptr && (*wildcard_ptr != '.') )
    {
        wildcard_ptr++;
    }  

    if ( *wildcard_ptr == '.' )
    {
        wildcard_ptr++;
    }

    for ( k = 0; k < 3; k++ )
    {
        cw = *wildcard_ptr;
        if ( cw == '*' )
        {
            *expanded_filename_ptr = '?';
        }
        else if ( (cw == '.') || (cw == '\0') )
        {
            *expanded_filename_ptr = ' ';
        }
        else
        {
            cw = CAPITALIZE(cw);
            *expanded_filename_ptr = cw;
            wildcard_ptr++;
        }  
        expanded_filename_ptr++;
    }  
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Expand_dotfile
* Returned Value   :  void
* Comments  :
*   Put a dot-format filename in non-dot format. Assumes a valid DOS
*   filename.
*   It maps non_dot_file[0] from 0xE5 to 0x05 if necessary.
*
*END*---------------------------------------------------------------------*/
void MFS_Expand_dotfile
    (
    char_ptr        dot_file,       /*[IN] pointer to the file's dot_name */
    char_ptr        non_dot_file    /*[IN] pointer to the file's non-dot_name  */
    )
{
    uint_16     k;
    uchar       c;
    char_ptr    save_non_dot_file;

    save_non_dot_file = non_dot_file;

    if ( *dot_file == '.' )
    {
        *non_dot_file++ = *dot_file++;
        for ( k = 0; k < 10; k++ )
        {
            c = *dot_file;
            if ( c )
            {
                *non_dot_file++ = CAPITALIZE(c);
                dot_file++;
            }
            else
            {
                *non_dot_file++ = ' ';
            }  
        }  
        return;                                     
    }

    for ( k = 0; k < 8; k++ )
    {
        if ( *dot_file && *dot_file != '.' )
        {
            c = *dot_file;
            *non_dot_file++ = CAPITALIZE(c);
            dot_file++;
        }
        else
        {
            *non_dot_file++ = ' ';
        }  
    }  

    if ( *dot_file == '.' )
    {
        dot_file++;
    }
    for ( k = 0; k < 3; k++ )
    {
        c = *dot_file;
        if ( c && c != '.' )
        {
            *non_dot_file++ = CAPITALIZE(c);
            dot_file++;
        }
        else
        {
            *non_dot_file++ = ' ';
        }  
    }  

    if ( *save_non_dot_file == (char) MFS_DEL_FILE )
    {
        *save_non_dot_file = 0x05;
    }

}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Compress_nondotfile
* Returned Value   :  void
* Comments  :
*   Put a non-dot-format filename in dot format. Assumes a valid DOS
*   filename.
*   It maps non_dot_file[0] from 0x05 to 0xE5 if necessary.
*
*END*---------------------------------------------------------------------*/

void MFS_Compress_nondotfile
    (
    char_ptr        nondot_file,    /*[IN] pointer to the file's non_dot_name */
    char_ptr        dot_file        /*[IN] pointer to the file's dot_name  */
    )
{
    uint_16  k;
    char_ptr s_ptr;
    char_ptr d_ptr;
    char_ptr saved_d_ptr = NULL;
    boolean  save = TRUE;

    s_ptr = nondot_file;
    d_ptr = dot_file;

    for ( k = 0; k < 8; k++ )
    {
        *d_ptr = *s_ptr;
        if ( *s_ptr == ' ' )
        {
            if ( save )
            {
                saved_d_ptr = d_ptr;
                save = FALSE;
            }
        }
        else
        {
            save = TRUE;
        }  
        d_ptr++; s_ptr++;
    }  

    if ( save )
    {
        *d_ptr = '.';
        d_ptr++;
    }
    else
    {
        *saved_d_ptr = '.';
        d_ptr = saved_d_ptr + 1;
        save  = TRUE;
    }  


    for ( k = 0; k < 3; k++ )
    {
        *d_ptr = *s_ptr;
        if ( *s_ptr == ' ' )
        {
            if ( save )
            {
                saved_d_ptr = d_ptr;
                save = FALSE;
            }
        }
        else
        {
            save = TRUE;
        }  
        d_ptr++; s_ptr++;
    }  

    if ( save )
    {
        *d_ptr = '\0';
    }
    else
    {
        *saved_d_ptr = '\0';
    }  
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Filename_valid
* Returned Value   :  boolean (TRUE if valid DOS filename.
* Comments  :
*        Checks for length, invalid characters.
*END*---------------------------------------------------------------------*/

boolean MFS_Filename_valid
    (
    char_ptr        filename   /*[IN] filename to validate */
    )
{
    char c;
    char *s;

    int name_len;
    int ext_len;
    int dot_found;

    if (filename == NULL)
    {
       return FALSE;
    }
    
    s = filename;    

    name_len = 0;
    ext_len = 0;
    dot_found = 0;    
    
    for (c = *s; c != '\0'; c = *(++s)) {

        if (c == '.')
        {
            if (dot_found)
            {
                /* dot may occur only once */
                return FALSE;
            }

            if (name_len == 0)
            {
                /* blank filename not allowed */
                return FALSE;
            }

            dot_found++;

            continue;
        }
    
        if ( c == ' ' || c == '\"' || c == '*' || c == '+' ||
             c == ',' || c == '/'  || c == ':' || c == ';' ||
             c == '<' || c == '='  || c == '>' || c == '?' ||
             c == '[' || c == '\\' || c == ']' || c == '|' )
        {
            return FALSE;
        }
        
        if (!dot_found)
        {
            if (++name_len > 8)
            {
                return FALSE; /* name too long */
            }
        }
        else
        {
            if (++ext_len > 3)
            {
                return FALSE; /* extension too long */
            }
        }
    }
    
    /* only non-blank filenames are valid */    
    return (name_len > 0);
}    


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Dirname_valid
* Returned Value   :  boolean - TRUE if valid DOS directory name.
* Comments  :
*        Allows . and ..
*END*---------------------------------------------------------------------*/

boolean MFS_Dirname_valid
    (
    char_ptr        filename    /*[IN] filename to validate */
    )
{

    if ( *filename != '.' )
    {
        return(MFS_Filename_valid(filename));
    }
    else
    {
        if ( (*(filename + 1) == '\0') ||
            ((*(filename+1) == '.') && !*(filename+2)) )
        {
            return(TRUE);
        }
    }  

    return(FALSE);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Attribute_match
* Returned Value   :  boolean (TRUE if the attributes match)
* Comments  :
*
*END*---------------------------------------------------------------------*/
boolean MFS_Attribute_match
    (
    uchar       dattr,  /*[IN]  the attribute of the existing file on disk */
    uchar       wattr   /*[IN]  the attribute we are trying to find out if it matches */
    )
{
    boolean   match;

    if ( wattr & MFS_ATTR_ANY )
    {
        match = TRUE;
    }
    else if ( wattr == MFS_ATTR_LFN )
    {
        if ( dattr == MFS_ATTR_LFN )
        {
            match = TRUE;
        }
        else
        {
            match = FALSE;
        }  
    }
    else if ( wattr == MFS_SEARCH_VOLUME )
    {
        if ( dattr == MFS_SEARCH_VOLUME )
        {
            match = TRUE;
        }
        else
        {
            match = FALSE;
        }  
    }
    else
    {
        if ( wattr & ATTR_EXCLUSIVE )
        {
            if ( dattr == (wattr & (~ATTR_EXCLUSIVE)) )
            {
                match = TRUE;
            }
            else
            {
                match = FALSE;
            }  
        }
        else
        {
            /* MFS_SEARCH_NORMAL returns all non-hidden, non-system files or directories */
            if (wattr == MFS_SEARCH_NORMAL)
            {
                if (dattr & (MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE))
                {
                    match = FALSE;
                }
                else
                {
                    match = TRUE;
                }
            }
            /* MFS_SEARCH_SUBDIR returns all non-hidden, non-system directories */
            else if (wattr == MFS_SEARCH_SUBDIR)
            {
                if ((dattr & (MFS_ATTR_DIR_NAME | MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE)) == MFS_ATTR_DIR_NAME)
                {
                    match = TRUE;
                }
                else
                {
                    match = FALSE;
                }
            }
            /* otherwise wattr must be subset of dattr */
            else
            {
                if ((dattr | (wattr & (MFS_ATTR_READ_ONLY | MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE | MFS_ATTR_DIR_NAME | MFS_ATTR_ARCHIVE))) == dattr)
                {
                    match = TRUE;
                }
                else
                {
                    match = FALSE;
                }
            }
        }  
    }  

    return(match);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Parse_next_filename
* Returned Value   :  char_ptr to where it left off (non / or \ char)
* Comments  :
*        Reads the first filename in source string, up to '\' ,'/' or '.'
*        If the filename we're reading is invalid, return NULL
*END*---------------------------------------------------------------------*/

char_ptr MFS_Parse_next_filename
    (
    char_ptr   src, /*[IN]  the pathanme */
    char_ptr   out  /*[IN/OUT]  the filename just read in */
    )
{
    uint_32     i;

    if ( out == NULL )
    {
        return(NULL);
    }

    i = 0;

    while ( *src && *src != '/' && *src != '\\' )
    {
        *out++ = *src++;
        i++;
        if ( i > FILENAME_SIZE )
        {
            return NULL;
        }
    }  

    *out = '\0';
    if ( *src == '\\' || *src == '/' )
    {
        src++;
    }

    return(src);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Is_dot_directory
* Returned Value   :  the number of dots in the filename
* Comments  :
*     It checks if the filename is on of '.' or '..' and returns 1 or 2
*     respectively. Otherwise, it returns 0
*
*END*---------------------------------------------------------------------*/

uint_16 MFS_Is_dot_directory
    (
    char_ptr    filename    /*[IN]  pointer to the filename to be checked.*/
    )
{
    if ( *filename++ == '.' )
    {
        if ( *filename )
        {
            if ( *filename++ == '.' )
            {
                if ( !*filename )
                {
                    return(2);
                }
            }
        }
        else
        {
            return(1);
        }  
    }

    return(0);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_strcmp
* Returned Value   :  TRUE if the two string are identical
* Comments  :
*     It stops at '\0' or at the given limit
*END*---------------------------------------------------------------------*/

boolean MFS_strcmp 
    (
    char_ptr    string1,    /* [IN] the first string to compare */
    char_ptr    string2,    /*[IN] the second string to compare */      
    uint_32     limit       /* [IN] the maximun number of chars to count */
    ) 
{
    while ( *string1 && *string2 && *string1 == *string2 && limit-- )
    {
        string1++;
        string2++;     
    }   

    if ( *string1 == *string2 )
    {
        return( TRUE );
    }
    else
    {
        return( FALSE );      
    }  

}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ipcfg6.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved                      
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcfg6.c$
* $Version : 3.8.2.0$
* $Date    : Jun-27-2012$
*
* Comments:
*
*   High level IP config functions and task.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <enet.h>
#include <rtcs.h>
#include <dns.h> 
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "ipcfg.h"
#include "ipcfg_prv.h"

#ifdef BSP_ENET_DEVICE_COUNT
#if  (BSP_ENET_DEVICE_COUNT > 0) 

/* Hidden global data. */
extern IPCFG_CONTEXT    ipcfg_data[IPCFG_DEVICE_COUNT];

/************************************************************************
* NAME: ipcfg6_get_addr_info_n
* RETURNS : RTCS_OK if successful. 
*           It returns FALSE if n-th address is not available.
* DESCRIPTION: Gets address information which corresponds to the n-th address.
*************************************************************************/
uint_32 ipcfg6_get_addr_info_n (uint_32 device, uint_32 n /*=>0*/, IPCFG6_GET_ADDR_DATA_PTR data /*out*/)
{
#if RTCSCFG_ENABLE_IP6

    uint_32 result = (uint_32)RTCS_ERROR;
    
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) 
        {
            IP6_IF_ADDR_INFO addr_info;
            
            /* Get address inormation.*/
            if(ip6_if_get_addr (ipcfg_data[device].ihandle, n, &addr_info) == TRUE)
            {
                data->ip_addr_type = addr_info.ip_addr_type;
                data->ip_addr_state = addr_info.ip_addr_state;
                _mem_copy(addr_info.ip_addr.s6_addr, data->ip_addr.s6_addr, sizeof(data->ip_addr));
                result = RTCS_OK;
            }
        }
    }
    return result;
    
#else

    return RTCSERR_IP_IS_DISABLED;    
    
#endif /* RTCSCFG_ENABLE_IP6 */
}

/************************************************************************
* NAME: ipcfg6_get_device_scope_id
* RETURNS : Scope id of device.
*************************************************************************/
uint_32 ipcfg6_get_device_scope_id (uint_32 device /* in */)
{
#if RTCSCFG_ENABLE_IP6

    uint_32 result = (uint_32)RTCS_ERROR;
    
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) 
        {
            IP_IF_PTR if_ptr = (IP_IF_PTR)(ipcfg_data[device].ihandle);
            
            /* Get scope_id inormation.*/

           return (if_ptr->IP6_IF.scope_id);
        }
    }
    return 0;
    
#else

    return 0;    
    
#endif /* RTCSCFG_ENABLE_IP6 */
}

/************************************************************************
* NAME: ipcfg6_get_addr_info
* RETURNS : TRUE if successful.
* DESCRIPTION: Gets address information which corresponds to the "addr".
*************************************************************************/
uint_32 ipcfg6_get_addr_info (uint_32 device,
                             in6_addr *addr /*in*/,  
                             IPCFG6_GET_ADDR_DATA_PTR data/*out*/)
{
#if RTCSCFG_ENABLE_IP6

    uint_32 result = (uint_32)RTCS_ERROR;
    IP6_IF_ADDR_INFO_PTR addr_info;
    
    addr_info = ip6_if_get_addr_info((IP_IF_PTR) ipcfg_data[device].ihandle, addr);
    
    if(addr_info)
    {
        data->ip_addr_type = addr_info->ip_addr_type;
        data->ip_addr_state = addr_info->ip_addr_state;
        _mem_copy(addr_info->ip_addr.s6_addr, data->ip_addr.s6_addr, sizeof(data->ip_addr));
        result = RTCS_OK;
    }
    
    return result;
    
#else

    return RTCSERR_IP_IS_DISABLED;    
    
#endif /* RTCSCFG_ENABLE_IP6 */    
}

/************************************************************************
* NAME: ipcfg6_unbind_addr
* RETURNS : ipcfg error code
* DESCRIPTION: Releases an IP address associated with given device.
*************************************************************************/
uint_32 ipcfg6_unbind_addr ( uint_32 device, IPCFG6_UNBIND_ADDR_DATA_PTR  ip_data)
{
#if RTCSCFG_ENABLE_IP6
 
    uint_32 result;

    if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;

    if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) 
        return RTCSERR_IPCFG_INIT;
    
    if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) 
        return RTCSERR_IPCFG_BUSY;
    
    /* Unbind.*/
    result = RTCS6_if_unbind_addr (ipcfg_data[device].ihandle, ip_data->ip_addr);

    if (result == IPCFG_OK)
    {
        ipcfg_data[device].desired_ip_data = ipcfg_data[device].actual_ip_data;
        ipcfg_data[device].desired_state = ipcfg_data[device].actual_state;
    }

    _lwsem_post (&(ipcfg_data[device].control_semaphore));

    return result; 
     
#else

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP6 */
    
}

/************************************************************************
* NAME: ipcfg6_bind_addr
* RETURNS : ipcfg error code
* DESCRIPTION: Tries to bind given ip for given device.
*************************************************************************/
uint_32 ipcfg6_bind_addr ( uint_32 device, IPCFG6_BIND_ADDR_DATA_PTR   ip_data)
{
#if RTCSCFG_ENABLE_IP6

    uint_32 result;

    if (device >= IPCFG_DEVICE_COUNT) 
        return RTCSERR_IPCFG_DEVICE_NUMBER;

    if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) 
        return RTCSERR_IPCFG_INIT;

    if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) 
        return RTCSERR_IPCFG_BUSY;
    
    if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;

    result = RTCSERR_IPCFG_BIND;
    
    /* Bind.*/
    if (RTCS6_if_bind_addr (ipcfg_data[device].ihandle, ip_data->ip_addr, ip_data->ip_addr_type) == RTCS_OK)
    {
        ipcfg_data[device].desired_state = IPCFG_STATE_STATIC_IP;
        ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
        result = IPCFG_OK;
    }

    _lwsem_post (&(ipcfg_data[device].request_semaphore));    
    

    _lwsem_post (&(ipcfg_data[device].control_semaphore));
    
    return result;
#else

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP6 */    
}


#endif /* (BSP_ENET_DEVICE_COUNT > 0) */
#endif /* BSP_ENET_DEVICE_COUNT */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/printer/usb_host_printer.h<|end_filename|>
#ifndef __print_host_printer_h__
#define __print_host_printer_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_printer.h$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains definitions for  USB printer class.
*   Reference Specification:
*   "USB Device Class Definition for Printing Devices" version 1.1
*   January 2000, from USB Implementers Forum.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_main.h"
#include "host_snd.h"
#include "host_rcv.h"
#include "host_ch9.h"

/* Printer Port-Status Bits */
#define  USB_PRINTER_PAPER_OUT     (0x20)   /* 0 = Not empty */
                                          /* 1 = Paper empty */
#define  USB_PRINTER_SELECTED      (0x10)   /* 0 = Not selected */
                                          /* 1 = Selected */
#define  USB_PRINTER_NO_ERROR      (0x08)   /* 0 = Error */
                                          /* 1 = No error!!! */

/* Bulk In/Out Endpoint-found tags */
#define  USB_PRINTER_IN_TAG   (0x01)
#define  USB_PRINTER_OUT_TAG  (0x02)
#define  USB_PRINTER_BI_TAG   (USB_PRINTER_IN_TAG | USB_PRINTER_OUT_TAG)

/* Error codes */
#define  USB_PRINTER_UNSUPPORTED_SUB_CLASS (0x80)
#define  USB_PRINTER_UNSUPPORTED_PROTOCOL  (0x81)
#define  USB_PRINTER_BAD_COMMAND           (0x82)

/* Class-specific Requests for Printers */
#define  USB_PRINTER_GET_DEVICE_ID        0
#define  USB_PRINTER_GET_PORT_STATUS      1
#define  USB_PRINTER_SOFT_RESET           2
/* Non-class Requests for Printers */
#define  USB_PRINTER_SEND_BULK            3
#define  USB_PRINTER_RECV_BULK            4

/* Class-specific interface info struct, useful for
**       an application to send/receive on in/out
**       pipes by name without internal details.
** NOTE: Since the class may have to handle several
**       printers attached simultaneously, it is
**       essential to have an array or list.
**       Here we choose a NULL-terminated list. */
typedef struct printer_interface {
   struct printer_interface _PTR_   next;    /* next printer */
   struct printer_interface _PTR_   anchor;  /* list start */
   _usb_device_instance_handle      dev_handle;
   _usb_interface_descriptor_handle intf_handle;
   _usb_host_handle                 host_handle;
   uint_32                          key_code;
   _usb_pipe_handle                 control_pipe;
   _usb_pipe_handle                 bulk_in_pipe;
   _usb_pipe_handle                 bulk_out_pipe;
} PRINTER_INTERFACE_STRUCT, _PTR_ PRINTER_INTERFACE_STRUCT_PTR;

/* Alphabetical list of Function Prototypes */

#ifdef __cplusplus
extern "C" {
#endif

USB_STATUS usb_printer_get_device_ID(CLASS_CALL_STRUCT_PTR,
   tr_callback, pointer, uint_32, uchar_ptr);
USB_STATUS usb_printer_get_port_status(CLASS_CALL_STRUCT_PTR,
   tr_callback, pointer, uint_8_ptr);
void usb_printer_init(PIPE_BUNDLE_STRUCT_PTR, CLASS_CALL_STRUCT_PTR);
USB_STATUS usb_printer_recv_data(CLASS_CALL_STRUCT_PTR,
   tr_callback, pointer, uint_32, uchar_ptr);
USB_STATUS usb_printer_send_data(CLASS_CALL_STRUCT_PTR,
   tr_callback, pointer, uint_32, uchar_ptr);
USB_STATUS usb_printer_soft_reset(CLASS_CALL_STRUCT_PTR,
   tr_callback, pointer);

#ifdef __cplusplus
}
#endif


#endif


<|start_filename|>Firmware/Inverter_bootloader/APP/USB_timer.c<|end_filename|>
#include <string.h>
#include "app_cfg.h"
#include "USB_timer.h"

#define APP_TIMER_PERIOD  100

/* Array of Timer Objects */
TIMER_OBJECT g_TimerObjectArray[MAX_TIMER_OBJECTS];
void         Init_periodic_app_timer(void);
INT8U        Add_periodic_callback(PTIMER_OBJECT pTimerObject);
INT8U        Remove_periodic_callback(INT8U index);
void         Timer_ISR(void);


//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void Init_periodic_app_timer()
{
  (void)memset(g_TimerObjectArray, (int)NULL, sizeof(g_TimerObjectArray));
  PIT0_init(APP_TIMER_PERIOD);
}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
INT8U Add_periodic_callback(PTIMER_OBJECT pTimerObject)
{
  INT8U index;
  if ( pTimerObject == NULL ) return (INT8U)ERR_INVALID_PARAM;
  if ( pTimerObject->msCount == (unsigned int)INVALID_TIME_COUNT ) return (INT8U)ERR_INVALID_PARAM;

  for (index = 0; index < MAX_TIMER_OBJECTS; index++)
  {
    /* Disable Timer Interrupts */
    PIT0_int_disable();

    if ( g_TimerObjectArray[index].pfnTimerCallback == NULL )
    {
      (void)memcpy(&g_TimerObjectArray[index], pTimerObject, sizeof(TIMER_OBJECT));
      /* Enable Timer Interrupts */
      PIT0_int_enable();
      break;
    }
    /* Enable Timer Interrupts */
    PIT0_int_enable();
  }
  if ( index == MAX_TIMER_OBJECTS ) return (INT8U)ERR_TIMER_QUEUE_FULL;
  return index;
}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
INT8U Remove_periodic_callback(INT8U index)
{
  if ( index >= MAX_TIMER_OBJECTS ) return (INT8U)ERR_INVALID_PARAM;
  /* Disable Timer Interrupts */
  PIT0_int_disable();
  (void)memset(&g_TimerObjectArray[index], (int)NULL, sizeof(TIMER_OBJECT));
  /* Enable Timer Interrupts */
  PIT0_int_enable();
  return (INT8U)ERR_SUCCESS;
}


//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void PIT0_IRQHandler(void)
{
  PIT_MemMapPtr PIT = PIT_BASE_PTR;
  INT8U index;

  if ( PIT->CHANNEL[0].TFLG & BIT(0) )
  {
    
    PIT->CHANNEL[0].TFLG = BIT(0); // Сбросит флаг прерывания 

    PIT0_int_disable();

    /* Call Pending Timer CallBacks */
    for (index = 0; index < MAX_TIMER_OBJECTS; index++)
    {
      PTIMER_OBJECT ptemp = &g_TimerObjectArray[index];
      if ( ptemp->pfnTimerCallback == NULL )
      {
        continue;
      }
      ptemp->msCount--;
      if ( ptemp->msCount < 0 )
      {
        PFNTIMER_CALLBACK pfnTimerCallback = ptemp->pfnTimerCallback;
#ifdef TIMER_CALLBACK_ARG
        void *parg = ptemp->arg;
#endif
        (void)Remove_periodic_callback(index);
#ifdef TIMER_CALLBACK_ARG
        pfnTimerCallback(parg);
#else
        pfnTimerCallback();
#endif
      }
    }
  }
  PIT0_int_enable();
}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hwtimer/hwtimer_pit.c<|end_filename|>
/*HEADER********************************************************************
 *
 * Copyright (c) 2013 Freescale Semiconductor;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: hwtimer_pit.c$
 * $Version : 4.0.1$
 * $Date : Jan-18-2013$
 *
 * Comments:
 *
 *   This file contains functions of the low level PIT module for hwtimer
 *   component.
 *
 *END************************************************************************/

#include "hwtimer.h"
#include "hwtimer_pit.h"
#include <bsp.h>

/*!
 * \cond DOXYGEN_PRIVATE
 * Macro allows the timers to be stopped when the device enters the Debug mode.
 */
#ifndef BSPCFG_HWTIMER_PIT_FREEZE
/* Timers continue to run in Debug mode */
#define  BSPCFG_HWTIMER_PIT_FREEZE 0
#endif    

/*!
 * \cond DOXYGEN_PRIVATE
 * Macro return number of pitmodule from pit_id
 */
#define GET_PIT_NUMBER_FROM_PITID(pit_id)   ((pit_id >> 16) & 0x0000FFFF)
/*!
 * \cond DOXYGEN_PRIVATE
 * Macro return pit channel from pit_id
 */
#define GET_PIT_CHANNEL_FROM_PITID(pit_id)  (pit_id & 0x0000FFFF)

extern void pit_io_init(uint_32);
extern uint_32 pit_get_vectors(uint_32, const _mqx_uint **);
extern uint_32 pit_get_hwtimers_array(HWTIMER_PTR **);


static void hwtimer_pit_isr_shared(pointer);
static void hwtimer_pit_isr(pointer);
static _mqx_int hwtimer_pit_init(HWTIMER_PTR , uint_32, uint_32);
static _mqx_int hwtimer_pit_deinit(HWTIMER_PTR);
static _mqx_int hwtimer_pit_set_div(HWTIMER_PTR, uint_32);
static _mqx_int hwtimer_pit_start(HWTIMER_PTR);
static _mqx_int hwtimer_pit_stop(HWTIMER_PTR);
static _mqx_int hwtimer_pit_get_time(HWTIMER_PTR , HWTIMER_TIME_PTR);


const HWTIMER_DEVIF_STRUCT pit_devif =
{
    hwtimer_pit_init,
    hwtimer_pit_deinit,
    hwtimer_pit_set_div,
    hwtimer_pit_start,
    hwtimer_pit_stop,
    hwtimer_pit_get_time
};

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief Shared interrupt service routine.
 *
 * This ISR is used when more channels share one vector in vector table.
 * Checks whether callback_func is not NULL,
 * and unless callback is blocked by callback_blocked being non-zero it calls the callback function with callback_data as parameter,
 * otherwise callback_pending is set to non-zero value.
 * \param p[in]   Null pointer.
 *
 * \return void
 *
 * \see hwtimer_pit_deinit
 * \see hwtimer_pit_set_div
 * \see hwtimer_pit_start
 * \see hwtimer_pit_stop
 * \see hwtimer_pit_get_time
 * \see hwtimer_pit_isr
 */
static void hwtimer_pit_isr_shared(pointer p)
{
    HWTIMER_PTR * pit_hwtimers_array = NULL;
    uint_32 pit_hwtimers_array_size;
    uint_32 i;
    HWTIMER_PTR hwtimer;
    PIT_MemMapPtr pit_base;
    uint_32 pit_channel;

    pit_hwtimers_array_size = pit_get_hwtimers_array(&pit_hwtimers_array);

    for (i = 0; i < pit_hwtimers_array_size; i++)
    {
        hwtimer =  pit_hwtimers_array[i];
        /* If hwtimer exist*/
        if (NULL != hwtimer)
        {
            pit_base    = (PIT_MemMapPtr) hwtimer->ll_context[0];
            pit_channel =  GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);

            /* Check if interrupt is enabled for this channel. */
            if (!(PIT_TCTRL_TIE_MASK & PIT_TCTRL_REG(pit_base, pit_channel)))
            {
                continue;
            }

            /* If interrupt occur for this pit and channel*/
            if(PIT_TFLG_REG((PIT_MemMapPtr)pit_base, pit_channel) & PIT_TFLG_TIF_MASK)
            {
                /* Clear interrupt flag */
                PIT_TFLG_REG((PIT_MemMapPtr)pit_base, pit_channel) = PIT_TFLG_TIF_MASK;
                /* Errata for OM33Z: e2682: PIT: Does not generate a subsequent interrupt after clearing the interrupt flag */
                /* Workaround: The user must access any PIT register after clearing the interrupt flag in the ISR. */
                PIT_TFLG_REG(pit_base, pit_channel);

                /* Following part of function is typically the same for all low level hwtimer drivers */
                hwtimer->ticks++;

                if (NULL != hwtimer->callback_func)
                {
                    if (hwtimer->callback_blocked)
                    {
                        hwtimer->callback_pending = 1;
                    }
                    else
                    {
                        /* Run user function*/
                        hwtimer->callback_func(hwtimer->callback_data);
                    }
                }
            }
        }
    }
}
/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief Interrupt service routine.
 *
 * This ISR is used when every channel has its own vector in vector table.
 * Checks whether callback_func is not NULL,
 * and unless callback is blocked by callback_blocked being non-zero it calls the callback function with callback_data as parameter,
 * otherwise callback_pending is set to non-zero value.
 *
 * \param p[in]   Pointer to hwtimer struct.
 *
 * \return void
 *
 * \see hwtimer_pit_deinit
 * \see hwtimer_pit_set_div
 * \see hwtimer_pit_start
 * \see hwtimer_pit_stop
 * \see hwtimer_pit_get_time
 * \see hwtimer_pit_isr_shared
 */
static void hwtimer_pit_isr(pointer p)
{
    HWTIMER_PTR hwtimer     = (HWTIMER_PTR) p;
    PIT_MemMapPtr pit_base  = (PIT_MemMapPtr) hwtimer->ll_context[0];
    uint_32 pit_channel     = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);

    /* Check if interrupt is enabled for this channel. Cancel spurious interrupt */
    if (!(PIT_TCTRL_TIE_MASK & PIT_TCTRL_REG(pit_base, pit_channel)))
    {
        return;
    }

    /* Clear interrupt flag */
    PIT_TFLG_REG(pit_base, pit_channel) = PIT_TFLG_TIF_MASK;
    /* Errata for OM33Z: e2682: PIT: Does not generate a subsequent interrupt after clearing the interrupt flag */
    /* Workaround: The user must access any PIT register after clearing the interrupt flag in the ISR. */
    PIT_TFLG_REG(pit_base, pit_channel);

    /* Following part of function is typically the same for all low level hwtimer drivers */
    hwtimer->ticks++;

    if (NULL != hwtimer->callback_func)
    {
        if (hwtimer->callback_blocked)
        {
            hwtimer->callback_pending = 1;
        }
        else
        {
            /* Run user function*/
            hwtimer->callback_func(hwtimer->callback_data);
        }
    }
}


/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief This function initializes caller allocated structure according to given
 * numerical identifier of the timer.
 *
 * Called by hwtimer_init().
 * Initializes the HWTIMER structure.
 * Sets interrupt priority and registers ISR.
 *
 * \param hwtimer[in]   Returns initialized hwtimer structure handle.
 * \param pit_id[in]    Determines PIT modul and pit channel.
 * \param isr_prior[in] Interrupt priority for PIT
 *
 * \return MQX_OK                       Success.
 * \return MQX_INVALID_PARAMETER        When channel number does not exist in pit module.
 * \return MQX_INVALID_COMPONENT_HANDLE Doesnt have any interrupt vectors, or pit does not exist.
 * \return IO_ERROR                     When pit is used byt PE or when _int_install_isr faild.
 *
 * \see hwtimer_pit_deinit
 * \see hwtimer_pit_set_div
 * \see hwtimer_pit_start
 * \see hwtimer_pit_stop
 * \see hwtimer_pit_get_time
 * \see hwtimer_pit_isr
 * \see hwtimer_pit_isr_shared
 */
static _mqx_int hwtimer_pit_init(HWTIMER_PTR hwtimer, uint_32 pit_id, uint_32 isr_prior)
{
    HWTIMER_PTR * pit_hwtimers_array = NULL;
    uint_32 pit_hwtimers_array_size;
    PSP_INTERRUPT_TABLE_INDEX    vector;
    PIT_MemMapPtr pit_base;
    uint_32 pit_number;
    uint_32 pit_channel;
    uint_32 pit_channels_count;
    uint_32 pit_vectors_count;
    _mqx_uint i;
    const _mqx_uint *pit_vectors = NULL;
    PIT_MemMapPtr pit;
    /* Count of chanels is computed, because this information missing in generated iomap file */
    pit_channels_count = sizeof(pit->CHANNEL) / sizeof(pit->CHANNEL[0]);

    #if MQX_CHECK_ERRORS
    if (pit_channels_count <= pit_id)
    {
        return MQX_INVALID_PARAMETER;
    }
    #endif

    /* We need to store pit_id of timer in context struct */
    hwtimer->ll_context[0] = (uint_32)PIT_BASE_PTR;
    hwtimer->ll_context[1] = pit_id;

    pit_base    = (PIT_MemMapPtr) hwtimer->ll_context[0];
    pit_channel = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);
    pit_number  = GET_PIT_NUMBER_FROM_PITID(hwtimer->ll_context[1]);
    #if PE_LDD_VERSION
    if (PE_PeripheralUsed((uint_32)pit_base))
    {
        return IO_ERROR;
    }
    #endif
    /* Enable PIT Module Clock */
    pit_io_init(0);

    /* Enable PIT module */
    PIT_MCR_REG(pit_base) =  PIT_MCR_FRZ_MASK;
    
    #if BSPCFG_HWTIMER_PIT_FREEZE
    /* Allows the timers to be stopped when the device enters the Debug mode. */
    PIT_MCR_REG(pit_base) |= PIT_MCR_FRZ_MASK;
    #endif
    
    /* Disable timer and interrupt */
    PIT_TCTRL_REG(pit_base, pit_channel) = 0;
    /* Clear any pending interrupt */
    PIT_TFLG_REG(pit_base, pit_channel) = PIT_TFLG_TIF_MASK;

    /* Set isr for timer*/
    pit_vectors_count =  pit_get_vectors(pit_number, &pit_vectors);
    #if MQX_CHECK_ERRORS
    if ((NULL == pit_vectors) || (0 == pit_vectors_count))
    {
        return MQX_INVALID_COMPONENT_HANDLE;  //doesnt have any interrupt vectors, or pit does not exist
    }
    #endif
    if (pit_channels_count <= pit_vectors_count)
    {
        /* Every channel has own interrupt vector */
        vector = (PSP_INTERRUPT_TABLE_INDEX) (pit_vectors[pit_channel]);
        if (NULL == _int_install_isr(vector, (INT_ISR_FPTR) hwtimer_pit_isr, (pointer) hwtimer))
        {
            return IO_ERROR;
        }
        _bsp_int_init(vector, isr_prior, 0, TRUE);
    }
    else
    {
        pit_hwtimers_array_size = pit_get_hwtimers_array(&pit_hwtimers_array);
        #if MQX_CHECK_ERRORS
        if ((NULL == pit_hwtimers_array) || (0 == pit_hwtimers_array_size))
        {
            return MQX_INVALID_COMPONENT_HANDLE;
        }
        #endif
        /* Pit has shared interrupt vectors */
        pit_hwtimers_array[pit_channel] = hwtimer;
        for (i = 0; i < pit_vectors_count; i++)
        {
            vector = (PSP_INTERRUPT_TABLE_INDEX) (pit_vectors[i]);
            if (NULL == _int_install_isr(vector, (INT_ISR_FPTR) hwtimer_pit_isr_shared, NULL))
            {
                return IO_ERROR;
            }
            _bsp_int_init(vector, isr_prior, 0, TRUE);
        }
    }
    return MQX_OK;
}

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief Initialization of pit timer module
 *
 * Called by hwtimer_deinit.
 * Stops the timer and disables the peripheral.
 * Unregisters ISR.

 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 *
 * \return MQX_OK                       Success.
 * \return MQX_INVALID_COMPONENT_HANDLE When doesnt have any interrupt vectors, or pit does not exist.
 *
 * \see hwtimer_pit_init
 * \see hwtimer_pit_set_div
 * \see hwtimer_pit_start
 * \see hwtimer_pit_stop
 * \see hwtimer_pit_get_time
 * \see hwtimer_pit_isr
 * \see hwtimer_pit_isr_shared
 */
static _mqx_int hwtimer_pit_deinit(HWTIMER_PTR hwtimer)
{
    HWTIMER_PTR * pit_hwtimers_array = NULL;
    uint_32 pit_hwtimers_array_size;

    PSP_INTERRUPT_TABLE_INDEX    vector;
    uint_32 pit_channel = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);
    uint_32 pit_number  = GET_PIT_NUMBER_FROM_PITID(hwtimer->ll_context[1]);

    uint_32 pit_channels_count;
    uint_32 pit_vectors_count;
    _mqx_uint i;
    const _mqx_uint *pit_vectors = NULL;

    PIT_MemMapPtr pit;
    /* Count of chanels is computed, because this information missing in generated iomap file */
    pit_channels_count = sizeof(pit->CHANNEL) / sizeof(pit->CHANNEL[0]);

    pit_vectors_count =  pit_get_vectors(pit_number, &pit_vectors);
    #if MQX_CHECK_ERRORS
    if ((NULL == pit_vectors) || (0 == pit_vectors_count))
    {
        return MQX_INVALID_COMPONENT_HANDLE;  //doesnt have any interrupt vectors, or pit does not exist
    }
    #endif
    /* If number of pit channels is the same as number of vector */
    if (pit_channels_count <= pit_vectors_count)
    {
        /* Every channel has own interrupt vector */
        vector = (PSP_INTERRUPT_TABLE_INDEX) (pit_vectors[pit_channel]);
        /* Disable interrupt on vector */
        _bsp_int_disable(vector);
        /* Install default isr routine for our pit */
        _int_install_isr(vector, _int_get_default_isr(), NULL);
    }
    else
    {
        pit_hwtimers_array_size = pit_get_hwtimers_array(&pit_hwtimers_array);
        #if MQX_CHECK_ERRORS
        if ((NULL == pit_hwtimers_array) || (0 == pit_hwtimers_array_size))
        {
            return MQX_INVALID_COMPONENT_HANDLE;
        }
        #endif
        /* Pit has shared interrupt vectors. We need undregister interrupt only when all hwtimers are deinited(set to NULL) */
        pit_hwtimers_array[pit_channel] = NULL;
        /* Check if this is last hwtimer in pit_hwtimers_array */
        for (i = 0; i < pit_hwtimers_array_size; i++)
        {
            if (NULL != pit_hwtimers_array[i])
            {
                break;
            }
        }

        if (i == pit_hwtimers_array_size)
        {
            for (i = 0; i < pit_vectors_count; i++)
            {
                vector = (PSP_INTERRUPT_TABLE_INDEX) (pit_vectors[i]);
                /* Disable interrupt on vector */
                _bsp_int_disable(vector);
                /* Install default isr routine for our pit */
                _int_install_isr(vector, _int_get_default_isr(), NULL);
            }
        }
    }

    return MQX_OK;
}

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief Sets up timer with divider settings closest to the requested total divider factor.
 *
 * Called by hwtimer_set_freq() and hwtimer_set_period().
 * Fills in the divider (actual total divider) and modulo (sub-tick resolution) members of the HWTIMER structure.
 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 * \param divider[in] Value which divide input clock of pit timer module to obtain requested period of timer.
 *
 * \return MQX_OK                Success.
 * \return MQX_INVALID_PARAMETER Divider is equal to zero.
 *
 * \see hwtimer_pit_init
 * \see hwtimer_pit_deinit
 * \see hwtimer_pit_start
 * \see hwtimer_pit_stop
 * \see hwtimer_pit_get_time
 * \see hwtimer_pit_isr
 * \see hwtimer_pit_isr_shared
 */
static _mqx_int hwtimer_pit_set_div(HWTIMER_PTR hwtimer, uint_32 divider)
{
    PIT_MemMapPtr pit_base  = (PIT_MemMapPtr) hwtimer->ll_context[0];
    uint_32 pit_channel     = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);
    #if MQX_CHECK_ERRORS
    if (0 == divider)
    {
        return MQX_INVALID_PARAMETER;
    }
    #endif

    PIT_LDVAL_REG(pit_base, pit_channel)   = divider - 1;

    hwtimer->divider    = divider;
    hwtimer->modulo     = divider;

    return MQX_OK;
}


/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief Start pit timer module
 *
 * This function enables the timer and leaves it running, timer is
 * periodically generating interrupts.
 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 *
 * \return MQX_OK Success.
 *
 * \see hwtimer_pit_init
 * \see hwtimer_pit_deinit
 * \see hwtimer_pit_set_div
 * \see hwtimer_pit_stop
 * \see hwtimer_pit_get_time
 * \see hwtimer_pit_isr
 * \see hwtimer_pit_isr_shared
 */
static _mqx_int hwtimer_pit_start(HWTIMER_PTR hwtimer)
{
    PIT_MemMapPtr pit_base  = (PIT_MemMapPtr) hwtimer->ll_context[0];
    uint_32 pit_channel     = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);

    PIT_TCTRL_REG(pit_base, pit_channel) = 0;  // Stop timer to force reseting the counter
    PIT_TFLG_REG(pit_base, pit_channel)  = PIT_TFLG_TIF_MASK; // Clear flag
    PIT_TCTRL_REG(pit_base, pit_channel) = PIT_TCTRL_TEN_MASK | PIT_TCTRL_TIE_MASK; // Run timer and enable interrupts

    return MQX_OK;
}

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief Stop pit timer module
 *
 * Disable timer and interrupt
 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 *
 * \return MQX_OK Success.
 *
 * \see hwtimer_pit_init
 * \see hwtimer_pit_deinit
 * \see hwtimer_pit_set_div
 * \see hwtimer_pit_start
 * \see hwtimer_pit_get_time
 * \see hwtimer_pit_isr
 * \see hwtimer_pit_isr_shared
 */
static _mqx_int hwtimer_pit_stop(HWTIMER_PTR hwtimer)
{
    PIT_MemMapPtr pit_base  = (PIT_MemMapPtr) hwtimer->ll_context[0];
    uint_32 pit_channel     = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);

    /* Disable timer and interrupt */
    PIT_TCTRL_REG(pit_base, pit_channel) = 0;
    PIT_TFLG_REG(pit_base, pit_channel) = PIT_TFLG_TIF_MASK; // Clear interrupt flag
    /* Errata for OM33Z: e2682: PIT: Does not generate a subsequent interrupt after clearing the interrupt flag */
    /* Workaround: The user must access any PIT register after clearing the interrupt flag in the ISR. */
    PIT_TFLG_REG(pit_base, pit_channel);

    return MQX_OK;
}

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief Atomically captures current time into HWTIMER_TIME_STRUCT structure
 *
 * Corrects/normalizes the values if necessary (interrupt pending, etc.)
 *
 * \param hwtimer[in] Pointer to hwtimer structure.
 * \param time[out]   Pointer to time structure. This value is filled with current value of the timer.
 *
 * \return MQX_OK Success.
 *
 * \see hwtimer_pit_init
 * \see hwtimer_pit_deinit
 * \see hwtimer_pit_set_div
 * \see hwtimer_pit_start
 * \see hwtimer_pit_stop
 * \see hwtimer_pit_isr
 * \see hwtimer_pit_isr_shared
 */
static _mqx_int hwtimer_pit_get_time(HWTIMER_PTR hwtimer, HWTIMER_TIME_PTR time)
{
    PIT_MemMapPtr pit_base  = (PIT_MemMapPtr) hwtimer->ll_context[0];
    uint_32 pit_channel     = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);
    uint_32 tif;

    /* Disable interrupt from timer*/
    PIT_TCTRL_REG(pit_base, pit_channel) &= ~PIT_TCTRL_TIE_MASK;
    time->TICKS = hwtimer->ticks;
    time->SUBTICKS = PIT_LDVAL_REG(pit_base, pit_channel) - PIT_CVAL_REG(pit_base, pit_channel);

    if(PIT_TFLG_REG(pit_base, pit_channel) & PIT_TFLG_TIF_MASK)
    {
        time->TICKS = hwtimer->ticks + 1;
        time->SUBTICKS = PIT_LDVAL_REG(pit_base, pit_channel) - PIT_CVAL_REG(pit_base, pit_channel);
    }
    /* Enable interrupt from timer*/
    PIT_TCTRL_REG(pit_base, pit_channel) |= PIT_TCTRL_TIE_MASK;

    return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/NFC_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type NFC
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(NFC_PDD_H_)
#define NFC_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error NFC PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10F12) /* NFC */ && \
      !defined(MCU_MK20F12) /* NFC */ && \
      !defined(MCU_MK60F12) /* NFC */ && \
      !defined(MCU_MK60F15) /* NFC */ && \
      !defined(MCU_MK61F12) /* NFC */ && \
      !defined(MCU_MK61F15) /* NFC */ && \
      !defined(MCU_MK61F12WS) /* NFC */ && \
      !defined(MCU_MK61F15WS) /* NFC */ && \
      !defined(MCU_MK70F12) /* NFC */ && \
      !defined(MCU_MK70F15) /* NFC */ && \
      !defined(MCU_MK70F12WS) /* NFC */ && \
      !defined(MCU_MK70F15WS) /* NFC */
  // Unsupported MCU is active
  #error NFC PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Interrupt flags constants (for GetInterruptFlags, ClearInterruptFlags
   macros). */
#define NFC_PDD_WERR_INT NFC_ISR_WERR_MASK       /**< Write error flag. */
#define NFC_PDD_DONE_INT NFC_ISR_DONE_MASK       /**< . */
#define NFC_PDD_IDLE_INT NFC_ISR_IDLE_MASK       /**< . */

/* ECC mode */
#define NFC_PDD_ECC_0_ERR  0U                    /**< ECC bypassed */
#define NFC_PDD_ECC_4_ERR  0x20000U              /**< 4 bits error correction */
#define NFC_PDD_ECC_6_ERR  0x40000U              /**< 6 bits error correction */
#define NFC_PDD_ECC_8_ERR  0x60000U              /**< 8 bits error correction */
#define NFC_PDD_ECC_12_ERR 0x80000U              /**< 12 bits error correction */
#define NFC_PDD_ECC_16_ERR 0xA0000U              /**< 16 bits error correction */
#define NFC_PDD_ECC_24_ERR 0xC0000U              /**< 24 bits error correction */
#define NFC_PDD_ECC_32_ERR 0xE0000U              /**< 32 bits error correction */

/* Dma mode */
#define NFC_PDD_DMA_NO  0U                       /**< No DMA after page read */
#define NFC_PDD_DMA_YES 0x100000U                /**< DMA after page read */


/* ----------------------------------------------------------------------------
   -- ReadCMD1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the CMD1 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_CMD1.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadCMD1Reg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadCMD1Reg(PeripheralBase) ( \
    NFC_CMD1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteCMD1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the CMD1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the CMD1 register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CMD1.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteCMD1Reg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteCMD1Reg(PeripheralBase, Value) ( \
    NFC_CMD1_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadCMD2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the CMD2 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_CMD1.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadCMD2Reg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadCMD2Reg(PeripheralBase) ( \
    NFC_CMD1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteCMD2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the CMD2 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the CMD2 register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CMD2.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteCMD2Reg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteCMD2Reg(PeripheralBase, Value) ( \
    NFC_CMD2_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadCARReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the CAR register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_CAR.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadCARReg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadCARReg(PeripheralBase) ( \
    NFC_CAR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteCARReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the CAR register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the CAR register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CAR.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteCARReg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteCARReg(PeripheralBase, Value) ( \
    NFC_CAR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadRARReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the RAR register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_RAR.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadRARReg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadRARReg(PeripheralBase) ( \
    NFC_RAR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteRARReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the RAR register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the RAR register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_RAR.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteRARReg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteRARReg(PeripheralBase, Value) ( \
    NFC_RAR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadRPTReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the RPT register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_RPT.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadRPTReg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadRPTReg(PeripheralBase) ( \
    NFC_RPT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteRPTReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the RPT register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the RPT register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_RPT.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteRPTReg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteRPTReg(PeripheralBase, Value) ( \
    NFC_RPT_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadRAIReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the RAI register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_RAI.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadRAIReg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadRAIReg(PeripheralBase) ( \
    NFC_RAI_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteRAIReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the RAI register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the RAI register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_RAI.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteRAIReg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteRAIReg(PeripheralBase, Value) ( \
    NFC_RAI_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSR1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the SR1 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_SR1.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadSR1Reg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadSR1Reg(PeripheralBase) ( \
    NFC_SR1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetID1
   ---------------------------------------------------------------------------- */

/**
 * @brief First byte returned by read ID command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: NFC_SR1.
 * @par Example:
 *      @code
 *      uint8_t result = NFC_PDD_GetID1(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetID1(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(NFC_SR1_REG(PeripheralBase) & NFC_SR1_ID1_MASK)) >> ( \
     NFC_SR1_ID1_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- GetID2
   ---------------------------------------------------------------------------- */

/**
 * @brief Second byte returned by read ID command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: NFC_SR1.
 * @par Example:
 *      @code
 *      uint8_t result = NFC_PDD_GetID2(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetID2(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(NFC_SR1_REG(PeripheralBase) & NFC_SR1_ID2_MASK)) >> ( \
     NFC_SR1_ID2_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- GetID3
   ---------------------------------------------------------------------------- */

/**
 * @brief Third byte returned by read ID command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: NFC_SR1.
 * @par Example:
 *      @code
 *      uint8_t result = NFC_PDD_GetID3(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetID3(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(NFC_SR1_REG(PeripheralBase) & NFC_SR1_ID3_MASK)) >> ( \
     NFC_SR1_ID3_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- GetID4
   ---------------------------------------------------------------------------- */

/**
 * @brief Fourth byte returned by read ID command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: NFC_SR1.
 * @par Example:
 *      @code
 *      uint8_t result = NFC_PDD_GetID4(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetID4(PeripheralBase) ( \
    (uint8_t)(NFC_SR1_REG(PeripheralBase) & NFC_SR1_ID4_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSR2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the SR2 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_SR2.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadSR2Reg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadSR2Reg(PeripheralBase) ( \
    NFC_SR2_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetID5
   ---------------------------------------------------------------------------- */

/**
 * @brief Fifth byte returned by read ID command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: NFC_SR2.
 * @par Example:
 *      @code
 *      uint8_t result = NFC_PDD_GetID5(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetID5(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(NFC_SR2_REG(PeripheralBase) & NFC_SR2_ID5_MASK)) >> ( \
     NFC_SR2_ID5_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- ReadDMA1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the DMA1 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_DMA1.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadDMA1Reg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadDMA1Reg(PeripheralBase) ( \
    NFC_DMA1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteDMA1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the DMA1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the DMA1 register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_DMA1.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteDMA1Reg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteDMA1Reg(PeripheralBase, Value) ( \
    NFC_DMA1_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSWAPReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the SWAP register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_SWAP.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadSWAPReg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadSWAPReg(PeripheralBase) ( \
    NFC_SWAP_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteSWAPReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the SWAP register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the SWAP register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_SWAP.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteSWAPReg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteSWAPReg(PeripheralBase, Value) ( \
    NFC_SWAP_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSECSZReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the SECSZ register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_SECSZ.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadSECSZReg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadSECSZReg(PeripheralBase) ( \
    NFC_SECSZ_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteSECSZReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the SECSZ register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the SECSZ register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_SECSZ.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteSECSZReg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteSECSZReg(PeripheralBase, Value) ( \
    NFC_SECSZ_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadCFGReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the CFG register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_CFG.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadCFGReg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadCFGReg(PeripheralBase) ( \
    NFC_CFG_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteCFGReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the CFG register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the CFG register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CFG.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteCFGReg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteCFGReg(PeripheralBase, Value) ( \
    NFC_CFG_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadDMA2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the DMA2 register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_DMA2.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadDMA2Reg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadDMA2Reg(PeripheralBase) ( \
    NFC_DMA2_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteDMA2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the DMA2 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the DMA2 register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_DMA2.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteDMA2Reg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteDMA2Reg(PeripheralBase, Value) ( \
    NFC_DMA2_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadISRReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the ISR register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_ReadISRReg(deviceID);
 *      @endcode
 */
#define NFC_PDD_ReadISRReg(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteISRReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Value to the ISR register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the ISR register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_WriteISRReg(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_WriteISRReg(PeripheralBase, Value) ( \
    NFC_ISR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- GetInterruptFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns a value that represents a mask of active (pending) interrupts.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "Interrupt flags constants (for
 *         GetInterruptFlags, ClearInterruptFlags macros)." for processing return value.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_GetInterruptFlags(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetInterruptFlags(PeripheralBase) ( \
    (uint32_t)(( \
     NFC_ISR_REG(PeripheralBase)) & ( \
     (uint32_t)(NFC_ISR_WERR_MASK | (NFC_ISR_DONE_MASK | NFC_ISR_IDLE_MASK)))) \
  )

/* ----------------------------------------------------------------------------
   -- ClrInterruptFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears interrupt flags.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of interrupt to clear flags. Use constants from group
 *        "Interrupt flags constants (for GetInterruptFlags, ClearInterruptFlags
 *        macros).". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_ClrInterruptFlags(deviceID, NFC_PDD_WERR_INT);
 *      @endcode
 */
#define NFC_PDD_ClrInterruptFlags(PeripheralBase, Mask) ( \
    NFC_ISR_REG(PeripheralBase) |= \
     (uint32_t)((uint32_t)((uint32_t)(Mask) >> 29U) << 17U) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables interrupts specified by the Mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "Interrupt flags
 *        constants (for GetInterruptFlags, ClearInterruptFlags macros).". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_EnableInterrupt(deviceID, NFC_PDD_WERR_INT);
 *      @endcode
 */
#define NFC_PDD_EnableInterrupt(PeripheralBase, Mask) ( \
    NFC_ISR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       NFC_ISR_REG(PeripheralBase)) | ( \
       (uint32_t)((uint32_t)((uint32_t)(Mask) >> 29U) << 20U)))) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables interrupts specified by the Mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "Interrupt flags
 *        constants (for GetInterruptFlags, ClearInterruptFlags macros).". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_DisableInterrupt(deviceID, NFC_PDD_WERR_INT);
 *      @endcode
 */
#define NFC_PDD_DisableInterrupt(PeripheralBase, Mask) ( \
    NFC_ISR_REG(PeripheralBase) &= \
     (uint32_t)(( \
      (uint32_t)(~(uint32_t)((uint32_t)((uint32_t)(Mask) >> 29U) << 20U))) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableWriteErrorInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables write error interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_EnableWriteErrorInterrupt(deviceID);
 *      @endcode
 */
#define NFC_PDD_EnableWriteErrorInterrupt(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_ISR_REG(PeripheralBase) | NFC_ISR_WERREN_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableWriteErrorInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables write error interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_DisableWriteErrorInterrupt(deviceID);
 *      @endcode
 */
#define NFC_PDD_DisableWriteErrorInterrupt(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) &= \
     (uint32_t)(( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERREN_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- GetWriteErrorInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns write error interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_GetWriteErrorInterruptFlag(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetWriteErrorInterruptFlag(PeripheralBase) ( \
    (uint32_t)(NFC_ISR_REG(PeripheralBase) & NFC_ISR_WERR_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClrWriteErrorInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears write error interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_ClrWriteErrorInterruptFlag(deviceID);
 *      @endcode
 */
#define NFC_PDD_ClrWriteErrorInterruptFlag(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_ISR_REG(PeripheralBase) | NFC_ISR_WERRCLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableCmdDoneInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables command done interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_EnableCmdDoneInterrupt(deviceID);
 *      @endcode
 */
#define NFC_PDD_EnableCmdDoneInterrupt(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_ISR_REG(PeripheralBase) | NFC_ISR_DONEEN_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableCmdDoneInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables command done interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_DisableCmdDoneInterrupt(deviceID);
 *      @endcode
 */
#define NFC_PDD_DisableCmdDoneInterrupt(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) &= \
     (uint32_t)(( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONEEN_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- GetCmdDoneInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns command done interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_GetCmdDoneInterruptFlag(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetCmdDoneInterruptFlag(PeripheralBase) ( \
    (uint32_t)(NFC_ISR_REG(PeripheralBase) & NFC_ISR_DONE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClrCmdDoneInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears command done interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_ClrCmdDoneInterruptFlag(deviceID);
 *      @endcode
 */
#define NFC_PDD_ClrCmdDoneInterruptFlag(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_ISR_REG(PeripheralBase) | NFC_ISR_DONECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK)))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableCmdIdleInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables command idle interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_EnableCmdIdleInterrupt(deviceID);
 *      @endcode
 */
#define NFC_PDD_EnableCmdIdleInterrupt(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_ISR_REG(PeripheralBase) | NFC_ISR_IDLEEN_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableCmdIdleInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables command idle interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_DisableCmdIdleInterrupt(deviceID);
 *      @endcode
 */
#define NFC_PDD_DisableCmdIdleInterrupt(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) &= \
     (uint32_t)(( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLEEN_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- GetCmdIdleInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns command idle interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_GetCmdIdleInterruptFlag(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetCmdIdleInterruptFlag(PeripheralBase) ( \
    (uint32_t)(NFC_ISR_REG(PeripheralBase) & NFC_ISR_IDLE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClrCmdIdleInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears command idle interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_ISR.
 * @par Example:
 *      @code
 *      NFC_PDD_ClrCmdIdleInterruptFlag(deviceID);
 *      @endcode
 */
#define NFC_PDD_ClrCmdIdleInterruptFlag(PeripheralBase) ( \
    NFC_ISR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_ISR_REG(PeripheralBase) | NFC_ISR_IDLECLR_MASK)) & (( \
      (uint32_t)(~(uint32_t)NFC_ISR_DONECLR_MASK)) & ( \
      (uint32_t)(~(uint32_t)NFC_ISR_WERRCLR_MASK)))) \
  )

/* ----------------------------------------------------------------------------
   -- SetFastFlashTiming
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables fast flash timing.
 * @param PeripheralBase Peripheral base address.
 * @param State Enables or disables fast flash timing. This parameter is of
 *        "Global enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CFG.
 * @par Example:
 *      @code
 *      NFC_PDD_SetFastFlashTiming(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define NFC_PDD_SetFastFlashTiming(PeripheralBase, State) ( \
    NFC_CFG_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_CFG_REG(PeripheralBase) & (uint32_t)(~(uint32_t)NFC_CFG_FAST_MASK))) | ( \
      (uint32_t)((uint32_t)(State) << NFC_CFG_FAST_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetEccModeDmaAndVirtPageCount
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets Ecc mode, Dma and virtual page count.
 * @param PeripheralBase Peripheral base address.
 * @param Ecc Ecc mode. This parameter is of "ECC mode" type.
 * @param Dma Dma state. This parameter is of "Dma mode" type.
 * @param VirtualPageCount Virtual page count. This parameter is a 4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CFG.
 * @par Example:
 *      @code
 *      NFC_PDD_SetEccModeDmaAndVirtPageCount(deviceID, NFC_PDD_ECC_0_ERR,
 *      NFC_PDD_DMA_NO, 1);
 *      @endcode
 */
#define NFC_PDD_SetEccModeDmaAndVirtPageCount(PeripheralBase, Ecc, Dma, VirtualPageCount) ( \
    NFC_CFG_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       NFC_CFG_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)NFC_CFG_ECCMODE_MASK)) & (( \
       (uint32_t)(~(uint32_t)NFC_CFG_DMAREQ_MASK)) & ( \
       (uint32_t)(~(uint32_t)NFC_CFG_PAGECNT_MASK)))))) | (( \
      (uint32_t)(Ecc)) | (( \
      (uint32_t)(Dma)) | ( \
      (uint32_t)(VirtualPageCount))))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableEcc
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables ECC.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CFG.
 * @par Example:
 *      @code
 *      NFC_PDD_DisableEcc(deviceID);
 *      @endcode
 */
#define NFC_PDD_DisableEcc(PeripheralBase) ( \
    NFC_CFG_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)NFC_CFG_ECCMODE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetSectorSize
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets transfer data size.
 * @param PeripheralBase Peripheral base address.
 * @param SectorSize Sector size. This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_SECSZ.
 * @par Example:
 *      @code
 *      NFC_PDD_SetSectorSize(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetSectorSize(PeripheralBase, SectorSize) ( \
    NFC_SECSZ_REG(PeripheralBase) = \
     (uint32_t)(SectorSize) \
  )

/* ----------------------------------------------------------------------------
   -- SetVirtualPageCount
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets virtual page count size.
 * @param PeripheralBase Peripheral base address.
 * @param Count Virtual page count. This parameter is a 4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CFG.
 * @par Example:
 *      @code
 *      NFC_PDD_SetVirtualPageCount(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetVirtualPageCount(PeripheralBase, Count) ( \
    NFC_CFG_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_CFG_REG(PeripheralBase) & (uint32_t)(~(uint32_t)NFC_CFG_PAGECNT_MASK))) | ( \
      (uint32_t)(Count))) \
  )

/* ----------------------------------------------------------------------------
   -- SetRowAddress
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets row address.
 * @param PeripheralBase Peripheral base address.
 * @param RowAddress Row address. This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_RAR.
 * @par Example:
 *      @code
 *      NFC_PDD_SetRowAddress(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetRowAddress(PeripheralBase, RowAddress) ( \
    NFC_RAR_REG(PeripheralBase) = \
     (uint32_t)(RowAddress) \
  )

/* ----------------------------------------------------------------------------
   -- IncRowAddress
   ---------------------------------------------------------------------------- */

/**
 * @brief Adds defined value to the row address.
 * @param PeripheralBase Peripheral base address.
 * @param Increment Row address increment. This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_RAR.
 * @par Example:
 *      @code
 *      NFC_PDD_IncRowAddress(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_IncRowAddress(PeripheralBase, Increment) ( \
    NFC_RAR_REG(PeripheralBase) = \
     NFC_RAR_REG(PeripheralBase) + (uint32_t)(Increment) \
  )

/* ----------------------------------------------------------------------------
   -- SetColAddress
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets row address.
 * @param PeripheralBase Peripheral base address.
 * @param ColAddress Column address. This parameter is a 24-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CAR.
 * @par Example:
 *      @code
 *      NFC_PDD_SetColAddress(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetColAddress(PeripheralBase, ColAddress) ( \
    NFC_CAR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_CAR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)0xFFFFFFU))) | ( \
      (uint32_t)(ColAddress))) \
  )

/* ----------------------------------------------------------------------------
   -- GetRepeatCount
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the RPT register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: NFC_RPT.
 * @par Example:
 *      @code
 *      uint32_t result = NFC_PDD_GetRepeatCount(deviceID);
 *      @endcode
 */
#define NFC_PDD_GetRepeatCount(PeripheralBase) ( \
    NFC_RPT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- SetRepeatCount
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets repeat counts.
 * @param PeripheralBase Peripheral base address.
 * @param RepeatCount 16-bit repeat count. Determines how many times
 *        NFC_CMD2[CODE] is executed. If 0 or 1, the flash command is executed once. This
 *        parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_RPT.
 * @par Example:
 *      @code
 *      NFC_PDD_SetRepeatCount(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetRepeatCount(PeripheralBase, RepeatCount) ( \
    NFC_RPT_REG(PeripheralBase) = \
     (uint32_t)(RepeatCount) \
  )

/* ----------------------------------------------------------------------------
   -- SetRowAddressInc
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets row address increment..
 * @param PeripheralBase Peripheral base address.
 * @param Increment Row address increment. This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_RAI.
 * @par Example:
 *      @code
 *      NFC_PDD_SetRowAddressInc(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetRowAddressInc(PeripheralBase, Increment) ( \
    NFC_RAI_REG(PeripheralBase) = \
     (uint32_t)(Increment) \
  )

/* ----------------------------------------------------------------------------
   -- SetDma1Address
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets Dma1 address.
 * @param PeripheralBase Peripheral base address.
 * @param Address Address. This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_DMA1.
 * @par Example:
 *      @code
 *      NFC_PDD_SetDma1Address(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetDma1Address(PeripheralBase, Address) ( \
    NFC_DMA1_REG(PeripheralBase) = \
     (uint32_t)(Address) \
  )

/* ----------------------------------------------------------------------------
   -- SetDma2Address
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets Dma2 address.
 * @param PeripheralBase Peripheral base address.
 * @param Address Address. This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_DMA2.
 * @par Example:
 *      @code
 *      NFC_PDD_SetDma2Address(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetDma2Address(PeripheralBase, Address) ( \
    NFC_DMA2_REG(PeripheralBase) = \
     (uint32_t)(Address) \
  )

/* ----------------------------------------------------------------------------
   -- SetDma1
   ---------------------------------------------------------------------------- */

/**
 * @brief Prepares DMA1 for transfer.
 * @param PeripheralBase Peripheral base address.
 * @param Address Buffer address. Must be 4 bytes aligned. This parameter is a
 *        32-bit value.
 * @param Size Data size. Data are transferred in multiple of 4 bytes. This
 *        parameter is a 12-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_DMA1, NFC_DMACFG
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      NFC_PDD_SetDma1(deviceID, 1, 1);
 *      @endcode
 */
#define NFC_PDD_SetDma1(PeripheralBase, Address, Size) ( \
    (NFC_DMA1_REG(PeripheralBase) = \
     (uint32_t)(Address)), \
    (NFC_DMACFG_REG(PeripheralBase) = \
     (uint32_t)((uint32_t)((uint32_t)(Size) << NFC_DMACFG_COUNT1_SHIFT) | NFC_DMACFG_ACT1_MASK)) \
  )

/* ----------------------------------------------------------------------------
   -- SetDma2
   ---------------------------------------------------------------------------- */

/**
 * @brief Prepares DMA2 for transfer.
 * @param PeripheralBase Peripheral base address.
 * @param Address Buffer address. Must be 8 bytes aligned. This parameter is a
 *        32-bit value.
 * @param Size Data size. Data are transferred in multiple of 8 bytes. This
 *        parameter is a 7-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_DMA2, NFC_DMACFG
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      NFC_PDD_SetDma2(deviceID, 1, 1);
 *      @endcode
 */
#define NFC_PDD_SetDma2(PeripheralBase, Address, Size) ( \
    (NFC_DMA2_REG(PeripheralBase) = \
     (uint32_t)(Address)), \
    (NFC_DMACFG_REG(PeripheralBase) = \
     (uint32_t)((uint32_t)((uint32_t)(Size) << NFC_DMACFG_COUNT2_SHIFT) | NFC_DMACFG_ACT2_MASK)) \
  )

/* ----------------------------------------------------------------------------
   -- SetDma1AndDma2
   ---------------------------------------------------------------------------- */

/**
 * @brief Prepares DMA1 and DMA2 for transfer.
 * @param PeripheralBase Peripheral base address.
 * @param Dma1DstAddress Buffer address. Must be 4 bytes aligned. This parameter
 *        is a 32-bit value.
 * @param Dma1DataSize Data size. Data are transferred in multiple of 4 bytes.
 *        This parameter is a 12-bit value.
 * @param Dma2DstAddress Buffer address. Must be 8 bytes aligned. This parameter
 *        is a 32-bit value.
 * @param Dma2DataSize Data size. Data are transferred in multiple of 8 bytes.
 *        This parameter is a 7-bit value.
 * @param Dma2Offset 256 byte offest from the begin of the active SRAM buffer.
 *        This parameter is a 4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_DMA1, NFC_DMA2,
 *          NFC_DMACFG (depending on the peripheral).
 * @par Example:
 *      @code
 *      NFC_PDD_SetDma1AndDma2(deviceID, 1, 1, 1, 1, 1);
 *      @endcode
 */
#define NFC_PDD_SetDma1AndDma2(PeripheralBase, Dma1DstAddress, Dma1DataSize, Dma2DstAddress, Dma2DataSize, Dma2Offset) ( \
    (NFC_DMA1_REG(PeripheralBase) = \
     (uint32_t)(Dma1DstAddress)), \
    ((NFC_DMA2_REG(PeripheralBase) = \
     (uint32_t)(Dma2DstAddress)), \
    (NFC_DMACFG_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)((uint32_t)(Dma1DataSize) << NFC_DMACFG_COUNT1_SHIFT)) | (( \
      (uint32_t)((uint32_t)(Dma2DataSize) << NFC_DMACFG_COUNT2_SHIFT)) | (( \
      (uint32_t)((uint32_t)(Dma2Offset) << NFC_DMACFG_OFFSET2_SHIFT)) | (( \
      NFC_DMACFG_ACT1_MASK) | ( \
      NFC_DMACFG_ACT2_MASK))))))) \
  )

/* ----------------------------------------------------------------------------
   -- SetResetCmd
   ---------------------------------------------------------------------------- */

/**
 * @brief Reset command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CMD2.
 * @par Example:
 *      @code
 *      NFC_PDD_SetResetCmd(deviceID);
 *      @endcode
 */
#define NFC_PDD_SetResetCmd(PeripheralBase) ( \
    NFC_CMD2_REG(PeripheralBase) = \
     0xFF404000U \
  )

/* ----------------------------------------------------------------------------
   -- SetReadIdCmd
   ---------------------------------------------------------------------------- */

/**
 * @brief Read ID command.
 * @param PeripheralBase Peripheral base address.
 * @param Address Address. This parameter is a 8-bit value.
 * @param Size Requested data size. This parameter is a 3-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CMD2, NFC_RAR,
 *          NFC_CFG (depending on the peripheral).
 * @par Example:
 *      @code
 *      NFC_PDD_SetReadIdCmd(deviceID, 1, 1);
 *      @endcode
 */
#define NFC_PDD_SetReadIdCmd(PeripheralBase, Address, Size) ( \
    (NFC_CMD2_REG(PeripheralBase) = \
     0x90480400U), \
    ((NFC_RAR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_RAR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)NFC_RAR_BYTE1_MASK))) | ( \
      (uint32_t)(Address)))), \
    (NFC_CFG_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_CFG_REG(PeripheralBase) & (uint32_t)(~(uint32_t)NFC_CFG_IDCNT_MASK))) | ( \
      (uint32_t)((uint32_t)(Size) << NFC_CFG_IDCNT_SHIFT))))) \
  )

/* ----------------------------------------------------------------------------
   -- SetReadPageCmd
   ---------------------------------------------------------------------------- */

/**
 * @brief Prepares NFC to read  up to 4 pages.
 * @param PeripheralBase Peripheral base address.
 * @param RowAddress Row address. This parameter is a 24-bit value.
 * @param ColAddress Column address. This parameter is a 32-bit value.
 * @param BufferNum Buffer number. This parameter is a 2-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CAR, NFC_RAR,
 *          NFC_CMD1, NFC_CMD2 (depending on the peripheral).
 * @par Example:
 *      @code
 *      NFC_PDD_SetReadPageCmd(deviceID, 1, 1, 1);
 *      @endcode
 */
#define NFC_PDD_SetReadPageCmd(PeripheralBase, RowAddress, ColAddress, BufferNum) ( \
    (NFC_CAR_REG(PeripheralBase) = \
     (uint32_t)(ColAddress)), \
    ((NFC_RAR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_RAR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)0xFFFFFFU))) | ( \
      (uint32_t)(RowAddress)))), \
    ((NFC_CMD1_REG(PeripheralBase) = \
     0x30000000U), \
    (NFC_CMD2_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)((uint32_t)0x7EE0U << NFC_CMD2_CODE_SHIFT)) | ( \
      (uint32_t)((uint32_t)(BufferNum) << NFC_CMD2_BUFNO_SHIFT)))))) \
  )

/* ----------------------------------------------------------------------------
   -- SetWritePageCmd
   ---------------------------------------------------------------------------- */

/**
 * @brief Prepares NFC to read  up to 4 pages.
 * @param PeripheralBase Peripheral base address.
 * @param RowAddress Row address. This parameter is a 24-bit value.
 * @param ColAddress Column address. This parameter is a 32-bit value.
 * @param BufferNum Buffer number. This parameter is a 2-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CAR, NFC_RAR,
 *          NFC_CMD1, NFC_CMD2 (depending on the peripheral).
 * @par Example:
 *      @code
 *      NFC_PDD_SetWritePageCmd(deviceID, 1, 1, 1);
 *      @endcode
 */
#define NFC_PDD_SetWritePageCmd(PeripheralBase, RowAddress, ColAddress, BufferNum) ( \
    (NFC_CAR_REG(PeripheralBase) = \
     (uint32_t)(ColAddress)), \
    ((NFC_RAR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_RAR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)0xFFFFFFU))) | ( \
      (uint32_t)(RowAddress)))), \
    ((NFC_CMD1_REG(PeripheralBase) = \
     0x10700000U), \
    (NFC_CMD2_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)((uint32_t)0x80U << NFC_CMD2_BYTE1_SHIFT)) | (( \
      (uint32_t)((uint32_t)0xFFD8U << NFC_CMD2_CODE_SHIFT)) | ( \
      (uint32_t)((uint32_t)(BufferNum) << NFC_CMD2_BUFNO_SHIFT))))))) \
  )

/* ----------------------------------------------------------------------------
   -- SetEraseBlockCmd
   ---------------------------------------------------------------------------- */

/**
 * @brief Prepares NFC to program up to 4 page.
 * @param PeripheralBase Peripheral base address.
 * @param BlockAddress Page address. This parameter is a 24-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CMD1, NFC_CMD2,
 *          NFC_RAR (depending on the peripheral).
 * @par Example:
 *      @code
 *      NFC_PDD_SetEraseBlockCmd(deviceID, 1);
 *      @endcode
 */
#define NFC_PDD_SetEraseBlockCmd(PeripheralBase, BlockAddress) ( \
    (NFC_CMD1_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)((uint32_t)0x70U << NFC_CMD1_BYTE3_SHIFT)) | ( \
      (uint32_t)((uint32_t)0xD0U << NFC_CMD1_BYTE2_SHIFT)))), \
    ((NFC_CMD2_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)((uint32_t)0x60U << NFC_CMD2_BYTE1_SHIFT)) | ( \
      (uint32_t)((uint32_t)0x4ED8U << NFC_CMD2_CODE_SHIFT)))), \
    (NFC_RAR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(NFC_RAR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)0xFFFFFFU))) | ( \
      (uint32_t)(BlockAddress))))) \
  )

/* ----------------------------------------------------------------------------
   -- SetEccModeDmaReqAndPageCount
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets address swap.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_SWAP.
 * @par Example:
 *      @code
 *      NFC_PDD_SetEccModeDmaReqAndPageCount(deviceID);
 *      @endcode
 */
#define NFC_PDD_SetEccModeDmaReqAndPageCount(PeripheralBase) ( \
    NFC_SWAP_REG(PeripheralBase) = \
     (uint32_t)(NFC_SWAP_ADDR1_MASK | NFC_SWAP_ADDR2_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- DisableAddressSwap
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets address swap.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_SWAP.
 * @par Example:
 *      @code
 *      NFC_PDD_DisableAddressSwap(deviceID);
 *      @endcode
 */
#define NFC_PDD_DisableAddressSwap(PeripheralBase) ( \
    NFC_SWAP_REG(PeripheralBase) = \
     (uint32_t)(NFC_SWAP_ADDR1_MASK | NFC_SWAP_ADDR2_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetAddressSwap
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets address swap.
 * @param PeripheralBase Peripheral base address.
 * @param Address1 Address 1. This parameter is a 11-bit value.
 * @param Address2 Address 2. This parameter is a 11-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_SWAP.
 * @par Example:
 *      @code
 *      NFC_PDD_SetAddressSwap(deviceID, 1, 1);
 *      @endcode
 */
#define NFC_PDD_SetAddressSwap(PeripheralBase, Address1, Address2) ( \
    NFC_SWAP_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)((uint32_t)(Address1) << NFC_SWAP_ADDR1_SHIFT)) | ( \
      (uint32_t)((uint32_t)(Address2) << NFC_SWAP_ADDR2_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- StartCommand
   ---------------------------------------------------------------------------- */

/**
 * @brief Starts command execution.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: NFC_CMD2.
 * @par Example:
 *      @code
 *      NFC_PDD_StartCommand(deviceID);
 *      @endcode
 */
#define NFC_PDD_StartCommand(PeripheralBase) ( \
    NFC_CMD2_REG(PeripheralBase) |= \
     NFC_CMD2_BUSY_START_MASK \
  )
#endif  /* #if defined(NFC_PDD_H_) */

/* NFC_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/adc_prv.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_prv.h$
* $Version : 3.8.28.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines, structure
*   definitions private to the fdv Ramdisk drivers
*
*END************************************************************************/
#ifndef __adc_prv_h__
#define __adc_prv_h__

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

#define IO_ERROR_INCOMPLETE_IOCTL       (IO_ERROR_INVALID_IOCTL_CMD) /* this is internal ADC IOCTL and means that IOCTL must be passed from ADC part to trigger part */

/* information stored here concerns only to AD converter */
typedef struct adc_generic {
   uint_32            resolution;
   uint_32            adc_frq;       /* frequency of ADC hardware, usually 1 / Tad */
} ADC_GENERIC, _PTR_ ADC_GENERIC_PTR;

/* information stored here concerns only to AD trigger */
typedef struct adt_generic {
   ADT_TRIGGER_MASK   triggers_fire; /* specifies triggers, which were set and there is still attached channel that did not complete conversion */
   boolean            run;           /* specifies if ADC is running (this is OR operation of all channel's ADC_CHANNEL_RUNNING flag) */
} ADT_GENERIC, _PTR_ ADT_GENERIC_PTR;

typedef struct adc_channel_generic {
   _mqx_uint number;     /* number of channel */
   uint_16               init_flags;        /* flags copied from initialization structure */
   uint_16               source;            /* source copied from initialization structure */
   uint_32               range;             /* output range */
   ADC_RESULT_STRUCT_PTR buffer_start;      /* circular result buffer start pointer */
   ADC_RESULT_STRUCT_PTR buffer_end;        /* circular result buffer end pointer */
   ADC_RESULT_STRUCT_PTR buffer_task;       /* circular result buffer - next read pointer for result */
   ADC_RESULT_STRUCT_PTR buffer_driver;     /* circular result buffer - next write pointer for result */
} ADC_CHANNEL_GENERIC, _PTR_ ADC_CHANNEL_GENERIC_PTR;

typedef struct adt_channel_generic {
   _mqx_uint number;     /* number of channel */
   uint_16               init_flags;        /* flags copied from initialization structure */
#define ADC_CHANNEL_RUNNING          (0x01) /* when ADC channel is running, this flag is set */
#define ADC_CHANNEL_RESUMED          (0x02) /* when ADC channel is not paused, this flag is set */
   uint_16               runtime_flags;     /* generic flags for ADC driver */
   int_32                offset;            /* offset of time, counter: first this needs to be decremented to zero to start conversion process */
   _mqx_uint             period;            /* time period between 2 samples taken */
   _mqx_uint             time;              /* time to next ADC */
   int_32                samples;           /* samples, counter: this needs to be decremented to zero to invoke any event */
   int_32                samples_preset;    /* constant: specifies predefined number of samples */
   ADT_TRIGGER_MASK      trigger;           /* trigger, that triggers this ADC channel */
#if MQX_USE_LWEVENTS
   LWEVENT_STRUCT_PTR    complete_event;    /* pointer to lwevent, triggered after counter_samples reaches zero */
   uint_32               event_mask;        /* mask of events in complete_event */
#endif
} ADT_CHANNEL_GENERIC, _PTR_ ADT_CHANNEL_GENERIC_PTR;

typedef uint_32 ADC_HW_CHANNEL_MASK; /* there can be only 32 channels per converter */

/* NOTE: DO NOT MOVE THESE INCLUDES, THEY MUST BE HERE. THEY DEFINES NEW MANDATORY TYPES (E.G. ADC_CHANNEL_BUNDLE) BASED ON GENERIC TYPES */
#if (PSP_MQX_CPU_IS_MCF51QM || PSP_MQX_CPU_IS_MCF51JF || PSP_MQX_CPU_IS_KINETIS)
    #include "adc_kadc_prv.h"
#elif PSP_MQX_CPU_IS_MCF5222X || PSP_MQX_CPU_IS_MCF5223X || PSP_MQX_CPU_IS_MCF5225X
    #include "adc_mcf522xx_prv.h"
#elif PSP_MQX_CPU_IS_MCF51MM
    #include "adc_mcf51mm_prv.h"
#elif PSP_MQX_CPU_IS_MCF51JE
    #include "adc_mcf51je_prv.h"
#elif PSP_MQX_CPU_IS_MCF51AG
    #include "adc_mcf51ag_prv.h"
#elif PSP_MQX_CPU_IS_MCF51EM
    #include "adc_mcf51em_prv.h"
#elif PSP_MQX_CPU_IS_MCF51
    #include "adc_mcf51xx_prv.h"
#elif PSP_MQX_CPU_IS_MCF5441X
    #include "adc_mcf544xx_prv.h"
#else
    #error ADC device driver not supported for processor.
#endif
/* AND NOW, WE HAVE ALL DEFINITIONS FOR DRIVER */

_mqx_int _adc_open(MQX_FILE_PTR, char_ptr, char_ptr);
_mqx_int _adc_close(MQX_FILE_PTR);
_mqx_int _adc_read (MQX_FILE_PTR, char_ptr, _mqx_int);
_mqx_int _adc_write(MQX_FILE_PTR, char_ptr, _mqx_int);
_mqx_int _adc_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);

/* these functions must be present for trigger */
_mqx_int _adt_trigger(MQX_FILE_PTR, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask);
_mqx_int _adt_pause(MQX_FILE_PTR, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask);
_mqx_int _adt_resume(MQX_FILE_PTR, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask);
_mqx_int _adt_stop(MQX_FILE_PTR, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask);
_mqx_int _adt_process_data(ADC_CHANNEL_BUNDLE_PTR channel);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/include/usb_cdc.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_cdc.h$
* $Version : 3.8.5.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
* @brief The file contains USB stack CDC class layer api header function.
*
*****************************************************************************/

#ifndef _USB_CDC_H
#define _USB_CDC_H 1

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "devapi.h"   
#include "usb_class.h"

/******************************************************************************
 * Constants - None
 *****************************************************************************/

/* if this macro is not zero, it implies that FEC is present in Soc */
#if BSPCFG_RX_RING_LEN 
    #define RNDIS_SUPPORT                    (1)/* TRUE:1, FALSE:0*/ 
#else   
    #define RNDIS_SUPPORT                    (0)/* TRUE:1, FALSE:0*/ 
#endif

/******************************************************************************
 * Macro's
 *****************************************************************************/
/* Class specific request Codes */
#define SEND_ENCAPSULATED_COMMAND       (0x00)
#define GET_ENCAPSULATED_RESPONSE       (0x01)
#define SET_COMM_FEATURE                (0x02)
#define GET_COMM_FEATURE                (0x03)
#define CLEAR_COMM_FEATURE              (0x04)
#define SET_AUX_LINE_STATE              (0x10)
#define SET_HOOK_STATE                  (0x11)
#define PULSE_SETUP                     (0x12)
#define SEND_PULSE                      (0x13)
#define SET_PULSE_TIME                  (0x14)
#define RING_AUX_JACK                   (0x15)
#define SET_LINE_CODING                 (0x20)
#define GET_LINE_CODING                 (0x21)
#define SET_CONTROL_LINE_STATE          (0x22)
#define SEND_BREAK                      (0x23)
#define SET_RINGER_PARAMS               (0x30)
#define GET_RINGER_PARAMS               (0x31)
#define SET_OPERATION_PARAM             (0x32)
#define GET_OPERATION_PARAM             (0x33)
#define SET_LINE_PARAMS                 (0x34)
#define GET_LINE_PARAMS                 (0x35)
#define DIAL_DIGITS                     (0x36)
#define SET_UNIT_PARAMETER              (0x37)
#define GET_UNIT_PARAMETER              (0x38)
#define CLEAR_UNIT_PARAMETER            (0x39)
#define GET_PROFILE                     (0x3A)
#define SET_ETHERNET_MULTICAST_FILTERS  (0x40)
#define SET_ETHERNET_POW_PATTER_FILTER  (0x41)
#define GET_ETHERNET_POW_PATTER_FILTER  (0x42)
#define SET_ETHERNET_PACKET_FILTER      (0x43)
#define GET_ETHERNET_STATISTIC          (0x44)
#define SET_ATM_DATA_FORMAT             (0x50)
#define GET_ATM_DEVICE_STATISTICS       (0x51)
#define SET_ATM_DEFAULT_VC              (0x52)
#define GET_ATM_VC_STATISTICS           (0x53)
#define MDLM_SPECIFIC_REQUESTS_MASK     (0x7F)

/* Class Specific Notification Codes */
#define NETWORK_CONNECTION_NOTIF        (0x00)
#define RESPONSE_AVAIL_NOTIF            (0x01)
#define AUX_JACK_HOOK_STATE_NOTIF       (0x08)
#define RING_DETECT_NOTIF               (0x09)
#define SERIAL_STATE_NOTIF              (0x20)
#define CALL_STATE_CHANGE_NOTIF         (0x28)
#define LINE_STATE_CHANGE_NOTIF         (0x29)
#define CONNECTION_SPEED_CHANGE_NOTIF   (0x2A)
#define MDLM_SPECIFIC_NOTIF_MASK        (0x5F)

/* Events to the Application */ /* 0 to 4 are reserved for class events */
#define USB_APP_CDC_CARRIER_DEACTIVATED   (0x21)
#define USB_APP_CDC_CARRIER_ACTIVATED     (0x22)
#define USB_APP_CDC_DTE_DEACTIVATED       (0x23)
#define USB_APP_CDC_DTE_ACTIVATED         (0x24)
#define USB_APP_GET_LINK_SPEED            (0x25)    
#define USB_APP_GET_LINK_STATUS           (0x26)    

/* other macros */
#define NOTIF_PACKET_SIZE             (0x08)
#define NOTIF_REQUEST_TYPE            (0xA1)
#define PSTN_SUBCLASS_NOTIF_SUPPORT   (1)/*TRUE*/

/* macros for queuing */
#define CDC_MAX_QUEUE_ELEMS              (16)  

#define GET_ABSTRACT_STATE               (0x23)
#define GET_COUNTRY_SETTING              (0x24)

#define SET_ABSTRACT_STATE                (0x25)
#define SET_COUNTRY_SETTING              (0x26)
#define MAX_CDC_DEVICE                    (0x01)
 
/*****************************************************************************
 * Local Functions
 *****************************************************************************/
void USB_Service_Cdc_Notif(PTR_USB_EVENT_STRUCT event,pointer arg);
void USB_Service_Dic_Bulk_In(PTR_USB_EVENT_STRUCT event,pointer arg);
void USB_Service_Dic_Bulk_Out(PTR_USB_EVENT_STRUCT event,pointer arg);

void USB_Class_CDC_Event(uint_8 event, void* val,pointer arg) ; 
/******************************************************************************
 * Types
 *****************************************************************************/
/* Type representing CDC class handle*/ 
typedef uint_32 CDC_HANDLE;

typedef uint_32 _ip_address;

typedef struct _app_data_struct 
{
    uint_8_ptr      data_ptr;         /* pointer to buffer       */            
    uint_32 data_size;                /* buffer size of endpoint */
}APP_DATA_STRUCT;
 
/* structure to hold a request in the endpoint queue */
typedef struct _usb_class_cdc_queue 
{
    _usb_device_handle  handle;
    uint_8 channel;       
    APP_DATA_STRUCT app_data;  
}USB_CLASS_CDC_QUEUE, *PTR_USB_CLASS_CDC_QUEUE;
 
/* USB class cdc endpoint data */
typedef struct _usb_class_cdc_endpoint 
{
    uint_8 endpoint; /* endpoint num */                    
    uint_8 type;     /* type of endpoint (interrupt, bulk or isochronous) */   
    uint_8 bin_consumer;/* the num of queued elements */
    uint_8 bin_producer;/* the num of de-queued elements */
    USB_CLASS_CDC_QUEUE queue[CDC_MAX_QUEUE_ELEMS]; /* queue data */  
}USB_CLASS_CDC_ENDPOINT;

typedef struct _cdc_variable_struct
{
    CDC_HANDLE cdc_handle;
    USB_CLASS_HANDLE class_handle;
    _usb_device_handle controller_handle;
    USB_ENDPOINTS *usb_ep_data;
    uint_32 comm_feature_data_size;
    uint_8  cic_send_endpoint;
    uint_8  cic_recv_endpoint;
    uint_8  dic_send_endpoint;
    uint_8  dic_recv_endpoint;
    uint_32 dic_recv_pkt_size;
    uint_32 dic_send_pkt_size;
    uint_32 cic_send_pkt_size;    
    /* Holds the PSTN object*/
    pointer pstn_obj_ptr;
    uint_8 max_supported_interfaces;
    USB_CLASS_CALLBACK_STRUCT cdc_class_cb;
    USB_REQ_CALLBACK_STRUCT       vendor_req_callback;            
    USB_CLASS_CALLBACK_STRUCT param_callback; 
    /* contains the endpoint info */
    USB_CLASS_CDC_ENDPOINT *ep;
    
    #if RNDIS_SUPPORT   
        /* rndis specific configuration */
        _enet_address mac_address;
        _ip_address ip_address;
        uint_32 rndis_max_frame_size;
    #endif
    
 }CDC_DEVICE_STRUCT, _PTR_ CDC_DEVICE_STRUCT_PTR;
 
 typedef struct _cdc_config_struct
 {
    uint_32 comm_feature_data_size;
    uint_8 cic_send_endpoint;
    uint_8 dic_send_endpoint;
    uint_8 dic_recv_endpoint;
    uint_32 dic_recv_pkt_size;
    uint_32 dic_send_pkt_size;
    uint_32 cic_send_pkt_size;
    uint_8 max_supported_interfaces;
    USB_ENDPOINTS *usb_ep_data;
    uint_32   desc_endpoint_cnt;
    USB_CLASS_CALLBACK_STRUCT  cdc_class_cb;
    USB_REQ_CALLBACK_STRUCT    vendor_req_callback;
    USB_CLASS_CALLBACK_STRUCT  param_callback;
    USB_CLASS_CDC_ENDPOINT *ep;
    DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr; 
    
    #if RNDIS_SUPPORT   
        /* rndis specific configuration */
        _enet_address mac_address;
        _ip_address ip_address;
        uint_32 rndis_max_frame_size;
    #endif
    
 }CDC_CONFIG_STRUCT,_PTR_ CDC_CONFIG_STRUCT_PTR;
/******************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param *cdc_config_ptr[IN]:  This structure contians configuration parameter
 *                              send by APP to configure CDC class.
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the CDC Class layer and layers it is dependednt on 
 *
 *****************************************************************************/
extern uint_32 USB_Class_CDC_Init
(
 CDC_CONFIG_STRUCT_PTR cdc_config_ptr
);
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Deinit
 *
 * @brief The funtion deinitializes the Device and Controller layer 
 *
 * @param cdc_handle:  
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the CDC Class layer and layers it is dependednt on 
 *
 *****************************************************************************/
extern uint_32 USB_Class_CDC_Deinit
(
  CDC_HANDLE cdc_handle
);
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Send_Data
 *
 * @brief  This function sends data to Host.
 *
 * @param handle          :   handle returned by USB_Class_CDC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK         : When Successfull 
 *         Others         : Errors
 *****************************************************************************/
extern uint_8 USB_Class_CDC_Send_Data
(
    CDC_HANDLE          cdc_handle,
    uint_8              ep_num,
    uint_8_ptr          buff_ptr,      /* [IN] buffer to send */      
    uint_32             size           /* [IN] length of the transfer */
);
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Recv_Data
 *
 * @brief This functions receives Data from Host.
 *
 * @param handle          :   handle returned by USB_Class_CDC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK         : When Successfull 
 *         Others         : Errors
 *****************************************************************************/
extern uint_8 USB_Class_CDC_Recv_Data
(
    CDC_HANDLE          cdc_handle,
    uint_8              ep_num,
    uint_8_ptr          buff_ptr,      /* [IN] buffer to send */      
    uint_32             size           /* [IN] length of the transfer */
);

/******************************************************************************
 * Global Functions of Subclass
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Pstn_Init
 *
 * @brief The funtion initializes the Pstn Module 
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param class_callback:       event callback 
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Pstn_Init
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_CLASS_CALLBACK_STRUCT_PTR pstn_cb
); 
/**************************************************************************//*!
 *
 * @name  USB_Pstn_Deinit
 *
 * @brief The funtion initializes the Pstn Module 
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param class_callback:       event callback 
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Pstn_Deinit
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr
);
/**************************************************************************//*!
 *
 * @name  PSTN_Get_Line_Coding
 *
 * @brief  This function is called in response to GetLineCoding request
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
extern uint_8 PSTN_Get_Line_Coding(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
                                   USB_SETUP_STRUCT * setup_packet,
                                   uint_8_ptr *data, 
                                   uint_32 *size);
                                   
/**************************************************************************//*!
 *
 * @name  PSTN_Set_Line_Coding
 *
 * @brief  This function is called in response to SetLineCoding request
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
extern uint_8 PSTN_Set_Line_Coding(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
                                   USB_SETUP_STRUCT * setup_packet,
                                   uint_8_ptr *data, 
                                   uint_32 *size);  
                                   
/**************************************************************************//*!
 *
 * @name  PSTN_Set_Ctrl_Line_State
 *
 * @brief  This function is called in response to Set Control Line State 
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/ 
extern uint_8 PSTN_Set_Ctrl_Line_State(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
                                       USB_SETUP_STRUCT * setup_packet, 
                                       uint_8_ptr *data, 
                                       uint_32 *size);
                                       
/**************************************************************************//*!
 *
 * @name  PSTN_Send_Break
 *
 * @brief  This function is called in response to Set Config request
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/ 
 extern uint_8 PSTN_Send_Break(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
                              USB_SETUP_STRUCT * setup_packet, 
                              uint_8_ptr *data, 
                              uint_32 *size);  
                              
/**************************************************************************//*!
 *
 * @name  PSTN_Get_Comm_Feature
 *
 * @brief  This function is called in response to GetCommFeature request
 *
 * @param cdc_obj_ptr :     Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
extern uint_8 PSTN_Get_Comm_Feature(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
                                    USB_SETUP_STRUCT * setup_packet,
                                    uint_8_ptr *data, 
                                    uint_32 *size);
                                    
/**************************************************************************//*!
 *
 * @name  PSTN_Set_Comm_Feature
 *
 * @brief  This function is called in response to SetCommFeature request
 *
 * @param cdc_obj_ptr :     Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
extern uint_8 PSTN_Set_Comm_Feature(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
                                    USB_SETUP_STRUCT * setup_packet,
                                    uint_8_ptr *data, 
                                    uint_32 *size);   
                                      
/**************************************************************************//*!
 *
 * @name  PSTN_Send_Serial_State
 *
 * @brief  This function is called to send serial state notification
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 *
 * @return NONE
 *****************************************************************************/ 
extern void PSTN_Send_Serial_State(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr) ;

/**************************************************************************//*!
 *
 * @name  PSTN_Response_Available
 *
 * @brief  This function is called to send notification to host that a 
 *         response is available
 *
 * @param cdc_obj_ptr   
 *
 * @return NONE
 *****************************************************************************/ 
extern void PSTN_Response_Available(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr);

#if RNDIS_SUPPORT
/**************************************************************************//*!
 *
 * @name  PSTN_Rndis_Message_Set
 *
 * @brief  This function is called in response to PSTN_Rndis_Message_Set 
 *
 * @param cdc_obj_ptr :     Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
 extern uint_8 PSTN_Rndis_Message_Set(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
                                    USB_SETUP_STRUCT * setup_packet,
                                    uint_8_ptr *data, 
                                    uint_32 *size); 
/**************************************************************************//*!
 *
 * @name  PSTN_Rndis_Message_Get
 *
 * @brief  This function is called in response to PSTN_Rndis_Message_Get
 *
 * @param cdc_obj_ptr :     Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/                                          
extern uint_8 PSTN_Rndis_Message_Get(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
                                    USB_SETUP_STRUCT * setup_packet,
                                    uint_8_ptr *data, 
                                    uint_32 *size);    
                                    

extern void RNDIS_Initialize_Command
    (
        CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
        uint_8_ptr *data, 
        uint_32 *size
    );
extern void RNDIS_Query_Command
    (
        CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
        uint_8_ptr *data, 
        uint_32 *size
    );
extern void RNDIS_Set_Command
    (
        CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
        uint_8_ptr *data, 
        uint_32 *size
    );
extern void RNDIS_Reset_Command
    (
        CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
        uint_8_ptr *data, 
        uint_32 *size
    );
extern void RNDIS_Indicate_Status_Command 
    (
        CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
        uint_8_ptr *data, 
        uint_32 *size
    );      
extern void RNDIS_Keepalive_Command
    (
        CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
        uint_8_ptr *data, 
        uint_32 *size
    );
extern void RNDIS_Halt_Command
    (
        CDC_DEVICE_STRUCT_PTR cdc_obj_ptr
    );                  
            
#endif/*endif RNDIS_SUPPORT*/


#define USB_CDC_Periodic_Task USB_Class_Periodic_Task                          

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ip-e.h<|end_filename|>
#ifndef __ipe_h__
#define __ipe_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip-e.h$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the private defines, externs and
*   data structure definitions required by the IP-E layer.
*
*END************************************************************************/

#include "ip_prv.h"


/***************************************
**
** Prototypes
**
*/

extern uint_32 IPE_open  (IP_IF_PTR);
extern uint_32 IPE_close (IP_IF_PTR);
extern uint_32 IPE_send  (IP_IF_PTR, RTCSPCB_PTR, uint_16, uchar[6] );
extern uint_32 IPE_send_IP (IP_IF_PTR, RTCSPCB_PTR, _ip_address, _ip_address, pointer);
extern uint_32 IPE_send_IP_ucast  (IP_IF_PTR, RTCSPCB_PTR, uchar[6]);
extern uint_32 IPE_send_ARP_bcast (IP_IF_PTR, RTCSPCB_PTR);
extern uint_32 IPE_send_ARP_ucast (IP_IF_PTR, RTCSPCB_PTR, uchar[6]);

extern void IPE_recv (PCB_PTR, pointer, void (_CODE_PTR_  service)(RTCSPCB_PTR));
extern void IPE_recv_IP  (PCB_PTR, pointer);
extern void IPE_recv_ARP (PCB_PTR, pointer);

extern uint_32 IPE_join  (IP_IF_PTR, _ip_address);
extern uint_32 IPE_leave (IP_IF_PTR, _ip_address);

#if RTCSCFG_ENABLE_IP6
extern uint_32 IP6E_open (IP_IF_PTR if_ptr);    /* Called by IPE_open.*/
extern uint_32 IP6E_close (IP_IF_PTR if_ptr);   /* Called by IPE_open.*/
extern void IP6E_recv_IP  (PCB_PTR, pointer);
extern uint_32 IP6E_send( IP_IF_PTR, RTCSPCB_PTR, in6_addr *, in6_addr *);
extern uint_32 IP6E_join  (IP_IF_PTR, const in6_addr *);
extern uint_32 IP6E_leave (IP_IF_PTR, const in6_addr *);
#endif /* RTCSCFG_ENABLE_IP6 */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/lwtimer.c<|end_filename|>
/*HEADER********************************************************************
 *
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: lwtimer.c$
 * $Version : 3.8.5.1$
 * $Date    : Feb-20-2012$
 *
 * Comments:
 *
 *   This file contains functions of the LWTimer component.
 *
 *END************************************************************************/

#include "mqx_inc.h"

#if MQX_USE_LWTIMER
#include "lwtimer.h"
#include "lwtimer_prv.h"

/*!
 * \brief Creates the periodic timer queue.
 *
 * \param[in] period_ptr The location of the data structure to be initialized.
 * \param[in] period     The cycle length of this timer in ticks.
 * \param[in] wait_ticks The number of ticks to wait before starting this queue.
 *
 * \return MQX_OK
 *
 * \see _lwtimer_add_timer_to_queue
 * \see _lwtimer_cancel_period
 * \see _lwtimer_cancel_timer
 * \see _lwtimer_create_periodic_queue
 * \see LWTIMER_PERIOD_STRUCT
 */
_mqx_uint _lwtimer_create_periodic_queue
(
    LWTIMER_PERIOD_STRUCT_PTR period_ptr,
    _mqx_uint                 period,
    _mqx_uint                 wait_ticks
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_lwtimer_create_periodic_queue, period_ptr, period, wait_ticks);

    period_ptr->PERIOD = period;
    period_ptr->EXPIRY = 0;
    period_ptr->WAIT   = wait_ticks;
    _QUEUE_INIT(&period_ptr->TIMERS,0);
    period_ptr->TIMER_PTR = (pointer) &period_ptr->TIMERS;

    _int_disable();
    if (kernel_data->LWTIMERS.NEXT == NULL)
    {
        /* Initialize the light weight timer queue */
        _QUEUE_INIT(&kernel_data->LWTIMERS, 0);
        kernel_data->LWTIMER_ISR = _lwtimer_isr_internal;
    } /* Endif */
    period_ptr->VALID = LWTIMER_VALID;
    _QUEUE_ENQUEUE(&kernel_data->LWTIMERS, &period_ptr->LINK);
    _int_enable();

    _KLOGX2(KLOG_lwtimer_create_periodic_queue, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Adds the lightweight timer to the periodic queue.
 *
 * This function inserts the timer in the queue in order of increasing offset
 * from the queue's start time.
 *
 * \param[in] period_ptr Pointer to the periodic queue.
 * \param[in] timer_ptr  Pointer to the lightweight timer to add to the queue,
 * must be smaller than queue.
 * \param[in] ticks      Tick offset from the timers period to expire at.
 * \param[in] func       Function to call when the timer expires.
 * \param[in] parameter  Parameter to pass to the function.
 *
 * \return MQX_OK
 * \return MQX_LWTIMER_INVALID (Period_ptr points to an invalid periodic queue.)
 * \return MQX_INVALID_PARAMETER (Ticks is greater than or equal to the
 * periodic queue's period.)
 *
 * \see _lwtimer_cancel_period
 * \see _lwtimer_cancel_timer
 * \see _lwtimer_create_periodic_queue
 * \see LWTIMER_PERIOD_STRUCT
 * \see LWTIMER_STRUCT
 */
 _mqx_uint _lwtimer_add_timer_to_queue
(
    LWTIMER_PERIOD_STRUCT_PTR period_ptr,
    LWTIMER_STRUCT_PTR        timer_ptr,
    _mqx_uint                 ticks,
    LWTIMER_ISR_FPTR          func,
    pointer                   parameter
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    LWTIMER_STRUCT_PTR     qe_ptr;
    _mqx_uint              i;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_lwtimer_add_timer_to_queue, period_ptr, timer_ptr, ticks);

#if MQX_CHECK_ERRORS
    if (period_ptr->VALID != LWTIMER_VALID)
    {
        _KLOGX2(KLOG_lwtimer_add_timer_to_queue, MQX_LWTIMER_INVALID);
        return (MQX_LWTIMER_INVALID);
    } /* Endif */
    if (ticks >= period_ptr->PERIOD)
    {
        _KLOGX2(KLOG_lwtimer_add_timer_to_queue, MQX_INVALID_PARAMETER);
        return (MQX_INVALID_PARAMETER);
    } /* Endif */
#endif

    timer_ptr->TIMER_FUNCTION = func;
    timer_ptr->PARAMETER      = parameter;
    timer_ptr->PERIOD_PTR     = period_ptr;
    timer_ptr->RELATIVE_TICKS = ticks;
    _int_disable();
    /* Insert into queue in order of increasing offset from start time */
    qe_ptr = (pointer) &period_ptr->TIMERS.NEXT;
    i = _QUEUE_GET_SIZE(&period_ptr->TIMERS) + 1;
    while (--i)
    {
        qe_ptr = (pointer) qe_ptr->LINK.NEXT;
        if (qe_ptr->RELATIVE_TICKS >= ticks)
        {
            qe_ptr = (pointer) qe_ptr->LINK.PREV;
            break;
        } /* Endif */
    } /* Endwhile */
    timer_ptr->VALID = LWTIMER_VALID;
    _QUEUE_INSERT(&period_ptr->TIMERS, qe_ptr, &timer_ptr->LINK);
    _int_enable();

    _KLOGX2(KLOG_lwtimer_add_timer_to_queue, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \private
 *
 * \brief This function checks the lwtimer queues, and if a timer is ready,
 *  calls an application function.
 */
void _lwtimer_isr_internal(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR    kernel_data;
    LWTIMER_PERIOD_STRUCT_PTR period_ptr;
    LWTIMER_STRUCT_PTR        timer_ptr;

    _GET_KERNEL_DATA(kernel_data);

    period_ptr = (pointer) kernel_data->LWTIMERS.NEXT;
    while ((pointer) period_ptr != (pointer) &kernel_data->LWTIMERS)
    {
        if (period_ptr->WAIT)
        {
            --period_ptr->WAIT;
        }
        else
        {
            timer_ptr = (pointer) period_ptr->TIMER_PTR->LINK.NEXT;
            for (; timer_ptr != (pointer) &period_ptr->TIMERS; timer_ptr = (LWTIMER_STRUCT_PTR) (pointer) timer_ptr->LINK.NEXT)
            {
                if (timer_ptr->RELATIVE_TICKS > period_ptr->EXPIRY)
                {
                    break;
                } /* Endif */
                /* Save the last timer processed */
                period_ptr->TIMER_PTR = timer_ptr;
                (*timer_ptr->TIMER_FUNCTION)(timer_ptr->PARAMETER);
            } /* Endwhile */
            if (++period_ptr->EXPIRY == period_ptr->PERIOD)
            {
                period_ptr->EXPIRY = 0;
                period_ptr->TIMER_PTR = (pointer) &period_ptr->TIMERS;
            } /* Endif */
        } /* Endif */
        period_ptr = (LWTIMER_PERIOD_STRUCT_PTR) (pointer) period_ptr->LINK.NEXT;
    } /* Endwhile */

} /* Endbody */

/*!
 * \brief Cancels an outstanding timer request.
 *
 * \param[in] timer_ptr Pointer to the lightweight timer to cancel.
 *
 * \return MQX_OK
 * \return MQX_LWTIMER_INVALID (Timer_ptr points to either an invalid timer or
 * to a timer with a periodic queue.)
 *
 * \see _lwtimer_add_timer_to_queue
 * \see _lwtimer_cancel_period
 * \see _lwtimer_create_periodic_queue
 * \see LWTIMER_STRUCT
 */
_mqx_uint _lwtimer_cancel_timer
(
    LWTIMER_STRUCT_PTR timer_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR    kernel_data;
    LWTIMER_PERIOD_STRUCT_PTR period_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwtimer_cancel_timer, timer_ptr);

#if MQX_CHECK_VALIDITY
    if (timer_ptr->VALID != LWTIMER_VALID)
    {
        _KLOGX2(KLOG_lwtimer_cancel_timer, MQX_LWTIMER_INVALID);
        return MQX_LWTIMER_INVALID;
    } /* Endif */
#endif

    period_ptr = timer_ptr->PERIOD_PTR;
    _int_disable();
#if MQX_CHECK_VALIDITY
    if (period_ptr->VALID != LWTIMER_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_lwtimer_cancel_timer, MQX_LWTIMER_INVALID);
        return MQX_LWTIMER_INVALID;
    } /* Endif */
#endif
    timer_ptr->VALID = 0;
    if (timer_ptr == period_ptr->TIMER_PTR)
    {
        period_ptr->TIMER_PTR = (pointer) timer_ptr->LINK.PREV;
    } /* Endif */
    _QUEUE_REMOVE(&period_ptr->TIMERS, timer_ptr);
    _int_enable();

    _KLOGX2(KLOG_lwtimer_cancel_timer, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Cancels all the lightweight timers in the periodic queue.
 *
 * \param[in] period_ptr Pointer to the periodic queue to cancel.
 *
 * \return MQX_OK
 * \return MQX_LWTIMER_INVALID (Period_ptr points to an invalid periodic queue.)
 *
 * \see _lwtimer_add_timer_to_queue
 * \see _lwtimer_cancel_timer
 * \see _lwtimer_create_periodic_queue
 * \see LWTIMER_PERIOD_STRUCT
 */
_mqx_uint _lwtimer_cancel_period
(
    LWTIMER_PERIOD_STRUCT_PTR period_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwtimer_cancel_period, period_ptr);

#if MQX_CHECK_VALIDITY
    if (period_ptr->VALID != LWTIMER_VALID)
    {
        _KLOGX2(KLOG_lwtimer_cancel_period, MQX_LWTIMER_INVALID);
        return MQX_LWTIMER_INVALID;
    } /* Endif */
#endif

    _int_disable();
    period_ptr->VALID = 0;
    _QUEUE_REMOVE(&kernel_data->LWTIMERS, period_ptr);
    _int_enable();

    _KLOGX2(KLOG_lwtimer_cancel_period, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Tests all the periodic queues and their lightweight timers for
 * validity and consistency.
 *
 * \param[out] period_error_ptr Pointer to the first periodic queue that has
 * an error (NULL if no error is found).
 * \param[out] timer_error_ptr  Pointer to the first timer that has an error
 * (NULL if no error is found).
 *
 * \return MQX_OK (No periodic queues have been created or no errors found
 * in any periodic queues or timers.)
 * \return MQX_LWTIMER_INVALID (Period_ptr points to an invalid periodic queue.)
 * \return Error from _queue_test() (A periodic queue or its queue was in error.)
 *
 * \see _lwtimer_add_timer_to_queue
 * \see _lwtimer_cancel_period
 * \see _lwtimer_cancel_timer
 * \see _lwtimer_create_periodic_queue
 */
 _mqx_uint _lwtimer_test
(
    pointer _PTR_ period_error_ptr,
    pointer _PTR_ timer_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR    kernel_data;
    LWTIMER_STRUCT_PTR        timer_ptr;
    LWTIMER_PERIOD_STRUCT_PTR period_ptr;
    _mqx_uint                 result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_lwtimer_test, period_error_ptr, timer_error_ptr);

    *period_error_ptr = NULL;
    *timer_error_ptr = NULL;

    /*
     * It is not considered an error if the lwtimer component has not been
     * created yet
     */
    if (kernel_data->LWTIMERS.NEXT == NULL)
    {
        return (MQX_OK);
    } /* Endif */

    result = _queue_test(&kernel_data->LWTIMERS, period_error_ptr);
    if (result != MQX_OK)
    {
        _KLOGX3(KLOG_lwtimer_test, result, *period_error_ptr);
        return (result);
    } /* Endif */

    _int_disable();
    period_ptr = (pointer) kernel_data->LWTIMERS.NEXT;
    while ((pointer) period_ptr != (pointer) &kernel_data->LWTIMERS)
    {
        if (period_ptr->VALID != LWTIMER_VALID)
        {
            _int_enable();
            *period_error_ptr = period_ptr;
            _KLOGX3(KLOG_lwtimer_test, MQX_LWTIMER_INVALID, period_ptr);
            return (MQX_LWTIMER_INVALID);
        } /* Endif */
        result = _queue_test(&period_ptr->TIMERS, timer_error_ptr);
        if (result != MQX_OK)
        {
            _int_enable();
            *period_error_ptr = period_ptr;
            _KLOGX4(KLOG_lwtimer_test, result, *period_error_ptr, *timer_error_ptr);
            return (result);
        } /* Endif */
        timer_ptr = (pointer) period_ptr->TIMERS.NEXT;
        while (timer_ptr != (pointer) &period_ptr->TIMERS)
        {
            if (timer_ptr->VALID != LWTIMER_VALID)
            {
                *period_error_ptr = period_ptr;
                *timer_error_ptr = timer_ptr;
                _KLOGX4(KLOG_lwtimer_test, MQX_LWTIMER_INVALID, period_ptr,
                                timer_ptr);
                return (MQX_LWTIMER_INVALID);
            } /* Endif */
            timer_ptr = (pointer) timer_ptr->LINK.NEXT;
        } /* Endwhile */
        period_ptr = (pointer) period_ptr->LINK.NEXT;
    } /* Endwhile */

    _int_enable();
    _KLOGX2(KLOG_lwtimer_test, MQX_OK);
    return (MQX_OK);

} /* Endbody */

#endif /* MQX_USE_LWTIMER */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb_dcd/usb_dcd_kn.h<|end_filename|>
#ifndef _usb_dcd_kn_h
#define _usb_dcd_kn_h 1

/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_dcd_kn.h$
* $Version : 3.8.1.0$
* $Date    : Jul-27-2011$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the DCD I/O functions.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** KUSB_DCD_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a USB DCD is initialized.
*/
typedef struct kusb_dcd_init_struct
{
   /* Clock speed in Khz */
   uint_32                CLOCK_SPEED;
   
   /* Sequence Initiation Time */
   uint_16                TSEQ_INIT;

   /* Time Period to Debounce D+ Signal */
   uint_16                TDCD_DBNC;
   
   /* Time Period to Comparator Enabled */
   uint_16                TVDPSRC_ON;
   
   /* Time Period Before Enabling D+ Pullup */
   uint_16                TVDPSRC_CON;
   
   /* Time Before Check of D- Line */
   uint_16                CHECK_DM;

   /* Interrupt level to use if interrupt driven */
   _int_level             LEVEL;

} KUSB_DCD_INIT_STRUCT, _PTR_ KUSB_DCD_INIT_STRUCT_PTR;

typedef const KUSB_DCD_INIT_STRUCT _PTR_ KUSB_DCD_INIT_STRUCT_CPTR;
                                           

/*--------------------------------------------------------------------------*/
/* 
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern uint_32 _kusb_dcd_polled_install (char_ptr, KUSB_DCD_INIT_STRUCT_CPTR);
extern uint_32 _kusb_dcd_int_install (char_ptr, KUSB_DCD_INIT_STRUCT_CPTR);
extern pointer _bsp_get_usb_dcd_base_address (void);
extern uint_32 _bsp_get_usb_dcd_vector (void);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/hmi_lwgpio_provider.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hmi_lwgpio_provider.c$
* $Version : 3.8.2.0$
* $Date    : Aug-14-2012$
*
* Comments:
*
*   This contains functions for lwgpio provider.
*
*END************************************************************************/
#include <mqx.h>
#include <bsp.h>
#include "hmi_lwgpio_provider.h"
#include "btnled.h"

/* static functions prototypes */
static void hmi_lwgpio_poll(HMI_PROVIDER_STRUCT_PTR);
static boolean hmi_lwgpio_set_value(HMI_PROVIDER_STRUCT_PTR, uint_32 ,uint_32);
static boolean hmi_lwgpio_get_value(HMI_PROVIDER_STRUCT_PTR, uint_32 ,uint_32_ptr);
static void hmi_lwgpio_install_interrupt(HMI_PROVIDER_STRUCT_PTR);
static void hmi_lwgpio_uninstall_interrupt(HMI_PROVIDER_STRUCT_PTR);
static void hmi_lwgpio_add(const HMI_LWGPIO_INIT_STRUCT _PTR_, HMI_LWGPIO_STRUCT_PTR);
static void hmi_lwgpio_attach_client(HMI_PROVIDER_STRUCT_PTR,HMI_CLIENT_STRUCT_PTR);

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_lwgpio_poll
* Returned Value   : void
* Comments         :
*   This function polls all LWGPIO pins and checks if actual state
*   has changed.
*
*END*--------------------------------------------------------------------*/
static void hmi_lwgpio_poll(HMI_PROVIDER_STRUCT_PTR provider_struct)
{
    _mqx_int         i;
    LWGPIO_VALUE     actual_state;
    HMI_LWGPIO_CONTEXT_STRUCT_PTR context_struct = (HMI_LWGPIO_CONTEXT_STRUCT_PTR)provider_struct->CONTEXT_PTR;
    uint_8           flag;

    for(i=0; i<context_struct->BTNLED_COUNT; i++)
    {
        /* Pull only inputs without interrupt flag */
        if(!HMI_LWGPIO_GET_DIRECTION(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG) && \
           !HMI_LWGPIO_GET_INT(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG))
        {
            /* gets actual state of the pin */
            actual_state = lwgpio_get_value(&context_struct->BTNLED_TABLE[i].HANDLE);
            if (actual_state != context_struct->BTNLED_TABLE[i].LAST_STATE)
            {
                 /* saves actual state */
                context_struct->BTNLED_TABLE[i].LAST_STATE = actual_state;
                /* check if actual state is equal to active state */
                if (actual_state == HMI_LWGPIO_GET_ACTIVE_STATE(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG))
                {
                    flag = HMI_VALUE_PUSH;
                }
                else
                {
                    flag = HMI_VALUE_RELEASE;
                }
                context_struct->CLIENT_HANDLE->ON_CHANGE(context_struct->CLIENT_HANDLE, context_struct->BTNLED_TABLE[i].INIT_STRUCT.UID, flag);
            }
        }
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_lwgpio_set_value
* Returned Value   : boolean
* Comments         :
*   This function sets value to LWGPIO pin.
*
*END*--------------------------------------------------------------------*/
static boolean hmi_lwgpio_set_value(HMI_PROVIDER_STRUCT_PTR provider_struct, uint_32 uid, uint_32 value)
{
    _mqx_int                        i;
    boolean                         result = FALSE;
    HMI_LWGPIO_CONTEXT_STRUCT_PTR   context_struct = (HMI_LWGPIO_CONTEXT_STRUCT_PTR) provider_struct->CONTEXT_PTR;

    for(i=0; i<context_struct->BTNLED_COUNT; i++)
    {
        if(context_struct->BTNLED_TABLE[i].INIT_STRUCT.UID == uid)
        {
            result = TRUE;
            if(value == HMI_VALUE_ON)
            {
                lwgpio_set_value(&(context_struct->BTNLED_TABLE[i].HANDLE), \
                    (LWGPIO_VALUE)HMI_LWGPIO_GET_ACTIVE_STATE(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG));
            }
            else if(value == HMI_VALUE_OFF)
            {
                lwgpio_set_value(&context_struct->BTNLED_TABLE[i].HANDLE, \
                    (LWGPIO_VALUE)!HMI_LWGPIO_GET_ACTIVE_STATE(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG));
            }
        context_struct->BTNLED_TABLE[i].LAST_STATE = (LWGPIO_VALUE)value;
        }
    }
    return result;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_lwgpio_get_value
* Returned Value   : boolean
* Comments         :
*   This function gets value from LWGPIO pin and returns TRUE if the pin
*   exists.
*
*END*--------------------------------------------------------------------*/
static boolean hmi_lwgpio_get_value(HMI_PROVIDER_STRUCT_PTR provider_struct, uint_32 uid, uint_32_ptr value)
{
    _mqx_int    i;
    uint_32     max_value = 0;
    boolean     result = FALSE;
    HMI_LWGPIO_CONTEXT_STRUCT_PTR context_struct = (HMI_LWGPIO_CONTEXT_STRUCT_PTR)provider_struct->CONTEXT_PTR;

    for(i=0; i<context_struct->BTNLED_COUNT; i++)
    {
        if (context_struct->BTNLED_TABLE[i].INIT_STRUCT.UID == uid)
        {
            *value = 0;
        }
    }
    for(i=0; i<context_struct->BTNLED_COUNT; i++)
    {
        if (context_struct->BTNLED_TABLE[i].INIT_STRUCT.UID == uid)
        {
            result = TRUE;
            max_value = lwgpio_get_value(&context_struct->BTNLED_TABLE[i].HANDLE);
            if (max_value == HMI_LWGPIO_GET_ACTIVE_STATE(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG))
            {
                max_value = HMI_VALUE_ON;
            }
            else
            {
                max_value = HMI_VALUE_OFF;
            }
            if(*value < max_value)
            {
                *value = max_value;
            }
        }
    }
    return result;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_lwgpio_isr
* Returned Value   : void
* Comments         :
*   This function is LWGPIO interrupt service routine.
*
*
*END*--------------------------------------------------------------------*/
static void hmi_lwgpio_isr(pointer provider_struct)
{
    _mqx_int        i=0;
    LWGPIO_VALUE    actual_state;
    uint_8          flag;
    
    HMI_LWGPIO_CONTEXT_STRUCT_PTR context_struct = (HMI_LWGPIO_CONTEXT_STRUCT_PTR)((HMI_PROVIDER_STRUCT_PTR)provider_struct)->CONTEXT_PTR;

    for(i=0; i<context_struct->BTNLED_COUNT; i++)
    {
        if ((((HMI_PROVIDER_STRUCT_PTR)provider_struct)->INSTALL_INTERRUPT_PTR != NULL) && lwgpio_int_get_flag(&context_struct->BTNLED_TABLE[i].HANDLE))
        {
            lwgpio_int_clear_flag(&context_struct->BTNLED_TABLE[i].HANDLE);
            actual_state = lwgpio_get_value(&context_struct->BTNLED_TABLE[i].HANDLE);
            /* check if actual state is equal to active state */
            if (actual_state == HMI_LWGPIO_GET_ACTIVE_STATE(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG))    
            {
                flag = HMI_VALUE_PUSH;
            }
            else
            {
                flag = HMI_VALUE_RELEASE;
            }
            context_struct->CLIENT_HANDLE->ON_CHANGE(context_struct->CLIENT_HANDLE, context_struct->BTNLED_TABLE[i].INIT_STRUCT.UID, flag);
        }
    }
}
/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_lwgpio_attach_client
* Returned Value   : void
* Comments         :
*    This function attaches a client to a provider.
*
*END*--------------------------------------------------------------------*/
static void hmi_lwgpio_attach_client(HMI_PROVIDER_STRUCT_PTR provider_struct, HMI_CLIENT_STRUCT_PTR client_struct)
{
    HMI_LWGPIO_CONTEXT_STRUCT_PTR context = (HMI_LWGPIO_CONTEXT_STRUCT_PTR)provider_struct->CONTEXT_PTR;
    
    /* attach client to provider */
    context->CLIENT_HANDLE = client_struct;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_lwgpio_install_interrupt
* Returned Value   : void
* Comments         :
*   This function install interrupt.
*
*END*--------------------------------------------------------------------*/
static void hmi_lwgpio_install_interrupt(HMI_PROVIDER_STRUCT_PTR provider_struct)
{
    HMI_LWGPIO_CONTEXT_STRUCT_PTR context_struct = (HMI_LWGPIO_CONTEXT_STRUCT_PTR) provider_struct->CONTEXT_PTR;
    _mqx_int    i;

    /* install interrupt if there's any requested */
    for (i=0; i<context_struct->BTNLED_COUNT; i++)
    {
        if (!HMI_LWGPIO_GET_DIRECTION(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG) && \
                HMI_LWGPIO_GET_INT(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG))
        {
            lwgpio_int_init(&context_struct->BTNLED_TABLE[i].HANDLE,LWGPIO_INT_MODE_RISING | LWGPIO_INT_MODE_FALLING);     /* falling,raising mode = 3 */
            context_struct->BTNLED_TABLE[i].INIT_ISR = _int_install_isr(lwgpio_int_get_vector(&context_struct->BTNLED_TABLE[i].HANDLE), hmi_lwgpio_isr, provider_struct);
            _bsp_int_init(lwgpio_int_get_vector(&context_struct->BTNLED_TABLE[i].HANDLE), 3, 0, TRUE);
            lwgpio_int_enable(&context_struct->BTNLED_TABLE[i].HANDLE, TRUE);
        }
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_lwgpio_uninstall_interrupt
* Returned Value   : void
* Comments         :
*   This function uninstall interrupt.
*
*END*--------------------------------------------------------------------*/
static void  hmi_lwgpio_uninstall_interrupt(HMI_PROVIDER_STRUCT_PTR provider_struct)
{
    _mqx_int    i;
    HMI_LWGPIO_CONTEXT_STRUCT_PTR context_struct = (HMI_LWGPIO_CONTEXT_STRUCT_PTR) provider_struct->CONTEXT_PTR;


    /* remove interrupt if there's any */
    for (i=0; i<context_struct->BTNLED_COUNT; i++)
    {
        if (!HMI_LWGPIO_GET_DIRECTION(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG) && \
                HMI_LWGPIO_GET_INT(context_struct->BTNLED_TABLE[i].INIT_STRUCT.FLAG))
        {
            _int_install_isr(lwgpio_int_get_vector(&context_struct->BTNLED_TABLE[i].HANDLE), context_struct->BTNLED_TABLE[i].INIT_ISR, NULL);
            /* disable bsp int */
            _bsp_int_init(lwgpio_int_get_vector(&context_struct->BTNLED_TABLE[i].HANDLE), 3, 0, FALSE);     
            /* disable LWGPIO int */
            lwgpio_int_enable(&context_struct->BTNLED_TABLE[i].HANDLE, FALSE);
        }
    }
}
/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_lwgpio_add
* Returned Value   : void
* Comments         :
*   This function adds BTN / LED.
*
*END*--------------------------------------------------------------------*/
static void hmi_lwgpio_add(const HMI_LWGPIO_INIT_STRUCT _PTR_ init_struct, HMI_LWGPIO_STRUCT_PTR btnled_struct)
{    
    /* save data from init table to context struct */
    btnled_struct->INIT_STRUCT.PID = init_struct->PID;
    btnled_struct->INIT_STRUCT.UID = init_struct->UID;
    btnled_struct->INIT_STRUCT.FLAG = init_struct->FLAG;
    btnled_struct->INIT_STRUCT.FUNC = init_struct->FUNC;
    lwgpio_init(&btnled_struct->HANDLE, \
                btnled_struct->INIT_STRUCT.PID, \
                (LWGPIO_DIR)HMI_LWGPIO_GET_DIRECTION(btnled_struct->INIT_STRUCT.FLAG), \
                (LWGPIO_VALUE)HMI_LWGPIO_GET_ACTIVE_STATE(btnled_struct->INIT_STRUCT.FLAG));

    if(!HMI_LWGPIO_GET_DIRECTION(init_struct->FLAG) && HMI_LWGPIO_GET_PULL_UP(init_struct->FLAG))
    {
        lwgpio_set_attribute(&btnled_struct->HANDLE, LWGPIO_ATTR_PULL_UP, LWGPIO_AVAL_ENABLE);
    }
    else if(!HMI_LWGPIO_GET_DIRECTION(init_struct->FLAG) && HMI_LWGPIO_GET_PULL_DOWN(init_struct->FLAG))
    {
        lwgpio_set_attribute(&btnled_struct->HANDLE, LWGPIO_ATTR_PULL_DOWN, LWGPIO_AVAL_ENABLE);
    }

    lwgpio_set_functionality(&btnled_struct->HANDLE, btnled_struct->INIT_STRUCT.FUNC);
    _time_delay(5);        /* needs time to enable pull up */
    btnled_struct->LAST_STATE = lwgpio_get_value(&btnled_struct->HANDLE);
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : _hmi_lwgpio_provider_init
* Returned Value   : HMI_PROVIDER_STRUCT_PTR
* Comments         :
*   This function initializes LWGPIO provider.
*
*END*--------------------------------------------------------------------*/
HMI_PROVIDER_STRUCT_PTR hmi_lwgpio_provider_init(const HMI_LWGPIO_INIT_STRUCT _PTR_ init_table)
{
    _mqx_uint                       i = 0;
    HMI_PROVIDER_STRUCT_PTR         provider_struct;
    HMI_LWGPIO_CONTEXT_STRUCT_PTR   context_struct;

    provider_struct = _mem_alloc_system(sizeof(HMI_PROVIDER_STRUCT));
    if(provider_struct == NULL)
    {
        return NULL;
    }

    context_struct = _mem_alloc_system(sizeof(HMI_LWGPIO_CONTEXT_STRUCT));
    if(context_struct == NULL)
    {
        _mem_free(provider_struct);
        return NULL;
    }
    while(init_table[i].UID != 0)
    {
        i++;
    }
    /* number of buttons and leds */
    context_struct->BTNLED_COUNT = i;
    context_struct->CLIENT_HANDLE = NULL;
    context_struct->BTNLED_TABLE = _mem_alloc_system_zero((context_struct->BTNLED_COUNT)*sizeof(HMI_LWGPIO_STRUCT));
    if (context_struct->BTNLED_TABLE == NULL)
    {
        _mem_free(provider_struct);
        _mem_free(context_struct);
        return NULL;
    }
    i=0;

    provider_struct->POLL_PTR = (void (_CODE_PTR_ )(pointer))hmi_lwgpio_poll;
    provider_struct->GET_VALUE_PTR = (boolean(_CODE_PTR_)(pointer, uint_32, uint_32_ptr))hmi_lwgpio_get_value;
    provider_struct->SET_VALUE_PTR = (boolean(_CODE_PTR_)(pointer, uint_32, uint_32))hmi_lwgpio_set_value;
    provider_struct->ATTACH_CLIENT = (void(_CODE_PTR_)(pointer, pointer ))hmi_lwgpio_attach_client;
    provider_struct->INSTALL_INTERRUPT_PTR = (void(_CODE_PTR_)(pointer ))hmi_lwgpio_install_interrupt;
    provider_struct->UNINSTALL_INTERRUPT_PTR = (void(_CODE_PTR_)(pointer))hmi_lwgpio_uninstall_interrupt;
    while(init_table[i].UID != 0)
    {
        hmi_lwgpio_add(&init_table[i], &context_struct->BTNLED_TABLE[i]);
        i++;
    }
    provider_struct->CONTEXT_PTR = context_struct;
    return provider_struct;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : _hmi_lwgpio_provider_deinit
* Returned Value   : HMI_PROVIDER_STRUCT_PTR
* Comments         :
*   This function deallocate all resources.
*
*END*--------------------------------------------------------------------*/
uint_32 hmi_lwgpio_provider_deinit(HMI_PROVIDER_STRUCT_PTR provider)
{
    uint_32 result = MQX_OK;
    HMI_LWGPIO_CONTEXT_STRUCT_PTR context_struct = (HMI_LWGPIO_CONTEXT_STRUCT_PTR) (provider)->CONTEXT_PTR;

    result = _mem_free(context_struct->BTNLED_TABLE);
    if(result != MQX_OK)
    {
        return result;
    }
    result = _mem_free((provider)->CONTEXT_PTR);
    if(result != MQX_OK)
    {
        return result;
    }
    (provider) = NULL;
    return result;
}


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_rw.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_rw.c$
* $Version : 3.8.19.0$
* $Date    : Oct-2-2012$
*
* Comments:
*
*   This file contains the functions that are used to read and write to the 
*   device under MFS. 
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>


#include "mfs.h"
#include "mfs_prv.h"
#include "part_mgr.h"


#if !MFSCFG_READ_ONLY

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Write_device_sectors
* Returned Value   :  error_code
* Comments  :
*     Reads or writes consecutive sectors.
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Write_device_sectors
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32                 sector_number,  /*[IN] first sector to read/write from/to file system medium */
    uint_32                 sector_count,   /*[IN] number of sectors to read/write from/to file system medium */
    uint_32                 max_retries,    /*[IN] number of retries of the same low level operation if it fails */ 
    char_ptr                buffer_ptr,     /*[IN/OUT] address of where data is to be stored/written */
    uint_32_ptr             processed       /*[OUT] number of sector successfully processed */
    )
{
    uint_32    attempts;
    int_32     num, expect_num, seek_loc, shifter;
    char_ptr   data_ptr;
    _mfs_error error;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error = MFS_NO_ERROR;

    MFS_LOG(printf("MFS_Write_device_sector %d\n", sector_number));

    if ( sector_number > drive_ptr->BPB.MEGA_SECTORS )
    {
        return(MFS_SECTOR_NOT_FOUND);
    }

    if ( drive_ptr->BLOCK_MODE )
    {
        shifter    = 0;
        seek_loc   = sector_number;
        expect_num = sector_count;
    }
    else
    {
        shifter    = drive_ptr->SECTOR_POWER;
        seek_loc   = sector_number << shifter;
        expect_num = sector_count << shifter;
    }  

    fseek(drive_ptr->DEV_FILE_PTR, seek_loc, IO_SEEK_SET);

    data_ptr = buffer_ptr;
    attempts = 0;
    while ( expect_num > 0 && attempts <= max_retries)
    {
        num = write(drive_ptr->DEV_FILE_PTR, data_ptr, expect_num);
        if ( num == IO_ERROR )
        {
            error = IO_ERROR_WRITE;
            break;
        }
        if ( num > 0 )
        {
            expect_num -= num;
            data_ptr += num << (drive_ptr->SECTOR_POWER - shifter);
            attempts = 0; /* there is a progress, reset attempts counter */
        }
        attempts++;
    }  

    if ( expect_num > 0 )
    {
        error = drive_ptr->DEV_FILE_PTR->ERROR;
    }
    else if (drive_ptr->READBACK_SECTOR_PTR) 
    {
        fseek(drive_ptr->DEV_FILE_PTR, seek_loc, IO_SEEK_SET);
        
        data_ptr = buffer_ptr;        
        expect_num = sector_count << shifter;
        while ( expect_num > 0 )
        {
            num = read(drive_ptr->DEV_FILE_PTR, drive_ptr->READBACK_SECTOR_PTR, 1<<shifter);
            if ( num != (1<<shifter) )
            {
                error = drive_ptr->DEV_FILE_PTR->ERROR;
                break;
            } 
            if ( memcmp(data_ptr, drive_ptr->READBACK_SECTOR_PTR, drive_ptr->BPB.SECTOR_SIZE) != 0 ) 
            {
                error = IO_ERROR_WRITE;
                break;
            }
            expect_num -= num;
            data_ptr += num << (drive_ptr->SECTOR_POWER - shifter);
        }
    }    
    
    switch ( error )
    {
        case IO_ERROR_WRITE_PROTECTED:
            error = MFS_DISK_IS_WRITE_PROTECTED;
            break;

        case IO_ERROR_WRITE:
            error = MFS_WRITE_FAULT;
            break;

        case IO_ERROR_WRITE_ACCESS:
            error = MFS_SECTOR_NOT_FOUND;
            break;

        case IO_ERROR_READ:
            error = MFS_READ_FAULT;
            break;

        case IO_ERROR_READ_ACCESS:
            error = MFS_SECTOR_NOT_FOUND;
            break;

        case MFS_NO_ERROR:
            /* Ensure that error code is always set if less than requested data was written */
            if ( expect_num > 0 ) error = MFS_WRITE_FAULT;
            break;

        default:
            break;
    }  

    if (processed)
        *processed = ((sector_count<<shifter) - expect_num) >> shifter;  
        
    return error;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Write_device_sector
* Returned Value   :  error_code
* Comments  :
*     Write one sector to the device
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Write_device_sector
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32                 sector_number,  /*[IN] sector number to read/write from/to file system medium */
    char_ptr                sector_ptr      /*[IN/OUT] address of where data is to be stored/written */
    )
{
    return MFS_Write_device_sectors(drive_ptr, sector_number, 1, MFSCFG_MAX_WRITE_RETRIES, sector_ptr, NULL);
}  

#endif


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Read_device_sectors
* Returned Value   :  error_code
* Comments  :
*     Reads consecutive sectors into given buffer
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Read_device_sectors
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32                 sector_number,  /*[IN] first sector to read/write from/to file system medium */
    uint_32                 sector_count,   /*[IN] number of sectors to read/write from/to file system medium */
    uint_32                 max_retries,    /*[IN] number of retries of the same low level operation if it fails */ 
    char_ptr                buffer_ptr,     /*[IN/OUT] address of where data is to be stored/written */          
    uint_32_ptr             processed       /*[OUT] number of sector successfully processed */
    )
{
    uint_32    attempts;
    int_32     num, expect_num, shifter, seek_loc;
    _mfs_error error;

    error = MFS_NO_ERROR;

    if ( sector_number+sector_count-1 > drive_ptr->BPB.MEGA_SECTORS )
    {
        return(MFS_SECTOR_NOT_FOUND);
    }

    MFS_LOG(printf("MFS_Read_device_sectors %d %d", sector_number, sector_count));

    if ( drive_ptr->BLOCK_MODE )
    {
        shifter    = 0;
        seek_loc   = sector_number;
        expect_num = sector_count;
    }
    else
    {
        shifter    = drive_ptr->SECTOR_POWER;
        seek_loc   = sector_number << shifter;
        expect_num = sector_count << shifter;
    }  

    fseek(drive_ptr->DEV_FILE_PTR, seek_loc, IO_SEEK_SET);

    attempts = 0;
    while ( expect_num > 0 && attempts <= max_retries )
    {
        num = read(drive_ptr->DEV_FILE_PTR, buffer_ptr, expect_num);
        if ( num == IO_ERROR )
        {
            error = IO_ERROR_READ;
            break;
        }
        if ( num > 0 )
        {
            expect_num -= num;
            buffer_ptr += num << (drive_ptr->SECTOR_POWER - shifter);
            attempts = 0; /* there is a progress, reset attempts counter */
        }
        attempts++;
    }  

    if ( expect_num > 0 )
    {
        error = drive_ptr->DEV_FILE_PTR->ERROR;
    }

    if ( error == IO_ERROR_READ )
    {
        error = MFS_READ_FAULT;
    }
    else if ( error == IO_ERROR_READ_ACCESS )
    {
        error = MFS_SECTOR_NOT_FOUND;
    }
    else if ( (error == MFS_NO_ERROR) && (expect_num > 0) )
    {
        /* Ensure that error code is always set if less than requested data was read */
        error = MFS_READ_FAULT;
    }

    if (processed)
        *processed = ((sector_count<<shifter) - expect_num) >> shifter;  

    return error;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Read_device_sector
* Returned Value   :  error_code
* Comments  :
*     Reads one sector from the device
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Read_device_sector
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32                 sector_number,  /*[IN] sector number to read/write from/to file system medium */
    char_ptr                sector_ptr      /*[IN/OUT] address of where data is to be stored/written */
    )
{
    return MFS_Read_device_sectors(drive_ptr, sector_number, 1, MFSCFG_MAX_READ_RETRIES, sector_ptr, NULL);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Invalidate_directory_sector
* Returned Value   :  error_code
* Comments  :
*     Invalidates the cached sector.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Invalidate_directory_sector
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr   /*[IN] the drive on which to operate */
    )
{
#if MFSCFG_READ_ONLY
    return MFS_NO_ERROR;
#else

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_NO_ERROR;
    }
#endif

    drive_ptr->DIR_SECTOR_NUMBER = MAX_UINT_32;
    drive_ptr->DIR_SECTOR_DIRTY=FALSE;
    return MFS_NO_ERROR;
#endif
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Flush_directory_sector_buffer
* Returned Value   :  MFS error code
* Comments  :
*   Write the sector buffer back to the disk.
*   Assumes the semaphore is already obtained.
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Flush_directory_sector_buffer
    (
    MFS_DRIVE_STRUCT_PTR  drive_ptr
    )
{
#if MFSCFG_READ_ONLY
    return MFS_NO_ERROR;
#else
    _mfs_error   error_code= MFS_NO_ERROR;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return error_code;
    }
#endif

    if ( drive_ptr->DIR_SECTOR_DIRTY )
    {
        error_code = MFS_Write_device_sector(drive_ptr,drive_ptr->DIR_SECTOR_NUMBER,drive_ptr->DIR_SECTOR_PTR);
        drive_ptr->DIR_SECTOR_DIRTY = FALSE;
    }

    return(error_code);
#endif
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Read_directory_sector
* Returned Value   :  MFS pointer
* Comments  :
*   Reads ONE sector in the sector_buffer.
*   This function cannot read any sectors before the root directory.
*   The semaphore is assumed to be obtained.
*
*END*---------------------------------------------------------------------*/

pointer MFS_Read_directory_sector
    (
    MFS_DRIVE_STRUCT_PTR  drive_ptr,
    uint_32         cluster,        /*[IN] number of the cluster containing the sector to be read */
    uint_16         sector,         /*[IN] index of the sector within the cluster */
    _mfs_error_ptr  error_ptr
    )
{
    uint_32   abs_sector;

    if ( cluster == 0 )
    {
        /*
        ** Reading the root directory
        */
        abs_sector = drive_ptr->ROOT_START_SECTOR+sector;
        /*
        ** Overflow...
        */
        if ( abs_sector >= drive_ptr->DATA_START_SECTOR )
        {
            *error_ptr = MFS_Flush_directory_sector_buffer(drive_ptr);
            drive_ptr->DIR_SECTOR_NUMBER = 0;
            return(NULL);
        }
    }
    else
    {
        abs_sector = CLUSTER_TO_SECTOR(cluster) + sector;
    }  

    if ( abs_sector > drive_ptr->BPB.MEGA_SECTORS )
    {
        *error_ptr = MFS_Flush_directory_sector_buffer(drive_ptr);
        return(NULL);
    }

    if ( abs_sector != drive_ptr->DIR_SECTOR_NUMBER )
    {
        *error_ptr = MFS_Flush_directory_sector_buffer(drive_ptr);
        if ( *error_ptr )
        {
            return(NULL);
        }
        *error_ptr = MFS_Read_device_sector(drive_ptr, abs_sector, drive_ptr->DIR_SECTOR_PTR);
        if ( *error_ptr )
        {
            MFS_Invalidate_directory_sector(drive_ptr);
            return( NULL );
        }
        drive_ptr->DIR_SECTOR_NUMBER = abs_sector;
    }
    else
    {
        *error_ptr = MFS_NO_ERROR;
    }  

    return(drive_ptr->DIR_SECTOR_PTR);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Flush_caches
* Returned Value   : error code
* Comments  :
*     Turns the write cache on or off.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Flush_caches
    (
    MFS_DRIVE_STRUCT_PTR  drive_ptr
    )
{
#if MFSCFG_READ_ONLY
    return MFS_NO_ERROR;
#else
    _mfs_error        error_code, return_code = MFS_NO_ERROR;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return return_code;
    }
#endif

    return_code = MFS_Flush_directory_sector_buffer(drive_ptr);
    error_code = MFS_Flush_data_sector_buffer(drive_ptr);
    if ( return_code == MFS_NO_ERROR ) return_code = error_code;
    error_code = MFS_Flush_fat_cache(drive_ptr);
    if ( return_code == MFS_NO_ERROR ) return_code = error_code;

    return(return_code);
#endif   
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hwtimer/hwtimer.h<|end_filename|>
#ifndef __hwtimer_h__
#define __hwtimer_h__
/*HEADER********************************************************************
 *
 * Copyright (c) 2013 Freescale Semiconductor;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: hwtimer.h$
 * $Version : 4.0.1$
 * $Date : Jan-18-2013$
 *
 * Comments:
 *
 *   This include file is used to define constants and data types for the
 *   hwtimer component
 *
 *END************************************************************************/

#include <mqx.h>

#define HWTIMER_LL_CONTEXT_LEN 5
/* Type definitions */

typedef void  (_CODE_PTR_  HWTIMER_CALLBACK_FPTR)(pointer);
/*!
 * \brief hwtimer structure.
 *
 * This structure defines a hwtimer.
 * The context structure is passed to all API functions (besides other parameters).
 *
 * \warning Application should not access members of this structure directly.
 *
 * \see hwtimer_init
 * \see hwtimer_deinit
 * \see hwtimer_start
 * \see hwtimer_stop
 * \see hwtimer_set_freq
 * \see hwtimer_get_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 * \see hwtimer_callback_reg
 * \see hwtimer_callback_block
 * \see hwtimer_callback_unblock
 * \see hwtimer_callback_cancel
 */
typedef struct hwtimer
{
    /*! \brief Pointer to device interface structure */
    const struct hwtimer_devif_struct *   devif;
    /*! \brief Clock identifier used for obtaining timer's source clock. */
    uint_32                         clock_id;
    /*! \brief Actual total divider */
    uint_32                         divider;
    /*! \brief Determine how many subticks are in one tick */
    uint_32                         modulo;
    /*! \brief Number of elapsed ticks */
    volatile uint_64                ticks;
    /*! \brief Function pointer to be called when the timer expires. */
    HWTIMER_CALLBACK_FPTR           callback_func;
    /*! \brief Arbitrary pointer passed as parameter to the callback function. */
    pointer                         callback_data;
    /*! \brief Indicate pending callback. 
     *  If the timer overflows when callbacks are blocked the callback becomes pending. */
    volatile int                    callback_pending;
    /*! \brief Indicate blocked callback */
    int                             callback_blocked;
    /*! \brief Private storage locations for arbitrary data keeping the context of the lower layer driver */
    uint_32                         ll_context[HWTIMER_LL_CONTEXT_LEN];
} HWTIMER, _PTR_ HWTIMER_PTR;

/*!
 * \brief hwtimer_time structure.
 *
 * hwtimer time structure represents a timestamp consisting of timer elapsed periods (TICKS) and current value of the timer counter (SUBTICKS).
 *
 * \see hwtimer_get_time
 */
typedef struct hwtimer_time_struct
{
    /*! \brief Ticks of timer */
    uint_64 TICKS;
    /*! \brief Subticks of timer */
    uint_32 SUBTICKS;
} HWTIMER_TIME_STRUCT, _PTR_ HWTIMER_TIME_PTR;

typedef _mqx_int (_CODE_PTR_  HWTIMER_DEVIF_INIT_FPTR)(HWTIMER_PTR, uint_32, uint_32);
typedef _mqx_int (_CODE_PTR_  HWTIMER_DEVIF_DEINIT_FPTR)(HWTIMER_PTR);
typedef _mqx_int (_CODE_PTR_  HWTIMER_DEVIF_SET_DIV_FPTR)(HWTIMER_PTR, uint_32);
typedef _mqx_int (_CODE_PTR_  HWTIMER_DEVIF_START_FPTR)(HWTIMER_PTR);
typedef _mqx_int (_CODE_PTR_  HWTIMER_DEVIF_STOP_FPTR)(HWTIMER_PTR);
typedef _mqx_int (_CODE_PTR_  HWTIMER_DEVIF_RESET_FPTR)(HWTIMER_PTR);
typedef _mqx_int (_CODE_PTR_  HWTIMER_DEVIF_GET_TIME_FPTR)(HWTIMER_PTR, HWTIMER_TIME_PTR);

/*!
 * \brief hwtimer_devif structure.
 *
 * Each low layer driver exports instance of this structure initialized with pointers to API functions the driver implements.
 * The functions themselves should be declared as static (not exported directly).
 *
 * \see hwtimer_init
 * \see hwtimer_deinit
 */
typedef struct hwtimer_devif_struct
{
     /*! \brief Function pointer to lower layer initialization */
    HWTIMER_DEVIF_INIT_FPTR             INIT;
     /*! \brief Function pointer to lower layer de-initialization */
    HWTIMER_DEVIF_DEINIT_FPTR           DEINIT;
     /*! \brief Function pointer to lower layer set divider functionality */
    HWTIMER_DEVIF_SET_DIV_FPTR          SET_DIV;
     /*! \brief Function pointer to lower layer start functionality */
    HWTIMER_DEVIF_START_FPTR            START;
     /*! \brief Function pointer to lower layer stop functionality */
    HWTIMER_DEVIF_STOP_FPTR             STOP;
     /*! \brief Function pointer to lower layer get time functionality */
    HWTIMER_DEVIF_GET_TIME_FPTR         GET_TIME;
} HWTIMER_DEVIF_STRUCT, _PTR_ HWTIMER_DEVIF_STRUCT_PTR;


/* Function prototypes */
_mqx_int hwtimer_init(HWTIMER_PTR, const HWTIMER_DEVIF_STRUCT *, uint_32, uint_32);
_mqx_int hwtimer_deinit(HWTIMER_PTR);
_mqx_int hwtimer_set_freq(HWTIMER_PTR, uint_32, uint_32);
_mqx_int hwtimer_set_period(HWTIMER_PTR, uint_32, uint_32);
uint_32 hwtimer_get_freq(HWTIMER_PTR);
uint_32 hwtimer_get_period(HWTIMER_PTR);
_mqx_int hwtimer_start(HWTIMER_PTR);
_mqx_int hwtimer_stop(HWTIMER_PTR);
_mqx_int hwtimer_reset(HWTIMER_PTR);
uint_32 hwtimer_get_modulo(HWTIMER_PTR);
_mqx_int hwtimer_get_time(HWTIMER_PTR, HWTIMER_TIME_PTR);
uint_32 hwtimer_get_ticks(HWTIMER_PTR);
_mqx_int hwtimer_callback_reg(HWTIMER_PTR, HWTIMER_CALLBACK_FPTR, pointer);
_mqx_int hwtimer_callback_block(HWTIMER_PTR);
_mqx_int hwtimer_callback_unblock(HWTIMER_PTR);
_mqx_int hwtimer_callback_cancel(HWTIMER_PTR);

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pccard/pccardflexbuspr.h<|end_filename|>
#ifndef _pccardflexbuspr_h_
#define _pccardflexbuspr_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pccardflexbuspr.h$
* $Version : 3.8.10.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   The file contains the structure definitions
*   private to the PC Card FlexbBus
*
*END************************************************************************/

/* default options */
#ifndef BSP_PCCARDFLEXBUS_WIDTH
#define BSP_PCCARDFLEXBUS_WIDTH              1
#endif

#ifndef BSP_PCCARDFLEXBUS_ADDR_SHIFT
#define BSP_PCCARDFLEXBUS_ADDR_SHIFT         0
#endif

#ifndef BSP_PCCARDFLEXBUS_CARD_PRESENT
#define BSP_PCCARDFLEXBUS_CARD_PRESENT       229
#endif

#ifndef BSP_PCCARDFLEXBUS_SLOT_EMPTY
#define BSP_PCCARDFLEXBUS_SLOT_EMPTY         173
#endif

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#define PCCARDFLEXBUS_REGISTER_MASK          (0x00000000<<BSP_PCCARDFLEXBUS_ADDR_SHIFT)
#define PCCARDFLEXBUS_COMMON_MEM_MASK        (0x00001000<<BSP_PCCARDFLEXBUS_ADDR_SHIFT)
#define PCCARDFLEXBUS_CARD_PRESENT_MASK      (0x00002000<<BSP_PCCARDFLEXBUS_ADDR_SHIFT)



/*
** Timing parameters
*/

/* Minimum time to wait from VCC application to when the card is ready (ms) */
#define PCCARDFLEXBUS_RESET_ALLOWED_TIME  (300 + BSP_ALARM_RESOLUTION)

/* 
** State conditions 
*/
#define PCCARDFLEXBUS_CARD_REMOVED    0
#define PCCARDFLEXBUS_CARD_INSERTED   1
#define PCCARDFLEXBUS_ACCESS_ALLOWED  5


/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/

/*
** Run time state information for a PC Card slot
*/
typedef struct io_pccardflexbus_struct
{
   PCCARDFLEXBUS_INIT_STRUCT INIT_DATA;
   boolean                CARD_IN;
   uint_32                STATE;
   volatile uchar _PTR_   PCMCIA_BASE;
   volatile uchar _PTR_   ATTRIB_PTR;
   TIME_STRUCT            START_TIME;
} IO_PCCARDFLEXBUS_STRUCT, _PTR_ IO_PCCARDFLEXBUS_STRUCT_PTR;


#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_pccardflexbus_open(FILE_DEVICE_STRUCT_PTR, char _PTR_, char _PTR_);
extern _mqx_int _io_pccardflexbus_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_pccardflexbus_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);

extern boolean   _io_pccardflexbus_card_detect(IO_PCCARDFLEXBUS_STRUCT_PTR);
extern uint_32   _io_pccardflexbus_read_tuple(volatile uchar _PTR_, uint_32, uchar_ptr);
extern void      _io_pccardflexbus_card_wait_till_ready(IO_PCCARDFLEXBUS_STRUCT_PTR);
extern void      _io_pccardflexbus_wait(IO_PCCARDFLEXBUS_STRUCT_PTR, uint_32);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/sockutil.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sockutil.c$
* $Version : 3.8.10.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*   This file contains utility functions for managing
*   socket structures.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "tcp_prv.h"
#include "socket.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_Get_sock_struct
* Returned Value  : none
* Comments        : Get a socket structure, initialize it and return
*                     address of socket.
*
*END*-----------------------------------------------------------------*/

SOCKET_STRUCT_PTR   SOCK_Get_sock_struct
   (
      RTCS_SOCKET_CALL_STRUCT_PTR   type,
      _rtcs_taskid                  owner

   )
{ /* Body */
   RTCS_DATA_PTR              RTCS_data_ptr;
   SOCKET_CONFIG_STRUCT_PTR   socket_cfg_ptr;
   SOCKET_STRUCT_PTR          socket_ptr;

   RTCS_data_ptr = RTCS_get_data();
   socket_cfg_ptr = RTCS_data_ptr->SOCKET_CFG;

   socket_ptr = RTCS_part_alloc_zero(RTCS_data_ptr->RTCS_socket_partition);

   if ( socket_ptr != NULL ) {

      RTCS_mutex_lock(&socket_cfg_ptr->SOCK_MUTEX);
      socket_cfg_ptr->CURRENT_SOCKETS++;

      SOCK_Add_owner(socket_ptr, owner);

      /*
      ** link in this socket into the linked list of active sockets
      */
      if ( socket_cfg_ptr->SOCKET_HEAD != NULL ) {

         ((SOCKET_STRUCT_PTR)socket_cfg_ptr->SOCKET_TAIL)->NEXT =
            (pointer)socket_ptr;
         socket_ptr->PREV = (SOCKET_STRUCT_PTR)socket_cfg_ptr->SOCKET_TAIL;

      } else {
         socket_cfg_ptr->SOCKET_HEAD = (pointer)socket_ptr;
         socket_ptr->PREV = NULL;

      } /* Endif */

      socket_ptr->NEXT = NULL;
      socket_cfg_ptr->SOCKET_TAIL = (pointer)socket_ptr;
      RTCS_mutex_unlock(&socket_cfg_ptr->SOCK_MUTEX);

      socket_ptr->VALID = SOCKET_VALID;

      /*
      ** set the default socket options
      */
      socket_ptr->CONNECT_TIMEOUT  = DEFAULT_CONNECT_TIMEOUT;
      socket_ptr->RETRANSMISSION_TIMEOUT = DEFAULT_RETRANSMISSION_TIMEOUT;
      socket_ptr->SEND_TIMEOUT     = DEFAULT_SEND_TIMEOUT;
      socket_ptr->RECEIVE_TIMEOUT  = DEFAULT_RECEIVE_TIMEOUT;
      socket_ptr->RECEIVE_PUSH     = DEFAULT_PUSH;
      socket_ptr->SEND_NOWAIT      = DEFAULT_SEND_NOWAIT;
      socket_ptr->SEND_WAIT        = DEFAULT_SEND_WAIT;
      socket_ptr->SEND_PUSH        = DEFAULT_PUSH;
      socket_ptr->RECEIVE_NOWAIT   = DEFAULT_RECEIVE_NOWAIT;
      socket_ptr->CHECKSUM_BYPASS  = DEFAULT_CHECKSUM_BYPASS;
      socket_ptr->ACTIVE           = DEFAULT_ACTIVE;
      socket_ptr->TBSIZE           = DEFAULT_TBSIZE;
      socket_ptr->RBSIZE           = DEFAULT_RBSIZE;
      socket_ptr->MAXRTO           = DEFAULT_MAXRTO;
      socket_ptr->MAXRCV_WND       = DEFAULT_MAXRCV_WND;
      socket_ptr->KEEPALIVE        = DEFAULT_KEEPALIVE;
      socket_ptr->NOWAIT           = DEFAULT_NOWAIT;
      socket_ptr->NO_NAGLE_ALGORITHM  = DEFAULT_NO_NAGLE_ALGORITHM;
      socket_ptr->NOSWRBUF         = DEFAULT_NOSWRBUF;
      socket_ptr->CALL_BACK        = DEFAULT_CALL_BACK;
      socket_ptr->TYPE_MIRROR      = (uint_32)type;
      socket_ptr->APPLICATION_CALLBACK  = DEFAULT_CALLBACK;
      socket_ptr->TIMEWAIT_TIMEOUT = DEFAULT_TIMEWAIT_TIMEOUT;
      socket_ptr->DELAY_ACK = DEFAULT_DELAY_ACK;

      socket_ptr->PROTOCOL     = type;

   } /* Endif */

   return(socket_ptr);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_Free_sock_struct
* Returned Value  : none
* Comments        : Delink and release a socket structure.
*
*END*-----------------------------------------------------------------*/

void SOCK_Free_sock_struct
   (
      SOCKET_STRUCT_PTR          socket_ptr
   )
{ /* Body */
   SOCKET_CONFIG_STRUCT_PTR   socket_cfg_ptr = RTCS_getcfg(SOCKET);
   
   #if RTCSCFG_SOCKET_OWNERSHIP //FSL AB
       SOCKET_OWNER_STRUCT_PTR  owner_ptr;
       SOCKET_OWNER_STRUCT_PTR  free_ptr;
   #endif

   socket_ptr->VALID = 0;

#if RTCSCFG_SOCKET_OWNERSHIP
   owner_ptr = socket_ptr->OWNERS.NEXT;
   while (owner_ptr != NULL) {
      free_ptr = owner_ptr;
      owner_ptr = owner_ptr->NEXT;
      _mem_free(free_ptr);
   } /* Endwhile */
#endif

   RTCS_mutex_lock(&socket_cfg_ptr->SOCK_MUTEX);

   /*
   ** Fix up the head/next pointer of our predecessor.
   */
   if ( socket_ptr->PREV == NULL ) {
      socket_cfg_ptr->SOCKET_HEAD = socket_ptr->NEXT;
   } else {
      (socket_ptr->PREV)->NEXT = socket_ptr->NEXT;
   } /* Endif */

   /*
   ** Fix up the tail/prev pointer of our successor.
   */
   if ( socket_ptr->NEXT == NULL ) {
      socket_cfg_ptr->SOCKET_TAIL = socket_ptr->PREV;
   } else {
      (socket_ptr->NEXT)->PREV = socket_ptr->PREV;
   } /* Endif */

   /*
   ** Release the socket structure memory.
   */
   RTCS_part_free(socket_ptr);

   socket_cfg_ptr->CURRENT_SOCKETS--;
   RTCS_mutex_unlock(&socket_cfg_ptr->SOCK_MUTEX);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_Remove_owner
* Returned Value  : none
* Comments        :
*
*END*-----------------------------------------------------------------*/

boolean SOCK_Remove_owner
   (
      SOCKET_STRUCT_PTR    socket_ptr,
      _rtcs_taskid         task_ptr
   )
{ /* Body */
#if RTCSCFG_SOCKET_OWNERSHIP
   SOCKET_OWNER_STRUCT_PTR owner_ptr;
   uint_32                 i;

   owner_ptr = &socket_ptr->OWNERS;

   while (owner_ptr != NULL) {
      for (i=0;i<SOCKET_NUMOWNERS;i++) {
         if (owner_ptr->TASK[i] == task_ptr) {
            owner_ptr->TASK[i] = NULL;
            return TRUE;
         } /* Endif */
      } /* Endfor */
      owner_ptr = owner_ptr->NEXT;
   } /* Endwhile */
   return FALSE;
#else
   return TRUE;
#endif
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_Is_owner
* Returned Value  : none
* Comments        :
*
*END*-----------------------------------------------------------------*/

boolean SOCK_Is_owner
   (
      SOCKET_STRUCT_PTR    socket_ptr,
      _rtcs_taskid         task_ptr
   )
{ /* Body */
#if RTCSCFG_SOCKET_OWNERSHIP
   SOCKET_OWNER_STRUCT_PTR owner_ptr;
   uint_32                 i;

   owner_ptr = &socket_ptr->OWNERS;


   while (owner_ptr != NULL) {
      for (i=0;i<SOCKET_NUMOWNERS;i++) {
         if (owner_ptr->TASK[i] == task_ptr) {
            /* already here, just return */
            return TRUE;
         } /* Endif */
      } /* Endfor */
      owner_ptr = owner_ptr->NEXT;
   } /* Endwhile */
   return FALSE;
#else
   return TRUE;
#endif
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_Add_owner
* Returned Value  : none
* Comments        :
*
*END*-----------------------------------------------------------------*/

boolean SOCK_Add_owner
   (
      SOCKET_STRUCT_PTR    socket_ptr,
      _rtcs_taskid         task_ptr
   )
{ /* Body */
#if RTCSCFG_SOCKET_OWNERSHIP
   SOCKET_OWNER_STRUCT_PTR owner_ptr, new_owner_ptr;
   uint_32                 i;
   pointer _PTR_           saved_ptr = NULL;

   owner_ptr = &socket_ptr->OWNERS;

   while (owner_ptr != NULL) {
      for (i=0;i<SOCKET_NUMOWNERS;i++) {
         if (owner_ptr->TASK[i] == task_ptr) {
            /* already here, just return */
            return TRUE;
         } else if ((owner_ptr->TASK[i] == 0) && (saved_ptr == NULL)) {
            saved_ptr = &owner_ptr->TASK[i];
         } /* Endif */
      } /* Endfor */
      owner_ptr = owner_ptr->NEXT;
   } /* Endwhile */

   if (saved_ptr != NULL) {
      *saved_ptr = task_ptr;
   } else {
      new_owner_ptr = RTCS_mem_alloc_zero(sizeof(SOCKET_OWNER_STRUCT));
      if (new_owner_ptr == NULL) {
         return FALSE;
      } /* Endif */

      _mem_set_type(new_owner_ptr, MEM_TYPE_SOCKET_OWNER_STRUCT);

      new_owner_ptr->TASK[0] = task_ptr;
      owner_ptr->NEXT = new_owner_ptr;
   } /* Endif */
   return TRUE;
#else
   return TRUE;
#endif
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pipe/io_pipe.h<|end_filename|>
#ifndef _io_pipe_h_
#define _io_pipe_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_pipe.h$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   The file contains the public functions prototype, defines, 
*   structure definitions to the Pipe IO device
*
*END************************************************************************/

#include "ioctl.h"

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/


/*
** PIPE IOCTL calls
*/
#define PIPE_IOCTL_GET_SIZE                  _IO(IO_TYPE_PIPE,0x01)
#define PIPE_IOCTL_FULL                      _IO(IO_TYPE_PIPE,0x02)
#define PIPE_IOCTL_EMPTY                     _IO(IO_TYPE_PIPE,0x03)
#define PIPE_IOCTL_RE_INIT                   _IO(IO_TYPE_PIPE,0x04)
#define PIPE_IOCTL_CHAR_AVAIL                _IO(IO_TYPE_PIPE,0x05)
#define PIPE_IOCTL_NUM_CHARS_FULL            _IO(IO_TYPE_PIPE,0x06)
#define PIPE_IOCTL_NUM_CHARS_FREE            _IO(IO_TYPE_PIPE,0x07)



/*----------------------------------------------------------------------*/
/*
**                          EXTERN FUNCTION DEFINITIONS
*/




#ifdef __cplusplus
extern "C" {
#endif

extern uint_32  _io_pipe_install(char_ptr, uint_32, uint_32);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb_dcd/polled/usb_dcd_pol_kn.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_dcd_pol_kn.c$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains low level functions for the USB DCD polled device driver
*   for Kinetis family.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "usb_dcd.h"
#include "usb_dcd_pol_prv.h"
#include "usb_dcd_kn_prv.h"

extern uint_32 _kusb_dcd_polled_init   (KUSB_DCD_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _kusb_dcd_polled_deinit (IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR, KUSB_DCD_INFO_STRUCT_PTR);
extern uint_32 _kusb_dcd_polled_read   (IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _kusb_dcd_polled_write  (IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _kusb_dcd_polled_ioctl  (KUSB_DCD_INFO_STRUCT_PTR, uint_32, uint_32_ptr);

/*FUNCTION****************************************************************
*
* Function Name    : _usb_dcd_finish_check
* Returned Value   : void
* Comments         :
*    Install an USB DCD device.
*
*END*********************************************************************/
void _usb_dcd_finish_check
	(
	)
{

}

/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_polled_install
* Returned Value   : MQX error code
* Comments         :
*    Install an USB DCD device.
*
*END*********************************************************************/

uint_32 _kusb_dcd_polled_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr           				identifier,

      /* [IN] The I/O init data pointer */
      KUSB_DCD_INIT_STRUCT_CPTR      init_data_ptr
   )
{ /* Body */


#if PE_LDD_VERSION
	if (PE_PeripheralUsed((uint_32)_bsp_get_usb_dcd_base_address()))
	{
		/* IO Device used by PE Component*/
		return IO_DEVICE_EXISTS;
	}
#endif


	return _io_usb_dcd_polled_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, pointer _PTR_, char_ptr))_kusb_dcd_polled_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_kusb_dcd_polled_deinit,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_kusb_dcd_polled_read,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_kusb_dcd_polled_write,
      (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_kusb_dcd_polled_ioctl,
      (pointer)init_data_ptr);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_polled_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an USB_DCD device.
*
*END*********************************************************************/

uint_32 _kusb_dcd_polled_init
   (
      /* [IN] Initialization information for the device being opened */
      KUSB_DCD_INIT_STRUCT_PTR      io_init_ptr,

      /* [OUT] Address to store device specific information */
      pointer _PTR_                 io_info_ptr_ptr,

      /* [IN] The rest of the name of the device opened */
      char_ptr                      open_name_ptr

   )
{ /* Body */
   USBDCD_MemMapPtr             usb_dcd_ptr;
   KUSB_DCD_INFO_STRUCT_PTR     io_info_ptr;
   SIM_MemMapPtr                sim = SIM_BASE_PTR;
   USB_MemMapPtr                usbotg = USB0_BASE_PTR;
   usb_dcd_ptr = _bsp_get_usb_dcd_base_address();
   if (NULL == usb_dcd_ptr)
   {
        return USB_DCD_ERROR_CHANNEL_INVALID;
   }

   io_info_ptr = (KUSB_DCD_INFO_STRUCT_PTR)_mem_alloc_system_zero ((uint_32)sizeof (KUSB_DCD_INFO_STRUCT));
   if (NULL == io_info_ptr)
   {
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type (io_info_ptr, MEM_TYPE_IO_USB_DCD_INFO_STRUCT);

   *io_info_ptr_ptr 				= io_info_ptr;
   io_info_ptr->INIT          = *io_init_ptr;
   io_info_ptr->USB_DCD_PTR   = usb_dcd_ptr;
   io_info_ptr->METHOD        = USB_DCD_POLLED;
   io_info_ptr->STATE         = USB_DCD_DISABLE;

   /* USB DCD board specific initialization */

   /* USB Clock Gating for OTG */
#ifdef BSP_TWRMCF51JF
   sim->SCGC6 |= SIM_SCGC6_USBOTG_MASK;
#elif BSP_TWR_K70F120M || BSP_TWR_K60F120M
   sim->SCGC4 |= SIM_SCGC4_USBFS_MASK;
#else
   sim->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
#endif
   /* USB Clock Gating for DCD */
   sim->SCGC6 |= SIM_SCGC6_USBDCD_MASK;

   /* USB pre-initialization */
   usbotg->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
   while (usbotg->USBTRC0 & USB_USBTRC0_USBRESET_MASK){};
   usbotg->ISTAT |= USB_ISTAT_USBRST_MASK;

   /* USB DCD initialization */

   /* CLOCK SPEED (in Khz)*/
   if (io_init_ptr->CLOCK_SPEED < 0x400) /*Khz*/
   {
   	if (io_init_ptr->CLOCK_SPEED < 0x04)
      	 return USB_DCD_CLOCK_SPEED_INVALID;
   	usb_dcd_ptr->CLOCK = ((uint_32)((uint_32)io_init_ptr->CLOCK_SPEED << USBDCD_CLOCK_CLOCK_SPEED_SHIFT)) & USBDCD_CLOCK_CLOCK_SPEED_MASK;
   }
   else
   {
   	if (((uint_32)(io_init_ptr->CLOCK_SPEED/1000)) > 0x3FF)
   		 return USB_DCD_CLOCK_SPEED_INVALID;
      usb_dcd_ptr->CLOCK = (((uint_32)(((uint_32)(io_init_ptr->CLOCK_SPEED/1000)) << USBDCD_CLOCK_CLOCK_SPEED_SHIFT)) & USBDCD_CLOCK_CLOCK_SPEED_MASK) | USBDCD_CLOCK_CLOCK_UNIT_MASK;
   }
   /* Timer0 initialization */
   usb_dcd_ptr->TIMER0 = (uint_32)((uint_32)(io_init_ptr->TSEQ_INIT)<<USBDCD_TIMER0_TSEQ_INIT_SHIFT) & USBDCD_TIMER0_TSEQ_INIT_MASK;

   /* Timer1 initialization */
   usb_dcd_ptr->TIMER1 = ((uint_32)((uint_32)(io_init_ptr->TDCD_DBNC)<<USBDCD_TIMER1_TDCD_DBNC_SHIFT) & USBDCD_TIMER1_TDCD_DBNC_MASK) |
   							 ((uint_32)((uint_32)(io_init_ptr->TVDPSRC_ON)<<USBDCD_TIMER1_TVDPSRC_ON_SHIFT) & USBDCD_TIMER1_TVDPSRC_ON_MASK);

   /* Timer2 initialization */
   usb_dcd_ptr->TIMER2 = ((uint_32)((uint_32)(io_init_ptr->TVDPSRC_CON)<<USBDCD_TIMER2_TVDPSRC_CON_SHIFT) & USBDCD_TIMER2_TVDPSRC_CON_MASK) |
   							 ((uint_32)((uint_32)(io_init_ptr->CHECK_DM)<<USBDCD_TIMER2_CHECK_DM_SHIFT) & USBDCD_TIMER2_CHECK_DM_MASK);

   /* Disable USB DCD module */
   usb_dcd_ptr->CONTROL = USBDCD_CONTROL_IACK_MASK | USBDCD_CONTROL_SR_MASK;

   return USB_DCD_OK;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_polled_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an USB DCD device.
*
*END*********************************************************************/

uint_32 _kusb_dcd_polled_deinit
   (
      /* [IN] the initialization information for the device being opened */
      IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] the address of the device specific information */
      KUSB_DCD_INFO_STRUCT_PTR     io_info_ptr
   )
{ /* Body */
   USBDCD_MemMapPtr            usb_dcd_ptr;

   if ((NULL == io_info_ptr) || (NULL == pol_io_dev_ptr))
   {
      return USB_DCD_ERROR_INVALID_PARAMETER;
   }

   usb_dcd_ptr = io_info_ptr->USB_DCD_PTR;

   /* Disable the USB DCD module */
   usb_dcd_ptr->CONTROL = USBDCD_CONTROL_IACK_MASK | USBDCD_CONTROL_SR_MASK;

   /* Free info struct */
   _mem_free (pol_io_dev_ptr->DEV_INFO_PTR);
   pol_io_dev_ptr->DEV_INFO_PTR = NULL;

   return MQX_OK;

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_polled_ioctl
* Returned Value   : MQX error code.
* Comments         :
*    This function performs miscellaneous services for
*    the USB DCD I/O device.
*
*END*********************************************************************/

uint_32 _kusb_dcd_polled_ioctl
   (
      /* [IN] the address of the device specific information */
      KUSB_DCD_INFO_STRUCT_PTR io_info_ptr,

      /* [IN] The command to perform */
      uint_32                     cmd,

      /* [IN] Parameters for the command */
      uint_32_ptr                 param_ptr
   )
{ /* Body */
   USBDCD_MemMapPtr             usb_dcd_ptr;
   uint_32                      result = MQX_OK;
   USB_MemMapPtr                usbotg = USB0_BASE_PTR;

   usb_dcd_ptr = io_info_ptr->USB_DCD_PTR;

   switch (cmd)
   {
      case IO_IOCTL_USB_DCD_SET_TSEQ_INIT:
      	usb_dcd_ptr->TIMER0 |= (uint_32)((uint_32)(*param_ptr)<<USBDCD_TIMER0_TSEQ_INIT_SHIFT);
         break;
      case IO_IOCTL_USB_DCD_GET_TSEQ_INIT:
      	*param_ptr = (uint_32)((usb_dcd_ptr->TIMER0 & USBDCD_TIMER0_TSEQ_INIT_MASK)>>USBDCD_TIMER0_TSEQ_INIT_SHIFT);
         break;
      case IO_IOCTL_USB_DCD_GET_TUNITCON:
      	*param_ptr = (uint_32)((usb_dcd_ptr->TIMER0 & USBDCD_TIMER0_TUNITCON_MASK)>>USBDCD_TIMER0_TUNITCON_SHIFT);
      	break;
      case IO_IOCTL_USB_DCD_SET_TDCD_DBNC:
      	usb_dcd_ptr->TIMER1 |= (uint_32)((uint_32)(*param_ptr)<<USBDCD_TIMER1_TDCD_DBNC_SHIFT);
      	break;
      case IO_IOCTL_USB_DCD_GET_TDCD_DBNC:
      	*param_ptr = (uint_32)((usb_dcd_ptr->TIMER1 & USBDCD_TIMER1_TDCD_DBNC_MASK)>>USBDCD_TIMER1_TDCD_DBNC_SHIFT);
      	break;
      case IO_IOCTL_USB_DCD_SET_TVDPSRC_ON:
      	usb_dcd_ptr->TIMER1 |= (uint_32)((uint_32)(*param_ptr)<<USBDCD_TIMER1_TVDPSRC_ON_SHIFT);
      	break;
      case IO_IOCTL_USB_DCD_GET_TVDPSRC_ON:
      	*param_ptr = (uint_32)((usb_dcd_ptr->TIMER1 & USBDCD_TIMER1_TVDPSRC_ON_MASK)>>USBDCD_TIMER1_TVDPSRC_ON_SHIFT);
      	break;
      case IO_IOCTL_USB_DCD_SET_TVDPSRC_CON:
      	usb_dcd_ptr->TIMER2 |= (uint_32)((uint_32)(*param_ptr)<<USBDCD_TIMER2_TVDPSRC_CON_SHIFT);
      case IO_IOCTL_USB_DCD_GET_TVDPSRC_CON:
      	*param_ptr = (uint_32)((usb_dcd_ptr->TIMER2 & USBDCD_TIMER2_TVDPSRC_CON_MASK)>>USBDCD_TIMER2_TVDPSRC_CON_SHIFT);
      	break;
      case IO_IOCTL_USB_DCD_SET_CHECK_DM:
      	usb_dcd_ptr->TIMER2 |= (uint_32)((uint_32)(*param_ptr)<<USBDCD_TIMER2_CHECK_DM_SHIFT);
      	break;
      case IO_IOCTL_USB_DCD_GET_CHECK_DM:
      	*param_ptr = (uint_32)((usb_dcd_ptr->TIMER2 & USBDCD_TIMER2_CHECK_DM_MASK)>>USBDCD_TIMER2_CHECK_DM_SHIFT);
      	break;
      case IO_IOCTL_USB_DCD_SET_CLOCK_SPEED:
      	if (*param_ptr < 0x400) /*Khz*/
   		{
   			if (*param_ptr < 0x04)
      	 		return USB_DCD_CLOCK_SPEED_INVALID;
   			usb_dcd_ptr->CLOCK = ((uint_32)((uint_32)(*param_ptr) << USBDCD_CLOCK_CLOCK_SPEED_SHIFT)) & USBDCD_CLOCK_CLOCK_SPEED_MASK;
   		}
   		else
   		{
   			if (((uint_32)(*param_ptr/1000)) > 0x3FF)
   		 		return USB_DCD_CLOCK_SPEED_INVALID;
      		usb_dcd_ptr->CLOCK = (((uint_32)(((uint_32)(*param_ptr/1000)) << USBDCD_CLOCK_CLOCK_SPEED_SHIFT)) & USBDCD_CLOCK_CLOCK_SPEED_MASK) | USBDCD_CLOCK_CLOCK_UNIT_MASK;
   		}
      	break;
      case IO_IOCTL_USB_DCD_GET_CLOCK_SPEED:
      	if (usb_dcd_ptr->CLOCK & USBDCD_CLOCK_CLOCK_UNIT_MASK)
      	{
      		*param_ptr = (uint_32)(((usb_dcd_ptr->CLOCK & USBDCD_CLOCK_CLOCK_SPEED_MASK) >> USBDCD_CLOCK_CLOCK_SPEED_SHIFT) * 1000);
      	}
      	else
      	{
      		*param_ptr = (uint_32)((usb_dcd_ptr->CLOCK & USBDCD_CLOCK_CLOCK_SPEED_MASK) >> USBDCD_CLOCK_CLOCK_SPEED_SHIFT);
         }
      	break;
      case IO_IOCTL_USB_DCD_GET_STATUS:
      	*param_ptr = (uint_32)(usb_dcd_ptr->STATUS>>16);
      	break;
      case IO_IOCTL_USB_DCD_RESET:
      	usb_dcd_ptr->CONTROL |= (USBDCD_CONTROL_SR_MASK | USBDCD_CONTROL_IACK_MASK);
      	io_info_ptr->STATE = USB_DCD_DISABLE;
      	break;
      case IO_IOCTL_USB_DCD_START:
      	usb_dcd_ptr->CONTROL |= (USBDCD_CONTROL_START_MASK | USBDCD_CONTROL_IACK_MASK);
      	io_info_ptr->STATE = USB_DCD_ENABLE;
      	break;
      case IO_IOCTL_USB_DCD_GET_STATE:
			if (io_info_ptr->METHOD == USB_DCD_POLLED)
			{
				/* update state */
				if (usb_dcd_ptr->CONTROL & USBDCD_CONTROL_IF_MASK)
				{
					io_info_ptr->STATE = USB_DCD_SEQ_COMPLETE;
					usb_dcd_ptr->CONTROL |= USBDCD_CONTROL_IACK_MASK;

					/* Enable pull-up register */
					if (usb_dcd_ptr->STATUS & USBDCD_STATUS_SEQ_RES_MASK)
					{
						 usbotg->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
				   }
				}
			}
         *param_ptr = io_info_ptr->STATE;
      	break;
      case IO_IOCTL_USB_DCD_GET_CHARGER_TYPE:
      	*param_ptr = (uint_32)((usb_dcd_ptr->STATUS & USBDCD_STATUS_SEQ_RES_MASK)>>16);
		   *param_ptr |= (uint_32)((usb_dcd_ptr->STATUS & (USBDCD_STATUS_ERR_MASK | USBDCD_STATUS_TO_MASK))>>16);
      	break;
      default:
      	return USB_DCD_ERROR_INVALID_CMD;
   }
   return result;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_polled_read
* Returned Value   : MQX_OK
* Comments         :
*
*
*END*********************************************************************/

uint_32 _kusb_dcd_polled_read
   (
      /* [IN] the address of the device specific information */
      IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] The array to copy data into */
      uchar_ptr                       buffer,

      /* [IN] number of bytes to read */
      uint_32                         length
   )
{ /* Body */
   return MQX_OK;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_polled_write
* Returned Value   : MQX_OK
* Comments         :
*
*
*END*********************************************************************/

uint_32 _kusb_dcd_polled_write
   (
      /* [IN] the address of the device specific information */
      IO_USB_DCD_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] The array characters are to be read from */
      uchar_ptr                       buffer,

      /* [IN] number of bytes to output */
      uint_32                         length
   )
{ /* Body */
   return MQX_OK;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/ftpclnt.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpclnt.c$
* $Version : 3.8.15.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains an implementation of an
*   FTP client.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <rtcs.h>
#include <fio.h>
#include <ftpc.h>

int_32 FTP_receive_message      (pointer, MQX_FILE_PTR);
int_32 FTP_receive_message_pasv (uint_32, MQX_FILE_PTR, _ip_address _PTR_, uint_16 _PTR_);
void   FTP_execute_command      (uint_32, boolean, MQX_FILE_PTR);

uint_32 FTPc_window_size = FTPCCFG_WINDOW_SIZE;
uint_32 FTPc_buffer_size = FTPCCFG_BUFFER_SIZE;

/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTP_open
* Returned Value   : 3-digit message code, or -1 on error
* Comments  :  Routine to open an FTP session.
*
*END*-----------------------------------------------------------------*/

int_32 FTP_open
   (
      pointer _PTR_  handle_ptr,
      _ip_address    server_ipaddr,
      MQX_FILE_PTR   ctrl_fd
   )
{ /* Body */
   sockaddr_in    server_sockaddr;
   uint_32        ctrl_sock;
   int_32         message;
   uint_32        option;
   int_32         error=RTCS_OK;

   /* Get a control socket */
   ctrl_sock = socket(PF_INET, SOCK_STREAM, 0);
   if (ctrl_sock == RTCS_SOCKET_ERROR) {
      return RTCS_ERROR;
   } /* Endif */


#if FTPCCFG_SMALL_FILE_PERFORMANCE_ENHANCEMENT
   option = TRUE;   
   error = setsockopt(ctrl_sock, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &option, sizeof(option));
#endif

   if (!error) {
      option = FTPc_window_size;   
      error = setsockopt(ctrl_sock, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));
   }
   
   if (!error) {
      option = FTPc_window_size;   
      error = setsockopt(ctrl_sock, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));
   }      

   if (!error) {
      option = FTPCCFG_TIMEWAIT_TIMEOUT; 
      error = setsockopt(ctrl_sock, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));
   } 

   if (error) {
      shutdown(ctrl_sock, FLAG_ABORT_CONNECTION);
      return RTCS_ERROR;
   } /* Endif */

   /* Connect the control socket to port 21 on the server  */
   server_sockaddr.sin_family      = AF_INET;
   server_sockaddr.sin_port        = IPPORT_FTP;  /* port 21 */
   server_sockaddr.sin_addr.s_addr = server_ipaddr;
   message = connect(ctrl_sock,(const sockaddr *)(&server_sockaddr), sizeof(server_sockaddr));
   if (message != RTCS_OK) {
      shutdown(ctrl_sock, FLAG_ABORT_CONNECTION);
      return RTCS_ERROR;
   } /* Endif */

   message = FTP_receive_message((pointer)ctrl_sock, ctrl_fd);

   if (message == RTCS_ERROR) {
      shutdown (ctrl_sock, FLAG_ABORT_CONNECTION);
   }
   
   if (handle_ptr) {
      *handle_ptr = (pointer)ctrl_sock;
   } /* Endif */

   return message;

} /* Endbody */

#if 0
/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTP_receive_message
* Returned Value   : 3-digit message code, or -1 on error
* Comments  :  Receive message on the control connection and write it
*              to fd_ctrl
*
*END*-----------------------------------------------------------------*/

int_32 FTP_receive_message
   (
      uint_32     ctrl_sock,
      MQX_FILE_PTR ctrl_fd
   )
{ /* Body */
   char        *message_buffer;
   uint_32     i, chars_left = 0;
   boolean     message_found = FALSE;
   int_32      message = 0, digit_count = 0, count = 0;

   message_buffer = RTCS_mem_alloc(BUF_SIZE);
   if (!message_buffer) {
      return RTCS_ERROR;
   }
   _mem_set_type(ftpc_context_ptr, MEM_TYPE_FTPc_RX_BUFFER);

   while (1) {
      if (!chars_left) {
         write(ctrl_fd, message_buffer, count);
         count = recv(ctrl_sock, message_buffer, BUF_SIZE, 0);
         if (count == RTCS_ERROR) {
            _mem_free(message_buffer);
            return RTCS_ERROR;
         } /* Endif */
         chars_left = count;
         i = 0;
      } /* Endif */

      if ((digit_count == 0) && (isdigit(message_buffer[i]))) {
         digit_count++;
         message *= 10;
         message += (message_buffer[i] - '0');
      } else if ((digit_count == 1) && (isdigit(message_buffer[i]))) {
         digit_count++;
         message *= 10;
         message += (message_buffer[i] - '0');
      } else if ((digit_count == 2) && (isdigit(message_buffer[i]))) {
         digit_count++;
         message *= 10;
         message += (message_buffer[i] - '0');
      } else if ((digit_count == 3) && (message_buffer[i] == ' ')) {
         message_found = TRUE;

      } else if (message_found) {
         /* EOL and found message code, so break. */
         if (message_buffer[i] == '\n') {
            break;
         } /* Endif */

      /* EOL: maybe message is on next line, so reset digit_count & message */
      } else if (message_buffer[i] == '\n') {
         digit_count = 0;
         message = 0;

      /* Not EOL.  Don't look for message code for the rest of this line. */
      } else {
         digit_count = -1;
      } /* Endif */

      i++;
      chars_left--;
   } /* Endwhile */

   write(ctrl_fd, message_buffer, count);
   _mem_free(message_buffer);
   return message;

} /* Endbody */
#endif


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTP_receive_message
* Returned Value   : 3-digit message code, or -1 on error
* Comments  :  Receive message on the control connection and write it
*              to fd_ctrl
*
*END*-----------------------------------------------------------------*/

int_32 FTP_receive_message
   (
      pointer     handle,
      MQX_FILE_PTR ctrl_fd
   )
{ /* Body */
   uint_32  ctrl_sock = (uint_32)handle;
  
   char        c;
   char        *message_buffer;
   uint_32     i=0;
   boolean     message_found = FALSE;
   int_32      message = 0, digit_count = 0;

   message_buffer = RTCS_mem_alloc(FTPc_window_size);
   if (!message_buffer) {
      return RTCS_ERROR;
   }
   _mem_set_type(message_buffer, MEM_TYPE_FTPc_RX_BUFFER);

   while (1) {
      if (recv(ctrl_sock, &c, 1, 0) == RTCS_ERROR) {
         _mem_free(message_buffer);
         return RTCS_ERROR;
      } /* Endif */
      message_buffer[i++]=c;

      if ((digit_count == 0) && (isdigit(c))) {
         digit_count++;
         message = (c - '0')*100;
      } else if ((digit_count == 1) && (isdigit(c))) {
         digit_count++;
         message += (c - '0')*10;
      } else if ((digit_count == 2) && (isdigit(c))) {
         digit_count++;
         message += (c - '0');
      } else if ((digit_count == 3) && (c == ' ')) {
         message_found = TRUE;

      } else if (c == '\n') {
         if (message_found) {
            /* EOL and found message code, so break. */
            break;
         } /* Endif */

         /* EOL: maybe message is on next line, so reset digit_count & message */
         digit_count = 0;
         message = 0;

      /* Not EOL.  Don't look for message code for the rest of this line. */
      } else {
         digit_count = -1;
      } /* Endif */
      
      if (i==FTPc_window_size)  {
         write(ctrl_fd, message_buffer, i);
         i=0;
      }
   } /* Endwhile */

   if (i)  {
      write(ctrl_fd, message_buffer, i);
   }
   
   _mem_free(message_buffer);
   return message;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTP_receive_message_pasv
* Returned Value   : 3-digit message code, or -1 on error
* Comments  :  Receive the response to a PASV command on the control
*              connection and write it to fd_ctrl
*
*END*-----------------------------------------------------------------*/

int_32 FTP_receive_message_pasv
   (
      uint_32           ctrl_sock,
      MQX_FILE_PTR      ctrl_fd,
      _ip_address _PTR_ data_ipaddr_ptr,
      uint_16 _PTR_     data_port_ptr
   )
{ /* Body */
   char        c, *message_buffer;
   uint_32     i=0, comma_count = 0;
   boolean     message_found = FALSE;
   int_32      message = 0, digit_count = 0, p=0;
   _ip_address ipaddr = 0;
   uint_16     port = 0;

   message_buffer = RTCS_mem_alloc(FTPc_window_size);
   if (!message_buffer) {
      return RTCS_ERROR;
   }
   _mem_set_type(message_buffer, MEM_TYPE_FTPc_RX_BUFFER);

   while (1) {
      if (recv(ctrl_sock, &c, 1, 0) == RTCS_ERROR)  {
         _mem_free(message_buffer);
         return RTCS_ERROR;
      } /* Endif */
      message_buffer[i++]=c;

      if ((digit_count == 0) && (isdigit(c))) {
         digit_count++;
         message = (c - '0')*100;
      } else if ((digit_count == 1) && (isdigit(c))) {
         digit_count++;
         message += (c - '0')*10;
      } else if ((digit_count == 2) && (isdigit(c))) {
         digit_count++;
         message += (c - '0');
      } else if ((digit_count == 3) && (c == ' ')) {
         message_found = TRUE;
         p = 0;

      } else if (message_found) {

         if (isdigit(c)) {
            p *= 10;
            p += (c - '0');
         } else if (c == ',') {
            comma_count++;
            if (comma_count <= 4) {
               ipaddr <<= 8;
               ipaddr |= p & 0xFF;
            } else if (comma_count <= 6) {
               port <<= 8;
               port |= p & 0xFF;
            } /* Endif */
            p = 0;
         } else if (c == '\n') {
            break;
         } /* Endif */

      /* EOL: maybe message is on next line, so reset digit_count & message */
      } else if (c == '\n') {
         digit_count = 0;
         comma_count = 0;
         message = 0;
         ipaddr = 0;
         port = 0;

      /* Not EOL.  Don't look for message code for the rest of this line. */
      } else {
         digit_count = -1;
      } /* Endif */
      
      if (i==FTPc_window_size)  {
         write(ctrl_fd, message_buffer, i);
         i=0;
      }
   } /* Endwhile */

   if (comma_count == 5) {
      port <<= 8;
      port |= p & 0xFF;
   } /* Endif */

   if (data_ipaddr_ptr) {
      *data_ipaddr_ptr = ipaddr;
   } /* Endif */
   if (data_port_ptr) {
      *data_port_ptr = port;
   } /* Endif */

   if (i)  {
      write(ctrl_fd, message_buffer, i);
   }
   
   _mem_free(message_buffer);
   return message;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTP_command
* Returned Value   : 3-digit message code, or -1 on error
* Comments  :  Issue an FTP command that does not require a data
*              connection
*
*END*-----------------------------------------------------------------*/

int_32 FTP_command
   (
      pointer     handle,
      char_ptr    command,
      MQX_FILE_PTR ctrl_fd
   )
{ /* Body */
   uint_32  ctrl_sock = (uint_32)handle;

   send(ctrl_sock, command, strlen(command), 0);
   return FTP_receive_message(handle, ctrl_fd);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTP_close
* Returned Value   : 3-digit message code, or -1 on error
* Comments  :  Close an FTP session
*
*END*-----------------------------------------------------------------*/

int_32 FTP_close
   (
      pointer     handle,
      MQX_FILE_PTR ctrl_fd
   )

{ /* Body */
   uint_32  ctrl_sock = (uint_32)handle;
   int_32   message;

   message = FTP_command(handle, "QUIT\r\n", ctrl_fd);
   shutdown(ctrl_sock, FLAG_CLOSE_TX);
   return message;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTP_command_data
* Returned Value   : int_32 3-digit message code or RTCS_ERROR
* Comments  :  Routine for FTP commands that require a data connection
*
*END*-----------------------------------------------------------------*/

int_32 FTP_command_data
   (
      pointer     handle,
      char_ptr    command,
      MQX_FILE_PTR ctrl_fd,
      MQX_FILE_PTR data_fd,
      uint_32     flags
   )
{ /* Body */
   uint_32     ctrl_sock = (uint_32)handle;
   uint_32     listen_sock, data_sock;
   sockaddr_in listen_addr, data_addr;
   uint_16     listen_addr_len;
   int_32      message;
   int_16      mode, direction;
   char        command_str[31];
   _ip_address data_ipaddr;
   uint_16     data_port;
   uint_32     option;
   int_32      error;


   mode = flags & 3;
   direction = flags & 4;

   switch (mode) {

   /*
   ** default mode: client control = P,  client data = P
   **               server control = 21, server data = 20
   **
   ** PORT mode:    client control = P,  client data = P'
   **               server control = 21, server data = 20
   */
   case 1:
   case 2:

      /* Get a listen socket */
      listen_sock = socket(PF_INET, SOCK_STREAM, 0);
      if (listen_sock == RTCS_SOCKET_ERROR) {
         return RTCS_ERROR;
      } /* Endif */


#ifdef FTPCCFG_SMALL_FILE_PERFORMANCE_ENHANCEMENT
      option = TRUE;   
      error = setsockopt(listen_sock, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &option, sizeof(option));
      if (error) {
         return RTCS_ERROR;
      } /* Endif */  
#endif
      option = FTPc_buffer_size;   
      error = setsockopt(listen_sock, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));
      if (error) {
         return RTCS_ERROR;
      } /* Endif */      

      option = FTPc_buffer_size;   
      error = setsockopt(listen_sock, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));
      if (error) {
         return RTCS_ERROR;
      } /* Endif */      

      option = FTPCCFG_TIMEWAIT_TIMEOUT; 
      error = setsockopt(listen_sock, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));
      if (error) {
         return RTCS_ERROR;
      } /* Endif */      

      /* Determine which local address and port to use */
      listen_addr_len = sizeof(listen_addr);
      message = getsockname(ctrl_sock, (sockaddr *)&listen_addr, &listen_addr_len);
      if (message != RTCS_OK) {
         shutdown(listen_sock, FLAG_CLOSE_TX);
         return RTCS_ERROR;
      } /* Endif */
      if (mode == 2) {
         listen_addr.sin_port = 0;
      } /* Endif */

      /* Put socket in listen mode */
      message = bind(listen_sock,(const sockaddr *) &listen_addr, sizeof(listen_addr));
      if (message != RTCS_OK) {
         shutdown(listen_sock, FLAG_CLOSE_TX);
         return RTCS_ERROR;
      } /* Endif */
      message = listen(listen_sock, 0);
      if (message != RTCS_OK) {
         shutdown(listen_sock, FLAG_CLOSE_TX);
         return RTCS_ERROR;
      } /* Endif */

      /* For PORT mode, send a PORT command with our local port */
      if (mode == 2) {
         listen_addr_len = sizeof(listen_addr);
         message = getsockname(listen_sock, (sockaddr *)&listen_addr, &listen_addr_len);
         if (message != RTCS_OK) {
            shutdown(listen_sock, FLAG_CLOSE_TX);
            return RTCS_ERROR;
         } /* Endif */
         /* Removed use of %hd due to incompatibility with certain compiler runtimes */ 
         sprintf(command_str, "PORT %ld,%ld,%ld,%ld,%ld,%ld\r\n",
                 (listen_addr.sin_addr.s_addr >> 24) & 0xFF,
                 (listen_addr.sin_addr.s_addr >> 16) & 0xFF,
                 (listen_addr.sin_addr.s_addr >>  8) & 0xFF,
                  listen_addr.sin_addr.s_addr        & 0xFF,
                 (uint_32) ((listen_addr.sin_port  >>  8) & 0xFF),
                 (uint_32) (listen_addr.sin_port  & 0xFF));
         message = FTP_command(handle, command_str, ctrl_fd);
         if ((message < 200) || (message >= 300)) {
            shutdown(listen_sock, FLAG_CLOSE_TX);
            return message;
         } /* Endif */
      } /* Endif */

      /* Send command, expecting "1xx Opening data connection" */
      message = FTP_command(handle, command, ctrl_fd);
      if ((message < 100) || (message >= 200)) {
         shutdown(listen_sock, FLAG_CLOSE_TX);
         return message;
      } /* Endif */

      /* Connection requested; accept it */
      data_sock = accept(listen_sock, NULL, NULL);
      shutdown(listen_sock, FLAG_CLOSE_TX);
      if (data_sock == RTCS_SOCKET_ERROR) {
         return RTCS_ERROR;
      } /* Endif */

      break;

   /*
   ** PASV mode:  client control = P,  client data = P'
   **             server control = 21, server data = P''
   */
   case 3:

      /* Send PASV command */
      strcpy(command_str, "PASV\r\n");
      send(ctrl_sock, command_str, strlen(command_str), 0);

      message = FTP_receive_message_pasv(ctrl_sock, ctrl_fd, &data_ipaddr, &data_port);
      if ((message < 200) || (message >= 300)) {
         return message;
      } /* Endif */

      /* Get data socket and connect it */
      data_sock = socket(PF_INET, SOCK_STREAM, 0);
      
#ifdef FTPCCFG_SMALL_FILE_PERFORMANCE_ENHANCEMENT
      option = TRUE;   
      error = setsockopt(data_sock, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &option, sizeof(option));
      if (error) {
         return RTCS_ERROR;
      } /* Endif */ 
#endif
      option = FTPc_buffer_size;   
      error = setsockopt(data_sock, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));
      if (error) {
         return RTCS_ERROR;
      } /* Endif */      

      option = FTPc_buffer_size;   
      error = setsockopt(data_sock, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));
      if (error) {
         return RTCS_ERROR;
      } /* Endif */      

      option = FTPCCFG_TIMEWAIT_TIMEOUT; 
      error = setsockopt(data_sock, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));
      if (error) {
         return RTCS_ERROR;
      } /* Endif */      
      
      data_addr.sin_family      = AF_INET;
      data_addr.sin_port        = data_port;
      data_addr.sin_addr.s_addr = data_ipaddr;
      message = connect(data_sock,(const sockaddr *)(&data_addr), sizeof(data_addr));
      if (message != RTCS_OK) {
         shutdown(data_sock, FLAG_CLOSE_TX);
         return RTCS_ERROR;
      } /* Endif */

      /* Send command, expecting "1xx Opening data connection" */
      message = FTP_command(handle, command, ctrl_fd);
      if ((message < 100) || (message >= 200)) {
         shutdown(data_sock, FLAG_CLOSE_TX);
         return message;
      } /* Endif */

      break;

   default:
      return RTCS_ERROR;
   } /* Endswitch */

   /* Execute the command */
   FTP_execute_command(data_sock, direction, data_fd);
   shutdown(data_sock, FLAG_CLOSE_TX);

   return FTP_receive_message(handle, ctrl_fd);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTP_execute_command
* Returned Value   : void
* Comments  :  Transfer data over the data connection
*
*END*-----------------------------------------------------------------*/

void FTP_execute_command
   (
      uint_32     data_sock,
      boolean     sending,
      MQX_FILE_PTR data_fd
   )
{ /* Body */
   char *buff;
   int_32 length;
   int_32 sendLength,index = 0;
   

   buff = RTCS_mem_alloc(FTPc_buffer_size);
   if (!buff) {
      return;
   }
   _mem_set_type(buff, MEM_TYPE_FTPc_COMMAND_BUFFER);

   if (sending) {
      for (;;) {
         length = read(data_fd, buff, FTPc_buffer_size);
        if (length <= 0) break;

         while((sendLength = send(data_sock, &buff[index], length, 0)) != length)
         {
            if(sendLength == RTCS_ERROR) {
               break;
            }
               _time_delay(1);
               index += sendLength;
               length = length - sendLength;
         }
      } /* Endfor */

   } else {
      for (;;) {
         length = recv(data_sock, buff, FTPc_buffer_size, 0);
        if (length <= 0) break;
         write(data_fd, buff, length);
      } /* Endfor */
   } /* Endif */

   _mem_free(buff);
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/int.c<|end_filename|>
/*HEADER*********************************************************************
 *
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: int.c$
 * $Version : 3.8.0.1$
 * $Date    : Feb-22-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Interrupt component.
 *
 *END************************************************************************/

#include "mqx_inc.h"

#if MQX_USE_INTERRUPTS

/*!
 * \brief Default ISR that MQX calls if an unhandled interrupt or exception occurs.
 *
 * This is the default MQX handler of interrupts or expections not hanlded by
 * a specific handler routine. This function changes the state of the active
 * task to UNHANDLED_INT_BLOCKED and blocks it.
 *
 * \param[in] vector_number Parameter that MQX passes to the ISR.
 *
 * \warning Blocks the active task. Do not call this function, use it as a default
 * handler of unhandled interrupts or exceptions.
 *
 * \see _int_install_default_isr
 * \see _int_install_unexpected_isr
 * \see _int_install_exception_isr
 */
void _int_default_isr
(
    pointer vector_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR          td_ptr;

    _GET_KERNEL_DATA(kernel_data);

    td_ptr = kernel_data->ACTIVE_PTR;
    _KLOGE5(KLOG_int_default_isr, td_ptr, vector_number,
                    &vector_number, vector_number);

    _int_disable();
    if (td_ptr->STATE != UNHANDLED_INT_BLOCKED)
    {
        td_ptr->STATE = UNHANDLED_INT_BLOCKED;
        td_ptr->INFO = (_mqx_uint) vector_number;
        _task_set_error_td_internal(td_ptr, MQX_UNHANDLED_INTERRUPT);
        _QUEUE_UNLINK(td_ptr);
    } /* Endif */
    _int_enable();

} /* Endbody */

/*!
 * \brief This function disables all interrupts for active task.
 *
 * The _int_disable() function disables all hardware interrupts at priorities up
 * to and including the MQX disable-interrupt level. As a result, no task can
 * interrupt the active task while the active task is running until interrupts
 * are re-enabled with _int_enable(). If the active task blocks while interrupts
 * are disabled, the state of the interrupts (disabled or enabled) depends on
 * the interrupt-disabled state of the next task that MQX makes ready.
 * \n Keep minimum code between calls to _int_disable() and its matching _int_enable().
 * If _int_disable() or _int_enable() are nested, MQX re-enables interrupts only
 * after the number of calls to _int_enable() are equal to the number of calls to
 * _int_disable().
 *
 * \see _int_enable
 */
void _int_disable(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    _INT_DISABLE_CODE();

} /* Endbody */

/*!
 * \brief This function enables all interrupts for active task.
 *
 * This function _int_enable() resets the processor priority to the hardware
 * priority that corresponds to the active task's software priority.
 * Keep minimum code between calls to _int_disable() and its matching
 * _int_enable().
 * \n If _int_disable() or _int_enable() are nested, MQX re-enables interrupts only
 * after the number of calls to _int_enable() are equal to the number of calls to
 * _int_disable().
 *
 * \see _int_disable
 */
void _int_enable(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    _INT_ENABLE_CODE();

} /* Endbody */

/*!
 * \brief Gets a pointer to the default ISR that MQX calls when an unexpected interrupt occurs.
 *
 * This function returns the pointer to current default ISR.
 *
 * \return Pointer to the default ISR for unhandled interrupts.
 * \return NULL (Failure.)
 *
 * \see _int_install_default_isr
 */
INT_ISR_FPTR _int_get_default_isr
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return(kernel_data->DEFAULT_ISR);

} /* Endbody */

/*!
 * \brief Gets a pointer to the current ISR exception handler for the vector number.
 *
 * The returned exception handler is either a default ISR or an ISR that the
 * application installed with _int_set_exception_handler().
 *
 * \param[in] vector Number of a vector whose exception handler is to be returned.
 *
 * \return Pointer to the current exception handler.
 * \return NULL (Failure.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code.
 *
 * \see _int_set_exception_handler
 * \see _int_exception_isr
 * \see _task_set_error
 */
#if !MQX_SPARSE_ISR_TABLE

INT_EXCEPTION_FPTR _int_get_exception_handler
(
    _mqx_uint vector
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        return(NULL);
    }/* Endif */
#endif

    vector -= kernel_data->FIRST_USER_ISR_VECTOR;
    return(kernel_data->INTERRUPT_TABLE_PTR[vector].APP_ISR_EXCEPTION_HANDLER);

} /* Endbody */

#else /* MQX_SPARSE_ISR_TABLE */

INT_EXCEPTION_FPTR _int_get_exception_handler
(
    _mqx_uint vector
)
{
    return NULL;
}

#endif /* MQX_SPARSE_ISR_TABLE */

/*!
 * \brief Gets the current ISR for the specified vector.
 *
 * The returned ISR is either a default ISR or an ISR that the application
 * installed with _int_install_isr().
 *
 * \param[in] vector Number of the vector whose ISR is to be returned.
 *
 * \return Pointer to the ISR. (Success.)
 * \return NULL (Failure.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code.
 *
 * \see _int_install_isr
 * \see _int_get_isr_data
 * \see _int_set_isr_data
 * \see _task_set_error
 */
#if !MQX_SPARSE_ISR_TABLE

INT_ISR_FPTR _int_get_isr
(
    _mqx_uint vector
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        return NULL;
    } /* Endif */
#endif

    vector -= kernel_data->FIRST_USER_ISR_VECTOR;

    return(kernel_data->INTERRUPT_TABLE_PTR[vector].APP_ISR);

} /* Endbody */

#else /* MQX_SPARSE_ISR_TABLE */
INT_ISR_FPTR _int_get_isr
(
    _mqx_uint vector
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR          kernel_data;
    INTERRUPT_SPARSE_REC_STRUCT_PTR int_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        return NULL;
    } /* Endif */
#endif

    _int_disable();

    int_ptr = kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT];

    while (int_ptr && int_ptr->VEC_NUM != vector)
    {
        int_ptr = int_ptr->NEXT;
    }

    _int_enable();

    return (int_ptr) ? int_ptr->APP_ISR : _int_default_isr;

}

#endif /* MQX_SPARSE_ISR_TABLE */

/*!
 * \brief Retrieves a pointer of the interrupt handler data for the specified
 * vector.
 *
 * When MQX calls _int_kernel_isr() or an application ISR, it passes the data
 * as the first parameter to the ISR.
 * \nISR data can be modified with _int_set_isr_data().
 *
 * \param[in] vector Number of the vector whose ISR data are to be returned.
 *
 * \return Pointer to the ISR data.
 * \return NULL (Failure.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code.
 *
 * \see _int_get_isr
 * \see _int_install_isr
 * \see _int_set_isr_data
 */
#if !MQX_SPARSE_ISR_TABLE

pointer _int_get_isr_data
(
    _mqx_uint vector
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        return(NULL);
    }/* Endif */
#endif

    vector -= kernel_data->FIRST_USER_ISR_VECTOR;
    return(kernel_data->INTERRUPT_TABLE_PTR[vector].APP_ISR_DATA);

} /* Endbody */

#else /* MQX_SPARSE_ISR_TABLE */

pointer _int_get_isr_data
(
    _mqx_uint vector
)
{
    KERNEL_DATA_STRUCT_PTR          kernel_data;
    INTERRUPT_SPARSE_REC_STRUCT_PTR int_ptr;

    _GET_KERNEL_DATA(kernel_data);
#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        return(NULL);
    }/* Endif */
#endif

    _int_disable();

    int_ptr = kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT];

    while (int_ptr && int_ptr->VEC_NUM != vector)
    {
        int_ptr = int_ptr->NEXT;
    }

    _int_enable();

    return (int_ptr) ? int_ptr->APP_ISR_DATA : NULL;
}

#endif /* MQX_SPARSE_ISR_TABLE */

/*!
 * \brief Gets the depth of nesting of the current interrupt stack.
 *
 * \return 0 (An interrupt is not being serviced.)
 * \return 1 (A non-nested interrupt is being serviced.)
 * \return >=2 (A nested interrupt is being serviced.)
 *
 * \see _int_install_isr
 */
_mqx_uint _int_get_isr_depth(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return( kernel_data->IN_ISR );
} /* Endbody */

/*!
 * \brief Installs the provided function as the default ISR, called whenever an
 * unhandled interrupt occurs.
 *
 * MQX uses the application-provided default ISR for all interrupts for which
 * the application has not installed an application ISR. The routine handles all
 * unhandled and unexpected interrupts.
 *
 * \param[in] default_isr The new default ISR function.
 *
 * \return Pointer to previous default ISR which was installed before this function was called.
 *
 * \see _int_get_default_isr
 * \see _int_install_isr
 * \see _int_default_isr
 * \see _int_install_exception_isr
 * \see _int_install_unexpected_isr
 */
#if !MQX_SPARSE_ISR_TABLE

INT_ISR_FPTR _int_install_default_isr
(
    INT_ISR_FPTR default_isr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    INT_ISR_FPTR                old_default_isr;
    INTERRUPT_TABLE_STRUCT_PTR  int_table_ptr;
    _mqx_uint                   number;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_int_install_default_isr, default_isr);

    old_default_isr = kernel_data->DEFAULT_ISR;
    kernel_data->DEFAULT_ISR = default_isr;

    int_table_ptr = kernel_data->INTERRUPT_TABLE_PTR;
    if (int_table_ptr != NULL)
    {
        number = (kernel_data->LAST_USER_ISR_VECTOR -
                        kernel_data->FIRST_USER_ISR_VECTOR) + 1 + 1;

        while (--number)
        {
            if (int_table_ptr->APP_ISR == old_default_isr)
            {
                int_table_ptr->APP_ISR = default_isr;
            } /* Endif */
            ++int_table_ptr;
        } /* Endwhile */
    } /* Endif */

    _KLOGX2(KLOG_int_install_default_isr, old_default_isr);

    return(old_default_isr);

} /* Endbody */

#else /* MQX_SPARSE_ISR_TABLE */

INT_ISR_FPTR _int_install_default_isr
(
    INT_ISR_FPTR default_isr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    INT_ISR_FPTR           old_default_isr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_int_install_default_isr, default_isr);

    old_default_isr = kernel_data->DEFAULT_ISR;
    kernel_data->DEFAULT_ISR = default_isr;

    _KLOGX2(KLOG_int_install_default_isr, old_default_isr);

    return(old_default_isr);

} /* Endbody */

#endif /* MQX_SPARSE_ISR_TABLE */

/*!
 * \brief Installs the MQX-provided _int_exception_isr() as the default ISR for
 * unhandled interrupts and exceptions.
 *
 * The exception ISR handler performs the following service when unhandled interrupt occurs:
 * \n a) A task is running
 * \n - If the task has installed an exception handler, this handler is called
 * \n - Otherwise, the task is aborted (_task_abort)
 * \n b) An ISR is running
 * \n - If the ISR has an exception handler installed, then the exception handler
 * is called. Finally, both exception and ISR interrupt frames are removed.
 *
 * \return Pointer to the default exception handler before this function was called.
 *
 * \see _int_get_default_isr
 */
INT_ISR_FPTR _int_install_exception_isr
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    kernel_data->FLAGS |= MQX_FLAGS_EXCEPTION_HANDLER_INSTALLED;
    return(_int_install_default_isr(_int_exception_isr));

} /* Endbody */

/*!
 * \brief Installs the ISR.
 *
 * MQX catches all hardware interrupts in the range specified in _int_init and saves
 * the context of the active task. For these interrupts, the MQX calls the ISR that is
 * stored in the interrupt vector table at the location identified by its interrupt
 * vector number.
 * \n The application defines the ISR data, which can be any constant or pointer value.
 *
 * \param[in] vector   Vector number (not the offset) of the interrupt.
 * \param[in] isr_ptr  Pointer to the ISR
 * \param[in] isr_data Pointer to the data to be passed as the first parameter to
 * the ISR when an interrupt occurs and the ISR runs
 *
 * \return Pointer to the previous ISR installed for the vector before calling this function.
 * \return NULL (Failure.)
 *
 * \see _int_get_default_isr
 * \see _int_install_default_isr
 * \see _int_get_isr_data
 * \see _int_set_isr_data
 * \see _int_get_isr
 * \see _task_set_error
 */
#if !MQX_SPARSE_ISR_TABLE

INT_ISR_FPTR _int_install_isr
(
    _mqx_uint        vector,
    INT_ISR_FPTR     isr_ptr,
    pointer          isr_data
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    INTERRUPT_TABLE_STRUCT_PTR table_ptr;
    INT_ISR_FPTR               old_isr_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_int_install_isr, vector, isr_ptr, isr_data);

#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        _KLOGX2(KLOG_int_install_isr, NULL);
        return(NULL);
    }/* Endif */
#endif

    table_ptr = &kernel_data->INTERRUPT_TABLE_PTR[vector -
                                                  kernel_data->FIRST_USER_ISR_VECTOR];

    _int_disable();
    old_isr_ptr = table_ptr->APP_ISR;
    table_ptr->APP_ISR  = isr_ptr;
    table_ptr->APP_ISR_DATA = isr_data;
    _int_enable();

    _KLOGX2(KLOG_int_install_isr, old_isr_ptr);

    return (old_isr_ptr);

} /* Endbody */

#else /* MQX_SPARSE_ISR_TABLE */

INT_ISR_FPTR _int_install_isr
(
    _mqx_uint        vector,
    INT_ISR_FPTR     isr_ptr,
    pointer          isr_data
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR          kernel_data;
    INTERRUPT_SPARSE_REC_STRUCT_PTR int_ptr;
    INT_ISR_FPTR                    old_isr_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_int_install_isr, vector, isr_ptr, isr_data);

#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        _KLOGX2(KLOG_int_install_isr, NULL);
        return(NULL);
    }/* Endif */
#endif

    _int_disable();

    int_ptr = kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT];

    while (int_ptr && int_ptr->VEC_NUM != vector)
    {
        int_ptr = int_ptr->NEXT;
    }

    if (!int_ptr)
    {
#if MQX_LITE_VERSION_NUMBER
        int_ptr = &sparse_struct;
#else
        int_ptr = _mem_alloc_system(sizeof(INTERRUPT_SPARSE_REC_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (int_ptr == NULL)
        {
            _int_enable();
            _task_set_error(MQX_OUT_OF_MEMORY);
            _KLOGX2(KLOG_int_install_isr, NULL);
            return(NULL);
        }
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */
        _mem_set_type(int_ptr, MEM_TYPE_INTERRUPT_VECTOR);
#endif /* MQX_LITE_VERSION_NUMBER */

        int_ptr->NEXT = kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT];
        kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT] = int_ptr;

        old_isr_ptr = _int_default_isr;
    }
    else
        old_isr_ptr = int_ptr->APP_ISR;

    int_ptr->VEC_NUM = vector;
    int_ptr->APP_ISR  = isr_ptr;
    int_ptr->APP_ISR_DATA = isr_data;

    _int_enable();

    _KLOGX2(KLOG_int_install_isr, old_isr_ptr);

    return (old_isr_ptr);

} /* Endbody */

#endif /* MQX_SPARSE_ISR_TABLE */

/*!
 * \brief Installs the MQX-provided unexpected ISR, _int_unexpected_isr(), for all
 * interrupts that do not have an application-installed ISR.
 *
 * The unexpected ISR handler writes the cause of the unexpected interrupt to the standard
 * I/O stream.
 *
 * \return Pointer to the previous unexpected interrupt ISR before this function was called.
 *
 * \see _int_install_exception_isr
 * \see _int_unexpected_isr
 */
INT_ISR_FPTR _int_install_unexpected_isr
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    kernel_data->FLAGS &= ~MQX_FLAGS_EXCEPTION_HANDLER_INSTALLED;

    return(_int_install_default_isr(_int_unexpected_isr));

} /* Endbody */

/*!
 * \brief Sets the ISR exception handler for the interrupt vector.
 *
 * This function sets the exception handler for an ISR. When an exception (unhandled
 * interrupt) occurs while the ISR is running, MQX calls the exception handler
 * and terminates the ISR.
 * \n In order to make use of exceptions, an application should install
 *  _int_exception_isr() as the MQX default ISR.
 * \n The returned exception handler is either the default handler or one that the
 * application previously installed with _int_set_exception_handler().
 *
 * \param[in] vector                Interrupt vector that this exception handler is for.
 * \param[in] error_handler_address Pointer to the exception handler.
 *
 * \return Pointer to the previous exception handler installed for the vector before
 *  this function was called.
 * \return NULL (Failure.)
 *
 * \warning On failure, the exception handler is not installed and _task_set_error()
 * is called to set the task error code.
 *
 * \see _int_get_exception_handler
 * \see _int_exception_isr
 * \see _task_set_error
 */
#if !MQX_SPARSE_ISR_TABLE

INT_EXCEPTION_FPTR _int_set_exception_handler
(
    _mqx_uint              vector,
    INT_EXCEPTION_FPTR error_handler_address
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    INT_EXCEPTION_FPTR old_handler = NULL;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_int_set_exception_handler, vector, error_handler_address);

#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX2(KLOG_int_set_exception_handler, NULL);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        _KLOGX2(KLOG_int_set_exception_handler, NULL);
        return(NULL);
    } /* Endif */
#endif

    vector -= kernel_data->FIRST_USER_ISR_VECTOR;

    old_handler = kernel_data->INTERRUPT_TABLE_PTR[vector].APP_ISR_EXCEPTION_HANDLER;
    kernel_data->INTERRUPT_TABLE_PTR[vector].APP_ISR_EXCEPTION_HANDLER = error_handler_address;

    _KLOGX2(KLOG_int_set_exception_handler, old_handler);
    return(old_handler);
} /* Endbody */

#else /* MQX_SPARSE_ISR_TABLE */

INT_EXCEPTION_FPTR _int_set_exception_handler
(
    _mqx_uint              vector,
    INT_EXCEPTION_FPTR error_handler_address
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    INT_EXCEPTION_FPTR old_handler = NULL;
    INTERRUPT_SPARSE_REC_STRUCT_PTR int_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_int_set_exception_handler, vector, error_handler_address);

#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX2(KLOG_int_set_exception_handler, NULL);
        return (NULL);
    }

    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        _KLOGX2(KLOG_int_set_exception_handler, NULL);
        return (NULL);
    }
#endif

    _int_disable();

    int_ptr = kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT];

    while (int_ptr && int_ptr->VEC_NUM != vector)
    {
        int_ptr = int_ptr->NEXT;
    }

    if (!int_ptr)
    {
#if MQX_LITE_VERSION_NUMBER
        int_ptr = &sparse_struct;
#else
        int_ptr = _mem_alloc_system(sizeof(INTERRUPT_SPARSE_REC_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (int_ptr == NULL)
        {
            _int_enable();
            _task_set_error(MQX_OUT_OF_MEMORY);
            _KLOGX2(KLOG_int_install_isr, NULL);
            return(NULL);
        }
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */
        _mem_set_type(int_ptr, MEM_TYPE_INTERRUPT_VECTOR);
#endif /* MQX_LITE_VERSION_NUMBER */

        int_ptr->NEXT = kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT];
        kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT] = int_ptr;

        old_handler = NULL;
    }
    else
        old_handler = int_ptr->APP_ISR_EXCEPTION_HANDLER;


    int_ptr->VEC_NUM = vector;
    int_ptr->APP_ISR_EXCEPTION_HANDLER  = error_handler_address;

    _int_enable();

    _KLOGX2(KLOG_int_set_exception_handler, old_handler);
    return (old_handler);
}

#endif /* MQX_SPARSE_ISR_TABLE */

/*!
 * \brief Sets the address of the interrupt handler data for the specified vector,
 * and returns the old value.
 *
 * \param[in] vector The interrupt vector that this data is for.
 * \param[in] data   Data that MQX passes to the ISR as its first parameter.
 *
 * \return Previous ISR data registred before this function was called.
 * \return NULL (Failure.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code.
 *
 * \see _int_get_isr
 * \see _int_get_isr_data
 */
#if !MQX_SPARSE_ISR_TABLE

pointer _int_set_isr_data
(
    _mqx_uint vector,
    pointer data
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                old_data;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_int_set_isr_data,vector,data);

#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX2(KLOG_int_set_isr_data,NULL);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        _KLOGX2(KLOG_int_set_isr_data,NULL);
        return(NULL);
    } /* Endif */
#endif

    vector -= (kernel_data->FIRST_USER_ISR_VECTOR);

    old_data = kernel_data->INTERRUPT_TABLE_PTR[vector].APP_ISR_DATA;
    kernel_data->INTERRUPT_TABLE_PTR[vector].APP_ISR_DATA = data;

    _KLOGX2(KLOG_int_set_isr_data,old_data);
    return old_data;

} /* Endbody */

#else /* MQX_SPARSE_ISR_TABLE */

pointer _int_set_isr_data
(
    _mqx_uint vector,
    pointer data
)
{
    KERNEL_DATA_STRUCT_PTR          kernel_data;
    pointer                         old_data = NULL;
    INTERRUPT_SPARSE_REC_STRUCT_PTR int_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_int_set_isr_data,vector,data);

#if MQX_CHECK_ERRORS
    if ( kernel_data->INTERRUPT_TABLE_PTR == NULL )
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX2(KLOG_int_set_isr_data,NULL);
        return(NULL);
    } /* Endif */
    if ((vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
        (vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
        _KLOGX2(KLOG_int_set_isr_data,NULL);
        return(NULL);
    } /* Endif */
#endif

    _int_disable();

    int_ptr = kernel_data->INTERRUPT_TABLE_PTR[(vector - kernel_data->FIRST_USER_ISR_VECTOR) >> MQX_SPARSE_ISR_SHIFT];

    while (int_ptr && int_ptr->VEC_NUM != vector)
    {
        int_ptr = int_ptr->NEXT;
    }

    if (int_ptr)
    {
        old_data = int_ptr->APP_ISR_DATA;
        int_ptr->APP_ISR_DATA = data;
    }

    _int_enable();

    _KLOGX2(KLOG_int_set_isr_data,old_data);
    return old_data;
}

#endif /* MQX_SPARSE_ISR_TABLE */

/*!
 * \brief This function initializes the kernel interrupt table.
 *
 * This function initializes the kernel interrupt table and install default interrupt
 * handler to all interrupt sources. This function is typically called very early
 * during system startup.
 *
 * \param[in] first_user_isr_vector_number The first (lower) user ISR vector number.
 * \param[in] last_user_isr_vector_number  The last user ISR vector number.
 *
 * \return MQX_OK (Success.)
 * \return MQX_INVALID_PARAMETER (first_user_isr_vector_number is greater than
 * last_user_isr_vector_number.)
 * \return MQX_OUT_OF_MEMORY (Not enough free memory for the interrupt table.)
 */
_mqx_uint _int_init
(
    _mqx_uint          first_user_isr_vector_number,
    _mqx_uint          last_user_isr_vector_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    INTERRUPT_TABLE_STRUCT_PTR int_table_ptr;
    _mqx_uint                  number;

#if MQX_CHECK_ERRORS
    if (last_user_isr_vector_number < first_user_isr_vector_number)
    {
        return MQX_INVALID_PARAMETER;
    } /* Endif */
#endif

    _GET_KERNEL_DATA(kernel_data);
    kernel_data->INT_KERNEL_ISR_ADDR = _int_kernel_isr;

    /* Set the current default ISR for MQX that is called whenever an
     * unhandled interrupt occurs
     */
    kernel_data->DEFAULT_ISR = _int_default_isr;

#if !MQX_SPARSE_ISR_TABLE
    number = last_user_isr_vector_number - first_user_isr_vector_number + 1;
#else
    number = ((last_user_isr_vector_number - first_user_isr_vector_number + 1) >> MQX_SPARSE_ISR_SHIFT) + 1;
#endif

#ifdef MQX_LITE_VERSION_NUMBER
    int_table_ptr = mqx_static_isr_table;
#else
    int_table_ptr = _mem_alloc_system_zero((_mem_size)(sizeof(INTERRUPT_TABLE_STRUCT) * number));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if ( int_table_ptr == NULL )
    {
        return(MQX_OUT_OF_MEMORY);
    }/* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */

    _mem_set_type(int_table_ptr, MEM_TYPE_INTERRUPT_TABLE);
#endif /* MQX_LITE_VERSION_NUMBER */

    kernel_data->INTERRUPT_TABLE_PTR   = int_table_ptr;
    kernel_data->FIRST_USER_ISR_VECTOR = first_user_isr_vector_number;
    kernel_data->LAST_USER_ISR_VECTOR  = last_user_isr_vector_number;

#if !MQX_SPARSE_ISR_TABLE
    while (number--)
    {
        int_table_ptr->APP_ISR      = _int_default_isr;
        int_table_ptr->APP_ISR_DATA = (pointer)(first_user_isr_vector_number++);
        ++int_table_ptr;
    } /* Endwhile */
#else /* MQX_SPARSE_ISR_TABLE */

    kernel_data->SPARSE_ISR_COUNT = number;
    kernel_data->SPARSE_ISR_SHIFT = MQX_SPARSE_ISR_SHIFT;

    while (number--)
    {
        int_table_ptr[number] = NULL;
    }

#endif /* MQX_SPARSE_ISR_TABLE */

    return MQX_OK;

} /* Endbody */

#endif /* MQX_USE_INTERRUPTS */

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/USB_DRIVER/usb_devapi.h<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/ /*!
  *
  * @file usb_devapi.h
  *
  * @author
  *
  * @version
  *
  * @date
  *
  * @brief This file contains S08 USB stack device layer API header function.
  *
  *****************************************************************************/

#ifndef _USB_DEVAPI_H
  #define _USB_DEVAPI_H

/******************************************************************************
 * Includes
 *****************************************************************************/
/* User Defined Data Types */
  #include "app_cfg.h"
/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
  #define USB_MAX_EP_BUFFER_SIZE     (64)

  #ifndef CONTROL_ENDPOINT
    #define CONTROL_ENDPOINT    (0)     /* control endpoint number */
  #endif

  #define USB_SETUP_PKT_SIZE  (8)     /* Setup Packet Size */

/* Error codes */
  #define  USB_OK                              (0x00)
  #define  USBERR_ALLOC                        (0x81)
  #define  USBERR_BAD_STATUS                   (0x82)
  #define  USBERR_CLOSED_SERVICE               (0x83)
  #define  USBERR_OPEN_SERVICE                 (0x84)
  #define  USBERR_TRANSFER_IN_PROGRESS         (0x85)
  #define  USBERR_ENDPOINT_STALLED             (0x86)
  #define  USBERR_ALLOC_STATE                  (0x87)
  #define  USBERR_DRIVER_INSTALL_FAILED        (0x88)
  #define  USBERR_DRIVER_NOT_INSTALLED         (0x89)
  #define  USBERR_INSTALL_ISR                  (0x8A)
  #define  USBERR_INVALID_DEVICE_NUM           (0x8B)
  #define  USBERR_ALLOC_SERVICE                (0x8C)
  #define  USBERR_INIT_FAILED                  (0x8D)
  #define  USBERR_SHUTDOWN                     (0x8E)
  #define  USBERR_INVALID_PIPE_HANDLE          (0x8F)
  #define  USBERR_OPEN_PIPE_FAILED             (0x90)
  #define  USBERR_INIT_DATA                    (0x91)
  #define  USBERR_SRP_REQ_INVALID_STATE        (0x92)
  #define  USBERR_TX_FAILED                    (0x93)
  #define  USBERR_RX_FAILED                    (0x94)
  #define  USBERR_EP_INIT_FAILED               (0x95)
  #define  USBERR_EP_DEINIT_FAILED             (0x96)
  #define  USBERR_TR_FAILED                    (0x97)
  #define  USBERR_BANDWIDTH_ALLOC_FAILED       (0x98)
  #define  USBERR_INVALID_NUM_OF_ENDPOINTS     (0x99)
  #define  USBERR_NOT_SUPPORTED                (0x9A)

  #define  USBERR_DEVICE_NOT_FOUND             (0xC0)
  #define  USBERR_DEVICE_BUSY                  (0xC1)
  #define  USBERR_NO_DEVICE_CLASS              (0xC3)
  #define  USBERR_UNKNOWN_ERROR                (0xC4)
  #define  USBERR_INVALID_BMREQ_TYPE           (0xC5)
  #define  USBERR_GET_MEMORY_FAILED            (0xC6)
  #define  USBERR_INVALID_MEM_TYPE             (0xC7)
  #define  USBERR_NO_DESCRIPTOR                (0xC8)
  #define  USBERR_NULL_CALLBACK                (0xC9)
  #define  USBERR_NO_INTERFACE                 (0xCA)
  #define  USBERR_INVALID_CFIG_NUM             (0xCB)
  #define  USBERR_INVALID_ANCHOR               (0xCC)
  #define  USBERR_INVALID_REQ_TYPE             (0xCD)

/* Pipe Types */
  #define  USB_CONTROL_PIPE                    (0x00)
  #define  USB_ISOCHRONOUS_PIPE                (0x01)
  #define  USB_BULK_PIPE                       (0x02)
  #define  USB_INTERRUPT_PIPE                  (0x03)

/* Device States */
  #define  USB_STATE_UNKNOWN                   (0xff)
  #define  USB_STATE_PENDING_ADDRESS           (0x04)
  #define  USB_STATE_POWERED                   (0x03)
  #define  USB_STATE_DEFAULT                   (0x02)
  #define  USB_STATE_ADDRESS                   (0x01)
  #define  USB_STATE_CONFIG                    (0x00)
  #define  USB_STATE_SUSPEND                   (0x80)

/* Get_Status Request information for DEVICE */
  #define  USB_SELF_POWERED                    (0x01)
  #define  USB_REMOTE_WAKEUP                   (0x02)

/* Get_Status Request information for OTG (WINDEX = 0xF000) */
  #ifdef OTG_BUILD
    #define  USB_OTG_HOST_REQUEST_FLAG           (0x01)
  #endif

/* Bus Control values */
  #define  USB_NO_OPERATION                    (0x00)
  #define  USB_ASSERT_BUS_RESET                (0x01)
  #define  USB_DEASSERT_BUS_RESET              (0x02)
  #define  USB_ASSERT_RESUME                   (0x03)
  #define  USB_DEASSERT_RESUME                 (0x04)
  #define  USB_SUSPEND_SOF                     (0x05)
  #define  USB_RESUME_SOF                      (0x06)

/* possible values of Status */
  #define  USB_STATUS_IDLE                     (0)
  #define  USB_STATUS_TRANSFER_ACCEPTED        (6)
  #define  USB_STATUS_TRANSFER_PENDING         (2)
  #define  USB_STATUS_TRANSFER_IN_PROGRESS     (3)
  #define  USB_STATUS_ERROR                    (4)
  #define  USB_STATUS_DISABLED                 (5)
  #define  USB_STATUS_STALLED                  (1)
  #define  USB_STATUS_TRANSFER_QUEUED          (7)

  #define  USB_STATUS_UNKNOWN                  (0xFFFF)

  #define  USB_CONTROL_ENDPOINT     (0)

  #define  USB_RECV                 (0)
  #define  USB_SEND                 (1)

  #define  USB_DEVICE_DONT_ZERO_TERMINATE      (0x1)

  #define  USB_SETUP_DATA_XFER_DIRECTION       (0x80)

  #define  USB_SPEED_FULL                      (0)
  #define  USB_SPEED_LOW                       (1)
  #define  USB_SPEED_HIGH                      (2)

  #define  USB_MAX_PKTS_PER_UFRAME             (0x6)

  #define  USB_TEST_MODE_TEST_PACKET           (0x0400)

/* Available service types */
/* Services 0 through 15 are reserved for endpoints */
  #define  USB_SERVICE_EP0                     (0x00)
  #define  USB_SERVICE_EP1                     (0x01)
  #define  USB_SERVICE_EP2                     (0x02)
  #define  USB_SERVICE_EP3                     (0x03)
  #define  USB_SERVICE_EP4                     (0x04)
  #define  USB_SERVICE_EP5                     (0x05)
  #define  USB_SERVICE_EP6                     (0x06)
  #define  USB_SERVICE_EP7                     (0x07)
  #define  USB_SERVICE_EP8                     (0x08)
  #define  USB_SERVICE_EP9                     (0x09)
  #define  USB_SERVICE_EP10                    (0x0a)
  #define  USB_SERVICE_EP11                    (0x0b)
  #define  USB_SERVICE_EP12                    (0x0c)
  #define  USB_SERVICE_EP13                    (0x0d)
  #define  USB_SERVICE_EP14                    (0x0e)
  #define  USB_SERVICE_EP15                    (0x0f)

  #define  USB_SERVICE_BUS_RESET               (0x10)
  #define  USB_SERVICE_SUSPEND                 (0x11)
  #define  USB_SERVICE_SOF                     (0x12)
  #define  USB_SERVICE_RESUME                  (0x13)
  #define  USB_SERVICE_SLEEP                   (0x14)
  #define  USB_SERVICE_SPEED_DETECTION         (0x15)
  #define  USB_SERVICE_ERROR                   (0x16)
  #define  USB_SERVICE_STALL                   (0x17)
  #define  USB_SERVICE_MAX                     (0x18)

  #ifdef  DOUBLE_BUFFERING_USED
    #define  USB_SERVICE_MAX_EP         USB_SERVICE_EP6
  #else
    #define  USB_SERVICE_MAX_EP         USB_SERVICE_EP4
  #endif

/* Informational Request/Set Types */
/* component parameter in USB_Device_Get/Set_Status */
  #define USB_COMPONENT_DIRECTION_SHIFT        (7)
  #define USB_COMPONENT_DIRECTION_MASK         (0x01)
  #define  USB_STATUS_DEVICE_STATE             (0x01)
  #define  USB_STATUS_INTERFACE                (0x02)
  #define  USB_STATUS_ADDRESS                  (0x03)
  #define  USB_STATUS_CURRENT_CONFIG           (0x04)
  #define  USB_STATUS_SOF_COUNT                (0x05)
  #define  USB_STATUS_DEVICE                   (0x06)

  #ifdef OTG_BUILD
    #define  USB_STATUS_OTG                      (0x07)
    #define  USB_STATUS_TEST_MODE                (0x08)
  #else
    #define  USB_STATUS_TEST_MODE                (0x07)
  #endif

  #define  USB_STATUS_ENDPOINT                 (0x10)
  #define  USB_STATUS_ENDPOINT_NUMBER_MASK     (0x0F)


  #define UNINITIALISED_VAL                    (0xffffffff)

/******************************************************************************
 * Types
 *****************************************************************************/

  #pragma pack(1)

typedef struct _USB_DEV_EVENT_STRUCT
{
  INT8U           controller_ID;      /* conttroler ID           */
  INT8U           ep_num;
  BOOLEAN         setup;              /* is setup packet         */
  BOOLEAN         direction;          /* direction of endpoint   */
  INT8U           *buffer_ptr;        /* pointer to buffer       */
  INT16U          len;                /* buffer size of endpoint */
  INT8U           errors;             /* Any errors              */
}
USB_DEV_EVENT_STRUCT, *PTR_USB_DEV_EVENT_STRUCT;

typedef void (*USB_SERVICE_CALLBACK)(PTR_USB_DEV_EVENT_STRUCT);

typedef struct _USB_EP_STRUCT
{
  INT8U          ep_num;      /* endpoint number         */
  INT8U          type;        /* type of endpoint        */
  INT8U          direction;   /* direction of endpoint   */
  INT16U         size;        /* buffer size of endpoint */
}
USB_EP_STRUCT, *USB_EP_STRUCT_PTR;

  #pragma pack()

/******************************************************************************
 * Global Functions
 *****************************************************************************/
extern INT8U  USB_Device_Init(INT8U controller_ID, INT8U endpoints);
extern INT8U  USB_Device_DeInit(void);
extern INT8U  USB_Device_Init_EndPoint(INT8U controller_ID, USB_EP_STRUCT_PTR ep_ptr, INT8U  flag);
extern INT8U  USB_Device_Cancel_Transfer(INT8U controller_ID, INT8U ep_num, INT8U direction);
extern INT8U  USB_Device_Deinit_EndPoint(INT8U controller_ID, INT8U ep_num, INT8U direction);
extern INT8U  USB_Device_Recv_Data(INT8U controller_ID, INT8U ep_num, INT8U_ptr buff_ptr, INT16U  size);
extern INT8U  USB_Device_Send_Data(INT8U controller_ID, INT8U ep_num, INT8U_ptr buff_ptr, INT16U  size);
extern void   USB_Device_Shutdown(INT8U controller_ID);
extern void   USB_Device_Stall_EndPoint(INT8U controller_ID, INT8U ep_num, INT8U  direction);
extern void   USB_Device_Unstall_EndPoint(INT8U controller_ID, INT8U ep_num, INT8U direction);
extern void   USB_Device_Read_Setup_Data(INT8U controller_ID, INT8U ep_num, INT8U_ptr buff_ptr);
extern INT8U  USB_Device_Get_Status(INT8U controller_ID, INT8U component, INT16U_ptr status);
extern INT8U  USB_Device_Set_Status(INT8U controller_ID, INT8U component, INT16U setting);
extern void   USB_Device_Assert_Resume(INT8U controller_ID);
extern INT8U  USB_Device_Register_Service(INT8U controller_ID, INT8U type, USB_SERVICE_CALLBACK service);
extern INT8U  USB_Device_Unregister_Service(INT8U controller_ID, INT8U    type);
extern INT8U  USB_Device_Get_Transfer_Status(INT8U controller_ID, INT8U    ep_num, INT8U  direction);
extern void   USB_Device_Set_Address(INT8U controller_ID, INT8U    address);
extern INT8U  USB_Device_Call_Service(INT8U type, PTR_USB_DEV_EVENT_STRUCT  event);

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/rtc_common.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtc_common.c$
* $Version : 3.8.3.0$
* $Date    : Sep-14-2011$
*
* Comments:
*           Common RTC functions for some platforms. Includes leap year count.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <rtc.h>

#define ZERO_YEAR   1970
#define SEC_IN_MIN  60
#define SEC_IN_HOUR 3600 
#define SEC_IN_DAY  86400

/*FUNCTION****************************************************************
* 
* Function Name    : _is_leap_year
* Returned Value   : none
* Comments         :
*    This function returns 1 if year is leaf.
*
*END*********************************************************************/
static uint_32 _is_leap_year( uint_16 year )
{
    uint_32 result = 0;
    
    if( year % 4 == 0 )
    {
        /* leap year, add day */
        result = 1;
        if( year % 100 == 0)
        {
            /* is not leap year, substract day*/  
            result = 0;
        }
        if( year % 400 == 0)
        {
            /* finally is leap year, get back one more day */
            result = 1;
        }
    }
    return result;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_date_to_days
* Returned Value   : none
* Comments         :
*    Returns sum of days in year, month and day in DATE_STRUCT
*
*END*********************************************************************/
static uint_16 _rtc_date_to_days
( 
   DATE_STRUCT_PTR time
)
{
   uint_16 day_sum;
   

   #define FEBRUARY    2

   static const uint_16 days_no_table[]= { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
   uint_32 days = 0;
   uint_32 month;
   uint_32 year;

   day_sum = 365 * (time->YEAR - ZERO_YEAR);
   /* get leap year */
   for( year = ZERO_YEAR; year < time->YEAR; year++)
   {
     day_sum += _is_leap_year( year );      
   }

   for( month = 1; month < time->MONTH; month++)
   {
     day_sum+= days_no_table[month - 1];
     /* is leap year? */
     if( month == FEBRUARY )
     {
         day_sum+= _is_leap_year( time->YEAR );  
     }
   }

   day_sum += time->DAY-1;
   return day_sum;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_set_time_mqxd
* Returned Value   : actual RTC minute stopwatch counter value
* Comments         :
*    This function sets the RTC time according to DATE_STRUCT.
*
*END*********************************************************************/
_mqx_int _rtc_set_time_mqxd
(
   DATE_STRUCT_PTR time
)
{
   RTC_TIME_STRUCT rtc_time; 
   
   rtc_time.days = _rtc_date_to_days(time);
   rtc_time.hours = time->HOUR;
   rtc_time.minutes = time->MINUTE;
   rtc_time.seconds = time->SECOND; 
   
   _rtc_set_time( &rtc_time ); 
   return MQX_OK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_time_mqxd
* Returned Value   : actual RTC minute stopwatch counter value
* Comments         :
*    This function returns rtc time to DATE_STRUCT.
*
*END*********************************************************************/
void _rtc_get_time_mqxd 
(
   DATE_STRUCT_PTR time
)
{
    RTC_TIME_STRUCT     rtc_time; 
    TIME_STRUCT         time_s;
    
    _rtc_get_time( &rtc_time);
    time_s.SECONDS = rtc_time.seconds + rtc_time.minutes*SEC_IN_MIN + \
      rtc_time.hours*SEC_IN_HOUR + rtc_time.days*SEC_IN_DAY;  
    time_s.MILLISECONDS = 0;  
    
    _time_to_date( &time_s, time );    
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_set_alarm_mqxd
* Returned Value   : none
* Comments         :
*    This function sets RTC alarm time.
*    Alarm happens immediately after match.
*
*END*********************************************************************/
_mqx_int _rtc_set_alarm_mqxd
(
   DATE_STRUCT_PTR time
)
{
   RTC_TIME_STRUCT rtc_alarm;
   
   rtc_alarm.days = _rtc_date_to_days(time);
   rtc_alarm.hours = time->HOUR;
   rtc_alarm.minutes = time->MINUTE;
   rtc_alarm.seconds = time->SECOND; 
   _rtc_set_alarm( &rtc_alarm ); 
   return MQX_OK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_alarm_mqxd
* Returned Value   : none
* Comments         :
*    This function gets the RTC alarm time and stores it in DATE_STRUCT.
*
*END*********************************************************************/
void _rtc_get_alarm_mqxd 
(
   DATE_STRUCT_PTR time
)
{
    RTC_TIME_STRUCT     rtc_time; 
    TIME_STRUCT         time_s;
    
    _rtc_get_alarm( &rtc_time);
    time_s.SECONDS = rtc_time.seconds + rtc_time.minutes*SEC_IN_MIN + \
      rtc_time.hours*SEC_IN_HOUR + rtc_time.days*SEC_IN_DAY;  
    time_s.MILLISECONDS = 0;  
    
    _time_to_date( &time_s, time );
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/DRY_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type DRY
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(DRY_PDD_H_)
#define DRY_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error DRY PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK11D5WS) /* DRY */ && \
      !defined(MCU_MK21D5WS) /* DRY */ && \
      !defined(MCU_MK61F12WS) /* DRY */ && \
      !defined(MCU_MK61F15WS) /* DRY */ && \
      !defined(MCU_MK70F12WS) /* DRY */ && \
      !defined(MCU_MK70F15WS) /* DRY */
  // Unsupported MCU is active
  #error DRY PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Secure key word masks */
#define DRY_PDD_SECURE_KEY_WORD_0_MASK 0x1U      /**< Secure key word 0 mask. */
#define DRY_PDD_SECURE_KEY_WORD_1_MASK 0x2U      /**< Secure key word 1 mask. */
#define DRY_PDD_SECURE_KEY_WORD_2_MASK 0x4U      /**< Secure key word 2 mask. */
#define DRY_PDD_SECURE_KEY_WORD_3_MASK 0x8U      /**< Secure key word 3 mask. */
#define DRY_PDD_SECURE_KEY_WORD_4_MASK 0x10U     /**< Secure key word 4 mask. */
#define DRY_PDD_SECURE_KEY_WORD_5_MASK 0x20U     /**< Secure key word 5 mask. */
#define DRY_PDD_SECURE_KEY_WORD_6_MASK 0x40U     /**< Secure key word 6 mask. */
#define DRY_PDD_SECURE_KEY_WORD_7_MASK 0x80U     /**< Secure key word 7 mask. */

/* Tamper flag masks */
#define DRY_PDD_TAMPER_PIN_0_MASK       0x10000U /**< Tamper pin 0 flag mask. */
#define DRY_PDD_TAMPER_PIN_1_MASK       0x20000U /**< Tamper pin 1 flag mask. */
#define DRY_PDD_TAMPER_PIN_2_MASK       0x40000U /**< Tamper pin 2 flag mask. */
#define DRY_PDD_TAMPER_PIN_3_MASK       0x80000U /**< Tamper pin 3 flag mask. */
#define DRY_PDD_TAMPER_PIN_4_MASK       0x100000U /**< Tamper pin 4 flag mask. */
#define DRY_PDD_TAMPER_PIN_5_MASK       0x200000U /**< Tamper pin 5 flag mask. */
#define DRY_PDD_TAMPER_PIN_6_MASK       0x400000U /**< Tamper pin 6 flag mask. */
#define DRY_PDD_TAMPER_PIN_7_MASK       0x800000U /**< Tamper pin 7 flag mask. */
#define DRY_PDD_TEST_MODE_MASK          0x200U   /**< Test mode flag mask. */
#define DRY_PDD_FLASH_SECURITY_MASK     0x100U   /**< Flash security flag mask. */
#define DRY_PDD_SECURITY_TAMPER_MASK    0x80U    /**< Security tamper flag mask. */
#define DRY_PDD_TEMPERATURE_TAMPER_MASK 0x40U    /**< Temperature tamper flag mask. */
#define DRY_PDD_CLOCK_TAMPER_MASK       0x20U    /**< Clock tamper flag mask. */
#define DRY_PDD_VOLTAGE_TAMPER_MASK     0x10U    /**< Voltage tamper flag mask. */
#define DRY_PDD_MONOTONIC_OVERFLOW_MASK 0x8U     /**< Monotonic overflow flag mask. */
#define DRY_PDD_TIME_OVERFLOW_MASK      0x4U     /**< Time overflow flag mask. */
#define DRY_PDD_TAMPER_ACK_MASK         0x2U     /**< Tamper acknowledge flag mask. */
#define DRY_PDD_DRY_ICE_TAMPER_MASK     0x1U     /**< Tamper flag mask. */

/* Lock masks */
#define DRY_PDD_PIN_0_GLITCH_FILTER_LOCK_MASK 0x10000U /**< Pin 0 glitch filter lock mask. */
#define DRY_PDD_PIN_1_GLITCH_FILTER_LOCK_MASK 0x20000U /**< Pin 1 glitch filter lock mask. */
#define DRY_PDD_PIN_2_GLITCH_FILTER_LOCK_MASK 0x40000U /**< Pin 2 glitch filter lock mask. */
#define DRY_PDD_PIN_3_GLITCH_FILTER_LOCK_MASK 0x80000U /**< Pin 3 glitch filter lock mask. */
#define DRY_PDD_PIN_4_GLITCH_FILTER_LOCK_MASK 0x100000U /**< Pin 4 glitch filter lock mask. */
#define DRY_PDD_PIN_5_GLITCH_FILTER_LOCK_MASK 0x200000U /**< Pin 5 glitch filter lock mask. */
#define DRY_PDD_PIN_6_GLITCH_FILTER_LOCK_MASK 0x400000U /**< Pin 6 glitch filter lock mask. */
#define DRY_PDD_PIN_7_GLITCH_FILTER_LOCK_MASK 0x800000U /**< Pin 7 glitch filter lock mask. */
#define DRY_PDD_ACTIVE_TAMPER_1_LOCK_MASK     0x2000U /**< Active tamper register 1 lock mask. */
#define DRY_PDD_ACTIVE_TAMPER_0_LOCK_MASK     0x1000U /**< Active tamper register 0 lock mask. */
#define DRY_PDD_PIN_POLARITY_LOCK_MASK        0x800U /**< Pin polarity register lock mask. */
#define DRY_PDD_PIN_DIRECTION_LOCK_MASK       0x400U /**< Pin direction register lock mask. */
#define DRY_PDD_TAMPER_ENABLE_LOCK_MASK       0x200U /**< Tamper enable register lock mask. */
#define DRY_PDD_TAMPER_SECONDS_LOCK_MASK      0x100U /**< Tamper seconds register lock mask. */
#define DRY_PDD_INTERRUPT_ENABLE_LOCK_MASK    0x80U /**< Interrupt enable register lock mask. */
#define DRY_PDD_LOCK_LOCK_MASK                0x40U /**< Lock register lock mask. */
#define DRY_PDD_STATUS_LOCK_MASK              0x20U /**< Status register lock mask. */
#define DRY_PDD_CONTROL_LOCK_MASK             0x10U /**< Control register lock mask. */
#define DRY_PDD_KEY_READ_LOCK_MASK            0x8U /**< Secure key read register lock mask. */
#define DRY_PDD_KEY_WRITE_LOCK_MASK           0x4U /**< Secure key write register lock mask. */
#define DRY_PDD_KEY_VALID_LOCK_MASK           0x2U /**< Secure key valid register lock mask. */

/* Tamper pin values. */
#define DRY_PDD_LOGIC_ZERO 0U                    /**< Logic zero. */
#define DRY_PDD_LOGIC_ONE  0x1U                  /**< Logic one. */

/* Tamper pin directions. */
#define DRY_PDD_INPUT  0U                        /**< Pin is input. */
#define DRY_PDD_OUTPUT 0x1U                      /**< Pin is output and drives inverse of expected value. */

/* Tamper pin polarity. */
#define DRY_PDD_NOT_INVERTED 0U                  /**< Expected value is not inverted. */
#define DRY_PDD_INVERTED     0x1U                /**< Expected value is inverted. */

/* Tamper pin expected values. */
#define DRY_PDD_LOGIC_ZERO_EXPECTED                                 0U /**< Logic zero. */
#define DRY_PDD_ACTIVE_TAMPER_0_OUTPUT_EXPECTED                     0x10000U /**< Active tamper 0 output. */
#define DRY_PDD_ACTIVE_TAMPER_1_OUTPUT_EXPECTED                     0x20000U /**< Active tamper 1 output. */
#define DRY_PDD_ACTIVE_TAMPER_0_XOR_ACTIVE_TAMPER_1_OUTPUT_EXPECTED 0x30000U /**< Active tamper 0 output XORed with active tamper 1 output. */

/* Glitch filter prescaler clocks. */
#define DRY_PDD_512_HZ_CLOCK   0U                /**< 512 Hz clock. */
#define DRY_PDD_32768_HZ_CLOCK 0x40U             /**< 32.768 kHz clock. */


/* ----------------------------------------------------------------------------
   -- InvalidateSecureKeyWords
   ---------------------------------------------------------------------------- */

/**
 * @brief Invalidates and clears the secure key words specified by the mask
 * parameter. At the same time unlocks the read and write access to the corresponding
 * secure key words.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Secure key word mask. Use constants from group "Secure key word
 *        masks". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_SKVR.
 * @par Example:
 *      @code
 *      DRY_PDD_InvalidateSecureKeyWords(deviceID,
 *      DRY_PDD_SECURE_KEY_WORD_0_MASK);
 *      @endcode
 */
#define DRY_PDD_InvalidateSecureKeyWords(PeripheralBase, Mask) ( \
    DRY_SKVR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(DRY_SKVR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)DRY_SKVR_SKV_MASK))) | ( \
      (uint32_t)(Mask))) \
  )

/* ----------------------------------------------------------------------------
   -- GetValidSecureKeyWordsMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the mask of valid secure key words. The mask can be tested
 * against predefined masks. See 'Secure key word masks'.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: DRY_SKVR.
 * @par Example:
 *      @code
 *      uint8_t result = DRY_PDD_GetValidSecureKeyWordsMask(deviceID);
 *      @endcode
 */
#define DRY_PDD_GetValidSecureKeyWordsMask(PeripheralBase) ( \
    (uint8_t)(DRY_SKVR_REG(PeripheralBase) & DRY_SKVR_SKV_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- LockSecureKeyWriteTillVBATReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Locks the secure key words specified by the mask parameter for write
 * until VBAT reset or software reset.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Secure key word mask. Use constants from group "Secure key word
 *        masks". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_SKWLR.
 * @par Example:
 *      @code
 *      DRY_PDD_LockSecureKeyWriteTillVBATReset(deviceID,
 *      DRY_PDD_SECURE_KEY_WORD_0_MASK);
 *      @endcode
 */
#define DRY_PDD_LockSecureKeyWriteTillVBATReset(PeripheralBase, Mask) ( \
    DRY_SKWLR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- LockSecureKeyReadTillVBATReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Locks the secure key words specified by the mask parameter for read
 * until VBAT reset or software reset.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Secure key word mask. Use constants from group "Secure key word
 *        masks". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_SKRLR.
 * @par Example:
 *      @code
 *      DRY_PDD_LockSecureKeyReadTillVBATReset(deviceID,
 *      DRY_PDD_SECURE_KEY_WORD_0_MASK);
 *      @endcode
 */
#define DRY_PDD_LockSecureKeyReadTillVBATReset(PeripheralBase, Mask) ( \
    DRY_SKRLR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- SetPrescalerInitValue
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures the initial value of the prescaler. Can be used only if the
 * peripheral is disabled.
 * @param PeripheralBase Peripheral base address.
 * @param Value Initial value of the prescaler. This parameter is a 15-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_SetPrescalerInitValue(deviceID, 1);
 *      @endcode
 */
#define DRY_PDD_SetPrescalerInitValue(PeripheralBase, Value) ( \
    DRY_CR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(DRY_CR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)DRY_CR_DPR_MASK))) | ( \
      (uint32_t)((uint32_t)(Value) << DRY_CR_DPR_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPrescalerValue
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the current value of the prescaler in the range from 0 to
 * 32767. The inverse of bit 7 is the 512 Hz prescaler clock output that is used to
 * clock the glitch filters. The inverse of bit 15 is the 1 Hz prescaler clock
 * output that is used to clock the active tamper shift registers.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 15-bit value. The value is cast to "uint16_t".
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      uint16_t result = DRY_PDD_GetPrescalerValue(deviceID);
 *      @endcode
 */
#define DRY_PDD_GetPrescalerValue(PeripheralBase) ( \
    (uint16_t)((uint32_t)(DRY_CR_REG(PeripheralBase) & DRY_CR_DPR_MASK) >> DRY_CR_DPR_SHIFT) \
  )

/* ----------------------------------------------------------------------------
   -- EnableTamperFastSlewRate
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables fast slew rate on tamper pins.
 * @param PeripheralBase Peripheral base address.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableTamperFastSlewRate(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableTamperFastSlewRate(PeripheralBase, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_CR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)DRY_CR_TSRE_MASK)) : ( \
      DRY_CR_REG(PeripheralBase) |= \
       DRY_CR_TSRE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableTamperHighDriveStrength
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables high drive strength on tamper pins.
 * @param PeripheralBase Peripheral base address.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableTamperHighDriveStrength(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableTamperHighDriveStrength(PeripheralBase, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_CR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)DRY_CR_TDSE_MASK)) : ( \
      DRY_CR_REG(PeripheralBase) |= \
       DRY_CR_TDSE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableTamperPassiveFilter
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables passive input filters on tamper pins.
 * @param PeripheralBase Peripheral base address.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableTamperPassiveFilter(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableTamperPassiveFilter(PeripheralBase, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_CR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)DRY_CR_TPFE_MASK)) : ( \
      DRY_CR_REG(PeripheralBase) |= \
       DRY_CR_TPFE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableTamperHysteresis
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables hysteresis on tamper pins.
 * @param PeripheralBase Peripheral base address.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableTamperHysteresis(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableTamperHysteresis(PeripheralBase, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_CR_REG(PeripheralBase) |= \
       DRY_CR_TPFE_MASK) : ( \
      DRY_CR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)DRY_CR_TPFE_MASK)) \
  )

/* ----------------------------------------------------------------------------
   -- EnableUpdateMode
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the update mode in which status flags can be written unless
 * the status register is locked, ignoring the tamper flag.
 * @param PeripheralBase Peripheral base address.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableUpdateMode(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableUpdateMode(PeripheralBase, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_CR_REG(PeripheralBase) |= \
       DRY_CR_UM_MASK) : ( \
      DRY_CR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)DRY_CR_UM_MASK)) \
  )

/* ----------------------------------------------------------------------------
   -- EnableTamperSystemReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the chip reset generation when the tamper flag is set and the
 * tamper acknowledge flag is clear.
 * @param PeripheralBase Peripheral base address.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableTamperSystemReset(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableTamperSystemReset(PeripheralBase, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_CR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)DRY_CR_TFSR_MASK)) : ( \
      DRY_CR_REG(PeripheralBase) |= \
       DRY_CR_TFSR_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableDevice
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the device clock. Must be enabled before enabling a glitch
 * filter or active tamper and should only be disabled after disabling all glitch
 * filters and active tampers.
 * @param PeripheralBase Peripheral base address.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableDevice(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableDevice(PeripheralBase, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_CR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)DRY_CR_DEN_MASK)) : ( \
      DRY_CR_REG(PeripheralBase) |= \
       DRY_CR_DEN_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ResetDevice
   ---------------------------------------------------------------------------- */

/**
 * @brief Resets all the registers except the control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_CR.
 * @par Example:
 *      @code
 *      DRY_PDD_ResetDevice(deviceID);
 *      @endcode
 */
#define DRY_PDD_ResetDevice(PeripheralBase) ( \
    DRY_CR_REG(PeripheralBase) |= \
     DRY_CR_SWR_MASK \
  )

/* ----------------------------------------------------------------------------
   -- GetTamperFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the mask of set tamper flags. The mask can be tested against
 * predefined masks. See 'Tamper flag masks'.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: DRY_SR.
 * @par Example:
 *      @code
 *      uint32_t result = DRY_PDD_GetTamperFlags(deviceID);
 *      @endcode
 */
#define DRY_PDD_GetTamperFlags(PeripheralBase) ( \
    (uint32_t)(( \
     DRY_SR_REG(PeripheralBase)) & ( \
     (uint32_t)(( \
      DRY_SR_TPF_MASK) | (( \
      DRY_SR_TMF_MASK) | (( \
      DRY_SR_FSF_MASK) | (( \
      DRY_SR_STF_MASK) | (( \
      DRY_SR_TTF_MASK) | (( \
      DRY_SR_CTF_MASK) | (( \
      DRY_SR_VTF_MASK) | (( \
      DRY_SR_MOF_MASK) | (( \
      DRY_SR_TOF_MASK) | (( \
      DRY_SR_TAF_MASK) | ( \
      DRY_SR_DTF_MASK))))))))))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearTamperFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears the tamper flags specified by the mask parameter. A tamper pin
 * flag should be cleared after the tamper pin equals its expected value and the
 * glitch filter output has updated.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Tamper flags mask. Use constants from group "Tamper flag masks".
 *        This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_SR.
 * @par Example:
 *      @code
 *      DRY_PDD_ClearTamperFlags(deviceID, DRY_PDD_TAMPER_PIN_0_MASK);
 *      @endcode
 */
#define DRY_PDD_ClearTamperFlags(PeripheralBase, Mask) ( \
    DRY_SR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       DRY_SR_REG(PeripheralBase)) & ( \
       (uint32_t)(~(uint32_t)(( \
        DRY_SR_TPF_MASK) | (( \
        DRY_SR_TMF_MASK) | (( \
        DRY_SR_FSF_MASK) | (( \
        DRY_SR_STF_MASK) | (( \
        DRY_SR_TTF_MASK) | (( \
        DRY_SR_CTF_MASK) | (( \
        DRY_SR_VTF_MASK) | (( \
        DRY_SR_MOF_MASK) | (( \
        DRY_SR_TOF_MASK) | (( \
        DRY_SR_TAF_MASK) | ( \
        DRY_SR_DTF_MASK))))))))))))))) | ( \
      (uint32_t)(Mask))) \
  )

/* ----------------------------------------------------------------------------
   -- LockWriteTillVBATReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Locks the registers specified by the mask parameter for write until
 * VBAT reset.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Lock mask. Use constants from group "Lock masks". This parameter
 *        is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_LR.
 * @par Example:
 *      @code
 *      DRY_PDD_LockWriteTillVBATReset(deviceID,
 *      DRY_PDD_PIN_0_GLITCH_FILTER_LOCK_MASK);
 *      @endcode
 */
#define DRY_PDD_LockWriteTillVBATReset(PeripheralBase, Mask) ( \
    DRY_LR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the interrupts specified by the mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask (except TAMPER_ACK_MASK). Use constants from group
 *        "Tamper flag masks". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_IER.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableInterrupts(deviceID, DRY_PDD_TAMPER_PIN_0_MASK);
 *      @endcode
 */
#define DRY_PDD_EnableInterrupts(PeripheralBase, Mask) ( \
    DRY_IER_REG(PeripheralBase) |= \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the interrupts specified by the mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask (except DRY_ICE_TAMPER_ACK_MASK). Use constants
 *        from group "Tamper flag masks". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_IER.
 * @par Example:
 *      @code
 *      DRY_PDD_DisableInterrupts(deviceID, DRY_PDD_TAMPER_PIN_0_MASK);
 *      @endcode
 */
#define DRY_PDD_DisableInterrupts(PeripheralBase, Mask) ( \
    DRY_IER_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- GetTamperSeconds
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the time in seconds (from the RTC Time Seconds Register) at
 * which the tamper flag was set.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: DRY_TSR.
 * @par Example:
 *      @code
 *      uint32_t result = DRY_PDD_GetTamperSeconds(deviceID);
 *      @endcode
 */
#define DRY_PDD_GetTamperSeconds(PeripheralBase) ( \
    DRY_TSR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- EnableTamperDetection
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the tamper detection flags specified by the mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Tamper flags mask (except TAMPER_ACK_MASK and
 *        DRY_ICE_TAMPER_MASK). Use constants from group "Tamper flag masks". This parameter is 32
 *        bits wide.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_TER.
 * @par Example:
 *      @code
 *      DRY_PDD_EnableTamperDetection(deviceID, DRY_PDD_TAMPER_PIN_0_MASK,
 *      PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableTamperDetection(PeripheralBase, Mask, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_TER_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)(Mask))) : ( \
      DRY_TER_REG(PeripheralBase) |= \
       (uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- SetTamperPinOutput
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets tamper pin output data.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Value Tamper pin output value. This parameter is of "Tamper pin
 *        values." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_PDR.
 * @par Example:
 *      @code
 *      DRY_PDD_SetTamperPinOutput(deviceID, periphID, DRY_PDD_LOGIC_ZERO);
 *      @endcode
 */
#define DRY_PDD_SetTamperPinOutput(PeripheralBase, Index, Value) ( \
    ((Value) == DRY_PDD_LOGIC_ZERO) ? ( \
      DRY_PDR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)((uint32_t)((uint32_t)0x1U << (Index)) << DRY_PDR_TPOD_SHIFT))) : ( \
      DRY_PDR_REG(PeripheralBase) |= \
       (uint32_t)((uint32_t)((uint32_t)0x1U << (Index)) << DRY_PDR_TPOD_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- SetTamperPinDirection
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets tamper pin direction.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Direction Tamper pin direction. This parameter is of "Tamper pin
 *        directions." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_PDR.
 * @par Example:
 *      @code
 *      DRY_PDD_SetTamperPinDirection(deviceID, periphID, DRY_PDD_INPUT);
 *      @endcode
 */
#define DRY_PDD_SetTamperPinDirection(PeripheralBase, Index, Direction) ( \
    ((Direction) == DRY_PDD_INPUT) ? ( \
      DRY_PDR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)((uint32_t)0x1U << (Index)))) : ( \
      DRY_PDR_REG(PeripheralBase) |= \
       (uint32_t)((uint32_t)0x1U << (Index))) \
  )

/* ----------------------------------------------------------------------------
   -- SetTamperPinInput
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets tamper pin input data.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Value Tamper pin input value. This parameter is of "Tamper pin
 *        values." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_PPR.
 * @par Example:
 *      @code
 *      DRY_PDD_SetTamperPinInput(deviceID, periphID, DRY_PDD_LOGIC_ZERO);
 *      @endcode
 */
#define DRY_PDD_SetTamperPinInput(PeripheralBase, Index, Value) ( \
    ((Value) == DRY_PDD_LOGIC_ZERO) ? ( \
      DRY_PPR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)((uint32_t)((uint32_t)0x1U << (Index)) << DRY_PPR_TPID_SHIFT))) : ( \
      DRY_PPR_REG(PeripheralBase) |= \
       (uint32_t)((uint32_t)((uint32_t)0x1U << (Index)) << DRY_PPR_TPID_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- SetTamperPinPolarity
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets tamper pin polarity.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Polarity Tamper pin polarity. This parameter is of "Tamper pin
 *        polarity." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_PPR.
 * @par Example:
 *      @code
 *      DRY_PDD_SetTamperPinPolarity(deviceID, periphID, DRY_PDD_NOT_INVERTED);
 *      @endcode
 */
#define DRY_PDD_SetTamperPinPolarity(PeripheralBase, Index, Polarity) ( \
    ((Polarity) == DRY_PDD_NOT_INVERTED) ? ( \
      DRY_PPR_REG(PeripheralBase) &= \
       (uint32_t)(~(uint32_t)((uint32_t)0x1U << (Index)))) : ( \
      DRY_PPR_REG(PeripheralBase) |= \
       (uint32_t)((uint32_t)0x1U << (Index))) \
  )

/* ----------------------------------------------------------------------------
   -- SetActiveTamperPolynomial
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the polynomial of the active tamper shift register. When set to
 * zero, the active tamper shift register is disabled. Once enabled, the active
 * tamper shift register updates once a second using the prescaler 1 Hz clock.
 * @param PeripheralBase Peripheral base address.
 * @param Index Active tamper index. This parameter is of index type.
 * @param Polynomial Polynomial of the active tamper shift register. This
 *        parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: ATR[Index].
 * @par Example:
 *      @code
 *      DRY_PDD_SetActiveTamperPolynomial(deviceID, periphID, 1);
 *      @endcode
 */
#define DRY_PDD_SetActiveTamperPolynomial(PeripheralBase, Index, Polynomial) ( \
    DRY_ATR_REG(PeripheralBase,(Index)) = \
     (uint32_t)(( \
      (uint32_t)(DRY_ATR_REG(PeripheralBase,(Index)) & (uint32_t)(~(uint32_t)DRY_ATR_ATP_MASK))) | ( \
      (uint32_t)((uint32_t)(Polynomial) << DRY_ATR_ATP_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetActiveTamperShiftValue
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the initial value of the active tamper shift register.
 * @param PeripheralBase Peripheral base address.
 * @param Index Active tamper index. This parameter is of index type.
 * @param Value Initial value of the active tamper shift register. This
 *        parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: ATR[Index].
 * @par Example:
 *      @code
 *      DRY_PDD_SetActiveTamperShiftValue(deviceID, periphID, 1);
 *      @endcode
 */
#define DRY_PDD_SetActiveTamperShiftValue(PeripheralBase, Index, Value) ( \
    DRY_ATR_REG(PeripheralBase,(Index)) = \
     (uint32_t)(( \
      (uint32_t)(DRY_ATR_REG(PeripheralBase,(Index)) & (uint32_t)(~(uint32_t)DRY_ATR_ATSR_MASK))) | ( \
      (uint32_t)(Value))) \
  )

/* ----------------------------------------------------------------------------
   -- GetActiveTamperShiftValue
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the active tamper shift register in the range
 * from 0x0000 to 0xFFFF.
 * @param PeripheralBase Peripheral base address.
 * @param Index Active tamper index. This parameter is of index type.
 * @return Returns a 16-bit value.
 * @remarks The macro accesses the following registers: ATR[Index].
 * @par Example:
 *      @code
 *      uint16_t result = DRY_PDD_GetActiveTamperShiftValue(deviceID, periphID);
 *      @endcode
 */
#define DRY_PDD_GetActiveTamperShiftValue(PeripheralBase, Index) ( \
    (uint16_t)(DRY_ATR_REG(PeripheralBase,(Index)) & DRY_ATR_ATSR_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableTamperPinPull
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the pull resistor on the tamper pin.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PGFR[Index].
 * @par Example:
 *      @code
 *      DRY_PDD_EnableTamperPinPull(deviceID, periphID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableTamperPinPull(PeripheralBase, Index, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_PGFR_REG(PeripheralBase,(Index)) &= \
       (uint32_t)(~(uint32_t)DRY_PGFR_TPE_MASK)) : ( \
      DRY_PGFR_REG(PeripheralBase,(Index)) |= \
       DRY_PGFR_TPE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetTamperPinExpectedValue
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the expected value on the input pin.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Value Expected value. This parameter is of "Tamper pin expected
 *        values." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PGFR[Index].
 * @par Example:
 *      @code
 *      DRY_PDD_SetTamperPinExpectedValue(deviceID, periphID,
 *      DRY_PDD_LOGIC_ZERO_EXPECTED);
 *      @endcode
 */
#define DRY_PDD_SetTamperPinExpectedValue(PeripheralBase, Index, Value) ( \
    DRY_PGFR_REG(PeripheralBase,(Index)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       DRY_PGFR_REG(PeripheralBase,(Index))) & ( \
       (uint32_t)(~(uint32_t)DRY_PGFR_TPEX_MASK)))) | ( \
      (uint32_t)(Value))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableGlitchFilter
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables tamper pin glitch filter.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Enable Enable flag. This parameter is of "Global enumeration used for
 *        specifying general enable/disable states (PDD_DISABLE and PDD_ENABLE
 *        defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PGFR[Index].
 * @par Example:
 *      @code
 *      DRY_PDD_EnableGlitchFilter(deviceID, periphID, PDD_DISABLE);
 *      @endcode
 */
#define DRY_PDD_EnableGlitchFilter(PeripheralBase, Index, Enable) ( \
    ((Enable) == PDD_DISABLE) ? ( \
      DRY_PGFR_REG(PeripheralBase,(Index)) &= \
       (uint32_t)(~(uint32_t)DRY_PGFR_GFE_MASK)) : ( \
      DRY_PGFR_REG(PeripheralBase,(Index)) |= \
       DRY_PGFR_GFE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetGlitchFilterPrescaler
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the glitch filter prescaler.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Clock Prescaler clock. This parameter is of "Glitch filter prescaler
 *        clocks." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PGFR[Index].
 * @par Example:
 *      @code
 *      DRY_PDD_SetGlitchFilterPrescaler(deviceID, periphID,
 *      DRY_PDD_512_HZ_CLOCK);
 *      @endcode
 */
#define DRY_PDD_SetGlitchFilterPrescaler(PeripheralBase, Index, Clock) ( \
    DRY_PGFR_REG(PeripheralBase,(Index)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       DRY_PGFR_REG(PeripheralBase,(Index))) & ( \
       (uint32_t)(~(uint32_t)DRY_PGFR_GFP_MASK)))) | ( \
      (uint32_t)(Clock))) \
  )

/* ----------------------------------------------------------------------------
   -- SetGlitchFilterWidth
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures the number of clock edges the input must remain stable for
 * to be passed through the glitch filter for tamper pin. The number of clock
 * edges is (GFW + 1) * 2 supporting a configuration of between 2 and 128 clock
 * edges. Do not change the glitch filter width when the glitch filter is enabled.
 * @param PeripheralBase Peripheral base address.
 * @param Index Tamper pin index. This parameter is of index type.
 * @param Width Glitch filter width. This parameter is a 6-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PGFR[Index].
 * @par Example:
 *      @code
 *      DRY_PDD_SetGlitchFilterWidth(deviceID, periphID, 1);
 *      @endcode
 */
#define DRY_PDD_SetGlitchFilterWidth(PeripheralBase, Index, Width) ( \
    DRY_PGFR_REG(PeripheralBase,(Index)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       DRY_PGFR_REG(PeripheralBase,(Index))) & ( \
       (uint32_t)(~(uint32_t)DRY_PGFR_GFW_MASK)))) | ( \
      (uint32_t)(Width))) \
  )

/* ----------------------------------------------------------------------------
   -- LockWriteTillChipReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Locks the registers specified by the mask parameter for write until a
 * chip reset.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Locks mask (except KEY_SELECT_LOCK_MASK). Use constants from
 *        group "Lock masks". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_WAC.
 * @par Example:
 *      @code
 *      DRY_PDD_LockWriteTillChipReset(deviceID,
 *      DRY_PDD_PIN_0_GLITCH_FILTER_LOCK_MASK);
 *      @endcode
 */
#define DRY_PDD_LockWriteTillChipReset(PeripheralBase, Mask) ( \
    DRY_WAC_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- LockReadTillChipReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Locks the registers specified by the mask parameter for read until a
 * chip reset.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Locks mask (except KEY_SELECT_LOCK_MASK). Use constants from
 *        group "Lock masks". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_RAC.
 * @par Example:
 *      @code
 *      DRY_PDD_LockReadTillChipReset(deviceID,
 *      DRY_PDD_PIN_0_GLITCH_FILTER_LOCK_MASK);
 *      @endcode
 */
#define DRY_PDD_LockReadTillChipReset(PeripheralBase, Mask) ( \
    DRY_RAC_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- SetSecureKeyWord
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the value of the specified secure key word.
 * @param PeripheralBase Peripheral base address.
 * @param Index Secure key word index. This parameter is of index type.
 * @param Value 32-bit wide secure key word value. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: SKR[Index].
 * @par Example:
 *      @code
 *      DRY_PDD_SetSecureKeyWord(deviceID, periphID, 1);
 *      @endcode
 */
#define DRY_PDD_SetSecureKeyWord(PeripheralBase, Index, Value) ( \
    DRY_SKR_REG(PeripheralBase,(Index)) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- GetSecureKeyWord
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the 32-bit wide value of the specified secure key word.
 * @param PeripheralBase Peripheral base address.
 * @param Index Secure key word index. This parameter is of index type.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: SKR[Index].
 * @par Example:
 *      @code
 *      uint32_t result = DRY_PDD_GetSecureKeyWord(deviceID, periphID);
 *      @endcode
 */
#define DRY_PDD_GetSecureKeyWord(PeripheralBase, Index) ( \
    DRY_SKR_REG(PeripheralBase,(Index)) \
  )

/* ----------------------------------------------------------------------------
   -- LockSecureKeyWriteTillChipReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Locks the secure key words specified by the mask parameter for write
 * until chip reset.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Secure key words mask. Use constants from group "Secure key word
 *        masks". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_SWAC.
 * @par Example:
 *      @code
 *      DRY_PDD_LockSecureKeyWriteTillChipReset(deviceID,
 *      DRY_PDD_SECURE_KEY_WORD_0_MASK);
 *      @endcode
 */
#define DRY_PDD_LockSecureKeyWriteTillChipReset(PeripheralBase, Mask) ( \
    DRY_SWAC_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- LockSecureKeyReadTillChipReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Locks the secure key words specified by the mask parameter for read
 * until chip reset.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Secure key words mask. Use constants from group "Secure key word
 *        masks". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: DRY_SRAC.
 * @par Example:
 *      @code
 *      DRY_PDD_LockSecureKeyReadTillChipReset(deviceID,
 *      DRY_PDD_SECURE_KEY_WORD_0_MASK);
 *      @endcode
 */
#define DRY_PDD_LockSecureKeyReadTillChipReset(PeripheralBase, Mask) ( \
    DRY_SRAC_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )
#endif  /* #if defined(DRY_PDD_H_) */

/* DRY_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/message.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: message.h$
* $Version : 3.0.6.0$
* $Date    : Jun-26-2009$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   message component.
*
*END************************************************************************/
#ifndef __message_h__
#define __message_h__

#include <mqx_cnfg.h>
#if (!MQX_USE_MESSAGES) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error MESSAGE component is currently disabled in MQX kernel. Please set MQX_USE_MESSAGES to 1 in user_config.h and recompile kernel.
#endif

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* Error codes */

#define MSGPOOL_OUT_OF_MESSAGES                  (MSG_ERROR_BASE|0x01)
#define MSGPOOL_OUT_OF_POOLS                     (MSG_ERROR_BASE|0x02)
#define MSGPOOL_INVALID_POOL_ID                  (MSG_ERROR_BASE|0x03)
#define MSGPOOL_ALL_MESSAGES_NOT_FREE            (MSG_ERROR_BASE|0x04)
#define MSGPOOL_MESSAGE_SIZE_TOO_SMALL           (MSG_ERROR_BASE|0x05)
#define MSGPOOL_POOL_NOT_CREATED                 (MSG_ERROR_BASE|0x06)

#define MSGQ_INVALID_QUEUE_ID                    (MSG_ERROR_BASE|0x10)
#define MSGQ_QUEUE_IN_USE                        (MSG_ERROR_BASE|0x11)
#define MSGQ_NOT_QUEUE_OWNER                     (MSG_ERROR_BASE|0x12)
#define MSGQ_QUEUE_IS_NOT_OPEN                   (MSG_ERROR_BASE|0x13)
#define MSGQ_MESSAGE_NOT_AVAILABLE               (MSG_ERROR_BASE|0x14)
#define MSGQ_INVALID_MESSAGE_PRIORITY            (MSG_ERROR_BASE|0x15)
#define MSGQ_INVALID_MESSAGE                     (MSG_ERROR_BASE|0x16)
#define MSGQ_QUEUE_FULL                          (MSG_ERROR_BASE|0x17)
#define MSGQ_RECEIVE_TIMEOUT                     (MSG_ERROR_BASE|0x18)
#define MSGQ_TOO_MANY_QUEUES                     (MSG_ERROR_BASE|0x19)
#define MSGQ_MESSAGE_IS_QUEUED                   (MSG_ERROR_BASE|0x1A)
#define MSGQ_INVALID_QUEUE_NUMBER                (MSG_ERROR_BASE|0x1B)

#define MSG_CANNOT_CREATE_COMPONENT              (MSG_ERROR_BASE|0x20)



/* What the msg component valid field should be */
#define MESSAGE_VALID                 (_mqx_uint)(0x6d657373)   /* "mess" */

/* What a NULL pool id looks like.  Used for error returns from functions */
#define MSGPOOL_NULL_POOL_ID     ((_pool_id)0)

/* Maximum number of data bytes in a message. */
#define MSGPOOL_MESSAGE_DATA_SIZE \
   (MAX_UINT_16 - sizeof(MESSAGE_HEADER_STRUCT))

/* What a NULL queue id looks like. Used for error returns from functions */
#define MSGQ_NULL_QUEUE_ID    ((_queue_id)0)

/* For _msgq_receive, receives from any queue */
#define MSGQ_ANY_QUEUE        ((_queue_id)0)

/* For open queue, this queue number will return a free queue_id */
#define MSGQ_FREE_QUEUE       (0)

/* The maximum priority level for the message */
#define MSG_MAX_PRIORITY      (0xF)

/* The lowest queue provided by msgq_open with an MSGQ_MSGQ_ANY_QUEUE request. */
#define MSGQ_FIRST_USER_QUEUE (8)

/*--------------------------------------------------------------------------*/
/*
 *             MESSAGE STRUCTURE CONTROL FIELD BIT DEFINITIONS
 */

#define MSG_HDR_ENDIAN_MASK             (0x40)
#define MSG_DATA_ENDIAN_MASK            (0x20)

#define MSG_HDR_LITTLE_ENDIAN           (0x40)
#define MSG_DATA_LITTLE_ENDIAN          (0x20)

#define MSG_HDR_BIG_ENDIAN              (0x00)
#define MSG_DATA_BIG_ENDIAN             (0x00)

/* Is the message an urgent message */
#define MSG_HDR_URGENT                  (0x10)
#define MSG_HDR_PRIORITY_MASK           (0x0F)

/* NOTE that the lower nibble of the control field is the message priority */

#define MSG_IS_HDR_LITTLE_ENDIAN(ctrl) \
   (((ctrl) & MSG_HDR_ENDIAN_MASK) == MSG_HDR_LITTLE_ENDIAN)
#define MSG_IS_DATA_LITTLE_ENDIAN(ctrl) \
   (((ctrl) & MSG_DATA_ENDIAN_MASK) == MSG_DATA_LITTLE_ENDIAN)

#define MSG_IS_HDR_BIG_ENDIAN(ctrl) \
   (((ctrl) & MSG_HDR_ENDIAN_MASK) == MSG_HDR_BIG_ENDIAN)
#define MSG_IS_DATA_BIG_ENDIAN(ctrl) \
   (((ctrl) & MSG_DATA_ENDIAN_MASK) == MSG_DATA_BIG_ENDIAN)

/*
 * ENDIAN
 * Indicate in messages the endianness of the message
 */
#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
#define MSG_HDR_ENDIAN   MSG_HDR_LITTLE_ENDIAN
#define MSG_DATA_ENDIAN  MSG_DATA_LITTLE_ENDIAN
#else
#define MSG_HDR_ENDIAN   MSG_HDR_BIG_ENDIAN
#define MSG_DATA_ENDIAN  MSG_DATA_BIG_ENDIAN
#endif

#define MSG_MUST_CONVERT_HDR_ENDIAN(ctrl) \
   (((ctrl) & MSG_HDR_ENDIAN_MASK) != MSG_HDR_ENDIAN)

#define MSG_MUST_CONVERT_DATA_ENDIAN(ctrl) \
   (((ctrl) & MSG_DATA_ENDIAN_MASK) != MSG_DATA_ENDIAN)

#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
#define MSG_SET_DATA_ENDIAN(ctrl)  (ctrl |= MSG_DATA_LITTLE_ENDIAN)
#else
#define MSG_SET_DATA_ENDIAN(ctrl)  (ctrl &= ~MSG_DATA_LITTLE_ENDIAN)
#endif

/*--------------------------------------------------------------------------*/
/*
 *                    TYPEDEFS FOR _CODE_PTR_ FUNCTIONS
 */ 
 
typedef void (_CODE_PTR_ MSGQ_NOTIFICATION_FPTR)( pointer);

/*--------------------------------------------------------------------------*/
/*                        DATATYPE DEFINITIONS                          */

typedef pointer _pool_id;           /* what a pool_id looks like */
typedef uint_16 _msg_size;          /* what a message size looks like */
#if MQX_USE_32BIT_MESSAGE_QIDS
typedef uint_32 _queue_number;      /* what a queue number is         */
typedef uint_32 _queue_id;          /* What a queue_id looks like */
#else
typedef uint_16 _queue_number;      /* what a queue number is         */
typedef uint_16 _queue_id;          /* What a queue_id looks like */
#endif

/*--------------------------------------------------------------------------*/

/* MESSAGE HEADER STRUCT */
/*!
 * \brief This structure defines the first field (header) of any message.
 *  
 * Any pool of messsages must have at least this size and must start with a 
 * message header.
 * 
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _msg_free
 * \see _msgq_poll
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks
 * \see _msgq_receive_until
 * \see _msgq_send
 */
typedef struct message_header_struct
{
   /*! 
    * \brief The size of the DATA field in bytes, including the header. The 
    * maximum value is MAX_MESSAGE_SIZE. This field is set by the application. 
    */
   _msg_size       SIZE;

#if MQX_USE_32BIT_MESSAGE_QIDS
   uint_16         PAD;
#endif

   /*! 
    * \brief Queue ID of the queue to which MQX is to send the message. This 
    * field is set by the application. 
    */
   _queue_id       TARGET_QID;

   /*!
    * \brief Queue ID of a message queue that is associated with the sending
    * task. 
    * 
    * When messages are allocated, this field is initialized to MSGQ_NULL_QUEUE_ID. 
    * If the sending task does not have a message queue associated with it, MQX 
    * does not use this field.
    */
   _queue_id       SOURCE_QID;

   /*! 
    * \brief Indicates the following for the message: endian format, priority 
    * and urgency.
    */
   uchar           CONTROL;

#if MQX_USE_32BIT_MESSAGE_QIDS
   /*! \brief Not used. */
   uchar           RESERVED[3];
#else
   /*! \brief Not used. */
   uchar           RESERVED;
#endif

} MESSAGE_HEADER_STRUCT, _PTR_ MESSAGE_HEADER_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern pointer          _msg_alloc(_pool_id);
extern pointer          _msg_alloc_system(_msg_size);
extern _mqx_uint        _msg_available(_pool_id);
extern _mqx_uint        _msg_create_component(void);
extern void             _msg_free(pointer);
extern void             _msg_swap_endian_data(uchar _PTR_,
   MESSAGE_HEADER_STRUCT_PTR);
extern void             _msg_swap_endian_header(MESSAGE_HEADER_STRUCT_PTR);

extern _pool_id         _msgpool_create(uint_16, uint_16, uint_16, uint_16);
extern boolean          _msgpool_create_system(uint_16, uint_16, uint_16, 
   uint_16);
extern _mqx_uint        _msgpool_destroy(_pool_id);
extern _mqx_uint        _msgpool_test(pointer _PTR_, pointer _PTR_);

extern boolean          _msgq_close(_queue_id);
extern _mqx_uint        _msgq_get_count(_queue_id);
extern _queue_id        _msgq_get_id(_processor_number, _queue_number);
extern _task_id         _msgq_get_owner(_queue_id);
extern _mqx_uint        _msgq_get_notification_function(_queue_id,
   MSGQ_NOTIFICATION_FPTR _PTR_, pointer _PTR_);
extern _queue_id        _msgq_open(_queue_number, uint_16);
extern _queue_id        _msgq_open_system(_queue_number, uint_16, 
   MSGQ_NOTIFICATION_FPTR, pointer);
extern pointer          _msgq_poll(_queue_id);
extern pointer          _msgq_peek(_queue_id);
extern pointer          _msgq_receive(_queue_id, uint_32);
extern pointer          _msgq_receive_for(_queue_id, MQX_TICK_STRUCT_PTR);
extern pointer          _msgq_receive_ticks(_queue_id, _mqx_uint);
extern pointer          _msgq_receive_until(_queue_id, MQX_TICK_STRUCT_PTR);
extern boolean          _msgq_send(pointer);
extern _mqx_uint        _msgq_send_broadcast(pointer, _queue_id _PTR_, _pool_id);
extern boolean          _msgq_send_queue(pointer, _queue_id);
extern boolean          _msgq_send_urgent(pointer);
extern boolean          _msgq_send_priority(pointer, _mqx_uint);
extern MSGQ_NOTIFICATION_FPTR _msgq_set_notification_function(_queue_id,
   MSGQ_NOTIFICATION_FPTR, pointer);
extern _mqx_uint        _msgq_test(pointer _PTR_, pointer _PTR_);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/phy/phy_dp83xxx.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: phy_dp83xxx.h$
* $Version : 3.8.5.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*  This file contains definitions that belongs to the Natioanl Semiconductor
*  PHY chips DP83848, DP83849, DP83640.
*
*END************************************************************************/
#ifndef _phy_dp83xxx_h_
#define _phy_dp83xxx_h_ 1

#ifdef __cplusplus
extern "C" {
#endif

/*
** Phy Register Indexes - Common Across Device Types.
*/
#define DP83XXX_REG_BMCR        0x0000  /* Basic Mode Control Register */
#define DP83XXX_REG_BMSR        0x0001  /* Basic Mode Status Register */
#define DP83XXX_REG_IDR1        0x0002  /* PHY Identification Register #1 */
#define DP83XXX_REG_IDR2        0x0003  /* PHY Identification Register #2 */
#define DP83XXX_REG_ANAR        0x0004  /* Auto-Negotiation Advertisement Register */
#define DP83XXX_REG_ANLPAR      0x0005  /* Auto-Negotiation Link Partner Ability Register */
#define DP83XXX_REG_ANER        0x0006  /* Auto-Negotiation Expansion Register */
#define DP83XXX_REG_ANNPTR      0x0007  /* Auto-Negotiation Next Page TX Register */
#define DP83XXX_REG_PHYSTS      0x0010  /* PHY Status Register */
#define DP83XXX_REG_MICR        0x0011  /* MII Interrupt Control Register */
#define DP83XXX_REG_MISR        0x0012  /* MII Interrupt Status and Event Control Register */
#define DP83XXX_REG_PAGESEL     0x0013  /* Page Select Register */
#define DP83XXX_REG_FCSCR       0x0014  /* False Carrier Sense Counter Register */
#define DP83XXX_REG_RECR        0x0015  /* Receive Error Counter Register */
#define DP83XXX_REG_PCSR        0x0016  /* PCS Sub-Layer Configuration and Status Register */
#define DP83XXX_REG_RBR         0x0017  /* RMII and Bypass Register */
#define DP83XXX_REG_LEDCR       0x0018  /* LED Direct Control Register */
#define DP83XXX_REG_PHYCTRL     0x0019  /* PHY Control Register */
#define DP83XXX_REG_10BTSCR     0x001A  /* 10Base-T Status/Control Register */
#define DP83XXX_REG_CDCTRL1     0x001B  /* CD Test Control Register and BIST Extensions Register */
#define DP83XXX_REG_EDCR        0x001D  /* Energy Detect Control Register */

/*
** DP83849 / DP83640 Specific Register Indexes
** Note: Bits [6:5] specify the register page (00-pg0, 01-pg1, 10-pg2, 11-pg3)
*/
#define DP83XXX_REG_PG0_PHYCR2      0x001C
#define DP83XXX_REG_PG1_PMDCNFG     0x0034
#define DP83XXX_REG_PG1_TMR1        0x0035
#define DP83XXX_REG_PG1_TMR2        0x0036
#define DP83XXX_REG_PG1_DSP_CTRL1   0x0037
#define DP83XXX_REG_PG1_DSP_CTRL2   0x0038
#define DP83XXX_REG_PG1_TRL_CTRL    0x0039
#define DP83XXX_REG_PG1_DEQ_CTRL    0x003A
#define DP83XXX_REG_PG1_ANEG_TST    0x003B
#define DP83XXX_REG_PG1_EXTCFG      0x003C
#define DP83XXX_REG_PG1_TST_CTRL    0x003D
#define DP83XXX_REG_PG1_SD_CNFG     0x003E
#define DP83XXX_REG_PG1_TSTDAT      0x003F
#define DP83XXX_REG_PG2_LEN100_DET  0x0054
#define DP83XXX_REG_PG2_FREQ100     0x0055
#define DP83XXX_REG_PG2_TDR_CTRL    0x0056
#define DP83XXX_REG_PG2_TDR_WIN     0x0057
#define DP83XXX_REG_PG2_TDR_PEAK    0x0058
#define DP83XXX_REG_PG2_TDR_THR     0x0059
#define DP83XXX_REG_PG2_VAR_CTRL    0x005A
#define DP83XXX_REG_PG2_VAR_DATA    0x005B
#define DP83XXX_REG_PG2_LQMR        0x005D
#define DP83XXX_REG_PG2_LQDR        0x005E

/*
** DP83640 Specific Register Indexes
** Note: Bits [7:5] specify the register page (000-pg0, 001-pg1, 010-pg2, 011-pg3, etc.)
*/
#define DP83XXX_REG_PG2_LQMR2       0x005F
#define DP83XXX_REG_PG3_CGCR        0x0074
#define DP83XXX_REG_PG3_PTPTR       0x0075
#define DP83XXX_REG_PG3_CDCR1       0x0077
#define DP83XXX_REG_PG3_CDCR2       0x0078
#define DP83XXX_REG_PG3_FCO1CR      0x0079
#define DP83XXX_REG_PG3_FCO2CR      0x007A
#define DP83XXX_REG_PG3_ADCCR1      0x007B
#define DP83XXX_REG_PG3_ADCCR2      0x007C
#define DP83XXX_REG_PG3_BGREGCR     0x007D
#define DP83XXX_REG_PG3_CGMCR       0x007E
#define DP83XXX_REG_PG3_PGMCR       0x007F
#define DP83XXX_REG_PG4_PTP_CTL     0x0094
#define DP83XXX_REG_PG4_PTP_TDR     0x0095
#define DP83XXX_REG_PG4_PTP_STS     0x0096
#define DP83XXX_REG_PG4_PTP_TSTS    0x0097
#define DP83XXX_REG_PG4_PTP_RATEL   0x0098
#define DP83XXX_REG_PG4_PTP_RATEH   0x0099
#define DP83XXX_REG_PG4_PTP_RDCKSUM 0x009A
#define DP83XXX_REG_PG4_PTP_WRCKSUM 0x009B
#define DP83XXX_REG_PG4_PTP_TXTS    0x009C
#define DP83XXX_REG_PG4_PTP_RXTS    0x009D
#define DP83XXX_REG_PG4_PTP_ESTS    0x009E
#define DP83XXX_REG_PG4_PTP_EDATA   0x009F
#define DP83XXX_REG_PG5_PTP_TRIG    0x00B4
#define DP83XXX_REG_PG5_PTP_EVNT    0x00B5
#define DP83XXX_REG_PG5_PTP_TXCFG0  0x00B6
#define DP83XXX_REG_PG5_PTP_TXCFG1  0x00B7
#define DP83XXX_REG_PG5_PSF_CFG0    0x00B8
#define DP83XXX_REG_PG5_PTP_RXCFG0  0x00B9
#define DP83XXX_REG_PG5_PTP_RXCFG1  0x00BA
#define DP83XXX_REG_PG5_PTP_RXCFG2  0x00BB
#define DP83XXX_REG_PG5_PTP_RXCFG3  0x00BC
#define DP83XXX_REG_PG5_PTP_RXCFG4  0x00BD
#define DP83XXX_REG_PG5_PTP_TRDL    0x00BE
#define DP83XXX_REG_PG5_PTP_TRDH    0x00BF
#define DP83XXX_REG_PG6_PTP_COC     0x00D4
#define DP83XXX_REG_PG6_PSF_CFG1    0x00D5
#define DP83XXX_REG_PG6_PSF_CFG2    0x00D6
#define DP83XXX_REG_PG6_PSF_CFG3    0x00D7
#define DP83XXX_REG_PG6_PSF_CFG4    0x00D8
#define DP83XXX_REG_PG6_PTP_SFDCFG  0x00D9
#define DP83XXX_REG_PG6_PTP_INTCTL  0x00DA
#define DP83XXX_REG_PG6_PTP_CLKSRC  0x00DB
#define DP83XXX_REG_PG6_PTP_ETR     0x00DC
#define DP83XXX_REG_PG6_PTP_OFF     0x00DD
#define DP83XXX_REG_PG6_PTP_GPIOMON 0x00DE
#define DP83XXX_REG_PG6_PTP_RXHASH  0x00DF

/*
** Common Register Bit Definitions
*/

/* PHY_BMCR Defs */
#define DP83XXX_REG_BMCR_FORCE_SPEED_1000    0x0040
#define DP83XXX_REG_BMCR_COLLISION_TEST      0x0080
#define DP83XXX_REG_BMCR_FORCE_FULL_DUP      0x0100
#define DP83XXX_REG_BMCR_RESTART_AUTONEG     0x0200
#define DP83XXX_REG_BMCR_ISOLATE             0x0400
#define DP83XXX_REG_BMCR_POWER_DOWN          0x0800
#define DP83XXX_REG_BMCR_AUTO_NEG_ENABLE     0x1000
#define DP83XXX_REG_BMCR_FORCE_SPEED_100     0x2000
#define DP83XXX_REG_BMCR_FORCE_SPEED_10      0x0000
#define DP83XXX_REG_BMCR_FORCE_SPEED_MASK    0x2040
#define DP83XXX_REG_BMCR_LOOPBACK            0x4000
#define DP83XXX_REG_BMCR_RESET               0x8000

/* PHY_BMSR Defs */
#define DP83XXX_REG_BMSR_EXTENDED_CAPABLE    0x0001
#define DP83XXX_REG_BMSR_JABBER_DETECT       0x0002
#define DP83XXX_REG_BMSR_LINK_STATUS         0x0004
#define DP83XXX_REG_BMSR_AUTO_NEG_ABILITY    0x0008
#define DP83XXX_REG_BMSR_REMOTE_FAULT        0x0010
#define DP83XXX_REG_BMSR_AUTO_NEG_COMPLETE   0x0020
#define DP83XXX_REG_BMSR_PREAMBLE_SUPPRESS   0x0040
#define DP83XXX_REG_BMSR_RESERVED            0x0080
#define DP83XXX_REG_BMSR_1000T_EXT_STATUS    0x0100
#define DP83XXX_REG_BMSR_100T2_HALF_DUP      0x0200
#define DP83XXX_REG_BMSR_100T2_FULL_DUP      0x0400
#define DP83XXX_REG_BMSR_10T_HALF_DUP        0x0800
#define DP83XXX_REG_BMSR_10T_FULL_DUP        0x1000
#define DP83XXX_REG_BMSR_100X_HALF_DUP       0x2000
#define DP83XXX_REG_BMSR_100X_FULL_DUP       0x4000
#define DP83XXX_REG_BMSR_100T4_CAPABLE       0x8000

/* PHY_IDR1 Defs */
#define DP83XXX_REG_IDR1_NATIONAL_OUI_VAL    0x2000    /* OUI bits 3-18 */

/* PHY_IDR2 Defs */
#define DP83XXX_REG_IDR2_OUI_MASK            0xFC00
#define DP83XXX_REG_IDR2_MODEL_NUMBER_MASK   0x03F0
#define DP83XXX_REG_IDR2_REVISION_MASK       0x000F
#define DP83XXX_REG_IDR2_MODEL_SHIFT         4

#define DP83XXX_REG_IDR2_NATIONAL_OUI_VAL    0x5C00    /* OUI bits 19-24 (15:10), Vendor Model (9:4), Revision (3:0) */
#define DP83XXX_REG_IDR2_MODEL_DP83848_VAL   0x0090    /* AspenPhy */
#define DP83XXX_REG_IDR2_MODEL_DP48_MINI_VAL 0x00C0    /* AspenPhy - Mini */
#define DP83XXX_REG_IDR2_MODEL_DP83849_VAL   0x00A0    /* Dual AspenPhy */
#define DP83XXX_REG_IDR2_MODEL_DP83640_VAL   0x00E0    /* High Precision Phy */

#define DP83XXX_REG_IDR2_REV_DP83848E_VAL    0x0001    /* DP83848 Enhanced version */

/* PHY_ANAR Defs */
#define DP83XXX_REG_ANAR_PROTO_SEL_MASK      0x001F
#define DP83XXX_REG_ANAR_PROTO_8023          0x0001
#define DP83XXX_REG_ANAR_10T_HALF_DUP        0x0020
#define DP83XXX_REG_ANAR_10T_FULL_DUP        0x0040
#define DP83XXX_REG_ANAR_100T_HALF_DUP       0x0080
#define DP83XXX_REG_ANAR_100T_FULL_DUP       0x0100
#define DP83XXX_REG_ANAR_100T4_SUPPORT       0x0200
#define DP83XXX_REG_ANAR_PAUSE_SUPPORT       0x0400
#define DP83XXX_REG_ANAR_ASY_PAUSE_SUPPORT   0x0800
#define DP83XXX_REG_ANAR_RESERVED0           0x1000
#define DP83XXX_REG_ANAR_REMOTE_FAULT        0x2000
#define DP83XXX_REG_ANAR_RESERVED1           0x4000
#define DP83XXX_REG_ANAR_NEXT_PAGE_IND       0x8000

/* PHY_ANLPAR Defs */
#define DP83XXX_REG_ANLPAR_PROTO_SEL_MASK    0x001F
#define DP83XXX_REG_ANLPAR_10T_HALF_DUP      0x0020
#define DP83XXX_REG_ANLPAR_10T_FULL_DUP      0x0040
#define DP83XXX_REG_ANLPAR_100T_HALF_DUP     0x0080
#define DP83XXX_REG_ANLPAR_100T_FULL_DUP     0x0100
#define DP83XXX_REG_ANLPAR_100T4_SUPPORT     0x0200
#define DP83XXX_REG_ANLPAR_PAUSE_SUPPORT     0x0400
#define DP83XXX_REG_ANLPAR_ASY_PAUSE         0x0800
#define DP83XXX_REG_ANLPAR_RESERVED0         0x1000
#define DP83XXX_REG_ANLPAR_REMOTE_FAULT      0x2000
#define DP83XXX_REG_ANLPAR_ACK               0x4000
#define DP83XXX_REG_ANLPAR_NEXT_PAGE_IND     0x8000

/* PHY_ANER Defs */
#define DP83XXX_REG_ANER_AUTO_NEG_CAPABLE    0x0001
#define DP83XXX_REG_ANER_PAGE_RX             0x0002
#define DP83XXX_REG_ANER_NEXT_PAGE_ABLE      0x0004
#define DP83XXX_REG_ANER_PRT_NEXT_PAGE_ABLE  0x0008
#define DP83XXX_REG_ANER_PARALLEL_DET_FAULT  0x0010

/* PHY_ANNPTR Defs */
#define DP83XXX_REG_ANNPTR_CODE_MASK         0x07FF
#define DP83XXX_REG_ANNPTR_TOGGLE            0x0800
#define DP83XXX_REG_ANNPTR_ACK2              0x1000
#define DP83XXX_REG_ANNPTR_MSG_PAGE          0x2000
#define DP83XXX_REG_ANNPTR_ACK               0x4000
#define DP83XXX_REG_ANNPTR_NEXT_PAGE_IND     0x8000


/*
** DP83848 Specific Register Bit Definitions
*/

/* PHY_PHYSTS Defs */
#define DP83848_REG_STS_LINK            0x0001
#define DP83848_REG_STS_SPEED           0x0002
#define DP83848_REG_STS_DUPLEX          0x0004
#define DP83848_REG_STS_LOOPBACK        0x0008
#define DP83848_REG_STS_AUTO_NEG_DONE   0x0010
#define DP83848_REG_STS_JABBER_DETECT   0x0020
#define DP83848_REG_STS_REMOTE_FAULT    0x0040
#define DP83848_REG_STS_MII_INTERRUPT   0x0080
#define DP83848_REG_STS_PAGE_RXED       0x0100
#define DP83848_REG_STS_DESCRAMBLER     0x0200
#define DP83848_REG_STS_SIGNAL_DETECT   0x0400
#define DP83848_REG_STS_FALSE_CARRIER   0x0800
#define DP83848_REG_STS_POLARITY        0x1000
#define DP83848_REG_STS_RX_ERROR_LATCH  0x2000
#define DP83848_REG_STS_MDIX_MODE       0x4000

/* PHY_MICR Defs */
#define DP83848_REG_MICR_INTEN          0x0001
#define DP83848_REG_MICR_UNMSK_INT      0x0002
#define DP83848_REG_MICR_TINT           0x0004

/* PHY_MISR Defs */
#define DP83848_REG_MISR_UNMSK_RHF      0x0001
#define DP83848_REG_MISR_UNMSK_FHF      0x0002
#define DP83848_REG_MISR_UNMSK_ANC      0x0004
#define DP83848_REG_MISR_UNMSK_RF       0x0008
#define DP83848_REG_MISR_UNMSK_JAB      0x0010
#define DP83848_REG_MISR_UNMSK_LINK     0x0020
#define DP83848_REG_MISR_UNMSK_ED       0x0040
#define DP83848_REG_MISR_MSK_RHF        0x0100
#define DP83848_REG_MISR_MSK_FHF        0x0200
#define DP83848_REG_MISR_MSK_ANC        0x0400
#define DP83848_REG_MISR_MSK_RF         0x0800
#define DP83848_REG_MISR_MSK_JAB        0x1000
#define DP83848_REG_MISR_MSK_LINK       0x2000
#define DP83848_REG_MISR_MSK_ED         0x4000

/* PHY_PAGESEL Defs */
#define DP83848_REG_PAGESEL_PAGE_SEL    0x0001
#define DP83848_REG_PAGESEL_PAGE_0      0x0000
#define DP83848_REG_PAGESEL_PAGE_1      0x0001
#define DP83848_REG_PAGESEL_PAGE_2      0x0002
#define DP83848_REG_PAGESEL_PAGE_3      0x0003

/* PHY_FCSCR Defs */
#define DP83848_REG_FCSCR_FCSCNT_MASK   0x00FF

/* PHY_RECR Defs */
#define DP83848_REG_RECR_RXERRCNT_MASK  0x00FF

/* PHY_PCSR Defs */
#define DP83848_REG_PCSR_DESCRAM_BYP    0x0001
#define DP83848_REG_PCSR_SCRAM_BYP      0x0002
#define DP83848_REG_PCSR_NRZI_BYP       0x0004
#define DP83848_REG_PCSR_FEFI_EN        0x0008
#define DP83848_REG_PCSR_FEFI_TST       0x0010
#define DP83848_REG_PCSR_FORCE_100_OK   0x0020
#define DP83848_REG_PCSR_FX_EN          0x0040
#define DP83848_REG_PCSR_SD_OPTION      0x0100
#define DP83848_REG_PCSR_SD_FORCE_PMA   0x0200
#define DP83848_REG_PCSR_TQ_EN          0x0400
#define DP83848_REG_PCSR_FREE_CLK       0x0800
#define DP83848_REG_PCSR_BYP_4B5B       0x1000

/* PHY_RBR Defs */
#define DP83848_REG_RBR_RX_RD_4         0x0000
#define DP83848_REG_RBR_RX_RD_1         0x0001
#define DP83848_REG_RBR_RX_RD_2         0x0002
#define DP83848_REG_RBR_RX_RD_3         0x0003
#define DP83848_REG_RBR_RX_UNF_STS      0x0004
#define DP83848_REG_RBR_RX_OVF_STS      0x0008
#define DP83848_REG_RBR_RMII_REV1_0     0x0010
#define DP83848_REG_RBR_RMII_MODE       0x0020

/* PHY_LEDCR Defs */
#define DP83848_REG_LED_ACTLED          0x0001
#define DP83848_REG_LED_LNKLED          0x0002
#define DP83848_REG_LED_SPDLED          0x0004
#define DP83848_REG_LED_DRV_ACTLED      0x0008
#define DP83848_REG_LED_DRV_LNKLED      0x0010
#define DP83848_REG_LED_DRV_SPDLED      0x0020

/* PHY_PHYCTRL Defs */
#define DP83848_REG_PHYCTRL_ADDR_MASK   0x001F
#define DP83848_REG_PHYCTRL_LED_CFG0    0x0020
#define DP83848_REG_PHYCTRL_LED_CFG1    0x0040
#define DP83848_REG_PHYCTRL_BP_STRETCH  0x0080
#define DP83848_REG_PHYCTRL_BIST_START  0x0100
#define DP83848_REG_PHYCTRL_BIST_STS    0x0200
#define DP83848_REG_PHYCTRL_PSR_15      0x0400
#define DP83848_REG_PHYCTRL_BIST_FE     0x0800
#define DP83848_REG_PHYCTRL_PAUSE_TX    0x1000
#define DP83848_REG_PHYCTRL_PAUSE_RX    0x2000
#define DP83848_REG_PHYCTRL_FORCE_MDIX  0x4000
#define DP83848_REG_PHYCTRL_MDIX_EN     0x8000

/* PHY_10BTSCR Defs */
#define DP83848_REG_10BTSCR_JABBER_DIS  0x0001
#define DP83848_REG_10BTSCR_HRTBT_DIS   0x0002
#define DP83848_REG_10BTSCR_SCALE_MSB   0x0004
#define DP83848_REG_10BTSCR_ATDIS       0x0008
#define DP83848_REG_10BTSCR_POLARITY    0x0010
#define DP83848_REG_10BTSCR_FORCEPOL    0x0020
#define DP83848_REG_10BTSCR_FRC_10      0x0040
#define DP83848_REG_10BTSCR_LP_DIS      0x0080
#define DP83848_REG_10BTSCR_LP_10_DIS   0x0100
#define DP83848_REG_10BTSCR_SQLCH_MASK  0x0E00
#define DP83848_REG_10BTSCR_ERRRG_MASK  0x3000
#define DP83848_REG_10BTSCR_REJECT100T  0x4000
#define DP83848_REG_10BTSCR_10BT_SER    0x8000

/* PHY_CDCTRL1 Defs */
#define DP83848_REG_CDCTRL1_CDPATTSEL0  0x0001
#define DP83848_REG_CDCTRL1_CDPATTSEL1  0x0002
#define DP83848_REG_CDCTRL1_10MEG_PG    0x0004
#define DP83848_REG_CDCTRL1_CDPATTEN10  0x0010
#define DP83848_REG_CDCTRL1_BIST_CONT   0x0020
#define DP83848_REG_CDCTRL1_BIST_EC_MSK 0xFF00

/* PHY_EDCR Defs */
#define DP83848_REG_EDCR_DATA_CNT_MASK  0x000F
#define DP83848_REG_EDCR_ERR_CNT_MASK   0x00F0
#define DP83848_REG_EDCR_DATA_MET       0x0100
#define DP83848_REG_EDCR_ERR_MET        0x0200
#define DP83848_REG_EDCR_PWR_STATE      0x0400
#define DP83848_REG_EDCR_BURST_DIS      0x0800
#define DP83848_REG_EDCR_MANUAL_POWER   0x1000
#define DP83848_REG_EDCR_AUTO_DOWN      0x2000
#define DP83848_REG_EDCR_AUTO_UP        0x4000
#define DP83848_REG_EDCR_ENABLE         0x8000

/*
** DP83849 Dual Specific Register Bit Definitions
*/

/* PHY_RBR Defs Specific to this device */
#define DP83849_REG_RBR_ELAST_BUF_MASK  0x0003
#define DP83849_REG_RBR_ELAST_14_BIT    0x0000
#define DP83849_REG_RBR_ELAST_2_BIT     0x0001
#define DP83849_REG_RBR_ELAST_6_BIT     0x0002
#define DP83849_REG_RBR_ELAST_10_BIT    0x0003
#define DP83849_REG_RBR_SINGLE_CLK_TX   0x0040
#define DP83849_REG_RBR_SINGLE_CLK_RX   0x0080
#define DP83849_REG_RBR_PMD_LOOP        0x0100
#define DP83849_REG_RBR_TX_SOURCE_MASK  0x0600
#define DP83849_REG_RBR_TX_NORMAL       0x0000
#define DP83849_REG_RBR_TX_OPPOSITE     0x0200
#define DP83849_REG_RBR_TX_OPPOSITE_RX  0x0400
#define DP83849_REG_RBR_TX_DISABLED     0x0600
#define DP83849_REG_RBR_RX_PORT_MASK    0x1800
#define DP83849_REG_RBR_RX_NORMAL       0x0000
#define DP83849_REG_RBR_RX_OPPOSITE     0x0800
#define DP83849_REG_RBR_RX_BOTH_PORTS   0x1000
#define DP83849_REG_RBR_RX_DISABLED     0x1800
#define DP83849_REG_RBR_DIS_TX_LAT_OPT  0x2000
#define DP83849_REG_RBR_SIM_WRITE_EN    0x8000

#define DP83849_REG_RBR_NORMAL (DP83849_REG_RBR_RX_NORMAL | DP83849_REG_RBR_TX_NORMAL)
#define DP83849_REG_RBR_SWAP   (DP83849_REG_RBR_RX_OPPOSITE | DP83849_REG_RBR_TX_OPPOSITE)
#define DP83849_REG_RBR_EXT    (DP83849_REG_RBR_RX_DISABLED | DP83849_REG_RBR_TX_OPPOSITE_RX)

/* PHY_PG0_PHYCR2 Def's */
#define DP83849_REG_FAST_ADAPT          0x0001
#define DP83849_REG_SOFT_RESET          0x0200

/* PHY_PG1_PMDCNFG Def's */
#define DP83849_REG_TEST_MODE_MASK      0x0003
#define DP83849_REG_TEST_MODE_NORMAL    0x0000
#define DP83849_REG_TEST_MODE_ED_OB     0x0001
#define DP83849_REG_TEST_MODE_MDIX_OB   0x0002
#define DP83849_REG_TEST_MODE_FXC_OB    0x0003
#define DP83849_REG_LEN100_AEQ          0x0100
#define DP83849_REG_PMD_SOFT_RESET      0x0200
#define DP83849_REG_AUTO_NEG_LOOPBACK   0x8000

/* PHY_PG1_TMR1 Def's */
#define DP83849_REG_TEST_SEL_MASK       0x0007
#define DP83849_REG_TEST_SEL_NORMAL     0x0000
#define DP83849_REG_TEST_SEL_ADC        0x0001
#define DP83849_REG_TEST_SEL_CD_OB      0x0002
#define DP83849_REG_TEST_SEL_AN_RX_SM   0x0004
#define DP83849_REG_TEST_SEL_AN_TX_SM   0x0005
#define DP83849_REG_TEST_SEL_AN_ARM_SM  0x0006
#define DP83849_REG_TEST_SEL_NLPLIT_SM  0x0007
#define DP83849_REG_NRZ_OBSERVE         0x0008
#define DP83849_REG_BYP_PLLS            0x0010
#define DP83849_REG_BYP_ADC             0x0020
#define DP83849_REG_DIS_IO_TURBO        0x0040
#define DP83849_REG_ATP0_EN             0x0080
#define DP83849_REG_ATP1_EN             0x0100
#define DP83849_REG_SD_OBSERVE          0x0200
#define DP83849_REG_PWRUP_OBSERVE       0x0400
#define DP83849_REG_FCO_CTL_EN_OB       0x0800
#define DP83849_REG_INVERT_ADC_CLK      0x1000
#define DP83849_REG_MDIX_TX_INV         0x2000
#define DP83849_REG_ADC_CLK_BYPASS      0x4000
#define DP83849_REG_ADC_CLK_OE          0x8000

/* PHY_PG1_TMR2 Def's */
#define DP83849_REG_PGM_VFILTER_LOW     0x0001
#define DP83849_REG_PGM_VFILTER_HIGH    0x0002
#define DP83849_REG_CGM_VFILTER_LOW     0x0004
#define DP83849_REG_CGM_VFILTER_HIGH    0x0008
#define DP83849_REG_MR_AAGC_10MB_MASK   0x00F0
#define DP83849_REG_MR_AAGC_10MB_SHIFT  4
#define DP83849_REG_MR_TM_RXSEL_MASK    0x0C00
#define DP83849_REG_MR_TM_RXSEL_SHIFT   8
#define DP83849_REG_MR_TM_TXSEL_MASK    0xF000
#define DP83849_REG_MR_TM_TXSEL_SHIFT   12

/* PHY_PG1_DSP_CTRL1 Def's */
#define DP83849_REG_AGC_ALPHA_MASK      0x0003
#define DP83849_REG_FREEZE_AGC          0x0004
#define DP83849_REG_LOAD_AGC            0x0008
#define DP83849_REG_FREEZE_BLW          0x0010
#define DP83849_REG_LOAD_BLW            0x0020
#define DP83849_REG_FORCE_MSE_NOTOK     0x0040
#define DP83849_REG_FORCE_MSE_OK        0x0080
#define DP83849_REG_INIT_MSE            0x0100
#define DP83849_REG_MSE_THSEL           0x0200
#define DP83849_REG_AGC_7BITS           0x0400
#define DP83849_REG_BLW_8BITS           0x0800
#define DP83849_REG_IGNORE_MSEOK        0x2000
#define DP83849_REG_DIS_PMD_INIT        0x4000
#define DP83849_REG_PMD_INIT_TEST       0x8000

/* PHY_PG1_DSP_CTRL2 Def's */
#define DP83849_REG_AAGC_THRESH_MASK    0x001F
#define DP83849_REG_AAGC_FREEZE         0x0020
#define DP83849_REG_LOAD_AAGC_ACC       0x0040
#define DP83849_REG_LOAD_AAGC_TMR       0x0080
#define DP83849_REG_FORCE_AEQ           0x0100
#define DP83849_REG_FORCE_AEQ_VAL_MASK  0x0600
#define DP83849_REG_FORCE_AEQ_VAL_SHIFT 9
#define DP83849_REG_MAX_AEQ_MASK        0x1800
#define DP83849_REG_MAX_AEQ_SHIFT       11
#define DP83849_REG_DIS_AEQ_DECR        0x2000
#define DP83849_REG_LOAD_AEQ_THRESH     0x4000

/* PHY_PG1_TRL_CTRL Def's */
#define DP83849_REG_TRL_ALPHA_MASK      0x0003
#define DP83849_REG_TRL_ALPHA_SHIFT     0
#define DP83849_REG_TRL_BETA_MASK       0x000C
#define DP83849_REG_TRL_BETA_SHIFT      2
#define DP83849_REG_TRL_THRESH_MASK     0x00F0
#define DP83849_REG_TRL_THRESH_SHIFT    4
#define DP83849_REG_TRL_KILLREG         0x0100
#define DP83849_REG_TRL_SEL_REG         0x0200
#define DP83849_REG_RST_TRL_ON_ERR      0x0400
#define DP83849_REG_TRL_FRZ_ACC         0x0800
#define DP83849_REG_TRL_FRZ_LFO         0x1000
#define DP83849_REG_LOAD_TRL_PHASE      0x2000
#define DP83849_REG_LOAD_TRL_LFO        0x4000
#define DP83849_REG_LOAD_TRL_BETA       0x8000

/* PHY_PG1_DEQ_CTRL Def's */
#define DP83849_REG_KILL_COEFF_N1       0x0001
#define DP83849_REG_KILL_EQ_TAP0        0x0002
#define DP83849_REG_KILL_COEF1          0x0004
#define DP83849_REG_KILL_COEF2          0x0008
#define DP83849_REG_KILL_COEF3          0x0010
#define DP83849_REG_FREEZE_COEF         0x0020
#define DP83849_REG_NOSHIFT_N1          0x0040
#define DP83849_REG_EQ_LOAD_COEF1       0x0080
#define DP83849_REG_EQ_LOAD_COEF2       0x0100
#define DP83849_REG_EQ_LOAD_COEF3       0x0200
#define DP83849_REG_COEF1_9BITS         0x0400
#define DP83849_REG_COEF2_8BITS         0x0800
#define DP83849_REG_COEF3_7BITS         0x1000
#define DP83849_REG_ALLOW_POS_C1        0x2000

/* PHY_PG1_ANEG_TST Def's */
#define DP83849_REG_LOAD_ARB_TIMER      0x0100
#define DP83849_REG_LOAD_TX_TIMER       0x0200
#define DP83849_REG_LOAD_FLP_DATA_TIMER 0x0400
#define DP83849_REG_LOAD_NLP_MIN_TIMER  0x0800
#define DP83849_REG_LOAD_NLP_MAX_TIMER  0x1000
#define DP83849_REG_LOAD_NLP_RX_TIMER   0x2000
#define DP83849_REG_LOAD_ED_TIMER       0x4000

/* PHY_PG1_EXTCFG Def's */
#define DP83849_REG_ADC_WATCHDOG_EN     0x0001
#define DP83849_REG_ADC_WATCHDOG_TO_EN  0x0002
#define DP83849_REG_ADC_WATCHDOG_ERR    0x0004
#define DP83849_REG_MR_10BT_LR_MASK     0x0018
#define DP83849_REG_MR_10BT_LR_SHIFT    3
#define DP83849_REG_MR_NLP_RX_FIX       0x0020
#define DP83849_REG_ADC_WD_THRESH_MASK  0x07C0
#define DP83849_REG_ADC_WD_THRESH_SHIFT 6
#define DP83849_REG_LP_THRESHOLD_MASK   0xF800
#define DP83849_REG_LP_THRESHOLD_SHIFT  11

/* PHY_PG1_TST_CTRL Def's */
#define DP83849_REG_SAMPLE_DATA         0x0001
#define DP83849_REG_PLLBIST_RSTN        0x0002
#define DP83849_REG_PLLBIST_EN          0x0004
#define DP83849_REG_PLLBIST_MODE        0x0008
#define DP83849_REG_PLLBIST_DONE        0x0010
#define DP83849_REG_TEST_DATA_SEL_MASK  0xF800
#define DP83849_REG_TEST_DATA_SEL_SHIFT 11

/* PHY_PG1_SD_CNFG Def's */
#define DP83849_REG_SDOFFT_MASK         0x000F
#define DP83849_REG_SDOFFT_SHIFT        0
#define DP83849_REG_SDONT_MASK          0x00F0
#define DP83849_REG_SDONT_SHIFT         4
#define DP83849_REG_SIG_DET_TIME        0x0100
#define DP83849_REG_FORCE_SIG_DET_PMD   0x0200
#define DP83849_REG_10B_SCALE_LSB       0x0400
#define DP83849_REG_MR_SHORT_CABLE      0x0800
#define DP83849_REG_SIG_DET_TH_DELTA    0x1000
#define DP83849_REG_100B_PMA_TEST_EN    0x2000
#define DP83849_REG_AUTO_NEG_TEST_EN    0x4000
#define DP83849_REG_SIG_DET_PTOP        0x8000

/* PHY_PG2_LEN100_DET Def's */
#define DP83849_REG_CABLE_LEN_MASK      0x00FF
#define DP83849_REG_CABLE_LEN_SHIFT     0
#define DP83849_REG_AEQ_VAL_MASK        0x0300
#define DP83849_REG_AEQ_VAL_SHIFT       8

/* PHY_PG2_FREQ100 Def's */
#define DP83849_REG_FREQ_OFFSET_MASK    0x00FF
#define DP83849_REG_FREQ_OFFSET_SHIFT   0
#define DP83849_REG_SEL_FC              0x0100
#define DP83849_REG_SAMPLE_FREQ         0x8000

/* PHY_PG2_TDR_CTRL Def's */
#define DP83849_REG_RX_THRESHOLD_MASK   0x003F
#define DP83849_REG_RX_THRESHOLD_SHIFT  0
#define DP83849_REG_TDR_MIN_MODE        0x0080
#define DP83849_REG_TDR_WIDTH_MASK      0x0700
#define DP83849_REG_TDR_WIDTH_SHIFT     8
#define DP83849_REG_SEND_TDR            0x0800
#define DP83849_REG_RX_CHANNEL          0x1000
#define DP83849_REG_TX_CHANNEL          0x2000
#define DP83849_REG_TDR_100MB           0x4000
#define DP83849_REG_TDR_ENABLE          0x8000

/* PHY_PG2_TDR_WIN Def's */
#define DP83849_REG_TDR_STOP_MASK       0x00FF
#define DP83849_REG_TDR_STOP_SHIFT      0
#define DP83849_REG_TDR_START_MASK      0xFF00
#define DP83849_REG_TDR_START_SHIFT     8

/* PHY_PG2_TDR_PEAK Def's */
#define DP83849_REG_TDR_PEAK_TIME_MASK  0x00FF
#define DP83849_REG_TDR_PEAK_TIME_SHIFT 0
#define DP83849_REG_TDR_PEAK_MASK       0x3F00
#define DP83849_REG_TDR_PEAK_SHIFT      8

/* PHY_PG2_TDR_THR Def's */
#define DP83849_REG_TDR_THR_TIME_MASK   0x00FF
#define DP83849_REG_TDR_THR_TIME_SHIFT  0
#define DP83849_REG_TDR_THR_MET         0x0100

/* PHY_PG2_VAR_CTRL Def's */
#define DP83849_REG_VAR_ENABLE          0x0001
#define DP83849_REG_VAR_TIMER_MASK      0x0006
#define DP83849_REG_VAR_FREEZE          0x0008
#define DP83849_REG_VAR_RDY             0x8000

/* PHY_PG2_LQMR Def's */
#define DP83849_REG_C1_LO_WARN          0x0001
#define DP83849_REG_C1_HI_WARN          0x0002
#define DP83849_REG_DAGC_LO_WARN        0x0004
#define DP83849_REG_DAGC_HI_WARN        0x0008
#define DP83849_REG_DBLW_LO_WARN        0x0010
#define DP83849_REG_DBLW_HI_WARN        0x0020
#define DP83849_REG_FREQ_LO_WARN        0x0040
#define DP83849_REG_FREQ_HI_WARN        0x0080
#define DP83849_REG_FC_LO_WARN          0x0100
#define DP83849_REG_FC_HI_WARN          0x0200
#define DP83849_REG_BRK_LNK_C1          0x0400
#define DP83849_REG_BRK_LNK_DAGC        0x0800
#define DP83849_REG_BRK_LNK_DBLW        0x1000
#define DP83849_REG_BRK_LNK_FREQ        0x2000
#define DP83849_REG_BRK_LNK_FC          0x4000
#define DP83849_REG_LQM_ENABLE          0x8000

/* PHY_PG2_LQDR Def's */
#define DP83849_REG_LQ_THR_DATA_MASK    0x00FF
#define DP83849_REG_LQ_THR_DATA_SHIFT   0
#define DP83849_REG_LQ_THR_SEL          0x0100
#define DP83849_REG_LQ_PARAM_SEL_MASK   0x0E00
#define DP83849_REG_LQ_PARAM_SEL_SHIFT  9
#define DP83849_REG_WRITE_LQ_THR        0x1000
#define DP83849_REG_SAMPLE_PARAM        0x2000


/*
** DP83640 Specific Register Bit Definitions
*/

/* PHY_PG0_PHYCR2 Def's */
#define DP83640_REG_SYNC_ENET_EN       0x2000
#define DP83640_REG_CLK_OUT_RX_EN      0x1000
#define DP83640_REG_BC_WRITE_EN        0x0800
#define DP83640_REG_PHY_CMP_MD         0x0400
#define DP83640_REG_SOFT_RESET         0x0200
#define DP83640_REG_CLK_OUT_DIS        0x0002

/* PHY_PG0_PCFCR Def's */
#define DP83640_REG_PCFCR              0x001F
#define DP83640_REG_PCF_EN             0x0001
#define DP83640_REG_PCF_BUF_SHIFT      1
#define DP83640_REG_PCF_BUF_MASK       0x001E
#define DP83640_REG_PCF_BC_DIS         0x0020
#define DP83640_REG_PCF_INT_CTL_SHIFT  6
#define DP83640_REG_PCF_INT_CTL_MASK   0x00C0
#define DP83640_REG_PCF_DA_SEL         0x0100
#define DP83640_REG_PCF_STS_OK         0x4000
#define DP83640_REG_PCF_STS_ERR        0x8000

/* PHY_PG2_LQMR2 Def's */
#define DP83640_REG_RESTART_ON_VAR     0x0400
#define DP83640_REG_VAR_HIGH_WARN      0x0002

/* PHY_PG3_CGCR Def's */
#define DP83640_REG_DIS_TRIG_UPD_GATE  0x8000
#define DP83640_REG_DIS_TX_TS_GATE     0x4000
#define DP83640_REG_DIS_RX_TS_GATE     0x2000
#define DP83640_REG_DIS_RX_INFO_GATE   0x1000
#define DP83640_REG_DIS_EVNT_GATE      0x0800
#define DP83640_REG_DIS_CLK_UPD_GATE   0x0400
#define DP83640_REG_DIS_REG125_GATE    0x0200
#define DP83640_REG_DIS_CLKTX_GATE     0x0100
#define DP83640_REG_DIS_CLKRX_GATE     0x0080
#define DP83640_REG_DIS_CLK125_GATE    0x0040
#define DP83640_REG_DIS_CLKDIV_GATE    0x0020
#define DP83640_REG_DIS_ADC125_GATE    0x0004
#define DP83640_REG_DIS_ADC80_GATE     0x0002
#define DP83640_REG_DIS_REGCLK_GATE    0x0001

/* PHY_PG4_PTP_CTL Def's */
#define DP83640_REG_TRIG_SEL_SHIFT     10
#define DP83640_REG_TRIG_SEL_MASK      0x1C00
#define DP83640_REG_TRIG_DIS           0x0200
#define DP83640_REG_TRIG_EN            0x0100
#define DP83640_REG_TRIG_READ          0x0080
#define DP83640_REG_TRIG_LOAD          0x0040
#define DP83640_REG_PTP_RD_CLK         0x0020
#define DP83640_REG_PTP_LOAD_CLK       0x0010
#define DP83640_REG_PTP_STEP_CLK       0x0008
#define DP83640_REG_PTP_ENABLE         0x0004
#define DP83640_REG_PTP_DISABLE        0x0002
#define DP83640_REG_PTP_RESET          0x0001

/* PHY_PG4_PTP_STS Def's */
#define DP83640_REG_TXTS_RDY           0x0800
#define DP83640_REG_RXTS_RDY           0x0400
#define DP83640_REG_TRIG_DONE          0x0200
#define DP83640_REG_EVENT_RDY          0x0100
#define DP83640_REG_TXTS_IE            0x0008
#define DP83640_REG_RXTS_IE            0x0004
#define DP83640_REG_TRIG_IE            0x0002
#define DP83640_REG_EVENT_IE           0x0001

/* PHY_PG4_PTP_TSTS Def's */
#define DP83640_REG_TRIG7_ERROR        0x8000
#define DP83640_REG_TRIG7_ACTIVE       0x4000
#define DP83640_REG_TRIG6_ERROR        0x2000
#define DP83640_REG_TRIG6_ACTIVE       0x1000
#define DP83640_REG_TRIG5_ERROR        0x0800
#define DP83640_REG_TRIG5_ACTIVE       0x0400
#define DP83640_REG_TRIG4_ERROR        0x0200
#define DP83640_REG_TRIG4_ACTIVE       0x0100
#define DP83640_REG_TRIG3_ERROR        0x0080
#define DP83640_REG_TRIG3_ACTIVE       0x0040
#define DP83640_REG_TRIG2_ERROR        0x0020
#define DP83640_REG_TRIG2_ACTIVE       0x0010
#define DP83640_REG_TRIG1_ERROR        0x0008
#define DP83640_REG_TRIG1_ACTIVE       0x0004
#define DP83640_REG_TRIG0_ERROR        0x0002
#define DP83640_REG_TRIG0_ACTIVE       0x0001

/* PHY_PG4_PTP_RATEH Def's */
#define DP83640_REG_PTP_RATE_DIR       0x8000
#define DP83640_REG_PTP_TMP_RATE       0x4000
#define DP83640_REG_PTP_RATE_HI_MASK   0x03FF
#define DP83640_REG_PTP_RATE_HI_SHIFT  16

/* PHY_PG4_PTP_ESTS Def's */
#define DP83640_REG_EVNTS_MISSED_SHIFT 8
#define DP83640_REG_EVNTS_MISSED_MASK  0x0700
#define DP83640_REG_EVNTS_TS_LEN_SHIFT 6
#define DP83640_REG_EVNTS_TS_LEN_MASK  0x00C0
#define DP83640_REG_EVNT_RF            0x0020
#define DP83640_REG_EVNT_NUM_SHIFT     2
#define DP83640_REG_EVNT_NUM_MASK      0x001C
#define DP83640_REG_MULT_EVENT         0x0002
#define DP83640_REG_EVENT_DET          0x0001

/* PHY_PG4_PTP_EDATA Def's */
#define DP83640_REG_E7_RISE            0x8000
#define DP83640_REG_E7_DET             0x4000
#define DP83640_REG_E6_RISE            0x2000
#define DP83640_REG_E6_DET             0x1000
#define DP83640_REG_E5_RISE            0x0800
#define DP83640_REG_E5_DET             0x0400
#define DP83640_REG_E4_RISE            0x0200
#define DP83640_REG_E4_DET             0x0100
#define DP83640_REG_E3_RISE            0x0080
#define DP83640_REG_E3_DET             0x0040
#define DP83640_REG_E2_RISE            0x0020
#define DP83640_REG_E2_DET             0x0010
#define DP83640_REG_E1_RISE            0x0008
#define DP83640_REG_E1_DET             0x0004
#define DP83640_REG_E0_RISE            0x0002
#define DP83640_REG_E0_DET             0x0001

/* PHY_PG5_PTP_TRIG Def's */
#define DP83640_REG_TRIG_PULSE         0x8000
#define DP83640_REG_TRIG_PER           0x4000
#define DP83640_REG_TRIG_IF_LATE       0x2000
#define DP83640_REG_TRIG_NOTIFY        0x1000
#define DP83640_REG_TRIG_GPIO_SHIFT    8
#define DP83640_REG_TRIG_GPIO_MASK     0x0F00
#define DP83640_REG_TRIG_TOGGLE        0x0080
#define DP83640_REG_TRIG_CSEL_SHIFT    1
#define DP83640_REG_TRIG_CSEL_MASK     0x000E
#define DP83640_REG_TRIG_WR            0x0001

/* PHY_PG5_PTP_EVNT Def's */
#define DP83640_REG_EVNT_RISE          0x4000
#define DP83640_REG_EVNT_FALL          0x2000
#define DP83640_REG_EVNT_GPIO_SHIFT    8
#define DP83640_REG_EVNT_GPIO_MASK     0x0F00
#define DP83640_REG_EVNT_SEL_SHIFT     1
#define DP83640_REG_EVNT_SEL_MASK      0x000E
#define DP83640_REG_EVNT_WR            0x0001

/* PHY_PG5_PTP_TXCFG0 Def's */
#define DP83640_REG_SYNC_1STEP         0x8000
#define DP83640_REG_DR_INSERT          0x2000
#define DP83640_REG_IP_DIRECT          0x1000
#define DP83640_REG_IGNORE_2STEP       0x0800
#define DP83640_REG_CRC_1STEP          0x0400
#define DP83640_REG_CHK_1STEP          0x0200
#define DP83640_REG_IP1588_EN          0x0100
#define DP83640_REG_TX_L2_EN           0x0080
#define DP83640_REG_TX_IPV6_EN         0x0040
#define DP83640_REG_TX_IPV4_EN         0x0020
#define DP83640_REG_TX_PTP_VER_SHIFT   1
#define DP83640_REG_TX_PTP_VER_MASK    0x001E
#define DP83640_REG_TX_TS_EN           0x0001

/* PHY_PG5_PTP_TXCFG1 Def's */
#define DP83640_REG_BYTE0_MASK_SHIFT   8
#define DP83640_REG_BYTE0_MASK_MASK    0xFF00
#define DP83640_REG_BYTE0_DATA_SHIFT   0
#define DP83640_REG_BYTE0_DATA_MASK    0x00FF

/* PHY_PG5_PSF_CFG0 Def's */
#define DP83640_REG_MAC_SRC_ADD_SHIFT  11
#define DP83640_REG_MAC_SRC_ADD_MASK   0x1800
#define DP83640_REG_MIN_PRE_SHIFT      8
#define DP83640_REG_MIN_PRE_MASK       0x0700
#define DP83640_REG_PKT_ENDIAN         0x0080
#define DP83640_REG_PKT_IPV4           0x0040
#define DP83640_REG_PKT_PCFR_EN        0x0020
#define DP83640_REG_PKT_ERR_EN         0x0010
#define DP83640_REG_PKT_TXTS_EN        0x0008
#define DP83640_REG_PKT_RXTS_EN        0x0004
#define DP83640_REG_PKT_TRIG_EN        0x0002
#define DP83640_REG_PKT_EVNT_EN        0x0001

/* PHY_PG5_PTP_RXCFG0 Def's */
#define DP83640_REG_DOMAIN_EN          0x8000
#define DP83640_REG_ALT_MAST_DIS       0x4000
#define DP83640_REG_USER_IP_SEL        0x2000
#define DP83640_REG_USER_IP_EN         0x1000
#define DP83640_REG_RX_SLAVE           0x0800
#define DP83640_REG_IP1588_EN2         0x0400
#define DP83640_REG_IP1588_EN1         0x0200
#define DP83640_REG_IP1588_EN0         0x0100
#define DP83640_REG_RX_L2_EN           0x0080
#define DP83640_REG_RX_IPV6_EN         0x0040
#define DP83640_REG_RX_IPV4_EN         0x0020
#define DP83640_REG_RX_PTP_VER_SHIFT   1
#define DP83640_REG_RX_PTP_VER_MASK    0x001E
#define DP83640_REG_RX_TS_EN           0x0001

/* PHY_PG5_PTP_RXCFG1 Def's */
#define DP83640_REG_BYTE0_MASK_SHIFT   8
#define DP83640_REG_BYTE0_MASK_MASK    0xFF00
#define DP83640_REG_BYTE0_DATA_SHIFT   0
#define DP83640_REG_BYTE0_DATA_MASK    0x00FF

/* PHY_PG5_PTP_RXCFG3 Def's */
#define DP83640_REG_TS_MIN_IFG_SHIFT   12
#define DP83640_REG_TS_MIN_IFG_MASK    0xF000
#define DP83640_REG_ACC_UDP            0x0800
#define DP83640_REG_ACC_CRC            0x0400
#define DP83640_REG_TS_APPEND          0x0200
#define DP83640_REG_TS_INSERT          0x0100
#define DP83640_REG_PTP_DOMAIN_SHIFT   0
#define DP83640_REG_PTP_DOMAIN_MASK    0x00FF

/* PHY_PG5_PTP_RXCFG4 Def's */
#define DP83640_REG_IPV4_UDP_MOD       0x8000
#define DP83640_REG_TS_SEC_EN          0x4000
#define DP83640_REG_TS_SEC_LEN_SHIFT   12
#define DP83640_REG_TS_SEC_LEN_MASK    0x3000
#define DP83640_REG_RXTS_NS_OFF_SHIFT  6
#define DP83640_REG_RXTS_NS_OFF_MASK   0x0FC0
#define DP83640_REG_RXTS_SEC_OFF_SHIFT 0
#define DP83640_REG_RXTS_SEC_OFF_MASK  0x003F

/* PHY_PG5_PTP_TRDH Def's */
#define DP83640_REG_PTP_TR_DURH_SHIFT  0
#define DP83640_REG_PTP_TR_DURH_MASK   0x03FF

/* PHY_PG6_PTP_COC Def's */
#define DP83640_REG_PTP_CLKOUT_EN      0x8000
#define DP83640_REG_PTP_CLKOUT_SEL     0x4000
#define DP83640_REG_PTP_CLKOUT_SPSEL   0x2000
#define DP83640_REG_PTP_CLKDIV_SHIFT   0
#define DP83640_REG_PTP_CLKDIV_MASK    0x00FF

/* PHY_PG6_PSF_CFG1 Def's */
#define DP83640_REG_PTP_RESERVED_SHIFT 12
#define DP83640_REG_PTP_RESERVED_MASK  0xF000
#define DP83640_REG_VERSION_PTP_SHIFT  8
#define DP83640_REG_VERSION_PTP_MASK   0x0F00
#define DP83640_REG_TRANSP_SPEC_SHIFT  4
#define DP83640_REG_TRANSP_SPEC_MASK   0x00F0
#define DP83640_REG_MESSAGE_TYPE_SHIFT 0
#define DP83640_REG_MESSAGE_TYPE_MASK  0x000F

/* PHY_PG6_PSF_CFG2 Def's */
#define DP83640_REG_IP_SA_BYTE1_SHIFT  8
#define DP83640_REG_IP_SA_BYTE1_MASK   0xFF00
#define DP83640_REG_IP_SA_BYTE0_SHIFT  0
#define DP83640_REG_IP_SA_BYTE0_MASK   0x00FF

/* PHY_PG6_PSF_CFG3 Def's */
#define DP83640_REG_IP_SA_BYTE3_SHIFT  8
#define DP83640_REG_IP_SA_BYTE3_MASK   0xFF00
#define DP83640_REG_IP_SA_BYTE2_SHIFT  0
#define DP83640_REG_IP_SA_BYTE2_MASK   0x00FF

/* PHY_PG6_PTP_SFDCFG Def's */
#define DP83640_REG_TX_SFD_GPIO_SHIFT  4
#define DP83640_REG_TX_SFD_GPIO_MASK   0x00F0
#define DP83640_REG_RX_SFD_GPIO_SHIFT  0
#define DP83640_REG_RX_SFD_GPIO_MASK   0x000F

/* PHY_PG6_PTP_INTCTL Def's */
#define DP83640_REG_PTP_INT_GPIO_SHIFT 0
#define DP83640_REG_PTP_INT_GPIO_MASK  0x000F

/* PHY_PG6_PTP_CLKSRC Def's */
#define DP83640_REG_CLK_SRC_SHIFT      14
#define DP83640_REG_CLK_SRC_MASK       0xC000
#define DP83640_REG_CLK_SRC_PER_SHIFT  0
#define DP83640_REG_CLK_SRC_PER_MASK   0x007F

/* PHY_PG6_PTP_OFF Def's */
#define DP83640_REG_PTP_OFFSET_SHIFT   0
#define DP83640_REG_PTP_OFFSET_MASK    0x00FF

/* PHY_PG6_PTP_GPIOMON Def's */
#define DP83640_REG_PTP_GPIO_IN_SHIFT  0
#define DP83640_REG_PTP_GPIO_IN_MASK   0x0FFF

/* PHY_PG6_PTP_RXHASH Def's */
#define DP83640_REG_RX_HASH_EN         0x1000
#define DP83640_REG_PTP_RX_HASH_SHIFT  0
#define DP83640_REG_PTP_RX_HASH_MASK   0x0FFF

extern const ENET_PHY_IF_STRUCT phy_dp83xxx_IF;

#define MII_TIMEOUT                     (0x10000)

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/i2c_ki2c.h<|end_filename|>
#ifndef _ki2c_h
#define _ki2c_h 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_ki2c.h$
* $Version : 3.8.8.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the I2C drivers for the Kinetis family.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** KI2C_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a serial port is initialized.
*/
typedef struct ki2c_init_struct
{
   /* The I2C channel to initialize */
   uint_8                 CHANNEL;

   /* Default operating mode */
   uint_8                 MODE;

   /* The I2C station address for the channel */
   uint_8                 STATION_ADDRESS;

   /* Desired baud rate */
   uint_32                BAUD_RATE;

   
#if !(BSP_TWRMCF51FD || BSP_TWRMCF51JF || BSP_TWRMCF51QM)   
   /* Interrupt level to use if interrupt driven */
   _int_level             LEVEL;

   /* Sub level within the interrupt level to use if interrupt driven */
   _int_priority          SUBLEVEL;
#endif
   /* Tx buffer size (interrupt only) */
   uint_32                TX_BUFFER_SIZE;

   /* Rx buffer size (interrupt only) */
   uint_32                RX_BUFFER_SIZE;

} KI2C_INIT_STRUCT, _PTR_ KI2C_INIT_STRUCT_PTR;

typedef const KI2C_INIT_STRUCT _PTR_ KI2C_INIT_STRUCT_CPTR;

/*--------------------------------------------------------------------------*/
/* 
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern uint_32 _ki2c_polled_install (char_ptr, KI2C_INIT_STRUCT_CPTR);
extern uint_32 _ki2c_int_install (char_ptr, KI2C_INIT_STRUCT_CPTR);
extern pointer _bsp_get_i2c_base_address (uint_8);
extern uint_32 _bsp_get_i2c_vector (uint_8);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/os/mqx25x/rtcspart.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcspart.c$
* $Version : 3.8.11.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the interface to the RTCS
*   partitions.
*
*END************************************************************************/

#include <rtcs.h>


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_mem_alloc
* Returned Values : An _rtcs_part if successful, or 0 if creation fails.
* Comments        :
*     Create and initialize a partition.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_mem_alloc(_mem_size size)
{
   if (_RTCS_mem_pool) {
      return _mem_alloc_from(_RTCS_mem_pool, size);
   } else {
      return _mem_alloc(size);
   }
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_mem_alloc_zero
* Returned Values : An _rtcs_part if successful, or 0 if creation fails.
* Comments        :
*     Create and initialize a partition.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_mem_alloc_zero(_mem_size size)
{
   if (_RTCS_mem_pool) {
      return _mem_alloc_zero_from(_RTCS_mem_pool, size);
   } else {
      return _mem_alloc_zero(size);
   }
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_mem_alloc_system
* Returned Values : An _rtcs_part if successful, or 0 if creation fails.
* Comments        :
*     Create and initialize a partition.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_mem_alloc_system(_mem_size size)
{
   if (_RTCS_mem_pool) {
      return _mem_alloc_system_from(_RTCS_mem_pool, size);
   } else {
      return _mem_alloc_system(size);
   }
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_mem_alloc_system_zero
* Returned Values : An _rtcs_part if successful, or 0 if creation fails.
* Comments        :
*     Create and initialize a partition.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_mem_alloc_system_zero(_mem_size size)
{
   if (_RTCS_mem_pool) {
      return _mem_alloc_system_zero_from(_RTCS_mem_pool, size);
   } else {
      return _mem_alloc_system_zero(size);
   }
}

#if RTCSCFG_USE_MQX_PARTITIONS
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_create
* Returned Values : An _rtcs_part if successful, or 0 if creation fails.
* Comments        :
*     Create and initialize a partition.
*
*END*-----------------------------------------------------------------*/

_rtcs_part RTCS_part_create
   (
      uint_32 size,                       /* [IN] size of one block */
      uint_32 init,                       /* [IN] initial number of blocks */
      uint_32 grow,                       /* [IN] number of blocks to grow by */
      uint_32 max,                        /* [IN] maximum number of blocks */
      int_32 (_CODE_PTR_ cons)(pointer),  /* [IN] block constructor */
      int_32 (_CODE_PTR_ dest)(pointer)   /* [IN] block destroyer */
   )
{ /* Body */
   _rtcs_part     part;
   pointer _PTR_  elem;
   uint_32        i;

   /* Allocate partition */
   part = RTCS_mem_alloc_system(sizeof(*part));
   if (!part) {
      return NULL;
   } /* Endif */
   
   _mem_set_type(part, MEM_TYPE_RTCS_PARTITION);

   part->PART = _partition_create(size + sizeof(pointer), init, grow, max);
   if (part->PART == PARTITION_NULL_ID) {
      _mem_free(part);
      return NULL;
   } /* Endif */

   /* Set up partition information */
   part->SIZE   = size;
   part->FREE   = NULL;
   part->CONSTR = cons;
   part->DESTR  = dest;

   /* Pre-construct some blocks and enqueue them */
   for (i = 0; i < init; i++) {
      elem = _partition_alloc_system(part->PART);
      if (!elem) {
         break;
      } /* Endif */
      if (part->CONSTR) {
         if (part->CONSTR(elem+1)) {
            _partition_free(elem);
            break;
         } /* Endif */
      } /* Endif */
      *elem = part;
      RTCS_part_free(elem+1);
   } /* Endfor */

   return part;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_alloc
* Returned Values : A pointer to a partition block if successful, or
*                   NULL if allocation fails.
* Comments        :
*     Allocate a partition block.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_part_alloc
   (
      _rtcs_part part            /* [IN] partition to allocate from */
   )
{ /* Body */
   pointer _PTR_  elem;

   _int_disable();
   if (!part->FREE) {
      _int_enable();

      /* Allocate a new block and construct it */
      elem = _partition_alloc_system(part->PART);
      if (!elem) {
         return NULL;
      } /* Endif */
      if (part->CONSTR) {
         if (part->CONSTR(elem+1)) {
            _partition_free(elem);
            return NULL;
         } /* Endif */
      } /* Endif */

   } else {
      // NOTE: we may have been interrupted here, and part-FREE may have become NULL 
      /* Dequeue a block */
      elem = part->FREE;
      part->FREE = *elem;
      _int_enable();

   } /* Endif */

   /* Point the block back to the partition (for RTCS_part_free()) */
   *elem = part;
   return elem + 1;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_alloc_zero
* Returned Values : A pointer to a zeroed partition block if successful,
*                   or NULL if allocation fails.
* Comments        :
*     Allocate a partition block and zero it.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_part_alloc_zero
   (
      _rtcs_part part            /* [IN] partition to allocate from */
   )
{ /* Body */
   pointer elem;

   elem = RTCS_part_alloc(part);
   if (elem) {
      _mem_zero(elem, part->SIZE);
   } /* Endif */

   return elem;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_free
* Returned Values : void
* Comments        :
*     Free a partition block.
*
*END*-----------------------------------------------------------------*/

void RTCS_part_free
   (
      pointer block              /* [IN] block to free */
   )
{ /* Body */
   pointer _PTR_  elem = block;
   _rtcs_part     part;

   part = *--elem;

   _int_disable();
   *elem = part->FREE;
   part->FREE = elem;
   _int_enable();

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_destroy
* Returned Values : void
* Comments        :
*     Destroy a partition
*
*END*-----------------------------------------------------------------*/

void RTCS_part_destroy
   (
      _rtcs_part part            /* [IN] partition to destroy */
   )
{ /* Body */
   pointer _PTR_  elem;

   /* Destroy all the elements */
   /* If we have destroy function ->  use it. */
    if (part->DESTR) 
    {
        while (part->FREE) 
        {
            elem = part->FREE;
            part->FREE = *elem;
            part->DESTR(elem+1);
            /*_partition_free(elem);*/
        } /* Endwhile */
    }
    else
    {   /* If not, lets use standart MQX function. */
        while (part->FREE) 
        {
            elem = part->FREE;
            part->FREE = *elem;
            _partition_free(elem);
        }
    }

   /* Free the partition */
    _partition_destroy(part->PART);
    _mem_free(part);

} /* Endbody */


#else

#define RTCS_PART_ALIGN(n) ((n) + (-(n) & 3))

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_grow
* Returned Values : RTCS_OK if successful, or RTCS_ERROR if a
*                   constructor failed
* Comments        :
*     Add blocks to a partition.
*
*END*-----------------------------------------------------------------*/

static RTCS_part_grow
   (
      _rtcs_part  part,          /* [IN] partition to grow */
      pointer     blocks,        /* [IN] array of blocks to add to part */
      uint_32     num_blocks     /* [IN] number of blocks to add to part */
   )
{ /* Body */
   uint_32  i;
   pointer  elem;

   /* Construct all the blocks */
   if (part->CONSTR) {
      elem = blocks;
      elem = (pointer _PTR_)elem + 1;
      for (i = 0; i < num_blocks; i++) {
         if (part->CONSTR(elem)) {
            if (part->DESTR) {
               while (i > 0) {
                  elem = (char_ptr)elem - part->BLOCK_SIZE;
                  part->DESTR(elem);
                  i--;
               } /* Endwhile */
            } /* Endif */
            return RTCS_ERROR;
         } /* Endif */
         elem = (char_ptr)elem + part->BLOCK_SIZE;
      } /* Endfor */
   } /* Endif */

   /* Add the blocks to the free list */
   part->NUM_BLOCKS += num_blocks;
   elem = blocks;
   for (i = 0; i < num_blocks; i++) {
      *(pointer _PTR_)elem = part;
      RTCS_part_free((pointer _PTR_)elem+1);
      elem = (char_ptr)elem + part->BLOCK_SIZE;
   } /* Endfor */

   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_create
* Returned Values : An _rtcs_part if successful, or 0 if creation fails.
* Comments        :
*     Create and initialize a partition.
*
*END*-----------------------------------------------------------------*/

_rtcs_part RTCS_part_create
   (
      uint_32 size,                       /* [IN] size of one block */
      uint_32 init,                       /* [IN] initial number of blocks */
      uint_32 grow,                       /* [IN] number of blocks to grow by */
      uint_32 max,                        /* [IN] maximum number of blocks */
      int_32 (_CODE_PTR_ cons)(pointer),  /* [IN] block constructor */
      int_32 (_CODE_PTR_ dest)(pointer)   /* [IN] block destroyer */
   )
{ /* Body */
   _rtcs_part  part;

   /* Allocate partition and initial blocks */
   size = RTCS_PART_ALIGN(sizeof(pointer) + size);
   part = _mem_alloc_system(sizeof(*part) + size * init);
   if (!part) {
      return NULL;
   } /* Endif */

   _mem_set_type(part, MEM_TYPE_RTCS_PARTITION);
 
   /* Set up partition information */
   part->BLOCK_SIZE  = size;
   part->NUM_BLOCKS  = 0;
   part->GROW_BLOCKS = grow;
   part->MAX_BLOCKS  = max;
   part->GROW        = NULL;
   part->FREE        = NULL;
   part->CONSTR      = cons;
   part->DESTR       = dest;

   /* Construct all the blocks and add them to the free list */
   if (RTCS_part_grow(part, part+1, init) == RTCS_ERROR) {
      _mem_free(part);
      return NULL;
   } /* Endif */

   return part;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_alloc
* Returned Values : A pointer to a partition block if successful, or
*                   NULL if allocation fails.
* Comments        :
*     Allocate a partition block.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_part_alloc
   (
      _rtcs_part part            /* [IN] partition to allocate from */
   )
{ /* Body */
   uint_32        new_blocks;
   pointer        grow;
   pointer _PTR_  elem;

   if (!part->FREE && part->GROW_BLOCKS) {
      _int_disable();
      if (!part->MAX_BLOCKS || (part->NUM_BLOCKS < part->MAX_BLOCKS)) {
         new_blocks = part->GROW_BLOCKS;
         if (part->MAX_BLOCKS && (new_blocks > part->MAX_BLOCKS-part->NUM_BLOCKS)) {
            /* Don't grow beyond maximum */
            new_blocks = part->MAX_BLOCKS - part->NUM_BLOCKS;
         } /* Endif */
         _int_enable();

         grow = _mem_alloc_system(sizeof(pointer) + part->BLOCK_SIZE * new_blocks);
         if (grow) {
            _mem_set_type(part, MEM_TYPE_RTCS_PARTITION);

            _int_disable();
            if (!part->MAX_BLOCKS || (part->NUM_BLOCKS+new_blocks <= part->MAX_BLOCKS)) {

               /* Construct all the blocks and add them to the free list */
               elem = grow;
               if (RTCS_part_grow(part, elem+1, new_blocks) == RTCS_ERROR) {
                  _int_enable();
                  _mem_free(grow);
               } else {
                  *elem = part->GROW;
                  part->GROW = elem;
                  _int_enable();
               } /* Endif */

            } else {
               _int_enable();
               _mem_free(grow);
            } /* Endif */

         } /* Endif */
      } else {
         _int_enable();
      } /* Endif */
   } /* Endif */

   _int_disable();
   if (!part->FREE) {
      _int_enable();
      return NULL;
   } /* Endif */

   /* Dequeue a block */
    elem = part->FREE;
   part->FREE = *elem;
   _int_enable();

   /* Point the block back to the partition (for RTCS_part_free()) */
   *elem = part;
   return elem + 1;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_alloc_zero
* Returned Values : A pointer to a zeroed partition block if successful,
*                   or NULL if allocation fails.
* Comments        :
*     Allocate a partition block and zero it.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_part_alloc_zero
   (
      _rtcs_part part            /* [IN] partition to allocate from */
   )
{ /* Body */
   pointer elem;

   elem = RTCS_part_alloc(part);
   if (elem) {
      _mem_zero(elem, part->BLOCK_SIZE - sizeof(pointer));
   } /* Endif */

   return elem;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_free
* Returned Values : void
* Comments        :
*     Free a partition block.
*
*END*-----------------------------------------------------------------*/

void RTCS_part_free
   (
      pointer block              /* [IN] block to free */
   )
{ /* Body */
   pointer _PTR_  elem = block;
   _rtcs_part     part;

   part = *--elem;

   _int_disable();
   *elem = part->FREE;
   part->FREE = elem;
   _int_enable();

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_part_destroy
* Returned Values : void
* Comments        :
*     Destroy a partition
*
*END*-----------------------------------------------------------------*/

void RTCS_part_destroy
   (
      _rtcs_part part            /* [IN] partition to destroy */
   )
{ /* Body */
   pointer _PTR_  elem;
   pointer _PTR_  nextelem;

   /* Destroy all the elements */
   if (part->DESTR) {
      for (elem = part->FREE; elem; elem = *elem) {
         part->DESTR(elem+1);
      } /* Endwhile */
   } /* Endif */

   /* Free all the grown blocks */
   for (elem = part->GROW; elem; elem = nextelem) {
      nextelem = *elem;
      _mem_free(elem);
   } /* Endfor */

   /* Free the partition and the initial blocks */
   _mem_free(part);

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/sharp/lh28fxxx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lh28fxxx.c$
* $Version : 3.8.5.0$
* $Date    : Oct-4-2011$
*
* Comments:
*
*   The file contains functions to program the LH28FXXX
*   flash devices.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "lh28fxxx_prv.h"
#include "lh28fxxx.h"

const FLASHX_DEVICE_IF_STRUCT _lh28fxxx_if = {
    _lh28fxxx_erase,
    _lh28fxxx_program,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _lh28fxxx_program
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs the prom device.
* 
*END*----------------------------------------------------------------------*/

boolean _lh28fxxx_program
   (  
      /* [IN] the flash information */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] where to copy data from */
      char_ptr             from_ptr,
      
      /* [OUT} where to copy data to */
      char_ptr             to_ptr,

      /* [IN] the amount to program */
      _mem_size            bytes
   )
{ /* Body */
   boolean result = TRUE;
   uint_32 count = bytes;
   uint_32 timeout;
   uint_32 tmp1;
   uint_32 tmp2;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 32){
      volatile uint_32 _PTR_  base32_ptr;
      volatile uint_32 _PTR_  dest32_ptr;
      uint_32_ptr             src32_ptr;

      src32_ptr  = (uint_32_ptr)from_ptr;         
      dest32_ptr = (volatile uint_32 _PTR_)to_ptr;
      base32_ptr = (volatile uint_32 _PTR_)to_ptr;
      count = (count+3) & ~3;   /* Round count up, multiple of 4 */

      *dest32_ptr = 0xFFFFFFFF;
      /* Clear status register */
      *dest32_ptr = 0x50505050;
      *dest32_ptr = 0xFFFFFFFF;

      while (count > 0) {

         tmp1 = *src32_ptr++;
         if (tmp1 != 0xFFFFFFFF) {
            *dest32_ptr = 0x40404040;  /* Write command */
            *dest32_ptr = tmp1;    /* Write data    */
            timeout = 100;
            while (timeout) {  
              /* Read status register */
               *dest32_ptr = 0x70707070;
               tmp2 = *dest32_ptr;
               if ((tmp2 & 0x00800080) == 0x00800080) {
                 if (tmp2 & 0x3E3E3E3E) {
                     /* An write error or Vpp low detect, or write protect, or bad cmd*/
                     *base32_ptr = 0xFFFFFFFF; /* Set read mode */
                     result = FALSE;
                     goto done;
                  } /* Endif */
                  break;
               }/* Endif */
               _io_flashx_wait_us(10);
               timeout--;
            }/* Endwhile */
            if (timeout == 0) {
               result = FALSE;
               *base32_ptr = 0xFFFFFFFF; /* Set read mode */
               goto done;
            } /* Endif */
         } /* Endif */
         dest32_ptr++;
         count -= 4;
      } /* Endwhile */

      *base32_ptr = 0xFFFFFFFF; /* Set read mode */

   } else if (flashx_ptr->WIDTH == 16){
      volatile uint_16 _PTR_  base16_ptr;
      volatile uint_16 _PTR_  dest16_ptr;
      uint_16_ptr             src16_ptr;

      src16_ptr  = (uint_16_ptr)from_ptr;         
      dest16_ptr = (volatile uint_16 _PTR_)to_ptr;
      base16_ptr = (volatile uint_16 _PTR_)to_ptr;
      count = (count+1) & ~1;   /* Round count up, multiple of 4 */

      *dest16_ptr = 0xFFFF;
      /* Clear status register */
      *dest16_ptr = 0x5050;
      *dest16_ptr = 0xFFFF;

      while (count > 0) {

         tmp1 = *src16_ptr++;
         if (tmp1 != 0xFFFF) {
            *dest16_ptr = 0x4040;  /* Write command */
            *dest16_ptr = tmp1;    /* Write data    */
            timeout = 100;
            while (timeout) {  
              /* Read status register */
               *dest16_ptr = 0x7070;
               tmp2 = *dest16_ptr;
               if ((tmp2 & 0x0080) == 0x0080) {
                 if (tmp2 & 0x3E3E) {
                     /* An write error or Vpp low detect, or write protect, or bad cmd*/
                     *base16_ptr = 0xFFFF; /* Set read mode */
                     result = FALSE;
                     goto done;
                  } /* Endif */
                  break;
               }/* Endif */
               _io_flashx_wait_us(10);
               timeout--;
            }/* Endwhile */
            if (timeout == 0) {
               result = FALSE;
               *base16_ptr = 0xFFFF; /* Set read mode */
               goto done;
            } /* Endif */
         } /* Endif */
         dest16_ptr++;
         count -= 2;
      } /* Endwhile */

      *base16_ptr = 0xFFFF; /* Set read mode */

   } else if (flashx_ptr->WIDTH == 8){
      volatile uint_8  _PTR_  base8_ptr;
      volatile uint_8  _PTR_  dest8_ptr;
      uint_8_ptr              src8_ptr;

      src8_ptr  = (uint_8_ptr)from_ptr;         
      dest8_ptr = (volatile uint_8 _PTR_)to_ptr;
      base8_ptr = (volatile uint_8 _PTR_)to_ptr;

      *dest8_ptr = 0xFF;
      /* Clear status register */
      *dest8_ptr = 0x50;
      *dest8_ptr = 0xFF;

      while (count > 0) {

         tmp1 = *src8_ptr++;
         if (tmp1 != 0xFF) {
            *dest8_ptr = 0x40;  /* Write command */
            *dest8_ptr = tmp1;    /* Write data    */
            timeout = 100;
            while (timeout) {  
              /* Read status register */
               *dest8_ptr = 0x70;
               tmp2 = *dest8_ptr;
               if ((tmp2 & 0x80) == 0x80) {
                 if (tmp2 & 0x3E) {
                     /* An write error or Vpp low detect, or write protect, or bad cmd*/
                     *base8_ptr = 0xFF; /* Set read mode */
                     result = FALSE;
                     goto done;
                  } /* Endif */
                  break;
               }/* Endif */
               _io_flashx_wait_us(10);
               timeout--;
            }/* Endwhile */
            if (timeout == 0) {
               result = FALSE;
               *base8_ptr = 0xFF; /* Set read mode */
               goto done;
            } /* Endif */
         } /* Endif */
         dest8_ptr++;
         count -= 1;
      } /* Endwhile */
      
      *base8_ptr = 0xFF; /* Set read mode */

   }/* Endif */

   if (flashx_ptr->WRITE_VERIFY) {
      /* Verify sector(s) is(are) written correctly */
      uint_32_ptr  src32_ptr  = (uint_32_ptr)from_ptr;
      uint_32_ptr  dest32_ptr =  (uint_32_ptr)to_ptr;
      count = bytes/4 + 1;
      while (--count) {
         if (*src32_ptr++ != *dest32_ptr++) {
            result = FALSE;
            break;
         } /* Endif */
      } /* Endwhile */
   } /* Endif */   

done:
   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */
   return(result);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _lh28fxxx_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases the prom device.
* 
*END*----------------------------------------------------------------------*/

boolean _lh28fxxx_erase
   (
      /* [IN] the flash information */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] the sector to erase */
      char_ptr             input_sect_ptr,

      /* [IN] the number of bytes to erase */
      _mem_size            bytes
   )
{ /* Body */
   boolean result = TRUE;
   uint_32 timeout;
   uint_32 tmp1;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 32){
      volatile uint_32 _PTR_  base32_ptr;
   
      base32_ptr = (volatile uint_32 _PTR_)input_sect_ptr;

      *base32_ptr = 0xFFFFFFFF;
      /* Clear status register */
      *base32_ptr = 0x50505050;
      *base32_ptr = 0xFFFFFFFF;

      /* Start block erase */
      *base32_ptr = 0x20202020;
      *base32_ptr = 0xD0D0D0D0;

      timeout = 7000000;
      while (timeout) {
         /* Read status register */
         *base32_ptr = 0x70707070;
         tmp1 = *base32_ptr;
         if ((tmp1 & 0x00800080) == 0x00800080) {
            if (tmp1 & 0x3E3E3E3E) {
               /* An write error or Vpp low detect, or write protect, or bad cmd */
               result = FALSE;
               break;
            }/* Endif */
            /* Done! */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */
      
      /* Reset the device */
      *base32_ptr = 0xFFFFFFFF;

   } else if (flashx_ptr->WIDTH == 16){
      volatile uint_16 _PTR_  base16_ptr;
   
      base16_ptr = (volatile uint_16 _PTR_)input_sect_ptr;

      *base16_ptr = 0xFFFF;
      /* Clear status register */
      *base16_ptr = 0x5050;
      *base16_ptr = 0xFFFF;

      /* Start block erase */
      *base16_ptr = 0x2020;
      *base16_ptr = 0xD0D0;

      timeout = 7000000;
      while (timeout) {
         /* Read status register */
         *base16_ptr = 0x7070;
         tmp1 = *base16_ptr;
         if ((tmp1 & 0x0080) == 0x0080) {
            if (tmp1 & 0x3E3E) {
               /* An write error or Vpp low detect, or write protect, or bad cmd */
               result = FALSE;
               break;
            }/* Endif */
            /* Done! */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */

      /* Reset the device */
      *base16_ptr = 0xFFFF;
   
   } else if (flashx_ptr->WIDTH == 8){
      volatile uint_8 _PTR_  base8_ptr;
   
      base8_ptr = (volatile uint_8 _PTR_)input_sect_ptr;

      *base8_ptr = 0xFF;
      /* Clear status register */
      *base8_ptr = 0x50;
      *base8_ptr = 0xFF;

      /* Start block erase */
      *base8_ptr = 0x20;
      *base8_ptr = 0xD0;

      timeout = 7000000;
      while (timeout) {
         /* Read status register */
         *base8_ptr = 0x70;
         tmp1 = *base8_ptr;
         if ((tmp1 & 0x80) == 0x80) {
            if (tmp1 & 0x3E) {
               /* An write error or Vpp low detect, or write protect, or bad cmd */
               result = FALSE;
               break;
            }/* Endif */
            /* Done! */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */

      /* Reset the device */
      *base8_ptr = 0xFF;

   } /* Endif */

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */
   return(result);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/partition.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: partition.h$
* $Version : 3.8.7.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This file contains public definitions for the memory partition
*   component
*
*END************************************************************************/
#ifndef __partition_h__
#define __partition_h__

#include <mqx_cnfg.h>
#if (! MQX_USE_PARTITIONS) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error PARTITION component is currently disabled in MQX kernel. Please set MQX_USE_PARTITIONS to 1 in user_config.h and recompile kernel.
#endif

/* Partition error return value */
#define PARTITION_NULL_ID       ((_partition_id)0)

/* Partition error codes */

#define PARTITION_INVALID                 (PART_ERROR_BASE|0x01)
#define PARTITION_OUT_OF_BLOCKS           (PART_ERROR_BASE|0x02)
#define PARTITION_BLOCK_INVALID_ALIGNMENT (PART_ERROR_BASE|0x03)
#define PARTITION_TOO_SMALL               (PART_ERROR_BASE|0x04)
#define PARTITION_INVALID_TASK_ID         (PART_ERROR_BASE|0x05)
#define PARTITION_BLOCK_INVALID_CHECKSUM  (PART_ERROR_BASE|0x06)
#define PARTITION_INVALID_TYPE            (PART_ERROR_BASE|0x07)
#define PARTITION_ALL_BLOCKS_NOT_FREE     (PART_ERROR_BASE|0x08)

/* The definition of a partition id */
typedef pointer _partition_id;

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern pointer       _partition_alloc(_partition_id);
extern pointer       _partition_alloc_system(_partition_id);
extern pointer       _partition_alloc_system_zero(_partition_id);
extern pointer       _partition_alloc_zero(_partition_id);
extern _mem_size     _partition_calculate_size(_mqx_uint, _mem_size);
extern _mqx_uint     _partition_calculate_blocks(_mem_size, _mem_size);
extern _mqx_uint     _partition_create_component(void);
extern _partition_id _partition_create(_mem_size, _mqx_uint, _mqx_uint, _mqx_uint);
extern _partition_id _partition_create_at(pointer, _mem_size, _mem_size);
extern _mqx_uint     _partition_destroy(_partition_id);
extern _mqx_uint     _partition_extend(_partition_id, pointer, _mem_size);
extern _mqx_uint     _partition_free(pointer);
extern _mqx_uint     _partition_get_free_blocks(_partition_id);
extern _mqx_uint     _partition_get_max_used_blocks(_partition_id);
extern _mqx_uint     _partition_get_number_of(void);
extern _mqx_uint     _partition_get_total_blocks(_partition_id);
extern _mem_size     _partition_get_block_size(_partition_id);
extern _mem_size     _partition_get_total_size(_partition_id);
extern _mqx_uint     _partition_test(_partition_id _PTR_, pointer _PTR_, 
   pointer _PTR_);
extern _mqx_uint     _partition_transfer(pointer, _task_id);
#endif

#ifdef __cplusplus
}
#endif

#endif /* __partition_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/dnsinit.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dnsinit.c$
* $Version : 192.168.3.11$
* $Date    : Aug-10-2011$
*
* Comments:
*
*   This file contains the Domain Name System resolver
*   initialization functions for RTCS.
*
*END************************************************************************/


#include <rtcs.h>
#include "rtcs_prv.h"

#if RTCSCFG_ENABLE_UDP
#if RTCSCFG_ENABLE_DNS 

#include "dns.h"


/* Start CR 2170 */
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_init_unwind
* Returned Value  : void
* Comments        : cleans up after a DNS_init error
*
*END*-----------------------------------------------------------------*/

static void DNS_init_unwind
   (
      DNS_CONTROL_STRUCT _PTR_ control_ptr,
      uint_32                  sock

   )
{ /* Body */
   RTCS_setcfg(DNS, NULL);
   if (sock)
      shutdown(sock, 0);
   if (control_ptr) {
      if (control_ptr->CNAME_PARTID)
         RTCS_part_destroy(control_ptr->CNAME_PARTID);
      if (control_ptr->RR_LIST_PARTID)
         RTCS_part_destroy(control_ptr->RR_LIST_PARTID);
      if (control_ptr->NAME_RR_PARTID)
         RTCS_part_destroy(control_ptr->NAME_RR_PARTID);
      if (control_ptr->INT_QUERY_PARTID)
         RTCS_part_destroy(control_ptr->INT_QUERY_PARTID);
      if (control_ptr->ADDR_RR_PARTID)
         RTCS_part_destroy(control_ptr->ADDR_RR_PARTID);
      _mem_free(control_ptr);
   }
   return;
} /* Endbody */
/* End CR 2170 */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_init
* Returned Value  : DNS_OK or error code
* Comments        : Initializes the DNS task
*
*END*-----------------------------------------------------------------*/

uint_32 DNS_init
   (
      void
   )

{ /* Body */
   DNS_CONTROL_STRUCT _PTR_ control_ptr = RTCS_getcfg(DNS);
   uint_32                  temp_socket = 0;
   int_32                   error;

   if (control_ptr != NULL) {
      return RTCS_OK;
   }

   /*
   ** Please note, if this is modified to use a value other than
   ** DNS_MAX_UDP_MESSAGE_SIZE, the recvfrom() in the DNS_Resolver_task
   ** will need to be modified as well, as they rely on this constant.
   */
   control_ptr = RTCS_mem_alloc_system_zero(sizeof(DNS_CONTROL_STRUCT)+DNS_MAX_UDP_MESSAGE_SIZE);
   if (control_ptr == NULL) {
      return RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY;
   } /* Endif */
   _mem_set_type(control_ptr, MEM_TYPE_DNS_CONTROL_STRUCT);

   RTCS_setcfg(DNS, control_ptr);

   temp_socket = socket(PF_INET, SOCK_DGRAM, 0);
   if (temp_socket == RTCS_HANDLE_ERROR) {
      DNS_init_unwind(control_ptr, temp_socket);
      return RTCSERR_DNS_UNABLE_TO_OPEN_SOCKET;
   } /* Endif */

   error = RTCS_detachsock(temp_socket);
   if (error != RTCS_OK) {
      DNS_init_unwind(control_ptr, temp_socket);
      return error;
   } /* Endif */

   control_ptr->INT_QUERY_PARTID  = RTCS_part_create(
      sizeof(DNS_INTERNAL_QUERY_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0,
      NULL, NULL);
   if (control_ptr->INT_QUERY_PARTID == 0) {
      DNS_init_unwind(control_ptr, temp_socket);
      return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION;
   } /* Endif */

   control_ptr->ADDR_RR_PARTID  = RTCS_part_create(
      sizeof(DNS_ADDR_RECORD_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0,
      NULL, NULL);
   if (control_ptr->ADDR_RR_PARTID == 0) {
      DNS_init_unwind(control_ptr, temp_socket);
      return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION;
   } /* Endif */

   control_ptr->NAME_RR_PARTID  = RTCS_part_create(
      sizeof(DNS_NAME_RECORD_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0,
      NULL, NULL);
   if (control_ptr->NAME_RR_PARTID == 0) {
      DNS_init_unwind(control_ptr, temp_socket);
      return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION;
   } /* Endif */

   control_ptr->RR_LIST_PARTID  = RTCS_part_create(
      sizeof(DNS_RR_LIST_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0,
      NULL, NULL);
   if (control_ptr->RR_LIST_PARTID == 0) {
      DNS_init_unwind(control_ptr, temp_socket);
      return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION;
   } /* Endif */

   control_ptr->CNAME_PARTID  = RTCS_part_create(
      sizeof(DNS_CNAME_STRUCT), DNSALLOC_SIZE, DNSALLOC_SIZE, 0,
      NULL, NULL);
   if (control_ptr->CNAME_PARTID == 0) {
      DNS_init_unwind(control_ptr, temp_socket);
      return RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION;
   } /* Endif */

   control_ptr->ROOT_SLIST_PTR  = DNS_A_Root_server;
   control_ptr->LOCAL_SLIST_PTR = DNS_First_Local_server;
   control_ptr->NS_BUFFER       = NULL;
   control_ptr->RES_BUFFER      = (uchar_ptr)(control_ptr + 1);
   control_ptr->RES_SOCKET      = temp_socket;
   control_ptr->UPDATING        = FALSE;

   error = RTCS_mutex_init(&control_ptr->CACHE_MUTEX);
   if (error != RTCS_OK) {
      DNS_init_unwind(control_ptr, temp_socket);
      return error;
   } /* Endif */

   error = RTCS_mutex_init(&control_ptr->SLIST_MUTEX);
   if (error != RTCS_OK) {
      DNS_init_unwind(control_ptr, temp_socket);
      return error;
   } /* Endif */

   error = RTCS_task_create("DNS Resolver", _RTCSTASK_priority,
      _RTCSTASK_stacksize + 500 * sizeof(uint_32),
      DNS_Resolver_task, control_ptr);
   if (error) {
      DNS_init_unwind(control_ptr, temp_socket);
      return error;
   } /* Endif */

   return RTCS_OK;

} /* Endbody */

#endif
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mcf51xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mcf51xx.c$
* $Version : 3.8.21.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions for internal flash read, write, erase 
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "flash_mcf51xx.h"
#include "flash_mcf51xx_prv.h"
   
/* Internal function definitions */
static void mcf51xx_ram_function(volatile uchar_ptr); 
static void mcf51xx_ram_function_end (void);

uchar_ptr mcf51xx_init_ram_function(void);

const FLASHX_BLOCK_INFO_STRUCT _flashx_mcf51xx_block_map[] = {
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE, (uint_32) BSP_INTERNAL_FLASH_BASE, BSP_INTERNAL_FLASH_SECTOR_SIZE, 0},
    { 0, 0, 0, 0 }
};

const FLASHX_DEVICE_IF_STRUCT _flashx_mcf51xx_if = {
    mcf51xx_flash_erase_sector,
    mcf51xx_flash_write_sector,
    NULL,
    NULL,
    mcf51xx_flash_init,
    mcf51xx_flash_deinit,
    NULL,
    _io_mcf51xx_flash_ioctl
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mcf51xx_set_cfmclkd
* Returned Value   : none
* Comments         :
*    Set the CFMCLKD register.
*
*END*----------------------------------------------------------------------*/
void _mcf51xx_set_cfmclkd(uint_8 mem_array)
{
#define PRDIV8_LIMIT_FREQ   12800000L // limit freq. for using PRDIV8_PRSC
#define FLASH_FREQ          200000L   // 190 kHz program frequency
#define PRDIV8_PRSC         8         // prescaller 8
    
    VMCF51XX_FTSR_STRUCT_PTR  ftsr_ptr;
    
    ftsr_ptr = _bsp_get_cfm_address(mem_array);
    
    if(BSP_BUS_CLOCK > PRDIV8_LIMIT_FREQ)
    {
        ftsr_ptr->FCDIV = MCF51XX_FTSR_FCDIV_PRDIV8 | MCF51XX_FTSR_FCDIV_FDIV((BSP_BUS_CLOCK + PRDIV8_PRSC * FLASH_FREQ - 1) / (PRDIV8_PRSC * FLASH_FREQ) - 1);
    }
    else
    {
        ftsr_ptr->FCDIV = MCF51XX_FTSR_FCDIV_FDIV((BSP_BUS_CLOCK + FLASH_FREQ - 1) / FLASH_FREQ - 1);
    }
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf51xx_flash_init
* Returned Value   : 
* Comments         :
*   Init flash - store the FSTAT register  
*
*END*----------------------------------------------------------------------*/
boolean mcf51xx_flash_init
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    volatile MCF51XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
    uint_8 array;
    VMCF51XX_FTSR_STRUCT_PTR ftsr_ptr;
    
    dev_spec_ptr = _mem_alloc(sizeof(MCF51XX_FLASH_INTERNAL_STRUCT));
#if MQX_CHECK_FOR_MEMORY_ALLOCATION_ERRORS
    /* test for correct memory allocation */
    if(dev_spec_ptr == NULL){
        return FALSE;
    }
#endif //MQX_CHECK_FOR_MEMORY_ALLOCATION_ERRORS

    /* get the pointer to cfm registers structure */
#ifndef PSP_HAS_DUAL_FLASH
    array = MEMORY_ARRAY_STD;
#else
    /* RTC_CFG_DATA[CFG0] = 0 : FSTR1 => 0x00000000 - see Flash Array Base Address table */
    array = (dev_ptr->BASE_ADDR == 0) ? MEMORY_ARRAY_1 : MEMORY_ARRAY_2;
    if (_mcf51_get_rtc_cfg_state() == 1) {
        /* if flash are already swapped, then swap the pointers */
        array = (array == MEMORY_ARRAY_1) ? MEMORY_ARRAY_2 : MEMORY_ARRAY_1;
    }
#endif //PSP_HAS_DUAL_FLASH
    ftsr_ptr = _bsp_get_cfm_address(array);

    dev_spec_ptr->ftsr_ptr = (vuchar_ptr)ftsr_ptr;
    dev_ptr->DEVICE_SPECIFIC_DATA = dev_spec_ptr;
    
    /* save pointer to function in ram - this is the default settings  */
    dev_spec_ptr->flash_execute_code_ptr = mcf51xx_init_ram_function();
    
    /* set correct clocking for CFM module */
    _mcf51xx_set_cfmclkd(array);

    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf51xx_flash_deinit
* Returned Value   : 
* Comments         :
*    release used memory      
*
*END*----------------------------------------------------------------------*/
void mcf51xx_flash_deinit
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    MCF51XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (MCF51XX_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    
    /* if the flash write,erase code run form RAM, free memory */
    if (dev_ptr->FLAGS & FLASHX_WR_ERASE_FROM_FLASH_ENABLED == 0) {
        /* de-allocate the ram function buffer */
        if(dev_spec_ptr->flash_execute_code_ptr) {
            _mem_free(dev_spec_ptr->flash_execute_code_ptr);
        }
    }
    dev_spec_ptr->flash_execute_code_ptr = NULL;
    /* de-allocate device specific structure */
    _mem_free(dev_ptr->DEVICE_SPECIFIC_DATA);
    dev_ptr->DEVICE_SPECIFIC_DATA = NULL; 
}   

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf51xx_init_ram_function
* Returned Value   : pointer to allocated RAM function
* Comments         :
*   allocate and copy flash RAM function  
*
*END*----------------------------------------------------------------------*/
uchar_ptr mcf51xx_init_ram_function()
{
    uchar_ptr ram_code_ptr;
    
    /* Allocate space on stack to run flash command out of SRAM */
    ram_code_ptr = _mem_alloc((char*)mcf51xx_ram_function_end - (char*)mcf51xx_ram_function);   
    /* copy code to RAM buffer */
    _mem_copy((void*)mcf51xx_ram_function, ram_code_ptr, (char*)mcf51xx_ram_function_end  - (char*)mcf51xx_ram_function);

    return ram_code_ptr;               
}
    
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf51xx_erase_sector_ext
* Returned Value   : true if success, or false
* Comments         :
*   Erase a flash memory block  
*
*END*----------------------------------------------------------------------*/
boolean mcf51xx_flash_erase_sector
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr, 

    /* [IN] Erased sector address */
    char_ptr             from_ptr,

    /* [IN] Erased sector size */
    _mem_size            size
)
{
    MCF51XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (MCF51XX_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    VMCF51XX_FTSR_STRUCT_PTR ftsr_ptr;
    int (*RunInRAM)(uchar_ptr);
    uint_32 temp;

    /* select the proper ramcode function */
    *RunInRAM = (int(*)(uchar_ptr))dev_spec_ptr->flash_execute_code_ptr;
    
    /* get the pointer to cfm registers structure */
    ftsr_ptr = (VMCF51XX_FTSR_STRUCT_PTR)dev_spec_ptr->ftsr_ptr;   
    
    _int_disable();
    /* prepare flash write operation, clear flags and wait for ready state */
    ftsr_ptr->FSTAT = (MCF51XX_FTSR_FSTAT_FPVIOL | MCF51XX_FTSR_FSTAT_FACCERR);
    while (!(ftsr_ptr->FSTAT & MCF51XX_FTSR_FSTAT_FCBEF)){
        /* wait */
    };

    /* latch address in Flash */
    (*(volatile vuint_32 *)(from_ptr)) = (vuint_32)-1;  
    
    /* issue erase command */
    ftsr_ptr->FCMD = MCF51XX_FTSR_FCMD_SECTOR_ERASE;
    
    /* run command and wait for it to finish (must execute from RAM) */ 
    temp = _psp_get_sr();
    _psp_set_sr(temp | 0x0700);
    RunInRAM( (volatile uchar_ptr)&ftsr_ptr->FSTAT );    
    _psp_set_sr(temp);
    
    if (ftsr_ptr->FSTAT & (MCF51XX_FTSR_FSTAT_FACCERR | MCF51XX_FTSR_FSTAT_FPVIOL)) {
        _int_enable();
        return FALSE;
    }
        
    _int_enable();
    return(TRUE);   
         
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf51xx_write_sector
* Returned Value   : true if success, or false
* Comments         :
*   Performs a write into flash memory  
*
*END*----------------------------------------------------------------------*/
boolean mcf51xx_flash_write_sector
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr, 

    /* [IN] Source address */
    char_ptr             from_ptr,

    /* [IN] Destination address */
    char_ptr             to_ptr,

    /* [IN] Number of bytes to write */
    _mem_size            size
) 
{
    MCF51XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (MCF51XX_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    VMCF51XX_FTSR_STRUCT_PTR    ftsr_ptr;
    VMCF51XX_PMC_STRUCT_PTR     pmc_ptr; 
    int (*RunInRAM)( uchar_ptr );
    volatile uint_32 temp, temp_data = 0xFFFFFFFF;
    volatile char_ptr temp_data_ptr;
    uchar byte_data_counter = 0;
    #define BYTES_IN_WORD   4
    /* get the offset in write word */
    uint_32 offset = (uint_32)to_ptr & 0x00000003;

    temp_data_ptr = (char_ptr)&temp_data;
    
    /* select the proper ramcode function */
    RunInRAM = (int(*)( uchar_ptr ))dev_spec_ptr->flash_execute_code_ptr;

    /* get the pointer to cfm registers structure */
    ftsr_ptr = (VMCF51XX_FTSR_STRUCT_PTR)dev_spec_ptr->ftsr_ptr;
    
    /* get the pointer to pmc registers structure */
    pmc_ptr = _bsp_get_pmc_address();    
    /* Clear any errors */
    _int_disable();
    ftsr_ptr->FSTAT = (MCF51XX_FTSR_FSTAT_FPVIOL | MCF51XX_FTSR_FSTAT_FACCERR); 
    
    /* if the start address !=  doesn't correspond with hardware, prepare
       variables for 1st word write */
    if(offset){
        /* Align pointer to writable address */
        to_ptr -= offset;
        /* jump over old data */
        byte_data_counter = offset; 
    }
    /* while are some data to write */
    while(size){
        /* move data to write word */       
        while( byte_data_counter < BYTES_IN_WORD && size ){
            *(temp_data_ptr+byte_data_counter) = *from_ptr++;
            byte_data_counter++;
            size--;
        }
        /* test the LVDF flag - if 1, we need to write data in 2 steps */
        if( pmc_ptr->SPMSC1 & MCF51XX_PMC_SPMSC1_LVDF) {
            /* write odd bytes */
            (*(vuint_32 *)(to_ptr)) = temp_data | 0x00FF00FF;
            /* write command to CFMCMD */
            ftsr_ptr->FCMD = MCF51XX_FTSR_FCMD_BURST_PROGRAM;
            /* run command and wait for it to finish (must execute from RAM) */     
            temp = _psp_get_sr();
            _psp_set_sr(temp | 0x0700);
            RunInRAM( (volatile uchar_ptr)&ftsr_ptr->FSTAT );
            _psp_set_sr(temp);
            /* write even bytes */              
            (*(vuint_32 *)(to_ptr)) = temp_data | 0xFF00FF00;
            /* write command to CFMCMD */
            ftsr_ptr->FCMD = MCF51XX_FTSR_FCMD_BURST_PROGRAM;
            /* run command and wait for it to finish (must execute from RAM) */     
            temp = _psp_get_sr();
            _psp_set_sr(temp | 0x0700);
            RunInRAM( (volatile uchar_ptr)&ftsr_ptr->FSTAT );
            _psp_set_sr(temp);
        } 
        else {  
            /* move write data to register */
            (*(vuint_32 *)(to_ptr)) = temp_data;
            
            /* write command to CFMCMD */
            ftsr_ptr->FCMD = MCF51XX_FTSR_FCMD_BURST_PROGRAM;
            /* run command and wait for it to finish (must execute from RAM) */     
            temp = _psp_get_sr();
            _psp_set_sr(temp | 0x0700);
            RunInRAM( (volatile uchar_ptr)&ftsr_ptr->FSTAT );                
            _psp_set_sr(temp);
        }
        /* Check for Errors */
        if (ftsr_ptr->FSTAT & (MCF51XX_FTSR_FSTAT_FPVIOL | MCF51XX_FTSR_FSTAT_FACCERR)) {
            _int_enable();
            return (FALSE);
        }
        
        /* init variables for next loop */
        to_ptr += BYTES_IN_WORD;
        byte_data_counter = 0;
        temp_data = 0xFFFFFFFF;
    }
    _int_enable();
    return (TRUE);  
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mcf51xx_ioctl
* Returned Value   : TRUE if successful
* Comments         : 
*    flash ioctl function
* 
*END*----------------------------------------------------------------------*/
_mqx_int _io_mcf51xx_flash_ioctl
   (
      /* [IN] the handle returned from _fopen */
      IO_FLASHX_STRUCT_PTR   dev_ptr,

      /* [IN] the ioctl command */
      _mqx_uint              cmd,

      /* [IN] the ioctl parameters */
      pointer                param_ptr
   )
{ /* Body */
    MCF51XX_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (MCF51XX_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA; 
    _mqx_uint   result = MQX_OK;
    
    switch(cmd) {
        #ifdef PSP_HAS_DUAL_FLASH
        case FLASH_IOCTL_SWAP_FLASH_AND_RESET:
            _mcf51_swap_flash_and_reset();
            break;
        #endif
            
        case FLASH_IOCTL_WRITE_ERASE_CMD_FROM_FLASH_ENABLE:
            dev_ptr->FLAGS |= FLASHX_WR_ERASE_FROM_FLASH_ENABLED; 
            if(dev_spec_ptr->flash_execute_code_ptr){
                _mem_free(dev_spec_ptr->flash_execute_code_ptr);
            }
            dev_spec_ptr->flash_execute_code_ptr = (uchar_ptr)mcf51xx_ram_function;
            break;
            
        case FLASH_IOCTL_WRITE_ERASE_CMD_FROM_FLASH_DISABLE:
            dev_ptr->FLAGS &= ~FLASHX_WR_ERASE_FROM_FLASH_ENABLED;
            dev_spec_ptr->flash_execute_code_ptr = mcf51xx_init_ram_function();
            break;
            
        default:
            break;
    }
    return result;
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf51xx_ram_function
* Returned Value   : 
* Comments         : 
*    Launch the program command and wait until execution complete. This code
*    is required to run in SRAM, 
*    unless FLASH_IOCTL_WRITE_ERASE_CMD_FROM_FLASH_ENABLE ioctl command is
*    applied to allow the low level flash write and erase routines being run
*    from internal flash memory (works only with the dual flash memory 
*    controllers).
*    
*END*----------------------------------------------------------------------*/
static void mcf51xx_ram_function(volatile uchar_ptr fstat_ptr) 
{
    /* Clear the FCBEF flag in the FSTAT register by writing a 1 */
    /* to FCBEF to launch the program command. */
    *fstat_ptr |= MCF51XX_FTSR_FSTAT_FCBEF;   
    /* wait until execution complete */
    while (!( *fstat_ptr & MCF51XX_FTSR_FSTAT_FCCF)){
    };
}


static void mcf51xx_ram_function_end (void) {}


<|start_filename|>Firmware/Inverter_bootloader/BSP/UART.h<|end_filename|>
#ifndef UART0_H_
  #define UART0_H_

  #include "PE_Error.h"
  #include "Cpu.h"


void UART_Init2(void);
void UART_Init(UART_MemMapPtr uartch, int sysclk, int baud);

void UART0_putchar(char ch);
char UART0_getchar(void);
void Out_char(char ch);

void Send_byte(unsigned char byte);
int Wait_byte(unsigned char *ptr_c, unsigned int timeout);

#endif



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/tftputil.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tftputil.c$
* $Version : 3.0.5.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the TFTP utility implementation for
*   the RTCS Communication Library.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include "tftp.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTP_timeout_init
* Returned Value  : time to expiry in milliseconds
* Comments        : This function initializes the adaptive timeout.
*
*END*-----------------------------------------------------------------*/

uint_32 TFTP_timeout_init
   (
      TFTP_TO_STRUCT_PTR   to
   )
{ /* Body */

   to->TS     = RTCS_time_get();
   to->UPDATE = TRUE;
   to->TO     = TFTP_TIMEOUT_MIN;
   to->M      = TFTP_TIMEOUT_MIN;
   to->D      = 0;

   return to->TO;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTP_timeout_restart
* Returned Value  : time to expiry in milliseconds
* Comments        : This function causes the next call to
*                   TFTP_timeout_update to not update the adaptive
*                   timeout.  Used when retransmitting before expiry.
*
*END*-----------------------------------------------------------------*/

uint_32 TFTP_timeout_restart
   (
      TFTP_TO_STRUCT_PTR   to
   )
{ /* Body */

   to->TS     = RTCS_time_get();
   to->UPDATE = FALSE;

   return to->TO;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTP_timeout_update
* Returned Value  : time to expiry in milliseconds
* Comments        : This function updates the timeout when a response
*                   is received without retransmission.
*
*END*-----------------------------------------------------------------*/

uint_32 TFTP_timeout_update
   (
      TFTP_TO_STRUCT_PTR   to
   )
{ /* Body */
   uint_32 time, time_elapsed;
   int_32 error;

   time = RTCS_time_get();
   if (to->UPDATE) {
      time_elapsed = RTCS_timer_get_interval(to->TS, time);
      error = time_elapsed - to->M;
      to->M += error >> 3;
      if (!to->M) to->M++;
      if (error < 0) error = -error;
      error -= to->D;
      to->D += error >> 2;
      if (!to->D) to->D++;
      to->TO = to->M + (to->D << 2);
   } /* Endif */

   to->TS     = time;
   to->UPDATE = TRUE;

   return to->TO;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTP_timeout_left
* Returned Value  : time to expiry in milliseconds
* Comments        : This function determines the amout of time until
*                   the timeout expires
*
*END*-----------------------------------------------------------------*/

uint_32 TFTP_timeout_left
   (
      TFTP_TO_STRUCT_PTR   to,
      boolean _PTR_        expire
   )
{ /* Body */
   uint_32 time;

   time = RTCS_time_get();
   if ((time - to->TS) >= to->TO) {
      to->TS     = time;
      to->UPDATE = FALSE;
      to->TO <<= 1;
      if (to->TO > TFTP_TIMEOUT_MAX) {
         to->TO = TFTP_TIMEOUT_MAX;
      } /* Endif */
      if (expire) *expire = TRUE;
      return to->TO;
   } /* Endif */

   if (expire) *expire = FALSE;
   return to->TO - (time - to->TS);

} /* Endbody */

#define TFTP_ERROR_PKT(err,str)  {{0, TFTPOP_ERROR}, {0, err}, str}

/* The Illegal TID error packet */
TFTP_ERROR_PACKET _tftp_error_tid    = TFTP_ERROR_PKT(TFTPERR_ILLEGAL_TID, "Invalid TID");

/* The Illegal Operation error packet */
TFTP_ERROR_PACKET _tftp_error_op     = TFTP_ERROR_PKT(TFTPERR_ILLEGAL_OP, "Illegal Operation");

/* The Access Violation error packet */
TFTP_ERROR_PACKET _tftp_error_accvio = TFTP_ERROR_PKT(TFTPERR_ACCESS_VIOLATION, "Access Violation");

/* The Server Failure error packet */
TFTP_ERROR_PACKET _tftp_error_srv    = TFTP_ERROR_PKT(TFTPERR_UNKNOWN, "TFTP Server Failure");

/* The Server Busy error packet */
TFTP_ERROR_PACKET _tftp_error_busy   = TFTP_ERROR_PKT(TFTPERR_UNKNOWN, "TFTP Server Busy");

/* The Excessive Retrasnmissions error packet */
TFTP_ERROR_PACKET _tftp_error_to     = TFTP_ERROR_PKT(TFTPERR_UNKNOWN, "Excessive Retransmissions");

/* The File Not Found error packet */
TFTP_ERROR_PACKET _tftp_error_nofile = TFTP_ERROR_PKT(TFTPERR_FILE_NOT_FOUND, "File Not Found");

/* The File Already Exists error packet */
TFTP_ERROR_PACKET _tftp_error_exists = TFTP_ERROR_PKT(TFTPERR_FILE_EXISTS, "File Already Exists");


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/telnet.h<|end_filename|>
#ifndef __telnet_h__
#define __telnet_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: telnet.h$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the definitions for the Telnet
*   client and server.
*
*END************************************************************************/

/* telnet command codes */
#define TELCMD_IP       '\xf4'   /* Interrupt process */
#define TELCMD_AO       '\xf5'   /* Abort Output */
#define TELCMD_AYT      '\xf6'   /* Are You There */
#define TELCMD_EC       '\xf7'   /* Erase Char */
#define TELCMD_EL       '\xf8'   /* Erase Line */
#define TELCMD_GA       '\xf9'   /* Process ready for input */
#define TELCMD_WILL     '\xfb'
#define TELCMD_WONT     '\xfc'
#define TELCMD_DO       '\xfd'
#define TELCMD_DONT     '\xfe'
#define TELCMD_IAC      '\xff'   /* TELNET command sequence header */

/* telnet mandatory control codes */
#define TELCC_NULL      '\0'
#define TELCC_LF        '\n'
#define TELCC_CR        '\r'

/* telnet optional control codes */
#define TELCC_BELL      '\x07'   /* BELL */
#define TELCC_BS        '\x08'   /* BACKSPACE */
#define TELCC_HT        '\x09'   /* HORIZONTAL TAB */
#define TELCC_VT        '\x0b'   /* VERTICAL TAB */
#define TELCC_FF        '\x0c'   /* FORM FEED */


#define TELOPT_BINARY   0        /* Use 8 bit binary transmission */
#define TELOPT_ECHO     1        /* Echo data received */
#define TELOPT_SGA      3        /* Suppress Go-ahead signal */

#define TELNET_MAX_OPTS 4

/* Terminal options */
#define TEROPT_CRLF_MODE 1       /* New line endings style CR LF as opposed to CR NULL */
#define TEROPT_RAW_MODE  2       /* Indicates that raw mode without any char translation is used */


/* set the proper stream for the device */
#define IO_IOCTL_SET_STREAM             0x0050L
#define IO_IOCTL_SET_ECHO               0x0051L
#define IO_IOCTL_GET_ECHO               0x0052L
#define IO_IOCTL_SET_INBINARY           0x0053L
#define IO_IOCTL_GET_INBINARY           0x0054L
#define IO_IOCTL_SET_OUTBINARY          0x0055L
#define IO_IOCTL_GET_OUTBINARY          0x0056L
#define IO_IOCTL_SET_BINARY             0x0057L
#define IO_IOCTL_GET_BINARY             0x0058L
#define IO_IOCTL_SET_CRLF               0x0059L
#define IO_IOCTL_GET_CRLF               0x005aL
#define IO_IOCTL_SET_RAW                0x005bL
#define IO_IOCTL_GET_RAW                0x005cL

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/sosock.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sosock.c$
* $Version : 3.0.4.0$
* $Date    : Mar-5-2009$
*
* Comments:
*
*   This file contains the implementation of getsockopt()
*   and setsockopt() at the SOL_SOCKET level.
*
*END************************************************************************/

#include <rtcs.h>

#define RTCS_ENTER(f,a) RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_SOCKET_ ## f, a)

#define RTCS_EXIT(f,a)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_SOCKET_ ## f, a); \
                        return a


uint_32 SOL_SOCKET_getsockopt  (uint_32, uint_32, uint_32, pointer, uint_32 _PTR_);
uint_32 SOL_SOCKET_setsockopt  (uint_32, uint_32, uint_32, pointer, uint_32);

const RTCS_SOCKOPT_CALL_STRUCT SOL_SOCKET_CALL = {
   SOL_SOCKET_getsockopt,
   SOL_SOCKET_setsockopt
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_SOCKET_getsockopt
* Returned Value  : error code
* Comments  :  Obtain the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_SOCKET_getsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] buffer for the current value of the option */
      uint_32  _PTR_ optlen
         /* [IN/OUT] length of the option value, in bytes */
   )
{ /* Body */
   uint_32 error;

   RTCS_ENTER(GETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   switch (optname) {

   case RTCS_SO_TYPE:
      *(uint_32_ptr)optval = (uint_32)((SOCKET_STRUCT_PTR)sock)->PROTOCOL;
      break;

   case RTCS_SO_ERROR:
      *(uint_32_ptr)optval = (uint_32)((SOCKET_STRUCT_PTR)sock)->ERROR_CODE;
      break;

   default:
      if ((uint_32)((SOCKET_STRUCT_PTR)sock)->PROTOCOL == SOCK_STREAM) {
         level = SOL_TCP;
#if RTCSCFG_ENABLE_UDP
      } else if ((uint_32)((SOCKET_STRUCT_PTR)sock)->PROTOCOL == SOCK_DGRAM) {
         level = SOL_UDP;
#endif
      } else {
         RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID_OPTION);
      } /* Endif */
      error = getsockopt(sock, level, optname, optval, optlen);
      RTCS_EXIT(GETSOCKOPT, error);
   } /* Endswitch */

   RTCS_EXIT(GETSOCKOPT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_SOCKET_setsockopt
* Returned Value  : error code
* Comments  :  Modify the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_SOCKET_setsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] new value for the option */
      uint_32        optlen
         /* [IN] length of the option value, in bytes */
   )
{ /* Body */
   uint_32 error;

   RTCS_ENTER(SETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   switch (optname) {

   case RTCS_SO_TYPE:
   case RTCS_SO_ERROR:
      RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID_OPTION);

   default:
      if ((uint_32)((SOCKET_STRUCT_PTR)sock)->PROTOCOL == SOCK_STREAM) {
         level = SOL_TCP;
#if RTCSCFG_ENABLE_UDP
      } else if ((uint_32)((SOCKET_STRUCT_PTR)sock)->PROTOCOL == SOCK_DGRAM) {
         level = SOL_UDP;
#endif
      } else {
         RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID_OPTION);
      } /* Endif */
      error = setsockopt(sock, level, optname, optval, optlen);
      RTCS_EXIT(SETSOCKOPT, error);
   } /* Endswitch */

   /* Start SPR P122-0266-35. remove all warnings from RTCS code. */
   /* RTCS_EXIT(SETSOCKOPT, RTCS_OK); */
   /* End SPR P122-0266-35. */

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/iftunnel.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iftunnel.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the interface functions to the
*   RTCS tunnel device.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "iptunnel.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_tunnel_add
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Adds an IP over IP tunnel to RTCS.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_tunnel_add
   (
      /* [IN] Inner IP header source address to tunnel */
      _ip_address  inner_source_addr,
      /* [IN] Inner IP header source address network mask */
      _ip_address  inner_source_netmask,
      /* [IN] Inner IP header destination address to tunnel */
      _ip_address  inner_dest_addr,
      /* [IN] Inner IP header destination network mask */
      _ip_address  inner_dest_netmask,
      /* [IN] Outer IP header source address */
      _ip_address  outer_source_addr,
      /* [IN] Outer IP header destination address */
      _ip_address  outer_dest_addr,
      /* [IN] Flags to set tunnel behaviour */
      uint_32 flags
   )
{ /* Body */
   IPIP_PARM  parms;

   parms.TUNNEL.INNER_SOURCE         = inner_source_addr & inner_source_netmask;
   parms.TUNNEL.INNER_SOURCE_NETMASK = inner_source_netmask;
   parms.TUNNEL.INNER_DEST           = inner_dest_addr & inner_dest_netmask;
   parms.TUNNEL.INNER_DEST_NETMASK   = inner_dest_netmask;
   parms.TUNNEL.OUTER_DEST           = outer_dest_addr;
   parms.TUNNEL.OUTER_SOURCE         = outer_source_addr;
   parms.TUNNEL.FLAGS                = flags;

   return RTCSCMD_issue(parms, IPIP_insert);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_tunnel_remove
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Removes an IP over IP tunnel from RTCS.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_tunnel_remove
   (
      /* [IN] Inner IP header source address to tunnel */
      _ip_address  inner_source_addr,
      /* [IN] Inner IP header source address network mask */
      _ip_address  inner_source_netmask,
      /* [IN] Inner IP header destination address to tunnel */
      _ip_address  inner_dest_addr,
      /* [IN] Inner IP header destination network mask */
      _ip_address  inner_dest_netmask,
      /* [IN] Outer IP header source address */
      _ip_address  outer_source_addr,
      /* [IN] Outer IP header destination address */
      _ip_address  outer_dest_addr,
      /* [IN] Flags to set tunnel behaviour */
      uint_32 flags
   )
{ /* Body */
   IPIP_PARM  parms;

   parms.TUNNEL.INNER_SOURCE         = inner_source_addr & inner_source_netmask;
   parms.TUNNEL.INNER_SOURCE_NETMASK = inner_source_netmask;
   parms.TUNNEL.INNER_DEST           = inner_dest_addr & inner_dest_netmask;
   parms.TUNNEL.INNER_DEST_NETMASK   = inner_dest_netmask;
   parms.TUNNEL.OUTER_DEST           = outer_dest_addr;
   parms.TUNNEL.OUTER_SOURCE         = outer_source_addr;
   parms.TUNNEL.FLAGS                = flags;

   return RTCSCMD_issue(parms, IPIP_delete);

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_ping.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_ping.c$
* $Version : 3.8.13.0$
* $Date    : Sep-11-2012$
*
* Comments:
*
*   This file contains the RTCS shell ping commnad.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <mqx.h>
#include "shell.h"

#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h"
#include <enet.h>

typedef struct shell_ping_parameter
{
	const char_ptr  parameter;
   	int_32          value;
} SHELL_PING_PARAMETER, _PTR_ SHELL_PING_PARAMETER_PTR; 


static int_32 shell_ping_take_value(int_32_ptr value, char_ptr param,char_ptr message )	;

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_ping
*  Returned Value:  none
*  Comments  :  SHELL utility to ping a host.
*
*END*-----------------------------------------------------------------*/
int_32  Shell_ping(int_32 argc, char_ptr argv[] )
{
   	uint_32         i;
    uint_32         x;
   	uint_16         pingid = 0;
   	boolean         print_usage;
   	boolean         shorthelp = FALSE;
   	int_32          return_code = SHELL_EXIT_SUCCESS;
	uint_32         error_flag=0;
    int_32          time;
    int_32          error=0;
    char            addr_str[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
    char            *ping_send_buffer=NULL;
    struct addrinfo hints;          /* Used for getaddrinfo()*/
    struct addrinfo *addrinfo_res;  /* Used for getaddrinfo()*/

    /* ping default parameters. */
    SHELL_PING_PARAMETER ping_params[] =
    {
        { "-n", 0	},  /* Resolve or not numeric IP addresses.*/ /* Ignored.*/
        { "-c", 4 	},  /* Amount of ping.*/
        { "-h", 64	},  /* Max hops for IPv6 , or TTL for IPv4.*/
        { "-i", 1000},  /* Wait interval seconds between sending each packet.*/
        { "-p", 0xff }, /* Byte pattern for data of paket.*/
        { "-s", 56	}   /* number of data bytes to be sent.*/
    };
    #define SHELL_PING_PARAMETERS_NUMBER (sizeof(ping_params)/sizeof(SHELL_PING_PARAMETER))


    print_usage = Shell_check_help_request(argc, argv, &shorthelp );

    if (!print_usage)
    {
        if (argc >= 2)
        {
            if (argc > 2)
            {
                i=1;
                while(i < argc)
                {/* Checking all input parameters.*/
                    x=0;
                    error_flag=0;   /*=0 - no error for unknown parameters.*/
                    while(x < SHELL_PING_PARAMETERS_NUMBER)
                    {/* Looking for valid parameters.*/
                        if((strcmp(argv[i],ping_params[x].parameter))==0)
                        {/* If we found something.*/
                            switch (x)
                            {
                                case (0): 
                                    ping_params[x].value = 1;
                                    printf("num output only\n");
                                    error_flag = 0;
                                    break; /* Ignored.*/
                                case (1):
                                    i++;
                                    error_flag = shell_ping_take_value(&(ping_params[x].value), argv[i], "count");       /* Amount of ping.*/
                                    break;
                                case (2):
                                    i++;
                                    error_flag = shell_ping_take_value(&(ping_params[x].value), argv[i], "hoplimit");    /* Something like TTL(time to live)*/
                                    break;
                                case (3):
                                    i++;
                                    error_flag = shell_ping_take_value(&(ping_params[x].value), argv[i], "p_wait");      /* Time interval between two packets.*/
                                    ping_params[x].value = ping_params[x].value * 1000;
                                    break;
                                case (4):
                                    i++;
                                    error_flag = shell_ping_take_value(&(ping_params[x].value), argv[i], "pattern");     /* What digit we will use for packets data.*/
                                    break;
                                case (5):
                                    i++;
                                    error_flag = shell_ping_take_value(&(ping_params[x].value), argv[i], "packet size"); /* Size of packet.*/
                                    break;
                                default:
                                    error_flag=0;
                            }/* switch (x) */
                        }/* if((strcmp(argv[i],ping6_param[x].parameter))==0) */
                        x++;
                    }/* while(x < SHELL_PING_PARAMETERS_NUMBER) */
                    i++;
                }/* while(i<argc) */
            } /* if (argc > 2) */
           
            /* TBD: handle error_flag */

            /* Extract IP address and detect family, here we will get scope_id too. */
            memset(&hints,0,sizeof(hints));
            hints.ai_family 	= AF_UNSPEC;
            hints.ai_socktype 	= SOCK_DGRAM;
            hints.ai_flags 		= AI_CANONNAME;
            if (getaddrinfo(argv[argc-1], NULL, &hints, &addrinfo_res) != 0)
            {
                printf("GETADDRINFO error\n");
                return(SHELL_EXIT_ERROR); /* We can return right here and do not need free freeaddrinfo(addrinfo_res)*/
            }

            /* Prepare ping */
            if(inet_ntop(addrinfo_res->ai_family,&((struct sockaddr_in6 *)((*addrinfo_res).ai_addr))->sin6_addr, addr_str, sizeof(addr_str)))
			{
                /* Allocate data buffer for ping. */
                ping_send_buffer = RTCS_mem_alloc(ping_params[5].value); /* ping6_param[5].value - value of bytes in packet */
                if(ping_send_buffer)
                {
                    /* Set value of bytes of data buffer in according with patterns
                     * ping6_param[4].value - patterns.
                     * ping6_param[5].value - size of buffer.
                     */
                    memset(ping_send_buffer, ping_params[4].value, ping_params[5].value);
                }
                else
                {
                    printf("Ping error - can not allocate ping buffer. Size is too big.\n");
                    return_code = SHELL_EXIT_ERROR;
                    goto EXIT_1;
                }
			}
			else
			{
		  	    printf("Address parameter is wrong.\n");
                return_code = SHELL_EXIT_ERROR;
                goto EXIT_1;
			}
            
            printf("Pinging %s:\n", addr_str);
            printf("Press [q] to cancel.\n", addr_str);

            /* Start of sending of packets. */
            for (i=0; i< ping_params[1].value; i++) /* Amount of how much packets we will send.*/
            {

                if (fstatus(stdin))
                { 
                    uchar c = fgetc(stdin); 
                    if (tolower(c)=='q')
                    { 
                        printf("\n"); 
                        goto EXIT_1; 
                    } 
                } 

                time = ping_params[3].value; /* Maximum waiting time for answer */

            #if RTCSCFG_ENABLE_IP4
                if(addrinfo_res->ai_family==AF_INET)
                {   /* IPv4 Ping. */
                     error = RTCS_ping( ((sockaddr_in *)(addrinfo_res->ai_addr))->sin_addr.s_addr, 
                                        (uint_32_ptr)&time,
                                        ++pingid,
                                        (uint_8)ping_params[2].value,
                                        ping_send_buffer,
                                        ping_params[5].value );
                }
                else 
            #endif
            #if RTCSCFG_ENABLE_IP6
                if(addrinfo_res->ai_family==AF_INET6)
                {   /* IPv6 Ping. */
                    error = RTCS6_ping( addrinfo_res->ai_addr,
                                        (uint_32_ptr)&time,
                                        ++pingid,
                                        (uint_8)ping_params[2].value,
                                        ping_send_buffer,
                                        ping_params[5].value );
                }
                else
            #endif
                {   /* Exit if inet family is unknown. */
                    printf("Ping error - %d is not supported inet family\n",addrinfo_res->ai_family);
                    return_code = SHELL_EXIT_ERROR;
                    goto EXIT_1;
                }


                if (error)
                {
                    if (error == RTCSERR_ICMP_ECHO_TIMEOUT)
                    {
                        printf("Request timed out\n");
                    }
                    else
                    {
                    #if BSP_ENET_DEVICE_COUNT > 0
                        printf("Error 0x%04lX - %s\n", error,  ENET_strerror(error));
                    #else
                        printf("Error 0x%04lX \n", error);
                    #endif
                    }
                }
                else
                {
                    if (time < 1)
                    {
                        printf("Reply from [%s]: time<1ms\n", addr_str);
                    }
                    else
                    {
                        printf("Reply from [%s]: time=%ldms\n", addr_str, time);
                    }
                }
                
                /* Possible timeout*/
                if ((time < ping_params[3].value) && (i<(ping_params[1].value-1)))
                {
                    RTCS_time_delay(ping_params[3].value - time); /* ping6_param[3].value - time interval between two packets*/
                }
            } 

            error = _mem_free(ping_send_buffer);
            if( error != MQX_OK)
            {
                printf("Ping buffer mem free error - %d \n", error);
                return_code = SHELL_EXIT_ERROR;
                goto EXIT_1;
            }
        }/* if (argc >= 2) */
        else
        {
            printf("Error, %s invoked with incorrect number of arguments\n", argv[0]);
            print_usage = TRUE;
        }
    }

    if (print_usage)
    {
        if (shorthelp)
        {
            printf("%s [-c count] [-h hoplimit] [-i interval] [-p pattern] [-s size] <host>\n", argv[0]);
        }
        else
        {
            printf("Usage: %s [-c count][-h hoplimit][-i wait][-p pattern][-s size] <host>\n", argv[0]);
        #if 0 /* TBD */
            printf("   -n numeric output only. (IPv6) \n");
        #endif
            printf("   -c Stop after sending count packets.\n");
            printf("   -h Set IPv6 hoplimit, or IPv4 TTL.\n");
            printf("   -i Wait interval seconds between sending each packet.\n");
            printf("   -p Byte pattern for data of paket.\n");
            printf("   -s Number of data bytes to be sent.\n");
        }
        goto EXIT_2;
    }

EXIT_1:
    freeaddrinfo(addrinfo_res);
EXIT_2:
    return return_code;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  shell_ping_take_value
*  Returned Value:  Error.
*  Comments  :  Convert sring to paraneter value.
*
*END*-----------------------------------------------------------------*/
static int_32 shell_ping_take_value(int_32_ptr value, char_ptr param, char_ptr message )	
{
    if((strcmp(param,"0"))==0)
    {
        *value = 0;
        printf("num. of %s= %d\n", message, (*value));

        return(0);
    }
    else
    {
        *value = _io_atoi(param);

        if(!(*value))
        {/* it can not to be 0 */
            printf("%s is not valid number of %s\n",param,message);
            return(1);
        }	
        else
        {
            printf("num. of %s= %d\n",message,(*value));
            return(0);
        }
    }
}




#endif /* SHELLCFG_USES_RTCS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Limit.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GFLIB_Limit.h
*
* @author    R29302
* 
* @version   1.0.1.0
* 
* @date      Dec-6-2012
* 
* @brief     Header file for two side limit function.
*
*******************************************************************************
*
* Function impemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_LIMIT_H_
#define _GFLIB_LIMIT_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/************************************************************************
| defines and macros (scope: module-local)
|-----------------------------------------------------------------------*/

/*! 
 * \def GFLIB_Limit(f32In, pParam)
 * Function alias for the #GFLIB_LimitANSIC function.
 */

#define GFLIB_Limit(f32In, pParam) GFLIB_LimitANSIC((f32In), (pParam))

/************************************************************************
| typedefs and structures (scope: module-local)
|-----------------------------------------------------------------------*/

/*------------------------------------------------------------------------*//*!
@struct     GFLIB_LIMIT_T "\GFLIB_Limit.h"

@brief      Structure containing the limits.

*//*-------------------------------------------------------------------------*/

typedef struct {
    Frac32 f32LowerLimit; /*!< Lower limit. */
    Frac32 f32UpperLimit; /*!< Upper limit. */
} GFLIB_LIMIT_T;

/************************************************************************
| exported variables
|-----------------------------------------------------------------------*/

/************************************************************************
| exported function prototypes
|-----------------------------------------------------------------------*/

/*! 
* @ingroup GFLIB_GROUP 
*/ 
extern Frac32 GFLIB_LimitANSIC (Frac32 f32In,
                                 const GFLIB_LIMIT_T *const pParam);

#ifdef __cplusplus
}
#endif

#endif /* _GFLIB_LIMIT_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GMCLIB/GMCLIB_ClarkInv.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GMCLIB_ClarkInv.h
*
* @author    <NAME>
*
* @version   1.0.1.0
*
* @date      Dec-6-2012
*
* @brief     Header file for #GMCLIB_ClarkInv transformation algorithm.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GMCLIB_CLARK_INV_H_
#define _GMCLIB_CLARK_INV_H_

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif

/************************************************************************
| defines and macros (scope: module-local)
|-----------------------------------------------------------------------*/
/*! Function alias for the #GMCLIB_ClarkInvANSIC function.*/
#define GMCLIB_ClarkInv(pOut, pIn)    GMCLIB_ClarkInvANSIC(pOut, pIn)

/************************************************************************
| typedefs and structures (scope: module-local)
|-----------------------------------------------------------------------*/

/************************************************************************
| exported variables
|-----------------------------------------------------------------------*/

/************************************************************************
| exported function prototypes
|-----------------------------------------------------------------------*/

/*!
* @ingroup GMCLIB_GROUP
*/
extern void GMCLIB_ClarkInvANSIC (MCLIB_3_COOR_SYST_T *pOut,
                                  const MCLIB_2_COOR_SYST_ALPHA_BETA_T *const pIn);

#ifdef __cplusplus
}
#endif
#endif /* _GMCLIB_CLARK_INV_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/int/serl_int_linflexd.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_int_linflexd.c$
* $Version : 3.8.2.0$
* $Date    : Oct-5-2011$
*
* Comments:
*
*   This file contains the driver functions for the LINFLEXD
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "io_prv.h"
#include "charq.h"
#include "fio_prv.h"
#include "serinprv.h"


extern _mqx_uint _linflexd_serial_polled_ioctl(LINFLEXD_SERIAL_INFO_STRUCT_PTR, _mqx_uint, pointer);
extern _mqx_uint _linflexd_serial_init(LINFLEXD_SERIAL_INIT_STRUCT_PTR, pointer _PTR_, char_ptr, uint_32);
extern _mqx_uint _linflexd_serial_polled_deinit(LINFLEXD_SERIAL_INIT_STRUCT_PTR, LINFLEXD_SERIAL_INFO_STRUCT_PTR );

static uint_32 _linflexd_serial_int_init( IO_SERIAL_INT_DEVICE_STRUCT_PTR, char_ptr);
static uint_32 _linflexd_serial_int_deinit( LINFLEXD_SERIAL_INIT_STRUCT_PTR,LINFLEXD_SERIAL_INFO_STRUCT_PTR);
static uint_32 _linflexd_serial_int_enable( LINFLEXD_SERIAL_INFO_STRUCT_PTR);
static void    _linflexd_serial_int_rx_isr(pointer);
static void    _linflexd_serial_int_tx_isr(pointer);
static void    _linflexd_serial_int_err_isr(pointer);
static void    _linflexd_serial_int_putc( IO_SERIAL_INT_DEVICE_STRUCT_PTR,char);


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _linflexd_serial_int_install
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    Install an interrupt driven uart serial device.
*
*END*----------------------------------------------------------------------*/

uint_32 _linflexd_serial_int_install
    (
        /* [IN] A string that identifies the device for fopen */
        char_ptr identifier,

        /* [IN] The I/O init data pointer */
        const LINFLEXD_SERIAL_INIT_STRUCT _PTR_ init_data_ptr
    )
{
    return _io_serial_int_install(identifier,
        (uint_32 (_CODE_PTR_)(pointer, char _PTR_))_linflexd_serial_int_init,
        (uint_32 (_CODE_PTR_)(pointer))_linflexd_serial_int_enable,
        (uint_32 (_CODE_PTR_)(pointer,pointer))_linflexd_serial_int_deinit,
        (void    (_CODE_PTR_)(pointer, char))_linflexd_serial_int_putc,
        (uint_32 (_CODE_PTR_)(pointer, uint_32, pointer))_linflexd_serial_polled_ioctl,
        (pointer)init_data_ptr,
        init_data_ptr->QUEUE_SIZE);
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_int_init
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function initializes the UART in interrupt mode.
*
*END*********************************************************************/

static uint_32 _linflexd_serial_int_init
    (
        /* [IN] the interrupt I/O initialization information */
        IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

        /* [IN] the rest of the name of the device opened */
        char_ptr                        open_name_ptr
    )
{
    LINFLEXD_SERIAL_INFO_STRUCT_PTR uart_info_ptr;
    LINFLEXD_SERIAL_INIT_STRUCT_PTR uart_init_ptr;
    uint_32                         i,result;

    uart_init_ptr = int_io_dev_ptr->DEV_INIT_DATA_PTR;

    result = _linflexd_serial_init((pointer)uart_init_ptr,
        &int_io_dev_ptr->DEV_INFO_PTR, open_name_ptr, LINFLEXD_BUFFER_MODE);

    if (result != MQX_OK)
    {
        return result;
    }

    uart_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;

    uart_info_ptr->NUM_VECTORS = _bsp_get_linflexd_vectors(uart_init_ptr->DEVICE, &uart_info_ptr->VECTORS);

    if (uart_info_ptr->NUM_VECTORS == LINFLEXD_NUM_VECTORS)
    {
        for (i=0; i < uart_info_ptr->NUM_VECTORS; i++)
        {
            uart_info_ptr->OLD_ISR_DATA[i] = _int_get_isr_data(uart_info_ptr->VECTORS[i]);
        }

        uart_info_ptr->OLD_ISR[LINFLEXD_RX_VECTOR_INDEX] =
             _int_install_isr(uart_info_ptr->VECTORS[LINFLEXD_RX_VECTOR_INDEX], _linflexd_serial_int_rx_isr, int_io_dev_ptr);

        uart_info_ptr->OLD_ISR[LINFLEXD_TX_VECTOR_INDEX] =
             _int_install_isr(uart_info_ptr->VECTORS[LINFLEXD_TX_VECTOR_INDEX], _linflexd_serial_int_tx_isr, int_io_dev_ptr);

        uart_info_ptr->OLD_ISR[LINFLEXD_ERR_VECTOR_INDEX] =
             _int_install_isr(uart_info_ptr->VECTORS[LINFLEXD_ERR_VECTOR_INDEX], _linflexd_serial_int_err_isr, int_io_dev_ptr);

        for (i=0;i<uart_info_ptr->NUM_VECTORS;i++)
        {
            _bsp_int_init(uart_info_ptr->VECTORS[i], uart_init_ptr->PRIORITY,0,TRUE);
        }
    }
    else
    {
         return MQX_INVALID_VECTORED_INTERRUPT;
    }
    
    return MQX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_int_deinit
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function de-initializes the UART in interrupt mode.
*
*END*********************************************************************/

static uint_32 _linflexd_serial_int_deinit
    (
        /* [IN] the interrupt I/O initialization information */
        LINFLEXD_SERIAL_INIT_STRUCT_PTR io_init_ptr,

        /* [IN] the address of the device specific information */
        LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr
    )
{
    VLINFLEXD_REG_STRUCT_PTR            linflexd_ptr = io_info_ptr->LINFLEXD_PTR;
    uint_32 i;

    /* Disable interrupts */
    linflexd_ptr->LINIER = 0;

    _linflexd_serial_polled_deinit(io_init_ptr, io_info_ptr);

    for (i=0;i<io_info_ptr->NUM_VECTORS;i++)
    {
        _int_install_isr(io_info_ptr->VECTORS[i], io_info_ptr->OLD_ISR[i], io_info_ptr->OLD_ISR_DATA[i]);
    }

    return(MQX_OK);
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_int_enable
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function enables the UART interrupts mode.
*
*END*********************************************************************/

uint_32 _linflexd_serial_int_enable
    (
        /* [IN] the address of the device specific information */
        LINFLEXD_SERIAL_INFO_STRUCT_PTR io_info_ptr
    )
{
    VLINFLEXD_REG_STRUCT_PTR            linflexd_ptr = io_info_ptr->LINFLEXD_PTR;

    linflexd_ptr->LINIER = LINFLEXD_LINIER_DTIE | LINFLEXD_LINIER_DRIE;

    return MQX_OK;
}



/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_int_rx_isr
* Returned Value   : none
* Comments         :
*   interrupt handler for the serial I/O interrupts.
*
*************************************************************************/

static void _linflexd_serial_int_rx_isr
    (
        /* [IN] the address of the device specific information */
        pointer parameter
    )
{
    IO_SERIAL_INT_DEVICE_STRUCT_PTR     int_io_dev_ptr = parameter;
    LINFLEXD_SERIAL_INFO_STRUCT_PTR     io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
    VLINFLEXD_REG_STRUCT_PTR            linflexd_ptr = io_info_ptr->LINFLEXD_PTR;
    int_32                              c;
    uint_16                             stat;

    /* Handle receive */
    while (linflexd_ptr->UARTSR & LINFLEXD_UARTSR_DRFRFE) {

        linflexd_ptr->UARTSR =  LINFLEXD_UARTSR_DRFRFE;
        c = linflexd_ptr->BDRM[3];

        stat = linflexd_ptr->UARTSR;
        if (stat & (LINFLEXD_UARTSR_BOF|LINFLEXD_UARTSR_SZF|LINFLEXD_UARTSR_FEF|LINFLEXD_UARTSR_PE)) {
            if (stat & LINFLEXD_UARTSR_SZF) {
                ++io_info_ptr->STATS.RX_BREAKS;
                linflexd_ptr->UARTSR = LINFLEXD_UARTSR_SZF;
            }
            if (stat & LINFLEXD_UARTSR_BOF) {
                ++io_info_ptr->STATS.RX_OVERRUNS;
                linflexd_ptr->UARTSR = LINFLEXD_UARTSR_BOF;
            }
            if (stat & LINFLEXD_UARTSR_FEF) {
                ++io_info_ptr->STATS.RX_FRAMING_ERRORS;
                linflexd_ptr->UARTSR = LINFLEXD_UARTSR_FEF;
            }
            if (stat & LINFLEXD_UARTSR_PE) {
                ++io_info_ptr->STATS.RX_PARITY_ERRORS;
                linflexd_ptr->UARTSR = LINFLEXD_UARTSR_PE;
            }
        }

        io_info_ptr->STATS.RX_CHARS++;

        if (!_io_serial_int_addc(int_io_dev_ptr, c)) {
            io_info_ptr->STATS.RX_DROPPED_INPUT++;
        }
    }

    io_info_ptr->STATS.INTERRUPTS++;
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_int_tx_isr
* Returned Value   : none
* Comments         :
*   interrupt handler for the serial I/O interrupts.
*
*************************************************************************/

static void _linflexd_serial_int_tx_isr
    (
        /* [IN] the address of the device specific information */
        pointer parameter
    )
{
    IO_SERIAL_INT_DEVICE_STRUCT_PTR     int_io_dev_ptr = parameter;
    LINFLEXD_SERIAL_INFO_STRUCT_PTR     io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
    VLINFLEXD_REG_STRUCT_PTR            linflexd_ptr = io_info_ptr->LINFLEXD_PTR;
    int_32                              c;

    /* Handle Transmit */
    linflexd_ptr->UARTSR = LINFLEXD_UARTSR_DTFTFF;

    c = _io_serial_int_nextc(int_io_dev_ptr);
    if (c >= 0)
    {
        linflexd_ptr->BDRL[3] = c;
        io_info_ptr->STATS.TX_CHARS++;
    }

    io_info_ptr->STATS.INTERRUPTS++;
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_int_err_isr
* Returned Value   : none
* Comments         :
*   interrupt handler for the serial I/O error interrupts.
*
*************************************************************************/

static void _linflexd_serial_int_err_isr
    (
        /* [IN] the address of the device specific information */
        pointer parameter
    )
{
    IO_SERIAL_INT_DEVICE_STRUCT_PTR     int_io_dev_ptr = parameter;
    LINFLEXD_SERIAL_INFO_STRUCT_PTR     io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
    VLINFLEXD_REG_STRUCT_PTR            linflexd_ptr = io_info_ptr->LINFLEXD_PTR;

    io_info_ptr->STATS.INTERRUPTS++;
}


/*FUNCTION****************************************************************
*
* Function Name    : _linflexd_serial_int_putc
* Returned Value   : none
* Comments         :
*   This function is called to write out the first character, when
* the output serial device and output ring buffers are empty.
*
*END*********************************************************************/

static void _linflexd_serial_int_putc
    (
        /* [IN] the address of the device specific information */
        IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

        /* [IN] the character to write out now */
        char c
    )
{
    LINFLEXD_SERIAL_INFO_STRUCT_PTR     io_info_ptr =  int_io_dev_ptr->DEV_INFO_PTR;
    VLINFLEXD_REG_STRUCT_PTR            linflexd_ptr = io_info_ptr->LINFLEXD_PTR;

    linflexd_ptr->BDRL[3] = c;
    io_info_ptr->STATS.TX_CHARS++;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_util.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_util.c$
* $Version : 3.8.12.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   Contains misc io functions.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include <ctype.h>
#include <string.h>


static char_ptr _parse_next_filename(char_ptr src, int_32_ptr len, int_32 max_len); 

static FS_TABLE_ENTRY _opened_fs_table[MAX_FS_INSTANCES]; 

/*!
 * \brief Converts specifed string to lower case.
 * 
 * \param[in] arg Pointer to string to convert.
 * 
 * \return TRUE or FALSE (Arg is NULL.) 
 */ 
boolean _io_strtolower( char_ptr arg)
{
   int_32 i=0;
   
   if (arg == NULL) return FALSE;
   while (arg[i])  {
      // Allows constant strings - as long as they are lowercase already
      if (isupper(arg[i])) {
        arg[i] = (char) tolower(arg[i]);
      }
      i++;
   }
   return FALSE;
}

/*!
 * \brief Compares two strings with different case size.
 * 
 * \param[in] s1 Pointer to string 1.
 * \param[in] s2 Pointer to string 2.
 * 
 * \return 0 End of string 1.
 * \return Difference between the two strings.    
 */ 
_mqx_int _io_strcasecmp(const char *s1, const char *s2)
{
   while (tolower((int)*s1) == tolower((int)*s2))
   {
      if (*s1++ == '\0')
         return (0);
      s2++;
   }
   return (tolower((int)*s1) - tolower((int)*s2));
}

/*!
 * \brief Compares first n characters of two strings with different case size.
 * 
 * \param[in] s1 Pointer to string 1.
 * \param[in] s2 Pointer to string 2.
 * \param[in] n  Number of characters to compare.
 * 
 * \return 0 End of string 1.
 * \return Difference between the two strings.    
 */ 
_mqx_int _io_strncasecmp(const char *s1, const char *s2, uint_32 n)
{
   if (n != 0)
   {
      do 
      {
         if (tolower((int)*s1) != tolower((int)*s2))
            return (tolower((int)*s1) - tolower((int)*s2));
         if (*s1++ == '\0')
            break;
         s2++;
      } while (--n != 0);
   }
   return (0);
}
 /*!
  * \brief Finds file name stored in specified string.
  * 
  * \param[in] arg Pointer to search file name in.
  * 
  * \return Pointer to file name.
  * \return NULL (failure)       
  */  
char_ptr _io_find_filename(char_ptr arg)  
{
   uint_32 i=0;

   if (arg==NULL) return NULL;
   
   while (isgraph(arg[i]) && (arg[i] != ':')) i++;
   if (arg[i] == ':')  {
      return &arg[i+1];
   } else  if (arg[i] == '\0')  {
      return arg;
   } else  {
      return NULL;
   }
}

/*!
 * \brief Validates specified device.
 * 
 * \param[in] arg Pointer to the device to validate.
 * 
 * \return TRUE or FALSE (failure)  
 */ 
boolean _io_validate_device(char_ptr arg)  
{
   uint_32 i=0;

   while (isgraph(arg[i]) && (arg[i] != ':')) i++;
   if (i && (arg[i]==':') && (arg[i+1]=='\0')) return TRUE;
   return FALSE;
}

/*!
 * \brief Creates prefixed file name.
 * 
 * If no new name supplied, current device name will be used.
 *  
 * \param[in] new_ptr Pointer to new file name.
 * \param[in] in_ptr  Pointer to string containing new file name.
 * \param[in] dev_ptr Pointer to current device name.
 */ 
void _io_create_prefixed_filename( char_ptr new_ptr, char_ptr in_ptr,  char_ptr dev_ptr)
{
   char_ptr file_ptr;
   
   new_ptr[0] = '\0';
   file_ptr = _io_find_filename(in_ptr);
   if (file_ptr == in_ptr)  {
      // No device name supplied, use current
      strcpy(new_ptr, dev_ptr);
   }  
   strcat(new_ptr, in_ptr);
}

/*!
 * \brief Gets pointer on the row where fs_name is stored.
 * 
 * \param[in] fs_name string that is being looked for.
 * 
 * \return Pointer to the row where the fs_name is stored.
 * \return NULL (failure)  
 */ 
MQX_FILE_PTR _io_get_fs_by_name(char_ptr fs_name)
{
   int i;
   char_ptr a;
   char_ptr b;

   if (*fs_name == '\0')
     return NULL;
   
   for(i=0;i<MAX_FS_INSTANCES;i++)
   {
      a = _opened_fs_table[i].FS_NAME;
      b = fs_name;

      while (*a && (*a == *b))
      {
         a++;
         b++;
      }

      // check whether name from the table is prefix of fs_name
      if (*a == '\0')
      {
         return _opened_fs_table[i].FS_PTR;
      }
   }
   // filesystem not found in table
   return NULL;
}
/*!
 * \brief Gets pointer on the row where first valid filesystem is stored.
 * 
 * \return Pointer to the row where the first fs_name is stored.
 * \return NULL (failure)  
 */ 
MQX_FILE_PTR _io_get_first_valid_fs()
{
   int i;
   // find first used field in table
   for(i=0;i<MAX_FS_INSTANCES;i++)
   {
      if (_opened_fs_table[i].FS_PTR != NULL)
      {
         return _opened_fs_table[i].FS_PTR; 
      }
   }
   return NULL;
}

/*!
 * \brief Return TRUE or FALSE if filesystem is in list or not.
 * 
 * \param[in] fs_ptr Pointer to file system structure.
 * 
 * \return TRUE (File system is in table.) of FALSE (failure). 
 */ 
boolean _io_is_fs_valid(MQX_FILE_PTR fs_ptr)
{
   int i;
   
   /* First check that file pointer is not null */
   if (fs_ptr == NULL)
   {
      return FALSE;    
   }
      
   /* find first used field in table */
   for(i=0;i<MAX_FS_INSTANCES;i++)
   {
      if (_opened_fs_table[i].FS_PTR == fs_ptr)
      {
         return TRUE;
      }
   }
   return FALSE;
}

/*!
 * \brief Checks whether file system is in list or not.
 * 
 * \param[in] fs_ptr      Pointer to the file system.
 * \param[in] fs_name     File system name.
 * \param[in] fs_name_len File system name length.
 * 
 * \return MQX_OK 
 * \return MQX_INVALID_POINTER (Fd_ptr is NULL.)
 * \return MQX_INVALID_SIZE (Invalid file system name length.) 
 */ 
int_32 _io_get_fs_name(MQX_FILE_PTR fs_ptr, char_ptr fs_name, int_32 fs_name_len)
{
   int i;
 
    /* First check that input parameters are not not null */
   if (fs_ptr == NULL || fs_name == NULL)
   {
      return MQX_INVALID_POINTER;    
   }
   
   /* find first used field in table */
   for(i=0;i<MAX_FS_INSTANCES;i++)
   {
      if (_opened_fs_table[i].FS_PTR == fs_ptr)
      {
         if(fs_name_len > strlen(_opened_fs_table[i].FS_NAME))
         {
           strcpy(fs_name,_opened_fs_table[i].FS_NAME);
           return MQX_OK;
         }
         else
         {
           return MQX_INVALID_SIZE;
         }
      }
   }
   return MQX_INVALID_POINTER;
}

/*!
 * \brief Store file system name and handle into _opened_fs_table.
 * 
 * \param[in] fd_ptr   Pointer to file.
 * \param[in] name_ptr Pointer to file name.
 * 
 * \return MQX_OK  
 * \return MQX_INVALID_POINTER (Fd_ptr is NULL.)
 * \return MQX_OUT_OF_MEMORY (There is no empty slot.)
 */ 
uint_32 _io_register_file_system(MQX_FILE_PTR fd_ptr,char_ptr name_ptr)
{
   int i;

   /* First check that file pointer is not null */
   if (fd_ptr == NULL || name_ptr == NULL)
   {
      return MQX_INVALID_POINTER;    
   }       
   
   
   /* find first empty field in table */
   for(i=0;i<MAX_FS_INSTANCES;i++)
   {
      if (_opened_fs_table[i].FS_PTR == NULL)
      {
        /* store filesystem pointer and name into the table */
        _opened_fs_table[i].FS_PTR = fd_ptr;
         strncpy(_opened_fs_table[i].FS_NAME, name_ptr, FS_MAX_DEVLEN);
         return MQX_OK;      
      }
   }
   /* there is no empty slot, report error */
   return MQX_OUT_OF_MEMORY;
}

/*!
 * \brief Removes filesystem name and handle from _opened_fs_table.
 * 
 * \param[in] fd_ptr Pointer to file.
 * 
 * \return MQX_OK 
 * \return MQX_INVALID_POINTER (Fd_ptr is NULL.)
 * \return MQX_INVALID_HANDLE (File system not found.)
 */ 
uint_32 _io_unregister_file_system(MQX_FILE_PTR fd_ptr)
{
   int i;

   /* First check that file pointer is not null */
   if (fd_ptr == NULL)
   {
      return MQX_INVALID_POINTER;    
   }    
   
   // find first empty field in table
   for(i=0;i<MAX_FS_INSTANCES;i++)
   {
      if (_opened_fs_table[i].FS_PTR == fd_ptr)
      {
         // store filesystem pointer and name into the table
         _opened_fs_table[i].FS_PTR = NULL;
         _opened_fs_table[i].FS_NAME[0] ='\0' ;
         // return MQX_OK
         return MQX_OK;      
      }
   }
   // filesystem not found report error
   return MQX_INVALID_HANDLE;
}

/*!
 * \brief  Parses given path and returns device name or current device name
 * (if there was no device name in specified path).
 * 
 * \param[out] out_dev        Pointer to place where device: will be stored.
 * \param[out] is_dev_in_path TRUE/FALSE - device name found in path
 * \param[in]  dev_len        Size of the output path.
 * \param[in]  input_path     Pointer to the parsed path.
 * \param[in]  cur_dev        Current device name.
 * 
 * \return Length of device name (can be 0).
 * \return MQX_INVALID_POINTER (Input_path is NULL.)
 */ 
int_32 _io_get_dev_for_path(char_ptr out_dev, boolean * is_dev_in_path, int_32 dev_len, char_ptr input_path, char_ptr cur_dev)
{
   int i = 0;
   if (input_path==NULL) return MQX_INVALID_POINTER;
   
   while (i < (dev_len-1) && isgraph(input_path[i]) && (input_path[i] != ':'))
      i++;

   if (input_path[i] == ':')  
   {
      // there is device name in input path 
      if (is_dev_in_path != NULL)
      {
        *is_dev_in_path = TRUE;
      }
      strncpy(out_dev, input_path, ++i);
      out_dev[i] = '\0';
      return i;
   } 
   else 
   {
      // device name is NOT in input path
      if (is_dev_in_path != NULL)
      {
        *is_dev_in_path = FALSE;
      }
      i = strlen(cur_dev);
      if (i < (dev_len - 1))
      {
         strcpy(out_dev,cur_dev);
         return i;
      }
      else 
      {
         return 0;
      }
   }
}

/*!
 * \brief Converts relative to absolute path and extend it by the device name if 
 * not present.
 * 
 * \param[out] result    Pointer to place where absolute path will be stored.
 * \param[in]  curdir    Current directory name.
 * \param[in]  inputpath Pointer to parsed path.
 * \param[in]  len       Size of result.
 * \param[in]  cur_dev   Current device name.
 * 
 * \return MQX_INVALID_PARAMETER 
 */ 
int_32 _io_rel2abs(char_ptr result, char_ptr curdir, char_ptr inputpath, int_32 len, char_ptr cur_dev)
{
  int_32 inputpathlen = strlen(inputpath);
  char_ptr path;
  char_ptr dest;
  char_ptr dirstart;  
  int_32 length = 0, devlen = 0,dirlen = 0,error_code = 0;
  boolean  relpathflag = FALSE, is_dev_in_path =  FALSE;

  devlen =  _io_get_dev_for_path(result,&is_dev_in_path,len,inputpath,cur_dev);

  // device name during path parsing will be skiped 
  dest = result = result + devlen;
  if(is_dev_in_path == TRUE)
  {
    // there was device name in input path -> skip it in parsing
    inputpath = inputpath + devlen;
  }
  dest[0] = '\\';
  dest[1] = '\0';
  length = 1;

 
  // selected path begins with / or \, that means absolute path
  if(*inputpath == '/' || *inputpath == '\\')
  {
    path = inputpath;
    relpathflag = 0;
  }
  else
  {
    path = curdir+1;
    relpathflag = 1;
  }

  // browse path, convert to upper case and eliminate . and ..
  while ( path )
  {
    if ( *path )
    {
      dirstart = path;
      path = _parse_next_filename(path, &dirlen, len);
      if (path != NULL && dirstart[0] == '.' && dirstart[1] == '.' )  // ".." 
      {
        if ( dest != result )
        {
          while ( dest != result && *dest != '\\' )
          {
            dest--;
            length--;
          }
          /* Erase the previous backslash, unless it is the
           * first (root directory).
           */
          if ( dest != result )
          {
            *dest-- = '\0';
            length--;
          }
          else                                        
          {                                           
             *(dest+1) = '\0';                        
          }                                           
        }                                             
        else                                          
        {                                             
          /*                                          
           * The check for underflow is redundant, because the path
           * has been found already.
           */
          error_code = MQX_INVALID_PARAMETER;
          break;
        }
      }
      else if ( dirstart[0] && dirstart[0] != '.' ) // not dotted path
      {
        if ( *dest != '\\' )
        {
          *(++dest) = '\\';
          length++;
        }
        length += dirlen;
        if ( length < len )
        {
          strncpy (++dest, dirstart, dirlen);
          dest[dirlen] = '\0';
          dest = result + length - 1;
        }
        else
        {
          error_code = MQX_INVALID_PARAMETER;
          break;
        }
      }
    }
    // the end of parsed string check relative/absolute path
    else
    {
      
      if(relpathflag == 1)
      {
        // new path was relative(did not started with / or \), continue in process
        path = inputpath;
        relpathflag = 0;
      }
      else
      {
        // absolute path finish process 
        break;
      }
    }
  }
  return error_code;
}


/*!
 * \brief Reads the first filename in source string, up to '\' ,'/' or '.'.
 * 
 * \param[in]  src     The path name.
 * \param[out] len     Number of currently read characters.
 * \param[in]  max_len Maximal allowend length for filename.
 * 
 * \return The read path name.
 * \return NULL (Len is larger then max_len.)  
 */ 
static char_ptr _parse_next_filename
    (
    char_ptr   src,
    int_32_ptr len,
    int_32     max_len
    )
{
    *len = 0;

    while ( *src && *src != '/' && *src != '\\' )
    {
        src++;
        (*len)++;
        if ( *len > max_len )
        {
            *len = 0;
            return NULL;
        }
    }  

    if ( *src == '\\' || *src == '/' )
    {
        src++;
    }

    return(src);
}  

/*!
 * \brief Converts ASCII to string.
 * 
 * \param[in] str Specified ASCII string.
 * 
 * \return Conveted data.
 * \return 0 (failure)   
 */ 
_mqx_int _io_atoi(const char *str) {
    int value = 0, sign = 1;
    while (*str == ' ') ++str; // skip leading whitespace

   if ( *str == '-' ) {
        sign = -1;
        str++;
   }

    while ( *str) {
        if ((*str >= '0') && (*str <= '9'))
            value = 10*value + (*str - '0');
        else
            break; // non-digit
        str++;
    }
    if (value < 0) return 0; // integer overflow
    return value*sign;
}

 
 /*
static MQX_FILE_PTR _io_default_filesystem = NULL;

void _io_set_default_filesystem(MQX_FILE_PTR fp)  
{
   _io_default_filesystem = fp;
}

MQX_FILE_PTR _io_get_default_filesystem(void)  
{
   return _io_default_filesystem;
}

static char_ptr _io_default_filesystem_name = NULL;

void _io_set_default_filesystem_name(char_ptr name)  
{
   _io_default_filesystem_name = name;
}

char_ptr _io_get_default_filesystem_name(void)  
{
   return _io_default_filesystem_name;
}
*/



<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/lwmem.c<|end_filename|>
/*HEADER*********************************************************************
 *
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: lwmem.c$
 * $Version : 3.8.2.0$
 * $Date    : Jun-25-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Lightweight Memory component.
 *
 *END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_LWMEM
#include "lwmem.h"
#include "lwmem_prv.h"

/*!
 * \private
 *
 * \brief Allocates a block of memory for a task from the free list.
 *
 * \param[in] requested_size The size of the memory block.
 * \param[in] td_ptr         The owner TD.
 * \param[in] pool_id        Which pool to allocate from.
 * \param[in] zero           Zero the memory after it is allocated.
 *
 * \return Pointer to the lightweight-memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 */
pointer _lwmem_alloc_internal
(
    _mem_size      requested_size,
    TD_STRUCT_PTR  td_ptr,
    _lwmem_pool_id pool_id,
    boolean        zero
)
{ /* Body */
    LWMEM_BLOCK_STRUCT_PTR block_ptr;
    LWMEM_BLOCK_STRUCT_PTR next_block_ptr;
    LWMEM_BLOCK_STRUCT_PTR prev_block_ptr = NULL;
    _mem_size              block_size;
    _mem_size              next_block_size;
    LWMEM_POOL_STRUCT_PTR  mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR) pool_id;

#if MQX_CHECK_VALIDITY
    if (mem_pool_ptr->VALID != LWMEM_POOL_VALID)
    {
        _task_set_error(MQX_LWMEM_POOL_INVALID);
        return (NULL);
    } /* Endif */
#endif

    /*
     * Adjust message size to allow for block management overhead
     * and force size to be aligned.
     */
    requested_size += (_mem_size) sizeof(LWMEM_BLOCK_STRUCT);
    if (requested_size < LWMEM_MIN_MEMORY_STORAGE_SIZE)
    {
        requested_size = LWMEM_MIN_MEMORY_STORAGE_SIZE;
    } /* Endif */

    _MEMORY_ALIGN_VAL_LARGER(requested_size);

    _int_disable();
    block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
    while (block_ptr != NULL)
    {
        /* Provide window for higher priority tasks */
        mem_pool_ptr->POOL_ALLOC_PTR = block_ptr;
        _int_enable();
        _int_disable();
        block_ptr = mem_pool_ptr->POOL_ALLOC_PTR;
        if (block_ptr == NULL)
        {
            /* The pool became full during preemption, no free block exists anymore */
            break;
        }
        if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR)
        {
            prev_block_ptr = block_ptr;
        } /* Endif */
        block_size = block_ptr->BLOCKSIZE;
        if (block_size >= requested_size)
        {
            /* request fits into this block */
            next_block_size = block_size - requested_size;
            if (next_block_size >= LWMEM_MIN_MEMORY_STORAGE_SIZE)
            {
                /*
                 * The current block is big enough to split.
                 * into 2 blocks.... the part to be allocated is one block,
                 * and the rest remains as a free block on the free list.
                 */
                next_block_ptr = (LWMEM_BLOCK_STRUCT_PTR) (pointer) ((uchar_ptr) block_ptr + requested_size);
                /* Initialize the new physical block values */
                next_block_ptr->BLOCKSIZE = next_block_size;
                /* Link new block into the free list */
                next_block_ptr->POOL = mem_pool_ptr;
                next_block_ptr->U.NEXTBLOCK = block_ptr->U.NEXTBLOCK;
                block_ptr->U.NEXTBLOCK = (pointer) next_block_ptr;

                /* Modify the current block, to point to this newly created block*/
                block_ptr->BLOCKSIZE = requested_size;
            }
            else
            {
                /* Take the entire block */
                requested_size = block_size;
                next_block_ptr = block_ptr->U.NEXTBLOCK;
            } /* Endif */

            if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR)
            {
                /* At the head of the free list */
                mem_pool_ptr->POOL_FREE_LIST_PTR = next_block_ptr;
            }
            else
            {
                prev_block_ptr->U.NEXTBLOCK = next_block_ptr;
            } /* Endif */

            mem_pool_ptr->POOL_ALLOC_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_FREE_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_TEST_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_TEST2_PTR = mem_pool_ptr->POOL_ALLOC_START_PTR;
#if MQX_TASK_DESTRUCTION
            mem_pool_ptr->POOL_DESTROY_PTR = mem_pool_ptr->POOL_ALLOC_START_PTR;
#endif
            /* Indicate the block is in use */
            block_ptr->U.S.TASK_NUMBER = TASK_NUMBER_FROM_TASKID(td_ptr->TASK_ID);
            block_ptr->U.S.MEM_TYPE = 0;
            block_ptr->POOL = (_lwmem_pool_id) mem_pool_ptr;

            if ((uint_32) block_ptr > (uint_32) mem_pool_ptr->HIGHWATER)
            {
                mem_pool_ptr->HIGHWATER = block_ptr;
            }

            _int_enable();

            if (zero)
            {
                _mem_zero((pointer) ((uchar_ptr) block_ptr + sizeof(LWMEM_BLOCK_STRUCT)), requested_size
                                - sizeof(LWMEM_BLOCK_STRUCT));
            } /* Endif */
            return ((pointer) ((uchar_ptr) block_ptr + sizeof(LWMEM_BLOCK_STRUCT)));
        }
        else
        {
            prev_block_ptr = block_ptr;
            block_ptr = block_ptr->U.NEXTBLOCK;
        } /* Endif */
    } /* Endwhile */

    _int_enable();
    _task_set_error(MQX_OUT_OF_MEMORY);
    return (NULL);

} /* Endbody */

/*!
 * \private
 *
 * \brief Allocates a block of memory for a task from the free list.
 *
 * \param[in] requested_size The size of the memory block.
 * \param[in] requested_addr The address of the memory block.
 * \param[in] td_ptr         The owner TD.
 * \param[in] pool_id        Which pool to allocate from.
 * \param[in] zero           Zero the memory after it is allocated.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 */
pointer _lwmem_alloc_at_internal
(
    _mem_size      requested_size,
    pointer        requested_addr,
    TD_STRUCT_PTR  td_ptr,
    _lwmem_pool_id pool_id,
    boolean        zero
)
{ /* Body */
    LWMEM_BLOCK_STRUCT_PTR block_ptr, requested_block_ptr;
    LWMEM_BLOCK_STRUCT_PTR next_block_ptr;
    LWMEM_BLOCK_STRUCT_PTR prev_block_ptr = NULL;
    _mem_size              block_size;
    _mem_size              next_block_size, free_block_size;
    LWMEM_POOL_STRUCT_PTR  mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR) pool_id;

#if MQX_CHECK_VALIDITY
    if (mem_pool_ptr->VALID != LWMEM_POOL_VALID)
    {
        _task_set_error(MQX_LWMEM_POOL_INVALID);
        return (NULL);
    } /* Endif */
#endif

    /*
     * Adjust message size to allow for block management overhead
     * and force size to be aligned.
     */
    requested_size += (_mem_size) sizeof(LWMEM_BLOCK_STRUCT);
    if (requested_size < LWMEM_MIN_MEMORY_STORAGE_SIZE)
    {
        requested_size = LWMEM_MIN_MEMORY_STORAGE_SIZE;
    } /* Endif */

    _MEMORY_ALIGN_VAL_LARGER(requested_size);

    _int_disable();
    block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
    while (block_ptr != NULL)
    {
        /* Provide window for higher priority tasks */
        mem_pool_ptr->POOL_ALLOC_PTR = block_ptr;

        _int_enable();
        _int_disable();

        block_ptr = mem_pool_ptr->POOL_ALLOC_PTR;
        if (block_ptr == NULL)
        {
            /* The pool became full during preemption, no free block exists anymore */
            break;
        }
        if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR)
        {
            prev_block_ptr = block_ptr;
        }

        block_size = block_ptr->BLOCKSIZE;
        if ((uchar_ptr) block_ptr + LWMEM_MIN_MEMORY_STORAGE_SIZE <= (uchar_ptr) requested_addr
                        - sizeof(LWMEM_BLOCK_STRUCT) && (uchar_ptr) block_ptr + block_size
                        >= (uchar_ptr) requested_addr - sizeof(LWMEM_BLOCK_STRUCT) + requested_size)
        {
            /* request fits into this block */

            requested_block_ptr = (LWMEM_BLOCK_STRUCT_PTR)((uchar_ptr) requested_addr - sizeof(LWMEM_BLOCK_STRUCT));

            free_block_size = (uchar_ptr) requested_block_ptr - (uchar_ptr) block_ptr;
            /* requested block size is known */
            next_block_size = block_size - requested_size - free_block_size;

            /* free_block_size is always > LWMEM_MIN_MEMORY_STORAGE_SIZE */
            block_ptr->BLOCKSIZE = free_block_size;

            /* chek and prepare free block after requested block */
            if (next_block_size >= LWMEM_MIN_MEMORY_STORAGE_SIZE)
            {
                /*
                 * The current block is big enough to split.
                 * into 2 blocks.... the part to be allocated is one block,
                 * and the rest remains as a free block on the free list.
                 */
                next_block_ptr = (LWMEM_BLOCK_STRUCT_PTR) (pointer) ((uchar_ptr) requested_block_ptr + requested_size);
                /* Initialize the new physical block values */
                next_block_ptr->BLOCKSIZE = next_block_size;
                /* Link new block into the free list */
                next_block_ptr->POOL = mem_pool_ptr;
                next_block_ptr->U.NEXTBLOCK = block_ptr->U.NEXTBLOCK;
                block_ptr->U.NEXTBLOCK = (pointer) next_block_ptr;
            }
            else
            {
                /* Take the entire block */
                requested_size += next_block_size;
                next_block_ptr = block_ptr->U.NEXTBLOCK;
            }

            /* first free block always stay first */

            /* add next free block to list */
            //prev_block_ptr->U.NEXTBLOCK = next_block_ptr;

            /* Modify the allocated block information to point to next block */
            requested_block_ptr->BLOCKSIZE = requested_size;
            requested_block_ptr->U.NEXTBLOCK = next_block_ptr;

            mem_pool_ptr->POOL_ALLOC_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_FREE_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_TEST_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_TEST2_PTR = mem_pool_ptr->POOL_ALLOC_START_PTR;
#if MQX_TASK_DESTRUCTION
            mem_pool_ptr->POOL_DESTROY_PTR = mem_pool_ptr->POOL_ALLOC_START_PTR;
#endif
            /* Indicate the block is in use */
            requested_block_ptr->U.S.TASK_NUMBER = TASK_NUMBER_FROM_TASKID(td_ptr->TASK_ID);
            requested_block_ptr->U.S.MEM_TYPE = 0;
            requested_block_ptr->POOL = (_lwmem_pool_id) mem_pool_ptr;

            if ((uint_32) block_ptr > (uint_32) mem_pool_ptr->HIGHWATER)
            {
                mem_pool_ptr->HIGHWATER = block_ptr;
            }

            _int_enable();

            if (zero)
            {
                _mem_zero((pointer) requested_addr, requested_size - sizeof(LWMEM_BLOCK_STRUCT));
            } /* Endif */
            return requested_addr;
        }
        else
        {
            prev_block_ptr = block_ptr;
            block_ptr = block_ptr->U.NEXTBLOCK;
        } /* Endif */
    } /* Endwhile */

    _int_enable();
    _task_set_error(MQX_OUT_OF_MEMORY);
    return (NULL);
}

/*!
 * \private
 *
 * \brief Allocate an aligned block of memory for a task from the free list.
 *
 * \param[in] requested_size The size of the memory block.
 * \param[in] req_align      Requested alignement (e.g. 8 for alignement to 8 bytes).
 * \param[in] td_ptr         The owner TD.
 * \param[in] pool_id        Which pool to allocate from.
 * \param[in] zero           Zero the memory after it is allocated.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 */
pointer _lwmem_alloc_align_internal
(
    _mem_size      requested_size,
    _mem_size      req_align,
    TD_STRUCT_PTR  td_ptr,
    _lwmem_pool_id pool_id,
    boolean        zero
)
{ /* Body */
    LWMEM_BLOCK_STRUCT_PTR block_ptr;
    LWMEM_BLOCK_STRUCT_PTR next_block_ptr;
    LWMEM_BLOCK_STRUCT_PTR prev_block_ptr;
    _mem_size              block_size;
    _mem_size              next_block_size;
    _mem_size              shift;
    LWMEM_POOL_STRUCT_PTR  mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR) pool_id;

#if MQX_CHECK_VALIDITY
    if (mem_pool_ptr->VALID != LWMEM_POOL_VALID)
    {
        _task_set_error(MQX_LWMEM_POOL_INVALID);
        return (NULL);
    }
#endif

    /*
     * Adjust message size to allow for block management overhead
     * and force size to be aligned.
     */
    requested_size += (_mem_size) sizeof(LWMEM_BLOCK_STRUCT);
    if (requested_size < LWMEM_MIN_MEMORY_STORAGE_SIZE)
    {
        requested_size = LWMEM_MIN_MEMORY_STORAGE_SIZE;
    }

    _MEMORY_ALIGN_VAL_LARGER(requested_size);

    _int_disable();
    block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
    while (block_ptr != NULL)
    {
        /* Provide window for higher priority tasks */
        mem_pool_ptr->POOL_ALLOC_PTR = block_ptr;
        _int_enable();
        _int_disable();
        block_ptr = mem_pool_ptr->POOL_ALLOC_PTR;
        if (block_ptr == NULL)
        {
            /* The pool became full during preemption, no free block exists anymore */
            break;
        }
        if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR)
        {
            prev_block_ptr = block_ptr;
        }

        shift = (((_mem_size) block_ptr + sizeof(LWMEM_BLOCK_STRUCT) + req_align) & ~(req_align - 1))
                        - ((_mem_size) block_ptr + sizeof(LWMEM_BLOCK_STRUCT));

        if (shift < (2 * LWMEM_MIN_MEMORY_STORAGE_SIZE))
        {
            shift = (((_mem_size) block_ptr + sizeof(LWMEM_BLOCK_STRUCT) + (3 * LWMEM_MIN_MEMORY_STORAGE_SIZE)
                            + req_align) & ~(req_align - 1)) - ((_mem_size) block_ptr + sizeof(LWMEM_BLOCK_STRUCT));
        }

        block_size = block_ptr->BLOCKSIZE;
        if (block_size >= requested_size + shift)
        {
            /* request fits into this block */

            /* create new free block */
            prev_block_ptr = block_ptr;
            block_ptr = (LWMEM_BLOCK_STRUCT_PTR)(((uchar_ptr) block_ptr) + shift);
            prev_block_ptr->BLOCKSIZE = shift;
            block_ptr->U.NEXTBLOCK = prev_block_ptr->U.NEXTBLOCK;

            next_block_size = block_size - requested_size - shift;
            if (next_block_size >= LWMEM_MIN_MEMORY_STORAGE_SIZE)
            {
                /*
                 * The current block is big enough to split.
                 * into 2 blocks.... the part to be allocated is one block,
                 * and the rest remains as a free block on the free list.
                 */
                next_block_ptr = (LWMEM_BLOCK_STRUCT_PTR) (pointer) ((uchar_ptr) block_ptr + requested_size);
                /* Initialize the new physical block values */
                next_block_ptr->BLOCKSIZE = next_block_size;
                /* Link new block into the free list */
                next_block_ptr->POOL = mem_pool_ptr;
                next_block_ptr->U.NEXTBLOCK = block_ptr->U.NEXTBLOCK;
                block_ptr->U.NEXTBLOCK = (pointer) next_block_ptr;

                /* Modify the current block, to point to this newly created block*/
                block_ptr->BLOCKSIZE = requested_size;
            }
            else
            {
                /* Take the entire block */
                requested_size = block_size;
                next_block_ptr = block_ptr->U.NEXTBLOCK;
            } /* Endif */

            if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR)
            {
                /* At the head of the free list */
                mem_pool_ptr->POOL_FREE_LIST_PTR = next_block_ptr;
            }
            else
            {
                prev_block_ptr->U.NEXTBLOCK = next_block_ptr;
            } /* Endif */

            mem_pool_ptr->POOL_ALLOC_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_FREE_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_TEST_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
            mem_pool_ptr->POOL_TEST2_PTR = mem_pool_ptr->POOL_ALLOC_START_PTR;
#if MQX_TASK_DESTRUCTION
            mem_pool_ptr->POOL_DESTROY_PTR = mem_pool_ptr->POOL_ALLOC_START_PTR;
#endif
            /* Indicate the block is in use */
            block_ptr->U.S.TASK_NUMBER = TASK_NUMBER_FROM_TASKID(td_ptr->TASK_ID);
            block_ptr->U.S.MEM_TYPE = 0;
            block_ptr->POOL = (_lwmem_pool_id) mem_pool_ptr;

            if ((uint_32) block_ptr > (uint_32) mem_pool_ptr->HIGHWATER)
            {
                mem_pool_ptr->HIGHWATER = block_ptr;
            }

            _int_enable();

            if (zero)
            {
                _mem_zero((pointer) ((uchar_ptr) block_ptr + sizeof(LWMEM_BLOCK_STRUCT)), requested_size
                                - sizeof(LWMEM_BLOCK_STRUCT));
            }

            return ((pointer) ((uchar_ptr) block_ptr + sizeof(LWMEM_BLOCK_STRUCT)));
        }
        else
        {
            prev_block_ptr = block_ptr;
            block_ptr = block_ptr->U.NEXTBLOCK;
        }
    }

    _int_enable();
    _task_set_error(MQX_OUT_OF_MEMORY);
    return (NULL);
}

#if MQX_ENABLE_USER_MODE
/*!
 * \private
 *
 * \brief Allocates a block of memory.
 *
 * \param[in] requested_size The size of the memory block.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 */
pointer _usr_lwmem_alloc_internal
(
    _mem_size requested_size
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_usr_lwmem_alloc, requested_size);

    result = _lwmem_alloc_internal(requested_size, kernel_data->ACTIVE_PTR,
                    (_lwmem_pool_id)kernel_data->KD_USER_POOL, FALSE);

    _KLOGX2(KLOG_usr_lwmem_alloc, result);
    return(result);
}

#endif /* MQX_ENABLE_USER_MODE */

/*!
 * \brief Allocates a private block of lightweight memory block from the default
 * memory pool.
 *
 * The application must first set a value for the default lightweight memory pool
 * by calling _lwmem_set_default_pool().
 * \n The _lwmem_alloc functions allocate at least size single-addressable units;
 * the actual number might be greater. The start address of the block is aligned
 * so that tasks can use the returned pointer as a pointer to any data type without
 * causing an error.
 * \n Tasks cannot use lightweight memory blocks as messages. Tasks must use
 * _msg_alloc() or _msg_alloc_system() to allocate messages.
 * \n Only the task that owns a lightweight memory block that was allocated with
 * one of the following functions can free the block:
 * \li _lwmem_alloc()
 * \li _lwmem_alloc_zero()
 * \li _lwmem_alloc_at()
 *
 * \n Any task can free a lightweight memory block that is allocated with one of
 * the following functions:
 * \li _lwmem_alloc_system()
 * \li _lwmem_alloc_system_zero()
 *
 * \n Function types:
 * <table>
 *  <tr>
 *    <td></td>
 *    <td><b>Allocate this type of lighweight memory block form the default memory
 *    pool:</b></td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc()</b></td>
 *    <td>Private</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_system()</b></td>
 *    <td>System</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_system_zero()</b></td>
 *    <td>System (zero-filled)</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_zero()</b></td>
 *    <td>Private (zero-filled)</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_at()</b></td>
 *    <td>Private (start address defined)</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_align()</b></td>
 *    <td>Private (aligned) </td>
 *  </tr>
 * </table>
 *
 * \param[in] requested_size Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_get_size
 * \see _lwmem_set_default_pool
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc
(
    _mem_size requested_size
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_lwmem_alloc(requested_size);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwmem_alloc, requested_size);

    result = _lwmem_alloc_internal(requested_size, kernel_data->ACTIVE_PTR,
                    (_lwmem_pool_id) kernel_data->KERNEL_LWMEM_POOL, FALSE);

    _KLOGX2(KLOG_lwmem_alloc, result);
    return (result);
}

#if MQX_ENABLE_USER_MODE
/*!
 * /brief Allocates a private block of lightweight memory block from the default
 * memory pool.
 *
 * This function is an equivalent to the _lwmem_alloc() API call but it can be
 * executed from within the User task or other code running in the CPU User mode.
 * Parameters passed to this function by pointer are required to meet the memory
 * protection requirements as described in the parameter list below.
 *
 * \param[in] requested_size Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _usr_lwmem_alloc_from
 * \see _usr_lwmem_create_pool
 * \see _usr_lwmem_free
 */
pointer _usr_lwmem_alloc
(
    _mem_size requested_size
)
{
    MQX_API_CALL_PARAMS params =
    {   (uint_32)requested_size, 0, 0, 0, 0};
    return (pointer)_mqx_api_call(MQX_API_LWMEM_ALLOC, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

/*!
 * \brief Allocates a private block (with defined start address) of
 * lightweight memory block from the default memory pool.
 *
 * See Description of _lwmem_alloc() function.
 *
 * \param[in] requested_size Number of single-addressable units to allocate.
 * \param[in] requested_addr Start address of the memory block.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_get_size
 * \see _lwmem_set_default_pool
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_at
(
    _mem_size requested_size,
    pointer   requested_addr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwmem_alloc_at, requested_size);

    result = _lwmem_alloc_at_internal(requested_size, requested_addr, kernel_data->ACTIVE_PTR,
                    (_lwmem_pool_id) kernel_data->KERNEL_LWMEM_POOL, FALSE);

    _KLOGX2(KLOG_lwmem_alloc_at, result);
    return (result);
}

/*!
 * \brief Allocates an aligned block of lightweight memory block from the default
 * memory pool.
 *
 * See Description of _lwmem_alloc() function.
 *
 * \param[in] requested_size Number of single-addressable units to allocate.
 * \param[in] req_align      Align requested value.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_get_size
 * \see _lwmem_set_default_pool
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_align
(
    _mem_size requested_size,
    _mem_size req_align
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_lwmem_alloc_align, requested_size, req_align);

    result = _lwmem_alloc_align_internal(requested_size, req_align, kernel_data->ACTIVE_PTR,
                    (_lwmem_pool_id) kernel_data->KERNEL_LWMEM_POOL, FALSE);

    _KLOGX2(KLOG_lwmem_alloc_align, result);

    return (result);
}

/*!
 * \brief Gets default system lwmem pool.
 *
 * \return Pointer to default szstem lwmem pool.
 * \return NULL (failure)
 */
_lwmem_pool_id _lwmem_get_system_pool_id(void)
{
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    return (_lwmem_pool_id) kernel_data->KERNEL_LWMEM_POOL;
}

/*!
 * \brief Allocates a private block of lightweight memory block from the specified
 * memory pool.
 *
 * The function is similar to _lwmem_alloc(), _lwmem_alloc_system(),
 * _lwmem_alloc_system_zero() and _lwmem_alloc_zero() except that the application
 * does not call _lwmem_set_default_pool() first.
 * \n Only the task that owns a lightweight memory block that was allocated with
 * one of the following functions can free the block:
 * \li _lwmem_alloc_from()
 * \li _lwmem_alloc_zero_from()
 *
 * \n Any task can free a lightweight memory block that is allocated with one of
 * the following functions:
 * \li _lwmem_alloc_system_from()
 * \li _lwmem_alloc_system_zero_from()
 *
 * \n Function types:
 * <table>
 *  <tr>
 *    <td></td>
 *    <td><b>Allocate this type of lighweight memory block form the specified
 *    lightweight memory pool:</b></td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_from()</b></td>
 *    <td>Private</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_system_from()</b></td>
 *    <td>System</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_system_zero_from()</b></td>
 *    <td>System (zero-filled)</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_zero_from()</b></td>
 *    <td>Private (zero-filled)</td>
 *  </tr>
 *  <tr>
 *    <td><b>_lwmem_alloc_align_from()</b></td>
 *    <td>Private (aligned) </td>
 *  </tr>
 * </table>
 *
 * \param[in] pool_id        Lightweight memory pool from which to allocate the
 * lightweight memory block (from _lwmem_create_pool()).
 * \param[in] requested_size Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_from
(
    _lwmem_pool_id pool_id,
    _mem_size      requested_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_lwmem_alloc_from(pool_id, requested_size);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_lwmem_alloc_from, pool_id, requested_size);

    result = _lwmem_alloc_internal(requested_size, kernel_data->ACTIVE_PTR, pool_id, FALSE);

    _KLOGX2(KLOG_lwmem_alloc_from, result);
    return (result);
}

#if MQX_ENABLE_USER_MODE
/*!
 * \brief Allocates a private block of lightweight memory block from the specified
 * memory pool.
 *
 * This function is an equivalent to the _lwmem_alloc_from() API call but it can
 * be executed from within the User task or other code running in the CPU User
 * mode. Parameters passed to this function by pointer are required to meet the
 * memory protection requirements as described in the parameter list below.
 *
 * \param[in] pool_id        Read/write. Lightweight memory pool from which to
 * allocate the lightweight memory block (pool created with _usr_lwmem_create_pool()
 * or ordinary lightweight memory pool for which the user-mode access has been
 * enabled by calling _watchdog_create_component()).
 * \param[in] requested_size Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc_from
 * \see _watchdog_create_component
 * \see _usr_lwmem_alloc
 * \see _usr_lwmem_create_pool
 * \see _usr_lwmem_free
 */
pointer _usr_lwmem_alloc_from
(
    _lwmem_pool_id pool_id,
    _mem_size      requested_size
)
{
    MQX_API_CALL_PARAMS params =
    {   (uint_32)pool_id, (uint_32)requested_size, 0, 0, 0};
    return (pointer)_mqx_api_call(MQX_API_LWMEM_ALLOC_FROM, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

/*!
 * \brief Allocates a private block of lightweight memory block from the specified
 * memory pool.
 *
 * See Description of _lwmem_alloc_from() function.
 *
 * \param[in] pool_id        Lightweight memory pool from which to allocate the
 * lightweight memory block (from _lwmem_create_pool()).
 * \param[in] requested_size Number of single-addressable units to allocate.
 * \param[in] req_align      Align requested value.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_align_from
(
    _lwmem_pool_id pool_id,
    _mem_size      requested_size,
    _mem_size      req_align
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE4(KLOG_lwmem_alloc_align_from, pool_id, requested_size, req_align);

    result = _lwmem_alloc_align_internal(requested_size, req_align, kernel_data->ACTIVE_PTR, pool_id, FALSE);

    _KLOGX2(KLOG_lwmem_alloc_align_from, result);

    return (result);
}

/*!
 * \brief Allocates a private (zero-filled) block of lightweight memory block from
 * the default memory pool.
 *
 * See Description of _lwmem_alloc() function.
 *
 * \param[in] size Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_get_size
 * \see _lwmem_set_default_pool
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_zero
(
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwmem_alloc_zero, size);

    result
                    = _lwmem_alloc_internal(size, kernel_data->ACTIVE_PTR,
                                    (_lwmem_pool_id) kernel_data->KERNEL_LWMEM_POOL, TRUE);

    _KLOGX2(KLOG_lwmem_alloc_zero, result);
    return (result);

} /* Endbody */

/*!
 * \brief Allocates a private (zero-filled) block of lightweight memory block from the specified
 * memory pool.
 *
 * See Description of _lwmem_alloc_from() function.
 *
 * \param[in] pool_id        Lightweight memory pool from which to allocate the
 * lightweight memory block (from _lwmem_create_pool()).
 * \param[in] size Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_zero_from
(
    pointer   pool_id,
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_lwmem_alloc_zero_from, pool_id, size);

    result = _lwmem_alloc_internal(size, kernel_data->ACTIVE_PTR, pool_id, TRUE);

    _KLOGX2(KLOG_lwmem_alloc_zero_from, result);
    return (result);

} /* Endbody */

/*!
 * \brief Creates the lightweight memory pool from memory that is outside the
 * default memory pool.
 *
 * Tasks use the pool ID to allocate (variable-size) lightweight memory blocks
 * from the pool.
 *
 * \param[in] mem_pool_ptr Pointer to the definition of the pool.
 * \param[in] start        Start of the memory for the pool.
 * \param[in] size         Number of single-addressable units in the pool.
 *
 * \return Pool ID
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 */
_lwmem_pool_id _lwmem_create_pool
(
    LWMEM_POOL_STRUCT_PTR mem_pool_ptr,
    pointer               start,
    _mem_size             size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    LWMEM_BLOCK_STRUCT_PTR block_ptr;
    uchar_ptr              end;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_lwmem_create_pool(mem_pool_ptr, start, size);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_lwmem_create_pool, start, size);

    /* Set the end of memory (aligned) */
    end = (uchar_ptr) start + size;
    mem_pool_ptr->POOL_ALLOC_END_PTR = (pointer) _ALIGN_ADDR_TO_LOWER_MEM(end);

    /* Align the start of the pool */
    block_ptr = (LWMEM_BLOCK_STRUCT_PTR)_ALIGN_ADDR_TO_HIGHER_MEM(start);
    mem_pool_ptr->POOL_ALLOC_START_PTR = (pointer) block_ptr;
    mem_pool_ptr->HIGHWATER = (pointer) block_ptr;

    /* Set up the first block as an idle block */
    block_ptr->BLOCKSIZE = (uchar_ptr) mem_pool_ptr->POOL_ALLOC_END_PTR - (uchar_ptr) block_ptr;
    block_ptr->U.NEXTBLOCK = NULL;
    block_ptr->POOL = mem_pool_ptr;
    mem_pool_ptr->POOL_FREE_LIST_PTR = block_ptr;
    mem_pool_ptr->POOL_ALLOC_PTR = block_ptr;
    mem_pool_ptr->POOL_FREE_PTR = block_ptr;
    mem_pool_ptr->POOL_TEST_PTR = block_ptr;

    /* Protect the list of pools while adding new pool */
    _int_disable();
    if (kernel_data->LWMEM_POOLS.NEXT == NULL)
    {
        /* Initialize the light weight memory */
        _QUEUE_INIT(&kernel_data->LWMEM_POOLS, 0);
    } /* Endif */
    _QUEUE_ENQUEUE(&kernel_data->LWMEM_POOLS, &mem_pool_ptr->LINK);
    _int_enable();
    mem_pool_ptr->VALID = LWMEM_POOL_VALID;

    _KLOGX2(KLOG_lwmem_create_pool, mem_pool_ptr);
    return ((_lwmem_pool_id) mem_pool_ptr);

}

#if MQX_ENABLE_USER_MODE
/*!
 * \brief Sets lightweight memory pool access rights for User-mode tasks.
 *
 * This function sets access rights for a (lightweight) memory pool. Setting
 * correct access rights is important for tasks and other code running in the
 * User-mode. User-mode access to a memory pool whose access rights are not set
 * properly causes memory protection exception to be risen.
 *
 * \param[in] mem_pool_id Lightweight memory pool for access rights to set
 * (returned by _lwmem_create_pool()).
 * \param[in] access      Access rights to set. Possible values:
 * \li POOL_USER_RW_ACCESS
 * \li POOL_USER_RO_ACCESS
 * \li POOL_USER_NO_ACCESS
 *
 * \return MQX_OK
 */

_mqx_uint _mem_set_pool_access
(
    _lwmem_pool_id mem_pool_id,
    uint_32        access
)
{
    _mqx_uint res = MQX_LWMEM_POOL_INVALID;
    LWMEM_POOL_STRUCT_PTR mem_pool_ptr = (_lwmem_pool_id)mem_pool_id;

    if (LWMEM_POOL_VALID == mem_pool_ptr->VALID)
    {
        res = _psp_mpu_add_region(mem_pool_ptr->POOL_ALLOC_START_PTR, mem_pool_ptr->POOL_ALLOC_END_PTR, access);
    }

    return res;
}

/*!
 * \brief Creates the lightweight memory pool from memory that is outside the
 * default memory pool.
 *
 * This function is an equivalent to the _lwmem_create_pool() API call but
 * it can be executed from within the User task or other code running in the CPU
 * User mode. Parameters passed to this function by pointer are required to meet
 * the memory protection requirements as described in the parameter list below.
 *
 * \param[in] mem_pool_ptr Read/write. Pointer to the definition of the pool.
 * \param[in] start        Start of the memory for the pool.
 * \param[in] size         Number of single-addressable units in the pool.
 *
 * \return Pool ID
 *
 * \see _lwmem_create_pool
 * \see _usr_lwmem_alloc
 * \see _usr_lwmem_alloc_from
 * \see _usr_lwmem_free
 */
_lwmem_pool_id _usr_lwmem_create_pool
(
    LWMEM_POOL_STRUCT_PTR mem_pool_ptr,
    pointer               start,
    _mem_size             size
)
{
    MQX_API_CALL_PARAMS params =
    {   (uint_32)mem_pool_ptr, (uint_32)start, (uint_32)size, 0, 0};
    return (_lwmem_pool_id)_mqx_api_call(MQX_API_LWMEM_CREATE_POOL, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

/*!
 * \brief Initializes a memory storage pool. Will set task error code if error occurs.
 *
 * \param[in] start The start of the memory pool.
 * \param[in] size  The size of the memory pool.
 *
 * \return A handle to the memory pool.
 */
_lwmem_pool_id _lwmem_create_pool_mapped
(
    pointer   start,
    _mem_size size
)
{ /* Body */
    LWMEM_POOL_STRUCT_PTR mem_pool_ptr;

    mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR)_ALIGN_ADDR_TO_HIGHER_MEM(start);
    _mem_zero((pointer) mem_pool_ptr, (_mem_size) sizeof(LWMEM_POOL_STRUCT));

    start = (pointer) ((uchar_ptr) mem_pool_ptr + sizeof(LWMEM_POOL_STRUCT));
    _lwmem_create_pool(mem_pool_ptr, start, size - sizeof(LWMEM_POOL_STRUCT)); /* real pool size is decreased by pool header struct (must be - memory overwrite) */

    return ((_mem_pool_id) mem_pool_ptr);

} /* Endbody */

/*!
 * \brief Frees the lightweight memory block.
 *
 * If the block was allocated with one of the following functions, only the task
 * that owns the block can free it:
 * \li _lwmem_alloc()
 * \li _lwmem_alloc_from()
 * \li _lwmem_alloc_zero()
 * \li _lwmem_alloc_zero_from()
 *
 * \n Any task can free a block that was allocated with one of the following functions:
 * \li _lwmem_alloc_system()
 * \li _lwmem_alloc_system_from()
 * \li _lwmem_alloc_system_zero()
 * \li _lwmem_alloc_system_zero_from()
 *
 * \n The function also coalesces any free block found physically on either side
 * of the block being freed. If coalescing is not possible, then the block is
 * placed onto the free list.
 *
 * \param[in] mem_ptr Pointer to the block to free.
 *
 * \return MQX_OK
 * \return MQX_INVALID_POINTER (mem_ptr is NULL.)
 * \return MQX_LWMEM_POOL_INVALID (Pool that contains the block is not valid.)
 * \return MQX_NOT_RESOURCE_OWNER (If the block was allocated with _lwmem_alloc()
 * or _lwmem_alloc_zero(), only the task that allocated it can free part of it.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_INVALID_POINTER (mem_ptr is NULL.)
 * \li MQX_LWMEM_POOL_INVALID (Pool that contains the block is not valid.)
 * \li MQX_NOT_RESOURCE_OWNER (If the block was allocated with _lwmem_alloc() or
 * _lwmem_alloc_zero(), only the task that allocated it can free part of it.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_free
 * \see _task_set_error
 */
_mqx_uint _lwmem_free
(
    pointer mem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    LWMEM_BLOCK_STRUCT_PTR block_ptr;
    LWMEM_BLOCK_STRUCT_PTR free_list_ptr;
    LWMEM_POOL_STRUCT_PTR  mem_pool_ptr;
    boolean                insert;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_lwmem_free(mem_ptr);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_lwmem_free, mem_ptr);

#if MQX_CHECK_ERRORS
    /* Verify the passed in parameter */
    if (mem_ptr == NULL)
    {
        _task_set_error(MQX_INVALID_POINTER);
        _KLOGX2(KLOG_lwmem_free, MQX_INVALID_POINTER);
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    block_ptr = GET_LWMEMBLOCK_PTR(mem_ptr);
    mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR) block_ptr->POOL;
#if MQX_CHECK_VALIDITY
    if (mem_pool_ptr->VALID != LWMEM_POOL_VALID)
    {
        _task_set_error(MQX_LWMEM_POOL_INVALID);
        _KLOGX2(KLOG_lwmem_free, MQX_LWMEM_POOL_INVALID);
        return (MQX_LWMEM_POOL_INVALID);
    } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    /* Verify the passed in parameter */
    if (!((block_ptr->U.S.TASK_NUMBER == TASK_NUMBER_FROM_TASKID(kernel_data->ACTIVE_PTR->TASK_ID))
                    || (block_ptr->U.S.TASK_NUMBER == SYSTEM_TASK_NUMBER)))
    {
        _task_set_error(MQX_NOT_RESOURCE_OWNER);
        return (MQX_NOT_RESOURCE_OWNER);
    } /* Endif */
#endif

    _int_disable();
    free_list_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
    while (TRUE)
    {
        if ((mem_pool_ptr->POOL_FREE_LIST_PTR == NULL) || ((pointer) block_ptr < mem_pool_ptr->POOL_FREE_LIST_PTR))
        {
            free_list_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
            if (((uchar_ptr) block_ptr + block_ptr->BLOCKSIZE) == (uchar_ptr) free_list_ptr)
            {
                /* Join with the next block on the list */
                block_ptr->BLOCKSIZE += free_list_ptr->BLOCKSIZE;
                block_ptr->U.NEXTBLOCK = free_list_ptr->U.NEXTBLOCK;
                /* The merged block should have cleared header to assure failure at multiple freeing with the same pointer */
                _mem_zero(free_list_ptr, sizeof(LWMEM_BLOCK_STRUCT));
            }
            else
            {
                block_ptr->U.NEXTBLOCK = free_list_ptr;
            } /* Endif */
            mem_pool_ptr->POOL_FREE_LIST_PTR = block_ptr;
            insert = FALSE;
            break;
        }/* Endif */
        if (((pointer) block_ptr < free_list_ptr->U.NEXTBLOCK) || (free_list_ptr->U.NEXTBLOCK == NULL))
        {
            insert = TRUE;
            break;
        }/* Endif */
        free_list_ptr = free_list_ptr->U.NEXTBLOCK;
        /* Provide window for higher priority tasks */
        mem_pool_ptr->POOL_FREE_PTR = free_list_ptr;
        _int_enable();
        _int_disable();
        free_list_ptr = mem_pool_ptr->POOL_FREE_PTR;
    } /* Endwhile */

    if (insert)
    {
        /*
         * We are between the two blocks where we are to be inserted,
         * free_list_ptr is before block_ptr,
         * block_ptr may be at end of list.
         */
        if (((uchar_ptr) block_ptr + block_ptr->BLOCKSIZE) == free_list_ptr->U.NEXTBLOCK)
        {
            /* Join with the next block on the list */
            block_ptr->BLOCKSIZE += ((LWMEM_BLOCK_STRUCT_PTR)(free_list_ptr->U.NEXTBLOCK))->BLOCKSIZE;
            block_ptr->U.NEXTBLOCK = ((LWMEM_BLOCK_STRUCT_PTR)(free_list_ptr->U.NEXTBLOCK))->U.NEXTBLOCK;
            /* The merged block should have cleared header to assure failure at multiple freeing with the same pointer */
            _mem_zero(free_list_ptr->U.NEXTBLOCK, sizeof(LWMEM_BLOCK_STRUCT));
        }
        else
        {
            /* this block is to be inserted */
            block_ptr->U.NEXTBLOCK = free_list_ptr->U.NEXTBLOCK;
        } /* Endif */

        if (((uchar_ptr) free_list_ptr + free_list_ptr->BLOCKSIZE == (uchar_ptr) block_ptr))
        {
            free_list_ptr->BLOCKSIZE += block_ptr->BLOCKSIZE;
            free_list_ptr->U.NEXTBLOCK = block_ptr->U.NEXTBLOCK;
            /* The merged block should have cleared header to assure failure at multiple freeing with the same pointer */
            _mem_zero(block_ptr, sizeof(LWMEM_BLOCK_STRUCT));
        }
        else
        {
            free_list_ptr->U.NEXTBLOCK = block_ptr;
        } /* Endif */

    } /* Endif */

    mem_pool_ptr->POOL_ALLOC_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
    mem_pool_ptr->POOL_FREE_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
    mem_pool_ptr->POOL_TEST_PTR = mem_pool_ptr->POOL_FREE_LIST_PTR;
    mem_pool_ptr->POOL_TEST2_PTR = mem_pool_ptr->POOL_ALLOC_START_PTR;
#if MQX_TASK_DESTRUCTION
    mem_pool_ptr->POOL_DESTROY_PTR = mem_pool_ptr->POOL_ALLOC_START_PTR;
#endif
    _int_enable();

    _KLOGX2(KLOG_lwmem_free, MQX_OK);
    return (MQX_OK);

} /* Endbody */

#if MQX_ENABLE_USER_MODE
/*!
 * \brief Frees the given block of memory.
 *
 * This function is an equivalent to the _lwmem_free() API call but it can be
 * executed from within the User task or other code running in the CPU User mode.
 * Parameters passed to this function by pointer are required to meet the memory
 * protection requirements as described in the parameter list below.
 *
 * \param[in] mem_ptr Pointer to the block to free.
 *
 * \return MQX_OK
 * \return MQX_INVALID_POINTER (mem_ptr is NULL.)
 * \return MQX_LWMEM_POOL_INVALID (Pool that contains the block is not valid.)
 * \return MQX_NOT_RESOURCE_OWNER (If the block was allocated with _lwmem_alloc()
 * or _lwmem_alloc_zero(), only the task that allocated it can free part of it.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_INVALID_POINTER (mem_ptr is NULL.)
 * \li MQX_LWMEM_POOL_INVALID (Pool that contains the block is not valid.)
 * \li MQX_NOT_RESOURCE_OWNER (If the block was allocated with _lwmem_alloc() or
 * _lwmem_alloc_zero(), only the task that allocated it can free part of it.)
 *
 * \see _lwmem_free
 * \see _usr_lwmem_alloc
 * \see _usr_lwmem_alloc_from
 * \see _usr_lwmem_create_pool
 */
_mqx_uint _usr_lwmem_free
(
    pointer mem_ptr
)
{
    MQX_API_CALL_PARAMS params =
    {   (uint_32)mem_ptr, 0, 0, 0, 0};
    return _mqx_api_call(MQX_API_LWMEM_FREE, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

/*!
 * \brief Gets the size of unallocated (free) memory.
 *
 * \return Size of free memory (success).
 * \return 0 (failure)
 *
 * \warning On failure, calls _task_set_error() to set the following task error code:
 * \li MQX_LWMEM_POOL_INVALID (Pool that contains the block is not valid.)
 */
_mem_size _lwmem_get_free()
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mem_size              result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE1(KLOG_lwmem_get_free);

    result = _lwmem_get_free_internal((_lwmem_pool_id) kernel_data->KERNEL_LWMEM_POOL);

    _KLOGX2(KLOG_lwmem_get_free, result);
    return (result);

} /* Endbody */

/*!
 * \brief Gets the size of unallocated (free) memory from a specified pool.
 *
 * \param[in] pool_id The pool to get free size from.
 *
 * \return Size of free memory (success).
 * \return 0 (failure)
 *
 * \warning On failure, calls _task_set_error() to set the following task error code:
 * \li MQX_LWMEM_POOL_INVALID (Pool that contains the block is not valid.)
 */
_mem_size _lwmem_get_free_from
(
    pointer pool_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mem_size              result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwmem_get_free_from, pool_id);

    result = _lwmem_get_free_internal((_lwmem_pool_id) pool_id);

    _KLOGX2(KLOG_lwmem_get_free_from, result);
    return (result);

} /* Endbody */

/*!
 * \private
 *
 * \brief Returns summarized size of free memory blocks in the pool.
 *
 * \param[in] pool_id Which pool to get free size from.
 *
 * \return Size of free memory (success).
 * \return 0 (failure)
 *
 * \warning On failure, calls _task_set_error() to set the following task error code:
 * \li MQX_LWMEM_POOL_INVALID (Pool that contains the block is not valid.)
 */
_mem_size _lwmem_get_free_internal
(
    _lwmem_pool_id pool_id
)
{ /* Body */
    LWMEM_BLOCK_STRUCT_PTR block_ptr;
    _mem_size              total_size = 0;
    LWMEM_POOL_STRUCT_PTR  mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR) pool_id;

#if MQX_CHECK_VALIDITY
    if (mem_pool_ptr->VALID != LWMEM_POOL_VALID)
    {
        _task_set_error(MQX_LWMEM_POOL_INVALID);
        return (0);
    } /* Endif */
#endif

    _int_disable();
    block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
    while (block_ptr != NULL)
    {
        /* Provide window for higher priority tasks */
        mem_pool_ptr->POOL_ALLOC_PTR = block_ptr;
        _int_enable();
        _int_disable();
        block_ptr = mem_pool_ptr->POOL_ALLOC_PTR;
        if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR)
        {
            total_size = 0; /* some task with higher priority did reset our loop pointer */
        } /* Endif */
        total_size += block_ptr->BLOCKSIZE;
        block_ptr = block_ptr->U.NEXTBLOCK;
    } /* Endwhile */

    _int_enable();
    return (total_size);
} /* Endbody */

/*!
 * \brief Allocates a system block of lightweight memory block from the specified
 * memory pool that is available system-wide.
 *
 * See Description of _lwmem_alloc_from() function.
 *
 * \param[in] pool_id Lightweight memory pool from which to allocate the
 * lightweight memory block (from _lwmem_create_pool()).
 * \param[in] size    Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_system_from
(
    _lwmem_pool_id pool_id,
    _mem_size      size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwmem_alloc_system_from, size);

    result = _lwmem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), pool_id, FALSE);

    _KLOGX2(KLOG_lwmem_alloc_system_from, result);
    return (result);

} /* Endbody */

/*!
 * \brief Allocates a system block of lightweight memory block from the default
 * memory pool that is available system-wide.
 *
 * See Description of _lwmem_alloc() function.
 *
 * \param[in] size Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_get_size
 * \see _lwmem_set_default_pool
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_system
(
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwmem_alloc_system, size);

    result = _lwmem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), (_lwmem_pool_id) kernel_data->KERNEL_LWMEM_POOL,
                    FALSE);

    _KLOGX2(KLOG_lwmem_alloc_system, result);
    return (result);

} /* Endbody */

/*!
 * \private
 *
 * \brief Initializes MQX to use the lwmem manager.
 *
 * \return MQX_OK
 */
_mqx_uint _lwmem_init_internal(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    LWMEM_POOL_STRUCT_PTR  lwmem_pool_ptr;
    uchar_ptr              start;

    _GET_KERNEL_DATA(kernel_data);

    /*
     * Move the MQX memory pool pointer past the end of kernel data.
     */
    start = (pointer) ((uchar_ptr) kernel_data + sizeof(KERNEL_DATA_STRUCT));
    lwmem_pool_ptr = (LWMEM_POOL_STRUCT_PTR) start;
    kernel_data->KERNEL_LWMEM_POOL = lwmem_pool_ptr;

    start = (pointer) ((uchar_ptr) start + sizeof(LWMEM_POOL_STRUCT));

    _lwmem_create_pool(lwmem_pool_ptr, start, (uchar_ptr) kernel_data->INIT.END_OF_KERNEL_MEMORY - (uchar_ptr) start);

    return (MQX_OK);

} /* Endbody */

/*!
 * \private
 *
 * \brief Find the next block associated with the specified Task.
 *
 * \param[in] td_ptr       The TD whose blocks are being looked for.
 * \param[in] in_block_ptr The block last obtained.
 *
 * \return Pointer to the next block.
 * \return NULL (failure)
 */
pointer _lwmem_get_next_block_internal
(
    TD_STRUCT_PTR td_ptr,
    pointer       in_block_ptr
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    LWMEM_POOL_STRUCT_PTR  lwmem_pool_ptr;
    LWMEM_BLOCK_STRUCT_PTR block_ptr = in_block_ptr;
    LWMEM_BLOCK_STRUCT_PTR free_ptr;

    _GET_KERNEL_DATA(kernel_data);

    if (block_ptr == NULL)
    {
        /* first item, start on first item in first pool */
        lwmem_pool_ptr = kernel_data->KERNEL_LWMEM_POOL;
        block_ptr = lwmem_pool_ptr->POOL_ALLOC_START_PTR;
    }
    else
    {
        /* continued, get lwmem pool from provided in_block_ptr */
        block_ptr = GET_LWMEMBLOCK_PTR(in_block_ptr);
        lwmem_pool_ptr = block_ptr->POOL;

        block_ptr = (LWMEM_BLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + block_ptr->BLOCKSIZE);
    }

    _int_disable();

    do
    {
        free_ptr = lwmem_pool_ptr->POOL_FREE_LIST_PTR;

        while ((uchar_ptr) block_ptr < (uchar_ptr) lwmem_pool_ptr->POOL_ALLOC_END_PTR)
        {
            if (block_ptr->U.S.TASK_NUMBER == TASK_NUMBER_FROM_TASKID(td_ptr->TASK_ID))
            {
                /* check for block is not free block */
                while (free_ptr && free_ptr < block_ptr)
                {
                    free_ptr = free_ptr->U.NEXTBLOCK;
                }

                if (free_ptr != block_ptr)
                {
                    /* This block is owned by the target task and it's not free block*/
                    _int_enable();

                    return ((pointer) ((uchar_ptr) block_ptr + sizeof(LWMEM_BLOCK_STRUCT)));
                }
            }
            block_ptr = (LWMEM_BLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + block_ptr->BLOCKSIZE);
        }

        /* continue in next lwmem pool */
        lwmem_pool_ptr = (LWMEM_POOL_STRUCT_PTR)(lwmem_pool_ptr->LINK.NEXT);
        block_ptr = lwmem_pool_ptr->POOL_ALLOC_START_PTR;
    } while (lwmem_pool_ptr != kernel_data->KERNEL_LWMEM_POOL); /* repeat until processed lwmem pool is not first pool (pool list is circular list) */

    _int_enable();

    return (NULL);
}

/*!
 * \brief Sets the value of the default lightweight memory pool.
 *
 * Because MQX allocates lightweight memory blocks from the default lightweight
 * memory pool when an application calls _lwmem_alloc(), _lwmem_alloc_system(),
 * _lwmem_alloc_system_zero() or _lwmem_alloc_zero(), the application must first
 * call _lwmem_set_default_pool().
 *
 * \param[in] pool_id New pool ID.
 *
 * \return Previous pool ID.
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwsem_destroy
 * \see _lwsem_post
 * \see _lwsem_test
 * \see _lwsem_wait
 * \see _lwsem_wait_for
 * \see _lwsem_wait_ticks
 * \see _lwsem_wait_until
 */
_lwmem_pool_id _lwmem_set_default_pool
(
    _lwmem_pool_id pool_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _lwmem_pool_id         old_pool_id;

    _GET_KERNEL_DATA(kernel_data);

    old_pool_id = kernel_data->KERNEL_LWMEM_POOL;
    kernel_data->KERNEL_LWMEM_POOL = pool_id;
    return (old_pool_id);

} /* Endbody */

/*!
 * \brief Gets the size of the lightweight memory block.
 *
 * The size is the actual size of the block and might be larger than the size
 * that a task requested.
 *
 * \param[in] mem_ptr Pointer to the lightweight memory block.
 *
 * \return Number of single-addressable units in the block (success).
 * \return 0 (failure)
 */
_mem_size _lwmem_get_size
(
    pointer mem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    LWMEM_BLOCK_STRUCT_PTR block_ptr;

    _GET_KERNEL_DATA(kernel_data);
#if MQX_CHECK_ERRORS
    if (mem_ptr == NULL)
    {
        _task_set_error(MQX_INVALID_POINTER);
        return (0);
    } /* Endif */
#endif

    /* Compute the start of the block  */
    block_ptr = GET_LWMEMBLOCK_PTR(mem_ptr);
    /* The size includes the block overhead, which the user is not
     * interested in. If the size is less than the overhead,
     * then there is a bad block or bad block pointer.
     */
#if MQX_CHECK_ERRORS
    if (block_ptr->BLOCKSIZE <= (_mem_size) sizeof(LWMEM_BLOCK_STRUCT))
    {
        _task_set_error(MQX_INVALID_POINTER);
        return (0);
    } /* Endif */
#endif

    return (block_ptr->BLOCKSIZE - (_mem_size) sizeof(LWMEM_BLOCK_STRUCT));

} /* Endbody */

/* Move to standalone file */

#if MQX_ALLOW_TYPED_MEMORY
/*!
 * \brief Gets type of the specified block.
 *
 * \param[in] mem_ptr Pointer to the lightweight memory block.
 *
 * \return Type of memory block.
 */
_mem_type _lwmem_get_type
(
    pointer mem_ptr
)
{
    LWMEM_BLOCK_STRUCT_PTR block_ptr;

    block_ptr = GET_LWMEMBLOCK_PTR(mem_ptr);
    return block_ptr->U.S.MEM_TYPE;
}

/*!
 * \brief Sets the type of the specified block.
 *
 * \param[in] mem_ptr  Pointer to the lightweight memory block.
 * \param[in] mem_type Type of lightweight memory block to set.
 *
 * \return TRUE (success) or FALSE (failure: mem_ptr ic NULL).
 */
boolean _lwmem_set_type
(
    pointer   mem_ptr,
    _mem_type mem_type
)
{
    LWMEM_BLOCK_STRUCT_PTR block_ptr;

    if (mem_ptr != NULL)
    {
        block_ptr = GET_LWMEMBLOCK_PTR(mem_ptr);
        block_ptr->U.S.MEM_TYPE = mem_type;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
#endif

/*!
 * \brief Sets the type of the specified block.
 *
 * \return Highest size of used memory.
 */
pointer _lwmem_get_highwater(void)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    return (((LWMEM_POOL_STRUCT_PTR)(kernel_data->KERNEL_LWMEM_POOL))->HIGHWATER);

}

/*!
 * \brief Tests all lightweight memory for errors.
 *
 * The function checks the checksums in the headers of all lightweight memory blocks.
 * \n The function can be called by only one task at a time because it keeps
 * state-in-progress variables that MQX controls. This mechanism lets other tasks
 * allocate and free lightweight memory while _lwmem_test() runs.
 *
 * \param[out] pool_error_ptr  Pointer to the pool in error (points to NULL if no
 * error was found).
 * \param[out] block_error_ptr Pointer to the block in error (points to NULL if
 * no error was found).
 *
 * \return MQX_OK
 * \return MQX_LWMEM_POOL_INVALID (Lightweight memory pool is corrupted.)
 * \return MQX_CORRUPT_STORAGE_POOL (A memory pool pointer is not correct.)
 * \return MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \return MQX_CORRUPT_QUEUE (An error was found.)
 *
 * \warning Can be called by only one task at a time (see description).
 * \warning Disables and enables interrupts.
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 */
_mqx_uint _lwmem_test
(
    _lwmem_pool_id _PTR_ pool_error_ptr,
    pointer _PTR_        block_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    LWMEM_POOL_STRUCT_PTR  mem_pool_ptr;
    LWMEM_BLOCK_STRUCT_PTR queue_ptr = NULL;
    LWMEM_BLOCK_STRUCT_PTR block_ptr;
    _mqx_uint              i;
    _mqx_uint              result;

    _GET_KERNEL_DATA(kernel_data);

    /*
     * It is not considered an error if the lwmem component has not been
     * created yet
     */
    if (kernel_data->LWMEM_POOLS.NEXT == NULL)
    {
        return (MQX_OK);
    } /* Endif */

    result = _queue_test(&kernel_data->LWMEM_POOLS, pool_error_ptr);
    if (result != MQX_OK)
    {
        return (result);
    } /* Endif */
    _int_disable();
    i = _QUEUE_GET_SIZE(&kernel_data->LWMEM_POOLS);
    mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR) (pointer) kernel_data->LWMEM_POOLS.NEXT;
    while (i--)
    {
        if (mem_pool_ptr->VALID != LWMEM_POOL_VALID)
        {
            _int_enable();
            *pool_error_ptr = mem_pool_ptr;
            *block_error_ptr = NULL;
            return (MQX_LWMEM_POOL_INVALID);
        } /* Endif */

        /* Make sure pool is ok */
        block_ptr = mem_pool_ptr->POOL_ALLOC_START_PTR;
        while ((uchar_ptr) block_ptr < (uchar_ptr) mem_pool_ptr->POOL_ALLOC_END_PTR)
        {
            mem_pool_ptr->POOL_TEST2_PTR = block_ptr;
            _int_enable();
            _int_disable();
            block_ptr = mem_pool_ptr->POOL_TEST2_PTR;
            if (block_ptr->POOL != mem_pool_ptr)
            {
                _int_enable();
                *pool_error_ptr = mem_pool_ptr;
                *block_error_ptr = (pointer) block_ptr;
                return (MQX_CORRUPT_STORAGE_POOL);
            } /* Endif */
            block_ptr = (LWMEM_BLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + block_ptr->BLOCKSIZE);
        } /* Endwhile */

        /* Make sure Freelist is ok */
        block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
        while (block_ptr)
        {
            /* Provide window for higher priority tasks */
            mem_pool_ptr->POOL_TEST_PTR = block_ptr;
            _int_enable();
            _int_disable();
            block_ptr = mem_pool_ptr->POOL_TEST_PTR;
            if (((pointer) block_ptr < mem_pool_ptr->POOL_ALLOC_START_PTR) || ((pointer) block_ptr
                            > mem_pool_ptr->POOL_ALLOC_END_PTR) || (block_ptr->POOL != mem_pool_ptr)
                            || (block_ptr->U.NEXTBLOCK && (block_ptr->U.NEXTBLOCK <= (pointer) ((uchar_ptr) block_ptr
                                            + block_ptr->BLOCKSIZE))))
            {
                /* This block is in error */
                _int_enable();
                *pool_error_ptr = mem_pool_ptr;
                *block_error_ptr = block_ptr;
                return (MQX_CORRUPT_STORAGE_POOL_FREE_LIST);
            } /* Endif */
            block_ptr = block_ptr->U.NEXTBLOCK;
        } /* Endwhile */
        mem_pool_ptr = (pointer) mem_pool_ptr->LINK.NEXT;
    } /* Endwhile */
    _int_enable();

    *pool_error_ptr = NULL;
    *block_error_ptr = NULL;
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Transfers the ownership of the lightweight memory block from one task
 * to another.
 *
 * \param[in] memory_ptr The memory block whose ownership is to be transferred.
 * \param[in] source_id  Task ID of the current owner.
 * \param[in] target_id  Task ID of the new owner.
 *
 * \return MQX_OK
 * \return MQX_INVALID_POINTER (Block_ptr is NULL.)
 * \return MQX_INVALID_TASK_ID (Source or target does not represent a valid task.)
 * \return MQX_NOT_RESOURCE_OWNER (Block is not a resource of the task represented
 * by source.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_INVALID_POINTER (Block_ptr is NULL.)
 * \li MQX_INVALID_TASK_ID (Source or target does not represent a valid task.)
 * \li MQX_NOT_RESOURCE_OWNER (Block is not a resource of the task represented
 * by source.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _task_set_error
 */
_mqx_uint _lwmem_transfer
(
    pointer  memory_ptr,
    _task_id source_id,
    _task_id target_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    LWMEM_BLOCK_STRUCT_PTR block_ptr;
    TD_STRUCT_PTR          source_td;
    TD_STRUCT_PTR          target_td;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_lwmem_transfer, memory_ptr, source_id, target_id);

#if MQX_CHECK_ERRORS
    if (memory_ptr == NULL)
    {
        _task_set_error(MQX_INVALID_POINTER);
        _KLOGX2(KLOG_lwmem_transfer, MQX_INVALID_POINTER);
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    /* Verify the block */
    block_ptr = GET_LWMEMBLOCK_PTR(memory_ptr);

    source_td = (TD_STRUCT_PTR) _task_get_td(source_id);
    target_td = (TD_STRUCT_PTR) _task_get_td(target_id);
#if MQX_CHECK_ERRORS
    if ((source_td == NULL) || (target_td == NULL))
    {
        _task_set_error(MQX_INVALID_TASK_ID);
        _KLOGX2(KLOG_lwmem_transfer, MQX_INVALID_TASK_ID);
        return (MQX_INVALID_TASK_ID);
    } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    if (block_ptr->U.S.TASK_NUMBER != TASK_NUMBER_FROM_TASKID(source_td->TASK_ID))
    {
        _task_set_error(MQX_NOT_RESOURCE_OWNER);
        return (MQX_NOT_RESOURCE_OWNER);
    } /* Endif */
#endif

    block_ptr->U.S.TASK_NUMBER = TASK_NUMBER_FROM_TASKID(target_td->TASK_ID);

    _KLOGX2(KLOG_lwmem_transfer, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \private
 *
 * \brief This function transfers the ownership of a block of memory from an owner
 * task to another task.
 *
 * \param[in] memory_ptr The address of the USER_AREA in the memory block to transfer.
 * \param[in] target_td  The target task descriptor.
 */
void _lwmem_transfer_internal
(
    pointer       memory_ptr,
    TD_STRUCT_PTR target_td
)
{ /* Body */
    LWMEM_BLOCK_STRUCT_PTR block_ptr;

    /* Verify the block */
    block_ptr = GET_LWMEMBLOCK_PTR(memory_ptr);
    block_ptr->U.S.TASK_NUMBER = TASK_NUMBER_FROM_TASKID(target_td->TASK_ID);

} /* Endbody */

/*!
 * \private
 *
 * \brief This routine transfers the ownership of a block of memory from an owner
 * task to another task.
 *
 * \param[in] memory_ptr The memory block whose ownership is to be transferred.
 * \param[in] source_td  The source (owner) TD.
 * \param[in] target_td  The target (new owner) TD.
 *
 * \return MQX_OK
 */
_mqx_uint _lwmem_transfer_td_internal
(
    pointer       memory_ptr,
    TD_STRUCT_PTR source_td,
    TD_STRUCT_PTR target_td
)
{ /* Body */
    LWMEM_BLOCK_STRUCT_PTR block_ptr;

    block_ptr = GET_LWMEMBLOCK_PTR(memory_ptr);
    block_ptr->U.S.TASK_NUMBER = TASK_NUMBER_FROM_TASKID(target_td->TASK_ID);

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Allocates a system(zero-filled) block of lightweight memory block from
 * the specified memory pool.
 *
 * See Description of _lwmem_alloc_from() function.
 *
 * \param[in] pool_id        Lightweight memory pool from which to allocate the
 * lightweight memory block (from _lwmem_create_pool()).
 * \param[in] size           Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_system_zero
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_system_zero_from
(
    _lwmem_pool_id pool_id,
    _mem_size      size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwmem_alloc_system_zero_from, size);

    result = _lwmem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), pool_id, TRUE);

    _KLOGX2(KLOG_lwmem_alloc_system_zero_from, result);
    return (result);

} /* Endbody */

/*!
 * \brief Allocates a system (zero-filled) block of lightweight memory block from
 * the default memory pool.
 *
 * See Description of _lwmem_alloc() function.
 *
 * \param[in] size Number of single-addressable units to allocate.
 *
 * \return Pointer to the lightweight memory block (success).
 * \return NULL (Failure: see Task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following task
 * error codes:
 * \li MQX_LWMEM_POOL_INVALID (Memory pool to allocate from is invalid.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 *
 * \see _lwmem_alloc
 * \see _lwmem_alloc_system
 * \see _lwmem_alloc_zero
 * \see _lwmem_alloc_at
 * \see _lwmem_alloc_align
 * \see _lwmem_alloc_align_from
 * \see _lwmem_alloc_from
 * \see _lwmem_alloc_system_from
 * \see _lwmem_alloc_system_zero_from
 * \see _lwmem_alloc_zero_from
 * \see _lwmem_create_pool
 * \see _lwmem_free
 * \see _lwmem_get_size
 * \see _lwmem_set_default_pool
 * \see _lwmem_transfer
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _lwmem_alloc_system_zero
(
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_lwmem_alloc_system_zero, size);

    result = _lwmem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), (_lwmem_pool_id) kernel_data->KERNEL_LWMEM_POOL,
                    TRUE);

    _KLOGX2(KLOG_lwmem_alloc_system_zero, result);
    return (result);

} /* Endbody */

#endif /* MQX_USE_LWMEM */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/cdc/usb_cdc_pstn.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_cdc_pstn.c$
* $Version : 3.8.5.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
* @brief The file contains USB CDC_PSTN module implimentation.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
 #include "usb_stack_config.h"
 #if CDC_CONFIG 
 #include "usb_cdc_pstn.h"
 
 /*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/
#define MAX_EXPECTED_COMMAND_SIZE           (76)
/* this is the max observed command size we get on control endpoint --
   we are allocating memory for command at initialization, instead of 
   dynamically allocating it when command is received, to avoid memory 
   fragmentation */
#define MAX_EXPECTED_RESPONSE_SIZE          (RESPONSE_RNDIS_QUERY_MSG_SIZE + \
                                             (NUM_OIDS_SUPPORTED << 2))
    /* left shifted by 2 to have effect of mutiplication by 4 i.e. size of uint_32 */ 
/*****************************************************************************
 * Global Functions Prototypes
 *****************************************************************************/

/****************************************************************************
 * Global Variables
 ****************************************************************************/              

/*****************************************************************************
 * Local Types - None
 *****************************************************************************/
 
/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
 
/*****************************************************************************
 * Local Variables 
 *****************************************************************************/                                                                                                                               
uint_8 g_serial_state_buf[NOTIF_PACKET_SIZE+UART_BITMAP_SIZE] = 
    { NOTIF_REQUEST_TYPE,SERIAL_STATE_NOTIF,
      0x00,0x00,/*wValue*/
      0x00,0x00,/*interface - modifies*/
      UART_BITMAP_SIZE,0x00,/* wlength*/
      0x00,0x00 /*data initialized - modifies*/
    };/*uart bitmap*/

uint_8 g_response_available_data[NOTIF_PACKET_SIZE] =
{
    NOTIF_REQUEST_TYPE, RESPONSE_AVAIL_NOTIF,
    0x00, 0x00,/*wValue*/
    0x00,0x00,/*interface - modifies*/
    0x00,0x00,/* wlength*/
};

#if RNDIS_SUPPORT
    static uint_32 g_list_supp_oid[NUM_OIDS_SUPPORTED] = 
    {
        OID_GEN_SUPPORTED_LIST,             
        OID_GEN_HARDWARE_STATUS,                 
        OID_GEN_MEDIA_SUPPORTED,                 
        OID_GEN_MEDIA_IN_USE,                
        OID_GEN_MAXIMUM_FRAME_SIZE,          
        OID_GEN_LINK_SPEED,                  
        OID_GEN_TRANSMIT_BLOCK_SIZE,
        OID_GEN_RECEIVE_BLOCK_SIZE,          
        OID_GEN_VENDOR_ID,                   
        OID_GEN_VENDOR_DESCRIPTION,
        OID_GEN_CURRENT_PACKET_FILTER,       
        OID_GEN_MAXIMUM_TOTAL_SIZE,          
        OID_GEN_MEDIA_CONNECT_STATUS,       
        OID_GEN_XMIT_OK,                      
        OID_GEN_RCV_OK,                    
        OID_GEN_XMIT_ERROR,               
        OID_GEN_RCV_ERROR,                 
        OID_GEN_RCV_NO_BUFFER,              
        OID_802_3_PERMANENT_ADDRESS,          
        OID_802_3_CURRENT_ADDRESS,         
        OID_802_3_MULTICAST_LIST,        
        OID_802_3_MAXIMUM_LIST_SIZE,          
        OID_802_3_RCV_ERROR_ALIGNMENT,     
        OID_802_3_XMIT_ONE_COLLISION,    
        OID_802_3_XMIT_MORE_COLLISIONS    
    };
    #define VENDOR_INFO_SIZE        (16)
    static uchar g_vendor_info[VENDOR_INFO_SIZE] = " FSL RNDIS PORT ";
#endif
    
 /*****************************************************************************
 * Local Functions
 *****************************************************************************/

/*****************************************************************************
 * Global Functions
 *****************************************************************************/

/**************************************************************************//*!
 *
 * @name  USB_Pstn_Init
 *
 * @brief The funtion initializes the Pstn Module 
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param class_callback:       event callback 
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
uint_8 USB_Pstn_Init
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_CLASS_CALLBACK_STRUCT_PTR pstn_cb
) 
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr = NULL;
    uint_8 error=USB_OK;   
    /* initialize the Global Variable Structure */
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)USB_mem_alloc_zero(sizeof(CDC_PSTN_STRUCT));
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("cdc_pstn_ptr malloc failed: USB_Pstn_Init\n");
        #endif  
        return USBERR_ALLOC;
    }
    
    USB_mem_zero(cdc_pstn_ptr, sizeof(CDC_PSTN_STRUCT));
    USB_mem_copy(g_serial_state_buf,
        cdc_pstn_ptr->serial_state_buf,(NOTIF_PACKET_SIZE+UART_BITMAP_SIZE));
 
    /* save input parameters */
    cdc_pstn_ptr->pstn_callback.callback = pstn_cb->callback;
    cdc_pstn_ptr->pstn_callback.arg = (void *)pstn_cb->arg;
    
    cdc_obj_ptr->pstn_obj_ptr = (void *)cdc_pstn_ptr;
    
    #if RNDIS_SUPPORT
        /* Initially RNDIS is in Uninitialized state */
        cdc_pstn_ptr->rndis_device_state = RNDIS_UNINITIALIZED;
        cdc_pstn_ptr->rndis_hw_state = NdisHardwareStatusNotReady;
        cdc_pstn_ptr->rndis_media_connect_status = NdisMediaStateUnknown;
        cdc_pstn_ptr->rndis_dev_max_tx_size = 
            cdc_obj_ptr->rndis_max_frame_size + RNDIS_USB_HEADER_SIZE;
        cdc_pstn_ptr->response_data_ptr = NULL; /* Initializing */
        cdc_pstn_ptr->rndis_command_ptr = NULL;
        
        cdc_pstn_ptr->response_data_ptr = 
            USB_mem_alloc_zero(MAX_EXPECTED_RESPONSE_SIZE);
        if(cdc_pstn_ptr->response_data_ptr == NULL)
        {
            #if _DEBUG
                printf("response_data_ptr malloc failed: USB_Pstn_Init\n");
            #endif  
            return USBERR_ALLOC;
        }
    
        cdc_pstn_ptr->rndis_command_ptr = 
            USB_mem_alloc_zero(MAX_EXPECTED_COMMAND_SIZE);
        if(cdc_pstn_ptr->rndis_command_ptr == NULL)
        {
            #if _DEBUG
                printf("rndis_command_ptr malloc failed: USB_Pstn_Init\n");
            #endif  
            return USBERR_ALLOC;
        }
    #endif
    
    return error;     
}

/**************************************************************************//*!
 *
 * @name  USB_Pstn_Deinit
 *
 * @brief The funtion initializes the Pstn Module 
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
uint_8 USB_Pstn_Deinit
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr
) 
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr = NULL;
    uint_8 error = USB_OK;   
    cdc_pstn_ptr = cdc_obj_ptr->pstn_obj_ptr;
    /* Free the Global Variable Structure */
   
    #if RNDIS_SUPPORT
    USB_mem_free(cdc_pstn_ptr->response_data_ptr);
    USB_mem_free(cdc_pstn_ptr->rndis_command_ptr);
    #endif
    USB_mem_free(cdc_pstn_ptr);
    return error;     
}
/**************************************************************************//*!
 *
 * @name  PSTN_Get_Line_Coding
 *
 * @brief  This function is called in response to GetLineCoding request
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
uint_8 PSTN_Get_Line_Coding
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{   
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    uint_8 error;
    UNUSED_ARGUMENT (size)
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Get_Line_Coding: cdc_pstn_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }       
    
    /*  *size is equal to LINE_CODING_SIZE; */
    cdc_pstn_ptr->current_interface =  (uint_8)setup_packet->index ; 
    error = USB_Class_Get_Desc(cdc_obj_ptr->class_handle,GET_LINE_CODING,cdc_pstn_ptr->current_interface,data); 

    return error;
}

/**************************************************************************//*!
 *
 * @name  PSTN_Set_Line_Coding
 *
 * @brief  This function is called in response to SetLineCoding request
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
uint_8 PSTN_Set_Line_Coding
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{   
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    uint_8 error;
    UNUSED_ARGUMENT(data)
    
    *size = 0;

    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Set_Line_Coding: cdc_pstn_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }
       
    /* send the data to the host */
    cdc_pstn_ptr->current_interface =  (uint_8)setup_packet->index ; 
    error = USB_Class_Set_Desc(cdc_obj_ptr->class_handle,SET_LINE_CODING,cdc_pstn_ptr->current_interface,(uint_8_ptr *)&setup_packet); 
   
    return error;
}

/**************************************************************************//*!
 *
 * @name  PSTN_Set_Ctrl_Line_State
 *
 * @brief  This function is called in response to Set Control Line State 
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/ 
uint_8 PSTN_Set_Ctrl_Line_State
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    UNUSED_ARGUMENT(data)
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Set_Ctrl_Line_State: cdc_pstn_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }
     
    *size=0;

    cdc_pstn_ptr->dte_status = (uint_8)setup_packet->value ;
    cdc_pstn_ptr->uart_bitmap._byte = 0x00; /* initialize */
    if(cdc_pstn_ptr->pstn_callback.callback != NULL)
    {   
        /* activate/deactivate Tx carrier */   
        cdc_pstn_ptr->uart_bitmap.Bitmap_Uart.bTxCarrier = (cdc_pstn_ptr->dte_status & 
            CARRIER_ACTIVATION_CHECK)?1:0 ;
        /* activate carrier and DTE */ 
        cdc_pstn_ptr->uart_bitmap.Bitmap_Uart.bRxCarrier = (cdc_pstn_ptr->dte_status & 
            DTE_PRESENCE_CHECK)?1:0 ;
           
        /* Indicates to DCE if DTE is present or not */
        cdc_pstn_ptr->dte_present = (cdc_pstn_ptr->dte_status & DTE_PRESENCE_CHECK)?TRUE:FALSE;

        PSTN_Send_Serial_State(cdc_obj_ptr);/* send notification to host*/

        if(cdc_pstn_ptr->dte_status & CARRIER_ACTIVATION_CHECK) 
        {  
            cdc_pstn_ptr->pstn_callback.callback(USB_APP_CDC_CARRIER_ACTIVATED, NULL, cdc_pstn_ptr->pstn_callback.arg);
        } 
        else
        {           
            cdc_pstn_ptr->pstn_callback.callback(USB_APP_CDC_CARRIER_DEACTIVATED, NULL, cdc_pstn_ptr->pstn_callback.arg);
        }                
        if(cdc_pstn_ptr->dte_status & DTE_PRESENCE_CHECK) 
        {  
            cdc_pstn_ptr->pstn_callback.callback(USB_APP_CDC_DTE_ACTIVATED, NULL, cdc_pstn_ptr->pstn_callback.arg);
        } 
        else
        {           
            cdc_pstn_ptr->pstn_callback.callback(USB_APP_CDC_DTE_DEACTIVATED, NULL, cdc_pstn_ptr->pstn_callback.arg);
        }                
    } 
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  PSTN_Send_Break
 *
 * @brief  This function is called in response to Set Config request
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/ 
uint_8 PSTN_Send_Break
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    UNUSED_ARGUMENT (data)
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Send_Break: cdc_pstn_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }

    *size = 0;        
    cdc_pstn_ptr->break_duration =  setup_packet->value;    
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  PSTN_Get_Comm_Feature
 *
 * @brief  This function is called in response to GetCommFeature request
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
uint_8 PSTN_Get_Comm_Feature
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{   uint_8 error;
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Get_Comm_Feature: cdc_pstn_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }
   
    error = USB_OK;
    *size = cdc_obj_ptr->comm_feature_data_size;
    cdc_pstn_ptr->current_interface =  (uint_8)setup_packet->index ; 
    if(setup_packet->value == ABSTRACT_STATE_FEATURE) 
    {     
    
        error = USB_Class_Get_Desc(cdc_obj_ptr->class_handle,GET_ABSTRACT_STATE,cdc_pstn_ptr->current_interface,data);           
    } 
    else if(setup_packet->value == COUNTRY_SETTING_FEATURE) 
    {
        
       error = USB_Class_Get_Desc(cdc_obj_ptr->class_handle,GET_COUNTRY_SETTING,cdc_pstn_ptr->current_interface,data);           
    } 
    else 
    {
        *size = 0; /* for Reserved/Invalid Feature Selector Value */ 
    }
    return error;
}

/**************************************************************************//*!
 *
 * @name  PSTN_Set_Comm_Feature
 *
 * @brief  This function is called in response to SetCommFeature request
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
uint_8 PSTN_Set_Comm_Feature
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{   uint_8 error;
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Set_Comm_Feature: cdc_pstn_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }
    
    error = USB_OK;
    *size = cdc_obj_ptr->comm_feature_data_size;
    cdc_pstn_ptr->current_interface =  (uint_8)setup_packet->index ;
    if(setup_packet->value == ABSTRACT_STATE_FEATURE) 
    {  
       error = USB_Class_Set_Desc(cdc_obj_ptr->class_handle,SET_ABSTRACT_STATE,cdc_pstn_ptr->current_interface,data);                 
    } 
    else if(setup_packet->value == COUNTRY_SETTING_FEATURE) 
    {
           error = USB_Class_Set_Desc(cdc_obj_ptr->class_handle,SET_COUNTRY_SETTING,cdc_pstn_ptr->current_interface,data);               
    } 
    else 
    {
        *size = 0; /* for Reserved/Invalid Feature Selector Value */ 
    }
    return error;
}

/**************************************************************************//*!
 *
 * @name  PSTN_Send_Serial_State
 *
 * @brief  This function is called to send serial state notification
 *
 * @param cdc_obj_ptr :   Pointer to CDC class object.
 *
 * @return NONE
 *****************************************************************************/ 
void PSTN_Send_Serial_State(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr) 
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    uint_32 val;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
        return;

    /* update array for current interface */
    cdc_pstn_ptr->serial_state_buf[4] = cdc_pstn_ptr->current_interface;
    /* Lower byte of UART BITMAP */
    cdc_pstn_ptr->serial_state_buf[NOTIF_PACKET_SIZE+UART_BITMAP_SIZE-2] = 
        cdc_pstn_ptr->uart_bitmap._byte;
    val = (uint_32)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
    (void)USB_Class_CDC_Send_Data(cdc_obj_ptr->cdc_handle, 
        cdc_obj_ptr->cic_send_endpoint,cdc_pstn_ptr->serial_state_buf,val); 
}

/**************************************************************************//*!
 *
 * @name  PSTN_Response_Available
 *
 * @brief  This function is called to send notification to host that a 
 *         response is available
 *
 * @param cdc_obj_ptr   
 *
 * @return NONE
 *****************************************************************************/ 
void PSTN_Response_Available(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr) 
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Response_Available: cdc_pstn_ptr is NULL\n");
        #endif  
        return;
    }
    /* update array for current interface */
    g_response_available_data[4] = cdc_pstn_ptr->current_interface;
    
    (void)USB_Class_CDC_Send_Data(cdc_obj_ptr->cdc_handle, 
        cdc_obj_ptr->cic_send_endpoint,
        g_response_available_data,NOTIF_PACKET_SIZE); 
}


#if RNDIS_SUPPORT
/**************************************************************************//*!
 *
 * @name  PSTN_Rndis_Message_Set
 *
 * @brief  This function is called in response to PSTN_Rndis_Message_Set 
 *
 * @param handle            handle to Identify the controller
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
uint_8 PSTN_Rndis_Message_Set
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{   
    uint_32 message_type;
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    UNUSED_ARGUMENT(data)
    UNUSED_ARGUMENT(size)
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Rndis_Message_Set: cdc_pstn_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }
    
    cdc_pstn_ptr->current_interface =  (uint_8)setup_packet->index ; 

    if(!(cdc_pstn_ptr->current_interface < 
         cdc_obj_ptr->max_supported_interfaces))
    {       
        #if _DEBUG
            printf("PSTN_Rndis_Message_Set:  %d interface not supported\n", cdc_pstn_ptr->current_interface); 
        #endif  
        return USBERR_INVALID_REQ_TYPE;
    }   

    if(setup_packet->length > MAX_EXPECTED_COMMAND_SIZE) 
    {
        #if _DEBUG
            printf("MAX_EXPECTED_COMMAND_SIZE insufficient, needed %d\n", setup_packet->length);
        #endif  
        return USBERR_ERROR;
    }

    /* Command data has been appended at the end of setup token in framework.c
       Copy data from that buffer to buffer in pstn.c memory for that buffer 
       will be freed on completion of setup transfer*/
    USB_mem_copy(setup_packet+1, cdc_pstn_ptr->rndis_command_ptr,
        setup_packet->length);
    
    message_type = LONG_LE_TO_HOST(*((uint_32_ptr)(cdc_pstn_ptr->rndis_command_ptr)));
    
    if(message_type == REMOTE_NDIS_HALT_MSG)
    {   
        /* No response is send to host on receving Halt Command */
        RNDIS_Halt_Command(cdc_obj_ptr);
    }
    else
    {
        PSTN_Response_Available(cdc_obj_ptr);       
    }
    
    if(message_type == REMOTE_NDIS_INITIALIZE_MSG)
    {
        /* Update the NDIS HW status */
        cdc_pstn_ptr->rndis_hw_state = NdisHardwareStatusInitializing;
    }
    
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  PSTN_Rndis_Message_Get
 *
 * @brief  This function is called in response to PSTN_Rndis_Message_Get 
 *
 * @param handle            handle to Identify the controller
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
uint_8 PSTN_Rndis_Message_Get
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{       
    uint_32_ptr message_type_ptr;
    uint_16 setup_pkt_len =  setup_packet->length;
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;

    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("PSTN_Rndis_Message_Get: cdc_pstn_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }

    *size = 0;
    
    message_type_ptr = (uint_32_ptr)(cdc_pstn_ptr->rndis_command_ptr);
    /* we can avoid one swap operation by using message_type_ptr in 
       PSTN_Rndis_Message_Set instead of message_type, but this gives 
       cleaner implementation as all manipulations and parsing on command 
       are done in this function */
    *message_type_ptr = LONG_LE_TO_HOST(*message_type_ptr);

    switch(*message_type_ptr)
    {
        case REMOTE_NDIS_INITIALIZE_MSG: 
            /* Preparing for response to REMOTE_NDIS_INITIALIZE_MSG command 
               i.e. REMOTE_NDIS_INITIALIZE_CMPLT data */
            RNDIS_Initialize_Command(cdc_obj_ptr,data,size);            
            break;
        case REMOTE_NDIS_QUERY_MSG:
            /* Preparing for response to REMOTE_NDIS_QUERY_MSG command 
               i.e. REMOTE_NDIS_QUERY_CMPLT data */
            /* correct the endianess of OID */
            *((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 3) = LONG_LE_TO_HOST(*((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 3));
            RNDIS_Query_Command(cdc_obj_ptr,data,size);         
            break;
        case REMOTE_NDIS_SET_MSG : 
            /* Preparing for response to REMOTE_NDIS_SET_MSG command 
               i.e. REMOTE_NDIS_SET_CMPLT data */
            /* Correct the endianess of OID and InformationBufferLength
               and InformationBufferOffset*/
            *((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 3) = LONG_LE_TO_HOST(*((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 3));
            *((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 4) = LONG_LE_TO_HOST(*((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 4));
            *((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 5) = LONG_LE_TO_HOST(*((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 5));
            RNDIS_Set_Command(cdc_obj_ptr,data,size);           
            break;
        case REMOTE_NDIS_RESET_MSG :
            /* Preparing for response to REMOTE_NDIS_RESET_MSG command 
               i.e. REMOTE_NDIS_RESET_CMPLT data */
            RNDIS_Reset_Command(cdc_obj_ptr,data,size);         
            break;
        case REMOTE_NDIS_INDICATE_STATUS_MSG : 
            /* Preparing for response to REMOTE_NDIS_INDICATE_STATUS_MSG 
               command */       
            RNDIS_Indicate_Status_Command(cdc_obj_ptr,data,size);           
            break;
        case REMOTE_NDIS_KEEPALIVE_MSG : 
            /* Preparing for response to REMOTE_NDIS_KEEPALIVE_MSG command 
               i.e. REMOTE_NDIS_KEEPALIVE_CMPLT data */
            RNDIS_Keepalive_Command(cdc_obj_ptr,data,size);         
            break;      
        default : 
            #if _DEBUG
                printf("UNSUPPORTED RNDIS Command : 0x%x\n",*message_type_ptr);
            #endif  
            return USBERR_INVALID_REQ_TYPE;         
    }
    
    if(*size > MAX_EXPECTED_RESPONSE_SIZE) 
    {
        #if _DEBUG
            printf("MAX_EXPECTED_RESPONSE_SIZE insufficient\n");
        #endif  
    }
    
    if(setup_pkt_len < *size)
    {
        #if _DEBUG
            printf("Error : Device has more data to send than Host needs.\n");
        #endif  
        return USBERR_INVALID_REQ_TYPE;
    }
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  RNDIS_Initialize_Command
 *
 * @brief  This function is called to initialize the RNDIS device and prepare
 *         data to be sent to host as Remote_NDIS_INITIALIZE_CMPLT 
 *
 * @param handle   handle to Identify the controller
 * @param data:    data to be send back
 * @param size:    size to be returned 
 *
 * @return NONE
 *
 *****************************************************************************/ 
void RNDIS_Initialize_Command
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    uint_32 max_tx_size ;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("RNDIS_Initialize_Command: cdc_pstn_ptr is NULL\n");
        #endif  
        return;
    }

    /* preparing for Byte 0-3 : MessageType*/   
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr) = LONG_LE_TO_HOST_CONST(REMOTE_NDIS_INITIALIZE_CMPLT);

    /* preparing for Byte 4-7 : MessageLength*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 1) = LONG_LE_TO_HOST_CONST(RESPONSE_RNDIS_INITIALIZE_MSG_SIZE);

    /* preparing for Byte 8-11 : RequestID*/
    USB_mem_copy(((uint_32_ptr)(cdc_pstn_ptr->rndis_command_ptr) + 2), 
        ((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 2),sizeof(uint_32));
    
    /* preparing for Byte 12-15 : Status*/
    if(cdc_pstn_ptr->rndis_device_state == RNDIS_UNINITIALIZED)
    {
        *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 3) = LONG_LE_TO_HOST_CONST(RNDIS_STATUS_SUCCESS); 
    }
    else
    {
        *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 3) = LONG_LE_TO_HOST_CONST(RNDIS_STATUS_FAILURE);
    }
    
    /* preparing for Byte 16-19 ; MajorVersion*/
    /* We are currently returning the same driver version to host in 
       response to initialization command as reported by host driver */
    USB_mem_copy(((uint_32_ptr)(cdc_pstn_ptr->rndis_command_ptr) + 3), 
        ((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 4),sizeof(uint_32));

    /* preparing for Byte 20-23 : MinorVersion*/
    USB_mem_copy(((uint_32_ptr)(cdc_pstn_ptr->rndis_command_ptr) + 4), 
        ((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 5),sizeof(uint_32));

    /* preparing for Byte 24-27 : DeviceFlags*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST_CONST(RNDIS_DF_CONNECTIONLESS);
    
    /* preparing for Byte 28-31 : Medium*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 7) = LONG_LE_TO_HOST(NdisMedium802_3);
    
    /* preparing for Byte 32-35 : MaxPacketsPerTransfer*/
    /* We are not implementing multiple packet transfer support in our RNDIS */
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 8) = LONG_LE_TO_HOST_CONST(RNDIS_SINGLE_PACKET_TRANSFER);
                
    /* preparing for Byte 36-39 : MaxTransferSize*/
    /* We are currently returning the same max transfer size to host
       as it send to device in its corresponding filed in 
       initialization command */
    cdc_pstn_ptr->rndis_host_max_tx_size = LONG_LE_TO_HOST(*((uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 5));
    max_tx_size = LONG_LE_TO_HOST(cdc_pstn_ptr->rndis_dev_max_tx_size);
    USB_mem_copy(&max_tx_size, 
        ((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 9),sizeof(uint_32));

    /* preparing for Byte 40-43 : PacketAlignmentFactor*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 10) = LONG_LE_TO_HOST_CONST(PACKET_ALIGNMENT_FACTOR);
    
    /* preparing for Byte 44-47 : PacketAlignmentFactor*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 11) = AF_LIST_OFFSET;

    /* preparing for Byte 48-51 : PacketAlignmentFactor*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 12) = AF_LIST_SIZE;
            
    *data = cdc_pstn_ptr->response_data_ptr;
    *size = RESPONSE_RNDIS_INITIALIZE_MSG_SIZE; 

    /* initializing RNDIS variables */
    cdc_pstn_ptr->rndis_device_state = RNDIS_INITIALIZED;
    cdc_pstn_ptr->rndis_hw_state = NdisHardwareStatusReady;
    cdc_pstn_ptr->rndis_media_connect_status = NdisMediaStateDisconnected;  
    cdc_pstn_ptr->num_frames_tx_ok = 0;
    cdc_pstn_ptr->num_frames_rx_ok = 0;
    cdc_pstn_ptr->num_frames_tx_error = 0;
    cdc_pstn_ptr->num_frames_rx_error = 0;
    cdc_pstn_ptr->num_recv_frames_missed = 0;
    cdc_pstn_ptr->num_recv_frames_alignment_error = 0;
    cdc_pstn_ptr->num_frames_tx_one_collision = 0;
    cdc_pstn_ptr->num_frames_tx_many_collision = 0;
}

/**************************************************************************//*!
 *
 * @name  RNDIS_Keepalive_Command
 *
 * @brief  This function is called to check the health of RNDIS device and prepare
 *         data to be sent to host as REMOTE_NDIS_KEEPALIVE_CMPLT 
 *
 * @param handle   handle to Identify the controller
 * @param data:    data to be send back
 * @param size:    size to be returned 
 *
 * @return NONE
 *
 *****************************************************************************/ 
void RNDIS_Keepalive_Command
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("RNDIS_Keepalive_Command: cdc_pstn_ptr is NULL\n");
        #endif  
        return;
    }
    
    /* preparing for Byte 0-3 : MessageType*/   
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr) = LONG_LE_TO_HOST_CONST(REMOTE_NDIS_KEEPALIVE_CMPLT);

    /* preparing for Byte 4-7 : MessageLength*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 1) = LONG_LE_TO_HOST_CONST(RESPONSE_RNDIS_KEEPALIVE_MSG_SIZE);

    /* preparing for Byte 8-11 : RequestID*/
    USB_mem_copy(((uint_32_ptr)(cdc_pstn_ptr->rndis_command_ptr) + 2), 
        ((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 2),sizeof(uint_32));
    
    /* preparing for Byte 12-15 : Status*/
    if(cdc_pstn_ptr->rndis_device_state == RNDIS_DATA_INITIALIZED)
    {
        *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 3) = LONG_LE_TO_HOST_CONST(RNDIS_STATUS_SUCCESS); 
    }
    else
    {
        *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 3) = LONG_LE_TO_HOST_CONST(RNDIS_STATUS_FAILURE);
    }
    
    *data = cdc_pstn_ptr->response_data_ptr;
    *size = RESPONSE_RNDIS_KEEPALIVE_MSG_SIZE;      
}

/**************************************************************************//*!
 *
 * @name  RNDIS_Query_Command
 *
 * @brief  This function is called to query the RNDIS device for its 
 *         characteristics or statistics information or status and prepare
 *         data to be sent to host as Remote_NDIS_Query_CMPLT 
 *
 * @param handle   handle to Identify the controller
 * @param data:    data to be send back
 * @param size:    size to be returned 
 *
 * @return NONE
 *
 *****************************************************************************/ 
void RNDIS_Query_Command
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    uint_32_ptr oid_ptr;
    uint_8 i;
    uint_32 info_buf_len = 0;
    uint_32 return_status = RNDIS_STATUS_SUCCESS;
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("RNDIS_Query_Command: cdc_pstn_ptr is NULL\n");
        #endif  
        return;
    }
    oid_ptr = (uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 3;
    
    /* preparing for Byte 0-3 : MessageType*/   
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr) = LONG_LE_TO_HOST_CONST(REMOTE_NDIS_QUERY_CMPLT);

    /* preparing for Byte 8-11 : RequestID*/
    USB_mem_copy(((uint_32_ptr)(cdc_pstn_ptr->rndis_command_ptr) + 2), 
        ((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 2),sizeof(uint_32));
    

    /* preparing for Byte 20-23 : InformationBufferOffset*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 5) = LONG_LE_TO_HOST_CONST(0x00000010);
        
    switch(*oid_ptr)
    {
        case OID_GEN_SUPPORTED_LIST : 
            /* List of supported OIDs - Query Manadatory - General Operational Characteristic */
            for(i=0;i<NUM_OIDS_SUPPORTED;i++)
            {   /* change the endianess of data before sending on USB Bus */
                g_list_supp_oid[i] = LONG_LE_TO_HOST(g_list_supp_oid[i]);             
            }                       
            info_buf_len = sizeof(g_list_supp_oid);         
            USB_mem_copy(g_list_supp_oid, 
                (uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6, info_buf_len);            
            break;
        case OID_GEN_HARDWARE_STATUS :
            /* Hardware status  - Query Mandatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->rndis_hw_state);
            break;
        case OID_GEN_MEDIA_SUPPORTED :
            /* Media types supported (encoded) - Query Manadatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(NdisMedium802_3);
            break;
        case OID_GEN_MEDIA_IN_USE :
            /* Media types in use (encoded) - Query Manadatory - General Operational Characteristic*/ 
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(NdisMedium802_3);
            break;
        case OID_GEN_MAXIMUM_FRAME_SIZE : 
            /* Maximum in bytes, frame size - Query Mandatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_obj_ptr->rndis_max_frame_size); 
            break;
        case OID_GEN_LINK_SPEED :
            /* Link speed in units of 100 bps - Query Mandatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            if(cdc_pstn_ptr->pstn_callback.callback != NULL)
            {   
                cdc_pstn_ptr->pstn_callback.callback(USB_APP_GET_LINK_SPEED,
                (void*)((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6),
                cdc_pstn_ptr->pstn_callback.arg);
            } 

            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(*((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6));
            break;
        case OID_GEN_TRANSMIT_BLOCK_SIZE : 
            /* Minimum amount of storage, in bytes, that a single packet 
               occupies in the transmit buffer space of the NIC - 
               Query Mandatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST((uint_32)cdc_obj_ptr->dic_send_pkt_size);
            break;
        case OID_GEN_RECEIVE_BLOCK_SIZE : 
            /* Amount of storage, in bytes, that a single packet occupies in 
               the receive buffer space of the NIC - Query Manadatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST((uint_32)cdc_obj_ptr->dic_recv_pkt_size);
            break;
        case OID_GEN_VENDOR_ID :
            /* Vendor NIC code - Query Mandatory - General Operational Characteristic*/
            /* This object specifies a three-byte IEEE-registered vendor code, 
               followed by a single byte that the vendor assigns to identify 
               a particular NIC. The IEEE code uniquely identifies the vendor 
               and is the same as the three bytes appearing at the beginning
               of the NIC hardware address.Vendors without an IEEE-registered 
               code should use the value 0xFFFFFF. */
            info_buf_len = sizeof(uint_32);
            
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST_CONST(
                (uint_32) (((uint_32) RNDIS_VENDOR_ID << 8) | (uint_32) NIC_IDENTIFIER_VENDOR));
            break;
        case OID_GEN_VENDOR_DESCRIPTION :
            /* Vendor network card description - Query Mandatory - General Operational Characteristic*/
            info_buf_len = VENDOR_INFO_SIZE;
            USB_mem_copy(g_vendor_info, (uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6, info_buf_len);            
            break;
        case OID_GEN_CURRENT_PACKET_FILTER : 
            /* Current packet filter (encoded) - Query and Set Manadatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->rndis_packet_filter);
            break;
        case OID_GEN_MAXIMUM_TOTAL_SIZE : 
            /* Maximum total packet length in bytes - Query Manadatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->rndis_dev_max_tx_size);
            break;
        case OID_GEN_MEDIA_CONNECT_STATUS : 
            /* Whether the NIC is connected to the network - Query Mandatory - General Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->rndis_media_connect_status);
            break;
        case OID_GEN_XMIT_OK : 
            /* Frames transmitted without errors - Query Mandatory - General Statistics*/ 
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->num_frames_tx_ok);
            break;
        case OID_GEN_RCV_OK : 
            /* Frames received without errors - Query Mandatory - General Statistics*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->num_frames_rx_ok);
            break;
        case OID_GEN_XMIT_ERROR : 
            /* Frames not transmitted or transmitted with errors - Query Mandatory - General Statistics*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->num_frames_tx_error);
            break;
        case OID_GEN_RCV_ERROR : 
            /* Frames received with errors - Query Mandatory - General Statistics*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->num_frames_rx_error);
            break;
        case OID_GEN_RCV_NO_BUFFER : 
            /* Frame missed, no buffers - Query Mandatory - General Statistics*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->num_recv_frames_missed);
            break;
        case OID_802_3_PERMANENT_ADDRESS : 
            /* Permanent station address - Query Mandatory - Ethernet Operational Characteristic*/
            info_buf_len = RNDIS_ETHER_ADDR_SIZE; 
            USB_mem_copy(cdc_obj_ptr->mac_address, 
                (uint_8_ptr)((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6), 
                info_buf_len);  
            
            break;
        case OID_802_3_CURRENT_ADDRESS : 
            /* Current station address - Query Mandatory - Ethernet Operational Characteristic*/
            info_buf_len = RNDIS_ETHER_ADDR_SIZE; 
            USB_mem_copy(cdc_obj_ptr->mac_address, 
                (uint_8_ptr)((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6), 
                info_buf_len);  
            
            break;
        case OID_802_3_MULTICAST_LIST : 
            /* Current multicast address list - Query and Set Mandatory - Ethernet Operational Characteristic*/
            info_buf_len = RNDIS_ETHER_ADDR_SIZE;
            /* Currently Our RNDIS driver does not support multicast addressing */
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST_CONST(0x00000000);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 7) = LONG_LE_TO_HOST_CONST(0x00000000);
            break;
        case OID_802_3_MAXIMUM_LIST_SIZE :
            /* Maximum size of multicast address list - Query Mandatory - Ethernet Operational Characteristic*/
            info_buf_len = sizeof(uint_32);
            /* Currently Our RNDIS driver does not support multicast addressing */
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST_CONST(RNDIS_MULTICAST_LIST_SIZE);
            break;
        case OID_802_3_RCV_ERROR_ALIGNMENT : 
            /* Frames received with alignment error - Query Mandatory - Ethernet Statistics*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->num_recv_frames_alignment_error); 
            break;
        case OID_802_3_XMIT_ONE_COLLISION : 
            /* Frames transmitted with one collision - Query Mandatory - Ethernet Statistics*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->num_frames_tx_one_collision);
            break;
        case OID_802_3_XMIT_MORE_COLLISIONS : 
            /* Frames transmitted with more than one collision - Query Mandatory - Ethernet Statistics*/
            info_buf_len = sizeof(uint_32);
            *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 6) = LONG_LE_TO_HOST(cdc_pstn_ptr->num_frames_tx_many_collision);
            break;
        default : 
            #if _DEBUG
                printf("OID 0x%x NOT SUPPORTED(QUERY)\n",*oid_ptr);
            #endif  
            return_status = RNDIS_STATUS_NOT_SUPPORTED;
            break;
    }

    /* preparing for Byte 12-15 : Status*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 3) = LONG_LE_TO_HOST(return_status);
    
    *size = RESPONSE_RNDIS_QUERY_MSG_SIZE + info_buf_len;       
    /* preparing for Byte 4-7 : MessageLength*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 1) = LONG_LE_TO_HOST(*size);
    /* preparing for Byte 16-19 : InformationBufferLength*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 4) = LONG_LE_TO_HOST(info_buf_len);
    *data = cdc_pstn_ptr->response_data_ptr;
}

/**************************************************************************//*!
 *
 * @name  RNDIS_Set_Command
 *
 * @brief  This function is called to Configure the operational parameters of
 *         RNDIS device.
 *
 * @param handle   handle to Identify the controller
 * @param data:    data to be send back
 * @param size:    size to be returned 
 *
 * @return NONE
 *
 *****************************************************************************/ 
void RNDIS_Set_Command
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    uint_32_ptr oid_ptr;
    uint_32_ptr info_buf_len_ptr;
    uint_32_ptr info_buf_offset_ptr;
    uint_32 return_status = RNDIS_STATUS_SUCCESS;
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("RNDIS_Set_Command: cdc_pstn_ptr is NULL\n");
        #endif  
        return;
    }
    oid_ptr = (uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 3;
    info_buf_len_ptr = (uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 4;
    info_buf_offset_ptr = (uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 5;
    
    /* preparing for Byte 0-3 : MessageType*/   
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr) = LONG_LE_TO_HOST_CONST(REMOTE_NDIS_SET_CMPLT);

    *size = RESPONSE_RNDIS_SET_MSG_SIZE;        
    /* preparing for Byte 4-7 : MessageLength*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 1) = LONG_LE_TO_HOST(*size);

    /* preparing for Byte 8-11 : RequestID*/
    USB_mem_copy(((uint_32_ptr)(cdc_pstn_ptr->rndis_command_ptr) + 2), 
        ((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 2),sizeof(uint_32));
    
    switch(*oid_ptr)
    {
        case OID_GEN_CURRENT_PACKET_FILTER : 
            /* Current packet filter (encoded) - Query and Set Manadatory - General Operational Characteristic*/
            if(*info_buf_len_ptr != 4 ) 
            {
                return_status = RNDIS_STATUS_INVALID_DATA;
            }
            else
            {   
                boolean media_connected = FALSE;

                cdc_pstn_ptr->rndis_packet_filter = LONG_LE_TO_HOST( *((uint_32_ptr)((uint_8_ptr)((uint_32_ptr)
                    cdc_pstn_ptr->rndis_command_ptr + 2) + *info_buf_offset_ptr)));
                if(cdc_pstn_ptr->pstn_callback.callback != NULL)
                {   
                    cdc_pstn_ptr->pstn_callback.callback(USB_APP_GET_LINK_STATUS,
                    (void*)(&media_connected),
                    cdc_pstn_ptr->pstn_callback.arg);
                } 

                if((cdc_pstn_ptr->rndis_packet_filter)&&(media_connected == TRUE))
                {
                    cdc_pstn_ptr->rndis_device_state = RNDIS_DATA_INITIALIZED;  
                    cdc_pstn_ptr->rndis_media_connect_status = NdisMediaStateConnected;
                }
                else
                {
                    cdc_pstn_ptr->rndis_device_state = RNDIS_INITIALIZED;   
                    cdc_pstn_ptr->rndis_media_connect_status = NdisMediaStateDisconnected;
                }
            }
            break;
        case OID_802_3_MULTICAST_LIST : 
            /* Current multicast address list - Query and Set Mandatory - Ethernet Operational Characteristic*/
            if(*info_buf_len_ptr != RNDIS_ETHER_ADDR_SIZE) 
            {
                return_status = RNDIS_STATUS_INVALID_DATA;
            }
            else
            {   uint_64 multi_cast_list;
                multi_cast_list = *((uint_64_ptr)((uint_8_ptr)((uint_32_ptr)
                    cdc_pstn_ptr->rndis_command_ptr + 2) + *info_buf_offset_ptr));
                if(multi_cast_list)
                {/* Currently Our RNDIS driver does not support multicast addressing */
                    return_status = RNDIS_STATUS_NOT_SUPPORTED;
                }
            }

            break;
        default : 
            #if _DEBUG
                printf("OID 0x%x NOT SUPPORTED(SET)\n",*oid_ptr);
            #endif  
            return_status = RNDIS_STATUS_NOT_SUPPORTED;
            break;
    }
    /* preparing for Byte 12-15 : Status*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 3) = LONG_LE_TO_HOST(return_status);
    *data = cdc_pstn_ptr->response_data_ptr;        
}

/**************************************************************************//*!
 *
 * @name  RNDIS_Reset_Command
 *
 * @brief  This function is called to soft reset the RNDIS device.
 *
 * @param handle   handle to Identify the controller
 * @param data:    data to be send back
 * @param size:    size to be returned 
 *
 * @return NONE
 *
 *****************************************************************************/ 
void RNDIS_Reset_Command
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    uint_8_ptr *data, 
    uint_32 *size
)
{
//    uint_32_ptr oid_ptr;
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;    
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("RNDIS_Reset_Command: cdc_pstn_ptr is NULL\n");
        #endif  
        return;
    }

//    oid_ptr = (uint_32_ptr)cdc_pstn_ptr->rndis_command_ptr + 3;
    
    /* preparing for Byte 0-3 : MessageType*/   
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr) = LONG_LE_TO_HOST_CONST(REMOTE_NDIS_RESET_CMPLT);

    *size = RESPONSE_RNDIS_RESET_MSG_SIZE;      
    /* preparing for Byte 4-7 : MessageLength*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 1) = LONG_LE_TO_HOST(*size);
    
    /* preparing for Byte 8-11 : Status*/
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 2) = LONG_LE_TO_HOST_CONST(RNDIS_STATUS_SUCCESS);

    /* preparing for Byte 12-15 : AddressingReset*/
    /* No need for host to resend addressing information */
    *((uint_32_ptr)cdc_pstn_ptr->response_data_ptr + 3) = LONG_LE_TO_HOST_CONST(0x00000000);

    *data = cdc_pstn_ptr->response_data_ptr;
    cdc_pstn_ptr->rndis_hw_state = NdisHardwareStatusReset;
    cdc_pstn_ptr->rndis_device_state = RNDIS_UNINITIALIZED;
    cdc_pstn_ptr->rndis_media_connect_status = NdisMediaStateUnknown;
}

/**************************************************************************//*!
 *
 * @name  RNDIS_Indicate_Status_Command
 *
 * @brief  Used to indicate change in status of device
 *
 * @param handle   handle to Identify the controller
 * @param data:    data to be send back
 * @param size:    size to be returned 
 *
 * @return NONE
 *
 *****************************************************************************/ 
void RNDIS_Indicate_Status_Command 
(
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    UNUSED_ARGUMENT(cdc_obj_ptr)
    UNUSED_ARGUMENT(data)
    UNUSED_ARGUMENT(size)   
    return;
}

/**************************************************************************//*!
 *
 * @name  RNDIS_Halt_Command
 *
 * @brief  This function is called to halt the RNDIS device.
 *         i.e. to terminate the network connection
 *
 * @param handle   handle to Identify the controller
 * @param data:    data to be send back
 * @param size:    size to be returned 
 *
 * @return NONE
 *
 *****************************************************************************/ 
void RNDIS_Halt_Command(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr)
{
    CDC_PSTN_STRUCT_PTR cdc_pstn_ptr;
    
    cdc_pstn_ptr = (CDC_PSTN_STRUCT_PTR)cdc_obj_ptr->pstn_obj_ptr;
    if (NULL == cdc_pstn_ptr)
    {
        #if _DEBUG
            printf("RNDIS_Halt_Command: cdc_pstn_ptr is NULL\n");
        #endif  
        return;
    }
    #if _DEBUG
        printf("RNDIS_Halt_Command\n");
    #endif
    cdc_pstn_ptr->rndis_device_state = RNDIS_UNINITIALIZED;
    cdc_pstn_ptr->rndis_media_connect_status = NdisMediaStateDisconnected;  
    cdc_pstn_ptr->rndis_hw_state = NdisHardwareStatusClosing;
    cdc_pstn_ptr->rndis_hw_state = NdisHardwareStatusNotReady;
}
#endif/* rndis support */

#endif /*CDC_CONFIG*/
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/common/include/usb_misc.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_misc.h$
* $Version : 3.8.4.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains USB Device API defines for state and function
*   returns.
*
*END************************************************************************/
#ifndef __usb_misc_h__
#define __usb_misc_h__ 1

/* Host specific */
#define USB_DEBOUNCE_DELAY                  (101)
#define USB_RESET_RECOVERY_DELAY            (11)
#define USB_RESET_DELAY                     (10)

/* Endpoint types */
#define USB_CONTROL_PIPE                    (0x00)
#define USB_ISOCHRONOUS_PIPE                (0x01)
#define USB_BULK_PIPE                       (0x02)
#define USB_INTERRUPT_PIPE                  (0x03)

/* USB device state- see USB 2.0 Documentation */
#define USB_STATE_UNKNOWN                   (0xff)
#define USB_STATE_PENDING_ADDRESS           (0x04) 
#define USB_STATE_POWERED                   (0x03)
#define USB_STATE_DEFAULT                   (0x02)
#define USB_STATE_ADDRESS                   (0x01)
#define USB_STATE_CONFIG                    (0x00)
#define USB_STATE_SUSPEND                   (0x80)

#define USB_SELF_POWERED                    (0x01)
#define USB_REMOTE_WAKEUP                   (0x02)

/* Bus Control values */
#define USB_NO_OPERATION                    (0x00)
#define USB_ASSERT_BUS_RESET                (0x01)
#define USB_DEASSERT_BUS_RESET              (0x02)
#define USB_ASSERT_RESUME                   (0x03)
#define USB_DEASSERT_RESUME                 (0x04)
#define USB_SUSPEND_SOF                     (0x05)
#define USB_RESUME_SOF                      (0x06)

/* possible values of XD->bStatus */
#define USB_STATUS_IDLE                     (0)
#define USB_STATUS_STALLED                  (1) 
#define USB_STATUS_TRANSFER_PENDING         (2)
#define USB_STATUS_TRANSFER_IN_PROGRESS     (3)
#define USB_STATUS_ERROR                    (4)
#define USB_STATUS_DISABLED                 (5)
#define USB_STATUS_TRANSFER_ACCEPTED        (6)
#define USB_STATUS_TRANSFER_QUEUED          (7)

/* Direction constants */
#define USB_RECV                            (0)
#define USB_SEND                            (1)

#define USB_DEVICE_DONT_ZERO_TERMINATE      (0x1)

#define USB_SETUP_DATA_XFER_DIRECTION       (0x80)

/* Speed definitions */
#define USB_SPEED_FULL                      (0)
#define USB_SPEED_LOW                       (1)
#define USB_SPEED_HIGH                      (2)

#define USB_MAX_PKTS_PER_UFRAME             (0x6)

/*----------------------------------------------------------------**
** Chapter 9.4 Standard Device Requests -- all devices            **
** See Table 9-3 p. 250 of USB 2.0 spec for combinations          **
**   of request type bitfields with requests, WVALUE, WINDEX etc. **
**----------------------------------------------------------------*/
#define USB_REQ_TYPE_DEVICE    (0x00)
#define USB_REQ_TYPE_INTERFACE (0x01)
#define USB_REQ_TYPE_ENDPOINT  (0x02)
/* Combine one of the 3 above with one of the following 2 */
#define USB_REQ_TYPE_IN        (0x80)
#define USB_REQ_TYPE_OUT       (0x00)
/* Also for class requests set the following bit */
#define USB_REQ_TYPE_CLASS     (0x20)
/* Standard USB requests, see Chapter 9 */
#define USB_REQ_GET_STATUS          (0)
#define USB_REQ_CLEAR_FEATURE       (1)
#define USB_REQ_SET_FEATURE         (3)
#define USB_REQ_SET_ADDRESS         (5)
#define USB_REQ_GET_DESCRIPTOR      (6)
#define USB_REQ_SET_DESCRIPTOR      (7)
#define USB_REQ_GET_CONFIGURATION   (8)
#define USB_REQ_SET_CONFIGURATION   (9)
#define USB_REQ_GET_INTERFACE       (10)
#define USB_REQ_SET_INTERFACE       (11)
#define USB_REQ_SYNCH_FRAME         (12)

/* Event codes for attach/detach etc. callback */
#define  USB_ATTACH_EVENT           (1)   /* device attach */
#define  USB_DETACH_EVENT           (2)   /* device detach */
#define  USB_CONFIG_EVENT           (3)   /* device reconfigured */
#define  USB_INTF_EVENT             (4)   /* device interface selected */

/* Memory blocks */
#define MEM_TYPE_USB_BASE                    ((IO_USB_COMPONENT) << (MEM_TYPE_COMPONENT_SHIFT))
#define MEM_TYPE_USB_HOST_DEVICE             (MEM_TYPE_USB_BASE+1)
#define MEM_TYPE_USB_HOST_STATE_STRUCT       (MEM_TYPE_USB_BASE+2)
#define MEM_TYPE_USB_ISO_PACKET_DESC_STRUCT  (MEM_TYPE_USB_BASE+3)
#define MEM_TYPE_USB_HOST_PIPE_DESCRIPTORS   (MEM_TYPE_USB_BASE+4)
#define MEM_TYPE_USB_HOST_PIPE_TR_STRUCT     (MEM_TYPE_USB_BASE+5)
#define MEM_TYPE_USB_FILESYSTEM_STRUCT       (MEM_TYPE_USB_BASE+6)
#define MEM_TYPE_USB_CALLBACK_STRUCT         (MEM_TYPE_USB_BASE+7)
#define MEM_TYPE_USB_MFS_STRUCT              (MEM_TYPE_USB_BASE+8)
#define MEM_TYPE_USB_HOST_SERVICE_STRUCT     (MEM_TYPE_USB_BASE+9)
#define MEM_TYPE_USB_HID_STRUCT              (MEM_TYPE_USB_BASE+10)
#define MEM_TYPE_USB_AUDIO_STRUCT            (MEM_TYPE_USB_BASE+11)
#define MEM_TYPE_USB_AUDIO_RING_BUFF         (MEM_TYPE_USB_BASE+12)
#define MEM_TYPE_USB_INTR_TMP_BUFF           (MEM_TYPE_USB_BASE+13)
#define MEM_TYPE_USB_CTRL_TMP_BUFF           (MEM_TYPE_USB_BASE+14)
#define MEM_TYPE_USB_BULK_TMP_BUFF           (MEM_TYPE_USB_BASE+15)
#define MEM_TYPE_USB_ISO_TMP_BUFF            (MEM_TYPE_USB_BASE+16)
#define MEM_TYPE_USB_LIST_MEM_BUFF           (MEM_TYPE_USB_BASE+17)
#define MEM_TYPE_USB_ASYNC_TMP_BUFF          (MEM_TYPE_USB_BASE+18)
#define MEM_TYPE_USB_END                     MEM_TYPE_USB_ISO_TMP_BUFF

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio_siul.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio_siul.c$
* $Version : 3.8.6.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the GPIO standard functions used on boards
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "lwgpio.h"

#include "lwgpio_siul.h"


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_init
* Returned Value   : TRUE if succesfull, FALSE otherwise
* Comments         :
*    Decodes ID to HW specific struct and then performs pin initialization
*
*END*********************************************************************/
boolean lwgpio_init
(
    /* Pointer to LWGPIO internal structure to be filled in */
    LWGPIO_STRUCT_PTR handle,
    /* Pin ID, bitmask integer value */
    LWGPIO_PIN_ID     id,
    /* Direction to be set within initialization */
    LWGPIO_DIR        dir,
    /* Value to be set within initialization */
    LWGPIO_VALUE      value
)
{
    /* no decoding necessary */
    handle->id=id;
    handle->eirq=-1; /* not assigned until required - performance */
    handle->siul_ptr = _bsp_get_gpio_base_address();
    if (handle->siul_ptr == NULL) return FALSE;

    /* Set value prior to set to output */
    if (value != LWGPIO_VALUE_NOCHANGE) {
        /* Note: there is no check for values not defined as LWGPIO_VALUE enum */
        lwgpio_set_value(handle, value);
    }

    if (dir != LWGPIO_DIR_NOCHANGE) {
        /* Note: there is no check for values not defined as LWGPIO_DIR enum */
        lwgpio_set_direction(handle, dir);
    }

    return TRUE;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_attribute
* Returned Value   : TRUE if succesfull, FALSE otherwise
* Comments         :
*    Sets attributes
*
*END*********************************************************************/
boolean lwgpio_set_attribute
(
    /* Pin handle to get function from */
    LWGPIO_STRUCT_PTR   handle,
    /* PORT attribute */
    uint_32             attribute_id,
    /* Attribute value */
    uint_32             value
)
{
    switch (attribute_id)
    {
        case LWGPIO_ATTR_PULL_UP:
            if (value == LWGPIO_AVAL_ENABLE)
            {
                handle->siul_ptr->PCR[handle->id] |= (SIUL_PCR_WPS_MASK | SIUL_PCR_WPE_MASK);
            }
            else if ((handle->siul_ptr->PCR[handle->id] & SIUL_PCR_WPS_MASK) != 0)
            {
                /* disable pull resistor only if pull-up was selected */
                handle->siul_ptr->PCR[handle->id] &= ~SIUL_PCR_WPE_MASK;
            }
            break;

        case LWGPIO_ATTR_PULL_DOWN:
            if (value == LWGPIO_AVAL_ENABLE)
            {
                handle->siul_ptr->PCR[handle->id] &= ~SIUL_PCR_WPS_MASK;
                handle->siul_ptr->PCR[handle->id] |=  SIUL_PCR_WPE_MASK;
            }
            else if ((handle->siul_ptr->PCR[handle->id] & SIUL_PCR_WPS_MASK) == 0)
            {
                /* disable pull resistor only if pull-down was selected */
                handle->siul_ptr->PCR[handle->id] &= ~SIUL_PCR_WPE_MASK;
            }
            break;

        case LWGPIO_ATTR_OPEN_DRAIN:
            if (value == LWGPIO_AVAL_ENABLE)
            {
                handle->siul_ptr->PCR[handle->id] |= SIUL_PCR_ODE_MASK;
            }
            else /* disable */
            {
            	handle->siul_ptr->PCR[handle->id] &= ~SIUL_PCR_ODE_MASK;
            }
            break;

        case LWGPIO_ATTR_SLEW_RATE:
            if (value == LWGPIO_AVAL_SLEW_RATE_SLOW)
            {
            	handle->siul_ptr->PCR[handle->id] &= ~SIUL_PCR_SRC_MASK;
            }
            else /* fast */
            {
            	handle->siul_ptr->PCR[handle->id] |= SIUL_PCR_SRC_MASK;
            }
            break;

        default:
            return FALSE;
    }

    return TRUE;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_functionality
* Returned Value   : void
* Comments         :
*    Sets functionality (peripheral mode) of the pin
*
*END*********************************************************************/
void lwgpio_set_functionality
(
    /* Pin handle to set function on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Function to be set (integer value) */
    uint_32            function
)
{
    /* keep pin direction settings */
    handle->siul_ptr->PCR[handle->id] = (handle->siul_ptr->PCR[handle->id]&SIUL_PCR_DIR_MASK) | function;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_functionality
* Returned Value   : void
* Comments         :
*    Gets functionality (peripheral mode) of the pin
*
*END*********************************************************************/
uint_32 lwgpio_get_functionality
(
    /* Pin handle to get function from */
    LWGPIO_STRUCT_PTR  handle
)
{
    return handle->siul_ptr->PCR[handle->id];
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_direction
* Returned Value   : void
* Comments         :
*    Sets direction of the pin
*
*END*********************************************************************/
void lwgpio_set_direction
(
    /* Pin handle to set direction on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Direction to be set */
    LWGPIO_DIR         dir
)
{
    if (dir == LWGPIO_DIR_INPUT) {
        handle->siul_ptr->PCR[handle->id] = (handle->siul_ptr->PCR[handle->id] & ~SIUL_PCR_DIR_MASK) | SIUL_PCR_IBE_MASK;
    }
    else if (dir == LWGPIO_DIR_OUTPUT) {
        handle->siul_ptr->PCR[handle->id] = (handle->siul_ptr->PCR[handle->id] & ~SIUL_PCR_DIR_MASK) | SIUL_PCR_OBE_MASK;
    }
    else { /* LWGPIO_DIR_NOCHANGE or other value */
    }
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_value
* Returned Value   : void
* Comments         :
*    Sets value (output latch) of the pin
*
*END*********************************************************************/
void lwgpio_set_value
(
    /* Pin handle to set value on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Direction to be set */
    LWGPIO_VALUE       out_value
)
{
    if (out_value == LWGPIO_VALUE_LOW) {
        handle->siul_ptr->GPDO[handle->id] = 0;
    }
    else if (out_value == LWGPIO_VALUE_HIGH) {
        handle->siul_ptr->GPDO[handle->id] = 1;
    }
    else { /* LWGPIO_VALUE_NOCHANGE or other value */
    }
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_toggle_value
* Returned Value   : void
* Comments         :
*    Toggles value of output latch of the pin
*
*END*********************************************************************/
void lwgpio_toggle_value
(
    /* Pin handle to toggle value on */
    LWGPIO_STRUCT_PTR  handle
)
{
    handle->siul_ptr->GPDO[handle->id] = handle->siul_ptr->GPDO[handle->id] ^ 1;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_value
* Returned Value   : LWGPIO_VALUE of pin status
* Comments         :
*    Returns value (output latch or read data) of the pin
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_value
(
    /* Pin handle to get value from */
    LWGPIO_STRUCT_PTR  handle
)
{
    /* if the pin is set to output */
    if (handle->siul_ptr->PCR[handle->id] & SIUL_PCR_OBE_MASK)
        /* return value from the output latch */
        return (handle->siul_ptr->GPDO[handle->id] & 1) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
    else
        /* return value read from input */
        return (handle->siul_ptr->GPDI[handle->id] & 1) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_raw
* Returned Value   : LWGPIO_VALUE of pin status
* Comments         :
*    Returns read level of the pin
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_raw
(
    /* Pin handle to get value from */
    LWGPIO_STRUCT_PTR  handle
)
{
    return (handle->siul_ptr->GPDI[handle->id] & 1) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_init
* Returned Value   : TRUE if succesfull, FALSE otherwise
* Comments         :
*    Initializes pin to generate interrupt
*
*END*********************************************************************/
boolean lwgpio_int_init
(
    /* Pin handle to initialize interrupt on */
    LWGPIO_STRUCT_PTR handle,
    /* Interrupt mode */
    LWGPIO_INT_MODE   mode
)
{
    uint_32 eirq_mask;

    /* acquire eirq for pin, if necessary */
    if (handle->eirq < 0) handle->eirq=_bsp_siul_pin_to_eirq(handle->id);
    if (handle->eirq < 0) return FALSE; /* pin does not support irq */

    /* rising and falling edge supported only */
    if ((mode | LWGPIO_INT_MODE_RISING | LWGPIO_INT_MODE_FALLING) != (LWGPIO_INT_MODE_RISING | LWGPIO_INT_MODE_FALLING))
        return FALSE; /* requested mode not supported */

    eirq_mask = 1 << handle->eirq;

    if (mode & LWGPIO_INT_MODE_RISING)
        handle->siul_ptr->IREER |= eirq_mask;
    else 
        handle->siul_ptr->IREER &= ~eirq_mask;

    if (mode & LWGPIO_INT_MODE_FALLING)
        handle->siul_ptr->IFEER |= eirq_mask;
    else
        handle->siul_ptr->IFEER &= ~eirq_mask;

    return TRUE;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_enable
* Returned Value   : void
* Comments         :
*    Enables / disables interrupts for specified pin
*
*END*********************************************************************/
void lwgpio_int_enable
(
    /* Pin handle to enable interrupt on */
    LWGPIO_STRUCT_PTR handle,
    /* Enable or disable interrupt? TRUE = enable */
    boolean           ena
)
{
    uint_32 eirq_mask;

    /* acquire eirq for pin, if necessary */
    if (handle->eirq < 0) handle->eirq=_bsp_siul_pin_to_eirq(handle->id);
    if (handle->eirq < 0) return; /* pin does not support irq */

    eirq_mask = 1 << handle->eirq;

    if (ena) {
        /* enable pin interrupts */
        handle->siul_ptr->IRER |= eirq_mask;
    }
    else {
        /* disable pin interrupts */
        handle->siul_ptr->IRER &= ~eirq_mask;
    }
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_get_flag
* Returned Value   : TRUE if interrupt flag is set
* Comments         :
*    Checks if there is pending interrupt flag for specified pin
*
*END*********************************************************************/
boolean lwgpio_int_get_flag
(
    /* Pin handle to get interrupt flag on */
    LWGPIO_STRUCT_PTR handle
)
{
    uint_32 eirq_mask;

    /* acquire eirq for pin, if necessary */
    if (handle->eirq < 0) handle->eirq=_bsp_siul_pin_to_eirq(handle->id);
    if (handle->eirq < 0) return FALSE; /* pin does not support irq */

    eirq_mask = 1 << handle->eirq;

    return (handle->siul_ptr->ISR & eirq_mask) ? TRUE : FALSE;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_clear_flag
* Returned Value   : void
* Comments         :
*    Clears pending interrupt flag on peripheral
*
*END*********************************************************************/
void lwgpio_int_clear_flag
(
    /* Pin handle to clear interrupt flag on */
    LWGPIO_STRUCT_PTR handle
)
{
    uint_32 eirq_mask;

    /* acquire eirq for pin, if necessary */
    if (handle->eirq < 0) handle->eirq=_bsp_siul_pin_to_eirq(handle->id);
    if (handle->eirq < 0) return; /* pin does not support irq */

    eirq_mask = 1 << handle->eirq;

    handle->siul_ptr->ISR = eirq_mask;
}


/*FUNCTION****************************************************************
* 
* Function Name    : lwgpio_int_get_vector
* Returned Value   : pointer to base of GPIO registers
* Comments         :
*    This function returns the vector associated with the specified pin.
*
*END*********************************************************************/
uint_32 lwgpio_int_get_vector
(
    /* Pin handle to get vector of */
    LWGPIO_STRUCT_PTR  handle
)
{
    /* acquire eirq for pin, if necessary */
    if (handle->eirq < 0) handle->eirq=_bsp_siul_pin_to_eirq(handle->id);
    if (handle->eirq < 0) return 0; /* pin does not support irq */

    return _bsp_siul_int_get_vector(handle->eirq);
}


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_LowerLimit.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GFLIB_LowerLimit.h
* 
* @author    R29302
* 
* @version   1.0.1.0
* 
* @date      Dec-6-2012
* 
* @brief     Header file for the lower limit function.
*
*******************************************************************************
*
* Function impemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_LOWERLIMIT_H_
#define _GFLIB_LOWERLIMIT_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/************************************************************************
| defines and macros (scope: module-local)
|-----------------------------------------------------------------------*/

/*! 
 * \def GFLIB_LowerLimit(f32In, pParam)
 * Function alias for the #GFLIB_LowerLimitANSIC function.
 */
#define GFLIB_LowerLimit(f32In, pParam) GFLIB_LowerLimitANSIC((f32In), (pParam))

/************************************************************************
| typedefs and structures (scope: module-local)
|-----------------------------------------------------------------------*/

/*------------------------------------------------------------------------*//*!
@struct		GFLIB_LOWERLIMIT_T "\GFLIB_LowerLimitANSIC.h"

@brief		Structure containing the lower limit.

*//*-------------------------------------------------------------------------*/

typedef struct  
{    
  Frac32 f32LowerLimit;  /*!<Lower limit. */
} GFLIB_LOWERLIMIT_T;

/************************************************************************
| exported variables
|-----------------------------------------------------------------------*/

/************************************************************************
| exported function prototypes
|-----------------------------------------------------------------------*/

/*! 
* @ingroup GFLIB_GROUP 
*/
extern Frac32 GFLIB_LowerLimitANSIC(Frac32 f32In,
                                     const GFLIB_LOWERLIMIT_T *const pParam);

#ifdef __cplusplus
}
#endif
#endif /* _GFLIB_LOWERLIMIT_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/md5step.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: md5step.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the "C" implementation of
*   PPP_MD5_task_block.
*
*END************************************************************************/

#include <stdarg.h>
#include <ppp.h>
#include "ppp_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_MD5_block
* Returned Value  :  void
* Comments        :
*     Computes an incremental MD5 hash of a 16 word block.
*
*END*-----------------------------------------------------------------*/

#if defined(__DCC__) && defined(__ppc)
asm uint_32 rotl (uint_32 num, uint_32 bits)
{
% reg num; reg bits
   rotlw r3, num, bits
}
#else
#define rotl(num, bits) ((num << bits) | (num >> (32 - bits)))
#endif

void PPP_MD5_block
   (
      uint_32_ptr context,
            /* [IN/OUT] - the incremental hash */

      register uint_32_ptr block,
            /* [IN] - the 16 word block */

      register const uint_32 _PTR_ ctab
            /* [IN] - the sine function */
   )
{ /* Body */

#define F(x,y,z)  ((y&x)|(z&~x))
#define G(x,y,z)  ((x&z)|(y&~z))
#define H(x,y,z)  (x^y^z)
#define I(x,y,z)  (y^(x|~z))

#define P1(f,k,s) t=a+f(b,c,d)+block[k]+*ctab++; a=rotl(t,s)+b
#define P2(f,k,s) t=d+f(a,b,c)+block[k]+*ctab++; d=rotl(t,s)+a
#define P3(f,k,s) t=c+f(d,a,b)+block[k]+*ctab++; c=rotl(t,s)+d
#define P4(f,k,s) t=b+f(c,d,a)+block[k]+*ctab++; b=rotl(t,s)+c

   register uint_32  a = context[0];
   register uint_32  b = context[1];
   register uint_32  c = context[2];
   register uint_32  d = context[3];
   register uint_32  t;

   P1(F,  0,  7); P2(F,  1, 12); P3(F,  2, 17); P4(F,  3, 22);
   P1(F,  4,  7); P2(F,  5, 12); P3(F,  6, 17); P4(F,  7, 22);
   P1(F,  8,  7); P2(F,  9, 12); P3(F, 10, 17); P4(F, 11, 22);
   P1(F, 12,  7); P2(F, 13, 12); P3(F, 14, 17); P4(F, 15, 22);

   P1(G,  1,  5); P2(G,  6,  9); P3(G, 11, 14); P4(G,  0, 20);
   P1(G,  5,  5); P2(G, 10,  9); P3(G, 15, 14); P4(G,  4, 20);
   P1(G,  9,  5); P2(G, 14,  9); P3(G,  3, 14); P4(G,  8, 20);
   P1(G, 13,  5); P2(G,  2,  9); P3(G,  7, 14); P4(G, 12, 20);

   P1(H,  5,  4); P2(H,  8, 11); P3(H, 11, 16); P4(H, 14, 23);
   P1(H,  1,  4); P2(H,  4, 11); P3(H,  7, 16); P4(H, 10, 23);
   P1(H, 13,  4); P2(H,  0, 11); P3(H,  3, 16); P4(H,  6, 23);
   P1(H,  9,  4); P2(H, 12, 11); P3(H, 15, 16); P4(H,  2, 23);

   P1(I,  0,  6); P2(I,  7, 10); P3(I, 14, 15); P4(I,  5, 21);
   P1(I, 12,  6); P2(I,  3, 10); P3(I, 10, 15); P4(I,  1, 21);
   P1(I,  8,  6); P2(I, 15, 10); P3(I,  6, 15); P4(I, 13, 21);
   P1(I,  4,  6); P2(I, 11, 10); P3(I,  2, 15); P4(I,  9, 21);

   context[0] += a;
   context[1] += b;
   context[2] += c;
   context[3] += d;

   PPP_memzero(block, sizeof(uint_32[16]));

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/event.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: event.c$
 * $Version : 3.8.2.0$
 * $Date    : Jun-25-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Event component.
 *
 *END************************************************************************/

#include <string.h>
#include "mqx_inc.h"
#if MQX_USE_EVENTS
#include "name.h"
#include "name_prv.h"
#include "event.h"
#include "event_prv.h"
#include "mqx_str.h"
#include "message.h"
#include "msg_prv.h"
#if MQX_USE_IPC
#include "ipc.h"
#include "ipc_prv.h"
#endif
/*!
 * \brief Wait for all the specified event bits to be set in the event group for
 * the specified number of milliseconds.
 * 
 * \param[in] users_event_ptr An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask        Each set bit represents an event bit to wait for.
 * \param[in] timeout         The maximum number of milliseconds to wait for the 
 * events to be set. If the value is 0, then the timeout will be infinite.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)
 * 
 * \warning Blocks until the event combination is set or until the timeout expires.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until                    
 */ 
_mqx_uint _event_wait_all
(
    pointer   users_event_ptr,
    _mqx_uint bit_mask,
    uint_32   timeout
)
{ /* Body */
    /* TIME_STRUCT                 time; */
    MQX_TICK_STRUCT ticks;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_event_wait_all, users_event_ptr, bit_mask, timeout);

    if (timeout)
    {
        /* Convert milliseconds to ticks */
        /* time.MILLISECONDS = timeout % 1000; */
        /* time.SECONDS      = timeout / 1000; */
        /*                                     */
        /* PSP_TIME_TO_TICKS(&time, &ticks);   */
        PSP_MILLISECONDS_TO_TICKS_QUICK(timeout, &ticks);

        result = _event_wait_internal(users_event_ptr, bit_mask, &ticks, FALSE, TRUE);
    }
    else
    {
        result = _event_wait_internal(users_event_ptr, bit_mask, NULL, FALSE, TRUE);
    } /* Endif */

    _KLOGX2(KLOG_event_wait_all, result);
    return (result);

} /* Endbody */

/*!
 * \brief Wait for all the specified event bits to be set in the event group for
 * the specified number of ticks (in tick time).
 * 
 * \param[in] users_event_ptr An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask        Each set bit represents an event bit to wait for.
 * \param[in] tick_ptr        The maximum number of ticks to wait for the events
 * to be set. If the value is NULL, then the timeout will be infinite.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)
 * 
 * \warning Blocks until the event combination is set or until the timeout expires.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_wait_all
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until                    
 */
_mqx_uint _event_wait_all_for
(
    pointer             users_event_ptr,
    _mqx_uint           bit_mask,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_event_wait_all_for, users_event_ptr, bit_mask, tick_ptr);

    result = _event_wait_internal(users_event_ptr, bit_mask, tick_ptr, FALSE, TRUE);

    _KLOGX2(KLOG_event_wait_all_for, result);
    return (result);

} /* Endbody */

/*!
 * \brief Wait for all the specified event bits to be set in the event group for
 * the specified number of ticks.
 * 
 * \param[in] users_event_ptr  An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask         Each set bit represents an event bit to wait for.
 * \param[in] timeout_in_ticks The maximum number of ticks to wait for the events
 * to be set. If the value is 0, then the timeout will be infinite.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)
 * 
 * \warning Blocks until the event combination is set or until the timeout expires.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_until
 * \see _event_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until                    
 */
_mqx_uint _event_wait_all_ticks
(
    pointer   users_event_ptr,
    _mqx_uint bit_mask,
    _mqx_uint timeout_in_ticks
)
{ /* Body */
    MQX_TICK_STRUCT ticks;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_event_wait_all_ticks, users_event_ptr, bit_mask,
                    timeout_in_ticks);

    if (!timeout_in_ticks)
    {
        result = _event_wait_internal(users_event_ptr, bit_mask, NULL, FALSE, TRUE);
    }
    else
    {
        ticks = _mqx_zero_tick_struct;

        PSP_ADD_TICKS_TO_TICK_STRUCT(&ticks, timeout_in_ticks, &ticks);
        result = _event_wait_internal(users_event_ptr, bit_mask, &ticks, FALSE, TRUE);
    } /* Endif */

    _KLOGX2(KLOG_event_wait_all_ticks, result);
    return (result);

} /* Endbody */

/*!
 * \brief Wait for all the specified event bits to be set in the event group 
 * until the specified time (in tick time).
 * 
 * \param[in] users_event_ptr An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask        Each set bit represents an event bit to wait for.
 * \param[in] tick_ptr        The time to wait until, in ticks, for the events 
 * to be set. If the value is NULL, then the timeout will be infinite.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)
 * 
 * \warning Blocks until the event combination is set or until the timeout expires.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until                    
 */
_mqx_uint _event_wait_all_until
(
    pointer users_event_ptr,
    _mqx_uint bit_mask,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_event_wait_all_until, users_event_ptr, bit_mask, tick_ptr);

    result = _event_wait_internal(users_event_ptr, bit_mask, tick_ptr, TRUE, TRUE);

    _KLOGX2(KLOG_event_wait_all_until, result);
    return (result);

} /* Endbody */

/*!
 * \brief Wait for any of the specified event bits to be set in the event group 
 * for the specified number of milliseconds.
 * 
 * \param[in] users_event_ptr An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask        Each set bit represents an event bit to wait for.
 * \param[in] timeout         The maximum number of milliseconds to wait for the 
 * events to be set. If the value is 0, then the timeout will be infinite.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)
 *  
 * \warning Blocks until the event combination is set or until the timeout expires.
 * \warning Cannot be called from an ISR. 
 *  
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until 
 * \see _event_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until        
 */  
_mqx_uint _event_wait_any
(
    pointer users_event_ptr,
    _mqx_uint bit_mask,
    uint_32 timeout
)
{ /* Body */
    /* TIME_STRUCT                    time; */
    MQX_TICK_STRUCT ticks;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_event_wait_any, users_event_ptr, bit_mask, timeout);

    if (timeout)
    {
        /* Convert milliseconds to ticks */
        /* time.MILLISECONDS = timeout % 1000; */
        /* time.SECONDS      = timeout / 1000; */
        /*                                     */
        /* PSP_TIME_TO_TICKS(&time, &ticks);   */
        PSP_MILLISECONDS_TO_TICKS_QUICK(timeout, &ticks);

        result = _event_wait_internal(users_event_ptr, bit_mask, &ticks, FALSE, FALSE);
    }
    else
    {
        result = _event_wait_internal(users_event_ptr, bit_mask, NULL, FALSE, FALSE);
    } /* Endif */

    _KLOGX2(KLOG_event_wait_any, result);
    return (result);

} /* Endbody */

/*!
 * \brief Wait for any of the specified event bits to be set in the event group 
 * for the specified number of milliseconds.
 * 
 * \param[in] users_event_ptr An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask        Each set bit represents an event bit to wait for.
 * \param[in] tick_ptr        The maximum number of ticks to wait for the events
 * to be set. If the value is 0, then the timeout will be infinite.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)
 *  
 * \warning Blocks until the event combination is set or until the timeout expires.
 * \warning Cannot be called from an ISR. 
 *  
 * \see _event_wait_any
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until 
 * \see _event_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until        
 */
_mqx_uint _event_wait_any_for
(
    pointer users_event_ptr,
    _mqx_uint bit_mask,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_event_wait_any_for, users_event_ptr, bit_mask, tick_ptr);

    result = _event_wait_internal(users_event_ptr, bit_mask, tick_ptr, FALSE, FALSE);

    _KLOGX2(KLOG_event_wait_any_for, result);
    return (result);

} /* Endbody */

/*!
 * \brief Wait for any of the specified event bits to be set in the event group 
 * for the number of ticks.
 * 
 * \param[in] users_event_ptr  An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask         Each set bit represents an event bit to wait for.
 * \param[in] timeout_in_ticks The maximum number of ticks to wait for the events 
 * to be set. If the value is 0, then the timeout will be infinite.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)
 *  
 * \warning Blocks until the event combination is set or until the timeout expires.
 * \warning Cannot be called from an ISR. 
 *  
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_until 
 * \see _event_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until        
 */
_mqx_uint _event_wait_any_ticks
(
    pointer users_event_ptr,
    _mqx_uint bit_mask,
    _mqx_uint timeout_in_ticks
)
{ /* Body */
    MQX_TICK_STRUCT ticks;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_event_wait_any_ticks, users_event_ptr, bit_mask,
                    timeout_in_ticks);

    if (timeout_in_ticks)
    {
        ticks = _mqx_zero_tick_struct;

        PSP_ADD_TICKS_TO_TICK_STRUCT(&ticks, timeout_in_ticks, &ticks);
        result = _event_wait_internal(users_event_ptr, bit_mask, &ticks, FALSE, FALSE);
    }
    else
    {
        result = _event_wait_internal(users_event_ptr, bit_mask, NULL, FALSE, FALSE);
    } /* Endif */

    _KLOGX2(KLOG_event_wait_any_ticks, result);
    return (result);

} /* Endbody */

/*!
 * \brief Wait for any of the specified event bits to be set in the event group 
 * until the specified time (in tick time).
 * 
 * \param[in] users_event_ptr An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask        Each set bit represents an event bit to wait for.
 * \param[in] tick_ptr        The time in ticks to wait for the events to be set. 
 * If the value is NULL, then the timeout will be infinite.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)
 *  
 * \warning Blocks until the event combination is set or until the timeout expires.
 * \warning Cannot be called from an ISR. 
 *  
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks 
 * \see _event_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until        
 */
_mqx_uint _event_wait_any_until
(
    pointer users_event_ptr,
    _mqx_uint bit_mask,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_event_wait_any_until, users_event_ptr, bit_mask, tick_ptr);

    result = _event_wait_internal(users_event_ptr, bit_mask, tick_ptr, TRUE, FALSE);

    _KLOGX2(KLOG_event_wait_any_until, result);
    return (result);

} /* Endbody */

/*! 
 * \brief Clears the specified event bits in an event group.
 * 
 * \param[in] users_event_ptr An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * \param[in] bit_mask        Each set bit represents an event bit to clear.
 * 
 * \return MQX_OK
 * \return EVENT_INVALID_EVENT_HANDLE (_event_open() or _event_open_fast() did 
 * not get the event group handle or _event_create() did not create the event 
 * group.)
 * \return EVENT_INVALID_EVENT (Event group is not valid.)
 * 
 * \see _event_create
 * \see _event_create_auto_clear
 * \see _event_open
 * \see _event_open_fast
 * \see _event_set
 * \see _event_get_value
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until 
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until          
 */  
_mqx_uint _event_clear
(
    pointer users_event_ptr,
    _mqx_uint bit_mask
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    register EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
    register EVENT_STRUCT_PTR            event_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_event_clear, users_event_ptr, bit_mask);
    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) users_event_ptr;

#if MQX_CHECK_VALIDITY
    if (event_connection_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_clear, EVENT_INVALID_EVENT_HANDLE);
        return (EVENT_INVALID_EVENT_HANDLE);
    } /* Endif */
#endif

    _INT_DISABLE();
    event_ptr = event_connection_ptr->EVENT_PTR;

#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != EVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_event_clear, EVENT_INVALID_EVENT);
        return (EVENT_INVALID_EVENT);
    } /* Endif */
#endif

    event_ptr->EVENT &= ~bit_mask;
    _INT_ENABLE();

    _KLOGX2(KLOG_event_clear, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Closes connection to the event group.
 * 
 * The function closes the connection to the event group and frees the event 
 * group handle.
 * \n A task that opened an event group on a remote processor can also close the 
 * event group.
 *   
 * \param[in] users_event_ptr An event handle returned from a call to _event_open() 
 * or _event_open_fast().
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Event group connection is not valid.)
 * \return Task error code from _mem_free() (MQX could not free the event group handle.)
 * 
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_destroy
 * \see _event_open
 * \see _event_open_fast         
 */  
_mqx_uint _event_close
(
    pointer users_event_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    register EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_event_close, users_event_ptr);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_event_close, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) users_event_ptr;
#if MQX_CHECK_VALIDITY
    if (event_connection_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_close, EVENT_INVALID_EVENT_HANDLE);
        return (EVENT_INVALID_EVENT_HANDLE);
    } /* Endif */

#endif

    event_connection_ptr->VALID = 0;

    if (_mem_free(event_connection_ptr) != MQX_OK)
    {
        _KLOGX2(KLOG_event_close, kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
        return (kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
    }
    else
    {
        _KLOGX2(KLOG_event_close, MQX_OK);
        return (MQX_OK);
    } /* Endif */

} /* Endbody */

 /*!
  * \brief Creates the event component so that other tasks may create and use 
  * events.
  * 
  * If an application previously called the function and maximum_number is now 
  * greater that what was previously specified, MQX changes the maximum number 
  * of event groups to maximum_number.
  * \n If an application does not explicitly create the event component, MQX does 
  * so with the following default values the first time that a task calls a 
  * function in the _event_create family of functions.
  * \n Parameter default values:
  * \li Initial_number = 8(default)
  * \li Grow_number = 8(default)
  * \li Maximum_number = 0(unlimited)
  * 
  * \param[in] initial_number Initial number of event groups that the application 
  * can create.
  * \param[in] grow_number Number of event groups to add if the application 
  * creates all the event groups
  * \param[in] maximum_number If grow_number is non-zero, maximum number of event 
  * groups (0 means an unlimited number)
  * 
  * \return MQX_OK
  * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
  * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event group.)
  * 
  * \see _event_create
  * \see _event_create_auto_clear
  * \see _event_create_fast
  * \see _event_create_fast_auto_clear
  * \see _event_open
  * \see _event_open_fast                                         
  */  
_mqx_uint _event_create_component
(
    _mqx_uint initial_number,
    _mqx_uint grow_number,
    _mqx_uint maximum_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    register EVENT_COMPONENT_STRUCT_PTR event_component_ptr;
    _mqx_uint                           result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_event_create_component, initial_number, grow_number, maximum_number);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_event_create_component, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    _lwsem_wait((LWSEM_STRUCT_PTR) (&kernel_data->COMPONENT_CREATE_LWSEM));

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
    if (event_component_ptr != NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR) (&kernel_data->COMPONENT_CREATE_LWSEM));
        _KLOGX2(KLOG_event_create_component, MQX_OK);
        return (MQX_OK);
    } /* Endif */

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) _mem_alloc_system_zero(
                    (_mem_size) sizeof(EVENT_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (event_component_ptr == NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR) (&kernel_data->COMPONENT_CREATE_LWSEM));
        _KLOGX2(KLOG_event_create_component, MQX_OUT_OF_MEMORY);
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(event_component_ptr, MEM_TYPE_EVENT_COMPONENT);

    result = _name_create_handle_internal(&event_component_ptr->NAME_TABLE_HANDLE, initial_number, grow_number,
                    maximum_number, initial_number);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        _lwsem_post((LWSEM_STRUCT_PTR) (&kernel_data->COMPONENT_CREATE_LWSEM));
        _mem_free(event_component_ptr);
        _KLOGX2(KLOG_event_create_component, result);
        return (result);
    } /* Endif */
#endif
    event_component_ptr->VALID = EVENT_VALID;
    event_component_ptr->GROW_NUMBER = grow_number;
    if (maximum_number == 0)
    {
        event_component_ptr->MAXIMUM_NUMBER = MAX_MQX_UINT;
    }
    else if (maximum_number < initial_number)
    {
        event_component_ptr->MAXIMUM_NUMBER = initial_number;
    }
    else
    {
        event_component_ptr->MAXIMUM_NUMBER = maximum_number;
    } /* Endif */

    kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS] = event_component_ptr;

#if MQX_COMPONENT_DESTRUCTION
    kernel_data->COMPONENT_CLEANUP[KERNEL_EVENTS] = _event_cleanup;
#endif

    _lwsem_post((LWSEM_STRUCT_PTR) (&kernel_data->COMPONENT_CREATE_LWSEM));

    _KLOGX2(KLOG_event_create_component, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Creates the named event group with autoclearing event bits.
 * 
 * After a task creates a named event group, any task that wants to use it must 
 * open a connection to it with _event_open(). When a task no longer needs a 
 * named event group, it can destroy the event group with _event_destroy().
 * \n When a task creates an event group with autoclearing event bits, MQX clears 
 * the event bits as soon as they are set. Tasks that are waiting for the event 
 * bits are made ready, but need not to clear the bits.
 * 
 * \param[in] name_ptr Pointer to the name of the event group.
 * 
 * \return MQX_OK 
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event group.)
 * \return EVENT_EXISTS (Event group was already created.)
 * \return EVENT_TABLE_FULL (Name table is full and cannot be expanded.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Event component was not created.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * 
 * \warning Creates the event component with default values if it was not 
 * previously created.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_create
 * \see _event_close
 * \see _event_create_component
 * \see _event_destroy
 * \see _event_open           
 */  
_mqx_uint _event_create_auto_clear
(
    char _PTR_ name_ptr
)
{ /* Body */
    EVENT_STRUCT_PTR event_ptr;
    _mqx_uint        result;

    result = _event_create_internal(name_ptr, &event_ptr);

#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        return (result);
    } /* Endif */
#endif

    event_ptr->AUTO_CLEAR = TRUE;

    return (result);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Used internally to create an instance of an event.
 * 
 * \param[in]  name_ptr      Pointer to the name of the event group.
 * \param[out] event_ptr_ptr Where the event pointer is.
 * 
 * \return MQX_OK 
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event group.)
 * \return EVENT_EXISTS (Event group was already created.)
 * \return EVENT_TABLE_FULL (Name table is full and cannot be expanded.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Event component was not created.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * 
 * \warning Creates the event component with default values if it was not 
 * previously created.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_create
 * \see _event_create_auto_clear          
 */
_mqx_uint _event_create_internal
(
    char _PTR_             name_ptr,
    EVENT_STRUCT_PTR _PTR_ event_ptr_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    register EVENT_COMPONENT_STRUCT_PTR event_component_ptr;
    register EVENT_STRUCT_PTR           event_ptr;
    _mqx_uint                           result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_event_create, name_ptr);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_event_create, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
    if (event_component_ptr == NULL)
    {
        result = _event_create_component(EVENT_DEFAULT_INITIAL_NUMBER, EVENT_DEFAULT_GROW_NUMBER,
                        EVENT_DEFAULT_MAXIMUM_NUMBER);
        event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (event_component_ptr == NULL)
        {
            _KLOGX2(KLOG_event_create, result);
            return (result);
        } /* Endif */
#endif
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (event_component_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_create, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    event_ptr = (EVENT_STRUCT_PTR) _mem_alloc_system_zero((_mem_size) sizeof(EVENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (event_ptr == NULL)
    {
        _KLOGX2(KLOG_event_create, MQX_OUT_OF_MEMORY);
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(event_ptr, MEM_TYPE_EVENT);

    _QUEUE_INIT(&event_ptr->WAITING_TASKS, EVENT_MAX_WAITING_TASKS);

    strncpy(event_ptr->NAME, name_ptr, (_mqx_uint) NAME_MAX_NAME_SIZE - 1);
    event_ptr->NAME[NAME_MAX_NAME_SIZE - 1] = '\0';
    result = _name_add_internal(event_component_ptr->NAME_TABLE_HANDLE, event_ptr->NAME, (_mqx_uint) event_ptr);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        _mem_free(event_ptr);
        if (result == NAME_EXISTS)
        {
            _KLOGX2(KLOG_event_create, EVENT_EXISTS);
            return (EVENT_EXISTS);
        }
        else if (result == NAME_TABLE_FULL)
        {
            _KLOGX2(KLOG_event_create, EVENT_TABLE_FULL);
            return (EVENT_TABLE_FULL);
        } /* Endif */
        _KLOGX2(KLOG_event_create, result);
        return (result);
    } /* Endif */
#endif
    event_ptr->VALID = EVENT_VALID;

    *event_ptr_ptr = event_ptr;

    _KLOGX2(KLOG_event_create, result);
    return (result);

} /* Endbody */

/*!
 * \brief Creates the named event group.
 * 
 * After a task creates a named event group, any task that wants to use it must 
 * open a connection to it with _event_open(). When a task no longer needs a 
 * named event group, it can destroy the event group with _event_destroy().
 * 
 * \param[in] name_ptr Pointer to the name of the event group.
 * 
 * \return MQX_OK 
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event group.)
 * \return EVENT_EXISTS (Event group was already created.)
 * \return EVENT_TABLE_FULL (Name table is full and cannot be expanded.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Event component was not created.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * 
 * \warning Creates the event component with default values if it was not 
 * previously created.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_create_auto_clear
 * \see _event_close
 * \see _event_create_component
 * \see _event_destroy
 * \see _event_open      
 */ 
_mqx_uint _event_create
(
    char _PTR_ name_ptr
)
{ /* Body */
    EVENT_STRUCT_PTR event_ptr;
    _mqx_uint        result;

    result = _event_create_internal(name_ptr, &event_ptr);

#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        return (result);
    } /* Endif */
#endif

    event_ptr->AUTO_CLEAR = FALSE;

    return (result);

} /* Endbody */

/*!
 * \brief Used by a task to destroy an instance of an event.
 * 
 * The event group must have been created with _event_create() or 
 * _event_create_auto_clear().
 * \n If tasks are blocked waiting for an event bit in the event group, MQX does 
 * the following:
 * \n - Moves them to their ready queues.
 * \n - Sets their task error code to EVENT_DELETED.
 * \n - Returns EVENT_DELETED for _event_wait_all() and _event_wait_any().
 * 
 * \param[in] name_ptr Pointer to the name of the event group.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Event component was not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return EVENT_NOT_FOUND (Name is not in the names database.)
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)   
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.) 
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * 
 * \warning Cannot be called from an ISR
 * 
 * \see _event_create
 * \see _event_create_auto_clear
 * \see _event_create_component
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until                  
 */ 
_mqx_uint _event_destroy
(
    char _PTR_ name_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    register EVENT_COMPONENT_STRUCT_PTR event_component_ptr;
    EVENT_STRUCT_PTR                    event_ptr;
    EVENT_CONNECTION_STRUCT_PTR         event_connection_ptr;
    QUEUE_STRUCT_PTR                    queue_ptr;
    TD_STRUCT_PTR                       td_ptr;
    _mqx_uint                           result;
    _mqx_uint                           i;
    _mqx_max_type                       tmp;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_event_destroy, name_ptr);

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_event_destroy, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
    if (event_component_ptr == NULL)
    {
        _KLOGX2(KLOG_event_destroy, MQX_COMPONENT_DOES_NOT_EXIST);
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (event_component_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_destroy, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    result = _name_find_internal(event_component_ptr->NAME_TABLE_HANDLE, name_ptr, &tmp);

#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        if (result == NAME_NOT_FOUND)
        {
            _KLOGX2(KLOG_event_destroy, EVENT_NOT_FOUND);
            return (EVENT_NOT_FOUND);
        } /* Endif */
        _KLOGX2(KLOG_event_destroy, result);
        return (result);
    } /* Endif */
#endif

    event_ptr = (EVENT_STRUCT_PTR) tmp;
    queue_ptr = &event_ptr->WAITING_TASKS;

    _int_disable();
    if (event_ptr->VALID != EVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_event_destroy, EVENT_INVALID_EVENT);
        return (EVENT_INVALID_EVENT);
    } /* Endif */

    /* Effectively stop all access to the event */
    event_ptr->VALID = 0;

    /* Ready all waiting tasks */
    i = _QUEUE_GET_SIZE(queue_ptr) + 1;
    while (--i)
    {
        event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) ((pointer) queue_ptr->NEXT);
        td_ptr = event_connection_ptr->TD_PTR;
        if ((td_ptr->STATE & STATE_MASK) == EVENT_BLOCKED)
        {
            _TIME_DEQUEUE(td_ptr, kernel_data);
            _task_set_error_td_internal(td_ptr, EVENT_DELETED);
            _TASK_READY(td_ptr,kernel_data);
        } /* Endif */
    } /* Endwhile */

    _int_enable();

    result = _name_delete_internal(event_component_ptr->NAME_TABLE_HANDLE, name_ptr);
#if MQX_CHECK_ERRORS
    if (result == NAME_NOT_FOUND)
    {
        result = EVENT_NOT_FOUND;
    } /* Endif */
#endif

    _mem_free(event_ptr);

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();

    _KLOGX2(KLOG_event_destroy, result);
    return (result);

} /* Endbody */

/*!
 * \brief Creates an instance of a numbered (NOT named) event.
 * 
 * After a task creates a named event group, any task that wants to use it must 
 * open a connection to it with _event_open_fast(). When a task no longer needs a 
 * named event group, it can destroy the event group with _event_destroy_fast().
 * 
 * \param[in] event_index The event group number.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event group.)
 * \return EVENT_EXISTS (Event group was already created.)
 * \return EVENT_TABLE_FULL (Name table is full and cannot be expanded.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 *  
 * \warning Creates the event component with default values if they were not 
 * previously created.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_create_fast_auto_clear
 * \see _event_close
 * \see _event_create
 * \see _event_create_auto_clear
 * \see _event_create_component
 * \see _event_destroy_fast
 * \see _event_open_fast           
 */  
_mqx_uint _event_create_fast
(
    _mqx_uint event_index
)
{ /* Body */
    EVENT_STRUCT_PTR event_ptr;
    _mqx_uint        result;

    result = _event_create_fast_internal(event_index, &event_ptr);

#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        return (result);
    } /* Endif */
#endif

    event_ptr->AUTO_CLEAR = FALSE;

    return (result);

} /* Endbody */

/*!
 * \brief Creates an instance of a numbered (NOT named) event with autoclearing
 * event bits.
 * 
 * After a task creates a named event group, any task that wants to use it must 
 * open a connection to it with _event_open_fast(). When a task no longer needs 
 * a named event group, it can destroy the event group with _event_destroy_fast().
 * \n If a task creates an event group with autoclearing event bits, MQX clears 
 * the event bits as soon as they are set. Task that are waiting for the event 
 * bits are made ready, but need not clear the bits.
 * 
 * \param[in] event_index The event group number.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event group.)
 * \return EVENT_EXISTS (Event group was already created.)
 * \return EVENT_TABLE_FULL (Name table is full and cannot be expanded.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * 
 * \warning Creates the event component with default values if they were not 
 * previously created.
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_create_fast
 * \see _event_close
 * \see _event_create
 * \see _event_create_auto_clear
 * \see _event_create_component
 * \see _event_destroy_fast
 * \see _event_open_fast           
 */ 
_mqx_uint _event_create_fast_auto_clear
(
    _mqx_uint event_index
)
{ /* Body */
    EVENT_STRUCT_PTR event_ptr;
    _mqx_uint        result;

    result = _event_create_fast_internal(event_index, &event_ptr);

#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        return (result);
    } /* Endif */
#endif

    event_ptr->AUTO_CLEAR = TRUE;

    return (result);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Used internally to create an instance of a numbered (NOT named) event.
 * 
 * \param[in]  event_index   The event number to initialize.
 * \param[out] event_ptr_ptr Pointer to event.
 *     
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event group.)
 * \return EVENT_EXISTS (Event group was already created.)
 * \return EVENT_TABLE_FULL (Name table is full and cannot be expanded.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * 
 * \see _event_create_fast
 * \see _event_create_fast_auto_clear          
 */ 
_mqx_uint _event_create_fast_internal
(
    _mqx_uint event_index,
    EVENT_STRUCT_PTR _PTR_ event_ptr_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    register EVENT_COMPONENT_STRUCT_PTR event_component_ptr;
    register EVENT_STRUCT_PTR           event_ptr;
    _mqx_uint                           result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_event_create_fast, event_index);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_event_create_fast, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
    if (event_component_ptr == NULL)
    {
        result = _event_create_component(EVENT_DEFAULT_INITIAL_NUMBER, EVENT_DEFAULT_GROW_NUMBER,
                        EVENT_DEFAULT_MAXIMUM_NUMBER);
        event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (event_component_ptr == NULL)
        {
            _KLOGX2(KLOG_event_create_fast, result);
            return (result);
        } /* Endif */
#endif
    } /* Endif */

#if MQX_CHECK_ERRORS
    if (event_component_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_create_fast, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    event_ptr = (EVENT_STRUCT_PTR) _mem_alloc_system_zero((_mem_size) sizeof(EVENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (event_ptr == NULL)
    {
        _KLOGX2(KLOG_event_create_fast, MQX_OUT_OF_MEMORY);
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(event_ptr, MEM_TYPE_EVENT);

    _QUEUE_INIT(&event_ptr->WAITING_TASKS, EVENT_MAX_WAITING_TASKS);

    _str_mqx_uint_to_hex_string(event_index, event_ptr->NAME);

    result = _name_add_internal_by_index(event_component_ptr->NAME_TABLE_HANDLE, event_ptr->NAME,
                    (_mqx_uint) event_ptr, event_index);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        _mem_free(event_ptr);
        if (result == NAME_EXISTS)
        {
            _KLOGX2(KLOG_event_create_fast, EVENT_EXISTS);
            return (EVENT_EXISTS);
        }
        else if (result == NAME_TABLE_FULL)
        {
            _KLOGX2(KLOG_event_create_fast, EVENT_TABLE_FULL);
            return (EVENT_TABLE_FULL);
        } /* Endif */
        _KLOGX2(KLOG_event_create_fast, result);
        return (result);
    } /* Endif */
#endif

    event_ptr->VALID = EVENT_VALID;

    *event_ptr_ptr = event_ptr;

    _KLOGX2(KLOG_event_create_fast, result);
    return (result);

} /* Endbody */

/*!
 * \brief Used by a task to destroy instance of an event using an index.
 * 
 * The event group must have been created with _event_create_fast() or 
 * _event_create_fast_auto_clear().
 * \n If tasks are blocked waiting for an event bit in the event group, MQX does 
 * the following:
 * \n - Moves them to their ready queues.
 * \n - Sets their task error code to EVENT_DELETED.
 * \n - Returns EVENT_DELETED for _event_wait_all() and _event_wait_any().
 * 
 * \param[in] event_index Index of an event to destroy.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Event component was not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return EVENT_NOT_FOUND (Name is not in the names database.)
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)   
 * 
 * \warning Cannot be called from an ISR.
 * 
 * \see _event_create_component
 * \see _event_create_fast
 * \see _event_create_fast_auto_clear          
 */ 
_mqx_uint _event_destroy_fast
(
    _mqx_uint event_index
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    register EVENT_COMPONENT_STRUCT_PTR event_component_ptr;
    EVENT_STRUCT_PTR                    event_ptr;
    EVENT_CONNECTION_STRUCT_PTR         event_connection_ptr;
    QUEUE_STRUCT_PTR                    queue_ptr;
    TD_STRUCT_PTR                       td_ptr;
    _mqx_uint                           result;
    _mqx_uint                           i;
    _mqx_max_type                       tmp;
#if MQX_CHECK_ERRORS
    char name[9];
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_event_destroy_fast, event_index);

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_event_destroy_fast, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
    if (event_component_ptr == NULL)
    {
        _KLOGX2(KLOG_event_destroy_fast, MQX_COMPONENT_DOES_NOT_EXIST);
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (event_component_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_destroy_fast, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    result = _name_find_internal_by_index(event_component_ptr->NAME_TABLE_HANDLE, event_index, &tmp);
    event_ptr = (EVENT_STRUCT_PTR) tmp;
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        if (result == NAME_NOT_FOUND)
        {
            _KLOGX2(KLOG_event_destroy_fast, EVENT_NOT_FOUND);
            return (EVENT_NOT_FOUND);
        } /* Endif */
        _KLOGX2(KLOG_event_destroy_fast, result);
        return (result);
    } /* Endif */

    /* event_ptr = (EVENT_STRUCT_PTR)tmp; */
    _str_mqx_uint_to_hex_string(event_index, name);
    if (strncmp(name, event_ptr->NAME, 8))
    {
        /* Name does not match */
        _KLOGX2(KLOG_event_destroy_fast, EVENT_NOT_FOUND);
        return (EVENT_NOT_FOUND);
    } /* Endif */
#endif

    queue_ptr = &event_ptr->WAITING_TASKS;

    _int_disable();
    if (event_ptr->VALID != EVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_event_destroy_fast, EVENT_INVALID_EVENT);
        return (EVENT_INVALID_EVENT);
    } /* Endif */

    /* Effectively stop all access to the event */
    event_ptr->VALID = 0;

    /* Ready all waiting tasks */
    i = _QUEUE_GET_SIZE(queue_ptr) + 1;
    while (--i)
    {
        event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) ((pointer) queue_ptr->NEXT);
        td_ptr = event_connection_ptr->TD_PTR;
        if ((td_ptr->STATE & STATE_MASK) == EVENT_BLOCKED)
        {
            _TIME_DEQUEUE(td_ptr, kernel_data);
            _task_set_error_td_internal(td_ptr, EVENT_DELETED);
            _TASK_READY(td_ptr,kernel_data);
        } /* Endif */
    } /* Endwhile */

    _int_enable();

    result = _name_delete_internal_by_index(event_component_ptr->NAME_TABLE_HANDLE, event_index);
#if MQX_CHECK_ERRORS
    if (result == NAME_NOT_FOUND)
    {
        result = EVENT_NOT_FOUND;
    } /* Endif */
#endif

    _mem_free(event_ptr);

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();

    _KLOGX2(KLOG_event_destroy_fast, result);
    return (result);

} /* Endbody */

/*!
 * \brief Opens a connection to the indexed event group.
 * 
 * The indexed event group must have been created with _event_create_fast() or 
 * _event_create_fast_auto_clear(). Each task that needs access to the indexed 
 * event group must first open a connection to it.
 * 
 * \param[in]  event_index        Index of the event group to gain access to.
 * \param[out] returned_event_ptr Where to write the event group handle (NULL is 
 * written if an error occurred).
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Event component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event 
 * connection data.)
 * \return EVENT_INVALID_EVENT (Event group data is no longer valid.)
 * \return EVENT_NOT_FOUND (Named event group is not in the name table.)
 * 
 * \see _event_close
 * \see _event_create_fast
 * \see _event_create_fast_auto_clear
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_all
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until                    
 */ 
_mqx_uint _event_open_fast
(
    _mqx_uint event_index,
    pointer _PTR_ returned_event_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    register EVENT_COMPONENT_STRUCT_PTR  event_component_ptr;
    EVENT_STRUCT_PTR                     event_ptr;
    register EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
    _mqx_uint                            result;
    _mqx_max_type                        tmp;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_event_open_fast, event_index, returned_event_ptr);

    *returned_event_ptr = NULL;

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
#if MQX_CHECK_ERRORS
    if (event_component_ptr == NULL)
    {
        _KLOGX2(KLOG_event_open_fast, MQX_COMPONENT_DOES_NOT_EXIST);
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (event_component_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_open_fast, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    result = _name_find_internal_by_index(event_component_ptr->NAME_TABLE_HANDLE, event_index, &tmp);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        if (result == NAME_NOT_FOUND)
        {
            _KLOGX2(KLOG_event_open_fast, EVENT_NOT_FOUND);
            return (EVENT_NOT_FOUND);
        } /* Endif */
        _KLOGX2(KLOG_event_open_fast, result);
        return (result);
    } /* Endif */
#endif

    event_ptr = (EVENT_STRUCT_PTR) tmp;

#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != EVENT_VALID)
    {
        /* Event not valid */
        _KLOGX2(KLOG_event_open_fast, EVENT_INVALID_EVENT);
        return (EVENT_INVALID_EVENT);
    } /* Endif */
#endif

    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) _mem_alloc_zero((_mem_size) sizeof(EVENT_CONNECTION_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (event_connection_ptr == NULL)
    {
        _KLOGX2(KLOG_event_open_fast, MQX_OUT_OF_MEMORY);
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(event_connection_ptr, MEM_TYPE_EVENT_CONNECTION);

    event_connection_ptr->EVENT_PTR = event_ptr;
    event_connection_ptr->VALID = EVENT_VALID;
    event_connection_ptr->TD_PTR = kernel_data->ACTIVE_PTR;

    *returned_event_ptr = (pointer) event_connection_ptr;

    _KLOGX3(KLOG_event_open_fast, MQX_OK, event_connection_ptr);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Opens a connection to the named event group.
 * 
 * The named event group must have been created with _event_create() or 
 * _event_create_auto_clear(). Each task that needs access to the named event 
 * group must first open a connection to it.
 * \n To open an event group on a remote processor, prepend the event-group name 
 * with the remote processor number as follows.
 * <table>
 *   <tr>
 *     <td><b>This string:</b></td>
 *     <td><b>Opens an event group with this name:</b></td>
 *     <td><b>On this processor:</b></td>   
 *   </tr>
 *   <tr>
 *     <td>"2:Fred"</td>
 *     <td>"Fred"</td>
 *     <td>2</td>   
 *   </tr>
 *   <tr>
 *     <td>"0:Sue"</td>
 *     <td>"Sue"</td>
 *     <td>Local processor</td>   
 *   </tr>   
 * </table> 
 * \n The other allowed event operations on remote processors are:
 * \n - _event_set()
 * \n - _event_close()
 * \n The task closes the connection with _event_close(). 
 * 
 * \param[in]  name_ptr           String name of the event.
 * \param[out] returned_event_ptr Where to write the event group handle (NULL 
 * is written if an error occurred).
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Event component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX could not allocate memory for the event 
 * connection data.)  
 * \return EVENT_INVALID_EVENT (Event group data is no longer valid.)
 * \return EVENT_NOT_FOUND (Named event group is not in the name table.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.) 
 * 
 * \see _event_close
 * \see _event_create
 * \see _event_create_auto_clear
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_all 
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until          
 */ 
_mqx_uint _event_open
(
    char _PTR_    name_ptr,
    pointer _PTR_ returned_event_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    register EVENT_COMPONENT_STRUCT_PTR  event_component_ptr;
    EVENT_STRUCT_PTR                     event_ptr;
    register EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
    _mqx_uint                            result;
    char _PTR_                           parse_ptr;
    uint_32                              processor;
    _mqx_max_type                        tmp;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_event_open, name_ptr, returned_event_ptr);

    *returned_event_ptr = NULL;

    event_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
#if MQX_CHECK_ERRORS
    if (event_component_ptr == NULL)
    {
        _KLOGX2(KLOG_event_open, MQX_COMPONENT_DOES_NOT_EXIST);
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (event_component_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_open, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    /* If lead by a number, this is a processor number */
    processor = 0;
    parse_ptr = name_ptr;
    while (*parse_ptr && (*parse_ptr >= '0') && (*parse_ptr <= '9'))
    {
        processor = (processor * 10) + *parse_ptr - (char) '0';
        parse_ptr++;
    } /* Endwhile */
    if (processor)
    {
        /* Processor number must be followed by ':' */
        if (*parse_ptr == ':')
        {
            parse_ptr++;
        }
        else
        {
            processor = 0;
        } /* Endif */
    } /* Endif */

    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) _mem_alloc_zero((_mem_size) sizeof(EVENT_CONNECTION_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (event_connection_ptr == NULL)
    {
        _KLOGX2(KLOG_event_open, MQX_OUT_OF_MEMORY);
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(event_connection_ptr, MEM_TYPE_EVENT_CONNECTION);

    if (processor != 0)
    {

#if MQX_IS_MULTI_PROCESSOR
        if (kernel_data->IPC)
        {
            /* This open is for a remote processor */
            result = (*kernel_data->IPC)(TRUE, processor, KERNEL_EVENTS,
                            IPC_EVENT_OPEN | IPC_STRING_PARAMETER, 1, parse_ptr);
            if (result != MQX_OK)
            {
                _mem_free(event_connection_ptr);
                _KLOGX2(KLOG_event_open, result);
                return(result);
            } /* Endif */
            event_connection_ptr->EVENT_PTR = (pointer)
            kernel_data->ACTIVE_PTR->INFO;
            event_connection_ptr->REMOTE_CPU = processor;
        }
        else
        {
#endif
        _mem_free(event_connection_ptr);
        _KLOGX2(KLOG_event_open, EVENT_NOT_FOUND);
        return (EVENT_NOT_FOUND);
#if MQX_IS_MULTI_PROCESSOR
    }/* Endif */
#endif

    }
    else
    {

        result = _name_find_internal(event_component_ptr->NAME_TABLE_HANDLE, name_ptr, &tmp);

#if MQX_CHECK_ERRORS
        if (result != MQX_OK)
        {
            _mem_free(event_connection_ptr);
            if (result == NAME_NOT_FOUND)
            {
                _KLOGX2(KLOG_event_open, EVENT_NOT_FOUND);
                return (EVENT_NOT_FOUND);
            } /* Endif */
            _KLOGX2(KLOG_event_open, result);
            return (result);
        } /* Endif */
#endif

        event_ptr = (EVENT_STRUCT_PTR) tmp;

#if MQX_CHECK_VALIDITY
        if (event_ptr->VALID != EVENT_VALID)
        {
            /* Event not valid */
            _mem_free(event_connection_ptr);
            _KLOGX2(KLOG_event_open, EVENT_INVALID_EVENT);
            return (EVENT_INVALID_EVENT);
        } /* Endif */
#endif

        event_connection_ptr->EVENT_PTR = event_ptr;

    }/* Endif */

    event_connection_ptr->VALID = EVENT_VALID;
    event_connection_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
    *returned_event_ptr = (pointer) event_connection_ptr;

    _KLOGX3(KLOG_event_open, MQX_OK, event_connection_ptr);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Sets the specified event bits in the event group.
 * 
 * Before a task can set an event bit in an event group, the event group must be 
 * created and the task must open an connection to the event group.
 * \n A task can set or clear one event bit or any combination of event bits in 
 * the event group.
 * \n A task that opened an event group on a remote processor can set bits in 
 * the event group.
 * 
 * \param[in] users_event_ptr Event group handle returned by _event_open() or 
 * _event_open_fast().
 * \param[in] bit_mask        Each set bit represents an event bit to be set.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Event component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is no longer valid.)
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_INVALID_EVENT_HANDLE (Event group handle is not a valid event
 * connection.) 
 * \return EVENT_NOT_FOUND
 * \return Task error code for ?   
 * 
 * \warning Tasks waiting for the event bits might be dispatched.
 * 
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_all 
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until             
 */ 
_mqx_uint _event_set
(
    pointer   users_event_ptr,
    _mqx_uint bit_mask
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    EVENT_STRUCT_PTR            event_ptr;
    EVENT_COMPONENT_STRUCT_PTR  event_component_ptr;
    EVENT_CONNECTION_STRUCT_PTR conn_ptr;
    EVENT_CONNECTION_STRUCT_PTR next_conn_ptr;
    EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
    TD_STRUCT_PTR               new_td_ptr;
    _mqx_uint                   set_bits;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_event_set, users_event_ptr, bit_mask);

    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) users_event_ptr;

#if MQX_CHECK_VALIDITY
    if (event_connection_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_set, EVENT_INVALID_EVENT_HANDLE);
        return (EVENT_INVALID_EVENT_HANDLE);
    } /* Endif */
#endif

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];

#if MQX_CHECK_ERRORS
    if (event_component_ptr == NULL)
    {
        _KLOGX2(KLOG_event_set, MQX_COMPONENT_DOES_NOT_EXIST);
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (event_component_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_set, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

#if MQX_IS_MULTI_PROCESSOR
    if (event_connection_ptr->REMOTE_CPU)
    {
        if (kernel_data->IPC)
        {
            /* This open is for a remote processor */
            (*kernel_data->IPC)(TRUE, event_connection_ptr->REMOTE_CPU,
                            KERNEL_EVENTS, IPC_EVENT_SET, 2, event_connection_ptr->EVENT_PTR,
                            bit_mask);
            _KLOGX2(KLOG_event_set, kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
            return(kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
        }
        else
        {
            _KLOGX2(KLOG_event_set, EVENT_NOT_FOUND);
            return(EVENT_NOT_FOUND);
        }/* Endif */
    }/* Endif */
#endif

    _INT_DISABLE();
    event_ptr = event_connection_ptr->EVENT_PTR;

#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != EVENT_VALID)
    {
        _INT_ENABLE();
        _KLOGX2(KLOG_event_set, EVENT_INVALID_EVENT);
        return (EVENT_INVALID_EVENT);
    } /* Endif */
#endif

    set_bits = event_ptr->EVENT | bit_mask;

    if (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS))
    {
        /* Schedule waiting task(s) to run if bits ok */

        conn_ptr = (EVENT_CONNECTION_STRUCT_PTR) ((pointer) event_ptr->WAITING_TASKS.NEXT);
        while (conn_ptr != (EVENT_CONNECTION_STRUCT_PTR) ((pointer) &event_ptr->WAITING_TASKS))
        {
            next_conn_ptr = (EVENT_CONNECTION_STRUCT_PTR) conn_ptr->NEXT;
            if (((conn_ptr->FLAGS & EVENT_WANTS_ALL) && ((conn_ptr->MASK & set_bits) == conn_ptr->MASK))
                            || ((!(conn_ptr->FLAGS & EVENT_WANTS_ALL)) && (conn_ptr->MASK & set_bits)))
            {
                new_td_ptr = conn_ptr->TD_PTR;
                if ((new_td_ptr->STATE & STATE_MASK) == EVENT_BLOCKED)
                {
                    /* He may have timed out */
                    conn_ptr->FLAGS |= EVENT_OCCURRED;
                    _TIME_DEQUEUE(new_td_ptr, kernel_data);
                    _TASK_READY(new_td_ptr, kernel_data);
                    /* Only ready one task if event is an auto clear event */
                    if (event_ptr->AUTO_CLEAR)
                    {
                        set_bits &= ~conn_ptr->MASK;
                        break;
                    } /* Endif */
                } /* Endif */
            } /* Endif */
            conn_ptr = next_conn_ptr;
        } /* Endwhile */
    } /* Endif */

    event_ptr->EVENT = set_bits;

    _INT_ENABLE();

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();

    _KLOGX2(KLOG_event_set, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Used during task destruction to free up any events resources owned by 
 * this task.
 * 
 * The function checks the resource list of the task and look for an event 
 * connection struct. It can detect one by looking for EVENT_VALID in the 
 * correct location.
 * 
 * \param[in] td_ptr Pointer to the task descriptor of a task to destroy.   
 */ 
void _event_cleanup
(
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
    EVENT_CONNECTION_STRUCT_PTR connection_ptr;
    EVENT_STRUCT_PTR            event_ptr;

    connection_ptr = _mem_get_next_block_internal(td_ptr, NULL);
    while (connection_ptr)
    {
        if ((connection_ptr->VALID == EVENT_VALID) && (connection_ptr->TD_PTR == td_ptr))
        {
            event_ptr = connection_ptr->EVENT_PTR;
            if (event_ptr->VALID == EVENT_VALID)
            {
                /* Check if the connection is on the queue */
                _int_disable();
                event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) ((pointer) event_ptr->WAITING_TASKS.NEXT);
                while (event_connection_ptr != (pointer) &event_ptr->WAITING_TASKS.NEXT)
                {
                    if (event_connection_ptr == connection_ptr)
                    {
                        /* Connection is queued, so dequeue it */
                        _QUEUE_REMOVE(&event_ptr->WAITING_TASKS, connection_ptr);
                        break;
                    }/* Endif */
                    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) event_connection_ptr->NEXT;
                } /* Endwhile */
                _int_enable();
            }/* Endif */
        } /* Endif */
        connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) _mem_get_next_block_internal(td_ptr, connection_ptr);
    } /* Endwhile */

} /* Endbody */

/*!
 * \brief Tests the event component for validity and consistency.
 * 
 * \param[out] event_error_ptr Handle for the event group that has an error if 
 * MQX found an error in the event component (NULL if no error is found).
 * 
 * \return MQX_OK
 * \return EVENT_INVALID_EVENT (Data for an event group is not valid.)
 * \return MQX_INVALID_COMPONENT_BASE (Event component data is not valid.)
 * \return Return code from _queue_test() (Waiting queue for an event group has 
 * an error.)
 * 
 * \see _event_close
 * \see _event_open
 * \see _event_set
 * \see _event_get_wait_count
 * \see _event_get_value
 * \see _event_wait_all 
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until            
 */ 
_mqx_uint _event_test
(
    pointer _PTR_ event_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    EVENT_COMPONENT_STRUCT_PTR event_component_ptr;
    EVENT_STRUCT_PTR           event_ptr;
    pointer                    table_ptr;
    _mqx_uint                  result;
    _mqx_uint                  i;
    _mqx_max_type              data;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_event_test, event_error_ptr);

    *event_error_ptr = NULL;

    event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
    if (event_component_ptr == NULL)
    {
        _KLOGX2(KLOG_event_test, MQX_OK);
        return (MQX_OK);
    } /* Endif */

    if (event_component_ptr->VALID != EVENT_VALID)
    {
        _KLOGX2(KLOG_event_test, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    _int_disable();
    /* Test the event name table */
    result = _name_test_internal((NAME_COMPONENT_STRUCT_PTR) event_component_ptr->NAME_TABLE_HANDLE,
                    (pointer _PTR_) &table_ptr, (pointer _PTR_) event_error_ptr);
    _int_enable();
    if (result != MQX_OK)
    {
        _KLOGX3(KLOG_event_test, MQX_INVALID_COMPONENT_BASE, *event_error_ptr);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    i = 0;
    while (TRUE)
    {
        _int_disable();
        result = _name_find_internal_by_index(event_component_ptr->NAME_TABLE_HANDLE, i++, &data);
        if (result != MQX_OK)
        {
            result = MQX_OK;
            break;
        } /* Endif */

        event_ptr = (EVENT_STRUCT_PTR) data;
        if (event_ptr->VALID != EVENT_VALID)
        {
            result = EVENT_INVALID_EVENT;
            break;
        } /* Endif */
        result = _queue_test(&event_ptr->WAITING_TASKS, event_error_ptr);
        if (result != MQX_OK)
        {
            break;
        } /* Endif */
        _int_enable();

    } /* Endwhile */

    _int_enable();

    _KLOGX3(KLOG_event_test, result, *event_error_ptr);
    return (result);

} /* Endbody */

/*!
 * \brief Gets the current event bits that have been set.
 * 
 * \param[in] users_event_ptr Event group handle returned by _event_open() or 
 * _event_open_fast().
 * \param[out] event_value_ptr Where to write the value of the event bits (on error, 
 * 0 is written). 
 * 
 * \return MQX_OK
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_INVALID_EVENT_HANDLE (Event group handle is not valid.)
 * 
 * \see _event_clear
 * \see _event_set
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until       
 */ 
_mqx_uint _event_get_value
(
    pointer users_event_ptr,
    _mqx_uint_ptr event_value_ptr
)
{ /* Body */
    register EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
    register EVENT_STRUCT_PTR            event_ptr;

    *event_value_ptr = 0;
    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) users_event_ptr;
#if MQX_CHECK_VALIDITY
    if (event_connection_ptr->VALID != EVENT_VALID)
    {
        return (EVENT_INVALID_EVENT_HANDLE);
    } /* Endif */
#endif

    event_ptr = event_connection_ptr->EVENT_PTR;
#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != EVENT_VALID)
    {
        return (EVENT_INVALID_EVENT);
    } /* Endif */
#endif

    *event_value_ptr = event_ptr->EVENT;

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Gets the number of tasks that are waiting for event bits in the event 
 * group.
 * 
 * Tasks can be waiting for different combinations of event bits.
 * 
 * \param[in] users_event_ptr Event group handle returned by _event_open() or 
 * _event_open_fast().
 * 
 * \return Number of waiting tasks. (Success.)
 * \return MAX_MQX_UINT (Failure.)
 * \return MAX_UINT_32 (Failure.)
 * 
 * \warning On failure, calls _task_set_error() to set the task error code to 
 * EVENT_INVALID_EVENT_HANDLE.
 * 
 * \see _event_open
 * \see _event_open_fast
 * \see _event_wait_all_for
 * \see _event_wait_all_ticks
 * \see _event_wait_all_until
 * \see _event_wait_any
 * \see _event_wait_any_for
 * \see _event_wait_any_ticks
 * \see _event_wait_any_until 
 * \see _task_set_error        
 */ 
_mqx_uint _event_get_wait_count
(
    pointer users_event_ptr
)
{ /* Body */
    register EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
    register EVENT_STRUCT_PTR            event_ptr;

    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) users_event_ptr;
#if MQX_CHECK_VALIDITY
    if (event_connection_ptr->VALID != EVENT_VALID)
    {
        _task_set_error(EVENT_INVALID_EVENT_HANDLE);
        return ((_mqx_uint) MAX_UINT_32);
    } /* Endif */
#endif

    event_ptr = event_connection_ptr->EVENT_PTR;
#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != EVENT_VALID)
    {
        _task_set_error(EVENT_INVALID_EVENT_HANDLE);
        return (MAX_MQX_UINT);
    } /* Endif */
#endif

    return (_QUEUE_GET_SIZE(&(event_ptr->WAITING_TASKS)));

} /* Endbody */

/*!
 * \private
 * 
 * \brief Used internally by a task to wait for all or any specified events
 * according to bit mask
 * 
 * \param[in] users_event_ptr    Event group handle returned by _event_open() or 
 * _event_open_fast().
 * \param[in] bit_mask           Each set bit represents an event bit to wait for.
 * \param[in] tick_ptr           The maximum number of ticks to wait for the 
 * events to be set. If the value is NULL, then the timeout will be infinite.
 * \param[in] ticks_are_absolute TRUE (ticks represents absolute time), FALSE 
 * (ticks represents relative time).
 * \param[in] all                Specifies whether wait for all bits.
 *  
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return EVENT_INVALID_EVENT_HANDLE (Handle is not a valid event group handle.)
 * \return EVENT_CANNOT_WAIT_ON_REMOTE_EVENT 
 * \return EVENT_INVALID_EVENT (Event group is no longer valid.)
 * \return EVENT_DELETED (Event group was destroyed while the task waited.)
 * \return EVENT_WAIT_TIMEOUT (Timeout expired before the event bits were set.)   
 */ 
_mqx_uint _event_wait_internal
(
    pointer             users_event_ptr,
    _mqx_uint           bit_mask,
    MQX_TICK_STRUCT_PTR tick_ptr,
    boolean             ticks_are_absolute,
    boolean             all
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    TD_STRUCT_PTR                        td_ptr;
    register EVENT_STRUCT_PTR            event_ptr;
    register EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR) users_event_ptr;

#if MQX_CHECK_VALIDITY
    if (event_connection_ptr->VALID != EVENT_VALID)
    {
        return (EVENT_INVALID_EVENT_HANDLE);
    } /* Endif */
#endif

    if (event_connection_ptr->REMOTE_CPU)
    {
        _KLOGX2(KLOG_event_wait_all, EVENT_CANNOT_WAIT_ON_REMOTE_EVENT);
        return (EVENT_CANNOT_WAIT_ON_REMOTE_EVENT);
    }/* Endif */

    td_ptr = kernel_data->ACTIVE_PTR;

#if MQX_CHECK_ERRORS
    if (event_connection_ptr->TD_PTR != td_ptr)
    {
        return (EVENT_INVALID_EVENT_HANDLE);
    } /* Endif */
#endif

    _INT_DISABLE();
    event_ptr = event_connection_ptr->EVENT_PTR;

#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != EVENT_VALID)
    {
        _int_enable();
        return (EVENT_INVALID_EVENT);
    } /* Endif */
#endif

    if ((all && ((event_ptr->EVENT & bit_mask) != bit_mask)) || (!all && ((event_ptr->EVENT & bit_mask) == 0)))
    {
        /* Must wait for a event to become available */
        if (all)
        {
            event_connection_ptr->FLAGS = EVENT_WANTS_ALL;
        }
        else
        {
            event_connection_ptr->FLAGS = 0;
        } /* Endif */

        event_connection_ptr->MASK = bit_mask;

        /* Enqueue at end */
        _QUEUE_ENQUEUE(&event_ptr->WAITING_TASKS, event_connection_ptr);

        /* Now put the task to sleep */
        td_ptr->STATE = EVENT_BLOCKED;

        if (tick_ptr)
        {
            if (ticks_are_absolute)
            {
                _time_delay_until(tick_ptr);
            }
            else
            {
                _time_delay_for(tick_ptr);
            } /* Endif */
        }
        else
        {
            _task_block();
        } /* Endif */

#if MQX_COMPONENT_DESTRUCTION
        if (event_ptr->VALID == 0)
        { /* We've been deleted */
            _int_enable();
            return (EVENT_DELETED);
        } /* Endif */
#endif

        _QUEUE_REMOVE(&event_ptr->WAITING_TASKS, event_connection_ptr);

        if (tick_ptr && !(event_connection_ptr->FLAGS & EVENT_OCCURRED))
        {
            /* MUST have timed out */
            _INT_ENABLE();
            return (EVENT_WAIT_TIMEOUT);
        } /* Endif */
    } /* Endif */

    if (event_ptr->AUTO_CLEAR)
    {
        event_ptr->EVENT = event_ptr->EVENT & ~bit_mask;
    } /* Endif */

    /* GOT IT */
    _INT_ENABLE();

    return (MQX_OK);

} /* Endbody */

#endif /* MQX_USE_EVENTS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/snmp.h<|end_filename|>
#ifndef __snmp_h__
#define __snmp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: snmp.h$
* $Version : 3.6.13.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains definitions for using the SNMP
*   agent.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/
#include <rtcs.h>

/*
** SNMP error status values
*/

#define SNMP_ERROR_noError              0
#define SNMP_ERROR_tooBig               1
#define SNMP_ERROR_noSuchName           2
#define SNMP_ERROR_badValue             3
#define SNMP_ERROR_readOnly             4
#define SNMP_ERROR_genErr               5

#define SNMP_ERROR_noAccess             6
#define SNMP_ERROR_wrongType            7
#define SNMP_ERROR_wrongLength          8
#define SNMP_ERROR_wrongEncoding        9
#define SNMP_ERROR_wrongValue          10
#define SNMP_ERROR_noCreation          11
#define SNMP_ERROR_inconsistentValue   12
#define SNMP_ERROR_resourceUnavailable 13
#define SNMP_ERROR_commitFailed        14
#define SNMP_ERROR_undoFailed          15
#define SNMP_ERROR_authorizationError  16
#define SNMP_ERROR_notWritable         17
#define SNMP_ERROR_inconsistentName    18

/* decide whether an error-status uses the error-index */
#define SNMP_ERROR_USEINDEX(n)         ((n) > 1)

/* not real error codes -- used internally */
#define SNMP_ERROR_PARSE               0x7F
#define SNMP_ERROR_noSuchObject        ASN1_TYPE_ERR_NOOBJECT
#define SNMP_ERROR_noSuchInstance      ASN1_TYPE_ERR_NOINST
#define SNMP_ERROR_endOfMibView        ASN1_TYPE_ERR_ENDOFMIB

/*
** MIB access types
*/
#define RTCSMIB_ACCESS_READ   0x01
#define RTCSMIB_ACCESS_WRITE  0x02

/*
** MIB node types
*/
#define RTCSMIB_NODETYPE_INT_CONST     1
#define RTCSMIB_NODETYPE_INT_PTR       2
#define RTCSMIB_NODETYPE_INT_FN        3
#define RTCSMIB_NODETYPE_UINT_CONST    4
#define RTCSMIB_NODETYPE_UINT_PTR      5
#define RTCSMIB_NODETYPE_UINT_FN       6
#define RTCSMIB_NODETYPE_DISPSTR_PTR   7
#define RTCSMIB_NODETYPE_DISPSTR_FN    8
#define RTCSMIB_NODETYPE_OCTSTR_FN     9
#define RTCSMIB_NODETYPE_OID_PTR       10
#define RTCSMIB_NODETYPE_OID_FN        11

#if SNMPCFG_HAVE_INT64
#define RTCSMIB_NODETYPE_INT64_CONST   12
#define RTCSMIB_NODETYPE_INT64_PTR     13
#define RTCSMIB_NODETYPE_INT64_FN      14
#define RTCSMIB_NODETYPE_UINT64_CONST  15
#define RTCSMIB_NODETYPE_UINT64_PTR    16
#define RTCSMIB_NODETYPE_UINT64_FN     17
#endif

/*
** Used internally by the MIB instance parser
*/
#define RTCSMIB_OP_GET              0
#define RTCSMIB_OP_GETNEXT          1
#define RTCSMIB_OP_GETFIRST         2
#define RTCSMIB_OP_FINDNEXT         3
#define RTCSMIB_OP_SET              4

#if RTCSCFG_ENABLE_SNMP_STATS
#define IF_SNMP_STATS_ENABLED(x) x
#else
#define IF_SNMP_STATS_ENABLED(x)
#endif


/***************************************
**
** Type definitions
**
*/

/*
** SNMP statistics for the SNMP MIB
*/

#if RTCSCFG_ENABLE_SNMP_STATS
typedef struct snmp_stats {
   RTCS_STATS_STRUCT COMMON;
   
   /* These are all included in ST_RX_DISCARDED */
   uint_32  ST_RX_BAD_PARSE;
   uint_32  ST_RX_BAD_VERSION;
   uint_32  ST_RX_BAD_COMMUNITY;
   uint_32  ST_RX_BAD_PDU;

   /* Breakdown of all packets received and sent */
   uint_32  ST_RX_VAR_GETS;
   uint_32  ST_RX_VAR_SETS;

   uint_32  ST_RX_GETREQ;
   uint_32  ST_RX_GETNEXTREQ;
   uint_32  ST_RX_RESPONSE;
   uint_32  ST_RX_SETREQ;
   uint_32  ST_RX_TRAP;
   uint_32  ST_RX_GETBULKREQ;
   uint_32  ST_RX_INFORM;
   uint_32  ST_RX_V2TRAP;
   uint_32  ST_RX_REPORT;
   uint_32  ST_RX_OTHER;

   uint_32  ST_TX_GETREQ;
   uint_32  ST_TX_GETNEXTREQ;
   uint_32  ST_TX_RESPONSE;
   uint_32  ST_TX_SETREQ;
   uint_32  ST_TX_TRAP;
   uint_32  ST_TX_GETBULKREQ;
   uint_32  ST_TX_INFORM;
   uint_32  ST_TX_V2TRAP;
   uint_32  ST_TX_REPORT;
   uint_32  ST_TX_OTHER;

   uint_32  ST_TX_TOOBIG;
   uint_32  ST_TX_NOSUCHNAME;
   uint_32  ST_TX_BADVALUE;
   uint_32  ST_TX_READONLY;
   uint_32  ST_TX_GENERR;
   uint_32  ST_TX_OTHERERR;

} SNMP_STATS, _PTR_ SNMP_STATS_PTR;
#endif
/*
** Internal state for the SNMP agent
*/

typedef struct snmp_parse {
#if RTCSCFG_ENABLE_SNMP_STATS
   SNMP_STATS  STATS;
#endif
   uint_32     trapsock;
   char_ptr    community[SNMPCFG_NUM_COMMUNITY];
   uint_32     communitylen[SNMPCFG_NUM_COMMUNITY];
   uint_32     currentcommunity;
   _ip_address trap_receiver_list[SNMPCFG_MAX_TRAP_RECEIVERS];

   uchar_ptr   inbuf;
   uint_32     inlen;
   uchar_ptr   outbuf;
   uint_32     outlen;

   uint_32     errstat;
   uint_32     errindex;
   uchar_ptr   errstatp;
   uchar_ptr   errindexp;

   uint_32     version;
   uint_32     pdutype;
   uint_32     nonrep;
   uint_32     reps;
} SNMP_PARSE, _PTR_ SNMP_PARSE_PTR;

/*
** Internal state for the MIB walker
*/

typedef struct rtcsmib_walk {
   TCPIP_PARM  COMMON;

   uint_8      pdutype;

   uchar_ptr   inbuf;
   uint_32     inlen;
   uchar_ptr   outbuf;
   uint_32     outlen;

   uint_32     errstat;

   uchar_ptr   oidp;
   uint_32     oidlen;
   uint_32     totlen;

} RTCSMIB_WALK, _PTR_ RTCSMIB_WALK_PTR;

/* Interface to pass messages to trap server */
typedef struct trap_parm {
   TCPIP_PARM           COMMON;
   _ip_address          address;
} TRAP_PARM, _PTR_ TRAP_PARM_PTR;

/*
** Structure of a single MIB node
*/

typedef struct rtcsmib_node {
   uint_32                    ID;

   struct rtcsmib_node _PTR_  NEXT;
   struct rtcsmib_node _PTR_  CHILD;
   struct rtcsmib_node _PTR_  PARENT;

   uint_32                    ACCESS;
   boolean (_CODE_PTR_        FIND)(uint_32, pointer, pointer _PTR_);
   boolean (_CODE_PTR_        PARSE)(RTCSMIB_WALK_PTR, uint_32, boolean (_CODE_PTR_)(uint_32, pointer, pointer _PTR_), boolean _PTR_, pointer _PTR_);
   uint_32                    ASN1_TYPE;

   struct rtcsmib_value _PTR_ GET;      

   uint_32 (_CODE_PTR_        SET)(pointer, uchar_ptr, uint_32);

} RTCSMIB_NODE, _PTR_ RTCSMIB_NODE_PTR;

typedef struct rtcsmib_value
{
    uint_32     TYPE; /* ignored in nonleaf nodes */
    pointer     PARAM;
} RTCSMIB_VALUE, _PTR_ RTCSMIB_VALUE_PTR ;

/* callback functions to provide MIB values dynamically */
typedef uint_32   (*RTCSMIB_UINT_FN_PTR)(pointer);
typedef int_32    (*RTCSMIB_INT_FN_PTR)(pointer);
typedef uchar_ptr (*RTCSMIB_DISPSTR_FN_PTR)(pointer);
typedef uchar_ptr (*RTCSMIB_OCTSTR_FN_PTR)(pointer, uint_32 _PTR_);
typedef RTCSMIB_NODE_PTR (*RTCSMIB_OID_FN_PTR)(pointer);    


/***************************************
**
** Prototypes
**
*/

/*
** Used by SNMP to make MIB requests:
*/

extern uint_32 RTCSMIB_request
(
   uint_8         pdutype,
   uchar_ptr      invarp,
   uint_32        invarlen,
   uchar_ptr      outvarp,
   uint_32        outvarlen,
   uint_32 _PTR_  writelen
);

/*
** Utilities for MIB implementations:
*/

extern void RTCSMIB_mib_add
(
   RTCSMIB_NODE_PTR  mib
);

extern int_32 RTCSMIB_int_read    (uchar_ptr, uint_32);
extern boolean RTCSMIB_id_read8   (RTCSMIB_WALK_PTR, uchar _PTR_);
extern boolean RTCSMIB_id_read32  (RTCSMIB_WALK_PTR, uint_32 _PTR_);
extern boolean RTCSMIB_id_write8  (RTCSMIB_WALK_PTR, uchar);
extern boolean RTCSMIB_id_write32 (RTCSMIB_WALK_PTR, uint_32);

extern boolean MIB_instance_zero
(
   RTCSMIB_WALK_PTR     mib,
   uint_32              op,
   boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
   boolean _PTR_        found,
   pointer _PTR_        instance
);

extern void       RTCS_insert_trap_receiver_internal(TRAP_PARM _PTR_);
extern void       RTCS_remove_trap_receiver_internal(TRAP_PARM _PTR_);
extern _mqx_uint  RTCS_count_trap_receivers_internal(void);

extern void SNMP_trap_warmStart(void);
extern void SNMP_trap_coldStart(void);
extern void SNMP_trap_authenticationFailure(void);
extern void SNMP_trap_userSpec(RTCSMIB_NODE_PTR trap_node , uint_32 spec_trap, RTCSMIB_NODE_PTR enterprises );
extern void SNMPv2_trap_warmStart(void);
extern void SNMPv2_trap_coldStart(void);
extern void SNMPv2_trap_authenticationFailure(void);
extern void SNMPv2_trap_userSpec(RTCSMIB_NODE_PTR trap_node);
extern boolean SNMP_trap_select_community(char_ptr);
extern void SNMP_trap_linkDown(pointer);
extern void SNMP_trap_myLinkDown(pointer);
extern void SNMP_trap_linkUp(pointer);
extern void SNMPv2_trap_linkDown(pointer);
extern void SNMPv2_trap_linkUp(pointer);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/PE_LDD.h<|end_filename|>
/** ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : PE_LDD.h
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Version     : Component 01.005, Driver 01.04, CPU db: 3.00.000
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-16, 17:36, # CodeGen: 13
**     Abstract    :
**
**     Settings    :
**
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file PE_LDD.h                                                  
** @version 01.04
** @brief
**
*/         
/*!
**  @addtogroup PE_LDD_module PE_LDD module documentation
**  @{
*/         
#ifndef __PE_LDD_H
#define __PE_LDD_H

/* MODULE PE_LDD. */

#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "MQX1.h"
#include "UART0.h"
#include "FTM0.h"


/*
** ===================================================================
** Function prototypes
** ===================================================================
*/

/*
** ===================================================================
**     Method      :  Cpu_PE_FillMemory (component MK60FN1M0LQ15)
*/
/*!
**     @brief
**         Fills a memory area block by a specified value.
**     @param
**       SourceAddressPtr - Source address pointer.
**     @param
**       c - A value used to fill a memory block.
**     @param
**       len - Length of a memory block to fill.
*/
/* ===================================================================*/
void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len);

/*
** ===================================================================
**     Method      :  Cpu_PE_PeripheralUsed (component MK60FN1M0LQ15)
*/
/*!
**     @brief
**         Returns information whether a peripheral is allocated by PEx 
**         or not.
**     @param
**       PrphBaseAddress - Base address of a peripheral.
**     @return
**       TRUE if a peripheral is used by PEx or FALSE if it isn't used.
*/
/* ===================================================================*/
bool PE_PeripheralUsed(uint32_t PrphBaseAddress);

/*
** ===================================================================
**     Method      :  Cpu_LDD_SetClockConfiguration (component MK60FN1M0LQ15)
*/
/*!
**     @brief
**         Changes the clock configuration of all LDD components in a 
**         project.
**     @param
**       ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method.
**     @param
**       ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method.
*/
/* ===================================================================*/
void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration);

/* END PE_LDD. */


#endif

/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_flashx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_flashx.c$
* $Version : 3.8.2.0$
* $Date    : Oct-8-2012$
*
* Comments:
*
*   This file contains the global generic settings for FLASHX driver.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"

const FLASHX_FILE_BLOCK _bsp_flashx_file_blocks[] = {
    { "bank0", BSP_INTERNAL_FLASH_BASE                                    , BSP_INTERNAL_FLASH_BASE + 1 * (BSP_INTERNAL_FLASH_SIZE / 4) - 1 },
    { "bank1", BSP_INTERNAL_FLASH_BASE + 1 * (BSP_INTERNAL_FLASH_SIZE / 4), BSP_INTERNAL_FLASH_BASE + 2 * (BSP_INTERNAL_FLASH_SIZE / 4) - 1 },
    { "bank2", BSP_INTERNAL_FLASH_BASE + 2 * (BSP_INTERNAL_FLASH_SIZE / 4), BSP_INTERNAL_FLASH_BASE + 3 * (BSP_INTERNAL_FLASH_SIZE / 4) - 1 },
    { "bank3", BSP_INTERNAL_FLASH_BASE + 3 * (BSP_INTERNAL_FLASH_SIZE / 4), BSP_INTERNAL_FLASH_BASE + 4 * (BSP_INTERNAL_FLASH_SIZE / 4) - 1 },
    { ""     , (uint_32) __FLASHX_START_ADDR, (uint_32) __FLASHX_END_ADDR },
    { NULL   ,                             0,                           0 }
};

const FLASHX_INIT_STRUCT _bsp_flashx_init = {
    0x00000000, /* BASE_ADDR should be 0 for internal flashes */
    _flashx_kinetisN_block_map, /* HW block map for KinetisN devices */
    _bsp_flashx_file_blocks, /* Files on the device defined by the BSP */
    &_flashx_ftfe_if, /* Interface for low level driver */
    32, /* For external devices, data lines for the flash. Not used for internal flash devices. */
    1,  /* Number of parallel external flash devices. Not used for internal flash devices. */
    0,  /* 0 if the write verify is requested, non-zero otherwise */
    NULL /* low level driver specific data */
};


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/asn1.h<|end_filename|>
#ifndef __asn1_h__
#define __asn1_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: asn1.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains definitions for parsing the ASN.1
*   subset used by SNMP.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

/*
** ASN.1 types
*/

#define ASN1_TYPE_INTEGER           0x02
#define ASN1_TYPE_OCTET             0x04
#define ASN1_TYPE_NULL              0x05
#define ASN1_TYPE_OBJECT            0x06
#define ASN1_TYPE_SEQUENCE          0x30

#define ASN1_TYPE_IpAddress         0x40
#define ASN1_TYPE_NetworkAddress    ASN1_TYPE_IpAddress
#define ASN1_TYPE_Counter           0x41
#define ASN1_TYPE_Gauge             0x42
#define ASN1_TYPE_TimeTicks         0x43
#define ASN1_TYPE_Opaque            0x44
/* CR 916 */
#define ASN1_TYPE_Counter64         0x46
/* End CR 916 */

#define ASN1_TYPE_ERR_NOOBJECT      0x80
#define ASN1_TYPE_ERR_NOINST        0x81
#define ASN1_TYPE_ERR_ENDOFMIB      0x82

#define ASN1_TYPE_PDU_GET           0xA0
#define ASN1_TYPE_PDU_GETNEXT       0xA1
#define ASN1_TYPE_PDU_RESPONSE      0xA2
#define ASN1_TYPE_PDU_SET           0xA3
#define ASN1_TYPE_PDU_TRAP          0xA4
#define ASN1_TYPE_PDU_GETBULK       0xA5
#define ASN1_TYPE_PDU_INFORM        0xA6
#define ASN1_TYPE_PDU_TRAPV2        0xA7
#define ASN1_TYPE_PDU_REPORT        0xA8


/***************************************
**
** Code macros
**
*/

#define ASN1_READ_IGNORE(p,len) \
      (p)->inbuf += len;  \
      (p)->inlen -= len

#define ASN1_READ_INT(p,len,val) \
      {                                    \
         uint_32 i = len;                  \
         if ((p)->inlen < i) return FALSE; \
         (p)->inlen -= i;                  \
         val = 0;                          \
         while (i--) {                     \
            val <<= 8;                     \
            val += *(p)->inbuf++;          \
         }                                 \
      }

#define ASN1_READ_TYPELEN(p,typecode,typelen) \
      if ((p)->inlen < 2) return FALSE;               \
      (p)->inlen -= 2;                                \
      typecode = *(p)->inbuf++;                       \
      if (*(p)->inbuf < 0x80) {                       \
         typelen = *(p)->inbuf++;                     \
      } else {                                        \
         ASN1_READ_INT(p,*(p)->inbuf++&0x7F,typelen); \
      }                                               \
      if ((p)->inlen < typelen) return FALSE

#define ASN1_READ_TYPELEN_EXPECT(p,typecode,typelen) \
      if ((p)->inlen < 2) return FALSE;                 \
      (p)->inlen -= 2;                                  \
      if (*(p)->inbuf++ != typecode) return FALSE;      \
      if (*(p)->inbuf < 0x80) {                         \
         typelen = *(p)->inbuf++;                       \
      } else {                                          \
         ASN1_READ_INT(p,(*(p)->inbuf++&0x7F),typelen); \
      }                                                 \
      if ((p)->inlen < typelen) return FALSE

#define ASN1_READZERO_IGNORE(p,len) \
      {                                    \
         uint_32 i = len;                  \
         if ((p)->inlen < i) return FALSE; \
         (p)->inlen -= i;                  \
         while (i--) {                     \
            *(p)->inbuf++ = 0;             \
         }                                 \
      }

#define ASN1_READZERO_INT(p,len,val) \
      {                                    \
         uint_32 i = len;                  \
         if ((p)->inlen < i) return FALSE; \
         (p)->inlen -= i;                  \
         val = 0;                          \
         while (i--) {                     \
            val <<= 8;                     \
            val += *(p)->inbuf;            \
            *(p)->inbuf++ = 0;             \
         }                                 \
      }

/*
** Warning:  In the BKWRITE_TYPELEN macro,
** we can have writelen == typelen
*/

#define ASN1_BKWRITE_TYPELEN(p,writelen,typecode,typelen) \
      if (typelen < 0x80) {           \
         (p)->outlen -= 2;            \
         *--(p)->outbuf = typelen;    \
         writelen += 2;               \
      } else if (typelen < 0x100) {   \
         (p)->outlen -= 3;            \
         *--(p)->outbuf = typelen;    \
         writelen += 3;               \
         *--(p)->outbuf = 0x81;       \
      } else {                        \
         (p)->outlen -= 4;            \
         (p)->outbuf -= 2;            \
         htons((p)->outbuf, typelen); \
         writelen += 4;               \
         *--(p)->outbuf = 0x82;       \
      }                               \
      *--(p)->outbuf = typecode

#define ASN1_BKWRITE_TYPELEN_BYTES(p,writelen,typecode,valp,vallen) \
      (p)->outlen -= vallen;                            \
      (p)->outbuf -= vallen;                            \
      _mem_copy(valp, (p)->outbuf, vallen);             \
      ASN1_BKWRITE_TYPELEN(p,writelen,typecode,vallen); \
      writelen += vallen

#define ASN1_BKWRITE_TYPELEN_INT(p,writelen,val) \
      (p)->outlen -= 3;                  \
      *--(p)->outbuf = val;              \
      writelen += 3;                     \
      *--(p)->outbuf = 0x01;             \
      *--(p)->outbuf = ASN1_TYPE_INTEGER

/* CR 850 */
#define ASN1_BKWRITE_TYPELEN_BIGINT(p,writelen,typecode,val) \
      if (val < 0) {                      \
         uint_32 vallen = 0;              \
         for (;; val = ~(~val >> 8)) {    \
            vallen++;                     \
            *--(p)->outbuf = val & 0xFF;  \
            if (val >= -0x80) {           \
               *--(p)->outbuf = vallen;   \
               *--(p)->outbuf = typecode; \
               (p)->outlen -= vallen+2;   \
               writelen += vallen+2;      \
               break;                     \
            }                             \
         }                                \
      } else {                            \
         ASN1_BKWRITE_TYPELEN_BIGUINT(p,writelen,typecode,val); \
      }

#define ASN1_BKWRITE_TYPELEN_BIGUINT(p,writelen,typecode,val) \
      {                                   \
         uint_32 vallen = 0;              \
         for (;; val >>= 8) {             \
            vallen++;                     \
            *--(p)->outbuf = val & 0xFF;  \
            if (val < 0x80) {             \
               *--(p)->outbuf = vallen;   \
               *--(p)->outbuf = typecode; \
               (p)->outlen -= vallen+2;   \
               writelen += vallen+2;      \
               break;                     \
            }                             \
         }                                \
      }
/* End CR 850 */

#define ASN1_BKWRITE_ID(p,writelen,id) \
      {                                         \
         uint_32 i = id;                        \
         (p)->outlen--;                         \
         *--(p)->outbuf = i & 0x7F;             \
         i >>= 7;                               \
         writelen++;                            \
         while (i) {                            \
            (p)->outlen--;                      \
            *--(p)->outbuf = (i & 0x7F) | 0x80; \
            i >>= 7;                            \
            writelen++;                         \
         }                                      \
      }


/*
** These macros are the only ones useful to
** MIB writers.
*/

#define ASN1_READ_ID(p,val) \
      val = 0;                             \
      if ((p)->inlen < 1) return FALSE;    \
      (p)->inlen -= 1;                     \
      while (*(p)->inbuf & 0x80) {         \
         if ((p)->inlen < 1) return FALSE; \
         (p)->inlen -= 1;                  \
         val <<= 7;                        \
         val += *(p)->inbuf++ & 0x7F;      \
      }                                    \
      val <<= 7;                           \
      val += *(p)->inbuf++

#define ASN1_WRITE_ID(p,id) \
      if ((p)->outlen < 1) return FALSE; \
      (p)->outlen--;                     \
      *(p)->outbuf++ = id

#define ASN1_WRITE_ID_OCTET(p,id) \
      {                                                  \
         uint_32 val = id;                               \
         if (val > 0x7F) {                               \
            if ((p)->outlen < 1) {                       \
               (p)->errstat = SNMP_ERROR_tooBig;         \
               return FALSE;                             \
            }                                            \
            (p)->outlen--;                               \
            *(p)->outbuf++ = ((val >> 7) & 0x7F) | 0x80; \
            val &= 0x7F;                                 \
         }                                               \
         if ((p)->outlen < 1) {                          \
            (p)->errstat = SNMP_ERROR_tooBig;            \
            return FALSE;                                \
         }                                               \
         (p)->outlen--;                                  \
         *(p)->outbuf++ = val;                           \
      }

#define ASN1_WRITE_ID_INT(p,id) \
      {                                                            \
         uint_32 val = id;                                         \
         if (val > 0x7F) {                                         \
            if (val > 0x3FFF) {                                    \
               if (val > 0x1FFFFF) {                               \
                  if (val > 0xFFFFFFF) {                           \
                     if ((p)->outlen < 1) {                        \
                        (p)->errstat = SNMP_ERROR_tooBig;          \
                        return FALSE;                              \
                     }                                             \
                     (p)->outlen--;                                \
                     *(p)->outbuf++ = ((val >> 28) & 0x7F) | 0x80; \
                     val &= 0xFFFFFFF;                             \
                  }                                                \
                  if ((p)->outlen < 1) {                           \
                     (p)->errstat = SNMP_ERROR_tooBig;             \
                     return FALSE;                                 \
                  }                                                \
                  (p)->outlen--;                                   \
                  *(p)->outbuf++ = (val >> 21) | 0x80;             \
                  val &= 0x1FFFFF;                                 \
               }                                                   \
               if ((p)->outlen < 1) {                              \
                  (p)->errstat = SNMP_ERROR_tooBig;                \
                  return FALSE;                                    \
               }                                                   \
               (p)->outlen--;                                      \
               *(p)->outbuf++ = (val >> 14) | 0x80;                \
               val &= 0x3FFF;                                      \
            }                                                      \
            if ((p)->outlen < 1) {                                 \
               (p)->errstat = SNMP_ERROR_tooBig;                   \
               return FALSE;                                       \
            }                                                      \
            (p)->outlen--;                                         \
            *(p)->outbuf++ = (val >> 7) | 0x80;                    \
            val &= 0x7F;                                           \
         }                                                         \
         if ((p)->outlen < 1) {                                    \
            (p)->errstat = SNMP_ERROR_tooBig;                      \
            return FALSE;                                          \
         }                                                         \
         (p)->outlen--;                                            \
         *(p)->outbuf++ = val;                                     \
      }


/***************************************
**
** Prototypes
**
*/


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/common/include/usb_types.h<|end_filename|>
#ifndef __types_h__
#define __types_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_types.h$
* $Version : 3.8.2.0$
* $Date    : Aug-15-2012$
*
* Comments:
*
*   This file contains appropriate processor specific header file include.
*
*END************************************************************************/
#include "psptypes.h"

typedef uint_32 USB_STATUS;

/* forward declarations */
struct dev_instance;
struct usb_interface_descriptor;
struct pipe_struct;
struct tr_struct;

typedef pointer _usb_device_handle;                /* device state struct */

typedef pointer _usb_host_handle;                  /* host state struct   */
typedef pointer _usb_device_instance_handle;       /* item on host's list */
typedef pointer _usb_interface_descriptor_handle;  /* Chapter 9 interface descriptor */
typedef pointer _usb_pipe_handle;                  /* pipe or pipe-bundle */
typedef pointer _usb_class_intf_handle;            /* interface state struct (general data + class driver specific data) */
typedef uint_32 descriptor_type;

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/mem.c<|end_filename|>
/*HEADER**********************************************************************
 *
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *****************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************
 *
 * $FileName: mem.c$
 * $Version : 3.8.2.0$
 * $Date    : Jun-25-2012$
 *
 * Comments:
 *
 *END************************************************************************/

#define __MEMORY_MANAGER_COMPILE__
#include "mqx_inc.h"
#include "mem_prv.h"

#if MQX_USE_MEM

#if MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE
extern uchar __UNCACHED_DATA_START[];
extern uchar __UNCACHED_DATA_END[];
#endif /* MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE */

/*!
 * \brief Allocates a block of memory.
 *
 * The functions allocate at least size single-addressable units; the actual
 * number might be greater. The start address of the block is aligned so that
 * tasks can use the returned pointer as a pointer to any data type without
 * causing an error.
 * \n Tasks cannot use memory blocks as messages. Tasks must use _msg_alloc() or
 * _msg_alloc_system() to allocate messages.
 * \n Only the task that allocates a memory block with one of the following
 * functions can free the memory block:
 * \li _mem_alloc()
 * \li _mem_alloc_from()
 * \li _mem_alloc_zero()
 * \li _mem_alloc_zero_from()
 * \li _mem_alloc_align()
 * \li _mem_alloc_align_from()
 * \li _mem_alloc_at()
 *
 * \n Any task can free a memory block that is allocated with one of the following
 * functions:
 * \li _mem_alloc_system()
 * \li _mem_alloc_system_from()
 * \li _mem_alloc_system_zero()
 * \li _mem_alloc_system_zero_from()
 *
 * \n Function types:
 * <table>
 *  <tr>
 *    <td></td>
 *    <td><b>Allocate this type of memory block:</b></td>
 *    <td><b>From:</b></td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc()</b></td>
 *    <td>Private</td>
 *    <td>Default memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_from()</b></td>
 *    <td>Private</td>
 *    <td>Specified memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_system()</b></td>
 *    <td>System</td>
 *    <td>Default memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_system_from()</b></td>
 *    <td>System</td>
 *    <td>Specified memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_system_zero()</b></td>
 *    <td>System (zero-filled)</td>
 *    <td>Default memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_system_zero_from()</b></td>
 *    <td>System (zero-filled)</td>
 *    <td>Specified memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_zero()</b></td>
 *    <td>Private (zero-filled)</td>
 *    <td>Default memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_zero_from()</b></td>
 *    <td>Private (zero-filled)</td>
 *    <td>Specified memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_align()</b></td>
 *    <td>Private (aligned)</td>
 *    <td>Default memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_align_from()</b></td>
 *    <td>Private (aligned)</td>
 *    <td>Specified memory pool</td>
 *  </tr>
 *  <tr>
 *    <td><b>_mem_alloc_at()</b></td>
 *    <td>Private (start address defined)</td>
 *    <td>Default memory pool</td>
 *  </tr>
 * </table>
 *
 * \param[in] size Size of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 * 
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at()
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc
(
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc, size);

    _INT_DISABLE();
    result = _mem_alloc_internal(size, kernel_data->ACTIVE_PTR, (MEMPOOL_STRUCT_PTR) & kernel_data->KD_POOL, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    kernel_data->KD_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->KD_POOL.POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    _KLOGX3(KLOG_mem_alloc, result, kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR);
    return (result);

} /* Endbody */

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] size  Size of the memory block.
 * \param[in] align Alignment of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at()
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_align
(
    _mem_size size,
    _mem_size align
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc, size);

    _INT_DISABLE();
    result = _mem_alloc_internal_align(size, align, kernel_data->ACTIVE_PTR, (MEMPOOL_STRUCT_PTR)
                    & kernel_data->KD_POOL, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    kernel_data->KD_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->KD_POOL.POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    _KLOGX3(KLOG_mem_alloc_align, result, kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR);
    return (result);
}

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] size Size of the memory block.
 * \param[in] addr Start address of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 * 
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align() 
 * \see _mem_alloc_align_from()
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error                 
 */
pointer _mem_alloc_at
(
    _mem_size size,
    pointer addr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc, size);

    _INT_DISABLE();
    result = _mem_alloc_at_internal(size, addr, kernel_data->ACTIVE_PTR, (MEMPOOL_STRUCT_PTR) & kernel_data->KD_POOL,
                    &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    kernel_data->KD_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->KD_POOL.POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    }
#endif

    _KLOGX3(KLOG_mem_alloc_at, result, kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR);
    return (result);
}

#if MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE

/*!
 * \brief Allocates a block of memory.
 *
 * \param[in] size Size of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is 
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)     
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 */ 
pointer _mem_alloc_uncached
(
    _mem_size size
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    //_KLOGE2(KLOG_mem_alloc_uncached, req_size);

    result = _mem_alloc_from(kernel_data->UNCACHED_POOL, size);

    //_KLOGX3(KLOG_mem_alloc_uncached, result, kernel_data->UNCACHED_POOL.POOL_BLOCK_IN_ERROR);

    return result;
}

/*!
 * \brief Allocates an aligned block of memory.
 *
 * \param[in] size  Size of the memory block.
 * \param[in] align Alignment of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is 
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)  
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 */ 
pointer _mem_alloc_align_uncached
(
    _mem_size size,
    _mem_size align
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    //_KLOGE2(KLOG_mem_alloc_uncached, size);

    result = _mem_alloc_align_from(kernel_data->UNCACHED_POOL, size, align);

    //_KLOGX3(KLOG_mem_alloc_uncached, result, kernel_data->UNCACHED_POOL.POOL_BLOCK_IN_ERROR);

    return result;
}

#endif /* MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE */

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] pool_id Pool from which to allocate the memory block (from
 * _mem_create_pool()).
 * \param[in] size    Number of single-addressable units to allocate.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_from
(
    _mem_pool_id pool_id,
    _mem_size size
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc_from, size);

    mem_pool_ptr = (MEMPOOL_STRUCT_PTR) pool_id;

    _INT_DISABLE();

    result = _mem_alloc_internal(size, kernel_data->ACTIVE_PTR, mem_pool_ptr, &error);

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

    _INT_ENABLE();

    _KLOGX3(KLOG_mem_alloc_from, result, mem_pool_ptr->POOL_BLOCK_IN_ERROR);
    return (result);

}

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] pool_id Pool from which to allocate the memory block (from
 * _mem_create_pool()).
 * \param[in] size    Number of single-addressable units to allocate.
 * \param[in] align   Alignment of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_at
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_align_from
(
    _mem_pool_id pool_id,
    _mem_size size,
    _mem_size align
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc_from, size);

    mem_pool_ptr = (MEMPOOL_STRUCT_PTR) pool_id;

    _INT_DISABLE();

    result = _mem_alloc_internal_align(size, align, kernel_data->ACTIVE_PTR, mem_pool_ptr, &error);

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

    _INT_ENABLE();

    _KLOGX3(KLOG_mem_alloc_from, result, mem_pool_ptr->POOL_BLOCK_IN_ERROR);
    return (result);

}

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] size Number of single-addressable units to allocate.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_zero
(
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc_zero, size);

    _INT_DISABLE();

    result = _mem_alloc_internal(size, kernel_data->ACTIVE_PTR, (MEMPOOL_STRUCT_PTR) & kernel_data->KD_POOL, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    kernel_data->KD_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->KD_POOL.POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    if (result != NULL) {
        _mem_zero(result, size);
    } /* Endif */

    _KLOGX3(KLOG_mem_alloc_zero, result,
                    kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR);
    return (result);

} /* Endbody */

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] pool_id Pool from which to allocate the memory block (from
 * _mem_create_pool()).
 * \param[in] size    Number of single-addressable units to allocate.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_zero_from
(
    pointer pool_id,
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc_zero, size);

    mem_pool_ptr = (MEMPOOL_STRUCT_PTR) pool_id;

    _INT_DISABLE();

    result = _mem_alloc_internal(size, kernel_data->ACTIVE_PTR, mem_pool_ptr, &error);

    /*
     * update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    if (result != NULL) {
        _mem_zero(result, size);
    } /* Endif */

    _KLOGX3(KLOG_mem_alloc_zero, result, mem_pool_ptr->POOL_BLOCK_IN_ERROR);
    return (result);

} /* Endbody */

/*!
 * \private
 *
 * \brief Creates the memory pool from memory that is outside the default memory
 * pool.
 *
 * Tasks use the pool ID to allocate (variable-size) memory blocks from the pool.
 *
 * \param[in] start        Address of the start of the memory pool.
 * \param[in] end          The end of the memory pool.
 * \param[in] mem_pool_ptr Where to store the memory pool context info.
 *
 * \return MQX_OK
 * \return MQX_CORRUPT_MEMORY_SYSTEM (Internal data for the message component is
 * corrupted.)
 * \return MQX_MEM_POOL_TOO_SMALL (Size is less than the minimum allowable
 * message-pool size.)
 *
 * \see _mem_create_pool
 */
_mqx_uint _mem_create_pool_internal
(
    pointer            start,
    pointer            end,
    MEMPOOL_STRUCT_PTR mem_pool_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    STOREBLOCK_STRUCT_PTR block_ptr;
    STOREBLOCK_STRUCT_PTR end_block_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_VALIDITY
    _INT_DISABLE();
    if (kernel_data->MEM_COMP.VALID != MEMPOOL_VALID) {
        /* The RTOS memory system has been corrupted */
        _int_enable();
        return (MQX_CORRUPT_MEMORY_SYSTEM);
    } /* Endif */

    _INT_ENABLE();
#endif

    /* Align the start of the pool */
    mem_pool_ptr->POOL_PTR = (STOREBLOCK_STRUCT_PTR)
    _ALIGN_ADDR_TO_HIGHER_MEM(start);

    /* Set the end of memory (aligned) */
    mem_pool_ptr->POOL_LIMIT = (STOREBLOCK_STRUCT_PTR)
    _ALIGN_ADDR_TO_LOWER_MEM(end);

#if MQX_CHECK_ERRORS
    if ((uchar_ptr) mem_pool_ptr->POOL_LIMIT <= ((uchar_ptr) mem_pool_ptr->POOL_PTR + MQX_MIN_MEMORY_POOL_SIZE)) {
        return MQX_MEM_POOL_TOO_SMALL;
    } /* Endif */
#endif

    block_ptr = (STOREBLOCK_STRUCT_PTR) mem_pool_ptr->POOL_PTR;
    mem_pool_ptr->POOL_HIGHEST_MEMORY_USED = (pointer) block_ptr;
    mem_pool_ptr->POOL_CHECK_POOL_PTR = (char _PTR_) mem_pool_ptr->POOL_PTR;
    mem_pool_ptr->POOL_BLOCK_IN_ERROR = NULL;

    /* Compute the pool size. */
    mem_pool_ptr->POOL_SIZE = (_mem_size) ((uchar_ptr) mem_pool_ptr->POOL_LIMIT - (uchar_ptr) mem_pool_ptr->POOL_PTR);

    /* Set up the first block as an idle block */
    block_ptr->BLOCKSIZE = mem_pool_ptr->POOL_SIZE - MQX_MIN_MEMORY_STORAGE_SIZE;
    block_ptr->USER_AREA = NULL;
    block_ptr->PREVBLOCK = NULL;
    block_ptr->NEXTBLOCK = NULL;
    MARK_BLOCK_AS_FREE(block_ptr);

    CALC_CHECKSUM(block_ptr);

    mem_pool_ptr->POOL_FREE_LIST_PTR = block_ptr;

    /*
     * Set up last block as an in_use block, so that the _mem_free algorithm
     * will work (block coalescing)
     */
    end_block_ptr = (STOREBLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + block_ptr->BLOCKSIZE);
    end_block_ptr->BLOCKSIZE = (_mem_size) (MQX_MIN_MEMORY_STORAGE_SIZE);
    end_block_ptr->USER_AREA = 0;
    end_block_ptr->PREVBLOCK = (struct storeblock_struct _PTR_) block_ptr;
    end_block_ptr->NEXTBLOCK = NULL;
    MARK_BLOCK_AS_USED(end_block_ptr, SYSTEM_TASK_ID(kernel_data));
    CALC_CHECKSUM(end_block_ptr);

    mem_pool_ptr->POOL_END_PTR = end_block_ptr;

    /* Initialize the list of extensions to this pool */
    _QUEUE_INIT(&mem_pool_ptr->EXT_LIST, 0);

    mem_pool_ptr->VALID = MEMPOOL_VALID;

    /* Protect the list of pools while adding new pool */
    _lwsem_wait((LWSEM_STRUCT_PTR) &kernel_data->MEM_COMP.SEM);
    _QUEUE_ENQUEUE(&kernel_data->MEM_COMP.POOLS, &mem_pool_ptr->LINK);
    _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->MEM_COMP.SEM);

    return MQX_OK;

} /* Endbody */

/*!
 * \brief Creates the memory pool from memory that is outside the default memory
 * pool.
 *
 * Tasks use the pool ID to allocate (variable-size) memory blocks from the pool.
 *
 * \param[in] start Address of the start of the memory pool.
 * \param[in] size  Size of the memory pool.
 *
 * \return MQX_OK
 * \return NULL
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_MEMORY_SYSTEM (Internal data for the message component is
 * corrupted.)
 * \li MQX_MEM_POOL_TOO_SMALL (Size is less than the minimum allowable
 * message-pool size.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _task_set_error
 */
_mem_pool_id _mem_create_pool
(
    pointer start,
    _mem_size size
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    uchar_ptr end;
    _mqx_uint error;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE3(KLOG_mem_create_pool, start, size);

#if MQX_CHECK_ERRORS
    if (size < MQX_MIN_MEMORY_POOL_SIZE) {
        error = MQX_MEM_POOL_TOO_SMALL;
        _task_set_error(error);
        _KLOGX4(KLOG_mem_create_pool, start, size, error);
        return NULL;
    } /* Endif */
#endif

    mem_pool_ptr = (MEMPOOL_STRUCT_PTR)_ALIGN_ADDR_TO_HIGHER_MEM(start);
    _mem_zero((pointer) mem_pool_ptr, (_mem_size) sizeof(MEMPOOL_STRUCT));

    end = (uchar_ptr) start + size;
    start = (pointer) ((uchar_ptr) mem_pool_ptr + sizeof(MEMPOOL_STRUCT));
    error = _mem_create_pool_internal(start, (pointer) end, mem_pool_ptr);

#if (MQX_CHECK_ERRORS)
    if (error != MQX_OK) {
        _task_set_error(error);
        _KLOGX4(KLOG_mem_create_pool, start, size, error);
        return NULL;
    } /* Endif */
#endif

    return ((_mem_pool_id) mem_pool_ptr);

} /* Endbody */

/*!
 * \brief Adds the specified memory area for use by the memory manager.
 *
 * The function adds the specified memory to the default memory pool.
 * \n The function fails if size is less than (3 * MQX_MIN_MEMORY_STORAGE_SIZE),
 * as defined in mem_prv.h
 *
 * \param[in] start_of_pool Pointer to the start of the memory to add.
 * \param[in] size          Size of the memory pool to add.
 *
 * \return MQX_OK
 * \return MQX_INVALID_SIZE (Failure, see Description.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Memory pool to extend is not valid.)
 *
 * \see _mem_get_highwater
 * \see MQX_INITIALIZATION_STRUCT
 */
_mqx_uint _mem_extend
(
    pointer start_of_pool,
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_mem_extend, start_of_pool, size);

    result = _mem_extend_pool_internal(start_of_pool, size, (MEMPOOL_STRUCT_PTR) & kernel_data->KD_POOL);

    _KLOGX2(KLOG_mem_extend, result);

    return (result);

} /* Endbody */

/*!
 * \private
 *
 * \brief Adds physical memory to the memory pool, which is outside the default
 * memory pool.
 *
 * \param[in] start_of_pool Pointer to the start of the memory to add.
 * \param[in] size          Size of the memory pool addition.
 * \param[in] mem_pool_ptr  The memory pool to extend.
 *
 * \return MQX_OK
 * \return MQX_INVALID_SIZE (Failure, see Description.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Memory pool to extend is not valid.)
 *
 * \see _mem_create_pool
 * \see _mem_get_highwater_pool
 */
_mqx_uint _mem_extend_pool_internal
(
    pointer            start_of_pool,
    _mem_size          size,
    MEMPOOL_STRUCT_PTR mem_pool_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    STOREBLOCK_STRUCT_PTR block_ptr;
    STOREBLOCK_STRUCT_PTR end_ptr;
    STOREBLOCK_STRUCT_PTR free_ptr;
    STOREBLOCK_STRUCT_PTR tmp_ptr;
    MEMPOOL_EXTENSION_STRUCT_PTR ext_ptr;
    uchar_ptr real_start_ptr;
    uchar_ptr end_of_pool;
    _mem_size block_size;
    _mem_size real_size;
    _mem_size free_block_size;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (size < (_mem_size) (3 * MQX_MIN_MEMORY_STORAGE_SIZE)) {
        /* Pool must be big enough to hold at least 3 memory blocks */
        return (MQX_INVALID_SIZE);
    }/* Endif */
#endif

#if MQX_CHECK_VALIDITY
    if (mem_pool_ptr->VALID != MEMPOOL_VALID) {
        return (MQX_INVALID_COMPONENT_HANDLE);
    }/* Endif */
#endif

    ext_ptr = (MEMPOOL_EXTENSION_STRUCT_PTR)
    _ALIGN_ADDR_TO_HIGHER_MEM(start_of_pool);

    real_start_ptr = (uchar_ptr) ext_ptr + sizeof(MEMPOOL_EXTENSION_STRUCT);
    real_start_ptr = (uchar_ptr) _ALIGN_ADDR_TO_HIGHER_MEM(real_start_ptr);

    end_of_pool = (uchar_ptr) start_of_pool + size;
    end_of_pool = (uchar_ptr) _ALIGN_ADDR_TO_LOWER_MEM(end_of_pool);

    real_size = (_mem_size) (end_of_pool - real_start_ptr);

    ext_ptr->START = start_of_pool;
    ext_ptr->SIZE = size;
    ext_ptr->REAL_START = real_start_ptr;

    block_ptr = (STOREBLOCK_STRUCT_PTR) real_start_ptr;
    block_size = MQX_MIN_MEMORY_STORAGE_SIZE;

    free_ptr = (STOREBLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + block_size);
    free_block_size = real_size - (_mem_size) (2 * MQX_MIN_MEMORY_STORAGE_SIZE);

    end_ptr = (STOREBLOCK_STRUCT_PTR)((uchar_ptr) free_ptr + free_block_size);

    /*
     * Make a small minimal sized memory block to be as
     * the first block in the pool.  This will be an in-use block
     * and will thus avoid problems with memory co-allescing during
     * memory frees
     */
    block_ptr->BLOCKSIZE = block_size;
    block_ptr->MEM_TYPE = 0;
    block_ptr->USER_AREA = 0;
    block_ptr->PREVBLOCK = (struct storeblock_struct _PTR_) NULL;
    block_ptr->NEXTBLOCK = free_ptr;
    MARK_BLOCK_AS_USED(block_ptr, SYSTEM_TASK_ID(kernel_data));
    CALC_CHECKSUM(block_ptr);

    /*
     * Let the next block be the actual free block that will be added
     * to the free list
     */
    free_ptr->BLOCKSIZE = free_block_size;
    free_ptr->MEM_TYPE = 0;
    free_ptr->USER_AREA = 0;
    free_ptr->PREVBLOCK = block_ptr;
    free_ptr->NEXTBLOCK = end_ptr;
    MARK_BLOCK_AS_FREE(free_ptr);
    CALC_CHECKSUM(free_ptr);

    /*
     * Set up a minimal sized block at the end of the pool, and also
     * mark it as being allocated.  Again this is to comply with the
     * _mem_free algorithm
     */
    end_ptr->BLOCKSIZE = block_size;
    end_ptr->MEM_TYPE = 0;
    end_ptr->USER_AREA = 0;
    end_ptr->PREVBLOCK = free_ptr;
    end_ptr->NEXTBLOCK = NULL;
    MARK_BLOCK_AS_USED(end_ptr, SYSTEM_TASK_ID(kernel_data));
    CALC_CHECKSUM(end_ptr);

    _int_disable(); /* Add the block to the free list */
    tmp_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
    mem_pool_ptr->POOL_FREE_LIST_PTR = free_ptr;
    if (tmp_ptr != NULL) {
        PREV_FREE( tmp_ptr) = free_ptr;
    } /* Endif */
    PREV_FREE( free_ptr) = NULL;
    NEXT_FREE( free_ptr) = tmp_ptr;

    /* Reset the free list queue walker for some other task */
    mem_pool_ptr->POOL_FREE_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

    /* Link in the extension */
    _QUEUE_ENQUEUE(&mem_pool_ptr->EXT_LIST, &ext_ptr->LINK);

    _int_enable();

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Adds physical memory to the memory pool, which is outside the default
 * memory pool.
 *
 * The function adds the specified memory to the memory pool.
 * \n The function fails if size is less than (3 * MIN_MEMORY_STORAGE_SIZE), as
 * defined in mem_prv.h.
 *
 * \param[in] pool_id       Pool to which to add memory (from _mem_create_pool()).
 * \param[in] start_of_pool Pointer to the start of the memory to add.
 * \param[in] size          Size of the memory pool addition.
 *
 * \return MQX_OK
 * \return MQX_INVALID_SIZE (Failure, see Description.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Memory pool to extend is not valid.)
 *
 * \see _mem_create_pool
 * \see _mem_get_highwater_pool
 */
_mqx_uint _mem_extend_pool
(
    _mem_pool_id pool_id,
    pointer      start_of_pool,
    _mem_size    size
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _mqx_uint result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_mem_extend_pool, start_of_pool, size, pool_id);

    result = _mem_extend_pool_internal(start_of_pool, size, (MEMPOOL_STRUCT_PTR) pool_id);

    _KLOGX2(KLOG_mem_extend_pool, result);

    return (result);

} /* Endbody */

/*!
 * \brief Free part of the memory block.
 *
 * Under the same restriction as for _mem_free(), the function trims from the
 * end of the memory block.
 * \n A successful call to the function frees memory only if requested_size is
 * sufficiently smaller than the size of the original block. To determine whether
 * the function freed memory, call _mem_get_size() before and after calling
 * _mem_free_part().
 *
 * \param[in] mem_ptr        Pointer to the memory block to trim.
 * \param[in] requested_size New size for the block.
 *
 * \return MQX_OK
 * \return MQX_INVALID_POINTER (Mem_ptr is NULL, not in the pool, or misaligned.)
 * \return MQX_INVALID_CHECKSUM (Block's checksum is not correct, indicating
 * that at least some of the block was overwritten.)
 * \return MQX_NOT_RESOURCE_OWNER (If the block was allocated with _mem_alloc()
 * or _mem_alloc_zero(), only the task that allocated it can free part of it.)
 * \return MQX_INVALID_SIZE (Size of the original block is less than requested_size
 * or requested_size is less than 0.).
 *
 * \warning On failure, calls _task_set_error() to set the task error code (see
 * return values)
 *
 * \see _mem_free
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_get_size
 * \see _task_set_error
 */
_mqx_uint _mem_free_part
(
    pointer   mem_ptr,
    _mem_size requested_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    STOREBLOCK_STRUCT_PTR block_ptr;
    STOREBLOCK_STRUCT_PTR prev_block_ptr;
    STOREBLOCK_STRUCT_PTR next_block_ptr;
    STOREBLOCK_STRUCT_PTR new_block_ptr;
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    TD_STRUCT_PTR td_ptr;

    _mem_size size;
    _mem_size block_size;
    _mem_size new_block_size;
    _mqx_uint result_code;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_mem_free_part, mem_ptr, requested_size);

#if MQX_CHECK_ERRORS
    /* Make sure a correct pointer was passed in.    */
    if (mem_ptr == NULL) {
        _task_set_error(MQX_INVALID_POINTER);
        _KLOGX2(KLOG_mem_free_part, MQX_INVALID_POINTER);
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    /* Verify the block size */
    block_ptr = GET_MEMBLOCK_PTR(mem_ptr);

#if MQX_CHECK_ERRORS
    if (!_MEMORY_ALIGNED(block_ptr)) {
        _task_set_error(MQX_INVALID_POINTER);
        _KLOGX2(KLOG_mem_free_part, MQX_INVALID_POINTER);
        return (MQX_INVALID_POINTER);
    } /* Endif */

    if ((block_ptr->BLOCKSIZE < MQX_MIN_MEMORY_STORAGE_SIZE) || BLOCK_IS_FREE(block_ptr)) {
        _task_set_error(MQX_INVALID_POINTER);
        kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
        _KLOGX3(KLOG_mem_free_part, MQX_INVALID_POINTER, block_ptr);
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    _INT_DISABLE();
#if MQX_CHECK_VALIDITY
    if (!VALID_CHECKSUM(block_ptr)) {
        _int_enable();
        _task_set_error(MQX_INVALID_CHECKSUM);
        kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
        _KLOGX3(KLOG_mem_free_part, MQX_INVALID_CHECKSUM, block_ptr);
        return (MQX_INVALID_CHECKSUM);
    } /* Endif */
#endif

    mem_pool_ptr = (MEMPOOL_STRUCT_PTR) block_ptr->MEM_POOL_PTR;
    td_ptr = SYSTEM_TD_PTR(kernel_data);
    if (block_ptr->TASK_NUMBER != (TASK_NUMBER_FROM_TASKID(td_ptr->TASK_ID))) {
        td_ptr = kernel_data->ACTIVE_PTR;
    }

    /*  Walk through the memory resources of the task descriptor.
     *  Two pointers are maintained, one to the current block
     *  and one to the previous block.
     */
    next_block_ptr = (STOREBLOCK_STRUCT_PTR) td_ptr->MEMORY_RESOURCE_LIST;
    prev_block_ptr = (STOREBLOCK_STRUCT_PTR)((uchar_ptr) (&td_ptr->MEMORY_RESOURCE_LIST)
                    - FIELD_OFFSET(STOREBLOCK_STRUCT,NEXTBLOCK));

    /* Scan the task's memory resource list searching for the block to
     * free, Stop when the current pointer is equal to the block to free
     * or the end of the list is reached.
     */
    while (next_block_ptr && ((pointer) next_block_ptr != mem_ptr)) {
        /* The block is not found, and the end of the list has not been
         * reached, so move down the list.
         */
        prev_block_ptr = GET_MEMBLOCK_PTR(next_block_ptr);
        next_block_ptr = (STOREBLOCK_STRUCT_PTR) prev_block_ptr->NEXTBLOCK;
    } /* Endwhile */

#if MQX_CHECK_ERRORS
    if (next_block_ptr == NULL) {
        _int_enable();
        /* The specified block does not belong to the calling task. */
        _task_set_error(MQX_NOT_RESOURCE_OWNER);
        _KLOGX2(KLOG_mem_free_part, MQX_NOT_RESOURCE_OWNER);
        return (MQX_NOT_RESOURCE_OWNER);
    } /* Endif */
#endif

    /* determine the size of the block.  */
    block_size = block_ptr->BLOCKSIZE;

    size = requested_size + (_mem_size) FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA);
    if (size < MQX_MIN_MEMORY_STORAGE_SIZE) {
        size = MQX_MIN_MEMORY_STORAGE_SIZE;
    } /* Endif */
    _MEMORY_ALIGN_VAL_LARGER(size);

#if MQX_CHECK_ERRORS
    /* Verify that the size parameter is within range of the block size. */
    if (size <= block_size) {
#endif
        /* Adjust the size to allow for the overhead and force alignment */

        /* Compute the size of the new_ block that would be created. */
        new_block_size = block_size - size;

        /* Decide if it worthwile to split the block. If the amount of space
         * returned is not at least twice the size of the block overhead,
         * then dont bother.
         */
        if (new_block_size >= (2 * MQX_MIN_MEMORY_STORAGE_SIZE)) {

            /* Create an 'inuse' block */
            new_block_ptr = (STOREBLOCK_STRUCT_PTR)((char _PTR_) block_ptr + size);
            new_block_ptr->BLOCKSIZE = new_block_size;
            PREV_PHYS( new_block_ptr) = block_ptr;
            new_block_ptr->TASK_NUMBER = block_ptr->TASK_NUMBER;
            new_block_ptr->MEM_POOL_PTR = block_ptr->MEM_POOL_PTR;
            CALC_CHECKSUM(new_block_ptr);
            /* Split the block */
            block_ptr->BLOCKSIZE = size;
            CALC_CHECKSUM(block_ptr);

            /* make sure right physical neighbour knows about it */
            block_ptr = NEXT_PHYS(new_block_ptr);
            PREV_PHYS( block_ptr) = new_block_ptr;
            CALC_CHECKSUM(block_ptr);

            /* Link the new block onto the requestor's task descriptor. */
            new_block_ptr->NEXTBLOCK = td_ptr->MEMORY_RESOURCE_LIST;
            td_ptr->MEMORY_RESOURCE_LIST = (char _PTR_) (&new_block_ptr->USER_AREA);

            result_code = _mem_free((pointer) &new_block_ptr->USER_AREA);
        }
        else {
            result_code = MQX_OK;
        } /* Endif */
#if MQX_CHECK_ERRORS
    }
    else {
        result_code = MQX_INVALID_SIZE;
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (result_code != MQX_OK) {
        _task_set_error(result_code);
    } /* Endif */
#endif

    _INT_ENABLE();
    _KLOGX2(KLOG_mem_free_part, result_code);
    return (result_code);
}

/*!
 * \brief Frees the given memory block.
 *
 * If the memory block was allocated with one of the following functions, only
 * the task that owns the block can free it:
 * \li _mem_alloc()
 * \li _mem_alloc_from()
 * \li _mem_alloc_zero()
 * \li _mem_alloc_zero_from()
 *
 * \n Any task can free a memory block that is allocated with one of the following
 * functions:
 * \li _mem_alloc_system()
 * \li _mem_alloc_system_from()
 * \li _mem_alloc_system_zero()
 * \li _mem_alloc_system_zero_from()
 *
 * \param[in] mem_ptr Pointer to the memory block to free.
 *
 * \return MQX_OK
 * \return MQX_INVALID_POINTER (Mem_ptr is NULL, not in the pool, or misaligned.)
 * \return MQX_INVALID_CHECKSUM (Block's checksum is not correct, indicating
 * that at least some of the block was overwritten.)
 * \return MQX_NOT_RESOURCE_OWNER (If the block was allocated with _mem_alloc()
 * or _mem_alloc_zero(), only the task that allocated it can free part of it.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code (see
 * return values).
 *
 * \see _mem_free_part
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _task_set_error
 */
_mqx_uint _mem_free
(
    pointer mem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    STOREBLOCK_STRUCT_PTR block_ptr;
    STOREBLOCK_STRUCT_PTR prev_block_ptr;
    STOREBLOCK_STRUCT_PTR next_block_ptr;
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    TD_STRUCT_PTR td_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_mem_free, mem_ptr);

#if MQX_CHECK_ERRORS
    /* Verify the passed in parameter */
    if (mem_ptr == NULL) {
        _task_set_error(MQX_INVALID_POINTER);
        _KLOGX2(KLOG_mem_free, MQX_INVALID_POINTER);
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    block_ptr = GET_MEMBLOCK_PTR(mem_ptr);

#if MQX_CHECK_ERRORS
    /* Verify pointer alignment */
    if (!_MEMORY_ALIGNED(block_ptr) || (block_ptr->BLOCKSIZE < MQX_MIN_MEMORY_STORAGE_SIZE) || BLOCK_IS_FREE(block_ptr)) {
        _task_set_error(MQX_INVALID_POINTER);
        _KLOGX2(KLOG_mem_free, MQX_INVALID_POINTER);
        return (MQX_INVALID_POINTER);
    } /* Endif */

#endif

    _INT_DISABLE();

#if MQX_CHECK_VALIDITY
    if (!VALID_CHECKSUM(block_ptr)) {
        _int_enable();
        _task_set_error(MQX_INVALID_CHECKSUM);
        _KLOGX2(KLOG_mem_free, MQX_INVALID_CHECKSUM);
        return (MQX_INVALID_CHECKSUM);
    } /* Endif */
#endif

    mem_pool_ptr = (MEMPOOL_STRUCT_PTR) block_ptr->MEM_POOL_PTR;
    td_ptr = SYSTEM_TD_PTR(kernel_data);
    if (block_ptr->TASK_NUMBER != (TASK_NUMBER_FROM_TASKID(td_ptr->TASK_ID))) {
        td_ptr = kernel_data->ACTIVE_PTR;
    } /* Endif */

    /*
     * Walk through the memory resources of the task descriptor.
     * Two pointers are maintained, one to the current block
     * and one to the previous block.
     */
    next_block_ptr = (STOREBLOCK_STRUCT_PTR) td_ptr->MEMORY_RESOURCE_LIST;
    prev_block_ptr = (STOREBLOCK_STRUCT_PTR)((uchar_ptr) (&td_ptr->MEMORY_RESOURCE_LIST)
                    - FIELD_OFFSET(STOREBLOCK_STRUCT,NEXTBLOCK));

    /*
     * Scan the task's memory resource list searching for the block to
     * free, Stop when the current pointer is equal to the block to free
     * or the end of the list is reached.
     */
    while (next_block_ptr && ((pointer) next_block_ptr != mem_ptr)) {
        /*
         * The block is not found, and the end of the list has not been
         * reached, so move down the list.
         */
        prev_block_ptr = GET_MEMBLOCK_PTR(next_block_ptr);
        next_block_ptr = (STOREBLOCK_STRUCT_PTR) prev_block_ptr->NEXTBLOCK;
    } /* Endwhile */

#if MQX_CHECK_ERRORS
    if (next_block_ptr == NULL) {
        _int_enable();
        /* The specified block does not belong to the calling task. */
        _task_set_error(MQX_NOT_RESOURCE_OWNER);
        _KLOGX2(KLOG_mem_free, MQX_NOT_RESOURCE_OWNER);
        return (MQX_NOT_RESOURCE_OWNER);
    } /* Endif */
#endif

    /* Remove the memory block from the resource list of the calling task. */
    prev_block_ptr->NEXTBLOCK = block_ptr->NEXTBLOCK;

#if MQX_ALLOW_TYPED_MEMORY
    block_ptr->MEM_TYPE = 0;
#endif

    /*
     * Check if the neighbouring blocks are free, so we
     * can coalesce the blocks.
     */
    if (_mem_check_coalesce_internal(block_ptr)) {
        /* No need to add block to free list if coalesced */
        _INT_ENABLE();
        _KLOGX2(KLOG_mem_free, MQX_OK);
        return (MQX_OK);
    } /* Endif */

#if MQX_MEMORY_FREE_LIST_SORTED == 1

    next_block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
    if (next_block_ptr != NULL) {

        /* Insertion sort into the free list by address*/
        while (next_block_ptr < block_ptr) {
            /* This takes some time, so allow higher priority tasks
             * to interrupt us.
             */

            if (NEXT_FREE(next_block_ptr) == NULL) {
                /* At end of free list */
                break;
            } /* Endif */

            next_block_ptr = (STOREBLOCK_STRUCT_PTR) NEXT_FREE(next_block_ptr);

            /* Save the current location in case premption occurs */
            mem_pool_ptr->POOL_FREE_CURRENT_BLOCK = next_block_ptr;
            _INT_ENABLE();
            _INT_DISABLE();

            /* Pick up where left off */
            next_block_ptr = mem_pool_ptr->POOL_FREE_CURRENT_BLOCK;

            if (_mem_check_coalesce_internal(block_ptr)) {
                /* No need to add block to free list if coalesced */
                _INT_ENABLE();
                _KLOGX2(KLOG_mem_free, MQX_OK);
                return (MQX_OK);
            } /* Endif */
        } /* Endwhile */

    } /* Endif */

    /* We have found the correct location */

    /* Make the block a free block */
    block_ptr->NEXTBLOCK = NULL;
    block_ptr->BLOCKSIZE = block_ptr->BLOCKSIZE;
    MARK_BLOCK_AS_FREE(block_ptr);
    CALC_CHECKSUM(block_ptr);

    /* Insert current block just before next block */
    if (next_block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR) {
        /* We are inserting at the head of the free list */
        mem_pool_ptr->POOL_FREE_LIST_PTR = block_ptr;
        if (next_block_ptr != NULL) {
            PREV_FREE( next_block_ptr) = (pointer) block_ptr;
        } /* Endif */
        PREV_FREE( block_ptr) = NULL;
        NEXT_FREE( block_ptr) = (pointer) next_block_ptr;

    }
    else if (next_block_ptr < block_ptr) {
        /* We are inserting at the end of the free list */
        NEXT_FREE( block_ptr) = NULL;
        PREV_FREE( block_ptr) = (pointer) next_block_ptr;
        NEXT_FREE( next_block_ptr) = (pointer) block_ptr;

    }
    else {
        /* We are inserting into the middle of the free list */
        PREV_FREE( block_ptr) = PREV_FREE(next_block_ptr);
        PREV_FREE( next_block_ptr) = (pointer) block_ptr;
        NEXT_FREE( block_ptr) = (pointer) next_block_ptr;
        NEXT_FREE( PREV_FREE(
            block_ptr)) = (pointer) block_ptr;
    } /* Endif */

    /*
     * Reset the freelist current block pointer in case we pre-empted
     * another task
     */
    mem_pool_ptr->POOL_FREE_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

#else

    /* Make the block a free block */
    block_ptr->NEXTBLOCK = NULL;
    MARK_BLOCK_AS_FREE(block_ptr);
    CALC_CHECKSUM(block_ptr);

    /* Put the block at the head of the free list */
    next_block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;
    mem_pool_ptr->POOL_FREE_LIST_PTR = block_ptr;

    if ( next_block_ptr != NULL ) {
        PREV_FREE(next_block_ptr) = (pointer)block_ptr;
    } /* Endif */
    PREV_FREE(block_ptr) = NULL;
    NEXT_FREE(block_ptr) = (pointer)next_block_ptr;

#endif

    /* Reset the _mem_test pointers */
    mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK = (STOREBLOCK_STRUCT_PTR) mem_pool_ptr->POOL_PTR;
    mem_pool_ptr->POOL_FREE_CHECK_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

    _INT_ENABLE();
    _KLOGX2(KLOG_mem_free, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \private
 *
 * \brief This function coalesces any free block found adjacent to the provided
 * block.
 *
 * \param[in] passed_block_ptr An Address of a memory block, whose neighbours
 * has to be checked to see if they are free.
 *
 * \return TRUE (Coalescing was performed), FALSE (Coalescing was not performed).
 */
boolean _mem_check_coalesce_internal
(
    STOREBLOCK_STRUCT_PTR passed_block_ptr
)
{ /* Body */
    register STOREBLOCK_STRUCT_PTR block_ptr;
    register STOREBLOCK_STRUCT_PTR prev_block_ptr;
    register STOREBLOCK_STRUCT_PTR next_block_ptr;
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    boolean have_coalesced = FALSE;

    block_ptr = passed_block_ptr;
    mem_pool_ptr = (MEMPOOL_STRUCT_PTR) block_ptr->MEM_POOL_PTR;

    /* Check the previous physical neighbour */
    prev_block_ptr = PREV_PHYS(block_ptr);
    if ((prev_block_ptr != NULL) && BLOCK_IS_FREE(prev_block_ptr)) {
        /* the block previous to this one is free */

        /*  make the current block a free block so it can't be freed again */
        block_ptr->NEXTBLOCK = NULL;
        MARK_BLOCK_AS_FREE(block_ptr);

        /* Add the current block to the previous block */
        prev_block_ptr->BLOCKSIZE += block_ptr->BLOCKSIZE;

        /* Modify the next physical block to point to the previous block */
        next_block_ptr = NEXT_PHYS(block_ptr);
        PREV_PHYS( next_block_ptr) = prev_block_ptr;
        CALC_CHECKSUM(prev_block_ptr);
        CALC_CHECKSUM(next_block_ptr);

        block_ptr = prev_block_ptr; /* Set up as the current block */
        have_coalesced = TRUE;

    } /* Endif */

    /* Now, check the next block to see if it is free */
    next_block_ptr = NEXT_PHYS(block_ptr);
    if (BLOCK_IS_FREE(next_block_ptr)) {
        /* the next block is free */

        if (mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK == next_block_ptr) {
            /* We must modify the _mem_alloc pointer to not point
             ** at the next block
             */
            mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = block_ptr;
        } /* Endif */

        if (have_coalesced) {
            /* the current block is already on the free list */

            /* Remove the block from the free list */
            if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR) {
                mem_pool_ptr->POOL_FREE_LIST_PTR = (STOREBLOCK_STRUCT_PTR) NEXT_FREE(block_ptr);
                if (NEXT_FREE(block_ptr) != NULL) {
                    PREV_FREE( NEXT_FREE(
                        block_ptr)) = 0;
                } /* Endif */
            }
            else {
                NEXT_FREE( PREV_FREE(
                    block_ptr)) = NEXT_FREE(block_ptr);
                if (NEXT_FREE(block_ptr) != NULL) {
                    PREV_FREE( NEXT_FREE(
                        block_ptr)) = PREV_FREE(block_ptr);
                } /* Endif */
            } /* Endif */

        }
        else {

            /* Make the block a free block */
            block_ptr->NEXTBLOCK = NULL;
            MARK_BLOCK_AS_FREE(block_ptr);

        } /* Endif */

        /*
         * The current block is now a free block not on the free list .
         * the freelist pointers have to be modified so that the next
         * block is removed from the list, replace with the current block.
         */

        /* set the next free block to be the same as the one on the free list */
        NEXT_FREE( block_ptr) = NEXT_FREE(next_block_ptr);

        /*
         * And set the back pointer of the block after the next free block
         * to point back to the current block
         */
        if (NEXT_FREE(block_ptr) != NULL) {
            PREV_FREE( NEXT_FREE(
                block_ptr)) = (STOREBLOCK_STRUCT_PTR) block_ptr;
        } /* Endif */

        if (next_block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR) {
            /*
             * If the next block pointer was at the head of the free list,
             * the kernel free list pointer must be updated
             */
            mem_pool_ptr->POOL_FREE_LIST_PTR = block_ptr;
            PREV_FREE( block_ptr) = NULL;
        }
        else {
            /*
             * Otherwise we need to adjust the pointers of the block that
             * was previous to the next block on the free list
             */
            PREV_FREE( block_ptr) = PREV_FREE(next_block_ptr);
            if (PREV_FREE(block_ptr) != NULL) {
                NEXT_FREE( PREV_FREE(
                    block_ptr)) = (pointer) block_ptr;
            } /* Endif */
        } /* Endif */

        /* Add the next block onto the current block */
        block_ptr->BLOCKSIZE += next_block_ptr->BLOCKSIZE;

        /*
         * Reset the previous physical block pointer of
         * the block after the next block (ie the next next block)
         */
        prev_block_ptr = NEXT_PHYS(next_block_ptr);
        PREV_PHYS( prev_block_ptr) = block_ptr;
        CALC_CHECKSUM(prev_block_ptr);
        CALC_CHECKSUM(block_ptr);

        have_coalesced = TRUE;
    } /* Endif */

    if (have_coalesced) {

        /* Reset the _mem_test pointers */
        mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK = (STOREBLOCK_STRUCT_PTR) mem_pool_ptr->POOL_PTR;
        mem_pool_ptr->POOL_FREE_CHECK_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

#if MQX_MEMORY_FREE_LIST_SORTED == 1
        /*
         * Reset the freelist current block pointer in case we pre-empted
         * another task
         */
        mem_pool_ptr->POOL_FREE_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;
#endif
    } /* Endif */

    return (have_coalesced);

} /* Endbody */

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] pool_id Pool from which to allocate the memory block (from
 * _mem_create_pool()).
 * \param[in] size    Size of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_system_from
(
    _mem_pool_id pool_id,
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    MEMPOOL_STRUCT_PTR mem_pool_ptr = (MEMPOOL_STRUCT_PTR) pool_id;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_mem_alloc_system_from, size);

    _INT_DISABLE();
    result = _mem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), mem_pool_ptr, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    _KLOGX3(KLOG_mem_alloc_system_from, result, mem_pool_ptr->POOL_BLOCK_IN_ERROR);

    return (result);

} /* Endbody */

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] size Size of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_system
(
    _mem_size size
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc_system, size);

    _INT_DISABLE();
    result = _mem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), (MEMPOOL_STRUCT_PTR) & kernel_data->KD_POOL, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    kernel_data->KD_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->KD_POOL.POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    _KLOGX3(KLOG_mem_alloc_system, result, kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR);

    return (result);
}

#if MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE

/*!
 * \brief Allocates uncached memory that is available system wide.
 *
 * \param[in] size Size of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 */
pointer _mem_alloc_system_uncached
(
    _mem_size size
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint error;
    pointer result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc_system, size);

    _INT_DISABLE();
    result = _mem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), (MEMPOOL_STRUCT_PTR)kernel_data->UNCACHED_POOL, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    kernel_data->UNCACHED_POOL->POOL_ALLOC_CURRENT_BLOCK = kernel_data->UNCACHED_POOL->POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    _KLOGX3(KLOG_mem_alloc_system, result, kernel_data->UNCACHED_POOL->POOL_BLOCK_IN_ERROR);

    return(result);
}

#endif /* MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE */
/*!
 * \private
 *
 * \brief This function initializes the memory storage pool.
 *
 * \return MQX_OK
 * \return MQX_CORRUPT_MEMORY_SYSTEM (Internal data for the message component is
 * corrupted.)
 * \return MQX_MEM_POOL_TOO_SMALL (Size is less than the minimum allowable
 * message-pool size.)
  */
_mqx_uint _mem_init_internal
(
    void
)
{ /* Body */
#if MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE
    pointer __uncached_data_start = (pointer )__UNCACHED_DATA_START;
    pointer __uncached_data_end   = (pointer )__UNCACHED_DATA_END;
#endif /* MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE */

    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer start;
    _mqx_uint result;

    _GET_KERNEL_DATA(kernel_data);

    _QUEUE_INIT(&kernel_data->MEM_COMP.POOLS, 0);

    _lwsem_create((LWSEM_STRUCT_PTR) &kernel_data->MEM_COMP.SEM, 1);

    kernel_data->MEM_COMP.VALID = MEMPOOL_VALID;

    /*
     * Move the MQX memory pool pointer past the end of kernel data.
     */
    start = (pointer) ((uchar_ptr) kernel_data + sizeof(KERNEL_DATA_STRUCT));

    result = _mem_create_pool_internal(start, kernel_data->INIT.END_OF_KERNEL_MEMORY, (MEMPOOL_STRUCT_PTR)
                    & kernel_data->KD_POOL);

#if MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE
    if (result == MQX_OK) {
        if ((__uncached_data_start <=  start) && (start <= __uncached_data_end)) {
            kernel_data->UNCACHED_POOL = &kernel_data->KD_POOL;
        }
        else {
            /* The pool state structure is created at the bottom of the pool */
            kernel_data->UNCACHED_POOL = (MEMPOOL_STRUCT_PTR)_mem_create_pool(__uncached_data_start, (_mem_size)__uncached_data_end - (_mem_size)__uncached_data_start);
        }
    }
#endif /* MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE */
    return result;

} /* Endbody */

/*!
 * \private
 *
 * \brief This routine returns what the next memory block is for a given memory
 * block (where the memory block is on a tasks resource list).
 *
 * \param[in] td_ptr     The task descriptor being checked.
 * \param[in] memory_ptr The address (USERS_AREA) of the memory block.
 *
 * return Pointer to next block.
 */
pointer _mem_get_next_block_internal
(
    TD_STRUCT_PTR td_ptr,
    pointer memory_ptr
)
{ /* Body */
    STOREBLOCK_STRUCT_PTR block_ptr;

    if (memory_ptr == NULL) {
        return (td_ptr->MEMORY_RESOURCE_LIST);
    }
    else {
        block_ptr = GET_MEMBLOCK_PTR(memory_ptr);
        return (block_ptr->NEXTBLOCK);
    } /* Endif */

} /* Endbody */

/*!
 * \brief Gets the allocated size (in bytes) of a block allocated using the MQX
 * storage allocator (_mem_alloc).
 *
 * The size is the actual size of the memory block and might be larger than the
 * size that a task requested.
 *
 * \param[in] mem_ptr Address of the memory block whose size is wanted.
 *
 * \return Number of single-addressable units in the block (Success.)
 * \return 0 (Failure.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL (Memory is corrupted or mem_ptr does not point
 * to a block that was allocated with a function from the _mem_alloc family.)
 * \li MQX_INVALID_CHECKSUM (Checksum is not correct because part of the memory
 * block header was overwritten.)
 * \li MQX_INVALID_POINTER (Mem_ptr is NULL or improperly aligned.)
 *
 * \see _mem_free
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_free_part
 * \see _task_set_error
 */
_mem_size _mem_get_size
(
    pointer mem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    STOREBLOCK_STRUCT_PTR block_ptr;
    _mem_size size;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (mem_ptr == NULL) {
        _task_set_error(MQX_INVALID_POINTER);
        return (0);
    } /* Endif */
#endif

    /* Compute the start of the block  */
    block_ptr = GET_MEMBLOCK_PTR(mem_ptr);

#if MQX_CHECK_ERRORS
    if (!_MEMORY_ALIGNED(block_ptr)) {
        _task_set_error(MQX_INVALID_POINTER);
        return (0);
    } /* Endif */
#endif

    size = block_ptr->BLOCKSIZE;

#if MQX_CHECK_ERRORS
    /* For all free blocks, a check is made to ensure that the user
     * has not corrupted the storage pool. This is done by checking the
     * 'magic value', which should not be corrupted. Alternatively, the
     * user could have passed in an invalid memory pointer.
     */
    if (BLOCK_IS_FREE(block_ptr)) {
        kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
        _task_set_error(MQX_CORRUPT_STORAGE_POOL);
        return (0);
    } /* Endif */

#endif

#if MQX_CHECK_VALIDITY
    if ((!VALID_CHECKSUM(block_ptr))) {
        kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
        _task_set_error(MQX_INVALID_CHECKSUM);
        return (0);
    } /* Endif */
#endif

    /* The size includes the block overhead, which the user is not
     * interested in. If the size is less than the overhead,
     * then there is a bad block or bad block pointer.
     */
#if MQX_CHECK_ERRORS
    if (size <= (_mem_size) FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA)) {
        kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
        _task_set_error(MQX_CORRUPT_STORAGE_POOL);
        return (0);
    } /* Endif */
#endif

    return (size - (_mem_size) FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA));

} /* Endbody */

/*!
 * \brief This function checks the all memory pool for any errors.
 *
 * \param[out] pool_error_ptr Pointer to the memory pool in error (initialized
 * only if an error was found).
 *
 * \return MQX_OK (No errors found.)
 * \return Errors from _mem_test() (A memory pool has an error.)
 * \return Errors from _queue_test() (Memory-pool queue has an error.)
 *
 * \see _mem_test
 * \see _mem_test_pool
 * \see _queue_test
 */
_mqx_uint _mem_test_all
(
    _mem_pool_id _PTR_ pool_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    MEMPOOL_STRUCT_PTR pool_ptr;
    _mqx_uint result;

    _GET_KERNEL_DATA(kernel_data);

    /* Use a semaphore to protect the list of pools */
    _lwsem_wait((LWSEM_STRUCT_PTR) &kernel_data->MEM_COMP.SEM);

    /* Make sure that the queue of memory pools is ok */
    result = _queue_test((QUEUE_STRUCT_PTR) &kernel_data->MEM_COMP.POOLS, (pointer _PTR_) pool_error_ptr);

    _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->MEM_COMP.SEM);

    if (result != MQX_OK) {
        return (result);
    } /* Endif */

    /* Now test application pools */
    _lwsem_wait((LWSEM_STRUCT_PTR) &kernel_data->MEM_COMP.SEM);
    pool_ptr = (MEMPOOL_STRUCT_PTR)((pointer) kernel_data->MEM_COMP.POOLS.NEXT);
    while (pool_ptr != (MEMPOOL_STRUCT_PTR)((pointer) &kernel_data->MEM_COMP.POOLS)) {
        result = _mem_test_pool(pool_ptr);
        if (result != MQX_OK) {
            break;
        } /* Endif */
        pool_ptr = (MEMPOOL_STRUCT_PTR)((pointer) pool_ptr->LINK.NEXT);
    } /* Endwhile */

    _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->MEM_COMP.SEM);

    *pool_error_ptr = (_mem_pool_id) pool_ptr;
    return (result);

} /* Endbody */

/*!
 * \brief Tests the memory in the memory pool.
 *
 * If _mem_test_pool() indicates an error, _mem_get_error_pool() indicates which
 * block has the error.
 *
 * \param[in] pool_id The pool to check.
 *
 * \return MQX_OK (No errors found.)
 * \return MQX_CORRUPT_STORAGE_POOL (A memory pool pointer is not correct.)
 * \return MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \return MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect (header is corrupted).)
 *
 * \see _mem_get_error_pool
 * \see _mem_test
 * \see _task_set_error
 */
_mqx_uint _mem_test_pool
(
    _mem_pool_id pool_id
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    STOREBLOCK_STRUCT_PTR next_block_ptr;
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    _mqx_uint result = MQX_OK;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE2(KLOG_mem_test_pool, pool_id);

    mem_pool_ptr = (MEMPOOL_STRUCT_PTR) pool_id;

    /* First check the physical blocks */
    mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK = (STOREBLOCK_STRUCT_PTR) mem_pool_ptr->POOL_PTR;
    while (mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK < mem_pool_ptr->POOL_END_PTR) {
        if ((!mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK) || (!_MEMORY_ALIGNED(mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK))) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = (STOREBLOCK_STRUCT_PTR) mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK;
            result = MQX_CORRUPT_STORAGE_POOL;
            break;
        } /* Endif */

        _int_disable();
        if (!VALID_CHECKSUM(mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK)) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = (STOREBLOCK_STRUCT_PTR) mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK;
            _int_enable();
            result = MQX_INVALID_CHECKSUM;
            break;
        } /* Endif */

        next_block_ptr = NEXT_PHYS(mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK);
        if (next_block_ptr->PREVBLOCK != mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = next_block_ptr;
            _int_enable();
            result = MQX_CORRUPT_STORAGE_POOL;
            break;
        } /* Endif */
        mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK = next_block_ptr;
        _int_enable();

    } /* Endwhile */

    if (result != MQX_OK) {
        _KLOGX3(KLOG_mem_test_pool, result, mem_pool_ptr->POOL_BLOCK_IN_ERROR);
        return (result);
    } /* Endif */

    /* Now check the free list */
    _int_disable();
    if (mem_pool_ptr->POOL_FREE_LIST_PTR == NULL) { /* no free list to check */
        _int_enable();
        return MQX_OK;
    } /* Endif */

    mem_pool_ptr->POOL_FREE_CHECK_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;
    next_block_ptr = mem_pool_ptr->POOL_FREE_CHECK_BLOCK;
    if (next_block_ptr->USER_AREA != (pointer) NULL) {
        _KLOGX3(KLOG_mem_test_pool, MQX_CORRUPT_STORAGE_POOL_FREE_LIST, next_block_ptr );
        mem_pool_ptr->POOL_BLOCK_IN_ERROR = next_block_ptr;
        _int_enable();
        return (MQX_CORRUPT_STORAGE_POOL_FREE_LIST);
    } /* Endif */

    _int_enable();

    while (mem_pool_ptr->POOL_FREE_CHECK_BLOCK < mem_pool_ptr->POOL_END_PTR) {
        if ((!mem_pool_ptr->POOL_FREE_CHECK_BLOCK) || (!_MEMORY_ALIGNED(mem_pool_ptr->POOL_FREE_CHECK_BLOCK))) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = mem_pool_ptr->POOL_FREE_CHECK_BLOCK;
            result = MQX_CORRUPT_STORAGE_POOL_FREE_LIST;
            break;
        } /* Endif */

        _int_disable();
        if (!VALID_CHECKSUM(mem_pool_ptr->POOL_FREE_CHECK_BLOCK)) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = mem_pool_ptr->POOL_FREE_CHECK_BLOCK;
            _int_enable();
            result = MQX_INVALID_CHECKSUM;
            break;
        } /* Endif */
        _int_enable();

        _int_disable();
        if (BLOCK_IS_USED(mem_pool_ptr->POOL_FREE_CHECK_BLOCK)) {
            /* An allocated block on the free list */
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = mem_pool_ptr->POOL_FREE_CHECK_BLOCK;
            _int_enable();
            result = MQX_CORRUPT_STORAGE_POOL_FREE_LIST;
            break;
        } /* Endif */

        next_block_ptr = (STOREBLOCK_STRUCT_PTR) NEXT_FREE(mem_pool_ptr->POOL_FREE_CHECK_BLOCK);
        if (!next_block_ptr) {
            _int_enable(); /* If zero, free list has been completed */
            break;
        } /* Endif */
        if (next_block_ptr->USER_AREA != (char _PTR_) mem_pool_ptr->POOL_FREE_CHECK_BLOCK) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = mem_pool_ptr->POOL_FREE_CHECK_BLOCK;
            _int_enable();
            result = MQX_CORRUPT_STORAGE_POOL_FREE_LIST;
            break;
        } /* Endif */
        mem_pool_ptr->POOL_FREE_CHECK_BLOCK = next_block_ptr;
        _int_enable();

    } /* Endwhile */

    if (result == MQX_OK) {
        _KLOGX2(KLOG_mem_test_pool, result);
    }
    else {
        _KLOGX3(KLOG_mem_test_pool, result, mem_pool_ptr->POOL_BLOCK_IN_ERROR);
    } /* Endif */
    return (result);

} /* Endbody */

/*!
 * \brief Tests memory that the memory component uses to allocate memory from
 * the default memory pool.
 *
 * The function checks the checksums of all memory-block headers. If the
 * function detects an error, _mem_get_error() gets the block in error.
 * \n The function can be called by only one task at a time because it keeps
 * state-in-progress variables that MQX controls. This mechanism lets other
 * tasks allocate and free memory while _mem_test() runs.
 *
 * \return MQX_OK (No errors found.)
 * \return MQX_CORRUPT_STORAGE_POOL (A memory pool pointer is not correct.)
 * \return MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \return MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect (header is corrupted).)
 *
 * \warning Can be called by only one task at a time (see Description).
 * \warning Disables and enables interrupts.
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_get_error
 * \see _mem_test_pool
 */
_mqx_uint _mem_test
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint result;

    _GET_KERNEL_DATA(kernel_data);

    result = _mem_test_pool((_mem_pool_id) &kernel_data->KD_POOL);

    return (result);

} /* Endbody */

/*!
 * \brief Gets the highest memory address that MQX has allocated in the default
 * memory pool.
 *
 * The function gets the highwater mark; that is, the highest memory address
 * ever allocated by MQX in the default memory pool. The mark does not decrease
 * if tasks free memory in the default memory pool.
 * \n If a task extends the default memory pool (_mem_extend()) with an area
 * above the highwater mark and MQX subsequently allocates memory from the
 * extended memory, the function returns an address from the extended memory.
 *
 * \return Highest address allocated in the default memory pool.
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_extend
 * \see _mem_get_highwater_pool
 */
pointer _mem_get_highwater
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    return (kernel_data->KD_POOL.POOL_HIGHEST_MEMORY_USED);

} /* Endbody */

/*!
 * \brief Gets the highest memory address that MQX has allocated in the pool.
 *
 * The function gets the highwater mark; that is, the highest memory address
 * ever allocated in the memory pool. The mark does not decrease if tasks free
 * blocks in the pool.
 * \n If a task extends the memory pool (_mem_extend_pool()) with an area above
 * the highwater mark and MQX subsequently allocates memory from the extended
 * memory, the function returns an address from the extended memory.
 *
 * \param[in] pool_id Pool for which to get the highwater mark (from
 * _mem_create_pool()).
 *
 * \return Highest address allocated in the memory pool.
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mem_create_pool
 * \see _mem_extend_pool
 * \see _mem_get_highwater
 */
pointer _mem_get_highwater_pool
(
    _mem_pool_id pool_id
)
{ /* Body */
    MEMPOOL_STRUCT_PTR mem_pool_ptr = (MEMPOOL_STRUCT_PTR) pool_id;

    return (mem_pool_ptr->POOL_HIGHEST_MEMORY_USED);

} /* Endbody */

/*!
 * \brief Gets the last memory block which caused a corrupt memory pool error in
 * kernel data.
 *
 * If _mem_test() indicates an error in the default memory pool, _mem_get_error()
 * indicates which block has the error.
 * \n In each memory block header, MQX maintains internal information, including
 * a checksum of the information. As tasks call functions from the _mem family,
 * MQX recalculates the checksum and compares it with the original. If the
 * checksums do not match, MQX marks the block as corrupted.
 * \n A block will be corrupted if:
 * \n - A task writes past the end of an allocated memory block and into the
 * header information in the next block. This can occur if:
 * \li The task allocated a block smaller than it needed.
 * \li A task overflows its stack.
 * \li A pointer is out of range.
 *
 * \n - A task randomly overwrites memory in the default memory pool.
 *
 * \return Pointer to the memory block that is corrupted.
 *
 * \see _mem_test
 */
pointer _mem_get_error
(
    void
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register pointer user_ptr;

    _GET_KERNEL_DATA(kernel_data);

    user_ptr = (pointer) ((uchar_ptr) kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR
                    + FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA));
    return (user_ptr);

} /* Endbody */

/*!
 * \brief Gets the last memory block which caused a corrupt memory pool error in
 * the specified pool.
 *
 * \param[in] pool_id Memory pool from which to get the block.
 *
 * \return Pointer to the memory block.
 *
 * \see _mem_test_pool
 */
pointer _mem_get_error_pool
(
    _mem_pool_id pool_id
)
{ /* Body */
    MEMPOOL_STRUCT_PTR mem_pool_ptr = (MEMPOOL_STRUCT_PTR) pool_id;
    register pointer user_ptr;

    user_ptr = (pointer) ((uchar_ptr) mem_pool_ptr->POOL_BLOCK_IN_ERROR + FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA));
    return (user_ptr);

} /* Endbody */

/*!
 * \brief Gets the pool ID of the system pool.
 *
 * \return system pool ID.
 */
_mem_pool_id _mem_get_system_pool_id
(
    void
)
{
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    return (_mem_pool_id) &kernel_data->KD_POOL;
}

#if MQX_ALLOW_TYPED_MEMORY
/*!
 * \brief Gets the type of the specified block.
 *
 * \param[in] mem_ptr Address of the memory block to get type of.
 *
 * \return Pointer to the memory block type.
 */
_mem_type _mem_get_type
(
    pointer mem_ptr
)
{
    STOREBLOCK_STRUCT_PTR block_ptr;

    block_ptr = GET_MEMBLOCK_PTR(mem_ptr);
    return block_ptr->MEM_TYPE;
}

/*!
 * \brief Sets type of the specified block.
 *
 * \param[in] mem_ptr  Address of the memory block to set type.
 * \param[in] mem_type Memory type to set.
 *
 * \return TRUE (Type has been set.), FALSE (Type has not been set.).
 */
boolean _mem_set_type
(
    pointer   mem_ptr,
    _mem_type mem_type
)
{
    STOREBLOCK_STRUCT_PTR block_ptr;

    if (mem_ptr != NULL) {
        block_ptr = GET_MEMBLOCK_PTR(mem_ptr);
        _int_disable();
        block_ptr->MEM_TYPE = mem_type;
        CALC_CHECKSUM(block_ptr);
        _int_enable();
        return TRUE;
    }
    else {
        return FALSE;
    }
}

#endif /* MQX_ALLOW_TYPED_MEMORY */

/*!
 * \brief Transfers the ownership of a block of memory from an owner task to
 * another task.
 *
 * \param[in] memory_ptr A memory block whose ownership is to be transferred.
 * \param[in] source_id  Task ID of the current owner.
 * \param[in] target_id  Task ID of the new owner.
 *
 * \return MQX_OK
 * \return MQX_INVALID_CHECKSUM (Block's checksum is not correct, indicating
 * that at least some of the block was overwritten.)
 * \return MQX_INVALID_POINTER (Block_ptr is NULL or misaligned.)
 * \return MQX_INVALID_TASK_ID (Source or target does not represent a valid task.)
 * \return MQX_NOT_RESOURCE_OWNER (Memory block is not a resource of the task
 * represented by source.)
 *
 * \warning On failure, calls _task_set_error() to set the error code (see Return).
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at
 * \see _mqx_get_system_task_id
 * \see _task_set_error
 */
_mqx_uint _mem_transfer
(
    pointer  memory_ptr,
    _task_id source_id,
    _task_id target_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    STOREBLOCK_STRUCT_PTR block_ptr;
    TD_STRUCT_PTR source_td;
    TD_STRUCT_PTR target_td;
    _mqx_uint result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_mem_transfer, memory_ptr, source_id, target_id);

#if MQX_CHECK_ERRORS
    if (memory_ptr == NULL) {
        _task_set_error(MQX_INVALID_POINTER);
        _KLOGX2(KLOG_mem_transfer, MQX_INVALID_POINTER);
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    /* Verify the block */
    block_ptr = GET_MEMBLOCK_PTR(memory_ptr);

#if MQX_CHECK_ERRORS
    if (!_MEMORY_ALIGNED(block_ptr)) {
        _task_set_error(MQX_INVALID_POINTER);
        _KLOGX2(KLOG_mem_transfer, MQX_INVALID_POINTER);
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

#if MQX_CHECK_VALIDITY
    if (!VALID_CHECKSUM(block_ptr)) {
        _task_set_error(MQX_INVALID_CHECKSUM);
        kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
        _KLOGX2(KLOG_mem_transfer, MQX_INVALID_CHECKSUM);
        return (MQX_INVALID_CHECKSUM);
    } /* Endif */
#endif

    source_td = (TD_STRUCT_PTR) _task_get_td(source_id);
    target_td = (TD_STRUCT_PTR) _task_get_td(target_id);

#if MQX_CHECK_ERRORS
    if ((source_td == NULL) || (target_td == NULL)) {
        _task_set_error(MQX_INVALID_TASK_ID);
        _KLOGX2(KLOG_mem_transfer, MQX_INVALID_TASK_ID);
        return (MQX_INVALID_TASK_ID);
    } /* Endif */
#endif

    _INT_DISABLE();

    result = _mem_transfer_td_internal(memory_ptr, source_td, target_td);
    if (result != MQX_OK) _task_set_error(result);

    _INT_ENABLE();

    _KLOGX2(KLOG_mem_transfer, result);
    return (result);

} /* Endbody */

/*!
 * \private
 *
 * \brief Transfers the ownership of a block of memory from an owner task to
 * another task.
 *
 * \param[in] memory_ptr Address of the USER_AREA in the memory block to transfer.
 * \param[in] target_td  Target task descriptor.
 */
void _mem_transfer_internal
(
    pointer       memory_ptr,
    TD_STRUCT_PTR target_td
)
{ /* Body */
    STOREBLOCK_STRUCT_PTR block_ptr;

    /* Verify the block */
    block_ptr = GET_MEMBLOCK_PTR(memory_ptr);

    /* Link the block onto the target's task descriptor. */
    block_ptr->NEXTBLOCK = target_td->MEMORY_RESOURCE_LIST;
    target_td->MEMORY_RESOURCE_LIST = (char _PTR_) (&block_ptr->USER_AREA);

    block_ptr->TASK_NUMBER = TASK_NUMBER_FROM_TASKID(target_td->TASK_ID);
    CALC_CHECKSUM(block_ptr);

} /* Endbody */

/*!
 * \private
 *
 * \brief Transfers the ownership of a block of memory from an owner task to
 * another task.
 *
 * \param[in] memory_ptr A memory block whose ownership is to be transferred.
 * \param[in] source_td  Task ID of the current owner.
 * \param[in] target_td  Task ID of the new owner.
 *
 * \return MQX_OK
 * \return MQX_NOT_RESOURCE_OWNER
 */
_mqx_uint _mem_transfer_td_internal
(
    pointer       memory_ptr,
    TD_STRUCT_PTR source_td,
    TD_STRUCT_PTR target_td
)
{ /* Body */
    STOREBLOCK_STRUCT_PTR block_ptr;
    STOREBLOCK_STRUCT_PTR prev_block_ptr = NULL; /* Initialize to supress compiler warning */
    STOREBLOCK_STRUCT_PTR next_block_ptr;

    block_ptr = GET_MEMBLOCK_PTR(memory_ptr);

    next_block_ptr = (STOREBLOCK_STRUCT_PTR) source_td->MEMORY_RESOURCE_LIST;

    /* prev_block_ptr = GET_MEMBLOCK_PTR(&source_td->MEMORY_RESOURCE_LIST); */
    if (memory_ptr == next_block_ptr) {
        /*
         * This is the last item on the resource list of the
         * source task. Remove it from the resource list by
         * pointing the resource list to the next item.
         */
        source_td->MEMORY_RESOURCE_LIST = block_ptr->NEXTBLOCK;
    }
    else {
        /* Scan the task's memory resource list searching for the block.
         * Stop when the current pointer is equal to the block,
         * or the end of the list is reached.
         */
        while (next_block_ptr && ((pointer) next_block_ptr != memory_ptr)) {
            prev_block_ptr = GET_MEMBLOCK_PTR(next_block_ptr);
            next_block_ptr = (STOREBLOCK_STRUCT_PTR) prev_block_ptr->NEXTBLOCK;
        } /* Endwhile */

        if (!next_block_ptr) {
            /* The specified block does not belong to the source task. */
            return (MQX_NOT_RESOURCE_OWNER);
        } /* Endif */

        /* Remove the memory block from the resource list of the
         * source task.
         */
        prev_block_ptr->NEXTBLOCK = block_ptr->NEXTBLOCK;
    } /* Endif */

    _mem_transfer_internal(memory_ptr, target_td);

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] pool_id Pool from which to allocate the memory block (from
 * _mem_create_pool()).
 * \param[in] size Size of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_form()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at()
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_system_zero_from
(
    _mem_pool_id pool_id,
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    MEMPOOL_STRUCT_PTR mem_pool_ptr;
    pointer result;
    _mqx_uint error;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc_system_zero_from, size);

    mem_pool_ptr = (MEMPOOL_STRUCT_PTR) pool_id;

    _INT_DISABLE();
    result = _mem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), mem_pool_ptr, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    if (result != NULL) {
        _mem_zero(result, size);
    } /* Endif */

    _KLOGX3(KLOG_mem_alloc_system_zero_from, result, mem_pool_ptr->POOL_BLOCK_IN_ERROR);

    return (result);

} /* Endbody */

/*!
 * \brief Allocates a block of memory.
 *
 * See Description of _mem_alloc() function.
 *
 * \param[in] size Size of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \see _mem_alloc()
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_form()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at()
 * \see _mem_create_pool
 * \see _mem_free
 * \see _mem_get_highwater
 * \see _mem_get_highwater_pool
 * \see _mem_get_size
 * \see _mem_transfer
 * \see _mem_free_part
 * \see _msg_alloc
 * \see _msg_alloc_system
 * \see _task_set_error
 */
pointer _mem_alloc_system_zero
(
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer result;
    _mqx_uint error;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mem_alloc_system_zero, size);

    _INT_DISABLE();
    result = _mem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), (MEMPOOL_STRUCT_PTR) & kernel_data->KD_POOL, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    kernel_data->KD_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->KD_POOL.POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    if (result != NULL) {
        _mem_zero(result, size);
    } /* Endif */

    _KLOGX3(KLOG_mem_alloc_system_zero, result, kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR);
    return (result);

}

#if MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE

/*!
 * \brief Allocates uncached memory from the system, zeroed.
 *
 * \param[in] size Size of the memory block.
 *
 * \return Pointer to the memory block (Success.)
 * \return NULL (Failure: see task error codes.)
 *
 * \warning On failure, calls _task_set_error() to set one of the following
 * task error codes:
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 */
pointer _mem_alloc_system_zero_uncached
(
    _mem_size size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer result;
    _mqx_uint error;

    _GET_KERNEL_DATA(kernel_data);
    /*_KLOGE2(KLOG_mem_alloc_system_zero_uncached, size);*/

    _INT_DISABLE();
    result = _mem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), (MEMPOOL_STRUCT_PTR)kernel_data->UNCACHED_POOL, &error);

    /* update the memory allocation pointer in case a lower priority
     * task was preempted inside _mem_alloc_internal
     */
    kernel_data->UNCACHED_POOL->POOL_ALLOC_CURRENT_BLOCK = kernel_data->UNCACHED_POOL->POOL_FREE_LIST_PTR;

    _INT_ENABLE();

#if MQX_CHECK_ERRORS
    if (error != MQX_OK) {
        _task_set_error(error);
    } /* Endif */
#endif

    if (result != NULL) {
        _mem_zero(result, size);
    } /* Endif */

    /*_KLOGX3(KLOG_mem_alloc_system_zero_uncached, result, kernel_data->UNCACHED_POOL.POOL_BLOCK_IN_ERROR);*/
    return(result);

}

#endif /* MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE */

/*!
 * \private
 *
 * \brief Internal function for memory allocation.
 *
 * This function must be called disabled.
 * \n A pointer to memory that can be used is returned. _mem_alloc_internal
 * walks down the free list, looking for a block big enough to satisfy the
 * request. If the found block is bigger than needed, then a new free block is
 * created from the remnants, and added into the free list.
 * \n A global memory pointer is used, this allows higher priority tasks to
 * pre-empt the current task in _mem_alloc_internal. Care is taken to make sure
 * that when the higher priority task is completed, the memory pool search
 * pointer is reset to the beginning of the free list.
 * \n Since the memory test function may be running concurrently with the
 * allocator, the memory test pointers are reset.
 *
 * \param[in]  requested_size Size of the memory block.
 * \param[in]  td_ptr         Owner's TD.
 * \param[in]  mem_pool_ptr   Which pool to allocate from.
 * \param[out] error_ptr      Error code for operation:
 * \li MQX_OK
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \return Pointer to the memory block (success)
 * \return NULL (Failure: see task error codes.)
 * \return (pointer) NULL (Failure: see task error codes.)
 */
pointer _mem_alloc_internal
(
    _mem_size          requested_size,
    TD_STRUCT_PTR      td_ptr,
    MEMPOOL_STRUCT_PTR mem_pool_ptr,
    _mqx_uint_ptr      error_ptr
)
{ /* Body */
    STOREBLOCK_STRUCT_PTR block_ptr;
    STOREBLOCK_STRUCT_PTR next_block_ptr;
    STOREBLOCK_STRUCT_PTR next_next_block_ptr;
    _mem_size block_size;
    _mem_size next_block_size;

    *error_ptr = MQX_OK;

    /*
     * Adjust message size to allow for block management overhead
     * and force size to be aligned.
     */
    requested_size += (_mem_size) (FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA));
#if MQX_CHECK_ERRORS
    if (requested_size < MQX_MIN_MEMORY_STORAGE_SIZE) {
        requested_size = MQX_MIN_MEMORY_STORAGE_SIZE;
    } /* Endif */
#endif

    _MEMORY_ALIGN_VAL_LARGER(requested_size);

    block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;

    while (TRUE) {

        /*
         * Save the current block pointer.
         * We will be enabling access to higher priority tasks.
         * A higher priority task may pre-empt the current task
         * and may do a memory allocation.  If this is true,
         * the higher priority task will reset the POOL_ALLOC_CURRENT_BLOCK
         * upon exit, and the current task will start the search over again.
         */
        mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = block_ptr;

        /* allow pending interrupts */
        _int_enable();
        _int_disable();

        /* Get block pointer in case reset by a higher priority task */
        block_ptr = mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK;

        if (block_ptr == NULL) { /* Null pointer */
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_OUT_OF_MEMORY;
            return (NULL); /* request failed */
        } /* Endif */

#if MQX_CHECK_VALIDITY
        if (!_MEMORY_ALIGNED(block_ptr) || BLOCK_IS_USED(block_ptr)) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_CORRUPT_STORAGE_POOL_FREE_LIST;
            return ((pointer) NULL);
        } /* Endif */
#endif

#if MQX_CHECK_VALIDITY
        if (!VALID_CHECKSUM(block_ptr)) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_INVALID_CHECKSUM;
            return ((pointer) NULL);
        } /* Endif */
#endif

        block_size = block_ptr->BLOCKSIZE;

        if (block_size >= requested_size) {
            /* request fits into this block */

            next_block_size = block_size - requested_size;
            if (next_block_size >= (2 * MQX_MIN_MEMORY_STORAGE_SIZE)) {
                /*
                 * The current block is big enough to split.
                 * into 2 blocks.... the part to be allocated is one block,
                 * and the rest remains as a free block on the free list.
                 */

                next_block_ptr = (STOREBLOCK_STRUCT_PTR)((char _PTR_) block_ptr + requested_size);

                /* Initialize the new physical block values */
                next_block_ptr->BLOCKSIZE = next_block_size;
                next_block_ptr->PREVBLOCK = (STOREBLOCK_STRUCT_PTR) block_ptr;
                MARK_BLOCK_AS_FREE(next_block_ptr);

                CALC_CHECKSUM(next_block_ptr);

                /* Link new block into the free list */
                next_block_ptr->NEXTBLOCK = block_ptr->NEXTBLOCK;
                block_ptr->NEXTBLOCK = (pointer) next_block_ptr;

                next_block_ptr->USER_AREA = (pointer) block_ptr;
                if (next_block_ptr->NEXTBLOCK != NULL) {
                    ((STOREBLOCK_STRUCT_PTR) next_block_ptr->NEXTBLOCK)-> USER_AREA = (pointer) next_block_ptr;
                } /* Endif */

                /*
                 * Modify the block on the other side of the next block
                 * (the next next block) so that it's previous block pointer
                 * correctly point to the next block.
                 */
                next_next_block_ptr = (STOREBLOCK_STRUCT_PTR) NEXT_PHYS(next_block_ptr);
                PREV_PHYS( next_next_block_ptr) = next_block_ptr;
                CALC_CHECKSUM(next_next_block_ptr);

            }
            else {

                /* Take the entire block */
                requested_size = block_size;

            } /* Endif */

            /* Set the size of the block */
            block_ptr->BLOCKSIZE = requested_size;

            /* Indicate the block is in use */
            MARK_BLOCK_AS_USED(block_ptr, td_ptr->TASK_ID);
            block_ptr->MEM_TYPE = 0;

            CALC_CHECKSUM(block_ptr);

            /* Unlink the block from the free list */
            if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR) {
                /* At the head of the free list */

                mem_pool_ptr->POOL_FREE_LIST_PTR = (STOREBLOCK_STRUCT_PTR) NEXT_FREE(block_ptr);
                if (mem_pool_ptr->POOL_FREE_LIST_PTR != NULL) {
                    PREV_FREE(mem_pool_ptr->POOL_FREE_LIST_PTR) = 0;
                } /* Endif */

            }
            else {

                /*
                 * NOTE: PREV_FREE guaranteed to be non-zero
                 * Have to make the PREV_FREE of this block
                 * point to the NEXT_FREE of this block
                 */
                NEXT_FREE( PREV_FREE(
                    block_ptr)) = NEXT_FREE(block_ptr);
                if (NEXT_FREE(block_ptr) != NULL) {
                    /*
                     * Now have to make the NEXT_FREE of this block
                     * point to the PREV_FREE of this block
                     */
                    PREV_FREE( NEXT_FREE(
                        block_ptr)) = PREV_FREE(block_ptr);
                } /* Endif */

            } /* Endif */

#if MQX_MEMORY_FREE_LIST_SORTED == 1
            if (block_ptr == mem_pool_ptr->POOL_FREE_CURRENT_BLOCK) {
                /* Reset the freelist insertion sort by _mem_free */
                mem_pool_ptr->POOL_FREE_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;
            } /* Endif */
#endif

            /* Reset the __mem_test freelist pointer */
            mem_pool_ptr->POOL_FREE_CHECK_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

            /*
             * Set the curent pool block to the start of the free list, so
             * that if this task pre-empted another that was performing a
             * _mem_alloc, the other task will restart it's search for a block
             */
            mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

            /* Remember some statistics - only for blocks which fall into the
             * main pool area. Ignore blocks in the extended areas (EXT_LIST)
             */
            next_block_ptr = NEXT_PHYS(block_ptr);
            if (((char _PTR_)(next_block_ptr) > (char _PTR_) mem_pool_ptr->POOL_HIGHEST_MEMORY_USED) &&
                ((char _PTR_)(next_block_ptr) > (char _PTR_) mem_pool_ptr->POOL_PTR) &&
                ((char _PTR_)(next_block_ptr) < (char _PTR_) mem_pool_ptr->POOL_END_PTR)
                )
            {
               mem_pool_ptr->POOL_HIGHEST_MEMORY_USED = ((char _PTR_)(next_block_ptr) - 1);
            } /* Endif */

            /* Link the block onto the task descriptor. */
            block_ptr->NEXTBLOCK = td_ptr->MEMORY_RESOURCE_LIST;
            td_ptr->MEMORY_RESOURCE_LIST = (pointer) (&block_ptr->USER_AREA);

            block_ptr->MEM_POOL_PTR = (pointer) mem_pool_ptr;

#if MQX_CHECK_VALIDITY
            /* Check that user area is aligned on a cache line boundary */
            if (!_MEMORY_ALIGNED(&block_ptr->USER_AREA)) {
                *error_ptr = MQX_INVALID_CONFIGURATION;
                return ((pointer) NULL);
            } /* Endif */
#endif

            return ((pointer) (&block_ptr->USER_AREA));

        }
        else {
            block_ptr = (STOREBLOCK_STRUCT_PTR) NEXT_FREE(block_ptr);
        } /* Endif */

    } /* Endwhile */

#ifdef lint
    return( NULL ); /* to satisfy lint */
#endif

} /* Endbody */

/*!
 * \private
 *
 * \brief Internal function for memory allocation at specified position.
 *
 * \param[in]  requested_size Size of the memory block.
 * \param[in]  requested_addr Address of the memory block to allocate.
 * \param[in]  td_ptr         Owner TD.
 * \param[in]  mem_pool_ptr   Which pool to allocate from.
 * \param[out] error_ptr      Error code for operation:
 * \li MQX_OK
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \return Pointer to the memory block (success)
 * \return NULL (Failure: see task error codes.)
 * \return (pointer) NULL (Failure: see task error codes.)
 */
pointer _mem_alloc_at_internal
(
    _mem_size          requested_size,
    pointer            requested_addr,
    TD_STRUCT_PTR      td_ptr,
    MEMPOOL_STRUCT_PTR mem_pool_ptr,
    _mqx_uint_ptr      error_ptr
)
{ /* Body */
    STOREBLOCK_STRUCT_PTR block_ptr, free_block_ptr;
    STOREBLOCK_STRUCT_PTR next_block_ptr;
    STOREBLOCK_STRUCT_PTR next_next_block_ptr;
    _mem_size block_size, next_block_size, free_block_size;

    *error_ptr = MQX_OK;

    /*
     * Adjust message size to allow for block management overhead
     * and force size to be aligned.
     */
    requested_size += (_mem_size) (FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA));
#if MQX_CHECK_ERRORS
    if (requested_size < MQX_MIN_MEMORY_STORAGE_SIZE) {
        requested_size = MQX_MIN_MEMORY_STORAGE_SIZE;
    } /* Endif */
#endif

    _MEMORY_ALIGN_VAL_LARGER(requested_size);

    block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;

    while (TRUE) {

        /*
         * Save the current block pointer.
         * We will be enabling access to higher priority tasks.
         * A higher priority task may pre-empt the current task
         * and may do a memory allocation.  If this is true,
         * the higher priority task will reset the POOL_ALLOC_CURRENT_BLOCK
         * upon exit, and the current task will start the search over
         * again.
         */
        mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = block_ptr;

        /* allow pending interrupts */
        _int_enable();
        _int_disable();

        /* Get block pointer in case reset by a higher priority task */
        block_ptr = mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK;

        if (block_ptr == NULL) { /* Null pointer */
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_OUT_OF_MEMORY;
            return (NULL); /* request failed */
        } /* Endif */

#if MQX_CHECK_VALIDITY
        if (!_MEMORY_ALIGNED(block_ptr) || BLOCK_IS_USED(block_ptr)) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_CORRUPT_STORAGE_POOL_FREE_LIST;
            return ((pointer) NULL);
        } /* Endif */
#endif

#if MQX_CHECK_VALIDITY
        if (!VALID_CHECKSUM(block_ptr)) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_INVALID_CHECKSUM;
            return ((pointer) NULL);
        } /* Endif */
#endif

        block_size = block_ptr->BLOCKSIZE;

        if ((uchar_ptr) &block_ptr->USER_AREA <= (uchar_ptr) requested_addr && (uchar_ptr) &block_ptr->USER_AREA
                        + block_size >= (uchar_ptr) requested_addr + requested_size && block_size >= requested_size) {
            /* request fits into this block */

            /* create new free block */
            free_block_ptr = (STOREBLOCK_STRUCT_PTR)((char _PTR_) block_ptr);

            block_ptr = (STOREBLOCK_STRUCT_PTR)((uchar_ptr) requested_addr
                            - (_mem_size) (FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA)));

            free_block_size = (uchar_ptr) block_ptr - (uchar_ptr) free_block_ptr;

            next_block_size = block_size - requested_size - free_block_size;
            if (next_block_size >= (2 * MQX_MIN_MEMORY_STORAGE_SIZE)) {
                /*
                 * The current block is big enough to split.
                 * into 2 blocks.... the part to be allocated is one block,
                 * and the rest remains as a free block on the free list.
                 */

                next_block_ptr = (STOREBLOCK_STRUCT_PTR)((char _PTR_) block_ptr + requested_size);

                /* Initialize the new physical block values */
                next_block_ptr->BLOCKSIZE = next_block_size;
                next_block_ptr->PREVBLOCK = (STOREBLOCK_STRUCT_PTR) block_ptr;
                MARK_BLOCK_AS_FREE(next_block_ptr);

                CALC_CHECKSUM(next_block_ptr);

                /* Link new block into the free list */
                next_block_ptr->NEXTBLOCK = free_block_ptr->NEXTBLOCK;
                block_ptr->NEXTBLOCK = (pointer) next_block_ptr;

                next_block_ptr->USER_AREA = (pointer) block_ptr;
                if (next_block_ptr->NEXTBLOCK != NULL) {
                    ((STOREBLOCK_STRUCT_PTR) next_block_ptr->NEXTBLOCK)->USER_AREA = (pointer) next_block_ptr;
                }

                /*
                 * Modify the current block, to point to this newly created
                 * block which is now the next physical block.
                 */
                block_ptr->BLOCKSIZE = requested_size;

                /*
                 * Modify the block on the other side of the next block
                 * (the next next block) so that it's previous block pointer
                 * correctly point to the next block.
                 */
                next_next_block_ptr = (STOREBLOCK_STRUCT_PTR) NEXT_PHYS(next_block_ptr);
                PREV_PHYS( next_next_block_ptr) = next_block_ptr;
                CALC_CHECKSUM(next_next_block_ptr);
            }
            else {
                /* Take the entire block */
                requested_size += next_block_size;
                next_block_ptr = free_block_ptr->NEXTBLOCK;
            }

            if (free_block_size >= (2 * MQX_MIN_MEMORY_STORAGE_SIZE)) {
                /* modify the new physical block values */
                free_block_ptr->BLOCKSIZE = free_block_size;
                free_block_ptr->NEXTBLOCK = (pointer) next_block_ptr;
                MARK_BLOCK_AS_FREE(free_block_ptr);

                CALC_CHECKSUM(free_block_ptr);

                /* Set the size of the block */
                block_ptr->BLOCKSIZE = requested_size;
                block_ptr->PREVBLOCK = (STOREBLOCK_STRUCT_PTR) free_block_ptr;
                block_ptr->MEM_TYPE = 0;
                MARK_BLOCK_AS_USED(block_ptr, td_ptr->TASK_ID);

                CALC_CHECKSUM(block_ptr);
            }
            else {
                /* Set the size of the block */
                block_ptr->PREVBLOCK = PREV_PHYS(free_block_ptr);/*->PREVBLOCK;*/
                block_ptr->BLOCKSIZE = requested_size;
                block_ptr->MEM_TYPE = 0;
                MARK_BLOCK_AS_USED(block_ptr, td_ptr->TASK_ID);
                CALC_CHECKSUM(block_ptr);

                (block_ptr->PREVBLOCK)->BLOCKSIZE += free_block_size;
                CALC_CHECKSUM(block_ptr->PREVBLOCK);

                /* Unlink the block from the free list */
                if (free_block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR) {
                    /* At the head of the free list */

                    mem_pool_ptr->POOL_FREE_LIST_PTR = next_block_ptr;
                    if (mem_pool_ptr->POOL_FREE_LIST_PTR != NULL) {
                        PREV_FREE(mem_pool_ptr->POOL_FREE_LIST_PTR) = 0;
                    }
                }
                else {
                    /*
                     * NOTE: PREV_FREE guaranteed to be non-zero
                     * Have to make the PREV_FREE of this block
                     * point to the NEXT_FREE of this block
                     */
                    NEXT_FREE( PREV_FREE(
                        free_block_ptr)) = NEXT_FREE(free_block_ptr);
                    if (NEXT_FREE(free_block_ptr) != NULL) {
                        /*
                         * Now have to make the NEXT_FREE of this block
                         * point to the PREV_FREE of this block
                         */
                        PREV_FREE( NEXT_FREE(
                            free_block_ptr)) = PREV_FREE(free_block_ptr);
                    }
                }
#if MQX_MEMORY_FREE_LIST_SORTED == 1
                if (free_block_ptr == mem_pool_ptr->POOL_FREE_CURRENT_BLOCK) {
                    /* Reset the freelist insertion sort by _mem_free */
                    mem_pool_ptr->POOL_FREE_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;
                }
#endif
            }

            /* Reset the __mem_test freelist pointer */
            mem_pool_ptr->POOL_FREE_CHECK_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

            /*
             * Set the curent pool block to the start of the free list, so
             * that if this task pre-empted another that was performing a
             * _mem_alloc, the other task will restart it's search for a block
             */
            mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

            /* Remember some statistics */
            next_block_ptr = NEXT_PHYS(block_ptr);
            if (((char _PTR_)(next_block_ptr) > (char _PTR_) mem_pool_ptr->POOL_HIGHEST_MEMORY_USED) &&
                ((char _PTR_)(next_block_ptr) > (char _PTR_) mem_pool_ptr->POOL_PTR) &&
                ((char _PTR_)(next_block_ptr) < (char _PTR_) mem_pool_ptr->POOL_END_PTR)
                )
            {
               mem_pool_ptr->POOL_HIGHEST_MEMORY_USED = ((char _PTR_)(next_block_ptr) - 1);
            }

            /* Link the block onto the task descriptor. */
            block_ptr->NEXTBLOCK = td_ptr->MEMORY_RESOURCE_LIST;
            td_ptr->MEMORY_RESOURCE_LIST = (pointer) (&block_ptr->USER_AREA);

            block_ptr->MEM_POOL_PTR = (pointer) mem_pool_ptr;

#if MQX_CHECK_VALIDITY
            /* Check that user area is aligned on a cache line boundary */
            if (!_MEMORY_ALIGNED(&block_ptr->USER_AREA)) {
                *error_ptr = MQX_INVALID_CONFIGURATION;
                return ((pointer) NULL);
            } /* Endif */
#endif

            return ((pointer) (&block_ptr->USER_AREA));
        }
        else {
            block_ptr = (STOREBLOCK_STRUCT_PTR) NEXT_FREE(block_ptr);
        }
    }

#ifdef lint
    return( NULL ); /* to satisfy lint */
#endif
}

#if MQX_ALLOC_ALLIGN_RESIZE

/*!
 * \private
 *
 * \brief Allocate an aligned block of memory for a task from the free list.
 *
 * \param[in]  requested_size Size of the memory block.
 * \param[in]  req_align      Requested alignment.
 * \param[in]  td_ptr         Owner TD.
 * \param[in]  mem_pool_ptr   Which pool to allocate from.
 * \param[out] error_ptr      Error code for operation:
 * \li MQX_OK
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is
 * incorrect.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \return Pointer to the memory block (success)
 * \return NULL (Failure: see task error codes.)
 * \return (pointer) NULL (Failure: see task error codes.)
 */
pointer _mem_alloc_internal_align
(
    _mem_size          requested_size,
    _mem_size          req_align,
    TD_STRUCT_PTR      td_ptr,
    MEMPOOL_STRUCT_PTR mem_pool_ptr,
    _mqx_uint_ptr      error_ptr
)
{ /* Body */
    STOREBLOCK_STRUCT_PTR block_ptr, old_block_ptr;
    STOREBLOCK_STRUCT_PTR next_block_ptr;
    STOREBLOCK_STRUCT_PTR next_next_block_ptr;
    _mem_size block_size;
    _mem_size next_block_size;
    _mem_size shift;
    STOREBLOCK_STRUCT saved_block;

    *error_ptr = MQX_OK;

    /*
     * Adjust message size to allow for block management overhead
     * and force size to be aligned.
     */
    requested_size += (_mem_size)(FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA));
#if MQX_CHECK_ERRORS
    if (requested_size < MQX_MIN_MEMORY_STORAGE_SIZE) {
        requested_size = MQX_MIN_MEMORY_STORAGE_SIZE;
    } /* Endif */
   /* Check if reg_align is power of 2 */
    if ((req_align != 0) && (req_align & (req_align - 1))) {
        *error_ptr = MQX_INVALID_PARAMETER;
        return (NULL); /* request failed */
    } /* Endif */
    /* If aligment is less than PSP_MEMORY_ALIGNMENT correction is needed. */
    if (req_align <= PSP_MEMORY_ALIGNMENT) {
        req_align = (PSP_MEMORY_ALIGNMENT + 1);
    } /* Endif */    
#endif

    _MEMORY_ALIGN_VAL_LARGER(requested_size);

    block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;

    while ( TRUE ) {

        /*
         * Save the current block pointer.
         * We will be enabling access to higher priority tasks.
         * A higher priority task may pre-empt the current task
         * and may do a memory allocation.  If this is true,
         * the higher priority task will reset the POOL_ALLOC_CURRENT_BLOCK
         * upon exit, and the current task will start the search over
         * again.
         */
        mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = block_ptr;

        /* allow pending interrupts */
        _int_enable();
        _int_disable();

        /* Get block pointer in case reset by a higher priority task */
        block_ptr = mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK;

        if (block_ptr == NULL) { /* Null pointer */
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_OUT_OF_MEMORY;
            return( NULL ); /* request failed */
        } /* Endif */

#if MQX_CHECK_VALIDITY
        if ( !_MEMORY_ALIGNED(block_ptr) || BLOCK_IS_USED(block_ptr) ) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_CORRUPT_STORAGE_POOL_FREE_LIST;
            return((pointer)NULL);
        } /* Endif */
#endif

#if MQX_CHECK_VALIDITY
        if ( ! VALID_CHECKSUM(block_ptr) ) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_INVALID_CHECKSUM;
            return((pointer)NULL);
        } /* Endif */
#endif

        block_size = block_ptr->BLOCKSIZE;
        shift = (((_mem_size)&block_ptr->USER_AREA + req_align) & ~(req_align - 1)) - (_mem_size)&block_ptr->USER_AREA;

        if (block_size >= requested_size + shift) {
            old_block_ptr = block_ptr;

            if (shift) {
                _mem_copy(block_ptr, &saved_block, sizeof(STOREBLOCK_STRUCT));
                /* move block by shift*/
                (char _PTR_)block_ptr += shift;
                _mem_copy(&saved_block, block_ptr, sizeof(STOREBLOCK_STRUCT));

                block_ptr->BLOCKSIZE -= shift;
                CALC_CHECKSUM(block_ptr);

                /*PREV_PHYS(block_ptr)->NEXTBLOCK = &block_ptr->USER_AREA;*/
                PREV_PHYS(block_ptr)->BLOCKSIZE += shift;
                CALC_CHECKSUM(PREV_PHYS(block_ptr));

                block_size = block_ptr->BLOCKSIZE;
            }
#if MQX_CHECK_VALIDITY
            /* Check that user area is aligned on a cache line boundary */
            if ( !_MEMORY_ALIGNED(&block_ptr->USER_AREA) ) {
                *error_ptr = MQX_INVALID_CONFIGURATION;
                return((pointer)NULL);
            } /* Endif */
#endif
            /* request fits into this block */

            next_block_size = block_size - requested_size;
            if ( next_block_size >= (2 * MQX_MIN_MEMORY_STORAGE_SIZE) ) {
                /*
                 * The current block is big enough to split.
                 * into 2 blocks.... the part to be allocated is one block,
                 * and the rest remains as a free block on the free list.
                 */

                next_block_ptr = (STOREBLOCK_STRUCT_PTR)
                ((char _PTR_)block_ptr + requested_size);

                /* Initialize the new physical block values */
                next_block_ptr->BLOCKSIZE = next_block_size;
                next_block_ptr->PREVBLOCK = (STOREBLOCK_STRUCT_PTR)block_ptr;
                MARK_BLOCK_AS_FREE(next_block_ptr);

                CALC_CHECKSUM(next_block_ptr);

                /* Link new block into the free list */
                next_block_ptr->NEXTBLOCK = block_ptr->NEXTBLOCK;
                block_ptr->NEXTBLOCK = (pointer)next_block_ptr;

                next_block_ptr->USER_AREA = (pointer)free_block_ptr;
                if ( next_block_ptr->NEXTBLOCK != NULL ) {
                    ((STOREBLOCK_STRUCT_PTR)next_block_ptr->NEXTBLOCK)->
                    USER_AREA = (pointer)next_block_ptr;
                } /* Endif */

                /*
                 * Modify the current block, to point to this newly created
                 * block which is now the next physical block.
                 */
                block_ptr->BLOCKSIZE = requested_size;

                /*
                 * Modify the block on the other side of the next block
                 * (the next next block) so that it's previous block pointer
                 * correctly point to the next block.
                 */
                next_next_block_ptr = (STOREBLOCK_STRUCT_PTR)
                NEXT_PHYS(next_block_ptr);
                PREV_PHYS(next_next_block_ptr) = next_block_ptr;
                CALC_CHECKSUM(next_next_block_ptr);

            }
            else {

                /* Take the entire block */
                requested_size = block_size;

            } /* Endif */

            /* Set the size of the block */
            block_ptr->BLOCKSIZE = requested_size;
            block_ptr->MEM_TYPE = 0;

            /* Indicate the block is in use */
            MARK_BLOCK_AS_USED(block_ptr, td_ptr->TASK_ID);

            CALC_CHECKSUM(block_ptr);

            /* Unlink the block from the free list */
            if (old_block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR ) {
                /* At the head of the free list */

                mem_pool_ptr->POOL_FREE_LIST_PTR = (STOREBLOCK_STRUCT_PTR)NEXT_FREE(block_ptr);
                if (mem_pool_ptr->POOL_FREE_LIST_PTR != NULL ) {
                    PREV_FREE(mem_pool_ptr->POOL_FREE_LIST_PTR) = 0;
                } /* Endif */

            }
            else {

                /*
                 * NOTE: PREV_FREE guaranteed to be non-zero
                 * Have to make the PREV_FREE of this block
                 * point to the NEXT_FREE of this block
                 */
                NEXT_FREE(PREV_FREE(block_ptr)) = NEXT_FREE(block_ptr);
                if ( NEXT_FREE(block_ptr) != NULL ) {
                    /*
                     * Now have to make the NEXT_FREE of this block
                     * point to the PREV_FREE of this block
                     */
                    PREV_FREE(NEXT_FREE(block_ptr)) = PREV_FREE(block_ptr);
                } /* Endif */

            } /* Endif */

#if MQX_MEMORY_FREE_LIST_SORTED == 1
            if (old_block_ptr == mem_pool_ptr->POOL_FREE_CURRENT_BLOCK ) {
                /* Reset the freelist insertion sort by _mem_free */
                mem_pool_ptr->POOL_FREE_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;
            } /* Endif */
#endif

            /* Reset the __mem_test freelist pointer */
            mem_pool_ptr->POOL_FREE_CHECK_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

            /*
             * Set the curent pool block to the start of the free list, so
             * that if this task pre-empted another that was performing a
             * _mem_alloc, the other task will restart it's search for a block
             */
            mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

            /* Remember some statistics */
            next_block_ptr = NEXT_PHYS(block_ptr);
            if (((char _PTR_)(next_block_ptr) > (char _PTR_) mem_pool_ptr->POOL_HIGHEST_MEMORY_USED) &&
                ((char _PTR_)(next_block_ptr) > (char _PTR_) mem_pool_ptr->POOL_PTR) &&
                ((char _PTR_)(next_block_ptr) < (char _PTR_) mem_pool_ptr->POOL_END_PTR)
                )
            {
               mem_pool_ptr->POOL_HIGHEST_MEMORY_USED = ((char _PTR_)(next_block_ptr) - 1);
            } /* Endif */

            /* Link the block onto the task descriptor. */
            block_ptr->NEXTBLOCK = td_ptr->MEMORY_RESOURCE_LIST;
            td_ptr->MEMORY_RESOURCE_LIST = (pointer)(&block_ptr->USER_AREA);

            block_ptr->MEM_POOL_PTR = (pointer)mem_pool_ptr;

            return( (pointer)(&block_ptr->USER_AREA ) );

        }
        else {
            block_ptr = (STOREBLOCK_STRUCT_PTR)NEXT_FREE(block_ptr);
        } /* Endif */

    } /* Endwhile */

#ifdef lint
    return( NULL ); /* to satisfy lint */
#endif

} /* Endbody */

#else

/*!
 * \private
 *
 * \brief Allocate an aligned block of memory for a task from the free list.
 *
 * \param[in]  requested_size Size of the memory block.
 * \param[in]  req_align      Requested alignment.
 * \param[in]  td_ptr         Owner TD.
 * \param[in]  mem_pool_ptr   Which pool to allocate from.
 * \param[out] error_ptr      Error code for operation:
 * \li MQX_OK
 * \li MQX_OUT_OF_MEMORY (MQX cannot find a block of the requested size.)
 * \li MQX_CORRUPT_STORAGE_POOL_FREE_LIST (Memory pool freelist is corrupted.)
 * \li MQX_INVALID_CHECKSUM (Checksum of the current memory block header is 
 * incorrect.)
 * \li MQX_INVALID_CONFIGURATION (User area not aligned on a cache line 
 * boundary.)
 *
 * \return Pointer to the memory block (success)
 * \return NULL (Failure: see task error codes.)
 * \return (pointer) NULL (Failure: see task error codes.)
 */
pointer _mem_alloc_internal_align
(
    _mem_size          requested_size,
    _mem_size          req_align,
    TD_STRUCT_PTR      td_ptr,
    MEMPOOL_STRUCT_PTR mem_pool_ptr,
    _mqx_uint_ptr      error_ptr
)
{ /* Body */
    STOREBLOCK_STRUCT_PTR block_ptr, free_block_ptr;
    STOREBLOCK_STRUCT_PTR next_block_ptr = NULL;
    STOREBLOCK_STRUCT_PTR next_next_block_ptr;
    _mem_size block_size;
    _mem_size next_block_size;
    _mem_size shift;
    *error_ptr = MQX_OK;

    /*
     * Adjust message size to allow for block management overhead
     * and force size to be aligned.
     */
    requested_size += (_mem_size) (FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA));
#if MQX_CHECK_ERRORS
    if (requested_size < MQX_MIN_MEMORY_STORAGE_SIZE) {
        requested_size = MQX_MIN_MEMORY_STORAGE_SIZE;
    } /* Endif */
    /* Check if reg_align is power of 2 */
    if ((req_align != 0) && (req_align & (req_align - 1))) {
        *error_ptr = MQX_INVALID_PARAMETER;
        return (NULL); /* request failed */
    } /* Endif */
    /* If aligment is less than PSP_MEMORY_ALIGNMENT correction is needed. */
    if (req_align <= PSP_MEMORY_ALIGNMENT) {
        req_align = (PSP_MEMORY_ALIGNMENT + 1);
    } /* Endif */
#endif

    _MEMORY_ALIGN_VAL_LARGER(requested_size);

    block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR;

    while (TRUE) {

        /*
         * Save the current block pointer.
         * We will be enabling access to higher priority tasks.
         * A higher priority task may pre-empt the current task
         * and may do a memory allocation.  If this is true,
         * the higher priority task will reset the POOL_ALLOC_CURRENT_BLOCK
         * upon exit, and the current task will start the search over
         * again.
         */
        mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK = block_ptr;

        /* allow pending interrupts */
        _int_enable();
        _int_disable();


        /* Get block pointer in case reset by a higher priority task */
        block_ptr = mem_pool_ptr->POOL_ALLOC_CURRENT_BLOCK;

        if (block_ptr == NULL) { /* Null pointer */
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_OUT_OF_MEMORY;
            return (NULL); /* request failed */
        } /* Endif */

#if MQX_CHECK_VALIDITY
        if (!_MEMORY_ALIGNED(block_ptr) || BLOCK_IS_USED(block_ptr)) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_CORRUPT_STORAGE_POOL_FREE_LIST;
            return ((pointer) NULL);
        }

        if (!VALID_CHECKSUM(block_ptr)) {
            mem_pool_ptr->POOL_BLOCK_IN_ERROR = block_ptr;
            *error_ptr = MQX_INVALID_CHECKSUM;
            return ((pointer) NULL);
        }
#endif

        block_size = block_ptr->BLOCKSIZE;
        shift = (((_mem_size) &block_ptr->USER_AREA + req_align) & ~(req_align - 1))
                        - (_mem_size) &block_ptr->USER_AREA;

        if (shift < (2 * MQX_MIN_MEMORY_STORAGE_SIZE)) {
            shift = (((_mem_size) &block_ptr->USER_AREA + (3 * MQX_MIN_MEMORY_STORAGE_SIZE) + req_align) & ~(req_align
                            - 1)) - (_mem_size) &block_ptr->USER_AREA;
        }

        if (block_size >= requested_size + shift) {
            /* request fits into this block */

            /* create new free block */
            free_block_ptr = (STOREBLOCK_STRUCT_PTR)((char _PTR_) block_ptr);
            block_ptr = (STOREBLOCK_STRUCT_PTR)(((char _PTR_) block_ptr) + shift);

#if MQX_CHECK_VALIDITY
            /* Assert that user area is aligned on a cache line boundary */
            if (!_MEMORY_ALIGNED(&block_ptr->USER_AREA)) {
                *error_ptr = MQX_INVALID_CONFIGURATION;
                return ((pointer) NULL);
            } /* Endif */
#endif
            block_ptr->PREVBLOCK = (STOREBLOCK_STRUCT_PTR) free_block_ptr;

            next_block_size = block_size - requested_size - shift;
            if (next_block_size >= (2 * MQX_MIN_MEMORY_STORAGE_SIZE)) {
                /*
                 * The current block is big enough to split.
                 * into 2 blocks.... the part to be allocated is one block,
                 * and the rest remains as a free block on the free list.
                 */

                next_block_ptr = (STOREBLOCK_STRUCT_PTR)((char _PTR_) block_ptr + requested_size);

                /* Initialize the new physical block values */
                next_block_ptr->BLOCKSIZE = next_block_size;
                next_block_ptr->PREVBLOCK = (STOREBLOCK_STRUCT_PTR) block_ptr;
                MARK_BLOCK_AS_FREE(next_block_ptr);

                CALC_CHECKSUM(next_block_ptr);

                /* Link new block into the free list */
                next_block_ptr->NEXTBLOCK = free_block_ptr->NEXTBLOCK;
                block_ptr->NEXTBLOCK = (pointer) next_block_ptr;

                next_block_ptr->USER_AREA = (pointer) free_block_ptr;
                if (next_block_ptr->NEXTBLOCK != NULL) {
                    ((STOREBLOCK_STRUCT_PTR) next_block_ptr->NEXTBLOCK)->USER_AREA = (pointer) next_block_ptr;
                }

                /*
                 * Modify the current block, to point to this newly created
                 * block which is now the next physical block.
                 */
                block_ptr->BLOCKSIZE = requested_size;

                /*
                 * Modify the block on the other side of the next block
                 * (the next next block) so that it's previous block pointer
                 * correctly point to the next block.
                 */
                next_next_block_ptr = (STOREBLOCK_STRUCT_PTR) NEXT_PHYS(next_block_ptr);
                PREV_PHYS( next_next_block_ptr) = next_block_ptr;
                CALC_CHECKSUM(next_next_block_ptr);
            }
            else {

                /* Take the entire block */
                requested_size = next_block_size;

            } /* Endif */

            /* modify the new physical block values */
            free_block_ptr->BLOCKSIZE = shift;
            free_block_ptr->NEXTBLOCK = (pointer) next_block_ptr;
            MARK_BLOCK_AS_FREE(free_block_ptr);

            CALC_CHECKSUM(free_block_ptr);

            /* Set the size of the block */
            block_ptr->BLOCKSIZE = requested_size;
            block_ptr->PREVBLOCK = (STOREBLOCK_STRUCT_PTR) free_block_ptr;
            block_ptr->MEM_TYPE = 0;
            MARK_BLOCK_AS_USED(block_ptr, td_ptr->TASK_ID);

            CALC_CHECKSUM(block_ptr);

            /* Remember some statistics */
            next_block_ptr = NEXT_PHYS(block_ptr);
            if (((char _PTR_)(next_block_ptr) > (char _PTR_) mem_pool_ptr->POOL_HIGHEST_MEMORY_USED) &&
                ((char _PTR_)(next_block_ptr) > (char _PTR_) mem_pool_ptr->POOL_PTR) &&
                ((char _PTR_)(next_block_ptr) < (char _PTR_) mem_pool_ptr->POOL_END_PTR)
                )
            {
               mem_pool_ptr->POOL_HIGHEST_MEMORY_USED = ((char _PTR_)(next_block_ptr) - 1);
            } /* Endif */

            /* Link the block onto the task descriptor. */
            block_ptr->NEXTBLOCK = td_ptr->MEMORY_RESOURCE_LIST;
            td_ptr->MEMORY_RESOURCE_LIST = (pointer) (&block_ptr->USER_AREA);

            block_ptr->MEM_POOL_PTR = (pointer) mem_pool_ptr;


            return ((pointer) (&block_ptr->USER_AREA));

        }
        else {
            block_ptr = (STOREBLOCK_STRUCT_PTR) NEXT_FREE(block_ptr);
        }

    }

#ifdef lint
    return( NULL ); /* to satisfy lint */
#endif
}

#endif /* MQX_ALLOC_ALLIGN_RESIZE */

#endif /* MQX_USE_MEM */

#if MQX_USE_MEM || MQX_USE_LWMEM

/*!
 * \brief Converts data to the other endian format.
 *
 * Converts data from Big to Little Endian byte order (or vice versa). The size
 * of the fields in the data are defined by the null terminated array of 8-bit
 * numbers.
 *
 * \param[in] definition Pointer to a NULL-terminated array, each element of
 * which defines the size (in single-addressable units) of each field in the
 * data structure that defines the data to convert.
 * \param[in] data       Pointer to the data to convert.
 *
 * \see _mem_swap_endian_len
 * \see _msg_swap_endian_data
 * \see _msg_swap_endian_header
 */
void _mem_swap_endian
(
    register uchar _PTR_ definition,
    pointer              data
)
{ /* Body */
    register uchar _PTR_ data_ptr;
    register uchar _PTR_ next_ptr;
    uchar _PTR_ b_ptr;
    _mqx_uint i;
    register _mqx_uint size;
    uchar c;

    data_ptr = (uchar _PTR_) data;
    size = (_mqx_uint) *definition++;
    while (size) {
        switch (size)
        {
            case 0: /* For compiler optimizations */
                break;
            case 1: /* No need to swap */
                ++data_ptr;
                break;
                /* Cases 2 & 4 are common sizes */
            case 2:
                c = data_ptr[0];
                data_ptr[0] = data_ptr[1];
                data_ptr[1] = c;
                data_ptr += 2;
                break;
            case 4:
                c = data_ptr[0];
                data_ptr[0] = data_ptr[3];
                data_ptr[3] = c;
                c = data_ptr[1];
                data_ptr[1] = data_ptr[2];
                data_ptr[2] = c;
                data_ptr += 4;
                break;
                /* All others done long hand */
            default:
                next_ptr = data_ptr + size;
                b_ptr = data_ptr + size - 1;
                i = (size / 2) + 1;
                while (--i) {
                    c = *data_ptr;
                    *data_ptr++ = *b_ptr;
                    *b_ptr-- = c;
                } /* Endwhile */
                data_ptr = next_ptr;
                break;
        } /* Endswitch */
        size = *definition++;
    } /* Endwhile */

} /* Endbody */

/*!
 * \brief Converts data to the other endian format.
 *
 * Converts data from Big to Little Endian byte order (or vice versa). The size
 * of the fields in the data are defined by the null terminated array of 8-bit
 * numbers.
 *
 * \param[in] definition Pointer to a NULL-terminated array, each element of
 * which defines the size (in single-addressable units) of each field in the
 * data structure that defines the data to convert.
 * \param[in] data       Pointer to the data to convert.
 * \param[in] len        The fields in the definition array to process.
 *
 * \see _mem_swap_endian
 * \see _msg_swap_endian_data
 * \see _msg_swap_endian_header
 */
void _mem_swap_endian_len
(
    register uchar _PTR_ definition,
    pointer              data,
    _mqx_uint            len
)
{ /* Body */
    register uchar _PTR_ data_ptr;
    register uchar _PTR_ next_ptr;
    uchar _PTR_ b_ptr;
    _mqx_uint i;
    register _mqx_uint size;
    uchar c;

    data_ptr = (uchar _PTR_) data;
    size = (_mqx_uint) *definition++;
    while (size && len--) {
        switch (size)
        {
            case 0: /* For compiler optimizations */
                break;
            case 1: /* No need to swap */
                ++data_ptr;
                break;
                /* Cases 2 & 4 are common sizes */
            case 2:
                c = data_ptr[0];
                data_ptr[0] = data_ptr[1];
                data_ptr[1] = c;
                data_ptr += 2;
                break;
            case 4:
                c = data_ptr[0];
                data_ptr[0] = data_ptr[3];
                data_ptr[3] = c;
                c = data_ptr[1];
                data_ptr[1] = data_ptr[2];
                data_ptr[2] = c;
                data_ptr += 4;
                break;
                /* All others done long hand */
            default:
                next_ptr = data_ptr + size;
                b_ptr = data_ptr + size - 1;
                i = (size / 2) + 1;
                while (--i) {
                    c = *data_ptr;
                    *data_ptr++ = *b_ptr;
                    *b_ptr-- = c;
                } /* Endwhile */
                data_ptr = next_ptr;
                break;
        } /* Endswitch */
        size = (_mqx_uint) *definition++;
    } /* Endwhile */

} /* Endbody */

#endif /* MQX_USE_MEM || MQX_USE_LWMEM */

/*!
 * \brief Checks whether memory can be read and written without corruption.
 *
 * It aligns the addresses it's given to a PSP specified value and then writes
 * every 32-bit element in the memory range once with values that change every
 * bit. Then it reads back the data and returns an error if the value read back
 * does not equal the value written.
 *
 * \param[in] base
 * \param[in] extent
 *
 * \return MQX_OK
 * \return MQX_INVALID_SIZE
 * \return MQX_CORRUPT_MEMORY_SYSTEM
 */
_mqx_uint _mem_verify
(
    pointer base,
    pointer extent
)
{ /* Body */

    _mqx_uint result = MQX_INVALID_SIZE;

    if (extent > base) {
        uchar_ptr cbase = (uchar_ptr) _ALIGN_ADDR_TO_HIGHER_MEM(base);
        uchar_ptr cextent = (uchar_ptr) _ALIGN_ADDR_TO_LOWER_MEM(extent);

        if (cextent > cbase) {
            uint_32 length = cextent - cbase;
            uint_32_ptr p, p1 = (uint_32_ptr) cbase;
            uint_32_ptr eom = (uint_32_ptr) (cbase + length);
            uint_32 v = 0x12345678;

            for (p = p1; p < eom; p++) {
                *p = v;
                v += 0x11111111;
            } /* Endfor */

            result = MQX_OK;

            v = 0x12345678;
            for (p = p1; p < eom; p++) {
                if (*p != v) {
                    result = MQX_CORRUPT_MEMORY_SYSTEM;
                    break;
                } /* Endif */
                v += 0x11111111;
            } /* Endfor */

        } /* Endif */

    } /* Endif */

    return (result);

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_mem/io_mem.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_mem.c$
* $Version : 3.6.7.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the Ramdisk driver functions
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "io_mem.h"
#include "iomemprv.h"

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mem_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a fdv_ram driver.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_mem_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr            identifier,
  
      /* [IN] the address of the fdv_ram */
      pointer             base_address, 
      
      /* [IN] the total size of the device */
      _file_size          size
       
   )
{ /* Body */
   IO_MEM_STRUCT_PTR handle_ptr;

#if (MAX_FILE_SIZE > MAX_MEM_SIZE)
   #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (size > MAX_MEM_SIZE) {
         return(MQX_OUT_OF_MEMORY);
      } /* Endif */
   #endif
#endif

   handle_ptr = (IO_MEM_STRUCT_PTR)
      _mem_alloc_system_zero((_mem_size)sizeof(IO_MEM_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (handle_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
  _mem_set_type(handle_ptr,MEM_TYPE_IO_MEM_STRUCT);            

   if (base_address == NULL) {
      base_address = _mem_alloc_system((_mem_size)size);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (base_address == NULL) {
         _mem_free(handle_ptr);
         return(MQX_OUT_OF_MEMORY);
      }/* Endif */
#endif
      _mem_set_type(base_address,MEM_TYPE_IO_MEM_DATA);              

      /* Indicate the the RAM drive was allocated from kernel memory */
      handle_ptr->TYPE = MEM_TYPE_DYNAMIC;
   } else {
      /* Indicate the the RAM drive was statically allocated (global mem) */
      handle_ptr->TYPE = MEM_TYPE_STATIC;
   }/* Endif */

   handle_ptr->BASE_ADDR   = base_address;
   handle_ptr->SIZE        = size;
   
   _lwsem_create(&handle_ptr->LWSEM, 1);

   return (_io_dev_install(identifier,
      _io_mem_open,
      _io_mem_close,
      _io_mem_read,
      _io_mem_write,
      _io_mem_ioctl,
      (pointer)handle_ptr)); 

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mem_uninstall
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Uninstall a fdv_ram driver.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_mem_uninstall
   (
      /* [IN] The devices context */
      IO_DEVICE_STRUCT_PTR  io_dev_ptr
   )
{ /* Body */
   IO_MEM_STRUCT_PTR     handle_ptr = (IO_MEM_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   _lwsem_destroy(&handle_ptr->LWSEM);

   if (handle_ptr->TYPE == MEM_TYPE_DYNAMIC) {
      _mem_free(handle_ptr->BASE_ADDR);
   } /* Endif */
   _mem_free(handle_ptr);

   return(MQX_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mem_open
* Returned Value   : MQX_OK
* Comments         : Opens and initializes fdv_ram driver.
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_mem_open
   (
      /* [IN] the file handle for the device being opened */
      FILE_DEVICE_STRUCT_PTR   fd_ptr,
       
      /* [IN] the remaining portion of the name of the device */
      char_ptr                 open_name_ptr,

      /* [IN] the flags to be used during operation:
      ** blockmode
      */
      char_ptr                 flags
   )
{ /* Body */
   /* Start CR 810 */
   IO_DEVICE_STRUCT_PTR  io_dev_ptr = fd_ptr->DEV_PTR;
   IO_MEM_STRUCT_PTR     handle_ptr = (IO_MEM_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   if (flags && (*flags == 'b')) {
      handle_ptr->BLOCK_MODE = TRUE;
      handle_ptr->NUM_BLOCKS = handle_ptr->SIZE >> IO_MEM_BLOCK_SIZE_POWER;

      /* Redirect the read/write functions */
      io_dev_ptr->IO_READ  = _io_mem_read_blocks;
      io_dev_ptr->IO_WRITE = _io_mem_write_blocks;
   } /* Endif */
   /* End CR 810 */

   return(MQX_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mem_close
* Returned Value   : ERROR CODE
* Comments         : Closes fdv_ram driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_mem_close
   (
      /* [IN] the file handle for the device being closed */
      FILE_DEVICE_STRUCT_PTR fd_ptr
   )
{ /* Body */

   /* Nothing to do */
   return(MQX_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mem_read
* Returned Value   : number of characters read
* Comments         : Reads data from fdv_ram driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_mem_read
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR   fd_ptr,

      /* [IN] where the characters are to be stored */
      char_ptr                 data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int                 num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR  io_dev_ptr = fd_ptr->DEV_PTR;
   IO_MEM_STRUCT_PTR     handle_ptr = (IO_MEM_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   uchar_ptr             src_ptr;
   _file_size            size = handle_ptr->SIZE;

   if( fd_ptr->LOCATION >= size) {
      fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
      return(0);
   } else {
      src_ptr = fd_ptr->LOCATION + handle_ptr->BASE_ADDR;
      if ( (src_ptr + num) > (handle_ptr->BASE_ADDR + size) ) {
         fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
         num = (_mqx_int)((handle_ptr->BASE_ADDR + size) - 
                        (handle_ptr->BASE_ADDR + fd_ptr->LOCATION) + 1);
      }/* Endif */
      _lwsem_wait(&handle_ptr->LWSEM);
      _mem_copy((pointer)src_ptr, (pointer)data_ptr, (_mem_size)num);
      fd_ptr->LOCATION += (_file_size)num;
      _lwsem_post(&handle_ptr->LWSEM);
      return(num);
   } /* Endif */
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mem_write
* Returned Value   : number of characters written
* Comments         : Writes data to the fdv_ram device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_mem_write
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR  fd_ptr,

      /* [IN] where the characters are */
      char_ptr                data_ptr,

      /* [IN] the number of characters to output */
      _mqx_int                num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR  io_dev_ptr = fd_ptr->DEV_PTR;
   IO_MEM_STRUCT_PTR     handle_ptr = (IO_MEM_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   uchar_ptr             dest_ptr;
   _file_size               size = handle_ptr->SIZE;

   if(fd_ptr->LOCATION >= size) {
      fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
      return(0);
   } else {  
      dest_ptr = fd_ptr->LOCATION + handle_ptr->BASE_ADDR;
      if ( (dest_ptr + num) > (handle_ptr->BASE_ADDR + size) )
      {
         fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
         num = (_mqx_int)((handle_ptr->BASE_ADDR + size) - 
                        (handle_ptr->BASE_ADDR + fd_ptr->LOCATION) + 1);
      }/* Endif */
      _lwsem_wait(&handle_ptr->LWSEM);
      _mem_copy((pointer)data_ptr, (pointer)dest_ptr, (_mem_size)num);
      fd_ptr->LOCATION += (_file_size)num;
      _lwsem_post(&handle_ptr->LWSEM);
      return(num);
   } /* Endif */

} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_mem_ioctl
* Returned Value   : _mqx_int
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_mem_ioctl
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint               cmd,

      /* [IN/OUT] the ioctl parameters */
      pointer                param_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR  io_dev_ptr = fd_ptr->DEV_PTR;
   IO_MEM_STRUCT_PTR     handle_ptr = (IO_MEM_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   pointer _PTR_         pparam_ptr;
   _mem_size_ptr         mparam_ptr;
   _mqx_uint_ptr         uparam_ptr;
   boolean _PTR_         bparam_ptr;
   _mqx_int              result = MQX_OK;
   /* Start CR 810 */
   uint_32_ptr           u32param_ptr;
   /* End   CR 810 */

   switch (cmd) {
      case IO_MEM_IOCTL_GET_BASE_ADDRESS:
         pparam_ptr  = (pointer _PTR_)param_ptr;
         *pparam_ptr = (pointer)handle_ptr->BASE_ADDR;
         break;
      case IO_MEM_IOCTL_GET_TOTAL_SIZE:
         mparam_ptr  = (_mem_size_ptr)param_ptr;
         *mparam_ptr = (_mem_size)handle_ptr->SIZE;
         break;
      case IO_MEM_IOCTL_GET_DEVICE_ERROR:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = ferror(fd_ptr);
         break;
      case IO_IOCTL_SEEK_AVAIL:
         bparam_ptr  = (boolean _PTR_)param_ptr;
         *bparam_ptr = TRUE;
         break;
      /* Start CR 810 */
      case IO_IOCTL_GET_BLOCK_SIZE:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = IO_MEM_BLOCK_SIZE;
         break;
      case IO_IOCTL_DEVICE_IDENTIFY:
         u32param_ptr  = (uint_32_ptr)param_ptr;
         u32param_ptr[IO_IOCTL_ID_PHY_ELEMENT]  = IO_DEV_TYPE_PHYS_MEMIO;
         u32param_ptr[IO_IOCTL_ID_LOG_ELEMENT]  = IO_DEV_TYPE_LOGICAL_MFS;
         u32param_ptr[IO_IOCTL_ID_ATTR_ELEMENT] = IO_MEM_ATTRIBS;
         if (handle_ptr->BLOCK_MODE) {
            u32param_ptr[IO_IOCTL_ID_ATTR_ELEMENT] |= IO_DEV_ATTR_BLOCK_MODE;
         } /* Endif */
         break;
      case IO_IOCTL_GET_NUM_SECTORS:
         /* return number of sectors, needed for MFS format */
         mparam_ptr = (_mem_size_ptr)param_ptr;
         *mparam_ptr = (_mem_size)handle_ptr->SIZE / IO_MEM_BLOCK_SIZE;
         break;
      default:
         result = IO_ERROR_INVALID_IOCTL_CMD;
         break;
      /* End CR 810 */
   } /* Endswitch */
   return result;

} /* Endbody */


/* Start CR 810 */
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mem_read_blocks
* Returned Value   : number of blocks read
* Comments         : Reads data from fdv_ram driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_mem_read_blocks
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR   fd_ptr,

      /* [IN] where the blocks are to be stored */
      char_ptr                 data_ptr,

      /* [IN] the number of blocks to input */
      _mqx_int                 num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR  io_dev_ptr = fd_ptr->DEV_PTR;
   IO_MEM_STRUCT_PTR     handle_ptr = (IO_MEM_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   uchar_ptr             src_ptr;
   _file_size            blocks     = handle_ptr->NUM_BLOCKS;
   _file_size            bytes_to_be_read;

   if ( (fd_ptr->LOCATION + num) > blocks) {
      fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
      num = blocks - fd_ptr->LOCATION - 1;
   } /* Endif */

   if (num <= 0) {
      return 0;
   } /* Endif */

   bytes_to_be_read = num << IO_MEM_BLOCK_SIZE_POWER;
   src_ptr = (fd_ptr->LOCATION << IO_MEM_BLOCK_SIZE_POWER) + handle_ptr->BASE_ADDR;

   _lwsem_wait(&handle_ptr->LWSEM);
   _mem_copy((pointer)src_ptr, (pointer)data_ptr, (_mem_size)bytes_to_be_read);
   fd_ptr->LOCATION += (_file_size)num;
   _lwsem_post(&handle_ptr->LWSEM);

   return num;
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mem_write_blocks
* Returned Value   : number of blocks written
* Comments         : Writes data to fdv_ram driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_mem_write_blocks
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR   fd_ptr,

      /* [IN] where the blocks are stored */
      char_ptr                 data_ptr,

      /* [IN] the number of blocks to output */
      _mqx_int                 num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR  io_dev_ptr = fd_ptr->DEV_PTR;
   IO_MEM_STRUCT_PTR     handle_ptr = (IO_MEM_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   uchar_ptr             src_ptr;
   _file_size            blocks     = handle_ptr->NUM_BLOCKS;
   _file_size            bytes_to_be_written;

   if ( (fd_ptr->LOCATION + num) > blocks) {
      fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
      num = blocks - fd_ptr->LOCATION;
   } /* Endif */

   if (num <= 0) {
      return 0;
   } /* Endif */

   bytes_to_be_written = num << IO_MEM_BLOCK_SIZE_POWER;
   src_ptr = (fd_ptr->LOCATION << IO_MEM_BLOCK_SIZE_POWER) + handle_ptr->BASE_ADDR;

   _lwsem_wait(&handle_ptr->LWSEM);
   _mem_copy((pointer)data_ptr, (pointer)src_ptr, (_mem_size)bytes_to_be_written);
   fd_ptr->LOCATION += (_file_size)num;
   _lwsem_post(&handle_ptr->LWSEM);

   return num;
   
} /* Endbody */
/* End   CR 810 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/include/usb_class.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_class.h$
* $Version : 3.8.7.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
* @brief The file contains USB stack class layer api header function.
*
*****************************************************************************/

#ifndef _USB_CLASS_H
#define _USB_CLASS_H 1

/******************************************************************************
 * Includes
 *****************************************************************************/
#include <mqx.h>
#include <bsp.h>

#include "usb.h"
#include "usb_prv.h"

#include "devapi.h"

/******************************************************************************
 * Global Variables
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
 /*#define DELAYED_PROCESSING  1 This define is used to delay the control 
                                processing and not have it executed as part
                                of the interrupt routine */

#define USB_MAX_EP_BUFFER_SIZE   (64)
#define SOF_HIGH_BYTE_SHIFT      (8)

#define GET_STATUS_DEVICE_MASK           (0x0003)  
#define REMOTE_WAKEUP_STATUS_MASK        (0x0002) 
#define BUS_POWERED                      (0x80)   
#define SELF_POWERED                     (0x40)  
#define SELF_POWER_BIT_SHIFT             (6)     


/* USB Specs define CONTROL_MAX_PACKET_SIZE for High Speed device as only 64,
   whereas for FS its allowed to be 8, 16, 32 or 64 */
#define CONTROL_MAX_PACKET_SIZE       (64)

#if (HIGH_SPEED_DEVICE && (CONTROL_MAX_PACKET_SIZE != 64))
#error "For High Speed CONTROL_MAX_PACKET_SIZE should be 64"
#endif

#define UNINITIALISED_VAL        (0xffffffff)  
/* Events to the Application */
#define USB_APP_BUS_RESET           (0)
#define USB_APP_CONFIG_CHANGED      (1)
#define USB_APP_ENUM_COMPLETE       (2)
#define USB_APP_SEND_COMPLETE       (3)
#define USB_APP_DATA_RECEIVED       (4) 
#define USB_APP_ERROR               (5)
#define USB_APP_GET_DATA_BUFF       (6)
#define USB_APP_EP_STALLED          (7)
#define USB_APP_EP_UNSTALLED        (8) 
#define USB_APP_GET_TRANSFER_SIZE   (9)

/* identification values and masks to identify request types  */
#define USB_REQUEST_CLASS_MASK   (0x60) 
#define USB_REQUEST_CLASS_STRD   (0x00) 
#define USB_REQUEST_CLASS_CLASS  (0x20) 
#define USB_REQUEST_CLASS_VENDOR (0x40) 
#define USB_MAX_CLASS_OBJECT     (0x1)
/******************************************************************************
 * Types
 *****************************************************************************/
typedef int_32 USB_CLASS_HANDLE;

/* callback function pointer structure for Application to handle events */
typedef void(_CODE_PTR_ USB_CLASS_CALLBACK)(uint_8 event, void* val, pointer arg);

/* callback function pointer structure to handle USB framework request */
typedef uint_8 (_CODE_PTR_ USB_REQ_FUNC)(USB_SETUP_STRUCT *,
                                          uint_8_ptr*,
                                          uint_32*,pointer arg); 

/*callback function pointer structure for application to provide class params*/
typedef uint_8 (_CODE_PTR_ USB_CLASS_SPECIFIC_HANDLER_FUNC)(
                           uint_8,
                           uint_16, 
                           uint_8_ptr*,
                           uint_32*,
                           pointer arg);

/* Structure Representing class callback */
typedef struct usb_class_callback_struct
{
    USB_CLASS_CALLBACK  callback;
    pointer arg;
}USB_CLASS_CALLBACK_STRUCT,_PTR_ USB_CLASS_CALLBACK_STRUCT_PTR ;

/* Structure other request class callback */
typedef struct usb_req_callback_struct
{
    USB_REQ_FUNC  callback;
    pointer arg;
}USB_REQ_CALLBACK_STRUCT,_PTR_ USB_REQ_CALLBACK_STRUCT_PTR ;

typedef struct usb_class_specific_handler_callback_struct
{
    USB_CLASS_SPECIFIC_HANDLER_FUNC  callback;
    pointer arg;
}USB_CLASS_SPECIFIC_HANDLER_CALLBACK_STRUCT,
_PTR_ USB_CLASS_SPECIFIC_HANDLER_CALLBACK_STRUCT_PTR;

/* Strucutre holding USB class object state*/
typedef struct _usb_class_object
{
   uint_32 usb_fw_handle;
   _usb_device_handle controller_handle;
   pointer arg;
   USB_CLASS_CALLBACK class_callback;   
}USB_CLASS_OBJECT_STRUCT,_PTR_ USB_CLASS_OBJECT_STRUCT_PTR;

 typedef struct _USB_LANGUAGE 
{
    uint_16 language_id;
    uint_8 ** lang_desc;
    uint_8 * lang_desc_size;    
} USB_LANGUAGE;
 
typedef struct _USB_ALL_LANGUAGES 
{
    uint_8 *languages_supported_string;
    uint_8 languages_supported_size;
    /*Allocate Memory In App Layer*/
    USB_LANGUAGE *usb_language;
       
}USB_ALL_LANGUAGES;

/* Strucutre Representing Endpoints and number of endpoints user want*/
typedef struct _USB_ENDPOINTS
{
    uint_8 count;
    /*Allocate Memory In App Layer*/
    USB_EP_STRUCT *ep; 
}USB_ENDPOINTS;

 /* Callback Functions to be implemented by APP.*/
 typedef struct _usb_desc_callbackFunction_struct
 {
    uint_32 handle;
    uint_8 (_CODE_PTR_ GET_DESC)(uint_32 handle,uint_8 type,uint_8 str_num,
        uint_16 index,uint_8_ptr *descriptor,uint_32 *size);
    USB_ENDPOINTS * (_CODE_PTR_ GET_DESC_ENDPOINTS)(uint_32 handle);
    uint_8 (_CODE_PTR_ GET_DESC_INTERFACE)(uint_32 handle,uint_8 interface,
        uint_8_ptr alt_interface);
    uint_8 (_CODE_PTR_ SET_DESC_INTERFACE)(uint_32 handle,uint_8 interface,
        uint_8 alt_interface);
    boolean (_CODE_PTR_ IS_DESC_VALID_CONFIGURATION)(uint_32 handle,
        uint_16 config_val);
    boolean (_CODE_PTR_ DESC_REMOTE_WAKEUP)(uint_32 handle);
    uint_8 (_CODE_PTR_ DESC_SET_FEATURE)(uint_32 handle,int_32 cmd,
        uint_8 in_data,uint_8_ptr* feature);
    uint_8 (_CODE_PTR_ DESC_GET_FEATURE)(uint_32 handle,int_32 cmd,
        uint_8 in_data,uint_8_ptr * feature);
 }DESC_CALLBACK_FUNCTIONS_STRUCT, * DESC_CALLBACK_FUNCTIONS_STRUCT_PTR;

/******************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Class_Init
 *
 * @brief The funtion initializes the Class Module 
 *
 * @param handle             :handle to Identify the controller
 * @param class_callback     :event callback      
 * @param other_req_callback :call back for class/vendor specific requests on 
 *                            CONTROL ENDPOINT
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
USB_CLASS_HANDLE USB_Class_Init
(
    _usb_device_handle handle, /* [IN] the USB device controller to initialize */                  
    USB_CLASS_CALLBACK class_callback,/*[IN]*/
    USB_REQ_FUNC       other_req_callback,/*[IN]*/
    pointer user_arg,/*[IN]*/
    DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr/*[IN]*/
); 

/**************************************************************************//*!
 *
 * @name  USB_Class_Deinit
 *
 * @brief The funtion initializes the Class Module 
 *
 * @param handle             :handle to Identify the controller
 * @param class_handle       :class handle      
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Class_Deinit
(
    _usb_device_handle handle, /* [IN] the USB device controller to initialize */                  
    USB_CLASS_HANDLE  class_handle
 );
 /**************************************************************************//*!
 *
 * @name  USB_Class_Send_Data
 *
 * @brief The funtion calls the device to send data upon recieving an IN token 
 *
 * @param handle:               handle to Identify the controller
 * @param ep_num:               The endpoint number     
 * @param buff_ptr:             buffer to send
 * @param size:                 length of transfer
 * 
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Class_Send_Data
(
    USB_CLASS_HANDLE handle, /*[IN]*/
    uint_8 ep_num,        /* [IN] the Endpoint number */                  
    uint_8_ptr buff_ptr,      /* [IN] buffer to send */      
    uint_32 size           /* [IN] length of the transfer */
); 

/**************************************************************************//*!
 *
 * @name  USB_Class_Get_Desc
 *
 * @brief  This function is called in to get the descriptor as specified in cmd.
 *
 * @param handle:           USB class handle. Received from
 *                          USB_Class_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param out_buf           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Class_Get_Desc(USB_CLASS_HANDLE handle,/*[IN]*/
int_32 cmd,/*[IN]*/
uint_8 input_data,/*[IN]*/
uint_8_ptr *in_buf /*[OUT]*/
);

/**************************************************************************//*!
 *
 * @name  USB_Class_Set_Desc
 *
 * @brief  This function is called in to Set the descriptor as specified in cmd.
 *
 * @param handle:           USB class handle. Received from
 *                          USB_Class_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param in_buf           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Class_Set_Desc(USB_CLASS_HANDLE handle,/*[IN]*/
int_32 cmd,/*[IN]*/
uint_8 input_data,/*[IN]*/
uint_8_ptr *out_buf /*[IN]*/
);

/**************************************************************************//*!
 *
 * @name   USB_Class_Periodic_Task
 *
 * @brief  The funtion calls for periodic tasks 
 *
 * @param  None
 *
 * @return None
 *
 *****************************************************************************/
extern void USB_Class_Periodic_Task(void);

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pipe/pipe_prv.h<|end_filename|>
#ifndef _pipe_prv_h_
#define _pipe_prv_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pipe_prv.h$
* $Version : 3.6.5.0$
* $Date    : Aug-27-2010$
*
* Comments:
*
*   The file contains the private internal functions prototype, defines, 
*   structure   definitions private to the Pipe device
*
*END************************************************************************/

/*----------------------------------------------------------------------*/
/*
**                          STRUCTURE DEFINITIONS
*/


/*
** IO_PIPE_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a Pipe is initialized.
*/

typedef struct io_pipe_init_struct
{
  
   /* The pipe character queue size */
   uint_32 QUEUE_SIZE;

   /* Initialization parameters for the pipe, currently not used*/
   uint_32 FLAGS;

 
} IO_PIPE_INIT_STRUCT, _PTR_ IO_PIPE_INIT_STRUCT_PTR;


/*
** IO_PIPE_INFO_STRUCT
**
** This structure defines the current parameters and status for a Pipe  
**
*/

typedef struct io_pipe_info_struct
{

   CHARQ_STRUCT_PTR     QUEUE;
  
   /* The serial pipe queue size */
   uint_32    QUEUE_SIZE;

   /* Mutext to protect against simulateous reads from the Pipe */ 
   MUTEX_STRUCT READ_MUTEX;

   /* Mutext to protect against simulateous writes to the Pipe */ 
   MUTEX_STRUCT WRITE_MUTEX;

   /* Mutext to protect against access to the Pipe data structures */ 
   MUTEX_STRUCT ACCESS_MUTEX;

   /* Semaphore used to block when pipe is full  */
   LWSEM_STRUCT FULL_SEM; 

   /* Semaphore used to block when pipe is empty */
   LWSEM_STRUCT EMPTY_SEM; 

   /* Flags to define options for the Pipe, currently not used */
   uint_32 FLAGS;

   /* Abort out of pending pipe reads, cleared by next pipe read */
   boolean KM_ABORT_READ;
   
   /* Abort out of pending pipe write, cleared by next pipe write */
   boolean KM_ABORT_WRITE;
 
} IO_PIPE_INFO_STRUCT, _PTR_ IO_PIPE_INFO_STRUCT_PTR;


/*----------------------------------------------------------------------*/
/*
**                          EXTERNAL FUCTION DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_pipe_open(FILE_DEVICE_STRUCT_PTR, char _PTR_, char_ptr);
extern _mqx_int _io_pipe_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_pipe_read(FILE_DEVICE_STRUCT_PTR, char _PTR_, _mqx_int);
extern _mqx_int _io_pipe_write(FILE_DEVICE_STRUCT_PTR, char _PTR_, _mqx_int);
extern _mqx_int _io_pipe_ioctl(FILE_DEVICE_STRUCT_PTR, uint_32, pointer);
extern _mqx_int _io_pipe_uninstall(IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mcc/source/include/mcc_common.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2013 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************
* $FileName: mcc_common.h.c$
* $Version : 3.8.1.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This is the MCC library header file
*
*END************************************************************************/

#ifndef __MCC_COMMON__
#define __MCC_COMMON__

#define MCC_INIT_STRING    "mccisrd"
#define MCC_VERSION_STRING "001.000"

typedef unsigned int MCC_BOOLEAN;
typedef unsigned int MCC_MEM_SIZE;
#define null ((void*)0)

typedef unsigned int MCC_CORE;
typedef unsigned int MCC_NODE;
typedef unsigned int MCC_PORT;

#if defined(__IAR_SYSTEMS_ICC__)
__packed
#endif
/*!
 * \brief Endpoint structure.
 *
 * Endpoints are receive buffer queues, implemented in shared RAM, 
 * and are addressed by a triplet containing core, node, and port.
 *
 * \see MCC_BOOKEEPING_STRUCT
 */
struct mcc_endpoint {
    /*! \brief Core number - identifies the core within the processor */
    MCC_CORE core;

    /*! \brief Node number - in Linux any user process participating in MCC is a unique node;
    MQX has only one node */
    MCC_NODE node;

    /*! \brief Port number - both Linux and MQX can have an arbitrary number of ports per node */
    MCC_PORT port;
#if defined(__IAR_SYSTEMS_ICC__)
};
#else
}__attribute__((packed));
#endif
typedef struct mcc_endpoint MCC_ENDPOINT;

#if defined(__IAR_SYSTEMS_ICC__)
__packed
#endif
/*!
 * \brief Receive buffer structure.
 *
 * This is the receive buffer structure used for exchanging data.
 *
 * \see MCC_BOOKEEPING_STRUCT
 */
struct mcc_receive_buffer {
    /*! \brief Pointer to the next receive buffer */
    struct mcc_receive_buffer *next;

    /*! \brief Length of data stored in this buffer */
    MCC_MEM_SIZE data_len;

    /*! \brief Space for data storage */
    char data [MCC_ATTR_BUFFER_SIZE_IN_BYTES];
#if defined(__IAR_SYSTEMS_ICC__)
};
#else
}__attribute__((packed));
#endif
typedef struct mcc_receive_buffer MCC_RECEIVE_BUFFER;

#if defined(__IAR_SYSTEMS_ICC__)
__packed
#endif
/*!
 * \brief List of buffers.
 *
 * Each endpoint keeps the list of received buffers.
 * The list of free buffers is kept in bookkeeping data structure. 
 *
 * \see MCC_RECEIVE_BUFFER
 * \see MCC_BOOKEEPING_STRUCT
 */
struct mcc_receive_list {
    /*! \brief Head of a buffers list */
    MCC_RECEIVE_BUFFER * head;

    /*! \brief Tail of a buffers list */
    MCC_RECEIVE_BUFFER * tail;
#if defined(__IAR_SYSTEMS_ICC__)
};
#else
}__attribute__((packed));
#endif
typedef struct mcc_receive_list MCC_RECEIVE_LIST;

#define BUFFER_QUEUED (0)
#define BUFFER_FREED  (1)
typedef unsigned int MCC_SIGNAL_TYPE;
#if defined(__IAR_SYSTEMS_ICC__)
__packed
#endif
/*!
 * \brief Signals and signal queues.
 *
 * This is one item of a signal queue.
 *
 * \see MCC_SIGNAL_TYPE
 * \see MCC_ENDPOINT
 * \see MCC_BOOKEEPING_STRUCT
 */
struct mcc_signal {
    /*! \brief Signal type - BUFFER_QUEUED or BUFFER_FREED */
    MCC_SIGNAL_TYPE type;

    /*! \brief Destination endpoint */
    MCC_ENDPOINT    destination;
#if defined(__IAR_SYSTEMS_ICC__)
};
#else
}__attribute__((packed));
#endif
typedef struct mcc_signal MCC_SIGNAL;

#if defined(__IAR_SYSTEMS_ICC__)
__packed
#endif
/*!
 * \brief Endpoint registration table.
 *
 * This is used for matching each endpoint structure with it's list of received buffers.
 *
 * \see MCC_ENDPOINT
 * \see MCC_RECEIVE_LIST
 * \see MCC_BOOKEEPING_STRUCT
 */
struct mcc_endpoint_map_item {
    /*! \brief Endpoint tripplet */
    MCC_ENDPOINT      endpoint;

    /*! \brief List of received buffers */
    MCC_RECEIVE_LIST  list;
#if defined(__IAR_SYSTEMS_ICC__)
};
#else
}__attribute__((packed));
#endif
typedef struct mcc_endpoint_map_item MCC_ENDPOINT_MAP_ITEM;

#if defined(__IAR_SYSTEMS_ICC__)
__packed
#endif
/*!
 * \brief MCC info structure.
 *
 * This is used for additional information about the MCC implementation.
 *
 * \see MCC_BOOKEEPING_STRUCT
 */
struct mcc_info_struct {
    /*! \brief <major>.<minor> - minor is changed whenever patched, major indicates compatibility */
    char version_string[sizeof(MCC_VERSION_STRING)];
#if defined(__IAR_SYSTEMS_ICC__)
};
#else
}__attribute__((packed));
#endif
typedef struct mcc_info_struct MCC_INFO_STRUCT;

#if defined(__IAR_SYSTEMS_ICC__)
__packed
#endif
/*!
 * \brief Share Memory data - Bookkeeping data and buffers.
 *
 * This is used for "bookkeeping data" such as endpoint and signal queue head 
 * and tail pointers and fixed size data buffers. The whole mcc_bookeeping_struct
 * as well as each individual structure members has to be defined and stored in the
 * memory as packed structure. This way, the same structure member offsets will be ensured
 * on all cores/OSes/compilers. Compiler-specific pragmas for data packing have to be applied.
 *
 * \see MCC_RECEIVE_LIST
 * \see MCC_SIGNAL
 * \see MCC_ENDPOINT_MAP_ITEM
 * \see MCC_RECEIVE_BUFFER
 */
struct mcc_bookeeping_struct {
    /*! \brief String that indicates if this structure has been already initialized */
    char init_string[sizeof(MCC_INIT_STRING)];

    /*! \brief String that indicates the MCC library version */
    char version_string[sizeof(MCC_VERSION_STRING)];

    /*! \brief List of free buffers */
    MCC_RECEIVE_LIST free_list;

    /*! \brief Each core has it's own queue of received signals */
    MCC_SIGNAL signals_received[MCC_NUM_CORES][MCC_MAX_OUTSTANDING_SIGNALS];

    /*! \brief Signal queue head for each core */
    unsigned int signal_queue_head[MCC_NUM_CORES];

    /*! \brief Signal queue tail for each core */
    unsigned int signal_queue_tail[MCC_NUM_CORES];

    /*! \brief Endpoint map */
    MCC_ENDPOINT_MAP_ITEM endpoint_table[MCC_ATTR_MAX_RECEIVE_ENDPOINTS];

    /*! \brief Receive buffers, the number is defined in mcc_config.h (MCC_ATTR_NUM_RECEIVE_BUFFERS) */
    MCC_RECEIVE_BUFFER r_buffers[MCC_ATTR_NUM_RECEIVE_BUFFERS];
#if defined(__IAR_SYSTEMS_ICC__)
};
#else
}__attribute__((packed));
#endif
typedef struct mcc_bookeeping_struct MCC_BOOKEEPING_STRUCT;

extern MCC_BOOKEEPING_STRUCT * bookeeping_data;

/*
 * Common Macros
 */
#define MCC_RESERVED_PORT_NUMBER        (0)
#define MCC_MAX_RECEIVE_ENDPOINTS_COUNT (255)

/*
 * Errors
 */
#define MCC_SUCCESS         (0) /* function returned successfully */
#define MCC_ERR_TIMEOUT     (1) /* blocking function timed out before completing */
#define MCC_ERR_INVAL       (2) /* invalid input parameter */
#define MCC_ERR_NOMEM       (3) /* out of shared memory for message transmission */
#define MCC_ERR_ENDPOINT    (4) /* invalid endpoint / endpoint doesn't exist */
#define MCC_ERR_SEMAPHORE   (5) /* semaphore handling error */
#define MCC_ERR_DEV         (6) /* Device Open Error */
#define MCC_ERR_INT         (7) /* Interrupt Error */
#define MCC_ERR_SQ_FULL     (8) /* Signal queue is full */
#define MCC_ERR_SQ_EMPTY    (9) /* Signal queue is empty */

/*
 * OS Selection
 */
#define MCC_LINUX         (1) /* Linux OS used */
#define MCC_MQX           (2) /* MQX RTOS used */

MCC_RECEIVE_LIST * mcc_get_endpoint_list(MCC_ENDPOINT endpoint);
MCC_RECEIVE_BUFFER * mcc_dequeue_buffer(MCC_RECEIVE_LIST *list);
void mcc_queue_buffer(MCC_RECEIVE_LIST *list, MCC_RECEIVE_BUFFER * r_buffer);
int mcc_remove_endpoint(MCC_ENDPOINT endpoint);
int mcc_register_endpoint(MCC_ENDPOINT endpoint);
int mcc_queue_signal(MCC_CORE core, MCC_SIGNAL signal);
int mcc_dequeue_signal(MCC_CORE core, MCC_SIGNAL *signal);

#define MCC_SIGNAL_QUEUE_FULL(core)  (((bookeeping_data->signal_queue_tail[core] + 1) % MCC_MAX_OUTSTANDING_SIGNALS) == bookeeping_data->signal_queue_head[core])
#define MCC_SIGNAL_QUEUE_EMPTY(core) (bookeeping_data->signal_queue_head[core] == bookeeping_data->signal_queue_tail[core])
#define MCC_ENDPOINTS_EQUAL(e1, e2)  ((e1.core == e2.core) && (e1.node == e2.node) && (e1.port == e2.port))

#if (MCC_ATTR_MAX_RECEIVE_ENDPOINTS > MCC_MAX_RECEIVE_ENDPOINTS_COUNT)
#error User-defined maximum number of endpoints can not exceed the value of MCC_MAX_RECEIVE_ENDPOINTS_COUNT
#endif

#endif /* __MCC_COMMON__ */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2s/i2s.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2s.h$
* $Version : 3.8.5.0$
* $Date    : Aug-20-2012$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the I2S I/O functions.
*
*END************************************************************************/


#ifndef _i2s_h_
#define _i2s_h_ 1

#include <ioctl.h>


/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/
#define I2S_CHAR_BIT    (0x08)

/*
** I2S Clock sources
*/
#define I2S_CLK_INT     (0x00)
#define I2S_CLK_EXT     (0x01)

/*
** I2S Bus Modes
*/
#define I2S_MODE_MASTER (0x01)
#define I2S_MODE_SLAVE  (0x02)
/*
** I2S I/O Mode
*/
#define I2S_IO_READ     (0x10)
#define I2S_IO_WRITE    (0x20)
/*
** I2S Error Codes
*/
#define I2S_ERROR_BASE                      (DRIVER_ERROR_BASE | 0x0FF0)
#define I2S_OK                              (0x00)
#define I2S_ERROR_INVALID_PARAMETER         (I2S_ERROR_BASE | 0x01)
#define I2S_ERROR_CHANNEL_INVALID           (I2S_ERROR_BASE | 0x02)
#define I2S_ERROR_MODE_INVALID              (I2S_ERROR_BASE | 0x03)
#define I2S_ERROR_WORD_LENGTH_UNSUPPORTED   (I2S_ERROR_BASE | 0x04)
#define I2S_ERROR_CLK_INVALID               (I2S_ERROR_BASE | 0x05)
#define I2S_ERROR_DIVIDER_VALUE_INVALID     (I2S_ERROR_BASE | 0x06)
#define I2S_ERROR_FREQUENCY_INVALID         (I2S_ERROR_BASE | 0x07)
#define I2S_ERROR_BUFFER_SMALL              (I2S_ERROR_BASE | 0x08)
#define I2S_ERROR_DEVICE_BUSY               (I2S_ERROR_BASE | 0x09)
#define I2S_ERROR_PARAM_OUT_OF_RANGE        (I2S_ERROR_BASE | 0x0A)
#define I2S_ERROR_IO_INIT_FAILED            (I2S_ERROR_BASE | 0x0B)

/*
** IOCTL calls specific to I2S
*/
#define IO_TYPE_I2S                                 0x15
#define IO_IOCTL_I2S_SET_MODE_MASTER                _IO(IO_TYPE_I2S, 0x01)
#define IO_IOCTL_I2S_SET_MODE_SLAVE                 _IO(IO_TYPE_I2S, 0x02)
#define IO_IOCTL_I2S_SET_CLOCK_SOURCE_INT           _IO(IO_TYPE_I2S, 0x03)
#define IO_IOCTL_I2S_SET_CLOCK_SOURCE_EXT           _IO(IO_TYPE_I2S, 0x04)
#define IO_IOCTL_I2S_SET_DATA_BITS                  _IO(IO_TYPE_I2S, 0x05)
#define IO_IOCTL_I2S_DISABLE_DEVICE                 _IO(IO_TYPE_I2S, 0x06)
#define IO_IOCTL_I2S_ENABLE_DEVICE                  _IO(IO_TYPE_I2S, 0x07)
#define IO_IOCTL_I2S_SET_MCLK_FREQ                  _IO(IO_TYPE_I2S, 0x08)
#define IO_IOCTL_I2S_SET_FS_FREQ                    _IO(IO_TYPE_I2S, 0x09)
#define IO_IOCTL_I2S_TX_DUMMY_ON                    _IO(IO_TYPE_I2S, 0x0A)
#define IO_IOCTL_I2S_TX_DUMMY_OFF                   _IO(IO_TYPE_I2S, 0x0B)
#define IO_IOCTL_I2S_GET_MODE                       _IO(IO_TYPE_I2S, 0x0C)
#define IO_IOCTL_I2S_GET_CLOCK_SOURCE               _IO(IO_TYPE_I2S, 0x0D)
#define IO_IOCTL_I2S_GET_DATA_BITS                  _IO(IO_TYPE_I2S, 0x0E)
#define IO_IOCTL_I2S_GET_MCLK_FREQ                  _IO(IO_TYPE_I2S, 0x0F)
#define IO_IOCTL_I2S_GET_BCLK_FREQ                  _IO(IO_TYPE_I2S, 0x10)
#define IO_IOCTL_I2S_GET_TX_DUMMY                   _IO(IO_TYPE_I2S, 0x11)
#define IO_IOCTL_I2S_GET_FS_FREQ                    _IO(IO_TYPE_I2S, 0x12)
#define IO_IOCTL_I2S_GET_STATISTICS                 _IO(IO_TYPE_I2S, 0x13)
#define IO_IOCTL_I2S_SET_TXFIFO_WATERMARK           _IO(IO_TYPE_I2S, 0x14)
#define IO_IOCTL_I2S_SET_RXFIFO_WATERMARK           _IO(IO_TYPE_I2S, 0x15)
#define IO_IOCTL_I2S_GET_TXFIFO_WATERMARK           _IO(IO_TYPE_I2S, 0x16)
#define IO_IOCTL_I2S_GET_RXFIFO_WATERMARK           _IO(IO_TYPE_I2S, 0x17)
#define IO_IOCTL_I2S_SET_CLK_ALWAYS_ENABLED_ON      _IO(IO_TYPE_I2S, 0x18)
#define IO_IOCTL_I2S_SET_CLK_ALWAYS_ENABLED_OFF     _IO(IO_TYPE_I2S, 0x19)
#define IO_IOCTL_I2S_GET_CLK_ALWAYS_ENABLED         _IO(IO_TYPE_I2S, 0x1A)
#define IO_IOCTL_I2S_CLEAR_STATISTICS               _IO(IO_TYPE_I2S, 0x1B)

/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** I2S_STATISTICS_STRUCT
** I2S run time statistics structure
*/

typedef struct i2s_statistics_struct
{
    /* Number of SAI interrupts so far */
    uint_32 INTERRUPTS;

    /* FIFO error */
    uint_32 FIFO_ERROR;

    /* FIFO sync error */
    uint_32 BUFFER_ERROR;

    /* Number of valid bytes received (not dummy receives) */
    uint_32 RX_PACKETS;

    /* Number of valid bytes transmitted (not dummy transmits) */
    uint_32 TX_PACKETS;

    /* Number of bytes currently read or wrote */
    uint_32 PACKETS_PROCESSED;

    /* Number of bytes currently buffered */
    uint_32 PACKETS_QUEUED;

    /* Number of bytes requested for reading or writing */
    uint_32 PACKETS_REQUESTED;

} I2S_STATISTICS_STRUCT, _PTR_ I2S_STATISTICS_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

   extern _mqx_uint _io_i2s_install(
    char_ptr,
    _mqx_uint (_CODE_PTR_)(pointer, char_ptr),
    _mqx_uint (_CODE_PTR_)(pointer, pointer),
    _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
    _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
    _mqx_int (_CODE_PTR_)(pointer, _mqx_uint, _mqx_uint_ptr),
    pointer);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_tins.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_tins.c$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*   This file contains the functions for converting ticks to nanoseconds
*
*END************************************************************************/

#include "mqx_inc.h"

/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_ticks_to_nanoseconds
* Returned Value   : uint_32 - number of nanoseconds
* Comments         :
*    This function converts ticks into nanoseconds, with rounding or truncating
*
*END*----------------------------------------------------------------------*/

static uint_32 __psp_ticks_to_nanoseconds
   (
      /* [IN] Ticks to be converted */
      PSP_TICK_STRUCT_PTR tick_ptr,

      /* [OUT] pointer to where the overflow boolean is to be written */
      boolean _PTR_       overflow_ptr,
      
      /* [IN] boolean to control rounding or truncating */
      boolean             round
   )
{ /* Body */
   PSP_128_BIT_UNION      tmp;
   KERNEL_DATA_STRUCT_PTR kernel_data;

   _GET_KERNEL_DATA(kernel_data);

#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
   tmp.LLW[1]  = tick_ptr->TICKS[0];
   tmp.LLW[0] = 0;
#else
   tmp.LLW[0]  = tick_ptr->TICKS[0];
   tmp.LLW[1] = 0;
#endif

   /* Convert ticks to hardware ticks */
   _psp_mul_128_by_32(&tmp, kernel_data->HW_TICKS_PER_TICK, &tmp);

   /* Add in hardware ticks */
   _psp_add_element_to_array(tmp.LW, tick_ptr->HW_TICKS[0], 
      sizeof(PSP_128_BIT_UNION) / sizeof(uint_32), tmp.LW);

   /* 
   ** Convert hardware ticks to ns. (H / (T/S * H/T) * 1000000000)
   ** Multiply by an extra 10 for rounding purposes.
   */
   _psp_mul_128_by_32(&tmp, 1000000000, &tmp);
   _psp_mul_128_by_32(&tmp, 10, &tmp);
   _psp_div_128_by_32(&tmp, kernel_data->TICKS_PER_SECOND, &tmp);
   _psp_div_128_by_32(&tmp, kernel_data->HW_TICKS_PER_TICK, &tmp);
      /* Round OR Truncate*/
   if (round)
   {
       _psp_add_element_to_array(tmp.LW, 5, sizeof(PSP_128_BIT_UNION) / sizeof(uint_32), tmp.LW);
   }
   _psp_div_128_by_32(&tmp, 10, &tmp);

#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
   *overflow_ptr = tmp.LLW[0] || tmp.LW[2];
   return tmp.LW[3];
#else
   *overflow_ptr = tmp.LLW[1] || tmp.LW[1];
   return tmp.LW[0];
#endif


} /* Endbody */

/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_ticks_to_nanoseconds
* Returned Value   : uint_32 - number of nanoseconds
* Comments         :
*    This function converts ticks into nanoseconds, with rounding
*
*END*----------------------------------------------------------------------*/

uint_32 _psp_ticks_to_nanoseconds
   (
      /* [IN] Ticks to be converted */
      PSP_TICK_STRUCT_PTR tick_ptr,

      /* [OUT] pointer to where the overflow boolean is to be written */
      boolean _PTR_       overflow_ptr
   )
{ /* Body */
    return __psp_ticks_to_nanoseconds(tick_ptr, overflow_ptr, TRUE);
}

/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_ticks_to_nanoseconds
* Returned Value   : uint_32 - number of nanoseconds
* Comments         :
*    This function converts ticks into nanoseconds, with truncating
*
*END*----------------------------------------------------------------------*/

uint_32 _psp_ticks_to_nanoseconds_truncate
   (
      /* [IN] Ticks to be converted */
      PSP_TICK_STRUCT_PTR tick_ptr,

      /* [OUT] pointer to where the overflow boolean is to be written */
      boolean _PTR_       overflow_ptr
   )
{ /* Body */
    return __psp_ticks_to_nanoseconds(tick_ptr, overflow_ptr, FALSE);
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_ftfe_prv.h<|end_filename|>
#ifndef __flash_ftfe_prv_h__
#define __flash_ftfe_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_ftfe_prv.h$
* $Version : 3.8.2.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*   The file contains function prototypes and defines for the internal 
*   flash driver.
*
*END************************************************************************/

#include "flashx.h"

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/* FTFE commands */
#define FTFE_VERIFY_BLOCK              0x00
#define FTFE_VERIFY_SECTION            0x01
#define FTFE_PROGRAM_CHECK             0x02
#define FTFE_READ_RESOURCE             0x03
#define FTFE_PROGRAM_LONGWORD          0x06
#define FTFE_PROGRAM_PHRASE            0x07
#define FTFE_ERASE_BLOCK               0x08
#define FTFE_ERASE_SECTOR              0x09
#define FTFE_PROGRAM_SECTION           0x0B
#define FTFE_VERIFY_ALL_BLOCK          0x40
#define FTFE_READ_ONCE                 0x41
#define FTFE_PROGRAM_ONCE              0x43
#define FTFE_ERASE_ALL_BLOCK           0x44
#define FTFE_SECURITY_BY_PASS          0x45
#define FTFE_PROGRAM_PARTITION         0x80
#define FTFE_SET_EERAM                 0x81

/* FTFE margin read settings */
#define FTFE_MARGIN_NORMAL             0x0000
#define FTFE_USER_MARGIN_LEVEL1        0x0001
#define FTFE_USER_MARGIN_LEVEL0        0x0002
#define FTFE_FACTORY_MARGIN_LEVEL0     0x0003
#define FTFE_FACTORY_MARGIN_LEVEL1     0x0004

/* FTFE sizes */
#define FTFE_WORD_SIZE                 0x0002
#define FTFE_PHRASE_SIZE               0x0008

/* FTFE error codes */
#define FTFE_OK                        0x0000
#define FTFE_ERR_SIZE                  0x0001
#define FTFE_ERR_RANGE                 0x0002
#define FTFE_ERR_ACCERR                0x0004
#define FTFE_ERR_PVIOL                 0x0008
#define FTFE_ERR_MGSTAT0               0x0010
#define FTFE_ERR_CHANGEPROT            0x0020
#define FTFE_ERR_EEESIZE               0x0040
#define FTFE_ERR_EFLASHSIZE            0x0080
#define FTFE_ERR_ADDR                  0x0100
#define FTFE_ERR_NOEEE                 0x0200
#define FTFE_ERR_EFLASHONLY            0x0400
#define FTFE_ERR_DFLASHONLY            0x0800
#define FTFE_ERR_RDCOLERR              0x1000
#define FTFE_ERR_RAMRDY                0x2000

/* Start and End Address of PFlash IFR and DFlash IFR */
#define PFLASH_IFR_START_ADDRESS       0x000000
#define PFLASH_IFR_END_ADDRESS         0x0000FF
#define DFLASH_IFR_START_ADDRESS       0x800000
#define DFLASH_IFR_END_ADDRESS         0x8000FF
#define DFLASH_IFR_LONGWORD_ADDRESS    0x8000FC

#define FLASHX_INVALIDATE_CACHE_ALL    0xFFFFFFFF
#define FLASHX_INVALIDATE_CACHE_BLOCK0 0x00000001
#define FLASHX_INVALIDATE_CACHE_BLOCK1 0x00000002
#define FLASHX_INVALIDATE_CACHE_BLOCK2 0x00000004
#define FLASHX_INVALIDATE_CACHE_BLOCK3 0x00000008

/*----------------------------------------------------------------------*/
/*
**                    Structure Definitions
*/

typedef struct ftfe_flash_internal_struct 
{
    vchar_ptr  ftfe_ptr;
    char_ptr   flash_execute_code_ptr;
        
} FTFE_FLASH_INTERNAL_STRUCT, _PTR_ FTFE_FLASH_INTERNAL_STRUCT_PTR;

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

boolean ftfe_flash_init(IO_FLASHX_STRUCT_PTR);
void    ftfe_flash_deinit(IO_FLASHX_STRUCT_PTR);
boolean ftfe_flash_erase_sector(IO_FLASHX_STRUCT_PTR, char_ptr, _mem_size);
boolean ftfe_flash_write_sector(IO_FLASHX_STRUCT_PTR, char_ptr, char_ptr, _mem_size);

#ifdef __cplusplus
}
#endif

#endif //__flash_ftfe_prv_h__


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_dopr.c<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_dopr.c$
* $Version : 3.8.18.0$
* $Date    : Jul-12-2012$
*
* Comments:
*
*   This file contains the functions for the formatting of
*   output.
*   $Header:io_dopr.c, 7, 2/23/2004 2:36:23 PM, $
*   $NoKeywords$
*
*END************************************************************************/


#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io_prv.h"

static volatile double tmp_d1, tmp_d2; 

extern void _io_doprint_prt(int_32, uchar _PTR_, int_32, boolean);
extern void _io_doprint_prt64(int_64, uchar _PTR_, int_32, boolean);

#if MQX_INCLUDE_FLOATING_POINT_IO
extern _mqx_int _io_dtoe(char _PTR_, double arg, char _PTR_, char, char, char, int_32, char);
extern _mqx_int _io_dtof(char _PTR_, double arg, char _PTR_, char, char, char, int_32, char);
extern _mqx_int _io_dtog(char _PTR_, double arg, char _PTR_, char, char, char, int_32, char);
#endif

// Keil: suppress ellipsis warning in va_arg usage below
#if defined(__CC_ARM)
#pragma diag_suppress 1256
#endif


// Utility function prototypes
static _mqx_int _io_mputc(MQX_FILE_PTR, IO_PUTCHAR_FPTR func_ptr, _mqx_int max_count, char c, _mqx_int count);
static _mqx_int _io_putstr(MQX_FILE_PTR, IO_PUTCHAR_FPTR func_ptr, _mqx_int max_count, char_ptr str);

/*!
 * \brief Gets given character count times.
 *
 * \note I/O is performed by calling given function pointer using following
 * (*func_ptr)(c,farg);
 *
 * \param[in] farg      Argument to func_ptr
 * \param[in] func_ptr  Function to put character out.
 * \param[in] max_count Maximum character count for snprintfand vsnprintf.
 * Default value is 0 (unlimited size).
 * \param[in] c         The character to put out.
 * \param[in] count     Number of characters to be printed out.
 *
 * \return Character count.
 */
static _mqx_int _io_mputc
(
    MQX_FILE_PTR farg,
    IO_PUTCHAR_FPTR func_ptr,
    _mqx_int        max_count,
    char            c,
    _mqx_int        count
)
{
    int_32   cnt = 0;

    if (count < 0)
    {
        count = 0;
    }

    for (;(cnt < count); cnt++)
    {
        if (max_count > (cnt + 1))
        {
            if (c != func_ptr((_mqx_int) c, farg))
            {
                break;
            }
        }
    }

    return cnt;
}

/*!
 * \brief Gets given string.
 *
 * \note I/O is performed by calling given function pointer using following
 * (*func_ptr)(c,farg);
 *
 * \param[in] farg      Argument to func_ptr.
 * \param[in] func_ptr  Function to put character out.
 * \param[in] max_count Maximum character count for snprintfand vsnprintf.
 * Default value is 0 (unlimited size).
 * \param[in] str       The string to put out.
 *
 * \return String.
 */
static _mqx_int _io_putstr
(
    MQX_FILE_PTR farg,
    IO_PUTCHAR_FPTR func_ptr,
    _mqx_int        max_count,
    char_ptr        str
)
{
    _mqx_int res = 0;
    boolean compare = TRUE;

    for ( ; *str && compare; res++, str++)
    {
        if (max_count > (res + 1))
        {
            compare = ((_mqx_int) *str == func_ptr((_mqx_int) *str, farg));
        }
        else
        {
            compare = TRUE;
        }
    }

    if (*str)
    {
        res--;
    }
    return res;
}


#ifdef __GNUC__
#pragma GCC push_options
#pragma GCC optimize ("O0")
#endif


/*!
 * \brief This function outputs its parameters according to a formatted string.
 *
 * \note I/O is performed by calling given function pointer using following
 * (*func_ptr)(c,farg);
 *
 * \param[in] farg      Argument to func_ptr.
 * \param[in] func_ptr  Function to put character out.
 * \param[in] max_count Maximum character count for snprintfand vsnprintf.
 * Default value is 0 (unlimited size).
 * \param[in] fmt_ptr   Format string for printf.
 * \param[in] args_ptr  Arguments to printf.
 *
 * \return Number of characters
 * \return IO_EOF (End Of File found.)
 */
_mqx_int _io_doprint
(
      MQX_FILE_PTR        farg,
      IO_PUTCHAR_FPTR     func_ptr,
      _mqx_int            max_count,
      register char _PTR_ fmt_ptr,
      va_list             args_ptr
)
{ /* Body */
   uchar    string[32];   /* The string str points to this output   */
   char     c;
   int_32   i;
   int_64   i64;
   _mqx_int f;            /* the format character (comes after %)   */
   uchar _PTR_ str_ptr;  /* running pointer in string              */
   /*    from number conversion              */
   _mqx_int length;       /* Length of string "str"                 */
   char     fill;         /* Fill character ( ' ' or '0' )          */
   _mqx_int leftjust;     /* 0 = right-justified, else left-just.   */
   _mqx_int prec,width;   /* Field specifications % width . precision */
   _mqx_int leading;      /* No. of leading/trailing fill chars.    */
   uchar    sign;         /* Set to '-' for negative decimals       */
   int      digit1;       /* Offset to add to first numeric digit.  */
   char     use_caps;     /* Hex output to use capital letters.     */
   char     use_signs;    /* Always output a sign for %d            */
   char     use_space;    /* If positive and not sign, print space for %d */
   char     use_prep;     /* Prepend 0 for octal, 0x , 0X for hex   */
   char     use_int_prec; /* Precision usage with d, i, o, u, x, X  */
   char     zero_value;   /* indicates 0 output value */
   char     zero_char;    /* indicates 0x00 char  */
   char     prepend;      /* What prepend type 3 octal 2 0x, 1 0X   */
   _mqx_int arg_length;   /* optional argument length               */
   char     done;
   char     is_integer;
   _mqx_int number_of_characters;  /* # chars printed out */
#if MQX_INCLUDE_FLOATING_POINT_IO
   char     prec_set;
   double   fnumber;
   char     fstring[324]; /* Floating point output string           */
#endif
   uint_32_ptr temp_ptr;
   _mqx_int    func_result = MQX_OK;

   enum types{ HALF, HALFHALF, LONG, LONGLONG, LONGDOUBLE };

   number_of_characters = 0;
   /* if max_count == -1 then maximal positive number is stored in max_count */
   /* it is not gnu standard because max count shoud be unsigned */
   if (max_count == -1)
   {
        max_count = MAX_INT_32;
   }
   for ( ;; ) {
      /* Echo characters until '%' or end of fmt_ptr string */
      while ((c = *fmt_ptr++ ) != '%')
      {
         if (c == '\0')
         {
            if (func_result == IO_EOF)
            {
               return(IO_EOF);
            } else
            {
               return number_of_characters;
            } /* Endif */
         } /* Endif */
         number_of_characters++;
         if (max_count > number_of_characters)
         {
            func_result = (*func_ptr)((_mqx_int)c, farg);
         }
      } /* Endwhile */

      /* Echo "...%%..." as '%' */
      if (  *fmt_ptr == '%'  )
      {
         number_of_characters++;
         if (max_count > number_of_characters)
         {
             func_result = (*func_ptr)((_mqx_int)*fmt_ptr++, farg);
         }
            continue;
      } /* Endif */

      /* Set default flag */
      fill         = ' ';
      sign         = '\0';
      arg_length   = sizeof(int_32);
      leftjust     = 0;
      use_caps     = 0;
      use_space    = 0;
      use_prep     = 0;
      use_signs    = 0;
      use_int_prec = 0;
      prepend      = 0;
      zero_value   = 0;
      zero_char    = 0;
#if MQX_INCLUDE_FLOATING_POINT_IO
      prec_set   = 0;
#endif

      /* Collect Valid Flags */
      done = FALSE;
      while ( *fmt_ptr && ! done ) {
         switch ( *fmt_ptr ) {

            case '-':
               /* Check for "%-..." EQ Left-justified output */
               leftjust = 1;
               fmt_ptr++;
               break;

            case '0':
               fill = '0';
               fmt_ptr++;
               break;

            case '+':
               use_signs = 1;
               fmt_ptr++;
               break;

            case ' ':
               use_space = 1;
               fmt_ptr++;
               break;

            case '#':
               use_prep = 1;
               fmt_ptr++;
               break;

            default:
               done = TRUE;
            break;
         } /* Endswitch */
      } /* Endwhile */

      /* Allow for minimum field width specifier for %d,u,x,o,c,s */
      /* Also allow %* for variable width ( %0* as well)           */
      width = 0;
      if (  *fmt_ptr == '*'  ) {
         width = va_arg(args_ptr, uint_32);
         ++fmt_ptr;
      } else {
         while (  ('0' <= *fmt_ptr) && (*fmt_ptr <= '9')  ) {
            width = width * 10 + *fmt_ptr++ - '0';
         } /* Endwhile */
         /* Allow for maximum string width for %s */
      } /* Endif */

      prec = -1;
      if (  *fmt_ptr == '.'  ) {
         prec = 0;
         if (  *(++fmt_ptr) == '*'  ) {
            prec = va_arg(args_ptr, uint_32);
#if MQX_INCLUDE_FLOATING_POINT_IO
            prec_set = 1;
#endif
            ++fmt_ptr;
         } else {
            while (  ('0' <= *fmt_ptr) && (*fmt_ptr <= '9')  ) {
               prec = prec * 10 + *fmt_ptr++ - '0';
#if MQX_INCLUDE_FLOATING_POINT_IO
               prec_set = 1;
#endif
            } /* Endwhile */
         } /* Endif */
      } /* Endif */

      str_ptr = string;
      if (  (f = *fmt_ptr++) == '\0'  ) {
         number_of_characters++;
         if (max_count > number_of_characters)
         {
             func_result = (*func_ptr)((_mqx_int)'%', farg);
         }
         if (func_result == IO_EOF) {
            return(IO_EOF);
         } else {
            return number_of_characters;
         } /* Endif */
      } /* Endif */

        switch (f)
        {
        case 'h' :
            arg_length = HALF;
            f = *fmt_ptr++;
            if (f == 'h')
            {
                arg_length = HALFHALF;
                f = *fmt_ptr++;
            }
            break;
        case 'l' :
            arg_length = LONG;
            f = *fmt_ptr++;
            if (f == 'l')
            {
                arg_length = LONGLONG;
                f = *fmt_ptr++;
            }
            break;
        case 'L' :
            arg_length = LONGDOUBLE;
            f = *fmt_ptr++;
            break;
        default:
            break;
        }

      use_caps = FALSE;
      is_integer = FALSE;
      length = 0;
      switch (  f  ) {
         case 'c':
         case 'C':
            string[0] = (char)va_arg(args_ptr, _mqx_int);
            if (string[0] == 0) {
               length += 1;
               zero_char = 1;
            } /* Endif */
            string[1] = '\0';
            prec = 0;
            fill = ' ';
            use_prep = 0;
            break;

         case 's':
         case 'S':
            str_ptr = (uchar _PTR_)va_arg(args_ptr, pointer);
            fill = ' ';
            use_prep = 0;
            break;

         case 'i':
         case 'I':
         case 'd':
         case 'D':
            is_integer = TRUE;
         case 'u':
         case 'U':
            if (f == 'u' || f == 'U') {
            }
            if (prec > 0) {
                use_int_prec = 1;
            }
            if (is_integer) {
               if (arg_length == LONGLONG) {
                  i64 = va_arg(args_ptr, int_64);
                  zero_value = i64 == 0L;
                  if (i64 < 0) {
                     sign = '-';
                     i64 = -i64;
                  } else if ( use_signs ) {  /* Always a sign */
                     sign = '+';
                  } else if ( use_space ) {  /* use spaces */
                     sign = ' ';
                  } /* Endif */
               } else {
                  if (arg_length == HALF) {
                     i = (int_16) va_arg(args_ptr,  signed int);
                  } else if (arg_length == HALFHALF) {
                     i = (int_8) va_arg(args_ptr,  signed int);
                  } else if (arg_length == LONG) {
                     i = va_arg(args_ptr, int_32);
                  } else {
                     i = va_arg(args_ptr, _mqx_int);
                  }
                  zero_value = i == 0;
                  if (i < 0) {
                     sign = '-';
                     i = -i;
                  } else if ( use_signs ) {  /* Always a sign */
                     sign = '+';
                  } else if ( use_space ) {  /* use spaces */
                     sign = ' ';
                  } /* Endif */
               }
            } else {
               if (arg_length == HALF) {
                  i = (uint_16) va_arg(args_ptr, unsigned int);
                  zero_value = i == 0;
               } else if (arg_length == HALFHALF) {
                  i = (uint_8) va_arg(args_ptr, unsigned int);
                  zero_value = i == 0;
               } else if (arg_length == LONG) {
                  i = va_arg(args_ptr, uint_32);
                  zero_value = i == 0;
               } else if (arg_length == LONGLONG) {
                  i64 = va_arg(args_ptr, uint_64);
                  zero_value = i64 == 0L;
               } else {
                  i = va_arg(args_ptr, _mqx_uint);
                  zero_value = i == 0;
               }/* Endif */
            } /* Endif */
            digit1 = '\0';
            /* "negative" longs in unsigned format       */
            /* can't be computed with long division      */
            /* convert *args_ptr to "positive", digit1   */
            /* = how much to add back afterwards         */
            if (arg_length == LONGLONG) {
               while (i64 < 0) {
                  i64 -= _MQX_IO_DIVISION_ADJUST_64;
                  ++digit1;
               } /* Endwhile */
               _io_doprint_prt64(i64, str_ptr + 1, PRINT_DECIMAL_64, (boolean)use_caps);
               str_ptr[1] += digit1;
               if (str_ptr[1] > '9') {
                  str_ptr[1] -= 10;
                  str_ptr[0] = '1';
               } else {
                  str_ptr += 1;
               }
            } else {
               while (i < 0) {
                  i -= _MQX_IO_DIVISION_ADJUST;
                  ++digit1;
               } /* Endwhile */
               _io_doprint_prt(i, str_ptr, PRINT_DECIMAL, (boolean)use_caps);
               str_ptr[0] += digit1;
            }
            use_prep = 0;
            break;

         case 'o':
         case 'O':
            if (prec > 0) {
               use_int_prec = 1;
            }
            if (arg_length == LONGLONG) {
               i64 = va_arg(args_ptr, uint_64);
               zero_value = i64 == 0L;
               _io_doprint_prt64(i64, str_ptr, PRINT_OCTAL_64, (boolean)use_caps);
            } else {
               if (arg_length == HALF) {
                  i = (uint_16) va_arg(args_ptr, unsigned int);
               } else if (arg_length == HALFHALF) {
                  i = (uint_8) va_arg(args_ptr, unsigned int);
               } else if (arg_length == LONG) {
                  i = va_arg(args_ptr, uint_32);
               } else {
                  i = va_arg(args_ptr, _mqx_uint);
               }/* Endif */
               zero_value = i == 0;
               _io_doprint_prt(i, str_ptr, PRINT_OCTAL, (boolean)use_caps);
            }
            prepend = 3;
            break;

         case 'P':
            use_caps = TRUE;
         case 'p':
            leading = 0;
            temp_ptr = (uint_32_ptr) va_arg(args_ptr, pointer);
            _io_doprint_prt((_mqx_max_type)temp_ptr, str_ptr, PRINT_ADDRESS,
               (boolean)use_caps);
         break;

         case 'X':
            use_caps = TRUE;
            prepend  = 1;
         case 'x':
            if (prec > 0) {
                use_int_prec = 1;
            }
            prepend++;
            if (arg_length == LONGLONG) {
               i64 = va_arg(args_ptr, uint_64);
               zero_value = i64 == 0L;
               _io_doprint_prt64(i64, str_ptr, PRINT_HEX_64, (boolean)use_caps);
            } else {
               if (arg_length == HALF) {
                  i = (uint_16) va_arg(args_ptr, unsigned int);
               } else if (arg_length == HALFHALF) {
                  i = (uint_8) va_arg(args_ptr, unsigned int);
               } else if (arg_length == LONG) {
                  i = va_arg(args_ptr, uint_32);
               } else {
                  i = va_arg(args_ptr, _mqx_uint);
               }/* Endif */
               zero_value = i == 0;
               _io_doprint_prt(i, str_ptr, PRINT_HEX, (boolean)use_caps);
            }
            break;

         case 'n':   /* Defaults to size of number on stack */
         case 'N':   /* Defaults to size of number on stack */
            str_ptr = (uchar _PTR_)va_arg(args_ptr, pointer);
            *(_mqx_int _PTR_)(str_ptr) = (int_32)number_of_characters;
            continue;

#if MQX_INCLUDE_FLOATING_POINT_IO

         case 'g':
         case 'G':

             if (! prec_set)
             {
                prec = 6;
             }
             if (arg_length == LONGDOUBLE) {
                fnumber = va_arg(args_ptr, long double);
             } else {
                fnumber = va_arg(args_ptr, double);
             }/* Endif */
             i = _io_dtog(fstring, fnumber, &fill, use_signs, use_space, use_prep,
                (prec - 1), (char)f);
             str_ptr = (uchar_ptr)fstring;
             if (*str_ptr == '+') {
                sign = '+';
                str_ptr++;
             } else if (*str_ptr == '-') {
                sign = '-';
                str_ptr++;
             }
             use_prep = 0;
             prec = 0;
          break;

         case 'f':
         case 'F':
            if (! prec_set) {
               prec = 6;
            } /* Endif */
            if (prec == 0) {
               prec = 1;
            }
            if (arg_length == LONGDOUBLE) {
               fnumber = va_arg(args_ptr, long double);
            } else {
               fnumber = va_arg(args_ptr, double);
            }/* Endif */
            tmp_d1 = fnumber;
            i = _io_dtof(fstring, fnumber, &fill, use_signs, use_space, use_prep,
               prec, (char)f);
            str_ptr = (uchar_ptr)fstring;
            if (*str_ptr == '+') {
               sign = '+';
               str_ptr++;
            } else if (*str_ptr == '-') {
               sign = '-';
               str_ptr++;
            }
            use_prep = 0;
            prec = 0;
         break;

         case 'e':
         case 'E':
            if (! prec_set) {
               prec = 6;
            }
            if (arg_length == LONGDOUBLE) {
               fnumber = va_arg(args_ptr, long double);
            } else {
               fnumber = va_arg(args_ptr, double);
            }/* Endif */
            i = _io_dtoe(fstring, fnumber, &fill, use_signs, use_space, use_prep,
               prec, (char)f);
            str_ptr = (uchar_ptr)fstring;
            if (*str_ptr == '+') {
               sign = '+';
               str_ptr++;
            } else if (*str_ptr == '-') {
               sign = '-';
               str_ptr++;
            }
            use_prep = 0;
            prec = 0;
         break;
#endif

         default:
            number_of_characters++;
            if (max_count > number_of_characters)
            {
                func_result = (*func_ptr)((_mqx_int)f, farg);
            }
            if (func_result == IO_EOF) {
               return(IO_EOF);
            } else {
               return number_of_characters;
            } /* Endif */
      } /* End Switch */

      for (; str_ptr[length] != '\0'; length++ )
      {
         ;
      } /* Endfor */

      if ( (width < 0) )
      {
         width = 0;
      } /* Endif */
      if ( (prec < 0) )
      {
         prec = 0;
      }
      else
      {
         if (('s' == f) || ('S' == f))
         {
            if (length > prec)
            {
               length = prec;
            }
         }
      }
      leading = 0;

      if ( (prec != 0) || (width != 0) ) {
         /*
          * prec = precision
          *    For a string, the maximum number of characters to be printed
          *    from the string.
          *    for f,e,E the number of digits after the decimal point
          *    for g,G the number of significant digits
          *    for integer, the minimum number of digits to be printed
          *       leading 0's will precede
          */
         if ( !use_int_prec && (prec != 0) ) {
            if ( length > prec ) {
               if ( str_ptr == string ) {
                  /* this was a numeric input */
                  /* thus truncate to the left */
                  str_ptr += (length - prec);
               } /* Endif */
               length = prec;
            } /* Endif */
         } /* Endif */

         /* width = minimum field width
          *    argument will be printed in a field at least this wide,
          *    and wider if necessary.  If argument has fewer characters
          *    than the field width, is will be padded on left or right
          *    to make up the width.  Normally pad ' ' unless 0 specified.
          */
         if (use_int_prec) {
            if (width > prec) {
               leading = (prec > length) ? width - prec : width - length;
               if ( !zero_value && use_prep && (prepend == 3) && (prec > length)) {
                  leading++; /* correction for octal because one prepend 0 is pad as well as prepend character */
               }
            } else {
               leading = 0;
            }
         } else if ( width != 0 ) {
            leading = width - length;
         } /* Endif */

         if ( sign ) {
            --leading;
         } /* Endif */
         if ( use_prep && !zero_value ) {
            --leading;
            if ( prepend < 3 ) { /* HEX */
               --leading;
            } /* Endif */
         } /* Endif */

      } /* Endif */

      if (leading < 0) {
          leading = 0;
      }

      if ( leftjust == 0 ) { /* main flow for right justification */
         if (use_int_prec) {
            /* print out leading spaces first */
            number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, ' ', leading);

            /* print out sign if there's any */
            if ( ((sign == '+') || (sign == '-') || (sign == ' ')) ) { /* Leading '-', '+', ' ' */
               number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, sign, 1);
            }

            /* handle leading '0', '0x' or '0X' */
            if ( use_prep && !zero_value ) {
               switch (prepend) {
               case 1:
                  number_of_characters += _io_putstr(farg, func_ptr, max_count - number_of_characters, "0x");
                  break;
               case 2:
                  number_of_characters += _io_putstr(farg, func_ptr, max_count - number_of_characters, "0X");
                  break;
               default:
                  if (!((prec - length) > 0)) {
                     number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, '0', 1);
                  }
               }
            } /* Endif */

            /* print out leading 0's given by precision */
            number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, '0', prec - length);
         } else { /* right justification without precision for integer types */
            if (fill == '0') { /* flow for leading zeroes */
               /* print out sign if there's any */
               if ((sign == '+') || (sign == '-') || (sign == ' ')) { /* Leading '-', '+', ' ' */
                  number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, sign, 1);
               }

               /* handle leading '0', '0x' or '0X' */
               if ( use_prep && !zero_value ) {
                  switch (prepend) {
                  case 1:
                     number_of_characters += _io_putstr(farg, func_ptr, max_count - number_of_characters, "0x");
                     break;
                  case 2:
                     number_of_characters += _io_putstr(farg, func_ptr, max_count - number_of_characters, "0X");
                     break;
                  default:
                     number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, '0', 1);
                  }
               } /* Endif */

               /* print out leading 0's */
               number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, fill, leading);
            } else { // flow for leading spaces
               /* print out leading spaces */
               number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, fill, leading);

               /* print out sign if there's any */
               if ((sign == '+') || (sign == '-') || (sign == ' ')) { /* Leading '-', '+', ' ' */
                  number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, sign, 1);
               }

               /* handle leading '0', '0x' or '0X' */
               if ( use_prep && !zero_value ) {
                  switch (prepend) {
                  case 1:
                     number_of_characters += _io_putstr(farg, func_ptr, max_count - number_of_characters, "0x");
                     break;
                  case 2:
                     number_of_characters += _io_putstr(farg, func_ptr, max_count - number_of_characters, "0X");
                     break;
                  default:
                      number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, '0', 1);
                  }
               } /* Endif */
            }
         }
      } else { /* left justification has different flow */
         /* print out sign if there's any */
         if ( ((sign == '+') || (sign == '-') || (sign == ' ')) ) { /* Leading '-', '+', ' ' */
            number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, sign, 1);
         }

         /* handle leading '0', '0x' or '0X' */
         if ( use_prep && !zero_value ) {
            switch (prepend) {
            case 1:
               number_of_characters += _io_putstr(farg, func_ptr, max_count - number_of_characters, "0x");
               break;
            case 2:
               number_of_characters += _io_putstr(farg, func_ptr, max_count - number_of_characters, "0X");
               break;
            default:
               if (!use_int_prec || ((prec - length) < 0)) {
                   number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, '0', 1);
               }
            }
         } /* Endif */

         if (use_int_prec) {
            /* print out leading 0's given by precision */
            number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, '0', prec - length);
         }
      }

      /* print out actual characters */
      length++;
      if (length > max_count - number_of_characters)
      {
      	 length = max_count - number_of_characters;
      }

      if(zero_char) {
         number_of_characters += _io_mputc(farg, func_ptr, length, *str_ptr, 1);
      } else {
         number_of_characters += _io_putstr(farg, func_ptr, length, (char_ptr) str_ptr);
      }

      if (leftjust != 0) { /* Print trailing pad characters */
         /* print out leading 0's */
         number_of_characters += _io_mputc(farg, func_ptr, max_count - number_of_characters, ' ', leading);
      } /* Endif */

   } /* Endfor */
} /* Endbody */


#ifdef __GNUC__
#pragma GCC pop_options
#endif


static const char upper_hex_string[] = "0123456789ABCDEF";
static const char lower_hex_string[] = "0123456789abcdef";
/*!
 * \brief Converts a number into a printable string.
 *
 * \param[in]     num      The number to convert.
 * \param[in,out] str_ptr  The string to generate.
 * \param[in]     type     What base to use.
 * \param[in]     use_caps Specifies whether to use CAPITALS in hex, or not.
 */
void _io_doprint_prt
   (
      int_32         num,
      uchar _PTR_    str_ptr,
      int_32         type,
      boolean        use_caps
   )
{ /* Body */
   register int_32 i;
   char     temp[16];

   temp[0] = '\0';
   if (type == PRINT_OCTAL) {
      for (i = 1; i <= type; i++) {
         temp[i] = (char)((num & 0x7) + '0');
         num >>= 3;
      } /* Endfor */
      temp[PRINT_OCTAL] &= '3';
   } else if (type == PRINT_DECIMAL) {
      for (i = 1; i <= type; i++) {
         temp[i] = (char)(num % 10 + '0');
         num /= 10;
      } /* Endfor */
   } else {
      for (i = 1; i <= type; i++) {
         temp[i] = use_caps ? upper_hex_string[num & 0xF] : lower_hex_string[num & 0xF];
         num >>= 4;
      } /* Endfor */
   } /* Endif */
   for (i = type; temp[i] == '0'; i--) {
      ;
   } /* Endfor */
   if (i == 0) {
      i++;
   } /* Endif */
   while (i >= 0) {
      *str_ptr++ = temp[i--];
   } /* Endwhile */

} /* Endbody */

/*!
 * \brief Converts a 64bit number into a printable string.
 *
 * \param[in]     num      The number to convert.
 * \param[in,out] str_ptr  The string to generate.
 * \param[in]     type     What base to use.
 * \param[in]     use_caps Specifies whether to use CAPITALS in hex, or not.
 */
void _io_doprint_prt64
   (
      int_64         num,
      uchar _PTR_    str_ptr,
      int_32         type,
      boolean        use_caps
   )
{ /* Body */
   register int_32 i;
   char     temp[32];

   temp[0] = '\0';
   if (type == PRINT_OCTAL_64) {
      for (i = 1; i <= type; i++) {
         temp[i] = (char)((num & 0x7) + '0');
         num >>= 3;
      } /* Endfor */
      temp[PRINT_OCTAL_64] &= '1';
   } else if (type == PRINT_DECIMAL_64) {
      for (i = 1; i <= type; i++) {
         temp[i] = (char)(num % 10 + '0');
         num /= 10;
      } /* Endfor */
   } else {
      for (i = 1; i <= type; i++) {
         temp[i] = use_caps ? upper_hex_string[num & 0xF] : lower_hex_string[num & 0xF];
         num >>= 4;
      } /* Endfor */
   } /* Endif */
   for (i = type; temp[i] == '0'; i--) {
      ;
   } /* Endfor */
   if (i == 0) {
      i++;
   } /* Endif */
   while (i >= 0) {
      *str_ptr++ = temp[i--];
   } /* Endwhile */

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/gpio/io_gpio.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_gpio.h$
* $Version : 3.8.50.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/
#ifndef __io_gpio_h__
#define __io_gpio_h__

#include "ioctl.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef uint_32 GPIO_PIN_STRUCT;
typedef void (* IRQ_FUNC)(pointer);

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/


#define GPIO_IOCTL_ADD_PINS         _IO(IO_TYPE_GPIO,0x01)  /* Add pins to the file */
#define GPIO_IOCTL_WRITE_LOG1       _IO(IO_TYPE_GPIO,0x02)  /* Set pins on output port */
#define GPIO_IOCTL_WRITE_LOG0       _IO(IO_TYPE_GPIO,0x03)  /* Clear (set to 0) pins on output port */
#define GPIO_IOCTL_READ             _IO(IO_TYPE_GPIO,0x04)  /* Read data from input port */
#define GPIO_IOCTL_WRITE            _IO(IO_TYPE_GPIO,0x05)  /* Write data to output port */
#define GPIO_IOCTL_SET_IRQ_FUNCTION _IO(IO_TYPE_GPIO,0x06)  /* Set IRQ handler function */
#define GPIO_IOCTL_ENABLE_IRQ       _IO(IO_TYPE_GPIO,0x07)  /* Enable pins opened as IRQ in file */
#define GPIO_IOCTL_DISABLE_IRQ      _IO(IO_TYPE_GPIO,0x08)  /* Disable pins opened as IRQ in file */
#define GPIO_IOCTL_CPU_SPECIFIC     _IO(IO_TYPE_GPIO,0x09)  /* Next commands are specific for CPU */


#define GPIO_LIST_END           0x00000000
#define GPIO_PIN_VALID          0x80000000
#define GPIO_PIN_STATUS         0x40000000
#define GPIO_PIN_STATUS_0       0x00000000
#define GPIO_PIN_STATUS_1       0x40000000
#define GPIO_PIN_IRQ_RISING     0x02000000
#define GPIO_PIN_IRQ_FALLING    0x01000000
#define GPIO_PIN_IRQ_ZERO       0x04000000
#define GPIO_PIN_IRQ_ONE        0x08000000
#define GPIO_PIN_ADDR           0x00FFFFFF

#if PSP_MQX_CPU_IS_KINETIS
  #define GPIO_PIN_IRQ_LIST       GPIO_PIN_IRQ_RISING | GPIO_PIN_IRQ_FALLING | GPIO_PIN_IRQ_ZERO | GPIO_PIN_IRQ_ONE
  #define GPIO_PIN_PORT_SHIFT     0x05
  #define GPIO_PIN_BIT_MASK       0x1F
  #define GPIO_GET_PIN_USED(pin_map, addr, pin) ( pin_map.memory32[addr] & pin )
  #define GPIO_SET_PIN_USED(pin_map, addr, pin) { pin_map.memory32[addr] |= pin; }
#else
  #define GPIO_PIN_IRQ_LIST       GPIO_PIN_IRQ_RISING | GPIO_PIN_IRQ_FALLING
  #define GPIO_PIN_PORT_SHIFT     0x03
  #define GPIO_PIN_BIT_MASK       0x07
  #define GPIO_GET_PIN_USED(pin_map, addr, pin) ( pin_map.memory8[addr] & pin )
  #define GPIO_SET_PIN_USED(pin_map, addr, pin) { pin_map.memory8[addr] |= pin; }
#endif

#define GPIO_GET_PORT(x)          ((x) & GPIO_PIN_ADDR) >> GPIO_PIN_PORT_SHIFT
#define GPIO_GET_BIT_MASK(x)      (1 << ((x) & GPIO_PIN_BIT_MASK )) 


#define GPIO_PIN_IRQ    GPIO_PIN_IRQ_RISING /* support of legacy IRQ pin definition */

#define GPIO_PIN0   (0)
#define GPIO_PIN1   (1)
#define GPIO_PIN2   (2)
#define GPIO_PIN3   (3)
#define GPIO_PIN4   (4)
#define GPIO_PIN5   (5)
#define GPIO_PIN6   (6)
#define GPIO_PIN7   (7)
#define GPIO_PIN8   (8)
#define GPIO_PIN9   (9)
#define GPIO_PIN10  (10)
#define GPIO_PIN11  (11)
#define GPIO_PIN12  (12)
#define GPIO_PIN13  (13)
#define GPIO_PIN14  (14)
#define GPIO_PIN15  (15)
#define GPIO_PIN16  (16)
#define GPIO_PIN17  (17)
#define GPIO_PIN18  (18)
#define GPIO_PIN19  (19)
#define GPIO_PIN20  (20)
#define GPIO_PIN21  (21)
#define GPIO_PIN22  (22)
#define GPIO_PIN23  (23)
#define GPIO_PIN24  (24)
#define GPIO_PIN25  (25)
#define GPIO_PIN26  (26)
#define GPIO_PIN27  (27)
#define GPIO_PIN28  (28)
#define GPIO_PIN29  (29)
#define GPIO_PIN30  (30)
#define GPIO_PIN31  (31)
#define GPIO_PIN(x) (x)

/*----------------------------------------------------------------------*/
/*
**                          TYPE DEFINITIONS
*/

/*----------------------------------------------------------------------*/
/*
**                          FUNCTION PROTOTYPES
*/

extern _mqx_uint _io_gpio_install(char_ptr);
pointer _bsp_get_gpio_base_address(void);

/*----------------------------------------------------------------------*/
/*
**                          DEVICE-SPECIFIC DEFINITIONS
*/

#if MQX_CPU == PSP_CPU_MCF5282
  #include "io_gpio_mcf5235.h"
#elif PSP_MQX_CPU_IS_MCF5225X
  #include "io_gpio_mcf5225.h"
#elif PSP_MQX_CPU_IS_MCF5227X
  #include "io_gpio_mcf5227.h"
#elif PSP_MQX_CPU_IS_MCF51AC
  #include "io_gpio_mcf51ac.h"  
#elif PSP_MQX_CPU_IS_MCF51JM
  #include "io_gpio_mcf51jm.h"  
#elif PSP_MQX_CPU_IS_MCF51AG
  #include "io_gpio_mcf51ag.h"   
#elif PSP_MQX_CPU_IS_MCF51CN
  #include "io_gpio_mcf51cn.h"
#elif PSP_MQX_CPU_IS_MCF51EM
  #include "io_gpio_mcf51em.h"
#elif PSP_MQX_CPU_IS_MCF51MM
  #include "io_gpio_mcf51mm.h"
 #elif PSP_MQX_CPU_IS_MCF51JE
  #include "io_gpio_mcf51je.h"   
#elif PSP_MQX_CPU_IS_MCF5222X
  #include "io_gpio_mcf5222.h"
#elif PSP_MQX_CPU_IS_MCF5223X
  #include "io_gpio_mcf5223.h"
#elif PSP_MQX_CPU_IS_MCF5441X
  #include "io_gpio_mcf5441.h"
#elif PSP_MQX_CPU_IS_MCF5301X
  #include "io_gpio_mcf5301.h"
#elif PSP_MQX_CPU_IS_MCF532X
  #include "io_gpio_mcf532.h"
#elif PSP_MQX_CPU_IS_MCF520X
  #include "io_gpio_mcf520.h"
#elif PSP_MQX_CPU_IS_KINETIS
  #include "io_gpio_kgpio.h"
#elif MQX_CPU==PSP_CPU_MPC8306
  #include "io_gpio_mpc8306.h"
#elif MQX_CPU==PSP_CPU_MPC8308
  #include "io_gpio_mpc8308.h"
#elif MQX_CPU==PSP_CPU_MPC8309
  #include "io_gpio_mpc8309.h"
#elif PSP_MQX_CPU_IS_MCF51FD
  #include "io_gpio_mcf51fd.h"
#elif PSP_MQX_CPU_IS_MCF51JF
  #include "io_gpio_mcf51jf.h"
#elif PSP_MQX_CPU_IS_MCF51QM
  #include "io_gpio_mcf51qm.h"

#else
  #error IO_GPIO device driver not supported for processor.
#endif

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/serl_mcf5225.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_mcf5225.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains board-specific serial initialization functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "serl_mcf52xx.h"

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_serial_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding UART
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_serial_base_address
(
    uint_8 dev_num
)
{
   if (dev_num >= MCF5225_NUM_UARTS)
   {
      return NULL;
   }
   
   return (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->UART[dev_num]);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_serial_vector
* Returned Value   : Vector number upon success, 0 upon failure
* Comments         :
*    This function returns desired interrupt vector number for specified UART
*
*END*----------------------------------------------------------------------*/
PSP_INTERRUPT_TABLE_INDEX _bsp_get_serial_vector
(
   uint_8 dev_num
)
{
    volatile PSP_INTERRUPT_TABLE_INDEX vector;
    switch (dev_num) {
      case 0:
         vector = MCF5225_INT_UART0;
         break;
      case 1:
         vector = MCF5225_INT_UART1;
         break;
      case 2:
         vector = MCF5225_INT_UART2;
         break;
      default:
         vector = (PSP_INTERRUPT_TABLE_INDEX)0;
         break;
    } /* Endswitch */
    return vector;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/app_IDs.h<|end_filename|>
#ifndef __APP_IDS
  #define __APP_IDS

//******************************************************************************************************************************************************
//  Частотный преобразователь
//******************************************************************************************************************************************************
#define INVERT_ONBUS_MSG                 0x1BF0FFFF  // Асинхронная посылка из платы инвертера
#define INVERT_REQ                       0x1BF1FFFF  // Посылка к плате с запросом данных или командой
#define INVERT_ANS                       0x1BF2FFFF  // Посылка из платы в ответ на запрос

// Идентификатором INVERT_REQ вызываются следующие команды (передаются в байте 0 блока данных)
#define START_MOVING                     0x01 // Начало движения
                                              // В байте  1 - направление (вниз - 1, вверх - 0)
                                              // В байтах 2 -  целевая частота вращения (Гц)
                                              // В байтах 3 -  время ускорения (в десятых долях секунды)

#define STOP_MOVING                      0x02 // Окончание движения
                                              // В байте  1 - время замедления (в десятых долях секунды)
#define EMERGENCY_STOP_MOVING            0x03 // Аварийная остановка


//******************************************************************************************************************************************************
//  Общие команды загрузчиков
//******************************************************************************************************************************************************

#define ALL_ENTER_TO_WRK_MOD              0x0001FFFF // Команда всем перейти в рабочий режим
#define ALL_PROLONG_BOOT_MODE             0x0002FFFF // Команда всем продлить загрузочный режим
#define ALL_ENTER_TO_BOOT_MOD             0x0003FFFF // Команда всем перейти в загрузочный режим

#define   BOOTL_GET_CRC           0x10  // Команда запроса контрольной суммы
#define   BOOTL_ACK_CRC           0x11  // Ответ на запрос контрольной суммы
#define   BOOTL_ACK_ERASE         0x12  // Ответ о завершении стрирания

#define   BOOTL_SET_BOOT_REC      0x20  // Команда с содержимым загрузочной записи
#define   BOOTL_ERASE_FLASH       0x21  // Команда стирания FLASH
#define   BOOTL_DO_PRG            0x30  // Команда выполнить программирование блока
#define   BOOTL_ACK_PRG           0x31  //


#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd_supp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd_supp.c$
* $Version : 3.8.28.0$
* $Date    : Aug-31-2012$
*
* Comments:
*
*   HTTPD support functions.
*
*END************************************************************************/

#include "httpd.h"
#include <string.h>

/** Send data to socket.
 * \param s < socket
 * \param buf < pointer to data buffer
 * \param len < data length
 * \return length of sent data
 */
static _mqx_int httpd_send(int s, char *buf, int len) {
    int res;

    HTTPD_DEBUG(4, "httpd_send buf:%p len:%d", buf, len);

#if RTCS_MINIMUM_FOOTPRINT
    // for better performance on small ram devices, split data to teo separate packets
    if (len > 2) {
        res = send(s, buf, len / 2, 0);
        
        if (res != RTCS_ERROR)
            res += send(s, buf + res, len - res, 0);
    }
    else
#endif
        res = send(s, buf, len, 0);

    HTTPD_DEBUG(4, "result:%d\n", res);

    return res;
}

_mqx_int httpd_sendstr(_mqx_int s, char *str) {
    return httpd_send(s, str, strlen(str));
}

/** Send extended data to socket.
 * \param s < socket
 * \param buf < pointer to data buffer
 * \param len < data length
 * \return length of sent data
 */
static _mqx_int httpd_sendext(_mqx_int s, char *buf, _mqx_int len) {
    (void)s;
    (void)buf;
    (void)len;

    return 0;
}

/**
 */
static _mqx_int httpd_call_fn(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session, char *fn_name) {
    HTTPD_FN_LINK_STRUCT *ptr = server->params->fn_lnk_tbl;

    if (ptr) {
        while (*(ptr->callback)) {
            if (0 == strcmp(fn_name, ptr->fn_name)) {
                ptr->callback(session);
                break;
            }

            ptr++;
        }
    }

    return 0;
}

_mqx_int httpd_cgi(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session, char *cgi_name) {
    HTTPD_CGI_LINK_STRUCT *ptr = server->params->cgi_lnk_tbl;
    int res = -1;

    if (ptr) {
        while (*(ptr->callback)) {
            if (0 == strcmp(cgi_name, ptr->cgi_name)) {
                res = ptr->callback(session);
                break;
            }

            ptr++;
        }
    }

    return res;
}

/** Send extended string to socket.
 * \param s < socket
 * \param str < pointer to string
 * \return length of sent data
 */
static _mqx_int httpd_sendextstr(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session, char *str) {
    char *src;
    int len, res;
    char fname[HTTPDCFG_MAX_SCRIPT_LN + 1];

    HTTPD_ASSERT(server && session && str);

    fname[0] = 0;

    if (!session->response.data)
    {
        session->response.data = str;
    }

    src = session->response.data;

    if (session->response.script_token)
    {
        // script token found
        len = (int)strcspn(src, " ;%<>\r\n\t");

        if (len > 1 && len < HTTPDCFG_MAX_SCRIPT_LN)
        {
            strncpy(fname, src, (unsigned long)len);
            fname[len] = 0;

            // call fn
            HTTPD_DEBUG(2, "script ln: %s\r\n", fname);

            httpd_call_fn(server, session, fname);
        }

        if (src[len] == '%' && src[len + 1] == '>')
        {
            session->response.script_token = 0;
            len += 1;
        }

        len++;

        session->response.data = src + len;
    }
    else
    {
        for (len = 0; *src && len < HTTPDCFG_MAX_BYTES_TO_SEND; src++, len++)
        {
            if (*src == '<' && *(src + 1) == '%')
            {
                session->response.script_token = 1;
                src += 2;

                break;
            }
        }

        res = httpd_send(session->sock, session->response.data, len);

        if (res < 0) {
            session->response.script_token = 0;
            res = errno;

            if (res != EAGAIN)
                len = 0;
        }
        else {
            if (len == res) {
                session->response.data = src;
            }
            else {
                session->response.script_token = 0;
                session->response.data += res;
            }
        }
    }

    return len;
}

#if HTTPDCFG_POLL_MODE
static _mqx_int httpd_readch(HTTPD_SESSION_STRUCT *session, char *ch) {
    int res;
    
    HTTPD_ASSERT(session && ch);
    HTTPD_ASSERT(session->recv_used >= 0 && session->recv_used < HTTPDCFG_RECV_BUF_LEN);

    if (session->recv_used == 0) {
        HTTPD_DEBUG(5, "recv BEGIN\n");
        res = recv(session->sock, session->recv_buf, HTTPDCFG_RECV_BUF_LEN, 0);
        HTTPD_DEBUG(5, "recv END\n");

        if (res <= 0) {
            *ch = 0;
            return res;
        }
        
        session->recv_used = res;
        session->recv_buf[session->recv_used] = 0;
        session->recv_rd = session->recv_buf;
    }

    *ch = *session->recv_rd++;
    session->recv_used--;

    return 1;
}
#endif

_mqx_int httpd_readln(HTTPD_SESSION_STRUCT *session, char *buf, _mqx_int max_len) {
    int used = 0, ret;
    char *dst = buf;
    uint_32 err;

    HTTPD_ASSERT(session && dst);
    
    HTTPD_DEBUG(5, "readln session(%p) buf(%p) max_len(%d)\n", session, buf, max_len);

    while (used < max_len) {
#if HTTPDCFG_POLL_MODE
        ret = httpd_readch(session, dst);
#else
        ret = recv(session->sock, dst, 1, 0);
#endif

        if (ret <= 0) {
            err = RTCS_geterror(session->sock);
            *buf = 0;
            HTTPD_DEBUG(5, "readln used(%d) ret(%d) err(0x%x)\n", used, ret, err);
            return ret;
        }

        dst++;
        used++;

        if (*(dst - 1) == '\n') {
            break;
        }
    }

    *dst = 0;
    
    HTTPD_DEBUG(5, "readln len(%d)\n", used);
    return used;
}

_mqx_int httpd_read(HTTPD_SESSION_STRUCT *session, char *dst, _mqx_int len) {
    int cnt = 0;

#if HTTPDCFG_POLL_MODE        
    while (len--) {
        if (!httpd_readch(session, dst++))
            break;

        cnt++;
    };
#else
    cnt = recv(session->sock, dst, len, 0);
#endif    

    return cnt;
}

/** string table item
 */
typedef struct {
    int id;
    char *str;
} tbl_str_itm_t;

/**
 */
static const tbl_str_itm_t reason_phrase[] = {
        { 200,  "OK" },
        { 404,  "Not Found" },
        { 0,    "" }
};

/** content type
 */
static const tbl_str_itm_t content_type[] = {
        { CONTENT_TYPE_PLAIN, "text/plain" },
        { CONTENT_TYPE_HTML, "text/html" },
        { CONTENT_TYPE_CSS, "text/css" },
        { CONTENT_TYPE_GIF, "image/gif" },
        { CONTENT_TYPE_JPG, "image/jpeg" },
        { CONTENT_TYPE_PNG, "image/png" },
        { CONTENT_TYPE_JS, "application/javascript"},
        { CONTENT_TYPE_OCTETSTREAM, "application/octet-stream" },
        { 0,    0 }
};

/** Get string from table by id
 * \param tbl < pointer to string table
 * \param id < string id
 */
static char* get_tbl_string(tbl_str_itm_t *tbl, const _mqx_int id) {
    tbl_str_itm_t *ptr = tbl;

    while (ptr->str) {
        if (id == ptr->id)
            break;

        ptr++;
    }

    return ptr->str;
}

void httpd_sendhdr(HTTPD_SESSION_STRUCT *session, _mqx_int content_len, _mqx_int mod_time) {
    char tmpBuf[100];

    HTTPD_ASSERT(session);

    if (session->response.hdrsent)
        return;

    sprintf(tmpBuf, "HTTP/1.0 %d %s\n",
            session->response.statuscode,
            get_tbl_string((tbl_str_itm_t*)reason_phrase, session->response.statuscode));
    httpd_sendstr(session->sock, tmpBuf);
    httpd_sendstr(session->sock, session->response.header);

    if (session->keep_alive) {
        httpd_sendstr(session->sock, "Connection: Keep-Alive\n");
    }
    else {
        httpd_sendstr(session->sock, "Connection: close\n");
    }

    sprintf(tmpBuf, "Content-Type: %s\n", get_tbl_string((tbl_str_itm_t*)content_type, session->response.contenttype));
    httpd_sendstr(session->sock, tmpBuf);

    //only non zero length cause to send Content-Length header field
    if (0 < content_len) {
        sprintf(tmpBuf, "Content-Length: %d\n", content_len);
        httpd_sendstr(session->sock, tmpBuf);
    }

    httpd_sendstr(session->sock, "\n");

    session->response.hdrsent = 1;

    HTTPD_DEBUG(4, "httpd_sendhdr\n");
}

void httpd_sendfile(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    char *ext;
    int expand = 0;
    int len;
    char buf[HTTPDCFG_MAX_BYTES_TO_SEND + 1];

    HTTPD_ASSERT(server && session);

    HTTPD_DEBUG(3, "httpd_sendfile(%p) %s\n", session, session->request.path);

    ext = strrchr(session->request.path, 46);
    if (ext) {
        if (0 == strcasecmp(ext, ".htm") || 0 == strcasecmp(ext, ".html")) {
            session->response.contenttype = CONTENT_TYPE_HTML;
            expand = 1;
        }
        else if (0 == strcasecmp(ext, ".gif"))
            session->response.contenttype = CONTENT_TYPE_GIF;
        else if (0 == strcasecmp(ext, ".jpg"))
            session->response.contenttype = CONTENT_TYPE_JPG;
        else if (0 == strcasecmp(ext, ".png"))
            session->response.contenttype = CONTENT_TYPE_PNG;
        else if (0 == strcasecmp(ext, ".css"))
            session->response.contenttype = CONTENT_TYPE_CSS;
        else if (0 == strcasecmp(ext, ".js"))
            session->response.contenttype = CONTENT_TYPE_JS;
        else
            session->response.contenttype = CONTENT_TYPE_OCTETSTREAM;
    }

    if (expand) {
        //if there will be any expansion there's no way how to calculate correct length
        //zero length prevents sending Content-Length header field
        httpd_sendhdr(session, 0, 0);
    } else {
        httpd_sendhdr(session, session->response.file->SIZE, 0);
    }

    if (expand) {
        session->response.data = buf;
        len = read(session->response.file, session->response.data, HTTPDCFG_MAX_BYTES_TO_SEND);

        if (len > 0) {
            buf[len] = 0;
			len = httpd_sendextstr(server, session, session->response.data);
            if (!len) {
                session->state = HTTPD_SES_END_REQ;
            }
            else {
                session->response.len += len;
                fseek(session->response.file, session->response.len, SEEK_SET);
            }
        }
        else
            session->state = HTTPD_SES_END_REQ;
    }
    else {
        session->response.data = buf;
        fseek(session->response.file, session->response.len, SEEK_SET);
        len = read(session->response.file, session->response.data, HTTPDCFG_MAX_BYTES_TO_SEND);
        
        HTTPD_DEBUG(4, "httpd_sendfile READ END %d\n", len);
        
        if (len > 0) {
            buf[len] = 0;

            len = httpd_send(session->sock, session->response.data, len);

            if (len < 0) {
                if (errno != EAGAIN)
                    session->state = HTTPD_SES_END_REQ;
            }
            else {
                session->response.len += len;
            }
        }
        else
            session->state = HTTPD_SES_END_REQ;
    }
    HTTPD_DEBUG(4, "httpd_sendfile END %s \n", session->request.path);
}

void httpd_send401(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session)
{
    HTTPD_DEBUG(3, "http_send401\n");

    session->response.file = fopen(server->params->page401, "r");
    session->response.len = 0;

    if (session->response.file) {
        httpd_sendfile(server, session);
    }
    else {
        httpd_sendhdr(session, 0, 0);
        httpd_sendstr(session->sock, "<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>\n");
        httpd_sendstr(session->sock, "<BODY><H1>Unauthorized!</H1>\n");
        httpd_sendstr(session->sock, "</BODY></HTML>\n");
    }
}

void httpd_send403(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    HTTPD_DEBUG(3, "http_send403\n");

    session->response.file = fopen(server->params->page403, "r");
    session->response.len = 0;

    if (session->response.file) {
        httpd_sendfile(server, session);
    }
    else {
        httpd_sendhdr(session, 0, 0);
        httpd_sendstr(session->sock, "<HTML><HEAD><TITLE>403 Forbidden</TITLE></HEAD>\n");
        httpd_sendstr(session->sock, "<BODY><H1>Forbidden!</H1>\n");
        httpd_sendstr(session->sock, "</BODY></HTML>\n");
    }
}

void httpd_send404(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    HTTPD_DEBUG(3, "http_send404\n");

    session->response.file = fopen(server->params->page404, "r");
    session->response.len = 0;

    if (session->response.file) {
        httpd_sendfile(server, session);
    }
    else {
        httpd_sendhdr(session, 0, 0);
        httpd_sendstr(session->sock, "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\n");
        httpd_sendstr(session->sock, "<BODY><H1>The request URL was not found!</H1>\n");
        httpd_sendstr(session->sock, "</BODY></HTML>\n");
    }
}

/** base64 decoding alphabet
 */
static const char decode_base64[] = "n###odefghijklm#######0123456789:;<=>?@ABCDEFGHI######JKLMNOPQRSTUVWXYZ[\\]^_`abc";

#define DECODE_BASE64_IDX(ch)       (decode_base64[ch - 43] - '0')

/** Decode base64 single block (4 char string).
 * \param in < 4 char input buffer
 * \param out < 3 char output buffer
 */
static void httpd_decode_b64_block(char in[4], char out[3]) {
    out[0] = (unsigned char)(in[0] << 2 | in[1] >> 4);
    out[1] = (unsigned char)(in[1] << 4 | in[2] >> 2);
    out[2] = (unsigned char)(((in[2] << 6) & 0xc0) | in[3]);
}


_mqx_int httpd_decode_base64(char *dst, char *src, _mqx_int dst_size) {
    char in[4];
    int i, len, free = dst_size;

    while (*src && free) {
        for (i = 0, len = 0; i < 4; i++) {
            if (*src) {
                if (!(*src < 43 || *src > 122) && *src != '=') {
                    len++;
                    in[i] = (unsigned char)DECODE_BASE64_IDX(*src);
                }
                else
                    in[i] = 0;

                src++;
            }
            else {
                in[i] = 0;
            }
        }

        if (len > 1 && free > len - 1) {
            httpd_decode_b64_block(in, dst);
            dst += len - 1;
            *dst = 0;
            free -= (len - 1);
        }
        else
            break;
    }

    return 0;
}

_mqx_int httpd_get_varval(HTTPD_SESSION_STRUCT *session, char *var_str, char *var_name, char *var_val, _mqx_int var_val_len) {
    char *var = var_str;    //session->request.urldata;
    int res = 0;
    int idx;

    HTTPD_ASSERT(session && var_str && var_name && var_val);

    var_val[0] = 0;

    while ((var = strstr(var, var_name)) != 0) {
        if (*(var + strlen(var_name)) == '=') {
            var += strlen(var_name) + 1;    // +1 bacause '='

            idx = (int)strcspn(var, "&");
            strncpy(var_val, var, (unsigned long)idx);
            var_val[idx] = 0;
            res = 1;
            break;
        }
        else {
            var = strchr(var, '&');
        }
    }

    return res;
}


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_open.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_open.c$
* $Version : 3.8.13.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the file specific interface functions
*   of the MFS.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Open_file
* Returned Value   : A pointer to an MFS_HANDLE
* Comments  :   Open a an existing file.
*
*END*---------------------------------------------------------------------*/

pointer  MFS_Open_file
    (
    MQX_FILE_PTR            mfs_fd_ptr,     /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    char_ptr                pathname,       /*[IN] directory and filename of the file to be opened */
    uchar                   access,         /*[IN] type of access required: read, write or read/write*/
    uint_32_ptr             error_ptr   /*[IN/OUT] error code is written to this address */   
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    MFS_HANDLE_PTR          handle,open_handle;
    uint_32                 dir_cluster, dir_index;
    _mfs_error              error_code;
    uint_32                 prev_cluster= CLUSTER_INVALID; 

    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        if ( error_ptr != NULL )
        {
            *error_ptr = MFS_INVALID_PARAMETER;
        }
        return NULL;
    }

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        if ( error_ptr != NULL )
        {
            *error_ptr = error_code;
        }
        return NULL;
    }

    handle = NULL;

    dir_entry_ptr = MFS_Find_entry_on_disk(drive_ptr, pathname, &error_code, &dir_cluster, &dir_index, &prev_cluster);  

    if ( error_code == MFS_NO_ERROR )
    {

        if ( dtohc(dir_entry_ptr->ATTRIBUTE) & (MFS_ATTR_DIR_NAME | MFS_ATTR_VOLUME_NAME) )
        {
            error_code = MFS_WRITE_FAULT;
        }
        else if ( (dtohc(dir_entry_ptr->ATTRIBUTE) & MFS_ATTR_READ_ONLY) && ((access == MFS_ACCESS_WRITE_ONLY) || (access == MFS_ACCESS_READ_WRITE)) )
        {
            error_code = MFS_ACCESS_DENIED;
        }
        else
        {
            // Check to see if the file is already opened
            open_handle = MFS_Find_handle(drive_ptr, dir_cluster, dir_index);
            
            if (open_handle) {
                // If we are opening to write, the file can't already be opened.
                if ((access == MFS_ACCESS_WRITE_ONLY) || (access == MFS_ACCESS_READ_WRITE)) {
                    error_code = MFS_SHARING_VIOLATION;
                }

                // And if we the file is already opened, it can't be opened to write.
                // Note that if it is opened for write, it will be the only instance on the list
                if ((handle->ACCESS == MFS_ACCESS_WRITE_ONLY) || (handle->ACCESS == MFS_ACCESS_READ_WRITE)) {
                    error_code = MFS_SHARING_VIOLATION;
                }
            }
        
            if (error_code == MFS_NO_ERROR) {
                handle = MFS_Get_handle(drive_ptr,dir_entry_ptr);
                if ( handle != NULL )
                {
                    handle->ACCESS = access;
                    handle->CURRENT_CLUSTER = 0;
                    handle->PREVIOUS_CLUSTER = 0;
                    handle->DIR_CLUSTER = dir_cluster;
                    handle->DIR_INDEX = dir_index;
                }
                else
                {
                    error_code = MFS_INSUFFICIENT_MEMORY;
                }  
            }
        }  
    }

    MFS_unlock(drive_ptr,FALSE);

    if ( error_ptr )
    {
        *error_ptr = error_code;
    }

    return((pointer) handle);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Close_file
* Returned Value   : error code
* Comments  :   Close an existing file.
*
*END*---------------------------------------------------------------------*/

int_32  MFS_Close_file
    (
    MQX_FILE_PTR            fd_ptr  /*[IN] file that is to be closed */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_HANDLE_PTR          handle;
    TIME_STRUCT             time;
    DATE_STRUCT             clk_time;
    _mfs_error              error_code;

    error_code = MFS_lock_handle( fd_ptr, &drive_ptr, &handle );
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }

#if !MFSCFG_READ_ONLY
#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        error_code = MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif    
    if ((handle->TOUCHED) && (error_code == MFS_NO_ERROR))
    {
        _time_get(&time);
        _time_to_date(&time, &clk_time);
        NORMALIZE_DATE(&clk_time);
        htods(handle->DIR_ENTRY.TIME, PACK_TIME(clk_time));
        htods(handle->DIR_ENTRY.DATE, PACK_DATE(clk_time));
        error_code = MFS_Update_entry(drive_ptr, handle);
    }
#endif

    MFS_Free_handle(drive_ptr, handle);
    MFS_unlock(drive_ptr,TRUE);

    return(int_32) error_code;
}  



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Move_file_pointer
* Returned Value   : current file pointer position
* Comments  :   Move the current file pointer position.
*               If filelength = 0, it returns MFS_EOF
*END*---------------------------------------------------------------------*/

uint_32 MFS_Move_file_pointer
    (
    MQX_FILE_PTR            fd_ptr,         /*[IN] file handle upon which the action is to be taken */
    _mfs_error_ptr             error_ptr    /*[IN/OUT] resulting error code is written to this address*/
    )
{

    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_HANDLE_PTR          handle;
    uint_32                 position_after_seek, position_before_seek;
    uint_32                 current_cluster,
                            previous_cluster,
                            first_cluster,
                            skip_clusters,
                            k;
    _mfs_error              error_code;


    error_code = MFS_lock_handle( fd_ptr, &drive_ptr, &handle );
    if ( error_code != MFS_NO_ERROR )
    {
        if ( error_ptr != NULL )
        {
            *error_ptr = error_code;
        }
        return 0;
    }

    position_after_seek = fd_ptr->LOCATION;

    MFS_LOG(printf("seek to %d\n",position_after_seek));

    /*
    ** Cannot move ahead of the beginning of the file; force beginning.
    */
    if ( error_code == MFS_NO_ERROR )
    {

        /*
        ** There are four cases
        **
        ** 1) Seeking to beginning of file (position_after_seek=0, cluster=0)
        ** 2) No change in position (position_after_seek==position_before_seek)
        ** 2) Seeking ahead of current file pointer
        ** 3) Seeking behind current file pointer
        */
        /*
        ** Cannot move beyond the end of file !
        */
        if ( position_after_seek> dtohl(handle->DIR_ENTRY.FILE_SIZE) )     // + 1
        {
            position_after_seek = dtohl(handle->DIR_ENTRY.FILE_SIZE);  //  - 1
            error_code = MFS_EOF;
        }

        current_cluster = 0;
        previous_cluster = 0;
        first_cluster = clustoh(handle->DIR_ENTRY.HFIRST_CLUSTER, handle->DIR_ENTRY.LFIRST_CLUSTER);
        MFS_LOG(printf("first_cluster =  %d\n",first_cluster));

        /*
        ** Set the current_cluster correctly.
        ** If we're moving ahead, don't start from the beginning.
        */
        position_before_seek = CLUSTER_BOUNDARY(((MFS_HANDLE_PTR) fd_ptr->DEV_DATA_PTR)->SAVED_POSITION);

        if ( handle->CURRENT_CLUSTER==0 )
        {
            handle->CURRENT_CLUSTER = first_cluster;
            handle->PREVIOUS_CLUSTER = 0;
            position_before_seek = 0;
        }

        if ( position_after_seek == 0 )
        {
            current_cluster = first_cluster;
            previous_cluster = 0;
        }
        else if ( position_after_seek == position_before_seek )
        {
            current_cluster  = handle->CURRENT_CLUSTER;
            previous_cluster = handle->PREVIOUS_CLUSTER;
        }
        else
        {
            if ( position_after_seek < position_before_seek )
            {
                position_before_seek = 0;
                current_cluster = first_cluster;
                previous_cluster = 0;
            }
            else
            {
                current_cluster  = handle->CURRENT_CLUSTER;
                previous_cluster = handle->PREVIOUS_CLUSTER;
            }  

            MFS_LOG(printf("current cluster =  %d\n",current_cluster));

            if ( current_cluster && (current_cluster!=CLUSTER_EOF) )
            {
                /*
                ** How many clusters do we need to skip?
                */
                skip_clusters = (position_after_seek - position_before_seek) >> drive_ptr->CLUSTER_POWER_BYTES;
                for ( k = 0; k < skip_clusters; k++ )
                {
                    previous_cluster = current_cluster;

                    error_code = MFS_get_cluster_from_fat(drive_ptr, previous_cluster, &current_cluster);
                    if ( error_code != MFS_NO_ERROR )
                    {
                        break;
                    }
                    if ( current_cluster==CLUSTER_EOF )
                    {
                        error_code = MFS_EOF;
                        break;
                    }
                    else if ( (current_cluster < CLUSTER_MIN_GOOD) || (current_cluster > drive_ptr->LAST_CLUSTER) )
                    {
                        error_code = MFS_BAD_DISK_UNIT;
                        break;
                    }
                    MFS_LOG(printf("skip, current cluster =  %d\n",current_cluster));
                }  
            }
            else
            {
                error_code = MFS_EOF;
            }
        }  

        if ( (error_code == MFS_NO_ERROR) || (error_code == MFS_EOF) )
        {
            ((MFS_HANDLE_PTR) fd_ptr->DEV_DATA_PTR)->SAVED_POSITION = position_after_seek;

            handle->PREVIOUS_CLUSTER  = previous_cluster;
            handle->CURRENT_CLUSTER   = current_cluster;
        }
    }
    MFS_unlock(drive_ptr,FALSE);

    if ( error_ptr )
    {
        *error_ptr = error_code;
    }

    return(fd_ptr->LOCATION);
}


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GDFLIB/GDFLIB_FilterMA.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GDFLIB_FilterMA.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GDFLIB_FilterMA function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GDFLIB_FILTER_MA_H
#define _GDFLIB_FILTER_MA_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif
     
/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GDFLIB_FilterMAInitANSIC function.*/
#define GDFLIB_FilterMAInit(pParam)\
        GDFLIB_FilterMAInitANSIC(pParam)

/*! Function alias for the #GDFLIB_FilterMAANSIC function.*/
#define GDFLIB_FilterMA(f32In, pParam)\
        GDFLIB_FilterMAANSIC(f32In, pParam)

/*! Macro containing default values of the first order MA filter structure.*/
#define GDFLIB_FILTER_MA_DEFAULT   {0,0}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct GDFLIB_FILTER_MA_T "\GDFLIB_FilterMA.h"

@brief  Structure containing filter buffer and coefficients.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32 f32Acc;             /*!< filter accumulator */
    UWord16    u16NSamples;        /*!< number of samples for averaging, filter sample window [0,31]*/
}GDFLIB_FILTER_MA_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
// Prototype of function for clearing buffers of IIR1 filter.
extern void GDFLIB_FilterMAInitANSIC(GDFLIB_FILTER_MA_T *pParam);

// Prototype of direct form II first order IIR filter.
extern Frac32 GDFLIB_FilterMAANSIC(Frac32 f32In, \
                                    GDFLIB_FILTER_MA_T *pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GDFLIB_FILTER_IIR1_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi/spi.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi.h$
* $Version : 3.8.1.0$
* $Date    : Sep-25-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the SPI driver
*
*END************************************************************************/


#ifndef __spi_h__
#define __spi_h__


/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/*
** IOCTL calls specific to SPI
*/
#define IO_IOCTL_SPI_GET_BAUD              _IO(IO_TYPE_SPI,0x01)
#define IO_IOCTL_SPI_SET_BAUD              _IO(IO_TYPE_SPI,0x02)
#define IO_IOCTL_SPI_GET_MODE              _IO(IO_TYPE_SPI,0x03)
#define IO_IOCTL_SPI_SET_MODE              _IO(IO_TYPE_SPI,0x04)
#define IO_IOCTL_SPI_GET_DUMMY_PATTERN     _IO(IO_TYPE_SPI,0x05)
#define IO_IOCTL_SPI_SET_DUMMY_PATTERN     _IO(IO_TYPE_SPI,0x06)
#define IO_IOCTL_SPI_GET_TRANSFER_MODE     _IO(IO_TYPE_SPI,0x07)
#define IO_IOCTL_SPI_SET_TRANSFER_MODE     _IO(IO_TYPE_SPI,0x08)
#define IO_IOCTL_SPI_GET_ENDIAN            _IO(IO_TYPE_SPI,0x09)
#define IO_IOCTL_SPI_SET_ENDIAN            _IO(IO_TYPE_SPI,0x0A)
#define IO_IOCTL_SPI_DEVICE_ENABLE         _IO(IO_TYPE_SPI,0x0B)
#define IO_IOCTL_SPI_DEVICE_DISABLE        _IO(IO_TYPE_SPI,0x0C)
#define IO_IOCTL_SPI_GET_FLAGS             _IO(IO_TYPE_SPI,0x0D)
#define IO_IOCTL_SPI_SET_FLAGS             _IO(IO_TYPE_SPI,0x0E)
#define IO_IOCTL_SPI_GET_STATS             _IO(IO_TYPE_SPI,0x0F)
#define IO_IOCTL_SPI_CLEAR_STATS           _IO(IO_TYPE_SPI,0x10)
#define IO_IOCTL_SPI_GET_FRAMESIZE         _IO(IO_TYPE_SPI,0x11)
#define IO_IOCTL_SPI_SET_FRAMESIZE         _IO(IO_TYPE_SPI,0x12)
#define IO_IOCTL_SPI_GET_CS                _IO(IO_TYPE_SPI,0x13)
#define IO_IOCTL_SPI_SET_CS                _IO(IO_TYPE_SPI,0x14)
#define IO_IOCTL_SPI_SET_CS_CALLBACK       _IO(IO_TYPE_SPI,0x15)
#define IO_IOCTL_SPI_READ_WRITE            _IO(IO_TYPE_SPI,0x16)
#define IO_IOCTL_SPI_FLUSH_DEASSERT_CS     _IO(IO_TYPE_SPI,0x17)


/*
** SPI clock polarity and phase (IO_IOCTL_SPI_XXX_MODE)
*/
#define SPI_CPHA_MASK                      (0x01)
#define SPI_CPOL_MASK                      (0x02)

#define SPI_CLK_POL_PHA_MODE0              (0x00)                            /* Inactive SPICLK low, sample on leading edge */
#define SPI_CLK_POL_PHA_MODE1              (SPI_CPHA_MASK)                   /* Inactive SPICLK low, sample on trailing edge */
#define SPI_CLK_POL_PHA_MODE2              (SPI_CPOL_MASK)                   /* Inactive SPICLK high, sample on leading edge */
#define SPI_CLK_POL_PHA_MODE3              (SPI_CPOL_MASK | SPI_CPHA_MASK)   /* Inactive SPICLK high, sample on trailing edge */
#define SPI_CLK_POL_PHA_MODE_MASK          (SPI_CPOL_MASK | SPI_CPHA_MASK)


/*
** SPI device modes of operation (IO_IOCTL_SPI_XXX_TRANSFER_MODE)
*/
#define SPI_DEVICE_MASTER_MODE             (0x00)
#define SPI_DEVICE_SLAVE_MODE              (0x01)


/*
** SPI data bits transferring format (IO_IOCTL_SPI_XXX_ENDIAN)
*/
#define SPI_DEVICE_BIG_ENDIAN              (0x0001)
#define SPI_DEVICE_LITTLE_ENDIAN           (0x8000)


/*
** SPI Open Flags
*/
#define SPI_FLAG_HALF_DUPLEX               (0 << IO_O_USER_SHIFT)
#define SPI_FLAG_FULL_DUPLEX               (1 << IO_O_USER_SHIFT)
#define SPI_FLAG_NO_DEASSERT_ON_FLUSH      (2 << IO_O_USER_SHIFT)


/*
** SPI Transfer Attributes
** Public so that it can be used in default parameters in init structures,
** otherwise there is no API to directly manipulate attibutes using these masks, use individual IOCTLs instead.
*/
#define SPI_ATTR_ENDIAN_MASK               0x01UL
#define SPI_ATTR_LITTLE_ENDIAN             SPI_ATTR_ENDIAN_MASK
#define SPI_ATTR_BIG_ENDIAN                0

#define SPI_ATTR_TRANSFER_MODE_MASK        0x02UL
#define SPI_ATTR_SLAVE_MODE                SPI_ATTR_TRANSFER_MODE_MASK
#define SPI_ATTR_MASTER_MODE               0


/* SPI Error Codes */
#define SPI_OK                             (0x00)
#define SPI_ERROR_MODE_INVALID             (SPI_ERROR_BASE | 0x01)
#define SPI_ERROR_TRANSFER_MODE_INVALID    (SPI_ERROR_BASE | 0x02)
#define SPI_ERROR_BAUD_RATE_INVALID        (SPI_ERROR_BASE | 0x03)
#define SPI_ERROR_ENDIAN_INVALID           (SPI_ERROR_BASE | 0x04)
#define SPI_ERROR_CHANNEL_INVALID          (SPI_ERROR_BASE | 0x05)
#define SPI_ERROR_DEINIT_FAILED            (SPI_ERROR_BASE | 0x06)
#define SPI_ERROR_INVALID_PARAMETER        (SPI_ERROR_BASE | 0x07)
#define SPI_ERROR_FRAMESIZE_INVALID        (SPI_ERROR_BASE | 0x08)


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/


/*
** SPI_PARAM_STRUCT
**
** This structure defines parameters of SPI bus transfer.
** The structure is stored in init data and file cotext of upper layer driver and passed to lower layer SPI driver.
*/
typedef struct spi_param_struct
{
    /* Baud rate to use */
    uint_32 BAUDRATE;

    /* The SPI clock phase and polarity mode */
    uint_32 MODE;

    /* Size of single SPI frame */
    uint_32 FRAMESIZE;

    /* CS signal(s) to activate for the transfer */
    uint_32 CS;

    /* Additional attributes for the transfer */
    uint_32 ATTR;

    /* Pattern to transmit during half-duplex rx transfer */
    uint_32 DUMMY_PATTERN;

} SPI_PARAM_STRUCT, _PTR_ SPI_PARAM_STRUCT_PTR;


/*
** Functions implemented by lower layer SPI driver (device interface).
*/
typedef _mqx_int (_CODE_PTR_ SPI_DEVIF_INIT_FPTR)(const void _PTR_ init_data_ptr, pointer *io_info_ptr_ptr);
typedef _mqx_int (_CODE_PTR_ SPI_DEVIF_DEINIT_FPTR)(pointer io_info_ptr);
typedef _mqx_int (_CODE_PTR_ SPI_DEVIF_SETPARAM_FPTR)(pointer io_info_ptr, SPI_PARAM_STRUCT_PTR spi_param_ptr);
typedef _mqx_int (_CODE_PTR_ SPI_DEVIF_TX_RX_FPTR)(pointer io_info_ptr, uint_8_ptr txbuf, uint_8_ptr rxbuf, uint_32 len);
typedef _mqx_int (_CODE_PTR_ SPI_DEVIF_CS_DEASSERT_FPTR)(pointer io_info_ptr);
typedef _mqx_int (_CODE_PTR_ SPI_DEVIF_IOCTL_FPTR)(pointer io_info_ptr, SPI_PARAM_STRUCT_PTR spi_param_ptr, uint_32 cmd, uint_32_ptr cmd_param_ptr);


typedef struct spi_devif_struct
{
    /* Initialization if low level SPI driver */
    SPI_DEVIF_INIT_FPTR     INIT;

    /* Deinitialization of low level SPI driver */
    SPI_DEVIF_DEINIT_FPTR   DEINIT;

    /* Sets up the SPI bus accorting to given parameters */
    SPI_DEVIF_SETPARAM_FPTR SETPARAM;

    /* Data trasfer function */
    SPI_DEVIF_TX_RX_FPTR    TX_RX;

    /* Immediate deassertion of CS signals, if handled by low level driver */
    SPI_DEVIF_CS_DEASSERT_FPTR CS_DEASSERT;

    /* IOCTL commands not fully handled by upper layer are passed to this function */
    SPI_DEVIF_IOCTL_FPTR    IOCTL;

} SPI_DEVIF_STRUCT, _PTR_ SPI_DEVIF_STRUCT_PTR;

typedef const SPI_DEVIF_STRUCT _PTR_ SPI_DEVIF_STRUCT_CPTR;


/*
** SPI_CS_CALLBACK
**
** This callback function is used to provide external CS handling funtionality.
*/
typedef _mqx_int (_CODE_PTR_ SPI_CS_CALLBACK)(uint_32 cs, pointer context_data);


/*
** SPI_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a spi port is initialized.
*/
typedef struct spi_init_struct
{
    /* Pointer to low level driver */
    SPI_DEVIF_STRUCT_CPTR DEVIF;

    /* Pointer to init data specific for low level driver */
    const void _PTR_      DEVIF_INIT;

    /* Default transfer parameters for low level driver */
    SPI_PARAM_STRUCT      PARAMS;

    /* Default callback function for external CS handling */
    SPI_CS_CALLBACK       CS_CALLBACK;

    /* Default context for CS callback function */
    pointer               CS_USERDATA;

} SPI_INIT_STRUCT, _PTR_ SPI_INIT_STRUCT_PTR;

typedef const SPI_INIT_STRUCT _PTR_ SPI_INIT_STRUCT_CPTR;


/*
** SPI_STATISTICS_STRUCT
**
** This is used to get statistics data from SPI device using IO_IOCTL_SPI_GET_STATS.
*/
typedef struct spi_statistics_struct
{
   /* Number of valid frames received (not dummy receives) */
   uint_32          RX_PACKETS;

   /* Number of valid frames transmitted (not dummy transmits) */
   uint_32          TX_PACKETS;

} SPI_STATISTICS_STRUCT, _PTR_ SPI_STATISTICS_STRUCT_PTR;


/*
** SPI_CS_CALLBACK_STRUCT
**
** This structure defines the parameters of the external chip select callback
** when passed to IO_IOCTL_SPI_SET_CS_CALLBACK.
*/

typedef struct spi_cs_callback_struct
{
   /* The SPI callback itself */
   SPI_CS_CALLBACK  CALLBACK;

   /* User data */
   pointer          USERDATA;

} SPI_CS_CALLBACK_STRUCT, _PTR_ SPI_CS_CALLBACK_STRUCT_PTR;


/*
** SPI_READ_WRITE_STRUCT
**
** Structure passed to IOCTL TX/RX command (IO_IOCTL_SPI_READ_WRITE) for true duplex operation.
*/

typedef struct spi_read_write_struct
{
   /* Byte length of each buffer */
   uint_32          BUFFER_LENGTH;

   /* Buffer containing bytes to write */
   char_ptr         WRITE_BUFFER;

   /* Buffer containing bytes read after transfer */
   char_ptr         READ_BUFFER;

} SPI_READ_WRITE_STRUCT, _PTR_ SPI_READ_WRITE_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif


extern _mqx_int _io_spi_install(char_ptr identifier, SPI_INIT_STRUCT_CPTR init_data_ptr);


#ifdef __cplusplus
}
#endif


#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ifadd.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifadd.c$
* $Version : 3.8.9.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the interface functions to the
*   packet driver interface.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_add
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Register a hardware interface with RTCS.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_add
   (
      pointer                 mhandle,
         /* [IN] the packet driver handle */
      RTCS_IF_STRUCT_PTR      if_ptr,
         /* [IN] call table for the interface */
      _rtcs_if_handle _PTR_   handle
         /* [OUT] the RTCS interface state structure */
   )
{ /* Body */
   IPIF_PARM   parms;
   uint_32     error;

   if (mhandle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }
   
   parms.mhandle = mhandle;
   parms.if_ptr  = if_ptr;

   error = RTCSCMD_issue(parms, IPIF_add);

   if (!error) {
      *handle = parms.ihandle;
   } /* Endif */
   return error;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_bind
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Bind an IP address to a registered hardware interface.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_bind
   (
      _rtcs_if_handle   handle,
         /* [IN] the RTCS interface state structure */
      _ip_address       address,
         /* [IN] the IP address for the interface */
      _ip_address       netmask
         /* [IN] the IP (sub)network mask for the interface */
   )
{ /* Body */
   IPIF_PARM   parms;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }
   
   parms.ihandle = handle;
   parms.address = address;
   parms.locmask = 0xFFFFFFFFL;
   parms.netmask = netmask;
   parms.probe   = FALSE;

   return RTCSCMD_issue(parms, IPIF_bind);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_probe_and_bind
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Bind an IP address to a registered hardware interface.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_probe_and_bind
   (
      _rtcs_if_handle   handle,
         /* [IN] the RTCS interface state structure */
      _ip_address       address,
         /* [IN] the IP address for the interface */
      _ip_address       netmask
         /* [IN] the IP (sub)network mask for the interface */
   )
{ /* Body */
   IPIF_PARM   parms;
   uint_32     error;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }

   parms.ihandle = handle;
   parms.address = address;
   parms.locmask = 0xFFFFFFFFL;
   parms.netmask = netmask;
   parms.probe   = TRUE;
   error = RTCSCMD_issue(parms, IPIF_bind);
   
   if (RTCS_OK == error)
   {
       _time_delay (500);
       
       parms.ihandle = handle;
       parms.address = address;
       parms.locmask = 0xFFFFFFFFL;
       parms.netmask = netmask;
       parms.probe   = TRUE;
       error = RTCSCMD_issue(parms, IPIF_bind_finish);
   }

   return error;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_gate_add
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Register a gateway with RTCS.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_gate_add
   (
      _ip_address       gateway,
         /* [IN] the IP address of the gateway */
      _ip_address       network,
         /* [IN] the IP (sub)network to route */
      _ip_address       netmask
         /* [IN] the IP (sub)network mask to route */
   )
{ /* Body */
#if RTCSCFG_ENABLE_GATEWAYS
   IPIF_PARM   parms;

   parms.address = gateway;
   parms.network = network;
   parms.netmask = netmask;
   /* Start CR 1133 */
   parms.locmask = 0;
   /* End CR 1133 */

   return RTCSCMD_issue(parms, IPIF_gate_add);
#else
   return RTCSERR_FEATURE_NOT_ENABLED;
#endif
} /* Endbody */


/* Start CR 1133 */
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_gate_add_metric
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Register a gateway with RTCS.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_gate_add_metric
   (
      _ip_address       gateway,
         /* [IN] the IP address of the gateway */
      _ip_address       network,
         /* [IN] the IP (sub)network to route */
      _ip_address       netmask,
         /* [IN] the IP (sub)network mask to route */
      uint_16           metric
         /* [IN] the metric of the gateway */
   )
{ /* Body */
#if RTCSCFG_ENABLE_GATEWAYS
   IPIF_PARM   parms;

   parms.address = gateway;
   parms.network = network;
   parms.netmask = netmask;
   parms.locmask = metric;

   return RTCSCMD_issue(parms, IPIF_gate_add);
#else
   return RTCSERR_FEATURE_NOT_ENABLED;
#endif

} /* Endbody */
/* End CR 1133 */

#if RTCSCFG_ENABLE_IP6
/************************************************************************
* NAME: RTCS6_if_bind_addr
* RETURNS : RTCS_OK or error code
* DESCRIPTION: Bind an IPv6 address to a registered hardware interface.
*************************************************************************/
uint_32 RTCS6_if_bind_addr( _rtcs_if_handle   handle        /* [IN] the RTCS interface state structure */,
                            in6_addr  ip_addr               /* [IN] the IP address for the interface */,
                            ip6_if_addr_type ip_addr_type   /* Type.*/)
{
   IP6_IF_PARM   parms;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }
   
   parms.ihandle = handle;
   parms.ip_addr = ip_addr;
   parms.ip_addr_type = ip_addr_type;
   
   return RTCSCMD_issue(parms, IP6_IF_bind_addr);
}
#endif /* RTCSCFG_ENABLE_IP6 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/tftp.h<|end_filename|>
#ifndef __tftp_h__
#define __tftp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tftp.h$
* $Version : 3.8.12.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the definitions needed by TFTP.
*
*END************************************************************************/

/* Constants */

#define TFTPOP_RRQ     1
#define TFTPOP_WRQ     2
#define TFTPOP_DATA    3
#define TFTPOP_ACK     4
#define TFTPOP_ERROR   5

#define TFTPERR_UNKNOWN            0
#define TFTPERR_FILE_NOT_FOUND     1
#define TFTPERR_ACCESS_VIOLATION   2
#define TFTPERR_DISK_FULL          3
#define TFTPERR_ILLEGAL_OP         4
#define TFTPERR_ILLEGAL_TID        5
#define TFTPERR_FILE_EXISTS        6
#define TFTPERR_ILLEGAL_USER       7

#define TFTP_DATA_SIZE            512
#define TFTPSRV_MAX_TRANSACTIONS  20

#define TFTP_TIMEOUT_RETRIES    1        /* retransmit forever */
#define TFTP_TIMEOUT_MIN        5000     /* 5 seconds */
#define TFTP_TIMEOUT_MAX        60000    /* 1 minute */
#define TFTP_MAX_MESSAGE_SIZE   576
/*
** TFTP_MAX_MODE_SIZE is set to 9 because "netascii" is eight characters, plus
** one for the NUL, if TFTP ever allows other mode types with more characters,
** this value will have to be increased accordingly.
*/
#define TFTP_MAX_MODE_SIZE      9
#define TFTPSRV_INFINITE_RETRIES -1
/*
** This value can be set to TFTP_INFINITE_RETRIES if the end user wishes to
** never cancel a transaction. The default value when shipped is 20.
*/
#define TFTPSRV_TIMEOUT_RETRIES 20

/* TFTP Structure definitions */
typedef struct tftp_header {
   uchar       OP[2];
   uchar       BLOCK[2];
} TFTP_HEADER, _PTR_ TFTP_HEADER_PTR;

/* TFTP data packet */
typedef struct tftp_packet {
   TFTP_HEADER HEAD;
   uchar       DATA[TFTP_DATA_SIZE];
} TFTP_PACKET, _PTR_ TFTP_PACKET_PTR;

/* The Illegal TID error packet */
typedef struct tftp_error_packet {
   uchar       OP[2];
   uchar       CODE[2];
   uchar       MSG[25];
} TFTP_ERROR_PACKET, _PTR_ TFTP_ERROR_PACKET_PTR;

typedef struct tftp_to_struct {
   uint_32  TS;
   boolean  UPDATE;
   uint_32  TO;
   uint_32  M;
   uint_32  D;
} TFTP_TO_STRUCT, _PTR_ TFTP_TO_STRUCT_PTR;

typedef struct tftp_trans_struct {
   struct tftp_trans_struct _PTR_       NEXT;
   struct tftp_trans_struct _PTR_ _PTR_ PREV;
   uint_32                       TIME;
   uint_32                       SOCK;
   MQX_FILE_PTR                  TRANS_FILE_PTR;
   sockaddr_in                   ADDR;
   uint_32                       RECV_OP;
   uint_32                       SEND_OP;
   uint_32                       BLOCK;
   uint_32                       SEND_SIZE;
   TFTP_TO_STRUCT                XMIT_TIMER;
   uint_32                       NUM_RETRIES;
   boolean                       EXIT;
   TFTP_PACKET                   SND;
} TFTP_TRANS_STRUCT, _PTR_ TFTP_TRANS_STRUCT_PTR;

/* The state structure for the TFTP Server */
typedef struct tftpsrv_state_struct {
   /* DO NOT INSERT ANYTHING BETWEEN SRV_SOCK and SOCKETS! */
   uint_32                 SRV_SOCK;
   uint_32                 SOCKETS[TFTPSRV_MAX_TRANSACTIONS];
   TFTP_TRANS_STRUCT _PTR_ TRANS_PTRS[TFTPSRV_MAX_TRANSACTIONS];
   TFTP_TRANS_STRUCT _PTR_ EVENT_HEAD;
   uint_32                 NUM_TRANSACTIONS;
   uchar                   BUFFER[TFTP_MAX_MESSAGE_SIZE];
} TFTPSRV_STATE_STRUCT, _PTR_ TFTPSRV_STATE_STRUCT_PTR;

/* TFTP Macros */
#define TFTP_WAIT(t) RTCS_selectset(&TFTP_config.SOCK, 1, t)

#define TFTP_RECV(p) recvfrom(TFTP_config.SOCK, &(p), sizeof(p), 0, \
                              (sockaddr *)&remote_addr, &remote_size)

#define TFTP_SEND(s,p,a) sendto(s, &(p), sizeof(p), 0, (sockaddr *)&(a), sizeof(a))

#define TFTP_SENDRRQ() sendto(TFTP_config.SOCK, TFTP_config.RRQ_PTR, TFTP_config.RRQ_LEN, 0, \
                              (sockaddr *)(&TFTP_config.SADDR), sizeof(TFTP_config.SADDR))

#define TFTP_RESEND() TFTP_config.RRQ_PTR ? TFTP_SENDRRQ() : TFTP_SEND(TFTP_config.SOCK, TFTP_config.ACK, TFTP_config.SADDR)

extern TFTP_ERROR_PACKET _tftp_error_tid;
extern TFTP_ERROR_PACKET _tftp_error_op;
extern TFTP_ERROR_PACKET _tftp_error_accvio;
extern TFTP_ERROR_PACKET _tftp_error_srv;
extern TFTP_ERROR_PACKET _tftp_error_busy;
extern TFTP_ERROR_PACKET _tftp_error_to;
extern TFTP_ERROR_PACKET _tftp_error_nofile;
extern TFTP_ERROR_PACKET _tftp_error_exists;

extern void    TFTPSRV_service_request     (TFTPSRV_STATE_STRUCT_PTR);
extern void    TFTPSRV_service_transaction (TFTPSRV_STATE_STRUCT_PTR, TFTP_TRANS_STRUCT_PTR);
extern void    TFTPSRV_close_transaction   (TFTPSRV_STATE_STRUCT_PTR, TFTP_TRANS_STRUCT_PTR);
extern uint_32 TFTPSRV_service_timer       (TFTPSRV_STATE_STRUCT_PTR);

extern void TFTPSRV_build_ACK  (TFTP_TRANS_STRUCT_PTR);
extern void TFTPSRV_build_DATA (TFTP_TRANS_STRUCT_PTR);
extern void TFTPSRV_send       (TFTP_TRANS_STRUCT_PTR);

extern void TFTPSRV_timer_start  (TFTPSRV_STATE_STRUCT_PTR, TFTP_TRANS_STRUCT_PTR, uint_32);
extern void TFTPSRV_timer_cancel (TFTPSRV_STATE_STRUCT_PTR, TFTP_TRANS_STRUCT_PTR);

extern uint_32 TFTPSRV_open_device (uint_32, char_ptr, char_ptr, MQX_FILE_PTR _PTR_);

extern uint_32 TFTP_timeout_init    (TFTP_TO_STRUCT_PTR);
extern uint_32 TFTP_timeout_restart (TFTP_TO_STRUCT_PTR);
extern uint_32 TFTP_timeout_update  (TFTP_TO_STRUCT_PTR);
extern uint_32 TFTP_timeout_left    (TFTP_TO_STRUCT_PTR, boolean _PTR_);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/include/usb_hid.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_hid.h$
* $Version : 3.8.2.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
* @brief The file contains USB stack HID class layer api header function.
*
*****************************************************************************/

#ifndef _USB_HID_H
#define _USB_HID_H 1

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_class.h"

/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
#define HID_MAX_QUEUE_ELEMS  (4) 
 
 /* class specific requests */
#define USB_HID_GET_REPORT_REQUEST     (0x01)
#define USB_HID_GET_IDLE_REQUEST       (0x02)
#define USB_HID_GET_PROTOCOL_REQUEST   (0x03)
#define USB_HID_SET_REPORT_REQUEST     (0x09)
#define USB_HID_SET_IDLE_REQUEST       (0x0A)
#define USB_HID_SET_PROTOCOL_REQUEST   (0x0B)

/* for class specific requests */
#define HIGH_BYTE_SHIFT                   (8) 
#define MSB_MASK                          (0xFF00)
#define USB_HID_REQUEST_DIR_MASK          (0x08)
#define USB_HID_REQUEST_TYPE_MASK         (0x01)
#define REPORT_SIZE                       (4)
#define CLASS_REQ_DATA_SIZE               (0x01)
#define MAX_HID_DEVICE                    (0x05)

/*****************************************************************************
 * Local Functions
 *****************************************************************************/
void USB_Service_Hid(PTR_USB_EVENT_STRUCT event,pointer arg);
void USB_Class_Hid_Event(uint_8 event, void* val,pointer arg) ;

 /******************************************************************************
 * Types
 *****************************************************************************/
 typedef uint_32 HID_HANDLE; 
 
 
 /* structure to hold a request in the endpoint queue */
typedef struct _usb_class_hid_queue 
{
    _usb_device_handle handle;
    uint_8 channel;       
    uint_8_ptr app_buff; /* buffer to send */
    uint_32 size; /* size of the transfer */  
}USB_CLASS_HID_QUEUE, *PTR_USB_CLASS_HID_QUEUE;
 
/* USB class hid endpoint data */
  
typedef struct _usb_class_hid_endpoint 
{
    uint_8 endpoint; /* endpoint num */                    
    uint_8 type;     /* type of endpoint (interrupt, bulk or isochronous) */   
    uint_8 bin_consumer;/* the num of queued elements */
    uint_8 bin_producer;/* the num of de-queued elements */
    USB_CLASS_HID_QUEUE queue[HID_MAX_QUEUE_ELEMS]; /* queue data */  
}USB_CLASS_HID_ENDPOINT;

/* contains the endpoint data for non control endpoints */
typedef struct _usb_class_hid_endpoint_data 
{    
    uint_8 count;  /* num of non control endpoints */  
    /* contains the endpoint info */
    /*Allocate Memory In App Layer*/    
    USB_CLASS_HID_ENDPOINT *ep;       
}USB_CLASS_HID_ENDPOINT_DATA, *PTR_USB_CLASS_HID_ENDPOINT_DATA;
 
 /* Strucutre holding HID class state information*/
 typedef struct hid_device_struct
 {
   _usb_device_handle handle;
   uint_32 user_handle;
   USB_CLASS_HANDLE class_handle;
   USB_ENDPOINTS *ep_desc_data;
   USB_CLASS_CALLBACK_STRUCT hid_class_callback;
   USB_REQ_CALLBACK_STRUCT       vendor_req_callback;
   USB_CLASS_SPECIFIC_HANDLER_CALLBACK_STRUCT param_callback;
   USB_CLASS_HID_ENDPOINT_DATA hid_endpoint_data;
   /* for get/set idle and protocol requests*/
   uint_8 class_request_params[2]; 
 }HID_DEVICE_STRUCT, _PTR_ HID_DEVICE_STRUCT_PTR;
 
 /* Structure used to configure HID class by APP*/
 typedef struct hid_config_struct
 {
    uint_32 desc_endpoint_cnt;
    USB_ENDPOINTS *ep_desc_data;
    USB_CLASS_HID_ENDPOINT *ep; 
    USB_CLASS_CALLBACK_STRUCT hid_class_callback;
    USB_REQ_CALLBACK_STRUCT       vendor_req_callback;
    USB_CLASS_SPECIFIC_HANDLER_CALLBACK_STRUCT param_callback;
    DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr; 
 }HID_CONFIG_STRUCT,_PTR_ HID_CONFIG_STRUCT_PTR;
/******************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Class_HID_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param *handle: handle pointer to Identify the controller
 * @param hid_class_callback:   event callback      
 * @param vendor_req_callback:  vendor specific class request callback      
 * @param param_callback:       application params callback      
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the HID Class layer and layers it is dependent on 
 *
 *****************************************************************************/
extern HID_HANDLE USB_Class_HID_Init (HID_CONFIG_STRUCT_PTR hid_config_ptr /*[IN]*/);

/**************************************************************************//*!
 *
 * @name  USB_Class_HID_Send_Data
 *
 * @brief 
 *
 * @param handle          :   handle returned by USB_Class_HID_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
extern uint_8 USB_Class_HID_Send_Data
(
    HID_HANDLE         handle,        /* [IN]*/
    uint_8             ep_num,        /* [IN]*/
    uint_8_ptr         buff_ptr,      /* [IN] buffer to send */      
    uint_32            size           /* [IN] length of the transfer */
);

#define USB_HID_Periodic_Task USB_Class_Periodic_Task

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/flashx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flashx.c$
* $Version : 3.8.32.0$
* $Date    : Aug-30-2012$
*
* Comments:
*
*   This file contains generic flash driver functions to deal with odd
*   size flash blocks.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "flashx.h"
#include "flashxprv.h"
#include <string.h>

#define MFS_SECTOR_SIZE 512

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a flash driver.
*
*END*----------------------------------------------------------------------*/
_mqx_uint _io_flashx_install
(
      /* [IN] A string that identifies the device for fopen */
      char_ptr                      identifier,

      /* [IN] BSP specific settings for installing device */
      FLASHX_INIT_STRUCT const _PTR_  init_ptr

)
{ /* Body */
   IO_FLASHX_STRUCT_PTR           dev_ptr;
  
   dev_ptr = (IO_FLASHX_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(IO_FLASHX_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL) {
      return MQX_OUT_OF_MEMORY;
   } /* Endif */
#endif

    dev_ptr->SECTOR_ERASE   = init_ptr->DEVICE_IF->SECTOR_ERASE;
    dev_ptr->SECTOR_PROGRAM = init_ptr->DEVICE_IF->SECTOR_PROGRAM;
    dev_ptr->CHIP_ERASE     = init_ptr->DEVICE_IF->CHIP_ERASE;
    dev_ptr->READ           = init_ptr->DEVICE_IF->READ;
    dev_ptr->INIT           = init_ptr->DEVICE_IF->INIT;
    dev_ptr->DEINIT         = init_ptr->DEVICE_IF->DEINIT;
    dev_ptr->WRITE_PROTECT  = init_ptr->DEVICE_IF->WRITE_PROTECT;
    dev_ptr->IOCTL          = init_ptr->DEVICE_IF->IOCTL;

    dev_ptr->BASE_ADDR      = init_ptr->BASE_ADDR;
    dev_ptr->HW_BLOCK       = (FLASHX_BLOCK_INFO_STRUCT_PTR) init_ptr->HW_BLOCK;
    dev_ptr->FILE_BLOCK     = (FLASHX_FILE_BLOCK_PTR) init_ptr->FILE_BLOCK;
    dev_ptr->WIDTH          = init_ptr->WIDTH;
    dev_ptr->DEVICES        = init_ptr->DEVICES;
    dev_ptr->WRITE_VERIFY   = init_ptr->WRITE_VERIFY;

    dev_ptr->DEVICE_SPECIFIC_INIT = init_ptr->DEVICE_SPECIFIC_INIT;

   _lwsem_create(&dev_ptr->HW_ACCESS, 1);
    
    return (_io_dev_install_ext(
        identifier,
        _io_flashx_open,
        _io_flashx_close,
        _io_flashx_read,
        _io_flashx_write,
        _io_flashx_ioctl,
        _io_flashx_uninstall,
        (pointer)dev_ptr));

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_uninstall
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Uninstalls a flash driver.
*
*END*----------------------------------------------------------------------*/
_mqx_int _io_flashx_uninstall
   (
      /* [IN] The IO device structure for the device */
      IO_DEVICE_STRUCT_PTR   io_dev_ptr
   )
{ /* Body */
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

    if (!dev_ptr->FILES) {
        _mem_free((pointer)dev_ptr);
        io_dev_ptr->DRIVER_INIT_PTR = NULL;
        return IO_OK;
    } else {
        return IO_ERROR_DEVICE_BUSY;
    } /* Endif */  
   
}  /* Endbody */    


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_open
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         : Opens and initializes flash driver.
*    Must be synchronized by app software with concurrent calls also with
*    close and uninstall function.
* 
*END*----------------------------------------------------------------------*/
_mqx_int _io_flashx_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR fd_ptr,
      
      /* [IN] the remaining portion of the name of the device */
      char_ptr   open_name_ptr,

      /* [IN] the flags to be used during operation: */
      char_ptr   flags
   )
{ /* Body */
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr;
    FLASHX_BLOCK_INFO_STRUCT_PTR b;
    char_ptr             file_name_ptr = fd_ptr->DEV_PTR->IDENTIFIER; /* use driver name temporarily */
    boolean              chip_initialized = TRUE;
    _mqx_uint            erase_array_size;
    _mqx_uint            skip_sectors;
    _mqx_uint            skip_size;
    _mem_size            sfa, efa; /* start file address, end file address */
    _mem_size            bsa, bea; /* block start address, block end address */
    _mem_size            size, sec_size; /* file size, maximum sector size */
    _mqx_int             f; /* file number */

    while (*file_name_ptr++ != 0)
        open_name_ptr++; /* move to the file name */
    file_name_ptr = open_name_ptr; /* throw out value of file_name_ptr and assign the correct file name */

    if (!dev_ptr->FILES) {
        /* First time of opening the device. */
        if (dev_ptr->INIT) {
            chip_initialized = (*dev_ptr->INIT)(dev_ptr);
        } /* Endif */
    } /* Endif */

#if MQX_CHECK_ERRORS
    if (!chip_initialized) {
        return IO_ERROR;
    } /* Endif */
#endif //MQX_CHECK_ERRORS

    /* Check if the file name is in the file list */
    if (dev_ptr->FILE_BLOCK) {
        for (f = 0; dev_ptr->FILE_BLOCK[f].FILENAME; f++) {
            if (strcmp(dev_ptr->FILE_BLOCK[f].FILENAME, file_name_ptr) == 0) {
                /* Found a block with correct filename, prepare file driver memory */
                break;
            }
        }
    }

    if (!dev_ptr->FILE_BLOCK || !dev_ptr->FILE_BLOCK[f].FILENAME) {
        /* File name not found in the list */
        if (*file_name_ptr == 0) {
            /* No filename, use the whole HW space (4GiB) */
            sfa = 0;
            efa = MAX_UINT_32;
            f = -1;
        }
        else {
            /* Specified file name not found in the list of files */
            return IO_ERROR;
        }
    }
    else {
        sfa = dev_ptr->FILE_BLOCK[f].START_ADDR;
        efa = dev_ptr->FILE_BLOCK[f].END_ADDR;
    }

    /* Go through all blocks in HW map and find the first one that matches start of file */
    for (b = dev_ptr->HW_BLOCK; b->NUM_SECTORS != 0; b++) {
        bsa = dev_ptr->BASE_ADDR + b->START_ADDR;
        bea = bsa + b->NUM_SECTORS * b->SECTOR_SIZE - 1;
        if (sfa <= bea)
             break; /* start address of the file preceed the block or is inside the block */
    }

    if ((b->NUM_SECTORS == 0) || (bsa > efa)) {
        return IO_ERROR; /* no intersection */
    }

    if (sfa < bsa) {
        sfa = bsa;
    }
#if MQX_CHECK_ERRORS
    else if ((sfa - bsa) % b->SECTOR_SIZE) {
        return IO_ERROR; /* start address of file is not sector aligned */
    }
#endif //MQX_CHECK_ERRORS

    skip_size = sfa - (dev_ptr->BASE_ADDR + b->START_ADDR);
    skip_sectors = skip_size / b->SECTOR_SIZE;

    /* Get the size of the file */
    size = 0;
    erase_array_size = 0;
    sec_size = 0;
    for ( ; b->NUM_SECTORS != 0; b++) {
        _mqx_uint block_size = b->NUM_SECTORS * b->SECTOR_SIZE;
        bsa = dev_ptr->BASE_ADDR + b->START_ADDR;
        bea = bsa + block_size - 1;

        /* Test if we have not overrun after the file area */
        if (bsa > efa) break;
        
        size += block_size;
        erase_array_size += b->NUM_SECTORS;
        /* Compute max. sector size for this file */
        if (sec_size < b->SECTOR_SIZE) {
            sec_size = b->SECTOR_SIZE;
        }

        /* Check if this is the last block in the file */
        if (bea >= efa) {
#if MQX_CHECK_ERRORS
            if ((efa + 1 - bsa) % b->SECTOR_SIZE) {
                return IO_ERROR; /* end address of file is not sector aligned */
            }
#endif //MQX_CHECK_ERRORS
            /* Remove the trailing space */
            size -= bea - efa;
            erase_array_size -= (bea - efa) / b->SECTOR_SIZE;
            break;
        }
    }
    /* Remove the heading space */
    size -= skip_size;
    erase_array_size -= skip_sectors;

    file_ptr = _mem_alloc_system(sizeof(IO_FLASHX_FILE_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (file_ptr == NULL) {
        return IO_ERROR;
    }
#endif //MQX_CHECK_MEMORY_ALLOCATION_ERRORS

    file_ptr->ERASE_ARRAY = _mem_alloc_system((erase_array_size + 7) / 8); /* size in bytes, each bit represents one sector */
    file_ptr->ERASE_ARRAY_MAX = erase_array_size; /* number of valid bits in ERASE_ARRAY */

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (file_ptr->ERASE_ARRAY == NULL) {
        _mem_free(file_ptr);
        return IO_ERROR; /* end address of file is not sector aligned */
    }
#endif //MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    _mem_set_type(file_ptr->ERASE_ARRAY, MEM_TYPE_IO_FLASHX_SECTOR_MAP); 
    /* Assume that the opened file's area in flash was not erased */
    _mem_zero(file_ptr->ERASE_ARRAY, (erase_array_size + 7) / 8);

    /* Store file block */
    if (f != -1)
        file_ptr->FILE_BLOCK = &dev_ptr->FILE_BLOCK[f];
    else
        file_ptr->FILE_BLOCK = NULL; /* the whole flash is used */

    /* Store the flags */
    file_ptr->FLAGS = 0;
    /* Set the cache for this file as not yet allocated */
    file_ptr->CACHE_PTR = 0;
    /* Invalidate cache, mark the data not dirty */
    file_ptr->DIRTY_DATA = 0;
    /* Store max. sector size */
    file_ptr->MAX_SECT_SIZE = sec_size;

    /* File size */
    fd_ptr->SIZE = size;
    /* Store file context structure */
    fd_ptr->DEV_DATA_PTR = (IO_FLASHX_STRUCT_PTR) file_ptr;

    /* Increment usage counter */
    dev_ptr->FILES++;

    return MQX_OK;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_close
* Returned Value   : MQX_OK
* Comments         : Closes flash driver
* 
*END*----------------------------------------------------------------------*/
_mqx_int _io_flashx_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
   
    if (file_ptr->FLAGS & FLASHX_FLASH_BUFFER_ENABLED) {
        _io_flashx_flush_buffer(fd_ptr);
    } /* Endif */

    if(file_ptr->CACHE_PTR) {
        _mem_free(file_ptr->CACHE_PTR);
    }

    _mem_free((pointer)file_ptr->ERASE_ARRAY);

    _mem_free(file_ptr);

    if (--dev_ptr->FILES == 0) {
        if (dev_ptr->DEINIT) {
            (*dev_ptr->DEINIT)(dev_ptr);
        } /* Endif */
    }

    return MQX_OK;  
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _allocate_sector_cache
* Returned Value   : True, False
* Comments         : Allocate the flash sector cache
* 
*END*----------------------------------------------------------------------*/
boolean _allocate_sector_cache(MQX_FILE_PTR fd_ptr) 
{
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;

    /* test for sector cache enable */
    if (!(file_ptr->FLAGS & FLASHX_SECTOR_CACHE_ENABLED))
        return FALSE;
    
    if (file_ptr->CACHE_PTR == NULL) {
        file_ptr->CACHE_PTR  = _mem_alloc_system(file_ptr->MAX_SECT_SIZE);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        /* test for memory allocation */
        if(file_ptr->CACHE_PTR == NULL)
            return FALSE;
#endif
        _mem_set_type(file_ptr->CACHE_PTR, MEM_TYPE_IO_FLASHX_SECTOR_CACHE);
    }
    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_read
* Returned Value   : number of characters read
* Comments         : Reads data from flash driver
*    NOTE: This function should normally call low-level driver read(),
*    but it is not implemented yet. That's why dev_ptr->BASE_ADDR is used
*    here, even if this information is for low level driver only.
*    The dev_ptr->BASE_ADDR is base HW address for external flashes and should
*    equal to zero for internal flashes.
* 
*END*----------------------------------------------------------------------*/
_mqx_int _io_flashx_read
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,
   
      /* [IN] where the characters are to be stored */
      char_ptr   data_ptr,
   
      /* [IN] the number of characters to input */
      _mqx_int   num
   )
{ /* Body */
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
    _mqx_uint            sb, ss, offset, fs, copy_num, remains;
     
    if (fd_ptr->LOCATION + num > fd_ptr->SIZE) {
        if (fd_ptr->LOCATION >= fd_ptr->SIZE) {
            fd_ptr->ERROR = IO_ERROR_READ_ACCESS;
            return 0;
        }
        num = fd_ptr->SIZE - fd_ptr->LOCATION;
    }

    _lwsem_wait(&dev_ptr->HW_ACCESS);
                             
    if (file_ptr->FLAGS & FLASHX_FLASH_BUFFER_ENABLED) {
        /* We do this in order to simplify algorithm for reading.
        ** In true write-back caching, we check if the requested data to be read have valid
        ** image in the cache and if they do, we will read them from the cache instead.
        */
        _io_flashx_flush_buffer(fd_ptr);
    } /* Endif */

    remains = num;

    /* Find the first block where to read from */
    _io_flashx_find_correct_sectors(fd_ptr, fd_ptr->LOCATION, &sb, &ss, &offset, &fs);

    while (remains)
    {
        copy_num = (dev_ptr->HW_BLOCK[sb].NUM_SECTORS - ss) * dev_ptr->HW_BLOCK[sb].SECTOR_SIZE - offset;
        if (copy_num > remains)
        copy_num = remains;
        _mem_copy((pointer)(dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[sb].START_ADDR + ss * dev_ptr->HW_BLOCK[sb].SECTOR_SIZE + offset), (pointer) data_ptr, copy_num);
        remains -= copy_num;
        fd_ptr->LOCATION += copy_num; /* move LOCATION after each partial read */
        ss = 0; /* ss is interesting only in first pass when reading from start block */
        offset = 0; /* offset is interesting only in first pass when reading from start block */
        sb++;
    }

    _lwsem_post(&dev_ptr->HW_ACCESS);

    if (fd_ptr->LOCATION >= fd_ptr->SIZE) {
        fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
    }

    /* Return the number of read bytes, not the remaining size */
    return num - remains;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_erase_sector
* Returned Value   : boolean, TRUE upon success
* Comments         : Although it seems counter-intuitive, we actually set the 
*                    DIRTY DATA bit here, or leave it set if it was set 
*                    previously.  This is to reduce code size. This function
*                    is only called before a write occurs, so the sector will
*                    be dirty again after the write finishes.
* 
*END*----------------------------------------------------------------------*/

boolean _io_flashx_erase_sector
   (
      /* [IN] The device handle */
      MQX_FILE_PTR          fd_ptr,
   
      /* Sector number within file */
      _mqx_uint             file_sector,
   
      /* [IN] The block of sectors to write to */
      _mqx_uint             block_number,
   
      /* [IN] The sector number within the block */
      _mqx_uint             sector_number
   )
{ /* Body */
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
    boolean    result = TRUE;
    char_ptr   dest_ptr;
    _mqx_uint  array_offset;
    uint_8     erase_mask;
   
    array_offset = file_sector / 8;
    erase_mask = 0x1 << (file_sector % 8); 
   
    if (dev_ptr->SECTOR_ERASE) {
        /* Check if sector was not erased before */
        if (0 == (file_ptr->ERASE_ARRAY[array_offset] & erase_mask)) {
            dest_ptr = (char_ptr)(dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[block_number].START_ADDR + sector_number * dev_ptr->HW_BLOCK[block_number].SECTOR_SIZE);
            result = (*dev_ptr->SECTOR_ERASE)(dev_ptr, dest_ptr, dev_ptr->HW_BLOCK[block_number].SECTOR_SIZE);
        }
    }

    return result;

} /* Endbody */  


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_phys_to_sector
* Returned Value   : void
* Comments         : Finds block for given physical address and provides with
*                    sector number, sector physical address and offset in the sector.
* 
*END*----------------------------------------------------------------------*/

FLASHX_BLOCK_INFO_STRUCT_PTR _io_flashx_phys_to_sector
   (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR dev_ptr,

      /* [IN] Physical address */
      _mem_size            addr,

      /* [IN/OUT] Number of sector sector in the block */
      _mqx_uint _PTR_      sector_number_ptr,

      /* [IN/OUT] Physical address of the sector */
      _mem_size _PTR_      sector_addr_ptr,

      /* [IN/OUT] The offset within the sector */
      _mem_size _PTR_      sector_offset_ptr

   )
{
    FLASHX_BLOCK_INFO_STRUCT_PTR b;

    _mem_size block_start;

    _mqx_uint sector_number;
    _mem_size sector_addr;
    _mem_size sector_offset;

    /* Go through all blocks in HW map and find the first one that matches */
    for (b = dev_ptr->HW_BLOCK; b->NUM_SECTORS != 0; b++) {
        block_start = dev_ptr->BASE_ADDR + b->START_ADDR;
        if ((addr >= block_start) && (addr <= block_start + b->NUM_SECTORS * b->SECTOR_SIZE - 1))
             break; /* start address of the file is inside the block */
    }

    if (b->NUM_SECTORS == 0)
        return NULL;

    sector_number = (addr - block_start) / b->SECTOR_SIZE;
    sector_addr = block_start + sector_number * b->SECTOR_SIZE;
    sector_offset = addr - sector_addr;

    if (sector_number_ptr != NULL)
        *sector_number_ptr = sector_number;

    if (sector_addr_ptr != NULL)
        *sector_addr_ptr = sector_addr;

    if (sector_offset_ptr != NULL)
        *sector_offset_ptr = sector_offset;

    return b;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_find_correct_sectors
* Returned Value   : void
* Comments         : Sets the start and end block, start and end sectors 
*                    relative to these blocks, and sets the absolute start 
*                    sector.
* 
*END*----------------------------------------------------------------------*/

void _io_flashx_find_correct_sectors
   (
      /* [IN] The device handle */
      MQX_FILE_PTR         fd_ptr,

      /* [IN] The linear address within the file */
      _mqx_uint            location,

      /* [IN/OUT] The HW start block for the write */
      _mqx_uint _PTR_      start_block_ptr,

      /* [IN/OUT] The start sector in the start_block */
      _mqx_uint _PTR_      start_sector_ptr,

      /* [IN/OUT] The offset within the first sector */
      _mqx_uint _PTR_      offset_ptr,

      /* [IN/OUT] The relative sector number within the file */ 
      _mqx_uint _PTR_      file_sector_ptr
   )
{  /* Body */
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
    FLASHX_BLOCK_INFO_STRUCT_PTR b;
    _mem_size sfa; /* start file address */
    _mem_size bsa, bea; /* block start address, block end address */
    _mqx_uint dummy_sect;

    *file_sector_ptr = 0;
    *start_block_ptr = 0;

    if (file_ptr->FILE_BLOCK == NULL) {
        sfa = 0;
    }
    else {
        sfa = file_ptr->FILE_BLOCK->START_ADDR;
    }

    /* Go through all blocks in HW map and find the first one that matches */
    for (b = dev_ptr->HW_BLOCK; b->NUM_SECTORS != 0; b++) {
        bsa = dev_ptr->BASE_ADDR + b->START_ADDR;
        bea = bsa + b->NUM_SECTORS * b->SECTOR_SIZE - 1;
        if ((sfa >= bsa) && (sfa <= bea))
             break; /* start address of the file is inside the block */
        *start_block_ptr += 1;
    }

    if (b->NUM_SECTORS != 0) {
        /* Rebase location so that is counts from the beginning of this block */
        location += sfa - bsa;
        /* Store the number of "dummy' sectors caused by rebasing location.
        ** These sectors are taken into computation in the loop.
        ** They must be subtracted at the end.
        */
        dummy_sect = (sfa - bsa) / b->SECTOR_SIZE;

        /* We are at the beginning of the file, seek to the location */
        for ( ; b->NUM_SECTORS != 0; b++) {
            if (b->NUM_SECTORS * b->SECTOR_SIZE > location) {
                break;
            }
            location -= b->SECTOR_SIZE * b->NUM_SECTORS;
            *file_sector_ptr += b->NUM_SECTORS;
            *start_block_ptr += 1;
        }

        *start_sector_ptr = location / b->SECTOR_SIZE;
        *offset_ptr = location % b->SECTOR_SIZE;
        /* Add the rest of sectors to the file sectors */               
        *file_sector_ptr += location / b->SECTOR_SIZE;
        /* At the end do not forget to subtract the dummy sectors */
        *file_sector_ptr -= dummy_sect;
    }
    else {
        /* TODO: the file is located after possible physical memory address space, return error */
    }
} /* Endbody */    


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_flush_buffer
* Returned Value   : number of characters written
* Comments         : Flushes the flash buffer. This is used only privately 
*                    within the flashx.c file. 
*END*----------------------------------------------------------------------*/

_mqx_int _io_flashx_flush_buffer
   (
      /* [IN] The device handle */
      MQX_FILE_PTR   fd_ptr
   ) 
{ /* Body */
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
    _mqx_int   error = MQX_OK;

    /* Check if buffering is enabled */
    if (file_ptr->FLAGS & FLASHX_FLASH_BUFFER_ENABLED) {
        /* Flush sector buffer */
        error = _io_flashx_flush_sector_buffer(fd_ptr);
    }

    /* No other buffering provided in this driver. */

    return error;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_flush_sector_buffer
* Returned Value   : number of characters written
* Comments         : Flushes the flash buffer. This is used only privately 
*                    within the flashx.c file. 
*END*----------------------------------------------------------------------*/

_mqx_int _io_flashx_flush_sector_buffer
   (
      /* [IN] The device handle */
      MQX_FILE_PTR   fd_ptr
   ) 
{ /* Body */
    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
    _mqx_uint  sb, ss, fs;
    _mqx_int   dest_ptr, error = MQX_OK;

    /* If the sector cache is disabled, return error */
    if (!(file_ptr->FLAGS & FLASHX_SECTOR_CACHE_ENABLED))
        return IO_ERROR;

    if (file_ptr->DIRTY_DATA) {
        sb = file_ptr->CACHE_BLOCK;
        ss = file_ptr->CACHE_SECTOR;
        fs = file_ptr->CACHE_FILE_SECTOR;

        if (!_io_flashx_erase_sector(fd_ptr, fs, sb, ss)) 
        {
            return IO_ERROR;
        } /* Endif */

        dest_ptr = (_mqx_int)(dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[sb].START_ADDR + (dev_ptr->HW_BLOCK[sb].SECTOR_SIZE * ss));
        if ((*dev_ptr->SECTOR_PROGRAM)(dev_ptr, file_ptr->CACHE_PTR, (char_ptr)dest_ptr, dev_ptr->HW_BLOCK[sb].SECTOR_SIZE))
        {
            error = dev_ptr->HW_BLOCK[sb].SECTOR_SIZE;
            /* Sector written to the flash is not erased */
            file_ptr->ERASE_ARRAY[fs / 8] &= ~(0x1 << (fs % 8));
        } else {
            return IO_ERROR;
        } /* Endif */

        file_ptr->DIRTY_DATA = FALSE;
    } /* Endif */

    return error;
}


 
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_write
* Returned Value   : number of characters written
* Comments         : Writes data to the flash device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_flashx_write
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,
   
      /* [IN] where the characters are */
      char_ptr     data_ptr,
   
      /* [IN] the number of characters to output */
      _mqx_int     num
   )
{ /* Body */
    IO_FLASHX_STRUCT_PTR  dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
    _mem_size             copy_num, remains;
    _mqx_uint             b, s, offset, fs;
    _mqx_uint             dest_ptr;
    _mqx_int              result;

    if (fd_ptr->LOCATION + num > fd_ptr->SIZE) {
        if (fd_ptr->LOCATION >= fd_ptr->SIZE) {
            fd_ptr->ERROR = IO_ERROR_WRITE_ACCESS;
            return 0;
        }
        num = fd_ptr->SIZE - fd_ptr->LOCATION;
    }

    _lwsem_wait(&dev_ptr->HW_ACCESS);

    remains = num;

    while (remains) {
        /* Get block, sector, offset and file sector */
        _io_flashx_find_correct_sectors(fd_ptr, fd_ptr->LOCATION, &b, &s, &offset, &fs);

        if (offset || (remains < dev_ptr->HW_BLOCK[b].SECTOR_SIZE)) {
            /* Write partial sector.
            ** Partial sector write handles data caching. For this reason we use
            ** partial write also for last sector (even if it is not partial).
            */
            copy_num = remains <= (dev_ptr->HW_BLOCK[b].SECTOR_SIZE - offset) ? remains : dev_ptr->HW_BLOCK[b].SECTOR_SIZE - offset;
            result = _io_flashx_write_partial_sector(fd_ptr, b, s, offset, copy_num, fs, data_ptr);
            if (result == IO_ERROR) {
                fd_ptr->ERROR = IO_ERROR_WRITE;
                _lwsem_post(&dev_ptr->HW_ACCESS);
                return result;
            }
        }
        else {
            /* Write whole sector. Whole sector does not handle sector caching. */
            copy_num = dev_ptr->HW_BLOCK[b].SECTOR_SIZE;
            
            result = _io_flashx_erase_sector(fd_ptr, fs, b, s);
            if (result != IO_ERROR) {
                dest_ptr = dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[b].START_ADDR + s * dev_ptr->HW_BLOCK[b].SECTOR_SIZE + offset;
                if (!(*dev_ptr->SECTOR_PROGRAM)(dev_ptr, data_ptr, (char_ptr) dest_ptr, copy_num))
                    result = IO_ERROR;
            }
            if (result == IO_ERROR) {
                fd_ptr->ERROR = IO_ERROR_WRITE;
                _lwsem_post(&dev_ptr->HW_ACCESS);
                return result;
            }

            if ((file_ptr->FLAGS & FLASHX_SECTOR_CACHE_ENABLED) &&
                (file_ptr->CACHE_BLOCK == b) && 
                (file_ptr->CACHE_SECTOR == s)) 
            {
                file_ptr->DIRTY_DATA = FALSE; /* data in the cache are invalid, because another data were written into flash */
            } /* Endif */
        }

        /* Sector written to the flash is not erased */
        file_ptr->ERASE_ARRAY[fs / 8] &= ~(0x1 << (fs % 8));
        fd_ptr->LOCATION += copy_num;
        data_ptr += copy_num;
        remains -= copy_num;
    }
      
    _lwsem_post(&dev_ptr->HW_ACCESS);

    if (fd_ptr->LOCATION >= fd_ptr->SIZE) {
        fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
    }

    return num - remains;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_write_partial_sector
* Returned Value   : _mem_size - number of bytes written if successfully,
*                    0 otherwise
* Comments         : Writes a partial flash sector while preserving contents of
*                    unused portions of the sector
* 
*END*----------------------------------------------------------------------*/
_mem_size _io_flashx_write_partial_sector
   (
       /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,
   
      /* [IN] The block of sectors to write to */
      _mqx_uint  block_number,
   
      /* [IN] The sector number within the block */
      _mqx_uint  sector_number,
   
      /* [IN] The start offset within the sector */
      _mem_size  offset_in_sector,
   
      /* [IN] The number of bytes to write */
      _mem_size  bytes_to_write,
   
      /* [IN/OUT] The relative sector number within the file */ 
      _mqx_uint  file_sector,
   
      /* [IN] The data to write */
      char_ptr   src_ptr
   )
{ /* Body */
    IO_FLASHX_STRUCT_PTR  dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
    _mem_size             sector_size;
    char_ptr              sector_dest_ptr;
    char_ptr              data_dest_ptr;
    _mem_size             num_data_before_write;
    _mem_size             num_data_after_write;  
   
    /* Get the sector size */
    sector_size = dev_ptr->HW_BLOCK[block_number].SECTOR_SIZE;
    /* Get the pointer to sector start */
    sector_dest_ptr = (char_ptr)(dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[block_number].START_ADDR + dev_ptr->HW_BLOCK[block_number].SECTOR_SIZE * sector_number);
    /* Get the pointer to start data write */ 
    data_dest_ptr = sector_dest_ptr + offset_in_sector;     

    /* Is the write area erased? */ 
    if (!_io_flashx_check_free_space(data_dest_ptr, bytes_to_write)) {
        /* Yes, write data */
        if (!(*dev_ptr->SECTOR_PROGRAM)(dev_ptr, src_ptr, data_dest_ptr, bytes_to_write)) { 
            return (_mem_size) IO_ERROR;
        } /* Endif */
    }
    else if ((file_ptr->FLAGS & FLASHX_FLASH_BUFFER_ENABLED) && (file_ptr->FLAGS & FLASHX_SECTOR_CACHE_ENABLED)) {  
        /* Writing using delayed write */
        if (!_allocate_sector_cache(fd_ptr))
            return (_mem_size) IO_ERROR;
        
        /* Buffering= delayed write caching */
        if ((file_ptr->DIRTY_DATA) && (file_ptr->CACHE_BLOCK != block_number || file_ptr->CACHE_SECTOR != sector_number)) {
            _io_flashx_flush_buffer(fd_ptr);
        }
        /* Read the sector for partial write from flash into RAM */
        _mem_copy((pointer)sector_dest_ptr, file_ptr->CACHE_PTR, sector_size);
 
        file_ptr->CACHE_BLOCK  = block_number;
        file_ptr->CACHE_SECTOR = sector_number;
        file_ptr->CACHE_FILE_SECTOR = file_sector;

        /* Write new data into RAM cache sector */
        _mem_copy((pointer)src_ptr, (pointer)((char_ptr) file_ptr->CACHE_PTR + offset_in_sector), bytes_to_write);

        /* Buffering: after an operation, leave cache valid for delayed write operation */
        file_ptr->DIRTY_DATA = TRUE;
    } /* Endif */
      
    else {
        /* Are there any data written before write area ? */
        num_data_before_write = _io_flashx_check_free_space(sector_dest_ptr, offset_in_sector); 
        /* Are there any data written behind write data? */
        num_data_after_write = _io_flashx_check_free_space(data_dest_ptr + bytes_to_write, sector_size - offset_in_sector - bytes_to_write );

        if (num_data_before_write || num_data_after_write) {
            /* If we have some data already in flash, we copy data to RAM and we assemble the sector to be written. */

            /* Allocate sector for partial write operation */
            if (!_allocate_sector_cache(fd_ptr))
                return (_mem_size) IO_ERROR;
        
            /* Flush buffer if data from another sector is valid in the cache.
            ** We do not need to perform this because the data in the sector cache
            ** are valid only when FLASHX_FLASH_BUFFER_ENABLED is set.
            */
            /*
            if ((file_ptr->DIRTY_DATA) && (file_ptr->CACHE_BLOCK != block_number || file_ptr->CACHE_SECTOR != sector_number)) {
                _io_flashx_flush_sector_buffer(fd_ptr);
            }
            */

            /* Read the sector to do the partial write into ram */
            _mem_copy((pointer)sector_dest_ptr, file_ptr->CACHE_PTR, sector_size);
            /* Write new data into ram copy sector */
            _mem_copy((pointer)src_ptr, (pointer)((char_ptr)file_ptr->CACHE_PTR + offset_in_sector), bytes_to_write);
            /* Erase sector */
            if (!_io_flashx_erase_sector(fd_ptr, file_sector, block_number, sector_number))
            {
                return (_mem_size) IO_ERROR;
            }
            /* Write the newly modified RAM sector back into flash, do not perform buffering (delayed write) */
            if (!(*dev_ptr->SECTOR_PROGRAM)(dev_ptr, file_ptr->CACHE_PTR, sector_dest_ptr, sector_size)) {
                return (_mem_size) IO_ERROR;
            } /* Endif */

            /* Sector caching: after the operation, invalidate cache and free memory. */
            file_ptr->DIRTY_DATA = FALSE;
            _mem_free(file_ptr->CACHE_PTR);
            file_ptr->CACHE_PTR = NULL;
        }
        else {
            /* Otherwise we do not need to store old data, we only erase sector and write new data */
            _io_flashx_erase_sector(fd_ptr, file_sector, block_number, sector_number);
            if (!(*dev_ptr->SECTOR_PROGRAM)(dev_ptr, src_ptr, data_dest_ptr, bytes_to_write)) {
                return (_mem_size) IO_ERROR;
            } /* Endif */
        }
    }

    /* Return number of bytes written */
    return bytes_to_write;
}

/*FUNCTION*****************************************************************
*
* Function Name    : _io_flashx_check_free_space
* Returned Value   : _mem_size
* Comments         :
*    Return position of last used byte in tested area.
*
*END*********************************************************************/
_mem_size _io_flashx_check_free_space(
    /* [IN] source pointer */
    char_ptr    src_ptr,
    /* [IN] number of bytes to check */
    _mem_size   num_bytes_to_check
)
{
    #define BLANK_MEM 0xFF
    uint_32 used_mem_position;
    
    /* Is the write area erased ? */
    for(used_mem_position = num_bytes_to_check; used_mem_position > 0; used_mem_position--)
    {
        /* Workaround for bug in CodeWarrior: do not optimize following two lines! */
        char_ptr tested_byte = src_ptr + used_mem_position - 1;
        if((char) *tested_byte != (char) BLANK_MEM)
            /* return last non-free byte possition */
            return used_mem_position;
    }
    /* space is free */
    return 0;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _io_flashx_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_flashx_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,
   
      /* [IN] the ioctl command */
      _mqx_uint    cmd,
   
      /* [IN/OUT] the ioctl parameters */
      pointer      param_ptr
   )
{ /* Body */
    IO_FLASHX_STRUCT_PTR  dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;
    _mqx_int                           result = MQX_OK;
    _mqx_uint                          i, j;
    _mqx_uint                          sb, ss, offset, fs;
    char_ptr                           temp_ptr;
    pointer _PTR_                      pparam_ptr;
    _mqx_uint_ptr                      uparam_ptr;
    _mem_size_ptr                      mparam_ptr;
   
    switch (cmd) {
        case FLASH_IOCTL_GET_BASE_ADDRESS:
            mparam_ptr = (_mem_size_ptr)param_ptr;
            *mparam_ptr = dev_ptr->BASE_ADDR;
            break;

        case FLASH_IOCTL_GET_BLOCK_GROUPS:
            for (i=0; dev_ptr->HW_BLOCK[i].NUM_SECTORS != 0; i++) { /* just count blocks */ }
            uparam_ptr = (_mqx_uint_ptr)param_ptr;
            *uparam_ptr = i;
            break;   

        case IO_IOCTL_GET_NUM_SECTORS:
            *(uint_32_ptr)param_ptr = fd_ptr->SIZE / MFS_SECTOR_SIZE;
            break;

        case FLASH_IOCTL_GET_NUM_SECTORS:
            _io_flashx_find_correct_sectors(fd_ptr, fd_ptr->SIZE, &sb, &ss, &offset, &fs);
            uparam_ptr = (_mqx_uint_ptr) param_ptr;
            *uparam_ptr = fs;
            break;

        case FLASH_IOCTL_GET_WIDTH: 
            uparam_ptr = (_mqx_uint_ptr)param_ptr;
            *uparam_ptr = dev_ptr->WIDTH;
            break;

        case IO_IOCTL_DEVICE_IDENTIFY:
            /* 
            ** This is to let the upper layer know what kind of device this is.
            ** It's a physical flash device, capable of being erased, read, seeked, 
            ** and written. Flash devices are not interrupt driven, so 
            ** IO_DEV_ATTR_POLL is included.
            */   
            uparam_ptr = (_mqx_uint_ptr)param_ptr;
            uparam_ptr[0] = IO_DEV_TYPE_PHYS_FLASHX;
            uparam_ptr[1] = IO_DEV_TYPE_LOGICAL_MFS;
            uparam_ptr[2] = IO_DEV_ATTR_ERASE | IO_DEV_ATTR_POLL
                             | IO_DEV_ATTR_READ | IO_DEV_ATTR_SEEK | 
                             IO_DEV_ATTR_WRITE;
            break; 
   
        case IO_IOCTL_GET_BLOCK_SIZE:
            /* returns the fixed size for MFS sector size */
            *(uint_32_ptr)param_ptr = MFS_SECTOR_SIZE;
            break;
      
        case FLASH_IOCTL_GET_SECTOR_SIZE:       
            /* 
            ** This returns the size of the sector after a user does an 
            ** fseek to the location he/she wants to know the sector size of.
            */
            _io_flashx_find_correct_sectors(fd_ptr, fd_ptr->LOCATION, &sb, &ss, &offset, &fs);
            mparam_ptr = (_mem_size_ptr) param_ptr;
            *mparam_ptr = dev_ptr->HW_BLOCK[sb].SECTOR_SIZE;
            break;

        case FLASH_IOCTL_GET_SECTOR_BASE:
            /* 
            ** This returns the start address of the sector after a user does an 
            ** fseek to the sector he/she wants know the start of.
            */
            _io_flashx_find_correct_sectors(fd_ptr, fd_ptr->LOCATION, &sb, &ss, &offset, &fs);
            mparam_ptr = (_mem_size_ptr) param_ptr;
            *mparam_ptr = dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[sb].START_ADDR + dev_ptr->HW_BLOCK[sb].SECTOR_SIZE * ss;
            break;

        case FLASH_IOCTL_GET_BLOCK_MAP:
            pparam_ptr = (pointer _PTR_) param_ptr;
            *pparam_ptr = (pointer) dev_ptr->HW_BLOCK;
            break;

        case IO_IOCTL_FLUSH_OUTPUT:
        case FLASH_IOCTL_FLUSH_BUFFER: 
            _lwsem_wait(&dev_ptr->HW_ACCESS);
            result = _io_flashx_flush_buffer(fd_ptr);
            _lwsem_post(&dev_ptr->HW_ACCESS);
            break;   
   
        case FLASH_IOCTL_ENABLE_BUFFERING:
           /* if RAM cache is enabled, enable buffer */
           if(file_ptr->FLAGS & FLASHX_SECTOR_CACHE_ENABLED)
           {
               file_ptr->FLAGS |= FLASHX_FLASH_BUFFER_ENABLED;
               result = MQX_OK;
           }
           /* else return error */
           else
               result = IO_ERROR;
           break;          

        case FLASH_IOCTL_DISABLE_BUFFERING: 
            _lwsem_wait(&dev_ptr->HW_ACCESS);
            result = _io_flashx_flush_buffer(fd_ptr);
            _lwsem_post(&dev_ptr->HW_ACCESS);
            if (result != MQX_OK) {
                break;
            } /* Endif */
            file_ptr->FLAGS &= ~FLASHX_FLASH_BUFFER_ENABLED;
            break;   

        case FLASH_IOCTL_ENABLE_SECTOR_CACHE:
            /* Set RAM cache flag */
            file_ptr->FLAGS |= FLASHX_SECTOR_CACHE_ENABLED;
            break; 

        case FLASH_IOCTL_DISABLE_SECTOR_CACHE:
            /* Disable buffering first */
            if(file_ptr->FLAGS & FLASHX_FLASH_BUFFER_ENABLED){
                 _lwsem_wait(&dev_ptr->HW_ACCESS);
                 result = _io_flashx_flush_sector_buffer(fd_ptr);
                 _lwsem_post(&dev_ptr->HW_ACCESS);
                 if (result != MQX_OK) {
                     break;
                 } /* Endif */
                 file_ptr->FLAGS &= ~FLASHX_FLASH_BUFFER_ENABLED;
            }
            /* clear ram cache flag */
            file_ptr->FLAGS &= ~FLASHX_SECTOR_CACHE_ENABLED;
            break; 

        case FLASH_IOCTL_ERASE_SECTOR:
            /* 
            ** This erases the sector after a user does an 
            ** fseek to the location of the sector he/she wants to erase.
            */
            if (!dev_ptr->SECTOR_ERASE) {
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            } /* Endif */   
            _io_flashx_find_correct_sectors(fd_ptr, fd_ptr->LOCATION, &sb, &ss, &offset, &fs);
            temp_ptr = (char_ptr)(dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[sb].START_ADDR + dev_ptr->HW_BLOCK[sb].SECTOR_SIZE * ss);

            _lwsem_wait(&dev_ptr->HW_ACCESS);
            if ((*dev_ptr->SECTOR_ERASE)(dev_ptr, temp_ptr, dev_ptr->HW_BLOCK[sb].SECTOR_SIZE)) {
                file_ptr->ERASE_ARRAY[fs / 8] |= (0x1 << (fs % 8));
                if ((sb == file_ptr->CACHE_BLOCK) && (ss == file_ptr->CACHE_SECTOR))
                    file_ptr->DIRTY_DATA = FALSE; /* invalidate cache */
            }
            else {
                result = IO_ERROR; /* could not erase sector */
            }
            _lwsem_post(&dev_ptr->HW_ACCESS);
            break;

        case FLASH_IOCTL_ERASE_CHIP:
            /* Though this command erases the whole flash,
            ** it does not invalidates all the caches
            ** associated with opened files on this driver.
             */ 
            if (dev_ptr->CHIP_ERASE) {
                _lwsem_wait(&dev_ptr->HW_ACCESS);
                if ((*dev_ptr->CHIP_ERASE)(dev_ptr)) {
                    for (i = 0; i < (file_ptr->ERASE_ARRAY_MAX + 7) / 8; i++) {
                        /* The whole chip is cleared, mark sectors as erased */
                        file_ptr->ERASE_ARRAY[i] = 0xFF;
                    }
                }
                else {
                    result = IO_ERROR; /* could not erase chip */
                }
                _lwsem_post(&dev_ptr->HW_ACCESS);
                break;
            } else if (!dev_ptr->SECTOR_ERASE) {
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            } else {
                fs = 0;
                _lwsem_wait(&dev_ptr->HW_ACCESS);
                for (i = 0; dev_ptr->HW_BLOCK[i].NUM_SECTORS != 0; i++) {
                    temp_ptr = (char_ptr)(dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[i].START_ADDR);
                    for (j = 0; j < dev_ptr->HW_BLOCK[i].NUM_SECTORS; j++) {
                        if ((*dev_ptr->SECTOR_ERASE)(dev_ptr, temp_ptr, dev_ptr->HW_BLOCK[i].SECTOR_SIZE)) {
                            file_ptr->ERASE_ARRAY[fs / 8] |= (0x1 << (fs % 8));
                            fs++;
                        }
                        else {
                            result = IO_ERROR; /* sector erase was not successfull */
                            break;
                        }
                        temp_ptr += dev_ptr->HW_BLOCK[i].SECTOR_SIZE;      
                    } /* Endfor */
                    if (result != MQX_OK)
                        break;
                } /* Endfor */
                _lwsem_post(&dev_ptr->HW_ACCESS);
            }/* Endif */
            break;
        
        case FLASH_IOCTL_WRITE_PROTECT:
            if (dev_ptr->WRITE_PROTECT != NULL) {
                _lwsem_wait(&dev_ptr->HW_ACCESS);
                result = (*dev_ptr->WRITE_PROTECT)(dev_ptr, *(_mqx_uint_ptr)param_ptr);
                _lwsem_post(&dev_ptr->HW_ACCESS);
            }
            break;
        
        default:
            if(dev_ptr->IOCTL != NULL){
                result = (*dev_ptr->IOCTL)(dev_ptr, cmd, param_ptr);
            }
            else {
                result = IO_ERROR_INVALID_IOCTL_CMD;    
            }         
            break;
    } /* Endswitch */

    return result;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_flashx_wait_us
* Returned Value   : none
* Comments         : 
*    This function waits at least the given amount of us, but it is possible
*    to wait longer
* 
*END*----------------------------------------------------------------------*/

void _io_flashx_wait_us
   (
      /* [IN] the time to spin wait for */
      _mqx_int wait_us
   ) 
{/* Body */
    _mqx_int total_us = 0;
    _mqx_int start_us;
    _mqx_int end_us;
     
    start_us = (int_32) _time_get_microseconds();
    while (total_us < wait_us) {
        end_us = (int_32) _time_get_microseconds();
        if (end_us > start_us) {
            total_us += (end_us - start_us);
        } /* Endif */
        start_us = end_us;
    } /* Endwhile */

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/include/sh_enet.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_enet.h$
* $Version : 3.0.2.0$
* $Date    : Jan-13-2009$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#ifndef __sh_enet_h__
#define __sh_enet_h__

#include <enet.h>


#define eaddrassign(p,x)   ((p)[0] = (x)[0], \
                           (p)[1] = (x)[1], \
                           (p)[2] = (x)[2], \
                           (p)[3] = (x)[3], \
                           (p)[4] = (x)[4], \
                           (p)[5] = (x)[5]  \
                          )

#define eaddriszero(p)   ( ((p)[0] == 0) && \
                           ((p)[1] == 0) && \
                           ((p)[2] == 0) && \
                           ((p)[3] == 0) && \
                           ((p)[4] == 0) && \
                           ((p)[5] == 0)    \
                          )

/*
** Function prototypes 
*/
#ifdef __cplusplus
extern "C" {
#endif

extern boolean Shell_parse_enet_address( char_ptr arg, _enet_address enet_address);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/RNG_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type RNG
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(RNG_PDD_H_)
#define RNG_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error RNG PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK52DZ10) /* RNG */ && \
      !defined(MCU_MK53DZ10) /* RNG */ && \
      !defined(MCU_MK60DZ10) /* RNG */ && \
      !defined(MCU_MK60N512VMD100) /* RNG */
  // Unsupported MCU is active
  #error RNG PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Auto-reseed constants */
#define RNG_PDD_RESEED_DISABLE 0U                /**< No automatic reseed. */
#define RNG_PDD_RESEED_ENABLE  RNG_CR_AR_MASK    /**< Automatic reseed enabled. */

/* FIFO Underflow response mode constants */
#define RNG_PDD_RET_ZERO         0U              /**< Return zero. */
#define RNG_PDD_GEN_BUS_ERROR    0x2U            /**< Generate bus error. */
#define RNG_PDD_GEN_INT_RET_ZERO 0x3U            /**< Generate interrupt and return zero. */

/* Status of RNG */
#define RNG_PDD_STATUS_ERROR          0xFFFFU    /**< Error occured. */
#define RNG_PDD_STATUS_NEW_SEED_DONE  0x40U      /**< New seed done. */
#define RNG_PDD_STATUS_SEED_DONE      0x20U      /**< Seed done. */
#define RNG_PDD_STATUS_SELF_TEST_DONE 0x10U      /**< Self-test done. */
#define RNG_PDD_STATUS_RESEED_NEEDED  0x8U       /**< Reseed needed. */
#define RNG_PDD_STATUS_SLEEP          0x4U       /**< RNG in sleep mode. */
#define RNG_PDD_STATUS_BUSY           0x2U       /**< RNG is busy. */

/* Extended error mask for status register */
#define RNG_PDD_SELF_TETS_RESEED_ERROR  0x200000U /**< Reseed error. */
#define RNG_PDD_SELF_TEST_PRNG_ERROR    0x400000U /**< PRNG error. */
#define RNG_PDD_SELF_TEST_TRNG_ERROR    0x800000U /**< TRNG error. */
#define RNG_PDD_MONOBIT_TEST_ERROR      0x1000000U /**< Monobit test error. */
#define RNG_PDD_LENGTH_1_RUN_TEST_ERROR 0x2000000U /**< Length 1 test error. */
#define RNG_PDD_LENGTH_2_RUN_TEST_ERROR 0x4000000U /**< Length 2 test error. */
#define RNG_PDD_LENGTH_3_RUN_TEST_ERROR 0x8000000U /**< Length 3 test error. */
#define RNG_PDD_LENGTH_4_RUN_TEST_ERROR 0x10000000U /**< Length 4 test error. */
#define RNG_PDD_LENGTH_5_RUN_TEST_ERROR 0x20000000U /**< Length 5 test error. */
#define RNG_PDD_LENGTH_6_RUN_TEST_ERROR 0x40000000U /**< Length 6 test error. */
#define RNG_PDD_LONG_RUN_TEST_ERROR     0x80000000U /**< Long run test error. */

/* Error mask for error status register */
#define RNG_PDD_LFSR_ERROR           0x1U        /**< LFSR error. */
#define RNG_PDD_OSCILLATOR_ERROR     0x2U        /**< Oscillator error. */
#define RNG_PDD_SELF_TEST_ERROR      0x4U        /**< Self-test error. */
#define RNG_PDD_FIFO_UNDERFLOW_ERROR 0x8U        /**< FIFO underflow error. */


/* ----------------------------------------------------------------------------
   -- EnableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables error and done interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CR.
 * @par Example:
 *      @code
 *      RNG_PDD_EnableInterrupts(deviceID);
 *      @endcode
 */
#define RNG_PDD_EnableInterrupts(PeripheralBase) ( \
    (RNG_CR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)RNG_CR_MASKERR_MASK)), \
    (RNG_CR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)RNG_CR_MASKDONE_MASK)) \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables error and done interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CR.
 * @par Example:
 *      @code
 *      RNG_PDD_DisableInterrupts(deviceID);
 *      @endcode
 */
#define RNG_PDD_DisableInterrupts(PeripheralBase) ( \
    (RNG_CR_REG(PeripheralBase) |= \
     RNG_CR_MASKERR_MASK), \
    (RNG_CR_REG(PeripheralBase) |= \
     RNG_CR_MASKDONE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetVersion
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns version of RNG module.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 16-bit value.
 * @remarks The macro accesses the following registers: RNG_VER.
 * @par Example:
 *      @code
 *      uint16_t result = RNG_PDD_GetVersion(deviceID);
 *      @endcode
 */
#define RNG_PDD_GetVersion(PeripheralBase) ( \
    (uint16_t)(RNG_VER_REG(PeripheralBase) & 0xFFFFU) \
  )

/* ----------------------------------------------------------------------------
   -- ErrorCondition
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns 1 if there is error in RNG module.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 1-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: RNG_SR.
 * @par Example:
 *      @code
 *      uint8_t result = RNG_PDD_ErrorCondition(deviceID);
 *      @endcode
 */
#define RNG_PDD_ErrorCondition(PeripheralBase) ( \
    (uint8_t)((uint32_t)(RNG_SR_REG(PeripheralBase) & RNG_SR_ERR_MASK) >> RNG_SR_ERR_SHIFT) \
  )

/* ----------------------------------------------------------------------------
   -- Busy
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns 1 if RNG is busy (generating seed, in self test mode...).
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 1-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: RNG_SR.
 * @par Example:
 *      @code
 *      uint8_t result = RNG_PDD_Busy(deviceID);
 *      @endcode
 */
#define RNG_PDD_Busy(PeripheralBase) ( \
    (uint8_t)((uint32_t)(RNG_SR_REG(PeripheralBase) & RNG_SR_BUSY_MASK) >> RNG_SR_BUSY_SHIFT) \
  )

/* ----------------------------------------------------------------------------
   -- SeedGenerated
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns 1 if the seed was generated since last reset.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 1-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: RNG_SR.
 * @par Example:
 *      @code
 *      uint8_t result = RNG_PDD_SeedGenerated(deviceID);
 *      @endcode
 */
#define RNG_PDD_SeedGenerated(PeripheralBase) ( \
    (uint8_t)((uint32_t)(RNG_SR_REG(PeripheralBase) & RNG_SR_SDN_MASK) >> RNG_SR_SDN_SHIFT) \
  )

/* ----------------------------------------------------------------------------
   -- SoftReset
   ---------------------------------------------------------------------------- */

/**
 * @brief Performs a software reset of the RNGB.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CMD.
 * @par Example:
 *      @code
 *      RNG_PDD_SoftReset(deviceID);
 *      @endcode
 */
#define RNG_PDD_SoftReset(PeripheralBase) ( \
    RNG_CMD_REG(PeripheralBase) |= \
     RNG_CMD_SR_MASK \
  )

/* ----------------------------------------------------------------------------
   -- ClearErrorAndInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears the errors in the RNG_ESR register and the RNGB interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CMD.
 * @par Example:
 *      @code
 *      RNG_PDD_ClearErrorAndInterrupts(deviceID);
 *      @endcode
 */
#define RNG_PDD_ClearErrorAndInterrupts(PeripheralBase) ( \
    (RNG_CMD_REG(PeripheralBase) |= \
     RNG_CMD_CE_MASK), \
    (RNG_CMD_REG(PeripheralBase) |= \
     RNG_CMD_CI_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClearError
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears the errors in the RNG_ESR register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CMD.
 * @par Example:
 *      @code
 *      RNG_PDD_ClearError(deviceID);
 *      @endcode
 */
#define RNG_PDD_ClearError(PeripheralBase) ( \
    RNG_CMD_REG(PeripheralBase) |= \
     RNG_CMD_CE_MASK \
  )

/* ----------------------------------------------------------------------------
   -- ClearInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears the RNGB interrupt if an error is not present.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CMD.
 * @par Example:
 *      @code
 *      RNG_PDD_ClearInterrupt(deviceID);
 *      @endcode
 */
#define RNG_PDD_ClearInterrupt(PeripheralBase) ( \
    RNG_CMD_REG(PeripheralBase) |= \
     RNG_CMD_CI_MASK \
  )

/* ----------------------------------------------------------------------------
   -- GenerateSeed
   ---------------------------------------------------------------------------- */

/**
 * @brief Initiates the seed generation process.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CMD.
 * @par Example:
 *      @code
 *      RNG_PDD_GenerateSeed(deviceID);
 *      @endcode
 */
#define RNG_PDD_GenerateSeed(PeripheralBase) ( \
    RNG_CMD_REG(PeripheralBase) |= \
     RNG_CMD_GS_MASK \
  )

/* ----------------------------------------------------------------------------
   -- SelfTest
   ---------------------------------------------------------------------------- */

/**
 * @brief Initiates a self test of the RNGB's internal logic.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CMD.
 * @par Example:
 *      @code
 *      RNG_PDD_SelfTest(deviceID);
 *      @endcode
 */
#define RNG_PDD_SelfTest(PeripheralBase) ( \
    RNG_CMD_REG(PeripheralBase) |= \
     RNG_CMD_ST_MASK \
  )

/* ----------------------------------------------------------------------------
   -- AutoReseed
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures automatic reseeding.
 * @param PeripheralBase Peripheral base address.
 * @param Reseed Determines auto-reseed function. Use constants from group
 *        "Auto-reseed constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CR.
 * @par Example:
 *      @code
 *      RNG_PDD_AutoReseed(deviceID, RNG_PDD_RESEED_DISABLE);
 *      @endcode
 */
#define RNG_PDD_AutoReseed(PeripheralBase, Reseed) ( \
    RNG_CR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(RNG_CR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)RNG_CR_AR_MASK))) | ( \
      (uint32_t)(Reseed))) \
  )

/* ----------------------------------------------------------------------------
   -- SetFIFOUnderflow
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets FIFO underflow response mode.
 * @param PeripheralBase Peripheral base address.
 * @param Mode Response mode. Use constants from group "FIFO Underflow response
 *        mode constants". This parameter is 2 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: RNG_CR.
 * @par Example:
 *      @code
 *      RNG_PDD_SetFIFOUnderflow(deviceID, RNG_PDD_RET_ZERO);
 *      @endcode
 */
#define RNG_PDD_SetFIFOUnderflow(PeripheralBase, Mode) ( \
    RNG_CR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(RNG_CR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)RNG_CR_FUFMOD_MASK))) | ( \
      (uint32_t)(Mode))) \
  )

/* ----------------------------------------------------------------------------
   -- GetFIFOUnderflow
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns FIFO underflow response mode.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: RNG_CR.
 * @par Example:
 *      @code
 *      uint32_t result = RNG_PDD_GetFIFOUnderflow(deviceID);
 *      @endcode
 */
#define RNG_PDD_GetFIFOUnderflow(PeripheralBase) ( \
    (uint32_t)(RNG_CR_REG(PeripheralBase) & RNG_CR_FUFMOD_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetStatusRegister
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the RNGB Status Register.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "Status of RNG" for processing return value.
 * @remarks The macro accesses the following registers: RNG_SR.
 * @par Example:
 *      @code
 *      uint32_t result = RNG_PDD_GetStatusRegister(deviceID);
 *      @endcode
 */
#define RNG_PDD_GetStatusRegister(PeripheralBase) ( \
    RNG_SR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetFIFOSize
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the FIFO size.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 4-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: RNG_SR.
 * @par Example:
 *      @code
 *      uint8_t result = RNG_PDD_GetFIFOSize(deviceID);
 *      @endcode
 */
#define RNG_PDD_GetFIFOSize(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(RNG_SR_REG(PeripheralBase) & RNG_SR_FIFO_SIZE_MASK)) >> ( \
     RNG_SR_FIFO_SIZE_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- GetFIFOLevel
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns FIFO level.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 4-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: RNG_SR.
 * @par Example:
 *      @code
 *      uint8_t result = RNG_PDD_GetFIFOLevel(deviceID);
 *      @endcode
 */
#define RNG_PDD_GetFIFOLevel(PeripheralBase) ( \
    (uint8_t)(( \
     (uint32_t)(RNG_SR_REG(PeripheralBase) & RNG_SR_FIFO_LVL_MASK)) >> ( \
     RNG_SR_FIFO_LVL_SHIFT)) \
  )

/* ----------------------------------------------------------------------------
   -- GetExtendedError
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the extended error from status register.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "Extended error mask for status register"
 *         for processing return value.
 * @remarks The macro accesses the following registers: RNG_SR.
 * @par Example:
 *      @code
 *      uint32_t result = RNG_PDD_GetExtendedError(deviceID);
 *      @endcode
 */
#define RNG_PDD_GetExtendedError(PeripheralBase) ( \
    (uint32_t)(RNG_SR_REG(PeripheralBase) & (uint32_t)((uint32_t)0x7FFU << 21U)) \
  )

/* ----------------------------------------------------------------------------
   -- GetErrorStatusRegister
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the RNGB Error Status Register.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "Error mask for error status register" for
 *         processing return value.
 * @remarks The macro accesses the following registers: RNG_ESR.
 * @par Example:
 *      @code
 *      uint32_t result = RNG_PDD_GetErrorStatusRegister(deviceID);
 *      @endcode
 */
#define RNG_PDD_GetErrorStatusRegister(PeripheralBase) ( \
    RNG_ESR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetOutValue
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the random data generated by the RNGB.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: RNG_OUT.
 * @par Example:
 *      @code
 *      uint32_t result = RNG_PDD_GetOutValue(deviceID);
 *      @endcode
 */
#define RNG_PDD_GetOutValue(PeripheralBase) ( \
    RNG_OUT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReseedNeeded
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns 1 if manual reseeding is required.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 1-bit value. The value is cast to "uint8_t".
 * @remarks The macro accesses the following registers: RNG_SR.
 * @par Example:
 *      @code
 *      uint8_t result = RNG_PDD_ReseedNeeded(deviceID);
 *      @endcode
 */
#define RNG_PDD_ReseedNeeded(PeripheralBase) ( \
    (uint8_t)((uint32_t)(RNG_SR_REG(PeripheralBase) & RNG_SR_RS_MASK) >> RNG_SR_RS_SHIFT) \
  )
#endif  /* #if defined(RNG_PDD_H_) */

/* RNG_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GMCLIB/GMCLIB_VectorLimit.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GMCLIB_VectorLimit.h
* 
* @author    r29302
* 
* @version   1.0.1.0
* 
* @date      Dec-6-2012
* 
* @brief     Header file for the Vector-Limit function.
*
*******************************************************************************
*
* Function impemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GMCLIB_VectorLimit_H_
#define _GMCLIB_VectorLimit_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/************************************************************************
| defines and macros (scope: module-local)
|-----------------------------------------------------------------------*/

/*! 
 * \def GMCLIB_VectorLimit(f32In, f32Out, pParam)
 * Function alias for the #GMCLIB_VectorLimitANSIC function.
 */

#define GMCLIB_VectorLimit(w32Out, w32In, pParam) \
            GMCLIB_VectorLimitANSIC((w32Out), (w32In), (pParam))
                            

/************************************************************************
| typedefs and structures (scope: module-local)
|-----------------------------------------------------------------------*/

/*------------------------------------------------------------------------*//*!
@struct     GMCLIB_VectorLimit_T "\GMCLIB_VectorLimit.h"

@brief      Structure containing the limits.

*//*-------------------------------------------------------------------------*/

typedef struct   
{
  Frac32 f32Lim;    /*!<The maximum magnitude of the input vector.  The
                         defined magnitude must be positive and equal to or
                         greater than \f$2^-15\f$.*/
} GMCLIB_VectorLimit_T;

/************************************************************************
| exported variables
|-----------------------------------------------------------------------*/

/************************************************************************
| exported function prototypes
|-----------------------------------------------------------------------*/
/*! 
* @ingroup GFLIB_GROUP 
*/

extern bool GMCLIB_VectorLimitANSIC(MCLIB_2_COOR_SYST_D_Q_T *const pOut,
                                    const MCLIB_2_COOR_SYST_D_Q_T *const pIn,
                                    const GMCLIB_VectorLimit_T *const pParam);

#ifdef __cplusplus
}
#endif

#endif /* _GMCLIB_VectorLimit_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/adc.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc.h$
* $Version : 3.8.31.1$
* $Date    : Jul-11-2012$
*
* Comments:
*
*   Generic ADC driver header file
*
*END************************************************************************/
#ifndef __adc_h__
#define __adc_h__

#if MQX_USE_LWEVENTS
    #include <lwevent.h>
#endif
/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

/* Initialization struct when opening driver */
typedef struct adc_init_struct {
   uint_32   resolution;       /* resolution of ADC driver, the bigger or equal possible value is used to configure ADC peripheral */
} ADC_INIT_STRUCT, _PTR_ ADC_INIT_STRUCT_PTR;

typedef uint_32 ADT_TRIGGER_MASK;
#define ADC_TRIGGER_1                  (0x0001)
#define ADC_TRIGGER_2                  (0x0002)
#define ADC_TRIGGER_3                  (0x0004)
#define ADC_TRIGGER_4                  (0x0008)
#define ADC_TRIGGER_5                  (0x0010)
#define ADC_TRIGGER_6                  (0x0020)
#define ADC_TRIGGER_7                  (0x0040)
#define ADC_TRIGGER_8                  (0x0080)
#define ADC_TRIGGER_9                  (0x0100)
#define ADC_TRIGGER_10                 (0x0200)
#define ADC_TRIGGER_11                 (0x0400)
#define ADC_TRIGGER_12                 (0x0800)
#define ADC_TRIGGER_13                 (0x1000)
#define ADC_TRIGGER_14                 (0x2000)
#define ADC_TRIGGER_15                 (0x4000)
#define ADC_TRIGGER_16                 (0x8000)

/* flags used to initialize every channel */
#define ADC_CHANNEL_MEASURE_LOOP       (0x00) /* measurement never ends, lwevents are set periodically during measurement */
#define ADC_CHANNEL_MEASURE_ONCE       (0x04) /* measurement ends with set lwevent */
#define ADC_CHANNEL_START_TRIGGERED    (0x02) /* after RUN on channel is set, delay is applied (trigger delay) */
#define ADC_CHANNEL_START_NOW          (0x00) /* after RUN on channel is set, no delay is applied and measurement is immediate */
#define ADC_CHANNEL_ACCUMULATE         (0x10) /* accumulate the samples into one result variable, not to the field of values */

typedef struct adc_init_channel_struct {
   uint_16   source;           /* one of ADC_SOURCE_* definitions defined in ./<module_name>/adc_<module_name>.h - CPU specific header file */
   uint_16   flags;            /* initialization flags, combination of ADC_CHANNEL_<FLAG_NAME> possibilities above */
   uint_32   number_samples;   /* the number of samples needed to trigger event */
   uint_32   time_offset;      /* the time offset applied once after measurement on given channel is started, in microseconds */
   uint_32   time_period;      /* the time slot between two samples in microseconds */
   /* NOTE: the following item is not used in the current ADC driver and is prepared to be used in the future */
   uint_32   range;            /* the range of result sample(s), NOT USED NOW */
                               /* Note #1: using ADC_CHANNEL_ACCUMULATE, you can achieve finer resolution than specified in ADC */
                               /* Note #2: The result of ADC driver always fits to the range specified here */
                               /* Note #3: if range is too low, then you lose LSbits */
                               /* Note #4: if range is too high, then you get LSbits cleared */
                               /* Note #5: range can be only a number 2^N (in C language: 1 << N) */
   _mqx_uint buffer_size;      /* ADC output buffer size, measured samples are stored here */
   ADT_TRIGGER_MASK trigger;   /* trigger mask that fires this channel */
#if MQX_USE_LWEVENTS
   LWEVENT_STRUCT_PTR complete_event; /* pointer to lwevent to be signaled after nuber_samples is measured */
   uint_32            event_mask;     /* event mask to be signalled in lwevent after nuber_samples is measured */
#endif
} ADC_INIT_CHANNEL_STRUCT, _PTR_ ADC_INIT_CHANNEL_STRUCT_PTR;

typedef uint_32 ADC_VALUE_TYPE;
typedef struct adc_result_struct {
   ADC_VALUE_TYPE   result;
} ADC_RESULT_STRUCT, _PTR_ ADC_RESULT_STRUCT_PTR;

/*
**  IOCTL commands used in ADC driver
*/
#define ADC_IOCTL_RUN_CHANNEL           _IO(IO_TYPE_ADC, 0x01)
#define ADC_IOCTL_RUN_CHANNELS          _IO(IO_TYPE_ADC, 0x02)
#define ADC_IOCTL_FIRE_TRIGGER          ADC_IOCTL_RUN_CHANNELS
#define ADC_IOCTL_STOP_CHANNEL          _IO(IO_TYPE_ADC, 0x03)
#define ADC_IOCTL_STOP_CHANNELS         _IO(IO_TYPE_ADC, 0x04)
#define ADC_IOCTL_PAUSE_CHANNEL         _IO(IO_TYPE_ADC, 0x05)
#define ADC_IOCTL_PAUSE_CHANNELS        _IO(IO_TYPE_ADC, 0x06)
#define ADC_IOCTL_RESUME_CHANNEL        _IO(IO_TYPE_ADC, 0x07)
#define ADC_IOCTL_RESUME_CHANNELS       _IO(IO_TYPE_ADC, 0x08)
#define ADC_IOCTL_HW_SPECIFIC           0x09 /* this is not valid IOCTL in fact */

/* IOCTL obsolete name convention, for backward compatibility */
#define IOCTL_ADC_RUN_CHANNEL           ADC_IOCTL_RUN_CHANNEL
#define IOCTL_ADC_RUN_CHANNELS          ADC_IOCTL_RUN_CHANNELS
#define IOCTL_ADC_FIRE_TRIGGER          ADC_IOCTL_FIRE_TRIGGER
#define IOCTL_ADC_STOP_CHANNEL          ADC_IOCTL_STOP_CHANNEL
#define IOCTL_ADC_STOP_CHANNELS         ADC_IOCTL_STOP_CHANNELS
#define IOCTL_ADC_PAUSE_CHANNEL         ADC_IOCTL_PAUSE_CHANNEL
#define IOCTL_ADC_PAUSE_CHANNELS        ADC_IOCTL_PAUSE_CHANNELS
#define IOCTL_ADC_RESUME_CHANNEL        ADC_IOCTL_RESUME_CHANNEL
#define IOCTL_ADC_RESUME_CHANNELS       ADC_IOCTL_RESUME_CHANNELS
#define IOCTL_ADC_HW_SPECIFIC           ADC_IOCTL_HW_SPECIFIC

/*
**  IOCTL error codes for IOCTLs
*/
#define ADC_OK                                        (IO_OK)
#define ADC_ERROR_ALLOC                               (ADC_ERROR_BASE | 0x01) /* memory allocation error */
#define ADC_ERROR_ISR                                 (ADC_ERROR_BASE | 0x02) /* cannot install ISR */
#define ADC_ERROR_PARAM                               (ADC_ERROR_BASE | 0x03) /* missing parameter */
#define ADC_ERROR_OPENED                              (ADC_ERROR_BASE | 0x04) /* file already opened */
#define ADC_ERROR_MISSING_DEVICE                      (ADC_ERROR_BASE | 0x05) /* device was not opened prior to channel open */
#define ADC_ERROR_BAD_PARAM                           (ADC_ERROR_BASE | 0x06) /* bad parameter */
#define ADC_ERROR_FULL                                (ADC_ERROR_BASE | 0x07) /* cannot open more files */
#define ADC_ERROR_NONEMPTY                            (ADC_ERROR_BASE | 0x08) /* cannot run command if channel is still opened */
#define ADC_ERROR_ONLY_DEVICE                         (ADC_ERROR_BASE | 0x09) /* cannot run such command on channel */
#define ADC_ERROR_ONLY_CHANNEL                        (ADC_ERROR_BASE | 0x0A) /* cannot run such command on device */
#define ADC_ERROR_HW_SPECIFIC                         0x0B /* this is not valid error in fact */


#if PSP_MQX_CPU_IS_MCF51JF || PSP_MQX_CPU_IS_MCF51QM || PSP_MQX_CPU_IS_KINETIS
    #include "adc_kadc.h"
#elif PSP_MQX_CPU_IS_MCF5222X || PSP_MQX_CPU_IS_MCF5223X || PSP_MQX_CPU_IS_MCF5225X
    #include "adc_mcf522xx.h"
#elif PSP_MQX_CPU_IS_MCF51EM
    #include "adc_mcf51em.h"
#elif PSP_MQX_CPU_IS_MCF51MM
    #include "adc_mcf51mm.h"
#elif PSP_MQX_CPU_IS_MCF51JE
    #include "adc_mcf51je.h"
#elif PSP_MQX_CPU_IS_MCF51AG
    #include "adc_mcf51ag.h"
#elif PSP_MQX_CPU_IS_MCF51
    #include "adc_mcf51xx.h"
#elif PSP_MQX_CPU_IS_MCF5441X
    #include "adc_mcf544xx.h"
#else
  #error ADC device driver not supported for processor.
#endif


_mqx_uint _io_adc_install(char_ptr, pointer);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/config/common/maximum_config.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 20089 Embedded Access Inc.;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: maximum_config.h$
* $Version : 3.8.5.0$
* $Date    : Aug-30-2011$
*
* Comments:
*
*   Smallest configuration for MQX components
*
*END************************************************************************/


#ifndef __maximum_config_h__
#define __maximum_config_h__

/* 
** When MQX_CHECK_ERRORS is defined as 1, 
** kernel functions will perform error checking on their parameters.
*/
#ifndef MQX_CHECK_ERRORS
#define MQX_CHECK_ERRORS 1
#endif


/* 
** When MQX_CHECK_MEMORY_ALLOCATION_ERRORS is defined as 1, 
** kernel functions will check all memory allocations for errors. 
** The functions will verify that the memory allocation 
** was successful.
*/
#ifndef MQX_CHECK_MEMORY_ALLOCATION_ERRORS
#define MQX_CHECK_MEMORY_ALLOCATION_ERRORS 1
#endif


/* 
** When MQX_CHECK_VALIDITY is defined as 1, 
** kernel functions will check the the VALIDITY fields of structures
** as they are accessed.
*/
#ifndef MQX_CHECK_VALIDITY
#define MQX_CHECK_VALIDITY 1
#endif


/* 
** When MQX_COMPONENT_DESTRUCTION is defined as 1,
** the kernel will handle the destruction of a kernel component object
** (such as a semaphore or event)
*/
#ifndef MQX_COMPONENT_DESTRUCTION
#define MQX_COMPONENT_DESTRUCTION 1
#endif


/* 
** When MQX_IO_COMPONENT_DESTRUCTION is defined as 1,
** the kernel will handle the destruction of an IO component object
*/
#ifndef MQX_IO_COMPONENT_DESTRUCTION
#define MQX_IO_COMPONENT_DESTRUCTION 1
#endif


/*
** When MQX_DEFAULT_TIME_SLICE_IN_TICKS is define as 1,
** then the default time slice in the task template structure
** is in units of ticks. Changing this to 0 will change the units
** to milliseconds. This also affects the time slice field in the
** task template since this is used to set a task's default time
** slice.
*/
#ifndef MQX_DEFAULT_TIME_SLICE_IN_TICKS
#define MQX_DEFAULT_TIME_SLICE_IN_TICKS  0
#endif


/* 
** When MQX_EXIT_ENABLED is defined as 1,
** code is compiled in to allow the application to return from _mqx().
*/
#ifndef MQX_EXIT_ENABLED
#define MQX_EXIT_ENABLED 1
#endif


/*
** When MQX_EXTRA_TASK_STACK_ENABLE is defined as 1,
** code is compiled in to reserve extra memory at the top of stack 
** in every task, if desired. Both "OS Changer" and the MetaWare C/C++
** runtime want additional per-task variables.
*/
#ifndef MQX_EXTRA_TASK_STACK_ENABLE
#define MQX_EXTRA_TASK_STACK_ENABLE 1
#endif


/* 
** When MQX_HAS_TIME_SLICE is defined as 1,
** then code is compiled in to support time sliced tasks.
*/
#ifndef MQX_HAS_TIME_SLICE
#define MQX_HAS_TIME_SLICE 1
#endif


/* 
** When MQX_INCLUDE_FLOATING_POINT_IO is defined as 1,
** _io_printf and _io_scanf will include floating point I/O code.
*/
#ifndef MQX_INCLUDE_FLOATING_POINT_IO
#define MQX_INCLUDE_FLOATING_POINT_IO 1
#endif


/* 
** When MQX_IS_MULTI_PROCESSOR is defined as 1,
** then code is compiled in to support multiple processor MQX systems.
*/
#ifndef MQX_IS_MULTI_PROCESSOR
#define MQX_IS_MULTI_PROCESSOR 1
#endif


/* 
** When MQX_KERNEL_LOGGING is defined as 1, 
** calls to write to the kernel log will be added to some kernel functions at 
** function entry (with parameters) and function exit (with error codes).
**
** The MQX functions that have logging compiled in will run slower, however
** it is only when the logging is enabled for the function that performance
** will be affected.
**
** The logging of specific functions can be controlled using the 
** _klog_control function.
**
** The default value of this define is dependent upon the PSP. Please see
** source\psp\<psp src dir>\psptypes.h
*/
#ifndef MQX_KERNEL_LOGGING
#define MQX_KERNEL_LOGGING   1
#endif


/*
** When MQX_LWLOG_TIME_STAMP_IN_TICKS is define as 0,
** then the time stamp in the light weight log component
** is in seconds, milliseconds, and microseconds. Changing this
** to 1 will causes the time stamp to be in ticks which is not
** as readable, but has much less overhead.
*/
#ifndef MQX_LWLOG_TIME_STAMP_IN_TICKS
#define MQX_LWLOG_TIME_STAMP_IN_TICKS  0
#endif


/* 
** When MQX_MEMORY_FREE_LIST_SORTED is defined as 1,
** then the free memory blocks are stored in order of address
** to reduce fragmentation. This can increase memory freeing time
** and code size
*/
#ifndef MQX_MEMORY_FREE_LIST_SORTED
#define MQX_MEMORY_FREE_LIST_SORTED   1
#endif


/*
** When MQX_MONITOR_STACK is defined as 1,
** the kernel will fill all stacks with a known value when the stack is 
** initialized.
** This allows utility software and debuggers to calculate how much of the 
** stack has been used.  This will only have an impact at task creation time.
*/
#ifndef MQX_MONITOR_STACK
#define MQX_MONITOR_STACK 1
#endif


/* 
** When MQX_MUTEX_HAS_POLLING is defined as 1,
** then extra code will be compiled in to support the
** mutex options: MUTEX_SPIN_ONLY and MUTEX_LIMITED_SPIN
*/
#ifndef MQX_MUTEX_HAS_POLLING
#define MQX_MUTEX_HAS_POLLING 1
#endif


/* 
** When MQX_PROFILING_ENABLE is defined as 1,
** code to support an external profiling tool will be compiled into the kernel
** Profiling will add to the size of the compiled image, and it will run slower
**
** Note: You can only use profiling if the toolset being used supports it
**
** The setting of this define must be the same as the definition by the same name,
** in source\psp\<psp>\psp_cnfg.<comp>
*/
#ifndef MQX_PROFILING_ENABLE
#define MQX_PROFILING_ENABLE 1
#endif


/* 
** When MQX_RUN_TIME_ERR_CHECK_ENABLE is defined as 1,
** code to support an external run-time error checking tool will be compiled
** into the kernel.  This will add to the size of the compiled image,
** and will cause MQX to run slower
**
** Note: You can only use run time error checking if the toolset being used 
**       supports it
**
** The setting of this define must be the same as the definition by the same name,
** in source\psp\<psp>\psp_cnfg.<comp>
*/
#ifndef MQX_RUN_TIME_ERR_CHECK_ENABLE
#define MQX_RUN_TIME_ERR_CHECK_ENABLE 1
#endif

#ifndef MQX_THREAD_LOCAL_STORAGE_ENABLE
#define MQX_THREAD_LOCAL_STORAGE_ENABLE 1
#endif

#ifndef MQX_TAD_RESERVED_ENABLE
#define MQX_TAD_RESERVED_ENABLE 1
#endif

/* 
** When MQX_TASK_CREATION_BLOCKS is defined as 1, 
** the creating task will be suspended when _task_create is called for a task 
** residing on a different processor.
**
** The creator task will be suspended until the target task is created, 
** and an error code is returned.
*/
#ifndef MQX_TASK_CREATION_BLOCKS
#define MQX_TASK_CREATION_BLOCKS 1
#endif


/* 
** When MQX_TASK_DESTRUCTION is defined as 1,
** the kernel will allow for the destruction of tasks,
** releasing all resources owned by the task when it is destroyed.
** (memory, events, semaphores, mutexes etc.)
*/
#ifndef MQX_TASK_DESTRUCTION
#define MQX_TASK_DESTRUCTION 1
#endif


/* 
** When MQX_TIMER_USES_TICKS_ONLY, the timer task will *only* process
** timer periodic and one-shot requests using ticks for timeout
** reporting, rather than the MQX2.40 milliseconds/seconds.
*/
#ifndef MQX_TIMER_USES_TICKS_ONLY
#define MQX_TIMER_USES_TICKS_ONLY 1
#endif


/* 
** When MQX_USE_32BIT_MESSAGE_QIDS is defined as 1,
** the message component datatypes (_queue_numbe & _queue_id) will be uint_32s 
** wide instead of uint_16s.
** This will allow for more than 256 message queues on a cpu, and
** more than 256 processors in a multi-processor network.
*/
#ifndef MQX_USE_32BIT_MESSAGE_QIDS
#define MQX_USE_32BIT_MESSAGE_QIDS 0
#endif


/* 
** When MQX_USE_32BIT_TYPES is defined as 1, the kernel will be forced
** to 32 bit mode regardless of the natural size of the processor. This will
** reduce the number of warning generated by the compiler when linking 2.4x
** applications against versio 2.5x of MQX.
*/
#ifndef MQX_USE_32BIT_TYPES
#define MQX_USE_32BIT_TYPES 0
#endif


/* 
** When MQX_USE_EVENTS is defined as 1,
** then mqx will compile in the support code for event component.
*/
#ifndef MQX_USE_EVENTS
#define MQX_USE_EVENTS 1
#endif


/* 
** When MQX_USE_IDLE_TASK is defined as 1,
** the kernel will create the idle task otherwise, no actual
** task will run when one is not ready to run.
*/
#ifndef MQX_USE_IDLE_TASK
#define MQX_USE_IDLE_TASK 1
#endif


/* 
** When MQX_USE_IPC is defined as 1,
** then mqx will compile in the support code for Interprocessor communication.
*/
#ifndef MQX_USE_IPC
#define MQX_USE_IPC 1
#endif


/* 
** When MQX_USE_INLINE_MACROS is defined as 1,
** certain internal utility functions called by MQX will
** be made "inline" rather than by function calls.  This allows the user
** to optimize for time or code space.  Inlining optimizes for time,
** not inlining optimizes for space.
*/
#ifndef MQX_USE_INLINE_MACROS
#define MQX_USE_INLINE_MACROS 1
#endif


/* 
** When MQX_USE_LWEVENTS is defined as 1,
** then mqx will compile in the support code for light weight event component.
*/
#ifndef MQX_USE_LWEVENTS
#define MQX_USE_LWEVENTS 1
#endif


/* 
** When MQX_USE_LOGS is defined as 1,
** then mqx will compile in the support code for log component.
*/
#ifndef MQX_USE_LOGS
#define MQX_USE_LOGS 1
#endif


/* 
** When MQX_USE_LWLOGS is defined as 1,
** then mqx will compile in the support code for light weight log component.
*/
#ifndef MQX_USE_LWLOGS
#define MQX_USE_LWLOGS 1
#endif

/* 
** When MQX_USE_LWMEM_ALLOCATOR is defined as 1,
** then mqx will use the light weight memory functions
** to allocate and free memory 
*/
#ifndef MQX_USE_LWMEM_ALLOCATOR
#define MQX_USE_LWMEM_ALLOCATOR 0
#endif

/* 
** When MQX_USE_LWMEM is defined as 1,
** then mqx will compile in the support code for light weight memory component.
*/
#ifndef MQX_USE_LWMEM
#define MQX_USE_LWMEM 1
#endif


/* 
** When MQX_USE_MEM is defined as 1,
** then mqx will compile in the support code for memory component.
*/
#ifndef MQX_USE_MEM
    #if MQX_USE_LWMEM_ALLOCATOR
        #define MQX_USE_MEM         0
    #else
        #define MQX_USE_MEM         1
    #endif
#endif

/* 
** When MQX_USE_UNCACHED_MEM is defined as 1,
** then mqx will compile with support for uncached memory allocation.
*/
#ifndef MQX_USE_UNCACHED_MEM
#define MQX_USE_UNCACHED_MEM         1
#endif 

/* 
** When MQX_USE_LWMSGQ is defined as 1,
** then mqx will compile in the support code for light weight message queues.
*/
#ifndef MQX_USE_LWMSGQ
#define MQX_USE_LWMSGQ 1
#endif


/* 
** When MQX_USE_LWTIMER is defined as 1,
** then mqx will compile in the support code for light weight timers.
*/
#ifndef MQX_USE_LWTIMER
#define MQX_USE_LWTIMER 1
#endif


/* 
** When MQX_USE_MESSAGES is defined as 1,
** then mqx will compile in the support code for messages.
*/
#ifndef MQX_USE_MESSAGES
#define MQX_USE_MESSAGES 1
#endif


/* 
** When MQX_USE_MUTEXES is defined as 1,
** then mqx will compile in the support code for mutex component.
*/
#ifndef MQX_USE_MUTEXES
#define MQX_USE_MUTEXES 1
#endif


/* 
** When MQX_USE_NAME is defined as 1,
** then mqx will compile in the support code for name component.
*/
#ifndef MQX_USE_NAME
#define MQX_USE_NAME 1
#endif


/* 
** When MQX_USE_PARTITIONS is defined as 1,
** then mqx will compile in the support code for memory with fixed-size blocks.
*/
#ifndef MQX_USE_PARTITIONS
#define MQX_USE_PARTITIONS 1
#endif


/* 
** When MQX_USE_SEMAPHORES is defined as 1,
** then mqx will compile in the support code for Semaphores
*/
#ifndef MQX_USE_SEMAPHORES
#define MQX_USE_SEMAPHORES 1
#endif


/* 
** When MQX_USE_SW_WATCHDOGS is defined as 1,
** then mqx will compile in the support code for software watchdog timers.
*/
#ifndef MQX_USE_SW_WATCHDOGS
#define MQX_USE_SW_WATCHDOGS 1
#endif


/* 
** When MQX_USE_TIMER is defined as 1,
** then mqx will compile in the support code for timer component.
*/
#ifndef MQX_USE_TIMER
#define MQX_USE_TIMER 1
#endif


/* 
** When MQX_VERIFY_KERNEL_DATA is defined as 1,
** then mqx will perform a memory check at startup to
** verify it can correcly read and write kernel memory.
*/
#ifndef MQX_VERIFY_KERNEL_DATA
#define MQX_VERIFY_KERNEL_DATA 1
#endif


/* 
** When MQX_ALLOW_TYPED_MEMORY is defined as 1,
** then mqx will include code that allows types memory blocks
*/
#ifndef MQX_ALLOW_TYPED_MEMORY
#define MQX_ALLOW_TYPED_MEMORY 1
#endif

/* Set _mem_alloc_align mode - default is 0.
** 0 create free mem block before allocated block for alignment.
** 1 resize previous used block for alignment.
*/
#ifndef MQX_ALLOC_ALLIGN_RESIZE
#define MQX_ALLOC_ALLIGN_RESIZE 0
#endif

#ifndef MQX_ROM_VECTORS
#define MQX_ROM_VECTORS 1
#endif

#ifndef MQX_SPARSE_ISR_TABLE
#define MQX_SPARSE_ISR_TABLE 0
#endif

#ifndef MQX_GUERRILLA_INTERRUPTS_EXIST
#define MQX_GUERRILLA_INTERRUPTS_EXIST  0
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/rtos/mqx/mqx_dll.h<|end_filename|>
#ifndef __mqx_dll_h__
#define __mqx_dll_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mqx_dll.h$
* $Version : 3.8.3.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   Doubly-linked list library header file
*
*END************************************************************************/

#include "mqx.h"

typedef struct mqx_dll_node
{
   struct mqx_dll_node _PTR_ next_ptr;
   struct mqx_dll_node _PTR_ prev_ptr;
} MQX_DLL_NODE, _PTR_ MQX_DLL_NODE_PTR;

typedef struct mqx_dll_list
{
   struct mqx_dll_node _PTR_ head_ptr;
   struct mqx_dll_node _PTR_ tail_ptr;
} MQX_DLL_LIST, _PTR_ MQX_DLL_LIST_PTR;

#define _mqx_dll_get_next_node(node_ptr, next_ptr_ptr)   (*(next_ptr_ptr) = (node_ptr)->next_ptr)
#define _mqx_dll_get_prev_node(node_ptr, prev_ptr_ptr)   (*(prev_ptr_ptr) = (node_ptr)->prev_ptr)
#define _mqx_dll_get_head_node(list_ptr, head_ptr_ptr)   (*(head_ptr_ptr) = (list_ptr)->head_ptr)
#define _mqx_dll_get_tail_node(list_ptr, tail_ptr_ptr)   (*(tail_ptr_ptr) = (list_ptr)->tail_ptr)

#define _mqx_dll_is_list_empty(list_ptr)                 ((list_ptr)->head_ptr == 0)
#define _mqx_dll_is_head_node(list_ptr, node_ptr)        ((node_ptr) == (list_ptr)->head_ptr)
#define _mqx_dll_is_tail_node(list_ptr, node_ptr)        ((node_ptr) == (list_ptr)->tail_ptr)
#define _mqx_dll_is_next_node(node_ptr, next_ptr)        ((next_ptr) == (node_ptr)->next_ptr)
#define _mqx_dll_is_prev_node(node_ptr, prev_ptr)        ((prev_ptr) == (node_ptr)->prev_ptr)

#ifdef __cplusplus
extern "C" {
#endif

void _mqx_dll_node_init
(
   MQX_DLL_NODE_PTR node_ptr
);

void _mqx_dll_list_init
(
   MQX_DLL_LIST_PTR list_ptr
);

void _mqx_dll_insert_at_head
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr
);

void _mqx_dll_insert_at_tail
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr
);

void _mqx_dll_insert_after_node
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr,
   MQX_DLL_NODE_PTR next_ptr
);

void _mqx_dll_insert_before_node
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr,
   MQX_DLL_NODE_PTR prev_ptr
);

void _mqx_dll_remove_node
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr
);

void _mqx_dll_create_sublist
(
   MQX_DLL_LIST_PTR  list_ptr,
   MQX_DLL_NODE_PTR  sublist_head_ptr,
   MQX_DLL_NODE_PTR  sublist_tail_ptr,
   MQX_DLL_LIST_PTR  sublist_ptr
);

void _mqx_dll_insert_sublist_at_tail
(
   MQX_DLL_LIST_PTR  sublist_ptr,
   MQX_DLL_LIST_PTR  list_ptr
);

void _mqx_dll_insert_sublist_at_head
(
   MQX_DLL_LIST_PTR  sublist_ptr,
   MQX_DLL_LIST_PTR  list_ptr
);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Lut1D.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Lut1D.h
*
* @author   r29302
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
* 
* @brief    Header file for the #GFLIB_Lut1D function. 
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GFLIB_LUT1D_H
#define _GFLIB_LUT1D_H

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/

/*! Function alias for the #GFLIB_Lut1DANSIC function.*/
#define GFLIB_Lut1D(x, pParam) GFLIB_Lut1DANSIC((x), (pParam))

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_LUT1D_T "\GFLIB_Lut1D.h"

@brief  Structure containing  look-up table parameters.
*//*-------------------------------------------------------------------------*/
typedef struct {
	Word32 w32ShamOffset;   /*!<Shift amount for extracting the fractional offset
                              within an interpolated interval. */
	Word32 w32ShamIntvl;    /*!<Shift amount for extracting the interval index
                              of an interpolated interval. */
    const Frac32 *pf32Table;   /*!<Table holding ordinate values of
                              interpolating intervals. */
} GFLIB_LUT1D_T;

/******************************************************************************
* Exported Variables
******************************************************************************/

/******************************************************************************
* Exported function prototypes
******************************************************************************/

/*! 
* @ingroup GFLIB_GROUP 
*/ 

extern Frac32 GFLIB_Lut1DANSIC(Frac32 f32In,
                        const GFLIB_LUT1D_T *const pParam);

/******************************************************************************
* Inline functions
******************************************************************************/

#endif /* _GFLIB_LUT1D_H */


<|start_filename|>Firmware/Inverter_firmware/mcc/source/mcc_api.c<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2013 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************
* $FileName: mcc_api.c$
* $Version : 3.8.1.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This file contains MCC library API functions implementation
*
*END************************************************************************/

#include <string.h>
#include "mcc_config.h"
#include "mcc_common.h"
#include "mcc_api.h"

#if (MCC_OS_USED == MCC_MQX)
#include "mcc_mqx.h"
extern LWEVENT_STRUCT lwevent_buffer_queued[MCC_MQX_LWEVENT_COMPONENTS_COUNT];
extern LWEVENT_STRUCT lwevent_buffer_freed;
#endif

const char * const init_string    = MCC_INIT_STRING;
const char * const version_string = MCC_VERSION_STRING;

/*!
 * \brief This function initializes the Multi Core Communication subsystem for a given node.
 *
 * This function should only be called once per node (once in MQX, once per process in Linux).
 *
 * \param[in] node Node number that will be used in endpoints created by this process.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 * \return MCC_ERR_INT (interrupt registration error)
 *
 * \see mcc_destroy
 * \see MCC_BOOKEEPING_STRUCT
 */
int mcc_initialize(MCC_NODE node)
{
    int i,j = 0;
    int return_value = MCC_SUCCESS;
    MCC_SIGNAL tmp_signals_received = {(MCC_SIGNAL_TYPE)0, (MCC_CORE)0, (MCC_NODE)0, (MCC_PORT)0};

#if (MCC_OS_USED == MCC_MQX)
    for(i=0; i<MCC_MQX_LWEVENT_COMPONENTS_COUNT; i++) {
        _lwevent_create(&lwevent_buffer_queued[i],0);
    }
    _lwevent_create(&lwevent_buffer_freed,0);
#endif

    /* Initialize synchronization module */
    return_value = mcc_init_semaphore(MCC_SHMEM_SEMAPHORE_NUMBER);
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Register CPU-to-CPU interrupt for inter-core signaling */
    //mcc_register_cpu_to_cpu_isr(MCC_CORE0_CPU_TO_CPU_VECTOR);
    return_value = mcc_register_cpu_to_cpu_isr();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Initialize the bookeeping structure */
    bookeeping_data = (MCC_BOOKEEPING_STRUCT *)MCC_BASE_ADDRESS;
    MCC_DCACHE_INVALIDATE_MLINES(bookeeping_data, sizeof(MCC_BOOKEEPING_STRUCT));
    if(strcmp(bookeeping_data->init_string, init_string) != 0) {

        /* Zero it all - no guarantee Linux or uboot didnt touch it before it was reserved */
        _mem_zero((void*) bookeeping_data, (_mem_size) sizeof(struct mcc_bookeeping_struct));

        /* Set init_string in case it has not been set yet by another core */
        mcc_memcpy((void*)init_string, bookeeping_data->init_string, (unsigned int)sizeof(bookeeping_data->init_string));

        /* Set version_string */
        mcc_memcpy((void*)version_string, bookeeping_data->version_string, (unsigned int)sizeof(bookeeping_data->version_string));

        /* Initialize the free list */
        bookeeping_data->free_list.head = &bookeeping_data->r_buffers[0];
        bookeeping_data->free_list.tail = &bookeeping_data->r_buffers[MCC_ATTR_NUM_RECEIVE_BUFFERS-1];

        /* Initialize receive buffers */
        for(i=0; i<MCC_ATTR_NUM_RECEIVE_BUFFERS-1; i++) {
            bookeeping_data->r_buffers[i].next = &bookeeping_data->r_buffers[i+1];
        }
        bookeeping_data->r_buffers[MCC_ATTR_NUM_RECEIVE_BUFFERS-1].next = null;

        /* Initialize signal queues */
        for(i=0; i<MCC_NUM_CORES; i++) {
            for(j=0; j<MCC_MAX_OUTSTANDING_SIGNALS; j++) {
                bookeeping_data->signals_received[i][j] = tmp_signals_received;
            }
            bookeeping_data->signal_queue_head[i] = 0;
            bookeeping_data->signal_queue_tail[i] = 0;
        }

        /* Mark all endpoint ports as free */
        for(i=0; i<MCC_ATTR_MAX_RECEIVE_ENDPOINTS; i++) {
            bookeeping_data->endpoint_table[i].endpoint.port = MCC_RESERVED_PORT_NUMBER;
        }
    }
    MCC_DCACHE_FLUSH_MLINES(bookeeping_data, sizeof(MCC_BOOKEEPING_STRUCT));
    return return_value;
}

/*!
 * \brief This function de-initializes the Multi Core Communication subsystem for a given node.
 *
 * The function frees all resources of the node. Deletes all endpoints and frees any buffers that may have been queued there.
 *
 * \param[in] node Node number to be deinitialized.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 *
 * \see mcc_initialize
 */
int mcc_destroy(MCC_NODE node)
{
    int i = 0, return_value;

#if (MCC_OS_USED == MCC_MQX)
    for(i=0; i<MCC_MQX_LWEVENT_COMPONENTS_COUNT; i++) {
        _lwevent_destroy(&lwevent_buffer_queued[i]);
    }
    _lwevent_destroy(&lwevent_buffer_freed);
#endif

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* All endpoints of the particular node have to be removed from the endpoint table */
    MCC_DCACHE_INVALIDATE_MLINES(&bookeeping_data->endpoint_table[0], MCC_ATTR_MAX_RECEIVE_ENDPOINTS * sizeof(MCC_ENDPOINT_MAP_ITEM));
    for(i = 0; i < MCC_ATTR_MAX_RECEIVE_ENDPOINTS; i++) {
        if (bookeeping_data->endpoint_table[i].endpoint.node == node) {
            /* Remove the endpoint from the table */
            mcc_remove_endpoint(bookeeping_data->endpoint_table[i].endpoint);
        }
    }

    /* Semaphore-protected section end */
    return_value = mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Deinitialize synchronization module */
    mcc_deinit_semaphore(MCC_SHMEM_SEMAPHORE_NUMBER);

    return return_value;
}

/*!
 * \brief This function creates an endpoint.
 *
 * The function creates an endpoint on the local node with the specified port number.
 * The core and node provided in the endpoint must match the caller's core and
 * node, and the port argument must match the endpoint port.
 *
 * \param[out] endpoint Pointer to the endpoint triplet to be created.
 * \param[in] port Port number.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_NOMEM (maximum number of endpoints exceeded)
 * \return MCC_ERR_ENDPOINT (invalid value for port or endpoint already registered)
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 *
 * \see mcc_destroy_endpoint
 * \see MCC_ENDPOINT
 */
int mcc_create_endpoint(MCC_ENDPOINT *endpoint, MCC_PORT port)
{
    int return_value = MCC_SUCCESS;

    /* Fill the endpoint structure */
    endpoint->core = (MCC_CORE)MCC_CORE_NUMBER;
    endpoint->node = (MCC_NODE)MCC_MQX_NODE_NUMBER;
    endpoint->port = (MCC_PORT)port;

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Add new endpoint data into the book-keeping structure */
    return_value = mcc_register_endpoint(*endpoint);
    if(return_value != MCC_SUCCESS) {
        mcc_release_semaphore();
        return return_value;
    }

    /* Semaphore-protected section end */
    return_value =  mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    return return_value;
}

/*!
 * \brief This function destroys an endpoint.
 *
 * The function destroys an endpoint on the local node and frees any buffers that may be queued.
 *
 * \param[in] endpoint Pointer to the endpoint triplet to be deleted.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_ENDPOINT (the endpoint doesn't exist)
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 *
 * \see mcc_create_endpoint
 * \see MCC_ENDPOINT
 */
int mcc_destroy_endpoint(MCC_ENDPOINT *endpoint)
{
    int return_value = MCC_SUCCESS;

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
	if(return_value != MCC_SUCCESS)
        return return_value;

    /* Add new endpoint data into the book-keeping structure */
    return_value = mcc_remove_endpoint(*endpoint);
    if(return_value != MCC_SUCCESS) {
        mcc_release_semaphore();
        return return_value;
    }

    /* Semaphore-protected section end */
    return_value =  mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    return return_value;
}

/*!
 * \brief This function sends a message to an endpoint.
 *
 * The message is copied into the MCC buffer and the destination core is signaled.
 *
 * \param[in] endpoint Pointer to the receiving endpoint to send to.
 * \param[in] msg Pointer to the message to be sent.
 * \param[in] msg_size Size of the message to be sent in bytes.
 * \param[in] timeout_us Timeout, in microseconds, to wait for a free buffer. A value of 0 means don't wait (non-blocking call). A value of 0xffffffff means wait forever (blocking call).
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_ENDPOINT (the endpoint does not exist)
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 * \return MCC_ERR_INVAL (the msg_size exceeds the size of a data buffer)
 * \return MCC_ERR_TIMEOUT (timeout exceeded before a buffer became available)
 * \return MCC_ERR_NOMEM (no free buffer available and timeout_us set to 0)
 * \return MCC_ERR_SQ_FULL (signal queue is full)
 *
 * \see mcc_recv_copy
 * \see mcc_recv_nocopy
 * \see MCC_ENDPOINT
 */
int mcc_send(MCC_ENDPOINT *endpoint, void *msg, MCC_MEM_SIZE msg_size, unsigned int timeout_us)
{
    int return_value, end_time_set_flag = 0;
    MCC_RECEIVE_LIST *list;
    MCC_RECEIVE_BUFFER * buf;
    MCC_SIGNAL affiliated_signal;
#if (MCC_OS_USED == MCC_MQX)
    unsigned int time_us_tmp;
    MQX_TICK_STRUCT tick_time;
#endif

    /* Check if the size of the message to be sent does not exceed the size of the mcc buffer */
    if(msg_size > sizeof(bookeeping_data->r_buffers[0].data)) {
        return MCC_ERR_INVAL;
    }

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Dequeue the buffer from the free list */
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->free_list, sizeof(MCC_RECEIVE_LIST*));
    buf = mcc_dequeue_buffer(&bookeeping_data->free_list);

    while(buf == null) {
        mcc_release_semaphore();

        /* Non-blocking call */
        if(timeout_us == 0) {
            return MCC_ERR_NOMEM;
        }
        /* Blocking calls: CPU-to-CPU ISR sets the event and thus resumes tasks waiting for a free MCC buffer.
         * As the interrupt request is send to all cores when a buffer is freed it could happen that several
         * tasks from different cores/nodes are waiting for a free buffer and all of them are notified that the buffer
         * has been freed. This function has to check (after the wake up) that a buffer is really available and has not been already
         * grabbed by another "competitor task" that has been faster. If so, it has to wait again for the next notification. */
        /* wait forever */
        else if(timeout_us == 0xFFFFFFFF) {
#if (MCC_OS_USED == MCC_MQX)
            _lwevent_wait_ticks(&lwevent_buffer_freed, 1, TRUE, 0);
            _lwevent_clear(&lwevent_buffer_freed, 1);
#endif
        }
        /* timeout_us > 0 */
        else {
#if (MCC_OS_USED == MCC_MQX)
            if(!end_time_set_flag) {
                _time_get_ticks(&tick_time);
                _time_add_usec_to_ticks(&tick_time, timeout_us);
                end_time_set_flag = 1;
            }
            return_value = _lwevent_wait_until(&lwevent_buffer_freed, 1, TRUE, &tick_time);
            if(return_value == LWEVENT_WAIT_TIMEOUT) {
                /* Buffer not dequeued before the timeout */
                return MCC_ERR_TIMEOUT;
            }
            _lwevent_clear(&lwevent_buffer_freed, 1);
#endif
        }
        MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->free_list, sizeof(MCC_RECEIVE_LIST*));
        mcc_get_semaphore();
        buf = mcc_dequeue_buffer(&bookeeping_data->free_list);
    }

    /* Semaphore-protected section end */
    mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Copy the message into the MCC receive buffer */
    mcc_memcpy(msg, (void*)buf->data, (unsigned int)msg_size);
    MCC_DCACHE_FLUSH_MLINES((void*)buf->data, msg_size);
    buf->data_len = msg_size;
    MCC_DCACHE_FLUSH_MLINES((void*)&buf->data_len, sizeof(MCC_MEM_SIZE));

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Get list of buffers kept by the particular endpoint */
    list = mcc_get_endpoint_list(*endpoint);

    if(list == null) {
        /* The endpoint does not exists (has not been registered so far),
         free the buffer and return immediately - error */
        /* Enqueue the buffer back into the free list */
        MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->free_list, sizeof(MCC_RECEIVE_LIST*));
        mcc_queue_buffer(&bookeeping_data->free_list, buf);
      
        mcc_release_semaphore();
        return MCC_ERR_ENDPOINT;
    }

    /* Write the signal type into the signal queue of the particular core */
    affiliated_signal.type = BUFFER_QUEUED;
    affiliated_signal.destination = *endpoint;
    return_value = mcc_queue_signal(endpoint->core, affiliated_signal);
    if(return_value != MCC_SUCCESS) {
        /* Signal queue is full, free the buffer and return immediately - error */
        MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->free_list, sizeof(MCC_RECEIVE_LIST*));
        mcc_queue_buffer(&bookeeping_data->free_list, buf);

        mcc_release_semaphore();
        return return_value;
    }

    /* Enqueue the buffer into the endpoint buffer list */
    mcc_queue_buffer(list, buf);

    /* Semaphore-protected section end */
    mcc_release_semaphore();

    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Signal the other core by generating the CPU-to-CPU interrupt */
    return_value = mcc_generate_cpu_to_cpu_interrupt();

    return return_value;
}

/*!
 * \brief This function receives a message from the specified endpoint if one is available.
 *        The data will be copied from the receive buffer into the user supplied buffer.
 *
 * This is the "receive with copy" version of the MCC receive function. This version is simple
 * to use but it requires copying data from shared memory into the user space buffer.
 * The user has no obligation or burden to manage the shared memory buffers.
 *
 * \param[in] endpoint Pointer to the receiving endpoint to receive from.
 * \param[in] buffer Pointer to the user-app. buffer where data will be copied into.
 * \param[in] buffer_size The maximum number of bytes to copy.
 * \param[out] recv_size Pointer to an MCC_MEM_SIZE that will contain the number of bytes actually copied into the buffer.
 * \param[in] timeout_us Timeout, in microseconds, to wait for a free buffer. A value of 0 means don't wait (non-blocking call). A value of 0xffffffff means wait forever (blocking call).
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_ENDPOINT (the endpoint does not exist)
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 * \return MCC_ERR_TIMEOUT (timeout exceeded before a new message came)
 *
 * \see mcc_send
 * \see mcc_recv_nocopy
 * \see MCC_ENDPOINT
 */
int mcc_recv_copy(MCC_ENDPOINT *endpoint, void *buffer, MCC_MEM_SIZE buffer_size, MCC_MEM_SIZE *recv_size, unsigned int timeout_us)
{
    MCC_RECEIVE_LIST *list;
    MCC_RECEIVE_BUFFER * buf;
    MCC_SIGNAL affiliated_signal;
    MCC_ENDPOINT tmp_destination = {(MCC_CORE)0, (MCC_NODE)0, (MCC_PORT)0};
    int return_value, i = 0;
#if (MCC_OS_USED == MCC_MQX)
    unsigned int time_us_tmp;
    unsigned int lwevent_index = endpoint->port / MCC_MQX_LWEVENT_GROUP_SIZE;
    unsigned int lwevent_group_index = endpoint->port % MCC_MQX_LWEVENT_GROUP_SIZE;
    MQX_TICK_STRUCT tick_time;
#endif

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Get list of buffers kept by the particular endpoint */
    list = mcc_get_endpoint_list(*endpoint);

    /* Semaphore-protected section end */
    return_value = mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* The endpoint is not valid */
    if(list == null) {
        return MCC_ERR_ENDPOINT;
    }

    if(list->head == (MCC_RECEIVE_BUFFER*)0) {
        /* Non-blocking call */
        if(timeout_us == 0) {
            return MCC_ERR_TIMEOUT;
        }
        /* Blocking call */
        else {
#if (MCC_OS_USED == MCC_MQX)
            if(timeout_us == 0xFFFFFFFF) {
                _lwevent_wait_ticks(&lwevent_buffer_queued[lwevent_index], 1<<lwevent_group_index, TRUE, 0);
            }
            /* timeout_us > 0 */
            else {
                _time_get_ticks(&tick_time);
                _time_add_usec_to_ticks(&tick_time, timeout_us);
                _lwevent_wait_until(&lwevent_buffer_queued[lwevent_index], 1<<lwevent_group_index, TRUE, &tick_time);
            }
#endif
            MCC_DCACHE_INVALIDATE_MLINES((void*)list, sizeof(MCC_RECEIVE_LIST*));
        }
    }

    /* Clear event bit specified for the particular endpoint in the lwevent_buffer_queued lwevent group */
    _lwevent_clear(&lwevent_buffer_queued[lwevent_index], 1<<lwevent_group_index);

    if(list->head == (MCC_RECEIVE_BUFFER*)0) {
        /* Buffer not dequeued before the timeout */
        return MCC_ERR_TIMEOUT;
    }

    /* Copy the message from the MCC receive buffer into the user-app. buffer */
    MCC_DCACHE_INVALIDATE_MLINES((void*)&list->head->data_len, sizeof(MCC_MEM_SIZE));
    if (list->head->data_len > buffer_size) {
        list->head->data_len = buffer_size;
    }
    *recv_size = (MCC_MEM_SIZE)(list->head->data_len);
    MCC_DCACHE_INVALIDATE_MLINES((void*)&list->head->data, list->head->data_len);
    mcc_memcpy((void*)list->head->data, buffer, list->head->data_len);

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Dequeue the buffer from the endpoint list */
    buf = mcc_dequeue_buffer(list);

    /* Enqueue the buffer into the free list */
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->free_list, sizeof(MCC_RECEIVE_LIST*));
    mcc_queue_buffer(&bookeeping_data->free_list, buf);

    /* Notify all cores (except of itself) via CPU-to-CPU interrupt that a buffer has been freed */
    affiliated_signal.type = BUFFER_FREED;
    affiliated_signal.destination = tmp_destination;
    for (i=0; i<MCC_NUM_CORES; i++) {
        if(i != MCC_CORE_NUMBER) {
            mcc_queue_signal(i, affiliated_signal);
        }
    }
    mcc_generate_cpu_to_cpu_interrupt();

    /* Semaphore-protected section end */
    return_value = mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    return return_value;
}

/*!
 * \brief This function receives a message from the specified endpoint if one is available. The data is NOT copied into the user-app. buffer.
 *
 * This is the "zero-copy receive" version of the MCC receive function. No data is copied. 
 * Only the pointer to the data is returned. This version is fast, but it requires the user to manage
 * buffer allocation. Specifically, the user must decide when a buffer is no longer in use and
 * make the appropriate API call to free it.
 *
 * \param[in] endpoint Pointer to the receiving endpoint to receive from.
 * \param[out] buffer_p Pointer to the MCC buffer of the shared memory where the received data is stored.
 * \param[out] recv_size Pointer to an MCC_MEM_SIZE that will contain the number of valid bytes in the buffer.
 * \param[in] timeout_us Timeout, in microseconds, to wait for a free buffer. A value of 0 means don't wait (non-blocking call). A value of 0xffffffff means wait forever (blocking call).
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_ENDPOINT (the endpoint does not exist)
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 * \return MCC_ERR_TIMEOUT (timeout exceeded before a new message came)
 *
 * \see mcc_send
 * \see mcc_recv_copy
 * \see MCC_ENDPOINT
 */
int mcc_recv_nocopy(MCC_ENDPOINT *endpoint, void **buffer_p, MCC_MEM_SIZE *recv_size, unsigned int timeout_us)
{
    MCC_RECEIVE_LIST *list;
    int return_value;
#if (MCC_OS_USED == MCC_MQX)
    unsigned int time_us_tmp;
    unsigned int lwevent_index = endpoint->port / MCC_MQX_LWEVENT_GROUP_SIZE;
    unsigned int lwevent_group_index = endpoint->port % MCC_MQX_LWEVENT_GROUP_SIZE;
    MQX_TICK_STRUCT tick_time;
#endif

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Get list of buffers kept by the particular endpoint */
    list = mcc_get_endpoint_list(*endpoint);

    /* Semaphore-protected section end */
    return_value = mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* The endpoint is not valid */
    if(list == null) {
        return MCC_ERR_ENDPOINT;
    }

    if(list->head == (MCC_RECEIVE_BUFFER*)0) {
        /* Non-blocking call */
        if(timeout_us == 0) {
            return MCC_ERR_TIMEOUT;
        }
        /* Blocking call */
        else {
#if (MCC_OS_USED == MCC_MQX)
            if(timeout_us == 0xFFFFFFFF) {
                _lwevent_wait_ticks(&lwevent_buffer_queued[lwevent_index], 1<<lwevent_group_index, TRUE, 0);
            }
            /* timeout_us > 0 */
            else {
                _time_get_ticks(&tick_time);
                _time_add_usec_to_ticks(&tick_time, timeout_us);
                _lwevent_wait_until(&lwevent_buffer_queued[lwevent_index], 1<<lwevent_group_index, TRUE, &tick_time);
            }
#endif
            MCC_DCACHE_INVALIDATE_MLINES((void*)list, sizeof(MCC_RECEIVE_LIST*));
        }
    }

    /* Clear event bit specified for the particular endpoint in the lwevent_buffer_queued lwevent group */
    _lwevent_clear(&lwevent_buffer_queued[lwevent_index], 1<<lwevent_group_index);

    if(list->head == (MCC_RECEIVE_BUFFER*)0) {
        /* Buffer not dequeued before the timeout */
        return MCC_ERR_TIMEOUT;
	}

    /* Get the message pointer from the head of the receive buffer list */
    MCC_DCACHE_INVALIDATE_MLINES((void*)&list->head->data, list->head->data_len);
    *buffer_p = (void*)&list->head->data;
    MCC_DCACHE_INVALIDATE_MLINES((void*)&list->head->data_len, sizeof(MCC_MEM_SIZE));
    *recv_size = (MCC_MEM_SIZE)(list->head->data_len);

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Dequeue the buffer from the endpoint list */
    mcc_dequeue_buffer(list);

    /* Semaphore-protected section end */
    return_value = mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    return return_value;
}

/*!
 * \brief This function returns the number of buffers currently queued at the endpoint.
 *
 * The function checks if messages are available on a receive endpoint. While the call only checks the
 * availability of messages, it does not dequeue them.
 *
 * \param[in] endpoint Pointer to the endpoint structure.
 * \param[out] num_msgs Pointer to an unsigned int that will contain the number of buffers queued.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_ENDPOINT (the endpoint does not exist)
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 *
 * \see mcc_recv_copy
 * \see mcc_recv_nocopy
 * \see MCC_ENDPOINT
 */
int mcc_msgs_available(MCC_ENDPOINT *endpoint, unsigned int *num_msgs)
{
    unsigned int count = 0;
    MCC_RECEIVE_LIST *list;
    MCC_RECEIVE_BUFFER * buf;
    int return_value;

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Get list of buffers kept by the particular endpoint */
    list = mcc_get_endpoint_list(*endpoint);
    if(list == null) {
        /* The endpoint does not exists (has not been registered so far), return immediately - error */
        mcc_release_semaphore();
        return MCC_ERR_ENDPOINT;
    }

    buf = list->head;
    while(buf != (MCC_RECEIVE_BUFFER*)0) {
        count++;
        MCC_DCACHE_INVALIDATE_MLINES((void*)&buf->next, sizeof(MCC_RECEIVE_BUFFER*));
        buf = (MCC_RECEIVE_BUFFER*)buf->next;
    }
    *num_msgs = count;

    /* Semaphore-protected section end */
    return_value = mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    return return_value;
}

/*!
 * \brief This function frees a buffer previously returned by mcc_recv_nocopy().
 *
 * Once the zero-copy mechanism of receiving data is used, this function
 * has to be called to free a buffer and to make it available for the next data
 * transfer.
 *
 * \param[in] buffer Pointer to the buffer to be freed.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 *
 * \see mcc_recv_nocopy
 */
int mcc_free_buffer(void *buffer)
{
    MCC_SIGNAL affiliated_signal;
    MCC_ENDPOINT tmp_destination = {(MCC_CORE)0, (MCC_NODE)0, (MCC_PORT)0};
    int return_value, i = 0;

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    /* Enqueue the buffer into the free list */
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->free_list, sizeof(MCC_RECEIVE_LIST*));
    mcc_queue_buffer(&bookeeping_data->free_list, (MCC_RECEIVE_BUFFER *)((unsigned int)buffer - (unsigned int)(&(((MCC_RECEIVE_BUFFER*)0)->data))));

    /* Notify all cores (except of itself) via CPU-to-CPU interrupt that a buffer has been freed */
    affiliated_signal.type = BUFFER_FREED;
    affiliated_signal.destination = tmp_destination;
    for (i=0; i<MCC_NUM_CORES; i++) {
        if(i != MCC_CORE_NUMBER) {
            mcc_queue_signal(i, affiliated_signal);
        }
    }
    mcc_generate_cpu_to_cpu_interrupt();

    /* Semaphore-protected section end */
    return_value = mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    return return_value;
}

/*!
 * \brief This function returns information about the MCC sub system.
 *
 * The function returns implementation-specific information.
 *
 * \param[in] node Node number.
 * \param[out] info_data Pointer to the MCC_INFO_STRUCT structure to hold returned data.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_SEMAPHORE (semaphore handling error)
 *
 * \see MCC_INFO_STRUCT
 */
int mcc_get_info(MCC_NODE node, MCC_INFO_STRUCT* info_data)
{
    int return_value;

    /* Semaphore-protected section start */
    return_value = mcc_get_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    mcc_memcpy(bookeeping_data->version_string, (void*)info_data->version_string, (unsigned int)sizeof(bookeeping_data->version_string));

    /* Semaphore-protected section end */
    return_value = mcc_release_semaphore();
    if(return_value != MCC_SUCCESS)
        return return_value;

    return return_value;
}


<|start_filename|>Firmware/Inverter_bootloader/BSP/UART.c<|end_filename|>
#include "app_cfg.h"
#include "UART.h"
#include "Cpu.h"

//-------------------------------------------------------------------------------------------------------
//   sysclk - частота ядра в килогерцах
//-------------------------------------------------------------------------------------------------------
void UART_Init(UART_MemMapPtr UART, int sysclk, int baud)
{
  register INT16U sbr, brfa;
  INT8U temp;

  /* Enable the clock to the selected UART */
  if ( UART == UART0_BASE_PTR ) SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
  else if ( UART == UART1_BASE_PTR ) SIM_SCGC4 |= SIM_SCGC4_UART1_MASK;
  else if ( UART == UART2_BASE_PTR ) SIM_SCGC4 |= SIM_SCGC4_UART2_MASK;
  else if ( UART == UART3_BASE_PTR ) SIM_SCGC4 |= SIM_SCGC4_UART3_MASK;
  else if ( UART == UART4_BASE_PTR ) SIM_SCGC1 |= SIM_SCGC1_UART4_MASK;
  else SIM_SCGC1 |= SIM_SCGC1_UART5_MASK;

  /* Make sure that the transmitter and receiver are disabled while we  change settings. */
  UART->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK);

  /* Configure the UART for 8-bit mode, no parity */
  UART->C1 = 0;    /* We need all default settings, so entire register is cleared */

  /* Calculate baud settings */
  sbr = (INT16U)((sysclk * 1000) / (baud * 16));

  /* Save off the current value of the UARTx_BDH except for the SBR field */
  temp = UART->BDH & ~(UART_BDH_SBR(0x1F));

  UART->BDH = temp |  UART_BDH_SBR(((sbr & 0x1F00) >> 8));
  UART->BDL = (INT8U)(sbr & UART_BDL_SBR_MASK);

  /* Determine if a fractional divider is needed to get closer to the baud rate */
  brfa = (((sysclk * 32000) / (baud * 16)) - (sbr * 32));

  /* Save off the current value of the UARTx_C4 register except for the BRFA field */
  temp = UART->C4 & ~(UART_C4_BRFA(0x1F));

  UART->C4 = temp |  UART_C4_BRFA(brfa);

  /* Enable receiver and transmitter */
  UART->C2 |= (UART_C2_TE_MASK | UART_C2_RE_MASK);
}


/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
void Send_byte(unsigned char byte)
{
   UART0_putchar(byte);
}

//-------------------------------------------------------------------------------------------------------
// 
//-------------------------------------------------------------------------------------------------------
void UART0_putchar(char ch)
{
  /* Wait until space is available in the FIFO */
  while (!(UART0_BASE_PTR->S1 & UART_S1_TDRE_MASK))
  {
    __no_operation();
  }

  /* Send the character */
  UART0_BASE_PTR->D = (INT8U)ch;
}

//-------------------------------------------------------------------------------------------------------
// 
//-------------------------------------------------------------------------------------------------------
int Wait_byte(unsigned char *ptr_c, unsigned int timeout)
{
  int cnt = 0;
  do
  {

    if (UART0_BASE_PTR->S1 & UART_S1_RDRF_MASK)
    {
      *ptr_c = UART0_BASE_PTR->D;
      return SUCCESS;
    }  
    cnt++;
    if ( cnt>500 )
    {
      timeout--;
      cnt = 0;
    }
    DELAY_2us;
  }
  while (timeout != 0);
  
  return ERROR;
}  

//-------------------------------------------------------------------------------------------------------
// 
//-------------------------------------------------------------------------------------------------------
char UART0_getchar(void)
{
  /* Wait until character has been received */
  while (!(UART0_BASE_PTR->S1 & UART_S1_RDRF_MASK))
  {;}

  /* Return the 8-bit data from the receiver */
  return UART0_BASE_PTR->D;
}

//-------------------------------------------------------------------------------------------------------
// 
//-------------------------------------------------------------------------------------------------------
void Out_char(char ch)
{
  UART0_putchar(ch);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fgetl.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fgetl.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the function for reading an input line.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Returns the number of characters read into the input line.
 * 
 * The terminating line feed is stripped.
 * 
 * \param[in]     file_ptr   The stream to read the characters from.
 * \param[in,out] str_ptr    Where to store the input characters.
 * \param[in]     max_length The maximum number of characters to store.
 * 
 * \return Number of characters read.
 * \return IO_EOF    
 */ 
_mqx_int _io_fgetline
   (
      MQX_FILE_PTR file_ptr,
      char _PTR_   str_ptr,
      _mqx_int     max_length
   )
{ /* Body */
   _mqx_int  c;
   _mqx_int  i;
   _mqx_uint flags;

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      *str_ptr = '\0';
      return(IO_EOF);
   } /* Endif */
#endif

   if (max_length) {
      max_length--;  /* Need to leave 1 space for the null termination */
   } else {
      max_length = MAX_MQX_INT;  /* Effectively infinite length */
   } /* Endif */

   c = _io_fgetc(file_ptr);
   if (c == IO_EOF) {
      *str_ptr = '\0';
      return(IO_EOF);
   } /* Endif */
   flags = file_ptr->FLAGS;
   i = 0;
   while ( (! ((c == '\n') || (c == '\r'))) && (i < max_length) ) {
      if ((flags & IO_FLAG_TEXT) && (c == '\b')) {
         if ( i ) {
            *--str_ptr = ' ';
            --i;
         } /* Endif */
      } else {
         *str_ptr++ = (char)c;
         ++i;
      } /* Endif */
      c = _io_fgetc(file_ptr);
      if (c == IO_EOF) {
         *str_ptr = '\0'; /* null terminate the string before returning */
         return(IO_EOF);
      } /* Endif */
   } /* Endwhile */

   if (i >= max_length) {
      _io_fungetc((_mqx_int)c, file_ptr);
   } /* Endif */

   *str_ptr = '\0';

   return (i);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_e200dec.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_e200dec.h$
* $Version : 3.8.6.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*    This file contains definitions for the PPC e200 core decrementer
*    timer driver.
*
*END***********************************************************************/

#ifndef __timer_e200dec_h__
#define __timer_e200dec_h__

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

uint_32 _e200_decrementer_timer_install(uint_32, uint_32);
uint_32 _e200_decrementer_null_install(void);

#ifdef __cplusplus
}
#endif

#endif //__timer_e200dec_h__


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ppp.h<|end_filename|>
#ifndef __ppp_h__
#define __ppp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ppp.h$
* $Version : 3.8.18.0$
* $Date    : Sep-21-2012$
*
* Comments:
*
*   This file contains the defines, externs and data
*   structure definitions required by application
*   programs in order to use the PPP Library.
*
*END************************************************************************/

#include <rtcs.h>
#include <rtcsrtos.h>
#include <rtcs_in.h>
#include <fio.h>
#include <ppphdlc.h>
#include <io_dun.h>



#ifndef PPP_SECRETS_NOT_SHARED
    #define PPP_SECRETS_NOT_SHARED 0
#endif

/***************************************
**
** Constants
*/


/*
** The default and minimum Maximum Receive Unit.
*/

#define DEFAULT_MRU  1500
#define MINIMUM_MRU    68

/*
** PPP error codes - backward compatibility
*/

   /* Initialization Failures */
#define  PPPERR_ALLOC_FAILED              RTCSERR_PPP_ALLOC_FAILED
#define  PPPERR_INIT_MUTEX_FAILED         RTCSERR_PPP_INIT_MUTEX_FAILED
#define  PPPERR_CREATE_CTRL_POOL_FAILED   RTCSERR_PPP_CREATE_CTRL_POOL_FAILED
#define  PPPERR_CREATE_PKT_POOL_FAILED    RTCSERR_PPP_CREATE_PKT_POOL_FAILED
#define  PPPERR_CREATE_RX_FAILED          RTCSERR_PPP_CREATE_RX_FAILED
#define  PPPERR_CREATE_TX_FAILED          RTCSERR_PPP_CREATE_TX_FAILED
#define  PPPERR_INVALID_CALLBACK          RTCSERR_PPP_INVALID_CALLBACK

   /* Send Failures */
#define  PPPERR_INVALID_HANDLE            RTCSERR_PPP_INVALID_HANDLE
#define  PPPERR_LINK_NOT_OPEN             RTCSERR_PPP_LINK_NOT_OPEN
#define  PPPERR_PACKET_TOO_SHORT          RTCSERR_PPP_PACKET_TOO_SHORT
#define  PPPERR_PACKET_TOO_LONG           RTCSERR_PPP_PACKET_TOO_LONG
#define  PPPERR_OUT_OF_BUFFERS            RTCSERR_PPP_OUT_OF_BUFFERS
#define  PPPERR_INVALID_PROTOCOL          RTCSERR_PPP_INVALID_PROTOCOL
#define  PPPERR_ALLOC_CALL_FAILED         RTCSERR_PPP_ALLOC_CALL_FAILED
#define  PPPERR_PROT_NOT_FOUND            RTCSERR_PPP_PROT_NOT_FOUND

   /* Other Failures (interface level) */
#define  PPPERR_FSM_ACTIVE                RTCSERR_PPP_FSM_ACTIVE

   /* Internal Failures */
#define  PPPERR_OPEN_QUEUE_FAILED         RTCSERR_PPP_OPEN_QUEUE_FAILED

/*
** LCP States.  Do not modify these constants!
*/

#define PPP_STATE_INITIAL  0
#define PPP_STATE_STARTING 1
#define PPP_STATE_CLOSED   2
#define PPP_STATE_STOPPED  3
#define PPP_STATE_CLOSING  4
#define PPP_STATE_STOPPING 5
#define PPP_STATE_REQ_SENT 6
#define PPP_STATE_ACK_RCVD 7
#define PPP_STATE_ACK_SENT 8
#define PPP_STATE_OPENED   9

/*
** LCP Options.  These control the LCP negotiation.
*/

#define PPP_OPT_SILENT  0x01
#define PPP_OPT_RESTART 0x02


/*
** PPP callback function numbers.
*/

#define PPP_CALL_LINK_UP      0
#define PPP_CALL_LINK_DOWN    1
#define PPP_CALL_ECHO_REPLY   2
#define PPP_CALL_AUTH_FAIL    3

#define PPP_CALL_MAX          4


/* Start CR 2207 */
#define PPP_PAP_LSECRET       1
#define PPP_PAP_RSECRETS      2
#define PPP_CHAP_LSECRETS     3
#define PPP_CHAP_RSECRETS     4
/* End CR 2207 */
/***************************************
**
** Global parameters
*/

extern uint_32 _PPPTASK_stacksize;
extern uint_32 _PPPTASK_priority;

extern uint_32 _PPP_MIN_XMIT_TIMEOUT;
extern uint_32 _PPP_MAX_XMIT_TIMEOUT;
extern uint_32 _PPP_MAX_CONF_RETRIES;
extern uint_32 _PPP_MAX_TERM_RETRIES;
extern uint_32 _PPP_MAX_CONF_NAKS;

extern uint_32 _PPP_ACCM;


/***************************************
**
** Type definitions
*/

/*
** The PPP handle.  This is returned by PPP_initialize(), and required
** as a parameter for all other PPP functions.
*/

typedef pointer _ppp_handle;

/*
** A secret.  This is the name/secret pair used by both PAP and CHAP.
*/

typedef struct ppp_secret {
   uint_16     PPP_ID_LENGTH;
   uint_16     PPP_PW_LENGTH;
   char_ptr    PPP_ID_PTR;
   char_ptr    PPP_PW_PTR;
} PPP_SECRET, _PTR_ PPP_SECRET_PTR;

/* Start CR 2207 */
#if PPP_SECRETS_NOT_SHARED
#define PPP_SECRET(p,s) p->s
#else
#define PPP_SECRET(p,s) s
/* End CR 2207 */

/* The secret to use if the peer requests PAP authentication */
extern PPP_SECRET_PTR   _PPP_PAP_LSECRET;

/* The array of secrets to use to authenticate the peer with PAP */
extern PPP_SECRET_PTR   _PPP_PAP_RSECRETS;

/* The name of the local host (required for CHAP) */
extern char_ptr   _PPP_CHAP_LNAME;

/* The array of secrets to use if the peer requests CHAP authentication */
extern PPP_SECRET_PTR   _PPP_CHAP_LSECRETS;

/* The array of secrets to use to authenticate the peer with CHAP */
extern PPP_SECRET_PTR   _PPP_CHAP_RSECRETS;
/* Start CR 2207 */
#endif
/* End CR 2207 */

/*
** Each PPP channel requires two tasks.  The Tx task is a mindless drone
** that sends out everything we tell it to.  The Rx task contains the
** LCP automaton.
*/

extern void PPP_rx_task (pointer, pointer);
extern void PPP_tx_task (pointer, pointer);


/***************************************
**
** The PPP interface functions
*/

extern uint_32 PPP_initialize (_iopcb_handle, _ppp_handle _PTR_);
extern uint_32 PPP_shutdown (_ppp_handle);

extern uint_32 PPP_getcall (_ppp_handle, uint_32, void (_CODE_PTR_ _PTR_)(), pointer _PTR_);
extern uint_32 PPP_setcall (_ppp_handle, uint_32, void (_CODE_PTR_ _PTR_)(), pointer _PTR_);

extern uint_32 PPP_register   (_ppp_handle, uint_16, void (_CODE_PTR_)(PCB_PTR, pointer), pointer);
extern uint_32 PPP_unregister (_ppp_handle, uint_16);

extern void    PPP_lowerup   (_ppp_handle);
extern void    PPP_lowerdown (_ppp_handle);
extern uint_32 PPP_open      (_ppp_handle, uint_32);
extern uint_32 PPP_close     (_ppp_handle);

extern uint_32 PPP_send (_ppp_handle, uint_16, PCB_PTR);

extern uint_32 PPP_discard (_ppp_handle, uchar, PCB_PTR);
extern uint_32 PPP_echo    (_ppp_handle, uchar, PCB_PTR);

extern uint_32 PPP_getmtu (_ppp_handle);


/*
** PPP 2.73 compatibility
*/

typedef uint_32 _ppp_channel;

typedef struct ppp_call { 
   uint_32  PARAM;
   void     (_CODE_PTR_ PPP_Link_up)    (uint_32);
   void     (_CODE_PTR_ PPP_Link_down)  (uint_32);
   void     (_CODE_PTR_ PPP_Echo_reply) (uint_32, uchar, PCB_PTR);
   void     (_CODE_PTR_ PPP_Auth_fail)  (uint_32);
} PPP_CALL, _PTR_ PPP_CALL_PTR;

extern PPP_CALL PPP_DEFAULT_CALL;

#define PPP_TASK_NUMBERS   (0x40)
#define PPP_RX_TASK        PPP_TASK_NUMBERS
#define PPP_TX_TASK        PPP_TASK_NUMBERS+1
#define PPP_Rx_task        PPP_rx_task
#define PPP_Tx_task        PPP_tx_task

extern int_32 PPP_Initialize(_ppp_channel, MQX_FILE_PTR, PPP_CALL_PTR);
extern int_32 PPP_Setcall(_ppp_channel, uint_32, void (_CODE_PTR_)(), uint_32);

/* Start CR 2207 */
extern boolean PPP_set_chap_lname( _ppp_handle, char_ptr ); 
extern boolean PPP_set_secrets(_ppp_handle,uint_32,PPP_SECRET_PTR);
/* End CR 2207 */

/*
** Compatibility for PPP_Register, PPP_Unregister, PPP_Send,
** PPP_Discard and PPP_Echo is not provided.
*/


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/dhcpsrv.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dhcpsrv.c$
* $Version : 192.168.127.12$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the DHCP Server for RTCS.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_UDP

#include "dhcpsrv.h"

static DHCPSRV_STATE_STRUCT_PTR DHCPSRV_cfg = NULL;

void DHCPSRV_task (pointer, pointer);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_lease_start
* Returned Value  : void
* Comments        : This function starts a lease or offer.
*
* Notes           : This function must be called with the IPLIST
*                   semaphore locked.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_lease_start
   (
      DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrhead,
      DHCPSRV_ADDR_STRUCT_PTR       addr,
      uint_32                       time
   )
{ /* Body */

   while ((*addrhead) && (*addrhead)->EXPIRE < time) {
      if (time < DHCP_LEASE_INFINITE) {
         time -= (*addrhead)->EXPIRE;
      } /* Endif */
      addrhead = &(*addrhead)->NEXT;
   } /* Endwhile */

   if (*addrhead && (*addrhead)->EXPIRE < DHCP_LEASE_INFINITE) {
      (*addrhead)->EXPIRE -= time;
   } /* Endif */

   addr->EXPIRE = time;
   addr->NEXT = (*addrhead);
   *addrhead = addr;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_lease_stop
* Returned Value  : dequeued IP address
* Comments        : This function terminates a lease or offer.
*
* Notes           : This function must be called with the IPLIST
*                   semaphore locked.
*
*END*-----------------------------------------------------------------*/

static DHCPSRV_ADDR_STRUCT_PTR DHCPSRV_lease_stop
   (
      DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrhead
   )
{ /* Body */
   DHCPSRV_ADDR_STRUCT_PTR addr = *addrhead;

   if (addr->NEXT && addr->NEXT->EXPIRE < DHCP_LEASE_INFINITE) {
      addr->NEXT->EXPIRE += addr->EXPIRE;
   } /* Endif */

   *addrhead = addr->NEXT;
   return addr;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_lease_extend
* Returned Value  : void
* Comments        : This function extends the EXPIRE time of an
*                   offer or a lease by delta.
*
* Notes           : This function must be called with the IPLIST
*                   semaphore locked.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_lease_extend
   (
      DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrhead,
      uint_32                       delta
   )
{ /* Body */
   DHCPSRV_ADDR_STRUCT_PTR addr = *addrhead;

   delta += addr->EXPIRE;
   addr = DHCPSRV_lease_stop(addrhead);
   DHCPSRV_lease_start(addrhead, addr, delta);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_ippool_add
* Returned Value  : error code
* Comments        : This function adds a block of IP addresses to
*                   the IP_AVAIL list.
*
*END*-----------------------------------------------------------------*/

uint_32 DHCPSRV_ippool_add
   (
      _ip_address             ipstart,
      uint_32                 ipnum,
      DHCPSRV_DATA_STRUCT_PTR params,
      uchar_ptr               optptr,
      uint_32                 optlen
   )
{ /* Body */
   DHCPSRV_OPTIONS_STRUCT_PTR    options;
   DHCPSRV_ADDR_STRUCT_PTR       addr;
   uchar_ptr                     moreoptions = NULL;

   options = RTCS_mem_alloc_system(sizeof(DHCPSRV_OPTIONS_STRUCT) + optlen);
   if (!options) {
      return RTCSERR_OUT_OF_MEMORY;
   } /* Endif */
   _mem_set_type(options, MEM_TYPE_DHCPSRV_OPTIONS_STRUCT);

   moreoptions = (uchar_ptr)(options+1);
   _mem_copy(optptr, moreoptions, optlen);

   options->COUNT = 0;
   options->SERVERID   = params->SERVERID;
   options->LEASE      = params->LEASE;
   options->MASK       = params->MASK;
   options->OPTION_PTR = moreoptions;
   options->OPTION_LEN = optlen;
   options->SADDR      = params->SADDR;
   _mem_copy(params->SNAME, options->SNAME, sizeof(options->SNAME) - 1);
   options->SNAME[sizeof(options->SNAME) - 1] = '\0';
   _mem_copy(params->FILE,  options->FILE,  sizeof(options->FILE)  - 1);
   options->FILE[sizeof(options->FILE) - 1] = '\0';

   RTCS_mutex_lock(&DHCPSRV_cfg->IPLIST_SEM);

   for (; ipnum; ipnum--, ipstart++) {
      addr = RTCS_mem_alloc_system(sizeof(DHCPSRV_ADDR_STRUCT));
      if (!addr) {
         if (options->COUNT == 0) {
            _mem_free(options);
         } /* Endif */
         RTCS_mutex_unlock(&DHCPSRV_cfg->IPLIST_SEM);
         return RTCSERR_OUT_OF_MEMORY;
      } /* Endif */
      _mem_set_type(options, MEM_TYPE_DHCPSRV_ADDR_STRUCT);

      addr->CLIENTID_LEN = 0;
      addr->CLIENTID_PTR = NULL;
      addr->IP_ADDR      = ipstart;
      addr->OPTIONS      = options;
      options->COUNT++;
      DHCPSRV_lease_start(&DHCPSRV_cfg->IP_AVAIL, addr, 0);
   } /* Endfor */

   RTCS_mutex_unlock(&DHCPSRV_cfg->IPLIST_SEM);
   return RTCS_OK;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_expire
* Returned Value  : time to next expiry, 0 = forever.
* Comments        : This function expires offers and leases.
*
*END*-----------------------------------------------------------------*/

static uint_32 DHCPSRV_expire
   (
      DHCPSRV_STATE_STRUCT_PTR   state
   )
{ /* Body */
   DHCPSRV_ADDR_STRUCT_PTR addr;
   TIME_STRUCT             time;
   uint_32                 elapsed;

   RTCS_mutex_lock(&state->IPLIST_SEM);
   _time_get(&time);

   /* Expire offers */
   elapsed = time.SECONDS - state->TIME;
   while (state->IP_OFFERED) {

      if (state->IP_OFFERED->EXPIRE > elapsed) {
         state->IP_OFFERED->EXPIRE -= elapsed;
         break;
      } /* Endif */

      addr = state->IP_OFFERED;
      state->IP_OFFERED = addr->NEXT;
      elapsed -= addr->EXPIRE;
      DHCPSRV_lease_start(&state->IP_AVAIL, addr, 0);

   } /* Endwhile */

   /* Expire leases */
   elapsed = time.SECONDS - state->TIME;
   while (state->IP_LEASED && state->IP_LEASED->EXPIRE < DHCP_LEASE_INFINITE) {

      if (state->IP_LEASED->EXPIRE > elapsed) {
         state->IP_LEASED->EXPIRE -= elapsed;
         break;
      } /* Endif */

      addr = state->IP_LEASED;
      state->IP_LEASED = addr->NEXT;
      elapsed -= addr->EXPIRE;
      DHCPSRV_lease_start(&state->IP_AVAIL, addr, 0);

   } /* Endwhile */

   /* Start CR 1547 */
   /* Expire takens */
   elapsed = time.SECONDS - state->TIME;
   while (state->IP_TAKEN && state->IP_TAKEN->EXPIRE < DHCP_LEASE_INFINITE) {

      if (state->IP_TAKEN->EXPIRE > elapsed) {
         state->IP_TAKEN->EXPIRE -= elapsed;
         break;
      } /* Endif */

      addr = state->IP_TAKEN;
      state->IP_TAKEN = addr->NEXT;
      elapsed -= addr->EXPIRE;
      DHCPSRV_lease_start(&state->IP_AVAIL, addr, 0);


   } /* Endwhile */
   /* End CR 1547 */

   /* Calculate time to next expiry */
   elapsed = DHCP_LEASE_INFINITE;
   if (state->IP_OFFERED && state->IP_OFFERED->EXPIRE < elapsed) {
      elapsed = state->IP_OFFERED->EXPIRE;
   } /* Endif */
   if (state->IP_LEASED  && state->IP_LEASED->EXPIRE  < elapsed) {
      elapsed = state->IP_LEASED->EXPIRE;
   } /* Endif */
   if (elapsed == DHCP_LEASE_INFINITE) {
      elapsed = 0;
   } /* Endif */

   state->TIME = time.SECONDS;
   RTCS_mutex_unlock(&state->IPLIST_SEM);

   return elapsed;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_find_option
* Returned Value  : uchar_ptr
* Comments        : This function searches through the OPTIONS section
*                   of a DHCP message to find a specific option type.
*                   If it is found, a pointer to the specific option
*                   field is returned, If no option of the specified
*                   type exists, NULL is returned.
*
*END*-----------------------------------------------------------------*/

static uchar_ptr DHCPSRV_find_option
   (
      uchar_ptr   msgptr,
      uint_32     msglen,
      uchar       option
   )
{ /* Body */
   uchar optype;
   uchar oplen;

   for (;;) {

      /* Get the next option code */
      if (msglen == 0) {
         return NULL;
      } /* Endif */
      optype = ntohc(msgptr);
      msgptr++;
      msglen--;

      if (optype == DHCPOPT_END) {
         return NULL;
      } /* Endif */
      if (optype == DHCPOPT_PAD) {
         continue;
      } /* Endif */

      /* Get the option length */
      if (msglen == 0) {
         return NULL;
      } /* Endif */
      oplen = ntohc(msgptr);
      msgptr++;
      msglen--;

      if (msglen < oplen) {
         return NULL;
      } /* Endif */

      if (optype == option) {
         return msgptr-2;
      } /* Endif */

      msgptr += oplen;
      msglen -= oplen;

   } /* Endfor */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_find_msgtype
* Returned Value  : value of the Message Type option
* Comments        : This function searches through the OPTIONS section
*                   of a DHCP message for the message type option.  If
*                   the message type option is is not present, 0 is
*                   returned.
*
*END*-----------------------------------------------------------------*/

static uchar DHCPSRV_find_msgtype
   (
      uchar_ptr   msgptr,
      uint_32     msglen
   )
{ /* Body */
   uchar msgtype = 0;

   msgptr = DHCPSRV_find_option(msgptr, msglen, DHCPOPT_MSGTYPE);
   if (msgptr != NULL) {
      msgptr++;
      if (ntohc(msgptr) == DHCPSIZE_MSGTYPE) {
         msgptr++;
         msgtype = ntohc(msgptr);
         if (!DHCPTYPE_ISVALID(msgtype)) {
            msgtype = 0;
         } /* Endif */
      } /* Endif */
   } /* Endif */

   return msgtype;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_find_clientid
* Returned Value  : IP address associated to client ID
* Comments        : This function searches a DHCPSRV_ADDR list for
*                   an IP address associated to a client.  If no
*                   address is found, NULL is returned.
*
* Notes           : This function must be called with the IPLIST
*                   semaphore locked.
*
*END*-----------------------------------------------------------------*/

static DHCPSRV_ADDR_STRUCT_PTR _PTR_ DHCPSRV_find_clientid
   (
      DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrhead,
      uchar_ptr                     cid_ptr,
      uint_32                       cid_len,
      uint_32_ptr                   expire_ptr
   )
{ /* Body */
   uint_32  i, expire;
   boolean  found;

   expire = 0;
   while (*addrhead) {
      expire += (*addrhead)->EXPIRE;
      if ((*addrhead)->CLIENTID_PTR && (*addrhead)->CLIENTID_LEN == cid_len) {

         found = TRUE;
         for (i=0; i<cid_len; i++) {
            if (cid_ptr[i] != (*addrhead)->CLIENTID_PTR[i]) {
               found = FALSE;
               break;
            } /* Endif */
         } /* Endfor */
         if (found) {
            if (expire_ptr) *expire_ptr = expire;
            return addrhead;
         } /* Endif */

      } /* Endif */
      addrhead = &(*addrhead)->NEXT;
   } /* Endwhile */

   return NULL;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_find_addr
* Returned Value  : IP address associated to client ID
* Comments        : This function searches a DHCPSRV_ADDR list for
*                   a specified IP address.  If the address is not
*                   found, NULL is returned.
*
* Notes           : This function must be called with the IPLIST
*                   semaphore locked.
*
*END*-----------------------------------------------------------------*/

static DHCPSRV_ADDR_STRUCT_PTR _PTR_ DHCPSRV_find_addr
   (
      DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrhead,
      _ip_address                   addr
   )
{ /* Body */

   while (*addrhead) {

      if ((*addrhead)->IP_ADDR == addr) {
         return addrhead;
      } /* Endif */

      addrhead = &(*addrhead)->NEXT;
   } /* Endwhile */

   return NULL;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_update_clientid
* Returned Value  : its first parameter if successful, NULL otherwise
* Comments        : This function updates a DHCPSRV_ADDR's client
*                   ID field with a new one.
*
* Notes           : This function must be called with the IPLIST
*                   semaphore locked.
*
*END*-----------------------------------------------------------------*/

static DHCPSRV_ADDR_STRUCT_PTR _PTR_ DHCPSRV_update_clientid
   (
      DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrhead,
      uchar_ptr                     cid_ptr,
      uint_32                       cid_len
   )
{ /* Body */
   DHCPSRV_ADDR_STRUCT_PTR addr = *addrhead;
   uchar_ptr               cid;

   cid = RTCS_mem_alloc(cid_len);
   if (!cid) return NULL;
   _mem_set_type(cid, MEM_TYPE_DHCPSRV_CID);

   if (addr->CLIENTID_PTR) _mem_free(addr->CLIENTID_PTR);

   _mem_copy(cid_ptr, cid, cid_len);
   addr->CLIENTID_PTR = cid;
   addr->CLIENTID_LEN = cid_len;

   return addrhead;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_write_header
* Returned Value  : void
* Comments        : This function fills the send buffer with the
*                   initial values needed in a DHCP response.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_write_header
   (
      DHCPSRV_STATE_STRUCT_PTR   state,
      DHCPSRV_ADDR_STRUCT_PTR    lease_ptr,
      uint_32                    lease_time,
      uchar                      msgtype
   )
{ /* Body */
   DHCP_HEADER_PTR   outp;
   DHCP_HEADER_PTR   inp;
   uchar_ptr         optptr;
   volatile uint_32           optlen;
   uint_32           temp_long;
   uint_16           temp_short;
   uchar             temp_char;

   outp = (DHCP_HEADER_PTR)state->SND_BUFFER;
   inp  = (DHCP_HEADER_PTR)state->RCV_BUFFER;

   /* Build a DHCPOFFER, DHCPACK, or DHCPNAK packet */
   htonc(outp->OP, DHCPOP_BOOTREPLY);
   htonc(outp->HTYPE, ARPLINK_ETHERNET);
   temp_char = ntohc(inp->HLEN);
   htonc(outp->HLEN, temp_char);
   htonc(outp->HOPS, 0);

   /* Use client's existing transaction ID */
   temp_long = ntohl(inp->XID);
   htonl(outp->XID, temp_long);

   htons(outp->SECS, 0);

   if (ntohl(inp->GIADDR) == 0) {
      htons(outp->FLAGS, 0);
   } else {
      temp_short = ntohs(inp->FLAGS);
      htons(outp->FLAGS, temp_short);
   } /* Endif */

   if (msgtype == DHCPTYPE_DHCPOFFER) {
      htonl(outp->CIADDR, 0);
   } else {
      temp_long = ntohl(inp->CIADDR);
      htonl(outp->CIADDR, temp_long);
   } /* Endif */

   if (msgtype == DHCPTYPE_DHCPNAK) {
      htonl(outp->YIADDR, 0);
      htonl(outp->SIADDR, 0);
   } else {
      htonl(outp->YIADDR, lease_ptr->IP_ADDR);
      htonl(outp->SIADDR, lease_ptr->OPTIONS->SADDR);
   } /* Endif */

   htonl(outp->GIADDR, 0);

   _mem_copy(inp->CHADDR, outp->CHADDR, sizeof(outp->CHADDR));

   if (msgtype == DHCPTYPE_DHCPNAK) {
      _mem_zero(outp->SNAME, sizeof(outp->SNAME));
      _mem_zero(outp->FILE,  sizeof(outp->FILE));
   } else {
      _mem_copy(lease_ptr->OPTIONS->SNAME, outp->SNAME, sizeof(outp->SNAME));
      _mem_copy(lease_ptr->OPTIONS->FILE,  outp->FILE,  sizeof(outp->FILE));
   } /* Endif */

   /*
   ** Fill in the required response options. These are message type,
   ** subnet mask, and server id.
   */

   optlen = sizeof(DHCP_HEADER);
   optptr = state->SND_BUFFER + optlen;

   /* The Magic Cookie must always be the first thing in the OPTIONS */
   htonl(optptr, DHCP_MAGIC);
   optptr += DHCPSIZE_MAGIC;
   optlen += DHCPSIZE_MAGIC;

#define DHCP_OPTION(type,len,val) \
            htonc(optptr, DHCPOPT_  ## type); optptr++; optlen++; \
            htonc(optptr, DHCPSIZE_ ## type); optptr++; optlen++; \
            hton ## len(optptr, val);                             \
            optptr += DHCPSIZE_ ## type;                          \
            optlen += DHCPSIZE_ ## type

   DHCP_OPTION(MSGTYPE,  c, msgtype);
   if (msgtype != DHCPTYPE_DHCPNAK) {
      DHCP_OPTION(SERVERID, l, lease_ptr->OPTIONS->SERVERID);
      DHCP_OPTION(MASK,     l, lease_ptr->OPTIONS->MASK);
      DHCP_OPTION(LEASE,    l, lease_time);
   } /* Endif */

   state->SND_BUFFER_LEN = optlen;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_write_options
* Returned Value  : void
* Comments        : This function fills the send buffer with the
*                   options specified by the application.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_write_options
   (
      DHCPSRV_STATE_STRUCT_PTR   state,
      DHCPSRV_ADDR_STRUCT_PTR    lease_ptr
   )
{ /* Body */
   uchar_ptr   inp, outp, scanptr;
   int_32      scanlen;
   uint_32     copylen;
   volatile uchar       optval, optlen;

   outp = state->SND_BUFFER + state->SND_BUFFER_LEN;
   inp  = lease_ptr->OPTIONS->OPTION_PTR;

   scanptr = inp;
   scanlen = sizeof(state->SND_BUFFER) - state->SND_BUFFER_LEN - 1;
   if (scanlen > lease_ptr->OPTIONS->OPTION_LEN) {
      scanlen = lease_ptr->OPTIONS->OPTION_LEN;
   } /* Endif */
   copylen = 0;

   for (;;) {

      if (scanlen < 1) break;
      optval = ntohc(scanptr);
      scanptr++;
      scanlen--;

      if (optval == DHCPOPT_END) {
         break;
      } /* Endif */
      if (optval == DHCPOPT_PAD) {
         copylen++;
         continue;
      } /* Endif */

      if (scanlen < 1) break;
      optlen = ntohc(scanptr);
      scanptr++;
      scanlen--;

      if (scanlen < optlen) break;

      scanptr += optlen;
      scanlen -= optlen;
      copylen += optlen + 2;

   } /* Endfor */

   _mem_copy(inp, outp, copylen);
   state->SND_BUFFER_LEN += copylen;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_write_end
* Returned Value  : void
* Comments        : This function writes an END option to the
*                   OPTIONS field.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_write_end
   (
      DHCPSRV_STATE_STRUCT_PTR   state
   )
{ /* Body */
   uchar_ptr   optptr;
   volatile uint_32     optlen;

   optlen = state->SND_BUFFER_LEN;
   optptr = state->SND_BUFFER + optlen;

   htonc(optptr, DHCPOPT_END);
   optlen++;

   state->SND_BUFFER_LEN = optlen;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_send
* Returned Value  : void
* Comments        : This function sends a prebuilt DHCP reply.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_send
   (
      DHCPSRV_STATE_STRUCT_PTR   state
   )
{ /* Body */
   _ip_address    giaddr;
   sockaddr_in    raddr;

   giaddr = ntohl(((DHCP_HEADER_PTR)state->RCV_BUFFER)->GIADDR);
   if (giaddr) {
      raddr.sin_family      = AF_INET;
      raddr.sin_port        = IPPORT_BOOTPS;
      raddr.sin_addr.s_addr = giaddr;
   } else {
      raddr.sin_family      = AF_INET;
      raddr.sin_port        = IPPORT_BOOTPC;
      raddr.sin_addr.s_addr = INADDR_BROADCAST;
   } /* Endif */

   /* Start CR 1131 */
   sendto(state->SOCKET, state->SND_BUFFER, state->SND_BUFFER_LEN,
      RTCS_MSG_NOLOOP, (sockaddr *)&raddr, sizeof(raddr));
   /* End CR 1131 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_service_discover
* Returned Value  : void
* Comments        : This function replies to a received DHCPDISCOVER
*                   message.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_service_discover
   (
      DHCPSRV_STATE_STRUCT_PTR   state
   )
{ /* Body */
   uchar_ptr                     inp,   cid_ptr, opt_ptr;
   uint_32                       inlen, cid_len;
   DHCPSRV_ADDR_STRUCT_PTR       addr;
   DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrp;
   uint_32                       time, lease;
   boolean                       leased, avail, newcid;

   inp   = state->RCV_BUFFER     + sizeof(DHCP_HEADER) + 4;
   inlen = state->RCV_BUFFER_LEN - sizeof(DHCP_HEADER) - 4;

   /* Get the client ID; use CHADDR if none */
   cid_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_CLIENTID);
   if (cid_ptr) {
      cid_ptr++;
      cid_len = ntohc(cid_ptr);
      cid_ptr++;
   } else {
      DHCP_HEADER_PTR pkt_ptr = (DHCP_HEADER_PTR)state->RCV_BUFFER;
      cid_ptr = pkt_ptr->CHADDR;
      cid_len = ntohc(pkt_ptr->HLEN);
      if (cid_len > sizeof(pkt_ptr->CHADDR)) {
         cid_len = sizeof(pkt_ptr->CHADDR);
      } /* Endif */
   } /* Endif */

   addrp = NULL;
   RTCS_mutex_lock(&state->IPLIST_SEM);

   /* First check whether the client already has a lease */
   if (!addrp) {
      addrp = DHCPSRV_find_clientid(&state->IP_LEASED,  cid_ptr, cid_len, &time);
      leased = TRUE;
      avail  = FALSE;
      newcid = FALSE;
   } /* Endif */

   /* Next check whether the client has been offered a lease */
   if (!addrp) {
      addrp = DHCPSRV_find_clientid(&state->IP_OFFERED, cid_ptr, cid_len, &time);
      leased = FALSE;
      avail  = FALSE;
      newcid = FALSE;
   } /* Endif */

   /* Next check whether any available address was previously offered/leased to the client */
   if (!addrp) {
      addrp = DHCPSRV_find_clientid(&state->IP_AVAIL,   cid_ptr, cid_len, NULL);
      leased = FALSE;
      avail  = TRUE;
      newcid = FALSE;
   } /* Endif */

   /* Next check whether the client's requested address is available */
   if (!addrp) {
      _ip_address reqaddr;

      opt_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_ADDRESS);
      if (opt_ptr && ntohc(opt_ptr+1) == DHCPSIZE_ADDRESS) {
         reqaddr = ntohl(opt_ptr+2);
      } else {
         DHCP_HEADER_PTR pkt_ptr = (DHCP_HEADER_PTR)state->RCV_BUFFER;
         reqaddr = ntohl(pkt_ptr->CIADDR);
      } /* Endif */

      addrp = DHCPSRV_find_addr(&state->IP_AVAIL, reqaddr);
      leased = FALSE;
      avail  = TRUE;
      newcid = TRUE;
   } /* Endif */

   /* Finally, offer the first available address */
   if (!addrp) {
      if (state->IP_AVAIL) {
         addrp = &state->IP_AVAIL;
      } /* Endif */
      leased = FALSE;
      avail  = TRUE;
      newcid = TRUE;
   } /* Endif */

   if (newcid && addrp) {
      addrp = DHCPSRV_update_clientid(addrp, cid_ptr, cid_len);
   } /* Endif */

   if (addrp) {

      /* Determine length of offer */
      opt_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_LEASE);
      if (opt_ptr && ntohc(opt_ptr+1) == DHCPSIZE_LEASE) {
         lease = ntohl(opt_ptr+2);
         if (lease > (*addrp)->OPTIONS->LEASE) {
            lease = (*addrp)->OPTIONS->LEASE;
         } /* Endif */
      } else if (leased) {
         lease = time;
      } else {
         lease = (*addrp)->OPTIONS->LEASE;
      } /* Endif */
      (*addrp)->OFFER = lease;

      DHCPSRV_write_header (state, *addrp, lease, DHCPTYPE_DHCPOFFER);
      DHCPSRV_write_options(state, *addrp);
      DHCPSRV_write_end    (state);

      /* Start CR 1547 */
      /* probe the address to see if it is already taken (if so configured) */
  
  
      if (addrp && DHCPSRV_cfg->FLAGS & DHCPSVR_FLAG_DO_PROBE) {
          uint_32   timeout = 50; /* miliseconds */
          uint_32   error;
          
          /* note: this will hang the dhserver application while we await the probe result */
          error = RTCS_ping((*addrp)->IP_ADDR, &timeout, 0xFACE, 0, 0, 0);
          
          if (error == RTCS_OK) {
             /* bad news: someone answered this ping, we can't use this address */
             addr = DHCPSRV_lease_stop(addrp);
             DHCPSRV_lease_start(&state->IP_TAKEN, addr, DHCPTIME_OFFER);
             avail = FALSE;
             
             /* nak this discover, client will send us another */
             DHCPSRV_write_header(state, NULL, 0, DHCPTYPE_DHCPNAK);
             DHCPSRV_write_end(state);
             
          }
      }
     /* End CR 1547 */ 
      
      /* Reserve the offer for at least DHCPTIME_OFFER */
      if (avail) {
         addr = DHCPSRV_lease_stop(addrp);
         DHCPSRV_lease_start(&state->IP_OFFERED, addr, DHCPTIME_OFFER);
      } else if (time < DHCPTIME_OFFER) {
         DHCPSRV_lease_extend(addrp, DHCPTIME_OFFER - time);
      } /* Endif */

   } else {
      DHCPSRV_write_header(state, NULL, 0, DHCPTYPE_DHCPNAK);
      DHCPSRV_write_end(state);
   } /* Endif */

   RTCS_mutex_unlock(&state->IPLIST_SEM);

   DHCPSRV_send(state);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_service_request
* Returned Value  : void
* Comments        : This function replies to a received DHCPREQUEST
*                   message.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_service_request
   (
      DHCPSRV_STATE_STRUCT_PTR   state
   )
{ /* Body */
   uchar_ptr                     inp,   cid_ptr, sid_ptr, lease_ptr;
   uint_32                       inlen, cid_len;
   _ip_address                   serverid = 0;
   uint_32                       lease = 0;
   DHCPSRV_ADDR_STRUCT_PTR       addr;
   DHCPSRV_ADDR_STRUCT_PTR _PTR_ addrp;
   /* Start CR 1599 */
   boolean                       reply=FALSE;
   /* End CR 1599 */

   inp   = state->RCV_BUFFER     + sizeof(DHCP_HEADER) + 4;
   inlen = state->RCV_BUFFER_LEN - sizeof(DHCP_HEADER) - 4;

   /* Get the client ID; use CHADDR if none */
   cid_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_CLIENTID);
   if (cid_ptr) {
      cid_ptr++;
      cid_len = ntohc(cid_ptr);
      cid_ptr++;
   } else {
      DHCP_HEADER_PTR pkt_ptr = (DHCP_HEADER_PTR)state->RCV_BUFFER;
      cid_ptr = pkt_ptr->CHADDR;
      cid_len = ntohc(pkt_ptr->HLEN);
      if (cid_len > sizeof(pkt_ptr->CHADDR)) {
         cid_len = sizeof(pkt_ptr->CHADDR);
      } /* Endif */
   } /* Endif */

   /* Get the server ID */
   sid_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_SERVERID);
   if (sid_ptr && ntohc(sid_ptr+1) == DHCPSIZE_SERVERID) {
      sid_ptr += 2;
      serverid = ntohl(sid_ptr);
   } else {
      sid_ptr = NULL;
   } /* Endif */

   /* Get the requested lease */
   lease_ptr = DHCPSRV_find_option(inp, inlen, DHCPOPT_LEASE);
   if (lease_ptr && ntohc(lease_ptr+1) == DHCPSIZE_LEASE) {
      lease_ptr += 2;
      lease = ntohl(lease_ptr);
   } else {
      lease_ptr = NULL;
   } /* Endif */

   addrp = NULL;
   RTCS_mutex_lock(&state->IPLIST_SEM);

   if (!addrp) {
      addrp = DHCPSRV_find_clientid(&state->IP_LEASED,  cid_ptr, cid_len, NULL);
   } /* Endif */

   if (!addrp && sid_ptr) {
      addrp = DHCPSRV_find_clientid(&state->IP_OFFERED, cid_ptr, cid_len, NULL);
   } /* Endif */

   /* Start CR 2089 */
   /* check whether any available address was previously offered/leased to the client */   
   if (!addrp) {
      addrp = DHCPSRV_find_clientid(&state->IP_AVAIL, cid_ptr, cid_len, NULL);
   } /* Endif */    
   /* End CR 2089 */
      
   if (addrp) {

      if (sid_ptr && serverid != (*addrp)->OPTIONS->SERVERID) {

         reply = FALSE;

         addr = DHCPSRV_lease_stop(addrp);
         DHCPSRV_lease_start(&state->IP_AVAIL, addr, 0);

      } else if (lease_ptr && lease > (*addrp)->OPTIONS->LEASE) {

         DHCPSRV_write_header(state, NULL, 0, DHCPTYPE_DHCPNAK);
         DHCPSRV_write_end(state);
         reply = TRUE;

      } else {

         if (!lease_ptr) {
            lease = (*addrp)->OFFER;
         } /* Endif */

         DHCPSRV_write_header (state, *addrp, lease, DHCPTYPE_DHCPACK);
         DHCPSRV_write_options(state, *addrp);
         DHCPSRV_write_end    (state);
         reply = TRUE;

         addr = DHCPSRV_lease_stop(addrp);
         DHCPSRV_lease_start(&state->IP_LEASED, addr, lease);

      } /* Endif */
   } /* Endif */

   RTCS_mutex_unlock(&state->IPLIST_SEM);

   if (reply) {
      DHCPSRV_send(state);
   } /* Endif */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_service_release
* Returned Value  : void
* Comments        : This function services a received DHCPRELEASE
*                   message.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_service_release
   (
      DHCPSRV_STATE_STRUCT_PTR   state
   )
{ /* Body */
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_service_decline
* Returned Value  : void
* Comments        : This function services a received DHCPDECLINE
*                   message.
*
*END*-----------------------------------------------------------------*/

static void DHCPSRV_service_decline
   (
      DHCPSRV_STATE_STRUCT_PTR   state
   )
{ /* Body */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPSRV_init
* Returned Value  : error code
* Comments        : Start the DHCP server.
*
*END*-----------------------------------------------------------------*/

uint_32 DHCPSRV_init
   (
      char_ptr name,
      uint_32  priority,
      uint_32  stacksize
   )
{ /* Body */
   return RTCS_task_create(name, priority, stacksize, DHCPSRV_task, NULL);
} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name   : DHCPSRV_task
* Returned Value  :
* Comments        : The DHCP server.
*
*END*-----------------------------------------------------------------*/

void DHCPSRV_task
   (
      pointer dummy,
      pointer creator
   )

{ /* Body */
   DHCPSRV_STATE_STRUCT    state;
   sockaddr_in             addr;
   uint_32                 timeout;
   uchar_ptr               msgptr;
   uint_32                 msglen;
   uchar                   msgtype;
   int_32                  error;

   state.IP_AVAIL   = NULL;
   state.IP_OFFERED = NULL;
   state.IP_LEASED  = NULL;

   /* Start CR 1547 */
   state.IP_TAKEN   = NULL;
   state.FLAGS      = DHCPSVR_FLAG_DO_PROBE;
   /* End CR 1547 */

   RTCS_mutex_init(&state.IPLIST_SEM);

   state.SOCKET = socket(PF_INET, SOCK_DGRAM, 0);
   if (state.SOCKET == RTCS_SOCKET_ERROR) {
      RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
   } /* Endif */

   addr.sin_family      = AF_INET;
   addr.sin_port        = IPPORT_BOOTPS;
   addr.sin_addr.s_addr = INADDR_ANY;

   error = bind(state.SOCKET,(sockaddr *)(&addr), sizeof(sockaddr_in));
  
   if (error != RTCS_OK) {
      RTCS_task_exit(creator, error);
   } /* Endif */

   DHCPSRV_cfg = &state;

   RTCS_task_resume_creator(creator, RTCS_OK);

   for (;;) {

      /* Wait for a message */
      timeout = DHCPSRV_expire(&state) * 1000;
      error = RTCS_selectset(&state.SOCKET, 1, timeout);
      if ((error == 0) || (error == RTCS_ERROR)) continue;

      /* Received a message, respond accordingly */
      error = recvfrom(state.SOCKET, state.RCV_BUFFER, sizeof(state.RCV_BUFFER), 0, NULL, NULL);
      if (error == RTCS_ERROR) continue;

      /* The datagram must contain at least a header and a magic cookie */
      if (error < sizeof(DHCP_HEADER) + DHCPSIZE_MAGIC) continue;
      msgptr = state.RCV_BUFFER + sizeof(DHCP_HEADER);
      if (ntohl(msgptr) != DHCP_MAGIC) continue;
      msgptr += DHCPSIZE_MAGIC;
      msglen = error - sizeof(DHCP_HEADER) - DHCPSIZE_MAGIC;
      state.RCV_BUFFER_LEN = error;

      /* Update the time before starting any new events */
      DHCPSRV_expire(&state);

      /* Service the packet */
      msgtype = DHCPSRV_find_msgtype(msgptr, msglen);
      switch (msgtype) {

      case DHCPTYPE_DHCPDISCOVER:
         DHCPSRV_service_discover(&state);
         break;

      case DHCPTYPE_DHCPREQUEST:
         DHCPSRV_service_request(&state);
         break;

      case DHCPTYPE_DHCPRELEASE:
         DHCPSRV_service_release(&state);
         break;

      case DHCPTYPE_DHCPDECLINE:
         DHCPSRV_service_decline(&state);
         break;

      } /* Endswitch */

   } /* Endwhile */
} /* Endbody */

/* Start CR 1547 */
/*FUNCION*-----------------------------------------------------------------
*
* Function Name   : DHCPSRV_set_config_flag_on
* Returned Value  : RTCS_OK if all went well
* Comment         : turns on the flags passed in
*                 : May be called anytime after DHCPSRV_init()
*                 : Flags are defined in dhcpsrv.h and look like :
*                 : DHCPSVR_FLAG_*
*
*END*-----------------------------------------------------------------*/

static uint_32 DHCPSRV_set_config_flag_on
   (
      uint_32   flags /* [IN]   flags to govern behaviour of dhcp server */
   )

{ /* Body */

   RTCS_mutex_lock(&DHCPSRV_cfg->IPLIST_SEM);

   DHCPSRV_cfg->FLAGS |= flags;
   
   RTCS_mutex_unlock(&DHCPSRV_cfg->IPLIST_SEM);
   
   return RTCS_OK;
} /* Endbody */

 
/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : DHCPSRV_set_config_flag_off
* Returned Value  : RTCS_OK if all went well
* Comment         : Turns off the flags passed in
*                 : May be called anytime after DHCPSRV_init()
*                 : Flags are defined in dhcpsrv.h and look like :
*                 : DHCPSVR_FLAG_*
*
*END*-----------------------------------------------------------------*/

static uint_32 DHCPSRV_set_config_flag_off
   (
      uint_32   flags /* [IN]   flags to govern behaviour of dhcp server */
   )

{ /* Body */

   RTCS_mutex_lock(&DHCPSRV_cfg->IPLIST_SEM);
   
   DHCPSRV_cfg->FLAGS &= !flags;
   
   RTCS_mutex_unlock(&DHCPSRV_cfg->IPLIST_SEM);
   
   return RTCS_OK;
} /* Endbody */

#endif

/* End CR 1547 */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/timer.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: timer.c$
 * $Version : 3.8.2.0$
 * $Date    : Jun-25-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Timer component.
 *
 *END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_TIMER
#include "timer.h"
#include "timer_prv.h"

/*!
 * \brief Cancels an outstanding timer request.
 * 
 * \param[in] id ID of the timer to be cancelled, from calling a function from 
 * the _timer_start family of functions.
 *  
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Timer component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \return MQX_INVALID_PARAMETER (Id is not valid.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_LWSEM
 * 
 * \warning Cannot be called from an ISR. 
 * 
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 */ 
_mqx_uint _timer_cancel
(
    _timer_id id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    TIMER_ENTRY_STRUCT_PTR     timer_entry_ptr;
    QUEUE_STRUCT_PTR           queue_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_timer_cancel, id);

    timer_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
#if MQX_CHECK_ERRORS
    if (timer_component_ptr == NULL)
    {
        _KLOGX2(KLOG_timer_cancel, MQX_COMPONENT_DOES_NOT_EXIST);
        return MQX_COMPONENT_DOES_NOT_EXIST;
    } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
    if (timer_component_ptr->VALID != TIMER_VALID)
    {
        _KLOGX2(KLOG_timer_cancel, MQX_INVALID_COMPONENT_BASE);
        return MQX_INVALID_COMPONENT_BASE;
    } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    if (id == 0)
    {
        _KLOGX2(KLOG_timer_cancel, MQX_INVALID_PARAMETER);
        return MQX_INVALID_PARAMETER;
    } /* Endif */

    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_timer_cancel, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return MQX_CANNOT_CALL_FUNCTION_FROM_ISR;
    } /* Endif */
#endif

    /* Gain exclusive access to the timer queues */
    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        if (_lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM) != MQX_OK)
        {
            _KLOGX2(KLOG_timer_cancel, MQX_INVALID_LWSEM);
            return(MQX_INVALID_LWSEM);
        } /* Endif */
    } /*Endif */
    timer_entry_ptr = _timer_find_entry_internal(timer_component_ptr, id);

    if ((timer_entry_ptr == NULL) || (timer_entry_ptr->VALID != TIMER_VALID))
    {
        if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
        {
            _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
        } /* Endif */
        _KLOGX2(KLOG_timer_cancel, MQX_INVALID_PARAMETER);
        return MQX_INVALID_PARAMETER;
    } /* Endif */

    if (timer_entry_ptr->MODE == TIMER_ELAPSED_TIME_MODE)
    {
        queue_ptr = &timer_component_ptr->ELAPSED_TIMER_ENTRIES;
    }
    else
    {
        queue_ptr = &timer_component_ptr->KERNEL_TIMER_ENTRIES;
    } /* Endif */

    timer_entry_ptr->VALID = 0;
    timer_entry_ptr->ID = 0;
    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        _QUEUE_REMOVE(queue_ptr, timer_entry_ptr);
        _mem_free(timer_entry_ptr);
        _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
    } /* Endif */

    _KLOGX2(KLOG_timer_cancel, MQX_OK);
    return(MQX_OK);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Locates a timer via its ID.
 * 
 * \param[in] timer_component_ptr The address of the timer component structure.
 * \param[in] id                  The timer ID.
 * 
 * \return Pointer to a timer entry.
 * \return NULL (failure)  
 */
TIMER_ENTRY_STRUCT_PTR _timer_find_entry_internal
(
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr,
    _timer_id                  id
)
{ /* Body */
    QUEUE_STRUCT_PTR       queue_ptr;
    TIMER_ENTRY_STRUCT_PTR timer_entry_ptr;
    _mqx_uint              i;
    _mqx_uint              size;

    for (i = 0; i < 2; i++)
    {
        if (i == 0)
        {
            queue_ptr = &timer_component_ptr->ELAPSED_TIMER_ENTRIES;
        }
        else
        {
            queue_ptr = &timer_component_ptr->KERNEL_TIMER_ENTRIES;
        } /* Endif */
        timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)((pointer)queue_ptr->NEXT);
        /* SPR P171-0023-01 use pre-decrement on while loop */
        size = queue_ptr->SIZE + 1;
        while (--size)
        {
            /* END SPR */
            if (timer_entry_ptr->ID == id)
            {
                return(timer_entry_ptr);
            } /* Endif */
            timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)
            ((pointer)timer_entry_ptr->QUEUE_ELEMENT.NEXT);
        } /* Endwhile */
    } /* Endfor */

    return(NULL);

} /* Endbody */

/*!
 * \brief Istalls the timer component into the kernel.
 * 
 * If the timer component is not explicitly created, MQX creates it with default 
 * values the first time that a task calls one of the functions from the 
 * _timer_start family.
 * \n The default values are:
 * \li TIMER_DEFAULT_TASK_PRIORITY
 * \li TIMER_DEFAULT_STACK_SIZE
 * 
 * \n The function returns MQX_OK if either:
 * \li Timer component is created.
 * \li Timer component was previously created and the configuration is not changed.
 *  
 * \param[in] timer_task_priority   The task priority of the timer task.
 * \param[in] timer_task_stack_size The stack size for the timer task.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \return task error codes  
 * 
 * \warning Creates Timer Task.
 * \warning Cannot be called from an ISR. 
 * 
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 * \see _timer_cancel   
 */ 
_mqx_uint _timer_create_component
(
    _mqx_uint timer_task_priority,
    _mqx_uint timer_task_stack_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    TASK_TEMPLATE_STRUCT       timer_tt;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_timer_create_component, timer_task_priority);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_timer_create_component, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);

    if (kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER] != NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);
        _KLOGX2(KLOG_timer_create_component, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    /* Get the timer component data structure */
    timer_component_ptr = _mem_alloc_system_zero((_mem_size)sizeof(TIMER_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (timer_component_ptr == NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);
        _KLOGX2(KLOG_timer_create_component, MQX_OUT_OF_MEMORY);
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif   
    _mem_set_type(timer_component_ptr, MEM_TYPE_TIMER_COMPONENT);
    _QUEUE_INIT(&timer_component_ptr->ELAPSED_TIMER_ENTRIES, 0);
    _QUEUE_INIT(&timer_component_ptr->KERNEL_TIMER_ENTRIES, 0);

    timer_tt.TASK_TEMPLATE_INDEX = 0;
    timer_tt.TASK_ADDRESS = _timer_task;
    if (timer_task_stack_size == 0)
    {
        timer_tt.TASK_STACKSIZE = TIMER_DEFAULT_STACK_SIZE;
    }
    else
    {
        timer_tt.TASK_STACKSIZE = timer_task_stack_size;
    } /* Endif */
    if (timer_task_priority == 0)
    {
        timer_tt.TASK_PRIORITY = TIMER_DEFAULT_TASK_PRIORITY;
    }
    else
    {
        timer_tt.TASK_PRIORITY = timer_task_priority;
    } /* Endif */
    timer_tt.TASK_NAME = "Timer Task";
    timer_tt.TASK_ATTRIBUTES = 0;
    timer_tt.DEFAULT_TIME_SLICE = 0;

    kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER] = timer_component_ptr;

    timer_component_ptr->TIMER_TID = _task_create(0, 0, (uint_32)&timer_tt);
#if MQX_CHECK_ERRORS
    if (timer_component_ptr->TIMER_TID == MQX_NULL_TASK_ID)
    {
        _mqx_uint result;

        kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER] = NULL;
        timer_component_ptr->VALID = 0;
        result = _task_get_error();
        if (result == MQX_OK)
        {
            result = MQX_OUT_OF_MEMORY;
        } /* Endif */
        _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);
        _mem_free(timer_component_ptr);
        _KLOGX2(KLOG_timer_create_component, result);
        return(result);
    }/* Endif */
#endif

#if MQX_COMPONENT_DESTRUCTION
    kernel_data->COMPONENT_CLEANUP[KERNEL_EVENTS] = _timer_cleanup;
#endif
    _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);

    _KLOGX2(KLOG_timer_create_component, MQX_OK);
    return(MQX_OK);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Initializes a timer to start once after a delay period expressed in ticks.
 * 
 * \param[in] notification_function_ptr The function to call when the timer expires.
 * \param[in] notification_data_ptr     The data to pass to the function when 
 * the timer expires.
 * \param[in] mode                      Which time to use when calculating time 
 * to start:
 * \li TIMER_ElAPSED_TIME_MODE
 * \li TIMER_KERNEL_TIME_MODE
 * \param[in] tick_ptr                  The number of ticks to wait before calling 
 * the notification function, and canceling the timer.
 * \param[in] uses_ticks                Set to true if called from the tick 
 * interface functions.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component() 
 */           
_timer_id _timer_start_oneshot_after_internal
(
    TIMER_NOTIFICATION_FPTR notification_function_ptr,
    pointer                 notification_data_ptr,
    _mqx_uint               mode,
    MQX_TICK_STRUCT_PTR     tick_ptr,
    boolean                 uses_ticks
)
{
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    TIMER_ENTRY_STRUCT_PTR     timer_entry_ptr;
    MQX_TICK_STRUCT            kernel_time;
    _mqx_uint                  result;

    _GET_KERNEL_DATA(kernel_data);

    timer_component_ptr = (TIMER_COMPONENT_STRUCT_PTR)kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
    if (timer_component_ptr == NULL)
    {
        result = _timer_create_component(TIMER_DEFAULT_TASK_PRIORITY,
                        TIMER_DEFAULT_STACK_SIZE);
        timer_component_ptr = (TIMER_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
#if MQX_CHECK_ERRORS
        if (timer_component_ptr == NULL)
        {
            _task_set_error(result);
            return TIMER_NULL_ID;
        } /* Endif */
#endif
    }/* Endif */

#if MQX_CHECK_VALIDITY
    if (timer_component_ptr->VALID != TIMER_VALID)
    {
        _task_set_error(MQX_INVALID_COMPONENT_BASE);
        return TIMER_NULL_ID;
    } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    if ((notification_function_ptr == NULL) ||
                    ! ((mode == TIMER_ELAPSED_TIME_MODE) || (mode == TIMER_KERNEL_TIME_MODE))
    )
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        return TIMER_NULL_ID;
    } /* Endif */

    result = (_mqx_uint)PSP_CMP_TICKS(&_mqx_zero_tick_struct, tick_ptr);
    if (result == 0)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(TIMER_ENTRY_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (timer_entry_ptr == NULL)
    {
        _task_set_error(MQX_OUT_OF_MEMORY);
        return TIMER_NULL_ID;
    } /* Endif */
#endif
    _mem_set_type(timer_entry_ptr, MEM_TYPE_TIMER_ENTRY);

    if (mode == TIMER_ELAPSED_TIME_MODE)
    {
        _time_get_elapsed_ticks(&kernel_time);
    }
    else
    {
        _time_get_ticks(&kernel_time);
    } /* Endif */

    PSP_ADD_TICKS(tick_ptr, &kernel_time, &timer_entry_ptr->EXPIRATION_TIME);

    timer_entry_ptr->NOTIFICATION_FUNCTION = notification_function_ptr;
    timer_entry_ptr->NOTIFICATION_DATA_PTR = notification_data_ptr;
    timer_entry_ptr->MODE = (uint_16)mode;
    timer_entry_ptr->TIMER_TYPE = TIMER_TYPE_ONESHOT_AFTER;
    timer_entry_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
    timer_entry_ptr->USES_TICKS = uses_ticks;

    /* Gain exclusive access to the timer queues */
    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        if (_lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM) != MQX_OK)
        {
            _task_set_error(MQX_INVALID_LWSEM);
            return(TIMER_NULL_ID);
        } /* Endif */
    } /* Endif */

    timer_entry_ptr->VALID = TIMER_VALID;
    timer_entry_ptr->ID = _timer_alloc_id_internal(timer_component_ptr);

    if (mode == TIMER_ELAPSED_TIME_MODE)
    {
        _timer_insert_queue_internal(&timer_component_ptr->ELAPSED_TIMER_ENTRIES,
                        timer_entry_ptr);
    }
    else
    {
        _timer_insert_queue_internal(&timer_component_ptr->KERNEL_TIMER_ENTRIES,
                        timer_entry_ptr);
    } /* Endif */

    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
    } /* Endif */

    return(timer_entry_ptr->ID);

} /* Endbody */

/*!
 * \brief Starts a timer that expires after the specified number of ticks (in tick 
 * time).
 * 
 * The function calculates the expiry time based on tick_ptr and mode.
 * \n You might need to increase the Timer Task stack size to accommodate the 
 * notification function (see _timer_create_component()).
 * 
 * \param[in] notification_function_ptr Notification function that MQX calls when 
 * the timer expires.
 * \param[in] notification_data_ptr     The data to pass to the notification 
 * function when the timer expires.
 * \param[in] mode                      Time to use when calculating the time to 
 * expire; one of the following:
 * \li TIMER_ELAPSED_TIME_MODE (Use _time_get_elapsed() or _time_get_elapsed_ticks(), 
 * which are not affected by _time_set() or _time_set_ticks().)
 * \li TIMER_KERNEL_TIME_MODE (Use _time_get() or _time_get_ticks().)
 * \param[in] tick_ptr                  The number of ticks to wait before calling 
 * the notification function, and canceling the timer.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure) 
 * 
 * \warning Creates the timer component with default values if it was not 
 * previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component() 
 * 
 * \see _timer_start_oneshot_after
 * \see _task_set_error
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see _timer_cancel
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 * \see _timer_create_component 
 */ 
_timer_id _timer_start_oneshot_after_ticks
(
    TIMER_NOTIFICATION_TICK_FPTR notification_function_ptr,
    pointer                      notification_data_ptr,
    _mqx_uint                    mode,
    MQX_TICK_STRUCT_PTR          tick_ptr
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _timer_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_timer_start_oneshot_after_ticks, notification_function_ptr,
                    mode, tick_ptr);

#if MQX_CHECK_ERRORS
    if (tick_ptr == NULL)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_timer_start_oneshot_after_ticks, TIMER_NULL_ID);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    result = _timer_start_oneshot_after_internal((TIMER_NOTIFICATION_FPTR)notification_function_ptr,
                    notification_data_ptr, mode, tick_ptr, TRUE);

    _KLOGX2(KLOG_timer_start_oneshot_after_ticks, result);

    return result;

} /* Endbody */

/*!
 * \private
 * 
 * \brief Initializes a timer to start once at a specified time.
 * 
 * \param[in] notification_function_ptr The function to call when the timer expires.
 * \param[in] notification_data_ptr     The data to pass to the function when 
 * the timer expires.
 * \param[in] mode                      Which time to use when calculating time 
 * to start:
 * \li TIMER_ElAPSED_TIME_MODE
 * \li TIMER_KERNEL_TIME_MODE
 * \param[in] tick_ptr                  The time at which to call the notification 
 * function, and then cancel the timer.
 * \param[in] uses_ticks                Set to true if notification function 
 * uses ticks.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component()   
 */ 
_timer_id _timer_start_oneshot_at_internal
(
    TIMER_NOTIFICATION_FPTR notification_function_ptr,
    pointer                 notification_data_ptr,
    _mqx_uint               mode,
    MQX_TICK_STRUCT_PTR     tick_ptr,
    boolean                 uses_ticks
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    TIMER_ENTRY_STRUCT_PTR     timer_entry_ptr;
    _mqx_uint                  error;

    _GET_KERNEL_DATA(kernel_data);

    timer_component_ptr = (TIMER_COMPONENT_STRUCT_PTR)kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
    if (timer_component_ptr == NULL)
    {
        error = _timer_create_component(TIMER_DEFAULT_TASK_PRIORITY,
                        TIMER_DEFAULT_STACK_SIZE);
        timer_component_ptr = (TIMER_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
#if MQX_CHECK_ERRORS
        if (timer_component_ptr == NULL)
        {
            _task_set_error(error);
            return TIMER_NULL_ID;
        } /* Endif */
#endif
    }/* Endif */

#if MQX_CHECK_VALIDITY
    if (timer_component_ptr->VALID != TIMER_VALID)
    {
        _task_set_error(MQX_INVALID_COMPONENT_BASE);
        return TIMER_NULL_ID;
    } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    if ((notification_function_ptr == NULL) ||
                    ! ((mode == TIMER_ELAPSED_TIME_MODE) || (mode == TIMER_KERNEL_TIME_MODE))
    )
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        return TIMER_NULL_ID;
    } /* Endif */

    error = (_mqx_uint)PSP_CMP_TICKS(&_mqx_zero_tick_struct, tick_ptr);
    if (error == 0)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(TIMER_ENTRY_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (timer_entry_ptr == NULL)
    {
        _task_set_error(MQX_OUT_OF_MEMORY);
        return TIMER_NULL_ID;
    } /* Endif */
#endif
    _mem_set_type(timer_entry_ptr, MEM_TYPE_TIMER_ENTRY);

    timer_entry_ptr->NOTIFICATION_FUNCTION = notification_function_ptr;
    timer_entry_ptr->NOTIFICATION_DATA_PTR = notification_data_ptr;
    timer_entry_ptr->MODE = (uint_16)mode;
    timer_entry_ptr->TIMER_TYPE = TIMER_TYPE_ONESHOT_AT;
    timer_entry_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
    timer_entry_ptr->USES_TICKS = uses_ticks;

    timer_entry_ptr->EXPIRATION_TIME = *tick_ptr;

    /* Gain exclusive access to the timer queues */
    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        if (_lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM) != MQX_OK)
        {
            _task_set_error(MQX_INVALID_LWSEM);
            return(TIMER_NULL_ID);
        } /* Endif */
    } /* Endif */

    timer_entry_ptr->VALID = TIMER_VALID;

    timer_entry_ptr->ID = _timer_alloc_id_internal(timer_component_ptr);

    if (mode == TIMER_ELAPSED_TIME_MODE)
    {
        _timer_insert_queue_internal(&timer_component_ptr->ELAPSED_TIMER_ENTRIES,
                        timer_entry_ptr);
    }
    else
    {
        _timer_insert_queue_internal(&timer_component_ptr->KERNEL_TIMER_ENTRIES,
                        timer_entry_ptr);
    } /* Endif */
    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
    } /* Endif */

    return(timer_entry_ptr->ID);

} /* Endbody */

/*!
 * \brief Starts a timer that expire once at the specified time in tick time.
 * 
 * When the timer expires, MQX calls notification_function with timer_id, 
 * notification_data_ptr, and the current time.
 * \n You might need to increase the Timer Task stack size to accommodate the 
 * notification function (see _timer_create_component()).
 *  
 * \param[in] notification_function_ptr Pointer to the notification function that 
 * MQX calls when the timer expire.
 * \param[in] notification_data_ptr     The data to pass to the function when the 
 * timer expires.
 * \param[in] mode                      Time to use when calculating the time to 
 * expire; one of the following:
 * \li TIMER_ELAPSED_TIME_MODE (Use _time_get_elapsed() or _time_get_elapsed_ticks(), 
 * which are not affected by _time_set() or _time_set_ticks().)
 * \li TIMER_KERNEL_TIME_MODE (Use _time_get() or _time_get_ticks().)
 * \param[in] tick_ptr                  Pointer to the tick time at which MQX 
 * calls the notification function and cancels the timer.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure) 
 * 
 * \warning Creates the timer component with default values if it was not 
 * previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component()
 * 
 * \see _timer_start_oneshot_at
 * \see _timer_cancel
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _task_set_error
 * \see _timer_create_component   
 */ 
_timer_id _timer_start_oneshot_at_ticks
(
    TIMER_NOTIFICATION_TICK_FPTR notification_function_ptr,
    pointer                      notification_data_ptr,
    _mqx_uint                    mode,
    MQX_TICK_STRUCT_PTR          tick_ptr
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _timer_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_timer_start_oneshot_at_ticks, notification_function_ptr, mode,
                    tick_ptr);

#if MQX_CHECK_ERRORS
    if (tick_ptr == NULL)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_timer_start_oneshot_at_ticks, TIMER_NULL_ID);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    result = _timer_start_oneshot_at_internal((TIMER_NOTIFICATION_FPTR)notification_function_ptr,
                    notification_data_ptr, mode, tick_ptr, TRUE);

    _KLOGX2(KLOG_timer_start_oneshot_at_ticks, result);

    return(result);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Initializes a timer to fire periodically at a specific time.
 * 
 * \param[in] notification_function_ptr The function to call when the timer expires.
 * \param[in] notification_data_ptr     The data to pass to the function when 
 * the timer expires.
 * \param[in] mode                      Which time to use when calculating time 
 * to start:
 * \li TIMER_ElAPSED_TIME_MODE
 * \li TIMER_KERNEL_TIME_MODE
 * \param[in] stick_ptr                 The time at which to call the notification 
 * function, and then cancel the timer.
 * \param[in] wtick_ptr                 The number of ticks to wait between calls 
 * to the notification function.
 * \param[in] uses_ticks                Set to true if notification function 
 * uses ticks.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component()   
 */ 
_timer_id _timer_start_periodic_at_internal
(
    TIMER_NOTIFICATION_FPTR notification_function_ptr,
    pointer                 notification_data_ptr,
    _mqx_uint               mode,
    MQX_TICK_STRUCT_PTR     stick_ptr,
    MQX_TICK_STRUCT_PTR     wtick_ptr,
    boolean                 uses_ticks
)
{
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    TIMER_ENTRY_STRUCT_PTR     timer_entry_ptr;
    _mqx_uint                  result;

    _GET_KERNEL_DATA(kernel_data);

    timer_component_ptr = (TIMER_COMPONENT_STRUCT_PTR)kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
    if (timer_component_ptr == NULL)
    {
        result = _timer_create_component(TIMER_DEFAULT_TASK_PRIORITY,
                        TIMER_DEFAULT_STACK_SIZE);
        timer_component_ptr = (TIMER_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
#if MQX_CHECK_ERRORS
        if (timer_component_ptr == NULL)
        {
            _task_set_error(result);
            return TIMER_NULL_ID;
        } /* Endif */
#endif
    }/* Endif */

#if MQX_CHECK_VALIDITY
    if (timer_component_ptr->VALID != TIMER_VALID)
    {
        _task_set_error(MQX_INVALID_COMPONENT_BASE);
        return TIMER_NULL_ID;
    } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    if (!notification_function_ptr ||
                    ! ((mode == TIMER_ELAPSED_TIME_MODE) || (mode == TIMER_KERNEL_TIME_MODE))
    )
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        return TIMER_NULL_ID;
    } /* Endif */

    result = (_mqx_uint)PSP_CMP_TICKS(&_mqx_zero_tick_struct, wtick_ptr);
    if (result == 0)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(TIMER_ENTRY_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (timer_entry_ptr == NULL)
    {
        _task_set_error(MQX_OUT_OF_MEMORY);
        return TIMER_NULL_ID;
    } /* Endif */
#endif
    _mem_set_type(timer_entry_ptr, MEM_TYPE_TIMER_ENTRY);

    timer_entry_ptr->NOTIFICATION_FUNCTION = notification_function_ptr;
    timer_entry_ptr->NOTIFICATION_DATA_PTR = notification_data_ptr;
    timer_entry_ptr->MODE = (uint_16)mode;
    timer_entry_ptr->TIMER_TYPE = TIMER_TYPE_PERIODIC_AT;
    timer_entry_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
    timer_entry_ptr->USES_TICKS = uses_ticks;
    timer_entry_ptr->EXPIRATION_TIME = *stick_ptr;
    timer_entry_ptr->CYCLE = *wtick_ptr;

    /* Gain exclusive access to the timer queues */
    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        if (_lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM) != MQX_OK)
        {
            _task_set_error(MQX_INVALID_LWSEM);
            return(TIMER_NULL_ID);
        } /* Endif */
    } /* Endif */

    timer_entry_ptr->VALID = TIMER_VALID;
    timer_entry_ptr->ID = _timer_alloc_id_internal(timer_component_ptr);

    if (mode == TIMER_ELAPSED_TIME_MODE)
    {
        _timer_insert_queue_internal(&timer_component_ptr->ELAPSED_TIMER_ENTRIES,
                        timer_entry_ptr);
    }
    else
    {
        _timer_insert_queue_internal(&timer_component_ptr->KERNEL_TIMER_ENTRIES,
                        timer_entry_ptr);
    } /* Endif */

    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
    } /* Endif */

    return(timer_entry_ptr->ID);

} /* Endbody */

/*!
 * \brief Starts a periodic timer at the specified time in tick time.
 * 
 * You might need to increase the Timer Task stack size to accommodate the 
 * notification function (see _timer_create_component()).
 *  
 * \param[in] notification_function_ptr Pointer to the notification function that 
 * MQX calls when the timer expire.
 * \param[in] notification_data_ptr     The data to pass to the function when the 
 * timer expires.
 * \param[in] mode                      Time to use when calculating the time to 
 * expire; one of the following:
 * \li TIMER_ELAPSED_TIME_MODE (Use _time_get_elapsed() or _time_get_elapsed_ticks(), 
 * which are not affected by _time_set() or _time_set_ticks().)
 * \li TIMER_KERNEL_TIME_MODE (Use _time_get() or _time_get_ticks().)
 * \param[in] stick_ptr                 Pointer to the tick time at which MQX 
 * starts calling the notification function.
 * \param[in] wtick_ptr                 Ticks (in tick time) that MQX waits 
 * between subsequent calls to the notification function.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure) 
 * 
 * \warning Creates the timer component with default values if it was not 
 * previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component()
 * 
 * \see _timer_start_periodic_at
 * \see _timer_cancel
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _task_set_error
 * \see _timer_create_component   
 */
_timer_id _timer_start_periodic_at_ticks
(
    TIMER_NOTIFICATION_TICK_FPTR notification_function_ptr,
    pointer                      notification_data_ptr,
    _mqx_uint                    mode,
    MQX_TICK_STRUCT_PTR          stick_ptr,
    MQX_TICK_STRUCT_PTR          wtick_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _timer_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_timer_start_periodic_at_ticks, notification_function_ptr, mode,
                    stick_ptr);

#if MQX_CHECK_ERRORS
    if ((notification_function_ptr == NULL) ||
                    (stick_ptr == NULL) ||
                    (wtick_ptr == NULL))
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_timer_start_periodic_at_ticks, TIMER_NULL_ID);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    result = _timer_start_periodic_at_internal((TIMER_NOTIFICATION_FPTR)notification_function_ptr,
                    notification_data_ptr, mode, stick_ptr, wtick_ptr, TRUE);

    _KLOGX2(KLOG_timer_start_periodic_at_ticks, result);

    return(result);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Initializes a timer to fire periodically.
 * 
 * \param[in] notification_function_ptr The function to call when the timer expires.
 * \param[in] notification_data_ptr     The data to pass to the function when 
 * the timer expires.
 * \param[in] mode                      Which time to use when calculating time 
 * to start:
 * \li TIMER_ElAPSED_TIME_MODE
 * \li TIMER_KERNEL_TIME_MODE
 * \param[in] wtick_ptr                 The number of ticks to wait before calling 
 * the notification function.
 * \param[in] uses_ticks                Set to true if called from the tick 
 * interface functions.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component()   
 */ 
_timer_id _timer_start_periodic_every_internal
(
    TIMER_NOTIFICATION_FPTR notification_function_ptr,
    pointer                 notification_data_ptr,
    _mqx_uint               mode,
    MQX_TICK_STRUCT_PTR     wtick_ptr,
    boolean                 uses_ticks
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    TIMER_ENTRY_STRUCT_PTR     timer_entry_ptr;
    MQX_TICK_STRUCT            kernel_time;
    _mqx_uint                  result;

    _GET_KERNEL_DATA(kernel_data);

    timer_component_ptr = (TIMER_COMPONENT_STRUCT_PTR)kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
    if (timer_component_ptr == NULL)
    {
        result = _timer_create_component(TIMER_DEFAULT_TASK_PRIORITY,
                        TIMER_DEFAULT_STACK_SIZE);
        timer_component_ptr = (TIMER_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
#if MQX_CHECK_ERRORS
        if (timer_component_ptr == NULL)
        {
            _task_set_error(result);
            return TIMER_NULL_ID;
        } /* Endif */
#endif
    }/* Endif */

#if MQX_CHECK_VALIDITY
    if (timer_component_ptr->VALID != TIMER_VALID)
    {
        _task_set_error(MQX_INVALID_COMPONENT_BASE);
        return TIMER_NULL_ID;
    } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    if (!notification_function_ptr || !((mode == TIMER_ELAPSED_TIME_MODE) ||
                                    (mode == TIMER_KERNEL_TIME_MODE)) )
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        return TIMER_NULL_ID;
    } /* Endif */

    result = (_mqx_uint)PSP_CMP_TICKS(&_mqx_zero_tick_struct, wtick_ptr);
    if (result == 0)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(TIMER_ENTRY_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (timer_entry_ptr == NULL)
    {
        return TIMER_NULL_ID;
    } /* Endif */
#endif
    _mem_set_type(timer_entry_ptr, MEM_TYPE_TIMER_ENTRY);

    timer_entry_ptr->CYCLE = *wtick_ptr;

    if (mode == TIMER_ELAPSED_TIME_MODE)
    {
        _time_get_elapsed_ticks(&kernel_time);
    }
    else
    {
        _time_get_ticks(&kernel_time);
    } /* Endif */

    timer_entry_ptr->NOTIFICATION_FUNCTION = notification_function_ptr;
    timer_entry_ptr->NOTIFICATION_DATA_PTR = notification_data_ptr;
    timer_entry_ptr->MODE = (uint_16)mode;
    timer_entry_ptr->USES_TICKS = uses_ticks;
    timer_entry_ptr->TIMER_TYPE = TIMER_TYPE_PERIODIC_EVERY;

    PSP_ADD_TICKS(wtick_ptr, &kernel_time, &timer_entry_ptr->EXPIRATION_TIME);

    timer_entry_ptr->TD_PTR = kernel_data->ACTIVE_PTR;

    /* Gain exclusive access to the timer queues */
    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        if (_lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM) != MQX_OK)
        {
            _task_set_error(MQX_INVALID_LWSEM);
            return(TIMER_NULL_ID);
        } /* Endif */
    } /* Endif */

    timer_entry_ptr->VALID = TIMER_VALID;
    timer_entry_ptr->ID = _timer_alloc_id_internal(timer_component_ptr);

    if (mode == TIMER_ELAPSED_TIME_MODE)
    {
        _timer_insert_queue_internal(&timer_component_ptr->ELAPSED_TIMER_ENTRIES,
                        timer_entry_ptr);
    }
    else
    {
        _timer_insert_queue_internal(&timer_component_ptr->KERNEL_TIMER_ENTRIES,
                        timer_entry_ptr);
    } /* Endif */

    if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR)
    {
        _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
    } /* Endif */

    return(timer_entry_ptr->ID);

} /* Endbody */

/*!
 * \brief Starts a periodic timer every specified number of ticks (in tick time).
 * 
 * When the timer expires, MQX calls notification_function with timer_id, notifier 
 * data, and the current time.
 * \n You might need to increase the Timer Task stack size to accommodate the 
 * notification function (see _timer_create_component()).
 *  
 * \param[in] notification_function_ptr Pointer to the notification function that 
 * MQX calls when the timer expire.
 * \param[in] notification_data_ptr     Pointer to the data that MQX passes to 
 * the notification function.
 * \param[in] mode                      Time to use when calculating the time to 
 * expire; one of the following:
 * \li TIMER_ELAPSED_TIME_MODE (Use _time_get_elapsed() or _time_get_elapsed_ticks(), 
 * which are not affected by _time_set() or _time_set_ticks().)
 * \li TIMER_KERNEL_TIME_MODE (Use _time_get() or _time_get_ticks().)
 * \param[in] wtick_ptr                 Ticks (in tick time) that MQX waits before 
 * it first calls the notification function and between subsequent calls to the 
 * notification function.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure) 
 * 
 * \warning Creates the timer component with default values if it was not 
 * previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component() 
 * 
 * \see _timer_start_periodic_every
 * \see _timer_cancel
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _task_set_error
 * \see _timer_create_component 
 */
_timer_id _timer_start_periodic_every_ticks
(
    TIMER_NOTIFICATION_TICK_FPTR notification_function_ptr,
    pointer                      notification_data_ptr,
    _mqx_uint                    mode,
    MQX_TICK_STRUCT_PTR          wtick_ptr
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _timer_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_timer_start_periodic_every_ticks, notification_function_ptr,
                    mode, wtick_ptr);

#if MQX_CHECK_ERRORS
    if ((notification_function_ptr == NULL) || (wtick_ptr == NULL))
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_timer_start_periodic_every_ticks, TIMER_NULL_ID);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    result = _timer_start_periodic_every_internal((TIMER_NOTIFICATION_FPTR)notification_function_ptr,
                    notification_data_ptr, mode, wtick_ptr, TRUE);

    _KLOGX2(KLOG_timer_start_periodic_every_ticks, result);
    return(result);

} /* Endbody */

/*!
 * \brief Starts a timer that expire after the specified number of milliseconds.
 * 
 * The function calculates the expiry time based on tick_ptr and mode.
 * \n You might need to increase the Timer Task stack size to accommodate the 
 * notification function (see _timer_create_component()).
 * 
 * \param[in] notification_function_ptr Notification function that MQX calls when 
 * the timer expires.
 * \param[in] notification_data_ptr     The data to pass to the notification 
 * function when the timer expires.
 * \param[in] mode                      Time to use when calculating the time to 
 * expire; one of the following:
 * \li TIMER_ELAPSED_TIME_MODE (Use _time_get_elapsed() or _time_get_elapsed_ticks(), 
 * which are not affected by _time_set() or _time_set_ticks().)
 * \li TIMER_KERNEL_TIME_MODE (Use _time_get() or _time_get_ticks().)
 * \param[in] milliseconds              Milliseconds to wait before MQX calls the 
 * notification function and cancels the timer.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure) 
 * 
 * \warning Creates the timer component with default values if it was not 
 * previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component() 
 * 
 * \see _timer_start_oneshot_after_ticks
 * \see _task_set_error
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see _timer_cancel
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 * \see _timer_create_component 
 */ 
_timer_id _timer_start_oneshot_after
(
    TIMER_NOTIFICATION_TIME_FPTR notification_function_ptr,
    pointer                      notification_data_ptr,
    _mqx_uint                    mode,
    uint_32                      milliseconds
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    MQX_TICK_STRUCT ticks;
    /* TIME_STRUCT                     time; */
    _timer_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_timer_start_oneshot_after, notification_function_ptr, mode,
                    milliseconds);

#if MQX_CHECK_ERRORS
    if (milliseconds == 0)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_timer_start_oneshot_after, TIMER_NULL_ID);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    /* time.SECONDS      = 0;            */
    /* time.MILLISECONDS = milliseconds; */
    /*                                   */
    /* PSP_TIME_TO_TICKS(&time, &ticks); */
    PSP_MILLISECONDS_TO_TICKS_QUICK(milliseconds, &ticks);

    result = _timer_start_oneshot_after_internal((TIMER_NOTIFICATION_FPTR)notification_function_ptr,
                    notification_data_ptr, mode, (MQX_TICK_STRUCT_PTR)&ticks, FALSE);

    _KLOGX2(KLOG_timer_start_oneshot_after, result);

    return result;

} /* Endbody */

/*!
 * \brief Starts a timer that expire once at the specified time in 
 * second/millisecond time.
 * 
 * When the timer expires, MQX calls notification_function with timer_id, 
 * notification_data_ptr, and the current time.
 * \n You might need to increase the Timer Task stack size to accommodate the 
 * notification function (see _timer_create_component()).
 *  
 * \param[in] notification_function_ptr Pointer to the notification function that 
 * MQX calls when the timer expire.
 * \param[in] notification_data_ptr     The data to pass to the function when the 
 * timer expires.
 * \param[in] mode                      Time to use when calculating the time to 
 * expire; one of the following:
 * \li TIMER_ELAPSED_TIME_MODE (Use _time_get_elapsed() or _time_get_elapsed_ticks(), 
 * which are not affected by _time_set() or _time_set_ticks().)
 * \li TIMER_KERNEL_TIME_MODE (Use _time_get() or _time_get_ticks().)
 * \param[in] time_ptr                  Pointer to the normalized second/millisecond 
 * time at which MQX calls the notification function and cancels the timer.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure) 
 * 
 * \warning Creates the timer component with default values if it was not 
 * previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component()
 * 
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_cancel
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 * \see _task_set_error
 * \see _timer_create_component   
 */ 
_timer_id _timer_start_oneshot_at
(
    TIMER_NOTIFICATION_TIME_FPTR notification_function_ptr,
    pointer          notification_data_ptr,
    _mqx_uint        mode,
    TIME_STRUCT_PTR  time_ptr
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    MQX_TICK_STRUCT ticks;
    _timer_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_timer_start_oneshot_at, notification_function_ptr, mode, time_ptr);

#if MQX_CHECK_ERRORS
    if (time_ptr == NULL)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_timer_start_oneshot_at, TIMER_NULL_ID);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    PSP_TIME_TO_TICKS(time_ptr, &ticks);

    result = _timer_start_oneshot_at_internal((TIMER_NOTIFICATION_FPTR)notification_function_ptr,
                    notification_data_ptr, mode, (MQX_TICK_STRUCT_PTR)&ticks, FALSE);

    _KLOGX2(KLOG_timer_start_oneshot_at, result);
    return(result);

} /* Endbody */

/*!
 * \brief Starts a periodic timer at the specified time in second/millisecond time.
 * 
 * You might need to increase the Timer Task stack size to accommodate the 
 * notification function (see _timer_create_component()).
 *  
 * \param[in] notification_function_ptr Pointer to the notification function that 
 * MQX calls when the timer expire.
 * \param[in] notification_data_ptr     The data to pass to the function when the 
 * timer expires.
 * \param[in] mode                      Time to use when calculating the time to 
 * expire; one of the following:
 * \li TIMER_ELAPSED_TIME_MODE (Use _time_get_elapsed() or _time_get_elapsed_ticks(), 
 * which are not affected by _time_set() or _time_set_ticks().)
 * \li TIMER_KERNEL_TIME_MODE (Use _time_get() or _time_get_ticks().)
 * \param[in] time_ptr                  Pointer to the normalized second/millisecond 
 * time at which MQX starts calling the notification function.
 * \param[in] milliseconds              Milliseconds that MQX waits between 
 * subsequent calls to the notification function.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure) 
 * 
 * \warning Creates the timer component with default values if it was not 
 * previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component()
 * 
 * \see _timer_start_periodic_at_ticks
 * \see _timer_cancel
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _task_set_error
 * \see _timer_create_component   
 */
_timer_id _timer_start_periodic_at
(
    TIMER_NOTIFICATION_TIME_FPTR notification_function_ptr,
    pointer          notification_data_ptr,
    _mqx_uint        mode,
    TIME_STRUCT_PTR  time_ptr,
    uint_32          milliseconds
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    MQX_TICK_STRUCT stick;
    MQX_TICK_STRUCT wtick;
    /* TIME_STRUCT                     wtime; */
    _timer_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_timer_start_periodic_at, notification_function_ptr, mode,
                    time_ptr);

#if MQX_CHECK_ERRORS
    if ((notification_function_ptr == NULL) ||
                    (time_ptr == NULL) ||
                    (milliseconds == 0))
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_timer_start_periodic_at, TIMER_NULL_ID);
        return TIMER_NULL_ID;
    } /* Endif */
#endif

    PSP_TIME_TO_TICKS(time_ptr, &stick);

    /* wtime.SECONDS      = 0;            */
    /* wtime.MILLISECONDS = milliseconds; */
    /*                                    */
    /* PSP_TIME_TO_TICKS(&wtime, &wtick); */
    PSP_MILLISECONDS_TO_TICKS_QUICK(milliseconds, &wtick);

    result = _timer_start_periodic_at_internal((TIMER_NOTIFICATION_FPTR)notification_function_ptr,
                    notification_data_ptr, mode, (MQX_TICK_STRUCT_PTR)&stick,
                    (MQX_TICK_STRUCT_PTR)&wtick, FALSE);

    _KLOGX2(KLOG_timer_start_periodic_at, result);

    return(result);

} /* Endbody */

/*!
 * \brief Starts a periodic timer every specified number of milliseconds.
 * 
 * When the timer expires, MQX calls notification_function with timer_id, notifier 
 * data, and the current time.
 * \n You might need to increase the Timer Task stack size to accommodate the 
 * notification function (see _timer_create_component()).
 *  
 * \param[in] notification_function_ptr Pointer to the notification function that 
 * MQX calls when the timer expire.
 * \param[in] notification_data_ptr     Pointer to the data that MQX passes to 
 * the notification function.
 * \param[in] mode                      Time to use when calculating the time to 
 * expire; one of the following:
 * \li TIMER_ELAPSED_TIME_MODE (Use _time_get_elapsed() or _time_get_elapsed_ticks(), 
 * which are not affected by _time_set() or _time_set_ticks().)
 * \li TIMER_KERNEL_TIME_MODE (Use _time_get() or _time_get_ticks().)
 * \param[in] milliseconds              Milliseconds that MQX waits before it 
 * first calls the notification function and between subsequent calls to the 
 * notification function.
 * 
 * \return Timer ID (success)
 * \return TIMER_NULL_ID (failure) 
 * 
 * \warning Creates the timer component with default values if it was not 
 * previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_COMPONENT_BASE (Timer component data is no longer valid.)
 * \li MQX_INVALID_PARAMETER (One of the following: mode is not one of the 
 * allowed modes, notification_function is NULL, milliseconds is 0 or 
 * tick_time_ptr is NULL.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the timer data.)
 * \li MQX_INVALID_LWSEM
 * \li return code from _timer_create_component() 
 * 
 * \see _timer_start_periodic_every_ticks
 * \see _timer_cancel
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _task_set_error
 * \see _timer_create_component 
 */
_timer_id _timer_start_periodic_every
(
    TIMER_NOTIFICATION_TIME_FPTR notification_function_ptr,
    pointer          notification_data_ptr,
    _mqx_uint        mode,
    uint_32          milliseconds
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    MQX_TICK_STRUCT wticks;
    /* TIME_STRUCT                    wtime; */
    _timer_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_timer_start_periodic_every, notification_function_ptr, mode,
                    milliseconds);

    /* wtime.SECONDS      = 0;             */
    /* wtime.MILLISECONDS = milliseconds;  */
    /*                                     */
    /* PSP_TIME_TO_TICKS(&wtime, &wticks); */
    PSP_MILLISECONDS_TO_TICKS_QUICK(milliseconds, &wticks);

    result = _timer_start_periodic_every_internal((TIMER_NOTIFICATION_FPTR)notification_function_ptr,
                    notification_data_ptr, mode, (MQX_TICK_STRUCT_PTR)&wticks, FALSE);

    _KLOGX2(KLOG_timer_start_periodic_every, result);
    return(result);

} /* Endbody */

/*!
 * \brief This task runs the timer queues, calling the notification functions as 
 * required.
 * 
 * \param[in] fake_parameter Fake parameter.
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_LWSEM
 */ 
void _timer_task
(
    uint_32 fake_parameter
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    TIMER_ENTRY_STRUCT_PTR     timer_entry_ptr;
    QUEUE_STRUCT_PTR           queue_ptrs[2];
    QUEUE_STRUCT_PTR           queue_ptr;
#if MQX_TIMER_USES_TICKS_ONLY==0
    TIME_STRUCT                time;
#endif
    MQX_TICK_STRUCT            ticks;
    _mqx_uint                  i;
    _mqx_int                   result;

    _GET_KERNEL_DATA(kernel_data);

    timer_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
#if MQX_CHECK_ERRORS
    if (timer_component_ptr == NULL)
    {
        _task_block();
    } /* Endif */
#endif

    timer_component_ptr->TIMER_TD_PTR = kernel_data->ACTIVE_PTR;
    _QUEUE_INIT(&timer_component_ptr->ELAPSED_TIMER_ENTRIES, 0);
    _QUEUE_INIT(&timer_component_ptr->KERNEL_TIMER_ENTRIES, 0);
    _lwsem_create(&timer_component_ptr->TIMER_ISR_LWSEM, 0);
    _lwsem_create(&timer_component_ptr->TIMER_ENTRIES_LWSEM, 1);
    timer_component_ptr->VALID = TIMER_VALID;

    kernel_data->TIMER_COMPONENT_ISR = _timer_isr;
    queue_ptrs[0] = &timer_component_ptr->ELAPSED_TIMER_ENTRIES;
    queue_ptrs[1] = &timer_component_ptr->KERNEL_TIMER_ENTRIES;

    while (TRUE)
    {

        for (i = 0; i < 2; ++i)
        {

            queue_ptr = queue_ptrs[i];

            /* Stop tasks from accessing the timer entries table */
            if (_lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM) != MQX_OK)
            {
                _task_set_error(MQX_INVALID_LWSEM);
                _task_block();
            } /* Endif */

            while (queue_ptr->SIZE > 0)
            {
                /* 
                 * Check the first entry on the queue to see if it has expired 
                 * Note that entries are always put into the list in sorted order.
                 */
                timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)
                ((pointer)queue_ptr->NEXT);
                if (i == 0)
                {
                    _time_get_elapsed_ticks(&ticks);
                }
                else
                {
                    _time_get_ticks(&ticks);
                } /* Endif */

                result = PSP_CMP_TICKS(&timer_entry_ptr->EXPIRATION_TIME, &ticks);

                if (result <= 0)
                {
                    /* This entry has expired, remove it from the queue */
                    _QUEUE_REMOVE(queue_ptr, timer_entry_ptr);

                    timer_component_ptr->ENTRY_PTR = timer_entry_ptr;

                    /* fire its notification function */

                    if (timer_entry_ptr->VALID)
                    {

#if MQX_TIMER_USES_TICKS_ONLY==0
                        if (!timer_entry_ptr->USES_TICKS)
                        {
                            PSP_TICKS_TO_TIME(&ticks, &time);
                            (*(TIMER_NOTIFICATION_TIME_FPTR)timer_entry_ptr->NOTIFICATION_FUNCTION)(
                                            timer_entry_ptr->ID,
                                            timer_entry_ptr->NOTIFICATION_DATA_PTR, time.SECONDS,
                                            time.MILLISECONDS);
                        }
                        else
                        {
#endif
                            (*(TIMER_NOTIFICATION_TICK_FPTR)timer_entry_ptr->NOTIFICATION_FUNCTION)(
                                            timer_entry_ptr->ID,
                                            timer_entry_ptr->NOTIFICATION_DATA_PTR,
                                            (pointer)&ticks);
#if MQX_TIMER_USES_TICKS_ONLY==0
                        } /* Endif */
#endif
                    }

                    /* This entry may be a one-shot, in which case it is to be deleted */
                    if (IS_ONESHOT(timer_entry_ptr->TIMER_TYPE) ||
                                    (timer_entry_ptr->VALID==0))
                    {
                        timer_entry_ptr->VALID = 0;
                        _mem_free(timer_entry_ptr);
                    }
                    else
                    {
                        /* Calculate next firing period */
                        PSP_ADD_TICKS(&timer_entry_ptr->EXPIRATION_TIME,
                                        &timer_entry_ptr->CYCLE,
                                        &timer_entry_ptr->EXPIRATION_TIME);
                        _timer_insert_queue_internal(queue_ptr, timer_entry_ptr);
                    }/* Endif */

                }
                else
                {
                    /* This queue does not require work */
                    break;
                }/* Endif */

            } /* Endwhile */

            if (_lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM) !=
                            MQX_OK)
            {
                _task_set_error(MQX_INVALID_LWSEM);
                _task_block();
            } /* Endif */

        } /* Endfor */

        /* wait until activation from the kernel timer isr */
        if (_lwsem_wait(&timer_component_ptr->TIMER_ISR_LWSEM) != MQX_OK)
        {
            _task_set_error(MQX_INVALID_LWSEM);
            _task_block();
        } /* Endif */

    } /* Endwhile */

} /* Endbody */

/*!
 * \brief Check the timer queues and if a timer is pending schedule the timer 
 * task to run. 
 * 
 * This function is called from the kernel timer ISR.
 * 
 *  
 */ 
void _timer_isr(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    TIMER_ENTRY_STRUCT_PTR     timer_entry_ptr;
    MQX_TICK_STRUCT            kernel_time;
    _mqx_int                   result;

    _GET_KERNEL_DATA(kernel_data);

    timer_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
#if MQX_CHECK_ERRORS
    if (timer_component_ptr == NULL)
    {
        return;
    } /* Endif */
#endif

    if (timer_component_ptr->TIMER_TD_PTR->STATE == READY)
    {
        return;
    }/* Endif */

    _time_get_elapsed_ticks(&kernel_time);
    if (_QUEUE_GET_SIZE(&timer_component_ptr->ELAPSED_TIMER_ENTRIES))
    {
        timer_entry_ptr = (pointer)timer_component_ptr->ELAPSED_TIMER_ENTRIES.NEXT;
        result = PSP_CMP_TICKS(&kernel_time, &timer_entry_ptr->EXPIRATION_TIME);
        if (result >= 0)
        {
            _lwsem_post(&timer_component_ptr->TIMER_ISR_LWSEM);
            return;
        }/* Endif */
    }/* Endif */

    if (_QUEUE_GET_SIZE(&timer_component_ptr->KERNEL_TIMER_ENTRIES))
    {
        PSP_ADD_TICKS(&kernel_time, &kernel_data->TIME_OFFSET, &kernel_time);
        timer_entry_ptr = (pointer)timer_component_ptr->KERNEL_TIMER_ENTRIES.NEXT;
        result = PSP_CMP_TICKS(&kernel_time, &timer_entry_ptr->EXPIRATION_TIME);
        if (result >= 0)
        {
            _lwsem_post(&timer_component_ptr->TIMER_ISR_LWSEM);
            return;
        }/* Endif */
    }/* Endif */

} /* Endbody */

/*!
 * \private
 * 
 * \brief Insert timer_entry_ptr into the queue by time with lowest time first.
 * 
 * \param[in] queue_ptr       The queue to insert onto.
 * \param[in] timer_entry_ptr The entry to insert into the queue.
 */ 
void _timer_insert_queue_internal
(
    register QUEUE_STRUCT_PTR       queue_ptr,
    register TIMER_ENTRY_STRUCT_PTR timer_entry_ptr
)
{ /* Body */
    /* The element on the queue to start inserting from */
    register TIMER_ENTRY_STRUCT_PTR element_ptr;
    register TIMER_ENTRY_STRUCT_PTR prev_ptr;
    register _mqx_int               result;

    prev_ptr = NULL;
    element_ptr = (pointer)queue_ptr->NEXT;
    while (element_ptr != (pointer)queue_ptr)
    {
        result = PSP_CMP_TICKS(&element_ptr->EXPIRATION_TIME,
                        &timer_entry_ptr->EXPIRATION_TIME);
        if (MQX_DELAY_ENQUEUE_POLICY(result))
        {
            /* Found the spot to insert it */
            break;
        }/* Endif */
        prev_ptr = element_ptr;
        element_ptr = (pointer)element_ptr->QUEUE_ELEMENT.NEXT;
    } /* Endwhile */

    _queue_insert(queue_ptr, (QUEUE_ELEMENT_STRUCT_PTR)((pointer)prev_ptr),
                    (QUEUE_ELEMENT_STRUCT_PTR)((pointer)timer_entry_ptr));

} /* Endbody */

/*!
 * \private
 * 
 * \brief Create a new timer ID
 * 
 * \param[in] timer_component_ptr The address of the timer component structure.
 * 
 * \return New timer ID. 
 */ 
_timer_id _timer_alloc_id_internal
(
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr
)
{ /* Body */
    QUEUE_STRUCT_PTR       queue_ptr;
    TIMER_ENTRY_STRUCT_PTR timer_entry_ptr;
    _timer_id              id;
    boolean                ok;
    _mqx_uint              i;
    _mqx_uint              size;

    if (timer_component_ptr->ID == 0)
    {
        timer_component_ptr->ID = 1;
    } /* Endif */
    id = timer_component_ptr->ID;

    /* Make sure ID not in use */
    ok = FALSE;
    while (!ok)
    {
        ok = TRUE;
        for (i = 0; (i < 2) && ok; i++)
        {
            if (i == 0)
            {
                queue_ptr = &timer_component_ptr->ELAPSED_TIMER_ENTRIES;
            }
            else
            {
                queue_ptr = &timer_component_ptr->KERNEL_TIMER_ENTRIES;
            } /* Endif */
            timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)((pointer)queue_ptr->NEXT);
            /* SPR P171-0023-01 use pre-decrement on while loop */
            size = queue_ptr->SIZE + 1;
            while (--size)
            {
                /* END SPR */
                if (timer_entry_ptr->ID == id)
                {
                    ok = FALSE;
                    id++;
                    break;
                } /* Endif */
                timer_entry_ptr = (TIMER_ENTRY_STRUCT_PTR)
                ((pointer)timer_entry_ptr->QUEUE_ELEMENT.NEXT);
            } /* Endwhile */
        } /* Endfor */
    } /* Endwhile */

    timer_component_ptr->ID = id + 1;

    return(id);

} /* Endbody */

/*!
 * \brief This is the function that is called by a task during task destruction, 
 * in order to cleanup any timers.
 * 
 * \param[in] td_ptr The task being destroyed. 
 */ 
void _timer_cleanup
(
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    QUEUE_STRUCT_PTR           queue_ptr;
    TIMER_ENTRY_STRUCT_PTR     element_ptr;
    TIMER_ENTRY_STRUCT_PTR     next_element_ptr;

    _GET_KERNEL_DATA(kernel_data);

    timer_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
    if (timer_component_ptr == NULL)
    {
        return;
    } /* Endif */

    /* Gain exclusive access to the timer queues */
    _lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM);

    queue_ptr = (QUEUE_STRUCT_PTR)&timer_component_ptr->ELAPSED_TIMER_ENTRIES;
    element_ptr = (TIMER_ENTRY_STRUCT_PTR)((pointer)queue_ptr->NEXT);
    while ((pointer)element_ptr != (pointer)queue_ptr)
    {
        next_element_ptr = (TIMER_ENTRY_STRUCT_PTR)
        ((pointer)element_ptr->QUEUE_ELEMENT.NEXT);
        if (element_ptr->TD_PTR == td_ptr)
        {
            _QUEUE_REMOVE(queue_ptr, element_ptr);
            element_ptr->VALID = 0;
            _mem_free(element_ptr);
        } /* Endif */
        element_ptr = next_element_ptr;
    } /* Endwhile */

    queue_ptr = (QUEUE_STRUCT_PTR)
    ((pointer)&timer_component_ptr->KERNEL_TIMER_ENTRIES);
    element_ptr = (TIMER_ENTRY_STRUCT_PTR)((pointer)queue_ptr->NEXT);
    while ((pointer)element_ptr != (pointer)queue_ptr)
    {
        next_element_ptr = (TIMER_ENTRY_STRUCT_PTR)
        ((pointer)element_ptr->QUEUE_ELEMENT.NEXT);
        if (element_ptr->TD_PTR == td_ptr)
        {
            _QUEUE_REMOVE(queue_ptr, element_ptr);
            element_ptr->VALID = 0;
            _mem_free(element_ptr);
        } /* Endif */
        element_ptr = next_element_ptr;
    } /* Endwhile */

    _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);

} /* Endbody */

/*!
 * \brief Tests the timer component for validity and consistency.
 * 
 * \param[out] timer_error_ptr Pointer to the first timer entry that has an error.
 * 
 * \return MQX_OK
 * \return MQX_INVALID_COMPONENT_HANDLE (One of the timer entries in the timer 
 * queue is not valid (timer_error_ptr).)
 * \return MQX_CORRUPT_QUEUE (Queue of timers is not valid.)  
 * 
 * \see _timer_start_oneshot_after
 * \see _timer_start_oneshot_after_ticks
 * \see _timer_start_oneshot_at
 * \see _timer_start_oneshot_at_ticks
 * \see _timer_start_periodic_at
 * \see _timer_start_periodic_at_ticks
 * \see _timer_start_periodic_every
 * \see _timer_start_periodic_every_ticks
 * \see _timer_cancel
 */ 
_mqx_uint _timer_test
(
    pointer _PTR_ timer_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TIMER_COMPONENT_STRUCT_PTR timer_component_ptr;
    QUEUE_STRUCT_PTR           queue_ptr;
    TIMER_ENTRY_STRUCT_PTR     element_ptr;
    _mqx_uint                  result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_timer_test, timer_error_ptr);

    *timer_error_ptr = NULL;

    timer_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
    if (timer_component_ptr == NULL)
    {
        _KLOGX2(KLOG_timer_test, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    /* Gain exclusive access to the timer queues */
    _lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM);

    result = _queue_test(&timer_component_ptr->ELAPSED_TIMER_ENTRIES,
                    timer_error_ptr);
    if (result != MQX_OK)
    {
        _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
        _KLOGX3(KLOG_timer_test, result, *timer_error_ptr);
        return(result);
    } /* Endif */

    result = _queue_test(&timer_component_ptr->KERNEL_TIMER_ENTRIES,
                    timer_error_ptr);
    if (result != MQX_OK)
    {
        _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
        _KLOGX3(KLOG_timer_test, result, *timer_error_ptr);
        return(result);
    } /* Endif */

    queue_ptr = (pointer)&timer_component_ptr->ELAPSED_TIMER_ENTRIES;
    element_ptr = (pointer)queue_ptr->NEXT;
    while (element_ptr != (pointer)queue_ptr)
    {
#if MQX_CHECK_VALIDITY
        if (element_ptr->VALID != TIMER_VALID)
        {
            *timer_error_ptr = element_ptr;
            _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
            _KLOGX3(KLOG_timer_test, MQX_INVALID_COMPONENT_HANDLE,
                            *timer_error_ptr);
            return(MQX_INVALID_COMPONENT_HANDLE);
        } /* Endif */
#endif
        element_ptr = (pointer)element_ptr->QUEUE_ELEMENT.NEXT;
    } /* Endwhile */

    queue_ptr = (pointer)&timer_component_ptr->KERNEL_TIMER_ENTRIES;
    element_ptr = (pointer)queue_ptr->NEXT;
    while (element_ptr != (pointer)queue_ptr)
    {
#if MQX_CHECK_VALIDITY
        if (element_ptr->VALID != TIMER_VALID)
        {
            *timer_error_ptr = element_ptr;
            _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
            _KLOGX3(KLOG_timer_test, MQX_INVALID_COMPONENT_HANDLE,
                            *timer_error_ptr);
            return(MQX_INVALID_COMPONENT_HANDLE);
        } /* Endif */
#endif
        element_ptr = (pointer)element_ptr->QUEUE_ELEMENT.NEXT;
    } /* Endwhile */

    _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
    _KLOGX2(KLOG_timer_test, MQX_OK);
    return(MQX_OK);

} /* Endbody */

#endif /* MQX_USE_TIMER */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2009 Embedded Access Inc.;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_prv.h$
* $Version : 3.8.18.1$
* $Date    : Oct-8-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the ethernet drivers for the ColdFire 32-bit MACNET 
*
*END************************************************************************/
#ifndef _macnet_prv_h
#define _macnet_prv_h 1

#include "macnet_1588.h"
#include "lwevent.h"

#define MACNET_RESET_TIMEOUT       (0x10000)

#define MACNET_RX_ALIGN(n) ENET_ALIGN(n,MACNET_RX_BUFFER_ALIGNMENT)
#define MACNET_TX_ALIGN(n) ENET_ALIGN(n,MACNET_TX_BUFFER_ALIGNMENT)
#define MACNET_BD_ALIGN(n) ENET_ALIGN(n,MACNET_BD_ALIGNMENT)

#define MACNET_NUM_ISRS      5

/* Assumes RX_BUFFER_SIZE >= 256, so that 256*6=1536, set higher for smaller RX_BUFFER_SIZE */
#define MACNET_MAX_FRAGS     6     

#define MACNET_int_disable()       _int_disable()
#define MACNET_int_enable()        _int_enable()
                                 


/* Set ENETCFG_SUPPORT_FRAGMENTED_PCBS to 1 if the upper layer can support receive PCBs with multiple
 fragments.  NOTE: RTCS currently does not support this.*/
#ifndef ENETCFG_SUPPORT_FRAGMENTED_PCBS
   #define ENETCFG_SUPPORT_FRAGMENTED_PCBS 0
#endif

/* Allow timestamping functionality */
#ifndef ENETCFG_SUPPORT_PTP
   #define ENETCFG_SUPPORT_PTP 0
#endif

#define BD_INC(index,maxnum)   if (++index == maxnum) index = 0


#ifdef __cplusplus
extern "C" {
#endif

#if PSP_MQX_CPU_IS_VYBRID
#define ENET_INT_RX_TX        0       /* Vybrid MACNET interrupt */ 
#define ENET_NUM_INTS         1   
#else
#define ENET_INT_TX_INTF      0       /* Transmit frame interrupt */
#define ENET_INT_TX_INTB      1       /* Transmit buffer interrupt */
#define ENET_INT_TX_UN        2       /* Transmit FIFO underrun */
#define ENET_INT_RL           3       /* Collision retry limit */
#define ENET_INT_RX_INTF      4       /* Receive frame interrupt */
#define ENET_INT_RX_INTB      5       /* Receive buffer interrupt */
#define ENET_INT_MII          6       /* MII interrupt */
#define ENET_INT_LC           7       /* Late collision */
#define ENET_INT_GRA          8       /* Graceful stop complete */
#define ENET_INT_EBERR        9       /* Ethernet bus error */
#define ENET_INT_BABT        10       /* Babbling transmit error */
#define ENET_INT_BABR        11       /* Babbling receive error */
#define ENET_INT_TS_AVAIL    12       /* Timestamp available */
#define ENET_INT_WAKEUP      13       /* Wake from sleep */
#define ENET_INT_PLR         14       /* Payload receive error */
#define ENET_INT_TS_TIMER    15       /* TS timer overflow */
#define ENET_NUM_INTS        16      
#endif //END PSP_MQX_CPU_IS_VYBRID

/* Ethernet Buffer descriptor bits */
#define ENET_BD_ETHER_RX_EMPTY                (1<<15)
#define ENET_BD_ETHER_RX_SOFTWARE_OWNERSHIP_1 (1<<14)
#define ENET_BD_ETHER_RX_WRAP                 (1<<13)
#define ENET_BD_ETHER_RX_SOFTWARE_OWNERSHIP_2 (1<<12)
#define ENET_BD_ETHER_RX_LAST_FRAME           (1<<11)
#define ENET_BD_ETHER_RX_MISS                 (1<<8)
#define ENET_BD_ETHER_RX_BROADCAST            (1<<7)
#define ENET_BD_ETHER_RX_MULTICAST            (1<<6)
#define ENET_BD_ETHER_RX_LENGTH_VIOLATION     (1<<5)
#define ENET_BD_ETHER_RX_NON_OCTET            (1<<4)
#define ENET_BD_ETHER_RX_CRC_ERROR            (1<<2)
#define ENET_BD_ETHER_RX_OVERRUN              (1<<1)
#define ENET_BD_ETHER_RX_TRUNCATED            (1<<0)

#define ENET_BD_EXT0_ETHER_RX_MAC_ERR         (1<<15)
#define ENET_BD_EXT0_ETHER_RX_PHY_ERR         (1<<10)
#define ENET_BD_EXT0_ETHER_RX_COLLISION       (1<<9)
#define ENET_BD_EXT0_ETHER_RX_UNICAST         (1<<8)
#define ENET_BD_EXT0_ETHER_RX_GENERATE_INTR   (1<<7)

#define ENET_BD_EXT1_ETHER_RX_IPHEADER_CHSUM_ERR  (1<<5)
#define ENET_BD_EXT1_ETHER_RX_PROTOCOL_CHSUM_ERR  (1<<4)
#define ENET_BD_EXT1_ETHER_RX_VLAN                (1<<2)
#define ENET_BD_EXT1_ETHER_RX_IPV6FRAME           (1<<1)
#define ENET_BD_EXT1_ETHER_RX_IPV4FRAGMENT        (1<<0)

#define ENET_BD_EXT2_ETHER_RX_LAST_BD_UPDATE_DONE 		(1<<15)

#define ENET_BD_ETHER_TX_READY                			(1<<15)
#define ENET_BD_ETHER_TX_SOFTWARE_OWNERSHIP_1 			(1<<14)
#define ENET_BD_ETHER_TX_WRAP                 			(1<<13)
#define ENET_BD_ETHER_TX_SOFTWARE_OWNERSHIP_2 			(1<<12)
#define ENET_BD_ETHER_TX_LAST                 			(1<<11)
#define ENET_BD_ETHER_TX_SEND_CRC             			(1<<10)

#define ENET_BD_EXT0_ETHER_TX_GENERATE_INTR          	(1<<14)
#define ENET_BD_EXT0_ETHER_TX_TIMESTAMP              	(1<<13)
#define ENET_BD_EXT0_ETHER_TX_INSERT_PROT_SPEC_CHSUM 	(1<<12)
#define ENET_BD_EXT0_ETHER_TX_INSERT_IPHEADER_CHSUM  	(1<<11)

#define ENET_BD_EXT1_ETHER_TX_ERR                  		(1<<15)
#define ENET_BD_EXT1_ETHER_TX_UNDERFLOW_ERR        		(1<<13)
#define ENET_BD_EXT1_ETHER_TX_EXCESS_COLLISION_ERR 		(1<<12)
#define ENET_BD_EXT1_ETHER_TX_FRAME_WIDTH_ERR      		(1<<11)
#define ENET_BD_EXT1_ETHER_TX_LATE_COLLISION_ERR   		(1<<10)
#define ENET_BD_EXT1_ETHER_TX_LATE_OVERFLOW_ERR    		(1<<9)
#define ENET_BD_EXT1_ETHER_TX_LATE_TIMESTAMP_ERR   		(1<<8)

#define ENET_BD_EXT2_ETHER_TX_LAST_BD_UPDATE_DONE  		(1<<15)

#define ENET_EIR_ALL_PENDING 							(0x7FFF8000)
	
typedef uint_16 bd_index_t;


#if ENETCFG_SUPPORT_FRAGMENTED_PCBS

   typedef struct macnet_rx_pcb
   {
      PCB            _FRAG0;
      PCB_FRAGMENT   _FRAGS[MACNET_MAX_FRAGS];
      PCB_FRAGMENT   _FREE_FRAG;
   } MACNET_RX_PCB, _PTR_ MACNET_RX_PCB_PTR;
#else
   typedef PCB2 MACNET_RX_PCB, _PTR_ MACNET_RX_PCB_PTR;
#endif



/* The Ethernet initialization structure */
typedef struct {
   uint_32      BUS_CLOCK;
   _mqx_uint    ERX_LEVEL;      /* Receive interrupt level */
   _mqx_uint    ERX_SUBLEVEL;   /* Receive interrupt sublevel */
   _mqx_uint    ETX_LEVEL;      /* Transmit interrupt level */
   _mqx_uint	ETX_SUBLEVEL;   /* Transmit interrupt sublevel */
} MACNET_INIT_STRUCT, _PTR_ MACNET_INIT_STRUCT_PTR;


#define MACNET_PTP_DEFAULT_RX_BUF_SZ      25
#define MACNET_PTP_DEFAULT_L2PCK_BUF_SZ   10

#define MACNET_PTP_MSG_SYNC              0x0
#define MACNET_PTP_MSG_DEL_REQ           0x1
#define MACNET_PTP_MSG_P_DEL_REQ         0x2
#define MACNET_PTP_MSG_P_DEL_RESP        0x3
#define MACNET_PTP_MSG_DEL_RESP          0x4
#define MACNET_PTP_MSG_ALL_OTHER         0x5

#define MACNET_PTP_UDP_IPLENGHT_OFFS     0x10
#define MACNET_PTP_UDP_PKT_TYPE_OFFS     0x17
#define MACNET_PTP_UDP_IPCHECKSUM_OFFS   0x18
#define MACNET_PTP_UDP_MULTI_ADDR_OFFS   0x1E
#define MACNET_PTP_UDP_PORT_OFFS         0x24
#define MACNET_PTP_UDP_UDPLENGHT_OFFS    0x26
#define MACNET_PTP_UDP_UDPCHECKSUM_OFFS  0x28
#define MACNET_PTP_UDP_MSG_TYPE_OFFS     0x2A
#define MACNET_PTP_UDP_CLOCKID           0x3E
#define MACNET_PTP_UDP_SEQ_ID_OFFS       0x48
#define MACNET_PTP_UDP_CTRL_OFFS         0x4A

#define MACNET_PTP_ETHER_PKT_TYPE_OFFS   0x0C
#define MACNET_PTP_ETHER_MSG_TYPE_OFFS   0x0E
#define MACNET_PTP_ETHER_CLOCKID         0x22
#define MACNET_PTP_ETHER_SEQ_ID_OFFS     0x2C
#define MACNET_PTP_ETHER_CTRL_OFFS       0x2E

#define MACNET_PACKET_TYPE_UDP           0x11
#define MACNET_PACKET_TYPE_IEEE_802_3    0x88F7
#define MACNET_PTP_EVNT_PORT             (319)
#define MACNET_PTP_GNRL_PORT             (320)

#define MACNET_PTP_LWEVENT_RX_TS         0x01
#define MACNET_PTP_LWEVENT_TX_TS         0x02
#define MACNET_PTP_LWEVENT_TX_TS_INTR    0x04

#define MACNET_PTP_COMM_PROTO_UDP_IPv4   0x01
#define MACNET_PTP_COMM_PROTO_UDP_IPv6   0x02
#define MACNET_PTP_COMM_PROTO_IEEE_802_3 0x03

#define MACNET_PTP_CLOCKID_SIZE          0x08


/* Structure for PTP Time Stamp */
typedef struct {
	uint_32		    KEY;
	uint_8          CLOCKID[10];
	MACNET_PTP_TIME	TS_TIME;
} MACNET_PTP_DATA;

typedef struct {
	uint_32	        FRONT;
	uint_32	        END;
	uint_32	        SIZE;
	MACNET_PTP_DATA *DATA_BUF;
} MACNET_PTP_CIRCULAR,  _PTR_ MACNET_PTP_CIRCULAR_PTR;

typedef struct 
{
  uint_8  PACKET[ENET_FRAMESIZE_MAXDATA];
  uint_16 LENGTH;
} MACNET_PTP_L2PKT;

typedef struct 
{
  /* Packet queue array */
  MACNET_PTP_L2PKT L2PCK[MACNET_PTP_DEFAULT_L2PCK_BUF_SZ];
  /* Queue write index */ 
  uint_32 WR_IDX;
  /* Queue read index */ 
  uint_32 RD_IDX;
} MACNET_PTP_L2QUEUE,  _PTR_ MACNET_PTP_L2QUEUE_PTR;

typedef struct {	
	ENET_MemMapPtr            MACNET_PTR;
	MACNET_PTP_CIRCULAR       RX_TIME_SYNC;
	MACNET_PTP_CIRCULAR       RX_TIME_DEL_REQ;
	MACNET_PTP_CIRCULAR       RX_TIME_PDEL_REQ;
	MACNET_PTP_CIRCULAR       RX_TIME_PDEL_RESP;
	MACNET_PTP_CIRCULAR       TX_TIME;
	LWEVENT_STRUCT            LWEVENT_PTP;
    uint_32                   PTIMER_PRESENT;
	MACNET_PTP_TIME           TXSTAMP;
	MACNET_PTP_L2QUEUE_PTR    L2PCKS_PTR;
} MACNET_PTP_PRIVATE,  _PTR_ MACNET_PTP_PRIVATE_PTR;


/*
** ENET_BD_STRUCT
** This structure defines what the Ethernet buffer descriptor looks like
*/
typedef struct enet_bd_struct
{
   uint_16   CONTROL;
   uint_16   LENGTH;
   uchar_ptr BUFFER;
   uint_16   CONTROL_EXT0;
   uint_16   CONTROL_EXT1;
   uint_8    HEADER_LENGTH;
   uint_8    PROTOCOL_TYPE;
   uint_16   PAYLOAD_CHECKSUM;
   uint_16   CONTROL_EXT2;
   uint_16   reserved0;
   uchar_ptr TIMESTAMP;
   uint_16   reserved1;
   uint_16   reserved2;
   uint_16   reserved3;
   uint_16   reserved4;
} ENET_BD_STRUCT, _PTR_ ENET_BD_STRUCT_PTR;
typedef volatile struct enet_bd_struct _PTR_ VENET_BD_STRUCT_PTR;



typedef struct mcf_macnet_context_struct {
    ENET_MemMapPtr        MACNET_ADDRESS;
    ENET_MemMapPtr        PHY_PTR;
    uint_16               AlignedRxBufferSize;
    uint_16               AlignedTxBufferSize;
   
   /*
   **    The Receive-Side State
   **
   ** RxPCBHead and RxPCBTail are the head and tail of a linked list
   ** of available PCBs for receiving packets.  RxEntries is
   ** the length of this list.
   **
   ** NextRxBD points to the 'first' queued receive descriptor, i.e., usually
   ** the one that RBPTR is pointing to.  When an RXF interrupt occurs,
   ** NextRxBD is pointing to the first descriptor with a received packet.
   ** The packets is forwarded to the upper layers, and NextRxBD is incremented.
   **
   ** LastRxBD points to the 'last' queued receive descriptor, i.e., the last
   ** one with E=1.  The LastRxBD descriptor usually precedes the LastRxBD descriptor.
   ** When the upper layers free a received packet, it gets placed at LastRxBD
   ** (with E=1), and LastRxBD is incremented.
   */

   PCB_PTR                       RxPCBHead;
   PCB_PTR                       RxPCBTail;
   
   uint_32                       CurrentRxFrag;
   ENET_ECB_STRUCT_PTR           CurrentRxECB;
#if ENETCFG_SUPPORT_FRAGMENTED_PCBS
   PCB_PTR                       CurrentRxPCB;     /* The PCB that is currently being built */
   boolean                       RxDiscarding;
#else
   PCB_FRAGMENT                  FRAGS[MACNET_MAX_FRAGS];
#endif


   bd_index_t                    ActiveRxBDs;
   bd_index_t                    NextRxBD;
   bd_index_t                    LastRxBD;
   bd_index_t                    NumRxBDs;

   /*
   **    The Transmit-Side State
   **
   ** TxPCBS_PTR is an array of pointers to the PCBs queued on the transmit ring.
   ** AvailableTxBDs is the number of free entries on the ring.
   **
   ** NextTxBD points to the first available transmit descriptor (when AvailableTxBDs>0),
   ** or to LastTxBD (when AvailableTxBDs==NumTxBDs).  It is the descriptor that will next
   ** be queued onto the transmit ring, as soon as there's a packet to send
   ** and room on the transmit ring.
   **
   ** LastTxBD points to the 'last' queued transmit descriptor, i.e., the one
   ** that TBPTR is pointing to.  When a TXB interrupt occurs, LastTxBD is
   ** pointing to the transmitted buffer.  The buffer is freed, and LastTxBD is
   ** incremented.
   **
   ** TxErrors keeps track of all the errors that occur during transmission
   ** of a frame comprised of multiple buffers.
   */

   PCB_PTR *                     TxPCBS_PTR;
   bd_index_t                    AvailableTxBDs;
   bd_index_t                    NextTxBD;
   bd_index_t                    LastTxBD;
   bd_index_t                    NumTxBDs;
   uint_32                       TxErrors;



   MACNET_RX_PCB_PTR             RX_PCB_BASE;
   pointer                       UNALIGNED_RING_PTR;        
   VENET_BD_STRUCT_PTR           MACNET_RX_RING_PTR; 
   VENET_BD_STRUCT_PTR           MACNET_TX_RING_PTR; 
   pointer                       UNALIGNED_BUFFERS;  
   uchar_ptr                     RX_BUFFERS;  
   uchar_ptr                     TX_BUFFERS;  
   uchar_ptr                     SMALL_BUFFERS;  
   uchar_ptr                     LARGE_BUFFERS;  
   uint_32                       FREE_TX;
   uint_32                       FREE_TX_SMALL;
   
#if BSPCFG_ENET_RESTORE
   /* These fields are kept only for ENET_shutdown() */
   INT_ISR_FPTR                  OLDISR_PTR[MACNET_NUM_ISRS];
   pointer                       OLDISR_DATA[MACNET_NUM_ISRS];
#endif
      
#if ENETCFG_SUPPORT_PTP
   MACNET_PTP_PRIVATE_PTR        PTP_PRIV;
#endif
} MACNET_CONTEXT_STRUCT, * MACNET_CONTEXT_STRUCT_PTR;


extern const   MACNET_INIT_STRUCT MACNET_device[];
extern const   ENET_MAC_IF_STRUCT MACNET_IF;
extern const   uint_32 MACNET_vectors[MACNET_DEVICE_COUNT][ENET_NUM_INTS];

extern boolean MACNET_install_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr, MACNET_INIT_STRUCT const * enet_init_ptr  ); 
extern boolean MACNET_install_isr( ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 int_num, uint_32 int_index, 
                                   INT_ISR_FPTR isr, uint_32 level, uint_32 sublevel  );
extern void    MACNET_add_buffers_to_rx_ring(MACNET_CONTEXT_STRUCT_PTR macnet_context_ptr);
extern uint_32 MACNET_initialize(ENET_CONTEXT_STRUCT_PTR);
extern uint_32 MACNET_shutdown( ENET_CONTEXT_STRUCT_PTR );
extern uint_32 MACNET_send( ENET_CONTEXT_STRUCT_PTR, PCB_PTR packet, uint_32 size, uint_32 frags, uint_32 flags );
extern uint_32 MACNET_join( ENET_CONTEXT_STRUCT_PTR, ENET_MCB_STRUCT_PTR mcb_ptr );
extern uint_32 MACNET_rejoin( ENET_CONTEXT_STRUCT_PTR );
extern void    MACNET_mask_interrupts( ENET_CONTEXT_STRUCT_PTR enet_ptr ); 
extern void    MACNET_uninstall_all_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr );
extern void    MACNET_TX_ISR(pointer);
extern void    MACNET_RX_ISR(pointer);
extern pointer MACNET_get_base_address (uint_32);
extern uint_32 MACNET_get_vector(uint_32,uint_32);
extern void    MACNET_io_init(uint_32);
extern void    MACNET_free_context( MACNET_CONTEXT_STRUCT_PTR macnet_context_ptr );

#if ENETCFG_SUPPORT_PTP
extern boolean MACNET_ptp_install_ts_avail_isr( ENET_CONTEXT_STRUCT_PTR enet_ptr, MACNET_INIT_STRUCT const * enet_init_ptr ); 
extern boolean MACNET_ptp_install_ts_timer_isr( ENET_CONTEXT_STRUCT_PTR enet_ptr, MACNET_INIT_STRUCT const * enet_init_ptr ); 
extern uint_32 MACNET_ptp_init(ENET_CONTEXT_STRUCT_PTR enet_ptr);
extern void    MACNET_ptp_store_txstamp(pointer);
extern void    MACNET_ptp_store_rxstamp(ENET_CONTEXT_STRUCT_PTR enet_ptr, PCB_PTR pcb_ptr, VENET_BD_STRUCT_PTR bdp);
extern void    MACNET_ptp_increment_seconds(pointer);
extern uint_32 MACNET_ptp_start(MACNET_PTP_PRIVATE *priv, boolean master_mode);
extern void    MACNET_ptp_stop(ENET_MemMapPtr macnet_ptr);
extern void    MACNET_ptp_cleanup(ENET_CONTEXT_STRUCT_PTR enet_ptr);
extern boolean MACNET_ptp_insert(MACNET_PTP_CIRCULAR *buf, MACNET_PTP_DATA *data);
extern ENET_MemMapPtr MACNET_ptp_get_master_base_address(void);
extern void    MACNET_ptp_set_master_base_address(ENET_MemMapPtr addr);
extern int_32  MACNET_ptp_get_rx_timestamp(MACNET_PTP_PRIVATE *priv, pointer param_ptr, MACNET_PTP_TIME *rx_time);
extern int_32  MACNET_ptp_get_tx_timestamp(MACNET_PTP_PRIVATE *priv, pointer param_ptr, MACNET_PTP_TIME *tx_time);
extern void    MACNET_ptp_service_L2pckts(PCB_PTR  pcb, pointer handle);
extern int_32  MACNET_ptp_send_L2pckts(_enet_handle handle, pointer param_ptr);
extern int_32  MACNET_ptp_recv_L2pckts(_enet_handle handle, pointer param_ptr);
extern uint_32 MACNET_ptp_ioctl(ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 command_id, pointer inout_param);
#endif /* ENETCFG_SUPPORT_PTP */

boolean MACNET_read_mii(ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 reg_index, uint_32_ptr data, uint_32 timeout);
boolean MACNET_write_mii(ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 reg_index, uint_32 data, uint_32 timeout);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/i2c_mcf5225.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_mcf5225.c$
* $Version : 3.0.3.0$
* $Date    : Jun-4-2009$
*
* Comments:
*
*   This file contains board-specific I2C initialization functions.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include "i2c_mcf52xx.h"


/*FUNCTION****************************************************************
*
* Function Name    : _bsp_get_i2c_base_address
* Returned Value   : address if successful, NULL otherwise
* Comments         :
*    This function returns the base register address of the corresponding I2C device.
*
*END*********************************************************************/

pointer _bsp_get_i2c_base_address
(
   uint_8 dev_num
)
{
   pointer addr;
   
   switch (dev_num) 
   {
      case 0:
         addr = (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->I2C1);
         break;
      case 1:
         addr = (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->I2C2);
         break;
      default:
        addr = NULL;
        break;
    }
    return addr;
}


/*FUNCTION****************************************************************
*
* Function Name    : _bsp_get_i2c_vector
* Returned Value   : vector number if successful, 0 otherwise
* Comments         :
*    This function returns desired interrupt vector number for specified I2C device.
*
*END*********************************************************************/

uint_32 _bsp_get_i2c_vector
(
   uint_8 dev_num
)
{
   uint_32 vector;
   switch (dev_num) 
   {
      case 0:
         vector = MCF5225_INT_I2C0;
         break;
      case 1:
         vector = MCF5225_INT_I2C1;
         break;
      default:
         vector = 0;
         break;
    }
    return vector;
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/cdc/usb_host_cdc.h<|end_filename|>
#ifndef __usb_host_cdc_h__
#define __usb_host_cdc_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_cdc.h$
* $Version : 3.8.8.0$
* $Date    : Sep-13-2012$
*
* Comments:
*
*   This file defines a template structure for Class Drivers.
*
*END************************************************************************/
#include <mqx.h>
#include <lwevent.h>

#include <fio.h>

#include <bsp.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_rcv.h"
#include "host_ch9.h"
#include "host_snd.h"

#define USB_CDC_SET_LINE_CODING              0x20
#define USB_CDC_GET_LINE_CODING              0x21
typedef struct {
    uint_32      baudrate;
    uint_8       stopbits; /* 1 ~ 1bit, 2 ~ 2bits, 3 ~ 1.5bit */
    uint_8       parity;   /* 1 ~ even, -1 ~ odd, 0 ~ no parity */
    uint_8       databits;
} USB_CDC_UART_CODING, _PTR_ USB_CDC_UART_CODING_PTR;

/* set ouput pin state */
#define USB_CDC_SET_CTRL_LINE_STATE          0x22
typedef struct {
#define USB_ACM_LINE_STATE_DTR               0x01
#define USB_ACM_LINE_STATE_RTS               0x02
    uint_16      state;
} USB_CDC_CTRL_STATE, _PTR_ USB_CDC_CTRL_STATE_PTR;

/* receive interrupt state */
typedef struct {
    uint_8       reservedA[8];
#define USB_ACM_STATE_RX_CARRIER             0x01
#define USB_ACM_STATE_TX_CARRIER             0x02
#define USB_ACM_STATE_BREAK                  0x04
#define USB_ACM_STATE_RING_SIGNAL            0x08
#define USB_ACM_STATE_FRAMING                0x10
#define USB_ACM_STATE_PARITY                 0x20
#define USB_ACM_STATE_OVERRUN                0x40
    uint_8       bmStates;
    uint_8       reservedB[1];
} USB_CDC_ACM_STATE, _PTR_ USB_CDC_ACM_STATE_PTR;

#define USB_DESC_SUBTYPE_CS_HEADER           0x00
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bcdCDC[2];
} USB_CDC_DESC_HEADER, _PTR_ USB_CDC_DESC_HEADER_PTR;

#define USB_DESC_SUBTYPE_CS_CM               0x01
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
#define USB_ACM_CM_CAP_HANDLE_MANAGEMENT     0x01
#define USB_ACM_CM_CAP_DATA_CLASS            0x02
    uint_8   bmCapabilities;
    uint_8   bDataInterface;
} USB_CDC_DESC_CM, _PTR_ USB_CDC_DESC_CM_PTR;

#define USB_DESC_SUBTYPE_CS_ACM              0x02
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
#define USB_ACM_CAP_COMM_FEATURE             0x01
#define USB_ACM_CAP_LINE_CODING              0x02
#define USB_ACM_CAP_SEND_BREAK               0x04
#define USB_ACM_CAP_NET_NOTIFY               0x08
    uint_8   bmCapabilities;
} USB_CDC_DESC_ACM, _PTR_ USB_CDC_DESC_ACM_PTR;

#define USB_DESC_SUBTYPE_CS_DL               0x03
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bmCapabilities;
} USB_CDC_DESC_DL, _PTR_ USB_CDC_DESC_DL_PTR;

#define USB_DESC_SUBTYPE_CS_TR               0x04
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bRingerVolSteps;
    uint_8   bNumRingerPatterns;
} USB_CDC_DESC_TR, _PTR_ USB_CDC_DESC_TR_PTR;

#define USB_DESC_SUBTYPE_CS_TCS              0x05
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bmCapabilities[4];
} USB_CDC_DESC_TCS, _PTR_ USB_CDC_DESC_TCS_PTR;

#define USB_DESC_SUBTYPE_CS_UNION            0x06
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bMasterInterface;
    uint_8   bSlaveInterface[];
} USB_CDC_DESC_UNION, _PTR_ USB_CDC_DESC_UNION_PTR;

#define USB_DESC_SUBTYPE_CS_TOM              0x08
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bmCapabilities;
} USB_CDC_DESC_TOM, _PTR_ USB_CDC_DESC_TOM_PTR;

typedef union {
    USB_CDC_DESC_HEADER         header;
    USB_CDC_DESC_CM             cm;
    USB_CDC_DESC_ACM            acm;
    USB_CDC_DESC_DL             dl;
    USB_CDC_DESC_TR             tr;
    USB_CDC_DESC_TCS            tcs;
    USB_CDC_DESC_TOM            tom;
    USB_CDC_DESC_UNION          uni;
} USB_CDC_FUNC_DESC, _PTR_ USB_CDC_FUNC_DESC_PTR;

/*
** CDC Class Interface structure. This structure will be passed to
** all commands to this class driver.
*/
typedef struct usb_cdc_general_class {
    /* Each class must start with a GENERAL_CLASS struct */
    GENERAL_CLASS                             G;

    /* Higher level callback and parameter */
    tr_callback                               USER_CALLBACK;
    pointer                                   USER_PARAM;

    uint_8                                    IFNUM;

} USB_CDC_GENERAL_CLASS, _PTR_ USB_CDC_GENERAL_CLASS_PTR;

typedef struct {
    /* Each CDC subclass must start with a USB_CDC_GENERAL_CLASS struct */
    USB_CDC_GENERAL_CLASS                     CDC_G;
    USB_CDC_DESC_ACM_PTR                      acm_desc;
    USB_CDC_DESC_CM_PTR                       cm_desc;
    USB_CDC_DESC_HEADER_PTR                   header_desc;
    USB_CDC_DESC_UNION_PTR                    union_desc;
   
    USB_CDC_UART_CODING                       uart_coding;

    _usb_pipe_handle                          interrupt_pipe;
    USB_CDC_ACM_STATE                         interrupt_buffer;
    
    USB_CDC_CTRL_STATE                        ctrl_state;

#define USB_ACM_DETACH           0x01
#define USB_ACM_CTRL_PIPE_FREE   0x02
#define USB_ACM_INT_PIPE_FREE    0x04
    LWEVENT_STRUCT_PTR                        acm_event;

} USB_ACM_CLASS_INTF_STRUCT, _PTR_ USB_ACM_CLASS_INTF_STRUCT_PTR;

typedef struct {
    /* Each CDC subclass must start with a USB_CDC_GENERAL_CLASS struct */
    USB_CDC_GENERAL_CLASS                     CDC_G;
    /* Address of bound control interface */
    CLASS_CALL_STRUCT_PTR                     BOUND_CONTROL_INTERFACE;

    char_ptr                                  RX_BUFFER;
    char_ptr                                  RX_BUFFER_DRV;
    char_ptr                                  RX_BUFFER_APP;
    uint_32                                   RX_BUFFER_SIZE;
    uint_32                                   RX_READ;
    
    uint_32                                   TX_SENT;

    PIPE_STRUCT_PTR                           in_pipe;
    PIPE_STRUCT_PTR                           out_pipe;
   
    char_ptr                                  device_name;

#define USB_DATA_DETACH            0x01
#define USB_DATA_READ_COMPLETE     0x02
#define USB_DATA_READ_PIPE_FREE    0x04
#define USB_DATA_SEND_COMPLETE     0x08
#define USB_DATA_SEND_PIPE_FREE    0x10
    LWEVENT_STRUCT_PTR                        data_event;

} USB_DATA_CLASS_INTF_STRUCT, _PTR_ USB_DATA_CLASS_INTF_STRUCT_PTR;

typedef struct {
    CLASS_CALL_STRUCT_PTR   CLASS_PTR;
    tr_callback             CALLBACK_FN;
    pointer                 CALLBACK_PARAM;
} CDC_COMMAND, _PTR_ CDC_COMMAND_PTR;

typedef struct cdc_serial_init {
#define USB_UART_BLOCKING          (0x0000)
#define USB_UART_NO_BLOCKING       (0x0001)
/* NOTE!!!
** HW control flow has one weakness: we dont know exactly when DCD signal got log. 0 or
** log.1. This is because interrupts pipe is polled in time intervals in some milliseconds.
** HW flow control is here only just for compatibility purposes.
** As for output pins, we set always DTR and RTS signal for HW flow control. The user can
** still use usb_class_cdc_set_acm_ctrl_state to control those signals manually.
** Note also, that additional HW control flow is done on USB,
** which implies from USB specification (NAK responding).
*/
#define USB_UART_HW_FLOW           (0x0002)
    _mqx_uint               FLAGS;
} CDC_SERIAL_INIT, _PTR_ CDC_SERIAL_INIT_PTR;

/* Class specific functions exported by CDC class driver */
#ifdef __cplusplus
extern "C" {
#endif

extern void usb_class_cdc_acm_init(PIPE_BUNDLE_STRUCT_PTR, CLASS_CALL_STRUCT_PTR);
extern USB_STATUS usb_class_cdc_acm_use_lwevent(CLASS_CALL_STRUCT_PTR, LWEVENT_STRUCT_PTR);

extern void usb_class_cdc_data_init(PIPE_BUNDLE_STRUCT_PTR, CLASS_CALL_STRUCT_PTR);
extern USB_STATUS usb_class_cdc_data_use_lwevent(CLASS_CALL_STRUCT_PTR, LWEVENT_STRUCT_PTR);

extern CLASS_CALL_STRUCT_PTR usb_class_cdc_get_ctrl_interface(pointer);
extern CLASS_CALL_STRUCT_PTR usb_class_cdc_get_data_interface(pointer);
extern USB_STATUS usb_class_cdc_get_acm_line_coding(CLASS_CALL_STRUCT_PTR, USB_CDC_UART_CODING_PTR);
extern USB_STATUS usb_class_cdc_set_acm_line_coding(CLASS_CALL_STRUCT_PTR, USB_CDC_UART_CODING_PTR);
extern USB_STATUS usb_class_cdc_set_acm_ctrl_state(CLASS_CALL_STRUCT_PTR, uint_8, uint_8);
extern USB_STATUS usb_class_cdc_get_acm_descriptors(_usb_device_instance_handle, _usb_interface_descriptor_handle, USB_CDC_DESC_ACM_PTR _PTR_, USB_CDC_DESC_CM_PTR _PTR_, USB_CDC_DESC_HEADER_PTR _PTR_, USB_CDC_DESC_UNION_PTR _PTR_);
extern USB_STATUS usb_class_cdc_set_acm_descriptors(CLASS_CALL_STRUCT_PTR, USB_CDC_DESC_ACM_PTR, USB_CDC_DESC_CM_PTR, USB_CDC_DESC_HEADER_PTR, USB_CDC_DESC_UNION_PTR);
extern USB_STATUS usb_class_cdc_get_ctrl_descriptor(_usb_device_instance_handle, _usb_interface_descriptor_handle, INTERFACE_DESCRIPTOR_PTR _PTR_);
extern USB_STATUS usb_class_cdc_bind_data_interfaces(_usb_device_instance_handle, CLASS_CALL_STRUCT_PTR);
extern USB_STATUS usb_class_cdc_unbind_data_interfaces(CLASS_CALL_STRUCT_PTR);
extern USB_STATUS usb_class_cdc_bind_acm_interface(CLASS_CALL_STRUCT_PTR, INTERFACE_DESCRIPTOR_PTR);
extern USB_STATUS usb_class_cdc_unbind_acm_interface(CLASS_CALL_STRUCT_PTR);
extern USB_STATUS usb_class_cdc_init_ipipe(CLASS_CALL_STRUCT_PTR);
extern USB_STATUS usb_class_cdc_install_driver(CLASS_CALL_STRUCT_PTR, char_ptr);
extern USB_STATUS usb_class_cdc_uninstall_driver(CLASS_CALL_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/core_mutex/sema4_vybrid.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sema4_vybrid.c$
* $Version : 3.8.1.0$
* $Date    : Sep-25-2012$
*
* Comments:
*
*   This file contains the MPXS30 specific driver functions for the SEMA4.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>



static const pointer sema4_address[] = { (pointer)SEMA4_BASE_PTR };

#if PSP_MQX_CPU_IS_VYBRID_A5
static const uint_32 sema4_vector[] = { INT_Directed_CA5_int0 };
#else
static const uint_32 sema4_vector[] = { 20 };
#endif

SEMA4_MemMapPtr _bsp_get_sema4_base_address(uint_32 device)
{
   if (device < ELEMENTS_OF(sema4_address)) {
      return (SEMA4_MemMapPtr) sema4_address[device];
   }
   return NULL;
}

uint_32 _bsp_get_sema4_vector(uint_32 device)
{
   if (device < ELEMENTS_OF(sema4_vector)) {
      return  sema4_vector[device];
   }
   return 0;
}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb_dcd/int/usb_dcd_int_kn.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_dcd_int_kn.c$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains low level functions for the USB DCD interrupt device driver
*   for Kinetis family.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "usb_dcd.h"
#include "usb_dcd_int_prv.h"
#include "usb_dcd_kn_prv.h"


extern uint_32 _kusb_dcd_polled_init (KUSB_DCD_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _kusb_dcd_polled_ioctl (KUSB_DCD_INFO_STRUCT_PTR, uint_32, uint_32_ptr);

extern uint_32 _kusb_dcd_int_init (IO_USB_DCD_INT_DEVICE_STRUCT_PTR, char_ptr);
extern uint_32 _kusb_dcd_int_deinit (IO_USB_DCD_INT_DEVICE_STRUCT_PTR, KUSB_DCD_INFO_STRUCT_PTR);
extern uint_32 _kusb_dcd_int_read (IO_USB_DCD_INT_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _kusb_dcd_int_write (IO_USB_DCD_INT_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
static void    _kusb_dcd_isr (pointer);


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_int_install
* Returned Value   : MQX error code
* Comments         :
*    Install an USB DCD device.
*
*END*********************************************************************/

uint_32 _kusb_dcd_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr           identifier,

      /* [IN] The I/O init data pointer */
      KUSB_DCD_INIT_STRUCT_CPTR  init_data_ptr
   )
{ /* Body */

   return _io_usb_dcd_int_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, char_ptr))_kusb_dcd_int_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_kusb_dcd_int_deinit,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_kusb_dcd_int_read,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_kusb_dcd_int_write,
      (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_kusb_dcd_polled_ioctl,
      (pointer)init_data_ptr);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_int_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an USB_DCD device.
*
*END*********************************************************************/

uint_32 _kusb_dcd_int_init
   (
      /* [IN] Initialization information for the device being opened */
      IO_USB_DCD_INT_DEVICE_STRUCT_PTR  int_io_dev_ptr,

      /* [IN] The rest of the name of the device opened */
      char_ptr                      open_name_ptr

   )
{ /* Body */
   USBDCD_MemMapPtr                     usb_dcd_ptr;
   KUSB_DCD_INFO_STRUCT_PTR      		 io_info_ptr;
   KUSB_DCD_INIT_STRUCT_PTR		       usb_dcd_init_ptr;
   uint_32                        		 vector, result;

   usb_dcd_init_ptr = (KUSB_DCD_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
   result = _kusb_dcd_polled_init (usb_dcd_init_ptr,
                                     &(int_io_dev_ptr->DEV_INFO_PTR),
                                     open_name_ptr);
   if (result)
   {
      return result;
   }

   io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   io_info_ptr->METHOD = USB_DCD_INT;
   usb_dcd_ptr = io_info_ptr->USB_DCD_PTR;
   vector = _bsp_get_usb_dcd_vector();
   if (0 == vector)
   {
      return USB_DCD_ERROR_INVALID_INT_VECTOR;
   }

   /* Install new vectors and backup the old ones */
   io_info_ptr->OLD_ISR_DATA = _int_get_isr_data (vector);
   io_info_ptr->OLD_ISR = _int_install_isr (vector, _kusb_dcd_isr, io_info_ptr);

   /* Enable USB DCD interrupts */
#ifndef BSP_TWRMCF51JF
   _bsp_int_init((IRQInterruptIndex)_bsp_get_usb_dcd_vector(), io_info_ptr->INIT.LEVEL, 0, TRUE);
   NVICICER2|=(1<<10);
   NVICISER2|=(1<<10);
   NVICICPR2|=(1<<10);
#endif
   usb_dcd_ptr->CONTROL |= USBDCD_CONTROL_IE_MASK;
   return result;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_int_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an USB DCD device.
*
*END*********************************************************************/

uint_32 _kusb_dcd_int_deinit
   (
      /* [IN] the initialization information for the device being opened */
      IO_USB_DCD_INT_DEVICE_STRUCT_PTR  int_io_dev_ptr,

      /* [IN] the address of the device specific information */
      KUSB_DCD_INFO_STRUCT_PTR   io_info_ptr
   )
{ /* Body */
   USBDCD_MemMapPtr                     usb_dcd_ptr;
   KUSB_DCD_INIT_STRUCT_PTR      usb_dcd_init_ptr;

   if ((NULL == io_info_ptr) || (NULL == int_io_dev_ptr))
   {
      return USB_DCD_ERROR_INVALID_PARAMETER;
   }

   usb_dcd_ptr = io_info_ptr->USB_DCD_PTR;

   /* Disable the USB DCD Interrupt */
   usb_dcd_ptr->CONTROL &= (uint_32)(~USBDCD_CONTROL_SR_MASK);
   /* Disable the USB DCD Module */
	usb_dcd_ptr->CONTROL |= USBDCD_CONTROL_SR_MASK;

   /* Install original vectors */
   usb_dcd_init_ptr = (KUSB_DCD_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
   _int_install_isr (_bsp_get_usb_dcd_vector(), io_info_ptr->OLD_ISR, io_info_ptr->OLD_ISR_DATA);

   /* Free buffers and info struct */
   _mem_free (int_io_dev_ptr->DEV_INFO_PTR);
   int_io_dev_ptr->DEV_INFO_PTR = NULL;

   return USB_DCD_OK;
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_int_read
* Returned Value   : MQX_OK
* Comments         :
*
*
*
*END*********************************************************************/

uint_32 _kusb_dcd_int_read
   (
      /* [IN] the address of the device specific information */
      IO_USB_DCD_INT_DEVICE_STRUCT_PTR   int_io_dev_ptr,

      /* [IN] The array to copy data into */
      uchar_ptr                      buffer,

      /* [IN] number of bytes to read */
      uint_32                        length
   )
{ /* Body */

   return MQX_OK;

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kusb_dcd_int_write
* Returned Value   : MQX_OK
* Comments         :
*
*
*
*END*********************************************************************/

uint_32 _kusb_dcd_int_write
   (
      /* [IN] the address of the device specific information */
      IO_USB_DCD_INT_DEVICE_STRUCT_PTR    int_io_dev_ptr,

      /* [IN] The array characters are to be read from */
      uchar_ptr                       buffer,

      /* [IN] number of bytes to output */
      uint_32                         length
   )
{ /* Body */

   return MQX_OK;

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    :_kusb_dcd_isr
* Returned Value   : none
*
*END*********************************************************************/
static void _kusb_dcd_isr
   (
      pointer                  parameter
   )
{ /* Body */
   KUSB_DCD_INFO_STRUCT_PTR     io_info_ptr = parameter;
   USBDCD_MemMapPtr             usb_dcd_ptr = io_info_ptr->USB_DCD_PTR;
   USB_MemMapPtr				usbotg = USB0_BASE_PTR;

   /* Clear interrupt flag */
   usb_dcd_ptr->CONTROL |= USBDCD_CONTROL_IACK_MASK;
   /* Update DCD state */
   io_info_ptr->STATE = USB_DCD_SEQ_COMPLETE;
   /* Enable pullup register for Non-OTG*/
	if (usb_dcd_ptr->STATUS & USBDCD_STATUS_SEQ_RES_MASK)
	{
		 usbotg->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
	}
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5xxx_fec_init.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5xxx_fec_init.c$
* $Version : 3.8.15.0$
* $Date    : Oct-7-2011$
*
* Comments:
*
*   This file contains the MCF5xxx Coldfire processor
*   Ethernet initialization
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "bsp_prv.h"
#include "mcf5xxx_fec_prv.h"
#include "mqx_inc.h"

extern _mem_pool_id _BSP_sram_pool;

const ENET_MAC_IF_STRUCT MCF5xxx_FEC_IF = {
    MCF5XXX_FEC_initialize,
    MCF5XXX_FEC_shutdown,
    MCF5XXX_FEC_send,
    MCF5XXX_FEC_read_mii,
    MCF5XXX_FEC_write_mii
    #if BSPCFG_ENABLE_ENET_MULTICAST
    ,
    MCF5XXX_FEC_join,
    MCF5XXX_FEC_rejoin
    #endif
};


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_initialize
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Initializes the chip (extended version).
*
*END*-----------------------------------------------------------------*/

#define IF_ERROR_EXIT(c,x) {if (c) { error = x; goto EXIT; }}

uint_32 MCF5XXX_FEC_initialize
   (
      ENET_CONTEXT_STRUCT_PTR enet_ptr
   )
{ 
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr=NULL;
   VMCF5XXX_FEC_STRUCT_PTR          fec_ptr;
   VMCF5XXX_FEC_BD_STRUCT_PTR       bd_ptr;
   uchar_ptr                        buf_ptr;
   MCF5XXX_FEC_RX_PCB_PTR           pcb_ptr;
   uint_32                          i, rxsize, txsize, ssize, lsize, pcbsize,rx_pcb_size, large_packet_size, rcr;
   uint_32                          timeout, error = ENET_OK;
   boolean                          bOK;
   KERNEL_DATA_STRUCT_PTR     kernel_data;
   
   _GET_KERNEL_DATA(kernel_data);
   
   
   fec_ptr = MCF5XXX_FEC_get_base_address(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER);
   if (fec_ptr == NULL) {
      return ENETERR_INVALID_DEVICE;
   }
   
   
   // currently limit number of TX BDs to 32, as a bitmask is used in the free function.
   if (enet_ptr->PARAM_PTR->NUM_TX_ENTRIES > 32) {
      return ENETERR_INVALID_INIT_PARAM;
   }
   
   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   FEC_int_disable();

   fec_context_ptr = _mem_alloc_system_zero(sizeof(MCF5XXX_FEC_CONTEXT_STRUCT));
   IF_ERROR_EXIT((NULL==fec_context_ptr), ENETERR_ALLOC_MAC_CONTEXT);
   _mem_set_type((pointer)fec_context_ptr, MEM_TYPE_IO_ENET_MAC_CONTEXT_STRUCT);
   
   enet_ptr->MAC_CONTEXT_PTR = (pointer) fec_context_ptr;  

   fec_context_ptr->FEC_ADDRESS = fec_ptr;
   fec_context_ptr->PHY_PTR = MCF5XXX_FEC_get_base_address(enet_ptr->PARAM_PTR->ENET_IF->PHY_NUMBER);

   /* Stop the chip */
   fec_ptr->ECR = MCF5XXX_FEC_ECR_RESET;

   /* wait until the initialization cycle completes */
   timeout = 0;
   while ((fec_ptr->ECR & MCF5XXX_FEC_ECR_RESET) && (timeout<MCF5XXX_FEC_RESET_TIMEOUT)){
      _time_delay(1);
      timeout++;
   } 
   IF_ERROR_EXIT((fec_ptr->ECR & MCF5XXX_FEC_ECR_RESET), ENETERR_INIT_FAILED);
   
   /* Disable all FEC interrupts */
   fec_ptr->EIMR = 0;

   /* clear any pending interrpts */
   fec_ptr->EIR = MCF5XXX_FEC_EIR_ALL_PENDING;

   fec_context_ptr->NumRxBDs = enet_ptr->PARAM_PTR->NUM_RX_ENTRIES;
   fec_context_ptr->NumTxBDs = enet_ptr->PARAM_PTR->NUM_TX_ENTRIES;
     
   // Compute aligned buffer sizes 
   if (enet_ptr->PARAM_PTR->TX_BUFFER_SIZE) {
      fec_context_ptr->AlignedTxBufferSize = MCF5XXX_FEC_TX_ALIGN(enet_ptr->PARAM_PTR->TX_BUFFER_SIZE);
   } else {
      fec_context_ptr->AlignedTxBufferSize = MCF5XXX_FEC_TX_ALIGN(enet_ptr->MaxTxFrameSize);
   }

   if (enet_ptr->PARAM_PTR->RX_BUFFER_SIZE) {
      fec_context_ptr->AlignedRxBufferSize = MCF5XXX_FEC_RX_ALIGN(enet_ptr->PARAM_PTR->RX_BUFFER_SIZE);
   } else {
      fec_context_ptr->AlignedRxBufferSize = MCF5XXX_FEC_RX_ALIGN(enet_ptr->MaxRxFrameSize);
   }

   // Allocate the Transmit and Receive buffer descriptors
   //bd_ptr = (VMCF5XXX_FEC_BD_STRUCT_PTR) _mem_alloc_system_zero((sizeof(MCF5XXX_FEC_BD_STRUCT)*(fec_context_ptr->NumRxBDs+fec_context_ptr->NumTxBDs))+MCF5XXX_FEC_BD_ALIGNMENT);

// TODO remake to using alloc_align fn
#if BSPCFG_HAS_SRAM_POOL && BSPCFG_ENET_SRAM_BUF
   bd_ptr = (VMCF5XXX_FEC_BD_STRUCT_PTR)_mem_alloc_system_zero_from(_BSP_sram_pool, (sizeof(MCF5XXX_FEC_BD_STRUCT) * (fec_context_ptr->NumRxBDs + fec_context_ptr->NumTxBDs)) + MCF5XXX_FEC_BD_ALIGNMENT);
#else
   bd_ptr = (VMCF5XXX_FEC_BD_STRUCT_PTR)_mem_alloc_system_zero_uncached((sizeof(MCF5XXX_FEC_BD_STRUCT) * (fec_context_ptr->NumRxBDs + fec_context_ptr->NumTxBDs)) + MCF5XXX_FEC_BD_ALIGNMENT);
#endif

   IF_ERROR_EXIT((NULL == bd_ptr), ENETERR_ALLOC_BD);
   _mem_set_type((pointer)bd_ptr, MEM_TYPE_IO_BD_STRUCT);

   fec_context_ptr->UNALIGNED_RING_PTR = (pointer) bd_ptr;
   fec_context_ptr->FEC_RX_RING_PTR = (VMCF5XXX_FEC_BD_STRUCT_PTR) MCF5XXX_FEC_BD_ALIGN((uint_32)bd_ptr);
   fec_context_ptr->FEC_TX_RING_PTR = &fec_context_ptr->FEC_RX_RING_PTR[fec_context_ptr->NumRxBDs];

   /* Set wrap bit in last BD */
   fec_context_ptr->FEC_RX_RING_PTR[fec_context_ptr->NumRxBDs - 1].CONTROL = MCF5XXX_FEC_BD_ETHER_RX_WRAP;
   fec_context_ptr->FEC_TX_RING_PTR[fec_context_ptr->NumTxBDs - 1].CONTROL = MCF5XXX_FEC_BD_ETHER_TX_WRAP;

   fec_context_ptr->AvailableTxBDs = fec_context_ptr->NumTxBDs;

   // Allocate array to hold Transmit PCB pointers while they are queued for transmission
   fec_context_ptr->TxPCBS_PTR = (PCB_PTR *) _mem_alloc_system_zero(sizeof(PCB_PTR)*fec_context_ptr->NumTxBDs);
   IF_ERROR_EXIT((NULL==fec_context_ptr->TxPCBS_PTR), ENETERR_ALLOC_PCB);
   _mem_set_type((pointer)fec_context_ptr->TxPCBS_PTR, MEM_TYPE_IO_PCB_PTR);

   // Allocate the Receive PCBs
   rx_pcb_size = sizeof(MCF5XXX_FEC_RX_PCB);
   pcbsize = enet_ptr->PARAM_PTR->NUM_RX_PCBS * rx_pcb_size;
   fec_context_ptr->RX_PCB_BASE = (MCF5XXX_FEC_RX_PCB_PTR) _mem_alloc_system_zero(pcbsize);
   IF_ERROR_EXIT((NULL==fec_context_ptr->RX_PCB_BASE), ENETERR_ALLOC_PCB);
   _mem_set_type((pointer)fec_context_ptr->RX_PCB_BASE, MEM_TYPE_IO_PCB_STRUCT);
       
   // Allocate the Transmit and Receive buffers
   txsize = (enet_ptr->PARAM_PTR->NUM_TX_BUFFERS * fec_context_ptr->AlignedTxBufferSize) + MCF5XXX_FEC_TX_BUFFER_ALIGNMENT;
   rxsize = (enet_ptr->PARAM_PTR->NUM_RX_BUFFERS  * fec_context_ptr->AlignedRxBufferSize) +MCF5XXX_FEC_RX_BUFFER_ALIGNMENT;
   ssize  = (enet_ptr->PARAM_PTR->NUM_SMALL_BUFFERS * MCF5XXX_SMALL_PACKET_SIZE);
   large_packet_size = enet_ptr->PARAM_PTR->OPTIONS&ENET_OPTION_VLAN ? ENET_FRAMESIZE_VLAN : ENET_FRAMESIZE;
   lsize  = (enet_ptr->PARAM_PTR->NUM_LARGE_BUFFERS * large_packet_size);

#if BSPCFG_HAS_SRAM_POOL && BSPCFG_ENET_SRAM_BUF
   buf_ptr = _mem_alloc_system_from(_BSP_sram_pool, rxsize + txsize + ssize + lsize);
#else
   buf_ptr = _mem_alloc_system_uncached(rxsize + txsize + ssize + lsize);  // temporary fix for cache problems... was befor _mem_alloc_system
#endif
   
   IF_ERROR_EXIT((NULL==buf_ptr), ENETERR_ALLOC_BUFFERS);
   _mem_set_type(buf_ptr, MEM_TYPE_IO_ENET_BUFFERS);

   fec_context_ptr->UNALIGNED_BUFFERS = buf_ptr;

   // Align to TX buffer boundary
   buf_ptr = (uchar_ptr)MCF5XXX_FEC_TX_ALIGN((uint_32)buf_ptr);
   
   // Queue packets on TX Buffer Q.
   fec_context_ptr->TX_BUFFERS = NULL;
   for (i=0;i<enet_ptr->PARAM_PTR->NUM_TX_BUFFERS;i++) {
      ENET_Enqueue_Buffer((pointer *)&fec_context_ptr->TX_BUFFERS, buf_ptr);
      buf_ptr += fec_context_ptr->AlignedTxBufferSize;
   }
   
   // Align to RX buffer boundary
   buf_ptr = (uchar_ptr)MCF5XXX_FEC_RX_ALIGN((uint_32)buf_ptr);
  
   // Queue packets on RX Buffer Q.
   fec_context_ptr->RX_BUFFERS = NULL;
   for (i=0;i<enet_ptr->PARAM_PTR->NUM_RX_BUFFERS;i++) {
      ENET_Enqueue_Buffer((pointer *)&fec_context_ptr->RX_BUFFERS, buf_ptr);
      buf_ptr += fec_context_ptr->AlignedRxBufferSize;
   }

   // Queue small packets on small buffer Q.
   for (i=0;i<enet_ptr->PARAM_PTR->NUM_SMALL_BUFFERS;i++) {
      ENET_Enqueue_Buffer((pointer *)&fec_context_ptr->SMALL_BUFFERS, buf_ptr);
      buf_ptr += MCF5XXX_SMALL_PACKET_SIZE;
   }

   // Queue large packets on large buffer Q.
   for (i=0;i<enet_ptr->PARAM_PTR->NUM_LARGE_BUFFERS;i++) {
      ENET_Enqueue_Buffer((pointer *)&fec_context_ptr->LARGE_BUFFERS, buf_ptr);
      buf_ptr += large_packet_size;
   }

   // Enqueue the RX PCBs onto the receive PCB queue 
   pcb_ptr = fec_context_ptr->RX_PCB_BASE;
   for (i = 0; i < enet_ptr->PARAM_PTR->NUM_RX_PCBS; i++) {
      QADD(fec_context_ptr->RxPCBHead, fec_context_ptr->RxPCBTail, (PCB_PTR) pcb_ptr);
      pcb_ptr++;
   } 

   // Fill up the receive ring 
   MCF5XXX_FEC_add_buffers_to_rx_ring(fec_context_ptr);

   // Initialize the FEC I/O Pins
   MCF5XXX_FEC_io_init(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER); 

   /* Program this station's Ethernet physical address */
   fec_ptr->PALR = *(uint_32_ptr) &enet_ptr->ADDRESS[0];
   fec_ptr->PAUR = (*(uint_16_ptr)(&enet_ptr->ADDRESS[4])) << 16;

   // Clear the individual hash table registers
   fec_ptr->IAUR = 0;
   fec_ptr->IALR = 0;

   // Clear the group hash table registers                                
   fec_ptr->GAUR = 0;
   fec_ptr->GALR = 0;  

   /* Program receive buffer size */
   fec_ptr->EMRBR = fec_context_ptr->AlignedRxBufferSize;     

   // Configure start of Rx and Tx BD rings
   fec_ptr->ERDSR = (uint_32)(fec_context_ptr->FEC_RX_RING_PTR);
   fec_ptr->ETDSR = (uint_32)(fec_context_ptr->FEC_TX_RING_PTR);

   // Set Receive Frame size 
   // NOTE: Oddly, the Receive Control Register (RCR) affects the transmit side too.  The RCR is used to determine if the 
   //       transmitter is babbling, which means, if the RX buffer size < Tx Buffer size, we can get babling transmitter
   //       errors if we set RCR to the maximum Receive frame length.  We really have no choice but to set RCR to one
   //       of ENET_FRAMESIZE or ENET_FRAMESIZE_VLAN.
   //

   rcr = MCF5XXX_FEC_RCR_MII_MODE | MCF5XXX_FEC_RCR_FRAME_LENGTH(large_packet_size);
   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_RMII) {
      rcr |= MCF5XXX_FEC_RCR_RMII_MODE;
   } else if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_7WIRE) {
      rcr &= ~MCF5XXX_FEC_RCR_MII_MODE;
   }
   fec_ptr->RCR =  rcr;
   

   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_MAC_LOOPBACK) {
      fec_ptr->RCR |= MCF5XXX_FEC_RCR_LOOP;
   }

   //  Set Full/Half duplex based on mode.
   if (enet_ptr->PARAM_PTR->MODE & ENET_HALF_DUPLEX) {
      fec_ptr->TCR = 0; // half duplex
   } else {
      fec_ptr->TCR = 4; // full duplex
   }
   
   // Enable MII_SPEED register 
   i = (MCF5XXX_FEC_device[enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER].BUS_CLOCK / enet_ptr->PARAM_PTR->ENET_IF->PHY_MII_SPEED + 1) & ~1;
   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_NO_PREAMBLE) {
      i |= MCF5XXX_FEC_MII_MSCR_PREAMBLE;
   }
   fec_context_ptr->PHY_PTR->MSCR = i;

   // Zero counters
   fec_ptr->MIBC = 0x80000000;
   _mem_zero((pointer)fec_ptr->MIB_RAM, sizeof(fec_ptr->MIB_RAM));
   fec_ptr->MIBC = 0;

   // Install the ISRs
   bOK = MCF5XXX_FEC_install_isrs( enet_ptr, &MCF5XXX_FEC_device[enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER] );
   IF_ERROR_EXIT(!bOK, ENETERR_INSTALL_ISR);
          
   // Unmask transmit/receive interrupts 
   // NOTE: need to enable both RXF and RXB, but only TXB, as RXB does not get generated with RXF, 
   //       but TXB does get generated with TXF
   // However, on 52259, enabling RXB is resulting in an HBERR interrupt. RXB is not required, so leave it disabled.
   fec_ptr->EIMR = MCF5XXX_FEC_EIR_TXB | MCF5XXX_FEC_EIR_RXF; 

   // Enable FEC 
   fec_ptr->ECR = MCF5XXX_FEC_ECR_ETHER_EN;

   // Discover PHY address if PHY_DISCOVER option is set
   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PHY_DISCOVER) {
      bOK = (*enet_ptr->PARAM_PTR->ENET_IF->PHY_IF->DISCOVER)(enet_ptr);
      IF_ERROR_EXIT(!bOK, ENETERR_INIT_FAILED);
   } else {
      // Set Phy address from initialization parameter
      enet_ptr->PHY_ADDRESS = enet_ptr->PARAM_PTR->ENET_IF->PHY_ADDRESS;
   }
   
   // Perform Phy initialization
   bOK = (*enet_ptr->PARAM_PTR->ENET_IF->PHY_IF->INIT)(enet_ptr);
   IF_ERROR_EXIT(!bOK, ENETERR_INIT_FAILED);


   // Signals the FEC that empty buffers are available.
   // It is NECESSARY to do this AFTER enabling the FEC.
   fec_ptr->RDAR = MCF5XXX_FEC_RDAR_ACTIVE;

   // control transfers to this point on any error, with error set to error code.
EXIT:
   if (ENET_OK!=error) {
      #if BSPCFG_ENET_RESTORE
         MCF5XXX_FEC_uninstall_all_isrs(enet_ptr);
      #endif
      MCF5XXX_FEC_free_context(fec_context_ptr);
   }
   FEC_int_enable();
   return error;
} 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/sosel1.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sosel1.c$
* $Version : 3.5.7.0$
* $Date    : Jan-27-2010$
*
* Comments:
*
*   This file contains the RTCS select() support functions.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "socket.h"
#include "tcpip.h"
/* Start CR 1707 */
#include "tcp_prv.h"    /* for TCP internal definitions */
#include "udp_prv.h"    /* for UDP internal definitions */
/* End CR 1707 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_select_unblock
* Returned Values :
* Comments  :
*     Dequeues a select() call from the select queue.
*
*END*-----------------------------------------------------------------*/

void SOCK_select_unblock
   (
      SOCKSELECT_PARM_PTR  parms,
      uint_16  state      // TCP state or UDP socket flag
   )
{ /* Body */

   if (parms->NEXT) {
      parms->NEXT->PREV = parms->PREV;
   } /* Endif */
   *parms->PREV = parms->NEXT;

   if (parms->timeout) {
      TCPIP_Event_cancel(&parms->EXPIRE);
   } /* Endif */

/* Start CR 1707 */
   //RTCSCMD_complete(parms, RTCS_OK);
   /* Check TCP state and UDP socket flag */
   if ( (state == CLOSED) || (state == UDP_SOCKET_CLOSE) ) {
      RTCSCMD_complete(parms, RTCSERR_SOCK_CLOSED);
   } else {
      RTCSCMD_complete(parms, RTCS_OK);
   } /* Endif */
   
/* End CR 1707 */   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_select_signal
* Returned Values :
* Comments  :
*     Unblocks all select() calls blocked on a specific socket.
*
*END*-----------------------------------------------------------------*/

void _SOCK_select_signal
   (
      uint_32  sock,
      uint_16  state,      // TCP state or UDP socket flag
      uint_32  flag        // direction flag - 0 recv, non zero send
   )
{ /* Body */
   SOCKET_CONFIG_STRUCT_PTR   socket_cfg_ptr = RTCS_getcfg(SOCKET);
   SOCKSELECT_PARM_PTR        parms, nextparms;
   uint_32                    i;

   if (!sock) {
      return;
   } /* Endif */

   for (parms=socket_cfg_ptr->SELECT_HEAD; parms; parms=nextparms) {

      nextparms = parms->NEXT;
      if (parms->owner) {
         if (SOCK_Is_owner((SOCKET_STRUCT_PTR)sock, parms->owner)) {
            parms->sock = sock;
            SOCK_select_unblock(parms, state);
         } /* Endif */
      } else {
         /* check if sock is on the select waiting list (array) */
         if (!flag) {         
            for (i=0; i<parms->sock_count; i++)
               if (parms->sock_ptr[i] == sock)
                  break;
            if(i>=parms->sock_count)
               continue;
         }
         else {
            for (i=0; i<parms->writesock_count; i++)
               if (parms->writesock_ptr[i] == sock)
                  break;
            if(i>=parms->writesock_count)               
               continue;
         }
         
         /* now, it is sure the select will be awaken. 
            Just zero out the others in both arrays */
         parms->sock = sock;

         _mem_zero(parms->writesock_ptr, sizeof(parms->writesock_ptr[0]) * parms->writesock_count);
         _mem_zero(parms->sock_ptr, sizeof(parms->sock_ptr[0]) * parms->sock_count);
         
         if (!flag) {         
            parms->sock_ptr[0] = sock; 
         }
         else {
            parms->writesock_ptr[0] = sock; 
         }
         
         SOCK_select_unblock(parms, state);
      } /* Endif */

   } /* Endfor */

   /*
   ** Finally, call the application callback, if one exists.
   */
   if (((SOCKET_STRUCT_PTR)sock)->APPLICATION_CALLBACK) {
      ((SOCKET_STRUCT_PTR)sock)->APPLICATION_CALLBACK(sock);
   } /* Endif */

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/sem.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sem.h$
* $Version : 3.0.5.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   semaphore component.
*
*END************************************************************************/
#ifndef __sem_h__
#define __sem_h__ 1

#include <mqx_cnfg.h>
#if (! MQX_USE_SEMAPHORES) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error SEMAPHORE component is currently disabled in MQX kernel. Please set MQX_USE_SEMAPHORES to 1 in user_config.h and recompile kernel.
#endif

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* ERROR messages */

#define SEM_MULTI_PROCESSOR_NOT_AVAILABLE   (SEM_ERROR_BASE|0x00)
#define SEM_SEMAPHORE_DELETED               (SEM_ERROR_BASE|0x01)
#define SEM_SEMAPHORE_NOT_DELETED           (SEM_ERROR_BASE|0x02)
#define SEM_INVALID_SEMAPHORE_HANDLE        (SEM_ERROR_BASE|0x03)
#define SEM_CANNOT_POST                     (SEM_ERROR_BASE|0x04)
#define SEM_CANNOT_GET_SEMAPHORE            (SEM_ERROR_BASE|0x05)
#define SEM_INVALID_SEMAPHORE_COUNT         (SEM_ERROR_BASE|0x06)
#define SEM_WAIT_TIMEOUT                    (SEM_ERROR_BASE|0x07)
#define SEM_SEMAPHORE_EXISTS                (SEM_ERROR_BASE|0x08)
#define SEM_SEMAPHORE_TABLE_FULL            (SEM_ERROR_BASE|0x09)
#define SEM_SEMAPHORE_NOT_FOUND             (SEM_ERROR_BASE|0x0A)
#define SEM_INVALID_POLICY                  (SEM_ERROR_BASE|0x0B)
#define SEM_INVALID_SEMAPHORE               (SEM_ERROR_BASE|0x0C)
#define SEM_INCORRECT_INITIAL_COUNT         (SEM_ERROR_BASE|0x0D)

/* bit flag parameters for _sem_create */

#define SEM_PRIORITY_QUEUEING               (1)
#define SEM_PRIORITY_INHERITANCE            (2)
#define SEM_STRICT                          (4)

/* Default component creation parameters */
#define SEM_DEFAULT_INITIAL_NUMBER          (8)
#define SEM_DEFAULT_GROW_NUMBER             (8)
#define SEM_DEFAULT_MAXIMUM_NUMBER          (0) /* Unlimited */

/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _sem_close(pointer);
extern _mqx_uint _sem_create(char _PTR_, _mqx_uint, _mqx_uint);
extern _mqx_uint _sem_create_fast(_mqx_uint, _mqx_uint, _mqx_uint);
extern _mqx_uint _sem_create_component(_mqx_uint, _mqx_uint, _mqx_uint);
extern _mqx_uint _sem_destroy(char _PTR_, boolean);
extern _mqx_uint _sem_destroy_fast(_mqx_uint, boolean);
extern _mqx_uint _sem_get_wait_count(pointer);
extern _mqx_uint _sem_open(char _PTR_, pointer _PTR_);
extern _mqx_uint _sem_open_fast(_mqx_uint, pointer _PTR_);
extern _mqx_uint _sem_post(pointer);
extern _mqx_uint _sem_test(pointer _PTR_);
extern _mqx_uint _sem_get_value(pointer);
extern _mqx_uint _sem_wait(pointer, uint_32);
extern _mqx_uint _sem_wait_for(pointer, MQX_TICK_STRUCT_PTR);
extern _mqx_uint _sem_wait_ticks(pointer, _mqx_uint);
extern _mqx_uint _sem_wait_until(pointer, MQX_TICK_STRUCT_PTR);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_AtanYX.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_AtanYX.h
*
* @author   B04459
* 
* @version  1.0.1.0
* 
* @date     Dec-6-2012
* 
* @brief    Header file for #GFLIB_AtanYX function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef GFLIB_ATANYX_H_
#define GFLIB_ATANYX_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif
/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*!
  \def GFLIB_AtanYX
  Function alias for the #GFLIB_AtanYXANSIC function.
*/
#define GFLIB_AtanYX(y,x) GFLIB_AtanYXANSIC((y), (x))

/*!
  \def GFLIB_AtanXY
  Function alias for the #GFLIB_AtanYXANSIC function.
*/
#define GFLIB_AtanXY(x, y) GFLIB_AtanYXANSIC((y), (x))

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/

/******************************************************************************
* Exported Variables
******************************************************************************/

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*! 
* @ingroup GFLIB_GROUP 
*/ 
extern Word32 GFLIB_AtanYXANSIC(Word32 w32InY, Word32 w32InX);

/******************************************************************************
* Inline functions
******************************************************************************/ 

#endif /*GFLIB_ATANYX_H_*/


<|start_filename|>Firmware/Inverter_firmware/shell/source/shell/shell.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: shell.c$
* $Version : 3.8.16.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include <fio.h>
#include "shell.h"
#include "sh_prv.h"

   
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell
*  Returned Value:  none
*  Comments  :  The RTCS shell
*
*END*-----------------------------------------------------------------*/

int_32 Shell
   (
      const SHELL_COMMAND_STRUCT   shell_commands[],
      char_ptr            start_file 
   )
{ /* Body */
   SHELL_CONTEXT_PTR    shell_ptr;
   // int_32               return_code;
   uint_32              i;

   printf("\nShell (build: %s)\n", __DATE__);
   printf("Copyright (c) 2013 Freescale Semiconductor;\n");
   
   
   shell_ptr = _mem_alloc_zero( sizeof( SHELL_CONTEXT ));
   if (shell_ptr == NULL)  {
      return SHELL_EXIT_ERROR;
   }
   _mem_set_type(shell_ptr, MEM_TYPE_SHELL_CONTEXT);
   
   shell_ptr->COMMAND_LIST_PTR=(SHELL_COMMAND_PTR)shell_commands; 

   if (start_file != NULL)  {
      if (start_file[0] == '\'') {
         strncpy(  shell_ptr->CMD_LINE, &start_file[1],sizeof(shell_ptr->CMD_LINE  ));    
      } else {
         shell_ptr->COMMAND_FP = fopen(start_file, "r");
      }
   }
   
   if (!shell_ptr->COMMAND_FP)  {
      shell_ptr->COMMAND_FP = stdin;
   }

#if SHELLCFG_USES_MFS
   // initialize current fs ptr, fs name and path
   Shell_set_current_filesystem((pointer)shell_ptr,NULL);
#endif //SHELLCFG_USES_MFS
   
   if (shell_ptr->CMD_LINE){
      printf("shell> %s\n",shell_ptr->CMD_LINE);
   } else {
      printf("shell> ");
   }
   fflush(stdout);
   
   while (!shell_ptr->EXIT) {
      
      if ((!shell_ptr->EXIT) && (shell_ptr->CMD_LINE[0] != '\0'))  {
         
         if (shell_ptr->COMMAND_FP != stdin)  {
            printf("%s\n", shell_ptr->CMD_LINE);
         }
      
         if (shell_ptr->CMD_LINE[0] != '#') {

            if (strcmp(shell_ptr->CMD_LINE, "!") == 0)  {
               strncpy(shell_ptr->CMD_LINE,shell_ptr->HISTORY,sizeof(shell_ptr->CMD_LINE));
            } else if (strcmp(shell_ptr->CMD_LINE, "\340H") == 0)  {
               strncpy(shell_ptr->CMD_LINE,shell_ptr->HISTORY,sizeof(shell_ptr->CMD_LINE));
            } else  {
               strncpy(shell_ptr->HISTORY,shell_ptr->CMD_LINE,sizeof(shell_ptr->HISTORY));
            }

            shell_ptr->ARGC = Shell_parse_command_line(shell_ptr->CMD_LINE, shell_ptr->ARGV );
         
            if (shell_ptr->ARGC > 0) { 
            
               _io_strtolower(shell_ptr->ARGV[0]); 
               for (i=0;shell_commands[i].COMMAND != NULL;i++)  {
                  if (strcmp(shell_ptr->ARGV[0], shell_commands[i].COMMAND) == 0)  {
                     /* return_code = */ (*shell_commands[i].SHELL_FUNC)(shell_ptr->ARGC, shell_ptr->ARGV);
                     break;   
                  }
               } 
            
               if (shell_commands[i].COMMAND == NULL)  {
                 printf("Invalid command.  Type 'help' for a list of commands.\n");
               } 
            }
         }
      }

      if (!shell_ptr->EXIT) { 
         printf("shell> ");
         fflush(stdout);

         do {
            if (!fgets(shell_ptr->CMD_LINE, sizeof(shell_ptr->CMD_LINE  ), shell_ptr->COMMAND_FP)) {
               if (shell_ptr->COMMAND_FP != stdin)  {
                  fclose(shell_ptr->COMMAND_FP);
                  shell_ptr->COMMAND_FP = stdin;
                  shell_ptr->HISTORY[0]=0;
                  shell_ptr->CMD_LINE[0]=0;
                  printf("\n");
               } else  {
                  shell_ptr->EXIT=TRUE;
                  break;
               }
            }
         } while ((shell_ptr->CMD_LINE[0] == '\0') && (shell_ptr->COMMAND_FP != stdin)) ; 
      }
   } 

   printf("Terminating shell.\n");
   _mem_free(shell_ptr);
   return SHELL_EXIT_SUCCESS;
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GDFLIB/GDFLIB_FilterIIR1.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GDFLIB_FilterIIR1.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GDFLIB_FilterIIR1 function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GDFLIB_FILTER_IIR1_H
#define _GDFLIB_FILTER_IIR1_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif
     
/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GDFLIB_FilterIIR1InitANSIC function.*/
#define GDFLIB_FilterIIR1Init(pParam) \
    GDFLIB_FilterIIR1InitANSIC(pParam)

/*! Function alias for the #GDFLIB_FilterIIR1ANSIC function.*/
#define GDFLIB_FilterIIR1(f32In,pParam)\
        GDFLIB_FilterIIR1ANSIC(f32In,pParam)

/*! Macro containing default values of the first order IIR filter structure.*/
#define GDFLIB_FILTER_IIR1_DEFAULT   {{0,0,0},{0},{0}}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct FILTER_IIR1_COEFF_T "\GDFLIB_FilterIIR1.h"

@brief  Sub-structure containing filter coefficients.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32 f32B0;  /*!< b0 coefficient of an IIR1 filter, 32-bit */
    Frac32 f32B1;  /*!< b1 coefficient of an IIR1 filter, 32-bit */
    Frac32 f32A1;  /*!< a1 coefficient of an IIR1 filter, 32-bit */
}FILTER_IIR1_COEFF_T;

/*------------------------------------------------------------------------*//*!
@struct GDFLIB_FILTER_IIR1_T "\GDFLIB_FilterIIR1.h"

@brief  Structure containing filter buffer and coefficients.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    FILTER_IIR1_COEFF_T trFiltCoeff; /*!< filter coefficients substructure */
    Frac32 f32FiltBufferX[2];  /*!< input buffer of an IIR1 filter */
    Frac32 f32FiltBufferY[2];  /*!< internal accumulator buffer */
}GDFLIB_FILTER_IIR1_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
// Prototype of function for clearing buffers of IIR1 filter.
extern void GDFLIB_FilterIIR1InitANSIC(GDFLIB_FILTER_IIR1_T *pParam);

// Prototype of direct form II first order IIR filter.
extern Frac32 GDFLIB_FilterIIR1ANSIC(Frac32 f32InErr, \
                                      GDFLIB_FILTER_IIR1_T *pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GDFLIB_FILTER_IIR1_H */



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/media/ipcpfsm.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcpfsm.c$
* $Version : 3.8.7.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the IPCP
*   automaton.
*
*END************************************************************************/

/*
** ipcp.c - PPP IP Control Protocol.
**
** Copyright (c) 1989 Carnegie Mellon University.
** All rights reserved.
**
** Redistribution and use in source and binary forms are permitted
** provided that the above copyright notice and this paragraph are
** duplicated in all such forms and that any documentation,
** advertising materials, and other materials related to such
** distribution and use acknowledge that the software was developed
** by Carnegie Mellon University.  The name of the
** University may not be used to endorse or promote products derived
** from this software without specific prior written permission.
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
** WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

#include <rtcs.h>

#if RTCSCFG_ENABLE_IP4 

#include <fio.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "dns.h"

#include <ppp.h>
#include "pppfsm.h"
#include "ipcp.h"


static boolean IPCP_up(PPPFSM_CFG_PTR);
static void    IPCP_down(PPPFSM_CFG_PTR);

static void    IPCP_resetconfreq(PPPFSM_CFG_PTR);
static uint_32 IPCP_buildconfreq(PPPFSM_CFG_PTR, uchar_ptr, uint_32);

static uint_32 IPCP_recvconfreq(PPPFSM_CFG_PTR, boolean);
static boolean IPCP_recvconfack(PPPFSM_CFG_PTR);
static boolean IPCP_recvconfnak(PPPFSM_CFG_PTR);
static boolean IPCP_recvconfrej(PPPFSM_CFG_PTR);
static boolean IPCP_recvcoderej(PPPFSM_CFG_PTR);

PPPFSM_CALL IPCP_FSM_CALL = {
   /* PROTOCOL    */    PPP_PROT_IPCP,
   /* linkup()    */    IPCP_up,
   /* linkdown()  */    IPCP_down,
   /* resetreq()  */    IPCP_resetconfreq,
   /* buildreq()  */    IPCP_buildconfreq,
   /* recvreq()   */    IPCP_recvconfreq,
   /* recvack()   */    IPCP_recvconfack,
   /* recvnak()   */    IPCP_recvconfnak,
   /* recvrej()   */    IPCP_recvconfrej,
   /* testcode()  */    IPCP_recvcoderej,
   /* recvcode()  */    NULL
};

static IPCP_NEG IPCP_DEFAULT_NEG = {
   /* NEG_* */    0,0,1,0,
   /* ADDR  */    INADDR_ANY,
   /* DNS   */    INADDR_ANY,
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_up
* Returned Value  :  TRUE if negotiated options are acceptable
* Comments        :
*     Called by the FSM when entering the OPENED state.
*
*END*-----------------------------------------------------------------*/

static boolean IPCP_up
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   IP_IF_PTR            if_ptr = fsm->PRIVATE;
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;

   /* Bind the negotiated IP address to this interface */
   ipcp_ptr->BIND_PARMS.ihandle = if_ptr;
   ipcp_ptr->BIND_PARMS.address = ipcp_ptr->LOPT.ADDR;
   ipcp_ptr->BIND_PARMS.network = ipcp_ptr->POPT.ADDR;
   
   RTCSCMD_smartissue(ipcp_ptr->BIND_PARMS, IPIF_bind_ppp);

   /* Install a default gateway */
   if (ipcp_ptr->INIT.DEFAULT_ROUTE) {
      ipcp_ptr->GATE_PARMS.address = ipcp_ptr->POPT.ADDR;
      ipcp_ptr->GATE_PARMS.network = INADDR_ANY;
      ipcp_ptr->GATE_PARMS.netmask = INADDR_ANY;
      /* Start CR 1133 */
      ipcp_ptr->GATE_PARMS.locmask = 0;
      /* End CR 1133 */
      RTCSCMD_smartissue(ipcp_ptr->GATE_PARMS, IPIF_gate_add);
   } /* Endif */

#if RTCSCFG_ENABLE_DNS
   /* Set up the primary DNS server */
   if (ipcp_ptr->NEG.NEG_DNS) {
      /* Start CR 2257 */
      DNS_SLIST_STRUCT slist_entry;
      DNS_init_slist_entry(&slist_entry);
      slist_entry.IPADDR = ipcp_ptr->LOPT.DNS;
      if (DNS_add_slist_entry(&slist_entry) != DNS_OK)
         return FALSE;
      /* End CR 2257 */
   } /* Endif */
#endif

   if (ipcp_ptr->IP_UP) {
      ipcp_ptr->IP_UP(ipcp_ptr->IP_PARAM);
   } /* Endif */

   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_down
* Returned Value  :  void
* Comments        :
*     Called by the FSM when leaving the OPENED state.
*
*END*-----------------------------------------------------------------*/

static void IPCP_down
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   IP_IF_PTR            if_ptr = fsm->PRIVATE;
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;

   /* Remove the default gateway */
   if (ipcp_ptr->INIT.DEFAULT_ROUTE) {
      RTCSCMD_smartissue(ipcp_ptr->GATE_PARMS, IPIF_gate_remove);
   } /* Endif */

   /* Unbind the interface */
   RTCSCMD_smartissue(ipcp_ptr->BIND_PARMS, IPIF_unbind_ppp);

   if (ipcp_ptr->IP_DOWN) {
      ipcp_ptr->IP_DOWN(ipcp_ptr->IP_PARAM);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_resetconfreq
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_Sendconfreq when starting negotiation.
*     Initializes the Send Options.
*
*END*-----------------------------------------------------------------*/

static void IPCP_resetconfreq
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   IPCP_CFG_STRUCT_PTR ipcp_ptr = ((IP_IF_PTR)fsm->PRIVATE)->HANDLE;

   ipcp_ptr->NEG = IPCP_DEFAULT_NEG;
   ipcp_ptr->NEG.NEG_DNS = ipcp_ptr->INIT.NEG_LOCAL_DNS;
   ipcp_ptr->NEG.ADDR = ipcp_ptr->INIT.LOCAL_ADDR;
   ipcp_ptr->NEG.DNS  = ipcp_ptr->INIT.LOCAL_DNS;

   ipcp_ptr->LOPT.ADDR = ipcp_ptr->INIT.LOCAL_ADDR;
   ipcp_ptr->LOPT.DNS  = ipcp_ptr->INIT.LOCAL_DNS;
   ipcp_ptr->POPT.ADDR = ipcp_ptr->INIT.REMOTE_ADDR;
   ipcp_ptr->POPT.DNS  = ipcp_ptr->INIT.REMOTE_DNS;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_buildconfreq
* Returned Value  :  number of bytes written
* Comments        :
*     Called by PPPFSM_Sendconfreq.  Builds a ConfReq packet.
*
*END*-----------------------------------------------------------------*/

static uint_32 IPCP_buildconfreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN] - State Machine */
      uchar_ptr         outp,
            /* [IN] - free packet */
      uint_32           sizeleft
            /* [IN] - size of packet */
   )
{ /* Body */
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = ((IP_IF_PTR)fsm->PRIVATE)->HANDLE;
   uint_32              totlen = 0;

#define IPCP_BREQ(ci,len) \
         *outp++ = IPCP_CI_ ## ci; \
         *outp++ = len;            \
         totlen += len

   if (ipcp_ptr->NEG.NEG_ADDR) {
      if (sizeleft >= totlen+6) {
         IPCP_BREQ(ADDR,6);
         htonl(outp, ipcp_ptr->NEG.ADDR); outp += 4;
      } /* Endif */
   } /* Endif */

   if (ipcp_ptr->NEG.NEG_DNS) {
      if (sizeleft >= totlen+6) {
         IPCP_BREQ(DNS,6);
         htonl(outp, ipcp_ptr->NEG.DNS); outp += 4;
      } /* Endif */
   } /* Endif */

   return totlen;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_recvconfack
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_Recvconfack.  Parses a ConfAck packet.
*     This function should not modify any state if the ack is bad.
*
*END*-----------------------------------------------------------------*/

static boolean IPCP_recvconfack
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = ((IP_IF_PTR)fsm->PRIVATE)->HANDLE;
   uchar_ptr            inp = fsm->DATA;
   uint_32              sizeleft = fsm->LENGTH;
   IPCP_OPT             ack_opt = ipcp_ptr->LOPT;

#define IPCP_RACK(ci,len) \
      if (sizeleft < len) goto badack;           \
      if (*inp++ != IPCP_CI_ ## ci) goto badack; \
      if (*inp++ != len)            goto badack; \
      sizeleft -= len

   /*
   ** The ack must be identical to the last ConfReq we sent
   */

   if (ipcp_ptr->NEG.NEG_ADDR) {
      IPCP_RACK(ADDR,6);
      ack_opt.ADDR = ntohl(inp); inp += 4;
      if (ack_opt.ADDR != ipcp_ptr->NEG.ADDR) goto badack;
   } /* Endif */

   if (ipcp_ptr->NEG.NEG_DNS) {
      IPCP_RACK(DNS,6);
      ack_opt.DNS = ntohl(inp); inp += 4;
      if (ack_opt.DNS != ipcp_ptr->NEG.DNS) goto badack;
   } /* Endif */

   if (sizeleft) goto badack;

   if (fsm->STATE < PPP_STATE_OPENED) {
      ipcp_ptr->LOPT = ack_opt;
   } /* Endif */
   return TRUE;

badack:
   return FALSE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_recvconfnak
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_Recvconfnak.  Parses a ConfNak packet.
*     This function should not modify any state if the nak is bad.
*
*END*-----------------------------------------------------------------*/

static boolean IPCP_recvconfnak
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = ((IP_IF_PTR)fsm->PRIVATE)->HANDLE;
   uchar_ptr            inp = fsm->DATA;
   uint_32              sizeleft = fsm->LENGTH;
   IPCP_NEG             req_neg = ipcp_ptr->NEG;
   uchar                code;

#define IPCP_RNAK(len) \
      if (sizeleft < len) goto badnak; \
      if (*inp++ != len)  goto badnak; \
      sizeleft -= len

   /*
   ** Nak'd codes must be in the same order as they were in the ConfReq
   */

   code = *inp++;

   if (sizeleft && req_neg.NEG_ADDR && code == IPCP_CI_ADDR) {
      IPCP_RNAK(6);

      /* Accept any address they want if we don't know who we are */
      if (ipcp_ptr->INIT.ACCEPT_LOCAL_ADDR) {
         req_neg.ADDR = ntohl(inp);
      } /* Endif */
      inp += 4;

      code = *inp++;
   } /* Endif */

   if (sizeleft && req_neg.NEG_DNS && code == IPCP_CI_DNS) {
      IPCP_RNAK(6);

      /* Accept any address they want if we don't know who we are */
      if (ipcp_ptr->INIT.ACCEPT_LOCAL_DNS) {
         req_neg.DNS = ntohl(inp);
      } /* Endif */
      inp += 4;

      code = *inp++;
   } /* Endif */

   /*
   ** There may be remaining codes if the peer wants us to
   ** negotiate an option we didn't include.
   */

#define IPCP_RNAK_ADD(ci,len) \
         if (req_neg.NEG_ ## ci || sizeleft < len || *inp++ != len) goto badnak; \
         sizeleft -= len

   while (sizeleft) {
      switch (code) {
      case IPCP_CI_ADDR:
         IPCP_RNAK_ADD(ADDR,6);
         req_neg.NEG_ADDR = 1;
         if (ipcp_ptr->INIT.ACCEPT_LOCAL_ADDR) {
            req_neg.ADDR = ntohl(inp);
         } /* Endif */
         inp += 4;
         break;
      case IPCP_CI_DNS:
         IPCP_RNAK_ADD(DNS,6);
         if (ipcp_ptr->INIT.NEG_LOCAL_DNS) {
            req_neg.NEG_DNS = 1;
            if (ipcp_ptr->INIT.ACCEPT_LOCAL_DNS) {
               req_neg.DNS = ntohl(inp);
            } /* Endif */
         } /* Endif */
         inp += 4;
         break;
      default:
         if (sizeleft < *inp || *inp < 2) goto badnak;
         sizeleft -= *inp;
         inp += *inp - 1;
      } /* Endswtich */
      code = *inp++;
   } /* Endwhile */

   if (fsm->STATE < PPP_STATE_OPENED) {
      ipcp_ptr->NEG = req_neg;
   } /* Endif */
   return TRUE;

badnak:
   return FALSE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_recvconfrej
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_Recvconfnak.  Parses a ConfRej packet.
*     This function should not modify any state if the rej is bad.
*
*END*-----------------------------------------------------------------*/

static boolean IPCP_recvconfrej
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = ((IP_IF_PTR)fsm->PRIVATE)->HANDLE;
   uchar_ptr            inp = fsm->DATA;
   uint_32              sizeleft = fsm->LENGTH;
   IPCP_OPT             req_opt = ipcp_ptr->LOPT;
   IPCP_NEG             req_neg = ipcp_ptr->NEG;
   uchar                code;

#define IPCP_RREJ(ci,len) \
      if (sizeleft < len) goto badrej; \
      if (*inp++ != len)  goto badrej; \
      sizeleft -= len;                 \
      req_neg.NEG_ ## ci = 0

      /*
      ** Rej'd codes must be in the same order as they were in the ConfReq
      */

   code = *inp++;

   if (sizeleft && req_neg.NEG_ADDR && code == IPCP_CI_ADDR) {
      IPCP_RREJ(ADDR,6);
      if (req_neg.ADDR != ntohl(inp)) goto badrej; inp += 4;
      req_opt.ADDR = ipcp_ptr->INIT.LOCAL_ADDR;
      code = *inp++;
   } /* Endif */

   if (sizeleft && req_neg.NEG_DNS && code == IPCP_CI_DNS) {
      IPCP_RREJ(DNS,6);
      if (req_neg.DNS != ntohl(inp)) goto badrej; inp += 4;
      req_opt.DNS = ipcp_ptr->INIT.LOCAL_DNS;
      code = *inp++;
   } /* Endif */

   if (sizeleft) goto badrej;

   if (fsm->STATE < PPP_STATE_OPENED) {
      ipcp_ptr->LOPT = req_opt;
      ipcp_ptr->NEG  = req_neg;
   } /* Endif */
   return TRUE;

badrej:
   return FALSE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_recvconfreq
* Returned Value  :  number of bytes written
* Comments        :
*     Called by PPPFSM_Recvconfreq.  Parses a ConfReq packet.
*     Builds a ConfAck/ConfNak/ConfRej packet out of fsm->PACKET,
*     and sets fsm->CODE appropriately.
*
*END*-----------------------------------------------------------------*/

static uint_32 IPCP_recvconfreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN] - State Machine */
      boolean           reject
            /* [IN] - whether to ConfRej if we disagree */
   )
{ /* Body */
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = ((IP_IF_PTR)fsm->PRIVATE)->HANDLE;
   uchar_ptr            inp = fsm->DATA;
   uchar_ptr            nakp, rejp;
   uint_32              sizeleft = fsm->LENGTH;
   uint_32              naklen, rejlen;
   IPCP_OPT             req_opt = ipcp_ptr->POPT;
   uchar                code;
   uchar                cicode, cilen;

#define CI_REJECT(n)                   \
   inp -= n;                           \
   code = CP_CODE_CONF_REJ;            \
   rejlen += cilen;                    \
   while (cilen--) *rejp++ = *inp++

#define CI_NAK                               \
   if (code != CP_CODE_CONF_REJ) {           \
      code = CP_CODE_CONF_NAK;               \
      if (reject) {                          \
         inp -= cilen;                       \
         naklen += cilen;                    \
         while (cilen--) *nakp++ = *inp++;   \
      } else

#define CI_ENDNAK                            \
   } /* Endif */

      /*
      ** Process all requested codes
      */

   rejp = nakp = inp;
   rejlen = naklen = 0;
   code = CP_CODE_CONF_ACK;

   while (sizeleft) {
         /* check remaining length */
      if (sizeleft < inp[1] || inp[1] < 2) {
         code = CP_CODE_CONF_REJ;
         rejlen += sizeleft;
         while (sizeleft--) *rejp++ = *inp++;
         break;
      } /* Endif */

      cicode = *inp++;
      sizeleft -= cilen = *inp++;

      switch (cicode) {
      case IPCP_CI_ADDR:
         if (cilen != 6) {
            CI_REJECT(2);
            break;
         } /* Endif */

         /* Accept their address if we don't know who they are */
         req_opt.ADDR = ntohl(inp); inp += 4;
         if (!ipcp_ptr->INIT.ACCEPT_REMOTE_ADDR &&
              ipcp_ptr->INIT.REMOTE_ADDR != req_opt.ADDR) {
            CI_NAK {
               *nakp++ = IPCP_CI_ADDR;
               naklen += *nakp++ = 6;
               htonl(nakp, ipcp_ptr->INIT.REMOTE_ADDR); nakp += 4;
            } CI_ENDNAK
         } /* Endif */
         break;

      case IPCP_CI_DNS:
         if (cilen != 6) {
            CI_REJECT(2);
            break;
         } /* Endif */

         /* Accept their address if we don't know who they are */
         req_opt.DNS = ntohl(inp); inp += 4;
         if (ipcp_ptr->INIT.NEG_REMOTE_DNS) {
            if (!ipcp_ptr->INIT.ACCEPT_REMOTE_DNS &&
                 ipcp_ptr->INIT.REMOTE_ADDR != req_opt.DNS) {
               CI_NAK {
                  *nakp++ = IPCP_CI_DNS;
                  naklen += *nakp++ = 6;
                  htonl(nakp, ipcp_ptr->INIT.REMOTE_DNS); nakp += 4;
               } CI_ENDNAK
            } /* Endif */
         } else {
            CI_REJECT(6);
         } /* Endif */
         break;

      default:
         CI_REJECT(2);
         break;
      } /* Endswitch */
   } /* Endwhile */

   /*
   ** If we wanted to send additional naks for unsent codes, they
   ** would go here, at *nakp.
   */

   if (code == CP_CODE_CONF_ACK) {
      ipcp_ptr->POPT = req_opt;
      sizeleft = fsm->LENGTH;
   } else if (code == CP_CODE_CONF_REJ) {
      sizeleft = rejlen;
   } else if (reject) {
      code = CP_CODE_CONF_REJ;
      sizeleft = naklen;
   } else { /* if code == NAK */
      sizeleft = naklen;
   } /* Endif */

   fsm->CODE = code;
   return sizeleft;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_recvcoderej
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_Recvcoderej.  Returns TRUE if the rejected
*     code is catastrophic.
*
*END*-----------------------------------------------------------------*/

static boolean IPCP_recvcoderej
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   uchar code = ntohc(fsm->DATA);
   return (code >= 1 && code <= 7);
} /* Endbody */

#endif  /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_receive.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_receive.c$
* $Version : 3.8.8.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the MACNET receive
*   support functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "bsp_prv.h"
#include "macnet_prv.h"          

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_rx_free_specific
*  Returned Value : void
*  Comments       :
*        Frees a receive buffer
*
*END*-----------------------------------------------------------------*/

static void MACNET_rx_free_specific
   (
      MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr,
         /* [IN] the PCB to enqueue */
      PCB_PTR     pcb_ptr,
      pointer *   list
   )
{ 
   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   MACNET_int_disable();
   ENET_Enqueue_Buffer(list, pcb_ptr->FRAG[0].FRAGMENT );
   pcb_ptr->FRAG[0].FRAGMENT = NULL;
   QADD(macnet_context_ptr->RxPCBHead, macnet_context_ptr->RxPCBTail, pcb_ptr);
   MACNET_int_enable();
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_rx_free_small
*  Returned Value : void
*  Comments       :
*        Frees a small receive buffer
*
*END*-----------------------------------------------------------------*/

static void MACNET_rx_free_small
   (
         /* [IN] the PCB to enqueue */
      PCB_PTR  pcb_ptr
   )
{ 
   ENET_CONTEXT_STRUCT_PTR     enet_ptr = (ENET_CONTEXT_STRUCT_PTR)pcb_ptr->PRIVATE;
   MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;


   MACNET_rx_free_specific(macnet_context_ptr, pcb_ptr, (pointer *)&macnet_context_ptr->SMALL_BUFFERS);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_rx_free_large
*  Returned Value : void
*  Comments       :
*        Frees a small receive buffer
*
*END*-----------------------------------------------------------------*/

static void MACNET_rx_free_large
   (
         /* [IN] the PCB to enqueue */
      PCB_PTR  pcb_ptr
   )
{ 
   ENET_CONTEXT_STRUCT_PTR     enet_ptr = (ENET_CONTEXT_STRUCT_PTR)pcb_ptr->PRIVATE;
   MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;


   MACNET_rx_free_specific(macnet_context_ptr, pcb_ptr, (pointer *)&macnet_context_ptr->LARGE_BUFFERS);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_rx_free
*  Returned Value : void
*  Comments       :
*        Frees a normal sized receive buffer
*
*END*-----------------------------------------------------------------*/

static void MACNET_rx_free
   (
         /* [IN] the PCB to enqueue */
      PCB_PTR  pcb_ptr
   )
{ 
   ENET_CONTEXT_STRUCT_PTR     enet_ptr = (ENET_CONTEXT_STRUCT_PTR)pcb_ptr->PRIVATE;
   MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   #if ENETCFG_SUPPORT_FRAGMENTED_PCBS
   uint_32                     i;
   #endif

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   MACNET_int_disable();

   #if ENETCFG_SUPPORT_FRAGMENTED_PCBS
      for (i=0;pcb_ptr->FRAG[i].FRAGMENT;i++) {
         ENET_Enqueue_Buffer((pointer*)&macnet_context_ptr->RX_BUFFERS, pcb_ptr->FRAG[i].FRAGMENT );
         pcb_ptr->FRAG[i].FRAGMENT = NULL;
      }
   #else   
      ENET_Enqueue_Buffer((pointer*)&macnet_context_ptr->RX_BUFFERS, pcb_ptr->FRAG[0].FRAGMENT );
      pcb_ptr->FRAG[0].FRAGMENT = NULL;
   #endif
   
   QADD(macnet_context_ptr->RxPCBHead, macnet_context_ptr->RxPCBTail, pcb_ptr);

   MACNET_add_buffers_to_rx_ring(macnet_context_ptr);
   MACNET_int_enable();
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_add_buffers_to_rx_ring
*  Returned Value : void
*  Comments       :
*        Enqueues a PCB onto the receive ring.
*
*END*-----------------------------------------------------------------*/

void MACNET_add_buffers_to_rx_ring(MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr)
{ 
   ENET_MemMapPtr            macnet_ptr = macnet_context_ptr->MACNET_ADDRESS;
   VENET_BD_STRUCT_PTR       bd_ptr;
   uchar_ptr buf;

   if (macnet_ptr == NULL) return;

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   MACNET_int_disable();
   
   while (macnet_context_ptr->ActiveRxBDs < macnet_context_ptr->NumRxBDs) {

      bd_ptr = &macnet_context_ptr->MACNET_RX_RING_PTR[macnet_context_ptr->LastRxBD];

      _DCACHE_INVALIDATE_MBYTES((pointer)bd_ptr, sizeof(ENET_BD_STRUCT));
      
      /* Initialize the descriptor and give it to the MACNET */
      buf = (uchar_ptr)HOST_TO_BE_LONG((uint_32)ENET_Dequeue_Buffer((pointer *) &macnet_context_ptr->RX_BUFFERS));
      if (buf == NULL) {
         MACNET_int_enable();
         return;
      }
      
      bd_ptr->BUFFER = buf;
      bd_ptr->LENGTH = 0;

      /*
      ** The processor doesn't clear control bits when errors don't occur;
      ** it just sets bits when errors do occur.  So we clear all the
      ** control bits before enqueueing the descriptor.
      */

      bd_ptr->CONTROL &= HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_RX_WRAP);

      /*
      ** Add the PCB to the receive PCB queue (linked via PRIVATE) and
      ** increment the tail to the next descriptor
      */
      BD_INC(macnet_context_ptr->LastRxBD, macnet_context_ptr->NumRxBDs);
      macnet_context_ptr->ActiveRxBDs++;

      bd_ptr->CONTROL |= HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_RX_EMPTY);

      /* In case Enhanced BD are used allow interrupt generation */
      bd_ptr->CONTROL_EXT0 |= HOST_TO_BE_SHORT_CONST(ENET_BD_EXT0_ETHER_RX_GENERATE_INTR);

      _DCACHE_FLUSH_MBYTES((pointer)bd_ptr, sizeof(ENET_BD_STRUCT));  

      /*
      ** Signals the MACNET that empty buffers are available.
      */
      macnet_ptr->RDAR = ENET_RDAR_RDAR_MASK;
   }
   MACNET_int_enable();
} 



#if !ENETCFG_SUPPORT_FRAGMENTED_PCBS

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_discard_current_rx
*  Returned Value : void
*  Comments       :
 *
*
*END*-----------------------------------------------------------------*/

static void MACNET_discard_current_rx(ENET_CONTEXT_STRUCT_PTR    enet_ptr,MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr, boolean last)
{
   uint_32  i;
   

   if (macnet_context_ptr->CurrentRxECB) {
      for (i=0;i<macnet_context_ptr->CurrentRxFrag;i++) {
         ENET_INC_STATS(COMMON.ST_RX_DISCARDED);
         if (macnet_context_ptr->FRAGS[i].FRAGMENT) {
            ENET_Enqueue_Buffer((pointer*)&macnet_context_ptr->RX_BUFFERS, macnet_context_ptr->FRAGS[i].FRAGMENT);
         }
         macnet_context_ptr->FRAGS[i].FRAGMENT = NULL;
      }
   }
   macnet_context_ptr->CurrentRxECB=NULL;
   
   if (last) 
      macnet_context_ptr->CurrentRxFrag=0;
}      


  
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_process_rx_bds
*  Returned Value : void
*  Comments       :
*        Processes received buffers.
*
* NOTE: For MACNET, a frame consists of one or more buffers.
*       For ENET, a packet consists of one or more fragments
*        Therefore, a frame = a packet, and a buffer = a fragment.
*
*
*END*-----------------------------------------------------------------*/
static void MACNET_process_rx_bds
   (
         /* [IN] the Ethernet state structure */
      ENET_CONTEXT_STRUCT_PTR    enet_ptr
   )
{ /* Body */
   MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   VENET_BD_STRUCT_PTR        bd_ptr;
   PCB_PTR                    pcb_ptr=NULL;
   uint_16                    rx_status;
   uint_32                    i,length;
   int_32                     ilength;
   uchar_ptr                  buffer, small_packet, large_packet;
   boolean                    buffer_is_valid, consumed, first, last;
   
   //_DCACHE_INVALIDATE();    // temporary - I can't find fast actual part of memory for cache invalidation

   /* Dequeue all received buffers (fragments) */
   while (macnet_context_ptr->ActiveRxBDs > 0) {

      bd_ptr = &macnet_context_ptr->MACNET_RX_RING_PTR[macnet_context_ptr->NextRxBD];
      _DCACHE_INVALIDATE_MBYTES((pointer)bd_ptr, sizeof(ENET_BD_STRUCT));  

      if ((bd_ptr->CONTROL & HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_RX_EMPTY)) != 0) {
         break; // Currently being written to by MII
      }  

      BD_INC(macnet_context_ptr->NextRxBD,macnet_context_ptr->NumRxBDs);
      macnet_context_ptr->ActiveRxBDs--;

      ENET_INC_STATS(COMMON.ST_RX_TOTAL);
      rx_status = SHORT_BE_TO_HOST(bd_ptr->CONTROL);
      length = SHORT_BE_TO_HOST(bd_ptr->LENGTH);
      buffer = (uchar_ptr)LONG_BE_TO_HOST((uint_32)(bd_ptr->BUFFER));
      //buffer = LONG_BE_TO_HOST(bd_ptr->BUFFER);
      
      consumed = FALSE;
      first = macnet_context_ptr->CurrentRxFrag == 0;
      last = TRUE;
      
      // Start by validating the received buffer 
      // a buffer is valid if:
      //   (it is error free) AND ( (it is the first buffer in a frame) OR (it is a subsequent buffer in a frame we want ) )
      // 
      buffer_is_valid = FALSE;
      if (rx_status & ENET_BD_ETHER_RX_TRUNCATED) {
      
         ENET_INC_STATS(ST_RX_RUNT);
     
      } else if (rx_status & ENET_BD_ETHER_RX_LAST_FRAME) {
         
         // Some error bits can only be checked on the last buffer
         
         // Overrun needs to be checked first,  If this bit is 
         // set, the other status bits, M, LG, NO, CR, and CL lose their normal meaning and are zero. This bit 
         // is valid only if the L-bit is set.
         if (rx_status & ENET_BD_ETHER_RX_OVERRUN) {
            ENET_INC_STATS(ST_RX_OVERRUN);
         
         } else if (rx_status & ENET_BD_ETHER_RX_LENGTH_VIOLATION) {
            ENET_INC_STATS(ST_RX_GIANT);
            
         } else if (rx_status & ENET_BD_ETHER_RX_NON_OCTET) {
            ENET_INC_STATS(ST_RX_ALIGN);
            
         } else if (rx_status & ENET_BD_ETHER_RX_CRC_ERROR) {
            ENET_INC_STATS(ST_RX_FCS);
         } else {
            #if BSPCFG_ENABLE_ENET_HISTOGRAM
               uint_32 index = length>> ENET_HISTOGRAM_SHIFT;
               
               if (index < ENET_HISTOGRAM_ENTRIES) {
                  ENET_INC_STATS(RX_HISTOGRAM[index]);
               }
            #endif
         
         
            // Good buffer (with Last bit set). 
            buffer_is_valid = TRUE;
            // Remove CRC and compute buffer length
            ilength = length - (ENET_FRAMESIZE_TAIL + (macnet_context_ptr->CurrentRxFrag * enet_ptr->PARAM_PTR->RX_BUFFER_SIZE));
            
            // The last fragment may contain nothing but part of the CRC. If this is the case, length will be <= 0,
            // and if length < 0, the previous fragment contains part of the CRC, which needs to be removed.
            if (ilength < 0) {
               length = 0;
               if (!first) {
                  macnet_context_ptr->FRAGS[macnet_context_ptr->CurrentRxFrag-1].LENGTH += ilength;
               } else {
                  // Should never get here - would mean we received a really small packet which should have already been
                  // caught above. But if we do, discard it.
                  buffer_is_valid = TRUE;
               }
            } else {
               length = (uint_32) ilength;
            }
                  
         }
         
      }  else {
         // Good buffer (without Last bit set). Can only be processed if we are not currently discarding.
         buffer_is_valid = TRUE;
         last = FALSE;
      }   
      
      
         
      if (!buffer_is_valid) {
         // Was a buffer with an error
         ENET_INC_STATS(COMMON.ST_RX_ERRORS);
         MACNET_discard_current_rx(enet_ptr,macnet_context_ptr,last);
         
      } else {
         // If it is the first buffer in the frame, we have to see if the frame is of interest. 
         if (first) {
            // make sure we don't examine a cached copy of the buffer
            _DCACHE_INVALIDATE_MBYTES(buffer, length);  

            // the frame is of interest if there is a receiver registered for the destination and protocol. We can do this on the first buffer
            // of the frame, since  the ethernet header information always fits in  the first buffer of a frame.
            macnet_context_ptr->CurrentRxECB = ENET_find_receiver(enet_ptr, (ENET_HEADER_PTR) buffer, &length);
         }

         
         // If we have an Rx ECB, it means we want this packet
         if (macnet_context_ptr->CurrentRxECB ) {
            if (!first) {
               // If it is not the first packet, the cache is still valid. We could have put the invalidate before the first "if (first)",
               // but that would mean we may invalidate the cache on buffers that we know we are discarding.
               _DCACHE_INVALIDATE_MBYTES(buffer, length);  
            }            
            
            // Add the packet to the list of fragments in the PCB               
            macnet_context_ptr->FRAGS[macnet_context_ptr->CurrentRxFrag].FRAGMENT = buffer;
            macnet_context_ptr->FRAGS[macnet_context_ptr->CurrentRxFrag].LENGTH = length;
            macnet_context_ptr->CurrentRxFrag++;

            consumed = TRUE;

            // Now, there are three cases:
            //  !l - start or mid frame buffer - store it for later coalecing into a large buffer
            //  !f, l - end of multi-buffer packet - coalece into a large buffer
            //   f, l - single buffer packet - ready to process 
            
            if (!last) { 

               // Not the last frame in the packet. Have to make sure there is room for at least one
               // more fragment. If not, the packet is too large
               if (macnet_context_ptr->CurrentRxFrag >= MACNET_MAX_FRAGS) {
                  MACNET_discard_current_rx(enet_ptr,macnet_context_ptr,last);
                  ENET_INC_STATS(RX_FRAGS_EXCEEDED);
               }                     

            } else {  
               // last buffer (may or may not also be the first buffer) so process it

               // There is a receiver, so need to allocate a receive PCB
               QGET(macnet_context_ptr->RxPCBHead, macnet_context_ptr->RxPCBTail, pcb_ptr);
               if (pcb_ptr) {
                  // allocation successful, initialize new receive PCB
                  pcb_ptr->PRIVATE = (pointer)enet_ptr;
                  pcb_ptr->FREE = MACNET_rx_free;
                  
                  // Check to see if it is a large packet
                  if (!first) {
                     // Coalese
                     large_packet = ENET_Dequeue_Buffer((pointer *)&macnet_context_ptr->LARGE_BUFFERS);
                     
                     if (large_packet) {
                        // need to compute the length of this fragment, because the length on a BD with the L bit set
                        // is not the length of the buffer, it is the length of the frame.
                        pcb_ptr->FRAG[0].FRAGMENT = large_packet;
                        pcb_ptr->FRAG[0].LENGTH = 0;
                        pcb_ptr->FREE = MACNET_rx_free_large;

                        for (i=0;i<macnet_context_ptr->CurrentRxFrag;i++) {
                           if (macnet_context_ptr->FRAGS[i].LENGTH ) {
                              _mem_copy(macnet_context_ptr->FRAGS[i].FRAGMENT, large_packet, macnet_context_ptr->FRAGS[i].LENGTH  );
                              large_packet += macnet_context_ptr->FRAGS[i].LENGTH;
                              pcb_ptr->FRAG[0].LENGTH += macnet_context_ptr->FRAGS[i].LENGTH;
                           }
                           ENET_Enqueue_Buffer((pointer*)&macnet_context_ptr->RX_BUFFERS, macnet_context_ptr->FRAGS[i].FRAGMENT);
                           macnet_context_ptr->FRAGS[i].FRAGMENT = NULL;
                        }
                  
                        ENET_INC_STATS(ST_RX_COPY_LARGE);
                     } else {
                        ENET_INC_STATS(RX_LARGE_BUFFERS_EXHAUSTED);
                     
                        MACNET_discard_current_rx(enet_ptr,macnet_context_ptr,last);
                        QADD(macnet_context_ptr->RxPCBHead, macnet_context_ptr->RxPCBTail, pcb_ptr);
                        pcb_ptr=NULL;
                     }                     
                  
                  // Check to see if it is a small packet
                  } else { 
                     pcb_ptr->FRAG[0].LENGTH = length;
                     pcb_ptr->FRAG[0].FRAGMENT = buffer;
                     if (length < MACNET_SMALL_PACKET_SIZE) {
 
                        small_packet = ENET_Dequeue_Buffer((pointer *)&macnet_context_ptr->SMALL_BUFFERS);
                        
                        if (small_packet) {
                           _mem_copy( macnet_context_ptr->FRAGS[0].FRAGMENT, small_packet, length );

                           pcb_ptr->FRAG[0].FRAGMENT = small_packet;
                           pcb_ptr->FREE = MACNET_rx_free_small;

                           consumed = FALSE;

                           ENET_INC_STATS(ST_RX_COPY_SMALL);
                        }
                     }
                  }
                  
                                    
                  if (pcb_ptr) {  
                     pcb_ptr->FRAG[1].LENGTH = 0;
                     pcb_ptr->FRAG[1].FRAGMENT = NULL;

#if ENETCFG_SUPPORT_PTP
                     if (macnet_context_ptr->PTP_PRIV->PTIMER_PRESENT) 
                     {
                        MACNET_ptp_store_rxstamp(enet_ptr, pcb_ptr, bd_ptr);
                     }
#endif /* ENETCFG_SUPPORT_PTP */
                     // Call the receiver's service function to pass the PCB to the receiver
                     macnet_context_ptr->CurrentRxECB->SERVICE(pcb_ptr, macnet_context_ptr->CurrentRxECB->PRIVATE);

                     // and clear the current ECB and PCB info, as it's gone to the receiver now.
                     macnet_context_ptr->CurrentRxECB = NULL;
                     macnet_context_ptr->CurrentRxFrag = 0;
                  }                  
                  
                  
               } else {

                  // Couldn't get a Receive PCB, so need to discard buffers until last buffer in frame.
                  MACNET_discard_current_rx(enet_ptr,macnet_context_ptr,last);
                  ENET_INC_STATS(RX_PCBS_EXHAUSTED);
               }
            }
         }         
      }
      
      
      if (!consumed) {
         ENET_INC_STATS(COMMON.ST_RX_DISCARDED);
         ENET_Enqueue_Buffer((pointer*)&macnet_context_ptr->RX_BUFFERS, buffer);
      }
   }
   MACNET_add_buffers_to_rx_ring(macnet_context_ptr);
} 

#else

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_discard_current_rx
*  Returned Value : void
*  Comments       :
 *
*
*END*-----------------------------------------------------------------*/

static void MACNET_discard_current_rx(ENET_CONTEXT_STRUCT_PTR    enet_ptr,MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr, boolean last)
{
   uint_32  i;
   PCB_PTR pcb_ptr = (PCB_PTR) macnet_context_ptr->CurrentRxPCB;
   
   macnet_context_ptr->CurrentRxECB=NULL; 

   if (pcb_ptr) {
      for (i=0;i<macnet_context_ptr->CurrentRxFrag;i++) {
         ENET_INC_STATS(COMMON.ST_RX_DISCARDED);
         ENET_Enqueue_Buffer((pointer*)&macnet_context_ptr->RX_BUFFERS, pcb_ptr->FRAG[i].FRAGMENT);
      }
      QADD(macnet_context_ptr->RxPCBHead, macnet_context_ptr->RxPCBTail, pcb_ptr);

      macnet_context_ptr->CurrentRxFrag=0;
      macnet_context_ptr->CurrentRxPCB=NULL;
      MACNET_add_buffers_to_rx_ring(macnet_context_ptr);
   }
   
   macnet_context_ptr->RxDiscarding = !last;
}      


  
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_process_rx_bds
*  Returned Value : void
*  Comments       :
*        Processes received buffers.
*
* NOTE: For MACNET, a frame consists of one or more buffers.
*       For ENET, a packet consists of one or more fragments
*        Therefore, a frame = a packet, and a buffer = a fragment.
*
*
*END*-----------------------------------------------------------------*/

static void MACNET_process_rx_bds
   (
         /* [IN] the Ethernet state structure */
      ENET_CONTEXT_STRUCT_PTR    enet_ptr
   )
{ /* Body */
   MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->DEVICE_CONTEXT_PTR;
   VENET_BD_STRUCT_PTR        bd_ptr;
   PCB_PTR                    pcb_ptr=NULL;
   uint_16                    rx_status;
   uint_32                    length,i;
   uchar_ptr                  buffer, small_packet;
   boolean                    buffer_is_valid, processed, last;

   /* Dequeue all received buffers (fragments) */
   while (macnet_context_ptr->ActiveRxBDs > 0) {

      bd_ptr = &macnet_context_ptr->MACNET_RX_RING_PTR[macnet_context_ptr->NextRxBD];
      _DCACHE_INVALIDATE_MBYTES(bd_ptr, sizeof(MACNET_BD_STRUCT));  

      if ((bd_ptr->CONTROL & HOST_TO_BE_SHORT_CONST(MCF5XXX_MACNET_BD_ETHER_RX_EMPTY)) != 0) {
         break; // Currently being written to by MII
      }  

      BD_INC(macnet_context_ptr->NextRxBD,macnet_context_ptr->NumRxBDs);
      macnet_context_ptr->ActiveRxBDs--;

      ENET_INC_STATS(COMMON.ST_RX_TOTAL);
      rx_status = SHORT_BE_TO_HOST(bd_ptr->CONTROL);
      length = SHORT_BE_TO_HOST(bd_ptr->LENGTH);
      buffer = LONG_BE_TO_HOST(bd_ptr->BUFFER);

      processed = FALSE;
      last = TRUE;
      
      // Start by validating the received buffer 
      buffer_is_valid = FALSE;
      if (rx_status & MCF5XXX_MACNET_BD_ETHER_RX_TRUNCATED) {
      
         ENET_INC_STATS(ST_RX_RUNT);
     
      } else if (rx_status & MCF5XXX_MACNET_BD_ETHER_RX_LAST_FRAME) {
         
         // Some error bits can only be checked on the last buffer
         
         // Overrun needs to be checked first,  If this bit is 
         // set, the other status bits, M, LG, NO, CR, and CL lose their normal meaning and are zero. This bit 
         // is valid only if the L-bit is set.
         if (rx_status & MCF5XXX_MACNET_BD_ETHER_RX_OVERRUN) {
            ENET_INC_STATS(ST_RX_OVERRUN);
         
         } else if (rx_status & MCF5XXX_MACNET_BD_ETHER_RX_LENGTH_VIOLATION) {
            ENET_INC_STATS(ST_RX_GIANT);
            
         } else if (rx_status & MCF5XXX_MACNET_BD_ETHER_RX_NON_OCTET) {
            ENET_INC_STATS(ST_RX_ALIGN);
            
         } else if (rx_status & MCF5XXX_MACNET_BD_ETHER_RX_CRC_ERROR) {
            ENET_INC_STATS(ST_RX_FCS);
         } else {
            // Good buffer (with Last bit set). Can only be processed if we are not currently discarding.
            buffer_is_valid = !macnet_context_ptr->RxDiscarding;
         }
         
      }  else {
         // Good buffer (without Last bit set). Can only be processed if we are not currently discarding.
         buffer_is_valid = !macnet_context_ptr->RxDiscarding;
         last = FALSE;
      }      

      if (buffer_is_valid) {
         // make sure we don't examine a cached copy of the buffer
         _DCACHE_INVALIDATE_MBYTES(buffer, length);  

         // Check to see if there is a receiver - if there is, this is not the first buffer of the frame.
         if (macnet_context_ptr->CurrentRxECB==NULL) {
            
            // There wasn't, so it is the first buffer of a frame. Check to see if there is a receiver registered for this packet's 
            // destination and protocol. We can do this on the first buffer of the frame, since this information always fits in 
            // the first buffer of a frame.
            macnet_context_ptr->CurrentRxECB = ENET_find_receiver(enet_ptr, (ENET_HEADER_PTR) buffer, &length);
   
            if (macnet_context_ptr->CurrentRxECB ) {
               // There is a receiver, so need to allocate a receive PCB
               QGET(macnet_context_ptr->RxPCBHead, macnet_context_ptr->RxPCBTail, pcb_ptr);
               if (pcb_ptr) {
                  // allocation successful, initialize new receive PCB
                  macnet_context_ptr->CurrentRxPCB = pcb_ptr;
                  macnet_context_ptr->CurrentRxFrag = 0;
                  pcb_ptr->FREE = MACNET_rx_free;
                  pcb_ptr->PRIVATE = (pointer)enet_ptr;
                  
               } else {
                  // Couldn't get a Receive PCB, so need to discard buffers until last buffer in frame.
                  macnet_context_ptr->RxDiscarding = !last;
                  macnet_context_ptr->CurrentRxECB = NULL;
               }
            
            } else {
               // There isn't a receiver, so need to discard buffers until last buffer in frame.
               macnet_context_ptr->RxDiscarding = !last;
               pcb_ptr = NULL;
            }
            
         
         } else {
            // we are already have a receiving ECB, and therefore a PCB.
            pcb_ptr = macnet_context_ptr->CurrentRxPCB;
         }

         if (pcb_ptr) {
         
            // We have a receiver (ecb) and a pcb, so the packet can be processed.
            processed = TRUE;                  

            // Add the packet to the list of fragments in the PCB               
            pcb_ptr->FRAG[macnet_context_ptr->CurrentRxFrag].FRAGMENT = buffer;
       
            // Check to see if this is the last buffer in the frame
            if (last) {
               // need to compute the length of this fragment, because the length on a BD with the L bit set
               // is not the length of the buffer, it is the length of the frame.
               for (i=0;i<macnet_context_ptr->CurrentRxFrag;i++) {
                  length -= pcb_ptr->FRAG[i].LENGTH;
               }
               // remove CRC
               pcb_ptr->FRAG[macnet_context_ptr->CurrentRxFrag].LENGTH = length - ENET_FRAMESIZE_TAIL;
                
               // Terminate the fragment list in the PCB.
               pcb_ptr->FRAG[macnet_context_ptr->CurrentRxFrag+1].LENGTH = 0;
               pcb_ptr->FRAG[macnet_context_ptr->CurrentRxFrag+1].FRAGMENT = 0;

               // Call the receiver's service function to pass the PCB to the receiver
               macnet_context_ptr->CurrentRxECB->SERVICE(pcb_ptr, macnet_context_ptr->CurrentRxECB->PRIVATE);

               // and clear the current ECB and PCB info, as it's gone to the receiver now.
               macnet_context_ptr->CurrentRxECB = NULL;
               macnet_context_ptr->CurrentRxPCB = NULL;
               macnet_context_ptr->CurrentRxFrag = 0;
            } else {
               pcb_ptr->FRAG[macnet_context_ptr->CurrentRxFrag].LENGTH = length;
               
               macnet_context_ptr->CurrentRxFrag++;
               
               // Not the last frame in the packet. Have to make sure there is room for at least one
               // more fragment. If not, the packet is too large
               if (macnet_context_ptr->CurrentRxFrag >= MACNET_MAX_FRAGS) {
                  MACNET_discard_current_rx(enet_ptr,macnet_context_ptr,last);
               }                     
            }
         }
      } else {
         // Was a buffer with an error
         ENET_INC_STATS(COMMON.ST_RX_ERRORS);
         MACNET_discard_current_rx(enet_ptr,macnet_context_ptr,last);
      } 
      
     
      if (!processed) {
         ENET_INC_STATS(COMMON.ST_RX_DISCARDED);
         ENET_Enqueue_Buffer((pointer*)&macnet_context_ptr->RX_BUFFERS, buffer);
         MACNET_add_buffers_to_rx_ring(macnet_context_ptr);
      }
   } 
} 

#endif                

/*NOTIFIER*-------------------------------------------------------------
*
*  Function Name  : MACNET_RX_ISR
*  Returned Value : void
*  Comments       :
*        Interrupt service routine for Rx.
*
*END*-----------------------------------------------------------------*/

void MACNET_RX_ISR
   (
         /* [IN] the Ethernet state structure */
      pointer  enet
   )
{ /* Body */

   ENET_CONTEXT_STRUCT_PTR    enet_ptr           = (ENET_CONTEXT_STRUCT_PTR)enet;
   MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   ENET_MemMapPtr             macnet_ptr         = macnet_context_ptr->MACNET_ADDRESS;
   uint_32                    events;

   if (macnet_ptr == NULL) return;

   events = macnet_ptr->EIR;
   while (events & (ENET_EIR_RXF_MASK | ENET_EIR_RXB_MASK)) {

      /* clear the RX interrupt */
      macnet_ptr->EIR = (ENET_EIR_RXF_MASK | ENET_EIR_RXB_MASK); 
      MACNET_process_rx_bds(enet_ptr);

      events = macnet_ptr->EIR;
   }
} 


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/build/bat/mfs_INV1_K60F120.bat<|end_filename|>
@echo off

rem convert path to backslash format
set MQXROOTDIR=%1
set MQXROOTDIR=%MQXROOTDIR:/=\%
set OUTPUTDIR=%2
set OUTPUTDIR=%OUTPUTDIR:/=\%
set TOOL=%3


rem copy common files
IF NOT EXIST %OUTPUTDIR% mkdir %OUTPUTDIR%
copy %MQXROOTDIR%\mfs\source\include\mfs.h %OUTPUTDIR%\mfs.h /Y
copy %MQXROOTDIR%\mfs\source\include\mfs_cnfg.h %OUTPUTDIR%\mfs_cnfg.h /Y
copy %MQXROOTDIR%\mfs\source\include\mfs_rev.h %OUTPUTDIR%\mfs_rev.h /Y
copy %MQXROOTDIR%\mfs\source\include\part_mgr.h %OUTPUTDIR%\part_mgr.h /Y


goto tool_%TOOL%

rem cw10 files
:tool_cw10
goto copy_end

rem iar files
:tool_iar
goto copy_end

rem cw10gcc files
:tool_cw10gcc
goto copy_end

rem uv4 files
:tool_uv4
goto copy_end

:copy_end



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/inet_ntop.c<|end_filename|>
/**HEADER*******************************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved                      
*
**************************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************************
*
* $FileName: inet_ntop.c$
* $Version : 3.8.3.0$
* $Date    : Aug-13-2012$
*
* Comments:
*
*   Convert a network format address to presentation format.
*
*END************************************************************************************/
/*
 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
 * Copyright (c) 1996-1999 by Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <string.h>
#include <ctype.h>
#include <rtcs.h>
#include <addrinfo.h>

static char	*inet_ntop4(const uchar *src, char *dst, socklen_t size);
static char	*inet_ntop6(const uchar *src, char *dst, socklen_t size);

/**************************************************************************************** 
 * char *
 * inet_ntop(af, src, dst, size)
 *	convert a network format address to presentation format.
 * return:
 *	pointer to presentation format address (`dst'), or NULL (see errno).
 * author:
 *	<NAME>, 1996.
 ****************************************************************************************/
char *inet_ntop(int_32 af, const void *src, char *dst, socklen_t size)
{
	switch (af) {
	case AF_INET:
		return (inet_ntop4(src, dst, size));
	case AF_INET6:
		return (inet_ntop6(src, dst, size));
	default:
		return (NULL);
	}
	/* NOTREACHED */
}

/**************************************************************************************** 
 * const char *
 * inet_ntop4(src, dst, size)
 *	format an IPv4 address
 * return:
 *	`dst' (as a const)
 * notes:
 *	(1) uses no statics
 *	(2) takes a u_char* not an in_addr as input
 *****************************************************************************************/
static char *inet_ntop4 (
                          const uchar  *h_src /*[IN]  inet4 address in bin format */,
                          char         *dst /*[OUT] inet4 address in prn format */,
                          socklen_t    size /*[IN]  sizeof dst buffer           */
                        )
{
	static const char fmt[] = "%u.%u.%u.%u";
	char tmp[sizeof "255.255.255.255"];
	int l;
    uint_32 h_address=0;
    uint_32 tmp_address=0;
    uchar *src;
    
   /* RTCS use always host presentation, so we will convert it to network presentation. */
    memcpy(&tmp_address, h_src, sizeof(h_address));
    htonl(&h_address,tmp_address);

    src = (uchar*)&h_address;
   /*l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
	* TBD
	* here we must use snprinf to avoid buffer overflow
    */
    l=sprintf(tmp,fmt,src[0], src[1], src[2], src[3]);
    
        
	if (l <= 0 || (socklen_t) l >= size) {
		return (NULL);
	}
	strlcpy(dst, tmp, size);
   /*
    * Return pointer to prn buffer.
	* It can be usefull for printf function.
	*/
	return (dst);
}

/*******************************************************************************************
 * const char *
 * inet_ntop6(src, dst, size)
 * convert IPv6 binary address into presentation (printable) format
 *******************************************************************************************/
static char *inet_ntop6 (
                          const uchar *src /*[IN]  pointer to inet6 address in bin format */,
                          char         *dst /*[OUT] pointer to inet6 address in prn format */,  
                          socklen_t    size /*[IN]  sizeof dst buffer                      */ 
                        )
{
	/*
	 * Note that int32_t and int16_t need only be "at least" large enough
	 * to contain a value of the specified size.  On some systems, like
	 * Crays, there is no such thing as an integer variable with 16 bits.
	 * Keep this in mind if you think this function should have been coded
	 * to use pointer overlays.  All the world's not a VAX.
	 */
	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
	struct { int base, len; } best, cur;

	#ifndef	NS_IN6ADDRSZ
		#define NS_IN6ADDRSZ	16
	#endif
	
	#ifndef NS_INT16SZ
		#define NS_INT16SZ		2
	#endif	
	
	unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
	int i;

	/*
	 * Preprocess:
	 *	Copy the input (bytewise) array into a wordwise array.
	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
	 */
	memset(words, '\0', sizeof words);
	for (i = 0; i < NS_IN6ADDRSZ; i++)
		words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
	best.base = -1;
	best.len = 0;
	cur.base = -1;
	cur.len = 0;
	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
		if (words[i] == 0) {
			if (cur.base == -1)
				cur.base = i, cur.len = 1;
			else
				cur.len++;
		} else {
			if (cur.base != -1) {
				if (best.base == -1 || cur.len > best.len)
					best = cur;
				cur.base = -1;
			}
		}
	}
	if (cur.base != -1) {
		if (best.base == -1 || cur.len > best.len)
			best = cur;
	}
	if (best.base != -1 && best.len < 2)
		best.base = -1;

	/*
	 * Format the result.
	 */
	tp = tmp;
	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
		/* Are we inside the best run of 0x00's? */
		if (best.base != -1 && i >= best.base &&
		    i < (best.base + best.len)) {
			if (i == best.base)
				*tp++ = ':';
			continue;
		}
		/* Are we following an initial run of 0x00s or any real hex? */
		if (i != 0)
			*tp++ = ':';
		/* Is this address an encapsulated IPv4? */
		if (i == 6 && best.base == 0 && (best.len == 6 ||
		    (best.len == 7 && words[7] != 0x0001) ||
		    (best.len == 5 && words[5] == 0xffff))) {
			if (!inet_ntop4((src+12),tp, sizeof tmp - (tp - tmp)))
				return (NULL);
			tp += strlen(tp);
			break;
		}
		tp += sprintf(tp, "%x", words[i]);
	}
	/* Was it a trailing run of 0x00's? */
	if (best.base != -1 && (best.base + best.len) == 
	    (NS_IN6ADDRSZ / NS_INT16SZ))
		*tp++ = ':';
	*tp++ = '\0';

	/*
	 * Check for overflow, copy, and we're done.
	 */
	if ((socklen_t)(tp - tmp) > size) {
		return (NULL);
	}
	strcpy(dst, tmp);
	return (dst);
}


/*************************************************************************************	
 * $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $	
 *
 * Copy src to string dst of size siz.  At most siz-1 characters
 * will be copied.  Always NUL terminates (unless siz == 0).
 * Returns strlen(src); if retval >= siz, truncation occurred.
 *************************************************************************************/
unsigned int strlcpy (
                    char *dst           /*[OUT]  */, 
                    const char *src     /*[IN] */, 
                    unsigned int siz          /*[IN]  */
               )
{
	char *d = dst;
	const char *s = src;
	unsigned int n = siz;

	/* Copy as many bytes as will fit */
	if (n != 0) {
		while (--n != 0) {
			if ((*d++ = *s++) == '\0')
				break;
		}
	}

	/* Not enough room in dst, add NUL and traverse rest of src */
	if (n == 0) {
		if (siz != 0)
			*d = '\0';		/* NUL-terminate dst  */
		while (*s++)		/* to set ent to "\0" */
			;
	}

	return(s - src - 1);	/* count does not include NUL */
}



<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_nat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_nat.c$
* $Version : 3.8.6.0$
* $Date    : Aug-29-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/
#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h"
#include <fio.h>


#include <nat.h>
#include <rtcstime.h>
#include <nat_session.h>

#if RTCSCFG_ENABLE_NAT

static char_ptr IP_Prot_str(uint_32 prot)
{
   switch (prot) {
      case IPPROTO_ICMP:   return "ICMP";
      case IPPROTO_IGMP:   return "IGMP";
      case IPPROTO_IP:     return "IP";
      case IPPROTO_TCP:    return "TCP";
      case IPPROTO_UDP:    return "UDP";
      default:             return "???";
   }
}


static char_ptr NAT_err_str(uint_32 err)
{
   switch (err) {
      case  RTCSERR_NAT_NO_SESSION:                return "No session";
      case  RTCSERR_NAT_UNSUPPORTED_PROTOCOL:      return "Unsupported protocol";
      case  RTCSERR_NAT_INITIALIZED:               return "NAT initialized";
      case  RTCSERR_NAT_UNEXPECTED:                return "Unexpected error";
      case  RTCSERR_NAT_NOT_INITIALIZED:           return "NAT not initialized";
      case  RTCSERR_NAT_INVALID_RULE:              return "Invalid rule";
      case  RTCSERR_OUT_OF_MEMORY:                 return "No memory";
      case  RTCSERR_NAT_INVALID_PRIVATE_NETWORK:   return "Invalid private network";
      case  RTCSERR_NAT_MAX_PRIVATE_NETWORKS:      return "Max private networks";
      case  RTCSERR_NAT_DUPLICATE_PRIORITY:        return "Duplicate priority";
      case  RTCSERR_NAT_END_OF_RULES:              return "End of rules";
      case  RTCSERR_NAT_INVALID_PRIVATE_ADDRESS:   return "Invalid private address";
      default:                                     return "Unknown error";
   }
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_natinit
*  Returned Value:  none
*  Comments  :  SHELL utility to initialize NAT
*END*-----------------------------------------------------------------*/

int_32  Shell_natinit(int_32 argc, char_ptr argv[] )
{
   uint_32              error;
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;
   _ip_address          addr, mask;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc == 3)  {
         if (! Shell_parse_ip_address( argv[1], &addr  ))  {
            printf("Error, invalid ip address\n");
            return_code = SHELL_EXIT_ERROR;
         } else if (! Shell_parse_netmask( argv[2], &mask  ))  {
            printf("Error, invalid ip address\n");
            return_code = SHELL_EXIT_ERROR;
         } else {
            error = NAT_init( addr, mask );
            if (error != RTCS_OK) {
               printf("Error initializing NAT: %s\n",NAT_err_str(error));
               return_code = SHELL_EXIT_ERROR;
            } else {
               printf("NAT Initialized\n");
            }
         }
      } else {
         print_usage = TRUE;
         return_code = SHELL_EXIT_ERROR;
      }
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <ipaddress> <netmask>\n", argv[0]);
      } else  {
         printf("Usage: %s <ipaddress> <netmask>\n",argv[0]);
      }
   }
   return return_code;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_natinfo
*  Returned Value:  none
*  Comments  :  SHELL utility to enable/disable NAT
*END*-----------------------------------------------------------------*/

#define NATINFO_STATS      0x01
#define NATINFO_RULES      0x02
#define NATINFO_NETWORKS   0x04
#define NATINFO_SESSIONS   0x08
#define NATINFO_ALL (NATINFO_STATS|NATINFO_RULES|NATINFO_NETWORKS|NATINFO_SESSIONS)

int_32  Shell_natinfo(int_32 argc, char_ptr argv[] )
{
   boolean                 print_usage, shorthelp = FALSE;
   int_32                  i  , return_code = SHELL_EXIT_SUCCESS;
   uint_32                 natinfo = 0, num_nets;
   NAT_STATS_PTR           nat_stats_ptr = NULL;
   NAT_NETWORK_STRUCT_PTR  nat_network_ptr = NULL;
   boolean                 continuous = FALSE;
   uint_32                 priority;        
   uint_16                 start_port;  
   uint_16                 end_port;        
   _ip_address             target_ip;     
   uint_16                 target_port; 
   uint_16                 protocol;
   uint_32                 result;

   NAT_SESSION_STRUCT_PTR  session_ptr;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );
      
   if (!print_usage)  {

      if (argc==1) {
         natinfo = NATINFO_ALL;   
      } else {
         for (i=1;i<argc;i++) {
            if (strcmp(argv[i],"stats")==0) {
               natinfo |= NATINFO_STATS;
            } else if (strcmp(argv[i],"rules")==0) {
               natinfo |= NATINFO_RULES;
            } else if (strcmp(argv[i],"networks")==0) {
               natinfo |= NATINFO_NETWORKS;
            } else if (strcmp(argv[i],"all")==0) {
               natinfo |= NATINFO_ALL;
            } else if (strcmp(argv[i],"loop")==0) {
               continuous = TRUE;
            } else {
                print_usage = TRUE;
                return_code = SHELL_EXIT_ERROR;
            }
         }
      }   
      if (return_code == SHELL_EXIT_SUCCESS) {
         do {
            if (natinfo & NATINFO_STATS) {
               nat_stats_ptr= NAT_stats();
               if (nat_stats_ptr == NULL) {
                  printf("NAT statistics not available.\n");
                  return_code = SHELL_EXIT_ERROR;
               } else {
                  printf("NAT Statistics:\n");
                  printf("   ST_SESSIONS:                0x%08x\n", nat_stats_ptr->ST_SESSIONS );   
                  printf("   ST_SESSIONS_SNAT:           0x%08x\n", nat_stats_ptr->ST_SESSIONS_SNAT );   
                  printf("   ST_SESSIONS_DNAT:           0x%08x\n", nat_stats_ptr->ST_SESSIONS_DNAT );   
                  printf("   ST_SESSIONS_OPEN:           0x%08x\n", nat_stats_ptr->ST_SESSIONS_OPEN );  
                  printf("   ST_SESSIONS_OPEN_MAX:       0x%08x\n", nat_stats_ptr->ST_SESSIONS_OPEN_MAX ); 
                  printf("   ST_PACKETS_TOTAL:           0x%08x\n", nat_stats_ptr->ST_PACKETS_TOTAL ); 
                  printf("   ST_PACKETS_BYPASS:          0x%08x\n", nat_stats_ptr->ST_PACKETS_BYPASS ); 
                  printf("   ST_PACKETS_PUB_PRV:         0x%08x\n", nat_stats_ptr->ST_PACKETS_PUB_PRV ); 
                  printf("   ST_PACKETS_PUB_PRV_ERR:     0x%08x\n", nat_stats_ptr->ST_PACKETS_PUB_PRV_ERR ); 
                  printf("   ST_PACKETS_PRV_PUB:         0x%08x\n", nat_stats_ptr->ST_PACKETS_PRV_PUB );
                  printf("   ST_PACKETS_PRV_PUB_ERR:     0x%08x\n", nat_stats_ptr->ST_PACKETS_PRV_PUB_ERR );
                  printf("   ST_PACKETS_FRAGMENTS:       0x%08x\n", nat_stats_ptr->ST_PACKETS_FRAGMENTS );
                  printf("   ST_PACKETS_REASSEMBLED:     0x%08x\n", nat_stats_ptr->ST_PACKETS_REASSEMBLED );
                  printf("   ST_PACKETS_REASSSEMBLY_ERR: 0x%08x\n", nat_stats_ptr->ST_PACKETS_REASSSEMBLY_ERR );
              }
            }
            if (natinfo & NATINFO_RULES) {
               priority=0;
               result = DNAT_get_next_rule(&priority,&protocol,&start_port,&end_port,
                  &target_ip,&target_port);
               if (result==RTCS_OK) {
                  printf("NAT Rules:\n");
                  while (result==RTCS_OK) {
                     printf("%d: %s (%d-%d) -> %03d.%03d.%03d.%03d:%d\n",
                        priority, protocol==IPPROTO_TCP?"TCP":"UDP",start_port,end_port, 
                        IPBYTES(target_ip), target_port);
                     result = DNAT_get_next_rule(&priority,&protocol,&start_port,&end_port,
                        &target_ip,&target_port);
                  }
               } else {
                  printf("NAT Rule data not available.\n");
                  return_code = SHELL_EXIT_ERROR;
               }
            }
            if (natinfo & NATINFO_NETWORKS) {
               nat_network_ptr= NAT_networks();
               if (nat_network_ptr == NULL) {
                  printf("NAT Network data not available.\n");
                  return_code = SHELL_EXIT_ERROR;
               } else {
                  printf("NAT Networks:\n");
                  for (num_nets=0;num_nets<nat_network_ptr->NUM_PRV_NETS;num_nets++) {
                     printf("   %2d: %03d.%03d.%03d.%03d  %03d.%03d.%03d.%03d \n", 
                        num_nets,
                        IPBYTES(nat_network_ptr->PRV_NET[num_nets]),
                        IPBYTES(nat_network_ptr->PRV_MASK[num_nets]));
                  }
                  for (num_nets=nat_network_ptr->NUM_PRV_NETS;num_nets<NAT_MAX_PRIVATE_NETWORKS;num_nets++) {
                     if ((nat_network_ptr->PRV_NET[num_nets]!=0) || (nat_network_ptr->PRV_MASK[num_nets])) {
                        printf("   Invalid Entry:\n   %2d: %03d.%03d.%03d.%03d  %03d.%03d.%03d.%03d \n", 
                           num_nets,
                           IPBYTES(nat_network_ptr->PRV_NET[num_nets]),
                           IPBYTES(nat_network_ptr->PRV_MASK[num_nets]));
                     }
                  }
               }
            }
            if (natinfo & NATINFO_SESSIONS) {
               printf("NAT Inbound sessions:\n");
               session_ptr = (NAT_SESSION_STRUCT_PTR) NAT_find_next_session(NULL, 0);
               while (session_ptr!=NULL) {
                  printf("%s-%s: %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d  [%d]\n",
                     session_ptr->SNAT_OR_DNAT==SNAT?"SNAT":"DNAT",
                     IP_Prot_str(session_ptr->IP_PROT), 
                     IPBYTES(session_ptr->PUB_HST), session_ptr->PUB_PORT,
                     IPBYTES(session_ptr->NAT_HST), session_ptr->NAT_PORT,
                     IPBYTES(session_ptr->PRV_HST), session_ptr->PRV_PORT,
                     session_ptr->TIMEOUT.TIME);

                     session_ptr = (NAT_SESSION_STRUCT_PTR) NAT_find_next_session((pointer)session_ptr, 0);
               }
               printf("NAT Outbound sessions:\n");
               session_ptr = (NAT_SESSION_STRUCT_PTR) NAT_find_next_session(NULL, 1);
               while (session_ptr!=NULL) {
                  printf("%s-%s: %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d  [%d]\n",
                     session_ptr->SNAT_OR_DNAT==SNAT?"SNAT":"DNAT",
                     IP_Prot_str(session_ptr->IP_PROT), 
                     IPBYTES(session_ptr->PRV_HST), session_ptr->PRV_PORT,
                     IPBYTES(session_ptr->NAT_HST), session_ptr->NAT_PORT,
                     IPBYTES(session_ptr->PUB_HST), session_ptr->PUB_PORT,
                     session_ptr->TIMEOUT.TIME);
                     session_ptr = (NAT_SESSION_STRUCT_PTR) NAT_find_next_session((pointer)session_ptr, 1);
               }
            }
            if (continuous) {
               if (status()) {
                  continuous = FALSE;
               } else {
                  _time_delay(1000);
               }
            }
         } while (continuous);
      }        
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s [stats|rules|networks|all|loop]\n", argv[0]);
      } else  {
         printf("Usage: %s [stats|rules|networks|all|loop]\n",argv[0]);
      }
   }
   return return_code;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_dnat
*  Returned Value:  none
*  Comments  :  SHELL utility to add a DNAT rule
*END*-----------------------------------------------------------------*/

int_32  Shell_dnat(int_32 argc, char_ptr argv[] )
{
   uint_32              error;
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;
   uint_32              priority=0;     
   uint_16              protocol=0;
   uint_16              start_port=0;   
   uint_16              end_port=0;     
   _ip_address          target_ip=0;      
   uint_16              target_port=0;  

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc == 7)  {
         if (!Shell_parse_uint_32(argv[1], &priority  )) {
            printf("Error, invalid rule priority\n");
            return_code = SHELL_EXIT_ERROR;
         } else if (!Shell_parse_uint_16(argv[3], &start_port  )) {
            printf("Error, invalid start port\n");
            return_code = SHELL_EXIT_ERROR;
         } else if (!Shell_parse_uint_16(argv[4], &end_port  )) {
            printf("Error, invalid end port\n");
            return_code = SHELL_EXIT_ERROR;
         } else if (! Shell_parse_ip_address( argv[5], &target_ip  ))  {
            printf("Error, invalid ip address\n");
            return_code = SHELL_EXIT_ERROR;
         } else if (!Shell_parse_uint_16(argv[6], &target_port  )) {
            printf("Error, invalid target port\n");
            return_code = SHELL_EXIT_ERROR;
         } else {
            if (strcmp(argv[2],"TCP")==0) {
               protocol = IPPROTO_TCP;
            } else if (strcmp(argv[2],"UDP")==0) {
               protocol = IPPROTO_UDP;
            } else {
               printf("Error, invalid protocol\n");
               return_code = SHELL_EXIT_ERROR;
            }
         }
         if (return_code == SHELL_EXIT_SUCCESS) {
            printf("Adding rule:\n");
            printf("%d: %s (%d-%d) -> %03d.%03d.%03d.%03d:%d",
               priority, protocol==IPPROTO_TCP?"TCP":"UDP",start_port,end_port, 
               IPBYTES(target_ip), target_port);

            error = DNAT_add_rule(priority, protocol, start_port, end_port, target_ip, target_port );
            if (error != RTCS_OK) {
               printf("   Error: %s\n",NAT_err_str(error));
               return_code = SHELL_EXIT_ERROR;
            } else {
               printf("   OK\n");
            }
         }
      } else {
         print_usage = TRUE;
         return_code = SHELL_EXIT_ERROR;
      }
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <priority> TCP|UDP <start_port> <end_port> <target_ip> <target_port>\n", argv[0]);
      } else  {
         printf("Usage: %s <priority> TCP|UDP <start_port> <end_port> <target_ip> <target_port>\n",argv[0]);
      }
   }
   return return_code;
} /* Endbody */






/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_dnat
*  Returned Value:  none
*  Comments  :  SHELL utility to add a DNAT rule
*END*-----------------------------------------------------------------*/

int_32  Shell_dnat_delet_rule(int_32 argc, char_ptr argv[] )
{
   uint_32              error;
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;
   uint_32              priority=0;     
   uint_16              protocol=0;
   uint_16              start_port=0;   
   uint_16              end_port=0;     
   _ip_address          target_ip=0;      
   uint_16              target_port=0;  

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  
   {
      if (argc == 2)  
      {
         if (!Shell_parse_uint_32(argv[1], &priority  )) 
         {
            printf("Error, invalid rule priority\n");
            return_code = SHELL_EXIT_ERROR;
         } 
         if (return_code == SHELL_EXIT_SUCCESS) 
         {
            error = DNAT_delete_rule(priority);
            
            if (error != RTCS_OK) 
            {
               printf("   Error: %s\n",NAT_err_str(error));
               return_code = SHELL_EXIT_ERROR;
            } 
            else 
            {
               printf("   OK\n");
            }
         }
      } 
      else 
      {
         print_usage = TRUE;
         return_code = SHELL_EXIT_ERROR;
      }
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <priority> TCP|UDP <start_port> <end_port> <target_ip> <target_port>\n", argv[0]);
      } else  {
         printf("Usage: %s <priority> TCP|UDP <start_port> <end_port> <target_ip> <target_port>\n",argv[0]);
      }
   }
   return return_code;
} /* Endbody */




























#endif
#endif /* SHELLCFG_USES_RTCS */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/icmp6.h<|end_filename|>
#ifndef __icmp6_h__
#define __icmp6_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: icmp6.h$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Definitions for the ICMP6 protocol layer.
*
*END************************************************************************/


/******************************************************************
* ICMPv6 message types (RFC 4443)
******************************************************************/

/* ICMPv6 error messages:*/
#define ICMP6_TYPE_DEST_UNREACH   	    1	/* Destination Unreachable. */
#define ICMP6_TYPE_PACKET_TOOBIG  	    2	/* Packet Too Big. */
#define ICMP6_TYPE_TIME_EXCEED	    	3	/* Time Exceeded. */
#define ICMP6_TYPE_PARAM_PROB		    4	/* Parameter Problem. */

/* ICMPv6 informational messages:*/
#define ICMP6_TYPE_ECHO_REQ			    128 /* Echo Request. */
#define ICMP6_TYPE_ECHO_REPLY		    129	/* Echo Reply. */

/*  Neighbor Discovery defines five different ICMP packet types (RFC4861):*/
#define ICMP6_TYPE_ROUTER_SOLICITATION		133	/* Router Solicitation. */
#define ICMP6_TYPE_ROUTER_ADVERTISEMENT		134	/* Router Advertisement. */
#define ICMP6_TYPE_NEIGHBOR_SOLICITATION	135	/* Neighbor Solicitation. */
#define ICMP6_TYPE_NEIGHBOR_ADVERTISEMENT	136	/* Neighbor Advertisement. */
#define ICMP6_TYPE_REDIRECT             	137 /* Redirect.*/

/* Destination Unreachable codes */
#define ICMP6_CODE_DU_NO_ROUTE          0   /* No route to destination. */
#define ICMP6_CODE_DU_ADMIN_PROHIBITED  1   /* Communication with destination administratively prohibited. */
#define ICMP6_CODE_DU_BEYOND_SCOPE      2   /* Beyond scope of source address.*/
#define ICMP6_CODE_DU_ADDR_UNREACH      3   /* Address unreachable.*/
#define ICMP6_CODE_DU_PORT_UNREACH      4   /* Port unreachable.*/
#define ICMP6_CODE_DU_ADDR_FAILED       5   /* Source address failed ingress/egress policy.*/
#define ICMP6_CODE_DU_REJECT_ROUTE      6   /* Reject route to destination.*/

/* Packet Too Big codes */
#define ICMP6_CODE_PTB                  0  

/* Time Exceeded codes */
#define ICMP6_CODE_TE_HOP_LIMIT         0   /* Hop limit exceeded in transit.*/
#define ICMP6_CODE_TE_FRG_REASSEMBLY    1   /* Fragment reassembly time exceeded.*/

/* Parameter Problem codes */
#define ICMP6_CODE_PP_HEADER            0   /* Erroneous header field encountered.*/
#define ICMP6_CODE_PP_NEXT_HEADER       1   /* Unrecognized Next Header type encountered.*/
#define ICMP6_CODE_PP_OPTION            2   /* Unrecognized IPv6 option encountered.*/


/******************************************************************
 * ICMP echo parameters
 ******************************************************************/
typedef struct icmp6_parm
{
    TCPIP_PARM                      COMMON;
    struct icmp6_parm               * NEXT;
    struct icmp6_parm               * * PREV;
    TCPIP_EVENT                     EXPIRE;
    in6_addr                        *ip_addr;
    uint_32                         if_scope_id;        /* Interface number. */
    uint_32                         timeout;
    uint_16                         id;
    uint_16                         seq;
    uint_8                          hop_limit;          /* Hop limit.*/ 
    pointer                         data_buffer;        /* Pointer to a data buffer (optional). */
    uint_32                         data_buffer_size;   /* Size of a buffer (optional). */
} ICMP6_PARM, _PTR_ ICMP6_PARM_PTR;

/******************************************************************
* Function Prototypes
*******************************************************************/
extern uint_32 ICMP6_init ( void );
extern void ICMP6_service (RTCSPCB_PTR, pointer);
extern void ICMP6_send_echo (ICMP6_PARM_PTR);

void ICMP6_send_error ( uint_8 type     /* [IN] the ICMPv6 type to send */,    
                        uint_8 code     /* [IN] the ICMPv6 code to send */,
                        uint_32 param   /* [IN] error parameter */,
                        RTCSPCB_PTR origpcb   /* [IN] the packet which caused the error */ );

#endif /* __icmp6_h__ */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/qrtc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: qrtc.c$
* $Version : 3.8.2.0$
* $Date    : Sep-26-2012$
*
* Comments:
*            PowerPC RTC driver functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <rtc.h>
#include <qrtc.h>
#if (BSP_TWRPXD20)
#include "MPXD20_cw.h"
#endif

static RTC_TIME_STRUCT real_time = {0};
static RTC_TIME_STRUCT alarm_time = {0};
static uint_32 stopwatch = 0;
static uint_32 user_enables = 0;
static uint_32 user_requests = 0;

void _rtc_time_to_mqx_time (RTC_TIME_STRUCT_PTR rtc_time, TIME_STRUCT_PTR mqx_time);
void _rtc_time_from_mqx_time (TIME_STRUCT_PTR mqx_time, RTC_TIME_STRUCT_PTR rtc_time);
_mqx_int _rtc_sync_with_mqx (boolean update_mqx);
void _api_isr (pointer ptr);

INT_ISR_FPTR user_isr = (INT_ISR_FPTR)NULL;

uint_32  _rtc_init (uint_32 flags) {
    uint_32 result = MQX_OK;
    VQRTC_REG_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    rtc->RTCC = 0x00;
    /* clear all interrupt flags*/
    rtc->RTCS |= (QRTC_RTCS_RTCF | QRTC_RTCS_ROVRF | QRTC_RTCS_APIF);
    /* disable module */
    rtc->RTCC &= ~QRTC_RTCC_CNTEN;
    
#if (!BSP_TWRPXN20)
    rtc->RTCSUPV = 0;
#endif
    
    
    /* select clock */
    rtc->RTCC &= ~QRTC_RTCC_CLKSEL(0x11);
    rtc->RTCC |= QRTC_RTCC_CLKSEL(0x01);

    /* clear time, alarm and stopwatch, if requested */
    if (flags & RTC_INIT_FLAG_CLEAR) {      
        real_time.seconds = 0;
        real_time.minutes = 0;
        real_time.hours = 0;
        real_time.days = 0;
        alarm_time.seconds = 0;
        alarm_time.minutes = 0;
        alarm_time.hours = 0;
        alarm_time.days = 0;
        stopwatch = 0;
    }

    /* reset current user interrupt state and callback, if requested */
    if (flags & RTC_INIT_FLAG_RESET) {
        user_requests = 0;
        user_enables = 0;
        user_isr = (INT_ISR_FPTR)NULL;
        stopwatch = (uint_32)(-1);
    }
    /* install HW interrupt and run the RTC, if requested */
    if (flags & RTC_INIT_FLAG_ENABLE) {
        if (flags & RTC_INIT_API_ENABLE) {
            if (NULL == _int_install_isr (_bsp_get_api_vector (),  _api_isr, (pointer)rtc)) result = _task_get_error ();
            if (MQX_OK == result) {
                _bsp_int_init(_bsp_get_api_vector (), BSP_API_INT_LEVEL, 0, TRUE);
                /* API Compare Value */
                rtc->RTCC &= ~QRTC_RTCC_APIVAL(0x3ff);
                rtc->RTCC |= QRTC_RTCC_APIVAL(API_VALUE);
                rtc->RTCC |= QRTC_RTCC_APIEN;
                /* Divide by 32 */
                rtc->RTCC |= QRTC_RTCC_DIV32EN;
                /* enable interrupt */
                rtc->RTCC |= QRTC_RTCC_APIIE;
            }
        }
        else {
            if (NULL == _int_install_isr (_bsp_get_rtc_vector (),  _rtc_isr, (pointer)rtc)) result = _task_get_error ();
            if (MQX_OK == result) {
                _bsp_int_init(_bsp_get_rtc_vector (), BSP_RTC_INT_LEVEL, 0, TRUE);
#if (!BSP_TWRPXN20)
                CGM.SIRC_CTL.B.LPRCDIV = 0;
#endif
                /* RTC Compare Value */
                rtc->RTCC &= ~QRTC_RTCC_CNTEN;
                rtc->RTCC &= ~QRTC_RTCC_RTCVAL(0xfff);
                rtc->RTCC |= QRTC_RTCC_RTCVAL(RTC_VALUE);
                rtc->RTCS |= QRTC_RTCS_RTCF;
            }
        }
        /* enable interrupt */
        rtc->RTCC |= QRTC_RTCC_RTCIE;
    }
    /* Counter does not freeze in debug mode */
    rtc->RTCC |= QRTC_RTCC_FRZEN;
    /* enable module */
    rtc->RTCC |= QRTC_RTCC_CNTEN;
    return result;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_isr
* Returned Value   : none
* Comments         :
*    This is ISR for RTC module, triggered each second.
*
*END*********************************************************************/
void _rtc_isr 
(
    /* [IN] rtc module pointer passed to interrupt */
    pointer ptr
)
{
    VQRTC_REG_STRUCT_PTR rtc = (VQRTC_REG_STRUCT_PTR)ptr;
    /* clear compare interrupt of RTC module & reset counter*/
    rtc->RTCC &= ~QRTC_RTCC_CNTEN;
    rtc->RTCS |= QRTC_RTCS_RTCF;
    rtc->RTCC |= QRTC_RTCC_CNTEN;
    user_requests |= QRTC_RTCISR_1HZ;   /* second boundary */
    real_time.seconds++;
    if (real_time.seconds > 59)         /* minute boundary */
    {
        real_time.seconds = 0;
        user_requests |= QRTC_RTCISR_MIN;
        if (stopwatch != (uint_32)-1) {   /* stopwatch decrementer */
            stopwatch--;
            if (stopwatch == (uint_32)-1) {
                user_requests |= QRTC_RTCISR_SW;
            }
        }          
        real_time.minutes++;
        if (real_time.minutes > 59)    /* hour boundary */
        {
            real_time.minutes = 0;
            user_requests |= QRTC_RTCISR_HR;
            real_time.hours++;
            if (real_time.hours > 23)    /* days boundary */
            {
                real_time.hours = 0;
                user_requests |= QRTC_RTCISR_DAY;
                real_time.days++;
            }    
        }    
    }
    /* alarm checking */
    if ((real_time.seconds == alarm_time.seconds) && (real_time.minutes == alarm_time.minutes) && (real_time.hours == alarm_time.hours) && (real_time.days == alarm_time.days)) {
        user_requests |= QRTC_RTCISR_ALM;
    }
    /* user callback triggering */
    if (((INT_ISR_FPTR)NULL != user_isr) && (user_requests & user_enables)) user_isr ((pointer)rtc);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _api_isr
* Returned Value   : none
* Comments         :
*    This is ISR for API mode, triggered each second.
*
*END*********************************************************************/
void _api_isr 
(
    /* [IN] rtc module pointer passed to interrupt */
    pointer ptr
)
{
    VQRTC_REG_STRUCT_PTR rtc = (VQRTC_REG_STRUCT_PTR)ptr;
    /* clear compare interrupt of RTC module */
    rtc->RTCS |= QRTC_RTCS_APIF;
    user_requests |= QRTC_RTCISR_1HZ;   /* second boundary */
    real_time.seconds++;
    if (real_time.seconds > 59)         /* minute boundary */
    {
        real_time.seconds = 0;
        user_requests |= QRTC_RTCISR_MIN;
        if (stopwatch != (uint_32)-1) {   /* stopwatch decrementer */
            stopwatch--;
            if (stopwatch == (uint_32)-1) {
                user_requests |= QRTC_RTCISR_SW;
            }
        }          
        real_time.minutes++;
        if (real_time.minutes > 59)    /* hour boundary */
        {
            real_time.minutes = 0;
            user_requests |= QRTC_RTCISR_HR;
            real_time.hours++;
            if (real_time.hours > 23)    /* days boundary */
            {
                real_time.hours = 0;
                user_requests |= QRTC_RTCISR_DAY;
                real_time.days++;
            }    
        }    
    }
    /* alarm checking */
    if ((real_time.seconds == alarm_time.seconds) && (real_time.minutes == alarm_time.minutes) && (real_time.hours == alarm_time.hours) && (real_time.days == alarm_time.days)) {
        user_requests |= QRTC_RTCISR_ALM;
    }
    /* user callback triggering */
    if (((INT_ISR_FPTR)NULL != user_isr) && (user_requests & user_enables)) user_isr ((pointer)rtc);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_int_install
* Returned Value   : MQX error code
* Comments         :
*    This function installs given user callback for RTC module.
*
*END*********************************************************************/
uint_32 _rtc_int_install 
(
    /* [IN] pointer to user ISR code */
    INT_ISR_FPTR isr
)
{
    user_isr = isr;
    return MQX_OK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_int_enable
* Returned Value   : bitmask of new int enable state
* Comments         :
*    This function enables/disables RTC interrupts according to specified bitmask.
*
*END*********************************************************************/
uint_32 _rtc_int_enable 
(
    /* [IN] whether to enable or disable interrupts */
    boolean enable, 
    /* [IN] bitmask of affected interrupts */
    uint_32 bitmask
)
{
    if (enable){
        user_enables |= bitmask;
    } else {
        user_enables &= (~ bitmask);
    }
    return user_enables;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_clear_requests
* Returned Value   : none
* Comments         :
*    This function clears RTC interrupt requests according to given bitmask.
*
*END*********************************************************************/
void _rtc_clear_requests 
(
    /* [IN] bitmask of affected interrupts */
    uint_32 bitmask
)
{
    user_requests &= (~ bitmask);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_status
* Returned Value   : bitmask of actual RTC interrupt requests + RTC enabled bit
* Comments         :
*    This function returns bitmask of pending RTC interrupt requests along
*    with RTC enabled bit (bit QRTC_RTCISR_EN).
*
*END*********************************************************************/
uint_32 _rtc_get_status 
(
    void
)
{
    VQRTC_REG_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    uint_32 result = user_requests;
    if (rtc->RTCC & QRTC_RTCC_RTCIE) result |= QRTC_RTCISR_EN;
    return result;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_set_time
* Returned Value   : none
* Comments         :
*    This function sets the RTC time according to given time struct.
*
*END*********************************************************************/
void _rtc_set_time 
(
    /* [IN] given time to be set as RTC time */
    RTC_TIME_STRUCT_PTR time
)
{
    VQRTC_REG_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    uint_32 tmp = rtc->RTCC & QRTC_RTCC_RTCIE;   
    rtc->RTCC &= ~(QRTC_RTCC_RTCIE);             
    real_time = *time;                                    
    if (real_time.seconds > 59) real_time.seconds = 59;   
    if (real_time.minutes > 59) real_time.minutes = 59;
    if (real_time.hours > 23) real_time.hours = 23;
    rtc->RTCS |= QRTC_RTCS_RTCF;                 
    rtc->RTCC |= tmp;                                    

}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_time
* Returned Value   : none
* Comments         :
*    This function gets the RTC time and stores it in given time struct.
*
*END*********************************************************************/
void _rtc_get_time 
(
    /* [OUT] this parameter gets actual RTC time */
    RTC_TIME_STRUCT_PTR time
)
{
    RTC_TIME_STRUCT tmp;  
    time->hours = 0xFF;
    do   // loop until same time is read twice - keeping time integrity
    {
        tmp = *time;
        *time = real_time;
    } while ((tmp.seconds != time->seconds) || (tmp.minutes != time->minutes) || (tmp.hours != time->hours) || (tmp.days != time->days));
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_set_alarm
* Returned Value   : none
* Comments         :
*    This function sets RTC alarm time according to given time struct.
*    Alarm happens immediately after match.
*
*END*********************************************************************/
void _rtc_set_alarm 
(
    /* [IN] time to be set as RTC alarm time */
    RTC_TIME_STRUCT_PTR time
)
{
    uint_32 enables = user_enables & QRTC_RTCIENR_ALM;
    user_enables &= (~ QRTC_RTCIENR_ALM);
    alarm_time = *time;
    if (alarm_time.seconds > 59) alarm_time.seconds = 59;
    if (alarm_time.minutes > 59) alarm_time.minutes = 59;
    if (alarm_time.hours > 23) alarm_time.hours = 23;
    user_requests &= (~ QRTC_RTCISR_ALM);
    user_enables |= enables;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_alarm
* Returned Value   : none
* Comments         :
*    This function gets the RTC alarm time and stores it in given time struct.
*
*END*********************************************************************/
void _rtc_get_alarm 
(
    /* [OUT] this parameter gets the RTC alarm time */
    RTC_TIME_STRUCT_PTR time
)
{
    *time = alarm_time;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_set_stopwatch
* Returned Value   : none
* Comments         :
*    This function sets the RTC stopwatch decrementer value (minutes).
*    Stopwatch decrements each new RTC minute and stops (disables) at -1.
*
*END*********************************************************************/
void _rtc_set_stopwatch 
(
    /* [IN] number of minutes to countdown */
    uint_32 minutes
)
{
    uint_32 enables = user_enables & QRTC_RTCIENR_SW;
    user_enables &= (~ QRTC_RTCIENR_SW);
    stopwatch = QRTC_STPWCH_CNT(minutes);
    user_requests &= (~ QRTC_RTCISR_SW);
    user_enables |= enables;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_stopwatch
* Returned Value   : actual RTC minute stopwatch counter value
* Comments         :
*    This function returns the actual value of RTC stopwatch decrementer.
*
*END*********************************************************************/
uint_32 _rtc_get_stopwatch 
(
    void
)
{
    return stopwatch;
}
/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_time_to_mqx_time
* Returned Value   : none
* Comments         :
*    This function transforms RTC time format to MQX time format.
*    RTC time range is wider (65536 days vs. 49710 days), overflow is not checked,
*    miliseconds are set to 0.
*
*END*********************************************************************/
void _rtc_time_to_mqx_time 
(
    /* [IN] RTC time representation */
    RTC_TIME_STRUCT_PTR rtc_time, 
    /* [OUT] MQX time representation */
    TIME_STRUCT_PTR mqx_time
)
{
    mqx_time->MILLISECONDS = 0;
    mqx_time->SECONDS = rtc_time->seconds + (rtc_time->minutes * 60L) + (rtc_time->hours * 3600L) + (rtc_time->days * 86400L);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_time_from_mqx_time
* Returned Value   : none
* Comments         :
*    This function transforms MQX time format to RTC time format.
*    MQX time range is shorter (49710 days vs. 65536 days), miliseconds are ignored.
*
*END*********************************************************************/

void _rtc_time_from_mqx_time
(
    /* [IN] MQX time representation */
    TIME_STRUCT_PTR mqx_time, 
    /* [OUT] RTC time representation */
    RTC_TIME_STRUCT_PTR rtc_time
)
{
    register uint_32 div, mod;
    
    mod  = mqx_time->SECONDS;
    div  = mod / 86400;
    mod -= div * 86400;
    rtc_time->days = (uint_16)div;
    div  = mod / 3600;
    mod -= div * 3600;
    rtc_time->hours = (uint_8)div;
    div  = mod / 60;
    mod -= div * 60;
    rtc_time->minutes = (uint_8)div;
    rtc_time->seconds = (uint_8)mod;
}


/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_sync_with_mqx
* Returned Value   : none
* Comments         :
*    This function synchronizes RTC time with MQX time.
*
*END*********************************************************************/
_mqx_int _rtc_sync_with_mqx 
(
    /* [IN] whether to update MQX time (source is RTC) or RTC time (source is MQX) */
    boolean update_mqx
)
{
    RTC_TIME_STRUCT rtc_time;
    TIME_STRUCT mqx_time;
    
    if (update_mqx) 
    {
        _rtc_get_time (&rtc_time);
        _rtc_time_to_mqx_time (&rtc_time, &mqx_time);
        _time_set (&mqx_time);
    }
    else
    {
        _time_get (&mqx_time);
        _rtc_time_from_mqx_time (&mqx_time, &rtc_time);
        _rtc_set_time (&rtc_time);
    }
    return MQX_OK;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/adc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc.c$
* $Version : 3.8.36.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the generic ADC driver functions
*
*END************************************************************************/
#include "mqx.h"
#include "bsp.h"
#include "fio.h"
#include "fio_prv.h"
#include <string.h>
#include "io.h"
#include "adc_conf.h"
#include "adc.h"
#include "adc_prv.h"

#ifndef ADC_MAX_CHANNELS
    #define ADC_MAX_CHANNELS ADC_MAX_SW_CHANNELS
#endif

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a adc driver.
*
*END*********************************************************************/
_mqx_uint _io_adc_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr  identifier,
      /* pointer to a HW specific structure */
      pointer   init
   ) 
   
{ /* Body */
   ADC_DRIVER_BUNDLE_PTR adc_driver_bundle;
   _mqx_uint result;

   if (NULL == (adc_driver_bundle = (ADC_DRIVER_BUNDLE_PTR) _mem_alloc(sizeof(ADC_DRIVER_BUNDLE))))
      return ADC_ERROR_ALLOC; /* memory allocation error */

   _mem_zero(adc_driver_bundle, sizeof(ADC_DRIVER_BUNDLE));

   if (IO_OK == (result = _adc_hw_install(identifier, adc_driver_bundle, init)))
      if (IO_OK == (result = _adt_hw_install(identifier, adc_driver_bundle, init)))
         result = _io_dev_install(identifier,
            _adc_open,
            _adc_close,
            _adc_read,
            _adc_write,
            _adc_ioctl,
            adc_driver_bundle);

   if (result != IO_OK)
      _mem_free(adc_driver_bundle); 

   return result;
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_open
* Returned Value   : _mqx_int - ADC_ERROR_* or ADC_OK
* Comments         : Opens and initializes ADC driver.
* 
*END*********************************************************************/
_mqx_int _adc_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR fd_ptr,
       
      /* [IN] the remaining portion of the name of the device */
      char_ptr   open_name_ptr,

      /* [IN] the initialization parameters (ADC_INIT_STRUCT_PTR) */
      char_ptr   flags
   )
{ /* Body */
   ADC_DRIVER_BUNDLE_PTR       adc_driver_bundle = (ADC_DRIVER_BUNDLE_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
   char_ptr                    file_name_ptr = fd_ptr->DEV_PTR->IDENTIFIER; /* use driver name temporarily */
   _mqx_int                    status;

   while (*file_name_ptr++ != 0)
      open_name_ptr++; /* move to the file name */
   file_name_ptr = open_name_ptr; /* throw out file_name_ptr and assign the correct file name */

   if (*file_name_ptr == 0) {
      /* 
      ** ADC DEVICE DRIVER OPENED WITHOUT CHANNEL SPECIFIED
      */                                         
      ADC_INIT_STRUCT_PTR  adc_init = (ADC_INIT_STRUCT_PTR) flags;

      if (adc_init == NULL)
         return ADC_ERROR_PARAM; /* mandatory open parameter missing */

      if (NULL == adc_driver_bundle->adc) {
         adc_driver_bundle->adc = (ADC_PTR) _mem_alloc_zero(sizeof(ADC));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
         if (adc_driver_bundle->adc == NULL)
            return ADC_ERROR_ALLOC; /* memory allocation error */
#endif
         adc_driver_bundle->adt = (ADT_PTR) _mem_alloc_zero(sizeof(ADT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
         if (adc_driver_bundle->adt == NULL) {
            _mem_free(adc_driver_bundle->adt);
            return ADC_ERROR_ALLOC; /* memory allocation error */
         }
#endif
      } else
         return ADC_ERROR_OPENED; /* cannot open more than one instance of ADC driver */
      
      adc_driver_bundle->adc->g.resolution = adc_init->resolution;
      adc_driver_bundle->adt->g.run = 0;

      if (IO_OK != (status = _adc_hw_init(fd_ptr, adc_driver_bundle->adc))) { /* init cpu according to adc_general_config */
         _mem_free(adc_driver_bundle->adc);
         _mem_free(adc_driver_bundle->adt);
         adc_driver_bundle->adc = NULL;
         adc_driver_bundle->adt = NULL;
      }
      else if (IO_OK != (status = _adt_hw_init(fd_ptr, adc_driver_bundle->adt))) { /* init cpu according to adt_general_config */
         _mem_free(adc_driver_bundle->adc);
         _mem_free(adc_driver_bundle->adt);
         adc_driver_bundle->adc = NULL;
         adc_driver_bundle->adt = NULL;
      }
      
      //fd_ptr->DEV_DATA_PTR = NULL; /* not needed: we dont need to store any additional data */

      return status;
   }
   else {
      /*
      ** CHANNEL TO BE OPENED, FILENAME IS IN OPEN_NAME_PTR
      */
      ADC_INIT_CHANNEL_STRUCT_PTR ch_init = (ADC_INIT_CHANNEL_STRUCT_PTR) flags;
      ADC_CHANNEL_BUNDLE_PTR      adc_channel_bundle;
      ADC_CHANNEL_PTR             *adc_ch;
      ADT_CHANNEL_PTR             *adt_ch;
      _mqx_uint                   ch = 0, i;
    
      adc_ch = adc_driver_bundle->adc_ch;
      adt_ch = adc_driver_bundle->adt_ch;
      
      if (ch_init == NULL)
         return ADC_ERROR_PARAM; /* mandatory open parameter missing */

      if (NULL == adc_driver_bundle->adc)
         return ADC_ERROR_MISSING_DEVICE; /* general device was not opened */

      if (ch_init->number_samples < 1)
         return ADC_ERROR_BAD_PARAM; /* number of samples must be more than 0 */

//      open_name_ptr = file_name_ptr; // not needed, already done

#if ADC_STORE_FILENAMES
      for (ch = 0; ch < ADC_MAX_CHANNELS; ch++)
         if (!strcmp((const char *) adc_driver_bundle->adc_name[ch], open_name_ptr))
            return ADC_ERROR_OPENED; /* file with such name already opened */
#endif
      for (ch = 0; (ch < ADC_MAX_CHANNELS) && (adc_driver_bundle->adc_name[ch] != NULL); ch++)
      { /* searching for free channel in the bundle */
      }
      
      if (ch == ADC_MAX_CHANNELS)
         return ADC_ERROR_FULL; /* no free channel */

      /* variable 'ch' now contains valid channel number */
      adc_channel_bundle = (ADC_CHANNEL_BUNDLE_PTR) _mem_alloc_zero(sizeof(ADC_CHANNEL_BUNDLE));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (adc_channel_bundle == NULL) {
         status = ADC_ERROR_ALLOC; /* memory allocation error */
         goto error_channel_0;
      }
#endif

      if (adc_ch[ch] == NULL) {
         adc_ch[ch] = (ADC_CHANNEL_PTR) _mem_alloc_zero(sizeof(ADC_CHANNEL));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
         if (adc_ch[ch] == NULL) {
            status = ADC_ERROR_ALLOC; /* memory allocation error */
            goto error_channel_1;
         }
#endif
         adt_ch[ch] = (ADT_CHANNEL_PTR) _mem_alloc_zero(sizeof(ADT_CHANNEL));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
         if (adt_ch[ch] == NULL) {
            status = ADC_ERROR_ALLOC; /* memory allocation error */
            goto error_channel_2;
         }
#endif
      } else
         return IO_ERROR; /* channel already in use */

      adc_channel_bundle->adc_ch = adc_ch[ch];
      adc_channel_bundle->adt_ch = adt_ch[ch];
      /* store file context for opened channel */
      fd_ptr->DEV_DATA_PTR = adc_channel_bundle; /* store information about channel */

      /* allocate channel buffer */
      adc_ch[ch]->g.buffer_start = _mem_alloc_zero((ch_init->buffer_size + 1) * sizeof(ADC_RESULT_STRUCT)); /* zero is needed for ADC_CHANNEL_ACCUMULATE */
      adc_ch[ch]->g.buffer_end = adc_ch[ch]->g.buffer_start + (ch_init->buffer_size + 1);

      if (adc_ch[ch]->g.buffer_start == NULL) {
         status = ADC_ERROR_ALLOC; /* memory allocation error */
         goto error_channel_3;
      }

      // initialize channel
      adc_ch[ch]->g.buffer_task = adc_ch[ch]->g.buffer_start;
      adc_ch[ch]->g.buffer_driver = adc_ch[ch]->g.buffer_start;

      adc_ch[ch]->g.number = ch;
      adc_ch[ch]->g.init_flags = ch_init->flags;
      adc_ch[ch]->g.source = ch_init->source;

      adt_ch[ch]->g.trigger = ch_init->trigger;
      adt_ch[ch]->g.offset = ch_init->time_offset;
      adt_ch[ch]->g.period = ch_init->time_period;
      
      adt_ch[ch]->g.number = ch;
      adt_ch[ch]->g.init_flags = ch_init->flags;
      adt_ch[ch]->g.samples_preset = ch_init->number_samples - 1;
      adt_ch[ch]->g.samples = adt_ch[ch]->g.samples_preset;

#if MQX_USE_LWEVENTS
      adt_ch[ch]->g.complete_event = ch_init->complete_event;
      if (ch_init->event_mask == 0)
         adt_ch[ch]->g.event_mask = 0x01;
      else
         adt_ch[ch]->g.event_mask = ch_init->event_mask;
#endif

      if (IO_OK != (status = _adc_hw_channel_init(fd_ptr, adc_ch[ch]))) /* this should initialize ADC converter hardware */
         goto error_channel_4;

      if (IO_OK != (status = _adt_hw_channel_init(fd_ptr, adt_ch[ch]))) /* this should initialize ADC timer hardware */
         goto error_channel_5;

#if ADC_STORE_FILENAMES
      /* allocate filename buffer */
      if (NULL == (adc_driver_bundle->adc_name[ch] = _mem_alloc_zero(strlen(open_name_ptr) + 1))) /* +1 for zero-ending char */
         goto error_channel_6;
      for (i = 0; open_name_ptr[i] != 0; i++)
         adc_driver_bundle->adc_name[ch][i] = open_name_ptr[i];
      adc_driver_bundle->adc_name[ch][i] = 0;
#else
      adc_driver_bundle->adc_name[ch] = (pointer) 0xFFFFFFFF; /* channel is used */
#endif
      
      /* if ADC_CHANNEL_START_NOW was defined, then start channel */
      if (!(ch_init->flags & ADC_CHANNEL_START_TRIGGERED))
         return _adc_ioctl(fd_ptr, ADC_IOCTL_RUN_CHANNEL, NULL);
      
      return IO_OK;     
      
error_channel_6:
      _adt_hw_channel_deinit(fd_ptr, adt_ch[ch]);
error_channel_5:
      _adc_hw_channel_deinit(fd_ptr, adc_ch[ch]);
error_channel_4:
      _mem_free(adc_ch[ch]->g.buffer_start);
error_channel_3:
      _mem_free(adt_ch[ch]);
      adt_ch[ch] = NULL;
error_channel_2:
      _mem_free(adc_ch[ch]);
      adc_ch[ch] = NULL;
error_channel_1:
      _mem_free(adc_channel_bundle);
error_channel_0:
      return status;
   }


} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_close
* Returned Value   : ERROR CODE
* Comments         : Closes ADC driver or channel
* 
*END*********************************************************************/
_mqx_int _adc_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR f
   )
{ /* Body */
   ADC_DRIVER_BUNDLE_PTR adc_driver_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
   ADC_CHANNEL_BUNDLE_PTR adc_channel_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
   ADC_CHANNEL_PTR *adc_ch = adc_driver_bundle->adc_ch;
   ADT_CHANNEL_PTR *adt_ch = adc_driver_bundle->adt_ch;
   _mqx_int        i, status;

   if (adc_channel_bundle == NULL) { /* we close ADC */
      /* let's check if there is no opened channel */
      for (i = 0; i < ADC_MAX_CHANNELS; i++)
         if (adc_ch[i] != NULL)
            return ADC_ERROR_NONEMPTY; /* cannot close ADC driver: there are still open channels */
      if (IO_OK != (status = _adt_hw_deinit(f, adc_driver_bundle->adt)))
         return status;
      if (IO_OK != (status = _adc_hw_deinit(f, adc_driver_bundle->adc)))
         return status;
      _mem_free(adc_driver_bundle->adt);
      adc_driver_bundle->adt = NULL; /* Needed for succesfull re-open */
      _mem_free(adc_driver_bundle->adc);
      adc_driver_bundle->adc = NULL; /* Needed for succesfull re-open */
   }
   else { /* we close ADC channel */
      i = adc_channel_bundle->adc_ch->g.number; /* get item number of channel in the array */
      _adt_stop(f, &adc_channel_bundle->adt_ch->g, 0);
      if (IO_OK != (status = _adt_hw_channel_deinit(f, adc_channel_bundle->adt_ch)))
         return status;
      if (IO_OK != (status = _adc_hw_channel_deinit(f, adc_channel_bundle->adc_ch)))
         return status;
#if ADC_STORE_FILENAMES
      _mem_free(adc_driver_bundle->adc_name[i]);
#endif
      adc_driver_bundle->adc_name[i] = NULL;
      _mem_free(adc_channel_bundle->adc_ch->g.buffer_start);
      _mem_free(adc_channel_bundle->adc_ch);
      _mem_free(adc_channel_bundle->adt_ch);
      _mem_free(adc_channel_bundle);
      adc_ch[i] = NULL;
      adt_ch[i] = NULL;
   }

   return IO_OK;
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_read
* Returned Value   : number of characters read
* Comments         : Reads data from ADC driver
* 
*END*********************************************************************/
_mqx_int _adc_read
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR f,

      /* [IN] where the characters are to be stored */
      char_ptr   data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int   num
   )
{ /* Body */
    _mqx_int cp_cnt;
    ADC_RESULT_STRUCT _PTR_ dst = (ADC_RESULT_STRUCT _PTR_) data_ptr;
    ADC_CHANNEL_BUNDLE_PTR adc_channel_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
    ADC_CHANNEL_GENERIC_PTR ch_conf = &adc_channel_bundle->adc_ch->g;
    
    if (ch_conf->buffer_task == NULL)
        return 0; /* channel not run yet */

    cp_cnt = (ch_conf->buffer_driver - ch_conf->buffer_task);
    if (cp_cnt < 0)
        cp_cnt += (ch_conf->buffer_end - ch_conf->buffer_start);
    
    if (cp_cnt > (num / sizeof(ADC_RESULT_STRUCT)))
        cp_cnt = (num / sizeof(ADC_RESULT_STRUCT));

    while (cp_cnt) {
        *dst = *ch_conf->buffer_task;
        dst++;
        ch_conf->buffer_task->result = 0; /* zero buffer to be usable next time (applicable for ADC_CHANNEL_ACCUMULATE) */
        if (++ch_conf->buffer_task >= ch_conf->buffer_end)
            ch_conf->buffer_task = ch_conf->buffer_start;

        cp_cnt--;
    }
    
    return (char_ptr)dst - data_ptr;
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_write
* Returned Value   : number of characters written
* Comments         : Does nothing, ADC is solely read-only driver
* 
*END*********************************************************************/
_mqx_int _adc_write
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR f,

      /* [IN] where the characters are */
      char_ptr   data_ptr,

      /* [IN] the number of characters to output */
      _mqx_int   num
   )
{ /* Body */
   return 0;
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/
_mqx_int _adc_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR f,

      /* [IN] the ioctl command */
      _mqx_uint  cmd,

      /* [IN] the ioctl parameters */
      pointer    param_ptr
   )
{ /* Body */
//    ADC_DRIVER_BUNDLE_PTR adc_driver_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;
    ADC_CHANNEL_BUNDLE_PTR adc_channel_bundle = (ADC_CHANNEL_BUNDLE_PTR) f->DEV_DATA_PTR;
//    ADC_CHANNEL_PTR *adc_ch = adc_driver_bundle->adc_ch;
//    ADT_CHANNEL_PTR *adt_ch = adc_driver_bundle->adt_ch;
    uint_32_ptr               uparam_ptr = param_ptr;
    _mqx_int                  status1, status2;

    switch (cmd) 
    {
        case ADC_IOCTL_RUN_CHANNEL:
            /* Runs specific channel */
            return _adt_trigger(f, &adc_channel_bundle->adt_ch->g, 0);
        case ADC_IOCTL_FIRE_TRIGGER:
            /* Runs channels associated with trigger mask */
            return _adt_trigger(f, NULL, (ADT_TRIGGER_MASK) param_ptr);
        case ADC_IOCTL_STOP_CHANNEL:
            /* Stops specific channel */
            return _adt_stop(f, &adc_channel_bundle->adt_ch->g, 0);
        case ADC_IOCTL_STOP_CHANNELS:
            /* Stops channels associated with trigger mask */
            return _adt_stop(f, NULL, (ADT_TRIGGER_MASK) param_ptr);
        case ADC_IOCTL_PAUSE_CHANNEL:
            /* Stops specific channel */
            return _adt_pause(f, &adc_channel_bundle->adt_ch->g, 0);
        case ADC_IOCTL_PAUSE_CHANNELS:
            /* Stops channels associated with trigger mask */
            return _adt_pause(f, NULL, (ADT_TRIGGER_MASK) param_ptr);
        case ADC_IOCTL_RESUME_CHANNEL:
            /* Resumes specific channel */
            return _adt_resume(f, &adc_channel_bundle->adt_ch->g, 0);
        case ADC_IOCTL_RESUME_CHANNELS:
            /* Resumes channels associated with trigger mask */
            return _adt_resume(f, NULL, (ADT_TRIGGER_MASK)param_ptr);
        case IO_IOCTL_DEVICE_IDENTIFY:  
            /* return the device identify */
            uparam_ptr[0] = IO_DEV_TYPE_PHYS_ADC;
            uparam_ptr[1] = 0;
            uparam_ptr[2] = IO_DEV_ATTR_READ;
            return IO_OK;

        default:
            /* hardware specific ioctl commands */
            status1 = _adc_hw_ioctl(f, cmd, param_ptr);
            if ((status1 == IO_OK) || (status1 == IO_ERROR_INVALID_IOCTL_CMD)) {
                status2 = _adt_hw_ioctl(f, cmd, param_ptr);
                if (status2 == IO_ERROR_INVALID_IOCTL_CMD)
                    return status1;
                return status2;
            }
            else
                return status1;
    }
} /* Endbody */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ipcfg.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcfg.c$
* $Version : 3.8.36.0$
* $Date    : Sep-19-2012$
*
* Comments:
*
*   High level IP config functions and task.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <enet.h>
#include <rtcs.h>
#include <dns.h> 
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "ipcfg.h"
#include "ipcfg_prv.h"

#ifdef BSP_ENET_DEVICE_COUNT
#if  (BSP_ENET_DEVICE_COUNT > 0) 


#if (RTCSCFG_IPCFG_ENABLE_DHCP || RTCSCFG_IPCFG_ENABLE_BOOT) && (! RTCSCFG_ENABLE_UDP)
#error "Please set RTCSCFG_ENABLE_UDP to 1 to enable DHCP or BOOT and recompile RTCS again!"
#endif


/* hidden global data */
static uchar            ipcfg_empty_string[]                = "";
static const char       ipcfg_task_name[]                   = IPCFG_TASK_NAME;
static boolean          ipcfg_task_run                      = FALSE;
IPCFG_CONTEXT    ipcfg_data[IPCFG_DEVICE_COUNT]  = {0};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ipcfg_get_device_number()
* Returned Value  : device number or -1
* Comments        : Returns corresponding device number for given interface.
*
*END*-----------------------------------------------------------------*/

uint_32 ipcfg_get_device_number
    (
        _rtcs_if_handle ihandle
    )
{
    _mqx_int i;
   
    for (i = 0; i < IPCFG_DEVICE_COUNT; i++) {
        if (ipcfg_data[i].ihandle == ihandle)
            break;
    }
   
    return (i < IPCFG_DEVICE_COUNT) ? i : -1;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ipcfg_add_interface()
* Returned Value  : device number or -1
* Comments        : Add new interface and returns corresponding device number.
*
*END*-----------------------------------------------------------------*/

uint_32 ipcfg_add_interface
    (
        uint_32 dev_num,
        _rtcs_if_handle ihandle
    )
{
    _mqx_int i = IPCFG_DEVICE_COUNT;
    
    if (dev_num != (uint_32)-1) {
        if (dev_num < IPCFG_DEVICE_COUNT && ipcfg_data[dev_num].ihandle == NULL) {
            ipcfg_data[dev_num].ihandle = ihandle;
            i = dev_num;
        }
    }
    else {
        for (i = 0; i < IPCFG_DEVICE_COUNT; i++) {
            if (ipcfg_data[i].ihandle == NULL) {
                ipcfg_data[i].ihandle = ihandle;
                break;
            }
        }
    }
   
    return (i < IPCFG_DEVICE_COUNT) ? i : -1;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ipcfg_del_interface()
* Returned Value  : ipcfg error code.
* Comments        : Delete interface defined by device number.
*
*END*-----------------------------------------------------------------*/
uint_32 ipcfg_del_interface (uint_32 dev_num)
{
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ipcfg_data[dev_num].actual_state = IPCFG_STATE_INIT;
        ipcfg_data[dev_num].ihandle = NULL;
        return IPCFG_OK;
    }
    else
        return RTCSERR_IPCFG_DEVICE_NUMBER;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ipcfg_get_ihandle()
* Returned Value  : interface handle or NULL
* Comments        : Returns interface handle for given device number.
*
*END*-----------------------------------------------------------------*/

_rtcs_if_handle ipcfg_get_ihandle 
    (
        uint_32 device
    )
{
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].ihandle;
    }
    return NULL;
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ipcfg_get_mac()
* Returned Value  : TRUE and mac address if successful, FALSE otherwise
* Comments        : Returns ethernet mac address for given device number.
*
*END*-----------------------------------------------------------------*/

boolean ipcfg_get_mac 
    (
        uint_32         device,
        _enet_address   mac
    )
{
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) 
        {
            ENET_get_address (((IP_IF_PTR)(ipcfg_data[device].ihandle))->HANDLE, mac);
            return TRUE;
        }
        else
        {
            ENET_get_mac_address (device, 0, mac);
            return TRUE;
        }
    }
    return FALSE;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ipcfg_get_state_string()
* Returned Value  : state name string or NULL
* Comments        : Returns const char_ptr to name of given state.
*
*END*-----------------------------------------------------------------*/

const char * ipcfg_get_state_string (IPCFG_STATE state)
{
    static const char_ptr ipcfg_states[] = 
    {
        "INIT",         //"init",
        "UNBOUND",      //"unbound",
        "BUSY",         //"busy",
        "MANUAL",       //"staticip",
        "DHCPNOAUTO",   //"dhcpnoauto",
        "AUTOIP",       //"autoip",
        "DHCP",         //"dhcp",
        "BOOT"          //"boot"
    };

    if (state < sizeof (ipcfg_states))
    {
        return ipcfg_states[state];
    }
    return NULL;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_get_state()
* Returned Value : actual ipcfg state
* Comments       : Returns ipcfg state enum element.
*
*END--------------------------------------------------------------------*/

IPCFG_STATE ipcfg_get_state 
    (
        uint_32 device
    )
{
    IPCFG_STATE state = IPCFG_STATE_INIT;
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
        {
            if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return IPCFG_STATE_BUSY;
            state = ipcfg_data[device].actual_state;
            _lwsem_post (&(ipcfg_data[device].request_semaphore));
        }
    }
    return state;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_get_last_state()
* Returned Value : last ipcfg state
* Comments       : Returns ipcfg state enum element.
*
*END--------------------------------------------------------------------*/

IPCFG_STATE ipcfg_get_desired_state 
    (
        uint_32 device
    )
{
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].desired_state;
    }
    return IPCFG_STATE_INIT;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_get_link_active()
* Returned Value : TRUE if link active, FALSE otherwise
* Comments       : Returns actual link state.
*
*END--------------------------------------------------------------------*/

boolean ipcfg_get_link_active 
    (
        uint_32 device
    )
{
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
            return ENET_link_status (((IP_IF_PTR)(ipcfg_data[device].ihandle))->HANDLE);
    }
    return FALSE;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_phy_registers()
* Returned Value : TRUE if link active, FALSE otherwise
* Comments       : Returns actual link state.
*
*END--------------------------------------------------------------------*/

boolean ipcfg_phy_registers 
    (
        uint_32     device,
        uint_32     num_regs,
        uint_32_ptr regs_ptr
    )
{
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
            return ENET_phy_registers(((IP_IF_PTR)(ipcfg_data[device].ihandle))->HANDLE, num_regs,regs_ptr);
    }
    return FALSE;
}

/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_get_dns_ip()
* Returned Value : dns IP address
* Comments       : Returns N-th DNS ip address from DNS list for given N.
*
*END--------------------------------------------------------------------*/

_ip_address ipcfg_get_dns_ip 
    (
        uint_32 device,
        uint_32 n
    )
{
    uint_32 result = 0;

#if RTCSCFG_IPCFG_ENABLE_DNS

    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) 
        {

#if RTCSCFG_ENABLE_LWDNS

            if (n == 0) result = LWDNS_server_ipaddr;

#else

            DNS_SLIST_STRUCT _PTR_ temp_ptr;

            for (temp_ptr = DNS_First_Local_server; (temp_ptr != NULL) && (n != 0); temp_ptr = temp_ptr->NEXT) n--;
            if (temp_ptr != NULL) 
            {
                result = temp_ptr->IPADDR;
            }

#endif

        }
    }

#endif

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_add_dns_ip()
* Returned Value : TRUE if successful, FALSE otherwise
* Comments       : Adds/updates DNS ip address info inside DNS list and
*                  starts the DNS machine, if not running already.
*
*END--------------------------------------------------------------------*/

boolean ipcfg_add_dns_ip 
    (
        uint_32     device,
        _ip_address address
    )
{
    boolean result = FALSE;

#if RTCSCFG_IPCFG_ENABLE_DNS

    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) 
        {

#if RTCSCFG_ENABLE_LWDNS

            LWDNS_server_ipaddr = address;
            result = TRUE;

#else
            DNS_CONTROL_STRUCT _PTR_ control_ptr = RTCS_getcfg(DNS);
            DNS_SLIST_STRUCT slist_entry;

            if (control_ptr == NULL)
            {
                DNS_init();
            }

            DNS_init_slist_entry (&slist_entry);
            slist_entry.IPADDR = address;
            if (DNS_add_slist_entry (&slist_entry) == DNS_OK) 
            {
                result = TRUE;
            }

#endif

        }
    }

#endif

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_del_dns_ip()
* Returned Value : TRUE if successful, FALSE otherwise
* Comments       : Removes given address from DNS list, if exists.
*
*END--------------------------------------------------------------------*/

boolean ipcfg_del_dns_ip 
    (
        uint_32     device,
        _ip_address address
    )
{
    boolean result = FALSE;

#if RTCSCFG_IPCFG_ENABLE_DNS

    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) 
        {
        
#if RTCSCFG_ENABLE_LWDNS

            if (LWDNS_server_ipaddr == address) 
            {
                LWDNS_server_ipaddr = 0;
                result = TRUE;
            }
        
#else

            DNS_remove_slist_entry (address);
            result = TRUE;

#endif

        }
    }

#endif

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_get_ip()
* Returned Value : TRUE and IP, mask and gateway, if successful
* Comments       : Returns actual ip information from DHCP response, if any.
*
*END--------------------------------------------------------------------*/

boolean ipcfg_get_ip 
    (
        uint_32                     device, 
        IPCFG_IP_ADDRESS_DATA_PTR   data
    )
{
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) 
        {
            *data = ipcfg_data[device].actual_ip_data;
            return TRUE;
        }
    }
    return FALSE;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_get_tftp_serveraddress()
* Returned Value : _ip_address
* Comments       : Returns TFTP serveraddress, if any.
*
*END--------------------------------------------------------------------*/

_ip_address ipcfg_get_tftp_serveraddress 
    (
        uint_32 device
    )
{
#if RTCSCFG_IPCFG_ENABLE_BOOT
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].tftp_serveraddress;
    }
#endif
    return 0;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_get_tftp_servername()
* Returned Value : pointer to string servername
* Comments       : Returns TFTP servername, if any.
*
*END--------------------------------------------------------------------*/

uchar_ptr ipcfg_get_tftp_servername 
    (
        uint_32 device
    )
{
#if RTCSCFG_IPCFG_ENABLE_BOOT
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].tftp_servername;
    }
#endif
    return ipcfg_empty_string;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_get_boot_filename()
* Returned Value : pointer to string filename
* Comments       : Returns boot filename, if any.
*
*END--------------------------------------------------------------------*/

uchar_ptr ipcfg_get_boot_filename 
    (
        uint_32 device
    )
{
#if RTCSCFG_IPCFG_ENABLE_BOOT
    if (device < IPCFG_DEVICE_COUNT)
    {
        if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].boot_filename;
    }
#endif
    return ipcfg_empty_string;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_unbind_internal_actual()
* Returned Value : ipcfg error code
* Comments       : Actual unbind process.
*
*END--------------------------------------------------------------------*/

static uint_32 ipcfg_unbind_internal_actual
    (
        uint_32 device
    )
{
    if (ipcfg_data[device].actual_ip_data.ip != 0) 
    {
        if ((ipcfg_data[device].actual_state == IPCFG_STATE_DHCP_IP) || (ipcfg_data[device].actual_state == IPCFG_STATE_DHCPAUTO_IP)) 
        {
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
            DHCPCLNT_release (ipcfg_data[device].ihandle);
#endif
        } 
        else if ((ipcfg_data[device].actual_state == IPCFG_STATE_STATIC_IP) || (ipcfg_data[device].actual_state == IPCFG_STATE_AUTO_IP) || (ipcfg_data[device].actual_state == IPCFG_STATE_BOOT))
        {
            RTCS_if_unbind (ipcfg_data[device].ihandle, ipcfg_data[device].actual_ip_data.ip);
        }
    }

#if RTCSCFG_ENABLE_GATEWAYS
    if (ipcfg_data[device].actual_ip_data.gateway != 0) 
    {
        RTCS_gate_remove (ipcfg_data[device].actual_ip_data.gateway, INADDR_ANY, INADDR_ANY);
    }
#endif

#if RTCSCFG_IPCFG_ENABLE_DNS
    if (ipcfg_data[device].dns != 0)
    {
        ipcfg_del_dns_ip (device, ipcfg_data[device].dns);
    }
    ipcfg_data[device].dns = 0;
#endif

    ipcfg_data[device].actual_ip_data.ip = 0;
    ipcfg_data[device].actual_ip_data.mask = 0;
    ipcfg_data[device].actual_ip_data.gateway = 0;
#if RTCSCFG_IPCFG_ENABLE_BOOT
    ipcfg_data[device].tftp_serveraddress = 0;
    ipcfg_data[device].tftp_servername[0] = ipcfg_empty_string[0];
    ipcfg_data[device].boot_filename[0] = ipcfg_empty_string[0];
#endif
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
    ipcfg_data[device].dhcp_retries = 0;
#endif
    ipcfg_data[device].actual_state = IPCFG_STATE_UNBOUND;
    return IPCFG_OK;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_unbind_internal()
* Returned Value : ipcfg error code
* Comments       : Control semaphore unprotected unbind.
*
*END--------------------------------------------------------------------*/

static uint_32 ipcfg_unbind_internal
    (
        uint_32 device
    )
{
    uint_32 result;
    
    if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;

    result = ipcfg_unbind_internal_actual (device);

    _lwsem_post (&(ipcfg_data[device].request_semaphore));

    return result;  
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_unbind()
* Returned Value : ipcfg error code
* Comments       : Releases any ip information associated with given device.
*
*END--------------------------------------------------------------------*/

uint_32 ipcfg_unbind
    (
        uint_32 device
    )
{
    uint_32 result;

    if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;

    if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
    
    if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;

    result = ipcfg_unbind_internal (device);

    if (result == IPCFG_OK)
    {
        ipcfg_data[device].desired_ip_data = ipcfg_data[device].actual_ip_data;
        ipcfg_data[device].desired_state = ipcfg_data[device].actual_state;
    }

    _lwsem_post (&(ipcfg_data[device].control_semaphore));

    return result;  
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_staticip_internal()
* Returned Value : ipcfg error code
* Comments       : Actual static bind process.
*
*END--------------------------------------------------------------------*/

static uint_32 ipcfg_bind_staticip_internal 
    (
        uint_32                     device,
        IPCFG_IP_ADDRESS_DATA_PTR   static_ip_data
    )
{
    uint_32 result;

    if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;

    ipcfg_unbind_internal_actual (device);
    
    if (static_ip_data == NULL)
    {
        static_ip_data = &(ipcfg_data[device].desired_ip_data);
    }

    result = RTCSERR_IPCFG_BIND;
    if (RTCS_if_probe_and_bind (ipcfg_data[device].ihandle, static_ip_data->ip, static_ip_data->mask) == RTCS_OK)
    {
        ipcfg_data[device].desired_ip_data.ip = static_ip_data->ip;
        ipcfg_data[device].desired_ip_data.mask = static_ip_data->mask;
        ipcfg_data[device].desired_ip_data.gateway = static_ip_data->gateway;
        ipcfg_data[device].actual_ip_data.ip = static_ip_data->ip;
        ipcfg_data[device].actual_ip_data.mask = static_ip_data->mask;
#if RTCSCFG_ENABLE_GATEWAYS
        if (static_ip_data->gateway != 0)
        {
            if (RTCS_gate_add (static_ip_data->gateway, INADDR_ANY, INADDR_ANY) == RTCS_OK) 
            {
                ipcfg_data[device].actual_ip_data.gateway = static_ip_data->gateway;
            }
        }
#endif
        ipcfg_data[device].desired_state = IPCFG_STATE_STATIC_IP;       
        ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
        result = IPCFG_OK;
    }

    _lwsem_post (&(ipcfg_data[device].request_semaphore));

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_staticip()
* Returned Value : ipcfg error code
* Comments       : Tries to bind given static ip for given device.
*
*END--------------------------------------------------------------------*/

uint_32 ipcfg_bind_staticip 
    (
        uint_32                     device,
        IPCFG_IP_ADDRESS_DATA_PTR   static_ip_data
    )
{
    uint_32 result;

    if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;

    if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;

    if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;

    result = ipcfg_bind_staticip_internal (device, static_ip_data);

    _lwsem_post (&(ipcfg_data[device].control_semaphore));
    
    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_autoip_internal_actual()
* Returned Value : ipcfg error code
* Comments       : Actual auto bind process.
*
*END--------------------------------------------------------------------*/

static uint_32 ipcfg_bind_autoip_internal_actual
    (
        uint_32                     device,
        IPCFG_IP_ADDRESS_DATA_PTR   auto_ip_data
    )
{
    uint_32 attempts;
    uint_32 result;
    
    ipcfg_unbind_internal_actual (device);

    if (auto_ip_data == NULL)
    {
        auto_ip_data = &(ipcfg_data[device].desired_ip_data);
    }

    result = RTCSERR_IPCFG_BIND;
    for (attempts = 0; attempts < IPCFG_MAX_AUTOIP_ATTEMPTS; attempts++)
    {
        if (RTCS_if_probe_and_bind (ipcfg_data[device].ihandle, auto_ip_data->ip, auto_ip_data->mask) == RTCS_OK)
        {
            ipcfg_data[device].desired_ip_data.ip = auto_ip_data->ip;
            ipcfg_data[device].desired_ip_data.mask = auto_ip_data->mask;
            ipcfg_data[device].desired_ip_data.gateway = auto_ip_data->gateway;
            ipcfg_data[device].actual_ip_data.ip = auto_ip_data->ip;
            ipcfg_data[device].actual_ip_data.mask = auto_ip_data->mask;
#if RTCSCFG_ENABLE_GATEWAYS
            if (auto_ip_data->gateway != 0)
            {   
                if (RTCS_gate_add (auto_ip_data->gateway, INADDR_ANY, INADDR_ANY) == RTCS_OK) 
                {
                    ipcfg_data[device].actual_ip_data.gateway = auto_ip_data->gateway;
                }
            }
#endif
            ipcfg_data[device].desired_state = IPCFG_STATE_AUTO_IP;
            ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
            result = IPCFG_OK;
            break;
        } 
        do
        {
            auto_ip_data->ip = (auto_ip_data->ip & auto_ip_data->mask) | ((auto_ip_data->ip + 1) & (~ auto_ip_data->mask));
        } while (auto_ip_data->ip & (~ auto_ip_data->mask) == 0);
    }

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_autoip_internal()
* Returned Value : ipcfg error code
* Comments       : Control semaphore unprotected auto bind.
*
*END--------------------------------------------------------------------*/

static uint_32 ipcfg_bind_autoip_internal
    (
        uint_32                     device,
        IPCFG_IP_ADDRESS_DATA_PTR   auto_ip_data
    )
{
    uint_32 result;
    
    if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;

    result = ipcfg_bind_autoip_internal_actual (device, auto_ip_data);

    _lwsem_post (&(ipcfg_data[device].request_semaphore));

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_autoip()
* Returned Value : ipcfg error code
* Comments       : Tries to bind given ip address data for given device and 
*                  continues incrementing ip until bound or maximum tries reached.
*
*END--------------------------------------------------------------------*/

uint_32 ipcfg_bind_autoip 
    (
        uint_32                     device,
        IPCFG_IP_ADDRESS_DATA_PTR   auto_ip_data
    )
{
    uint_32 result;
    
    if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;

    if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;

    if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;
    
    result = ipcfg_bind_autoip_internal (device, auto_ip_data);

    _lwsem_post (&(ipcfg_data[device].control_semaphore));

    return result;
}


#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_dhcp_choice_func()
* Returned Value : 0 == not acceptable
* Comments       : This function is used to choose if a DHCPOFFER is
*                  acceptable. If it is, the Client will request the
*                  lease with the parameters given.
*
*END--------------------------------------------------------------------*/

static int_32 ipcfg_dhcp_choice_func
    (
        uchar_ptr buffer_ptr,
        uint_32 buffer_size
    )
{
#if IPCFG_DEBUG_LEVEL >= 1
    printf ("DHCP choice func.\n");
#endif
    return 1;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_dhcp_func()
* Returned Value : void
* Comments       : This function is called when the DHCP interface is bound
*                  to inform the application that a network connection has
*                  been established. Can be used to trigger an event, etc..
*
*END--------------------------------------------------------------------*/

static void ipcfg_bind_dhcp_func
    (
        uchar_ptr buffer_ptr,
        uint_32 buffer_size,
        _rtcs_if_handle ihandle
    )
{
    uchar_ptr           optptr;
    uint_32             optlen;
    DHCP_HEADER_PTR     dhcp_ptr = (DHCP_HEADER_PTR)buffer_ptr;
    uint_32             device = ipcfg_get_device_number (ihandle);

    if (device >= IPCFG_DEVICE_COUNT)
    {
#if IPCFG_DEBUG_LEVEL >= 1
        printf ("DHCP bind func - wrong device number.\n");
#endif
        return;
    } 

    if ((buffer_ptr == NULL) || (buffer_size == 0)) 
    {
#if IPCFG_DEBUG_LEVEL >= 1
        printf ("DHCP bind func - lease not obtained.\n");
#endif
    }
    else 
    {
#if IPCFG_DEBUG_LEVEL >= 1
        printf ("DHCP bind func - success.\n");
#endif

        ipcfg_data[device].actual_ip_data.ip = ntohl (dhcp_ptr->YIADDR);

        optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_MASK);
        if (optptr) 
        {
            optptr++;
            optlen = ntohc (optptr);
            optptr++;
            if (optlen >= 4)
            {
                ipcfg_data[device].actual_ip_data.mask = ntohl  (optptr);
            }
        } 

#if RTCSCFG_ENABLE_GATEWAYS
        optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_ROUTER);
        if (optptr) {
            optptr++;
            optlen = ntohc (optptr);
            optptr++;
            if (optlen >= 4) 
            {
                ipcfg_data[device].actual_ip_data.gateway = ntohl (optptr);
            }
        } 
#endif

#if RTCSCFG_IPCFG_ENABLE_DNS
        optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_DNSSERVER);
        if (optptr) 
        {
            optptr++;
            optlen = ntohc (optptr);
            optptr++;
            if (optlen >= 4) 
            {
                ipcfg_data[device].dns = ntohl (optptr);
            }
        }
#endif

#if RTCSCFG_IPCFG_ENABLE_BOOT
        optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_TFTPSERVER);
        if (optptr) 
        {
            optptr++;
            optlen = ntohc (optptr);
            optptr++;
            if (optlen >= RTCS_SNAME_LEN - 1) optlen = RTCS_SNAME_LEN - 2; 
            _mem_copy (optptr, ipcfg_data[device].tftp_servername, optlen);
            ipcfg_data[device].tftp_servername[optlen + 1] = '\0';
        } 
        else 
        {
            _mem_copy (dhcp_ptr->SNAME, ipcfg_data[device].tftp_servername, RTCS_SNAME_LEN);
            ipcfg_data[device].tftp_servername[RTCS_SNAME_LEN - 1] = '\0';
        } 

        optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_BOOTFILENAME);
        if (optptr) 
        {
            optptr++;
            optlen = ntohc (optptr);
            optptr++;
            if (optlen >= RTCS_BOOTFILE_LEN - 1) optlen = RTCS_BOOTFILE_LEN - 2; 
            _mem_copy (optptr, ipcfg_data[device].boot_filename, optlen);
            ipcfg_data[device].boot_filename[optlen + 1] = '\0';
        } 
        else
        {
            _mem_copy (dhcp_ptr->FILE, ipcfg_data[device].boot_filename, RTCS_BOOTFILE_LEN);
            ipcfg_data[device].boot_filename[RTCS_BOOTFILE_LEN - 1] = '\0';
        } 
#endif

        if (ipcfg_data[device].actual_state == IPCFG_STATE_UNBOUND) 
			ipcfg_data[device].actual_state = IPCFG_STATE_BUSY;
    }   

    if (ipcfg_data[device].actual_state == IPCFG_STATE_BUSY) 
		_lwsem_post (&(ipcfg_data[device].dhcp_response_semaphore));
} 


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_dhcp_nak_func()
* Returned Value : boolean
* Comments       : This function is called when the DHCP interface is bound
*                  to inform the application that a network connection has
*                  been established. Can be used to trigger an event, etc..
*
*END--------------------------------------------------------------------*/

static boolean ipcfg_dhcp_nak_func
    (
        uchar_ptr buffer_ptr,
        uint_32 buffer_size,
        _rtcs_if_handle ihandle
    )
{
    uint_32 device = ipcfg_get_device_number (ihandle);
#if IPCFG_DEBUG_LEVEL >= 1
    printf("DHCP nak func - ");
#endif
    if (device >= IPCFG_DEVICE_COUNT)
    {
#if IPCFG_DEBUG_LEVEL >= 1
        printf ("wrong device number.\n");
#endif
        return FALSE;
    }
    if (ipcfg_data[device].dhcp_retries++ < IPCFG_MAX_NAK_RETRIES) 
    {
#if IPCFG_DEBUG_LEVEL >= 1
        printf ("retry %d.\n", ipcfg_data[device].dhcp_retries);
#endif
        return TRUE;
    } 
    else 
    {
#if IPCFG_DEBUG_LEVEL >= 1
        printf ("abort.\n");
#endif
        return FALSE;
    }
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_dhcp_unbind_func()
* Returned Value : boolean
* Comments       : This function is called when the DHCP lease terminates.
*                  It allows the application the flexibility to decide if
*                  it wishes to re-bind the interface again or terminate the
*                  DHCP client and permanently unbind.
*
*END--------------------------------------------------------------------*/

static boolean ipcfg_dhcp_unbind_func
    (
        _rtcs_if_handle ihandle
    )
{
#if IPCFG_DEBUG_LEVEL >= 1
    printf("DHCP unbind func.\n");
#endif
    // remove gateway here
    return( TRUE );
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_dhcp_fail_func()
* Returned Value : boolean
* Comments       : This function is called when a DHCP failure is detected
*                  This is will invoked if the a NAK is recieved from the server
*
*END--------------------------------------------------------------------*/
static boolean ipcfg_dhcp_fail_func
    (
        _rtcs_if_handle ihandle
    )
{
    uint_32 device = ipcfg_get_device_number (ihandle);
#if IPCFG_DEBUG_LEVEL >= 1
    printf("DHCP fail func.\n");
#endif
    if (device < IPCFG_DEVICE_COUNT)
    {
        _lwsem_post(&(ipcfg_data[device].dhcp_response_semaphore));
    }
    return FALSE;
}
#endif


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : ipcfg_bind_dhcp_internal()
* Returned Value : ipcfg error code
* Comments       : Actual DHCP start process.
*
*END------------------------------------------------------------------*/

static uint_32 ipcfg_bind_dhcp_internal
    (
        uint_32 device,
        boolean try_auto_ip
    )
{
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
    DHCP_DATA_STRUCT    options;
    uchar_ptr           optptr;
    uchar               DHCP_option_array[256];
    uint_32             optlen = sizeof (DHCP_option_array);
    uchar               parm_options[] = {DHCPOPT_MASK, DHCPOPT_DNSSERVER, DHCPOPT_ROUTER, DHCPOPT_TFTPSERVER, DHCPOPT_BOOTFILENAME};
    uint_32             error = 0;
    uint_32             result = IPCFG_OK;

    if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;
    
    ipcfg_unbind_internal_actual (device);

    options.CHOICE_FUNC  = ipcfg_dhcp_choice_func;
    options.BIND_FUNC    = ipcfg_bind_dhcp_func;
    options.UNBIND_FUNC  = ipcfg_dhcp_unbind_func;
    options.FAILURE_FUNC = ipcfg_dhcp_fail_func;
    options.NAK_FUNC     = ipcfg_dhcp_nak_func;

    optptr = DHCP_option_array;

    DHCP_option_variable (&optptr, &optlen, DHCPOPT_PARAMLIST, parm_options, sizeof (parm_options));

    error = RTCS_if_bind_DHCP (ipcfg_data[device].ihandle, &options, DHCP_option_array, optptr - DHCP_option_array);
    if (error != RTCS_OK) 
    { 
        if (try_auto_ip) 
        {
            _lwsem_post(&(ipcfg_data[device].dhcp_response_semaphore));
        }
        else 
        {
            _lwsem_post (&(ipcfg_data[device].request_semaphore));
            result = RTCSERR_IPCFG_BIND;
        }
    } 

    return result;
#else
    return RTCSERR_IPCFG_BIND;
#endif
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : ipcfg_bind_dhcp()
* Returned Value : ipcfg error code
* Comments       : Starts DHCP process for given device, locks it with semaphore.
*
*END------------------------------------------------------------------*/

uint_32 ipcfg_bind_dhcp 
    (
        uint_32 device,
        boolean try_auto_ip
    )
{
    uint_32 result;

    if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;

    if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
        
    if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;

#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
    result = ipcfg_bind_dhcp_internal (device, try_auto_ip);
#else
    result = RTCSERR_IPCFG_BIND;
#endif
    
    _lwsem_post (&(ipcfg_data[device].control_semaphore));

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_poll_dhcp_internal()
* Returned Value : ipcfg error code
* Comments       : Actual DHCP polling process.
*
*END--------------------------------------------------------------------*/

static uint_32 ipcfg_poll_dhcp_internal
    (
        uint_32                     device,
        boolean                     try_auto_ip,
        IPCFG_IP_ADDRESS_DATA_PTR   auto_ip_data
    )
{
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
    uint_32 result = RTCSERR_IPCFG_BUSY;

    if (_lwsem_poll (&(ipcfg_data[device].dhcp_response_semaphore)))
    {
        if (ipcfg_data[device].actual_state == IPCFG_STATE_BUSY)
        {
            result = IPCFG_OK;
            
#if RTCSCFG_IPCFG_ENABLE_DNS
            if (ipcfg_data[device].dns != 0)
            {
                if (! ipcfg_add_dns_ip (device, ipcfg_data[device].dns))
                {
                    ipcfg_data[device].dns = 0;
                }               
            }
#endif
#if RTCSCFG_ENABLE_GATEWAYS
            if (ipcfg_data[device].actual_ip_data.gateway != 0) 
            {
                if (RTCS_gate_add (ipcfg_data[device].actual_ip_data.gateway, INADDR_ANY, INADDR_ANY) != RTCS_OK)
                {
                    ipcfg_data[device].actual_ip_data.gateway = 0;
                }
            }
#endif
            if (auto_ip_data == NULL)
            {
                auto_ip_data = &(ipcfg_data[device].desired_ip_data);
            }

            ipcfg_data[device].desired_ip_data.ip = auto_ip_data->ip;
            ipcfg_data[device].desired_ip_data.mask = auto_ip_data->mask;
            ipcfg_data[device].desired_ip_data.gateway = auto_ip_data->gateway;
            if (try_auto_ip)
            {
                ipcfg_data[device].desired_state = IPCFG_STATE_DHCPAUTO_IP;
            }
            else
            {
                ipcfg_data[device].desired_state = IPCFG_STATE_DHCP_IP;
            }
            ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
        }
        else 
        {
            result = RTCSERR_IPCFG_BIND;
            if (try_auto_ip) 
            {
                result = ipcfg_bind_autoip_internal_actual (device, auto_ip_data);
                if (result == IPCFG_OK)
                {
                    ipcfg_data[device].desired_state = IPCFG_STATE_DHCPAUTO_IP;
                    ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
                }
            }
        }
        
        _lwsem_post (&(ipcfg_data[device].request_semaphore));
    }
    return result;
#else
    return RTCSERR_IPCFG_BIND;
#endif
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_poll_dhcp()
* Returned Value : ipcfg error code
* Comments       : Polls DHCP bind completion for given device, releases 
*                  the device related semaphore lock.
*
*END--------------------------------------------------------------------*/

uint_32 ipcfg_poll_dhcp 
    (
        uint_32                     device,
        boolean                     try_auto_ip,
        IPCFG_IP_ADDRESS_DATA_PTR   auto_ip_data
    )
{
    uint_32 result;

    if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;

    if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
    
    if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return IPCFG_STATE_BUSY;

#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
    result = ipcfg_poll_dhcp_internal (device, try_auto_ip, auto_ip_data);
#else
    result = RTCSERR_IPCFG_BIND;
#endif

    _lwsem_post (&(ipcfg_data[device].control_semaphore));

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_boot_internal()
* Returned Value : ipcfg error code
* Comments       : Control semaphore unprotected boot bind.
*
*END--------------------------------------------------------------------*/

static uint_32 ipcfg_bind_boot_internal
    (
        uint_32 device
    )
{
#if RTCSCFG_IPCFG_ENABLE_BOOT   
    BOOTP_DATA_STRUCT   boot_data;
#endif  
    uint_32             result = RTCSERR_IPCFG_BIND;
    
#if RTCSCFG_IPCFG_ENABLE_BOOT
    if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;
    
    ipcfg_unbind_internal_actual (device);

    if (RTCS_if_bind_BOOTP (ipcfg_data[device].ihandle, &boot_data) == RTCS_OK)
    {
#if RTCSCFG_BOOTP_RETURN_YIADDR
        if (boot_data.YIADDR != 0)
        {
            ipcfg_data[device].actual_ip_data.ip = boot_data.YIADDR;
            ipcfg_data[device].actual_ip_data.mask = 0;
            ipcfg_data[device].actual_ip_data.gateway = 0;
        } 
#endif
        if (boot_data.SADDR != 0)
        {
            ipcfg_data[device].tftp_serveraddress = boot_data.SADDR;
        }

        if (boot_data.SNAME[0] != '\0')
        {
            _mem_copy (boot_data.SNAME, ipcfg_data[device].tftp_servername, RTCS_SNAME_LEN);
            ipcfg_data[device].tftp_servername[RTCS_SNAME_LEN - 1] = '\0';
        }
                     
        if (boot_data.BOOTFILE[0] != '\0')
        {
            _mem_copy (boot_data.BOOTFILE, ipcfg_data[device].boot_filename, RTCS_BOOTFILE_LEN);
            ipcfg_data[device].boot_filename[RTCS_BOOTFILE_LEN - 1] = '\0';
        }
    
        ipcfg_data[device].desired_state = IPCFG_STATE_BOOT;
        ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
        result = IPCFG_OK;
    }

    _lwsem_post (&(ipcfg_data[device].request_semaphore));
#endif

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_boot()
* Returned Value : ipcfg error code
* Comments       : Tries to bind via boot protocol for given device.
*
*END--------------------------------------------------------------------*/

uint_32 ipcfg_bind_boot 
    (
        uint_32 device
    )
{
    uint_32 result;
    
    if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;

    if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;

    if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;
    
    result = ipcfg_bind_boot_internal (device);

    _lwsem_post (&(ipcfg_data[device].control_semaphore));

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_bind_dhcp_wait()
* Returned Value : ipcfg error code
* Comments       : Tries to bind via dhcp (followed by auto ip) and waits for it.
*
*END----------------------------------------------------------------*/

uint_32 ipcfg_bind_dhcp_wait 
    (
        uint_32                     device, 
        boolean                     try_auto_ip,
        IPCFG_IP_ADDRESS_DATA_PTR   auto_ip_data
    )
{
    uint_32 result = IPCFG_OK;

    do 
    {
        if (result == RTCSERR_IPCFG_BUSY) _time_delay (200);
        result = ipcfg_bind_dhcp (device, try_auto_ip);
    } while (result == RTCSERR_IPCFG_BUSY);
    if (result != IPCFG_OK) return result;
    do 
    {
        _time_delay (200);
        result = ipcfg_poll_dhcp (device, try_auto_ip, auto_ip_data);
    } while (result == RTCSERR_IPCFG_BUSY);
    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_task_poll()
* Returned Value : TRUE if bind process finished (stable), FALSE otherwise (must call it again)
* Comments       : One step of the ethernet link/bind monitoring task.
*
*END----------------------------------------------------------------*/

boolean ipcfg_task_poll (void)
{
    IPCFG_STATE     actual_state;
    IPCFG_STATE     desired_state;
    uint_32         error;
    uint_32         i;
    boolean         link;
    boolean         can_finish = TRUE;

    // go through all ethernet devices
    for (i = 0; i < IPCFG_DEVICE_COUNT; i++)
    {
        // check if current device interface is initialized
        if (ipcfg_data[i].actual_state != IPCFG_STATE_INIT)
        {
            link = ipcfg_get_link_active (i);
            
            // take control, outside binds are discarded for the moment, or skip this otherwise
            if (_lwsem_poll (&(ipcfg_data[i].control_semaphore))) 
            {
                // check link and bind status
                actual_state = ipcfg_get_state (i);
                desired_state = ipcfg_get_desired_state (i);
                if ((link) && (actual_state != desired_state)) 
                {
                    // link is up but bind is not finished
                    switch (desired_state)
                    {
                        case IPCFG_STATE_UNBOUND:
                            ipcfg_unbind_internal (i);
                            break;
                        case IPCFG_STATE_STATIC_IP:
                            ipcfg_bind_staticip_internal (i, NULL);
                            break;
                        case IPCFG_STATE_DHCP_IP:
                            error = ipcfg_bind_dhcp_internal (i, FALSE);
                            if ((error == IPCFG_OK) || (error == RTCSERR_IPCFG_BUSY))
                            {
                                ipcfg_poll_dhcp_internal (i, FALSE, NULL);
                            }
                            break;
                        case IPCFG_STATE_AUTO_IP:
                            ipcfg_bind_autoip_internal (i, NULL);
                            break;
                        case IPCFG_STATE_DHCPAUTO_IP:
                            error = ipcfg_bind_dhcp_internal (i, TRUE);
                            if ((error == IPCFG_OK) || (error == RTCSERR_IPCFG_BUSY))
                            {
                                ipcfg_poll_dhcp_internal (i, TRUE, NULL);
                            }
                            break;
                        case IPCFG_STATE_BOOT:
                            ipcfg_bind_boot_internal (i);
                            break;
                        default: 
                            break;                      
                    }
                } 
				else if ((! link) && (actual_state != IPCFG_STATE_UNBOUND)) 
				{
					// link is down, unbind any interface
					ipcfg_unbind_internal (i);
				}

                // if busy, don't finish the task and check it next time
                can_finish &= (actual_state != IPCFG_STATE_BUSY);

                _lwsem_post (&(ipcfg_data[i].control_semaphore));
                
            }
            else
            {
                // interface was busy, don't finish the task and check it next time
                actual_state = IPCFG_STATE_BUSY;
                can_finish = FALSE;
            }

#if IPCFG_DEBUG_LEVEL >= 2
            printf ("Eth#:%d link:%s state:%s\n", i, link ? "on" : "off", ipcfg_get_state_string (actual_state));
#endif
        }
    }

    return can_finish;
}


/*TASK*--------------------------------------------------------------
*
* Function Name  : ipcfg_monitor_task()
* Returned Value : void
* Comments       : All ethernet devices monitoring/binding task.
*
*END----------------------------------------------------------------*/

static void ipcfg_monitor_task 
    (
        uint_32     check_period_ms
    )
{
    boolean can_finish;

#if IPCFG_DEBUG_LEVEL >= 2
    printf ("IPCFG task created.\n");
#endif
    
    while (TRUE) 
    {
        can_finish = ipcfg_task_poll ();

        if ((! ipcfg_task_run) && can_finish) break;

        _time_delay (check_period_ms);
    }

#if IPCFG_DEBUG_LEVEL >= 2
    printf ("IPCFG task destroyed.\n");
#endif
    _task_destroy (MQX_NULL_TASK_ID);
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_task_create()
* Returned Value : MQX error code
* Comments       : Starts ipcfg task, if not started yet.
*
*END--------------------------------------------------------------------*/

uint_32 ipcfg_task_create
    (
        uint_32 priority, 
        uint_32 task_period_ms
    )
{
    TASK_TEMPLATE_STRUCT  task_templ;
    _task_id              tid;
	uint_32               tec;
    uint_32               result;

    if (ipcfg_task_status ())
    {
        return MQX_DUPLICATE_TASK_TEMPLATE_INDEX;
    }

    ipcfg_task_run = TRUE;

	tec = _task_get_error();
    _mem_zero ((uchar_ptr)&task_templ, sizeof (task_templ));
    task_templ.TASK_ADDRESS       = ipcfg_monitor_task;
    task_templ.TASK_STACKSIZE     = IPCFG_TASK_STACK_SIZE;
    task_templ.TASK_PRIORITY      = priority;
    task_templ.TASK_NAME          = (char_ptr)ipcfg_task_name;
    task_templ.CREATION_PARAMETER = task_period_ms;
    
    tid = _task_create (0, 0, (uint_32)&task_templ);
    if (tid == MQX_NULL_TASK_ID) 
    {
        result = MQX_INVALID_TASK_ID;
    } 
    else 
    {
        result = MQX_OK;
    }
	_task_set_error(tec);

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_task_destroy()
* Returned Value : void
* Comments       : Sets flag to destroy ipcfg task, can wait for completion.
*
*END--------------------------------------------------------------------*/

void ipcfg_task_destroy
    (
        boolean wait_task_finish
    )
{
    _task_id    tid;
    uint_32     period;

    ipcfg_task_run = FALSE;
    if (! wait_task_finish) return;
    do
    {
        tid = _task_get_id_from_name ((char_ptr)&ipcfg_task_name);
        if (tid != MQX_NULL_TASK_ID) 
        {
            period = _task_get_parameter_for (tid);
            if ((period < 10 || period > 10000)) period = 1000;
            _time_delay (period);
        }
    } while (tid != MQX_NULL_TASK_ID);
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_task_status()
* Returned Value : TRUE if running, FALSE otherwise
* Comments       : Checks whether task is running.
*
*END--------------------------------------------------------------------*/

boolean ipcfg_task_status (void)
{
    _task_id tid;
    
    tid = _task_get_id_from_name ((char_ptr)&ipcfg_task_name);
    if (tid != MQX_NULL_TASK_ID) 
    {
        return TRUE;
    }
    return FALSE;   
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_init_device()
* Returned Value : error code
* Comments       : Initializes given enet device and associated ip interface.
*
*END--------------------------------------------------------------------*/

uint_32 ipcfg_init_device
    (
        uint_32         device,
        _enet_address   mac
    )
{
    _enet_handle    ehandle;
    _rtcs_if_handle ihandle;
    uint_32         error = 0;
    
    error = ENET_initialize (device, mac, 0, &ehandle);
    
    if (error == RTCS_OK) 
    {
        error = RTCS_if_add (ehandle, RTCS_IF_ENET, &ihandle);
        if (error == RTCS_OK) 
        {
            error = ipcfg_init_interface(device, ihandle);
            if (error != RTCS_OK)
            {
                RTCS_if_remove (ihandle);
                ENET_shutdown (ehandle);
#if IPCFG_DEBUG_LEVEL >= 2
                printf ("IPCFG init error: %08x\n", error);
#endif
            }
        }
        else 
        {
            ENET_shutdown (ehandle);
#if IPCFG_DEBUG_LEVEL >= 2
            printf ("Interface add error: %08x\n", error);
#endif
        }
        
    }
    else if (error == ENETERR_INIT_DEVICE)
    {
#if IPCFG_DEBUG_LEVEL >= 2
        printf ("Device reinitialization... \n");
#endif
    }
    else  
    {
#if IPCFG_DEBUG_LEVEL >= 2
        printf ("Device initialization error: %08x\n", error);
#endif
    }
    
    return error;
}

/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_release_device()
* Returned Value : error code
* Comments       : Releases given enet device and associated ip interface.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_release_device(uint_32  device )
{
    _enet_handle    ehandle;
    _rtcs_if_handle ihandle;
    uint_32         error = 0;

    if (device < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(device);
        if(ihandle != NULL)
        {
            ehandle = RTCS_get_enet_handle(ihandle);

            error = ipcfg_release_interface(device);
            if (error == RTCS_OK)
            {
                error = RTCS_if_remove (ihandle);
                if (error == RTCS_OK)
                {
                    error = ENET_shutdown (ehandle);
                }
            }
            return error;
        }
        else /* Not initialised by ipcfg_init_device().*/
            return RTCSERR_IPCFG_NOT_INIT;

    }
    else
        return RTCSERR_IPCFG_DEVICE_NUMBER;

}

/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_init_interface()
* Returned Value : ipcfg error code
* Comments       : Initializes interface related internal structure - once.
*
*END--------------------------------------------------------------------*/

uint_32 ipcfg_init_interface 
    (
        uint_32 dev_num,
        _rtcs_if_handle ihandle
    )
{
    _mqx_uint device;

    if (ihandle == NULL) return RTCSERR_IPCFG_INIT; 
    
    device = ipcfg_add_interface(dev_num, ihandle);
    
    if (device == (uint_32)-1)
        return RTCSERR_IPCFG_INIT;
    
    if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
        return RTCSERR_IPCFG_BUSY;

    if (_lwsem_create (&ipcfg_data[device].control_semaphore, 1) != MQX_OK)
    {
        return RTCSERR_IPCFG_INIT;
    }
    if (_lwsem_create (&ipcfg_data[device].request_semaphore, 1) != MQX_OK)
    {
        _lwsem_destroy (&ipcfg_data[device].control_semaphore);
        return RTCSERR_IPCFG_INIT;
    }
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
    if (_lwsem_create (&ipcfg_data[device].dhcp_response_semaphore, 0) != MQX_OK)
    {
        _lwsem_destroy (&ipcfg_data[device].control_semaphore);
        _lwsem_destroy (&ipcfg_data[device].request_semaphore);
        return RTCSERR_IPCFG_INIT;
    }
    ipcfg_data[device].dhcp_retries = 0;
#endif  
    ipcfg_data[device].ihandle = ihandle;
    ipcfg_data[device].desired_ip_data.ip = 0;
    ipcfg_data[device].desired_ip_data.mask = 0;
    ipcfg_data[device].desired_ip_data.gateway = 0;
    ipcfg_data[device].actual_ip_data.ip = 0;
    ipcfg_data[device].actual_ip_data.mask = 0;
    ipcfg_data[device].actual_ip_data.gateway = 0;
#if RTCSCFG_IPCFG_ENABLE_DNS
    ipcfg_data[device].dns = 0;
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT   
    ipcfg_data[device].tftp_serveraddress = 0;
    ipcfg_data[device].tftp_servername[0] = ipcfg_empty_string[0];
    ipcfg_data[device].boot_filename[0] = ipcfg_empty_string[0];
#endif  
    ipcfg_data[device].desired_state = IPCFG_STATE_UNBOUND;
    ipcfg_data[device].actual_state = IPCFG_STATE_UNBOUND;
    
    return RTCS_OK;    
}

/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : ipcfg_release_interface()
* Returned Value : ipcfg error code
* Comments       : Releases interface related internal structure.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_release_interface ( uint_32 dev_num)
{
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ipcfg_unbind (dev_num);

    #if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
        _lwsem_destroy (&ipcfg_data[dev_num].dhcp_response_semaphore);
    #endif
        _lwsem_destroy (&ipcfg_data[dev_num].request_semaphore);
        _lwsem_destroy (&ipcfg_data[dev_num].control_semaphore);

        ipcfg_del_interface(dev_num);
        return RTCS_OK;
    }
    else
        return RTCSERR_IPCFG_DEVICE_NUMBER;
}



#endif /* (BSP_ENET_DEVICE_COUNT > 0) */
#endif /* BSP_ENET_DEVICE_COUNT */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb/usb_mcf5225_device.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_mcf5225_device.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains board-specific USB initialization functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"

struct usb_dev_if_struct _bsp_usb_dev_khci0_if = {
    &_usb_khci_dev_callback_table,
    (pointer) &_khci0_dev_init_param,
    NULL
};

_mqx_int _bsp_usb_init(pointer param);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_usb_dev_init
* Returned Value   : 0 for success, -1 for failure
* Comments         :
*    This function performs BSP-specific initialization related to USB device
*
*END*----------------------------------------------------------------------*/
_mqx_int _bsp_usb_dev_init(struct usb_dev_if_struct *usb_if)
{
    return _bsp_usb_init(NULL);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/MQX1.c<|end_filename|>
/* ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : MQX1.c
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : MQX
**     Version     : Component 01.032, Driver 01.01, CPU db: 3.00.000
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-08, 17:46, # CodeGen: 1
**     Abstract    :
**         MQX RTOS Adapter component.
**     Settings    :
**          Component name                                 : MQX1
**          Settings                                       : 
**            RTOS adaptor                                 : 
**              Memory allocation                          : 
**                User function for memory allocation      : no
**                User function for memory deallocation    : no
**              Critical section                           : 
**                User function for entering critical section : no
**                User function for exiting critical section : no
**     Contents    :
**         No public methods
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file MQX1.c
** @version 01.01
** @brief
**         MQX RTOS Adapter component.
*/         
/*!
**  @addtogroup MQX1_module MQX1 module documentation
**  @{
*/         

/* MODULE MQX1. */

#include "MQX1.h"

/* END MQX1. */

/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/bsp_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: bsp_prv.h$
* $Version : 3.8.3.0$
* $Date    : Oct-1-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for initialization of the card.
*
*END************************************************************************/
#ifndef _bsp_prv_h
#define _bsp_prv_h 1
#ifdef __cplusplus
extern "C" {
#endif

/*
**  FUNCTION PROTOTYPES
*/

extern void     __init(void);
extern uint_32  _bsp_get_hwticks(pointer);
extern void     _bsp_exit_handler(void);
extern void     _bsp_timer_isr(pointer);
extern uint_32  _rtc_int_install(INT_ISR_FPTR); 
extern void     _bsp_ddr2_setup (void);
extern void     _bsp_flexbus_pccard_setup (const uint_32 base_address);
extern void     systick_config(uint32_t bsp_system_clock, uint32_t bsp_alarm_frequency);


/*
**  STRUCTURE DEFINITIONS
*/

/* I/O initialization controlled by initialization structures for each channel */
extern const KUART_INIT_STRUCT _bsp_sci0_init;
extern const KUART_INIT_STRUCT _bsp_sci1_init;
extern const KUART_INIT_STRUCT _bsp_sci2_init;
extern const KUART_INIT_STRUCT _bsp_sci3_init;
extern const KUART_INIT_STRUCT _bsp_sci4_init;
extern const KUART_INIT_STRUCT _bsp_sci5_init;

extern const SPI_INIT_STRUCT _bsp_spi0_init;
extern const SPI_INIT_STRUCT _bsp_spi1_init;
extern const SPI_INIT_STRUCT _bsp_spi2_init;

extern const KI2C_INIT_STRUCT _bsp_i2c0_init;
extern const KI2C_INIT_STRUCT _bsp_i2c1_init;

extern const KADC_INIT_STRUCT _bsp_adc0_init;
extern const KADC_INIT_STRUCT _bsp_adc1_init;
extern const KADC_INIT_STRUCT _bsp_adc2_init;
extern const KADC_INIT_STRUCT _bsp_adc3_init;

extern const TCHRES_INIT_STRUCT _bsp_tchscr_resisitve_init;
extern const PCCARDFLEXBUS_INIT_STRUCT  _bsp_cfcard_init;
extern const IODEBUG_INIT_STRUCT _bsp_iodebug_init;

extern const KUSB_DCD_INIT_STRUCT _bsp_usb_dcd_init;
extern const ESDHC_INIT_STRUCT _bsp_esdhc0_init;
extern const FLASHX_FILE_BLOCK _bsp_flashx_file_blocks[];
extern const FLASHX_INIT_STRUCT _bsp_flashx_init;
extern const NANDFLASH_INIT_STRUCT _bsp_nandflash_init;
extern const SAI_INIT_STRUCT _bsp_sai_init;

#ifdef __cplusplus
}
#endif

#endif
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/natftp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: natftp.c$
* $Version : 3.8.5.0$
* $Date    : Sep-21-2012$
*
* Comments:
*
*   This file contains the NAT FTP ALG.
*
*END************************************************************************/

#include <rtcs.h>
#include <rtcs_prv.h>
#include <fio.h>
#include <tftp.h>
#include <ctype.h>
#include <string.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"

/*****************************************
**
** NAT FTP ALG Private structures
*/

typedef struct nat_ftp_struct{
   NAT_ALG_CFG_STRUCT   HEADER;
   _rtcs_part           FTP_PART_ID;
} NAT_FTP_STRUCT, _PTR_ NAT_FTP_STRUCT_PTR;

typedef struct nat_session_ftp_struct {
   NAT_SESSION_EXT_STRUCT     HEADER;
   int_32                     LAST_ADJ;
   uint_32                    LAST_SEQ;
   int_32                     NEXT_ADJ;
   uint_32                    NEXT_SEQ;
} NAT_SESSION_FTP_STRUCT, _PTR_ NAT_SESSION_FTP_STRUCT_PTR;

struct  {
   IP_HEADER   IP;
   TCP_HEADER  TCP;
} NAT_ALG_FTP_dummy = {
   {
      {0x45},                       /* VERSLEN */
      {0x00},                       /* TOS */
      {0x00, 0x28},                 /* LENGTH */
      {0xA1, 0x10},                 /* ID */
      {0x40, 0x00},                 /* FRAGMENT */
      {0x80},                       /* TTL */
      {0x06},                       /* PROTOCOL */
      {0xF8, 0xE8},                 /* CHECKSUM */
      {0x00, 0x00, 0x00, 0x00},     /* SOURCE */
      {0x00, 0x00, 0x00, 0x00}      /* DESTINATION */
   },
   {
      {0x00, 0x00},                 /* SOURCE PORT */
      {0x00, 0x00},                 /* DEST PORT */
      {0x00, 0x00, 0x00, 0x00},     /* SEQ */
      {0x00, 0x00, 0x00, 0x00},     /* ACK */
      {0x50, 0x10},                 /* FLAGS */
      {0x22, 0x38},                 /* WINDOW */
      {0x00, 0x00},                 /* CHECKSUM */
      {0x00, 0x00}                  /* URGENT */
   }
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_ALG_ftp
* Returned Value  : error code
* Comments        :
*        Initializes the NAT FTP ALG.
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_ALG_ftp
   (
      pointer ptr       /* [IN] Pointer to NAT config struct */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR   nat_cfg_ptr = ptr;
   NAT_FTP_STRUCT_PTR   ftp_ptr;

   ftp_ptr = _mem_alloc_system(sizeof(NAT_FTP_STRUCT));

   if (ftp_ptr)  {
      ftp_ptr->FTP_PART_ID = RTCS_part_create(
         sizeof(NAT_SESSION_FTP_STRUCT), 4, 4, 0, NULL, NULL);

      if (ftp_ptr->FTP_PART_ID) {
         ftp_ptr->HEADER.NEXT = nat_cfg_ptr->ALG_INFO_PTR;
         nat_cfg_ptr->ALG_INFO_PTR = (NAT_ALG_CFG_STRUCT_PTR)(pointer)ftp_ptr;
         ftp_ptr->HEADER.ALG_TYPE = NAT_ALG_FTP_TYPE;
         ftp_ptr->HEADER.ALG_EXEC = NAT_ALG_ftp_apply;
         return RTCS_OK;
      } else {
         _mem_free((pointer)ftp_ptr);
      } /* Endif */
   } /* Endif */

   return RTCSERR_OUT_OF_MEMORY;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_ALG_detect_port
* Returned Value  : boolean
* Comments        :
*        Detects a "PORT" command. Assumes data starts with "PORT".
*
*END*-----------------------------------------------------------------*/

static boolean NAT_ALG_detect_port
   (
      uchar_ptr      data_ptr,            /* [IN] pointer to data          */
      uint_32        len,                 /* [IN] length of data           */
      uint_32_ptr    ip_address_ptr,      /* [OUT] address read from data  */
      uint_16_ptr    port_ptr             /* [OUT] port read from data     */
   )
{ /* Body */
   uchar       buf[6] =  { 0, 0, 0, 0, 0, 0 };
   uchar_ptr   ptr;
   uint_32     state;

   *ip_address_ptr = 0;
   *port_ptr = 0;

   /* "PORT a,a,a,a,p,p" 16 bytes minimum */
   if (len < 18)  {
      return FALSE;
   } /* Endif */

   /* Skip "PORT" */
   ptr = data_ptr + 4;

   /*
   ** Regular expression for PORT command: ' '+([0-9]{1,3},){5}[0-9]{1,3}
   */

   /* At least 1 space */
   if (*ptr++ != ' ')  {
      return FALSE;
   } /* Endif */

   /* Skip all spaces */
   while ((ptr < (data_ptr + len)) && (*ptr == ' '))  {
      ptr++;
   } /* Enwhile */

   for (state = 0; ptr < (data_ptr + len); ptr++)  {
      if (isdigit(*ptr) && (state < 12))  {
         if ((state & 1) == 0)  {
            state++;
         } /* Endif */
         buf[state/2] = buf[state/2] * 10 + *ptr - '0';
      } else if ((*ptr == ',') && (state & 1)) {
         state++;
      } else {
         break;
      } /* Endif */
   } /* Endfor */

   if (state != 11)  {
      return FALSE;
   } /* Endif */

   *ip_address_ptr = ((buf[0] & 0xFF) << 24) +
         ((buf[1] & 0xFF) << 16) +
         ((buf[2] & 0xFF) <<  8) +
         (buf[3] & 0xFF);

   *port_ptr = ((buf[4] & 0xFF) << 8) + (buf[5] & 0xFF);

   return TRUE;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_ALG_ftp_pcb_free
* Returned Value  : void
* Comments        :
*        Frees a PCB
*
*END*-----------------------------------------------------------------*/

static void NAT_ALG_ftp_pcb_free
   (
      PCB_PTR  pcb_ptr   /* [IN] PCB to free */
   )
{ /* Body */
   _mem_free(pcb_ptr);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_ALG_ftp_bwrite
* Returned Value  : void
* Comments        :
*        Writes the ascii representation of a byte
*
*END*-----------------------------------------------------------------*/

static void NAT_ALG_ftp_bwrite
   (
      uchar             byte,          /* [IN] Byte to write         */
      uchar_ptr _PTR_   store_ptr_ptr  /* [IN/OUT] Pointer to data   */
   )
{
   uchar_ptr   store_ptr = *store_ptr_ptr;
   uint_32     len = 1;

   /* Determine length of byte */
   if (byte > 99)  {
      len = 3;
   } else if (byte > 9)  {
      len = 2;
   } /* Endif */

   /* Write out byte */
   switch (len)  {
      case 3:
         *store_ptr++ = '0' + byte / 100;
         byte %= 100;
      case 2:
         *store_ptr++ = '0' + byte / 10;
         byte %= 10;
      case 1:
         *store_ptr++ = '0' + byte;
         break;
   } /* Endif */

   *store_ptr_ptr = store_ptr;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_ALG_ftp_apply
* Returned Value  : error code
* Comments        :
*        Applies the NAT FTP ALG to a packet.
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_ALG_ftp_apply
   (
      RTCSPCB_PTR _PTR_ pcb_ptr_ptr,
      boolean           pub_to_prv,
      pointer           alg_cfg_ptr,
      pointer _PTR_     session_ptr_ptr
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR         nat_cfg_ptr = RTCS_getcfg(NAT);
   NAT_SESSION_STRUCT_PTR     nat_session_ptr = *((NAT_SESSION_STRUCT_PTR *)session_ptr_ptr);
   NAT_SESSION_STRUCT_PTR     nat_data_session_ptr;
   uchar_ptr                  orig_pcb_data_ptr = (pointer)RTCSPCB_DATA(*pcb_ptr_ptr), new_pcb_data_ptr;
   IP_HEADER_PTR              ip_header_ptr = (IP_HEADER_PTR)(pointer)orig_pcb_data_ptr;
   TRANSPORT_UNION            transport;
   NAT_SESSION_FTP_STRUCT_PTR ftp_session_ptr;
   RTCSPCB_PTR                new_pcb_ptr;
   uchar_ptr                  tcp_data_ptr;
   boolean                    src_port_is_ftp, dest_port_is_ftp;
   uint_32                    ack, temp, seq, addr, error;
   uint_16                    orig_tcp_data_length, new_tcp_data_length;
   int_32                     seq_adj, i;
   uint_16                    chksum,  port,  ip_header_length, tcp_header_length;
   uint_16                    orig_ip_length, new_ip_length;
   PCB_PTR                    new_mqx_pcb_ptr;

   if (nat_session_ptr == NULL)  {
      /*
      ** There is no session yet. This packet may be part of the TCP handshake,
      ** and not a data message. Let NAT first create a session.
      */
      return RTCS_OK;
   } /* Endif */

   /* FTP uses TCP only */
   if (ntohc(ip_header_ptr->PROTOCOL) != IPPROTO_TCP) {
      return RTCS_OK;
   } /* Endif */

   /* Extract port information */
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);
   src_port_is_ftp = (ntohs(transport.TCP_PTR->source_port) == IPPORT_FTP);
   dest_port_is_ftp = (ntohs(transport.TCP_PTR->dest_port) == IPPORT_FTP);

   
   /* ALG is only applicable on FTP command sessions (typically port 21) */
   if (!src_port_is_ftp && !dest_port_is_ftp) {
     return RTCS_OK;
   } /* Endif */

   if (! ((src_port_is_ftp && pub_to_prv) || (dest_port_is_ftp && !pub_to_prv))) {
     return RTCS_OK;
   } /* Endif */

   /* Get TCP data pointer */
   ip_header_length = IPH_LEN(ip_header_ptr);
   orig_ip_length = ntohs(ip_header_ptr->LENGTH);
   tcp_header_length = (((ntohs(transport.TCP_PTR->flags)) & DATAOFS_MASK) >> (DATAOFS_SHIFT - 2));
   tcp_data_ptr = &transport.DATA_OFFSET[tcp_header_length];
   orig_tcp_data_length = orig_ip_length - (ip_header_length + tcp_header_length);

   /* Check if an FTP session struct exists */
   ftp_session_ptr = (NAT_SESSION_FTP_STRUCT_PTR)(pointer)nat_session_ptr->ALG_INFO_PTR;
   while (ftp_session_ptr != NULL)  {
      if (ftp_session_ptr->HEADER.ALG_TYPE == NAT_ALG_FTP_TYPE)  {
         /* Found the FTP session struct */
         break;
      } /* Endif */
      ftp_session_ptr = (NAT_SESSION_FTP_STRUCT_PTR)(pointer)ftp_session_ptr->HEADER.NEXT; 
   } /* Endwhile */

   /*
   ** If the packet is entering the priv net from FTP command port, we don't
   ** modify it if no FTP session struct exists. The session may be using a mode
   ** that doesn't require any ALG.If there is a session struct, update ACK.
   */
   if (src_port_is_ftp && pub_to_prv) {
      if (ftp_session_ptr)  {
         /* Update packet with correct ACK */
         ack = ntohl(transport.TCP_PTR->ack);
         chksum = ntohs(transport.TCP_PTR->checksum);
         if ((int_32)(ack - (ftp_session_ptr->LAST_SEQ + ftp_session_ptr->LAST_ADJ)) <= 0)  {
            temp = ftp_session_ptr->LAST_SEQ;
         } else  {
            temp = ftp_session_ptr->NEXT_SEQ;
         } /* Endif */
         chksum = NAT_chksum_mod(chksum,    /* Old checksum */
            (uint_16)(ack & 0xFFFF),                   /* Old data */
            (uint_16)(temp &0xFFFF));                  /* New data */
         chksum = NAT_chksum_mod(chksum,    /* Old checksum */
            (uint_16)((ack >> 16) & 0xFFFF),           /* Old data */
            (uint_16)((temp >> 16) & 0xFFFF));         /* New data */
         htonl(transport.TCP_PTR->ack, temp);             /* Replace old ACK with new one */
         htons(transport.TCP_PTR->checksum, chksum);
      } /* Endif */

      return RTCS_OK;
   } /* Endif */

   seq_adj = 0;
   seq = ntohl(transport.TCP_PTR->seq);
   chksum = ntohs(transport.TCP_PTR->checksum);

   /* We can only reach this point is the dest port is FTP command port */
   if (ftp_session_ptr) {

      /* If SEQ > NEXT_SEQ:
      **
      ** We have received an out of order packet. We are expecting a packet with
      ** SEQ == NEXT_SEQ, but we got a higher SEQ number than expected. The adj
      ** to the current packets SEQ number is unknown, and it depends on the
      ** packet with SEQ == NEXT_SEQ (it may or may not be a PORT command). We
      ** can't do anything until we get the previous packet, so we discard and
      ** let TCP retransmit it later.
      */
      if ((int_32)(seq - ftp_session_ptr->NEXT_SEQ) > 0) {
         return (uint_32)RTCS_ERROR;
      } else

      /* If SEQ < LAST_SEQ:
      **
      ** This is a retransmitted packet or one that took a slow path to the
      ** NAT gateway. The outside host has already ACKed this packet, and the
      ** internal host has already properly received the ACK because it has
      ** sent the next FTP command.
      */
      if ((int_32)(seq - ftp_session_ptr->LAST_SEQ) < 0) {
         return (uint_32)RTCS_ERROR;
      } else

      /* If SEQ == NEXT_SEQ:
      **
      ** This is a new packet. Normal scenario.
      */
      if (seq == ftp_session_ptr->NEXT_SEQ) {
         seq_adj = ftp_session_ptr->NEXT_ADJ;
         if (orig_tcp_data_length != 0)  {
            /* Only update if packet is not a pure ACK with no data */
            ftp_session_ptr->LAST_SEQ = seq;
            ftp_session_ptr->LAST_ADJ = seq_adj;
            ftp_session_ptr->NEXT_SEQ = seq + orig_tcp_data_length;
         } /* Endif */
      } else /* Endif */

      /* IF SEQ == LAST_SEQ:
      **
      ** The last command sent is being retransmitted. Let it through, and do
      ** any neccessary PORT command modifications
      */
      if (seq == ftp_session_ptr->LAST_SEQ) {
         seq_adj = ftp_session_ptr->LAST_ADJ;
      }

      /* This is when the SEQ is > LAST but < NEXT */
      else {
         return (uint_32)RTCS_ERROR;   /* Rebuild? */
      } /* Endif */

      temp = seq + seq_adj;

      /* Write new SEQ number to packet */
      chksum = NAT_chksum_mod(chksum,
         (uint_16)(seq & 0xFFFF),
         (uint_16)(temp & 0xFFFF));
      chksum = NAT_chksum_mod(chksum,
         (uint_16)((seq >> 16) & 0xFFFF),
         (uint_16)((temp >> 16) & 0xFFFF));
      htonl(transport.TCP_PTR->seq, temp);
      htons(transport.TCP_PTR->checksum, chksum);
   } /* Endif */

   if (orig_tcp_data_length < 4)  {
      return RTCS_OK;
   } /* Endif */

   /* We send the packet through if we don't have a PORT command */
   if (memcmp(tcp_data_ptr, "PORT", 4)) {
      return RTCS_OK;
   } /* Endif */

   if (!NAT_ALG_detect_port(tcp_data_ptr, orig_tcp_data_length, &addr, &port))  {
      /* This is bad. We only have part of a port command. Toss packet */
      return (uint_32)RTCS_ERROR;
   } /* Endif */

   if (!ftp_session_ptr)  {
      ftp_session_ptr = RTCS_part_alloc(((NAT_FTP_STRUCT_PTR)(alg_cfg_ptr))->FTP_PART_ID);
      if (!ftp_session_ptr)  {
         return RTCSERR_OUT_OF_MEMORY;
      } /* Endif */

      /* Attach to session */
      ftp_session_ptr->HEADER.ALG_TYPE = NAT_ALG_FTP_TYPE;
      ftp_session_ptr->HEADER.NEXT = nat_session_ptr->ALG_INFO_PTR;
      nat_session_ptr->ALG_INFO_PTR = (NAT_SESSION_EXT_STRUCT_PTR)(pointer)ftp_session_ptr;
   } /* Endif */

   /* Create new session for data channel (or find existing session) */
   _mem_copy(ip_header_ptr->DEST, NAT_ALG_FTP_dummy.IP.DEST, 4);
   htonl(NAT_ALG_FTP_dummy.IP.SOURCE, addr);
   htons(NAT_ALG_FTP_dummy.TCP.source_port, port);
   htons(NAT_ALG_FTP_dummy.TCP.dest_port, IPPORT_FTPDATA);

   nat_data_session_ptr = NAT_lookup(&NAT_ALG_FTP_dummy.IP, FALSE, FALSE, &error);

   if (nat_data_session_ptr == NULL) {
      nat_data_session_ptr = NAT_insert(&NAT_ALG_FTP_dummy.IP, &error); 
      if (!nat_data_session_ptr)  {
         return error;
      } /* Endif */
      NAT_event_add(&nat_cfg_ptr->TCP_TOUT, &nat_data_session_ptr->TIMEOUT);
   } /* Endif */

   /* Determine space needed for new PORT information */
   new_tcp_data_length = 5;                     /* "PORT " */
   new_tcp_data_length += 7;                    /* 5 commas and 2 termination bytes */
   addr = nat_data_session_ptr->NAT_HST;
   port = nat_data_session_ptr->NAT_PORT;

   /* Add IP addr len */
   for (i = 0; i < 32; i+=8)  {
      temp = ((addr >> i) & 0xFF);
      new_tcp_data_length += (temp < 10) ? 1 : ((temp < 100) ? 2 : 3);
   } /* Endfor */

   /* Add port len */
   for (i = 0; i < 16; i+=8)  {
      temp = ((port >> i) & 0xFF);
      new_tcp_data_length += (temp < 10) ? 1 : ((temp < 100) ? 2 : 3);
   } /* Endif */

   new_ip_length = ip_header_length + tcp_header_length + new_tcp_data_length;
   if (new_ip_length <= orig_ip_length)  {
      RTCSPCB_shrink(*pcb_ptr_ptr, orig_ip_length - new_ip_length);
   } else {
      new_mqx_pcb_ptr = _mem_alloc_system(sizeof(PCB) + sizeof(PCB_FRAGMENT) + new_ip_length);
      if (!new_mqx_pcb_ptr)  {
         return RTCSERR_OUT_OF_MEMORY;
      } /* Endif */
      new_pcb_data_ptr = (uchar_ptr)new_mqx_pcb_ptr + sizeof(PCB) + sizeof(PCB_FRAGMENT);
      new_mqx_pcb_ptr->FREE = NAT_ALG_ftp_pcb_free;
      new_mqx_pcb_ptr->PRIVATE = NULL;
      new_mqx_pcb_ptr->FRAG[0].LENGTH = new_ip_length;
      new_mqx_pcb_ptr->FRAG[0].FRAGMENT = new_pcb_data_ptr;
      ((PCB_FRAGMENT_PTR)(pointer)(new_mqx_pcb_ptr + 1))->LENGTH = 0;
      ((PCB_FRAGMENT_PTR)(pointer)(new_mqx_pcb_ptr + 1))->FRAGMENT = NULL;

      new_pcb_ptr = RTCSPCB_alloc_recv(new_mqx_pcb_ptr);
      if (!new_pcb_ptr)  {
         _mem_free(new_mqx_pcb_ptr);
         return RTCSERR_OUT_OF_MEMORY;
      } /* Endif */

      RTCSPCB_DATA_NETWORK(new_pcb_ptr) = RTCSPCB_DATA(new_pcb_ptr);

      new_pcb_ptr->TYPE = (*pcb_ptr_ptr)->TYPE;
      new_pcb_ptr->IFSRC = (*pcb_ptr_ptr)->IFSRC;
      new_pcb_ptr->LINK_OPTIONS = (*pcb_ptr_ptr)->LINK_OPTIONS;
      new_pcb_ptr->IP_COMPLETE = IP_complete_recv;

      _mem_copy(ip_header_ptr, new_pcb_data_ptr, ip_header_length + tcp_header_length);

      /*
      ** Update all pointers to the new data
      */
      new_pcb_data_ptr = (pointer)RTCSPCB_DATA(new_pcb_ptr);
      ip_header_ptr = (pointer)new_pcb_data_ptr;
      transport.PTR = TRANSPORT_PTR(ip_header_ptr);
      tcp_data_ptr = &transport.DATA_OFFSET[tcp_header_length];

      RTCSPCB_free(*pcb_ptr_ptr);
      *pcb_ptr_ptr = new_pcb_ptr;
   } /* Endif */

   /* Rewrite data */
   _mem_copy("PORT ", tcp_data_ptr, 5);
   tcp_data_ptr += 5;

   for (i = 24; i >= 0; i-=8)  {
      temp = ((addr >> i) & 0xFF);
      NAT_ALG_ftp_bwrite((uchar)temp, &tcp_data_ptr);
      *tcp_data_ptr++ = ',';
   } /* Endfor */

   temp = ((port >> 8) & 0xFF);
   NAT_ALG_ftp_bwrite((uchar)temp, &tcp_data_ptr);
   *tcp_data_ptr++ = ',';

   temp = port & 0xFF;
   NAT_ALG_ftp_bwrite((uchar)temp, &tcp_data_ptr);
   *tcp_data_ptr++ = '\r';
   *tcp_data_ptr++ = '\n';

   ftp_session_ptr->LAST_SEQ = seq;
   ftp_session_ptr->LAST_ADJ = seq_adj;
   ftp_session_ptr->NEXT_SEQ = seq + orig_tcp_data_length;
   ftp_session_ptr->NEXT_ADJ = seq_adj - orig_tcp_data_length + new_tcp_data_length;

   /* Update IP length */
   chksum = ntohs(ip_header_ptr->CHECKSUM);
   chksum = NAT_chksum_mod(chksum, orig_ip_length, new_ip_length);
   htons(ip_header_ptr->CHECKSUM, chksum);
   htons(ip_header_ptr->LENGTH, new_ip_length);

   /* Calculate TCP checksum */
   NAT_ALG_TCP_checksum(ip_header_ptr);

   return RTCS_OK;
} /* Endbody */

#endif


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/dev_ep_deinit.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dev_ep_deinit.c$
* $Version : 3.8.3.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*  This file contains USB device API specific function to 
* deinitialize the endpoint.
*                                                               
*END*********************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "dev_cnfg.h"
#include "devapi.h"
#include "dev_main.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_deinit_endpoint
*  Returned Value : USB_OK or error code
*  Comments       :
*  Disables the endpoint and the data structures associated with the 
*  endpoint
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_deinit_endpoint
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                    ep_num,
            
      /* [IN] Direction */
      uint_8                    direction
   )
{ /* Body */
   uint_8         error = 0;
   USB_DEV_STATE_STRUCT_PTR      usb_dev_ptr;

   if (handle == NULL)
   {
      return USBERR_ERROR;
   }
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   USB_lock();

   if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
      usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_DEINIT_ENDPOINT != NULL) 
   {
        error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
            usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_DEINIT_ENDPOINT(handle, 
            ep_num, direction);
    
   }
   else
   {
        #if _DEBUG
            printf("_usb_device_deinit_endpoint: DEV_DEINIT_ENDPOINT is NULL\n");                     
        #endif  
        return USBERR_ERROR;
   }
   
   USB_unlock();
   return error;
} 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2s/i2s_ki2s_prv.h<|end_filename|>
#ifndef _i2s_ki2s_prv_h
#define _i2s_ki2s_prv_h 
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2s_ki2s_prv.h$
* $Version : 3.8.4.0$
* $Date    : Aug-20-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the I2S drivers for 54XX Coldfire family.
*
*END************************************************************************/
#include "i2s_ki2s.h"
#include "i2s_audio.h"

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/*
** I2S defaults
*/
#define I2S_DEFAULT_BUFFER_SIZE 64
#define I2S_DEFAULT_DATA_BITS   16
#define I2S_DEFAULT_CHANNEL     0
#define I2S_DEFAULT_MODE        I2S_MODE_MASTER
#define I2S_DEFAULT_CLK_SOURCE  I2S_CLK_INT
/*
** I2S Registers
*/
#define MCF54XX_CCM_MISCCR_SSI0SRC (0x10)
#define MCF54XX_CCM_MISCCR_SSI1SRC (0x20)
#define MCF54XX_CCM_MISCCR_CDRH_SSI0DIV(x) ((x) << 8)
#define MCF54XX_CCM_MISCCR_CDRH_SSI1DIV(x) (x)
/*
** I2S limits
*/
#define SSIDIV_MIN 3
#define SSIDIV_MAX 100
#define BCLK_DIV_MIN 1
#define BCLK_DIV_MAX 4096
#define FIFO_WATERMARK_MAX 15
#define SSI0_SLOT 47
#define SSI1_SLOT 50

//#define I2S_DEBUG 1
#define MEM_TYPE_IO_I2S_INFO_STRUCT 1046
#define MEM_TYPE_IO_I2S_LEFT_BUFFER 1047
#define MEM_TYPE_IO_I2S_RIGHT_BUFFER 1048

/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** I2S software buffer structure
*/
typedef struct ki2s_buffer
{
	/* Pointer to data */
	uint_32_ptr DATA;
	
	/* Buffer size */
	uint_32 SIZE;
	
	/* Data input index */
	uint_32 IN;
	
	/* Data output index */
	uint_32 OUT;
	
	/* Free space in buffer */
	uint_32 SPACE;
		
} KI2S_BUFFER, _PTR_ KI2S_BUFFER_PTR;

/*
**
*/
typedef struct ki2s_dummy_data
{
   /* Pointer to dummy data (sine wave) */
   int_16_ptr DATA;
   
   /* Length in samples of dummy data */
   uint_32 LENGTH;
   
   /* Output index left */
   uint_32 INDEX_L;
   
   /* Output index right */
   uint_32 INDEX_R;
   
} KI2S_DUMMY_DATA, _PTR_  KI2S_DUMMY_DATA_PTR;

/*
** I2S_STATISTICS_STRUCT
** I2S run time statistics structure
*/
typedef struct i2s_statistics_struct_prv
{
    /* Number of I2S interrupts so far */
    uint_32 INTERRUPTS;

    /* FIFO0 underruns */
    uint_32 UNDERRUNS_L;

    /* FIFO1 underruns */
    uint_32 UNDERRUNS_R;

    /* FIFO0 overruns */
    uint_32 OVERRUNS_L;

    /* FIFO1 underruns */
    uint_32 OVERRUNS_R;

    /* Number of valid bytes received (not dummy receives) */
    uint_32 RX_PACKETS;

    /* Number of valid bytes transmitted (not dummy transmits) */
    uint_32 TX_PACKETS;

    /* Number of bytes currently read or wrote - left */
    uint_32 PACKETS_PROCESSED_L;

    /* Number of bytes currently buffered - left */
    uint_32 PACKETS_QUEUED_L;

    /* Number of bytes requested for reading or writing - left */
    uint_32 PACKETS_REQUESTED_L;

    /* Number of bytes currently read or wrote - right */
    uint_32 PACKETS_PROCESSED_R;

    /* Number of bytes currently buffered - right */
    uint_32 PACKETS_QUEUED_R;

    /* Number of bytes requested for reading or writing - right */
    uint_32 PACKETS_REQUESTED_R;

} I2S_STATISTICS_STRUCT_PRV, _PTR_ I2S_STATISTICS_STRUCT_PRV_PTR;

/*
** KI2S_INFO_STRUCT
** I2S run time state information
*/
typedef struct ki2s_info_struct
{  
   /* Current initialized values */
   KI2S_INIT_STRUCT INIT;
   
   I2S_MemMapPtr I2S_PTR;
   
   /* The previous interrupt handler and data */
   void (_CODE_PTR_ OLD_ISR)(pointer);
   pointer  OLD_ISR_DATA;

   /* SSI channel */
   uint_8 CHANNEL;
   
   /* Divider of fsys to create SSI clock*/
   uint_8 MCLK_DIV;
   
   /* Bit clock divider */
   uint_16 BCLK_DIV;
   
   /* Oversampling clock frequency in Hz - only valid when internal clock source
	is selected, ignored otherwise */
   uint_32 MCLK_FREQ;
	
   /* Bit clock frequency in Hz - only valid when internal clock source
	is selected, ignored otherwise */
   uint_32 BCLK_FREQ;

   /* Frame sync frequency in Hz - only valid when internal clock source
	is selected, ignored otherwise */
   uint_32 FS_FREQ;
	
   /* SSI module clock source (only affects I2S master mode) */
   uint_8 CLOCK_SOURCE;
   
   /* I2S mode of operation (master/slave)*/
   uint_8 MODE;
   
   /* I2S I/O mode (write/read) */
   uint_8 IO_MODE;
   
   /* Audio data input/output format */
   AUDIO_DATA_FORMAT IO_FORMAT;
   
   /* Transmit I2S clocks and dummy data when buffer is empty */
   boolean TX_DUMMY;
   
   /* Number of valid data bits */
   uint_8 DATA_BITS;
   
   /* Transmission in progress */
   boolean ONTHEWAY;

   /* Pointer to the buffer to use for current data - left */
   KI2S_BUFFER BUFFER_L;
   
   /* Pointer to the buffer to use for current data - right */
   KI2S_BUFFER BUFFER_R;
   
   /* Transmission statistics */
   I2S_STATISTICS_STRUCT_PRV STATS;
   
   /* Data for dummy transmission*/
   KI2S_DUMMY_DATA DUMMY;
   
   /* Pointer to data that are going to be processed in left channel*/
   char_ptr DATA_L;
   
   /* Pointer to data that are going to be processed in right channel*/ 
   char_ptr DATA_R;
   
   /* Event signaling finished read/write operation */
   LWSEM_STRUCT EVENT_IO_FINISHED;
   
   /* Clock state when no tx/rx */
   boolean CLK_ALWAYS_ON;
   
   /* First Input/Output operation */
   boolean FIRST_IO;
   
   /* Mask for receive interrupts enabling/disabling*/
   uint_32 RX_INT_MASK;
   
   /* Mask for transmitt interrupts enabling/disabling*/
   uint_32 TX_INT_MASK;
   
} KI2S_INFO_STRUCT, _PTR_ KI2S_INFO_STRUCT_PTR;

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/iproute.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008-2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iproute.c$
* $Version : 3.8.14.0$
* $Date    : Sep-19-2012$
*
* Comments:
* 
*     This file contains the interface to the IP routing table.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_IP4  

#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "route.h"


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_init
*  Returned Value : void
*  Comments       :
*        Initializes the head of the routing table.
*
*END*-----------------------------------------------------------------*/

void IP_route_init
   (
      IP_ROUTE_PTR   head     /* Pointer to the head of the IPRADIX tree */
   )
{ /* Body */
   IPRADIX_init(&head->NODE);
   head->DIRECT = NULL;
   head->INDIRECT = NULL;
   head->VIRTUAL = NULL;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_insert
*  Returned Value : void
*  Comments       :
*        Adds a route to the routing table. Called by IPRADIX_insert.
*
*END*-----------------------------------------------------------------*/

struct ip_route_insert {
   uint_32           error;
   pointer           route;
   uint_32           index;
   void (_CODE_PTR_  sort)(pointer, pointer);
};

static void IP_route_insert
   (
      pointer _PTR_  node,
      pointer        data
   )
{ /* Body */
   struct ip_route_insert _PTR_     insertdata = data;
   IP_ROUTE_PRV_PTR                 route;
   IP_ROUTE_DIRECT_PTR              new_route = insertdata->route;
   uint_32                          i = insertdata->index;

   /* Make sure the node is initialized */
   if (!*node) {
      *node = node;
      _mem_zero(((IP_ROUTE_PRV_PTR)*node)->ROUTETYPE, sizeof(route->ROUTETYPE));
   } /* endif */

   route = *node;
   if (!route->ROUTETYPE[i]) {
      new_route->NEXT = new_route;
      route->ROUTETYPE[i] = new_route;
   } else if (insertdata->sort) {
      insertdata->sort(&route->ROUTETYPE[i], new_route);
   } else {
      new_route->NEXT = route->ROUTETYPE[i]->NEXT;
      route->ROUTETYPE[i]->NEXT = new_route;
   } /* Endif */

   insertdata->error = RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_delete
*  Returned Value : void
*  Comments       :
*        Removes a route from the IP routing table. Called by IPRADIX_insert.
*
*END*-----------------------------------------------------------------*/

struct ip_route_delete {
   uint_32              index;
   boolean (_CODE_PTR_  test)(pointer, pointer);
   pointer              data;
   IP_ROUTE_FN_PTR      fn;
};

static void IP_route_delete
   (
      pointer _PTR_  node,   /* ptr to address of the IPRADIX_NODE DATA ptr */
      pointer        data    /* ptr to data that can ID node to be deleted  */
   )
{ /* Body */
   IP_ROUTE_PRV_PTR                    route = *node;
   IP_ROUTE_DIRECT_PTR                 tmp_ptr, search_ptr;
   struct ip_route_delete _PTR_        remdata = data;
   uint_32                             i = remdata->index;
   IP_ROUTE_FN_PTR                     fn;

   if (route && route->ROUTETYPE[i]) {  /* Make sure the node is valid */

      /*
      ** Search the circular list for the correct node.
      ** tmp_ptr will always point to the node BEFORE search_ptr
      */
      tmp_ptr = route->ROUTETYPE[i];
      search_ptr = tmp_ptr->NEXT;
      do {

         if (remdata->test(search_ptr, remdata->data)) {
            tmp_ptr->NEXT = search_ptr->NEXT;    /* De-thread the node */
            if (route->ROUTETYPE[i] == search_ptr) {
               /* Update head if needed */
               route->ROUTETYPE[i] = search_ptr->NEXT;
            } /* Endif */
            if (route->ROUTETYPE[i] == search_ptr) {
               /* There is 1 node */
               route->ROUTETYPE[i] = NULL;
               if (route->ROUTETYPE[0] == NULL &&
                   route->ROUTETYPE[1] == NULL &&
                   route->ROUTETYPE[2] == NULL)
               {
                  *node = NULL;                  /* Free data ptr if needed */
               } /* Endif */
            } /* Endif */
            for (fn = remdata->fn; fn; fn = fn->NEXT) {
               fn->REM_RT((IP_ROUTE_INDIRECT_PTR)search_ptr);
            } /* Endfor */
            RTCS_part_free(search_ptr);
            break;
         } /* Endif */

         /* Move on to the next node */
         tmp_ptr = search_ptr;
         search_ptr = search_ptr->NEXT;
      } while (search_ptr != route->ROUTETYPE[i]->NEXT);
   } /* Endif */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_add_direct
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Adds a direct route to the IP routing table. Assumes the
*        address, netmask and interfaces are valid.
*
*END*-----------------------------------------------------------------*/

uint_32 IP_route_add_direct
   (
      _ip_address    address,    /* Address or network address of destif   */
      _ip_address    netmask,    /* Mask for the address parameter         */
      IP_IF_PTR      netif,      /* Interface for incomming packets        */
      IP_IF_PTR      destif      /* Interface for outgoing packets         */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR             IP_cfg_ptr = RTCS_getcfg(IP);
   IP_ROUTE_DIRECT_PTR           route;
   IP_ROUTE_FN_PTR               fn;
   struct ip_route_insert        insertdata;

   route = RTCS_part_alloc(IP_cfg_ptr->ROUTE_PARTID);
   if (!route) {
      return RTCSERR_IP_ROUTE_ALLOC;
   } /* Endif */

   route->ADDRESS       = address;
   route->NETIF         = netif;
   route->DESTIF        = destif;
   route->FLAGS         = RTF_STATIC | RTF_UP;

   insertdata.error = RTCSERR_IP_ROUTE_ALLOC;
   insertdata.route = route;
   insertdata.index = 0;
   insertdata.sort = NULL;

   IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, address & netmask, netmask,
                  IP_cfg_ptr->RADIX_PARTID,
                  IP_route_insert, &insertdata);

   if (insertdata.error) {
      RTCS_part_free(route);
   } else if (!~netmask) {
      ROUTE_new_bindif(route);   /* If the route is a leaf (has a full IP) */
   } else if (route->DESTIF != RTCS_IF_LOCALHOST_PRV) {
      fn = IP_cfg_ptr->ROUTE_FN; /* If the route is a network connection */
      while (fn) {
         fn->INIT_RT((IP_ROUTE_INDIRECT_PTR)((void _PTR_)route), 0);
         fn = fn->NEXT;
      } /* Endwhile */
   } /* Endif */

   return insertdata.error;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_remove_direct
*  Returned Value : void
*  Comments       :
*        Removes a direct route from the IP routing table, if the node
*        is present.
*
*END*-----------------------------------------------------------------*/

struct ip_route_remove_direct {
   _ip_address          ipaddress;
   IP_IF_PTR            netif;
};

static boolean IP_route_delete_direct_test
   (
      pointer     routeptr,
      pointer     dataptr
   )
{ /* Body */
   IP_ROUTE_DIRECT_PTR                    route = routeptr;
   struct ip_route_remove_direct _PTR_    data  = dataptr;

   return (route->ADDRESS == data->ipaddress && route->NETIF == data->netif);
} /* Endbody */

void IP_route_remove_direct
   (
      _ip_address    address,    /* IP address of route to remove    */
      _ip_address    netmask,    /* IP netmask of route to remove    */
      IP_IF_PTR      netif       /* pointer to the route interface   */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR                IP_cfg_ptr = RTCS_getcfg(IP);
   struct ip_route_remove_direct    removedata;
   struct ip_route_delete           deldata;

   removedata.ipaddress = address;
   removedata.netif     = netif;

   deldata.data = &removedata;
   deldata.index = 0;
   deldata.test = IP_route_delete_direct_test;
   deldata.fn = IP_cfg_ptr->ROUTE_FN;
  
   IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, address & netmask, netmask,
                  0, IP_route_delete, &deldata);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_add_indirect
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Adds an indirect route to the IP routing table. Assumes the
*        address and netmask are valid. The caller has to set flag to
*        RTF_STATIC if ipif_bind or RTF_REDIRECT if icmpredirect.
*
*END*-----------------------------------------------------------------*/

static void IP_route_add_indirect_sort
   (
      pointer       head,
      pointer       new_node
   )
{ /* Body */
   IP_ROUTE_INDIRECT_PTR _PTR_      head_ptr = head;
   IP_ROUTE_INDIRECT_PTR            node = new_node, search = *head_ptr, last;
   IP_CFG_STRUCT_PTR                IP_cfg_ptr = RTCS_getcfg(IP);
   IP_ROUTE_FN_PTR                  fn;

   search = *head_ptr;

   /*
   ** Check if there is non static route here. Remove it if there is because
   ** static routes take precedence over dynamic routes. This function is only
   ** called if there is already a node, and if this node is a dynamic node
   ** there will only be one. We can simply replace it with the new node.
   */
   if (!(search->FLAGS & RTF_STATIC)) {
      for (fn = IP_cfg_ptr->ROUTE_FN; fn; fn = fn->NEXT) {
         fn->REM_RT(search);
      } /* Endfor */
      RTCS_part_free(search);
      *head_ptr = node;
      return;
   } /* Endif */

   /* Find the place to insert the new node */
   last = NULL;
   while (search->METRIC < node->METRIC) {
      last = search;
      search = search->NEXT;
      if (search == *head_ptr) {
         break;
      } /* Endif */
   } /* Endwhile */

   /*
   ** At this point we found the place to insert. We need to special case
   ** insertion into the front of the list, but the other cases are easy.
   */
   if (!last) {
      /*
      ** The new node has to be the first in the list. We need a pointer to the
      ** last element in the list to complete the insertion. The following
      ** insertion works for any number of nodes.
      */
      last = search->NEXT;
      while (last->NEXT != search) {
         last = last->NEXT;
      } /* Endwhile */

      /* Update the head_ptr to point to the new node */
      *head_ptr = node;
   } /* Endif */

   /* Link in the new node */
   node->NEXT = search;
   last->NEXT = node;

   return;
} /* Endbody */

#if RTCSCFG_ENABLE_GATEWAYS
uint_32 IP_route_add_indirect
   (
      _ip_address    address,    /* Gateway address */
      _ip_address    netmask,    /* Network mask    */
      _ip_address    network,    /* Network address */
      uint_32        flag,       /* [IN] RTF_* */
      uint_16        metric      /* [IN] the route metric [0,65535] */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR                IP_cfg_ptr = RTCS_getcfg(IP);
   IP_ROUTE_INDIRECT_PTR            route;
   struct ip_route_insert           insertdata;
   IP_ROUTE_FN_PTR                  fn;

   route = RTCS_part_alloc(IP_cfg_ptr->GATE_PARTID);
   if (!route) {
      return RTCSERR_IP_GATE_ALLOC;
   } /* Endif */

   route->GATEWAY    = address;
   route->FLAGS      = flag | RTF_UP;
   route->IS_DIRECT  = NULL;
   route->METRIC     = metric;

   insertdata.error = RTCSERR_IP_GATE_ALLOC;
   insertdata.route = route;
   insertdata.index = 1;
   insertdata.sort = IP_route_add_indirect_sort;

   IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, network & netmask, netmask,
                  IP_cfg_ptr->RADIX_PARTID,
                  IP_route_insert, &insertdata);

   if (insertdata.error) {
      RTCS_part_free(route);
   } else  {
      fn = IP_cfg_ptr->ROUTE_FN;
      while (fn) {
         fn->INIT_RT(route, metric);
         fn = fn->NEXT;
      } /* Endwhile */
   } /* Endif */

   return insertdata.error;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_remove_indirect
*  Returned Value : void
*  Comments       :
*        Removes one or all indirect routes from the IP routing table,
*        if the node is present.
*
*END*-----------------------------------------------------------------*/

static void IP_route_delete_indirect_all
   (
      pointer _PTR_  node,   /* ptr to address of the IPRADIX_NODE DATA ptr */
      pointer        data    /* ptr to the gateway address to be removed    */
   )
{ /* Body */
   IP_ROUTE_PTR            route = *node;
   IP_ROUTE_INDIRECT_PTR   tmp_ptr, search_ptr;
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   IP_ROUTE_FN_PTR         fn;

   if (route && route->INDIRECT) {  /* Make sure the node is valid */

      search_ptr = route->INDIRECT->NEXT; /* search with next element */
      tmp_ptr = search_ptr->NEXT;
      /* if we  have only one elment while loop will not execute */
      while (search_ptr != route->INDIRECT) {
         for (fn = IP_cfg_ptr->ROUTE_FN; fn; fn = fn->NEXT) {
            fn->REM_RT(search_ptr);
         } /* Endfor */
         RTCS_part_free(search_ptr);
         search_ptr = tmp_ptr;
         tmp_ptr = search_ptr->NEXT;
      } /* Endwhile */
      /* Free the first element */
      for (fn = IP_cfg_ptr->ROUTE_FN; fn; fn = fn->NEXT) {
         fn->REM_RT(search_ptr);
      } /* Endfor */
      RTCS_part_free(search_ptr);
      if (route->DIRECT == NULL && route->VIRTUAL == NULL) {
         *node = NULL;                   /* Free data ptr if needed */
      } else {
         route->INDIRECT = NULL;
      } /* Endif */
   } /* Endif */

} /* Endbody */

static boolean IP_route_delete_indirect_test
   (
      pointer         routeptr,
      pointer         dataptr
   )
{ /* Body */
   IP_ROUTE_INDIRECT_PTR     route = routeptr;
   struct {
      _ip_address       gate;
      uint_32           flag;
      uint_16           metric;
   } _PTR_ testdata = dataptr;

   return (route->GATEWAY == testdata->gate &&
           (route->FLAGS & testdata->flag) == testdata->flag &&
           route->METRIC == testdata->metric);
} /* Endbody */

void IP_route_remove_indirect
   (
      _ip_address    gateway,    /* Gateway address   */
      _ip_address    netmask,    /* Network mask      */
      _ip_address    network,    /* Network address   */
      uint_32        flag,       /* [IN] RTF_* */
      uint_16        metric      /* [IN] the route metric [0,65535] */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   struct ip_route_delete  deldata;
   struct {
      _ip_address       gate;
      uint_32           flag;
      uint_16           metric;
   } testdata;

   if (gateway) {
      testdata.gate = gateway;
      testdata.flag = flag;
      testdata.metric = metric;

      deldata.index = 1;
      deldata.data = &testdata;
      deldata.test = IP_route_delete_indirect_test;
      deldata.fn = IP_cfg_ptr->ROUTE_FN;

      IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, network & netmask, netmask,
                    0, IP_route_delete, &deldata);
   } else {
      IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, network & netmask, netmask,
                     0, IP_route_delete_indirect_all, &gateway);
   } /* Endif */

} /* Endbody */
#endif

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_add_virtual
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Adds a virtual route to the IP routing table. Assumes the
*        address, netmask and interfaces are valid.
*
*END*-----------------------------------------------------------------*/

uint_32 IP_route_add_virtual
   (
      _ip_address   address,        /* Destination address              */
      _ip_address   netmask,        /* Mask for the address parameter   */
      _ip_address   source,         /* Source address for interface     */
      _ip_address   source_net,     /* Allowed source network           */
      _ip_address   source_mask,    /* Allowes source network mask      */
      IP_IF_PTR     destif,         /* Interface for outgoing packets   */
      pointer       data            /* Route information                */
   )
{ /* Body */
#if RTCSCFG_ENABLE_VIRTUAL_ROUTES
   IP_CFG_STRUCT_PTR                IP_cfg_ptr = RTCS_getcfg(IP);
   IP_ROUTE_VIRTUAL_PTR             route;
   struct ip_route_insert           insdata;
   IP_ROUTE_FN_PTR                  fn;

   route = RTCS_part_alloc(IP_cfg_ptr->VIRTUAL_PARTID);
   if (!route) {
      return RTCSERR_IP_VIRTUAL_ALLOC;
   } /* Endif */

   route->ADDRESS       = source;
   route->IS_DIRECT     = NULL;
   route->DESTIF        = destif;
   route->FLAGS         = RTF_STATIC | RTF_UP;
   route->SOURCE_NET    = source_net;
   route->SOURCE_MASK   = source_mask;
   route->DATA          = data;

   insdata.error = RTCSERR_IP_VIRTUAL_ALLOC;
   insdata.route = route;
   insdata.index = 2;
   insdata.sort = NULL;

   IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, address & netmask, netmask,
                  IP_cfg_ptr->RADIX_PARTID, IP_route_insert, &insdata);

   if (insdata.error) {
      RTCS_part_free(route);
   } else if (!~netmask) {
      fn = IP_cfg_ptr->ROUTE_FN;
      while (fn) {
         fn->INIT_RT((IP_ROUTE_INDIRECT_PTR)route, 0);
         fn = fn->NEXT;
      } /* Endwhile */
   } /* Endif */

   return insdata.error;
#else
      return RTCSERR_IP_VIRTUAL_ALLOC;
#endif
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_remove_virtual
*  Returned Value : void
*  Comments       :
*        Removes a virtual route from the IP routing table, if the node
*        is present.
*
*END*-----------------------------------------------------------------*/

struct ip_route_remove_virtual {
   _ip_address          source;
   _ip_address          source_net;
   _ip_address          source_mask;
   IP_IF_PTR            netif;
};

static boolean IP_route_delete_virtual_test
(
      pointer    routeptr,
      pointer    dataptr
   )
{ /* Body */
   IP_ROUTE_VIRTUAL_PTR                    route = routeptr;
   struct ip_route_remove_virtual _PTR_    data  = dataptr;

   return (route->ADDRESS == data->source &&
           route->SOURCE_NET == data->source_net &&
           route->SOURCE_MASK == data->source_mask &&
           route->DESTIF == data->netif);
} /* Endbody */

void IP_route_remove_virtual
   (
      _ip_address    address,       /* IP address of route to remove    */
      _ip_address    netmask,       /* IP netmask of route to remove    */
      _ip_address    source,        /* IP of interface                  */
      _ip_address    source_net,    /* Allowed source network           */
      _ip_address    source_mask,   /* Allowed source source netmak     */
      IP_IF_PTR      netif          /* pointer to the route interface   */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR                 IP_cfg_ptr = RTCS_getcfg(IP);
   struct ip_route_remove_virtual    removedata;
   struct ip_route_delete            deldata;

   removedata.source       = source;
   removedata.source_net   = source_net;
   removedata.source_mask  = source_mask;
   removedata.netif        = netif;

   deldata.data = &removedata;
   deldata.index = 2;
   deldata.test = IP_route_delete_virtual_test;
   deldata.fn = IP_cfg_ptr->ROUTE_FN;

   IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, address & netmask, netmask,
                  0, IP_route_delete, &deldata);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_local
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Decides whether or not to keep a packet.
*
*END*-----------------------------------------------------------------*/

struct ip_route_local_test {
   IP_IF_PTR   ifdest;
   _ip_address ipdest;
   RTCSPCB_PTR pcb;
};

static boolean IP_route_local_test
   (
      pointer  node,
      pointer  data
   )
{ /* Body */
   struct ip_route_local_test _PTR_ testdata = data;
   IP_ROUTE_PTR                     route = node;
   IP_ROUTE_DIRECT_PTR              search_ptr = route->DIRECT;
   _ip_address                      ip_bcast;

   /* Don't process IP unicast packets without link-layer unicast bit set */
   if (!~route->NODE.MASK && !(testdata->pcb->TYPE & RTCSPCB_TYPE_UNICAST)) {
      return TRUE;
   } /* Endif */

#if RTCSCFG_IP_DISABLE_DIRECTED_BROADCAST
   /*
   ** This node matches a unicast address if MASK == 0xFFFFFFFF, and a
   ** directed broadcast if MASK != 0xFFFFFFFF.  Here we return IP_UNREACH
   ** for directed broadcast packets.
   */
   if (~route->NODE.MASK) {
      return TRUE;
   } /* Endif */
#endif

   /* Calculate this route's broadcast address */
   ip_bcast = route->NODE.IP | ~route->NODE.MASK;

   if (search_ptr) {
      do {
         /*
         ** 1. Only check interfaces on which the packet was received, unless
         **    IP_forwarding is enabled.
         ** 2. Accept broadcast, or unicast packets with destinations that
         **    match node address.
         */
         if ((testdata->pcb->IFSRC == search_ptr->NETIF || _IP_forward) &&
             (testdata->ipdest == ip_bcast))
         {
            testdata->ifdest = search_ptr->DESTIF;
            return TRUE;
         } /* Endif */

         search_ptr = search_ptr->NEXT;
      } while (search_ptr != route->DIRECT);
   } /* Endif */

   return FALSE;
} /* Endbody */

uint_32 IP_route_local
   (
      RTCSPCB_PTR    pcb,
            /* [IN] the packet to send */
      _ip_address    ipdest
            /* [IN] the ultimate destination */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR          IP_cfg_ptr = RTCS_getcfg(IP);
   struct ip_route_local_test testdata;

   /* 
   ** RFC 2131 says:
   ** "In the case of a client using DHCP for initial configuration (before
   ** the client's TCP/IP software has been completely configured), DHCP
   ** requires creative use of the client's TCP/IP software and liberal
   ** interpretation of RFC 1122.  The TCP/IP software SHOULD accept and
   ** forward to the IP layer any IP packets delivered to the client's
   ** hardware address before the IP address is configured."
   **
   ** So if the broadcast flag is disabled, we check, and if the packet's 
   ** source interface is not bound, we send the packet to IF_LOCALHOST.
   ** This is paired with the same test in ip.c:IP_service(), which sends 
   ** the packet here.
   */
   if ((ipdest == INADDR_BROADCAST) 
       || IN_MULTICAST(ipdest)
       || (!_DHCP_broadcast && (IP_get_ipif_addr(pcb->IFSRC) == INADDR_ANY))) { 
      /* Accept broadcasts and multicasts and unbound unicasts */
      testdata.ifdest = RTCS_IF_LOCALHOST_PRV;
   } else {

      /* If unicast, check routing table */
      testdata.ifdest = NULL;
      testdata.ipdest = ipdest;
      testdata.pcb    = pcb;
      IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, ipdest,
                       IP_route_local_test, &testdata);
   } /* Endif */

   /* Send the packet to the interface. */
   if (testdata.ifdest) {
      return IP_send_dgram( RTCS_IF_LOCALHOST_PRV, pcb, 0, ipdest, ipdest, 0, NULL);
   } /* Endif */

   /* No interface was found. Discard the packet */
   IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
   IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_ADDR_ERRORS++);
   RTCSLOG_PCB_FREE(pcb, RTCSERR_IP_UNREACH);
   RTCSPCB_free(pcb);
   return RTCSERR_IP_UNREACH;

} /* Endbody */





/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_multi
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Chooses one or more routes for a multicast or limited broadcast
*        packet and sends it.  Note:  at the very least, the packet will
*        be sent up to the localhost's transport layer.
*
*END*-----------------------------------------------------------------*/

struct ip_route_multi_struct {
   RTCSPCB_PTR pcb;
   uint_32     protocol;
   _ip_address ipsrc;
   _ip_address ipdest;
   uint_32     flags;
};

static boolean IP_route_multi_test
   (
      _ip_address node_ip,
      _ip_address node_mask,
      pointer     node_data,
      pointer     data
   )
{ /* Body */
   IP_CFG_STRUCT_PTR                   IP_cfg_ptr = RTCS_getcfg(IP);
   struct ip_route_multi_struct _PTR_  testdata = data;
   IP_ROUTE_PTR                        route = node_data;
   IP_ROUTE_DIRECT_PTR                 direct;
   IP_ROUTE_VIRTUAL_PTR                virtual;
   _ip_address                         ip_bcast;
   RTCSPCB_PTR                         dup_pcb;

   if (!route) {
      return FALSE;
   } /* Endif */

   /* Calculate this route's broadcast address */
   ip_bcast = node_ip | ~node_mask;

   direct = route->DIRECT;
   if (direct) {
      do {
         /* Note:
         ** 1. The packet is sent to LOCALHOST in IP_route_multi.
         ** 2. The source address must match one of the interface's address(es).
         ** 3. If the source address is broadcast or if it is specified, use
         **    this interface.
         */
         if (direct->DESTIF != RTCS_IF_LOCALHOST_PRV &&
             (testdata->ipsrc == INADDR_ANY ||
              testdata->ipsrc == INADDR_BROADCAST ||
              testdata->ipsrc == ip_bcast ||
              testdata->ipsrc == direct->ADDRESS))
         {
            /*
            ** Make sure not to send the packet back to the interface it was
            ** received on.
            */
            if (!(testdata->flags & IPROUTEOPT_RECVIF) ||
               (testdata->pcb->IFSRC != direct->DESTIF))
            {
               /* We've chosen an interface. Duplicate the PCB and send it */
               dup_pcb = RTCSPCB_alloc_dup(testdata->pcb);
               if (dup_pcb) {
                  //RTCSLOG_PCB_ALLOC(dup_pcb);
                  IP_send_dgram(direct->DESTIF, dup_pcb, direct->ADDRESS,
                     testdata->ipdest, testdata->ipdest, testdata->protocol,
                     NULL);
               } else {
                  IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
               } /* Endif */
            } /* Endif */
         } /* Endif */

         direct = direct->NEXT;
      } while (direct != route->DIRECT);
   } /* Endif */

   virtual = route->VIRTUAL;
   if (virtual) {
      do {
         /*
         ** This section is similar to the direct route case above.
         ** However, we only want to send to numbered interfaces.
         */
         if (virtual->DESTIF != RTCS_IF_LOCALHOST_PRV &&
             virtual->ADDRESS &&
             (testdata->ipsrc == INADDR_ANY ||
              testdata->ipsrc == INADDR_BROADCAST ||
              testdata->ipsrc == virtual->ADDRESS))
         {
            /*
            ** Make sure not to send the packet back to the interface it was
            ** received on.
            */
            if (!(testdata->flags & IPROUTEOPT_RECVIF) ||
               (testdata->pcb->IFSRC != virtual->DESTIF))
            {
               /* We've chosen an interface. Duplicate the PCB and send it */
               dup_pcb = RTCSPCB_alloc_dup(testdata->pcb);
               if (dup_pcb) {
                  //RTCSLOG_PCB_ALLOC(dup_pcb);
                  IP_send_dgram(virtual->DESTIF, dup_pcb, virtual->ADDRESS,
                     testdata->ipdest, testdata->ipdest, testdata->protocol,
                     NULL);
               } else {
                  IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
               } /* Endif */
            } /* Endif */
         } /* Endif */

         virtual = virtual->NEXT;
      } while (virtual != route->VIRTUAL);
   } /* Endif */

   return FALSE;
} /* Endbody */

uint_32 IP_route_multi
   (
      RTCSPCB_PTR    pcb,
            /* [IN] the packet to send */
      uint_32        protocol,
            /* [IN] the transport layer protocol */
      _ip_address    ipsrc,
            /* [IN] the destination interface (0 = any) */
      _ip_address    ipdest,
            /* [IN] the ultimate destination */
      uint_32        flags
            /* [IN] optional flags */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR             IP_cfg_ptr = RTCS_getcfg(IP);
   struct ip_route_multi_struct  testdata;

   testdata.pcb      = pcb;
   testdata.protocol = protocol;
   testdata.ipsrc    = ipsrc;
   testdata.ipdest   = ipdest;
   testdata.flags    = flags;

   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, IP_route_multi_test, &testdata);

   /*
   ** At this point, we've sent the packet out each interface it's
   ** intended for.  Only the local host is left.
   */

   if ((flags & IPROUTEOPT_RECVIF) &&
      (pcb->IFSRC == RTCS_IF_LOCALHOST_PRV))
   {
      RTCSLOG_PCB_FREE(pcb, RTCS_OK);
      RTCSPCB_free(pcb);
      return RTCS_OK;
   } /* Endif */

   return IP_send_dgram( RTCS_IF_LOCALHOST_PRV, pcb, INADDR_LOOPBACK,
      ipdest, ipdest, protocol, NULL);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Chooses a route for a packet and sends it.  Note:  this
*        includes sending the packet up to the localhost's transport
*        layer (by choosing ifdest == RTCS_IF_LOCALHOST_PRV).
*
*END*-----------------------------------------------------------------*/

struct ip_route_struct {
   RTCSPCB_PTR pcb;
   _ip_address ipsrc;
   _ip_address ipdest;
   uint_32     flags;

   uint_32     retval;
   boolean     check_gateway;
   IP_IF_PTR   ifdest;
   _ip_address hopdest;
   _ip_address hopsrc;
   RTCSPCB_PTR keep_pcb;

   boolean     sendit;   /* Should we send out the packet ? */
   boolean     keepit;   /* Should we send a copy to the localhost ? */
   boolean     hopsrcislocal;
   pointer     data;     /* Routing entry data */
};

static boolean IP_route_test
   (
      pointer     node_data,
      pointer     data
   )
{ /* Body */
   IP_CFG_STRUCT_PTR                IP_cfg_ptr = RTCS_getcfg(IP);
   struct ip_route_struct _PTR_     testdata = data;
   IP_ROUTE_PTR                     route = node_data;
   IP_ROUTE_DIRECT_PTR              direct = route->DIRECT;
   IP_ROUTE_INDIRECT_PTR            indirect = route->INDIRECT;
   IP_ROUTE_VIRTUAL_PTR             virtual = route->VIRTUAL;
   _ip_address                      ip_bcast, source;

   if (direct) {

      /* Calculate this route's broadcast address */
      ip_bcast = route->NODE.IP | ~route->NODE.MASK;

      /* Reject a packet with a destination of 0 for the host IP */
      if (~route->NODE.MASK && testdata->ipdest == route->NODE.IP) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_DISCARDED++);
         return TRUE;
      } /* Endif */

      do {
         /* source address must match (one of) the interface's address(es) */
         if (testdata->hopsrc == INADDR_ANY||
             testdata->hopsrc == INADDR_BROADCAST ||
             testdata->hopsrc == ip_bcast ||
             testdata->hopsrc == direct->ADDRESS ||
             _IP_forward)
         {
            /*
            ** At this point we've chosen an interface.
            ** Now decide whether destination is unicast or
            ** directed broadcast.
            */

            /* Use this interface's source address if we don't have one */
            if (!testdata->hopsrcislocal) {
               testdata->hopsrc = direct->ADDRESS;
            } /* Endif */

            /*
            ** Decide if we should send a copy to the local host. We want to
            ** send a copy to the local host if it is a directed broadcast.
            */
            testdata->keepit = (~route->NODE.MASK && testdata->ipdest == ip_bcast);
            testdata->sendit = TRUE;

#if RTCSCFG_IP_DISABLE_DIRECTED_BROADCAST
            if (testdata->keepit) {
               /*
               ** If this is a directed broadcast, discard it.  Don't even
               ** keep a copy for the localhost.
               */
               testdata->keepit = FALSE;
               testdata->sendit = FALSE;
            } /* Endif */
#endif

            /*
            ** IPROUTEOPT_RECVIF means that we must not send the packet
            ** out the interface it was received on.  This is turned on
            ** when we receive a broadcast (because everyone on that
            ** network already received a copy), and also when originating
            ** a packet with the MSG_NOLOOP flag.
            */
            if (testdata->flags & IPROUTEOPT_RECVIF) {
               if (testdata->keepit) {
                  /*
                  ** If broadcast packet, set hopdest to INADDR_BROADCAST. 
                  */
                  testdata->hopdest = INADDR_BROADCAST;
               } /* Endif */
               testdata->keepit = testdata->keepit && (testdata->pcb->IFSRC != RTCS_IF_LOCALHOST_PRV);
               testdata->sendit = testdata->sendit && (testdata->pcb->IFSRC != direct->DESTIF);
            } /* Endif */

            /*
            ** This #if is purely for code size reduction.  If directed
            ** broadcasts are disabled, keepit will always be false.
            */
#if !RTCSCFG_IP_DISABLE_DIRECTED_BROADCAST

            if (testdata->keepit) {

               /*
               ** If keepit and sendit:
               **
               ** We will need two PCB's. One to send out of the interface and
               ** one to send up to the localhost. The packet is being sent to both
               ** interfaces because it is a broadcast packet, so we set hopdest to
               ** INADDR_BROADCAST. We also set the destif to the network interface
               ** and we don't bother saving a pointer to the locahost interface
               ** because it is already accessible in the IP_CFG_STRUCT.
               */
               if (testdata->sendit) {
                  testdata->ifdest = direct->DESTIF;
                  testdata->hopdest = INADDR_BROADCAST;

                  testdata->keep_pcb = RTCSPCB_alloc_dup(testdata->pcb);
                  if (!testdata->keep_pcb) {
                     IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
                  } /* Endif */
               } /* Endif */

               /* If keepit and !sendit:
               **
               ** This means that a direct broadcast was received, and the network
               ** it was received from is the destination network.
               ** eg: The packet is received from an interface connected to a
               ** network 192.168.1.0 and the packet destination is 192.168.1.255
               ** If it was received on its destination network everybody on that
               ** network also received a copy. There is no reason to send it back
               ** out, so we send it to the localhost only.
               ** The packet was a broadcast packet, so hopdest = INADDR_BROADCAST.
               ** But IP_route will know this if keepit is true, so we don't bother
               ** setting hopdest.
               */
               else {
                  testdata->keep_pcb = testdata->pcb;
               } /* Endif */

            } else
#endif

            /* If !keepit and sendit:
            **
            ** This is the case when we receive a unicast packet. We simply send
            ** it out of the chosen interface (set ifdest). We could be sending
            ** this packet directly to the destination, or we could be sending
            ** it to a gateway. If we are sending it to a gateway, hopdest is
            ** already set to the address of the gateway, so we don't modify it.
            ** Otherwise, if we are sending directly to the destination, set
            ** hopdest to the destination IP.
            */
            if (testdata->sendit) {
               testdata->ifdest = direct->DESTIF;
               if (!testdata->hopdest) {
                  testdata->hopdest = testdata->ipdest;
               } /* Endif */
            } /* Endif */

            /* If !keepit and !sendit:
            **
            ** Do nothing, and IP_route will silently discard the packet.
            */
            else { } /* Endif */

            /* Use a different interface next time */
            route->DIRECT = route->DIRECT->NEXT;
            testdata->retval = RTCS_OK;
            return TRUE;
         } /* Endif */

         direct = direct->NEXT;
      } while(direct != route->DIRECT);
   } /* Endif */

   /*
   ** Reaching this point means that the destination isn't directly connected
   ** to us. Check for a virtual route (tunnel, unnumbered interface or other).
   ** Only send packets out of interfaces, never directly to localhost
   */

   if (virtual && !(testdata->flags & IPROUTEOPT_NOVIRTUAL)) {

      /*
      ** If we are forwarding the packet, ipsrc is set to the source address
      ** of the IP header. If we are originating a packet, hopsrc is set to the
      ** IP address of the local originating interface
      */
      source = testdata->ipsrc ? testdata->ipsrc : testdata->hopsrc;

      do {
         /*
         ** The following THREE conditions must be TRUE:
         **
         ** 1. One of the following:
         **       a) source address must be INADDR_ANY (means pick the source of
         **          the interface), OR
         **       b) source address must be INADDR_BROADCAST, in which case the
         **          IP source address becomes the source of the interface, OR
         **       c) the source address matches the interface address, OR
         **       d) IP forwarding is enabled
         **
         ** 2. If we are not forwarding a packet, the local hop source must be
         **    specified (hopsrc != INADDR_ANY) or the interface must have a
         **    source address (which we will use when we have no hopsrc).
         **    NOTE: (testdata->ipsrc != INADDR_ANY) means we are forwarding
         **
         ** 3. The source IP of the packet must be within the source network
         **    allowed by the interface
         */
         if ((testdata->hopsrc == INADDR_ANY ||
              testdata->hopsrc == INADDR_BROADCAST ||
              testdata->hopsrc == virtual->ADDRESS ||
              _IP_forward) &&
             (virtual->ADDRESS || testdata->ipsrc || testdata->hopsrcislocal) &&
             ((source & virtual->SOURCE_MASK) == virtual->SOURCE_NET))
         {
            /*
            ** At this point we've chosen an interface.
            */

            /* Use this interface's source address if we don't have one */
            if (!testdata->hopsrcislocal) {
               testdata->hopsrc = virtual->ADDRESS;
               if (!testdata->hopsrc) {
                  testdata->hopsrc = testdata->ipsrc;
               } /* Endif */
            } /* Endif */

            /*
            **
            ** This is the case when we receive a unicast packet. We simply send
            ** it out of the chosen interface (set ifdest). We could be sending
            ** this packet directly to the destination, or we could be sending
            ** it to a gateway. If we are sending it to a gateway, hopdest is
            ** already set to the address of the gateway, so we don't modify it.
            ** Otherwise, if we are sending directly to the destination, set
            ** hopdest to the destination IP.
            */

            testdata->ifdest = virtual->DESTIF;
            if (!testdata->hopdest) {
               testdata->hopdest = testdata->ipdest;
            } /* Endif */

            /* Use a different interface next time */
            route->VIRTUAL = route->VIRTUAL->NEXT;
            testdata->sendit = TRUE;
            testdata->retval = RTCS_OK;
            testdata->data = virtual->DATA;
            return TRUE;
         } /* Endif */

         virtual = virtual->NEXT;
      } while(virtual != route->VIRTUAL);

   } /* Endif */

   /*
   ** Reaching this point means that the destination isn't directly connected
   ** to us. Check for a gateway (if we haven't done so already).
   */

   if (indirect && testdata->check_gateway) {
      do {
          if (indirect->FLAGS & RTF_UP) {
            testdata->hopdest = indirect->GATEWAY;

            /* Notify calling function that a gateway was found */
            testdata->check_gateway = FALSE;

            return TRUE;
          } /* Endif */

         indirect = indirect->NEXT;
      } while(indirect != route->INDIRECT);
   } /* Endif */

   return FALSE;
} /* Endbody */


uint_32 IP_route
   (
      RTCSPCB_PTR    pcb,
            /* [IN] the packet to send */
      uint_32        protocol,
            /* [IN] the transport layer protocol */
      _ip_address    hopsrc,
            /* [IN] the destination interface (0 = any) */
      _ip_address    ipsrc,
            /* [IN]the ultimate source */
      _ip_address    ipdest,
            /* [IN] the ultimate destination */
      uint_32        flags
            /* [IN] optional flags */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   struct ip_route_struct  testdata;
   
   RTCSLOG_FNE4(RTCSLOG_FN_IP_route, pcb, protocol, hopsrc);

   testdata.pcb            = pcb;
   testdata.ipsrc          = ipsrc;
   testdata.ipdest         = ipdest;
   testdata.flags          = flags;

   testdata.retval         = RTCSERR_IP_UNREACH;
   testdata.check_gateway  = TRUE;
   testdata.ifdest         = NULL;
   testdata.hopdest        = INADDR_ANY;
   testdata.keep_pcb       = NULL;

   testdata.keepit         = FALSE;
   testdata.sendit         = FALSE;
   testdata.hopsrc         = hopsrc;
   testdata.hopsrcislocal  = IP_is_local(NULL, hopsrc);
   testdata.data           = NULL;

   IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, ipdest, IP_route_test, &testdata);

   /* If we have found a gateway, find an interface for the gateway */
   if (!testdata.check_gateway) {
      IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, testdata.hopdest,
         IP_route_test, &testdata);
   } /* Endif */

   /* Discard the packet */
   if (testdata.retval || (!testdata.keepit && !testdata.sendit)) {
      RTCSLOG_PCB_FREE(pcb, testdata.retval);
      RTCSPCB_free(pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_route, testdata.retval);
      return testdata.retval;
   } /* Endif */

   /* Should we send to localhost? */
   if (testdata.keepit && testdata.keep_pcb) {
      testdata.retval = IP_send_dgram( RTCS_IF_LOCALHOST_PRV,
         testdata.keep_pcb, testdata.hopsrc, INADDR_BROADCAST, ipdest, protocol,
         NULL);
   } /* Endif */

   /* Should we send it out? */
   if (testdata.sendit) {
      testdata.retval = IP_send_dgram(testdata.ifdest, pcb, testdata.hopsrc,
         testdata.hopdest, ipdest, protocol, testdata.data);
   } /* Endid */

   RTCSLOG_FNX2(RTCSLOG_FN_IP_route, testdata.retval);
   return testdata.retval;
} /* Endbody */


#endif /* RTCSCFG_ENABLE_IP4 */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/include/devapi.h<|end_filename|>
#ifndef __devapi_h__
#define __devapi_h__ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: devapi.h$
* $Version : 3.8.6.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
*  This file contains the declarations specific to the USB Device API
*
*END*********************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Informational Request/Set Types */
#define  USB_STATUS_DEVICE_STATE          (0x01)
#define  USB_STATUS_INTERFACE             (0x02)
#define  USB_STATUS_ADDRESS               (0x03)
#define  USB_STATUS_CURRENT_CONFIG        (0x04)
#define  USB_STATUS_SOF_COUNT             (0x05)
#define  USB_STATUS_DEVICE                (0x06)
#define  USB_STATUS_TEST_MODE             (0x07)
#define  USB_STATUS_ENDPOINT              (0x10)
#define  USB_STATUS_ENDPOINT_NUMBER_MASK  (0x0F)

#define  USB_TEST_MODE_TEST_PACKET        (0x0400)

/* Available service types */
/* Services 0 through 15 are reserved for endpoints */
#define  USB_SERVICE_EP0                  (0x00)
#define  USB_SERVICE_EP1                  (0x01)
#define  USB_SERVICE_EP2                  (0x02)
#define  USB_SERVICE_EP3                  (0x03)
#define  USB_SERVICE_BUS_RESET            (0x10)
#define  USB_SERVICE_SUSPEND              (0x11)
#define  USB_SERVICE_SOF                  (0x12)
#define  USB_SERVICE_RESUME               (0x13)
#define  USB_SERVICE_SLEEP                (0x14)
#define  USB_SERVICE_SPEED_DETECTION      (0x15)
#define  USB_SERVICE_ERROR                (0x16)
#define  USB_SERVICE_STALL                (0x17)

#define USB_CONTROL_ENDPOINT              (0)
#define USB_SETUP_PKT_SIZE                (8)/* Setup Packet Size */
#define  USB_UNINITIALIZED_VAL_32         (0xFFFFFFFF)
#define COMPONENT_PREPARE_SHIFT           (7)

/* Common Data Structures */
typedef struct _USB_SETUP_STRUCT
{
   uint_8      request_type;
   uint_8      request;
   uint_16     value;
   uint_16     index;
   uint_16     length;
} USB_SETUP_STRUCT, _PTR_ USB_SETUP_STRUCT_PTR;

typedef struct _USB_EP_STRUCT
{
  uint_8          ep_num;      /* endpoint number         */
  uint_8          type;        /* type of endpoint        */
  uint_8          direction;   /* direction of endpoint   */
  uint_32         size;        /* buffer size of endpoint */
}USB_EP_STRUCT;

typedef USB_EP_STRUCT* USB_EP_STRUCT_PTR;


typedef struct _USB_EVENT_STRUCT
{
  _usb_device_handle handle;          /* conttroler device handle*/
  uint_8          ep_num;
  boolean         setup;              /* is setup packet         */
  boolean         direction;          /* direction of endpoint   */
  uint_8_ptr      buffer_ptr;         /* pointer to buffer       */
  uint_32         len;                /* buffer size of endpoint */
} USB_EVENT_STRUCT, *PTR_USB_EVENT_STRUCT;

typedef struct {
   pointer              PRIVATE;
   void (_CODE_PTR_     FREE)(_usb_device_handle, pointer);
   pointer              XD_FOR_THIS_DTD;
} SCRATCH_STRUCT, _PTR_ SCRATCH_STRUCT_PTR;

/* Callback function storage structure */
typedef struct service_struct 
{
   uint_8   TYPE;
   void     (_CODE_PTR_ SERVICE)(PTR_USB_EVENT_STRUCT,pointer arg);
   pointer  arg;
   struct service_struct _PTR_   NEXT;
} SERVICE_STRUCT, _PTR_ SERVICE_STRUCT_PTR;

void _usb_device_free_XD(_usb_device_handle, pointer  xd_ptr);
USB_STATUS _usb_device_init(struct usb_dev_if_struct *, _usb_device_handle _PTR_, _mqx_uint);
USB_STATUS _usb_device_deinit(_usb_device_handle);
USB_STATUS _usb_device_recv_data(_usb_device_handle, uint_8, uint_8_ptr, uint_32);
USB_STATUS _usb_device_send_data(_usb_device_handle, uint_8, uint_8_ptr, uint_32);
USB_STATUS _usb_device_get_transfer_status(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_device_cancel_transfer(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_device_get_status(_usb_device_handle, uint_8, uint_16_ptr);
USB_STATUS _usb_device_set_status(_usb_device_handle, uint_8, uint_16);
USB_STATUS _usb_device_register_service(_usb_device_handle, uint_8,
   void(_CODE_PTR_ service)(PTR_USB_EVENT_STRUCT, pointer),pointer arg);
USB_STATUS _usb_device_unregister_service(_usb_device_handle, uint_8);
USB_STATUS _usb_device_call_service(uint_8, PTR_USB_EVENT_STRUCT);
USB_STATUS _usb_device_shutdown(_usb_device_handle);
USB_STATUS _usb_device_set_address(_usb_device_handle, uint_8);
USB_STATUS _usb_device_read_setup_data(_usb_device_handle, uint_8, uint_8_ptr);
USB_STATUS _usb_device_assert_resume(_usb_device_handle);
USB_STATUS _usb_device_init_endpoint(_usb_device_handle, USB_EP_STRUCT_PTR, uint_8);
USB_STATUS _usb_device_stall_endpoint(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_device_unstall_endpoint(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_device_deinit_endpoint(_usb_device_handle, uint_8, uint_8);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/USB_task.c<|end_filename|>
#include "app_cfg.h"
#include "usb_class.h"
#include "usb_hid.h"
#include "USB_task.h"
#include "usb_dfu.h"

INT8U           usb_device_state;  /* Device state */

TIMER_OBJECT    dfu_timeout;
INT8U           g_dfu_flash_result = RES_NONE;

static BOOLEAN  mouse_init = FALSE;           /* Application Init Flag */
static INT8U    rpt_buf[MOUSE_BUFF_SIZE];     /* Mouse Event Report Buffer Key press */
static INT8U    g_app_request_params[2];      /* for get/set idle and protocol requests*/

static INT16U   last_usb_status;

INT32U   g_flashed_size;      // Количество запрограммированных байт

void         USB_App_init(void);
void         USB_App_task(void);
static void  USB_App_HID_Callback(INT8U controller_ID, INT8U event_type, void *val);
static void  USB_App_DFU_Callback(INT8U controller_ID, INT8U event_type, void *val);
static INT8U USB_App_Param_Callback(INT8U request, INT16U value, INT8U_ptr *data, INT16U *size);
static void  USB_App_Process_Detach_TimeOut(void);

INT8U Flash_recv_buff(INT8U *dfu_recv_buff, INT32U dfu_data_size);
static void Erase_sectors(INT32U *addr, INT32U size);
//-------------------------------------------------------------------------------------------------------
//  This function handles the callback
//
//  controller_ID    : Controller ID
//  event_type       : value of the event
//  val              : gives the configuration value
//
//  None
//
//  This function is called from the class layer whenever reset occurs or enum is complete.
//  After the enum is complete this function sets a variable so that the application can start
//-------------------------------------------------------------------------------------------------------
static void USB_App_HID_Callback(INT8U controller_ID, INT8U event_type, void *val)
{

  if ( (event_type == USB_APP_BUS_RESET) || (event_type == USB_APP_CONFIG_CHANGED) )
  {
    mouse_init = FALSE;
  }
  else if ( event_type == USB_APP_ENUM_COMPLETE )
  {
    mouse_init = TRUE; // После команды установки конфигурации
  }
  return;
}

//-------------------------------------------------------------------------------------------------------
//  This function is called to processed detach timeout
//-------------------------------------------------------------------------------------------------------
static void USB_App_Process_Detach_TimeOut()
{
  usb_device_state = USB_Class_DFU_App_Getstate();
  if ( usb_device_state == USB_APP_DETACH )
  {
    USB_Class_DFU_App_SetIdle();
    USB_Device_Shutdown(0);
    g_dfu_mode = RUNTIME_MODE;
    (void)USB_Class_HID_Init(CONTROLLER_ID, USB_App_HID_Callback, NULL, USB_App_Param_Callback);
  }
}

//-------------------------------------------------------------------------------------------------------
//   This function handles callbacks for USB HID Class request
//
//   request  : request type
//   value    : give report type and id
//   data     : pointer to the data
//   size     : size of the transfer
//
//   status
//   USB_OK  :  if successful
//   else return error
//
//
//   This function is called whenever a HID class request is received.
//   This function handles these class requests
//-------------------------------------------------------------------------------------------------------
static INT8U USB_App_Param_Callback(INT8U request, INT16U value, INT8U_ptr *data, INT16U *size)
{
  INT8U status = USB_OK;
  INT8U index = (INT8U)((request - 2) & USB_HID_REQUEST_TYPE_MASK);

  *size = 0;
  /* handle the class request */
  switch (request)
  {
  case USB_HID_GET_REPORT_REQUEST :
    *data = &rpt_buf[0]; /* point to the report to send */
    *size = MOUSE_BUFF_SIZE; /* report size */
    break;

  case USB_HID_SET_REPORT_REQUEST :
    for (index = 0; index < MOUSE_BUFF_SIZE; index++)
    {   /* copy the report sent by the host */
      rpt_buf[index] = *(*data + index);
    }
    break;

  case USB_HID_GET_IDLE_REQUEST :
    /* point to the current idle rate */
    *data = &g_app_request_params[index];
    *size = REQ_DATA_SIZE;
    break;

  case USB_HID_SET_IDLE_REQUEST :
    /* set the idle rate sent by the host */
    g_app_request_params[index] = (INT8U)((value & MSB_MASK) >> HIGH_BYTE_SHIFT);
    break;

  case USB_HID_GET_PROTOCOL_REQUEST :
    /* point to the current protocol code
       0 = Boot Protocol
       1 = Report Protocol*/
    *data = &g_app_request_params[index];
    *size = REQ_DATA_SIZE;
    break;

  case USB_HID_SET_PROTOCOL_REQUEST :
    /* set the protocol sent by the host
       0 = Boot Protocol
       1 = Report Protocol*/
    g_app_request_params[index] = (INT8U)(value);
    break;
  default:
    if ( request == USB_DFU_DETACH )
    {
#if !(DETACH)
      (void)Remove_periodic_callback(0);
      dfu_timeout.msCount = (INT16U)value;
      dfu_timeout.pfnTimerCallback = USB_App_Process_Detach_TimeOut;
      (void)Add_periodic_callback(&dfu_timeout);
#endif
      USB_Class_DFU_App_SetDetach();
      USB_Device_Shutdown(0);
      g_dfu_mode = DFU_MODE;
      (void)USB_Class_DFU_Init(CONTROLLER_ID, USB_App_DFU_Callback, NULL, NULL);
    }
    break;
  }
  return status;
}

//-------------------------------------------------------------------------------------------------------
//   This function handles USB Class callback
//
//   controller_ID    : Controller ID
//   event_type       : value of the event
//   val              : gives the configuration value
//
//   None
//
//  This function is called from the class layer whenever reset occurs or enum is complete.
//  After the enum is complete this function sets a variable so that the application can start
//-------------------------------------------------------------------------------------------------------
static void USB_App_DFU_Callback(INT8U controller_ID, INT8U event_type, void *val)
{
  BOOLEAN  manifest;    /* Flag to check manifest phase complete or not */

  UNUSED(controller_ID)
  UNUSED(val)
  usb_device_state = USB_Class_DFU_App_Getstate();
  manifest = USB_Class_DFU_App_Get_Flag_Manifest();
  if ( event_type == USB_APP_BUS_RESET )
  {
    switch (usb_device_state)
    {
    case USB_APP_DETACH:
      USB_Class_DFU_App_Set_Usbreset();
      break;
    default:
      USB_Class_DFU_App_Set_Usbreset();
      // Вернемся в реальный режим работы только если обработан манифест
      if ( manifest )
      {
        g_dfu_mode = RUNTIME_MODE;
        (void)USB_Class_HID_Init(CONTROLLER_ID, USB_App_HID_Callback, NULL, USB_App_Param_Callback);
        (void)USB_Class_DFU_App_Reset_Flag_Manifest();
      }
      break;
    } /* EndSwitch */
  }
  else if ( event_type == USB_APP_ENUM_COMPLETE )
  {}
  return;
}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void USB_App_init(void)
{

  INT8U   error;

  rpt_buf[3] = 0x00;   /* always zero */
  *((INT32U_ptr)rpt_buf) = 0;

  Flash_Init();       // no clk related

  __disable_interrupt();
  error = USB_Class_HID_Init(CONTROLLER_ID, USB_App_HID_Callback, NULL, USB_App_Param_Callback);
  __enable_interrupt();
  if ( error != USB_OK )
  {
    return;
  }

}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
static void Show_USB_status_on_LCD(void)
{
  INT16U status;
  USB_Device_Get_Status(0, USB_STATUS_DEVICE_STATE, &status);
  if ( status != last_usb_status )
  {
    if ( status == USB_STATE_SUSPEND )
    {
      LCD_print_str("---", 0, 0);
    }
    else if ( status == USB_STATE_CONFIG )
    {
      LCD_print_str("USB", 0, 0);
    }
    else
    {
      LCD_print_str("...", 0, 0);
    }

    last_usb_status = status;
  }

}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void USB_App_task(void)
{
  /* call the periodic task function */
  USB_Class_HID_task();

  if ( mouse_init )
  {
    // Функциональность если класс

  }
  USB_Class_DFU_task();


  if ( g_dfu_flash_result == RES_OK )
  {
    g_dfu_flash_result =  RES_NONE;
    USB_Class_DFU_App_SetIdle();
  }

  Show_USB_status_on_LCD();
}



//-------------------------------------------------------------------------------------------------------
// 
//-------------------------------------------------------------------------------------------------------
void Loader_init(void)
{
  g_flashed_size   = 0;
}


//-------------------------------------------------------------------------------------------------------
// 
//-------------------------------------------------------------------------------------------------------
static void Erase_sectors(INT32U *addr, INT32U size)
{
  INT16U   remain_bytes, counter;
  INT16U   len;
  INT8U    delete_flag = 0;
  INT32U   start_add = (INT32U)addr;
  INT32U   sector = (INT32U)(start_add / ERASE_SECTOR_SIZE);
  INT32U   offset = (INT32U)(start_add % ERASE_SECTOR_SIZE);

  do
  {
    remain_bytes = (INT16U)(((sector + 1) * ERASE_SECTOR_SIZE) - start_add);
    if ( size< remain_bytes)
    {
      len = size;
    }
    else
    {
      len = remain_bytes;
    }
    // Проверяем сектор на чистоту
    for (counter = 0; counter < len; counter++)
    {
      if ( *(INT8U *)(start_add + counter) != 0xFF )
      {
        delete_flag = 1;
        break;
      }
    }

    // Стирание сектора если обнаружены не стертые данные
    if ( delete_flag )
    {
      if ( Flash_SectorErase((INT32U)((sector * ERASE_SECTOR_SIZE) + offset)) != Flash_OK ) break;
      delete_flag = 0;
    }
    size -= len;
    start_add += len;
    sector++;
  }
  while (size);


}

//-------------------------------------------------------------------------------------------------------
// 
//-------------------------------------------------------------------------------------------------------
INT8U Flash_recv_buff(INT8U *dfu_recv_buff, INT32U dfu_data_size)
{

  INT8U           result;
  INT32U          write_addr;     /* address to write to flash */
  static  INT32U  bytes_written;  /* number of bytes was written to flash */
  INT32U          header;


  write_addr = (INT32U)IMAGE_START_ADDR + bytes_written;
  __disable_interrupt();
  (void)Erase_sectors((INT32U *)(write_addr), dfu_data_size);
  result = Flash_ByteProgram(write_addr, dfu_recv_buff, dfu_data_size);
  __enable_interrupt();

  bytes_written += dfu_data_size;

  LCD_show_programming_progress(write_addr + dfu_data_size, bytes_written);
  g_flashed_size = bytes_written;

  return RES_OK;
}



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/os/mqx25x/rtcstask.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcstask.c$
* $Version : 3.5.11.0$
* $Date    : Dec-11-2009$
*
* Comments:
*
*   This file contains the interface to the RTOS
*   task management functions.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>


struct rtcs_task_state {
   _rtcs_sem        sem;
   void (_CODE_PTR_ start)(pointer, pointer);
   pointer          arg;
   uint_32          error;
};

/*TASK*-----------------------------------------------------------------
*
* Function Name   : RTCS_task
* Returned Values :
* Comments        :
*     The parent of all RTCS tasks.
*
*END*-----------------------------------------------------------------*/

static void RTCS_task
   (
      uint_32 task_parm
   )
{ /* Body */
   struct rtcs_task_state _PTR_ task = (struct rtcs_task_state _PTR_)task_parm;
   /* This is completely unnecessary -- it's done only for Task Aware Debugging */
   _task_get_template_ptr (MQX_NULL_TASK_ID)->TASK_ADDRESS = (void(_CODE_PTR_)(uint_32))task->start;
 
   task->start(task->arg, task);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_task_create
* Returned Values : uint_32 (error code)
* Comments        :
*     Create a task and wait for it to complete initialization.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_task_create
   (
      char_ptr          name,
      uint_32           priority,
      uint_32           stacksize,
      void (_CODE_PTR_  start)(pointer, pointer),
      pointer           arg
   )
{ /* Body */
   TASK_TEMPLATE_STRUCT    task_template;
   struct rtcs_task_state  task;

   RTCS_sem_init(&task.sem);
   task.start = start;
   task.arg   = arg;
   task.error = RTCS_OK;

   _mem_zero((uchar_ptr)&task_template, sizeof(task_template));
   task_template.TASK_NAME          = name;
   task_template.TASK_PRIORITY      = priority;
   task_template.TASK_STACKSIZE     = stacksize;
   task_template.TASK_ADDRESS       = RTCS_task;
   task_template.CREATION_PARAMETER = (uint_32)&task;
   if (_task_create(0, 0, (uint_32)&task_template) == MQX_NULL_TASK_ID) {
      RTCS_sem_destroy(&task.sem);
      return RTCSERR_CREATE_FAILED;
   } /* Endif */

   RTCS_sem_wait(&task.sem);
   RTCS_sem_destroy(&task.sem);
   return task.error;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_task_resume_creator
* Returned Values : void
* Comments        :
*     Return an error code to the caller's creator.
*
*END*-----------------------------------------------------------------*/

void RTCS_task_resume_creator
   (
      pointer creator,
      uint_32 error
   )
{ /* Body */
   struct rtcs_task_state _PTR_ task = creator;

   if (task) {
      task->error = error;
      RTCS_sem_post(&task->sem);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_task_exit
* Returned Values : void
* Comments        :
*     Return an error code to the caller's creator, and block.
*
*END*-----------------------------------------------------------------*/

void RTCS_task_exit
   (
      pointer creator,
      uint_32 error
   )
{ /* Body */

   RTCS_task_resume_creator(creator, error);
   _task_set_error(error);
   _task_block();

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_task_id_from_td
* Returned Values : MQX _task_id
* Comments        :
*     Returns MQX task id from RTCS task id.
*
*END*-----------------------------------------------------------------*/

_task_id RTCS_task_id_from_td
   (
      _rtcs_taskid   taskid
   )
{ /* Body */

   return _task_get_id_from_td (taskid);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_task_destroy
* Returned Values : void
* Comments        :
*     Destroy a task.
*
*END*-----------------------------------------------------------------*/

void RTCS_task_destroy
   (
      _rtcs_taskid   taskid
   )
{ /* Body */

   _task_destroy (RTCS_task_id_from_td (taskid));

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_task_abort
* Returned Values : void
* Comments        :
*     Destroy a task.
*
*END*-----------------------------------------------------------------*/

void RTCS_task_abort
   (
      _rtcs_taskid   taskid
   )
{ /* Body */

   _task_abort (RTCS_task_id_from_td (taskid));

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/checksum6.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: checksum6.c$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation for a one's
*   complement checksum (IPv6 version).
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_IP6

#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"


/************************************************************************
* NAME: IP6_Sum_pseudo
*
* DESCRIPTION: Returns a one's complement checksum of the IP pseudo header
*
*     Note:  This function returns 0 iff all summands are 0..
*************************************************************************/
uint_16 IP6_Sum_pseudo( uint_16 sum /* [IN] initial sum */, RTCSPCB_PTR pcb /* [IN] the PCB */)
{
    IP6_HEADER_PTR iphead = (IP6_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb);
    uint_16 protocol;

    protocol = RTCSPCB_TRANSPORT_PROTL(pcb);
    sum = _mem_sum_ip(sum, 32, iphead->SOURCE); /* source and dest */
    sum = IP_Sum_immediate(sum, protocol);      /* protocol */
    return sum;
}

#endif /* RTCSCFG_ENABLE_IP6 */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/PE_LDD.c<|end_filename|>
/** ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : PE_LDD.c
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Version     : Component 01.005, Driver 01.04, CPU db: 3.00.000
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-16, 17:36, # CodeGen: 13
**     Abstract    :
**
**     Settings    :
**
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file PE_LDD.c                                                  
** @version 01.04
** @brief
**
*/         
/*!
**  @addtogroup PE_LDD_module PE_LDD module documentation
**  @{
*/         

/* MODULE PE_LDD. */

#include "mqx.h"
#include "ioctl.h"

#include "PE_LDD.h"
#include "Cpu.h"

/*lint -esym(765,PE_PeripheralUsed,LDD_SetClockConfiguration,PE_CpuClockConfigurations,PE_FillMemory) Disable MISRA rule (8.10) checking for symbols (PE_PeripheralUsed,LDD_SetClockConfiguration,PE_CpuClockConfigurations,PE_FillMemory). */

/*
** ===========================================================================
** The array of clock frequencies in configured clock configurations.
** ===========================================================================
*/
/*! The array of clock configurations (frequencies) configured in configured clock configurations of the CPU component. */
const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER] = {
  /* Clock configuration 0 */
  {
    CPU_CORE_CLK_HZ_CONFIG_0,          /*!< Core clock frequency in clock configuration 0 */
    CPU_BUS_CLK_HZ_CONFIG_0,           /*!< Bus clock frequency in clock configuration 0 */
    CPU_FLEXBUS_CLK_HZ_CONFIG_0,       /*!< Flexbus clock frequency in clock configuration 0 */
    CPU_FLASH_CLK_HZ_CONFIG_0,         /*!< FLASH clock frequency in clock configuration 0 */
    CPU_USB_CLK_HZ_CONFIG_0,           /*!< USB clock frequency in clock configuration 0 */
    CPU_PLL_FLL_CLK_HZ_CONFIG_0,       /*!< PLL/FLL clock frequency in clock configuration 0 */
    CPU_MCGIR_CLK_HZ_CONFIG_0,         /*!< MCG internal reference clock frequency in clock configuration 0 */
    CPU_OSCER_CLK_HZ_CONFIG_0,         /*!< System OSC external reference clock frequency in clock configuration 0 */
    CPU_ERCLK32K_CLK_HZ_CONFIG_0,      /*!< External reference clock 32k frequency in clock configuration 0 */
    CPU_MCGFF_CLK_HZ_CONFIG_0          /*!< MCG fixed frequency clock */
  },
  /* Clock configuration 1 */
  {
    CPU_CORE_CLK_HZ_CONFIG_1,          /*!< Core clock frequency in clock configuration 1 */
    CPU_BUS_CLK_HZ_CONFIG_1,           /*!< Bus clock frequency in clock configuration 1 */
    CPU_FLEXBUS_CLK_HZ_CONFIG_1,       /*!< Flexbus clock frequency in clock configuration 1 */
    CPU_FLASH_CLK_HZ_CONFIG_1,         /*!< FLASH clock frequency in clock configuration 1 */
    CPU_USB_CLK_HZ_CONFIG_1,           /*!< USB clock frequency in clock configuration 1 */
    CPU_PLL_FLL_CLK_HZ_CONFIG_1,       /*!< PLL/FLL clock frequency in clock configuration 1 */
    CPU_MCGIR_CLK_HZ_CONFIG_1,         /*!< MCG internal reference clock frequency in clock configuration 1 */
    CPU_OSCER_CLK_HZ_CONFIG_1,         /*!< System OSC external reference clock frequency in clock configuration 1 */
    CPU_ERCLK32K_CLK_HZ_CONFIG_1,      /*!< External reference clock 32k frequency in clock configuration 1 */
    CPU_MCGFF_CLK_HZ_CONFIG_1          /*!< MCG fixed frequency clock */
  },
  /* Clock configuration 2 */
  {
    CPU_CORE_CLK_HZ_CONFIG_2,          /*!< Core clock frequency in clock configuration 2 */
    CPU_BUS_CLK_HZ_CONFIG_2,           /*!< Bus clock frequency in clock configuration 2 */
    CPU_FLEXBUS_CLK_HZ_CONFIG_2,       /*!< Flexbus clock frequency in clock configuration 2 */
    CPU_FLASH_CLK_HZ_CONFIG_2,         /*!< FLASH clock frequency in clock configuration 2 */
    CPU_USB_CLK_HZ_CONFIG_2,           /*!< USB clock frequency in clock configuration 2 */
    CPU_PLL_FLL_CLK_HZ_CONFIG_2,       /*!< PLL/FLL clock frequency in clock configuration 2 */
    CPU_MCGIR_CLK_HZ_CONFIG_2,         /*!< MCG internal reference clock frequency in clock configuration 2 */
    CPU_OSCER_CLK_HZ_CONFIG_2,         /*!< System OSC external reference clock frequency in clock configuration 2 */
    CPU_ERCLK32K_CLK_HZ_CONFIG_2,      /*!< External reference clock 32k frequency in clock configuration 2 */
    CPU_MCGFF_CLK_HZ_CONFIG_2          /*!< MCG fixed frequency clock */
  }
};

/*
** ===================================================================
**     Method      :  Cpu_PE_FillMemory (component MK60FN1M0LQ15)
*/
/*!
**     @brief
**         Fills a memory area block by a specified value.
**     @param
**       SourceAddressPtr - Source address pointer.
**     @param
**       c - A value used to fill a memory block.
**     @param
**       len - Length of a memory block to fill.
*/
/* ===================================================================*/
void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len)
{
  register uint8_t *ptr = (uint8_t*)SourceAddressPtr;

  if (len > 0U) {
    while (len--) {
      *ptr++ = c;
    }
  }
}

/*
** ===================================================================
**     Method      :  Cpu_PE_PeripheralUsed (component MK60FN1M0LQ15)
*/
/*!
**     @brief
**         Returns information whether a peripheral is allocated by PEx 
**         or not.
**     @param
**       PrphBaseAddress - Base address of a peripheral.
**     @return
**       TRUE if a peripheral is used by PEx or FALSE if it isn't used.
*/
/* ===================================================================*/
bool PE_PeripheralUsed(uint32_t PrphBaseAddress)
{
  (void)PrphBaseAddress;               /*!< Parameter is not used, suppress unused argument warning */
  return FALSE;
}

/*
** ===================================================================
**     Method      :  Cpu_LDD_SetClockConfiguration (component MK60FN1M0LQ15)
*/
/*!
**     @brief
**         Changes the clock configuration of all LDD components in a 
**         project.
**     @param
**       ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method.
**     @param
**       ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method.
*/
/* ===================================================================*/
void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration)
{
  (void)ClockConfiguration;            /*!< Parameter is not used, suppress unused argument warning */
}

/* END PE_LDD. */

/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/rtcsload.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcsload.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the interface functions to the
*   Exec function of the RTCS Communication Library.
*
*END************************************************************************/

#include <rtcs.h>


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : RTCS_load
* Returned Value   : RTCS_OK or error code
* Comments  :  Routine to load and execute a bootimage from a server.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_load
   (
      FT_CALL_STRUCT_PTR   ft_ptr,
         /* [IN] file transfer protocol to use */
      pointer              ft_data,
         /* [IN] file transfer data */
      FF_CALL_STRUCT_PTR   ff_ptr,
         /* [IN] file format to decode */
      pointer              ff_data,
         /* [IN] file format data */
      uint_32              flags
         /* [IN] optional flags */
   )
{ /* Body */
   uint_32   error;  /* also used as packet size */
   uchar_ptr data;

   /*
   ** Initialize
   */
   error = (*ft_ptr->OPEN)(ft_data);
   if (error) {
      return error;
   } /* Endif */
   error = (*ff_ptr->START)(ff_data);
   if (error) {
      (*ft_ptr->CLOSE)();
      return error;
   } /* Endif */

   /*
   ** Repeat until end of file
   */
   while (!(*ft_ptr->EOFT)()) {

      /*
      ** Retrieve some data...
      */
      data = (*ft_ptr->READ)(&error);
      if (!data) {
         (*ff_ptr->EOFD)();
         return error;
      } /* Endif */

      /*
      ** ...and decode it
      **
      ** Note:  If data is non-NULL, then error contains the
      **        number of bytes read.
      */
      error = (*ff_ptr->DECODE)(error, data);
      if (error) {
         (*ft_ptr->CLOSE)();
         return error;
      } /* Endif */
   } /* Endwhile */

   /*
   ** Check if the decoding succeeded
   */
   error = (*ff_ptr->EOFD)();
   if (error) {
      (*ft_ptr->CLOSE)();
      return error;
   } /* Endif */

   /*
   ** End the file transfer session
   */
   error = (*ft_ptr->CLOSE)();
   if (error) {
      return error;
   } /* Endif */

   /*
   ** If we get here, the file was retrieved and decoded successfully.
   ** Run the image.
   */
   if (flags & RTCSLOADOPT_EXEC) {
      (*ff_ptr->EXEC)();
   } /* Endif */

   return RTCS_OK;

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Acos.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Acos.h
*
* @author   B04459
* 
* @version  1.0.1.0
* 
* @date     Dec-6-2012
* 
* @brief    Header file for #GFLIB_Acos function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef GFLIB_ACOS_H_
#define GFLIB_ACOS_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif
/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*!
  \def GFLIB_Acos
  Function alias.
*/
#define GFLIB_Acos(x) GFLIB_AcosANSIC((x), &gflibAcosCoef)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/

/*------------------------------------------------------------------------*//*!
@struct GFLIB_ACOS_TAYLOR_COEF_T "\GFLIB_Acos.h"

@brief      Structure containing five polynomial coefficients for one sub-interval.

@details    Output of \f$\arccos\left(f32In\right)\f$ for
            interval \f$\left[0,1\right)\f$ of the input ratio is divided into two
            sub-sectors. Polynomial approximation is done using a 5th order
            polynomial, for each sub-sector respectively. Five coefficients for
            a single sub-interval are stored in this
            (#GFLIB_ACOS_TAYLOR_COEF_T) structure.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    const Frac32  f32a[5];  /*!< Array of five 32-bit elements for storing
                            coefficients of the piece-wise polynomial. */
} GFLIB_ACOS_TAYLOR_COEF_T;

/*-------------------------------------------Sz-----------------------------*//*!
@struct GFLIB_ACOS_TAYLOR_T "\GFLIB_Acos.h"

@brief      Structure containing two sub-structures with polynomial coefficients
            to cover all sub-intervals.

@details    Output of \f$\arccos\left(f32In\right)\f$ for
            interval \f$\left[0,1\right)\f$ of the input ratio is divided
            into two sub-sectors. Polynomial approximation is done using a 5th
            order polynomial, for each sub-sector respectively. Two arrays,
            each including five polynomial coefficients for each sub-interval,
            are stored in this (#GFLIB_ACOS_TAYLOR_T) structure.

            \par
            By calling the function alias #GFLIB_Acos, default values of the
            coefficients are used. Polynomial coefficients can be modified by
            the user and in such a case the full function call shall be used, i.e.
            #GFLIB_AcosANSIC
*//*-------------------------------------------------------------------------*/

typedef struct
{
    const GFLIB_ACOS_TAYLOR_COEF_T  GFLIB_ACOS_SECTOR[2]; /*!< Array of two
                                elements for storing two sub-arrays (each
                                sub-array contains five 32-bit coefficients)
                                for all sub-intervals.*/
} GFLIB_ACOS_TAYLOR_T;

/******************************************************************************
* Exported Variables
******************************************************************************/

extern const GFLIB_ACOS_TAYLOR_T gflibAcosCoef;

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*! 
* @ingroup GFLIB_GROUP 
*/ 
extern Frac32 GFLIB_AcosANSIC(Frac32 f32In, const GFLIB_ACOS_TAYLOR_T *const pParam);

/******************************************************************************
* Inline functions
******************************************************************************/ 

#endif /*GFLIB_ACOS_H_*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/select.h<|end_filename|>
#ifndef __select_h__
#define __select_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: select.h$
* $Version : 3.8.6.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the defines, externs and data
*   structure definitions required by the select function.
*
*END************************************************************************/


#define RTCS_SELECT_MAX_FDS 32
#define RTCS_SELECT_ERROR   (-1)

#define select   RTCS_select
#define FD_CLR   RTCS_FD_CLR
#define FD_ISSET RTCS_FD_ISSET
#define FD_SET   RTCS_FD_SET
#define FD_ZERO  RTCS_FD_ZERO


typedef struct {
    uint_32 COUNT;
    uint_32 FDS[RTCS_SELECT_MAX_FDS];
} fd_set, _PTR_ fd_set_ptr;


struct timeval { 
    uint_32    tv_sec;         /* seconds */
    uint_32    tv_usec;        /* microseconds */
};

extern boolean RTCS_FD_CLR(uint_32 fd, fd_set _PTR_ set_ptr ); 
extern boolean RTCS_FD_ISSET(uint_32 fd, fd_set _PTR_ set_ptr ); 
extern boolean RTCS_FD_SET(uint_32 fd, fd_set _PTR_ set_ptr ); 
extern boolean RTCS_FD_ZERO(fd_set _PTR_ set_ptr );
extern boolean RTCS_FD_COPY(fd_set _PTR_ src_ptr, fd_set _PTR_ dest_ptr );
extern int_32  RTCS_select(int_32 n, fd_set _PTR_ readfds, fd_set _PTR_ writefds, fd_set _PTR_ exceptfds, struct timeval *timeout); 

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/pkttx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pkttx.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the PPP Tx
*   task.
*
*END************************************************************************/

#include <ppp.h>
#include "ppp_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_send
* Returned Value  :  error code
* Comments        :
*     Sends a PPP packet.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_send
   (
      _ppp_handle    handle,
            /* [IN] - the PPP state structure */
      uint_16        protocol,
            /* [IN] - protocol for the packet */
      PCB_PTR        pcb
            /* [IN] - the packet to send */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR       ppp_ptr = handle;
   PCB_FRAGMENT_PTR  frag_ptr;
   uint_32           size, mru;
   uint_32           error;

   /* Do some error checking */
   if (ppp_ptr->VALID != PPP_VALID) {
      PCB_free(pcb);
      return RTCSERR_PPP_INVALID_HANDLE;
   } else if (!(protocol&1) || (protocol&0x100)) {
      PCB_free(pcb);
      return RTCSERR_PPP_INVALID_PROTOCOL;
   } /* Endif */

   error = PPP_OK;
   PPP_mutex_lock(&ppp_ptr->MUTEX);
   if (!ppp_ptr->LINK_STATE) {
      error = RTCSERR_PPP_LINK_NOT_OPEN;
   } else {
      /* SPR P122-0371-01 */
      /* PCB includes 2-byte protocol field, but negotiated MRU doesn't */
      mru = ppp_ptr->SEND_OPTIONS->MRU + 2;
      /* End SPR P122-0371-01 */
   } /* Endif */
   PPP_mutex_unlock(&ppp_ptr->MUTEX);
   if (error) {
      PCB_free(pcb);
      return error;
   } /* Endif */

   /*
   ** Make sure the first fragment is long enough for the PPP protocol
   ** field.  This isn't strictly necessary, but it's impractical
   ** to split a 2 byte field over multiple fragments.
   */
   if (pcb->FRAG[0].LENGTH < 2) {
      PCB_free(pcb);
      return RTCSERR_PPP_PACKET_TOO_SHORT;
   } /* Endif */

   /*
   ** Make sure that no fragment exceeds a maximum packet length.
   ** We check every fragment because we want to prevent something
   ** like FRAG[0].LENGTH = 2000, FRAG[1].LENGTH = -1000.  This
   ** situation would not be detected if we only check the total
   ** length.
   */
   size = 0;
   for (frag_ptr = pcb->FRAG; frag_ptr->LENGTH; frag_ptr++) {
      if (frag_ptr->LENGTH > mru) {
         PCB_free(pcb);
         return RTCSERR_PPP_PACKET_TOO_LONG;
      } /* Endif */
      size += frag_ptr->LENGTH;
   } /* Endfor */

   /*
   ** Make sure that the total sum of the fragments doesn't exceed
   ** a maximum packet length.
   */
   if (size > mru) {
      PCB_free(pcb);
      return RTCSERR_PPP_PACKET_TOO_LONG;
   } /* Endif */

   /*
   ** Everything checks out -- send the packet to the Tx task.
   */
   htons(pcb->FRAG[0].FRAGMENT, protocol);
   return PPP_send_one(ppp_ptr, protocol, pcb);

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */     

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_send_one
* Returned Value  :  None
* Comments        :
*     Sends a PPP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 PPP_send_one
   (
      PPP_CFG_PTR    ppp_ptr,
            /* [IN] - PPP handle */
      uint_16        protocol,
            /* [IN] - protocol for the packet */
      PCB_PTR        pcb
            /* [IN] - packet */
   )
{ /* Body */
   PPP_MESSAGE_PTR   message;

   message = RTCS_msg_alloc(ppp_ptr->MSG_POOL);
   if (message == NULL) {
      return RTCSERR_PPP_OUT_OF_BUFFERS;
   } /* Endif */

   message->HEADER.SIZE       = sizeof(*message);
   message->HEADER.TARGET_QID = ppp_ptr->MSG_QUEUE;

   message->COMMAND  = PPPCMD_SEND;
   message->PROTOCOL = protocol & 0xFFFF;
   message->PCB      = pcb;
   message->TIMEOUT  = 0;

   RTCS_msgq_send(message, ppp_ptr->MSG_POOL);
   return PPP_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_send_rexmit
* Returned Value  :  None
* Comments        :
*     Sends a PPP packet, with retransmissions.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 PPP_send_rexmit
   (
      PPP_CFG_PTR       ppp_ptr,
            /* [IN] - PPP handle */
      uint_16           protocol,
            /* [IN] - protocol for the packet */
      PCB_PTR           pcb,
            /* [IN] - packet */
      uint_32           retries,
            /* [IN] - maximum number of retries */
      void (_CODE_PTR_  timeout)(pointer, PCB_PTR, boolean),
            /* [IN] - function to call after max retransmissions */
      pointer           param
            /* [IN] - parameter for timeout function */
   )
{ /* Body */
   PPP_MESSAGE_PTR   message;

   message = RTCS_msg_alloc(ppp_ptr->MSG_POOL);
   if (message == NULL) {
      return RTCSERR_PPP_OUT_OF_BUFFERS;
   } /* Endif */

   message->HEADER.SIZE       = sizeof(*message);
   message->HEADER.TARGET_QID = ppp_ptr->MSG_QUEUE;

   message->COMMAND  = PPPCMD_SEND;
   message->PROTOCOL = protocol & 0xFFFF;
   message->PCB      = pcb;
   message->TIMEOUT  = _PPP_MIN_XMIT_TIMEOUT;
   message->RETRY    = retries;
   message->CALL     = timeout;
   message->PARAM    = param;

   RTCS_msgq_send(message, ppp_ptr->MSG_POOL);
   return PPP_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_send_shutdown
* Returned Value  :  None
* Comments        :
*     send a message to remove tx task.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 PPP_send_shutdown
   (
      PPP_CFG_PTR       ppp_ptr,
            /* [IN] - PPP handle */
      pointer           param
            /* [IN] - parameter for timeout function */
   )
{ /* Body */
   PPP_MESSAGE_PTR   message;

   message = RTCS_msg_alloc(ppp_ptr->MSG_POOL);
   if (message == NULL) {
      return RTCSERR_PPP_OUT_OF_BUFFERS;
   } /* Endif */

   message->HEADER.SIZE       = sizeof(*message);
   message->HEADER.TARGET_QID = ppp_ptr->MSG_QUEUE;

   message->COMMAND  = PPPCMD_SHUTDOWN;
   message->TIMEOUT  = 0;
   message->PARAM    = param;

   RTCS_msgq_send(message, ppp_ptr->MSG_POOL);
   return PPP_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_send_restart
* Returned Value  :  None
* Comments        :
*     Restart the retransmission timer for a particular protocol.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 PPP_send_restart
   (
      PPP_CFG_PTR       ppp_ptr,
            /* [IN] - PPP handle */
      uint_16           protocol
            /* [IN] - protocol for the packet */
   )
{ /* Body */
   PPP_MESSAGE_PTR   message;

   message = RTCS_msg_alloc(ppp_ptr->MSG_POOL);
   if (message == NULL) {
      return RTCSERR_PPP_OUT_OF_BUFFERS;
   } /* Endif */

   message->HEADER.SIZE       = sizeof(*message);
   message->HEADER.TARGET_QID = ppp_ptr->MSG_QUEUE;

   message->COMMAND  = PPPCMD_RESTART;
   message->PROTOCOL = protocol & 0xFFFF;

   RTCS_msgq_send(message, ppp_ptr->MSG_POOL);

   return PPP_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_send_stop
* Returned Value  :  None
* Comments        :
*     Abort the retransmission timer for a particular protocol.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 PPP_send_stop
   (
      PPP_CFG_PTR       ppp_ptr,
            /* [IN] - PPP handle */
      uint_16           protocol
            /* [IN] - protocol for the packet */
   )
{ /* Body */
   PPP_MESSAGE_PTR   message;

   message = RTCS_msg_alloc(ppp_ptr->MSG_POOL);
   if (message == NULL) {
      return RTCSERR_PPP_OUT_OF_BUFFERS;
   } /* Endif */

   message->HEADER.SIZE       = sizeof(*message);
   message->HEADER.TARGET_QID = ppp_ptr->MSG_QUEUE;

   message->COMMAND  = PPPCMD_STOP;
   message->PROTOCOL = protocol & 0xFFFF;

   RTCS_msgq_send(message, ppp_ptr->MSG_POOL);

   return PPP_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_tx_pcbfree
* Returned Value  :  void
* Comments        :
*     Replacement for a PCB's FREE function.
*
*     When the Tx task needs to retransmit a packet, it tries
*     to reuse the PCB sent by the application.  Unfortunately,
*     _iopcb_write() frees the PCB when it's done.
*
*     So, when the Tx task detects that it may need to retransmit
*     a PCB, it replaces its FREE function with this empty
*     function, while preserving the original FREE function in
*     message->ORIG_FREE.
*
*     When the Tx finally does want to free the PCB, (either when
*     message->RETRIES reaches 0, or it receives a PPPCMD_STOP
*     command), it restores the original FREE function and calls
*     PCB_free().
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4

static void PPP_tx_pcbfree(PCB_PTR pcb) {}

#endif /* RTCSCFG_ENABLE_IP4 */

/*TASK*-----------------------------------------------------------------
*
* Task Name       :   PPP_tx_task
* Comments        :
*     This task receives requests from PPP_send().
*
*  When we receive a packet with a nonzero TIMEOUT field, we will
*  resend the packet RETRY times.
*
*  Packets to be retransmitted are put on a linked list (called the
*  retransmission queue) starting at xmithead.  This list is sorted
*  by time as follows:  for each packet 'message', message->DELTA is
*  the amount of time to wait before sending message, after sending
*  previous packet.  That is, xmithead->DELTA is the amount of time
*  to wait before sending xmithead, and xmithead->NEXT->DELTA is the
*  amount of time to wait bewteen sending xmithead and xmithead->NEXT.
*  Thus whenever we measure elapsed time, we only decrement the head
*  of the retransmission queue.
*
*  Every time through the loop, we do the following:
*
*     1) If the head of the retransmission queue timed out
*        (xmithead->DELTA <= 0), we resend it.
*
*     2) If the retransmission queue is nonempty, but the head
*        hasn't timed out, call _msgq_receive() with timeout
*        xmithead->DELTA.
*
*     3) If the retransmission queue is empty, call _msgq_receive()
*        with no timeout.
*
*     4) If _msgq_receive() timed out (case 2 only), resend the
*        head of the retransmission queue.
*
*     5) If _msgq_receive() obtained a control message (case 2 or 3),
*        process it.
*
*     6) If _msgq_receive() obtained a packet (case 2 or 3), send it.
*
*END*-----------------------------------------------------------------*/

void PPP_tx_task
   (
      pointer     handle,
            /* [IN] - the PPP state structure */
      pointer     creator
            /* [IN] - the creation information */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR       ppp_ptr = handle;
   uint_32           ctrl;
   boolean           state;
   PPP_OPT           opt;
   PCB_PTR           pcb;
   uint_32           pcbopt;
   PPP_MESSAGE_PTR   message, xmithead, _PTR_ xmitnode;
   uint_32           timebefore, timeafter;
   boolean           wait;
   int_32            timeout;
   uint_16           protocol;
   _queue_id         queue;
   pointer           param;

   /* Obtain a message queue so that PPP_send() can reach us */
   queue = RTCS_msgq_open(0, 0);
   if (queue == 0) {
      RTCS_task_exit(creator, RTCSERR_PPP_OPEN_QUEUE_FAILED);
   } /* Endif */

   RTCS_task_resume_creator(creator, PPP_OK);

   ppp_ptr->MSG_QUEUE = queue;

   xmithead = NULL;
   timebefore = RTCS_time_get();

#define PPPTX_DISCARD(msg) \
            (msg)->PCB->FREE = (msg)->ORIG_FREE;   \
            PCB_free((msg)->PCB);                  \
            RTCS_msg_free(msg)

   for (;;) {

      /**********************************************************
      **
      **    Wait for a packet to send
      **
      */

      wait = TRUE;
      timeout = 0;

      /* Check if a packet is waiting for retransmission */
      if (xmithead) {

         /* Measure elapsed time */
         timeafter = RTCS_time_get();
         timeout = RTCS_timer_get_interval(timebefore, timeafter); 
         timebefore = timeafter;
         xmithead->DELTA -= timeout;

         /* If its timer has expired, send it */
         timeout = xmithead->DELTA;
         if (timeout <= 0) {
            message = NULL;
            wait = FALSE;
         } /* Endif */
      } /* Endif */

      /*
      ** There are three cases at this point:
      **    1) Retransmission queue is empty
      **          (wait == TRUE,  timeout == 0, message == ?)
      **    2) Retransmission queue is nonempty, positive timeout
      **          (wait == TRUE,  timeout > 0,  message == ?)
      **    3) Retransmission queue is nonempty, nonpositive timeout,
      **       i.e., head of retransmission queue timed out
      **          (wait == FALSE, timeout == 0, message == NULL)
      */

      /* If there are no expired messages, block */
      if (wait) {
         message = RTCS_msgq_receive(queue, timeout, ppp_ptr->MSG_POOL);
      } /* Endif */

      /*
      ** There are two cases at this point:
      **    1) We got a message from _msgq_receive
      **          (message != NULL)
      **    2) Head of retransmission queue timed out
      **          (message == NULL)
      */

      /* We got a packet to send */
      if (message) {

         /* Control packets restart or stop retransmission */
         ctrl = message->COMMAND;

         if (ctrl == PPPCMD_SHUTDOWN) {
            param = message->PARAM;
            /* Free the message we just got */
            RTCS_msg_free(message);
            for (xmitnode = &xmithead;;){
               if (*xmitnode == NULL) {
                  break;
               } else {
                 /* unlink */
                 message = *xmitnode;
                 *xmitnode = message->NEXT;
                 /* Free the message from the list */
                 PPPTX_DISCARD(message);
               } /* Endif */
            } /* Endfor */
            RTCS_msgq_close(queue);
            /* Unblock PPP_shutdown() */
            RTCS_sem_post(param);
            /* Kill self */
            return;
         } /* Endif */
         
         if (ctrl != PPPCMD_SEND) {
            protocol = message->PROTOCOL;
            RTCS_msg_free(message);

            /*
            ** Search the retransmission queue for a packet
            ** matching the protocol field of the control message
            */
            for (xmitnode = &xmithead;;
                 xmitnode = &(*xmitnode)->NEXT) {
               if (*xmitnode == NULL) {
                  break;
               } else if ((*xmitnode)->PROTOCOL == protocol) {
                  message = *xmitnode;
                  switch (ctrl) {
                  case PPPCMD_RESTART:
                     message->TIMEOUT = _PPP_MIN_XMIT_TIMEOUT;
                     message->RETRY = _PPP_MAX_CONF_RETRIES;
                     break;
                  case PPPCMD_STOP:
                     if (message->NEXT) {
                        message->NEXT->DELTA += message->DELTA;
                     } /* Endif */
                     *xmitnode = message->NEXT;
                     PPPTX_DISCARD(message);
                     break;
                  } /* Endswitch */
                  break;
               } /* Endif */
            } /* Endfor */

            continue;
         } /* Endif */

         /* Save the PCB's FREE field */
         message->ORIG_FREE = message->PCB->FREE;
         if (message->TIMEOUT) {
            message->PCB->FREE = PPP_tx_pcbfree;
         } /* Endif */

      /* Receive timed out -- get the head of the retransmission queue */
      } else {
         message = xmithead;
         xmithead = message->NEXT;
         if (xmithead) {
            xmithead->DELTA += message->DELTA;
         } /* Endif */

         /* Generate a TO event */
         if (message->CALL) {
            message->CALL(message->PARAM, message->PCB, message->RETRY == 1);
         } /* Endif */

         /* RETRY == 0 means retry forever */
         if (message->RETRY) {

            /* When the retry count reaches zero, discard the packet */
            if (!--message->RETRY) {
               PPPTX_DISCARD(message);
               continue;
            } /* Endif */
         } /* Endif */

         /* Use exponential backoff when retransmitting */
         message->TIMEOUT <<= 1;
         if (message->TIMEOUT > _PPP_MAX_XMIT_TIMEOUT) {
            message->TIMEOUT = _PPP_MAX_XMIT_TIMEOUT;
         } /* Endif */
      } /* Endif */

      /**********************************************************
      **
      **    We have a packet -- validate it
      **
      */

      /* Take a snapshot of the current state and send options */
      PPP_mutex_lock(&ppp_ptr->MUTEX);
      state = ppp_ptr->LINK_STATE;
      opt = *ppp_ptr->SEND_OPTIONS;
      PPP_mutex_unlock(&ppp_ptr->MUTEX);

      /* Send the data packet (unless the link is not open) */
      if (!state && message->PROTOCOL != PPP_PROT_LCP) {
         PPPTX_DISCARD(message);
         ppp_ptr->ST_TX_DISCARDED++;
         continue;
      } /* Endif */

      /**********************************************************
      **
      **    We have a valid packet -- send it
      **
      */

      /* LCP control packets are always sent with default options */
      if (message->PROTOCOL == PPP_PROT_LCP
       && message->PCB->FRAG[0].FRAGMENT[2] >= 1
       && message->PCB->FRAG[0].FRAGMENT[2] <= 7) {
         pcbopt = 1;
      } else {
         pcbopt = 0;
      } /* Endif */

      pcb = message->PCB;

      /* Only data packets are compressed */
      /* Start CR 2296 */
      if (((message->PROTOCOL & 0xC000) == 0) && opt.CP) {
      /* End CR 2296 */
         pcb = opt.CP->CP_comp(&ppp_ptr->CCP_STATE.SEND_DATA, pcb, ppp_ptr, &opt);
         htons(pcb->FRAG[0].FRAGMENT, PPP_PROT_CP);
      } /* Endif */

      _iopcb_write(ppp_ptr->DEVICE, pcb, pcbopt);

      /**********************************************************
      **
      **    Packet is sent -- update retransmission queue
      **
      */

      /* Free the buffer unless it may need to be retransmitted */
      if (message->TIMEOUT) {

         /* Measure elapsed time */
         timeafter = RTCS_time_get();
         timeout = RTCS_timer_get_interval(timebefore, timeafter); 
         timebefore = timeafter;
         if (xmithead) {
            xmithead->DELTA -= timeout;
         } /* Endif */

         /* Insert packet into proper place in retransmission queue */
         for (message->DELTA = message->TIMEOUT,    xmitnode = &xmithead;;
              message->DELTA -= (*xmitnode)->DELTA, xmitnode = &(*xmitnode)->NEXT) {
            if (*xmitnode == NULL) {
               /* Add packet at tail of queue */
               message->NEXT = NULL;
               *xmitnode = message;
               break;
            } else if ((*xmitnode)->DELTA > message->TIMEOUT) {
               /* Insert packet in middle (possibly head) of queue */
               (*xmitnode)->DELTA -= message->DELTA;
               message->NEXT = *xmitnode;
               *xmitnode = message;
               break;
            } /* Endif */
         } /* Endfor */

      } else {
         /* PCB has already been freed by _iopcb_write() */
         RTCS_msg_free(message);
      } /* Endif */

   } /* Endfor */
   
#endif /* RTCSCFG_ENABLE_IP4 */
   
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/inet_pton.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: inet_pton.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
*END************************************************************************/

/*
 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
 * Copyright (c) 1996,1999 by Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <string.h>
#include <ctype.h>
#include <rtcs.h>

static int_32	inet_pton4(const char *src, in_addr *dst);
static int_32	inet_pton6(const char *src, in6_addr *dst);

/****************************************************************************************
 * int
 * inet_pton(af, src, dst)
 *	convert from presentation format (which usually means ASCII printable)
 *	to network format (which is usually some kind of binary format).
 * return:
 *	RTCS_OK if the address was valid for the specified address family
 *	RTCS_ERROR if the address wasn't valid (`dst' is untouched in this case)
 *	RTCS_ERROR if some other error occurred (`dst' is untouched in this case, too)
 ***************************************************************************************/
int_32 inet_pton (
                     int_32 af,               /*[IN]  family name                     */
                     const char *src,         /*[IN]  pointer to prn form of address  */
                     void *dst,               /*[OUT] pointer to bin form of address  */
                     unsigned int sizeof_dst  /*[IN]  size of dst buffer              */
                 )
{
	switch (af) {
	case AF_INET:
	    /*checking value sizeof_dst of output buffer to avoid overflow*/
        if(sizeof_dst < sizeof( *((in_addr*)dst) ))
	    {
	        return (RTCS_ERROR);
	    }
		return (inet_pton4(src, dst));
	case AF_INET6:
		/*checking value sizeof_dst of output buffer to avoid overflow*/
        if(sizeof_dst < sizeof(*((in6_addr*)dst)) )
	    {
	        return (RTCS_ERROR);
	    }
		return (inet_pton6(src, dst));
	default:
		return (RTCS_ERROR);
	}
}


/****************************************************************************************
 * int
 * inet_pton4(src, dst)
 *	like inet_aton() but without all the hexadecimal and shorthand.
 * return:
 *	RTCS_OK if `src' is a valid dotted quad, else RTCS_ERROR.
 * notice:
 *	does not touch `dst' unless it's returning 1.
 ****************************************************************************************/

static int_32 inet_pton4(
                            const char *src, /*[IN]  pointer to inet4 address in prn format */
                            in_addr *dst     /*[OUT] pointer to inet4 address in bin format */
                         )
{
	static const char digits[] = "0123456789";
	int saw_digit, octets, ch;
	uchar tmp[sizeof(*dst)], *tp;
    uint_32 temp=0;

	saw_digit = 0;
	octets = 0;
	*(tp = tmp) = 0;
	while ((ch = *src++) != '\0')
	{
		const char *pch;

		if ((pch = strchr(digits, ch)) != NULL)
		{
			unsigned int new = *tp * 10 + (pch - digits);

			if (saw_digit && *tp == 0)
			{
				return  (RTCS_ERROR);
			}
			if (new > 255)
			{
				return(RTCS_ERROR);
			}
			*tp = new;
			if (!saw_digit)
			{
				if (++octets > 4)
				{
					return(RTCS_ERROR);
				}
				saw_digit = 1;
			}
		}
		else if (ch == '.' && saw_digit)
		{
			if (octets == 4)
			{
				return(RTCS_ERROR);
			}
			*++tp = 0;
			saw_digit = 0;
		}
		else
		{
			return(RTCS_ERROR);
        }
	}
	if (octets < 4)
	{
		return(RTCS_ERROR);
	}

	memcpy(&temp, tmp, sizeof(temp));
	htonl(dst,temp);




	return (RTCS_OK);
}

/****************************************************************************************
 * int
 * inet_pton6(src, dst)
 *	convert presentation level address to network order binary form.
 * return:
 *	RTCS_OK if `src' is a valid [RFC1884 2.2] address, else RTCS_ERROR.
 * notice:
 *	(1) does not touch `dst' unless it's returning 1.
 *	(2) :: in a full address is silently ignored.
 * credit:
 *	inspired by <NAME>.
 ****************************************************************************************/
static int_32 inet_pton6(
                            const char *src,/*[IN]  pointer to inet6 address in prn format */
                            in6_addr *dst   /*[OUT] pointer to inet6 address in bin format */
                         )
{
	static const char   xdigits_l[] = "0123456789abcdef",
			            xdigits_u[] = "0123456789ABCDEF";
	uchar tmp[sizeof(*dst)], *tp, *endp, *colonp;
	const char *xdigits, *curtok;
	int ch, seen_xdigits;
	unsigned int val;

	#ifndef	NS_INADDRSZ
	    #define NS_INADDRSZ     4
	#endif

	#ifndef NS_INT16SZ
		#define NS_INT16SZ		2
	#endif

	memset((tp = tmp), '\0', sizeof(*dst));
	endp = tp + sizeof(*dst);
	colonp = NULL;
	/* Leading :: requires some special handling. */
	if (*src == ':')
		if (*++src != ':')
			return(RTCS_ERROR);
	curtok = src;
	seen_xdigits = 0;
	val = 0;
	while ((ch = *src++) != '\0') {
		const char *pch;

		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
			pch = strchr((xdigits = xdigits_u), ch);
		if (pch != NULL) {
			val <<= 4;
			val |= (pch - xdigits);
			if (++seen_xdigits > 4)
				return(RTCS_ERROR);
			continue;
		}
		if (ch == ':') {
			curtok = src;
			if (!seen_xdigits) {
				if (colonp)
					return(RTCS_ERROR);
				colonp = tp;
				continue;
			} else if (*src == '\0') {
				return(RTCS_ERROR);
			}
			if (tp + NS_INT16SZ > endp)
				return(RTCS_ERROR);
			*tp++ = (uchar) (val >> 8) & 0xff;
			*tp++ = (uchar) val & 0xff;
			seen_xdigits = 0;
			val = 0;
			continue;
		}
		if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) > 0)
		{
		    if(inet_pton4(curtok,(in_addr*)tp) == RTCS_OK)
		    {
			    tp += NS_INADDRSZ;
			    seen_xdigits = 0;
			    break;	/*%< '\\0' was seen by inet_pton4(). */
            }
		}
		return(RTCS_ERROR);
	}
	if (seen_xdigits) {
		if (tp + NS_INT16SZ > endp)
			return(RTCS_ERROR);
		*tp++ = (uchar) (val >> 8) & 0xff;
		*tp++ = (uchar) val & 0xff;
	}
	if (colonp != NULL) {
		/*
		 * Since some memmove()'s erroneously fail to handle
		 * overlapping regions, we'll do the shift by hand.
		 */
		const int n = tp - colonp;
		int i;

		if (tp == endp)
			return(RTCS_ERROR);
		for (i = 1; i <= n; i++) {
			endp[- i] = colonp[n - i];
			colonp[n - i] = 0;
		}
		tp = endp;
	}
	if (tp != endp)
		return(RTCS_ERROR);
	memcpy(dst, tmp, sizeof(*dst));
	return (RTCS_OK);
}



<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/dir_read.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dir_read.c$
* $Version : 3.6.14.0$
* $Date    : Oct-5-2012$
*
* Comments:
*
*   This file contains the functions for a partition manager device that is 
*   is built to work under MFS1.40. These functions can also create or 
*   remove partitions from a disk.
*
*END************************************************************************/


#include <string.h>
#include <mqx.h>
#include <fio.h>
#include "mfs.h"
#include "mfs_prv.h"


// Nees to be integrated into fopen (dirname, "d+mode_ptr"); etc


#define  FS_DIR_MODE_UNIX        1
#define  FS_DIR_MODE_MSDOS       2
#define  FS_DIR_MODE_FILENAME    3

typedef struct
{
    MQX_FILE_PTR         FS_PTR;
    MFS_GET_LFN_STRUCT   LFN_DATA;
    MFS_SEARCH_DATA      SEARCH_DATA;
    MFS_SEARCH_PARAM     SEARCH;
    char                 LFN[PATHNAME_SIZE];
    uint_32              MODE;
    boolean              FIRST;
} DIR_STRUCT, _PTR_ DIR_STRUCT_PTR;


pointer _io_mfs_dir_open(MQX_FILE_PTR fs_ptr, char_ptr wildcard_ptr, char_ptr mode_ptr)
{
    DIR_STRUCT_PTR       dir_ptr;
    uchar                attr = 0;
    uint_32              i;

    if ( fs_ptr == NULL ) return NULL;

    dir_ptr = (DIR_STRUCT_PTR) MFS_mem_alloc_zero( sizeof(DIR_STRUCT) );
    if ( dir_ptr == NULL )
        return NULL;

    _mem_set_type(dir_ptr, MEM_TYPE_MFS_DIR_STRUCT);

    dir_ptr->FS_PTR = fs_ptr;
    dir_ptr->SEARCH.WILDCARD = wildcard_ptr;

    dir_ptr->SEARCH.SEARCH_DATA_PTR = &dir_ptr->SEARCH_DATA;
    dir_ptr->SEARCH.ATTRIBUTE = attr;
    dir_ptr->MODE = FS_DIR_MODE_UNIX;

    if ( mode_ptr != NULL )
    {
        for ( i=0; mode_ptr[i]; i++ )
        {
            switch ( mode_ptr[i] )
            {
                case '*': 
                    attr = MFS_ATTR_ANY;
                    break;

                case 'r': 
                    attr |= MFS_ATTR_READ_ONLY;    
                    break;

                case 's': 
                    attr |= MFS_ATTR_SYSTEM_FILE;
                    break;

                case 'h': 
                    attr |= MFS_ATTR_HIDDEN_FILE;
                    break;

                case 'd': 
                    attr |= MFS_ATTR_DIR_NAME;
                    break;

                case 'v': 
                    attr |= MFS_ATTR_VOLUME_NAME;
                    break;

                case 'a': 
                    attr |= MFS_ATTR_ARCHIVE;
                    break;

                case 'u': 
                    dir_ptr->MODE = FS_DIR_MODE_UNIX;
                    break;

                case 'm': 
                    dir_ptr->MODE = FS_DIR_MODE_MSDOS;
                    break;

                case 'f': 
                    dir_ptr->MODE = FS_DIR_MODE_FILENAME;
                    break;

                default:                           
                    break;
            }
        }
        dir_ptr->SEARCH.ATTRIBUTE = attr;
    }

    dir_ptr->LFN_DATA.PATHNAME = dir_ptr->SEARCH_DATA.NAME;
    dir_ptr->LFN_DATA.LONG_FILENAME = dir_ptr->LFN;
    dir_ptr->LFN_DATA.SEARCH_DATA_PTR = &dir_ptr->SEARCH_DATA;

    dir_ptr->FIRST = TRUE;

    return(pointer) dir_ptr;
}   


static const char_ptr months[] =  
{
    "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 
};



int_32 _io_mfs_dir_read( pointer dir, char_ptr buffer, uint_32 size)
{
    DIR_STRUCT_PTR       dir_ptr = (DIR_STRUCT_PTR) dir;
    uint_32              error_code;
    uint_32              month;
    uint_32              year;
    uint_32              ofs;
    uint_32              len=0;

    if ( dir_ptr == NULL ) return IO_ERROR;

    if ( dir_ptr->FIRST )
    {
        error_code = ioctl(dir_ptr->FS_PTR, IO_IOCTL_FIND_FIRST_FILE, (pointer)&dir_ptr->SEARCH);
        dir_ptr->FIRST = FALSE;
    }
    else
    {
        error_code = ioctl(dir_ptr->FS_PTR, IO_IOCTL_FIND_NEXT_FILE,  (pointer) &dir_ptr->SEARCH_DATA);
    }
    if ( error_code != MFS_NO_ERROR )
    {
        return IO_ERROR;
    }
    /* read file */
    error_code = ioctl(dir_ptr->FS_PTR, IO_IOCTL_GET_LFN, (pointer)&dir_ptr->LFN_DATA);
    /* attributes test */
        
    if ( dir_ptr->MODE == FS_DIR_MODE_MSDOS )
    {    
        ofs = len<size ? len : size;
        len = snprintf(buffer+ofs, size-ofs, "%-12.12s %8lu %02lu-%02lu-%04lu %02lu:%02lu:%02lu %c%c%c%c%c%c ",
            dir_ptr->SEARCH_DATA.NAME, dir_ptr->SEARCH_DATA.FILE_SIZE,

            (uint_32)(dir_ptr->SEARCH_DATA.DATE & MFS_MASK_MONTH) >> MFS_SHIFT_MONTH,
            (uint_32)(dir_ptr->SEARCH_DATA.DATE & MFS_MASK_DAY)   >> MFS_SHIFT_DAY,
            (uint_32)((dir_ptr->SEARCH_DATA.DATE & MFS_MASK_YEAR) >> MFS_SHIFT_YEAR) + 1980,

            (uint_32)(dir_ptr->SEARCH_DATA.TIME & MFS_MASK_HOURS)   >> MFS_SHIFT_HOURS,
            (uint_32)(dir_ptr->SEARCH_DATA.TIME & MFS_MASK_MINUTES) >> MFS_SHIFT_MINUTES,
            (uint_32)(dir_ptr->SEARCH_DATA.TIME & MFS_MASK_SECONDS) << 1,

            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_READ_ONLY) ? 'R':' ',
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_HIDDEN_FILE) ? 'H':' ',
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_SYSTEM_FILE) ? 'S':' ',
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_VOLUME_NAME) ? 'V':' ',
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_DIR_NAME) ? 'D':' ',
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_ARCHIVE) ? 'A':' ');
    }
    else if ( dir_ptr->MODE == FS_DIR_MODE_UNIX )
    {
        ofs = len<size ? len : size;
        len += snprintf(buffer+ofs, size-ofs, "%cr%c-r%c-r%c-   1 ",
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_DIR_NAME)?'d':'-',

            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_READ_ONLY)?'-':'w',
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_READ_ONLY)?'-':'w',
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_READ_ONLY)?'-':'w',
            (dir_ptr->SEARCH_DATA.ATTRIBUTE & MFS_ATTR_DIR_NAME)?'+':' ');

        ofs = len<size ? len : size;
        len += snprintf(buffer+ofs, size-ofs, "ftp      ftp  "); 

        ofs = len<size ? len : size;
        len += snprintf (buffer+ofs, size-ofs, "  %10lu ",  dir_ptr->SEARCH_DATA.FILE_SIZE );

        month = (uint_32)(dir_ptr->SEARCH_DATA.DATE & MFS_MASK_MONTH) >> MFS_SHIFT_MONTH;
        if (month > 12)
            month = 0;

        ofs = len<size ? len : size;
        len += snprintf (buffer+ofs, size-ofs, "%3s %02d ", months[month], 
            (uint_32)(dir_ptr->SEARCH_DATA.DATE & MFS_MASK_DAY) );

        year = (uint_32)((dir_ptr->SEARCH_DATA.DATE & MFS_MASK_YEAR) >> MFS_SHIFT_YEAR) + 1980;
        ofs = len<size ? len : size;
        len += snprintf (buffer+ofs, size-ofs, " %4d ", year ); 
    }

    if ( !error_code )
    {
        ofs = len<size ? len : size;
        len += snprintf (buffer+ofs, size-ofs, "%s\r\n",dir_ptr->LFN ); 
    }
    else
    {
        ofs = len<size ? len : size;
        len += snprintf (buffer+ofs, size-ofs, "%s\r\n",dir_ptr->SEARCH_DATA.NAME ); 
    }

    /* Terminate the string for sure */
    if (size > 0)
        buffer[size - 1] = '\0';

    return len;
} 


int_32 _io_mfs_dir_close( pointer dir)
{
    if ( dir == NULL ) return IO_ERROR;
    _mem_free(dir);
    return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/mutex_prv.h<|end_filename|>
/*HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mutex_prv.h$
* $Version : 3.8.0.1$
* $Date    : Feb-20-2012$
*
* Comments:
*
*   This include file is used to define constants and data types
*   private to the mutex component.
*
*END************************************************************************/
#ifndef __mutex_prv_h__
#define __mutex_prv_h__ 1

/*--------------------------------------------------------------------------*/
/* 
 *                      CONSTANT DECLARATIONS
 */

/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief This structure defines the mutex component data structure.
 */
typedef struct mutex_component_struct 
{

   /*! \brief A queue of all created mutexes. */
   QUEUE_STRUCT MUTEXES;
      
   /*! \brief A validation field for mutexes. */
   _mqx_uint     VALID;
     
} MUTEX_COMPONENT_STRUCT, _PTR_ MUTEX_COMPONENT_STRUCT_PTR;
/*! \endcond */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern void _mutex_cleanup(TD_STRUCT_PTR);
#endif

#ifdef __cplusplus
}
#endif

#endif  /* __mutex_prv_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_time.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_time.h$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*   This file contains the definitions for time as used by the PSP.
*
*END************************************************************************/

#ifndef __psp_time_h__
#define __psp_time_h__

/*
** Macros and defines to manipulate the tick struct
*/
#define PSP_NUMBER_OF_TICK_FIELDS   (1)
#define PSP_NUMBER_OF_HWTICK_FIELDS (1)

/* Macro to retrieve the least significant _mqx_uint from a tick struct */
#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
   #define PSP_GET_LS_TICK_FROM_TICK_STRUCT(t_ptr) \
      (((MQX_TICK_STRUCT_PTR)(t_ptr))->TICKS[0])
#else
   #define PSP_GET_LS_TICK_FROM_TICK_STRUCT(t_ptr) \
      (((MQX_TICK_STRUCT_PTR)(t_ptr))->TICKS[MQX_NUM_TICK_FIELDS-1])
#endif

/* Macro to retrieve a _mqx_uint from a tick struct */
#define PSP_GET_ELEMENT_FROM_TICK_STRUCT(t_ptr, idx) \
   (((PSP_TICK_STRUCT_PTR)(t_ptr))->TICKS[0])

/* Macro increments to incrment tick structure */
#define PSP_INC_TICKS(t_ptr)  (++(((PSP_TICK_STRUCT_PTR)(t_ptr))->TICKS[0]))
   
#define PSP_NORMALIZE_TICKS(tick_ptr)	_psp_normalize_ticks((PSP_TICK_STRUCT_PTR)(tick_ptr))

/* Macro to add two tick structures including hw ticks */
#define PSP_ADD_TICKS(a_ptr, b_ptr, r_ptr)                                    \
   _psp_add_ticks((PSP_TICK_STRUCT_PTR)(a_ptr), (PSP_TICK_STRUCT_PTR)(b_ptr), \
      (PSP_TICK_STRUCT_PTR)(r_ptr))

/* Macro to subtract two tick structures NOT including hw ticks */
#define PSP_SUB_TICKS(a_ptr, b_ptr, r_ptr)    \
   _psp_subtract_ticks((PSP_TICK_STRUCT_PTR)(a_ptr), (PSP_TICK_STRUCT_PTR)(b_ptr), \
      (PSP_TICK_STRUCT_PTR)(r_ptr))

/* Macro to subtract two tick structures NOT including hw ticks and clamp into int32 interval */
#define PSP_SUB_TICKS_INT32(a_ptr, b_ptr, o_ptr)    \
   _psp_subtract_ticks_int32((PSP_TICK_STRUCT_PTR)(a_ptr), (PSP_TICK_STRUCT_PTR)(b_ptr), \
      (boolean _PTR_)(o_ptr))

/* Macro to add a single quantity of ticks to a tick structure */
#define PSP_ADD_TICKS_TO_TICK_STRUCT(a_ptr, v, r_ptr) \
   ((PSP_TICK_STRUCT_PTR)(r_ptr))->TICKS[0] = \
   ((PSP_TICK_STRUCT_PTR)(a_ptr))->TICKS[0] + (uint_64)(v)

/* Macro to subtract a single quantity of ticks from a tick structure */
#define PSP_SUB_TICKS_FROM_TICK_STRUCT(a_ptr, v, r_ptr) \
   ((PSP_TICK_STRUCT_PTR)(r_ptr))->TICKS[0] = \
   ((PSP_TICK_STRUCT_PTR)(a_ptr))->TICKS[0] - (uint_64)(v)

/* Macro to multipy the ticks by a 32 bit quantity */
#define PSP_MULTIPLY_TICKS_BY_UINT_32(m_ptr, m, r_ptr) \
   ((PSP_TICK_STRUCT_PTR)(r_ptr))->TICKS[0] = ((PSP_TICK_STRUCT_PTR)(m_ptr))->TICKS[0] * (uint_32)(m)

/* 
** Returns  1 if a >  b
** Returns -1 if a <  b
** Returns  0 if a == b
*/
#define PSP_CMP_TICKS(a_ptr, b_ptr) \
     ((((PSP_TICK_STRUCT_PTR)(a_ptr))->TICKS[0] > ((PSP_TICK_STRUCT_PTR)(b_ptr))->TICKS[0]) ?  1 : \
     (((PSP_TICK_STRUCT_PTR)(a_ptr))->TICKS[0] < ((PSP_TICK_STRUCT_PTR)(b_ptr))->TICKS[0]) ? -1 : \
     0 )

#define PSP_TICKS_TO_TIME(tick_ptr, time_ptr) \
   _psp_ticks_to_time((PSP_TICK_STRUCT_PTR)(tick_ptr), \
      (TIME_STRUCT_PTR)(time_ptr))
#define PSP_TIME_TO_TICKS(time_ptr, tick_ptr) \
   _psp_time_to_ticks((TIME_STRUCT_PTR)(time_ptr), \
      (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_TICKS_TO_XDATE(tick_ptr, xdate_ptr) \
   _psp_ticks_to_xdate((PSP_TICK_STRUCT_PTR)(tick_ptr), xdate_ptr)

#define PSP_TICKS_TO_DAYS(tick_ptr, o_ptr) \
   _psp_ticks_to_days((PSP_TICK_STRUCT_PTR)(tick_ptr), \
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_HOURS(tick_ptr, o_ptr) \
   _psp_ticks_to_hours((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_MINUTES(tick_ptr, o_ptr) \
   _psp_ticks_to_minutes((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_SECONDS(tick_ptr, o_ptr) \
   _psp_ticks_to_seconds((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_MILLISECONDS(tick_ptr, o_ptr) \
   _psp_ticks_to_milliseconds((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_MILLISECONDS_TRUNCATE(tick_ptr, o_ptr) \
   _psp_ticks_to_milliseconds_truncate((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_MICROSECONDS(tick_ptr, o_ptr) \
   _psp_ticks_to_microseconds((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_MICROSECONDS_TRUNCATE(tick_ptr, o_ptr) \
   _psp_ticks_to_microseconds_truncate((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_NANOSECONDS(tick_ptr, o_ptr) \
   _psp_ticks_to_nanoseconds((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_NANOSECONDS_TRUNCATE(tick_ptr, o_ptr) \
   _psp_ticks_to_nanoseconds_truncate((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_PICOSECONDS(tick_ptr, o_ptr) \
   _psp_ticks_to_picoseconds((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))
#define PSP_TICKS_TO_PICOSECONDS_TRUNCATE(tick_ptr, o_ptr) \
   _psp_ticks_to_picoseconds_truncate((PSP_TICK_STRUCT_PTR)(tick_ptr),\
      (boolean _PTR_)(o_ptr))

#define PSP_GET_ELAPSED_MILLISECONDS() \
   _psp_get_elapsed_milliseconds()

#define PSP_DAYS_TO_TICKS(days, tick_ptr) \
   _psp_days_to_ticks((_mqx_uint)(days), (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_HOURS_TO_TICKS(hours, tick_ptr) \
   _psp_hours_to_ticks((_mqx_uint)(hours), (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_MINUTES_TO_TICKS(mins, tick_ptr) \
   _psp_minutes_to_ticks((_mqx_uint)(mins), (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_SECONDS_TO_TICKS(secs, tick_ptr) \
   _psp_seconds_to_ticks((_mqx_uint)(secs), (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_MILLISECONDS_TO_TICKS(msecs, tick_ptr) \
   _psp_msecs_to_ticks((_mqx_uint)(msecs), (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_MILLISECONDS_TO_TICKS_QUICK(msecs, tick_ptr) \
   _psp_msecs_to_ticks_quick((_mqx_uint)(msecs), (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_MICROSECONDS_TO_TICKS(usecs, tick_ptr) \
   _psp_usecs_to_ticks((_mqx_uint)(usecs), (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_NANOSECONDS_TO_TICKS(nsecs, tick_ptr) \
   _psp_nsecs_to_ticks((_mqx_uint)(nsecs), (PSP_TICK_STRUCT_PTR)(tick_ptr))
#define PSP_PICOSECONDS_TO_TICKS(psecs, tick_ptr) \
   _psp_psecs_to_ticks((_mqx_uint)(psecs), (PSP_TICK_STRUCT_PTR)(tick_ptr))

#define PSP_PRINT_TICKS(tick_ptr) \
   _psp_print_ticks((PSP_TICK_STRUCT_PTR)(tick_ptr))


#ifndef __ASM__

/*-----------------------------------------------------------------------*/
/*
** PSP TICK STRUCT
**
** The representation of the MQX tick struct from the PSP's
** view
**
*/
/* 
** The _Packed keyword is specific to the MetaWare compiler. It will force the
** the PSP_TICK_STRUCT to be aligned on 32 bit boundaries instead of 64. This
** will allow casting between the PSP_TICK_STRUCT and the MQX_TICK_STRUCT
*/
typedef struct psp_tick_struct
{
   /* We need 64 bits for the ticks */
   uint_64    TICKS[PSP_NUMBER_OF_TICK_FIELDS];

   /* also need 32 bits for the hw ticks */
   uint_32    HW_TICKS[PSP_NUMBER_OF_HWTICK_FIELDS];

} PSP_TICK_STRUCT, _PTR_ PSP_TICK_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                  PROTOTYPES OF PSP FUNCTIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

void      _psp_add_ticks(PSP_TICK_STRUCT_PTR, PSP_TICK_STRUCT_PTR, 
   PSP_TICK_STRUCT_PTR);
void      _psp_subtract_ticks(PSP_TICK_STRUCT_PTR, PSP_TICK_STRUCT_PTR, 
   PSP_TICK_STRUCT_PTR);
int_32    _psp_subtract_ticks_int32(PSP_TICK_STRUCT_PTR, PSP_TICK_STRUCT_PTR, 
   boolean _PTR_);
void      _psp_mul_ticks_by_32(PSP_TICK_STRUCT_PTR, uint_32,
   PSP_TICK_STRUCT_PTR);

uint_32   _psp_ticks_to_time(PSP_TICK_STRUCT_PTR, TIME_STRUCT_PTR);
boolean   _psp_ticks_to_xdate(PSP_TICK_STRUCT_PTR, MQX_XDATE_STRUCT_PTR);

uint_32   _psp_ticks_to_days(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_hours(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_minutes(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_seconds(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_milliseconds(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_milliseconds_truncate(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_microseconds(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_microseconds_truncate(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_nanoseconds(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_nanoseconds_truncate(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_picoseconds(PSP_TICK_STRUCT_PTR, boolean _PTR_);
uint_32   _psp_ticks_to_picoseconds_truncate(PSP_TICK_STRUCT_PTR, boolean _PTR_);

uint_32   _psp_get_elapsed_milliseconds(void);
void      _psp_time_to_ticks(TIME_STRUCT_PTR, PSP_TICK_STRUCT_PTR);
boolean   _psp_xdate_to_ticks(MQX_XDATE_STRUCT_PTR, PSP_TICK_STRUCT_PTR);

void      _psp_days_to_ticks(_mqx_uint, PSP_TICK_STRUCT_PTR);
void      _psp_hours_to_ticks(_mqx_uint, PSP_TICK_STRUCT_PTR);
void      _psp_minutes_to_ticks(_mqx_uint, PSP_TICK_STRUCT_PTR);
void      _psp_seconds_to_ticks(_mqx_uint, PSP_TICK_STRUCT_PTR);
void      _psp_msecs_to_ticks(_mqx_uint, PSP_TICK_STRUCT_PTR);
void      _psp_msecs_to_ticks_quick(_mqx_uint, PSP_TICK_STRUCT_PTR);
void      _psp_usecs_to_ticks(_mqx_uint, PSP_TICK_STRUCT_PTR);
void      _psp_nsecs_to_ticks(_mqx_uint, PSP_TICK_STRUCT_PTR);
void      _psp_psecs_to_ticks(_mqx_uint, PSP_TICK_STRUCT_PTR);

void      _psp_print_ticks(PSP_TICK_STRUCT_PTR);

void      _psp_normalize_ticks(PSP_TICK_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif /* __ASM__ */

#endif /*__psp_time_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/ehci/ehci_utl.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_utl.c$
* $Version : 3.8.7.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the low-level Host API functions specific to the VUSB 
*   chip.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "hostapi.h"
#include "ehci_prv.h"

#include "ehci_utl.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_bus_control
*  Returned Value : None
*  Comments       :
*        Bus control
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_ehci_bus_control
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle        handle,

      /* The operation to be performed on the bus */
      uint_8                  bControl
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   switch(bControl) {
      case USB_ASSERT_BUS_RESET:
         break;
      case USB_ASSERT_RESUME:
         break;
      case USB_SUSPEND_SOF:
         _usb_ehci_bus_suspend(handle);
         break;
      case USB_DEASSERT_BUS_RESET:
      case USB_RESUME_SOF:
      case USB_DEASSERT_RESUME:
      default:
         break;
   } /* EndSwitch */
   
   return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_bus_suspend
*  Returned Value : None
*  Comments       :
*        Suspend the bus
*END*-----------------------------------------------------------------*/

void _usb_ehci_bus_suspend
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle              handle
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   VUSB20_REG_STRUCT_PTR                        cap_dev_ptr;
   uint_8                                       i, total_port_numbers;
   uint_32                                      port_control;
   USB_EHCI_HOST_INIT_STRUCT_PTR                param;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   param = (USB_EHCI_HOST_INIT_STRUCT_PTR) usb_host_ptr->G.INIT_PARAM;

   cap_dev_ptr = (VUSB20_REG_STRUCT_PTR) param->CAP_BASE_PTR;
   dev_ptr = (VUSB20_REG_STRUCT_PTR) usb_host_ptr->G.DEV_PTR;
      
   total_port_numbers = 
   (uint_8)((EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.HCS_PARAMS) & 
         EHCI_HCS_PARAMS_N_PORTS));
         
   USB_lock();
      

   /* Suspend all ports */
   for (i=0;i<total_port_numbers;i++) {
      port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);
      
      if (port_control & EHCI_PORTSCX_PORT_ENABLE) {
      
         port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]);
         port_control &= ~EHCI_PORTSCX_W1C_BITS;
         
         EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i],(port_control | EHCI_PORTSCX_PORT_SUSPEND));
      } /* Endif */
      
   } /* Endfor */
   
   /* Stop the controller 
   SGarg: This should not be done. If the controller is stopped, we will
   get no attach or detach interrupts and this will stop all operatings
   including the OTG state machine which is still running assuming that
   Host is alive.
   
   EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_CMD_RUN_STOP);
   */   
      
   USB_unlock();
   
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_bus_resume
*  Returned Value : None
*  Comments       :
*        Resume the bus
*END*-----------------------------------------------------------------*/

void _usb_ehci_bus_resume
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle              handle,

      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR          pipe_descr_ptr
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   VUSB20_REG_STRUCT_PTR                        cap_dev_ptr;
   uint_8                                       i, total_port_numbers;
   uint_32                                      port_control;
   USB_EHCI_HOST_INIT_STRUCT_PTR                param;

   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   param = (USB_EHCI_HOST_INIT_STRUCT_PTR) usb_host_ptr->G.INIT_PARAM;

   cap_dev_ptr = (VUSB20_REG_STRUCT_PTR) param->CAP_BASE_PTR;
   dev_ptr = (VUSB20_REG_STRUCT_PTR) usb_host_ptr->G.DEV_PTR;
   
   total_port_numbers = (uint_8)(EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.HCS_PARAMS) & EHCI_HCS_PARAMS_N_PORTS);

   USB_lock();
      

   /* Resume all ports */
   for (i=0;i<total_port_numbers;i++) {
      port_control = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i]);
      
      if (port_control & EHCI_PORTSCX_PORT_ENABLE) {
         port_control &= ~EHCI_PORTSCX_W1C_BITS;
         EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PORTSCX[i],(port_control | EHCI_PORTSCX_PORT_FORCE_RESUME));
      } /* Endif */
      
   } /* Endfor */
   
   /* 
    S Garg: This should not be done. See comments in suspend.
      Restart the controller   
      EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,EHCI_CMD_RUN_STOP);
     */

   USB_unlock();
   
} /* EndBody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/VIC_control.c<|end_filename|>
#include <mqx.h>
#include <bsp.h>
#include <fio.h>
#include "App.h"


/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void Set_VIC_chanel(unsigned char irq_ch, unsigned char preemp_prio, unsigned char sub_prio)
{
  NVIC_MemMapPtr NVIC = NVIC_BASE_PTR;
  SCB_MemMapPtr  SCB  = SystemControl_BASE_PTR;
  unsigned int prio;

  
  irq_ch -= 16; // Конвертировать индекс в массиве векторов в номер прерывания для регистров NVIC 

  /* Compute the Corresponding IRQ Priority --------------------------------*/
  prio = (SCB->AIRCR  >> 8) & 0x07; // Определим сколько бит выделяется под приоритет

  // Используються только 4-е старших бита
  switch (prio)
  {
  case 0:
    // bxxxxxxx.y
    prio = preemp_prio;
    break;
  case 1:
    // bxxxxxx.yy
    prio = preemp_prio;
    break;
  case 2:
    // bxxxxx.yyy
    prio = preemp_prio;
    break;
  case 3:
    // bxxxx.yyyy
    prio = preemp_prio;
    break;
  case 4:
    // bxxx.yyyyy
    prio = (preemp_prio << 1) | (sub_prio & 0x01);
    break;
  case 5:
    // bxx.yyyyyy
    prio = (preemp_prio << 2) | (sub_prio & 0x03);
    break;
  case 6:
    // bx.yyyyyyy
    prio = (preemp_prio << 3) | (sub_prio & 0x07);
    break;
  case 7:
    // b.yyyyyyyy
    prio = sub_prio & 0x0F;
    break;
  }

  prio = prio << 4;                 // Установим приоритет в нужной позиции в 8-и разрядном регистре с учетом имплементации только 4-х старших битов
  NVIC->IP[irq_ch] = prio;          // Записать в контроллер VIC

  /* Enable the Selected IRQ Channels --------------------------------------*/
  NVIC->ISER[(irq_ch >> 0x05)] = 0x01 << (irq_ch & 0x1F);
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void Disable_VIC_chanel(unsigned char irq_ch)
{
  NVIC_MemMapPtr NVIC = NVIC_BASE_PTR;
  /* Disable the Selected IRQ Channels -------------------------------------*/
  NVIC->ICER[(irq_ch >> 0x05)] = 0x01 << (irq_ch & 0x1F);
}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/mqx.h<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2008-2012 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mqx.h$
* $Version : 3.8.94.0$
* $Date    : Jul-27-2012$
*
* Comments:
*
*   This file contains the structure definitions and constants for an
*   application which will be using MQX.
*   All compiler provided header files must be included before mqx.h.
*
*END************************************************************************/

#ifndef __mqx_h__
#define __mqx_h__


#if defined(__CWBUILD__)
/* CW 10.1 compilation issue - switch off peephole optimization */
#if  (__CWBUILD__ == 3009)
#pragma peephole off
#pragma no_register_coloring on
#endif

/* CW 10.1 Cortex compiler 2402 build patch */
#if (__arm__)
#if (__CWBE__ < 0x05000200)
#error  You need to install Code Warrior V10.1 latest compiler patch. The code is unstable if patch is not used.
#endif
#endif

#endif

/* In EWL version 15.0 tolower and toupper functionality was swapped */
#if defined(__EWL__)
#if __EWL__ == 0x00015000
#include "ctype.h"
inline int  _mqx_tolower(int c) { return isupper(c) ? c + ('a' - 'A') : c; }
inline int  _mqx_toupper(int c) { return islower(c) ? c - ('a' - 'A') : c; }
#define tolower _mqx_tolower
#define toupper _mqx_toupper
#endif
#endif


/*--------------------------------------------------------------------------*/
/*
 *                         MQX VERSION NUMBER
 */
#define MQX_VERSION (401)
#define __MQX__

/*--------------------------------------------------------------------------*/
/*
 *                   INCLUDE MQX CONFIGURATION CONSTANTS
 */

#include "mqx_cnfg.h"

/*--------------------------------------------------------------------------*/
/*
 *                 INCLUDE MQX STANDARD TYPES FROM THE PSP
 */

#include "psptypes.h"


/*--------------------------------------------------------------------------*/
/*
 *  INCLUDE COMPILER SPECIFIC DEFINITIONS, MACROS AND SUPPORT FUNCTIONS
 */

#include <psp_comp.h>
#include "psp_supp.h"

/*--------------------------------------------------------------------------*/
/*
 *                 INCLUDE MQX IO COMPONENT CONSTANTS
 */

#include "mqx_ioc.h"



/*--------------------------------------------------------------------------*/
/*
 *                 INCLUDE VARIOUS MACROS
 */

#include "mqx_macros.h"


/*--------------------------------------------------------------------------*/
/*
 *                          STANDARD CONSTANTS
 *
 *  Note that if standard 'C' library files are included after mqx.h,
 *  the defines of TRUE, FALSE and NULL may sometimes conflict, as most
 *  standard library files do not check for previous definitions.
 */

#ifdef  FALSE
   #undef  FALSE
#endif
#define FALSE ((boolean)0)

#ifdef  TRUE
   #undef  TRUE
#endif
#define TRUE ((boolean)1)

#ifdef  NULL
   #undef  NULL
#endif
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((pointer)0)
#endif


#ifndef __ASM__
/*--------------------------------------------------------------------------*/
/*
 *                    TASK IDS AND PROCESSOR NUMBERS
 *
 * These definitions are for MQX task IDs and processor numbers.
 */

typedef uint_16 _task_number;       /* what a task_number looks like  */
typedef uint_32 _task_id;           /* what a task_id looks like  */

#define MQX_NULL_TASK_ID        ((_task_id)0)
#define MQX_DEFAULT_TASK_ID     ((_task_id)-1)
#define MQX_IDLE_TASK_NAME      "_mqx_idle_task"
#define MQX_IDLE_TASK_PARAMETER 0
#if (MQX_USE_IDLE_TASK) && (MQX_ENABLE_LOW_POWER) && (MQX_IDLE_TASK_PARAMETER != 0)
   #error MQX_IDLE_TASK_PARAMETER must be 0 when Low Power feature is enabled!
#endif

typedef uint_16 _processor_number;  /* what a processor number is */

/*
 * Valid processor numbers run from 1 to 255 for 16 bit queue IDs or
 * 1 to 65535 for 32 bit queue IDs
 */
#if MQX_USE_32BIT_MESSAGE_QIDS == 0
   #define MQX_MAX_PROCESSOR_NUMBER  ((_processor_number)255)
#else
   #define MQX_MAX_PROCESSOR_NUMBER  ((_processor_number)65535)
#endif

#endif

/*--------------------------------------------------------------------------*/
/*
 *                       MEMORY ENDIAN DEFINITIONS
 *
 *  A PSP will define in its header file PSP_ENDIAN to be one of these
 */
#define MQX_BIG_ENDIAN    (0)
#define MQX_LITTLE_ENDIAN (1)


/*--------------------------------------------------------------------------*/
/*
 *                          ERROR CODE BASES
 *
 *  These are the base values of various MQX component error codes
 */
#define MQX_ERROR_BASE         (0x0000)
#define RTCS_ERROR_BASE        (0x1000)
#define IO_PCB_ERROR_BASE      (0x2000)
#define FS_ERROR_BASE          (0x3000)
#define USB_ERROR_BASE         (0x4000)
#define SHELL_ERROR_BASE       (0x5000)
#define IPC_PCB_ERROR_BASE     (0x9000)
#define DRIVER_ERROR_BASE      (0xA000)
#define IPC_ERROR_BASE         (0xC000)

#define SEM_ERROR_BASE         (MQX_ERROR_BASE | 0x0100)
#define EDS_SERIAL_ERROR_BASE  (MQX_ERROR_BASE | 0x0200)
#define EVENT_ERROR_BASE       (MQX_ERROR_BASE | 0x0300)
#define POSIX_ERROR_BASE       (MQX_ERROR_BASE | 0x0400)
#define LOG_ERROR_BASE         (MQX_ERROR_BASE | 0x0500)
#define WATCHDOG_ERROR_BASE    (MQX_ERROR_BASE | 0x0600)
#define MSG_ERROR_BASE         (MQX_ERROR_BASE | 0x0700)
#define PART_ERROR_BASE        (MQX_ERROR_BASE | 0x0800)
#define RESERVED2_ERROR_BASE   (MQX_ERROR_BASE | 0x0900)
#define IO_ERROR_BASE          (MQX_ERROR_BASE | 0x0A00)
#define RESERVED3_ERROR_BASE   (MQX_ERROR_BASE | 0x0B00)
#define RESERVED4_ERROR_BASE   (MQX_ERROR_BASE | 0x0C00)
#define RESERVED5_ERROR_BASE   (MQX_ERROR_BASE | 0x0D00)
#define RESERVED6_ERROR_BASE   (MQX_ERROR_BASE | 0x0E00)
#define NAME_ERROR_BASE        (MQX_ERROR_BASE | 0x0F00)

#define CAN_ERROR_BASE         (DRIVER_ERROR_BASE | 0x0100)
#define FLEXCAN_ERROR_BASE     (DRIVER_ERROR_BASE | 0x0200)
#define MSCAN_ERROR_BASE       (DRIVER_ERROR_BASE | 0x0300)
#define ENET_ERROR_BASE        (DRIVER_ERROR_BASE | 0x0400)
#define PCFLASH_ERROR_BASE     (DRIVER_ERROR_BASE | 0x0500)
#define QSPI_ERROR_BASE        (DRIVER_ERROR_BASE | 0x0600)
#define SPI_ERROR_BASE         (DRIVER_ERROR_BASE | 0x0700)
#define FLASHX_ERROR_BASE      (DRIVER_ERROR_BASE | 0x0800)
#define I2C_ERROR_BASE         (DRIVER_ERROR_BASE | 0x0900)
#define SERIAL_ERROR_BASE      (DRIVER_ERROR_BASE | 0x0A00)
#define NANDFLASH_ERROR_BASE   (DRIVER_ERROR_BASE | 0x0B00)
#define ESDHC_ERROR_BASE       (DRIVER_ERROR_BASE | 0x0C00)
#define TCHRES_ERROR_BASE      (DRIVER_ERROR_BASE | 0x0D00)
#define ADC_ERROR_BASE         (DRIVER_ERROR_BASE | 0x0E00)
#define DAC_ERROR_BASE         (DRIVER_ERROR_BASE | 0x0F00)
#define RTC_ERROR_BASE         (DRIVER_ERROR_BASE | 0x0F80)
#define COREMUTEX_ERROR_BASE   (DRIVER_ERROR_BASE | 0x0F90)


/*--------------------------------------------------------------------------*/
/*
 *                          FS ERROR CODES
 *
 *  These are the values of the error codes used by file systems
 */
#define FS_NO_ERROR                          (0)
#define FS_INVALID_FUNCTION_CODE             (FS_ERROR_BASE|1)
#define FS_FILE_NOT_FOUND                    (FS_ERROR_BASE|2)
#define FS_PATH_NOT_FOUND                    (FS_ERROR_BASE|3)
#define FS_ACCESS_DENIED                     (FS_ERROR_BASE|5)
#define FS_INVALID_HANDLE                    (FS_ERROR_BASE|6)
#define FS_INSUFFICIENT_MEMORY               (FS_ERROR_BASE|8)
#define FS_INVALID_MEMORY_BLOCK_ADDRESS      (FS_ERROR_BASE|9)
#define FS_ATTEMPT_TO_REMOVE_CURRENT_DIR     (FS_ERROR_BASE|16)
#define FS_DISK_IS_WRITE_PROTECTED           (FS_ERROR_BASE|19)
#define FS_BAD_DISK_UNIT                     (FS_ERROR_BASE|20)
#define FS_INVALID_LENGTH_IN_DISK_OPERATION  (FS_ERROR_BASE|24)
#define FS_NOT_A_DOS_DISK                    (FS_ERROR_BASE|26)
#define FS_SECTOR_NOT_FOUND                  (FS_ERROR_BASE|27)
#define FS_WRITE_FAULT                       (FS_ERROR_BASE|29)
#define FS_READ_FAULT                        (FS_ERROR_BASE|30)
#define FS_SHARING_VIOLATION                 (FS_ERROR_BASE|32)
#define FS_FILE_EXISTS                       (FS_ERROR_BASE|80)
#define FS_ALREADY_ASSIGNED                  (FS_ERROR_BASE|85)
#define FS_INVALID_PARAMETER                 (FS_ERROR_BASE|87)
#define FS_DISK_FULL                         (FS_ERROR_BASE|101)
#define FS_ROOT_DIR_FULL                     (FS_ERROR_BASE|102)
#define FS_EOF                               (FS_ERROR_BASE|103)
#define FS_CANNOT_CREATE_DIRECTORY           (FS_ERROR_BASE|104)
#define FS_NOT_INITIALIZED                   (FS_ERROR_BASE|151)
#define FS_OPERATION_NOT_ALLOWED             (FS_ERROR_BASE|152)
#define FS_ERROR_INVALID_DRIVE_HANDLE        (FS_ERROR_BASE|157)
#define FS_ERROR_INVALID_FILE_HANDLE         (FS_ERROR_BASE|158)
#define FS_ERROR_UNKNOWN_FS_VERSION          (FS_ERROR_BASE|159)
#define FS_LOST_CHAIN                        (FS_ERROR_BASE|160)
#define FS_INVALID_DEVICE                    (FS_ERROR_BASE|161)
#define FS_INVALID_CLUSTER_NUMBER            (FS_ERROR_BASE|162)
#define FS_FAILED_TO_DELETE_LFN              (FS_ERROR_BASE|163)
#define FS_BAD_LFN_ENTRY                     (FS_ERROR_BASE|164)
#define FS_PMGR_INVALID_PARTITION            (FS_ERROR_BASE|170)
#define FS_PMGR_INSUF_MEMORY                 (FS_ERROR_BASE|171)
#define FS_PMGR_UNKNOWN_PARTITION            (FS_ERROR_BASE|172)
#define FS_PMGR_INVALID_PARTTABLE            (FS_ERROR_BASE|173)


/*--------------------------------------------------------------------------*/
/*
 *                          TASK ERROR CODES
 *
 *  These are the values of the task error codes used by Kernel
 */
#define MQX_OK                              (0)

#define MQX_INVALID_POINTER                 (MQX_ERROR_BASE|0x01)
#define MQX_INVALID_SIZE                    (MQX_ERROR_BASE|0x02)
#define MQX_NOT_RESOURCE_OWNER              (MQX_ERROR_BASE|0x03)
#define MQX_OUT_OF_MEMORY                   (MQX_ERROR_BASE|0x04)
#define MQX_CORRUPT_MEMORY_SYSTEM           (MQX_ERROR_BASE|0x05)
#define MQX_CORRUPT_STORAGE_POOL            (MQX_ERROR_BASE|0x06)
#define MQX_CORRUPT_STORAGE_POOL_FREE_LIST  (MQX_ERROR_BASE|0x07)
#define MQX_CORRUPT_STORAGE_POOL_POINTERS   (MQX_ERROR_BASE|0x08)
#define MQX_INVALID_CHECKSUM                (MQX_ERROR_BASE|0x09)
#define MQX_OUT_OF_TASK_DESCRIPTORS         (MQX_ERROR_BASE|0x0A)
#define MQX_INVALID_MEMORY_BLOCK            (MQX_ERROR_BASE|0x0B)
#define MQX_INVALID_PARAMETER               (MQX_ERROR_BASE|0x0C)
#define MQX_CANNOT_CALL_FUNCTION_FROM_ISR   (MQX_ERROR_BASE|0x0D)
#define MQX_INVALID_TASK_PRIORITY           (MQX_ERROR_BASE|0x0E)
#define MQX_TASK_QUEUE_EMPTY                (MQX_ERROR_BASE|0x0F)
#define MQX_NO_TASK_TEMPLATE                (MQX_ERROR_BASE|0x10)
#define MQX_INVALID_TASK_STATE              (MQX_ERROR_BASE|0x11)
#define MQX_INVALID_TASK_ID                 (MQX_ERROR_BASE|0x12)
#define MQX_INVALID_PROCESSOR_NUMBER        (MQX_ERROR_BASE|0x13)
#define MQX_INVALID_VECTORED_INTERRUPT      (MQX_ERROR_BASE|0x14)
#define MQX_INVALID_TEMPLATE_INDEX          (MQX_ERROR_BASE|0x15)
#define MQX_INVALID_CONFIGURATION           (MQX_ERROR_BASE|0x16)

/* Kernel component error codes */
#define MQX_COMPONENT_EXISTS                (MQX_ERROR_BASE|0x17)
#define MQX_COMPONENT_DOES_NOT_EXIST        (MQX_ERROR_BASE|0x18)
#define MQX_INVALID_COMPONENT_HANDLE        (MQX_ERROR_BASE|0x19)
#define MQX_INVALID_COMPONENT_BASE          (MQX_ERROR_BASE|0x1A)
#define MQX_INVALID_COMPONENT_NAME          (MQX_ERROR_BASE|0x1B)
#define MQX_INVALID_HANDLE                  (MQX_ERROR_BASE|0x1C)

/* Test error codes */
#define MQX_CORRUPT_QUEUE                   (MQX_ERROR_BASE|0x1D)
#define MQX_INVALID_TASK_QUEUE              (MQX_ERROR_BASE|0x1E)
#define MQX_INVALID_LWSEM                   (MQX_ERROR_BASE|0x1F)
#define MQX_CORRUPT_INTERRUPT_STACK         (MQX_ERROR_BASE|0x20)

/* Initialization error return codes */
#define MQX_KERNEL_MEMORY_TOO_SMALL         (MQX_ERROR_BASE|0x21)
#define MQX_COULD_NOT_CREATE_IPC_TASK       (MQX_ERROR_BASE|0x22)
#define MQX_TOO_MANY_PRIORITY_LEVELS        (MQX_ERROR_BASE|0x23)
#define MQX_TOO_MANY_INTERRUPTS             (MQX_ERROR_BASE|0x24)
#define MQX_DUPLICATE_TASK_TEMPLATE_INDEX   (MQX_ERROR_BASE|0x25)
#define MQX_TIMER_ISR_INSTALL_FAIL          (MQX_ERROR_BASE|0x26)

/* Scheduler error codes */
#define MQX_SCHED_INVALID_POLICY            (MQX_ERROR_BASE|0x27)
#define MQX_SCHED_INVALID_PARAMETER_PTR     (MQX_ERROR_BASE|0x28)
#define MQX_SCHED_INVALID_PARAMETER         (MQX_ERROR_BASE|0x29)
#define MQX_SCHED_INVALID_TASK_ID           (MQX_ERROR_BASE|0x2A)

/* I/O error codes */
#define MQX_INVALID_IO_CHANNEL              (MQX_ERROR_BASE|0x2B)
#define MQX_IO_OPERATION_NOT_AVAILABLE      (MQX_ERROR_BASE|0x2C)

/* IPC error codes */
#define MQX_INTER_PROCESSOR_INIT_FAILED     (MQX_ERROR_BASE|0x2D)
#define MQX_IPC_INVALID_MESSAGE             (MQX_ERROR_BASE|0x2E)
#define MQX_IPC_SERVICE_NOT_AVAILABLE       (MQX_ERROR_BASE|0x2F)
#define MQX_IPC_ROUTE_EXISTS                (MQX_ERROR_BASE|0x30)

/* User memory error codes */
#define MQX_MEM_POOL_TOO_SMALL              (MQX_ERROR_BASE|0x31)
#define MQX_MEM_POOL_INVALID                (MQX_ERROR_BASE|0x32)

/* MMU error codes */
#define MQX_OUT_OF_MMU_PAGE_TABLES          (MQX_ERROR_BASE|0x33)
#define MQX_MMU_CONTEXT_EXISTS              (MQX_ERROR_BASE|0x34)
#define MQX_MMU_CONTEXT_DOES_NOT_EXIST      (MQX_ERROR_BASE|0x35)
#define MQX_MMU_PARENT_TASK_CANNOT_BE_MMU   (MQX_ERROR_BASE|0x36)

/* LWSEM wait timeout error codes */
#define MQX_LWSEM_WAIT_TIMEOUT              (MQX_ERROR_BASE|0x37)

/* LWMEM error codes              */
#define MQX_LWMEM_POOL_INVALID              (MQX_ERROR_BASE|0x38)

/* LWEVENT error codes            */
#define MQX_LWEVENT_INVALID                 (MQX_ERROR_BASE|0x39)

/* LWTIMER error codes            */
#define MQX_LWTIMER_INVALID                 (MQX_ERROR_BASE|0x40)

/* UNHANDLED error codes            */
#define MQX_UNHANDLED_INTERRUPT             (MQX_ERROR_BASE|0x41)

/* RTC error codes */
#define MQX_RTC_UNLOCK_FAILED               (MQX_ERROR_BASE|0x42)

#define MQX_NO_USER_TASKS                   (MQX_ERROR_BASE|0x43)
#define MQX_TOO_MANY_USER_TASKS             (MQX_ERROR_BASE|0x44)
#define MQX_ACCESS_ERROR                    (MQX_ERROR_BASE|0x45)

#define MQX_INVALID_DEVICE                  (MQX_ERROR_BASE|0x46)
#define MQX_TASKQ_CREATE_FAILED             (MQX_ERROR_BASE|0x47)

#define MQX_ERROR                           (MQX_ERROR_BASE|0xff)

/*--------------------------------------------------------------------------*/
/*
 *                          POSIX ERROR CODES
 *
 * These are the POSIX error codes used by POSIX compliant functions
 * in MQX.
 */

#define _task_errno  (*_task_get_error_ptr())

#define MQX_EOK             (0x00)
#define MQX_E2BIG           (POSIX_ERROR_BASE|0x01)
#define MQX_EACCES          (POSIX_ERROR_BASE|0x02)
#define MQX_EAGAIN          (POSIX_ERROR_BASE|0x03)
#define MQX_EBADF           (POSIX_ERROR_BASE|0x04)
#define MQX_EBADMSG         (POSIX_ERROR_BASE|0x05)
#define MQX_EBUSY           (POSIX_ERROR_BASE|0x06)
#define MQX_ECANCELED       (POSIX_ERROR_BASE|0x07)
#define MQX_ECHILD          (POSIX_ERROR_BASE|0x08)
#define MQX_EDEADLK         (POSIX_ERROR_BASE|0x09)
#define MQX_EDOM            (POSIX_ERROR_BASE|0x0a)
#define MQX_EEXIST          (POSIX_ERROR_BASE|0x0b)
#define MQX_EFAULT          (POSIX_ERROR_BASE|0x0c)
#define MQX_EFBIG           (POSIX_ERROR_BASE|0x0d)
#define MQX_EINPROGRESS     (POSIX_ERROR_BASE|0x0e)
#define MQX_EINTR           (POSIX_ERROR_BASE|0x0f)
#define MQX_EINVAL          (POSIX_ERROR_BASE|0x10)
#define MQX_EIO             (POSIX_ERROR_BASE|0x11)
#define MQX_EISDIR          (POSIX_ERROR_BASE|0x12)
#define MQX_EMFILE          (POSIX_ERROR_BASE|0x13)
#define MQX_EMLINK          (POSIX_ERROR_BASE|0x14)
#define MQX_EMSGSIZE        (POSIX_ERROR_BASE|0x15)
#define MQX_ENAMETOOLONG    (POSIX_ERROR_BASE|0x16)
#define MQX_ENFILE          (POSIX_ERROR_BASE|0x17)
#define MQX_ENODEV          (POSIX_ERROR_BASE|0x18)
#define MQX_ENOENT          (POSIX_ERROR_BASE|0x19)
#define MQX_ENOEXEC         (POSIX_ERROR_BASE|0x1a)
#define MQX_ENOLCK          (POSIX_ERROR_BASE|0x1b)
#define MQX_ENOMEM          (POSIX_ERROR_BASE|0x1c)
#define MQX_ENOSPC          (POSIX_ERROR_BASE|0x1d)
#define MQX_ENOSYS          (POSIX_ERROR_BASE|0x1e)
#define MQX_ENOTDIR         (POSIX_ERROR_BASE|0x1f)
#define MQX_ENOTEMPTY       (POSIX_ERROR_BASE|0x20)
#define MQX_ENOTSUP         (POSIX_ERROR_BASE|0x21)
#define MQX_ENOTTY          (POSIX_ERROR_BASE|0x22)
#define MQX_ENXIO           (POSIX_ERROR_BASE|0x23)
#define MQX_EPERM           (POSIX_ERROR_BASE|0x24)
#define MQX_EPIPE           (POSIX_ERROR_BASE|0x25)
#define MQX_ERANGE          (POSIX_ERROR_BASE|0x26)
#define MQX_EROFS           (POSIX_ERROR_BASE|0x27)
#define MQX_ESPIPE          (POSIX_ERROR_BASE|0x28)
#define MQX_ESRCH           (POSIX_ERROR_BASE|0x29)
#define MQX_ETIMEDOUT       (POSIX_ERROR_BASE|0x2a)
#define MQX_EXDEV           (POSIX_ERROR_BASE|0x2b)


/*--------------------------------------------------------------------------*/
/*
 *                 TASK TEMPLATE ATTRIBUTES FLAGS
 *
 * These are bit flags or'd together to form the creation attributes for
 * a task. This is combined with INTERNAL TASK FLAGS.
 */

/*
 * Tasks with this attribute will be created automatically at
 * system initialization time.
 */
#define MQX_AUTO_START_TASK            (0x01)

/*
 * Tasks with this attribute will save the floating point co-processor
 * registers during context switching.
 * If the floating point registers are separate from the normal registers,
 * their context is managed independently during task switching. The registers
 * are saved/restored only when a new floating point task is scheduled to run.
 */
#define MQX_FLOATING_POINT_TASK        (0x02)

/*
 * Tasks with this attribute will use the time slice
 * scheduler within the kernel
 */
#if MQX_HAS_TIME_SLICE
#define MQX_TIME_SLICE_TASK            (0x04)
#endif

/*
 * Tasks with this attribute will save the DSP co-processor
 * registers during context switching.
 * If the DSP registers are separate from the normal registers,
 * their context is managed independently during task switching. The registers
 * are saved/restored only when a new DSP task is scheduled to run.
 */
#define MQX_DSP_TASK                   (0x08)

#if MQX_ENABLE_USER_MODE
#define MQX_USER_TASK                   (0x10)
#else
#define MQX_USER_TASK                   (0)
#endif


/*--------------------------------------------------------------------------*/
/*
 *                             TASK ID MACROS
 *
 * These macros manipulate the internals of a TASKID
 */

/* Obtain the processor number from the task ID */
#define PROC_NUMBER_FROM_TASKID(taskid) ((uint_16)((taskid) >> 16))

/* Obtain the task number from the task ID */
#define TASK_NUMBER_FROM_TASKID(taskid) ((uint_16)((taskid) & 0xFFFF))


/*--------------------------------------------------------------------------*/
/*
 *                        MONITOR DEFINITIONS
 *
 * These definitions are used by the MQX BSPs to determine which type of
 * monitor is currently running, and thus to modify their initialization
 * behaviour (Handling of caches, interrupts etc)
 * The variable _mqx_monitor_type is set to one of these by the application
 * program.  The default value is MONITOR_TYPE_NONE
 */

#define MQX_MONITOR_TYPE_NONE      (0)

/* Polled serial I/O monitor debugger */
#define MQX_MONITOR_TYPE_MON       (0x01)

/* Interrupt driven serial I/O monitor debugger */
#define MQX_MONITOR_TYPE_MON_INT   (0x02)

/* Background mode debugger being used */
#define MQX_MONITOR_TYPE_BDM       (0x03)

/* JTAG debugger being used */
#define MQX_MONITOR_TYPE_JTAG      (0x04)

/* Some other monitor in use */
#define MQX_MONITOR_TYPE_OTHER     (0x10)


/*--------------------------------------------------------------------------*/
/*
 *                       KERNEL SCHEDULER CONSTANTS
 */

/* Scheduling policy constants */
#define MQX_SCHED_FIFO                 (1)
#if MQX_HAS_TIME_SLICE
#define MQX_SCHED_RR                   (2)
#endif

/* Explicit scheduler task queueing policy */
#define MQX_TASK_QUEUE_FIFO           (0x00)
#define MQX_TASK_QUEUE_BY_PRIORITY    (0x08)
#define MQX_TASK_QUEUE_RESUME_ONE     FALSE
#define MQX_TASK_QUEUE_RESUME_ALL     TRUE

/*--------------------------------------------------------------------------*/
/*
 *                       TEST AND SET CONSTANTS
 *
 * These are the possible values returned by the MQX test and set function.
 * It is also used by the mutex functions as the value used when locking
 * a mutex.
 */
#define MQX_TEST_AND_SET_VALUE        (0x80)
#define MQX_TEST_AND_SET_NOT_ACQUIRED MQX_TEST_AND_SET_VALUE
#define MQX_TEST_AND_SET_ACQUIRED     (0x00)


/*--------------------------------------------------------------------------*/
/*
 *                       GENERIC CONSTANTS
 *
 */
/*
 * The maximum number of characters in a task's name. Includes terminating
 * /0 character.
 */
#define MQX_MAX_TASK_NAME_SIZE        (50)

/*--------------------------------------------------------------------------*/
/*
 *                       MEMORY CONSTANTS AND TYPE DEFINITIONS
 */
/* what a memory pool ID looks like  */
#ifndef __ASM__
typedef pointer _mem_pool_id;
#endif

#define MQX_NULL_MEM_POOL_ID    (NULL)

/* The minimum amount of memory needed by the memory management routines. */
#define MQX_MIN_MEMORY_POOL_SIZE (256)

#if !MQX_ENABLE_USER_MODE
#ifndef KERNEL_ACCESS
#define KERNEL_ACCESS
#endif
#ifndef USER_RW_ACCESS
#define USER_RW_ACCESS
#endif
#ifndef USER_RO_ACCESS
#define USER_RO_ACCESS
#endif
#ifndef USER_NO_ACCESS
#define USER_NO_ACCESS
#endif
#endif /* MQX_ENABLE_USER_MODE */
/*--------------------------------------------------------------------------*/
/*
 *                          DATA STRUCTURES
 */

/*--------------------------------------------------------------------------*/
/*
 *                            TIME CONSTANTS
 */
#define PICOSECS_IN_NANOSECOND   (1000)
#define NANOSECS_IN_MICROSECOND  (1000)
#define MICROSECS_IN_MILLISECOND (1000)
#define MILLISECS_IN_SECOND      (1000)
#define MICROSECS_IN_SECOND      (MILLISECS_IN_SECOND*MICROSECS_IN_MILLISECOND)
#define NANOSECS_IN_SECOND       (MICROSECS_IN_SECOND*NANOSECS_IN_MICROSECOND)
#define SECS_IN_MINUTE           (60UL)
#define MINUTES_IN_HOUR          (60UL)
#define HOURS_IN_DAY             (24UL)
#define MAX_DAYS_IN_MONTH        (31UL)
#define DAYS_IN_YEAR             (365UL)
#define MAX_DAYS_IN_YEAR         (366UL)
#define MONTHS_IN_YEAR           (12UL)
#define SECS_IN_HOUR             (SECS_IN_MINUTE*MINUTES_IN_HOUR)
#define SECS_IN_DAY              (SECS_IN_HOUR*HOURS_IN_DAY)
#define SECS_IN_YEAR             (SECS_IN_DAY*DAYS_IN_YEAR)
#define CLK_FIRST_YEAR           (1970UL)
#define XCLK_FIRST_YEAR          (1970)
#define CLK_LAST_YEAR            (2239UL)
#define XCLK_LAST_YEAR           (2481)
#define XCLK_ENTRIES             (512)
#define MAXIMUM_SECONDS_IN_TIME  (4102444800UL)
#define MAXIMUM_MILLISECONDS     (999UL)
#define MAXIMUM_DAYS_IN_XDATE    (187004UL)

/* This defines the mininum number of bits in the tick structure */
#define MQX_MIN_BITS_IN_TICK_STRUCT (64)

/* This defines the number of _mqx_uints in the tick structure */
#define MQX_NUM_TICK_FIELDS  ((MQX_MIN_BITS_IN_TICK_STRUCT+ \
   MQX_INT_SIZE_IN_BITS-1) / MQX_INT_SIZE_IN_BITS)

/*
 * Alarm frequency. This is for pre-2.50 BSPs
 * that do not have the define. New BSPs overide this define
 *
 *#ifndef BSP_ALARM_FREQUENCY
 *#define BSP_ALARM_FREQUENCY     (MILLISECS_IN_SECOND / BSP_ALARM_RESOLUTION)
 *#endif
 */

/*--------------------------------------------------------------------------*/
/*
 *                         MQX MEMORY TYPES
 */
#define MEM_TYPE_SYSTEM_STACK             1
#define MEM_TYPE_INTERRUPT_STACK          2
#define MEM_TYPE_INTERRUPT_TABLE          3
#define MEM_TYPE_TASK                     4
#define MEM_TYPE_READYQ                   5
#define MEM_TYPE_PARTITION_COMPONENT      6
#define MEM_TYPE_PARTITION                7
#define MEM_TYPE_PARTITION_BLOCKS         8
#define MEM_TYPE_MESSAGE_COMPONENT        9
#define MEM_TYPE_MESSAGE_QUEUES           10
#define MEM_TYPE_MESSAGE_POOLS            11
#define MEM_TYPE_MESSAGE_POOL_BLOCKS      12
#define MEM_TYPE_LWLOG_COMPONENT          13
#define MEM_TYPE_LWLOG                    14
#define MEM_TYPE_IO_DEVICE                15
#define MEM_TYPE_FILE_PTR                 16
#define MEM_TYPE_TASK_Q                   17
#define MEM_TYPE_EDS_BUFFER               18
#define MEM_TYPE_EVENT_COMPONENT          19
#define MEM_TYPE_EVENT_CONNECTION         20
#define MEM_TYPE_EVENT                    21
#define MEM_TYPE_LOG_COMPONENT            22
#define MEM_TYPE_LOG                      23
#define MEM_TYPE_MUTEX_COMPONENT          24
#define MEM_TYPE_NAME_COMPONENT           25
#define MEM_TYPE_SEMAPHORE_COMPONENT      26
#define MEM_TYPE_SEMAPHORE_CONNECTION     27
#define MEM_TYPE_SEMAPHORE                28
#define MEM_TYPE_TIMER_COMPONENT          29
#define MEM_TYPE_TIMER_ENTRY              30
#define MEM_TYPE_WATCHDOG_COMPONENT       31
#define MEM_TYPE_WATCHDOG_ALARM           32
#define MEM_TYPE_PSP_SUPPORT_STRUCT       33
#define MEM_TYPE_FP_CONTEXT               34
#define MEM_TYPE_INTERRUPT_VECTOR         35
#define MEM_TYPE_TD                       36
#define MEM_TYPE_TASK_STACK               37

#define MEM_TYPE_COMPONENT_SHIFT          12

#define MEM_TYPE_IO_PCFLASH               1001
#define MEM_TYPE_IO_SECTOR_BUFFER         1002
#define MEM_TYPE_IO_CHAN_STRUCT           1003
#define MEM_TYPE_IO_ENET_CONTEXT_STRUCT   1004
#define MEM_TYPE_IO_ENET_BUFFERS          1005
#define MEM_TYPE_IO_ENET_MCB              1006
#define MEM_TYPE_IO_ENET_ECB              1007
#define MEM_TYPE_IO_DUN                   1010
#define MEM_TYPE_IO_DUN_DEV               1011
#define MEM_TYPE_IO_GPIO_DEV_DATA         1012
#define MEM_TYPE_IO_GPIO_PIN_MAP          1013
#define MEM_TYPE_IO_MEM_STRUCT            1014
#define MEM_TYPE_IO_MEM_DATA              1015
#define MEM_TYPE_IO_SERIAL_INT_DEVICE_STRUCT    1016
#define MEM_TYPE_IO_SERIAL_POLLED_DEVICE_STRUCT 1017
#define MEM_TYPE_IO_SERIAL_IN_QUEUE       1018
#define MEM_TYPE_IO_SERIAL_OUT_QUEUE      1019
#define MEM_TYPE_IO_SERIAL_CHARQ          1020
#define MEM_TYPE_IO_SERIAL_INFO_STRUCT    1021
#define MEM_TYPE_IO_TFS_DRIVE_STRUCT      1022
#define MEM_TYPE_IO_SPI_INT_DEVICE_STRUCT    1023
#define MEM_TYPE_IO_SPI_POLLED_DEVICE_STRUCT 1024
#define MEM_TYPE_IO_SPI_IN_BUFFER            1025
#define MEM_TYPE_IO_SPI_OUT_BUFFER           1026
#define MEM_TYPE_IO_SPI_INFO_STRUCT          1027
#define MEM_TYPE_IO_FLASHX_RAM_FUNCT         1028
#define MEM_TYPE_IO_FLASHX_SECTOR_CACHE      1029
#define MEM_TYPE_IO_FLASHX_SECTOR_MAP        1030
#define MEM_TYPE_IO_I2C_INT_DEVICE_STRUCT    1031
#define MEM_TYPE_IO_I2C_POLLED_DEVICE_STRUCT 1032
#define MEM_TYPE_IO_I2C_IN_BUFFER            1033
#define MEM_TYPE_IO_I2C_OUT_BUFFER           1034
#define MEM_TYPE_IO_I2C_INFO_STRUCT          1035
#define MEM_TYPE_IO_PCB_PTR               1036
#define MEM_TYPE_IO_PCB_STRUCT            1037
#define MEM_TYPE_IO_BD_STRUCT                1038
#define MEM_TYPE_IO_ENET_MAC_CONTEXT_STRUCT  1039
#define MEM_TYPE_IO_SDCARD_STRUCT            1040
#define MEM_TYPE_IO_ESDHC_DEVICE_STRUCT      1041
#define MEM_TYPE_IO_ESDHC_INFO_STRUCT        1042
#define MEM_TYPE_IO_TCHRES_STRUCT            1043
#define MEM_TYPE_IO_TCHRES_XY_PIN_STRUCT     1044
#define MEM_TYPE_IO_USB_DCD_INFO_STRUCT          1045
#define MEM_TYPE_IO_USB_DCD_POLLED_DEVICE_STRUCT 1046
#define MEM_TYPE_IO_USB_DCD_INT_DEVICE_STRUCT    1047
#define MEM_TYPE_IO_SDIO_INT_DEVICE_STRUCT       1048
#define MEM_TYPE_IO_SDIO_IN_BUFFER               1049
#define MEM_TYPE_IO_SDIO_OUT_BUFFER              1050
#define MEM_TYPE_IO_LPM_DRIVER_ENTRY         1051
#ifndef __ASM__

typedef uint_16 _mem_type;

 /*--------------------------------------------------------------------------*/
 /*
  *                    TYPEDEFS FOR _CODE_PTR_ FUNCTIONS
  *
  */
 /* int.c */
 typedef void (_CODE_PTR_ INT_EXCEPTION_FPTR)(_mqx_uint, _mqx_uint, pointer, pointer);
 typedef void (_CODE_PTR_ INT_ISR_FPTR)(pointer);
 typedef void (_CODE_PTR_ INT_KERNEL_ISR_FPTR)(void);

 /* lwtimer.c/.h */
 typedef void (_CODE_PTR_ LWTIMER_ISR_FPTR)(pointer);

 /* mqx_utils.c */
 typedef void (_CODE_PTR_ MQX_EXIT_FPTR)(void);

 /* task_template_struct */
 typedef void (_CODE_PTR_ TASK_FPTR)(uint_32);

 /* kernel_data_struct */
 typedef uint_32 (_CODE_PTR_ MQX_GET_HWTICKS_FPTR)(pointer);
 typedef void (_CODE_PTR_ TIMER_COMPONENT_ISR_FPTR)(void);
 typedef _mqx_uint (_CODE_PTR_ MQX_IPC_FPTR)( boolean, _processor_number, _mqx_uint, _mqx_uint, _mqx_uint, ...);

 /* task.c */
 typedef void (_CODE_PTR_ TASK_EXCEPTION_FPTR)(_mqx_uint, pointer);
 typedef void (_CODE_PTR_ TASK_EXIT_FPTR)(void);



/*--------------------------------------------------------------------------*/
/* IDLE LOOP STRUCTURE */
/*!
 * \brief This structure defines idle loop counters.
 */
typedef struct idle_loop_struct
{
    /*! brief Idle loop. */
    _mqx_uint                   IDLE_LOOP1;
    /*! brief Idle loop. */
    _mqx_uint                   IDLE_LOOP2;
    /*! brief Idle loop. */
    _mqx_uint                   IDLE_LOOP3;
    /*! brief Idle loop. */
    _mqx_uint                   IDLE_LOOP4;

} IDLE_LOOP_STRUCT, _PTR_ IDLE_LOOP_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/* TIME STRUCTURE */
/*!
 * \brief A structure to represent time in seconds and milliseconds.
 *
 * \see _time_from_date
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see _time_to_date
 * \see DATE_STRUCT
 */
typedef struct time_struct
{

   /*! \brief The number of seconds in the time. */
   uint_32     SECONDS;

   /*! \brief The number of milliseconds in the time. */
   uint_32     MILLISECONDS;

} TIME_STRUCT, _PTR_ TIME_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/* DATE STRUCT */
/*!
 * \brief This structure is used to hold the time in a simple "date" format.
 *
 * Conversion functions _time_to_date, _time_from_date convert between this date
 * struct and the time struct.
 *
 * \warning If you violate the ranges, undefined behavior results.
 *
 * \see _time_from_date
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see _time_to_date
 * \see MQX_XDATE_STRUCT
 * \see TIME_STRUCT
 */
typedef struct date_struct
{
   /*! \brief Range from 1970 to 2099. */
   uint_16 YEAR;

   /*! \brief Range from 1 to 12. */
   uint_16 MONTH;

   /*! \brief Range from 1 to 31 (depending on month). */
   uint_16 DAY;

   /*! \brief Range from 0 to 23. */
   uint_16 HOUR;

   /*! \brief Range from 0 to 59. */
   uint_16 MINUTE;

   /*! \brief Range from 0 to 59. */
   uint_16 SECOND;

   /*! \brief Range from 0 to 999. */
   uint_16 MILLISEC;

} DATE_STRUCT, _PTR_ DATE_STRUCT_PTR;

/*!
 * \brief This structure defines how time is maintained in the system.
 *
 * Time is kept internally in the form of ticks. This is a 64 bit
 * field which is maintained in an array whose size is
 * dependent upon the PSP. HW_TICKS is used to track time between
 * ticks (timer interrupts).
 */
typedef struct mqx_tick_struct
{
    /*!
     * \brief Ticks since MQX started.
     *
     * The field is a minimum of 64 bits; the exact size depends on the PSP.
     */
    _mqx_uint TICKS[MQX_NUM_TICK_FIELDS];

    /*!
     * \brief Hardware ticks (timer counter increments) between ticks.
     *
     * The field increases the accuracy over counting the time simply in ticks.
     */
    uint_32   HW_TICKS;
} MQX_TICK_STRUCT, _PTR_ MQX_TICK_STRUCT_PTR;

/*--------------------------------------------------------------------------*/

/* EXTENDED DATE STRUCT */
/*!
 * \brief This structure is used to hold the time in a "date" format more detailed
 * than the MQX_DATE_STRUCT.
 *
 * Conversion functions _time_ticks_to_xdate, _time_xdate_to_ticks
 * convert between this extended date struct and the tick struct.
 *
 * \see _time_ticks_to_xdate
 * \see _time_xdate_to_ticks
 * \see DATE_STRUCT
 * \see MQX_TICK_STRUCT
 */
typedef struct mqx_xdate_struct
{

   /*! \brief Year since 1970. Range is from 1970 to 2481. */
   uint_16 YEAR;
   /*! \brief Month since January. Range is from 1 to 12. */
   uint_16 MONTH;
   /*! \brief Day of the month. Range is from 1 to 31. */
   uint_16 MDAY;
   /*! \brief Hour since midnight. Range is from 0 to 23. */
   uint_16 HOUR;
   /*! \brief Minute since the last hour. Range is from 0 to 59. */
   uint_16 MIN;
   /*! \brief Second since the last minute. Range is from 0 to 59. */
   uint_16 SEC;
   /*! \brief Milliseconds. Range is from 0 to 999. */
   uint_16 MSEC;
   /*! \brief Microseconds. Range is from 0 to 999. */
   uint_16 USEC;
   /*! \brief Nanoseconds. Range is from 0 to 999. */
   uint_16 NSEC;
   /*! \brief Picoseconds. Range is from 0 to 999. */
   uint_16 PSEC;
#if 0
   /*! \brief Day of the week. Sunday is day 1. Range is from 1 to 7. */
   uint_16 WDAY;
#endif
   /*! \brief Day of the week. Sunday is day 0. Range is from 0 to 6. */
   uint_16 WDAY;
   /*! \brief Day of the year. Range is from 0 to 365. */
   uint_16 YDAY;
} MQX_XDATE_STRUCT, _PTR_ MQX_XDATE_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/* TASK TEMPLATE STRUCTURE */
/*!
 * \brief Task template that MQX uses to create instances of a task.
 *
 * The task template list is an array of these structures, terminated by a
 * zero-filled element. The MQX initialization structure contains a pointer to
 * the list.
 *
 * \see _mqx
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 * \see MQX_INITIALIZATION_STRUCT
 */

typedef struct   task_template_struct
{
   /*!
    * \brief Application-unique number that identifies the task template.
    *
    * The minimum value is 1, maximum is MAX_MQX_UINT. The field is ignored if you
    * call _task_create() or _task_create_blocked() or _task_create_at() with a
    * template index equal to 0 and a creation parameter set to a pointer to a task
    * template.
    */
   _mqx_uint            TASK_TEMPLATE_INDEX;

   /*!
    * \brief Pointer to the root function for the task.
    *
    * This function will be called when a task is created with the task template
    * index above. The task is deleted when this function returns.
    */
   TASK_FPTR            TASK_ADDRESS;

   /*! \brief The amount of stack space required by this task. */
   _mem_size            TASK_STACKSIZE;


   /*!
    * \brief Software priority of the task.
    *
    * Priorities start at 0, which is the highest priority. 1, 2, 3, and so on
    * are progressively lower priorities.
    */
   _mqx_uint            TASK_PRIORITY;

   /*! \brief Pointer to a string name for tasks that MQX creates from the template. */
   char           _PTR_ TASK_NAME;

   /*!
    * \brief Possible attributes for the task.
    *
    * Possible bit values are:
    * \li MQX_AUTO_START_TASK (When MQX starts, it creates one instance of the task.)
    * \li MQX_FLOATING_POINT_TASK (Task uses the floating point co-processor. MQX
    * also saves floating-point registers as part of the task's context.)
    * \li MQX_TIME_SLICE_TASK (MQX uses round robin scheduling for the task (the
    * default is FIFO scheduling).)
    */
   _mqx_uint             TASK_ATTRIBUTES;

   /*! \brief Parameter passed to tasks that MQX creates from the template. */
   uint_32               CREATION_PARAMETER;

   /*!
    * \brief This field is the default time slice to use for the task.
	  *
    * Time slice in ticks or milliseconds depending on configuration bit in
    * mqx_cnfg.h
    */
   _mqx_uint             DEFAULT_TIME_SLICE;

} TASK_TEMPLATE_STRUCT, _PTR_ TASK_TEMPLATE_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/* MQX INITIALIZATION STRUCTURE */
/*!
 * \brief MQX initialization structure for each processor.
 *
 * When an application starts MQX on each processor, it calls _mqx() with the
 * MQX initialization structure.
 *
 * \see _mqx
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 * \see _task_get_processor
 * \see TASK_TEMPLATE_STRUCT
 */
typedef  struct mqx_initialization_struct
{
   /*!
    * \brief Application-unique processor number of the processor.
    *
    * Minimum is 1, maximum is 255. (Processor number 0 is reserved and is used
    * by tasks to indicate their local processor.)
    */
   _mqx_uint       PROCESSOR_NUMBER;

   /*! \brief Lowest address from which MQX allocates dynamic memory and task stacks. */
   pointer        START_OF_KERNEL_MEMORY;

   /*!
    * \brief Highest address from which MQX allocates dynamic memory and task stacks.
    *
    * It is the application's responsibility to allocate enough memory for all
    * tasks.
    */
   pointer        END_OF_KERNEL_MEMORY;

   /*!
    * \brief The size of the interrupt stack.
    *
    * This is the maximum amount of stack space used by all interrupt handlers.
    *
    */
   _mqx_uint       INTERRUPT_STACK_SIZE;

   /*! \brief Pointer to the task template list for the processor.
    *
    * The default name for the list is MQX_template_list[].
    */
   TASK_TEMPLATE_STRUCT_PTR TASK_TEMPLATE_LIST;

   /*!
    * \brief The maximum hardware interrupt priority level of MQX.
    *
    * All tasks and interrupts run at lower priority (Applicable to CPUs with
    * multiple interrupt levels only).
    */
   _mqx_uint       MQX_HARDWARE_INTERRUPT_LEVEL_MAX;

   /*! \brief Maximum number of message pools. */
   _mqx_uint       MAX_MSGPOOLS;

   /*!
    * \brief Maximum number of message queues. Minimum is MSGQ_FIRST_USER_QUEUE,
    * maximum is 255.
    */
   _mqx_uint       MAX_MSGQS;

   /*!
    * \brief A string indicating which device is to be used as
    * the default (console) I/O for the processor.
    */
   char     _PTR_ IO_CHANNEL;

   /*! \brief The open flags to pass to the default I/O device */
   char     _PTR_ IO_OPEN_MODE;

   /* reserved fields for later use */
/*   _mqx_uint       RESERVED[2];*/

   /*! \brief The location of the interrupt stack (if not NULL). */
   pointer        INTERRUPT_STACK_LOCATION;
   /*! \brief Reserved field.
    *
    * Reserved for future enhancements to MQX; each element of the array must be
    * initialized to 0.
    */
   _mqx_uint       RESERVED[1];

#if MQX_ENABLE_USER_MODE
   /*! \brief Lowest adress of kernel area. */
   pointer          START_OF_KERNEL_AREA;
   /*! \brief Highest adress of kernel area. */
   pointer          END_OF_KERNEL_AREA;

   /*! \brief Lowest adress of default data section (.data .bss). */
   pointer          START_OF_USER_DEFAULT_MEMORY;
   /*! \brief Highest adress of default data section (.data .bss). */
   pointer          END_OF_USER_DEFAULT_MEMORY;

   /*! \brief Lowest adress of user heap - mem alloc. */
   pointer          START_OF_USER_HEAP;
   /*! \brief Highest adress of user heap - mem alloc. */
   pointer          END_OF_USER_HEAP;

   /*! \brief Lowest adress of user read/write memory. */
   pointer          START_OF_USER_RW_MEMORY;
   /*! \brief Highest adress of user read/write memory. */
   pointer          END_OF_USER_RW_MEMORY;

   /*! \brief Lowest adress of user read-only memory. */
   pointer          START_OF_USER_RO_MEMORY;
   /*! \brief Highest adress of user read-only memory. */
   pointer          END_OF_USER_RO_MEMORY;

   /*! \brief Lowest adress of user no access memory. */
   pointer          START_OF_USER_NO_MEMORY;
   /*! \brief Highest adress of user no access memory. */
   pointer          END_OF_USER_NO_MEMORY;
   /*! \brief Maximal priority of user's tasks. */
   _mqx_uint        MAX_USER_TASK_PRIORITY;
   /*! \brief Maximal number of user's tasks. */
   _mqx_uint        MAX_USER_TASK_COUNT;
#endif

} MQX_INITIALIZATION_STRUCT, _PTR_ MQX_INITIALIZATION_STRUCT_PTR;


/* Include queue structures and function prototypes */
#include "queue.h"

#include "lwsem.h"


#endif /* __ASM__ */

/*--------------------------------------------------------------------------*/
/*
 *                 INCLUDE MQX PROCESSOR CONFIGURATION
 */
#include <psp_cpu.h>


/*--------------------------------------------------------------------------*/
/*
 *                  PROTOTYPES OF KERNEL FUNCTIONS
 */

#ifndef __ASM__
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __TAD_COMPILE__
extern void             _int_default_isr(pointer);
extern void             _int_disable(void);
extern void             _int_enable(void);
extern void             _int_exception_isr(pointer);
extern INT_ISR_FPTR     _int_get_default_isr(void);
extern INT_EXCEPTION_FPTR _int_get_exception_handler(_mqx_uint);
extern INT_ISR_FPTR     _int_get_isr(_mqx_uint);
extern pointer          _int_get_isr_data(_mqx_uint);
extern _mqx_uint        _int_get_isr_depth(void);
extern INT_KERNEL_ISR_FPTR _int_get_kernel_isr(_mqx_uint);
extern _mqx_max_type    _int_get_previous_vector_table(void);
extern _mqx_max_type    _int_get_vector_table(void);
extern _mqx_uint        _int_init(_mqx_uint, _mqx_uint);
extern INT_ISR_FPTR     _int_install_default_isr(INT_ISR_FPTR);
extern INT_KERNEL_ISR_FPTR _int_install_kernel_isr(_mqx_uint,INT_KERNEL_ISR_FPTR);
extern INT_ISR_FPTR     _int_install_isr(_mqx_uint,INT_ISR_FPTR, pointer);
extern INT_ISR_FPTR     _int_install_exception_isr(void);
extern INT_ISR_FPTR     _int_install_unexpected_isr(void);
extern void             _int_kernel_isr(void);
extern INT_EXCEPTION_FPTR _int_set_exception_handler(_mqx_uint,INT_EXCEPTION_FPTR);
extern pointer          _int_set_isr_data(_mqx_uint, pointer);
extern _mqx_max_type    _int_set_vector_table(_mqx_max_type);
extern void             _int_unexpected_isr(pointer);

extern _mqx_uint        _klog_create(_mqx_uint, _mqx_uint);
extern _mqx_uint        _klog_create_at(_mqx_uint, _mqx_uint, pointer);
extern _mqx_uint        _klog_get_interrupt_stack_usage(_mem_size_ptr, _mem_size_ptr);
extern _mqx_uint        _klog_get_task_stack_usage(_task_id, _mem_size_ptr,
   _mem_size_ptr);
extern void             _klog_control(uint_32, boolean);
extern void             _klog_disable_logging_task(_task_id);
extern boolean          _klog_display(void);
extern void             _klog_enable_logging_task(_task_id);
extern void             _klog_show_stack_usage(void);
extern void             _klog_log(_mqx_uint,_mqx_max_type,_mqx_max_type,_mqx_max_type,_mqx_max_type,_mqx_max_type);
extern void             _klog_log_function(pointer fn);

extern void _PTR_       _mem_alloc(_mem_size);
extern void _PTR_       _mem_alloc_at(_mem_size, pointer);
extern void _PTR_       _mem_alloc_align(_mem_size, _mem_size);
extern void _PTR_       _mem_alloc_from(_mem_pool_id, _mem_size);
extern void _PTR_       _mem_alloc_align_from(_mem_pool_id, _mem_size, _mem_size);
extern void _PTR_       _mem_alloc_zero(_mem_size);
extern void _PTR_       _mem_alloc_zero_from(_mem_pool_id, _mem_size);
extern pointer          _mem_alloc_system(_mem_size);
extern pointer          _mem_alloc_system_from(_mem_pool_id, _mem_size);
extern pointer          _mem_alloc_system_zero(_mem_size);
extern pointer          _mem_alloc_system_zero_from(_mem_pool_id, _mem_size);

#if MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE
void _PTR_ _mem_alloc_uncached(_mem_size);
void _PTR_ _mem_alloc_align_uncached(_mem_size, _mem_size);
pointer _mem_alloc_system_uncached(_mem_size);
pointer _mem_alloc_system_zero_uncached(_mem_size);
#else /* MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE */
#define _mem_alloc_uncached _mem_alloc
#define _mem_alloc_align_uncached _mem_alloc_align
#define _mem_alloc_system_uncached _mem_alloc_system
#define _mem_alloc_system_zero_uncached _mem_alloc_system_zero
#endif /* MQX_USE_UNCACHED_MEM && PSP_HAS_DATA_CACHE */

#if MQXCFG_MEM_COPY || MQXCFG_MEM_COPY_NEON
extern void             _mem_copy(pointer, pointer, _mem_size);
#else
# include <string.h>
#define _mem_copy(s,d,l) memcpy(d,s,l)
#endif

#if MQX_USE_MEM_ZERO
extern void             _mem_zero(pointer, _mem_size);
#else
# include <string.h>
#define _mem_zero(p,n)  memset(p,0,n)
#endif

extern _mem_pool_id     _mem_create_pool(pointer, _mem_size);
extern _mqx_uint        _mem_extend(pointer, _mem_size);
extern _mqx_uint        _mem_extend_pool(_mem_pool_id, pointer, _mem_size);
extern _mqx_uint        _mem_free(pointer);
extern _mqx_uint        _mem_free_part(pointer, _mem_size);
extern pointer          _mem_get_error(void);
extern pointer          _mem_get_error_pool(_mem_pool_id);
extern void _PTR_       _mem_get_highwater(void);
extern void _PTR_       _mem_get_highwater_pool(_mem_pool_id);
extern _mem_size        _mem_get_size(pointer);
extern _mem_pool_id     _mem_get_system_pool_id(void);
extern uint_32          _mem_sum_ip(uint_32, _mem_size, pointer);
extern void             _mem_swap_endian(uchar _PTR_, pointer);
extern void             _mem_swap_endian_len(uchar _PTR_, pointer, _mqx_uint);
extern _mqx_uint        _mem_test(void);
extern _mqx_uint        _mem_test_all(_mem_pool_id _PTR_);
extern _mqx_uint        _mem_test_pool(_mem_pool_id);
extern _mqx_uint        _mem_test_and_set(uchar_ptr);
extern _mqx_uint        _mem_transfer(pointer, _task_id, _task_id);

#if MQXCFG_MEM_COPY_NEON
_mem_size neon_copy_offset_0(pointer dst, pointer src, _mem_size len);
_mem_size neon_copy_offset_1(pointer dst, pointer src, _mem_size len);
_mem_size neon_copy_offset_2(pointer dst, pointer src, _mem_size len);
_mem_size neon_copy_offset_3(pointer dst, pointer src, _mem_size len);
#endif // MQXCFG_MEM_COPY_NEON

#if MQX_ALLOW_TYPED_MEMORY
extern boolean          _mem_set_type(pointer, _mem_type);
extern _mem_type        _mem_get_type(pointer);
#else
#define _mem_get_type(p)   0
#define _mem_set_type(p,u)
#endif



extern _mqx_uint         _mem_verify(pointer base, pointer extent);

extern _mqx_uint         _mqx(MQX_INITIALIZATION_STRUCT_PTR);
extern const MQX_TICK_STRUCT  _mqx_zero_tick_struct;
extern const uint_32     _mqx_version_number;
extern const char _PTR_  const _mqx_vendor;
extern const char _PTR_  const _mqx_version;
extern const char _PTR_  const _mqx_copyright;
extern const char _PTR_  const _mqx_date;
extern const char _PTR_  const _mqx_generic_revision;
extern const char _PTR_  const _mqx_psp_revision;
extern const char _PTR_  _mqx_bsp_revision;
extern const char _PTR_  _mqx_io_revision;
extern void              _mqx_exit(_mqx_uint);
extern void              _mqx_fatal_error(_mqx_uint);
extern _mqx_uint         _mqx_get_counter(void);
extern _mqx_uint         _mqx_get_cpu_type(void);
extern MQX_INITIALIZATION_STRUCT_PTR _mqx_get_initialization(void);
extern pointer           _mqx_get_kernel_data(void);
extern MQX_EXIT_FPTR     _mqx_get_exit_handler(void);
extern _task_id          _mqx_get_system_task_id(void);
extern pointer           _mqx_get_tad_data(pointer);
extern void              _mqx_idle_task(uint_32);
extern volatile _mqx_uint _mqx_monitor_type;
extern void              _mqx_set_cpu_type(_mqx_uint);
extern void              _mqx_set_exit_handler(MQX_EXIT_FPTR);
extern void              _mqx_set_tad_data(pointer, pointer);
extern _mqx_uint         _mqx_get_idle_loop_count(IDLE_LOOP_STRUCT_PTR);


extern _mqx_uint         _sched_get_max_priority(_mqx_uint);
extern _mqx_uint         _sched_get_min_priority(_mqx_uint);
extern uint_32           _sched_get_rr_interval(_task_id, uint_32_ptr);
extern _mqx_uint         _sched_get_rr_interval_ticks(_task_id, MQX_TICK_STRUCT_PTR);
extern _mqx_uint         _sched_get_policy(_task_id, _mqx_uint_ptr);
extern _mqx_uint         _sched_set_policy(_task_id, _mqx_uint);
extern uint_32           _sched_set_rr_interval(_task_id, uint_32);
extern _mqx_uint         _sched_set_rr_interval_ticks(_task_id,
   MQX_TICK_STRUCT_PTR, MQX_TICK_STRUCT_PTR);
extern void              _sched_yield(void);


extern _mqx_uint         _task_abort(_task_id);
extern void              _task_block(void);
extern _mqx_uint         _task_check_stack(void);
extern _task_id          _task_create(_processor_number, _mqx_uint, uint_32);
extern _task_id          _task_create_blocked(_processor_number, _mqx_uint, uint_32);
extern _task_id          _task_create_at(_processor_number, _mqx_uint,
   uint_32, pointer, _mem_size);
extern _mqx_uint         _task_destroy(_task_id);
extern void              _task_disable_fp(void);
extern boolean           _task_enable_fp(void);
extern _task_id          _task_get_creator(void);
extern pointer           _task_get_environment(_task_id);
extern TASK_EXCEPTION_FPTR _task_get_exception_handler(_task_id);
extern _mqx_uint         _task_get_error(void);
extern _mqx_uint   _PTR_ _task_get_error_ptr(void);
extern TASK_EXIT_FPTR    _task_get_exit_handler(_task_id);
extern _task_id          _task_get_id(void);
extern _task_id          _task_get_id_from_name(char_ptr);
extern _task_id          _task_get_id_from_td(pointer);
extern _mqx_uint         _task_get_index_from_id(_task_id);
extern uint_32           _task_get_parameter(void);
extern uint_32           _task_get_parameter_for(_task_id);
extern _processor_number _task_get_processor(_task_id);
extern _mqx_uint         _task_get_priority(_task_id, _mqx_uint_ptr);
extern pointer           _task_get_td(_task_id);
extern _mqx_uint         _task_get_template_index(char_ptr);
extern TASK_TEMPLATE_STRUCT_PTR _task_get_template_ptr(_task_id);
extern void              _task_ready(pointer);
extern _mqx_uint         _task_restart(_task_id, uint_32_ptr, boolean);
extern pointer           _task_set_environment(_task_id, pointer);
extern _mqx_uint         _task_set_error(_mqx_uint);
extern TASK_EXCEPTION_FPTR _task_set_exception_handler(_task_id,TASK_EXCEPTION_FPTR);
extern TASK_EXIT_FPTR    _task_set_exit_handler(_task_id,TASK_EXIT_FPTR);
extern uint_32           _task_set_parameter(uint_32);
extern uint_32           _task_set_parameter_for(uint_32, _task_id);
extern _mqx_uint         _task_set_priority(_task_id, _mqx_uint, _mqx_uint_ptr);
extern void              _task_stop_preemption(void);
extern void              _task_start_preemption(void);

extern _mqx_uint         _task_reserve_space(_mqx_uint);
extern pointer           _task_get_reserved_base(void);

#if MQX_ENABLE_USER_MODE
extern _task_id          _usr_task_create(_processor_number, _mqx_uint, uint_32);
extern _mqx_uint         _usr_task_destroy(_task_id);
extern _mqx_uint         _usr_task_abort(_task_id task_id);
extern _mqx_uint         _usr_task_set_error(_mqx_uint);
extern pointer           _usr_task_get_td(_task_id);
extern void              _usr_task_ready(pointer);
#endif

extern pointer           _taskq_create(_mqx_uint);
extern _mqx_uint         _taskq_destroy(pointer);
extern _mqx_uint         _taskq_resume(pointer, boolean);
extern _mqx_uint         _taskq_suspend(pointer);
extern _mqx_uint         _taskq_suspend_task(_task_id, pointer);
extern _mqx_uint         _taskq_test(pointer _PTR_, pointer _PTR_);
extern _mqx_uint         _taskq_get_value(pointer);

extern MQX_TICK_STRUCT_PTR  _time_add_day_to_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);
extern MQX_TICK_STRUCT_PTR  _time_add_hour_to_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);
extern MQX_TICK_STRUCT_PTR  _time_add_min_to_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);
extern MQX_TICK_STRUCT_PTR  _time_add_msec_to_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);
extern MQX_TICK_STRUCT_PTR  _time_add_nsec_to_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);
extern MQX_TICK_STRUCT_PTR  _time_add_sec_to_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);
extern MQX_TICK_STRUCT_PTR  _time_add_usec_to_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);
extern MQX_TICK_STRUCT_PTR  _time_add_psec_to_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);

extern void                 _time_delay(uint_32);
extern void                 _time_delay_ticks(_mqx_uint);
extern void                 _time_delay_for(MQX_TICK_STRUCT_PTR);
extern void                 _time_delay_until(MQX_TICK_STRUCT_PTR);
extern void                 _time_dequeue(_task_id);
extern void                 _time_dequeue_td(pointer);
extern void                 _time_diff(TIME_STRUCT_PTR, TIME_STRUCT_PTR, TIME_STRUCT_PTR);
extern int_32               _time_diff_days(MQX_TICK_STRUCT_PTR, MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern int_32               _time_diff_hours(MQX_TICK_STRUCT_PTR, MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern int_32               _time_diff_minutes(MQX_TICK_STRUCT_PTR, MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern int_32               _time_diff_milliseconds(MQX_TICK_STRUCT_PTR, MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern int_32               _time_diff_nanoseconds(MQX_TICK_STRUCT_PTR,
   MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern int_32               _time_diff_picoseconds(MQX_TICK_STRUCT_PTR,
   MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern int_32               _time_diff_seconds(MQX_TICK_STRUCT_PTR,
   MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern int_32               _time_diff_microseconds(MQX_TICK_STRUCT_PTR,
   MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern _mqx_uint            _time_diff_ticks(MQX_TICK_STRUCT_PTR,
   MQX_TICK_STRUCT_PTR, MQX_TICK_STRUCT_PTR);
extern int_32               _time_diff_ticks_int32(MQX_TICK_STRUCT_PTR,
   MQX_TICK_STRUCT_PTR, boolean _PTR_);
extern boolean              _time_from_date(DATE_STRUCT_PTR, TIME_STRUCT_PTR);
extern void                 _time_get(TIME_STRUCT_PTR);
extern void                 _time_get_elapsed(TIME_STRUCT_PTR);
extern void                 _time_get_elapsed_ticks(MQX_TICK_STRUCT_PTR);
extern void                 _time_get_elapsed_ticks_fast(MQX_TICK_STRUCT_PTR);
extern uint_32              _time_get_hwticks(void);
extern uint_32              _time_get_hwticks_per_tick(void);
extern uint_16              _time_get_microseconds(void);
extern uint_32              _time_get_nanoseconds(void);
extern _mqx_uint            _time_get_resolution(void);
extern void                 _time_get_ticks(MQX_TICK_STRUCT_PTR);
extern _mqx_uint            _time_get_ticks_per_sec(void);
extern _mqx_uint            _time_init_ticks(MQX_TICK_STRUCT_PTR, _mqx_uint);
extern boolean              _time_normalize_xdate(MQX_XDATE_STRUCT_PTR);
extern void                 _time_notify_kernel(void);
extern void                 _time_set(TIME_STRUCT_PTR);
extern void                 _time_set_hwtick_function(MQX_GET_HWTICKS_FPTR, pointer);
extern void                 _time_set_hwticks_per_tick(uint_32);
extern _mqx_uint            _time_set_resolution(_mqx_uint);
extern void                 _time_set_ticks(MQX_TICK_STRUCT_PTR);
extern void                 _time_set_ticks_per_sec(_mqx_uint);
extern void                 _time_set_timer_vector(_mqx_uint);
extern boolean              _time_ticks_to_xdate(MQX_TICK_STRUCT_PTR,
   MQX_XDATE_STRUCT_PTR);
extern boolean              _time_to_date(TIME_STRUCT_PTR, DATE_STRUCT_PTR);
extern boolean              _time_xdate_to_ticks(MQX_XDATE_STRUCT_PTR,
   MQX_TICK_STRUCT_PTR);
extern boolean              _time_to_ticks(TIME_STRUCT_PTR, MQX_TICK_STRUCT_PTR);
extern boolean              _ticks_to_time(MQX_TICK_STRUCT_PTR, TIME_STRUCT_PTR);

#if MQX_ENABLE_USER_MODE
extern void                 _usr_time_delay(uint_32);
extern void                 _usr_time_delay_ticks(_mqx_uint);
extern void                 _usr_time_get_elapsed_ticks(MQX_TICK_STRUCT_PTR);
#endif /* MQX_ENABLE_USER_MODE */
#define MQX_TLS_SUPPORTED   1 /* Thread local storage supported */
extern pointer              _crt_tls_reference(void);

/*--------------------------------------------------------------------------*/
/*
 *                  ENDIAN SWAP MACROS AND PROTOTYPES
 */

#define _PSP_SWAP2BYTE_CONST(n) ((((n) & 0x00FF) << 8) | (((n) & 0xFF00) >> 8))
#define _PSP_SWAP4BYTE_CONST(n) ((((n) & 0x000000FF) << 24) | (((n) & 0x0000FF00) << 8) | (((n) & 0x00FF0000) >> 8) | (((n) & 0xFF000000) >> 24))

#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
    #define HOST_TO_BE_SHORT(n)           (n)
    #define HOST_TO_BE_SHORT_CONST(n)     (n)
    #define HOST_TO_LE_SHORT(n)           _PSP_SWAP2BYTE(n)
    #define HOST_TO_LE_SHORT_CONST(n)     _PSP_SWAP2BYTE_CONST(n)
    #define SHORT_BE_TO_HOST(n)           (n)
    #define SHORT_BE_TO_HOST_CONST(n)     (n)
    #define SHORT_LE_TO_HOST(n)           _PSP_SWAP2BYTE(n)
    #define SHORT_LE_TO_HOST_CONST(n)     _PSP_SWAP2BYTE_CONST(n)
    #define SHORT_UNALIGNED_LE_TO_HOST(n) ((n[1]<<8)|n[0])

    #define HOST_TO_BE_LONG(n)            (n)
    #define HOST_TO_BE_LONG_CONST(n)      (n)
	#define HOST_TO_BE_UNALIGNED_LONG(n, m)  \
    { \
       m[0]=((n>>24) & 0xFF); \
       m[1]=((n>>16) & 0xFF); \
       m[2]=((n>>8) & 0xFF); \
       m[3]=(n & 0xFF); \
    }
    #define HOST_TO_LE_LONG(n)            _PSP_SWAP4BYTE(n)
    #define HOST_TO_LE_LONG_CONST(n)      _PSP_SWAP4BYTE_CONST(n)
	#define HOST_TO_LE_UNALIGNED_LONG(n, m)  \
	{ \
       m[0]=(n & 0xFF); \
       m[1]=((n>>8) & 0xFF); \
       m[2]=((n>>16) & 0xFF); \
       m[3]=((n>>24) & 0xFF); \
    }
    #define LONG_BE_TO_HOST(n)            (n)
    #define LONG_BE_TO_HOST_CONST(n)      (n)
    #define LONG_LE_TO_HOST(n)            _PSP_SWAP4BYTE(n)
    #define LONG_LE_TO_HOST_CONST(n)      _PSP_SWAP4BYTE_CONST(n)
    #define LONG_UNALIGNED_LE_TO_HOST(n)  ((n[3]<<24)|(n[2]<<16)|(n[1]<<8)|n[0])

#else /* (PSP_ENDIAN == MQX_BIG_ENDIAN) */

    #define HOST_TO_BE_SHORT(n)           _PSP_SWAP2BYTE(n)
    #define HOST_TO_BE_SHORT_CONST(n)     _PSP_SWAP2BYTE_CONST(n)
    #define HOST_TO_LE_SHORT(n)           (n)
    #define HOST_TO_LE_SHORT_CONST(n)     (n)
    #define SHORT_BE_TO_HOST(n)           _PSP_SWAP2BYTE(n)
    #define SHORT_BE_TO_HOST_CONST(n)     _PSP_SWAP2BYTE_CONST(n)
    #define SHORT_LE_TO_HOST(n)           (n)
    #define SHORT_LE_TO_HOST_CONST(n)     (n)
    #define SHORT_UNALIGNED_LE_TO_HOST(n) ((n[1]<<8)|n[0])

    #define HOST_TO_BE_LONG(n)            _PSP_SWAP4BYTE(n)
    #define HOST_TO_BE_LONG_CONST(n)      _PSP_SWAP4BYTE_CONST(n)
    #define HOST_TO_BE_UNALIGNED_LONG(n, m)  \
    { \
       m[0]=((n>>24) & 0xFF); \
       m[1]=((n>>16) & 0xFF); \
       m[2]=((n>>8) & 0xFF); \
       m[3]=(n & 0xFF); \
    }
    #define HOST_TO_LE_LONG(n)            (n)
    #define HOST_TO_LE_LONG_CONST(n)      (n)
    #define HOST_TO_LE_UNALIGNED_LONG(n, m)  \
    { \
       m[0]=(n & 0xFF); \
       m[1]=((n>>8) & 0xFF); \
       m[2]=((n>>16) & 0xFF); \
       m[3]=((n>>24) & 0xFF); \
    }

    #define LONG_BE_TO_HOST(n)            _PSP_SWAP4BYTE(n)
    #define LONG_BE_TO_HOST_CONST(n)      _PSP_SWAP4BYTE_CONST(n)
    #define LONG_LE_TO_HOST(n)            (n)
    #define LONG_LE_TO_HOST_CONST(n)      (n)
    #define LONG_UNALIGNED_LE_TO_HOST(n)  ((n[3]<<24)|(n[2]<<16)|(n[1]<<8)|n[0])


#endif /* (PSP_ENDIAN == MQX_BIG_ENDIAN) */

#endif /* __TAD_COMPILE__ */

#ifdef __cplusplus
}
#endif

#endif /* __ASM__ */

/*--------------------------------------------------------------------------*/
/*
 *                  SPECIAL MEMORY ALLOCATOR OPTION
 */

#if MQX_USE_LWMEM_ALLOCATOR
#ifndef __MEMORY_MANAGER_COMPILE__
#include "lwmem.h"
#define _mem_pool_id _lwmem_pool_id
#define _mem_alloc _lwmem_alloc
#define _mem_alloc_at _lwmem_alloc_at
#define _mem_alloc_align _lwmem_alloc_align
#define _mem_alloc_align_from _lwmem_alloc_align_from
#define _mem_alloc_from _lwmem_alloc_from
#define _mem_alloc_zero _lwmem_alloc_zero
#define _mem_alloc_zero_from _lwmem_alloc_zero_from
#define _mem_alloc_system _lwmem_alloc_system
#define _mem_alloc_system_from _lwmem_alloc_system_from
#define _mem_alloc_system_zero _lwmem_alloc_system_zero
#define _mem_alloc_system_zero_from _lwmem_alloc_system_zero_from
#define _mem_free _lwmem_free
#define _mem_transfer _lwmem_transfer
#define _mem_get_system_pool_id _lwmem_get_system_pool_id
#define _mem_create_pool _lwmem_create_pool_mapped
#define _mem_get_highwater _lwmem_get_highwater
#define _mem_get_free _lwmem_get_free
#define _mem_get_free_from _lwmem_get_free_from
#if MQX_ALLOW_TYPED_MEMORY
#define _mem_get_type _lwmem_get_type
#define _mem_set_type _lwmem_set_type
#endif
#if MQX_ENABLE_USER_MODE
#define _usr_mem_alloc                  _usr_lwmem_alloc
#define _usr_mem_alloc_from             _usr_lwmem_alloc_from
#define _usr_mem_free                   _usr_lwmem_free
#endif /* MQX_ENABLE_USER_MODE */
#endif
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/include/host_main.h<|end_filename|>
#ifndef __host_main_h__
#define __host_main_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_main.h$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   
*
*END************************************************************************/
#include "hostapi.h"
#include "mqx_host.h"

typedef struct usb_host_generic_structure {
   pointer                             INIT_PARAM;
   pointer                             DEV_PTR;
   uint_8                              DEV_NUM; //deprecated, should not be used
   uint_32                             SPEED;
   const USB_HOST_CALLBACK_FUNCTIONS_STRUCT * CALLBACK_STRUCT_PTR;
   pointer                             DEVICE_LIST_PTR;
   struct pipe_struct                  * PIPE_DESCRIPTOR_BASE_PTR;
   struct host_service_struct          * SERVICE_HEAD_PTR;
   struct driver_info                  * DEVICE_INFO_TABLE;
   uint_32                             PIPE_SIZE;
   uint_32                             TR_SIZE;
} USB_HOST_STATE_STRUCT, _PTR_ USB_HOST_STATE_STRUCT_PTR;

/* List of Function Prototypes */

#ifdef __cplusplus
extern "C" {
#endif

USB_STATUS _usb_host_init_call_interface (_usb_host_handle);
USB_STATUS _usb_host_shutdown_call_interface (_usb_host_handle);
USB_STATUS _usb_host_send_call_interface (_usb_host_handle, struct pipe_struct _PTR_, struct tr_struct _PTR_);
USB_STATUS _usb_host_send_setup_call_interface (_usb_host_handle, struct pipe_struct _PTR_, struct tr_struct _PTR_);
USB_STATUS _usb_host_recv_data_call_interface (_usb_host_handle, struct pipe_struct _PTR_ pipe_descr_ptr, struct tr_struct _PTR_);
USB_STATUS _usb_host_cancel_call_interface (_usb_host_handle, struct pipe_struct _PTR_, struct tr_struct _PTR_);
USB_STATUS _usb_host_bus_control_data_call_interface (_usb_host_handle, uint_8);
USB_STATUS _usb_host_alloc_bandwidth_call_interface (_usb_host_handle, struct pipe_struct _PTR_);
USB_STATUS _usb_host_close_pipe_call_interface (_usb_host_handle, struct pipe_struct _PTR_);
USB_STATUS _usb_host_open_pipe_call_interface (_usb_host_handle, struct pipe_struct _PTR_);
USB_STATUS _usb_host_update_max_packet_size_call_interface (_usb_host_handle, struct pipe_struct _PTR_);
USB_STATUS _usb_host_update_device_address_call_interface (_usb_host_handle, struct pipe_struct _PTR_);
//USB_STATUS _usb_host_iso_packet_desc_pool_create (uint_32);
//void _usb_host_iso_packet_desc_pool_destroy (void);
//USB_STATUS _usb_host_iso_packet_desc_list_alloc (uint_32, USB_ISO_PACKET_DESC_LIST_STRUCT_PTR);
//void _usb_host_iso_packet_desc_list_free (USB_ISO_PACKET_DESC_LIST_STRUCT_PTR);
USB_STATUS _usb_host_init (USB_HOST_IF_STRUCT_PTR, _usb_host_handle _PTR_);
USB_STATUS _usb_host_register_service (_usb_host_handle, uint_8, void(_CODE_PTR_ service)(pointer, uint_32));
USB_STATUS _usb_host_call_service (_usb_host_handle, uint_8, uint_32);
USB_STATUS _usb_host_check_service (_usb_host_handle, uint_8, uint_32);
USB_STATUS _usb_host_unregister_service (_usb_host_handle, uint_8);
USB_STATUS _usb_host_open_pipe (_usb_host_handle, PIPE_INIT_PARAM_STRUCT_PTR, _usb_pipe_handle _PTR_);
struct tr_struct _PTR_ _usb_host_get_tr_element (_usb_pipe_handle, uint_32);
USB_STATUS  _usb_host_set_up_tr (_usb_pipe_handle, TR_INIT_PARAM_STRUCT_PTR, struct tr_struct _PTR_ _PTR_);
uint_32 _usb_host_get_transfer_status (_usb_pipe_handle, uint_32);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/App.h<|end_filename|>
#include <ctype.h>
#include <math.h>
#include <mqx.h>
#include <bsp.h>
#include <mutex.h>
#include <fio.h>
//#include <flexcan.h>
#include <arm_itm.h>
#include "gflib.h"
#include "gdflib.h"
#include "gmclib.h"
#include "Pins_control.h"
#include "Motor_control.h"
#include "Temperature_control.h"
#include "ADC_control.h"
#include "LCD_control.h"
#include "SIN_COS_generator.h"
#include "MonitorVT100.h"
#include "Tests.h"
#include "CAN_control.h"
#include "app_IDs.h"


#define MOTISR_IDX  1
#define CTRL_IDX    2
#define MEAS_IDX    3
#define VT100_IDX   4
#define LCD_IDX     5
#define CAN_TX_IDX  6
#define CAN_RX_IDX  7


#define MOTISR_ID_PRIO   7
#define CTRL_ID_PRIO     8
#define MEAS_ID_PRIO     9

#define CAN_RX_ID_PRIO   9
#define CAN_TX_ID_PRIO   9

#define VT100_ID_PRIO    10
#define LCD_ID_PRIO      11

#define ETM0_ISR_PRIO  3  // Приоритет процедуры прерывания узла ШИМ модуляции
#define PDB0_ISR_PRIO  3  // Приоритет процедуры прерывания узла программируемой задержки для считывания результатов АЦП
#define CAN_ISR_PRIO   3  // Приоритет процедуры прерывания от контроллера CAN шины


#define MEAS_RES_ARR_SZ 11
#define MEAS_RES_LOG_SZ 1000 // 50 сек

extern void Delay_m8(int cnt); // Задержка на (cnt+1)*8 тактов . Передача нуля недопускается

  #define  DELAY_1us  Delay_m8(15-1)
  #define  DELAY_2us  Delay_m8(2*15-1)
  #define  DELAY_4us  Delay_m8(4*15-1)
  #define  DELAY_8us  Delay_m8(8*15-1)
  #define  DELAY_30us Delay_m8(30*15-1)


void    Lock_meas_mutex(void);
void    Unlock_meas_mutex(void);
//INT32U  Reset_rms_log(void);
//INT32U  Get_rms_log_pos(void);
//void    Get_rms_log_arr(float **ptr);
float   Get_aver_curr(void);
void    Reset_aver_curr(void);


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/name.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: name.h$
* $Version : 3.0.5.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   name component.
*
*END************************************************************************/
#ifndef __name_h__
#define __name_h__ 1

#include <mqx_cnfg.h>
#if (! MQX_USE_NAME) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error NAME component is currently disabled in MQX kernel. Please set MQX_USE_NAME to 1 in user_config.h and recompile kernel.
#endif

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* Error codes */

#define NAME_TABLE_FULL             (NAME_ERROR_BASE|0x00)
#define NAME_EXISTS                 (NAME_ERROR_BASE|0x01)
#define NAME_NOT_FOUND              (NAME_ERROR_BASE|0x02)
#define NAME_TOO_LONG               (NAME_ERROR_BASE|0x03)
#define NAME_TOO_SHORT              (NAME_ERROR_BASE|0x04)

/* The maximum name size for a name component name */
#define NAME_MAX_NAME_SIZE          (32)

/* Default component creation parameters */
#define NAME_DEFAULT_INITIAL_NUMBER (8)
#define NAME_DEFAULT_GROW_NUMBER    (8)
#define NAME_DEFAULT_MAXIMUM_NUMBER (0) /* Unlimited */

/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _name_create_component(_mqx_uint, _mqx_uint, _mqx_uint);
extern _mqx_uint _name_add(char_ptr, _mqx_max_type);
extern _mqx_uint _name_delete(char_ptr);
extern _mqx_uint _name_find(char_ptr, _mqx_max_type_ptr);
extern _mqx_uint _name_find_by_number(_mqx_max_type, char_ptr);
extern _mqx_uint _name_test(pointer _PTR_, pointer _PTR_);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/chap.h<|end_filename|>
#ifndef __chap_h__
#define __chap_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: chap.h$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the defines and data structure
*   definitions required by CHAP.
*
*END************************************************************************/


/*
** CHAP header = Code, id, length.
*/

#define CHAP_HDR_LEN    4

/*
** The length of generated challenges
*/

#define CHAP_CHALLENGE_LEN    64

/*
** CHAP packet types
*/

#define CHAP_CODE_CHALLENGE   1     /* Challenge */
#define CHAP_CODE_RESPONSE    2     /* Response to challenge */
#define CHAP_CODE_SUCCESS     3     /* Successful response */
#define CHAP_CODE_FAILURE     4     /* Failed response */

/*
** Internal CHAP states
*/

#define CHAP_STATE_CLOSED     0
#define CHAP_STATE_INITIAL    1
#define CHAP_STATE_SUCCESS    CHAP_CODE_SUCCESS
#define CHAP_STATE_FAILURE    CHAP_CODE_FAILURE

/*
** Private state required by the CHAP server
*/

typedef struct chap_data {

   /* Statistics counters */
   uint_32  ST_CHAP_SHORT;    /* packet too short */
   uint_32  ST_CHAP_CODE;     /* invalid code */
   uint_32  ST_CHAP_ID;       /* incorrect id */
   uint_32  ST_CHAP_NOAUTH;   /* challenge received but CHAP not negotiated */
   uint_32  ST_CHAP_NOCHAL;   /* response received but no challenge made */
   uint_32  ST_CHAP_NOPW;     /* no password for peer */

   uchar MD5[64];

   uchar CLIENT_STATE;
   uchar SERVER_STATE;
   uchar CURID;

} CHAP_DATA, _PTR_ CHAP_DATA_PTR;


/*
** Prototypes
*/

extern void CHAP_init      (_ppp_handle);
extern void CHAP_challenge (_ppp_handle);
extern void CHAP_open      (_ppp_handle);

extern void CHAP_input (PCB_PTR, _ppp_handle);


/*
** Available hashing algorithms
*/

extern void PPP_MD5(uchar_ptr, ...);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/string/str_utos.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: str_utos.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the function for converting a _mqx_uint to a string.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "mqx_str.h"

const char _str_hex_array_internal[] = "0123456789ABCDEF";

/*!
 * \brief Converts the _mqx_uint value to a hexadecimal string.
 * 
 * \param[in]  num    The number to convert.
 * \param[out] string The address of the string to write to.
 * 
 * \see _strnlen
 */ 
void _str_mqx_uint_to_hex_string
   (
      register _mqx_uint num,
      register char_ptr  string
   )
{ /* Body */

#if (MQX_INT_SIZE_IN_BITS == 64)
   string[0]  = _str_hex_array_internal[(num >> 60)&0xF];
   string[1]  = _str_hex_array_internal[(num >> 56)&0xF];
   string[2]  = _str_hex_array_internal[(num >> 52)&0xF];
   string[3]  = _str_hex_array_internal[(num >> 48)&0xF];
   string[4]  = _str_hex_array_internal[(num >> 44)&0xF];
   string[5]  = _str_hex_array_internal[(num >> 40)&0xF];
   string[6]  = _str_hex_array_internal[(num >> 36)&0xF];
   string[7]  = _str_hex_array_internal[(num >> 32)&0xF];
   string[8]  = _str_hex_array_internal[(num >> 28)&0xF];
   string[9]  = _str_hex_array_internal[(num >> 24)&0xF];
   string[10] = _str_hex_array_internal[(num >> 20)&0xF];
   string[11] = _str_hex_array_internal[(num >> 16)&0xF];
   string[12] = _str_hex_array_internal[(num >> 12)&0xF];
   string[13] = _str_hex_array_internal[(num >>  8)&0xF];
   string[14] = _str_hex_array_internal[(num >>  4)&0xF];
   string[16] = _str_hex_array_internal[(num      )&0xF];
   string[17] = 0;
#elif (MQX_INT_SIZE_IN_BITS == 32)
   string[0] = _str_hex_array_internal[(num >> 28)&0xF];
   string[1] = _str_hex_array_internal[(num >> 24)&0xF];
   string[2] = _str_hex_array_internal[(num >> 20)&0xF];
   string[3] = _str_hex_array_internal[(num >> 16)&0xF];
   string[4] = _str_hex_array_internal[(num >> 12)&0xF];
   string[5] = _str_hex_array_internal[(num >>  8)&0xF];
   string[6] = _str_hex_array_internal[(num >>  4)&0xF];
   string[7] = _str_hex_array_internal[(num      )&0xF];
   string[8] = 0;
#elif (MQX_INT_SIZE_IN_BITS == 24)
   string[0] = _str_hex_array_internal[(num >> 20)&0xF];
   string[1] = _str_hex_array_internal[(num >> 16)&0xF];
   string[2] = _str_hex_array_internal[(num >> 12)&0xF];
   string[3] = _str_hex_array_internal[(num >>  8)&0xF];
   string[4] = _str_hex_array_internal[(num >>  4)&0xF];
   string[5] = _str_hex_array_internal[(num      )&0xF];
   string[6] = 0;
#elif (MQX_INT_SIZE_IN_BITS == 16)
   string[0] = _str_hex_array_internal[(num >> 12)&0xF];
   string[1] = _str_hex_array_internal[(num >>  8)&0xF];
   string[2] = _str_hex_array_internal[(num >>  4)&0xF];
   string[3] = _str_hex_array_internal[(num      )&0xF];
   string[4] = 0;
#endif

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/usb_descriptor.h<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
**************************************************************************/ /*!
  *
  * @file usb_descriptor.h
  *
  * @author
  *
  * @version
  *
  * @date
  *
  * @brief The file is a header file for USB Descriptors required for Mouse
  *        Application
  *****************************************************************************/

#ifndef _USB_DESCRIPTOR_H
  #define _USB_DESCRIPTOR_H

/******************************************************************************
 * Includes
 *****************************************************************************/

  #include "usb_class.h"
  #include "usb_dfu.h"
/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
  #define REMOTE_WAKEUP_SHIFT               (5)
  #define REMOTE_WAKEUP_SUPPORT             (TRUE)

/* Various descriptor sizes */
  #define DEVICE_DESCRIPTOR_SIZE            (18)
  #define CONFIG_DESC_SIZE_RUNTIME          (52)
  #define DEVICE_QUALIFIER_DESCRIPTOR_SIZE  (10)
  #define REPORT_DESC_SIZE                  (52)
  #define CONFIG_ONLY_DESC_SIZE             (9)
  #define IFACE_ONLY_DESC_SIZE              (9)
  #define HID_ONLY_DESC_SIZE                (9)
  #define ENDP_ONLY_DESC_SIZE               (7)

/* HID buffer size */
  #define HID_BUFFER_SIZE                   (8)
/* Max descriptors provided by the Application */
  #define USB_MAX_STD_DESCRIPTORS               (8)
  #define USB_MAX_CLASS_SPECIFIC_DESCRIPTORS    (2)
/* Max configuration supported by the Application */
  #define USB_MAX_CONFIG_SUPPORTED          (1)

/* Max string descriptors supported by the Application */
  #define USB_MAX_STRING_DESCRIPTORS        (4)

/* Max language codes supported by the USB */
  #define USB_MAX_LANGUAGES_SUPPORTED       (1)


  #define HID_DESC_ENDPOINT_COUNT  (1)
  #define HID_ENDPOINT             (1)
  #define HID_ENDPOINT_PACKET_SIZE (8)

  #define DFU_MAX_BLOCK_SIZE       (63) // Если сделать 64 то запись 64-х битных DFU OUT пакетов сбивается.
                                        // Какая-то проблема с приемом пакетов в функции USB_Packet_RXTX_Handler в строках 1184-1220 

/* only control enpoint */
  #define DFU_DESC_ENDPOINT_COUNT  (0)
  #define FUNCTIONAL_DESC_SIZE     (9)

  #define CONFIG_DESC_SIZE_DFU  (CONFIG_ONLY_DESC_SIZE + \
                                IFACE_ONLY_DESC_SIZE + \
                                FUNCTIONAL_DESC_SIZE + \
                                ENDP_ONLY_DESC_SIZE * DFU_DESC_ENDPOINT_COUNT)
/* string descriptors sizes */
  #define USB_STR_DESC_SIZE         (2)
  #define USB_STR_0_SIZE            (2)
  #define USB_STR_1_SIZE           (56)
  #define USB_STR_2_SIZE           (24)
  #define USB_STR_3_SIZE           (20)
  #define USB_STR_n_SIZE           (32)

/* descriptors codes */
  #define USB_DEVICE_DESCRIPTOR     (1)
  #define USB_CONFIG_DESCRIPTOR     (2)
  #define USB_STRING_DESCRIPTOR     (3)
  #define USB_IFACE_DESCRIPTOR      (4)
  #define USB_ENDPOINT_DESCRIPTOR   (5)
  #define USB_DEVQUAL_DESCRIPTOR    (6)
  #define USB_HID_DESCRIPTOR        (0x21)
  #define USB_REPORT_DESCRIPTOR     (0x22)

  #define USB_MAX_SUPPORTED_INTERFACES     (1)
/* DFU functional codes */
  #define USB_DFU_FUNCTIONAL_DESCRIPTOR     (0x21)


/* DFU functional codes */
  #define DETACH               (1)
  #define MANIFESTATION        (1)
  #define BITCANUPLOAD         (1)
  #define BITCANDOWNLOAD       (1)
/* DFU_EP is control enpoint*/
  #define DFU_EP               0x00

/******************************************************************************
 * Types
 *****************************************************************************/
typedef const struct _USB_LANGUAGE
{
  INT16U const language_id;      /* Language ID */
  INT8U const **lang_desc;      /* Language Descriptor String */
  INT8U const *lang_desc_size;  /* Language Descriptor Size */
} USB_LANGUAGE;

typedef const struct _USB_ALL_LANGUAGES
{
  /* Pointer to Supported Language String */
  INT8U const *languages_supported_string;
  /* Size of Supported Language String */
  INT8U const languages_supported_size;
  /* Array of Supported Languages */
  USB_LANGUAGE usb_language[USB_MAX_SUPPORTED_INTERFACES];
}USB_ALL_LANGUAGES;

typedef const struct _USB_ENDPOINTS
{
  /* Number of non control Endpoints */
  INT8U count;
  /* Array of Endpoints Structures */
  USB_EP_STRUCT ep[HID_DESC_ENDPOINT_COUNT];
}USB_ENDPOINTS;

/******************************************************************************/
  #define STORAGE_FIRMWARE FALSE

/******************************************************************************
 * Global Functions
 *****************************************************************************/
extern INT8U USB_Desc_Get_Descriptor(INT8U controller_ID,INT8U type,INT8U str_num,INT16U index,INT8U_ptr *descriptor,INT16U *size);
extern INT8U USB_Desc_Get_Interface(INT8U controller_ID,INT8U interface,INT8U_ptr alt_interface);
extern INT8U USB_Desc_Set_Interface(INT8U controller_ID,INT8U interface,INT8U alt_interface);
extern BOOLEAN USB_Desc_Valid_Configation(INT8U controller_ID,INT16U config_val);
extern BOOLEAN USB_Desc_Valid_Interface(INT8U controller_ID,INT8U interface);
extern BOOLEAN USB_Desc_Remote_Wakeup(INT8U controller_ID);
extern void* USB_Desc_Get_Endpoints(INT8U controller_ID);
#endif


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/audio/usb_audio.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_audio.c$
* $Version : 3.8.6.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
* @brief The file contains USB stack AUDIO layer implimentation.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_stack_config.h"

#if AUDIO_CONFIG
 
#include "usb_audio.h"

/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/


/****************************************************************************
 * Global Variables
 ****************************************************************************/
 AUDIO_DEVICE_STRUCT    *device_array[MAX_AUDIO_DEVICE];          
/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
static uint_8 USB_Audio_Other_Requests(USB_SETUP_STRUCT * setup_packet, 
                          uint_8_ptr *data, 
                          uint_32 *size,pointer arg);
static void USB_Class_Audio_Event(uint_8 event, void* val,pointer arg);
static AUDIO_HANDLE  USB_Audio_Get_Free_Handle(void);
static uint_32 USB_Audio_Free_Handle(AUDIO_HANDLE handle);
static void USB_Service_Audio_Status_Interrupt(PTR_USB_EVENT_STRUCT event,pointer arg);
static void USB_Service_Audio_Isochronous_OUT(PTR_USB_EVENT_STRUCT event,pointer arg);
static void USB_Service_Audio_Isochronous_IN(PTR_USB_EVENT_STRUCT event,pointer arg);

/*****************************************************************************
 * Local Variables - None
 *****************************************************************************/
 
 
/*****************************************************************************
 * Local Functions
 *****************************************************************************/
 /*************************************************************************//*!
 *
 * @name  	USB_Audio_Get_Free_Handle
 *
 * @brief 	The funtion reserves entry in device array and returns the index.
 *
 * @param 	none.
 * @return 	returns the reserved handle or if no entry found device busy.      
 *
 *****************************************************************************/
static AUDIO_HANDLE  USB_Audio_Get_Free_Handle()
{
    uint_32 cnt = 0;
   	for (;cnt< MAX_AUDIO_DEVICE;cnt++)
   	{
   	   if (device_array[cnt] == NULL)
   	   	return cnt;
   	}
   	return USBERR_DEVICE_BUSY;
}
 /*************************************************************************//*!
 *
 * @name  USB_Audio_Free_Handle
 *
 * @brief The funtion releases entry in device array .
 *
 * @param handle  index in device array to be released..
 * @return returns and error code or USB_OK.      
 *
 *****************************************************************************/

static uint_32 USB_Audio_Free_Handle(AUDIO_HANDLE handle)
{
	if (handle > MAX_AUDIO_DEVICE)
		return USBERR_ERROR;
	
	USB_mem_free((void *)device_array[handle]);
	device_array[handle] = NULL;
	return USB_OK;
}
 
/**************************************************************************//*!
 *
 * @name  USB_Service_Audio_Status_Interrupt
 *
 * @brief The funtion is callback function of Audio Status Interrupt endpoint 
 *
 * @param event
 *
 * @return None       
 *
 *****************************************************************************/
static void USB_Service_Audio_Status_Interrupt(PTR_USB_EVENT_STRUCT event,pointer arg)
{
	AUDIO_DEVICE_STRUCT_PTR  audio_obj_ptr;

#if IMPLEMENT_QUEUING
    uint_8 index;
    uint_8 producer, consumer;
    USB_ENDPOINTS *usb_ep_data;
#endif
        
    audio_obj_ptr = (AUDIO_DEVICE_STRUCT_PTR)arg;

#if IMPLEMENT_QUEUING
    usb_ep_data = audio_obj_ptr->usb_ep_data; 

     /* map the endpoint num to the index of the endpoint structure */
    for(index = 0; index < usb_ep_data->count; index++) 
    {
        if(usb_ep_data->ep[index].ep_num == event->ep_num)
            break;
    }
                                               
    producer = audio_obj_ptr->ep[index].bin_producer;    
        
    /* if there are no errors de-queue the queue and decrement the no. of 
     transfers left, else send the same data again */
     /* de-queue if the send is complete with no error */
     consumer = audio_obj_ptr->ep[index].bin_consumer;
    if(consumer == (AUDIO_MAX_QUEUE_ELEMS -1))
    {
    	audio_obj_ptr->ep[index].bin_consumer = 0;
    }
    else
    {
    	audio_obj_ptr->ep[index].bin_consumer++;
    }
     
    audio_obj_ptr->ep[index].queue_num--;
          
    if(0 != audio_obj_ptr->ep[index].queue_num) 
    {/*if bin is not empty */
        
        USB_CLASS_AUDIO_QUEUE queue;    
        /* send the next packet in queue */
        consumer = audio_obj_ptr->ep[index].bin_consumer;
        queue = audio_obj_ptr->ep[index].queue[consumer];
        (void)USB_Class_Send_Data(audio_obj_ptr->class_handle, queue.channel, 
                                      queue.app_data.data_ptr, queue.app_data.data_size);                                                                                                
    }        
#endif

    /* Callback to application */
    if (audio_obj_ptr->audio_class_callback.callback != NULL)
    {
	    /* notify the app of the send complete */
	    audio_obj_ptr->audio_class_callback.callback(USB_APP_SEND_COMPLETE, 0,
	    audio_obj_ptr->audio_class_callback.arg); 
    }
}

/**************************************************************************//*!
 *
 * @name  USB_Service_Audio_Isochronous_IN
 *
 * @brief The funtion ic callback function of Audio Isochronous IN endpoint 
 *
 * @param event
 *
 * @return None       
 *
 *****************************************************************************/
static void USB_Service_Audio_Isochronous_IN(PTR_USB_EVENT_STRUCT event,pointer arg)
{

    APP_DATA_STRUCT iso_in_recv;
    uint_8 event_type;
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr = (AUDIO_DEVICE_STRUCT_PTR)arg;
    
	#if IMPLEMENT_QUEUING
	    uint_8 index;
	    uint_8 producer, consumer;
	    USB_ENDPOINTS *usb_ep_data = audio_obj_ptr->usb_ep_data;
	    
	    USB_CLASS_AUDIO_QUEUE queue;

	    /* map the endpoint num to the index of the endpoint structure */
	    for(index = 0; index < usb_ep_data->count; index++) 
	    {
	        if(usb_ep_data->ep[index].ep_num ==event->ep_num)
	            break;
	    }
	     
	    producer = audio_obj_ptr->ep[index].bin_producer;	        
	    /* if there are no errors de-queue the queue and decrement the no. of 
	       transfers left, else send the same data again */
	    consumer = audio_obj_ptr->ep[index].bin_consumer;
	    if((AUDIO_MAX_QUEUE_ELEMS-1) == consumer)
	    {
	    	audio_obj_ptr->ep[index].bin_consumer = 0;
	    }
	    else
	    {
	    	audio_obj_ptr->ep[index].bin_consumer++;
	    }
	    consumer = audio_obj_ptr->ep[index].bin_consumer;
	    audio_obj_ptr->ep[index].queue_num--;
	        
	    if(0 != audio_obj_ptr->ep[index].queue_num) 
	    {/*if bin is not empty */
	                        
	        queue = audio_obj_ptr->ep[index].queue[consumer];
	                        
	        (void)USB_Class_Send_Data(audio_obj_ptr->class_handle, queue.channel, 
	        	queue.app_data.data_ptr, queue.app_data.data_size);
	    }          
	#endif
    
    /* Callback to application */
    if(audio_obj_ptr->param_callback.callback != NULL) 
    {
        event_type = USB_APP_SEND_COMPLETE;
        iso_in_recv.data_ptr = event->buffer_ptr;
        iso_in_recv.data_size = event->len;
        audio_obj_ptr->param_callback.callback(event_type,
                (void*)&iso_in_recv,audio_obj_ptr->param_callback.arg);             
    }
}

/**************************************************************************//*!
 *
 * @name  USB_Service_Audio_Isochronous_OUT
 *
 * @brief The funtion is callback function of Isochronous Out Endpoint 
 *
 * @param event
 *
 * @return None       
 *
 *****************************************************************************/
static void USB_Service_Audio_Isochronous_OUT(PTR_USB_EVENT_STRUCT event,pointer arg)
{   
    APP_DATA_STRUCT iso_out_recv;
    uint_8 event_type; 
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr = (AUDIO_DEVICE_STRUCT_PTR)arg;
    event_type = USB_APP_DATA_RECEIVED; 
    iso_out_recv.data_ptr = event->buffer_ptr;
    iso_out_recv.data_size = event->len; 
  	
  	/* Callback to application */
    if(audio_obj_ptr->param_callback.callback != NULL) 
    {
      audio_obj_ptr->param_callback.callback(event_type,
      (void*)&iso_out_recv,audio_obj_ptr->param_callback.arg);             
    }
 }


/**************************************************************************//*!
 *
 * @name  USB_Class_Audio_Event
 *
 * @brief The funtion initializes Audio endpoint 
 *
 * @param handle          handle to Identify the controller
 * @param event           pointer to event structure
 * @param val             gives the configuration value 
 *
 * @return None       
 *
 *****************************************************************************/
static void USB_Class_Audio_Event(uint_8 event, void* val,pointer arg) 
{  
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr = (AUDIO_DEVICE_STRUCT_PTR)arg;
    
    if (audio_obj_ptr == NULL)
    {
        #ifdef _DEV_DEBUG
            printf("USB_Class_Audio_Event:audio_obj_ptr is NULL\n");
        #endif  
        return;
    }
    
    /* if enum is complete initialize non-control endpoints */
    if(event == USB_APP_ENUM_COMPLETE) 
    {
        uint_8 count = 0;
        USB_EP_STRUCT_PTR ep_struct_ptr;
        
        /* get the endpoints from the descriptor module */            
        USB_ENDPOINTS *usb_ep_data = audio_obj_ptr->usb_ep_data;
        
        /* intialize all non control endpoints */            
        while(count < usb_ep_data->count) 
        {
            ep_struct_ptr = (USB_EP_STRUCT*)&usb_ep_data->ep[count];

            (void)_usb_device_init_endpoint(audio_obj_ptr->controller_handle,
             ep_struct_ptr,TRUE);
  
            /* register callback service for Non Control EndPoints */
            switch(ep_struct_ptr->type) 
            {
              	case USB_INTERRUPT_PIPE :
                  	(void)_usb_device_register_service(audio_obj_ptr->controller_handle,
                    	(uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                        USB_Service_Audio_Status_Interrupt,(void *)audio_obj_ptr);
                  	break;                              
              	case USB_ISOCHRONOUS_PIPE :
                  	if(ep_struct_ptr->direction == USB_RECV) 
                  	{
                      	(void)_usb_device_register_service(audio_obj_ptr->controller_handle,
                        	(uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                            USB_Service_Audio_Isochronous_OUT,(void *)audio_obj_ptr);
                  	} 
                  	else
                  	{
                      	(void)_usb_device_register_service(audio_obj_ptr->controller_handle,
                        	(uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                            USB_Service_Audio_Isochronous_IN,(void *)audio_obj_ptr);
                  	}
                  	break;
              	default : break;        
            }
                          
            /* set the EndPoint Status as Idle in the device layer */
            /* (no need to specify direction for this case) */
			(void)_usb_device_set_status(audio_obj_ptr->controller_handle,
            	(uint_8)(USB_STATUS_ENDPOINT|ep_struct_ptr->ep_num),
                (uint_8)USB_STATUS_IDLE);                                                                                                         
            count++;                                                    
        }/* EndWhile */
    }
    if(audio_obj_ptr->audio_class_callback.callback != NULL) 
    {
        audio_obj_ptr->audio_class_callback.callback(event,
        	val,audio_obj_ptr->audio_class_callback.arg);
    } 
}

/**************************************************************************//*!
 *
 * @name  USB_Get_Cur_Audio_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Get_Cur_Audio_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{	
	uint_8 error;
	int_32 cmd = -1;
   if (size == NULL)				 
   {
   		return USBERR_ERROR;	
   }
	error = USBERR_INVALID_REQ_TYPE;
	switch(setup_packet->value>>8)
	{
      case MUTE_CONTROL:
      	*size = 1;
      	cmd = GET_CUR_MUTE_CONTROL;
        break;
      case VOLUME_CONTROL:
      	*size = 2;
      	cmd = GET_CUR_VOLUME_CONTROL;
        break;
      case BASS_CONTROL:
      	*size = 1;
      	cmd = GET_CUR_BASS_CONTROL;
        break;
      case MID_CONTROL:
      	*size = 1;
      	cmd = GET_CUR_MID_CONTROL;
        break;
      case TREBLE_CONTROL:
      	*size = 1;
      	cmd = GET_CUR_TREBLE_CONTROL;
        break;
      case GRAPHIC_EQUALIZER_CONTROL:
      	*size = 5;
      	cmd = GET_CUR_GRAPHIC_EQUALIZER_CONTROL;
        break;
      case AUTOMATIC_GAIN_CONTROL:
      	*size = 1;
      	cmd = GET_CUR_AUTOMATIC_GAIN_CONTROL;
        break;
      case DELAY_CONTROL:
      	*size = 2;
      	cmd = GET_CUR_DELAY_CONTROL;
        break;
      case BASS_BOOST_CONTROL:
      	*size = 1;
      	cmd = GET_CUR_BASS_BOOST_CONTROL;
        break;
      case LOUDNESS_CONTROL:
      	*size = 1;
      	cmd = GET_CUR_LOUDNESS_CONTROL;
        break;
      default:
    	break;    
   }
   if(cmd > 0)
   {
	  	error = USB_Class_Get_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
   
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Get_Min_Audio_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Get_Min_Audio_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{	
	uint_8 error;
	int cmd = -1;
    if (size == NULL)				 
    {
   		return USBERR_ERROR;	
    }
	error = USBERR_INVALID_REQ_TYPE;
	switch(setup_packet->value>>8)
	{
      case VOLUME_CONTROL:
      	*size = 2;
      	cmd = GET_MIN_VOLUME_CONTROL;
        break;
      case BASS_CONTROL:
      	*size = 1;
      	cmd = GET_MIN_BASS_CONTROL;
        break;
      case MID_CONTROL:
      	*size = 1;
      	cmd = GET_MIN_MID_CONTROL;
        break;
      case TREBLE_CONTROL:
      	*size = 1;
      	cmd = GET_MIN_TREBLE_CONTROL;
        break;
      case GRAPHIC_EQUALIZER_CONTROL:
      	*size = 5;
      	cmd = GET_MIN_GRAPHIC_EQUALIZER_CONTROL;
        break;
      case DELAY_CONTROL:
      	*size = 2;
      	cmd = GET_MIN_DELAY_CONTROL;
        break;
      default:
    	break;    
   }
   if(cmd > 0)
   {
	  	error = USB_Class_Get_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Get_Max_Audio_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Get_Max_Audio_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{	
	uint_8 error;
	int_32 cmd = -1;
   if (size == NULL)				 
   {
   		return USBERR_ERROR;	
   }	
	error = USBERR_INVALID_REQ_TYPE;
	switch(setup_packet->value>>8)
	{
      case VOLUME_CONTROL:
      	*size = 2;
      	cmd = GET_MAX_VOLUME_CONTROL;
        break;
      case BASS_CONTROL:
      	*size = 1;
      	cmd = GET_MAX_BASS_CONTROL;
        break;
      case MID_CONTROL:
      	*size = 1;
      	cmd = GET_MAX_MID_CONTROL;
        break;
      case TREBLE_CONTROL:
      	*size = 1;
      	cmd = GET_MAX_TREBLE_CONTROL;
        break;
      case GRAPHIC_EQUALIZER_CONTROL:
      	*size = 5;
      	cmd = GET_MAX_GRAPHIC_EQUALIZER_CONTROL;
        break;
      case DELAY_CONTROL:
      	*size = 2;
      	cmd = GET_MAX_DELAY_CONTROL;
        break;
      default:
    	break;    
   }
   if(cmd > 0)
   {
	  	error = USB_Class_Get_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Get_Res_Audio_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Get_Res_Audio_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{	
	uint_8 error;
	int_32 cmd = -1;
	error = USBERR_INVALID_REQ_TYPE;
   if (size == NULL)				 
   {
   		return USBERR_ERROR;	
   }
	switch(setup_packet->value>>8)
	{
      case VOLUME_CONTROL:
      	*size = 2;
      	cmd = GET_RES_VOLUME_CONTROL;
        break;
      case BASS_CONTROL:
      	*size = 1;
      	cmd = GET_RES_BASS_CONTROL;
        break;
      case MID_CONTROL:
      	*size = 1;
      	cmd = GET_RES_MID_CONTROL;
        break;
      case TREBLE_CONTROL:
      	*size = 1;
      	cmd = GET_RES_TREBLE_CONTROL;
        break;
      case GRAPHIC_EQUALIZER_CONTROL:
      	*size = 5;
      	cmd = GET_RES_GRAPHIC_EQUALIZER_CONTROL;
        break;
      case DELAY_CONTROL:
      	*size = 2;
      	cmd = GET_RES_DELAY_CONTROL;
        break;
      default:
    	break;    
   }
   if(cmd > 0)
   {
	  	error = USB_Class_Get_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Audio_Get_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Audio_Get_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
   uint_8 error = USBERR_INVALID_REQ_TYPE;
    /* Select SET request Control Feature Unit Module */
   switch(setup_packet->request)
   {
     case GET_CUR:
       error = USB_Get_Cur_Audio_Feature_Unit(audio_obj_ptr,setup_packet,data,size);
       break;
     case GET_MIN:
       error = USB_Get_Min_Audio_Feature_Unit(audio_obj_ptr,setup_packet,data,size);
       break;
     case GET_MAX:
       error = USB_Get_Max_Audio_Feature_Unit(audio_obj_ptr,setup_packet,data,size);                         
       break;
     case GET_RES:
       error = USB_Get_Res_Audio_Feature_Unit(audio_obj_ptr,setup_packet,data,size);                         
       break;
     default:
       break;
   }
 return error;  
}

/**************************************************************************//*!
 *
 * @name  USB_Audio_Get_Control_Terminal
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Audio_Get_Control_Terminal
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    uint_8 error = USBERR_INVALID_REQ_TYPE;
    if (size == NULL)
    {
    	return USBERR_ERROR;	
    }
    switch(setup_packet -> request)
    {
      /* Copy Protect Control only supports the CUR attribute!*/
      case GET_CUR:
      	*size = 1;
        if((setup_packet->value >>8) == COPY_PROTECT_CONTROL )
        {
          error = USB_Class_Get_Desc(audio_obj_ptr->class_handle,GET_CUR_COPY_PROTECT_CONTROL,
          								audio_obj_ptr->current_interface,data);
        }
        break;
      default:
        break;
    }
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Get_Request_Interface
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Get_Request_Interface
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
  int i;
  uint_8 error = USBERR_INVALID_REQ_TYPE;
  USB_AUDIO_UNITS *entity_desc_data;
  USB_UT_STRUCT_PTR ut_struct;
  /* get the I/O Interface and Feature from the descriptor module */
  entity_desc_data = audio_obj_ptr->usb_ut_data;
  for(i=0;i<entity_desc_data->count; i++)
  {
    ut_struct=(&entity_desc_data->epp[i]);
    if((setup_packet->index >>8) == ut_struct->unit_id)
    {
      switch(ut_struct->type)
      {
        case AUDIO_CONTROL_INPUT_TERMINAL:
          error = USB_Audio_Get_Control_Terminal(audio_obj_ptr,setup_packet,data,size);
          break;
        case AUDIO_CONTROL_FEATURE_UNIT:
          error = USB_Audio_Get_Feature_Unit(audio_obj_ptr,setup_packet,data,size);
          break;
        default:
          break;
      }
    }
  }
  return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Set_Cur_Audio_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Set_Cur_Audio_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
   int cmd = -1;
   uint_8 error = USBERR_INVALID_REQ_TYPE;
   if (size == NULL)				 
   {
   		return USBERR_ERROR;	
   }
   *size = 0;
   switch(setup_packet->value>>8)
   {
      case MUTE_CONTROL:
      	cmd = SET_CUR_MUTE_CONTROL;
        break;
      case VOLUME_CONTROL:
      	cmd = SET_CUR_VOLUME_CONTROL;
        break;
      case BASS_CONTROL:
      	cmd = SET_CUR_BASS_CONTROL;
        break;
      case MID_CONTROL:
      	cmd = SET_CUR_MID_CONTROL;
        break;
      case TREBLE_CONTROL:
      	cmd = SET_CUR_TREBLE_CONTROL;
        break;
      case GRAPHIC_EQUALIZER_CONTROL:
      	cmd = SET_CUR_GRAPHIC_EQUALIZER_CONTROL;
        break;
      case AUTOMATIC_GAIN_CONTROL:
      	cmd = SET_CUR_AUTOMATIC_GAIN_CONTROL;
        break;
      case DELAY_CONTROL:
      	cmd = SET_CUR_DELAY_CONTROL;
        break;
      case BASS_BOOST_CONTROL:
      	cmd = SET_CUR_BASS_BOOST_CONTROL;
        break;
      case LOUDNESS_CONTROL:
      	cmd = SET_CUR_LOUDNESS_CONTROL;
        break;
      default:
    	break;    
   }
   if (cmd > 0)
   {
	  	error = USB_Class_Set_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Set_Min_Audio_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Set_Min_Audio_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
   uint_8 error = USBERR_INVALID_REQ_TYPE; 
   int cmd = -1;
   if (size == NULL)				 
   {
   		return USBERR_ERROR;	
   }
   *size = 0;
   switch(setup_packet->value>>8)
   {
      case VOLUME_CONTROL:
      	cmd = SET_MIN_VOLUME_CONTROL;
        break;
      case BASS_CONTROL:
      	cmd = SET_MIN_BASS_CONTROL;
        break;
      case MID_CONTROL:
      	cmd = SET_MIN_MID_CONTROL;
        break;
      case TREBLE_CONTROL:
      	cmd = SET_MIN_TREBLE_CONTROL;
        break;
      case GRAPHIC_EQUALIZER_CONTROL:
      	cmd = SET_MIN_GRAPHIC_EQUALIZER_CONTROL;
        break;
      case DELAY_CONTROL:
      	cmd = SET_MIN_DELAY_CONTROL;
        break;
      default:
    	break;    
   }
   if (cmd > 0)
   {
	  	error = USB_Class_Set_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Set_Max_Audio_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Set_Max_Audio_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
   int cmd = -1;
   uint_8 error = USBERR_INVALID_REQ_TYPE; 
   if (size == NULL)				 
   {
   		return USBERR_ERROR;	
   }
   *size = 0;
   switch(setup_packet->value>>8)
   {
      case VOLUME_CONTROL:
      	cmd = SET_MAX_VOLUME_CONTROL;
        break;
      case BASS_CONTROL:
      	cmd = SET_MAX_BASS_CONTROL;
        break;
      case MID_CONTROL:
      	cmd = SET_MAX_MID_CONTROL;
        break;
      case TREBLE_CONTROL:
      	cmd = SET_MAX_TREBLE_CONTROL;
        break;
      case GRAPHIC_EQUALIZER_CONTROL:
      	cmd = SET_MAX_GRAPHIC_EQUALIZER_CONTROL;
        break;
      case DELAY_CONTROL:
      	cmd = SET_MAX_DELAY_CONTROL;
        break;
      default:
    	break;    
   }
   if (cmd > 0)
   {
	  	error = USB_Class_Set_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Set_Res_Audio_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Set_Res_Audio_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
   int cmd = -1;
   uint_8 error = USBERR_INVALID_REQ_TYPE;
   if (size == NULL)				 
   {
   		return USBERR_ERROR;	
   } 
   *size = 0;
   switch(setup_packet->value>>8)
   {
      case VOLUME_CONTROL:
      	cmd = SET_RES_VOLUME_CONTROL;
        break;
      case BASS_CONTROL:
      	cmd = SET_RES_BASS_CONTROL;
        break;
      case MID_CONTROL:
      	cmd = SET_RES_MID_CONTROL;
        break;
      case TREBLE_CONTROL:
      	cmd = SET_RES_TREBLE_CONTROL;
        break;
      case GRAPHIC_EQUALIZER_CONTROL:
      	cmd = SET_RES_GRAPHIC_EQUALIZER_CONTROL;
        break;
      case DELAY_CONTROL:
      	cmd = SET_RES_DELAY_CONTROL;
        break;
      default:
    	break;    
   }
   if (cmd > 0)
   {
	  	error = USB_Class_Set_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
	return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Audio_Set_Feature_Unit
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Audio_Set_Feature_Unit
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
   uint_8 error = USBERR_INVALID_REQ_TYPE;
    /* Select SET request Control Feature Unit Module */
   switch(setup_packet->request)
   {
     case SET_CUR:
       error = USB_Set_Cur_Audio_Feature_Unit(audio_obj_ptr,setup_packet,data,size);
       break;
     case SET_MIN:
       error = USB_Set_Min_Audio_Feature_Unit(audio_obj_ptr,setup_packet,data,size);
       break;
     case SET_MAX:
       error = USB_Set_Max_Audio_Feature_Unit(audio_obj_ptr,setup_packet,data,size);                         
       break;
     case SET_RES:
       error = USB_Set_Res_Audio_Feature_Unit(audio_obj_ptr,setup_packet,data,size);                         
       break;
     default:
       break;
   }
 return error;  
}


/**************************************************************************//*!
 *
 * @name  USB_Audio_Set_Control_Terminal
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Audio_Set_Control_Terminal
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    uint_8 error = USBERR_INVALID_REQ_TYPE;
    if(size == NULL)
    {
    	return USBERR_ERROR;	
    }
    *size = 0;
    switch(setup_packet -> request)
    {
      /* Copy Protect Control only supports the CUR attribute!*/
      case SET_CUR:
        if((setup_packet->value >>8) == COPY_PROTECT_CONTROL )
        {
          error = USB_Class_Set_Desc(audio_obj_ptr->class_handle,SET_CUR_COPY_PROTECT_CONTROL,
          							  audio_obj_ptr->current_interface,data);
        }
        break;
      default:
        break;
    }
	return error;
}

/**************************************************************************//*!
 *
 * @name  USB_Set_Request_Interface
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Set_Request_Interface
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
  int i;
  uint_8 error = USBERR_INVALID_REQ_TYPE;
  USB_AUDIO_UNITS *entity_desc_data;
  USB_UT_STRUCT_PTR ut_struct;
  /* get the I/O Interface and Feature  from the descriptor module */
  entity_desc_data = audio_obj_ptr->usb_ut_data;
  for(i=0;i<entity_desc_data->count; i++)
  {
    ut_struct=(&entity_desc_data->epp[i]);
    if((setup_packet->index >>8) == ut_struct->unit_id)
    {
      switch(ut_struct->type)
      {
      	case AUDIO_CONTROL_OUTPUT_TERMINAL:
          /*Select SET Request Control Input Terminal Module */
          error = USB_Audio_Set_Control_Terminal(audio_obj_ptr,setup_packet,data,size);
          break;
        case AUDIO_CONTROL_FEATURE_UNIT:
          /* Select SET request Control Feature Unit Module */
          error = USB_Audio_Set_Feature_Unit(audio_obj_ptr,setup_packet,data,size);
          break;
        default:
          break;
      }
    }
  }
  return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Set_Request_Endpoint
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Set_Request_Endpoint
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    int cmd = -1;
    uint_8 error = USBERR_INVALID_REQ_TYPE;
   if (size == NULL)				 
   {
   		return USBERR_ERROR;	
   }
    *size = 0;
    switch(setup_packet->request)
    {
      case  SET_CUR:
        switch(setup_packet->value>>8)
        {
          case SAMPLING_FREQ_CONTROL:
          	cmd = SET_CUR_SAMPLING_FREQ_CONTROL;
            break;
          case PITCH_CONTROL:
          	cmd = SET_CUR_PITCH_CONTROL;
            break;
          default:
          	break;    
        }
      	break;
      case SET_MIN:
        switch(setup_packet->value>>8)
        {
          case SAMPLING_FREQ_CONTROL:
          	cmd = SET_MIN_SAMPLING_FREQ_CONTROL;
            break;
          default:
          	break;    
        }
      	break;
      case SET_MAX:
        switch(setup_packet->value>>8)
        {
          case SAMPLING_FREQ_CONTROL:
          	cmd = SET_MAX_SAMPLING_FREQ_CONTROL;
            break;
          default:
          	break;    
        }
      break;
      case SET_RES:
        switch(setup_packet->value>>8)
        {
          case SAMPLING_FREQ_CONTROL:
          	cmd = SET_RES_SAMPLING_FREQ_CONTROL;
            break;
          default:
          	break;    
        }
       break;
      case SET_MEM:
      	*size = setup_packet->length;
      	if (audio_obj_ptr->mem_param_callback.callback != NULL)
      	{
      		error = audio_obj_ptr->mem_param_callback.callback(
                                      /* request type */ 
                                      setup_packet->request,
                                      setup_packet->value, 
                                      /* pointer to the data */      
                                      data,
                                      /* size of the transfer */                                    
                                      size,audio_obj_ptr->mem_param_callback.arg);	
      	}
      break;
    default:
    	break;
    }
    if (cmd > 0)
    {
        error = USB_Class_Set_Desc(audio_obj_ptr->class_handle,cmd,
        							audio_obj_ptr->current_interface,data);
    }
	return error;    
}

/**************************************************************************//*!
 *
 * @name  USB_Get_Request_Endpoint
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param audio_obj_ptr:	Pointer to Audio class object.
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
static uint_8 USB_Get_Request_Endpoint
(
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr,
    USB_SETUP_STRUCT * setup_packet,
    uint_8_ptr *data, 
    uint_32 *size
)
{
    int cmd = -1;
    uint_8 error = USBERR_INVALID_REQ_TYPE;
    if (size == NULL)				 
    {
   		return USBERR_ERROR;	
    }
    switch(setup_packet->request)
    {
      case  GET_CUR:
        switch(setup_packet->value>>8)
        {
          case SAMPLING_FREQ_CONTROL:
          	*size = 3;
          	cmd = GET_CUR_SAMPLING_FREQ_CONTROL;
            break;
          case PITCH_CONTROL:
          	*size = 1;
          	cmd = GET_CUR_PITCH_CONTROL;
            break;
          default:
          	break;    
        }
      break;
      case GET_MIN:
        switch(setup_packet->value>>8)
        {
          case SAMPLING_FREQ_CONTROL:
          	*size = 3;
          	cmd = GET_MIN_SAMPLING_FREQ_CONTROL;
            break;
          default:
          	break;    
        }
      break;
      case GET_MAX:
        switch(setup_packet->value>>8)
        {
          case SAMPLING_FREQ_CONTROL:
          	*size = 3;
          	cmd = GET_MAX_SAMPLING_FREQ_CONTROL;
            break;
          default:
          	break;    
        }
      break;
      case GET_RES:
        switch(setup_packet->value>>8)
        {
          case SAMPLING_FREQ_CONTROL:
          	cmd = GET_RES_SAMPLING_FREQ_CONTROL;
          	*size = 3;
            break;
          default:
          	break;    
        }
       break;
      case GET_MEM:
      	*size = setup_packet->length;
      	if (audio_obj_ptr->mem_param_callback.callback != NULL)
      	{
      		error = audio_obj_ptr->mem_param_callback.callback(
                                      /* request type */ 
                                      setup_packet->request,
                                      setup_packet->value, 
                                      /* pointer to the data */      
                                      data,
                                      /* size of the transfer */                                    
                                      size,audio_obj_ptr->mem_param_callback.arg);	
      	}
	   break;
      default:
   	   break;
    }
   if (cmd > 0)
   {
	  	error = USB_Class_Get_Desc(audio_obj_ptr->class_handle,cmd,
	  								audio_obj_ptr->current_interface,data);
   }
   return error;    
}
/**************************************************************************//*!
 *
 * @name  USB_Audio_Other_Requests
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param handle
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return error:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Audio_Other_Requests
(
	USB_SETUP_STRUCT * setup_packet, 
	uint_8_ptr *data, 
	uint_32 *size,
	pointer arg
) 
{
    uint_8 error;
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr = (AUDIO_DEVICE_STRUCT_PTR)arg;
    error = USBERR_INVALID_REQ_TYPE;
    *data = ((uint_8*)setup_packet)+USB_SETUP_PKT_SIZE;
    
    if (audio_obj_ptr == NULL)
    {
        #ifdef _DEV_DEBUG
            printf("USB_Audio_Other_Requests:audio_obj_ptr is NULL\n");
        #endif  
        return error;
    }
    
    if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
        USB_REQUEST_CLASS_CLASS) 
    {  /* class request so handle it here */
    	audio_obj_ptr->current_interface = (uint_8)setup_packet->index;
    	switch(setup_packet->request_type)     
    	{
           /* Set I/O Interface and Feature Unit */
           case SET_REQUEST_ITF:
             error = USB_Set_Request_Interface(audio_obj_ptr,setup_packet,data,size);
             break; 
           /*Get I/O Interface and Feature Unit */ 
           case GET_REQUEST_ITF:
             error = USB_Get_Request_Interface(audio_obj_ptr,setup_packet,data,size);
             break;
           /* Set Requests of Endpoint */
           case SET_REQUEST_EP:
             error = USB_Set_Request_Endpoint(audio_obj_ptr,setup_packet,data,size);
             break;
           /* Get Requests of Endpoint */
           case GET_REQUEST_EP:
             error = USB_Get_Request_Endpoint(audio_obj_ptr,setup_packet,data,size);
             break;
           default:
             *size = 0;
             break;	
    	} /* End of switch */
    }
    else if ((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
        USB_REQUEST_CLASS_VENDOR)
    {   /* vendor specific request  */    
        if(audio_obj_ptr->vendor_req_callback.callback != NULL) 
        {
            error = audio_obj_ptr->vendor_req_callback.callback(setup_packet,
            data,size,audio_obj_ptr->vendor_req_callback.arg);
        }
    }
    return error;
}

/*****************************************************************************
 * Global Functions
 *****************************************************************************/


/**************************************************************************//*!
 *
 * @name  USB_Class_Audio_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param *audio_config_ptr[IN]:  This structure contains configuration parameter
 *                              send by APP to configure audio class.
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the Audio Class layer and layers it is dependednt on 
 *
 *****************************************************************************/
uint_32 USB_Class_Audio_Init
(
   AUDIO_CONFIG_STRUCT_PTR audio_config_ptr                               
) 
{
    uint_8 index;
    uint_8 error;
    AUDIO_HANDLE           audioHandle;
    AUDIO_DEVICE_STRUCT_PTR  devicePtr = NULL;
    USB_ENDPOINTS *usb_ep_data;
    USB_AUDIO_UNITS *usb_ut_data;
    
    if (NULL == audio_config_ptr)
    {
    	return USBERR_ERROR;	
    }
    
    
    devicePtr = (AUDIO_DEVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(AUDIO_DEVICE_STRUCT));
    if (NULL == devicePtr)
    {
    	#ifdef _DEV_DEBUG
    		printf("USB_Class_Audio_Init: Memalloc failed\n");
    	#endif	
    	return USBERR_ALLOC;
    }

    audioHandle = USB_Audio_Get_Free_Handle();
    if (USBERR_DEVICE_BUSY == audioHandle) 
    {
        USB_mem_free(devicePtr);
        devicePtr = NULL;
     	return USBERR_INIT_FAILED;
    }

    devicePtr->ep = audio_config_ptr->ep;
    usb_ep_data = audio_config_ptr->usb_ep_data;
    usb_ut_data = audio_config_ptr->usb_ut_data;
        
 	/* Initialize the device layer*/
    error = _usb_device_init(USBCFG_DEFAULT_DEVICE_CONTROLLER, &devicePtr->controller_handle, usb_ep_data->count + 1);
    if(error != USB_OK)
    {
	     USB_Audio_Free_Handle(audioHandle);
	     USB_mem_free(devicePtr);
	     devicePtr = NULL;
	  	 return error;
    }

   audio_config_ptr->desc_callback_ptr->handle = audioHandle;
   /* Initialize the generic class functions */
   devicePtr->class_handle = USB_Class_Init(devicePtr->controller_handle,
    USB_Class_Audio_Event,USB_Audio_Other_Requests,(void *)devicePtr,
    audio_config_ptr->desc_callback_ptr);
   if(error != USB_OK)
   {
		USB_Audio_Free_Handle(audioHandle);
		USB_mem_free(devicePtr);
		devicePtr = NULL;
		return error;
   }
	                                                    
   devicePtr->usb_ep_data =  usb_ep_data;
   devicePtr->usb_ut_data =  usb_ut_data;
   	    
   for(index = 0; index < usb_ep_data->count; index++)
   {            
      devicePtr->ep[index].endpoint = usb_ep_data->ep[index].ep_num;
      devicePtr->ep[index].type = usb_ep_data->ep[index].type;
      devicePtr->ep[index].bin_consumer = 0x00;
      devicePtr->ep[index].bin_producer = 0x00;
      devicePtr->ep[index].queue_num = 0x00;
    }
	
	audio_config_ptr->desc_callback_ptr->handle = audioHandle;
	if (NULL == audio_config_ptr->desc_callback_ptr)
	{
		USB_Audio_Free_Handle(audioHandle);
		USB_mem_free(devicePtr);
		devicePtr = NULL;
		return error;
   }
	    
    /* save the callback pointer */
    devicePtr->audio_class_callback.callback = audio_config_ptr->audio_class_callback.callback;
    devicePtr->audio_class_callback.arg = audio_config_ptr->audio_class_callback.arg;         
    /* save the callback pointer */
    devicePtr->mem_param_callback.callback = audio_config_ptr->mem_param_callback.callback;
    devicePtr->mem_param_callback.arg = audio_config_ptr->mem_param_callback.arg;         
    /* save the callback pointer */
    devicePtr->vendor_req_callback.callback = audio_config_ptr->vendor_req_callback.callback;
    devicePtr->vendor_req_callback.arg = audio_config_ptr->vendor_req_callback.arg; 
    /* save the callback pointer */
    devicePtr->param_callback.callback = audio_config_ptr->param_callback.callback;
    devicePtr->param_callback.arg = audio_config_ptr->param_callback.arg; 	       	        
    
    devicePtr->audio_handle = audioHandle;
  
    device_array[audioHandle] = devicePtr;
  
  return audioHandle;
}

/**************************************************************************//*!
 *
 * @name  USB_Class_Audio_Send_Data
 *
 * @brief 
 *
 * @param handle          :   handle returned by USB_Class_HID_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
uint_8 USB_Class_Audio_Send_Data(
                                AUDIO_HANDLE handle,/*[IN]*/
                                uint_8 ep_num,/*[IN]*/
                                uint_8_ptr app_buff,/*[IN]*/
                                uint_32 size /*[IN]*/
                               ) 
{
#if IMPLEMENT_QUEUING
    uint_8 index;
    uint_8 producer, consumer,queue_num;
    USB_ENDPOINTS *ep_desc_data;
#endif
    
    uint_8 error = USB_OK;
    AUDIO_DEVICE_STRUCT_PTR  devicePtr;
    PTR_USB_CLASS_AUDIO_QUEUE queue_tmp;  
    
    /* get device ptr */
    if (handle > MAX_AUDIO_DEVICE)
    {
    	return USBERR_NO_DEVICE_CLASS;
    }
    else 
    {
    	devicePtr = device_array[handle];	
    }
#if IMPLEMENT_QUEUING
    ep_desc_data = devicePtr->usb_ep_data; 
    
    /* map the endpoint num to the index of the endpoint structure */
    for(index = 0; index < ep_desc_data->count; index++) 
    {
        if(ep_desc_data->ep[index].ep_num == ep_num)
            break;
    }
   
    producer = devicePtr->ep[index].bin_producer;
    consumer = devicePtr->ep[index].bin_consumer;
    queue_num = devicePtr->ep[index].queue_num;

    if(queue_num != AUDIO_MAX_QUEUE_ELEMS)
    {/* the bin is not full*/
        /* put all send request parameters in the endpoint data structure */
        queue_tmp = &(devicePtr->ep[index].queue[producer]);
        queue_tmp->channel = ep_num;
        queue_tmp->app_data.data_ptr = app_buff;
        queue_tmp->app_data.data_size = size; 
        queue_tmp->handle = devicePtr->controller_handle;
   
        /* increment producer bin by 1*/
        if (producer == (AUDIO_MAX_QUEUE_ELEMS -1))
        {
        	devicePtr->ep[index].bin_producer = 0;	
        }
        else
        {
        	devicePtr->ep[index].bin_producer++;
        }
        devicePtr->ep[index].queue_num++;
             
        if(devicePtr->ep[index].queue_num == 1)         
        { 
#endif  
        	/*send the IO if there is only one element in the queue */          
            error = USB_Class_Send_Data(devicePtr->class_handle, ep_num, app_buff,size);
#if IMPLEMENT_QUEUING
        }        
    }
    else /* bin is full */
    {
        error = USBERR_DEVICE_BUSY; 
    }
#endif
    
    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_Class_Audio_Recv_Data
 *
 * @brief This functions receives Data from Host.
 *
 * @param handle          :   handle returned by USB_Class_Audio_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK         : When Successfull 
 *         Others         : Errors
 *****************************************************************************/
uint_8 USB_Class_Audio_Recv_Data
(
    AUDIO_HANDLE          audio_handle,
    uint_8              ep_num,
    uint_8_ptr          buff_ptr,      /* [IN] buffer to recv */      
    uint_32             size           /* [IN] length of the transfer */
)
{
    AUDIO_DEVICE_STRUCT_PTR audio_obj_ptr;
    uint_8 error = USB_OK;

    if (audio_handle > MAX_AUDIO_DEVICE)
    {
    	return USBERR_ERROR;
    }
    else 
    {
    	audio_obj_ptr = device_array[audio_handle];	
    }
   
    error = _usb_device_recv_data(audio_obj_ptr->controller_handle,
    ep_num,buff_ptr,size);
    
    return error;
	
}

#endif /*AUDIO_CONFIG*/
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_ftfl_prv.h<|end_filename|>
/**HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* $FileName: flash_ftfl_prv.h$
* $Version : 3.8.5.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*   The file contains function prototypes and defines for the internal 
*   flash driver.
*
*END*************************************************************************/

#ifndef __flash_ftfl_prv_h__
    #define __flash_ftfl_prv_h__


#include "flashx.h"

/*--------------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/* FTFL commands */
#define FTFL_VERIFY_BLOCK              0x00
#define FTFL_VERIFY_SECTION            0x01
#define FTFL_PROGRAM_CHECK             0x02
#define FTFL_READ_RESOURCE             0x03
#define FTFL_PROGRAM_LONGWORD          0x06
#define FTFL_PROGRAM_PHRASE            0x07
#define FTFL_ERASE_BLOCK               0x08
#define FTFL_ERASE_SECTOR              0x09
#define FTFL_PROGRAM_SECTION           0x0B
#define FTFL_VERIFY_ALL_BLOCK          0x40
#define FTFL_READ_ONCE                 0x41
#define FTFL_PROGRAM_ONCE              0x43
#define FTFL_ERASE_ALL_BLOCK           0x44
#define FTFL_SECURITY_BY_PASS          0x45
#define FTFL_PROGRAM_PARTITION         0x80
#define FTFL_SET_EERAM                 0x81

/* FTFL margin read settings */
#define FTFL_MARGIN_NORMAL             0x0000
#define FTFL_USER_MARGIN_LEVEL1        0x0001
#define FTFL_USER_MARGIN_LEVEL0        0x0002
#define FTFL_FACTORY_MARGIN_LEVEL0     0x0003
#define FTFL_FACTORY_MARGIN_LEVEL1     0x0004

/* FTFL sizes */
#define FTFL_WORD_SIZE                 0x0002
#define FTFL_LONGWORD_SIZE             0x0004

/* FTFL error codes */
#define FTFL_OK                        0x0000
#define FTFL_ERR_SIZE                  0x0001
#define FTFL_ERR_RANGE                 0x0002
#define FTFL_ERR_ACCERR                0x0004
#define FTFL_ERR_PVIOL                 0x0008
#define FTFL_ERR_MGSTAT0               0x0010
#define FTFL_ERR_CHANGEPROT            0x0020
#define FTFL_ERR_EEESIZE               0x0040
#define FTFL_ERR_EFLASHSIZE            0x0080
#define FTFL_ERR_ADDR                  0x0100
#define FTFL_ERR_NOEEE                 0x0200
#define FTFL_ERR_EFLASHONLY            0x0400
#define FTFL_ERR_DFLASHONLY            0x0800
#define FTFL_ERR_RDCOLERR              0x1000
#define FTFL_ERR_RAMRDY                0x2000

/* Start and End Address of PFlash IFR and DFlash IFR */
#define PFLASH_IFR_START_ADDRESS       0x000000
#define PFLASH_IFR_END_ADDRESS         0x0000FF
#define DFLASH_IFR_START_ADDRESS       0x800000
#define DFLASH_IFR_END_ADDRESS         0x8000FF
#define DFLASH_IFR_LONGWORD_ADDRESS    0x8000FC

#define FLASHX_INVALIDATE_CACHE_ALL    0xFFFFFFFF
#define FLASHX_INVALIDATE_CACHE_BLOCK0 0x00000001
#define FLASHX_INVALIDATE_CACHE_BLOCK1 0x00000002
#define FLASHX_INVALIDATE_CACHE_BLOCK2 0x00000004
#define FLASHX_INVALIDATE_CACHE_BLOCK3 0x00000008

/* FlexNVM partition code bit mask */
#define FLEXNVM_PART_CODE_MASK              (0x0f)

/* FlexNVM split bit mask */
#define FLEXNVM_EE_SPLIT_MASK               (0x30)

/* FlexNVM EEPROM size bit mask */
#define FLEXNVM_EE_SIZE_MASK                (0x0f)

/*--------------------------------------------------------------------------*/
/*
**                    Structure Definitions
*/

typedef struct ftfl_flash_internal_struct 
{
    vchar_ptr  ftfl_ptr;
    char_ptr   flash_execute_code_ptr;
        
} FTFL_FLASH_INTERNAL_STRUCT, _PTR_ FTFL_FLASH_INTERNAL_STRUCT_PTR;

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

boolean  ftfl_flash_init(IO_FLASHX_STRUCT_PTR);
void     ftfl_flash_deinit(IO_FLASHX_STRUCT_PTR);
boolean  ftfl_flash_erase_sector(IO_FLASHX_STRUCT_PTR, char_ptr, _mem_size);
boolean  ftfl_flash_write_sector(IO_FLASHX_STRUCT_PTR, char_ptr, char_ptr, _mem_size);
_mqx_int flexnvm_flash_ioctl(IO_FLASHX_STRUCT_PTR, _mqx_uint, pointer);

#ifdef __cplusplus
}
#endif

#endif /* __flash_ftfl_prv_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/Cpu.h<|end_filename|>
/* ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : Cpu.h
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : MK60FN1M0LQ15
**     Version     : Component 01.005, Driver 01.04, CPU db: 3.00.000
**     Datasheet   : K60P144M150SF3RM, Rev. 2, Dec 2011
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-09, 08:31, # CodeGen: 4
**     Abstract    :
**
**     Settings    :
**
**     Contents    :
**         SetClockConfiguration - LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID);
**         GetClockConfiguration - uint8_t Cpu_GetClockConfiguration(void);
**         SetOperationMode      - LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode,...
**         EnableInt             - void Cpu_EnableInt(void);
**         DisableInt            - void Cpu_DisableInt(void);
**         GetLLSWakeUpFlags     - uint32_t Cpu_GetLLSWakeUpFlags(void);
**         MCGAutoTrim           - LDD_TError Cpu_MCGAutoTrim(uint8_t ClockSelect);
**
**     (c) Freescale Semiconductor, Inc.
**     2004 All Rights Reserved
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file Cpu.h
** @version 01.04
** @brief
**
*/         
/*!
**  @addtogroup Cpu_module Cpu module documentation
**  @{
*/         

#ifndef __Cpu_H
#define __Cpu_H

/* MODULE Cpu. */
/*Include shared modules, which are used for whole project*/
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"

#ifdef __cplusplus
extern "C" {
#endif 

/* Active configuration define symbol */
#define PEcfg_RAM 1U

/* Methods configuration constants - generated for all enabled component's methods */
#define Cpu_SetClockConfiguration_METHOD_ENABLED
#define Cpu_GetClockConfiguration_METHOD_ENABLED
#define Cpu_SetOperationMode_METHOD_ENABLED
#define Cpu_EnableInt_METHOD_ENABLED
#define Cpu_DisableInt_METHOD_ENABLED
#define Cpu_GetLLSWakeUpFlags_METHOD_ENABLED
#define Cpu_MCGAutoTrim_METHOD_ENABLED

/* Events configuration constants - generated for all enabled component's events */
#define Cpu_OnLLSWakeUpINT_EVENT_ENABLED

#define CPU_BUS_CLK_HZ                  60000000U /* Initial value of the bus clock frequency in Hz */
#define CPU_CORE_CLK_HZ                 120000000U /* Initial value of the core/system clock frequency in Hz.  */

#define CPU_CLOCK_CONFIG_NUMBER         0x03U /* Specifies number of defined clock configurations. */

#define CPU_BUS_CLK_HZ_CLOCK_CONFIG0    60000000U /* Value of the bus clock frequency in the clock configuration 0 in Hz. */
#define CPU_CORE_CLK_HZ_CLOCK_CONFIG0   120000000U /* Value of the core/system clock frequency in the clock configuration 0 in Hz. */

#define CPU_BUS_CLK_HZ_CLOCK_CONFIG1    12000000U /* Value of the bus clock frequency in the clock configuration 1 in Hz. */
#define CPU_CORE_CLK_HZ_CLOCK_CONFIG1   12000000U /* Value of the core/system clock frequency in the clock configuration 1 in Hz. */

#define CPU_BUS_CLK_HZ_CLOCK_CONFIG2    2000000U /* Value of the bus clock frequency in the clock configuration 2 in Hz. */
#define CPU_CORE_CLK_HZ_CLOCK_CONFIG2   2000000U /* Value of the core/system clock frequency in the clock configuration 2 in Hz. */


#define CPU_XTAL_CLK_HZ                 8000000U /* Value of the external crystal or oscillator clock frequency in Hz */
#define CPU_XTAL32k_CLK_HZ              32768U /* Value of the external 32k crystal or oscillator clock frequency in Hz */
#define CPU_INT_SLOW_CLK_HZ             32768U /* Value of the slow internal oscillator clock frequency in Hz  */
#define CPU_INT_FAST_CLK_HZ             4000000U /* Value of the fast internal oscillator clock frequency in Hz  */

#define CPU_FAMILY_Kinetis             /* Specification of the core type of the selected cpu */
#define CPU_DERIVATIVE_MK60FN1M0LQ15   /* Name of the selected cpu derivative */
#define CPU_PARTNUM_MK60FN1M0VLQ12     /* Part number of the selected cpu */
#define CPU_LITTLE_ENDIAN              /* The selected cpu uses little endian */

/* CPU frequencies in clock configuration 0 */
#define CPU_CLOCK_CONFIG_0              0x00U /* Clock configuration 0 identifier */
#define CPU_CORE_CLK_HZ_CONFIG_0        120000000UL /* Core clock frequency in clock configuration 0 */
#define CPU_BUS_CLK_HZ_CONFIG_0         60000000UL /* Bus clock frequency in clock configuration 0 */
#define CPU_FLEXBUS_CLK_HZ_CONFIG_0     40000000UL /* Flexbus clock frequency in clock configuration 0 */
#define CPU_FLASH_CLK_HZ_CONFIG_0       20000000UL /* FLASH clock frequency in clock configuration 0 */
#define CPU_USB_CLK_HZ_CONFIG_0         0UL /* USB clock frequency in clock configuration 0 */
#define CPU_PLL_FLL_CLK_HZ_CONFIG_0     120000000UL /* PLL/FLL clock frequency in clock configuration 0 */
#define CPU_MCGIR_CLK_HZ_CONFIG_0       2000000UL /* MCG internal reference clock frequency in clock configuration 0 */
#define CPU_OSCER_CLK_HZ_CONFIG_0       8000000UL /* System OSC external reference clock frequency in clock configuration 0 */
#define CPU_ERCLK32K_CLK_HZ_CONFIG_0    32768UL /* External reference clock 32k frequency in clock configuration 0 */
#define CPU_MCGFF_CLK_HZ_CONFIG_0       15625UL /* MCG fixed frequency clock */

/* CPU frequencies in clock configuration 1 */
#define CPU_CLOCK_CONFIG_1              0x01U /* Clock configuration 1 identifier */
#define CPU_CORE_CLK_HZ_CONFIG_1        12000000UL /* Core clock frequency in clock configuration 1 */
#define CPU_BUS_CLK_HZ_CONFIG_1         12000000UL /* Bus clock frequency in clock configuration 1 */
#define CPU_FLEXBUS_CLK_HZ_CONFIG_1     12000000UL /* Flexbus clock frequency in clock configuration 1 */
#define CPU_FLASH_CLK_HZ_CONFIG_1       12000000UL /* FLASH clock frequency in clock configuration 1 */
#define CPU_USB_CLK_HZ_CONFIG_1         0UL /* USB clock frequency in clock configuration 1 */
#define CPU_PLL_FLL_CLK_HZ_CONFIG_1     120000000UL /* PLL/FLL clock frequency in clock configuration 1 */
#define CPU_MCGIR_CLK_HZ_CONFIG_1       2000000UL /* MCG internal reference clock frequency in clock configuration 1 */
#define CPU_OSCER_CLK_HZ_CONFIG_1       8000000UL /* System OSC external reference clock frequency in clock configuration 1 */
#define CPU_ERCLK32K_CLK_HZ_CONFIG_1    32768UL /* External reference clock 32k frequency in clock configuration 1 */
#define CPU_MCGFF_CLK_HZ_CONFIG_1       15625UL /* MCG fixed frequency clock */

/* CPU frequencies in clock configuration 2 */
#define CPU_CLOCK_CONFIG_2              0x02U /* Clock configuration 2 identifier */
#define CPU_CORE_CLK_HZ_CONFIG_2        2000000UL /* Core clock frequency in clock configuration 2 */
#define CPU_BUS_CLK_HZ_CONFIG_2         2000000UL /* Bus clock frequency in clock configuration 2 */
#define CPU_FLEXBUS_CLK_HZ_CONFIG_2     2000000UL /* Flexbus clock frequency in clock configuration 2 */
#define CPU_FLASH_CLK_HZ_CONFIG_2       500000UL /* FLASH clock frequency in clock configuration 2 */
#define CPU_USB_CLK_HZ_CONFIG_2         0UL /* USB clock frequency in clock configuration 2 */
#define CPU_PLL_FLL_CLK_HZ_CONFIG_2     2000000UL /* PLL/FLL clock frequency in clock configuration 2 */
#define CPU_MCGIR_CLK_HZ_CONFIG_2       2000000UL /* MCG internal reference clock frequency in clock configuration 2 */
#define CPU_OSCER_CLK_HZ_CONFIG_2       8000000UL /* System OSC external reference clock frequency in clock configuration 2 */
#define CPU_ERCLK32K_CLK_HZ_CONFIG_2    0UL /* External reference clock 32k frequency in clock configuration 2 */
#define CPU_MCGFF_CLK_HZ_CONFIG_2       16384UL /* MCG fixed frequency clock */


typedef struct  {
  uint32_t cpu_core_clk_hz;            /* Core clock frequency in clock configuration */
  uint32_t cpu_bus_clk_hz;             /* Bus clock frequency in clock configuration */
  uint32_t cpu_flexbus_clk_hz;         /* Flexbus clock frequency in clock configuration */
  uint32_t cpu_flash_clk_hz;           /* FLASH clock frequency in clock configuration */
  uint32_t cpu_usb_clk_hz;             /* USB clock frequency in clock configuration */
  uint32_t cpu_pll_fll_clk_hz;         /* PLL/FLL clock frequency in clock configuration */
  uint32_t cpu_mcgir_clk_hz;           /* MCG internal reference clock frequency in clock configuration */
  uint32_t cpu_oscer_clk_hz;           /* System OSC external reference clock frequency in clock configuration */
  uint32_t cpu_erclk32k_clk_hz;        /* External reference clock 32k frequency in clock configuration */
  uint32_t cpu_mcgff_clk_hz;           /* MCG fixed frequency clock */
} TCpuClockConfiguration;

/* The array of clock frequencies in configured clock configurations */
extern const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER];

/* Constants defined for use with GetLLSWakeUpFlags method */
#define LLWU_EXT_PIN0                  0x01U /* WakeUp caused by - External pin 0 (ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/SDHC0_D0/I2C1_SCL/SPI1_SIN) */
#define LLWU_EXT_PIN1                  0x02U /* WakeUp caused by - External pin 1 (ADC1_SE6a/PTE2/LLWU_P1/SPI1_SCK/UART1_CTS_b/SDHC0_DCLK) */
#define LLWU_EXT_PIN2                  0x04U /* WakeUp caused by - External pin 2 (PTE4/LLWU_P2/SPI1_PCS0/UART3_TX/SDHC0_D3) */
#define LLWU_EXT_PIN3                  0x08U /* WakeUp caused by - External pin 3 (TSI0_CH5/PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b) */
#define LLWU_EXT_PIN4                  0x10U /* WakeUp caused by - External pin 4 (CMP2_IN1/PTA13/LLWU_P4/CAN0_RX/FTM1_CH1/RMII0_RXD0/MII0_RXD0/I2S0_TX_FS/FTM1_QD_PHB) */
#define LLWU_EXT_PIN5                  0x20U /* WakeUp caused by - External pin 5 (ADC0_SE8/ADC1_SE8/ADC2_SE8/ADC3_SE8/TSI0_CH0/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/RMII0_MDIO/MII0_MDIO/FTM1_QD_PHA) */
#define LLWU_EXT_PIN6                  0x40U /* WakeUp caused by - External pin 6 (ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/FBa_AD13/NFC_DATA10/I2S0_TXD0) */
#define LLWU_EXT_PIN7                  0x80U /* WakeUp caused by - External pin 7 (CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUTa/I2S0_TX_BCLK) */
#define LLWU_EXT_PIN8                  0x0100U /* WakeUp caused by - External pin 8 (PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/NFC_DATA8/CMP1_OUT/I2S1_TX_BCLK) */
#define LLWU_EXT_PIN9                  0x0200U /* WakeUp caused by - External pin 9 (PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FBa_AD10/NFC_DATA7/CMP0_OUT/I2S1_TX_FS) */
#define LLWU_EXT_PIN10                 0x0400U /* WakeUp caused by - External pin 10 (CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FBa_AD9/NFC_DATA6/I2S0_MCLK) */
#define LLWU_EXT_PIN11                 0x0800U /* WakeUp caused by - External pin 11 (ADC1_SE7b/PTC11/LLWU_P11/I2C1_SDA/FTM3_CH7/I2S0_RXD1/FBa_RW_b/NFC_WE) */
#define LLWU_EXT_PIN12                 0x1000U /* WakeUp caused by - External pin 12 (PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b/FTM3_CH0/FBa_ALE/FBa_CS1_b/FBa_TS_b/I2S1_RXD1) */
#define LLWU_EXT_PIN13                 0x2000U /* WakeUp caused by - External pin 13 (PTD2/LLWU_P13/SPI0_SOUT/UART2_RX/FTM3_CH2/FBa_AD4/I2S1_RX_FS) */
#define LLWU_EXT_PIN14                 0x4000U /* WakeUp caused by - External pin 14 (PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/FBa_AD2/NFC_DATA1/EWM_IN) */
#define LLWU_EXT_PIN15                 0x8000U /* WakeUp caused by - External pin 15 (ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FBa_AD0/FTM0_FLT0) */
#define LLWU_INT_MODULE0               0x00010000U /* WakeUp caused by - Internal module 0 (LPTMR0) */
#define LLWU_INT_MODULE1               0x00020000U /* WakeUp caused by - Internal module 1 (CMP0) */
#define LLWU_INT_MODULE2               0x00040000U /* WakeUp caused by - Internal module 2 (CMP1) */
#define LLWU_INT_MODULE3               0x00080000U /* WakeUp caused by - Internal module 3 (CMP2/CMP3) */
#define LLWU_INT_MODULE4               0x00100000U /* WakeUp caused by - Internal module 4 (TSI0) */
#define LLWU_INT_MODULE5               0x00200000U /* WakeUp caused by - Internal module 5 (RTC) */
#define LLWU_INT_MODULE7               0x00800000U /* WakeUp caused by - Internal module 7 (RTC_Seconds) */
#define LLWU_FILTER1                   0x01000000U /* WakeUp caused by digital filter 1 */
#define LLWU_FILTER2                   0x02000000U /* WakeUp caused by digital filter 2 */

/* Global variables */
/*lint -esym(765,SR_reg) Disable MISRA rule (8.10) checking for symbols (SR_reg). The SR_reg is used in inline assembler. */
extern volatile uint8_t SR_reg;        /* Current FAULTMASK register */
/*lint -esym(765,SR_lock) Disable MISRA rule (8.10) checking for symbols (SR_lock). The SR_reg is used in inline assembler. */
extern volatile uint8_t SR_lock;

/*
** ===================================================================
**     Method      :  Cpu_MCGAutoTrim (component MK60FN1M0LQ15)
**     Description :
**         This method uses MCG auto trim feature to trim internal
**         reference clock. This method can be used only in a clock
**         configuration which derives its bus clock from external
**         reference clock (<MCG mode> must be one of the following
**         modes - FEE, FBE, BLPE, PEE, PBE) and if value of <Bus clock>
**         is in the range <8; 16>MHz.
**         The slow internal reference clock is trimmed to the value
**         selected by <Slow internal reference clock [kHz]> property. 
**         The fast internal reference clock will be trimmed to value
**         4MHz.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ClockSelect     - Selects which internal
**                           reference clock will be trimmed.
**                           0 ... slow (32kHz) internal reference clock
**                           will be trimmed
**                           > 0 ... fast (4MHz) internal reference
**                           clock will be trimmed
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_SPEED - The method does not work in the
**                           active clock configuration.
**                           ERR_FAILED - Autotrim process failed.
** ===================================================================
*/
LDD_TError Cpu_MCGAutoTrim(uint8_t ClockSelect);

/*
** ===================================================================
**     Method      :  Cpu_GetLLSWakeUpFlags (component MK60FN1M0LQ15)
**     Description :
**         This method returns the current status of the LLWU wake-up
**         flags indicating which wake-up source caused the MCU to exit
**         LLS or VLLSx low power mode.
**         The following predefined constants can be used to determine
**         the wake-up source:
**         LLWU_EXT_PIN0, ... LLWU_EXT_PIN15 - external pin 0 .. 15
**         caused the wake-up
**         LLWU_INT_MODULE0 .. LLWU_INT_MODULE7 - internal module 0..15
**         caused the wake-up.
**     Parameters  : None
**     Returns     :
**         ---             - Returns the current status of the LLWU
**                           wake-up flags indicating which wake-up
**                           source caused the MCU to exit LLS or VLLSx
**                           low power mode.
** ===================================================================
*/
uint32_t Cpu_GetLLSWakeUpFlags(void);

/*
** ===================================================================
**     Method      :  Cpu_SetClockConfiguration (component MK60FN1M0LQ15)
**     Description :
**         Calling of this method will cause the clock configuration
**         change and reconfiguration of all components according to
**         the requested clock configuration setting.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ModeID          - Clock configuration identifier
**     Returns     :
**         ---             - ERR_OK - OK.
**                           ERR_RANGE - Mode parameter out of range
** ===================================================================
*/
LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID);

/*
** ===================================================================
**     Method      :  Cpu_GetClockConfiguration (component MK60FN1M0LQ15)
**     Description :
**         Returns the active clock configuration identifier. The
**         method is enabled only if more than one clock configuration
**         is enabled in the component.
**     Parameters  : None
**     Returns     :
**         ---             - Active clock configuration identifier
** ===================================================================
*/
uint8_t Cpu_GetClockConfiguration(void);

/*
** ===================================================================
**     Method      :  Cpu_SetOperationMode (component MK60FN1M0LQ15)
**     Description :
**         This method requests to change the component's operation
**         mode (RUN, WAIT, SLEEP, STOP). The target operation mode
**         will be entered immediately. 
**         See <Operation mode settings> for further details of the
**         operation modes mapping to low power modes of the cpu.
**     Parameters  :
**         NAME            - DESCRIPTION
**         OperationMode   - Requested driver
**                           operation mode
**         ModeChangeCallback - Callback to
**                           notify the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**       * ModeChangeCallbackParamPtr 
**                           - Pointer to callback parameter to notify
**                           the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_PARAM_MODE - Invalid operation mode
** ===================================================================
*/
LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr);

/*
** ===================================================================
**     Method      :  Cpu_EnableInt (component MK60FN1M0LQ15)
**     Description :
**         Enables all maskable interrupts.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_EnableInt(void);

/*
** ===================================================================
**     Method      :  Cpu_DisableInt (component MK60FN1M0LQ15)
**     Description :
**         Disables all maskable interrupts.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_DisableInt(void);

/*
** ===================================================================
**     Method      :  PE_low_level_init (component MK60FN1M0LQ15)
**
**     Description :
**         Initializes beans and provides common register initialization. 
**         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 PE_low_level_init(void);

/* {MQX RTOS Adapter} ISR function prototype */
void Cpu_INT_LLWInterrupt(LDD_RTOS_TISRParameter _isrParameter);
/*
** ===================================================================
**     Method      :  Cpu_INT_LLWInterrupt (component MK60FN1M0LQ15)
**
**     Description :
**         This ISR services the 'LLWU' interrupt.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

void __pe_initialize_hardware(void);
/*
** ===================================================================
**     Method      :  __pe_initialize_hardware (component MK60FN1M0LQ15)
**
**     Description :
**         Initializes the whole system like timing, external bus, etc.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

/* END Cpu. */

#ifdef __cplusplus
}  /* extern "C" */
#endif 

#endif
/* __Cpu_H */

/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/crc/crc_kn.h<|end_filename|>
#ifndef __CRC_KN_H
#define __CRC_KN_H 1

/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: crc_kn.h$
* $Version : 3.8.3.0$
* $Date    : Sep-27-2012$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access CRC module
*
*END************************************************************************/

/*
*	Error code Definitions
*/
#define CRC_ERR_SUCCESS       0 
#define CRC_ERR_CODE_BASE    (0x2000)
#define CRC_ERR_TOT_VAL      (CRC_ERR_CODE_BASE+1)
#define CRC_ERR_TOTR_VAL     (CRC_ERR_CODE_BASE+2)
#define CRC_ERR_FXOR_VAL     (CRC_ERR_CODE_BASE+3)
#define CRC_ERR_TCRC_VAL     (CRC_ERR_CODE_BASE+4) 


/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

uint_32 CRC_Config(uint_32 poly,uint_32 tot,uint_32 totr,uint_32 fxor,uint_32 tcrc);
uint_32 CRC_Cal_16(uint_32 seed,uint_8 *msg, uint_32 sizeBytes);
uint_32 CRC_Cal_32(uint_32 seed,uint_8 *msg, uint_32 sizeBytes);
uint_32 CRC_init(void);

#ifdef __cplusplus
}
#endif

#endif /* __CRC_KN_H */



<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_iwconfig.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_iwconfig.c$
* $Version : 3.7.8.0$
* $Date    : Feb-24-2011$
*
* Comments:
*
*   Example using RTCS Library.
*
*END************************************************************************/


#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS
#include <bsp.h>
#include <rtcs.h>
#include <enet.h>
#include <ipcfg.h>
#include <iwcfg.h>
#include <enet_wifi.h>
#include <ctype.h>
#include "sh_rtcs.h"
#include "sh_enet.h"
#include "string.h"

#ifdef BSP_ENET_DEVICE_COUNT
#if  (BSP_ENET_DEVICE_COUNT > 0) 

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig_set_ssid
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/
static int_32 Shell_iwconfig_set_ssid (uint_32 enet_device,char_ptr ssid)
{
    uint_32 error;

    error = iwcfg_set_essid (enet_device,ssid);
    if (error != 0)
    {
        printf ("Error during setting of ssid %s error=%08x!\n",ssid, error);
        return SHELL_EXIT_ERROR;
    }
    
    printf ("SSID %s set successful.\n",ssid);
    return SHELL_EXIT_SUCCESS;
}
/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig_set_mode
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/
static int_32 Shell_iwconfig_set_mode (uint_32 enet_device,char_ptr mode)
{
    uint_32 error;

    error = iwcfg_set_mode (enet_device,mode);
    if (error != 0)
    {
        printf ("Error during setting of mode %08x!\n", error);
        return SHELL_EXIT_ERROR;
    }
    
    printf ("mode %s set successful.\n",mode);
    return SHELL_EXIT_SUCCESS;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig_set_mode
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/
static int_32 Shell_iwconfig_commit (uint_32 enet_device)
{
    uint_32 error;

    error = iwcfg_commit (enet_device);
    if (error != 0)
    {
        printf ("Error commiting \n");
        return SHELL_EXIT_ERROR;
    }
    
    printf ("commit successful.\n");
    return SHELL_EXIT_SUCCESS;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig_set_mode
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/
static int_32 Shell_iwconfig_set_wep_key (uint_32 enet_device,int_32 index,int_32 argc,char_ptr key[])
{
    uint_32 error;
    uint_32 i = 0;
    uint_32 flags = 0;
    char_ptr wep_key = NULL;
    uint_32 key_index = 0;
    uint_32 key_len=0;
        
    for (i=index+1;i<argc;i++) 
    {
        if (strcmp(key[i],"none") == 0)
        {
            wep_key = NULL;
            key_len = 0;
            break;
        }
        else if (strncmp(key[i],"[",1) == 0)
        {
          char_ptr ptr = key[i];
          if (!isdigit(*(++ptr)))
          {
            printf("%s key index passed is incorrect\n",key[i]);
            return SHELL_EXIT_ERROR;
          }
          key_index = key_index*10 + (*ptr - '0');
          continue;     
          
        }
        else if (strncmp(key[i],"s:",2) == 0)
        {
            char_ptr data = key[i];
            wep_key = data+2;
            key_len = strlen(data)-2;
            continue;
        }
        else if (strcmp(key[i],"restricted") == 0)
        {
           continue;
        }
        else if (strcmp(key[i],"open") == 0)
        {
            continue;
        }
        else
        {
            //Key is in hexadecimal format.
            printf("WEP Key in hexadecimal format not supported. Pass it as string using s:[password]\n");
            return SHELL_EXIT_ERROR;
        }
        
    }
    error = iwcfg_set_wep_key (enet_device,wep_key,key_len,key_index);
    if (error != 0)
    {
        printf ("Error during setting of key %08x!\n", error);
        return SHELL_EXIT_ERROR;
    }
    
    printf ("key set successful.\n");
    return SHELL_EXIT_SUCCESS;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig_set_sec_type
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/
static int_32 Shell_iwconfig_set_sec_type (uint_32 enet_device,char_ptr sec_type)
{
    uint_32 error;

    error = iwcfg_set_sec_type (enet_device,sec_type);
    if (error != 0)
    {
        printf ("Error during setting of sectype %08x!\n", error);
        return SHELL_EXIT_ERROR;
    }
    
    printf ("sectype %s set successful.\n",sec_type);
    return SHELL_EXIT_SUCCESS;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig_set_passphrase
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/
static int_32 Shell_iwconfig_set_passphrase (uint_32 enet_device,char_ptr passphrase)
{
    uint_32 error;
    char_ptr p_phrase;
   
    
    if (passphrase[0] == '"')
    {
       uint_32 tmp_len = 0;
       p_phrase = passphrase+1;
       tmp_len = strlen(p_phrase);
       p_phrase[tmp_len] = '\0';    
    }
    else 
    {
        p_phrase = passphrase;
    }
        
    error = iwcfg_set_passphrase (enet_device,p_phrase);
    if (error != 0)
    {
        printf ("Error during setting of passphrase %08x!\n", error);
        return SHELL_EXIT_ERROR;
    }
    
    printf ("passphrase %s set successful.\n",p_phrase);
    return SHELL_EXIT_SUCCESS;
}
/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig_set_power
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/
static int_32 Shell_iwconfig_set_power (uint_32 enet_device,int_32 index,int_32 argc,char_ptr argv[])
{
    uint_32 error;
    uint_32 i = 0;
    uint_32 flags = 0;
    uint_32 pow_val=0;
        
    for (i=index+1;i<argc;i++) 
    {
        if (strcmp(argv[i],"off") == 0)
        {
            flags = TRUE;
            break;
        }
        else if (strcmp(argv[i],"on") == 0)
        {
           flags = FALSE;
           break;
        }
        else if (strcmp(argv[i],"period") == 0)
        {
            char_ptr data = argv[i+1];
            uint_32 str_len = strlen(data);
            uint_32 sec_flag;
            if (data[str_len-1] == 's')
            {
              sec_flag = 1;
            }
            else if (data[str_len-1] == 'm')
            {
                sec_flag = 0;
            }
            else
            {
                printf("period supported only in seconds\n");
                return SHELL_EXIT_ERROR;
            }
            
            data[--str_len] = '\0';
  
            while (*data != '\0') 
            {
               if (!isdigit(*data))
               {
                   printf("%s  period value passed is incorrect\n",argv[i+1]);
                   return SHELL_EXIT_ERROR;
               }
          
               pow_val = pow_val*10 + (*data - '0');
               data++;
            }
            i++;
            flags = FALSE;
            if (sec_flag)
               pow_val = pow_val*1000;
            
            break;
        }
        else
        {
            //Key is in hexadecimal format.
            printf("parameter not supported with power command\n");
            return SHELL_EXIT_ERROR;
        }
        
    }
    error = iwcfg_set_power (enet_device,pow_val,flags);
    if (error != 0)
    {
        printf ("Error during setting of key %08x!\n", error);
        return SHELL_EXIT_ERROR;
    }
    
    printf ("power %s set successful.\n",argv[index+1]);
    return SHELL_EXIT_SUCCESS;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig_set_power
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/
static int_32 Shell_iwconfig_set_scan (uint_32 enet_device,int_32 index,int_32 argc,char_ptr argv[])
{
    uint_32 error;
    char_ptr ssid = NULL;
    if (argc > 2)
    {
        ssid = argv[index+1];
    }

    error = iwcfg_set_scan (enet_device, ssid);
    if (error != 0)
    {
        printf ("Error during scan %08x!\n", error);
        return SHELL_EXIT_ERROR;
    }
    
    if (ssid)
      printf ("scan %s done.\n",ssid);
    else
      printf("scan done.\n");
    
    return SHELL_EXIT_SUCCESS;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name  : Shell_iwconfig
* Returned Value : ERROR code on error else success
* Comments       :
*
*END------------------------------------------------------------------*/

int_32 Shell_iwconfig(int_32 argc, char_ptr argv[] )
{ /* Body */
    boolean                 print_usage, shorthelp = FALSE;
    int_32                  return_code = SHELL_EXIT_SUCCESS;
    uint_32                 enet_device = BSP_DEFAULT_ENET_DEVICE, index = 1;
  
    print_usage = Shell_check_help_request (argc, argv, &shorthelp);

    if (!print_usage)  
    {
        if (argc > index)  
        {
            if (Shell_parse_number (argv[index], &enet_device))
            {
                index++;
            }
        }

        if (enet_device >= BSP_ENET_DEVICE_COUNT)
        {
            printf ("Wrong number of ethernet device (%d)!\n", enet_device);
            return_code = SHELL_EXIT_ERROR;
        }
        else
        {
            if (argc > index)
            {
                if (strcmp (argv[index], "ssid") == 0)
                {
                    return_code = Shell_iwconfig_set_ssid(enet_device,argv[index+1]);
                }
                else if (strcmp (argv[index], "mode") == 0)
                {
                    return_code = Shell_iwconfig_set_mode(enet_device,argv[index+1]);
                }
                else if (strcmp (argv[index], "commit") == 0)
                {
                    return_code = Shell_iwconfig_commit(enet_device);   
                }
                else if (strcmp (argv[index], "key") == 0)
                {
                    return_code = Shell_iwconfig_set_wep_key(enet_device,index,argc,argv);
                }
                else if (strcmp (argv[index], "sectype") == 0)
                {
                    return_code = Shell_iwconfig_set_sec_type(enet_device,argv[index+1]);
                }
                else if (strcmp (argv[index], "passphrase") == 0)
                {
                    return_code = Shell_iwconfig_set_passphrase(enet_device,argv[index+1]);
                }
                else if (strcmp (argv[index], "power") == 0)
                {
                    return_code = Shell_iwconfig_set_power(enet_device,index,argc,argv);
                }
                else if (strcmp (argv[index], "scan") == 0)
                {
                    return_code = Shell_iwconfig_set_scan(enet_device,index,argc,argv);
                }

                else if (strcmp (argv[index], "help") == 0)
                {
                    return_code = SHELL_EXIT_ERROR; 
                }
                else
                {
                    printf ("Unknown iwconfig command!\n");
                    return_code = SHELL_EXIT_ERROR;
                }
            }
            else if (argc == 1)
            {
                char data[32];
                uint_32 error;
                error = iwcfg_get_essid (enet_device,(char_ptr)data);
                if (error != 0)
                   return_code = SHELL_EXIT_ERROR;
                
                printf("ssid=%s\n",data);
                iwcfg_get_mode (enet_device,(char_ptr)data);
                printf("mode=%s\n",data);
                iwcfg_get_sectype (enet_device,(char_ptr)data);
                printf("security type=%s\n",data);
                if (strcmp(data,"wep") == 0)
                {
                    uint_32 def_key_index;
                    iwcfg_get_wep_key(enet_device,(char_ptr)data,&def_key_index);
                    printf ("wep key=%s\n",data);
                    printf ("default key index=%d\n",def_key_index);
                }
                if (strcmp(data,"wpa") == 0)
                {
                    uchar p_phrase[65];
                    iwcfg_get_passphrase(enet_device,(char_ptr)p_phrase);
                    printf ("   passphrase=%s\n",p_phrase);
                }   
                if (strcmp(data,"wpa2") == 0)
                {
                    uchar p_phrase[65];
                    iwcfg_get_passphrase(enet_device,(char_ptr)p_phrase);
                    printf ("   passphrase=%s\n",p_phrase);
                }                           
            }
        }
    }
    else
    {
        return_code = SHELL_EXIT_ERROR;
    }

    if ((print_usage) || (return_code != SHELL_EXIT_SUCCESS))
    {
        if (shorthelp)
        {
            printf ("%s [<device>] [<command>]\n", argv[0]);
        } 
        else  
        {
            printf ("Use iwconfig commands if Wifi device is initialized\n");
            printf ("Usage: %s [<command>]\n", argv[0]);
            printf ("  Commands:\n");
            printf ("    ssid   [<network id>]   = Set SSID on device to associate with AP\n");
            printf ("    mode   [<network mode>] = Set network mode on device\n");          
            printf ("    commit                  = Forces the card to apply all pending changes.\n");                       
            printf ("    key [<WEP Key>],[<key index>]  = Sets WEP Keys and enables WEP security\n");
            printf ("    passphrase [<passphrase string>] = Enables WPA2 security and sets the passphrase\n");
            printf ("    sectype [<security type>]= Sets the Security for WiFi Device    \n");
            printf ("    power   [<on>] [<off>] [period] [<value>] = Enables or disables the power mode and sets the sleep duration.\n");
            printf ("    scan                   = Scan for Access Points and display there infrmation\n");
            printf ("    help                   = Display commands list and parameters.\n");
            printf ("  Parameters:\n");
            printf ("    <network id>   = name of the wireless network\n");
            printf ("    <network mode> = type of Wireless network. Possible values: managed or adhoc\n");
            printf ("    <WEP Key>      = WEP Security Key. If set to none, WEP security is disabled.\n");
            printf ("    <key index>    = Four keys can be set as WEP keys.Set index as [1],[2],[3],[4]\n");
            printf ("                   = To change which key is the currently active key, just enter [index]\n");
            printf ("                   = (without entering any key value).\n");
            printf ("    <security type>= wep,wpa,wpa2 or none\n");
            printf ("    <passphrase string> = pass phrase string\n");
            printf ("    <on>                = enables power mode\n");
            printf ("    <off>               = disables power mode\n");
            printf ("    <value>             = sleep duration\n");
        }
    }

    return return_code;
} /* Endbody */

#else /* (BSP_ENET_DEVICE_COUNT > 0) */
int_32 Shell_iwconfig(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;
}
#endif /* (BSP_ENET_DEVICE_COUNT > 0) */
#else  /* BSP_ENET_DEVICE_COUNT */
int_32 Shell_iwconfig(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;
}
#endif /* BSP_ENET_DEVICE_COUNT */
#endif /* SHELLCFG_USES_RTCS */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/esdhc/esdhc_prv.h<|end_filename|>
#ifndef __esdhc_prv_h__ 
#define __esdhc_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: esdhc_prv.h$
* $Version : 3.8.6.0$
* $Date    : Jul-19-2012$
*
* Comments:
*
*   This file contains definitions private to the ESDHC driver.
*
*END************************************************************************/

#include "esdhc.h"

/*--------------------------------------------------------------------------*/
/*
**                    CONSTANT DEFINITIONS
*/

#define IO_ESDHC_ATTRIBS (IO_DEV_ATTR_READ | IO_DEV_ATTR_REMOVE | IO_DEV_ATTR_SEEK | IO_DEV_ATTR_WRITE | IO_DEV_ATTR_BLOCK_MODE)

#define ESDHC_PROCTL_EMODE_BIG               (0x00)
#define ESDHC_PROCTL_EMODE_LITTLE            (0x02)

#define ESDHC_PROCTL_DTW_1BIT                (0x00)
#define ESDHC_PROCTL_DTW_4BIT                (0x01)
#define ESDHC_PROCTL_DTW_8BIT                (0x10)


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** ESDHC_INFO_STRUCT
** ESDHC run time state information
*/
typedef struct esdhc_info_struct
{
   /* The actual card status */
   uint_32                        CARD;
   
} ESDHC_INFO_STRUCT, _PTR_ ESDHC_INFO_STRUCT_PTR;


/*
** ESDHC_DEVICE_STRUCT
** ESDHC install parameters
*/
typedef struct esdhc_device_struct
{
   /* The current init values for this device */
   ESDHC_INIT_STRUCT_CPTR INIT;
   
   /* The number of opened file descriptors */
   uint_32                        COUNT;

} ESDHC_DEVICE_STRUCT, _PTR_ ESDHC_DEVICE_STRUCT_PTR;
    
/*--------------------------------------------------------------------------*/
/* 
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _esdhc_open (MQX_FILE_PTR, char_ptr, char_ptr);
extern _mqx_int _esdhc_close (MQX_FILE_PTR);
extern _mqx_int _esdhc_read (MQX_FILE_PTR, char_ptr, int_32);
extern _mqx_int _esdhc_write (MQX_FILE_PTR, char_ptr, int_32);
extern _mqx_int _esdhc_ioctl (MQX_FILE_PTR, uint_32, pointer);
extern _mqx_int _esdhc_uninstall (IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif
      
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/qrtc.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: qrtc.h$
* $Version : 3.8.2.0$
* $Date    : Sep-26-2012$
*
* Comments:
*
*   This include file is used to provide constant and structure definitions
*   common for RTC module 
*
*END************************************************************************/
#ifndef __qrtc_h__
#define __qrtc_h__

#ifdef __cplusplus
extern "C" {
#endif

#define _RTC                    (1)
#define _API                    (2)
#define BSP_RTC_INT_LEVEL       (4)
#define BSP_API_INT_LEVEL       (4)

#define RTC_VALUE               (125)
#define API_VALUE               (1000)
#ifndef PSP_MPXD10
#define RTC_INIT_FLAG_CLEAR     (1 << 0)
#define RTC_INIT_FLAG_RESET     (1 << 1)
#define RTC_INIT_FLAG_ENABLE    (1 << 2)
#endif
#define RTC_INIT_RTC_ENABLE     (1 << 3)
#define RTC_INIT_API_ENABLE     (1 << 4)  
/* Flags used to signal user callback requests */
#define RTC_EVENT_SW                       (1<<0)
#define RTC_EVENT_MIN                      (1<<1)
#define RTC_EVENT_ALM                      (1<<2)
#define RTC_EVENT_DAY                      (1<<3)
#define RTC_EVENT_1HZ                      (1<<4)
#define RTC_EVENT_HR                       (1<<5)

#define RTC_STPWCH_CNT(x)                 ((x)&0x1F)

/* standardized names used outside of driver */
/* currently, only alarms and stopwatches are signaled */
#define DEVSPEC_RTC_RTCISR_SW   RTC_EVENT_SW
#define DEVSPEC_RTC_RTCISR_ALM  RTC_EVENT_ALM
#define DEVSPEC_RTC_RTCIENR_SW  RTC_EVENT_SW
#define DEVSPEC_RTC_RTCIENR_ALM RTC_EVENT_ALM
/*------------------------------------------------------------------------*/
/*
** RTC registers
*/

//#include "typedefs.h"

// RTC register masks
#define QRTC_RTCSUPV_SUPV                    (1<<31)

#define QRTC_RTCC_CNTEN                      (1<<31)
#define QRTC_RTCC_RTCIE                      (1<<30)
#define QRTC_RTCC_FRZEN                      (1<<29)
#define QRTC_RTCC_ROVREN                     (1<<28)
#define QRTC_RTCC_RTCVAL(x)                  (((x)&0x0FFF)<<16)
#define QRTC_RTCC_APIEN                      (1<<15)
#define QRTC_RTCC_APIIE                      (1<<14)
#define QRTC_RTCC_CLKSEL(x)                  (((x)&0x03)<<12)
#define QRTC_RTCC_DIV512EN                   (1<<11)
#define QRTC_RTCC_DIV32EN                    (1<<10)
#define QRTC_RTCC_APIVAL(x)                  (((x)&0x03FF))
#define QRTC_RTCS_RTCF                       (1<<29)
#define QRTC_RTCS_ROVRF                      (1<<10)
#define QRTC_RTCS_APIF                       (1<<13)

// RTC status bits

#define QRTC_RTCISR_SW                       (1<<0)
#define QRTC_RTCISR_MIN                      (1<<1)
#define QRTC_RTCISR_ALM                      (1<<2)
#define QRTC_RTCISR_DAY                      (1<<3)
#define QRTC_RTCISR_1HZ                      (1<<4)
#define QRTC_RTCISR_HR                       (1<<5)
#define QRTC_RTCISR_EN                       (1<<31)
#define QRTC_RTCIENR_SW                      (1<<0)
#define QRTC_RTCIENR_MIN                     (1<<1)
#define QRTC_RTCIENR_ALM                     (1<<2)
#define QRTC_RTCIENR_DAY                     (1<<3)
#define QRTC_RTCIENR_1HZ                     (1<<4)
#define QRTC_RTCIENR_HR                      (1<<5)
#define QRTC_STPWCH_CNT(x)                   ((x)&0x1F)

/* RTC register structure */
typedef struct qrtc_regs_struct
{
  uint_32 RTCSUPV;                     /* RTC Supervisor Control Register */
  uint_32 RTCC;                        /* RTC Control Register */
  uint_32 RTCS;                        /* RTC Status Register */
  uint_32 RTCCNT;                      /* RTC Counter Register */

} QRTC_REGS_STRUCT, _PTR_ QRTC_REG_STRUCT_PTR;
typedef volatile struct qrtc_regs_struct _PTR_ VQRTC_REG_STRUCT_PTR;
typedef struct rtc_time_struct
{
    uint_8      seconds;
    uint_8      minutes;
    uint_8      hours;
    uint_16     days;
} RTC_TIME_STRUCT, _PTR_ RTC_TIME_STRUCT_PTR;

PSP_INTERRUPT_TABLE_INDEX _bsp_get_api_vector (void);

#ifdef __cplusplus
}
#endif

#endif  //__qi2c_h__


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi/spi_mk60.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_mk60.c$
* $Version : 3.8.3.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This file contains board-specific SPI initialization functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "spi_dspi.h"


static const pointer dspi_address[] =
{
    (pointer)SPI0_BASE_PTR,
    (pointer)SPI1_BASE_PTR,
    (pointer)SPI2_BASE_PTR
};


static const uint_32 /*PSP_INTERRUPT_TABLE_INDEX*/ dspi_vectors[][1] =
{
    { INT_SPI0 },
    { INT_SPI1 },
    { INT_SPI2 },
};


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_dspi_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding SPI
*    module.
*
*END*----------------------------------------------------------------------*/

pointer _bsp_get_dspi_base_address(uint_8 dev_num)
{
    if (dev_num < ELEMENTS_OF(dspi_address)) {
        return dspi_address[dev_num];
    }
    return NULL;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_dspi_vectors
* Returned Value   : Number of vectors associated with the peripheral
* Comments         :
*    This function returns desired interrupt vector table indices for specified
*    SPI module.
*
*END*----------------------------------------------------------------------*/

uint_32 _bsp_get_dspi_vectors(uint_32 dev_num, const uint_32 _PTR_ _PTR_ vectors_ptr)
{
    if (dev_num < ELEMENTS_OF(dspi_vectors)) {
        *vectors_ptr = dspi_vectors[dev_num];
        return ELEMENTS_OF(dspi_vectors[0]);
    }
    return 0;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcshdlc.h<|end_filename|>
#ifndef __rtcshdlc_h__
#define __rtcshdlc_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcshdlc.h$
* $Version : 3.6.10.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the defines, externs and data
*   structure definitions required by application
*   programs in order to use the HDLC device.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>

#include <fio.h>


/***************************************
**
** MQX compatibility
*/
#define _RTCS_poolid            _pool_id
#define _RTCS_queueid           _queue_id
#define _RTCS_queue_number      _queue_number
#define RTCS_memcopy            _mem_copy
#define RTCS_memalloc           _mem_alloc_zero
#define RTCS_memfree            _mem_free

/***************************************
**
** Constants
*/
#define HDLCIO_OK              0
#define RTCS_HDLC_MESSAGE_SIZE 1502

/***************************************
**
** Structures
*/

typedef struct rtcs_hdlc_header_struct
{
   MESSAGE_HEADER_STRUCT         HEADER;
   uint_32                       PACKET_SIZE;
} RTCS_HDLC_HEADER_STRUCT, _PTR_ RTCS_HDLC_HEADER_PTR;

typedef struct rtcs_hdlc_message_struct
{
   RTCS_HDLC_HEADER_STRUCT HDLC_HEADER;
   uchar       DATA[RTCS_HDLC_MESSAGE_SIZE];
} RTCS_HDLC_MESSAGE_STRUCT, _PTR_ RTCS_HDLC_MESSAGE_STRUCT_PTR;



typedef struct hdlcio_stats {
   RTCS_STATS_STRUCT  COMMON;

   uint_32  ST_RX_RUNT;
   uint_32  ST_RX_GIANT;

} HDLCIO_STATS, _PTR_ HDLCIO_STATS_PTR;


typedef struct hdlcio_struct {
   struct _iopcb_table PCB_TABLE;
   HDLCIO_STATS        STATS;
   _RTCS_poolid        POOL_ID;
   _RTCS_queueid       QID;
   uint_16             CHANNEL_Q;
   _ppp_mutex _PTR_    MUTEX_PTR;
   _rtcs_part          PART_ID;
   void (_CODE_PTR_    UP)(pointer);
   void (_CODE_PTR_    DOWN)(pointer);
   pointer             PARAM;

} HDLCIO_STRUCT, _PTR_ HDLCIO_STRUCT_PTR;

extern _iopcb_handle _iopcb_hdlc_init(uint_16, _RTCS_poolid, _RTCS_queueid, _ppp_mutex _PTR_);
extern void          _iopcb_hdlc_rcv_unblock(pointer);
extern void          _iopcb_hdlcio_rcv_unblock( pointer );
extern _iopcb_handle _iopcb_hdlcio_init(MQX_FILE_PTR);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/include/usb_cdc_pstn.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_cdc_pstn.h$
* $Version : 3.8.3.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
* @brief The file contains USB stack CDC-PSTN class layer api header function.
*
*****************************************************************************/

#ifndef _USB_CDC_PSTN_H
#define _USB_CDC_PSTN_H 1

/******************************************************************************
 * Includes
 *****************************************************************************/
 #include "usb_cdc.h"
/******************************************************************************
 * Constants 
 *****************************************************************************/  
typedef struct _BITMAP_UART 
{
    uint_8 reserved1 : 1; 
    uint_8 bOverRun : 1;
    uint_8 bParity  : 1;
    uint_8 bFraming : 1;
    uint_8 bRingSignal : 1;
    uint_8 bBreak : 1;
    uint_8 bTxCarrier : 1;
    uint_8 bRxCarrier : 1;           
}BITMAP_UART; /* for MQX */

typedef union _UART_BITMAP
{
    uint_8 _byte;                    
    BITMAP_UART Bitmap_Uart;
}UART_BITMAP;   /* UART STATE BITMAP */


/******************************************************************************
 * Macro's
 *****************************************************************************/
 #define UART_BITMAP_SIZE           (0x02)
 #define ABSTRACT_STATE_FEATURE     (0x01)
 #define COUNTRY_SETTING_FEATURE    (0x02)
 #define CARRIER_ACTIVATION_CHECK   (0x02)
 #define DTE_PRESENCE_CHECK         (0x01)
  
/*****************************
 * RNDIS Message State Macros 
 *****************************/
 #define REMOTE_NDIS_INITIALIZE_MSG         (0x00000002)
 #define REMOTE_NDIS_HALT_MSG               (0x00000003)
 #define REMOTE_NDIS_QUERY_MSG              (0x00000004)
 #define REMOTE_NDIS_SET_MSG                (0x00000005)
 #define REMOTE_NDIS_RESET_MSG              (0x00000006)
 #define REMOTE_NDIS_INDICATE_STATUS_MSG    (0x00000007)
 #define REMOTE_NDIS_KEEPALIVE_MSG          (0x00000008)
 #define REMOTE_NDIS_INITIALIZE_CMPLT       (0x80000002)
 #define REMOTE_NDIS_QUERY_CMPLT            (0x80000004)
 #define REMOTE_NDIS_SET_CMPLT              (0x80000005)
 #define REMOTE_NDIS_RESET_CMPLT            (0x80000006)
 #define REMOTE_NDIS_KEEPALIVE_CMPLT        (0x80000008)
 
/**********************
 * RNDIS Device States 
 **********************/
 #define RNDIS_UNINITIALIZED                (0x01)
 #define RNDIS_INITIALIZED                  (0x02)
 #define RNDIS_DATA_INITIALIZED             (0x03)
 
/**********************
 * RNDIS status values 
 **********************/
/*The requested operation completed successfully.*/
#define RNDIS_STATUS_SUCCESS                (0x00000000)
/*The underlying driver does not support the requested operation.*/
#define RNDIS_STATUS_NOT_RECOGNIZED         (0x00010001)
#define RNDIS_STATUS_NOT_SUPPORTED          (0xC00000BB)
/*The underlying driver attempted the requested operation, usually a set, 
  on its NIC but it was failed by the netcard. For example, an attempt to set 
  too many multicast addresses might cause the return of this value.*/
#define RNDIS_STATUS_NOT_ACCEPTED           (0x00010003)
/*This value usually is a nonspecific default, returned when none of the more 
  specific NDIS_STATUS_XXX caused the underlying driver to fail the request.*/
#define RNDIS_STATUS_FAILURE                (0xC0000001)
/*The request could not be satisfied due to a resource shortage. 
 Usually, this return indicates that an attempt to allocate memory was 
 unsuccessful, but it does not necessarily indicate that the same request, 
 submitted later, will be failed for the same reason.*/
#define RNDIS_STATUS_RESOURCES              (0xC000009A)
/*The underlying driver failed the requested operation because a close is in progress.*/
#define RNDIS_STATUS_CLOSING                (0xC0010002)
#define RNDIS_STATUS_CLOSING_INDICATING     (0xC001000E)
/*The underlying NIC driver cannot satisfy the request at this time because it 
  is currently resetting the netcard.*/
#define RNDIS_STATUS_RESET_IN_PROGRESS      (0xC001000D)
/*The value specified in the InformationBufferLength member of the 
  NDIS_REQUEST-structured buffer at NdisRequest does not match the 
  requirements for the given OID_XXX code. If the information buffer
  is too small, the BytesNeeded member contains the correct value for
  InformationBufferLength on return from NdisRequest.*/
#define RNDIS_STATUS_INVALID_LENGTH         (0xC0010014)
#define RNDIS_STATUS_BUFFER_TOO_SHORT       (0xC0010016)
/*The data supplied at InformationBuffer in the given NDIS_REQUEST structure 
  is invalid for the given OID_XXX code.*/
#define RNDIS_STATUS_INVALID_DATA           (0xC0010015)
/*The OID_XXX code specified in the Oid member of the NDIS_REQUEST-structured
  buffer at NdisRequest is invalid or unsupported by the underlying driver*/
#define RNDIS_STATUS_INVALID_OID            (0xC0010017)
#define RNDIS_STATUS_MEDIA_CONNECT          (0x4001000B)
#define RNDIS_STATUS_MEDIA_DISCONNECT       (0x4001000C) 
 
/***********************
 * RNDIS Response sizes 
 ***********************/
 #define RESPONSE_RNDIS_INITIALIZE_MSG_SIZE       (52)
 #define RESPONSE_RNDIS_QUERY_MSG_SIZE            (24)
 #define RESPONSE_RNDIS_SET_MSG_SIZE              (16)
 #define RESPONSE_RNDIS_RESET_MSG_SIZE            (16)
 #define RESPONSE_RNDIS_KEEPALIVE_MSG_SIZE        (16)
 
/*********************
 * RNDIS Other Macros 
 *********************/
 #define RNDIS_DF_CONNECTIONLESS            (0x00000001)
 #define RNDIS_DF_CONNECTION_ORIENTED       (0x00000002)
 #define RNDIS_MEDIUM_802_3                 (0x00000000)
 #define RNDIS_SINGLE_PACKET_TRANSFER       (0x00000001)
 #define PACKET_ALIGNMENT_FACTOR            (0x00000003)
 #define NUM_OIDS_SUPPORTED                 (25)
 #define RNDIS_VENDOR_ID                    (0xFFFFFF)
 #define NIC_IDENTIFIER_VENDOR              (0x01)
 /* Randomly selected mac address for reference design */
 /* Following two defines are reserved for connection oriented devices. Set value to zero */
 #define AF_LIST_OFFSET                     (0x00000000)
 #define AF_LIST_SIZE                       (0x00000000)
 /* Size of Ethernet address*/
 #define RNDIS_ETHER_ADDR_SIZE              (6)
 /* Size of ethernet header*/
 #define RNDIS_USB_HEADER_SIZE              (44)
 #define RNDIS_ETHER_HDR_SIZE               (14)
 #define RNDIS_ETH_MIN_PACKET               (60)
 #define RNDIS_ETH_MAX_PACKET               (1514)
 #define RNDIS_MCAST_LIST_SIZE              (32)
 #define RNDIS_ETH_MIN_FRAME                (16)
 #define RNDIS_MULTICAST_LIST_SIZE          (0)
 #define REMOTE_NDIS_PACKET_MSG             (0x00000001)

/*******************************************************
 * NDIS Hardware status codes (OID_GEN_HARDWARE_STATUS) 
 *******************************************************/
/* Available and capable of sending and receiving data over the wire */
#define NdisHardwareStatusReady             (0x00000000)
/* Initializing */
#define NdisHardwareStatusInitializing      (0x00000001)
/* Resetting */
#define NdisHardwareStatusReset             (0x00000002)
/* Closing */
#define NdisHardwareStatusClosing           (0x00000003)    
/* Not ready */
#define NdisHardwareStatusNotReady          (0x00000004)

/************************************************ 
 * NDIS media types that the NIC can support 
 ************************************************/
/* Ethernet (802.3) is not supported for NDIS 6.0 drivers.*/
/* Note  NDIS 5.x miniport drivers that conform to the 802.11 interface must
   use this media type. For more information about the 802.11 interface, 
   see 802.11 Wireless LAN Miniport Drivers.*/    
#define NdisMedium802_3                     (0x00000000)
/*Token Ring (802.5) is not supported for NDIS 6.0 drivers.*/
#define NdisMedium802_5                     (0x00000001)
/*FDDI is not supported on Windows Vista.*/    
#define NdisMediumFddi                      (0x00000002)
/*WAN*/    
#define NdisMediumWan                       (0x00000003)
/*LocalTalk*/    
#define NdisMediumLocalTalk                 (0x00000004)
/*DEC/Intel/Xerox (DIX) Ethernet*/    
#define NdisMediumDix                       (0x00000005)
/*ARCNET (raw) is not supported on Windows Vista.*/    
#define NdisMediumArcnetRaw                 (0x00000006)
/*ARCNET (878.2) is not supported on Windows Vista.*/    
#define NdisMediumArcnet878_2               (0x00000007)
/*ATM is not supported for NDIS 6.0 drivers.*/    
#define NdisMediumAtm                       (0x00000008)
/*Native 802.11. This media type is used by miniport drivers that conform to 
  the Native 802.11 interface. For more information about this interface, see
  Native 802.11 Wireless LAN Miniport Drivers.
  Note: Native 802.11 interface is supported in NDIS 6.0 and later versions*/    
#define NdisMediumNative802_11              (0x00000009)
/*Various types of NdisWirelessXxx media
Note  This media type is not available for use beginning with Windows Vista*/
#define NdisMediumWirelessWan               (0x0000000A)
/*Infrared (IrDA)*/    
#define NdisMediumIrda                      (0x0000000B)
/*Connection-oriented WAN */    
#define NdisMediumCoWan                     (0x0000000C)
/*IEEE 1394 (firewire) bus*/    
#define NdisMedium1394                      (0x0000000D)
/*Broadcast PC network.*/     
#define NdisMediumBpc                       (0x0000000E)
/*InfiniBand network.*/    
#define NdisMediumInfiniBand                (0x0000000F)
/*Tunnel network.*/    
#define NdisMediumTunnel                    (0x00000010)
/*  NDIS loopback network. */    
#define NdisMediumLoopback                  (0x00000011)

 
/*********************************************************** 
 * Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER).
 ***********************************************************/ 
/*Directed packets. Directed packets contain a destination address
  equal to the station address of the NIC. */
#define NDIS_PACKET_TYPE_DIRECTED               (0x0001)
/*Multicast address packets sent to addresses in the multicast address list.
  A protocol driver can receive Ethernet (802.3) multicast packets or 
  Token Ring (802.5) functional address packets by specifying the multicast or
  functional address packet type. Setting the multicast address list or 
  functional address determines which multicast address 
  groups the NIC driver enables.*/
#define NDIS_PACKET_TYPE_MULTICAST              (0x0002) 
/*All multicast address packets, not just the ones enumerated in the 
  multicast address list.*/
#define NDIS_PACKET_TYPE_ALL_MULTICAST          (0x0004) 
/*Broadcast packets. */
#define NDIS_PACKET_TYPE_BROADCAST              (0x0008) 
/*All source routing packets. If the protocol driver sets this bit, 
  the NDIS library attempts to act as a source routing bridge. */
#define NDIS_PACKET_TYPE_SOURCE_ROUTING         (0x0010) 
/*Specifies all packets.*/
#define NDIS_PACKET_TYPE_PROMISCUOUS            (0x0020) 
/*SMT packets that an FDDI NIC receives. */
#define NDIS_PACKET_TYPE_SMT                    (0x0040) 
/*All packets sent by installed protocols and all packets indicated by the NIC
 that is identified by a given NdisBindingHandle*/
#define NDIS_PACKET_TYPE_ALL_LOCAL              (0x0080) 
/*NIC driver frames that a Token Ring NIC receives. */
#define NDIS_PACKET_TYPE_MAC_FRAME              (0x8000) 
/*Functional address packets sent to addresses 
  included in the current functional address. */
#define NDIS_PACKET_TYPE_FUNCTIONAL             (0x4000) 
/*All functional address packets, not just the ones in the 
  current functional address. */
#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL         (0x2000) 
/*Packets sent to the current group address. */
#define NDIS_PACKET_TYPE_GROUP                  (0x1000)

  
 
/***************************************************************
 * Object Identifiers used by NdisRequest Query/Set Information  
 ***************************************************************/   
/* General Objects */ 
#define OID_GEN_SUPPORTED_LIST                  0x00010101 
#define OID_GEN_HARDWARE_STATUS                 0x00010102 
#define OID_GEN_MEDIA_SUPPORTED                 0x00010103 
#define OID_GEN_MEDIA_IN_USE                    0x00010104 
#define OID_GEN_MAXIMUM_LOOKAHEAD               0x00010105 
#define OID_GEN_MAXIMUM_FRAME_SIZE              0x00010106 
#define OID_GEN_LINK_SPEED                      0x00010107 
#define OID_GEN_TRANSMIT_BUFFER_SPACE           0x00010108 
#define OID_GEN_RECEIVE_BUFFER_SPACE            0x00010109 
#define OID_GEN_TRANSMIT_BLOCK_SIZE             0x0001010A 
#define OID_GEN_RECEIVE_BLOCK_SIZE              0x0001010B 
#define OID_GEN_VENDOR_ID                       0x0001010C 
#define OID_GEN_VENDOR_DESCRIPTION              0x0001010D 
#define OID_GEN_CURRENT_PACKET_FILTER           0x0001010E 
#define OID_GEN_CURRENT_LOOKAHEAD               0x0001010F 
#define OID_GEN_DRIVER_VERSION                  0x00010110 
#define OID_GEN_MAXIMUM_TOTAL_SIZE              0x00010111 
#define OID_GEN_PROTOCOL_OPTIONS                0x00010112 
#define OID_GEN_MAC_OPTIONS                     0x00010113 
#define OID_GEN_MEDIA_CONNECT_STATUS            0x00010114 
#define OID_GEN_MAXIMUM_SEND_PACKETS            0x00010115 
#define OID_GEN_VENDOR_DRIVER_VERSION           0x00010116 
#define OID_GEN_XMIT_OK                         0x00020101 
#define OID_GEN_RCV_OK                          0x00020102 
#define OID_GEN_XMIT_ERROR                      0x00020103 
#define OID_GEN_RCV_ERROR                       0x00020104 
#define OID_GEN_RCV_NO_BUFFER                   0x00020105 
#define OID_GEN_DIRECTED_BYTES_XMIT             0x00020201 
#define OID_GEN_DIRECTED_FRAMES_XMIT            0x00020202 
#define OID_GEN_MULTICAST_BYTES_XMIT            0x00020203 
#define OID_GEN_MULTICAST_FRAMES_XMIT           0x00020204 
#define OID_GEN_BROADCAST_BYTES_XMIT            0x00020205 
#define OID_GEN_BROADCAST_FRAMES_XMIT           0x00020206 
#define OID_GEN_DIRECTED_BYTES_RCV              0x00020207 
#define OID_GEN_DIRECTED_FRAMES_RCV             0x00020208 
#define OID_GEN_MULTICAST_BYTES_RCV             0x00020209 
#define OID_GEN_MULTICAST_FRAMES_RCV            0x0002020A 
#define OID_GEN_BROADCAST_BYTES_RCV             0x0002020B 
#define OID_GEN_BROADCAST_FRAMES_RCV            0x0002020C 
#define OID_GEN_RCV_CRC_ERROR                   0x0002020D 
#define OID_GEN_TRANSMIT_QUEUE_LENGTH           0x0002020E 
#define OID_GEN_GET_TIME_CAPS                   0x0002020F 
#define OID_GEN_GET_NETCARD_TIME                0x00020210 
/* 802.3 Objects (Ethernet) */ 
#define OID_802_3_PERMANENT_ADDRESS             0x01010101 
#define OID_802_3_CURRENT_ADDRESS               0x01010102 
#define OID_802_3_MULTICAST_LIST                0x01010103 
#define OID_802_3_MAXIMUM_LIST_SIZE             0x01010104 
#define OID_802_3_MAC_OPTIONS                   0x01010105 
 
#define NDIS_802_3_MAC_OPTION_PRIORITY          0x00000001 
#define OID_802_3_RCV_ERROR_ALIGNMENT           0x01020101 
#define OID_802_3_XMIT_ONE_COLLISION            0x01020102 
#define OID_802_3_XMIT_MORE_COLLISIONS          0x01020103 
#define OID_802_3_XMIT_DEFERRED                 0x01020201 
#define OID_802_3_XMIT_MAX_COLLISIONS           0x01020202 
#define OID_802_3_RCV_OVERRUN                   0x01020203 
#define OID_802_3_XMIT_UNDERRUN                 0x01020204 
#define OID_802_3_XMIT_HEARTBEAT_FAILURE        0x01020205 
#define OID_802_3_XMIT_TIMES_CRS_LOST           0x01020206 
#define OID_802_3_XMIT_LATE_COLLISIONS          0x01020207 

/****************************
 * NDIS Media Connect Status
 ****************************/
#define NdisMediaStateConnected         (0x00000000)
#define NdisMediaStateDisconnected      (0x00000001) 
#define NdisMediaStateUnknown           (0xFFFFFFFF)

/********************************************************************
 * DeviceState : Result of the NDISUIO query of OID_GEN_MEDIA_IN_USE.
 ********************************************************************/
 #define RNDIS_DEVICE_STATE_CONNECTED           (0x00000001)
 #define RNDIS_DEVICE_STATE_DISCONNECTED        (0x00000000)

 /******************************************************************************
 * Types
 *****************************************************************************/
 /*
  * This Structure represents PSTN object 
  */
typedef struct _cdc_pstn_struct
{
    uint_8 serial_state_buf[NOTIF_PACKET_SIZE+UART_BITMAP_SIZE];
    USB_CLASS_CALLBACK_STRUCT pstn_callback;
    boolean dte_present; 
    /* Status of DATA TERMINAL EQUIPMENT */
    uint_8 dte_status; 
    /* Length of time in milliseconds of the break signal */
    uint_16 break_duration; 
    uint_8 current_interface; 
    UART_BITMAP uart_bitmap;
    #if RNDIS_SUPPORT
        uint_8 rndis_device_state;
        uint_8_ptr rndis_command_ptr;
        uint_8_ptr response_data_ptr;
        uint_32 rndis_host_max_tx_size;  
        uint_32 rndis_dev_max_tx_size;  
        uint_32 rndis_hw_state;     
        uint_32 rndis_packet_filter;
        uint_32 rndis_media_connect_status;
        uint_32 num_frames_tx_ok;
        uint_32 num_frames_rx_ok;
        uint_32 num_frames_tx_error;
        uint_32 num_frames_rx_error;
        uint_32 num_recv_frames_missed;
        uint_32 num_recv_frames_alignment_error;
        uint_32 num_frames_tx_one_collision;
        uint_32 num_frames_tx_many_collision;
    #endif  
 }CDC_PSTN_STRUCT, _PTR_ CDC_PSTN_STRUCT_PTR;

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/adc_conf.h<|end_filename|>
#ifndef __adc_conf_h__
#define __adc_conf_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_conf.h$
* $Version : 3.6.6.0$
* $Date    : May-18-2010$
*
* Comments:
*
*   ADC driver configuration header file
*
*END************************************************************************/

/* Note that these are SW channels for MQX driver, not related to the HW */
#define ADC_MAX_SW_CHANNELS       (2)
/* ADC driver can hold file name in the driver to prevent open file 2 times */
#define ADC_STORE_FILENAMES       1

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Asin.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Asin.h
*
* @author   B04459
* 
* @version  1.0.1.0
* 
* @date     Dec-6-2012
* 
* @brief    Header file for #GFLIB_Asin function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef GFLIB_ASIN_H_
#define GFLIB_ASIN_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif
/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*!
  \def GFLIB_Asin
  Function alias.
*/
#define GFLIB_Asin(x) GFLIB_AsinANSIC((x), &gflibAsinCoef)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/

/*------------------------------------------------------------------------*//*!
@struct GFLIB_ASIN_TAYLOR_COEF_T "\GFLIB_Asin.h"

@brief      Structure containing five polynomial coefficients for one sub-interval.

@details    Output of \f$\arcsin\left(f32In\right)\f$ for
            interval \f$\left[0,1\right)\f$ of the input ratio is divided
            into two sub-sectors. Polynomial approximation is done using a 5th
            order polynomial, for each sub-sector respectively. Five coefficients
            for a single sub-interval are stored in this (#GFLIB_ASIN_TAYLOR_COEF_T)
            structure.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    const Frac32  f32a[5];  /*!< Array of five 32-bit elements for storing
                                  coefficients of the piece-wise polynomial. */
}GFLIB_ASIN_TAYLOR_COEF_T;

/*------------------------------------------------------------------------*//*!
@struct GFLIB_ASIN_TAYLOR_T "\GFLIB_Asin.h"

@brief      Structure containing two sub-structures with polynomial coefficients
            to cover all sub-intervals.

@details    Output of \f$\arcsin\left(f32In\right)\f$ for
            interval \f$\left[0,1\right)\f$ of the input ratio is divided
            into two sub-sectors. Polynomial approximation is done using a 5th
            order polynomial, for each sub-sector respectively. Two arrays,
            each including five polynomial coefficients for each sub-interval,
            are stored in this (#GFLIB_ASIN_TAYLOR_T) structure.

            \par
            By calling the function alias #GFLIB_Asin, default values of
            the coefficients are used. Polynomial coefficients can be modified by
            the user and in such a case the full function call shall be used, i.e.
            #GFLIB_AsinANSIC
*//*-------------------------------------------------------------------------*/

typedef struct
{
    const GFLIB_ASIN_TAYLOR_COEF_T  GFLIB_ASIN_SECTOR[2]; /*!< Array of two
                                    elements for storing eight sub-arrays (each
                                    sub-array contains four 32-bit
                                    coefficients) for all sub-intervals.*/
} GFLIB_ASIN_TAYLOR_T;

/******************************************************************************
* Exported Variables
******************************************************************************/

extern GFLIB_ASIN_TAYLOR_T gflibAsinCoef;

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*! 
* @ingroup GFLIB_GROUP 
*/ 
extern Frac32 GFLIB_AsinANSIC(Frac32 f32In, const GFLIB_ASIN_TAYLOR_T *const pParam);

/******************************************************************************
* Inline functions
******************************************************************************/ 

#endif /*GFLIB_ASIN_H_*/


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_readtest.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_readtest.c$
* $Version : 3.8.16.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <shell.h>
#include <mfs.h>
#include <sh_mfs.h>
#include "sh_prv.h"

#if SHELLCFG_USES_MFS

const char MFS_File_test_data[] = 
"3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342"
"11706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294"
"89549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133"
"93607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466"
"52138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188"
"57527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171"
"76293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224"
"95343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721"
"13499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710"
"10003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957"
"78185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823"
"03019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278"
"55889075098381754637464939319255060400927701671139009848824012858361603563707660104710181942955"
"59619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205"
"69660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216"
"41219924586315030286182974555706749838505494588586926995690927210797509302955321165344987202755"
"96023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614"
"52491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624"
"16862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383827"
"96797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118"
"63067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780"
"27590099465764078951269468398352595709825822620522489407726719478268482601476990902640136394437"
"45530506820349625245174939965143142980919065925093722169646151570985838741059788595977297549893"
"01617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362"
"22626099124608051243884390451244136549762780797715691435997700129616089441694868555848406353422"
"07222582848864815845602850601684273945226746767889525213852254995466672782398645659611635488623"
"05774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601"
"01503308617928680920874760917824938589009714909675985261365549781893129784821682998948722658804"
"85756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610213"
"59695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457"
"13868751943506430218453191048481005370614680674919278191197939952061419663428754440643745123718"
"19217999839101591956181467514269123974894090718649423196156794520809514655022523160388193014209"
"37621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252"
"01497442850732518666002132434088190710486331734649651453905796268561005508106658796998163574736"
"38405257145910289706414011097120628043903975951567715770042033786993600723055876317635942187312"
"51471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280"
"17350671274858322287183520935396572512108357915136988209144421006751033467110314126711136990865"
"85163983150197016515116851714376576183515565088490998985998238734552833163550764791853589322618"
"54896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233"
"26097299712084433573265489382391193259746366730583604142813883032038249037589852437441702913276"
"56180937734440307074692112019130203303801976211011004492932151608424448596376698389522868478312"
"35526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652"
"27211166039666557309254711055785376346682065310989652691862056476931257058635662018558100729360"
"65987648611791045334885034611365768675324944166803962657978771855608455296541266540853061434443"
"18586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390"
"81454664645880797270826683063432858785698305235808933065757406795457163775254202114955761581400"
"25012622859413021647155097925923099079654737612551765675135751782966645477917450112996148903046"
"39947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094"
"12147221317947647772622414254854540332157185306142288137585043063321751829798662237172159160771"
"66925474873898665494945011465406284336639379003976926567214638530673609657120918076383271664162"
"74888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947"
"26547364252308177036751590673502350728354056704038674351362222477158915049530984448933309634087"
"80769325993978054193414473774418426312986080998886874132604721569516239658645730216315981931951"
"67353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237"
"89690706977942236250822168895738379862300159377647165122893578601588161755782973523344604281512"
"62720373431465319777741603199066554187639792933441952154134189948544473456738316249934191318148"
"09277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619"
"32668633606273567630354477628035045077723554710585954870279081435624014517180624643626794561275"
"31813407833033625423278394497538243720583531147711992606381334677687969597030983391307710987040"
"85913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931"
"13835049316312840425121925651798069411352801314701304781643788518529092854520116583934196562134"
"91434159562586586557055269049652098580338507224264829397285847831630577775606888764462482468579"
"26039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131"
"53595845068772460290161876679524061634252257719542916299193064553779914037340432875262888963995"
"87947572917464263574552540790914513571113694109119393251910760208252026187985318877058429725916"
"77813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922"
"33451722013812806965011784408745196012122859937162313017114448464090389064495444006198690754851"
"60263275052983491874078668088183385102283345085048608250393021332197155184306354550076682829493"
"04137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282"
"78921250771262946322956398989893582116745627010218356462201349671518819097303811980049734072396"
"10368540664319395097901906996395524530054505806855019567302292191393391856803449039820595510022"
"63535361920419947455385938102343955449597783779023742161727111723643435439478221818528624085140"
"06660443325888569867054315470696574745855033232334210730154594051655379068662733379958511562578"
"43229882737231989875714159578111963583300594087306812160287649628674460477464915995054973742562"
"69010490377819868359381465741268049256487985561453723478673303904688383436346553794986419270563"
"87293174872332083760112302991136793862708943879936201629515413371424892830722012690147546684765"
"35761647737946752004907571555278196536213239264061601363581559074220202031872776052772190055614"
"84255518792530343513984425322341576233610642506390497500865627109535919465897514131034822769306"
"24743536325691607815478181152843667957061108615331504452127473924544945423682886061340841486377"
"67009612071512491404302725386076482363414334623518975766452164137679690314950191085759844239198"
"62916421939949072362346468441173940326591840443780513338945257423995082965912285085558215725031"
"07125701266830240292952522011872676756220415420516184163484756516999811614101002996078386909291"
"60302884002691041407928862150784245167090870006992821206604183718065355672525325675328612910424"
"87761825829765157959847035622262934860034158722980534989650226291748788202734209222245339856264"
"76691490556284250391275771028402799806636582548892648802545661017296702664076559042909945681506"
"52653053718294127033693137851786090407086671149655834343476933857817113864558736781230145876871"
"26603489139095620099393610310291616152881384379099042317473363948045759314931405297634757481193"
"56709110137751721008031559024853090669203767192203322909433467685142214477379393751703443661991"
"04033751117354719185504644902636551281622882446257591633303910722538374218214088350865739177150"
"96828874782656995995744906617583441375223970968340800535598491754173818839994469748676265516582"
"76584835884531427756879002909517028352971634456212964043523117600665101241200659755851276178583"
"82920419748442360800719304576189323492292796501987518721272675079812554709589045563579212210333"
"46697499235630254947802490114195212382815309114079073860251522742995818072471625916685451333123"
"94804947079119153267343028244186041426363954800044800267049624820179289647669758318327131425170"
"29692348896276684403232609275249603579964692565049368183609003238092934595889706953653494060340"
"21665443755890045632882250545255640564482465151875471196218443965825337543885690941130315095261"
"79378002974120766514793942590298969594699556576121865619673378623625612521632086286922210327488"
"92186543648022967807057656151446320469279068212073883778142335628236089632080682224680122482611"
"77185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417254"
"37090697939612257142989467154357846878861444581231459357198492252847160504922124247014121478057"
"34551050080190869960330276347870810817545011930714122339086639383395294257869050764310063835198"
"34389341596131854347546495569781038293097164651438407007073604112373599843452251610507027056235"
"26601276484830840761183013052793205427462865403603674532865105706587488225698157936789766974220"
"57505968344086973502014102067235850200724522563265134105592401902742162484391403599895353945909"
"44070469120914093870012645600162374288021092764579310657922955249887275846101264836999892256959"
"6881592056001016552563756";

const uint_32 MFS_File_test_data_size = sizeof(MFS_File_test_data)-1;


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_read_test
* Returned Value   :  int_32 error code
* Comments  :  Reads from a file .
*
*END*---------------------------------------------------------------------*/
#ifndef min
   #define min(a,b) ((a)<(b)?(a):(b))
#endif

int_32  Shell_read_test(int_32 argc, char_ptr argv[] )
{ 
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   MQX_FILE_PTR      fd; 
   char_ptr          read_buffer = NULL;
   uint_32           test_size = MFS_File_test_data_size;
   uint_32           read_size = 1,num,size,bytes_read,i,p=0;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   char_ptr             abs_path = NULL;
   int_32               error = 0;      

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc != 2) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else  {
         if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
            printf("Error, unable to allocate memory for paths\n" );
            return_code = SHELL_EXIT_ERROR;
         }
         else
         {
            error = _io_rel2abs(abs_path,shell_ptr->CURRENT_DIR,(char *) argv[1],PATHNAME_SIZE,shell_ptr->CURRENT_DEVICE_NAME);
            if(!error)
            {
               fd = fopen(abs_path, "w");
               write(fd, (pointer)MFS_File_test_data, test_size);
               fclose(fd);
            
               fd = fopen(abs_path, "r");
               read_buffer = _mem_alloc(test_size + 1);
               _mem_zero (read_buffer, test_size + 1);
            }
            if (fd && read_buffer && !error)  {
               for (read_size=1;read_size<test_size;read_size++) {
                  printf("Test Iteration #%d ", read_size);
                  fseek(fd,0,IO_SEEK_SET);
                  bytes_read = 0;
                  while ( bytes_read<test_size) {
                     size = min(read_size,test_size-bytes_read);
                     num = read(fd, &read_buffer[bytes_read],size);
                     if (num) {
                        bytes_read+=num;
                     } else {
                        printf("Read failed, offset = %d", bytes_read);
                       break;
                     }
                  } 
                  for (i = 0; i < test_size; i++)
                  {
                     if (MFS_File_test_data[i] != read_buffer[i]) {
                        printf("Failed %d. %d != %d\n", i, MFS_File_test_data[i], read_buffer[i]);
                        p++;
                        break;
                     }
                  }
                  if (i == test_size)
                  {
                     printf("Passed, errors: %d\n", p);
                  }
               } 
            }
            else
            {
               printf("Error, unable open file: %s\n", argv[1]);
            }
            if (fd) fclose(fd);
            if (read_buffer) _mem_free(read_buffer);
            MFS_free_path(abs_path);
         }
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <filename> \n", argv[0]);
      } else  {
         printf("Usage: %s <filename> \n", argv[0]);
         printf("   <filename>   = filename to verify\n");
      }
   }
   return return_code;
} /* Endbody */

#endif //SHELLCFG_USES_MFS


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcflash/apcflash.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: apcflash.c$
* $Version : 3.8.13.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   This file contains the advanced PC Card flash disk driver functions
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "ata.h"
#include "io_prv.h"
#include "apcflshpr.h"

#if !BSP_USE_OLD_PCCARD_INTERFACE /* Advanced PCMCIA */
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_install
* Returned Value   : uint_32 - a task error code or MQX_OK
* Comments         :
*    Install a PC Card flash driver.
*
*END*----------------------------------------------------------------------*/

uint_32 _io_apcflash_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr                      identifier
   )
{ /* Body */
   IO_PCFLASH_STRUCT_PTR            info_ptr;

   /* Allocate memory for the state structure */
   info_ptr = _mem_alloc_system_zero((uint_32)sizeof(IO_PCFLASH_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (info_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(info_ptr,MEM_TYPE_IO_PCFLASH);

   /* Fill in the state structure with the info we know */
   info_ptr->DRIVE         = 0;    /* always use ATA device 0 */     
   info_ptr->SECTOR_SIZE   = ATA_SECTOR_SIZE;          
   info_ptr->TEMP_BUFF_PTR = NULL;
   info_ptr->ERROR_CODE    = IO_OK;

   _lwsem_create(&info_ptr->LWSEM, 1L);
    
   return (_io_dev_install(identifier,
      _io_apcflash_open,
      _io_apcflash_close,
      _io_apcflash_read,
      _io_apcflash_write,
      _io_apcflash_ioctl,
      (pointer)info_ptr)); 

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_open
* Returned Value   : An error code or MQX_OK
* Comments         : Opens and initializes a PC Card flash driver.  
*                    A flash card must be inserted for this operation to be 
*                    successful 
*END*----------------------------------------------------------------------*/

_mqx_int _io_apcflash_open
   (
      /* [IN] the file handle for the device being opened */
      FILE_DEVICE_STRUCT_PTR   fd_ptr,
      
      /* [IN] the remaining portion of the name of the device */
      char _PTR_               open_name_ptr,

      /* [IN] the flags to be used during operation */
      char _PTR_               flags
   )
{ /* Body */
   APCCARD_ADDR_INFO_STRUCT         addr_info;
   IO_DEVICE_STRUCT_PTR             io_dev_ptr = fd_ptr->DEV_PTR;
   IO_PCFLASH_STRUCT_PTR            info_ptr
      = (IO_PCFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   ATA_IDENTIFY_DEVICE_STRUCT_PTR   identify_ptr;
   MQX_FILE_PTR                     pccard_stream = (MQX_FILE_PTR)flags;
   uint_32_ptr                      temp_ptr;
   uchar_ptr                        temp8_ptr;
   uint_32                          temp;
   uint_32                          error;
   int_32                           io_error;
   uint_32                          num_sectors;
   uchar                            end_defn[] = {2, 0};

#if MQX_CHECK_ERRORS
   if (pccard_stream == NULL) {
      /* No PCCARD device open */
      return(IO_ERROR);
   } /* Endif */
#endif

   /* 
   ** Allocate a ram buffer the size of one sector to be used when 
   ** reading/writing  partial sectors -- this buffer is also used in this 
   ** function for the identify info 
   */
   temp_ptr = (uint_32_ptr)_mem_alloc_system_zero(info_ptr->SECTOR_SIZE);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (temp_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif   
  _mem_set_type(temp_ptr,MEM_TYPE_IO_SECTOR_BUFFER);         

#if MQX_CHECK_ERRORS
   /* Is the lower layer compatible? */
   io_error = _io_ioctl(pccard_stream, IO_IOCTL_DEVICE_IDENTIFY, temp_ptr);
   if ((io_error != MQX_OK) || (temp_ptr[0] != IO_DEV_TYPE_PHYS_ADV_PCCARD)) {
      _mem_free(temp_ptr);
      if (io_error == MQX_OK) {
         io_error = IO_ERROR_DEVICE_INVALID;
      }/* Endif */
      return(io_error);
   } /* Endif */
#endif

   /* Is there a card present? */
   _io_ioctl(pccard_stream, APCCARD_IOCTL_IS_CARD_INSERTED, &temp);
   if ((boolean)temp == FALSE) {
      _mem_free(temp_ptr);
      return(IO_ERROR);
   } /* Endif */

   /* Wait for card to power up. This will apply Vcc and also Vpp if needed */
   _io_ioctl(pccard_stream, APCCARD_IOCTL_WAIT_TILL_READY, NULL);

   /* Make sure card is an ATA flash card */

   /* Read CISTPL_FUNCID tuple */
   temp_ptr[0] = IO_APCCARD_TUPLE_CISTPL_FUNCID;
   _io_ioctl(pccard_stream, APCCARD_IOCTL_READ_TUPLE, temp_ptr);

   temp8_ptr = (uchar_ptr)(temp_ptr + 1);
   if (temp8_ptr[0] != 0x4) {
      /* This is not a flash disk */
      _mem_free(temp_ptr);
      return(IO_ERROR_DEVICE_INVALID);
   } /* Endif */
      
   info_ptr->TEMP_BUFF_PTR = (uchar_ptr)temp_ptr;   

   /* Save the PCCard stream */
   info_ptr->PCCARD_STREAM = pccard_stream;


   /* Get memory locations of the flash card */
   /* Register memory */
   addr_info.OFFSET    = PCFLASH_REG_BASE;
   addr_info.TYPE      = APCCARD_COMMON_SPACE;
#if APCCARD_BUS_WIDTH == 2
   addr_info.BANK_SIZE = 32;
   addr_info.PORT_SIZE = 16;
#else
   addr_info.BANK_SIZE = 16;
   addr_info.PORT_SIZE = 8;
#endif
   _io_ioctl(pccard_stream, APCCARD_IOCTL_GET_ADDR_SPACE, (pointer)&addr_info);
   info_ptr->ATA_REG_PTR  = (uchar_ptr)addr_info.ADDRESS;

   /* Data memory */
   addr_info.OFFSET    = PCFLASH_REG_BASE + PCFLASH_REG_DATA_BUF;
   addr_info.TYPE      = APCCARD_COMMON_SPACE;
   addr_info.BANK_SIZE = 0x400;
   addr_info.PORT_SIZE = 16;
   _io_ioctl(pccard_stream, APCCARD_IOCTL_GET_ADDR_SPACE, (pointer)&addr_info);
   info_ptr->ATA_DATA_PTR  = (uint_16_ptr)addr_info.ADDRESS;

   /* Perform a soft reset on the device */
   error = _io_apcflash_reset(info_ptr);
   if (error != PCFLASH_NO_ERROR) {
      _io_ioctl(info_ptr->PCCARD_STREAM, APCCARD_IOCTL_POWERDOWN_CARD, NULL);
      _io_ioctl(pccard_stream, APCCARD_IOCTL_FREE_ADDR_SPACE, (pointer)info_ptr->ATA_REG_PTR);
      _io_ioctl(pccard_stream, APCCARD_IOCTL_FREE_ADDR_SPACE, (pointer)info_ptr->ATA_DATA_PTR);
      _mem_free(temp_ptr);
      return(IO_ERROR);
   } /* Endif */

   /* Get information about the device */
   identify_ptr = (ATA_IDENTIFY_DEVICE_STRUCT_PTR)((pointer)temp_ptr);
   _io_apcflash_identify_device(info_ptr, (uchar_ptr)identify_ptr);

   /* Store the info in the state structure */
#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
   _mem_swap_endian((uchar_ptr)end_defn, &(identify_ptr->NUMBER_CYLINDERS));
   _mem_swap_endian((uchar_ptr)end_defn, &(identify_ptr->SECTORS_PER_TRACK));
   _mem_swap_endian((uchar_ptr)end_defn, &(identify_ptr->NUMBER_HEADS));
#endif
   num_sectors =  identify_ptr->NUMBER_CYLINDERS * identify_ptr->SECTORS_PER_TRACK
                   * identify_ptr->NUMBER_HEADS;

   info_ptr->NUM_SECTORS   = num_sectors;  
   info_ptr->SIZE          = num_sectors * info_ptr->SECTOR_SIZE;

   info_ptr->NUMBER_OF_HEADS   = (uint_32)identify_ptr->NUMBER_HEADS;
   info_ptr->NUMBER_OF_TRACKS  = (uint_32)identify_ptr->NUMBER_CYLINDERS;
   info_ptr->SECTORS_PER_TRACK = (uint_32)identify_ptr->SECTORS_PER_TRACK;

   return(MQX_OK);   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_close
* Returned Value   : ERROR CODE
* Comments         : Closes the PC Card flash driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_apcflash_close
   (
      /* [IN] the file handle for the device being closed */
      FILE_DEVICE_STRUCT_PTR fd_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   io_dev_ptr = fd_ptr->DEV_PTR;
   IO_PCFLASH_STRUCT_PTR  info_ptr = (IO_PCFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   /* power down card */
   _io_ioctl(info_ptr->PCCARD_STREAM, APCCARD_IOCTL_POWERDOWN_CARD, NULL);

   _io_ioctl(info_ptr->PCCARD_STREAM, APCCARD_IOCTL_FREE_ADDR_SPACE, 
      (uint_32_ptr)&info_ptr->ATA_DATA_PTR);
   _io_ioctl(info_ptr->PCCARD_STREAM, APCCARD_IOCTL_FREE_ADDR_SPACE, 
      (pointer)&info_ptr->ATA_REG_PTR);

   _mem_free((pointer)info_ptr->TEMP_BUFF_PTR);
   info_ptr->TEMP_BUFF_PTR = NULL;

   return(MQX_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_read
* Returned Value   : number of bytes read
* Comments         : Reads data from the PC Card flash device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_apcflash_read
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR   fd_ptr,

      /* [IN] where the newly-read bytes are to be stored */
      char_ptr                 data_ptr,

      /* [IN] the number of bytes to read */
      _mqx_int                 num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   io_dev_ptr = fd_ptr->DEV_PTR;
   IO_PCFLASH_STRUCT_PTR  info_ptr = (IO_PCFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   uint_32                sector_size;
   uint_32                sector_loc;
   uint_32                offset;
   uint_32                remains;
   uint_32                processed;
   uint_32                temp;
    int_32                results;

   _lwsem_wait(&info_ptr->LWSEM);
   
   /* Is there a card present? */
   _io_ioctl(info_ptr->PCCARD_STREAM, APCCARD_IOCTL_IS_CARD_INSERTED, &temp);
   if ((boolean)temp == FALSE) {
      fd_ptr->ERROR = IO_ERROR_READ_ACCESS;
      _lwsem_post(&info_ptr->LWSEM);
      return(IO_ERROR);
   } /* Endif */

   if (info_ptr->BLOCK_MODE) {
      results = _io_apcflash_read_write_blocks(fd_ptr, info_ptr, data_ptr, 
         num, FALSE);
      _lwsem_post(&info_ptr->LWSEM);
      return results;
   } /* Endif */

   /* Read beyond end of the media treated as an error */
   if (fd_ptr->LOCATION >= info_ptr->SIZE) {
      fd_ptr->ERROR = IO_ERROR_READ_ACCESS;
      _lwsem_post(&info_ptr->LWSEM);
      return(IO_ERROR);
   } /* Endif */

   /* Too long read reaching end of media is truncated */
   if ((num + fd_ptr->LOCATION) > info_ptr->SIZE) {
      fd_ptr->ERROR = IO_ERROR_READ_ACCESS;
      num = (int_32)(info_ptr->SIZE - fd_ptr->LOCATION);
   } /* Endif */

   sector_size  = info_ptr->SECTOR_SIZE;
   sector_loc   = fd_ptr->LOCATION / info_ptr->SECTOR_SIZE; 
   offset       = fd_ptr->LOCATION - sector_size * sector_loc;           
   processed    = 0;
      
   /*
   ** We have three conditions:
   **   1. The read is contained in one PCflash sector
   **   2. The read is contained in two adjacent PCflash sectors
   **   3. The read spans many PCflash sectors   
   **
   ** In case 1, it is possible to have a partial PCflash sector. 
   ** In case 2, it is possible that both the end and the start are only 
   **  partial PCflash sectors.
   ** In case 3(really a subset of case 2), the start and end may be partial
   **  but the others will all be complete PCflash sectors.
   */
      
   if (offset > 0) {
      /* First sector is partial */
      remains = info_ptr->SECTOR_SIZE - offset;
      if (remains > num) {
         remains = num;
      }/* Endif */
      results = _io_apcflash_read_partial_sector(info_ptr, sector_loc, offset, remains, (uchar_ptr)data_ptr);
      if (results == IO_ERROR)
      {
         fd_ptr->ERROR = IO_ERROR_WRITE;
         _lwsem_post(&info_ptr->LWSEM);
         return(results);
      } else {
         fd_ptr->LOCATION += results;
         data_ptr         += results;
         processed        += results;
         num              -= results;
         sector_loc++;
      } /* Endif */
   } /* Endif */
      
   /* Whole sectors in the middle */
   while (num >= sector_size)
   {
      if (_io_apcflash_read_sector(info_ptr, sector_loc, (uchar_ptr)data_ptr) == PCFLASH_NO_ERROR) {
         fd_ptr->LOCATION += sector_size;
         data_ptr         += sector_size;
         processed        += sector_size;
         num              -= sector_size;
         sector_loc++;
      } else {
         fd_ptr->ERROR = IO_ERROR_WRITE;
         _lwsem_post(&info_ptr->LWSEM);
         return(IO_ERROR);
      } /* Endif */
   }
      
   if (num > 0) {
      /* Last partial sector */
      results  = _io_apcflash_read_partial_sector(info_ptr, sector_loc, 0, num, (uchar_ptr)data_ptr);
      if (results == IO_ERROR) {
         fd_ptr->ERROR = IO_ERROR_WRITE;
         _lwsem_post(&info_ptr->LWSEM);
         return(results);
      } else {
         fd_ptr->LOCATION += results;
         processed += results;
      } /* Endif */
   } /* Endif */

   _lwsem_post(&info_ptr->LWSEM);
   return(processed);
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_write
* Returned Value   : number of bytes written
* Comments         : Writes data to the PC Card flash device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_apcflash_write
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] where the outgoing data is store */
      char_ptr               data_ptr,

      /* [IN] the number of bytes to output */
      _mqx_int               num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   io_dev_ptr = fd_ptr->DEV_PTR;
   IO_PCFLASH_STRUCT_PTR  info_ptr = (IO_PCFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   uint_32                sector_size;
   uint_32                sector_loc;
   uint_32                offset;
   uint_32                remains;
   uint_32                processed;
   uint_32                temp;
    int_32                results;

   _lwsem_wait(&info_ptr->LWSEM);
   
   /* Is there a card present? */
   _io_ioctl(info_ptr->PCCARD_STREAM, APCCARD_IOCTL_IS_CARD_INSERTED, &temp);
   if ((boolean)temp == FALSE) {
      fd_ptr->ERROR = IO_ERROR_READ_ACCESS;
      _lwsem_post(&info_ptr->LWSEM);
      return(IO_ERROR);
   } /* Endif */

   if (info_ptr->BLOCK_MODE) {
      results = _io_apcflash_read_write_blocks(fd_ptr, info_ptr, data_ptr, 
         num, TRUE);
      _lwsem_post(&info_ptr->LWSEM);
      return results;
   } /* Endif */

   /* Write beyond end of the media treated as an error */
   if (fd_ptr->LOCATION >= info_ptr->SIZE) {
      fd_ptr->ERROR = IO_ERROR_WRITE_ACCESS;
      _lwsem_post(&info_ptr->LWSEM);
      return(IO_ERROR);
   } /* Endif */

   /* Too long write reaching end of media is truncated */
   if ((num + fd_ptr->LOCATION) > info_ptr->SIZE) {
      fd_ptr->ERROR = IO_ERROR_WRITE_ACCESS;
      num = (int_32)(info_ptr->SIZE - fd_ptr->LOCATION);
   } /* Endif */

   sector_size  = info_ptr->SECTOR_SIZE;
   sector_loc   = fd_ptr->LOCATION / info_ptr->SECTOR_SIZE; 
   offset       = fd_ptr->LOCATION - sector_size * sector_loc;           
   processed    = 0;

   /*
   ** We have three conditions:
   **   1. The write is contained in one PCflash sector
   **   2. The write is contained in two adjacent PCflash sectors
   **   3. The write spans many PCflash sectors   
   **
   ** In case 1, it is possible to have a partial PCflash sector. 
   ** In case 2, it is possible that both the end and the start are only 
   **  partial PCflash sectors.
   ** In case 3(really a subset of case 2), the start and end may be partial
   **  but the others will all be complete PCflash sectors.
   */
      
   if (offset > 0) {
      /* First sector is partial */
      remains = info_ptr->SECTOR_SIZE - offset;
      if (remains > num) {
         remains = num;
      }/* Endif */
      results = _io_apcflash_write_partial_sector(info_ptr, sector_loc, offset, remains, (uchar_ptr)data_ptr);
      if (results == IO_ERROR)
      {
         fd_ptr->ERROR = IO_ERROR_WRITE;
         _lwsem_post(&info_ptr->LWSEM);
         return(results);
      } else {
         fd_ptr->LOCATION += results;
         data_ptr         += results;
         processed        += results;
         num              -= results;
         sector_loc++;
      } /* Endif */
   } /* Endif */
      
   /* Whole sectors in the middle */
   while (num >= sector_size)
   {
      if (_io_apcflash_write_sector(info_ptr, sector_loc, (uchar_ptr)data_ptr) == PCFLASH_NO_ERROR) {
         fd_ptr->LOCATION += sector_size;
         data_ptr         += sector_size;
         processed        += sector_size;
         num              -= sector_size;
         sector_loc++;
      } else {
         fd_ptr->ERROR = IO_ERROR_WRITE;
         _lwsem_post(&info_ptr->LWSEM);
         return(IO_ERROR);
      } /* Endif */
   }
      
   if (num > 0) {
      /* Last partial sector */
      results  = _io_apcflash_write_partial_sector(info_ptr, sector_loc, 0, num, (uchar_ptr)data_ptr);
      if (results == IO_ERROR) {
         fd_ptr->ERROR = IO_ERROR_WRITE;
         _lwsem_post(&info_ptr->LWSEM);
         return(results);
      } else {
         fd_ptr->LOCATION += results;
         processed += results;
      } /* Endif */
   } /* Endif */

   _lwsem_post(&info_ptr->LWSEM);
   return(processed);

} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*-------------------------------------------------------------------------*/

_mqx_int _io_apcflash_ioctl
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint              cmd,

      /* [IN] the ioctl parameters */
      pointer                input_param_ptr
   )
{ /* Body */
   PCFLASH_DRIVE_INFO_STRUCT_PTR drive_info_ptr;
   IO_DEVICE_STRUCT_PTR          io_dev_ptr = fd_ptr->DEV_PTR;
   IO_PCFLASH_STRUCT_PTR         info_ptr = 
      (IO_PCFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   int_32                        result = MQX_OK;
   uint_32_ptr                   param_ptr = input_param_ptr;

   switch (cmd) {
      case PCFLASH_IOCTL_IS_CARD_INSERTED:
         _lwsem_wait(&info_ptr->LWSEM);
         /* Is there a card present? (TRUE/FALSE) */
         _io_ioctl(info_ptr->PCCARD_STREAM, APCCARD_IOCTL_IS_CARD_INSERTED, param_ptr);
         _lwsem_post(&info_ptr->LWSEM);
         break;     
      case IO_IOCTL_GET_NUM_SECTORS:
      case PCFLASH_IOCTL_GET_NUM_SECTORS:
         *param_ptr = info_ptr->NUM_SECTORS;
         break;
      case IO_IOCTL_GET_BLOCK_SIZE:
      case PCFLASH_IOCTL_GET_SECTOR_SIZE:
         *param_ptr = info_ptr->SECTOR_SIZE;
         break;
      case IO_IOCTL_DEVICE_IDENTIFY:
         param_ptr[0] = IO_DEV_TYPE_PHYS_PCFLASH;
         param_ptr[1] = IO_DEV_TYPE_LOGICAL_MFS;
         param_ptr[2] = IO_DEV_ATTR_ERASE | IO_DEV_ATTR_POLL
                         | IO_DEV_ATTR_READ | IO_DEV_ATTR_REMOVE
                         | IO_DEV_ATTR_SEEK | IO_DEV_ATTR_WRITE;
         if (info_ptr->BLOCK_MODE) {
            param_ptr[2] |= IO_DEV_ATTR_BLOCK_MODE;
         } /* Endif */
         break;
      case PCFLASH_IOCTL_GET_DRIVE_PARAMS:
         drive_info_ptr = (PCFLASH_DRIVE_INFO_STRUCT_PTR)((pointer)param_ptr);
         drive_info_ptr->NUMBER_OF_HEADS   = info_ptr->NUMBER_OF_HEADS; 
         drive_info_ptr->NUMBER_OF_TRACKS  = info_ptr->NUMBER_OF_TRACKS;
         drive_info_ptr->SECTORS_PER_TRACK = info_ptr->SECTORS_PER_TRACK;
         break;
      case PCFLASH_IOCTL_SET_BLOCK_MODE:
         info_ptr->BLOCK_MODE = TRUE;
         break;
      default:
         result = IO_ERROR_INVALID_IOCTL_CMD;
         break;
   } /* Endswitch */
   return(result);

} /* Endbody */


/* Private functions */
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_read_sector
* Returned Value   : error code
* Comments         : 
*
* 
*END*----------------------------------------------------------------------*/

uint_32 _io_apcflash_read_sector
   (
      /* [IN] PC Flash state structure */
      IO_PCFLASH_STRUCT_PTR  info_ptr,

      /* [IN] The sector number to read */
      uint_32                sector,

      /* [IN] Location to read data into */
      uchar_ptr              data_ptr 
   )
{ /* Body */

#if APCCARD_BUS_WIDTH == 2
   volatile uint_16 _PTR_       ata_reg16_ptr = (uint_16_ptr)info_ptr->ATA_REG_PTR;
#else
   volatile uchar   _PTR_       ata_reg_ptr = info_ptr->ATA_REG_PTR;
#endif
   /* data register access is always 16 bit, regardless of actual bus width, silicon eventually perform 2 access cycles */ 
   volatile uint_16 _PTR_       ata_data16_ptr = ((uint_16_ptr)info_ptr->ATA_REG_PTR)+PCFLASH_REG16_DATA;

   uint_16 _PTR_                data16_ptr = (uint_16_ptr)data_ptr;
   uint_32                      data16_size = info_ptr->SECTOR_SIZE / 2;

   uint_16                      temp;
   
   if (sector > info_ptr->NUM_SECTORS) {
      return(PCFLASH_INVALID_SECTOR);
   } /* Endif */
   
   /* Make sure device isn't busy */
   if (_io_apcflash_status_timeout(info_ptr, ATA_BSY_DEFAULT_TIMEOUT, ATA_STAT_DRDY | ATA_STAT_DSC)) {
      return(PCFLASH_READ_ERROR);
   } /* Endif */
   
   /*
    * Setup for Logical Block Addressing (LBA)
    * A7 - A0 reside in the sector register
    * A15 - A8 reside in the cylinder low register
    * A23 - A16 reside in the cylinder high register
    * A27 - A24 reside in the drive/head register
    */
    
#if APCCARD_BUS_WIDTH == 2   
   ata_reg16_ptr[PCFLASH_REG16_SECTOR] = ((uint_16)(0x000000FF & sector) << 8) | (uint_16)1 ;
   ata_reg16_ptr[PCFLASH_REG16_CYLINDER]  = ((uint_16)((0x00FF0000 & sector) >> 16) << 8) | (uint_16)((0x0000FF00 & sector) >> 8);      
   ata_reg16_ptr[PCFLASH_REG16_DHC] = (ATA_READ_SECTOR << 8) | 0xA0 | ATA_DRIVE_REG_LBA | (info_ptr->DRIVE << 4) | (uint_16)((0x0F000000 & sector) >> 24);
#else
   ata_reg_ptr[PCFLASH_REG_SECTOR_COUNT]   = 1;
   ata_reg_ptr[PCFLASH_REG_SECTOR]         = (uchar)(0x000000FF & sector);
   ata_reg_ptr[PCFLASH_REG_CYLINDER_LOW]   = (uchar)((0x0000FF00 & sector) >> 8);
   ata_reg_ptr[PCFLASH_REG_CYLINDER_HIGH]  = (uchar)((0x00FF0000 & sector) >> 16);
   ata_reg_ptr[PCFLASH_REG_CARD_DRIVE_HEAD] = 0xA0 | ATA_DRIVE_REG_LBA | (info_ptr->DRIVE << 4) | (uchar)((0x0F000000 & sector) >> 24);
   ata_reg_ptr[PCFLASH_REG_COMMAND] = ATA_READ_SECTOR;
#endif
   
   /* Wait for data request flag */
   if (_io_apcflash_status_timeout(info_ptr, ATA_BSY_DEFAULT_TIMEOUT, ATA_STAT_DRQ)) {
      return(PCFLASH_READ_ERROR);
   }
   
   /* Read the sector buffer */

#if PSP_MEMORY_ACCESSING_CAPABILITY != 8
   if ((uint_32)data_ptr & 1) {
      /* Odd address, byte by byte access needed */
      while (data16_size--) {
         temp = *ata_data16_ptr;
#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
         *data_ptr++ = (temp & 0xFF);
         *data_ptr++ = (temp & 0xFF00) >> 8;
#else
         *data_ptr++ = (temp & 0xFF00) >> 8;
         *data_ptr++ = (temp & 0xFF);
#endif            
      }
   } else
#endif      

   {
      while (data16_size--) {
#if APCCARD_BUS_WIDTH == 2 && PSP_ENDIAN == MQX_BIG_ENDIAN 
         temp = *ata_data16_ptr;     
         *data16_ptr++ = _PSP_SWAP2BYTE(temp);
#else
         *data16_ptr++ = *ata_data16_ptr;
#endif            
      }
   }
          
   return(PCFLASH_NO_ERROR);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_read_partial_sector
* Returned Value   : uint_32 - number of bytes read if successful,
*                    IO_ERROR otherwise
* Comments         : Read a partial pcflash sector  
*END*----------------------------------------------------------------------*/

int_32 _io_apcflash_read_partial_sector
   (
      IO_PCFLASH_STRUCT_PTR  info_ptr,
      uint_32                sector_number,
      uint_32                offset_in_sector,
      uint_32                remains_in_sector,
      uchar_ptr              dst_ptr
   )
{ /* Body */
   uchar_ptr               tmp_ptr    = info_ptr->TEMP_BUFF_PTR;
   uint_32                 error;
         
   /* Read the sector into temporary buffer */
   error = _io_apcflash_read_sector(info_ptr, sector_number, tmp_ptr);
   if (error != PCFLASH_NO_ERROR) {
      return(IO_ERROR);
   } /* Endif */ 
   
   /* Copy only the part of the sector we want */
   _mem_copy(tmp_ptr + offset_in_sector, dst_ptr, remains_in_sector);

   return(remains_in_sector);   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_write_sector
* Returned Value   : error code
* Comments         : 
*
* 
*END*----------------------------------------------------------------------*/

uint_32 _io_apcflash_write_sector
   (
      /* [IN] PC Flash state structure */
      IO_PCFLASH_STRUCT_PTR  info_ptr,

      /* [IN] The sector number to write */
      uint_32                sector,

      /* [IN] Source data location */
      uchar_ptr              data_ptr 
   )
{ /* Body */

#if APCCARD_BUS_WIDTH == 2
   volatile uint_16 _PTR_       ata_reg16_ptr = (uint_16_ptr)info_ptr->ATA_REG_PTR;
#else
   volatile uchar   _PTR_       ata_reg_ptr = info_ptr->ATA_REG_PTR;
#endif
   /* data register access is always 16 bit, regardless of actual bus width, silicon eventually perform 2 access cycles */ 
   volatile uint_16 _PTR_       ata_data16_ptr = ((uint_16_ptr)info_ptr->ATA_REG_PTR)+PCFLASH_REG16_DATA;

   uint_16 _PTR_                data16_ptr = (uint_16_ptr)data_ptr;
   uint_32                      data16_size = info_ptr->SECTOR_SIZE / 2;

   uint_16                      temp;
   
   if (sector > info_ptr->NUM_SECTORS) {
      return(PCFLASH_INVALID_SECTOR);
   } /* Endif */
   
   /* Make sure device isn't busy */
   if (_io_apcflash_status_timeout(info_ptr, ATA_BSY_DEFAULT_TIMEOUT, ATA_STAT_DRDY | ATA_STAT_DSC)) {
      return(PCFLASH_WRITE_ERROR);
   } /* Endif */
   
   /*
    * Setup for Logical Block Addressing (LBA)
    * A7 - A0 reside in the sector register
    * A15 - A8 reside in the cylinder low register
    * A23 - A16 reside in the cylinder high register
    * A27 - A24 reside in the drive/head register
    */
    
#if APCCARD_BUS_WIDTH == 2   
   ata_reg16_ptr[PCFLASH_REG16_SECTOR] = ((uint_16)(0x000000FF & sector) << 8) | (uint_16)1 ;
   ata_reg16_ptr[PCFLASH_REG16_CYLINDER]  = ((uint_16)((0x00FF0000 & sector) >> 16) << 8) | (uint_16)((0x0000FF00 & sector) >> 8);      
   ata_reg16_ptr[PCFLASH_REG16_DHC] = (ATA_WRITE_SECTOR << 8) | 0xA0 | ATA_DRIVE_REG_LBA | (info_ptr->DRIVE << 4) | (uint_16)((0x0F000000 & sector) >> 24);
#else
   ata_reg_ptr[PCFLASH_REG_SECTOR_COUNT]   = 1;
   ata_reg_ptr[PCFLASH_REG_SECTOR]         = (uchar)(0x000000FF & sector);
   ata_reg_ptr[PCFLASH_REG_CYLINDER_LOW]   = (uchar)((0x0000FF00 & sector) >> 8);
   ata_reg_ptr[PCFLASH_REG_CYLINDER_HIGH]  = (uchar)((0x00FF0000 & sector) >> 16);
   ata_reg_ptr[PCFLASH_REG_CARD_DRIVE_HEAD] = 0xA0 | ATA_DRIVE_REG_LBA | (info_ptr->DRIVE << 4) | (uchar)((0x0F000000 & sector) >> 24);
   ata_reg_ptr[PCFLASH_REG_COMMAND] = ATA_WRITE_SECTOR;
#endif
      
   /* Wait for data request flag */
   if (_io_apcflash_status_timeout(info_ptr, ATA_BSY_DEFAULT_TIMEOUT, ATA_STAT_DRQ)) {
      return(PCFLASH_WRITE_ERROR);
   } /* Endif */

#if PSP_MEMORY_ACCESSING_CAPABILITY != 8
   if ((uint_32)data_ptr & 1) {
      /* Odd address, byte by byte access needed */
      while (data16_size--) {
#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
         temp = *data_ptr++;
         temp |= (*data_ptr++) << 8;
#else
         temp = (*data_ptr++) << 8;
         temp |= *data_ptr++;
#endif            
         *ata_data16_ptr = temp;;
      }
   } else /* Aplies to following block outside conditional compilation */
#endif

   {
      while (data16_size--) {
#if APCCARD_BUS_WIDTH == 2 && PSP_ENDIAN == MQX_BIG_ENDIAN 
         temp = *data16_ptr++;     
         *ata_data16_ptr = _PSP_SWAP2BYTE(temp);
#else
         *ata_data16_ptr = *data16_ptr++;
#endif            
      }
   }

   /* Wait for device to finish writing data */
   if (_io_apcflash_status_timeout(info_ptr, ATA_BSY_DEFAULT_TIMEOUT, ATA_STAT_DRDY | ATA_STAT_DSC)) {
      return(PCFLASH_WRITE_ERROR);
   } /* Endif */

#if APCCARD_BUS_WIDTH == 2   
   temp = ata_reg16_ptr[PCFLASH_REG16_ERROR] >> 8;
#else
   temp = ata_reg_ptr[PCFLASH_REG_ERROR];
#endif

   if (temp & ATA_ERR_MASK) {
      return(PCFLASH_WRITE_ERROR);
   } /* Endif */

   return(PCFLASH_NO_ERROR);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_write_partial_sector
* Returned Value   : uint_32 - number of bytes written if successful,
*                    IO_ERROR otherwise
* Comments         : Writes a partial pcflash sector while preserving contents of
*                    unused portions of the sector
* 
*END*----------------------------------------------------------------------*/

int_32 _io_apcflash_write_partial_sector
   (
      IO_PCFLASH_STRUCT_PTR  info_ptr,
      uint_32                sector_number,
      uint_32                offset_in_sector,
      uint_32                remains_in_sector,
      uchar_ptr              src_ptr
   )
{ /* Body */
   uchar_ptr               tmp_ptr    = info_ptr->TEMP_BUFF_PTR;
   uint_32                 error;
         
   /* Read the sector into temporary buffer */
   error = _io_apcflash_read_sector(info_ptr, sector_number, tmp_ptr);
   if (error != PCFLASH_NO_ERROR) {
      return(IO_ERROR);
   } /* Endif */
   
   /* Write new data into temporary buffer */
   _mem_copy(src_ptr, tmp_ptr + offset_in_sector, remains_in_sector);
   
   /* Write the newly modified ram sector back into pcflash */
   if (_io_apcflash_write_sector(info_ptr, sector_number, tmp_ptr) == PCFLASH_NO_ERROR) {
      return(remains_in_sector);
   } else {
      return(IO_ERROR);
   } /* Endif */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_identify_device
* Returned Value   : error code
* Comments         : 
*
* 
*END*----------------------------------------------------------------------*/

uint_32 _io_apcflash_identify_device
   (
      /* [IN] PC Flash state structure */
      IO_PCFLASH_STRUCT_PTR  info_ptr,

      /* [IN] Location to read data into */
      uchar_ptr              data_ptr 
   )
{ /* Body */

#if APCCARD_BUS_WIDTH == 2
   volatile uint_16 _PTR_       ata_reg16_ptr = (uint_16_ptr)info_ptr->ATA_REG_PTR;
#else
   volatile uchar   _PTR_       ata_reg_ptr = info_ptr->ATA_REG_PTR;
#endif
   /* data register access is always 16 bit, regardless of actual bus width, silicon eventually perform 2 access cycles */ 
   volatile uint_16 _PTR_       ata_data16_ptr = ((uint_16_ptr)info_ptr->ATA_REG_PTR)+PCFLASH_REG16_DATA;

   uint_16 _PTR_                data16_ptr = (uint_16_ptr)data_ptr;
   uint_32                      data16_size = info_ptr->SECTOR_SIZE / 2;

   uint_16                      temp;
   
   /* Make sure device isn't busy */
   if (_io_apcflash_status_timeout(info_ptr, ATA_BSY_DEFAULT_TIMEOUT, ATA_STAT_DRDY | ATA_STAT_DSC)) {
      return(PCFLASH_READ_ERROR);
   } /* Endif */
  
#if APCCARD_BUS_WIDTH == 2
   ata_reg16_ptr[PCFLASH_REG16_DHC] = 0xA0 | (info_ptr->DRIVE << 4) | (ATA_IDENTIFY_DEVICE << 8);   
#else
   ata_reg_ptr[PCFLASH_REG_CARD_DRIVE_HEAD] = 0xA0 | (info_ptr->DRIVE << 4);
   ata_reg_ptr[PCFLASH_REG_COMMAND] = ATA_IDENTIFY_DEVICE;
#endif

   /* Wait for device to become free */
   if (_io_apcflash_status_timeout(info_ptr, ATA_BSY_DEFAULT_TIMEOUT, ATA_STAT_DRQ)) {
      return(PCFLASH_READ_ERROR);
   } /* Endif */

#if PSP_MEMORY_ACCESSING_CAPABILITY != 8
   if ((uint_32)data_ptr & 1) {
      /* Odd address, byte by byte access needed */
      while (data16_size--) {
         temp = *ata_data16_ptr;
#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
         *data_ptr++ = (temp & 0xFF);
         *data_ptr++ = (temp & 0xFF00) >> 8;
#else
         *data_ptr++ = (temp & 0xFF00) >> 8;
         *data_ptr++ = (temp & 0xFF);
#endif            
      }
   } else
#endif      

   {
      while (data16_size--) {
#if APCCARD_BUS_WIDTH == 2 && PSP_ENDIAN == MQX_BIG_ENDIAN 
         temp = *ata_data16_ptr;     
         *data16_ptr++ = _PSP_SWAP2BYTE(temp);
#else
         *data16_ptr++ = *ata_data16_ptr;
#endif            
      }
   }

   return(PCFLASH_NO_ERROR);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_reset
* Returned Value   : error code
* Comments         : 
* 
*END*----------------------------------------------------------------------*/

uint_32 _io_apcflash_reset
   (
      /* [IN] PC Flash state structure */
      IO_PCFLASH_STRUCT_PTR  info_ptr
   )
{ /* Body */

#if APCCARD_BUS_WIDTH == 2
   volatile uint_16 _PTR_       ata_reg16_ptr = (uint_16_ptr)info_ptr->ATA_REG_PTR;
#else
   volatile uchar   _PTR_       ata_reg_ptr = info_ptr->ATA_REG_PTR;
#endif

   MQX_TICK_STRUCT              start, current;
   boolean                      overflow;
   
   /* Perform soft reset */
#if APCCARD_BUS_WIDTH == 2
   ata_reg16_ptr[PCFLASH_REG16_DEV_CNTRL] = ATA_DEV_CNTL_SRST;
#else
   ata_reg_ptr[PCFLASH_REG_DEV_CNTRL] = ATA_DEV_CNTL_SRST;
#endif
   
   /* wait 5 ms */ 
   _time_delay(5);
   
   /* Bring device out of reset */
#if APCCARD_BUS_WIDTH == 2
   ata_reg16_ptr[PCFLASH_REG16_DEV_CNTRL] = 0;
#else
   ata_reg_ptr[PCFLASH_REG_DEV_CNTRL] = 0; 
#endif
   
   /* Wait for device to come out of reset */
   if (_io_apcflash_status_timeout(info_ptr, ATA_RST_TIMEOUT, ATA_STAT_DRDY | ATA_STAT_DSC)) {
      return(PCFLASH_HARDWARE_ERROR);
   } /* Endif */

   return(PCFLASH_NO_ERROR);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_status_timeout
* Returned Value   : TRUE if timed out or error, FALSE otherwise
* Comments         : Waits for non-busy status of CF card 
* 
*END*----------------------------------------------------------------------*/

boolean _io_apcflash_status_timeout
   (
      /* [IN] PC Flash state structure */
      IO_PCFLASH_STRUCT_PTR  info_ptr,
      /* [IN] Number of seconds to timeout */
      uint_32 timeout_val,
      /* [IN] Bit mask to wait for */
      uchar status_mask
   )
{ /* Body */

#if APCCARD_BUS_WIDTH == 2
   volatile uint_16 _PTR_       ata_reg16_ptr = (uint_16_ptr)info_ptr->ATA_REG_PTR;
#else
   volatile uchar   _PTR_       ata_reg_ptr = info_ptr->ATA_REG_PTR;
#endif

   MQX_TICK_STRUCT              start, current;
   boolean                      overflow;

   uchar                        status;

   /* check status and return ASAP if already ok */
#if APCCARD_BUS_WIDTH == 2
   status = (uchar)(ata_reg16_ptr[PCFLASH_REG16_STATUS] >> 8);
#else
   status = ata_reg_ptr[PCFLASH_REG_STATUS];
#endif
   if ((status & (ATA_STAT_BSY | status_mask)) == status_mask) return(FALSE); /* Ok */

   _time_get_elapsed_ticks(&start);
   do {

#if APCCARD_BUS_WIDTH == 2
      status = (uchar)(ata_reg16_ptr[PCFLASH_REG16_STATUS] >> 8);
#else
      status = ata_reg_ptr[PCFLASH_REG_STATUS];
#endif
      if ((status & (ATA_STAT_BSY | status_mask)) == status_mask) return(FALSE); /* Ok */
      _time_get_elapsed_ticks(&current);

   } while (_time_diff_seconds(&current, &start, &overflow) < timeout_val || overflow);

   return(TRUE); /* Timeout */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_apcflash_read_write_blocks
* Returned Value   : error or number of blocks read/written
* Comments         : This function is used to read/write blocks when driver
*   is in block mode
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_apcflash_read_write_blocks
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR   fd_ptr,

      /* [IN] device info */
      IO_PCFLASH_STRUCT_PTR    info_ptr,

      /* [IN] pointer to data buffer */
      char_ptr                 data_ptr,

      /* [IN] the number of blocks to read/write */
      _mqx_int                 num,

      /* [IN] read/write mode */
      boolean                  write
     
   )
{ /* Body */
   uint_32    i;
   _mqx_int   error_code;
   uint_32 (_CODE_PTR_ rw_func)(IO_PCFLASH_STRUCT_PTR, uint_32, uchar_ptr);

   if (write) {
      error_code = IO_ERROR_WRITE_ACCESS;
      rw_func    = _io_apcflash_write_sector;
   } else {
      error_code = IO_ERROR_READ_ACCESS;
      rw_func    = _io_apcflash_read_sector;
   } /* Endif */


   if (fd_ptr->LOCATION >= info_ptr->NUM_SECTORS) {
      fd_ptr->ERROR = error_code;
      return(IO_ERROR);
   } else {
      if ((num + fd_ptr->LOCATION) > info_ptr->NUM_SECTORS) {
         fd_ptr->ERROR = error_code;
         num = (int_32)(info_ptr->NUM_SECTORS - fd_ptr->LOCATION);
      } /* Endif */
      
      /* Read/write all the sectors, one at a time */
      for (i = 0; i < num; i++) {
         if (rw_func(info_ptr, fd_ptr->LOCATION, (uchar_ptr)data_ptr) == 
            PCFLASH_NO_ERROR) 
         {
            fd_ptr->LOCATION++;
            data_ptr += info_ptr->SECTOR_SIZE;
         } else {
            fd_ptr->ERROR = error_code;
            break;
         } /* Endif */
      } /* Endfor */

   } /* Endif */
      
   return(i); /* Number of sectors read/written */ 
   
} /* Endbody */
#endif /* Advanced PCMCIA */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_tftp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_tftp.c$
* $Version : 3.8.13.0$
* $Date    : Oct-6-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h"
        
         
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_TFTP_client
*  Returned Value:  none
*  Comments  :  SHELL utility to TFTP to or from a host
*  Usage:  tftp host get source [destination] [mode] 
*
*END*-----------------------------------------------------------------*/

int_32  Shell_TFTP_client(int_32 argc, char_ptr argv[] )
{
   _ip_address          hostaddr;
   char                 hostname[MAX_HOSTNAMESIZE]="";
   char_ptr             file_ptr;
   uint_32              tftp_handle, buffer_size,byte_number;
   uchar_ptr            buffer_ptr;
   TFTP_DATA_STRUCT     tftp_data;
   MQX_FILE_PTR         fd;
   int_32               error;
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;
   char                 path[SHELL_MAX_FILELEN];  
   boolean              trans = FALSE;
   
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
   
      if ((argc >= 3) && (argc <= 5))  {
         RTCS_resolve_ip_address( argv[1], &hostaddr, hostname, MAX_HOSTNAMESIZE ); 

         if (!hostaddr)  {
            printf("Unable to resolve host.\n");
            return_code = SHELL_EXIT_ERROR;
         } else  {
            tftp_data.SERVER   = hostaddr;
            tftp_data.FILENAME = argv[2];
            tftp_data.FILEMODE = "netascii";
            if (argc > 3)  {
               file_ptr = argv[3];
               if (argc > 4) {
                  tftp_data.FILEMODE = argv[4];
               } else {
                  tftp_data.FILEMODE = "netascii";
               }
            } else {
               file_ptr = argv[2];
            }
#if SHELLCFG_USES_MFS  
            
            Shell_create_prefixed_filename(path, file_ptr, argv);
            fd = fopen(path,"a");
            if (fd)  {
               printf("\nDownloading file %s from TFTP server: %s [%ld.%ld.%ld.%ld]\n",
                  tftp_data.FILENAME,hostname, IPBYTES(hostaddr));
               tftp_handle = (*FT_TFTP->OPEN)( (pointer) &tftp_data );
               if ( tftp_handle != RTCS_OK )  {
                  printf("\nError opening file %s\n",tftp_data.FILENAME);
                  return_code = SHELL_EXIT_ERROR;
               } else  {
                if (! (*FT_TFTP->EOFT)())  {
                   do {
                     buffer_ptr = (*FT_TFTP->READ)( &buffer_size );
                     if ((buffer_ptr != NULL) && (buffer_size))  {
                         fseek(fd, 0 , IO_SEEK_CUR);
                        _io_write(fd,buffer_ptr,buffer_size); 
                        trans = TRUE;
                     } else {
                   
                         switch (buffer_size) {
                         case 0:
                            // end of file
                           break;
                         case (RTCSERR_TFTP_ERROR + 1):
                            printf("\nFile %s not found\n", tftp_data.FILENAME);
                            break;
                         case (RTCSERR_TFTP_ERROR + 2):
                            printf("\nAccess violation\n");
                            break;
                         case (RTCSERR_TFTP_ERROR + 3):
                            printf("\nDisk full or allocation exceeded\n");
                            break;
                         case (RTCSERR_TFTP_ERROR + 4):
                            printf("\nIllegal TFTP operation\n");
                            break;
                         case (RTCSERR_TFTP_ERROR + 5):
                            printf("\nUnknown transfer ID\n");
                            break;
                         case (RTCSERR_TFTP_ERROR + 6):
                            printf("\nFile already exists\n");
                            break;
                         case (RTCSERR_TFTP_ERROR + 7):
                            printf("\nNo such user\n");
                            break;
                         default:
                            if(trans) 
                            {
                              trans =FALSE;
                              break;
                            }
                          else
                            printf("\nError reading file %s\n", tftp_data.FILENAME);
                         } /* Endswitch */
                        }
                     } while((buffer_ptr !=NULL) && buffer_size &&  (! (*FT_TFTP->EOFT)()) );
                     fclose(fd);
                  }
                  
                  error = (*FT_TFTP->CLOSE)();
                  
               }
               
            } else  {
               printf("\nError opening local file %s\n",file_ptr);
               return_code = SHELL_EXIT_ERROR;
            }
#else
            tftp_handle = (*FT_TFTP->OPEN)( (pointer) &tftp_data );
            if ( tftp_handle != RTCS_OK )  {
               printf("\nError opening file %s\n",tftp_data.FILENAME);
               return_code = SHELL_EXIT_ERROR;
            } else  {
               printf("SHELLCFG_USES_MFS is not set to 1 in user_config.h - file wont be written to disk\n");
            }
            error = (*FT_TFTP->CLOSE)();
#endif            
         }
      } else  {
         printf("Error, %s invoked with incorrect number of arguments\n", argv[0]);
         print_usage = TRUE;
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <host> <source> [<dest>] [<mode>]\n", argv[0]);
      } else  {
         printf("Usage: %s <host> <source> [<dest>] [<mode>]\n", argv[0]);
         printf("   <host>   = host ip address or name\n");
         printf("   <source> = remote file name\n");
         printf("   <dest>   = local file name\n");
         printf("   <mode>   = file transfer mode (netascii, etc.)\n");
      }
   }
   return return_code;
} /* Endbody */

#endif /* SHELLCFG_USES_RTCS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/rtc_mcf52xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtc_mcf52xx.c$
* $Version : 3.7.11.0$
* $Date    : Mar-16-2011$
*
* Comments:
*
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <rtc.h>
#include <mcf52xx_rtc.h>

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_register_write
* Returned Value   : previous value of RTC register
* Comments         :
*    This function writes given value to specified RTC register (size32 or size16)
*    according to RTC register access protocol.
*
*END*********************************************************************/
static uint_32 _rtc_register_write 
(
    /* [IN] pointer to RTC register to write to */
    pointer reg, 
    /* [IN] whether 16 or 32 bit register write */
    boolean size32, 
    /* [IN] value to assign */
    uint_32 value
)
{
    vuint_32 result;
    if (size32)
    {
        result = result;
        result = *(vuint_32 *)reg;
        *(vuint_32 *)reg = value;
    }
    else
    {
        result = result;
        result = *(vuint_16 *)reg;
        *(vuint_16 *)reg = value;
    }
    return result;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_register_read
* Returned Value   : actual RTC register value
* Comments         :
*    This function returns the value of given RTC register (size32 or size16)
*    according to RTC register access protocol.
*
*END*********************************************************************/
static uint_32 _rtc_register_read 
(
    /* [IN] pointer to RTC register to read from */
    pointer reg, 
    /* [IN] whether 16 or 32 bit register read */
    boolean size32
)
{
    vuint_32 result;
    if (size32)
    {
        result = result;
        result = *(vuint_32 *)reg;
        result = *(vuint_32 *)reg;
    }
    else
    {
        result = result;
        result = *(vuint_16 *)reg;
        result = *(vuint_16 *)reg;
    }
    return result;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_init
* Returned Value   : MQX error code
* Comments         :
*    This function (re)initializes/clears/enables RTC module.
*    If cleared, alarm happens after RTC overflow, stopwatch happens next minute.
*    Reset disables and clears all interrupts and stopwatch (even if cleared).
*
*END*********************************************************************/
uint_32 _rtc_init 
(
    /* [IN] flags identifying init operations */
    uint_32 flags
)
{
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    _rtc_register_write((pointer)&rtc->RTCCTL, TRUE, 0);
    if (flags & RTC_INIT_FLAG_CLEAR)
    {
        _rtc_register_write ((pointer)&rtc->DAYS, FALSE, MCF52XX_RTC_DAYS_DAYS(0));
        _rtc_register_write ((pointer)&rtc->SECONDS, TRUE, MCF52XX_RTC_SECONDS_WRITE(0));
        _rtc_register_write ((pointer)&rtc->HOURMIN, TRUE, MCF52XX_RTC_HOURMIN_HOURS_WRITE(0) | MCF52XX_RTC_HOURMIN_MINUTES_WRITE(0));
        _rtc_register_write ((pointer)&rtc->ALRM_DAY, FALSE, MCF52XX_RTC_ALRM_DAY_DAYS(0));
        _rtc_register_write ((pointer)&rtc->ALRM_SEC, TRUE, MCF52XX_RTC_ALRM_SEC_WRITE(0));
        _rtc_register_write ((pointer)&rtc->ALRM_HM, TRUE, MCF52XX_RTC_ALRM_HM_HOURS_WRITE(0) | MCF52XX_RTC_ALRM_HM_MINUTES_WRITE(0));
        _rtc_register_write ((pointer)&rtc->STPWCH, TRUE, MCF52XX_RTC_STPWCH_CNT(0));
    }
    if (flags & RTC_INIT_FLAG_RESET)
    {
        _rtc_register_write ((pointer)&rtc->RTCCTL, TRUE, MCF52XX_RTC_RTCCTL_SWR);
        _rtc_register_write ((pointer)&rtc->RTCIENR, TRUE, 0);
        _rtc_register_write ((pointer)&rtc->RTCISR, TRUE, 0xFFFFFFFF);
    }
    if (flags & RTC_INIT_FLAG_ENABLE)
    {
        _rtc_register_write ((pointer)&rtc->RTCCTL, TRUE, MCF52XX_RTC_RTCCTL_EN);
    }
    return MQX_OK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_isr
* Returned Value   : none
* Comments         :
*    This is template ISR for RTC module.
*
*END*********************************************************************/
void _rtc_isr 
(
    /* [IN] data pointer passed to interrupt */
    pointer ptr
)
{
    uint_32 tmp;
    VMCF52XX_RTC_STRUCT_PTR rtc = (VMCF52XX_RTC_STRUCT_PTR)ptr;
    tmp = _rtc_register_read ((pointer)&rtc->RTCISR, TRUE) & _rtc_register_read ((pointer)&rtc->RTCIENR, TRUE);
    if (tmp & MCF52XX_RTC_RTCISR_ALM)
    {
        // alarm interrupt
    }
    if (tmp & MCF52XX_RTC_RTCISR_SW)
    {
        // stopwatch interrupt
    }
    if (tmp & (MCF52XX_RTC_RTCISR_1HZ | MCF52XX_RTC_RTCISR_MIN | MCF52XX_RTC_RTCISR_HR | MCF52XX_RTC_RTCISR_DAY))
    {
        // time change interrupt (sec, min, hour, day)
    }
    _rtc_register_write ((pointer)&rtc->RTCISR, TRUE, tmp);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_int_install
* Returned Value   : MQX error code
* Comments         :
*    This function installs given ISR for RTC module.
*
*END*********************************************************************/
uint_32 _rtc_int_install 
(
    /* [IN] pointer to user ISR code */
    INT_ISR_FPTR isr
)
{
    INT_ISR_FPTR result;
    VMCF52XX_RTC_STRUCT_PTR rtc;
    if (NULL == isr) return MQX_INVALID_POINTER;
    rtc = _bsp_get_rtc_base_address ();
    result = _int_install_isr (_bsp_get_rtc_vector (), isr, (pointer)rtc);
    if ((INT_ISR_FPTR)NULL == result) return _task_get_error ();
    return MQX_OK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_int_enable
* Returned Value   : bitmask of new int enable state
* Comments         :
*    This function enables/disables RTC interrupts according to specified bitmask.
*
*END*********************************************************************/
uint_32 _rtc_int_enable 
(
    /* [IN] whether to enable or disable interrupts */
    boolean enable, 
    /* [IN] bitmask of affected interrupts */
    uint_32 bitmask
)
{
    uint_32 result = MQX_OK;
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    if (enable)
    {
        bitmask = _rtc_register_read ((pointer)&rtc->RTCIENR, TRUE) | bitmask;
        _rtc_register_write ((pointer)&rtc->RTCIENR, TRUE, bitmask);
        if (0 != bitmask) result = _mcf52xx_int_init (_bsp_get_rtc_vector (), BSP_RTC_INT_LEVEL, BSP_RTC_INT_SUBLEVEL, TRUE);
    }
    else
    {
        bitmask = _rtc_register_read ((pointer)&rtc->RTCIENR, TRUE) & (~ bitmask);
        _rtc_register_write ((pointer)&rtc->RTCIENR, TRUE, bitmask);
        if (0 == bitmask) result = _mcf52xx_int_init (_bsp_get_rtc_vector (), BSP_RTC_INT_LEVEL, BSP_RTC_INT_SUBLEVEL, FALSE);
    }
    if (MQX_OK != result) bitmask = 0;
    return bitmask;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_clear_requests
* Returned Value   : none
* Comments         :
*    This function clears RTC interrupt requests according to given bitmask.
*
*END*********************************************************************/
void _rtc_clear_requests 
(
    /* [IN] bitmask of affected interrupts */
    uint_32 bitmask
)
{
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    _rtc_register_write ((pointer)&rtc->RTCISR, TRUE, bitmask);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_status
* Returned Value   : bitmask of actual RTC interrupt requests + RTC enabled bit
* Comments         :
*    This function returns bitmask of pending RTC interrupt requests along
*    with RTC enabled bit (bit MCF52XX_RTC_RTCISR_EN).
*
*END*********************************************************************/
uint_32 _rtc_get_status 
(
    void
)
{
    uint_32 result;
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    result = _rtc_register_read ((pointer)&rtc->RTCISR, TRUE);
    if (_rtc_register_read ((pointer)&rtc->RTCCTL, TRUE) & MCF52XX_RTC_RTCCTL_EN)
    {
        result |= (uint_32)MCF52XX_RTC_RTCISR_EN;
    }
    return result;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_set_time
* Returned Value   : none
* Comments         :
*    This function sets the RTC time according to given time struct.
*
*END*********************************************************************/
void _rtc_set_time 
(
    /* [IN] given time to be set as RTC time */
    RTC_TIME_STRUCT_PTR time
)
{
    uint_32 tmp;
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    tmp = _rtc_register_write ((pointer)&rtc->RTCCTL, TRUE, 0);
    _rtc_register_write ((pointer)&rtc->DAYS, FALSE, MCF52XX_RTC_DAYS_DAYS(time->days));
    _rtc_register_write ((pointer)&rtc->SECONDS, TRUE, MCF52XX_RTC_SECONDS_WRITE(time->seconds));
    _rtc_register_write ((pointer)&rtc->HOURMIN, TRUE, MCF52XX_RTC_HOURMIN_HOURS_WRITE(time->hours) | MCF52XX_RTC_HOURMIN_MINUTES_WRITE(time->minutes));
    if (tmp & MCF52XX_RTC_RTCCTL_EN) 
    {
        _rtc_register_write ((pointer)&rtc->RTCCTL, TRUE, MCF52XX_RTC_RTCCTL_EN);
    }
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_time
* Returned Value   : none
* Comments         :
*    This function gets the RTC time and stores it in given time struct.
*
*END*********************************************************************/
void _rtc_get_time 
(
    /* [OUT] this parameter gets actual RTC time */
    RTC_TIME_STRUCT_PTR time
)
{
    vuint_32 hm;
    RTC_TIME_STRUCT tmp;
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    time->hours = 0xFF;
    do 
    {
        tmp.days = time->days;
        tmp.seconds = time->seconds;
        tmp.hours = time->hours;
        tmp.minutes = time->minutes;
        time->days = MCF52XX_RTC_DAYS_DAYS(_rtc_register_read ((pointer)&rtc->DAYS, FALSE));
        time->seconds = MCF52XX_RTC_SECONDS_READ(_rtc_register_read ((pointer)&rtc->SECONDS, TRUE));
        hm = _rtc_register_read ((pointer)&rtc->HOURMIN, TRUE);
        time->hours = MCF52XX_RTC_HOURMIN_HOURS_READ(hm);
        time->minutes = MCF52XX_RTC_HOURMIN_MINUTES_READ(hm);
    } while ((tmp.seconds != time->seconds) || (tmp.minutes != time->minutes) || (tmp.hours != time->hours) || (tmp.days != time->days));
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_set_alarm
* Returned Value   : none
* Comments         :
*    This function sets RTC alarm time according to given time struct.
*    Alarm happens a half second after match.
*
*END*********************************************************************/
void _rtc_set_alarm 
(
    /* [IN] time to be set as RTC alarm time */
    RTC_TIME_STRUCT_PTR time
)
{
    uint_32 tmp;
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    tmp = _rtc_register_read ((pointer)&rtc->RTCIENR, TRUE);
    _rtc_register_write ((pointer)&rtc->RTCIENR, TRUE, tmp & (~ MCF52XX_RTC_RTCIENR_ALM));
    _rtc_register_write ((pointer)&rtc->ALRM_DAY, FALSE, MCF52XX_RTC_ALRM_DAY_DAYS(time->days));
    _rtc_register_write ((pointer)&rtc->ALRM_SEC, TRUE, MCF52XX_RTC_ALRM_SEC_WRITE(time->seconds));
    _rtc_register_write ((pointer)&rtc->ALRM_HM, TRUE, MCF52XX_RTC_ALRM_HM_MINUTES_WRITE(time->minutes) | MCF52XX_RTC_ALRM_HM_HOURS_WRITE(time->hours));
    _rtc_clear_requests (MCF52XX_RTC_RTCISR_ALM);
    _rtc_register_write ((pointer)&rtc->RTCIENR, TRUE, tmp);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_alarm
* Returned Value   : none
* Comments         :
*    This function gets the RTC alarm time and stores it in given time struct.
*
*END*********************************************************************/
void _rtc_get_alarm 
(
    /* [OUT] this parameter gets the RTC alarm time */
    RTC_TIME_STRUCT_PTR time
)
{
    vuint_32 hm;
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    time->days = MCF52XX_RTC_ALRM_DAY_DAYS(_rtc_register_read ((pointer)&rtc->ALRM_DAY, FALSE));
    time->seconds = MCF52XX_RTC_ALRM_SEC_READ(_rtc_register_read ((pointer)&rtc->ALRM_SEC, TRUE));
    hm = _rtc_register_read ((pointer)&rtc->ALRM_HM, TRUE);
    time->minutes = MCF52XX_RTC_ALRM_HM_MINUTES_READ(hm);
    time->hours = MCF52XX_RTC_ALRM_HM_HOURS_READ(hm);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_set_stopwatch
* Returned Value   : none
* Comments         :
*    This function sets the RTC stopwatch decrementer value (minutes).
*    Stopwatch decrements each new RTC minute and stops (disables) at -1.
*
*END*********************************************************************/
void _rtc_set_stopwatch 
(
    /* [IN] number of minutes to countdown */
    uint_32 minutes
)
{
    uint_32 tmp;
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    tmp = _rtc_register_read ((pointer)&rtc->RTCIENR, TRUE);
    _rtc_register_write ((pointer)&rtc->RTCIENR, TRUE, tmp & (~ MCF52XX_RTC_RTCIENR_SW));
    _rtc_register_write ((pointer)&rtc->STPWCH, TRUE, MCF52XX_RTC_STPWCH_CNT(minutes));
    _rtc_clear_requests (MCF52XX_RTC_RTCISR_SW);
    _rtc_register_write ((pointer)&rtc->RTCIENR, TRUE, tmp);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_stopwatch
* Returned Value   : actual RTC minute stopwatch counter value
* Comments         :
*    This function returns the actual value of RTC stopwatch decrementer.
*
*END*********************************************************************/
uint_32 _rtc_get_stopwatch 
(
    void
)
{
    VMCF52XX_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    return MCF52XX_RTC_STPWCH_CNT(_rtc_register_read ((pointer)&rtc->STPWCH, TRUE));
}
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_scanl.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_scanl.c$
* $Version : 3.8.9.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the function for scanning and converting a line
*   of text.
*
*END************************************************************************/

#include "mqx.h"
#include <string.h>
#include <stdlib.h>

#if MQX_INCLUDE_FLOATING_POINT_IO
#include <math.h>
#endif

#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "fpio_prv.h"


extern char _io_scanline_ignore_white_space( char _PTR_ _PTR_ , _mqx_uint _PTR_ , 
   _mqx_uint);
extern char _io_scanline_format_ignore_white_space( char _PTR_ _PTR_ , 
   _mqx_uint _PTR_);
extern int_32 _io_scanline_base_convert( uchar, _mqx_uint );
extern boolean _io_scanline_is_octal_digit( char );
extern boolean _io_scanline_is_hex_digit( char );

/*!
 * \brief Converts an input line of ASCII characters based upon a provided 
 * string format.
 * 
 * \param[in] line_ptr The input line of ASCII data.
 * \param[in] format   Format first points to the format string.
 * \param[in] args_ptr The list of parameters.
 * 
 * \return Number of input items converted and assigned.
 */ 
_mqx_int _io_scanline
   (
      char _PTR_ line_ptr,
      char _PTR_ format, 
      va_list       args_ptr
   )
{ /* Body */
            char       suppress_field;
   register _mqx_int   c;
   register _mqx_uint  n;
            char _PTR_ sptr = NULL;
            _mqx_int   sign;
            uint_32    val;
            _mqx_int   width;
            _mqx_int   numtype;  /* used to indicate bit size of argument */
   register _mqx_int   number_of_chars;
            _mqx_uint  temp;
            _mqx_uint  base;
            pointer    tmp_ptr;
#if MQX_INCLUDE_FLOATING_POINT_IO
            double     dnum;
#endif
   
   n = 0;
   number_of_chars = 0;
   while ((c = *format++) != 0) {

      width = 0;

      /* 
       * skip white space in format string, and any in input line
       */
      if ( (c == ' ') || (c == '\t') ) {
         if ( ! _io_scanline_format_ignore_white_space( 
            (char _PTR_ _PTR_)&format, &temp ) ) {
            /*
             * End of format string encountered, scanning is finished.
             */
            return (_mqx_int)n;
         } /* Endif */

         if ( ! _io_scanline_ignore_white_space( 
            (char _PTR_ _PTR_)&line_ptr , &temp, 0 ) ) {
            /*
             * End of line string encountered, no more input to scan.
             */
            return (_mqx_int)n;
         } /* Endif */
         number_of_chars += temp;
         continue; 
      } /* Endif */

      if ( c != '%' ) {

         /* 
          * if format character is not %, then it must match text
          * in input line 
          */
         if ( c != _io_scanline_ignore_white_space( 
            (char _PTR_ _PTR_)&line_ptr , &temp, 0) ) {
            /*
             * Text not matched, stop scanning..
             */
            return (_mqx_int)n;
         } else {
            ++line_ptr;
         } /* Endif */
         number_of_chars += temp;

      } else {
         /*
          * process % format conversion 
          */
         suppress_field = 0;
         width = 0;
         numtype = SCAN_MLONG;
         sign = 1;
         val = 0;

         /* 
          * Skip whitespace. Check for " %  ", return if found, otherwise
          * get next character.
          */
         if ( ! _io_scanline_format_ignore_white_space( (char _PTR_ _PTR_)&format,
         &temp ) ) {
            return (_mqx_int)n;
         } /* Endif */
         c = *format;

         /*
          * Check for assignment suppression. if "*" given, 
          * suppress assignment 
          */
         if ( c == '*' ) {
            ++suppress_field;   
            c = *(++format); 
         } /* Endif */

         /* 
          * Skip whitespace. Check for " %  *  ", return if found, otherwise
          * get next character.
          */
         if ( ! _io_scanline_format_ignore_white_space( (char _PTR_ _PTR_)&format,
            &temp)) 
         {
            return (_mqx_int)n;
         } /* Endif */
         c = *format;

         /*
          * Now check for a width field 
          */
         width = 0;
         while (  ('0' <= c) && (c <= '9')  ) {
            width = width * 10 + (int_32)(c - '0');
            c = *(++format); 
         } /* Endwhile */

         /* 
          * Skip whitespace. Check for " %  *  23 ", return if found, 
          * otherwise get next character.
          */
         if ( ! _io_scanline_format_ignore_white_space( 
            (char _PTR_ _PTR_)&format,   &temp ) ) {
            return (_mqx_int)n;
         } /* Endif */
         c = *format++;

         /*
          * Check to see if c is lower case, if so convert to upper case
          */
         if (  (c >= 'a') && (c <= 'z')  ) {
            c -= 32; 
         } /* Endif */
                  
         /*
          * Now check to see if c is a type specifier.
          */
         if (c  == 'H') {
            numtype = SCAN_WLONG;
            if ( ! _io_scanline_format_ignore_white_space(
               (char _PTR_ _PTR_)&format, &temp ) )
            {
               return (_mqx_int)n;
            } /* Endif */
            c = *format++;
         } else if (c == 'L') {
            numtype = SCAN_LLONG;
            if ( ! _io_scanline_format_ignore_white_space(
               (char _PTR_ _PTR_)&format, &temp ) )
            {
               return (_mqx_int)n;
            } /* Endif */
            c = *format++;
         } else if (c == 'Z') {               
            numtype = SCAN_BLONG;
            if ( ! _io_scanline_format_ignore_white_space(
               (char _PTR_ _PTR_)&format, &temp ) )
            {
               return (_mqx_int)n;
            } /* Endif */
            c = *format++;
         } else if (c == 'M') {
            numtype = SCAN_MLONG;
            if ( ! _io_scanline_format_ignore_white_space(
               (char _PTR_ _PTR_)&format, &temp ) )
            {
               return (_mqx_int)n;
            } /* Endif */
            c = *format++;
         } /* Endif */

         /*
          * Check to see if c is lower case, if so convert to upper case
          */
         if (  (c >= 'a') && (c <= 'z')  ) {
            c -= 32; 
         } /* Endif */

         /*
          * Now check to see if c is a valid format specifier.
          */
         switch ( c ) {
               
            case 'I':
               c = _io_scanline_ignore_white_space( (char _PTR_ _PTR_)&line_ptr,
                  &temp, 0 );
               if ( *line_ptr == '0' ) {
                  ++number_of_chars;
                  ++line_ptr;
                  if ( width ) {
                     if ( --width <= 0 ) {
                        goto print_val;
                     } /* Endif */
                  } /* Endif */
                  if ( (*line_ptr == 'x') || (*line_ptr == 'X') ) {
                     base = 16;
                     ++line_ptr;
                     ++number_of_chars;
                     if ( width ) {
                        if ( --width <= 0 ) {
                           goto print_val;
                        } /* Endif */
                     } /* Endif */
                  } else if ( (*line_ptr == 'b') || (*line_ptr == 'B') ) {
                     base = 2;
                     ++line_ptr;
                     ++number_of_chars;
                     if ( width ) {
                        if ( --width <= 0 ) {
                           goto print_val;
                        } /* Endif */
                     } /* Endif */
                  } else {
                     base = 8;
                     if ( ! _io_scanline_is_octal_digit(*line_ptr) ) {
                        goto print_val;
                     } /* Endif */
                  } /* Endif */
               } else {
                  goto decimal;
               } /* Endif */
               goto doval;

            case 'P':
            case 'X':
               base = 16;
               c = _io_scanline_ignore_white_space( (char _PTR_ _PTR_)&line_ptr,
                  &temp, 0 );
               if ( *line_ptr == '0' ) {
                  ++line_ptr;
                  ++number_of_chars;
                  if ( width ) {
                     if ( --width <= 0 ) {
                        goto print_val;
                     } /* Endif */
                  } /* Endif */
                  if ( (*line_ptr == 'x') || (*line_ptr == 'X') ) {
                     ++line_ptr;
                     ++number_of_chars;
                     if ( width ) {
                        if ( --width <= 0 ) {
                           goto print_val;
                        } /* Endif */
                     } /* Endif */
                  } else if ( ! _io_scanline_is_hex_digit(*line_ptr) ) {
                     goto print_val;
                  } /* Endif */
               } /* Endif */
               goto doval;

            case 'O':
               base = 8;
               c = _io_scanline_ignore_white_space( (char _PTR_ _PTR_)&line_ptr,
                  &temp, 0 );
               if ( *line_ptr == '0' ) {
                  ++number_of_chars;
                  ++line_ptr;
                  if ( width ) {
                     if ( --width <= 0 ) {
                        goto print_val;
                     } /* Endif */
                  } /* Endif */
                  if ( ! _io_scanline_is_octal_digit(*line_ptr) ) {
                     goto print_val;
                  }
               } /* Endif */
               goto doval;

            case 'B':
               base = 2;
               c = _io_scanline_ignore_white_space( (char _PTR_ _PTR_)&line_ptr,
                  &temp, 0 );
               if ( *line_ptr == '0' ) {
                  ++line_ptr;
                  ++number_of_chars;
                  if ( width ) {
                     if ( --width <= 0 ) {
                        goto print_val;
                     } /* Endif */
                  } /* Endif */
                  if ( (*line_ptr == 'b') || (*line_ptr == 'B') ) {
                     ++line_ptr;
                     ++number_of_chars;
                     if ( width ) {
                        if ( --width <= 0 ) {
                           goto print_val;
                        } /* Endif */
                     } /* Endif */
                  } else if ( ! _io_scanline_is_hex_digit(*line_ptr) ) {
                     goto print_val;
                  } /* Endif */
               } /* Endif */
               goto doval;

            case 'D':
               decimal:
               base = 10;
               temp = 0;
               if (  _io_scanline_ignore_white_space( (char _PTR_ _PTR_)&line_ptr,
                  &temp, 0 ) == '-'  ) 
               {
                  number_of_chars += temp;
                  sign = -1;
                  ++line_ptr;
                  ++number_of_chars;
                  if ( width ) {
                     width -= (int_32)temp;
                     if ( width <= 0 ) {
                        goto print_val;
                     } /* Endif */
                  } /* Endif */
               } else {
                  number_of_chars += temp;
               } /* Endif */

            case 'U':
               base = 10;
               c = _io_scanline_ignore_white_space( (char _PTR_ _PTR_)&line_ptr,
                  &temp, 0 );
doval:  
               val = 0;
               /* remove spaces if any but don't */
               /* parse passed end of line       */
               c = *line_ptr;
               number_of_chars += temp;
               if ( width ) {
                  width -= temp;
                  if ( width <= 0 ) {
                     break;
                  } /* Endif */
               } /* Endif */
               if (  _io_scanline_base_convert( (uchar)c, base ) == SCAN_ERROR  ) {
                  return (_mqx_int)n; 
               } /* Endif */

               while ( (( c = _io_scanline_base_convert( *line_ptr, base ))
               != SCAN_ERROR) ) {
                  ++line_ptr;
                  ++number_of_chars;
                  val = val * base + (uint_32)((uchar)c & 0x7F); 
                  if ( width ) {
                     if ( --width <= 0 ) {
                        break;
                     } /* Endif */
                  } /* Endif */
               } /* Endwhile */

print_val:
               if (  ! suppress_field  ) {
                  /* assign value using appropriate pointer */
                  val *= sign;
                  tmp_ptr = (pointer)va_arg(args_ptr, pointer);
                  switch ( numtype ) {
                     case SCAN_LLONG:
                        *((uint_32 _PTR_)tmp_ptr) = val;
                        break;
                     case SCAN_WLONG:
                        *((uint_16 _PTR_)tmp_ptr) = (uint_16)val;
                        break;
                     case SCAN_BLONG:
                        *((uchar _PTR_)tmp_ptr) = (uchar)val;
                        break;
                     case SCAN_MLONG:
                        *((_mqx_uint _PTR_)tmp_ptr) = (_mqx_uint)val;
                        break;
                     default:
                        break;
                  } /* End Switch */
                  ++n;
               } /* Endif */
               break;
               
            case 'S':
               temp = 0;
               _io_scanline_ignore_white_space( (char _PTR_ _PTR_)&line_ptr,
                  &temp, 0 );
               number_of_chars += temp;
               if ( ! suppress_field ) {
                  sptr = (char _PTR_)va_arg(args_ptr, pointer);
               } /* Endif */
               if ( width ) {
                  width -= (int_32)temp;
                  if ( width <= 0 ) {
                     goto string_done;
                  } /* Endif */
               } /* Endif */

               while (( c = *line_ptr ) != 0) {
                  ++line_ptr;
                  ++number_of_chars;
                  if ( c == *format ) {
                     ++format;
                     break;
                  } /* Endif */

                  if ( ! suppress_field ) {
                     *sptr++ = (char)c; 
                  } /* Endif */
                  if ( width ) {
                     if ( --width <= 0 ) {
                        break;
                     } /* Endif */
                  } /* Endif */

               } /* Endwhile */

string_done:
               if ( ! suppress_field ) {
                  ++n;
                  *sptr = '\0';
               } /* Endif */
               break;
               
            case 'C':
               if ( width == 0 ) {
                  width = 1;
               } /* Endif */

               if ( ! suppress_field ) {
                  sptr = (char _PTR_)va_arg(args_ptr, pointer);
               } /* Endif */
               while ( width-- > 0 ) {
                  if ( ! suppress_field ) {
                     *sptr++ = (uchar)*line_ptr;
                  } /* Endif */

                  ++line_ptr;
                  ++number_of_chars;
               } /* Endwhile */
   
               if ( ! suppress_field ) {
                  ++n;
               } /* Endif */
               break;
               
            case 'N':
               if ( ! suppress_field ) {
                  tmp_ptr = va_arg(args_ptr, pointer);
                  *(_mqx_int _PTR_)(tmp_ptr) = (_mqx_int)number_of_chars;
               } /* Endif */
               break;

#if MQX_INCLUDE_FLOATING_POINT_IO
         case 'G':
         case 'F':
         case 'E':
            dnum = strtod((char _PTR_)line_ptr, (char _PTR_ _PTR_)&tmp_ptr);

            if ((dnum == HUGE_VAL) || (dnum == -HUGE_VAL))
            {
               return (_mqx_int)n;
            }

            line_ptr = tmp_ptr;
            tmp_ptr = (pointer)va_arg(args_ptr, pointer);
            if (SCAN_LLONG == numtype)
            {
               *((double _PTR_)tmp_ptr) = dnum;
            } else {
               *((float _PTR_)tmp_ptr) = (float)dnum;
            }
            ++n;
         break;
#endif

            default:
               return (_mqx_int)n;

         } /* End Switch */
         
      } /* Endif */
#if 0
      if ( ! *line_ptr || ! *format ) {
         return (_mqx_int)n; 
      } /* Endif */
#endif

      /* if end of input string, return */

   } /* Endwhile */
   return (_mqx_int)n;

} /* Endbody */


/*!
 * \brief Scanline function which ignores white spaces.
 * 
 * \param[in,out] s_ptr The addres of the string pointer to update.
 * \param[out]    count The number of characters skipped.
 * \param[in]     width Maximum number of white spaces to skip.
 * 
 * \return String without white spaces. 
 */ 
char _io_scanline_ignore_white_space
   (  
      register char _PTR_ _PTR_ s_ptr,
      register _mqx_uint _PTR_  count,
      register _mqx_uint        width
   )
{ /* Body */
   register char c;
   
   c = **s_ptr;
   *count = 0;
   while (  (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') ||
   (c == '\v') || (c == '\f') ) {
      c = *(++*s_ptr);
      (*count)++;
      if ( width ) {
         if ( --width == 0 ) {
            return(c);
         } /* Endif */
      } /* Endif */
   } /* Endwhile */
   return (c);

} /* Endbody */

/*!
 * \brief Scanline function which ignores white spaces.
 * 
 * \param[in,out] s_ptr The address of the string pointer.
 * \param[out]    count The number of characters skipped.
 * 
 * \return String without white spaces. 
 */ 
char _io_scanline_format_ignore_white_space
   ( 
      register char _PTR_ _PTR_ s_ptr,
      register _mqx_uint _PTR_  count
   )
{ /* Body */
   register char c;
   
   *count = 0;
   c = **s_ptr;
   while (  (c == ' ') || (c == '\t') ) {
      c = *(++*s_ptr);
      (*count)++;
   } /* Endwhile */
   return (c);

} /* Endbody */

/*!
 * \brief Converts input string.
 * 
 * \param[in] c    The character to convert.
 * \param[in] base The base to convert the character in.
 * 
 * \return Input string.
 * \return SCAN_ERROR (Failure.)  
 */ 
int_32 _io_scanline_base_convert
   (
      register unsigned char c,
      _mqx_uint              base
   )
{ /* Body */

   if (  c >= 'a' && c <= 'z'  ) {
      /* upper case c */
      c -= 32; 
   } /* Endif */
   
   if (  c >= 'A' && c <= 'Z'  ) {
      /* reduce hex digit */
      c -= 55;
   } else if (  (c >= '0') && (c <= '9')  ) {
      /* reduce decimal digit */
      c -= 0x30;
   } else {
      return SCAN_ERROR;
   } /* Endif */
   if ( (_mqx_uint)c  > (base-1) ) {
      return SCAN_ERROR;
   } else {
      return c;
   } /* Endif */

} /* Endbody */

/*!
 * \brief Determines whether input character is an octal number.
 * 
 * \param[in] c The character to check.
 * 
 * \return TRUE (Input is an octal number.), FALSE (Input is not an octal number.) 
 */ 
boolean _io_scanline_is_octal_digit
   (
      char c
   )
{ /* Body */

   if ( (c >= '0') && (c <= '7') ) {   /* An octal digit */
      return TRUE;
   } else {
      return FALSE;
   } /* Endif */

} /* Endbody */

/*!
 * \brief Determines whether input character is a hexadecimal number.
 * 
 * \param[in] c The character to check.
 * 
 * \return TRUE (Input is a hexadecimal number.), FALSE (Input is not a 
 * hexadecimal number.) 
 */  
boolean _io_scanline_is_hex_digit
   (
      char c
   )
{ /* Body */

   if ( ((c >= '0') && (c <= '9')) ||
      ((c >= 'a') && (c <= 'f')) ||
      ((c >= 'A') && (c <= 'F'))
   ) {   /* A hex digit */
      return TRUE;
   } else {
      return FALSE;
   } /* Endif */

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_ftfl.h<|end_filename|>
#ifndef __flash_ftfl_h__
#define __flash_ftfl_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_ftfl.h$
* $Version : 3.8.11.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains function prototypes and defines for the internal 
*   flash driver.
*
*END************************************************************************/

/* FlexNVM IOCTL codes */
#define FLEXNVM_IOCTL_READ_RESOURCE         _IO(IO_TYPE_FLASH, 0x14)
#define FLEXNVM_IOCTL_GET_PARTITION_CODE    _IO(IO_TYPE_FLASH, 0x15)
#define FLEXNVM_IOCTL_SET_PARTITION_CODE    _IO(IO_TYPE_FLASH, 0x16)
#define FLEXNVM_IOCTL_GET_FLEXRAM_FN        _IO(IO_TYPE_FLASH, 0x17)
#define FLEXNVM_IOCTL_SET_FLEXRAM_FN        _IO(IO_TYPE_FLASH, 0x18)
#define FLEXNVM_IOCTL_WAIT_EERDY            _IO(IO_TYPE_FLASH, 0x19)
#define FLEXNVM_IOCTL_GET_EERDY             _IO(IO_TYPE_FLASH, 0x1a)

/* FlexNVM EEPROM / FlexRAM choice */
#define FLEXNVM_FLEXRAM_RAM                 (0xff)
#define FLEXNVM_FLEXRAM_EE                  (0)

/*----------------------------------------------------------------------*/
/* 
**              EXPORTED TYPES
*/

typedef struct flexnvm_prog_part_struct {
    uint_8 EE_DATA_SIZE_CODE;
    uint_8 FLEXNVM_PART_CODE;
} FLEXNVM_PROG_PART_STRUCT, _PTR_ FLEXNVM_PROG_PART_STRUCT_PTR;

typedef struct flexnvm_read_rsrc_struct {
    uint_32 ADDR;
    uint_8 RSRC_CODE;
    uint_32 RD_DATA;
} FLEXNVM_READ_RSRC_STRUCT, _PTR_ FLEXNVM_READ_RSRC_STRUCT_PTR;

/*----------------------------------------------------------------------*/
/* 
**              DEFINED VARIABLES
*/

extern const FLASHX_BLOCK_INFO_STRUCT _flashx_kinetisN_block_map[];
extern const FLASHX_BLOCK_INFO_STRUCT _flashx_kinetisX_block_map[];
extern const FLASHX_BLOCK_INFO_STRUCT _flashx_mcf51xx_plus_block_map[];

extern const FLASHX_DEVICE_IF_STRUCT _flashx_ftfl_if;

#endif //__flash_ftfl_h__


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ipcfg.h<|end_filename|>
#ifndef __ipcfg_h__
#define __ipcfg_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcfg.h$
* $Version : 192.168.127.12$
* $Date    : Aug-15-2012$
*
* Comments:
*
*   Definitions for the IP config layer.
*
*   RTCSCFG_ENABLE_GATEWAYS must be set to work with gateways
*   RTCSCFG_IPCFG_ENABLE_DNS must be set to enable DNS resolving
*   RTCSCFG_IPCFG_ENABLE_DHCP must be set for DHCP
*   RTCSCFG_IPCFG_ENABLE_BOOT must be set to enable tftp/boot names processing
*
*END************************************************************************/


#include <enet.h>
#include <rtcs.h>


/* configuration defines */
#define IPCFG_DEBUG_LEVEL           0

#define IPCFG_MAX_NAK_RETRIES       6
#define IPCFG_MAX_AUTOIP_ATTEMPTS   256

#define IPCFG_TASK_NAME             "IPCFG_TASK"
#define IPCFG_TASK_STACK_SIZE       1000


#define IPCFG_DEVICE_COUNT  BSP_ENET_DEVICE_COUNT

/* error codes - backward compatibility */
#define IPCFG_ERROR_OK              IPCFG_OK
#define IPCFG_ERROR_BUSY            RTCSERR_IPCFG_BUSY
#define IPCFG_ERROR_DEVICE_NUMBER   RTCSERR_IPCFG_DEVICE_NUMBER
#define IPCFG_ERROR_INIT            RTCSERR_IPCFG_INIT
#define IPCFG_ERROR_BIND            RTCSERR_IPCFG_BIND


/* types */
typedef enum ipcfg_state
{
    IPCFG_STATE_INIT = 0,
    IPCFG_STATE_UNBOUND,
    IPCFG_STATE_BUSY,
    IPCFG_STATE_STATIC_IP,
    IPCFG_STATE_DHCP_IP,
    IPCFG_STATE_AUTO_IP,
    IPCFG_STATE_DHCPAUTO_IP,
    IPCFG_STATE_BOOT
} IPCFG_STATE;

typedef struct ipcfg_ip_address_data
{
    _ip_address ip;
    _ip_address mask;
    _ip_address gateway;
} IPCFG_IP_ADDRESS_DATA, _PTR_ IPCFG_IP_ADDRESS_DATA_PTR;

/* ipcfg general API */
uint_32         ipcfg_init_device (uint_32, _enet_address);
uint_32         ipcfg_release_device(uint_32);
uint_32         ipcfg_init_interface(uint_32, _rtcs_if_handle);
uint_32         ipcfg_release_interface(uint_32);

/* immediate action API */
uint_32         ipcfg_unbind (uint_32);
uint_32         ipcfg_bind_staticip (uint_32, IPCFG_IP_ADDRESS_DATA_PTR);
uint_32         ipcfg_bind_autoip (uint_32, IPCFG_IP_ADDRESS_DATA_PTR);
uint_32         ipcfg_bind_dhcp (uint_32, boolean);
uint_32         ipcfg_poll_dhcp (uint_32, boolean, IPCFG_IP_ADDRESS_DATA_PTR);
uint_32         ipcfg_bind_boot (uint_32);
uint_32         ipcfg_bind_dhcp_wait (uint_32, boolean, IPCFG_IP_ADDRESS_DATA_PTR);

/* monitoring-task API */
uint_32         ipcfg_task_create (uint_32, uint_32);
void            ipcfg_task_destroy (boolean);
boolean         ipcfg_task_status (void);
boolean         ipcfg_task_poll (void);

/* general information retrieval */
uint_32         ipcfg_get_device_number(_rtcs_if_handle);
uint_32         ipcfg_add_interface(uint_32, _rtcs_if_handle);
uint_32         ipcfg_del_interface (uint_32);
_rtcs_if_handle ipcfg_get_ihandle (uint_32);
boolean         ipcfg_get_mac (uint_32, _enet_address);
const char *    ipcfg_get_state_string (IPCFG_STATE);
IPCFG_STATE     ipcfg_get_state (uint_32);
boolean         ipcfg_phy_registers(uint_32,uint_32,uint_32_ptr);
IPCFG_STATE     ipcfg_get_desired_state (uint_32);
boolean         ipcfg_get_link_active (uint_32);
_ip_address     ipcfg_get_dns_ip (uint_32, uint_32);
boolean         ipcfg_add_dns_ip (uint_32, _ip_address);
boolean         ipcfg_del_dns_ip (uint_32, _ip_address);
boolean         ipcfg_get_ip (uint_32, IPCFG_IP_ADDRESS_DATA_PTR);
_ip_address     ipcfg_get_tftp_serveraddress (uint_32);
uchar_ptr       ipcfg_get_tftp_servername (uint_32);
uchar_ptr       ipcfg_get_boot_filename (uint_32);

#define IPCFG_INC_IP(ip, mask, val)     ((ip & mask) | ((ip + val + ((((ip + val) & 0xff) == 0xff) ? 2 : 0)) & ~mask))

/******************************************************************
 * Possible states for the address of an interface.
 ******************************************************************/
typedef enum
{
    IP6_ADDR_STATE_NOT_USED = 0,    /* Not used.*/
    IP6_ADDR_STATE_TENTATIVE = 1,	/* Tentative address - (RFC4862) an address whose uniqueness on a link is being
                                     * verified, prior to its assignment to an interface. A tentative
                                     * address is not considered assigned to an interface in the usual
                                     * sense. An interface discards received packets addressed to a
                                     * tentative address, but accepts Neighbor Discovery packets related
                                     * to Duplicate Address Detection for the tentative address.
                                     */
    IP6_ADDR_STATE_PREFERRED = 2 	/* Prefered address - (RFC4862) an address assigned to an interface whose use by
                                     * upper-layer protocols is unrestricted. Preferred addresses may be
                                     * used as the source (or destination) address of packets sent from
                                     * (or to) the interface.
                                     */
} ip6_if_addr_state;

/******************************************************************
* Structures
*******************************************************************/
typedef struct ipcfg6_bind_addr_data
{
    in6_addr            ip_addr;    /* is IP address if "type" is MANUAL, 
                                     * or is prefix/64 if "type" is AUTOCONFIGURABLE"*/
    ip6_if_addr_type    ip_addr_type;
} IPCFG6_BIND_ADDR_DATA, _PTR_ IPCFG6_BIND_ADDR_DATA_PTR;

typedef struct ipcfg6_unbind_addr_data
{
    in6_addr        ip_addr;
} IPCFG6_UNBIND_ADDR_DATA, _PTR_ IPCFG6_UNBIND_ADDR_DATA_PTR;

typedef struct ipcfg6_get_addr_data
{
    in6_addr            ip_addr;        /* Address.*/
    ip6_if_addr_state   ip_addr_state;  /* Address current state.*/
    ip6_if_addr_type    ip_addr_type;   /* Address type.*/
} IPCFG6_GET_ADDR_DATA, _PTR_ IPCFG6_GET_ADDR_DATA_PTR;


/******************************************************************
* Function Prototypes
*******************************************************************/
/* Immediate action API. */
uint_32         ipcfg6_unbind_addr (uint_32, IPCFG6_UNBIND_ADDR_DATA_PTR);
uint_32         ipcfg6_bind_addr (uint_32, IPCFG6_BIND_ADDR_DATA_PTR);

/* General information retrieval. */
uint_32 ipcfg6_get_addr_info_n ( uint_32 device, uint_32 n /*>0*/, IPCFG6_GET_ADDR_DATA_PTR data/*out*/);
uint_32 ipcfg6_get_addr_info (uint_32 device, in6_addr *addr /*in*/, IPCFG6_GET_ADDR_DATA_PTR data/*out*/);
uint_32 ipcfg6_get_device_scope_id( uint_32 device /* in */ );

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/echosrv.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: echosrv.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains an implementation of an
*   RFC 862 Echo server.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_UDP

#define BUFFER_SIZE  1500
static char buffer[BUFFER_SIZE];

/* Start CR 1658C */
typedef struct echo_context  {
   uint_32     UDPSOCK;
   uint_32     LISTENSOCK;
} ECHOSRV_CONTEXT, _PTR_ ECHOSRV_CONTEXT_PTR;

_rtcs_taskid ECHOSRV_task_id = 0;

#ifdef __MQX__ 
void ECHOSRV_Exit_handler(void);
#endif
/* End CR 1658C */

void ECHOSRV_task(pointer, pointer);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : ECHOSRV_init
* Returned Value   : error code
* Comments  :  Start the port 7 echo server.
*
*END*-----------------------------------------------------------------*/

uint_32 ECHOSRV_init
   (
      char_ptr name,
      uint_32  priority,
      uint_32  stacksize
   )
{ /* Body */
   /* Start CR 1658C */
   if (ECHOSRV_task_id == 0)  {
      return RTCS_task_create(name, priority, stacksize, ECHOSRV_task, NULL);
   } else  {
      return RTCSERR_SERVER_ALREADY_RUNNING;
   }
   /* End CR 1658C */
} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name    : ECHO_task
* Returned Value   : none
* Comments  :  Simple Echo server.
*
*END*-----------------------------------------------------------------*/

void ECHO_task
   (
      uint_32 dummy
   )
{ /* Body */
   ECHOSRV_task(NULL, NULL);
} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name    : ECHOSRV_task
* Returned Value   : none
* Comments  :  Simple Echo server.
*
*END*-----------------------------------------------------------------*/

void ECHOSRV_task
   (
      pointer dummy,
      pointer creator
   )
{ /* Body */
   sockaddr_in    laddr, raddr;
   uint_32        sock, listensock;
   uint_32        error;
   uint_32        optval, optlen;
   int_32         length;
   uint_16        rlen;
   /* Start CR 1658C */
   ECHOSRV_CONTEXT   echo_context =  { 0 };

   ECHOSRV_task_id = RTCS_task_getid();
#ifdef __MQX__ 
   /* Set up exit handler and context so that we can clean up if the Echo Server is terminated */
   _task_set_environment( _task_get_id(), (pointer) &echo_context );
   _task_set_exit_handler( _task_get_id(), ECHOSRV_Exit_handler );
#endif 
   
   /* Echo server services port 7 */
   laddr.sin_family      = AF_INET;
   laddr.sin_port        = IPPORT_ECHO;
   laddr.sin_addr.s_addr = INADDR_ANY;

   /* Bind to UDP port */
   echo_context.UDPSOCK = socket(PF_INET, SOCK_DGRAM, 0);
   if (echo_context.UDPSOCK == RTCS_SOCKET_ERROR) {
      RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
   } /* Endif */
   error = bind(echo_context.UDPSOCK, (const sockaddr *)&laddr, sizeof(laddr));
   if (error) {
      RTCS_task_exit(creator, error);
   } /* Endif */

   /* Listen on TCP port */
   echo_context.LISTENSOCK = socket(PF_INET, SOCK_STREAM, 0);
   listensock = echo_context.LISTENSOCK;
   if (listensock == RTCS_SOCKET_ERROR) {
      RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
   } /* Endif */
   error = bind(listensock, (const sockaddr *)&laddr, sizeof(laddr));
   if (error) {
      RTCS_task_exit(creator, error);
   } /* Endif */
   error = listen(listensock, 0);
   if (error) {
      RTCS_task_exit(creator, error);
   } /* Endif */
   /* End CR 1658C */

   RTCS_task_resume_creator(creator, RTCS_OK);

   for (;;) {

      sock = RTCS_selectall(0);

      if (sock == listensock) {

         /* Connection requested; accept it */
         rlen = sizeof(raddr);
         accept(listensock,(sockaddr *)&raddr, &rlen);

      } else {

         /* Get the socket type */
         getsockopt(sock, SOL_SOCKET, RTCS_SO_TYPE, (char_ptr)&optval, &optlen);

         if (optval == SOCK_STREAM) {

            length = recv(sock, buffer, BUFFER_SIZE, 0);
            if (length == RTCS_ERROR) {
               shutdown(sock, FLAG_CLOSE_TX);
            } else {
               send(sock, buffer, length, 0);
            } /* Endif */

         } else { /* optval == SOCK_DGRAM */

            rlen = sizeof(raddr);
            length = recvfrom(sock, buffer, BUFFER_SIZE, 0, (sockaddr *)&raddr, &rlen);
            sendto(sock, buffer, length, 0, (sockaddr *)&raddr, rlen);

         } /* Endif */

      } /* Endif */

   } /* Endfor */

} /* Endbody */

/* Start CR 1658C */
#ifdef __MQX__ 
/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : ECHOSRV_stop
* Returned Value   : error code
* Comments  :  Start the ECHO task.
*
*END*-----------------------------------------------------------------*/

uint_32 ECHOSRV_stop( void )
{ /* Body */
   if (ECHOSRV_task_id == 0)  {
      return RTCSERR_SERVER_NOT_RUNNING;
   }
   RTCS_task_abort(ECHOSRV_task_id);
   ECHOSRV_task_id = 0;
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : ECHOSRV_Exit_handler
* Returned Value   : error code
* Comments  :  Start the ECHO task.
*
*END*-----------------------------------------------------------------*/

void ECHOSRV_Exit_handler( void )
{ /* Body */
   ECHOSRV_CONTEXT_PTR    echo_context_ptr;
   
   echo_context_ptr = (ECHOSRV_CONTEXT_PTR) _task_get_environment( _task_get_id() );
   if (echo_context_ptr != NULL)  {
      if (echo_context_ptr->UDPSOCK)  {
         shutdown(echo_context_ptr->UDPSOCK, 0);
         echo_context_ptr->UDPSOCK = 0;   
      }   
      if (echo_context_ptr->LISTENSOCK)  {
         shutdown(echo_context_ptr->LISTENSOCK, FLAG_ABORT_CONNECTION);   
         echo_context_ptr->LISTENSOCK = 0;   
      }   
   }
   ECHOSRV_task_id = 0;
} /* Endbody */
#endif
/* End CR 1658 */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/ip.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip.c$
* $Version : 3.8.20.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   This file contains the implementation of the Internet
*   Protocol.  For more details, refer to RFC791 and RFC1122.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IP_init
* Returned Values : RTCS_OK or error code
* Comments        :
*     Initialize the IP layer.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4  

uint_32 IP_init
   (
      void
   )
{ /* Body */
   IP_CFG_STRUCT_PTR IP_cfg_ptr;

   IP_cfg_ptr = RTCS_mem_alloc_zero(sizeof(IP_CFG_STRUCT));

   if (IP_cfg_ptr == NULL)  {
      return RTCSERR_OUT_OF_MEMORY;
   }

   _mem_set_type(IP_cfg_ptr, MEM_TYPE_IP_CFG_STRUCT);
   
   RTCS_setcfg(IP, IP_cfg_ptr);

   RTCS_LIST_INIT(IP_cfg_ptr->ICB_HEAD);
   IP_cfg_ptr->NEXT_ID  = 0;
   IP_cfg_ptr->DEFAULT_TTL = IPTTL_DEFAULT;

   IP_cfg_ptr->ROUTE_PARTID  = RTCS_part_create(sizeof(IP_ROUTE_DIRECT),
      IPROUTEALLOC_SIZE, IPROUTEALLOC_SIZE, 0, NULL, NULL);
#if RTCSCFG_ENABLE_GATEWAYS
   IP_cfg_ptr->GATE_PARTID   = RTCS_part_create(sizeof(IP_ROUTE_INDIRECT),
      IPGATEALLOC_SIZE,  IPGATEALLOC_SIZE,  0, NULL, NULL);
#endif
#if RTCSCFG_ENABLE_VIRTUAL_ROUTES
   IP_cfg_ptr->VIRTUAL_PARTID   = RTCS_part_create(sizeof(IP_ROUTE_VIRTUAL),
      IPROUTEALLOC_SIZE,  IPROUTEALLOC_SIZE,  0, NULL, NULL);
#endif
   IP_cfg_ptr->ROUTE_FN      = NULL;
#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   IP_cfg_ptr->MCB_PARTID    = RTCS_part_create(sizeof(MC_MEMBER),
      IPMCBALLOC_SIZE,   IPMCBALLOC_SIZE,   0, NULL, NULL);
#endif
#if RTCSCFG_ENABLE_IPSEC
   IP_cfg_ptr->SEC_SERVICE_FN = NULL;
   IP_cfg_ptr->SEC_SEND_FN    = NULL;
   IP_cfg_ptr->SEC_FN_ARG     = NULL;
#endif
   IP_cfg_ptr->RADIX_PARTID  = RTCS_part_create(sizeof(IP_ROUTE),
      RADIXALLOC_SIZE,   RADIXALLOC_SIZE,   0, NULL, NULL);

   IP_route_init(&IP_cfg_ptr->ROUTE_ROOT);

   return RTCS_OK;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_send
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Sends an IP packet generated on the local host.
*
*END*-----------------------------------------------------------------*/

uint_32 IP_send
   (
      RTCSPCB_PTR    rtcs_pcb,
            /* [IN] the packet to send */
      uint_32        protocol,
            /* [IN] the transport layer protocol */
      _ip_address    ipsrc,
            /* [IN] the destination interface (0 = any) */
      _ip_address    ipdest,
            /* [IN] the ultimate destination */
      uint_32        flags
            /* [IN] optional flags */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   IP_CFG_STRUCT_PTR    IP_cfg_ptr;

   IP_cfg_ptr = RTCS_getcfg(IP);

   IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);

   rtcs_pcb->IP_COMPLETE = IP_complete_send;
   rtcs_pcb->IFSRC       = RTCS_IF_LOCALHOST_PRV;

   /*
   ** Validate destination address
   */
   if (IN_ZERONET(ipdest)) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_DISCARDED++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_ADDRESS);
      RTCSPCB_free(rtcs_pcb);
      return RTCSERR_IP_BAD_ADDRESS;
   } /* Endif */

   if ((ipdest == INADDR_BROADCAST)
    || IN_MULTICAST(ipdest)) {
      return IP_route_multi(rtcs_pcb, protocol, ipsrc, ipdest, flags);
   } else {
      return IP_route(rtcs_pcb, protocol, ipsrc, INADDR_ANY, ipdest, flags);
   } /* Endif */

#else

    RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_IS_DISABLED);
    RTCSPCB_free(rtcs_pcb);
    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4 */   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_send_IF
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Sends an IP packet through a specified interface.
*
*END*-----------------------------------------------------------------*/

uint_32 IP_send_IF
   (
      RTCSPCB_PTR    rtcs_pcb,
            /* [IN] the packet to send */
      uint_32        protocol,
            /* [IN] the transport layer protocol */
      pointer        interface
            /* [IN] the destination interface */
   )
{ 

#if RTCSCFG_ENABLE_IP4

   IP_CFG_STRUCT_PTR    IP_cfg_ptr;
   IP_IF_PTR            ifdest = interface;

   IP_cfg_ptr = RTCS_getcfg(IP);

   IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);


   rtcs_pcb->IP_COMPLETE = IP_complete_send;
   rtcs_pcb->IFSRC       = RTCS_IF_LOCALHOST_PRV;

   return IP_send_dgram(ifdest, rtcs_pcb, INADDR_ANY, INADDR_BROADCAST,
      INADDR_BROADCAST, protocol, NULL);
      
#else

    RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_IS_DISABLED);
    RTCSPCB_free(rtcs_pcb);
    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4 */  

} 

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_complete_send
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Generates an IP header for outgoing packets.  This function
*        must not consume pcb.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4

uint_32 IP_complete_send
   (
      pointer           ifdest,
            /* [IN] the destination interface */
      RTCSPCB_PTR _PTR_ rtcs_pcb_ptr_ptr,
            /* [IN] the packet to send */
      _ip_address       hopsrc,
            /* [IN] the destination interface */
       _ip_address      ipdest,
            /* [IN] the ultimate dest */
      uint_32           protocol
            /* [IN] the transport layer protocol */
   )
{ /* Body */
   RTCSPCB_PTR            rtcs_pcb = *rtcs_pcb_ptr_ptr;
   IP_CFG_STRUCT_PTR      IP_cfg_ptr;
   IP_HEADER_PTR          packet;
   uchar                  proto, ttl, tos;
   uint_32                error;
   uint_16                chksum;
   uchar                  dfrag;

   IP_cfg_ptr = RTCS_getcfg(IP);

   error = RTCSPCB_insert_header(rtcs_pcb, sizeof(IP_HEADER));
   if (error) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      IF_IP_STATS_ENABLED(RTCS_seterror(&IP_cfg_ptr->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
      /* The PCB will be freed for us. */
      return error;
   } /* Endif */

   RTCSLOG_PCB_WRITE(rtcs_pcb, RTCS_LOGCTRL_PROTO(IPPROTO_IP), IP_VERSION);
   packet = (IP_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
   RTCSPCB_DATA_NETWORK(rtcs_pcb) = RTCSPCB_DATA(rtcs_pcb);
   proto  = IPPROTO_GET(protocol);
   tos    = IPTOS_GET(protocol);
   if (!tos) 
     tos = rtcs_pcb->LINK_OPTIONS.TX.TOS;
   dfrag  = IPDFRAG_GET(protocol);
   
      
   ttl = rtcs_pcb->LINK_OPTIONS.TX.TTL;
   if (!ttl) ttl = IPTTL_GET(protocol);
   if (!ttl) ttl = IP_cfg_ptr->DEFAULT_TTL;

   htonc(packet->VERSLEN,  (IP_VERSION << 4) | (sizeof(IP_HEADER) >> 2));
   htonc(packet->TOS,      tos);
   htons(packet->LENGTH,   RTCSPCB_SIZE(rtcs_pcb));
   htons(packet->ID,       IP_cfg_ptr->NEXT_ID);
   IP_cfg_ptr->NEXT_ID++;
   if (dfrag) {
      htons(packet->FRAGMENT, IP_FRAG_DF);
   } else {
      htons(packet->FRAGMENT, 0);
   } /* Endif */
   htonc(packet->TTL,      ttl);
   htonc(packet->PROTOCOL, proto);
   htonl(packet->DEST,     ipdest);
   htons(packet->CHECKSUM, 0);
   htonl(packet->SOURCE,   hopsrc);

   /* Set up the transport layer protocol and delta. */
   RTCSPCB_SET_TRANS_PROTL(rtcs_pcb, proto);
   RTCSPCB_SET_TRANS_DELTA(rtcs_pcb, sizeof(IP_HEADER));

   /*
   ** If the transport layer needs a pseudo header checksum,
   ** calculate it now.
   */
   if (rtcs_pcb->IP_SUM_PTR) {
      chksum = IP_Sum_pseudo(rtcs_pcb->IP_SUM, rtcs_pcb, 0);
      chksum = IP_Sum_invert(chksum);
      htons(rtcs_pcb->IP_SUM_PTR, chksum);
   } /* Endif */

#if RTCSCFG_ENABLE_IPSEC
   if (IP_cfg_ptr->SEC_SEND_FN) {
      error = IP_cfg_ptr->SEC_SEND_FN(IP_cfg_ptr->SEC_FN_ARG, ifdest,
         rtcs_pcb_ptr_ptr, hopsrc, ipdest);
      if (error) {
         /* The calling function will discard the packet for us. */
         return error;
      } /* Endif */
   } /* Endif */
#endif

   rtcs_pcb = *rtcs_pcb_ptr_ptr;

   /* We need to refresh the header location, as it may have been shifted.*/
   packet = (IP_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
   chksum = _mem_sum_ip(0, sizeof(IP_HEADER), packet);
   chksum = IP_Sum_invert(chksum);
   htons(packet->CHECKSUM, chksum);

   /* Special case for loopback */
   if (ifdest == RTCS_IF_LOCALHOST_PRV) {
      RTCSPCB_PTR            new_rtcs_pcb;
      uchar_ptr              data;
      PCB_FRAGMENT_PTR       frag;

      data = RTCS_mem_alloc_system(sizeof(PCB) + sizeof(PCB_FRAGMENT) + RTCSPCB_SIZE(rtcs_pcb));

      if (!data)  {
         return RTCSERR_OUT_OF_MEMORY;
      } /* Endif */

      _mem_set_type(data, MEM_TYPE_IP_DATA);

      frag = ((PCB_PTR)data)->FRAG;
      ((PCB_PTR)data)->FREE = (void(_CODE_PTR_)(PCB_PTR))_mem_free;
      ((PCB_PTR)data)->PRIVATE = NULL;
      frag[0].LENGTH = RTCSPCB_SIZE(rtcs_pcb);
      frag[0].FRAGMENT = data + sizeof(PCB) + sizeof(PCB_FRAGMENT);
      frag[1].LENGTH = 0;
      frag[1].FRAGMENT = NULL;

      new_rtcs_pcb = RTCSPCB_alloc_recv((PCB_PTR)data);
      if (!new_rtcs_pcb)  {
         _mem_free(data);
         return RTCSERR_OUT_OF_MEMORY;
      } /* Endif */

      new_rtcs_pcb->TYPE = rtcs_pcb->TYPE;
      new_rtcs_pcb->IFSRC = rtcs_pcb->IFSRC;
      new_rtcs_pcb->LINK_OPTIONS = rtcs_pcb->LINK_OPTIONS;
      new_rtcs_pcb->IP_COMPLETE = IP_complete_recv;

      data += sizeof(PCB) + sizeof(PCB_FRAGMENT);
      RTCSPCB_memcopy(rtcs_pcb, data, 0, RTCSPCB_SIZE(rtcs_pcb));
      RTCSPCB_DATA_NETWORK(new_rtcs_pcb) = RTCSPCB_DATA(new_rtcs_pcb);
      RTCSPCB_free(rtcs_pcb);

      *rtcs_pcb_ptr_ptr = new_rtcs_pcb;

      return IP_complete_recv(ifdest, rtcs_pcb_ptr_ptr, hopsrc, ipdest, protocol);

   } /* Endif */

   return RTCS_OK;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_service
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Parses a received IP packet.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4

void IP_service
   (
      RTCSPCB_PTR    rtcs_pcb
            /* [IN] the packet to send */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR          IP_cfg_ptr;
   IP_HEADER_PTR              packet = (IP_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
   _ip_address                ipsrc, ipdest;
   uint_16                    hdrlen, pktlen;
   uint_32                    routeopt, error;
   #if RTCSCFG_ENABLE_NAT
   uint_32 (_CODE_PTR_ _PTR_  nat_exec)(RTCSPCB_PTR _PTR_);
   #endif
   
   RTCSLOG_FNE2(RTCSLOG_FN_IP_service, rtcs_pcb);

   IP_cfg_ptr = RTCS_getcfg(IP);

   IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_TOTAL++);
   hdrlen = (ntohc(packet->VERSLEN) & 0x0F) << 2;
   pktlen = ntohs(packet->LENGTH);
   RTCSPCB_DATA_NETWORK(rtcs_pcb) = RTCSPCB_DATA(rtcs_pcb);

   /*
   ** Make sure that
   **    sizeof(IP_HEADER) <= hdrlen <= pktlen <= RTCSPCB_SIZE(pcb)
   */
   if (hdrlen < sizeof(IP_HEADER)) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_HDR_ERRORS++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_SMALL_HDR++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_HEADER);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 1);
      return;
   } /* Endif */
   if (pktlen < hdrlen) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_HDR_ERRORS++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_SMALL_DGRAM++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_HEADER);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 2);
      return;
   } /* Endif */
   if (RTCSPCB_SIZE(rtcs_pcb) < pktlen) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_HDR_ERRORS++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_SMALL_PKT++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_HEADER);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 3);
      return;
   } /* Endif */

   /*
   ** IP version must be 4
   */
   if ((ntohc(packet->VERSLEN) >> 4) != IP_VERSION) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_HDR_ERRORS++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_BAD_VERSION++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_HEADER);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 4);
      return;
   } /* Endif */

   RTCSLOG_PCB_READ(rtcs_pcb, RTCS_LOGCTRL_PROTO(IPPROTO_IP), IP_VERSION);

   /*
   ** Validate source address
   */
   ipsrc = ntohl(packet->SOURCE);
   if (IN_LOOPBACK(ipsrc)
    || IN_MULTICAST(ipsrc)
    || IN_EXPERIMENTAL(ipsrc)) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_HDR_ERRORS++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_BAD_SOURCE++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_ADDRESS);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 5);
      return;
   } 

   /*
   ** Validate destination address
   */
   ipdest = ntohl(packet->DEST);
   if (IN_LOOPBACK(ipdest)
    || IN_ZERONET(ipdest)
    || (IN_EXPERIMENTAL(ipdest) && ipdest != INADDR_BROADCAST)) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_ADDR_ERRORS++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_ADDRESS);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 6);
      return;
   } /* Endif */

   /*
   ** Verify the checksum
   */
   if (_mem_sum_ip(0, hdrlen, packet) != 0xFFFF) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_HDR_ERRORS++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_BAD_CHECKSUM++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_CHECKSUM);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 7);
      return;
   } 

   /*
   ** In this function, the PCB always has only one fragment, so it's
   ** always safe to call RTCSPCB_shrink() here.
   */
   error = RTCSPCB_shrink(rtcs_pcb, RTCSPCB_SIZE(rtcs_pcb) - pktlen);
   if (error) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_ERRORS++);
      IF_IP_STATS_ENABLED(RTCS_seterror(&IP_cfg_ptr->STATS.ERR_RX, error, (uint_32)rtcs_pcb));
      RTCSLOG_PCB_FREE(rtcs_pcb, error);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 8);
      return;
   } 


   rtcs_pcb->IP_COMPLETE = IP_complete_recv;
/* rtcs_pcb->IFSRC has already been set by link layer */

   /*
   ** Now decide what to do with the packet.
   **
   ** Normally, we should do:
   **
   **    if (!FORWARD || !(TYPE & UNICAST))
   **       IP_route_local();
   **    else
   **       IP_route();
   **
   ** i.e. we only forward unicast packets, and only if forwarding is
   ** turned on.  Unfortunately, this isn't sufficient.
   **
   ** If forwarding is turned on, limited broadcasts from PPP links
   ** will be discarded, because on PPP links, (TYPE & UNICAST) is
   ** always true (PPP packets are both unicast and broadcast), and
   ** IP_route() discards limited broadcasts.
   **
   ** Hence, we have to explicitly make sure that limited broadcasts
   ** and multicasts go through IP_route_local().
   **
   ** Once multicast routing is implemented, we'll remove IN_MULTICAST()
   ** from the first condition.
   **
   ** RFC 2131 says:
   ** "In the case of a client using DHCP for initial configuration (before
   ** the client's TCP/IP software has been completely configured), DHCP
   ** requires creative use of the client's TCP/IP software and liberal
   ** interpretation of RFC 1122.  The TCP/IP software SHOULD accept and
   ** forward to the IP layer any IP packets delivered to the client's
   ** hardware address before the IP address is configured."
   ** 
   ** So if the broadcast flag is disabled, we check, and if the packet's 
   ** source interface is not bound, we make sure the packet goes through 
   ** IP_route_local(), where we have the same test to send the packet to 
   ** IF_LOCALHOST.  
   */

   if (!_IP_forward
    || !(rtcs_pcb->TYPE & RTCSPCB_TYPE_UNICAST)
    || (ipdest == INADDR_BROADCAST)
    || IN_MULTICAST(ipdest)
    || (!_DHCP_broadcast && (IP_get_ipif_addr(rtcs_pcb->IFSRC) == INADDR_ANY))) { 

      IP_route_local(rtcs_pcb, ipdest);

   } else {

      if (IN_ZERONET(ipsrc)) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_HDR_ERRORS++);
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_BAD_SOURCE++);
         RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_IP_BAD_ADDRESS);
         RTCSPCB_free(rtcs_pcb);
         RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 9);
         return;
      } /* Endif */

      /*
      ** If the packet was broadcast, don't send it out the receiving
      ** interface.  This protects mainly against bouncing PPP directed
      ** broadcasts.
      */
      if (rtcs_pcb->TYPE & RTCSPCB_TYPE_BROADCAST) {
         routeopt = IPROUTEOPT_RECVIF;
      } else {
         routeopt = 0;
      } /* Endif */

      #if RTCSCFG_ENABLE_NAT   
      /* Apply NAT if it is installed */
      nat_exec = RTCS_getcfg(NAT);
      if (nat_exec && *nat_exec) {
         error = (*nat_exec)(&rtcs_pcb);
         if (error) {
            if (rtcs_pcb!=NULL) {
               IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
               RTCSLOG_PCB_FREE(rtcs_pcb, error);
               RTCSPCB_free(rtcs_pcb);
            }
            RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 10);
            return;
         } /* Endif */

         // NAT may have consumed the PCB if it was a fragment
         if (rtcs_pcb==NULL) {
            RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 11);
            return;
         }

         /* PCB pointer may have changed */
         rtcs_pcb->IP_COMPLETE = IP_complete_recv;
         packet = (IP_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
         ipdest = ntohl(packet->DEST);
      } /* Endif */
      #endif

      IP_route(rtcs_pcb, 0, INADDR_ANY, ipsrc, ipdest, routeopt);

   } /* Endif */
   
    RTCSLOG_FNX2(RTCSLOG_FN_IP_service, 0);
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_complete_recv
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Decrements the TTL on forwarding packets.  This function
*        must not consume pcb.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 IP_complete_recv
   (
      pointer           ifdest,
            /* [IN] the destination interface */
      RTCSPCB_PTR _PTR_ rtcs_pcb_ptr_ptr,
            /* [IN] the packet to send */
      _ip_address       hopsrc,
            /* [IN] the destination interface */
      _ip_address       ipdest,
      /* [IN] the ultimate dest */
      uint_32           protocol
      /* [IN] the transport layer protocol */
   )
{ /* Body */
   RTCSPCB_PTR          rtcs_pcb = *rtcs_pcb_ptr_ptr;
   IP_CFG_STRUCT_PTR    IP_cfg_ptr;
   IP_HEADER_PTR packet = (IP_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
   uint_16       hdrlen, pktlen;
   uint_16       chksum;
   uchar         ttl;
   uint_32       error;

   IP_cfg_ptr = RTCS_getcfg(IP);

   /* Set up the transport layer protocol and delta. */
   RTCSPCB_SET_TRANS_PROTL(rtcs_pcb, ntohc(packet->PROTOCOL));
   RTCSPCB_SET_TRANS_DELTA(rtcs_pcb, ((ntohc(packet->VERSLEN) & 0x0F) << 2));

#if RTCSCFG_ENABLE_IPSEC
   if (IP_cfg_ptr->SEC_SEND_FN) {
      error = IP_cfg_ptr->SEC_SERVICE_FN(IP_cfg_ptr->SEC_FN_ARG, ifdest,
         rtcs_pcb_ptr_ptr, hopsrc, ipdest);
      if (error) {
         /* The calling function will discard the packet for us. */
         return error;
      } /* Endif */
   } /* Endif */
#endif

   /* Either no security database exists, or the packet has been decoded, or */
   /* the packet has been let through unchanged (bypass). */
   rtcs_pcb = *rtcs_pcb_ptr_ptr;

   if ((IP_IF_PTR)ifdest != RTCS_IF_LOCALHOST_PRV) {
      /*
      ** Check the TTL
      */

      ttl = ntohc(packet->TTL);
      if (ttl <= 1) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_HDR_ERRORS++);
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_TTL_EXCEEDED++);
         #if RTCSCFG_ENABLE_ICMP
         ICMP_send_error(ICMPTYPE_TIMEEXCEED, ICMPCODE_TE_TTL, 0, rtcs_pcb, 0);
         #endif
         return RTCSERR_IP_TTL;
      } /* Endif */

      /*
      ** Fork the PCB and duplicate the IP header.  Also copy up to
      ** 8 bytes of data in case we need to generate an ICMP error.
      */

      hdrlen = (ntohc(packet->VERSLEN) & 0x0F) << 2;
      pktlen = ntohs(packet->LENGTH);
      if (pktlen > hdrlen + 8) {
         pktlen = hdrlen + 8;
      } /* Endif */

      error = RTCSPCB_next(rtcs_pcb, pktlen);
      if (error) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_IP_STATS_ENABLED(RTCS_seterror(&IP_cfg_ptr->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
         return error;
      } /* Endif */

      error = RTCSPCB_fork(rtcs_pcb);
      if (error) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_IP_STATS_ENABLED(RTCS_seterror(&IP_cfg_ptr->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
         return error;
      } /* Endif */

      RTCSLOG_PCB_WRITE(rtcs_pcb, RTCS_LOGCTRL_PROTO(IPPROTO_IP), IP_VERSION);

      error = RTCSPCB_insert_header(rtcs_pcb, pktlen);
      if (error) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_IP_STATS_ENABLED(RTCS_seterror(&IP_cfg_ptr->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
         return error;
      } /* Endif */

      _mem_copy((uchar_ptr)packet, RTCSPCB_DATA(rtcs_pcb), pktlen);
      packet = (IP_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
      RTCSPCB_DATA_NETWORK(rtcs_pcb) = RTCSPCB_DATA(rtcs_pcb);

      /*
      ** Decrement the TTL and adjust the checksum
      */

      ttl--;
      htonc(packet->TTL, ttl);
      chksum = ntohs(packet->CHECKSUM);
      chksum = IP_Sum_immediate(chksum, 0x100);
      htons(packet->CHECKSUM, chksum);

      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_FORWARDED++);

   } /* Endif */

   rtcs_pcb->LINK_OPTIONS.RX.DEST  = ipdest;
   rtcs_pcb->LINK_OPTIONS.RX.TOS   = ntohc(packet->TOS);
   rtcs_pcb->LINK_OPTIONS.RX.TTL   = ntohc(packet->TTL);

   return RTCS_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_send_dgram
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Sends an IP datagram out an interface, fragmenting it if
*        necessary.
*
*END*-----------------------------------------------------------------*/

uint_32 IP_send_dgram
   (
      IP_IF_PTR      ifdest,     /* [IN] the outgoing interface */
      RTCSPCB_PTR    inrtcs_pcb, /* [IN] the packet to send */
      _ip_address    hopsrc,     /* [IN] the hop src */
      _ip_address    hopdest,    /* [IN] the hop dest */
      _ip_address    ipdest,     /* [IN] the ultimate dest */
      uint_32        protocol,   /* [IN] the transport layer protocol */
      pointer        data        /* [IN] routing entry data */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP);
   IP_HEADER_PTR     srciph;
   uint_32           iphlen;
   uint_32           srcdatalen;
   uint_32           dmtumax, dmtu;
   uint_32           srclen, offset, error;
   uchar_ptr         srcdata;
   PCB_FRAGMENT_PTR  frag_ptr;
   
   RTCSLOG_FNE2(RTCSLOG_FN_IP_send_dgram, ifdest);

   error = inrtcs_pcb->IP_COMPLETE(ifdest, &inrtcs_pcb, hopsrc, ipdest, protocol);
   if (error) {
      RTCSLOG_PCB_FREE(inrtcs_pcb, error);
      RTCSPCB_free(inrtcs_pcb);
      
      RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, error);
      return error;
   } /* Endif */

   /* If the packet doesn't exceed the MTU, send it directly */
   if (RTCSPCB_SIZE(inrtcs_pcb) <= ifdest->MTU) {
      error = ifdest->DEVICE.SEND(ifdest, inrtcs_pcb, hopsrc, hopdest, data);
      
      RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, error);
      return error;
   } /* Endif */

   srciph = (IP_HEADER_PTR)RTCSPCB_DATA(inrtcs_pcb);
   iphlen = (ntohc(srciph->VERSLEN) & 0x0F) << 2;
   srcdatalen = RTCSPCB_SIZE(inrtcs_pcb) - iphlen;

   /* If the datagram exceeds the MTU, but DF is set, respond with ICMP */
   if (ntohs(srciph->FRAGMENT) & IP_FRAG_DF) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_TX_FRAG_DISCARDED++);
      #if RTCSCFG_ENABLE_ICMP
      ICMP_send_error(ICMPTYPE_DESTUNREACH, ICMPCODE_DU_NEEDFRAG, ifdest->MTU, inrtcs_pcb, 0);
      #endif
      RTCSLOG_PCB_FREE(inrtcs_pcb, RTCSERR_IP_CANTFRAG);
      RTCSPCB_free(inrtcs_pcb);
      
      RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, RTCSERR_IP_CANTFRAG);
      return RTCSERR_IP_CANTFRAG;
   } /* Endif */

   /* Sanity check.  Note: it's an error to bind an interface with an MTU < 68 */
   if (iphlen + IP_FRAG_MIN > ifdest->MTU) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_TX_FRAG_DISCARDED++);
      RTCSLOG_PCB_FREE(inrtcs_pcb, RTCSERR_IP_SMALLMTU);
      RTCSPCB_free(inrtcs_pcb);
      
      RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, RTCSERR_IP_SMALLMTU);
      return RTCSERR_IP_SMALLMTU;
   } /* Endif */

   IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_TX_FRAG_FRAGD++);
   dmtumax = ifdest->MTU - iphlen;
   dmtu = dmtumax & (((uint_32)(-1))<<IP_FRAG_SHIFT);
   offset = (ntohs(srciph->FRAGMENT) & IP_FRAG_MASK) << IP_FRAG_SHIFT;
   srcdata = RTCSPCB_DATA(inrtcs_pcb) + iphlen;
   srclen = inrtcs_pcb->HEADER_FRAG_USED - iphlen;
   frag_ptr = inrtcs_pcb->PCBPTR->FRAG;

   do {
      IP_HEADER_PTR  dstiph;
      uchar_ptr      dstdata;
      uint_32        dstlen = (srcdatalen > dmtumax) ? dmtu : srcdatalen;
      RTCSPCB_PTR    rtcs_pcb;
      uint_16        chksum, fragment;

      /* Allocate the PCB */
      rtcs_pcb = RTCSPCB_alloc_send();
      if (rtcs_pcb == NULL) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         RTCSLOG_PCB_FREE(inrtcs_pcb, RTCSERR_PCB_ALLOC);
         RTCSPCB_free(inrtcs_pcb);
         
         RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, RTCSERR_PCB_ALLOC);
         return RTCSERR_PCB_ALLOC;
      } /* Endif */

      /* Allocate the memory for the IP data */
      dstdata = RTCS_mem_alloc_system(dstlen);
      if (dstdata == NULL) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_OUT_OF_MEMORY);
         RTCSPCB_free(rtcs_pcb);
         RTCSLOG_PCB_FREE(inrtcs_pcb, RTCSERR_OUT_OF_MEMORY);
         RTCSPCB_free(inrtcs_pcb);
         
         RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, RTCSERR_OUT_OF_MEMORY);
         return RTCSERR_OUT_OF_MEMORY;
      } /* Endif */
      _mem_set_type(dstdata, MEM_TYPE_IP_DATA);

      /* Append the data to the PCB */
      error = RTCSPCB_append_fragment_autofree(rtcs_pcb, dstlen, dstdata);
      if (error) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_IP_STATS_ENABLED(RTCS_seterror(&IP_cfg_ptr->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
         _mem_free(dstdata);
         RTCSLOG_PCB_FREE(rtcs_pcb, error);
         RTCSPCB_free(rtcs_pcb);
         RTCSLOG_PCB_FREE(inrtcs_pcb, error);
         RTCSPCB_free(inrtcs_pcb);
         
         RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, error);
         return error;
      } /* Endif */

      /* Allocate the IP header */
      error = RTCSPCB_insert_header(rtcs_pcb, iphlen);
      if (error) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_IP_STATS_ENABLED(RTCS_seterror(&IP_cfg_ptr->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
         /* don't _mem_free(dstdata) here because RTCSPCB_free(pcb) will do it */
         RTCSLOG_PCB_FREE(rtcs_pcb, error);
         RTCSPCB_free(rtcs_pcb);
         RTCSLOG_PCB_FREE(inrtcs_pcb, error);
         RTCSPCB_free(inrtcs_pcb);
         
         RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, error);
         return error;
      } /* Endif */

      /* Copy the IP header */
      dstiph = (IP_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
      RTCSPCB_DATA_NETWORK(rtcs_pcb) = RTCSPCB_DATA(rtcs_pcb);
      _mem_copy(srciph, dstiph, iphlen);

      /* Update the LENGTH field */
      htons(dstiph->LENGTH, iphlen + dstlen);

      /* Build the FRAGMENT field */
      fragment = offset >> IP_FRAG_SHIFT;
      offset     += dstlen;
      srcdatalen -= dstlen;
      /* An MF bit must be added on all fragments except the last */
      if (srcdatalen > 0 || (ntohs(srciph->FRAGMENT) & IP_FRAG_MF)) {
         fragment |= IP_FRAG_MF;
      } /* Endif */
      htons(dstiph->FRAGMENT, fragment);

      /* Recompute the IP header checksum */
      htons(dstiph->CHECKSUM, 0);
      chksum = _mem_sum_ip(0, iphlen, dstiph);
      chksum = IP_Sum_invert(chksum);
      htons(dstiph->CHECKSUM, chksum);

      /* Copy the IP data */
      for (;;) {
         uint_32 copylen = (srclen > dstlen) ? dstlen : srclen;
         _mem_copy(srcdata, dstdata, copylen);
         srcdata += copylen;
         dstdata += copylen;
         srclen  -= copylen;
         dstlen  -= copylen;
         if (dstlen == 0) break;
         frag_ptr++;
         srcdata = frag_ptr->FRAGMENT;
         srclen = frag_ptr->LENGTH;
      } /* Endfor */

      /* Send the fragment through the interface */
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_TX_FRAG_SENT++);
      error = ifdest->DEVICE.SEND(ifdest, rtcs_pcb, hopsrc, hopdest, data);
      if (error) {
         RTCSLOG_PCB_FREE(inrtcs_pcb, error);
         RTCSPCB_free(inrtcs_pcb);
         
         RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, error);
         return error;
      } /* Endif */

   } while (srcdatalen > 0);

   RTCSLOG_PCB_FREE(inrtcs_pcb, RTCS_OK);
   RTCSPCB_free(inrtcs_pcb);
   
   RTCSLOG_FNX2(RTCSLOG_FN_IP_send_dgram, RTCS_OK);
   return RTCS_OK;

#else
    
    RTCSLOG_PCB_FREE(inrtcs_pcb, RTCSERR_IP_IS_DISABLED);
    RTCSPCB_free(inrtcs_pcb);
    return RTCSERR_IP_IS_DISABLED; 

#endif /* RTCSCFG_ENABLE_IP4 */
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IP_source
* Returned Value  : source IP address
* Comments        :
*     Return source IP address of packet.
*
*END*-----------------------------------------------------------------*/


_ip_address IP_source
   (
      RTCSPCB_PTR    rtcs_pcb      /* [IN] packet to find source of */
   )
{
#if RTCSCFG_ENABLE_IP4

   uchar_ptr srcptr = ((IP_HEADER_PTR)RTCSPCB_DATA_NETWORK(rtcs_pcb))->SOURCE;

   return ntohl(srcptr);
   
#else
    
    return 0;

#endif /* RTCSCFG_ENABLE_IP4 */   

} 


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IP_dest
* Returned Value  : destination IP address
* Comments        :
*     Return destination IP address of packet.
*
*END*-----------------------------------------------------------------*/

_ip_address IP_dest
   (
      RTCSPCB_PTR    rtcs_pcb      /* [IN] packet to find dest of */
   )
{ 
#if RTCSCFG_ENABLE_IP4

   uchar_ptr dstptr = ((IP_HEADER_PTR)RTCSPCB_DATA_NETWORK(rtcs_pcb))->DEST;

   return ntohl(dstptr);
   
#else
    
    return 0;

#endif /* RTCSCFG_ENABLE_IP4 */
}




/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/pap.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pap.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation for the
*   Password Authentication Protocol.
*
*END************************************************************************/

#include <string.h>
#include <ppp.h>
#include "ppp_prv.h"


static void PAP_timeout (pointer, PCB_PTR, boolean);
static void PAP_up      (_ppp_handle);
static void PAP_fail    (_ppp_handle);
static void PAP_close   (pointer, PCB_PTR, boolean);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PAP_init
* Returned Value  :  void
* Comments        :
*     Called by PPP_initialize.  Initializes the PAP state.
*
*END*-----------------------------------------------------------------*/

void PAP_init
   (
      _ppp_handle   handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

   ppp_ptr->PAP_STATE.CLIENT_STATE = PAP_STATE_CLOSED;
   ppp_ptr->PAP_STATE.SERVER_STATE = PAP_STATE_CLOSED;

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PAP_timeout
* Returned Value  :  void
* Comments        :
*     Called by PPP_tx_task.  Timeout expired.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PAP_timeout
   (
      pointer        pap_data,
            /* [IN/OUT] - PAP state */
      PCB_PTR        pcb,
            /* [IN] - expired packet */
      boolean        hard
            /* [IN] - TRUE if this is a hard timeout (TO- event) */
   )
{ /* Body */
   PAP_DATA_PTR   pap_ptr = pap_data;

   /* Increment the identifier */
   pap_ptr->CURID = (pap_ptr->CURID + 1) & 0xFF;
   pcb->FRAG[0].FRAGMENT[3] = pap_ptr->CURID;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PAP_send
* Returned Value  :  void
* Comments        :
*     Called by LCP_up.  Sends an Authenticate-Request packet.
*
*END*-----------------------------------------------------------------*/

void PAP_send
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR    ppp_ptr = handle;
   PAP_DATA_PTR   pap_ptr = &ppp_ptr->PAP_STATE;
   PCB_PTR        pcb;
   uchar_ptr      outp;
   uint_16        len;

   pap_ptr->CLIENT_STATE = PAP_STATE_INITIAL;
   pap_ptr->CURID = RTCS_rand() & 0xFF;

   /* Acquire a PCB */
   len = PAP_HDR_LEN + 2
/* Start CR 2207 */
       + PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_LENGTH)
       + PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_LENGTH);
/* End CR 2207 */

   pcb = PPP_pcballoc(PPP_PROT_PAP, len);
   if (pcb == NULL) {
      return;
   } /* Endif */

   /* Build an Authenticate-Request packet */
   outp = pcb->FRAG[0].FRAGMENT + 2;
   *outp++ = PAP_CODE_AUTH_REQ;
   *outp++ = pap_ptr->CURID;
   *outp++ = (len >> 8) & 0xFF;
   *outp++ =  len       & 0xFF;
/* Start CR 2207 */
   *outp++ = len = PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_LENGTH);
   PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_PTR), outp, len);
   outp += len;
   *outp++ = len = PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_LENGTH);
   PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_PTR), outp, len);
/* End CR 2207 */

   /* Send the PCB */
   PPP_send_rexmit(ppp_ptr, PPP_PROT_PAP, pcb, 0, PAP_timeout, pap_ptr);

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PAP_open
* Returned Value  :  void
* Comments        :
*     Called by LCP_up.  Starts the PAP server.
*
*END*-----------------------------------------------------------------*/

void PAP_open
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

   ppp_ptr->PAP_STATE.SERVER_STATE = PAP_STATE_INITIAL;
   
#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PAP_input
* Returned Value  :  void
* Comments        :
*     Called by PPP_rx_task.  Parses a PAP packet.
* Side effects    :
*     Consumes (sends or frees) the packet.
*
*END*-----------------------------------------------------------------*/

void PAP_input
   (
      PCB_PTR        pcb,
            /* [IN] - PAP packet */
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR    ppp_ptr = handle;
   PAP_DATA_PTR   pap_ptr = &ppp_ptr->PAP_STATE;
   PPP_SECRET_PTR secret;
   uchar_ptr      inp = pcb->FRAG[0].FRAGMENT + 2;
   uchar_ptr      idp, pwp;
   uchar          code, id;
   uchar          idlen, pwlen;
   uint_16        len;
   boolean        delay = FALSE;

   /*
   ** Parse header (code, id and length).
   ** If packet too short, drop it.
   */
   if (pcb->FRAG[0].LENGTH < 2 + PAP_HDR_LEN) {
      pap_ptr->ST_PAP_SHORT++;
      PCB_free(pcb);
      return;
   } /* Endif */

   code = *inp++;
   id = *inp++;
   len = *inp++ << 8;
   len += *inp++;

   if ((len < PAP_HDR_LEN) || (len > pcb->FRAG[0].LENGTH - 2)) {
      pap_ptr->ST_PAP_SHORT++;
      PCB_free(pcb);
      return;
   } /* Endif */
   len -= PAP_HDR_LEN;

   switch (code) {

   case PAP_CODE_AUTH_REQ:

      switch (pap_ptr->SERVER_STATE) {
      case PAP_STATE_INITIAL:

         /* Parse the peer id and password */
         idp = inp;
         idlen = *idp++;
         pwp = idp + idlen;
         pwlen = *pwp++;
         if (len < idlen + pwlen + 2) {
            pap_ptr->ST_PAP_SHORT++;
            PCB_free(pcb);
            break;
         } /* Endif */

         /* Match id/password pair against the secrets table */
/* Start CR 2207 */
         secret = PPP_SECRET(ppp_ptr,_PPP_PAP_RSECRETS);
/* End CR 2207 */
         for (;;) {
            if ((secret->PPP_ID_LENGTH == 0)
             && (secret->PPP_PW_LENGTH == 0)) {
               pap_ptr->SERVER_STATE = PAP_STATE_AUTH_NAK;
               PAP_fail(handle);
               delay = TRUE;
               break;
            } /* Endif */
            if ((secret->PPP_ID_LENGTH == idlen)
             && (secret->PPP_PW_LENGTH == pwlen)
             && (memcmp(secret->PPP_ID_PTR, idp, idlen) == 0)
             && (memcmp(secret->PPP_PW_PTR, pwp, pwlen) == 0)) {
               pap_ptr->SERVER_STATE = PAP_STATE_AUTH_ACK;
               PAP_up(handle);
               break;
            } /* Endif */
            secret++;
         } /* Endfor */

         /* fall through */
      case PAP_STATE_AUTH_ACK:
      case PAP_STATE_AUTH_NAK:
         /* Build an Auth-Ack or Auth-Nak reply */
         inp = pcb->FRAG[0].FRAGMENT + 2;
         *inp++ = pap_ptr->SERVER_STATE;
         inp++;                              /* Keep same ID */
         *inp++ = 0;
         *inp++ = 5;
         *inp++ = 0;
         pcb->FRAG[0].LENGTH = 7;
         if (delay) {
            PPP_send_rexmit(ppp_ptr, PPP_PROT_PAP, pcb, 1, PAP_close, handle);
         } else {
            PPP_send_one(ppp_ptr, PPP_PROT_PAP, pcb);
         } /* Endif */
         break;

      default:
         pap_ptr->ST_PAP_NOAUTH++;
         PCB_free(pcb);
         break;
      } /* Endswitch */
      break;

   case PAP_CODE_AUTH_ACK:
       pap_ptr->CLIENT_STATE = PAP_STATE_AUTH_ACK;
       PAP_up(handle);
   case PAP_CODE_AUTH_NAK:
      if (pap_ptr->CLIENT_STATE != PAP_STATE_AUTH_ACK) {
         pap_ptr->CLIENT_STATE = PAP_STATE_AUTH_NAK;
      } /* Endif */
      
      if (pap_ptr->CLIENT_STATE != PAP_STATE_INITIAL && pap_ptr->CLIENT_STATE != PAP_STATE_AUTH_ACK) {
         pap_ptr->ST_PAP_NOREQ++;
      } else if (id != pap_ptr->CURID) {
         pap_ptr->ST_PAP_ID++;
      } else if (len < 1) {
         pap_ptr->ST_PAP_SHORT++;
      } else if (--len < *inp++) {
         pap_ptr->ST_PAP_SHORT++;
      } else {
         /* All is well -- stop send Auth-Req's */
         PPP_send_stop(ppp_ptr, PPP_PROT_PAP);
      } /* Endif */
      PCB_free(pcb);
      break;

   default:
      pap_ptr->ST_PAP_CODE++;
      PCB_free(pcb);
      break;
   } /* Endswitch */

#else

    PCB_free(pcb);

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PAP_up
* Returned Value  :  void
* Comments        :
*     Called by PAP_input once the peer has been authenticated.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PAP_up
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = handle;

   PPP_mutex_lock(&ppp_ptr->MUTEX);
   ppp_ptr->LINK_AUTH = TRUE;
   PPP_mutex_unlock(&ppp_ptr->MUTEX);

   PPP_up(handle);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PAP_fail
* Returned Value  :  void
* Comments        :
*     Called by PAP_input if the peer's credentials are rejected.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PAP_fail
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = handle;
   PPP_CALL_INTERNAL_PTR call_ptr = &ppp_ptr->LCP_CALL[PPP_CALL_AUTH_FAIL];

   if (call_ptr->CALLBACK) {
      call_ptr->CALLBACK(call_ptr->PARAM);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PAP_close
* Returned Value  :  void
* Comments        :
*     Called by the Tx task.  Terminates the link after an
*     Authenticate-Nak packet is sent.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void PAP_close
   (
      pointer        handle,
            /* [IN] - the PPP state structure */
      PCB_PTR        pcb,
            /* [IN] - expired packet */
      boolean        hard
            /* [IN] - TRUE if this is a hard timeout (TO- event) */
   )
{ /* Body */

   PPP_close(handle);

} /* Endbody */


#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_lpt_kinetis.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_lpt_kinetis.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains board-specific LPT initialization functions.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>


static const pointer lpt_address[] =
{
    (pointer)LPTMR0_BASE_PTR
};


static const uint_32 lpt_vectors[] =
{
    INT_LPTimer
};


static const CM_CLOCK_SOURCE lpt_clock_source[] =
{
    CM_CLOCK_SOURCE_MCGIR,
    CM_CLOCK_SOURCES,
    CM_CLOCK_SOURCE_ERCLK32K,
    CM_CLOCK_SOURCE_OSCER
};


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_lpt_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding LPT
*    module.
*
*END*----------------------------------------------------------------------*/

pointer _bsp_get_lpt_base_address
    (
        /* [IN] LPT index */
        uint_8 dev_num
    )
{
    if (dev_num < ELEMENTS_OF(lpt_address)) 
    {
        return lpt_address[dev_num];
    }
    return NULL;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_lpt_vector
* Returned Value   : Number of vectors associated with the peripheral
* Comments         :
*    This function returns desired interrupt vector for specified LPT module.
*
*END*----------------------------------------------------------------------*/

uint_32 _bsp_get_lpt_vector
    (
        /* [IN] LPT index */
        uint_8 dev_num
    )
{
    if (dev_num < ELEMENTS_OF(lpt_vectors)) 
    {
        return lpt_vectors[dev_num];
    } 
    else 
    {
        return 0;
    }
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_lpt_clock_frequency
* Returned Value   : Frequency for given clock source
* Comments         :
*    This function returns the input clock frequency for corresponding LPT
*    module and input source.
*
*END*----------------------------------------------------------------------*/

uint_32 _bsp_get_lpt_clock_frequency
    (
        /* [IN] LPT index */
        uint_8  dev_num,
        
        /* [IN} LPT clock source index */
        uint_32 source
    )
{
    if (source < ELEMENTS_OF(lpt_clock_source)) 
    {
        if (CM_CLOCK_SOURCES != lpt_clock_source[source])
        {
            return _bsp_get_clock (_bsp_get_clock_configuration (), lpt_clock_source[source]);
        }
        else
        {
            return 1000;
        }
    }
    return 0;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_enable_lpt_clock
* Returned Value   : MQX error code
* Comments         :
*    This function enables the clock for LPT so the registers are accessible.
*
*END*----------------------------------------------------------------------*/

uint_32 _bsp_enable_lpt_clock
    (
        /* [IN] LPT index */
        uint_8  dev_num
    )
{
    if (dev_num < ELEMENTS_OF(lpt_address)) 
    {
        SIM_SCGC5 |= SIM_SCGC5_LPTIMER_MASK;
        return MQX_OK;
    }
    return MQX_INVALID_DEVICE;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/sdgram.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sdgram.c$
* $Version : 3.8.7.0$
* $Date    : Jun-27-2012$
*
* Comments:
*
*   This file contains the socket interface functions for
*   (PF_INET,SOCK_DGRAM) sockets.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"

#if RTCSCFG_ENABLE_UDP

#include "tcpip.h"
#include "udp.h"
#include "socket.h"

#define RTCS_ENTER(f,a)    RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_DGRAM_ ## f, a)

#define RTCS_EXIT(f,a)     RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_DGRAM_ ## f, a); \
                           return a

#define RTCS_EXIT2(f,a,e)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_DGRAM_ ## f, a); \
                           return e


uint_32 SOCK_DGRAM_socket      (uint_32);
uint_32 SOCK_DGRAM_bind        (uint_32, const sockaddr _PTR_, uint_16);
uint_32 SOCK_DGRAM_connect     (uint_32, const sockaddr _PTR_, uint_16);
uint_32 SOCK_DGRAM_getsockname (uint_32, sockaddr _PTR_, uint_16 _PTR_);
uint_32 SOCK_DGRAM_getpeername (uint_32, sockaddr _PTR_, uint_16 _PTR_);
 int_32 SOCK_DGRAM_recv        (uint_32, pointer, uint_32, uint_32);
 int_32 SOCK_DGRAM_recvfrom    (uint_32, pointer, uint_32, uint_32, sockaddr _PTR_, uint_16 _PTR_);//IPv4+6
 int_32 SOCK_DGRAM_send        (uint_32, pointer, uint_32, uint_32);
 int_32 SOCK_DGRAM_sendto      (uint_32, pointer, uint_32, uint_32, sockaddr _PTR_, uint_16);
uint_32 SOCK_DGRAM_shutdown    (uint_32, uint_32);

const RTCS_SOCKET_CALL_STRUCT SOCK_DGRAM_CALL = {
   SOCK_DGRAM_socket,
   SOCK_DGRAM_bind,
   SOCK_DGRAM_connect,
   NULL,
   NULL,
   SOCK_DGRAM_getsockname,
   SOCK_DGRAM_getpeername,
   SOCK_DGRAM_recv,
   SOCK_DGRAM_recvfrom,
   NULL,
   SOCK_DGRAM_send,
   SOCK_DGRAM_sendto,
   NULL,
   NULL,
   SOCK_DGRAM_shutdown
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_socket
* Returned Value  : error code
* Comments  :  Creates an unbound socket.
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_DGRAM_socket
   (
      uint_32     sock
         /* [IN] socket handle */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;

   error = RTCSCMD_issue(parms, UDP_open);
   if (error) return error;

   ((SOCKET_STRUCT_PTR)sock)->STATE         = SOCKSTATE_DGRAM_GROUND;
   ((SOCKET_STRUCT_PTR)sock)->UCB_PTR       = parms.ucb;
   ((SOCKET_STRUCT_PTR)sock)->MCB_PTR       = &parms.ucb->MCB_PTR;
   ((SOCKET_STRUCT_PTR)sock)->IGMP_LEAVEALL = &parms.ucb->IGMP_LEAVEALL;
   return RTCS_OK;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
************************************************************************
*
* Function Name   : SOCK_DGRAM_bind
* Returned Value  : error code 
*
* Comments  :  Binds the local endpoint of a socket. Support IPv6 and IPv4
*
************************************************************************
*END*-----------------------------------------------------------------*/
uint_32  SOCK_DGRAM_bind
   (
      uint_32                    sock,
         /* [IN] socket handle */
      const sockaddr _PTR_    localaddr,
         /* [IN] local address to which to bind the socket */
      uint_16                    addrlen
         /* [IN] length of the address, in bytes */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;

   RTCS_ENTER(BIND, sock);

#if RTCSCFG_CHECK_ERRORS
   if(((SOCKET_STRUCT_PTR)sock)->STATE != SOCKSTATE_DGRAM_GROUND) 
   {
      RTCS_EXIT(BIND, RTCSERR_SOCK_IS_BOUND);
   } /* Endif */
#endif

#if RTCSCFG_CHECK_ADDRSIZE

    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (localaddr->sa_family == AF_INET) 
            {
        #endif
                if (addrlen < sizeof(sockaddr_in)) 
                {
                    RTCS_EXIT(BIND, RTCSERR_SOCK_SHORT_ADDRESS);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (localaddr->sa_family == AF_INET6) 
            {
        #endif
                if (addrlen < sizeof(struct sockaddr_in6)) 
                {
                    RTCS_EXIT(BIND, RTCSERR_SOCK_SHORT_ADDRESS);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
#endif


#if RTCSCFG_CHECK_ERRORS
    error =1;

    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (localaddr->sa_family == AF_INET) 
            {
        #endif
                error = 0;
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (localaddr->sa_family == AF_INET6) 
            {
        #endif
                error = 0;
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
        if (error != 0) 
        {
            RTCS_EXIT(BIND, RTCSERR_SOCK_INVALID_AF);
        } /* Endif */
#endif


   parms.ucb        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
   parms.udpword    = sock;


    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (localaddr->sa_family == AF_INET) 
            {
        #endif
                parms.udpport    =((sockaddr_in *)localaddr)->sin_port;
                parms.udpservice = UDP_process;
                parms.ipaddress  =((sockaddr_in *)localaddr)->sin_addr.s_addr;
                error = RTCSCMD_issue(parms, UDP_bind);
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (localaddr->sa_family == AF_INET6) 
            {
        #endif
                parms.udpport    =((sockaddr_in6 *)localaddr)->sin6_port;
                parms.udpservice = UDP_process6;
                memcpy( &(parms.ipv6address), &(((sockaddr_in6 *)localaddr)->sin6_addr),sizeof(struct in6_addr));
                /*add scope_id here*/
                parms.if_scope_id = ((sockaddr_in6 *)localaddr)->sin6_scope_id;
                error = RTCSCMD_issue(parms, UDP_bind6);
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
   if (error) 
   {
      RTCS_EXIT(BIND, error);
   } /* Endif */


   ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_DGRAM_BOUND;

   RTCS_EXIT(BIND, RTCS_OK);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
************************************************************************
*
* Function Name   : SOCK_DGRAM_connect
* Returned Value  : error code
* Comments  :  Binds the remote endpoint of a socket. Support IPv6 and IPv4.
*
*     1. If connect succeeds the socket is in OPEN state.
*     2. If connect fails, the socket is in BOUND or GROUND state, and the
*        local IP is the same as it was immediatly after the bind() call.
*
***********************************************************************
*END*-----------------------------------------------------------------*/
uint_32  SOCK_DGRAM_connect
   (
      uint_32                    sock,
         /* [IN] socket handle */
      const struct sockaddr _PTR_    peeraddr,
         /* [IN] remote address to which to bind the socket */
      uint_16                    addrlen
         /* [IN] length of the address, in bytes */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error = RTCS_OK;
   uint_16     state = ((SOCKET_STRUCT_PTR)sock)->STATE;
    
    
   RTCS_ENTER(CONNECT, sock);

#if RTCSCFG_CHECK_ADDRSIZE


    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (peeraddr->sa_family == AF_INET) 
            {
        #endif
                if (addrlen < sizeof(sockaddr_in)) 
                {
                    error = RTCSERR_SOCK_SHORT_ADDRESS;
                } /* Endif */
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (peeraddr->sa_family == AF_INET6) 
            {
        #endif
                if (addrlen < sizeof(struct sockaddr_in6)) 
                {
                    error = RTCSERR_SOCK_SHORT_ADDRESS;
                } /* Endif */
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
#endif

#if RTCSCFG_CHECK_ERRORS
        if(!error)
        {
            error = RTCSERR_SOCK_INVALID_AF;
    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if(peeraddr->sa_family == AF_INET) 
            {
        #endif
                error = RTCS_OK;
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if(peeraddr->sa_family == AF_INET6) 
            {
        #endif
                error = RTCS_OK;
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
        
        }
#endif

   
   /* If socket is unbound, bind it  SOCK_DGRAM_bind */
   if (state == SOCKSTATE_DGRAM_GROUND) 
   {
      //struct sockaddr_in6 localaddr;   
      struct sockaddr localaddr;   

      if (error)  
      {
         RTCS_EXIT(CONNECT, error);
      } /* Endif */

     
    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (peeraddr->sa_family == AF_INET) 
            {
        #endif

                localaddr.sa_family = AF_INET;
                ((sockaddr_in*)&localaddr)->sin_port = 0;
                /*Set INADDR_ANY address*/
                memset(&(((sockaddr_in*)&localaddr)->sin_addr), 0, sizeof(in_addr));

        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (peeraddr->sa_family == AF_INET6) 
            {
        #endif
                localaddr.sa_family = AF_INET6;
                ((sockaddr_in6 *)&localaddr)->sin6_port = 0;
                /* add local scope_id here */
                ((sockaddr_in6 *)&localaddr)->sin6_scope_id = 0;
                /*Set INADDR_ANY address*/
                memset(&(((sockaddr_in6 *)&localaddr)->sin6_addr), 0, sizeof(in6_addr));
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
      
      error = SOCK_DGRAM_bind(sock, &localaddr, sizeof(localaddr));
      if (error)  {
         RTCS_EXIT(CONNECT, error);
      } /* Endif */
   } /* Endif */



   /** check below for IPv6 ************************************/
   /*
   ** Set socket in BOUND state and proceed normaly. If connect
   ** fails, leave the socket in BOUND state. If connect
   ** succeeds, set state to OPEN.
   */
   ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_DGRAM_BOUND;

    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (peeraddr->sa_family == AF_INET) 
            {
        #endif
                parms.ipaddress =((sockaddr_in *)peeraddr)->sin_addr.s_addr;
                parms.udpport   =((sockaddr_in *)peeraddr)->sin_port;
                parms.ucb       =((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
                parms.udpword   = error;
                error = RTCSCMD_issue(parms, UDP_connect);
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (peeraddr->sa_family == AF_INET6) 
            {
        #endif
                memcpy( &(parms.ipv6address), &(((sockaddr_in6 *)peeraddr)->sin6_addr),sizeof(struct in6_addr));
                parms.udpport   = ((sockaddr_in6 *)peeraddr)->sin6_port;
                parms.ucb       = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
                parms.udpword   = error;
               /*
                * choose and add scope_id here. 
                * If peeraddr(target addr) scope_id is NULL we well use local(binded) scope_id 
                */
                parms.if_scope_id = ((sockaddr_in6 *)peeraddr)->sin6_scope_id;
                if(parms.if_scope_id ==0)
                {
                    parms.if_scope_id = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->IF_SCOPE_ID;                        
                }
                error = RTCSCMD_issue(parms, UDP_connect6);
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
    
   if (error) {
      RTCS_EXIT(CONNECT, error);
   } /* Endif */

   /* Success */
   ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_DGRAM_OPEN;
   RTCS_EXIT(CONNECT, RTCS_OK);

} /* Endbody */



#if 0
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_getsockname
* Returned Value  : error code
* Comments  :  Retrieve the address of the local endpoint of a
*              bound socket.
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_DGRAM_getsockname
   (
      uint_32              sock,
         /* [IN] socket handle */
      sockaddr_in _PTR_    name,
         /* [OUT] address of local endpoint */
      uint_16     _PTR_    namelen
         /* [IN/OUT] length of the address, in bytes */
   )
{ /* Body */

   RTCS_ENTER(GETSOCKNAME, sock);

#if RTCSCFG_CHECK_ERRORS
   if (((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) {
      RTCS_EXIT(GETSOCKNAME, RTCSERR_SOCK_NOT_BOUND);
   } /* Endif */
#endif

   if (!namelen) {

#if RTCSCFG_CHECK_ADDRSIZE
   } else if (*namelen < sizeof(sockaddr_in)) {
      sockaddr_in fullname;
      fullname.sin_family      = AF_INET;
      fullname.sin_port        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->PORT;
      fullname.sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->IPADDR;
      _mem_copy(&fullname, name, *namelen);
      *namelen = sizeof(sockaddr_in);
#endif

   } else {
      name->sin_family      = AF_INET;
      name->sin_port        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->PORT;
      name->sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->IPADDR;
      *namelen = sizeof(sockaddr_in);

   } /* Endif */

   RTCS_EXIT(GETSOCKNAME, RTCS_OK);

} /* Endbody */

#endif



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_getsockname
* Returned Value  : error code
* Comments  :  Retrieve the address of the local endpoint of a
*              bound socket.Support IPv6 and IPv4
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_DGRAM_getsockname
   (
      uint_32              sock,
         /* [IN] socket handle */
      sockaddr _PTR_       name,
         /* [OUT] address of local endpoint */
      uint_16     _PTR_    namelen
         /* [IN/OUT] length of the address, in bytes */
   )
{ /* Body */

   RTCS_ENTER(GETSOCKNAME, sock);

#if RTCSCFG_CHECK_ERRORS
   if (((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) {
      RTCS_EXIT(GETSOCKNAME, RTCSERR_SOCK_NOT_BOUND);
   } /* Endif */
#endif

    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif
                if (!namelen) 
                {

        #if RTCSCFG_CHECK_ADDRSIZE
                } else if (*namelen < sizeof(sockaddr_in)) 
                {
                    sockaddr_in fullname;
                    fullname.sin_family      = AF_INET;
                    fullname.sin_port        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->PORT;
                    fullname.sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->IPADDR;
                    _mem_copy(&fullname, name, *namelen);
        #endif
                }
                else 
                {
                    ((sockaddr_in *)name)->sin_family      = AF_INET;
                    ((sockaddr_in *)name)->sin_port        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->PORT;
                    ((sockaddr_in *)name)->sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->IPADDR;
                    *namelen = sizeof(sockaddr_in);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                if(!namelen) 
                {

        #if RTCSCFG_CHECK_ADDRSIZE
                } 
                else if (*namelen < sizeof(struct sockaddr_in6)) 
                {
                    struct sockaddr_in6 fullname;
                    fullname.sin6_family      = AF_INET6;
                    fullname.sin6_port        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT;
                    IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->UCB_PTR->IPV6ADDR,&(fullname.sin6_addr));
                    _mem_copy(&fullname,name, *namelen);
        #endif
                } 
                else 
                {
                    ((sockaddr_in6 *)name)->sin6_family   = AF_INET6;
                    ((sockaddr_in6 *)name)->sin6_port     = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT;
                    IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->UCB_PTR->IPV6ADDR,&(((sockaddr_in6 *)name)->sin6_addr));
                    *namelen = sizeof(sockaddr_in6);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif

   RTCS_EXIT(GETSOCKNAME, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_getpeername
* Returned Value  : error code
* Comments  :  Retrieve the address of the peer endpoint of a
*              connected socket.
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_DGRAM_getpeername
   (
      uint_32              sock,
         /* [IN] socket handle */
      sockaddr _PTR_    name,
         /* [OUT] address of peer endpoint */
      uint_16     _PTR_    namelen
         /* [IN/OUT] length of the address, in bytes */
   )
{ /* Body */

        RTCS_ENTER(GETPEERNAME, sock);

    #if RTCSCFG_CHECK_ERRORS
        if (((SOCKET_STRUCT_PTR)sock)->STATE != SOCKSTATE_DGRAM_OPEN) 
        {
            RTCS_EXIT(GETPEERNAME, RTCSERR_SOCK_NOT_CONNECTED);
        } /* Endif */
    #endif


    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif
                if (!namelen) 
                {

        #if RTCSCFG_CHECK_ADDRSIZE
                } else if (*namelen < sizeof(sockaddr_in)) 
                {
                    sockaddr_in fullname;
                    fullname.sin_family      = AF_INET;
                    fullname.sin_port        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT;
                    fullname.sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_HOST;
                    _mem_copy(&fullname, name, *namelen);
        #endif
                }
                else 
                {
                    ((sockaddr_in *)name)->sin_family      = AF_INET;
                    ((sockaddr_in *)name)->sin_port        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT;
                    ((sockaddr_in *)name)->sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_HOST;
                    *namelen = sizeof(sockaddr_in);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                if(!namelen) 
                {

        #if RTCSCFG_CHECK_ADDRSIZE
                } 
                else if (*namelen < sizeof(struct sockaddr_in6)) 
                {
                    struct sockaddr_in6 fullname;
                    fullname.sin6_family      = AF_INET6;
                    fullname.sin6_port        = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT;
                    IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_HOST6,&(fullname.sin6_addr));
                    _mem_copy(&fullname,name, *namelen);
        #endif
                } 
                else 
                {
                    ((sockaddr_in6 *)name)->sin6_family   = AF_INET6;
                    ((sockaddr_in6 *)name)->sin6_port     = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_PORT;
                    IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->UCB_PTR->REMOTE_HOST6,&(((sockaddr_in6 *)name)->sin6_addr));
                    *namelen = sizeof(sockaddr_in);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
 
    RTCS_EXIT(GETPEERNAME, RTCS_OK); 
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_recv
* Returned Value  : number of bytes received or RTCS_ERROR
* Comments  :  Receives data from a socket.
*
*END*-----------------------------------------------------------------*/

int_32  SOCK_DGRAM_recv
   (
      uint_32        sock,
         /* [IN] socket handle */
      pointer        buffer,
         /* [IN] buffer for received data */
      uint_32        buflen,
         /* [IN] length of the buffer, in bytes */
      uint_32        flags
         /* [IN] flags to underlying protocols */
   )
{ /* Body */
   int_32   len;

   RTCS_ENTER(RECV, sock);
   len = SOCK_DGRAM_recvfrom(sock, buffer, buflen, flags, NULL, NULL);
   RTCS_EXIT2(RECV, (len < 0) ? RTCS_ERROR : RTCS_OK, len);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_recvfrom
* Returned Value  : number of bytes received or RTCS_ERROR
* Comments  :  Receive data from a socket for IPv6 and IPv4 family.
*
*END*-----------------------------------------------------------------*/
int_32  SOCK_DGRAM_recvfrom
   (
      uint_32              sock,
         /* [IN] socket handle */
      pointer              buffer,
         /* [IN] buffer for received data */
      uint_32              buflen,
         /* [IN] length of the buffer, in bytes */
      uint_32              flags,
         /* [IN] flags to underlying protocols */
      
         /*sockaddr_in6 _PTR_    sourceaddr,*/
      struct sockaddr _PTR_ sourceaddr,
         /* [OUT] address from which data was received */
      uint_16     _PTR_    addrlen
         /* [IN/OUT] length of the address, in bytes */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;

   RTCS_ENTER(RECVFROM, sock);

#if RTCSCFG_CHECK_ERRORS
   if (((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) {
      RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_BOUND);
      RTCS_EXIT2(RECVFROM, RTCSERR_SOCK_NOT_BOUND, RTCS_ERROR);
   } /* Endif */
#endif

    parms.ucb      = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
    parms.udpptr   = buffer;
    parms.udpword  = buflen;
    parms.udpflags = flags;

    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif

                error = RTCSCMD_issue(parms, UDP_receive);
                if (error) 
                {
                    RTCS_setsockerror(sock, error);
                    RTCS_EXIT2(RECVFROM, error, RTCS_ERROR);
                } /* Endif */
                if (!addrlen) 
                {
                #if RTCSCFG_CHECK_ADDRSIZE
                } 
                else if (*addrlen < sizeof(sockaddr_in)) 
                {
                    sockaddr_in fullname;
                    fullname.sin_family      = AF_INET;
                    fullname.sin_port        = parms.udpport;
                    fullname.sin_addr.s_addr = parms.ipaddress;
                    _mem_copy(&fullname, sourceaddr, *addrlen);
                    *addrlen = sizeof(sockaddr_in);
                #endif
                } 
                else 
                {
                    ((sockaddr_in *)sourceaddr)->sin_family      = AF_INET;
                    ((sockaddr_in *)sourceaddr)->sin_port        = parms.udpport;
                    ((sockaddr_in *)sourceaddr)->sin_addr.s_addr = parms.ipaddress;
                    *addrlen = sizeof(sockaddr_in);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                error = RTCSCMD_issue(parms, UDP_receive6);
                if (error) 
                {
                    RTCS_setsockerror(sock, error);
                    RTCS_EXIT2(RECVFROM, error, RTCS_ERROR);
                } /* Endif */
                /* copy addr structure to output */ 
                if(!addrlen)//if parameter of addrlen is not NULL
                {
                #if RTCSCFG_CHECK_ADDRSIZE
                } 
                else if (*addrlen < sizeof(struct sockaddr_in6)) 
                {
                    struct sockaddr_in6 fullname;
                    fullname.sin6_family      = AF_INET6;
                    fullname.sin6_port        = parms.udpport;
                    fullname.sin6_scope_id    = parms.if_scope_id;
                    IN6_ADDR_COPY(&(parms.ipv6address),&(fullname.sin6_addr));
                    /*do safe mem copy to avoid overflow*/
                    _mem_copy(&fullname, sourceaddr, *addrlen);
                    /*return real value of size of addr structure*/
                    *addrlen = sizeof(struct sockaddr_in6);
                #endif
                } 
                else 
                {   
                    ((sockaddr_in6 *)sourceaddr)->sin6_family      = AF_INET6;
                    ((sockaddr_in6 *)sourceaddr)->sin6_port        = parms.udpport;
                    ((sockaddr_in6 *)sourceaddr)->sin6_scope_id    = parms.if_scope_id;
                    IN6_ADDR_COPY(&(parms.ipv6address),&(((sockaddr_in6 *)sourceaddr)->sin6_addr));
                    *addrlen = sizeof(struct sockaddr_in6);
                }
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
   
   RTCS_EXIT2(RECVFROM, RTCS_OK, parms.udpword);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_send
* Returned Value  : number of bytes sent or RTCS_ERROR
* Comments  :  Send data to a connected socket.
*
*END*-----------------------------------------------------------------*/

int_32  SOCK_DGRAM_send
   (
      uint_32        sock,
         /* [IN] socket handle */
      pointer        buffer,
         /* [IN] data to transmit */
      uint_32        buflen,
         /* [IN] length of the buffer, in bytes */
      uint_32        flags
         /* [IN] flags to underlying protocols */
   )
{ /* Body */
   int_32 len= -1 ; // it will generate error if AF != AF_INET or AF_INET6

   RTCS_ENTER(SEND, sock);
     
   len = SOCK_DGRAM_sendto(sock, buffer, buflen, flags, NULL, 0);
 
   RTCS_EXIT2(SEND, (len < 0) ? RTCS_ERROR : RTCS_OK, len);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_sendto
* Returned Value  : number of bytes sent or RTCS_ERROR
* Comments  :  Send data to a socket.
*
*END*-----------------------------------------------------------------*/

int_32  SOCK_DGRAM_sendto
   (
      uint_32              sock,
         /* [IN] socket handle */
      pointer              send_buffer,
         /* [IN] data to transmit */
      uint_32              buflen,
         /* [IN] length of the buffer, in bytes */
      uint_32              flags,
         /* [IN] flags to underlying protocols */
      sockaddr _PTR_    destaddr,
         /* [IN] address to which to send data */
      uint_16              addrlen
         /* [IN] length of the address, in bytes */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;
   sockaddr    addr;
   uint_16     len = sizeof(addr);

   RTCS_ENTER(SENDTO, sock);

#if RTCSCFG_CHECK_ADDRSIZE
   
    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif

                if(destaddr && addrlen < sizeof(sockaddr_in)) 
                {
                    RTCS_setsockerror(sock, RTCSERR_SOCK_SHORT_ADDRESS);
                    RTCS_EXIT2(SENDTO, RTCSERR_SOCK_SHORT_ADDRESS, RTCS_ERROR);
                } /* Endif */

        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                if(destaddr && addrlen < sizeof(sockaddr_in6)) 
                {
                    RTCS_setsockerror(sock, RTCSERR_SOCK_SHORT_ADDRESS);
                    RTCS_EXIT2(SENDTO, RTCSERR_SOCK_SHORT_ADDRESS, RTCS_ERROR);
                } /* Endif */

        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif

#endif


   if(!destaddr) 
   {
      error = SOCK_DGRAM_getpeername(sock, &addr, &len);
      if(error) 
      {
         RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_CONNECTED);
         RTCS_EXIT2(SENDTO, RTCSERR_SOCK_NOT_CONNECTED, RTCS_ERROR);
      } /* Endif */
   } 
   else 
   {

      _mem_copy(destaddr, &addr, sizeof(addr));

   } /* Endif */


    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif
                if(((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) 
                {
                    sockaddr_in localaddr;
                    localaddr.sin_family      = AF_INET;
                    localaddr.sin_port        = 0;
                    localaddr.sin_addr.s_addr = INADDR_ANY;
                    error = SOCK_DGRAM_bind(sock,(sockaddr *)&localaddr, sizeof(localaddr));
                    if(error) 
                    {
                        RTCS_setsockerror(sock, error);
                        RTCS_EXIT2(SENDTO, error, RTCS_ERROR);
                    } /* Endif */
                } /* Endif */
                parms.ipaddress = ((sockaddr_in *)&addr)->sin_addr.s_addr;
                parms.udpport   = ((sockaddr_in *)&addr)->sin_port;

        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                if(((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) 
                {
                    struct sockaddr_in6 localaddr;
                    localaddr.sin6_family      = AF_INET6;
                    localaddr.sin6_port        = 0;
                    IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(localaddr.sin6_addr));
                    error = SOCK_DGRAM_bind(sock, (sockaddr *)&localaddr, sizeof(localaddr));
                    if (error) 
                    {
                        RTCS_setsockerror(sock, error);
                        RTCS_EXIT2(SENDTO, error, RTCS_ERROR);
                    } /* Endif */
                } /* Endif */

                IN6_ADDR_COPY(&(((sockaddr_in6 *)&addr)->sin6_addr),&(parms.ipv6address));
                parms.udpport   = ((sockaddr_in6 *)&addr)->sin6_port;
                parms.if_scope_id =((sockaddr_in6 *)&addr)->sin6_scope_id; 
   
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
   
   parms.ucb       = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
   parms.udpptr    = send_buffer;
   parms.udpword   = buflen;
   parms.udpflags  = flags;

   error = RTCSCMD_issue(parms, UDP_send);

   if(error) 
   {
      RTCS_setsockerror(sock, error);
      RTCS_EXIT2(SENDTO, error, RTCS_ERROR);
   } /* Endif */

   RTCS_EXIT2(SENDTO, RTCS_OK, buflen);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_shutdown
* Returned Value  : error code
* Comments  :  Close a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_DGRAM_shutdown
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        how
         /* [IN] how to terminate the socket */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;

   RTCS_ENTER(SHUTDOWN, sock);

   parms.ucb = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
   error = RTCSCMD_issue(parms, UDP_close);
   if (error) {
      RTCS_EXIT(SHUTDOWN, error);
   } /* Endif */

   RTCS_EXIT(SHUTDOWN, RTCS_OK);

} /* Endbody */

#endif 
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_ControllerPIr.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_ControllerPIr.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_ControllerPIr function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_CONTROLLER_PIR_H
#define _GFLIB_CONTROLLER_PIR_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif

/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GFLIB_ControllerPIrANSIC function.*/
#define GFLIB_ControllerPIr(f32InErr,pParam)\
        GFLIB_ControllerPIrANSIC(f32InErr, pParam)

/*! Macro containing default values of the recurrent form PI controller structure.*/
#define GFLIB_CONTROLLER_PI_R_DEFAULT   {0,0,0,0,0}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_CONTROLLER_PI_R_T "\GFLIB_ControllerPIr.h"

@brief  Structure containing parameters and states of the recurrent form PI controller.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32 f32CC1sc;   /*!< CC1 coefficient, fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ */
    Frac32 f32CC2sc;   /*!< CC2 coefficient, fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ */
    Frac32 f32Acc;     /*!< Internal controller accumulator */
    Frac32 f32InErrK1; /*!< Controller input from the previous calculation step */
    UWord16    u16NShift;  /*!< Scaling factor for controller coefficients, integer format \f$\left[0,31\right]\f$ */
}GFLIB_CONTROLLER_PI_R_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*!
* @ingroup GFLIB_GROUP
*/

extern Frac32 GFLIB_ControllerPIrANSIC(Frac32 f32InErr,
                                        GFLIB_CONTROLLER_PI_R_T *pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GFLIB_CONTROLLER_PIR_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_send.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_send.c$
* $Version : 3.8.16.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the MACNET send
*   support function.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "macnet_prv.h"          



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_send
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Sends a packet.
*
*END*-----------------------------------------------------------------*/

uint_32 MACNET_send
   (
      ENET_CONTEXT_STRUCT_PTR  enet_ptr,
         /* [IN] the Ethernet state structure */
      PCB_PTR              packet,
         /* [IN] the packet to send */
      uint_32              size,
         /* [IN] total size of the packet */
      uint_32              frags,
         /* [IN] total fragments in the packet */
      uint_32              flags
         /* [IN] optional flags, zero = default */
   )
{ 
   MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   ENET_MemMapPtr              macnet_ptr= macnet_context_ptr->MACNET_ADDRESS;
   PCB_FRAGMENT_PTR            frag_ptr;
   VENET_BD_STRUCT_PTR         tx_bd_ptr;
   uint_32                     len,totlen,frag;
   uchar_ptr                   txmem;
   boolean                     aligned;
   uint_32                     err = ENET_OK;
#if ENETCFG_SUPPORT_PTP
   MACNET_PTP_DATA             tmp_tx_time;
   boolean                     wait_for_ts=FALSE;
#endif

   if (macnet_ptr == NULL) 
      return ENETERR_INVALID_DEVICE;
   
   MACNET_int_disable();
   
   /*
   ** Make sure there aren't too many fragments.  (We really should check
   ** this every time through the previous loop, but it is extremely
   ** unlikely that the fragment counter overflowed -- there would have
   ** to be over 2^32 fragments.)
   */
   if (macnet_context_ptr->AvailableTxBDs < 1) {
      ENET_INC_STATS(COMMON.ST_TX_MISSED);
   
      err = ENETERR_SEND_FULL;      
      goto END;
   } 

   #if BSPCFG_ENABLE_ENET_HISTOGRAM
   {
      uint_32 index = size>> ENET_HISTOGRAM_SHIFT;
      
      if (index < ENET_HISTOGRAM_ENTRIES) {
         ENET_INC_STATS(TX_HISTOGRAM[index]);
      }
   }
   #endif
   
   aligned = TRUE;
   for (frag_ptr = packet->FRAG; frag_ptr->LENGTH; frag_ptr++) {
      if (MACNET_TX_ALIGN((uint_32)frag_ptr->FRAGMENT)!= (uint_32)frag_ptr->FRAGMENT)
         aligned = FALSE;
   } 
   if (aligned) {
      ENET_INC_STATS(TX_ALL_ALIGNED);
   }
   
   /*
   ** Enqueue the packet on the transmit ring.  Don't set the ready
   ** bit in the first descriptor until all descriptors are enqueued.
   */
   tx_bd_ptr = &macnet_context_ptr->MACNET_TX_RING_PTR[macnet_context_ptr->NextTxBD];

   frag_ptr = packet->FRAG;
   frag = (uint_32) frag_ptr->FRAGMENT;
   if (frags > 1 || (MACNET_TX_ALIGN(frag)!= frag)) {
      // Packet is fragmented and/or it is misaligned, needs to be copied
      txmem = NULL;
      // See if it fits in a small buffer
      if (size <= MACNET_SMALL_PACKET_SIZE) {
         // it does
         txmem = ENET_Dequeue_Buffer((pointer *) &macnet_context_ptr->SMALL_BUFFERS);
      }
      // If it didn't fit, or the small alloc failed, try for a large buffer
      if (txmem) {
         // signal buffer is to be deallocated.
         macnet_context_ptr->FREE_TX_SMALL |= (1<<macnet_context_ptr->NextTxBD);
         ENET_INC_STATS(ST_TX_COPY_SMALL);

      } else { 
         if (size <=  macnet_context_ptr->AlignedTxBufferSize) {

            txmem = ENET_Dequeue_Buffer((pointer *) &macnet_context_ptr->TX_BUFFERS);
         }
         if (txmem) {
            // signal buffer is to be deallocated.
            macnet_context_ptr->FREE_TX |= (1<<macnet_context_ptr->NextTxBD);
         } else {
            ENET_INC_STATS(COMMON.ST_TX_MISSED);
            
            err = ENETERR_NO_TX_BUFFER;      
            goto END;
         }
         
      }
      totlen = 0;
      
      for (len = frag_ptr->LENGTH; len != 0; len = frag_ptr->LENGTH) {
         _mem_copy(frag_ptr->FRAGMENT, txmem + totlen, len);
         totlen += len;
         frag_ptr++;
      } 

   } else {
      // Packet is not fragmented and it is not misaligned
      totlen = frag_ptr->LENGTH;
      txmem  = frag_ptr->FRAGMENT;
      ENET_INC_STATS(TX_ALIGNED);
   } 

   // Flush the buffer from cache
   _DCACHE_FLUSH_MBYTES(txmem, totlen);  

   // Invalidate the bd from cache
   _DCACHE_INVALIDATE_MBYTES((pointer)tx_bd_ptr, sizeof(ENET_BD_STRUCT));  

   // set up the tx bd
   tx_bd_ptr->CONTROL &= HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_TX_WRAP);
   tx_bd_ptr->BUFFER = (uchar_ptr)HOST_TO_BE_LONG((uint_32)txmem);
   tx_bd_ptr->LENGTH = HOST_TO_BE_SHORT(totlen);
   tx_bd_ptr->CONTROL |= HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_TX_LAST | ENET_BD_ETHER_TX_SEND_CRC | ENET_BD_ETHER_TX_READY);
   
   tx_bd_ptr->CONTROL_EXT0 |= HOST_TO_BE_SHORT_CONST(ENET_BD_EXT0_ETHER_TX_GENERATE_INTR);
     
   
#if ENETCFG_SUPPORT_PTP
   if (macnet_context_ptr->PTP_PRIV->PTIMER_PRESENT) 
   {
       /* PTP over Ethernet frames: Check the PTPv2 over Ethernet type (identifier) */
       if((totlen > 44) && 
          (*(uint_16 *)(txmem + MACNET_PTP_ETHER_PKT_TYPE_OFFS) == HOST_TO_BE_SHORT_CONST(MACNET_PACKET_TYPE_IEEE_802_3)))
       {
           /* Allow interrupt and timestamp generation */
           tx_bd_ptr->CONTROL_EXT0 |= HOST_TO_BE_SHORT_CONST(ENET_BD_EXT0_ETHER_TX_TIMESTAMP);
           tmp_tx_time.KEY = HOST_TO_BE_SHORT(*((uint_16 *)(txmem + MACNET_PTP_ETHER_SEQ_ID_OFFS)));
           for(len=0;len<MACNET_PTP_CLOCKID_SIZE;len++)
               tmp_tx_time.CLOCKID[len] = *((uint_8 *)(txmem + MACNET_PTP_ETHER_CLOCKID + len));
           wait_for_ts = TRUE;
       }
       /* PTP over UDP: Check if port is 319 for PTP Event, and check for UDP */
       else if((totlen > 44) && 
          (*(uchar_ptr)(txmem + MACNET_PTP_UDP_PKT_TYPE_OFFS) == MACNET_PACKET_TYPE_UDP) && 
          (*(uint_16 *)(txmem + MACNET_PTP_UDP_PORT_OFFS) == HOST_TO_BE_SHORT_CONST(MACNET_PTP_EVNT_PORT)))
       {
           tx_bd_ptr->CONTROL_EXT0 |= HOST_TO_BE_SHORT_CONST(ENET_BD_EXT0_ETHER_TX_TIMESTAMP);
           tmp_tx_time.KEY = HOST_TO_BE_SHORT(*((uint_16 *)(txmem + MACNET_PTP_UDP_SEQ_ID_OFFS)));
           for(len=0;len<MACNET_PTP_CLOCKID_SIZE;len++)
               tmp_tx_time.CLOCKID[len] = *((uint_8 *)(txmem + MACNET_PTP_UDP_CLOCKID + len));
           wait_for_ts = TRUE;
       }

   }
#endif /* ENETCFG_SUPPORT_PTP */

   // Flush the tx bd from cache
   _DCACHE_FLUSH_MBYTES((pointer)tx_bd_ptr, sizeof(ENET_BD_STRUCT));  

   macnet_context_ptr->TxPCBS_PTR[macnet_context_ptr->NextTxBD] = packet;
   
   macnet_context_ptr->AvailableTxBDs--;
   BD_INC(macnet_context_ptr->NextTxBD,macnet_context_ptr->NumTxBDs);

   macnet_ptr->TDAR = ENET_TDAR_TDAR_MASK;
   
END:
   MACNET_int_enable();
      
#if ENETCFG_SUPPORT_PTP
   if(wait_for_ts)
   {
      /* Wait for the interrupt */
      _lwevent_wait_ticks(&macnet_context_ptr->PTP_PRIV->LWEVENT_PTP, MACNET_PTP_LWEVENT_TX_TS_INTR, FALSE, (uint_32)NULL);

      /* Clear the event */
      _lwevent_clear(&macnet_context_ptr->PTP_PRIV->LWEVENT_PTP, MACNET_PTP_LWEVENT_TX_TS_INTR);

      /* Clear the TS flag from the BD */
      tx_bd_ptr->CONTROL_EXT0 &= HOST_TO_BE_SHORT_CONST(~ENET_BD_EXT0_ETHER_TX_TIMESTAMP);
      
      tmp_tx_time.TS_TIME.NSEC = macnet_context_ptr->PTP_PRIV->TXSTAMP.NSEC;
      tmp_tx_time.TS_TIME.SEC  = macnet_context_ptr->PTP_PRIV->TXSTAMP.SEC;
      MACNET_ptp_insert(&(macnet_context_ptr->PTP_PRIV->TX_TIME), &tmp_tx_time);
      wait_for_ts = FALSE;
   }
#endif /* ENETCFG_SUPPORT_PTP */
   return err;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_process_tx_bds
*  Returned Value : void
*  Comments       :
*        Processes transmitted packets.
*
*END*-----------------------------------------------------------------*/

static void MACNET_process_tx_bds
   (
         /* [IN] the Ethernet state structure */
      ENET_CONTEXT_STRUCT_PTR  enet_ptr
   )
{ 
   MACNET_CONTEXT_STRUCT_PTR   macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   uint_16                     tx_status;
   

   /* Dequeue all transmitted frames */
   while (macnet_context_ptr->AvailableTxBDs < macnet_context_ptr->NumTxBDs) {
      VENET_BD_STRUCT_PTR bd_ptr = &macnet_context_ptr->MACNET_TX_RING_PTR[macnet_context_ptr->LastTxBD];

      _DCACHE_INVALIDATE_MBYTES((pointer)bd_ptr, sizeof(ENET_BD_STRUCT));  

      if (bd_ptr->CONTROL & HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_TX_READY)) {
         break;
      } /* Endif */

      macnet_context_ptr->TxErrors |= SHORT_BE_TO_HOST(bd_ptr->CONTROL);
      tx_status = macnet_context_ptr->TxErrors;

      /* Record statistics for each frame (not each buffer) */
      if (tx_status & ENET_BD_ETHER_TX_LAST) {
         PCB_PTR pcb_ptr;
         macnet_context_ptr->TxErrors = 0;

         ENET_INC_STATS(COMMON.ST_TX_TOTAL);

         pcb_ptr = macnet_context_ptr->TxPCBS_PTR[macnet_context_ptr->LastTxBD];
         PCB_free(pcb_ptr);
      } 

      if (macnet_context_ptr->FREE_TX_SMALL & (1<<macnet_context_ptr->LastTxBD)) {
         ENET_Enqueue_Buffer((pointer *) &macnet_context_ptr->SMALL_BUFFERS, (pointer)LONG_BE_TO_HOST((uint_32)(bd_ptr->BUFFER)));
         macnet_context_ptr->FREE_TX_SMALL &= ~(1<<macnet_context_ptr->LastTxBD);
      } else if (macnet_context_ptr->FREE_TX & (1<<macnet_context_ptr->LastTxBD)) {
         ENET_Enqueue_Buffer((pointer *) &macnet_context_ptr->TX_BUFFERS, (pointer)LONG_BE_TO_HOST((uint_32)(bd_ptr->BUFFER)));
         macnet_context_ptr->FREE_TX &= ~(1<<macnet_context_ptr->LastTxBD);
      }      
      BD_INC(macnet_context_ptr->LastTxBD,macnet_context_ptr->NumTxBDs);
      macnet_context_ptr->AvailableTxBDs++;

   } 
} 


/*NOTIFIER*-------------------------------------------------------------
*
*  Function Name  : MACNET_TX_ISR
*  Returned Value : void
*  Comments       :
*        Interrupt service routine for Tx.
*
*END*-----------------------------------------------------------------*/

void MACNET_TX_ISR 
   (
         /* [IN] the Ethernet state structure */
      pointer  enet
   )
{    
   ENET_CONTEXT_STRUCT_PTR    enet_ptr           = (ENET_CONTEXT_STRUCT_PTR)enet;
   MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   ENET_MemMapPtr             macnet_ptr         = macnet_context_ptr->MACNET_ADDRESS;
   uint_32                    events;

   if (macnet_ptr == NULL) return;
   
   events = macnet_ptr->EIR;
   while (events & (ENET_EIR_TXB_MASK | ENET_EIR_TXF_MASK)) {

      /* clear the interrupt */
      macnet_ptr->EIR = (ENET_EIR_TXF_MASK | ENET_EIR_TXB_MASK);
      MACNET_process_tx_bds(enet_ptr);

      events = macnet_ptr->EIR;
   } 
    
   /* Needed for Kinetis: otherwise last packet in ring buffer may be not sent.*/
   macnet_ptr->TDAR = ENET_TDAR_TDAR_MASK;
} 




/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_valdev.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_valdev.c$
* $Version : 3.8.9.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the function for making sure the device on which
*   MFS is being run on is suitable
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>
#include <io_prv.h>

#include "mfs.h"
#include "mfs_prv.h"
#include "part_mgr.h"


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _mfs_validate_device
* Returned Value   : MFS_NO_ERROR or an error
* Comments         : Checks the lower layer device for compatibility
* 
*END*----------------------------------------------------------------------*/

_mfs_error _mfs_validate_device
    (
    MQX_FILE_PTR             dev_fd,            /* [IN] the file handle for the lower layer device */
    uint_32_ptr              sector_size_ptr,   /* [OUT] Pointer to where the sector size is to be stored  */
    boolean _PTR_            block_mode_ptr     /* [OUT] Pointer to where the block mode is to be stored  */
    )
{
    _mfs_error      error_code;
#ifdef IO_DEV_ATTR_BLOCK_MODE
    uint_32         id_array[3];

    id_array[0] = id_array[1] = id_array[2] = 0;

    /* 
    ** Issue the id command. Block mode drivers must support this command but
    ** other drivers can support it also
    */
    error_code = _io_ioctl(dev_fd, IO_IOCTL_DEVICE_IDENTIFY, id_array);

    if ( error_code == IO_OK )
    {
        /* 
        ** The identify command is supported. Check to see if it is a block mode
        ** driver
        */
        if ( id_array[IO_IOCTL_ID_ATTR_ELEMENT] & IO_DEV_ATTR_BLOCK_MODE )
        {
            *block_mode_ptr = TRUE;
        }
        else
        {
            *block_mode_ptr = FALSE;
        }  
    }
    else if ( error_code == IO_ERROR_INVALID_IOCTL_CMD )
    {
        /* 
        ** The ID command is not supported by the lower layer. It is not a block
        ** mode driver
        */
        *block_mode_ptr = FALSE;
    }
    else
    {
        /* Something bad happened at the lower layer */
        return( error_code );
    }  
#else
    *block_mode_ptr = FALSE;
#endif

    *sector_size_ptr = MFS_DEFAULT_SECTOR_SIZE;
    error_code  = _io_ioctl(dev_fd, IO_IOCTL_GET_BLOCK_SIZE, sector_size_ptr);

    if ( error_code == IO_ERROR_INVALID_IOCTL_CMD )
    {
        /* 
        ** The command is not supported. This is OK as long as it isn't a block
        ** mode driver.
        */
        if ( *block_mode_ptr )
        {
            /* MFS needs to know the block size for block mode drivers */
            error_code = MFS_INVALID_DEVICE;
        }
        else
        {
            /* 
            ** It doesn't matter that we can't tell the actual block size. MFS 
            ** will be doing byte accesses anyway since it isn't a block mode 
            ** driver.
            */
            *sector_size_ptr = MFS_DEFAULT_SECTOR_SIZE;
            error_code = MFS_NO_ERROR;
        }  
    }
    else if ( error_code == IO_OK )
    {
        /* Check to see if the sector or block size is suitable for MFS */
        if ( !((*sector_size_ptr == 512) || (*sector_size_ptr == 1024) || 
            (*sector_size_ptr == 2048) || (*sector_size_ptr == 4096)) )
        {
            /* 
            ** The block size isn't compatible. This may still be OK as long as we 
            ** are not dealing with a block mode driver otherwise MFS won't be 
            ** able to work with it
            */
            if ( *block_mode_ptr )
            {
                error_code = MFS_INVALID_DEVICE;
            }

        }
    }

    return(error_code);
}


<|start_filename|>Firmware/Inverter_firmware/mcc/source/mcc_vf600.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2013 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************
* $FileName: mcc_vf600.c$
* $Version : 3.8.1.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This file contains Vybrid-specific functions of the MCC library
*
*END************************************************************************/

#include "mcc_vf600.h"
#include "mcc_mqx.h"

/* This field contains CPU-to-CPU interrupt vector numbers for all device cores */
static const unsigned int mcc_cpu_to_cpu_vectors[] = { INT_CPU_to_CPU_int0, NVIC_CPU_to_CPU_int0 };

/*!
 * \brief This function gets the CPU-to-CPU vector number for the particular core.
 *
 * Platform-specific inter-CPU vector numbers for each core are defined in the mcc_cpu_to_cpu_vectors[] field.
 *
 * \param[in] core Core number.
 *
 * \return vector number for the particular core
 * \return MCC_VECTOR_NUMBER_INVALID (vector number for the particular core number not found)
 */
unsigned int mcc_get_cpu_to_cpu_vector(unsigned int core)
{
    if (core < (sizeof(mcc_cpu_to_cpu_vectors)/sizeof(mcc_cpu_to_cpu_vectors[0]))) {
        return  mcc_cpu_to_cpu_vectors[core];

    }
    return MCC_VECTOR_NUMBER_INVALID;
}

/*!
 * \brief This function clears the CPU-to-CPU interrupt flag for the particular core.
 *
 * Implementation is platform-specific.
 *
 * \param[in] core Core number.
 */
void mcc_clear_cpu_to_cpu_interrupt(unsigned int core)
{
    if(core == 0) {
        /* clear the flag in the MSCM_IRCP0IR register */
        MSCM_IRCP0IR = MSCM_IRCP0IR_INT0_MASK;
    }
    else if(core == 1) {
        /* clear the flag in the MSCM_IRCP1IR register */
        MSCM_IRCP1IR = MSCM_IRCP1IR_INT0_MASK;
   }
}

/*!
 * \brief This function triggers the CPU-to-CPU interrupt.
 *
 * Platform-specific software triggering the inter-CPU interrupts.
 */
void mcc_triger_cpu_to_cpu_interrupt(void)
{
    /* set TLF filed of the MSCM_IRCPGIR to assert directed CPU interrupts for all processors except the requesting core */
    MSCM_IRCPGIR = MSCM_IRCPGIR_TLF(1) | MSCM_IRCPGIR_INTID(0);
}


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_mkdir.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_mkdir.c$
* $Version : 3.8.12.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_prv.h>

#if SHELLCFG_USES_MFS


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_mkdir
* Returned Value   :  int_32 error code
* Comments  :  mount a filesystem on a device.
*
* Usage:  mkdir <directory>
*
*END*---------------------------------------------------------------------*/

int_32  Shell_mkdir(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean                    print_usage, temp, shorthelp = FALSE;
   int_32                     error = 0, return_code = SHELL_EXIT_SUCCESS;
   MQX_FILE_PTR               fs_ptr;
   SHELL_CONTEXT_PTR          shell_ptr = Shell_get_context( argv );
   char_ptr                   abs_path = NULL;
 
   
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc !=  2) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else  {
         if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
            printf("Error, unable to allocate memory for paths\n" );
            return_code = SHELL_EXIT_ERROR;
         }
         else
         {
            _io_get_dev_for_path(abs_path,&temp,PATHNAME_SIZE,(char *)argv[1],Shell_get_current_filesystem_name(shell_ptr));
            fs_ptr = _io_get_fs_by_name(abs_path);
            /* check if filesystem is mounted */
            if (fs_ptr == NULL)  {
               printf("Error, file system not mounted\n" );
               return_code = SHELL_EXIT_ERROR;
            } else  {
               error = _io_rel2abs(abs_path,shell_ptr->CURRENT_DIR,(char *) argv[1],PATHNAME_SIZE,Shell_get_current_filesystem_name(shell_ptr));
               if(!error)
               {
                  error = ioctl(fs_ptr, IO_IOCTL_CREATE_SUBDIR, (pointer) abs_path);
               }
               if (error)  {
                  printf("Error creating directory %s\n", argv[1]);
               }
            }
          MFS_free_path(abs_path);  
         }
      }
   }
      
      
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <directory> \n", argv[0]);
      } else  {
         printf("Usage: %s <directory>\n", argv[0]);
         printf("   <directory> = name of directory to create\n");
      }
   }
   return return_code;
}

#endif //SHELLCFG_USES_MFS
/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/ipsum.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipsum.c$
* $Version : 3.7.4.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the implementation for a one's complement checksum.
*   The function can handle any alignment of the memory area 
*   being checksum'd.
*
*END************************************************************************/

#include "mqx_inc.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : _mem_sum_ip
* Returned Value  : one's complement checksum
* Comments        :
*     Returns a one's complement checksum over a block of memory, as
*     used for packets in Internet protocols (see RFC791 for definition).
*
*     Note:  This function returns 0 iff all summands are 0.
*
*END*-----------------------------------------------------------------*/

uint_32 _mem_sum_ip
   (
      register uint_32   sum,
      register uint_32   length,
      register pointer   loc
   )
{ /* Body */
   register uint_32   total = sum;
   register uint_32   temp;
   register uchar_ptr buf = (uchar_ptr)loc;

   if (length & 1) {
      length--;
      total += buf[length] << 8;
   } /* Endif */

   length >>= 1;
   while (length--) {
      temp   = (uint_16)(*buf);
      total += temp<<8 | buf[1];
      buf   += 2;
   } /* Endwhile */

   sum = ((total >> 16) & 0xFFFF);
   if (sum) {
      total = (total & 0xFFFF) + sum;
      sum = ((total >> 16) & 0xFFFF);
      if (sum) {
         total = (total & 0xFFFF) + sum;
      } /* Endif */
   } /* Endif */

   return total;

}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/shmem/pcb_shm.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pcb_shm.c$
* $Version : 3.8.10.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the code which implements a PCB driver
*   that sends MQX format packets over shared memory driver.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "io.h"
#include "io_prv.h"
#include "io_pcb.h"
#include "iopcbprv.h"
#include "pcb_shm.h"
#include "pcbshmv.h"
#include "bsp.h"

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_shm_install
* Returned Value  : _mqx_uint result   MQX_OK or an error code.
* Comments        :
*     This function is use to install the shared memory device.
*
*END*---------------------------------------------------------------------*/

_mqx_uint _io_pcb_shm_install
    (
        /* [IN] the name of this device */
        char_ptr    device_name_ptr,

        /* [IN] the initialization record for this device */
        pointer     init_ptr
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR info_ptr;
    uint_32                    tmp;

    info_ptr = _mem_alloc_system_zero(sizeof(IO_PCB_SHM_INFO_STRUCT));
    if (info_ptr == NULL) {
        return(MQX_OUT_OF_MEMORY);
    }

    info_ptr->INIT = *((IO_PCB_SHM_INIT_STRUCT_PTR)init_ptr);

    /* Initialize the info structure */
    /*
    ** Set the Tx and Rx RINGPTR address base
    **
    */
    info_ptr->TX_RING_PTR = (IO_PCB_SHM_BUFFER_STRUCT_PTR)(
        ((IO_PCB_SHM_INIT_STRUCT_PTR)init_ptr)->TX_BD_ADDR);

    info_ptr->TX_RING_PTR = (IO_PCB_SHM_BUFFER_STRUCT_PTR)
        SHM_DESCR_ALIGN((uint_32)info_ptr->TX_RING_PTR);
    tmp = (uint_32)(IO_PCB_SHM_BUFFER_STRUCT_PTR)(((IO_PCB_SHM_INIT_STRUCT_PTR)
        init_ptr)->TX_LIMIT_ADDR);
    tmp -= (uint_32)(info_ptr->TX_RING_PTR);
    tmp /= sizeof(IO_PCB_SHM_BUFFER_STRUCT);

    info_ptr->TXENTRIES = tmp;
    info_ptr->TX_LENGTH = tmp;
    info_ptr->TXNEXT = 0;
    info_ptr->TXLAST = 0;

    info_ptr->RX_RING_PTR = (IO_PCB_SHM_BUFFER_STRUCT_PTR)(
        ((IO_PCB_SHM_INIT_STRUCT_PTR)init_ptr)->RX_BD_ADDR);

    info_ptr->RX_RING_PTR = (IO_PCB_SHM_BUFFER_STRUCT_PTR)
        SHM_DESCR_ALIGN((uint_32)info_ptr->RX_RING_PTR);

    tmp = (uint_32)(IO_PCB_SHM_BUFFER_STRUCT_PTR)(((IO_PCB_SHM_INIT_STRUCT_PTR)
        init_ptr)->RX_LIMIT_ADDR);
    tmp -= (uint_32)(info_ptr->RX_RING_PTR);
    tmp /= sizeof(IO_PCB_SHM_BUFFER_STRUCT);
    info_ptr->RXENTRIES = tmp;
    info_ptr->RX_LENGTH = tmp;
    info_ptr->RXNEXT = 0;
    info_ptr->RXLAST = 0;

    return (_io_pcb_dev_install(device_name_ptr,
        _io_pcb_shm_open,
        _io_pcb_shm_close,
        _io_pcb_shm_read,
        _io_pcb_shm_write,
        _io_pcb_shm_ioctl,
        _io_pcb_shm_uninstall,
        (pointer)info_ptr));

}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_shm_open
* Returned Value  : _mqx_int result MQX_OK or an error code.
* Comments        :
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_shm_open
    (
        /* [IN] the file handle */
        FILE_DEVICE_STRUCT_PTR fd_ptr,

        /* [IN] the rest of the filename used to open the device */
        char _PTR_             open_name_ptr,

        /* [IN] the open flags for this device */
        char _PTR_             open_mode_flags
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR  info_ptr;
    IO_PCB_DEVICE_STRUCT_PTR    dev_ptr;

    dev_ptr = (IO_PCB_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    fd_ptr->DEV_DATA_PTR = dev_ptr->DRIVER_INIT_PTR;
    info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;

    fd_ptr->FLAGS |= IO_FLAG_IS_PCB_DEVICE;
    info_ptr->READ_CALLBACK_FUNCTION = NULL;
    _lwsem_create(&info_ptr->READ_LWSEM, 0);
    _lwsem_create(&info_ptr->WRITE_LWSEM, 0);
    _queue_init(&info_ptr->READ_QUEUE, 0);
    _queue_init(&info_ptr->WRITE_QUEUE, 0);

    return(MQX_OK);

}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_shm_close
* Returned Value  : _mqx_int result   MQX_OK or an error code.
* Comments        :
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_shm_close
    (
        /* [IN] the file handle */
        FILE_DEVICE_STRUCT_PTR fd_ptr
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR  info_ptr;
    IO_PCB_STRUCT_PTR           pcb_ptr;
    IO_PCB_SHM_INIT_STRUCT_PTR  init_ptr;

#if MQX_CHECK_ERRORS
    if (!(fd_ptr->FLAGS & IO_FLAG_IS_PCB_DEVICE)) {
        fd_ptr->ERROR = IO_PCB_NOT_A_PCB_DEVICE;
        return(IO_ERROR);
    }
#endif
    info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;
    init_ptr = &info_ptr->INIT;

    if (!_int_install_isr(init_ptr->RX_VECTOR,
        info_ptr->RX_OLDISR_PTR, info_ptr->RX_OLDISR_DATA))
    {
        return MQX_IO_PCB_SHM_INSTALL_ISR_FAILLED;
    }

    if (init_ptr->TX_VECTOR) {
        if (!_int_install_isr(init_ptr->TX_VECTOR, info_ptr->TX_OLDISR_PTR,
            info_ptr->TX_OLDISR_DATA))
        {
            return MQX_IO_PCB_SHM_INSTALL_ISR_FAILLED;
        }
    }

    _lwsem_destroy(&info_ptr->READ_LWSEM);
    _lwsem_destroy(&info_ptr->WRITE_LWSEM);

    while (_queue_get_size(&info_ptr->WRITE_QUEUE)) {
        pcb_ptr = (IO_PCB_STRUCT_PTR)
            ((pointer)_queue_dequeue(&info_ptr->WRITE_QUEUE));
        _io_pcb_free(pcb_ptr);
    }

    while (_queue_get_size(&info_ptr->READ_QUEUE)) {
        pcb_ptr = (IO_PCB_STRUCT_PTR)
            ((pointer)_queue_dequeue(&info_ptr->READ_QUEUE));
        _io_pcb_free(pcb_ptr);
    }

    return(MQX_OK);

}


/*READ*---------------------------------------------------------------------
*
* Function Name   : _io_pcb_shm_read
* Returned Value  : _mqx_int result MQX_OK or an error code.
* Comments        :
*     This function reads a packet directly
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_shm_read
    (
        /* [IN] the file descriptor */
        FILE_DEVICE_STRUCT_PTR  fd_ptr,

        /* [IN] the pcb address from which to write data */
        IO_PCB_STRUCT_PTR _PTR_ pcb_ptr
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR info_ptr;

    info_ptr = fd_ptr->DEV_DATA_PTR;

    _int_disable();
    if (fd_ptr->FLAGS & IO_O_NONBLOCK) {
        if (! _queue_get_size(&info_ptr->READ_QUEUE)) {
            *pcb_ptr = NULL;
            _int_enable();
            return(MQX_OK);
        }
    }
    _lwsem_wait(&info_ptr->READ_LWSEM);
    *pcb_ptr = (IO_PCB_STRUCT_PTR) ((pointer)_queue_dequeue(&info_ptr->READ_QUEUE));
    _int_enable();

    return(MQX_OK);

}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_shm_write
* Returned Value  : _mqx_uint result   MQX_OK or an error code.
* Comments        :
*     This function sends the pcb to the pcb output task.
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_shm_write
    (
        /* [IN] the file descriptor */
        FILE_DEVICE_STRUCT_PTR  fd_ptr,

        /* [IN] the pcb address from which to write data */
        IO_PCB_STRUCT_PTR       pcb_ptr
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR info_ptr;

    info_ptr = fd_ptr->DEV_DATA_PTR;


    _queue_enqueue((QUEUE_STRUCT_PTR)((pointer)&info_ptr->WRITE_QUEUE),
        (QUEUE_ELEMENT_STRUCT_PTR)((pointer)&pcb_ptr->QUEUE));
    _DCACHE_FLUSH_MLINES(pcb_ptr, sizeof(IO_PCB_STRUCT));
    _io_pcb_shm_tx((pointer)info_ptr);

    return(MQX_OK);
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _io_pcb_shm_tx
*  Returned Value : void
*  Comments       :
*        Packet transmission ISR.
*
*END*-----------------------------------------------------------------*/

void _io_pcb_shm_tx
    (
        /* [IN] the device info */
        pointer handle
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR   info_ptr;
    IO_PCB_STRUCT_PTR            pcb_ptr;
    IO_PCB_SHM_BUFFER_STRUCT_PTR bd_ptr;
    IO_PCB_SHM_INIT_STRUCT_PTR   init_ptr;
    IO_PCB_FRAGMENT_STRUCT_PTR   frag_ptr;
    uint_32                      work = FALSE;
    uint_16                      num_frags;

    info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)handle;
    init_ptr = &info_ptr->INIT;

    while (TRUE) {

        _int_disable();

        /* Check if queue empty */
        if (!_queue_get_size(&info_ptr->WRITE_QUEUE)) {
          _int_enable();
            break;
        }

        /* Check if queue empty */
        if (!(info_ptr->TXENTRIES)) {
          _int_enable();
          info_ptr->TX_BD_RUNOVER++;
          break;
        }

        /* Get the packet from output queue */
        pcb_ptr = (IO_PCB_STRUCT_PTR)((pointer)
            _queue_dequeue(&info_ptr->WRITE_QUEUE));

        /* Get the next buffer descriptor */
        bd_ptr = &info_ptr->TX_RING_PTR[info_ptr->TXNEXT];

        /* Flush packet */
        num_frags = pcb_ptr->NUMBER_OF_FRAGMENTS;
        for(frag_ptr = (IO_PCB_FRAGMENT_STRUCT_PTR) &(pcb_ptr->FRAGMENTS[0]); num_frags; num_frags--, frag_ptr++)
        {
             _DCACHE_FLUSH_MLINES(frag_ptr->FRAGMENT,frag_ptr->LENGTH);
            frag_ptr->FRAGMENT = _bsp_vtop(frag_ptr->FRAGMENT);
        }


        /* Set the buffer descriptor */
        bd_ptr->PACKET_PTR = (IO_PCB_STRUCT_PTR) _bsp_vtop(pcb_ptr);
        bd_ptr->CONTROL = (IO_PCB_SHM_BUFFER_OWN|IO_PCB_SHM_BUFFER_ALOCATED);
        _DCACHE_FLUSH_LINE(bd_ptr);

        /* Update Info structure  */
        info_ptr->TXNEXT = NEXT_INDEX(info_ptr->TXNEXT, info_ptr->TX_LENGTH);
        info_ptr->TXENTRIES--;
        work = TRUE;
        _int_enable();

    }

    if (work) {
        /* Trigger remote ISR */
        (*init_ptr->INT_TRIGGER)(init_ptr->REMOTE_RX_VECTOR);
    }
}


/*NOTIFIER*-------------------------------------------------------------
*
*  Function Name  : io_pcb_shm_tx_isr
*  Returned Value : void
*  Comments       :
*        Packet transmission ISR.
*
*END*-----------------------------------------------------------------*/

void _io_pcb_shm_tx_isr
    (
        /* [IN] the info structure */
        pointer     handle
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR     info_ptr;
    IO_PCB_STRUCT_PTR              pcb_ptr;
    IO_PCB_SHM_BUFFER_STRUCT_PTR   bd_ptr;
    IO_PCB_FRAGMENT_STRUCT_PTR     frag_ptr;
    uint_16                        num_frags;
    uint_32                        cntrl;

    info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)handle;
    _int_disable();

    while (info_ptr->TXENTRIES < info_ptr->TX_LENGTH) {

        /* Get the address of the Tx descriptor */
        bd_ptr = &info_ptr->TX_RING_PTR[info_ptr->TXLAST];
        _DCACHE_INVALIDATE_LINE(bd_ptr);
        pcb_ptr = (IO_PCB_STRUCT_PTR) _bsp_ptov(bd_ptr->PACKET_PTR);
        cntrl = bd_ptr->CONTROL;

        /* Make sure the buffer is released by remote CPU */
        if (cntrl != IO_PCB_SHM_BUFFER_ALOCATED) {
            break;
        }

       // Have to restore virtual addresses to free fragments
       num_frags = pcb_ptr->NUMBER_OF_FRAGMENTS;
       for(frag_ptr = (IO_PCB_FRAGMENT_STRUCT_PTR) &(pcb_ptr->FRAGMENTS[0]); num_frags; num_frags--, frag_ptr++)
       {
            frag_ptr->FRAGMENT = _bsp_ptov(frag_ptr->FRAGMENT);
       }

        /* Free PCB */
        _io_pcb_free(pcb_ptr);

        /* Update info */
        info_ptr->TX_PACKETS++;
        info_ptr->TXLAST = NEXT_INDEX(info_ptr->TXLAST, info_ptr->TX_LENGTH);
        info_ptr->TXENTRIES++;

    }

    /* Check if there is more to send */
    _io_pcb_shm_tx(handle);

    /* Enable Interrupts */
    _int_enable();

}


/*NOTIFIER*-------------------------------------------------------------
*
*  Function Name  : io_pcb_shm_rx_isr
*  Returned Value : void
*  Comments       :
*        Packet reception ISR.
*
*END*-----------------------------------------------------------------*/

void _io_pcb_shm_rx_isr
    (
        /* [IN] the info structure */
        pointer     handle
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR   info_ptr;
    IO_PCB_SHM_INIT_STRUCT_PTR   init_ptr;
    IO_PCB_STRUCT_PTR            local_pcb_ptr;
    IO_PCB_STRUCT_PTR            remote_pcb_ptr;
    IO_PCB_FRAGMENT_STRUCT_PTR   frag_ptr;
    IO_PCB_SHM_BUFFER_STRUCT_PTR bd_ptr;
    uchar_ptr                    data_addr;
    uint_32                      data_length;
    uint_32                      cntrl;
    uint_16                      num_frags;
    uint_32                      max_size;
    boolean                      discard;

    info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)handle;
    init_ptr = &info_ptr->INIT;

    /* Get the next RX buffer descriptor */
    bd_ptr = &info_ptr->RX_RING_PTR[info_ptr->RXNEXT];
    _DCACHE_INVALIDATE_LINE(bd_ptr);
    cntrl = bd_ptr->CONTROL;
    remote_pcb_ptr = (IO_PCB_STRUCT_PTR) _bsp_ptov(bd_ptr->PACKET_PTR);
    _DCACHE_INVALIDATE_MBYTES(remote_pcb_ptr, sizeof(*remote_pcb_ptr));
    num_frags = remote_pcb_ptr->NUMBER_OF_FRAGMENTS;

    /* Disable interrupts */
    _int_disable();

    while(cntrl == (IO_PCB_SHM_BUFFER_OWN|IO_PCB_SHM_BUFFER_ALOCATED)){

        discard = FALSE;
        /* Get a PCB */
        local_pcb_ptr = _io_pcb_alloc(info_ptr->READ_PCB_POOL, FALSE);
        if ((local_pcb_ptr == NULL)) {
            break;
        }
        data_addr = local_pcb_ptr->FRAGMENTS[0].FRAGMENT;
        data_length = ((IO_PCB_SHM_INIT_STRUCT_PTR) &info_ptr->INIT)->INPUT_MAX_LENGTH;
        max_size = ((IO_PCB_SHM_INIT_STRUCT_PTR) &info_ptr->INIT)->INPUT_MAX_LENGTH;

        /* Copy packet */
        for(frag_ptr = (IO_PCB_FRAGMENT_STRUCT_PTR) &(remote_pcb_ptr->FRAGMENTS[0]); num_frags; num_frags--, frag_ptr++)
        {
            if(frag_ptr->LENGTH > max_size){
                discard = TRUE;
                break;
            }

            _DCACHE_INVALIDATE_MBYTES(frag_ptr->FRAGMENT, frag_ptr->LENGTH);
            _mem_copy(_bsp_ptov((pointer)frag_ptr->FRAGMENT), (pointer)data_addr, frag_ptr->LENGTH);
             data_addr += frag_ptr->LENGTH;
             data_length -= frag_ptr->LENGTH;
        }

        local_pcb_ptr->FRAGMENTS[0].LENGTH = max_size - data_length;
        if (info_ptr->READ_CALLBACK_FUNCTION) {
            (*info_ptr->READ_CALLBACK_FUNCTION)(info_ptr->FD,
                local_pcb_ptr);
        } else {
            _queue_enqueue((QUEUE_STRUCT_PTR)&info_ptr->READ_QUEUE,
                (QUEUE_ELEMENT_STRUCT_PTR)&local_pcb_ptr->QUEUE);
            _lwsem_post(&info_ptr->READ_LWSEM);
        }

        /* Set the buffer pointer and control bits */
        bd_ptr->CONTROL &= IO_PCB_SHM_BUFFER_ALOCATED;
        _DCACHE_FLUSH_LINE(bd_ptr);
        /* Update Info structure  */
        info_ptr->RXNEXT = NEXT_INDEX(info_ptr->RXNEXT, info_ptr->RX_LENGTH);
        info_ptr->RXENTRIES--;
        /* Get the next RX buffer descriptor */
        bd_ptr = &info_ptr->RX_RING_PTR[info_ptr->RXNEXT];
        _DCACHE_INVALIDATE_LINE(bd_ptr);
        cntrl = bd_ptr->CONTROL;
        remote_pcb_ptr = (IO_PCB_STRUCT_PTR) _bsp_ptov(bd_ptr->PACKET_PTR);
        _DCACHE_INVALIDATE_MBYTES(remote_pcb_ptr, sizeof(*remote_pcb_ptr));
        num_frags = remote_pcb_ptr->NUMBER_OF_FRAGMENTS;
    }

    if (init_ptr->TX_VECTOR == 0) {
        _io_pcb_shm_tx_isr(handle);
    }

    /* Reception successful  */
    if (!discard) {
        /* Trigger remote side */
        (*init_ptr->INT_TRIGGER)(init_ptr->REMOTE_TX_VECTOR);
    }

    _int_enable();

}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_shm_ioctl
* Returned Value  : _mqx_uint result   MQX_OK or an error code.
* Comments        :
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_shm_ioctl
    (
        /* [IN] the file handle for the device */
        FILE_DEVICE_STRUCT_PTR fd_ptr,

        /* [IN] the ioctl command */
        _mqx_uint              cmd,

        /* [IN] the ioctl parameters */
        pointer                param_ptr
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR  info_ptr;
    IO_PCB_STRUCT_PTR           pcb_ptr;
    _mqx_uint                   result = MQX_OK;
    _psp_code_addr              old_value;
    _psp_code_addr_ptr          pc_ptr = (_psp_code_addr_ptr)param_ptr;
    _psp_data_addr_ptr          pd_ptr = (_psp_data_addr_ptr)param_ptr;
    boolean _PTR_               bool_param_ptr;
    IO_PCB_SHM_INIT_STRUCT_PTR  init_ptr;

    info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;
    init_ptr = &info_ptr->INIT;

    switch (cmd) {

        case IO_PCB_IOCTL_ENQUEUE_READQ:
            pcb_ptr = (IO_PCB_STRUCT_PTR)*pd_ptr;
            _queue_enqueue((QUEUE_STRUCT_PTR)&info_ptr->READ_QUEUE,
                (QUEUE_ELEMENT_STRUCT_PTR)&pcb_ptr->QUEUE);
            _lwsem_post(&info_ptr->READ_LWSEM);
            break;

        case IO_PCB_IOCTL_READ_CALLBACK_SET:
            old_value = (_psp_code_addr)info_ptr->READ_CALLBACK_FUNCTION;
            info_ptr->READ_CALLBACK_FUNCTION = (void (_CODE_PTR_)(
                FILE_DEVICE_STRUCT_PTR, IO_PCB_STRUCT_PTR))*pc_ptr;
            *pc_ptr = old_value;
            break;

        case IO_PCB_IOCTL_SET_INPUT_POOL:
            old_value = (_psp_code_addr)info_ptr->READ_PCB_POOL;
            info_ptr->READ_PCB_POOL = (_io_pcb_pool_id)*pc_ptr;
            *pc_ptr = old_value;
            info_ptr->FD = fd_ptr;
            break;

        case IO_PCB_IOCTL_START:
             info_ptr->RX_OLDISR_PTR  = _int_get_isr( init_ptr->RX_VECTOR);
             info_ptr->RX_OLDISR_DATA = _int_get_isr_data(init_ptr->RX_VECTOR);
             info_ptr->TX_OLDISR_PTR  = _int_get_isr( init_ptr->TX_VECTOR);
             info_ptr->TX_OLDISR_DATA = _int_get_isr_data(init_ptr->TX_VECTOR);

#if BSPCFG_IO_PCB_SHM_SUPPORT
             if (_bsp_io_pcb_shm_int_install(init_ptr,info_ptr)!=MQX_OK) {
                  _mem_free(info_ptr);
                  return MQX_IO_PCB_SHM_INSTALL_ISR_FAILLED;
              }
#else
            /* Install rx ISR */
            if (!_int_install_isr(init_ptr->RX_VECTOR, _io_pcb_shm_rx_isr, info_ptr))
            {
                _mem_free(info_ptr);
                return MQX_IO_PCB_SHM_INSTALL_ISR_FAILLED;
            }

            /* Install the tx finished ISR */
            if (!_int_install_isr(init_ptr->TX_VECTOR, _io_pcb_shm_tx_isr, info_ptr))
            {
                _mem_free(info_ptr);
                return MQX_IO_PCB_SHM_INSTALL_ISR_FAILLED;
            }
#endif
            break;

        case IO_PCB_IOCTL_UNPACKED_ONLY:
            bool_param_ptr = (boolean _PTR_)param_ptr;
            *bool_param_ptr = TRUE;
            break;

        default:
            /* result = _io_ioctl(info_ptr->FD, cmd, param_ptr); */
            break;

    }
    return result;

}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pcb_shm_uninstall
* Returned Value  : _mqx_uint result   MQX_OK or an error code.
* Comments        :
*
*END*---------------------------------------------------------------------*/

_mqx_int _io_pcb_shm_uninstall
    (
        IO_PCB_DEVICE_STRUCT_PTR dev_ptr
    )
{
    IO_PCB_SHM_INFO_STRUCT_PTR  info_ptr;
    _mqx_int                    result = MQX_OK;
    _mqx_uint                   valid;

    info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)dev_ptr->DRIVER_INIT_PTR;
    valid = info_ptr->WRITE_LWSEM.VALID;
    if (valid) {
         return IO_ERROR_DEVICE_BUSY;
    }

    _mem_free(info_ptr);

     return result;

}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rip_prv.h<|end_filename|>
#ifndef __rip_prv_h__
#define __rip_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rip_prv.h$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   Private definitions for the RIP protocol layer.
*
*END************************************************************************/

typedef struct rip_info {
   TCPIP_EVENT TIMEOUT; /* used for timeout _AND_ garbage collecting */
   uint_32     METRIC;
   uint_32     RT_TAG;
   boolean     CHANGED_F;
   IP_IF_PTR   IPIFSRC; /* the incoming interface of this route */
}  RIP_INFO, _PTR_ RIP_INFO_PTR;

#endif   /* __rip_prv_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2s/i2s_mk40.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2s_mk40.c$
* $Version : 3.8.4.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains board-specific I2S initialization functions.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include "i2s.h"
#include "i2s_ki2s.h"
#include "i2s_ki2s_prv.h"

/*FUNCTION****************************************************************
*
* Function Name    : _bsp_get_i2s_base_address
* Returned Value   : address if successful, NULL otherwise
* Comments         :
*    This function returns the base register address of the corresponding I2S device.
*
*END*********************************************************************/

pointer _bsp_get_i2s_base_address
(
   uint_8 dev_num
)
{
   pointer addr;

   switch (dev_num)
   {
      case 0:
         addr = (pointer) I2S0_BASE_PTR;
         break;
      default:
        addr = NULL;
        break;
    }
    return addr;
}


/*FUNCTION****************************************************************
*
* Function Name    : _bsp_get_i2s_vector
* Returned Value   : vector number if successful, 0 otherwise
* Comments         :
*    This function returns desired interrupt vector number for specified I2S device.
*
*END*********************************************************************/

uint_32 _bsp_get_i2s_vector
(
   uint_8 dev_num
)
{
   uint_32 vector;
   switch (dev_num)
   {
      case 0:
         vector = INT_I2S0;
         break;
      default:
         vector = 0;
         break;
    }
    return vector;
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/partition.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: partition.c$
 * $Version : 3.8.2.0$
 * $Date    : Jun-25-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Partititon component.
 *
 *END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_PARTITIONS
#include "partition.h"
#include "partition_prv.h"

/*!
 * \brief Allocates a private partition block from the partition.
 * 
 * The functions allocate a fixed-size memory block, which the task owns.
 * 
 * \param[in] partition Partition from which to allocate the partition block.
 * 
 * \return Pointer to the partition block (success).
 * \return NULL (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li PARTITION_INVALID (Partition does not represent a valid partition.)
 * \li PARTITION_OUT_OF_BLOCKS (All the partition blocks in the partition are 
 * allocated (for static partitions only).)
 * \li PARTITION_BLOCK_INVALID_CHECKSUM (MQX found an incorrect checksum in the 
 * partition block header.)
 * \li Task error code set by _mem_alloc_system() MQX cannot allocate memory for 
 * the partition block (for dynamic partitions only).     
 * 
 * \see _partition_alloc_zero
 * \see _partition_alloc_system
 * \see _partition_alloc_system_zero
 * \see _partition_create
 * \see _task_set_error
 * \see _mem_alloc_system
 */ 
pointer _partition_alloc
(
    _partition_id partition
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_partition_alloc, partition);

    result = _partition_alloc_internal((PARTPOOL_STRUCT_PTR) partition, kernel_data->ACTIVE_PTR);

    _KLOGX2(KLOG_partition_alloc, result);

    return (result);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Allocates a private partition block from the partition.
 * 
 * \param[in] partpool_ptr The partition to obtain the memory block from.
 * \param[in] td_ptr       The task to own the partition block.
 * 
 * \return Pointer to the partition block (success).
 * \return NULL (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li PARTITION_INVALID (Partition does not represent a valid partition.)
 * \li PARTITION_OUT_OF_BLOCKS (All the partition blocks in the partition are 
 * allocated (for static partitions only).)
 * \li PARTITION_BLOCK_INVALID_CHECKSUM (MQX found an incorrect checksum in the 
 * partition block header.)
 * \li Task error code set by _mem_alloc_system() MQX cannot allocate memory for 
 * the partition block (for dynamic partitions only). 
 */ 
pointer _partition_alloc_internal
(
    PARTPOOL_STRUCT_PTR partpool_ptr,
    TD_STRUCT_PTR       td_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr;
    PARTPOOL_BLOCK_STRUCT_PTR           partpool_block_ptr;
    _mqx_uint                           number_of_blocks;

#if MQX_CHECK_ERRORS
    if (partpool_ptr == NULL)
    {
        _task_set_error(PARTITION_INVALID);
        return NULL;
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

#if MQX_CHECK_VALIDITY
    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _task_set_error(PARTITION_INVALID);
        return NULL;
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    _GET_KERNEL_DATA(kernel_data);

    _INT_DISABLE();

    if (partpool_ptr->AVAILABLE == 0)
    {
        if ((partpool_ptr->PARTITION_TYPE == PARTITION_DYNAMIC) && partpool_ptr->GROW_BLOCKS
                        && ((partpool_ptr->MAXIMUM_BLOCKS == 0) || (partpool_ptr->TOTAL_BLOCKS
                                        < partpool_ptr->MAXIMUM_BLOCKS)))
        {
            /* We can attempt to grow the partition */
            number_of_blocks = partpool_ptr->GROW_BLOCKS;
            if ((partpool_ptr->MAXIMUM_BLOCKS != 0) && (number_of_blocks > (partpool_ptr->MAXIMUM_BLOCKS
                            - partpool_ptr->TOTAL_BLOCKS)))
            {
                number_of_blocks = partpool_ptr->MAXIMUM_BLOCKS - partpool_ptr->TOTAL_BLOCKS;
            } /* Endif */

            /* 
             * Temporarily boost up TOTAL BLOCKS to allow us to
             * enable interrupts during memory allocation
             */
            partpool_ptr->TOTAL_BLOCKS += number_of_blocks;
            _int_enable();

#if PSP_MEMORY_ALIGNMENT
            partpool_block_ptr = (PARTPOOL_BLOCK_STRUCT_PTR) _mem_alloc_system(
                            (_mem_size) (sizeof(PARTPOOL_BLOCK_STRUCT) + PSP_MEMORY_ALIGNMENT
                                            + (partpool_ptr->BLOCK_SIZE * number_of_blocks)));
#else
            partpool_block_ptr = _mem_alloc_system((_mem_size)
                            (sizeof(PARTPOOL_BLOCK_STRUCT) +
                                            (partpool_ptr->BLOCK_SIZE * number_of_blocks)));
#endif /* PSP_MEMORY_ALIGNMENT */
            if (partpool_block_ptr != NULL)
            {
                _mem_set_type(partpool_block_ptr, MEM_TYPE_PARTITION_BLOCKS);

                _partition_extend_internal(partpool_ptr, partpool_block_ptr, number_of_blocks);
            }
            else
            {
                partpool_ptr->TOTAL_BLOCKS -= number_of_blocks;
            } /* Endif */

            _int_disable();

        } /* Endif */

        if (((volatile PARTPOOL_STRUCT _PTR_) partpool_ptr)->AVAILABLE == 0)
        {
            _int_enable();
            _task_set_error(PARTITION_OUT_OF_BLOCKS);
            return NULL;
        } /* Endif */
    } /* Endif */

    block_ptr = partpool_ptr->FREE_LIST_PTR;

#if MQX_CHECK_VALIDITY
    if (!VALID_PARTITION_CHECKSUM(block_ptr))
    {
        _int_enable();
        _task_set_error(PARTITION_BLOCK_INVALID_CHECKSUM);
        return NULL;
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    partpool_ptr->FREE_LIST_PTR = block_ptr->LINK.NEXT_BLOCK_PTR;
    --partpool_ptr->AVAILABLE;

    if ((partpool_ptr->TOTAL_BLOCKS - partpool_ptr->AVAILABLE) > partpool_ptr->MAX_BLOCKS_USED)
    {
        partpool_ptr->MAX_BLOCKS_USED = partpool_ptr->TOTAL_BLOCKS - partpool_ptr->AVAILABLE;
    }/* Endif */
    block_ptr->TASK_ID = td_ptr->TASK_ID;
    block_ptr->LINK.PARTITION_PTR = partpool_ptr;

    CALC_PARTITION_CHECKSUM(block_ptr);

    /* Reset partition test walker */
    partpool_ptr->TEST_FREE_PTR = partpool_ptr->FREE_LIST_PTR;

    _INT_ENABLE();

    return (pointer) ((uchar_ptr) block_ptr + sizeof(INTERNAL_PARTITION_BLOCK_STRUCT));

} /* Endbody */

/*!
 * \brief Gets the number of free partition blocks in the partition.
 * 
 * \param[in] partition Partition about which to get info.
 * 
 * \return Number of free partition blocks (success).
 * \return MAX_MQX_UINT (failure)
 * 
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li PARTITION_INVALID (Partition does not represent a valid partition.)
 * 
 * \see _partition_get_block_size
 * \see _partition_get_max_used_blocks
 * \see _partition_get_total_blocks
 * \see _partition_get_total_size
 * \see _task_set_error 
 */ 
_mqx_uint _partition_get_free_blocks
(
    _partition_id partition
)
{ /* Body */
    PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;

#if MQX_CHECK_VALIDITY
    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _task_set_error(PARTITION_INVALID);
        return (MAX_MQX_UINT);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    return (partpool_ptr->AVAILABLE);

} /* Endbody */

/*!
 * \brief Creates the partition kernel component.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * 
 * \warning Cannot be called from an ISR.
 * \warning Might block the calling task.
 * 
 * \see _partition_create
 * \see _partition_destroy   
 */ 
_mqx_uint _partition_create_component(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR         kernel_data;
    PARTITION_COMPONENT_STRUCT_PTR part_component_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE1(KLOG_partition_create_component);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_partition_create_component, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    _lwsem_wait((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM);

#if MQX_CHECK_ERRORS
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS] != NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM);
        _KLOGX2(KLOG_partition_create_component, MQX_OK);
        return (MQX_OK);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    part_component_ptr = _mem_alloc_system_zero((_mem_size) sizeof(PARTITION_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (part_component_ptr == NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM);
        _KLOGX2(KLOG_partition_create_component, MQX_OUT_OF_MEMORY);
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */
    _mem_set_type(part_component_ptr, MEM_TYPE_PARTITION_COMPONENT);

    kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS] = part_component_ptr;
    part_component_ptr->VALID = PARTITION_VALID;

    _QUEUE_INIT(&part_component_ptr->PARTITIONS, 0);

#if MQX_COMPONENT_DESTRUCTION
    kernel_data->COMPONENT_CLEANUP[KERNEL_PARTITIONS] = _partition_cleanup;
#endif /* MQX_COMPONENT_DESTRUCTION */

    _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM);

    _KLOGX2(KLOG_partition_create_component, MQX_OK);

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Creates the partition at the specific location outside the default 
 * memory pool (a static partition).
 * 
 * \param[in] partition_location Pointer to the start of the partition.
 * \param[in] partition_size     The size of the partition.
 * \param[in] block_size         Number of single-addressable units in each 
 * partition block in the partition.
 * 
 * \return Partition ID (success).
 * \return PARTITION_NULL_ID (failure)
 * 
 * \warning Creates the partition component if it were not previously created.
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li MAX_INVALID_PARAMETER (One of the following: block_size is 0 or 
 * partition_size is too small.)  
 * 
 * \see _partition_alloc
 * \see _partition_alloc_zero
 * \see _partition_alloc_system
 * \see _partition_alloc_system_zero
 * \see _partition_calculate_size
 * \see _partition_create
 * \see _partition_extend
 * \see _task_set_error
 */ 
_partition_id _partition_create_at
(
    pointer   partition_location,
    _mem_size partition_size,
    _mem_size block_size
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    PARTPOOL_STRUCT_PTR partpool_ptr;
    uchar_ptr           firstblock_ptr;
    _mqx_uint           number_of_blocks;
    _mqx_uint           result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_partition_create_at, partition_location, partition_size, block_size);

#if MQX_CHECK_ERRORS
    if (block_size == 0)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_partition_create_at, PARTITION_NULL_ID);
        return (PARTITION_NULL_ID);
    } /* Endif */

    if (partition_size < sizeof(PARTPOOL_STRUCT))
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_partition_create_at, PARTITION_NULL_ID);
        return (PARTITION_NULL_ID);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    block_size += (_mem_size) sizeof(INTERNAL_PARTITION_BLOCK_STRUCT);
    _MEMORY_ALIGN_VAL_LARGER(block_size);

    partpool_ptr = (PARTPOOL_STRUCT_PTR)
    _ALIGN_ADDR_TO_HIGHER_MEM(partition_location);

    firstblock_ptr = (uchar_ptr) partpool_ptr + sizeof(PARTPOOL_STRUCT);
    firstblock_ptr = (uchar_ptr) _ALIGN_ADDR_TO_HIGHER_MEM(firstblock_ptr);
    partition_size -= (_mem_size) firstblock_ptr - (_mem_size) partition_location;

    number_of_blocks = (_mqx_uint) (partition_size / block_size);

#if MQX_CHECK_ERRORS
    if (!number_of_blocks)
    {
        _KLOGX2(KLOG_partition_create_at, PARTITION_NULL_ID);
        return (PARTITION_NULL_ID);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    result = _partition_create_internal(partpool_ptr, block_size, number_of_blocks);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        _KLOGX2(KLOG_partition_create_at, result);
        return (PARTITION_NULL_ID);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    partpool_ptr->PARTITION_TYPE = PARTITION_STATIC;

    _KLOGX5(KLOG_partition_create_at, partpool_ptr, partition_size, block_size, MQX_OK);
    return ((_partition_id) partpool_ptr);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Create a partition at a location with a specified number of blocks.
 * 
 * \param[in] partpool_ptr   The start of the partition.
 * \param[in] actual_size    The total size of each block with overheads.
 * \param[in] initial_blocks The initial number of blocks in the partition.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)   
 */ 
_mqx_uint _partition_create_internal
(
    PARTPOOL_STRUCT_PTR partpool_ptr,
    _mem_size           actual_size,
    _mqx_uint           initial_blocks
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr;
    PARTITION_COMPONENT_STRUCT_PTR      part_component_ptr;
    _mqx_uint                           result;

    _GET_KERNEL_DATA(kernel_data);

    part_component_ptr = (PARTITION_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS];
    if (part_component_ptr == NULL)
    {
        result = _partition_create_component();
        part_component_ptr = (PARTITION_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (part_component_ptr == NULL)
        {
            return (result);
        } /* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */
    } /* Endif */

    _mem_zero(partpool_ptr, (_mem_size) sizeof(PARTPOOL_STRUCT));

    partpool_ptr->BLOCK_SIZE = actual_size;
    partpool_ptr->POOL.VALID = PARTITION_VALID;
    partpool_ptr->POOL.NUMBER_OF_BLOCKS = initial_blocks;
    partpool_ptr->AVAILABLE = initial_blocks;
    partpool_ptr->TOTAL_BLOCKS = initial_blocks;

    block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) partpool_ptr + sizeof(PARTPOOL_STRUCT));

    block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)
    _ALIGN_ADDR_TO_HIGHER_MEM(block_ptr);

    partpool_ptr->POOL.FIRST_IBLOCK_PTR = block_ptr;

    while (initial_blocks--)
    {
        block_ptr->LINK.NEXT_BLOCK_PTR = partpool_ptr->FREE_LIST_PTR;
        CALC_PARTITION_CHECKSUM(block_ptr);
        partpool_ptr->FREE_LIST_PTR = block_ptr;
        block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + actual_size);
    } /* Endwhile */

    _int_disable();
    _QUEUE_ENQUEUE(&part_component_ptr->PARTITIONS, partpool_ptr);
    _int_enable();

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Creates the partition in the default memory pool (a dynamic partition).
 * 
 * The function creates a partition of fixed-size partition blocks in the default 
 * memory pool.
 * 
 * \param[in] block_size     Number of single-addressable units in each partition 
 * block.
 * \param[in] initial_blocks The initial number of blocks in the partition.
 * \param[in] grow_blocks    Number of blocks by which to grow the partition if 
 * all the partition blocks are allocated.
 * \param[in] maximum_blocks If grow_blocks is not 0, one of:
 * \li Maximum number of blocks in the partition.
 * \li 0 (Unlimited growth.)
 * 
 * \return Partition ID (success).
 * \return PARTITION_NULL_ID (failure)
 * 
 * \warning Creates the partition component if it were not previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_PARAMETER (Block_size is 0.)
 * \li Task error codes returned by _mem_alloc_system()
 * 
 * \see _partition_alloc
 * \see _partition_alloc_zero
 * \see _partition_alloc_system
 * \see _partition_alloc_system_zero
 * \see _partition_calculate_size
 * \see _partition_create_at
 * \see _partition_destroy
 * \see _task_set_error
 * \see _mem_alloc_system 
 */ 
_partition_id _partition_create
(
    _mem_size block_size,
    _mqx_uint initial_blocks,
    _mqx_uint grow_blocks,
    _mqx_uint maximum_blocks
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    PARTPOOL_STRUCT_PTR    partpool_ptr;
    _mem_size              actual_size;
    _mqx_uint              result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE5(KLOG_partition_create, block_size, initial_blocks, grow_blocks,
                    maximum_blocks);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _task_set_error(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        _KLOGX2(KLOG_partition_create, PARTITION_NULL_ID);
        return (PARTITION_NULL_ID);
    } /* Endif */

    if (block_size == 0)
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_partition_create, PARTITION_NULL_ID);
        return (PARTITION_NULL_ID);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    actual_size = (_mem_size) sizeof(INTERNAL_PARTITION_BLOCK_STRUCT) + block_size;
    _MEMORY_ALIGN_VAL_LARGER(actual_size);

#if PSP_MEMORY_ALIGNMENT
    partpool_ptr = (PARTPOOL_STRUCT_PTR) _mem_alloc_system((_mem_size) (sizeof(PARTPOOL_STRUCT) + PSP_MEMORY_ALIGNMENT
                    + (actual_size * initial_blocks)));
#else
    partpool_ptr = ((PARTPOOL_STRUCT_PTR))_mem_alloc_system(
                    (_mem_size)(sizeof(PARTPOOL_STRUCT) + (actual_size * initial_blocks)));
#endif /* PSP_MEMORY_ALIGNMENT */
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (partpool_ptr == NULL)
    {
        _KLOGX2(KLOG_partition_create, PARTITION_NULL_ID);
        return (PARTITION_NULL_ID);
    }/* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */
    _mem_set_type(partpool_ptr, MEM_TYPE_PARTITION);

    result = _partition_create_internal(partpool_ptr, actual_size, initial_blocks);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (result != MQX_OK)
    {
        _KLOGX2(KLOG_partition_create, PARTITION_NULL_ID);
        _mem_free(partpool_ptr);
        return (PARTITION_NULL_ID);
    } /* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */

    partpool_ptr->PARTITION_TYPE = PARTITION_DYNAMIC;
    partpool_ptr->GROW_BLOCKS = grow_blocks;
    partpool_ptr->MAXIMUM_BLOCKS = maximum_blocks;

    _KLOGX3(KLOG_partition_create, partpool_ptr, MQX_OK);
    return ((_partition_id) partpool_ptr);

} /* Endbody */

/*!
 * \brief Destroys a partition that is in the default memory pool (a dynamic 
 * partition).
 * 
 * If all the partition blocks in a dynamic partition are first freed, any task 
 * can destroy the partition.
 * 
 * \param[in] partition Partition ID of the partition to destroy.
 * 
 * \return MQX_OK 
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Partition component is not created.)
 * \return MQX_INVALID_PARAMETER (Partition_id is invalid.)
 * \return PARTITION_INVALID_TYPE (Partition is not a dynamic partition.)
 * \return PARTITION_ALL_BLOCKS_NOT_FREE (There are allocated partition blocks in 
 * the partition.)
 * \return Errors from _mem_free() 
 * 
 * \see _mem_free
 * \see _partition_create
 * \see _partition_free      
 */ 
_mqx_uint _partition_destroy
(
    _partition_id partition
)
{ /* Body */
    /* _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;) */
    KERNEL_DATA_STRUCT_PTR         kernel_data;
    PARTPOOL_STRUCT_PTR            partpool_ptr;
    PARTPOOL_BLOCK_STRUCT_PTR      current_ptr;
    PARTPOOL_BLOCK_STRUCT_PTR      next_ptr;
    _mqx_uint                      result;
    PARTITION_COMPONENT_STRUCT_PTR part_component_ptr;

    /* _KLOGM(_GET_KERNEL_DATA(kernel_data);) */
    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_partition_destroy, partition);

    part_component_ptr = (PARTITION_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS];

    partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;

#if MQX_CHECK_ERRORS
    if (part_component_ptr == NULL)
    {
        _KLOGX2(KLOG_partition_destroy, MQX_COMPONENT_DOES_NOT_EXIST);
        return MQX_COMPONENT_DOES_NOT_EXIST;
    } /* Endif */

    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _KLOGX2(KLOG_partition_destroy, MQX_INVALID_PARAMETER);
        return MQX_INVALID_PARAMETER;
    } /* Endif */

    if (partpool_ptr->PARTITION_TYPE != PARTITION_DYNAMIC)
    {
        _KLOGX2(KLOG_partition_destroy, PARTITION_INVALID_TYPE);
        return PARTITION_INVALID_TYPE;
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    if (partpool_ptr->TOTAL_BLOCKS != partpool_ptr->AVAILABLE)
    {
        _KLOGX2(KLOG_partition_destroy, PARTITION_ALL_BLOCKS_NOT_FREE);
        return PARTITION_ALL_BLOCKS_NOT_FREE;
    } /* Endif */

    /* Remove the partition from the list of partitions maintained by MQX */
    _int_disable();
    _QUEUE_REMOVE(&part_component_ptr->PARTITIONS, partpool_ptr);
    _int_enable();

    partpool_ptr->POOL.VALID = 0;

    /* Free any extensions */
    current_ptr = partpool_ptr->POOL.NEXT_POOL_PTR;
    while (current_ptr)
    {
        next_ptr = current_ptr->NEXT_POOL_PTR;
        _mem_free(current_ptr);
        current_ptr = next_ptr;
    } /* Endwhile */

    result = _mem_free(partpool_ptr);

    _KLOGX2(KLOG_partition_destroy, result);

    return result;

} /* Endbody */

/*!
 * \brief Adds more blocks of memory to the static partition.
 * 
 * The function extends a partition that was created with _partition_create_at(). 
 * Based on the size of the partition's partition blocks, the function divides 
 * the additional memory into partition blocks and adds them to the partition.
 * 
 * \param[in] partition          Static partition to extend.
 * \param[in] partition_location Where the additional blocks are to start from.
 * \param[in] partition_size     Number of single-addressable units to add.
 * 
 * \return MQX_OK
 * \return PARTITION_INVALID (Partition does not represent a valid partition.)
 * \return MQX_INVALID_PARAMETER (One of the following:
 * \li Partition_size is 0.
 * \li Partition_id does not represent a static partition.)
 * 
 * \see _partition_create_at
 * \see _partition_alloc
 * \see _partition_alloc_zero
 */ 
_mqx_uint _partition_extend
(
    _partition_id partition,
    pointer       partition_location,
    _mem_size     partition_size
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    PARTPOOL_STRUCT_PTR                 partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;
    PARTPOOL_BLOCK_STRUCT_PTR           partpool_block_ptr;
    INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr;
    _mqx_uint                           number_of_blocks;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_partition_extend, partition, partition_location, partition_size);

#if MQX_CHECK_VALIDITY
    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _KLOGX2(KLOG_partition_extend, PARTITION_INVALID);
        return (PARTITION_INVALID);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

#if MQX_CHECK_ERRORS
    if (partpool_ptr->PARTITION_TYPE == PARTITION_DYNAMIC)
    {
        _KLOGX2(KLOG_partition_extend, MQX_INVALID_PARAMETER);
        return (MQX_INVALID_PARAMETER);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    partpool_block_ptr = (PARTPOOL_BLOCK_STRUCT_PTR)
    _ALIGN_ADDR_TO_HIGHER_MEM(partition_location);
    partition_size = partition_size - (_mem_size) partpool_block_ptr + (_mem_size) partition_location;
    _MEMORY_ALIGN_VAL_SMALLER(partition_size);

#if MQX_CHECK_ERRORS
    if (partition_size < (_mem_size) sizeof(PARTPOOL_STRUCT))
    {
        _KLOGX2(KLOG_partition_extend, MQX_INVALID_PARAMETER);
        return (MQX_INVALID_PARAMETER);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) partpool_block_ptr + sizeof(PARTPOOL_BLOCK_STRUCT));
    block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)
    _ALIGN_ADDR_TO_HIGHER_MEM(block_ptr);

    number_of_blocks = (partition_size - ((uchar_ptr) block_ptr - (uchar_ptr) partpool_block_ptr))
                    / partpool_ptr->BLOCK_SIZE;
    partpool_ptr->TOTAL_BLOCKS += number_of_blocks;

    _partition_extend_internal(partpool_ptr, partpool_block_ptr, number_of_blocks);

    _KLOGX5(KLOG_partition_extend, partition, partpool_ptr, partition_size, MQX_OK);

    return MQX_OK;

} /* Endbody */

/*!
 * \private
 * 
 * \brief Adds more blocks of memory into the partition.
 * 
 * \param[in] partpool_ptr       The partition to add to.
 * \param[in] partpool_block_ptr The new block to add.
 * \param[in] number_of_blocks   The number of blocks to add.
 */ 
void _partition_extend_internal
(
    PARTPOOL_STRUCT_PTR       partpool_ptr,
    PARTPOOL_BLOCK_STRUCT_PTR partpool_block_ptr,
    _mqx_uint                 number_of_blocks
)
{ /* Body */
    INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr;

    partpool_block_ptr->VALID = PARTITION_VALID;
    partpool_block_ptr->NUMBER_OF_BLOCKS = number_of_blocks;

    block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) partpool_block_ptr + sizeof(PARTPOOL_BLOCK_STRUCT));
    block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)
    _ALIGN_ADDR_TO_HIGHER_MEM(block_ptr);

    partpool_block_ptr->FIRST_IBLOCK_PTR = block_ptr;

    while (number_of_blocks--)
    {
        _int_disable();
        block_ptr->LINK.NEXT_BLOCK_PTR = partpool_ptr->FREE_LIST_PTR;
        CALC_PARTITION_CHECKSUM(block_ptr);
        partpool_ptr->FREE_LIST_PTR = block_ptr;
        partpool_ptr->AVAILABLE++;
        _int_enable();
        block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + partpool_ptr->BLOCK_SIZE);
    } /* Endwhile */

    _int_disable();
    partpool_block_ptr->NEXT_POOL_PTR = partpool_ptr->POOL.NEXT_POOL_PTR;
    partpool_ptr->POOL.NEXT_POOL_PTR = partpool_block_ptr;
    _int_enable();

} /* Endbody */

/*!
 * \brief Frees the selected partition block and returns it to the partition.
 * 
 * Partition blocks created by _partition_alloc() or _partition_alloc_zero() can 
 * be freed only by task, that allocated them. However when partition block was 
 * created by _partition_alloc_system() or _partition_alloc_system_zero(), then 
 * it can be freed by any task.
 * 
 * \param[in] mem_ptr Pointer to the partition block to free.
 * 
 * \return MQX_OK
 * \return PARTITION_BLOCK_INVALID_CHECKSUM (Checksum in the partition block 
 * header is not correct; the integrity of the partition is in question.)
 * \return MQX_NOT_RESOURCE_OWNER (Task is not the one that owns the partition block.)
 * \return PARTITION_INVALID (Mem_ptr is part of a partition that is not valid.)
 * 
 * \see _partition_alloc
 * \see _partition_alloc_zero
 * \see _partition_alloc_system
 * \see _partition_alloc_system_zero
 * \see _partition_create    
 */ 
_mqx_uint _partition_free
(
    pointer mem_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    PARTPOOL_STRUCT_PTR                 partpool_ptr;
    INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_partition_free, mem_ptr);

    block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) mem_ptr - sizeof(INTERNAL_PARTITION_BLOCK_STRUCT));

#if MQX_CHECK_VALIDITY
    if (!VALID_PARTITION_CHECKSUM(block_ptr))
    {
        _KLOGX2(KLOG_partition_free, PARTITION_BLOCK_INVALID_CHECKSUM);
        return (PARTITION_BLOCK_INVALID_CHECKSUM);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

#if MQX_CHECK_ERRORS
    if (block_ptr->TASK_ID != SYSTEM_TD_PTR(kernel_data)->TASK_ID)
    {
        /* Let system blocks be freed by anyone */
        if (block_ptr->TASK_ID != kernel_data->ACTIVE_PTR->TASK_ID)
        {
            _KLOGX2(KLOG_partition_free, MQX_NOT_RESOURCE_OWNER);
            return (MQX_NOT_RESOURCE_OWNER);
        } /* Endif */
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    partpool_ptr = block_ptr->LINK.PARTITION_PTR;
    _INT_DISABLE();

#if MQX_CHECK_VALIDITY
    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_partition_free, PARTITION_INVALID);
        return (PARTITION_INVALID);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    block_ptr->TASK_ID = 0;
    block_ptr->LINK.NEXT_BLOCK_PTR = partpool_ptr->FREE_LIST_PTR;
    partpool_ptr->FREE_LIST_PTR = block_ptr;

    ++partpool_ptr->AVAILABLE;
    CALC_PARTITION_CHECKSUM(block_ptr);

    _INT_ENABLE();
    _KLOGX2(KLOG_partition_free, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Allocates a system partition block from the partition.
 * 
 * The functions allocate a fixed-size block of memory that is not owned by any 
 * task.
 * 
 * \param[in] partition Partition from which to allocate the partition block.
 * 
 * \return Pointer to the partition block (success).
 * \return NULL (failure)
 *   
 * \warning On failure, calls _task_set_error() to set one of the task error codes 
 * described for _partition_alloc().
 *   
 * \see _partition_alloc_system_zero
 * \see _partition_alloc
 * \see _partition_alloc_zero
 * \see _partition_create
 * \see _task_set_error
 */ 
pointer _partition_alloc_system
(
    _partition_id partition
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_partition_alloc_system, partition);

    result = _partition_alloc_internal((PARTPOOL_STRUCT_PTR) partition, SYSTEM_TD_PTR(kernel_data));

    _KLOGX2(KLOG_partition_alloc_system, result);
    return (result);

} /* Endbody */

/*!
 * \brief Allocates a zero-filled system partition block from the partition.
 * 
 * The functions allocate a fixed-size block of memory that is not owned by any 
 * task.
 * 
 * \param[in] partition Partition from which to allocate the partition block.
 * 
 * \return Pointer to the partition block (success).
 * \return NULL (failure)
 *   
 * \warning On failure, calls _task_set_error() to set one of the task error codes 
 * described for _partition_alloc(). 
 * 
 * \see _partition_alloc_system
 * \see _partition_alloc
 * \see _partition_alloc_zero
 * \see _partition_create
 * \see _task_set_error
 */ 
pointer _partition_alloc_system_zero
(
    _partition_id partition
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    PARTPOOL_STRUCT_PTR    partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_partition_alloc_system_zero, partition);

    result = _partition_alloc_internal(partpool_ptr, SYSTEM_TD_PTR(kernel_data));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (result == NULL)
    {
        _KLOGX2(KLOG_partition_alloc_system_zero, result);
        return (result);
    } /* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */

    _mem_zero(result, (_mem_size) (partpool_ptr->BLOCK_SIZE - sizeof(INTERNAL_PARTITION_BLOCK_STRUCT)));

    _KLOGX2(KLOG_partition_alloc_system_zero, result);
    return (result);

} /* Endbody */

/*!
 * \brief Returns all partition blocks owned by the task to the pool.
 * 
 * \param[in] td_ptr The task being destroyed.
 */ 
void _partition_cleanup
(
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    PARTPOOL_STRUCT_PTR                 partpool_ptr;
    PARTPOOL_BLOCK_STRUCT_PTR           partpool_block_ptr;
    PARTITION_COMPONENT_STRUCT_PTR      part_component_ptr;
    INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr;
    _mqx_uint                           i;

    _GET_KERNEL_DATA(kernel_data);

    part_component_ptr = (PARTITION_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS];

    if (part_component_ptr == NULL)
    {
        return; /* No work to do! */
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (part_component_ptr->VALID != PARTITION_VALID)
    {
        return;
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    partpool_ptr = (PARTPOOL_STRUCT_PTR)((pointer) part_component_ptr->PARTITIONS.NEXT);
    while (partpool_ptr != (PARTPOOL_STRUCT_PTR)((pointer) &part_component_ptr->PARTITIONS))
    {
        /* Check each partition */
        partpool_block_ptr = &partpool_ptr->POOL;
        while (partpool_block_ptr != NULL)
        {
            /* Check each poolblock in the partition */
#if MQX_CHECK_VALIDITY
            if (partpool_block_ptr->VALID != PARTITION_VALID)
            {
                break;
            }/* Endif */
#endif /* MQX_CHECK_VALIDITY */
            block_ptr = partpool_block_ptr->FIRST_IBLOCK_PTR;
            i = partpool_block_ptr->NUMBER_OF_BLOCKS + 1;
            while (--i)
            {
                if ((block_ptr->TASK_ID == td_ptr->TASK_ID) && (block_ptr->LINK.PARTITION_PTR == partpool_ptr))
                { /* An allocated Block */
                    _int_disable();
                    block_ptr->LINK.NEXT_BLOCK_PTR = partpool_ptr->FREE_LIST_PTR;
                    partpool_ptr->FREE_LIST_PTR = block_ptr;
                    ++partpool_ptr->AVAILABLE;
                    CALC_PARTITION_CHECKSUM(block_ptr);
                    _int_enable();
                } /* Endif */
                block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + partpool_ptr->BLOCK_SIZE);
            } /* Endwhile */
            partpool_block_ptr = partpool_block_ptr->NEXT_POOL_PTR;
        } /* Endwhile */

        partpool_ptr = (PARTPOOL_STRUCT_PTR) partpool_ptr->NEXT;
    } /* Endwhile */

} /* Endbody */

/*!
 * \brief Tests all partition block checksums for validity.
 * 
 * \param[out] partpool_in_error       Pointer to the partition pool in error 
 * (initialized only if an error is found).
 * \param[out] partpool_block_in_error Pointer to the partition pool block in 
 * error (internal to MQX).
 * \param[out] block_in_error          Pointer to the partition block in error 
 * (initialized only if an error is found).
 * 
 * \return MQX_OK (No partitions have errors.)
 * \return MQX_INVALID_COMPONENT_BASE (Partition component data are not valid.)
 * \return PARTITION_INVALID (MQX found an invalid partition.)
 * \return PARTITION_BLOCK_INVALID_CHECKSUM (MQX found a partition block with an 
 * incorrect checksum.)
 * \return MQX_CORRUPT_QUEUE (An error is found.)
 * 
 * \warning Disables and enables interrupts.
 * 
 * \see _partition_alloc
 * \see _partition_alloc_zero
 * \see _partition_alloc_system
 * \see _partition_alloc_system_zero
 * \see _partition_create
 * \see _partition_free     
 */ 
_mqx_uint _partition_test
(
    _partition_id _PTR_ partpool_in_error,
    pointer _PTR_       partpool_block_in_error,
    pointer _PTR_       block_in_error
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    PARTPOOL_STRUCT_PTR                 partpool_ptr;
    PARTPOOL_BLOCK_STRUCT_PTR           partpool_block_ptr;
    INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr;
    PARTITION_COMPONENT_STRUCT_PTR      part_component_ptr;
    _mqx_uint                           i;
    _mqx_uint                           result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE1(KLOG_partition_test);

    part_component_ptr = (PARTITION_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS];
    if (part_component_ptr == NULL)
    {
        _KLOGX2(KLOG_partition_test, MQX_OK);
        return (MQX_OK);
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (part_component_ptr->VALID != PARTITION_VALID)
    {
        _KLOGX2(KLOG_partition_test, MQX_INVALID_COMPONENT_BASE);
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    _int_disable();

    /* Make sure that the queue of partitions is ok */
    result = _queue_test(&part_component_ptr->PARTITIONS, partpool_in_error);
    _int_enable();
    if (result != MQX_OK)
    {
        _KLOGX3(KLOG_partition_test, result, *partpool_in_error);
        return (result);
    } /* Endif */

    partpool_ptr = (PARTPOOL_STRUCT_PTR)((pointer) part_component_ptr->PARTITIONS.NEXT);
    while (partpool_ptr != (PARTPOOL_STRUCT_PTR)((pointer) &part_component_ptr->PARTITIONS))
    {
        /* Check all partitions */
        *partpool_in_error = partpool_ptr;

        partpool_block_ptr = &partpool_ptr->POOL;
        while (partpool_block_ptr != NULL)
        {
            /* Check all partition pool blocks contiguously */
            *partpool_block_in_error = partpool_block_ptr;

            block_ptr = partpool_block_ptr->FIRST_IBLOCK_PTR;
            i = partpool_block_ptr->NUMBER_OF_BLOCKS + 1;
            while (--i)
            {
#if MQX_CHECK_VALIDITY
                if (partpool_ptr->POOL.VALID != PARTITION_VALID)
                {
                    *block_in_error = NULL;
                    _KLOGX2(KLOG_partition_test, PARTITION_INVALID);
                    return (PARTITION_INVALID);
                } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
                _int_disable();
                if (!VALID_PARTITION_CHECKSUM(block_ptr))
                {
                    _int_enable();
                    *block_in_error = (pointer) ((uchar_ptr) block_ptr + sizeof(INTERNAL_PARTITION_BLOCK_STRUCT));
                    _KLOGX2(KLOG_partition_test, PARTITION_BLOCK_INVALID_CHECKSUM);
                    return (PARTITION_BLOCK_INVALID_CHECKSUM);
                } /* Endif */
                _int_enable();
                block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) block_ptr + partpool_ptr->BLOCK_SIZE);
            } /* Endwhile */

            partpool_block_ptr = partpool_block_ptr->NEXT_POOL_PTR;
        } /* Endwhile */

        /* Check partition free list */
        _int_disable();
        block_ptr = partpool_ptr->FREE_LIST_PTR;
        while (block_ptr != NULL)
        {
            partpool_ptr->TEST_FREE_PTR = block_ptr;
            _int_enable();
            _int_disable();
            block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR) partpool_ptr->TEST_FREE_PTR;
            if (!VALID_PARTITION_CHECKSUM(block_ptr))
            {
                _int_enable();
                *block_in_error = (pointer) ((uchar_ptr) block_ptr + sizeof(INTERNAL_PARTITION_BLOCK_STRUCT));
                _KLOGX2(KLOG_partition_test, PARTITION_BLOCK_INVALID_CHECKSUM);
                return (PARTITION_BLOCK_INVALID_CHECKSUM);
            } /* Endif */
            block_ptr = block_ptr->LINK.NEXT_BLOCK_PTR;
        } /* Endwhile */

        partpool_ptr = (PARTPOOL_STRUCT_PTR) partpool_ptr->NEXT;
        _int_enable();
    } /* Endwhile */

    _KLOGX2(KLOG_partition_test, MQX_OK);
    return MQX_OK;

} /* Endbody */

/*!
 * \brief Transfers the ownership of the partition block.
 * 
 * Any task can transfer the ownership of a private partition block or a system 
 * partition block.
 * \n If new_owner_id is the System Task ID, the partition block becomes a system 
 * partition block.
 * \n If the ownership of a system partition block is transferred to a task, the 
 * partition block becomes a resource of the task.
 * 
 * \param[in] mem_ptr      Pointer to the partition block to transfer.
 * \param[in] new_owner_id Task ID of the new owner.
 * 
 * \return MQX_OK 
 * \return PARTITION_BLOCK_INVALID_CHECKSUM (Checksum of the partition block 
 * header is not correct, which indicates that mem_ptr might not point to a valid 
 * partition block.)
 * \return PARTITION_INVALID_TASK_ID (Task_id is not valid.)
 * 
 * \see _partition_alloc
 * \see _partition_alloc_zero
 * \see _partition_alloc_system
 * \see _partition_alloc_system_zero   
 */ 
_mqx_uint _partition_transfer
(
    pointer  mem_ptr,
    _task_id new_owner_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR              kernel_data;
    TD_STRUCT_PTR                       new_td_ptr;
    INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_partition_transfer, mem_ptr, new_owner_id);

    block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr) mem_ptr - sizeof(INTERNAL_PARTITION_BLOCK_STRUCT));

#if MQX_CHECK_VALIDITY
    if (!VALID_PARTITION_CHECKSUM(block_ptr))
    {
        _KLOGX2(KLOG_partition_transfer, PARTITION_BLOCK_INVALID_CHECKSUM);
        return (PARTITION_BLOCK_INVALID_CHECKSUM);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    new_td_ptr = (TD_STRUCT_PTR) _task_get_td(new_owner_id);
#if MQX_CHECK_ERRORS
    if (new_td_ptr == NULL)
    {
        _KLOGX2(KLOG_partition_transfer, PARTITION_INVALID_TASK_ID);
        return (PARTITION_INVALID_TASK_ID);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    _INT_DISABLE();
    block_ptr->TASK_ID = new_owner_id;
    CALC_PARTITION_CHECKSUM(block_ptr);
    _INT_ENABLE();

    _KLOGX2(KLOG_partition_transfer, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Gets the number of allocated partition blocks in the partition.
 * 
 * \param[in] partition The partition to obtain information about.
 * 
 * \return Number of allocated partition blocks (success).
 * \return 0 (failure)
 * 
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li PARTITION_INVALID (Partition does not represent a valid partition.)
 * 
 * \see _partition_get_block_size
 * \see _partition_get_free_blocks
 * \see _partition_get_total_blocks
 * \see _partition_get_total_size
 * \see _task_set_error  
 */ 
_mqx_uint _partition_get_max_used_blocks
(
    _partition_id partition
)
{ /* Body */
    PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;

#if MQX_CHECK_VALIDITY
    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _task_set_error(PARTITION_INVALID);
        return 0;
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    return (partpool_ptr->MAX_BLOCKS_USED);

} /* Endbody */

/*!
 * \brief Gets the total number of partition blocks in the partition.
 * 
 * The function returns the sum of the number of free partition blocks and the 
 * number of allocated partition blocks in the partition.
 * 
 * \param[in] partition The partition to obtain information about.
 * 
 * \return Total number of partition blocks in the partition (success).
 * \return 0 (failure)
 * 
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li PARTITION_INVALID (Partition does not represent a valid partition.)
 * 
 * \see _partition_get_block_size
 * \see _partition_get_free_blocks
 * \see _partition_get_max_used_blocks
 * \see _partition_get_total_size
 * \see _task_set_error  
 */ 
_mqx_uint _partition_get_total_blocks
(
    _partition_id partition
)
{ /* Body */
    PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;

#if MQX_CHECK_VALIDITY
    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _task_set_error(PARTITION_INVALID);
        return 0;
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    return (partpool_ptr->TOTAL_BLOCKS);

} /* Endbody */

/*!
 * \brief Gets the size of the partition blocks in the partition.
 * 
 * If the processor supports memory alignment, the function might return a value 
 * that is larger that what was specified when the partition was created.
 * 
 * \param[in] partition The partition to obtain information about.
 * 
 * \return Number of single-addressable units in a partition block (success).
 * \return 0 (failure) 
 * 
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li PARTITION_INVALID (Partition does not represent a valid partition.)
 * 
 * \see _partition_get_free_blocks
 * \see _partition_get_max_used_blocks
 * \see _partition_get_total_blocks
 * \see _partition_get_total_size
 * \see _partition_create_at
 * \see _task_set_error 
 */ 
_mem_size _partition_get_block_size
(
    _partition_id partition
)
{ /* Body */
    PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;

#if MQX_CHECK_VALIDITY
    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _task_set_error(PARTITION_INVALID);
        return 0;
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    return (partpool_ptr->BLOCK_SIZE - (_mem_size) sizeof(INTERNAL_PARTITION_BLOCK_STRUCT));

} /* Endbody */

/*!
 * \brief Gets the size of the partition.
 * 
 * The size of the partition includes extensions and internal overhead.
 * 
 * \param[in] partition The partition to obtain information about.
 * 
 * \return Number of single-addressable units in the partition (success).
 * \return 0 (failure)
 *    
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li PARTITION_INVALID (Partition does not represent a valid partition.)
 * 
 * \see _partition_get_block_size
 * \see _partition_get_free_blocks
 * \see _partition_get_max_used_blocks
 * \see _partition_get_total_blocks
 * \see _partition_extend
 * \see _task_set_error
 */ 
_mem_size _partition_get_total_size
(
    _partition_id partition
)
{ /* Body */
    PARTPOOL_STRUCT_PTR       partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;
    PARTPOOL_BLOCK_STRUCT_PTR partpool_block_ptr;
    register _mem_size        size;
    uchar_ptr                 tmp_ptr;

#if MQX_CHECK_VALIDITY
    if (partpool_ptr->POOL.VALID != PARTITION_VALID)
    {
        _task_set_error(PARTITION_INVALID);
        return 0;
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    size = 0;
    partpool_block_ptr = partpool_ptr->POOL.NEXT_POOL_PTR;
    while (partpool_block_ptr != NULL)
    {
        tmp_ptr = (uchar_ptr) partpool_block_ptr + sizeof(PARTPOOL_BLOCK_STRUCT);
        tmp_ptr = (uchar_ptr) _ALIGN_ADDR_TO_HIGHER_MEM(tmp_ptr);
        size += (_mem_size) (tmp_ptr - (uchar_ptr) partpool_block_ptr);
        partpool_block_ptr = partpool_block_ptr->NEXT_POOL_PTR;
    } /* Endif */

    tmp_ptr = (uchar_ptr) partition + sizeof(PARTPOOL_STRUCT);
    tmp_ptr = (uchar_ptr) _ALIGN_ADDR_TO_HIGHER_MEM(tmp_ptr);

    size += (_mem_size) (tmp_ptr - (uchar_ptr) partition);

    return (size + partpool_ptr->BLOCK_SIZE * partpool_ptr->TOTAL_BLOCKS);

} /* Endbody */

/*!
 * \brief Calculates the number of single-addressable units in a partition.
 * 
 * If an application wants to use as much as possible of some memory that is 
 * outside the default memory pool, it can use the function to determine the 
 * maximum number of blocks that can be created.
 * \n For a dynamic partition, the application might want to limit (based on the 
 * results of the function) the amount of memory in the default memory pool that 
 * it uses to create the partition.
 * 
 * \param[in] number_of_blocks Number of partition blocks in the partition.
 * \param[in] block_size       Number of single-addressable units in one partition 
 * block in the partition.
 * 
 * \return Number of single-addressable units in the partition.
 * 
 * \see _partition_calculate_blocks
 * \see _partition_create
 * \see _partition_create_at 
 */ 
_mem_size _partition_calculate_size
(
    _mqx_uint number_of_blocks,
    _mem_size block_size
)
{ /* Body */
    _mem_size actual_block_size;
    _mem_size size;

    actual_block_size = sizeof(INTERNAL_PARTITION_BLOCK_STRUCT) + block_size;
    _MEMORY_ALIGN_VAL_LARGER(actual_block_size);

#if PSP_MEMORY_ALIGNMENT
    size = sizeof(PARTPOOL_STRUCT) + PSP_MEMORY_ALIGNMENT + actual_block_size * number_of_blocks;
#else
    size = sizeof(PARTPOOL_STRUCT) + actual_block_size * number_of_blocks;
#endif /* PSP_MEMORY_ALIGNMENT */

    return (size);
} /* Endbody */

/*!
 * /brief Calculates the number of partition blocks in a static partition.
 * 
 * When a task creates a static partition (_partition_create_at()), it specifies 
 * the size of the partition and the size of partition blocks. The function 
 * _partition_calculate_blocks() calculates how many blocks MQX actually created, 
 * taking into account internal headers.
 * 
 * \param[in] partition_size Number of single-addressable units that the partition 
 * can occupy.
 * \param[in] block_size     Number of single-addressable units in one partition 
 * block of the partition.
 * 
 * \return Number of partition blocks in the partition.
 * 
 * \see _partition_calculate_size
 * \see _partition_create_at 
 */ 
_mqx_uint _partition_calculate_blocks
(
    _mem_size partition_size,
    _mem_size block_size
)
{ /* Body */
    _mem_size actual_size;
    _mem_size size;

    actual_size = sizeof(INTERNAL_PARTITION_BLOCK_STRUCT) + block_size;
    _MEMORY_ALIGN_VAL_LARGER(actual_size);

    size = (_mem_size) sizeof(PARTPOOL_STRUCT);
    _MEMORY_ALIGN_VAL_LARGER(size);
    return ((_mqx_uint) ((partition_size - size) / actual_size));

} /* Endbody */
/*!
 * \brief Gets size of partition.
 * 
 * \return Size of partition (Success).
 * \return 0 (Failure)   
 */ 
_mqx_uint _partition_get_number_of(void)
{
    uint_32                        count = 0;
    KERNEL_DATA_STRUCT_PTR         kernel_data;
    PARTITION_COMPONENT_STRUCT_PTR part_component_ptr;

    _GET_KERNEL_DATA(kernel_data);

    part_component_ptr = (PARTITION_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS];

    if (part_component_ptr)
    {
        count = part_component_ptr->PARTITIONS.SIZE;
    }
    else
    {
        count = 0;
    } /* Endif */

    return count;
}
/*!
 * \brief Allocates a zero-filled private partition block from the partition.
 * 
 * The functions allocate a fixed-size memory block, which the task owns.
 * 
 * \param[in] partition Partition from which to allocate the partition block.
 * 
 * \return Pointer to the partition block (success).
 * \return NULL (failure)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li PARTITION_INVALID (Partition does not represent a valid partition.)
 * \li PARTITION_OUT_OF_BLOCKS (All the partition blocks in the partition are 
 * allocated (for static partitions only).)
 * \li PARTITION_BLOCK_INVALID_CHECKSUM (MQX found an incorrect checksum in the 
 * partition block header.)
 * \li Task error code set by _mem_alloc_system() MQX cannot allocate memory for 
 * the partition block (for dynamic partitions only).     
 * 
 * \see _partition_alloc
 * \see _partition_alloc_system
 * \see _partition_alloc_system_zero
 * \see _partition_create
 * \see _task_set_error
 * \see _mem_alloc_system  
 */ 
pointer _partition_alloc_zero
(
    _partition_id partition
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    PARTPOOL_STRUCT_PTR    partpool_ptr = (PARTPOOL_STRUCT_PTR) partition;
    pointer                result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_partition_alloc_zero, partition);

    result = _partition_alloc_internal(partpool_ptr, kernel_data->ACTIVE_PTR);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (result == NULL)
    {
        _KLOGX2(KLOG_partition_alloc_zero, result);
        return (result);
    } /* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */

    _mem_zero(result, (_mem_size) (partpool_ptr->BLOCK_SIZE - sizeof(INTERNAL_PARTITION_BLOCK_STRUCT)));

    _KLOGX2(KLOG_partition_alloc_zero, result);
    return (result);

} /* Endbody */

#endif /* MQX_USE_PARTITIONS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/iptunnel.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iptunnel.c$
* $Version : 3.8.11.0$
* $Date    : Sep-19-2012$
*
* Comments:
*
*   This file contains the IP tunnel encapsulation functionnality.
*
*END************************************************************************/

#include <string.h>
#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "iptunnel.h"

#if RTCSCFG_ENABLE_IPIP && RTCSCFG_ENABLE_IP4 
/*
** The structure used by RTCS to bind an IP address
** to an IP over IP tunnel driver.
*/

static RTCS_IF_STRUCT rtcs_iptunnel = {
   IPIP_open,
   IPIP_close,
   IPIP_send,
#if RTCSCFG_ENABLE_IGMP && BSPCFG_ENABLE_ENET_MULTICAST && RTCSCFG_ENABLE_IP4
   NULL,
   NULL
#endif
};

const RTCS_IF_STRUCT_PTR RTCS_IF_IPIP = &rtcs_iptunnel;


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IPIP_init
* Returned Values : RTCS_OK or error code
* Comments        :
*     Initialize the IP over IP tunnel device.
*
*END*-----------------------------------------------------------------*/

uint_32 IPIP_init
   (
      void
   )
{ /* Body */
   IPIP_CFG_STRUCT_PTR  cfg;
   uint_32              status = RTCS_OK;
   IPIF_PARM            parms;

   cfg = RTCS_mem_alloc_zero(sizeof(IPIP_CFG_STRUCT));

   if (!cfg) {
      return RTCSERR_OUT_OF_MEMORY;
   } /* Endif */

   cfg->IPIP_PART = RTCS_part_create(sizeof(IPIP_TUNNEL), IPIP_INITIAL_COUNT,
      IPIP_GROW_COUNT, 0, NULL, NULL);

   if (!cfg->IPIP_PART) {
      return RTCSERR_CREATE_PARTITION_FAILED;
   } /* Endif */

   /* Add the tunnel device interface to RTCS */
   parms.mhandle = NULL;
   parms.if_ptr = RTCS_IF_IPIP;
   status = RTCSCMD_internal(parms, IPIF_add);
   if (!status) {
      cfg->IPIP_IF = parms.ihandle;
      cfg->IPIP_IF->MTU_FN = IPIP_MTU;
      IP_open(IPPROTO_IPIP, IPIP_service, NULL, &status);
      if (status) {
         RTCSCMD_internal(parms, IPIF_remove);
      } /* Endif */
   } /* Endif */

   if (status) {
      RTCS_part_destroy(cfg->IPIP_PART);
      _mem_free(cfg);
      return status;
   } /* Endif */

   RTCS_setcfg(IPIP, cfg);

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IPIP_service
* Returned Values : void
* Comments        :
*     Services IP over IP packets
*
*END*-----------------------------------------------------------------*/

void IPIP_service
   (
      RTCSPCB_PTR    pcb_ptr,          /* [IN] incoming packet */
      pointer        dummy             /* [IN] not used        */
   )
{ /* Body */
   IPIP_CFG_STRUCT_PTR     cfg = RTCS_getcfg(IPIP);
   pcb_ptr->IFSRC = cfg->IPIP_IF;
   RTCSCMD_service(pcb_ptr, IP_service);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIP_insert
*  Parameters     :
*
*  _ip_address    INNER_SOURCE;         [IN] Embedded header source
*  _ip_address    INNER_SOURCE_NETMASK; [IN] Embedded header source mask
*  _ip_address    INNER_DEST;           [IN] Embedded header destination
*  _ip_address    INNER_DEST_NETMASK;   [IN] Embedded header destination mask
*  _ip_address    OUTER_SOURCE;         [IN] Source for outer header
*  _ip_address    OUTER_DEST;           [IN] Destination for outer header
*  uint_32        FLAGS;                [IN] Behaviour flags
*
*  Comments       :
*        Adds a new IP encasulation tunnel to the IP routing table and to the
*        IPTunnel configuration
*
*END*-----------------------------------------------------------------*/

void IPIP_insert
   (
      IPIP_PARM_PTR  parms
   )
{ /* Body */
   IPIP_CFG_STRUCT_PTR     cfg = RTCS_getcfg(IPIP);
   IPIP_TUNNEL_PTR         tunnel = &parms->TUNNEL;
   uint_32                 error = RTCS_OK;

   /* Make sure IPIP is initialized */
   if (!cfg) {
      RTCSCMD_complete(parms, RTCSERR_IPIP_NOT_INITIALIZED);
      return;
   } /* Endif */

   /*
   ** Make sure the netmask is valid.  We use the fact that
   ** (x & x+1) == 0  <=>  x = 2^n-1.
   */
   if ((~tunnel->INNER_DEST_NETMASK & (~tunnel->INNER_DEST_NETMASK + 1)) ||
       (~tunnel->INNER_SOURCE_NETMASK & (~tunnel->INNER_SOURCE_NETMASK + 1)))
   {
      RTCSCMD_complete(parms, RTCSERR_IP_BIND_MASK);
      return;
   } /* Endif */

   tunnel = RTCS_part_alloc(cfg->IPIP_PART);
   if (!tunnel) {
      RTCSCMD_complete(parms, RTCSERR_OUT_OF_MEMORY);
      return;
   } /* Endif */

   tunnel->NEXT                   = cfg->NEXT;
   tunnel->INNER_SOURCE           = parms->TUNNEL.INNER_SOURCE;
   tunnel->INNER_SOURCE_NETMASK   = parms->TUNNEL.INNER_SOURCE_NETMASK;
   tunnel->INNER_DEST             = parms->TUNNEL.INNER_DEST;
   tunnel->INNER_DEST_NETMASK     = parms->TUNNEL.INNER_DEST_NETMASK;
   tunnel->OUTER_SOURCE           = parms->TUNNEL.OUTER_SOURCE;
   tunnel->OUTER_DEST             = parms->TUNNEL.OUTER_DEST;
   tunnel->FLAGS                  = parms->TUNNEL.FLAGS;

   /* Create the IPIP route entry, if neccessary */
   error = IP_route_add_virtual(
      tunnel->INNER_DEST, tunnel->INNER_DEST_NETMASK,
      INADDR_ANY,
      tunnel->INNER_SOURCE, tunnel->INNER_SOURCE_NETMASK,
      cfg->IPIP_IF, tunnel);

   if (!error) {
      cfg->NEXT = tunnel;        /* Add tunnel to tunnel list  */
      cfg->TUNNELS++;            /* Increment count of tunnels */
   } else {
      RTCS_part_free(tunnel);
   } /* Endif */

   RTCSCMD_complete(parms, error);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIP_delete
*  Parameters     :
*
*  _ip_address    INNER_SOURCE;         [IN] Embedded header source
*  _ip_address    INNER_SOURCE_NETMASK; [IN] Embedded header source mask
*  _ip_address    INNER_DEST;           [IN] Embedded header destination
*  _ip_address    INNER_DEST_NETMASK;   [IN] Embedded header destination mask
*  _ip_address    OUTER_SOURCE;         [IN] Source for outer header
*  _ip_address    OUTER_DEST;           [IN] Destination for outer header
*  uint_32        FLAGS;                [IN] Behaviour flags
*
*  Comments       :
*        Removes a IP over IP encasulation tunnel
*
*END*-----------------------------------------------------------------*/

void IPIP_delete
   (
      IPIP_PARM_PTR  parms
   )
{ /* Body */
   IPIP_CFG_STRUCT_PTR     cfg = RTCS_getcfg(IPIP);
   IPIP_TUNNEL_PTR         tunnel, _PTR_ search;

   if (!cfg) {
      RTCSCMD_complete(parms, RTCS_OK);
      return;
   } /* Endif */

   /* Find the tunnel information struct */
   RTCS_LIST_SEARCHMOD(cfg->NEXT, search) {
      parms->TUNNEL.NEXT = (*search)->NEXT;
      if (memcmp(*search, &parms->TUNNEL, sizeof(IPIP_TUNNEL)) == 0) {
         /* Found it */
         break;
      } /* Endif */
   } /* EndSEARCH */

   /* If it doesn't exist we are done */
   if (!*search) {
      RTCSCMD_complete(parms, RTCS_OK);
      return;
   } /* Endif */

   /* Remove the tunnel from the routing table */
   tunnel = *search;
   IP_route_remove_virtual(
      tunnel->INNER_DEST, tunnel->INNER_DEST_NETMASK,
      INADDR_ANY,
      tunnel->INNER_SOURCE, tunnel->INNER_SOURCE_NETMASK,
      cfg->IPIP_IF);

   cfg->TUNNELS--;

   *search = tunnel->NEXT;
   RTCS_part_free(tunnel);

   RTCSCMD_complete(parms, RTCS_OK);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIP_open
*  Returned Value : RTCS_OK
*  Comments       :
*        Registers the IP tunnel device as an IP interface.
*
*END*-----------------------------------------------------------------*/

uint_32 IPIP_open
   (
      /* [IN] the IP interface structure */
      IP_IF_PTR   if_ptr
   )
{ /* Body */

   if_ptr->MTU          = IP_MAX_MTU;
   if_ptr->ARP          = NULL;
   if_ptr->DEV_TYPE     = 0;
   if_ptr->DEV_ADDRLEN  = 0;

#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4
   if_ptr->SNMP_IF_TYPE = IPIFTYPE_TUNNEL;
#endif

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIP_close
*  Returned Value : RTCS_OK
*  Comments       :
*        Unregisters the IP tunnel device as an IP interface.
*
*END*-----------------------------------------------------------------*/

uint_32 IPIP_close
   (
      /* [IN] the IP interface structure */
      IP_IF_PTR   if_ptr
   )
{ /* Body */
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIP_send
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Tunnels a packet (IP over IP).
*
*END*-----------------------------------------------------------------*/

uint_32 IPIP_send
   (
      /* [IN] the IP interface structure */
      IP_IF_PTR         if_ptr,
      /* [IN] the packet to send */
      RTCSPCB_PTR       pcb,
      /* [IN] the next-hop source address */
      _ip_address       src,
      /* [IN] the next-hop destination address */
      _ip_address       dest,
      /* [IN] the data pointer in the routing table */
      pointer           dataptr
   )
{ /* Body */
   IP_HEADER_PTR           ip;
   _ip_address             orig_dest;
   IPIP_CFG_STRUCT_PTR     cfg = RTCS_getcfg(IPIP);
   IP_CFG_STRUCT_PTR       IP_cfg = RTCS_getcfg(IP);
   IPIP_TUNNEL_PTR         data = dataptr;

   ip = (IP_HEADER_PTR)RTCSPCB_DATA(pcb);
   orig_dest = IP_dest(pcb);

   /*
   ** IP over IP RFC requires routers to not tunnel forwarded datagrams when
   ** one of the following is true:
   **
   ** 1. The IP source address of the datagram matches the IP source address
   **    of the routers network interfaces, OR
   **
   ** 2. The IP source address of the datagram matches the IP destination
   **    address of the tunnel
   */
   if ((pcb->IFSRC != RTCS_IF_LOCALHOST_PRV && IP_is_local(NULL, src)) ||
       (src == data->OUTER_DEST))
   {
      RTCSLOG_PCB_FREE(pcb, RTCSERR_IPIP_LOOP);
      RTCSPCB_free(pcb);
      return RTCSERR_IPIP_LOOP;
   } /* Endif */

   pcb->IPIP_SOURCE = data->OUTER_SOURCE;
   pcb->IPIP_DEST = data->OUTER_DEST;

   if (!RTCSCMD_service(pcb, IPIP_send_internal)) {
      RTCSLOG_PCB_FREE(pcb, RTCSERR_OUT_OF_BUFFERS);
      RTCSPCB_free(pcb);
      return RTCSERR_OUT_OF_BUFFERS;
   } /* Endif */

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IPIP_send_internal
* Returned Values : void
* Comments        :
*     Sends an IP over IP packet.
*
*END*-----------------------------------------------------------------*/

void IPIP_send_internal
   (
      /* [IN] the packet to send */
      RTCSPCB_PTR      pcb
   )
{ /* Body */
   uint_32        proto = IPPROTO_IPIP;
   uint_32        flags = 0;
   IP_HEADER_PTR  ip    = (IP_HEADER_PTR)RTCSPCB_DATA(pcb);

   /* Copy the TOS of the inner header to the outer header */
   proto |= IPTOS(ntohc(ip->TOS));

   if (ntohl(ip->DEST) == pcb->IPIP_DEST) {
      flags |= IPROUTEOPT_NOVIRTUAL;
   } /* Endif */

   pcb->IP_SUM_PTR = NULL;

   IP_send(pcb, proto, pcb->IPIP_SOURCE, pcb->IPIP_DEST, flags);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIP_MTU
*  Returned Value : the MTU
*  Comments       :
*        Finds the MTU difference for a destination IP going through a tunnel.
*     Returns the final source and destination of the last encapsulation.
*
*END*-----------------------------------------------------------------*/

uint_32 IPIP_MTU
   (
      /* [IN] pointer to a IPIP_TUNNEL structure */
      pointer               data_ptr
   )
{ /* Body */
   IPIP_TUNNEL_PTR       tunnel = data_ptr;

   /*
   ** Recursively call IP_MTU. If there is a loop in the tunnels the stack will
   ** be blown, but the fault lies with the application
   */
   return IP_MTU(tunnel->OUTER_SOURCE, tunnel->OUTER_DEST) - sizeof(IP_HEADER);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IPIP && RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enet.h<|end_filename|>
#ifndef __enet_h__
#define __enet_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enet.h$
* $Version : 3.8.40.0$
* $Date    : Sep-20-2012$
*
* Comments:
*
*   This file contains the defines, externs and data
*   structure definitions required by application
*   programs in order to use the Ethernet packet driver.
*
*END************************************************************************/

#include <pcb.h>
#include <ethernet.h>

/*--------------------------------------------------------------------------*/
/*                        
**                            CONSTANT DEFINITIONS
*/

/* Error codes */

#define ENET_OK                     (0)
#define ENET_ERROR                  (ENET_ERROR_BASE | 0xff)  /* general ENET error */

#define ENETERR_INVALID_DEVICE      (ENET_ERROR_BASE | 0x00)   /* Device number out of range  */
#define ENETERR_INIT_DEVICE         (ENET_ERROR_BASE | 0x01)   /* Device already initialized  */
#define ENETERR_ALLOC_CFG           (ENET_ERROR_BASE | 0x02)   /* Alloc state failed          */
#define ENETERR_ALLOC_PCB           (ENET_ERROR_BASE | 0x03)   /* Alloc PCBs failed           */
#define ENETERR_ALLOC_BD            (ENET_ERROR_BASE | 0x04)   /* Alloc BDs failed            */
#define ENETERR_INSTALL_ISR         (ENET_ERROR_BASE | 0x05)   /* Install ISR failed          */
#define ENETERR_FREE_PCB            (ENET_ERROR_BASE | 0x06)   /* PCBs in use                 */
#define ENETERR_ALLOC_ECB           (ENET_ERROR_BASE | 0x07)   /* Alloc ECB failed            */
#define ENETERR_OPEN_PROT           (ENET_ERROR_BASE | 0x08)   /* Protocol not open           */
#define ENETERR_CLOSE_PROT          (ENET_ERROR_BASE | 0x09)   /* Protocol already open       */
#define ENETERR_SEND_SHORT          (ENET_ERROR_BASE | 0x0A)   /* Packet too short            */
#define ENETERR_SEND_LONG           (ENET_ERROR_BASE | 0x0B)   /* Packet too long             */
#define ENETERR_JOIN_MULTICAST      (ENET_ERROR_BASE | 0x0C)   /* Not a multicast address     */
#define ENETERR_ALLOC_MCB           (ENET_ERROR_BASE | 0x0D)   /* Alloc MCB failed            */
#define ENETERR_LEAVE_GROUP         (ENET_ERROR_BASE | 0x0E)   /* Not a joined group          */
#define ENETERR_SEND_FULL           (ENET_ERROR_BASE | 0x0F)   /* Transmit ring full          */
#define ENETERR_IP_TABLE_FULL       (ENET_ERROR_BASE | 0x10)   /* IP Table full of IP pairs   */
#define ENETERR_ALLOC               (ENET_ERROR_BASE | 0x11)   /* Generic alloc failed        */
#define ENETERR_INIT_FAILED         (ENET_ERROR_BASE | 0x12)   /* Device failed to initialize */
#define ENETERR_DEVICE_TIMEOUT      (ENET_ERROR_BASE | 0x13)   /* Device read/write timeout   */
#define ENETERR_ALLOC_BUFFERS       (ENET_ERROR_BASE | 0x14)   /* Buffer alloc failed         */
#define ENETERR_ALLOC_MAC_CONTEXT   (ENET_ERROR_BASE | 0x15)   /* Buffer alloc failed         */
#define ENETERR_NO_TX_BUFFER        (ENET_ERROR_BASE | 0x16)   /* TX Buffer alloc failed      */
#define ENETERR_INVALID_INIT_PARAM  (ENET_ERROR_BASE | 0x17)   /* Invalid init. parameter     */
#define ENETERR_DEVICE_IN_USE       (ENET_ERROR_BASE | 0x18)   /* Shutdown failed, dev. in use*/
#define ENETERR_INITIALIZED_DEVICE  (ENET_ERROR_BASE | 0x19)   /* Device already initialized  */
#define ENETERR_INPROGRESS          (ENET_ERROR_BASE | 0x1A)   /* In Wifi Device Setting of ESSID in progress*/
#define ENETERR_1588_LWEVENT        (ENET_ERROR_BASE | 0x1B)   /* 1588driver lwevent creation failed */
#define ENETERR_INVALID_MODE        (ENET_ERROR_BASE | 0x1C)   /* Invalid mode for this ethernet driver */
#define ENETERR_INVALID_OPTION      (ENET_ERROR_BASE | 0x1D)   /* Invalid option for this ethernet driver */

#define ENETERR_MIN                 (ENETERR_INVALID_DEVICE)
#define ENETERR_MAX                 (ENETERR_INVALID_OPTION)

/* Other constants */


/* MODES */
#define ENET_HALF_DUPLEX    0x1
#define ENET_FULL_DUPLEX    0x0
#define ENET_DUPLEX_MASK    0x1

#define ENET_10M            0x02
#define ENET_100M           0x04
#define ENET_1G             0x06
#define ENET_SPEED_MASK     0x0e

#define ENET_AUTONEGOTIATE  0x10

/* OPTIONS */
#define ENET_OPTION_MII             0x00000000
#define ENET_OPTION_VLAN            0x00000001
#define ENET_OPTION_PHY_DISCOVER    0x00000002
#define ENET_OPTION_MAC_LOOPBACK    0x00000004
#define ENET_OPTION_PHY_LOOPBACK    0x00000008
#define ENET_OPTION_NO_PREAMBLE     0x00000010
#define ENET_OPTION_RMII            0x00000020
#define ENET_OPTION_7WIRE           0x00000040
#define ENET_OPTION_STORE_AND_FORW  0x00000080
#define ENET_OPTION_PTP_MASTER_CLK  0x00000100
#define ENET_OPTION_PTP_INBAND      0x00000200

/* NOTE: Not all MAC drivers will support all modes and options. */

/* Media control definition types */
#define IO_TYPE_MEDIACTL_WIFI   0x00
#define IO_TYPE_MEDIACTL_PTP    0x10


#if BSPCFG_ENABLE_ENET_STATS

   #ifndef BSPCFG_ENABLE_ENET_HISTOGRAM
      #define BSPCFG_ENABLE_ENET_HISTOGRAM 1
   #endif
   
   #define ENET_INC_STATS(x)   { enet_ptr->STATS.x++; }
#define ENET_INC_STATS_IF(c,x)   { if (c) ENET_INC_STATS(x) }
#else
   #define ENET_INC_STATS(x)
#define ENET_INC_STATS_IF(c,x)   
#endif

#define ENET_HISTOGRAM_SHIFT       (6)
#define ENET_HISTOGRAM_ENTRIES     (((ENET_FRAMESIZE)>>ENET_HISTOGRAM_SHIFT)+1)


/*--------------------------------------------------------------------------*/
/*                        
**                            TYPE DEFINITIONS
*/

typedef pointer _enet_handle;
  
typedef enum {
  Half_Duplex_10M   = (ENET_HALF_DUPLEX | ENET_10M),
  Full_Duplex_10M   = (ENET_FULL_DUPLEX | ENET_10M),
  Half_Duplex_100M  = (ENET_HALF_DUPLEX | ENET_100M),
  Full_Duplex_100M  = (ENET_FULL_DUPLEX | ENET_100M),
  Half_Duplex_1G    = (ENET_HALF_DUPLEX | ENET_1G),
  Full_Duplex_1G    = (ENET_FULL_DUPLEX | ENET_1G),
  Auto_Negotiate    = ENET_AUTONEGOTIATE
} ENET_mode;
  
#if BSPCFG_ENABLE_ENET_STATS
typedef struct enet_commom_stats_struct {
   uint_32     ST_RX_TOTAL;         /* Total number of received packets    */
   uint_32     ST_RX_MISSED;        /* Number of missed packets            */
   uint_32     ST_RX_DISCARDED;     /* Discarded -- unrecognized protocol  */
   uint_32     ST_RX_ERRORS;        /* Discarded -- error during reception */

   uint_32     ST_TX_TOTAL;         /* Total number of transmitted packets */
   uint_32     ST_TX_MISSED;        /* Discarded -- transmit ring full     */
   uint_32     ST_TX_DISCARDED;     /* Discarded -- bad packet             */
   uint_32     ST_TX_ERRORS;        /* Error during transmission           */
} ENET_COMMON_STATS_STRUCT, _PTR_ ENET_COMMON_STATS_STRUCT_PTR;

typedef struct enet_stats {
   ENET_COMMON_STATS_STRUCT   COMMON;

   /* Following stats are physical errors/conditions */
   uint_32     ST_RX_ALIGN;         /* Frame Alignment error    */
   uint_32     ST_RX_FCS;           /* CRC error                */
   uint_32     ST_RX_RUNT;          /* Runt packet received     */
   uint_32     ST_RX_GIANT;         /* Giant packet received    */
   uint_32     ST_RX_LATECOLL;      /* Late collision           */
   uint_32     ST_RX_OVERRUN;       /* DMA overrun              */

   uint_32     ST_TX_SQE;           /* Heartbeat lost           */
   uint_32     ST_TX_DEFERRED;      /* Transmission deferred    */
   uint_32     ST_TX_LATECOLL;      /* Late collision           */
   uint_32     ST_TX_EXCESSCOLL;    /* Excessive collisions     */
   uint_32     ST_TX_CARRIER;       /* Carrier sense lost       */
   uint_32     ST_TX_UNDERRUN;      /* DMA underrun             */

   /* Following stats are collected by the ethernet driver  */
   uint_32     ST_RX_COPY_SMALL;     /* Driver had to copy packet */
   uint_32     ST_RX_COPY_LARGE;     /* Driver had to copy packet */
   uint_32     ST_TX_COPY_SMALL;     /* Driver had to copy packet */
   uint_32     ST_TX_COPY_LARGE;     /* Driver had to copy packet */

   uint_32     RX_FRAGS_EXCEEDED;
   uint_32     RX_PCBS_EXHAUSTED;
   uint_32     RX_LARGE_BUFFERS_EXHAUSTED;

   uint_32     TX_ALIGNED;
   uint_32     TX_ALL_ALIGNED;

#if BSPCFG_ENABLE_ENET_HISTOGRAM
   uint_32     RX_HISTOGRAM[ENET_HISTOGRAM_ENTRIES];  
   uint_32     TX_HISTOGRAM[ENET_HISTOGRAM_ENTRIES];  
#endif
  
} ENET_STATS, _PTR_ ENET_STATS_PTR;
#endif


/* forward declarations */
struct enet_mcb_struct;
struct enet_context_struct;
struct enet_param_struct;

typedef struct {
   uint_32 (_CODE_PTR_  INIT) (struct enet_context_struct *);
   uint_32 (_CODE_PTR_  STOP)(struct enet_context_struct *);
   uint_32 (_CODE_PTR_  SEND) (struct enet_context_struct *, PCB_PTR, uint_32, uint_32, uint_32);
   
   uint_32 (_CODE_PTR_  PHY_READ) (struct enet_context_struct *, uint_32, uint_32_ptr, uint_32);
   uint_32 (_CODE_PTR_  PHY_WRITE) (struct enet_context_struct *,  uint_32, uint_32, uint_32);

#if BSPCFG_ENABLE_ENET_MULTICAST
   uint_32 (_CODE_PTR_  JOIN) (struct enet_context_struct *, struct enet_mcb_struct *);
   uint_32 (_CODE_PTR_  REJOIN)(struct enet_context_struct *);
#endif
   uint_32 (_CODE_PTR_  MEDIACTL) (struct enet_context_struct *, uint_32 command_id, pointer inout_param);
} ENET_MAC_IF_STRUCT, * ENET_MAC_IF_STRUCT_PTR;


typedef struct enet_pyh_if_struct {
   boolean (_CODE_PTR_  DISCOVER) (struct enet_context_struct *);
   boolean (_CODE_PTR_  INIT) (struct enet_context_struct *);
   uint_32 (_CODE_PTR_  SPEED)(struct enet_context_struct *);
   boolean (_CODE_PTR_  STATUS) (struct enet_context_struct *);
   boolean (_CODE_PTR_  DUPLEX)(struct enet_context_struct *);
} ENET_PHY_IF_STRUCT, * ENET_PHY_IF_STRUCT_PTR;



typedef struct enet_if_struct {
   const ENET_MAC_IF_STRUCT *    MAC_IF;        /* pointer to MAC interface struct */
   const ENET_PHY_IF_STRUCT *    PHY_IF;        /* pointer to PHY interface struct */
   uchar                         MAC_NUMBER;    /* MAC device number */
   uchar                         PHY_NUMBER;    /* MAC device number for communication with PHY */
   uchar                         PHY_ADDRESS;   /* PHY address */
   uint_32                       PHY_MII_SPEED; /* PHY MII Speed (MDC - Management Data Clock) */
} ENET_IF_STRUCT, * ENET_IF_STRUCT_PTR;



typedef struct enet_param_struct {
   const ENET_IF_STRUCT         *ENET_IF;
   ENET_mode                     MODE;
   uint_32                       OPTIONS;
   
   uint_16                       NUM_TX_ENTRIES;
   uint_16                       NUM_TX_BUFFERS;
   uint_16                       TX_BUFFER_SIZE;

   uint_16                       NUM_RX_ENTRIES;
   uint_16                       NUM_RX_BUFFERS;
   uint_16                       RX_BUFFER_SIZE;
   uint_16                       NUM_RX_PCBS;
   
   uint_16                       NUM_SMALL_BUFFERS;
   uint_16                       NUM_LARGE_BUFFERS;
   pointer                       MAC_PARAM;
    
} ENET_PARAM_STRUCT, * ENET_PARAM_STRUCT_PTR;


/*
 *      Generic format for most parameters that fit in an int
 */
typedef struct  _param
{
   int_32          value;          /* The value of the parameter itself */
   uint_8          fixed;          /* Hardware should not use auto select */
   uint_8          disabled;       /* Disable the feature */
   uint_32         flags;          /* Various specifc flags (if any) */
   pointer         data;
   uint_32         length;
}ENET_MEDIACTL_PARAM,* ENET_MEDIACTL_PARAM_PTR;

/*--------------------------------------------------------------------------*/
/*                        
**                            PROTOTYPES AND GLOBAL EXTERNS
*/

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__

extern const ENET_PARAM_STRUCT ENET_default_params[];

extern uint_32        ENET_close(_enet_handle, uint_16);
extern uint_32        ENET_get_address(_enet_handle, _enet_address);
extern _mqx_uint      ENET_initialize(_mqx_uint, _enet_address, _mqx_uint,    _enet_handle _PTR_);
extern _mqx_uint      ENET_initialize_ex(const ENET_PARAM_STRUCT *,  _enet_address,  _enet_handle _PTR_);
extern uint_32        ENET_open(_enet_handle, uint_16, void (_CODE_PTR_)(PCB_PTR, pointer), pointer);
extern uint_32        ENET_send(_enet_handle, PCB_PTR, uint_16, _enet_address, uint_32);
extern uint_32        ENET_send_raw(_enet_handle, PCB_PTR);
extern uint_32        ENET_shutdown(_enet_handle);
extern const char * ENET_strerror(_mqx_uint);
extern uint_32        ENET_get_speed (_enet_handle);
extern uint_32        ENET_get_MTU(_enet_handle);
extern uint_32        ENET_get_mac_address(uint_32, uint_32,_enet_address);
extern boolean        ENET_link_status(_enet_handle);
extern boolean        ENET_read_mii(_enet_handle, uint_32, uint_32_ptr, uint_32);
extern boolean        ENET_write_mii(_enet_handle, uint_32, uint_32, uint_32);
extern uint_32        ENET_get_phy_addr(_enet_handle);
extern uint_32        ENET_mediactl(_enet_handle,uint_32,pointer);
extern boolean        ENET_phy_registers(_enet_handle,uint_32,uint_32_ptr);
extern _enet_handle   ENET_get_next_device_handle(_enet_handle handle);

#if BSPCFG_ENABLE_ENET_STATS
extern ENET_STATS_PTR ENET_get_stats(_enet_handle);
#endif

#if BSPCFG_ENABLE_ENET_MULTICAST
extern uint_32        ENET_join(_enet_handle, uint_16, _enet_address);
extern uint_32        ENET_leave(_enet_handle, uint_16, _enet_address);
#endif


#endif

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_esdhc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_esdhc.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the global settings for eSDHC driver.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"

const ESDHC_INIT_STRUCT _bsp_esdhc0_init = {
    0,                          /* ESDHC device number */ 
    25000000,                   /* ESDHC baudrate      */
    BSP_SYSTEM_CLOCK            /* ESDHC clock source  */ 
};


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/igmputil.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: igmputil.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the Internet
*   Group Management Protocol.  For more details, refer
*   to RFC1112 for version 1 and RFC2236 for version 2.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"

#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4

/*
** Warning: IGMP is OPTIONAL.  The functions below (most notably
**          IGMP_ipif_add, IGMP_ipif_bind, IGMP_ipif_unbind_nosock
**          and IGMP_is_member) may be called without a prior call
**          to IGMP_init.
*/

uint_32 IGMP_join_if_local      (IP_IF_PTR, ip_mreq _PTR_);
uint_32 IGMP_leave_if_local     (IP_IF_PTR, MC_MEMBER_PTR _PTR_);
uint_32 IGMP_ipif_unbind_nosock (IP_IF_PTR, _ip_address);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_filter_add
* Returned Values : uint_32
* Comments        :
*     add a IGMP_filter in the physical interface
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_filter_add
   (
      IP_IF_PTR   ipif,
      _ip_address group_ip
   )
{ /* Body */
   if (!ipif->DEVICE.JOIN) {
      return RTCS_OK;
   } /* Endif */

   /* join the group on the physical interface */
   return ipif->DEVICE.JOIN(ipif, group_ip);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_filter_rm
* Returned Values : uint_32
* Comments        :
*     remove a IGMP_filter in the physical interface
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_filter_rm
   (
      IP_IF_PTR   ipif,
      _ip_address group_ip
   )
{ /* Body */
   if (!ipif->DEVICE.LEAVE) {
      return RTCS_OK;
   } /* Endif */

   /* leave the group on the physical interface */
   return ipif->DEVICE.LEAVE(ipif, group_ip);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_member_find
* Returned Values : MC_MEMBER_PTR
* Comments        :
*     look for a given group through a list of joined group
*
*END*-----------------------------------------------------------------*/

MC_MEMBER_PTR _PTR_ IGMP_member_find
   (
      MC_MEMBER_PTR _PTR_  phead,
      ip_mreq _PTR_        igrp
   )
{ /* Body */

   for (; *phead ; phead = &(*phead)->NEXT) {
      if ((*phead)->IGRP.imr_multiaddr.s_addr == igrp->imr_multiaddr.s_addr
       && (*phead)->IGRP.imr_interface.s_addr == igrp->imr_interface.s_addr) {
         /* the group is already joined */
         return phead;
      } /* Endif */
   } /* Endfor */

   return NULL;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_member_create
* Returned Values : MC_MEMBER_PTR
* Comments        :
*     add a new group in a list
*
*END*-----------------------------------------------------------------*/

MC_MEMBER_PTR _PTR_ IGMP_member_create
   (
      MC_MEMBER_PTR _PTR_  phead,
      ip_mreq _PTR_        igrp
   )
{ /* Body */
   IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP);
   MC_MEMBER_PTR     group;

   group = RTCS_part_alloc_zero(IP_cfg_ptr->MCB_PARTID);
   if (!group) {
      return NULL;
   } /* Endif */
   group->IGRP = *igrp;
   group->UCOUNT = 1;
   group->NEXT = *phead;
   *phead = group;

   return phead;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_member_delete
* Returned Values : uint_32
* Comments        :
*     remove a group from a list
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_member_delete
   (
      MC_MEMBER_PTR _PTR_  pmember
   )
{ /* Body */
   MC_MEMBER_PTR  group;

   group = *pmember;
   *pmember = group->NEXT;
   RTCS_part_free(group);

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_join_if_local
* Returned Values : uint_32
* Comments        :
*     join a local group on a given interface
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_join_if_local
   (
      IP_IF_PTR      ipif, /* [IN] the interface descriptor */
      ip_mreq _PTR_  igrp  /* [IN] the group description */
   )
{ /* Body */
   MC_MEMBER_PTR _PTR_  pgroup;
   uint_32              status;

   /* join the group */
   pgroup = IGMP_member_create(&ipif->IGMP_MEMBER, igrp);
   if (!pgroup) {
      return RTCSERR_IGMP_GROUP_ALLOC;
   } /* Endif */

   /* join the group on the physical interface */
   status = IGMP_filter_add(ipif, igrp->imr_multiaddr.s_addr);
   if (status != RTCS_OK) {
      IGMP_member_delete(pgroup);
      return status;
   } /* Endif */

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_leave_if_local
* Returned Values : uint_32
* Comments        :
*     leave the group on a given interface
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_leave_if_local
   (
      IP_IF_PTR            ipif,    /* [IN] the interface descriptor */
      MC_MEMBER_PTR _PTR_  pmember  /* [IN] the group to leave */
   )
{ /* Body */
   uint_32  status, tmp;

   /* leave the group on the physical interface */
   status = IGMP_filter_rm(ipif, (*pmember)->IGRP.imr_multiaddr.s_addr);

   /* leave the group */
   tmp = IGMP_member_delete(pmember);
   if (tmp != RTCS_OK && status == RTCS_OK) {
      status = tmp;
   } /* Endif */

   return status;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_ipif_add
* Returned Values : error code
* Comments        :
*     init the IGMP part of a given interface. called by IPIF_add
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_ipif_add
   (
      IP_IF_PTR   ipif /* [IN] the interface descriptor */
   )
{ /* Body */
   ipif->IGMP_MEMBER = NULL;
   ipif->IGMP_UNBIND = IGMP_ipif_unbind_nosock;
#ifdef IGMP_V2
   ipif->IGMP_V1_ROUTER_FLAG = FALSE;
#endif
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_ipif_bind
* Returned Values : error code
* Comments        :
*     bind the IGMP part of a given interface. called by IPIF_bind
*     mainly for joining the ALL_HOSTS group.
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_ipif_bind
   (
      IP_IF_PTR   ipif,       /* [IN] the interface descriptor */
      _ip_address ip_address  /* [IN] the ip address of the interface */
   )
{ /* Body */
   ip_mreq  group;

   /* join the ALL_HOSTS group */
   group.imr_multiaddr.s_addr = INADDR_ALLHOSTS_GROUP;
   group.imr_interface.s_addr = ip_address;
   return IGMP_join_if_local(ipif, &group);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_ipif_unbind_nosock
* Returned Values : error code
* Comments        :
*     unbind a address to an interface. called by IPIF_unbind.
*     leave the groups still joined on this address/interface.
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_ipif_unbind_nosock
   (
      IP_IF_PTR   ipif,       /* [IN] the interface descriptor */
      _ip_address ip_address  /* [IN] the ip address of the interface */
   )
{ /* Body */
   MC_MEMBER_PTR _PTR_  pmember;
   uint_32              status, tmp;

   status = RTCS_OK;

   /* leave all joined groups */
   for (pmember = &ipif->IGMP_MEMBER; *pmember;) {
      if ((*pmember)->IGRP.imr_interface.s_addr != ip_address) {
         pmember = &(*pmember)->NEXT;
         continue;
      } /* Endif */
      tmp = IGMP_leave_if_local(ipif, pmember);
      if (tmp != RTCS_OK && status == RTCS_OK) {
         status = tmp;
      } /* Endif */
   } /* Endfor */

   return status;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_is_member
* Returned Values : boolean
* Comments        :
*     return TRUE if the socket is a member of a given group.
*
*END*-----------------------------------------------------------------*/

struct IGMP_is_member_test_struct {
   _ip_address          multiaddr;
   IP_IF_PTR            ipif;
   MC_MEMBER_PTR _PTR_  phead;
   boolean              result;
};

static boolean IGMP_is_member_test
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct IGMP_is_member_test_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                              route = node_data;
   IP_ROUTE_DIRECT_PTR                       search_ptr;
   ip_mreq                                   group;

   if (route && route->DIRECT) {
      search_ptr = route->DIRECT;
      group.imr_multiaddr.s_addr = testdata->multiaddr;

      do { /* Body */
         if (search_ptr->NETIF == testdata->ipif) {
            group.imr_interface.s_addr = search_ptr->ADDRESS;
            if (IGMP_member_find(testdata->phead, &group)) {
               testdata->result = TRUE;
               return TRUE;
            } /* Endif */
         } /* Endif */

         search_ptr = search_ptr->NEXT;
      } while(search_ptr != route->DIRECT);
   } /* Endif */

   return FALSE;
} /* Body */


boolean IGMP_is_member
   (
      MC_MEMBER_PTR _PTR_  phead,      /* [IN] head of MCB list */
      IP_IF_PTR            ipif,       /* [IN] the incoming interface */
      _ip_address          multiaddr   /* [IN] the multicast ip */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR                   IP_cfg_ptr = RTCS_getcfg(IP);
   struct IGMP_is_member_test_struct   testdata;

   if (!*phead) {
      return FALSE;
   } /* Endif */

   testdata.multiaddr   = multiaddr;
   testdata.ipif        = ipif;
   testdata.phead       = phead;
   testdata.result      = FALSE;

   /*
   ** Scan all directly connected networks, to have all the ip
   ** address of this interface
   */
   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, IGMP_is_member_test, &testdata);

   return testdata.result;

} /* Endbody */
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/include/ehci/ehci_dev_main.h<|end_filename|>
#ifndef __ehci_dev_main_h__
#define __ehci_dev_main_h__ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_dev_main.h$
* $Version : 3.8.7.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*  This file contains the defines, externs and
*  data structure definitions required by the VUSB_HS Device
*  driver.
*
*END*********************************************************************/

#include "devapi.h"
#include "usb_bsp.h"

/* should only define these macros if using HIGH SPEED device */
#define TRIP_WIRE                           (1) 
#define USB_OTG_UOCSR_BVLD                  (0x0040)


typedef  uint_32  VUSB_REGISTER;

/* usbhs specific defines */
#define  USBHS_MAX_PORTS                          (8)
#define  EHCI_CAP_LEN_MASK                        (0x000000FF)
#define  EHCI_DATA_STRUCTURE_BASE_ADDRESS         (0)

/* Command Register Bit Masks */
#define  EHCI_CMD_RUN_STOP                         (0x00000001)
#define  EHCI_CMD_CTRL_RESET                       (0x00000002)
#define  EHCI_CMD_SETUP_TRIPWIRE_SET               (0x00002000)
#define  EHCI_CMD_SETUP_TRIPWIRE_CLEAR             (~ EHCI_CMD_SETUP_TRIPWIRE_SET)

#define  EHCI_CMD_ATDTW_TRIPWIRE_SET               (0x00004000)// for DragonFire : (0x00001000); for RedStripe : (0x00004000)
#define  EHCI_CMD_ATDTW_TRIPWIRE_CLEAR             (~ EHCI_CMD_SETUP_TRIPWIRE_CLEAR)

/*bit 15,3,2 are for frame list size */
#define  EHCI_CMD_FRAME_SIZE_1024                  (0x00000000) /* 000 */
#define  EHCI_CMD_FRAME_SIZE_512                   (0x00000004) /* 001 */
#define  EHCI_CMD_FRAME_SIZE_256                   (0x00000008) /* 010 */
#define  EHCI_CMD_FRAME_SIZE_128                   (0x0000000C) /* 011 */
#define  EHCI_CMD_FRAME_SIZE_64                    (0x00008000) /* 100 */
#define  EHCI_CMD_FRAME_SIZE_32                    (0x00008004) /* 101 */
#define  EHCI_CMD_FRAME_SIZE_16                    (0x00008008) /* 110 */
#define  EHCI_CMD_FRAME_SIZE_8                     (0x0000800C) /* 111 */

/* Mode Register Bit Masks */
#define  USBHS_MODE_CTRL_MODE_IDLE                (0x00000000)
#define  USBHS_MODE_CTRL_MODE_DEV                 (0x00000002)
#define  USBHS_MODE_CTRL_MODE_HOST                (0x00000003)
#define  USBHS_MODE_BIG_ENDIAN                    (0x00000004)
#define  USBHS_MODE_SETUP_LOCK_DISABLE            (0x00000008)

/* Interrupt Enable Register Bit Masks */
#define  EHCI_INTR_INT_EN                          (0x00000001)
#define  EHCI_INTR_ERR_INT_EN                      (0x00000002)
#define  EHCI_INTR_PORT_CHANGE_DETECT_EN           (0x00000004)

#define  EHCI_INTR_ASYNC_ADV_AAE                   (0x00000020)
         #define  EHCI_INTR_ASYNC_ADV_AAE_ENABLE   (0x00000020) /* | with this to enable */
         #define  EHCI_INTR_ASYNC_ADV_AAE_DISABLE  (0xFFFFFFDF) /* & with this to disable */

#define  EHCI_INTR_RESET_EN                        (0x00000040)
#define  EHCI_INTR_SOF_UFRAME_EN                   (0x00000080)
#define  EHCI_INTR_DEVICE_SUSPEND                  (0x00000100)
#define  USB_INTR_ULPII_EN                         (0x00000400)
/* Interrupt Status Register Masks */
#define  EHCI_STS_SOF                              (0x00000080)
#define  EHCI_STS_RESET                            (0x00000040)
#define  EHCI_STS_PORT_CHANGE                      (0x00000004)
#define  EHCI_STS_ERR                              (0x00000002)
#define  EHCI_STS_INT                              (0x00000001)
#define  EHCI_STS_SUSPEND                          (0x00000100)
#define  EHCI_STS_HC_HALTED                        (0x00001000)
#define  USB_STS_ULPII                             (0x00000400)

/* Endpoint Queue Head Bit Masks */
#define  VUSB_EP_QUEUE_HEAD_IOS                    (0x00008000)
#define  VUSB_EP_QUEUE_HEAD_IOC                    (0x00008000)
#define  VUSB_EP_QUEUE_HEAD_INT                    (0x00000100)
#define  VUSB_EP_QUEUE_HEAD_NEXT_TERMINATE         (0x00000001)
#define  VUSB_EP_QUEUE_HEAD_MAX_PKT_LEN_POS        (16)
#define  VUSB_EP_QUEUE_HEAD_ZERO_LEN_TER_SEL       (0x20000000)
#define  VUSB_EP_QUEUE_HEAD_MULT_POS               (30)
#define  VUSB_EP_MAX_LENGTH_TRANSFER               (0x4000)

#define  VUSB_EP_QUEUE_HEAD_STATUS_ACTIVE          (0x00000080)

#define  USBHS_TD_NEXT_TERMINATE                  (0x00000001)
#define  USBHS_TD_IOC                             (0x00008000)
#define  USBHS_TD_STATUS_ACTIVE                   (0x00000080)
#define  USBHS_TD_STATUS_HALTED                   (0x00000040)
#define  USBHS_TD_RESERVED_FIELDS                 (0x00007F00)
#define  USBHS_TD_ERROR_MASK                      (0x68)
#define  USBHS_TD_ADDR_MASK                       (0xFFFFFFE0)
#define  USBHS_TD_LENGTH_BIT_POS                  (16)

#define  EHCI_EPCTRL_TX_DATA_TOGGLE_RST            (0x00400000)
#define  EHCI_EPCTRL_TX_EP_STALL                   (0x00010000)
#define  EHCI_EPCTRL_RX_EP_STALL                   (0x00000001)
#define  EHCI_EPCTRL_RX_DATA_TOGGLE_RST            (0x00000040)
#define  EHCI_EPCTRL_RX_ENABLE                     (0x00000080)
#define  EHCI_EPCTRL_TX_ENABLE                     (0x00800000)
#define  EHCI_EPCTRL_CONTROL                       (0x00000000)
#define  EHCI_EPCTRL_ISOCHRONOUS                   (0x00040000)
#define  EHCI_EPCTRL_BULK                          (0x00080000)
#define  EHCI_EPCTRL_INT                           (0x000C0000)
#define  EHCI_EPCTRL_TX_TYPE                       (0x000C0000)
#define  EHCI_EPCTRL_RX_TYPE                       (0x0000000C)
#define  EHCI_EPCTRL_DATA_TOGGLE_INHIBIT           (0x00000020)
#define  EHCI_EPCTRL_TX_EP_TYPE_SHIFT              (18)
#define  EHCI_EPCTRL_RX_EP_TYPE_SHIFT              (2)

#define  EHCI_PORTSCX_PORT_POWER                   (0x00001000)
#define  EHCI_PORTSCX_LINE_STATUS_BITS             (0x00000C00)
#define  EHCI_PORTSCX_LINE_STATUS_SE0              (0x00000000)
#define  EHCI_PORTSCX_LINE_STATUS_KSTATE           (0x00000400)
#define  EHCI_PORTSCX_LINE_STATUS_JSTATE           (0x00000800)
#define  EHCI_PORTSCX_PORT_HIGH_SPEED              (0x00000200)
#define  EHCI_PORTSCX_PORT_RESET                   (0x00000100)
#define  EHCI_PORTSCX_PORT_SUSPEND                 (0x00000080)
#define  EHCI_PORTSCX_PORT_FORCE_RESUME            (0x00000040)
#define  EHCI_PORTSCX_PORT_EN_DIS_CHANGE           (0x00000008)
#define  EHCI_PORTSCX_PORT_ENABLE                  (0x00000004)
#define  EHCI_PORTSCX_CONNECT_STATUS_CHANGE        (0x00000002)
#define  EHCI_PORTSCX_CURRENT_CONNECT_STATUS       (0x00000001)

#define  USBHS_PORTSCX_PORT_SPEED_FULL            (0x00000000)
#define  USBHS_PORTSCX_PORT_SPEED_LOW             (0x04000000)
#define  USBHS_PORTSCX_PORT_SPEED_HIGH            (0x08000000)
#define  USBHS_SPEED_MASK                         (0x0C000000)
#define  USBHS_SPEED_BIT_POS                      (26)

#define  EHCI_PORTSCX_W1C_BITS                     (0x2A)

#define  VUSB_EP_TR_PACKET_SIZE                    (0x7FFF0000)

#define  USBHS_FRINDEX_MS_MASK                    (0xFFFFFFF8)
#define  USBHS_ADDRESS_BIT_SHIFT                  (25)

#define  USBHS_MAX_ENDPTS_SUPPORTED               (0x1F)
#define  EHCI_HCC_PARAMS_64_BIT_ADDR_CAP           (0x01)
#define  EHCI_HCC_PARAMS_PGM_FRM_LIST_FLAG         (0x02)
#define  EHCI_HCC_PARAMS_ASYNC_PARK_CAP            (0x04)
#define  EHCI_HCC_PARAMS_ISOCH_SCHED_THRESHOLD     (0xF0)
#define  EHCI_HCC_PARAMS_ISOCH_FRAME_CACHED        (0x80)

#define  USBHS_HCS_PARAMS_PORT_POWER_CONTROL_FLAG (0x10)

#define  USBHS_HOST_INTR_EN_BITS                  (0x37)

#define  USBHS_DEFAULT_PERIODIC_FRAME_LIST_SIZE   (1024)
#define  USBHS_NEW_PERIODIC_FRAME_LIST_BITS       (2)
#define  EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT     (0x01)
#define  EHCI_ITD_T_BIT                            (0x01)
#define  EHCI_SITD_T_BIT                           (0x01)
#define  EHCI_QUEUE_HEAD_POINTER_T_BIT             (0x01)


/************************************************************
Split transatcions specific defines
************************************************************/
#define  EHCI_START_SPLIT_MAX_BUDGET               188

#define  EHCI_ELEMENT_TYPE_ITD                     (0x00)
#define  EHCI_ELEMENT_TYPE_QH                      (0x02)
#define  EHCI_ELEMENT_TYPE_SITD                    (0x04)
#define  EHCI_ELEMENT_TYPE_FSTN                    (0x06)
#define  EHCI_ELEMENT_TYPE_MASK                    (0x06)

#define  EHCI_FRAME_LIST_ELEMENT_TYPE_ITD          (0x00)
#define  EHCI_FRAME_LIST_ELEMENT_TYPE_QH           (0x01)
#define  EHCI_FRAME_LIST_ELEMENT_TYPE_SITD         (0x02)
#define  EHCI_FRAME_LIST_ELEMENT_TYPE_FSTN         (0x03)
#define  EHCI_FRAME_LIST_ELEMENT_TYPE_BIT_POS      (1)


#define  EHCI_QH_ELEMENT_TYPE_ITD                  (0x00)
#define  EHCI_QH_ELEMENT_TYPE_QH                   (0x01)
#define  EHCI_QH_ELEMENT_TYPE_SITD                 (0x02)
#define  EHCI_QH_ELEMENT_TYPE_FSTN                 (0x03)

#define  EHCI_QH_ELEMENT_TYPE_BIT_POS              (1)

#define  EHCI_QTD_PID_OUT_TOKEN                    (0x000)
#define  EHCI_QTD_PID_IN_TOKEN                     (0x100)
#define  EHCI_QTD_PID_SETUP_TOKEN                  (0x200)
#define  EHCI_QTD_IOC                              (0x8000)
#define  EHCI_QTD_STATUS_ACTIVE                    (0x0080)
#define  EHCI_QTD_STATUS_HALTED                    (0x0040)
#define  EHCI_QTD_PID_SETUP                        (0x0200)
#define  EHCI_QTD_PID_IN                           (0x0100)
#define  EHCI_QTD_PID_OUT                          (0x0000)
#define  EHCI_QTD_LENGTH_BIT_POS                   (16)
#define  EHCI_QTD_DATA_TOGGLE                      (0x80000000)
#define  EHCI_QTD_DATA_TOGGLE_BIT_POS              (31)
#define  EHCI_QTD_LENGTH_BIT_MASK                  (0x7FFF0000)
#define  EHCI_QTD_ERROR_BITS_MASK                  (0x0000003E)
#define  EHCI_QTD_DEFAULT_CERR_VALUE               (0xC00)

#define  EHCI_SETUP_TOKEN                          (2)
#define  EHCI_OUT_TOKEN                            (0)
#define  EHCI_IN_TOKEN                             (1)

#define  EHCI_QTD_T_BIT                            (0x01)

#define  EHCI_QH_ENDPOINT_SPEED_FULL               (0x00)
#define  EHCI_QH_ENDPOINT_SPEED_LOW                (0x01)
#define  EHCI_QH_ENDPOINT_SPEED_HIGH               (0x02)
#define  EHCI_QH_ENDPOINT_SPEED_RESERVED           (0x03)

#define  EHCI_ITD_LENGTH_BIT_POS                   (16)
#define  EHCI_ITD_IOC_BIT                          (0x00008000)
#define  EHCI_ITD_ACTIVE_BIT                       (0x80000000)
#define  EHCI_ITD_PG_SELECT_BIT_POS                (12)
#define  EHCI_ITD_DIRECTION_BIT_POS                (11)
#define  EHCI_ITD_EP_BIT_POS                       (8)
#define  EHCI_ITD_STATUS                           (0xF0000000)
        #define  EHCI_ITD_STATUS_ACTIVE            (0x80000000) /*bit 4 = 1000*/
        #define  EHCI_ITD_STATUS_DATA_BUFFER_ERR   (0x40000000) /*bit 3 = 0100*/
        #define  EHCI_ITD_STATUS_BABBLE_ERROR      (0x20000000) /*bit 2 = 0010*/
        #define  EHCI_ITD_STATUS_TRANSACTION_ERR   (0x10000000) /*bit 4 = 0001*/

#define  EHCI_ITD_LENGTH_TRANSMITTED               (0x0FFF0000)
#define  EHCI_ITD_BUFFER_OFFSET                    (0x00000FFF)
#define  EHCI_ITD_PAGE_NUMBER                      (0x00007000)
#define  EHCI_ITD_BUFFER_POINTER                   (0xFFFFF000)
#define  EHCI_ITD_MULTI_TRANSACTION_BITS           (0x00000003)



/* SITD position bits */
#define  EHCI_SITD_DIRECTION_BIT_POS                (31)
#define  EHCI_SITD_PORT_NUMBER_BIT_POS              (24)
#define  EHCI_SITD_HUB_ADDR_BIT_POS                 (16)
#define  EHCI_SITD_EP_ADDR_BIT_POS                  (8)

#define  EHCI_SITD_COMPLETE_SPLIT_MASK_BIT_POS      (8)

#define  EHCI_SITD_IOC_BIT_SET                      (0x80000000)
#define  EHCI_SITD_PAGE_SELECT_BIT_POS              (30)
#define  EHCI_SITD_TRANSFER_LENGTH_BIT_POS          (16)
#define  EHCI_SITD_STATUS_ACTIVE                    (0x80)

#define  EHCI_SITD_STATUS                           (0xFF)
#define  EHCI_SITD_LENGTH_TRANSMITTED               (0x03FF0000)
#define  EHCI_SITD_BUFFER_OFFSET                    (0x00000FFF)
#define  EHCI_SITD_PAGE_NUMBER                      (0x40000000)
#define  EHCI_SITD_BUFFER_POINTER                   (0xFFFFF000)



#define  EHCI_SITD_BUFFER_PTR_BIT_POS                 (12)
#define  EHCI_SITD_TP_BIT_POS                         (3)
    #define  EHCI_SITD_TP_ALL                         (0)
    #define  EHCI_SITD_TP_BEGIN                       (1)
    #define  EHCI_SITD_TP_MID                         (2)
    #define  EHCI_SITD_TP_END                         (3)



/* Interrupt enable bit masks */
#define  EHCI_IER_ASYNCH_ADVANCE                   (0x00000020)
#define  EHCI_IER_HOST_SYS_ERROR                   (0x00000010)
#define  EHCI_IER_FRAME_LIST_ROLLOVER              (0x00000008)
#define  EHCI_IER_PORT_CHANGE                      (0x00000004)
#define  EHCI_IER_USB_ERROR                        (0x00000002)
#define  EHCI_IER_USB_INTERRUPT                    (0x00000001)

/* Interrupt status bit masks */
#define  EHCI_STS_RECLAIMATION                     (0x00002000)
#define  EHCI_STS_SOF_COUNT                        (0x00000080)
#define  EHCI_STS_ASYNCH_ADVANCE                   (0x00000020)
#define  EHCI_STS_HOST_SYS_ERROR                   (0x00000010)
#define  EHCI_STS_FRAME_LIST_ROLLOVER              (0x00000008)
#define  EHCI_STS_PORT_CHANGE                      (0x00000004)
#define  EHCI_STS_USB_ERROR                        (0x00000002)
#define  EHCI_STS_USB_INTERRUPT                    (0x00000001)

/* Status bit masks */
#define  EHCI_STS_ASYNCH_SCHEDULE                  (0x00008000)
#define  EHCI_STS_PERIODIC_SCHEDULE                (0x00004000)
#define  EHCI_STS_RECLAMATION                      (0x00002000)
#define  EHCI_STS_HC_HALTED                        (0x00001000)

/* USB command bit masks */
#define  EHCI_USBCMD_ASYNC_SCHED_ENABLE            (0x00000020)
#define  EHCI_USBCMD_PERIODIC_SCHED_ENABLE         (0x00000010)

#define  EHCI_HCS_PARAMS_N_PORTS                   (0x0F)

#define  VUSB_HS_DELAY                             (3500)

#define  EHCI_QH_EP_NUM_MASK                       (0x0F00)
#define  EHCI_QH_EP_NUM_BITS_POS                   (8)
#define  EHCI_QH_DEVICE_ADDRESS_MASK               (0x7F)
#define  EHCI_QH_SPEED_BITS_POS                    (12)
#define  EHCI_QH_MAX_PKT_SIZE_BITS_POS             (16)
#define  EHCI_QH_NAK_COUNT_RL_BITS_POS             (28)
#define  EHCI_QH_EP_CTRL_FLAG_BIT_POS              (27)
#define  EHCI_QH_HEAD_RECLAMATION_BIT_POS          (15)
#define  EHCI_QH_DTC_BIT_POS                       (14)
#define  EHCI_QH_HIGH_BW_MULT_BIT_POS              (30)
#define  EHCI_QH_HUB_PORT_NUM_BITS_POS             (23)
#define  EHCI_QH_HUB_ADDR_BITS_POS                 (16)
#define  EHCI_QH_SPLIT_COMPLETION_MASK_BITS_POS    (8)
#define  EHCI_QH_SPLIT_COMPLETION_MASK             (0xFF00)
#define  EHCI_QH_INTR_SCHED_MASK                   (0xFF)
#define  EHCI_QH_INACTIVATE_NEXT_TR_BIT_POS        (7)
#define  EHCI_QH_HORIZ_PHY_ADDRESS_MASK            (0xFFFFFFE0)
#define  EHCI_QH_TR_OVERLAY_DT_BIT                 (0x80000000)

#define  EHCI_SITD_SPLIT_COMPLETION_MASK_BITS_POS  (8)

#define  EHCI_INTR_NO_THRESHOLD_IMMEDIATE          (0x00010000)
#define  EHCI_NEW_PERIODIC_FRAME_LIST_SIZE         (1024)
#define  EHCI_FRAME_LIST_SIZE_BITS_POS             (2)
#define  EHCI_HORIZ_PHY_ADDRESS_MASK              (0xFFFFFFE0)

#define  DEFAULT_MAX_NAK_COUNT                     (15)

/* OTG Status and control register bit masks */

/* OTG interrupt enable bit masks */
#define  USBHS_OTGSC_INTERRUPT_ENABLE_BITS_MASK   (0x5F000000)
#define  USBHS_OTGSC_DPIE                         (0x40000000)   /* Data-line pulsing IE */
#define  USBHS_OTGSC_1MSIE                        (0x20000000)
#define  USBHS_OTGSC_BSEIE                        (0x10000000)   /* B-session end IE */
#define  USBHS_OTGSC_BSVIE                        (0x08000000)   /* B-session valid IE */
#define  USBHS_OTGSC_ASVIE                        (0x04000000)   /* A-session valid IE */
#define  USBHS_OTGSC_AVVIE                        (0x02000000)   /* A-V-bus valid IE */
#define  USBHS_OTGSC_IDIE                         (0x01000000)   /* OTG ID IE */

/* OTG interrupt status bit masks */
#define  USBHS_OTGSC_INTERRUPT_STATUS_BITS_MASK   (0x005F0000)
#define  USBHS_OTGSC_DPIS                         (0x00400000)   /* Data-line pulsing IS */
#define  USBHS_OTGSC_1MSIS                        (0x00200000)
#define  USBHS_OTGSC_BSEIS                        (0x00100000)   /* B-session end IS */
#define  USBHS_OTGSC_BSVIS                        (0x00080000)   /* B-session valid IS */
#define  USBHS_OTGSC_ASVIS                        (0x00040000)   /* A-session valid IS */
#define  USBHS_OTGSC_AVVIS                        (0x00020000)   /* A-Vbus valid IS */
#define  USBHS_OTGSC_IDIS                         (0x00010000)   /* OTG ID IS */

/* OTG status bit masks */
#define  USBHS_OTGSC_DPS                          (0x00004000)
#define  USBHS_OTGSC_BSE                          (0x00001000)   /* B-session end */
#define  USBHS_OTGSC_BSV                          (0x00000800)   /* B-session valid */
#define  USBHS_OTGSC_ASV                          (0x00000400)   /* A-session valid */
#define  USBHS_OTGSC_AVV                          (0x00000200)   /* A-Vbus Valid */
#define  USBHS_OTGSC_ID                           (0x00000100)   /* OTG ID */

/* OTG control bit masks */
#define  USBHS_OTGSC_CTL_BITS                     (0x2F)
#define  USBHS_OTGSC_B_HOST_EN                    (0x00000020)   /* B_host_enable */
#define  USBHS_OTGSC_DP                           (0x00000010)   /* Data-pulsing */
#define  USBHS_OTGSC_OT                           (0x00000008)   /* OTG termination */
#define  USBHS_OTGSC_VO                           (0x00000004)   /* Vbus on */
#define  USBHS_OTGSC_VC                           (0x00000002)   /* Vbus charge */
#define  USBHS_OTGSC_VD                           (0x00000001)   /* Vbus discharge */


#if USBCFG_REGISTER_ENDIANNESS==MQX_BIG_ENDIAN
   #define ehci_reg_read(r,n)           LONG_BE_TO_HOST((uint_32)r)
   #define ehci_reg_write(r,v,n)       {r=HOST_TO_BE_LONG(v);_PSP_SYNC();}
#else
   #define ehci_reg_read(r,n)           LONG_LE_TO_HOST((uint_32)r)
   #define ehci_reg_write(r,v,n)       {r=HOST_TO_LE_LONG(v);_PSP_SYNC();}
#endif

#if USBCFG_MEMORY_ENDIANNESS==MQX_BIG_ENDIAN
   #define ehci_mem_read(r,n)           LONG_BE_TO_HOST((uint_32)r)
   #define ehci_mem_write(r,v,n)       {r=HOST_TO_BE_LONG(v);_PSP_SYNC();}
#else
   #define ehci_mem_read(r,n)           LONG_LE_TO_HOST((uint_32)r)
   #define ehci_mem_write(r,v,n)       {r=HOST_TO_LE_LONG(v);_PSP_SYNC();}
#endif

#define ehci_reg_clear_bits(r,v,n)  ehci_reg_write(r, ehci_reg_read(r,n) & ~v,n)
#define ehci_reg_set_bits(r,v,n)    ehci_reg_write(r, ehci_reg_read(r,n) | v,n)
#define ehci_mem_clear_bits(r,v,n)  ehci_mem_write(r, ehci_mem_read(r,n) & ~v,n)
#define ehci_mem_set_bits(r,v,n)    ehci_mem_write(r, ehci_mem_read(r,n) | v,n)

#define EHCI_REG_READ(r)            ehci_reg_read(r,#r)
#define EHCI_REG_WRITE(r,v)         ehci_reg_write(r,v,#r)
#define EHCI_REG_CLEAR_BITS(r,v)    ehci_reg_clear_bits(r,v,#r)
#define EHCI_REG_SET_BITS(r,v)      ehci_reg_set_bits(r,v,#r)

#define EHCI_MEM_READ(r)            ehci_mem_read(r,#r)
#define EHCI_MEM_WRITE(r,v)         ehci_mem_write(r,v,#r)
#define EHCI_MEM_CLEAR_BITS(r,v)    ehci_mem_clear_bits(r,v,#r)
#define EHCI_MEM_SET_BITS(r,v)      ehci_mem_set_bits(r,v,#r)



typedef  volatile uint_32  USB_REGISTER, _PTR_ USB_REGISTER_PTR;

/* The VUSB register structure */
typedef volatile struct {
   union  {
      struct  {
         USB_REGISTER   CAPLENGTH_HCIVER;
         USB_REGISTER   HCS_PARAMS;       /* HC structural parameters */
         USB_REGISTER   HCC_PARAMS;       /* HC Capability Parameters*/
         USB_REGISTER   RESERVED1[5];
         USB_REGISTER   DCI_VERSION;      /* DC version number and reserved 16 bits */
         USB_REGISTER   DCC_PARAMS;       /* DC Capability Parameters */
      } CAPABILITY_REGISTERS;

      struct  {
         USB_REGISTER   USB_CMD;                   /* Command register */
         USB_REGISTER   USB_STS;                   /* Status register */
         USB_REGISTER   USB_INTR;                  /* Interrupt enable */
         USB_REGISTER   USB_FRINDEX;               /* Frame index */
         USB_REGISTER   CTRLDSSEGMENT;             /* 4G segment selector */
         USB_REGISTER   DEVICE_ADDR;               /* Device Address */
         USB_REGISTER   EP_LIST_ADDR;              /* Endpoint List Address */
         USB_REGISTER   RESERVED0[9];
         USB_REGISTER   CONFIG_FLAG;               /* Configured Flag register */
         USB_REGISTER   PORTSCX[USBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */
         USB_REGISTER   OTGSC;
         USB_REGISTER   USB_MODE;                  /* USB Host/Device mode */
         USB_REGISTER   ENDPT_SETUP_STAT;          /* Endpoint Setup Status */
         USB_REGISTER   ENDPTPRIME;                /* Endpoint Initialize */
         USB_REGISTER   ENDPTFLUSH;                /* Endpoint De-initialize */
         USB_REGISTER   ENDPTSTATUS;               /* Endpoint Status */
         USB_REGISTER   ENDPTCOMPLETE;             /* Endpoint Interrupt On Complete */
         USB_REGISTER   ENDPTCTRLX[16];            /* Endpoint Control, where x = 0.. 15 */
      } OPERATIONAL_DEVICE_REGISTERS;

      struct  {
         USB_REGISTER   USB_CMD;                   /* Command register */
         USB_REGISTER   USB_STS;                   /* Status register */
         USB_REGISTER   USB_INTR;                  /* Interrupt enable */
         USB_REGISTER   USB_FRINDEX;               /* Frame index */
         USB_REGISTER   CTRLDSSEGMENT;             /* 4G segment selector */
         USB_REGISTER   PERIODIC_LIST_BASE_ADDR;   /* Periodic schedule list */
         USB_REGISTER   CURR_ASYNC_LIST_ADDR;      /* Current Asynch schedule list */
         USB_REGISTER   ASYNCTTSTS;                /* Async buffer in embedded TT control */
         USB_REGISTER   RESERVED0[8];
         USB_REGISTER   CONFIG_FLAG;               /* Configured Flag register */
         USB_REGISTER   PORTSCX[USBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */
         USB_REGISTER   OTGSC;                     /* OTG status and control register */
         USB_REGISTER   USB_MODE;                  /* USB Host/Device mode */
      } OPERATIONAL_HOST_REGISTERS;
   } REGISTERS;
} USBHS_REG_STRUCT, _PTR_ USBHS_REG_STRUCT_PTR;

typedef volatile struct {
   uint_32   MAX_PKT_LENGTH;      /* Bits 16..26 Bit 15 is Interrupt
                                          ** On Setup
                                          */
   uint_32   CURR_DTD_PTR;        /* Current dTD Pointer - not used */
   uint_32   NEXT_DTD_PTR;        /* Next dTD Pointer */
   uint_32   SIZE_IOC_INT_STS;    /* Total bytes (16..30), IOC (15),
                                          ** INT (8), STS (0-7)
                                          */
   uint_32   BUFF_PTR0;           /* Buffer pointer Page 0 (12-31) */
   uint_32   BUFF_PTR1;           /* Buffer pointer Page 1 (12-31) */
   uint_32   BUFF_PTR2;           /* Buffer pointer Page 2 (12-31) */
   uint_32   BUFF_PTR3;           /* Buffer pointer Page 3 (12-31) */
   uint_32   BUFF_PTR4;           /* Buffer pointer Page 4 (12-31) */
   uint_32   RESERVED1;
   uchar     SETUP_BUFFER[8];     /* 8 bytes of setup data that follows
                                  ** the Setup PID
                                  */
   uint_32   RESERVED2[4];
} USBHS_EP_QUEUE_HEAD_STRUCT, _PTR_ USBHS_EP_QUEUE_HEAD_STRUCT_PTR;


typedef volatile struct ep_tr_struct {
   uint_32      NEXT_TR_ELEM_PTR; /* Memory address of next
                                          ** dTD to be processed (5-31)
                                          ** and the T (bit 0) indicating
                                          ** pointer validity
                                          */
   uint_32      SIZE_IOC_STS;     /* total bytes (16-30),
                                          ** IOC (15), Status (0-7)
                                          */
   uint_32      BUFF_PTR0;        /* Buffer pointer Page 0 */
   uint_32      BUFF_PTR1;        /* Buffer pointer Page 1 */
   uint_32      BUFF_PTR2;        /* Buffer pointer Page 2 */
   uint_32      BUFF_PTR3;        /* Buffer pointer Page 3 */
   uint_32      BUFF_PTR4;        /* Buffer pointer Page 4 */
   SCRATCH_STRUCT_PTR   SCRATCH_PTR;
} USBHS_EP_TR_STRUCT, _PTR_ USBHS_EP_TR_STRUCT_PTR;

void _usb_dci_usbhs_free_dTD(_usb_device_handle, pointer);
uint_8 _usb_dci_usbhs_add_dTD(_usb_device_handle, XD_STRUCT_PTR);
void _usb_dci_usbhs_process_tr_complete(_usb_device_handle);
void _usb_dci_usbhs_process_reset(_usb_device_handle);
void _usb_dci_usbhs_process_tr_complete(_usb_device_handle);
void _usb_dci_usbhs_process_suspend(_usb_device_handle);
void _usb_dci_usbhs_process_SOF(_usb_device_handle);
void _usb_dci_usbhs_process_port_change(_usb_device_handle);
void _usb_dci_usbhs_process_error(_usb_device_handle);
USB_STATUS _usb_dci_usbhs_set_test_mode(_usb_device_handle, uint_16);
void _usb_dci_usbhs_chip_initialize(_usb_device_handle);


USB_STATUS _usb_dci_usbhs_preinit(_usb_device_handle _PTR_);
USB_STATUS _usb_dci_usbhs_init(_usb_device_handle);
USB_STATUS _usb_dci_usbhs_send_data(_usb_device_handle, XD_STRUCT_PTR);
USB_STATUS _usb_dci_usbhs_recv_data(_usb_device_handle, XD_STRUCT_PTR);
USB_STATUS _usb_dci_usbhs_cancel_transfer(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_dci_usbhs_set_address(_usb_device_handle, uint_8);
USB_STATUS _usb_dci_usbhs_shutdown(_usb_device_handle);
USB_STATUS _usb_dci_usbhs_get_setup_data(_usb_device_handle, uint_8, uint_8_ptr);
USB_STATUS _usb_dci_usbhs_assert_resume(_usb_device_handle);
USB_STATUS _usb_dci_usbhs_init_endpoint(_usb_device_handle, XD_STRUCT_PTR);
USB_STATUS _usb_dci_usbhs_stall_endpoint(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_dci_usbhs_unstall_endpoint(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_dci_usbhs_deinit_endpoint(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_dci_usbhs_get_endpoint_status(_usb_device_handle, uint_8, uint_16_ptr);
USB_STATUS _usb_dci_usbhs_set_endpoint_status(_usb_device_handle, uint_8, uint_16);
USB_STATUS _usb_dci_usbhs_get_transfer_status(_usb_device_handle, uint_8, uint_8);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/msg.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: msg.c$
 * $Version : 3.8.2.0$
 * $Date    : Jun-25-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Message component.
 *
 *END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_MESSAGES
#include "message.h"
#include "msg_prv.h"

/*!
 * \brief Allocates a message from the private message pool.
 * 
 * The size of the message is determined by the message size that a task 
 * specified when it called _msgpool_create(). The message is a resource of the 
 * task until the task either frees it (_msg_free()) or puts it on a message 
 * queue (_msgq_send() family of functions.)
 * 
 * \param[in] pool A pool ID from _msgpool_create().
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)
 *  
 * \warning On failure, calls _task_set_error() to set one the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGPOOL_INVALID_POOL_ID (Pool_id is not valid.)
 * \li MSGPOOL_OUT_OF_MESSAGES (All the messages in the pool are allocated.)
 * \li Task error codes from _mem_alloc_system() (If MQX needs to grow the pool.)
 * 
 * \see _msg_alloc_system
 * \see _msg_free
 * \see _msgpool_create
 * \see _msgpool_destroy
 * \see _task_set_error
 * \see _mem_alloc
 * \see _mem_alloc_from
 * \see _mem_alloc_system
 * \see _mem_alloc_system_from
 * \see _mem_alloc_system_zero
 * \see _mem_alloc_system_zero_from
 * \see _mem_alloc_zero
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align
 * \see _mem_alloc_align_from
 * \see _mem_alloc_at
 * \see MESSAGE_HEADER_STRUCT     
 */ 
pointer _msg_alloc
(
    _pool_id pool
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
#if MQX_CHECK_ERRORS
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
#endif
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;
    uint_16                              grow_number;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msg_alloc, pool);

#if MQX_CHECK_ERRORS
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msg_alloc, NULL, MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
#endif

    message_ptr = NULL;
    msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool;

#if MQX_CHECK_VALIDITY || MQX_CHECK_ERRORS
    if (
#if MQX_CHECK_VALIDITY
                    (msgpool_ptr->VALID != MSG_VALID)
#if MQX_CHECK_ERRORS
                    ||
#endif
#endif
#if MQX_CHECK_ERRORS
                    (msgpool_ptr->MSGPOOL_TYPE != MSG_POOL)
#endif
    )
    {
        _task_set_error(MSGPOOL_INVALID_POOL_ID);
        _KLOGX3(KLOG_msg_alloc, message_ptr, MSGPOOL_INVALID_POOL_ID);
        return (message_ptr);
    } /* Endif */
#endif

    if ( (msgpool_ptr->SIZE == 0) && (msgpool_ptr->GROW_NUMBER) &&
                    ( (msgpool_ptr->MAX < msgpool_ptr->GROW_LIMIT) ||
                                    (msgpool_ptr->GROW_LIMIT == 0) ) )
    {
        /* Attempt to add elements to the pool */
        grow_number = msgpool_ptr->GROW_NUMBER;
        if (grow_number > (uint_16)(msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX))
        {
            grow_number = msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX;
        } /* Endif */
        _msgpool_add_internal(msgpool_ptr, grow_number);
    } /* Endif */

    _INT_DISABLE();
    imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
    if (imsg_ptr == NULL)
    {
        _int_enable();
        _task_set_error(MSGPOOL_OUT_OF_MESSAGES);
        _KLOGX3(KLOG_msg_alloc, message_ptr, MSGPOOL_OUT_OF_MESSAGES);
        return((pointer)message_ptr);
    } /* Endif */

    msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr->NEXT;
    --msgpool_ptr->SIZE;
    _INT_ENABLE();
    imsg_ptr->FREE = FALSE;
    imsg_ptr->QUEUED = FALSE;
    if (kernel_data->IN_ISR)
    {
        imsg_ptr->TD_PTR = NULL;
    }
    else
    {
        imsg_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
    } /* Endif */
    message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;
    message_ptr->TARGET_QID = MSGQ_NULL_QUEUE_ID;
    message_ptr->SOURCE_QID = MSGQ_NULL_QUEUE_ID;
    message_ptr->SIZE = msgpool_ptr->MESSAGE_SIZE;
    message_ptr->CONTROL = MSG_HDR_ENDIAN | MSG_DATA_ENDIAN;
    _KLOGX3(KLOG_msg_alloc, message_ptr, MQX_OK);
    return (pointer)message_ptr;

} /* Endbody */

/*!
 * \brief Creates the message component.
 * 
 * The function uses fields in the MQX initialization structure to create the 
 * number of message pools (MAX_MSGPOOLS) and message queues (MAX_MSGQS). MQX 
 * creates the message component if it is not created when an application calls 
 * one of:
 * \li _msgpool_create()
 * \li _msgpool_create_system()
 * \li _msgq_open()
 * \li _msgq_open_system()
 * 
 * \return MQX_OK
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * \return MSGPOOL_POOL_NOT_CREATED (MQX cannot allocate the data structures for 
 * message pools.)
 * \return MSGQ_TOO_MANY_QUEUES (MQX cannot allocate the data structures for 
 * message queues.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.) 
 * \return MQX_INVALID_LWSEM (Sem_ptr is for a lightweight semaphore that is not 
 * longer valid.)
 * \return MQX_LWSEM_WAIT_TIMEOUT (Timeout expired before the task could get the 
 * lightweight semaphore.)       
 */ 
_mqx_uint _msg_create_component(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR            kernel_data;
    register MSG_COMPONENT_STRUCT_PTR msg_component_ptr;
    pointer                           pools_ptr;
    pointer                           msgqs_ptr;
    _mqx_uint                         error;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE1(KLOG_msg_create_component);

    error = _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);
#if MQX_CHECK_ERRORS
    if (error != MQX_OK)
    {
        _KLOGX2(KLOG_msg_create_component, error);
        return(error);
    } /* Endif */
#endif

    if (kernel_data->KERNEL_COMPONENTS[KERNEL_MESSAGES] != NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);
        _KLOGX2(KLOG_msg_create_component, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    msg_component_ptr = (MSG_COMPONENT_STRUCT_PTR)
    _mem_alloc_system_zero((_mem_size)sizeof(MSG_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (msg_component_ptr == NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);
        _KLOGX2(KLOG_msg_create_component, MQX_OUT_OF_MEMORY);
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(msg_component_ptr, MEM_TYPE_MESSAGE_COMPONENT);

    if (kernel_data->INIT.MAX_MSGPOOLS == 0)
    {
        kernel_data->INIT.MAX_MSGPOOLS = 1;
    } /* Endif */
    pools_ptr = _mem_alloc_system_zero((_mem_size)(kernel_data->INIT.MAX_MSGPOOLS *
                                    sizeof(MSGPOOL_STRUCT)));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (pools_ptr == NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);
        _KLOGX2(KLOG_msg_create_component, MSGPOOL_POOL_NOT_CREATED);
        return MSGPOOL_POOL_NOT_CREATED;
    }/* Endif */
#endif
    _mem_set_type(pools_ptr, MEM_TYPE_MESSAGE_POOLS);

    if (kernel_data->INIT.MAX_MSGQS >= MAX_UINT_16)
    {
        kernel_data->INIT.MAX_MSGQS = MAX_UINT_16 - 1;
    }
    else if (kernel_data->INIT.MAX_MSGQS < 1)
    {
        kernel_data->INIT.MAX_MSGQS = 1;
    } /* Endif */
    msgqs_ptr = _mem_alloc_system_zero( (_mem_size)((kernel_data->INIT.MAX_MSGQS + 1) *
                                    sizeof(MSGQ_STRUCT)));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (msgqs_ptr == NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);
        _mem_free(pools_ptr);
        _KLOGX2(KLOG_msg_create_component, MSGQ_TOO_MANY_QUEUES);
        return MSGQ_TOO_MANY_QUEUES;
    } /* Endif */
#endif
    _mem_set_type(msgqs_ptr, MEM_TYPE_MESSAGE_QUEUES);

    if (msg_component_ptr->MSGPOOLS_PTR == NULL)
    {
        msg_component_ptr->MAX_MSGPOOLS_EVER = 0;
        msg_component_ptr->SMALLEST_MSGPOOL_PTR = NULL;
        msg_component_ptr->LARGEST_MSGPOOL_PTR = NULL;
        msg_component_ptr->MAX_MSGPOOLS = kernel_data->INIT.MAX_MSGPOOLS;
        msg_component_ptr->MAX_MSGQS = kernel_data->INIT.MAX_MSGQS;
        msg_component_ptr->MSGPOOLS_PTR = (MSGPOOL_STRUCT_PTR)pools_ptr;
        pools_ptr = NULL;
        msg_component_ptr->MSGQS_PTR = (MSGQ_STRUCT_PTR)msgqs_ptr;
        msgqs_ptr = NULL;
    }/* Endif */

    msg_component_ptr->VALID = MESSAGE_VALID;

    kernel_data->KERNEL_COMPONENTS[KERNEL_MESSAGES] = msg_component_ptr;

#if MQX_COMPONENT_DESTRUCTION
    kernel_data->COMPONENT_CLEANUP[KERNEL_MESSAGES] = _msg_cleanup;
#endif

    _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM);

    if (pools_ptr)
    {
        _mem_free(pools_ptr);
    }/* Endif */
    if (msgqs_ptr)
    {
        _mem_free(msgqs_ptr);
    }/* Endif */

    _KLOGX2(KLOG_msg_create_component, MQX_OK);
    return MQX_OK;

} /* Endbody */

/*!
 * \brief Marks the message as "free".
 * 
 * Only the task that has the message as its resource can free the message. A 
 * message becomes a task's resource when the task allocates the message, and it 
 * continues to be a resource until the task either frees it or puts it in a 
 * message queue. A message becomes a resource of the task that got it from a 
 * message queue.
 * \n The function returns the message to the message pool from which it was 
 * allocated.
 * 
 * \param[in] msg_ptr Pointer to a message struct which is to be freed.
 * 
 * \warning On failure, calls _task_set_error() to set one the following task 
 * error codes:
 * \li MQX_INVALID_POINTER (Msg_ptr does not point to a valid message.)
 * \li MQX_NOT_RESOURCE_OWNER (Message is already freed.)
 * \li MSGQ_MESSAGE_IS_QUEUED (Message is in a queue.)
 * 
 * \see _msgpool_create
 * \see _msgpool_create_system
 * \see _msgpool_destroy
 * \see _msg_alloc_system
 * \see _msg_alloc
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT    
 */ 
void _msg_free
(
    pointer msg_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_msg_free, msg_ptr);

    imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);
#if MQX_CHECK_VALIDITY
    if ( imsg_ptr->VALID != MSG_VALID )
    {
        _KLOGX2(KLOG_msg_free, MQX_INVALID_POINTER);
        _task_set_error(MQX_INVALID_POINTER);
        return;
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (imsg_ptr->FREE)
    {
        _KLOGX2(KLOG_msg_free, MQX_NOT_RESOURCE_OWNER);
        _task_set_error(MQX_NOT_RESOURCE_OWNER);
        return;
    } /* Endif */
    if (imsg_ptr->QUEUED)
    {
        _KLOGX2(KLOG_msg_free, MSGQ_MESSAGE_IS_QUEUED);
        _task_set_error(MSGQ_MESSAGE_IS_QUEUED);
        return;
    } /* Endif */
#endif

    msgpool_ptr = imsg_ptr->MSGPOOL_PTR;
    imsg_ptr->FREE = TRUE;
    imsg_ptr->QUEUED = FALSE;

    _INT_DISABLE();
    /* Link onto the free list */
    imsg_ptr->NEXT = msgpool_ptr->MSG_FREE_LIST_PTR;
    msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr;
    ++msgpool_ptr->SIZE;
    _INT_ENABLE();

    _KLOGX2(KLOG_msg_free, MQX_OK);

} /* Endbody */

/*!
 * \brief Gets the number of free messages in the message pool.
 * 
 * The function fails if either:
 * \li Message component is not created.
 * \li Pool_id is for a private message pool, but does not represent a valid one.
 * 
 * \param[in] pool One of the following:
 * \li Private message pool for which to get the number of free messages.
 * \li MSGPOOL_NULL_POOL_ID (for system message pools).
 * 
 * \return The number of free messages in the private message pool (success).
 * \return The number of free messages in all system message pools (success).
 * \return 0 (Success: No free messages.)
 * \return 0 (Failure: see Description.)
 * 
 * \warning If pool_id does not represent a valid private message pool, calls 
 * _task_set_error() to set the task error code to MSGPOOL_INVALID_POOL_ID
 * 
 * \see _msgpool_create
 * \see _msgpool_destroy
 * \see _msg_free
 * \see _msg_alloc_system
 * \see _task_set_error
 * \see _msg_create_component      
 */ 
_mqx_uint _msg_available
(
    _pool_id pool
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
    register MSGPOOL_STRUCT_PTR msgpool_ptr;
    _mqx_uint                   i;
    _mqx_uint                   count;

    _GET_KERNEL_DATA(kernel_data);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        return(0);
    } /* Endif */
#endif

    msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR;
#if MQX_CHECK_ERRORS
    if (msgpool_ptr == NULL)
    {
        return(0);
    }/* Endif */
#endif

    if (pool == MSGPOOL_NULL_POOL_ID)
    {

        count = 0;
        _INT_DISABLE();
        i = msg_component_ptr->MAX_MSGPOOLS_EVER + 1;
        while ( --i )
        {
            if (
#if MQX_CHECK_VALIDITY
                (msgpool_ptr->VALID == MSG_VALID) &&
#endif
                (msgpool_ptr->MSGPOOL_TYPE == SYSTEM_MSG_POOL))
            {
                count += msgpool_ptr->SIZE;
            } /* Endif */
            ++msgpool_ptr;
        } /* Endwhile */
        _INT_ENABLE();
        return count;

    }
    else
    {

        msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool;
        if (
#if MQX_CHECK_VALIDITY
            (msgpool_ptr->VALID != MSG_VALID) ||
#endif
            (msgpool_ptr->MSGPOOL_TYPE != MSG_POOL) )
        {
            _task_set_error(MSGPOOL_INVALID_POOL_ID);
            return (0);
        } /* Endif */
        return (_mqx_uint)msgpool_ptr->SIZE;

    } /* Endif */

} /* Endbody */

/*!
 * \brief Converts the messages header from intel to motorola byte order (or vice 
 * versa).
 * 
 * The function is not needed for general application code because the IPC 
 * component converts the message header. Use it only if you are writing IPC 
 * message drivers for a new BSP.
 * \n The function calls _mem_swap_endian() and uses the field sizes of 
 * MESSAGE_HEADER_STRUCT to convert the header to the other endian format.
 * \n The macro MSG_MUST_CONVERT_HDR_ENDIAN determines whether the message 
 * header needs to be converted to the other endian format.
 * 
 * \param[in] message_ptr Pointer to a message whosenn header is to be converted.
 * 
 * \warning Sets CONTROL in the message header to indicate the correct endian 
 * format for the processor.
 * 
 * \see _mem_swap_endian
 * \see _msg_swap_endian_data
 * \see MSG_MUST_CONVERT_HDR_ENDIAN
 * \see MESSAGE_HEADER_STRUCT  
 */ 
static const uchar _KRNL_Hdr_def[] =
{
    sizeof(_msg_size),
#if MQX_USE_32BIT_MESSAGE_QIDS
    sizeof(uint_16),
#endif
    sizeof(_queue_id),
    sizeof(_queue_id),
    0
};

void _msg_swap_endian_header
(
    register MESSAGE_HEADER_STRUCT_PTR message_ptr
)
{ /* Body */

    _mem_swap_endian( (uchar _PTR_)_KRNL_Hdr_def, (pointer)&(message_ptr->SIZE));
    message_ptr->CONTROL &= ~MSG_HDR_ENDIAN_MASK;
    message_ptr->CONTROL |= MSG_HDR_ENDIAN;

} /* Endbody */

/*!
 * \brief Converts the data portion of the message from intel to motorola byte 
 * order ( or vice versa ).
 * 
 * The function calls _mem_swap_endian() and uses definition to swap 
 * single-addressable units: message_ptr + sizeof(MESSAGE_HEADER_STRUCT)
 * \n The macro MSG_MUST_CONVERT_DATA_ENDIAN determines whether the data portion 
 * of the message needs to be converted to the other endian format.
 * 
 * \param[in] definition  Pointer to an array (NULL-terminated), each element of 
 * which defines the size (in single-addressable units) of fields in the data 
 * portion of the message.
 * \param[in] message_ptr Pointer to the message whose data is to be converted.
 * 
 * \warning Sets CONTROL in the message header to indicate the correct endian 
 * format for the processor.
 * 
 * \see _mem_swap_endian
 * \see MSG_MUST_CONVERT_DATA_ENDIAN
 * \see MESSAGE_HEADER_STRUCT 
 */ 
void _msg_swap_endian_data
(
    uchar _PTR_                        definition,
    register MESSAGE_HEADER_STRUCT_PTR message_ptr
)
{ /* Body */

    _mem_swap_endian( definition, (pointer)((uchar _PTR_)message_ptr +
                                    sizeof(MESSAGE_HEADER_STRUCT)) );
    message_ptr->CONTROL &= ~MSG_DATA_ENDIAN_MASK;
    message_ptr->CONTROL |= MSG_DATA_ENDIAN;

} /* Endbody */

/*!
 * \brief This function is called when a task is being destroyed.
 * 
 * Closes all open message queues and then free all messages owned by this task.
 * 
 * \param[in] td_ptr The task descriptor of the task that is being destroyed.   
 */ 
void _msg_cleanup
(
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
    MSGQ_STRUCT_PTR             msgq_ptr;
    MSGQ_STRUCT_PTR             qprev_ptr;
    MSGPOOL_STRUCT_PTR          msgpool_ptr;
    MSGPOOL_BLOCK_STRUCT_PTR    msgpool_block_ptr;
    INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    INTERNAL_MESSAGE_STRUCT_PTR tmp_imsg_ptr;
    _mqx_uint                   i,j,raw_message_size;

    _GET_KERNEL_DATA(kernel_data);
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        return;
    } /* Endif */
#endif

    /* Delete the message queues owned by the task, and free the messages
     * on the queues
     */
    msgq_ptr = (MSGQ_STRUCT_PTR)td_ptr->MSG_QUEUE_HEAD;
    while (msgq_ptr != NULL)
    {
        if (msgq_ptr->TD_PTR != NULL)
        {
            msgq_ptr->TD_PTR->MESSAGES_AVAILABLE -= msgq_ptr->NO_OF_ENTRIES;
        } /* Endif */

        imsg_ptr = msgq_ptr->FIRST_MSG_PTR;
        while ( imsg_ptr != NULL )
        {
            tmp_imsg_ptr = imsg_ptr->NEXT;
            imsg_ptr->QUEUED = FALSE;
            _msg_free((pointer)&imsg_ptr->MESSAGE);
            imsg_ptr = tmp_imsg_ptr;
        } /* Endwhile */
        qprev_ptr = msgq_ptr;
        msgq_ptr = msgq_ptr->NEXT_MSGQ_PTR;
        qprev_ptr->FIRST_MSG_PTR = NULL;
        qprev_ptr->NEXT_MSGQ_PTR = NULL;
        qprev_ptr->QUEUE = 0;
    } /* Endwhile */

    td_ptr->MSG_QUEUE_HEAD = NULL;
    td_ptr->MSG_QUEUE_TAIL = NULL;

    /* Search through all of the message pools, looking for any messages
     * owned by this task.  If found free them.
     */
    msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR;
    i = msg_component_ptr->MAX_MSGPOOLS + 1;
    while (--i)
    {
        if (msgpool_ptr->VALID == MSG_VALID)
        {

            /* Search through all of the message pool blocks for this pool */
            msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR;
            while (msgpool_block_ptr != NULL)
            {
                raw_message_size = msgpool_block_ptr->RAW_MESSAGE_SIZE;
                imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR)
                ((uchar _PTR_)msgpool_block_ptr + sizeof(MSGPOOL_BLOCK_STRUCT));

                /* if the message is not free, not queued and the
                 * owner is the task being destroyed, then Free the message
                 */
                j = msgpool_block_ptr->NUM_MESSAGES + 1;
                while (--j)
                {
                    if ( (imsg_ptr->TD_PTR == td_ptr) &&
                                    (imsg_ptr->FREE == FALSE) &&
                                    (imsg_ptr->QUEUED == FALSE) )
                    {
                        _msg_free(&imsg_ptr->MESSAGE);
                    } /* Endif */
                    imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR)
                    ((uchar _PTR_)imsg_ptr + raw_message_size);
                } /* Endwhile */

                msgpool_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR;
            } /* Endwhile */

        } /* Endif */
        msgpool_ptr++;
    } /* Endwhile */

} /* Endbody */

/*!
 * \brief Allocates a message from a system message pool.
 * 
 * The size of the message is determined by the message size that a task 
 * specified when it called _msgpool_create_system().
 * \n The message is a resource of the task until the task either frees it 
 * (_msg_free()) or puts it on a message queue (_msgq_send family of functions.)
 * 
 * \param[in] message_size Maximum size (in single-addressable units) of the 
 * message.
 * 
 * \return Pointer to a message of at least message_size single-addressable 
 * units (success).
 * \return NULL (Failure: message component is not created.)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li Task error codes from _mem_alloc_system() (If MQX needs to grow the pool.)
 * 
 * \see _mem_alloc
 * \see _mem_alloc_from
 * \see _mem_alloc_system
 * \see _mem_alloc_system_from
 * \see _mem_alloc_system_zero
 * \see _mem_alloc_system_zero_from
 * \see _mem_alloc_zero
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align
 * \see _mem_alloc_align_from
 * \see _mem_alloc_at        
 * \see _msg_alloc
 * \see _msg_free
 * \see _msgpool_create_system
 * \see _msgq_send
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT 
 */ 
pointer _msg_alloc_system
(
    _msg_size message_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;
    uint_16                              grow_number;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_msg_alloc_system, message_size );

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX2( KLOG_msg_alloc_system, NULL );
        return(NULL);
    }/* Endif */
#endif

    message_ptr = NULL;
    _INT_DISABLE();
    msgpool_ptr = msg_component_ptr->SMALLEST_MSGPOOL_PTR;
    while (msgpool_ptr != NULL)
    {
        if (msgpool_ptr->MESSAGE_SIZE >= message_size)
        {
            imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
            if ( (imsg_ptr == NULL) &&
                            (msgpool_ptr->GROW_NUMBER) &&
                            (msgpool_ptr->MAX < msgpool_ptr->GROW_LIMIT) )
            {
                /* Attempt to add elements to the pool */
                grow_number = msgpool_ptr->GROW_NUMBER;
                if ( ((uint_16)(msgpool_ptr->MAX + grow_number) > msgpool_ptr->GROW_LIMIT))
                {
                    grow_number = msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX;
                } /* Endif */
                _msgpool_add_internal(msgpool_ptr, grow_number);
                imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
            } /* Endif */
            if ( imsg_ptr != NULL )
            {
                msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr->NEXT;
                --msgpool_ptr->SIZE;
                _INT_ENABLE();
                imsg_ptr->FREE = FALSE;
                imsg_ptr->QUEUED = FALSE;
                if (kernel_data->IN_ISR)
                {
                    imsg_ptr->TD_PTR = NULL;
                }
                else
                {
                    imsg_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
                } /* Endif */
                message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;
                message_ptr->TARGET_QID = MSGQ_NULL_QUEUE_ID;
                message_ptr->SOURCE_QID = MSGQ_NULL_QUEUE_ID;
                message_ptr->SIZE = message_size;
                message_ptr->CONTROL = MSG_HDR_ENDIAN | MSG_DATA_ENDIAN;

                _KLOGX2(KLOG_msg_alloc_system, message_ptr);
                return (pointer)message_ptr;
            } /* Endif */
        } /* Endif */
        msgpool_ptr = msgpool_ptr->NEXT_MSGPOOL_PTR;
    } /* Endwhile */

    _int_enable();
    _KLOGX2(KLOG_msg_alloc_system, message_ptr);
    return (pointer)message_ptr;

} /* Endbody */

#endif /* MQX_USE_MESSAGES */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/ehci/ehci_dev_main.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_dev_main.c$
* $Version : 3.8.14.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
*   This file contains the main VUSBHS USB Device Controller interface
*   functions.
*
*END*********************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "dev_cnfg.h"
#include "devapi.h"
#include "dev_main.h"

#include "ehci_dev_main.h"
#include "ehci_usbprv.h"

/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/
#define USB_TEST_MODE_TEST_PACKET_LENGTH   (53)
#define MCF_USB_USBMODE             (*(volatile uint_32*)(0xFC0B01A8))
#define MCF_USB_USBCMD              (*(volatile uint_32*)(0xFC0B0140))
#define MCF_USB_USBMODE_SLOM        (0x00000008)
#define MCF_USB_USBCMD_ITC(x)       (((x)&0x000000FF)<<16)
#define MCF_USB_USBSTS              (*(volatile uint_32*)(0xFC0B0144))
#define MCF_USB_USBSTS_URI          (0x00000040)
/****************************************************************************
 * Global Variables
 ****************************************************************************/
static uint_8_ptr g_ep_recv_buff_ptr[USB_MAX_ENDPOINTS];

/****************************************************************************
 * Global Functions
 ****************************************************************************/

/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/

/*****************************************************************************
 * Local Variables
 *****************************************************************************/
/* Test packet for Test Mode :
   TEST_PACKET. USB 2.0 Specification section 7.1.20 */
uint_8 test_packet[USB_TEST_MODE_TEST_PACKET_LENGTH] =
{
    /* Synch */
    /* DATA 0 PID */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
    0xAA, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
    0xEE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xBF, 0xDF,
    0xEF, 0xF7, 0xFB, 0xFD, 0xFC, 0x7E, 0xBF, 0xDF,
    0xEF, 0xF7, 0xFB, 0xFD, 0x7E
};

/*****************************************************************************
 * Global Functions
 *****************************************************************************/
/********************************************************************/
/**************************************************************************//*!
*
* @name        : _usb_dci_usbhs_preinit
* @brief       : Allocates space for the USB device controller.
* @param handle: Handle to USB Device to be filled
* @return   USB_OK on successful.
******************************************************************************/
USB_STATUS _usb_dci_usbhs_preinit
(
    /* [IN] the USB device handle */
    _usb_device_handle _PTR_ handle_ptr
)
{
    USB_EHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR) USB_mem_alloc_zero(sizeof(USB_EHCI_DEV_STATE_STRUCT));
    EHCI_XD_STRUCT_PTR            xd_ptr;
    SCRATCH_STRUCT_PTR            temp_scratch_ptr;
    _mqx_uint j;

    if (NULL != usb_dev_ptr) {
        /* Allocate MAX_XDS_FOR_TR_CALLS */
        usb_dev_ptr->G.XD_BASE = (XD_STRUCT_PTR) USB_mem_alloc_zero(sizeof(EHCI_XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);

        if (usb_dev_ptr->G.XD_BASE == NULL)
        {
            #if DEV_DEBUG
            printf("2 memalloc failed in _usb_device_init\n");
            #endif

            _mem_free(usb_dev_ptr);
            return USBERR_ALLOC;
        } /* Endif */

        /* Allocate memory for internal scratch structure */
        usb_dev_ptr->G.XD_SCRATCH_STRUCT_BASE = (SCRATCH_STRUCT_PTR) USB_mem_alloc_zero(sizeof(SCRATCH_STRUCT) * MAX_XDS_FOR_TR_CALLS);

        if (usb_dev_ptr->G.XD_SCRATCH_STRUCT_BASE == NULL)
        {
            #if DEV_DEBUG
            printf("3 memalloc failed in _usb_device_init\n");
            #endif

            _mem_free(usb_dev_ptr->G.XD_BASE);
            _mem_free(usb_dev_ptr);
            return USBERR_ALLOC;
        } /* Endif */

        usb_dev_ptr->G.TEMP_XD_PTR = (XD_STRUCT_PTR) USB_mem_alloc_zero(sizeof(EHCI_XD_STRUCT));
        if(usb_dev_ptr->G.TEMP_XD_PTR == NULL)
        {
            #ifdef _DEV_DEBUG
                printf("4 memalloc failed in _usb_device_init\n");
            #endif  
            _mem_free(usb_dev_ptr->G.XD_SCRATCH_STRUCT_BASE);
            _mem_free(usb_dev_ptr->G.XD_BASE);
            _mem_free(usb_dev_ptr);
            return USBERR_ALLOC;
        }

    } /* Endif */

    usb_dev_ptr->G.XD_HEAD = NULL;
    usb_dev_ptr->G.XD_TAIL = NULL;
    usb_dev_ptr->G.XD_ENTRIES = 0;

    /* Enqueue all the XDs */   
    xd_ptr = (EHCI_XD_STRUCT_PTR) usb_dev_ptr->G.XD_BASE;
    temp_scratch_ptr = usb_dev_ptr->G.XD_SCRATCH_STRUCT_BASE;
    for (j = 0; j < MAX_XDS_FOR_TR_CALLS; j++) 
    {
       xd_ptr->G.SCRATCH_PTR = temp_scratch_ptr;
       xd_ptr->G.SCRATCH_PTR->FREE = _usb_device_free_XD;
       xd_ptr->G.SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
       _usb_device_free_XD(usb_dev_ptr,(pointer)xd_ptr);
       xd_ptr++;
       temp_scratch_ptr++;
    }

    *handle_ptr = (_usb_device_handle) usb_dev_ptr;
    return USB_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_init
*  Returned Value : USB_OK or error code
*  Comments       :
*        Initializes the USB device controller.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_init
(
    /* [IN] the USB device handle */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    volatile USBHS_REG_STRUCT_PTR      dev_ptr;
    volatile USBHS_REG_STRUCT_PTR      cap_dev_ptr;
    USB_EHCI_DEV_INIT_STRUCT_PTR       param = (USB_EHCI_DEV_INIT_STRUCT_PTR) usb_dev_ptr->G.INIT_PARAM;
    _mqx_uint                          temp;
    _mem_size                          total_memory=0;
    uint_8_ptr                         driver_memory;
    _mqx_uint                          vector;

    if (usb_dev_ptr == NULL) {
        return USBERR_INVALID_DEVICE_NUM;
    }
    usb_dev_ptr->G.DEV_PTR = param->BASE_PTR;
    usb_dev_ptr->G.DEV_VEC = param->VECTOR;
    usb_dev_ptr->G.USB_STATE = USB_STATE_UNKNOWN;
   
    usb_dev_ptr->CAP_BASE_PTR = param->CAP_BASE_PTR;
    cap_dev_ptr = (USBHS_REG_STRUCT_PTR) usb_dev_ptr->CAP_BASE_PTR;

    /* Get the maximum number of endpoints supported by this USB controller */
    usb_dev_ptr->G.MAX_ENDPOINTS =
        (uint_8)((EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.DCC_PARAMS) &
         USBHS_MAX_ENDPTS_SUPPORTED) & 0x000000FF);

    temp = (uint_8)(usb_dev_ptr->G.MAX_ENDPOINTS * 2);

    /****************************************************************
     Consolidated memory allocation
     ****************************************************************/
    total_memory = ((temp * sizeof(USBHS_EP_QUEUE_HEAD_STRUCT)) + 2048) +
                   ((MAX_EP_TR_DESCRS * sizeof(USBHS_EP_TR_STRUCT)) + 32) +
                   (sizeof(SCRATCH_STRUCT)*MAX_EP_TR_DESCRS);

    driver_memory = (uint_8_ptr) USB_mem_alloc_uncached(total_memory);


    if (driver_memory == NULL)
    {
        return USBERR_ALLOC;
    }

    /****************************************************************
     Zero out the memory allocated
    ****************************************************************/
    USB_mem_zero((void *)driver_memory,total_memory);

    #if PSP_HAS_DATA_CACHE
    /****************************************************************
     Flush the zeroed memory if cache is enabled
     ****************************************************************/
        USB_dcache_flush_mlines((pointer)driver_memory,total_memory);
    #endif

    /****************************************************************
     Keep a pointer to driver memory alloctaion
     ****************************************************************/
    usb_dev_ptr->DRIVER_MEMORY = driver_memory;
    usb_dev_ptr->TOTAL_MEMORY = total_memory;
    /****************************************************************
     Assign QH base
     ****************************************************************/
    usb_dev_ptr->EP_QUEUE_HEAD_BASE = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR) driver_memory;
    driver_memory += ((temp * sizeof(USBHS_EP_QUEUE_HEAD_STRUCT)) + 2048);

    /* Align the endpoint queue head to 2K boundary */
    usb_dev_ptr->EP_QUEUE_HEAD_PTR = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR)
        USB_MEM2048_ALIGN((uint_32)usb_dev_ptr->EP_QUEUE_HEAD_BASE);

    /****************************************************************
     Assign DTD base
     ****************************************************************/
    usb_dev_ptr->DTD_BASE_PTR = (USBHS_EP_TR_STRUCT_PTR) driver_memory;
    driver_memory += ((MAX_EP_TR_DESCRS * sizeof(USBHS_EP_TR_STRUCT)) + 32);

    /* Align the dTD base to 32 byte boundary */
    usb_dev_ptr->DTD_ALIGNED_BASE_PTR = (USBHS_EP_TR_STRUCT_PTR)
        USB_MEM32_ALIGN((uint_32)usb_dev_ptr->DTD_BASE_PTR);

    /****************************************************************
     Assign SCRATCH Structure base
     ****************************************************************/
    /* Allocate memory for internal scratch structure */
    usb_dev_ptr->G.SCRATCH_STRUCT_BASE = (SCRATCH_STRUCT_PTR) driver_memory;

    /* Install the interrupt service routine */
    if (!(USB_install_isr(usb_dev_ptr->G.DEV_VEC,_usb_dci_usbhs_isr,(pointer)usb_dev_ptr)))
    {
        #ifdef _DEV_DEBUG
            printf("USB_Install_isr failed.\n");
        #endif
        return USBERR_INSTALL_ISR;
    }

    usb_dev_ptr->G.USB_STATE = USB_STATE_UNKNOWN;

    /* Initialize the VUSB_HS controller */
    _usb_dci_usbhs_chip_initialize((_usb_device_handle) usb_dev_ptr);

    return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_chip_initialize
*  Returned Value : USB_OK or error code
*  Comments       :
*        Initializes the USB device controller.
*
*END*-----------------------------------------------------------------*/
void _usb_dci_usbhs_chip_initialize
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR    usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR             dev_ptr;
    volatile USBHS_REG_STRUCT_PTR             cap_dev_ptr;
    volatile USBHS_EP_QUEUE_HEAD_STRUCT_PTR   ep_queue_head_ptr;
    volatile USBHS_EP_TR_STRUCT_PTR           dTD_ptr;
    uint_8                                    temp,i;
    SCRATCH_STRUCT_PTR                        temp_scratch_ptr;
    volatile uint_16_ptr                      pUOCSR;
    USB_EHCI_DEV_INIT_STRUCT_PTR              param;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR) handle;
    if (usb_dev_ptr == NULL) {
        return;
    }
    
    param = (USB_EHCI_DEV_INIT_STRUCT_PTR) usb_dev_ptr->G.INIT_PARAM;

    USB_lock();

    cap_dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->CAP_BASE_PTR;
    /* Modify the base address of the VUSB_HS registers, do not use the old one anymore */
    usb_dev_ptr->G.DEV_PTR = (pointer) ((uint_32)cap_dev_ptr +
        (EHCI_REG_READ(cap_dev_ptr->REGISTERS.CAPABILITY_REGISTERS.CAPLENGTH_HCIVER) &
         EHCI_CAP_LEN_MASK));
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* Program the controller to be the USB device controller */
    #if USBCFG_MEMORY_ENDIANNESS==MQX_BIG_ENDIAN
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_MODE,
        ( USBHS_MODE_CTRL_MODE_DEV | USBHS_MODE_BIG_ENDIAN | USBHS_MODE_SETUP_LOCK_DISABLE));
    #else
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_MODE,
        ( USBHS_MODE_CTRL_MODE_DEV | USBHS_MODE_SETUP_LOCK_DISABLE));
    #endif

    temp = (uint_8)(usb_dev_ptr->G.MAX_ENDPOINTS * 2);

    /* Initialize the internal dTD head and tail to NULL */
    usb_dev_ptr->DTD_HEAD = NULL;
    usb_dev_ptr->DTD_TAIL = NULL;

    /* Make sure the 16 MSBs of this register are 0s */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPT_SETUP_STAT,0);

    ep_queue_head_ptr = usb_dev_ptr->EP_QUEUE_HEAD_PTR;

    /* Initialize all device queue heads */
    for (i = 0; i < temp; i++)
    {
        /* Interrupt on Setup packet */
        EHCI_MEM_WRITE((ep_queue_head_ptr + i)->MAX_PKT_LENGTH,
            ((uint_32)USB_MAX_CTRL_PAYLOAD <<
                VUSB_EP_QUEUE_HEAD_MAX_PKT_LEN_POS)
            | VUSB_EP_QUEUE_HEAD_IOS);
        EHCI_MEM_WRITE((ep_queue_head_ptr + i)->NEXT_DTD_PTR, VUSB_EP_QUEUE_HEAD_NEXT_TERMINATE);
    }

    #if PSP_HAS_DATA_CACHE
        USB_dcache_flush_mlines((void *)ep_queue_head_ptr, ((sizeof(USBHS_EP_QUEUE_HEAD_STRUCT))*temp));
    #endif

    /* Configure the Endpoint List Address */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.EP_LIST_ADDR,
        (uint_32)ep_queue_head_ptr);

    dTD_ptr = usb_dev_ptr->DTD_ALIGNED_BASE_PTR;
    usb_dev_ptr->DTD_ENTRIES = 0;

    temp_scratch_ptr = usb_dev_ptr->G.SCRATCH_STRUCT_BASE;

    /* Enqueue all the dTDs */
    for (i=0;i<MAX_EP_TR_DESCRS;i++)
    {
        dTD_ptr->SCRATCH_PTR = temp_scratch_ptr;
        dTD_ptr->SCRATCH_PTR->FREE = _usb_dci_usbhs_free_dTD;
        /* Set the dTD to be invalid */
        EHCI_MEM_WRITE(dTD_ptr->NEXT_TR_ELEM_PTR, USBHS_TD_NEXT_TERMINATE);
        /* Set the Reserved fields to 0 */
        EHCI_MEM_CLEAR_BITS(dTD_ptr->SIZE_IOC_STS,USBHS_TD_RESERVED_FIELDS);
        dTD_ptr->SCRATCH_PTR->PRIVATE = (pointer) usb_dev_ptr;
        _usb_dci_usbhs_free_dTD(usb_dev_ptr, (pointer)dTD_ptr);
        dTD_ptr++;
        temp_scratch_ptr++;
    }

    /*--- Intial Configuration ---*/
    /* Initialize the endpoint 0 properties */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[0],
        (EHCI_EPCTRL_TX_DATA_TOGGLE_RST | EHCI_EPCTRL_RX_DATA_TOGGLE_RST));
    EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[0],
        0 ); //(EHCI_EPCTRL_TX_EP_STALL | EHCI_EPCTRL_RX_EP_STALL));

    /* Enable interrupts */
    /* There is no need to enable SOF Interrupt as its generated automatically
       by hardware irrespective of device attachment status */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_INTR,
        (EHCI_INTR_INT_EN | EHCI_INTR_ERR_INT_EN |
        EHCI_INTR_PORT_CHANGE_DETECT_EN | EHCI_INTR_RESET_EN |
        EHCI_INTR_DEVICE_SUSPEND));

    /* Enable the interrupts */
    USB_unlock();

    usb_dev_ptr->G.USB_STATE = USB_STATE_UNKNOWN;

    /* Set the OTG Termination bit: not needed; the device termination is done with USBCMD:RS bit
    ** when B session is active: see below
    */
    //EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.OTGSC,USBHS_OTGSC_OT);

    /* Set the Run bit in the command register */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD,EHCI_CMD_RUN_STOP);
    
    /* Enable a valid B session to allow device to connect to a host*/
    pUOCSR = param->USBOTGCSR_ADDR;
    if (pUOCSR != NULL) {
      *pUOCSR = USB_OTG_UOCSR_BVLD;
    }
} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_free_dTD
*  Returned Value : void
*  Comments       :
*        Enqueues a dTD onto the free DTD ring.
*
*END*-----------------------------------------------------------------*/

void _usb_dci_usbhs_free_dTD
(
    _usb_device_handle handle,
    /* [IN] the dTD to enqueue */
    pointer  dTD_ptr
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR) handle;

    /*
    ** This function can be called from any context, and it needs mutual
    ** exclusion with itself.
    */
    USB_lock();

    /*
    ** Add the dTD to the free dTD queue (linked via PRIVATE) and
    ** increment the tail to the next descriptor
    */
    EHCI_DTD_QADD(usb_dev_ptr->DTD_HEAD, usb_dev_ptr->DTD_TAIL,
        (USBHS_EP_TR_STRUCT_PTR)dTD_ptr);
    usb_dev_ptr->DTD_ENTRIES++;
    USB_unlock();
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_add_dTD
*  Returned Value : USB_OK or error code
*  Comments       :
*        Adds a device transfer desriptor(s) to the queue.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_dci_usbhs_add_dTD
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] The transfer descriptor address */
    XD_STRUCT_PTR              xd_ptr
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR  usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR     dev_ptr;
    volatile USBHS_EP_TR_STRUCT_PTR   dTD_ptr, temp_dTD_ptr, first_dTD_ptr = NULL;
    volatile USBHS_EP_QUEUE_HEAD_STRUCT_PTR ep_queue_head_ptr;
    uint_32 curr_pkt_len, remaining_len, curr_offset, bit_pos, addr;
    uint_8 temp;

    /*********************************************************************
     For a optimal implementation, we need to detect the fact that
     we are adding DTD to an empty list. If list is empty, we can
     actually skip several programming steps esp. those for ensuring
     that there is no race condition.The following boolean will be useful
     in skipping some code here.
     *********************************************************************/
     boolean   list_empty = FALSE;
     boolean   read_safe;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    remaining_len = xd_ptr->WTOTALLENGTH;

    curr_offset = 0;
    temp = (uint_8)(2*xd_ptr->EP_NUM + xd_ptr->BDIRECTION);
    bit_pos = (uint_32)(1 << (16 * xd_ptr->BDIRECTION + xd_ptr->EP_NUM));

    ep_queue_head_ptr = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR)
        EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.EP_LIST_ADDR) +
        temp;

    #if PSP_HAS_DATA_CACHE
        USB_dcache_flush_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
    #endif

   /*********************************************************************
    This loops iterates through the length of the transfer and divides
    the data in to DTDs each handling the a max of 0x4000 bytes of data.
    The first DTD in the list is stored in a pointer called first_dTD_ptr.
    This pointer is later linked in to QH for processing by the hardware.
    *********************************************************************/

    do
    {
        /* Check if we need to split the transfer into multiple dTDs */
        if(remaining_len > VUSB_EP_MAX_LENGTH_TRANSFER)
        {
            curr_pkt_len = VUSB_EP_MAX_LENGTH_TRANSFER;
        }
        else
        {
            curr_pkt_len = remaining_len;
        }

        remaining_len -= curr_pkt_len;

        /* Get a dTD from the queue */
        EHCI_DTD_QGET(usb_dev_ptr->DTD_HEAD, usb_dev_ptr->DTD_TAIL, dTD_ptr);

        if (!dTD_ptr)
        {
            return USBERR_TR_FAILED;
        }

        usb_dev_ptr->DTD_ENTRIES--;

        if (curr_offset == 0)
        {
            first_dTD_ptr = dTD_ptr;
        }

        #if PSP_HAS_DATA_CACHE
            /**************************************************************
             USB Memzero does not bypass the cache and hence we must use
             DTD pointer to update the memory and bypass the cache. If
             your DTD are allocated from an uncached region, you can
             eliminitate this approach and switch back to USB_mem_zero().
             **************************************************************/
            EHCI_MEM_WRITE(dTD_ptr->NEXT_TR_ELEM_PTR, 0);
            EHCI_MEM_WRITE(dTD_ptr->SIZE_IOC_STS, 0);
            EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR0, 0);
            EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR1,0);
            EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR2,0);
            EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR3,0);
            EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR4,0);
        #else
            /* Zero the dTD. Leave the last 4 bytes as that is the
               scratch pointer*/
            USB_mem_zero((void *) dTD_ptr,(sizeof(USBHS_EP_TR_STRUCT) - 4));
        #endif

        /* Initialize the dTD */
        dTD_ptr->SCRATCH_PTR->PRIVATE = handle;

        /* Set the Terminate bit */
        EHCI_MEM_WRITE(dTD_ptr->NEXT_TR_ELEM_PTR, VUSB_EP_QUEUE_HEAD_NEXT_TERMINATE);

        /*************************************************************
         FIX ME: For hig-speed and high-bandwidth ISO IN endpoints,
         we must initialize the multiplied field so that Host can issues
         multiple IN transactions on the endpoint. See the DTD data
         structure for MultiIO field.

         <NAME> 11/06/2003
         *************************************************************/

        /* Set the reserved field to 0 */
        EHCI_MEM_CLEAR_BITS(dTD_ptr->SIZE_IOC_STS,USBHS_TD_RESERVED_FIELDS);

        /* 4K apart buffer page pointers */
        
        addr = (uint_32)(xd_ptr->WSTARTADDRESS + curr_offset);
        EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR0, addr);
        EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR1, (addr + 4096));
        EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR2, (addr + (4096*2)));
        EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR3, (addr + (4096*3)));
        EHCI_MEM_WRITE(dTD_ptr->BUFF_PTR4, (addr + (4096*4)));

        curr_offset += curr_pkt_len;
        /* Fill in the transfer size */
        if (!remaining_len)
        {
            EHCI_MEM_WRITE(dTD_ptr->SIZE_IOC_STS,((curr_pkt_len << USBHS_TD_LENGTH_BIT_POS) | USBHS_TD_IOC | USBHS_TD_STATUS_ACTIVE));
        }
        else
        {
            EHCI_MEM_WRITE(dTD_ptr->SIZE_IOC_STS,((curr_pkt_len << USBHS_TD_LENGTH_BIT_POS) | USBHS_TD_STATUS_ACTIVE));
        }
        #if PSP_HAS_DATA_CACHE
            USB_dcache_flush_mlines((void *)dTD_ptr,sizeof(USBHS_EP_TR_STRUCT));
        #endif
        /* Maintain the first and last device transfer descriptor per
           endpoint and direction */
        if (!usb_dev_ptr->EP_DTD_HEADS[temp])
        {
            usb_dev_ptr->EP_DTD_HEADS[temp] = dTD_ptr;
            /***********************************************
             If list does not have a head, it means that list
             is empty. An empty condition is detected.
             ***********************************************/
            list_empty = TRUE;
        }

        /* Check if the transfer is to be queued at the end or beginning */
        temp_dTD_ptr = usb_dev_ptr->EP_DTD_TAILS[temp];

        /* Remember which XD to use for this dTD */
        dTD_ptr->SCRATCH_PTR->XD_FOR_THIS_DTD = (pointer)xd_ptr;

        /* New tail */
        usb_dev_ptr->EP_DTD_TAILS[temp] = dTD_ptr;

        if (temp_dTD_ptr)
        {
            /* Should not do |=. The Terminate bit should be zero */
            EHCI_MEM_WRITE(temp_dTD_ptr->NEXT_TR_ELEM_PTR, (uint_32)dTD_ptr);
        }

    } while (remaining_len); /* EndWhile */


    /**************************************************************
     In the loop above DTD has already been added to the list
     However endpoint has not been primed yet. If list is not empty
     we need safer ways to add DTD to the
     existing list. Else we just skip to adding DTD to QH safely.
     **************************************************************/
    if(list_empty)/* If List is Empty : case 1*/
    {
        /* No other transfers on the queue */
        /* Step 1 of Executing a Transfer Descriptor documentation */
        EHCI_MEM_WRITE(ep_queue_head_ptr->NEXT_DTD_PTR,(uint_32)first_dTD_ptr);
        /* Step 2 of Executing a Transfer Descriptor documentation */
        EHCI_MEM_WRITE(ep_queue_head_ptr->SIZE_IOC_INT_STS,0);

        /* Prime the Endpoint */
        /* Step 3 of Executing a Transfer Descriptor documentation */
        EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME,bit_pos);
    }
    else /* If list is not empty : case 2*/
    {
        #ifdef TRIP_WIRE
            /*********************************************************
             Hardware v3.2+ require the use of semaphore to ensure that
             QH is safely updated.
             *********************************************************/

            /*********************************************************
             Check the prime bit. If set return USB_OK
             *********************************************************/
            if (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME) &
                bit_pos)
            {
                return USB_OK;
            }

            read_safe = FALSE;
            while(!read_safe)
            {
                /*********************************************************
                 start with setting the semaphores
                 *********************************************************/
                EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD,
                    EHCI_CMD_ATDTW_TRIPWIRE_SET);

                /*********************************************************
                 Read the endpoint status
                 *********************************************************/
                if(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD) &
                    EHCI_CMD_ATDTW_TRIPWIRE_SET)
                {
                    read_safe = TRUE;
                }
            }/*end while loop */

            /*********************************************************
             Clear the semaphore
             *********************************************************/
            EHCI_MEM_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD,
                EHCI_CMD_SETUP_TRIPWIRE_CLEAR);
        #else   /*workaround old method */
            /* Start CR 1015 */
            /* Prime the Endpoint */
            EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME, bit_pos);

            if(!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos))
            {
               /* old workaround will be compiled */
               while(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME) & bit_pos)
               {
                    /* Wait for the ENDPTPRIME to go to zero */
               }

               if(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos)
               {
                    /* The endpoint was not not primed so no other transfers on
                       the queue */
                    return USB_OK;
               }
            }
            else
            {
                return USB_OK;
            }

            #if PSP_HAS_DATA_CACHE
                USB_dcache_invalidate_mlines((void *)first_dTD_ptr, sizeof(USBHS_EP_TR_STRUCT));
            #endif

            /* No other transfers on the queue */
            EHCI_MEM_WRITE(ep_queue_head_ptr->NEXT_DTD_PTR,(uint_32)first_dTD_ptr);
            EHCI_MEM_WRITE(ep_queue_head_ptr->SIZE_IOC_INT_STS, 0);

            #if PSP_HAS_DATA_CACHE
                USB_dcache_flush_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
            #endif

            /* Prime the Endpoint */
            EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME,bit_pos);
        #endif
    }
    return USB_OK;
   /* End CR 1015 */
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_send_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Sends data by adding and executing the dTD. Non-blocking.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_send_data
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] The transfer descriptor address */
    XD_STRUCT_PTR              xd_ptr
)
{   /* Body */
    /* Add and execute the device transfer descriptor */
    #if PSP_HAS_DATA_CACHE
        USB_dcache_flush_mlines((void *)xd_ptr->WSTARTADDRESS, xd_ptr->WTOTALLENGTH);
    #endif

    return(_usb_dci_usbhs_add_dTD(handle, xd_ptr));
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_recv_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Receives data by adding and executing the dTD. Non-blocking.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_recv_data
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] The transfer descriptor address */
    XD_STRUCT_PTR              xd_ptr
)
{   /* Body */
    /* Add and execute the device transfer descriptor */
    #if PSP_HAS_DATA_CACHE
        USB_dcache_invalidate_mlines((void *)xd_ptr->WSTARTADDRESS, xd_ptr->WTOTALLENGTH);
    #endif

    return(_usb_dci_usbhs_add_dTD(handle, xd_ptr));
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_process_tr_complete
*  Returned Value : None
*  Comments       :
*        Services transaction complete interrupt
*
*END*-----------------------------------------------------------------*/
void _usb_dci_usbhs_process_tr_complete
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR  usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR     dev_ptr;
    volatile USBHS_EP_TR_STRUCT_PTR   dTD_ptr;
    volatile USBHS_EP_TR_STRUCT_PTR   temp_dTD_ptr;
    volatile USBHS_EP_QUEUE_HEAD_STRUCT_PTR ep_queue_head_ptr;
    uint_8  temp, i, ep_num, direction;
    uint_32  remaining_length = 0;
    uint_32  actual_transfer_length = 0;
    uint_32  errors = 0;
    volatile EHCI_XD_STRUCT_PTR  xd_ptr;
    volatile EHCI_XD_STRUCT_PTR  temp_xd_ptr = NULL;
    uint_8_ptr buff_start_address = NULL;

    USB_EVENT_STRUCT event;
    uint_32 max_packet_size, bit_pos;


    _int_disable();
    USB_mem_zero(&event, sizeof(USB_EVENT_STRUCT)); /* Initialize event structure */

    event.handle = handle;
    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;
    /* We use separate loops for ENDPTSETUPSTAT and ENDPTCOMPLETE because the
       setup packets are to be read ASAP */
    /* Process all Setup packet received interrupts */
    bit_pos = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPT_SETUP_STAT);

    if (bit_pos)
    {

        for (i = 0; i < 16; i++)
        {
            if (bit_pos & (1 << i))
            {
                event.ep_num = USB_CONTROL_ENDPOINT;
                event.setup = TRUE;
                event.direction = USB_RECV;
                event.len = USB_SETUP_PKT_SIZE;
                event.buffer_ptr =
                    (uint_8_ptr)USB_mem_alloc_zero(USB_SETUP_PKT_SIZE);
                if(event.buffer_ptr == NULL)
                {
                    #ifdef _DEV_DEBUG
                        printf("1 memalloc failed in _usb_dci_usbhs_process_tr_complete\n");
                    #endif
                    return;
                }

                (void)_usb_dci_usbhs_get_setup_data(handle,
                    USB_CONTROL_ENDPOINT,event.buffer_ptr);

                (void)_usb_device_call_service(i, &event);

                USB_mem_free(event.buffer_ptr);
             } /* Endif */
         } /* Endfor */
    } /* Endif */

   /* Don't clear the endpoint setup status register here. It is cleared as a
      setup packet is read out of the buffer */

    /* Process non-setup transaction complete interrupts */
    bit_pos = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCOMPLETE);

    /* Clear the bits in the register */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCOMPLETE,bit_pos);

    if (bit_pos)
    {
        /* Get the endpoint number and the direction of transfer */
        for (i = 0; i < 32; i++)
        {
            if (bit_pos & (1 << i))
            {
                if (i > 15)
                {
                    ep_num = (uint_8)(i - 16);
                    direction = 1;
                }
                else
                {
                    ep_num = i;
                    direction = 0;
                } /* Endif */

                temp = (uint_8)(2*ep_num + direction);

                /* Get the first dTD */
                dTD_ptr = usb_dev_ptr->EP_DTD_HEADS[temp];

                ep_queue_head_ptr = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR)
                EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.EP_LIST_ADDR) +
                temp;
                max_packet_size = (EHCI_MEM_READ(ep_queue_head_ptr->MAX_PKT_LENGTH) >> 16) &
                    0x000007FF;

                #if PSP_HAS_DATA_CACHE
                    USB_dcache_invalidate_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
                #endif

                /* Process all the dTDs for respective transfers */
                while (dTD_ptr)
                {

                    if (EHCI_MEM_READ(dTD_ptr->SIZE_IOC_STS) & USBHS_TD_STATUS_ACTIVE)
                    {
                        /*No more dTDs to process. Next one is owned by VUSB*/
                        break;
                    } /* Endif */

                    /* Get the correct internal transfer descriptor */
                    xd_ptr = (EHCI_XD_STRUCT_PTR)dTD_ptr->SCRATCH_PTR->XD_FOR_THIS_DTD;

                    if (xd_ptr)
                    {
                        buff_start_address = xd_ptr->G.WSTARTADDRESS;
                        actual_transfer_length = xd_ptr->G.WTOTALLENGTH;
                        event.buffer_ptr = xd_ptr->G.WSTARTADDRESS;
                        temp_xd_ptr = xd_ptr;
                    } /* Endif */

                    /* Get the address of the next dTD */
                    temp_dTD_ptr = (USBHS_EP_TR_STRUCT_PTR)
                    (EHCI_MEM_READ(dTD_ptr->NEXT_TR_ELEM_PTR) & USBHS_TD_ADDR_MASK);

                    /* Read the errors */
                    errors = (EHCI_MEM_READ(dTD_ptr->SIZE_IOC_STS) & USBHS_TD_ERROR_MASK);

                    if (!errors)
                    {
                        /* No errors */
                        /* Get the length of transfer from the current dTD */
                        remaining_length += ((EHCI_MEM_READ(dTD_ptr->SIZE_IOC_STS) &
                            VUSB_EP_TR_PACKET_SIZE) >> 16);
                        actual_transfer_length -= remaining_length;
                    }
                    else
                    {
                        if (errors & USBHS_TD_STATUS_HALTED)
                        {
                            /* Clear the errors and Halt condition */
                            EHCI_MEM_CLEAR_BITS(ep_queue_head_ptr->SIZE_IOC_INT_STS,errors);
                        } /* Endif */
                    } /* Endif */

                    /* Retire the processed dTD */
                    (void)_usb_dci_usbhs_cancel_transfer(handle, ep_num,
                        direction);
                    event.ep_num = ep_num;
                    event.setup = FALSE;
                    event.direction = direction;
                    /* if wtotallength is greater tahn max_packet_size,
                       then it marks split transaction */
                    event.len = (xd_ptr->G.WTOTALLENGTH > max_packet_size)?
                        xd_ptr->G.WTOTALLENGTH : actual_transfer_length;

                    if (temp_dTD_ptr)
                    {
                        if((uint_32)temp_dTD_ptr->SCRATCH_PTR->\
                            XD_FOR_THIS_DTD != (uint_32)temp_xd_ptr)
                        {
                            /* Transfer complete. Call the register service
                               function for the endpoint */
                            (void)_usb_device_call_service(ep_num,&event);
                            remaining_length = 0;
                        } /* Endif */
                    }
                    else
                    {
                        /* Transfer complete. Call the register service
                           function for the endpoint */
                        (void)_usb_device_call_service(ep_num,&event);
                    } /* Endif */

                    dTD_ptr = temp_dTD_ptr;
                    errors = 0;
                } /* Endwhile */
            } /* Endif */
        } /* Endfor */
    }/* Endif */
    _int_enable();
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_process_reset
*  Returned Value : None
*  Comments       :
*        Services reset interrupt
*
*END*-----------------------------------------------------------------*/
void _usb_dci_usbhs_process_reset
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR  usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR     dev_ptr;
    uint_32                    temp;
    uint_8                     cnt=0;

    USB_EVENT_STRUCT           event;

    event.handle = handle;
    event.ep_num = USB_CONTROL_ENDPOINT;
    event.setup = FALSE;
    event.direction = USB_RECV;
    event.buffer_ptr = NULL;
    event.len = ZERO_LENGTH;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* De-Init All the End Point.  */
    for (cnt = 0; cnt < USB_MAX_ENDPOINTS; cnt++)
    {
        _usb_dci_usbhs_deinit_endpoint(handle,cnt,USB_RECV);
        _usb_dci_usbhs_deinit_endpoint(handle,cnt,USB_SEND);
    }

    /* The address bits are past bit 25-31. Set the address */
    EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.DEVICE_ADDR,0xFE000000);

    /* Clear all the setup token semaphores */
    temp = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPT_SETUP_STAT);
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPT_SETUP_STAT ,temp);

    /* Clear all the endpoint complete status bits */
    temp = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCOMPLETE);
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCOMPLETE ,temp);

    while (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME) & 0xFFFFFFFF)
    {
        /* Wait until all ENDPTPRIME bits cleared */
    } /* Endif */

    /* Write 1s to the Flush register */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH, 0xFFFFFFFF);

    if (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]) &
        EHCI_PORTSCX_PORT_RESET)
    {
        usb_dev_ptr->BUS_RESETTING = TRUE;
        usb_dev_ptr->G.USB_STATE = USB_STATE_POWERED;
    }
    else
    {
        /* re-initialize */
        _usb_dci_usbhs_chip_initialize((pointer)usb_dev_ptr);
    } /* Endif */

    /* Inform the application so that it can cancel all previously queued transfers */
    _usb_device_call_service(USB_SERVICE_BUS_RESET,&event);
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_process_suspend
*  Returned Value : None
*  Comments       :
*        Services suspend interrupt
*
*END*-----------------------------------------------------------------*/
void _usb_dci_usbhs_process_suspend
(
      /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;

    USB_EVENT_STRUCT          event;

    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    usb_dev_ptr->USB_DEV_STATE_B4_SUSPEND = usb_dev_ptr->USB_STATE;

    usb_dev_ptr->USB_STATE = USB_STATE_SUSPEND;

    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = handle;
    event.ep_num = (uint_8)USB_UNINITIALIZED_VAL_32;
    event.setup = 0;
    event.direction = 0;
    event.buffer_ptr = (uint_8*)NULL;
    event.len = ZERO_LENGTH;
    /* Inform the upper layers */
    (void)_usb_device_call_service(USB_SERVICE_SLEEP,&event);

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_process_SOF
*  Returned Value : None
*  Comments       :
*        Services SOF interrupt
*
*END*-----------------------------------------------------------------*/
void _usb_dci_usbhs_process_SOF
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_DEV_STATE_STRUCT_PTR                    usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR                       dev_ptr;

    USB_EVENT_STRUCT      event;

    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->DEV_PTR;

    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = handle;
    event.ep_num = (uint_8)USB_UNINITIALIZED_VAL_32;
    event.setup = 0;
    event.direction = 0;
    event.len = sizeof(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_FRINDEX);
    event.buffer_ptr = (uint_8_ptr)USB_mem_alloc_zero(event.len);
    if(event.buffer_ptr == NULL)
    {
        #ifdef _DEV_DEBUG
            printf("memalloc failed in _usb_dci_usbhs_process_SOF\n");
        #endif
        return;
    }

    USB_mem_copy((void*)&(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_FRINDEX),
        event.buffer_ptr, event.len);
    /* Inform the upper layer */
    (void)_usb_device_call_service(USB_SERVICE_SOF,&event);
    USB_mem_free(event.buffer_ptr);
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_process_port_change
*  Returned Value : None
*  Comments       :
*        Services port change detect interrupt
*
*END*-----------------------------------------------------------------*/
void _usb_dci_usbhs_process_port_change
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR dev_ptr;

    USB_EVENT_STRUCT      event;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = handle;
    event.ep_num = (uint_8)USB_UNINITIALIZED_VAL_32;
    event.setup = 0;
    event.direction = 0;

    if (usb_dev_ptr->BUS_RESETTING)
    {
        /* Bus reset operation complete */
        usb_dev_ptr->BUS_RESETTING = FALSE;
    } /* Endif */

    if (!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]) &
        EHCI_PORTSCX_PORT_RESET))
    {
        /* Get the speed */
        if (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]) &
            EHCI_PORTSCX_PORT_HIGH_SPEED)
        {
            usb_dev_ptr->G.SPEED = USB_SPEED_HIGH;
        }
        else
        {
            usb_dev_ptr->G.SPEED = USB_SPEED_FULL;
        } /* Endif */

        event.len = sizeof(usb_dev_ptr->G.SPEED);
        event.buffer_ptr = (uint_8_ptr)USB_mem_alloc_zero(event.len);

        if(event.buffer_ptr == NULL)
        {
            #ifdef _DEV_DEBUG
                printf("memalloc failed in _usb_dci_usbhs_process_port_change\n");
            #endif
            return;
        }

        USB_mem_copy(&(usb_dev_ptr->G.SPEED), event.buffer_ptr,event.len);
        /* Inform the upper layers of the speed of operation */
        USB_mem_free(event.buffer_ptr);
    } /* Endif */

    if (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]) &
        EHCI_PORTSCX_PORT_SUSPEND)
    {
        usb_dev_ptr->G.USB_DEV_STATE_B4_SUSPEND = usb_dev_ptr->G.USB_STATE;
        usb_dev_ptr->G.USB_STATE = USB_STATE_SUSPEND;

        event.len = ZERO_LENGTH;
        event.buffer_ptr = (uint_8*)NULL;
        /* Inform the upper layers */
        (void)_usb_device_call_service(USB_SERVICE_SUSPEND,&event);
    } /* Endif */

    if(!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]) &
        EHCI_PORTSCX_PORT_SUSPEND) &&
        (usb_dev_ptr->G.USB_STATE == USB_STATE_SUSPEND))
    {
        usb_dev_ptr->G.USB_STATE = usb_dev_ptr->G.USB_DEV_STATE_B4_SUSPEND;

        event.len = ZERO_LENGTH;
        event.buffer_ptr = (uint_8*)NULL;
        /* Inform the upper layers */
        (void)_usb_device_call_service(USB_SERVICE_RESUME,&event);

        return;
    } /* Endif */

    usb_dev_ptr->G.USB_STATE = USB_STATE_DEFAULT;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_process_error
*  Returned Value : None
*  Comments       :
*        Services error interrupt
*
*END*-----------------------------------------------------------------*/
void _usb_dci_usbhs_process_error
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_DEV_STATE_STRUCT_PTR  usb_dev_ptr;
    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    /* Increment the error count */
    usb_dev_ptr->ERRORS++;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_isr
*  Returned Value : None
*  Comments       :
*        Services all the VUSB_HS interrupt sources
*
*END*-----------------------------------------------------------------*/
void _usb_dci_usbhs_isr(_usb_device_handle handle)

{   /* Body */
    volatile USB_DEV_STATE_STRUCT_PTR   usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR      dev_ptr;
    uint_32 error;

    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->DEV_PTR;

    error = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_STS) &
        EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_INTR);
        /* Clear all the interrupts occured */
        EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_STS, error);
        if(error & EHCI_STS_RESET)
        {
            /* Print so that user can be notified of reset in general */
            _usb_dci_usbhs_process_reset((pointer)usb_dev_ptr);
        }

        if (error & EHCI_STS_INT)
        {
            _usb_dci_usbhs_process_tr_complete((pointer)usb_dev_ptr);
        }

        if (error & EHCI_STS_PORT_CHANGE)
        {
            _usb_dci_usbhs_process_port_change((pointer)usb_dev_ptr);
        }

        if (error & EHCI_STS_ERR)
        {
            #ifdef _DEV_DEBUG
                printf("USB Error\n");
            #endif
            _usb_dci_usbhs_process_error((pointer)usb_dev_ptr);
        }

        if (error & EHCI_STS_SOF)
        {
            _usb_dci_usbhs_process_SOF((pointer)usb_dev_ptr);
        }

        if (error & EHCI_STS_SUSPEND)
        {
            _usb_dci_usbhs_process_suspend((pointer)usb_dev_ptr);
            return;
        }
} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_set_address
*  Returned Value : None
*  Comments       :
*        Sets the newly assigned device address
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_set_address
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* Address of the device assigned by the host */
    uint_8                     address
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR   usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR            dev_ptr;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* The address bits are past bit 25-31. Set the address */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.DEVICE_ADDR,
        ((uint_32)address << USBHS_ADDRESS_BIT_SHIFT));

    usb_dev_ptr->G.USB_STATE = USB_STATE_ADDRESS;
    return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_get_setup_data
*  Returned Value : None
*  Comments       :
*        Reads the Setup data from the 8-byte setup buffer
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_get_setup_data
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] the Endpoint number */
    uint_8                     ep_num,

    /* [OUT] address of the buffer to read the setup data into */
    uint_8_ptr                  buffer_ptr
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR              usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR                       dev_ptr;
    volatile USBHS_EP_QUEUE_HEAD_STRUCT_PTR             ep_queue_head_ptr;
    boolean  read_safe;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* Get the endpoint queue head */
    ep_queue_head_ptr = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR)
        EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.EP_LIST_ADDR) +
        2*ep_num + USB_RECV;

    /********************************************************************
     CR 1219. Hardware versions 2.3+ have a implementation of tripwire
     semaphore mechanism that requires that we read the contents of
     QH safely by using the semaphore. Read the USBHS document to under
     stand how the code uses the semaphore mechanism. The following are
     the steps in brief

     1. USBCMD Write ‘1’ to Setup Tripwire in register.
     2. Duplicate contents of dQH.StatusBuffer into local software byte
        array.
     3  Read Setup TripWire in register. (if set - continue; if
        cleared goto 1.)
     4. Write '0' to clear Setup Tripwire in register.
     5. Process setup packet using local software byte array copy and
        execute status/handshake phases.
     ********************************************************************/

    /*if semaphore mechanism is used the following code is compiled in*/
    #ifdef TRIP_WIRE
        read_safe = FALSE;
        while(!read_safe)
        {
    #if PSP_HAS_DATA_CACHE
      USB_dcache_invalidate_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
      USB_dcache_invalidate_mlines((void *)ep_queue_head_ptr->SETUP_BUFFER, USB_SETUP_PKT_SIZE);
    #endif

            /*********************************************************
             start with setting the semaphores
             *********************************************************/

            EHCI_MEM_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD,
                EHCI_CMD_SETUP_TRIPWIRE_SET);
            /*********************************************************
             Duplicate the contents of SETUP buffer to our buffer
             Note:On 5329 the data returned is little endian so it needs
             to be byte swapped.Here while copying it is been takencare.
             If you are using this as reference code care should be taken
             while copying the setup packet on your chip.
             *********************************************************/
             #if USBCFG_MEMORY_ENDIANNESS==MQX_BIG_ENDIAN
            buffer_ptr[0]= ep_queue_head_ptr->SETUP_BUFFER[3];
            buffer_ptr[1]= ep_queue_head_ptr->SETUP_BUFFER[2];
            buffer_ptr[2]= ep_queue_head_ptr->SETUP_BUFFER[1];
            buffer_ptr[3]= ep_queue_head_ptr->SETUP_BUFFER[0];
            buffer_ptr[4]= ep_queue_head_ptr->SETUP_BUFFER[7];
            buffer_ptr[5]= ep_queue_head_ptr->SETUP_BUFFER[6];
            buffer_ptr[6]= ep_queue_head_ptr->SETUP_BUFFER[5];
            buffer_ptr[7]= ep_queue_head_ptr->SETUP_BUFFER[4];
            #else
            _mem_copy((pointer)ep_queue_head_ptr->SETUP_BUFFER,buffer_ptr, 8);
            #endif
            /*********************************************************
             If setup tripwire semaphore is cleared by hardware it means
             that we have a danger and we need to restart.
             else we can exit out of loop safely.
             *********************************************************/
            if(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD) &
                EHCI_CMD_SETUP_TRIPWIRE_SET)
            {
                /* we can proceed exiting out of loop*/
                read_safe = TRUE;
            }
        }

        /*********************************************************
         Clear the semaphore bit now
         *********************************************************/
        EHCI_MEM_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD,
            EHCI_CMD_SETUP_TRIPWIRE_SET);
    #else   /*when semaphore is not used */
        /*********************************************************
         Duplicate the contents of SETUP buffer to our buffer
         Note:On 5329 the data returned is little endian so it needs
         to be byte swapped.Here while copying it is been takencare.
         If you are using this as reference code care should be taken
         while copying the setup packet on your chip.
         *********************************************************/
        buffer_ptr[0]= ep_queue_head_ptr->SETUP_BUFFER[3];
        buffer_ptr[1]= ep_queue_head_ptr->SETUP_BUFFER[2];
        buffer_ptr[2]= ep_queue_head_ptr->SETUP_BUFFER[1];
        buffer_ptr[3]= ep_queue_head_ptr->SETUP_BUFFER[0];
        buffer_ptr[4]= ep_queue_head_ptr->SETUP_BUFFER[7];
        buffer_ptr[5]= ep_queue_head_ptr->SETUP_BUFFER[6];
        buffer_ptr[6]= ep_queue_head_ptr->SETUP_BUFFER[5];
        buffer_ptr[7]= ep_queue_head_ptr->SETUP_BUFFER[4];
    #endif

    /* Clear the bit in the ENDPTSETUPSTAT */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPT_SETUP_STAT,
        (uint_32)(1 << ep_num));

    return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_init_endpoint
*  Returned Value : None
*  Comments       :
*        Initializes the specified endpoint and the endpoint queue head
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_init_endpoint
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] the transaction descriptor address */
    XD_STRUCT_PTR              xd_p
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR       usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR                dev_ptr;
    volatile USBHS_EP_QUEUE_HEAD_STRUCT _PTR_    ep_queue_head_ptr;
    uint_32                                      bit_pos;
    EHCI_XD_STRUCT_PTR                           xd_ptr = (EHCI_XD_STRUCT_PTR)xd_p;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    xd_ptr->MAX_PKTS_PER_UFRAME =
      (uint_8)(((uint_8)xd_ptr->G.DONT_ZERO_TERMINATE & USB_MAX_PKTS_PER_UFRAME) >> 1);

    if((xd_ptr->G.EP_TYPE > USB_INTERRUPT_PIPE) ||
        (xd_ptr->G.BDIRECTION > USB_SEND))
    {
        return USBERR_EP_INIT_FAILED;
    }

    /* before initializing cancel all transfers on EP as there may be calls
       for endpoint initialization more than once. This will free any allocated
       queue */
    (void)_usb_device_cancel_transfer(handle, xd_ptr->G.EP_NUM, xd_ptr->G.BDIRECTION);

    /* Get the endpoint queue head address */
    ep_queue_head_ptr = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR)
        EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.EP_LIST_ADDR) +
        2 * xd_ptr->G.EP_NUM + xd_ptr->G.BDIRECTION;

    bit_pos = (uint_32)(1 << (16 * xd_ptr->G.BDIRECTION + xd_ptr->G.EP_NUM));

    /* Check if the Endpoint is Primed */
    if((!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME) & bit_pos))
      &&
      (!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos)))
    {
        /* Set the max packet length, interrupt on Setup and Mult fields */
        if (xd_ptr->G.EP_TYPE == USB_ISOCHRONOUS_PIPE)
        {
            /* Mult bit should be set for isochronous endpoints */
            EHCI_MEM_WRITE(ep_queue_head_ptr->MAX_PKT_LENGTH,(uint_32)((xd_ptr->G.WMAXPACKETSIZE << 16) |
               ((xd_ptr->MAX_PKTS_PER_UFRAME ? xd_ptr->MAX_PKTS_PER_UFRAME : 1)
                << VUSB_EP_QUEUE_HEAD_MULT_POS)));
            #if PSP_HAS_DATA_CACHE
                USB_dcache_flush_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
            #endif
        }
        else
        {
            if (xd_ptr->G.EP_TYPE != USB_CONTROL_PIPE)
            {
                EHCI_MEM_WRITE(ep_queue_head_ptr->MAX_PKT_LENGTH, (uint_32)
                    ((xd_ptr->G.WMAXPACKETSIZE << 16) |
                     (xd_ptr->G.DONT_ZERO_TERMINATE ?
                     VUSB_EP_QUEUE_HEAD_ZERO_LEN_TER_SEL : 0)));
                if(xd_ptr->G.BDIRECTION == USB_RECV)
                {
                    g_ep_recv_buff_ptr[xd_ptr->G.EP_NUM] =
                        (uint_8*)USB_mem_alloc_uncached_zero(xd_ptr->G.WMAXPACKETSIZE);

                    if(g_ep_recv_buff_ptr[xd_ptr->G.EP_NUM] == NULL)
                    {
                        #ifdef _DEV_DEBUG
                            printf("memalloc failed in _usb_dci_usbhs_init_endpoint\n");
                        #endif
                        return USBERR_ALLOC;
                    }

                    (void)_usb_device_recv_data(handle, xd_ptr->G.EP_NUM, g_ep_recv_buff_ptr[xd_ptr->G.EP_NUM], xd_ptr->G.WMAXPACKETSIZE);
                }
            }
            else
            {
                EHCI_MEM_WRITE(ep_queue_head_ptr->MAX_PKT_LENGTH, (uint_32)
                    ((xd_ptr->G.WMAXPACKETSIZE << 16) | VUSB_EP_QUEUE_HEAD_IOS));
               #if PSP_HAS_DATA_CACHE
                    USB_dcache_flush_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
                #endif
            } /* Endif */
        } /* Endif */

        /* Enable the endpoint for Rx and Tx and set the endpoint type */
        EHCI_MEM_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[xd_ptr->G.EP_NUM],
            ((xd_ptr->G.BDIRECTION ? (EHCI_EPCTRL_TX_ENABLE |
            EHCI_EPCTRL_TX_DATA_TOGGLE_RST) :
            (EHCI_EPCTRL_RX_ENABLE | EHCI_EPCTRL_RX_DATA_TOGGLE_RST)) |
            (xd_ptr->G.EP_TYPE << (xd_ptr->G.BDIRECTION ?
            EHCI_EPCTRL_TX_EP_TYPE_SHIFT : EHCI_EPCTRL_RX_EP_TYPE_SHIFT))));
    }
    else
    {
        return USBERR_EP_INIT_FAILED;
    } /* Endif */

    return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_deinit_endpoint
*  Returned Value : None
*  Comments       :
*        Disables the specified endpoint and the endpoint queue head
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_deinit_endpoint
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] the Endpoint number */
    uint_8                     ep_num,

    /* [IN] direction */
    uint_8                     direction
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR             usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR                      dev_ptr;
    volatile USBHS_EP_QUEUE_HEAD_STRUCT _PTR_          ep_queue_head_ptr;
    uint_32                                      bit_pos;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /*before de-initializing cancel all transfers on EP */
    (void)_usb_device_cancel_transfer(handle, ep_num, direction);

    /* Ger the endpoint queue head address */
    ep_queue_head_ptr = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR)
        EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.EP_LIST_ADDR) +
        (2*ep_num + direction);

    #if PSP_HAS_DATA_CACHE
        USB_dcache_invalidate_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
    #endif

    bit_pos = (uint_32)(1 << (16 * direction + ep_num));

    /* Check if the Endpoint is Primed */
    if((!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME) & bit_pos))
      &&
      (!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos)))
    {
        /* Reset the max packet length and the interrupt on Setup */
        EHCI_MEM_WRITE(ep_queue_head_ptr->MAX_PKT_LENGTH,0);

        /* Disable the endpoint for Rx or Tx and reset the endpoint type */
        EHCI_MEM_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num],
           (direction ? (EHCI_EPCTRL_TX_ENABLE|EHCI_EPCTRL_TX_TYPE):(EHCI_EPCTRL_RX_ENABLE|EHCI_EPCTRL_RX_TYPE)));

        /* TODO: flush buffers. See EHCI EPFLUSH register */
    }
    else
    {
        return USBERR_EP_DEINIT_FAILED;
    }

    if((ep_num != USB_CONTROL_ENDPOINT)&&(direction == USB_RECV))
    {
        USB_mem_free(g_ep_recv_buff_ptr[ep_num]);
    }

    return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_get_transfer_status
*  Returned Value : USB_OK or error code
*  Comments       :
*        Gets the status of a transfer
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_get_transfer_status
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] the Endpoint number */
    uint_8                     ep_num,

    /* [IN] direction */
    uint_8                     direction
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr;
    volatile USBHS_EP_TR_STRUCT_PTR        dTD_ptr;
    volatile EHCI_XD_STRUCT_PTR            xd_ptr;
    uint_8                                 error;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;

    /* Unlink the dTD */
    dTD_ptr = usb_dev_ptr->EP_DTD_HEADS[2*ep_num + direction];

    if (dTD_ptr)
    {
        /* Get the transfer descriptor for the dTD */
        xd_ptr = (EHCI_XD_STRUCT_PTR)dTD_ptr->SCRATCH_PTR->XD_FOR_THIS_DTD;
        error = xd_ptr->G.BSTATUS;
    }
    else
    {
        error = USB_STATUS_IDLE;
    }

    return (error);
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_cancel_transfer
*  Returned Value : USB_OK or error code
*  Comments       :
*        Cancels a transfer
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_cancel_transfer
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] the Endpoint number */
    uint_8                     ep_num,

    /* [IN] direction */
    uint_8                     direction
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR    usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR             dev_ptr;
    volatile USBHS_EP_TR_STRUCT_PTR           dTD_ptr, check_dTD_ptr;
    volatile USBHS_EP_QUEUE_HEAD_STRUCT_PTR   ep_queue_head_ptr;
    volatile EHCI_XD_STRUCT_PTR               xd_ptr;
    uint_32                                   temp, bit_pos;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    bit_pos = (uint_32)(1 << (16 * direction + ep_num));
    temp = (uint_32)(2*ep_num + direction);

    ep_queue_head_ptr = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR)
        EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.EP_LIST_ADDR) +
        temp;

    #if PSP_HAS_DATA_CACHE
        USB_dcache_invalidate_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
    #endif

    /* Unlink the dTD */
    dTD_ptr = usb_dev_ptr->EP_DTD_HEADS[temp];

    if (dTD_ptr)
    {
        check_dTD_ptr = (USBHS_EP_TR_STRUCT_PTR) \
            ((uint_32)EHCI_MEM_READ(dTD_ptr->NEXT_TR_ELEM_PTR) &
            USBHS_TD_ADDR_MASK);

        if (EHCI_MEM_READ(dTD_ptr->SIZE_IOC_STS & USBHS_TD_STATUS_ACTIVE))
        {
            /* Flushing will halt the pipe */
            /* Write 1 to the Flush register */
            EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH,bit_pos);
            /* Wait until flushing completed */
            while (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH) & bit_pos)
            {
                /* ENDPTFLUSH bit should be cleared to indicate this
                   operation is complete */
            }

            while (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos)
            {
                /* Write 1 to the Flush register */
                EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH,bit_pos);

                /* Wait until flushing completed */
                while (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH) & bit_pos)
                {
                    /* ENDPTFLUSH bit should be cleared to indicate this
                       operation is complete */
                }
            }
        }

        /* Retire the current dTD */
        EHCI_MEM_WRITE(dTD_ptr->SIZE_IOC_STS, 0);
        EHCI_MEM_WRITE(dTD_ptr->NEXT_TR_ELEM_PTR, USBHS_TD_NEXT_TERMINATE);

        /* The transfer descriptor for this dTD */
        xd_ptr = (EHCI_XD_STRUCT_PTR)dTD_ptr->SCRATCH_PTR->XD_FOR_THIS_DTD;
        dTD_ptr->SCRATCH_PTR->PRIVATE = (pointer) usb_dev_ptr;
        /* Free the dTD */
        _usb_dci_usbhs_free_dTD(usb_dev_ptr, (pointer)dTD_ptr);

        /* Update the dTD head and tail for specific endpoint/direction */
        if (!check_dTD_ptr)
        {
            usb_dev_ptr->EP_DTD_HEADS[temp] = NULL;
            usb_dev_ptr->EP_DTD_TAILS[temp] = NULL;

            if (xd_ptr)
            {
                xd_ptr->G.SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
                /* Free the transfer descriptor */
                _usb_device_free_XD(usb_dev_ptr, (pointer)xd_ptr);
            }

            /* No other transfers on the queue */
            EHCI_MEM_WRITE(ep_queue_head_ptr->NEXT_DTD_PTR, VUSB_EP_QUEUE_HEAD_NEXT_TERMINATE);
            EHCI_MEM_WRITE(ep_queue_head_ptr->SIZE_IOC_INT_STS,0);
        }
        else
        {
            usb_dev_ptr->EP_DTD_HEADS[temp] = check_dTD_ptr;

            if (xd_ptr)
            {
                if ((uint_32)check_dTD_ptr->SCRATCH_PTR->\
                    XD_FOR_THIS_DTD != (uint_32)xd_ptr)
                {
                    xd_ptr->G.SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
                    /* Free the transfer descriptor */
                    _usb_device_free_XD(usb_dev_ptr, (pointer)xd_ptr);
                }
            }

            if (EHCI_MEM_READ(check_dTD_ptr->SIZE_IOC_STS) & USBHS_TD_STATUS_ACTIVE)
            {
                /* Start CR 1015 */
                /* Prime the Endpoint */
                EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME, bit_pos);

                if (!(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos))
                {
                    while(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME) & bit_pos)
                    {
                        /* Wait for the ENDPTPRIME to go to zero */
                    }

                    if (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos)
                    {
                        /* The endpoint was not not primed so no other
                        transfers on the queue */
                        return USB_OK;
                    }
                }
                else
                {
                    return USB_OK;
                }

                /* No other transfers on the queue */
                EHCI_MEM_WRITE(ep_queue_head_ptr->NEXT_DTD_PTR, (uint_32)check_dTD_ptr);
                EHCI_MEM_WRITE(ep_queue_head_ptr->SIZE_IOC_INT_STS , 0);

                /* Prime the Endpoint */
                EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME,bit_pos);
            }
        }
    }

    return USB_OK;
    /* End CR 1015 */
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_shutdown
*  Returned Value : None
*  Comments       :
*        Shuts down the VUSB_HS Device
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_shutdown
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR              usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR                       dev_ptr;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* Disable interrupts */
    EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_INTR,
        (EHCI_INTR_INT_EN | EHCI_INTR_ERR_INT_EN | EHCI_INTR_PORT_CHANGE_DETECT_EN | EHCI_INTR_RESET_EN));

    /* Reset the Run the bit in the command register to stop VUSB */
    EHCI_REG_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD,EHCI_CMD_RUN_STOP);

    /* Reset the controller to get default values */
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_CMD , EHCI_CMD_CTRL_RESET);

    USB_mem_free((pointer)usb_dev_ptr->DRIVER_MEMORY);

    return USB_OK;
} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_assert_resume
*  Returned Value : None
*  Comments       :
*        Resume signalling for remote wakeup
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_assert_resume
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR          dev_ptr;
    uint_32                                temp;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* Assert the Resume signal */
    temp = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]);
    temp &= ~EHCI_PORTSCX_W1C_BITS;
    temp |= EHCI_PORTSCX_PORT_FORCE_RESUME;
    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0] , temp);

    /* Port change interrupt will be asserted at the end of resume
       operation */

   return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_stall_endpoint
*  Returned Value : None
*  Comments       :
*        Stalls the specified endpoint
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_stall_endpoint
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] the Endpoint number */
    uint_8                     ep_num,

    /* [IN] direction */
    uint_8                     direction
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR    usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR             dev_ptr;
    volatile USBHS_EP_QUEUE_HEAD_STRUCT _PTR_ ep_queue_head_ptr;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* Get the endpoint queue head address */
    ep_queue_head_ptr = (USBHS_EP_QUEUE_HEAD_STRUCT_PTR)
        EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.EP_LIST_ADDR) + 2 * ep_num + direction;

    #if PSP_HAS_DATA_CACHE
        USB_dcache_flush_mlines((void *)ep_queue_head_ptr, sizeof(USBHS_EP_QUEUE_HEAD_STRUCT));
    #endif

    /* Stall the endpoint for Rx or Tx and set the endpoint type */
    if (EHCI_MEM_READ(ep_queue_head_ptr->MAX_PKT_LENGTH) & VUSB_EP_QUEUE_HEAD_IOS)
    {
        /* This is a control endpoint so STALL both directions */
        EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num],
            (EHCI_EPCTRL_TX_EP_STALL | EHCI_EPCTRL_RX_EP_STALL));
    }
    else
    {
        EHCI_REG_SET_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num],
            (direction ? EHCI_EPCTRL_TX_EP_STALL:EHCI_EPCTRL_RX_EP_STALL));
    }

    return USB_OK;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_usbhs_unstall_endpoint
*  Returned Value : None
*  Comments       :
*        Unstall the specified endpoint in the specified direction
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_unstall_endpoint
(
    /* [IN] the USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] the Endpoint number */
    uint_8                     ep_num,

    /* [IN] direction */
    uint_8                     direction
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR  usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR     dev_ptr;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    /* Enable the endpoint for Rx or Tx and set the endpoint type */
    EHCI_MEM_CLEAR_BITS(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep_num],
        (direction ? EHCI_EPCTRL_TX_EP_STALL : EHCI_EPCTRL_RX_EP_STALL));

    return USB_OK;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_dci_usbhs_get_endpoint_status
* Returned Value : None
* Comments       :
*     Gets the endpoint status
*
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_get_endpoint_status
(
    /* [IN] Handle to the USB device */
    _usb_device_handle   handle,

    /* [IN] Endpoint to get */
    uint_8               ep,
    /* [OUT] Status to get */
    uint_16_ptr error
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR          dev_ptr;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    *error = (uint_16)((EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[ep]) &
        (EHCI_EPCTRL_TX_EP_STALL | EHCI_EPCTRL_RX_EP_STALL)) ? 1 : 0);

    return USB_OK;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_dci_usbhs_set_test_mode
* Returned Value : None
* Comments       :
*     sets/resets the test mode
*
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_set_test_mode
(
    /* [IN] Handle to the USB device */
    _usb_device_handle handle,

    /* [IN] Test mode */
    uint_16 test_mode
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR       usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR                dev_ptr;
    uint_32                                      temp;

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    temp = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[0]);

    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTCTRLX[0],
        (temp | EHCI_EPCTRL_TX_DATA_TOGGLE_RST));

    if (test_mode == USB_TEST_MODE_TEST_PACKET)
    {
        _usb_device_send_data(handle, 0, test_packet,
            USB_TEST_MODE_TEST_PACKET_LENGTH);
    } /* Endif */

    temp = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0]);
    temp &= ~EHCI_PORTSCX_W1C_BITS;

    EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.PORTSCX[0], (temp | ((uint_32)test_mode << 8)));

    return USB_OK;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_dci_usbhs_set_endpoint_status
* Returned Value : None
* Comments       :
*     Sets the endpoint registers e.g. to enable TX, RX, control
*
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_dci_usbhs_set_endpoint_status
(
    /* [IN] Handle to the USB device */
    _usb_device_handle   handle,

    /* [IN] Endpoint to set */
    uint_8               component,

    /* [IN] Endpoint characteristics */
    uint_16               setting
)
{   /* Body */
    volatile USB_EHCI_DEV_STATE_STRUCT_PTR  usb_dev_ptr;
    volatile USBHS_REG_STRUCT_PTR     dev_ptr;
    uint_8 error = USBERR_ERROR;
    uint_8 ep_num = (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK);
    uint_8 direction = (uint_8)((component>>COMPONENT_PREPARE_SHIFT) & 0x01);

    if (ep_num > USB_MAX_ENDPOINTS) {
        return error;
    }

    usb_dev_ptr = (USB_EHCI_DEV_STATE_STRUCT_PTR)handle;
    dev_ptr = (USBHS_REG_STRUCT_PTR)usb_dev_ptr->G.DEV_PTR;

    if(setting == USB_STATUS_STALLED)
    {
        error = _usb_device_stall_endpoint(handle, ep_num, direction);

    }
    else if(setting == USB_STATUS_IDLE)
    {
        error = _usb_device_unstall_endpoint(handle, ep_num, direction);
    } /* Endif */

    return USB_OK;
} /* EndBody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/rtc.h<|end_filename|>
/**HEADER***********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
********************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************
*
* $FileName: rtc.h$
* $Version : 3.8.28.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This include file is used to provide constant and structure definitions
*   common for RTC module
*
*END***************************************************************************/

#ifndef __rtc_h__
#define __rtc_h__ 1


#define RTC_RTCISR_SW       DEVSPEC_RTC_RTCISR_SW
#define RTC_RTCISR_ALM      DEVSPEC_RTC_RTCISR_ALM
#define RTC_RTCIENR_SW      DEVSPEC_RTC_RTCIENR_SW
#define RTC_RTCIENR_ALM     DEVSPEC_RTC_RTCIENR_ALM
#ifndef RTC_INT_ALL_MASK
#define RTC_INT_ALL_MASK    DEVSPEC_RTC_INT_ALL_MASK
#endif

#ifndef RTC_INVALID_TIME
#define  RTC_INVALID_TIME  (RTC_ERROR_BASE | 0x01)
#endif

#define RTC_INIT_FLAG_CLEAR     (1 << 0)
#define RTC_INIT_FLAG_RESET     (1 << 1)
#define RTC_INIT_FLAG_ENABLE    (1 << 2)

#ifdef __cplusplus
extern "C" {
#endif

pointer                      _bsp_get_rtc_base_address (void);
PSP_INTERRUPT_TABLE_INDEX    _bsp_get_rtc_vector (void);

_mqx_int _rtc_set_time_mqxd (DATE_STRUCT_PTR time);
void     _rtc_get_time_mqxd (DATE_STRUCT_PTR time);
_mqx_int _rtc_set_alarm_mqxd (DATE_STRUCT_PTR time);
void     _rtc_get_alarm_mqxd (DATE_STRUCT_PTR time);

uint_32  _rtc_init (uint_32 flags);
void     _rtc_isr (pointer ptr);
uint_32  _rtc_int_install (INT_ISR_FPTR isr);
uint_32  _rtc_int_enable (boolean enable, uint_32 bitmask);
void     _rtc_clear_requests (uint_32 bitmask);
uint_32  _rtc_get_status (void);
void     _rtc_set_time (RTC_TIME_STRUCT_PTR time);
void     _rtc_get_time (RTC_TIME_STRUCT_PTR time);
void     _rtc_set_alarm (RTC_TIME_STRUCT_PTR time);
void     _rtc_get_alarm (RTC_TIME_STRUCT_PTR time);
void     _rtc_set_stopwatch (uint_32 minutes);
uint_32  _rtc_get_stopwatch (void);

void     _rtc_time_to_mqx_time (RTC_TIME_STRUCT_PTR rtc_time, TIME_STRUCT_PTR mqx_time);
void     _rtc_time_from_mqx_time (TIME_STRUCT_PTR mqx_time, RTC_TIME_STRUCT_PTR rtc_time);
void     _rtc_time_to_mqx_date (RTC_TIME_STRUCT_PTR rtc_time, DATE_STRUCT_PTR mqx_date);
void     _rtc_time_from_mqx_date (DATE_STRUCT_PTR mqx_date, RTC_TIME_STRUCT_PTR rtc_time);
_mqx_int _rtc_sync_with_mqx (boolean update_mqx);

#ifdef __cplusplus
}
#endif

#endif /* __rtc_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb/usb_install.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_install.c$
* $Version : 3.8.3.0$
* $Date    : Aug-21-2012$
*
* Comments:
*
*   This file contains board-specific USB initialization functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_driver_install
*  Returned Value : None
*  Comments       :
*        Installs the device
*END*-----------------------------------------------------------------*/
_mqx_int _usb_device_driver_install
(
   /* [IN] address if the callback functions structure */
   USB_DEV_IF_STRUCT_PTR    usb_if
)
{ /* Body */
   USB_DEV_IF_STRUCT_PTR usb_c;
   _mqx_int      i, f;
   
   /* Check usb_if structure */
   if (usb_if == NULL) {
         return IO_ERROR;
   }
   
   usb_c = _mqx_get_io_component_handle(IO_USB_COMPONENT);
   
   if (!usb_c) {
      usb_c = _mem_alloc_zero(USBCFG_MAX_DRIVERS * sizeof(USB_DEV_IF_STRUCT));
      
      if (!usb_c) {
         return IO_ERROR;
      } /* Endif */
      /* TODO: change memory type */
      //_mem_set_type(usb_c, MEM_TYPE_USB_CALLBACK_STRUCT);
      _mem_transfer(usb_c, _task_get_id(), _mqx_get_system_task_id()); //this should return failure value anytime
	  _mqx_set_io_component_handle(IO_USB_COMPONENT, (pointer) usb_c);
      i = USBCFG_MAX_DRIVERS;
   }
   else {
      /* Find out if the interface has not been already installed */
      for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
         if (usb_c[i].DEV_INIT_PARAM == usb_if->DEV_INIT_PARAM) {
            /* The interface was already installed, skip search */
            break;
         }
      }
   }

   if (i == USBCFG_MAX_DRIVERS) {
      /* The interface was not installed yet, search for a free position. */
      for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
         if (usb_c[i].DEV_INIT_PARAM == NULL) {
            usb_c[i].DEV_IF = usb_if->DEV_IF;
            usb_c[i].DEV_INIT_PARAM = usb_if->DEV_INIT_PARAM;
            usb_c[i].DEV_HANDLE = NULL; /* not initialized yet */
            break;
         }
      }
   }
   else {
      /* The interface was already installed */
   }
   
   if (i == USBCFG_MAX_DRIVERS) {
      /* Not enough space to install interface */
      return IO_ERROR;
   }

   return MQX_OK;

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dev_driver_uninstall
*  Returned Value : USB_OK or error code
*  Comments       :
*        Uninstalls the device
*END*-----------------------------------------------------------------*/
_mqx_int _usb_device_driver_uninstall
   (
		void
   )
{ /* Body */
   pointer callback_struct_table_ptr;
   callback_struct_table_ptr = _mqx_get_io_component_handle(IO_USB_COMPONENT);
   
   if (callback_struct_table_ptr) 
   {
      _mem_free(callback_struct_table_ptr); 
   }
   else
   {
      return IO_ERROR; 
   }
   /* Endif */
   _mqx_set_io_component_handle(IO_USB_COMPONENT, NULL);
   return MQX_OK;

} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_driver_install
*  Returned Value : None
*  Comments       :
*        Installs the host controller
*END*-----------------------------------------------------------------*/
_mqx_int _usb_host_driver_install
(
   /* [IN] address if the callback functions structure */
   USB_HOST_IF_STRUCT_PTR    usb_if
)
{ /* Body */
   USB_HOST_IF_STRUCT_PTR usb_c;
   _mqx_int      i, f;
   
   /* Check usb_if structure */
   if (usb_if == NULL) {
         return IO_ERROR;
   }
   
   usb_c = _mqx_get_io_component_handle(IO_USB_COMPONENT);
   
   if (!usb_c) {
      usb_c = _mem_alloc_zero(USBCFG_MAX_DRIVERS * sizeof(USB_HOST_IF_STRUCT));
      
      if (!usb_c) {
         return IO_ERROR;
      } /* Endif */
      /* TODO: change memory type */
      //_mem_set_type(usb_c, MEM_TYPE_USB_CALLBACK_STRUCT);
      _mem_transfer(usb_c, _task_get_id(), _mqx_get_system_task_id()); //this should return failure value anytime
      _mqx_set_io_component_handle(IO_USB_COMPONENT, (pointer) usb_c);
      i = USBCFG_MAX_DRIVERS;
   }
   else {
      /* Find out if the interface has not been already installed */
      for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
         if (usb_c[i].HOST_INIT_PARAM == usb_if->HOST_INIT_PARAM) {
            /* The interface was already installed, skip search */
            break;
         }
      }
   }

   if (i == USBCFG_MAX_DRIVERS) {
      /* The interface was not installed yet, search for a free position. */
      for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
         if (usb_c[i].HOST_INIT_PARAM == NULL) {
            usb_c[i].HOST_IF = usb_if->HOST_IF;
            usb_c[i].HOST_INIT_PARAM = usb_if->HOST_INIT_PARAM;
            usb_c[i].HOST_HANDLE = NULL; /* not initialized yet */
            break;
         }
      }
   }
   else {
      /* The interface was already installed */
   }
   
   if (i == USBCFG_MAX_DRIVERS) {
      /* Not enough space to install interface */
      return IO_ERROR;
   }

   return MQX_OK;

} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_get_init
*  Returned Value : None
*  Comments       :
*        Gets the init parameters for the driver
*END*-----------------------------------------------------------------*/
pointer _usb_host_get_init
(
   /* [IN] address if the callback functions structure */
   pointer    host_handle
)
{ /* Body */
   USB_HOST_IF_STRUCT_PTR usb_c;
   pointer retval = NULL;
   int i;
   
   usb_c = _mqx_get_io_component_handle(IO_USB_COMPONENT);
   
   if (usb_c) {
      /* Find out if the interface has not been already installed */
      for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
         if (usb_c[i].HOST_HANDLE == host_handle) {
            retval = usb_c[i].HOST_INIT_PARAM;
            break;
         }
      }
   }

   return retval;

} /* EndBody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/rtcscmd.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcscmd.c$
* $Version : 3.6.14.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the interface functions to the
*   RTCS Communication Library.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "socket.h"
#include "ip_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_create
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Initialize RTCS.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_create
   (
      void
   )
{ /* Body */
   RTCS_DATA_PTR              RTCS_data_ptr;
   SOCKET_CONFIG_STRUCT_PTR   socket_cfg_ptr;
   uint_32                    error;

   /*
   ** Check and see if this is the first time we have initialized,
   */
   if (RTCS_get_data() != NULL) {
      return RTCSERR_INITIALIZED;
   } 
//
   RTCS_data_ptr = RTCS_mem_alloc_system_zero(sizeof(RTCS_DATA));

   if (RTCS_data_ptr == NULL)  {
      error = RTCSERR_OUT_OF_MEMORY;
   } else {

   _mem_set_type(RTCS_data_ptr, MEM_TYPE_RTCS_DATA);

   RTCS_set_data(RTCS_data_ptr);

   /*
   ** Initialize socket state
   */
   socket_cfg_ptr = RTCS_mem_alloc_system_zero(sizeof(SOCKET_CONFIG_STRUCT));

      if (socket_cfg_ptr == NULL)  {
         error =  RTCSERR_OUT_OF_MEMORY;
      } else {
         _mem_set_type(socket_cfg_ptr, MEM_TYPE_SOCKET_CONFIG_STRUCT);
      
         socket_cfg_ptr->INITIALIZED = TRUE;
         socket_cfg_ptr->SOCKET_HEAD = NULL;
         socket_cfg_ptr->SOCKET_TAIL = NULL;
         RTCS_mutex_init(&socket_cfg_ptr->SOCK_MUTEX);
         RTCS_setcfg(SOCKET, socket_cfg_ptr);

   /*
   ** Initialize global data
   */
   _IP_forward    = FALSE;
   _TCP_bypass_rx = FALSE;
   _TCP_bypass_tx = FALSE;

   RTCS_data_ptr->VERSION            = RTCS_VERSION;
#if RTCSCFG_LOG_SOCKET_API||RTCSCFG_LOG_PCB
   RTCS_data_ptr->RTCS_LOG_PROTCOUNT = RTCSLOG_PROT_MAX;
   RTCSLOG_disable(RTCS_LOGCTRL_ALL);
#endif
   RTCS_data_ptr->TCPIP_qid = RTCS_msgq_get_id(0,TCPIP_QUEUE);

         /*
         ** Create a pool of buffers for use in communicating to the TCP/IP task.
         */
         RTCS_data_ptr->TCPIP_msg_pool = RTCS_msgpool_create(sizeof(TCPIP_MESSAGE),
            _RTCS_msgpool_init, _RTCS_msgpool_grow, _RTCS_msgpool_max);
         if (RTCS_data_ptr->TCPIP_msg_pool == MSGPOOL_NULL_POOL_ID) {
            RTCS_log_error( ERROR_TCPIP, RTCSERR_CREATE_POOL_FAILED, 0, 0, 0);
            error =  RTCSERR_CREATE_POOL_FAILED;
         } else {
            /*
            ** Create the socket partition
            */
            RTCS_data_ptr->RTCS_socket_partition = RTCS_part_create(sizeof(SOCKET_STRUCT),
              _RTCS_socket_part_init, _RTCS_socket_part_grow, _RTCS_socket_part_max, NULL, NULL);
            if (RTCS_data_ptr->RTCS_socket_partition == 0) {
               RTCS_log_error(ERROR_RTCS, RTCSERR_CREATE_PARTITION_FAILED, 0, 0, 0);
               error = RTCSERR_CREATE_PARTITION_FAILED;
            } else {
               /*
               ** Create TCPIP task
               */
               error = RTCS_task_create("TCP/IP", _RTCSTASK_priority, _RTCSTASK_stacksize, TCPIP_task, NULL);
               if (error) {
                  RTCS_part_destroy(RTCS_data_ptr->RTCS_socket_partition);
               }
            }
            if (error) {
               RTCS_msgpool_destroy( RTCS_data_ptr->TCPIP_msg_pool );
            }     
         }
         if (error) {
            RTCS_setcfg(SOCKET, NULL);
            _mem_free(socket_cfg_ptr);
         }
      }
      if (error) {
         RTCS_set_data(NULL);
         _mem_free(RTCS_data_ptr);
      }
   }
   
   return error;
            
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_cmd_issue
* Returned Values : uint_32 (error code)
* Comments        :
*     Issue a command to the TCP/IP task
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_cmd_issue
   (
      TCPIP_PARM_PTR    parm_ptr,
      void (_CODE_PTR_  command)(pointer)
   )
{ /* Body */
   RTCS_DATA_PTR        RTCS_data_ptr;
   TCPIP_MESSAGE_PTR    message;

   RTCS_data_ptr = RTCS_get_data();

   message = RTCS_msg_alloc(RTCS_data_ptr->TCPIP_msg_pool);
   if (message == NULL) {
      parm_ptr->ERROR = RTCSERR_OUT_OF_BUFFERS;
   } else {
      parm_ptr->ERROR = RTCS_OK;
      parm_ptr->SYNC  = _task_get_td(0);

      message->HEAD.TARGET_QID = RTCS_data_ptr->TCPIP_qid;
      message->HEAD.SOURCE_QID = 0;
      message->HEAD.SIZE = sizeof(*message);
      message->COMMAND = command;
      message->DATA = parm_ptr;

      if (!RTCS_msgq_send_blocked(message, RTCS_data_ptr->TCPIP_msg_pool)) {
         parm_ptr->ERROR = RTCSERR_SEND_FAILED;
      } /* Endif */

   } /* Endif */

   return parm_ptr->ERROR;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_cmd_internal
* Returned Values : uint_32 (error code)
* Comments        :
*     Issue a command from within the TCP/IP task
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_cmd_internal
   (
      TCPIP_PARM_PTR    parm_ptr,
      void (_CODE_PTR_  command)(pointer)
   )
{ /* Body */

   parm_ptr->ERROR = RTCS_OK;
   parm_ptr->SYNC  = NULL;

   command(parm_ptr);

   return parm_ptr->ERROR;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_cmd_smartissue
* Returned Values : uint_32 (error code)
* Comments        :
*     Issue a command from any context
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_cmd_smartissue
   (
      TCPIP_PARM_PTR    parm_ptr,
      void (_CODE_PTR_  command)(pointer)
   )
{ /* Body */
   RTCS_DATA_PTR        RTCS_data_ptr;

   RTCS_data_ptr = RTCS_get_data();

   if (RTCS_task_getid() == RTCS_data_ptr->TCPIP_TASKID) {
      return RTCS_cmd_internal(parm_ptr, command);
   } else {
      return RTCS_cmd_issue(parm_ptr, command);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_cmd_complete
* Returned Values : void
* Comments        :
*     Unblocks an application following successful completion of a command.
*
*END*-----------------------------------------------------------------*/

void RTCS_cmd_complete
   (
      TCPIP_PARM_PTR    parm_ptr,
      uint_32           error
   )
{ /* Body */

   if (error) {
      parm_ptr->ERROR = error;
   } /* Endif */

   if (parm_ptr->SYNC) {
      _task_ready(parm_ptr->SYNC);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_cmd_service
* Returned Values : TRUE on success
* Comments        :
*     Issue a nonblocking command to the TCP/IP task
*
*END*-----------------------------------------------------------------*/

boolean RTCS_cmd_service
   (
      RTCSPCB_PTR       pcb,
      void (_CODE_PTR_  command)(pointer)
   )
{ /* Body */
   RTCS_DATA_PTR        RTCS_data_ptr;
   TCPIP_MESSAGE_PTR    message;

   RTCS_data_ptr = RTCS_get_data();

   message = RTCS_msg_alloc(RTCS_data_ptr->TCPIP_msg_pool);
   if (message == NULL) {
      return FALSE;
   } /* Endif */

   message->HEAD.TARGET_QID = RTCS_data_ptr->TCPIP_qid;
   message->HEAD.SOURCE_QID = 0;
   message->HEAD.SIZE = sizeof(*message);
   message->COMMAND = command;
   message->DATA = pcb;

   return RTCS_msgq_send(message, RTCS_data_ptr->TCPIP_msg_pool);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  RTCS_seterror
*  Returned Value:  void
*  Comments      :  Called to record an error condition in a
*                   provided error structure.
*
*END*-----------------------------------------------------------------*/

void RTCS_seterror
   (
      RTCS_ERROR_STRUCT_PTR   errptr,
         /* [IN/OUT] where to record the error */
      uint_32                 errcode,
         /* [IN] the error that occurred */
      uint_32                 errparm
         /* [IN] additional information */
   )
{ /* Body */

   /* Only record the first error that occurs */
   if (errptr->ERROR == RTCS_OK) {
      errptr->ERROR    = errcode;
      errptr->PARM     = errparm;
#ifdef __MQX__
      errptr->TASK_ID   = _task_get_id();
      errptr->TASKCODE = _task_get_error();
      errptr->MEMPTR   = _mem_get_highwater();
      errptr->STACK    = _task_check_stack();
#endif
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : RTCS_log_error
* Returned Value   : none
* Comments  :  Routine to handle non-fatal errors.
*
*END*-----------------------------------------------------------------*/

void  RTCS_log_error
   (
      uint_32  module,
      uint_32  error,
      uint_32  p1,
      uint_32  p2,
      uint_32  p3
   )
{ /* Body */
#if RTCSCFG_LOG_SOCKET_API || RTCSCFG_LOG_PCB
   RTCS_log(RTCSLOG_TYPE_ERROR,module,error,p1,p2,p3);
#endif
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_io_open
* Returned Value  : open file descriptor
* Comments        : RTOS-specific wrapper for fopen().
*
*END*-----------------------------------------------------------------*/

pointer RTCS_io_open
   (
      char_ptr       filename,
      char_ptr       filemode,
      uint_32 _PTR_  error_ptr
   )
{ /* Body */
   MQX_FILE_PTR file;
   uint_32  i;

   /* Scan for device name delimiter */
   for (i = 0; filename[i] && filename[i] != ':'; i++) {};

   /* 
   ** If the next char is not nul then a file
   ** on the resident file system is probably
   ** being opened.
   */
   if (filename[i] == ':' && filename[i+1] != '\0') {
      /* Assume we are opening a file */
      file = fopen(filename, filemode);
   } else {
      file = fopen(filename, 0);
   } /* Endif */

   if (error_ptr) {
      if (file) {
         *error_ptr = RTCS_OK;
      } else {
         *error_ptr = _task_get_error();
         if (!*error_ptr) {
            *error_ptr = RTCS_ENOENT;
         } /* Endif */
      } /* Endif */
   } /* Endif */

   return file;

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/MCM_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type MCM
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(MCM_PDD_H_)
#define MCM_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error MCM PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MKL02Z4) /* MCM */ && \
      !defined(MCU_MKL04Z4) /* MCM */ && \
      !defined(MCU_MKL05Z4) /* MCM */ && \
      !defined(MCU_MKL14Z4) /* MCM */ && \
      !defined(MCU_MKL15Z4) /* MCM */ && \
      !defined(MCU_MKL16Z4) /* MCM */ && \
      !defined(MCU_MKL24Z4) /* MCM */ && \
      !defined(MCU_MKL25Z4) /* MCM */ && \
      !defined(MCU_MKL26Z4) /* MCM */ && \
      !defined(MCU_MKL34Z4) /* MCM */ && \
      !defined(MCU_MKL36Z4) /* MCM */ && \
      !defined(MCU_MKL46Z4) /* MCM */
  // Unsupported MCU is active
  #error MCM PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Crossbar master arbitration type */
#define MCM_PDD_FIXED_PRIORITY 0U                /**< Fixed-priority arbitration for the crossbar masters */
#define MCM_PDD_ROUND_ROBIN    0x200U            /**< Round-robin arbitration for the crossbar masters */


/* ----------------------------------------------------------------------------
   -- DisableStallingFlashController
   ---------------------------------------------------------------------------- */

/**
 * @brief Disable stalling flash controller.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_DisableStallingFlashController(deviceID);
 *      @endcode
 */
#define MCM_PDD_DisableStallingFlashController(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)MCM_PLACR_ESFC_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableStallingFlashController
   ---------------------------------------------------------------------------- */

/**
 * @brief Enable stalling flash controller.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_EnableStallingFlashController(deviceID);
 *      @endcode
 */
#define MCM_PDD_EnableStallingFlashController(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) |= \
     MCM_PLACR_ESFC_MASK \
  )

/* ----------------------------------------------------------------------------
   -- DisableFlashControllerSpeculation
   ---------------------------------------------------------------------------- */

/**
 * @brief Disable flash controller speculation.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_DisableFlashControllerSpeculation(deviceID);
 *      @endcode
 */
#define MCM_PDD_DisableFlashControllerSpeculation(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)MCM_PLACR_DFCS_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableFlashControllerSpeculation
   ---------------------------------------------------------------------------- */

/**
 * @brief Enable flash controller speculation.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_EnableFlashControllerSpeculation(deviceID);
 *      @endcode
 */
#define MCM_PDD_EnableFlashControllerSpeculation(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) |= \
     MCM_PLACR_DFCS_MASK \
  )

/* ----------------------------------------------------------------------------
   -- DisableFlashDataSpeculation
   ---------------------------------------------------------------------------- */

/**
 * @brief Disable flash data speculation.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_DisableFlashDataSpeculation(deviceID);
 *      @endcode
 */
#define MCM_PDD_DisableFlashDataSpeculation(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)MCM_PLACR_EFDS_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableFlashDataSpeculation
   ---------------------------------------------------------------------------- */

/**
 * @brief Enable flash data speculation.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_EnableFlashDataSpeculation(deviceID);
 *      @endcode
 */
#define MCM_PDD_EnableFlashDataSpeculation(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) |= \
     MCM_PLACR_EFDS_MASK \
  )

/* ----------------------------------------------------------------------------
   -- EnableFlashControllerCache
   ---------------------------------------------------------------------------- */

/**
 * @brief Enable flash controllerCache.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_EnableFlashControllerCache(deviceID);
 *      @endcode
 */
#define MCM_PDD_EnableFlashControllerCache(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)MCM_PLACR_DFCC_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- DisableFlashControllerCache
   ---------------------------------------------------------------------------- */

/**
 * @brief Disable flash controllerCache.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_DisableFlashControllerCache(deviceID);
 *      @endcode
 */
#define MCM_PDD_DisableFlashControllerCache(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) |= \
     MCM_PLACR_DFCC_MASK \
  )

/* ----------------------------------------------------------------------------
   -- EnableFlashControllerInstructionCaching
   ---------------------------------------------------------------------------- */

/**
 * @brief Enable flash controller instruction caching.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_EnableFlashControllerInstructionCaching(deviceID);
 *      @endcode
 */
#define MCM_PDD_EnableFlashControllerInstructionCaching(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)MCM_PLACR_DFCIC_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- DisableFlashControllerInstructionCaching
   ---------------------------------------------------------------------------- */

/**
 * @brief Disable flash controller instruction caching.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_DisableFlashControllerInstructionCaching(deviceID);
 *      @endcode
 */
#define MCM_PDD_DisableFlashControllerInstructionCaching(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) |= \
     MCM_PLACR_DFCIC_MASK \
  )

/* ----------------------------------------------------------------------------
   -- EnableFlashControllerDataCaching
   ---------------------------------------------------------------------------- */

/**
 * @brief Enable flash controller data caching.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_EnableFlashControllerDataCaching(deviceID);
 *      @endcode
 */
#define MCM_PDD_EnableFlashControllerDataCaching(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)MCM_PLACR_DFCDA_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- DisableFlashControllerDataCaching
   ---------------------------------------------------------------------------- */

/**
 * @brief Disable flash controller data caching.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_DisableFlashControllerDataCaching(deviceID);
 *      @endcode
 */
#define MCM_PDD_DisableFlashControllerDataCaching(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) |= \
     MCM_PLACR_DFCDA_MASK \
  )

/* ----------------------------------------------------------------------------
   -- InvalidateFlashCache
   ---------------------------------------------------------------------------- */

/**
 * @brief Invalidates flash cache.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_InvalidateFlashCache(deviceID);
 *      @endcode
 */
#define MCM_PDD_InvalidateFlashCache(PeripheralBase) ( \
    MCM_PLACR_REG(PeripheralBase) |= \
     MCM_PLACR_CFCC_MASK \
  )

/* ----------------------------------------------------------------------------
   -- SetCrossbarMastersArbitrationType
   ---------------------------------------------------------------------------- */

/**
 * @brief Selects arbitration type for crossbar masters.
 * @param PeripheralBase Peripheral base address.
 * @param State Crossbar masters arbitration type. This parameter is of
 *        "Crossbar master arbitration type" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: MCM_PLACR.
 * @par Example:
 *      @code
 *      MCM_PDD_SetCrossbarMastersArbitrationType(deviceID,
 *      MCM_PDD_FIXED_PRIORITY);
 *      @endcode
 */
#define MCM_PDD_SetCrossbarMastersArbitrationType(PeripheralBase, State) ( \
    MCM_PLACR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(MCM_PLACR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)MCM_PLACR_ARB_MASK))) | ( \
      (uint32_t)(State))) \
  )
#endif  /* #if defined(MCM_PDD_H_) */

/* MCM_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi_legacy/int/spi_int_prv.h<|end_filename|>
#ifndef __spi_int_prv_h__
#define __spi_int_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_int_prv.h$
* $Version : 3.5.3.0$
* $Date    : Nov-24-2009$
*
* Comments:
*
*   This file includes the private definitions for the interrupt SPI
*   I/O drivers.
*
*END************************************************************************/

/*--------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/

/*---------------------------------------------------------------------
**
** IO SPI INT DEVICE STRUCT
**
** This structure used to store information about an SPI interrupt io device
** for the IO device table
*/
typedef struct io_spi_int_device_struct
{

   /* The I/O init function */
   _mqx_uint (_CODE_PTR_ DEV_INIT)(pointer, char _PTR_);

   /* The I/O deinit function */
   _mqx_uint (_CODE_PTR_ DEV_DEINIT)(pointer, pointer);
   
   /* The enable interrupts function */
   _mqx_uint (_CODE_PTR_ DEV_ENABLE_INTS)(pointer);
   
   /* [IN] The READ function */
   _mqx_int (_CODE_PTR_  DEV_READ)(pointer, char_ptr, _mqx_int);
      
   /* [IN] The WRITE function */
   _mqx_int (_CODE_PTR_  DEV_WRITE)(pointer, char_ptr, _mqx_int);
   
   /* The ioctl function, (change bauds etc) */
   _mqx_int (_CODE_PTR_  DEV_IOCTL)(pointer, _mqx_uint, _mqx_uint_ptr, _mqx_uint);

   /* The I/O channel initialization data */
   pointer               DEV_INIT_DATA_PTR;
   
   /* Device specific information */
   pointer               DEV_INFO_PTR;

   /* Open count for number of accessing file descriptors */
   uint_32               COUNT;

   /* Open flags for this channel */
   uint_32               FLAGS;
   
} IO_SPI_INT_DEVICE_STRUCT, _PTR_ IO_SPI_INT_DEVICE_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/* 
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_spi_int_open(FILE_DEVICE_STRUCT_PTR, char _PTR_, char _PTR_);
extern _mqx_int _io_spi_int_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_spi_int_read(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_spi_int_write(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_spi_int_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);
extern _mqx_int _io_spi_int_uninstall(IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/tchres/tchres.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tchres.c$
* $Version : 3.8.9.0$
* $Date    : Sep-22-2011$
*
* Comments:
*
*   This file contains the source for the hello example program.
*
*END************************************************************************/
#include "mqx.h"
#include "bsp.h"
#include "tchres_prv.h"
#include <string.h>

#if !MQX_USE_LWEVENTS
#error use MQX_USE_LWEVENTS
#endif

#define ADC_XPLUS_CHANNEL "adc_X"
#define ADC_YPLUS_CHANNEL "adc_Y"

#if 0
const ADC_INIT_STRUCT adc_init = {
    ADC_RESOLUTION_DEFAULT,     /* resolution */
};
#endif
/* static function prototypes */
static _mqx_int _tchres_uninstall( IO_DEVICE_STRUCT_PTR );
static _mqx_int _tchres_open( MQX_FILE_PTR, char_ptr, char_ptr );
static _mqx_int _tchres_close( MQX_FILE_PTR );
static _mqx_int _tchres_ioctl( MQX_FILE_PTR, _mqx_uint, pointer );
static _mqx_int _tchres_get_position_raw( int_16 *, int_16 *, TCHRES_DEVICE_STRUCT_PTR );
static uint_16 _tchres_read_touch_axis( TCHRES_PIN_SELECT_ENUM, TCHRES_DEVICE_STRUCT_PTR );
static int_16 _tchres_get_raw_limits( TCHRES_LIMITS_ENUM, TCHRES_DEVICE_STRUCT_PTR );
static uchar _tchres_get_filtered_axis(TCHRES_DEVICE_STRUCT_PTR, TCHRES_PIN_SELECT_ENUM, uint_16 *);
static void _tchres_set_pins_to_default( TCHRES_DEVICE_STRUCT_PTR );
static _mqx_int _tchres_measure_position(TCHRES_PIN_SELECT_ENUM, int_16 *, TCHRES_DEVICE_STRUCT_PTR);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_tchres_install
* Returned Value   : none
* Comments         :
*    Return filtered value from adc
*
*END*----------------------------------------------------------------------*/
_mqx_uint _io_tchres_install
(
   /* [IN] A string that identifies the device for fopen */
   char_ptr             identifier,

   /* [IN] The I/O init data pointer */
   TCHRES_INIT_STRUCT_PTR  init_ptr,

   /* [IN] adc devices used for measuring X+ and Y+ */
   TCHRES_INSTALL_PARAM_STRUCT_PTR install_params
)
{
   TCHRES_DEVICE_STRUCT_PTR    dev_ptr;
   ADC_INIT_CHANNEL_STRUCT_PTR adc_x_ptr, adc_y_ptr;
   _mqx_int                    result = MQX_OK;

   if ((install_params->ADC_XPLUS_DEVICE == NULL) || (install_params->ADC_YPLUS_DEVICE == NULL))
   {
      result = MQX_INVALID_IO_CHANNEL;
      goto tchres_alloc_err;
   }

   /* allocate memory */
   dev_ptr = _mem_alloc_system_zero((_mem_size)sizeof( TCHRES_DEVICE_STRUCT ));
   #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL)
   {
      result = MQX_OUT_OF_MEMORY;
      goto tchres_alloc_err;
   } /* Endif */
   #endif

   adc_x_ptr = _mem_alloc_system_zero((_mem_size)sizeof( ADC_INIT_CHANNEL_STRUCT ));
   #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (adc_x_ptr == NULL)
   {
      result = MQX_OUT_OF_MEMORY;
      goto adcx_alloc_err;
   } /* Endif */
   #endif

   adc_y_ptr = _mem_alloc_system_zero((_mem_size)sizeof( ADC_INIT_CHANNEL_STRUCT ));
   #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (adc_y_ptr == NULL)
   {
      result = MQX_OUT_OF_MEMORY;
      goto adcy_alloc_err;
   } /* Endif */
   #endif

   _mem_set_type( dev_ptr, MEM_TYPE_IO_TCHRES_STRUCT );
   _mem_set_type( adc_x_ptr, MEM_TYPE_IO_TCHRES_STRUCT );
   _mem_set_type( adc_y_ptr, MEM_TYPE_IO_TCHRES_STRUCT );

   if (_lwevent_create(&dev_ptr->TCH_EVENT, LWEVENT_AUTO_CLEAR) != MQX_OK)
   {
      result = MQX_IO_OPERATION_NOT_AVAILABLE;
      goto event_err;
   }

   /* Channel X adc settings */
   adc_x_ptr->source = init_ptr->ADC_CHANNEL_X_SOURCE;
   adc_x_ptr->flags = TCHRES_ADC_FLAGS;
   adc_x_ptr->number_samples = TCHRES_ADC_NUM_SAMPLES;
   adc_x_ptr->time_offset = 0;
   adc_x_ptr->time_period = TCHRES_ADC_TIME_PERIOD;
   adc_x_ptr->range = TCHRES_ADC_RANGE;
   adc_x_ptr->buffer_size = TCHRES_ADC_BUFFER_SIZE;
   adc_x_ptr->trigger = init_ptr->ADC_CHANNEL_X_TRIGGER;
   adc_x_ptr->complete_event = &dev_ptr->TCH_EVENT;
   adc_x_ptr->event_mask = TCH_ADC_X_COMPLETE;

   /* Channel Y adc settings */
   adc_y_ptr->source = init_ptr->ADC_CHANNEL_Y_SOURCE;
   adc_y_ptr->flags = TCHRES_ADC_FLAGS;
   adc_y_ptr->number_samples = TCHRES_ADC_NUM_SAMPLES;
   adc_y_ptr->time_offset = TCHRES_ADC_TIME_PERIOD / 2;
   adc_y_ptr->time_period = TCHRES_ADC_TIME_PERIOD;
   adc_y_ptr->range = TCHRES_ADC_RANGE;
   adc_y_ptr->buffer_size = TCHRES_ADC_BUFFER_SIZE;
   adc_y_ptr->trigger = init_ptr->ADC_CHANNEL_Y_TRIGGER;
   adc_y_ptr->complete_event = &dev_ptr->TCH_EVENT;
   adc_y_ptr->event_mask = TCH_ADC_Y_COMPLETE;

   /* copy the adc channel information */
   dev_ptr->ADC_LIMITS = init_ptr->ADC_LIMITS;
   dev_ptr->ADC_CHANNEL_X_STRUCT = adc_x_ptr;
   dev_ptr->ADC_CHANNEL_Y_STRUCT = adc_y_ptr;
   dev_ptr->ADC_XPLUS_DEVICE = install_params->ADC_XPLUS_DEVICE;
   dev_ptr->ADC_YPLUS_DEVICE = install_params->ADC_YPLUS_DEVICE;

   /* initialize lwgpio */
   if (!lwgpio_init(&dev_ptr->X_PLUS_PIN, init_ptr->PIN_CONFIG.X_PLUS, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE))
   {
      result = MQX_IO_OPERATION_NOT_AVAILABLE;
      goto lw_err;
   }
   if (!lwgpio_init(&dev_ptr->Y_PLUS_PIN, init_ptr->PIN_CONFIG.Y_PLUS, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE))
   {
      result = MQX_IO_OPERATION_NOT_AVAILABLE;
      goto lw_err;
   }
   if (!lwgpio_init(&dev_ptr->X_MINUS_PIN, init_ptr->PIN_CONFIG.X_MINUS, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE))
   {
      result = MQX_IO_OPERATION_NOT_AVAILABLE;
      goto lw_err;
   }
   if (!lwgpio_init(&dev_ptr->Y_MINUS_PIN, init_ptr->PIN_CONFIG.Y_MINUS, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE))
   {
      result = MQX_IO_OPERATION_NOT_AVAILABLE;
      goto lw_err;
   }

   /* set adc and gpio functionality mux indexes */
   dev_ptr->PIN_FUNCT = init_ptr->PIN_CONFIG.PIN_FUNCT;

   /* install device */
   return ( _io_dev_install_ext ( identifier,
      _tchres_open,
      _tchres_close,
      NULL,
      NULL,
      _tchres_ioctl,
      _tchres_uninstall,
      (pointer)dev_ptr) );

    /* exceptions, clear memory */
lw_err:
    _lwevent_destroy(&dev_ptr->TCH_EVENT);
event_err:
   _mem_free(adc_y_ptr);
adcy_alloc_err:
   _mem_free(adc_x_ptr);
adcx_alloc_err:
   _mem_free(dev_ptr);
tchres_alloc_err:
   return result;

}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _tchres_uninstall
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Uninstall the touch screen driver.
*
*END*----------------------------------------------------------------------*/
static _mqx_int _tchres_uninstall
(
    IO_DEVICE_STRUCT_PTR    io_dev_ptr
)
{
   TCHRES_DEVICE_STRUCT_PTR tchscr_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

   /* free adc channel infos */
   if( tchscr_dev_ptr->ADC_CHANNEL_X_STRUCT )
   {
      _mem_free(tchscr_dev_ptr->ADC_CHANNEL_X_STRUCT);
   }
   if( tchscr_dev_ptr->ADC_CHANNEL_Y_STRUCT )
   {
      _mem_free(tchscr_dev_ptr->ADC_CHANNEL_Y_STRUCT);
   }
   if( &tchscr_dev_ptr->TCH_EVENT )
   {
      _lwevent_destroy( &tchscr_dev_ptr->TCH_EVENT );
   }
   if( tchscr_dev_ptr )
   {
      _mem_free (tchscr_dev_ptr);
   }
   io_dev_ptr->DRIVER_INIT_PTR = NULL;
   return IO_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _tchres_open
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Open the touch screen driver and initialize the gpio pins to default
*    states. Register  used pins in gpio driver as used. .
*
*END*----------------------------------------------------------------------*/
static _mqx_int _tchres_open
(
   /* [IN] The address of the device specific information */
   MQX_FILE_PTR     fd_ptr,

   /* [IN] The rest of the name of the device opened */
   char_ptr open_name_ptr,

   /* [IN] the flags to be used during operation: */
   char_ptr   flags
)
{
   IO_DEVICE_STRUCT_PTR       io_dev_ptr;
   TCHRES_DEVICE_STRUCT_PTR   tchscr_dev_ptr;
   _mqx_int                   result = MQX_OK;
   char_ptr					  ch_xplus, ch_yplus;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   tchscr_dev_ptr = (TCHRES_DEVICE_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   /* open this driver only once */
   if( tchscr_dev_ptr->COUNT == 0 )
   {
      tchscr_dev_ptr->COUNT = 1;
      
      
      ch_xplus = _mem_alloc_system_zero((_mem_size) strlen(tchscr_dev_ptr->ADC_XPLUS_DEVICE) + strlen(ADC_XPLUS_CHANNEL) + 1);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (ch_xplus == NULL) {
    	  result = MQX_OUT_OF_MEMORY;
    	  goto _channels_alloc_err;
      }
#endif
      strcpy(ch_xplus, tchscr_dev_ptr->ADC_XPLUS_DEVICE);
      strcpy(ch_xplus + strlen(ch_xplus), ADC_XPLUS_CHANNEL);
      
      
      ch_yplus = _mem_alloc_system_zero((_mem_size) strlen(tchscr_dev_ptr->ADC_YPLUS_DEVICE) + strlen(ADC_YPLUS_CHANNEL) + 1);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (ch_yplus == NULL) {
    	  result = MQX_OUT_OF_MEMORY;
    	  goto ch_yplus_alloc_err;
      }
#endif
      strcpy(ch_yplus, tchscr_dev_ptr->ADC_YPLUS_DEVICE);
      strcpy(ch_yplus + strlen(ch_yplus), ADC_YPLUS_CHANNEL);
      
      /* open X adc channel */
      tchscr_dev_ptr->ADC_CHANNEL_X = fopen(ch_xplus, (const char*)tchscr_dev_ptr->ADC_CHANNEL_X_STRUCT);
      if( tchscr_dev_ptr->ADC_CHANNEL_X == NULL )
      {
         result = MQX_IO_OPERATION_NOT_AVAILABLE;
      }
      _mem_free(ch_xplus);
      
      /* open Y adc channel */
      tchscr_dev_ptr->ADC_CHANNEL_Y = fopen(ch_yplus, (const char*)tchscr_dev_ptr->ADC_CHANNEL_Y_STRUCT);
      if( tchscr_dev_ptr->ADC_CHANNEL_Y == NULL )
      {
         result = MQX_IO_OPERATION_NOT_AVAILABLE;
      }
      _mem_free(ch_yplus);

      /* set pisns to default state */
      lwgpio_set_direction( &tchscr_dev_ptr->X_PLUS_PIN, LWGPIO_DIR_OUTPUT );
      lwgpio_set_direction( &tchscr_dev_ptr->Y_PLUS_PIN, LWGPIO_DIR_OUTPUT );
      lwgpio_set_direction( &tchscr_dev_ptr->X_MINUS_PIN, LWGPIO_DIR_OUTPUT );
      lwgpio_set_direction( &tchscr_dev_ptr->Y_MINUS_PIN, LWGPIO_DIR_OUTPUT );

      lwgpio_set_value( &tchscr_dev_ptr->X_PLUS_PIN, LWGPIO_VALUE_LOW );
      lwgpio_set_value( &tchscr_dev_ptr->X_MINUS_PIN, LWGPIO_VALUE_LOW );
      lwgpio_set_value( &tchscr_dev_ptr->Y_PLUS_PIN, LWGPIO_VALUE_LOW );
      lwgpio_set_value( &tchscr_dev_ptr->Y_MINUS_PIN, LWGPIO_VALUE_LOW );

#if PSP_MQX_CPU_IS_MCF51JE || PSP_MQX_CPU_IS_MCF51MM
      ioctl(tchscr_dev_ptr->ADC_CHANNEL_X, ADC_IOCTL_PIN_DISABLE, (pointer) tchscr_dev_ptr->ADC_CHANNEL_X_STRUCT->source);
      ioctl(tchscr_dev_ptr->ADC_CHANNEL_Y, ADC_IOCTL_PIN_DISABLE, (pointer) tchscr_dev_ptr->ADC_CHANNEL_Y_STRUCT->source);
#else
      lwgpio_set_functionality( &tchscr_dev_ptr->X_PLUS_PIN, tchscr_dev_ptr->PIN_FUNCT.X_PLUS_GPIO_FUNCTION );
      lwgpio_set_functionality( &tchscr_dev_ptr->Y_PLUS_PIN, tchscr_dev_ptr->PIN_FUNCT.Y_PLUS_GPIO_FUNCTION );
#endif

      lwgpio_set_functionality( &tchscr_dev_ptr->X_MINUS_PIN, tchscr_dev_ptr->PIN_FUNCT.X_MINUS_GPIO_FUNCTION );
      lwgpio_set_functionality( &tchscr_dev_ptr->Y_MINUS_PIN, tchscr_dev_ptr->PIN_FUNCT.Y_MINUS_GPIO_FUNCTION );
   }
   else
   {
      result = MQX_IO_OPERATION_NOT_AVAILABLE;
   }

   return result;
   
ch_yplus_alloc_err:
   _mem_free(ch_xplus);
_channels_alloc_err:
   return MQX_OUT_OF_MEMORY;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _tchres_close
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Close the touch screen driver.
*
*END*----------------------------------------------------------------------*/
static _mqx_int _tchres_close
(
   /* [IN] The address of the device specific information */
   MQX_FILE_PTR     fd_ptr
)
{
   IO_DEVICE_STRUCT_PTR       io_dev_ptr;
   TCHRES_DEVICE_STRUCT_PTR   tchscr_dev_ptr;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   tchscr_dev_ptr = (TCHRES_DEVICE_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   if( tchscr_dev_ptr )
   {
      fclose( tchscr_dev_ptr->ADC_CHANNEL_X );
      fclose( tchscr_dev_ptr->ADC_CHANNEL_Y );

      /* open this driver only once */
      tchscr_dev_ptr->COUNT = 0;
   }

   return( MQX_OK );
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _tchres_ioctl
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    This driver function performs various commands upon the opened TCHSCR
*    device.
*
*END*----------------------------------------------------------------------*/
static _mqx_int _tchres_ioctl
(
   /* [IN] the handle returned from _fopen */
   MQX_FILE_PTR     handle_ptr,

   /* [IN] the ioctl command */
   _mqx_uint   cmd,

   /* [IN] the ioctl parameters */
   pointer     param_ptr
)
{
   IO_DEVICE_STRUCT_PTR       io_dev_ptr;
   TCHRES_DEVICE_STRUCT_PTR   tchscr_dev_ptr;
   _mqx_int                   result = MQX_OK;
   int_16                        x_pos, y_pos;
   TCHRES_POSITION_STRUCT_PTR position_ptr;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)handle_ptr->DEV_PTR;
   tchscr_dev_ptr = (TCHRES_DEVICE_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   switch (cmd) {
      /* not supported yet
        case IO_IOCTL_TCHSCR_GET_POSITION :
            break;
      case IO_IOCTL_TCHSCR_SET_CALIBRATION :
         break;
      case  IO_IOCTL_TCHSCR_GET_CALIBRATION :
         break;
        */
      case IO_IOCTL_TCHSCR_GET_POSITION_RAW :
         if( param_ptr == NULL )
         {
            result = TCHRES_ERROR_INVALID_PARAMETER;
            break;
         }
         /* Call the generic get_possition_raw function */
         result = _tchres_get_position_raw( &x_pos, &y_pos, tchscr_dev_ptr );
         if( result == TCHRES_OK )
         {
            position_ptr = (TCHRES_POSITION_STRUCT_PTR)param_ptr;
            position_ptr->X = x_pos;
            position_ptr->Y = y_pos;
         }

         break;

      case IO_IOCTL_TCHSCR_GET_RAW_LIMITS:
         if( param_ptr != NULL )
         {
            *(TCHRES_ADC_LIMITS_STRUCT_PTR)param_ptr = tchscr_dev_ptr->ADC_LIMITS;
            result = MQX_OK;
         }
         else
         {
            result = TCHRES_ERROR_INVALID_PARAMETER;
         }
         break;

        default:
           /* return unsupported command */
           result = IO_ERROR_INVALID_IOCTL_CMD;
         break;

    } /* end switch */

   return( result );
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _tchres_read_touch_axis
* Returned Value   : adc value or 0
* Comments         :
*    Returns the value from ADC from selected channel
*
*END*----------------------------------------------------------------------*/
static uint_16 _tchres_read_touch_axis
(
   TCHRES_PIN_SELECT_ENUM pin_select,
   TCHRES_DEVICE_STRUCT_PTR tchscr_dev_ptr
)
{
   ADC_RESULT_STRUCT data;

   switch( pin_select )
   {
      case X_PLUS:
         ioctl(tchscr_dev_ptr->ADC_CHANNEL_X, ADC_IOCTL_FIRE_TRIGGER, (pointer) tchscr_dev_ptr->ADC_CHANNEL_X_STRUCT->trigger);
         _lwevent_wait_ticks(&tchscr_dev_ptr->TCH_EVENT, tchscr_dev_ptr->ADC_CHANNEL_X_STRUCT->event_mask, TRUE, 0);
         if (read(tchscr_dev_ptr->ADC_CHANNEL_X, &data, sizeof(data)) != 2) {
             return 0;
         }
         break;

      case Y_PLUS:
         ioctl(tchscr_dev_ptr->ADC_CHANNEL_Y, ADC_IOCTL_FIRE_TRIGGER, (pointer) tchscr_dev_ptr->ADC_CHANNEL_Y_STRUCT->trigger);
         _lwevent_wait_ticks(&tchscr_dev_ptr->TCH_EVENT, tchscr_dev_ptr->ADC_CHANNEL_Y_STRUCT->event_mask, TRUE, 0);
         if (read(tchscr_dev_ptr->ADC_CHANNEL_Y, &data, sizeof(data)) != 2) {
             return 0;
         }
         break;
      default:
         return  0;
   }

   return(data.result);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _tchres_get_filtered_axis
* Returned Value   : 1 on success
*                    0 when measurement failed
* Comments         :
*    Return filtered value from adc
*
*END*----------------------------------------------------------------------*/
static uchar _tchres_get_filtered_axis
(
        TCHRES_DEVICE_STRUCT_PTR tchscr_dev_ptr,
        TCHRES_PIN_SELECT_ENUM pinId,
        uint_16 *Res
)
{
    #define ABS(a) (((a) < 0) ? -(a) : (a))
    #define NBR_SAMPLES 8
    #define NBR_VALID_SAMPLES 6

    uint_16 wSample[NBR_SAMPLES];
    uint_16 wADCReading, adcMin, adcMax, wRes = 0, wSum = 0;
    uint_8 tmp, tmp_res, deviation, cnt = 0;

    TCHRES_ADC_LIMITS_STRUCT_PTR p_limits = &tchscr_dev_ptr->ADC_LIMITS;
    deviation = (uchar) (p_limits->FULL_SCALE / 256);

    switch (pinId) {
    case X_PLUS:
        adcMin = p_limits->X_TOUCH_MIN;
        adcMax = p_limits->X_TOUCH_MAX;
        break;
    case Y_PLUS:
        adcMin = p_limits->Y_TOUCH_MIN;
        adcMax = p_limits->Y_TOUCH_MAX;
        break;
    default:
        adcMin = 0;
        adcMax = p_limits->FULL_SCALE;
    }

    for (tmp = 0; tmp < NBR_SAMPLES; tmp++) {
        //reading sample from ADC
        wADCReading = _tchres_read_touch_axis(pinId, tchscr_dev_ptr);

        /* check if input value is from valid range */
        if((wADCReading < adcMin) || (wADCReading > adcMax)) {
            break;
        }

        wSample[tmp] = wADCReading;
        wSum += wADCReading;
    }

    //measuring failed due to exceeded sample range
    if (tmp < NBR_SAMPLES) {
        return 0;
    }

    wRes = wSum / NBR_SAMPLES;

    for (tmp = 0, tmp_res = 0; tmp < NBR_SAMPLES; tmp++) {
        if (ABS(wSample[tmp] - wRes) < deviation) {
            tmp_res++;
        }
    }

    if (tmp_res >= NBR_VALID_SAMPLES) {
        *Res = wRes;
        return 1;
    } else {
        return 0;
    }
}

/*FUNCTION*-------------------------------------------------------------------------------
*
* Function Name    : _tchres_set_pins_to_default
* Returned Value   : none
* Comments         : set X, Y pins to default state - ADC off, pins low, output direction
*
*
*END*-----------------------------------------------------------------------------------*/
static void _tchres_set_pins_to_default
(
   TCHRES_DEVICE_STRUCT_PTR tchscr_dev_ptr
)
{
   lwgpio_set_direction( &tchscr_dev_ptr->X_PLUS_PIN, LWGPIO_DIR_OUTPUT );
   lwgpio_set_direction( &tchscr_dev_ptr->X_MINUS_PIN, LWGPIO_DIR_OUTPUT );
   lwgpio_set_direction( &tchscr_dev_ptr->Y_PLUS_PIN, LWGPIO_DIR_OUTPUT );
   lwgpio_set_direction( &tchscr_dev_ptr->Y_MINUS_PIN, LWGPIO_DIR_OUTPUT );

   /* Put on touch screen pins into default mode */
   lwgpio_set_value( &tchscr_dev_ptr->X_PLUS_PIN, LWGPIO_VALUE_LOW );
   lwgpio_set_value( &tchscr_dev_ptr->X_MINUS_PIN, LWGPIO_VALUE_LOW );
   lwgpio_set_value( &tchscr_dev_ptr->Y_PLUS_PIN, LWGPIO_VALUE_LOW );
   lwgpio_set_value( &tchscr_dev_ptr->Y_MINUS_PIN, LWGPIO_VALUE_LOW );

   /* Disable ADC function on X+ and Y+ */
#if PSP_MQX_CPU_IS_MCF51JE || PSP_MQX_CPU_IS_MCF51MM
  ioctl(tchscr_dev_ptr->ADC_CHANNEL_X, ADC_IOCTL_PIN_DISABLE, (pointer) 0);
  ioctl(tchscr_dev_ptr->ADC_CHANNEL_Y, ADC_IOCTL_PIN_DISABLE, (pointer) 0);
#else
  lwgpio_set_functionality(&tchscr_dev_ptr->X_PLUS_PIN, tchscr_dev_ptr->PIN_FUNCT.X_PLUS_GPIO_FUNCTION);
  lwgpio_set_functionality(&tchscr_dev_ptr->Y_PLUS_PIN, tchscr_dev_ptr->PIN_FUNCT.Y_PLUS_GPIO_FUNCTION);
#endif

}

/*FUNCTION*------------------------------------------------------------------------
*
* Function Name    : _tchres_measure_position
* Returned Value   : touchPosition with raw value from ADC valid only on TCHRES_OK
*                    TCHRES_OK on success
*                    TCHRES_ERROR_XXX on failure where XXX describes error
* Comments         : Convenient function for measuring either X or Y coordinate.
*                    Measuring is performed on either X+ or Y+ pin, no other pin
*                    is accepted in parameter pin_select.
*
*
*END*----------------------------------------------------------------------------*/
static _mqx_int _tchres_measure_position
(
    /* [IN] Pin ID to use for measurement either X (X+) or Y (Y+) coordinate */
    TCHRES_PIN_SELECT_ENUM pin_select,
    /* [OUT] Output parameter for result */
    int_16 *touchPosition,
    /* [IN] Touch screen device structure pointer */
    TCHRES_DEVICE_STRUCT_PTR tchscr_dev_ptr
)
{
    #define RAW_VALID_VALUE_TIMEOUT 254
    /* Declare and initialize local variables */
    uint_16 tmpCnt = 0, tmpRes = 0, min_voltage = 0;
    uint_32 adc_func;
    MQX_FILE_PTR adc_channel;
    LWGPIO_STRUCT pin_adc, pin_high, pin_z;

    switch (pin_select) {
    case X_PLUS:
        adc_channel = tchscr_dev_ptr->ADC_CHANNEL_X;
        adc_func = tchscr_dev_ptr->PIN_FUNCT.X_PLUS_ADC_FUNCTION;
        pin_adc = tchscr_dev_ptr->X_PLUS_PIN;
        pin_high = tchscr_dev_ptr->Y_PLUS_PIN;
        pin_z = tchscr_dev_ptr->X_MINUS_PIN;
        min_voltage = _tchres_get_raw_limits(X_TOUCH_MIN, tchscr_dev_ptr);
        break;
    case Y_PLUS:
        adc_channel = tchscr_dev_ptr->ADC_CHANNEL_Y;
        adc_func = tchscr_dev_ptr->PIN_FUNCT.Y_PLUS_ADC_FUNCTION;
        pin_adc = tchscr_dev_ptr->Y_PLUS_PIN;
        pin_high = tchscr_dev_ptr->X_PLUS_PIN;
        pin_z = tchscr_dev_ptr->Y_MINUS_PIN;
        min_voltage = _tchres_get_raw_limits(Y_TOUCH_MIN, tchscr_dev_ptr);
        break;
    default:
        return TCHRES_ERROR_INVALID_PARAMETER;
    }

    /* Set pins to default values */
    _tchres_set_pins_to_default(tchscr_dev_ptr);

    /* Switch to ADC */
 #if PSP_MQX_CPU_IS_MCF51JE || PSP_MQX_CPU_IS_MCF51MM
    ioctl(adc_channel, ADC_IOCTL_PIN_ENABLE, (pointer) 0);
 #else
    lwgpio_set_functionality(&pin_adc, adc_func);
 #endif

    /* Check that the touch screen surface is without any voltage and prepared */
    while (_tchres_read_touch_axis(pin_select, tchscr_dev_ptr) > min_voltage)
    {
        if (++tmpCnt >= RAW_VALID_VALUE_TIMEOUT) break;
    }

    /* test for tmpCnt overflow */
    if(tmpCnt >= RAW_VALID_VALUE_TIMEOUT) {
        return (TCHRES_ERROR_TIMEOUT);
    }

    /* When the touch screen surface is prepared */
    /* Switch on pin_high wire into high level */
    lwgpio_set_value(&pin_high, LWGPIO_VALUE_HIGH);

    /* Switch on pin_z wire into high Z mode to keep measurement non affected */
    lwgpio_set_direction(&pin_z, LWGPIO_DIR_INPUT);

    if(_tchres_get_filtered_axis(tchscr_dev_ptr, pin_select, &tmpRes)) {
        *touchPosition = tmpRes;
        return TCHRES_OK;
    } else {
        return TCHRES_ERROR_NO_TOUCH;
    }
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _tchres_get_position_raw
* Returned Value   : unsigned int *TouchPositionX    Pointer to X coordinate
*                    unsigned int *TouchPositionY    Pointer to Y coordinate
*                    TCHRES_OK or some kind of TCHRES_ERROR
* Comments         : returns the filtered coordinate values from adc
*
*
*END*----------------------------------------------------------------------*/
static _mqx_int _tchres_get_position_raw(
        int_16 *TouchPositionX,
        int_16 *TouchPositionY,
        TCHRES_DEVICE_STRUCT_PTR tchscr_dev_ptr)
{
    _mqx_int result;
    result = _tchres_measure_position(Y_PLUS, TouchPositionY, tchscr_dev_ptr);
    if (result == TCHRES_OK) {
        result = _tchres_measure_position(X_PLUS, TouchPositionX, tchscr_dev_ptr);
    }

    return result;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _tchres_get_raw_limits
* Returned Value   : none
* Comments         :
*    Return selected limit for adc
*
*END*----------------------------------------------------------------------*/
static int_16 _tchres_get_raw_limits
(
   TCHRES_LIMITS_ENUM limit,
   TCHRES_DEVICE_STRUCT_PTR tchscr_dev_ptr
)
{
   int_16 result = 0;

   switch( limit )
   {
      case FULL_SCALE:
         result = tchscr_dev_ptr->ADC_LIMITS.FULL_SCALE;
         break;
      case X_TOUCH_MIN:
         result = tchscr_dev_ptr->ADC_LIMITS.X_TOUCH_MIN;
         break;
      case Y_TOUCH_MIN:
         result = tchscr_dev_ptr->ADC_LIMITS.Y_TOUCH_MIN;
         break;
      case X_TOUCH_MAX:
         result = tchscr_dev_ptr->ADC_LIMITS.X_TOUCH_MAX;
         break;
      case Y_TOUCH_MAX:
         result = tchscr_dev_ptr->ADC_LIMITS.Y_TOUCH_MAX;
         break;
      default:
      break;
   }
   return result;
}
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/qi2c.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: qi2c.h$
* $Version : 3.8.4.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the type definitions for the mcf54xx I2C module.
*
*END************************************************************************/

#ifndef __qi2c_h__
#define __qi2c_h__

#define __qi2c_h__version "$Version:3.8.4.0$"
#define __qi2c_h__date    "$Date:Jun-6-2012$"

#ifdef __cplusplus
extern "C" {
#endif


/*------------------------------------------------------------------------*/
/*
** I2C registers
*/

/* Bit definitions and macros for QI2C_I2ADR */
#define QI2C_I2ADR_ADR(x)                 (((x)&0x7F)<<0x1)

/* Bit definitions and macros for QI2C_I2FDR */
#define QI2C_I2FDR_IC(x)                  (((x)&0x3F)<<0)

/* Bit definitions and macros for QI2C_I2CR */
#define QI2C_I2CR_DMAEN                   (0x2)
#define QI2C_I2CR_RSTA                    (0x4)
#define QI2C_I2CR_NOAK                    (0x8)
#define QI2C_I2CR_TX                      (0x10)
#define QI2C_I2CR_MS                      (0x20)
#define QI2C_I2CR_IBIE                    (0x40)
#define QI2C_I2CR_MDIS                    (0x80)

/* Bit definitions and macros for QI2C_I2SR */
#define QI2C_I2SR_RXAK                    (0x1)
#define QI2C_I2SR_IBIF                    (0x2)
#define QI2C_I2SR_SRW                     (0x4)
#define QI2C_I2SR_IBAL                    (0x10)
#define QI2C_I2SR_IBB                     (0x20)
#define QI2C_I2SR_IAAS                    (0x40)
#define QI2C_I2SR_TCF                     (0x80)


/* Bit definitions and macros for QI2C_I2IC */
#define QI2C_I2IC_BIIE                    (0x80)

#define QI2C_REG(r) uchar r


/*------------------------------------------------------------------------*/


/*
** QI2C_STRUCT
** This structure defines what one i2c register look like
*/

typedef struct qi2c_reg_struct
{
    QI2C_REG(I2ADR);          // I2C address register
    QI2C_REG(I2FDR);          // I2C frequency divider register
    QI2C_REG(I2CR);           // I2C control register
    QI2C_REG(I2SR);           // I2C status register
    QI2C_REG(I2DR);           // I2C data I/O register
    QI2C_REG(I2IC);           // I2C Interrupt Configuration

} QI2C_REG_STRUCT;
typedef volatile struct qi2c_reg_struct _PTR_ VQI2C_REG_STRUCT_PTR;

#ifdef __cplusplus
}
#endif

#endif  //__qi2c_h__


<|start_filename|>Firmware/Inverter_bootloader/APP/flash_FTFL.h<|end_filename|>
#ifndef _FLASH_FTFL_H_
#define _FLASH_FTFL_H_


/*FSL: new Kinetis/ColdFire+ devices might use this new FTFE implementation instead of FTFL*/

#define     FTFL_FSTAT_ACCERR_MASK       FTFE_FSTAT_ACCERR_MASK
#define     FTFL_FSTAT_FPVIOL_MASK       FTFE_FSTAT_FPVIOL_MASK
#define     FTFL_FSTAT_RDCOLERR_MASK     FTFE_FSTAT_RDCOLERR_MASK
#define     FTFL_FSTAT_CCIF_MASK         FTFE_FSTAT_CCIF_MASK
#define     FTFL_FSTAT_MGSTAT0_MASK      FTFE_FSTAT_MGSTAT0_MASK
#define     FTFL_FSTAT                   FTFE_FSTAT
#define     FTFL_FCCOB0                  FTFE_FCCOB0
#define     FTFL_FCCOB1                  FTFE_FCCOB1
#define     FTFL_FCCOB2                  FTFE_FCCOB2
#define     FTFL_FCCOB3                  FTFE_FCCOB3
#define     FTFL_FCCOB4                  FTFE_FCCOB4
#define     FTFL_FCCOB5                  FTFE_FCCOB5
#define     FTFL_FCCOB6                  FTFE_FCCOB6
#define     FTFL_FCCOB7                  FTFE_FCCOB7


/* error code */
#define Flash_OK           0x00
#define Flash_FACCERR      0x01
#define Flash_FPVIOL       0x02
#define Flash_MGSTAT0	   0x04
#define Flash_RDCOLERR	   0x08
#define Flash_NOT_ERASED   0x10
#define Flash_CONTENTERR   0x11

/* flash commands */
#define FLASH_CMD_PROGR_LWORD  	0x07
#define FLASH_CMD_SECTOR_ERASE  0x09


void Flash_Init(void);
unsigned char Flash_SectorErase(INT32U addr);
unsigned char Flash_ByteProgram(INT32U addr, INT8U *buff, INT32U size);

__ramfunc void SpSub(void);

#endif /*_FLASH_FTFL_H_*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/polled/serl_pol_mcf52xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_pol_mcf52xx.c$
* $Version : 3.8.16.0$
* $Date    : Aug-8-2012$
*
* Comments:
*
*   This file contains the functions for the polled serial I/O
*   low level functions for the MCF52XX UART.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "io_prv.h"
#include "charq.h"
#include "fio_prv.h"
#include "serplprv.h"
#include "serl_mcf52xx.h"

/* Polled driver functions */
extern char    _mcf52xx_uart_serial_polled_getc(MCF52XX_UART_SERIAL_INFO_STRUCT_PTR);
extern void    _mcf52xx_uart_serial_polled_putc(MCF52XX_UART_SERIAL_INFO_STRUCT_PTR, char);
extern boolean _mcf52xx_uart_serial_polled_status(MCF52XX_UART_SERIAL_INFO_STRUCT_PTR);
extern uint_32 _mcf52xx_uart_serial_polled_ioctl(MCF52XX_UART_SERIAL_INFO_STRUCT_PTR, uint_32,
   uint_32_ptr);
extern uint_32 _mcf52xx_uart_serial_polled_init(MCF52XX_UART_SERIAL_INIT_STRUCT_PTR,
   pointer _PTR_, char _PTR_);
extern uint_32 _mcf52xx_uart_serial_polled_deinit(MCF52XX_UART_SERIAL_INIT_STRUCT_PTR,
   MCF52XX_UART_SERIAL_INFO_STRUCT_PTR);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mcf52xx_uart_serial_polled_install
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    Install a polled uart serial device.
*
*END*----------------------------------------------------------------------*/

uint_32 _mcf52xx_uart_serial_polled_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr           identifier,

      /* [IN] The I/O init data pointer */
       MCF52XX_UART_SERIAL_INIT_STRUCT_CPTR     init_data_ptr,

      /* [IN] The I/O queue size to use */
      uint_32            queue_size
   )
{ /* Body */

  return _io_serial_polled_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, pointer _PTR_, char _PTR_))_mcf52xx_uart_serial_polled_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_mcf52xx_uart_serial_polled_deinit,
      (char    (_CODE_PTR_)(pointer))_mcf52xx_uart_serial_polled_getc,
      (void    (_CODE_PTR_)(pointer, char))_mcf52xx_uart_serial_polled_putc,
      (boolean (_CODE_PTR_)(pointer))_mcf52xx_uart_serial_polled_status,
      (uint_32 (_CODE_PTR_)(pointer, uint_32, pointer))_mcf52xx_uart_serial_polled_ioctl,
      (pointer)init_data_ptr, queue_size);

} /* Endbody */



/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_polled_init
* Returned Value   : MQX_OK or a MQX error code.
* Comments         :
*    This function initializes the UART
*
*END*********************************************************************/

uint_32 _mcf52xx_uart_serial_polled_init
   (
      /* [IN] the initialization information for the device being opened */
      MCF52XX_UART_SERIAL_INIT_STRUCT_PTR io_init_ptr,

      /* [OUT] the address to store device specific information */
      pointer _PTR_                       io_info_ptr_ptr,

      /* [IN] the rest of the name of the device opened */
      char _PTR_                          open_name_ptr
   )
{ /* Body */
   volatile MCF52XX_UART_STRUCT _PTR_  uart_ptr;
   MCF52XX_UART_SERIAL_INFO_STRUCT _PTR_ uart_info_ptr;
   uint_32                             channel;
   uint_32                             baud;

   uart_info_ptr = _mem_alloc_system_zero((uint_32)
      sizeof(MCF52XX_UART_SERIAL_INFO_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if ( uart_info_ptr == NULL ) {
        return(MQX_OUT_OF_MEMORY);
   }/* Endif */
#endif
   _mem_set_type(uart_info_ptr,MEM_TYPE_IO_SERIAL_INFO_STRUCT);    

   *io_info_ptr_ptr = uart_info_ptr;

   /* Save initialization values */
   uart_info_ptr->INIT = *io_init_ptr;

   channel = uart_info_ptr->INIT.DEVICE;
   _bsp_serial_io_init (channel);
   uart_ptr = _bsp_get_serial_base_address (channel);
   uart_info_ptr->UART_PTR = (pointer)uart_ptr;

   uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_RX;
   uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_TX;
   uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_ERROR;
   uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_BREAK;
   uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_POINTER;

   uart_ptr->WRITE.UMR = uart_info_ptr->INIT.UMR1_VALUE;
   uart_ptr->WRITE.UMR = uart_info_ptr->INIT.UMR2_VALUE;

   uart_ptr->WRITE.UCSR = MCF52XX_UART_UCSR_RX_TIMER |
                          MCF52XX_UART_UCSR_TX_TIMER;

   uart_ptr->WRITE.UIMR = 0; /* Disable all interrupts */

   /* Set up the baud rate */
   /* baud = fsck / (32 * baudrate) + 0.5 */ 
   baud = (uint_32)((uart_info_ptr->INIT.CLOCK_SPEED + 16 * uart_info_ptr->INIT.BAUD_RATE )/ (32 * uart_info_ptr->INIT.BAUD_RATE));   
   uart_ptr->WRITE.UBG1 = (uchar)((baud >> 8) & 0xFF);
   uart_ptr->WRITE.UBG2 = (uchar)(baud & 0xFF);

   uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_TX_ENABLE |
                         MCF52XX_UART_UCR_RX_ENABLE;

   return( MQX_OK );

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_polled_deinit
* Returned Value   : MQX_OK or a mqx error code.
* Comments         :
*    This function de-initializes the UART.
*
*END*********************************************************************/

uint_32 _mcf52xx_uart_serial_polled_deinit
   (
      /* [IN] the initialization information for the device being opened */
      MCF52XX_UART_SERIAL_INIT_STRUCT_PTR io_init_ptr,

      /* [IN] the address of the device specific information */
      MCF52XX_UART_SERIAL_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */

   _mem_free(io_info_ptr);

   return(MQX_OK);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_polled_getc
* Returned Value   : char
* Comments         :
*   Return a character when it is available.  This function polls the
* device for input.
*
*************************************************************************/

char _mcf52xx_uart_serial_polled_getc
   (
      /* [IN] the address of the device specific information */
      MCF52XX_UART_SERIAL_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   volatile MCF52XX_UART_STRUCT _PTR_ uart_ptr = io_info_ptr->UART_PTR;

   /* Wait until a character is available */
   while ( (uart_ptr->READ.USR & MCF52XX_UART_USR_RXRDY) == 0 ) {
   } /* Endwhile */

   io_info_ptr->RX_CHARS++;

   return uart_ptr->READ.URB;

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_polled_putc
* Returned Value   : void
* Comments         :
*   Writes the provided character.
*
*END*********************************************************************/

void _mcf52xx_uart_serial_polled_putc
   (
      /* [IN] the address of the device specific information */
      MCF52XX_UART_SERIAL_INFO_STRUCT_PTR io_info_ptr,

      /* [IN] the character to write */
      char                               c
   )
{ /* Body */
   volatile MCF52XX_UART_STRUCT _PTR_ uart_ptr = io_info_ptr->UART_PTR;

   /* Wait until free to send a character */
   while ( (uart_ptr->READ.USR & MCF52XX_UART_USR_TXRDY) == 0 ) {
   } /* Endwhile */

   uart_ptr->WRITE.UTB = c;

   io_info_ptr->TX_CHARS++;

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_polled_status
* Returned Value   : boolean
* Comments         :
*            This function returns TRUE if a character is available
*            on the on I/O device, otherwise it returns FALSE.
*
*END*********************************************************************/

boolean _mcf52xx_uart_serial_polled_status
   (
      /* [IN] the address of the device specific information */
      MCF52XX_UART_SERIAL_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   volatile MCF52XX_UART_STRUCT _PTR_ uart_ptr = io_info_ptr->UART_PTR;
   return (uart_ptr->READ.USR & MCF52XX_UART_USR_RXRDY) != 0;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _mcf52xx_uart_serial_polled_ioctl
* Returned Value   : uint_32 MQX_OK or a mqx error code.
* Comments         :
*    This function performs miscellaneous services for
*    the I/O device.
*
*END*********************************************************************/

uint_32 _mcf52xx_uart_serial_polled_ioctl
   (
      /* [IN] the address of the device specific information */
      MCF52XX_UART_SERIAL_INFO_STRUCT_PTR io_info_ptr,

      /* [IN] The command to perform */
      uint_32                    cmd,

      /* [IN] Parameters for the command */
      uint_32_ptr                param_ptr
   )
{ /* Body */
   volatile MCF52XX_UART_STRUCT _PTR_ uart_ptr = io_info_ptr->UART_PTR;
   uint_32                            baud,tmp;

   switch (cmd) {
      case IO_IOCTL_SERIAL_GET_STOP_BITS:
         tmp = io_info_ptr->INIT.UMR2_VALUE & MCF52XX_UART_UMR2_2_STOP_BITS;
         *param_ptr = (tmp == MCF52XX_UART_UMR2_1_STOP_BIT)
            ? MCF52XX_UART_UMR2_1_STOP_BIT
            : MCF52XX_UART_UMR2_2_STOP_BITS;
         break;
      case IO_IOCTL_SERIAL_SET_STOP_BITS:
         tmp = io_info_ptr->INIT.UMR2_VALUE;
         tmp &= ~MCF52XX_UART_UMR2_MASK_STOP_BITS;
         /* Tell user to change terminal settings */
         switch (*param_ptr) {
         case IO_SERIAL_STOP_BITS_1:
            tmp |= MCF52XX_UART_UMR2_1_STOP_BIT;
            break;
         case IO_SERIAL_STOP_BITS_2:
            tmp |= MCF52XX_UART_UMR2_2_STOP_BITS;
            break;
         default:
            return MQX_INVALID_PARAMETER;
         } /* Endswitch */
         io_info_ptr->INIT.UMR2_VALUE = tmp;
         uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_POINTER;
         uart_ptr->WRITE.UMR = io_info_ptr->INIT.UMR1_VALUE;
         uart_ptr->WRITE.UMR = io_info_ptr->INIT.UMR2_VALUE;
         break;
      case IO_IOCTL_SERIAL_GET_DATA_BITS:
         tmp = io_info_ptr->INIT.UMR1_VALUE & MCF52XX_UART_UMR1_MASK_DATA_BITS;
         *param_ptr = tmp + 5;
         break;
      case IO_IOCTL_SERIAL_SET_DATA_BITS:
         tmp = io_info_ptr->INIT.UMR1_VALUE & ~MCF52XX_UART_UMR1_MASK_DATA_BITS;
         tmp |=                          (*param_ptr == 5)
            ? MCF52XX_UART_UMR1_5_BITS : (*param_ptr == 6)
            ? MCF52XX_UART_UMR1_6_BITS : (*param_ptr == 7)
            ? MCF52XX_UART_UMR1_7_BITS : MCF52XX_UART_UMR1_8_BITS;
         io_info_ptr->INIT.UMR1_VALUE = tmp;
         uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_POINTER;
         uart_ptr->WRITE.UMR = io_info_ptr->INIT.UMR1_VALUE;
         uart_ptr->WRITE.UMR = io_info_ptr->INIT.UMR2_VALUE;
         break;
      case IO_IOCTL_SERIAL_GET_BAUD:
         *param_ptr = io_info_ptr->INIT.BAUD_RATE;
         break;
      case IO_IOCTL_SERIAL_SET_BAUD:
         io_info_ptr->INIT.BAUD_RATE = *param_ptr;
         /* baud = fsck / (32 * baudrate) + 0.5 */ 
         baud = (uint_32)((io_info_ptr->INIT.CLOCK_SPEED + 16 * io_info_ptr->INIT.BAUD_RATE )/ (32 * io_info_ptr->INIT.BAUD_RATE));
         uart_ptr->WRITE.UBG1 = (uchar)((baud >> 8) & 0xFF);
         uart_ptr->WRITE.UBG2 = (uchar)(baud & 0xFF);
         break;
      case IO_IOCTL_SERIAL_GET_STATS:
         *param_ptr++ = io_info_ptr->INTERRUPTS;
         *param_ptr++ = io_info_ptr->RX_CHARS;
         *param_ptr++ = io_info_ptr->TX_CHARS;
         *param_ptr++ = io_info_ptr->RX_BREAKS;
         *param_ptr++ = io_info_ptr->RX_PARITY_ERRORS;
         *param_ptr++ = io_info_ptr->RX_FRAMING_ERRORS;
         *param_ptr++ = io_info_ptr->RX_OVERRUNS;
         *param_ptr++ = io_info_ptr->RX_DROPPED_INPUT;
         break;
      case IO_IOCTL_SERIAL_CLEAR_STATS:
         io_info_ptr->INTERRUPTS = 0;
         io_info_ptr->RX_CHARS = 0;
         io_info_ptr->TX_CHARS = 0;
         io_info_ptr->RX_BREAKS = 0;
         io_info_ptr->RX_PARITY_ERRORS = 0;
         io_info_ptr->RX_FRAMING_ERRORS = 0;
         io_info_ptr->RX_OVERRUNS = 0;
         io_info_ptr->RX_DROPPED_INPUT = 0;
         break;
      case IO_IOCTL_SERIAL_CAN_TRANSMIT:
         *param_ptr = io_info_ptr->UART_PTR->READ.USR & MCF52XX_UART_USR_TXRDY ? 1 : 0;
         break;
      case IO_IOCTL_SERIAL_CAN_RECEIVE:
         *param_ptr = io_info_ptr->UART_PTR->READ.USR & MCF52XX_UART_USR_RXRDY ? 1 : 0;
         break;
      case IO_IOCTL_SERIAL_GET_PARITY:
         switch (io_info_ptr->INIT.UMR1_VALUE & MCF52XX_UART_UMR1_MD_ADDRESS) {
            case MCF52XX_UART_UMR1_EVEN_PARITY:
               tmp = IO_SERIAL_PARITY_EVEN;
               break;
            case MCF52XX_UART_UMR1_ODD_PARITY:
               tmp = IO_SERIAL_PARITY_ODD;
               break;
            case MCF52XX_UART_UMR1_LOW_PARITY:
               tmp = IO_SERIAL_PARITY_SPACE;
               break;
            case MCF52XX_UART_UMR1_HI_PARITY:
               tmp = IO_SERIAL_PARITY_MARK;
               break;
            default:
               tmp = IO_SERIAL_PARITY_NONE;
               break;
         }
         *param_ptr = tmp;
         break;
      case IO_IOCTL_SERIAL_SET_PARITY:
         tmp = io_info_ptr->INIT.UMR1_VALUE & ~MCF52XX_UART_UMR1_MD_ADDRESS;
         switch (*param_ptr) {
            case IO_SERIAL_PARITY_NONE:
               tmp |= MCF52XX_UART_UMR1_NO_PARITY;
               break;
            case IO_SERIAL_PARITY_ODD:
               tmp |= MCF52XX_UART_UMR1_ODD_PARITY;
               break;
            case IO_SERIAL_PARITY_EVEN:
               tmp |= MCF52XX_UART_UMR1_EVEN_PARITY;
               break;
            case IO_SERIAL_PARITY_MARK:
               tmp |= MCF52XX_UART_UMR1_HI_PARITY;
               break;
            case IO_SERIAL_PARITY_SPACE:
               tmp |= MCF52XX_UART_UMR1_LOW_PARITY;
               break;
            default:
               return MQX_INVALID_PARAMETER;
         }
         io_info_ptr->INIT.UMR1_VALUE = tmp;
         uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_POINTER;
         uart_ptr->WRITE.UMR = io_info_ptr->INIT.UMR1_VALUE;
         uart_ptr->WRITE.UMR = io_info_ptr->INIT.UMR2_VALUE;
         break;
      case IO_IOCTL_SERIAL_GET_HW_SIGNAL:
         tmp = 0;
         if (0 == (uart_ptr->READ.UIPCR & MCF52XX_UART_UIP_CTS)) {
            tmp |= IO_SERIAL_CTS;
         }
         if (io_info_ptr->CONTROL_BITS & MCF52XX_UART_UOP_RTS) {
            tmp |= IO_SERIAL_RTS;
         }
         *param_ptr = tmp;
         break;
      case IO_IOCTL_SERIAL_SET_HW_SIGNAL:  /* Assert */
         if (*param_ptr & IO_SERIAL_RTS) {
            if (io_info_ptr->INIT.UMR1_VALUE & MCF52XX_UART_UMR1_RXRTS) {
               return MQX_IO_OPERATION_NOT_AVAILABLE;
            }
            io_info_ptr->CONTROL_BITS |= MCF52XX_UART_UOP_RTS;
         }
         else {
            return MQX_INVALID_PARAMETER;
         }
         uart_ptr->WRITE.UOP1 = MCF52XX_UART_UOP_RTS;
         break;
      case IO_IOCTL_SERIAL_CLEAR_HW_SIGNAL:  /* Negate */
         if (*param_ptr & IO_SERIAL_RTS) {
            if (io_info_ptr->INIT.UMR1_VALUE & MCF52XX_UART_UMR1_RXRTS) {
               return MQX_IO_OPERATION_NOT_AVAILABLE;
            }
            io_info_ptr->CONTROL_BITS &= ~MCF52XX_UART_UOP_RTS;
         }
         else {
            return MQX_INVALID_PARAMETER;
         }
         uart_ptr->WRITE.UOP0 = MCF52XX_UART_UOP_RTS;
         break;         
      case IO_IOCTL_SERIAL_SET_FLAGS:
         /* automatic HW flow control */
    	 io_info_ptr->INIT.UMR1_VALUE &= (~MCF52XX_UART_UMR1_RXRTS);
    	 io_info_ptr->INIT.UMR2_VALUE &= (~MCF52XX_UART_UMR2_TXCTS);
    	 if (*param_ptr & IO_SERIAL_HW_FLOW_CONTROL) {
    		 io_info_ptr->INIT.UMR1_VALUE |= MCF52XX_UART_UMR1_RXRTS;
    		 io_info_ptr->INIT.UMR2_VALUE |= MCF52XX_UART_UMR2_TXCTS;
    	 }
    	 uart_ptr->WRITE.UCR = MCF52XX_UART_UCR_RESET_POINTER;
    	 uart_ptr->WRITE.UMR = io_info_ptr->INIT.UMR1_VALUE;
   	     uart_ptr->WRITE.UMR = io_info_ptr->INIT.UMR2_VALUE;
         break;
      case IO_IOCTL_SERIAL_WAIT_FOR_TC:
         while(!(uart_ptr->READ.USR & MCF52XX_UART_USR_TXEMP)) ;
         break;
      
      default:
         return IO_ERROR_INVALID_IOCTL_CMD;
   } /* Endswitch */

   return (MQX_OK);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2s/int/i2s_int_prv.h<|end_filename|>
#ifndef _i2s_int_prv_h_
#define _i2s_int_prv_h_ 1

/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2s_int_prv.h$
* $Version : 3.8.1.0$
* $Date    : Sep-16-2011$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the I2S I/O functions.
*
*END************************************************************************/

/*--------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/


/*---------------------------------------------------------------------
**
** IO I2S DEVICE STRUCT
**
** This structure used to store information about an I2S interrupt io device
** for the IO device table
*/
typedef struct io_i2s_device_struct
{

    /* The I/O init function */
    _mqx_uint (_CODE_PTR_ DEV_INIT)(pointer, char_ptr);

    /* The I/O deinit function */
    _mqx_uint (_CODE_PTR_ DEV_DEINIT)(pointer, pointer);

    /* [IN] The READ function */
    _mqx_int  (_CODE_PTR_ DEV_READ)(pointer, char_ptr, _mqx_int);

    /* [IN] The WRITE function */
    _mqx_int  (_CODE_PTR_ DEV_WRITE)(pointer, char_ptr, _mqx_int);

    /* The ioctl function, (change bauds etc) */
    _mqx_int  (_CODE_PTR_ DEV_IOCTL)(pointer, _mqx_uint, _mqx_uint_ptr);

    /* The I/O channel initialization data */
    pointer    DEV_INIT_DATA_PTR;

    /* Device specific information */
    pointer    DEV_INFO_PTR;

    /* Open count for number of accessing file descriptors */
    _mqx_uint  COUNT;

    /* Open flags for this channel */
    _mqx_uint  FLAGS;

} IO_I2S_DEVICE_STRUCT, _PTR_ IO_I2S_DEVICE_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

    /* I/O prototypes */
    extern _mqx_int _io_i2s_open(MQX_FILE_PTR fd_ptr, char_ptr open_name_ptr, char_ptr flags);
    extern _mqx_int _io_i2s_close(MQX_FILE_PTR fd_ptr);
    extern _mqx_int _io_i2s_read(MQX_FILE_PTR fd_ptr, char_ptr data_ptr, _mqx_int n);
    extern _mqx_int _io_i2s_write(MQX_FILE_PTR fd_ptr, char_ptr data_ptr, _mqx_int n);
    extern _mqx_int _io_i2s_ioctl(MQX_FILE_PTR fd_ptr, _mqx_uint cmd, pointer input_param_ptr);
    extern _mqx_int _io_i2s_uninstall(IO_DEVICE_STRUCT_PTR io_dev_ptr);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GDFLIB/GDFLIB_FilterFIR.h<|end_filename|>
/*****************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GDFLIB_FilterFIR.h
* 
* @author    r29302 
* 
* @version   1.0.1.0
* 
* @date      Dec-6-2012
* 
* @brief     Header file for the filter FIR function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GDFLIB_FILTERFIR_H_
#define _GDFLIB_FILTERFIR_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/************************************************************************
| defines and macros (scope: module-local)
|-----------------------------------------------------------------------*/

/*! Function alias for the #GDFLIB_FilterFIRInitANSIC function.*/
#define GDFLIB_FilterFIRInit(pParam, pState, pInBuf) \
    GDFLIB_FilterFIRInitANSIC((pParam), (pState), (pInBuf))

/*! Function alias for the #GDFLIB_FilterFIRANSIC function.*/
#define GDFLIB_FilterFIR(f32In, pParam, pState) \
    GDFLIB_FilterFIRANSIC((f32In), (pParam), (pState))

/************************************************************************
| typedefs and structures (scope: module-local)
|-----------------------------------------------------------------------*/

/*------------------------------------------------------------------------*//*!
@struct     GDFLIB_FILTERFIR_PARAM_T "\GDFLIB_FilterFIR.h"

@brief      Structure containing parameters of the filter.
*
*//*-------------------------------------------------------------------------*/
typedef struct  
{    
     UWord32    u32Order;      /*!<FIR filter order, must be 1 or more. */
     const Frac32 *pf32CoefBuf;  /*!<FIR filter coefficients buffer. */
} GDFLIB_FILTERFIR_PARAM_T;

/*------------------------------------------------------------------------*//*!
@struct     GDFLIB_FILTERFIR_STATE_T "\GDFLIB_FilterFIR.h"

@brief      Structure containing the current state of the filter.
*
*//*-------------------------------------------------------------------------*/
typedef struct
{    
     UWord32 u32Idx;          /*!<Input buffer index. */
     Frac32 *pf32InBuf;   /*!<Pointer to the input buffer. */
} GDFLIB_FILTERFIR_STATE_T;

/************************************************************************
| exported variables
|-----------------------------------------------------------------------*/

/************************************************************************
| exported function prototypes
|-----------------------------------------------------------------------*/
/*! 
* @ingroup GDFLIB_GROUP 
*/

void GDFLIB_FilterFIRInitANSIC(const GDFLIB_FILTERFIR_PARAM_T *const pParam,
                               GDFLIB_FILTERFIR_STATE_T *const pState,
                               Frac32 *pf32InBuf);

/*! 
* @ingroup GDFLIB_GROUP 
*/
Frac32 GDFLIB_FilterFIRANSIC(Frac32 f32In,
                              const GDFLIB_FILTERFIR_PARAM_T *const pParam,
                              GDFLIB_FILTERFIR_STATE_T *const pState);

#ifdef __cplusplus
}
#endif
#endif /* _GDFLIB_FILTERFIR_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enet_wifi.h<|end_filename|>
/**HEADER**********************************************************************
*
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
*
*******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* $FileName: enet_wifi.h$
* $Version : 3.6.3.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the definitions of constants,IOCTL'S and structures
*   required for the Wifi operation.
*
*END**************************************************************************/
#ifndef enet_wifi_h
#define enet_wifi_h 1

#include "mqx.h"
#include "bsp.h"
#include "ioctl.h"

/* IOCTL's to set various features of WIFI device. */
#define ENET_SET_MEDIACTL_COMMIT                                 _IO(IO_TYPE_MEDIACTL_WIFI,0x01)
#define ENET_SET_MEDIACTL_FREQ                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x02)
#define ENET_SET_MEDIACTL_MODE                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x03)
#define ENET_SET_MEDIACTL_SCAN                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x04)
#define ENET_SET_MEDIACTL_ESSID                                  _IO(IO_TYPE_MEDIACTL_WIFI,0x05)
#define ENET_SET_MEDIACTL_RATE                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x06)
#define ENET_SET_MEDIACTL_RTS                                    _IO(IO_TYPE_MEDIACTL_WIFI,0x07)
#define ENET_SET_MEDIACTL_RETRY                                  _IO(IO_TYPE_MEDIACTL_WIFI,0x08)
#define ENET_SET_MEDIACTL_ENCODE                                 _IO(IO_TYPE_MEDIACTL_WIFI,0x09)
#define ENET_SET_MEDIACTL_POWER                                  _IO(IO_TYPE_MEDIACTL_WIFI,0x0A)
#define ENET_SET_MEDIACTL_SEC_TYPE                               _IO(IO_TYPE_MEDIACTL_WIFI,0x0B)
#define ENET_SET_MEDIACTL_PASSPHRASE                             _IO(IO_TYPE_MEDIACTL_WIFI,0x0C)
#define ENET_SET_MEDIACTL_DEBUG                                  _IO(IO_TYPE_MEDIACTL_WIFI,0x0D)

/* IOCTL's to get various features of WIFI device. */
#define ENET_GET_MEDIACTL_NAME                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x0E)
#define ENET_GET_MEDIACTL_FREQ                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x0F)
#define ENET_GET_MEDIACTL_MODE                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x10)
#define ENET_GET_MEDIACTL_RANGE                                  _IO(IO_TYPE_MEDIACTL_WIFI,0x11)
#define ENET_GET_MEDIACTL_WAP                                    _IO(IO_TYPE_MEDIACTL_WIFI,0x12)
#define ENET_GET_MEDIACTL_SCAN                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x13)
#define ENET_GET_MEDIACTL_ESSID                                  _IO(IO_TYPE_MEDIACTL_WIFI,0x14)
#define ENET_GET_MEDIACTL_RATE                                   _IO(IO_TYPE_MEDIACTL_WIFI,0x15)
#define ENET_GET_MEDIACTL_RTS                                    _IO(IO_TYPE_MEDIACTL_WIFI,0x16)
#define ENET_GET_MEDIACTL_RETRY                                  _IO(IO_TYPE_MEDIACTL_WIFI,0x17)
#define ENET_GET_MEDIACTL_ENCODE                                 _IO(IO_TYPE_MEDIACTL_WIFI,0x18)
#define ENET_GET_MEDIACTL_POWER                                  _IO(IO_TYPE_MEDIACTL_WIFI,0x19)
#define ENET_GET_MEDIACTL_SEC_TYPE                               _IO(IO_TYPE_MEDIACTL_WIFI,0x20)
#define ENET_MEDIACTL_IS_INITIALIZED                             _IO(IO_TYPE_MEDIACTL_WIFI,0x21)
#define ENET_GET_MEDIACTL_PASSPHRASE                             _IO(IO_TYPE_MEDIACTL_WIFI,0x22)

#define ENET_MEDIACTL_FREQ_AUTO                                  (0x00)/* Let the driver decides */
#define ENET_MEDIACTL_FREQ_FIXED                                 (0x01)/* Force a specific value */
/* Flags for encoding (along with the token) */
#define ENET_MEDIACTL_ENCODE_INDEX                               0x00FF  /* Token index (if needed) */
#define ENET_MEDIACTL_ENCODE_FLAGS                               0xFF00  /* Flags defined below */
#define ENET_MEDIACTL_ENCODE_MODE                                0xF000  /* Modes defined below */
#define ENET_MEDIACTL_ENCODE_DISABLED                            0x8000  /* Encoding disabled */
#define ENET_MEDIACTL_ENCODE_ENABLED                             0x0000  /* Encoding enabled */
#define ENET_MEDIACTL_ENCODE_RESTRICTED                          0x4000  /* Refuse non-encoded packets */
#define ENET_MEDIACTL_ENCODE_OPEN                                0x2000  /* Accept non-encoded packets */
#define ENET_MEDIACTL_ENCODE_NOKEY                               0x0800  /* Key is write only, so not present */
#define ENET_MEDIACTL_ENCODE_TEMP                                0x0400  /* Temporary key */
/* Retry limits and lifetime flags available */
#define ENET_MEDIACTL_RETRY_ON                                   0x0000  /* No details... */
#define ENET_MEDIACTL_RETRY_TYPE                                 0xF000  /* Type of parameter */
#define ENET_MEDIACTL_RETRY_LIMIT                                0x1000  /* Maximum number of retries*/
#define ENET_MEDIACTL_RETRY_LIFETIME                             0x2000  /* Maximum duration of retries in us */
#define ENET_MEDIACTL_RETRY_MODIFIER                             0x00FF  /* Modify a parameter */
#define ENET_MEDIACTL_RETRY_MIN                                  0x0001  /* Value is a minimum  */
#define ENET_MEDIACTL_RETRY_MAX                                  0x0002  /* Value is a maximum */
#define ENET_MEDIACTL_RETRY_RELATIVE                             0x0004  /* Value is not in seconds/ms/us */
#define ENET_MEDIACTL_RETRY_SHORT                                0x0010  /* Value is for short packets  */
#define ENET_MEDIACTL_RETRY_LONG                                 0x0020  /* Value is for long packets */

/* Power management flags available (along with the value, if any) */
#define ENET_MEDIACTL_POWER_ON                                   0x0000  /* No details... */
#define ENET_MEDIACTL_POWER_TYPE                                 0xF000  /* Type of parameter */
#define ENET_MEDIACTL_POWER_PERIOD                               0x1000  /* Value is a period/duration of  */
#define ENET_MEDIACTL_POWER_TIMEOUT                              0x2000  /* Value is a timeout (to go asleep) */
#define ENET_MEDIACTL_POWER_MODE                                 0x0F00  /* Power Management mode */
#define ENET_MEDIACTL_POWER_UNICAST_R                            0x0100  /* Receive only unicast messages */
#define ENET_MEDIACTL_POWER_MULTICAST_R                          0x0200  /* Receive only multicast messages */
#define ENET_MEDIACTL_POWER_ALL_R                                0x0300  /* Receive all messages though PM */
#define ENET_MEDIACTL_POWER_FORCE_S                              0x0400  /* Force PM procedure for sending unicast */
#define ENET_MEDIACTL_POWER_REPEATER                             0x0800  /* Repeat broadcast messages in PM period */
#define ENET_MEDIACTL_POWER_MODIFIER                             0x000F  /* Modify a parameter */
#define ENET_MEDIACTL_POWER_MIN                                  0x0001  /* Value is a minimum  */
#define ENET_MEDIACTL_POWER_MAX                                  0x0002  /* Value is a maximum */
#define ENET_MEDIACTL_POWER_RELATIVE                             0x0004  /* Value is not in seconds/ms/us */

/* Security types */
#define ENET_MEDIACTL_SECURITY_TYPE_NONE                         (0x00)
#define ENET_MEDIACTL_SECURITY_TYPE_WEP                          (0x01)
#define ENET_MEDIACTL_SECURITY_TYPE_WPA                          (0x02)
#define ENET_MEDIACTL_SECURITY_TYPE_WPA2                         (0x03)

#define ENET_MEDIACTL_MODE_AUTO                                  (0)
/* Single cell network */
#define ENET_MEDIACTL_MODE_ADHOC                                 (1)
/* Multi cell network, roaming, ... */
#define ENET_MEDIACTL_MODE_INFRA                                 (2)
/* Synchronisation master or Access Point */
#define ENET_MEDIACTL_MODE_MASTER                                (3)
/* Wireless Repeater (forwarder) */
#define ENET_MEDIACTL_MODE_REPEAT                                (4)
 /* Secondary master/repeater (backup) */
#define ENET_MEDIACTL_MODE_SECOND                                (5)
/* Passive monitor (listen only) */
#define ENET_MEDIACTL_MODE_MONITOR                               (6)
/* Mesh (IEEE 802.11s) network */
#define ENET_MEDIACTL_MODE_MESH                                  (7)


typedef struct __essid
{
    char_ptr  essid;
    uint_16 flags;
    uint_32 length;
}ENET_ESSID,* ENET_ESSID_PTR;

typedef struct _scan_info 
{
    uint_8 channel;
    uint_8 ssid_len;
    uint_8 rssi;
    uint_8 security_enabled;
    uint_16 beacon_period;
    uint_8 preamble;
    uint_8 bss_type;
    uint_8 bssid[6];
    uint_8 ssid[32];
} ENET_SCAN_INFO, * ENET_SCAN_INFO_PTR;

typedef struct _scan_list 
{
    int_32 num_scan_entries;
    ENET_SCAN_INFO_PTR scan_info_list;  
}ENET_SCAN_LIST,* ENET_SCAN_LIST_PTR;
#endif
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/mcf522xx/adc_mcf522xx.h<|end_filename|>
#ifndef __adc_mcf52xx_h__
#define __adc_mcf52xx_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_mcf522xx.h$
* $Version : 3.6.6.0$
* $Date    : Jun-1-2010$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END************************************************************************/

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

#define ADC_HW_CHANNELS         8

#define ADC_RESOLUTION_12BIT   0x1000
#define ADC_RESOLUTION_DEFAULT ADC_RESOLUTION_12BIT

#define ADC_SOURCE_AN0      0x00
#define ADC_SOURCE_AN1      0x01
#define ADC_SOURCE_AN2      0x02
#define ADC_SOURCE_AN3      0x03
#define ADC_SOURCE_AN4      0x04
#define ADC_SOURCE_AN5      0x05
#define ADC_SOURCE_AN6      0x06
#define ADC_SOURCE_AN7      0x07

#define ADC_SOURCE_AN0_AN1  0x08
#define ADC_SOURCE_AN2_AN3  0x09
#define ADC_SOURCE_AN4_AN5  0x10
#define ADC_SOURCE_AN6_AN7  0x11
#define ADC_SOURCE_MAX      0x11

pointer _bsp_get_adc_base_address(void);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/nat_session.h<|end_filename|>
#ifndef __nat_session_h__
#define __nat_session_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nat_session.h$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   Private Network Address Translator definitions.
*
*END************************************************************************/

 


/* 
** NAT_EVENT_STRUCT:
**    Used for timeouts.
**
*/
struct nat_session;

typedef struct nat_event_struct { 
   uint_32                    TIME;    
   struct nat_session_struct _PTR_   SESSION_PTR;
   TCPIP_EVENT_PTR            EVENT;
   struct nat_event_struct _PTR_     NEXT;
   struct nat_event_struct _PTR_     PREV;
} NAT_EVENT_STRUCT, _PTR_ NAT_EVENT_STRUCT_PTR;


/* 
** NAT_SESSION_EXT_STRUCT 
**    Holds ALG specific information attached to a session
*/
typedef struct nat_session_ext_struct {
   struct nat_session_ext_struct _PTR_  NEXT;
   uint_32     ALG_TYPE;
} NAT_SESSION_EXT_STRUCT, _PTR_ NAT_SESSION_EXT_STRUCT_PTR;

/* 
** NAT_SESSION_STRUCT: 
**    Holds information about a sessions. One of these is allocated for 
**    each session.
*/
typedef struct nat_session_struct {
   struct nat_session_struct _PTR_      NEXT_IN;       /* Used for IN tree           */
   struct nat_session_struct _PTR_      NEXT_OUT;      /* Used for OUT tree          */
   _ip_address                   PRV_HST;       /* private host IP            */
   _ip_address                   PUB_HST;       /* public host IP             */
   _ip_address                   NAT_HST;       /* replacement IP             */
   uint_16                       PRV_PORT;      /* private host port          */
   uint_16                       PUB_PORT;      /* public host port           */
   uint_16                       NAT_PORT;      /* replacement port           */
   uint_16                       RESERVED;      /* unused                     */
   uint_32                       IP_PROT;       /* IP protocol                */
   NAT_EVENT_STRUCT              TIMEOUT;       /* to close sessions          */   
   uint_32                       STATE;         /* holds state information    */
   NAT_SESSION_EXT_STRUCT_PTR    ALG_INFO_PTR;  /* ALG specifif information   */
   boolean                       SNAT_OR_DNAT;  /* SNAT or DNAT session       */ 
} NAT_SESSION_STRUCT, _PTR_ NAT_SESSION_STRUCT_PTR;



#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/ipc_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipc_prv.h$
* $Version : 3.0.5.0$
* $Date    : Jul-28-2009$
*
* Comments:
*
*   This file contains the private definitions for the inter-processor
*   communications component.
*
*END************************************************************************/
#ifndef __ipc_prv__
#define __ipc_prv__

/*--------------------------------------------------------------------------*/
/*
 *                          CONSTANT DECLARATIONS
 */

/*
 * The number of ipc messages in the ipc message pool
 * which is created at initialization time.
 */
#define IPC_NUM_MESSAGES        (8)
#define IPC_GROW_MESSAGES       (8)
#define IPC_LIMIT_MESSAGES      (0)

/*
 * 2.3X message types 
 */
#define IPC_MQX_CREATE          (0x01)
#define IPC_MQX_DESTROY         (0x02)
#define IPC_MQX_ACTIVATE        (0x03)
//#define IPC_MQX_TYPE_MASK       (0x03)
#define IPC_MQX_ABORT           (0x05)  
#define IPC_MQX_RESTART         (0x06)
#define IPC_MQX_TYPE_MASK       (0x07)

/* Helpful macros for packing and unpacking the message type */
#define IPC_GET_COMPONENT(t) \
   (((uint_32)(t) >> 16) & 0x3FF)
#define IPC_SET_COMPONENT(t,c)  \
   ((uint_32)(t) | (((uint_32)(c) & 0x3FF) << 16))
#define IPC_SET_IO_COMPONENT(t,c)  \
   ((uint_32)(t) | ((((uint_32)(c) + MAX_KERNEL_COMPONENTS) & 0x3FF) << 16))

#define IPC_GET_NON_BLOCKING(t) \
   ((uint_32)(t) & 0x80000000)
#define IPC_SET_NON_BLOCKING(t,c) \
   ((c) ? ((uint_32)(t) | 0x80000000) : ((uint_32)(t)))

#define IPC_GET_TYPE(t) \
   (((uint_32)(t) >> 8) & 0xFF)
#define IPC_SET_TYPE(t,c) \
   ((uint_32)(t) | ((uint_32)(c) & 0xFF) << 8)

#define IPC_SET_MESSAGE_TYPE(comp,type,non_blocking,val) \
   ((val) | \
   (((uint_32)(comp) & 0x3FF) << 16) | \
   (((uint_32)(type) & 0xFF) << 8) | \
   ((non_blocking) ? 0x80000000 : 0x0))

#define IPC_SET_IO_MESSAGE_TYPE(comp,type,non_blocking,val) \
   ((val) | \
   ((((uint_32)(comp) + MAX_KERNEL_COMPONENTS) & 0x3FF) << 16) | \
   (((uint_32)(type) & 0xFF) << 8) | \
   ((non_blocking) ? 0x80000000 : 0x0))

/* The ipc_task message queue number */
#define IPC_MESSAGE_QUEUE_NUMBER  (1)

/* The most number of parameters that can be sent via the IPC */
#if IPC_DATA_SIZE < 3
#error INVALID IPC DATA SIZE
#endif
#define IPC_MAX_PARAMETERS        (IPC_DATA_SIZE-3)

/* The last parameter is a string to send to the target */
#define IPC_STRING_PARAMETER      (0x8000)

/*--------------------------------------------------------------------------*/
/*
 *                         DATATYPE DECLARATIONS
 */

/* IPC MESSAGE STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief This structure defines the message sent to the ipc task.
 */
typedef struct ipc_message_struct
{
   /*! \brief MQX standard message header. */
   MESSAGE_HEADER_STRUCT HEADER;

   /* 
    * The high bit is set if the message is non-blocking
    * Bits 25 to 16 indicate the component number.
    * Bits 15 to 8  indicate the message type for the component.
    * Bits 1  to 0  are used for task creation, destruction and
    *   activation.
    */
   /*! \brief Type of message. */
   uint_32               MESSAGE_TYPE;

   /*! \brief The number of parameters to follow. */
   uint_32               NUMBER_OF_PARAMETERS;
   
   /*! \brief The task ID of the requesting task. */
   _task_id              REQUESTOR_ID;

   /*! \brief The maximum number of parameters to send. */
   uint_32               PARAMETERS[IPC_MAX_PARAMETERS];
   
} IPC_MESSAGE_STRUCT, _PTR_ IPC_MESSAGE_STRUCT_PTR;
/*! \endcond */

/* IPC MQX MESSAGE STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief This structure defines the ipc messages for 2.3x compatibility.
 */
typedef struct ipc_mqx_message_struct
{

   /*! \brief MQX standard message header. */
   MESSAGE_HEADER_STRUCT HEADER;

   /*! \brief Type of message (see ipc_message_struct). */
   uint_32               MESSAGE_TYPE;

   /*!
    * \brief The task template index on the processor. If 0, then use the task 
    * template embedded in the message.
    */
   uint_32               TEMPLATE_INDEX;

   /*! \brief The task ID of the requesting task. */
   _task_id              REQUESTOR_ID;

   /*! \brief The task ID of the task to be destroyed. */
   _task_id              VICTIM_ID;

   /*! \brief The task creation parameter for the task being created. */
   uint_32               CREATE_PARAMETER;

   /*! \brief The embedded task template. */
   TASK_TEMPLATE_STRUCT  TEMPLATE;

} IPC_MQX_MESSAGE_STRUCT, _PTR_ IPC_MQX_MESSAGE_STRUCT_PTR;
/*! \endcond */


/* IPC COMPONENT STRUCT */
/*! 
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief This structure contains the component information for the IPC task.
 */
typedef struct ipc_component_struct
{
   /*! \brief Handlers for ipc components. */
   IPC_HANDLER_FPTR IPC_COMPONENT_HANDLER[MAX_KERNEL_COMPONENTS];

   /*! \brief Handlers for ipc components. */
   IPC_HANDLER_FPTR IPC_IO_COMPONENT_HANDLER[MAX_IO_COMPONENTS];

} IPC_COMPONENT_STRUCT, _PTR_ IPC_COMPONENT_STRUCT_PTR;
/*! \endcond */
/*--------------------------------------------------------------------------*/
/*
 *                          C PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _ipc_send_internal(boolean, _processor_number, _mqx_uint,
   _mqx_uint, _mqx_uint, ...);      
extern _mqx_uint _event_ipc_handler(pointer imsg_ptr);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/media/ipcp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcp.c$
* $Version : 3.8.14.0$
* $Date    : Sep-19-2012$
*
* Comments:
*
*   This file contains the interface between IP and
*   the PPP packet driver.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"

#include <ppp.h>
#include "pppfsm.h"
#include "ipcp.h"


static void IPCP_lowerup   (pointer);
static void IPCP_lowerdown (pointer);

/*
** The structure used by the application to bind an IP address
** to a PPP channel.
*/

static RTCS_IF_STRUCT rtcs_ppp =
{
    IPCP_init,
    IPCP_destroy
#if RTCSCFG_ENABLE_IP4 
    ,  
    IPCP_send
#if RTCSCFG_ENABLE_IGMP && BSPCFG_ENABLE_ENET_MULTICAST 
    ,
    NULL,
    NULL
#endif
#endif /* RTCSCFG_ENABLE_IP4 */
};

const RTCS_IF_STRUCT_PTR RTCS_IF_PPP = &rtcs_ppp;


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_init
* Returned Value  :  error code
* Comments        :
*     Called by TCP/IP task.  Initializes a PPP link.
*
*END*-----------------------------------------------------------------*/

uint_32 IPCP_init
   (
      IP_IF_PTR   if_ptr
         /* [IN] the IP interface structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4  

   _ppp_handle handle = if_ptr->HANDLE;
   IPCP_CFG_STRUCT_PTR ipcp_ptr;
   PPPFSM_CFG_PTR fsm;
   uint_32 error;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   } /* Endif */

   /* Allocate state for this interface */
   ipcp_ptr = RTCS_mem_alloc(sizeof(IPCP_CFG_STRUCT));
   if (!ipcp_ptr) {
      return RTCSERR_IPCP_CFG;
   } /* Endif */

   /* Initialize the IPCP FSM */
   fsm = &ipcp_ptr->FSM;
   error = PPPFSM_init(fsm, handle, &IPCP_FSM_CALL, if_ptr);
   if (error) {
      _mem_free(ipcp_ptr);
      return PPP_TO_RTCS_ERROR(error);
   } /* Endif */

   /* Register IPCP */
   error = PPP_register(handle, PPP_PROT_IPCP, PPPFSM_input, fsm);
   if (error) {
      PPPFSM_destroy(fsm);
      _mem_free(ipcp_ptr);
      return PPP_TO_RTCS_ERROR(error);
   } /* Endif */

   /* Register IP */
   error = PPP_register(handle, PPP_PROT_IP, IPCP_recv, if_ptr);
   if (error) {
      PPP_unregister(handle, PPP_PROT_IPCP);
      PPPFSM_destroy(fsm);
      _mem_free(ipcp_ptr);
      return PPP_TO_RTCS_ERROR(error);
   } /* Endif */

   ipcp_ptr->HANDLE = handle;
   if_ptr->HANDLE = ipcp_ptr;
   if_ptr->MTU = IP_DEFAULT_MTU;
   if_ptr->ARP = NULL;

   if_ptr->DEV_TYPE    = 20;
   if_ptr->DEV_ADDRLEN = 1;
   if_ptr->DEV_ADDR[0] = 0xFF;
#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4
   if_ptr->SNMP_IF_TYPE = IPIFTYPE_PPP;
#endif
   return RTCS_OK;

#else
    
    return RTCSERR_IP_IS_DISABLED;    
    
#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_destroy
* Returned Value  :  error code
* Comments        :
*     Called by TCP/IP task.  Closes a PPP link.
*
*END*-----------------------------------------------------------------*/

uint_32 IPCP_destroy
   (
      IP_IF_PTR   if_ptr
         /* [IN] the IP interface structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;

   PPP_unregister(ipcp_ptr->HANDLE, PPP_PROT_IP);
   PPP_unregister(ipcp_ptr->HANDLE, PPP_PROT_IPCP);
   PPPFSM_lowerdown(&ipcp_ptr->FSM);
   PPPFSM_destroy(&ipcp_ptr->FSM);
   _mem_free(ipcp_ptr);
   if_ptr->HANDLE = NULL;

   return RTCS_OK;

#else
    
    return RTCSERR_IP_IS_DISABLED;    
    
#endif /* RTCSCFG_ENABLE_IP4 */   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_bind
* Returned Value  :  error code
* Comments        :
*     Called by TCP/IP task.  Initializes and opens a PPP link.
*
*END*-----------------------------------------------------------------*/

void IPCP_bind
   (
      TCPIP_PARM_IPCP _PTR_ parms
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   IP_IF_PTR            if_ptr = parms->handle;
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;
   _ppp_handle          handle = ipcp_ptr->HANDLE;
   uint_32              error;

   ipcp_ptr->CALLUP  = IPCP_lowerup;
   ipcp_ptr->PARAMUP = &ipcp_ptr->FSM;
   ipcp_ptr->CALLDOWN  = IPCP_lowerdown;
   ipcp_ptr->PARAMDOWN = &ipcp_ptr->FSM;

   error = PPP_setcall(handle, PPP_CALL_LINK_UP, &ipcp_ptr->CALLUP, &ipcp_ptr->PARAMUP);
   if (!error) {
      error = PPP_setcall(handle, PPP_CALL_LINK_DOWN, &ipcp_ptr->CALLDOWN, &ipcp_ptr->PARAMDOWN);
      if (error) {
         PPP_setcall(handle, PPP_CALL_LINK_UP, &ipcp_ptr->CALLUP, &ipcp_ptr->PARAMUP);
      } /* Endif */
   } /* Endif */

   if (!error) {
      ipcp_ptr->IP_UP    = parms->data->IP_UP;
      ipcp_ptr->IP_DOWN  = parms->data->IP_DOWN;
      ipcp_ptr->IP_PARAM = parms->data->IP_PARAM;

      ipcp_ptr->INIT.ACCEPT_LOCAL_ADDR  = parms->data->ACCEPT_LOCAL_ADDR;
      ipcp_ptr->INIT.LOCAL_ADDR         = parms->data->LOCAL_ADDR;
      ipcp_ptr->INIT.ACCEPT_REMOTE_ADDR = parms->data->ACCEPT_REMOTE_ADDR;
      ipcp_ptr->INIT.REMOTE_ADDR        = parms->data->REMOTE_ADDR;
      ipcp_ptr->INIT.DEFAULT_NETMASK    = parms->data->DEFAULT_NETMASK;
      ipcp_ptr->INIT.NETMASK            = parms->data->NETMASK;
      ipcp_ptr->INIT.DEFAULT_ROUTE      = parms->data->DEFAULT_ROUTE;
      ipcp_ptr->INIT.NEG_LOCAL_DNS      = parms->data->NEG_LOCAL_DNS;
      ipcp_ptr->INIT.ACCEPT_LOCAL_DNS   = parms->data->ACCEPT_LOCAL_DNS;
      ipcp_ptr->INIT.LOCAL_DNS          = parms->data->LOCAL_DNS;
      ipcp_ptr->INIT.NEG_REMOTE_DNS     = parms->data->NEG_REMOTE_DNS;
      ipcp_ptr->INIT.ACCEPT_REMOTE_DNS  = parms->data->ACCEPT_REMOTE_DNS;
      ipcp_ptr->INIT.REMOTE_DNS         = parms->data->REMOTE_DNS;

      /* Start IPCP */
      PPPFSM_open(&ipcp_ptr->FSM, 0);

      /* Open the link */
      error = PPP_open(handle, 0);

   } /* Endif */

   RTCSCMD_complete(parms, PPP_TO_RTCS_ERROR(error));

#else
    
    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);
    
#endif /* RTCSCFG_ENABLE_IP4 */     

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_lowerup
* Returned Value  :  void
* Comments        :
*     Called by PPP.  Begin negotiating IPCP once PPP is up.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4 

static void IPCP_lowerup
   (
      pointer fsm
            /* [IN] - IPCP automaton */
   )
{ /* Body */
   IP_IF_PTR            if_ptr = ((PPPFSM_CFG_PTR)fsm)->PRIVATE;
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;

   /* Set the MTU */
   if_ptr->MTU = PPP_getmtu(ipcp_ptr->HANDLE);

   /* Call the previous PPP_LINK_UP callback */
   if (ipcp_ptr->CALLUP) {
      ipcp_ptr->CALLUP(ipcp_ptr->PARAMUP);
   } /* Endif */

   /* Start IPCP */
   PPPFSM_lowerup(fsm);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_lowerdown
* Returned Value  :  void
* Comments        :
*     Called by PPP.  Terminate IPCP once PPP is down.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4 

static void IPCP_lowerdown
   (
      pointer fsm
            /* [IN] - IPCP automaton */
   )
{ /* Body */
   IP_IF_PTR            if_ptr = ((PPPFSM_CFG_PTR)fsm)->PRIVATE;
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;

   /* Call the previous PPP_LINK_DOWN callback */
   if (ipcp_ptr->CALLDOWN) {
      ipcp_ptr->CALLDOWN(ipcp_ptr->PARAMDOWN);
   } /* Endif */

   /* Start IPCP */
   PPPFSM_lowerdown(fsm);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_recv
* Returned Value  :  nothing
* Comments        :
*     Called by PPP.  Service an incoming IP datagram.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4 

void IPCP_recv
   (
      PCB_PTR     pcb,
            /* [IN] received packet */
      pointer     handle
            /* [IN] IPCP configuration */
   )
{ /* Body */
   IP_IF_PTR            if_ptr = handle;
   RTCSPCB_PTR          packet;
   uint_32              error;

   IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_TOTAL++);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_RX_OCTETS += pcb->FRAG[0].LENGTH);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_RX_UNICAST++);

   packet = RTCSPCB_alloc_recv(pcb);
   if (packet == NULL) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_MISSED++);
      PCB_free(pcb);
      return;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(packet);

   error = RTCSPCB_next(packet, 2);
   if (error) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_ERRORS++);
      IF_IPIF_STATS_ENABLED(RTCS_seterror(&if_ptr->STATS.ERR_RX, error, (uint_32)packet));
      RTCSLOG_PCB_FREE(packet, error);
      RTCSPCB_free(packet);
      return;
   } /* Endif */

   RTCSLOG_PCB_READ(packet, RTCS_LOGCTRL_IFTYPE(IPIFTYPE_PPP), 0);

   packet->TYPE = RTCSPCB_TYPE_ONLYCAST;
   packet->IFSRC = if_ptr;

   if (!RTCSCMD_service(packet, IP_service)) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_MISSED++);
      RTCSLOG_PCB_FREE(packet, RTCS_OK);
      RTCSPCB_free(packet);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_send
* Returned Value  :  nothing
* Comments        :
*     Called by IP_Send.  Send an IP datagram over a PPP link.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4 

uint_32 IPCP_send
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      RTCSPCB_PTR    pcb,
         /* [IN] the packet to send */
      _ip_address    src,
         /* [IN] the next-hop source address */
      _ip_address    dest,
         /* [IN] the next-hop destination address */
      pointer        data
         /* [IN] unused */
   )
{ /* Body */
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;
   _ppp_handle          handle = ipcp_ptr->HANDLE;
   uint_32              error;

   IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_TOTAL++);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_OCTETS += RTCSPCB_SIZE(pcb));
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_UNICAST++);

   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_IFTYPE(IPIFTYPE_PPP), 0);

   error = RTCSPCB_insert_header(pcb, 2);
   if (error) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_ERRORS++);
      IF_IPIF_STATS_ENABLED(RTCS_seterror(&if_ptr->STATS.ERR_TX, error, (uint_32)pcb));
      RTCSLOG_PCB_FREE(pcb, error);
      RTCSPCB_free(pcb);
      return error;
   } /* Endif */

   pcb->PCBPTR->FRAG[0].LENGTH   = pcb->HEADER_FRAG_USED;
   pcb->PCBPTR->FRAG[0].FRAGMENT = RTCSPCB_DATA(pcb);

   error = PPP_send(handle, PPP_PROT_IP, pcb->PCBPTR);
   RTCSLOG_PCB_FREE(pcb, error);
   if (error) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_ERRORS++);
      IF_IPIF_STATS_ENABLED(RTCS_seterror(&if_ptr->STATS.ERR_TX, error, (uint_32)pcb));
   } /* Endif */

   return error;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_get_local_addr
* Returned Value  :  void
* Comments        :
*     Called by the application to get local address.
*
*END*-----------------------------------------------------------------*/

_ip_address  IPCP_get_local_addr
   (
      _rtcs_if_handle   ihandle
            /* [IN] - interface handle */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   IP_IF_PTR            if_ptr = ihandle;
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;
   return ipcp_ptr->LOPT.ADDR;

#else

    return 0;   

#endif /* RTCSCFG_ENABLE_IP4 */
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPCP_get_peer_addr
* Returned Value  :  void
* Comments        :
*     Called by the application to get local address.
*
*END*-----------------------------------------------------------------*/

_ip_address  IPCP_get_peer_addr
   (
      _rtcs_if_handle   ihandle
            /* [IN] - interface handle */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   IP_IF_PTR            if_ptr = ihandle;
   IPCP_CFG_STRUCT_PTR  ipcp_ptr = if_ptr->HANDLE;
   return ipcp_ptr->POPT.ADDR;

#else

    return 0;   

#endif /* RTCSCFG_ENABLE_IP4 */
   
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/iftraps.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iftraps.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "snmpcfg.h"
#include "asn1.h"
#include "snmp.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_trap_target_add
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Register an IP address to direct SNMP traps to.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_trap_target_add(_ip_address ip_addr) {

#if RTCSCFG_ENABLE_IP4

   TRAP_PARM   parms;
   uint_32     error;

   parms.address = ip_addr;
   
   error = RTCSCMD_issue(parms, RTCS_insert_trap_receiver_internal);

   return error;

#else

    return RTCSERR_IP_IS_DISABLED; 

#endif /* RTCSCFG_ENABLE_IP4 */   

}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_trap_target_remove
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Register an IP address to direct SNMP traps to.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_trap_target_remove(_ip_address ip_addr) {

#if RTCSCFG_ENABLE_IP4

   TRAP_PARM   parms;
   uint_32     error;

   parms.address = ip_addr;
   
   error = RTCSCMD_issue(parms, RTCS_remove_trap_receiver_internal);

   return error;


#else

    return RTCSERR_IP_IS_DISABLED; 

#endif /* RTCSCFG_ENABLE_IP4 */     

}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/crc/crc_kn.c<|end_filename|>

/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: crc_kn.c$
* $Version : 3.8.1.1$
* $Date    : Aug-10-2012$
*
* Comments:
*
*   The file contains the functions which use to calculate CRC 
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "crc_kn.h"


/********************************************************************/
uint_32 CRC_Config(uint_32 poly,uint_32 tot,uint_32 totr,uint_32 fxor,uint_32 tcrc)
{
  CRC_MemMapPtr CRC_ADDR = CRC_BASE_PTR ;   
  uint_32       error = CRC_ERR_SUCCESS;
     
/*
*  Configure CRC_CTRL Register
*/
  if( tot > 3 ) 
  {
	  	error = CRC_ERR_TOT_VAL;
  }
  else if( totr > 3 ) 
  {
  		error = CRC_ERR_TOTR_VAL;
  }
  else if( fxor > 1 ) 
  {
  		error = CRC_ERR_FXOR_VAL;
  }
  else if( tcrc > 1 ) 
  {
  		error = CRC_ERR_TCRC_VAL;
  } 
  else 
  {
  		CRC_ADDR->CTRL = ((tot<<30)|(totr<<28)|(fxor<<26)|(tcrc<<24));
  }

/*  
*   Configure Polynomial Register
*/   
  CRC_ADDR->GPOLY = poly;

 return(error);
}


 /********************************************************************  
  * 16bit data CRC Calculation
 ********************************************************************/  
uint_32 CRC_Cal_16(uint_32 seed,uint_8 *msg, uint_32 sizeBytes)
{
   CRC_MemMapPtr CRC_ADDR = CRC_BASE_PTR;   
  uint_32 	ctrl_reg,data_out,data_in;
  uint_8  	*pCRCBytes;
  uint_32 	sizeWords;
  uint_32 	i,j;
  
/*
*	Input seed, Set WaS=1
*/
  ctrl_reg = CRC_ADDR->CTRL;
  CRC_ADDR->CTRL = ctrl_reg | 0x02000000;
  CRC_ADDR->CRC  = seed;
/*  
*   Input data, Set WaS=0
*/
  CRC_ADDR->CTRL = ctrl_reg & 0xFD000000;
  
/*
*   Wait for calculation completion
*/
  sizeWords = sizeBytes>>1;
  j = 0;
  for(i=0;i<sizeWords;i++){ 
      data_in = (msg[j] << 8) | (msg[j+1]);
      j += 2;
      CRC_ADDR->ACCESS16BIT.CRCL = data_in; 
  }
  if(j<sizeBytes)
  { 
     pCRCBytes = (uint_8*)&(CRC_ADDR->CRC);
     *pCRCBytes++ = msg[j];
  }
  data_out=CRC_ADDR->CRC;

 return(data_out);
}
/********************************************************************
* 32bit data CRC Calculation
********************************************************************/  
uint_32 CRC_Cal_32(uint_32 seed,uint_8 *msg, uint_32 sizeBytes)
{
   CRC_MemMapPtr CRC_ADDR = CRC_BASE_PTR;   
  uint_32  ctrl_reg,data_out,data_in;
  uint_32  sizeDwords;
  uint_8   *pCRCBytes;
  int i,j;
/*  
*   Input seed, Set WaS=1
*/
  ctrl_reg = CRC_ADDR->CTRL;
  CRC_ADDR->CTRL = ctrl_reg | 0x02000000;
  CRC_ADDR->CRC = seed;
 
/* 
*   Input data, Set WaS=0
*/
  CRC_ADDR->CTRL = ctrl_reg & 0xFD000000;
  
/*  
*   Wait for calculation completion
*/
  
  sizeDwords = sizeBytes>>2;
  j = 0;
  for(i=0;i<sizeDwords;i++){ 
      data_in = ((msg[j] << 24) | (msg[j+1] << 16) | (msg[j+2] << 8) | msg[j+3]);
      j += 4;
      CRC_ADDR->CRC = data_in; 
  }
  if(j<sizeBytes)
  {
    pCRCBytes = (uint8_t*)&CRC_ADDR->CRC;

#if  defined(BYTE_ENABLES_1_2_4_8)   
/*
*  write single byte  
*/
    for(;j<sizeBytes;j++)
    {     
       *pCRCBytes++ = msg[j];
    }
#elif  defined(BYTE_ENABLES_3_6_C)     
/*
*  write two bytes
*/
    data_in = 0;
    i = 0;
    for(;j<sizeBytes;j++)
    {     
      data_in = (data_in <<8) | msg[j];
      i++;
      if(i==2)
      {
        i = 0;
        CRC_ADDR->ACCESS16BIT.CRCL = data_in;
      }
    }
    if(i==1)
    {
    	 CRC_ADDR->ACCESS16BIT.CRCLL = data_in; 	
    }
#elif  defined(BYTE_ENABLES_7_E)        
/*
* write three bytes
*/
    data_in = 0;
    i = 0;
    for(;j<sizeBytes;j++)
    {     
      data_in = (data_in <<8) | msg[j];
      i++;
      if(i==3)
      {
        i = 0;
        /* write first  char */
        CRC_ADDR->ACCESS16BIT.CRCHL = (data_in>>16) & 0xff;
        /*  write last two chars */
        CRC_ADDR->ACCESS16BIT.CRCL  = data_in & 0x00ffff;     /*  write low word */
       }
    }
    if( i == 2)
    {
       CRC_ADDR->ACCESS16BIT.CRCL = (data_in); /* write last byte */
    }
    else if (i == 1)
    {
       CRC_ADDR->ACCESS16BIT.CRCLL = data_in; /* write last byte      */
    }
#else                          /* write low byte only */
    for(;j<sizeBytes;j++)
    {     
       *pCRCBytes = msg[j];
    }
#endif            
  }
  data_out=CRC_ADDR->CRC;

 return(data_out);
}
 /********************************************************************/ 
uint_32 CRC_init(void)
{
	/* Enable clock gating to CRC */
#if defined BSP_TWRMCF51JF || defined BSP_TWRMCF51QM 
	SIM_SCGC3 |= SIM_SCGC3_CRC_MASK;
#else	
	SIM_SCGC6 |= SIM_SCGC6_CRC_MASK;
#endif
	return 0;
}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/int_ctrl/qintc.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: qintc.h$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definitions for the INTC module.
*
*END************************************************************************/


#ifndef __qintc_h__
#define __qintc_h__


/* INTC */
#define QINTC_BCR_VTES     (1<<5)
#define QINTC_BCR_HVEN     (1<<0)

#define QINTC_CPR_PRI      (0x0000000F)

#define QINTC_IACKR_VTBA   (0xFFFFF800)
#define QINTC_IACKR_INTVEC (0x000007FC)

#define QINTC_SSCIR_SET    (1<<1)
#define QINTC_SSCIR_CLR    (1<<0)

#define QINTC_PSR_PRI      (0x0000000F)

/* PRI values */
#define QINTC_PRI_MAX      (15) /* Priority 15 (highest) */
#define QINTC_PRI_MIN      (0)  /* Priority 0 (lowest) */


/* Register access */
typedef struct qintc_reg_struct
{
    uint_32 BCR;        /* block configuration register */
    uint_32 R_0x08;
    uint_32 CPR;        /* current priority register */
    uint_32 R_0x0C;
    uint_32 IACKR;      /* interrupt acknowledge register */
    uint_32 R_0x14;
    uint_32 EOIR;       /* end-of-interrupt register */
    uint_32 R_0x1C;
    uint_8  SSCIR[8];   /* software set/clear interrupt registers */
    uint_32 R_0x28[6];
    uint_8  PSR[256];   /* priority select registers */

} QINTC_REG_STRUCT;

typedef volatile struct qintc_reg_struct * VQINTC_REG_STRUCT_PTR;


#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcsrtos.h<|end_filename|>
#ifndef __rtcsrtos_h__
#define __rtcsrtos_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcsrtos.h$
* $Version : 3.0.8.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   This file contains the definitions required to
*   use RTCS with MQX.
*
*END************************************************************************/

#ifdef __cplusplus
extern "C" {
#endif

/* MQX is the only one supported */
#include <rtcs25x.h>


/***************************************
**
** Random Number Generation
*/

void     RTCS_rand_seed (uint_32);
uint_32  RTCS_rand      (void);


/***************************************
**
** The _iopcb_handle
*/

#ifndef __IOPCB__
#define __IOPCB__

#define IOPCB_IOCTL_S_ACCM       4
#define IOPCB_IOCTL_R_ACCM       5
#define IOPCB_IOCTL_GET_IFTYPE   6
#define IOPCB_IOCTL_S_PFC        14
#define IOPCB_IOCTL_R_PFC        15
#define IOPCB_IOCTL_S_ACFC       16
#define IOPCB_IOCTL_R_ACFC       17

typedef struct _iopcb_table {
   uint_32 (_CODE_PTR_ OPEN)  (struct _iopcb_table _PTR_, void (_CODE_PTR_)(pointer), void (_CODE_PTR_)(pointer), pointer);
   uint_32 (_CODE_PTR_ CLOSE) (struct _iopcb_table _PTR_);
   PCB_PTR (_CODE_PTR_ READ)  (struct _iopcb_table _PTR_, uint_32);
   void    (_CODE_PTR_ WRITE) (struct _iopcb_table _PTR_, PCB_PTR, uint_32);
   uint_32 (_CODE_PTR_ IOCTL) (struct _iopcb_table _PTR_, uint_32, pointer);
} _PTR_ _iopcb_handle;

#define _iopcb_open(h,up,down,param)   ((h)->OPEN(h,up,down,param))
#define _iopcb_close(h)                ((h)->CLOSE(h))
#define _iopcb_read(h,flags)           ((h)->READ(h,flags))
#define _iopcb_write(h,pcb,flags)      ((h)->WRITE(h,pcb,flags))
#define _iopcb_ioctl(h,opt,val)        ((h)->IOCTL(h,opt,val))

#endif




#ifdef __cplusplus
}
#endif


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/rtcspcb.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcspcb.c$
* $Version : 3.5.9.0$
* $Date    : Nov-24-2009$
*
* Comments:
*
*   This file contains the PCB (Packet Control Block)
*   library.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"

#define PCBLOG(x) /*printf x*/


/*
** Note:  The following discussion deals with two different types of data
** structures.  A 'PCB' is a very simple structure consisting of a 'free'
** function and a sequence of fragments.  An 'RTCSPCB' is a larger
** structure used by RTCS to hold extra information for 'PCB's.
**
** For PCBs generated on the local host, RTCS calls RTCSPCB_alloc_send(),
** and PCB_PTR points to the PCB field.  The PCB is initialized with only
** one fragment, which is stored in the BUFFER array.
**
** For PCBs arriving from the link layer, RTCS calls RTCSPCB_alloc_recv(),
** and PCB_PTR points the the received PCB.  Here, the PCB, FRAG and BUFFER
** fields of the RTCSPCB are unused.
**
** In both cases, PCB_PTR points to the "actual" PCB.
**
** Some terminology:  RTCSPCBs where PCB_PTR points to the PCB field will
** be called S-PCBs (since they're allocated with RTCSPCB_alloc_send()),
** and RTCSPCBs where PCB_PTR points to an external PCB will be called
** R-PCBs (since they're allocated with RTCSPCB_alloc_recv()).
**
** Now, there exist situations (e.g. IP forwarding) where we want to
** convert an R-PCB to an S-PCB.  In order to do this, we cut the R-PCB's
** first fragment at the current layer, and prepend a fragment for the
** new headers.  This is done by RTCSPCB_fork().  Note that we must prepend
** a fragment:  although there was room in the R-PCB's first fragment for
** headers, we can't use it in case the new headers turn out to be larger
** than the old ones.
**
** Additionally, there are situations where we want to duplicate an RTCSPCB
** (e.g. broadcasting and multicasting).  RTCSPCB_alloc_dup() will allocate
** an S-PCB containing the same data as the original.
**
*/


static void RTCSPCB_free_internal(PCB_PTR);


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_construct
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Construct an RTCSPCB.
*
*END*-----------------------------------------------------------------*/

static int_32 RTCSPCB_construct
   (
      pointer block
   )
{ 
   RTCSPCB_PTR rtcs_pcb = block;

   rtcs_pcb->PCB.FREE    = RTCSPCB_free_internal;
   rtcs_pcb->PCB.PRIVATE = rtcs_pcb;

   rtcs_pcb->DUPPTR = NULL;
   RTCS_sem_init(&rtcs_pcb->DUPCOUNT);

   rtcs_pcb->PCB_ORIG = NULL;

   rtcs_pcb->FREE_FRAG_BITFIELD = 0;

   rtcs_pcb->UDP_REQUEST = NULL;

   return RTCS_OK;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_destroy
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Destroy an RTCSPCB.
*
*END*-----------------------------------------------------------------*/

static int_32 RTCSPCB_destroy
   (
      pointer block
   )
{ 
   RTCSPCB_PTR rtcs_pcb = block;

   RTCS_sem_destroy(&rtcs_pcb->DUPCOUNT);

   return RTCS_OK;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_init
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Initializes the PCB module.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSPCB_init
   (
      void
   )
{
   RTCS_DATA_PTR    RTCS_data_ptr;

   RTCS_data_ptr = RTCS_get_data();

   RTCS_data_ptr->RTCS_PCB_partition =
      RTCS_part_create(sizeof(RTCSPCB),_RTCSPCB_init, _RTCSPCB_grow, _RTCSPCB_max,
         RTCSPCB_construct, RTCSPCB_destroy);
   if (RTCS_data_ptr->RTCS_PCB_partition == 0) {
      return RTCSERR_PCB_ALLOC;
   } /* Endif */

   return RTCS_OK;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_alloc
*  Returned Value : pcb_ptr or NULL
*  Comments       :
*         Allocate an RTCSPCB
*
*END*-----------------------------------------------------------------*/

RTCSPCB_PTR RTCSPCB_alloc
   (
      void
   )
{ 
   RTCS_DATA_PTR     RTCS_data_ptr;
   RTCSPCB_PTR       rtcs_pcb;

   RTCS_data_ptr = RTCS_get_data();

   rtcs_pcb = RTCS_part_alloc(RTCS_data_ptr->RTCS_PCB_partition);

   if (rtcs_pcb != NULL) {
      rtcs_pcb->IP_SUM_PTR = NULL;
      _mem_zero(&rtcs_pcb->LINK_OPTIONS, sizeof(rtcs_pcb->LINK_OPTIONS));
   } /* Endif */

   RTCSLOG_PCB_ALLOC(rtcs_pcb);

   return rtcs_pcb;

}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_alloc_send
*  Returned Value : pointer to PCB
*  Comments       :
*        Allocates a PCB for sending.
*        Caller must still fill in FRAG[n] and SIZE.
*
*END*-----------------------------------------------------------------*/

RTCSPCB_PTR RTCSPCB_alloc_send
   (
      void
   )
{ 
   RTCSPCB_PTR          rtcs_pcb;
   PCB_FRAGMENT _PTR_   pcb_frag_ptr;

   rtcs_pcb = RTCSPCB_alloc();

   if (rtcs_pcb != NULL) {

      rtcs_pcb->PCBPTR = &rtcs_pcb->PCB;

      pcb_frag_ptr = rtcs_pcb->PCB.FRAG;
      pcb_frag_ptr->LENGTH   = 0;

      // grows down from end of buffer 
      pcb_frag_ptr->FRAGMENT = &rtcs_pcb->HEADER_FRAG_BUFFER[RTCSPCB_DATA_MAX];
      
      // The following code assumed that PCB immediately followed BUFFER in RTCS_PCB data structure
      /* grows down into BUFFER */
      // pcb_frag_ptr->FRAGMENT = (uchar_ptr)&pcb->PCB;  
      
      pcb_frag_ptr++;
      pcb_frag_ptr->LENGTH   = 0;
      pcb_frag_ptr->FRAGMENT = NULL;

      rtcs_pcb->HEADER_FRAG_USED = 0;
      rtcs_pcb->HEADER_FRAG_FREE = RTCSPCB_DATA_MAX;
      rtcs_pcb->NUM_FRAGS = 1;
      
      RTCSPCB_SIZE(rtcs_pcb) = 0;
      RTCSPCB_DATA(rtcs_pcb) = rtcs_pcb->PCB.FRAG[0].FRAGMENT;

      rtcs_pcb->TYPE = RTCSPCB_TYPE_ONLYCAST;

      rtcs_pcb->PCB_FREE = NULL;
   }

   return rtcs_pcb;

} 



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_alloc_recv
*  Returned Value : pointer to PCB
*  Comments       :
*        Allocates a PCB for receiving.
*
* 
*
*END*-----------------------------------------------------------------*/

RTCSPCB_PTR RTCSPCB_alloc_recv
   (
      PCB_PTR  inpcb
         /* [IN] received packet */
   )
{ 
   RTCSPCB_PTR      rtcs_pcb;
   PCB_FRAGMENT_PTR frag;

   rtcs_pcb = RTCSPCB_alloc();

   if (rtcs_pcb != NULL) {

      rtcs_pcb->PCBPTR  = inpcb;

      rtcs_pcb->HEADER_FRAG_USED = inpcb->FRAG[0].LENGTH;
      rtcs_pcb->HEADER_FRAG_FREE = 0;
      
      // We are not using the PCB contained in the RTCS_PCB, so
      // NUM_FRAGS is set to 0 to indicate this.
      rtcs_pcb->NUM_FRAGS = 0;   
      RTCSPCB_SIZE(rtcs_pcb) = 0;
      RTCSPCB_DATA(rtcs_pcb) = inpcb->FRAG[0].FRAGMENT;

      for (frag = inpcb->FRAG; frag->LENGTH; frag++) {
         RTCSPCB_SIZE(rtcs_pcb) += frag->LENGTH;
      } 
      
      rtcs_pcb->PCB_FREE    = inpcb->FREE;
      rtcs_pcb->PCB_PRIVATE = inpcb->PRIVATE;
      rtcs_pcb->PCB_BUFFER  = inpcb->FRAG[0];
      inpcb->FREE      = RTCSPCB_free_internal;
      inpcb->PRIVATE   = rtcs_pcb;
   } 
   
   return rtcs_pcb;

} 



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_alloc_dup
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Duplicate a PCB.
*
*END*-----------------------------------------------------------------*/

RTCSPCB_PTR RTCSPCB_alloc_dup
   (
      RTCSPCB_PTR    orig_rtcs_pcb
         /* [IN] packet to duplicate */
   )
{ 
   RTCSPCB_PTR rtcs_pcb;

   rtcs_pcb = RTCSPCB_alloc();

   if (rtcs_pcb != NULL) {
      RTCS_sem_destroy(&rtcs_pcb->DUPCOUNT);

      _mem_copy((uchar_ptr)orig_rtcs_pcb, (uchar_ptr)rtcs_pcb, sizeof(RTCSPCB));
      rtcs_pcb->PCB.PRIVATE = rtcs_pcb;

      rtcs_pcb->PCBPTR = &rtcs_pcb->PCB;

      if (orig_rtcs_pcb->PCBPTR == &orig_rtcs_pcb->PCB) {

         /* Packet originated on this host */

         RTCSPCB_DATA(rtcs_pcb) = rtcs_pcb->HEADER_FRAG_BUFFER + (RTCSPCB_DATA(orig_rtcs_pcb) - orig_rtcs_pcb->HEADER_FRAG_BUFFER);

         if (rtcs_pcb->IP_SUM_PTR) {
            rtcs_pcb->IP_SUM_PTR = rtcs_pcb->HEADER_FRAG_BUFFER + (orig_rtcs_pcb->IP_SUM_PTR - orig_rtcs_pcb->HEADER_FRAG_BUFFER);
         } 

      } else {
         _mem_copy(orig_rtcs_pcb->PCBPTR->FRAG, rtcs_pcb->PCB.FRAG, sizeof(PCB_FRAGMENT)*2);

      } 

      rtcs_pcb->PCB_FREE = NULL;
      rtcs_pcb->PCB_ORIG = NULL;

      RTCS_sem_init(&rtcs_pcb->DUPCOUNT);
      RTCSPCB_depend(rtcs_pcb, orig_rtcs_pcb);  /* can't fail because we allocated pcb */

      rtcs_pcb->UDP_REQUEST = NULL;
      rtcs_pcb->FREE_FRAG_BITFIELD = 0;

      PCBLOG(("\nPCB: Alloc_dup: returning %p, duplicate of %p", rtcs_pcb, orig_rtcs_pcb));
   } 
   return rtcs_pcb;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_depend
*  Returned Value : uint_32
*  Comments       :
*        Adds a dependency to another PCB.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSPCB_depend
   (
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] pcb that depends on another */
      RTCSPCB_PTR    orig_rtcs_pcb
         /* [IN] pcb that is given a dependency */
   )
{
   
   if (rtcs_pcb->DUPPTR) {
      return RTCSERR_PCB_DEPEND;
   } 

   rtcs_pcb->DUPPTR   = orig_rtcs_pcb;
   RTCS_sem_post(&orig_rtcs_pcb->DUPCOUNT);

   return RTCS_OK;
} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_fork
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Prepends a fragment to a received PCB to allow it to be sent.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSPCB_fork
   (
      RTCSPCB_PTR    rtcs_pcb
         /* [IN] packet to fork */
   )
{ 
   PCB_PTR            rx_pcb_ptr;
   uint_32           frag;

   if (rtcs_pcb->NUM_FRAGS != 0) {
      PCBLOG(("\nPCB: Fork: can't fork %p", rtcs_pcb));
      return RTCSERR_PCB_FORK;
   } 

   rx_pcb_ptr = rtcs_pcb->PCBPTR; 
   if (rx_pcb_ptr == &rtcs_pcb->PCB) {
      PCBLOG(("\nPCB: Fork: can't fork %p", rtcs_pcb));
      return RTCSERR_PCB_FORK;
   } 
   

   if (!rtcs_pcb->DUPPTR) {
      rx_pcb_ptr->FREE    = rtcs_pcb->PCB_FREE;
      rx_pcb_ptr->PRIVATE = rtcs_pcb->PCB_PRIVATE;
      rx_pcb_ptr->FRAG[0] = rtcs_pcb->PCB_BUFFER;  // TBD - check this
      rtcs_pcb->PCB_ORIG = rx_pcb_ptr;
   } 
   rtcs_pcb->PCB_FREE = NULL;

   rtcs_pcb->PCBPTR = &rtcs_pcb->PCB;

   rtcs_pcb->PCB.FRAG[0].LENGTH   = 0;
   // grows down from end of buffer 
   rtcs_pcb->PCB.FRAG[0].FRAGMENT = &rtcs_pcb->HEADER_FRAG_BUFFER[RTCSPCB_DATA_MAX];

   rtcs_pcb->PCB.FRAG[1].LENGTH   = rtcs_pcb->HEADER_FRAG_USED;
   rtcs_pcb->PCB.FRAG[1].FRAGMENT = RTCSPCB_DATA(rtcs_pcb);
 
   frag = 0;
   do { 
      frag++;
      rtcs_pcb->PCB.FRAG[frag+1].LENGTH   = rx_pcb_ptr->FRAG[frag].LENGTH;
      rtcs_pcb->PCB.FRAG[frag+1].FRAGMENT = rx_pcb_ptr->FRAG[frag].FRAGMENT;
   } while (rx_pcb_ptr->FRAG[frag].FRAGMENT); 
   
   rtcs_pcb->HEADER_FRAG_USED = 0;
   rtcs_pcb->HEADER_FRAG_FREE = RTCSPCB_DATA_MAX;
   rtcs_pcb->NUM_FRAGS = frag+1;
   RTCSPCB_DATA(rtcs_pcb) = rtcs_pcb->PCB.FRAG[0].FRAGMENT;

   PCBLOG(("\nPCB: Fork: forked %p", rtcs_pcb));
   return RTCS_OK;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_free_internal
*  Returned Value : void
*  Comments       :
*        Frees an allocated PCB.
*
*END*-----------------------------------------------------------------*/

static void RTCSPCB_free_internal
   (
      PCB_PTR   inpcb
         /* [IN] packet to free */
   )
{ 
   RTCSPCB_PTR rtcs_pcb = (RTCSPCB_PTR)inpcb->PRIVATE;

   /* Can't free this PCB until all duplicates are freed */
   if (RTCS_sem_trywait(&rtcs_pcb->DUPCOUNT) == RTCS_OK) {
      PCBLOG(("\nPCB: Free_internal: delaying %p", rtcs_pcb));
      return;
   } 

   /* If this PCB is a duplicate, decrement the original's refcount */
   if (rtcs_pcb->DUPPTR) {
      PCBLOG(("\nPCB: Free_internal: about to free %p", rtcs_pcb->DUPPTR));
      RTCSPCB_free(rtcs_pcb->DUPPTR);
      rtcs_pcb->DUPPTR = NULL;
   } 

   /* If this PCB has been forked, don't forget the link layer's PCB */
   if (rtcs_pcb->PCB_ORIG) {
      PCB_free(rtcs_pcb->PCB_ORIG);
      rtcs_pcb->PCB_ORIG = NULL;
   } 

   /* handle the FREE_FRAG_FIELD */
   if (rtcs_pcb->FREE_FRAG_BITFIELD) {
      uint_32  i;
      for (i = 0; i < RTCSPCB_FRAG_MAX; i++) {
         if (rtcs_pcb->FREE_FRAG_BITFIELD & (1 << i)) {
            _mem_free(rtcs_pcb->PCBPTR->FRAG[i].FRAGMENT);
         } 
      } 
      rtcs_pcb->FREE_FRAG_BITFIELD = 0;
   } 

   if (rtcs_pcb->PCB_FREE) {
      inpcb->FREE    = rtcs_pcb->PCB_FREE;
      inpcb->PRIVATE = rtcs_pcb->PCB_PRIVATE;
      inpcb->FRAG[0] = rtcs_pcb->PCB_BUFFER;
      PCBLOG(("\nPCB: Free_internal: PCB is %p", inpcb));
      PCB_free(inpcb);
   } 

   if (rtcs_pcb->UDP_REQUEST) {
      RTCS_cmd_complete(rtcs_pcb->UDP_REQUEST, RTCS_OK);
      rtcs_pcb->UDP_REQUEST = NULL;
   } 

   RTCS_part_free(rtcs_pcb);

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_insert_header
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Prepend a layer header in a PCB.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSPCB_insert_header
   (
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] packet to change */
      uint_32        size
         /* [IN] size of new header */
   )
{ 
   uchar_ptr data_ptr;

   if (size > rtcs_pcb->HEADER_FRAG_FREE) {
      PCBLOG(("\nPCB: Insert: out of space in %p (%d/%d)", rtcs_pcb, size, rtcs_pcb->FRAGFREE));
      return RTCSERR_PCB_BUFFER;
   } 

   rtcs_pcb->HEADER_FRAG_FREE     -= size;
   rtcs_pcb->HEADER_FRAG_USED     += size;
   RTCSPCB_SIZE(rtcs_pcb) += size;

   data_ptr = RTCSPCB_DATA(rtcs_pcb);
   data_ptr -= size;
   RTCSPCB_DATA(rtcs_pcb) = data_ptr;

   PCBLOG(("\nPCB: Insert: inserted %d bytes in %p", size, rtcs_pcb));
   return RTCS_OK;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_next
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Advance a layer header in a PCB.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSPCB_next
   (
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] packet to change */
      uint_32        size
         /* [IN] size of last header */
   )
{ 
   uchar_ptr data_ptr;

   if (size > rtcs_pcb->HEADER_FRAG_USED) {
      PCBLOG(("\nPCB: Next: out of space in %p (%d/%d)", rtcs_pcb, size, rtcs_pcb->FRAGUSED));
      return RTCSERR_PCB_BUFFER;
   } 

   rtcs_pcb->HEADER_FRAG_FREE     += size;
   rtcs_pcb->HEADER_FRAG_USED     -= size;
   RTCSPCB_SIZE(rtcs_pcb) -= size;

   data_ptr = RTCSPCB_DATA(rtcs_pcb);
   data_ptr += size;
   RTCSPCB_DATA(rtcs_pcb) = data_ptr;

   PCBLOG(("\nPCB: Next: skipped %d bytes in %p", size, rtcs_pcb));
   return RTCS_OK;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_shrink
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Shrinks the first fragment of a PCB.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSPCB_shrink
   (
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] packet to change */
      uint_32        size
         /* [IN] size to remove */
   )
{ 

   if (size > rtcs_pcb->HEADER_FRAG_USED) {
      PCBLOG(("\nPCB: Shrink: out of space in %p (%d/%d)", rtcs_pcb, size, rtcs_pcb->HEADER_FRAG_USED));
      return RTCSERR_PCB_BUFFER;
   } 

   rtcs_pcb->HEADER_FRAG_USED     -= size;
   RTCSPCB_SIZE(rtcs_pcb) -= size;

   PCBLOG(("\nPCB: Shrink: shrunk %d bytes in %p", size, rtcs_pcb));
   return RTCS_OK;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_append_fragment_autofree
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Adds a fragment to a PCB, and get RTCSPCB_free to _mem_free()
*        it when called.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSPCB_append_fragment_autofree
   (
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] packet to change */
      uint_32        size,
         /* [IN] size of new fragment */
      uchar_ptr      frag
   )
{ 
   uint_32 lastfrag = rtcs_pcb->NUM_FRAGS;
   uint_32 error = RTCSPCB_append_fragment(rtcs_pcb, size, frag);

   if (error == RTCS_OK) {
      rtcs_pcb->FREE_FRAG_BITFIELD |= 1 << lastfrag;
   } 
   return error;

} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_append_fragment
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Adds a fragment to a PCB.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSPCB_append_fragment
   (
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] packet to change */
      uint_32        size,
         /* [IN] size of new fragment */
      uchar_ptr      frag
         /* [IN] pointer to new fragment */
   )
{ 

   if (rtcs_pcb->NUM_FRAGS == 0) {
      PCBLOG(("\nPCB: Frag: must fork %p", rtcs_pcb));
      return RTCSERR_PCB_NOFRAG;
   } 

   if (rtcs_pcb->NUM_FRAGS >= RTCSPCB_FRAG_MAX) {
      PCBLOG(("\nPCB: Frag: out of fragments in %p", rtcs_pcb));
      return RTCSERR_PCB_FRAG;
   } 

   rtcs_pcb->PCBPTR->FRAG[rtcs_pcb->NUM_FRAGS].LENGTH   = size;
   rtcs_pcb->PCBPTR->FRAG[rtcs_pcb->NUM_FRAGS].FRAGMENT = frag;
   RTCSPCB_SIZE(rtcs_pcb) += size;
   rtcs_pcb->NUM_FRAGS++;
   rtcs_pcb->PCBPTR->FRAG[rtcs_pcb->NUM_FRAGS].LENGTH   = 0;
   rtcs_pcb->PCBPTR->FRAG[rtcs_pcb->NUM_FRAGS].FRAGMENT = NULL;

   PCBLOG(("\nPCB: Frag: added %d bytes to %p", size, rtcs_pcb));
   return RTCS_OK;

}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCSPCB_memcopy
*  Returned Value : void
*  Comments       :
*        Copies data out from a PCB.
*
*END*-----------------------------------------------------------------*/

void RTCSPCB_memcopy
   (
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] packet to copy */
      pointer        dest,
         /* [IN] destination */
      uint_32        offset,
         /* [IN] offset into PCB */
      uint_32        dest_size
         /* [IN] number of bytes to copy */
   )
{ 
   PCB_FRAGMENT_PTR  frag_ptr = rtcs_pcb->PCBPTR->FRAG;
   uchar_ptr         src_ptr  = RTCSPCB_DATA(rtcs_pcb);
   uchar_ptr         dest_ptr = dest;
   uint_32           src_size = rtcs_pcb->HEADER_FRAG_USED;

   while (src_size < offset) {

      offset -= src_size;
      frag_ptr++;
      src_ptr  = frag_ptr->FRAGMENT;
      src_size = frag_ptr->LENGTH;

   }

   src_ptr  += offset;
   src_size -= offset;

   while (src_size < dest_size) {

      _mem_copy(src_ptr, dest_ptr, src_size);
      dest_ptr  += src_size;
      dest_size -= src_size;
      frag_ptr++;
      src_ptr  = frag_ptr->FRAGMENT;
      src_size = frag_ptr->LENGTH;

   } 

   _mem_copy(src_ptr, dest_ptr, dest_size);

} 


/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/USB_DRIVER/usb_framework.c<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/ /*!
 *
 * @file usb_framework.c
 *
 * @author
 *
 * @version
 *
 * @date
 *
 * @brief The file contains USB stack framework module implementation.
 *
 *****************************************************************************/
/******************************************************************************
* Includes
*****************************************************************************/
/* Contains User Defined Data Types */
#include <string.h>
#include "usb_class.h"      /* USB class Header File */
#include "usb_framework.h"  /* USB Framework Header File */
#include "usb_descriptor.h" /* USB descriptor Header File */
#include <intrinsics.h>

#ifdef OTG_BUILD
  #include "usb_otg_main.h"   /* OTG header file */
#endif
/*****************************************************************************
* Constant and Macro's
*****************************************************************************/
/****************************************************************************
* Global Variables
****************************************************************************/
static USB_SETUP_STRUCT g_setup_pkt;
/*is used to store the value of data which needs to be sent to the USB
host in response to the standard requests.*/
static INT16U g_std_framework_data;
/*used to store the address received in Set Address in the standard request.*/
static INT8U  g_assigned_address;
/* Framework module callback pointer */
static USB_CLASS_CALLBACK g_framework_callback = NULL;
/* Other Requests Callback pointer */
static USB_REQ_FUNC g_other_req_callback = NULL;
#ifdef DELAYED_PROCESSING
static USB_DEV_EVENT_STRUCT g_f_event;
/* initially no pending request */
static BOOLEAN g_control_pending = FALSE;
#endif
BOOLEAN const g_validate_request[MAX_STRD_REQ][3] =
{
  TRUE, TRUE, FALSE, /*USB_Strd_Req_Get_Status*/
  /* configured state: valid for existing interfaces/endpoints
          address state   : valid only for interface or endpoint 0
          default state   : not specified
      */
  TRUE, TRUE, FALSE, /* Clear Feature */
  /* configured state: valid only for device in configured state
          address state   : valid only for device (in address state),
                          interface and endpoint 0
          default state   : not specified
      */
  FALSE, FALSE, FALSE, /*reserved for future use*/
  /* configured state: request not supported
          address state   : request not supported
          default state   : request not supported
      */
#ifdef OTG_BUILD
  TRUE, TRUE, TRUE, /* Set Feature */
  /*  configured state: A B-device that supports OTG features  
          address state   : shall be able to accept the SetFeature command
          default state   : in the Default, Addressed and Configured states
      */
#else
  TRUE, TRUE, FALSE, /* Set Feature */
  /*  configured state: valid only for device in configured state
          address state   : valid only for interface or endpoint 0
          default state   : not specified
      */
#endif

  FALSE, FALSE, FALSE, /*reserved for future use*/
  /*  configured state: request not supported
          address state   : request not supported
          default state   : request not supported
      */
  FALSE, TRUE, TRUE, /*USB_Strd_Req_Set_Address*/
  /*  configured state: not specified
          address state   : changes to default state if specified addr == 0,
                          but uses newly specified address
          default state   : changes to address state if specified addr != 0
      */
  TRUE, TRUE, TRUE, /*USB_Strd_Req_Get_Descriptor*/
  /* configured state: valid request
          address state   : valid request
          default state   : valid request
      */
  FALSE, FALSE, FALSE, /*Set Descriptor*/
  /* configured state: request not supported
          address state   : request not supported
          default state   : request not supported
      */
  TRUE, TRUE, FALSE, /*USB_Strd_Req_Get_Config*/
  /* configured state: bConfiguration Value of current config returned
          address state   : value zero must be returned
          default state   : not specified
      */
  TRUE, TRUE, FALSE, /*USB_Strd_Req_Set_Config*/
  /* configured state: If the specified configuration value is zero,
                          then the device enters the Address state.If the
                          specified configuration value matches the
                          configuration value from a config descriptor,
                          then that config is selected and the device
                          remains in the Configured state. Otherwise, the
                          device responds with a Request Error.
          address state   : If the specified configuration value is zero,
                          then the device remains in the Address state. If
                          the specified configuration value matches the
                          configuration value from a configuration
                          descriptor, then that configuration is selected
                          and the device enters the Configured state.
                          Otherwise,response is Request Error.
          default state   : not specified
      */
  TRUE, FALSE, FALSE, /*USB_Strd_Req_Get_Interface*/
  /* configured state: valid request
          address state   : request error
          default state   : not specified
      */
  TRUE, FALSE, FALSE, /*USB_Strd_Req_Set_Interface*/
  /* configured state: valid request
          address state   : request error
          default state   : not specified
      */
  TRUE, FALSE, FALSE /*USB_Strd_Req_Sync_Frame*/
  /* configured state: valid request
          address state   : request error
          default state   : not specified
      */
};


static void USB_Control_Service(PTR_USB_DEV_EVENT_STRUCT event);
static void USB_Control_Service_Handler(INT8U  controller_ID, INT8U status, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Get_Status(INT8U     controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Feature(INT8U        controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Set_Address(INT8U    controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Assign_Address(INT8U controller_ID);
static INT8U USB_Strd_Req_Get_Config(INT8U     controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Set_Config(INT8U     controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Get_Interface(INT8U  controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Set_Interface(INT8U  controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Sync_Frame(INT8U     controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U USB_Strd_Req_Get_Descriptor(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
#ifdef DELAYED_PROCESSING
static void USB_Control_Service_Callback(PTR_USB_DEV_EVENT_STRUCT event);
#endif

static INT8U ext_req_to_host[129]; //[64+8]; // Буфер для транзакции OUT следующей за транзакцией SETUP


USB_REQ_FUNC const g_standard_request[MAX_STRD_REQ] =
{
  USB_Strd_Req_Get_Status,
  USB_Strd_Req_Feature,
  NULL,
  USB_Strd_Req_Feature,
  NULL,
  USB_Strd_Req_Set_Address,
  USB_Strd_Req_Get_Descriptor,
  NULL,
  USB_Strd_Req_Get_Config,
  USB_Strd_Req_Set_Config,
  USB_Strd_Req_Get_Interface,
  USB_Strd_Req_Set_Interface,
  USB_Strd_Req_Sync_Frame
};

/**************************************************************************/ /*!
 *
 * @name  USB_Framework_Init
 *
 * @brief The funtion initializes the Class Module
 *
 * @param controller_ID     : Controller ID
 * @param class_callback    : Class callback pointer
 * @param other_req_callback: Other Request Callback
 *
 * @return status
 *         USB_OK           : When Successfull
 *         Others           : Errors
 *
 ******************************************************************************
 * This fuction registers the service on the control endpoint
 *****************************************************************************/
INT8U USB_Framework_Init
(
 INT8U              controller_ID,       /* [IN] Controller ID */
 USB_CLASS_CALLBACK  class_callback,      /* Class Callback */
 USB_REQ_FUNC        other_req_callback   /* Other Request Callback */
 )
{

  INT8U error = USB_OK;
  /* save input parameters */
  g_framework_callback = class_callback;
  g_other_req_callback = other_req_callback;
  /* Register CONTROL service */

#ifdef DELAYED_PROCESSING
  error = USB_Device_Register_Service(controller_ID, USB_SERVICE_EP0, USB_Control_Service_Callback);
#else
  error = USB_Device_Register_Service(controller_ID, USB_SERVICE_EP0, USB_Control_Service);
#endif
  return error;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Framework_DeInit
 *
 * @brief The funtion De-initializes the Class Module
 *
 * @param controller_ID     : Controller ID
 *
 * @return status
 *         USB_OK           : When Successfull
 *         Others           : Errors
 *
 ******************************************************************************
 * This fuction unregisters control service
 *****************************************************************************/
INT8U USB_Framework_DeInit
(
 INT8U controller_ID       /* [IN] Controller ID */
 )
{

  INT8U error;
  /* Free framwork_callback */
  g_framework_callback = NULL;

  /* Free other_req_callback */
  g_other_req_callback = NULL;

  /* Unregister CONTROL service */
  error = USB_Device_Unregister_Service(controller_ID, USB_SERVICE_EP0);


  return error;
}
#ifdef DELAYED_PROCESSING
/**************************************************************************/ /*!
 *
 * @name  USB_Framework_Periodic_Task
 *
 * @brief The funtion is called to respond to any control request
 *
 * @param None
 *
 * @return None
 *
 ******************************************************************************
 * This function checks for any pending requests and handles them if any
 *****************************************************************************/
void USB_Framework_Periodic_Task(void)
{

  /* if control request pending to be completed */
  if ( g_control_pending == TRUE )
  {
    /* handle pending control request */
    USB_Control_Service(&g_f_event);
    g_control_pending = FALSE;
  }
}
#endif
/**************************************************************************/ /*!
 *
 * @name  USB_Framework_Reset
 *
 * @brief The funtion resets the framework
 *
 * @param controller_ID     : Controller ID
 *
 * @return status
 *         USB_OK           : When Successfull
 *
 ******************************************************************************
 * This function is used to reset the framework module
 *****************************************************************************/
INT8U USB_Framework_Reset
(
 INT8U controller_ID /* [IN] Controller ID */
 )
{

  UNUSED(controller_ID)
  return USB_OK;
}
#ifdef DELAYED_PROCESSING
/**************************************************************************/ /*!
 *
 * @name  USB_Control_Service_Callback
 *
 * @brief The funtion can be used as a callback function to the service.
 *
 * @param event : Pointer to USB Event Structure
 *
 * @return None
 *
 ******************************************************************************
 * This function saves the event parameters and queues a pending request
 *****************************************************************************/
void USB_Control_Service_Callback
(
 PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */
 )
{

  /* save the event parameters */
  g_f_event.buffer_ptr = event->buffer_ptr;
  g_f_event.controller_ID = event->controller_ID;
  g_f_event.ep_num = event->ep_num;
  g_f_event.setup  = event->setup;
  g_f_event.len = event->len;
  g_f_event.errors = event->errors;
  /* set the pending request flag */
  g_control_pending = TRUE;
}
#endif
/**************************************************************************/ /*!
 *
 * @name  USB_Control_Service
 *
 * @brief Called upon a completed endpoint 0 transfer
 *
 * @param event : Pointer to USB Event Structure
 *
 * @return None
 *
 ******************************************************************************
 * This function handles the data sent or received on the control endpoint
 *****************************************************************************/
static void USB_Control_Service(PTR_USB_DEV_EVENT_STRUCT event)
{

  INT16U    device_state = 0;
  INT8U     status = USBERR_INVALID_REQ_TYPE;
  INT8U_ptr data = NULL;
  INT16U size;
  /* get the device state  */
  (void)USB_Device_Get_Status(event->controller_ID, USB_STATUS_DEVICE_STATE, &device_state);
  if ( event->setup == TRUE )
  {
    /* get the setup packet */
    (void)memcpy(&g_setup_pkt, event->buffer_ptr, USB_SETUP_PKT_SIZE);

    /* take care of endianess  of the 16 bt fields correctly */
    g_setup_pkt.index = BYTE_SWAP16(g_setup_pkt.index);
    g_setup_pkt.value = BYTE_SWAP16(g_setup_pkt.value);
    g_setup_pkt.length = BYTE_SWAP16(g_setup_pkt.length);

    /* if the request is standard request */
    if ( (g_setup_pkt.request_type & USB_REQUEST_CLASS_MASK) == USB_REQUEST_CLASS_STRD )
    {
      /* if callback is not NULL */
      if ( g_standard_request[g_setup_pkt.request] != NULL )
      {
        /* if the request is valid in this device state */
        if ( (device_state < USB_STATE_POWERED) && (g_validate_request[g_setup_pkt.request][device_state] == TRUE) )
        {
          /* Standard Request function pointers */
          status = g_standard_request[g_setup_pkt.request](event->controller_ID, &g_setup_pkt, &data, (INT16U *)&size);
        }
      }
    }
    else /* for Class/Vendor requests */
    {
      // Отладочная вставка
      if (( g_setup_pkt.request == 0x01 ) && (g_setup_pkt.request_type == 0x21))
      {
        __no_operation();
      }

      /*get the length from the setup_request*/
      size = (INT16U)g_setup_pkt.length;
      if ( (size != 0) && ((g_setup_pkt.request_type & USB_DATA_DIREC_MASK) == USB_DATA_TO_DEVICE) )
      {
        (void)memcpy(ext_req_to_host, &g_setup_pkt, USB_SETUP_PKT_SIZE);
        /* expecting host to send data (OUT TRANSACTION)*/
        (void)USB_Device_Recv_Data(event->controller_ID, CONTROL_ENDPOINT, ext_req_to_host + USB_SETUP_PKT_SIZE, (INT16U)(size));
        return;
      }
      else if ( g_other_req_callback != NULL ) /*call class/vendor request*/
      {
        // Здесь обрабатываем только запросы SETUP идущие от хоста без пакета данных OUT
        status = g_other_req_callback(event->controller_ID, &g_setup_pkt, &data, (INT16U *)&size);
      }
    }
    USB_Control_Service_Handler(event->controller_ID, status, &g_setup_pkt, &data, (INT16U *)&size);
  }
  /* if its not a setup request */
  else if ( device_state == USB_STATE_PENDING_ADDRESS )
  {
    /* Device state is PENDING_ADDRESS */
    /* Assign the new adddress to the Device */
    (void)USB_Strd_Req_Assign_Address(event->controller_ID);
    return;
  }
  else if ( ((g_setup_pkt.request_type & USB_DATA_DIREC_MASK) == USB_DATA_TO_DEVICE) && (event->direction == USB_RECV) )
  {
    // Отладочная вставка
    //if ( g_setup_pkt.request != 0x05 )
    //{
    //  __no_operation();
    //}
    /* execution enters Control Service because of OUT transaction on CONTROL_ENDPOINT*/
    if ( g_other_req_callback != NULL )
    {   /* class or vendor request */


      size = (INT16U)(event->len + USB_SETUP_PKT_SIZE);
      status = g_other_req_callback(event->controller_ID, (USB_SETUP_STRUCT *)(ext_req_to_host), &data, (INT16U *)&size);
    }
    USB_Control_Service_Handler(event->controller_ID, status, &g_setup_pkt, &data, (INT16U *)&size);
  }
  return;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Control_Service_Handler
 *
 * @brief The function is used to send a response to the Host based.
 *
 * @param controller_ID : Controller ID
 * @param status        : Status of request
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return None
 *
 ******************************************************************************
 * This function sends a response to the data received on the control endpoint.
 * the request is decoded in the control service
 *****************************************************************************/
static void USB_Control_Service_Handler
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 INT8U status,                      /* [IN] Device Status */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  if ( status == USBERR_INVALID_REQ_TYPE )
  {
    /* incase of error Stall endpoint */
    (void)USB_Device_Set_Status(controller_ID, (INT8U)(USB_STATUS_ENDPOINT | CONTROL_ENDPOINT | (USB_SEND << USB_COMPONENT_DIRECTION_SHIFT)), USB_STATUS_STALLED);
  }
  else /* Need to send Data to the USB Host */
  {
    /* send the data prepared by the handlers.*/
    if ( *size > setup_packet->length )
    {
      *size = (INT16U)setup_packet->length;
    }
    /* send the data to the host */
    (void)USB_Class_Send_Data(controller_ID, CONTROL_ENDPOINT, *data, *size);
    if ( (setup_packet->request_type & USB_DATA_DIREC_MASK) == USB_DATA_TO_HOST )
    {   /* Request was to Get Data from device */
      /* setup rcv to get status from host */
      (void)USB_Device_Recv_Data(controller_ID, CONTROL_ENDPOINT, NULL, 0);
    }
  }
  return;
}
/*************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Get_Status
 *
 * @brief  This function is called in response to Get Status request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : When Successfull
 *               Others : When Error
 *
 ******************************************************************************
 * this is a ch9 request and is called by the host to know the status of the
 * device, the interface and the endpoint
 *****************************************************************************/
static INT8U USB_Strd_Req_Get_Status
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  INT8U interface, endpoint;
  INT8U status;
  if ( (setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_DEVICE )
  {
#ifdef OTG_BUILD

    if ( setup_packet->index == USB_WINDEX_OTG_STATUS_SEL )
    {
      /* request for Device */
      status = USB_Device_Get_Status(controller_ID, USB_STATUS_OTG, &g_std_framework_data);
      g_std_framework_data &= GET_STATUS_OTG_MASK;
      g_std_framework_data = BYTE_SWAP16(g_std_framework_data);
      *size = OTG_STATUS_SIZE;
    }
    else
#endif
    {
      /* request for Device */
      status = USB_Device_Get_Status(controller_ID, USB_STATUS_DEVICE, &g_std_framework_data);
      g_std_framework_data &= GET_STATUS_DEVICE_MASK;
      g_std_framework_data = BYTE_SWAP16(g_std_framework_data);
      *size = DEVICE_STATUS_SIZE;
    }
  }
  else if ( (setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_INTERFACE )
  {
    /* request for Interface */
    interface  = (INT8U)setup_packet->index;
    status =  USB_Desc_Get_Interface(controller_ID, interface, (INT8U_ptr) & g_std_framework_data);
    *size = INTERFACE_STATUS_SIZE;
  }
  else if ( (setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_ENDPOINT )
  {
    /* request for Endpoint */
    endpoint  = (INT8U)(((INT8U)setup_packet->index) | USB_STATUS_ENDPOINT);
    status =  USB_Device_Get_Status(controller_ID, endpoint, &g_std_framework_data);
    g_std_framework_data = BYTE_SWAP16(g_std_framework_data);
    *size = ENDP_STATUS_SIZE;
  }
  *data = (INT8U_ptr) & g_std_framework_data;
  return status;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Feature
 *
 * @brief  This function is called in response to Clear or Set Feature request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : When Successfull
 *               Others : When Error
 *
 ******************************************************************************
 * This is a ch9 request, used to set/clear a feature on the device
 * (device_remote_wakeup and test_mode) or on the endpoint(ep halt)
 *****************************************************************************/
static INT8U USB_Strd_Req_Feature
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  INT16U device_status;
  INT8U  set_request;
  INT8U  status = USBERR_INVALID_REQ_TYPE;
  INT8U  epinfo;
  INT8U  event;
  UNUSED(data)
    * size = 0;
  /* find whether its a clear feature request or a set feature request */
  set_request = (INT8U)((setup_packet->request & USB_SET_REQUEST_MASK) >> 1);
  if ( (setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_DEVICE )
  {
    if ( set_request == TRUE )
    {
      INT16U device_set_feature_bitfield = DEVICE_SET_FEATURE_MASK;
#ifdef OTG_BUILD
      OTG_DESCRIPTOR_PTR_T otg_desc_ptr;
      INT16U size;
      status = USB_Desc_Get_Descriptor(controller_ID, USB_OTG_DESCRIPTOR, (INT8U)UNINITIALISED_VAL, (INT16U)UNINITIALISED_VAL, (INT8U_ptr *)&otg_desc_ptr, &size);
      if ( status == USB_OK )
      {
        if ( otg_desc_ptr->bmAttributes & USB_OTG_HNP_SUPPORT )
        {
          device_set_feature_bitfield |= (1 << DEVICE_SET_FEATURE_B_HNP_ENABLE) | (1 << DEVICE_SET_FEATURE_A_HNP_SUPPORT);
        }
      }
#endif

      if ( ((INT16U)(1 << (INT8U)setup_packet->value)) & device_set_feature_bitfield )
      {
        status = USB_OK;
        if ( setup_packet->value == DEVICE_FEATURE_REMOTE_WAKEUP )
        {
          status = USB_Device_Get_Status(controller_ID, USB_STATUS_DEVICE, &device_status);
          /* add the request to be cleared from device_status */
          device_status |= (INT16U)(1 << (INT8U)setup_packet->value);

          /* set the status on the device */
          status = USB_Device_Set_Status(controller_ID, USB_STATUS_DEVICE, device_status);
        }

#ifdef OTG_BUILD
        else if ( setup_packet->value == DEVICE_SET_FEATURE_B_HNP_ENABLE )
        {
          _usb_otg_hnp_enable(controller_ID, set_request);
        }
#endif
      }
      else
      {
        status = USBERR_INVALID_REQ_TYPE;
      }
    }
    else //(set_request == FALSE) it is a clear feature request
    {
      if ( ((INT16U)(1 << (INT8U)setup_packet->value)) & DEVICE_CLEAR_FEATURE_MASK )
      {
        status = USB_OK;
        if ( setup_packet->value == DEVICE_FEATURE_REMOTE_WAKEUP )
        {
          status = USB_Device_Get_Status(controller_ID, USB_STATUS_DEVICE, &device_status);
          /* remove the request to be cleared from device_status */
          device_status &= (INT16U)~(1 << (INT8U)setup_packet->value);
          status = USB_Device_Set_Status(controller_ID, USB_STATUS_DEVICE, device_status);
        }
      }
      else
      {
        status = USBERR_INVALID_REQ_TYPE;
      }
    }
  }
  else if ( (setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_ENDPOINT )
  {
    /* request for Endpoint */
    epinfo = (INT8U)(setup_packet->index & 0x00FF);
    status = USB_Device_Set_Status(controller_ID, (INT8U)(epinfo | USB_STATUS_ENDPOINT), set_request);
    if ( (set_request == 0) && (epinfo == 0x03) )
    {
      __no_operation();
    }
    event = (INT8U)(set_request ? USB_APP_EP_STALLED : USB_APP_EP_UNSTALLED);
    /* inform the upper layers of stall/unstall */
    g_framework_callback(controller_ID, event, (void *)&epinfo);
  }
  return status;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Set_Address
 *
 * @brief  This function is called in response to Set Address request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : When Successfull
 *               Others : When Error
 *
 ******************************************************************************
 * This is a ch9 request, saves the new address in a global variable. this
 * address is assigned to the device after this transaction completes
 *****************************************************************************/
static INT8U USB_Strd_Req_Set_Address
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  UNUSED(data)
    * size = 0;
  /* update device stae */
  (void)USB_Device_Set_Status(controller_ID, USB_STATUS_DEVICE_STATE, USB_STATE_PENDING_ADDRESS);
  /*store the address from setup_packet into assigned_address*/
  g_assigned_address = (INT8U)setup_packet->value;
  return USB_OK;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Assign_Address
 *
 * @brief  This function assigns the address to the Device
 *
 * @param controller_ID : Controller ID
 *
 * @return status
 *                       USB_OK: Always
 *
 ******************************************************************************
 * This function assigns the new address and is called (from the control
 * service) after the set address transaction completes
 *****************************************************************************/
static INT8U USB_Strd_Req_Assign_Address
(
 INT8U    controller_ID         /* [IN] Controller ID */
 )
{

  /* Set Device Address */
  (void)USB_Device_Set_Address(controller_ID, g_assigned_address);
  /* Set Device state */
  (void)USB_Device_Set_Status(controller_ID, USB_STATUS_DEVICE_STATE, USB_STATE_ADDRESS);
  /* Set Device state */
  (void)USB_Device_Set_Status(controller_ID, USB_STATUS_ADDRESS, g_assigned_address);
  return USB_OK;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Get_Config
 *
 * @brief  This function is called in response to Get Config request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : Always
 *
 ******************************************************************************
 * This is a ch9 request and is used to know the currently used configuration
 *****************************************************************************/
static INT8U USB_Strd_Req_Get_Config
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  UNUSED(setup_packet)
    * size = CONFIG_SIZE;
  (void)USB_Device_Get_Status(controller_ID, USB_STATUS_CURRENT_CONFIG, &g_std_framework_data);
  g_std_framework_data = BYTE_SWAP16(g_std_framework_data);
  *data = (INT8U_ptr)(&g_std_framework_data);
  return USB_OK;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Set_Config
 *
 * @brief  This function is called in response to Set Config request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : When Successfull
 *               Others : When Error
 *
 ******************************************************************************
 * This is a ch9 request and is used by the host to set the new configuration
 *****************************************************************************/
static INT8U USB_Strd_Req_Set_Config
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size                       /* [OUT] Size to be returned */
 )
{

  INT8U status = USBERR_INVALID_REQ_TYPE;
  INT16U config_val;
  UNUSED(data)
    * size = 0;
  status = USB_STATUS_ERROR;
  config_val = setup_packet->value;
  if ( USB_Desc_Valid_Configation(controller_ID, config_val) )
  /*if valid configuration (fn returns boolean value)*/
  {
    INT16U device_state = USB_STATE_CONFIG;

    /* if config_val is 0 */
    if ( !config_val )
    {
      device_state = USB_STATE_ADDRESS;
    }
    status = USB_Device_Set_Status(controller_ID, USB_STATUS_DEVICE_STATE, device_state);
    status = USB_Device_Set_Status(controller_ID, USB_STATUS_CURRENT_CONFIG, config_val);
    /*
    Callback to the app. to let the application know about the new
    Configuration
    */
    g_framework_callback(controller_ID, USB_APP_CONFIG_CHANGED, (void *)&config_val);
    g_framework_callback(controller_ID, USB_APP_ENUM_COMPLETE, NULL);
  }
  return status;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Get_Interface
 *
 * @brief  This function is called in response to Get Interface request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : When Successfull
 *               Others : When Error
 *
 ******************************************************************************
 * This is a ch9 request and is used to know the current interface
 *****************************************************************************/
static INT8U USB_Strd_Req_Get_Interface
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  INT8U status;
  *size = INTERFACE_STATUS_SIZE;
  status = USB_Desc_Get_Interface(controller_ID, (INT8U)setup_packet->index, (INT8U_ptr) & g_std_framework_data);
  *data = (INT8U_ptr) & g_std_framework_data;
  return status;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Set_Interface
 *
 * @brief  This function is called in response to Set Interface request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : Always
 *
 ******************************************************************************
 * This is a ch9 request and is used by the  host to set the interface
 *****************************************************************************/
static INT8U USB_Strd_Req_Set_Interface
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  //uint_8 status;
  UNUSED(data)
    * size = 0;
  /* Request type not for interface */
  if ( (setup_packet->request_type & 0x03) != 0x01 )
  {
    return USB_STATUS_ERROR;
  }
  /* Get Interface and alternate interface from setup_packet */
  (void)USB_Desc_Set_Interface(controller_ID, (INT8U)setup_packet->index, (INT8U)setup_packet->value);
  return USB_OK;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Strd_Req_Sync_Frame
 *
 * @brief  This function is called in response to Sync Frame request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : When Successfull
 *               Others : When Error
 *
 ******************************************************************************
 * This req is used to set and then report an ep's synchronization frame
 *****************************************************************************/
static INT8U USB_Strd_Req_Sync_Frame
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  INT8U status;
  UNUSED(setup_packet)
    * size = FRAME_SIZE;
  /* Get the frame number */
  status = USB_Device_Get_Status(controller_ID, USB_STATUS_SOF_COUNT, &g_std_framework_data);
  *data = (INT8U_ptr) & g_std_framework_data;
  return status;
}
/**************************************************************************/ /*!
 *
 * @name  USB_Std_Req_Get_Descriptor
 *
 * @brief  This function is called in response to Get Descriptor request
 *
 * @param controller_ID : Controller ID
 * @param setup_packet  : Setup packet received
 * @param data          : Data to be send back
 * @param size          : Size to be returned
 *
 * @return status:
 *               USB_OK : When Successfull
 *               Others : When Error
 *
 ******************************************************************************
 * This is a ch9 request and is used to send the descriptor requested by the
 * host
 *****************************************************************************/
static INT8U USB_Strd_Req_Get_Descriptor
(
 INT8U    controller_ID,            /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned */
 )
{

  INT8U type = USB_uint_16_high(setup_packet->value);
  INT16U index = (INT8U)UNINITIALISED_VAL;
  INT8U str_num = (INT8U)UNINITIALISED_VAL;
  INT8U status;
  if ( type == STRING_DESCRIPTOR_TYPE )
  {
    /* for string descriptor set the language and string number */
    index = setup_packet->index;
    /*g_setup_pkt.lValue*/
    str_num = USB_uint_16_low(setup_packet->value);
  }
  /* Call descriptor class to get descriptor */
  status = USB_Desc_Get_Descriptor(controller_ID, type, str_num, index, data, size);
  return status;
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Cos.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Cos.h
*
* @author   B04459
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_Cos function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_COS_H
#define _GFLIB_COS_H

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif
/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*! Function alias for the #GFLIB_CosANSIC function.*/
#define GFLIB_Cos(f32In) GFLIB_CosANSIC(f32In, &gflibCosCoef)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_COSTLR_T "\GFLIB_Cos.h"

@brief      Structure containing one array of five 32-bit elements for storing
            coefficients of a Taylor polynomial.

@details    By calling the function alias #GFLIB_Cos, default values of the coefficients
            are used. Polynomial coefficients can be modified by the user
            and in such a case the full function call shall be used, i.e. #GFLIB_CosANSIC.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32  f32A[5];  /*!< Array of five 32-bit elements for storing coefficients
                            of the Taylor polynomial. */
}GFLIB_COSTLR_T;

/******************************************************************************
* Exported Variables
******************************************************************************/
extern const GFLIB_COSTLR_T gflibCosCoef;

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*!
* @ingroup GFLIB_GROUP
*/
extern Frac32 GFLIB_CosANSIC(Frac32 f32In, const GFLIB_COSTLR_T * const pParam);

/******************************************************************************
* Inline functions
******************************************************************************/

#endif /* _GFLIB_COS_H */



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/rtcsinit.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcsinit.c$
* $Version : 3.8.7.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the default protocol table for RTCS.
*
*END************************************************************************/

#include <rtcs.h>


uint_32 (_CODE_PTR_ const RTCS_protocol_table[])(void) = {
#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   RTCSPROT_IGMP,
#endif 
   
#if RTCSCFG_ENABLE_UDP
   RTCSPROT_UDP,
#endif 
   
#if RTCSCFG_ENABLE_TCP
   RTCSPROT_TCP,
#endif 

   NULL
};


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/getaddrinfo.c<|end_filename|>
/**HEADER*******************************************************************************
* 
* Copyright (c) 2011 , Freescale Semiconductor;
* All Rights Reserved                      
*
**************************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************************
*
* $FileName: getaddrinfo.c$
* $Version : 3.8.3.0$
* $Date    : Oct-2-2012$
*
* Comments:
*
*   getaddrinfo() is used to get a list of IP addresses and port
*   numbers for host hostname and service servname. 
*
*END************************************************************************************/

/*
 * Copyright (C) 2004-2007, 2009  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 1999-2001  Internet Software Consortium.
 *
 * This code is derived from software contributed to ISC by
 * Berkeley Software Design, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND BERKELEY SOFTWARE DESIGN, INC.
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE
 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <string.h>
#include <ctype.h>
#include <rtcs.h>
#include <posix.h> // it is for errno, if we want to know error number
#include <stdlib.h>//stdtol() 
#include <addrinfo.h>


#define SA(addr)	((struct sockaddr *)(addr))
#define SIN(addr)	((struct sockaddr_in *)(addr))
#define SIN6(addr)	((struct sockaddr_in6 *)(addr))
#define SLOCAL(addr)	((struct sockaddr_un *)(addr))

/*! \struct addrinfo
 */
static struct addrinfo
	*ai_reverse(struct addrinfo *oai),
	*ai_clone(struct addrinfo *oai, int family),
	*ai_alloc(int family, int addrlen);

static char *RTCS_strsep(char **stringp, const char *delim);
static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port);
static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port);
static void set_order(int, int (**)(const char *, int, struct addrinfo **, int, int));



#define FOUND_IPV4	0x1
#define FOUND_IPV6	0x2
#define FOUND_MAX	2

#define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : getaddrinfo
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Get a list of IP addresses and port numbers for host hostname and service servname.
*
*END*-----------------------------------------------------------------*/
int_32 getaddrinfo
(
	const char 				*hostname, 	/* host name or IP or NULL							*/
	const char 				*servname,	/* service name or port number						*/
	const struct addrinfo 	*hints,		/* set flags										*/
	struct addrinfo 		**res		/* [OUT]list of address structures					*/
)

{
//	struct servent *sp;
	const char 		*proto = NULL;
	int 			family; 
	int				socktype; 
	int				flags; 
	int				protocol;
	
	struct addrinfo *ai;
	struct addrinfo *ai_list;
	uint_16 port; 
	uint_16 err; 
	uint_16 i;
	
	
	int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,int, int);

	/*hostname and send name can not be NULL in same time*/
	if (hostname == NULL && servname == NULL)
	{
		return (EAI_NONAME);
	}

	proto = NULL;
	if (hints != NULL) 
	{
		if ((hints->ai_flags & ~(ISC_AI_MASK)) != 0)
		{
			return (EAI_BADFLAGS);
		}
		if (hints->ai_addrlen || hints->ai_canonname || hints->ai_addr || hints->ai_next) 
		{
			errno = EINVAL;
			return (EAI_SYSTEM);
	    }

		family = hints->ai_family;
		socktype = hints->ai_socktype;
		protocol = hints->ai_protocol;
		flags = hints->ai_flags;
		
		/* looking for correct protocol depended on family and socket type */
		switch (family) {
			case AF_UNSPEC:
			
			/* switch operator is not implemented here */
				if(hints->ai_socktype == SOCK_STREAM)
				{
					proto = "tcp";
				
				}else if(hints->ai_socktype == SOCK_DGRAM)	{
				
					proto = "udp";
				
				}else{
				
					return (EAI_SOCKTYPE);				
				
				}

			break;
			case AF_INET:
			case AF_INET6:
				if(hints->ai_socktype == 0)
				{
					break;
			
				}else if(hints->ai_socktype == SOCK_STREAM)	{
				
					proto = "tcp";
				
				}else if(hints->ai_socktype == SOCK_DGRAM)	{
					
					proto = "udp";
			
				}else{
				
					return (EAI_SOCKTYPE);
			
				}

			break;

		default:
			return (EAI_FAMILY);

		}/* end of  switch (family) */
	} else {
	
		protocol = 0;
		family = 0;
		socktype = 0;
		flags = 0;
	
	}/* end of (hints != NULL) */

	if(proto !=NULL)
	{
		protocol = (strcmp(proto,"tcp")) ? 2 : 1;

	}

	/*
	 * Ok, only AF_INET and AF_INET6 left.
	 */
	 
	/*************************************/

	/*
	 * First, look up the service port if it was
	 * requested.  If the socket type wasn't specified, then
	 * try and figure it out.
	 */
	if (servname != NULL) {
		char *e;

		port = strtol(servname, &e, 10);
		if (*e == '\0') {					//*e - end pointer
			if (socktype == 0)				//I am not shure that it is necessary here
			{								//
				return (EAI_SOCKTYPE);		//
			}								//

			htons(&port,(uint_16) port);	//MQX version of htons

		} else {
		/* b23362 - we use only port number.We do not use a service name*/
			return (EAI_SERVICE);			
		}/*end of (*e == '\0')*/
	} else {

		port = 0;

	} /* end (servname != NULL)	*/

	/*
	 * Next, deal with just a service name, and no hostname.
	 * (we verified that one of them was non-null up above).
	 */
	
	ai_list = NULL;
				 
	if (hostname == NULL && (flags & AI_PASSIVE) != 0) 
	{
	    if (family == AF_INET || family == 0) 
		{
		
			/* Allocate an addrinfo structure, and a sockaddr structure */		
			ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in));

			if (ai == NULL)
			{
				freeaddrinfo(ai_list);
				return (EAI_MEMORY);
			}
			ai->ai_socktype = socktype;
			ai->ai_protocol = protocol;
			SIN(ai->ai_addr)->sin_port = port;
			ai->ai_next = ai_list;
			ai_list = ai;
		}
		if (family == AF_INET6 || family == 0) 
		{
			ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
			if (ai == NULL) 
			{
				freeaddrinfo(ai_list);
				return (EAI_MEMORY);
			}
			ai->ai_socktype = socktype;
			ai->ai_protocol = protocol;
			SIN6(ai->ai_addr)->sin6_port = port;
			ai->ai_next = ai_list;
			ai_list = ai;
		}

		*res = ai;
		return (0);
	}/* end of (hostname == NULL && (flags & AI_PASSIVE) != 0) */


	/*
	 * If the host is not NULL and the family isn't specified or AI_NUMERICHOST 
	 * specified, check first to see if it is a numeric address.
	 * Though the gethostbyname2() routine
	 * will recognize numeric addresses, it will only recognize
	 * the format that it is being called for.  Thus, a numeric
	 * AF_INET address will be treated by the AF_INET6 call as
	 * a domain name, and vice versa.  Checking for both numerics
	 * here avoids that.
	 */
	if (hostname != NULL && (family == 0 || (flags & AI_NUMERICHOST) != 0)) 
	{
		char abuf[sizeof(struct in6_addr)];
		char nbuf[NI_MAXHOST];
		int addrsize, addroff;
		char *p, *ep;
		char ntmp[NI_MAXHOST];
		uint_32 scopeid;

		/*
		 * Scope identifier portion.
		 * scope id must be a decimal number
		 */
		ntmp[0] = '\0';
		if (strchr(hostname, '%') != NULL) 
		{
			strncpy(ntmp, hostname, sizeof(ntmp) - 1);
			ntmp[sizeof(ntmp) - 1] = '\0';
            /*Returns a pointer to the first occurrence of character '%'.*/			
			p = strchr(ntmp, '%');
			ep = NULL;

			/*
			 * Vendors may want to support non-numeric
			 * scopeid around here.
			 */

			if (p != NULL)
			{
				scopeid = (uint_32)strtoul(p + 1, &ep, 10);
			}				
			if (p != NULL && ep != NULL && ep[0] == '\0')
			{
				*p = '\0';
			}else {
				ntmp[0] = '\0';
				scopeid = 0;
			}
		} else{
			scopeid = 0;
		} /* end of  (strchr(hostname, '%') != NULL) */	


		  /*
	 	   * Converts a human readable IP address into an address 
	 	   * family appropriate 32bit or 128bit binary structure.
	 	   */
	    if (inet_pton(AF_INET, hostname, (struct in_addr *)abuf,sizeof( *((struct in_addr *)abuf)))== RTCS_OK)
	    {
			if (family == AF_INET6) 
			{
				/*
			 	 * Convert to a V4 mapped address.
			 	 */
				struct in6_addr *a6 = (struct in6_addr *)abuf;
				memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4);
				memset(&a6->s6_addr[10], 0xff, 2);
				memset(&a6->s6_addr[0], 0, 10);
				goto inet6_addr;
			}
			addrsize = sizeof(struct in_addr);
			addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;
			family = AF_INET;
			goto common;
		} else if (ntmp[0] != '\0' && inet_pton(AF_INET6, ntmp, abuf,sizeof(struct in6_addr)) == RTCS_OK)
		{
			if (family && family != AF_INET6)
			{
				return (EAI_NONAME);
			}
			addrsize = sizeof(struct in6_addr);
			addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
			family = AF_INET6;
			goto common;
		} else if (inet_pton(AF_INET6, hostname, abuf,sizeof(struct in6_addr)) == RTCS_OK) 
		{
			if (family != 0 && family != AF_INET6)
			{
				return (EAI_NONAME);
			}
inet6_addr:
			addrsize = sizeof(struct in6_addr);
			addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
			family = AF_INET6;

common:
			ai = ai_clone(ai_list, family);
			if (ai == NULL)
			{
				return (EAI_MEMORY);
			}
			ai_list = ai;
			ai->ai_socktype = socktype;
			//ai->ai_protocol = protocol;
			SIN(ai->ai_addr)->sin_port = port;
			memcpy((char *)ai->ai_addr + addroff, abuf, addrsize);

			if (flags & AI_CANONNAME) 
			{

				if (ai->ai_family == AF_INET6)
				{
					SIN6(ai->ai_addr)->sin6_scope_id = scopeid;
				}	

				if (getnameinfo(	ai->ai_addr,
			    					ai->ai_addrlen, 
			    					nbuf, 
			    					sizeof(nbuf),
					      			NULL, 
					      			0,
					      			NI_NUMERICHOST
					       		) == 0) 
				{
					ai->ai_canonname = strdup(nbuf);
					if (ai->ai_canonname == NULL) 
					{
						freeaddrinfo(ai_list);
						return (EAI_MEMORY);
					}
				} else 	
				{
					/* XXX raise error? */
					ai->ai_canonname = NULL;
				}
			}/*end of (flags & AI_CANONNAME)*/
			goto done;
		} else if ((flags & AI_NUMERICHOST) != 0) 
		{
			return (EAI_NONAME);
		}
	}/* end of (inet_pton(AF_INET, hostname, (struct in_addr *)abuf)== 1) */

	set_order(family, net_order);
	for (i = 0; i < FOUND_MAX; i++) {
		if (net_order[i] == NULL)
			break;
		err = (net_order[i])(hostname, flags, &ai_list,
				     socktype, port);
		if (err != 0)
			return (err);
	}

	if (ai_list == NULL)
		return (EAI_NODATA);

done:
	ai_list->ai_protocol = protocol;
	ai_list->ai_flags = flags;

	ai_list = ai_reverse(ai_list);

	*res = ai_list;
	return (0);
}

static char *RTCS_strsep	(
								char **stringp, 
								const char *delim
							) 
{
	char *string = *stringp;
	char *s;
	const char *d;
	char sc, dc;

	if (string == NULL)
		return (NULL);

	for (s = string; *s != '\0'; s++) {
		sc = *s;
		for (d = delim; (dc = *d) != '\0'; d++)
			if (sc == dc) {
				*s++ = '\0';
				*stringp = s;
				return (string);
			}
	}
	*stringp = NULL;
	return (string);
}

static void set_order	(
							int family, 
							int (**net_order)(const char *, int, struct addrinfo **,int, int)
						)
{
	char *order, *tok;
	int found;

	if (family) 
	{
		switch (family) 
		{
			case AF_INET:
				*net_order++ = add_ipv4;
				break;
			case AF_INET6:
				*net_order++ = add_ipv6;
			break;
		}
	} else {
		order = NET_ORDER;//"inet";// : inet6";//getenv("NET_ORDER");
		found = 0;
		while (order != NULL) 
		{
			/*
			 * We ignore any unknown names.
			 */
			tok = RTCS_strsep(&order, ":");
			if (strcasecmp(tok, "inet6") == 0) 
			{
				if ((found & FOUND_IPV6) == 0)
					{
						*net_order++ = add_ipv6;
					}
						
				found |= FOUND_IPV6;
			} else if (strcasecmp(tok, "inet") == 0 || strcasecmp(tok, "inet4") == 0) 
			{
				if ((found & FOUND_IPV4) == 0)
				{
					*net_order++ = add_ipv4;
				}
				found |= FOUND_IPV4;
			}
		}

		/*
		 * Add in anything that we didn't find.
		 */
		if ((found & FOUND_IPV4) == 0)
			*net_order++ = add_ipv4;
		if ((found & FOUND_IPV6) == 0)
			*net_order++ = add_ipv6;
	}
	*net_order = NULL;
	return;
}

static char v4_loop[4] = { 127, 0, 0, 1 };

#define SETERROR(code) \
	do { result = (code);			\
		if (result != 0) goto cleanup;	\
	} while (0)

static int add_ipv4
(
	const char 		*hostname, 
	int 			flags, 
	struct addrinfo **aip,
	int 			socktype, 
	int 			port
)
{
	struct addrinfo *ai;
	int 			result = 0;
	boolean 		resolving_result = FALSE;
	_ip_address 	ipaddr; 
    char  		   *ipname = NULL; 

    /*
     *	In this case addr = 127.0.0.1 to get connection 
     *	inside host using LOOPBACK interface .
     */
     
	if (hostname == NULL && (flags & AI_PASSIVE) == 0) 
	{
		ai = ai_clone(*aip, AF_INET);
		if (ai == NULL) 
		{
			freeaddrinfo(*aip);
			SETERROR(EAI_MEMORY);
		}
		*aip = ai;
		ai->ai_socktype = socktype;
		SIN(ai->ai_addr)->sin_port = port;
		memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
	} else 	{
		/* if the hostname is not NULL,lets try to resolve it 		*/
		/* here we are using RTCS DNS  service to get addr by name 	*/
	ipname= RTCS_mem_alloc(MAX_HOSTNAME_SIZE);
	if(ipname == NULL)
	{
		SETERROR(EAI_MEMORY);
	}
		memset (ipname, 0, sizeof (ipname));
		resolving_result =  RTCS_resolve_ip_address(
													(char *)hostname, 
															&ipaddr,        	 
															ipname, 			
															MAX_HOSTNAME_SIZE	
          	   		                               );
		if (resolving_result != TRUE) 
		{
				SETERROR(EAI_FAIL);
		}
		ai = ai_clone(*aip, AF_INET);
			if (ai == NULL) 
			{
				freeaddrinfo(*aip);
				SETERROR(EAI_MEMORY);
			}
			*aip = ai;
			ai->ai_socktype = socktype;
			((struct sockaddr_in *)(ai->ai_addr))->sin_port = port;
			memcpy(&((struct sockaddr_in *)(ai->ai_addr))->sin_addr,&ipaddr,4);
			if (flags & AI_CANONNAME) 
			{
				ai->ai_canonname = strdup(ipname);
				if (ai->ai_canonname == NULL)
				{
					SETERROR(EAI_NONAME);
				}
			}
	
		
	}/* end of (hostname == NULL && (flags & AI_PASSIVE) == 0) */
 
 cleanup:
	_mem_free(ipname);
	return (result);
}


static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };

static int add_ipv6	(
						const char 			*hostname, 
						int 				flags, 
						struct addrinfo 	**aip,
	 					int 				socktype, 
	 					int 				port
	 				)
{

	struct addrinfo *ai;
	int 			result = 0;
	boolean 		resolving_result = FALSE;
    char  		   *ipname = NULL; 


	if (hostname == NULL && (flags & AI_PASSIVE) == 0) 
	{
		ai = ai_clone(*aip, AF_INET6);
		if (ai == NULL) 
		{
			freeaddrinfo(*aip);
			SETERROR(EAI_MEMORY);
		}
		*aip = ai;
		ai->ai_socktype = socktype;
		SIN6(ai->ai_addr)->sin6_port = port;
		memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
	
	} else {
   
   /*	IPv6 DNS resolver is not ready yet*/
    
   /*
	*	resolving_result = RTCS_resolve_ip_address6(
	*										(char *)hostname, 
	*										&ipaddr,        	 
	*										ipname, 			
	*										MAX_HOSTNAME_SIZE	
    *    	   		                     );
	*/
		resolving_result= TRUE;
		ipname = "www.example.com";
	/*************************************************/
	
		if (resolving_result!= TRUE) 
		{
				SETERROR(EAI_FAIL);
		}				
		ai = ai_clone(*aip, AF_INET6);
		if (ai == NULL) 
		{
			freeaddrinfo(*aip);
			SETERROR(EAI_MEMORY);
		}
		*aip = ai;
		ai->ai_socktype = socktype;
		SIN6(ai->ai_addr)->sin6_port = port;
		
		/* memcpy(&SIN6(ai->ai_addr)->sin6_addr, &ipaddr, 16); */
		memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
		
		if (flags & AI_CANONNAME) 
		{
			ai->ai_canonname = strdup(ipname);
			if (ai->ai_canonname == NULL)
			{
				freeaddrinfo(*aip);
				SETERROR(EAI_NONAME);
			}
		}
		
	}/* end of (hostname == NULL && (flags & AI_PASSIVE) == 0) */
	
 cleanup:

	return (result);
}



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : freeaddrinfo
* Returned Value  : void
* Comments        : Free address info.
*
*END*-----------------------------------------------------------------*/
void freeaddrinfo	(
						struct addrinfo *ai
					) 
{
	struct addrinfo *ai_next;

	while (ai != NULL) 
	{
		ai_next = ai->ai_next;
		if (ai->ai_addr != NULL)
		{
			_mem_free(ai->ai_addr);
		}
		if (ai->ai_canonname)
		{
			_mem_free(ai->ai_canonname);
		}
		_mem_free(ai);
		ai = ai_next;
	}
}


/*!
 * Allocate an addrinfo structure, and a sockaddr structure
 * of the specificed length.  We initialize:
 *	ai_addrlen
 *	ai_family
 *	ai_addr
 *	ai_addr->sa_family
 *	ai_addr->sa_len	(LWRES_PLATFORM_HAVESALEN)
 * and everything else is initialized to zero.
 */
static struct addrinfo *ai_alloc	(
										int family, 
										int addrlen
									) 
{
	struct addrinfo *ai;

	ai = (struct addrinfo *) _mem_alloc_system_zero(sizeof(*ai));
	if (ai == NULL)
	{
		return (NULL);
	}
	ai->ai_addr = SA(_mem_alloc_system_zero(addrlen));
	if (ai->ai_addr == NULL) 
	{
		_mem_free(ai);
		return (NULL);
	}
	ai->ai_addrlen = addrlen;
	ai->ai_family = family;

    ai->ai_addr->sa_family = family;
	
	return (ai);
}

static struct addrinfo *ai_clone	(
										struct addrinfo *oai, 
										int family
									) 
{
	struct addrinfo *ai;

	ai = ai_alloc(family, ((family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)));
	if (ai == NULL) 
	{
		freeaddrinfo(oai);
		return (NULL);
	}
	if (oai == NULL)
	{
		return (ai);
	}
	ai->ai_flags = oai->ai_flags;
	ai->ai_socktype = oai->ai_socktype;
	ai->ai_protocol = oai->ai_protocol;
	ai->ai_canonname = NULL;
	ai->ai_next = oai;
	return (ai);
}

static struct addrinfo *ai_reverse	(
										struct addrinfo *oai
									) 
{
	struct addrinfo *nai, *tai;

	nai = NULL;

	while (oai != NULL) 
	{
		/*
		 * Grab one off the old list.
		 */
		tai = oai;
		oai = oai->ai_next;
		/*
		 * Put it on the front of the new list.
		 */
		tai->ai_next = nai;
		nai = tai;
	}
	return (nai);
}


char * strdup	( 
					const char *s
				)
{
  unsigned int len = strlen (s) + 1;
  
  char *result = (char*) _mem_alloc_system(len);
  if (result != NULL)
  {
	  _mem_copy((void*) s, result, len);
  }
  return result;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/ifdnat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifdnat.c$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the implementation of DNAT specific
*   user interface functions
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>
#include <stddef.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNAT_add_rule
* Returned Value  : RTCS_OK or error code
* Comments        :  
*    Adds a dnat rule to the dnat rule table. Rules in the dnat 
*    rule are adminisratively ordered based on priority. The priority 
*    must be unique.
*
*END*-----------------------------------------------------------------*/

uint_32 DNAT_add_rule
   (
      uint_32         priority,        /* [IN] */   
      uint_16         protocol,        /* [IN] */
      uint_16         start_port,      /* [IN] */
      uint_16         end_port,        /* [IN] */
      _ip_address     private_ip,      /* [IN]  */
      uint_16         private_port
   )
{ /* Body */
   
   DNAT_PARM          dparms;

   if (priority == 0) {
      return RTCSERR_NAT_INVALID_RULE;
   }

   dparms.RULE.PRIORITY           = priority;
   dparms.RULE.IP_PROTOCOL        = protocol;
   dparms.RULE.PUBLIC_START_PORT  = start_port;
   dparms.RULE.PUBLIC_END_PORT    = end_port;
   dparms.RULE.PRIVATE_START_PORT = private_port;
   dparms.RULE.PRIVATE_END_PORT   = (uint_16) ((uint_32)private_port+end_port-start_port);
   dparms.RULE.PRIVATE_IP         = private_ip;
   // NAT event add needs to sort timeouts before a non-default (non-zero) timeout will work
   dparms.RULE.TIMEOUT            = 0;  
   return RTCSCMD_issue(dparms, DNAT_add_rule_internal);
     
}/* Endbody */
  
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNAT_delete_rule
* Returned Value  : RTCS_OK or error code
* Comments        :
*     Removes a dnat rule from the dnat rule table.
*
*END*-----------------------------------------------------------------*/

uint_32  DNAT_delete_rule
   (
    uint_32  priority
    )
{ /* Body */   
   DNAT_PARM          dparms;
   
   if (priority == 0) {
      return RTCSERR_NAT_INVALID_RULE;
   }

   dparms.RULE.PRIORITY = priority;
   
   return RTCSCMD_issue(dparms, DNAT_delete_rule_internal);
   
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNAT_get_next_rule
* Returned Value  : RTCS_OK or error code
* Comments        :
*     Returns a dnat rul from the rule table.
*
*END*-----------------------------------------------------------------*/

uint_32  DNAT_get_next_rule
   (
      uint_32_ptr          priority_ptr,    /* [IN/OUT] */  
      uint_16_ptr          protocol_ptr,    /* [OUT] */
      uint_16_ptr          start_port_ptr,  /* [OUT] */
      uint_16_ptr          end_port_ptr,    /* [OUT] */
      _ip_address _PTR_    private_ip_ptr,  /* [OUT] */
      uint_16_ptr          private_port_ptr /* [OUT] */
    )
{ /* Body */   
   DNAT_PARM      dparms;
   uint_32        result;
      
   dparms.RULE.PRIORITY = MAX_UINT_32;
   
   if (priority_ptr != NULL)
   {
	   dparms.RULE.PRIORITY = (*priority_ptr) ? (*priority_ptr) : (MAX_UINT_32); 
   }
	   
   result = RTCSCMD_issue(dparms, DNAT_get_next_rule_internal);

   if (result == RTCS_OK) {
      if (priority_ptr != NULL)     *priority_ptr     = dparms.RULE.PRIORITY;
      if (protocol_ptr != NULL)     *protocol_ptr     = dparms.RULE.IP_PROTOCOL;
      if (start_port_ptr != NULL)   *start_port_ptr   = dparms.RULE.PUBLIC_START_PORT;
      if (end_port_ptr != NULL)     *end_port_ptr     = dparms.RULE.PUBLIC_END_PORT;
      if (private_port_ptr != NULL) *private_port_ptr = dparms.RULE.PRIVATE_START_PORT;
      if (private_ip_ptr != NULL)   *private_ip_ptr   = dparms.RULE.PRIVATE_IP;
   }
   return result;

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/phy/phy_dp83xxx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: phy_dp83xxx.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*  This file contains definitions that belongs to the Natioanl Semiconductor
*  PHY chips DP83848, DP83849, DP83640.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"
#include "enet.h"
#include "enetprv.h"
#include "phy_dp83xxx.h"

static boolean phy_dp83xxx_discover_addr(ENET_CONTEXT_STRUCT_PTR enet_ptr);
static boolean phy_dp83xxx_init(ENET_CONTEXT_STRUCT_PTR enet_ptr);
static uint_32 phy_dp83xxx_get_speed(ENET_CONTEXT_STRUCT_PTR enet_ptr);
static boolean phy_dp83xxx_get_link_status(ENET_CONTEXT_STRUCT_PTR enet_ptr);

const ENET_PHY_IF_STRUCT phy_dp83xxx_IF = {
  phy_dp83xxx_discover_addr,
  phy_dp83xxx_init,
  phy_dp83xxx_get_speed,
  phy_dp83xxx_get_link_status
};
  
  

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : phy_dp83xxx_discover_addr
*  Returned Value : none
*  Comments       :
*    Scan possible PHY addresses looking for a valid device
*
*END*-----------------------------------------------------------------*/

static boolean phy_dp83xxx_discover_addr
   (
       ENET_CONTEXT_STRUCT_PTR     enet_ptr
   )
{ 
   uint_32              i;
   uint_32              id;

   for (i = 0; i < 32; i++) {
      id = 0;
      enet_ptr->PHY_ADDRESS = i;
      
      if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, DP83XXX_REG_IDR1, &id, MII_TIMEOUT)) 
      {
          if ((id != 0) && (id != 0xffff)) 
          {
                return TRUE;
          }
      } 
   } 
   
   return FALSE; 
} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : phy_dp83xxx_init
*  Returned Value : boolean
*  Comments       :
*    Wait for PHY to automatically negotiate its configuration
*
*END*-----------------------------------------------------------------*/

static boolean phy_dp83xxx_init
   (
       ENET_CONTEXT_STRUCT_PTR     enet_ptr
   )
{ 
   uint_32              phy_status=0;

   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PHY_LOOPBACK) {
      if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, DP83XXX_REG_BMCR, &phy_status, MII_TIMEOUT)) {
         phy_status |= DP83XXX_REG_BMCR_LOOPBACK;
         (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_WRITE)(enet_ptr, DP83XXX_REG_BMCR, phy_status, MII_TIMEOUT);
         return TRUE;
      }
   } else {
     if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, DP83XXX_REG_BMSR, &phy_status, MII_TIMEOUT)) {
        if (phy_status & DP83XXX_REG_BMSR_AUTO_NEG_ABILITY) { 
           // Has auto-negotiate ability
           int i;
           for (i = 0; i < 3 * BSP_ALARM_FREQUENCY; i++) {
              if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, DP83XXX_REG_BMSR, &phy_status, MII_TIMEOUT)) 
                 if ((phy_status & DP83XXX_REG_BMSR_AUTO_NEG_COMPLETE) != 0) 
                    return TRUE;
              _time_delay(BSP_ALARM_RESOLUTION);
           }  
        }
        return TRUE;
      }
   }  
   return FALSE;
}  


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : phy_dp83xxx_get_speed
*  Returned Value : uint_32 - connection speed
*  Comments       :
*    Determine if connection speed is 10 or 100 Mbit
*
*END*-----------------------------------------------------------------*/

static uint_32 phy_dp83xxx_get_speed
   (
       ENET_CONTEXT_STRUCT_PTR     enet_ptr
   )
{ 
   uint_32              speed_status;

   if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, DP83XXX_REG_PHYSTS, &speed_status, MII_TIMEOUT)) {
      return ((speed_status & DP83848_REG_STS_SPEED) == 0) ? 100 : 10;
   }
   return 0;
} 
   
  
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : phy_dp83xxx_get_link_status
*  Returned Value : TRUE if link active, FALSE otherwise
*  Comments       : 
*    Get actual link status.
*
*END*-----------------------------------------------------------------*/

static boolean phy_dp83xxx_get_link_status
   (
       ENET_CONTEXT_STRUCT_PTR     enet_ptr
   )
{ 
   uint_32 data;
   boolean res = FALSE;

   /* Some PHY (e.g.DP8340) returns "unconnected" and than "connected" state
   *  just to show that was transition event from one state to another.
   *  As we need only curent state,  read 2 times and return 
   *  the current/latest state. */
   if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, DP83XXX_REG_BMSR, &data, MII_TIMEOUT)) {
      if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, DP83XXX_REG_BMSR, &data, MII_TIMEOUT))
      {
         res = ((data & DP83XXX_REG_BMSR_LINK_STATUS) != 0) ? TRUE : FALSE;
      }
   }
   return res;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/i2c.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c.h$
* $Version : 3.8.13.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the I2C I/O functions.
*
*END************************************************************************/

#ifndef _i2c_h_
#define _i2c_h_ 1

#include <ioctl.h>


/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/* 
** I2C internal states
*/
enum 
{
   I2C_STATE_READY = 0,
   I2C_STATE_REPEATED_START,
   I2C_STATE_TRANSMIT,
   I2C_STATE_RECEIVE,
   I2C_STATE_ADDRESSED_AS_SLAVE_RX,
   I2C_STATE_ADDRESSED_AS_SLAVE_TX,
   I2C_STATE_LOST_ARBITRATION,
   I2C_STATE_FINISHED
};

/* 
** IOCTL calls specific to I2C 
*/
#define IO_IOCTL_I2C_SET_BAUD                         _IO(IO_TYPE_I2C,0x01)
#define IO_IOCTL_I2C_GET_BAUD                         _IO(IO_TYPE_I2C,0x02)
#define IO_IOCTL_I2C_SET_MASTER_MODE                  _IO(IO_TYPE_I2C,0x03)
#define IO_IOCTL_I2C_SET_SLAVE_MODE                   _IO(IO_TYPE_I2C,0x04)
#define IO_IOCTL_I2C_GET_MODE                         _IO(IO_TYPE_I2C,0x05)
#define IO_IOCTL_I2C_SET_STATION_ADDRESS              _IO(IO_TYPE_I2C,0x06)
#define IO_IOCTL_I2C_GET_STATION_ADDRESS              _IO(IO_TYPE_I2C,0x07)
#define IO_IOCTL_I2C_SET_DESTINATION_ADDRESS          _IO(IO_TYPE_I2C,0x08)
#define IO_IOCTL_I2C_GET_DESTINATION_ADDRESS          _IO(IO_TYPE_I2C,0x09)
#define IO_IOCTL_I2C_SET_RX_REQUEST                   _IO(IO_TYPE_I2C,0x0A)
#define IO_IOCTL_I2C_REPEATED_START                   _IO(IO_TYPE_I2C,0x0B)
#define IO_IOCTL_I2C_STOP                             _IO(IO_TYPE_I2C,0x0C)
#define IO_IOCTL_I2C_GET_STATE                        _IO(IO_TYPE_I2C,0x0D)
#define IO_IOCTL_I2C_GET_STATISTICS                   _IO(IO_TYPE_I2C,0x0E)
#define IO_IOCTL_I2C_CLEAR_STATISTICS                 _IO(IO_TYPE_I2C,0x0F)
#define IO_IOCTL_I2C_DISABLE_DEVICE                   _IO(IO_TYPE_I2C,0x10)
#define IO_IOCTL_I2C_ENABLE_DEVICE                    _IO(IO_TYPE_I2C,0x11)
#define IO_IOCTL_I2C_GET_BUS_AVAILABILITY             _IO(IO_TYPE_I2C,0x12)

/* 
** I2C Bus Modes
*/
#define I2C_MODE_MASTER                               (0x00)
#define I2C_MODE_SLAVE                                (0x01)

/* 
** I2C Bus Operations
*/
#define I2C_OPERATION_WRITE                           (0x00)
#define I2C_OPERATION_READ                            (0x01)
#define I2C_OPERATION_STARTED                         (0x02)

/* 
** I2C Bus Availability
*/
#define I2C_BUS_IDLE                                  (0x00)
#define I2C_BUS_BUSY                                  (0x01)

/* 
** I2C Error Codes
*/
#define I2C_OK                                        (0x00)
#define I2C_ERROR_DEVICE_BUSY                         (I2C_ERROR_BASE | 0x01)
#define I2C_ERROR_CHANNEL_INVALID                     (I2C_ERROR_BASE | 0x02)
#define I2C_ERROR_INVALID_PARAMETER                   (I2C_ERROR_BASE | 0x03)
#define I2C_ERROR_LINE_TIMEOUT                        (I2C_ERROR_BASE | 0x04)

/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/
 
typedef struct i2c_statistics_struct 
{
   /* Number of I2C interrupts so far */
   uint_32               INTERRUPTS;

   /* Number of valid bytes received (not dummy receives) */
   uint_32               RX_PACKETS;

   /* Number of valid bytes transmitted (not dummy transmits) */
   uint_32               TX_PACKETS;

   /* Number of times master lost arbitration */
   uint_32               TX_LOST_ARBITRATIONS;

   /* Number of times master was addressed as slave */
   uint_32               TX_ADDRESSED_AS_SLAVE;

   /* Number of not acknowledged (interrupted) transmits */
   uint_32               TX_NAKS;
   
} I2C_STATISTICS_STRUCT, _PTR_ I2C_STATISTICS_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_uint _io_i2c_polled_install(
      char_ptr,
      _mqx_uint (_CODE_PTR_)(pointer, pointer _PTR_, char_ptr),
      _mqx_uint (_CODE_PTR_)(pointer, pointer),
      _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
      _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
      _mqx_int (_CODE_PTR_)(pointer, _mqx_uint, _mqx_uint_ptr),
      pointer);

extern _mqx_uint _io_i2c_int_install(
      char_ptr,
      _mqx_uint (_CODE_PTR_)(pointer, char_ptr),
      _mqx_uint (_CODE_PTR_)(pointer, pointer),
      _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
      _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
      _mqx_int (_CODE_PTR_)(pointer, _mqx_uint, _mqx_uint_ptr),
      pointer);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/FTM_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type FTM
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(FTM_PDD_H_)
#define FTM_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error FTM PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK10D5) /* FTM0, FTM1 */ && \
      !defined(MCU_MK10D7) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK10F12) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK10DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK11D5) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK11D5WS) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK12D5) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK20D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK20D5) /* FTM0, FTM1 */ && \
      !defined(MCU_MK20D7) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK20F12) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK20DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK21D5) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK21D5WS) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK22D5) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK30D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK30D7) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK30DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK40D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK40D7) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK40DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK40X256VMD100) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK50D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK50D7) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK50DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK51D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK51D7) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK51DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK52D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK52DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK53D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK53DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK60D10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK60F12) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK60F15) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK60DZ10) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK60N512VMD100) /* FTM0, FTM1, FTM2 */ && \
      !defined(MCU_MK61F12) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK61F15) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK61F12WS) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK61F15WS) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK70F12) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK70F15) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK70F12WS) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_MK70F15WS) /* FTM0, FTM1, FTM2, FTM3 */ && \
      !defined(MCU_PCK20L4) /* FTM0, FTM1 */
  // Unsupported MCU is active
  #error FTM PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* FTM channel constants */
#define FTM_PDD_CHANNEL_0 0U                     /**< 0 */
#define FTM_PDD_CHANNEL_1 0x1U                   /**< 1 */
#define FTM_PDD_CHANNEL_2 0x2U                   /**< 2 */
#define FTM_PDD_CHANNEL_3 0x3U                   /**< 3 */
#define FTM_PDD_CHANNEL_4 0x4U                   /**< 4 */
#define FTM_PDD_CHANNEL_5 0x5U                   /**< 5 */
#define FTM_PDD_CHANNEL_6 0x6U                   /**< 6 */
#define FTM_PDD_CHANNEL_7 0x7U                   /**< 7 */

/* Prescaler constants */
#define FTM_PDD_DIVIDE_1   0U                    /**< 1 */
#define FTM_PDD_DIVIDE_2   0x1U                  /**< 2 */
#define FTM_PDD_DIVIDE_4   0x2U                  /**< 4 */
#define FTM_PDD_DIVIDE_8   0x3U                  /**< 8 */
#define FTM_PDD_DIVIDE_16  0x4U                  /**< 16 */
#define FTM_PDD_DIVIDE_32  0x5U                  /**< 32 */
#define FTM_PDD_DIVIDE_64  0x6U                  /**< 64 */
#define FTM_PDD_DIVIDE_128 0x7U                  /**< 128 */

/* PWM aligned mode constants */
#define FTM_PDD_EDGE_ALIGNED   0U                /**< Edge aligned */
#define FTM_PDD_CENTER_ALIGNED FTM_SC_CPWMS_MASK /**< Center aligned */

/* Interrupt flag masks for ClearChannelFlag */
#define FTM_PDD_FLAG_0 0x1U                      /**< 0 */
#define FTM_PDD_FLAG_1 0x2U                      /**< 1 */
#define FTM_PDD_FLAG_2 0x4U                      /**< 2 */
#define FTM_PDD_FLAG_3 0x8U                      /**< 3 */
#define FTM_PDD_FLAG_4 0x10U                     /**< 4 */
#define FTM_PDD_FLAG_5 0x20U                     /**< 5 */
#define FTM_PDD_FLAG_6 0x40U                     /**< 6 */
#define FTM_PDD_FLAG_7 0x80U                     /**< 7 */

/* Clock source constants. */
#define FTM_PDD_DISABLED 0U                      /**< Disabled */
#define FTM_PDD_SYSTEM   0x8U                    /**< System clock */
#define FTM_PDD_FIXED    0x10U                   /**< Fixed clock */
#define FTM_PDD_EXTERNAL 0x18U                   /**< External clock */

/* Edge and level constants. */
#define FTM_PDD_EDGE_NONE    0U                  /**< Disabled */
#define FTM_PDD_EDGE_RISING  0x4U                /**< Rising */
#define FTM_PDD_EDGE_FALLING 0x8U                /**< Falling */
#define FTM_PDD_EDGE_BOTH    0xCU                /**< Both */

/* Output action constants. */
#define FTM_PDD_OUTPUT_NONE   0U                 /**< Disconnect */
#define FTM_PDD_OUTPUT_TOGGLE 0x10U              /**< Toggle */
#define FTM_PDD_OUTPUT_CLEAR  0x20U              /**< Clear */
#define FTM_PDD_OUTPUT_SET    0x30U              /**< Set */


/* ----------------------------------------------------------------------------
   -- SetPrescaler
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets prescale value.
 * @param PeripheralBase Peripheral base address.
 * @param Prescaler New value of the prescaler. Use constants from group
 *        "Prescaler constants". This parameter is 3 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_SetPrescaler(deviceID, FTM_PDD_DIVIDE_1);
 *      @endcode
 */
#define FTM_PDD_SetPrescaler(PeripheralBase, Prescaler) ( \
    FTM_SC_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       FTM_SC_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)FTM_SC_PS_MASK)) & ( \
       (uint32_t)(~(uint32_t)FTM_SC_TOF_MASK))))) | ( \
      (uint32_t)(Prescaler))) \
  )

/* ----------------------------------------------------------------------------
   -- SelectPrescalerSource
   ---------------------------------------------------------------------------- */

/**
 * @brief Select clock source.
 * @param PeripheralBase Peripheral base address.
 * @param Source New value of the source. This parameter is of "Clock source
 *        constants." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_SelectPrescalerSource(deviceID, FTM_PDD_DISABLED);
 *      @endcode
 */
#define FTM_PDD_SelectPrescalerSource(PeripheralBase, Source) ( \
    FTM_SC_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       FTM_SC_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)FTM_SC_CLKS_MASK)) & ( \
       (uint32_t)(~(uint32_t)FTM_SC_TOF_MASK))))) | ( \
      (uint32_t)(Source))) \
  )

/* ----------------------------------------------------------------------------
   -- GetEnableDeviceStatus
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns current state of FTM device.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_GetEnableDeviceStatus(deviceID);
 *      @endcode
 */
#define FTM_PDD_GetEnableDeviceStatus(PeripheralBase) ( \
    (uint32_t)(FTM_SC_REG(PeripheralBase) & FTM_SC_CLKS_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SelectPwmAlignMode
   ---------------------------------------------------------------------------- */

/**
 * @brief Configures PWM aligned mode.
 * @param PeripheralBase Peripheral base address.
 * @param Mode New value of the mode. Use constants from group "PWM aligned mode
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_SelectPwmAlignMode(deviceID, FTM_PDD_EDGE_ALIGNED);
 *      @endcode
 */
#define FTM_PDD_SelectPwmAlignMode(PeripheralBase, Mode) ( \
    FTM_SC_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       FTM_SC_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)FTM_SC_CPWMS_MASK)) & ( \
       (uint32_t)(~(uint32_t)FTM_SC_TOF_MASK))))) | ( \
      (uint32_t)(Mode))) \
  )

/* ----------------------------------------------------------------------------
   -- GetOverflowInterruptMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns overflow interrupt mask.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_GetOverflowInterruptMask(deviceID);
 *      @endcode
 */
#define FTM_PDD_GetOverflowInterruptMask(PeripheralBase) ( \
    (uint32_t)(FTM_SC_REG(PeripheralBase) & FTM_SC_TOIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableOverflowInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the FTM overflow interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_EnableOverflowInterrupt(deviceID);
 *      @endcode
 */
#define FTM_PDD_EnableOverflowInterrupt(PeripheralBase) ( \
    FTM_SC_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(FTM_SC_REG(PeripheralBase) | FTM_SC_TOIE_MASK)) & ( \
      (uint32_t)(~(uint32_t)FTM_SC_TOF_MASK))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableOverflowInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the FTM overflow interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_DisableOverflowInterrupt(deviceID);
 *      @endcode
 */
#define FTM_PDD_DisableOverflowInterrupt(PeripheralBase) ( \
    FTM_SC_REG(PeripheralBase) &= \
     (uint32_t)(( \
      (uint32_t)(~(uint32_t)FTM_SC_TOIE_MASK)) & ( \
      (uint32_t)(~(uint32_t)FTM_SC_TOF_MASK))) \
  )

/* ----------------------------------------------------------------------------
   -- GetOverflowInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns overflow interrupt flag bit.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_GetOverflowInterruptFlag(deviceID);
 *      @endcode
 */
#define FTM_PDD_GetOverflowInterruptFlag(PeripheralBase) ( \
    (uint32_t)(FTM_SC_REG(PeripheralBase) & FTM_SC_TOF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClearOverflowInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears overflow interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SC, FTM1_SC,
 *          FTM2_SC, FTM3_SC (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_ClearOverflowInterruptFlag(deviceID);
 *      @endcode
 */
#define FTM_PDD_ClearOverflowInterruptFlag(PeripheralBase) ( \
    FTM_SC_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)FTM_SC_TOF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ReadCounterReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the counter register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_CNT, FTM1_CNT,
 *          FTM2_CNT, FTM3_CNT (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadCounterReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadCounterReg(PeripheralBase) ( \
    FTM_CNT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- InitializeCounter
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value 0 to the counter register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_CNT, FTM1_CNT,
 *          FTM2_CNT, FTM3_CNT (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_InitializeCounter(deviceID);
 *      @endcode
 */
#define FTM_PDD_InitializeCounter(PeripheralBase) ( \
    FTM_CNT_REG(PeripheralBase) = \
     0U \
  )

/* ----------------------------------------------------------------------------
   -- WriteModuloReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the modulo register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the modulo register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_MOD, FTM1_MOD,
 *          FTM2_MOD, FTM3_MOD (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteModuloReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteModuloReg(PeripheralBase, Value) ( \
    FTM_MOD_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadModuloReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the modulo register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_MOD, FTM1_MOD,
 *          FTM2_MOD, FTM3_MOD (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadModuloReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadModuloReg(PeripheralBase) ( \
    FTM_MOD_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- EnableChannelDma
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the FTM channel DMA.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_EnableChannelDma(deviceID, FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_EnableChannelDma(PeripheralBase, ChannelIdx) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) = \
     (uint32_t)(( \
      (uint32_t)(FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) | FTM_CnSC_DMA_MASK)) & ( \
      (uint32_t)(~(uint32_t)FTM_CnSC_CHF_MASK))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableChannelDma
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the FTM channel DMA.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_DisableChannelDma(deviceID, FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_DisableChannelDma(PeripheralBase, ChannelIdx) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) &= \
     (uint32_t)(( \
      (uint32_t)(~(uint32_t)FTM_CnSC_DMA_MASK)) & ( \
      (uint32_t)(~(uint32_t)FTM_CnSC_CHF_MASK))) \
  )

/* ----------------------------------------------------------------------------
   -- SelectChannelEdgeLevel
   ---------------------------------------------------------------------------- */

/**
 * @brief Selects the FTM channel edge and level.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @param ELSBA_val FTM channel ELSB:ELSA bits. This parameter is of "Edge and
 *        level constants." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_SelectChannelEdgeLevel(deviceID, FTM_PDD_CHANNEL_0,
 *      FTM_PDD_EDGE_NONE);
 *      @endcode
 */
#define FTM_PDD_SelectChannelEdgeLevel(PeripheralBase, ChannelIdx, ELSBA_val) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       FTM_CnSC_REG(PeripheralBase,(ChannelIdx))) & (( \
       (uint32_t)(~(uint32_t)((uint32_t)0x3U << 2U))) & ( \
       (uint32_t)(~(uint32_t)FTM_CnSC_CHF_MASK))))) | ( \
      (uint32_t)(ELSBA_val))) \
  )

/* ----------------------------------------------------------------------------
   -- SelectChannelMode
   ---------------------------------------------------------------------------- */

/**
 * @brief Selects the FTM channel mode.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @param MSBA_val FTM channel MSB:MSA bits. This parameter is of "Output action
 *        constants." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_SelectChannelMode(deviceID, FTM_PDD_CHANNEL_0,
 *      FTM_PDD_OUTPUT_NONE);
 *      @endcode
 */
#define FTM_PDD_SelectChannelMode(PeripheralBase, ChannelIdx, MSBA_val) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       FTM_CnSC_REG(PeripheralBase,(ChannelIdx))) & (( \
       (uint32_t)(~(uint32_t)((uint32_t)0x3U << 4U))) & ( \
       (uint32_t)(~(uint32_t)FTM_CnSC_CHF_MASK))))) | ( \
      (uint32_t)(MSBA_val))) \
  )

/* ----------------------------------------------------------------------------
   -- GetChannelInterruptMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns channel interrupt mask.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_GetChannelInterruptMask(deviceID,
 *      FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_GetChannelInterruptMask(PeripheralBase, ChannelIdx) ( \
    (uint32_t)(FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) & FTM_CnSC_CHIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableChannelInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the FTM channel interrupt.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_EnableChannelInterrupt(deviceID, FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_EnableChannelInterrupt(PeripheralBase, ChannelIdx) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) = \
     (uint32_t)(( \
      (uint32_t)(FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) | FTM_CnSC_CHIE_MASK)) & ( \
      (uint32_t)(~(uint32_t)FTM_CnSC_CHF_MASK))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableChannelInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the FTM channel interrupt.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_DisableChannelInterrupt(deviceID, FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_DisableChannelInterrupt(PeripheralBase, ChannelIdx) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) &= \
     (uint32_t)(( \
      (uint32_t)(~(uint32_t)FTM_CnSC_CHIE_MASK)) & ( \
      (uint32_t)(~(uint32_t)FTM_CnSC_CHF_MASK))) \
  )

/* ----------------------------------------------------------------------------
   -- GetChannelInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns channel interrupt flag bit.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_GetChannelInterruptFlag(deviceID,
 *      FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_GetChannelInterruptFlag(PeripheralBase, ChannelIdx) ( \
    (uint32_t)(FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) & FTM_CnSC_CHF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClearChannelInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears channel interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_ClearChannelInterruptFlag(deviceID, FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_ClearChannelInterruptFlag(PeripheralBase, ChannelIdx) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) &= \
     (uint32_t)(~(uint32_t)FTM_CnSC_CHF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ReadChannelControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the channel status and control register.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadChannelControlReg(deviceID,
 *      FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_ReadChannelControlReg(PeripheralBase, ChannelIdx) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) \
  )

/* ----------------------------------------------------------------------------
   -- WriteChannelControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the channel status and control register.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @param Value New content of the channel status and control register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnSC[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_WriteChannelControlReg(deviceID, FTM_PDD_CHANNEL_0, 1);
 *      @endcode
 */
#define FTM_PDD_WriteChannelControlReg(PeripheralBase, ChannelIdx, Value) ( \
    FTM_CnSC_REG(PeripheralBase,(ChannelIdx)) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadChannelValueReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the channel value register.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: CnV[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadChannelValueReg(deviceID,
 *      FTM_PDD_CHANNEL_0);
 *      @endcode
 */
#define FTM_PDD_ReadChannelValueReg(PeripheralBase, ChannelIdx) ( \
    FTM_CnV_REG(PeripheralBase,(ChannelIdx)) \
  )

/* ----------------------------------------------------------------------------
   -- WriteChannelValueReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the channel value register.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx FTM channel index. Use constants from group "FTM channel
 *        constants". This parameter is 32 bits wide.
 * @param Value New content of the channel value register. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: CnV[ChannelIdx].
 * @par Example:
 *      @code
 *      FTM_PDD_WriteChannelValueReg(deviceID, FTM_PDD_CHANNEL_0, 1);
 *      @endcode
 */
#define FTM_PDD_WriteChannelValueReg(PeripheralBase, ChannelIdx, Value) ( \
    FTM_CnV_REG(PeripheralBase,(ChannelIdx)) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteInitialValueReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the counter initial value register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the counter initial value register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_CNTIN, FTM1_CNTIN,
 *          FTM2_CNTIN, FTM3_CNTIN (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteInitialValueReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteInitialValueReg(PeripheralBase, Value) ( \
    FTM_CNTIN_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadInitialValueReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the counter initial value register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_CNTIN, FTM1_CNTIN,
 *          FTM2_CNTIN, FTM3_CNTIN (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadInitialValueReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadInitialValueReg(PeripheralBase) ( \
    FTM_CNTIN_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetChannelFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the capture and compare status register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_STATUS,
 *          FTM1_STATUS, FTM2_STATUS, FTM3_STATUS (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_GetChannelFlags(deviceID);
 *      @endcode
 */
#define FTM_PDD_GetChannelFlags(PeripheralBase) ( \
    FTM_STATUS_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ClearChannelFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears channel interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt flag mask. Use constants from group "Interrupt flag
 *        masks for ClearChannelFlag". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_STATUS,
 *          FTM1_STATUS, FTM2_STATUS, FTM3_STATUS (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_ClearChannelFlags(deviceID, FTM_PDD_FLAG_0);
 *      @endcode
 */
#define FTM_PDD_ClearChannelFlags(PeripheralBase, Mask) ( \
    FTM_STATUS_REG(PeripheralBase) = \
     (uint32_t)((uint32_t)(~(uint32_t)(Mask)) & (uint32_t)0xFFU) \
  )

/* ----------------------------------------------------------------------------
   -- EnableFaultInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the FTM fault interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_MODE, FTM1_MODE,
 *          FTM2_MODE, FTM3_MODE (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_EnableFaultInterrupt(deviceID);
 *      @endcode
 */
#define FTM_PDD_EnableFaultInterrupt(PeripheralBase) ( \
    FTM_MODE_REG(PeripheralBase) |= \
     FTM_MODE_FAULTIE_MASK \
  )

/* ----------------------------------------------------------------------------
   -- DisableFaultInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the FTM fault interrupt.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_MODE, FTM1_MODE,
 *          FTM2_MODE, FTM3_MODE (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_DisableFaultInterrupt(deviceID);
 *      @endcode
 */
#define FTM_PDD_DisableFaultInterrupt(PeripheralBase) ( \
    FTM_MODE_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)FTM_MODE_FAULTIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- WriteProtectionDisable
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the write protection.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_MODE, FTM1_MODE,
 *          FTM2_MODE, FTM3_MODE (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteProtectionDisable(deviceID);
 *      @endcode
 */
#define FTM_PDD_WriteProtectionDisable(PeripheralBase) ( \
    FTM_MODE_REG(PeripheralBase) |= \
     FTM_MODE_WPDIS_MASK \
  )

/* ----------------------------------------------------------------------------
   -- InitializeOutputs
   ---------------------------------------------------------------------------- */

/**
 * @brief Initialize the channel outputs.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_MODE, FTM1_MODE,
 *          FTM2_MODE, FTM3_MODE (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_InitializeOutputs(deviceID);
 *      @endcode
 */
#define FTM_PDD_InitializeOutputs(PeripheralBase) ( \
    FTM_MODE_REG(PeripheralBase) |= \
     FTM_MODE_INIT_MASK \
  )

/* ----------------------------------------------------------------------------
   -- WriteFeaturesModeReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the feature mode selection register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the feature mode selection register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_MODE, FTM1_MODE,
 *          FTM2_MODE, FTM3_MODE (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteFeaturesModeReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteFeaturesModeReg(PeripheralBase, Value) ( \
    FTM_MODE_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFeaturesModeReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the features mode selection register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_MODE, FTM1_MODE,
 *          FTM2_MODE, FTM3_MODE (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadFeaturesModeReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadFeaturesModeReg(PeripheralBase) ( \
    FTM_MODE_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteSynchronizationReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the synchronization register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the synchronization register. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SYNC, FTM1_SYNC,
 *          FTM2_SYNC, FTM3_SYNC (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteSynchronizationReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteSynchronizationReg(PeripheralBase, Value) ( \
    FTM_SYNC_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSynchronizationReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the synchronization register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_SYNC, FTM1_SYNC,
 *          FTM2_SYNC, FTM3_SYNC (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadSynchronizationReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadSynchronizationReg(PeripheralBase) ( \
    FTM_SYNC_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteInitialOutputReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the initial state for channels output register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the initial state for channel output register.
 *        This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_OUTINIT,
 *          FTM1_OUTINIT, FTM2_OUTINIT, FTM3_OUTINIT (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteInitialOutputReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteInitialOutputReg(PeripheralBase, Value) ( \
    FTM_OUTINIT_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadInitialOutputReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the initial state for channels output register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_OUTINIT,
 *          FTM1_OUTINIT, FTM2_OUTINIT, FTM3_OUTINIT (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadInitialOutputReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadInitialOutputReg(PeripheralBase) ( \
    FTM_OUTINIT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteOutputMaskReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the output mask register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the output mask register. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_OUTMASK,
 *          FTM1_OUTMASK, FTM2_OUTMASK, FTM3_OUTMASK (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteOutputMaskReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteOutputMaskReg(PeripheralBase, Value) ( \
    FTM_OUTMASK_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadOutputMaskReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the output mask register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_OUTMASK,
 *          FTM1_OUTMASK, FTM2_OUTMASK, FTM3_OUTMASK (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadOutputMaskReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadOutputMaskReg(PeripheralBase) ( \
    FTM_OUTMASK_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteCombineReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the function for linked channels register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the function for linked channels register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_COMBINE,
 *          FTM1_COMBINE, FTM2_COMBINE, FTM3_COMBINE (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteCombineReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteCombineReg(PeripheralBase, Value) ( \
    FTM_COMBINE_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadCombineReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the function for linked channels register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_COMBINE,
 *          FTM1_COMBINE, FTM2_COMBINE, FTM3_COMBINE (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadCombineReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadCombineReg(PeripheralBase) ( \
    FTM_COMBINE_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteDeadtimeReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the deadtime insertion control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the deadtime insertion control register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_DEADTIME,
 *          FTM1_DEADTIME, FTM2_DEADTIME, FTM3_DEADTIME (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteDeadtimeReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteDeadtimeReg(PeripheralBase, Value) ( \
    FTM_DEADTIME_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadDeadtimeReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the deadtime insertion control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_DEADTIME,
 *          FTM1_DEADTIME, FTM2_DEADTIME, FTM3_DEADTIME (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadDeadtimeReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadDeadtimeReg(PeripheralBase) ( \
    FTM_DEADTIME_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteExternalTriggerReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the FTM external trigger register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the FTM external trigger register. This parameter
 *        is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_EXTTRIG,
 *          FTM1_EXTTRIG, FTM2_EXTTRIG, FTM3_EXTTRIG (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteExternalTriggerReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteExternalTriggerReg(PeripheralBase, Value) ( \
    FTM_EXTTRIG_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadExternalTriggerReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the FTM external trigger register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_EXTTRIG,
 *          FTM1_EXTTRIG, FTM2_EXTTRIG, FTM3_EXTTRIG (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadExternalTriggerReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadExternalTriggerReg(PeripheralBase) ( \
    FTM_EXTTRIG_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WritePolarityReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the channels polarity register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the channels polarity register. This parameter is
 *        a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_POL, FTM1_POL,
 *          FTM2_POL, FTM3_POL (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WritePolarityReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WritePolarityReg(PeripheralBase, Value) ( \
    FTM_POL_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadPolarityReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the channels polarity register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_POL, FTM1_POL,
 *          FTM2_POL, FTM3_POL (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadPolarityReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadPolarityReg(PeripheralBase) ( \
    FTM_POL_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFaultStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the fault mode status register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_FMS, FTM1_FMS,
 *          FTM2_FMS, FTM3_FMS (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadFaultStatusReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadFaultStatusReg(PeripheralBase) ( \
    FTM_FMS_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteProtectionEnable
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the write protection.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_FMS, FTM1_FMS,
 *          FTM2_FMS, FTM3_FMS (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteProtectionEnable(deviceID);
 *      @endcode
 */
#define FTM_PDD_WriteProtectionEnable(PeripheralBase) ( \
    FTM_FMS_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(FTM_FMS_REG(PeripheralBase) | FTM_FMS_WPEN_MASK)) & (( \
      (uint32_t)(~(uint32_t)FTM_FMS_FAULTF0_MASK)) & (( \
      (uint32_t)(~(uint32_t)FTM_FMS_FAULTF1_MASK)) & (( \
      (uint32_t)(~(uint32_t)FTM_FMS_FAULTF2_MASK)) & (( \
      (uint32_t)(~(uint32_t)FTM_FMS_FAULTF3_MASK)) & ( \
      (uint32_t)(~(uint32_t)FTM_FMS_FAULTF_MASK))))))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteInputCaptureFilterReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the input capture filter control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the input capture filter control register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_FILTER,
 *          FTM1_FILTER, FTM2_FILTER, FTM3_FILTER (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteInputCaptureFilterReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteInputCaptureFilterReg(PeripheralBase, Value) ( \
    FTM_FILTER_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadInputCaptureFilterReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the input capture filter control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_FILTER,
 *          FTM1_FILTER, FTM2_FILTER, FTM3_FILTER (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadInputCaptureFilterReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadInputCaptureFilterReg(PeripheralBase) ( \
    FTM_FILTER_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFaultControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the fault control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the fault control register. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_FLTCTRL,
 *          FTM1_FLTCTRL, FTM2_FLTCTRL, FTM3_FLTCTRL (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteFaultControlReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteFaultControlReg(PeripheralBase, Value) ( \
    FTM_FLTCTRL_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFaultControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the fault control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_FLTCTRL,
 *          FTM1_FLTCTRL, FTM2_FLTCTRL, FTM3_FLTCTRL (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadFaultControlReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadFaultControlReg(PeripheralBase) ( \
    FTM_FLTCTRL_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteQuadratureDecoderReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the quadrature decoder control and status register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the quadrature decoder control and status
 *        register. This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_QDCTRL,
 *          FTM1_QDCTRL, FTM2_QDCTRL, FTM3_QDCTRL (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteQuadratureDecoderReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteQuadratureDecoderReg(PeripheralBase, Value) ( \
    FTM_QDCTRL_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadQuadratureDecoderReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the quadrature decoder control and status
 * register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_QDCTRL,
 *          FTM1_QDCTRL, FTM2_QDCTRL, FTM3_QDCTRL (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadQuadratureDecoderReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadQuadratureDecoderReg(PeripheralBase) ( \
    FTM_QDCTRL_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteConfigurationReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the configuration register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the configuration register. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_CONF, FTM1_CONF,
 *          FTM2_CONF, FTM3_CONF (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteConfigurationReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteConfigurationReg(PeripheralBase, Value) ( \
    FTM_CONF_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadConfigurationReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the configuration register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_CONF, FTM1_CONF,
 *          FTM2_CONF, FTM3_CONF (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadConfigurationReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadConfigurationReg(PeripheralBase) ( \
    FTM_CONF_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFaultInputPolarityReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the FTM fault input polarity register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the FTM fault input polarity register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_FLTPOL,
 *          FTM1_FLTPOL, FTM2_FLTPOL, FTM3_FLTPOL (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteFaultInputPolarityReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteFaultInputPolarityReg(PeripheralBase, Value) ( \
    FTM_FLTPOL_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFaultInputPolarityReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the FTM fault input polarity register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_FLTPOL,
 *          FTM1_FLTPOL, FTM2_FLTPOL, FTM3_FLTPOL (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadFaultInputPolarityReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadFaultInputPolarityReg(PeripheralBase) ( \
    FTM_FLTPOL_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteSynchronizationConfigReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the synchronization configuration register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the synchronization configuration register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SYNCONF,
 *          FTM1_SYNCONF, FTM2_SYNCONF, FTM3_SYNCONF (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteSynchronizationConfigReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteSynchronizationConfigReg(PeripheralBase, Value) ( \
    FTM_SYNCONF_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSynchronizationConfigReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the synchronization configuration register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_SYNCONF,
 *          FTM1_SYNCONF, FTM2_SYNCONF, FTM3_SYNCONF (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadSynchronizationConfigReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadSynchronizationConfigReg(PeripheralBase) ( \
    FTM_SYNCONF_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteInvertingReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the FTM inverting control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the FTM inverting control register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_INVCTRL,
 *          FTM1_INVCTRL, FTM2_INVCTRL, FTM3_INVCTRL (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteInvertingReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteInvertingReg(PeripheralBase, Value) ( \
    FTM_INVCTRL_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadInvertingReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the FTM inverting control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_INVCTRL,
 *          FTM1_INVCTRL, FTM2_INVCTRL, FTM3_INVCTRL (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadInvertingReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadInvertingReg(PeripheralBase) ( \
    FTM_INVCTRL_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteSoftwareOutputReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the FTM software output control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the FTM software output control register. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_SWOCTRL,
 *          FTM1_SWOCTRL, FTM2_SWOCTRL, FTM3_SWOCTRL (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WriteSoftwareOutputReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WriteSoftwareOutputReg(PeripheralBase, Value) ( \
    FTM_SWOCTRL_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSoftwareOutputReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the FTM software output control register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_SWOCTRL,
 *          FTM1_SWOCTRL, FTM2_SWOCTRL, FTM3_SWOCTRL (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadSoftwareOutputReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadSoftwareOutputReg(PeripheralBase) ( \
    FTM_SWOCTRL_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WritePwmLoadReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the FTM PWM load register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the FTM PWM load register. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTM0_PWMLOAD,
 *          FTM1_PWMLOAD, FTM2_PWMLOAD, FTM3_PWMLOAD (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTM_PDD_WritePwmLoadReg(deviceID, 1);
 *      @endcode
 */
#define FTM_PDD_WritePwmLoadReg(PeripheralBase, Value) ( \
    FTM_PWMLOAD_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadPwmLoadReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the FTM PWM load register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTM0_PWMLOAD,
 *          FTM1_PWMLOAD, FTM2_PWMLOAD, FTM3_PWMLOAD (depending on the peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = FTM_PDD_ReadPwmLoadReg(deviceID);
 *      @endcode
 */
#define FTM_PDD_ReadPwmLoadReg(PeripheralBase) ( \
    FTM_PWMLOAD_REG(PeripheralBase) \
  )
#endif  /* #if defined(FTM_PDD_H_) */

/* FTM_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/phdc/usb_phdc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_phdc.c$
* $Version : 3.8.7.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
* @brief The file contains USB stack PHDC layer implimentation.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
 #include "usb_stack_config.h"
 #if PHDC_CONFIG 
#include "usb_phdc.h"
#include <string.h>
/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/

/****************************************************************************
 * Global Functions - Prototypes
 ****************************************************************************/
void USB_PHDC_Endpoint_Service(PTR_USB_EVENT_STRUCT event,pointer arg);
/****************************************************************************
 * Global Variables
 ****************************************************************************/
 /* Add all the variables needed for usb_phdc.c to this structure */
 PHDC_STRUCT_PTR  phdc_object_array[MAX_PHDC_OBJECT];

#if USB_METADATA_SUPPORTED
    static char msg_preamble_signature[17] = "PhdcQoSSignature";
    /* string used to give preamble verifiability */
#endif           
/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
static uint_8 USB_PHDC_Other_Requests(USB_SETUP_STRUCT * setup_packet, 
                                 uint_8_ptr *data, 
                                 uint_32 *size,
                                 pointer arg);
                          
static void USB_Class_PHDC_Event(uint_8 event,
                                 void * value,
                                 pointer arg);
/*****************************************************************************
 * Local Functions
 *****************************************************************************/
  /*************************************************************************//*!
 *
 * @name  USB_Phdc_Allocate_Handle
 *
 * @brief The funtion reserves entry in device array and returns the index.
 *
 * @param none.
 * @return returns the reserved handle or if no entry found device busy.      
 *
 *****************************************************************************/
static PHDC_HANDLE  USB_Phdc_Allocate_Handle()
{
    uint_32 cnt = 0;
    for (;cnt < MAX_PHDC_OBJECT;cnt++)
    {
       if (phdc_object_array[cnt] == NULL)
        return cnt;
    }
    return USBERR_DEVICE_BUSY;
}
 /*************************************************************************//*!
 *
 * @name  USB_Phdc_Free_Handle
 *
 * @brief The funtion releases entry in device array .
 *
 * @param handle  index in device array to be released..
 * @return returns and error code or USB_OK.      
 *
 *****************************************************************************/
static int_32 USB_Phdc_Free_Handle(PHDC_HANDLE handle)
{
    if (/*(handle < 0) || */(handle > MAX_PHDC_OBJECT))
        return USBERR_ERROR;
    
    USB_mem_free((void *)phdc_object_array[handle]);
    phdc_object_array[handle] = NULL;
    return USB_OK;
}
 /*************************************************************************//*!
 *
 * @name  USB_Phdc_Get_Device_Ptr
 *
 * @brief The funtion gets the device pointer from device array .
 *
 * @param handle  index in device array.
 * @return returns returns pointer to HID device structure..      
 *
 *****************************************************************************/
static PHDC_STRUCT_PTR USB_Phdc_Get_Device_Ptr(PHDC_HANDLE handle)
{
    if (/*(handle < 0) || */(handle > MAX_PHDC_OBJECT))
        return NULL;
    
     return phdc_object_array[handle]; 
}
 /**************************************************************************//*!
 *
 * @name  USB_Class_PHDC_Event
 *
 * @brief Initializes non control endpoints
 *
 * @param handle         
 * @param event          : event notified by the layer below
 * @param value          : additional parameter used by the event
 *
 * @return               : None
 ******************************************************************************
 * Initializes non control endpoints when Enumeration complete event is 
 * recieved. 
 *****************************************************************************/  
static void USB_Class_PHDC_Event(uint_8 event, 
                                 void* val,pointer arg)         
{   
    uint_8 ep_count;    
    USB_EP_STRUCT ep_struct;
    PHDC_STRUCT_PTR phdc_obj_ptr = (PHDC_STRUCT_PTR)arg;
    
    if (phdc_obj_ptr == NULL)
    {
        #if _DEBUG
            printf("USB_Class_PHDC_Event:phdc_object_ptr is NULL\n");
        #endif  
        return;
    }
    /* if enum is complete initialize non-control endpoints */
    if(event == USB_APP_ENUM_COMPLETE) 
    {
        /* initialize all recieve endpoints */
        for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_rx; ep_count++)
        {                         
            uint_8 component = (uint_8)(phdc_obj_ptr->ep_data.ep_rx[ep_count].endpoint | 
                (USB_RECV << COMPONENT_PREPARE_SHIFT));
            
            /* initialize ep_struct */
            ep_struct.ep_num = phdc_obj_ptr->ep_data.ep_rx[ep_count].endpoint;
            ep_struct.size = phdc_obj_ptr->ep_data.ep_rx[ep_count].size;
            ep_struct.type = phdc_obj_ptr->ep_data.ep_rx[ep_count].type;
            ep_struct.direction = USB_RECV;             
            
            /* intialize endpoint */
            (void)_usb_device_init_endpoint(phdc_obj_ptr->controller_handle,
             &ep_struct,TRUE);
            
            phdc_obj_ptr->service_buff_ptr = (uint_8_ptr)USB_mem_alloc_zero(ep_struct.size);
            if (NULL == phdc_obj_ptr->service_buff_ptr)
            {
                #if _DEBUG
                    printf("USB_Class_PHDC_Event: Memalloc failed\n");
                #endif  
                return ;
            }
            
            /* set endpt status as idle in the device layer */
            (void)_usb_device_set_status(phdc_obj_ptr->controller_handle,
                (uint_8)(USB_STATUS_ENDPOINT |component), 
                (uint_16)USB_STATUS_IDLE);
            phdc_obj_ptr->ep_data.ep_rx[ep_count].buff_ptr = NULL;
            phdc_obj_ptr->ep_data.ep_rx[ep_count].buffer_size = 0;
        }
        
        /* initialize all transmit endpoints */
        for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_tx; ep_count++)
        {                
            uint_8 component = (uint_8)(phdc_obj_ptr->ep_data.ep_tx[ep_count].endpoint | 
                (USB_SEND << COMPONENT_PREPARE_SHIFT));

            /* initialize ep_struct */
            ep_struct.ep_num = phdc_obj_ptr->ep_data.ep_tx[ep_count].endpoint;
            ep_struct.size = phdc_obj_ptr->ep_data.ep_tx[ep_count].size;
            ep_struct.type = phdc_obj_ptr->ep_data.ep_tx[ep_count].type;
            ep_struct.direction = USB_SEND;             
            
            /* intialize endpoint */
            (void)_usb_device_init_endpoint(phdc_obj_ptr->controller_handle,
             &ep_struct, TRUE);
            
            /* set endpt status as idle in the device layer */
            (void)_usb_device_set_status(phdc_obj_ptr->controller_handle,
                (uint_8)(USB_STATUS_ENDPOINT |component), 
                (uint_16)USB_STATUS_IDLE);
        }
    }     
    else if(event == USB_APP_BUS_RESET) 
    {            
        /* initialize producer and consumer to zero for transmit endpoints */
        for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_tx; ep_count++)   
        {                                                                                        
            phdc_obj_ptr->ep_data.ep_tx[ep_count].bin_consumer = (uint_8)0x00;         
            phdc_obj_ptr->ep_data.ep_tx[ep_count].bin_producer = (uint_8)0x00;                                                                                              
        }
    }            
    
    if(phdc_obj_ptr->phdc_callback.callback != NULL) 
    {
        phdc_obj_ptr->phdc_callback.callback(event,
            val,phdc_obj_ptr->phdc_callback.arg);
    }   
}

/**************************************************************************//*!
 *
 * @name  USB_PHDC_Other_Requests
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param handle           
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned                   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 * The funtion provides flexibilty to add class and vendor specific requests
 *****************************************************************************/  
static uint_8 USB_PHDC_Other_Requests
(
    USB_SETUP_STRUCT * setup_packet,/* [IN] setup packet recieved */
    uint_8_ptr *data,/* [OUT] data to be send back */
    uint_32 *size,   /* [OUT] size to be returned */
    pointer arg
) 
{
    uint_8 error = USBERR_INVALID_REQ_TYPE;
    PHDC_STRUCT_PTR phdc_obj_ptr = (PHDC_STRUCT_PTR)arg;
    
    if (phdc_obj_ptr == NULL)
    {
        #if _DEBUG
            printf("USB_PHDC_Other_Requests:phdc_object_ptr is NULL\n");
        #endif  
        return error;
    }
    if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
        USB_REQUEST_CLASS_CLASS) 
    {   /*class request so handle it here */        
        *size = 0;
        error = USB_OK;
        
        switch(setup_packet->request) 
        {
            case SET_FEATURE_REQUEST:
            case CLEAR_FEATURE_REQUEST: 
            {
                #if USB_METADATA_SUPPORTED
                    /* set/clear meta data feature */ 
                    phdc_obj_ptr->phdc_metadata = (boolean)((setup_packet->request & 
                        USB_SET_REQUEST_MASK) >> 1);                            
                    /* inform the application that feature has changed */
                    if (phdc_obj_ptr->phdc_callback.callback != NULL)
                      phdc_obj_ptr->phdc_callback.callback(USB_APP_FEATURE_CHANGED,
                      (void*)(&phdc_obj_ptr->phdc_metadata),
                      phdc_obj_ptr->phdc_callback.arg);
                #endif                       
                break;
            }
            case GET_STATUS_REQUEST: 
            {
                /*implement get status request to get which endpoint has data*/
                *data = (uint_8_ptr)(&phdc_obj_ptr->phdc_ep_has_data);
                *size = setup_packet->length; 
                break;
            }
        }
    }
    else if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
        USB_REQUEST_CLASS_VENDOR) 
    {    /* vendor specific request  */    
        if(phdc_obj_ptr->vendor_callback.callback != NULL) 
        {
            error = phdc_obj_ptr->vendor_callback.callback(setup_packet,data,
            size,phdc_obj_ptr->vendor_callback.arg);
        }
    }    
    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_PHDC_Endpoint_Service
 *
 * @brief Called upon a completed endpoint (non-control) transfer 
 *
 * @param event :  Pointer to the event structure
 * 
 * @return  None
 *****************************************************************************
 * This function is called when a transfer completes on a non control endpoint
 *****************************************************************************/  
void USB_PHDC_Endpoint_Service(PTR_USB_EVENT_STRUCT event,pointer arg) 
{/* Body*/
    uint_8 index;
    uint_8 meta_data_packet;
    uint_8 transfers_left;
    uint_8 producer, consumer;    
    USB_APP_EVENT_SEND_COMPLETE event_send_complete; 
    USB_APP_EVENT_DATA_RECIEVED event_data_recieved;
    #if USB_METADATA_SUPPORTED   
        USB_APP_EVENT_METADATA_PARAMS metadata_params;                                                     
    #endif    
    USB_CLASS_PHDC_QOS_BIN qos_bin;
    PHDC_STRUCT_PTR phdc_obj_ptr = (PHDC_STRUCT_PTR)arg;

    if(event->direction == USB_SEND) 
    {        
        /* get the index for the corressponding endpoint(channel) */
        for(index = 0; index < PHDC_TX_ENDPOINTS; index++) 
        {
            if(phdc_obj_ptr->ep_data.ep_tx[index].endpoint == event->ep_num) 
            break;
        }   
        
        /* initialize producer with the num of queued transfers */
        producer = phdc_obj_ptr->ep_data.ep_tx[index].bin_producer;
        /* initialize consumer with the num of de-queued transfers */
        consumer = phdc_obj_ptr->ep_data.ep_tx[index].bin_consumer;        
         
        if(phdc_obj_ptr->ep_data.ep_tx[index].
              qos_bin[consumer % MAX_QOS_BIN_ELEMS].meta_data == FALSE) 
        {/* if the previous packet sent was a meta data do not 
            decrement the transfers_left else decrement */
            phdc_obj_ptr->ep_data.ep_tx[index].transfers_left--;     
        }            
          
        /* de-queue the queue */
        phdc_obj_ptr->ep_data.ep_tx[index].bin_consumer++; 
        
        consumer = phdc_obj_ptr->ep_data.ep_tx[index].bin_consumer;
        
        /* get the qos information of the next transfer */                    
        qos_bin = phdc_obj_ptr->ep_data.ep_tx[index].
            qos_bin[consumer % MAX_QOS_BIN_ELEMS];
                     
        #if USB_METADATA_SUPPORTED   
            /* if transfers left is non zero and the next packet to send 
               is a meta data, discard the meta data packet */
            if(phdc_obj_ptr->ep_data.ep_tx[index].transfers_left != 0) 
            {
                /* discard all the meta data packets if any */
                while(qos_bin.meta_data == TRUE) 
                {
                    /* de-queue the queue-- discarding meta data packet */
                    consumer = 
                        ++phdc_obj_ptr->ep_data.ep_tx[index].bin_consumer;
                
                    if(consumer == producer)
                    break; /* queue is empty */
                    
                    /* set qos_bin for next packet in the queue */
                    qos_bin = phdc_obj_ptr->ep_data.ep_tx[index].
                        qos_bin[consumer % MAX_QOS_BIN_ELEMS];                
                }
            }        
        #endif  
 
        if(consumer != producer) 
        {/*if bin is not empty */                                    
            #if USB_METADATA_SUPPORTED   
                if(qos_bin.meta_data == TRUE) 
                {
                    /* initialize transfers left if the packet is a meta data */
                    phdc_obj_ptr->ep_data.ep_tx[index].transfers_left = 
                        qos_bin.num_tfr;
                    /* initialize current_qos of the transfers that follow the 
                       meta data packet */                                                          
                    phdc_obj_ptr->ep_data.ep_tx[index].current_qos = 
                        qos_bin.qos;                                                                
                }            
            #endif   
            /* send data */
            (void)USB_Class_Send_Data(phdc_obj_ptr->class_handle, qos_bin.channel, 
                qos_bin.app_buff, qos_bin.size);                                                                                                
        } 
        else /* bin is empty */
        {
            /*set endpoint bin as non active */
            phdc_obj_ptr->phdc_ep_has_data &= ~(1<<event->ep_num);
        }

        /* Set the USB_APP_EVENT_SEND_DATA structure */
        event_send_complete.qos = phdc_obj_ptr->ep_data.ep_tx[index].qos;
        event_send_complete.buffer_ptr = event->buffer_ptr;
        event_send_complete.size = event->len;
        
        /* notify the application of the send complete */
        phdc_obj_ptr->phdc_callback.callback(USB_APP_SEND_COMPLETE, 
            (void*)(&event_send_complete),phdc_obj_ptr->phdc_callback.arg);                   
    } 
    else /* direction is USB_RECV */
    {
        USB_CLASS_PHDC_RX_BUFF rx_buff;
        if(!event->len)
        {/* indicates there was call of zero byte recv */
            return; 
        }

        /* get the index for the corressponding endpoint */
        for(index = 0; index < PHDC_RX_ENDPOINTS; index++) 
        {
            if(phdc_obj_ptr->ep_data.ep_rx[index].endpoint == event->ep_num) 
            break;
        }
       
        if(phdc_obj_ptr->ep_data.ep_rx[index].buff_ptr == NULL) 
        {
            /* First Call will have buff_ptr == NULL */
            rx_buff.in_buff = event->buffer_ptr;
            rx_buff.in_size = event->len;
            rx_buff.out_size = 0;
            rx_buff.out_buff = NULL;   
            phdc_obj_ptr->phdc_callback.callback(USB_APP_GET_DATA_BUFF, 
                (void*)(&rx_buff),phdc_obj_ptr->phdc_callback.arg);                        

            phdc_obj_ptr->ep_data.ep_rx[index].buffer_size = rx_buff.out_size;        
            phdc_obj_ptr->ep_data.ep_rx[index].buff_ptr = rx_buff.out_buff;        
        
            if(event->len == rx_buff.out_size) 
            {
                /* Recieved Complete packet first time itself */ 
                USB_mem_copy(event->buffer_ptr,rx_buff.out_buff,
                    rx_buff.out_size);
                event->buffer_ptr = rx_buff.out_buff;
            }
            else 
            {            
                /* Some data is still pending to be recieved
                   copy data to app buffer and schedule next transfer */
                (void)USB_Class_PHDC_Recv_Data(phdc_obj_ptr->phdc_handle,
                    phdc_obj_ptr->ep_data.ep_rx[index].qos,
                    rx_buff.out_buff,
                    phdc_obj_ptr->ep_data.ep_rx[index].buffer_size);
                return;
            }
        }
        
        if(event->len == phdc_obj_ptr->ep_data.ep_rx[index].buffer_size) 
        {        
            #if USB_METADATA_SUPPORTED   
                transfers_left = phdc_obj_ptr->ep_data.ep_rx[index].
                    transfers_left;
                /*compare the recieved signature with the string for preamble 
                  verifiability. if meta_data_packet = 0(both signatures match) 
                  the incoming packet is a meta data */
                meta_data_packet = (uint_8)strncmp(
                    phdc_obj_ptr->meta_data_msg_preamble.signature, 
                    msg_preamble_signature, METADATA_PREAMBLE_SIGNATURE);
                                                                                                                          
                /*check whether transfers are left. we check for meta data only
                  when number of transfers left is zero */
                if((phdc_obj_ptr->phdc_metadata == FALSE) || (transfers_left != 0 && 
                    meta_data_packet !=0)) 
                {
                    phdc_obj_ptr->ep_data.ep_rx[index].transfers_left = 
                        (uint_8)(transfers_left - 1);          
                    /* set the data recieved structure */                                                                 
                    event_data_recieved.qos =
                        phdc_obj_ptr->ep_data.ep_rx[index].qos;
                    event_data_recieved.buffer_ptr = event->buffer_ptr;
                    event_data_recieved.size = event->len;
                
                    /* notify the application that recieve data is complete */
                    phdc_obj_ptr->phdc_callback.callback(USB_APP_DATA_RECEIVED, 
                        (void*)(&event_data_recieved),phdc_obj_ptr->phdc_callback.arg);           
                }
                else if((transfers_left == 0 ) && (meta_data_packet == 0))
                {/*if number of transfers left is zero and the packet is meta 
                   data msg preamble initialize the endpoint data structure 
                   from the meta data msg preamble data structure */                   
                    phdc_obj_ptr->ep_data.ep_rx[index].transfers_left = 
                        phdc_obj_ptr->meta_data_msg_preamble.num_tfr;
                    phdc_obj_ptr->ep_data.ep_rx[index].current_qos = 
                        phdc_obj_ptr->meta_data_msg_preamble.qos;                
                    /* set the event phdc meta data params structure*/
                    metadata_params.channel = event->ep_num;
                    metadata_params.num_tfr =
                    phdc_obj_ptr->meta_data_msg_preamble.num_tfr;
                    metadata_params.qos = phdc_obj_ptr->meta_data_msg_preamble.qos;                                                     
                    metadata_params.metadata_ptr = 
                        &phdc_obj_ptr->meta_data_msg_preamble.opaque_data[0];
                
                    /*notify the appl that meta data params has changed*/
                    phdc_obj_ptr->phdc_callback.callback(USB_APP_META_DATA_PARAMS_CHANGED, 
                        (void*)(&metadata_params),phdc_obj_ptr->phdc_callback.arg);                                                     
                }             
            #else
                /* set the data recieved structure */                                                                 
                event_data_recieved.qos =phdc_obj_ptr->ep_data.ep_rx[index].qos;
                event_data_recieved.buffer_ptr = event->buffer_ptr;
                event_data_recieved.size = event->len;
                
                /* notify the application that recieve data is complete */
                phdc_obj_ptr->phdc_callback.callback(USB_APP_DATA_RECEIVED, 
                (void*)(&event_data_recieved),phdc_obj_ptr->phdc_callback.arg);
            #endif     
            /* when complete packet is recieved 
               reset the buffer_size and buff_ptr */
            phdc_obj_ptr->ep_data.ep_rx[index].buffer_size = 0;        
            phdc_obj_ptr->ep_data.ep_rx[index].buff_ptr = NULL;  
            phdc_obj_ptr->ep_data.ep_rx[index].buff_ptr = NULL;            
        }/* Endif */           
    }/* Endif */                                                                     
}/* EndBody*/

/*****************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Class_PHDC_Send_Data
 *
 * @brief This fucntion is used by Application to send data through PHDC class
 *
 * @param handle          :   handle returned by USB_Class_PHDC_Init
 * @param meta_data       :   packet is meta data or not
 * @param num_tfr         :   no. of transfers
 * @param qos             :   current qos of the transfer
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 * This fucntion is used by Application to send data through PHDC class 
 *****************************************************************************/  
uint_8 USB_Class_PHDC_Send_Data
(
    PHDC_HANDLE handle, 
    boolean meta_data,    /* [IN] packet is meta data or not */
    uint_8 num_tfr,       /* [IN] no. of transfers */
    uint_8 qos,           /* [IN] current qos of the transfer */
    uint_8_ptr app_buff,      /* [IN] buffer to send */
    uint_32 size   /* [IN] length of the transfer */
) 
{
    uint_8 channel;
    uint_8 producer, consumer;
    uint_8 tx_index; 
    PHDC_STRUCT_PTR phdc_obj_ptr;
    uint_8 error = USB_OK; 
    static uint_32 cnt=0;
    
    cnt++;
    
    phdc_obj_ptr =   USB_Phdc_Get_Device_Ptr(handle);
    if (NULL == phdc_obj_ptr)
    {
        return USBERR_ERROR;
    }
        
    
    /* get the index for the corressponding endpoint(channel) to send data
       of desired qos */
    for(tx_index = 0; tx_index < PHDC_TX_ENDPOINTS; tx_index++) 
    {
        if(phdc_obj_ptr->ep_data.ep_tx[tx_index].qos == qos) 
            break;
    }
    
    if(tx_index == PHDC_TX_ENDPOINTS) 
    {
        return USBERR_TX_FAILED;
    }    
    
    #if USB_METADATA_SUPPORTED   
        /* if the packet to send is not as desired return with an error */
        if((((phdc_obj_ptr->ep_data.ep_tx[tx_index].transfers_left == 0) || 
            (phdc_obj_ptr->ep_data.ep_tx[tx_index].type != USB_BULK_PIPE)) &&
            (meta_data == FALSE) && (phdc_obj_ptr->phdc_metadata == TRUE)) || 
            ((phdc_obj_ptr->phdc_metadata == FALSE) && (meta_data == TRUE)))            
        {
            return USBERR_TX_FAILED;
        }
    #endif
    
    channel = phdc_obj_ptr->ep_data.ep_tx[tx_index].endpoint;
    /*set channel active. Set bit map for the corressponding channel(endp)*/
    phdc_obj_ptr->phdc_ep_has_data |= 1 << channel; 
    
    /* initialize producer with the num of queued transfers */
    producer = phdc_obj_ptr->ep_data.ep_tx[tx_index].bin_producer;
    /* initialize consumer with the num of de-queued transfers */
    consumer = phdc_obj_ptr->ep_data.ep_tx[tx_index].bin_consumer;
    
    if((uint_8)(producer - consumer) != (uint_8)(MAX_QOS_BIN_ELEMS))  
    {/* the bin is not full*/    
        uint_8 queue_num = (uint_8)(producer % MAX_QOS_BIN_ELEMS);
        
        /* put all send request parameters in the endpoint data structure */
        phdc_obj_ptr->ep_data.ep_tx[tx_index].qos_bin[queue_num].channel = 
            channel;
        phdc_obj_ptr->ep_data.ep_tx[tx_index].qos_bin[queue_num].meta_data = 
            meta_data;
        phdc_obj_ptr->ep_data.ep_tx[tx_index].qos_bin[queue_num].num_tfr = 
            num_tfr;
        phdc_obj_ptr->ep_data.ep_tx[tx_index].qos_bin[queue_num].qos = qos;
        phdc_obj_ptr->ep_data.ep_tx[tx_index].qos_bin[queue_num].app_buff = 
            app_buff;
        phdc_obj_ptr->ep_data.ep_tx[tx_index].qos_bin[queue_num].size = size;
        
        /* increment producer bin by 1 -- queue the transfer */       
        phdc_obj_ptr->ep_data.ep_tx[tx_index].bin_producer = ++producer;
                
        if((uint_8)(producer - consumer) == (uint_8)1) 
        {/* bin has only this packet to send */                               
            #if USB_METADATA_SUPPORTED   
                /* discard the packet if the packet is a meta data and num of 
                   transfers is not equal to zero */
                if( (meta_data == TRUE) && 
                    (phdc_obj_ptr->ep_data.ep_tx[tx_index].transfers_left != 0))
                {/* notify the application of the error*/
                    phdc_obj_ptr->phdc_callback.callback(USB_APP_ERROR,NULL,
                    phdc_obj_ptr->phdc_callback.arg);
                        return USBERR_TX_FAILED;                
                } 
                else if(meta_data == TRUE) 
                {
                    /* initialize transfers left if the packet is a meta data */
                    phdc_obj_ptr->ep_data.ep_tx[tx_index].transfers_left = 
                        num_tfr;                            
                    /* initialize current_qos of the transfers that follow the 
                       meta data packet */  
                    phdc_obj_ptr->ep_data.ep_tx[tx_index].current_qos = qos;
                }          
            #endif    
            /* send the packet if there is no packet (other than this packet) 
               in the queue */
            error = USB_Class_Send_Data(phdc_obj_ptr->class_handle,channel, 
            app_buff,size);
        }        
    }
    else /* bin is full */
    {
        /* return device is busy when the queue is full */
        error = USBERR_DEVICE_BUSY; 
    }    
    _int_enable();     
    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_Class_PHDC_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param  phdc_config_ptr[IN]  : Phdc configuration structure pointer
 * @return PHDC_HANDLE      : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 * This function initializes the PHDC Class layer and layers it is dependednt on 
 *****************************************************************************/                          
PHDC_HANDLE USB_Class_PHDC_Init
(
    PHDC_CONFIG_STRUCT_PTR phdc_config_ptr /*[IN]*/
)
{
    uint_8 ep_count, count=0;
    uint_8 error;    
    PHDC_HANDLE phdc_handle;
    PHDC_STRUCT_PTR devicePtr = NULL;
    USB_ENDPOINTS *info;  
    
    if (NULL == (void *)phdc_config_ptr)
        return USBERR_ERROR;
    
    devicePtr = (PHDC_STRUCT_PTR)USB_mem_alloc_zero(sizeof(PHDC_STRUCT));
    if (NULL == devicePtr)
    {
        #if _DEBUG
            printf("USB_Class_PHDC_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }
    
    phdc_handle = USB_Phdc_Allocate_Handle();
    if (USBERR_DEVICE_BUSY == phdc_handle) 
    {
        USB_mem_free(devicePtr);
        devicePtr = NULL;
        return USBERR_INIT_FAILED;
    }

        /* initialize the Global Variable Structure */
    USB_mem_zero(devicePtr, sizeof(PHDC_STRUCT));

    
    /* get the endpoint info from the descriptor module */
    info = phdc_config_ptr->info;

    /* initialize the device */
    error = _usb_device_init(USBCFG_DEFAULT_DEVICE_CONTROLLER,
        (_usb_device_handle *)&devicePtr->controller_handle,(uint_8)((info->count) + 1));
    if(error != USB_OK)
    {
      goto error1;  
    }
    
    phdc_config_ptr->desc_callback_ptr->handle = phdc_handle;    
    devicePtr->phdc_ep_has_data = 0; /* no endpoint has data */
    devicePtr->phdc_callback.callback = phdc_config_ptr->phdc_callback.callback;
    devicePtr->phdc_callback.arg = phdc_config_ptr->phdc_callback.arg;
    devicePtr->vendor_callback.callback = phdc_config_ptr->vendor_callback.callback;                                
    devicePtr->vendor_callback.arg = phdc_config_ptr->vendor_callback.arg;
    devicePtr->ep_data.count_rx = 0;
    devicePtr->ep_data.count_tx = 0;
    devicePtr->ep_data.handle = devicePtr->controller_handle;
    devicePtr->service_buff_ptr = NULL;
    devicePtr->class_handle = USB_Class_Init(devicePtr->controller_handle, 
        USB_Class_PHDC_Event,USB_PHDC_Other_Requests,(void *)devicePtr,
        phdc_config_ptr->desc_callback_ptr);
 
    /* initialize endpoint data structure for all endpoints */
    for(ep_count = 0; ep_count < info->count; ep_count++)   
    { 
        if((info->ep[ep_count].direction == USB_RECV) & 
                (devicePtr->ep_data.count_rx < PHDC_RX_ENDPOINTS))
        {                
            count= devicePtr->ep_data.count_rx;
                    
            /* initialize endpoint data structure for recv endpoint */
            devicePtr->ep_data.ep_rx[count].endpoint = 
                    info->ep[ep_count].ep_num;
            devicePtr->ep_data.ep_rx[count].type = 
                    info->ep[ep_count].type;  
            devicePtr->ep_data.ep_rx[count].size = 
                    info->ep[ep_count].size;                                            
            devicePtr->ep_data.ep_rx[count].qos = (
                    info->ep[ep_count].type == USB_INTERRUPT_PIPE ? PHDC_INT_IN_QOS : PHDC_BULK_IN_QOS);
            devicePtr->ep_data.ep_rx[count].current_qos = 
                    INVALID_VAL;                    
            /* register endpoint service on the endpoint*/
            (void)_usb_device_register_service(devicePtr->controller_handle, 
                    devicePtr->ep_data.ep_rx[count].endpoint, 
            USB_PHDC_Endpoint_Service,(void *)devicePtr);                                                                                 
            /* increment count_rx by 1 */
            devicePtr->ep_data.count_rx++;                               
         } 
          else if((info->ep[ep_count].direction == USB_SEND) & 
                (devicePtr->ep_data.count_tx < PHDC_TX_ENDPOINTS))                   
          {                
              count= devicePtr->ep_data.count_tx;                    
              /* initialize endpoint data structure for send endpoint */
              devicePtr->ep_data.ep_tx[count].endpoint =
                    (uint_8)info->ep[ep_count].ep_num;
              devicePtr->ep_data.ep_tx[count].type = 
                    (uint_8)info->ep[ep_count].type;        
              devicePtr->ep_data.ep_tx[count].size = 
                    (uint_32)info->ep[ep_count].size;                                                                
              devicePtr->ep_data.ep_tx[count].qos = (
                    info->ep[ep_count].type == USB_INTERRUPT_PIPE ? PHDC_INT_OUT_QOS : PHDC_BULK_OUT_QOS);
              devicePtr->ep_data.ep_tx[count].current_qos = 
                    (uint_8)INVALID_VAL;
              devicePtr->ep_data.ep_tx[count].bin_consumer = 
                    (uint_8)0x00;         
              devicePtr->ep_data.ep_tx[count].bin_producer = 
                    (uint_8)0x00;                                                                              
              /* register endpoint service on the endpoint*/
              (void)_usb_device_register_service(devicePtr->controller_handle, 
                devicePtr->ep_data.ep_tx[devicePtr->ep_data.count_tx].
                        endpoint, USB_PHDC_Endpoint_Service,(void *)devicePtr);                   
               /* increment count_tx by 1 */
               devicePtr->ep_data.count_tx++;            
          }
    }
            /* set device state as powered */
    (void)_usb_device_set_status(devicePtr->controller_handle,
        (uint_8)USB_STATUS_DEVICE_STATE,
        (uint_16)USB_STATE_POWERED);
    
    #if USB_METADATA_SUPPORTED   
      devicePtr->phdc_metadata = FALSE; /* metadata feature disabled */
    #endif
    phdc_object_array[phdc_handle] = devicePtr;        
    return phdc_handle;
    
 error2:
  /* Implement Denit class and invoke here*/    
 error1: 
     USB_Phdc_Free_Handle(phdc_handle);
     USB_mem_free(devicePtr);
     devicePtr = NULL;
    return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Class_PHDC_Recv_Data
 *
 * @brief This fucntion is used by Application to receive data through PHDC class
 *
 * @param phdc_handle     :   Handle returned by USB_Class_PHDC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 * This fucntion is used by Application to send data through PHDC class 
 *****************************************************************************/  
uint_8 USB_Class_PHDC_Recv_Data
(
    PHDC_HANDLE         phdc_handle,
    uint_8              qos,           /* [IN] Qos of the transfer */   
    uint_8_ptr          buff_ptr,      /* [IN] buffer to recv */      
    uint_32             size           /* [IN] length of the transfer */
)
{
    PHDC_STRUCT_PTR phdc_obj_ptr;
    uint_8 rx_index;
    uint_8 status = USB_OK;
    USB_CLASS_PHDC_RX_ENDPOINT *phdc_rx_endpoint;

    phdc_obj_ptr = USB_Phdc_Get_Device_Ptr(phdc_handle);
    if (NULL == phdc_obj_ptr)
    {
        return USBERR_ERROR;
    }

    /* get the index for the corressponding endpoint(channel) to receive data
     of desired qos */
    for(rx_index = 0; rx_index < PHDC_RX_ENDPOINTS; rx_index++)
    {
        if((phdc_obj_ptr->ep_data.ep_rx[rx_index].qos & qos) !=0)
            break;
    }

    /* no channel supports the desired qos */
    if(rx_index == PHDC_RX_ENDPOINTS)
    {
        return USBERR_RX_FAILED;
    }

    status = _usb_device_recv_data(phdc_obj_ptr->controller_handle,
        phdc_obj_ptr->ep_data.ep_rx[rx_index].endpoint,buff_ptr,size);
    
   return status;   
}

#endif /*PHDC_CONFIG*/
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb_dcd/usb_dcd.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_dcd.h$
* $Version : 3.8.1.0$
* $Date    : Jul-27-2011$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the USB DCD I/O functions.
*
*END************************************************************************/

#ifndef _usb_dcd_h_
#define _usb_dcd_h_ 1

#include <ioctl.h>


/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/* 
** USB DCD Sequence 
*/
enum 
{
   VBUS_DETECTION = 0,
   USB_DCD_ACTIVE = 1,
   USB_DCD_SEQ_STAT0 = 2,
   USB_DCD_SEQ_STAT1 = 3,
   USB_DCD_SEQ_RES0 = 4,
   USB_DCD_SEQ_RES1 = 5,
   USB_DCD_ISR_SIGNAL = 6,
   USB_DCD_TO = 7,
   USB_DCD_ERR = 8 ,
   USB_DCD_DEBUG = 9
};

/* 
** USB Charger Type 
*/
enum
{
	 STANDARD_HOST = 1,
	 CHARGING_HOST = 2,
	 DEDICATED_CHARGER = 3	
};

/* 
** USB DCD state  
*/
enum
{
	 USB_DCD_DISABLE = 0,
	 USB_DCD_ENABLE,
	 USB_DCD_SEQ_COMPLETE	 
};

/* 
** USB DCD METHOD
*/
enum
{
	 USB_DCD_POLLED = 0,
	 USB_DCD_INT
};

/* 
** USB DCD Registers reset value 
*/
#define USBDCD_CLOCK_SPEED_RESET_VALUE    (48000) /* 48 Mhz*/
#define USBDCD_TSEQ_INIT_RESET_VALUE      (0x10)
#define USB_DCD_TDCD_DBNC_RESET_VALUE		(0x0A)
#define USB_DCD_TVDPSRC_ON_RESET_VALUE		(0x28)
#define USB_DCD_TVDPSRC_CON_RESET_VALUE	(0x28)
#define USB_DCD_CHECK_DM_RESET_VALUE		(0x01)
#define USB_DCD_LEVEL_RESET_VALUE			(1)

/* 
** IOCTL calls specific to USB_DC 
*/
#define IO_IOCTL_USB_DCD_SET_TSEQ_INIT                _IO(IO_TYPE_USB_DCD,0x01)
#define IO_IOCTL_USB_DCD_GET_TSEQ_INIT                _IO(IO_TYPE_USB_DCD,0x02)
#define IO_IOCTL_USB_DCD_GET_TUNITCON                 _IO(IO_TYPE_USB_DCD,0x03)
#define IO_IOCTL_USB_DCD_SET_TDCD_DBNC                _IO(IO_TYPE_USB_DCD,0x04)
#define IO_IOCTL_USB_DCD_GET_TDCD_DBNC                _IO(IO_TYPE_USB_DCD,0x05)
#define IO_IOCTL_USB_DCD_SET_TVDPSRC_ON					_IO(IO_TYPE_USB_DCD,0x06)
#define IO_IOCTL_USB_DCD_GET_TVDPSRC_ON					_IO(IO_TYPE_USB_DCD,0x07)
#define IO_IOCTL_USB_DCD_SET_TVDPSRC_CON					_IO(IO_TYPE_USB_DCD,0x08)	
#define IO_IOCTL_USB_DCD_GET_TVDPSRC_CON					_IO(IO_TYPE_USB_DCD,0x09)
#define IO_IOCTL_USB_DCD_SET_CHECK_DM   					_IO(IO_TYPE_USB_DCD,0x0A)
#define IO_IOCTL_USB_DCD_GET_CHECK_DM   					_IO(IO_TYPE_USB_DCD,0x0B)
#define IO_IOCTL_USB_DCD_SET_CLOCK_SPEED     			_IO(IO_TYPE_USB_DCD,0x0C)
#define IO_IOCTL_USB_DCD_GET_CLOCK_SPEED     			_IO(IO_TYPE_USB_DCD,0x0D)
#define IO_IOCTL_USB_DCD_GET_STATUS				  			_IO(IO_TYPE_USB_DCD,0x0E)
#define IO_IOCTL_USB_DCD_RESET    				  			_IO(IO_TYPE_USB_DCD,0x0F)
#define IO_IOCTL_USB_DCD_START    				  			_IO(IO_TYPE_USB_DCD,0x10)
#define IO_IOCTL_USB_DCD_GET_STATE  			  			_IO(IO_TYPE_USB_DCD,0x11)
#define IO_IOCTL_USB_DCD_GET_CHARGER_TYPE				   _IO(IO_TYPE_USB_DCD,0x12)  


/* 
** USB DCD ERROR CODE
*/

#define USB_DCD_OK												0x00
#define USB_DCD_ERROR_CHANNEL_INVALID  					0x01
#define USB_DCD_INIT_INVALID									0x02
#define USB_DCD_CLOCK_SPEED_INVALID							0x03
#define USB_DCD_ERROR_INVALID_PARAMETER					0x04
#define USB_DCD_ERROR_INVALID_CMD							0x05
#define USB_DCD_ERROR_INVALID_INT_VECTOR  				0x06

/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_uint _io_usb_dcd_polled_install(
      char_ptr,
      _mqx_uint (_CODE_PTR_)(pointer, pointer _PTR_, char_ptr),
      _mqx_uint (_CODE_PTR_)(pointer, pointer),
      _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
      _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
      _mqx_int (_CODE_PTR_)(pointer, _mqx_uint, _mqx_uint_ptr),
      pointer);

extern _mqx_uint _io_usb_dcd_int_install(
      char_ptr,
      _mqx_uint (_CODE_PTR_)(pointer, char_ptr),
      _mqx_uint (_CODE_PTR_)(pointer, pointer),
      _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
      _mqx_int (_CODE_PTR_)(pointer, char_ptr, _mqx_int),
      _mqx_int (_CODE_PTR_)(pointer, _mqx_uint, _mqx_uint_ptr),
      pointer);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/taskq.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: taskq.c$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains the function for creating a task queue.
 *
 *END************************************************************************/

#include "mqx_inc.h"

/*!
 * \brief Creates a task queue for use.
 * 
 * A task can use the task queue to suspend and resume tasks.
 * 
 * \param[in] policy Queuing policy, one of the following:
 * \li MQX_TASK_QUEUE_BY_PRIORITY
 * \li MQX_TASK_QUEUE_FIFO
 * 
 * \return Pointer to the task queue (Success.)
 * \return NULL (Failure.)
 * 
 * \warning Cannot be called from an ISR.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li Error from _mem_alloc_system() (MQX cannot allocate memory for the task 
 * queue.)
 * \li MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \li MQX_INVALID_PARAMETER (Policy is not one of the allowed policies.)
 * 
 * \see _taskq_destroy
 * \see _taskq_resume
 * \see _taskq_suspend
 * \see _task_set_error      
 */ 
pointer _taskq_create
(
    _mqx_uint policy
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TASK_QUEUE_STRUCT_PTR task_queue_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_taskq_create, policy);

#if MQX_CHECK_ERRORS
    if (! ((policy == MQX_TASK_QUEUE_FIFO) ||
                                    (policy == MQX_TASK_QUEUE_BY_PRIORITY)))
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_taskq_create, NULL);
        return (NULL);
    } /* Endif */
    if (kernel_data->IN_ISR) {
        _task_set_error(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        _KLOGX2(KLOG_taskq_create, NULL);
        return(NULL);
    }/* Endif */
#endif

    task_queue_ptr = (TASK_QUEUE_STRUCT_PTR) _mem_alloc_system((_mem_size) sizeof(TASK_QUEUE_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (task_queue_ptr == NULL) {
        _KLOGX2(KLOG_taskq_create, NULL);
        return(NULL);
    } /* Endif */
#endif

    _mem_set_type(task_queue_ptr, MEM_TYPE_TASK_Q);

    task_queue_ptr->POLICY = policy;
    _QUEUE_INIT(&task_queue_ptr->TD_QUEUE, 0);
    task_queue_ptr->VALID = TASK_QUEUE_VALID;
    _int_disable();
    if (kernel_data->KERNEL_TASK_QUEUES.NEXT == NULL) {
        /* Initialize the task queue */
        _QUEUE_INIT(&kernel_data->KERNEL_TASK_QUEUES, 0);

    } /* Endif */
    _QUEUE_ENQUEUE(&kernel_data->KERNEL_TASK_QUEUES, task_queue_ptr);
    _int_enable();

    _KLOGX2(KLOG_taskq_create, task_queue_ptr);

    return (task_queue_ptr);

} /* Endbody */

/*!
 * \brief Destroys the task queue.
 * 
 * The function removes all tasks from the task queue, puts them in their ready 
 * queues, and frees the task queue.
 * 
 * \param[in] users_task_queue_ptr Pointer to the task queue to destroy; 
 * returned by _taskq_create().
 * 
 * \return MQX_OK
 * \return MQX_INVALID_PARAMETER (Users_task_queue_ptr is NULL.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an 
 * ISR.)
 * \return MQX_INVALID_TASK_QUEUE (Task_queue_ptr does not point to a valid task 
 * queue.)
 * 
 * \warning Might put tasks in their ready queues.
 * \warning Cannot be called from an ISR.
 * 
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 * \see _taskq_resume
 * \see _taskq_suspend    
 */ 
_mqx_uint _taskq_destroy
(
    pointer users_task_queue_ptr
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TD_STRUCT_PTR td_ptr;
    register TASK_QUEUE_STRUCT_PTR task_queue_ptr = (TASK_QUEUE_STRUCT_PTR) users_task_queue_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_taskq_destroy, users_task_queue_ptr);

#if MQX_CHECK_ERRORS
    if (task_queue_ptr == NULL) {
        _int_enable();
        _KLOGX2(KLOG_taskq_destroy, MQX_INVALID_PARAMETER);
        return(MQX_INVALID_PARAMETER);
    } /* Endif */
    if (kernel_data->IN_ISR) {
        _KLOGX2(KLOG_taskq_destroy, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    }/* Endif */
#endif

    _int_disable();
#if MQX_CHECK_VALIDITY
    if (task_queue_ptr->VALID != TASK_QUEUE_VALID) {
        _int_enable();
        _KLOGX2(KLOG_taskq_destroy, MQX_INVALID_TASK_QUEUE);
        return(MQX_INVALID_TASK_QUEUE);
    } /* Endif */
#endif

    task_queue_ptr->VALID = 0;
    while (_QUEUE_GET_SIZE(&task_queue_ptr->TD_QUEUE)) {
        _QUEUE_DEQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
        _TASK_READY(td_ptr, kernel_data);
        _int_enable();
        _int_disable();
    } /* Endwhile */

    _QUEUE_REMOVE(&kernel_data->KERNEL_TASK_QUEUES, task_queue_ptr);

    _int_enable();

    _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */

    _mem_free(task_queue_ptr);

    _KLOGX2(KLOG_taskq_destroy, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Suspends the active task and put it in the specified task queue.
 * 
 * The function blocks the calling task and puts the task's task descriptor in 
 * the task queue.
 * 
 * \param[in] users_task_queue_ptr Pointer to the task queue returned by 
 * _taskq_create().
 * 
 * \return MQX_OK
 * \return MQX_INVALID_PARAMETER (Users_task_queue_ptr is NULL.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an 
 * ISR.)
 * \return MQX_INVALID_TASK_QUEUE (Task_queue_ptr does not point to a valid task
 * queue.)
 * 
 * \warning Blocks the calling task.
 * \warning Cannot be called from an ISR. 
 * 
 * \see _taskq_destroy
 * \see _taskq_create
 * \see _taskq_resume
 * \see _taskq_get_value      
 */ 
_mqx_uint _taskq_suspend
(
    pointer users_task_queue_ptr
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TD_STRUCT_PTR td_ptr;
    register TASK_QUEUE_STRUCT_PTR task_queue_ptr = (TASK_QUEUE_STRUCT_PTR) users_task_queue_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_taskq_suspend, users_task_queue_ptr);

#if MQX_CHECK_ERRORS
    if (task_queue_ptr == NULL) {
        _KLOGX2(KLOG_taskq_suspend, MQX_INVALID_PARAMETER);
        return(MQX_INVALID_PARAMETER);
    } /* Endif */
    if (kernel_data->IN_ISR) {
        _KLOGX2(KLOG_taskq_suspend, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    }/* Endif */
#endif

    td_ptr = kernel_data->ACTIVE_PTR;

    _INT_DISABLE();

#if MQX_CHECK_VALIDITY
    if (task_queue_ptr->VALID != TASK_QUEUE_VALID) {
        _int_enable();
        _KLOGX2(KLOG_taskq_suspend, MQX_INVALID_TASK_QUEUE);
        return(MQX_INVALID_TASK_QUEUE);
    } /* Endif */
#endif

    td_ptr->STATE = TASK_QUEUE_BLOCKED;
    _QUEUE_UNLINK(td_ptr); /* Remove task from ready to run queue */
    td_ptr->INFO = (_mqx_uint) & task_queue_ptr->TD_QUEUE;
    if (task_queue_ptr->POLICY & MQX_TASK_QUEUE_BY_PRIORITY) {
        _sched_insert_priorityq_internal(&task_queue_ptr->TD_QUEUE, td_ptr);
    }
    else {
        _QUEUE_ENQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
    } /* Endif */

    _sched_execute_scheduler_internal(); /* Let the other tasks run */

    _INT_ENABLE();

    _KLOGX2(KLOG_taskq_suspend, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Restarts the task that is suspended in the task queue.
 *  
 * The function removes the task or tasks from the task queue and puts them in 
 * their ready queues. MQX schedules the tasks based on their priority, 
 * regardless of the scheduling policy of the task queue.
 * 
 * \param[in] users_task_queue_ptr Pointer to the task queue returned by 
 * _taskq_create().
 * \param[in] all_tasks FALSE (Make the first task ready.), TRUE (Makes all tasks 
 * ready.)
 * 
 * \return MQX_OK
 * \return MQX_INVALID_TASK_QUEUE (Task_queue_ptr is NULL.)
 * \return MQX_TASK_QUEUE_EMPTY (Task queue is empty.)   
 */ 
_mqx_uint _taskq_resume
(
    pointer users_task_queue_ptr,
    boolean all_tasks
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TD_STRUCT_PTR td_ptr;
    register TASK_QUEUE_STRUCT_PTR task_queue_ptr = (TASK_QUEUE_STRUCT_PTR) users_task_queue_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_taskq_resume, users_task_queue_ptr, all_tasks);

#if MQX_CHECK_ERRORS
    if (task_queue_ptr == NULL) {
        _KLOGX2(KLOG_taskq_resume, MQX_INVALID_TASK_QUEUE);
        return(MQX_INVALID_TASK_QUEUE);
    } /* Endif */
#endif

    _INT_DISABLE();

#if MQX_CHECK_VALIDITY
    if (task_queue_ptr->VALID != TASK_QUEUE_VALID) {
        _int_enable();
        _KLOGX2(KLOG_taskq_resume, MQX_INVALID_TASK_QUEUE);
        return(MQX_INVALID_TASK_QUEUE);
    } /* Endif */
#endif

    if (_QUEUE_GET_SIZE(&task_queue_ptr->TD_QUEUE) == 0) {
        /* Task queue is empty */
        _int_enable();
        _KLOGX2(KLOG_taskq_resume, MQX_TASK_QUEUE_EMPTY);
        return (MQX_TASK_QUEUE_EMPTY);
    } /* Endif */

    if (all_tasks) {
        while (_QUEUE_GET_SIZE(&task_queue_ptr->TD_QUEUE)) {
            _QUEUE_DEQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
            _TASK_READY(td_ptr, kernel_data);
        } /* Endwhile */
    }
    else {
        _QUEUE_DEQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
        _TASK_READY(td_ptr, kernel_data);
    } /* Endif */

    _INT_ENABLE();

    _CHECK_RUN_SCHEDULER();/* Let higher priority task run */

    _KLOGX2(KLOG_taskq_resume, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Tests all task queues for correctness.
 * 
 * \param[out] task_queue_error_ptr Pointer to the task queue with an error 
 * (NULL if no error is found).
 * \param[out] td_error_ptr         Pointer to the task descriptor with an error 
 * (NULL if no error is found).
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an 
 * ISR.)
 * \return MQX_CORRUPT_QUEUE (A task on a task queue is not valid.) 
 * \return MQX_INVALID_TASK_QUEUE (A task queue is not valid.)
 * 
 * \warning Cannot be called from an ISR.
 * \warning Disables and enables interrupts.
 * 
 * \see _taskq_destroy
 * \see _taskq_create
 * \see _taskq_resume
 * \see _taskq_get_value    
 */ 
_mqx_uint _taskq_test
(
    pointer _PTR_ task_queue_error_ptr,
    pointer _PTR_ td_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TASK_QUEUE_STRUCT_PTR task_queue_ptr;
    _mqx_uint queue_size;
    _mqx_uint result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_taskq_test, task_queue_error_ptr, td_error_ptr);

    *td_error_ptr = NULL;
    *task_queue_error_ptr = NULL;

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR) {
        _KLOGX2(KLOG_taskq_test, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    }/* Endif */
#endif

    task_queue_ptr = (TASK_QUEUE_STRUCT_PTR)
    ((pointer)kernel_data->KERNEL_TASK_QUEUES.NEXT);
    if (_QUEUE_GET_SIZE(&kernel_data->KERNEL_TASK_QUEUES) == 0) {
        _KLOGX2(KLOG_taskq_test, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    _int_disable();

    result = _queue_test((QUEUE_STRUCT_PTR)&kernel_data->KERNEL_TASK_QUEUES,
                    task_queue_error_ptr);
    if (result != MQX_OK) {
        _int_enable();
        _KLOGX3(KLOG_taskq_test, result, *task_queue_error_ptr);
        return(result);
    } /* Endif */

    queue_size = _QUEUE_GET_SIZE(&kernel_data->KERNEL_TASK_QUEUES);
    while (queue_size--) {
        if (task_queue_ptr->VALID != TASK_QUEUE_VALID) {
            result = MQX_INVALID_TASK_QUEUE;
            break;
        } /* Endif */

        result = _queue_test(&task_queue_ptr->TD_QUEUE, td_error_ptr);
        if (result != MQX_OK) {
            break;
        } /* Endif */

        task_queue_ptr = task_queue_ptr->NEXT;
    } /* Endwhile */

    _int_enable();

    if (result != MQX_OK) {
        *task_queue_error_ptr = (pointer)task_queue_ptr;
    } /* Endif */
    _KLOGX4(KLOG_taskq_test, result, *task_queue_error_ptr, *td_error_ptr);

    return(result);

} /* Endbody */

/*!
 * \brief Suspends the specified task in the specified task queue.
 * 
 * The function blocks the specified task and puts the task's task descriptor in 
 * the task queue.
 * 
 * \param[in] task_id              Task ID of the task to suspend.
 * \param[in] users_task_queue_ptr Pointer to the task queue; returned by 
 * _taskq_create().
 * 
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID (Task_id is not a valid task descriptor.) 
 * \return MQX_INVALID_PARAMETER (Users_task_queue_ptr is NULL.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an 
 * ISR.)
 * \return MQX_INVALID_TASK_QUEUE (Users_task_queue_ptr does not point to a 
 * valid task queue.) 
 * \return MQX_INVALID_TASK_STATE (Task is not in the ready state.)
 * 
 * \warning Blocks the specified task.
 * \warning Cannot be called from an ISR.
 * 
 * \see _taskq_destroy
 * \see _taskq_create
 * \see _taskq_resume
 * \see _taskq_get_value   
 */ 
_mqx_uint _taskq_suspend_task
(
    _task_id task_id,
    pointer  users_task_queue_ptr
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TASK_QUEUE_STRUCT_PTR task_queue_ptr = (TASK_QUEUE_STRUCT_PTR) users_task_queue_ptr;
    register TD_STRUCT_PTR td_ptr;
    boolean me;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_taskq_suspend_task, task_id, users_task_queue_ptr);

    td_ptr = (TD_STRUCT_PTR) _task_get_td(task_id);
    me = (td_ptr == kernel_data->ACTIVE_PTR);

#if MQX_CHECK_ERRORS
    if (td_ptr == NULL) {
        _KLOGX2(KLOG_taskq_suspend_task, MQX_INVALID_TASK_ID);
        return(MQX_INVALID_TASK_ID);
    } /* Endif */
    if (task_queue_ptr == NULL) {
        _KLOGX2(KLOG_taskq_suspend_task, MQX_INVALID_PARAMETER);
        return(MQX_INVALID_PARAMETER);
    } /* Endif */
    if (me && kernel_data->IN_ISR) {
        _KLOGX2(KLOG_taskq_suspend_task, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    }/* Endif */
#endif

    _INT_DISABLE();

#if MQX_CHECK_VALIDITY
    if (task_queue_ptr->VALID != TASK_QUEUE_VALID) {
        _int_enable();
        _KLOGX2(KLOG_taskq_suspend_task, MQX_INVALID_TASK_QUEUE);
        return(MQX_INVALID_TASK_QUEUE);
    } /* Endif */
#endif

    if (td_ptr->STATE != READY) {
        _INT_ENABLE();
        _KLOGX2(KLOG_taskq_suspend_task, MQX_INVALID_TASK_STATE);
        return (MQX_INVALID_TASK_STATE);
    } /* Endif */

    td_ptr->STATE = TASK_QUEUE_BLOCKED;
    _QUEUE_UNLINK(td_ptr); /* Remove task from ready to run queue */
    td_ptr->INFO = (_mqx_uint) & task_queue_ptr->TD_QUEUE;
    if (task_queue_ptr->POLICY & MQX_TASK_QUEUE_BY_PRIORITY) {
        _sched_insert_priorityq_internal(&task_queue_ptr->TD_QUEUE, td_ptr);
    }
    else {
        _QUEUE_ENQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
    } /* Endif */

    if (me && (kernel_data->IN_ISR == 0)) {
        _sched_execute_scheduler_internal(); /* Let the other tasks run */
    } /* Endif */

    _INT_ENABLE();

    _KLOGX2(KLOG_taskq_suspend_task, MQX_OK);
    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Gets the size of the task queue.
 * 
 * \param[in] users_task_queue_ptr Pointer to the task queue; returned by 
 * _taskq_create().
 * 
 * \return Number of tasks on the task queue (Success.)
 * \return MAX_MQX_UINT (Failure.) 
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_PARAMETER (Users_task_queue_ptr is NULL.)
 * \li MQX_INVALID_TASK_QUEUE (Users_task_queue_ptr does not point to a valid 
 * task queue.)
 * 
 * \see _taskq_create
 * \see _task_set_error  
 */ 
_mqx_uint _taskq_get_value
(
    pointer users_task_queue_ptr
)
{ /* Body */
    register TASK_QUEUE_STRUCT_PTR task_queue_ptr = (TASK_QUEUE_STRUCT_PTR) users_task_queue_ptr;

#if MQX_CHECK_ERRORS
    if (task_queue_ptr == NULL) {
        _task_set_error(MQX_INVALID_PARAMETER);
        return(MAX_MQX_UINT);
    } /* Endif */
#endif

#if MQX_CHECK_VALIDITY   
    if (task_queue_ptr->VALID != TASK_QUEUE_VALID) {
        _task_set_error(MQX_INVALID_TASK_QUEUE);
        return(MAX_MQX_UINT);
    } /* Endif */
#endif

    return (task_queue_ptr->TD_QUEUE.SIZE);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/hmi_uids.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hmi_uids.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*   This header defines HID tables.
*
*END************************************************************************/
#ifndef __hmi_uids_h__
#define __hmi_uids_h__ 1

#define HMI_HID_USAGE_PAGE_MASK             0xffff0000
#define HMI_HID_USAGE_ID_MASK               0x0000ffff

/* USAGE PAGES */
#define HMI_HID_USAGE_PAGE_UNDEFINED        0x00000000
#define HMI_HID_USAGE_PAGE_GENERIC          0x00010000
#define HMI_HID_USAGE_PAGE_SIMULATION       0x00020000
#define HMI_HID_USAGE_PAGE_VR               0x00030000
#define HMI_HID_USAGE_PAGE_SPORT            0x00040000
#define HMI_HID_USAGE_PAGE_GAME             0x00050000
#define HMI_HID_USAGE_PAGE_DEV_CONTROLS     0x00060000
#define HMI_HID_USAGE_PAGE_KEYBOARD         0x00070000
#define HMI_HID_USAGE_PAGE_LED              0x00080000
#define HMI_HID_USAGE_PAGE_BUTTON           0x00090000
#define HMI_HID_USAGE_PAGE_ORDINAL          0x000A0000
#define HMI_HID_USAGE_PAGE_TELEPHONY        0x000B0000
#define HMI_HID_USAGE_PAGE_CONSUMER         0x000C0000
#define HMI_HID_USAGE_PAGE_DIGITIZER        0x000D0000
#define HMI_HID_USAGE_PAGE_UNICODE          0x00100000
#define HMI_HID_USAGE_PAGE_ALPHANUMERIC     0x00140000
/* Reserved space in HID USAGE table used for LEDx */
#define HMI_HID_USAGE_PAGE_LED_OFFSET       0x0000004E    /* reserved space in LED page */

#define HMI_GET_BUTTON_ID(number)           (HMI_HID_USAGE_PAGE_BUTTON     + (number))
#define HMI_GET_LED_ID(number)              (HMI_HID_USAGE_PAGE_LED + HMI_HID_USAGE_PAGE_LED_OFFSET + (number))
#define HMI_GET_ORDINAL_ID(number)          (HMI_HID_USAGE_PAGE_ORDINAL    + (number))
#define HMI_GET_GENERIC_ID(number)          (HMI_HID_USAGE_PAGE_GENERIC    + (number))

#define HMI_GET_BUTTON_NUMBER(id)   (HMI_HID_USAGE_ID_MASK & (id))
#define HMI_GET_LED_NUMBER(id)      ((HMI_HID_USAGE_ID_MASK & (id)) - HMI_HID_USAGE_PAGE_LED_OFFSET)

/* BUTTONS */
#define HMI_BUTTON_1        HMI_GET_BUTTON_ID(1)
#define HMI_BUTTON_2        HMI_GET_BUTTON_ID(2)
#define HMI_BUTTON_3        HMI_GET_BUTTON_ID(3)
#define HMI_BUTTON_4        HMI_GET_BUTTON_ID(4)
#define HMI_BUTTON_5        HMI_GET_BUTTON_ID(5)
#define HMI_BUTTON_6        HMI_GET_BUTTON_ID(6)
#define HMI_BUTTON_7        HMI_GET_BUTTON_ID(7)
#define HMI_BUTTON_8        HMI_GET_BUTTON_ID(8)
#define HMI_BUTTON_9        HMI_GET_BUTTON_ID(9)
#define HMI_BUTTON_10       HMI_GET_BUTTON_ID(10)
#define HMI_BUTTON_11       HMI_GET_BUTTON_ID(11)
#define HMI_BUTTON_12       HMI_GET_BUTTON_ID(12)
#define HMI_BUTTON_13       HMI_GET_BUTTON_ID(13)
#define HMI_BUTTON_14       HMI_GET_BUTTON_ID(14)
#define HMI_BUTTON_15       HMI_GET_BUTTON_ID(15)
#define HMI_BUTTON_16       HMI_GET_BUTTON_ID(16)
#define HMI_BUTTON_17       HMI_GET_BUTTON_ID(17)
#define HMI_BUTTON_18       HMI_GET_BUTTON_ID(18)
#define HMI_BUTTON_19       HMI_GET_BUTTON_ID(19)
#define HMI_BUTTON_20       HMI_GET_BUTTON_ID(20)
#define HMI_BUTTON_21       HMI_GET_BUTTON_ID(21)
#define HMI_BUTTON_22       HMI_GET_BUTTON_ID(22)
#define HMI_BUTTON_23       HMI_GET_BUTTON_ID(23)
#define HMI_BUTTON_24       HMI_GET_BUTTON_ID(24)
#define HMI_BUTTON_25       HMI_GET_BUTTON_ID(25)
#define HMI_BUTTON_26       HMI_GET_BUTTON_ID(26)
#define HMI_BUTTON_27       HMI_GET_BUTTON_ID(27)
#define HMI_BUTTON_28       HMI_GET_BUTTON_ID(28)
#define HMI_BUTTON_29       HMI_GET_BUTTON_ID(29)
#define HMI_BUTTON_30       HMI_GET_BUTTON_ID(30)
#define HMI_BUTTON_31       HMI_GET_BUTTON_ID(31)
#define HMI_BUTTON_32       HMI_GET_BUTTON_ID(32)
#define HMI_BUTTON_33       HMI_GET_BUTTON_ID(33)
#define HMI_BUTTON_34       HMI_GET_BUTTON_ID(34)
#define HMI_BUTTON_35       HMI_GET_BUTTON_ID(35)
#define HMI_BUTTON_36       HMI_GET_BUTTON_ID(36)
#define HMI_BUTTON_37       HMI_GET_BUTTON_ID(37)
#define HMI_BUTTON_38       HMI_GET_BUTTON_ID(38)
#define HMI_BUTTON_39       HMI_GET_BUTTON_ID(39)
#define HMI_BUTTON_40       HMI_GET_BUTTON_ID(40)
#define HMI_BUTTON_41       HMI_GET_BUTTON_ID(41)
#define HMI_BUTTON_42       HMI_GET_BUTTON_ID(42)
#define HMI_BUTTON_43       HMI_GET_BUTTON_ID(43)
#define HMI_BUTTON_44       HMI_GET_BUTTON_ID(44)
#define HMI_BUTTON_45       HMI_GET_BUTTON_ID(45)
#define HMI_BUTTON_46       HMI_GET_BUTTON_ID(46)
#define HMI_BUTTON_47       HMI_GET_BUTTON_ID(47)
#define HMI_BUTTON_48       HMI_GET_BUTTON_ID(48)
#define HMI_BUTTON_49       HMI_GET_BUTTON_ID(49)
#define HMI_BUTTON_50       HMI_GET_BUTTON_ID(50)

/* LEDS */
#define HMI_LED_1           HMI_GET_LED_ID(1)
#define HMI_LED_2           HMI_GET_LED_ID(2)
#define HMI_LED_3           HMI_GET_LED_ID(3)
#define HMI_LED_4           HMI_GET_LED_ID(4)
#define HMI_LED_5           HMI_GET_LED_ID(5)
#define HMI_LED_6           HMI_GET_LED_ID(6)
#define HMI_LED_7           HMI_GET_LED_ID(7)
#define HMI_LED_8           HMI_GET_LED_ID(8)
#define HMI_LED_9           HMI_GET_LED_ID(9)
#define HMI_LED_10          HMI_GET_LED_ID(10)

/* SLIDERS 
*  first slider - generic page, other instances are in ordinal page
*/
#define HMI_SLIDER_1        HMI_GET_GENERIC_ID(36)      /* slider = 36 */
#define HMI_SLIDER_2        HMI_GET_ORDINAL_ID(1)       /* ordinal 1-4 for sliders */
#define HMI_SLIDER_3        HMI_GET_ORDINAL_ID(2)
#define HMI_SLIDER_4        HMI_GET_ORDINAL_ID(3)
#define HMI_SLIDER_5        HMI_GET_ORDINAL_ID(4)

/* ROTARIES 
*  first rotary - generic page, other instances are in ordinal page
*/
#define HMI_ROTARY_1        HMI_GET_GENERIC_ID(38)    /* wheel = 38*/
#define HMI_ROTARY_2        HMI_GET_ORDINAL_ID(10)    /* ordinal 10-13 for rotary */
#define HMI_ROTARY_3        HMI_GET_ORDINAL_ID(11)
#define HMI_ROTARY_4        HMI_GET_ORDINAL_ID(12)
#define HMI_ROTARY_5        HMI_GET_ORDINAL_ID(13)

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mpc5675k.c<|end_filename|>
#include "flash_mpxs30.c"


<|start_filename|>Firmware/Inverter_firmware/Main/MonitorVT100.c<|end_filename|>
#include "app.h"

#define CNTLQ      0x11
#define CNTLS      0x13
#define DEL        0x7F
#define BACKSPACE  0x08
//#define CR         0x0D  конфликт имен с регистрами периферии
#define LF         0x0A
#define ESC        0x1B

#define COL        80   /* Maximum column size       */

#define EDSTLEN 20



T_VT100_cb  vt100_cb;

static void  Do_motor_test(INT8U keycode);
static void  Do_I2C_test(INT8U keycode);
static void  Do_LCD_test(INT8U keycode);
static void  Do_CAN_log_view(INT8U keycode);
//static void  Do_ADC_test(INT8U keycode);
static void  Do_ADC_read_smpls(INT8U keycode);
static void  Do_Meas_values_view(INT8U keycode);

extern const T_VT100_Menu MENU_MAIN;
extern const T_VT100_Menu MENU_PARAMETERS;
extern const T_VT100_Menu MENU_SPEC;

static INT32S       Lookup_menu_item(T_VT100_Menu_item **item, INT8U b);


int          special_access;
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

      Пункты имеющие свое подменю распологаются на следующем уровне вложенности
      Их функция подменяет в главном цикле обработчик нажатий по умолчанию и должна 
      отдавать управление периодически в главный цикл 

      Пункты не имеющие функции просто переходят на следующий уровень подменю

      Пункты не имеющие подменю полностью захватывают управление и на следующий уровень не переходят 

      Пункты без подменю и функции означают возврат на предыдущий уровень
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

//-------------------------------------------------------------------------------------
const T_VT100_Menu_item MENU_MAIN_ITEMS[] =
{
  { '1', 0,                         (void *)&MENU_PARAMETERS },
  { '2', Do_motor_test,              0 },
  { '3', Do_CAN_log_view,            0 },
//  { '3', Do_I2C_test,                0 },
//  { '4', Do_LCD_test,                0 },
//  { '5', 0,                         (void *)&MENU_SPEC },
//  { '6', Do_ADC_test,                0 },
//  { '7', Do_ADC_read_smpls,          0 },
  { '8', Do_Meas_values_view,        0 },
  { 'R', 0,                          0 },
  { 'M', 0,                         (void *)&MENU_MAIN }
};

const T_VT100_Menu MENU_MAIN =
{
  "Inverter 1.0 MONITOR Ver.130904",
  "\033[5C MAIN MENU \r\n"
  "\033[5C <1> - Adjustable parameters and settings\r\n"
  "\033[5C <2> - Motor test\r\n"
  "\033[5C <3> - CAN test\r\n"
//  "\033[5C <4> - LCD test\r\n"
//  "\033[5C <5> - Special menu\r\n"
//  "\033[5C <6> - ADC test\r\n"
//  "\033[5C <7> - Read ADC samples\r\n"
  "\033[5C <8> - Measured values view\r\n",
  MENU_MAIN_ITEMS,
  sizeof(MENU_MAIN_ITEMS) / sizeof(MENU_MAIN_ITEMS[0])
};

//-------------------------------------------------------------------------------------
const T_VT100_Menu MENU_PARAMETERS =
{
  "",
  "",
  0,
  0
};

const T_VT100_Menu_item MENU_SPEC_ITEMS[] =
{
  { '1', 0,                          0 },
  { 'R', 0,                          0 },
  { 'M', 0,                         (void *)&MENU_MAIN }
};

const T_VT100_Menu MENU_SPEC =
{
  "Inverter 1.0 MONITOR Ver.130904",
  "\033[5C SPECIAL MENU \r\n"
  "\033[5C <1> - Signals diagnostic\r\n"
  "\033[5C <R> - Display previous menu\r\n"
  "\033[5C <M> - Display main menu\r\n",
  MENU_SPEC_ITEMS,
  sizeof(MENU_SPEC_ITEMS) / sizeof(MENU_SPEC_ITEMS[0])
};



/*-------------------------------------------------------------------------------------------------------------
   Задача монитора
-------------------------------------------------------------------------------------------------------------*/
void VT100_task(uint_32 initial_data)
{
  INT8U    b;

  printf(VT100_CLEAR_AND_HOME);
  Goto_main_menu();

  do
  {
    if ( Mon_wait_byte(&b, 100) == MQX_OK )
    {
      if ( b != 0 )
      {
        if ( vt100_cb.Monitor_func ) vt100_cb.Monitor_func(b);  // Обработчик нажатий главного цикла
      }
    }


    if ( vt100_cb.menu_trace[vt100_cb.menu_nesting] == &MENU_MAIN )
    {
      // Вывод на дисплей счетчиков
      VT100_set_cursor_pos(20, 0);
      //VT100_set_cursor_pos(25, 0);
      //Mon_printf("Date/Time: %02d%02d.%02d.%02d %02d:%02d:%02d",vt100_cb.date.century,vt100_cb.date.year,vt100_cb.date.month,vt100_cb.date.day,vt100_cb.tim.hours,vt100_cb.tim.minutes,vt100_cb.tim.seconds);
    }


  }
  while (1);

}


/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void Set_monitor_func(void (*func)(unsigned char))
{
  vt100_cb.Monitor_func = func;
}



/*-------------------------------------------------------------------------------------------------------------
  Вывести на экран текущее меню
  1. Вывод заголовока меню
  2. Вывод содержания меню
-------------------------------------------------------------------------------------------------------------*/
void Display_menu(void)
{

  printf(VT100_CLEAR_AND_HOME);

  if ( vt100_cb.menu_trace[vt100_cb.menu_nesting] == 0 ) return;

  VT100_send_str_to_pos((INT8U *)vt100_cb.menu_trace[vt100_cb.menu_nesting]->menu_header, 1, Find_str_center((INT8U *)vt100_cb.menu_trace[vt100_cb.menu_nesting]->menu_header));
  VT100_send_str_to_pos(DASH_LINE, 2, 0);
  VT100_send_str_to_pos((INT8U *)vt100_cb.menu_trace[vt100_cb.menu_nesting]->menu_body, 3, 0);
  printf("\r\n");
  printf(DASH_LINE);

}
/*-------------------------------------------------------------------------------------------------------------
  Поиск в текущем меню пункта вызываемого передаваемым кодом
  Параметры:
    b - код команды вазывающей пункт меню
  Возвращает:
    Указатель на соответствующий пункт в текущем меню
-------------------------------------------------------------------------------------------------------------*/
INT32S Lookup_menu_item(T_VT100_Menu_item **item, INT8U b)
{
  INT16S i;

  if ( isalpha(b) != 0 ) b = toupper(b);
  for (i = 0; i < vt100_cb.menu_trace[vt100_cb.menu_nesting]->menu_items_cnt; i++)
  {
    *item = (T_VT100_Menu_item *)vt100_cb.menu_trace[vt100_cb.menu_nesting]->menu_items + i;
    if ( (*item)->but == b ) return (1);
  }
  return (0);
}


/*----------------------------------------------------------------------------
 *      Line Editor
 *---------------------------------------------------------------------------*/
static int Get_string(char *lp, int n)
{
  int cnt = 0;
  char c;

  do
  {
    Mon_wait_byte((unsigned char *)&c, 0xFFFF);
    switch (c)
    {
    case CNTLQ:                          /* ignore Control S/Q             */
    case CNTLS:
      break;

    case BACKSPACE:
    case DEL:
      if ( cnt == 0 )
      {
        break;
      }
      cnt--;                             /* decrement count                */
      lp--;                              /* and line pointer               */
      /* echo backspace                 */
      printf("\x008 \x008");
      break;
    case ESC:
      *lp = 0;                           /* ESC - stop editing line        */
      return (MQX_ERROR);
    default:
      printf("*");
      *lp = c;                           /* echo and store character       */
      lp++;                              /* increment line pointer         */
      cnt++;                             /* and count                      */
      break;
    }
  }
  while (cnt < n - 1  &&  c != 0x0d);      /* check limit and line feed      */
  *lp = 0;                                 /* mark end of string             */
  return (MQX_OK);
}

/*-------------------------------------------------------------------------------------------------------------
  Ввод кода для доступа к специальному меню
-------------------------------------------------------------------------------------------------------------*/
int Enter_special_code(void)
{
  char str[32];
  if ( special_access != 0 )
  {
    return MQX_OK;
  }
  printf(VT100_CLEAR_AND_HOME"Enter access code>");
  if ( Get_string(str, 31) == MQX_OK )
  {
    if ( strcmp(str, "4321\r") == 0 )
    {
      special_access = 1;
      return MQX_OK;
    }
  }

  return MQX_ERROR;
}
/*-------------------------------------------------------------------------------------------------------------
  Поиск пункта меню по коду вызова (в текущем меню)
  и выполнение соответствующей ему функции
  Параметры:
    b - код команды вазывающей пункт меню

-------------------------------------------------------------------------------------------------------------*/
void Execute_menu_func(INT8U b)
{
  T_VT100_Menu_item *menu_item;

  if ( Lookup_menu_item(&menu_item, b) != 0 )
  {
    // Нашли соответствующий пункт меню
    if ( menu_item->psubmenu != 0 )
    {
      // Если присутствует субменю, то вывести его

      if ( (T_VT100_Menu *)menu_item->psubmenu == &MENU_SPEC )
      {
        if ( Enter_special_code() != MQX_OK )
        {
          Display_menu();
          return;
        }
      }

      vt100_cb.menu_nesting++;
      vt100_cb.menu_trace[vt100_cb.menu_nesting] = (T_VT100_Menu *)menu_item->psubmenu;

      Display_menu();
      // Если есть функция у пункта меню, то передать ей обработчик нажатий в главном цикле и выполнить функцию.
      if ( menu_item->func != 0 )
      {
        vt100_cb.Monitor_func = (T_menu_func)(menu_item->func); // Установить обработчик нажатий главного цикла на функцию из пункта меню
        menu_item->func(0);                // Выполнить саму функцию меню
      }
    }
    else
    {
      if ( menu_item->func == 0 )
      {
        // Если нет ни субменю ни функции, значит это пункт возврата в предыдущее меню
        // Управление остается в главном цикле у обработчика по умолчанию
        Return_to_prev_menu();
        Display_menu();
      }
      else
      {
        // Если у пункта нет своего меню, то перейти очистить экран и перейти к выполению  функции выбранного пункта
        printf(VT100_CLEAR_AND_HOME);
        menu_item->func(0);
        // Управление возвращается в главный цикл обработчику по умолчанию
        Display_menu();
      }
    }

  }
}


/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void Goto_main_menu(void)
{

  vt100_cb.menu_nesting = 0;
  vt100_cb.menu_trace[vt100_cb.menu_nesting] = (T_VT100_Menu *)&MENU_MAIN;
  Display_menu();
  vt100_cb.Monitor_func = Execute_menu_func; // Назначение функции
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void Return_to_prev_menu(void)
{

  if ( vt100_cb.menu_nesting > 0 )
  {
    vt100_cb.menu_trace[vt100_cb.menu_nesting] = 0;
    vt100_cb.menu_nesting--;
  }
  vt100_cb.Monitor_func = Execute_menu_func; // Назначение функции
}



/*-------------------------------------------------------------------------------------------------------------
  Очистка экрана монитора
-------------------------------------------------------------------------------------------------------------*/
void VT100_clr_screen(void)
{
  printf(VT100_CLEAR_AND_HOME);
}

/*-------------------------------------------------------------------------------------------------------------
     Установка курсора в заданную позицию
-------------------------------------------------------------------------------------------------------------*/
void VT100_set_cursor_pos(INT8U row, INT8U col)
{
  printf("\033[%.2d;%.2dH", row, col);
}

/*-------------------------------------------------------------------------------------------------------------
     Вывод строки в заданную позицию
-------------------------------------------------------------------------------------------------------------*/
void VT100_send_str_to_pos(INT8U *str, INT8U row, INT8U col)
{
  printf("\033[%.2d;%.2dH", row, col);
  Mon_send_buf(str, strlen((char *)str));
}

/*-------------------------------------------------------------------------------------------------------------
    Находим позицию начала строки для расположения ее по центру экрана
-------------------------------------------------------------------------------------------------------------*/
INT8U Find_str_center(INT8U *str)
{
  INT16S l = 0;
  while (*(str + l) != 0) l++; // Находим длину строки
  return(COLCOUNT - l) / 2;
}



/*-------------------------------------------------------------------------------------------------------------
  Прием строки 
-------------------------------------------------------------------------------------------------------------*/
INT32S Mon_input_line(char *buf, int buf_len, int row, char *instr)
{

  int  i;
  INT8U b;
  int  res;
  INT8U  bs_seq[] = { 0x08, 0x020, 0x08, 0 };

  i = 0;
  VT100_set_cursor_pos(row, 0);
  printf(VT100_CLL_FM_CRSR);
  printf(">");

  if ( instr != 0 )
  {
    i = strlen(instr);
    if ( i < buf_len )
    {
      printf(instr);
    }
    else i = 0;
  }
  do
  {
    if ( Mon_wait_byte(&b, 1000) != MQX_OK )
    {
      res = MQX_ERROR;
      goto exit_;
    };

    if ( b == 0x08 )
    {
      if ( i > 0 )
      {
        i--;
        Mon_send_buf(bs_seq, sizeof(bs_seq));
      }
    }
    else if ( b != 0x0D && b != 0x0A && b != 0 )
    {
      Mon_send_buf(&b, 1);
      buf[i] = b;           /* String[i] value set to alpha */
      i++;
      if ( i >= buf_len )
      {
        res = MQX_ERROR;
        goto exit_;
      };
    }
  }
  while ((b != 0x0D) && (i < COL));

  res = MQX_OK;
  buf[i] = 0;                     /* End of string set to NUL */
exit_:

  VT100_set_cursor_pos(row, 0);
  printf(VT100_CLL_FM_CRSR);

  return (res);
}



/*-------------------------------------------------------------------------------------------------------------
  Вывод форматированной строки в коммуникационный канал порта
-------------------------------------------------------------------------------------------------------------*/
INT32S  Mon_send_buf(INT8U *buf, INT32U len)
{
  int i;
  for (i = 0; i < len; i++)
  {
    printf("%c", buf[i]);
  }
  return MQX_OK;
}

/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
INT32S Mon_wait_byte(INT8U *b, INT32U timeout)
{
  for (;;)
  {
    while (status() == 0)
    {
      if ( timeout == 0 )
      {
        return MQX_ERROR;
      }
      _time_delay_ticks(2);
      timeout--;
    }
    *b = getchar();
    return MQX_OK;
  }
}

static void FixStrerr(int len)
{
  static volatile int dummy;

  dummy = len;
}
/*-----------------------------------------------------------------------------------------------------
 
-----------------------------------------------------------------------------------------------------*/
static void  Do_motor_test(INT8U keycode)
{
  INT8U              b;
  T_MC_CBL           cbl;
  float              temp;
  unsigned long long cnt;
  char               str[64];
  T_meas_results     mres[MEAS_RES_ARR_SZ];

  printf("Motor algorithm test.\n\r");
  printf("Press 'R' to exit. '<'-down, '>'-up, 'F'-Fun on,'G'-Fun off, 'Q'-stop \n\r");

  do
  {
    //__ITM_EVENT32(1, 100);
    //ITM_EVENT32_WITH_PC(3, cnt);

    VT100_set_cursor_pos(3, 0);
    printf(DASH_LINE"\r\n");
    printf(VT100_CLR_LINE"%lld\r\n", cnt);

    MC_get_CBL(&cbl);
    printf(VT100_CLR_LINE"(0) Moving up accel.PWM scale factor  = %0.3f\r\n", cbl.up_accel_pwm_scale);
    printf(VT100_CLR_LINE"(1) Moving up PWM scale factor        = %0.3f\r\n", cbl.up_pwm_scale);
    printf(VT100_CLR_LINE"(2) Moving up decel.PWM scale factor  = %0.3f\r\n", cbl.up_decel_pwm_scale);
    printf(VT100_CLR_LINE"(3) Moving up rot.speed               = %d\r\n",    cbl.up_move_freq);
    printf(VT100_CLR_LINE"(4) Moving up acceler.time            = %d\r\n",    cbl.up_acceler_time);
    printf(VT100_CLR_LINE"(5) Moving up deceler.time            = %d\r\n",    cbl.up_deceler_time);

    printf(VT100_CLR_LINE"(6) Moving down accel.PWM scale factor= %0.3f\r\n", cbl.down_accel_pwm_scale);
    printf(VT100_CLR_LINE"(7) Moving down PWM scale factor      = %0.3f\r\n", cbl.down_pwm_scale);
    printf(VT100_CLR_LINE"(8) Moving down decel.PWM scale factor= %0.3f\r\n", cbl.down_decel_pwm_scale);
    printf(VT100_CLR_LINE"(9) Moving down rot.speed             = %d\r\n",    cbl.down_move_freq);
    printf(VT100_CLR_LINE"(A) Moving down acceler.time          = %d\r\n",    cbl.down_acceler_time);
    printf(VT100_CLR_LINE"(B) Moving down deceler.time          = %d\r\n",    cbl.down_deceler_time);
    printf(VT100_CLR_LINE"\r\n");
    printf(VT100_CLR_LINE"Motor cur.rot.speed = %d\r\n", cbl.mot_freq);
    printf(VT100_CLR_LINE"Rotation dir        = %d\r\n", cbl.direction);
    printf(VT100_CLR_LINE"skew_cnt = %06d, step = %016llX, ll_freq = %016llX\r\n", cbl.skew_cnt, cbl.ll_step, cbl.ll_mot_freq);
    printf(VT100_CLR_LINE"PWM scale= %0.3f\r\n", cbl.pwm_scale);

    if ( TempCtrl_read_IGBT_temperature(&temp) == MQX_OK )
    {
      snprintf(str, 63, "%0.3lf", temp);
      if ( strlen(str) > 6 ) FixStrerr(strlen(str));
      printf(VT100_CLR_LINE"IGBT temperature = %s\r\n", str);
    }
    else
    {
      printf(VT100_CLR_LINE"IGBT temperature reading error!\r\n");
    }

    if ( cbl.motor_drv_fail )
    {
      printf(VT100_CLR_LINE"Detected VFO = 0. Motor driver fail!\r\n");
    }
    else
    {
      printf(VT100_CLR_LINE"Motor driver Ok!\r\n");
    }
    Get_copy_meas_results(mres);
/* 
  ii_w         
  ii_v         
  ii_u         
  v_bus        
  smpl_temper  
  smpl_15v     
  smpl_5v       
  smpl_ii_u  
*/
    printf(VT100_CLR_LINE"Currents(w,v,u). Max  : %05.2f , %05.2f , %05.2f\r\n", mres[0].fmax, mres[1].fmax, mres[2].fmax);
    printf(VT100_CLR_LINE"Currents(w,v,u). Min  : %05.2f , %05.2f , %05.2f\r\n", mres[0].fmin, mres[1].fmin, mres[2].fmin);
    printf(VT100_CLR_LINE"Currents(w,v,u). Aver : %05.2f , %05.2f , %05.2f\r\n", mres[0].favr, mres[1].favr, mres[2].favr);
    printf(VT100_CLR_LINE"Currents(w,v,u). RMS  : %05.2f , %05.2f , %05.2f\r\n", mres[0].frms, mres[1].frms, mres[2].frms);
    printf("\r\n");
    printf(VT100_CLR_LINE"DC BUS. : max=%06.2f , min=%06.2f , avr=%06.2f, RMS=%06.2f\r\n", mres[3].fmax, mres[3].fmin, mres[3].favr, mres[3].frms);
    printf(VT100_CLR_LINE"Temper. : max=%06.2f , min=%06.2f , avr=%06.2f, RMS=%06.2f\r\n", mres[4].fmax, mres[4].fmin, mres[4].favr, mres[4].frms);



    if ( Mon_wait_byte(&b, 50) == MQX_OK )
    {
      switch (b)
      {
      case '0':
        sprintf(str, "%0.3f", cbl.up_accel_pwm_scale);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%f", &cbl.up_accel_pwm_scale) == 1 )
          {
            if ( (cbl.up_accel_pwm_scale <= 1) && (cbl.up_accel_pwm_scale >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;
      case '1':
        sprintf(str, "%0.3f", cbl.up_pwm_scale);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%f", &cbl.up_pwm_scale) == 1 )
          {
            if ( (cbl.up_pwm_scale <= 1) && (cbl.up_pwm_scale >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;
      case '2':
        sprintf(str, "%0.3f", cbl.up_decel_pwm_scale);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%f", &cbl.up_decel_pwm_scale) == 1 )
          {
            if ( (cbl.up_decel_pwm_scale <= 1) && (cbl.up_decel_pwm_scale >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;

      case '3':
        sprintf(str, "%d", cbl.up_move_freq);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%d", &cbl.up_move_freq) == 1 )
          {
            if ( (cbl.up_move_freq < 101) && (cbl.up_move_freq >= 1) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;
      case '4':
        sprintf(str, "%d", cbl.up_acceler_time);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%d", &cbl.up_acceler_time) == 1 )
          {
            if ( (cbl.up_acceler_time < 10000) && (cbl.up_acceler_time >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;
      case '5':
        sprintf(str, "%d", cbl.up_deceler_time);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%d", &cbl.up_deceler_time) == 1 )
          {
            if ( (cbl.up_deceler_time < 10000) && (cbl.up_deceler_time >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;

      case '6':
        sprintf(str, "%0.3f", cbl.down_accel_pwm_scale);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%f", &cbl.down_accel_pwm_scale) == 1 )
          {
            if ( (cbl.down_accel_pwm_scale <= 1) && (cbl.down_accel_pwm_scale >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;

      case '7':
        sprintf(str, "%0.3f", cbl.down_pwm_scale);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%f", &cbl.down_pwm_scale) == 1 )
          {
            if ( (cbl.down_pwm_scale <= 1) && (cbl.down_pwm_scale >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;

      case '8':
        sprintf(str, "%0.3f", cbl.down_decel_pwm_scale);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%f", &cbl.down_decel_pwm_scale) == 1 )
          {
            if ( (cbl.down_decel_pwm_scale <= 1) && (cbl.down_decel_pwm_scale >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;


      case '9':
        sprintf(str, "%d", cbl.down_move_freq);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%d", &cbl.down_move_freq) == 1 )
          {
            if ( (cbl.down_move_freq < 101) && (cbl.down_move_freq >= 1) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;
      case 'A':
        sprintf(str, "%d", cbl.down_acceler_time);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%d", &cbl.down_acceler_time) == 1 )
          {
            if ( (cbl.down_acceler_time < 10000) && (cbl.down_acceler_time >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;
      case 'B':
        sprintf(str, "%d", cbl.down_deceler_time);
        if ( Mon_input_line(str, 30, 24, str) == MQX_OK )
        {
          if ( sscanf(str, "%d", &cbl.down_deceler_time) == 1 )
          {
            if ( (cbl.down_deceler_time < 10000) && (cbl.down_deceler_time >= 0) )
            {
              MC_set_CBL(&cbl);
            }
          }
        }
        break;



      case '<':
        MC_set_events(MOTOR_START_DOWN);
        break;
      case '>':
        MC_set_events(MOTOR_START_UP);
        break;
      case 'q':
      case 'Q':
        MC_set_events(MOTOR_STOP);
        break;
      case 'f':
      case 'F':
          Fun_control(1);
        break;
      case 'g':
      case 'G':
          Fun_control(0);
        break;
      case 'R':
      case 'r':
        return;
      }
    }
    cnt++;
  }
  while (1);
}

/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
#define I2C_DEVICE_POLLED    "i2c0:"
#define I2C_DEVICE_INTERRUPT "ii2c0:"
#define I2C_MAX31725_ADDRESS  (0x90>>1)
#define BUFF_SZ               32

static void  Do_I2C_test(INT8U keycode)
{
  INT8U          b;
  MQX_FILE_PTR   fd;
  _mqx_int                     param, result;
  I2C_STATISTICS_STRUCT        stats;
  _mqx_int   n = BUFF_SZ;
  uchar  buffer[BUFF_SZ];

  printf("I2C test.\n\r");
  printf("Press 'R' to exit. \n\r");

  fd = fopen(I2C_DEVICE_POLLED, NULL);
  if ( fd == NULL )
  {
    printf("ERROR opening the I2C driver!\n\r");
  }
  else
  {
    /* Test ioctl commands */
    param = 100000;
    printf("Set current baud rate to %d ... ", param);
    if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_SET_BAUD, &param) )
    {
      printf("OK\n\r");
    }
    else
    {
      printf("ERROR\n\r");
    }

    printf("Set master mode ... ");
    if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_SET_MASTER_MODE, NULL) )
    {
      printf("OK\n\r");
    }
    else
    {
      printf("ERROR\n\r");
    }

    printf("Get statistics ... ");
    if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_GET_STATISTICS, (pointer) & stats) )
    {
      printf("OK\n\r  Interrupts:  %d\n\r", stats.INTERRUPTS);
      printf("  Rx packets:  %d\n\r", stats.RX_PACKETS);
      printf("  Tx packets:  %d\n\r", stats.TX_PACKETS);
      printf("  Tx lost arb: %d\n\r", stats.TX_LOST_ARBITRATIONS);
      printf("  Tx as slave: %d\n\r", stats.TX_ADDRESSED_AS_SLAVE);
      printf("  Tx naks:     %d\n\r", stats.TX_NAKS);
    }
    else
    {
      printf("ERROR\n\r");
    }

  }

  printf("Get current state ... ");
  if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_GET_STATE, &param) )
  {
    printf("0x%02x\n\r", param);
  }
  else
  {
    printf("ERROR\n\r");
  }

  param = I2C_MAX31725_ADDRESS;
  printf("Set destination address to 0x%02x ... ", param);
  if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_SET_DESTINATION_ADDRESS, &param) )
  {
    printf("OK\n\r");
  }
  else
  {
    printf("ERROR\n\r");
  }

  /* Initiate start and send I2C bus address */
  printf("  I2C start, send address and get ack ... ");
  fwrite(buffer, 1, 0, fd);

  /* Check ack (device exists) */
  if ( I2C_OK == ioctl(fd, IO_IOCTL_FLUSH_OUTPUT, &param) )
  {
    printf("OK ... ack == %d\n\r", param);
    if ( param )
    {
      /* Stop I2C transfer */
      printf("  Stop transfer ... ");
      if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_STOP, NULL) )
      {
        printf("OK\n\r");
      }
      else
      {
        printf("ERROR\n\r");
      }
    }
  }
  else
  {
    printf("ERROR\n\r");
  }

  buffer[0] = 0;
  printf("  Write to address 0x%02x ... ", buffer[0]);
  result = fwrite(buffer, 1, 1, fd);
  if ( 1 == result )
  {
    printf("OK\n\r");
  }
  else
  {
    printf("ERROR\n\r");
  }


  /* Restart I2C transfer for reading */
  printf("  Initiate repeated start ... ");
  if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_REPEATED_START, NULL) )
  {
    printf("OK\n\r");
  }
  else
  {
    printf("ERROR\n\r");
  }

  /* Set read request */
  param = n;
  printf("  Set number of bytes requested to %d ... ", param);
  if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_SET_RX_REQUEST, &param) )
  {
    printf("OK\n\r");
  }
  else
  {
    printf("ERROR\n\r");
  }


  /* Read all data */
  printf("  Read %d bytes ... ", n);
  result = fread(buffer, 1, n, fd);
  if ( result == n )
  {
    printf("OK\n\r");
  }
  else
  {
    printf("ERROR\n\r");
  }

  /* Stop I2C transfer - initiate EEPROM write cycle */
  printf("  Stop transfer ... ");
  if ( I2C_OK == ioctl(fd, IO_IOCTL_I2C_STOP, NULL) )
  {
    printf("OK\n\r");
  }
  else
  {
    printf("ERROR\n\r");
  }

  /* Close the driver */
  result = fclose(fd);
  if ( result )
  {
    printf("ERROR during close, returned: %d\n\r", result);
  }

  {
    int i, j;

    printf("\r\nDump:\r\n");

    for (j = 0; j < 2; j++)
    {
      for (i = 0; i < 16; i++)
      {
        printf("%02X ", buffer[i + j * 16]);
      }
      printf("\r\n");
    }

  }

  do
  {
    if ( Mon_wait_byte(&b, 50) == MQX_OK )
    {
      switch (b)
      {
      case 'R':
      case 'r':
        return;
      }
    }
  }
  while (1);

}

/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static void  Do_LCD_test(INT8U keycode)
{
  INT8U          b;

  printf("LCD test.\n\r");
  printf("Press 'R' to exit. \n\r");

  do
  {
    int r;
    LCD_init();

    _time_delay_ticks(1);
    r = rand();
    LCD_wr_data(r);

    if ( Mon_wait_byte(&b, 100) == MQX_OK )
    {
      switch (b)
      {
      case 'R':
      case 'r':
        return;
      }
    }
  }
  while (1);


}

/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/

static void  Do_CAN_log_view(INT8U keycode)
{
  INT8U          b;
  T_can_rx       rx;
  INT32U         i;

  printf("CAN log.\n\r");
  printf("Press 'R' to exit. \n\r");

  do
  {
    // Ожидаем сообщения о помещении в лог нового сообщения
    if ( CAN_wait_log_rec(10) == MQX_OK )
    {
      // Отобразить записи из лога
      while (CAN_pop_log_rec(&rx) == MQX_OK)
      {

        printf("%02X %08X %01X %01X %01X - ",  rx.code, rx.canid, rx.ext, rx.rtr, rx.len);
        for (i = 0; i < rx.len; i++)
        {
          printf("%02X ", rx.data[i]);
        }
        for (; i < 8; i++)
        {
          printf("   ");
        }
        printf("\r\n");
      }
    }
    if ( Mon_wait_byte(&b, 0) == MQX_OK )
    {
      switch (b)
      {
      case 'R':
      case 'r':
        return;
      }
    }
  }
  while (1);


}


/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
/*
static void  Do_ADC_test(INT8U keycode)
{
  INT8U           b;
  MQX_TICK_STRUCT start_time;
  MQX_TICK_STRUCT end_time;
  boolean         ovrfl;
  int_32          dt;
  signed short    res;
  int             i;

  PDB_deactivate_ADC_triggers();
  ADC_activate_soft_trig(ADC0_BASE_PTR);
  ADC_activate_soft_trig(ADC1_BASE_PTR);
  ADC_activate_soft_trig(ADC2_BASE_PTR);
  ADC_activate_soft_trig(ADC3_BASE_PTR);

  printf("ADC test.\n\r");
  printf("Press 'R' to exit. \n\r");


  printf("\r\nADC0 registers:\r\n");
  ADC_print_regs(ADC0_BASE_PTR);
  printf("\r\nADC1 registers:\r\n");
  ADC_print_regs(ADC1_BASE_PTR);
  printf("\r\nADC2 registers:\r\n");
  ADC_print_regs(ADC2_BASE_PTR);
  printf("\r\nADC3 registers:\r\n");
  ADC_print_regs(ADC3_BASE_PTR);

  printf("\r\n---==== CALIBRATING ====---\r\n");
  _time_get_ticks(&start_time);
  res = ADC_calibrating(ADC0_BASE_PTR);
  _time_get_ticks(&end_time);
  dt = _time_diff_microseconds(&end_time, &start_time, &ovrfl);
  printf("t=%d us, res=%d, ", dt, res);

  _time_get_ticks(&start_time);
  res = ADC_calibrating(ADC1_BASE_PTR);
  _time_get_ticks(&end_time);
  dt = _time_diff_microseconds(&end_time, &start_time, &ovrfl);
  printf("t=%d us, res=%d, ", dt, res);

  _time_get_ticks(&start_time);
  res = ADC_calibrating(ADC2_BASE_PTR);
  _time_get_ticks(&end_time);
  dt = _time_diff_microseconds(&end_time, &start_time, &ovrfl);
  printf("t=%d us, res=%d, ", dt, res);

  _time_get_ticks(&start_time);
  res = ADC_calibrating(ADC3_BASE_PTR);
  _time_get_ticks(&end_time);
  dt = _time_diff_microseconds(&end_time, &start_time, &ovrfl);
  printf("t=%d us, res=%d, ", dt, res);
  printf("\r\n");

  printf("\r\nADC0 registers:\r\n");
  ADC_print_regs(ADC0_BASE_PTR);
  printf("\r\nADC1 registers:\r\n");
  ADC_print_regs(ADC1_BASE_PTR);
  printf("\r\nADC2 registers:\r\n");
  ADC_print_regs(ADC2_BASE_PTR);
  printf("\r\nADC3 registers:\r\n");
  ADC_print_regs(ADC3_BASE_PTR);


  ADC_init(ADC0_BASE_PTR);
  ADC_init(ADC1_BASE_PTR);
  ADC_init(ADC2_BASE_PTR);
  ADC_init(ADC3_BASE_PTR);


  VT100_clr_screen();
  printf("Test ADC sampling (Press 'R' to exit):");
  do
  {
    VT100_set_cursor_pos(2, 0);

    for (i = 0; i < TEST_CH_ARR_SZ; i++)
    {
      int n;
      unsigned short r;
      _time_get_ticks(&start_time);
      for (n = 0; n < 100; n++)
      {
        res = ADC_get_sample(adca[i].padc, adca[i].ch, adca[i].diff, adca[i].aver);
      }
      _time_get_ticks(&end_time);
      dt = _time_diff_microseconds(&end_time, &start_time, &ovrfl) / 100;
      r = res;
      printf(VT100_CLR_LINE"%s(%02d) : R=%05d (%04X), Time=%03d us, val=%0.2f\r\n", adca[i].name, adca[i].ch, r, r,  dt, adca[i].converter(res));
    }


    if ( Mon_wait_byte(&b, 100) == MQX_OK )
    {
      switch (b)
      {
      case 'R':
      case 'r':

        ADC_activate_hrdw_trig(ADC0_BASE_PTR);
        ADC_activate_hrdw_trig(ADC1_BASE_PTR);
        ADC_activate_hrdw_trig(ADC2_BASE_PTR);
        ADC_activate_hrdw_trig(ADC3_BASE_PTR);
        PDB_activate_ADC_triggers();

        return;
      }
    }
  }
  while (1);
}
*/


/*-----------------------------------------------------------------------------------------------------
   Здесь пытаюсь определить как зависит шум измерения АЦП от момента когда сработает триггер на следующую выборку
    
   Похоже шум зависит случайно от калибровки
-----------------------------------------------------------------------------------------------------*/
/*
static void  Do_ADC_test(INT8U keycode)
{
  INT8U           b;
  int             i, k, n;
  signed short   *arr[8];
  float           avr[8];
  float           disp[8];
  T_ADC_state    *adc_state;

  printf("ADC test.\n\r");
  printf("Press 'R' to exit. \n\r\n\r");

  adc_state = ADC_get_state();

  for (i = 0; i < 100; i++)
  {
    int delay;
    delay = 100 + i;

    ADCs_prepare();
    PDB_set_delays(delay, delay);

    ADC_reset_smpl_arr_pos();
    do
    {
      _time_delay_ticks(1);
    }
    while (ADC_is_smpl_arr_ready() == 0);

    ADC_get_smpl_arr(arr);


    for (n = 0; n < 8; n++)
    {
      avr[n] = 0;
      for (k = 0; k < TST_SMPLS_ARR_SZ; k++)
      {
        // Находим среднее
        avr[n] += arr[n][k];
      }
      avr[n] = avr[n] / TST_SMPLS_ARR_SZ;

      disp[n] = 0;
      for (k = 0; k < TST_SMPLS_ARR_SZ; k++)
      {
        // Находим отклонение
        disp[n] += (arr[n][k] - avr[n]) * (arr[n][k] - avr[n]);
      }
      disp[n] = sqrt(disp[n] / TST_SMPLS_ARR_SZ);
    }
//    printf("%03d, %05.0f %05.0f %05.0f %05.0f %05.0f %05.0f %05.0f %05.0f\r\n",delay,avr[0],avr[1],avr[2],avr[3],avr[4],avr[5],avr[6],avr[7]);
//    printf("      %05.0f %05.0f %05.0f %05.0f %05.0f %05.0f %05.0f %05.0f\r\n",     disp[0],disp[1],disp[2],disp[3],disp[4],disp[5],disp[6],disp[7]);
    printf("%03d, %05.0f %05.0f %05.0f %05.0f  -  %06.2f %06.2f %06.2f %06.2f :%d%d%d%d\r\n", delay, avr[0], avr[2], avr[4], avr[1], disp[0], disp[2], disp[4], disp[1], adc_state->adc0_cal_res, adc_state->adc1_cal_res, adc_state->adc2_cal_res, adc_state->adc3_cal_res);
  }


  do
  {
    if ( Mon_wait_byte(&b, 100) == MQX_OK )
    {
      switch (b)
      {
      case 'R':
      case 'r':
        return;
      }
    }
  }
  while (1);
}
*/
static void Send_short(unsigned short val)
{
  putchar(val & 0xFF);
  putchar((val >> 8) & 0xFF);
}
/*-----------------------------------------------------------------------------------------------------
  Чтение из массива отсчетов ADC
-----------------------------------------------------------------------------------------------------*/
/*
static void  Do_ADC_read_smpls(INT8U keycode)
{
  INT8U          b;
  unsigned int   i;
  signed short   arr[16];


  // Ожидаем стартового символа кроме 'R'
  do
  {
    if ( Mon_wait_byte(&b, 100) == MQX_OK )
    {
      switch (b)
      {
      case 'R':
      case 'r':
        return;

      default:
        {
          _mqx_uint events;

          Lock_meas_mutex();
          MC_get_events(&events, 1000, SMPL_ARR1_FULL);
          if ( b == '9' )
          {
            for (i = 0; i < TST_SMPLS_ARR_SZ; i++)
            {
              ADC_get_arr_smp(i, arr);
              Send_short(i);
              Send_short(arr[0]);
              Send_short(arr[1]);
              Send_short(arr[2]);
              Send_short(arr[3]);
              Send_short(arr[4]);
              Send_short(arr[5]);
              Send_short(arr[6]);
              Send_short(arr[7]);
              _time_delay_ticks(3);

            }
          }
          else
          {
            for (i = 0; i < TST_SMPLS_ARR_SZ; i++)
            {
              ADC_get_arr_smp(i, arr);
              printf("%0.7f,%05d,%05d,%05d,%05d,%05d,%05d,%05d\r\n", (float)i / (float)PWM_FREQ, arr[0], arr[1], arr[2], arr[3], arr[8], arr[9], arr[10]);
            }
          }
          ADC_reset_smpl_arr_pos();
          Unlock_meas_mutex();
        }
        break;
      }
    }
  }
  while (1);
}
*/
/*-----------------------------------------------------------------------------------------------------
 
-----------------------------------------------------------------------------------------------------*/
static void  Do_Meas_values_view(INT8U keycode)
{
  INT8U          b;
  T_meas_results     mres[MEAS_RES_ARR_SZ]; 


  // Ожидаем стартового символа кроме 'R'
  do
  {
    if ( Mon_wait_byte(&b, 100) == MQX_OK )
    {
      switch (b)
      {
      case 'R':
      case 'r':
        return;

      case '0':
        {
          _mqx_uint events;
          MC_get_events(&events, 2, MEAS_RES_READY);
          for (;;)
          {
            if (MC_get_events(&events, 2, MEAS_RES_READY) == MQX_OK )
            {
              float aver = Get_aver_curr();
              Get_copy_meas_results(mres);
              printf("%0.1f, %0.1f\r\n", (mres[0].frms + mres[1].frms + mres[2].frms)/3, aver);
            }
            if (Mon_wait_byte(&b, 0) == MQX_OK) 
            {
              if ( (b=='R') || (b=='r') )
              {
                return;
              }
            }
          }
        }
        break;
      }
    }
  }
  while (1);


}


<|start_filename|>Firmware/Inverter_bootloader/BSP/low_level_init.c<|end_filename|>
/*************************************************************************
 *
 *    Used with ICCARM and AARM.
 *
 *    (c) Copyright IAR Systems 2010
 *
 *    File name   : low_level_init.c
 *    Description : Low level init procedure
 *
 *    History :
 *    1. Date        : 08, September 2010
 *       Author      : <NAME>
 *       Description : Create
 *
 *
 *    $Revision: #2 $
 **************************************************************************/
#include "app_cfg.h"

/*************************************************************************
 * Function Name: low_level_init
 * Parameters: none
 *
 * Return: none
 *
 * Description: This function is used for low level initialization
 *
 *************************************************************************/
int __low_level_init(void)
{
  WDOG_MemMapPtr WDOG = WDOG_BASE_PTR;

  // Выключать WATCHDOG надо сразу, иначе может возникнуть нестабильный запуск кода после холодного рестарта 
  //--------------------------------------------------------------------------------------------------------------------------------------
  WDOG->UNLOCK = 0xC520; // Откроем доступ на запись в регитры управления WDOG
  WDOG->UNLOCK = 0xD928;
  WDOG->STCTRLH = 0
                  + LSHIFT(0x00, 14) // DISTESTWDOG | Allows the WDOG’s functional test mode to be disabled permanently| 0 WDOG functional test mode is not disabled.
                  + LSHIFT(0x00, 12) // BYTESEL[1:0]| This 2-bit field select the byte to be tested ...                | 00 Byte 0 selected
                  + LSHIFT(0x00, 11) // TESTSEL     | Selects the test to be run on the watchdog timer                 | 0 Quick test
                  + LSHIFT(0x00, 10) // TESTWDOG    | Puts the watchdog in the functional test mode                    |
                  + LSHIFT(0x01, 8)  // Reserved    |
                  + LSHIFT(0x01, 7)  // WAITEN      | Enables or disables WDOG in wait mode.                           | 1 WDOG is enabled in CPU wait mode.
                  + LSHIFT(0x01, 6)  // STOPEN      | Enables or disables WDOG in stop mode                            | 1 WDOG is enabled in CPU stop mode.
                  + LSHIFT(0x00, 5)  // DBGEN       | Enables or disables WDOG in Debug mode                           | 0 WDOG is disabled in CPU Debug mode.
                  + LSHIFT(0x01, 4)  // ALLOWUPDATE | Enables updates to watchdog write once registers                 | 1 WDOG write once registers can be unlocked for updating
                  + LSHIFT(0x00, 3)  // WINEN       | Enable windowing mode.                                           | 0 Windowing mode is disabled.
                  + LSHIFT(0x00, 2)  // IRQRSTEN    | Used to enable the debug breadcrumbs feature                     | 0 WDOG time-out generates reset only.
                  + LSHIFT(0x01, 1)  // CLKSRC      | Selects clock source for the WDOG                                | 1 WDOG clock sourced from alternate clock source
                  + LSHIFT(0x00, 0)  // WDOGEN      | Enables or disables the WDOG’s operation                         | 1 WDOG is enabled.
  ;


  Init_pins();
  Init_cpu();

  return 1;
}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi_legacy/spi_mcf5xxx_qspi_prv.h<|end_filename|>
#ifndef __spi_mcf5xxx_qspi_prv_h__ 
#define __spi_mcf5xxx_qspi_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_mcf5xxx_qspi_prv.h$
* $Version : 3.6.4.0$
* $Date    : Jun-22-2010$
*
* Comments:
*
*   This file contains definitions private to the SPI driver.
*
*END************************************************************************/

#include "spi.h"
#include "spi_mcf5xxx_qspi.h"

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

#define MCF5XXX_QSPI_QDR_TX (0x0001)
#define MCF5XXX_QSPI_QDR_RX (0x0002)

/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** MCF5XXX_QSPI_INFO_STRUCT
** Run time state information for each spi channel
*/
typedef struct mcf5xxx_qspi_info_struct
{
   /* The spi device register */
   VMCF5XXX_QSPI_STRUCT_PTR          QSPI_PTR;

   /* The current init values for this port */
   MCF5XXX_QSPI_INIT_STRUCT          INIT;

   /* The previous vector, interrupt handler and data */
   void                  (_CODE_PTR_ OLD_ISR)(pointer);
   pointer                           OLD_ISR_DATA;

   /* Receive/transmit flag */
   uint_16                           RECEIVING;
   
   /* Difference between transmitted and received bytes */
   uint_16                           ONTHEWAY;
   
   /* Number of bytes requested to receive */
   uint_32                           RX_REQUEST;
  
   /* Pointer to the buffer to use for Tx/Rx data */
   uchar_ptr                         RX_BUFFER;

   /* Rx write index */
   uint_32                           RX_IN;

   /* Rx read index */
   uint_32                           RX_OUT;

   /* Pointer to the buffer to use for current Tx data */
   uchar_ptr                         TX_BUFFER;

   /* Tx write index */
   uint_32                           TX_IN;

   /* Tx read index */
   uint_32                           TX_OUT;
   
   /* Chip select used during transfers */
   uint_32                           CS;

   /* Previous state of chip select */
   uint_32                           CS_ACTIVE;

   /* Chip select set callback */
   SPI_CS_CALLBACK                   CS_CALLBACK[MCF5XXX_QSPI_CS_COUNT];

   /* User data for callback */
   pointer                           CS_USERDATA[MCF5XXX_QSPI_CS_COUNT];

   /* Statistical information */
   SPI_STATISTICS_STRUCT             STATS;
   
   /* Whether to hold CS low between subsequent transfers */
   boolean                           CSIV_ACTIVE;

} MCF5XXX_QSPI_INFO_STRUCT, _PTR_ MCF5XXX_QSPI_INFO_STRUCT_PTR;
      
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ipradix.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipradix.h$
* $Version : 3.5.6.0$
* $Date    : Dec-8-2009$
*
* Comments:
*
*   IP Radix Tree definitions
*
*END************************************************************************/

#ifndef __ipradix_h__
#define __ipradix_h__

/***************************************
**
** Type definitions
**
*/

typedef struct ipradix_node {
   pointer              DATA;    /* must be first field */
   _ip_address          IP;
   _ip_address          MASK;
   struct ipradix_node _PTR_ PARENT;
   struct ipradix_node _PTR_ CHILD[2];
} IPRADIX_NODE, _PTR_ IPRADIX_NODE_PTR;


/***************************************
**
** Prototypes
**
*/

void IPRADIX_init(IPRADIX_NODE_PTR);

void IPRADIX_findbest
(
   IPRADIX_NODE_PTR     root,    /* [IN] the root of the radix tree */
   _ip_address          ip,      /* [IN] the IP address to search for */
   boolean (_CODE_PTR_  test)(pointer, pointer),
                                 /* [IN] application-specific test */
   pointer              data     /* [IN] data for test() */
);

void IPRADIX_insert
(
   IPRADIX_NODE_PTR     root,    /* [IN] the root of the radix tree */
   _ip_address          ip,      /* [IN] the IP address to insert */
   _ip_address          mask,    /* [IN] the IP network mask */
   _rtcs_part           part,    /* [IN] the node partition */
   void (_CODE_PTR_     insert)(pointer _PTR_, pointer),
                                 /* [IN] application-specific insert */
   pointer              data     /* [IN] data for insert() */
);

void IPRADIX_walk
(
   IPRADIX_NODE_PTR     root,    /* [IN] the root of the radix tree */
   boolean (_CODE_PTR_  test)(_ip_address, _ip_address, pointer, pointer),
                                 /* [IN] application-specific test */
   pointer              data     /* [IN] data for test() */
);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/audio/usb_host_audio.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_audio.c$
* $Version : 3.8.5.0$
* $Date    : Aug-31-2012$
*
* Comments:
*
*   This file Contains the implementation of class driver for Audio devices.
*
*END************************************************************************/
#include "usb_host_audio.h"

static void usb_class_audio_cntrl_callback(pointer, pointer, uchar_ptr, uint_32, USB_STATUS);
static USB_STATUS check_valid_fu(USB_AUDIO_CTRL_DESC_FU_PTR,uint_8,uint_8);
static USB_STATUS check_valid_ep(USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP_PTR,uint_8);

LWEVENT_STRUCT USB_Event;
#define USB_EVENT_CTRL 0x01
#define USB_EVENT_DATA 0x02

/* usb audio feature command declaration */
static USB_AUDIO_COMMAND usb_audio_feature_commands[NUMBER_OF_FEATURE_COMMANDS] = 
{
    /* Mute commands */
    {FU_MUTE_MASK, GET_REQUEST_ITF, GET_CUR, USB_AUDIO_CTRL_FU_MUTE, 1}, /* USB_AUDIO_GET_CUR_MUTE */
    {FU_MUTE_MASK, SET_REQUEST_ITF, SET_CUR, USB_AUDIO_CTRL_FU_MUTE, 1}, /* USB_AUDIO_SET_CUR_MUTE */
    /* Volume commands */
    {FU_VOLUME_MASK, GET_REQUEST_ITF, GET_CUR, USB_AUDIO_CTRL_FU_VOLUME, 2}, /* USB_AUDIO_GET_CUR_VOLUME */
    {FU_VOLUME_MASK, SET_REQUEST_ITF, SET_CUR, USB_AUDIO_CTRL_FU_VOLUME, 2}, /* USB_AUDIO_SET_CUR_VOLUME */
    {FU_VOLUME_MASK, GET_REQUEST_ITF, GET_MIN, USB_AUDIO_CTRL_FU_VOLUME, 2}, /* USB_AUDIO_GET_MIN_VOLUME */
    {FU_VOLUME_MASK, SET_REQUEST_ITF, SET_MIN, USB_AUDIO_CTRL_FU_VOLUME, 2}, /* USB_AUDIO_SET_MIN_VOLUME */
    {FU_VOLUME_MASK, GET_REQUEST_ITF, GET_MAX, USB_AUDIO_CTRL_FU_VOLUME, 2}, /* USB_AUDIO_GET_MAX_VOLUME */
    {FU_VOLUME_MASK, SET_REQUEST_ITF, SET_MAX, USB_AUDIO_CTRL_FU_VOLUME, 2}, /* USB_AUDIO_SET_MAX_VOLUME */
    {FU_VOLUME_MASK, GET_REQUEST_ITF, GET_RES, USB_AUDIO_CTRL_FU_VOLUME, 2}, /* USB_AUDIO_GET_RES_VOLUME */
    {FU_VOLUME_MASK, SET_REQUEST_ITF, SET_RES, USB_AUDIO_CTRL_FU_VOLUME, 2}, /* USB_AUDIO_SET_RES_VOLUME */
    /* Bass commands */
    {FU_BASS_MASK, GET_REQUEST_ITF, GET_CUR, USB_AUDIO_CTRL_FU_BASS, 1}, /* USB_AUDIO_GET_CUR_BASS */
    {FU_BASS_MASK, SET_REQUEST_ITF, SET_CUR, USB_AUDIO_CTRL_FU_BASS, 1}, /* USB_AUDIO_SET_CUR_BASS */
    {FU_BASS_MASK, GET_REQUEST_ITF, GET_MIN, USB_AUDIO_CTRL_FU_BASS, 1}, /* USB_AUDIO_GET_MIN_BASS */
    {FU_BASS_MASK, SET_REQUEST_ITF, SET_MIN, USB_AUDIO_CTRL_FU_BASS, 1}, /* USB_AUDIO_SET_MIN_BASS */
    {FU_BASS_MASK, GET_REQUEST_ITF, GET_MAX, USB_AUDIO_CTRL_FU_BASS, 1}, /* USB_AUDIO_GET_MAX_BASS */
    {FU_BASS_MASK, SET_REQUEST_ITF, SET_MAX, USB_AUDIO_CTRL_FU_BASS, 1}, /* USB_AUDIO_SET_MAX_BASS */
    {FU_BASS_MASK, GET_REQUEST_ITF, GET_RES, USB_AUDIO_CTRL_FU_BASS, 1}, /* USB_AUDIO_GET_RES_BASS */
    {FU_BASS_MASK, SET_REQUEST_ITF, SET_RES, USB_AUDIO_CTRL_FU_BASS, 1}, /* USB_AUDIO_SET_RES_BASS */
    /* Mid commands */
    {FU_MID_MASK, GET_REQUEST_ITF, GET_CUR, USB_AUDIO_CTRL_FU_MID, 1}, /* USB_AUDIO_GET_CUR_MID */
    {FU_MID_MASK, SET_REQUEST_ITF, SET_CUR, USB_AUDIO_CTRL_FU_MID, 1}, /* USB_AUDIO_SET_CUR_MID */
    {FU_MID_MASK, GET_REQUEST_ITF, GET_MIN, USB_AUDIO_CTRL_FU_MID, 1}, /* USB_AUDIO_GET_MIN_MID */
    {FU_MID_MASK, SET_REQUEST_ITF, SET_MIN, USB_AUDIO_CTRL_FU_MID, 1}, /* USB_AUDIO_SET_MIN_MID */
    {FU_MID_MASK, GET_REQUEST_ITF, GET_MAX, USB_AUDIO_CTRL_FU_MID, 1}, /* USB_AUDIO_GET_MAX_MID */
    {FU_MID_MASK, SET_REQUEST_ITF, SET_MAX, USB_AUDIO_CTRL_FU_MID, 1}, /* USB_AUDIO_SET_MAX_MID */
    {FU_MID_MASK, GET_REQUEST_ITF, GET_RES, USB_AUDIO_CTRL_FU_MID, 1}, /* USB_AUDIO_GET_RES_MID */
    {FU_MID_MASK, SET_REQUEST_ITF, SET_RES, USB_AUDIO_CTRL_FU_MID, 1}, /* USB_AUDIO_SET_RES_MID */
    /* Treble commands */
    {FU_TREBLE_MASK, GET_REQUEST_ITF, GET_CUR, USB_AUDIO_CTRL_FU_TREBLE, 1}, /* USB_AUDIO_GET_CUR_TREBLE */
    {FU_TREBLE_MASK, SET_REQUEST_ITF, SET_CUR, USB_AUDIO_CTRL_FU_TREBLE, 1}, /* USB_AUDIO_SET_CUR_TREBLE */
    {FU_TREBLE_MASK, GET_REQUEST_ITF, GET_MIN, USB_AUDIO_CTRL_FU_TREBLE, 1}, /* USB_AUDIO_GET_MIN_TREBLE */
    {FU_TREBLE_MASK, SET_REQUEST_ITF, SET_MIN, USB_AUDIO_CTRL_FU_TREBLE, 1}, /* USB_AUDIO_SET_MIN_TREBLE */
    {FU_TREBLE_MASK, GET_REQUEST_ITF, GET_MAX, USB_AUDIO_CTRL_FU_TREBLE, 1}, /* USB_AUDIO_GET_MAX_TREBLE */
    {FU_TREBLE_MASK, SET_REQUEST_ITF, SET_MAX, USB_AUDIO_CTRL_FU_TREBLE, 1}, /* USB_AUDIO_SET_MAX_TREBLE */
    {FU_TREBLE_MASK, GET_REQUEST_ITF, GET_RES, USB_AUDIO_CTRL_FU_TREBLE, 1}, /* USB_AUDIO_GET_RES_TREBLE */
    {FU_TREBLE_MASK, SET_REQUEST_ITF, SET_RES, USB_AUDIO_CTRL_FU_TREBLE, 1}, /* USB_AUDIO_SET_RES_TREBLE */
    /* AGC commands */
    {FU_AGC_MASK, GET_REQUEST_ITF, GET_CUR, USB_AUDIO_CTRL_FU_AGC, 1}, /* USB_AUDIO_GET_CUR_AGC */
    {FU_AGC_MASK, SET_REQUEST_ITF, SET_CUR, USB_AUDIO_CTRL_FU_AGC, 1}, /* USB_AUDIO_SET_CUR_AGC */
    /* Delay commands */
    {FU_DELAY_MASK, GET_REQUEST_ITF, GET_CUR, USB_AUDIO_CTRL_FU_DELAY, 1}, /* USB_AUDIO_GET_CUR_DELAY */
    {FU_DELAY_MASK, SET_REQUEST_ITF, SET_CUR, USB_AUDIO_CTRL_FU_DELAY, 1}, /* USB_AUDIO_SET_CUR_DELAY */
    {FU_DELAY_MASK, GET_REQUEST_ITF, GET_MIN, USB_AUDIO_CTRL_FU_DELAY, 1}, /* USB_AUDIO_GET_MIN_DELAY */
    {FU_DELAY_MASK, SET_REQUEST_ITF, SET_MIN, USB_AUDIO_CTRL_FU_DELAY, 1}, /* USB_AUDIO_SET_MIN_DELAY */
    {FU_DELAY_MASK, GET_REQUEST_ITF, GET_MAX, USB_AUDIO_CTRL_FU_DELAY, 1}, /* USB_AUDIO_GET_MAX_DELAY */
    {FU_DELAY_MASK, SET_REQUEST_ITF, SET_MAX, USB_AUDIO_CTRL_FU_DELAY, 1}, /* USB_AUDIO_SET_MAX_DELAY */
    {FU_DELAY_MASK, GET_REQUEST_ITF, GET_RES, USB_AUDIO_CTRL_FU_DELAY, 1}, /* USB_AUDIO_GET_RES_DELAY */
    {FU_DELAY_MASK, SET_REQUEST_ITF, SET_RES, USB_AUDIO_CTRL_FU_DELAY, 1}, /* USB_AUDIO_SET_RES_DELAY */
    /* Bass boost commands */
    {FU_BASS_BOOST_MASK, GET_REQUEST_ITF, GET_CUR, USB_AUDIO_CTRL_FU_BASS_BOOST, 1}, /* USB_AUDIO_GET_CUR_BASS_BOOST */
    {FU_BASS_BOOST_MASK, SET_REQUEST_ITF, SET_CUR, USB_AUDIO_CTRL_FU_BASS_BOOST, 1}, /* USB_AUDIO_SET_CUR_BASS_BOOST */
};
/* usb audio endpoint command declaration */
static USB_AUDIO_COMMAND usb_audio_endpoint_commands[NUMBER_OF_ENDPOINT_COMMANDS] = 
{
    /* Pitch commands */
    {PITCH_MASK, GET_REQUEST_EP , GET_CUR, PITCH_CONTROL, 1}, /* USB_AUDIO_GET_CUR_PITCH */
    {PITCH_MASK, SET_REQUEST_EP, SET_CUR, PITCH_CONTROL, 1}, /* USB_AUDIO_SET_CUR_PITCH */
    /* Sampling frequency commands */
    {SAMPLING_FREQ_MASK, GET_REQUEST_EP, GET_CUR, SAMPLING_FREQ_CONTROL, 3}, /* USB_AUDIO_GET_CUR_SAMPLING_FREQ */
    {SAMPLING_FREQ_MASK, SET_REQUEST_EP, SET_CUR, SAMPLING_FREQ_CONTROL, 3}, /* USB_AUDIO_SET_CUR_SAMPLING_FREQ */
    {SAMPLING_FREQ_MASK, GET_REQUEST_EP, GET_MIN, SAMPLING_FREQ_CONTROL, 3}, /* USB_AUDIO_GET_MIN_SAMPLING_FREQ */
    {SAMPLING_FREQ_MASK, SET_REQUEST_EP, SET_MIN, SAMPLING_FREQ_CONTROL, 3}, /* USB_AUDIO_SET_MIN_SAMPLING_FREQ */
    {SAMPLING_FREQ_MASK, GET_REQUEST_EP, GET_MAX, SAMPLING_FREQ_CONTROL, 3}, /* USB_AUDIO_GET_MAX_SAMPLING_FREQ */
    {SAMPLING_FREQ_MASK, SET_REQUEST_EP, SET_MAX, SAMPLING_FREQ_CONTROL, 3}, /* USB_AUDIO_SET_MAX_SAMPLING_FREQ */
    {SAMPLING_FREQ_MASK, GET_REQUEST_EP, GET_RES, SAMPLING_FREQ_CONTROL, 3}, /* USB_AUDIO_GET_RES_SAMPLING_FREQ */
    {SAMPLING_FREQ_MASK, SET_REQUEST_EP, SET_RES, SAMPLING_FREQ_CONTROL, 3}, /* USB_AUDIO_SET_RES_SAMPLING_FREQ */
};
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_cntrl_callback
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This is the callback used when audio control information is sent or received.
*
*END*--------------------------------------------------------------------*/
static void usb_class_audio_cntrl_callback
(
    /* [IN] Unused */
    pointer     pipe,

    /* [IN] Pointer to the class interface instance */
    pointer     param,

    /* [IN] Data buffer */
    uchar_ptr   buffer,

    /* [IN] Length of buffer */
    uint_32     len,

    /* [IN] Error code (if any) */
    USB_STATUS  status
)
{ /* Body */
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR      if_ptr;

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_cntrl_callback");
#endif

    /*
    ** There is no need for USB_lock in the callback function, and there is also no
    ** need to check if the device is still attached (otherwise this callback
    ** would never have been called!
    */
    /* Get class interface handle, reset IN_SETUP and call callback */
    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)param;

    if (if_ptr->AUDIO_G.USER_CALLBACK) {
        if_ptr->AUDIO_G.USER_CALLBACK(pipe, if_ptr->AUDIO_G.USER_PARAM, buffer, len, status);
    } /* Endif */

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_cntrl_callback, SUCCESSFUL");
#endif
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_cntrl_common
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is used to send a control request.
*     It must be run with USB locked.
*
*END*--------------------------------------------------------------------*/
static USB_STATUS usb_class_audio_cntrl_common
(
    /* [IN] The communication device common command structure */
    AUDIO_COMMAND_PTR           com_ptr,

    /* [IN] The audio control interface */
    //AUDIO_CONTROL_INTERFACE_STRUCT_PTR if_ctrl_ptr,

    /* [IN] Bitmask of the request type */
    uint_8                    bmrequesttype,

    /* [IN] Request code */
    uint_8                    brequest,

    /* [IN] Value to copy into WVALUE field of the REQUEST */
    uint_16                   wvalue,

    /* [IN] Value to copy into WINDEX field of the REQUEST */
    uint_16                   wIndex,

    /* [IN] Length of the data associated with REQUEST */
    uint_16                   wlength,

    /* [IN] Pointer to data buffer used to send/recv */
    uchar_ptr                 data
)
{ /* Body */
    USB_AUDIO_GENERAL_CLASS_PTR      if_ptr;
    USB_SETUP                        req;
    USB_STATUS                       status = USBERR_NO_INTERFACE;

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_cntrl_common");
#endif

    if_ptr = (USB_AUDIO_GENERAL_CLASS_PTR) com_ptr->CLASS_PTR->class_intf_handle;

    /* Save the higher level callback and ID */
    if_ptr->USER_CALLBACK = com_ptr->CALLBACK_FN;
    if_ptr->USER_PARAM = com_ptr->CALLBACK_PARAM;

    /* Setup the request */
    req.BMREQUESTTYPE = bmrequesttype;
    req.BREQUEST = brequest;

    *(uint_16*)req.WINDEX = HOST_TO_LE_SHORT(wIndex);
    *(uint_16*)req.WVALUE = HOST_TO_LE_SHORT(wvalue);
    *(uint_16*)req.WLENGTH = HOST_TO_LE_SHORT(wlength);


    if (USB_STATUS_TRANSFER_QUEUED == (status = _usb_hostdev_cntrl_request(if_ptr->G.dev_handle, &req, data,
                                       usb_class_audio_cntrl_callback, if_ptr)))
        status = USB_OK;

#ifdef _HOST_DEBUG_
    if (!status)
        DEBUG_LOG_TRACE("usb_class_audio_cntrl_common, SUCCESSFUL");
    else
        DEBUG_LOG_TRACE("usb_class_audio_cntrl_common, FAILED");
#endif

    return status;
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : check_valid_fu
* Returned Value : None
* Comments       :
*     Check whether attribute of feature valid or not.
*
*END*--------------------------------------------------------------------*/
static USB_STATUS check_valid_fu
(
    /* [IN] pointer to feature unit */
    USB_AUDIO_CTRL_DESC_FU_PTR fu_ptr,

    /* [IN] Control mask */
    uint_8 control_mask,

    uint_8 atribute_index
)
{
    USB_STATUS status = USBERR_ERROR;

    if (NULL!=fu_ptr)
    {
        if(atribute_index<(fu_ptr->bLength - 7))
        /* Call num_logical_chan is number of logical channels.
         * Compare atribute_index with (fu_ptr->bControlSize*(num_logical_chan + 1))= (fu_ptr->bLength -7)
         * to make sure atribute_index is valid element in bmaControls() array */
        {
            if (fu_ptr->bmaControls[atribute_index] & control_mask)
            {
                status = USB_OK;
            }
        }
    }
    return status;
}
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : check_valid_ep
* Returned Value : None
* Comments       :
*     Check whether attribute of endpoint valid or not.
*
*END*--------------------------------------------------------------------*/
static USB_STATUS check_valid_ep
(
    /* [IN] pointer to isochonounous endpoint */
    USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP_PTR ep_ptr,

    /* [IN] control selector */
    uint_8 control_selector
)
{
    USB_STATUS status = USBERR_ERROR;

    if (NULL!=ep_ptr)
    {
        if (ep_ptr->bmAttributes && control_selector)
            status = USB_OK;
        else
            status = USBERR_INVALID_REQ_TYPE;
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_int_callback
* Returned Value : None
* Comments       :
*     Called on interrupt endpoint data reception.
*
*END*--------------------------------------------------------------------*/
static void usb_class_audio_int_callback
(
    /* [IN] pointer to pipe */
    _usb_pipe_handle  pipe,

    /* [IN] user-defined parameter */
    pointer           param,

    /* [IN] buffer address */
    pointer           buffer,

    /* [IN] length of data transferred */
    uint_32           len,

    /* [IN] status, hopefully USB_OK or USB_DONE */
    uint_32           status
)
{ /* Body */
    CLASS_CALL_STRUCT_PTR         audio_instance = (CLASS_CALL_STRUCT_PTR) param;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR if_ptr;

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_int_callback");
#endif
    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR) audio_instance->class_intf_handle;

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_int_callback, SUCCESSFUL");
#endif

    if (NULL!=pipe)
    {
        if_ptr->interrupt_callback(pipe,param,buffer,len,status);
    }

    usb_class_audio_init_ipipe(audio_instance,if_ptr->interrupt_callback,if_ptr->interrupt_callback_param);

    _lwevent_set(&USB_Event, USB_EVENT_DATA);

} /*EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_init_ipipe
* Returned Value : Success as USB_OK
* Comments       :
*     Starts interrupt endpoint to poll for interrupt on specified device.
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_init_ipipe
(
    /* control interface instance */
    CLASS_CALL_STRUCT_PTR     audio_instance,

    /* Callback to application */
    tr_callback               user_callback,

    /* Callback parameter */
    pointer                   user_callback_param
)
{ /* Body */
    TR_INIT_PARAM_STRUCT           tr;
    USB_STATUS                     status = USBERR_NO_INTERFACE;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR  if_ptr;

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_init_ipipe");
#endif

    USB_lock();
    /* Validity checking, always needed when passing data to lower API */
    if (usb_host_class_intf_validate(audio_instance)) {
        if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR) audio_instance->class_intf_handle;

        if_ptr->interrupt_callback = user_callback;
        if_ptr->interrupt_callback_param = user_callback_param;

        if (if_ptr->interrupt_pipe != NULL) {
            usb_hostdev_tr_init(&tr, (tr_callback) usb_class_audio_int_callback, (pointer) audio_instance);
            tr.G.RX_BUFFER = (uchar_ptr) &if_ptr->interrupt_buffer;
            tr.G.RX_LENGTH = sizeof(if_ptr->interrupt_buffer);

            if (USB_STATUS_TRANSFER_QUEUED == (status = _usb_host_recv_data(
                                                   if_ptr->AUDIO_G.G.host_handle,
                                                   if_ptr->interrupt_pipe,
                                                   &tr
                                               )))
            {
                status = USB_OK;
            }
        }
        else
            status = USBERR_OPEN_PIPE_FAILED;
    }/* Endif */

    USB_unlock();

#ifdef _HOST_DEBUG_
    if (!status)
        DEBUG_LOG_TRACE("usb_class_audio_init_ipipe, SUCCESSFUL");
    else
        DEBUG_LOG_TRACE("usb_class_audio_init_ipipe, FAILED");
#endif

    return status;
} /* End Body */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_audio_recv_data
* Returned Value : USB status
* Comments       :
*     Receive data on isochronous IN pipe.
*
*END*--------------------------------------------------------------------*/
USB_STATUS usb_audio_recv_data
(
    /* [IN] class-interface control pointer */
    CLASS_CALL_STRUCT_PTR   control_ptr,

    /* [IN] class-interface stream pointer */
    CLASS_CALL_STRUCT_PTR   stream_ptr,

    /* [IN] callback upon completion */
    tr_callback             callback,

    /* [IN] user parameter returned by callback */
    pointer                 call_parm,

    /* [IN] data length */
    uint_32                 buf_size,

    /* [IN] buffer pointer */
    uchar_ptr               buffer
)
{ /* Body */
    AUDIO_STREAM_INTERFACE_STRUCT_PTR   stream_if_ptr;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR  control_if_ptr;
    TR_INIT_PARAM_STRUCT                tr;
    USB_STATUS                          status = USBERR_NO_INTERFACE;

    USB_lock();
    /* Validity checking, always needed when passing data to lower API */
    if (!usb_host_class_intf_validate(control_ptr)) {
        USB_unlock();
        return USBERR_NO_INTERFACE;
    }
    stream_if_ptr = (AUDIO_STREAM_INTERFACE_STRUCT_PTR) stream_ptr->class_intf_handle;
    control_if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR) control_ptr->class_intf_handle;

    /* Do the device use OUT pipe? */
    if (stream_if_ptr->iso_in_pipe == NULL) {
        USB_unlock();
        return USBERR_OPEN_PIPE_FAILED;
    }

    /* Validity checking, always needed when passing data to lower API */
    if (!usb_host_class_intf_validate(control_ptr)) {
        USB_unlock();
        return USBERR_NO_INTERFACE;
    }

    usb_hostdev_tr_init(&tr, (tr_callback) callback, (pointer) call_parm);
    tr.G.RX_BUFFER = (uchar_ptr) buffer;
    tr.G.RX_LENGTH = buf_size;

    status = _usb_host_recv_data(control_if_ptr->AUDIO_G.G.host_handle,
                                 stream_if_ptr->iso_in_pipe, &tr);

    USB_unlock();

    return status;
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_audio_send_data
* Returned Value : USB status
* Comments       :
*     Send audio data to device through a isochronous OUT pipe.
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_audio_send_data
(
    /* [IN] audio control class interface pointer  */
    CLASS_CALL_STRUCT_PTR   control_ptr,

    /* [IN] audio stream class interface pointer  */
    CLASS_CALL_STRUCT_PTR   stream_ptr,

    /* [IN] callback upon completion */
    tr_callback             callback,

    /* [IN] user parameter returned by callback */
    pointer                 call_parm,

    /* [IN] data length */
    uint_32                 buf_size,

    /* [IN] buffer pointer */
    uchar_ptr               buffer
)
{ /* Body */
    AUDIO_STREAM_INTERFACE_STRUCT_PTR   stream_if_ptr;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR  control_if_ptr;
    TR_INIT_PARAM_STRUCT                tr;
    USB_STATUS                          status = USBERR_NO_INTERFACE;

    USB_lock();
    /* Validity checking, always needed when passing data to lower API */
    if (!usb_host_class_intf_validate(control_ptr)) {
        USB_unlock();
        return USBERR_NO_INTERFACE;
    }
    stream_if_ptr = (AUDIO_STREAM_INTERFACE_STRUCT_PTR) stream_ptr->class_intf_handle;
    control_if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR) control_ptr->class_intf_handle;

    /* Do the device use OUT pipe? */
    if (stream_if_ptr->iso_out_pipe == NULL) {
        USB_unlock();
        return USBERR_OPEN_PIPE_FAILED;
    }

    /* Validity checking, always needed when passing data to lower API */
    if (!usb_host_class_intf_validate(control_ptr)) {
        USB_unlock();
        return USBERR_NO_INTERFACE;
    }

    usb_hostdev_tr_init(&tr, (tr_callback) callback, (pointer) call_parm);
    tr.G.TX_BUFFER = (uchar_ptr) buffer;
    tr.G.TX_LENGTH = buf_size;

    status = _usb_host_send_data(control_if_ptr->AUDIO_G.G.host_handle, stream_if_ptr->iso_out_pipe, &tr);

    USB_unlock();

    return status;
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_get_copy_protect
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to get copy protect value
*     from the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_get_copy_protect
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] Buffer to receive data */
    pointer                    buf
)
{ /* Body */

    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    uint_16 wIndex;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->it_desc->bTerminalID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* check valid of input terminal descriptor */
    if (if_ptr->it_desc==NULL)
    {
        return USBERR_NO_DESCRIPTOR;
    }
    else
    {
        return usb_class_audio_cntrl_common(com_ptr,GET_REQUEST_ITF,GET_CUR,
                                            (uint_16)((COPY_PROTECT_CONTROL << 8)),wIndex,1,buf);
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_set_copy_protect
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to send copy protect value
*     to the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_set_copy_protect
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] Buffer to send data */
    pointer                    buf
)
{ /* Body */

    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    uint_16 wIndex;
    USB_AUDIO_CTRL_DESC_OT_PTR ot_desc;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    ot_desc = (USB_AUDIO_CTRL_DESC_OT_PTR)if_ptr->ot_desc;

    wIndex = (uint_16)(((ot_desc->bTerminalID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* check valid of input terminal descriptor */
    if (ot_desc==NULL)
    {
        return USBERR_NO_DESCRIPTOR;
    }
    else
    {
        return usb_class_audio_cntrl_common(com_ptr,SET_REQUEST_ITF,SET_CUR,
                                            (uint_16)((COPY_PROTECT_CONTROL << 8)),wIndex,1,buf);
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_feature_command
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to get or set feature units 
*     of audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_feature_command
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to send data */
    pointer                      buf,
    /* [IN] The command to perform */
    uint_32                      cmd
)
{ /* Body */
    uint_16 wIndex;
    uint_16 request_value;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_AUDIO_COMMAND_PTR p_feature_command;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    /* Validity checking: for audio interface */
    status = usb_host_class_intf_validate(if_ptr);
    if (USB_OK == status)
    {
        /* pointer to command */
        p_feature_command = &(usb_audio_feature_commands[cmd]);
        /* get request value */
        request_value = (uint_16)((p_feature_command->request_value << 8) | channel_no);
        wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

        /* Check whether this attribute valid or not */
        status = check_valid_fu(if_ptr->fu_desc,p_feature_command->control_mask,if_ptr->fu_desc->bControlSize*channel_no);

        if (USB_OK == status)
        {
            status = usb_class_audio_cntrl_common(com_ptr,
                                                  p_feature_command->request_type,
                                                  p_feature_command->request_code,
                                                  request_value,
                                                  wIndex,
                                                  p_feature_command->length,
                                                  buf);
        }
    }
    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_endpoint_command
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to performs services
*      for endpoint
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_endpoint_command
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] Buffer to receive data */
    pointer                      buf,
    /* [IN] The command to perform */
    uint_32                      cmd
)
{
    uint_8 Endp_num;
    AUDIO_STREAM_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;
    uint_16 request_value;
    USB_AUDIO_COMMAND_PTR p_endpoint_command;

    if_ptr = (AUDIO_STREAM_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    
    /* pointer to command */
    p_endpoint_command = &(usb_audio_endpoint_commands[cmd]);
    /* get request value */
    request_value     = (uint_16)((p_endpoint_command->request_value << 8));
    
    /* Check whether this attribute valid or not */
    status = check_valid_ep(if_ptr->iso_endp_spec_desc,p_endpoint_command->control_mask);

    if (USB_OK == status)
    {
        /* Any isochronous pipe is supported? */
        if ((NULL == if_ptr->iso_in_pipe) && (NULL == if_ptr->iso_out_pipe))
        {
            return USBERR_INVALID_NUM_OF_ENDPOINTS;
        }
        else if (NULL!=if_ptr->iso_in_pipe)
        {
            Endp_num = (if_ptr->iso_in_pipe->ENDPOINT_NUMBER | 0x80);
        }
        else
        {
            Endp_num = if_ptr->iso_out_pipe->ENDPOINT_NUMBER;
        }/* Endif */

        status = usb_class_audio_cntrl_common(com_ptr,
                                              p_endpoint_command->request_type,
                                              p_endpoint_command->request_code,
                                              request_value,
                                              (uint_16)Endp_num,
                                              p_endpoint_command->length,
                                              buf);
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_get_cur_graphic_eq
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to get current graphic equalizer value
*     from the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_get_cur_graphic_eq
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] length of the Buffer */
    uint_16                      blen,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to receive data */
    pointer                      buf
)
{ /* Body */

    uint_16 wIndex;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* Check whether this attribute valid or not */
    status = check_valid_fu(if_ptr->fu_desc,FU_GRAPHIC_EQ_MASK,if_ptr->fu_desc->bControlSize*channel_no);

    if (USB_OK == status)
    {
        status = usb_class_audio_cntrl_common(com_ptr,GET_REQUEST_ITF,GET_CUR,
                                            (uint_16)((USB_AUDIO_CTRL_FU_GRAPHIC_EQ << 8) | channel_no),wIndex,blen,buf);
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_set_cur_graphic_eq
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to send current graphic equalizer value
*     to the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_set_cur_graphic_eq
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] length of the Buffer */
    uint_16                      blen,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to send data */
    pointer                      buf
)
{ /* Body */
    uint_16 wIndex;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* Check whether this attribute valid or not */
    status = check_valid_fu(if_ptr->fu_desc,FU_GRAPHIC_EQ_MASK,if_ptr->fu_desc->bControlSize*channel_no);

    if (USB_OK == status)
    {
        status = usb_class_audio_cntrl_common(com_ptr,SET_REQUEST_ITF,SET_CUR,
                                            (uint_16)((USB_AUDIO_CTRL_FU_GRAPHIC_EQ << 8) | channel_no),wIndex,blen,buf);
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_get_min_graphic_eq
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to get min graphic equalizer value
*     from the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_get_min_graphic_eq
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] length of the Buffer */
    uint_16                      blen,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to receive data */
    pointer                      buf
)
{ /* Body */

    uint_16 wIndex;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* Check whether this attribute valid or not */
    status = check_valid_fu(if_ptr->fu_desc,FU_GRAPHIC_EQ_MASK,if_ptr->fu_desc->bControlSize*channel_no);

    if (USB_OK == status)
    {
        status = usb_class_audio_cntrl_common(com_ptr,GET_REQUEST_ITF,GET_MIN,
                                            (uint_16)((USB_AUDIO_CTRL_FU_GRAPHIC_EQ << 8) | channel_no),wIndex,blen,buf);
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_set_min_graphic_eq
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to send min graphic equalizer value
*     to the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_set_min_graphic_eq
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] length of the Buffer */
    uint_16                      blen,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to send data */
    pointer                      buf
)
{ /* Body */
    uint_16 wIndex;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* Check whether this attribute valid or not */
    status = check_valid_fu(if_ptr->fu_desc,FU_GRAPHIC_EQ_MASK,if_ptr->fu_desc->bControlSize*channel_no);

    if (USB_OK == status)
    {
        status = usb_class_audio_cntrl_common(com_ptr,SET_REQUEST_ITF,SET_MIN,
                                            (uint_16)((USB_AUDIO_CTRL_FU_GRAPHIC_EQ << 8) | channel_no),wIndex,blen,buf);
    }

    return status;
}


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_get_max_graphic_eq
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to get max graphic equalizer value
*     from the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_get_max_graphic_eq
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] length of the Buffer */
    uint_16                      blen,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to receive data */
    pointer                      buf
)
{ /* Body */

    uint_16 wIndex;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* Check whether this attribute valid or not */
    status = check_valid_fu(if_ptr->fu_desc,FU_GRAPHIC_EQ_MASK,if_ptr->fu_desc->bControlSize*channel_no);

    if (USB_OK == status)
    {
        status = usb_class_audio_cntrl_common(com_ptr,GET_REQUEST_ITF,GET_MAX,
                                            (uint_16)((USB_AUDIO_CTRL_FU_GRAPHIC_EQ << 8) | channel_no),wIndex,blen,buf);
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_set_max_graphic_eq
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to send max graphic equalizer value
*     to the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_set_max_graphic_eq
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] length of the Buffer */
    uint_16                      blen,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to send data */
    pointer                      buf
)
{ /* Body */
    uint_16 wIndex;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* Check whether this attribute valid or not */
    status = check_valid_fu(if_ptr->fu_desc,FU_GRAPHIC_EQ_MASK,if_ptr->fu_desc->bControlSize*channel_no);

    if (USB_OK == status)
    {
        status = usb_class_audio_cntrl_common(com_ptr,SET_REQUEST_ITF,SET_MAX,
                                            (uint_16)((USB_AUDIO_CTRL_FU_GRAPHIC_EQ << 8) | channel_no),wIndex,blen,buf);
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_get_res_graphic_eq
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to get resolution graphic equalizer value
*     from the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_get_res_graphic_eq
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] length of the Buffer */
    uint_16                      blen,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to receive data */
    pointer                      buf
)
{ /* Body */

    uint_16 wIndex;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* Check whether this attribute valid or not */
    status = check_valid_fu(if_ptr->fu_desc,FU_GRAPHIC_EQ_MASK,if_ptr->fu_desc->bControlSize*channel_no);

    if (USB_OK == status)
    {
        status = usb_class_audio_cntrl_common(com_ptr,GET_REQUEST_ITF,GET_RES,
                                            (uint_16)((USB_AUDIO_CTRL_FU_GRAPHIC_EQ << 8) | channel_no),wIndex,blen,buf);
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_set_res_graphic_eq
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to send resolution graphic equalizer value
*     to the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_set_res_graphic_eq
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR            com_ptr,

    /* [IN] length of the Buffer */
    uint_16                      blen,

    /* [IN] channel number */
    uint_8                       channel_no,

    /* [IN] Buffer to send data */
    pointer                      buf
)
{ /* Body */
    uint_16 wIndex;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;
    wIndex = (uint_16)(((if_ptr->fu_desc->bUnitID)<<8)|(if_ptr->AUDIO_G.IFNUM));

    /* Check whether this attribute valid or not */
    status = check_valid_fu(if_ptr->fu_desc,FU_GRAPHIC_EQ_MASK,if_ptr->fu_desc->bControlSize*channel_no);

    if (USB_OK == status)
    {
        status = usb_class_audio_cntrl_common(com_ptr,SET_REQUEST_ITF,SET_RES,
                                            (uint_16)((USB_AUDIO_CTRL_FU_GRAPHIC_EQ << 8) | channel_no),wIndex,blen,buf);
    }

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_get_mem_endpoint
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to get memory of the endpoint
*     from the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_get_mem_endpoint
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR          com_ptr,

    /* [IN] zero-based offset value */
    uint_16                    offset,

    /* [IN] length of the Buffer */
    uint_16                    blen,

    /* [IN] Buffer to receive data */
    pointer                    buf
)
{ /* Body */

    uint_8 Endp_num;
    AUDIO_STREAM_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_STREAM_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;

    /* Any isochronous pipe is supported? */
    if ((NULL == if_ptr->iso_in_pipe) && (NULL == if_ptr->iso_out_pipe))
    {
        return USBERR_INVALID_NUM_OF_ENDPOINTS;
    }
    else if (if_ptr->iso_in_pipe!=NULL)
    {
        Endp_num = if_ptr->iso_in_pipe->ENDPOINT_NUMBER;
    }
    else
    {
        Endp_num = if_ptr->iso_out_pipe->ENDPOINT_NUMBER;
    }/* Endif */

    status = usb_class_audio_cntrl_common(com_ptr,GET_REQUEST_EP,GET_MEM,
                                         offset,(uint_16)Endp_num,blen,buf);

    return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_set_mem_endpoint
* Returned Value : USB_OK if command has been passed on USB
* Comments       :
*     This function is called by the application to send memory of the endpoint
*     to the audio device
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_set_mem_endpoint
(
    /* [IN] Class Interface structure pointer */
    AUDIO_COMMAND_PTR           com_ptr,

    /* [IN] zero-based offset value */
    uint_16                     offset,

    /* [IN] length of the Buffer */
    uint_16                     blen,

    /* [IN] Buffer to send data */
    pointer                     buf
)
{ /* Body */

    uint_8 Endp_num;
    AUDIO_STREAM_INTERFACE_STRUCT_PTR     if_ptr;
    USB_STATUS status = USBERR_ERROR;

    if_ptr = (AUDIO_STREAM_INTERFACE_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle;

    /* Any isochronous pipe is supported? */
    if ((NULL == if_ptr->iso_in_pipe) && (NULL == if_ptr->iso_out_pipe))
    {
        return USBERR_INVALID_NUM_OF_ENDPOINTS;
    }
    else if (if_ptr->iso_in_pipe!=NULL)
    {
        Endp_num = if_ptr->iso_in_pipe->ENDPOINT_NUMBER;
    }
    else
    {
        Endp_num = if_ptr->iso_out_pipe->ENDPOINT_NUMBER;
    }/* Endif */

    status = usb_class_audio_cntrl_common(com_ptr,SET_REQUEST_EP,SET_MEM,
                                         offset,(uint_16)Endp_num,blen,buf);

    return status;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ftpc.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpc.h$
* $Version : 3.8.9.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/
#define FTPC_BUF_SIZE      1460
#define FTPC_LINELEN       128
#define FTPC_MAX_ARGS      8

//#define FTPd_send_msg(p,m) send(p->CONTROL_SOCK, m, strlen(m), 0)
void FTPd_send_msg(pointer p, const char * m);


typedef struct ftpc_context_struct  {
   char_ptr             ARGV[FTPC_MAX_ARGS];
   int_32               ARGC;
   char                 CMD_LINE[FTPC_LINELEN];
   char                 HISTORY[FTPC_LINELEN];
   char                 BUFFER[FTPC_BUF_SIZE];
   
   _ip_address          HOSTADDR;
   char                 HOSTNAME[RTCS_SNAME_LEN];
   pointer              HANDLE;
   
   boolean              EXIT;
} FTPc_CONTEXT_STRUCT, _PTR_ FTPc_CONTEXT_PTR;

typedef struct FTPc_command_struct  {
   char_ptr  COMMAND;
   int_32      (*FTPc_FUNC)(FTPc_CONTEXT_PTR context_ptr,int_32 argc, char_ptr argv[]);
} FTPc_COMMAND_STRUCT, _PTR_ FTPc_COMMAND_PTR; 




extern const FTPc_COMMAND_STRUCT FTPc_commands[];


extern int_32  FTPc_help(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_ascii(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_binary(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_bye(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_cd(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_close(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_delete(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_get(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_ls(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_mkdir(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_open(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_pass(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_put(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_pwd(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_remotehelp(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_rename(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_rmdir(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );
extern int_32  FTPc_user(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] );

extern _mqx_int FTP_client(char_ptr dest);

extern int_32  FTP_open         (pointer _PTR_, _ip_address, MQX_FILE_PTR);
extern int_32  FTP_command      (pointer, char_ptr, MQX_FILE_PTR);
extern int_32  FTP_command_data (pointer, char_ptr, MQX_FILE_PTR, MQX_FILE_PTR, uint_32);
extern int_32  FTP_close        (pointer, MQX_FILE_PTR);
extern int_32  FTP_receive_message(pointer , MQX_FILE_PTR);

/*EOF*/


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_df.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_df.c$
* $Version : 3.8.3.0$
* $Date    : May-16-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_prv.h>

#if SHELLCFG_USES_MFS

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_df
* Returned Value   :  int_32 error code
* Comments  :  Prints out disk free information for current filesystem .
*
*END*---------------------------------------------------------------------*/

int_32  Shell_df(int_32 argc, char_ptr argv[])
{ /* Body */
    boolean              print_usage;
    boolean              shorthelp = FALSE;
    int_32               return_code = SHELL_EXIT_SUCCESS;
    SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context(argv);
    MQX_FILE_PTR         fs_ptr;
    int_64               space;
    int_32               clusters;
    uint_32              cluster_size;
    int_32               error = 0;
    char_ptr             fs_name;

    print_usage = Shell_check_help_request(argc, argv, &shorthelp);

    if (!print_usage)  {
        if (argc > 2)  {        
            printf("Error, invalid number of parameters\n");
            return_code = SHELL_EXIT_ERROR;
            print_usage=TRUE;
        }
    }

    if (print_usage)  {
        if (shorthelp)  {
            printf("%s [<filesystem>]\n", argv[0]);
        }
        else {
            printf("Usage: %s [filesystem]\n", argv[0]);
            printf("   <filesystem> = filesystem to query for free space\n");
        }
        return return_code;
    }
           

    if (argc == 2) {
        fs_name = argv[1];
        fs_ptr = _io_get_fs_by_name(fs_name);
    }
    else {
        fs_name = Shell_get_current_filesystem_name(shell_ptr);
        fs_ptr = Shell_get_current_filesystem(argv);
    }          

    /* check if filesystem is mounted */ 
    if (fs_ptr == NULL)  {
        printf("Error, file system not mounted\n");
        return return_code = SHELL_EXIT_ERROR;
    }


    ioctl(fs_ptr, IO_IOCTL_FREE_SPACE, &space);
    clusters = ioctl(fs_ptr, IO_IOCTL_FREE_CLUSTERS, NULL);
    error = ioctl(fs_ptr, IO_IOCTL_GET_CLUSTER_SIZE, &cluster_size);
    if (error) cluster_size=0;

    printf("Free disk space on %s\n", fs_name);
    printf("%ld clusters, %ld bytes each\n", (long int)clusters, (long int)cluster_size);
    printf("%lu KB\n", (unsigned long int)(space>>10));

    return return_code;
} /* Endbody */

#endif //SHELLCFG_USES_MFS


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd_task.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd_task.c$
* $Version : 172.16.58.3$
* $Date    : Aug-31-2012$
*
* Comments:
*
*   HTTPD os specific part implementation.
*
*END************************************************************************/

#include "httpd_mqx.h"
#include "httpd.h"
#include "httpd_prv.h"
#include "socket.h"

#if !HTTPDCFG_POLL_MODE

/** initialize httpd server with default configuration
 * \param root_dir < root directory structure
 * \param index_page < pointer to index page with absolut path
 * \return pointer to created server structure
 *
 *  If AF inet family was not defined, it will be started 
 *  in depend on IP4 or IP6 or IP4+IP6 configuration choosed. 
 *  So, IP4 - server for IP4, IP6 - server for IP6, IP4+IP6 two 
 *  servers well be started.
 */
#if RTCSCFG_ENABLE_IP4

HTTPD_STRUCT* httpd_server_init(HTTPD_ROOT_DIR_STRUCT *root_dir, const char *index_page) 
{
    extern HTTPD_PARAMS_STRUCT  *httpd_default_params(HTTPD_PARAMS_STRUCT *params);
    extern HTTPD_STRUCT         *httpd_init(HTTPD_PARAMS_STRUCT *params);
    HTTPD_STRUCT                *server = NULL;
    HTTPD_PARAMS_STRUCT         *params;
    
    params = httpd_default_params(NULL);
    if (params) 
    {
        params->root_dir = root_dir;
        params->index_page = (char*)index_page;
        params->af = AF_INET;
        server = httpd_init(params);
    }
    
    return server;
}

#endif

HTTPD_STRUCT* httpd_server_init_af(HTTPD_ROOT_DIR_STRUCT *root_dir, const char *index_page, uint_32 af_inet_family)
{
    extern HTTPD_PARAMS_STRUCT  *httpd_default_params(HTTPD_PARAMS_STRUCT *params);
    extern HTTPD_STRUCT         *httpd_init(HTTPD_PARAMS_STRUCT *params);
    HTTPD_STRUCT                *server = NULL;
    HTTPD_PARAMS_STRUCT         *params;
    
    params = httpd_default_params(NULL);
    if (params) 
    {
        params->root_dir = root_dir;
        params->index_page = (char*)index_page;
        params->af=af_inet_family;
        server = httpd_init(params);
    }
    return server;
}



#if HTTPDCFG_STATIC_TASKS

/** session task
 */
static void httpd_session_static_task(pointer init_ptr, pointer creator) {
    extern HTTPD_SESSION_STRUCT* httpd_ses_alloc(HTTPD_STRUCT *server);
    extern void httpd_ses_poll(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session);
    HTTPD_SESSION_STRUCT *session;
    
    if (!init_ptr)
        goto ERROR;
    
    session = httpd_ses_alloc((HTTPD_STRUCT*)init_ptr);
    
    if (session) {
        RTCS_task_resume_creator(creator, RTCS_OK);
        httpd_ses_poll((HTTPD_STRUCT*)init_ptr, session);
    }
    else
        goto ERROR;
    
    return;
    
ERROR:
    RTCS_task_resume_creator(creator, RTCS_ERROR);
}

/** create task for session
 * \param server < pointer to server structure
 * \param stack < stack size for session task
 * \return
 */
static uint_32 httpd_session_static_task_create(HTTPD_STRUCT *server) {
    return RTCS_task_create("httpd session", HTTPDCFG_DEF_SERVER_PRIO , server->params->ses_stack, httpd_session_static_task, server);
}

/** run httpd server - each session run in separete task
 * \param server < pointer to server structure
 * \return zero if success
 */
_mqx_int httpd_server_run(HTTPD_STRUCT *server) {
    _mqx_int ses_cnt = server->params->max_ses;
    
    // try create task per session
    while (server && ses_cnt) {
        if (httpd_session_static_task_create(server) != RTCS_OK)
            break;  // task creation failed, stop
        
        ses_cnt--;
    }
    
    return (ses_cnt);
}

#else // HTTPDCFG_STATIC_TASKS

static LWSEM_STRUCT sem_session_counter;

static void httpd_session_dynamic_task(pointer init_ptr, pointer creator) 
{

    
    
    HTTPD_SES_TASK_PARAM *param = (HTTPD_SES_TASK_PARAM*)init_ptr;
    HTTPD_SESSION_STRUCT *session;
    
    HTTPD_ASSERT(init_ptr);
    
    HTTPD_DEBUG(1, "session task start\n");
    
    session = httpd_ses_alloc(param->server);
    
    if (session) 
    {
        RTCS_task_resume_creator(creator, RTCS_OK);
        
        HTTPD_DEBUG(1, "session task run...\n");
        
        httpd_ses_init(param->server, session, param->sock);
    
        while (HTTPD_SESSION_VALID == session->valid) 
        {
            httpd_ses_process(param->server, session);
        }
    
        httpd_ses_free(session);
    }
    else 
    {
        RTCS_task_resume_creator(creator, (uint_32) RTCS_ERROR);
    }
    
    HTTPD_FREE(init_ptr);
    
    _lwsem_post(&sem_session_counter);
    
    HTTPD_DEBUG(1, "session task stop\n");
}

/** server task - httpd main task which create new task for each new request
 */
static void httpd_server_task(pointer init_ptr, pointer creator) 
{
    HTTPD_STRUCT *server = (HTTPD_STRUCT*)init_ptr;
    int s;
    unsigned short len;
    uint_32 connsock; //socket with connection
    struct sockaddr sin;
    
    HTTPD_SES_TASK_PARAM *param;
    _mqx_uint res;
    uint_32 stack;
 
    HTTPD_DEBUG(1, "server task start\n");
      
    res = _lwsem_create(&sem_session_counter, server->params->max_ses);

    if (!server && res != MQX_OK)
        goto ERROR;
        
    RTCS_task_resume_creator(creator, RTCS_OK);
    
    HTTPD_DEBUG(1, "server task run...\n");

    while (server->run) 
    {
        // limit maximal opened sessions
        _lwsem_wait(&sem_session_counter);
        
        // allocate session task parameter structure
        param = _mem_alloc_system(sizeof(HTTPD_SES_TASK_PARAM));
        
        if (param) 
        {
            param->server = server;
            connsock = RTCS_selectset(&(server->sock_v4), 2, 0);
            param->sock = accept(connsock,(sockaddr *) &sin, &len);
            /* Check if accept returned valid socket */
            if (param->sock != RTCS_SOCKET_ERROR)
            {
                // try create task for session
                res = RTCS_task_create("httpd session", server->params->ses_prio, server->params->ses_stack, httpd_session_dynamic_task, param);

                if (MQX_OK != res)
                {
                    // session task creation failed, clean and wait...
                    shutdown(param->sock, FLAG_ABORT_CONNECTION);   // abort opened connection
                    _mem_free(param);
                    _lwsem_post(&sem_session_counter);
                    _time_delay(1);
                }
            }
            else
            {
                // accept return error, clean and wait, then try again...
                _mem_free(param);
                _lwsem_post(&sem_session_counter);
                _time_delay(1);
            }
        }
        else
        {
            // allocation failed ?!?!? wait some time
            _time_delay(100);
        }
    }
    
    HTTPD_DEBUG(1, "server task stop\n");
    
ERROR:
    RTCS_task_resume_creator(creator, (uint_32)RTCS_ERROR);
}

/** create httpd server task - 
 * \param server < pointer to server structure
 * \return
 */
static uint_32 httpd_server_task_create(HTTPD_STRUCT *server) {
    return RTCS_task_create("httpd server", server->params->server_prio, server->params->server_stack, httpd_server_task, server);
}

/** run httpd server in 
 * \param server < pointer to server structure
 * \return zero if success
 */
_mqx_int httpd_server_run(HTTPD_STRUCT *server) {
    HTTPD_ASSERT(server);
    
    if (server && httpd_server_task_create(server) == RTCS_OK)
        return 0;
    
    return -1;
}

#endif // HTTPDCFG_STATIC_TASKS

/** stop httpd server
 * \param server < pointer to server structure
 * \return zero if success
 */
_mqx_int httpd_server_stop(HTTPD_STRUCT *server) {
    HTTPD_ASSERT(server);

    server->run = 0;
    
    return httpd_release(server);   
}

#endif // !HTTPDCFG_POLL_MODE


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/icmp_prv.h<|end_filename|>
#ifndef __icmp_prv_h__
#define __icmp_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: icmp_prv.h$
* $Version : 3.0.6.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   Private definitions for the ICMP protocol layer.
*
*END************************************************************************/

#include "ip_prv.h"     /* For IP_HEADER */


/***************************************
**
** Code macros
**
*/

#define ICMPTYPE_ISQUERY(t)   (((t) == ICMPTYPE_ECHO_REPLY) \
                            || ((t) == ICMPTYPE_ECHO_REQ)   \
                            || (((t) >= ICMPTYPE_TIME_REQ) && ((t) <= ICMPTYPE_AM_REPLY)))


#if RTCSCFG_ENABLE_ICMP_STATS 
   #define IF_ICMP_STATS_ENABLED(x) x
#else
   #define IF_ICMP_STATS_ENABLED(x)
#endif


/***************************************
**
** Type definitions
**
*/

/*
** Generic ICMP packet header
*/
typedef struct icmp_header
{
   uchar    TYPE[1];
   uchar    CODE[1];
   uchar    CHECKSUM[2];
} ICMP_HEADER, _PTR_ ICMP_HEADER_PTR;

/*
** ICMP Redirect packet
*/
typedef struct icmp_err_header
{
   ICMP_HEADER HEAD;
   uchar       DATA[4];
   IP_HEADER   IP;
} ICMP_ERR_HEADER, _PTR_ ICMP_ERR_HEADER_PTR;

/*
** ICMP Echo packet
*/
typedef struct icmp_echo_header
{
   ICMP_HEADER HEAD;
   uchar       ID[2];
   uchar       SEQ[2];
} ICMP_ECHO_HEADER, _PTR_ ICMP_ECHO_HEADER_PTR;

/*
** ICMP Configuration.  This information is persistent for the ICMP layer.
*/
typedef struct icmp_cfg_struct {
#if RTCSCFG_ENABLE_ICMP_STATS
   ICMP_STATS     STATS;
#endif
   ICMP_PARM_PTR  ECHO_PARM_HEAD;
   uint_16        ECHO_SEQ;
   uint_16        RESERVED;

} ICMP_CFG_STRUCT, _PTR_ ICMP_CFG_STRUCT_PTR;


/***************************************
**
** Prototypes
**
*/

extern void ICMP_send_error_internal
(
   uint_8         type,    /* [IN] the type to send */
   uint_8         code,    /* [IN] the code to send */
   uint_32        param,   /* [IN] the icmp parameter */
   IP_HEADER_PTR  iph,     /* [IN] the IP header */
   RTCSPCB_PTR    origpcb, /* [IN] the bad packet pcb */
   uint_32        maxlen   /* [IN[ the max data len to send, 0 = default */
);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/fio_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: fio_prv.h$
* $Version : 3.8.8.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file includes the private definitions for the formatted I/O .
*
*END************************************************************************/
#ifndef __fio_prv_h__
#define __fio_prv_h__

/*--------------------------------------------------------------------------*/
/*
 *  Compiler Dependencies
 *
 *  Most compilers have adequate modf and strtod functions
 */
#ifdef NEED_MODF
#define  modf       _io_modf
#endif
#ifdef NEED_STRTOD
#define  strtod     _io_strtod
#endif

/*--------------------------------------------------------------------------*/
/*
 *                            CONSTANT DEFINITIONS
 */

/* 
 * Type definitions also used for sizing by doprint 
 * They are the maximum string size that a 32/64 bit number 
 * can be displayed as. 
 */
#define _MQX_IO_DIVISION_ADJUST_64 1000000000000000000LL
#define PRINT_OCTAL_64   (22L)
#define PRINT_DECIMAL_64 (20L)
#define PRINT_HEX_64     (16L)

#define _MQX_IO_DIVISION_ADJUST 1000000000L
#define PRINT_OCTAL   (11L)
#define PRINT_DECIMAL (10L)
#define PRINT_HEX     (8L)

#define PRINT_ADDRESS (8L)

/* Type definitions use in the control of scanline */

#define SCAN_ERROR    (-1)
#define SCAN_LLONG    (0)
#define SCAN_WLONG    (1)
#define SCAN_BLONG    (2)
#define SCAN_MLONG    (3)


/*--------------------------------------------------------------------------*/
/*
 *                            FUNCTION PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_int _io_doprint(MQX_FILE_PTR, IO_PUTCHAR_FPTR, _mqx_int max_count, char _PTR_, va_list);
extern _mqx_int _io_sputc(_mqx_int, MQX_FILE_PTR);
extern _mqx_int _io_scanline(char _PTR_, char _PTR_, va_list);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/sotcp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sotcp.c$
* $Version : 3.0.4.0$
* $Date    : Mar-5-2009$
*
* Comments:
*
*   This file contains the implementation of getsockopt()
*   and setsockopt() at the SOL_TCP level.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"

#if RTCSCFG_ENABLE_TCP

#define RTCS_ENTER(f,a) RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_TCP_ ## f, a)

#define RTCS_EXIT(f,a)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_TCP_ ## f, a); \
                        return a


uint_32 SOL_TCP_getsockopt (uint_32, uint_32, uint_32, pointer, uint_32 _PTR_);
uint_32 SOL_TCP_setsockopt (uint_32, uint_32, uint_32, pointer, uint_32);

const RTCS_SOCKOPT_CALL_STRUCT SOL_TCP_CALL = {
   SOL_TCP_getsockopt,
   SOL_TCP_setsockopt
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_TCP_getsockopt
* Returned Value  : error code
* Comments  :  Obtain the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_TCP_getsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] buffer for the current value of the option */
      uint_32  _PTR_ optlen
         /* [IN/OUT] length of the option value, in bytes */
   )
{ /* Body */
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;

   RTCS_ENTER(GETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   *(uint_32_ptr)optval = ((uint_32_ptr)&socket_ptr->CONNECT_TIMEOUT)[optname-1];
   *optlen = sizeof(uint_32);

   RTCS_EXIT(GETSOCKOPT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_TCP_setsockopt
* Returned Value  : error code
* Comments  :  Routine is used to modify the current socket options.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_TCP_setsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] new value for the option */
      uint_32        optlen
         /* [IN] length of the option value, in bytes */
   )
{ /* Body */
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;

   RTCS_ENTER(SETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   ((uint_32_ptr)&socket_ptr->CONNECT_TIMEOUT)[optname-1] = *(uint_32_ptr)optval;

   RTCS_EXIT(SETSOCKOPT, RTCS_OK);

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd_types.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd_types.h$
* $Version : 3.8.17.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   HTTPD type definitions.
*
*END************************************************************************/

#ifndef HTTPD_TYPES_H_
#define HTTPD_TYPES_H_

#include "user_config.h"

#include "httpd_cnfg.h"
#include "httpd_wrapper.h"
#include "httpd_mqx.h"

#ifndef HTTPD_DBG_LEV
#define HTTPD_DBG_LEV                       0       // http debug info level ( 0 - 4 )
#endif

/** http debug macro
 */
#if HTTPD_DBG_LEV > 0

#define HTTPD_DEBUG(lev, ...)   {           \
    if (lev <= HTTPD_DBG_LEV)   {           \
        HTTPD_TIME_STRUCT time;             \
        HTTPD_GET_TIME(&time);              \
        printf("HTTP (%u) - %4d.%3d: ", lev, time.SECONDS, time.MILLISECONDS);          \
        printf(__VA_ARGS__);                \
    }                                       \
}

#define HTTPD_ASSERT(cond) {                \
    if (!(cond)) while(1) {};                   \
}

#else
#define HTTPD_DEBUG(lev, ...)           {}
#define HTTPD_ASSERT(cond)              {}
#endif

#define HTTPD_SESSION_VALID             1
#define HTTPD_SESSION_INVALID           0

/** http state machine status
 */
typedef enum httpd_ses_state {
    HTTPD_SES_WAIT_REQ,
    HTTPD_SES_PROCESS_REQ,
    HTTPD_SES_END_REQ,
    HTTPD_SES_CLOSE,
    HTTPD_SES_RESP
} HTTPD_SES_STATE;

/** http request method type
 */
typedef enum httpd_req_method {
    HTTPD_REQ_UNKNOWN,
    HTTPD_REQ_GET,
    HTTPD_REQ_POST
} HTTPD_REQ_METHOD;

/** http content type
 */
typedef enum httpd_content_type {
    CONTENT_TYPE_PLAIN,
    CONTENT_TYPE_HTML,
    CONTENT_TYPE_CSS,
    CONTENT_TYPE_GIF,
    CONTENT_TYPE_JPG,
    CONTENT_TYPE_PNG,
    CONTENT_TYPE_JS,
    CONTENT_TYPE_OCTETSTREAM
} HTTPD_CONTENT_TYPE;

/** http request parameters
 */
typedef struct httpd_req_struct {
    HTTPD_REQ_METHOD method;
    char *path;
    char *urldata;

    _mqx_int content_len;

    char *auth;
    char *authPasswd;
} HTTPD_REQ_STRUCT;

/** http response parameters
 */
typedef struct httpd_res_struct {
    HTTPD_FILE *file;                   ///< file node for send
    char hdrsent;                       ///< 1 - header sended
    _mqx_int statuscode;                ///< status code - http_sendhdr transform it to text
    HTTPD_CONTENT_TYPE contenttype;     ///< content type
    char header[HTTPDCFG_MAX_HEADER_LEN + 1];

    char script_token;
    char *data;
    _mqx_int len;
} HTTPD_RES_STRUCT;


/** http session structure
 */
typedef struct httpd_session_struct {
    HTTPD_SES_STATE state;      ///< http session state
    _mqx_int valid;             ///< non zero (1) = session is valid - data in this entry is valid
    _mqx_uint keep_alive;       ///< connection Persistance
    _mqx_int sock;              ///< used socket

    HTTPD_REQ_STRUCT request;
    HTTPD_RES_STRUCT response;
    _mqx_int header;
    _mqx_int req_lines;
    _mqx_int remain;
    HTTPD_TIME_STRUCT time;     ///< state start time in ticks.

#if HTTPDCFG_POLL_MODE
    char recv_buf[HTTPDCFG_RECV_BUF_LEN + 1];
    char *recv_rd;
    _mqx_int recv_used;
    char *line;
    _mqx_int line_used;
#endif    
} HTTPD_SESSION_STRUCT;

typedef struct httpd_root_dir_struct {
    char *alias;
    char *path;
} HTTPD_ROOT_DIR_STRUCT;

/** CGI callback function - script can evaluate content data.
 * Function is called until remain content data or until script return error (<0)
 * return < 0 if error or evaluated data length
 */
typedef _mqx_int(*CGI_CALLBACK)(HTTPD_SESSION_STRUCT*);

/** CGI function link - script associate name with function.
 * Request for script is always scriptname.cgi, but name in table is without extension.
 */
typedef struct httpd_cgi_link_struct {
    char cgi_name[HTTPDCFG_MAX_SCRIPT_LN + 1];
    CGI_CALLBACK callback;
} HTTPD_CGI_LINK_STRUCT;

/**
 */
typedef void(*FN_CALLBACK)(HTTPD_SESSION_STRUCT*);

/** call function link - dynamic web.
 */
typedef struct httpd_fn_link_struct {
    char fn_name[HTTPDCFG_MAX_SCRIPT_LN + 1];
    FN_CALLBACK callback;
} HTTPD_FN_LINK_STRUCT;

/** Authentification callback function.
 * Callback return 0 if authorization is correct.
 */
typedef _mqx_int(*HTTPD_AUTH_CALLBACK)(HTTPD_SESSION_STRUCT*);

/** http server parameters
 */
typedef struct httpd_params_struct {
    unsigned short port;            ///< listening port
    _ip_address  address;
  
  #if RTCSCFG_ENABLE_IP6    
     in6_addr  ipv6_address;     /* variable has IPv6 address */
     uint_32   if_scope_id;      /* server interface number  */
  #endif
     uint_16   af;               /* Inet family               */
         
    _mqx_uint max_uri;           ///< maximal URI length
    _mqx_uint max_auth;          ///< maximal auth length
    _mqx_uint max_ses;           ///< sessions count

#if HTTPDCFG_POLL_MODE  
    _mqx_uint max_line;          ///< maximal line length
#endif

    HTTPD_ROOT_DIR_STRUCT *root_dir;        ///< pointer root dir structure
    char *index_page;               ///< index page full path and name

    // callback functions
    HTTPD_CGI_LINK_STRUCT *cgi_lnk_tbl; ///< cgi callback table
    HTTPD_FN_LINK_STRUCT *fn_lnk_tbl;   ///< function callback table (dynamic web pages)
    HTTPD_AUTH_CALLBACK auth_fn;    ///< callback for authentification

    char *page401;
    char *page403;
    char *page404;

    uint_32 server_prio;
    uint_32 server_stack;    
#if !HTTPDCFG_POLL_MODE
    uint_32 ses_prio;    
    uint_32 ses_stack;
#endif    
} HTTPD_PARAMS_STRUCT;

/** http server main structure.
 */
typedef struct httpd_struct {
    HTTPD_PARAMS_STRUCT *params;            ///< pointer to server parameters

    // runtime data
    _mqx_int sock;                          ///< listening socket
    /* !!
    ** Do not change order of following two variables (sock_v4 and sock_v6)
    ** sock_v6 MUST always follow sock_v4.
    ** !!*/
    _mqx_int sock_v4;                       ///< listening socket v4
    _mqx_int sock_v6;                       ///< listening socket v6       
    _mqx_int run;                           ///< run flag
    HTTPD_SESSION_STRUCT **session;         ///< pointers array to session
} HTTPD_STRUCT;


#endif  // HTTPD_TYPES_H_


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/timer.h<|end_filename|>
/*HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer.h$
* $Version : 3.0.5.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   timer component.
*
*END************************************************************************/
#ifndef __timer_h__
#define __timer_h__ 1

#include <mqx_cnfg.h>
#if (! MQX_USE_TIMER) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error TIMER component is currently disabled in MQX kernel. Please set MQX_USE_TIMER to 1 in user_config.h and recompile kernel.
#endif

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* 
 * This mode tells the timer to use the elapsed time when calculating time 
 * (_time_get_elapsed)
 */
#define TIMER_ELAPSED_TIME_MODE       (1)

/* 
 * This mode tells the timer to use the actual time when calculating time
 * (_time_get)  Note that the time returned by _time_get can be modified
 * by _time_set.
 */
#define TIMER_KERNEL_TIME_MODE        (2)

/* The error return from the timer start functions */
#define TIMER_NULL_ID                 ((_timer_id)0)

/* The default parameters for the timer_create_component function */
#define TIMER_DEFAULT_TASK_PRIORITY   (1)
#define TIMER_DEFAULT_STACK_SIZE      (800)

/*--------------------------------------------------------------------------*/
/*                     DATA STRUCTURE DEFINITIONS                           */

typedef _mqx_uint  _timer_id;

/*--------------------------------------------------------------------------*/
/*
 *                    TYPEDEFS FOR _CODE_PTR_ FUNCTIONS
 */
typedef void (_CODE_PTR_  TIMER_NOTIFICATION_TIME_FPTR)( _timer_id, pointer, uint_32, uint_32);
typedef void (_CODE_PTR_  TIMER_NOTIFICATION_TICK_FPTR)( _timer_id, pointer, MQX_TICK_STRUCT_PTR);

/*--------------------------------------------------------------------------*/
/*                       EXTERNAL DECLARATIONS                              */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint  _timer_cancel(_timer_id);
extern _mqx_uint  _timer_create_component(_mqx_uint, _mqx_uint);
extern _timer_id  _timer_start_oneshot_after(
   TIMER_NOTIFICATION_TIME_FPTR, pointer, _mqx_uint, uint_32);
extern _timer_id  _timer_start_oneshot_at( 
   TIMER_NOTIFICATION_TIME_FPTR, pointer, _mqx_uint, TIME_STRUCT_PTR);        
extern _timer_id  _timer_start_periodic_every( 
   TIMER_NOTIFICATION_TIME_FPTR, pointer, _mqx_uint, uint_32);        
extern _timer_id  _timer_start_periodic_at( 
   TIMER_NOTIFICATION_TIME_FPTR, pointer, _mqx_uint, TIME_STRUCT_PTR, uint_32);
extern _timer_id  _timer_start_oneshot_after_ticks(
   TIMER_NOTIFICATION_TICK_FPTR, pointer, _mqx_uint, MQX_TICK_STRUCT_PTR);
extern _timer_id  _timer_start_oneshot_at_ticks( 
   TIMER_NOTIFICATION_TICK_FPTR, pointer, _mqx_uint, MQX_TICK_STRUCT_PTR);        
extern _timer_id  _timer_start_periodic_every_ticks( 
   TIMER_NOTIFICATION_TICK_FPTR, pointer, _mqx_uint, MQX_TICK_STRUCT_PTR);        
extern _timer_id  _timer_start_periodic_at_ticks( 
   TIMER_NOTIFICATION_TICK_FPTR, pointer, _mqx_uint,
   MQX_TICK_STRUCT_PTR, MQX_TICK_STRUCT_PTR);
extern _mqx_uint  _timer_test(pointer _PTR_);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010-2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio.h$
* $Version : 3.8.8.0$
* $Date    : Sep-22-2011$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/
#ifndef __lwgpio_h__
#define __lwgpio_h__ 1

#include <mqx.h>

#ifdef __cplusplus
extern "C" {
#endif

/* Type holding pin ID */
typedef uint_32 LWGPIO_PIN_ID;

/* Type holding pin direction */
typedef enum {
    LWGPIO_DIR_INPUT,
    LWGPIO_DIR_OUTPUT,
    /* special value; for function parameters it means that value should not be changed */
    LWGPIO_DIR_NOCHANGE
} LWGPIO_DIR; 

/* Type holding pin value */
typedef enum {
    LWGPIO_VALUE_LOW,
    LWGPIO_VALUE_HIGH,
    /* special value; for function parameters it means that value should not be changed */
    LWGPIO_VALUE_NOCHANGE
} LWGPIO_VALUE;

/* Type identifying pin interrupt mode */
#ifndef LWGPIO_INT_MODE_NONE
    #define LWGPIO_INT_MODE_NONE    (0x00)
#endif
#ifndef LWGPIO_INT_MODE_RISING
    #define LWGPIO_INT_MODE_RISING  (0x01)
#endif
#ifndef LWGPIO_INT_MODE_FALLING
    #define LWGPIO_INT_MODE_FALLING (0x02)
#endif
#ifndef LWGPIO_INT_MODE_HIGH
    #define LWGPIO_INT_MODE_HIGH    (0x04)
#endif
#ifndef LWGPIO_INT_MODE_LOW
    #define LWGPIO_INT_MODE_LOW     (0x08)
#endif

/* Pin attributes*/
#define LWGPIO_ATTR_PULL_UP         (1)
#define LWGPIO_ATTR_PULL_DOWN       (2)
#define LWGPIO_ATTR_OPEN_DRAIN      (3)

/*attributes value*/
#define LWGPIO_AVAL_ENABLE          (1)
#define LWGPIO_AVAL_DISABLE         (0)

typedef uchar LWGPIO_INT_MODE;

boolean lwgpio_init(LWGPIO_STRUCT_PTR, LWGPIO_PIN_ID, LWGPIO_DIR, LWGPIO_VALUE);
void lwgpio_set_functionality(LWGPIO_STRUCT_PTR, uint_32);
boolean lwgpio_set_attribute(LWGPIO_STRUCT_PTR, uint_32, uint_32);
uint_32 lwgpio_get_functionality(LWGPIO_STRUCT_PTR);
void lwgpio_set_direction(LWGPIO_STRUCT_PTR, LWGPIO_DIR);
void lwgpio_set_value(LWGPIO_STRUCT_PTR, LWGPIO_VALUE);
void lwgpio_toggle_value(LWGPIO_STRUCT_PTR);
LWGPIO_VALUE lwgpio_get_value(LWGPIO_STRUCT_PTR);
LWGPIO_VALUE lwgpio_get_raw(LWGPIO_STRUCT_PTR);

boolean lwgpio_int_init(LWGPIO_STRUCT_PTR, LWGPIO_INT_MODE);
uint_32 lwgpio_int_get_vector(LWGPIO_STRUCT_PTR);
void lwgpio_int_enable(LWGPIO_STRUCT_PTR, boolean);
boolean lwgpio_int_get_flag(LWGPIO_STRUCT_PTR);
void lwgpio_int_clear_flag(LWGPIO_STRUCT_PTR);

extern boolean lwgpio_set_pin_output(LWGPIO_PIN_ID, LWGPIO_VALUE);
extern boolean lwgpio_toggle_pin_output(LWGPIO_PIN_ID);
extern LWGPIO_VALUE lwgpio_get_pin_input(LWGPIO_PIN_ID);

#ifdef __cplusplus
}
#endif

#endif /* __lwgpio_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_mii.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_mii.c$
* $Version : 3.8.8.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the MACNET MII Interface functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "macnet_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_mii_enabled
*  Returned Value : boolean
*  Comments       :
*    We can only read the PHY registers if the PHY is enabled
*
*END*-----------------------------------------------------------------*/

static boolean MACNET_mii_enabled
   (
		   ENET_MemMapPtr macnet_ptr
   )
{  
   return (macnet_ptr->MSCR & 0x7E) != 0;
} 

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_read_write_mii
*  Returned Value : TRUE and MII Data register value, FALSE if timeout
*  Comments       :
*    Return entire MII data register value
*
*END*-----------------------------------------------------------------*/

static boolean MACNET_read_write_mii
   (
      ENET_MemMapPtr             macnet_ptr,
      uchar                      phy_addr,
      uint_32                    reg_index,
      uint_32                    op,
      uint_32                    write_data,
      uint_32_ptr                read_data_ptr,
      uint_32                    timeout
   )
{
   uint_32                    tm;
    
   if (macnet_ptr == NULL) 
      return FALSE;
   
   if (!MACNET_mii_enabled(macnet_ptr))
        return FALSE;
    
   // Clear the MII interrupt bit 
   macnet_ptr->EIR = ENET_EIR_MII_MASK;

   // Kick-off the MII read or write operation 
   macnet_ptr->MMFR = (vuint_32)(0 
      | (ENET_MMFR_ST_MASK & (0x01 << ENET_MMFR_ST_SHIFT))
      | op
      | (ENET_MMFR_PA_MASK & (phy_addr << ENET_MMFR_PA_SHIFT))
      | (ENET_MMFR_RA_MASK & (reg_index << ENET_MMFR_RA_SHIFT))
      | (ENET_MMFR_TA_MASK & (0x02 << ENET_MMFR_TA_SHIFT))
      | (write_data & 0xffff));

    // Poll for MII complete
   for (tm = 0; tm < timeout; tm++)
   {
      if(macnet_ptr->EIR & ENET_EIR_MII_MASK)
         break;
      _time_delay(0);
   }

   if (tm != timeout) 
      if (read_data_ptr) 
         *read_data_ptr = (ENET_MMFR_DATA_MASK & (macnet_ptr->MMFR));

   // Clear the MII interrupt bit 
   macnet_ptr->EIR = ENET_EIR_MII_MASK;

   return (tm != timeout);
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_read_mii
*  Returned Value : TRUE and MII Data register value, FALSE if timeout
*  Comments       :
*    Return entire MII data register value
*
*END*-----------------------------------------------------------------*/

boolean MACNET_read_mii
    (
        ENET_CONTEXT_STRUCT_PTR enet_ptr,
        uint_32 reg_index,
        uint_32_ptr data,
        uint_32 timeout
    )
{
    MACNET_CONTEXT_STRUCT_PTR macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR)enet_ptr->MAC_CONTEXT_PTR;

    return MACNET_read_write_mii(macnet_context_ptr->PHY_PTR, enet_ptr->PHY_ADDRESS, reg_index, ENET_MMFR_OP_MASK & (0x02 << ENET_MMFR_OP_SHIFT), 0, data, timeout);
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_write_mii
*  Returned Value : TRUE if success, FALSE if timeout
*  Comments       :
*    Write MII data register value
*
*END*-----------------------------------------------------------------*/

boolean MACNET_write_mii
    (
        ENET_CONTEXT_STRUCT_PTR enet_ptr,
        uint_32 reg_index,
        uint_32 data,
        uint_32 timeout
    )
{
    MACNET_CONTEXT_STRUCT_PTR macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR)enet_ptr->MAC_CONTEXT_PTR;

    return MACNET_read_write_mii(macnet_context_ptr->PHY_PTR, enet_ptr->PHY_ADDRESS, reg_index, ENET_MMFR_OP_MASK & (0x01 << ENET_MMFR_OP_SHIFT), data, NULL, timeout);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mk40.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010-2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mk40.h$
* $Version : 3.8.15.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines for the internal 
*   flash driver.
*
*END************************************************************************/

#ifndef __flash_mk40_h__
#define __flash_mk40_h__

/* FlexNVM partition code values */
#define FLEXNVM_PART_CODE_DATA256_EE0       (0)
#define FLEXNVM_PART_CODE_DATA224_EE32      (3)
#define FLEXNVM_PART_CODE_DATA192_EE64      (4)
#define FLEXNVM_PART_CODE_DATA128_EE128     (5)
#define FLEXNVM_PART_CODE_DATA32_EE224      (0x0b)
#define FLEXNVM_PART_CODE_DATA64_EE192      (0x0c)
#define FLEXNVM_PART_CODE_DATA0_EE256       (8)
#define FLEXNVM_PART_CODE_NOPART            (0x0f)

/* FlexNVM EEPROM size values */
#define FLEXNVM_EE_SIZE_4096                (2)
#define FLEXNVM_EE_SIZE_2048                (3)
#define FLEXNVM_EE_SIZE_1024                (4)
#define FLEXNVM_EE_SIZE_512                 (5)
#define FLEXNVM_EE_SIZE_256                 (6)
#define FLEXNVM_EE_SIZE_128                 (7)
#define FLEXNVM_EE_SIZE_64                  (8)
#define FLEXNVM_EE_SIZE_32                  (9)
#define FLEXNVM_EE_SIZE_0                   (0x0f)

/* FlexNVM split values */
#define FLEXNVM_EE_SPLIT_1_7                (0)
#define FLEXNVM_EE_SPLIT_1_3                (0x10)
#define FLEXNVM_EE_SPLIT_1_1                (0x30)

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/
#ifdef __cplusplus
extern "C" {
#endif

pointer _bsp_get_ftfl_address(void);
void kinetis_flash_invalidate_cache(uint_32);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/tfs/tfs_prv.h<|end_filename|>
#ifndef __tfs_prv_h__
#define __tfs_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tfs_prv.h$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the structure definitions and constants
*   that are internal to the Embedded MS-DOS File System (TFS)
*
*END************************************************************************/


#include <tfs.h>


/* configuration data for the TFS */
typedef struct tfs_drive_struct
{
   char_ptr                 IDENTIFIER;
   const TFS_DIR_ENTRY      *ROOT;
  
} TFS_DRIVE_STRUCT, _PTR_ TFS_DRIVE_STRUCT_PTR;


/*
** extern statements for TFS
*/
#ifdef __cplusplus
extern "C" {
#endif

extern char_ptr TFS_Parse_Out_Device_Name (char_ptr);
extern int_32 TFS_Cmp (char_ptr, char_ptr);
extern pointer TFS_Open_File (TFS_DRIVE_STRUCT_PTR, char_ptr, uint_32_ptr);
extern uint_32 TFS_Read (MQX_FILE_PTR, uint_32, char_ptr, uint_32_ptr);
extern uint_32 TFS_Write (MQX_FILE_PTR, uint_32, char_ptr, uint_32_ptr);
extern uint_32 TFS_Move_File_Pointer (MQX_FILE_PTR, uint_32_ptr);
extern int_32 TFS_Close_File (MQX_FILE_PTR);
    
#ifdef __cplusplus
}
#endif

    
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ppphdlc.h<|end_filename|>
#ifndef __ppphdlc_h__
#define __ppphdlc_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ppphdlc.h$
* $Version : 3.8.11.0$
* $Date    : Aug-27-2012$
*
* Comments:
*
*   This file contains the defines, externs and data
*   structure definitions required by application
*   programs in order to use the PPPHDLC device.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include <fio.h>


/***************************************
**
** MQX compatibility
*/

#define _ppphdlc_mutex             LWSEM_STRUCT
#define PPPHDLC_mutex_init(p)      _lwsem_create_hidden(p,1)
#define PPPHDLC_mutex_destroy(p)   _lwsem_destroy(p)
#define PPPHDLC_mutex_lock(p)      _lwsem_wait(p)
#define PPPHDLC_mutex_unlock(p)    _lwsem_post(p)

#define PPPHDLC_memalloc      _mem_alloc_zero
#define PPPHDLC_memfree       _mem_free
#define PPPHDLC_memcopy       _mem_copy

#define _ppphdlc_partid       _rtcs_part
#define PPPHDLC_partcreate    RTCS_part_create
#define PPPHDLC_partdestroy   RTCS_part_destroy
#define PPPHDLC_partalloc     RTCS_part_alloc
#define PPPHDLC_partfree      RTCS_part_free

#define PPPHDLC_delay         _time_delay


/***************************************
**
** Constants
*/

#define PPPHDLC_FRAMESIZE_MAXDATA 1502    /* protocol(2) + data(1500) */
#define PPPHDLC_FRAMESIZE_FCS        2

/*
** Special PPPHDLC characters
*/

#define PPPHDLC_ESC     0x7D
#define PPPHDLC_FLAG    0x7E

#define PPPHDLC_ADDR    0xFF
#define PPPHDLC_CTRL    0x03

#define PPPHDLC_OK      0
#define PPPHDLC_END     1
#define PPPHDLC_ABORT   2

/*
** Size of the Async Control Character Map
*/

#define PPPHDLC_BITS_IN_UINT32  32
#define PPPHDLC_BITS_IN_ACCM    256


///* TBC */
//#ifndef RTCS_PRINT_PPP_PACKETS
//        #define RTCS_PRINT_PPP_PACKETS 0
//#endif


typedef struct ppphdlc_opt {
   uint_32           ACCM[PPPHDLC_BITS_IN_ACCM / PPPHDLC_BITS_IN_UINT32];
   boolean           PFC;
   boolean           ACFC;
} PPPHDLC_OPT, _PTR_ PPPHDLC_OPT_PTR;

extern PPPHDLC_OPT PPPHDLC_DEFAULT_OPTIONS;

typedef struct ppphdlc_stats {
   RTCS_STATS_STRUCT COMMON;

   uint_32  ST_RX_ABORTED;
   uint_32  ST_RX_RUNT;
   uint_32  ST_RX_GIANT;
   uint_32  ST_RX_BAD_ADDR;
   uint_32  ST_RX_BAD_CTRL;
   uint_32  ST_RX_BAD_FCS;

} PPPHDLC_STATS, _PTR_ PPPHDLC_STATS_PTR;


typedef struct ppphdlc_struct {
   struct _iopcb_table PCB_TABLE;
   PPPHDLC_STATS       STATS;
   _ppphdlc_partid     PART_ID;
   _ppphdlc_mutex      MUTEX;
   MQX_FILE_PTR        DEVICE;
   PPPHDLC_OPT         SEND_OPT;
   PPPHDLC_OPT         RECV_OPT;
   uint_16             FCS_SEND;
   uint_16             FCS_RECV;
   void (_CODE_PTR_    UP)(pointer);
   void (_CODE_PTR_    DOWN)(pointer);
   pointer             PARAM;

} PPPHDLC_STRUCT, _PTR_ PPPHDLC_STRUCT_PTR;


extern _iopcb_handle _iopcb_ppphdlc_init(MQX_FILE_PTR);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_join.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_join.c$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the Ethernet multicasting
*   support functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "enet.h"
#include "enetprv.h"
#include "macnet_prv.h"          

#if BSPCFG_ENABLE_ENET_MULTICAST

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_join
*  Returned Value : void
*  Comments       :
*        Joins a multicast group on an Ethernet channel.
*
*END*-----------------------------------------------------------------*/

uint_32 MACNET_join
   (
     ENET_CONTEXT_STRUCT_PTR  enet_ptr,
         /* [IN] the Ethernet state structure */
      ENET_MCB_STRUCT_PTR     mcb_ptr
         /* [IN] the multicast control block */
   )
{ 
   MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   ENET_MemMapPtr             macnet_ptr         = macnet_context_ptr->MACNET_ADDRESS;
   uint_32                    i,j,crc            = 0xFFFFFFFFL;
   
   if (macnet_ptr == NULL) return ENETERR_INVALID_DEVICE;

   /* Compute the CRC-32 polynomial on the multicast group */
   for (i=0; i<6; i++) {
      uchar c = mcb_ptr->GROUP[i];
      for (j=0; j<8; j++) {
         if ((c ^ crc) & 1) {
            crc >>= 1;
            c >>= 1;
            crc ^= 0xEDB88320L;
         } else {
            crc >>= 1;
            c >>= 1;
         }  
      } 
   }  

   /* Set the appropriate bit in the hash table */
   crc >>= 26;
   crc &= 0x3F;
   mcb_ptr->HASH = crc;

   if (crc < 32) {
      macnet_ptr->GALR |= 0x1 << (crc & 0x1F);
   } else {
      macnet_ptr->GAUR |= 0x1 << (crc & 0x1F);
   }  

   return ENET_OK;
} 

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/amd/29LV800BT.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: 29LV800BT.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains the block definitions for the AM29LV800BT
*   flash device.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"

/* Reference sector size */
#define AMD29LV800BT_SECTOR_SIZE     (0x4000 * BSP_FLASH_DEVICES)

#define AMD29LV800BT_NUM_SECTORS_0 (15) /* block 0 */
#define AMD29LV800BT_NUM_SECTORS_1 (1)  /* block 1 */
#define AMD29LV800BT_NUM_SECTORS_2 (2)  /* block 2 */
#define AMD29LV800BT_NUM_SECTORS_3 (1)  /* block 3 */

const FLASHX_BLOCK_INFO_STRUCT _29lv800bt_block_map_16bit[] =  {
    /* sectors per block        , offset                     ,  sector size */
    { AMD29LV800BT_NUM_SECTORS_0, (0),                          (4*AMD29LV800BT_SECTOR_SIZE)},/* 64K */
    { AMD29LV800BT_NUM_SECTORS_1, (0xF0000*BSP_FLASH_DEVICES),  (2*AMD29LV800BT_SECTOR_SIZE)},/* 32K */
    { AMD29LV800BT_NUM_SECTORS_2, (0xF8000*BSP_FLASH_DEVICES),  (AMD29LV800BT_SECTOR_SIZE/2)},/* 8K  */
    { AMD29LV800BT_NUM_SECTORS_3, (0xFC000*BSP_FLASH_DEVICES),  (AMD29LV800BT_SECTOR_SIZE)},  /* 16K */
    { 0, 0, 0 }
};

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_tkti.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       

*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_tkti.c$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*   This file contains the functions for converting between ticks and
*   the TIME_STRUCT format.
*
*END************************************************************************/

#include "mqx_inc.h"


/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_ticks_to_time
* Returned Value   : boolean - Returns FALSE is overflow occurs
* Comments         :
*    This function converts ticks into the time struct format
*
*END*----------------------------------------------------------------------*/

boolean _psp_ticks_to_time
   (
      /* [IN] Pointer to the tick struct to store the results in */
      PSP_TICK_STRUCT_PTR tick_ptr,

      /* [OUT] Pointer to the time struct to convert */
      TIME_STRUCT_PTR     time_ptr
   )
{ /* Body */
   uint_64                tmp;
   uint_32                tps;
   KERNEL_DATA_STRUCT_PTR kernel_data;

   _GET_KERNEL_DATA(kernel_data);

   tps = kernel_data->TICKS_PER_SECOND;

   /* Saturate if ticks go out of range of time struct */
   if ( (tick_ptr->TICKS[0] / tps) > MAX_UINT_32) {
      time_ptr->SECONDS      = MAX_UINT_32;
      time_ptr->MILLISECONDS = 999;
      return FALSE;
   } /* Endif */

   /* Recompute TICKS to milliseconds, together with HW_TICKS */
   tmp = (tick_ptr->TICKS[0] * 1000) + (tick_ptr->HW_TICKS[0] * 1000 / kernel_data->HW_TICKS_PER_TICK);
   tmp = tmp / tps;
 
   /* Compute seconds and remainder from milliseconds value */
   time_ptr->SECONDS      = tmp / 1000;
   time_ptr->MILLISECONDS = tmp - time_ptr->SECONDS * 1000;

   return TRUE;

} /* Endbody */

<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/ftpd_msg.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpd_msg.c$
* $Version : 3.8.9.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains an implementation of an
*   FTP server.
*
*END************************************************************************/


/* Response messages */
const char ftpmsg_sending[]   = "150 Opening data connection for RETR (%ld,%ld,%ld,%ld,%hd)\r\n";
const char ftpmsg_typeok[]    = "200 Type OK\r\n";
const char ftpmsg_portok[]    = "200 Port command okay\r\n";
const char ftpmsg_banner[]    = "220 RTCS FTP Server Ready\r\n";
const char ftpmsg_bye[]       = "221 Goodbye!\r\n";
const char ftpmsg_rxok[]      = "226 File received OK - %ld bytes in %ld.%03ld sec\r\n";
const char ftpmsg_txok[]      = "226 File sent OK - %ld bytes in %ld.%03ld sec\r\n";
const char ftpmsg_logged[]    = "230 Logged in\r\n";
const char ftpmsg_pass[]      = "<PASSWORD>, User logged in.\r\n";
const char ftpmsg_noconn[]    = "425 Data connection refused\r\n";
const char ftpmsg_writefail[] = "426 write error\r\n";
const char ftpmsg_writeeof[]  = "426 device full\r\n";
const char ftpmsg_badcmd[]    = "500 Unknown command\r\n";
const char ftpmsg_badtype[]   = "501 Unknown type \"%s\"\r\n";
const char ftpmsg_badport[]   = "501 Bad port syntax\r\n";
const char ftpmsg_badsyntax[] = "501 Incorrect command syntax\r\n";
const char ftpmsg_unimp[]     = "502 Command not implemented\r\n";
const char ftpmsg_cantopen[]  = "550 Can't open file \"%s\"\r\n";

const char ftpmsg_size[]            = "226 File size is %d.\r\n";
const char ftpmsg_syntax_error[]    = "501 Syntax error in parameters or arguments.\r\n";
const char ftpmsg_need_password[]   = "<PASSWORD>, need password.\<PASSWORD>";   
const char ftpmsg_not_logged[]      = "530 Not logged in.\r\n";
const char ftpmsg_goodbye[]         = "221 Goodbye.\r\n";
const char ftpmsg_no_fs[]           = "550 Requested action not taken. File system not mounted.\r\n";
const char ftpmsg_pasv_mode[]       = "227 Entering Passive Mode (%ld,%ld,%ld,%ld,%hd,%hd).\r\n";
const char ftpmsg_site_info[]       = "200 RTCS FTPd: No site specific information.\r\n";
const char ftpmsg_bad_option[]      = "501 Option not supported.\r\n";
const char ftpmsg_syst[]            = "215 MQX\r\n";
const char ftpmsg_help_start[]      = "214- The following commands are recognized:\r\n";
const char ftpmsg_help_end[]        = "214 Direct comments to Embedded Access Inc.\r\n";
const char ftpmsg_pwd_error[]       = "521 Error getting current directory.\r\n";
const char ftpmsg_cd_error[]        = "521 Error changing directory.\r\n";
const char ftpmsg_rmdir_error[]     = "521 Error removing directory.\r\n";
const char ftpmsg_delete_error[]    = "521 Error deleting file.\r\n";
const char ftpmsg_mkdir_error[]     = "521 Error creating directory.\r\n";
const char ftpmsg_ok[]              = "200 OK.\r\n";
const char ftpmsg_type_ascii[]      = "200 Type ASCII.\r\n";
const char ftpmsg_type_image[]      = "200 Type Binary.\r\n";
const char ftpmsg_type_unknown[]    = "501 Unknown type.\r\n";
const char ftpmsg_no_file[]         = "550 Requested action not taken. File unavailable.\r\n";
const char ftpmsg_opening_datacon[] = "150 Opening data connection.\r\n";
const char ftpmsg_tx_complete[]     = "226 Transfer complete.\r\n";
const char ftpmsg_no_datacon[]      = "425 Data connection refused.\r\n";
const char ftpmsg_no_memory[]       = "550 Requested action not taken. Memory unavailable.\r\n";

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/soselall.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: soselall.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the RTCS_selectall() implementation.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "socket.h"
#include "tcpip.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_selectall
* Returned Value  : socket handle
* Comments  :  Wait for data or connection requests on any socket
*      owned by this task.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_selectall
   (
      uint_32     timeout
         /* [IN] specifies the maximum amount of time to wait for data */
   )
{ /* Body */
   SOCKSELECT_PARM   parms;
   uint_32           error;

   parms.owner   = RTCS_task_getid();
   parms.timeout = timeout;
   error = RTCSCMD_issue(parms, SOCK_selectall);
   if (error) return RTCS_SOCKET_ERROR;

   return parms.sock;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_selectall
* Parameters      :
*
*     _rtcs_taskid      owner       [IN] socket owner
*     uint_32 _PTR_     sock_ptr    not used
*     uint_32           sock_count  not used
*     uint_32           timeout     [IN] timeout, 0=forever, -1=none
*     uint_32           sock        [OUT] socket with activity
*
* Comments  :  Wait for data or connection requests on any socket
*      owned by this task.
*
*END*-----------------------------------------------------------------*/

void SOCK_selectall
   (
      SOCKSELECT_PARM_PTR  parms
   )
{ /* Body */
   SOCKET_CONFIG_STRUCT_PTR   socket_cfg_ptr = RTCS_getcfg(SOCKET);
   SOCKET_STRUCT_PTR          socket_ptr;

   /* cycle through sockets looking for one owned by this task */
   for (socket_ptr = socket_cfg_ptr->SOCKET_HEAD;
        socket_ptr;
        socket_ptr = socket_ptr->NEXT) 
   {
      if (SOCK_Is_owner(socket_ptr, parms->owner)
         && SOCK_select_activity(socket_ptr, 0)) 
      {   
         break;
      } /* Endif */
   } /* Endfor */

   if (socket_ptr) 
   {
      parms->sock = (uint_32)socket_ptr;
      RTCSCMD_complete(parms, RTCS_OK);
      return;
   } /* Endif */

   if (parms->timeout == (uint_32)-1) 
   {
      parms->sock = 0;
      RTCSCMD_complete(parms, RTCS_OK);
      return;
   } /* Endif */

   SOCK_select_block(parms);

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mcf51em.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mcf51em.c$
* $Version : 3.8.7.0$
* $Date    : Oct-4-2011$
*
* Comments:
*
*   The file contains functions for internal flash read, write, erase 
*
*END************************************************************************/
#include "mqx.h"
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "flash_mcf51xx.h"
#include "flash_mcf51xx_prv.h"
#include "flash_mcf51em.h"

static void mcf51em_swap_flash_ram_end(void);
static void mcf51em_swap_flash_ram(VMCF51EM_RTC_STRUCT_PTR rtc_ptr);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_cfm_address
* Returned Value   : Address upon success
* Comments         :
*    This function returns the base register address of the FTSR
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_cfm_address(uchar fstr_set)
{
    if ( fstr_set == FSTR_SET_1) {    
        return (pointer)(&((VMCF51EM_STRUCT_PTR)BSP_IPSBAR)->FTSR1);
    } 
    /* FTSR_SET_2 */
    else {
        return (pointer)(&((VMCF51EM_STRUCT_PTR)BSP_IPSBAR)->FTSR2);
    }        
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_pmc_address
* Returned Value   : Address upon success
* Comments         :
*    This function returns the base register address of the PMC
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_pmc_address()
{
   return (pointer)(&((VMCF51EM_STRUCT_PTR)BSP_IPSBAR)->PMC);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mcf51em_get_rtc_cfg_state
* Returned Value   : Value of bit CFG0
* Comments         :
*    This function returns the value of RTC_CFG_DATA_CFG0.
*    There is stored information which flash bank is addressed from 0
*
*END*----------------------------------------------------------------------*/
uint_32 _mcf51_get_rtc_cfg_state()
{
    uint_32 result;
    
    if ( ( ((VMCF51EM_STRUCT_PTR)BSP_IPSBAR)->RTC.RTC_CFG_DATA ) & RTC_CFG_DATA_CFG0 ){    
        result = 1;
    } else {
        result = 0;
    }
    return result;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mcf51_swap_flash_and_reset
* Returned Value   : none
* Comments         :
*    Swap the flash adresses and restart device.
*
*END*----------------------------------------------------------------------*/
void _mcf51_swap_flash_and_reset()
{
    
    uchar_ptr ramcode_ptr = NULL;
    int_32 (*RunInRAM)( VMCF51EM_RTC_STRUCT_PTR );
    VMCF51EM_RTC_STRUCT_PTR rtc = _bsp_get_rtc_base_address ();
    
    /* Allocate space on stack to run flash command out of SRAM */
    ramcode_ptr = _mem_alloc((char*)mcf51em_swap_flash_ram_end - (char*)mcf51em_swap_flash_ram); 
    /* copy code to RAM buffer */
    _mem_copy((void*)mcf51em_swap_flash_ram, ramcode_ptr, (char*)mcf51em_swap_flash_ram_end  - (char*)mcf51em_swap_flash_ram);
    *RunInRAM = (int_32(*)( VMCF51EM_RTC_STRUCT_PTR ))ramcode_ptr;   

    /* start the swap flash sequence */
    _rtc_unlock();
    /* Run the code from RAM */
    RunInRAM( rtc );
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : mcf51em_swap_flash_ram
* Returned Value   : none
* Comments         :
*    Finish the swap of flash adresses and restart device. This function is
*    copied to RAM
*
*    WARNING! This code doesn't run correctly from debuger. If debuger is used,
*    instead reset jump to exception occured.
*
*END*----------------------------------------------------------------------*/
static void mcf51em_swap_flash_ram(VMCF51EM_RTC_STRUCT_PTR rtc_ptr) 
{
    void (_CODE_PTR_ jump_to_address)(void);
    uint_32 temp;

    /* disable flash speculation */
    _psp_set_cpucr(0x02000000);
    
    /* disable all interrupts */
    temp = _psp_get_sr();
    _psp_set_sr(temp | 0x0700);

    /* toggle RTC_CFG_DATA[CFG0] */
    rtc_ptr->RTC_CFG_DATA ^= 1;
    
    /* wait after write to RTC_CFG_DATA */
    _ASM_NOP();
    _ASM_NOP();
    _ASM_NOP();

    /* The processor generates a reset if CPUCR[ARD] = 0 */
    _psp_set_cpucr(0);
    
    /* reset using illegal address jump */
    jump_to_address = (void (_CODE_PTR_)(void))0x00804001;
    jump_to_address();

}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : mcf51em_swap_flash_ram_end
* Returned Value   : none
* Comments         :
*    End-mark function
*
*END*----------------------------------------------------------------------*/
static void mcf51em_swap_flash_ram_end(void) {}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mpc5643l.h<|end_filename|>
#include "flash_mpxs20.h"


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lpm/lpm.h<|end_filename|>

/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: lpm.h$
* $Version : 3.8.4.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   Low Power Manager header file.
*
*END************************************************************************/

#ifndef __lpm_h__
#define __lpm_h__

/*-------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

typedef enum {
    LPM_NOTIFICATION_TYPE_PRE,
    LPM_NOTIFICATION_TYPE_POST
} LPM_NOTIFICATION_TYPE;

typedef enum {
    LPM_NOTIFICATION_RESULT_OK,
    LPM_NOTIFICATION_RESULT_ERROR
} LPM_NOTIFICATION_RESULT;


/*-------------------------------------------------------------------------*/
/*
**                            MACRO DECLARATIONS
*/


/*-------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/

typedef struct lpm_notification_struct {
    /* When the notification happens */
    LPM_NOTIFICATION_TYPE   NOTIFICATION_TYPE;
    
    /* Current system operation mode */
    LPM_OPERATION_MODE      OPERATION_MODE;
    
    /* Current system clock configuration */
    BSP_CLOCK_CONFIGURATION CLOCK_CONFIGURATION;
    
} LPM_NOTIFICATION_STRUCT, _PTR_ LPM_NOTIFICATION_STRUCT_PTR;

typedef LPM_NOTIFICATION_RESULT (_CODE_PTR_ LPM_NOTIFICATION_CALLBACK)(LPM_NOTIFICATION_STRUCT_PTR, pointer);

typedef struct lpm_registration_struct {
    /* Callback called when system clock configuration changes */
    LPM_NOTIFICATION_CALLBACK CLOCK_CONFIGURATION_CALLBACK;

    /* Callback called when system operation mode changes */
    LPM_NOTIFICATION_CALLBACK OPERATION_MODE_CALLBACK;

    /* The order (priority) of notifications among other drivers */
    _mqx_uint                 DEPENDENCY_LEVEL;
   
} LPM_REGISTRATION_STRUCT, _PTR_ LPM_REGISTRATION_STRUCT_PTR;


/*-------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif


extern _mqx_uint                _lpm_install (const LPM_CPU_OPERATION_MODE _PTR_, LPM_OPERATION_MODE);
extern _mqx_uint                _lpm_uninstall (void);
extern _mqx_uint                _lpm_register_driver (const LPM_REGISTRATION_STRUCT_PTR, const pointer, _mqx_uint_ptr);
extern _mqx_uint                _lpm_unregister_driver (_mqx_uint);
extern _mqx_uint                _lpm_set_clock_configuration (BSP_CLOCK_CONFIGURATION);
extern BSP_CLOCK_CONFIGURATION  _lpm_get_clock_configuration (void);
extern _mqx_uint                _lpm_set_operation_mode (LPM_OPERATION_MODE);
extern LPM_OPERATION_MODE       _lpm_get_operation_mode (void);
extern _mqx_uint                _lpm_idle_sleep_setup (boolean);


#ifdef __cplusplus
}
#endif


#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/eds.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: eds.c$
* $Version : 172.16.17.32$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Source for the Embedded Debug Server.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_UDP

#define EDS_PORT          5002
#define EDS_TASK          10
#define EDS_BIG_ENDIAN    0L
#define EDS_LITTLE_ENDIAN 0xFFFFFFFF

/* server operations */
#define EDS_IDENTIFY 1L
#define EDS_READ     2L
#define EDS_WRITE    3L
#define EDS_LITTLE_ENDIAN_IDENTIFY 0x01000000

/* error codes */
#define EDS_INVALID_OP   1L
#define EDS_INVALID_SIZE 2L
#define EDS_OK           0L

/* structure declarations */
typedef struct eds_op_struct {
   uchar OPERATION[4];   /* server operation          */
   uchar ADDRESS[4];     /* read/write memory address */
   uchar ADDRESS2[4];    /* extra address field       */
   uchar SIZE[4];        /* size of buffer            */
   uchar PROCESSOR[4];   /* processor type            */
   uchar ENDIAN[4];      /* endian of processor       */
   uchar EDS_ERROR[4];   /* error code                */
} EDS_OP_STRUCT, _PTR_ EDS_OP_STRUCT_PTR;

/* macros */
#define EDS_OP_STRUCT_SIZE (sizeof(EDS_OP_STRUCT))
#define EDS_BUFFER_SIZE    (1472 - EDS_OP_STRUCT_SIZE)

#if (PSP_MEMORY_ADDRESSING_CAPABILITY == 8)

#define READ_BYTES(dest,src,size)   _mem_copy(dest,src,size)
#define WRITE_BYTES(dest,src,size)  _mem_copy(dest,src,size)

#elif (PSP_ENDIAN == MQX_BIG_ENDIAN)

#define READ_BYTES(src,dest,size) \
                              {\
                                 uint_32 i, j;\
                                 uint_32 _PTR_ src_lp;\
                                 uchar   _PTR_ dest_lp;\
                                 src_lp = (src);\
                                 dest_lp = (dest);\
                                 for(i=0;i<(size);i+=4) {\
                                    j = *src_lp++;\
                                    *dest_lp++ = (j >> 24) & 0xFF;\
                                    *dest_lp++ = (j >> 16) & 0xFF;\
                                    *dest_lp++ = (j >>  8) & 0xFF;\
                                    *dest_lp++ = (j)       & 0xFF;\
                                 }\
                              }

#define WRITE_BYTES(src,dest,size) \
                              {\
                                 uint_32 i;\
                                 uchar   _PTR_ src_lp;\
                                 uint_32 _PTR_ dest_lp;\
                                 src_lp = (src);\
                                 dest_lp = (dest);\
                                 for(i=0;i<(size);i+=4) {\
                                    *dest_lp++ = (((src_lp[0] & 0xFF) << 24) |\
                                                  ((src_lp[1] & 0xFF) << 16) |\
                                                  ((src_lp[2] & 0xFF) <<  8) |\
                                                  ((src_lp[3] & 0xFF)));\
                                    src_lp+=4;\
                                 }\
                              }

#else /* PSP_ENDIAN == MQX_LITTLE_ENDIAN */

#define READ_BYTES(src,dest,size) \
                              {\
                                 uint_32 i, j;\
                                 uint_32 _PTR_ src_lp;\
                                 uchar   _PTR_ dest_lp;\
                                 src_lp = (src);\
                                 dest_lp = (dest);\
                                 for(i=0;i<(size);i+=4) {\
                                    j = *src_lp++;\
                                    *dest_lp++ = (j)       & 0xFF;\
                                    *dest_lp++ = (j >>  8) & 0xFF;\
                                    *dest_lp++ = (j >> 16) & 0xFF;\
                                    *dest_lp++ = (j >> 24) & 0xFF;\
                                 }\
                              }
#define WRITE_BYTES(src,dest,size) \
                              {\
                                 uint_32 i;\
                                 uchar   _PTR_ src_lp;\
                                 uint_32 _PTR_ dest_lp;\
                                 src_lp = (src);\
                                 dest_lp = (dest);\
                                 for(i=0;i<(size);i+=4) {\
                                    *dest_lp++ = ((src_lp[0] & 0xFF)        |\
                                                 ((src_lp[1] & 0xFF) <<  8) |\
                                                 ((src_lp[2] & 0xFF) << 16) |\
                                                 ((src_lp[3] & 0xFF) << 24));\
                                    src_lp+=4;\
                                 }\
                              }

#endif


/* #define DEBUG  */   /* Uncomment to enable debug printfs */
#ifdef DEBUG
#define DEBUGM(x) x
#else
#define DEBUGM(x)
#endif


/* Start CR 1658 */
typedef struct eds_context  {
   uint_32     UDPSOCK;
   uint_32     LISTENSOCK;
   char _PTR_  BUFFER_PTR;
} EDS_CONTEXT, _PTR_ EDS_CONTEXT_PTR;

_rtcs_taskid EDS_task_id = 0;
//char _PTR_  buffer;

#ifdef __MQX__ 
void EDS_Exit_handler(void);
#endif
void EDS_Process_TCP_packet(uint_32, char _PTR_ );
void EDS_Process_UDP_packet(uint_32, char _PTR_);
/* End CR 1658 */
void EDS_Check_errors(EDS_OP_STRUCT_PTR);
void EDS_identify(EDS_OP_STRUCT_PTR);
void EDS_task_internal (pointer, pointer);

/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : EDS_init
* Returned Value   : error code
* Comments  :  Start the EDS task.
*
*END*-----------------------------------------------------------------*/

uint_32 EDS_init
   (
      char_ptr name,
      uint_32  priority,
      uint_32  stacksize
   )
{ /* Body */
   /* Start CR 1658 */
   if (EDS_task_id == 0)  {
      return RTCS_task_create(name, priority, stacksize, EDS_task_internal, NULL);
   } else  {
      return RTCSERR_SERVER_ALREADY_RUNNING;
   }
   /* End CR 1658 */
} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name    : EDS_task
* Returned Value   : none
* Comments  :  The Embedded Debug Server.
*
*END*-----------------------------------------------------------------*/

void EDS_task
   (
      uint_32 dummy
   )
{ /* Body */
   EDS_task_internal(NULL, NULL);
} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name    : EDS_task_internal
* Returned Value   : none
* Comments  :  The Embedded Debug Server.
*
*END*-----------------------------------------------------------------*/

void EDS_task_internal
   (
      pointer dummy,
      pointer creator
   )
{ /* Body */
   /* Start CR 1658 */
   sockaddr_in    laddr;
   EDS_CONTEXT    eds_context =  { 0 };
   uint_32        sock;
   uint_32        optval, optlen;
   uint_32        error;

   DEBUGM(printf("\nRTCS Embedded Debug Server");)

   EDS_task_id = RTCS_task_getid();
#ifdef __MQX__ 
   /* Set up exit handler and context so that we can clean up if EDS is terminated */
   _task_set_environment( _task_get_id(), (pointer) &eds_context );
   _task_set_exit_handler( _task_get_id(), EDS_Exit_handler );
#endif 
   
   eds_context.BUFFER_PTR = RTCS_mem_alloc_zero(EDS_BUFFER_SIZE);
   if (!eds_context.BUFFER_PTR) {
      DEBUGM(printf("\n_mem_alloc failed ");)
      RTCS_task_exit(creator, RTCSERR_OUT_OF_MEMORY);
   } /* Endif */
   _mem_set_type(eds_context.BUFFER_PTR, MEM_TYPE_EDS_BUFFER);

   laddr.sin_family      = AF_INET;
   laddr.sin_port        = EDS_PORT;
   laddr.sin_addr.s_addr = INADDR_ANY;

   /* Bind to UDP port */
   eds_context.UDPSOCK = socket(PF_INET, SOCK_DGRAM, 0);
   if (eds_context.UDPSOCK == RTCS_SOCKET_ERROR) {
      DEBUGM(printf("\nCreate datagram socket failed");)
      RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
   } /* Endif */
   error = bind(eds_context.UDPSOCK,(const sockaddr *) &laddr, sizeof(laddr));
   if (error != RTCS_OK) {
      DEBUGM(printf("\nDatagram bind failed - 0x%lx", error);)
      RTCS_task_exit(creator, error);
   } /* Endif */

   /* Listen on TCP port */
   eds_context.LISTENSOCK = socket(PF_INET, SOCK_STREAM, 0);
   if (eds_context.LISTENSOCK == RTCS_SOCKET_ERROR) {
      DEBUGM(printf("\nCreate stream socket failed");)
      RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
   } /* Endif */
   error = bind(eds_context.LISTENSOCK,(const sockaddr *) &laddr, sizeof(laddr));
   if (error != RTCS_OK) {
      DEBUGM(printf("\nStream bind failed - 0x%lx", error);)
      RTCS_task_exit(creator, error);
   } /* Endif */
   error = listen(eds_context.LISTENSOCK, 0);
   if (error != RTCS_OK) {
      DEBUGM(printf("\nListen failed - 0x%lx", error);)
      RTCS_task_exit(creator, error);
   } /* Endif */

   RTCS_task_resume_creator(creator, RTCS_OK);

   DEBUGM(printf("\n\nEmbedded Debug Server active (port %d)\n", EDS_PORT);)

   while (TRUE) {

      sock = RTCS_selectall(0);

      if (sock == eds_context.LISTENSOCK) {
         /* Connect received; issue ACCEPT on listening stream socket */
         sock = accept(eds_context.LISTENSOCK, NULL, NULL);
         if (sock == RTCS_SOCKET_ERROR) {
            DEBUGM(printf("\nAccept failed, error 0x%lx",
               RTCS_geterror(listensock));)
         } /* Endif */
         DEBUGM(printf("\nAccepted connection");)
      } else {
         /* Get the socket type */
         optlen = sizeof(optval);
         getsockopt(sock, SOL_SOCKET, OPT_SOCKET_TYPE, &optval, &optlen);

         if (optval == SOCK_STREAM) {
            EDS_Process_TCP_packet(sock, eds_context.BUFFER_PTR);
         } else {   /* optval == SOCK_DGRAM */
            EDS_Process_UDP_packet(sock, eds_context.BUFFER_PTR);
         } /* Endif */

      } /* Endif */
   } /* Endwhile */
   /* End CR 1658 */
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : EDS_Process_TCP_packet
* Returned Value : void
* Comments       : Receives a stream packet and processes it according to the
*                  client's request.
*
*END------------------------------------------------------------------*/

void EDS_Process_TCP_packet
(
   uint_32     sock,
   /* Start CR 1658 */
   char _PTR_  buffer
   /* End CR 1658 */
)
{ /* Body */
   EDS_OP_STRUCT_PTR      op_ptr;
   sockaddr_in            raddr;
   int_32                 length;
   uint_16                rlen;

   _mem_zero((char_ptr)&raddr, sizeof(raddr));
   rlen = sizeof(raddr);

   getpeername(sock,(sockaddr *)&raddr, &rlen);
   length = recv(sock, buffer, EDS_OP_STRUCT_SIZE, 0);
   if (length == RTCS_ERROR) {
     shutdown(sock, FLAG_CLOSE_TX);
     DEBUGM(printf("\nClosed connection to %d.%d.%d.%d, port %d",
        (raddr.sin_addr.s_addr >> 24) & 0xFF,
        (raddr.sin_addr.s_addr >> 16) & 0xFF,
        (raddr.sin_addr.s_addr >>  8) & 0xFF,
         raddr.sin_addr.s_addr        & 0xFF,
         raddr.sin_port);)
      return;
   } else {
      DEBUGM(printf("\n%d bytes received from %d.%d.%d.%d, port %d",
         length,
         (raddr.sin_addr.s_addr >> 24) & 0xFF,
         (raddr.sin_addr.s_addr >> 16) & 0xFF,
         (raddr.sin_addr.s_addr >>  8) & 0xFF,
          raddr.sin_addr.s_addr        & 0xFF,
          raddr.sin_port);)
   } /* Endif */

   op_ptr = (EDS_OP_STRUCT_PTR)buffer;

   EDS_Check_errors(op_ptr);
   if ((ntohl(op_ptr->EDS_ERROR)) != MQX_OK) {
      DEBUGM(printf("\nOperation error %d", op_ptr->EDS_ERROR);)
      send(sock, (char_ptr)op_ptr, (uint_32)EDS_OP_STRUCT_SIZE, 0);
   } else {
      /* Determine and handle client request */
      switch(ntohl(op_ptr->OPERATION)) {

         case EDS_IDENTIFY:
         case EDS_LITTLE_ENDIAN_IDENTIFY:
            EDS_identify(op_ptr);

            /* Send the identity */
            length = send(sock, (char_ptr)op_ptr, (uint_32)EDS_OP_STRUCT_SIZE, 0);
            if (length == RTCS_ERROR) {
               DEBUGM(printf("\n(error 0x%lx)", RTCS_geterror(sock));)
            } else {
               DEBUGM(printf("\n(%d bytes sent)", length);)
            } /* Endif */

            break;

         case EDS_READ:
            READ_BYTES((pointer)(ntohl(op_ptr->ADDRESS)),
            (pointer)&buffer[EDS_OP_STRUCT_SIZE], ntohl(op_ptr->SIZE));
            /* Send the result status and the data to read */
            length = send(sock, buffer, EDS_OP_STRUCT_SIZE + ntohl(op_ptr->SIZE), 0);
            if (length == RTCS_ERROR) {
               DEBUGM(printf("\n(error 0x%lx)", RTCS_geterror(sock));)
            } else {
               DEBUGM(printf("\n(%d bytes sent)", length);)
            } /* Endif */

            break;

         case EDS_WRITE:
            /* Write data directly to memory */
            length = recv(sock, (char_ptr)(&buffer[EDS_OP_STRUCT_SIZE]), ntohl(op_ptr->SIZE), 0);
            WRITE_BYTES((pointer)&buffer[EDS_OP_STRUCT_SIZE],
               (pointer)(ntohl(op_ptr->ADDRESS)), ntohl(op_ptr->SIZE));
            if (length == RTCS_ERROR) {
               DEBUGM(printf("\n(error 0x%lx)", RTCS_geterror(sock));)
            } else {
               DEBUGM(printf("\n%d bytes received from %d.%d.%d.%d, port %d",
                  length,
                  (raddr.sin_addr.s_addr >> 24) & 0xFF,
                  (raddr.sin_addr.s_addr >> 16) & 0xFF,
                  (raddr.sin_addr.s_addr >>  8) & 0xFF,
                   raddr.sin_addr.s_addr        & 0xFF,
                   raddr.sin_port);)
            } /* Endif */

            /* Send the result status */
            length = send(sock, (char_ptr)op_ptr, (uint_32)EDS_OP_STRUCT_SIZE,
               0);
            if (length == RTCS_ERROR) {
               DEBUGM(printf("\n(error 0x%lx)", RTCS_geterror(sock));)
            } else {
               DEBUGM(printf("\n(%d bytes sent)", length);)
            } /* Endif */

            break;

         default:
            break;
      } /* Endswitch */
   }/* Endif */
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : EDS_Process_UDP_packet
* Returned Value : void
* Comments       : Receives a datagram packet and processes it according to the
*                  client's request.
*
*END------------------------------------------------------------------*/

void EDS_Process_UDP_packet
(
   uint_32                   sock,
   /* Start CR 1658 */
   char _PTR_  buffer
   /* End CR 1658 */
)
{ /* Body */
   EDS_OP_STRUCT_PTR      op_ptr;
   sockaddr_in            raddr;
   uint_16                rlen;
   int_32                 length;

   _mem_zero((char_ptr)&raddr, sizeof(raddr));
   rlen = sizeof(raddr);

   length = recvfrom(sock, buffer, EDS_BUFFER_SIZE, 0, (sockaddr *)&raddr, &rlen);
   if (length == RTCS_ERROR) {
      DEBUGM(printf("\nError %d receiving from %d.%d.%d.%d, port %d",
         RTCS_geterror(sock),
         (raddr.sin_addr.s_addr >> 24) & 0xFF,
         (raddr.sin_addr.s_addr >> 16) & 0xFF,
         (raddr.sin_addr.s_addr >>  8) & 0xFF,
          raddr.sin_addr.s_addr        & 0xFF,
          raddr.sin_port);)
   } else {
      /* Success on receive */
      DEBUGM(printf("\nDatagram (%d bytes) received from %d.%d.%d.%d, port %d",
         length,
         (raddr.sin_addr.s_addr >> 24) & 0xFF,
         (raddr.sin_addr.s_addr >> 16) & 0xFF,
         (raddr.sin_addr.s_addr >>  8) & 0xFF,
          raddr.sin_addr.s_addr        & 0xFF,
          raddr.sin_port);)
   } /* Endif */

   op_ptr = (EDS_OP_STRUCT_PTR)buffer;

   EDS_Check_errors(op_ptr);
   if ((ntohl(op_ptr->EDS_ERROR)) != MQX_OK) {
      DEBUGM(printf("\nOperation error %d", op_ptr->EDS_ERROR);)
      sendto(sock, (char_ptr)op_ptr, (uint_32)EDS_OP_STRUCT_SIZE, 0, (sockaddr *)&raddr, rlen);
   } else {
      /* Determine and handle client request */
      switch(ntohl(op_ptr->OPERATION)) {

         case EDS_IDENTIFY:
         case EDS_LITTLE_ENDIAN_IDENTIFY:
            EDS_identify(op_ptr);

            length = sendto(sock, (char_ptr)op_ptr, (uint_32)EDS_OP_STRUCT_SIZE,
                            0, (sockaddr *)&raddr, rlen);
            if (length == RTCS_ERROR) {
               DEBUGM(printf("\n(error 0x%lx)", RTCS_geterror(sock));)
            } else {
               DEBUGM(printf("\n(%d bytes sent)", length);)
            } /* Endif */

            break;

         case EDS_READ:
            /* Copy data read into buffer */
            READ_BYTES((pointer)(ntohl(op_ptr->ADDRESS)),
            (pointer)&buffer[EDS_OP_STRUCT_SIZE], ntohl(op_ptr->SIZE));
            /* Send buffer */
            length = sendto(sock, buffer, EDS_OP_STRUCT_SIZE + ntohl(op_ptr->SIZE), 0,
                            (sockaddr *)&raddr, rlen);
            if (length == RTCS_ERROR) {
               DEBUGM(printf("\n(error 0x%lx)", RTCS_geterror(sock));)
            } else {
               DEBUGM(printf("\n(%d bytes sent)", length);)
            } /* Endif */

            break;

         case EDS_WRITE:
            /* Write received data into memory */
            WRITE_BYTES((pointer)&buffer[EDS_OP_STRUCT_SIZE],
               (pointer)(ntohl(op_ptr->ADDRESS)), ntohl(op_ptr->SIZE));

            /* Send the result status */
            length = sendto(sock, (char_ptr)op_ptr, (uint_32)EDS_OP_STRUCT_SIZE,
                            0, (sockaddr *)&raddr, rlen);
            if (length == RTCS_ERROR) {
               DEBUGM(printf("\n(error 0x%lx)", RTCS_geterror(sock));)
            } else {
               DEBUGM(printf("\n(%d bytes sent)", length);)
            } /* Endif */

            break;

         default:
            break;
      } /* Endswitch */
   } /* Endif */
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : EDS_Check_errors
* Returned Value : void
* Comments       : Determines if the client request is valid.
*
*END------------------------------------------------------------------*/

void EDS_Check_errors
(
   EDS_OP_STRUCT_PTR op_ptr
)
{ /* Body */
   /* Valid operation? */
   switch(ntohl(op_ptr->OPERATION)) {
      case EDS_IDENTIFY:
      case EDS_LITTLE_ENDIAN_IDENTIFY:
      case EDS_READ:
      case EDS_WRITE:
         htonl(op_ptr->EDS_ERROR,EDS_OK);
         break;
      default:
         htonl(op_ptr->EDS_ERROR,EDS_INVALID_OP);
         return;
   } /* Endswitch */

   /* Valid size? */
   if ((ntohl(op_ptr->OPERATION) == EDS_READ) || (ntohl(op_ptr->OPERATION) == EDS_WRITE)) {
      if (ntohl(op_ptr->SIZE) > (uint_32)EDS_BUFFER_SIZE) {
         htonl(op_ptr->EDS_ERROR,EDS_INVALID_SIZE);
      } else {
         htonl(op_ptr->EDS_ERROR,EDS_OK);
      } /* Endif */
   } /* Endif */
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : EDS_identify
* Returned Value : void
* Comments       : Fills in an OP_STRUCT containing the processor type, endian,
*                  start and end of kernel memory of this server, and the result
*                  status.
*
*END------------------------------------------------------------------*/

void EDS_identify
(
   EDS_OP_STRUCT_PTR op_ptr
)
{ /* Body */
#ifdef __MQX__
   /* Only useful if MQX is present */

   htonl(op_ptr->PROCESSOR,_mqx_get_cpu_type());
   htonl(op_ptr->ENDIAN, MSG_HDR_ENDIAN);
   htonl(op_ptr->ADDRESS,(uint_32)_mqx_get_initialization()->START_OF_KERNEL_MEMORY);
   htonl(op_ptr->ADDRESS2,(uint_32)_mqx_get_initialization()->END_OF_KERNEL_MEMORY);
#endif
} /* Endbody */

/* Start CR 1658 */
#ifdef __MQX__ 
/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : EDS_stop
* Returned Value   : error code
* Comments  :  Start the EDS task.
*
*END*-----------------------------------------------------------------*/

uint_32 EDS_stop( void )
{ /* Body */
   if (EDS_task_id == 0)  {
      return RTCSERR_SERVER_NOT_RUNNING;
   }
   RTCS_task_abort(EDS_task_id);
   EDS_task_id = 0;
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : EDS_Exit_handler
* Returned Value   : error code
* Comments  :  Start the EDS task.
*
*END*-----------------------------------------------------------------*/

void EDS_Exit_handler( void )
{ /* Body */
   EDS_CONTEXT_PTR    eds_context_ptr;
   
   eds_context_ptr = (EDS_CONTEXT_PTR) _task_get_environment( _task_get_id() );
   if (eds_context_ptr != NULL)  {
      if (eds_context_ptr->UDPSOCK)  {
         shutdown(eds_context_ptr->UDPSOCK, 0);
         eds_context_ptr->UDPSOCK = 0;   
      }   
      if (eds_context_ptr->LISTENSOCK)  {
         shutdown(eds_context_ptr->LISTENSOCK, FLAG_ABORT_CONNECTION);   
         eds_context_ptr->LISTENSOCK = 0;   
      }   
      if (eds_context_ptr->BUFFER_PTR)  {
         _mem_free(eds_context_ptr->BUFFER_PTR);   
         eds_context_ptr->BUFFER_PTR = 0;   
      }   
   }
   EDS_task_id = 0;
} /* Endbody */
#endif
/* End CR 1658 */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/dnsutil.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dnsutil.c$
* $Version : 172.16.58.3$
* $Date    : Jan-20-2010$
*
* Comments:
*
*   This file contains the functions used exclusively by the
*   user interface functions RTCS_gethostbyname,
*   DNS_gethostbyname, and DNS_gethostbyaddr for RTCS.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"

#if RTCSCFG_ENABLE_UDP
#if RTCSCFG_ENABLE_DNS

#include <ctype.h>
#include <string.h>
#include <fio.h>
#include "dns.h"

/*

GCC compiler did not have ctype in libc.
Used these definitions to resolve the problem:

#define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)-'A'+'a' : (c))
#define isalpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
#define isdigit(c) ( (c) >= '0' && (c) <= '9' )
#define isalnum(c) (isalpha(c) || isdigit(c))

*/

/* Global variable used for gethostbyaddr and gethostbyname calls */
static INTERNAL_HOSTENT_STRUCT RTCS_HOST;
static uchar RTCS_HOST_NAMES[DNS_MAX_NAMES][DNS_MAX_CHARS_IN_NAME];
static _ip_address RTCS_HOST_ADDRS[DNS_MAX_ADDRS];

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_is_dotted_IP_addr()
* Returned Value  : char _PTR_
* Comments        :
*
*END*-----------------------------------------------------------------*/

uint_32 DNS_is_dotted_IP_addr
   (
   uchar _PTR_ name,
   uchar _PTR_ fill_buffer_ptr
   )

{  /* Body */

   uint_32     i;
   uint_32     j = 0;
   uint_32     k;
   uint_32     size = 0;
   uint_32     digit_count = 0;
   uint_32     dot_count = 0;
   int_32      byte_num;
   uint_32     addr_number = 0;
   uchar       number_chars[4];
   uchar       actual_number;
   uchar       addr[4][3];
   uchar _PTR_ number_buffer_ptr;
   uchar       appended_name[12] = {"in-addr.arpa"};
   boolean     leading_zero;

   /*
   ** first check to see if name is written in correct dotted decimal
   ** IP address format
   */
   for (i=0; name[i] != '\0'; ++i ) {
      if ( name[i] == '.' ) {
         dot_count++;

         if ( dot_count > 3 ) {
            /* invalid IP address */
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         }/* Endif */

         if ( digit_count == 0 ) {
            /* there are no digits before the '.' */
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         }/* Endif */

         byte_num = byte_num / 10; /* shift back */

         if ( (byte_num < 0 ) || (byte_num > 255) ) {
         /* if the number does fall within this range it's invalid */
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         } else {
            addr_number++;
            number_chars[j] = digit_count;
            j++;
            digit_count = 0;
         } /* Endif */
      } else { /* a digit */

         if ( digit_count == 0 ) {
            byte_num = 0;
         }/* Endif */
         ++digit_count;

         if ( digit_count > 3 ) {
            /* too many digits between the '.' */
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         }/* Endif */

         if ( isdigit(name[i]) ) {
            /* number is in range */
            addr[addr_number][digit_count - 1] = name[i];
            byte_num = byte_num + name[i] - '0';
            byte_num = byte_num * 10;
         } else {
            /* if the characters are not decimal digits it's invalid */
            return( RTCSERR_DNS_INVALID_IP_ADDR );
         }/* Endif */
      }/* Endif */
   } /* Endfor */

   if ( digit_count == 0 ) {
      /* there are no digits after the last '.' */
      return( RTCSERR_DNS_INVALID_IP_ADDR );
   } /* Endif */

   byte_num = byte_num / 10;
   if ( (byte_num < 0 ) || (byte_num > 255) ) {
      /* if the number does fall within this range it's invalid */
      return( RTCSERR_DNS_INVALID_IP_ADDR );
   } else {
      number_chars[j] = digit_count;
   }  /* Endif */

   if ( dot_count != 3 ) {
      /* the wrong number of dots were found */
      return( RTCSERR_DNS_INVALID_IP_ADDR );
   }/* Endif */

   /*
   ** If we got this far, it's a legal IP addr, reverse the numbers,
   ** in the fill_buffer and append "in-addr.arpa" to it.
   */
   for ( i = 0; i < 4; i++) {

      leading_zero       = FALSE;
      number_buffer_ptr  = fill_buffer_ptr;
      actual_number      = number_chars[j];
      htonc(fill_buffer_ptr, number_chars[j]);
      fill_buffer_ptr++;
      size++;

      for ( k = 0; k < number_chars[j]; k++ ) {
         if ( addr[addr_number][k] == '0' ) {
            if ( addr[addr_number][k] == '0' && k == 0 ) {
               leading_zero = TRUE;
               actual_number--;
               continue;
            } /* Endif */

            if ( addr[addr_number][k] == '0' && k == 1
                 && leading_zero == TRUE && k < number_chars[j] ) {
               actual_number--;
               continue;
            } /* Endif */

            if ( addr[addr_number][k] == '0' && k == 1
                 && leading_zero == TRUE && k == number_chars[j] ) {

               htonc(fill_buffer_ptr, addr[addr_number][k]);
               fill_buffer_ptr++;
               htonc(number_buffer_ptr, actual_number);
               number_buffer_ptr++;
               size++;
               break;
            }/* Endif */
         } /* Endif */

         htonc(fill_buffer_ptr, addr[addr_number][k]);
         fill_buffer_ptr++;
         size++;
      } /* Endfor */

      addr_number--;
      j--;
   } /* Endfor */

   htonc(fill_buffer_ptr, 7);
   fill_buffer_ptr++;

   for ( i = 0; i < 7;  i++) {
      htonc(fill_buffer_ptr, appended_name[i]);
      fill_buffer_ptr++;
   } /* Endfor */

   htonc(fill_buffer_ptr, 4);
   fill_buffer_ptr++;
   i++;

   for ( ; i < 12;  i++) {
      htonc(fill_buffer_ptr, appended_name[i]);
      fill_buffer_ptr++;
   } /* Endfor */

   /*
   ** Need to append '\0' to terminate a domain name properly.
   ** This signifies the ROOT domain
   */
   htonc(fill_buffer_ptr, '\0');

   return( DNS_OK );

}  /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_insert_IP_query()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_insert_IP_query
   (
   uchar _PTR_ name,
   uchar _PTR_ fill_buffer_ptr
   )
{ /* Body */
   uchar my_buff[DNS_MAX_IP_STRING_SIZE];
   sprintf((char _PTR_)my_buff,"%ld.%ld.%ld.%ld", (uint_32)name[0],
      (uint_32)name[1], (uint_32)name[2], (uint_32)name[3]);
   return(DNS_is_dotted_IP_addr(my_buff, fill_buffer_ptr));
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_append_local_name()
* Returned Value  : char _PTR_
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_append_local_name
   (
   uchar   _PTR_ qname_buffer,
   uint_32       total_length
   )

{  /* Body */

   uint_32       local_name_length = 0;
   uint_32       error;
   uchar   _PTR_ label_length_ptr;
   uchar         label_length = 0;


   if ( DNS_Local_network_name[local_name_length] == '\0' ) {
      return( RTCSERR_DNS_INVALID_LOCAL_NAME );
   }/* Endif */

   /* If the Local Network is the ROOT Domain Name */
   if ( ( DNS_Local_network_name[local_name_length] == '.' )
        && ( DNS_Local_network_name[local_name_length + 1] == '\0' )) {
      htonc((qname_buffer + total_length), '\0');
      return( DNS_OK );
   }/* Endif */

   label_length_ptr = qname_buffer + total_length;
   error            = DNS_OK;

   while ( DNS_Local_network_name[local_name_length] ) {

      /*
      ** RFC 1035 says labels must start with a letter, but in practice
      ** some aren't
      */
      if ( isalnum(DNS_Local_network_name[local_name_length]) ) {
         htonc((qname_buffer + total_length + 1),
               DNS_Local_network_name[local_name_length]);
         total_length++;
         local_name_length++;
         label_length++;
      } else {
         error = RTCSERR_DNS_INVALID_LOCAL_NAME;
         break;
      }  /* Endif */

      while ( ( DNS_Local_network_name[local_name_length] != '.' ) &&
              ( DNS_Local_network_name[local_name_length] != '\0' ) ) {

         /* Domain Name characters can only be letters, hyphens, or numbers */
         if ( (isalnum(DNS_Local_network_name[local_name_length]) ||
               DNS_Local_network_name[local_name_length] == '-'  ) &&
              total_length < DNS_MAX_CHARS_IN_NAME  &&
              label_length <= DNS_MAX_LABEL_LENGTH ) {
            htonc((qname_buffer + total_length + 1),
                  DNS_Local_network_name[local_name_length]);
            total_length++;
            local_name_length++;
            label_length++;
         } else {
            error = RTCSERR_DNS_INVALID_LOCAL_NAME;
            break;
         } /* Endif */
      } /* Endwhile */

      if ( error == RTCSERR_DNS_INVALID_LOCAL_NAME ) {
         break;
      }/* Endif */

      htonc(label_length_ptr, label_length);
      label_length = 0;
      total_length++;
      label_length_ptr = qname_buffer + total_length;
      local_name_length++;
   } /* Endwhile */

   if ( error == DNS_OK ) {
      /*
      ** Need to append '\0' to terminate domain name properly.
      ** This signifies the ROOT domain
      */
      htonc(label_length_ptr, '\0');
   }/* Endif */

   return( error );

}  /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_is_dotted_domain_name()
* Returned Value  : uint_32
* Comments        : Checks the DNS Domain Name passed to it to see if the
*                   proper naming conventions have been followed.
*
*END*-----------------------------------------------------------------*/

uint_32 DNS_is_dotted_domain_name
   (
   uchar _PTR_ domain_name,
   uchar _PTR_ qname_buffer
   )
{  /* Body */
   uint_32     total_length = 0;
   uint_32     error;
   uchar _PTR_ label_length_ptr;
   uchar       label_length = 0;


   if ( domain_name[total_length] == '\0' ) {
      return( RTCSERR_DNS_INVALID_NAME );
   }/* Endif */

   /* If the request is for the ROOT Domain Name */
   if ( ( domain_name[total_length] == '.' )
        && ( domain_name[total_length + 1] == '\0' )) {
      htonc(qname_buffer, '\0');
      return( DNS_OK );
   }/* Endif */

   label_length_ptr = qname_buffer;
   error            = DNS_OK;

   while ( domain_name[total_length] != '\0' ) {

      /*
      ** RFC 1035 says labels must start with a letter, but in practice
      ** some aren't
      */
      if ( isalnum(domain_name[total_length]) ) {
         htonc((qname_buffer + total_length + 1), domain_name[total_length]);
         total_length++;
         label_length++;
      } else {
         error = RTCSERR_DNS_INVALID_NAME;
         break;
      }  /* Endif */

      while ( ( domain_name[total_length] != '.') &&
              ( domain_name[total_length] != '\0' ) ) {

         /* Domain Name characters can only be letters, hyphens, or numbers */
         if ( (isalnum(domain_name[total_length]) ||
               domain_name[total_length] == '-'  ) &&
              total_length < DNS_MAX_CHARS_IN_NAME &&
              label_length <= DNS_MAX_LABEL_LENGTH ) {
            htonc((qname_buffer + total_length + 1), domain_name[total_length]);
            total_length++;
            label_length++;
         } else {
            error = RTCSERR_DNS_INVALID_NAME;
            break;
         } /* Endif */
      } /* Endwhile */

      if ( error == RTCSERR_DNS_INVALID_NAME ) {
         break;
      }/* Endif */

      htonc(label_length_ptr, label_length);
      label_length = 0;


      if ( domain_name[total_length] != '\0' ) {
         label_length_ptr = qname_buffer + total_length + 1;
      } else {
         /* It's NULL, append the local network name */
         error = DNS_append_local_name( qname_buffer, total_length + 1 );
         return( error );
      } /* Endif */
      total_length++;
   } /* Endwhile */

   if ( error == DNS_OK ) {
      /*
      ** Need to append '\0' to terminate domain name properly.
      ** This denotes the ROOT domain
      */
      htonc(label_length_ptr, '\0');
   }/* Endif */

   return( error );

}  /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_parse_answer_name_to_dotted_form()
* Returned Value  : uchar _PTR_
* Comments        :
*
*END*-----------------------------------------------------------------*/

static uchar _PTR_ DNS_parse_answer_name_to_dotted_form
   (
   uchar _PTR_ buffer_ptr,
   uchar _PTR_ name,
   uint_32     loc
   )

{  /* Body */

   uchar   _PTR_ compressed_name;
   uchar   _PTR_ fill_ptr;
   uchar         label_size;
   uint_32       i;
   uint_16       new_location;

   fill_ptr = RTCS_HOST_NAMES[loc];
   _mem_zero(fill_ptr, DNS_MAX_CHARS_IN_NAME);

   compressed_name = name;

   while ( ntohc(compressed_name) != '\0' ) {

      if ( ntohc(compressed_name) & DNS_COMPRESSED_NAME_MASK ) {
         new_location = ntohs(compressed_name)
                        & DNS_COMPRESSED_LOCATION_MASK;
         compressed_name = buffer_ptr + new_location;
      }/* Endif */

      label_size  = ntohc(compressed_name);
      compressed_name++;

      for ( i = 0; i < label_size; i++ ) {
           *fill_ptr++ = ntohc(compressed_name);
            compressed_name++;
      } /* Endfor */

      if ( ntohc(compressed_name) != '\0' ) {
         *fill_ptr++ = '.';
      }/* Endif */
   } /* Endwhile */

   *fill_ptr = '\0';

   return( RTCS_HOST_NAMES[loc] );

}  /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_free_HOSTENT_STRUCT()
* Returned Value  : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

void DNS_free_HOSTENT_STRUCT
   (
   HOSTENT_STRUCT _PTR_ host_ptr
   )

{  /* Body */
   /*
   ** This function is no longer needed, but the wrapper is left for
   ** backwards compatibility.
   */
}  /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_parse_UDP_response()
* Returned Value  : HOSTENT_STRUCT_PTR
* Comments        : If answers were returned, this function will
*                   parse them into a HOSTENT_STRUCT
*
*END*-----------------------------------------------------------------*/

HOSTENT_STRUCT _PTR_ DNS_parse_UDP_response
   (
   uchar   _PTR_ buffer_ptr,
   uchar   _PTR_ name_ptr,
   uint_16       query_type
   )

{  /* Body */

   DNS_MESSAGE_HEADER_STRUCT     _PTR_   message_head_ptr = NULL;
   DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_   answer_middle;
   INTERNAL_HOSTENT_STRUCT       _PTR_   host_ptr = &RTCS_HOST;
   uchar                         _PTR_   answer_ptr;
   uchar                         _PTR_   answer_tail;
   uchar                         _PTR_   temp_ptr;
   uint_16                               response_length, answer_type,
      name_size, number_of_answers, num_queries;
   uint_32                               i, name_index = 0;
   uint_32                               j = 0;
   uint_32                               k = 0;
   uint_32                               buffer_size;
   uint_32                       _PTR_   addr_ptr;
   boolean                               unknown_answer_type = FALSE;

   message_head_ptr  = (DNS_MESSAGE_HEADER_STRUCT _PTR_)buffer_ptr;
   buffer_size       = sizeof(DNS_MESSAGE_HEADER_STRUCT);
   temp_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT );

   /* Zero the global HOSTENT_STRUCT */
   _mem_zero((char_ptr)host_ptr, sizeof(INTERNAL_HOSTENT_STRUCT));

   /* Get the number of queries. */
   num_queries = ntohs(message_head_ptr->QDCOUNT);
   for (i = 0; i < num_queries; i++) {
      name_size = 0;
      while( (ntohc(temp_ptr) != '\0') &&
         name_size < DNS_MAX_CHARS_IN_NAME ) {
         name_size = name_size + ntohc(temp_ptr) + 1;
         temp_ptr  = temp_ptr  + ntohc(temp_ptr) + 1;
      } /* Endwhile */
      /* To include the terminating NULL char */
      name_size++;
      buffer_size += (name_size + sizeof(DNS_MESSAGE_TAIL_STRUCT));
      temp_ptr    += (1 + sizeof(DNS_MESSAGE_TAIL_STRUCT));
   } /* Endfor */

   number_of_answers = ntohs(message_head_ptr->ANCOUNT);
   if (number_of_answers > DNS_MAX_NAMES ) {
      number_of_answers = DNS_MAX_NAMES;
   } /* Endif */

   host_ptr->HOSTENT.h_aliases   = &host_ptr->ALIASES[0];
   host_ptr->HOSTENT.h_addr_list = (char_ptr _PTR_)&host_ptr->ADDRESSES[0];
   host_ptr->ADDRESSES[0]        = NULL;
   host_ptr->HOSTENT.h_name      = NULL;
   host_ptr->HOSTENT.h_length    = sizeof( _ip_address );

   for (i = 0; (i < number_of_answers) && (j < DNS_MAX_ADDRS) &&
       (k < DNS_MAX_NAMES); i++ )
   {
      answer_ptr = temp_ptr;
      name_size  = 0;

      while( (ntohc(temp_ptr) != '\0') &&
             name_size < DNS_MAX_CHARS_IN_NAME &&
             !(ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK)) {
         name_size += ntohc(temp_ptr);
         temp_ptr += ntohc(temp_ptr) + 1;
      } /* Endwhile */

      if ( ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK ) {
         temp_ptr++;
      }/* Endif */

      temp_ptr++;
      answer_middle   = (DNS_RESPONSE_RR_MIDDLE_STRUCT _PTR_)temp_ptr;
      response_length = ntohs(answer_middle->RDLENGTH);
      answer_type     = ntohs(answer_middle->TYPE);
      temp_ptr       += sizeof(DNS_RESPONSE_RR_MIDDLE_STRUCT);
      answer_tail     = temp_ptr;
      temp_ptr       += response_length;

      switch ( answer_type ) {

         case DNS_A:
            if ( host_ptr->HOSTENT.h_name == NULL ) {
               host_ptr->HOSTENT.h_name =
                  (char _PTR_)DNS_parse_answer_name_to_dotted_form(
                  buffer_ptr, answer_ptr, name_index );
               name_index++;
            } /* Endif */

            RTCS_HOST_ADDRS[j] = ntohl((uchar_ptr)answer_tail);
            /*
            ** j is used in case BOTH CNAME and A data is received.  If CNAME
            ** answer is first, will write into wrong address space if using
            ** i.
            */
            host_ptr->ADDRESSES[j] = &RTCS_HOST_ADDRS[j];
            j++;
            /*
            ** This is to assure that the first IP address used is the first
            ** one that was given
            */
            host_ptr->IP_address = *host_ptr->ADDRESSES[0];
            break;

         case DNS_PTR:
            if (query_type == DNS_PTR) {
               if (host_ptr->HOSTENT.h_name != NULL) {
                  host_ptr->ALIASES[k] = host_ptr->HOSTENT.h_name;
                  k++;
               } /* Endif */
               host_ptr->HOSTENT.h_name =
                  (char _PTR_)DNS_parse_answer_name_to_dotted_form(
                  buffer_ptr, answer_tail, name_index );
               name_index++;
               addr_ptr = RTCS_mem_alloc_zero( sizeof( _ip_address ));
               if ( addr_ptr == NULL ) {
                  RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY,
                                 0, 0, 0);
                  return( NULL );
               }/* Endif */

               *addr_ptr = *((_ip_address _PTR_)name_ptr);
               host_ptr->ADDRESSES[j] = addr_ptr;
               j++;
               host_ptr->IP_address = *host_ptr->ADDRESSES[0];
            } else {
               host_ptr->ALIASES[k] = (char _PTR_)
                     DNS_parse_answer_name_to_dotted_form( buffer_ptr,
                     answer_tail, name_index );
               name_index++;
               k++;
            } /* Endif */
            break;

         case DNS_CNAME:
            /* the k is used for ALIASES as the j is used for ADDRESSES */
            host_ptr->ALIASES[k] = (char _PTR_)
               DNS_parse_answer_name_to_dotted_form(
               buffer_ptr, answer_tail, name_index );
            name_index++;
            k++;
            break;

         default:
            unknown_answer_type = TRUE;
      } /* Endswitch */

      if ( unknown_answer_type == TRUE ) {
         break;
      }/* Endif */

      host_ptr->ADDRESSES[j]       = NULL;
      host_ptr->ALIASES[k]         = NULL;
      host_ptr->HOSTENT.h_addrtype = ntohs(answer_middle->CLASS);

   } /* Endfor */

   if ( number_of_answers == 0 ) {
      return( NULL );
   } /* Endif */

   return( &RTCS_HOST.HOSTENT );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_query_resolver_task()
* Returned Value  : HOSTENT_STRUCT _PTR_
* Comments        :
*
*END*-----------------------------------------------------------------*/

HOSTENT_STRUCT _PTR_ DNS_query_resolver_task
   (
   uchar _PTR_ name,
   uint_16     query_type
   )

{  /* Body */

   DNS_MESSAGE_HEADER_STRUCT _PTR_   message_head_ptr;
   DNS_MESSAGE_TAIL_STRUCT   _PTR_   message_tail_ptr;
   HOSTENT_STRUCT            _PTR_   host_ptr = NULL;
   sockaddr_in                       addr;
   uint_32                           local_sock;
   uint_32                           qname_size;
   uint_32                           buffer_size;
   uint_16                           rlen;
   int_32                            temp_size;
   int_32                            error;
   uchar                     _PTR_   temp_ptr;
   uchar                     _PTR_   qname_ptr;
   uchar                     _PTR_   buffer_ptr;



   /*
   ** If the size of this buffer is changed, also change the buffer size
   ** in the recvfrom() call near the bottom of this function
   */
   buffer_ptr = RTCS_mem_alloc_zero( DNS_MAX_UDP_MESSAGE_SIZE );
   if ( buffer_ptr == NULL ) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY,
                     0, 0, 0);
      return( NULL );
   }/* Endif */
   _mem_set_type(buffer_ptr, MEM_TYPE_DNS_UDP_MESSAGE);
   qname_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT );

   if ( query_type == DNS_A ) {
       error = DNS_is_dotted_domain_name( name, qname_ptr );
       if ( error == RTCSERR_DNS_INVALID_NAME ||
            error == RTCSERR_DNS_INVALID_LOCAL_NAME ) {
          _mem_free(buffer_ptr);
          return( NULL );
       }/* Endif */
   } else {
      if ( query_type == DNS_PTR ) {
         error = DNS_insert_IP_query( name, qname_ptr );
         if ( error == RTCSERR_DNS_INVALID_IP_ADDR ) {
            _mem_free(buffer_ptr);
            return( NULL );
         }/* Endif */
      } else {
         _mem_free(buffer_ptr);
         return( NULL );
      } /* Endif */
   } /* Endif */

   local_sock = socket(AF_INET, SOCK_DGRAM, 0);

   if ( local_sock == RTCS_HANDLE_ERROR ) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_OPEN_SOCKET,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   }/* Endif */

   /* Local address  */
   addr.sin_family       = AF_INET;
   addr.sin_port         = 0;
   addr.sin_addr.s_addr  = INADDR_ANY;

   error =  bind(local_sock, &addr, sizeof(addr));
   if (error != RTCS_OK) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_BIND_SOCKET,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   } /* Endif */

   /* set up buffer for sending query.   */
   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT _PTR_)buffer_ptr;

   htons(message_head_ptr->ID, 0);
   htons(message_head_ptr->CONTROL, DNS_STANDARD_QUERY);
   htons(message_head_ptr->QDCOUNT, DNS_SINGLE_QUERY);
   htons(message_head_ptr->NSCOUNT, 0);
   htons(message_head_ptr->ARCOUNT, 0);
   htons(message_head_ptr->ANCOUNT, 0);

   qname_size = strlen((char _PTR_)qname_ptr );
   /* Need to include the last '\0' character as well */
   qname_size++;

   temp_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT )
                          + qname_size;

   message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT _PTR_)temp_ptr;

   htons(message_tail_ptr->QTYPE, query_type);
   htons(message_tail_ptr->QCLASS, DNS_IN);

   buffer_size = sizeof(DNS_MESSAGE_HEADER_STRUCT) + qname_size
                 + sizeof(DNS_MESSAGE_TAIL_STRUCT);

    /* Remote address, DNS_Resolver currently uses port 1024 */
   addr.sin_port        = DNS_RESOLVER_PORT;
   addr.sin_addr.s_addr = DNS_RESOLVER_IP_ADDR;

   rlen = sizeof(addr);

   /* Send the buffer to the resolver for making a query */
   error = sendto(local_sock, buffer_ptr, buffer_size, 0, &addr, rlen);
   if (error == RTCS_ERROR) {
      shutdown(local_sock, FLAG_ABORT_CONNECTION);
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_SEND_QUERY,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   }/* Endif */

   /* Get the response from the resolver, if none received, return NULL */
   error = (uint_32)RTCS_selectset( &local_sock, 1, DNS_QUERY_TIMEOUT );
   if ( !error || error == RTCS_ERROR ) {
      shutdown(local_sock, FLAG_ABORT_CONNECTION);
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_NO_RESPONSE_FROM_RESOLVER,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   } /* Endif */

   temp_size = recvfrom(local_sock, buffer_ptr, DNS_MAX_UDP_MESSAGE_SIZE,
                        0, &addr, &rlen);
   if ( temp_size == RTCS_ERROR ) {
     shutdown(local_sock, FLAG_ABORT_CONNECTION);
     RTCS_log_error(ERROR_DNS, RTCSERR_DNS_PACKET_RECEPTION_ERROR,
                    0, 0, 0);
     _mem_free(buffer_ptr);
     return( NULL );
   }/* Endif */

   host_ptr = DNS_parse_UDP_response(buffer_ptr, name, query_type);
   shutdown(local_sock, FLAG_ABORT_CONNECTION);
   _mem_free(buffer_ptr);
   return( host_ptr );

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_check_local_host_file()
* Returned Value  : HOSTENT_STRUCT_PTR
* Comments        : Maps a host name to an IP address
*
*END*-----------------------------------------------------------------*/

HOSTENT_STRUCT_PTR DNS_check_local_host_file
   (
      uchar_ptr  name
   )
{  /* Body */
   INTERNAL_HOSTENT_STRUCT_PTR host_ptr = &RTCS_HOST;
   uint_32                     i;
   boolean                     name_found;
   uint_32                     num_aliases = 0;
   uint_32                     host_index = 0;
   uint_32                     digit_count = 0;
   uint_32                     dot_count = 0;
   uint_32                     name_size, name_index = 0;
   int_32                      byte_num;
   boolean                     dotted_decimal;
   uint_32                     temp = 0;

   /* zero memory for HOSTENT_STRUCT */
   _mem_zero(host_ptr, sizeof(INTERNAL_HOSTENT_STRUCT));

   host_ptr->HOSTENT.h_aliases = &host_ptr->ALIASES[0];
   host_ptr->HOSTENT.h_addr_list = (char_ptr _PTR_)&host_ptr->ADDRESSES[0];

   /* assign address type and length */
   host_ptr->HOSTENT.h_addrtype = AF_INET;
   host_ptr->HOSTENT.h_length = 4;     /* IP addresses only used - 4 bytes */

   /* check to see if name is written in dotted decimal IP format */
   dotted_decimal = TRUE;
   for (i=0; name[i] != '\0'; ++i ) {
      if ( name[i] == '.' ) {
         dot_count++;
         if ( dot_count > 3 ) {
            /* invalid IP address */
            dotted_decimal = FALSE;
            break;
         }/* Endif */

         if ( digit_count == 0 ) {
            /* there are no digits before the '.' */
            dotted_decimal = FALSE;
            break;
         }/* Endif */
         digit_count = 0;
         byte_num = byte_num / 10; /* shift back */

         if ( (byte_num < 0 ) || (byte_num > 255) ) {
         /* if the number does fall within this range it's invalid */
            dotted_decimal = FALSE;
            break;
         } else  {
            temp = temp + byte_num;
            temp = temp * 0x100;
         }/* Endif */
      } else { /* a digit */

         if ( digit_count == 0 ) {
            byte_num = 0;
         }/* Endif */
         ++digit_count;

         if ( digit_count > 3 ) {
            /* too many digits between the '.' */
            dotted_decimal = FALSE;
            break;
         }/* Endif */

         if ( isdigit(name[i]) ) {
            /* number is in range */
            byte_num = byte_num + name[i] - '0';
            byte_num = byte_num * 10;
         } else {
            /* if the characters are not decimal digits it's invalid */
            dotted_decimal = FALSE;
            break;
         }/* Endif */
      }/* Endif */
   } /* Endfor */

   if ( dotted_decimal ) { /* check last number */
      if ( digit_count == 0 ) {
         /* there are no digits before the '.' */
         dotted_decimal = FALSE;
      }/* Endif */

      byte_num = byte_num / 10;
      if ( (byte_num < 0 ) || (byte_num > 255) ) {
         /* if the number does fall within this range it's invalid */
         dotted_decimal = FALSE;
      } else {
         temp = temp + byte_num;
      }/* Endif */

      if ( dot_count != 3 ) {
         /* the wrong number of dots were found */
         dotted_decimal = FALSE;
      }/* Endif */

   }/* Endif */


   if ( i == 0 ) {
      /* no name string of first char was not a number */
      dotted_decimal = FALSE;
   }/* Endif */

   _mem_zero(RTCS_HOST_NAMES[name_index], DNS_MAX_CHARS_IN_NAME);
   if ( dotted_decimal == TRUE ) {
      name_size = strlen((char _PTR_)name );
      name_size++;
      _mem_copy(name, RTCS_HOST_NAMES[name_index], name_size);
      /* assign the hostent struct from the dotted decimal IP name */
      host_ptr->HOSTENT.h_name = (char _PTR_)RTCS_HOST_NAMES[name_index];
      host_ptr->ALIASES[num_aliases] = NULL;
      host_ptr->IP_address = temp;
      host_ptr->ADDRESSES[0] = &host_ptr->IP_address;
      host_ptr->ADDRESSES[1] = NULL;
      name_found = TRUE;
   } else  {

      name_found = FALSE;

      /* search for the name in the hosts structure */
      while ( ((RTCS_Hosts_list[host_index]).ip_address != 0) && !name_found) {
      /*end of list hasn't been reached*/
         /* check the aliases for the name */
         i = 0;
         while ( ((RTCS_Hosts_list[host_index]).aliases[i] != NULL) &&
                 !name_found)
         {
            if ( strcmp((char _PTR_)(RTCS_Hosts_list[host_index]).aliases[i],
                        (char _PTR_)name) == 0 )
            {
               name_found = TRUE;
            }/* Endif */
            ++i;
         } /* Endwhile */

         /* check the name field for the name */
         if ( strcmp((char _PTR_)(RTCS_Hosts_list[host_index]).host_name,
             (char _PTR_)name) == 0)
         {
            name_found = TRUE;
         } /* Endif */

         if (name_found == TRUE ) { /* host name was found */
            name_size = strlen( (RTCS_Hosts_list[host_index]).host_name );
            name_size++;
            _mem_copy((RTCS_Hosts_list[host_index]).host_name,
               RTCS_HOST_NAMES[name_index], name_size);

            host_ptr->HOSTENT.h_name = (char _PTR_)RTCS_HOST_NAMES[name_index];
            name_index++;

            /* assign alias list */
            while ( (num_aliases < MAX_HOST_ALIASES)
               && ((RTCS_Hosts_list[host_index]).aliases[num_aliases] != NULL)
               && (name_index < DNS_MAX_NAMES))
            {
               name_size =
                  strlen((RTCS_Hosts_list[host_index]).aliases[num_aliases]);
               name_size++;


               _mem_zero(RTCS_HOST_NAMES[name_index], DNS_MAX_CHARS_IN_NAME);
               _mem_copy((RTCS_Hosts_list[host_index]).aliases[num_aliases],
                  RTCS_HOST_NAMES[name_index], name_size);
               host_ptr->ALIASES[num_aliases] =
                  (char _PTR_)RTCS_HOST_NAMES[name_index];
               name_index++;
               num_aliases++;
            } /* Endwhile */
            host_ptr->ALIASES[num_aliases] = NULL;

            /* assign addresses (in our case only one IP address is allowed) */
            _mem_copy((_ip_address _PTR_)
               &((RTCS_Hosts_list[host_index]).ip_address), &RTCS_HOST_ADDRS[0],
               sizeof(_ip_address));

            host_ptr->ADDRESSES[0] = (uint_32_ptr)&RTCS_HOST_ADDRS[0];
            host_ptr->ADDRESSES[1] = NULL;
         } /* Endif */
         ++host_index;
      } /* Endwhile */
   }/* Endif */


   if ( !name_found ) {
      return( NULL );
   }/* Endif */

   return( &host_ptr->HOSTENT );
}/* EndBody */

#endif
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ifstat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifstat.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file has functions to retrieve statistics structures
*   for each protocol in RTCS.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "tcp.h"
#include "udp_prv.h"
#include "icmp_prv.h"
#include "ip_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IP_stats
* Returned Value  :  IP statistics
* Comments        :
*     Returns a pointer to the IP layer statistics.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP_STATS
IP_STATS_PTR IP_stats
   (
      void
   )
{
#if RTCSCFG_ENABLE_IP4
   IP_CFG_STRUCT_PTR   ip_cfg_ptr;

   ip_cfg_ptr = RTCS_getcfg(IP);

   if (ip_cfg_ptr != NULL) {
      return &ip_cfg_ptr->STATS;
   }
#endif /* RTCSCFG_ENABLE_IP4 */
   return NULL;
}

#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IP6_stats
* Returned Value  :  IPv6 statistics
* Comments        :
*     Returns a pointer to the IPv6 layer statistics.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP6_STATS
IP6_STATS_PTR IP6_stats
   (
      void
   )
{ 
#if RTCSCFG_ENABLE_IP6
   IP6_CFG_STRUCT_PTR   ip6_cfg_ptr;

   ip6_cfg_ptr = RTCS_getcfg(IP6);

   if (ip6_cfg_ptr != NULL) {
      return &ip6_cfg_ptr->STATS;
   }
#endif /* RTCSCFG_ENABLE_IP6 */
   return NULL;
} 

#endif


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  ICMP_stats
* Returned Value  :  ICMP statistics
* Comments        :
*     Returns a pointer to the ICMP layer statistics.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_ICMP_STATS
ICMP_STATS_PTR ICMP_stats
   (
      void
   )
{
#if RTCSCFG_ENABLE_IP4
   ICMP_CFG_STRUCT_PTR   icmp_cfg_ptr;

   icmp_cfg_ptr = RTCS_getcfg(ICMP);

   if (icmp_cfg_ptr != NULL) {
      return &icmp_cfg_ptr->STATS;
   }
#endif /* RTCSCFG_ENABLE_IP4 */
   return NULL;
}

#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  ICMP6_stats
* Returned Value  :  ICMPv6 statistics
* Comments        :
*     Returns a pointer to the ICMPv6 layer statistics.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_ICMP6_STATS
ICMP6_STATS_PTR ICMP6_stats
   (
      void
   )
{
#if RTCSCFG_ENABLE_IP6
   ICMP6_CFG_STRUCT_PTR   icmp6_cfg_ptr;

   icmp6_cfg_ptr = RTCS_getcfg(ICMP6);

   if (icmp6_cfg_ptr != NULL) {
      return &icmp6_cfg_ptr->STATS;
   }
#endif /* RTCSCFG_ENABLE_IP6 */
   return NULL;
} 

#endif


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  UDP_stats
* Returned Value  :  UDP statistics
* Comments        :
*     Returns a pointer to the UDP layer statistics.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_UDP_STATS
UDP_STATS_PTR UDP_stats
   (
      void
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   udp_cfg_ptr;

   udp_cfg_ptr = RTCS_getcfg(UDP);

   if (udp_cfg_ptr != NULL) {
      return &udp_cfg_ptr->STATS;
   } /* Endif */

   return NULL;
} /* Endbody */
#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  TCP_stats
* Returned Value  :  TCP statistics
* Comments        :
*     Returns a pointer to the TCP layer statistics.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_TCP_STATS
TCP_STATS_PTR TCP_stats
   (
      void
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg_ptr;

   tcp_cfg_ptr = RTCS_getcfg(TCP);

   if (tcp_cfg_ptr != NULL) {
      return &tcp_cfg_ptr->STATS;
   } /* Endif */

   return NULL;
} /* Endbody */
#endif


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  IPIF_stats
* Returned Value  :  IPIF statistics
* Comments        :
*     Returns a pointer to an interface's statistics.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IPIF_STATS
IPIF_STATS_PTR IPIF_stats
   (
      _rtcs_if_handle   handle
         /* [IN] the RTCS interface state structure */
   )
{ /* Body */
   IP_IF_PTR if_ptr = (IP_IF_PTR)handle;
   return &if_ptr->STATS;
} /* Endbody */
#endif


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  ARP_stats
* Returned Value  :  ARP statistics
* Comments        :
*     Returns a pointer to an interface's ARP statistics.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_ARP_STATS
ARP_STATS_PTR ARP_stats
   (
      _rtcs_if_handle   handle
         /* [IN] the RTCS interface state structure */
   )
{ /* Body */
#if RTCSCFG_ENABLE_IP4
    IP_IF_PTR if_ptr = (IP_IF_PTR)handle;
    return (ARP_STATS_PTR)if_ptr->ARP;
#else
    return NULL;   
#endif /* RTCSCFG_ENABLE_IP4 */
} /* Endbody */
#endif


/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/Y_Loader.c<|end_filename|>
#include "app_cfg.h"

extern md5_context ctx;
extern unsigned char md5sum[16];

extern const unsigned char   AES_init_vector[16];
extern T_Boot_record         p_boot_rec1;
extern T_Boot_record         p_boot_rec2;
extern unsigned char         block[HEADER_BLOCK_SZ+10];

static   INT32S            g_destination;  // Индекс записи об образе в массиве информации о принимаемых образах img_file_cbl
                                           // Если 0    - программирование собственной FLASH микроконтроллера,
                                           // Если не 0 - программирование другого микроконтроллера по CAN

static   INT32U            g_blocks_cnt;
static   INT32U            g_indx_in_block;
static   INT32U            g_file_remainder;
static   INT32U            g_addr;
static   INT32U            g_programmed_size; // Общее количество данных отправленных в процедуру программирования 

static   INT32U            g_file_size;
static   INT32S            g_packets_cnt;
static   INT32S            g_session_begin;
static   INT32S            g_file_done;
static   INT32U            g_chank_size;
static   INT8U            *g_ptr_in_pack_buf;

int             boot_encrypted;

static INT8U  packet_buf[PACKET_1K_SIZE + PACKET_OVERHEAD];
INT8U         file_size_str[FILE_SIZE_LENGTH+1];
INT8U         file_name[FILE_NAME_LENGTH+1];
INT8U         tmp_file_name[FILE_NAME_LENGTH+3];


extern INT8U   chainCipherBlock[16];   // Buffer for Cipher Block


#define RCV_OK       0
#define RCV_ERROR   -1
#define RCV_ABORT    1
#define RCV_TIMEOUT  2

#define IS_AF(c)  ((c >= 'A') && (c <= 'F'))
#define IS_af(c)  ((c >= 'a') && (c <= 'f'))
#define IS_09(c)  ((c >= '0') && (c <= '9'))
#define ISVALIDHEX(c) IS_AF(c) || IS_af(c) || IS_09(c)
#define ISVALIDDEC(c) IS_09(c)
#define CONVERTDEC(c) (c - '0')
#define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A'+10) : (c - 'a'+10))
#define CONVERTHEX(c)   (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c))




static INT32S  Ymodem_packets_receiving(INT8U *data, INT32S *length, INT32U timeout);
static int     Ymodem_packets_processing(INT32S  pack_len);
static int     Ymodem_pack_prg_to_FLASH(int pack_len);
static int     Ymodem_pack_prg_by_CAN(int pack_len);

/*-------------------------------------------------------------------------------------------------------------
  Прем пакетов по Y-Modem и программирование из во FLASH микроконтроллера
 
 
  Состав пакетов Y-modem
 
  [01] или [02] ( 01 - SOH, передача 128 байт пакета )  (02 - STX,передача 1024 байт пакета )
  [indx]
  [indx ^ 0xFF]
  [data]....[data]
  [crc hi] - первый байт контрольной суммы CRC16
  [crc lo] - второй байт контрольной суммы CRC16
 
  На первый пакет должен быть ответ               - [0x06] [0x43]     (ACK, CRC)
  На последующие                                  - [0x06]            (ACK)
  Если пакет с ошибкой то в ответ высылаеться     - [0x15]            (NAK)
 
  Передатчик может отправить сигнал аборта        - [0x41] или [0x61] (ABORT1, ABORT2)
  В ответ должно быть выслано подтверждение абрта - [0x18] [0x18]     (CA, CA)
 
  В конце передачи файла передатчик высылает      - [0x04]            (EOT)
  В ответ должен получить                         - [0x15]            (NAK)
  Потом снова высылает                            - [0x04]            (EOT)
  В ответ должен получить                         - [0x06] [0x43]     (ACK, CRC)
 
-------------------------------------------------------------------------------------------------------------*/
INT32S Ymodem_programmator(void)
{
  INT32S  errors;
  INT32S  pack_len;
  INT32S  res;

  errors          = 0;
  g_session_begin = 0;
  g_packets_cnt   = 0;
  g_file_done     = 0;

  LCD_print_str("SER",0,0);

  Send_byte(CRC16);


  while (1)
  {
    switch (Ymodem_packets_receiving(packet_buf, &pack_len, NAK_TIMEOUT))
    {
    case RCV_OK:
      errors = 0;
      switch (pack_len)
      {
      case -1:    // Получено два символа CA - сигнал аборта от передатчика
        Send_byte(ACK);
        return 0;
      case 0:     // RCV_OK и pack_len=0 означает получение символа EOT
        if ( g_file_done == 1 )
        {
          Send_byte(NAK); // Отправка NAK в ответ на EOT означает окончание программирования файла
          g_file_done   = 0;
          g_packets_cnt = 0;
        }
        else
        {
          Send_byte(ACK);
          Send_byte(CRC16);
        }
        break;
      default:    // Получен нормальный пакет
        if ( (packet_buf[PACKET_SEQNO_INDEX] & 0xff) != (g_packets_cnt & 0xff) )
        {
          Send_byte(NAK);
        }
        else
        {
          res = Ymodem_packets_processing(pack_len);

          switch (res)
          {
          case ABORT_SESSION:
            g_file_done   = 0;
            g_packets_cnt = 0;
            Send_byte(CA);  // Завершаем сессию в случае ошибки
            Send_byte(CA);
            return 0;
          case FIRST_PACKET:
            Send_byte(ACK); // Начинаем сессию
            Send_byte(CRC16);
            g_session_begin = 1;
            break;
          case NEXT_PACKET:
            Send_byte(ACK); // Продолжаем сессию
            break;
          case SKIP_SESSION:
            g_file_done   = 0;
            g_packets_cnt = 0;
            Send_byte(NAK);
            Send_byte(CRC16);
            break;
          }
        }
      }
      break;
    case RCV_ABORT:
      Send_byte(CA);
      Send_byte(CA);
      return 0;

    case RCV_ERROR:
      // Либо произошел таймаут, либо пришел неизвестный символ
      if ( g_session_begin > 0 )
      {
        errors++;
      }
      if ( errors > MAX_ERRORS )
      {
        Send_byte(CA);
        Send_byte(CA);
        return 0;
      }
      Send_byte(CRC16);
      break;
    case RCV_TIMEOUT:
      Send_byte(CRC16);

      break;
    }  // switch( Wait_Ymodem_packet(packet_data, &packet_length, NAK_TIMEOUT) )
  }    // while ( 1 )
}

/*------------------------------------------------------------------------------
 
 ------------------------------------------------------------------------------*/
void Decrypt_block(INT8U *buf, int len)
{
  do
  {
    aesDecrypt(buf, chainCipherBlock); // Расшифровываем блок
    buf += 16;
    len -= 16;
  }
  while (len >= 16);
}

/*-------------------------------------------------------------------------------------------------------------
* Function Name  : Str2Int
* Description    : Convert a string to an integer
* Input 1        : - inputstr: The string to be converted
*                  - intnum: The intger value
* Output         : None
* Return         : 1: Correct
*                  0: Error
-------------------------------------------------------------------------------------------------------------*/
INT32U Str2Int(INT8U *inputstr, INT32S *intnum)
{
  INT32U i = 0, res = 0;
  INT32U val = 0;

  if ( inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X') )
  {
    if ( inputstr[2] == '\0' )
    {
      return 0;
    }
    for (i = 2; i < 11; i++)
    {
      if ( inputstr[i] == '\0' )
      {
        *intnum = val;
        res = 1; /* return 1; */
        break;
      }
      if ( ISVALIDHEX(inputstr[i]) )
      {
        val = (val << 4) + CONVERTHEX(inputstr[i]);
      }
      else
      {
        /* return 0; Invalid input */
        res = 0;
        break;
      }
    }

    if ( i >= 11 ) res = 0; /* over 8 digit hex --invalid */
  }
  else /* max 10-digit decimal input */
  {
    for (i = 0; i < 11; i++)
    {
      if ( inputstr[i] == '\0' )
      {
        *intnum = val;
        /* return 1; */
        res = 1;
        break;
      }
      else if ( (inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0) )
      {
        val = val << 10;
        *intnum = val;
        res = 1;
        break;
      }
      else if ( (inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0) )
      {

        val = val << 20;
        *intnum = val;
        res = 1;
        break;
      }
      else if ( ISVALIDDEC(inputstr[i]) ) val = val * 10 + CONVERTDEC(inputstr[i]);
      else
      {
        /* return 0; Invalid input */
        res = 0;
        break;
      }
    }
    if ( i >= 11 ) res = 0; /* Over 10 digit decimal --invalid */
  }

  return res;
}


/*-------------------------------------------------------------------------------------------------------------
 Function Name  : Receive_Packet
 Description    : Receive a packet from sender
 Input 1        : - data
 Input 2        : - length
 Input 3        : - timeout
 Output         : *length:
                  0: end of transmission
                  -1: abort by sender
                  >0: packet length
 Return :        0: normally return
                 -1: timeout or packet error
                 1: abort by user
-------------------------------------------------------------------------------------------------------------*/
static INT32S Ymodem_packets_receiving(INT8U *data, INT32S *length, INT32U timeout)
{
  INT16U i, packet_size;
  INT8U c;
  *length = 0;
  if ( Wait_byte(&c, timeout) != SUCCESS ) return RCV_TIMEOUT;

  switch (c)
  {
  case SOH:
    packet_size = PACKET_128B_SIZE;
    break;
  case STX:
    packet_size = PACKET_1K_SIZE;
    break;
  case EOT:
    return RCV_OK;
  case CA:
    if ( (Wait_byte(&c, timeout) == SUCCESS) && (c == CA) )
    {
      *length = -1;
      return RCV_OK;
    }
    else
    {
      return RCV_ERROR;
    }
  case ABORT1:
  case ABORT2:
    return RCV_ABORT;
  case 0x1B:
    return RCV_ABORT;
  default:
    return RCV_ERROR;
  }
  *data = c;
  for (i = 1; i < (packet_size + PACKET_OVERHEAD); i++)
  {
    if ( Wait_byte(data + i, timeout) != SUCCESS )
    {
      return RCV_ERROR;
    }
  }
  if ( data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff) )
  {
    return RCV_ERROR;
  }
  *length = packet_size;
  return RCV_OK;
}
/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
static int Ymodem_packets_processing(INT32S  pack_len)
{
  int             i;
  T_img_file_cbl  *p_img_file_cbl;

  g_file_size = 0;

  // Проверяем является ли это пустым пакетом от протокола Ymodem-а с PC
  if ( (packet_buf[0] == SOH) && (packet_buf[1] == 00) && (packet_buf[2] == 0xFF) && (packet_buf[3] == 0x00) && (packet_buf[4] == 0x00) )
  {
    return ABORT_SESSION;
  }

  g_ptr_in_pack_buf = packet_buf + PACKET_HEADER;

  // Первый пакет всегда содержит имя файла и размер
  if ( g_packets_cnt == 0 )
  {

    // Прием имени файла
    for (i = 0; i < FILE_NAME_LENGTH; i++)
    {
      file_name[i] = tolower(*g_ptr_in_pack_buf++);
      if ( file_name[i] == 0 ) break;
    }
    file_name[i] = '\0';



    // Прием размера файла
    for (i = 0; i < FILE_SIZE_LENGTH; i++)
    {
      file_size_str[i] = *g_ptr_in_pack_buf++;
      if ( file_size_str[i] == ' ' ) break;
    }
    file_size_str[i] = '\0';
    Str2Int(file_size_str, (INT32S *)&g_file_size);

    if ( g_destination == 0 )
    {
      // Проверить размер файла для записи
      if ( g_file_size > (FLASH_AREA_SIZE - BOOTL_IMG_SIZE - sizeof(p_boot_rec1)) )
      {
        // Прерывание процесса если размер больше допустимого
        return ABORT_SESSION;
      }
    }
    g_blocks_cnt    = 0;
    g_indx_in_block = 0;
    g_file_remainder  = g_file_size;

    g_packets_cnt++;
    return FIRST_PACKET;

  }
  else
  {
    return  Ymodem_pack_prg_to_FLASH(pack_len);
  }
}

/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
static int Finish_file_program(void)
{
  if ( g_packets_cnt < 2 )
  {
    return ERROR;
  }
  // Проверяем хэш записанных данных
  md5_starts(&ctx);
  md5_update(&ctx, (uint8 *)PROGRAMM_AREA_BEG_ADDR, p_boot_rec1.orig_img_size);
  md5_finish(&ctx, md5sum);

  if ( memcmp(p_boot_rec1.md5_hash, md5sum, 16) != 0 )
  {
    return ERROR;
  }

  // Записываем запись boot
  g_addr = FLASH_AREA_ADDR + FLASH_AREA_SIZE - sizeof(p_boot_rec1);
  __disable_interrupt();
  Flash_ByteProgram(g_addr,(unsigned char *)&p_boot_rec1, sizeof(p_boot_rec1));
  __enable_interrupt();

  if ( memcmp((void *)g_addr, (void *)&p_boot_rec1, sizeof(p_boot_rec1)) != 0 )  // Проверка
  {
    LCD_show_programming_end(ERROR);
    return ERROR;
  }
  LCD_show_programming_end(SUCCESS);
  return SUCCESS;
}



/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
static int Ymodem_pack_prg_to_FLASH(int pack_len)
{
  int i;
  // Полученные в пакете данные разбиваем на блоки заданной длины которые программируем
  do
  {
    // Перенос данных из пакета в блок
    g_chank_size = HEADER_BLOCK_SZ - g_indx_in_block; // Рассчитываем количество свободного места в блоке
    if ( g_chank_size > pack_len )         g_chank_size = pack_len; // Если места в блоке больше чем данных в пакете
    if ( g_chank_size > g_file_remainder ) g_chank_size = g_file_remainder;

    memcpy(block, g_ptr_in_pack_buf, g_chank_size);
    g_indx_in_block   += g_chank_size;
    g_file_remainder  -= g_chank_size;
    g_ptr_in_pack_buf += g_chank_size;

    // Программируем только когда наберется полный буфер размером HEADER_BLOCK_SZ или когда новых данных уже не поступит
    if ( (g_file_remainder == 0) || (g_indx_in_block == HEADER_BLOCK_SZ) )
    {
      // Записываем блок во FLASH
      if ( g_blocks_cnt == 0 )
      {
        // Проверяем хидер файла

        memcpy(chainCipherBlock, (void *)AES_init_vector, 16);
        aesInit(); // Init AES algorithm.

        // Определяем зашифрован или нет файл
        memcpy(&p_boot_rec1, &block[HEADER_BLOCK_SZ - sizeof(p_boot_rec1)], sizeof(p_boot_rec1));

        if ( p_boot_rec1.magic_val != MAGIC_TAG )
        {
          Decrypt_block(block, HEADER_BLOCK_SZ);
          memcpy(&p_boot_rec1, &block[HEADER_BLOCK_SZ - sizeof(p_boot_rec1)], sizeof(p_boot_rec1));

          // Если не обнаружен в первом блоке MAGIC_TAG и до и после шифрования, то прерываем программирование
          if ( p_boot_rec1.magic_val != MAGIC_TAG ) return ABORT_SESSION;
          boot_encrypted = 1;
        }

        // Проверяем допустимость размера файла с образом программирования
        if ( p_boot_rec1.orig_img_size > (FLASH_AREA_SIZE - BOOTL_IMG_SIZE - sizeof(p_boot_rec1)) )
        {
          return ABORT_SESSION; // У образа недопустимо большой размер
        }

        // Образы с установленны флагом сжатия не принимаються
        if ( p_boot_rec1.compress_flag != 0 )
        {
          return ABORT_SESSION; // Сжатые файлы не обрабатываем
        }

        // Начинаем запись файлов во Flash
        __disable_interrupt();
        Flash_Init();
        __enable_interrupt();

        // Начинаем со стирания последнего сектора
        __disable_interrupt();
        Flash_SectorErase(FLASH_AREA_ADDR + FLASH_AREA_SIZE - ERASE_SECTOR_SIZE);
        __enable_interrupt();

        {
          unsigned int n = p_boot_rec1.orig_img_size / ERASE_SECTOR_SIZE;
          if ( (p_boot_rec1.orig_img_size % ERASE_SECTOR_SIZE) != 0 ) n++;
          if ( n >= MAX_SECTOR_NUM ) n  = MAX_SECTOR_NUM - 1; // Чтобы не повтороять повтороное стирание последнего сектора

          // Стираем все изменяемые сектора
          for (i = 0; i < n; i++)
          {
            __disable_interrupt();
            Flash_SectorErase(FLASH_AREA_ADDR + BOOTL_IMG_SIZE + i * ERASE_SECTOR_SIZE);
            __enable_interrupt();
          }
        }
        g_programmed_size = 0;
        g_addr = FLASH_AREA_ADDR + BOOTL_IMG_SIZE;


      }
      else
      {
        // Записываем данные во FLASH
        if ( boot_encrypted == 1 )
        {
          Decrypt_block(block, g_chank_size);
        }
        __disable_interrupt();
        Flash_ByteProgram(g_addr, block, g_chank_size);    // Программирование
        __enable_interrupt();

        if ( memcmp((void *)g_addr, block, g_chank_size) != 0 )  // Проверка
        {
          return ABORT_SESSION;
        }
        g_addr += g_chank_size;
        g_programmed_size += g_chank_size;
        LCD_show_programming_progress(g_addr, g_programmed_size );
      }
      g_indx_in_block = 0;
      g_blocks_cnt++;
    }

    if ( g_file_remainder == 0 )
    {
      // Завершаем запись во FLASH
      if ( Finish_file_program() == SUCCESS )
      {
        g_file_done   = 1;
        return NEXT_PACKET;
      }
      else
      {
        return ABORT_SESSION;
      }
    }
    pack_len = pack_len - g_chank_size;
  }
  while (pack_len != 0);
  g_packets_cnt++;
  return NEXT_PACKET;
}




<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_enet.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_enet.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the function that reads the timer and returns
*   the number of nanoseconds elapsed since the last interrupt.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"
#include "enet.h"
#include "enetprv.h"
#include <macnet_prv.h>          
#include "phy_ksz8041.h"


const MACNET_INIT_STRUCT MACNET_device[MACNET_DEVICE_COUNT] =  {
    { BSP_SYSTEM_CLOCK, BSP_MACNET0_INT_RX_LEVEL, 0, BSP_MACNET0_INT_TX_LEVEL, 0 },
};


const ENET_IF_STRUCT ENET_0 = {
    &MACNET_IF,
    &phy_ksz8041_IF,
    MACNET_DEVICE_0,
    MACNET_DEVICE_0,
    BSP_ENET0_PHY_ADDR,
    BSP_ENET0_PHY_MII_SPEED
};

const ENET_PARAM_STRUCT ENET_default_params[BSP_ENET_DEVICE_COUNT] = {
    {
        &ENET_0,
        Auto_Negotiate,
        ENET_OPTION_RMII | ENET_OPTION_PTP_MASTER_CLK, 

        BSPCFG_TX_RING_LEN,   // # tx ring entries
        BSPCFG_TX_RING_LEN,   // # large tx packets
        ENET_FRAMESIZE,       // tx packet size
     
        BSPCFG_RX_RING_LEN,   // # rx ring entries
        BSPCFG_RX_RING_LEN,   // # normal rx packets - must be >= rx ring entries
        ENET_FRAMESIZE,       // ENET_FRAMESIZE,   // rx packet size
        BSPCFG_RX_RING_LEN,   // # rx PCBs - should be >= large rx packets.
     
        0,     
        0     
    },
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_mac_address
* Returned Value   : uint_32
* Comments         :
*    This function returns the mac address associated with the specified device
*
* If the MAC address is stored in NV-storage, this fuction should read the
* MAC address from NV-storage and set it.
*
* If the MAC address is generated from a device serial number and an OUI, the
* serial number should be passed in, and the MAC address should be constructed
*
*END*----------------------------------------------------------------------*/

const _enet_address _enet_oui = BSP_DEFAULT_ENET_OUI;

boolean _bsp_get_mac_address
   (
      uint_32        device,
      uint_32        value,
      _enet_address  address
   )
{ /* Body */
   if (device >= BSP_ENET_DEVICE_COUNT) 
      return FALSE;

   address[0] = _enet_oui[0];
   address[1] = _enet_oui[1];
   address[2] = _enet_oui[2];
   address[3] = (value & 0xFF0000) >> 16;
   address[4] = (value & 0xFF00) >> 8;
   address[5] = (value & 0xFF);

   return TRUE;

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/icmp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: icmp.c$
* $Version : 3.8.14.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of a minimal
*   Internet Control Message Protocol.  For more details,
*   refer to RFC792.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "icmp_prv.h"
#include "tcp_prv.h"
#include "udp_prv.h"

#if RTCSCFG_ENABLE_ICMP && RTCSCFG_ENABLE_IP4

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ICMP_init
* Returned Values : uint_32
* Comments        :
*     Initialize the ICMP layer.
*
*END*-----------------------------------------------------------------*/

uint_32 ICMP_init
   (
      void
   )
{ /* Body */
   ICMP_CFG_STRUCT_PTR  icmp_cfg_ptr;
   uint_32              status = RTCS_OK;     /* return code */

   icmp_cfg_ptr = RTCS_mem_alloc_zero(sizeof(ICMP_CFG_STRUCT));
   if (icmp_cfg_ptr == NULL) {
      return RTCSERR_OUT_OF_MEMORY;
   } /* Endif */

   _mem_set_type(icmp_cfg_ptr, MEM_TYPE_ICMP_CFG_STRUCT);
   
   RTCS_setcfg(ICMP, icmp_cfg_ptr);

   IP_open(IPPROTO_ICMP, ICMP_service, NULL, &status);

   return status;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ICMP_service
* Returned Values : void
* Comments        :
*     Process incoming ICMP packets.  Called from IP_service.
*
*END*-----------------------------------------------------------------*/

void ICMP_service
   (
      RTCSPCB_PTR    pcb,        /* [IN/OUT] incoming packet */
      pointer        dummy       /* [IN]     not used        */
   )
{ /* Body */
   ICMP_CFG_STRUCT_PTR  ICMP_cfg_ptr;
   ICMP_HEADER_PTR      packet;
   _ip_address          source, dest;
   uint_32              error;
   uint_16              chksum;
   uchar                type;


   ICMP_cfg_ptr = RTCS_getcfg(ICMP);

   IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_TOTAL++);
   packet = (ICMP_HEADER_PTR)RTCSPCB_DATA(pcb);
   source = IP_source(pcb);
   dest   = IP_dest(pcb);
   type = ntohc(packet->TYPE);

   /*
   ** Make sure that
   **    sizeof(ICMP_HEADER) <= RTCSPCB_SIZE(pcb)
   */
   if (RTCSPCB_SIZE(pcb) < sizeof(ICMP_HEADER)) {
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.ST_RX_SMALL_DGRAM++);
      RTCSLOG_PCB_FREE(pcb, RTCSERR_ICMP_BAD_HEADER);
      RTCSPCB_free(pcb);
      return;
   } /* Endif */

   /*
   ** Verify the checksum
   */
   if (IP_Sum_PCB(0, pcb) != 0xFFFF) {
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.ST_RX_BAD_CHECKSUM++);
      RTCSLOG_PCB_FREE(pcb, RTCSERR_ICMP_BAD_CHECKSUM);
      RTCSPCB_free(pcb);
      return;
   } /* Endif */

   RTCSLOG_PCB_READ(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_ICMP), 0);

   switch (type) {

   case ICMPTYPE_REDIRECT:
#if RTCSCFG_ENABLE_GATEWAYS

      { /* Scope */
         _ip_address          origdest, gateway;
         ICMP_ERR_HEADER_PTR  rdpacket = (ICMP_ERR_HEADER_PTR)packet;
         IPIF_PARM            parms;

         /*
         ** Make sure that
         **    sizeof(ICMP_ERR_HEADER) <= RTCSPCB_SIZE(pcb)
         */
         if (RTCSPCB_SIZE(pcb) < sizeof(ICMP_ERR_HEADER)) {
            IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
            IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.ST_RX_SMALL_DGRAM++);
            RTCSLOG_PCB_FREE(pcb, RTCSERR_ICMP_BAD_HEADER);
            RTCSPCB_free(pcb);
            return;
         } /* Endif */

         gateway  = ntohl(rdpacket->DATA);
         origdest = ntohl(rdpacket->IP.DEST);

         // If we receive a redirect to ourselves, silently discard it
         if (IP_is_local(NULL, gateway)) {
            IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
            // Might want to add a counter here

         } else  if (IP_is_gate(source, origdest)) {
            parms.address = gateway;
            parms.network = origdest;
            parms.netmask = 0xFFFFFFFFL;
            parms.locmask = 0;
            RTCSCMD_internal(parms, IPIF_gate_add_redirect);
         } else {
            IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
            IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.ST_RX_RD_NOTGATE++);
         } /* Endif */

      } /* Endscope */
#else
            IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
#endif
      break;

   case ICMPTYPE_ECHO_REQ:

      error = RTCSPCB_next(pcb, sizeof(ICMP_HEADER));
      if (error) {
         IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_ERRORS++);
         IF_ICMP_STATS_ENABLED(RTCS_seterror(&ICMP_cfg_ptr->STATS.ERR_RX, error, (uint_32)pcb));
         RTCSLOG_PCB_FREE(pcb, error);
         RTCSPCB_free(pcb);
         return;
      } /* Endif */

      /*
      ** RTCSPCB_fork() failing isn't a serious error, so we don't check
      ** the error code
      */
      RTCSPCB_fork(pcb);

      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
      RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_ICMP), 0);

      error = RTCSPCB_insert_header(pcb, sizeof(ICMP_HEADER));
      if (error) {
         IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.ST_RX_ECHO_REQ++);
         IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_ICMP_STATS_ENABLED(RTCS_seterror(&ICMP_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb));
         RTCSLOG_PCB_FREE(pcb, error);
         RTCSPCB_free(pcb);
         return;
      } /* Endif */

      /* Change type from Echo to Echo Reply and recalculate checksum */
      packet = (ICMP_HEADER_PTR)RTCSPCB_DATA(pcb);
      htonc(packet->TYPE, ICMPTYPE_ECHO_REPLY);
      htonc(packet->CODE, 0);
      htons(packet->CHECKSUM, 0);
      chksum = IP_Sum_PCB(0, pcb);
      chksum = IP_Sum_invert(chksum);
      htons(packet->CHECKSUM, chksum);
      pcb->IP_SUM_PTR = NULL;

      /* Send the Echo Reply whence came the Echo */
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.ST_TX_ECHO_REPLY++);
      IP_send(pcb, IPPROTO_ICMP, dest, source, 0);
      pcb = NULL;
      break;

   case ICMPTYPE_ECHO_REPLY:
      { /* Scope */
         ICMP_ECHO_HEADER_PTR echopacket = (ICMP_ECHO_HEADER_PTR)packet;
         ICMP_PARM_PTR        parms;
         uint_16              id, seq;

         /*
         ** Make sure that
         **    sizeof(ICMP_ECHO_HEADER) <= RTCSPCB_SIZE(pcb)
         */
         if (RTCSPCB_SIZE(pcb) < sizeof(ICMP_ECHO_HEADER)) {
            IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
            IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.ST_RX_SMALL_DGRAM++);
            RTCSLOG_PCB_FREE(pcb, RTCSERR_ICMP_BAD_HEADER);
            RTCSPCB_free(pcb);
            return;
         } /* Endif */

         /*
         ** get the ID and Sequence number from the packet
         */
         id  = ntohs(echopacket->ID);
         seq = ntohs(echopacket->SEQ);

         /*
         ** Find a match for the ID and sequence number
         */
         for (parms=ICMP_cfg_ptr->ECHO_PARM_HEAD; parms; parms=parms->NEXT) {

            if ((parms->id == id) && (parms->seq == seq)) {
               /*  received reply for the ping request */

               if (parms->NEXT) {
                  parms->NEXT->PREV = parms->PREV;
               } /* Endif */
               *parms->PREV = parms->NEXT;

               TCPIP_Event_cancel(&parms->EXPIRE);

               /* calculate round trip time */
               parms->timeout = RTCS_timer_get_interval(parms->timeout, RTCS_time_get());

               RTCSCMD_complete(parms, RTCS_OK);
               break;
            } /* Endif */
         } /* Endfor */
      } /* Endscope */
      break;

   case ICMPTYPE_DESTUNREACH:
   case ICMPTYPE_TIMEEXCEED:
      { /* Scope */
         IP_HEADER_PTR       ip;
         ICMP_ERR_HEADER_PTR icmp_err = (ICMP_ERR_HEADER_PTR)packet;
         uint_32             len, remain;
         boolean             discard = TRUE;
         uchar               code;

         /*
         ** Check if the attached IP header is IP over IP, and if so, strip IP
         ** headers until we find one whose source address is not local. Then we
         ** forward the ICMP error to that IP address
         */

         remain = RTCSPCB_SIZE(pcb);

         /* Make sure we have at least a full IP header */
         if (remain >= sizeof(ICMP_HEADER) + 4 + sizeof(IP_HEADER)) {
            ip = (IP_HEADER_PTR)((uchar_ptr)packet + sizeof(ICMP_HEADER) + 4);
            remain -= sizeof(ICMP_HEADER) + 4;

            do {
               /* Make sure the IP header is IP over IP */
               if (ntohc(ip->PROTOCOL) != IPPROTO_IPIP) {
                  break;
               } /* Endif */

               /* Make sure we have a full IP header + 8 bytes */
               len = (ntohc(ip->VERSLEN) & 0x0F) << 2;
               if (remain < len + sizeof(IP_HEADER)) {
                  break;
               } /* Endif */

               /* Get next header */
               ip = (IP_HEADER_PTR)((uchar_ptr)(ip) + len);
               remain -= len;
               source = ntohl(ip->SOURCE);

               discard = IP_is_local(NULL, source);

            } while(discard);

            len = (ntohc(ip->VERSLEN) & 0x0F) << 2;

            /*
            ** discard is true if we are the originator of the IP packet
            ** in error, or if there was not enough information to find the
            ** originator. We make sure discard is false, and there is at
            ** least a full IP header + 8 bytes of data left
            */
            if (!discard && (len + 8 <= remain)) {
               if (type == ICMPTYPE_DESTUNREACH) {
                  code = ntohc(packet->CODE);
                  switch (code) {
                  case ICMPCODE_DU_PROTO_UNREACH:
                     /*
                     ** If we are sending back to the originator, and the
                     ** originator did not use IP over IP, the protocol
                     ** unreachable error is useless.
                     */
                     code = ICMPCODE_DU_NET_UNREACH;
                     break;
                  case ICMPCODE_DU_PORT_UNREACH:
                     /* It doesn't make sense to receive this */
                     discard = TRUE;
                     break;
                  case ICMPCODE_DU_SRCROUTE:
                     discard = TRUE;
                     break;
                  } /* Endswitch */
               } else {
                  /*
                  ** Type is ICMPTYPE_TIMEEXCEED
                  **
                  ** Problem with routing loops within tunnel. Originator
                  ** does not need to know about tunnel.
                  */
                  type = ICMPTYPE_DESTUNREACH;
                  code = ICMPCODE_DU_HOST_UNREACH;
               } /* Endif */

               if (!discard) {
                  ICMP_send_error_internal(type, code, ntohl(icmp_err->DATA),
                     ip, NULL, remain);
               } /* Endif */
            } /* Endif */
         } /* Endif */
      } /* Endscope */
      break;
   } /* End Switch */

#if RTCSCFG_ENABLE_ICMP_STATS
   /* Update the statistics */
   switch (type) {
   case ICMPTYPE_DESTUNREACH: ICMP_cfg_ptr->STATS.ST_RX_DESTUNREACH++; break;
   case ICMPTYPE_TIMEEXCEED:  ICMP_cfg_ptr->STATS.ST_RX_TIMEEXCEED++;  break;
   case ICMPTYPE_PARMPROB:    ICMP_cfg_ptr->STATS.ST_RX_PARMPROB++;    break;
   case ICMPTYPE_SRCQUENCH:   ICMP_cfg_ptr->STATS.ST_RX_SRCQUENCH++;   break;
   case ICMPTYPE_REDIRECT:    ICMP_cfg_ptr->STATS.ST_RX_REDIRECT++;    break;
   case ICMPTYPE_ECHO_REQ:    ICMP_cfg_ptr->STATS.ST_RX_ECHO_REQ++;    break;
   case ICMPTYPE_ECHO_REPLY:  ICMP_cfg_ptr->STATS.ST_RX_ECHO_REPLY++;  break;
   case ICMPTYPE_TIME_REQ:    ICMP_cfg_ptr->STATS.ST_RX_TIME_REQ++;    break;
   case ICMPTYPE_TIME_REPLY:  ICMP_cfg_ptr->STATS.ST_RX_TIME_REPLY++;  break;
   case ICMPTYPE_INFO_REQ:    ICMP_cfg_ptr->STATS.ST_RX_INFO_REQ++;    break;
   case ICMPTYPE_INFO_REPLY:  ICMP_cfg_ptr->STATS.ST_RX_INFO_REPLY++;  break;
   default:                   
      ICMP_cfg_ptr->STATS.ST_RX_OTHER++;       
      ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++;
      break;
   } /* Endswitch */
#endif

   if (pcb) {
      RTCSLOG_PCB_FREE(pcb, RTCS_OK);
      RTCSPCB_free(pcb);
   } /* Endif */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ICMP_send_error_internal
* Returned Values : void
* Comments        :
*     Send a ICMP error with the IP header that produced it.
*
* Warning         :
*     This packet assumes that the IP header is correct,
*     i.e. IP must not use this function on packets recorded
*     in ST_RX_HDR_ERRORS.
*
*END*-----------------------------------------------------------------*/

void ICMP_send_error_internal
   (
      uint_8         type,    /* [IN] the type to send */
      uint_8         code,    /* [IN] the code to send */
      uint_32        param,   /* [IN] a parameter */
      IP_HEADER_PTR  iph,     /* [IN] the IP header */
      RTCSPCB_PTR    origpcb, /* [IN] pcb with bad packet */
      uint_32        maxlen   /* [IN] the max data len to send, 0 = default */
   )
{ /* Body */
   ICMP_CFG_STRUCT_PTR  ICMP_cfg_ptr = RTCS_getcfg(ICMP);
   RTCSPCB_PTR          pcb;
   ICMP_ERR_HEADER_PTR  icmph;
   _ip_address          ipsrc = ntohl(iph->SOURCE);
   _ip_address          ipdst = ntohl(iph->DEST);
   uint_16              iphdrlen = (ntohc(iph->VERSLEN) & 0x0F) << 2;
   uint_16              ippktlen = ntohs(iph->LENGTH) - iphdrlen;
   uint_16              checksum;
   _ip_address          icmpsrc = IP_is_local(NULL,ipdst) ? ipdst : INADDR_ANY;
   uint_32              error;
   uchar_ptr            buffer;
   uint_32              temp;
#if RTCSCFG_ENABLE_NAT   
   TCP_HEADER_PTR       tcp_hdr;
   UDP_HEADER_PTR       udp_hdr;
   IP_HEADER_PTR        ip_hdr;
   uint_32              protocol;
   uint_16              src_port, dest_port;
   uint_32 (_CODE_PTR_ _PTR_  nat_exec)(RTCSPCB_PTR _PTR_);
#endif 
   
   /*
   ** Only include up to a maximum of maxlen bytes of data from the
   ** original IP datagram
   */
   if (!maxlen) {
      maxlen = IP_DEFAULT_MTU - sizeof(IP_HEADER) - sizeof(ICMP_HEADER) - 4;
   } /* Endif */

   if (origpcb) {
      temp = RTCSPCB_DATA(origpcb) - RTCSPCB_DATA_NETWORK(origpcb);
      if (maxlen >  origpcb->HEADER_FRAG_USED + temp) {
         maxlen = origpcb->HEADER_FRAG_USED + temp;
      } /* Endif */   
   } /* Endif */

   if (ippktlen + iphdrlen > maxlen) {
      ippktlen = maxlen - iphdrlen;
   } /* Endif */

   /* Don't send an error in response to an ICMP error */
   if (ntohc(iph->PROTOCOL) == IPPROTO_ICMP) {
      /* Make sure the packet has at least a 'TYPE' field */
      if (ippktlen == 0) {
         return;
      } /* Endif */
      icmph = (ICMP_ERR_HEADER_PTR)((uchar_ptr)iph + iphdrlen);
      if (!ICMPTYPE_ISQUERY(ntohc(icmph->HEAD.TYPE))) {
         return;
      } /* Endif */
   } /* Endif */

   IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);

   /* Allocate a PCB */
   pcb = RTCSPCB_alloc_send();
   if (pcb == NULL) {
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      return;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb);

   if (origpcb) {

      /* Add a dependency and a pointer to the ICMP data */
      RTCSPCB_depend(pcb, origpcb);
      error = RTCSPCB_append_fragment(pcb, iphdrlen + ippktlen, (uchar_ptr)iph);

   } else {
      /* Reserve space for the ICMP data */
      buffer = RTCS_mem_alloc_system(iphdrlen + ippktlen);
      if (!buffer) {
         IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_ICMP_STATS_ENABLED(RTCS_seterror(&ICMP_cfg_ptr->STATS.ERR_TX, RTCSERR_OUT_OF_MEMORY, (uint_32)pcb));
         RTCSLOG_PCB_FREE(pcb, RTCSERR_OUT_OF_MEMORY);
         RTCSPCB_free(pcb);
         return;
      } /* Endif */
   
      _mem_set_type(buffer, MEM_TYPE_ICMP_DATA);

      _mem_copy(iph, buffer, iphdrlen + ippktlen);
      error = RTCSPCB_append_fragment_autofree(pcb, iphdrlen + ippktlen, buffer);
      if (error) {
         _mem_free(buffer);
      } /* Endif */

   } /* Endif */

   if (!error) {
      error = RTCSPCB_insert_header(pcb, sizeof(ICMP_HEADER) + 4);
   } /* Endif */

   if (error) {
      IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      IF_ICMP_STATS_ENABLED(RTCS_seterror(&ICMP_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb));
      RTCSLOG_PCB_FREE(pcb, error);
      RTCSPCB_free(pcb);
      return;
   } /* Endif */

   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_ICMP), 0);

   /* Build the header */
   icmph = (ICMP_ERR_HEADER_PTR)RTCSPCB_DATA(pcb);
   htonc(icmph->HEAD.TYPE,     type);
   htonc(icmph->HEAD.CODE,     code);
   htons(icmph->HEAD.CHECKSUM, 0);
   htonl(icmph->DATA,          param);

   checksum = IP_Sum_PCB (0, pcb);
   checksum = IP_Sum_invert(checksum);
   htons(icmph->HEAD.CHECKSUM, checksum);

#if RTCSCFG_ENABLE_ICMP_STATS
   /* Update the statistics */
   switch (type) {
   case ICMPTYPE_DESTUNREACH: ICMP_cfg_ptr->STATS.ST_TX_DESTUNREACH++; break;
   case ICMPTYPE_TIMEEXCEED:  ICMP_cfg_ptr->STATS.ST_TX_TIMEEXCEED++;  break;
   case ICMPTYPE_PARMPROB:    ICMP_cfg_ptr->STATS.ST_TX_PARMPROB++;    break;
   case ICMPTYPE_SRCQUENCH:   ICMP_cfg_ptr->STATS.ST_TX_SRCQUENCH++;   break;
   case ICMPTYPE_REDIRECT:    ICMP_cfg_ptr->STATS.ST_TX_REDIRECT++;    break;
   case ICMPTYPE_ECHO_REQ:    ICMP_cfg_ptr->STATS.ST_TX_ECHO_REQ++;    break;
   case ICMPTYPE_ECHO_REPLY:  ICMP_cfg_ptr->STATS.ST_TX_ECHO_REPLY++;  break;
   case ICMPTYPE_TIME_REQ:    ICMP_cfg_ptr->STATS.ST_TX_TIME_REQ++;    break;
   case ICMPTYPE_TIME_REPLY:  ICMP_cfg_ptr->STATS.ST_TX_TIME_REPLY++;  break;
   case ICMPTYPE_INFO_REQ:    ICMP_cfg_ptr->STATS.ST_TX_INFO_REQ++;    break;
   case ICMPTYPE_INFO_REPLY:  ICMP_cfg_ptr->STATS.ST_TX_INFO_REPLY++;  break;
   default:                   ICMP_cfg_ptr->STATS.ST_TX_OTHER++;       break;
   } /* Endswitch */
#endif


#if RTCSCFG_ENABLE_NAT
   /* Reverse NAT (if it is installed) on the origpcb,
      otherwise the icmp error will not get sent to the
      original src */
   nat_exec = RTCS_getcfg(NAT);
   if (origpcb && nat_exec && *nat_exec) {
      // swap src and dst IPs and ports so NAT_apply
      // will process the pcb
      ip_hdr = (IP_HEADER_PTR)RTCSPCB_DATA(origpcb);
      protocol = ntohc(ip_hdr->PROTOCOL);
      // Swap ports if it is udp or tcp
      if ((protocol == IPPROTO_TCP) || (protocol == IPPROTO_UDP)) {
         switch(protocol)
         {
            case IPPROTO_TCP:
               tcp_hdr = (TCP_HEADER_PTR)((uchar_ptr)ip_hdr + IPH_LEN(ip_hdr));
               dest_port = ntohs(tcp_hdr->dest_port);
               src_port  = ntohs(tcp_hdr->source_port);
               htons(tcp_hdr->dest_port, src_port);
               htons(tcp_hdr->source_port, dest_port);
               break;
            case IPPROTO_UDP:
               udp_hdr = (UDP_HEADER_PTR)((uchar_ptr)ip_hdr + IPH_LEN(ip_hdr));
               dest_port = ntohs(udp_hdr->DEST_PORT);
               src_port  = ntohs(udp_hdr->SRC_PORT);
               htons(udp_hdr->DEST_PORT, src_port);
               htons(udp_hdr->SRC_PORT, dest_port);            
               break;
            default:
               // should not get here
               break;
         }
      }
      // swap IPs
      ipsrc = ntohl(ip_hdr->SOURCE);
      ipdst = ntohl(ip_hdr->DEST);
      htonl(ip_hdr->SOURCE, ipdst);
      htonl(ip_hdr->DEST,ipsrc);

      // call NAT
      error = (*nat_exec)(&origpcb);

      if (!error) {
         // swap IPs and ports back
         ip_hdr = (IP_HEADER_PTR)RTCSPCB_DATA(origpcb);
         protocol = ntohc(ip_hdr->PROTOCOL);
         // swap ports if it is udp or tcp
         if ((protocol == IPPROTO_TCP) || (protocol == IPPROTO_UDP)) {
            switch(protocol)
            {
               case IPPROTO_TCP:
                  tcp_hdr = (TCP_HEADER_PTR)((uchar_ptr)ip_hdr + IPH_LEN(ip_hdr));
                  dest_port = ntohs(tcp_hdr->dest_port);
                  src_port  = ntohs(tcp_hdr->source_port);
                  htons(tcp_hdr->dest_port, src_port);
                  htons(tcp_hdr->source_port, dest_port);
                  break;
               case IPPROTO_UDP:
                  udp_hdr = (UDP_HEADER_PTR)((uchar_ptr)ip_hdr + IPH_LEN(ip_hdr));
                  dest_port = ntohs(udp_hdr->DEST_PORT);
                  src_port  = ntohs(udp_hdr->SRC_PORT);
                  htons(udp_hdr->DEST_PORT, src_port);
                  htons(udp_hdr->SRC_PORT, dest_port);            
                  break;
               default:
                  // should not get here
                  break;
            }
         }
         // swap IPs
         ipsrc = ntohl(ip_hdr->SOURCE);
         ipdst = ntohl(ip_hdr->DEST);
         htonl(ip_hdr->SOURCE, ipdst);
         htonl(ip_hdr->DEST,ipsrc);   

         // Recalculate the cksum
         htons(icmph->HEAD.CHECKSUM, 0);
         checksum = IP_Sum_PCB (0, pcb);
         checksum = IP_Sum_invert(checksum);
         htons(icmph->HEAD.CHECKSUM, checksum);

         // recalculate icmpsrc, and use new ipsrc.
         ipdst = ntohl(ip_hdr->DEST);
         ipsrc = ntohl(ip_hdr->SOURCE);
         icmpsrc = IP_is_local(NULL,ipdst) ? ipdst : INADDR_ANY;
      }
   }
#endif
   
   /* Send it */
   IP_send(pcb, IPPROTO_ICMP, icmpsrc, ipsrc, 0);

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ICMP_send_error
* Returned Values : void
* Comments        :
*     Send a ICMP error with the IP header that produced it.
*
* Warning         :
*     This packet assumes that the IP header is correct,
*     i.e. IP must not use this function on packets recorded
*     in ST_RX_HDR_ERRORS.
*
*END*-----------------------------------------------------------------*/

void ICMP_send_error
   (
      uint_8         type,    /* [IN] the type to send */
      uint_8         code,    /* [IN] the code to send */
      uint_32        param,   /* [IN] a parameter */
      RTCSPCB_PTR    inpcb,   /* [IN] the packet which caused the error */
      int_32         layer    /* [IN] IP layer, relative to current */
   )
{ /* Body */
   IP_HEADER_PTR  iph = (IP_HEADER_PTR)RTCSPCB_DATA_NETWORK(inpcb);

   /* Don't send an error in response to a broadcast packet */
   if (inpcb->TYPE & RTCSPCB_TYPE_BROADCAST) {
      return;
   } /* Endif */

   ICMP_send_error_internal(type, code, param, iph, inpcb, 0);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_ICMP && RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GDFLIB/GDFLIB_FilterIIR2.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GDFLIB_FilterIIR2.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GDFLIB_FilterIIR2 function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GDFLIB_FILTER_IIR2_H
#define _GDFLIB_FILTER_IIR2_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif
     
/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GDFLIB_FilterIIR2InitANSIC function.*/
#define GDFLIB_FilterIIR2Init(pParam) \
    GDFLIB_FilterIIR2InitANSIC(pParam)

/*! Function alias for the #GDFLIB_FilterIIR2ANSIC function.*/
#define GDFLIB_FilterIIR2(f32In,pParam)\
        GDFLIB_FilterIIR2ANSIC(f32In,pParam)

/*! Macro containing default values of the second order IIR filter structure.*/
#define GDFLIB_FILTER_IIR2_DEFAULT   {{0,0,0,0,0},{0,0},{0,0}}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct FILTER_IIR2_COEFF_T "\GDFLIB_FilterIIR2.h"

@brief  Sub-structure containing filter coefficients.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32 f32B0;  /*!< b0 coefficient of an IIR2 filter, 32-bit */
    Frac32 f32B1;  /*!< b1 coefficient of an IIR2 filter, 32-bit */
    Frac32 f32B2;  /*!< b2 coefficient of an IIR2 filter, 32-bit */
    Frac32 f32A1;  /*!< a1 coefficient of an IIR2 filter, 32-bit */
    Frac32 f32A2;  /*!< a2 coefficient of an IIR2 filter, 32-bit */
}FILTER_IIR2_COEFF_T;

/*------------------------------------------------------------------------*//*!
@struct GDFLIB_FILTER_IIR2_T "\GDFLIB_FilterIIR2.h"

@brief  Structure containing filter buffer and coefficients.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    FILTER_IIR2_COEFF_T trFiltCoeff;  /*!< filter coefficients substructure */
    Frac32 f32FiltBufferX[3];        /*!< input buffer of an IIR2 filter */
    Frac32 f32FiltBufferY[3];        /*!< internal accumulator buffer */
}GDFLIB_FILTER_IIR2_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*! 
* @ingroup GDFLIB_GROUP 
*/

/*! @brief  Prototype of function for clearing buffers of IIR2 filter.*/
extern void GDFLIB_FilterIIR2InitANSIC(GDFLIB_FILTER_IIR2_T *pParam);

/*! @brief  Prototype of direct form II second order IIR filter.*/
extern Frac32 GDFLIB_FilterIIR2ANSIC(Frac32 f32InErr, \
                                      GDFLIB_FILTER_IIR2_T *pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GDFLIB_FILTER_IIR2_H */



<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_lfn.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_lfn.c$
* $Version : 3.8.15.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains functions related to using long filenames of up to
*   255 characters.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_lfn_to_sfn
* Returned Value   :  none
* Comments  :  Will take a long filename (actual file name or directory name
*   and will parse it into the corresponding 8.3 name. It is assumed that 
*   there is space allocated for the short name. 
*END*---------------------------------------------------------------------*/

_mfs_error  MFS_lfn_to_sfn
    (
    char_ptr    l_fname,    /*[IN] the long filename */
    char_ptr    s_fname     /*[OUT] the short filename */
    )
{
    int_32      i; 
    int_32      len;
    char_ptr    temp_lname1, temp_lname2;
    char_ptr    new, orig, valid_dot = NULL;
    _mfs_error  error_code;

    error_code = MFS_alloc_2paths(&temp_lname1,&temp_lname2);
    if ( error_code != MFS_NO_ERROR )
    {
        return( error_code );
    }

    orig = l_fname;
    new = temp_lname1;

    /* 1. Remove all spaces and translate all unwanted 8.3 chars into '_' */
    for ( i = 0 ; i < FILENAME_SIZE; i++ )
    {
        if ( *orig == '\0' )
        {
            break;
        }

        switch (*orig)
        {
            case '[':
            case ']':
            case ';':
            case ',':
            case '+':
            case '=':
                *new++ = '_';
                orig++;
                break;
                
            case ' ':
                orig++;
                break;

            default:
                *new++ = *orig++;
                break;            
        }        
    }  
    *new-- = '\0';

    /* Remove all of the trailing '.'  */
    while ( *new == '.' )
    {
        *new-- = '\0';
    }  

    /* 
    ** Locate the valid '.' if there is one
    */
    while ( new != temp_lname1 )
    {
        if ( *new == '.' )
        {
            valid_dot = new;
            break;
        }
        new--;
    }  

    /* Now we can start copying to the new name, without the extra periods */
    new = temp_lname2;
    orig = temp_lname1;
    while ( *orig != '\0' )
    {
        if ( *orig == '.' )
        {
            if ( orig == valid_dot )
            {
                *new++ = *orig++;
            }
            else
            {
                orig++;
            }  
        }
        else
        {
            *new++ = *orig++;
        }  
    }  
    *new = '\0';

    /* Now we create final 8.3 name */
    for ( i = 0 ; i <= 5 && temp_lname2[i] != '.' && temp_lname2[i] != '\0'; i++ )
    {
        s_fname[i] =  temp_lname2[i];
    }     

    len = i;
    s_fname[len++] = '~';
    s_fname[len++] = '1';
    if ( valid_dot != NULL )
    {
        s_fname[len++] = '.';
        orig = temp_lname2;
        while ( *orig++ != '.' )
            /* void */ ;
        for ( i = 0 ; i <= 2 && orig[i] != '\0'; i++ )
        {
            s_fname[len++] = orig[i];
        }  
    }

    s_fname[len] = '\0';

    /* Capitalize the name */
    for ( i = 0; i <= len - 1; i++ )
        if ( s_fname[i] >= 'a' && s_fname[i] <= 'z' )
        {
            s_fname[i] -= 32;
        }

    MFS_free_path(temp_lname1);
    MFS_free_path(temp_lname2);

    return( MFS_NO_ERROR );
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_is_valid_lfn
* Returned Value   :  boolean
* Comments  :  Will take a long filename (actual file name or directory name)
*   and will validate it by checking for length and for invalid characters.
*END*---------------------------------------------------------------------*/

boolean  MFS_is_valid_lfn
    (
    char_ptr    l_fname /*[IN] the long filename */
    )
{
    register uint_32     i, k;
    register char        c;
    char                 illegal[] = "*?<>|\":/\\";
    boolean              ok_char_flag;

    ok_char_flag = FALSE;
    for ( i = 0 ; i <= FILENAME_SIZE ; i++ )
    {
        c = *l_fname;
        /* if we have reached the end, and there was some chars, the name is ok */
        if ( *l_fname == '\0' )
        {
            return(ok_char_flag); 
        }
        else if ( c == '.' || c == ' ' )
        {
            /* Do nothing */      
        }
        else
        {
            for ( k=0 ; k <= 8; k++ )
            {
                if ( c == illegal[k] )
                {
                    return( FALSE );
                }
            }  
            ok_char_flag = TRUE;
        }  
        l_fname++;
    }        

    if ( i <= FILENAME_SIZE && ok_char_flag )
    {
        return( TRUE );
    }

    return( FALSE );
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_is_autogenerated_name
* Returned Value   :  boolean
* Comments  :  Will take a short filename (actual file name or directory name)
*   and will determine if it is an autogenerated name. If it is, LFN entries
*   should exist for it, if not no LFN entries should exist.
*
*  The autogenerated name has the following format:
*     [
*
*END*---------------------------------------------------------------------*/

boolean  MFS_is_autogenerated_name
    (
    char_ptr    s_fname /*[IN] the long filename */
    )
{
    uint_32  i, digits=0;
    boolean  found_tilde = FALSE;


    for ( i=0;i<SFILENAME_SIZE;i++ )
    {
        if ( !found_tilde )
        {
            // Looking for '~'
            switch ( s_fname[i] )
            {
                case '[':
                case ']':
                case ';':
                case ',':
                case '+':
                case '=':
                case ' ':
                case '\0':
                    // All invalid before ~ in an autogenerated name.
                    return FALSE;

                case '~':
                    found_tilde=TRUE;
                    break;
            }
        }
        else
        {
            // Found '~', counting numbers
            if ( (s_fname[i]=='.')  || (s_fname[i]==0) )
            {
                // Valid if we saw at least on digit
                return(digits!=0);
            }

            if ( (s_fname[i]>='0') && (s_fname[i]<='9') )
            {
                digits++;
                if ( digits>6 ) return FALSE;
            }
        }
    }
    return FALSE;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_lfn_dirname_valid
* Returned Value   :  boolean - TRUE if valid LFN directory name.
* Comments  :
*        Allows . and ..
*END*---------------------------------------------------------------------*/

boolean MFS_lfn_dirname_valid
    (
     char_ptr        filename   /*[IN] filename to validate */
    )
{

    if ( *filename != '.' )
    {
        return(MFS_is_valid_lfn(filename));
    }
    else
    {
        if ( (*(filename + 1) == '\0') ||
            ((*(filename+1) == '.') && *(filename+2) == '\0') )
        {
            return(TRUE);
        }
    }  

    return(FALSE);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_lfn_match
* Returned Value   :  boolean - TRUE if the dir_entry_ptr points to the entry
*                     actually corresponding to the LFN. 
* Comments  : Will read the previous entries and reconstruct the LFN
*END*---------------------------------------------------------------------*/

boolean MFS_lfn_match
    (
    char_ptr  search_ptr,   /* [IN] the search string */
    char_ptr  lfn,          /* [IN] the long file name to compare */
    uint_32   level         /* [IN] the level of recursion or the number of * encountered */
    ) 
{
    char cw;
    char ct;

    if ( *search_ptr == '\0' )
    {
        return TRUE;
    }
    if ( *lfn == '\0' )
    {
        return FALSE;
    }

    while ( *search_ptr )
    {
        if ( *lfn == '\0' )
        {
            if ( (*search_ptr == '*') || (*search_ptr == '?') )
            {
                if ( !*(search_ptr+1) )
                {
                    return TRUE;
                }
            }
            return FALSE;
        }
        else if ( *search_ptr == '?' )
        {
            search_ptr++;
            lfn++;
        }
        else if ( *search_ptr == '*' )
        {
            if ( level > 3 )
            {
                return FALSE;
            }
            search_ptr++;
            while ( *lfn )
            {
                if ( MFS_lfn_match(search_ptr, lfn, level + 1) )
                {
                    return TRUE;
                }
                lfn++;
            }  
        }
        else
        {
            cw = CAPITALIZE(*search_ptr);
            ct = CAPITALIZE(*lfn);
            if ( cw != ct )
            {
                return FALSE;
            }
            else
            {
                search_ptr++;
                lfn++;
            }  
        }  
    }  
    if ( *lfn )
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }  
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_lfn_extract
* Returned Value   :  
*
* Comments  : Will take a LFN directory entry and extract the name for
*             the given entry. Will copy the 13 UNICODE chars fromt the
*             entry. The output string does not always end with '\0'.
*             Assumes the entry is valid.
*END*---------------------------------------------------------------------*/

void MFS_lfn_extract
    (
    MFS_LNAME_ENTRY_PTR     lname_entry,    /* [IN] pointer to the entry to read UNICODE name from */
    char_ptr                filename        /* [OUT] buffer to store the 13 chars in  */
    )
{
    uint_32     i;
    char_ptr     tempfilename;

    /* 
    ** The LFN are stored in unicode. A unicode character occupies 2 bytes. One
    ** byte is the character set, and the other is the character. In our case
    ** we are using a macro to extract the unicode char and we are converting it
    ** directly into a char. We can do this because the ASCII set is represented
    ** by char set 0 (stored in the upper byte). 
    */
    tempfilename = filename;
    for ( i = 0 ; i <= 9 ; i = i + 2 )
    {
        *tempfilename++ = (char) dtohs(lname_entry->NAME0_4 + i);
    }  

    for ( i = 0 ; i <= 11 ; i = i + 2 )
    {
        *tempfilename++ = (char) dtohs(lname_entry->NAME5_10 + i);
    }  

    for ( i = 0 ; i <= 3 ; i = i + 2 )
    {
        *tempfilename++ = (char) dtohs(lname_entry->NAME11_12 + i);
    }  
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_increment_lfn
* Returned Value   :  void
*
* Comments  : Takes a compressed short filename (that represents a lfn) and
*             increments the number after the ~ 
*END*---------------------------------------------------------------------*/

void MFS_increment_lfn
    (
    char_ptr       filename /* [IN]/[OUT] a short compressed filename (a valid one) */
    )
{
    int_32     i;
    uint_32     num;
    uint_32     power;

    /* Find out where the ~ starts and get the number after the ~ */
    for ( i = 7, power = 1, num = 0; i >= 0; i-- )
    {
        if ( filename[i] == '~' )
        {
            break;
        }
        /* Translate the ASCII value to an int value */
        num += power * (uint_32) (filename[i] - '0');
        power *= 10;
    }  

    num++;

    if ( num / power >= 1 )
    {
        i--;
        filename[i] = '~';
        power *= 10;
    }

    /* Write the new number */
    for ( i++ ; i <= 7 ;i++ )
    {
        power /= 10;
        /* Translate the int value into an ASCII value */
        filename[i] = (uchar) (num / power) + '0';
        num %= power;
    }  
}       

#if !MFSCFG_READ_ONLY
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_remove_lfn_entries
* Returned Value   :  uint_32 error code
*
* Comments  : Removes the extra entries (corresponding to the dir_entry_ptr
*             containing the LFN). Can be used on a normal dir entry, but does
*             nothing in this case.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_remove_lfn_entries
    (
    MFS_DRIVE_STRUCT_PTR       drive_ptr,       /* [IN] drive on which to operate */
    uint_32                    parent_cluster,  /* [IN] the cluster in which the entry lies */
    uint_32                    dir_index,       /* [IN] the index of where in the cluster the entry lies */
    uint_32                    prev_cluster     /* [IN] the cluster previous to the cluster in which the entry lies */    
    )
{
    MFS_LNAME_ENTRY_PTR           lname_entry = NULL;
    boolean                       last_entry_flag = FALSE;
    uint_32                       current_index;
    _mfs_error                    error_code = MFS_NO_ERROR;
    uint_32                       temp_prev_cluster;  
    boolean                       went_back = FALSE;
    boolean                       start_deletion = FALSE;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    /* As long as we haven't found the EOF flag in the LFN name */
    while ( last_entry_flag == FALSE )
    {
        /* Check to see if the LFN spans to different sector */
        if ( dir_index == 0 )
        {
            /* Check to see if we are in root directory */
            if ( parent_cluster == 0 )
            {
                break;
            }
            else if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
            {
                if ( drive_ptr->BPB32.ROOT_CLUSTER == parent_cluster )
                {
                    break;
                }
            }
            if ( !went_back )
            {
                error_code = MFS_get_prev_cluster(drive_ptr, &parent_cluster, prev_cluster);
                went_back = TRUE;
            }
            else
            {
                if ( start_deletion )
                {
                    error_code = MFS_FAILED_TO_DELETE_LFN;
                }
                break;
            }
            dir_index = drive_ptr->ENTRIES_PER_SECTOR * drive_ptr->BPB.SECTORS_PER_CLUSTER ;   
        }

        current_index = dir_index;

        if ( !error_code )
        {
            dir_index--;
            lname_entry = (MFS_LNAME_ENTRY_PTR) MFS_Find_directory_entry(drive_ptr, 
                NULL, &parent_cluster, &dir_index, &temp_prev_cluster, MFS_ATTR_LFN, &error_code); 
        }

        /* If a LFN, mark entry as deleted */
        if ( (lname_entry != NULL) && !error_code && (dir_index < current_index) )
        {
            if ( lname_entry->ID & MFS_LFN_END )
            {
                last_entry_flag = TRUE;
            }

            lname_entry->ID = MFS_DEL_FILE;
            drive_ptr->DIR_SECTOR_DIRTY = TRUE;

            start_deletion = TRUE;  
        }
        else
        {
            break;  
        }  
    }  

    return( error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_lfn_name_to_entry
* Returned Value   :  uint_32 error code
*
* Comments  : Takes a string of up to 13 characters and writes them to a LFN 
*             directory entry.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_lfn_name_to_entry
    (
    char_ptr                filename,   /* [IN] a string up to 13 chars long, to be put in the entry */
    MFS_LNAME_ENTRY_PTR     entry_ptr   /* [OUT] the LNAME entry in which the string is places */
    )
{
    uint_32     i;
    boolean     end_of_name = FALSE;

    if ( entry_ptr == NULL )
    {
        return( MFS_CANNOT_CREATE_DIRECTORY );
    }


    /* The entry contains UNICODE chars... Which is why i = i +2 */
    /* Copy chars 0 to 4 */
    for ( i = 0 ; i <= 9 ; i = i + 2 )
    {
        if ( *filename )
        {
            htods((entry_ptr->NAME0_4 + i),(uint_16) *filename);
            filename++;      
        }
        else if ( !end_of_name )
        {
            htods((entry_ptr->NAME0_4 + i), 0);
            end_of_name = TRUE;
        }
        else
        {
            htods((entry_ptr->NAME0_4 + i), 0xFFFF);
        }  
    }  

    /* Copy chars 5 to 10 */
    for ( i = 0 ; i <= 11 ; i = i + 2 )
    {
        if ( *filename )
        {
            htods((entry_ptr->NAME5_10 + i), (uint_16) *filename);      
            filename++;
        }
        else if ( !end_of_name )
        {
            htods((entry_ptr->NAME5_10 + i), 0);
            end_of_name = TRUE;
        }
        else
        {
            htods((entry_ptr->NAME5_10 + i), 0xFFFF);         
        }  
    }  

    /* Copy chars 11 to 12 */
    for ( i = 0 ; i <= 3 ; i = i + 2 )
    {
        if ( *filename )
        {
            htods((entry_ptr->NAME11_12 + i), (uint_16) *filename);      
            filename++;
        }
        else if ( !end_of_name )
        {
            htods((entry_ptr->NAME11_12 + i), 0);
            end_of_name = TRUE;
        }
        else
        {
            htods((entry_ptr->NAME11_12 + i), 0xFFFF);         
        }  
    }  


    return( MFS_NO_ERROR );
}  

#endif

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_lfn_checksum
* Returned Value   :  uchar checksum
*
* Comments  : Takes a valid expanded filename of 11 characters (doesn't need 
*             to be terminated by a NULL char) and calculates the LFN checksum
*             value for it.
*END*---------------------------------------------------------------------*/
uchar MFS_lfn_checksum
    (
    char_ptr       filename_ptr /*[IN] pointer to filename on which to calculate checksum */
    )
{
    uchar       sum;
    uint_32     i;

    for ( sum = 0, i = 0 ; i < 11 ; i++ )
    {
        sum = (((sum & 1) << 7) | (( sum & 0xfe) >> 1)) + *filename_ptr++;
    }  

    return( sum );
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_get_prev_cluster
* Returned Value   :  uint_32 error_code 
*
* Comments  : Finds the previous cluster in the cluster chain for any given
*             cluster. 
*END*---------------------------------------------------------------------*/

_mfs_error MFS_get_prev_cluster
    (
    MFS_DRIVE_STRUCT_PTR       drive_ptr,       /* [IN] the drive on which to operate */
    uint_32_ptr                cluster_ptr,     /* [IN]/[OUT] cluster to perform search with / previous cluster */
    uint_32                    previous_cluster /* [IN] the previous cluster */  
    )
{
    uint_32        i;
    _mfs_error     error_code = MFS_NO_ERROR;
    uint_32        next_cluster;

    /* Check to see if we are at the very first cluster */
    if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
    {
        if ( *cluster_ptr == drive_ptr->BPB32.ROOT_CLUSTER )
        {
            return MFS_INVALID_CLUSTER_NUMBER;  
        }
    }
    else if ( *cluster_ptr == 0 )
    {
        return MFS_INVALID_CLUSTER_NUMBER;  
    }

    // If we have been given a previous cluster
    if ( previous_cluster != CLUSTER_INVALID )
    {
        // Make sure it is before the current cluster
        MFS_get_cluster_from_fat(drive_ptr, previous_cluster, &next_cluster); 
        if ( *cluster_ptr == next_cluster )
        {
            // It is, so use it
            *cluster_ptr = previous_cluster;
            return MFS_NO_ERROR;
        }
    }

    if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
    {
        return MFS_INVALID_CLUSTER_NUMBER;  
    }

    /* Search the rest of the fat for the wanted cluster */
    for ( i = CLUSTER_MIN_GOOD ; i <= drive_ptr->LAST_CLUSTER &&
        !error_code; i++ )
    {
        MFS_get_cluster_from_fat(drive_ptr, previous_cluster, &next_cluster); 
        if ( *cluster_ptr == next_cluster )
        {
            *cluster_ptr = i;
            break;
        }
    }  

    if ( i > drive_ptr->LAST_CLUSTER )
    {
        error_code = MFS_INVALID_CLUSTER_NUMBER;
    }

    return( error_code );
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_get_lfn
* Returned Value   :  uint_32 error code
*
* Comments  : Will take an a pathname that points to a normal 8.3 entry. 
*             If this entry has a LFN, the LFN will be placed in the lfn buffer.
*             Assumes the drive is locked. 
*END*---------------------------------------------------------------------*/

_mfs_error MFS_get_lfn
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,  /*[IN] the drive on which to operate */
    char_ptr                filepath,   /*[IN] the filepath to the 8.3 filename */
    char_ptr                lfn         /*[OUT] the long file name, if it exists */
    )
{
    MFS_DIR_ENTRY_PTR  entry_ptr;
    uint_32              index;
    uint_32              cluster;
    _mfs_error           error_code;
    uint_32              prev_cluster; 


    // If filepath is not an autogenerated name, then it will not have a
    // corresponding long file name.

    entry_ptr =  MFS_Find_entry_on_disk(drive_ptr, filepath, &error_code, &cluster, &index, &prev_cluster);  

    if ( error_code==MFS_NO_ERROR )
    {
        error_code = MFS_get_lfn_of_entry(drive_ptr,entry_ptr,cluster,index,prev_cluster,lfn);
    }
    return error_code;

}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_get_lfn
* Returned Value   :  uint_32 error code
*
* Comments  : Will take an a pathname that points to a normal 8.3 entry. 
*             If this entry has a LFN, the LFN will be placed in the lfn buffer.
*             Assumes the drive is locked. 
*END*---------------------------------------------------------------------*/

_mfs_error MFS_get_lfn_of_entry
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,  /*[IN] the drive on which to operate */
    MFS_DIR_ENTRY_PTR       entry_ptr,
    uint_32                 cluster,
    uint_32                 index,
    uint_32                 prev_cluster,
    char_ptr                lfn         /*[OUT] the long file name, if it exists */
    )
{
    _mfs_error           error_code=MFS_NO_ERROR;
    uint_32              sum;
    uint_32              entry_count;
    boolean             went_back = FALSE;
    boolean              extracting = FALSE;
    MFS_LNAME_ENTRY_PTR  lfn_entry_ptr;


    if ( entry_ptr == NULL )
    {
        return(MFS_INVALID_PARAMETER);
    }
    else
    {
        /* Calculate the checksum for the file */
        sum = MFS_lfn_checksum(((MFS_DIR_ENTRY_PTR) entry_ptr)->NAME);
    }  

    entry_count = 1;

    while ( TRUE )
    {
        /* Check to see if the LFN spans to different sector */
        if ( index == 0 )
        {
            if ( went_back )
            {
                if ( extracting )
                {
                    error_code = MFS_BAD_LFN_ENTRY;
                }
                break;
            }
            else
            {
                went_back=TRUE;
                error_code = MFS_get_prev_cluster(drive_ptr, &cluster, prev_cluster); 
                index = drive_ptr->ENTRIES_PER_SECTOR * 
                    drive_ptr->BPB.SECTORS_PER_CLUSTER ; 
            } 
        }

        if ( !error_code )
        {
            index--;
            entry_ptr = MFS_Find_directory_entry(drive_ptr, 
                NULL, &cluster, &index, &prev_cluster, MFS_ATTR_ANY, &error_code); 
        }

        if ( error_code )
        {
            *lfn = '\0';
            return( error_code );
        }

        if ( !entry_ptr )
        {
            *lfn = '\0';
            return MFS_FILE_NOT_FOUND;
        }

        lfn_entry_ptr = (MFS_LNAME_ENTRY_PTR) entry_ptr;

        if ( lfn_entry_ptr->ATTR != MFS_ATTR_LFN )
        {
            *lfn = '\0';
            return MFS_FILE_NOT_FOUND;
        }

        if ( lfn_entry_ptr->ALIAS_CHECKSUM != sum )
        {
            *lfn = '\0';
            break;
        }
        else if ( !(lfn_entry_ptr->ID & entry_count++) )
        {
            *lfn = '\0';
            break;
        }
        else
        {
            MFS_lfn_extract(lfn_entry_ptr, lfn);
            lfn = lfn + 13;
            *lfn = '\0';
        }  

        /* Check if this is the last entry */
        if ( lfn_entry_ptr->ID & MFS_LFN_END )
        {
            break;
        }
    }  

    return( MFS_NO_ERROR );
}  

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_get_lfn_dir_cluster
* Returned Value   :  uint_32 error code
*
* Comments  : Will take an a current directory cluster entry. 
*             If this entry has a LFN, the LFN will be placed in the lfn buffer.
*             Assumes the drive is locked. 
*END*---------------------------------------------------------------------*/

_mfs_error MFS_get_lfn_dir_cluster
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,          /*[IN] the drive on which to operate */
    pointer                 search_next_ptr,    /*[IN] address of search data block indicating the current criteria and the results of
                                                ** the last search results of this search are placed in this data block */
    char_ptr                filepath,           /*[OUT] the long file name, if it exists */
    char_ptr                lfn                 /*[IN] the filepath to the 8.3 filename */
    )
{
    MFS_INTERNAL_SEARCH_PTR     internal_search_ptr;
    MFS_LNAME_ENTRY_PTR         entry_ptr;
    uint_32                     index;
    uint_32                     cluster;
    _mfs_error                  error_code;
    uint_32                     sum;
    uint_32                     entry_count;
    MFS_SEARCH_DATA_PTR         transfer_ptr;
    uint_32                     temp_prev_cluster; 
    boolean                     went_back = FALSE;
    boolean                     extracting = FALSE;

    transfer_ptr = (MFS_SEARCH_DATA_PTR) search_next_ptr;

    if ( transfer_ptr == NULL )
    {
        return(MFS_INVALID_PARAMETER);
    }

    internal_search_ptr = &transfer_ptr->INTERNAL_SEARCH_DATA;                      
    entry_ptr = (MFS_LNAME_ENTRY_PTR)MFS_Find_directory_entry(drive_ptr,NULL, &internal_search_ptr->CURRENT_CLUSTER,
        &internal_search_ptr->DIR_ENTRY_INDEX, &internal_search_ptr->PREV_CLUSTER, MFS_ATTR_ANY,&error_code);
    cluster    = internal_search_ptr->CURRENT_CLUSTER;
    index      = internal_search_ptr->DIR_ENTRY_INDEX;
    /* Calculate the checksum for the file */
    sum = MFS_lfn_checksum(((MFS_DIR_ENTRY_PTR) entry_ptr)->NAME);

    entry_count = 1;

    while ( TRUE )
    {
        /* Check to see if the LFN spans to different sector */
        if ( index == 0 )
        {
            if ( went_back )
            {
                if ( extracting )
                {
                    error_code = MFS_BAD_LFN_ENTRY;
                }
                break;
            }
            else
            {
                went_back=TRUE;
                error_code = MFS_get_prev_cluster(drive_ptr, &cluster, internal_search_ptr->PREV_CLUSTER); 
                index = drive_ptr->ENTRIES_PER_SECTOR * drive_ptr->BPB.SECTORS_PER_CLUSTER ;   
            }
        }

        if ( !error_code )
        {
            index--;
            entry_ptr = (MFS_LNAME_ENTRY_PTR) MFS_Find_directory_entry(drive_ptr, 
                NULL, &cluster, &index, &temp_prev_cluster, MFS_ATTR_ANY, &error_code); 
        }

        if ( error_code )
        {
            *lfn = '\0';
            return( error_code );
        }

        if ( !entry_ptr )
        {
            *lfn = '\0';
            return MFS_FILE_NOT_FOUND;
        }

        if ( entry_ptr->ATTR != MFS_ATTR_LFN )
        {
            *lfn = '\0';
            return MFS_FILE_NOT_FOUND;
        }

        if ( entry_ptr->ALIAS_CHECKSUM != sum )
        {
            *lfn = '\0';
            break;
        }
        else if ( !(entry_ptr->ID & entry_count++) )
        {
            *lfn = '\0';
            break;
        }
        else
        {
            extracting = TRUE; 
            MFS_lfn_extract(entry_ptr, lfn);
            lfn = lfn + 13;
            *lfn = '\0';
        }  

        /* Check if this is the last entry */
        if ( entry_ptr->ID & MFS_LFN_END )
        {
            break;
        }
    }  

    return( MFS_NO_ERROR );
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/ipif_rem.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipif_rem.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the
*   packet driver interface.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_remove
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     [IN] the IP interface handle
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     not used
*     _ip_address          locmask     not used
*     _ip_address          network     not used
*     _ip_address          netmask     not used
*
*  Comments       :
*        Unregisters a hardware interface with RTCS.
*
*END*-----------------------------------------------------------------*/

void IPIF_remove
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */
   IP_CFG_STRUCT_PTR IP_cfg_ptr;
   IP_IF_PTR         ipif;
   uint_32           error;

   IP_cfg_ptr = RTCS_getcfg(IP);

   ipif = (IP_IF_PTR)parms->ihandle;
   error = ipif->DEVICE.CLOSE(ipif);

   /* Enqueue onto the free list */
   ipif->HANDLE = IF_FREE;
   IF_FREE = ipif;

   RTCSCMD_complete(parms, error);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_unbind
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     [IN] the IP interface handle
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     [IN] the local address
*     _ip_address          locmask     not used
*     _ip_address          network     not used
*     _ip_address          netmask     not used
*
*  Comments       :
*        Unbinds an IP address and network from a hardware interface.
*
*END*-----------------------------------------------------------------*/

void IPIF_unbind
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   _ip_address    mask;

   IP_route_remove_direct(parms->address, 0xFFFFFFFF, parms->ihandle);
   
#if RTCSCFG_ENABLE_IGMP 
   if (parms->ihandle) {
      ((IP_IF_PTR)(parms->ihandle))->IGMP_UNBIND((IP_IF_PTR)parms->ihandle,
         parms->address);
   } /* Endif */
#endif
   IP_get_netmask(parms->ihandle, parms->address, &mask);
   
   /* If mask is invalid do not try to remove direct route */
   if (mask != 1)
   {
        IP_route_remove_direct(parms->address, mask, parms->ihandle);
   }
   RTCSCMD_complete(parms, RTCS_OK);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);

#endif /* RTCSCFG_ENABLE_IP4 */
   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_unbind_ppp
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     [IN] the IP interface handle
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     [IN] the local address
*     _ip_address          locmask     not used
*     _ip_address          network     [IN] the peer address
*     _ip_address          netmask     not used
*
*  Comments       :
*        Unbinds an IP address and network from a hardware interface.
*
*END*-----------------------------------------------------------------*/

void IPIF_unbind_ppp
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   IP_route_remove_virtual(parms->network, 0xFFFFFFFF, parms->address,
      INADDR_ANY, INADDR_ANY, parms->ihandle);
      
#if RTCSCFG_ENABLE_IGMP
   if (parms->ihandle) {
      ((IP_IF_PTR)(parms->ihandle))->IGMP_UNBIND((IP_IF_PTR)parms->ihandle,
         parms->address);
   } /* Endif */
#endif

   IP_route_remove_direct(parms->address, 0xFFFFFFFF, parms->ihandle);

   RTCSCMD_complete(parms, RTCS_OK);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);

#endif /* RTCSCFG_ENABLE_IP4 */
   

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPIF_gate_remove
*  Parameters     :
*
*     pointer              mhandle     not used
*     _rtcs_if_handle      ihandle     not used
*     RTCS_IF_STRUCT_PTR   if_ptr      not used
*     _ip_address          address     [IN] the gateway address
*     _ip_address          locmask     not used
*     _ip_address          network     [IN] the network address
*     _ip_address          netmask     [IN] the network address mask
*
*  Comments       :
*        Removes a gateway from the routing table.
*
*END*-----------------------------------------------------------------*/

void IPIF_gate_remove
   (
      IPIF_PARM_PTR  parms
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

    /* Start CR 1133 */
    IP_route_remove_indirect(parms->address, parms->netmask, parms->network, RTF_STATIC, parms->locmask);
    /* End CR 1133 */

    RTCSCMD_complete(parms, RTCS_OK);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);

#endif /* RTCSCFG_ENABLE_IP4 */
   

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/dhcpuprv.h<|end_filename|>
#ifndef __dhcpuprv_h__
#define __dhcpuprv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dhcpuprv.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   Dynamic Host Configuration Protocol utility prototypes.
*
*END************************************************************************/

/***************************************
**
** Prototypes
**
*/
static void DHCPCLNT_fill_header ( DHCP_CLNT_STRUCT  _PTR_ );
static void DHCPCLNT_fill_options (DHCP_CLNT_STRUCT  _PTR_,
                                   TCPIP_PARM_IF_DHCP _PTR_ );
static void DHCPCLNT_open ( DHCP_CLNT_STRUCT _PTR_ );
static void DHCPCLNT_modify_options ( DHCP_CLNT_STRUCT _PTR_ );
static void DHCPCLNT_send_one_shot ( DHCP_CLNT_STRUCT _PTR_ );
static boolean DHCPCLNT_rebind_lease ( TCPIP_EVENT _PTR_ );
static boolean DHCPCLNT_renew_lease ( TCPIP_EVENT _PTR_ );
static boolean DHCPCLNT_terminate_lease ( TCPIP_EVENT _PTR_ );
static boolean DHCPCLNT_bind_attempt_timeout( TCPIP_EVENT _PTR_ );
static void DHCPCLNT_decline ( DHCP_CLNT_STRUCT _PTR_, uint_32 );
static void DHCPCLNT_parse_offer ( DHCP_CLNT_STRUCT _PTR_, RTCSPCB _PTR_ );
static void DHCPCLNT_copy_binding ( DHCP_CLNT_STRUCT _PTR_ );
static boolean DHCPCLNT_verify_address ( DHCP_CLNT_STRUCT _PTR_ );
static uchar DHCPCLNT_verify_packet (DHCP_CLNT_STRUCT _PTR_, RTCSPCB_PTR, uchar _PTR_, uint_32 _PTR_, _ip_address _PTR_, _ip_address _PTR_, uint_32 _PTR_);
static void DHCPCLNT_service_offer (DHCP_CLNT_STRUCT _PTR_, RTCSPCB_PTR, uchar _PTR_, uint_32, _ip_address, _ip_address);
static void DHCPCLNT_service_ack (DHCP_CLNT_STRUCT _PTR_, RTCSPCB_PTR, uchar _PTR_, uint_32, IP_IF_PTR);
/* Start CR 2199 */
static void DHCPCLNT_service_nak (DHCP_CLNT_STRUCT _PTR_, uchar _PTR_, uint_32);
/* End CR 2199 */  
static void DHCPCLNT_set_timed_events(DHCP_CLNT_STRUCT _PTR_);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/amd/29f0xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: 29f0xx.c$
* $Version : 3.8.4.0$
* $Date    : Oct-4-2011$
*
* Comments:
*
*   The file contains functions to program any AMD 29F0XX
*   flash device.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "29f0xx.h"
#include "29f0xx_prv.h"

const FLASHX_DEVICE_IF_STRUCT _29f0xx_if = {
    _29f0xx_sector_erase,
    _29f0xx_program,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29f0xx_program
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs the prom device listed below:
* 
*END*----------------------------------------------------------------------*/

boolean _29f0xx_program
   (  
      /* [IN] the flash information */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] where to copy data from */
      char_ptr             from_ptr,
      
      /* [OUT} where to copy data to */
      char_ptr             to_ptr,

      /* [IN] the amount to program */
      _mem_size            bytes
   )
{ /* Body */
   boolean result = TRUE;
   uint_32 count = bytes;
   uint_32 timeout;
   uint_32 tmp1;
   uint_32 tmp2;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 32){
      volatile uint_32 _PTR_  base32_ptr;
      volatile uint_32 _PTR_  dest32_ptr;
      uint_32_ptr             src32_ptr;

      src32_ptr  = (uint_32_ptr)from_ptr;         
      dest32_ptr = (volatile uint_32 _PTR_)to_ptr;
      base32_ptr = (volatile uint_32 _PTR_)to_ptr;

      *base32_ptr = 0xFFFFFFFF; /* Set read mode */

      count = (count+3) & ~3;   /* Round count up, multiple of 4 */
      while (count > 0) {
         tmp1 = *src32_ptr++;
         if (tmp1 != 0xFFFFFFFF) {
            base32_ptr[0x5555] = 0xAAAAAAAA; 
            base32_ptr[0x2AAA] = 0x55555555;
            base32_ptr[0x5555] = 0xA0A0A0A0;       /* Write command */
            dest32_ptr[0]      = tmp1;
            timeout = 100;
            while (timeout) {
               tmp2 = dest32_ptr[0];
               /* Check timeout or data bit of byte being programmed */
               if ((tmp2 & 0x80808080) != (tmp1 & 0x80808080)) {
                  /* Check for timeout error */
                  if ((tmp2 & 0x20202020) == 0x20202020) {
                     tmp2 = dest32_ptr[0];
                     if ((tmp2 & 0x80808080) != (tmp1 & 0x80808080)) {
                        result = FALSE;
                        *base32_ptr = 0xFFFFFFFF; /* Set read mode */
                        goto done;
                     } /* Endif */
                     break;
                  } /* Endif */
               } else  {
                  break;      /* done: byte programmed */
               } /* Endif */
               _io_flashx_wait_us(10);
               timeout--;
            } /* Endwhile */
            if (timeout==0) {
               result = FALSE;
               *base32_ptr = 0xFFFFFFFF; /* Set read mode */
               goto done;
            } /* Endif */
         } /* Endif */
         dest32_ptr++;
         count -= 4;
      } /* Endwhile */

      *base32_ptr = 0xFFFFFFFF; /* Set read mode */

   } else if (flashx_ptr->WIDTH == 16){
      volatile uint_16 _PTR_  base16_ptr;
      volatile uint_16 _PTR_  dest16_ptr;
      uint_16_ptr             src16_ptr;

      src16_ptr  = (uint_16_ptr)from_ptr;         
      dest16_ptr = (volatile uint_16 _PTR_)to_ptr;
      base16_ptr = (volatile uint_16 _PTR_)to_ptr;

      *base16_ptr = 0xFFFF; /* Set read mode */

      count = (count+1) & ~1;   /* Round count up, multiple of 2 */
      while (count > 0) {
         tmp1 = *src16_ptr++;
         if (tmp1 != 0xFFFF) {
            base16_ptr[0x5555] = 0xAAAA; 
            base16_ptr[0x2AAA] = 0x5555;
            base16_ptr[0x5555] = 0xA0A0;       /* Write command */
            dest16_ptr[0]      = tmp1;
            timeout = 100;
            while (timeout) {
               tmp2 = dest16_ptr[0];
               /* Check timeout or data bit of byte being programmed */
               if ((tmp2 & 0x8080) != (tmp1 & 0x8080)) {
                  /* Check for timeout error */
                  if ((tmp2 & 0x2020) == 0x2020) {
                     tmp2 = dest16_ptr[0];
                     if ((tmp2 & 0x8080) != (tmp1 & 0x8080)) {
                        result = FALSE;
                        *base16_ptr = 0xFFFF; /* Set read mode */
                        goto done;  /*** */
                     } /* Endif */
                     break;
                  } /* Endif */
               } else  {
                  break;      /* done: byte programmed */
               } /* Endif */
               _io_flashx_wait_us(10);
               timeout--;
            } /* Endwhile */
            if (timeout==0) {
               result = FALSE;
               *base16_ptr = 0xFFFF; /* Set read mode */
               goto done;  /*** */
            } /* Endif */
         } /* Endif */
         dest16_ptr++;
         count -= 2;
      } /* Endwhile */

      *base16_ptr = 0xFFFF; /* Set read mode */

   } else if (flashx_ptr->WIDTH == 8){
      volatile uint_8  _PTR_  base8_ptr;
      volatile uint_8  _PTR_  dest8_ptr;
      uint_8_ptr              src8_ptr;

      src8_ptr  = (uint_8_ptr)from_ptr;         
      dest8_ptr = (volatile uint_8 _PTR_)to_ptr;
      base8_ptr = (volatile uint_8 _PTR_)to_ptr;

      *base8_ptr = 0xFF; /* Set read mode */

      while (count > 0) {
         tmp1 = *src8_ptr++;
         if (tmp1 != 0xFFFF) {
            base8_ptr[0x5555] = 0xAA; 
            base8_ptr[0x2AAA] = 0x55;
            base8_ptr[0x5555] = 0xA0;       /* Write command */
            dest8_ptr[0]      = tmp1;
            timeout = 100;
            while (timeout) {
               tmp2 = dest8_ptr[0];
               /* Check timeout or data bit of byte being programmed */
               if ((tmp2 & 0x80) != (tmp1 & 0x80)) {
                  /* Check for timeout error */
                  if ((tmp2 & 0x20) == 0x20) {
                     tmp2 = dest8_ptr[0];
                     if ((tmp2 & 0x80) != (tmp1 & 0x80)) {
                        result = FALSE;
                        *base8_ptr = 0xFF; /* Set read mode */
                        goto done;  /****/
                     } /* Endif */
                     break;
                  } /* Endif */
               } else  {
                  break;      /* done: byte programmed */
               } /* Endif */
               _io_flashx_wait_us(10);
               timeout--;
            } /* Endwhile */
            if (timeout==0) {
               result = FALSE;
               *base8_ptr = 0xFF; /* Set read mode */
               goto done;  /****/
            } /* Endif */
         } /* Endif */
         dest8_ptr++;
         count -= 1;
      } /* Endwhile */

      *base8_ptr = 0xFF; /* Set read mode */

   }/* Endif */

   if (flashx_ptr->WRITE_VERIFY) {
      /* Verify sector(s) is(are) written correctly */
      uint_32_ptr  src32_ptr  = (uint_32_ptr)from_ptr;
      uint_32_ptr  dest32_ptr =  (uint_32_ptr)to_ptr;
      count = bytes/4 + 1;
      while (--count) {
         if (*src32_ptr++ != *dest32_ptr++) {
            result = FALSE;
            break;
         } /* Endif */
      } /* Endwhile */
   } /* Endif */   

done:
   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */
   return(result);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29f0xx_sector_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases all 29f0xx devices.
* 
*END*----------------------------------------------------------------------*/

boolean _29f0xx_sector_erase
   (
      /* [IN] the flash information */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] the sector to erase */
      char_ptr             input_sect_ptr,

      /* [IN] the number of bytes to erase */
      _mem_size            bytes
   )
{ /* Body */
   boolean result = TRUE;
   uint_32 timeout;
   uint_32 tmp1;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 32){
      volatile uint_32 _PTR_  base32_ptr;
   
      base32_ptr = (volatile uint_32 _PTR_)input_sect_ptr;

      /* Erase a sector */
      base32_ptr[0x5555] = 0xAAAAAAAA;
      base32_ptr[0x2AAA] = 0x55555555;
      base32_ptr[0x5555] = 0x80808080; /* Erase command */
      base32_ptr[0x5555] = 0xAAAAAAAA;
      base32_ptr[0x2AAA] = 0x55555555;

      base32_ptr[0]      = 0x30303030;

      timeout = 9000000;
      while (timeout) {
         tmp1 = base32_ptr[0];
         if ((tmp1 & 0x80808080) == 0x80808080) {
            break;
         } /* Endif */
         if ((tmp1 & 0x20202020) == 0x20202020) {
            tmp1 = base32_ptr[0];
            if ( (tmp1 & 0x80808080) != 0x80808080) {
               base32_ptr[0] = 0xFFFFFFFF; /* Set read mode */
               /* Reset FLASH */
               base32_ptr[0x555] = 0xF0F0F0F0;  /* Reset command */
               result = FALSE;
               break;
            } /* Endif */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      tmp1 = base32_ptr[0];
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */
      base32_ptr[0] = 0xFFFFFFFF; /* Set read mode */
      
   } else if (flashx_ptr->WIDTH == 16){
      volatile uint_16 _PTR_  base16_ptr;

      base16_ptr = (volatile uint_16 _PTR_)input_sect_ptr;

      /* Erase a sector */
      base16_ptr[0x5555] = 0xAAAA;
      base16_ptr[0x2AAA] = 0x5555;
      base16_ptr[0x5555] = 0x8080; /* Erase command */
      base16_ptr[0x5555] = 0xAAAA;
      base16_ptr[0x2AAA] = 0x5555;

      base16_ptr[0]      = 0x3030;

      timeout = 9000000;
      while (timeout) {
         tmp1 = base16_ptr[0];
         if ((tmp1 & 0x8080) == 0x8080) {
            break;
         } /* Endif */
         if ((tmp1 & 0x2020) == 0x2020) {
            tmp1 = base16_ptr[0];
            if ( (tmp1 & 0x8080) != 0x8080) {
               base16_ptr[0] = 0xFFFF; /* Set read mode */
               /* Reset FLASH */
               base16_ptr[0x555] = 0xF0F0;  /* Reset command */
               result = FALSE;
               break;
            } /* Endif */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      tmp1 = base16_ptr[0];
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */
      base16_ptr[0] = 0xFFFF; /* Set read mode */

   } else if (flashx_ptr->WIDTH == 8){
      volatile uint_8  _PTR_  base8_ptr;

      base8_ptr = (volatile uint_8 _PTR_)input_sect_ptr;
      /* Erase a sector */
      base8_ptr[0x5555] = 0xAA;
      base8_ptr[0x2AAA] = 0x55;
      base8_ptr[0x5555] = 0x80; /* Erase command */
      base8_ptr[0x5555] = 0xAA;
      base8_ptr[0x2AAA] = 0x55;

      base8_ptr[0]      = 0x30;

      timeout = 9000000;
      while (timeout) {
         tmp1 = base8_ptr[0];
         if ((tmp1 & 0x80) == 0x80) {
            break;
         } /* Endif */
         if ((tmp1 & 0x20) == 0x20) {
            tmp1 = base8_ptr[0];
            if ( (tmp1 & 0x80) != 0x80) {
               base8_ptr[0] = 0xFF; /* Set read mode */
               /* Reset FLASH */
               base8_ptr[0x555] = 0xF0;  /* Reset command */
               result = FALSE;
            } /* Endif */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      tmp1 = base8_ptr[0];
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */
      base8_ptr[0] = 0xFF; /* Set read mode */

   }/* Endif */

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */
   return(result);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/io_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_prv.h$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file includes the private definitions for the I/O subsystem.
*
*END************************************************************************/
#ifndef __io_prv_h__
#define __io_prv_h__

/*--------------------------------------------------------------------------*/
/*
 *                            CONSTANT DEFINITIONS
 */


/* Flag meanings */

/* Is the stream at EOF? */
#define IO_FLAG_TEXT        (4)
#define IO_FLAG_AT_EOF      (8)

/* Maximum name check length */
#define IO_MAXIMUM_NAME_LENGTH (1024)

/*--------------------------------------------------------------------------*/
/*
 *                            DATATYPE DECLARATIONS
 */

/*
 * FILE DEVICE STRUCTURE
 *
 * This structure is used by the current I/O Subsystem to store
 * state information.
 * Use the same structure as the formatted I/O.
 */
typedef MQX_FILE FILE_DEVICE_STRUCT, _PTR_ FILE_DEVICE_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
 *                            FUNCTION PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/cdc/usb_cdc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_cdc.c$
* $Version : 3.8.8.0$
* $Date    : Jul-2-2012$
*
*
* @brief The file contains CDC layer implimentation.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_stack_config.h"


#if CDC_CONFIG 
#include "usb_cdc.h"
/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/

/****************************************************************************
 * Global Variables
 ****************************************************************************/
CDC_DEVICE_STRUCT_PTR   cdc_device_array[MAX_CDC_DEVICE];

/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
uint_8 USB_CDC_Other_Requests(USB_SETUP_STRUCT * setup_packet, 
                          uint_8_ptr *data, 
                          uint_32 *size,pointer arg);
uint_8 USB_Map_Ep_To_Struct_Index(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr, uint_8 ep_num);  
static CDC_HANDLE  USB_Cdc_Allocate_Handle(void);
static int_32 USB_Cdc_Free_Handle(CDC_HANDLE handle);
static CDC_DEVICE_STRUCT_PTR USB_Cdc_Get_Device_Ptr(CDC_HANDLE handle);
/*****************************************************************************
 * Local Variables - None
 *****************************************************************************/
  /*************************************************************************//*!
 *
 * @name  USB_Cdc_Allocate_Handle
 *
 * @brief The funtion reserves entry in device array and returns the index.
 *
 * @param none.
 * @return returns the reserved handle or if no entry found device busy.      
 *
 *****************************************************************************/
static CDC_HANDLE  USB_Cdc_Allocate_Handle(void)
{
    uint_32 cnt = 0;
    for (;cnt< MAX_CDC_DEVICE;cnt++)
    {
       if (cdc_device_array[cnt] == NULL)
        return cnt;
    }
    return USBERR_DEVICE_BUSY;
}
 /*************************************************************************//*!
 *
 * @name  USB_Cdc_Free_Handle
 *
 * @brief The funtion releases entry in device array .
 *
 * @param handle  index in device array to be released..
 * @return returns and error code or USB_OK.      
 *
 *****************************************************************************/

static int_32 USB_Cdc_Free_Handle(CDC_HANDLE handle)
{
    if (/*(handle < 0) || */ (handle > MAX_CDC_DEVICE))
        return USBERR_ERROR;
    
    USB_mem_free((void *)cdc_device_array[handle]);
    cdc_device_array[handle] = NULL;
    return USB_OK;
}
 /*************************************************************************//*!
 *
 * @name  USB_Cdc_Get_Device_Ptr
 *
 * @brief The funtion gets the device pointer from device array .
 *
 * @param handle  index in device array.
 * @return returns returns pointer to HID device structure..      
 *
 *****************************************************************************/
static CDC_DEVICE_STRUCT_PTR USB_Cdc_Get_Device_Ptr(CDC_HANDLE handle)
{
    if (/*(handle < 0) || */ (handle > MAX_CDC_DEVICE))
        return NULL;
    
     return cdc_device_array[handle]; 
}
 /*****************************************************************************
 * Local Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Map_Ep_To_Struct_Index
 *
 * @brief The funtion maps the endpoint num to the index of the ep data 
 *           structure
 *
 * @param handle          handle to identify the controller
 * @param ep_num          endpoint num
 *
 * @return index          mapped index       
 *
 *****************************************************************************/
uint_8 USB_Map_Ep_To_Struct_Index(CDC_DEVICE_STRUCT_PTR cdc_obj_ptr,uint_8 ep_num) 
{
    uint_8 index = 0;
     
    USB_ENDPOINTS *ep_desc_data = cdc_obj_ptr->usb_ep_data;
    
    /* map the endpoint num to the index of the endpoint structure */
    for(index = 0; index < ep_desc_data->count; index++) 
    {
        if(ep_desc_data->ep[index].ep_num == ep_num)
            break;
    }    
    return index;     
}

/**************************************************************************//*!
 *
 * @name  USB_Service_Cdc_Notif
 *
 * @brief The funtion ic callback function of CIC Notification endpoint 
 *
  * @param event
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Service_Cdc_Notif(PTR_USB_EVENT_STRUCT event,pointer arg)
{    
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr = (CDC_DEVICE_STRUCT_PTR)arg;
    #if IMPLEMENT_QUEUING
        uint_8 index;
        uint_8 producer, consumer;
//        USB_ENDPOINTS *usb_ep_data = cdc_obj_ptr->usb_ep_data;
        
        USB_CLASS_CDC_QUEUE queue;
    #endif
    
    UNUSED_ARGUMENT (event)
    
    #if IMPLEMENT_QUEUING
        /* map the endpoint num to the index of the endpoint structure */
        index = USB_Map_Ep_To_Struct_Index(cdc_obj_ptr, event->ep_num); 

        producer = cdc_obj_ptr->ep[index].bin_producer;
            
        /* if there are no errors de-queue the queue and decrement the no. of 
           transfers left, else send the same data again */
        cdc_obj_ptr->ep[index].bin_consumer++;              
        consumer = cdc_obj_ptr->ep[index].bin_consumer;
            
        if(consumer != producer) 
        {/*if bin is not empty */                           
            queue = cdc_obj_ptr->ep[index].queue[consumer%CDC_MAX_QUEUE_ELEMS];                         
            (void)USB_Class_Send_Data(cdc_obj_ptr->class_handle, queue.channel, 
                queue.app_data.data_ptr, queue.app_data.data_size);
        }        
    #endif
    
    if(cdc_obj_ptr->cdc_class_cb.callback != NULL) 
    {
        uint_8 event_type = USB_APP_SEND_COMPLETE;
        cdc_obj_ptr->cdc_class_cb.callback(event_type,NULL,
        cdc_obj_ptr->cdc_class_cb.arg);
    }   
}

/**************************************************************************//*!
 *
 * @name  USB_Service_Dic_Bulk_In
 *
 * @brief The funtion ic callback function of DIC Bulk In Endpoint 
 *
 * @param event
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Service_Dic_Bulk_In(PTR_USB_EVENT_STRUCT event,pointer arg)
{
    APP_DATA_STRUCT bulk_in_recv;
    uint_8 event_type;
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr = (CDC_DEVICE_STRUCT_PTR)arg;
    
    #if IMPLEMENT_QUEUING
        uint_8 index;
        uint_8 producer, consumer;
//        USB_ENDPOINTS *usb_ep_data = cdc_obj_ptr->usb_ep_data;
        
        USB_CLASS_CDC_QUEUE queue;

        /* map the endpoint num to the index of the endpoint structure */
        index = USB_Map_Ep_To_Struct_Index(cdc_obj_ptr, event->ep_num); 
        producer = cdc_obj_ptr->ep[index].bin_producer;         
        /* if there are no errors de-queue the queue and decrement the no. of 
           transfers left, else send the same data again */
        cdc_obj_ptr->ep[index].bin_consumer++;                  
        consumer = cdc_obj_ptr->ep[index].bin_consumer;
            
        if(consumer != producer) 
        {/*if bin is not empty */
                            
            queue = cdc_obj_ptr->ep[index].queue[consumer%CDC_MAX_QUEUE_ELEMS];
                            
            (void)USB_Class_Send_Data(cdc_obj_ptr->class_handle, queue.channel, 
                queue.app_data.data_ptr, queue.app_data.data_size);
        }          
    #endif
    
    if(cdc_obj_ptr->param_callback.callback != NULL) 
    {
        event_type = USB_APP_SEND_COMPLETE;
        bulk_in_recv.data_ptr = event->buffer_ptr;
        bulk_in_recv.data_size = event->len;
        cdc_obj_ptr->param_callback.callback(event_type,
                (void*)&bulk_in_recv,cdc_obj_ptr->param_callback.arg);             
    }
}

/**************************************************************************//*!
 *
 * @name  USB_Service_Dic_Bulk_Out
 *
 * @brief The funtion ic callback function of DIC Bulk Out Endpoint 
 *
 * @param event
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Service_Dic_Bulk_Out(PTR_USB_EVENT_STRUCT event,pointer arg)
{   
    APP_DATA_STRUCT bulk_out_recv;
    uint_8 event_type; 
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr = (CDC_DEVICE_STRUCT_PTR)arg;
      
    event_type = USB_APP_DATA_RECEIVED; 
    bulk_out_recv.data_ptr = event->buffer_ptr;
    bulk_out_recv.data_size = event->len; 
  
    if(cdc_obj_ptr->param_callback.callback != NULL) 
    {
      cdc_obj_ptr->param_callback.callback(event_type,
      (void*)&bulk_out_recv,cdc_obj_ptr->param_callback.arg);             
    }
 }

/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Event
 *
 * @brief The funtion initializes CDC endpoints 
 *
 * @param handle   handle to Identify the controller
 * @param event           pointer to event structure
 * @param val             gives the configuration value 
 *
 * @return None       
 *
 *****************************************************************************/
 void USB_Class_CDC_Event(uint_8 event, void* val,pointer arg) 
{  
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr = (CDC_DEVICE_STRUCT_PTR)arg;
    
    if(event == USB_APP_ENUM_COMPLETE) 
    {
        uint_8 count = 0;
        USB_EP_STRUCT_PTR ep_struct_ptr;
        
        /* get the endpoints from the descriptor module */            
        USB_ENDPOINTS *usb_ep_data = cdc_obj_ptr->usb_ep_data;
        
        /* intialize all non control endpoints */            
        while(count < usb_ep_data->count) 
        {
            ep_struct_ptr = (USB_EP_STRUCT*) &usb_ep_data->ep[count];

            (void)_usb_device_init_endpoint(cdc_obj_ptr->controller_handle,
             ep_struct_ptr,TRUE);
  
            /* register callback service for Non Control EndPoints */
            switch(ep_struct_ptr->type) 
            {
                case USB_INTERRUPT_PIPE :
                    (void)_usb_device_register_service(cdc_obj_ptr->controller_handle,
                        (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                        USB_Service_Cdc_Notif,(void *)cdc_obj_ptr);
                    break;                              
                case USB_BULK_PIPE :
                    if(ep_struct_ptr->direction == USB_RECV) 
                    {
                        (void)_usb_device_register_service(cdc_obj_ptr->controller_handle,
                            (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                            USB_Service_Dic_Bulk_Out,(void *)cdc_obj_ptr);
                    } 
                    else
                    {
                        (void)_usb_device_register_service(cdc_obj_ptr->controller_handle,
                            (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                            USB_Service_Dic_Bulk_In,(void *)cdc_obj_ptr);
                    }
                    break;
                default : break;        
            }
                          
            /* set the EndPoint Status as Idle in the device layer */
            /* (no need to specify direction for this case) */
            (void)_usb_device_set_status(cdc_obj_ptr->controller_handle,
                (uint_8)(USB_STATUS_ENDPOINT|ep_struct_ptr->ep_num),
                (uint_8)USB_STATUS_IDLE);                                                                                                         
            count++;                                                    
        }/* EndWhile */
    }
    #if RNDIS_SUPPORT
    else if(event == USB_APP_BUS_RESET)
    {
        uint_8_ptr data; 
        uint_32 size;
        RNDIS_Reset_Command(cdc_obj_ptr, &data, &size);     
    }
    #endif        
    if(cdc_obj_ptr->cdc_class_cb.callback != NULL) 
    {
        cdc_obj_ptr->cdc_class_cb.callback(event,
            val,cdc_obj_ptr->cdc_class_cb.arg);
    } 
}

/**************************************************************************//*!
 *
 * @name  USB_CDC_Other_Requests
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param handle
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_CDC_Other_Requests
(   
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size,
    pointer arg
) 
{
    uint_8 status;
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr = (CDC_DEVICE_STRUCT_PTR)arg;
    status = USBERR_INVALID_REQ_TYPE;

    if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
        USB_REQUEST_CLASS_CLASS) 
    {  /* class request so handle it here */     
        status=USB_OK;
        /* call for class/subclass specific requests */
        switch(setup_packet->request) 
        {
            case SEND_ENCAPSULATED_COMMAND :
                #if RNDIS_SUPPORT               
                    /* Pass the Remote NDIS Control Message supoported by 
                       802.3 connectionless device to PSTN Layer */
                    status = PSTN_Rndis_Message_Set(cdc_obj_ptr,setup_packet,data,size); 
                #endif
                *size = 0;              
                break;
            case GET_ENCAPSULATED_RESPONSE :
                #if RNDIS_SUPPORT               
                    /* Get the Remote NDIS Control Message supoported by 
                       802.3 connectionless device from  PSTN Layer */
                    status = PSTN_Rndis_Message_Get(cdc_obj_ptr,setup_packet,data,size); 
                #else
                    *size = 0;
                    /* protocol says to return zero byte data instead of stalling 
                       the command if you don't have data to return */
                    status = USB_OK;                
                #endif
                break; 
            case SET_COMM_FEATURE :
                status = PSTN_Set_Comm_Feature(cdc_obj_ptr,setup_packet,data,size);  
                break;
            case GET_COMM_FEATURE :
                status = PSTN_Get_Comm_Feature(cdc_obj_ptr,setup_packet,data,size); 
                break;
            case CLEAR_COMM_FEATURE : /* Verify this implementation */
                *size = cdc_obj_ptr->comm_feature_data_size;
                **data = 0x00; *(++(*data)) = 0x00;/*clear both feature bytes*/
                status = PSTN_Set_Comm_Feature(cdc_obj_ptr,
                setup_packet,data,size);  
                break; 
            case GET_LINE_CODING :               
                status = PSTN_Get_Line_Coding(cdc_obj_ptr,
                setup_packet,data,size); 
                break;
            case SET_LINE_CODING :               
                status = PSTN_Set_Line_Coding(cdc_obj_ptr,setup_packet,data,size); 
                break;    
            case SET_CONTROL_LINE_STATE : 
                status = PSTN_Set_Ctrl_Line_State(cdc_obj_ptr,
                setup_packet,data,size); 
                break;
            case SEND_BREAK : 
                status = PSTN_Send_Break(cdc_obj_ptr,setup_packet,data,size);
                break;
            default :  *size=0;break;        
        }
    } 
    else if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
        USB_REQUEST_CLASS_VENDOR) 
    {   /* vendor specific request  */    
        if(cdc_obj_ptr->vendor_req_callback.callback != NULL) 
        {
            status = cdc_obj_ptr->vendor_req_callback.callback(setup_packet,
            data,size,cdc_obj_ptr->vendor_req_callback.arg);
        }
    }
        
    return status;
}


/*****************************************************************************
 * Global Functions
 *****************************************************************************/


/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param *cdc_config_ptr[IN]:  This structure contians configuration parameter
 *                              send by APP to configure CDC class.
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the CDC Class layer and layers it is dependednt on 
 *
 *****************************************************************************/
uint_32 USB_Class_CDC_Init
(
  CDC_CONFIG_STRUCT_PTR cdc_config_ptr
)
{   
#if IMPLEMENT_QUEUING
    uint_8 index;
#endif

    uint_8 error;
    CDC_HANDLE cdc_handle;
    CDC_DEVICE_STRUCT_PTR devicePtr = NULL;
    USB_ENDPOINTS *usb_ep_data;
    
    if (NULL == (void *)cdc_config_ptr)
        return USBERR_ERROR;
    
    devicePtr = (CDC_DEVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(CDC_DEVICE_STRUCT));
    if (NULL == devicePtr) 
    {
        #if _DEBUG
            printf("memalloc failed in USB_Class_CDC_Init\n");
        #endif  
        return USBERR_ALLOC;    
    }
    
    cdc_handle = USB_Cdc_Allocate_Handle();
    if (USBERR_DEVICE_BUSY == cdc_handle) 
    {
        USB_mem_free(devicePtr);
        devicePtr = NULL;
        return USBERR_INIT_FAILED;
    }

        /* initialize the Global Variable Structure */
    USB_mem_zero(devicePtr, sizeof(CDC_DEVICE_STRUCT));

    devicePtr->ep = cdc_config_ptr->ep;
    usb_ep_data = cdc_config_ptr->usb_ep_data;
    devicePtr->max_supported_interfaces = 
        cdc_config_ptr->max_supported_interfaces;
    #if RNDIS_SUPPORT
        USB_mem_copy(cdc_config_ptr->mac_address, devicePtr->mac_address, 
            sizeof(_enet_address));
        devicePtr->ip_address = cdc_config_ptr->ip_address;
        devicePtr->rndis_max_frame_size = cdc_config_ptr->rndis_max_frame_size;
    #endif
    /* Initialize the device layer*/
    error = _usb_device_init(USBCFG_DEFAULT_DEVICE_CONTROLLER, &devicePtr->controller_handle, (uint_8)(usb_ep_data->count+1));
    /* +1 is for Control Endpoint */ 
    if(error != USB_OK)
    {
      goto error1;  
    }
    
    cdc_config_ptr->desc_callback_ptr->handle = cdc_handle;
    
    /* Initialize the generic class functions */
    devicePtr->class_handle = USB_Class_Init(devicePtr->controller_handle,
    USB_Class_CDC_Event,USB_CDC_Other_Requests,(void *)devicePtr,
    cdc_config_ptr->desc_callback_ptr);

    /* Initialize the generic class functions */
    #if PSTN_SUBCLASS_NOTIF_SUPPORT
    /* Initialize the pstn subclass functions */
    error = USB_Pstn_Init(devicePtr,&cdc_config_ptr->param_callback);
    if(error != USB_OK)
    {
      goto error2;  
    }
    #endif
     
    devicePtr->usb_ep_data = usb_ep_data;
    #if IMPLEMENT_QUEUING
     for(index = 0; index < usb_ep_data->count; index++) 
     {            
        devicePtr->ep[index].endpoint = usb_ep_data->ep[index].ep_num;
        devicePtr->ep[index].type = usb_ep_data->ep[index].type;        
        devicePtr->ep[index].bin_consumer = 0x00;         
        devicePtr->ep[index].bin_producer = 0x00;        
      }
    #endif
        
    /* save the callback pointer */
    devicePtr->cdc_class_cb.callback = cdc_config_ptr->cdc_class_cb.callback;
    devicePtr->cdc_class_cb.arg = cdc_config_ptr->cdc_class_cb.arg;         
    /* save the callback pointer */
    devicePtr->vendor_req_callback.callback = 
    cdc_config_ptr->vendor_req_callback.callback;
    devicePtr->vendor_req_callback.arg = cdc_config_ptr->vendor_req_callback.arg; 
    /* save the callback pointer */
    devicePtr->param_callback.callback = cdc_config_ptr->param_callback.callback;
    devicePtr->param_callback.arg = cdc_config_ptr->param_callback.arg; 
    devicePtr->comm_feature_data_size =  cdc_config_ptr->comm_feature_data_size;  
    devicePtr->cic_send_endpoint = cdc_config_ptr->cic_send_endpoint;
    devicePtr->cic_recv_endpoint = USB_CONTROL_ENDPOINT;
    devicePtr->dic_send_endpoint = cdc_config_ptr->dic_send_endpoint;
    devicePtr->dic_recv_endpoint = cdc_config_ptr->dic_recv_endpoint; 
    devicePtr->dic_recv_pkt_size = cdc_config_ptr->dic_recv_pkt_size;
    devicePtr->dic_send_pkt_size = cdc_config_ptr->dic_send_pkt_size;
    devicePtr->cic_send_pkt_size = cdc_config_ptr->cic_send_pkt_size;
     
      
    devicePtr->cdc_handle = cdc_handle;
   
   cdc_device_array[cdc_handle] = devicePtr;
   
   return cdc_handle;
 error2:
  /* Implement Denit class and invoke here*/    
 error1: 
     USB_Cdc_Free_Handle(cdc_handle);
     USB_mem_free(devicePtr);
     devicePtr = NULL;    
    return error;    
}

/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Deinit
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param cdc_handle
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the CDC Class layer and layers it is dependednt on 
 *
 *****************************************************************************/
uint_32 USB_Class_CDC_Deinit
(
  CDC_HANDLE cdc_handle
)
{   

    uint_8 error = USB_OK;
    CDC_DEVICE_STRUCT_PTR devicePtr = NULL;
    devicePtr = USB_Cdc_Get_Device_Ptr(cdc_handle);

    #if PSTN_SUBCLASS_NOTIF_SUPPORT
    /* deinitialize the pstn subclass functions */
    error = USB_Pstn_Deinit(devicePtr);
    #endif
    if(error == USB_OK)
    /* deinitialize the generic class functions */
    error = USB_Class_Deinit(devicePtr->controller_handle,devicePtr->class_handle);
    if(error == USB_OK)
    /* deinitialize the device layer*/
    error = _usb_device_deinit(devicePtr->controller_handle);
    if(error == USB_OK)
    error = USB_Cdc_Free_Handle(cdc_handle);
    return error;    
}
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Send_Data
 *
 * @brief 
 *
 * @param handle          :   handle returned by USB_Class_CDC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK         : When Successfull 
 *         Others         : Errors
 *****************************************************************************/
uint_8 USB_Class_CDC_Send_Data
(
    CDC_HANDLE handle,
    uint_8 ep_num,
    uint_8_ptr app_buff,
    uint_32 size
) 
{
    #if IMPLEMENT_QUEUING
        uint_8 index;
        uint_8 producer, consumer; 
//        USB_ENDPOINTS *usb_ep_data; 
    #endif    
        
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr;
    uint_8 status = USB_OK;

    cdc_obj_ptr = USB_Cdc_Get_Device_Ptr(handle);
    if (NULL == cdc_obj_ptr)
      return USBERR_ERROR;
    
    #if IMPLEMENT_QUEUING
//        usb_ep_data = cdc_obj_ptr->usb_ep_data;
      
        /* map the endpoint num to the index of the endpoint structure */
        index = USB_Map_Ep_To_Struct_Index(cdc_obj_ptr, ep_num); 
                
        producer = cdc_obj_ptr->ep[index].bin_producer;
        consumer = cdc_obj_ptr->ep[index].bin_consumer;
                                
        if(((uint_8)(producer - consumer)) != (uint_8)(CDC_MAX_QUEUE_ELEMS))  
        {   /* the bin is not full*/        
            uint_8 queue_num = (uint_8)(producer % CDC_MAX_QUEUE_ELEMS);
            
            /* put all send request parameters in the endpoint data structure*/
            cdc_obj_ptr->ep[index].queue[queue_num].channel = ep_num;
            cdc_obj_ptr->ep[index].queue[queue_num].app_data.data_ptr = app_buff;
            cdc_obj_ptr->ep[index].queue[queue_num].app_data.data_size = size; 
            cdc_obj_ptr->ep[index].queue[queue_num].handle = 
            cdc_obj_ptr->controller_handle;         
            /* increment producer bin by 1*/       
            cdc_obj_ptr->ep[index].bin_producer = ++producer;

            if((uint_8)(producer - consumer) == (uint_8)1)         
            {          
    #endif      
                status = USB_Class_Send_Data(cdc_obj_ptr->class_handle,
                 ep_num, app_buff,size);
    #if IMPLEMENT_QUEUING
            }
        }
        else /* bin is full */
        {
            status = USBERR_DEVICE_BUSY; 
        }    
    #endif 
    return status;
}
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Recv_Data
 *
 * @brief This functions receives Data from Host.
 *
 * @param handle          :   handle returned by USB_Class_CDC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK         : When Successfull 
 *         Others         : Errors
 *****************************************************************************/
uint_8 USB_Class_CDC_Recv_Data
(
    CDC_HANDLE          cdc_handle,
    uint_8              ep_num,
    uint_8_ptr          buff_ptr,      /* [IN] buffer to recv */      
    uint_32             size           /* [IN] length of the transfer */
)
{
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr;
    uint_8 status = USB_OK;

    cdc_obj_ptr = USB_Cdc_Get_Device_Ptr(cdc_handle);
    if (NULL == cdc_obj_ptr)
    {
        return USBERR_ERROR;    
    }
   
    status = _usb_device_recv_data(cdc_obj_ptr->controller_handle,
    ep_num,buff_ptr,size);
    
    return status;
    
}

#endif /*CDC_CONFIG*/
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/pcb.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pcb.h$
* $Version : 3.8.9.0$
* $Date    : Aug-7-2012$
*
* Comments:
*
*   This file contains the definitions of the generic
*   PCB (Packet Control Block) structure.  
*   Since this structure is common to
*   various protocols, this file is distributed with
*   several products.
*
*END************************************************************************/
#ifndef __pcb_h__
#define __pcb_h__

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */


#define __PCB__

#define PCB_free(pcb_ptr)  ((pcb_ptr)->FREE(pcb_ptr))
#define htonl(p,x) (((uint_8_ptr)(p))[0] = ((x) >> 24) & 0xFF, \
                    ((uint_8_ptr)(p))[1] = ((x) >> 16) & 0xFF, \
                    ((uint_8_ptr)(p))[2] = ((x) >>  8) & 0xFF, \
                    ((uint_8_ptr)(p))[3] =  (x)        & 0xFF, \
                    (x))

#define htons(p,x) (((uint_8_ptr)(p))[0] = ((x) >>  8) & 0xFF, \
                    ((uint_8_ptr)(p))[1] =  (x)        & 0xFF, \
                    (x))

#define htonc(p,x) (((uint_8_ptr)(p))[0] = (x) & 0xFF, \
                    (x))

#define ntohl(p)   (\
                    (((uint_32)(((uint_8_ptr)(p))[0])) << 24) | \
                    (((uint_32)(((uint_8_ptr)(p))[1])) << 16) | \
                    (((uint_32)(((uint_8_ptr)(p))[2])) << 8) | \
                    ( (uint_32)(((uint_8_ptr)(p))[3])) \
                   )

#define ntohs(p)   (\
                    (((uint_16)(((uint_8_ptr)(p))[0])) << 8) | \
                    ( (uint_16)(((uint_8_ptr)(p))[1])) \
                   )

#define ntohc(p)   ((uint_8)(((uint_8_ptr)(p))[0]))

/*--------------------------------------------------------------------------*/
/*
 *                          DATA STRUCTURES
 */

/*
 * The PCB (Packet Control Block)
 * 
 * One PCB contains exactly one packet, possibly split over several areas of
 * memory.
 * 
 * The PCB structure consists of two pointers (FREE and PRIVATE) followed by a
 * variable-length array of PCB_FRAGMENT structures.  The array is terminated
 * by an entry with LENGTH=0 and FRAGMENT=NULL.
 *
 * The PCB's owner (i.e. the module that allocated it) must initialize the
 * FREE field to point to a function to free the PCB.  PRIVATE can be used by
 * the PCB's owner to store any information it wishes.
 */

struct pcb;
typedef void (_CODE_PTR_  PCB_FREE_FPTR)(struct pcb _PTR_);

/*!
 * \brief Structure that contains fragment of PCB. 
 */ 
typedef struct pcb_fragment 
{
   /*! \brief Length of PCB fragment. */
   uint_32           LENGTH;
   /*! \brief Pointer to fragment. */
   uchar_ptr         FRAGMENT;
} PCB_FRAGMENT, _PTR_ PCB_FRAGMENT_PTR;

/*!
 * \brief PCB structure. 
 * 
 * The array is terminated by an entry with LENGTH=0 and FRAGMENT=NULL.
 */ 
typedef struct pcb 
{
   /*! \brief Function that frees PCB. */
   PCB_FREE_FPTR     FREE;
   /*! \brief Private PCB information. */
   pointer           PRIVATE;
   /*! \brief Pointer to PCB fragment. */
   PCB_FRAGMENT      FRAG[1];
} PCB, _PTR_ PCB_PTR;

// The minimum size of a PCB must contain two fragments, so the following represents
// the smallest PCB
/*!
 * \brief PCB structure contains two fragments.
 * 
 * The array is terminated by an entry with LENGTH=0 and FRAGMENT=NULL. 
 */
typedef struct pcb2
{
   /*! \brief Function that frees PCB. */
   PCB_FREE_FPTR     FREE;
   /*! \brief Private PCB information. */
   pointer           PRIVATE;
   /*! \brief Pointers to two PCB fragments. */
   PCB_FRAGMENT      FRAG[2];
} PCB2, _PTR_ PCB2_PTR;

#define PCB_MINIMUM_SIZE (sizeof(PCB2))

/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_lpt.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*****************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: timer_lpt.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains LPT functionality.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <timer_lpt.h>


static void _lpt_kernel_isr (pointer parameter);


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpt_set_period
* Returned Value   : Difference to desired period.
* Comments         :
*    This function finds and sets closest longer period for given LPT across
*    all given clock sources.
*
*END*----------------------------------------------------------------------*/

static uint_32 _lpt_set_period
    (
        /* [IN] Timer to initialize */
        uint_8  timer,
        
        /* [IN] Desired timer period in Hz */
        uint_32 period_hz,

        /* [IN] Desired timer period in us */
        uint_32 period_us,
        
        /* [IN] Allowed clock sources */
        uint_32 sources
    )
{
    static const uint_32 clock_inputs_ordered[] = {LPT_FLAG_CLOCK_SOURCE_LPO, LPT_FLAG_CLOCK_SOURCE_OSCERCLK, LPT_FLAG_CLOCK_SOURCE_MCGIRCLK, LPT_FLAG_CLOCK_SOURCE_ERCLK32K};
    static const uint_8  clock_inputs_log[] = {0, 0, 1, 0, 2, 0, 0, 0, 3};
    uint_32 i, frequency, prescaler, psr = 0, cmr = 0, f = 1;
    uint_64 compare, tmp, diff, min = (uint_64)-1;
    LPTMR_MemMapPtr lpt_ptr = _bsp_get_lpt_base_address (timer);
    
    if ((NULL == lpt_ptr) || ((0 == period_hz) && (0 == period_us)) || (0 == sources))
    {
        return (uint_32)min;
    }
    
    for (i = 0; i < ELEMENTS_OF(clock_inputs_ordered); i++)
    {
        if (sources & clock_inputs_ordered[i])
        {
            frequency = _bsp_get_lpt_clock_frequency (timer, LPTMR_PSR_PCS(clock_inputs_log[clock_inputs_ordered[i]]));
            if (period_hz)
            {
                compare = (frequency + period_hz - 1) / period_hz;
                diff = compare * period_hz - frequency;
            }
            else
            {
                tmp = (uint_64)frequency * (uint_64)period_us;
                compare = (tmp + 999999) / 1000000;
                diff = compare * 1000000 - tmp;
            }
            if (((0 < compare) && (compare <= 65536)) && (min > diff))
            {
                min = diff;
                f = frequency;
                psr = LPTMR_PSR_PBYP_MASK | LPTMR_PSR_PCS(clock_inputs_log[clock_inputs_ordered[i]]);
                cmr = LPTMR_CMR_COMPARE(compare - 1);
                if (0 == min)
                {
                    break;
                }
            }
            for (prescaler = 1; prescaler < 16; prescaler++)
            {
                if (period_hz)
                {
                    tmp = ((uint_64)period_hz) << (prescaler + 1);
                    compare = (frequency + tmp - 1) / tmp;
                    diff = (compare << (prescaler + 1)) * period_hz - frequency;
                }
                else
                {
                    diff = 1000000;
                    diff <<= (prescaler + 1);
                    compare = (tmp + diff - 1) / diff;
                    diff = compare * diff - tmp;
                }
                if (((0 < compare) && (compare <= 65536)) && (min > diff))
                {
                    min = diff;
                    f = frequency;
                    psr = LPTMR_PSR_PRESCALE(prescaler) | LPTMR_PSR_PCS(clock_inputs_log[clock_inputs_ordered[i]]); 
                    cmr = LPTMR_CMR_COMPARE(compare - 1);
                    if (0 == min)
                    {
                        break;
                    }
                }
            }
            if (0 == min)
            {
                break;
            }
        }
    }

    lpt_ptr->PSR = psr;
    lpt_ptr->CMR = cmr;

    return (uint_32)(min / f);
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_install
* Returned Value  : MQX error code
* Comments        :
*   This function installs LPT timer into MQX.
*
*END*---------------------------------------------------------------------*/

_mqx_int _lpt_install
    (
        /* [IN] Timer to initialize */
        uint_8  timer,
    
        /* [IN] Period in microseconds */
        uint_32 period_us,

        /* [IN] Input clock sources mask */
        uint_32 clk,
    
        /* [IN] Interrupt priority */
        uint_32 priority,
    
        void (_CODE_PTR_ isr_ptr)(pointer),
        
        /* [IN] Unmask the timer after installation */
        boolean unmask_timer
    )
{
    uint_32 result;
    _mqx_uint vector = _bsp_get_lpt_vector (timer);
    if (0 == vector)
    {
        return MQX_INVALID_DEVICE;
    }
    if (0 == period_us)
    {
        return MQX_INVALID_PARAMETER;
    }

    _bsp_int_disable (vector);

    if (NULL == _int_install_isr (vector, isr_ptr, (pointer)timer))
    {
        return MQX_TIMER_ISR_INSTALL_FAIL;
    }
    
    _bsp_enable_lpt_clock (timer);
    
    _lpt_init (timer, period_us, clk, unmask_timer);
    
    _bsp_int_init (vector, priority, 0, TRUE);
    _bsp_int_enable (vector);
    
    return MQX_OK;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_install_kernel
* Returned Value  : MQX error code
* Comments        :
*   This function installs LPT timer as MQX tick source.
*
*END*---------------------------------------------------------------------*/

_mqx_int _lpt_install_kernel
(
        /* [IN] Timer to initialize */
        uint_8  timer,

        /* [IN] Period in microseconds */
        uint_32 period_us,

        /* [IN] Input clock sources mask */
        uint_32 clk,

        /* [IN] Interrupt priority */
        uint_32 priority,

        /* [IN] Unmask the timer after installation */
        boolean unmask_timer
)
{
    uint_32 result, period, ticks;
    _mqx_uint vector = _bsp_get_lpt_vector (timer);
    if (0 == vector)
    {
        return MQX_INVALID_DEVICE;
    }
    if (0 == period_us)
    {
        return MQX_INVALID_PARAMETER;
    }
    ticks = 1000000 / period_us;
    if (0 == ticks)
    {
        return MQX_INVALID_PARAMETER;
    }

    _bsp_int_disable (vector);

    if (NULL == _int_install_isr (vector, _lpt_kernel_isr, (pointer)timer))
    {
        return MQX_TIMER_ISR_INSTALL_FAIL;
    }

    _bsp_enable_lpt_clock (timer);

    period = _lpt_init (timer, period_us, clk, unmask_timer);

    _time_set_timer_vector (vector);
    _time_set_hwtick_function (_lpt_get_hwticks, (pointer) timer);
    _time_set_hwticks_per_tick (period);
    _time_set_ticks_per_sec (ticks);

    _bsp_int_init (vector, priority, 0, TRUE);
    _bsp_int_enable (vector);

    return MQX_OK;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_init
* Returned Value  : HW counter modulo per 1 timer interrupt
* Comments        :
*   This function sets up the LPT period.
*
*END*---------------------------------------------------------------------*/

uint_32 _lpt_init
    (
        /* [IN] Timer to initialize */
        uint_8  timer,

        /* [IN] Period in microseconds */
        uint_32 period_us,

        /* [IN] Input clock sources mask */
        uint_32 clk,

        /* [IN] Unmask the timer after initializing */
        boolean unmask_timer
    )
{
    uint_32 period;
    LPTMR_MemMapPtr lpt_ptr = _bsp_get_lpt_base_address (timer);
    if (NULL == lpt_ptr) 
    {
        return 0;
    }

    _lpt_run (timer, FALSE);
    
    _lpt_mask_int (timer);
    _lpt_clear_int (timer);
    
    _lpt_set_period (timer, 0, period_us, clk);
    period = lpt_ptr->CMR + 1;
        
    _lpt_run (timer, TRUE);
        
    if (unmask_timer) 
    {
        _lpt_unmask_int (timer);
    }
    
    return period;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_get_hwticks
* Returned Value  : Number of ticks
* Comments        :
*   This function returns the number of ticks elapsed since the last
*   timer tick.
*
*END*---------------------------------------------------------------------*/

uint_32 _lpt_get_hwticks
   (
      /* [IN] the timer to clear */
      pointer parameter
   )
{
    uint_32 timer = (uint_32)parameter;
    uint_32 ticks;
    uint_32 modulo;
    
    LPTMR_MemMapPtr lpt_ptr = _bsp_get_lpt_base_address (timer);
    if (NULL == lpt_ptr) 
    {
        return 0;
    }

    modulo = lpt_ptr->CMR + 1;
    ticks = lpt_ptr->CNR;

    if (lpt_ptr->CSR & LPTMR_CSR_TCF_MASK) 
    {
        /* Another full TICK period has expired since we handled the last timer interrupt.
        We need to read the counter again, since the wrap may have
        occurred between the previous read and the checking of the overflow bit. */
        ticks = lpt_ptr->CNR + modulo;
    }

    /* actual ticks + what we have missed because of sw prescaller */ 
    return ticks;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_mask_int
* Returned Value  : None
* Comments        :
*   This function masks interrupt of given timer.
*
*END*---------------------------------------------------------------------*/

void _lpt_mask_int
    (
        /* [IN] Timer to use */
        uint_8 timer
    )
{
    LPTMR_MemMapPtr lpt_ptr = _bsp_get_lpt_base_address (timer);
    if (NULL != lpt_ptr)
    {
        lpt_ptr->CSR &= (~ LPTMR_CSR_TIE_MASK);
    }
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_unmask_int
* Returned Value  : None
* Comments        :
*   This function unmasks interrupt of given timer.
*
*END*---------------------------------------------------------------------*/

void _lpt_unmask_int
    (
        /* [IN] Timer to use */
        uint_8 timer
    )
{
    LPTMR_MemMapPtr lpt_ptr = _bsp_get_lpt_base_address (timer);
    if (NULL != lpt_ptr)
    {
        lpt_ptr->CSR |= LPTMR_CSR_TIE_MASK;
    }
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_clear_int
* Returned Value  : None
* Comments        :
*   This function clears interrupt flag of given timer.
*
*END*---------------------------------------------------------------------*/

void _lpt_clear_int
    (
        /* [IN] Timer to use */
        uint_8 timer
    )
{
    LPTMR_MemMapPtr lpt_ptr = _bsp_get_lpt_base_address (timer);
    if (NULL != lpt_ptr) 
    {
        lpt_ptr->CSR |= LPTMR_CSR_TCF_MASK;
    }
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_run
* Returned Value  : None
* Comments        :
*   This function starts/stops the given timer.
*
*END*---------------------------------------------------------------------*/

void _lpt_run
    (
        /* [IN] Timer to use */
        uint_8  timer,
        
        /* [IN] Whether to start or stop */
        boolean run
    )
{
    LPTMR_MemMapPtr lpt_ptr = _bsp_get_lpt_base_address (timer);
    if (NULL != lpt_ptr)
    {
        if (run)
        {
            lpt_ptr->CSR |= LPTMR_CSR_TEN_MASK;
        }
        else
        {
            lpt_ptr->CSR &= (~ LPTMR_CSR_TEN_MASK);
        }
    }
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _lpt_kernel_isr
* Returned Value  : NOne
* Comments        :
*   ISR for LPT event to be used as system timer.
*
*END*---------------------------------------------------------------------*/

static void _lpt_kernel_isr
    (
        pointer parameter
    ) 
{
    _lpt_clear_int ((uint_32)parameter);
    _time_notify_kernel ();
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/kadc/adc_kadc_prv.h<|end_filename|>
/**************************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_kadc_prv.h$
* $Version : 3.8.10.0$
* $Date    : Oct-2-2012$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END************************************************************************/

#ifndef __adc_kadc_prv_h__
#define __adc_kadc_prv_h__

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

#define ADC_MAX_FREQUENCY 5000000 /* 5 MHz for ADC clock source is maximum */

#ifndef ADC_CHANNELS_PER_ADC
    #define ADC_CHANNELS_PER_ADC (2)  /* one ADC can handle 2 channels */
#endif
#define ADC_MAX_HW_CHANNELS  ADC_CHANNELS_PER_ADC /* there is no sense to have more channels allocated */

#ifndef ADC_MAX_MODULES
    #error Define number of ADC peripheral modules on chip in BSP (<MQX>/source/bsp/<board_name>/<board_name>.h)
#endif

#ifndef ADC_MAX_SW_CHANNELS
    #define ADC_MAX_CHANNELS ADC_MAX_HW_CHANNELS
#else
    #if (ADC_MAX_HW_CHANNELS >= ADC_MAX_SW_CHANNELS)
        #define ADC_MAX_CHANNELS ADC_MAX_SW_CHANNELS
    #else
        #error The ADC_MAX_SW_CHANNELS must be less than ADC_MAX_HW_CHANNELS.
    #endif
#endif

#define ADC_CFG2_ADLSTS_20             ADC_CFG2_ADLSTS(0)
#define ADC_CFG2_ADLSTS_12             ADC_CFG2_ADLSTS(1)
#define ADC_CFG2_ADLSTS_6              ADC_CFG2_ADLSTS(2)
#define ADC_CFG2_ADLSTS_2              ADC_CFG2_ADLSTS(3)
#define ADC_CFG2_ADLSTS_DEFAULT       (ADC_CFG2_ADLSTS_20)

#define ADC_SC3_AVGS_4                 ADC_SC3_AVGS(0x00)
#define ADC_SC3_AVGS_8                 ADC_SC3_AVGS(0x01)
#define ADC_SC3_AVGS_16                ADC_SC3_AVGS(0x02)
#define ADC_SC3_AVGS_32                ADC_SC3_AVGS(0x03)
#define ADC_SC3_AVGE                   ADC_SC3_AVGE_MASK
#define ADC_SC3_ADCO                   ADC_SC3_ADCO_MASK
#define ADC_SC3_CALF                   ADC_SC3_CALF_MASK
#define ADC_SC3_CAL                    ADC_SC3_CAL_MASK

#define ADC_SC2_REFSEL_VREF            ADC_SC2_REFSEL(0x00)
#define ADC_SC2_REFSEL_VALT            ADC_SC2_REFSEL(0x01)
#define ADC_SC2_REFSEL_VBG             ADC_SC2_REFSEL(0x02)

#define ADC_SC1_ADCH_DISABLED          ADC_SC1_ADCH(0x1F)

#define ADC_CFG1_ADIV_1                ADC_CFG1_ADIV(0x00)
#define ADC_CFG1_ADIV_2                ADC_CFG1_ADIV(0x01)
#define ADC_CFG1_ADIV_4                ADC_CFG1_ADIV(0x02)
#define ADC_CFG1_ADIV_8                ADC_CFG1_ADIV(0x03)

#define ADC_CFG1_ADICLK_BUSCLK         ADC_CFG1_ADICLK(0x00)
#define ADC_CFG1_ADICLK_BUSCLK2        ADC_CFG1_ADICLK(0x01)
#define ADC_CFG1_ADICLK_ALTCLK         ADC_CFG1_ADICLK(0x02)
#define ADC_CFG1_ADICLK_ADACK          ADC_CFG1_ADICLK(0x03)

#define PDB_SC_TRGSEL_SWTRIG           PDB_SC_TRGSEL(0x1F)
/* Structure holding ADC driver settings */
typedef struct adc {
   ADC_GENERIC           g; /* this must be included as the first member at the beginning of structure */
   /* below, CPU specific members are used */
   void (*old_isr)(pointer);
   pointer old_isr_data;
   uint_8                muxsel; /* holds setting for MUX selection- used for checking whether MUXSEL settings meets channel criteria */
} ADC, _PTR_ ADC_PTR;

/* Structure holding ADC driver settings */
typedef struct adt {
   ADT_GENERIC           g; /* this must be included as the first item at the beginning of structure */
} ADT, _PTR_ ADT_PTR;

/* Structure holding ADC driver channel settings */
typedef struct adc_channel {
   ADC_CHANNEL_GENERIC   g; /* this must be included as the first member at the beginning of structure */
   /* below, CPU specific members are used */
   struct adc_channel_bundle *b;
} ADC_CHANNEL, _PTR_ ADC_CHANNEL_PTR;

/* Structure holding ADT driver channel settings, must be declared */
typedef struct adt_channel {
   ADT_CHANNEL_GENERIC   g; /* this must be included as the first member at the beginning of structure */
   /* below, CPU specific members are used */
   struct adc_channel_bundle *b;
   /* All ADT channels use one common HW trigger settings. Only delay is per - channel set */
} ADT_CHANNEL, _PTR_ ADT_CHANNEL_PTR;

/* ADC converter + trigger channel bundle structure */
typedef struct adc_channel_bundle {
   ADC_CHANNEL_PTR  adc_ch;
   ADT_CHANNEL_PTR  adt_ch;
   /* below, CPU specific members are used */
   _mqx_int         ch_num; /* this channel is A or B (0 or 1) ? */
   _mqx_int         adc_num; /* number of ADC */
   _mqx_int         periods_preset; /* how many dummy PDB periods must pass to readout result data */
   _mqx_int         periods;        /* how many dummy PDB periods elapsed */
    boolean         waste_channel;  /* workaround to waste all channel results */
} ADC_CHANNEL_BUNDLE, _PTR_ ADC_CHANNEL_BUNDLE_PTR;

/* ADC converter + trigger driver bundle structure */
typedef struct adc_driver_bundle {
   ADC_PTR          adc;                      /* ADC driver status information (generic + HW specific) */
   ADT_PTR          adt;                      /* ADT driver status information (generic + HW specific) */
   ADC_CHANNEL_PTR  adc_ch[ADC_MAX_CHANNELS];
   ADT_CHANNEL_PTR  adt_ch[ADC_MAX_CHANNELS];
   uchar_ptr        adc_name[ADC_MAX_CHANNELS]; /* filename of channel(s) */
   /* below, CPU specific members are used */
   struct kadc_install_struct *init;
} ADC_DRIVER_BUNDLE, _PTR_ ADC_DRIVER_BUNDLE_PTR;

typedef struct adc_bundle {
/* Following must be defined, because following values should be written in one uninterruptable block of code, so we cannot
** split IOCTL command to ADC and ADT. There is posibility that ADC module disables interrupts and ADT module enables interrupt,
** but that's not the right solution.
*/
   uint_32 late_process; /* This is mask of late processing channel, constrained to 32 channels. */
} ADC_BUNDLE, ADC_BUNDLE_PTR;

_mqx_int _adc_hw_install(char_ptr, ADC_DRIVER_BUNDLE_PTR, pointer);
_mqx_int _adt_hw_install(char_ptr, ADC_DRIVER_BUNDLE_PTR, pointer);
_mqx_int _adc_hw_init(MQX_FILE_PTR, ADC_PTR);
_mqx_int _adt_hw_init(MQX_FILE_PTR, ADT_PTR);
_mqx_int _adc_hw_deinit(MQX_FILE_PTR, ADC_PTR);
_mqx_int _adt_hw_deinit(MQX_FILE_PTR, ADT_PTR);
_mqx_int _adc_hw_channel_init(MQX_FILE_PTR, ADC_CHANNEL_PTR);
_mqx_int _adt_hw_channel_init(MQX_FILE_PTR, ADT_CHANNEL_PTR);
_mqx_int _adc_hw_channel_deinit(MQX_FILE_PTR, ADC_CHANNEL_PTR);
_mqx_int _adt_hw_channel_deinit(MQX_FILE_PTR, ADT_CHANNEL_PTR);
_mqx_int _adc_hw_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);
_mqx_int _adt_hw_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);

void _adc_hw_measure(ADC_HW_CHANNEL_MASK);
_mqx_int _adt_hw_run(void);
_mqx_int _adt_hw_stop(void);
void _adt_hw_set_wait(uint_32);
uint_32 _adt_hw_get_time(void);

void adc_process_all_data(void);

#ifdef __cplusplus
}
#endif

#endif /* __adc_kadc_prv_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_c90.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_c90.c$
* $Version : 3.8.4.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions for internal flash read, write, erase 
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "flash_c90_prv.h"
#include "flash_c90.h"


/* Forward declarations */
static void c90_flash_exec(VC90_REG_STRUCT_PTR reg_ptr);
static void c90_flash_exec_end(void);


const FLASHX_DEVICE_IF_STRUCT _flashx_c90_if = {
    c90_flash_sector_erase,
    c90_flash_sector_program,
    c90_flash_chip_erase,
    NULL /* READ */, 
    c90_flash_init,
    c90_flash_deinit,
    c90_flash_write_protect,
    NULL /* IOCTL */
};


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : c90_flash_init
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Initialize flash specific information.
*
*END*----------------------------------------------------------------------*/
boolean c90_flash_init
(
    /* [IN] Flash info structure */
    IO_FLASHX_STRUCT_PTR flash_ptr
)
{
    C90_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
    VC90_REG_STRUCT_PTR reg_ptr;
    FLASHX_BLOCK_INFO_STRUCT_PTR block_info_ptr;

    pointer ram_code_ptr;
    int     ram_code_size;
    uint_32 aspace;

    reg_ptr = _bsp_get_c90_address(flash_ptr->BASE_ADDR);
    if (reg_ptr == NULL)
    {
        return FALSE;
    }

    /* allocate internal structure */
    dev_spec_ptr = _mem_alloc_system(sizeof (C90_FLASH_INTERNAL_STRUCT));
    if( dev_spec_ptr == NULL)
    {
        return FALSE;
    }
    flash_ptr->DEVICE_SPECIFIC_DATA = dev_spec_ptr;

    dev_spec_ptr->reg_ptr = reg_ptr;

    /* allocate space to execute flashing from RAM, FIXME: this shall be in PSP */
    ram_code_size = (char_ptr)c90_flash_exec_end  - (char_ptr)c90_flash_exec;
    ram_code_ptr = _mem_alloc_system(ram_code_size);
    
    if (ram_code_ptr == NULL)
    {
        _mem_free(dev_spec_ptr);
        return FALSE; 
    }
    dev_spec_ptr->flash_exec = ram_code_ptr;

    /* copy code to RAM */
    _mem_copy ((char_ptr)c90_flash_exec, ram_code_ptr, ram_code_size);

    /* count how many sectors belong to each address space */
    dev_spec_ptr->aspace_sectors[C90_ASPACE_LAS] = 0;
    dev_spec_ptr->aspace_sectors[C90_ASPACE_MAS] = 0;
    dev_spec_ptr->aspace_sectors[C90_ASPACE_HAS] = 0;
    dev_spec_ptr->aspace_sectors[C90_ASPACE_SHADOW] = 0;

    block_info_ptr = flash_ptr->HW_BLOCK;
    
    while (block_info_ptr->NUM_SECTORS) {

        aspace = C90_ASPACE(block_info_ptr->SPECIAL_TAG);
        if (aspace >= 0 && aspace < C90_ASPACE_COUNT)
            dev_spec_ptr->aspace_sectors[aspace] += block_info_ptr->NUM_SECTORS;

        block_info_ptr++;
    }        

    return TRUE;    
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : c90_flash_deinit
* Returned Value   : none
* Comments         :
*   Release flash specific information.  
*
*END*----------------------------------------------------------------------*/
void c90_flash_deinit 
( 
    /* [IN] Flash info structure */
    IO_FLASHX_STRUCT_PTR flash_ptr 
)
{
    C90_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;

    /* de-allocate the device specific structure */
    dev_spec_ptr = flash_ptr->DEVICE_SPECIFIC_DATA;
    _mem_free(dev_spec_ptr->flash_exec);
    _mem_free(dev_spec_ptr);

    flash_ptr->DEVICE_SPECIFIC_DATA = NULL;
}   


    
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : c90_flash_addr_to_sector
* Returned Value   : pointer to matching FLASHX_BLOCK_INFO_STRUCT  
* Comments         :
*   Finds address space and sector number for given address
*
*END*----------------------------------------------------------------------*/
static FLASHX_BLOCK_INFO_STRUCT_PTR c90_flash_addr_to_sector
(
    /* [IN] Flash info structure */
    IO_FLASHX_STRUCT_PTR flash_ptr, 
    
    /* [IN] Address */
    uint_32 addr,
    
    /* [OUT] Address space */
    int *aspace,

    /* [OUT] Sector in the address space */
    int *aspace_sec
)  
{
    C90_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
    FLASHX_BLOCK_INFO_STRUCT_PTR block_info_ptr;

    dev_spec_ptr = flash_ptr->DEVICE_SPECIFIC_DATA;
    block_info_ptr = flash_ptr->HW_BLOCK;

    *aspace = 0;
    *aspace_sec = 0;    

    /* walk through the block info array, assuming it is:
       1) address space boundaries are between the blocks
       2) blocks belonging to different address spaces are not mixed */
    while (block_info_ptr->NUM_SECTORS) {

        if (*aspace != C90_ASPACE(block_info_ptr->SPECIAL_TAG))
        {
            *aspace = C90_ASPACE(block_info_ptr->SPECIAL_TAG);
            *aspace_sec=0;        
        } 
        
        if ((addr >= block_info_ptr->START_ADDR) && (addr < block_info_ptr->START_ADDR + block_info_ptr->NUM_SECTORS * block_info_ptr->SECTOR_SIZE))
            break; /* found matching sector */

        *aspace_sec += block_info_ptr->NUM_SECTORS;
        block_info_ptr++;
    }

    if (block_info_ptr->NUM_SECTORS == 0)
    {
        *aspace = 0;
        *aspace_sec = 0;
        return NULL; /*  no matching sector found */
    }

    *aspace_sec += (addr - block_info_ptr->START_ADDR) / block_info_ptr->SECTOR_SIZE;
    return block_info_ptr;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : c90_flash_protection_check
* Returned Value   : TRUE if write protected, FALSE otherwise
* Comments         :
*   Check for protection of given sector
*
*END*----------------------------------------------------------------------*/
static boolean c90_flash_protection_check
(
    /* [IN] Flash info structure */
    IO_FLASHX_STRUCT_PTR flash_ptr,
     
    /* [IN] Address space */
    int aspace,

    /* [IN] Sector in the address space */
    int aspace_sec
)
{
    C90_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
    VC90_REG_STRUCT_PTR reg_ptr;

    uint_32 aspace_mask;

    dev_spec_ptr = flash_ptr->DEVICE_SPECIFIC_DATA;
    reg_ptr = dev_spec_ptr->reg_ptr;
    
    aspace_mask = 1<<aspace_sec;

    switch (aspace) {
        case C90_ASPACE_LAS:
            if (reg_ptr->LML & C90_LML_LLOCK(aspace_mask)) return TRUE;        
            if (reg_ptr->SLL & C90_SLL_SLLOCK(aspace_mask)) return TRUE;        
            break;
        case C90_ASPACE_MAS:
            if (reg_ptr->LML & C90_LML_MLOCK(aspace_mask)) return TRUE;        
            if (reg_ptr->SLL & C90_SLL_SMLOCK(aspace_mask)) return TRUE;        
            break;
        case C90_ASPACE_HAS:
            if (reg_ptr->HBL & C90_HBL_HLOCK(aspace_mask)) return TRUE;
            break;
        case C90_ASPACE_SHADOW:
            if (reg_ptr->LML & C90_LML_SLOCK) return TRUE;
            if (reg_ptr->SLL & C90_SLL_SSLOC) return TRUE;
            break;
    }

    return FALSE;
}



/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : c90_flash_sector_erase
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Erase a flash memory block.
*
*END*----------------------------------------------------------------------*/
boolean c90_flash_sector_erase
(
    /* [IN] Flash info structure */
    IO_FLASHX_STRUCT_PTR flash_ptr, 

    /* [IN] Erased sector address */
    char_ptr             erase_ptr,

    /* [IN] Erased sector size */
    _mem_size            size
)
{
    C90_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
    VC90_REG_STRUCT_PTR reg_ptr;
    FLASHX_BLOCK_INFO_STRUCT_PTR block_info_ptr;

    uint_32 erase_addr;

    int aspace; /* address space (LAS, MAS, HAS) */
    int aspace_sec; /* sector counter of current address space */
    uint_32 aspace_mask[4];

    /* -- end of declarations -- */

    dev_spec_ptr = flash_ptr->DEVICE_SPECIFIC_DATA;
    reg_ptr = dev_spec_ptr->reg_ptr;

    erase_addr = (uint_32)erase_ptr - (uint_32)(flash_ptr->BASE_ADDR);

    /* convert address to address space and sector number */
    block_info_ptr = c90_flash_addr_to_sector(flash_ptr, erase_addr, &aspace, &aspace_sec);  

    if (block_info_ptr == NULL)
        return FALSE; /* no matching sector found */
        
    if ((erase_addr - block_info_ptr->START_ADDR) % block_info_ptr->SECTOR_SIZE)
        return FALSE; /* misaligned address */

    if (size != block_info_ptr->SECTOR_SIZE)
        return FALSE; /* only single sector erase is supported */

    /* check for protection */
    if (c90_flash_protection_check(flash_ptr, aspace, aspace_sec))
        return FALSE;

    aspace_mask[0] = aspace_mask[1] = aspace_mask[2] = aspace_mask[3] = 0;
    aspace_mask[aspace] = 1<<aspace_sec;

    /* start erase sequence */
    reg_ptr->MCR |= C90_MCR_ERS;

    reg_ptr->LMS = C90_LMS_LSEL(aspace_mask[C90_ASPACE_LAS]) | C90_LMS_MSEL(aspace_mask[C90_ASPACE_MAS]);
    reg_ptr->HBS = C90_HBS_HSEL(aspace_mask[C90_ASPACE_HAS]);

    *((uint_32 *)erase_ptr) = 0; /* dummy write to flash required */
    dev_spec_ptr->flash_exec(reg_ptr);
    
    if ((reg_ptr->MCR & C90_MCR_PEG) == 0)
    {
        reg_ptr->MCR &= ~C90_MCR_ERS;
        return FALSE;
    }
    
    reg_ptr->MCR &= ~C90_MCR_ERS;
    
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : c90_flash_sector_program
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Performs a write into flash memory.
*
*END*----------------------------------------------------------------------*/
boolean c90_flash_sector_program
(
    /* [IN] Flash info structure */
    IO_FLASHX_STRUCT_PTR flash_ptr,

    /* [IN] Source address */
    char_ptr             from_ptr,

    /* [IN] Destination address */
    char_ptr             to_ptr,

    /* [IN] Number of bytes to write */
    _mem_size            size
) 
{
    C90_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
    VC90_REG_STRUCT_PTR reg_ptr;
    FLASHX_BLOCK_INFO_STRUCT_PTR block_info_ptr;

    uint_32 *src;
    volatile uint_32 *dst;
    
    int aspace;
    int aspace_sec;

    int align;
    int width;

    uint_32 to_addr;
           

    to_addr = (uint_32)to_ptr - (uint_32)(flash_ptr->BASE_ADDR);

    /* convert address to address space and sector number */
    block_info_ptr = c90_flash_addr_to_sector(flash_ptr, to_addr, &aspace, &aspace_sec);
    
    if (block_info_ptr == NULL)
        return FALSE; /* no matching sector found */

    /* check alignment if applicable, ECC might not be computed correctly for missaligned data */
    align = C90_ALIGN(block_info_ptr->SPECIAL_TAG);
    
    if (align)
    {
        if (to_addr % align)
            return FALSE; /* misaligned address */
        
        if (size % align)
            return FALSE; /* misaligned size */
    }  

    if ((to_addr - block_info_ptr->START_ADDR) % block_info_ptr->SECTOR_SIZE + size > block_info_ptr->SECTOR_SIZE)
        return FALSE; /* write only within a single sector is supported */

    /* check for protection */
    if (c90_flash_protection_check(flash_ptr, aspace, aspace_sec))
        return FALSE;

    dev_spec_ptr = flash_ptr->DEVICE_SPECIFIC_DATA;
    reg_ptr = dev_spec_ptr->reg_ptr;

    src = (uint_32 *)from_ptr;    
    dst = (uint_32 *)to_ptr;    

    width = C90_WIDTH(block_info_ptr->SPECIAL_TAG);

    while (size >= 4)
    {
        /* start programming sequence */
        reg_ptr->MCR |= C90_MCR_PGM;

        /* if there are at least 128 bits to be written and the destination address is aligned */ 
        if ((width >= 128) && (size >= 16 && (((uint_32)dst % 16) == 0)))
        {
            *dst++ = *src++;
            *dst++ = *src++;
            *dst++ = *src++;
            *dst++ = *src++;
            size -= 16;    
        }         
        else if ((width >= 64) && (size >= 8 && (((uint_32)dst % 8) == 0)) ){
            /* write 64 bits */
            *dst++ = *src++;
            *dst++ = *src++;
            size -= 8;
        } else {
            /* write 32 bits */
            *dst++ = *src++;
            size -= 4;
        }            
   
        dev_spec_ptr->flash_exec(reg_ptr);
    
        if ((reg_ptr->MCR & C90_MCR_PEG) == 0)
        {
            reg_ptr->MCR &= ~C90_MCR_PGM;    
            return FALSE;
        }

        reg_ptr->MCR &= ~C90_MCR_PGM;
    }

    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : c90_flash_chip_erase
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Erase the whole flash memory.
*
*END*----------------------------------------------------------------------*/
boolean c90_flash_chip_erase 
(
    /* [IN] Flash info structure */
    IO_FLASHX_STRUCT_PTR flash_ptr
)
{
    C90_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
    VC90_REG_STRUCT_PTR reg_ptr;

    uint_32 las_mask;
    uint_32 mas_mask;
    uint_32 has_mask;

    dev_spec_ptr = flash_ptr->DEVICE_SPECIFIC_DATA;
    reg_ptr = dev_spec_ptr->reg_ptr;
     
    las_mask = (1 << dev_spec_ptr->aspace_sectors[C90_ASPACE_LAS]) - 1;
    mas_mask = (1 << dev_spec_ptr->aspace_sectors[C90_ASPACE_MAS]) - 1;
    has_mask = (1 << dev_spec_ptr->aspace_sectors[C90_ASPACE_HAS]) - 1;
    
    /* check for protection */
    if (reg_ptr->LML & (C90_LML_LLOCK(las_mask) | C90_LML_MLOCK(mas_mask)))
        return FALSE;

    if (reg_ptr->SLL & (C90_SLL_SLLOCK(las_mask) | C90_SLL_SMLOCK(mas_mask)))
        return FALSE;

    if (reg_ptr->HBL & C90_HBL_HLOCK(has_mask))
        return FALSE;
        
    /* start erase sequence */
    reg_ptr->MCR |= C90_MCR_ERS;

    reg_ptr->LMS = C90_LMS_LSEL(las_mask) | C90_LMS_MSEL(mas_mask);
    reg_ptr->HBS = C90_HBS_HSEL(has_mask);

    *((uint_32 *)(flash_ptr->BASE_ADDR)) = 0; /* dummy write to flash required */
    dev_spec_ptr->flash_exec(reg_ptr);
    
    if ((reg_ptr->MCR & C90_MCR_PEG) == 0)
    {
        reg_ptr->MCR &= ~C90_MCR_ERS;
        return FALSE;
    }
    
    reg_ptr->MCR &= ~C90_MCR_ERS;
    
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : c90_flash_write_protect
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Sets/clears write protection of the FLASH
*
*END*----------------------------------------------------------------------*/
boolean c90_flash_write_protect
(
    /* [IN] Flash info structure */
    IO_FLASHX_STRUCT_PTR flash_ptr,

    /* [IN] Requested protection state (true = protected) */
    _mqx_uint state
)
{
    uint_32 las_mask;
    uint_32 mas_mask;
    uint_32 has_mask;

    uint_32 lml_mask;
    uint_32 sll_mask;
    uint_32 hbl_mask;
    
    uint_32 lml;
    uint_32 sll;
    uint_32 hbl;

    C90_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr;
    VC90_REG_STRUCT_PTR reg_ptr;

    dev_spec_ptr = flash_ptr->DEVICE_SPECIFIC_DATA;
    reg_ptr = dev_spec_ptr->reg_ptr;

    las_mask = (1 << dev_spec_ptr->aspace_sectors[C90_ASPACE_LAS]) - 1;
    mas_mask = (1 << dev_spec_ptr->aspace_sectors[C90_ASPACE_MAS]) - 1;
    has_mask = (1 << dev_spec_ptr->aspace_sectors[C90_ASPACE_HAS]) - 1;

    lml_mask = C90_LML_SLOCK | C90_LML_MLOCK(mas_mask) | C90_LML_LLOCK(las_mask);
    sll_mask = C90_SLL_SSLOC | C90_SLL_SMLOCK(mas_mask) | C90_SLL_SLLOCK(las_mask);
    hbl_mask = C90_HBL_HLOCK(has_mask);

    if (state)
    {
        lml = lml_mask;
        sll = sll_mask;
        hbl = hbl_mask;
    }
    else
    {
        lml = 0;
        sll = 0;
        hbl = 0;
    }
    
    if ((reg_ptr->LML & lml_mask) != lml)
    {
        if ((reg_ptr->LML & C90_LML_LME) == 0)
            reg_ptr->LML = C90_LML_PASSWORD;
        reg_ptr->LML = lml;
    }

    if ((reg_ptr->SLL & sll_mask) != sll)
    {
        if ((reg_ptr->SLL & C90_SLL_SLE) == 0)
            reg_ptr->SLL = C90_SLL_PASSWORD;
        reg_ptr->SLL = sll;
    }

    if ((reg_ptr->HBL & hbl_mask) != hbl)
    {
        if ((reg_ptr->HBL & C90_HBL_HBE) == 0)
            reg_ptr->HBL = C90_HBL_PASSWORD;
        reg_ptr->HBL = hbl;
    }

    return TRUE;
}


/********************************************************************
*
*  Code required to run in SRAM to perform flash commands. 
*  All else can be run in flash.
*  Parameter is an address of flash status register.
*
********************************************************************/ 
static void c90_flash_exec
( 
    VC90_REG_STRUCT_PTR reg_ptr
) 
{
  
    reg_ptr->MCR |= C90_MCR_EHV;
    while ((reg_ptr->MCR & C90_MCR_DONE) == 0)
    	;
    reg_ptr->MCR &= ~C90_MCR_EHV;
}
         
/* Dummy function to obtain ram_function length. This assumes that linker places objects in the same order as they appear in the source */
static void c90_flash_exec_end
(
    void
)
{
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ip6_prv.h<|end_filename|>
#ifndef __ip6_prv_h__
#define __ip6_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip6_prv.h$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Internal definitions for the Internet Protocol layer.
*
*
*END************************************************************************/

#include "rtcs.h"
#include "ip.h"

#if RTCSCFG_ENABLE_IP6_STATS
#define IF_IP6_STATS_ENABLED(x) x
#else
#define IF_IP6_STATS_ENABLED(x)
#endif


/*********************************************************************
*
* Type definitions
*
*********************************************************************/

/* RFC4484:
 *  Multicast destination addresses have a 4-bit scope field that
 *  controls the propagation of the multicast packet.  The IPv6
 *  addressing architecture defines scope field values for interface-
 *  local (0x1), link-local (0x2), subnet-local (0x3), admin-local (0x4),
 *  site-local (0x5), organization-local (0x8), and global (0xE)
 *  scopes [11].
 */
#define IP6_ADDR_SCOPE_INTFACELOCAL (0x01)
#define IP6_ADDR_SCOPE_LINKLOCAL    (0x02)
#define IP6_ADDR_SCOPE_SITELOCAL    (0x05)
#define IP6_ADDR_SCOPE_ORGLOCAL     (0x08)
#define IP6_ADDR_SCOPE_GLOBAL       (0x0e)


#define IP6_ADDR_MULTICAST_SCOPE(a) ((a)->s6_addr[1] & 0x0f)

/*********************************************************************
* IP packet header
**********************************************************************
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |Version| Traffic Class |           Flow Label                  |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |         Payload Length        |  Next Header  |   Hop Limit   |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |                                                               |
*   +                                                               +
*   |                                                               |
*   +                         Source Address                        +
*   |                                                               |
*   +                                                               +
*   |                                                               |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |                                                               |
*   +                                                               +
*   |                                                               |
*   +                      Destination Address                      +
*   |                                                               |
*   +                                                               +
*   |                                                               |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
**********************************************************************/
typedef struct IP6_HEADER
{
   uchar    VERSION_TCLASS[1];	/* 4-bit Internet Protocol version number = 6, 8-bit traffic class field. */
   uchar    TCLASS_FLOWL[1]; 	/* 20-bit flow label. */
   uchar    FLOWL[2];        
   uchar    LENGTH[2];			/* Length of the IPv6
								 * payload, i.e., the rest of the packet following
							     * this IPv6 header, in octets. */
   uchar    NEXT_HEADER[1]; 	/* Identifies the type of header
                        		 * immediately following the IPv6 header.  Uses the
                        		 * same values as the IPv4 Protocol field [RFC-1700
                        		 * et seq.].*/
   uchar    HOP_LIMIT[1];   	/* Decremented by 1 by
                        		 * each node that forwards the packet. The packet
                        		 * is discarded if Hop Limit is decremented to
                        		 * zero. */
   uchar    SOURCE[16];     	/* 128-bit address of the originator of the packet. */
   uchar    DEST[16];       	/* 128-bit address of the intended recipient of the
								 * packet (possibly not the ultimate recipient, if
								 * a Routing header is present). */

} IP6_HEADER, _PTR_ IP6_HEADER_PTR;

#define IP6_HEADER_LEN		    (40) /* IPv6 Header size. */

#define IP6_HEADER_VERSION		0x60
#define IP6_HEADER_VERSION_MASK	0xf0

/******************************************************************
* Extension header types
*******************************************************************/
#define IP6_TYPE_HOP_BY_HOP_OPTIONS                     (0)
#define IP6_TYPE_DESTINATION_OPTIONS                    (60)
#define IP6_TYPE_ROUTING_HEADER                         (43)
#define IP6_TYPE_FRAGMENT_HEADER                        (44)
#define IP6_TYPE_AUTHENTICATION_HEADER                  (51)
#define IP6_TYPE_ENCAPSULATION_SECURITY_PAYLOAD_HEADER  (50)
#define IP6_TYPE_MOBILITY_HEADER                        (135)
#define IP6_TYPE_NO_NEXT_HEADER                         (59)

/***********************************************************************
 * Hop-by-Hop Options Header & Destination Options Header
 *
 * The Hop-by-Hop Options header is used to carry optional information
 * that must be examined by every node along a packet’s delivery path.
 *
 * The Destination Options header is used to carry optional information
 * that need be examined only by a packet’s destination node(s).
 ***********************************************************************
 * RFC 2460 4.3/4.6:
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  | Next Header   | Hdr Ext Len   |                               |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
 *  |                                                               |
 *  .                                                               .
 *  .                         Options                               .
 *  .                                                               .
 *  |                                                               |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 ***********************************************************************/
typedef struct IP6_OPTIONS_HEADER
{
   uchar    NEXT_HEADER[1];     /* 8-bit selector. Identifies the type of header
                                 * immediately following the Options
                                 * header. */
   uchar    HDR_EXT_LENGTH[1];  /* 8-bit unsigned integer. Length of the Hop-by-
                                 * Hop Options header in 8-octet units, not
                                 * including the first 8 octets. */
   uchar    OPTIONS[6];         /* Variable-length field, of length such that the
                                 * complete Options header is an integer
                                 * multiple of 8 octets long. */
} IP6_OPTIONS_HEADER, _PTR_ IP6_OPTIONS_HEADER_PTR;


/***********************************************************************
 * Options (used in op-by-Hop Options Header & Destination Options Header) 
 ***********************************************************************
 * RFC 2460 4.2:
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
 * | Option Type   | Opt Data Len  | Option Data
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
 ***********************************************************************/
typedef struct IP6_OPTION_HEADER
{
   uchar    TYPE[1];        /* 8-bit identifier of the type of option. */
   uchar    DATA_LENGTH[1]; /* 8-bit unsigned integer. Length of the Option
                             * Data field of this option, in octets. */
} IP6_OPTION_HEADER, _PTR_ IP6_OPTION_HEADER_PTR;

/* RFC 2460 4.2: There are two padding options which are used when necessary to align
 * subsequent options and to pad out the containing header to a multiple
 * of 8 octets in length. */

#define IP6_OPTION_TYPE_PAD1    (0x00)  /* The Pad1 option is used to insert 
                                         * one octet of padding into the Options area of a header.*/
#define IP6_OPTION_TYPE_PADN    (0x01)  /* The PadN option is used to insert two or more octets of padding
                                         * into the Options area of a header. For N octets of padding, the
                                         * Opt Data Len field contains the value N-2, and the Option Data
                                         * consists of N-2 zero-valued octets. */


/* RFC 2460: The Option Type identifiers are internally encoded such that their
 * highest-order two bits specify the action that must be taken if the
 * processing IPv6 node does not recognize the Option Type:*/
#define IP6_OPTION_TYPE_UNRECOGNIZED_MASK           (0xC0)

#define IP6_OPTION_TYPE_UNRECOGNIZED_SKIP           (0x00)  /* 00 - skip over this option and continue processing the header.*/
#define IP6_OPTION_TYPE_UNRECOGNIZED_DISCARD        (0x40)  /* 01 - discard the packet. */
#define IP6_OPTION_TYPE_UNRECOGNIZED_DISCARD_ICMP   (0x80)  /* 10 - discard the packet and, regardless of whether or not the
                                                             * packet’s Destination Address was a multicast address, send an
                                                             * ICMP Parameter Problem, Code 2, message to the packet’s
                                                             * Source Address, pointing to the unrecognized Option Type.*/
#define IP6_OPTION_TYPE_UNRECOGNIZED_DISCARD_UICMP  (0xC0)  /* 11 - discard the packet and, only if the packet’s Destination
                                                             * Address was not a multicast address, send an ICMP Parameter
                                                             * Problem, Code 2, message to the packet’s Source Address,
                                                             * pointing to the unrecognized Option Type.*/

/***********************************************************************
 * Routing Header
 *
 * The Routing header is used by an IPv6 source to list one or more
 * intermediate nodes to be "visited" on the way to a packet’s
 * destination.
 ***********************************************************************
 * RFC 2460 4.4:
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  | Next Header   | Hdr Ext Len   | Routing Type  | Segments Left |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |                                                               |
 *  .                                                               .
 *  .                       type-specific data                      .
 *  .                                                               .
 *  |                                                               |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 ***********************************************************************/
typedef struct IP6_ROUTING_HEADER
{
    uchar    NEXT_HEADER[1];    /* 8-bit selector. Identifies the type of header
                                 * immediately following the Options
                                 * header. */
    uchar    HDR_EXT_LENGTH[1]; /* 8-bit unsigned integer. Length of the Hop-by-
                                 * Hop Options header in 8-octet units, not
                                 * including the first 8 octets. */
    uchar    ROUTING_TYPE[1];   /* 8-bit identifier of a particular Routing header
                                 * variant.*/ 
    uchar    SEGMENTS_LEFT[1];  /* 8-bit unsigned integer. Number of route
                                 * segments remaining, i.e., number of explicitly
                                 * listed intermediate nodes still to be visited
                                 * before reaching the final destination.*/                                                                
    uchar    DATA[4];           /* Variable-length field, of format determined by
                                 * the Routing Type, and of length such that the
                                 * complete Routing header is an integer multiple
                                 * of 8 octets long. */
} IP6_ROUTING_HEADER, _PTR_ IP6_ROUTING_HEADER_PTR;







/* Time to live of a datagram awaiting reassembly (no relation to the IP TTL) */
/* RFC 2460: If insufficient fragments are received to complete reassembly of a
 * packet within 60 seconds of the reception of the first-arriving
 * fragment of that packet, reassembly of that packet must be
 * abandoned and all the fragments that have been received for that
 * packet must be discarded.*/
#define IP6REASM_TTL              60000       /* 60 secs */

/***********************************************************************
 * Fragment Header
 ***********************************************************************
 * RFC 2460 4.5:
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |  Next Header  |   Reserved    |      Fragment Offset    |Res|M|
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |                         Identification                        |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 ***********************************************************************/
typedef struct IP6_FRAGMENT_HEADER
{
   uchar    NEXT_HEADER[1]; /* 8-bit selector.  Identifies the initial header
                             * type of the Fragmentable Part of the original
                             * packet (defined below).  Uses the same values as
                             * the IPv4 Protocol field [RFC-1700 et seq.]. */
   uchar    RESERVED[1]; 	/* Initialized to zero for
                             * transmission; ignored on reception. */
   uchar    OFFSET_MORE[2]; /* @ 13-bit unsigned integer.  The offset, in 8-octet
                             * units, of the data following this header,
                             * relative to the start of the Fragmentable Part
                             * of the original packet.
                             * @ 2-bit reserved field.  Initialized to zero for
                             * transmission; ignored on reception.
                             * @ 1 = more fragments; 0 = last fragment.*/       
   uchar    ID[4];			/* Identification. */
} IP6_FRAGMENT_HEADER, _PTR_ IP6_FRAGMENT_HEADER_PTR;


#define IP6_FRAGMENT_MF             0x1     /* If 1, this is not last fragment */
#define IP6_FRAGMENT_OFFSET_MASK    0xFFF8  /* The offset of frag in dgram */

/***********************************************************************
* IPv6 Configuration.  This information is persistent for the IPv6 layer.
***********************************************************************/
typedef struct ip6_cfg_struct
{
#if RTCSCFG_ENABLE_IP6_STATS
    IP6_STATS         STATS;
#endif
    ICB_STRUCT_PTR    ICB6_HEAD;        /* Head of open ICBs, used by IPv6 */
    uint_32           NEXT_ID6;         /* Next packet identifier */
    uint_16           DEFAULT_HOPLIMIT; /* Default Hop Limit */

} IP6_CFG_STRUCT, _PTR_ IP6_CFG_STRUCT_PTR;

/******************************************************************
* Function Prototypes
*******************************************************************/
struct ip_if; /* Just to avoid header conflicts.*/
uint_32 IP6_send_dgram ( struct ip_if *ifdest, RTCSPCB_PTR inrtcs_pcb, in6_addr *hopsrc, in6_addr *hopdest, in6_addr *ipdest, uint_32 protocol);
void ip6_get_solicited_multicast_addr(in6_addr *ip_addr, in6_addr *solicited_multicast_addr);

uint_32 IP6_reasm_init (void);
uint_32 IP6_reasm      (RTCSPCB_PTR, RTCSPCB_PTR _PTR_);


uint_32 IP6_MTU ( in6_addr *iplocal     /* [IN] the local IP address */,
                  in6_addr *ipremote    /* [IN] the remote IP address to test */ );
in6_addr * IP6_route_find( in6_addr *ipdest   /* [IN] the ultimate destination */,
                                 uint_32 flags      /* [IN] optional flags (Not used - TBD delete it*/); 
int ip6_common_prefix_length(in6_addr *ip_addr_1, in6_addr *ip_addr_2);                                                  
int ip6_addr_scope(in6_addr *ip_addr);
boolean ip6_addr_pefix_cmp(in6_addr *addr_1, in6_addr *addr_2, uint_32 prefix_length);

#endif /* __ip6_prv_h__ */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/hdlcio.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hdlcio.c$
* $Version : 3.8.8.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the HDLC device functions needed
*   for communication.
*
*END************************************************************************/

#include <rtcshdlc.h>
#include <rtcs_in.h>


static uint_32 _iopcb_hdlc_open  (_iopcb_handle, void (_CODE_PTR_)(pointer), void (_CODE_PTR_)(pointer), pointer);
static uint_32 _iopcb_hdlc_close (_iopcb_handle);
static void    _iopcb_hdlc_write (_iopcb_handle, PCB_PTR, uint_32);
static PCB_PTR _iopcb_hdlc_read  (_iopcb_handle, uint_32);
static uint_32 _iopcb_hdlc_ioctl (_iopcb_handle, uint_32, pointer);


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlc_rcv_unblock
*  Returned Value : void
*  Comments       : Unblocks the PPP rx task when a messge is received
*
*
*END*-----------------------------------------------------------------*/

void _iopcb_hdlc_rcv_unblock
   (
   pointer param
   /* [IN] The semaphore to unblock when the message arrives */
   )
{  /* Body */

#if RTCSCFG_ENABLE_IP4

   LWSEM_STRUCT _PTR_ sem = (LWSEM_STRUCT _PTR_)param;
   PPP_mutex_unlock(sem);
   
#endif /* RTCSCFG_ENABLE_IP4  */

}  /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlc_init
*  Returned Value : a HANDLE to be used by other functions
*  Comments       :
*      Sets some of the values of the ppphdlc structure and
*  returns the handle of the structure.
*
*END*-----------------------------------------------------------------*/

_iopcb_handle _iopcb_hdlc_init
   (
   uint_16       channel_queue,
   /* [IN] - the HDLC message queue for this channel */
   _RTCS_poolid  pool_id,
   /* [IN] - the HDLC message pool */
   _RTCS_queueid channel_qid,
   /* [IN] - the HDLC queue id */
   _ppp_mutex _PTR_ mutex_ptr
   )
{  /* Body */

#if RTCSCFG_ENABLE_IP4

   HDLCIO_STRUCT_PTR hdlcio_ptr;
   _rtcs_part        part_id;

   hdlcio_ptr = RTCS_memalloc(sizeof(HDLCIO_STRUCT));
   if (!hdlcio_ptr) {
      return NULL;
   } /* Endif */
   part_id = RTCS_part_create(sizeof(PCB)
                            + sizeof(PCB_FRAGMENT)
                            + RTCS_HDLC_MESSAGE_SIZE,
                              8, 0, 8, NULL, NULL);

   hdlcio_ptr->PART_ID         = part_id;
   hdlcio_ptr->MUTEX_PTR       = mutex_ptr;
   hdlcio_ptr->POOL_ID         = pool_id;
   hdlcio_ptr->QID             = channel_qid;
   hdlcio_ptr->CHANNEL_Q       = channel_queue;
   hdlcio_ptr->PCB_TABLE.OPEN  = _iopcb_hdlc_open;
   hdlcio_ptr->PCB_TABLE.CLOSE = _iopcb_hdlc_close;
   hdlcio_ptr->PCB_TABLE.READ  = _iopcb_hdlc_read;
   hdlcio_ptr->PCB_TABLE.WRITE = _iopcb_hdlc_write;
   hdlcio_ptr->PCB_TABLE.IOCTL = _iopcb_hdlc_ioctl;

   return &hdlcio_ptr->PCB_TABLE;
   
#else   

    return FALSE;

#endif /* RTCSCFG_ENABLE_IP4 */
   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlc_open
*  Returned Value : uint_32, an ERROR code
*  Comments       :
*      Sets some of the values of the ppphdlc structure and opens the link.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_hdlc_open
   (
      _iopcb_handle       handle,
         /* [IN] - the IO handle*/
      void (_CODE_PTR_    up)(pointer),
         /* [IN] - function to put the link up */
      void (_CODE_PTR_    down)(pointer),
         /* [IN] - function to put the link down */
      pointer             param
         /* [IN] - for the up/down functions */
   )
{  /* Body */
   HDLCIO_STRUCT_PTR hdlcio_ptr = (HDLCIO_STRUCT_PTR)((void _PTR_)handle);
   hdlcio_ptr->UP      = up;
   hdlcio_ptr->DOWN    = down;
   hdlcio_ptr->PARAM   = param;

   /* signal the PPP layer that the connection is open */
   if (hdlcio_ptr->UP) {
      up(param);
   } /* Endif */

   return HDLCIO_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlc_write
*  Returned Value :
*  Comments       :
*      Transmits the data
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void _iopcb_hdlc_write
   (
   _iopcb_handle      handle,
   /* [IN] - the handle */
   PCB_PTR            pcb_ptr,
   /* [IN] - the packet */
   uint_32            flags
   /* [IN] - the flags */
   )
{ /* Body */
   RTCS_HDLC_MESSAGE_STRUCT_PTR msg_ptr;
   HDLCIO_STRUCT_PTR            hdlcio_ptr = (HDLCIO_STRUCT_PTR)((void _PTR_)handle);
   uint_32                      data_length = 0;
   uint_32                      i = 0;
   uint_32                      j = 0;
   _RTCS_queueid                qid;

   while (pcb_ptr->FRAG[i].LENGTH && (data_length <= RTCS_HDLC_MESSAGE_SIZE)) {
      data_length += pcb_ptr->FRAG[i].LENGTH;
      i++;
   } /* Endwhile */
   i = 0;

   if ( data_length > RTCS_HDLC_MESSAGE_SIZE ) {
      PCB_free(pcb_ptr);
      return;
   }/* Endif */

   hdlcio_ptr->STATS.COMMON.ST_TX_TOTAL++;
   msg_ptr = (RTCS_HDLC_MESSAGE_STRUCT_PTR)RTCS_msg_alloc(hdlcio_ptr->POOL_ID);
   if (msg_ptr == NULL) {
      /* Free the PCB and return */
      hdlcio_ptr->STATS.COMMON.ST_TX_MISSED++;
      PCB_free(pcb_ptr);
      return;
   } /* Endif */

   /* assemble message to send */
   qid = RTCS_msgq_get_id(0, hdlcio_ptr->CHANNEL_Q);
   msg_ptr->HDLC_HEADER.HEADER.TARGET_QID = qid;
   msg_ptr->HDLC_HEADER.HEADER.SOURCE_QID = hdlcio_ptr->QID;
   msg_ptr->HDLC_HEADER.HEADER.SIZE = sizeof(RTCS_HDLC_MESSAGE_STRUCT)
      + data_length + 2;
   msg_ptr->HDLC_HEADER.PACKET_SIZE = data_length + 2;

   /* Add address and control bytes */
   msg_ptr->DATA[0] = 0xFF;
   msg_ptr->DATA[1] = 0x03;
   j+=2;



   while (pcb_ptr->FRAG[i].LENGTH) {
      RTCS_memcopy(pcb_ptr->FRAG[i].FRAGMENT, &msg_ptr->DATA[j],
         pcb_ptr->FRAG[i].LENGTH);
      j += pcb_ptr->FRAG[i].LENGTH;
      i++;
   } /* Endwhile */

   PCB_free(pcb_ptr);

   if (!RTCS_msgq_send(msg_ptr, hdlcio_ptr->POOL_ID)) {
      hdlcio_ptr->STATS.COMMON.ST_TX_MISSED++;
   } /* Endif */ ;

} /* Endbody */


#endif /* RTCSCFG_ENABLE_IP4 */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlc_read
*  Returned Value : PCB_PTR
*  Comments       :
*      Receives the data
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static PCB_PTR _iopcb_hdlc_read
   (
      _iopcb_handle    handle,
         /* [IN] - the structure handle */
      uint_32          flags
         /* [IN] - flags */
   )
{  /* Body */

   RTCS_HDLC_MESSAGE_STRUCT_PTR msg_ptr;
   HDLCIO_STRUCT_PTR            hdlcio_ptr = (HDLCIO_STRUCT_PTR)((void _PTR_)handle);
   PCB_FRAGMENT _PTR_           pcb_frag_ptr;
   uint_32                      data_length;
   PCB_PTR                      pcb;

   while (TRUE) {
      PPP_mutex_lock(hdlcio_ptr->MUTEX_PTR);
      msg_ptr = RTCS_msgq_receive(hdlcio_ptr->QID, 0, hdlcio_ptr->POOL_ID);
      hdlcio_ptr->STATS.COMMON.ST_RX_TOTAL++;
      if ( msg_ptr == NULL ) {
         hdlcio_ptr->STATS.COMMON.ST_RX_ERRORS++;
         RTCS_time_delay(1);
      } else {
         data_length = msg_ptr->HDLC_HEADER.PACKET_SIZE;
         if (data_length > RTCS_HDLC_MESSAGE_SIZE ) {
            hdlcio_ptr->STATS.ST_RX_GIANT++;
            RTCS_msg_free(msg_ptr);
            continue;
         } else if (data_length < 2) {
            hdlcio_ptr->STATS.ST_RX_RUNT++;
            RTCS_msg_free(msg_ptr);
            continue;
         } else {
            pcb = RTCS_part_alloc(hdlcio_ptr->PART_ID);
            if (!pcb) {
               hdlcio_ptr->STATS.COMMON.ST_RX_MISSED++;
               RTCS_msg_free(msg_ptr);
               continue;
            }/* Endif */
            break;
         } /* Endif */
      } /* Endif */
   } /* Endwhile */

   pcb->FREE = (void (_CODE_PTR_)(PCB_PTR))RTCS_part_free;
   pcb->PRIVATE = pcb;
   pcb_frag_ptr = pcb->FRAG;
   pcb_frag_ptr->FRAGMENT = (uchar_ptr)pcb + sizeof(PCB) + sizeof(PCB_FRAGMENT);
   pcb_frag_ptr->LENGTH = data_length - 2;
   pcb_frag_ptr++;
   pcb_frag_ptr->LENGTH = 0;
   pcb_frag_ptr->FRAGMENT = NULL;
   RTCS_memcopy(msg_ptr->DATA+2, pcb->FRAG[0].FRAGMENT, data_length - 2);
   RTCS_msg_free(msg_ptr);
   return pcb;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlc_close
*  Returned Value : uint_32, an ERROR code
*  Comments       :
*     Close link and free memory
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_hdlc_close
   (
      _iopcb_handle  handle
         /* [IN] - the structure handle */
   )
{  /* Body */
   HDLCIO_STRUCT_PTR hdlcio_ptr = (HDLCIO_STRUCT_PTR)((void _PTR_)handle);

   /* close connection */
   if (hdlcio_ptr->DOWN) {
      hdlcio_ptr->DOWN(hdlcio_ptr->PARAM);
   } /* Endif */

   RTCS_memfree(hdlcio_ptr);

   return HDLCIO_OK;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _iopcb_hdlc_ioctl
*  Returned Value : an ERROR code
*  Comments       :
*      Store and set the options
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 _iopcb_hdlc_ioctl
   (
      _iopcb_handle    handle,
         /* [IN] - the structure handle */
      uint_32          option,
         /* [IN] - options */
      pointer          value
         /* [IN] - option value */
   )
{  /* Body */
   uint_32 result = HDLCIO_OK;

   switch(option)  {
      case IOPCB_IOCTL_S_ACCM:
         break;
      case IOPCB_IOCTL_R_ACCM:
         break;
      case IOPCB_IOCTL_S_PFC:
         break;
      case IOPCB_IOCTL_R_PFC:
         break;
      case IOPCB_IOCTL_S_ACFC:
         break;
      case IOPCB_IOCTL_R_ACFC:
         break;
      case IOPCB_IOCTL_GET_IFTYPE:
         *(uint_32_ptr)value = IPIFTYPE_HDLC;
          break;
      default:
         result = IO_ERROR_INVALID_IOCTL_CMD;
         break;
   } /* Endswitch */

   return result;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwadc/lwadc_mpxsxx_prv.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2011 Embedded Access Inc
* All Rights Reserved
*
****************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwadc_mpxsxx_prv.h$
* $Version : 3.8.2.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*   CPU specific LWADC driver header file
*
*END************************************************************************/

#ifndef __lwadc_mpxsxx_prv_h__
#define __lwadc_mpxsxx_prv_h__

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern VPXADC_REG_STRUCT_PTR _bsp_get_adc_base_address(uint_32 device);
extern boolean _bsp_adc_enable_access(uint_32 device);
extern uint_32 _bsp_get_adc_channel_mask(uint_32 device);

#ifdef __cplusplus
}
#endif

#endif //__lwadc_mpxsxx_prv_h__


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/idletask.c<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: idletask.c$
* $Version : 3.8.3.2$
* $Date    : Mar-12-2012$
*
* Comments:
*
*   This file contains the idle task.
*
*END************************************************************************/

#include "mqx_inc.h"

#if MQX_USE_IDLE_TASK

/*!
 * \brief This function is the code for the idle task.
 *
 * Idle Task is a MQX task that runs when all application tasks are blocked.
 * \n This function implements a simple counter.
 * \n Counter can be read from a debugger and idle CPU time can be calculated.
 *
 * \param[in] parameter Parameter passed to the task when created.
 */
void _mqx_idle_task
    (
        uint_32 parameter
    )
{ /* Body */
    volatile KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    while (1) {
#if !defined(MQX_ENABLE_IDLE_LOOP) || MQX_ENABLE_IDLE_LOOP
        if (++kernel_data->IDLE_LOOP.IDLE_LOOP1 == 0) {
            if (++kernel_data->IDLE_LOOP.IDLE_LOOP2 == 0) {
                if (++kernel_data->IDLE_LOOP.IDLE_LOOP3 == 0) {
                ++kernel_data->IDLE_LOOP.IDLE_LOOP4;
                } /* Endif */
            } /* Endif */
        } /* Endif */
#endif
#if MQX_ENABLE_LOW_POWER
        if (parameter)
        {
            _ASM_SLEEP();
        }
#endif

    } /* Endwhile */

} /* Endbody */
#endif /* MQX_USE_IDLE_TASK */

/* EOF */



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/dnshosts.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dnshosts.c$
* $Version : 3.0.9.0$
* $Date    : Mar-5-2009$
*
* Comments:
*
*   This file contains the default hosts file structures
*   which contains the current list of root name servers.
*   It also contains the default local network name (for
*   appending to non-authoritative names (don't end in a '.')),
*   the default local server name struct, the default local
*   server list, and the initial Zone of Authority list.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_UDP
#if RTCSCFG_ENABLE_DNS

#include "dns.h"

char DNS_Local_network_name[] = ".";
uint_32 DNS_CACHE_NAME_LIMIT = 0;

/***********************************************************************

 This section is for the Root Servers List.
 This should only be assigned to the DNS config_ptr->ROOT_SLIST_PTR

***********************************************************************/

DNS_SLIST_STRUCT DNS_M_Root_server[] =
      {{"M.ROOT-SERVERS.NET.", NULL,
        0xCA0C1B21, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_L_Root_server[] =
      {{"L.ROOT-SERVERS.NET.", DNS_M_Root_server,
        0xC620400C, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_K_Root_server[] =
      {{"K.ROOT-SERVERS.NET.", DNS_L_Root_server,
        0xC1000E81, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_J_Root_server[] =
      {{"J.ROOT-SERVERS.NET.", DNS_K_Root_server,
        0xC03A801E, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_I_Root_server[] =
      {{"I.ROOT-SERVERS.NET.", DNS_J_Root_server,
        0xC0249411, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_H_Root_server[] =
      {{"H.ROOT-SERVERS.NET.", DNS_I_Root_server,
        0x803F0235, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_G_Root_server[] =
      {{"G.ROOT-SERVERS.NET.", DNS_H_Root_server,
        0xC0702404, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_F_Root_server[] =
      {{"F.ROOT-SERVERS.NET.", DNS_G_Root_server,
        0xC00505F1, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_E_Root_server[] =
      {{"E.ROOT-SERVERS.NET.", DNS_F_Root_server,
        0xC0CBE60A, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_D_Root_server[] =
      {{"D.ROOT-SERVERS.NET.", DNS_E_Root_server,
        0x80080A5A, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_C_Root_server[] =
      {{"C.ROOT-SERVERS.NET.", DNS_D_Root_server,
        0xC021040C, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_B_Root_server[] =
      {{"B.ROOT-SERVERS.NET.", DNS_C_Root_server,
        0xC0E44FC9, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT DNS_A_Root_server[] =
      {{"A.ROOT-SERVERS.NET.", DNS_B_Root_server,
        0xC6290004, 0, 0, 0, 0, 0, DNS_A, DNS_IN }};



/***********************************************************************
 End of Root List Section
***********************************************************************/


/***********************************************************************

 This section is for the Local Servers List.
 This should only be assigned to the DNS config_ptr->LOCAL_SLIST_PTR

***********************************************************************/


char DNS_Local_server_name[] = "ns.arc.com.";


DNS_SLIST_STRUCT DNS_Local_server_list[] =
   {{DNS_Local_server_name, 0, INADDR_LOOPBACK, 0, 0, 0, 0,
     0, DNS_A, DNS_IN }};

DNS_SLIST_STRUCT _PTR_ DNS_First_Local_server = &DNS_Local_server_list[0];


/***********************************************************************
 End of Local List Section
***********************************************************************/


/***********************************************************************

 This section is for the Name Server initial Zone of Authority List.
 This should only be used by the Name Server and only assigned to
 the config_ptr->NS_ZONE_AUTH_LIST;

***********************************************************************/


/***********************************************************************
 End of Zone of Authority List Section
***********************************************************************/

#endif
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/ADC_control.c<|end_filename|>
#include "App.h"



static T_ADC_state adc_state;
static T_ADC_res   adc_res;

signed short   smpls[MEAS_RES_ARR_SZ][TST_SMPLS_ARR_SZ];
unsigned int   arr_pos;


/*-------------------------------------------------------------------------------------------------------------
  Обработчик прерывания PDB (Программируемой задержки синхронизирующей PWM и ADC)
  Принимает результаты ADC
-------------------------------------------------------------------------------------------------------------*/
static void PDB0_isr(pointer user_isr_ptr)
{
  Led_control(LED2, 1);
  PDB0_SC &= ~(BIT(7) + BIT(6));
  PDB0_CH0S = 0;
  PDB0_CH1S = 0;
  PDB0_CH2S = 0;
  PDB0_CH3S = 0;
  PDB0_SC |= BIT(7);

  adc_res.smpl_ii_w    = ADC0_RA;
  adc_res.smpl_v_bus   = ADC0_RB;
  adc_res.smpl_ii_v    = ADC1_RA;
  adc_res.smpl_temper  = ADC1_RB;
  adc_res.smpl_ii_u    = ADC2_RA;
  adc_res.smpl_v_u     = ADC2_RB;
  adc_res.smpl_15v     = ADC3_RA;
  adc_res.smpl_5v      = ADC3_RB;
  
  // Фильтруем токи от постоянной составляющей
  adc_res.ii_w = adc_res.smpl_ii_w - (adc_res.ii_w_offs >> 12);
  adc_res.ii_w_offs += adc_res.ii_w;       

  adc_res.ii_v = adc_res.smpl_ii_v - (adc_res.ii_v_offs >> 12);
  adc_res.ii_v_offs += adc_res.ii_v;       

  adc_res.ii_u = adc_res.smpl_ii_u - (adc_res.ii_u_offs >> 12);
  adc_res.ii_u_offs += adc_res.ii_u;       

  // Фильтруем напряжения с помощью бегущего среднего на 16 отсчетов
  adc_res.v_bus_acc -= adc_res.v_bus_arr[adc_res.aai]; 
  adc_res.v_bus_arr[adc_res.aai] = adc_res.smpl_v_bus;
  adc_res.v_bus_acc += adc_res.v_bus_arr[adc_res.aai];
  adc_res.aai++;
  if ( adc_res.aai >= FILTR_AVER_SZ ) adc_res.aai = 0;
  adc_res.v_bus = adc_res.v_bus_acc/FILTR_AVER_SZ;

 

  // Запись отсчетов в тестовый массив
  if ( arr_pos < TST_SMPLS_ARR_SZ )
  {
/*
    smpls[0][arr_pos] = adc_res.smpl_ii_w   ;
    smpls[1][arr_pos] = adc_res.smpl_v_bus  ;
    smpls[2][arr_pos] = adc_res.smpl_ii_v   ;
    smpls[3][arr_pos] = adc_res.smpl_temper ; 
    smpls[4][arr_pos] = adc_res.smpl_ii_u   ; 
    smpls[5][arr_pos] = adc_res.smpl_v_u    ; 
    smpls[6][arr_pos] = adc_res.smpl_15v    ; 
    smpls[7][arr_pos] = adc_res.smpl_5v     ;
*/ 
    smpls[0][arr_pos] = adc_res.ii_w        ;
    smpls[1][arr_pos] = adc_res.ii_v        ;
    smpls[2][arr_pos] = adc_res.ii_u        ;
    smpls[3][arr_pos] = adc_res.v_bus       ; 
    smpls[4][arr_pos] = adc_res.smpl_temper ; 
    smpls[5][arr_pos] = adc_res.smpl_15v    ; 
    smpls[6][arr_pos] = adc_res.smpl_5v     ; 
    smpls[7][arr_pos] = adc_res.smpl_ii_u   ;

    arr_pos++;
    if ( arr_pos == (TST_SMPLS_ARR_SZ/2) )
    {
      MC_set_events(SMPL_ARR1_FULL);
    }
    else if ( arr_pos == TST_SMPLS_ARR_SZ )
    {
      MC_set_events(SMPL_ARR2_FULL);
      arr_pos = 0;
    }
  }
  Led_control(LED2, 0);
}


/*-------------------------------------------------------------------------------------------------------------
 Включаем тактирование всех ADC
-------------------------------------------------------------------------------------------------------------*/
void ADC_switch_on_all(void)
{
  SIM_SCGC3 |= BIT(28); // Тактирование ADC3
  SIM_SCGC3 |= BIT(27); // Тактирование ADC1
  SIM_SCGC6 |= BIT(28); // Тактирование ADC2
  SIM_SCGC6 |= BIT(27); // Тактирование ADC0
}

/*-------------------------------------------------------------------------------------------------------------
  Первоначальная инициализация ADC 
 
 
  // Самое короткое время преобразования
  // ADLSMP = 0
  // ADICLK = 0
  // 3 ADCK cycles + 5 bus clock cycles

  // 13-и битное дифференциальное
  // 30 ADCK cycles

  // ADLSMP = 0
  // 0 ADCK cycles

  // ADHSC = 0
  // 0 ADCK cycles

  // В сумме: 3 ADCK cycles + 5 bus clock cycles +  30 ADCK cycles + 0 ADCK cycles + 0 ADCK cycles = 33*4 + 5 = 137 тактов шины = 2.28 мкс

-------------------------------------------------------------------------------------------------------------*/
void ADC_init(ADC_MemMapPtr ADC)
{
  // Выбор частоты тактирования, разрядность результата
  // Частота тактирования для 16-и битного результата не должна быть больше 12 МГц, для 13-и битного 18 МГц
  // Устанавливаем 15 МГц
  ADC->CFG1 = 0
              + LSHIFT(0, 7) // ADLPC.  Low power configuration. The power is reduced at the expense of maximum clock speed. 0 Normal power configuration
              + LSHIFT(2, 5) // ADIV.   Clock divide select. 00 The divide ratio is 1 and the clock rate is input clock. 10 The divide ratio is 4 and the clock rate is (input clock)/4.
              + LSHIFT(0, 4) // ADLSMP. Sample time configuration. 0 Short sample time.
              + LSHIFT(1, 2) // MODE.   Conversion mode selection. 01 When DIFF=0: It is single-ended 12-bit conversion; when DIFF=1, it is differential 13-bit conversion with 2's complement output.
              + LSHIFT(0, 0) // ADICLK. Input clock select. 00 Bus clock.
  ;
  // Выбор канала между A и B, установка времени выборки
  ADC->CFG2 = 0
              + LSHIFT(0, 4) // MUXSEL.  0 ADxxa channels are selected.
              + LSHIFT(0, 3) // ADACKEN. Asynchronous clock output enable
              + LSHIFT(0, 2) // ADHSC.   High speed configuration. 0 Normal conversion sequence selected.
              + LSHIFT(0, 0) // ADLSTS.  Long sample time select
  ;

  // Регистр статуса и управления. Выбор типа тригера, управление функцией сравнения, разрешение DMA, выбор типа опоры
  ADC->SC2 = 0
             + LSHIFT(0, 7) // ADACT.   Read only. 1 Conversion in progress.
             + LSHIFT(0, 6) // ADTRG.   Conversion trigger select. 0 Software trigger selected.
             + LSHIFT(0, 5) // ACFE.    Compare function enable. 0 Compare function disabled.
             + LSHIFT(0, 4) // ACFGT.   Compare function greater than enable
             + LSHIFT(0, 3) // ACREN.   Compare function range enable
             + LSHIFT(0, 2) // DMAEN.   DMA enable
             + LSHIFT(0, 0) // REFSEL.  Voltage reference selection. 00 Default voltage reference pin pair (external pins VREFH and VREFL)
  ;
  // Регистр статуса и управления. Управление и статус калибровки, управление усреднением, управление непрерывным преобразованием
  ADC->SC3 = 0
             + LSHIFT(0, 7) // CAL.     CAL begins the calibration sequence when set.
             + LSHIFT(0, 3) // ADCO.    Continuous conversion enable
             + LSHIFT(0, 2) // AVGE.
             + LSHIFT(0, 0) // AVGS.
  ;

  // Регистры значений для функции сравнения
  //ADC->CV1 = 0;
  //ADC->CV2 = 0;

  // Регист корректировки смещения
  //ADC->OFS = 0;

  // Регистры корректировки усиления для положительной и отрицательной сторон дифференциального преобразования в формате с фиксированной точкой 15,14
  // Записываються вручную
  //ADC->PG = 0x8200;
  //ADC->MG = 0x8200;


  ADC->PGA = 0
             + LSHIFT(0, 23) // PGAEN.   1 PGA enabled.
             + LSHIFT(0, 21) // PGACHPb. 1 Chopping disabled.
             + LSHIFT(0, 20) // PGALPb.  1 PGA runs in normal power mode.
             + LSHIFT(0, 16) // PGAG     PGA gain setting. PGA gain = 2^(PGAG)
             + LSHIFT(0, 14) // PGAOFSM  1 PGA runs in offset measurement mode.
  ;


  // Контрольный регистр B
  // Результат управляемый этим регистром будет находиться в регистре ADC->RB
  // Используеться только при включенном аппаратном триггере
  ADC->SC1[1] = 0
                + LSHIFT(0, 7) // COCO. Read only. 1 Conversion completed.
                + LSHIFT(0, 6) // AIEN. 1 Conversion complete interrupt enabled.
                + LSHIFT(1, 5) // DIFF. 1 Differential conversions and input channels are selected.
                + LSHIFT(0, 0) // ADCH. Input channel select. 11111 Module disabled.
                                //                             00000 When DIFF=0, DADP0 is selected as input; when DIFF=1, DAD0 is selected as input.
  ;
  // Контрольный регистр A
  // Результат управляемый этим регистром будет находиться в регистре ADC0_RA
  // Запись в данный регист либо прерывает текущее преобразование либо инициирует новое (если установлен флаг софтварныого тригера - ADTRG = 0)
  ADC->SC1[0] = 0
                + LSHIFT(0, 7) // COCO. Read only. 1 Conversion completed.
                + LSHIFT(0, 6) // AIEN. 1 Conversion complete interrupt enabled.
                + LSHIFT(0, 5) // DIFF. 1 Differential conversions and input channels are selected.
                + LSHIFT(16, 0) // ADCH. Input channel select. 11111 Module disabled.
                               //                             00000 When DIFF=0, DADP0 is selected as input; when DIFF=1, DAD0 is selected as input.
  ;

}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
int ADC_calibrating(ADC_MemMapPtr ADC)
{

  unsigned short tmp;

  ADC->SC1[0] = 0
                + LSHIFT(0, 7) // COCO. Read only. 1 Conversion completed.
                + LSHIFT(0, 6) // AIEN. 1 Conversion complete interrupt enabled.
                + LSHIFT(1, 5) // DIFF. 1 Differential conversions and input channels are selected.
                + LSHIFT(0, 0) // ADCH. Input channel select. 11111 Module disabled.
                               //                             00000 When DIFF=0, DADP0 is selected as input; when DIFF=1, DAD0 is selected as input.
  ;
  // Устанавливаем частоту ADC 3.75 MHz
  ADC->CFG1 = 0
              + LSHIFT(0, 7) // ADLPC.  Low power configuration. The power is reduced at the expense of maximum clock speed. 0 Normal power configuration
              + LSHIFT(3, 5) // ADIV.   Clock divide select. 11 - The divide ratio is 8 and the clock rate is (input clock)/8.
              + LSHIFT(0, 4) // ADLSMP. Sample time configuration. 0 Short sample time.
              + LSHIFT(1, 2) // MODE.   Conversion mode selection. 01 When DIFF=0: It is single-ended 12-bit conversion; when DIFF=1, it is differential 13-bit conversion with 2's complement output.
              + LSHIFT(1, 0) // ADICLK. Input clock select. 00 Bus clock.
  ;
  ADC->CFG2 = 0
              + LSHIFT(0, 4) // MUXSEL.  0 ADxxa channels are selected.
              + LSHIFT(0, 3) // ADACKEN. Asynchronous clock output enable
              + LSHIFT(0, 2) // ADHSC.   High speed configuration. 0 Normal conversion sequence selected.
              + LSHIFT(0, 0) // ADLSTS.  Long sample time select
  ;
  // Регистр статуса и управления. Выбор типа тригера, управление функцией сравнения, разрешение DMA, выбор типа опоры
  ADC->SC2 = 0
             + LSHIFT(0, 7) // ADACT.   Read only. 1 Conversion in progress.
             + LSHIFT(0, 6) // ADTRG.   Conversion trigger select. 0 Software trigger selected.
             + LSHIFT(0, 5) // ACFE.    Compare function enable. 0 Compare function disabled.
             + LSHIFT(0, 4) // ACFGT.   Compare function greater than enable
             + LSHIFT(0, 3) // ACREN.   Compare function range enable
             + LSHIFT(0, 2) // DMAEN.   DMA enable
             + LSHIFT(0, 0) // REFSEL.  Voltage reference selection. 00 Default voltage reference pin pair (external pins VREFH and VREFL)
  ;
  ADC->SC3 = 0
             + LSHIFT(1, 7) // CAL.     CAL begins the calibration sequence when set.
             + LSHIFT(1, 6) // CALF.    Read Only. 1 Calibration failed.
             + LSHIFT(0, 3) // ADCO.    Continuous conversion enable
             + LSHIFT(1, 2) // AVGE.    1 Hardware average function enabled.
             + LSHIFT(3, 0) // AVGS.    11 32 samples averaged.
  ;

  // Ожидать завершения калибровки
  while (ADC->SC3 & BIT(7));

  tmp = (ADC->CLP0 + ADC->CLP1 + ADC->CLP2 + ADC->CLP3 + ADC->CLP4 + ADC->CLPS) / 2;
  ADC->PG = tmp | 0x8000;

  tmp = (ADC->CLM0 + ADC->CLM1 + ADC->CLM2 + ADC->CLM3 + ADC->CLM4 + ADC->CLMS) / 2;
  ADC->MG = tmp | 0x8000;

  if ( ADC->SC3 & BIT(6) )
  {
    return MQX_ERROR;
  }
  else
  {
    return MQX_OK;
  }
}

/*-------------------------------------------------------------------------------------------------------------
  Установить номер канала и признак дифференциальнф-простой для указанного регистра управления у ADC  
-------------------------------------------------------------------------------------------------------------*/
void ADC_set_channel(ADC_MemMapPtr ADC,int ch, int diff, int reg)
{
  reg  = reg & 1;
  diff = diff & 1;
  ch   = ch & 0x1F;

  ADC->SC1[reg] = 0
                + LSHIFT(0, 7)    // COCO. Read only. 1 Conversion completed.
                + LSHIFT(0, 6)    // AIEN. 1 Conversion complete interrupt enabled.
                + LSHIFT(diff, 5) // DIFF. 1 Differential conversions and input channels are selected.
                + LSHIFT(ch, 0)   // ADCH. Input channel select. 11111 Module disabled.
                                  //                             00000 When DIFF=0, DADP0 is selected as input; when DIFF=1, DAD0 is selected as input.
;
}

/*-------------------------------------------------------------------------------------------------------------
  Активировать хардварный триггер 
-------------------------------------------------------------------------------------------------------------*/
void ADC_activate_hrdw_trig(ADC_MemMapPtr ADC)
{
  ADC->SC2 |= BIT(6); // ADTRG.   Conversion trigger select. 0 Software trigger selected.
}

/*-------------------------------------------------------------------------------------------------------------
  Активировать софтварный триггер 
-------------------------------------------------------------------------------------------------------------*/
void ADC_activate_soft_trig(ADC_MemMapPtr ADC)
{
  ADC->SC2 &= ~BIT(6); // ADTRG.   Conversion trigger select. 0 Software trigger selected.
}


/*-------------------------------------------------------------------------------------------------------------
  Конфигурировать триггеры для всех ADC   
 
 
 Синхронизируем так чтобы измерения проводить когда каналы T0C0=0, T0C1=1, T0C2=0, T0C3=1, T0C4=0, T0C5=1
 В это время все нижние ключи открыты 
 У нас T0C0, T0C2, T0C4 принимают значение 0 когда счетчик не дошел до компаратора (FTM0_CxSC.ELSB=1,FTM0_CxSC.ELSA=1)
 Обновление компараторов надо делать в верхней точке, чтобы измерение не приходилось на фронт или спад импульсов 
-------------------------------------------------------------------------------------------------------------*/
void PDB_configure_ADC_triggers(void)
{
  SIM_SCGC6 |= BIT(22); // Разрешаем тактирование PDB
  SIM_SOPT7 = 0;        // Триггерами для всех ADC служит PDB


  // Первый претриггер канала работает без задержки, второй с задержкой на время преобразования ADC
  PDB0_CH0C1 = 0
               + LSHIFT(2, 8) // Установка битов подключения претриггеров к задержкам. 0-й претригер в байпасе, 1-й претрегер после задержки
               + LSHIFT(3, 0) // Установка битов разрешения выходов претриггеров
  ;
  PDB0_CH1C1 = 0
               + LSHIFT(2, 8) // Установка битов подключения претриггеров к задержкам
               + LSHIFT(3, 0) // Установка битов разрешения выходов претриггеров
  ;
  PDB0_CH2C1 = 0
               + LSHIFT(2, 8) // Установка битов подключения претриггеров к задержкам
               + LSHIFT(3, 0) // Установка битов разрешения выходов претриггеров
  ;
  PDB0_CH3C1 = 0
               + LSHIFT(2, 8) // Установка битов подключения претриггеров к задержкам
               + LSHIFT(3, 0) // Установка битов разрешения выходов претриггеров
  ;
  PDB0_CH0DLY1 = 138; // 2.3 мкс в тактах системной шины  
  PDB0_CH1DLY1 = 138; // 2.3 мкс в тактах системной шины  
  PDB0_CH2DLY1 = 138; // 2.3 мкс в тактах системной шины  
  PDB0_CH3DLY1 = 138; // 2.3 мкс в тактах системной шины  

  PDB0_IDLY    = 138 + 138; // Время после которого произойдет прерывание PDB0 и можно будет забрать результаты ADC
/*
  // Первый претриггер канала работает без задержки, второй с задержкой на время преобразования ADC
  PDB0_CH0C1 = 0
               + LSHIFT(3, 8) // Установка битов подключения претриггеров к задержкам. 0-й претригер после задержки, 1-й претрегер после задержки
               + LSHIFT(3, 0) // Установка битов разрешения выходов претриггеров
  ;
  PDB0_CH1C1 = 0
               + LSHIFT(3, 8) // Установка битов подключения претриггеров к задержкам
               + LSHIFT(3, 0) // Установка битов разрешения выходов претриггеров
  ;
  PDB0_CH2C1 = 0
               + LSHIFT(3, 8) // Установка битов подключения претриггеров к задержкам
               + LSHIFT(3, 0) // Установка битов разрешения выходов претриггеров
  ;
  PDB0_CH3C1 = 0
               + LSHIFT(3, 8) // Установка битов подключения претриггеров к задержкам
               + LSHIFT(3, 0) // Установка битов разрешения выходов претриггеров
  ;


  #define DELAYC (1) 
  PDB0_CH0DLY0 = DELAYC;//138; // 2.3 мкс в тактах системной шины  
  PDB0_CH1DLY0 = DELAYC;//138; // 2.3 мкс в тактах системной шины  
  PDB0_CH2DLY0 = DELAYC;//138; // 2.3 мкс в тактах системной шины  
  PDB0_CH3DLY0 = DELAYC;//138; // 2.3 мкс в тактах системной шины  

  PDB0_CH0DLY1 = DELAYC + 143;//138; // 2.3 мкс в тактах системной шины  
  PDB0_CH1DLY1 = DELAYC + 143;//138; // 2.3 мкс в тактах системной шины  
  PDB0_CH2DLY1 = DELAYC + 143;//138; // 2.3 мкс в тактах системной шины  
  PDB0_CH3DLY1 = DELAYC + 143;//138; // 2.3 мкс в тактах системной шины  

  PDB0_IDLY    = DELAYC + 143 + 143; // Время после которого произойдет прерывание PDB0 и можно будет забрать результаты ADC
*/


  _int_install_isr(INT_PDB0, PDB0_isr, 0);
  // Разрешить прерывание только после установки вектора! Иначе можем уйти в непрерывный вызов ISR по дефолтному вектору
  _bsp_int_init(INT_PDB0, PDB0_ISR_PRIO, 0, TRUE);


  PDB0_SC = 0
            + LSHIFT(0,   18) // LDMOD.     00 The internal registers are loaded with the values from their buffers immediately after 1 is written to LDOK.
            + LSHIFT(0,   17) // PDBEIE.    0 PDB sequence error interrupt disabled.
            + LSHIFT(0,   16) // SWTRIG.    Software Trigger
            + LSHIFT(0,   15) // DMAEN.     0 DMA disabled
            + LSHIFT(0,   12) // PRESCALER. 000 Counting uses the peripheral clock divided by multiplication factor selected by MULT.
            + LSHIFT(0x8,  8) // TRGSEL.    1000 FTM0 Init and Ext Trigger Outputs
            + LSHIFT(1,    7) // PDBEN.     1 PDB enabled
            + LSHIFT(0,    6) // PDBIF.     PDB Interrupt Flag
            + LSHIFT(1,    5) // PDBIE.     1 PDB interrupt enabled
            + LSHIFT(0,    2) // MULT.      00 Multiplication factor is 1
            + LSHIFT(0,    1) // CONT.      1 PDB operation in Continuous mode
            + LSHIFT(1,    0) // LDOK.      Writing 1 to this bit updates the internal registers
  ;
}

/*-------------------------------------------------------------------------------------------------------------
  
-------------------------------------------------------------------------------------------------------------*/
void PDB_set_delays(int delay1, int delay2)
{
  PDB0_SC &= ~(BIT(7) + BIT(6));
  PDB0_CH0S = 0;
  PDB0_CH1S = 0;
  PDB0_CH2S = 0;
  PDB0_CH3S = 0;

  PDB0_CH0DLY1 = delay1;  
  PDB0_CH1DLY1 = delay1;  
  PDB0_CH2DLY1 = delay1;  
  PDB0_CH3DLY1 = delay1;  

  PDB0_IDLY    = delay1 + delay2; // Время после которого произойдет прерывание PDB0 и можно будет забрать результаты ADC

  PDB0_SC |= BIT(7) + BIT(0);
}


/*-------------------------------------------------------------------------------------------------------------
  
-------------------------------------------------------------------------------------------------------------*/
void PDB_activate_ADC_triggers(void)
{
  PDB0_SC |= BIT(7);
}
/*-------------------------------------------------------------------------------------------------------------
  
-------------------------------------------------------------------------------------------------------------*/
void PDB_deactivate_ADC_triggers(void)
{
  PDB0_SC &= ~BIT(7);
}
/*-------------------------------------------------------------------------------------------------------------
  
-------------------------------------------------------------------------------------------------------------*/
signed short ADC_get_sample(ADC_MemMapPtr ADC, INT32U channel, INT32U diff, INT32U aver)
{
  if ( aver != 0 )
  {
    ADC->SC3 = 0
               + LSHIFT(0, 7) // CAL.     CAL begins the calibration sequence when set.
               + LSHIFT(0, 6) // CALF.    Read Only. 1 Calibration failed.
               + LSHIFT(0, 3) // ADCO.    Continuous conversion enable
               + LSHIFT(1, 2) // AVGE.    1 Hardware average function enabled.
               + LSHIFT(((aver - 1) & 0x03), 0) // AVGS.    11 32 samples averaged.
    ;
  }
  else
  {
    ADC->SC3 = 0
               + LSHIFT(0, 7) // CAL.     CAL begins the calibration sequence when set.
               + LSHIFT(0, 6) // CALF.    Read Only. 1 Calibration failed.
               + LSHIFT(0, 3) // ADCO.    Continuous conversion enable
               + LSHIFT(0, 2) // AVGE.    1 Hardware average function enabled.
               + LSHIFT(0, 0) // AVGS.    11 32 samples averaged.
    ;
  }
  ADC->SC1[0] = 0
                + LSHIFT(0, 7) // COCO. Read only. 1 Conversion completed.
                + LSHIFT(0, 6) // AIEN. 1 Conversion complete interrupt enabled.
                + LSHIFT((diff    & 0x01), 5) // DIFF. 1 Differential conversions and input channels are selected.
                + LSHIFT((channel & 0x1F), 0) // ADCH. Input channel select. 11111 Module disabled.
  ;

  // Ожидать завершения преобразования
  while ((ADC->SC1[0] & BIT(7)) == 0);

  return ADC->R[0];
}

/*-------------------------------------------------------------------------------------------------------------
  Подготовка всех ADC к работе
-------------------------------------------------------------------------------------------------------------*/
void ADCs_prepare(void)
{
  ADC_switch_on_all();
  adc_state.adc0_cal_res = ADC_calibrating(ADC0_BASE_PTR);
  adc_state.adc1_cal_res = ADC_calibrating(ADC1_BASE_PTR);
  adc_state.adc2_cal_res = ADC_calibrating(ADC2_BASE_PTR);
  adc_state.adc3_cal_res = ADC_calibrating(ADC3_BASE_PTR);
  ADC_init(ADC0_BASE_PTR);
  ADC_init(ADC1_BASE_PTR);
  ADC_init(ADC2_BASE_PTR);
  ADC_init(ADC3_BASE_PTR);

  ADC_set_channel(ADC0_BASE_PTR, SIG_II_W_CHANNEL     ,0,0);
  ADC_set_channel(ADC0_BASE_PTR, SIG_V_BUS_CHANNEL    ,0,1);
                                                      
  ADC_set_channel(ADC1_BASE_PTR, SIG_II_V_CHANNEL     ,0,0);
  ADC_set_channel(ADC1_BASE_PTR, SIG_TEMPER_CHANNEL   ,0,1);
                                                      
  ADC_set_channel(ADC2_BASE_PTR, SIG_II_U_CHANNEL     ,0,0);
  ADC_set_channel(ADC2_BASE_PTR, SIG_V_U_CHANNEL      ,0,1);
                                                      
  ADC_set_channel(ADC3_BASE_PTR, SIG_15V_MEAS_CHANNEL ,0,0);
  ADC_set_channel(ADC3_BASE_PTR, SIG_5V_MEAS_CHANNEL  ,0,1);

  ADC_activate_hrdw_trig(ADC0_BASE_PTR);
  ADC_activate_hrdw_trig(ADC1_BASE_PTR);
  ADC_activate_hrdw_trig(ADC2_BASE_PTR);
  ADC_activate_hrdw_trig(ADC3_BASE_PTR);
  PDB_configure_ADC_triggers();
}


/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
T_ADC_state *ADC_get_state(void)
{
  return &adc_state;
}

/*-------------------------------------------------------------------------------------------------------------
  Получить массив отсчетов  
-------------------------------------------------------------------------------------------------------------*/
void ADC_get_arr_smp(unsigned int indx, signed short *arr)
{
  INT32U i;

  for (i=0;i<MEAS_RES_ARR_SZ;i++)
  {
    arr[i]  = smpls[i][indx]; 
  }
}
/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void ADC_reset_smpl_arr_pos(void)
{
  arr_pos = 0;
}
/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
int ADC_is_smpl_arr_ready(void)
{
  if ( arr_pos == TST_SMPLS_ARR_SZ)
    return 1;
  else
    return 0;
}
/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void ADC_get_smpl_arr(signed short **ptr)
{
  int i;
  for (i=0;i<MEAS_RES_ARR_SZ;i++)
  {
    ptr[i] = &smpls[i][0]; 
  }
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void ADC_print_regs(ADC_MemMapPtr ADC)
{
  printf("SC1A=%04X ", ADC->SC1[0]);
  printf("SC1B=%04X ", ADC->SC1[1]);
  printf("CFG1=%04X ", ADC->CFG1);
  printf("CFG2=%04X ", ADC->CFG2);
  printf(" SC2=%04X ", ADC->SC2);
  printf(" SC3=%04X ", ADC->SC3);
  printf("\r\n");

  printf(" CV1=%04X ", ADC->CV1);
  printf(" CV2=%04X ", ADC->CV2);
  printf(" OFS=%04X ", ADC->OFS);
  printf("  PG=%04X ", ADC->PG);
  printf("  MG=%04X ", ADC->MG);
  printf("\r\n");

  printf("CLPD=%04X ", ADC->CLPD);
  printf("CLPS=%04X ", ADC->CLPS);
  printf("CLP4=%04X ", ADC->CLP4);
  printf("CLP3=%04X ", ADC->CLP3);
  printf("CLP2=%04X ", ADC->CLP2);
  printf("CLP1=%04X ", ADC->CLP1);
  printf("CLP0=%04X ", ADC->CLP0);
  printf("\r\n");

  printf("CLMD=%04X ", ADC->CLMD);
  printf("CLMS=%04X ", ADC->CLMS);
  printf("CLM4=%04X ", ADC->CLM4);
  printf("CLM3=%04X ", ADC->CLM3);
  printf("CLM2=%04X ", ADC->CLM2);
  printf("CLM1=%04X ", ADC->CLM1);
  printf("CLM0=%04X ", ADC->CLM0);
  printf("\r\n");

  printf("PGA =%08X ", ADC->PGA);
  printf("RA  =%08X ", ADC->R[0]);
  printf("RB  =%08X ", ADC->R[1]);
  printf("\r\n");

}


<|start_filename|>Firmware/Inverter_firmware/mcc/source/mqx/mcc_mqx.c<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2013 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************
* $FileName: mcc_mqx.c$
* $Version : 3.8.1.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This file contains MQX-specific MCC library functions
*
*END************************************************************************/

#include "mcc_config.h"
#include "mcc_common.h"
#include "mcc_api.h"
#include "mcc_mqx.h"
#include "mcc_vf600.h"

/* Global variables */
CORE_MUTEX_PTR cm_ptr;
LWEVENT_STRUCT lwevent_buffer_queued[MCC_MQX_LWEVENT_COMPONENTS_COUNT];
LWEVENT_STRUCT lwevent_buffer_freed;

/*!
 * \brief This function is the CPU-to-CPU interrupt handler.
 *
 * Each core can interrupt the other. There are two logical signals:
 * \n - Receive data available for (Node,Port) - signaled when a buffer is queued to a Receive Data Queue.
 * \n - Buffer available - signaled when a buffer is queued to the Free Buffer Queue.
 * \n It is possible that several signals can occur while one interrupt is being processed.
 *  Therefore, a Receive Signal Queue of received signals is also required - one for each core.
 *  The interrupting core queues to the tail and the interrupted core pulls from the head.
 *  For a circular file, no semaphore is required since only the sender modifies the tail and only the receiver modifies the head.
 *
 * \param[in] param Pointer to data being passed to the ISR.
 */
static void mcc_cpu_to_cpu_isr(void *param)
{
    MCC_SIGNAL serviced_signal;

    /* Clear the interrupt flag */
    mcc_clear_cpu_to_cpu_interrupt(MCC_CORE_NUMBER);

    while(MCC_SUCCESS == mcc_dequeue_signal(MCC_CORE_NUMBER, &serviced_signal)) {
        if((serviced_signal.type == BUFFER_QUEUED) &&
           (serviced_signal.destination.core == MCC_CORE_NUMBER)) {
            /* Unblock receiver, in case of asynchronous communication */
            _lwevent_set(&lwevent_buffer_queued[serviced_signal.destination.port / MCC_MQX_LWEVENT_GROUP_SIZE], 1<<(serviced_signal.destination.port % MCC_MQX_LWEVENT_GROUP_SIZE));
        }
        else if(serviced_signal.type == BUFFER_FREED) {
            /* Unblock sender, in case of asynchronous communication */
            _lwevent_set(&lwevent_buffer_freed, 1);
        }
    }
}

/*!
 * \brief This function initializes the hw semaphore (SEMA4).
 *
 * Calls MQX core-mutex driver to create a core mutex.
 *
 * \param[in] sem_num SEMA4 gate number.
 */
int mcc_init_semaphore(unsigned int sem_num)
{
    /* Create a core mutex */
    cm_ptr = _core_mutex_create(0, sem_num, MQX_TASK_QUEUE_FIFO);

    if(NULL == cm_ptr)
        return MCC_ERR_SEMAPHORE;
    else
        return MCC_SUCCESS;
}

/*!
 * \brief This function de-initializes the hw semaphore (SEMA4).
 *
 * Calls MQX core-mutex driver to destroy a core mutex.
 *
 * \param[in] sem_num SEMA4 gate number.
 */
int mcc_deinit_semaphore(unsigned int sem_num)
{
    /* Destroy the core mutex */
    if(COREMUTEX_OK == _core_mutex_destroy(cm_ptr))
        return MCC_SUCCESS;
    else
        return MCC_ERR_SEMAPHORE;
}

/*!
 * \brief This function locks the specified core mutex.
 *
 * Calls MQX core-mutex driver to lock the core mutex.
 *
 */
int mcc_get_semaphore(void)
{
    if(COREMUTEX_OK == _core_mutex_lock(cm_ptr))
        return MCC_SUCCESS;
    else
        return MCC_ERR_SEMAPHORE;
}

/*!
 * \brief This function unlocks the specified core mutex.
 *
 * Calls MQX core-mutex driver to unlock the core mutex.
 *
 */
int mcc_release_semaphore(void)
{
    if(COREMUTEX_OK == _core_mutex_unlock(cm_ptr))
        return MCC_SUCCESS;
    else
        return MCC_ERR_SEMAPHORE;
}

/*!
 * \brief This function registers the CPU-to-CPU interrupt.
 *
 * Calls MQX interrupt component functions to install and enable the CPU-to-CPU interrupt.
 *
 */
int mcc_register_cpu_to_cpu_isr(void)
{
    unsigned int vector_number;

    vector_number = mcc_get_cpu_to_cpu_vector(MCC_CORE_NUMBER);

    if(vector_number != MCC_VECTOR_NUMBER_INVALID) {
        _int_install_isr((_mqx_uint)vector_number, mcc_cpu_to_cpu_isr, NULL);
        mcc_clear_cpu_to_cpu_interrupt(MCC_CORE_NUMBER);
        _bsp_int_init(vector_number, 3, 0, TRUE);
        _bsp_int_enable(vector_number);
        return MCC_SUCCESS;
    }
    else {
        return MCC_ERR_INT;
    }
}

/*!
 * \brief This function triggers an interrupt to other core(s).
 *
 */
int mcc_generate_cpu_to_cpu_interrupt(void)
{
    /* Assert directed CPU interrupts for all processors except the requesting core */
    mcc_triger_cpu_to_cpu_interrupt();

    return MCC_SUCCESS;
}

/*!
 * \brief This function copies data.
 *
 * Copies the number of single-addressable units from the source address to destination address.
 *
 * \param[in] src Source address.
 * \param[in] dest Destination address.
 * \param[in] size Number of single-addressable units to copy.
 */
void mcc_memcpy(void *src, void *dest, unsigned int size)
{
    _mem_copy((pointer)src, (pointer)dest, (_mem_size)size);
}



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ifdns.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifdns.c$
* $Version : 172.16.31.10$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the Domain Name System user interface
*   functions for RTCS.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"

#if RTCSCFG_ENABLE_UDP
#if RTCSCFG_ENABLE_DNS

#include <string.h>
#include "dns.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_gethostbyname()
* Returned Value  : DNS_RESOURCE_RECORD_STRUCT_PTR
* Comments        : Maps a host name to an IP address
*
*END*-----------------------------------------------------------------*/

HOSTENT_STRUCT _PTR_ DNS_gethostbyname
   (
   char _PTR_  name_ptr
   )
{   /* Body */
   HOSTENT_STRUCT _PTR_    host_ptr = NULL;
   DNS_SLIST_STRUCT _PTR_  slist_ptr;
   
   char _PTR_ full_name_ptr;
   /*
   ** First check to see if the information exists in the RTCS_host.c
   ** file.  This check is included for backwards compatibility
   ** with previous versions of RTCS
   */

   host_ptr = DNS_check_local_host_file((uchar _PTR_)name_ptr);

   /* Try to query all DNS servers from the DNS list */
   slist_ptr = DNS_First_Local_server;
   while (( slist_ptr != NULL ) && ( host_ptr == NULL )) {
      host_ptr = DNS_query_resolver_task((uchar _PTR_)name_ptr, DNS_A);
      slist_ptr = slist_ptr->NEXT;
   }

   /*
    * In case this is a fully qualified dotted domain name without the 
    * trailing "." Root domain, append the trailing "." and try again.
    */
   if ( host_ptr == NULL ) {
      /* allocate string + dot + null */    
      full_name_ptr = (char _PTR_)RTCS_mem_alloc(strlen(name_ptr) +1 +1); 
      if (full_name_ptr == NULL){
          return NULL;  
      }          
      strcpy(full_name_ptr, name_ptr);
      strcat(full_name_ptr, ".");
      
      slist_ptr = DNS_First_Local_server;
      while (( slist_ptr != NULL ) && ( host_ptr == NULL )) {
         host_ptr = DNS_query_resolver_task((uchar _PTR_)full_name_ptr, DNS_A);
         slist_ptr = slist_ptr->NEXT;
      }
      
      _mem_free(full_name_ptr);

   }/* Endif */

   return( host_ptr );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_gethostbyaddr()
* Returned Value  : DNS_RESOURCE_RECORD_STRUCT_PTR
* Comments        : Maps a host name to an IP address
*
*END*-----------------------------------------------------------------*/

HOSTENT_STRUCT _PTR_ DNS_gethostbyaddr
   (
   char _PTR_ addr_ptr,
   uint_32    len,
   uint_32    type
   )
{   /* Body */
   HOSTENT_STRUCT _PTR_   host_ptr = NULL;
   DNS_SLIST_STRUCT _PTR_ slist_ptr;

   /*
   ** This is only included to conform to how UNIX handles gethostbyaddr,
   ** internally, RTCS DNS can handle other types.
   */
   if ((type != AF_INET) || (len != sizeof(_ip_address))) {
      return NULL;
   } /* Endif */

   slist_ptr = DNS_First_Local_server;
   while (( slist_ptr != NULL ) && ( host_ptr == NULL )) {
      host_ptr = DNS_query_resolver_task((uchar _PTR_)addr_ptr, DNS_PTR );
      slist_ptr = slist_ptr->NEXT;
   }

   return( host_ptr );

} /* Endbody */


/* Start CR 2257 */
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_find_slist_entry()
* Returned Value  : DNS_SLIST_STRUCT _PTR_
* Comments        : 
*
*END*-----------------------------------------------------------------*/

DNS_SLIST_STRUCT _PTR_ DNS_find_slist_entry
   (
   _ip_address ipaddr
   )
{ /* Body */

   DNS_SLIST_STRUCT _PTR_ temp_ptr;

   if (ipaddr == 0) 
   {
      return( NULL );
   }

   temp_ptr = DNS_First_Local_server;
   while ( temp_ptr != NULL ) 
   {
      if (temp_ptr->IPADDR == ipaddr)
      {
         return(temp_ptr);
      }
      temp_ptr = temp_ptr->NEXT;
   }
   return (NULL);
   
} /* End Body */
 
 
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_init_slist_entry()
* Returned Value  : void
* Comments        : Init slist record to default values
*
*END*-----------------------------------------------------------------*/

void DNS_init_slist_entry
   (
   DNS_SLIST_STRUCT _PTR_   slist_entry_ptr
   )
{ /* Body */

   slist_entry_ptr->NAME_PTR = DNS_Local_server_name;
   slist_entry_ptr->NEXT = NULL;
   slist_entry_ptr->IPADDR = INADDR_LOOPBACK;
   slist_entry_ptr->LAST_TTL_CHECK = 0;
   slist_entry_ptr->TTL = 0;
   slist_entry_ptr->NUMBER_OF_HITS = 0;
   slist_entry_ptr->NUMBER_OF_TRIES = 0;
   slist_entry_ptr->AVG_RESPONSE_TIME = 0;
   slist_entry_ptr->TYPE = DNS_A;
   slist_entry_ptr->CLASS = DNS_IN;
   
} /* Endbody */


/* Flags for second parameter of DNS_insert_slist_entry() */
#define DNS_APPEND_SLIST_ENTRY              0x01
#define DNS_PREPEND_SLIST_ENTRY             0x02

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_insert_slist_entry()
* Returned Value  : uint_32
* Comments        : This is called by the publically visible
*                   DNS_add_slist_entry() and
*                   DNS_append_slist_entry().
*
*END*-----------------------------------------------------------------*/

static uint_32 DNS_insert_slist_entry
   (
   DNS_SLIST_STRUCT _PTR_ usr_slist_entry_ptr,
   uint_32 add_flag
   )

{ /* Body */

   DNS_SLIST_STRUCT _PTR_ new_slist_entry_ptr;
   DNS_SLIST_STRUCT _PTR_ tmp_slist_entry_ptr;

   if (usr_slist_entry_ptr == NULL) 
   {
      return RTCSERR_DNS_INVALID_IP_ADDR;
   }
   
   if (usr_slist_entry_ptr->IPADDR == 0)
   {
      return RTCSERR_DNS_INVALID_IP_ADDR;
   }

   /*
    * If an entry with the same ipaddr already exists, update it
    */
   tmp_slist_entry_ptr = DNS_find_slist_entry(usr_slist_entry_ptr->IPADDR);
   if (tmp_slist_entry_ptr) 
   {
      DNS_SLIST_STRUCT _PTR_ tmp_ptr;
      char * tmp_str = NULL;
   
      if (usr_slist_entry_ptr->NAME_PTR)
      {
         tmp_str = RTCS_mem_alloc(strlen(usr_slist_entry_ptr->NAME_PTR));
         if (tmp_str == NULL)
            return RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY;
         strcpy(tmp_str, usr_slist_entry_ptr->NAME_PTR);
      }
      
      if (tmp_slist_entry_ptr->NAME_PTR)
         _mem_free(tmp_slist_entry_ptr->NAME_PTR);
   
      tmp_ptr = tmp_slist_entry_ptr->NEXT;
      
      memcpy(tmp_slist_entry_ptr, usr_slist_entry_ptr, sizeof(DNS_SLIST_STRUCT));
      
      tmp_slist_entry_ptr->NEXT = tmp_ptr;
      tmp_slist_entry_ptr->NAME_PTR = tmp_str;
      
      return DNS_OK;
   }
   
   new_slist_entry_ptr = RTCS_mem_alloc(sizeof(DNS_SLIST_STRUCT));
   if (new_slist_entry_ptr == NULL) 
   {
      return RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY;
   }
   
   memcpy(new_slist_entry_ptr, usr_slist_entry_ptr, sizeof(DNS_SLIST_STRUCT));
   
   new_slist_entry_ptr->NAME_PTR = RTCS_mem_alloc(strlen(usr_slist_entry_ptr->NAME_PTR) + 1);
   if (new_slist_entry_ptr->NAME_PTR == NULL)
   {
      _mem_free(new_slist_entry_ptr);
      return RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY;
   }
   strcpy(new_slist_entry_ptr->NAME_PTR, usr_slist_entry_ptr->NAME_PTR);
 
   /* If the list is empty, make the new entry the first entry */
   if (DNS_First_Local_server == NULL)
   {
      DNS_First_Local_server = new_slist_entry_ptr;
   }
   else
   {
      /* prepend or append? */
      switch (add_flag)
      {
         default:
         case DNS_PREPEND_SLIST_ENTRY:
            new_slist_entry_ptr->NEXT = DNS_First_Local_server;
            DNS_First_Local_server = new_slist_entry_ptr;
            break;
         case DNS_APPEND_SLIST_ENTRY:
            tmp_slist_entry_ptr = DNS_First_Local_server;
            while (tmp_slist_entry_ptr->NEXT)
            {
               tmp_slist_entry_ptr = tmp_slist_entry_ptr->NEXT;
            }
            tmp_slist_entry_ptr->NEXT = new_slist_entry_ptr;
            break;
      }
   }
   
   return( DNS_OK );

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_append_slist_entry()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

uint_32 DNS_append_slist_entry
   (
   DNS_SLIST_STRUCT _PTR_ usr_slist_entry_ptr
   )
{
   uint_32 ret;
   DNS_CONTROL_STRUCT _PTR_ control_ptr = RTCS_getcfg(DNS);
   
   RTCS_mutex_lock(&control_ptr->SLIST_MUTEX);
   ret = (DNS_insert_slist_entry(usr_slist_entry_ptr, DNS_APPEND_SLIST_ENTRY));
   RTCS_mutex_unlock(&control_ptr->SLIST_MUTEX);

   if (ret == DNS_OK)
   {
      control_ptr->LOCAL_SLIST_PTR = DNS_First_Local_server;
   }

   return ret;
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_add_slist_entry()
* Returned Value  : uint_32
* Comments        :
*
*END*-----------------------------------------------------------------*/

uint_32 DNS_prepend_slist_entry
   (
   DNS_SLIST_STRUCT _PTR_ usr_slist_entry_ptr
   )
{
   uint_32 ret;
   DNS_CONTROL_STRUCT _PTR_ control_ptr = RTCS_getcfg(DNS);
   
   RTCS_mutex_lock(&control_ptr->SLIST_MUTEX);
   ret = (DNS_insert_slist_entry(usr_slist_entry_ptr, DNS_PREPEND_SLIST_ENTRY));
   RTCS_mutex_unlock(&control_ptr->SLIST_MUTEX);
   
   if (ret == DNS_OK)
   {
      control_ptr->LOCAL_SLIST_PTR = DNS_First_Local_server;
   }
   
   return ret;
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNS_remove_slist_entry()
* Returned Value  : uint_32
* Comments        : Remove slist record from list
*
*END*-----------------------------------------------------------------*/

uint_32 DNS_remove_slist_entry
   (
   _ip_address ipaddr
   )

{ /* Body */

   DNS_SLIST_STRUCT _PTR_ prev_ptr = NULL;
   DNS_SLIST_STRUCT _PTR_ temp_ptr = NULL;
   DNS_CONTROL_STRUCT _PTR_ control_ptr = RTCS_getcfg(DNS);

   /* 
   ** If ipaddr is 0, return error
   */
   if (ipaddr == 0) 
   {
      return( RTCSERR_DNS_INVALID_IP_ADDR );
   }

   temp_ptr = DNS_First_Local_server;

   /*
   ** find entry in list
   */
   while ( temp_ptr != NULL ) 
   {
      if (temp_ptr->IPADDR == ipaddr) 
      {
         /*
         ** Is it the first added entry?
         */
         if (prev_ptr == NULL) 
         {
            DNS_First_Local_server = temp_ptr->NEXT;
            control_ptr->LOCAL_SLIST_PTR = DNS_First_Local_server;
         }
         else 
         {
            prev_ptr->NEXT = temp_ptr->NEXT;
         }
         _mem_free(temp_ptr->NAME_PTR);
         _mem_free(temp_ptr);
         break;
      }
      prev_ptr = temp_ptr;
      temp_ptr = temp_ptr->NEXT;
   }

   /*
    * Never leave the list empty
    */
   if (DNS_First_Local_server == NULL)
   {
      DNS_SLIST_STRUCT tmp_slist_entry;
      DNS_init_slist_entry(&tmp_slist_entry);
      return( DNS_add_slist_entry(&tmp_slist_entry));
   }
   
   return( DNS_OK );

} /* Endbody */

/* Cleanup local defines */
#undef DNS_APPEND_SLIST_ENTRY
#undef DNS_PREPEND_SLIST_ENTRY
/* End CR 2257 */

#endif
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/UART0.h<|end_filename|>
/* ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : UART0.h
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : Init_UART
**     Version     : Component 01.004, Driver 01.04, CPU db: 3.00.000
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-09, 15:03, # CodeGen: 12
**     Abstract    :
**          This file implements the UART (UART0) module initialization
**          according to the Peripheral Initialization settings, and
**          defines interrupt service routines prototypes.
**     Settings    :
**          Component name                                 : UART0
**          Device                                         : UART0
**          Settings                                       : 
**            Clock gate                                   : Enabled
**            Clock settings                               : 
**              Baud rate divisor                          : 65
**              Baud rate fine adjust                      : 3
**              Baud rate                                  : 115218.435 baud
**            Transfer settings                            : 
**              Data format                                : 8bit
**              Bits ordering                              : LSB first
**              Parity                                     : Off
**              Parity placement                           : Parity in last data bit
**            Idle character counting                      : After start bit
**            Break character generation length            : Short
**            LIN Break detection                          : Disabled
**            Stop in Wait mode                            : Disabled
**            Receiver wakeup settings                     : 
**              Receiver wakeup                            : Normal operation
**              Receiver wake up method                    : Idle-line
**              Receive wakeup idle detect                 : Don't set IDLE bit
**              Match address settings                     : 
**                Match address 1                          : Disabled
**                Match address 1 value                    : 0
**                Match address 2                          : Disabled
**                Match address 2 value                    : 0
**            Modem settings                               : 
**              Tx CTS                                     : Disabled
**              Tx RTS                                     : Disabled
**              Tx RTS polarity                            : Active low
**              Rx RTS                                     : Disabled
**            Infrared settings                            : 
**              Infrared                                   : Disabled
**              Tx narrow pulse width                      : 3/16
**            FIFOs settings                               : 
**              Tx FIFO                                    : Enabled
**              Tx watermark                               : 32
**              Rx FIFO                                    : Enabled
**              Rx watermark                               : 32
**            Smartcards interface (ISO7816) settings      : 
**              ISO7816 functionality                      : Disabled
**              Transfer type                              : T=0
**                Rx error action                          : Error NACK not generated
**                Rx FIFO overflow action                  : Overflow NACK not generated
**                Rx NACK threshold                        : 0
**                Tx NACK threshold                        : 0
**                Wait time value                          : 10
**              Init char detection                        : Disabled
**              Guard band N                               : 0
**              FD multiplier                              : 1
**            CEA709.1-B interface settings                : 
**              CEA709 functionality                       : Disabled
**              Collision detection                        : Disabled
**              Transmitter                                : Disabled
**              Collision signal polarity                  : Low
**              Packet time counter                        : 0
**              Beta 1 timer                               : 0
**              Secondary delay timer                      : 0
**              Preamble                                   : 0
**              WBase                                      : 0
**              Collision pulse width                      : 0
**              Receive indeterminate time                 : 0
**              Transmit indeterminate time                : 0
**            Loops and Single wire settings               : 
**              Loop mode                                  : Disabled
**              Receiver source in Loop mode               : Loop mode
**              TxD pin direction in Single-wire mode      : Input
**            Receiver input                               : Not inverted
**            Transmitter output                           : Not inverted
**          Pins/Signals                                   : 
**            Receiver pin                                 : Enabled
**              Pin                                        : TSI0_CH9/PTB16/SPI1_SOUT/UART0_RX/I2S1_TXD0/FBa_AD17/EWM_IN
**              Pin signal                                 : 
**            Transmitter pin                              : Enabled
**              Pin                                        : TSI0_CH10/PTB17/SPI1_SIN/UART0_TX/I2S1_TXD1/FBa_AD16/EWM_OUT_b
**              Pin signal                                 : 
**              Transmitter modulation                     : Disabled
**            CTS pin                                      : Disabled
**            RTS pin                                      : Disabled
**          Interrupts/DMA                                 : 
**            Common Tx/Rx interrupt                       : 
**              Interrupt                                  : INT_UART0_RX_TX
**              Interrupt request                          : Disabled
**              Interrupt priority                         : 0 (Highest)
**              ISR name                                   : 
**              Transmit empty request                     : Disabled
**              Transmit empty request type                : IRQ
**              Transmit complete request                  : Disabled
**              Receiver full request                      : Disabled
**              Receiver full request type                 : IRQ
**              Idle line request                          : Disabled
**              LIN break detect request                   : Disabled
**              Rx active edge interrupt                   : Disabled
**              Smartcards interface (ISO7816) interrupts  : 
**                Init char detected interrupt             : Disabled
**            Error Interrupt                              : 
**              Error interrupt                            : INT_UART0_ERR
**              Interrupt request                          : Disabled
**              Interrupt priority                         : 0 (Highest)
**              ISR name                                   : 
**              Overrun error interrupt                    : Disabled
**              Noise error interrupt                      : Disabled
**              Framing error interrupt                    : Disabled
**              Parity error interrupt                     : Disabled
**              FIFOs interrupts                           : 
**                Tx FIFO overflow interrupt               : Disabled
**                Rx FIFO underflow interrupt              : Disabled
**              Smartcards interface (ISO7816) interrupts  : 
**                Wait timer interrupt                     : Disabled
**                Char wait timer interrupt                : Disabled
**                Block wait timer interrupt               : Disabled
**                Tx threshold exceeded interrupt          : Disabled
**                Rx threshold exceeded                    : Disabled
**                Guard timer violated interrupt           : Disabled
**            CEA709 Interrupt                             : 
**              CEA709 interrupt                           : INT_UART0_LON
**              Interrupt request                          : Disabled
**              Interrupt priority                         : 0 (Highest)
**              ISR name                                   : 
**              Wbase expired interrupt                    : Disabled
**              Initial sync detection interrupt           : Disabled
**              Packet received interrupt                  : Disabled
**              Packet transmitted interrupt               : Disabled
**              Packet cycle timer interrupt               : Disabled
**              Preamble start interrupt                   : Disabled
**              Transmission fail interrupt                : Disabled
**          Initialization                                 : 
**            Send break                                   : Disabled
**            Enable transmitter                           : Enabled
**            Enable receiver                              : Enabled
**            Call Init method                             : yes
**     Contents    :
**         Init - void UART0_Init(void);
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file UART0.h
** @version 01.04
** @brief
**          This file implements the UART (UART0) module initialization
**          according to the Peripheral Initialization settings, and
**          defines interrupt service routines prototypes.
*/         
/*!
**  @addtogroup UART0_module UART0 module documentation
**  @{
*/         

#ifndef UART0_H_
#define UART0_H_

/* MODULE UART0. */

/* Including shared modules, which are used in the whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
#include "Cpu.h"

/* Peripheral base address parameter */
#define UART0_DEVICE UART0_BASE_PTR


/*
** ===================================================================
**     Method      :  UART0_Init (component Init_UART)
**     Description :
**         This method initializes registers of the UART module
**         according to the Peripheral Initialization settings.
**         Call this method in user code to initialize the module. By
**         default, the method is called by PE automatically; see "Call
**         Init method" property of the component for more details.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void UART0_Init(void);


/* END UART0. */
#endif /* #ifndef __UART0_H_ */
/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/FMC_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type FMC
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(FMC_PDD_H_)
#define FMC_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error FMC PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* FMC */ && \
      !defined(MCU_MK10D5) /* FMC */ && \
      !defined(MCU_MK10D7) /* FMC */ && \
      !defined(MCU_MK10F12) /* FMC */ && \
      !defined(MCU_MK10DZ10) /* FMC */ && \
      !defined(MCU_MK11D5) /* FMC */ && \
      !defined(MCU_MK11D5WS) /* FMC */ && \
      !defined(MCU_MK12D5) /* FMC */ && \
      !defined(MCU_MK20D10) /* FMC */ && \
      !defined(MCU_MK20D5) /* FMC */ && \
      !defined(MCU_MK20D7) /* FMC */ && \
      !defined(MCU_MK20F12) /* FMC */ && \
      !defined(MCU_MK20DZ10) /* FMC */ && \
      !defined(MCU_MK21D5) /* FMC */ && \
      !defined(MCU_MK21D5WS) /* FMC */ && \
      !defined(MCU_MK22D5) /* FMC */ && \
      !defined(MCU_MK30D10) /* FMC */ && \
      !defined(MCU_MK30D7) /* FMC */ && \
      !defined(MCU_MK30DZ10) /* FMC */ && \
      !defined(MCU_MK40D10) /* FMC */ && \
      !defined(MCU_MK40D7) /* FMC */ && \
      !defined(MCU_MK40DZ10) /* FMC */ && \
      !defined(MCU_MK40X256VMD100) /* FMC */ && \
      !defined(MCU_MK50D10) /* FMC */ && \
      !defined(MCU_MK50D7) /* FMC */ && \
      !defined(MCU_MK50DZ10) /* FMC */ && \
      !defined(MCU_MK51D10) /* FMC */ && \
      !defined(MCU_MK51D7) /* FMC */ && \
      !defined(MCU_MK51DZ10) /* FMC */ && \
      !defined(MCU_MK52D10) /* FMC */ && \
      !defined(MCU_MK52DZ10) /* FMC */ && \
      !defined(MCU_MK53D10) /* FMC */ && \
      !defined(MCU_MK53DZ10) /* FMC */ && \
      !defined(MCU_MK60D10) /* FMC */ && \
      !defined(MCU_MK60F12) /* FMC */ && \
      !defined(MCU_MK60F15) /* FMC */ && \
      !defined(MCU_MK60DZ10) /* FMC */ && \
      !defined(MCU_MK60N512VMD100) /* FMC */ && \
      !defined(MCU_MK61F12) /* FMC */ && \
      !defined(MCU_MK61F15) /* FMC */ && \
      !defined(MCU_MK61F12WS) /* FMC */ && \
      !defined(MCU_MK61F15WS) /* FMC */ && \
      !defined(MCU_MK70F12) /* FMC */ && \
      !defined(MCU_MK70F15) /* FMC */ && \
      !defined(MCU_MK70F12WS) /* FMC */ && \
      !defined(MCU_MK70F15WS) /* FMC */ && \
      !defined(MCU_PCK20L4) /* FMC */
  // Unsupported MCU is active
  #error FMC PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   -- InvalidateFlashCache
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MK10F12)) || (defined(MCU_MK20F12)) || (defined(MCU_MK60F12)) || (defined(MCU_MK60F15)) || (defined(MCU_MK61F12)) || (defined(MCU_MK61F12WS)) || (defined(MCU_MK61F15)) || (defined(MCU_MK61F15WS)) || (defined(MCU_MK70F12)) || (defined(MCU_MK70F12WS)) || (defined(MCU_MK70F15)) || (defined(MCU_MK70F15WS)))
/**
 * @brief Invalidates flash cache.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FMC_PFB0CR, FMC_PFB01CR
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      FMC_PDD_InvalidateFlashCache(deviceID);
 *      @endcode
 */
  #define FMC_PDD_InvalidateFlashCache(PeripheralBase) ( \
      FMC_PFB01CR_REG(PeripheralBase) |= \
       (uint32_t)(FMC_PFB01CR_CINV_WAY_MASK | FMC_PFB01CR_S_B_INV_MASK) \
    )
#else /* (defined(MCU_MK10D10)) || (defined(MCU_MK10D5)) || (defined(MCU_MK10D7)) || (defined(MCU_MK10DZ10)) || (defined(MCU_MK11D5)) || (defined(MCU_MK11D5WS)) || (defined(MCU_MK12D5)) || (defined(MCU_MK20D10)) || (defined(MCU_MK20D5)) || (defined(MCU_MK20D7)) || (defined(MCU_MK20DZ10)) || (defined(MCU_MK21D5)) || (defined(MCU_MK21D5WS)) || (defined(MCU_MK22D5)) || (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK50D10)) || (defined(MCU_MK50D7)) || (defined(MCU_MK50DZ10)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK52D10)) || (defined(MCU_MK52DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) || (defined(MCU_MK60D10)) || (defined(MCU_MK60DZ10)) || (defined(MCU_MK60N512VMD100)) || (defined(MCU_PCK20L4)) */
/**
 * @brief Invalidates flash cache.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FMC_PFB0CR, FMC_PFB01CR
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      FMC_PDD_InvalidateFlashCache(deviceID);
 *      @endcode
 */
  #define FMC_PDD_InvalidateFlashCache(PeripheralBase) ( \
      FMC_PFB0CR_REG(PeripheralBase) |= \
       (uint32_t)(FMC_PFB0CR_CINV_WAY_MASK | FMC_PFB0CR_S_B_INV_MASK) \
    )
#endif /* (defined(MCU_MK10D10)) || (defined(MCU_MK10D5)) || (defined(MCU_MK10D7)) || (defined(MCU_MK10DZ10)) || (defined(MCU_MK11D5)) || (defined(MCU_MK11D5WS)) || (defined(MCU_MK12D5)) || (defined(MCU_MK20D10)) || (defined(MCU_MK20D5)) || (defined(MCU_MK20D7)) || (defined(MCU_MK20DZ10)) || (defined(MCU_MK21D5)) || (defined(MCU_MK21D5WS)) || (defined(MCU_MK22D5)) || (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK50D10)) || (defined(MCU_MK50D7)) || (defined(MCU_MK50DZ10)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK52D10)) || (defined(MCU_MK52DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) || (defined(MCU_MK60D10)) || (defined(MCU_MK60DZ10)) || (defined(MCU_MK60N512VMD100)) || (defined(MCU_PCK20L4)) */
#endif  /* #if defined(FMC_PDD_H_) */

/* FMC_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/arpif.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: arpif.h$
* $Version : 3.0.6.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   
*
*END************************************************************************/

#ifndef __arpif_h__
#define __arpif_h__

/* ARPIF_*() */
typedef struct arpif_parm {
   TCPIP_PARM           COMMON;
   _rtcs_if_handle      ihandle;
   _ip_address          PADDR;
   char        LADDR[6];
} ARPIF_PARM, _PTR_ ARPIF_PARM_PTR;

extern void ARPIF_delete
   (
      ARPIF_PARM_PTR  parms
   );
extern void ARPIF_add
   (
      ARPIF_PARM_PTR  parms
   );
extern void ARP_display_if_table(_rtcs_if_handle   ihandle);

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_adc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_adc.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the settings for ADC1 converter
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

/*
** parameters of PDB initialization
*/
const KPDB_INIT_STRUCT _bsp_pdb_init = {
    /* PDB interrupt vector */
    INT_PDB0,
    /* PDB interrupt vector */
    BSP_PDB_VECTOR_PRIORITY,
     /* PDB interrupt vector */
};

/*
** parameters of ADC initialization
*/

const KADC_INIT_STRUCT _bsp_adc0_init = {
    /* The number of ADC peripheral, use adc_t enum from PSP */
    0,
    /* The clock source, selects the best from BUSCLK and BUSCLK/2 */
    ADC_CLK_BUSCLK_ANY,
    /* The clock divisor for ADC. use the fastest one */
    ADC_DIV_ANY,
    /* ADC high speed control, see ADC_HSC enum */
    ADC_HSC_NORMAL,
    /* ADC low power control, see ADC_LPC enum */
    ADC_LPC_NORMAL,
    /* The calibration data pointer */
    NULL,
    /* ADC interrupt vector */
    INT_ADC0,
    /* ADC interrupt vector */
    BSP_ADC0_VECTOR_PRIORITY,
    /* PDB init structure */
    &_bsp_pdb_init
};

/*
** parameters of ADC initialization
*/
const KADC_INIT_STRUCT _bsp_adc1_init = {
    /* The number of ADC peripheral, use adc_t enum from PSP */
    1,
    /* The clock source, selects the best from BUSCLK and BUSCLK/2 */
    ADC_CLK_BUSCLK_ANY,
    /* The clock divisor for ADC. use the fastest one */
    ADC_DIV_ANY,
    /* ADC high speed control, see ADC_HSC enum */
    ADC_HSC_NORMAL,
    /* ADC low power control, see ADC_LPC enum */
    ADC_LPC_NORMAL,
    /* The calibration data pointer */
    NULL,
    /* ADC interrupt vector */
    INT_ADC1,
    /* ADC interrupt vector */
    BSP_ADC1_VECTOR_PRIORITY,
    /* PDB init structure */
    &_bsp_pdb_init
};

const KADC_INIT_STRUCT _bsp_adc2_init = {
    /* The number of ADC peripheral, use adc_t enum from PSP */
    2,
    /* The clock source, selects the best from BUSCLK and BUSCLK/2 */
    ADC_CLK_BUSCLK_ANY,
    /* The clock divisor for ADC. use the fastest one */
    ADC_DIV_ANY,
    /* ADC high speed control, see ADC_HSC enum */
    ADC_HSC_NORMAL,
    /* ADC low power control, see ADC_LPC enum */
    ADC_LPC_NORMAL,
    /* The calibration data pointer */
    NULL,
    /* ADC interrupt vector */
    INT_ADC2,
    /* ADC interrupt vector */
    BSP_ADC2_VECTOR_PRIORITY,
    /* PDB init structure */
    &_bsp_pdb_init
};

const KADC_INIT_STRUCT _bsp_adc3_init = {
    /* The number of ADC peripheral, use adc_t enum from PSP */
    3,
    /* The clock source, selects the best from BUSCLK and BUSCLK/2 */
    ADC_CLK_BUSCLK_ANY,
    /* The clock divisor for ADC. use the fastest one */
    ADC_DIV_ANY,
    /* ADC high speed control, see ADC_HSC enum */
    ADC_HSC_NORMAL,
    /* ADC low power control, see ADC_LPC enum */
    ADC_LPC_NORMAL,
    /* The calibration data pointer */
    NULL,
    /* ADC interrupt vector */
    INT_ADC3,
    /* ADC interrupt vector */
    BSP_ADC3_VECTOR_PRIORITY,
    /* PDB init structure */
    &_bsp_pdb_init
};

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/checksum.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: checksum.c$
* $Version : 3.8.7.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation for a one's
*   complement checksum.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IP_Sum_immediate
* Returned Value  : one's complement checksum
* Comments        :
*     Returns a one's complement checksum of two numbers.
*
*     Note:  This function returns 0 iff both summands are 0.
*
*END*-----------------------------------------------------------------*/

uint_16 IP_Sum_immediate
   (
      uint_16        sum,
         /* [IN] initial sum */
      uint_16        immediate
         /* [IN] number to add to sum */
   )
{ /* Body */
   uint_32 total = sum & 0xFFFF;

   total += immediate & 0xFFFF;

   sum = (total >> 16) & 0xFFFF;
   total = (total & 0xFFFF) + sum;
   return total;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IP_Sum_PCB
* Returned Value  : one's complement checksum
* Comments        :
*     Returns a one's complement checksum over all fragments in a PCB.
*
*     Note:  This function returns 0 iff all summands are 0.
*
*END*-----------------------------------------------------------------*/

uint_16 IP_Sum_PCB
   (
      uint_16        sum,
         /* [IN] initial sum */
      RTCSPCB_PTR    pcb
         /* [IN] the PCB */
   )
{ /* Body */
   PCB_FRAGMENT_PTR  frag = &pcb->PCBPTR->FRAG[1];
   uint_32           is_odd = pcb->HEADER_FRAG_USED & 1;

   sum = _mem_sum_ip(sum, pcb->HEADER_FRAG_USED, RTCSPCB_DATA(pcb));

   while (frag->LENGTH) {
      if (is_odd) {
         /* If previous fragment was odd, add in first byte in lower 8 bits */
         sum = IP_Sum_immediate(sum, frag->FRAGMENT[0] & 0xFF);
      } /* Endif */

      sum = _mem_sum_ip(sum, frag->LENGTH - is_odd, frag->FRAGMENT + is_odd);
      is_odd = (frag->LENGTH - is_odd) & 1;
      frag++;
   } /* Endwhile */

   return sum;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IP_Sum_pseudo
* Returned Value  : one's complement checksum
* Comments        :
*     Returns a one's complement checksum of the IP pseudo header
*
*     Note:  This function returns 0 iff all summands are 0.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_16 IP_Sum_pseudo
   (
      uint_16        sum,
         /* [IN] initial sum */
      RTCSPCB_PTR    pcb,
         /* [IN] the PCB */
      int_32         layer
         /* [IN] IP layer, relative to current */
   )
{ /* Body */
   IP_HEADER_PTR iphead = (IP_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb);
   uint_16 protocol;

   protocol = RTCSPCB_TRANSPORT_PROTL(pcb);
   sum = _mem_sum_ip(sum, 8, iphead->SOURCE);     /* source and dest */
   sum = IP_Sum_immediate(sum, protocol);    /* protocol */
   return sum;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_ftfl.c<|end_filename|>
/**HEADER*********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* $FileName: flash_ftfl.c$
* $Version : 3.8.25.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions for internal flash read, write, erase
*
*END*************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"
#include "flashx.h"
#include "flashxprv.h"
#include "flash_ftfl_prv.h"
#include "flash_ftfl.h"

/* local function prototypes */
static void     ftfl_ram_function(volatile uint_8 *);
static void     ftfl_ram_function_end(void);
static char_ptr ftfl_init_ram_function(void);
static _mqx_int ftfl_deinit_ram_function(char_ptr);
static uint_32  ftfl_flash_command_sequence(FTFL_FLASH_INTERNAL_STRUCT_PTR, uint_8_ptr, uint_8, boolean);

static boolean  flexnvm_read_resource(IO_FLASHX_STRUCT_PTR, FLEXNVM_READ_RSRC_STRUCT_PTR);
static boolean  flexnvm_prog_part(IO_FLASHX_STRUCT_PTR, FLEXNVM_PROG_PART_STRUCT_PTR);
static boolean  flexnvm_set_flexram(IO_FLASHX_STRUCT_PTR, uchar);


const FLASHX_BLOCK_INFO_STRUCT _flashx_kinetisN_block_map[] = {
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE / 2,(_mem_size) BSP_INTERNAL_FLASH_BASE                              , BSP_INTERNAL_FLASH_SECTOR_SIZE, 0 },
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE / 2,(_mem_size) BSP_INTERNAL_FLASH_BASE + BSP_INTERNAL_FLASH_SIZE / 2, BSP_INTERNAL_FLASH_SECTOR_SIZE, 0 },
    { 0, 0, 0 }
};

#ifdef BSP_INTERNAL_FLEXRAM_BASE
const FLASHX_BLOCK_INFO_STRUCT _flashx_kinetisX_block_map[] = {
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE,(_mem_size) BSP_INTERNAL_FLASH_BASE, BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { 1, (_mem_size) BSP_INTERNAL_FLEXRAM_BASE, BSP_INTERNAL_FLEXRAM_SIZE },
    { 0, 0, 0 }
};

const FLASHX_BLOCK_INFO_STRUCT _flashx_mcf51xx_plus_block_map[] =  {
    { BSP_INTERNAL_FLASH_SIZE / BSP_INTERNAL_FLASH_SECTOR_SIZE,(_mem_size) BSP_INTERNAL_FLASH_BASE, BSP_INTERNAL_FLASH_SECTOR_SIZE },
    { 1, (_mem_size) BSP_INTERNAL_FLEXRAM_BASE, BSP_INTERNAL_FLEXRAM_SIZE },
    { 0, 0, 0 }
};
#endif

const FLASHX_DEVICE_IF_STRUCT _flashx_ftfl_if = {
    ftfl_flash_erase_sector,
    ftfl_flash_write_sector,
    NULL,
    NULL,
    ftfl_flash_init,
    ftfl_flash_deinit,
    NULL,
    flexnvm_flash_ioctl
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfl_flash_command_sequence
* Returned Value   : uint_32 an error code
* Comments         :
*    Run command in FTFL device.
*
*END*-----------------------------------------------------------------------*/
static uint_32 ftfl_flash_command_sequence
(
    /* [IN] Flash specific structure */
    FTFL_FLASH_INTERNAL_STRUCT_PTR     dev_spec_ptr,

    /* [IN] Command byte array */
    uint_8_ptr                         command_array,

    /* [IN] Number of values in the array */
    uint_8                             count,

    /* [IN] Read the result back? */
    boolean                            read

)
{
    uint_8  fstat;
    uint_32 result, temp;
    void (* RunInRAM)(volatile uint_8 *);
    FTFL_MemMapPtr ftfl_ptr;
    uint_8 cnt;

    ftfl_ptr = (FTFL_MemMapPtr)dev_spec_ptr->ftfl_ptr;

    /* get pointer to RunInRAM function */
    RunInRAM = (void(*)(volatile uint_8 *))(dev_spec_ptr->flash_execute_code_ptr);

    /* set the default return as FTFL_OK */
    result = FTFL_OK;

    /* check CCIF bit of the flash status register */
    while (0 == (ftfl_ptr->FSTAT & FTFL_FSTAT_CCIF_MASK))
    { /* void */ }

    /* clear RDCOLERR & ACCERR & FPVIOL error flags in flash status register */
    if (ftfl_ptr->FSTAT & FTFL_FSTAT_RDCOLERR_MASK)
    {
        ftfl_ptr->FSTAT |= FTFL_FSTAT_RDCOLERR_MASK;
    }
    if (ftfl_ptr->FSTAT & FTFL_FSTAT_ACCERR_MASK)
    {
        ftfl_ptr->FSTAT |= FTFL_FSTAT_ACCERR_MASK;
    }
    if (ftfl_ptr->FSTAT & FTFL_FSTAT_FPVIOL_MASK)
    {
        ftfl_ptr->FSTAT |= FTFL_FSTAT_FPVIOL_MASK;
    }

    cnt = count;
    switch (cnt)
    {

        case 12: ftfl_ptr->FCCOBB = command_array[--cnt];
        case 11: ftfl_ptr->FCCOBA = command_array[--cnt];
        case 10: ftfl_ptr->FCCOB9 = command_array[--cnt];
        case  9: ftfl_ptr->FCCOB8 = command_array[--cnt];
        case  8: ftfl_ptr->FCCOB7 = command_array[--cnt];
        case  7: ftfl_ptr->FCCOB6 = command_array[--cnt];
        case  6: ftfl_ptr->FCCOB5 = command_array[--cnt];
        case  5: ftfl_ptr->FCCOB4 = command_array[--cnt];
        case  4: ftfl_ptr->FCCOB3 = command_array[--cnt];
        case  3: ftfl_ptr->FCCOB2 = command_array[--cnt];
        case  2: ftfl_ptr->FCCOB1 = command_array[--cnt];
        case  1: ftfl_ptr->FCCOB0 = command_array[--cnt];
        default: break;
    }

#if PSP_MQX_CPU_IS_COLDFIRE
    temp = _psp_get_sr();
    _psp_set_sr(temp | 0x0700);
#elif PSP_MQX_CPU_IS_KINETIS
    __disable_interrupt ();
#endif /* PSP_MQX_CPU_IS_KINETIS */

    /* run command and wait for it to finish (must execute from RAM) */
    RunInRAM(&ftfl_ptr->FSTAT);

#if PSP_MQX_CPU_IS_COLDFIRE
    _psp_set_sr(temp);
#elif PSP_MQX_CPU_IS_KINETIS
    __enable_interrupt ();
#endif /* PSP_MQX_CPU_IS_KINETIS */

    cnt = count;
    if (read) {
        switch (cnt)
        {
            case 12: command_array[--cnt] = ftfl_ptr->FCCOBB;
            case 11: command_array[--cnt] = ftfl_ptr->FCCOBA;
            case 10: command_array[--cnt] = ftfl_ptr->FCCOB9;
            case  9: command_array[--cnt] = ftfl_ptr->FCCOB8;
            case  8: command_array[--cnt] = ftfl_ptr->FCCOB7;
            case  7: command_array[--cnt] = ftfl_ptr->FCCOB6;
            case  6: command_array[--cnt] = ftfl_ptr->FCCOB5;
            case  5: command_array[--cnt] = ftfl_ptr->FCCOB4;
            case  4: command_array[--cnt] = ftfl_ptr->FCCOB3;
            case  3: command_array[--cnt] = ftfl_ptr->FCCOB2;
            case  2: command_array[--cnt] = ftfl_ptr->FCCOB1;
            case  1: command_array[--cnt] = ftfl_ptr->FCCOB0;
            default: break;
        }
    }
    /* get flash status register value */
    fstat = ftfl_ptr->FSTAT;

#if PSP_MQX_CPU_IS_KINETIS
    /* invalidate flash cache to expose flash changes */
    kinetis_flash_invalidate_cache(FLASHX_INVALIDATE_CACHE_ALL);
#endif

    /* checking access error */
    if (0 != (fstat & FTFL_FSTAT_ACCERR_MASK))
    {
        /* return an error code FTFL_ERR_ACCERR */
        result = FTFL_ERR_ACCERR;
    }
    /* checking protection error */
    else if (0 != (fstat & FTFL_FSTAT_FPVIOL_MASK))
    {
        /* return an error code FTFL_ERR_PVIOL */
        result = FTFL_ERR_PVIOL;
    }
    /* checking MGSTAT0 non-correctable error */
    else if (0 != (fstat & FTFL_FSTAT_MGSTAT0_MASK))
    {
        /* return an error code FTFL_ERR_MGSTAT0 */
        result = FTFL_ERR_MGSTAT0;
    }

    return result;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfl_flash_init
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Initialize flash specific information.
*
*END*-----------------------------------------------------------------------*/
boolean ftfl_flash_init
(
    /* [IN] Device instance */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    FTFL_FLASH_INTERNAL_STRUCT_PTR    dev_spec_ptr;
    FTFL_MemMapPtr                    ftfl_ptr;

    if (_bsp_ftfx_io_init(0)) {
        /* Cannot initialize FTF module */
        return FALSE;
    }

    /* allocate internal structure */
    dev_spec_ptr = _mem_alloc(sizeof(FTFL_FLASH_INTERNAL_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (dev_spec_ptr == NULL)
    {
        return FALSE;
    }
#endif
    dev_ptr->DEVICE_SPECIFIC_DATA = dev_spec_ptr;

    /* get the pointer to ftfl registers structure */
    ftfl_ptr = (FTFL_MemMapPtr)_bsp_get_ftfl_address();
    dev_spec_ptr->ftfl_ptr = (vchar_ptr)ftfl_ptr;

    /* save pointer to function in ram */
    dev_spec_ptr->flash_execute_code_ptr = ftfl_init_ram_function();

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (dev_spec_ptr->flash_execute_code_ptr == NULL)
    {
        return FALSE;
    }
#endif

    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfl_flash_deinit
* Returned Value   : none
* Comments         :
*   Release flash specific information.
*
*END*-----------------------------------------------------------------------*/
void ftfl_flash_deinit
(
    /* [IN] Device instance */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    FTFL_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFL_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA;

    /* de-allocate the ram function buffer */
    ftfl_deinit_ram_function(dev_spec_ptr->flash_execute_code_ptr);

    /* de-allocate the device specific structure */
    _mem_free(dev_spec_ptr);

    dev_ptr->DEVICE_SPECIFIC_DATA = NULL;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfl_init_ram_function
* Returned Value   : pointer to allocated RAM function
* Comments         :
*   Allocate and copy flash RAM function.
*
*END*-----------------------------------------------------------------------*/
char_ptr ftfl_init_ram_function
(
    void
)
{
    char_ptr ram_code_ptr;
    _mem_size ftfl_ram_function_start;

    /* remove thumb2 flag from the address and align to word size */
    ftfl_ram_function_start = (_mem_size)ftfl_ram_function & ~3;

    /* allocate space to run flash command out of RAM */
    ram_code_ptr = _mem_alloc_align((char_ptr)ftfl_ram_function_end - (char_ptr)ftfl_ram_function_start, 4);

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (ram_code_ptr == NULL)
    {
        return NULL;
    }
#endif

    /* aopy code to RAM buffer */
    _mem_copy ((char_ptr)ftfl_ram_function_start, ram_code_ptr, (char_ptr)ftfl_ram_function_end - (char_ptr)ftfl_ram_function_start);

    /* adjust address with respect to the original alignment */
    ram_code_ptr = (char_ptr)((_mem_size)ram_code_ptr | ((_mem_size)ftfl_ram_function & 3));

    return ram_code_ptr;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfl_deinit_ram_function
* Returned Value   : MQX_OK or an error code 
* Comments         :
*   Free up flash RAM function, if any.
*
*END*-----------------------------------------------------------------------*/
_mqx_int ftfl_deinit_ram_function
(
    char_ptr ram_code_ptr
)
{
    if (NULL != ram_code_ptr)
    {
        return _mem_free((pointer)((_mem_size)ram_code_ptr & ~3));
    }

    return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfl_flash_erase_sector
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Erase a flash memory block.
*
*END*-----------------------------------------------------------------------*/
boolean ftfl_flash_erase_sector
(
    /* [IN] Device instance */
    IO_FLASHX_STRUCT_PTR dev_ptr,

    /* [IN] Erased sector address */
    char_ptr             from_ptr,

    /* [IN] Erased sector size */
    _mem_size            size
)
{
    FTFL_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFL_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA;
    FTFL_MemMapPtr                    ftfl_ptr;
    _mqx_uint                         i;
    _mem_size                         write_addr;
    uint_8                            command_array[4];

    /* get the pointer to ftfl registers structure */
    ftfl_ptr = (FTFL_MemMapPtr)dev_spec_ptr->ftfl_ptr;

    for (i = 0; dev_ptr->HW_BLOCK[i].NUM_SECTORS != 0; i++)
    {
        if (((uint_32)from_ptr >= dev_ptr->HW_BLOCK[i].START_ADDR) &&
            ((uint_32)from_ptr <= dev_ptr->HW_BLOCK[i].START_ADDR + dev_ptr->HW_BLOCK[i].SECTOR_SIZE * dev_ptr->HW_BLOCK[i].NUM_SECTORS))
        {
             /* check if the from_ptr is sector aligned or not */
             if ((uint_32)from_ptr % dev_ptr->HW_BLOCK[i].SECTOR_SIZE)
                return FALSE;
             /* check if the size is sector aligned or not */
             if ((uint_32)size % dev_ptr->HW_BLOCK[i].SECTOR_SIZE)
                return FALSE;
             break;
        }
    }

    write_addr = (_mem_size) from_ptr;

    /* preparing passing parameter to erase a flash block */
    command_array[0] = FTFL_ERASE_SECTOR;
    command_array[1] = (uint_8)(write_addr >> 16);
    command_array[2] = (uint_8)((write_addr >> 8) & 0xFF);
    command_array[3] = (uint_8)(write_addr & 0xFF);

    /* call flash command sequence function to execute the command */
    if (FTFL_OK != ftfl_flash_command_sequence (dev_spec_ptr, command_array, 4, FALSE))
    {
        return FALSE;
    }

    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfl_flash_write_sector
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Performs a write into flash memory.
*
*END*-----------------------------------------------------------------------*/
boolean ftfl_flash_write_sector
(
    /* [IN] Device instance */
    IO_FLASHX_STRUCT_PTR dev_ptr,

    /* [IN] Source address */
    char_ptr             from_ptr,

    /* [IN] Destination address */
    char_ptr             to_ptr,

    /* [IN] Number of bytes to write */
    _mem_size            size
)
{
    FTFL_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFL_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA;
    FTFL_MemMapPtr                    ftfl_ptr;
    _mqx_uint                         i;
    _mem_size                         write_addr;
    uint_8                            command_array[4 + FTFL_LONGWORD_SIZE];
    char                              temp_data[FTFL_LONGWORD_SIZE];
    uchar                             byte_data_counter = 0;
    uint_32                           offset = ((uint_32)to_ptr) & 0x00000003;

    dev_spec_ptr = dev_ptr->DEVICE_SPECIFIC_DATA;

    /* get the pointer to ftfl registers structure */
    ftfl_ptr = (FTFL_MemMapPtr)dev_spec_ptr->ftfl_ptr;

    /* write to address mod 4 correction */
    if (offset)
    {
        /* align pointer to writable address */
        to_ptr -= offset;

        /* jump over old data */
        byte_data_counter = offset;
    }

    write_addr = (_mem_size) to_ptr;

    /* heading space should be 0xFF */
    for (i = 0; i < offset; i++)
        temp_data[i] = 0xFF;

    while (size)
    {
        /* move data to temporary char array */
        while ((byte_data_counter < FTFL_LONGWORD_SIZE) && size)
        {
            temp_data[byte_data_counter++] = *from_ptr++;
            size--;
        }

        /* remaining space should be 0xFF */
        while (byte_data_counter < FTFL_LONGWORD_SIZE) {
            temp_data[byte_data_counter++] = 0xFF;
        }

        /* prepare parameters to program the flash block */
        command_array[0] = FTFL_PROGRAM_LONGWORD;
        command_array[1] = (uint_8)(write_addr >> 16);
        command_array[2] = (uint_8)((write_addr >> 8) & 0xFF);
        command_array[3] = (uint_8)(write_addr & 0xFF);

#if PSP_ENDIAN == MQX_BIG_ENDIAN
        command_array[4] = temp_data[0];
        command_array[5] = temp_data[1];
        command_array[6] = temp_data[2];
        command_array[7] = temp_data[3];
#else
        command_array[4] = temp_data[3];
        command_array[5] = temp_data[2];
        command_array[6] = temp_data[1];
        command_array[7] = temp_data[0];
#endif /* PSP_ENDIAN */

        /* call flash command sequence function to execute the command */
        if (FTFL_OK != ftfl_flash_command_sequence (dev_spec_ptr, command_array, 4 + FTFL_LONGWORD_SIZE, FALSE))
        {
            return FALSE;
        }

        /* update destination address for next iteration */
        write_addr += FTFL_LONGWORD_SIZE;
        /* init variables for next loop */
        byte_data_counter = 0;
    }

    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : ftfl_ram_function
* Returned Value   : void
* Comments         :
*   Code required to run in SRAM to perform flash commands.
*   All else can be run in flash.
*   Parameter is an address of flash status register.
*
*END*-----------------------------------------------------------------------*/
static void ftfl_ram_function
(
    /* [IN] Flash info structure */
    volatile uint_8 *ftfl_fstat_ptr
)
{
    /* start flash write */
    *ftfl_fstat_ptr |= FTFL_FSTAT_CCIF_MASK;

    /* wait until execution complete */
    while (0 == ((*ftfl_fstat_ptr) & FTFL_FSTAT_CCIF_MASK))
    { /* void */ }
}

static void ftfl_ram_function_end(void)
{}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : flexnvm_read_resource
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Program Partition Command
*
*END*-----------------------------------------------------------------------*/
static boolean flexnvm_read_resource
(
    /* [IN] Device instance */
    IO_FLASHX_STRUCT_PTR         dev_ptr,

    /* [IN] Pointer to resource to be read */
    FLEXNVM_READ_RSRC_STRUCT_PTR param_ptr
)
{
    FTFL_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFL_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA;
    FTFL_MemMapPtr                 ftfl_ptr;
    uint_8 command_array[9];

    /* get the pointer to ftfl registers structure */
    ftfl_ptr = (FTFL_MemMapPtr)dev_spec_ptr->ftfl_ptr;

    /* preparing passing parameter to erase a flash block */
    command_array[0] = FTFL_READ_RESOURCE;
    command_array[1] = (uint_8)((param_ptr->ADDR >> 16) & 0xFF);
    command_array[2] = (uint_8)((param_ptr->ADDR >> 8) & 0xFF);
    command_array[3] = (uint_8)(param_ptr->ADDR & 0xFF);

    command_array[8] = (uint_8)(param_ptr->RSRC_CODE);

    /* call flash command sequence function to execute the command */
    if (FTFL_OK != ftfl_flash_command_sequence(dev_spec_ptr, command_array, 9, TRUE)) {
        return FALSE;
    }

    param_ptr->RD_DATA = *(uint_32*)(&command_array[4]);

    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : flexnvm_prog_part
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Program Partition Command
*
*END*-----------------------------------------------------------------------*/
static boolean flexnvm_prog_part
(
    /* [IN] Device instance */
    IO_FLASHX_STRUCT_PTR         dev_ptr,

    /* [IN] Pointer to the structure containing partitioning info */
    FLEXNVM_PROG_PART_STRUCT_PTR param_ptr
)
{
    FTFL_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFL_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA;
    FTFL_MemMapPtr                 ftfl_ptr;
    uint_8 command_array[6];

    /* get the pointer to ftfl registers structure */
    ftfl_ptr = (FTFL_MemMapPtr)dev_spec_ptr->ftfl_ptr;

    /* preparing passing parameter to erase a flash block */
    command_array[0] = FTFL_PROGRAM_PARTITION;
    command_array[1] = 0;
    command_array[2] = 0;
    command_array[3] = 0;
    command_array[4] = param_ptr->EE_DATA_SIZE_CODE;
    command_array[5] = param_ptr->FLEXNVM_PART_CODE;

    /* call flash command sequence function to execute the command */
    if (FTFL_OK != ftfl_flash_command_sequence(dev_spec_ptr, command_array, 6, FALSE)) {
        return FALSE;
    }

    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : flexnvm_set_flexram
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Program Partition Command
*
*END*----------------------------------------------------------------------*/
static boolean flexnvm_set_flexram
(
    /* [IN] Device instance */
    IO_FLASHX_STRUCT_PTR dev_ptr,

    /* [IN] Command code */
    uchar ctrl_code
)
{
    FTFL_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = (FTFL_FLASH_INTERNAL_STRUCT_PTR) dev_ptr->DEVICE_SPECIFIC_DATA;
    FTFL_MemMapPtr ftfl_ptr;
    uint_8 command_array[2];

    /* get the pointer to ftfl registers structure */
    ftfl_ptr = (FTFL_MemMapPtr)dev_spec_ptr->ftfl_ptr;

    /* prepare to pass the parameter to set FlexRAM */
    command_array[0] = FTFL_SET_EERAM;
    command_array[1] = ctrl_code;

    /* call flash command sequence function to execute the command */
    if (FTFL_OK != ftfl_flash_command_sequence (dev_spec_ptr, command_array, 2, FALSE)) {
        return FALSE;
    }

    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : flexnvm_flash_ioctl
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*   Program Partition Command
*
*END*----------------------------------------------------------------------*/
_mqx_int flexnvm_flash_ioctl
(
    /* [IN] Device instance */
    IO_FLASHX_STRUCT_PTR dev_ptr,

    /* [IN] the ioctl command */
    _mqx_uint cmd,

    /* [IN] the ioctl command parameter */
    pointer param_ptr
)
{
    _mqx_int result = IO_OK;

    switch (cmd) {
        case FLEXNVM_IOCTL_READ_RESOURCE:
            flexnvm_read_resource(dev_ptr, (FLEXNVM_READ_RSRC_STRUCT_PTR)param_ptr);
            break;
        case FLEXNVM_IOCTL_GET_PARTITION_CODE: {
                FLEXNVM_READ_RSRC_STRUCT rsrc_param;

                rsrc_param.ADDR = 0x8000fc;
                rsrc_param.RSRC_CODE = 0;

                if (flexnvm_read_resource(dev_ptr, &rsrc_param) && NULL != param_ptr) {
                    ((FLEXNVM_PROG_PART_STRUCT_PTR)param_ptr)->EE_DATA_SIZE_CODE = (rsrc_param.RD_DATA >> 8) & (FLEXNVM_EE_SPLIT_MASK | FLEXNVM_EE_SIZE_MASK);
                    ((FLEXNVM_PROG_PART_STRUCT_PTR)param_ptr)->FLEXNVM_PART_CODE = rsrc_param.RD_DATA & FLEXNVM_PART_CODE_MASK;
                }
                else {
                    result = IO_ERROR_READ;
                }

                break;
            }
        case FLEXNVM_IOCTL_SET_PARTITION_CODE:
            flexnvm_prog_part(dev_ptr, (FLEXNVM_PROG_PART_STRUCT_PTR)param_ptr);
            break;
        case FLEXNVM_IOCTL_SET_FLEXRAM_FN:
            flexnvm_set_flexram(dev_ptr, *(uchar*)param_ptr);
            break;
        case FLEXNVM_IOCTL_WAIT_EERDY: {
                FTFL_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = dev_ptr->DEVICE_SPECIFIC_DATA;
                FTFL_MemMapPtr ftfl_ptr = (FTFL_MemMapPtr)dev_spec_ptr->ftfl_ptr;

                while (!(ftfl_ptr->FCNFG & FTFL_FCNFG_EEERDY_MASK)){}

                break;
            }
        case FLEXNVM_IOCTL_GET_EERDY: {
                FTFL_FLASH_INTERNAL_STRUCT_PTR dev_spec_ptr = dev_ptr->DEVICE_SPECIFIC_DATA;
                FTFL_MemMapPtr ftfl_ptr = (FTFL_MemMapPtr)dev_spec_ptr->ftfl_ptr;

                if (NULL != param_ptr)
                    *(uint_32*)param_ptr = (ftfl_ptr->FCNFG & FTFL_FCNFG_EEERDY_MASK);

                break;
            }
        default:
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }

    return result;
}


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/msd/mfs/usbmfspr.h<|end_filename|>
#ifndef _usbmfspr_h_
#define _usbmfspr_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usbmfspr.h$
* $Version : 3.8.9.0$
* $Date    : Jun-22-2012$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions private to the USB mass storage link driver
*   to MFS.
*
*END************************************************************************/

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/* Error codes from lower layers */
#define USB_MFS_DEFAULT_SECTOR_SIZE  (512)

/*----------------------------------------------------------------------*/
/*
**                          ERROR CODES
*/

/* Error codes from lower layers */
//#define USB_MFS_NO_ERROR             MQX_OK
//#define USB_MFS_READ_ERROR           IO_ERROR_READ
//#define USB_MFS_WRITE_ERROR          IO_ERROR_WRITE
//#define USB_MFS_INVALID_SECTOR       IO_ERROR_SEEK

/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/


/*
** USB_MFS_INFO_STRUCT
** Run time state information for each USB mass storage device
*/
typedef struct io_usb_mfs_info_struct
{
   COMMAND_OBJECT_STRUCT      COMMAND;    // MUST BE FIRST
#if PSP_HAS_DATA_CACHE
   uchar                      FILLER1[CACHE_LINE_FILLER(sizeof(COMMAND_OBJECT_STRUCT))];
#endif
   CBW_STRUCT                 CBW;
#if PSP_HAS_DATA_CACHE
   uchar                      FILLER2[CACHE_LINE_FILLER(sizeof(CBW_STRUCT))];
#endif
   CSW_STRUCT                 CSW;
#if PSP_HAS_DATA_CACHE
   uchar                      FILLER3[CACHE_LINE_FILLER(sizeof(CSW_STRUCT))];
#endif
   INQUIRY_DATA_FORMAT        INQUIRY_DATA;
#if PSP_HAS_DATA_CACHE
   uchar                      FILLER4[CACHE_LINE_FILLER(sizeof(INQUIRY_DATA_FORMAT))];
#endif
  MASS_STORAGE_READ_CAPACITY_CMD_STRUCT_INFO   CAPACITY;
#if PSP_HAS_DATA_CACHE
   uchar                      FILLER5[CACHE_LINE_FILLER(sizeof(MASS_STORAGE_READ_CAPACITY_CMD_STRUCT_INFO))];
#endif
   REQ_SENSE_DATA_FORMAT      SENSE;
#if PSP_HAS_DATA_CACHE
   uchar                      FILLER6[CACHE_LINE_FILLER(sizeof(REQ_SENSE_DATA_FORMAT))];
#endif
   /* Handle for mass storage class  calls */
   pointer       MSC_STREAM;
   
   /* 8 bytes of ASCI Data identifying the vendor of the product */
   
   /* 16 bytes of ASCI Data defined by the vendor */
  
   /* 4 bytes of ASCI Data defined by the vendor */
   
   /* CBW tag used for commands */
   uint_32       CBW_TAG;         
   
   /* Drive number to associate with this slot */
   uint_8        LUN;
   
   uint_32       BLENGTH;   // logic block length
   uint_32       BCOUNT;    // logic blocks count

   /* Total size of Drive in bytes */
   uint_32       SIZE_BYTES; 

   /* The number of heads as reported  */
   uint_32       NUMBER_OF_HEADS;          

   /* The number of tracks as reported  */
   uint_32       NUMBER_OF_TRACKS;

   /* The number of sectos per cylinder as reported */
   uint_32       SECTORS_PER_TRACK;

   /* Light weight semaphore struct */
   LWSEM_STRUCT  LWSEM;
   
   /* The address of temp buffer */

   /* The current error code for the device */
   uint_32       ERROR_CODE;
   
   /* Start CR 812 */
   /* Indicates if the device is running in block mode or character mode */
   boolean       BLOCK_MODE;
   /* End   CR 812 */

   uint_32       COMMAND_STATUS;
   LWSEM_STRUCT  COMMAND_DONE;
} IO_USB_MFS_STRUCT, _PTR_ IO_USB_MFS_STRUCT_PTR;

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_usb_mfs_open(MQX_FILE_PTR, char _PTR_, char _PTR_);
extern _mqx_int _io_usb_mfs_close(MQX_FILE_PTR);
extern _mqx_int _io_usb_mfs_read (MQX_FILE_PTR, char_ptr, int_32);
extern _mqx_int _io_usb_mfs_write(MQX_FILE_PTR, char_ptr, int_32);
extern _mqx_int _io_usb_mfs_ioctl(MQX_FILE_PTR, int_32, pointer);
extern int_32 _io_usb_mfs_uninstall(IO_DEVICE_STRUCT_PTR  io_dev_ptr);
   
#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_spr.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_spr.c$
* $Version : 3.8.5.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the function for sprintf and snprintf.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Performs similarly to the sprintf function found in 'C'.
 * 
 * The returned number of characters does not include the terminating '\0'
 * 
 * \param[in] str_ptr The string to print into.
 * \param[in] fmt_ptr The format specifier.
 * 
 * \return Number of characters
 * \return IO_EOF (End Of File found.)   
 */ 
_mqx_int _io_sprintf
   (
      char        _PTR_ str_ptr,
      const char  _PTR_ fmt_ptr,
      ...
   )
{ /* Body */
   _mqx_int result;
   va_list ap;
   
   va_start(ap, fmt_ptr);
   result = _io_doprint((MQX_FILE_PTR)((pointer)&str_ptr), _io_sputc, -1, (char _PTR_)fmt_ptr, ap);
   *str_ptr = '\0';
   va_end(ap);
   return result;

} /* Endbody */

/*!
 * \brief This function performs similarly to the sprintf function found in 'C'.
 * 
 * The returned number of characters does not include the terminating '\0'.
 * 
 * \param[in] str_ptr   The string to print into.
 * \param[in] max_count The maximal size of string.
 * \param[in] fmt_ptr   The format specifier.
 * 
 * \return Number of characters
 * \return IO_EOF (End Of File found.) 
 */ 
_mqx_int _io_snprintf
   (
      char          _PTR_ str_ptr,
      _mqx_int      max_count,
      const char    _PTR_ fmt_ptr,
      ...
   )
{
    _mqx_int result;

    va_list ap;
    va_start(ap, fmt_ptr);
    result = _io_doprint((MQX_FILE_PTR)((pointer)&str_ptr), _io_sputc, max_count, (char _PTR_)fmt_ptr, ap);
    va_end(ap);
    if (0 != max_count)
    {
        *str_ptr = '\0';
    }
   
    return result;

}

/*!
 * \brief Erites the character into the string located by the string pointer and
 * updates the string pointer.
 * 
 * \param[in]      c                The character to put into the string.
 * \param[in, out] input_string_ptr This is an updated pointer to a string pointer.
 * 
 * \return Character written into string. 
 */ 
_mqx_int _io_sputc
   (
      _mqx_int     c,
      MQX_FILE_PTR input_string_ptr
   )
{ /* Body */
   char _PTR_ _PTR_ string_ptr = (char _PTR_ _PTR_)((pointer)input_string_ptr);

   *(*string_ptr)++ = (char)c;
   return c;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_SystemSetupVal.h<|end_filename|>
/***********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
*********************************************************************************************************************//*!
*
* @file   TSS_SystemSetupVal.h
*
* @brief  Validates the configuration in the TSS_SystemSetup.h file 
*
* @version 1.0.37.0
* 
* @date Sep-12-2012
* 
* This file validates the configuration parameters stablished by the user in the TSS_SystemSetup.h file. 
* For every invalid parameter a error message is generated indicaiting why the parameter is invalid.
* The parameters are validated while compiling therefore errors appear when compiling.
*
***********************************************************************************************************************/


#ifndef TSS_SYSTEMSETUPVAL_H
#define TSS_SYSTEMSETUPVAL_H

    #include "TSS_SystemSetup.h" 
    #include "TSS_API.h" 

   
    #if (TSS_USE_PE_COMPONENT > 1)
        #error "TSS - TSS_USE_PE_COMPONENT is set to invalid value"
    #endif

    #if (TSS_USE_SIMPLE_LOW_LEVEL > 1)
        #error "TSS - TSS_USE_SIMPLE_LOW_LEVEL is set to invalid value"
    #endif

    #if (TSS_USE_DELTA_LOG > 1)
        #error "TSS - TSS_USE_DELTA_LOG is set to invalid value"
    #endif
    
    #if (TSS_USE_SIGNAL_LOG > 1)
        #error "TSS - TSS_USE_SIGNAL_LOG is set to invalid value"
    #endif
    
    #if (TSS_USE_GPIO_STRENGTH > 1)
        #error "TSS - TSS_USE_GPIO_STRENGTH is set to invalid value"
    #endif
    
    #if (TSS_USE_GPIO_SLEW_RATE > 1)
        #error "TSS - TSS_USE_GPIO_SLEW_RATE is set to invalid value"
    #endif

    #if (TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW > 1)
        #error "TSS - TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW is set to invalid value"
    #endif
   
    #if (TSS_USE_IIR_FILTER > 1)
        #error "TSS - TSS_USE_IIR_FILTER is set to invalid value"
    #endif
    
    #if (TSS_USE_DATA_CORRUPTION_CHECK > 1)
        #error "TSS - TSS_USE_DATA_CORRUPTION_CHECK is set to invalid value"
    #endif

    #if (TSS_USE_FREEMASTER_GUI > 1)
        #error "TSS - TSS_USE_FREEMASTER_GUI is set to invalid value"
    #endif

    #if (TSS_ENABLE_DIAGNOSTIC_MESSAGES > 1)
        #error "TSS - TSS_ENABLE_DIAGNOSTIC_MESSAGES is set to invalid value"
    #endif

    #if (TSS_USE_CONTROL_PRIVATE_DATA > 1)
        #error "TSS - TSS_USE_CONTROL_PRIVATE_DATA is set to invalid value"
    #endif

    #if (TSS_USE_SIGNAL_SHIELDING > 1)
        #error "TSS - TSS_USE_SIGNAL_SHIELDING is set to invalid value"
    #endif

    #if (TSS_USE_SIGNAL_DIVIDER > 1)
        #error "TSS - TSS_USE_SIGNAL_DIVIDER is set to invalid value"
    #endif

    #if (TSS_USE_SIGNAL_MULTIPLIER > 1)
        #error "TSS - TSS_USE_SIGNAL_MULTIPLIER is set to invalid value"
    #endif

    #if (TSS_USE_STUCK_KEY > 1)
        #error "TSS - TSS_USE_STUCK_KEY is set to invalid value"
    #endif

    #if (TSS_USE_NEGATIVE_BASELINE_DROP > 1)
        #error "TSS - TSS_USE_NEGATIVE_BASELINE_DROP is set to invalid value"
    #endif

    #if (TSS_USE_AUTO_HW_RECALIBRATION > 1)
        #error "TSS - TSS_USE_AUTO_HW_RECALIBRATION is set to invalid value"
    #endif

    #if (TSS_USE_TRIGGER_FUNCTION > 1)
       #error "TSS - TSS_USE_TRIGGER_FUNCTION is set to invalid value"
    #endif

    #if (TSS_USE_BASELINE_INIT_DURATION > 255)
       #error "TSS - TSS_USE_BASELINE_INIT_DURATION is out of range"
    #endif

    #if (TSS_USE_AUTO_SENS_CALIBRATION > 1)
       #error "TSS - TSS_USE_AUTO_SENS_CALIBRATION is set to invalid value"
    #endif

    #if (TSS_USE_AUTO_SENS_CALIB_INIT_DURATION > 255)
       #error "TSS - TSS_USE_AUTO_SENS_CALIB_INIT_DURATION is out of range"    
    #endif
    
    #if (TSS_USE_DELTA_NOISE_ANALYSIS_BUFFER_LENGTH > 255)
       #error "TSS - TSS_USE_DELTA_NOISE_ANALYSIS_BUFFER_LENGTH is out of range"    
    #endif
  
    #if (TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT1 > 127) || (TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT1 < -127)
       #error "TSS - TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT1 is out of range"    
    #endif

    #if (TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT2 > 127) || (TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT2 < -127)
       #error "TSS - TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT2 is out of range"    
    #endif

    #if (TSS_ASLIDER_POSITION_IIR_WEIGHT > 15)
        #error "TSS - TSS_ASLIDER_POSITION_IIR_WEIGHT is out of range"
    #endif

    #if (TSS_ASLIDER_DELAY_BUFFER_LENGTH > 255)
        #error "TSS - TSS_ASLIDER_DELAY_BUFFER_LENGTH is out of range"
    #endif

    #if (TSS_ASLIDER_TREND_BUFFER_LENGTH > 255)
        #error "TSS - TSS_ASLIDER_TREND_BUFFER_LENGTH is out of range"
    #endif

    #if (TSS_ASLIDER_TREND_THRESHOLD > 127)
        #error "TSS - TSS_ASLIDER_TREND_THRESHOLD is out of range"
    #endif

    #if (TSS_MATRIX_POSITION_IIR_WEIGHT > 15)
        #error "TSS - TSS_MATRIX_POSITION_IIR_WEIGHT is out of range"
    #endif

    #if (TSS_USE_NOISE_AMPLITUDE_FILTER > 1)
        #error "TSS - TSS_USE_NOISE_AMPLITUDE_FILTER is set to invalid value"
    #endif
    
    #if TSS_USE_NOISE_AMPLITUDE_FILTER
      #ifdef TSS_E0_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E0_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E0_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E0_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E1_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E1_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E1_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E1_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E2_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E2_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E2_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E2_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E3_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E3_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E3_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E3_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E4_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E4_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E4_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E4_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E5_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E5_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E5_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E5_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E6_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E6_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E6_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E6_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E7_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E7_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E7_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E7_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E8_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E8_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E8_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E8_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E9_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E9_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E9_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E9_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E10_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E10_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E10_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E10_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E11_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E11_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E11_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E11_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E12_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E12_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E12_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E12_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E13_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E13_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E13_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E13_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E14_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E14_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E14_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E14_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E15_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E15_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E15_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E15_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E16_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E16_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E16_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E16_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E17_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E17_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E17_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E17_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E18_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E18_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E18_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E18_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E19_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E19_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E19_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E19_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E20_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E20_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E20_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E20_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E21_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E21_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E21_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E21_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E22_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E22_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E22_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E22_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E23_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E23_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E23_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E23_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E24_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E24_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E24_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E24_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E25_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E25_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E25_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E25_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E26_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E26_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E26_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E26_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E27_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E27_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E27_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E27_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E28_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E28_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E28_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E28_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E29_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E29_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E29_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E29_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E30_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E30_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E30_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E30_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E31_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E31_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E31_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E31_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E32_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E32_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E32_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E32_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E33_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E33_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E33_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E33_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E34_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E34_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E34_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E34_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E35_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E35_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E35_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E35_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E36_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E36_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E36_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E36_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E37_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E37_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E37_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E37_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E38_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E38_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E38_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E38_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E39_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E39_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E39_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E39_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E40_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E40_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E40_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E40_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E41_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E41_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E41_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E41_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E42_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E42_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E42_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E42_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E43_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E43_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E43_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E43_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E44_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E44_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E44_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E44_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E45_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E45_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E45_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E45_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E46_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E46_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E46_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E46_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E47_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E47_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E47_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E47_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E48_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E48_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E48_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E48_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E49_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E49_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E49_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E49_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E50_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E50_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E50_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E50_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E51_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E51_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E51_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E51_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E52_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E52_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E52_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E52_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E53_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E53_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E53_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E53_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E54_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E54_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E54_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E54_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E55_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E55_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E55_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E55_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E56_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E56_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E56_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E56_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E57_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E57_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E57_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E57_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E58_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E58_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E58_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E58_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E59_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E59_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E59_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E59_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E60_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E60_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E60_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E60_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E61_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E61_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E61_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E61_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E62_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E62_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E62_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E62_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
      #ifdef TSS_E63_NOISE_AMPLITUDE_FILTER_SIZE
        #if ((TSS_E63_NOISE_AMPLITUDE_FILTER_SIZE < 2) || (TSS_E63_NOISE_AMPLITUDE_FILTER_SIZE > 255))
          #error "TSS - TSS_E63_NOISE_AMPLITUDE_FILTER_SIZE is out of range"
        #endif
      #endif
    #endif  

    #if TSS_USE_SIGNAL_SHIELDING
      #if TSS_N_ELECTRODES > 0
        #ifdef TSS_E0_SHIELD_ELECTRODE
          #if (TSS_E0_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E0_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E0_SHIELD_ELECTRODE == 0) 
            #error "TSS - TSS_E0_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 1
        #ifdef TSS_E1_SHIELD_ELECTRODE
          #if (TSS_E1_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E1_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E1_SHIELD_ELECTRODE == 1) 
            #error "TSS - TSS_E1_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 2
        #ifdef TSS_E2_SHIELD_ELECTRODE
          #if (TSS_E2_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E2_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E2_SHIELD_ELECTRODE == 2) 
            #error "TSS - TSS_E2_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 3
        #ifdef TSS_E3_SHIELD_ELECTRODE
          #if (TSS_E3_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E3_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E3_SHIELD_ELECTRODE == 3) 
            #error "TSS - TSS_E3_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 4
        #ifdef TSS_E4_SHIELD_ELECTRODE
          #if (TSS_E4_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E4_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E4_SHIELD_ELECTRODE == 4) 
            #error "TSS - TSS_E4_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 5
        #ifdef TSS_E5_SHIELD_ELECTRODE
          #if (TSS_E5_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E5_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E5_SHIELD_ELECTRODE == 5) 
            #error "TSS - TSS_E5_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 6
        #ifdef TSS_E6_SHIELD_ELECTRODE
          #if (TSS_E6_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E6_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E6_SHIELD_ELECTRODE == 6) 
            #error "TSS - TSS_E6_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 7
        #ifdef TSS_E7_SHIELD_ELECTRODE
          #if (TSS_E7_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E7_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E7_SHIELD_ELECTRODE == 7) 
            #error "TSS - TSS_E7_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 8
        #ifdef TSS_E8_SHIELD_ELECTRODE
          #if (TSS_E8_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E8_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E8_SHIELD_ELECTRODE == 8) 
            #error "TSS - TSS_E8_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 9
        #ifdef TSS_E9_SHIELD_ELECTRODE
          #if (TSS_E9_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E9_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E9_SHIELD_ELECTRODE == 9) 
            #error "TSS - TSS_E9_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 10
        #ifdef TSS_E10_SHIELD_ELECTRODE
          #if (TSS_E10_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E10_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E10_SHIELD_ELECTRODE == 10) 
            #error "TSS - TSS_E10_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 11
        #ifdef TSS_E11_SHIELD_ELECTRODE
          #if (TSS_E11_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E11_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E11_SHIELD_ELECTRODE == 11) 
            #error "TSS - TSS_E11_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 12
        #ifdef TSS_E12_SHIELD_ELECTRODE
          #if (TSS_E12_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E12_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E12_SHIELD_ELECTRODE == 12) 
            #error "TSS - TSS_E12_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 13
        #ifdef TSS_E13_SHIELD_ELECTRODE
          #if (TSS_E13_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E13_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E13_SHIELD_ELECTRODE == 13) 
            #error "TSS - TSS_E13_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 14
        #ifdef TSS_E14_SHIELD_ELECTRODE
          #if (TSS_E14_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E14_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E14_SHIELD_ELECTRODE == 14) 
            #error "TSS - TSS_E14_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 15
        #ifdef TSS_E15_SHIELD_ELECTRODE
          #if (TSS_E15_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E15_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E15_SHIELD_ELECTRODE == 15) 
            #error "TSS - TSS_E15_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 16
        #ifdef TSS_E16_SHIELD_ELECTRODE
          #if (TSS_E16_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E16_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E16_SHIELD_ELECTRODE == 16) 
            #error "TSS - TSS_E16_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 17
        #ifdef TSS_E17_SHIELD_ELECTRODE
          #if (TSS_E17_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E17_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E17_SHIELD_ELECTRODE == 17) 
            #error "TSS - TSS_E17_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 18
        #ifdef TSS_E18_SHIELD_ELECTRODE
          #if (TSS_E18_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E18_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E18_SHIELD_ELECTRODE == 18) 
            #error "TSS - TSS_E18_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 19
        #ifdef TSS_E19_SHIELD_ELECTRODE
          #if (TSS_E19_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E19_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E19_SHIELD_ELECTRODE == 19) 
            #error "TSS - TSS_E19_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 20
        #ifdef TSS_E20_SHIELD_ELECTRODE
          #if (TSS_E20_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E20_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E20_SHIELD_ELECTRODE == 20) 
            #error "TSS - TSS_E20_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 21
        #ifdef TSS_E21_SHIELD_ELECTRODE
          #if (TSS_E21_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E21_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E21_SHIELD_ELECTRODE == 21) 
            #error "TSS - TSS_E21_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 22
        #ifdef TSS_E22_SHIELD_ELECTRODE
          #if (TSS_E22_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E22_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E22_SHIELD_ELECTRODE == 22) 
            #error "TSS - TSS_E22_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 23
        #ifdef TSS_E23_SHIELD_ELECTRODE
          #if (TSS_E23_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E23_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E23_SHIELD_ELECTRODE == 23) 
            #error "TSS - TSS_E23_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 24
        #ifdef TSS_E24_SHIELD_ELECTRODE
          #if (TSS_E24_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E24_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E24_SHIELD_ELECTRODE == 24) 
            #error "TSS - TSS_E24_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 25
        #ifdef TSS_E25_SHIELD_ELECTRODE
          #if (TSS_E25_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E25_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E25_SHIELD_ELECTRODE == 25) 
            #error "TSS - TSS_E25_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 26
        #ifdef TSS_E26_SHIELD_ELECTRODE
          #if (TSS_E26_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E26_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E26_SHIELD_ELECTRODE == 26) 
            #error "TSS - TSS_E26_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 27
        #ifdef TSS_E27_SHIELD_ELECTRODE
          #if (TSS_E27_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E27_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E27_SHIELD_ELECTRODE == 27) 
            #error "TSS - TSS_E27_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 28
        #ifdef TSS_E28_SHIELD_ELECTRODE
          #if (TSS_E28_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E28_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E28_SHIELD_ELECTRODE == 28) 
            #error "TSS - TSS_E28_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 29
        #ifdef TSS_E29_SHIELD_ELECTRODE
          #if (TSS_E29_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E29_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E29_SHIELD_ELECTRODE == 29) 
            #error "TSS - TSS_E29_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 30
        #ifdef TSS_E30_SHIELD_ELECTRODE
          #if (TSS_E30_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E30_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E30_SHIELD_ELECTRODE == 30) 
            #error "TSS - TSS_E30_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 31
        #ifdef TSS_E31_SHIELD_ELECTRODE
          #if (TSS_E31_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E31_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E31_SHIELD_ELECTRODE == 31) 
            #error "TSS - TSS_E31_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 32
        #ifdef TSS_E32_SHIELD_ELECTRODE
          #if (TSS_E32_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E32_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E32_SHIELD_ELECTRODE == 32) 
            #error "TSS - TSS_E32_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 33
        #ifdef TSS_E33_SHIELD_ELECTRODE
          #if (TSS_E33_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E33_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E33_SHIELD_ELECTRODE == 33) 
            #error "TSS - TSS_E33_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 34
        #ifdef TSS_E34_SHIELD_ELECTRODE
          #if (TSS_E34_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E34_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E34_SHIELD_ELECTRODE == 34) 
            #error "TSS - TSS_E34_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 35
        #ifdef TSS_E35_SHIELD_ELECTRODE
          #if (TSS_E35_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E35_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E35_SHIELD_ELECTRODE == 35) 
            #error "TSS - TSS_E35_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 36
        #ifdef TSS_E36_SHIELD_ELECTRODE
          #if (TSS_E36_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E36_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E36_SHIELD_ELECTRODE == 36) 
            #error "TSS - TSS_E36_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 37
        #ifdef TSS_E37_SHIELD_ELECTRODE
          #if (TSS_E37_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E37_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E37_SHIELD_ELECTRODE == 37) 
            #error "TSS - TSS_E37_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 38
        #ifdef TSS_E38_SHIELD_ELECTRODE
          #if (TSS_E38_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E38_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E38_SHIELD_ELECTRODE == 38) 
            #error "TSS - TSS_E38_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 39
        #ifdef TSS_E39_SHIELD_ELECTRODE
          #if (TSS_E39_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E39_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E39_SHIELD_ELECTRODE == 39) 
            #error "TSS - TSS_E39_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 40
        #ifdef TSS_E40_SHIELD_ELECTRODE
          #if (TSS_E40_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E40_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E40_SHIELD_ELECTRODE == 40) 
            #error "TSS - TSS_E40_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 41
        #ifdef TSS_E41_SHIELD_ELECTRODE
          #if (TSS_E41_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E41_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E41_SHIELD_ELECTRODE == 41) 
            #error "TSS - TSS_E41_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 42
        #ifdef TSS_E42_SHIELD_ELECTRODE
          #if (TSS_E42_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E42_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E42_SHIELD_ELECTRODE == 42) 
            #error "TSS - TSS_E42_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 43
        #ifdef TSS_E43_SHIELD_ELECTRODE
          #if (TSS_E43_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E43_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E43_SHIELD_ELECTRODE == 43) 
            #error "TSS - TSS_E43_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 44
        #ifdef TSS_E44_SHIELD_ELECTRODE
          #if (TSS_E44_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E44_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E44_SHIELD_ELECTRODE == 44) 
            #error "TSS - TSS_E44_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 45
        #ifdef TSS_E45_SHIELD_ELECTRODE
          #if (TSS_E45_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E45_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E45_SHIELD_ELECTRODE == 45) 
            #error "TSS - TSS_E45_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 46
        #ifdef TSS_E46_SHIELD_ELECTRODE
          #if (TSS_E46_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E46_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E46_SHIELD_ELECTRODE == 46) 
            #error "TSS - TSS_E46_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 47
        #ifdef TSS_E47_SHIELD_ELECTRODE
          #if (TSS_E47_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E47_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E47_SHIELD_ELECTRODE == 47) 
            #error "TSS - TSS_E47_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 48
        #ifdef TSS_E48_SHIELD_ELECTRODE
          #if (TSS_E48_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E48_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E48_SHIELD_ELECTRODE == 48) 
            #error "TSS - TSS_E48_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 49
        #ifdef TSS_E49_SHIELD_ELECTRODE
          #if (TSS_E49_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E49_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E49_SHIELD_ELECTRODE == 49) 
            #error "TSS - TSS_E49_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 50
        #ifdef TSS_E50_SHIELD_ELECTRODE
          #if (TSS_E50_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E50_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E50_SHIELD_ELECTRODE == 50) 
            #error "TSS - TSS_E50_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 51
        #ifdef TSS_E51_SHIELD_ELECTRODE
          #if (TSS_E51_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E51_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E51_SHIELD_ELECTRODE == 51) 
            #error "TSS - TSS_E51_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 52
        #ifdef TSS_E52_SHIELD_ELECTRODE
          #if (TSS_E52_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E52_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E52_SHIELD_ELECTRODE == 52) 
            #error "TSS - TSS_E52_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 53
        #ifdef TSS_E53_SHIELD_ELECTRODE
          #if (TSS_E53_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E53_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E53_SHIELD_ELECTRODE == 53) 
            #error "TSS - TSS_E53_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 54
        #ifdef TSS_E54_SHIELD_ELECTRODE
          #if (TSS_E54_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E54_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E54_SHIELD_ELECTRODE == 54) 
            #error "TSS - TSS_E54_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 55
        #ifdef TSS_E55_SHIELD_ELECTRODE
          #if (TSS_E55_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E55_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E55_SHIELD_ELECTRODE == 55) 
            #error "TSS - TSS_E55_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 56
        #ifdef TSS_E56_SHIELD_ELECTRODE
          #if (TSS_E56_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E56_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E56_SHIELD_ELECTRODE == 56) 
            #error "TSS - TSS_E56_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 57
        #ifdef TSS_E57_SHIELD_ELECTRODE
          #if (TSS_E57_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E57_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E57_SHIELD_ELECTRODE == 57) 
            #error "TSS - TSS_E57_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 58
        #ifdef TSS_E58_SHIELD_ELECTRODE
          #if (TSS_E58_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E58_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E58_SHIELD_ELECTRODE == 58) 
            #error "TSS - TSS_E58_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 59
        #ifdef TSS_E59_SHIELD_ELECTRODE
          #if (TSS_E59_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E59_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E59_SHIELD_ELECTRODE == 59) 
            #error "TSS - TSS_E59_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 60
        #ifdef TSS_E60_SHIELD_ELECTRODE
          #if (TSS_E60_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E60_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E60_SHIELD_ELECTRODE == 60) 
            #error "TSS - TSS_E60_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 61
        #ifdef TSS_E61_SHIELD_ELECTRODE
          #if (TSS_E61_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E61_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E61_SHIELD_ELECTRODE == 61) 
            #error "TSS - TSS_E61_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 62
        #ifdef TSS_E62_SHIELD_ELECTRODE
          #if (TSS_E62_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E62_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E62_SHIELD_ELECTRODE == 62) 
            #error "TSS - TSS_E62_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 63
        #ifdef TSS_E63_SHIELD_ELECTRODE
          #if (TSS_E63_SHIELD_ELECTRODE >= TSS_N_ELECTRODES) 
            #error "TSS - TSS_E63_SHIELD_ELECTRODE is out of range"
          #elif (TSS_E63_SHIELD_ELECTRODE == 63) 
            #error "TSS - TSS_E63_SHIELD_ELECTRODE is assigned to itself"
          #endif
        #endif
      #endif
    #endif

    #if TSS_USE_SIGNAL_DIVIDER
      #if TSS_N_ELECTRODES > 0
        #ifdef TSS_E0_SIGNAL_DIVIDER
          #if (TSS_E0_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E0_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 1
        #ifdef TSS_E1_SIGNAL_DIVIDER
          #if (TSS_E1_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E1_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 2
        #ifdef TSS_E2_SIGNAL_DIVIDER
          #if (TSS_E2_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E2_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 3
        #ifdef TSS_E3_SIGNAL_DIVIDER
          #if (TSS_E3_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E3_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 4
        #ifdef TSS_E4_SIGNAL_DIVIDER
          #if (TSS_E4_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E4_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 5
        #ifdef TSS_E5_SIGNAL_DIVIDER
          #if (TSS_E5_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E5_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 6
        #ifdef TSS_E6_SIGNAL_DIVIDER
          #if (TSS_E6_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E6_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 7
        #ifdef TSS_E7_SIGNAL_DIVIDER
          #if (TSS_E7_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E7_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 8
        #ifdef TSS_E8_SIGNAL_DIVIDER
          #if (TSS_E8_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E8_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 9
        #ifdef TSS_E9_SIGNAL_DIVIDER
          #if (TSS_E9_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E9_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 10
        #ifdef TSS_E10_SIGNAL_DIVIDER
          #if (TSS_E10_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E10_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 11
        #ifdef TSS_E11_SIGNAL_DIVIDER
          #if (TSS_E11_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E11_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 12
        #ifdef TSS_E12_SIGNAL_DIVIDER
          #if (TSS_E12_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E12_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 13
        #ifdef TSS_E13_SIGNAL_DIVIDER
          #if (TSS_E13_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E13_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 14
        #ifdef TSS_E14_SIGNAL_DIVIDER
          #if (TSS_E14_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E14_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 15
        #ifdef TSS_E15_SIGNAL_DIVIDER
          #if (TSS_E15_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E15_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 16
        #ifdef TSS_E16_SIGNAL_DIVIDER
          #if (TSS_E16_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E16_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 17
        #ifdef TSS_E17_SIGNAL_DIVIDER
          #if (TSS_E17_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E17_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 18
        #ifdef TSS_E18_SIGNAL_DIVIDER
          #if (TSS_E18_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E18_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 19
        #ifdef TSS_E19_SIGNAL_DIVIDER
          #if (TSS_E19_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E19_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 20
        #ifdef TSS_E20_SIGNAL_DIVIDER
          #if (TSS_E20_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E20_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 21
        #ifdef TSS_E21_SIGNAL_DIVIDER
          #if (TSS_E21_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E21_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 22
        #ifdef TSS_E22_SIGNAL_DIVIDER
          #if (TSS_E22_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E22_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 23
        #ifdef TSS_E23_SIGNAL_DIVIDER
          #if (TSS_E23_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E23_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 24
        #ifdef TSS_E24_SIGNAL_DIVIDER
          #if (TSS_E24_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E24_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 25
        #ifdef TSS_E25_SIGNAL_DIVIDER
          #if (TSS_E25_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E25_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 26
        #ifdef TSS_E26_SIGNAL_DIVIDER
          #if (TSS_E26_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E26_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 27
        #ifdef TSS_E27_SIGNAL_DIVIDER
          #if (TSS_E27_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E27_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 28
        #ifdef TSS_E28_SIGNAL_DIVIDER
          #if (TSS_E28_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E28_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 29
        #ifdef TSS_E29_SIGNAL_DIVIDER
          #if (TSS_E29_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E29_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 30
        #ifdef TSS_E30_SIGNAL_DIVIDER
          #if (TSS_E30_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E30_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 31
        #ifdef TSS_E31_SIGNAL_DIVIDER
          #if (TSS_E31_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E31_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 32
        #ifdef TSS_E32_SIGNAL_DIVIDER
          #if (TSS_E32_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E32_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 33
        #ifdef TSS_E33_SIGNAL_DIVIDER
          #if (TSS_E33_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E33_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 34
        #ifdef TSS_E34_SIGNAL_DIVIDER
          #if (TSS_E34_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E34_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 35
        #ifdef TSS_E35_SIGNAL_DIVIDER
          #if (TSS_E35_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E35_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 36
        #ifdef TSS_E36_SIGNAL_DIVIDER
          #if (TSS_E36_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E36_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 37
        #ifdef TSS_E37_SIGNAL_DIVIDER
          #if (TSS_E37_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E37_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 38
        #ifdef TSS_E38_SIGNAL_DIVIDER
          #if (TSS_E38_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E38_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 39
        #ifdef TSS_E39_SIGNAL_DIVIDER
          #if (TSS_E39_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E39_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 40
        #ifdef TSS_E40_SIGNAL_DIVIDER
          #if (TSS_E40_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E40_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 41
        #ifdef TSS_E41_SIGNAL_DIVIDER
          #if (TSS_E41_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E41_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 42
        #ifdef TSS_E42_SIGNAL_DIVIDER
          #if (TSS_E42_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E42_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 43
        #ifdef TSS_E43_SIGNAL_DIVIDER
          #if (TSS_E43_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E43_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 44
        #ifdef TSS_E44_SIGNAL_DIVIDER
          #if (TSS_E44_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E44_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 45
        #ifdef TSS_E45_SIGNAL_DIVIDER
          #if (TSS_E45_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E45_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 46
        #ifdef TSS_E46_SIGNAL_DIVIDER
          #if (TSS_E46_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E46_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 47
        #ifdef TSS_E47_SIGNAL_DIVIDER
          #if (TSS_E47_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E47_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 48
        #ifdef TSS_E48_SIGNAL_DIVIDER
          #if (TSS_E48_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E48_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 49
        #ifdef TSS_E49_SIGNAL_DIVIDER
          #if (TSS_E49_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E49_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 50
        #ifdef TSS_E50_SIGNAL_DIVIDER
          #if (TSS_E50_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E50_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 51
        #ifdef TSS_E51_SIGNAL_DIVIDER
          #if (TSS_E51_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E51_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 52
        #ifdef TSS_E52_SIGNAL_DIVIDER
          #if (TSS_E52_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E52_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 53
        #ifdef TSS_E53_SIGNAL_DIVIDER
          #if (TSS_E53_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E53_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 54
        #ifdef TSS_E54_SIGNAL_DIVIDER
          #if (TSS_E54_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E54_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 55
        #ifdef TSS_E55_SIGNAL_DIVIDER
          #if (TSS_E55_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E55_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 56
        #ifdef TSS_E56_SIGNAL_DIVIDER
          #if (TSS_E56_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E56_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 57
        #ifdef TSS_E57_SIGNAL_DIVIDER
          #if (TSS_E57_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E57_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 58
        #ifdef TSS_E58_SIGNAL_DIVIDER
          #if (TSS_E58_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E58_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 59
        #ifdef TSS_E59_SIGNAL_DIVIDER
          #if (TSS_E59_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E59_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 60
        #ifdef TSS_E60_SIGNAL_DIVIDER
          #if (TSS_E60_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E60_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 61
        #ifdef TSS_E61_SIGNAL_DIVIDER
          #if (TSS_E61_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E61_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 62
        #ifdef TSS_E62_SIGNAL_DIVIDER
          #if (TSS_E62_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E62_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 63
        #ifdef TSS_E63_SIGNAL_DIVIDER
          #if (TSS_E63_SIGNAL_DIVIDER > 255)
            #error "TSS - TSS_E63_SIGNAL_DIVIDER is out of range"
          #endif
        #endif
      #endif
    #endif
  
    #if TSS_USE_SIGNAL_MULTIPLIER
      #if TSS_N_ELECTRODES > 0
        #ifdef TSS_E0_SIGNAL_MULTIPLIER
          #if (TSS_E0_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E0_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 1
        #ifdef TSS_E1_SIGNAL_MULTIPLIER
          #if (TSS_E1_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E1_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 2
        #ifdef TSS_E2_SIGNAL_MULTIPLIER
          #if (TSS_E2_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E2_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 3
        #ifdef TSS_E3_SIGNAL_MULTIPLIER
          #if (TSS_E3_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E3_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 4
        #ifdef TSS_E4_SIGNAL_MULTIPLIER
          #if (TSS_E4_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E4_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 5
        #ifdef TSS_E5_SIGNAL_MULTIPLIER
          #if (TSS_E5_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E5_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 6
        #ifdef TSS_E6_SIGNAL_MULTIPLIER
          #if (TSS_E6_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E6_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 7
        #ifdef TSS_E7_SIGNAL_MULTIPLIER
          #if (TSS_E7_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E7_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 8
        #ifdef TSS_E8_SIGNAL_MULTIPLIER
          #if (TSS_E8_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E8_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 9
        #ifdef TSS_E9_SIGNAL_MULTIPLIER
          #if (TSS_E9_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E9_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 10
        #ifdef TSS_E10_SIGNAL_MULTIPLIER
          #if (TSS_E10_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E10_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 11
        #ifdef TSS_E11_SIGNAL_MULTIPLIER
          #if (TSS_E11_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E11_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 12
        #ifdef TSS_E12_SIGNAL_MULTIPLIER
          #if (TSS_E12_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E12_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 13
        #ifdef TSS_E13_SIGNAL_MULTIPLIER
          #if (TSS_E13_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E13_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 14
        #ifdef TSS_E14_SIGNAL_MULTIPLIER
          #if (TSS_E14_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E14_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 15
        #ifdef TSS_E15_SIGNAL_MULTIPLIER
          #if (TSS_E15_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E15_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 16
        #ifdef TSS_E16_SIGNAL_MULTIPLIER
          #if (TSS_E16_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E16_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 17
        #ifdef TSS_E17_SIGNAL_MULTIPLIER
          #if (TSS_E17_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E17_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 18
        #ifdef TSS_E18_SIGNAL_MULTIPLIER
          #if (TSS_E18_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E18_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 19
        #ifdef TSS_E19_SIGNAL_MULTIPLIER
          #if (TSS_E19_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E19_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 20
        #ifdef TSS_E20_SIGNAL_MULTIPLIER
          #if (TSS_E20_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E20_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 21
        #ifdef TSS_E21_SIGNAL_MULTIPLIER
          #if (TSS_E21_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E21_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 22
        #ifdef TSS_E22_SIGNAL_MULTIPLIER
          #if (TSS_E22_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E22_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 23
        #ifdef TSS_E23_SIGNAL_MULTIPLIER
          #if (TSS_E23_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E23_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 24
        #ifdef TSS_E24_SIGNAL_MULTIPLIER
          #if (TSS_E24_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E24_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 25
        #ifdef TSS_E25_SIGNAL_MULTIPLIER
          #if (TSS_E25_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E25_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 26
        #ifdef TSS_E26_SIGNAL_MULTIPLIER
          #if (TSS_E26_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E26_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 27
        #ifdef TSS_E27_SIGNAL_MULTIPLIER
          #if (TSS_E27_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E27_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 28
        #ifdef TSS_E28_SIGNAL_MULTIPLIER
          #if (TSS_E28_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E28_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 29
        #ifdef TSS_E29_SIGNAL_MULTIPLIER
          #if (TSS_E29_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E29_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 30
        #ifdef TSS_E30_SIGNAL_MULTIPLIER
          #if (TSS_E30_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E30_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 31
        #ifdef TSS_E31_SIGNAL_MULTIPLIER
          #if (TSS_E31_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E31_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 32
        #ifdef TSS_E32_SIGNAL_MULTIPLIER
          #if (TSS_E32_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E32_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 33
        #ifdef TSS_E33_SIGNAL_MULTIPLIER
          #if (TSS_E33_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E33_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 34
        #ifdef TSS_E34_SIGNAL_MULTIPLIER
          #if (TSS_E34_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E34_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 35
        #ifdef TSS_E35_SIGNAL_MULTIPLIER
          #if (TSS_E35_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E35_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 36
        #ifdef TSS_E36_SIGNAL_MULTIPLIER
          #if (TSS_E36_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E36_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 37
        #ifdef TSS_E37_SIGNAL_MULTIPLIER
          #if (TSS_E37_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E37_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 38
        #ifdef TSS_E38_SIGNAL_MULTIPLIER
          #if (TSS_E38_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E38_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 39
        #ifdef TSS_E39_SIGNAL_MULTIPLIER
          #if (TSS_E39_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E39_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 40
        #ifdef TSS_E40_SIGNAL_MULTIPLIER
          #if (TSS_E40_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E40_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 41
        #ifdef TSS_E41_SIGNAL_MULTIPLIER
          #if (TSS_E41_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E41_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 42
        #ifdef TSS_E42_SIGNAL_MULTIPLIER
          #if (TSS_E42_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E42_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 43
        #ifdef TSS_E43_SIGNAL_MULTIPLIER
          #if (TSS_E43_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E43_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 44
        #ifdef TSS_E44_SIGNAL_MULTIPLIER
          #if (TSS_E44_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E44_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 45
        #ifdef TSS_E45_SIGNAL_MULTIPLIER
          #if (TSS_E45_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E45_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 46
        #ifdef TSS_E46_SIGNAL_MULTIPLIER
          #if (TSS_E46_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E46_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 47
        #ifdef TSS_E47_SIGNAL_MULTIPLIER
          #if (TSS_E47_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E47_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 48
        #ifdef TSS_E48_SIGNAL_MULTIPLIER
          #if (TSS_E48_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E48_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 49
        #ifdef TSS_E49_SIGNAL_MULTIPLIER
          #if (TSS_E49_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E49_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 50
        #ifdef TSS_E50_SIGNAL_MULTIPLIER
          #if (TSS_E50_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E50_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 51
        #ifdef TSS_E51_SIGNAL_MULTIPLIER
          #if (TSS_E51_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E51_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 52
        #ifdef TSS_E52_SIGNAL_MULTIPLIER
          #if (TSS_E52_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E52_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 53
        #ifdef TSS_E53_SIGNAL_MULTIPLIER
          #if (TSS_E53_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E53_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 54
        #ifdef TSS_E54_SIGNAL_MULTIPLIER
          #if (TSS_E54_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E54_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 55
        #ifdef TSS_E55_SIGNAL_MULTIPLIER
          #if (TSS_E55_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E55_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 56
        #ifdef TSS_E56_SIGNAL_MULTIPLIER
          #if (TSS_E56_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E56_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 57
        #ifdef TSS_E57_SIGNAL_MULTIPLIER
          #if (TSS_E57_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E57_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 58
        #ifdef TSS_E58_SIGNAL_MULTIPLIER
          #if (TSS_E58_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E58_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 59
        #ifdef TSS_E59_SIGNAL_MULTIPLIER
          #if (TSS_E59_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E59_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 60
        #ifdef TSS_E60_SIGNAL_MULTIPLIER
          #if (TSS_E60_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E60_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 61
        #ifdef TSS_E61_SIGNAL_MULTIPLIER
          #if (TSS_E61_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E61_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 62
        #ifdef TSS_E62_SIGNAL_MULTIPLIER
          #if (TSS_E62_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E62_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
      #if TSS_N_ELECTRODES > 63
        #ifdef TSS_E63_SIGNAL_MULTIPLIER
          #if (TSS_E63_SIGNAL_MULTIPLIER > 255) 
            #error "TSS - TSS_E63_SIGNAL_MULTIPLIER is out of range"
          #endif
        #endif
      #endif
    #endif

    #ifndef TSS_N_CONTROLS
        #error "TSS - Not defined TSS_N_CONTROLS"
    #endif 
   
    #ifndef TSS_N_ELECTRODES
        #error "TSS - Not defined TSS_N_ELECTRODES"
    #endif

    #if (TSS_N_ELECTRODES < 1)
        #error "TSS - At least one electrode must be used"
    #elif (TSS_N_ELECTRODES > 64)
        #error "TSS - Maximum number of electrodes exceeded"
    #endif

    #if TSS_N_CONTROLS == 1
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 2
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 3
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 4
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 5
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 6
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 7
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 8
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 9
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES + TSS_C8_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 10
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES + TSS_C8_ELECTRODES + TSS_C9_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 11
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES + TSS_C8_ELECTRODES + TSS_C9_ELECTRODES + TSS_C10_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 12
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES + TSS_C8_ELECTRODES + TSS_C9_ELECTRODES + TSS_C10_ELECTRODES + TSS_C11_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 13
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES + TSS_C8_ELECTRODES + TSS_C9_ELECTRODES + TSS_C10_ELECTRODES + TSS_C11_ELECTRODES + TSS_C12_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 14
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES + TSS_C8_ELECTRODES + TSS_C9_ELECTRODES + TSS_C10_ELECTRODES + TSS_C11_ELECTRODES + TSS_C12_ELECTRODES + TSS_C13_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 15
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES + TSS_C8_ELECTRODES + TSS_C9_ELECTRODES + TSS_C10_ELECTRODES + TSS_C11_ELECTRODES + TSS_C12_ELECTRODES + TSS_C13_ELECTRODES + TSS_C14_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    #if TSS_N_CONTROLS == 16
        #if (TSS_N_ELECTRODES != (TSS_C0_ELECTRODES + TSS_C1_ELECTRODES + TSS_C2_ELECTRODES + TSS_C3_ELECTRODES + TSS_C4_ELECTRODES + TSS_C5_ELECTRODES + TSS_C6_ELECTRODES + TSS_C7_ELECTRODES + TSS_C8_ELECTRODES + TSS_C9_ELECTRODES + TSS_C10_ELECTRODES + TSS_C11_ELECTRODES + TSS_C12_ELECTRODES + TSS_C13_ELECTRODES + TSS_C14_ELECTRODES + TSS_C15_ELECTRODES))
            #error "TSS - Electrodes sumatory assigned to the controls doesn't match with the TSS_N_ELECTRODES"
        #endif
    #endif
    
    #if ((TSS_N_CONTROLS >= 0) && (TSS_N_CONTROLS < 17))
        #if TSS_N_CONTROLS > 0
            #ifndef TSS_C0_TYPE
                #error "TSS - Not defined TSS_C0_TYPE"
            #endif
            #ifndef TSS_C0_STRUCTURE
                #error "TSS - Not defined TSS_C0_STRUCTURE"
            #endif
            #ifndef TSS_C0_CALLBACK
                #error "TSS - Not defined TSS_C0_CALLBACK"
            #endif
            #if ((TSS_C0_TYPE < TSS_CT_KEYPAD) || (TSS_C0_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C0"
            #else
              #if (TSS_C0_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C0_ELECTRODES_X
                  #error "TSS - Not defined TSS_C0_ELECTRODES_X"
                #else
                  #if ((TSS_C0_ELECTRODES_X < 2) || (TSS_C0_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C0"
                  #endif
                #endif
                #ifndef TSS_C0_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C0_ELECTRODES_Y"
                #else
                  #if ((TSS_C0_ELECTRODES_Y < 2) || (TSS_C0_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C0"
                  #endif
                #endif
                #if defined(TSS_C0_ELECTRODES_X) && defined(TSS_C0_ELECTRODES_Y)
                  #if ((TSS_C0_ELECTRODES_X + TSS_C0_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C0"
                  #endif
                #endif
              #else
                #ifndef TSS_C0_ELECTRODES
                  #error "TSS - Not defined TSS_C0_ELECTRODES"
                #else
                  #if (TSS_C0_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C0"
                  #elif (TSS_C0_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C0"
                  #elif ((TSS_C0_TYPE == TSS_CT_SLIDER) && (TSS_C0_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C0"
                  #elif ((TSS_C0_TYPE == TSS_CT_ROTARY) && (TSS_C0_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C0"
                  #elif ((TSS_C0_TYPE == TSS_CT_ASLIDER) && (TSS_C0_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C0"
                  #elif ((TSS_C0_TYPE == TSS_CT_AROTARY) && (TSS_C0_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C0"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 1
            #ifndef TSS_C1_TYPE
                #error "TSS - Not defined TSS_C1_TYPE"
            #endif
            #ifndef TSS_C1_STRUCTURE
                #error "TSS - Not defined TSS_C1_STRUCTURE"
            #endif
            #ifndef TSS_C1_CALLBACK
                #error "TSS - Not defined TSS_C1_CALLBACK"
            #endif
            #if ((TSS_C1_TYPE < TSS_CT_KEYPAD) || (TSS_C1_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C1"
            #else
              #if (TSS_C1_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C1_ELECTRODES_X
                  #error "TSS - Not defined TSS_C1_ELECTRODES_X"
                #else
                  #if ((TSS_C1_ELECTRODES_X < 2) || (TSS_C1_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C1"
                  #endif
                #endif
                #ifndef TSS_C1_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C1_ELECTRODES_Y"
                #else
                  #if ((TSS_C1_ELECTRODES_Y < 2) || (TSS_C1_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C1"
                  #endif
                #endif
                #if defined(TSS_C1_ELECTRODES_X) && defined(TSS_C1_ELECTRODES_Y)
                  #if ((TSS_C1_ELECTRODES_X + TSS_C1_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C1"
                  #endif
                #endif
              #else
                #ifndef TSS_C1_ELECTRODES
                  #error "TSS - Not defined TSS_C1_ELECTRODES"
                #else
                  #if (TSS_C1_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C1"
                  #elif (TSS_C1_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C1"
                  #elif ((TSS_C1_TYPE == TSS_CT_SLIDER) && (TSS_C1_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C1"
                  #elif ((TSS_C1_TYPE == TSS_CT_ROTARY) && (TSS_C1_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C1"
                  #elif ((TSS_C1_TYPE == TSS_CT_ASLIDER) && (TSS_C1_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C1"
                  #elif ((TSS_C1_TYPE == TSS_CT_AROTARY) && (TSS_C1_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C1"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 2
            #ifndef TSS_C2_TYPE
                #error "TSS - Not defined TSS_C2_TYPE"
            #endif
            #ifndef TSS_C2_STRUCTURE
                #error "TSS - Not defined TSS_C2_STRUCTURE"
            #endif
            #ifndef TSS_C2_CALLBACK
                #error "TSS - Not defined TSS_C2_CALLBACK"
            #endif
            #if ((TSS_C2_TYPE < TSS_CT_KEYPAD) || (TSS_C2_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C2"
            #else
              #if (TSS_C2_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C2_ELECTRODES_X
                  #error "TSS - Not defined TSS_C2_ELECTRODES_X"
                #else
                  #if ((TSS_C2_ELECTRODES_X < 2) || (TSS_C2_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C2"
                  #endif
                #endif
                #ifndef TSS_C2_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C2_ELECTRODES_Y"
                #else
                  #if ((TSS_C2_ELECTRODES_Y < 2) || (TSS_C2_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C2"
                  #endif
                #endif
                #if defined(TSS_C2_ELECTRODES_X) && defined(TSS_C2_ELECTRODES_Y)
                  #if ((TSS_C2_ELECTRODES_X + TSS_C2_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C2"
                  #endif
                #endif
              #else
                #ifndef TSS_C2_ELECTRODES
                  #error "TSS - Not defined TSS_C2_ELECTRODES"
                #else
                  #if (TSS_C2_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C2"
                  #elif (TSS_C2_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C2"
                  #elif ((TSS_C2_TYPE == TSS_CT_SLIDER) && (TSS_C2_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C2"
                  #elif ((TSS_C2_TYPE == TSS_CT_ROTARY) && (TSS_C2_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C2"
                  #elif ((TSS_C2_TYPE == TSS_CT_ASLIDER) && (TSS_C2_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C2"
                  #elif ((TSS_C2_TYPE == TSS_CT_AROTARY) && (TSS_C2_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C2"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 3
            #ifndef TSS_C3_TYPE
                #error "TSS - Not defined TSS_C3_TYPE"
            #endif
            #ifndef TSS_C3_STRUCTURE
                #error "TSS - Not defined TSS_C3_STRUCTURE"
            #endif
            #ifndef TSS_C3_CALLBACK
                #error "TSS - Not defined TSS_C3_CALLBACK"
            #endif
            #if ((TSS_C3_TYPE < TSS_CT_KEYPAD) || (TSS_C3_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C3"
            #else
              #if (TSS_C3_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C3_ELECTRODES_X
                  #error "TSS - Not defined TSS_C3_ELECTRODES_X"
                #else
                  #if ((TSS_C3_ELECTRODES_X < 2) || (TSS_C3_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C3"
                  #endif
                #endif
                #ifndef TSS_C3_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C3_ELECTRODES_Y"
                #else
                  #if ((TSS_C3_ELECTRODES_Y < 2) || (TSS_C3_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C3"
                  #endif
                #endif
                #if defined(TSS_C3_ELECTRODES_X) && defined(TSS_C3_ELECTRODES_Y)
                  #if ((TSS_C3_ELECTRODES_X + TSS_C3_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C3"
                  #endif
                #endif
              #else
                #ifndef TSS_C3_ELECTRODES
                  #error "TSS - Not defined TSS_C3_ELECTRODES"
                #else
                  #if (TSS_C3_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C3"
                  #elif (TSS_C3_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C3"
                  #elif ((TSS_C3_TYPE == TSS_CT_SLIDER) && (TSS_C3_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C3"
                  #elif ((TSS_C3_TYPE == TSS_CT_ROTARY) && (TSS_C3_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C3"
                  #elif ((TSS_C3_TYPE == TSS_CT_ASLIDER) && (TSS_C3_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C3"
                  #elif ((TSS_C3_TYPE == TSS_CT_AROTARY) && (TSS_C3_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C3"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 4
            #ifndef TSS_C4_TYPE
                #error "TSS - Not defined TSS_C4_TYPE"
            #endif
            #ifndef TSS_C4_STRUCTURE
                #error "TSS - Not defined TSS_C4_STRUCTURE"
            #endif
            #ifndef TSS_C4_CALLBACK
                #error "TSS - Not defined TSS_C4_CALLBACK"
            #endif
            #if ((TSS_C4_TYPE < TSS_CT_KEYPAD) || (TSS_C4_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C4"
            #else
              #if (TSS_C4_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C4_ELECTRODES_X
                  #error "TSS - Not defined TSS_C4_ELECTRODES_X"
                #else
                  #if ((TSS_C4_ELECTRODES_X < 2) || (TSS_C4_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C4"
                  #endif
                #endif
                #ifndef TSS_C4_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C4_ELECTRODES_Y"
                #else
                  #if ((TSS_C4_ELECTRODES_Y < 2) || (TSS_C4_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C4"
                  #endif
                #endif
                #if defined(TSS_C4_ELECTRODES_X) && defined(TSS_C4_ELECTRODES_Y)
                  #if ((TSS_C4_ELECTRODES_X + TSS_C4_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C4"
                  #endif
                #endif
              #else
                #ifndef TSS_C4_ELECTRODES
                  #error "TSS - Not defined TSS_C4_ELECTRODES"
                #else
                  #if (TSS_C4_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C4"
                  #elif (TSS_C4_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C4"
                  #elif ((TSS_C4_TYPE == TSS_CT_SLIDER) && (TSS_C4_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C4"
                  #elif ((TSS_C4_TYPE == TSS_CT_ROTARY) && (TSS_C4_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C4"
                  #elif ((TSS_C4_TYPE == TSS_CT_ASLIDER) && (TSS_C4_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C4"
                  #elif ((TSS_C4_TYPE == TSS_CT_AROTARY) && (TSS_C4_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C4"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 5
            #ifndef TSS_C5_TYPE
                #error "TSS - Not defined TSS_C5_TYPE"
            #endif
            #ifndef TSS_C5_STRUCTURE
                #error "TSS - Not defined TSS_C5_STRUCTURE"
            #endif
            #ifndef TSS_C5_CALLBACK
                #error "TSS - Not defined TSS_C5_CALLBACK"
            #endif
            #if ((TSS_C5_TYPE < TSS_CT_KEYPAD) || (TSS_C5_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C5"
            #else
              #if (TSS_C5_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C5_ELECTRODES_X
                  #error "TSS - Not defined TSS_C5_ELECTRODES_X"
                #else
                  #if ((TSS_C5_ELECTRODES_X < 2) || (TSS_C5_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C5"
                  #endif
                #endif
                #ifndef TSS_C5_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C5_ELECTRODES_Y"
                #else
                  #if ((TSS_C5_ELECTRODES_Y < 2) || (TSS_C5_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C5"
                  #endif
                #endif
                #if defined(TSS_C5_ELECTRODES_X) && defined(TSS_C5_ELECTRODES_Y)
                  #if ((TSS_C5_ELECTRODES_X + TSS_C5_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C5"
                  #endif
                #endif
              #else
                #ifndef TSS_C5_ELECTRODES
                  #error "TSS - Not defined TSS_C5_ELECTRODES"
                #else
                  #if (TSS_C5_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C5"
                  #elif (TSS_C5_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C5"
                  #elif ((TSS_C5_TYPE == TSS_CT_SLIDER) && (TSS_C5_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C5"
                  #elif ((TSS_C5_TYPE == TSS_CT_ROTARY) && (TSS_C5_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C5"
                  #elif ((TSS_C5_TYPE == TSS_CT_ASLIDER) && (TSS_C5_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C5"
                  #elif ((TSS_C5_TYPE == TSS_CT_AROTARY) && (TSS_C5_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C5"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 6
            #ifndef TSS_C6_TYPE
                #error "TSS - Not defined TSS_C6_TYPE"
            #endif
            #ifndef TSS_C6_STRUCTURE
                #error "TSS - Not defined TSS_C6_STRUCTURE"
            #endif
            #ifndef TSS_C6_CALLBACK
                #error "TSS - Not defined TSS_C6_CALLBACK"
            #endif
            #if ((TSS_C6_TYPE < TSS_CT_KEYPAD) || (TSS_C6_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C6"
            #else
              #if (TSS_C6_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C6_ELECTRODES_X
                  #error "TSS - Not defined TSS_C6_ELECTRODES_X"
                #else
                  #if ((TSS_C6_ELECTRODES_X < 2) || (TSS_C6_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C6"
                  #endif
                #endif
                #ifndef TSS_C6_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C6_ELECTRODES_Y"
                #else
                  #if ((TSS_C6_ELECTRODES_Y < 2) || (TSS_C6_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C6"
                  #endif
                #endif
                #if defined(TSS_C6_ELECTRODES_X) && defined(TSS_C6_ELECTRODES_Y)
                  #if ((TSS_C6_ELECTRODES_X + TSS_C6_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C6"
                  #endif
                #endif
              #else
                #ifndef TSS_C6_ELECTRODES
                  #error "TSS - Not defined TSS_C6_ELECTRODES"
                #else
                  #if (TSS_C6_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C6"
                  #elif (TSS_C6_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C6"
                  #elif ((TSS_C6_TYPE == TSS_CT_SLIDER) && (TSS_C6_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C6"
                  #elif ((TSS_C6_TYPE == TSS_CT_ROTARY) && (TSS_C6_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C6"
                  #elif ((TSS_C6_TYPE == TSS_CT_ASLIDER) && (TSS_C6_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C6"
                  #elif ((TSS_C6_TYPE == TSS_CT_AROTARY) && (TSS_C6_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C6"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 7
            #ifndef TSS_C7_TYPE
                #error "TSS - Not defined TSS_C7_TYPE"
            #endif
            #ifndef TSS_C7_STRUCTURE
                #error "TSS - Not defined TSS_C7_STRUCTURE"
            #endif
            #ifndef TSS_C7_CALLBACK
                #error "TSS - Not defined TSS_C7_CALLBACK"
            #endif
            #if ((TSS_C7_TYPE < TSS_CT_KEYPAD) || (TSS_C7_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C7"
            #else
              #if (TSS_C7_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C7_ELECTRODES_X
                  #error "TSS - Not defined TSS_C7_ELECTRODES_X"
                #else
                  #if ((TSS_C7_ELECTRODES_X < 2) || (TSS_C7_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C7"
                  #endif
                #endif
                #ifndef TSS_C7_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C7_ELECTRODES_Y"
                #else
                  #if ((TSS_C7_ELECTRODES_Y < 2) || (TSS_C7_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C7"
                  #endif
                #endif
                #if defined(TSS_C7_ELECTRODES_X) && defined(TSS_C7_ELECTRODES_Y)
                  #if ((TSS_C7_ELECTRODES_X + TSS_C7_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C7"
                  #endif
                #endif
              #else
                #ifndef TSS_C7_ELECTRODES
                  #error "TSS - Not defined TSS_C7_ELECTRODES"
                #else
                  #if (TSS_C7_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C7"
                  #elif (TSS_C7_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C7"
                  #elif ((TSS_C7_TYPE == TSS_CT_SLIDER) && (TSS_C7_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C7"
                  #elif ((TSS_C7_TYPE == TSS_CT_ROTARY) && (TSS_C7_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C7"
                  #elif ((TSS_C7_TYPE == TSS_CT_ASLIDER) && (TSS_C7_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C7"
                  #elif ((TSS_C7_TYPE == TSS_CT_AROTARY) && (TSS_C7_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C7"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 8
            #ifndef TSS_C8_TYPE
                #error "TSS - Not defined TSS_C8_TYPE"
            #endif
            #ifndef TSS_C8_STRUCTURE
                #error "TSS - Not defined TSS_C8_STRUCTURE"
            #endif
            #ifndef TSS_C8_CALLBACK
                #error "TSS - Not defined TSS_C8_CALLBACK"
            #endif
            #if ((TSS_C8_TYPE < TSS_CT_KEYPAD) || (TSS_C8_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C8"
            #else
              #if (TSS_C8_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C8_ELECTRODES_X
                  #error "TSS - Not defined TSS_C8_ELECTRODES_X"
                #else
                  #if ((TSS_C8_ELECTRODES_X < 2) || (TSS_C8_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C8"
                  #endif
                #endif
                #ifndef TSS_C8_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C8_ELECTRODES_Y"
                #else
                  #if ((TSS_C8_ELECTRODES_Y < 2) || (TSS_C8_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C8"
                  #endif
                #endif
                #if defined(TSS_C8_ELECTRODES_X) && defined(TSS_C8_ELECTRODES_Y)
                  #if ((TSS_C8_ELECTRODES_X + TSS_C8_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C8"
                  #endif
                #endif
              #else
                #ifndef TSS_C8_ELECTRODES
                  #error "TSS - Not defined TSS_C8_ELECTRODES"
                #else
                  #if (TSS_C8_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C8"
                  #elif (TSS_C8_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C8"
                  #elif ((TSS_C8_TYPE == TSS_CT_SLIDER) && (TSS_C8_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C8"
                  #elif ((TSS_C8_TYPE == TSS_CT_ROTARY) && (TSS_C8_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C8"
                  #elif ((TSS_C8_TYPE == TSS_CT_ASLIDER) && (TSS_C8_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C8"
                  #elif ((TSS_C8_TYPE == TSS_CT_AROTARY) && (TSS_C8_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C8"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 9
            #ifndef TSS_C9_TYPE
                #error "TSS - Not defined TSS_C9_TYPE"
            #endif
            #ifndef TSS_C9_STRUCTURE
                #error "TSS - Not defined TSS_C9_STRUCTURE"
            #endif
            #ifndef TSS_C9_CALLBACK
                #error "TSS - Not defined TSS_C9_CALLBACK"
            #endif
            #if ((TSS_C9_TYPE < TSS_CT_KEYPAD) || (TSS_C9_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C9"
            #else
              #if (TSS_C9_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C9_ELECTRODES_X
                  #error "TSS - Not defined TSS_C9_ELECTRODES_X"
                #else
                  #if ((TSS_C9_ELECTRODES_X < 2) || (TSS_C9_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C9"
                  #endif
                #endif
                #ifndef TSS_C9_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C9_ELECTRODES_Y"
                #else
                  #if ((TSS_C9_ELECTRODES_Y < 2) || (TSS_C9_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C9"
                  #endif
                #endif
                #if defined(TSS_C9_ELECTRODES_X) && defined(TSS_C9_ELECTRODES_Y)
                  #if ((TSS_C9_ELECTRODES_X + TSS_C9_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C9"
                  #endif
                #endif
              #else
                #ifndef TSS_C9_ELECTRODES
                  #error "TSS - Not defined TSS_C9_ELECTRODES"
                #else
                  #if (TSS_C9_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C9"
                  #elif (TSS_C9_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C9"
                  #elif ((TSS_C9_TYPE == TSS_CT_SLIDER) && (TSS_C9_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C9"
                  #elif ((TSS_C9_TYPE == TSS_CT_ROTARY) && (TSS_C9_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C9"
                  #elif ((TSS_C9_TYPE == TSS_CT_ASLIDER) && (TSS_C9_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C9"
                  #elif ((TSS_C9_TYPE == TSS_CT_AROTARY) && (TSS_C9_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C9"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 10
            #ifndef TSS_C10_TYPE
                #error "TSS - Not defined TSS_C10_TYPE"
            #endif
            #ifndef TSS_C10_STRUCTURE
                #error "TSS - Not defined TSS_C10_STRUCTURE"
            #endif
            #ifndef TSS_C10_CALLBACK
                #error "TSS - Not defined TSS_C10_CALLBACK"
            #endif
            #if ((TSS_C10_TYPE < TSS_CT_KEYPAD) || (TSS_C10_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C10"
            #else
              #if (TSS_C10_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C10_ELECTRODES_X
                  #error "TSS - Not defined TSS_C10_ELECTRODES_X"
                #else
                  #if ((TSS_C10_ELECTRODES_X < 2) || (TSS_C10_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C10"
                  #endif
                #endif
                #ifndef TSS_C10_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C10_ELECTRODES_Y"
                #else
                  #if ((TSS_C10_ELECTRODES_Y < 2) || (TSS_C10_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C10"
                  #endif
                #endif
                #if defined(TSS_C10_ELECTRODES_X) && defined(TSS_C10_ELECTRODES_Y)
                  #if ((TSS_C10_ELECTRODES_X + TSS_C10_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C10"
                  #endif
                #endif
              #else
                #ifndef TSS_C10_ELECTRODES
                  #error "TSS - Not defined TSS_C10_ELECTRODES"
                #else
                  #if (TSS_C10_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C10"
                  #elif (TSS_C10_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C10"
                  #elif ((TSS_C10_TYPE == TSS_CT_SLIDER) && (TSS_C10_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C10"
                  #elif ((TSS_C10_TYPE == TSS_CT_ROTARY) && (TSS_C10_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C10"
                  #elif ((TSS_C10_TYPE == TSS_CT_ASLIDER) && (TSS_C10_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C10"
                  #elif ((TSS_C10_TYPE == TSS_CT_AROTARY) && (TSS_C10_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C10"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 11
            #ifndef TSS_C11_TYPE
                #error "TSS - Not defined TSS_C11_TYPE"
            #endif
            #ifndef TSS_C11_STRUCTURE
                #error "TSS - Not defined TSS_C11_STRUCTURE"
            #endif
            #ifndef TSS_C11_CALLBACK
                #error "TSS - Not defined TSS_C11_CALLBACK"
            #endif
            #if ((TSS_C11_TYPE < TSS_CT_KEYPAD) || (TSS_C11_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C11"
            #else
              #if (TSS_C11_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C11_ELECTRODES_X
                  #error "TSS - Not defined TSS_C11_ELECTRODES_X"
                #else
                  #if ((TSS_C11_ELECTRODES_X < 2) || (TSS_C11_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C11"
                  #endif
                #endif
                #ifndef TSS_C11_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C11_ELECTRODES_Y"
                #else
                  #if ((TSS_C11_ELECTRODES_Y < 2) || (TSS_C11_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C11"
                  #endif
                #endif
                #if defined(TSS_C11_ELECTRODES_X) && defined(TSS_C11_ELECTRODES_Y)
                  #if ((TSS_C11_ELECTRODES_X + TSS_C11_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C11"
                  #endif
                #endif
              #else
                #ifndef TSS_C11_ELECTRODES
                  #error "TSS - Not defined TSS_C11_ELECTRODES"
                #else
                  #if (TSS_C11_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C11"
                  #elif (TSS_C11_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C11"
                  #elif ((TSS_C11_TYPE == TSS_CT_SLIDER) && (TSS_C11_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C11"
                  #elif ((TSS_C11_TYPE == TSS_CT_ROTARY) && (TSS_C11_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C11"
                  #elif ((TSS_C11_TYPE == TSS_CT_ASLIDER) && (TSS_C11_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C11"
                  #elif ((TSS_C11_TYPE == TSS_CT_AROTARY) && (TSS_C11_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C11"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 12
            #ifndef TSS_C12_TYPE
                #error "TSS - Not defined TSS_C12_TYPE"
            #endif
            #ifndef TSS_C12_STRUCTURE
                #error "TSS - Not defined TSS_C12_STRUCTURE"
            #endif
            #ifndef TSS_C12_CALLBACK
                #error "TSS - Not defined TSS_C12_CALLBACK"
            #endif
            #if ((TSS_C12_TYPE < TSS_CT_KEYPAD) || (TSS_C12_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C12"
            #else
              #if (TSS_C12_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C12_ELECTRODES_X
                  #error "TSS - Not defined TSS_C12_ELECTRODES_X"
                #else
                  #if ((TSS_C12_ELECTRODES_X < 2) || (TSS_C12_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C12"
                  #endif
                #endif
                #ifndef TSS_C12_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C12_ELECTRODES_Y"
                #else
                  #if ((TSS_C12_ELECTRODES_Y < 2) || (TSS_C12_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C12"
                  #endif
                #endif
                #if defined(TSS_C12_ELECTRODES_X) && defined(TSS_C12_ELECTRODES_Y)
                  #if ((TSS_C12_ELECTRODES_X + TSS_C12_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C12"
                  #endif
                #endif
              #else
                #ifndef TSS_C12_ELECTRODES
                  #error "TSS - Not defined TSS_C12_ELECTRODES"
                #else
                  #if (TSS_C12_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C12"
                  #elif (TSS_C12_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C12"
                  #elif ((TSS_C12_TYPE == TSS_CT_SLIDER) && (TSS_C12_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C12"
                  #elif ((TSS_C12_TYPE == TSS_CT_ROTARY) && (TSS_C12_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C12"
                  #elif ((TSS_C12_TYPE == TSS_CT_ASLIDER) && (TSS_C12_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C12"
                  #elif ((TSS_C12_TYPE == TSS_CT_AROTARY) && (TSS_C12_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C12"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 13
            #ifndef TSS_C13_TYPE
                #error "TSS - Not defined TSS_C13_TYPE"
            #endif
            #ifndef TSS_C13_STRUCTURE
                #error "TSS - Not defined TSS_C13_STRUCTURE"
            #endif
            #ifndef TSS_C13_CALLBACK
                #error "TSS - Not defined TSS_C13_CALLBACK"
            #endif
            #if ((TSS_C13_TYPE < TSS_CT_KEYPAD) || (TSS_C13_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C13"
            #else
              #if (TSS_C13_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C13_ELECTRODES_X
                  #error "TSS - Not defined TSS_C13_ELECTRODES_X"
                #else
                  #if ((TSS_C13_ELECTRODES_X < 2) || (TSS_C13_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C13"
                  #endif
                #endif
                #ifndef TSS_C13_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C13_ELECTRODES_Y"
                #else
                  #if ((TSS_C13_ELECTRODES_Y < 2) || (TSS_C13_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C13"
                  #endif
                #endif
                #if defined(TSS_C13_ELECTRODES_X) && defined(TSS_C13_ELECTRODES_Y)
                  #if ((TSS_C13_ELECTRODES_X + TSS_C13_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C13"
                  #endif
                #endif
              #else
                #ifndef TSS_C13_ELECTRODES
                  #error "TSS - Not defined TSS_C13_ELECTRODES"
                #else
                  #if (TSS_C13_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C13"
                  #elif (TSS_C13_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C13"
                  #elif ((TSS_C13_TYPE == TSS_CT_SLIDER) && (TSS_C13_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C13"
                  #elif ((TSS_C13_TYPE == TSS_CT_ROTARY) && (TSS_C13_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C13"
                  #elif ((TSS_C13_TYPE == TSS_CT_ASLIDER) && (TSS_C13_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C13"
                  #elif ((TSS_C13_TYPE == TSS_CT_AROTARY) && (TSS_C13_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C13"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 14
            #ifndef TSS_C14_TYPE
                #error "TSS - Not defined TSS_C14_TYPE"
            #endif
            #ifndef TSS_C14_STRUCTURE
                #error "TSS - Not defined TSS_C14_STRUCTURE"
            #endif
            #ifndef TSS_C14_CALLBACK
                #error "TSS - Not defined TSS_C14_CALLBACK"
            #endif
            #if ((TSS_C14_TYPE < TSS_CT_KEYPAD) || (TSS_C14_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C14"
            #else
              #if (TSS_C14_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C14_ELECTRODES_X
                  #error "TSS - Not defined TSS_C14_ELECTRODES_X"
                #else
                  #if ((TSS_C14_ELECTRODES_X < 2) || (TSS_C14_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C14"
                  #endif
                #endif
                #ifndef TSS_C14_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C14_ELECTRODES_Y"
                #else
                  #if ((TSS_C14_ELECTRODES_Y < 2) || (TSS_C14_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C14"
                  #endif
                #endif
                #if defined(TSS_C14_ELECTRODES_X) && defined(TSS_C14_ELECTRODES_Y)
                  #if ((TSS_C14_ELECTRODES_X + TSS_C14_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C14"
                  #endif
                #endif
              #else
                #ifndef TSS_C14_ELECTRODES
                  #error "TSS - Not defined TSS_C14_ELECTRODES"
                #else
                  #if (TSS_C14_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C14"
                  #elif (TSS_C14_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C14"
                  #elif ((TSS_C14_TYPE == TSS_CT_SLIDER) && (TSS_C14_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C14"
                  #elif ((TSS_C14_TYPE == TSS_CT_ROTARY) && (TSS_C14_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C14"
                  #elif ((TSS_C14_TYPE == TSS_CT_ASLIDER) && (TSS_C14_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C14"
                  #elif ((TSS_C14_TYPE == TSS_CT_AROTARY) && (TSS_C14_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C14"
                  #endif
                #endif
              #endif
            #endif
        #endif

        #if TSS_N_CONTROLS > 15
            #ifndef TSS_C15_TYPE
                #error "TSS - Not defined TSS_C15_TYPE"
            #endif
            #ifndef TSS_C15_STRUCTURE
                #error "TSS - Not defined TSS_C15_STRUCTURE"
            #endif
            #ifndef TSS_C15_CALLBACK
                #error "TSS - Not defined TSS_C15_CALLBACK"
            #endif
            #if ((TSS_C15_TYPE < TSS_CT_KEYPAD) || (TSS_C15_TYPE > TSS_CT_MATRIX))
                #error "TSS - Invalid control type for C15"
            #else
              #if (TSS_C15_TYPE == TSS_CT_MATRIX)
                #ifndef TSS_C15_ELECTRODES_X
                  #error "TSS - Not defined TSS_C15_ELECTRODES_X"
                #else
                  #if ((TSS_C15_ELECTRODES_X < 2) || (TSS_C15_ELECTRODES_X > 16))
                    #error "TSS - Invalid Electrode X axis quantity for C15"
                  #endif
                #endif
                #ifndef TSS_C15_ELECTRODES_Y
                  #error "TSS - Not defined TSS_C15_ELECTRODES_Y"
                #else
                  #if ((TSS_C15_ELECTRODES_Y < 2) || (TSS_C15_ELECTRODES_Y > 16))
                    #error "TSS - Invalid Electrode Y axis quantity for C15"
                  #endif
                #endif
                #if defined(TSS_C15_ELECTRODES_X) && defined(TSS_C15_ELECTRODES_Y)
                  #if ((TSS_C15_ELECTRODES_X + TSS_C15_ELECTRODES_Y) > 16)
                    #error "TSS - Invalid Electrode sumatory of X and Y axis for C15"
                  #endif
                #endif
              #else
                #ifndef TSS_C15_ELECTRODES
                  #error "TSS - Not defined TSS_C15_ELECTRODES"
                #else
                  #if (TSS_C15_ELECTRODES < 1)
                    #error "TSS - At least one electrode must be used at C15"
                  #elif (TSS_C15_ELECTRODES > 16)
                    #error "TSS - Maximum number of electrodes exceeded at C15"
                  #elif ((TSS_C15_TYPE == TSS_CT_SLIDER) && (TSS_C15_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C15"
                  #elif ((TSS_C15_TYPE == TSS_CT_ROTARY) && (TSS_C15_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C15"
                  #elif ((TSS_C15_TYPE == TSS_CT_ASLIDER) && (TSS_C15_ELECTRODES < 2))
                    #error "TSS - Invalid Electrode quantity for C15"
                  #elif ((TSS_C15_TYPE == TSS_CT_AROTARY) && (TSS_C15_ELECTRODES < 3))
                    #error "TSS - Invalid Electrode quantity for C15"
                  #endif
                #endif
              #endif
            #endif
        #endif
    #else
        #error "TSS - Invalid number of controls"    
    #endif

    /**************************************************************************************
    *                            Validation of trigger settings
    **************************************************************************************/
  
    #if (TSS_AUTOTRIGGER_SOURCE_USED && TSS_USE_TRIGGER_FUNCTION)
      #if TSS_DETECT_AUTOTRIGGER_SOURCE_USAGE(RTC)
        #if ((TSS_HCS08_MCU == 1) && (TSS_USE_SIMPLE_LOW_LEVEL == 1))
          #error "TSS - TSS_USE_AUTOTRIGGER_SOURCE is set to invalid value. RTC auto-trigger is not usable for TSS_USE_SIMPLE_LOW_LEVEL = 1 on the MCU "
        #elif !((TSS_HCS08_MCU == 1) && (TSS_USE_SIMPLE_LOW_LEVEL == 0)) && !((TSS_KINETIS_MCU == 1) && (TSS_USE_SIMPLE_LOW_LEVEL == 0)) 
          #error "TSS - TSS_USE_AUTOTRIGGER_SOURCE is set to invalid value. RTC auto-trigger is not usable on the MCU."
        #endif
      #endif
    #endif


#endif  /* TSS_SYSTEMSETUPVAL_H */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ghbname.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ghbname.c$
* $Version : 3.6.13.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the gethostbyname() function.
*
*END************************************************************************/

#include <string.h>
#include <rtcs.h>

static boolean RTCS_get_dotted_address (char_ptr name, uint_32_ptr address)
{
   uint_32                     i;
   uint_32                     digit_count = 0;
   uint_32                     dot_count = 0;
   int_32                      byte_num;
   boolean                     dotted_decimal = TRUE;
   
   if ((name == NULL) || (address == NULL)) return FALSE;
   
   *address = 0;
   
   for (i=0; name[i] != '\0'; ++i ) {
      if ( name[i] == '.' ) {
         dot_count++;
         if ( dot_count > 3 ) {
            /* invalid IP address */
            dotted_decimal = FALSE;
            break;
         }/* Endif */

         if ( digit_count == 0 ) {
            /* there are no digits before the '.' */
            dotted_decimal = FALSE;
            break;
         }/* Endif */
         digit_count = 0;
         byte_num = byte_num / 10; /* shift back */

         if ( (byte_num < 0 ) || (byte_num > 255) ) {
         /* if the number does fall within this range it's invalid */
            dotted_decimal = FALSE;
            break;
         } else  {
            *address = (*address) + byte_num;
            *address = (*address) * 0x100;
         }/* Endif */
      } else { /* a digit */

         if ( digit_count == 0 ) {
            byte_num = 0;
         }/* Endif */
         ++digit_count;

         if ( digit_count > 3 ) {
            /* too many digits between the '.' */
            dotted_decimal = FALSE;
            break;
         }/* Endif */

         if ( (name[i] >= '0') && (name[i] <= '9') ) {
            /* number is in range */
            byte_num = byte_num + name[i] - '0';
            byte_num = byte_num * 10;
         } else {
            /* if the characters are not decimal digits it's invalid */
            dotted_decimal = FALSE;
            break;
         }/* Endif */
      }/* Endif */
   } /* Endfor */

   if ( dotted_decimal ) { /* check last number */
      if ( digit_count == 0 ) {
         /* there are no digits before the '.' */
         dotted_decimal = FALSE;
      }/* Endif */

      byte_num = byte_num / 10;
      if ( (byte_num < 0 ) || (byte_num > 255) ) {
         /* if the number does fall within this range it's invalid */
         dotted_decimal = FALSE;
      } else {
         *address = (*address) + byte_num;
      }/* Endif */

      if ( dot_count != 3 ) {
         /* the wrong number of dots were found */
         dotted_decimal = FALSE;
      }/* Endif */

   }/* Endif */


   if ( i == 0 ) {
      /* no name string of first char was not a number */
      dotted_decimal = FALSE;
   }/* Endif */
    
   return dotted_decimal;
}






#if RTCSCFG_ENABLE_LWDNS && RTCSCFG_ENABLE_UDP
boolean RTCS_resolve_ip_address( char_ptr arg, _ip_address _PTR_ ipaddr_ptr, char_ptr ipname, uint_32 ipnamesize)
{
   /* first check to see if name is written in dotted decimal IP format */
   if(RTCS_get_dotted_address (arg, ipaddr_ptr))
   {
      /* name was in dotted decimal format */
      return TRUE;
   }
   else
   {
      /* neccessary to resolve name */
      return LWDNS_resolve(arg, ipaddr_ptr, ipname, ipnamesize);
   }
}



#elif RTCSCFG_ENABLE_DNS && RTCSCFG_ENABLE_UDP



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_gethostbyname()
* Returned Value  : HOSTENT_STRUCT_PTR
* Comments        : Maps a host name to an IP address
*
*END*-----------------------------------------------------------------*/

HOSTENT_STRUCT_PTR RTCS_gethostbyname
   (
      char_ptr  name
   )
{  /* Body */
   INTERNAL_HOSTENT_STRUCT_PTR host_ptr;
   uint_32                     i;
   boolean                     name_found;
   boolean                     dotted_decimal;
   uint_32                     num_aliases = 0;
   uint_32                     host_index = 0;
   uint_32                     temp;

   /* allocate memory for HOSTENT_STRUCT */
   host_ptr = RTCS_mem_alloc_zero(sizeof(INTERNAL_HOSTENT_STRUCT));
   if ( host_ptr == NULL ) {
      return(NULL);
   }/* Endif */
   _mem_set_type(host_ptr, MEM_TYPE_HOSTENT_STRUCT);
   
   host_ptr->HOSTENT.h_aliases = &host_ptr->ALIASES[0];
   host_ptr->HOSTENT.h_addr_list = (char_ptr _PTR_)&host_ptr->ADDRESSES[0];

   /* assign address type and length */
   host_ptr->HOSTENT.h_addrtype = AF_INET;
   host_ptr->HOSTENT.h_length = 4;     /* IP addresses only used - 4 bytes */

   /* check to see if name is written in dotted decimal IP format */
   dotted_decimal = RTCS_get_dotted_address (name, &temp);

   if ( dotted_decimal == TRUE ) {
      /* assign the hostent struct from the dotted decimal IP name */
      host_ptr->HOSTENT.h_name = name;
      host_ptr->ALIASES[num_aliases] = NULL;
      host_ptr->IP_address = temp;
      host_ptr->ADDRESSES[0] = &host_ptr->IP_address;
      host_ptr->ADDRESSES[1] = NULL;
      name_found = TRUE;
   } else  {

      name_found = FALSE;

     /* search for the name in the hosts structure */
      while ( ((RTCS_Hosts_list[host_index]).ip_address != 0) && !name_found) {
      /*end of list hasn't been reached*/
         /* check the aliases for the name */
         i=0;
         while ( ((RTCS_Hosts_list[host_index]).aliases[i] != NULL) && !name_found) {
            if ( strcmp((RTCS_Hosts_list[host_index]).aliases[i],name) == 0 ) {
               name_found = TRUE;
            }/* Endif */
            ++i;
         } /* Endwhile */

         /* check the name field for the name */
         if ( strcmp((RTCS_Hosts_list[host_index]).host_name, name) == 0)  {
            name_found = TRUE;
         } /* Endif */

         if (name_found == TRUE ) { /* host name was found */

            host_ptr->HOSTENT.h_name = (RTCS_Hosts_list[host_index]).host_name;

            /* assign alias list */
            while ( (num_aliases < MAX_HOST_ALIASES)
                     && (RTCS_Hosts_list[host_index]).aliases[num_aliases] != NULL) {

               host_ptr->ALIASES[num_aliases] = (RTCS_Hosts_list[host_index]).aliases[num_aliases];
               ++num_aliases;
            } /* Endwhile */
            host_ptr->ALIASES[num_aliases] = NULL;

            /* assign addresses (in our case only one IP address is allowed) */

            host_ptr->ADDRESSES[0] = (uint_32_ptr)&((RTCS_Hosts_list[host_index]).ip_address);
            host_ptr->ADDRESSES[1] = NULL;
         } /* Endif */
         ++host_index;
      } /* Endwhile */
   }/* Endif */


   if ( !name_found ) {
      _mem_free(host_ptr);
      return( NULL );
   }/* Endif */

   return( &host_ptr->HOSTENT );

}/* EndBody */


boolean RTCS_resolve_ip_address( char_ptr arg, _ip_address _PTR_ ipaddr_ptr, char_ptr ipname, uint_32 ipnamesize)
{
    HOSTENT_STRUCT_PTR   host_ptr;
    boolean              result = FALSE;

   if (ipaddr_ptr == NULL) return FALSE;
   
   *ipaddr_ptr = 0;
   if (*arg != '\0') {
      host_ptr = gethostbyname(arg);
      if (host_ptr != NULL)  {
         if (*host_ptr->h_addr_list != NULL) {
            *ipaddr_ptr = *(_ip_address _PTR_)*host_ptr->h_addr_list;
            strncpy(ipname, host_ptr->h_name, ipnamesize);
            result = TRUE;
         } 
         DNS_free_HOSTENT_STRUCT(host_ptr);
      } 
   } 
   
   return result;
}



#else



boolean RTCS_resolve_ip_address( char_ptr arg, _ip_address _PTR_ ipaddr_ptr, char_ptr ipname, uint_32 ipnamesize)
{
    return RTCS_get_dotted_address (arg, ipaddr_ptr);
}



#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/io_pcb.h<|end_filename|>
#ifndef __io_pcb_h__
#define __io_pcb_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_pcb.h$
* $Version : 3.6.7.0$
* $Date    : Oct-5-2011$
*
* Comments:
*
*   This file is the header file for the I/O subsystem interface.                        
*
*END************************************************************************/

#include "ioctl.h"

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/* An invalid pool id */
#define IO_PCB_NULL_POOL_ID (_io_pcb_pool_id)(0)

/* Error codes */
#define IO_PCB_POOL_INVALID            (IO_PCB_ERROR_BASE|0x10)
#define IO_PCB_INVALID                 (IO_PCB_ERROR_BASE|0x11)
#define IO_PCB_NOT_A_PCB               (IO_PCB_ERROR_BASE|0x12)
#define IO_PCB_NOT_A_PCB_DEVICE        (IO_PCB_ERROR_BASE|0x13)
#define IO_PCB_READ_NOT_AVAILABLE      (IO_PCB_ERROR_BASE|0x14)
#define IO_PCB_WRITE_NOT_AVAILABLE     (IO_PCB_ERROR_BASE|0x15)
#define IO_PCB_DEVICE_DOES_NOT_EXIST   (IO_PCB_ERROR_BASE|0x16)
#define IO_PCB_ALLOC_CALLBACK_FAILED   (IO_PCB_ERROR_BASE|0x17)

/* PCB IOCTL Commands */
#define IO_PCB_IOCTL_READ_CALLBACK_SET _IO(IO_TYPE_PCB,0x01)
#define IO_PCB_IOCTL_SET_INPUT_POOL    _IO(IO_TYPE_PCB,0x02)
#define IO_PCB_IOCTL_ENQUEUE_READQ     _IO(IO_TYPE_PCB,0x03)
#define IO_PCB_IOCTL_START             _IO(IO_TYPE_PCB,0x04)
#define IO_PCB_IOCTL_UNPACKED_ONLY     _IO(IO_TYPE_PCB,0x05)

/*--------------------------------------------------------------------------*/
/*
**                            MACRO DEFINITIONS
*/
#define IO_PCB_FREE(pcb_ptr) \
   (*(pcb_ptr)->FREE_PCB_FUNCTION_PTR)(pcb_ptr)

/*--------------------------------------------------------------------------*/
/*
**                            DATATYPES
*/

/* The type of an IO PCB Pool ID (the address of the pool - 4) */
typedef pointer _io_pcb_pool_id;

typedef struct pcb_queue_element_struct {

   /* next element in queue, MUST BE FIRST FIELD */
   struct pcb_queue_element_struct _PTR_ NEXT;

   /* previous element in queue, MUST BE SECOND FIELD */
   struct pcb_queue_element_struct _PTR_ PREV;
   
} PCB_QUEUE_ELEMENT_STRUCT, _PTR_ PCB_QUEUE_ELEMENT_STRUCT_PTR;

/* 
** IO PCB FRAGMENT STRUCT
** This structure defines the location and size of a memory fragment, used by
** the IO PCB structure.
*/
typedef struct io_pcb_fragment_struct {

   /* The length of the data in bytes */
   _mqx_uint  LENGTH;

   /* The starting address of the data */
   uchar_ptr  FRAGMENT;

} IO_PCB_FRAGMENT_STRUCT, _PTR_ IO_PCB_FRAGMENT_STRUCT_PTR;

/*
** IO PCB STRUCT
** This structure defines what a Packet Control Block (PCB) looks like.
** The PCB is used to define the format of a data packet.  The data packet
** consists of any number of fragments of data located in various memory locations.
** The meaning of each fragment is protocol and application dependent.
*/
typedef struct io_pcb_struct {

   /* MQX queue utility pointers for queueing up PCBs */
   PCB_QUEUE_ELEMENT_STRUCT  QUEUE;

   /* The function to call when freeing this PCB */
   _mqx_uint     (_CODE_PTR_ FREE_PCB_FUNCTION_PTR)(struct io_pcb_struct _PTR_);

   /* PCB Validity field used for validity checking*/
   _mqx_uint                 VALID;

   /* The PCB pool that the PCB was allocated from */
   _io_pcb_pool_id           POOL_ID;

   /* Addresss of private information for used by the protocol/application */
   pointer                   OWNER_PRIVATE;
   pointer                   INSTANTIATOR_PRIVATE;

   /* protocol/application specific data */
   uint_16                   PRIVATE;

   /* The number of fragments in the variable length array */
   uint_16                   NUMBER_OF_FRAGMENTS;

   /* A variable length array of data fragments */
   IO_PCB_FRAGMENT_STRUCT  FRAGMENTS[1];

} IO_PCB_STRUCT, _PTR_ IO_PCB_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                      FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

/* IO PCB functions */
#ifndef __TAD_COMPILE__
extern _io_pcb_pool_id   _io_pcb_create_pool(_mqx_uint, _mem_size, _mqx_uint, 
   _mqx_uint, _mqx_uint, 
   IO_PCB_STRUCT_PTR (_CODE_PTR_) (IO_PCB_STRUCT_PTR, pointer), pointer,
   IO_PCB_STRUCT_PTR (_CODE_PTR_) (IO_PCB_STRUCT_PTR, pointer), pointer);
extern IO_PCB_STRUCT_PTR _io_pcb_alloc(_io_pcb_pool_id, boolean);
extern _mqx_int  _io_pcb_read(MQX_FILE_PTR, IO_PCB_STRUCT_PTR _PTR_);
extern _mqx_int  _io_pcb_write(MQX_FILE_PTR, IO_PCB_STRUCT _PTR_);
extern _mqx_uint _io_pcb_free(IO_PCB_STRUCT _PTR_);
extern _mqx_uint _io_pcb_free_internal(IO_PCB_STRUCT _PTR_);
extern _mqx_uint _io_pcb_destroy_pool(_io_pcb_pool_id);
extern _mqx_uint _io_pcb_test(pointer _PTR_, pointer _PTR_);
extern _mqx_int  _io_pcb_start(MQX_FILE_PTR fd_ptr);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/serl_kuart.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_kuart.h$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the sci drivers for the MCF51XX
*
*END************************************************************************/
#ifndef _serial_kuart_h_
#define _serial_kuart_h_


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

#if MQX_ENABLE_LOW_POWER

/*
** KUART_CLOCK_CONFIGURATION_STRUCT
**
** This structure defines the behavior of KUART in specific
** low power clock configuration.
*/
typedef struct kuart_clock_configuration_struct
{
    /* Whether channel is enabled in particular clock configuration */
    uint_8      ENABLED;

} KUART_CLOCK_CONFIGURATION_STRUCT, _PTR_ KUART_CLOCK_CONFIGURATION_STRUCT_PTR;
typedef const KUART_CLOCK_CONFIGURATION_STRUCT _PTR_ KUART_CLOCK_CONFIGURATION_STRUCT_CPTR;

/*
** KUART_OPERATION_MODE_STRUCT
**
** This structure defines the behavior of KUART in specific
** low power operation mode.
*/
typedef struct kuart_operation_mode_struct
{
    /* HW/wakeup enable/disable flags */
    uint_8      FLAGS;

    /* Wakeup register bits combination: UART_C2_RWU_MASK, UART_C1_WAKE_MASK, UART_C1_ILT_MASK, UART_C4_MAEN1_MASK, UART_C4_MAEN2_MASK */
    uint_8      WAKEUP_BITS;

    /* Wakeup settings of register UART_MA1 */
    uint_8      MA1;

    /* Wakeup settings of register UART_MA2 */
    uint_8      MA2;

} KUART_OPERATION_MODE_STRUCT, _PTR_ KUART_OPERATION_MODE_STRUCT_PTR;
typedef const KUART_OPERATION_MODE_STRUCT _PTR_ KUART_OPERATION_MODE_STRUCT_CPTR;

/*
**
** IO SERIAL LPM STRUCT
**
** This structure is used to store information regarding low power functionality.
**
*/
typedef struct io_serial_lpm_struct
{
   /* Low power manager registration handle */
   _mqx_uint           REGISTRATION_HANDLE;

   /* Low level device lock */
   LWSEM_STRUCT        LOCK;

   /* Special flags */
   uint_8              FLAGS;

} IO_SERIAL_LPM_STRUCT, _PTR_ IO_SERIAL_LPM_STRUCT_PTR;

#endif

/*
** KUART_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a serial port is initialized.
*/
typedef struct kuart_init_struct
{

   /* The size of the queues to buffer incoming/outgoing data */
   uint_32 QUEUE_SIZE;

   /* The device to initialize */
   uint_32 DEVICE;

   /* The clock speed of cpu */
   uint_32 CLOCK_SPEED;

   /* The baud rate for the channel */
   uint_32 BAUD_RATE;

   /* RX / TX interrupt vector */
   uint_32 RX_TX_VECTOR;

   /* ERR interrupt vector */
   uint_32 ERR_VECTOR;

   /* RX / TX interrupt vector priority */
   uint_32 RX_TX_PRIORITY;

   /* ERR interrupt vector priority */
   uint_32 ERR_PRIORITY;

#if MQX_ENABLE_LOW_POWER
   /* Clock source */
   CM_CLOCK_SOURCE                          CLOCK_SOURCE;

   /* Low power operation mode */
   KUART_OPERATION_MODE_STRUCT_CPTR         OPERATION_MODE;
#endif

} KUART_INIT_STRUCT, _PTR_ KUART_INIT_STRUCT_PTR;
typedef const KUART_INIT_STRUCT _PTR_ KUART_INIT_STRUCT_CPTR;

/*
** KUART_INFO_STRUCT
** Run time state information for each serial channel
*/
typedef struct kuart_info_struct
{
   /* The current init values for this port */
   KUART_INIT_STRUCT          INIT;

   /* The sci device register */
   UART_MemMapPtr             SCI_PTR;

   /* The previous interrupt handler and data */
   void       (_CODE_PTR_ OLD_ISR)(pointer);
   void       (_CODE_PTR_ OLD_ISR_EXCEPTION_HANDLER)(uint_32, uint_32, pointer,
               pointer);
   pointer                           OLD_ISR_DATA;

   /* Various flags */
   uint_32                           FLAGS;
   
   /* Statistical information */
   uint_32                           INTERRUPTS;
   uint_32                           RX_CHARS;
   uint_32                           TX_CHARS;
   uint_32                           RX_BREAKS;
   uint_32                           RX_PARITY_ERRORS;
   uint_32                           RX_FRAMING_ERRORS;
   uint_32                           RX_OVERRUNS;
   uint_32                           RX_DROPPED_INPUT;
   uint_32                           RX_NOISE_ERRORS;
} KUART_INFO_STRUCT, _PTR_ KUART_INFO_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern uint_32 _kuart_polled_init(KUART_INIT_STRUCT_PTR, pointer _PTR_,char _PTR_);
extern uint_32 _kuart_polled_install(char_ptr, KUART_INIT_STRUCT_CPTR, uint_32);
extern uint_32 _kuart_int_install(char_ptr, KUART_INIT_STRUCT_CPTR, uint_32);
extern pointer _bsp_get_serial_base_address(uint_8);

#ifdef __cplusplus
}
#endif

#endif //_serial_kuart_h_

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/gpio/kgpio/io_gpio_kgpio.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_gpio_kgpio.c$
* $Version : 3.8.14.0$
* $Date    : Aug-30-2011$
*
* Comments:
*
*   This file contains the GPIO standard functions used on boards
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "../io_gpio.h"
#include "../io_gpio_prv.h"
#include <string.h>


#define MUX_GPIO    0x01
#define PORT_END    5
#define PIN_IDX_NUM 32

/* This structure will hold 'used pins'. If somebody would like to open 'already used pin',
** the operation will fail. All open pins within all GPIO driver files will be written here.
** We can predefine this structure with 'already used' bits for those bits, which are not
** used at all - so we will prevent open operation to be successful.
*/
GPIO_PIN_MAP  gpio_global_pin_map = {
    0x0000,  /* porta */
    0x0000,  /* portb */
    0x0000,  /* portc */
    0x0000,  /* portd */
    0x0000   /* porte */
};

GPIO_PIN_MAP  gpio_global_irq_map = {
    0x0000,  /* porta */
    0x0000,  /* portb */
    0x0000,  /* portc */
    0x0000,  /* portd */
    0x0000   /* porte */
};

static uint32_t volatile * const pctl_ptr_arr[] = { 
    &(PORTA_PCR(0)),
    &(PORTB_PCR(0)),
    &(PORTC_PCR(0)),
    &(PORTD_PCR(0)),
    &(PORTE_PCR(0))
};

const static uint_8 _port_int_prio[] = {
    BSP_PORTA_INT_LEVEL,
    BSP_PORTB_INT_LEVEL,
    BSP_PORTC_INT_LEVEL,
    BSP_PORTD_INT_LEVEL,
    BSP_PORTE_INT_LEVEL,
};

extern GPIO_DEV_DATA_PTR first_irq; /* first file having used IRQ */

static _mqx_int install_isr( MQX_FILE_PTR );
static uint_32 get_irq_mask( boolean n, boolean p, boolean l);
void gpio_cpu_configure(GPIO_DEV_DATA_PTR);
_mqx_int gpio_cpu_init(void);
_mqx_int gpio_cpu_open(MQX_FILE_PTR, char_ptr, char_ptr);

_mqx_int gpio_cpu_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);
static void gpio_eport_irq (pointer param);

/*FUNCTION*****************************************************************
* 
* Function Name    : get_irg_mask
* Returned Value   : IRQ MASK
* Comments         :
*    return the IRQ mask
*
*END*********************************************************************/

static uint_32 get_irq_mask
    ( 
        /* IN first bitmask of decode table */ 
        uint_32 n,
        /* IN second bitmask of decode table */ 
        uint_32 p, 
        /* IN third bitmask of decode table */ 
        uint_32 l
     )
{ /* Body */
    /* Create index to the table below is done through these bit definitions */
    #define GPIO_LEVEL_MASK    (0x01)
    #define GPIO_RISING_MASK   (0x02)
    #define GPIO_FALLING_MASK  (0x04)

    #define IRQ_MASK_RISING     0x09    //1001 Interrupt on rising edge.
    #define IRQ_MASK_FALLING    0x0A    //1010 Interrupt on falling edge.
    #define IRQ_MASK_EITHER     0x0B    //1011 Interrupt on either edge.
    #define IRQ_MASK_ZERO       0x08    //1000 Interrupt when logic zero.
    #define IRQ_MASK_ONE        0x0C    //1100 Interrupt when logic one.

    _mqx_uint index = (n ? GPIO_FALLING_MASK : 0) | (p ? GPIO_RISING_MASK : 0) | (l ? GPIO_LEVEL_MASK : 0);

    const static uint_8 gpio_irq_mask_table[] = {
        0,                /* 000, no valid value */
        0,                /* 001, no valid value */
        IRQ_MASK_RISING,  /* 010, rising edge irq */
        IRQ_MASK_ONE,     /* 011, level one irq */
        IRQ_MASK_FALLING, /* 100, falling edge irq */
        IRQ_MASK_ZERO,    /* 101, level zero irq */
        IRQ_MASK_EITHER,  /* 110, falling and rising edge irq */
        0,                /* 111, no valid value */
    };

    return (uint_32) gpio_irq_mask_table[index];
} /* Endbody */
  
/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_configure
* Returned Value   : IO_OK
* Comments         :
*    Configures pins to be GPIO based on pin map
*
*END*********************************************************************/

void gpio_cpu_configure
   (
      /* [IN] pointer to file data */
      GPIO_DEV_DATA_PTR   dev_data_ptr
   )
{ /* Body */  
    _mqx_int  port_pointer,
              pin_idx;        
  
    /* set GPIO output behavior */
    if (dev_data_ptr->type == DEV_OUTPUT) {       
        GPIOA_PDDR |= dev_data_ptr->pin_map.reg.porta;
        GPIOB_PDDR |= dev_data_ptr->pin_map.reg.portb;
        GPIOC_PDDR |= dev_data_ptr->pin_map.reg.portc;
        GPIOD_PDDR |= dev_data_ptr->pin_map.reg.portd;
        GPIOE_PDDR |= dev_data_ptr->pin_map.reg.porte;
    }
    else { /* DEV_INPUT type is supposed */
        GPIOA_PDDR &= ~dev_data_ptr->pin_map.reg.porta;
        GPIOB_PDDR &= ~dev_data_ptr->pin_map.reg.portb;
        GPIOC_PDDR &= ~dev_data_ptr->pin_map.reg.portc;
        GPIOD_PDDR &= ~dev_data_ptr->pin_map.reg.portd;
        GPIOE_PDDR &= ~dev_data_ptr->pin_map.reg.porte;
    }
 
    /* set pin functionality to be GPIO for the whole file */
    for( port_pointer = 0; port_pointer < PORT_END; port_pointer++)
    {
        /* This variable is for quick access to determine if we should perform any change
        ** interrupt configuration for port.
        */
        uint_32 port_imask =
            dev_data_ptr->irqp_map.memory32[ port_pointer ] | \
            dev_data_ptr->irqn_map.memory32[ port_pointer ] | \
            dev_data_ptr->irql_map.memory32[ port_pointer ];

        for( pin_idx = 0; pin_idx < PIN_IDX_NUM; pin_idx ++)
        {
            /* set pin mux as gpio */
            if( dev_data_ptr->pin_map.memory32[ port_pointer ] & ( 1 << pin_idx ) )
            {
                /* set PCRx to default state */
                *(pctl_ptr_arr[port_pointer] + pin_idx) = PORT_PCR_MUX(MUX_GPIO) 
                    | PORT_PCR_IRQC( get_irq_mask( 
                        dev_data_ptr->irqn_map.memory32[ port_pointer ] & ( 1 << pin_idx),
                        dev_data_ptr->irqp_map.memory32[ port_pointer ] & ( 1 << pin_idx),
                        dev_data_ptr->irql_map.memory32[ port_pointer ] & ( 1 << pin_idx)));
                /* enable internal pull-up resistor for output pin */
                if(dev_data_ptr->type == DEV_INPUT)
                {
                    *(pctl_ptr_arr[port_pointer] + pin_idx) |= (PORT_PCR_PE_MASK|PORT_PCR_PS_MASK);
                }
            }
        }

        if (port_imask) {
            /* Enable and configure interrupts on NVIC */
            _bsp_int_init(INT_PORTA + port_pointer, _port_int_prio[port_pointer], 0, TRUE);
        }
    }  
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_install
* Returned Value   : IO_OK
* Comments         :
*    Performs basic initialization specific to board
*
*END*********************************************************************/

_mqx_int gpio_cpu_init()
{ /* Body */

    _bsp_gpio_io_init();    
    return IO_OK;
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_open
* Returned Value   : IO_OK or error
* Comments         :
*    Implements initialization for DATA GPIO
*
*END*********************************************************************/

static _mqx_int install_isr
( 
    MQX_FILE_PTR fd_ptr 
)
{
    /* clear all flags */
    PORTA_ISFR = 0xFFFFFFFF;
    PORTB_ISFR = 0xFFFFFFFF;
    PORTC_ISFR = 0xFFFFFFFF;
    PORTD_ISFR = 0xFFFFFFFF;
    PORTE_ISFR = 0xFFFFFFFF;
  
    if (NULL == _int_install_isr(INT_PORTA, gpio_eport_irq, NULL))
    {
        return IO_ERROR; /* could not install interrupt routine */
    }
    if (NULL == _int_install_isr(INT_PORTB, gpio_eport_irq, NULL))
    {
        return IO_ERROR; 
    }
    if (NULL == _int_install_isr(INT_PORTC, gpio_eport_irq, NULL))
    {
        return IO_ERROR; 
    }
    if (NULL == _int_install_isr(INT_PORTD, gpio_eport_irq, NULL))
    {
        return IO_ERROR; 
    }
    if (NULL == _int_install_isr(INT_PORTE, gpio_eport_irq, NULL))
    {
        return IO_ERROR; 
    } 
    
    gpio_cpu_ioctl( fd_ptr, GPIO_IOCTL_ENABLE_IRQ, NULL);
    
    return IO_OK;   
}
/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_open
* Returned Value   : IO_OK or error
* Comments         :
*    Implements initialization for DATA GPIO
*
*END*********************************************************************/

_mqx_int gpio_cpu_open
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the file name */
      char_ptr   file_name,

      /* [IN] pointer to parameters */
      char_ptr   param_ptr
   )
{ /* Body */
    GPIO_DEV_DATA_PTR dev_data_ptr = (GPIO_DEV_DATA_PTR) fd_ptr->DEV_DATA_PTR;
 
    /* if file_name is used, then the user wants to open peripheral */
    if ((file_name != NULL) && (*file_name != 0)) {
        if (!strncmp(file_name, "gpio:write", 11))  /* user wants write access to GPIO */
            dev_data_ptr->type = DEV_OUTPUT;
        else if (!strncmp(file_name, "gpio:output", 12))  /* user wants write access to GPIO */
            dev_data_ptr->type = DEV_OUTPUT;
        else if (!strncmp(file_name, "gpio:read", 10)) /* user wants read access to GPIO */
            dev_data_ptr->type = DEV_INPUT;
        else if (!strncmp(file_name, "gpio:input", 11)) /* user wants read access to GPIO */
            dev_data_ptr->type = DEV_INPUT;
        else
        /* peripherals not used yet */
            return IO_ERROR;
    }
    else
        return IO_ERROR;
    
    /* install interrupt service routine */
    if( IO_OK != install_isr( fd_ptr ) )
    {
        return IO_ERROR;  
    }
    
    /* set pins status before selecting GPIO function */
    if ((param_ptr != NULL) && (dev_data_ptr->type == DEV_OUTPUT)) { 
        /* note that this is similar to GPIO_IOCTL_WRITE function, but no checking 
        ** is performed (was done in io_gpio_open function) */
        GPIO_PIN_STRUCT _PTR_  pin_table;
        uint_32        addr;
        uint_8         pin;
        GPIO_PIN_MAP   temp_pin0_map = {0};
        GPIO_PIN_MAP   temp_pin1_map = {0};
        
        /* prepare pin map */
        for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) {
            /* prepare address of port */
            addr = GPIO_GET_PORT(*pin_table);  
            /* prepare bit mask */
            pin = GPIO_GET_BIT_MASK( *pin_table );  
            if (*pin_table & GPIO_PIN_STATUS)
                temp_pin1_map.memory32[addr] |= pin;
            else
                temp_pin0_map.memory32[addr] |= pin;
        }
        /* ok, now we can apply new map */
        /* note: applying the map after collecting pins is due to have pins applied in one instruction */
        GPIOA_PSOR = temp_pin1_map.memory32[0];
        GPIOA_PCOR = temp_pin0_map.memory32[0];
        GPIOB_PSOR = temp_pin1_map.memory32[1];
        GPIOB_PCOR = temp_pin0_map.memory32[1];
        GPIOC_PSOR = temp_pin1_map.memory32[2];
        GPIOC_PCOR = temp_pin0_map.memory32[2];
        GPIOD_PSOR = temp_pin1_map.memory32[3];
        GPIOD_PCOR = temp_pin0_map.memory32[3];
        GPIOE_PSOR = temp_pin1_map.memory32[4];
        GPIOE_PCOR = temp_pin0_map.memory32[4];
 
    }

    gpio_cpu_configure(dev_data_ptr);
    return IO_OK;
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_ioctl
* Returned Value   : depends on IOCTL command
* Comments         :
*    Implements all ioctl for GPIO
*
*END*********************************************************************/

_mqx_int gpio_cpu_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint  cmd,

      /* [IN] the ioctl parameters */
      pointer    param_ptr
   )
{ /* Body */
    GPIO_DEV_DATA_PTR  dev_data_ptr = (GPIO_DEV_DATA_PTR) fd_ptr->DEV_DATA_PTR;
 
    switch (cmd) {
        case GPIO_IOCTL_ADD_PINS: 
        {
            /* Add pins to this file. Params: table with pin addresses */
            GPIO_PIN_STRUCT _PTR_  pin_table;
            uint_32        addr;
            uint_32         pin;

            /* check pin_table if they are not in global pin_map */
            _int_disable();
            for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) 
            {
                /* check pin validity bit */
                if (*pin_table & GPIO_PIN_VALID) 
                { 
                    /* prepare address of port */ 
                    addr = GPIO_GET_PORT(*pin_table); 
                    /* prepare bit mask */
                    pin = GPIO_GET_BIT_MASK( *pin_table );  
                    /* pin address out of map scope? */
                    if (addr < sizeof(GPIO_PIN_MAP) * 8 / (GPIO_PIN_BIT_MASK + 1))
                    { 
                        /* pin address already used? */
                        if (! (gpio_global_pin_map.memory32[addr] & pin))
                        { 
                            /* manage next pin */
                            continue; 
                        }      
                    }
                }
                /* some problem occured */
                _int_enable();
                return IO_ERROR;
            }
            /* check successful, now we have to copy these bits to local pin map */
            for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) 
            {
                /* prepare address of port */
                addr = GPIO_GET_PORT(*pin_table);
                /* prepare bit mask */
                pin = GPIO_GET_BIT_MASK( *pin_table ); 
                /* mark pin as used by this file */
                dev_data_ptr->pin_map.memory32[addr] |= pin;
                /* mark pin as used globally */
                gpio_global_pin_map.memory32[addr] |= pin; 
            }
            gpio_cpu_configure(dev_data_ptr);
            _int_enable();
        }
        break;

        case GPIO_IOCTL_WRITE_LOG1: 
        {
            /* If this file is configured as output, sets every pin to 1. Params:
            list of pin addresses to be used or NULL for every pin in the file */
            if (dev_data_ptr->type != DEV_OUTPUT)
                return IO_ERROR;
            if (param_ptr == NULL) 
            { 
                /* apply command to whole file */
                _int_disable(); /* _lwsem_wait(&gpio_sem) replacement */
                GPIOA_PSOR = dev_data_ptr->pin_map.memory32[0];
                GPIOB_PSOR = dev_data_ptr->pin_map.memory32[1];
                GPIOC_PSOR = dev_data_ptr->pin_map.memory32[2];
                GPIOD_PSOR = dev_data_ptr->pin_map.memory32[3];
                GPIOE_PSOR = dev_data_ptr->pin_map.memory32[4];
                _int_enable(); 
                break;
            }
            else 
            {
                GPIO_PIN_STRUCT _PTR_   pin_table;
                uint_32                 addr;
                uint_32                 pin;
                GPIO_PIN_MAP            temp_pin_map = {0};

                _int_disable();
                /* check if there is not pin in the list which this file does not contain */
                for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) 
                {
                    /* check pin validity bit */
                    if (*pin_table & GPIO_PIN_VALID) 
                    { 
                        /* prepare address of port */
                        addr = GPIO_GET_PORT(*pin_table);
                        /* prepare bit mask */
                        pin = GPIO_GET_BIT_MASK( *pin_table );
                        /* pin address out of map scope? */
                        if (addr < sizeof(GPIO_PIN_MAP) * 8 / (GPIO_PIN_BIT_MASK + 1))
                        {
                            /* pin address already used? */
                            if (dev_data_ptr->pin_map.memory32[addr] & pin) 
                            { 
                                temp_pin_map.memory32[addr] |= pin;
                                continue; /* manage next pin */
                            }
                        }    
                    }
                    /* some problem occured */
                    _int_enable();
                    return IO_ERROR;
                }
                /* ok, now we can apply new map */
                /* note: applying the map after collecting pins is due to have pins applied in one instruction */
                GPIOA_PSOR = temp_pin_map.memory32[0];
                GPIOB_PSOR = temp_pin_map.memory32[1];
                GPIOC_PSOR = temp_pin_map.memory32[2];
                GPIOD_PSOR = temp_pin_map.memory32[3];
                GPIOE_PSOR = temp_pin_map.memory32[4];
                _int_enable();
            }
        }
        break;

        case GPIO_IOCTL_WRITE_LOG0: 
        {
            /* If this file is configured as output, clears every pin to 0. Params:
            list of pin addresses to be used or NULL for every pin in the file */
            if (dev_data_ptr->type != DEV_OUTPUT)
                return IO_ERROR;
            /* apply command to whole file */
            if (param_ptr == NULL) 
            { 
                _int_disable(); /* _lwsem_wait(&gpio_sem) replacement */
                GPIOA_PCOR = dev_data_ptr->pin_map.memory32[0];
                GPIOB_PCOR = dev_data_ptr->pin_map.memory32[1];
                GPIOC_PCOR = dev_data_ptr->pin_map.memory32[2];
                GPIOD_PCOR = dev_data_ptr->pin_map.memory32[3];
                GPIOE_PCOR = dev_data_ptr->pin_map.memory32[4];
                _int_enable();
                break;
            }
            else {
                GPIO_PIN_STRUCT _PTR_   pin_table;
                uint_32                 addr;
                uint_32                 pin;
                GPIO_PIN_MAP            temp_pin_map = {0};

                _int_disable();
                /* check if there is not pin in the list which this file does not contain */
                for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) 
                {
                    /* check pin validity bit */
                    if (*pin_table & GPIO_PIN_VALID) 
                    { 
                        /* prepare address of port */
                        addr = GPIO_GET_PORT(*pin_table);
                        /* prepare bit mask */
                        pin = GPIO_GET_BIT_MASK( *pin_table );
                        /* pin address out of map scope? */
                        if (addr < sizeof(GPIO_PIN_MAP) * 8 / (GPIO_PIN_BIT_MASK + 1))
                        {  
                            /* pin address already used? */
                            if (dev_data_ptr->pin_map.memory32[addr] & pin) { 
                                temp_pin_map.memory32[addr] |= pin;
                                continue; /* manage next pin */
                            }
                        }
                    }
                    /* some problem occurred */
                    _int_enable();
                    return IO_ERROR;
                }
                /* ok, now we can apply new map */
                /* note: applying the map after collecting pins is due to have pins applied in one instruction */
                GPIOA_PCOR = temp_pin_map.memory32[0];
                GPIOB_PCOR = temp_pin_map.memory32[1];
                GPIOC_PCOR = temp_pin_map.memory32[2];
                GPIOD_PCOR = temp_pin_map.memory32[3];
                GPIOE_PCOR = temp_pin_map.memory32[4];
                _int_enable();
            }
        }
        break;

        case GPIO_IOCTL_WRITE: 
        {
            /* If this file is configured as output, sets every pin to the state 
            ** defined in GPIO_PIN_STATUS. Params:
            ** list of pin addresses to be used or NULL for every pin in the file */
            if (dev_data_ptr->type != DEV_OUTPUT)
                return IO_ERROR;
            
            if (param_ptr == NULL) /* no param specified , but must be */
                return IO_ERROR;
            else {
                GPIO_PIN_STRUCT _PTR_   pin_table;
                uint_32                 addr;
                uint_32                  pin;
                GPIO_PIN_MAP             temp_pin0_map = {0};
                GPIO_PIN_MAP             temp_pin1_map = {0};

                _int_disable();
                /* check if there is not pin in the list which this file does not contain */
                for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) 
                {
                    /* check pin validity bit */
                    if (*pin_table & GPIO_PIN_VALID) 
                    { 
                        /* prepare address of port */
                        addr = GPIO_GET_PORT(*pin_table);  
                        /* prepare bit mask */
                        pin = GPIO_GET_BIT_MASK( *pin_table );  
                        /* pin address out of map scope? */
                        if (addr < sizeof(GPIO_PIN_MAP) * 8 / (GPIO_PIN_BIT_MASK + 1)) 
                        {
                            /* pin address already used? */
                            if (dev_data_ptr->pin_map.memory32[addr] & pin) 
                            { 
                                if (*pin_table & GPIO_PIN_STATUS)
                                    temp_pin1_map.memory32[addr] |= pin;
                                else
                                    temp_pin0_map.memory32[addr] |= pin;
                                continue; /* manage next pin */
                            }
                        }
                    }
                    /* some problem occurred */
                    _int_enable();
                    return IO_ERROR;
                }
                /* ok, now we can apply new map */
                /* note: applying the map after collecting pins is due to have pins applied in one instruction */
                GPIOA_PSOR = temp_pin1_map.memory32[0];
                GPIOA_PCOR = temp_pin0_map.memory32[0];
                GPIOB_PSOR = temp_pin1_map.memory32[1];
                GPIOB_PCOR = temp_pin0_map.memory32[1];
                GPIOC_PSOR = temp_pin1_map.memory32[2];
                GPIOC_PCOR = temp_pin0_map.memory32[2];
                GPIOD_PSOR = temp_pin1_map.memory32[3];
                GPIOD_PCOR = temp_pin0_map.memory32[3];
                GPIOE_PSOR = temp_pin1_map.memory32[4];
                GPIOE_PCOR = temp_pin0_map.memory32[4];
                _int_enable();
            }
        }
        break;

        case GPIO_IOCTL_READ: 
        {
            /* Read status of pins, if configured as input. Params: pointer to 
            ** predefined table where data will be written */
            GPIO_PIN_STRUCT _PTR_   pin_table;
            uint_32                 addr;
            volatile uint32_t _PTR_ rgpio_pdir_ptr;
            uint_32                 pin;
            
            volatile uint32_t _PTR_ rgpio_ptr_arr[] = { 
                &GPIOA_PDIR,
                &GPIOB_PDIR,
                &GPIOC_PDIR,
                &GPIOD_PDIR,
                &GPIOE_PDIR
            }; 

            if (dev_data_ptr->type != DEV_INPUT)
                return IO_ERROR;
            if (param_ptr == NULL) /* no list defined */
                return IO_ERROR;
            
            _int_disable();
            /* check if there is not pin in the list which this file does not contain */
            for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) 
            {
                /* check pin validity bit */
                if (*pin_table & GPIO_PIN_VALID) 
                { 
                    /* prepare address of port */ 
                    addr = GPIO_GET_PORT(*pin_table);
                    rgpio_pdir_ptr = rgpio_ptr_arr[ addr ];                    
                    /* prepare bit mask */
                    pin = GPIO_GET_BIT_MASK( *pin_table );  
                    /* pin address out of map scope? */
                    if (addr < sizeof(GPIO_PIN_MAP) * 8 / (GPIO_PIN_BIT_MASK + 1)) 
                    {  
                        /* pin address already used? */
                        if (dev_data_ptr->pin_map.memory32[addr] & pin) 
                        { 
                            /* GPIO port */
                            /* check pin status */
                            if ( *rgpio_pdir_ptr & pin)
                            {  
                                /* set pin status to 1 in the list */
                                *pin_table |= GPIO_PIN_STATUS; 
                            }
                            else
                            {
                                /* clear pin status to 0 in the list */
                                *pin_table &= ~GPIO_PIN_STATUS; 
                            }    
                            continue; /* manage next pin */
                        }
                    }
                }
                /* some problem occured */
                _int_enable();
                return IO_ERROR;
            }
            _int_enable();
        }
        break;

        case GPIO_IOCTL_ENABLE_IRQ: {

            uint_32 port_pointer, pin_idx;

            /* set "interrupt enabled" for the whole file */
            for( port_pointer = 0; port_pointer < PORT_END; port_pointer++)
            {
                /* This variable is for quick access to determine if we should perform any change
                ** to IRQC register field.
                ** We can set IRQC for every pin of port also, but it will be time consuming
                */
                uint_32 port_imask =
                    dev_data_ptr->irqp_map.memory32[ port_pointer ] | \
                    dev_data_ptr->irqn_map.memory32[ port_pointer ] | \
                    dev_data_ptr->irql_map.memory32[ port_pointer ];

                for( pin_idx = 0; pin_idx < PIN_IDX_NUM; pin_idx ++)
                {
                    if (port_imask & 0x00000001) {
                        /* clear PCRx.IRQC field */
                        *(pctl_ptr_arr[port_pointer] + pin_idx) &= ~PORT_PCR_IRQC(0x0F);
                        *(pctl_ptr_arr[port_pointer] + pin_idx) |=  PORT_PCR_IRQC( get_irq_mask( 
                                dev_data_ptr->irqn_map.memory32[ port_pointer ] & ( 1 << pin_idx),
                                dev_data_ptr->irqp_map.memory32[ port_pointer ] & ( 1 << pin_idx),
                                dev_data_ptr->irql_map.memory32[ port_pointer ] & ( 1 << pin_idx)));
                    }
                    port_imask >>= 1; 
                }
            }
        }
        break;

        case GPIO_IOCTL_DISABLE_IRQ: {

            uint_32 port_pointer, pin_idx;

            /* set "interrupt disabled" for whole file */
            for( port_pointer = 0; port_pointer < PORT_END; port_pointer++)
            {
                /* This variable is for quick access to determine if we should perform any change
                ** to IRQC register field.
                ** We can set IRQC for every pin of port also, but it will be time consuming
                */
                uint_32 port_imask =
                    dev_data_ptr->irqp_map.memory32[ port_pointer ] | \
                    dev_data_ptr->irqn_map.memory32[ port_pointer ] | \
                    dev_data_ptr->irql_map.memory32[ port_pointer ];
                for( pin_idx = 0; pin_idx < PIN_IDX_NUM; pin_idx ++)
                {
                    if (port_imask & 0x00000001) {
                        /* set PCRx to default state */
                        *(pctl_ptr_arr[port_pointer] + pin_idx) &= ~PORT_PCR_IRQC(0x0F);
                    }
                    port_imask >>= 1; 
                }
            }
        }
        break;

        case GPIO_IOCTL_SET_IRQ_FUNCTION: {
          
            if (dev_data_ptr->type == DEV_OUTPUT)
                return IO_ERROR; /* cannot set IRQ for output devices */

            dev_data_ptr->irq_func = (IRQ_FUNC)param_ptr;
            _int_disable();
            
            if (param_ptr == NULL) {  /* remove function from list */
                if (first_irq != NULL) {
                    GPIO_DEV_DATA_PTR gptr = first_irq;
                    while (gptr->NEXT != NULL) {
                        if (gptr == dev_data_ptr)
                            break;
                        if (gptr->NEXT == dev_data_ptr)
                            break;
                        gptr = gptr->NEXT;
                    }
                    if (gptr == dev_data_ptr) /* found as first in the list */
                        first_irq = first_irq->NEXT;
                    else if (gptr->NEXT == dev_data_ptr) /* found in the middle or at the end of list */
                        gptr->NEXT = gptr->NEXT->NEXT;
                }
            }
            else { /* add new function to the list */
                if (first_irq == NULL) {
                    first_irq = dev_data_ptr;
                }
                else {
                    GPIO_DEV_DATA_PTR gptr = first_irq;
                    while (gptr->NEXT != NULL) {
                        if (gptr == dev_data_ptr)
                            break;
                        gptr = gptr->NEXT;
                    }
                    if (gptr != dev_data_ptr)
                        gptr->NEXT = dev_data_ptr;
                }
            }
            _int_enable();       

        }    
        break;

        default:
            return IO_ERROR_INVALID_IOCTL_CMD;
    }
 
    return IO_OK;
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : gpio_eport_irq
* Returned Value   : 
* Comments         : GPIO IRQ handler
* 
*   This function find through all gpio files interrupt flag, clear it 
*   and call installed irq function
*
*END*********************************************************************/

static void gpio_eport_irq 
    (
        pointer param
     ) 
{ /* Body */
    /* DO NOT REMOVE volatile KEYWORD!!!
    ** This is workaround for bug in CodeWarrior 10.1 ARMCC.
    */
    volatile GPIO_DEV_DATA_PTR   gptr = first_irq;  
    volatile boolean             irq_flag = 0;
    volatile _mqx_int            port_pointer;
    volatile _mqx_int            pin_idx;
    
    /* list through all files */
    while (gptr) 
    { 
        /* list through all ports */
        for( port_pointer = 0; port_pointer < PORT_END; port_pointer++)
        {
            /* list through all pins */ 
            for( pin_idx = 0; pin_idx < PIN_IDX_NUM; pin_idx ++)
            {
                /* is pin in file ? */
                if( gptr->pin_map.memory32[ port_pointer ] & ( 1 << pin_idx ) )
                {                               
                    /* have pin set irq flag ? */
                    if( * (pctl_ptr_arr[port_pointer] + pin_idx) & PORT_PCR_ISF_MASK )
                    {
                        /* clear ISF flag */
                        * (pctl_ptr_arr[port_pointer] + pin_idx) |= PORT_PCR_ISF_MASK;
                        /* set irq call function flag */      
                        irq_flag = 1;
                    }               
                }
            }
        }   
        if ( irq_flag )
        {
            /* call irq function */
            gptr->irq_func(NULL);
            irq_flag = 0;
        }
        /* go to next file */
        gptr = gptr->NEXT;
    }
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_gpio_base_address
* Returned Value   : pointer to base of GPIO registers
* Comments         :
*    This function returns base address of GPIO related register space.
*
*END*********************************************************************/
pointer _bsp_get_gpio_base_address
(
    void
)
{
    return NULL;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/amd/29f0xx.h<|end_filename|>
#ifndef _29f0xx_h_
#define _29f0xx_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: 29f0xx.h$
* $Version : 3.8.4.0$
* $Date    : Oct-4-2011$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions specific for the 29f0xx devices
*
*END************************************************************************/

/*----------------------------------------------------------------------*/
/* 
**              DEFINED VARIABLES
*/
extern const FLASHX_BLOCK_INFO_STRUCT _29f010_block_map_8bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f010_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f010_block_map_32bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f040_block_map_8bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f040_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f040_block_map_32bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f080_block_map_8bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f080_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f080_block_map_32bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f016_block_map_8bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f016_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29f016_block_map_32bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29lv640_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29lv160_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29lv320_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _29pl160_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _at49bv1614a_block_map_16bit[];
extern const FLASHX_BLOCK_INFO_STRUCT _at49bv6416_block_map_16bit[];

extern const FLASHX_DEVICE_IF_STRUCT _29f0xx_if;


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi/spi_dspi.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_dspi.h$
* $Version : 3.8.2.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the SPI driver
*
*END************************************************************************/

#ifndef __spi_dspi_h__
#define __spi_dspi_h__

#include <bsp.h>


/*--------------------------------------------------------------------------*/
/*
**                    CONSTANT DEFINITIONS
*/

#define DSPI_CS_COUNT       8

#define DSPI_ATTR_USE_ISR   (1u<<31)


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** DSPI_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a spi port is initialized.
*/
typedef struct dspi_init_struct
{
   /* SPI channel number */
   uint_32 CHANNEL;

   /* The input clock source of the module */
   CM_CLOCK_SOURCE CLOCK_SOURCE;

} DSPI_INIT_STRUCT, _PTR_ DSPI_INIT_STRUCT_PTR;

typedef const DSPI_INIT_STRUCT _PTR_ DSPI_INIT_STRUCT_CPTR;


/*----------------------------------------------------------------------*/
/*
**              DEFINED VARIABLES
*/

extern const SPI_DEVIF_STRUCT _spi_dspi_devif;


/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern pointer   _bsp_get_dspi_base_address(uint_8);
extern uint_32   _bsp_get_dspi_vectors(uint_32 dev_num, const uint_32 _PTR_ _PTR_ vectors_ptr);
extern boolean   _bsp_dspi_enable_access(uint_32 device);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_bootloader/APP/usb_descriptor.c<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
**************************************************************************/ /*!
  *
  * @file usb_descriptor.c
  *
  * @author
  *
  * @version
  *
  * @date
  *
  * @brief The file contains USB descriptors for Mouse Application
  *
  *****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/

#include "app_cfg.h"
#include "usb_class.h"
#include "usb_descriptor.h"

/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/


/* structure containing details of all the endpoints used by this device */
const USB_ENDPOINTS usb_desc_runtime_ep =
{ 
  HID_DESC_ENDPOINT_COUNT,
  { HID_ENDPOINT,
    USB_INTERRUPT_PIPE,
    USB_SEND,
    HID_ENDPOINT_PACKET_SIZE,
  }
};

const USB_ENDPOINTS usb_desc_dfu_ep = 
{ 
  DFU_DESC_ENDPOINT_COUNT
};

#define USB_CONST  const
INT8U USB_CONST g_device_runtime_descriptor[DEVICE_DESCRIPTOR_SIZE] =
{
  DEVICE_DESCRIPTOR_SIZE,        /* "Device Descriptor Size        */
  USB_DEVICE_DESCRIPTOR,         /* "Device" Type of descriptor    */
  0x00, 0x02,                    /*  BCD USB version               */
  0x00,                          /*  Device Class is indicated in the interface descriptors     */
  0x00,                          /*  Device Subclass is indicated in the interface descriptors  */
  0x00,                          /*  Device Protocol               */
  CONTROL_MAX_PACKET_SIZE,       /*  Max Packet size               */
  0xA2, 0x15,                    /*  Vendor ID                     */
  0x00, 0x05,                    /*  Product ID                    */
  0x02, 0x00,                    /*  BCD Device version            */
  0x01,                          /*  Manufacturer string index     */
  0x02,                          /*  Product string index          */
  0x00,                          /*  Serial number string index    */
  0x01                           /*  Number of configurations      */
};

INT8U USB_CONST g_device_dfu_descriptor[DEVICE_DESCRIPTOR_SIZE] =
{
  DEVICE_DESCRIPTOR_SIZE,        /* "Device Descriptor Size        */
  USB_DEVICE_DESCRIPTOR,         /* "Device" Type of descriptor    */
  0x00, 0x02,                    /*  BCD USB version               */
  0x00,                          /*  Device Class is indicated in the interface descriptors     */
  0x00,                          /*  Device Subclass is indicated in the interface descriptors  */
  0x00,                          /*  Device Protocol               */
  CONTROL_MAX_PACKET_SIZE,       /*  Max Packet size               */
  0xA2, 0x15,                    /*  Vendor ID                     */
  0x00, 0x10,                    /*  Product ID                    */
  0x02, 0x00,                    /*  BCD Device version            */
  0x01,                          /*  Manufacturer string index     */
  0x03,                          /*  Product string index          */
  0x00,                          /*  Serial number string index    */
  0x01                           /*  Number of configurations      */
};
INT8U USB_CONST g_config_runtime_descriptor[CONFIG_DESC_SIZE_RUNTIME] =
{
  CONFIG_ONLY_DESC_SIZE,       /*  Configuration Descriptor Size - always 9 bytes*/
  USB_CONFIG_DESCRIPTOR,       /* "Configuration" type of descriptor */
  CONFIG_DESC_SIZE_RUNTIME, 0x00,     /*  Total length of the Configuration descriptor */
  2,                           /*  NumInterfaces */
  1,                           /*  Configuration Value */
  0,                           /*  Configuration Description String Index*/
  BUS_POWERED | SELF_POWERED | (REMOTE_WAKEUP_SUPPORT << REMOTE_WAKEUP_SHIFT),
  /* S08/CFv1 are both self powered (its compulsory to set bus powered)*/
  /*Attributes.support RemoteWakeup and self power*/
  0x32,                        /*  Current draw from bus */

  /* Interface Descriptor0 */
  IFACE_ONLY_DESC_SIZE,
  USB_IFACE_DESCRIPTOR,
  0x00,
  0x00,
  HID_DESC_ENDPOINT_COUNT,
  0x03,
  0x01,
  0x02,
  0x00,

  /* HID descriptor */
  HID_ONLY_DESC_SIZE,
  USB_HID_DESCRIPTOR,
  0x00, 0x01,
  0x00,
  0x01,
  0x22,
  0x34, 0x00,
  /*Endpoint descriptor */
  ENDP_ONLY_DESC_SIZE,
  USB_ENDPOINT_DESCRIPTOR,
  HID_ENDPOINT | (USB_SEND << 7),
  USB_INTERRUPT_PIPE,
  HID_ENDPOINT_PACKET_SIZE, 0x00,
  0x0A,

  /* Interface Descriptor 1*/
  IFACE_ONLY_DESC_SIZE,
  USB_IFACE_DESCRIPTOR,
  0x01,
  0x00,
  0x00,
  0xFE,  /*    bInterfaceClass */
  0x01,  /*     bInterfaceSubClass */
  0x01,   /* bInterfaceProtocol   */
  0x03,      /*   String index */

  /* Functional descriptor  */
  FUNCTIONAL_DESC_SIZE,                            /* Functional descriptor size */
  USB_DFU_FUNCTIONAL_DESCRIPTOR,                       /* Functional descriptor type */
  (DETACH << 3) | (MANIFESTATION << 2) | (BITCANUPLOAD << 1) | BITCANDOWNLOAD, /*  bmAttributes */
  0x64, 0x00,                                       /* wDetachTimeOut   */
  DFU_MAX_BLOCK_SIZE, 0x00,                             /* wTransferSize IN BYTES */
  0x10, 0x01                                        /* bcdDFUVersion */

};

INT8U USB_CONST g_config_dfu_descriptor[CONFIG_DESC_SIZE_DFU] =
{
  CONFIG_ONLY_DESC_SIZE,     /*  Configuration Descriptor Size - always 9 bytes*/
  USB_CONFIG_DESCRIPTOR,     /* "Configuration" type of descriptor */
  CONFIG_DESC_SIZE_DFU, 0x00, /*  Total length of the Configuration descriptor */
  0x01,                      /*  NumInterfaces */
  0x01,                      /*  Configuration Value */
  0x00,                      /*  Configuration Description String Index*/
  BUS_POWERED | SELF_POWERED | (REMOTE_WAKEUP_SUPPORT << REMOTE_WAKEUP_SHIFT),
  /* S08/CFv1 are both self powered (its compulsory to set bus powered)*/
  /*Attributes.support RemoteWakeup and self power*/
  0x32,                      /*  Current draw from bus */

  /* Interface Descriptor */
  IFACE_ONLY_DESC_SIZE,      /*  Interface Descriptor  Size - always 9 bytes*/
  USB_IFACE_DESCRIPTOR,      /*  type of descriptor */
  0x00,                      /*  bInterfaceNumbe */
  0x00,                      /*  bAlternateSetting */
  0x00,                      /*  bNumEndpoints (only control endpoint */
  0xFE,                      /*  bInterfaceClass */
  0x01,                      /*  bInterfaceSubClass */
  0x02,                      /*  bInterfaceProtocol */
  0x00,                      /*  Index of String Descriptor Describing this interface */

  /* Functional descriptor  */
  FUNCTIONAL_DESC_SIZE,                                                 /* Functional descriptor size */
  USB_DFU_FUNCTIONAL_DESCRIPTOR,                                        /* Functional descriptor type */
  (DETACH << 3) | (MANIFESTATION << 2) | (BITCANUPLOAD << 1) | BITCANDOWNLOAD,      /*  bmAttributes */
  0x64, 0x00,                                                            /* wDetachTimeOut   */
  DFU_MAX_BLOCK_SIZE, 0x00,                                                  /* wTransferSize IN BYTES */
  0x10, 0x01,                                                            /* bcdDFUVersion */
};


INT8U USB_CONST g_report_descriptor[REPORT_DESC_SIZE] =
{
  0x05, 0x01,   /* Usage Page (Generic Desktop)*/
  0x09, 0x02,   /* Usage (Mouse) */
  0xA1, 0x01,   /* Collection (Application) */
  0x09, 0x01,   /* Usage (Pointer) */

  0xA1, 0x00,   /* Collection (Physical) */
  0x05, 0x09,   /* Usage Page (Buttons) */
  0x19, 0x01,   /* Usage Minimun (01) */
  0x29, 0x03,   /* Usage Maximum (03) */

  0x15, 0x00,   /* logical Minimun (0) */
  0x25, 0x01,   /* logical Maximum (1) */
  0x95, 0x03,   /* Report Count (3) */
  0x75, 0x01,   /* Report Size (1) */

  0x81, 0x02,   /* Input(Data, Variable, Absolute) 3 button bits */
  0x95, 0x01,   /* Report count (1) */
  0x75, 0x05,   /* Report Size (5) */
  0x81, 0x01,   /* Input (Constant), 5 bit padding */

  0x05, 0x01,   /* Usage Page (Generic Desktop) */
  0x09, 0x30,   /* Usage (X) */
  0x09, 0x31,   /* Usage (Y) */
  0x09, 0x38,   /* Usage (Z) */

  0x15, 0x81,   /* Logical Minimum (-127) */
  0x25, 0x7F,   /* Logical Maximum (127) */
  0x75, 0x08,   /* Report Size (8) */
  0x95, 0x03,   /* Report Count (2) */

  0x81, 0x06,   /* Input(Data, Variable, Relative), 2 position bytes (X & Y)*/
  0xC0,         /* end collection */
  0xC0          /* end collection */
};

INT8U USB_CONST USB_STR_0[USB_STR_0_SIZE+USB_STR_DESC_SIZE] =
{ sizeof(USB_STR_0),
  USB_STRING_DESCRIPTOR,
  0x09,
  0x04 /*equiavlent to 0x0409*/
};

INT8U USB_CONST USB_STR_1[USB_STR_1_SIZE+USB_STR_DESC_SIZE] =
{  sizeof(USB_STR_1),
  USB_STRING_DESCRIPTOR,
  'F', 0,
  'R', 0,
  'E', 0,
  'E', 0,
  'S', 0,
  'C', 0,
  'A', 0,
  'L', 0,
  'E', 0,
  ' ', 0,
  'S', 0,
  'E', 0,
  'M', 0,
  'I', 0,
  'C', 0,
  'O', 0,
  'N', 0,
  'D', 0,
  'U', 0,
  'C', 0,
  'T', 0,
  'O', 0,
  'R', 0,
  ' ', 0,
  'I', 0,
  'N', 0,
  'C', 0,
  '.', 0
};
INT8U USB_CONST USB_STR_2[USB_STR_2_SIZE+USB_STR_DESC_SIZE] =
{  sizeof(USB_STR_2),
  USB_STRING_DESCRIPTOR,
  ' ', 0,
  'M', 0,
  'O', 0,
  'U', 0,
  'S', 0,
  'E', 0,
  ' ', 0,
  'D', 0,
  'E', 0,
  'M', 0,
  'O', 0,
  ' ', 0
};
INT8U USB_CONST USB_STR_3[USB_STR_3_SIZE+USB_STR_DESC_SIZE] =
{  sizeof(USB_STR_3),
  USB_STRING_DESCRIPTOR,
  ' ', 0,
  'D', 0,
  'F', 0,
  'U', 0,
  ' ', 0,
  'D', 0,
  'E', 0,
  'M', 0,
  'O', 0,
  ' ', 0
};
INT8U USB_CONST USB_STR_n[USB_STR_n_SIZE+USB_STR_DESC_SIZE] =
{  sizeof(USB_STR_n),
  USB_STRING_DESCRIPTOR,
  'B', 0,
  'A', 0,
  'D', 0,
  ' ', 0,
  'S', 0,
  'T', 0,
  'R', 0,
  'I', 0,
  'N', 0,
  'G', 0,
  ' ', 0,
  'I', 0,
  'N', 0,
  'D', 0,
  'E', 0,
  'X', 0
};

INT16U  *g_std_desc_size;
INT8U_ptr  *g_std_descriptors;

INT16U  g_std_desc_runtime_size[USB_MAX_STD_DESCRIPTORS+1] =
{ 0,
  DEVICE_DESCRIPTOR_SIZE,
  CONFIG_DESC_SIZE_RUNTIME,
  0, /* string */
  0, /* Interface */
  0, /* Endpoint */
  0, /* Device Qualifier */
  0, /* other speed config */
  REPORT_DESC_SIZE
};

INT8U_ptr  g_std_runtime_descriptors[USB_MAX_STD_DESCRIPTORS+1] =
{
  NULL,
  (INT8U_ptr)g_device_runtime_descriptor,
  (INT8U_ptr)g_config_runtime_descriptor,
  NULL, /* string */
  NULL, /* Interface */
  NULL, /* Endpoint */
  NULL, /* Device Qualifier */
  NULL, /* other speed config*/
  (INT8U_ptr)g_report_descriptor
};

INT16U  g_std_desc_dfu_size[USB_MAX_STD_DESCRIPTORS+1] =
{ 0,
  DEVICE_DESCRIPTOR_SIZE,
  CONFIG_DESC_SIZE_DFU,
  0, /* string */
  0, /* Interface */
  0, /* Endpoint */
  0, /* Device Qualifier */
  0, /* other speed config */

};

INT8U_ptr  g_std_dfu_descriptors[USB_MAX_STD_DESCRIPTORS+1] =
{
  NULL,
  (INT8U_ptr)g_device_dfu_descriptor,
  (INT8U_ptr)g_config_dfu_descriptor,
  NULL, /* string */
  NULL, /* Interface */
  NULL, /* Endpoint */
  NULL, /* Device Qualifier */
  NULL, /* other speed config*/

};
INT8U const g_string_desc_size[USB_MAX_STRING_DESCRIPTORS+1] =
{ sizeof(USB_STR_0),
  sizeof(USB_STR_1),
  sizeof(USB_STR_2),
  sizeof(USB_STR_3),
  sizeof(USB_STR_n)
};

INT8U_ptr USB_CONST g_string_descriptors[USB_MAX_STRING_DESCRIPTORS+1] =
{
  (INT8U_ptr const)USB_STR_0,
  (INT8U_ptr const)USB_STR_1,
  (INT8U_ptr const)USB_STR_2,
  (INT8U_ptr const)USB_STR_3,
  (INT8U_ptr const)USB_STR_n
};

USB_ALL_LANGUAGES g_languages =
{ USB_STR_0, sizeof(USB_STR_0),
  {
    (INT16U const)0x0409,
    (const INT8U **)g_string_descriptors,
    g_string_desc_size
  }
};

INT8U const g_valid_config_values[USB_MAX_CONFIG_SUPPORTED+1] = { 0, 1 };

INT8U       g_dfu_mode = RUNTIME_MODE;

static INT8U g_alternate_interface[USB_MAX_SUPPORTED_INTERFACES];

/**************************************************************************/ /*!
  *
  * @name  USB_Desc_Get_Descriptor
  *
  * @brief The function returns the correponding descriptor
  *
  * @param controller_ID : Controller ID
  * @param type          : Type of descriptor requested
  * @param sub_type      : String index for string descriptor
  * @param index         : String descriptor language Id
  * @param descriptor    : Output descriptor pointer
  * @param size          : Size of descriptor returned
  *
  * @return USB_OK                              When Successfull
  *         USBERR_INVALID_REQ_TYPE             when Error
  *****************************************************************************
  * This function is used to pass the pointer of the requested descriptor
  *****************************************************************************/
INT8U USB_Desc_Get_Descriptor
(
 INT8U controller_ID,   /* [IN]  Controller ID */
 INT8U type,            /* [IN]  Type of descriptor requested */
 INT8U str_num,         /* [IN]  String index for string descriptor */
 INT16U index,          /* [IN]  String descriptor language Id */
 INT8U_ptr *descriptor, /* [OUT] Output descriptor pointer */
 INT16U *size   /* [OUT] Size of descriptor returned */
 )
{
  
  UNUSED(controller_ID)
  if ( g_dfu_mode == RUNTIME_MODE )
  {
    g_std_descriptors  =  g_std_runtime_descriptors;
    g_std_desc_size    =  g_std_desc_runtime_size;
  }
  else
  {
    g_std_descriptors  =  g_std_dfu_descriptors;
    g_std_desc_size    =  g_std_desc_dfu_size;
  } 
  switch (type)
  {
  case USB_REPORT_DESCRIPTOR:
    {
      type = USB_MAX_STD_DESCRIPTORS;
      *descriptor = (INT8U_ptr)g_std_descriptors[type];
      *size = g_std_desc_size[type];
    }
    break;
  case USB_HID_DESCRIPTOR: /* hid descriptor and functional descriptor has the same index (0x21)*/
    {
      type = USB_CONFIG_DESCRIPTOR;
      *descriptor = (INT8U_ptr)(g_std_descriptors[type] +
                                CONFIG_ONLY_DESC_SIZE + IFACE_ONLY_DESC_SIZE);
      *size = HID_ONLY_DESC_SIZE;
    }
    break;
  case USB_STRING_DESCRIPTOR:
    {
      if ( index == 0 )
      {
        /* return the string and size of all languages */
        *descriptor = (INT8U_ptr)g_languages.
        languages_supported_string;
        *size = g_languages.languages_supported_size;
      }
      else
      {
        INT8U lang_id = 0;
        INT8U lang_index = USB_MAX_LANGUAGES_SUPPORTED;

        for (; lang_id < USB_MAX_LANGUAGES_SUPPORTED; lang_id++)
        {
          /* check whether we have a string for this language */
          if ( index == g_languages.usb_language[lang_id].language_id )
          {   /* check for max descriptors */
            if ( str_num < USB_MAX_STRING_DESCRIPTORS )
            {   /* setup index for the string to be returned */
              lang_index = str_num;
            } 
            break;
          } 
        } 
        /* set return val for descriptor and size */
        *descriptor = (INT8U_ptr)g_languages.usb_language[lang_id].
        lang_desc[lang_index];
        *size = g_languages.usb_language[lang_id].
        lang_desc_size[lang_index];
      } 
    }
    break;
  default :
    if ( type < USB_MAX_STD_DESCRIPTORS )
    {
      /* set return val for descriptor and size*/
      *descriptor = (INT8U_ptr)g_std_descriptors[type];
      /* if there is no descriptor then return error */
      if ( *descriptor == NULL )
      {
        return USBERR_INVALID_REQ_TYPE;
      } 
      *size = g_std_desc_size[type];
    }
    else /* invalid descriptor */
    {
      return USBERR_INVALID_REQ_TYPE;
    } 
    break;
  } /* EndSwitch */
  return USB_OK;
}
/**************************************************************************/ /*!
  *
  * @name  USB_Desc_Get_Interface
  *
  * @brief The function returns the alternate interface
  *
  * @param controller_ID : Controller ID
  * @param interface     : Interface number
  * @param alt_interface : Output alternate interface
  *
  * @return USB_OK                              When Successfull
  *         USBERR_INVALID_REQ_TYPE             when Error
  *****************************************************************************
  *This function is called by the framework module to get the current interface
  *****************************************************************************/
INT8U USB_Desc_Get_Interface
(
 INT8U controller_ID,     /* [IN] Controller ID */
 INT8U interface,         /* [IN] Interface number */
 INT8U_ptr alt_interface  /* [OUT] Output alternate interface */
 )
{
  
  UNUSED(controller_ID)
  /* if interface valid */
  if ( interface < USB_MAX_SUPPORTED_INTERFACES )
  {
    /* get alternate interface*/
    *alt_interface = g_alternate_interface[interface];
    return USB_OK;
  } 
  return USBERR_INVALID_REQ_TYPE;
} 
/**************************************************************************/ /*!
  *
  * @name  USB_Desc_Set_Interface
  *
  * @brief The function sets the alternate interface
  *
  * @param controller_ID : Controller ID
  * @param interface     : Interface number
  * @param alt_interface : Input alternate interface
  *
  * @return USB_OK                              When Successfull
  *         USBERR_INVALID_REQ_TYPE             when Error
  *****************************************************************************
  *This function is called by the framework module to set the interface
  *****************************************************************************/
INT8U USB_Desc_Set_Interface
(
 INT8U controller_ID, /* [IN] Controller ID */
 INT8U interface,     /* [IN] Interface number */
 INT8U alt_interface  /* [IN] Input alternate interface */
 )
{
  
  UNUSED(controller_ID)
  /* if interface valid */
  if ( interface < USB_MAX_SUPPORTED_INTERFACES )
  {
    /* set alternate interface*/
    g_alternate_interface[interface] = alt_interface;
    return USB_OK;
  } 
  return USBERR_INVALID_REQ_TYPE;
} 
/**************************************************************************/ /*!
  *
  * @name  USB_Desc_Valid_Configation
  *
  * @brief The function checks whether the configuration parameter
  *        input is valid or not
  *
  * @param controller_ID : Controller ID
  * @param config_val    : Configuration value
  *
  * @return TRUE           When Valid
  *         FALSE          When Error
  *****************************************************************************
  * This function checks whether the configuration is valid or not
  *****************************************************************************/
BOOLEAN USB_Desc_Valid_Configation
(
 INT8U controller_ID, /*[IN] Controller ID */
 INT16U config_val   /*[IN] Configuration value */
 )
{
  
  INT8U loop_index = 0;
  UNUSED(controller_ID)
  /* check with only supported val right now */
  while (loop_index < (USB_MAX_CONFIG_SUPPORTED + 1))
  {
    if ( config_val == g_valid_config_values[loop_index] )
    {
      return TRUE;
    } 
    loop_index++;
  } /* EndWhile */
  return FALSE;
} 
/**************************************************************************/ /*!
  *
  * @name  USB_Desc_Valid_Interface
  *
  * @brief The function checks whether the interface parameter
  *        input is valid or not
  *
  * @param controller_ID : Controller ID
  * @param interface     : Target interface
  *
  * @return TRUE           When Valid
  *         FALSE          When Error
  *****************************************************************************
  * This function checks whether the interface is valid or not
  *****************************************************************************/
BOOLEAN USB_Desc_Valid_Interface
(
 INT8U controller_ID, /*[IN] Controller ID */
 INT8U interface      /*[IN] Target interface */
 )
{
  
  INT8U loop_index = 0;
  UNUSED(controller_ID)

  /* check with only supported val right now */
  while (loop_index < USB_MAX_SUPPORTED_INTERFACES)
  {
    if ( interface == g_alternate_interface[loop_index] )
    {
      return TRUE;
    } 
    loop_index++;
  } /* EndWhile */
  return FALSE;
} 
/**************************************************************************/ /*!
  *
  * @name  USB_Desc_Remote_Wakeup
  *
  * @brief The function checks whether the remote wakeup is supported or not
  *
  * @param controller_ID : Controller ID
  *
  * @return REMOTE_WAKEUP_SUPPORT (TRUE) - If remote wakeup supported
  *****************************************************************************
  * This function returns remote wakeup is supported or not
  *****************************************************************************/
BOOLEAN USB_Desc_Remote_Wakeup
(
 INT8U controller_ID      /* [IN] Controller ID */
 )
{
  
  UNUSED(controller_ID)
  return REMOTE_WAKEUP_SUPPORT;
} 
/**************************************************************************/ /*!
  *
  * @name  USB_Desc_Get_Endpoints
  *
  * @brief The function returns with the list of all non control endpoints used
  *
  * @param controller_ID : Controller ID
  *
  * @return pointer to USB_ENDPOINTS
  *****************************************************************************
  * This function returns the information about all the non control endpoints
  * implemented
  *****************************************************************************/
void* USB_Desc_Get_Endpoints(INT8U controller_ID)
{
  
  UNUSED(controller_ID)

  if ( g_dfu_mode == RUNTIME_MODE ) 
    return (void *)&usb_desc_runtime_ep;
  else 
    return (void *)&usb_desc_dfu_ep;
} 
 
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/Cpu.c<|end_filename|>
/* ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : Cpu.c
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : MK60FN1M0LQ15
**     Version     : Component 01.005, Driver 01.04, CPU db: 3.00.000
**     Datasheet   : K60P144M150SF3RM, Rev. 2, Dec 2011
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-16, 17:36, # CodeGen: 13
**     Abstract    :
**
**     Settings    :
**
**     Contents    :
**         SetClockConfiguration - LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID);
**         GetClockConfiguration - uint8_t Cpu_GetClockConfiguration(void);
**         SetOperationMode      - LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode,...
**         EnableInt             - void Cpu_EnableInt(void);
**         DisableInt            - void Cpu_DisableInt(void);
**         GetLLSWakeUpFlags     - uint32_t Cpu_GetLLSWakeUpFlags(void);
**         MCGAutoTrim           - LDD_TError Cpu_MCGAutoTrim(uint8_t ClockSelect);
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file Cpu.c
** @version 01.04
** @brief
**
*/         
/*!
**  @addtogroup Cpu_module Cpu module documentation
**  @{
*/         

/* MODULE Cpu. */

#include "mqx.h"
#include "ioctl.h"
#include "MQX1.h"
#include "UART0.h"
#include "FTM0.h"
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
#include "Events.h"
#include "Cpu.h"

#ifdef __cplusplus
extern "C" {
#endif 

/* Symbols representing MCG modes */
#define MCG_MODE_FBI                    0x00U
#define MCG_MODE_BLPI                   0x01U
#define MCG_MODE_FBE                    0x02U
#define MCG_MODE_PBE                    0x03U
#define MCG_MODE_PEE                    0x04U
static const uint8_t MCGTransitionMatrix[5][5] = {
/* This matrix defines which mode is next in the MCG Mode state diagram in transitioning from the
   current mode to a target mode*/
  {  MCG_MODE_FBI,  MCG_MODE_BLPI,  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_FBE}, /* FBI */
  {  MCG_MODE_FBI,  MCG_MODE_BLPI,  MCG_MODE_FBI,  MCG_MODE_FBI,  MCG_MODE_FBI}, /* BLPI */
  {  MCG_MODE_FBI,  MCG_MODE_FBI,  MCG_MODE_FBE,  MCG_MODE_PBE,  MCG_MODE_PBE}, /* FBE */
  {  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_PBE,  MCG_MODE_PEE}, /* PBE */
  {  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PEE}  /* PEE */
};

/* Global variables */
volatile uint8_t SR_reg;               /* Current value of the FAULTMASK register */
volatile uint8_t SR_lock = 0x00U;      /* Lock */
static uint8_t ClockConfigurationID = CPU_CLOCK_CONFIG_0; /* Active clock configuration */

/*
** ===================================================================
**     Method      :  Cpu_LDD_SetClockConfiguration (component MK60FN1M0LQ15)
*/
/*!
**     @brief
**         Changes the clock configuration of all LDD components in a 
**         project.
**     @param
**       ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method.
*/
/* ===================================================================*/
extern void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration);

/*
** ===================================================================
**     Method      :  Cpu_SetBASEPRI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the BASEPRI core register.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
void Cpu_SetBASEPRI(uint32_t Level);

/*
** ===================================================================
**     Method      :  Cpu_MCGAutoTrim (component MK60FN1M0LQ15)
**     Description :
**         This method uses MCG auto trim feature to trim internal
**         reference clock. This method can be used only in a clock
**         configuration which derives its bus clock from external
**         reference clock (<MCG mode> must be one of the following
**         modes - FEE, FBE, BLPE, PEE, PBE) and if value of <Bus clock>
**         is in the range <8; 16>MHz.
**         The slow internal reference clock is trimmed to the value
**         selected by <Slow internal reference clock [kHz]> property. 
**         The fast internal reference clock will be trimmed to value
**         4MHz.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ClockSelect     - Selects which internal
**                           reference clock will be trimmed.
**                           0 ... slow (32kHz) internal reference clock
**                           will be trimmed
**                           > 0 ... fast (4MHz) internal reference
**                           clock will be trimmed
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_SPEED - The method does not work in the
**                           active clock configuration.
**                           ERR_FAILED - Autotrim process failed.
** ===================================================================
*/
LDD_TError Cpu_MCGAutoTrim(uint8_t ClockSelect)
{
  switch (ClockConfigurationID) {
    case CPU_CLOCK_CONFIG_1:
      if (ClockSelect == 0x00U) {
        /* Slow internal reference clock */
        MCG_ATCVH = 0x1EU;
        MCG_ATCVL = 0x0AU;
      } else {
        /* Fast internal reference clock */
        MCG_ATCVH = 0x1FU;
        MCG_ATCVL = 0x80U;
      }
      break;
    default:
      return ERR_SPEED;
  }
  if (ClockSelect == 0x00U) {
    /* MCG_SC: ATME=1,ATMS=0 */
    MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
              MCG_SC_ATMS_MASK
             )) | (uint8_t)(
              MCG_SC_ATME_MASK
             ));                       /* Start trimming of the slow internal reference clock */
  } else {
    /* MCG_SC: ATME=1,ATMS=1 */
    MCG_SC |= (MCG_SC_ATME_MASK | MCG_SC_ATMS_MASK); /* Start trimming of the fast internal reference clock */
  }
  while ((MCG_SC & MCG_SC_ATME_MASK) != 0x00U) { /* Wait until autotrim completes */
  }
  if ((MCG_SC & MCG_SC_ATMF_MASK) == 0x00U) {
    return ERR_OK;                     /* Trim operation completed successfully */
  } else {
    return ERR_FAILED;                 /* Trim operation failed */
  }
}

/*
** ===================================================================
**     Method      :  Cpu_GetLLSWakeUpFlags (component MK60FN1M0LQ15)
**     Description :
**         This method returns the current status of the LLWU wake-up
**         flags indicating which wake-up source caused the MCU to exit
**         LLS or VLLSx low power mode.
**         The following predefined constants can be used to determine
**         the wake-up source:
**         LLWU_EXT_PIN0, ... LLWU_EXT_PIN15 - external pin 0 .. 15
**         caused the wake-up
**         LLWU_INT_MODULE0 .. LLWU_INT_MODULE7 - internal module 0..15
**         caused the wake-up.
**     Parameters  : None
**     Returns     :
**         ---             - Returns the current status of the LLWU
**                           wake-up flags indicating which wake-up
**                           source caused the MCU to exit LLS or VLLSx
**                           low power mode.
** ===================================================================
*/
uint32_t Cpu_GetLLSWakeUpFlags(void)
{
  uint32_t Flags;

  Flags = LLWU_F1;
  Flags |= (uint32_t)((uint32_t)LLWU_F2 << 8U);
  Flags |= (uint32_t)((uint32_t)LLWU_F3 << 16U);
  if ((LLWU_FILT1 & 0x80U) != 0x00U ) {
    Flags |= LLWU_FILTER1;
  }
  if ((LLWU_FILT2 & 0x80U) != 0x00U ) {
    Flags |= LLWU_FILTER2;
  }
  return Flags;
}

static void Cpu_SetMCGModePEE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePEE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PEE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModePBE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeFBE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeBLPI(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeBLPI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to BLPI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeFBI(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCG(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCG (component MK60FN1M0LQ15)
**
**     Description :
**         This method updates the MCG according the requested clock 
**         source setting.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static uint8_t Cpu_GetCurrentMCGMode(void);
/*
** ===================================================================
**     Method      :  Cpu_GetCurrentMCGMode (component MK60FN1M0LQ15)
**
**     Description :
**         This method returns the active MCG mode
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

/*
** ===================================================================
**     Method      :  Cpu_INT_LLWInterrupt (component MK60FN1M0LQ15)
**
**     Description :
**         This ISR services the 'LLWU' interrupt.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
void Cpu_INT_LLWInterrupt(LDD_RTOS_TISRParameter _isrParameter)
{
  Cpu_OnLLSWakeUpINT();
  /* LLWU_F1: WUF7=1,WUF6=1,WUF5=1,WUF4=1,WUF3=1,WUF2=1,WUF1=1,WUF0=1 */
  LLWU_F1 = LLWU_F1_WUF7_MASK |
            LLWU_F1_WUF6_MASK |
            LLWU_F1_WUF5_MASK |
            LLWU_F1_WUF4_MASK |
            LLWU_F1_WUF3_MASK |
            LLWU_F1_WUF2_MASK |
            LLWU_F1_WUF1_MASK |
            LLWU_F1_WUF0_MASK;         /* Clear external pin flags */
  /* LLWU_F2: WUF15=1,WUF14=1,WUF13=1,WUF12=1,WUF11=1,WUF10=1,WUF9=1,WUF8=1 */
  LLWU_F2 = LLWU_F2_WUF15_MASK |
            LLWU_F2_WUF14_MASK |
            LLWU_F2_WUF13_MASK |
            LLWU_F2_WUF12_MASK |
            LLWU_F2_WUF11_MASK |
            LLWU_F2_WUF10_MASK |
            LLWU_F2_WUF9_MASK |
            LLWU_F2_WUF8_MASK;         /* Clear external pin flags */
  /* LLWU_F3: MWUF7=1,MWUF6=1,MWUF5=1,MWUF4=1,MWUF3=1,MWUF2=1,MWUF1=1,MWUF0=1 */
  LLWU_F3 = LLWU_F3_MWUF7_MASK |
            LLWU_F3_MWUF6_MASK |
            LLWU_F3_MWUF5_MASK |
            LLWU_F3_MWUF4_MASK |
            LLWU_F3_MWUF3_MASK |
            LLWU_F3_MWUF2_MASK |
            LLWU_F3_MWUF1_MASK |
            LLWU_F3_MWUF0_MASK;        /* Clear Error detect flag */
  /* LLWU_FILT1: FILTF=1 */
  LLWU_FILT1 |= LLWU_FILT1_FILTF_MASK; /* Clear filter flag */
  /* LLWU_FILT2: FILTF=1 */
  LLWU_FILT2 |= LLWU_FILT2_FILTF_MASK; /* Clear filter flag */

}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePEE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PEE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModePEE(uint8_t CLKMode)
{
  switch (CLKMode) {
    case 0U:
      /* Switch to PEE Mode */
      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
      OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
      /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC1_CR = OSC_CR_ERCLKEN_MASK;                                   
      /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
      MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);                                   
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = MCG_C2_RANGE0(0x02) |
               MCG_C2_HGO0_MASK |
               MCG_C2_EREFS0_MASK |
               MCG_C2_IRCS_MASK;       
      /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
      MCG_C11 = MCG_C11_PRDIV1(0x00);                                   
      /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
      MCG_C12 = MCG_C12_VDIV1(0x00);                                   
      /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
      MCG_C5 = MCG_C5_PRDIV0(0x00);                                   
      /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
      MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));                                   
      while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */
      }
      break;
    default:
      break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModePBE(uint8_t CLKMode)
{
  switch (CLKMode) {
    case 0U:
      /* Switch to PBE Mode */
      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
      OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
      /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC1_CR = OSC_CR_ERCLKEN_MASK;                                   
      /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
      MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);                                   
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = MCG_C2_RANGE0(0x02) |
               MCG_C2_HGO0_MASK |
               MCG_C2_EREFS0_MASK |
               MCG_C2_IRCS_MASK;       
      /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
      MCG_C5 = MCG_C5_PRDIV0(0x00);                                   
      /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
      MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));                                   
      while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
      }
      while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until PLL locked */
      }
      break;
    case 1U:
      /* Switch to PBE Mode */
      /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
      OSC0_CR = (OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
      /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC1_CR = 0x00U;                                   
      /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
      MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);                                   
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = MCG_C2_RANGE0(0x02) |
               MCG_C2_HGO0_MASK |
               MCG_C2_EREFS0_MASK |
               MCG_C2_IRCS_MASK;       
      while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
      }
      break;
    default:
      break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeFBE(uint8_t CLKMode)
{
  switch (CLKMode) {
    case 0U:
      /* Switch to FBE Mode */
      /* MCG_C7: OSCSEL=0 */
      MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);                                   
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = MCG_C2_RANGE0(0x02) |
               MCG_C2_HGO0_MASK |
               MCG_C2_EREFS0_MASK |
               MCG_C2_IRCS_MASK;       
      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
      OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
      /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC1_CR = OSC_CR_ERCLKEN_MASK;                                   
      /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
      MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);                                   
      /* MCG_C4: DMX32=0,DRST_DRS=0 */
      MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));                                   
      /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
      MCG_C5 = MCG_C5_PRDIV0(0x00);                                   
      /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
      MCG_C6 = MCG_C6_VDIV0(0x0E);                                   
      /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
      MCG_C11 = MCG_C11_PRDIV1(0x00);                                   
      /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
      MCG_C12 = MCG_C12_VDIV1(0x00);                                   
      while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */
      }
      while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
      }
      while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
      }
      break;
    case 1U:
      /* Switch to FBE Mode */
      /* MCG_C7: OSCSEL=0 */
      MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);                                   
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = MCG_C2_RANGE0(0x02) |
               MCG_C2_HGO0_MASK |
               MCG_C2_EREFS0_MASK |
               MCG_C2_IRCS_MASK;       
      /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
      OSC0_CR = (OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
      /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC1_CR = 0x00U;                                   
      /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
      MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);                                   
      /* MCG_C4: DMX32=0,DRST_DRS=0 */
      MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));                                   
      /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
      MCG_C5 = MCG_C5_PRDIV0(0x00);                                   
      /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
      MCG_C6 = MCG_C6_VDIV0(0x00);                                   
      /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
      MCG_C11 = MCG_C11_PRDIV1(0x00);                                   
      /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
      MCG_C12 = MCG_C12_VDIV1(0x00);                                   
      while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */
      }
      while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
      }
      while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
      }
      break;
    default:
      break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeBLPI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to BLPI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeBLPI(uint8_t CLKMode)
{
  switch (CLKMode) {
    case 1U:
      /* Switch to BLPI Mode */
      /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
      MCG_C1 = MCG_C1_CLKS(0x01) |
               MCG_C1_FRDIV(0x00) |
               MCG_C1_IREFS_MASK |
               MCG_C1_IRCLKEN_MASK;       
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=1,IRCS=1 */
      MCG_C2 = MCG_C2_RANGE0(0x02) |
               MCG_C2_HGO0_MASK |
               MCG_C2_EREFS0_MASK |
               MCG_C2_LP_MASK |
               MCG_C2_IRCS_MASK;       
      /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
      OSC0_CR = (OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
      /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC1_CR = 0x00U;                                   
      while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */
      }
      while((MCG_S & MCG_S_IRCST_MASK) == 0x00U) { /* Check that the fast external reference clock is selected. */
      }
      break;
    default:
      break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeFBI(uint8_t CLKMode)
{
  switch (CLKMode) {
    case 0U:
      /* Switch to FBI Mode */
      /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
      MCG_C1 = MCG_C1_CLKS(0x01) |
               MCG_C1_FRDIV(0x00) |
               MCG_C1_IREFS_MASK |
               MCG_C1_IRCLKEN_MASK;       
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = MCG_C2_RANGE0(0x02) |
               MCG_C2_HGO0_MASK |
               MCG_C2_EREFS0_MASK |
               MCG_C2_IRCS_MASK;       
      /* MCG_C4: DMX32=0,DRST_DRS=0 */
      MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));                                   
      /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
      OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
      /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC1_CR = OSC_CR_ERCLKEN_MASK;                                   
      /* MCG_C7: OSCSEL=0 */
      MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);                                   
      /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
      MCG_C5 = MCG_C5_PRDIV0(0x00);                                   
      /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
      MCG_C6 = MCG_C6_VDIV0(0x0E);                                   
      /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
      MCG_C11 = MCG_C11_PRDIV1(0x00);                                   
  /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
  MCG_C12 = MCG_C12_VDIV1(0x00);       /* 7 */
      while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */
      }
      while((MCG_S & 0x0CU) != 0x04U) { /* Wait until internal reference clock is selected as MCG output */
      }
      break;
    case 1U:
      /* Switch to FBI Mode */
      /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
      MCG_C1 = MCG_C1_CLKS(0x01) |
               MCG_C1_FRDIV(0x00) |
               MCG_C1_IREFS_MASK |
               MCG_C1_IRCLKEN_MASK;       
      /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
      MCG_C2 = MCG_C2_RANGE0(0x02) |
               MCG_C2_HGO0_MASK |
               MCG_C2_EREFS0_MASK |
               MCG_C2_IRCS_MASK;       
      /* MCG_C4: DMX32=0,DRST_DRS=0 */
      MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));                                   
      /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
      OSC0_CR = (OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
      /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
      OSC1_CR = 0x00U;                                   
      /* MCG_C7: OSCSEL=0 */
      MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);                                   
      /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
      MCG_C5 = MCG_C5_PRDIV0(0x00);                                   
      /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
      MCG_C6 = MCG_C6_VDIV0(0x00);                                   
      /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
      MCG_C11 = MCG_C11_PRDIV1(0x00);                                   
  /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
  MCG_C12 = MCG_C12_VDIV1(0x00);       /* 7 */
      while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */
      }
      while((MCG_S & 0x0CU) != 0x04U) { /* Wait until internal reference clock is selected as MCG output */
      }
      break;
    default:
      break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCG (component MK60FN1M0LQ15)
**
**     Description :
**         This method updates the MCG according the requested clock 
**         source setting.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCG(uint8_t CLKMode)
{
  uint8_t TargetMCGMode = 0x00U;
  uint8_t NextMCGMode;

  switch (CLKMode) {
    case 0U:
      TargetMCGMode = MCG_MODE_PEE;
      break;
    case 1U:
      TargetMCGMode = MCG_MODE_BLPI;
      break;
    default:
      break;
  }
  NextMCGMode = Cpu_GetCurrentMCGMode(); /* Identify the currently active MCG mode */
  do {
    NextMCGMode = MCGTransitionMatrix[NextMCGMode][TargetMCGMode]; /* Get the next MCG mode on the path to the target MCG mode */
    switch (NextMCGMode) {             /* Set the next MCG mode on the path to the target MCG mode */
      case MCG_MODE_FBI:
        Cpu_SetMCGModeFBI(CLKMode);
        break;
      case MCG_MODE_BLPI:
        Cpu_SetMCGModeBLPI(CLKMode);
        break;
      case MCG_MODE_FBE:
        Cpu_SetMCGModeFBE(CLKMode);
        break;
      case MCG_MODE_PBE:
        Cpu_SetMCGModePBE(CLKMode);
        break;
      case MCG_MODE_PEE:
        Cpu_SetMCGModePEE(CLKMode);
        break;
      default:
        break;
    }
  } while (TargetMCGMode != NextMCGMode); /* Loop until the target MCG mode is set */
}

/*
** ===================================================================
**     Method      :  Cpu_GetCurrentMCGMode (component MK60FN1M0LQ15)
**
**     Description :
**         This method returns the active MCG mode
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
uint8_t Cpu_GetCurrentMCGMode(void)
{
  switch (MCG_C1  & MCG_C1_CLKS_MASK) {
    case  0x00U:
      return MCG_MODE_PEE;
    case 0x40U:
      /* Internal reference clock is selected */
      if ((MCG_C2 & MCG_C2_LP_MASK) == 0x00U) {
        /* Low power mode is disabled */
        return MCG_MODE_FBI;
      } else {
        /* Low power mode is enabled */
        return MCG_MODE_BLPI;
      }
    case 0x80U:
      if ((MCG_C6 & MCG_C6_PLLS_MASK) == 0x00U) {
        /* FLL is selected */
        return MCG_MODE_FBE;
      } else {
        /* PLL is selected */
        return MCG_MODE_PBE;
       }
    default:
      return 0x00U;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetClockConfiguration (component MK60FN1M0LQ15)
**     Description :
**         Calling of this method will cause the clock configuration
**         change and reconfiguration of all components according to
**         the requested clock configuration setting.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ModeID          - Clock configuration identifier
**     Returns     :
**         ---             - ERR_OK - OK.
**                           ERR_RANGE - Mode parameter out of range
** ===================================================================
*/
LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID)
{
  if (ModeID > 0x02U) {
    return ERR_RANGE;                  /* Undefined clock configuration requested requested */
  }
  switch (ModeID) {
    case CPU_CLOCK_CONFIG_0:
      if (ClockConfigurationID == 2U) {
        /* Clock configuration 0 and clock configuration 2 use different clock configuration */
        /* MCG_C6: CME0=0 */
        MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
        /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
        SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                      SIM_CLKDIV1_OUTDIV2(0x03) |
                      SIM_CLKDIV1_OUTDIV3(0x07) |
                      SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
        if ((MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U) {
          /* MCG_SC: FCRDIV=1 */
          MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                    MCG_SC_FCRDIV(0x06)
                   )) | (uint8_t)(
                    MCG_SC_FCRDIV(0x01)
                   ));                                  
        } else {
          /* MCG_C2: IRCS=0 */
          MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);                                   
          /* MCG_SC: FCRDIV=1 */
          MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                    MCG_SC_FCRDIV(0x06)
                   )) | (uint8_t)(
                    MCG_SC_FCRDIV(0x01)
                   ));                                  
          /* MCG_C2: IRCS=1 */
          MCG_C2 |= MCG_C2_IRCS_MASK;                                   
        }
        Cpu_SetMCG(0U);                /* Update clock source setting */
        /* MCG_C6: CME0=1 */
        MCG_C6 |= MCG_C6_CME0_MASK;    /* Enable the clock monitor */
      }
      /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=2,OUTDIV4=5,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
      SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) |
                    SIM_CLKDIV1_OUTDIV2(0x01) |
                    SIM_CLKDIV1_OUTDIV3(0x02) |
                    SIM_CLKDIV1_OUTDIV4(0x05); /* Update system prescalers */
      /* SIM_SOPT2: PLLFLLSEL=1 */
      SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
                   SIM_SOPT2_PLLFLLSEL(0x02)
                  )) | (uint32_t)(
                   SIM_SOPT2_PLLFLLSEL(0x01)
                  ));                  /* Select PLL 0 as a clock source for various peripherals */
      /* SIM_SOPT1: OSC32KSEL=1 */
      SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; /* RTC oscillator drives 32 kHz clock for various peripherals */
      break;
    case CPU_CLOCK_CONFIG_1:
      if (ClockConfigurationID == 2U) {
        /* Clock configuration 1 and clock configuration 2 use different clock configuration */
        /* MCG_C6: CME0=0 */
        MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
        /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
        SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                      SIM_CLKDIV1_OUTDIV2(0x03) |
                      SIM_CLKDIV1_OUTDIV3(0x07) |
                      SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
        if ((MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U) {
          /* MCG_SC: FCRDIV=1 */
          MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                    MCG_SC_FCRDIV(0x06)
                   )) | (uint8_t)(
                    MCG_SC_FCRDIV(0x01)
                   ));                                  
        } else {
          /* MCG_C2: IRCS=0 */
          MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);                                   
          /* MCG_SC: FCRDIV=1 */
          MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                    MCG_SC_FCRDIV(0x06)
                   )) | (uint8_t)(
                    MCG_SC_FCRDIV(0x01)
                   ));                                  
          /* MCG_C2: IRCS=1 */
          MCG_C2 |= MCG_C2_IRCS_MASK;                                   
        }
        Cpu_SetMCG(0U);                /* Update clock source setting */
        /* MCG_C6: CME0=1 */
        MCG_C6 |= MCG_C6_CME0_MASK;    /* Enable the clock monitor */
      }
      /* SIM_CLKDIV1: OUTDIV1=9,OUTDIV2=9,OUTDIV3=9,OUTDIV4=9,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
      SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x09) |
                    SIM_CLKDIV1_OUTDIV2(0x09) |
                    SIM_CLKDIV1_OUTDIV3(0x09) |
                    SIM_CLKDIV1_OUTDIV4(0x09); /* Update system prescalers */
      /* SIM_SOPT2: PLLFLLSEL=1 */
      SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
                   SIM_SOPT2_PLLFLLSEL(0x02)
                  )) | (uint32_t)(
                   SIM_SOPT2_PLLFLLSEL(0x01)
                  ));                  /* Select PLL 0 as a clock source for various peripherals */
      /* SIM_SOPT1: OSC32KSEL=1 */
      SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; /* RTC oscillator drives 32 kHz clock for various peripherals */
      break;
    case CPU_CLOCK_CONFIG_2:
      /* MCG_C6: CME0=0 */
      MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
      /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
      SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                    SIM_CLKDIV1_OUTDIV2(0x03) |
                    SIM_CLKDIV1_OUTDIV3(0x07) |
                    SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
      if ((MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U) {
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                  MCG_SC_FCRDIV(0x06)
                 )) | (uint8_t)(
                  MCG_SC_FCRDIV(0x01)
                 ));                                  
      } else {
        /* MCG_C2: IRCS=0 */
        MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);                                   
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                  MCG_SC_FCRDIV(0x06)
                 )) | (uint8_t)(
                  MCG_SC_FCRDIV(0x01)
                 ));                                  
        /* MCG_C2: IRCS=1 */
        MCG_C2 |= MCG_C2_IRCS_MASK;                                   
      }
      Cpu_SetMCG(1U);                  /* Update clock source setting */
      /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV3=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
      SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) |
                    SIM_CLKDIV1_OUTDIV2(0x00) |
                    SIM_CLKDIV1_OUTDIV3(0x00) |
                    SIM_CLKDIV1_OUTDIV4(0x03); /* Update system prescalers */
      /* SIM_SOPT2: PLLFLLSEL=3 */
      SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x03); /* Select Core clock as a clock source for various peripherals */
      /* SIM_SOPT1: OSC32KSEL=0 */
      SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL_MASK); /* System oscillator drives 32 kHz clock for various peripherals */
      break;
    default:
      break;
  }
  LDD_SetClockConfiguration(ModeID);   /* Call all LDD components to update the clock configuration */
  ClockConfigurationID = ModeID;       /* Store clock configuration identifier */
  return ERR_OK;
}

/*
** ===================================================================
**     Method      :  Cpu_GetClockConfiguration (component MK60FN1M0LQ15)
**     Description :
**         Returns the active clock configuration identifier. The
**         method is enabled only if more than one clock configuration
**         is enabled in the component.
**     Parameters  : None
**     Returns     :
**         ---             - Active clock configuration identifier
** ===================================================================
*/
uint8_t Cpu_GetClockConfiguration(void)
{
  return ClockConfigurationID;         /* Return the actual clock configuration identifier */
}

/*
** ===================================================================
**     Method      :  Cpu_SetOperationMode (component MK60FN1M0LQ15)
**     Description :
**         This method requests to change the component's operation
**         mode (RUN, WAIT, SLEEP, STOP). The target operation mode
**         will be entered immediately. 
**         See <Operation mode settings> for further details of the
**         operation modes mapping to low power modes of the cpu.
**     Parameters  :
**         NAME            - DESCRIPTION
**         OperationMode   - Requested driver
**                           operation mode
**         ModeChangeCallback - Callback to
**                           notify the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**       * ModeChangeCallbackParamPtr 
**                           - Pointer to callback parameter to notify
**                           the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_PARAM_MODE - Invalid operation mode
** ===================================================================
*/
LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr)
{
  (void) ModeChangeCallback;           /* Parameter is not used, suppress unused argument warning */
  (void) ModeChangeCallbackParamPtr;   /* Parameter is not used, suppress unused argument warning */
  switch (OperationMode) {
    case DOM_RUN:
      /* SCB_SCR: SLEEPDEEP=0,SLEEPONEXIT=0 */
      SCB_SCR &= (uint32_t)~(uint32_t)(
                  SCB_SCR_SLEEPDEEP_MASK |
                  SCB_SCR_SLEEPONEXIT_MASK
                 );                                   
      if  (ClockConfigurationID != 2U) {
        if ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) { /* If in PBE mode, switch to PEE. PEE to PBE transition was caused by wakeup from low power mode. */
          /* MCG_C1: CLKS=0,IREFS=0 */
          MCG_C1 &= (uint8_t)~(uint8_t)((MCG_C1_CLKS(0x03) | MCG_C1_IREFS_MASK));                                   
          while( (MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait for PLL lock */
          }
        }
      }
      break;
    case DOM_WAIT:
      /* SCB_SCR: SLEEPDEEP=0 */
      SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPDEEP_MASK);                                   
      /* SCB_SCR: SLEEPONEXIT=0 */
      SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPONEXIT_MASK);                                   
      PE_WFI();
      break;
    case DOM_SLEEP:
      /* SCB_SCR: SLEEPDEEP=1 */
      SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;                                   
      /* SMC_PMCTRL: STOPM=0 */
      SMC_PMCTRL &= (uint8_t)~(uint8_t)(SMC_PMCTRL_STOPM(0x07));                                   
      (void)(SMC_PMCTRL == 0U);        /* Dummy read of SMC_PMCTRL to ensure the register is written before enterring low power mode */
      /* SCB_SCR: SLEEPONEXIT=1 */
      SCB_SCR |= SCB_SCR_SLEEPONEXIT_MASK;                                   
      PE_WFI();
      break;
    case DOM_STOP:
    /* Clear LLWU flags */
      /* LLWU_F1: WUF7=1,WUF6=1,WUF5=1,WUF4=1,WUF3=1,WUF2=1,WUF1=1,WUF0=1 */
      LLWU_F1 = LLWU_F1_WUF7_MASK |
                LLWU_F1_WUF6_MASK |
                LLWU_F1_WUF5_MASK |
                LLWU_F1_WUF4_MASK |
                LLWU_F1_WUF3_MASK |
                LLWU_F1_WUF2_MASK |
                LLWU_F1_WUF1_MASK |
                LLWU_F1_WUF0_MASK;       
      /* LLWU_F2: WUF15=1,WUF14=1,WUF13=1,WUF12=1,WUF11=1,WUF10=1,WUF9=1,WUF8=1 */
      LLWU_F2 = LLWU_F2_WUF15_MASK |
                LLWU_F2_WUF14_MASK |
                LLWU_F2_WUF13_MASK |
                LLWU_F2_WUF12_MASK |
                LLWU_F2_WUF11_MASK |
                LLWU_F2_WUF10_MASK |
                LLWU_F2_WUF9_MASK |
                LLWU_F2_WUF8_MASK;       
      /* LLWU_F3: MWUF7=1,MWUF6=1,MWUF5=1,MWUF4=1,MWUF3=1,MWUF2=1,MWUF1=1,MWUF0=1 */
      LLWU_F3 = LLWU_F3_MWUF7_MASK |
                LLWU_F3_MWUF6_MASK |
                LLWU_F3_MWUF5_MASK |
                LLWU_F3_MWUF4_MASK |
                LLWU_F3_MWUF3_MASK |
                LLWU_F3_MWUF2_MASK |
                LLWU_F3_MWUF1_MASK |
                LLWU_F3_MWUF0_MASK;       
      /* LLWU_FILT1: FILTF=1 */
      LLWU_FILT1 |= LLWU_FILT1_FILTF_MASK;                                   
      /* LLWU_FILT2: FILTF=1 */
      LLWU_FILT2 |= LLWU_FILT2_FILTF_MASK;                                   
      /* SCB_SCR: SLEEPONEXIT=0 */
      SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPONEXIT_MASK);                                   
      /* SCB_SCR: SLEEPDEEP=1 */
      SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;                                   
      /* SMC_PMCTRL: STOPM=3 */
      SMC_PMCTRL = (uint8_t)((SMC_PMCTRL & (uint8_t)~(uint8_t)(
                    SMC_PMCTRL_STOPM(0x04)
                   )) | (uint8_t)(
                    SMC_PMCTRL_STOPM(0x03)
                   ));                                  
      (void)(SMC_PMCTRL == 0U);        /* Dummy read of SMC_PMCTRL to ensure the register is written before enterring low power mode */
      PE_WFI();
      break;
    default:
      return ERR_PARAM_MODE;
  }
  return ERR_OK;
}

/*
** ===================================================================
**     Method      :  Cpu_EnableInt (component MK60FN1M0LQ15)
**     Description :
**         Enables all maskable interrupts.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_EnableInt(void)
{
 __EI();
}

/*
** ===================================================================
**     Method      :  Cpu_DisableInt (component MK60FN1M0LQ15)
**     Description :
**         Disables all maskable interrupts.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_DisableInt(void)
{
 __DI();
}


/*** !!! Here you can place your own code using property "User data declarations" on the build options tab. !!! ***/

void __pe_initialize_hardware(void)
{

  /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/

  /*** ### MK60FN1M0VLQ12 "Cpu" init code ... ***/
  /*** PE initialization code after reset ***/
  /* SIM_SCGC6: RTC=1 */
  SIM_SCGC6 |= SIM_SCGC6_RTC_MASK;                                   
  if ((RTC_CR & RTC_CR_OSCE_MASK) == 0u) { /* Only if the OSCILLATOR is not already enabled */
    /* RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    RTC_CR &= (uint32_t)~(uint32_t)(
               RTC_CR_SC2P_MASK |
               RTC_CR_SC4P_MASK |
               RTC_CR_SC8P_MASK |
               RTC_CR_SC16P_MASK
              );                                   
    /* RTC_CR: OSCE=1 */
    RTC_CR |= RTC_CR_OSCE_MASK;                                   
    /* RTC_CR: CLKO=0 */
    RTC_CR &= (uint32_t)~(uint32_t)(RTC_CR_CLKO_MASK);                                   
  }
  /* Disable the WDOG module */
  /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */
  WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */
  /* WDOG_UNLOCK: WDOGUNLOCK=0xD928 */
  WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */
  /* WDOG_STCTRLH: ??=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,??=0,??=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */
  WDOG_STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) |
                 WDOG_STCTRLH_WAITEN_MASK |
                 WDOG_STCTRLH_STOPEN_MASK |
                 WDOG_STCTRLH_ALLOWUPDATE_MASK |
                 WDOG_STCTRLH_CLKSRC_MASK |
                 0x0100U;       
  /* System clock initialization */
  /* SIM_SCGC5: PORTD=1,PORTC=1,PORTB=1,PORTA=1 */
  SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK |
               SIM_SCGC5_PORTC_MASK |
               SIM_SCGC5_PORTB_MASK |
               SIM_SCGC5_PORTA_MASK;   /* Enable clock gate for ports to enable pin routing */
  if ( *((uint8_t*) 0x03FFU) != 0xFFU) {
    MCG_C3 = *((uint8_t*) 0x03FFU);
    MCG_C4 = (MCG_C4 & 0xE0U) | ((*((uint8_t*) 0x03FEU)) & 0x1FU);
  }
  /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=2,OUTDIV4=5,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) |
                SIM_CLKDIV1_OUTDIV2(0x01) |
                SIM_CLKDIV1_OUTDIV3(0x02) |
                SIM_CLKDIV1_OUTDIV4(0x05); /* Update system prescalers */
  /* SIM_SOPT2: PLLFLLSEL=1 */
  SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
               SIM_SOPT2_PLLFLLSEL(0x02)
              )) | (uint32_t)(
               SIM_SOPT2_PLLFLLSEL(0x01)
              ));                      /* Select PLL 0 as a clock source for various peripherals */
  /* SIM_SOPT1: OSC32KSEL=1 */
  SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; /* RTC oscillator drives 32 kHz clock for various peripherals */
  /* SIM_SCGC1: OSC1=1 */
  SIM_SCGC1 |= SIM_SCGC1_OSC1_MASK;                                   
  /* PORTA_PCR18: ISF=0,MUX=0 */
  PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));                                   
  /* PORTA_PCR19: ISF=0,MUX=0 */
  PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));                                   
  /* Switch to FBE Mode */
  /* MCG_C7: OSCSEL=0 */
  MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);                                   
  /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
  MCG_C2 = MCG_C2_RANGE0(0x02) |
           MCG_C2_HGO0_MASK |
           MCG_C2_EREFS0_MASK |
           MCG_C2_IRCS_MASK;       
  /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
  OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);                                   
  /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
  OSC1_CR = OSC_CR_ERCLKEN_MASK;                                   
  /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
  MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);                                   
  /* MCG_C4: DMX32=0,DRST_DRS=0 */
  MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));                                   
  /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
  MCG_C5 = MCG_C5_PRDIV0(0x00);                                   
  /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
  MCG_C6 = MCG_C6_VDIV0(0x0E);                                   
  /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
  MCG_C11 = MCG_C11_PRDIV1(0x00);                                   
  /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
  MCG_C12 = MCG_C12_VDIV1(0x00);                                   
  while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */
  }
  while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
  }
  while((MCG_S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
  }
  /* Switch to PBE Mode */
  /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
  MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));                                   
  while((MCG_S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
  }
  while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until PLL locked */
  }
  /* Switch to PEE Mode */
  /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
  MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);                                   
  while((MCG_S & 0x0CU) != 0x0CU) {    /* Wait until output of the PLL is selected */
  }
  /* MCG_C6: CME0=1 */
  MCG_C6 |= MCG_C6_CME0_MASK;          /* Enable the clock monitor */
  /*** End of PE initialization code after reset ***/

  /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/

}

/*
** ===================================================================
**     Method      :  Cpu_SetBASEPRI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the BASEPRI core register.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
/*lint -save  -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */
#ifdef _lint
  #define Cpu_SetBASEPRI(Level)  /* empty */
#else
void Cpu_SetBASEPRI(uint32_t Level) {
  asm ("msr basepri, %[input]"::[input] "r" (Level):);
}
#endif
/*lint -restore Enable MISRA rule (2.1,1.1) checking. */


/*
** ===================================================================
**     Method      :  PE_low_level_init (component MK60FN1M0LQ15)
**
**     Description :
**         Initializes beans and provides common register initialization. 
**         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 PE_low_level_init(void)
{
  #ifdef PEX_RTOS_INIT
    PEX_RTOS_INIT();                   /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /* {MQX RTOS Adapter} Set new interrupt vector (function handler and ISR parameter) */
  (void)_int_install_isr(LDD_ivIndex_INT_LLW, Cpu_INT_LLWInterrupt, NULL);
      /* Initialization of the SIM module */
  /* SIM_SOPT2: CMTUARTPAD=0,CLKOUTSEL=2 */
  SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
               SIM_SOPT2_CMTUARTPAD_MASK |
               SIM_SOPT2_CLKOUTSEL(0x05)
              )) | (uint32_t)(
               SIM_SOPT2_CLKOUTSEL(0x02)
              ));                                  
  /* PORTA_PCR4: ISF=0,MUX=7 */
  PORTA_PCR4 = (uint32_t)((PORTA_PCR4 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK
               )) | (uint32_t)(
                PORT_PCR_MUX(0x07)
               ));                                  
        /* Initialization of the RCM module */
  /* RCM_RPFW: RSTFLTSEL=0 */
  RCM_RPFW &= (uint8_t)~(uint8_t)(RCM_RPFW_RSTFLTSEL(0x1F));                                   
  /* RCM_RPFC: RSTFLTSS=0,RSTFLTSRW=0 */
  RCM_RPFC &= (uint8_t)~(uint8_t)(
               RCM_RPFC_RSTFLTSS_MASK |
               RCM_RPFC_RSTFLTSRW(0x03)
              );                                   
      /* Initialization of the PMC module */
  /* PMC_REGSC: ACKISO=0,BGBE=0 */
  PMC_REGSC &= (uint8_t)~(uint8_t)(
                PMC_REGSC_ACKISO_MASK |
                PMC_REGSC_BGBE_MASK
               );                                   
  /* PMC_LVDSC1: LVDACK=1,LVDIE=0,LVDRE=1,LVDV=0 */
  PMC_LVDSC1 = (uint8_t)((PMC_LVDSC1 & (uint8_t)~(uint8_t)(
                PMC_LVDSC1_LVDIE_MASK |
                PMC_LVDSC1_LVDV(0x03)
               )) | (uint8_t)(
                PMC_LVDSC1_LVDACK_MASK |
                PMC_LVDSC1_LVDRE_MASK
               ));                                  
  /* PMC_LVDSC2: LVWACK=1,LVWIE=0,LVWV=0 */
  PMC_LVDSC2 = (uint8_t)((PMC_LVDSC2 & (uint8_t)~(uint8_t)(
                PMC_LVDSC2_LVWIE_MASK |
                PMC_LVDSC2_LVWV(0x03)
               )) | (uint8_t)(
                PMC_LVDSC2_LVWACK_MASK
               ));                                  
  /* SIM_SCGC4: LLWU=1 */
  SIM_SCGC4 |= SIM_SCGC4_LLWU_MASK;                                   
        /* Initialization of the LLWU module */
  /* LLWU_PE1: WUPE3=0,WUPE2=0,WUPE1=0,WUPE0=0 */
  LLWU_PE1 = LLWU_PE1_WUPE3(0x00) |
             LLWU_PE1_WUPE2(0x00) |
             LLWU_PE1_WUPE1(0x00) |
             LLWU_PE1_WUPE0(0x00);       
  /* LLWU_PE2: WUPE7=0,WUPE6=0,WUPE5=0,WUPE4=0 */
  LLWU_PE2 = LLWU_PE2_WUPE7(0x00) |
             LLWU_PE2_WUPE6(0x00) |
             LLWU_PE2_WUPE5(0x00) |
             LLWU_PE2_WUPE4(0x00);       
  /* LLWU_PE3: WUPE11=0,WUPE10=0,WUPE9=0,WUPE8=0 */
  LLWU_PE3 = LLWU_PE3_WUPE11(0x00) |
             LLWU_PE3_WUPE10(0x00) |
             LLWU_PE3_WUPE9(0x00) |
             LLWU_PE3_WUPE8(0x00);       
  /* LLWU_PE4: WUPE15=0,WUPE14=0,WUPE13=0,WUPE12=0 */
  LLWU_PE4 = LLWU_PE4_WUPE15(0x00) |
             LLWU_PE4_WUPE14(0x00) |
             LLWU_PE4_WUPE13(0x00) |
             LLWU_PE4_WUPE12(0x00);       
  /* LLWU_ME: WUME7=0,WUME5=0,WUME4=0,WUME3=0,WUME2=0,WUME1=0,WUME0=1 */
  LLWU_ME = (uint8_t)((LLWU_ME & (uint8_t)~(uint8_t)(
             LLWU_ME_WUME7_MASK |
             LLWU_ME_WUME5_MASK |
             LLWU_ME_WUME4_MASK |
             LLWU_ME_WUME3_MASK |
             LLWU_ME_WUME2_MASK |
             LLWU_ME_WUME1_MASK
            )) | (uint8_t)(
             LLWU_ME_WUME0_MASK
            ));                                  
  /* LLWU_FILT1: FILTF=1,FILTE=0,??=0,FILTSEL=0 */
  LLWU_FILT1 = LLWU_FILT1_FILTF_MASK |
               LLWU_FILT1_FILTE(0x00) |
               LLWU_FILT1_FILTSEL(0x00);       
  /* LLWU_FILT2: FILTF=1,FILTE=0,??=0,FILTSEL=0 */
  LLWU_FILT2 = LLWU_FILT2_FILTF_MASK |
               LLWU_FILT2_FILTE(0x00) |
               LLWU_FILT2_FILTSEL(0x00);       
  /* LLWU_RST: ??=0,??=0,??=0,??=0,??=0,??=0,LLRSTE=0,RSTFILT=0 */
  LLWU_RST = 0x00U;                                   
  /* SMC_PMPROT: ??=0,??=0,AVLP=1,??=0,ALLS=1,??=0,AVLLS=0,??=0 */
  SMC_PMPROT = (SMC_PMPROT_AVLP_MASK | SMC_PMPROT_ALLS_MASK); /* Setup Power mode protection register */
  /* Common initialization of the CPU registers */
  /* NVICIP45: PRI45=0 */
  NVICIP45 = NVIC_IP_PRI45(0x00);                                   
  /* NVICIP46: PRI46=0 */
  NVICIP46 = NVIC_IP_PRI46(0x00);                                   
  /* NVICIP44: PRI44=0 */
  NVICIP44 = NVIC_IP_PRI44(0x00);                                   
  /* NVICIP62: PRI62=0 */
  NVICIP62 = NVIC_IP_PRI62(0x00);                                   
  /* NVICIP20: PRI20=0 */
  NVICIP20 = NVIC_IP_PRI20(0x00);                                   
  /* NVICIP21: PRI21=0 */
  NVICIP21 = NVIC_IP_PRI21(0x00);                                   
  /* SIM_SOPT5: UART0TXSRC=0 */
  SIM_SOPT5 &= (uint32_t)~(uint32_t)(SIM_SOPT5_UART0TXSRC(0x03));                                   
/*
  PORTB_PCR16 = (uint32_t)((PORTB_PCR16 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x04)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x03)
                ));                                  
  PORTB_PCR17 = (uint32_t)((PORTB_PCR17 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x04)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x03)
                ));                                  
  PORTC_PCR1 = (uint32_t)((PORTC_PCR1 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x03)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x04)
               ));                                  
  PORTC_PCR2 = (uint32_t)((PORTC_PCR2 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x03)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x04)
               ));                                  
  PORTC_PCR3 = (uint32_t)((PORTC_PCR3 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x03)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x04)
               ));                                  
  PORTC_PCR4 = (uint32_t)((PORTC_PCR4 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x03)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x04)
               ));                                  
  PORTD_PCR4 = (uint32_t)((PORTD_PCR4 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x03)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x04)
               ));                                  
  PORTD_PCR5 = (uint32_t)((PORTD_PCR5 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x03)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x04)
               ));                                  
  NVICISER1 |= NVIC_ISER_SETENA(0x40000000);                                   
  PORTA_PCR6 = (uint32_t)((PORTA_PCR6 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x02)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x05)
               ));                                  
  NVICISER0 |= NVIC_ISER_SETENA(0x00200000);                                   
*/

  /* ### Init_UART "UART0" init code ... */
  UART0_Init();
  /* ### Init_FTM "FTM0" init code ... */
 // FTM0_Init();
}

/* END Cpu. */

#ifdef __cplusplus
}  /* extern "C" */
#endif 

/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/Main/LCD_control.c<|end_filename|>
#include <mqx.h>
#include <bsp.h>
#include <fio.h>
#include "App.h"


/*-------------------------------------------------------------------------------------------------------------
  Запись команды
-------------------------------------------------------------------------------------------------------------*/
void LCD_wr_cmd(int cmd)
{
  int i;
  LCD_SCB(0);
  DELAY_1us;
  LCD_RS(0);
  DELAY_1us;
  for (i=0;i<8;i++)
  {
    if ( (cmd & 0x80)!=0 )
      LCD_SI(1);
    else
      LCD_SI(0);
    cmd <<=1;
    DELAY_1us;
    LCD_SCL(0);
    DELAY_1us;
    LCD_SCL(1);
    DELAY_1us;
    LCD_SCL(0);
    DELAY_1us;
  }
  LCD_SCB(1);
  LCD_SI(0);
  DELAY_30us;
}

/*-------------------------------------------------------------------------------------------------------------
  Запись команды
-------------------------------------------------------------------------------------------------------------*/
void LCD_wr_data(int data)
{
  int i;
  LCD_SCB(0);
  DELAY_1us;
  LCD_RS(1);
  DELAY_1us;
  for (i=0;i<8;i++)
  {
    if ( (data & 0x80)!=0 )
      LCD_SI(1);
    else
      LCD_SI(0);
    data <<=1;
    DELAY_1us;
    LCD_SCL(0);
    DELAY_1us;
    LCD_SCL(1);
    DELAY_1us;
    LCD_SCL(0);
    DELAY_1us;
  }
  LCD_SCB(1);
  LCD_RS(0);
  LCD_SI(0);
  DELAY_1us;
}

/*-------------------------------------------------------------------------------------------------------------
  Вывести символ в заданную позицию
-------------------------------------------------------------------------------------------------------------*/
void LCD_print_str(char *str, int x, int y)
{
  LCD_set_pos(x,y);
  while (*str)
  {
    LCD_wr_data(*str++);
  }
}

/*-------------------------------------------------------------------------------------------------------------
  Вывести символ в заданную позицию
-------------------------------------------------------------------------------------------------------------*/
void LCD_print_char(char ch, int x, int y)
{
  LCD_set_pos(x,y);
  LCD_wr_data(ch);
}

/*-------------------------------------------------------------------------------------------------------------
  Установить текущую позицию вывода
-------------------------------------------------------------------------------------------------------------*/
void LCD_set_pos(int x, int y)
{
  unsigned char addr;
  addr = y*0x40+x;
  LCD_wr_cmd(addr + 0x80);     
}

/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
void LCD_clear_row(int row)
{
  int i;
  LCD_set_pos(0, row & 1);
  for (i=0;i<16;i++)
  {
    LCD_wr_data(0x20);
  }
}
/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void LCD_init(void)
{
  LCD_RST(0);
  _time_delay_ticks(1);
  LCD_RST(1);
  _time_delay_ticks(8);
  LCD_wr_cmd(0x30);     //wake up
  _time_delay_ticks(1);
  LCD_wr_cmd(0x30);     //wake up
  LCD_wr_cmd(0x30);     //wake up
  LCD_wr_cmd(0x39);     //function set. 8-bit bus mode, 2-line display mode is set, display font is normal (5x8 dot), extension instruction be selected
  LCD_wr_cmd(0x14);     //internal osc frequency. bias will be 1/5 , Frame frequency ( Hz ) = 183
  LCD_wr_cmd(0x56);     //power control. ICON display off, booster circuit is turn on.
  LCD_wr_cmd(0x6D);     //internal follower circuit is turn on, 
  LCD_wr_cmd(0x70);     //contrast
  LCD_wr_cmd(0x0C);     //display on
  LCD_wr_cmd(0x06);     //entry mode
  LCD_wr_cmd(0x01);     //clear
  _time_delay_ticks(2);
}


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_ppp.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved

*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_ppp.c$
* $Version : 3.8.10.0$
* $Date    : Oct-2-2012$
*
* Comments:
*
*   This file contains the RTCS shell command related to PPP connection.
*
*END************************************************************************/
#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h"
#include <ppp.h>
#include <fio.h>


SHELL_PPP_LINK default_ppp;

static boolean   PPP_link = FALSE;
static void PPP_linkup (pointer lwsem)
{
    PPP_link = TRUE;
    _lwsem_post(lwsem);
    printf( " PPP link On \n");
}
static void PPP_linkdown (pointer lwsem)
{
    PPP_link = FALSE;
    _lwsem_post(lwsem);
    printf( " PPP link Off \n");
}
extern PPP_SECRET_PTR _PPP_PAP_LSECRET;
extern PPP_SECRET_PTR _PPP_PAP_RSECRETS;
extern char_ptr       _PPP_CHAP_LNAME;
extern PPP_SECRET_PTR _PPP_CHAP_LSECRETS;
extern PPP_SECRET_PTR _PPP_CHAP_RSECRETS;

void   shell_ppp_start(SHELL_PPP_LINK_PTR ppp_current);
int_32 shell_ppp_stop(SHELL_PPP_LINK_PTR ppp_current);

/*FUNCTION*------------------------------------------------
*
* Function Name: Shell_ppp
* Comments     : Shell command "ppp" is starting or stopping PPP connection.
*
*END*-----------------------------------------------------*/
int_32 Shell_ppp(int_32 argc, char_ptr argv[] )
{
    uint_32           error;
    uint_32           i=1;
    boolean           print_usage, shorthelp = FALSE;

   default_ppp.LOCAL_NAME     = NULL;
   default_ppp.LOCAL_PASSWORD = <PASSWORD>;

   /* Check for help. */
    print_usage = Shell_check_help_request(argc, argv, &shorthelp );
    if (!print_usage)
    {
        if (argc >= 2)
        {  /* If we have more args, we need parce them. */
            while(i<argc)
            {
                switch (i)
                {
                    case (1):
                        /* If "stop" start shell_ppp_stop. */
                        if( strcmp(argv[i],"stop")==0)
                        {
                            return(shell_ppp_stop(&default_ppp));
                        }
                        else if(strcmp(argv[i],"client")==0)
                        {
                            default_ppp.SERVER_FLAG=0;
                        }
                        else if(strcmp(argv[i],"server")==0)
                        {
                            default_ppp.SERVER_FLAG=1;
                            /* In case of "server" we need have min 7 arg : ppp server ittyX: rlogin rpassword boardip clientip */
                            if(argc <=6)
                            {
                                print_usage = TRUE;
                            }
                        }
                        else
                        {
                            print_usage = TRUE;
                        }
                        break;
                    case (2):
                        if( strstr(argv[i],"itty") !=0)
                        {
                            default_ppp.PPP_CONNECTION_DEVICE = argv[i];
                        }
                         else
                        {
                            printf("Incorrect ittyX: device name.\n");
                            print_usage = TRUE;
                        }
                        break;
                    case (3):
                        if(default_ppp.SERVER_FLAG==0)
                        {
                            default_ppp.LOCAL_NAME = argv[i];
                        }
                        else
                        {
                            default_ppp.REMOTE_NAME = argv[i];
                        }
                        break;
                    case (4):
                        if(default_ppp.SERVER_FLAG==0)
                        {
                            default_ppp.LOCAL_PASSWORD = argv[i];
                        }
                        else
                        {
                            default_ppp.REMOTE_PASSWORD = argv[i];
                        }
                        break;
                    case (5):
                        if(default_ppp.SERVER_FLAG==1)
                        {  /* It is valid only for server mode.*/
                          if( inet_pton(AF_INET, argv[i],&default_ppp.PPP_LOCAL_ADDRESS,sizeof(default_ppp.PPP_LOCAL_ADDRESS)) == (uint_32)RTCS_ERROR)
                            {
                                print_usage = TRUE;
                            }
                        }
                        else
                        {
                            print_usage = TRUE;
                        }
                        break;
                    case (6):
                        if(default_ppp.SERVER_FLAG==1)
                        {  /* It is valid only for server mode.*/
                            if( inet_pton(AF_INET, argv[i],&default_ppp.PPP_REMOTE_ADDRESS,sizeof(default_ppp.PPP_REMOTE_ADDRESS)) ==(uint_32)RTCS_ERROR)
                            {
                                print_usage = TRUE;
                            }
                        }
                        else
                        {
                            print_usage = TRUE;
                        }
                        break;
                    default:
                        error = 0;
                        break;
                }
                i++;
            }
        }
        else
        {
            print_usage = TRUE;
        }
    }

    if (print_usage)
    {
        if (shorthelp)
        {
            printf(" %s - Start PPP connection. \n", argv[0]);
            return RTCS_OK;
        }
        else
        {
            printf(" Usage: %s\n", argv[0]);
            printf(" [param] [device name] [login] [password] [localIPaddress ] [remoteIPaddress]\n");
            printf(" [param]           - is \"server\", \"client\" \"stop\"\n");
            printf(" [device name]     - is system name of interrupting device,\n");
            printf("                     suitable for your board, like  ittyX: \n");
            printf(" [login] and\n");
            printf(" [password]        - is \"login\" and \"password\" for PPP PAP.\n");
            printf("                     For \"server\" login and pass should be defined. \n");
            printf("                     For \"server\" and \"client\" the device name is requered.\n");
            printf(" [localIPaddress]  - is IP addres of your board(server mode).\n");
            printf(" [remoteIPaddress] - is IP addres for  client of your board(server mode).\n");
            printf("\n Examples:\n");
            printf("    To start PPP client using \"ittyd:\" you need type:\n");
            printf("        shell> ppp client ittyd: \n");
            printf("    or using PPP PAP client:\n");
            printf("        shell> ppp client ittyd: yourlogin yourpassword \n");
            printf("\n    To start PPP PAP server using \"ittyd:\":\n");
            printf("        shell> ppp server ittyd: yrlog yrpass brd_ip_addr cl_ip_addr\n");
            printf("        shell> ppp server ittyd: guest anon 192.168.0.1 192.168.0.217\n");
            printf("\n    To stop PPP connection you need type \"ppp stop\":\n");
            printf("        shell> ppp stop\n\n");
            return RTCS_OK;
        }
    }
   /* Check if PPP already started. */
    if(default_ppp.PPP_HANDLE)
    {
        printf("\n PPP already started. Stop it first.\n");
        return RTCS_OK;
    }
   /* Start connection:   */
   /* Open serial device. */
    default_ppp.PPP_CON_DEV_HANDLE = fopen(default_ppp.PPP_CONNECTION_DEVICE, NULL);

   /* Open suitable ppp device. */
    if(default_ppp.SERVER_FLAG==0)
    {
        /* Open PPP like client. */
        default_ppp.PPP_DEV_HANDLE = fopen("dcn:", (char_ptr)default_ppp.PPP_CON_DEV_HANDLE);
        /* Checking, does it open ? */
        if(default_ppp.PPP_DEV_HANDLE == NULL)
        {
            if(default_ppp.PPP_CON_DEV_HANDLE)
            {
                /* Close PPP_DEVICE. */
                fclose(default_ppp.PPP_CON_DEV_HANDLE);
            }
            printf("\n ERROR: Can not open \"dcn\" PPP driver.\n");
            return RTCS_ERROR;
        }
    }
    else
    {
        /* Open PPP like server. */
        default_ppp.PPP_DEV_HANDLE = fopen("dun:", (char_ptr)default_ppp.PPP_CON_DEV_HANDLE);
        /* Checking, does it open ? */
        if(default_ppp.PPP_DEV_HANDLE == NULL)
        {
            /* Checking, was driver installed or not. */
            if(default_ppp.PPP_CON_DEV_HANDLE)
            {
                /* Close Close PPP_DEVICE. */
                fclose(default_ppp.PPP_CON_DEV_HANDLE);
            }
            printf("\n ERROR: Can not open \"dun\" PPP driver.\n");
            return RTCS_ERROR;
        }
    }

    if(default_ppp.SERVER_FLAG==0)
    {
       /* Send invitation string to Windows PPP server. */
        _io_fputs("CLIENTCLIENT", default_ppp.PPP_DEV_HANDLE);
        fflush(default_ppp.PPP_DEV_HANDLE);
       /* Start connection procedure. */
        default_ppp.PPP_GATE_ADDR = IPADDR(192,168,0,1);
    }
    else
    {
        default_ppp.PPP_GATE_ADDR = default_ppp.PPP_LOCAL_ADDRESS;
        /* Fill  rsecrets[] array here. */
         default_ppp.rsecrets[0].PPP_ID_LENGTH = strlen(default_ppp.REMOTE_NAME);
         default_ppp.rsecrets[0].PPP_PW_LENGTH = strlen(default_ppp.REMOTE_PASSWORD);
         default_ppp.rsecrets[0].PPP_ID_PTR    = default_ppp.REMOTE_NAME;
         default_ppp.rsecrets[0].PPP_PW_PTR    = default_ppp.REMOTE_PASSWORD;
         default_ppp.rsecrets[1].PPP_ID_LENGTH = 0;
         default_ppp.rsecrets[1].PPP_PW_LENGTH = 0;
         default_ppp.rsecrets[1].PPP_ID_PTR    = NULL;
         default_ppp.rsecrets[1].PPP_PW_PTR    = NULL;
    }

    shell_ppp_start(&default_ppp);
    /* shell_ppp_start() must get PPP_HANDLE */
    if(default_ppp.PPP_HANDLE)
    {
        return RTCS_OK;
    }
    else
    {  /* Remove all created elements. */
        printf("\n Error: The connection attemp failed because the modem (or other connecting device) on the remote computer is out of order \n");
        /* Destroy semafor. */
        error = _lwsem_destroy(&default_ppp.PPP_SEM);
        if(default_ppp.PPP_IF_HANDLE)
        {
           /* Unregister PPP interface. */
            error = RTCS_if_remove(default_ppp.PPP_IF_HANDLE);
        }
        if(default_ppp.PPP_IO_DRIVER_HANDLE)
        {
           /* Close PPP driver. */
            error = _iopcb_close(default_ppp.PPP_IO_DRIVER_HANDLE);
        }
        if(default_ppp.PPP_DEV_HANDLE)
        {
            /* Close PPP driver. */
            error = fclose(default_ppp.PPP_DEV_HANDLE);
        }
        if(default_ppp.PPP_CON_DEV_HANDLE)
        {
            /* Close Close PPP_DEVICE. */
            error = fclose(default_ppp.PPP_CON_DEV_HANDLE);
        }
        if(error)
        {
          printf("\nSome error happend during closing PPP connection.\n");
        }
        else
        {
          printf("\nPPP connection closed.\n");
        }
        return RTCS_ERROR;
    }
}

/*FUNCTION*------------------------------------------------
*
* Function Name: shell_ppp_stop
* Comments     : Shell command "ppp stop" is calling this function to stop PPP connection.
*
*END*-----------------------------------------------------*/
int_32 shell_ppp_stop(SHELL_PPP_LINK_PTR local_ppp)
{
    uint_32           error;

   /* Check if PPP is alive. */
    if(!local_ppp->PPP_HANDLE)
    {
      printf("Can not stop PPP.It is not started\n");
    }
   /* Cleanup PPP connection. */

   /* Unbind interface. */
    error = RTCS_if_unbind(local_ppp->PPP_IF_HANDLE, IPCP_get_local_addr(local_ppp->PPP_IF_HANDLE));
    if(default_ppp.PPP_HANDLE)
    {
       /* Send connection terminate request to remote server and close PPP connection. */
        error = PPP_close(local_ppp->PPP_HANDLE);

       /* Clean up all PPP structure. */
        error = PPP_shutdown(local_ppp->PPP_HANDLE);
        local_ppp->PPP_HANDLE =NULL;
    }
   /* Destroing the semafor. */
    error = _lwsem_destroy(&local_ppp->PPP_SEM);
    if(local_ppp->PPP_IF_HANDLE)
    {
       /* Unregister PPP interface. */
        error = RTCS_if_remove(local_ppp->PPP_IF_HANDLE);
        local_ppp->PPP_IF_HANDLE=0;
    }
    if(local_ppp->PPP_IO_DRIVER_HANDLE)
    {
       /* Closing PPP driver. */
        error = _iopcb_close(local_ppp->PPP_IO_DRIVER_HANDLE);
    }
    if(local_ppp->PPP_DEV_HANDLE)
    {
        /* Close PPP driver. */
         error = fclose(default_ppp.PPP_DEV_HANDLE);
    }
    if(local_ppp->PPP_CON_DEV_HANDLE)
    {
       /* Close Close PPP_DEVICE. */
        error = fclose(default_ppp.PPP_CON_DEV_HANDLE);
    }
    local_ppp->PPP_HANDLE = NULL;
   /* We need remove route. */
    RTCS_gate_remove(local_ppp->PPP_GATE_ADDR, INADDR_ANY, INADDR_ANY);
    if(error)
    {
      printf("\nSome error happend during closing PPP connection.\n");
      return RTCS_ERROR;
    }
    else
    {
      printf("PPP connection closed\n");
      return RTCS_OK;
    }
}

/*FUNCTION*------------------------------------------------
*
* Function Name: shell_ppp_start()
* Comments     :
*   This function start PPP communication and try to establish PPP connection.
*END*-----------------------------------------------------*/
void shell_ppp_start(SHELL_PPP_LINK_PTR ppp_current)
{
     uint_32           error;
     _ip_address       local_address;
     _ip_address       peer_address=0;
     IPCP_DATA_STRUCT  ipcp_data;

    /* This is configuration for PAP. */
     char* localname     = ppp_current->LOCAL_NAME;
     char* localsecret   = ppp_current->LOCAL_PASSWORD;
     PPP_SECRET lsecret;
    if(default_ppp.SERVER_FLAG==0)
    {   /* Setup  PAP for client mode.*/
         lsecret.PPP_ID_LENGTH = strlen(localname);
         lsecret.PPP_PW_LENGTH = strlen(localsecret);
         lsecret.PPP_ID_PTR    = localname;
         lsecret.PPP_PW_PTR    = localsecret;
        _PPP_PAP_LSECRET   = &lsecret; /* lsecrets  */
        _PPP_PAP_RSECRETS  =  NULL;    /* rsecrets  */
        _PPP_CHAP_LNAME    =  NULL;    /* localname */
        _PPP_CHAP_LSECRETS =  NULL;    /* lsecrets  */
        _PPP_CHAP_RSECRETS =  NULL;    /* rsecrets  */
    }
    else if(default_ppp.SERVER_FLAG==1)
    {   /* Setup  PAP for server mode.*/
        _PPP_PAP_LSECRET   =  NULL;                  /* lsecrets  */
        _PPP_PAP_RSECRETS  =  ppp_current->rsecrets; /* rsecrets  */
        _PPP_CHAP_LNAME    =  NULL;                  /* localname */
        _PPP_CHAP_LSECRETS =  NULL;                  /* lsecrets  */
        _PPP_CHAP_RSECRETS =  NULL;                  /* rsecrets  */
    }
    else
    {
         ppp_current->PPP_HANDLE = NULL;
         return;
    }

   /* Install a route for a default gateway */
    RTCS_gate_add(ppp_current->PPP_GATE_ADDR, INADDR_ANY, INADDR_ANY);

    ppp_current->PPP_IO_DRIVER_HANDLE = _iopcb_ppphdlc_init(ppp_current->PPP_DEV_HANDLE);
    _PPP_ACCM = 0;
    error = PPP_initialize(ppp_current->PPP_IO_DRIVER_HANDLE, &ppp_current->PPP_HANDLE);
    if (error)
    {
       printf("\n PPP initialize: %lx", error);
       _task_block();
    }
    _iopcb_open(ppp_current->PPP_IO_DRIVER_HANDLE, PPP_lowerup, PPP_lowerdown,ppp_current->PPP_HANDLE);
    error = RTCS_if_add(ppp_current->PPP_HANDLE, RTCS_IF_PPP, &ppp_current->PPP_IF_HANDLE);
    if (error)
    {
       printf("\n IF add failed, error = %lx", error);
       _task_block();
    }
    _lwsem_create(&ppp_current->PPP_SEM, 0);
    _mem_zero(&ipcp_data, sizeof(ipcp_data));
    ipcp_data.IP_UP              = PPP_linkup;
    ipcp_data.IP_DOWN            = PPP_linkdown;
    ipcp_data.IP_PARAM           = &ppp_current->PPP_SEM;

    if(default_ppp.SERVER_FLAG==0)
    {
        ipcp_data.ACCEPT_LOCAL_ADDR  = TRUE;
        ipcp_data.ACCEPT_REMOTE_ADDR = TRUE;
    }
    else
    {
        ipcp_data.ACCEPT_LOCAL_ADDR  = FALSE;
        ipcp_data.ACCEPT_REMOTE_ADDR = FALSE;
    }
    ipcp_data.LOCAL_ADDR         = ppp_current->PPP_LOCAL_ADDRESS;
    ipcp_data.REMOTE_ADDR        = ppp_current->PPP_REMOTE_ADDRESS;
    ipcp_data.DEFAULT_NETMASK    = TRUE;
    ipcp_data.DEFAULT_ROUTE      = TRUE;

    error = RTCS_if_bind_IPCP(ppp_current->PPP_IF_HANDLE, &ipcp_data);

    if (error)
    {
       printf("\n IF bind failed, error = %lx", error);
       _task_block();
    }

    /*In case "client" we need wait for connection to server*/
    if(default_ppp.SERVER_FLAG==0)
    {
        printf("\n Please wait initiate PPP connection.  Waiting...\n");
       /*Handshake with RAS server */
       /* 10 attempts to connect */
        error = 0;
        while (error < 10)
        {
            if (PPP_link == FALSE)
            {
                _time_delay(1000);
            }
            else
            {
                printf("\n PPP_link = %d, time = %d\n",PPP_link,error);
                break;
            }
            error ++;
        }

        if (PPP_link == TRUE)
        {
            local_address = IPCP_get_local_addr(ppp_current->PPP_IF_HANDLE);
            peer_address = IPCP_get_peer_addr(ppp_current->PPP_IF_HANDLE);
            printf("\n PPP device on %s is bound on.\n", ppp_current->PPP_CONNECTION_DEVICE );
            printf(" PPP local  address is : %d.%d.%d.%d\n", IPBYTES(local_address));
            printf(" PPP remote address is : %d.%d.%d.%d\n", IPBYTES(peer_address));
            printf(" Now PPP connection is established on %d.%d.%d.%d\n", IPBYTES(peer_address));
        }
        else
        {
            if(ppp_current->PPP_HANDLE)
            {
               /* clean up all PPP structure */
                error = PPP_shutdown(ppp_current->PPP_HANDLE);
            }
            ppp_current->PPP_HANDLE = NULL;
           /* We shoul remove route to clear part block. */
            RTCS_gate_remove(ppp_current->PPP_GATE_ADDR, INADDR_ANY, INADDR_ANY);
        }

    }
    else
    {
       /* In case of "server" we do not need wait at all. */
        printf("\n PPP server ready and waiting for connection.\n");
    }
}
#endif /* SHELLCFG_USES_RTCS */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/esdhc/esdhc.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: esdhc.c$
* $Version : 3.8.12.0$
* $Date    : Jul-19-2012$
*
* Comments:
*
*   The file contains low level eSDHC driver functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include <string.h>
#include "esdhc.h"
#include "esdhc_prv.h"


/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_set_baudrate
* Returned Value   : None
* Comments         :
*    Find and set closest divider values for given baudrate.
*
*END*********************************************************************/
static void _esdhc_set_baudrate
    (
        /* [IN/OUT] Module registry pointer */
        SDHC_MemMapPtr esdhc_ptr,

        /* [IN] Module input clock in Hz */
        uint_32         clock,

        /* [IN] Desired baudrate in Hz */
        uint_32         baudrate
    )
{
    uint_32 pres, div, min, minpres = 0x80, mindiv = 0x0F;
    int_32  val;

    /* Find closest setting */
    min = (uint_32)-1;
    for (pres = 2; pres <= 256; pres <<= 1)
    {
        for (div = 1; div <= 16; div++)
        {
            val = pres * div * baudrate - clock;
            if (val >= 0)
            {
                if (min > val)
                {
                    min = val;
                    minpres = pres;
                    mindiv = div;
                }
            }
        }
    }

    /* Disable ESDHC clocks */
    esdhc_ptr->SYSCTL &= (~ SDHC_SYSCTL_SDCLKEN_MASK);

    /* Change dividers */
    div = esdhc_ptr->SYSCTL & (~ (SDHC_SYSCTL_DTOCV_MASK | SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK));
    esdhc_ptr->SYSCTL = div | (SDHC_SYSCTL_DTOCV(0x0E) | SDHC_SYSCTL_SDCLKFS(minpres >> 1) | SDHC_SYSCTL_DVS(mindiv - 1));

    /* Wait for stable clock */
    while (0 == (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_SDSTB_MASK))
    {
        /* Workaround... */
        _time_delay (BSP_ALARM_RESOLUTION);

     /* not every controller has this bit */
#if defined (BSP_M53015EVB) || (BSP_MPC8377RDB)
        break;
#endif
    };

    /* Enable ESDHC clocks */
    esdhc_ptr->SYSCTL |= SDHC_SYSCTL_SDCLKEN_MASK;
    esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DTOE_MASK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_is_running
* Returned Value   : TRUE if running, FALSE otherwise
* Comments         :
*    Checks whether eSDHC module is currently in use.
*
*END*********************************************************************/
static boolean _esdhc_is_running
    (
        /* [IN] Module registry pointer */
        SDHC_MemMapPtr esdhc_ptr
    )
{
    return (0 != (esdhc_ptr->PRSSTAT & (SDHC_PRSSTAT_RTA_MASK | SDHC_PRSSTAT_WTA_MASK | SDHC_PRSSTAT_DLA_MASK | SDHC_PRSSTAT_CDIHB_MASK | SDHC_PRSSTAT_CIHB_MASK)));
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_status_wait
* Returned Value   : bits set for given mask
* Comments         :
*    Waits for ESDHC interrupt status register bits according to given mask.
*
*END*********************************************************************/
static uint_32 _esdhc_status_wait
    (
        /* [IN] Module registry pointer */
        SDHC_MemMapPtr esdhc_ptr,

        /* [IN] Mask of IRQSTAT bits to wait for */
        uint_32         mask
    )
{
    uint_32             result;
    do
    {
        result = esdhc_ptr->IRQSTAT & mask;
    }
    while (0 == result);
    return result;
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_init
* Returned Value   : MQX error code
* Comments         :
*    ESDHC registers initialization and card detection.
*
*END*********************************************************************/
static int_32 _esdhc_init
    (
        /* [IN/OUT] Module registry pointer */
        SDHC_MemMapPtr        esdhc_ptr,

        /* [IN/OUT] Device runtime information */
        ESDHC_INFO_STRUCT_PTR  esdhc_info_ptr,

        /* [IN] Device initialization data */
        ESDHC_INIT_STRUCT_CPTR esdhc_init_ptr
    )
{
    esdhc_info_ptr->CARD = ESDHC_CARD_NONE;

    /* De-init GPIO - to prevent unwanted clocks on bus */
    if (_bsp_esdhc_io_init (esdhc_init_ptr->CHANNEL, 0) == -1)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    /* Reset ESDHC */
    esdhc_ptr->SYSCTL = SDHC_SYSCTL_RSTA_MASK | SDHC_SYSCTL_SDCLKFS(0x80);
    while (esdhc_ptr->SYSCTL & SDHC_SYSCTL_RSTA_MASK)
        { };

    /* Initial values */
    esdhc_ptr->VENDOR = 0;
    esdhc_ptr->BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(512);
#if PSP_ENDIAN == MQX_BIG_ENDIAN
    esdhc_ptr->PROCTL = SDHC_PROCTL_EMODE(ESDHC_PROCTL_EMODE_BIG) | SDHC_PROCTL_D3CD_MASK;
#else
    esdhc_ptr->PROCTL = SDHC_PROCTL_EMODE(ESDHC_PROCTL_EMODE_LITTLE) | SDHC_PROCTL_D3CD_MASK;
#endif
    esdhc_ptr->WML = SDHC_WML_RDWML(2) | SDHC_WML_WRWML(1);

    /* Set the ESDHC initial baud rate divider and start */
    _esdhc_set_baudrate (esdhc_ptr, esdhc_init_ptr->CLOCK_SPEED, 400000);

    /* Poll inhibit bits */
    while (esdhc_ptr->PRSSTAT & (SDHC_PRSSTAT_CIHB_MASK | SDHC_PRSSTAT_CDIHB_MASK))
        { };

    /* Init GPIO again */
    if (_bsp_esdhc_io_init (esdhc_init_ptr->CHANNEL, 0xFFFF) == -1)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    /* Enable requests */
    esdhc_ptr->IRQSTAT = 0xFFFF;
    esdhc_ptr->IRQSTATEN = SDHC_IRQSTATEN_DEBESEN_MASK | SDHC_IRQSTATEN_DCESEN_MASK | SDHC_IRQSTATEN_DTOESEN_MASK
                         | SDHC_IRQSTATEN_CIESEN_MASK | SDHC_IRQSTATEN_CEBESEN_MASK | SDHC_IRQSTATEN_CCESEN_MASK | SDHC_IRQSTATEN_CTOESEN_MASK
                         | SDHC_IRQSTATEN_BRRSEN_MASK | SDHC_IRQSTATEN_BWRSEN_MASK | SDHC_IRQSTATEN_CRMSEN_MASK
                         | SDHC_IRQSTATEN_TCSEN_MASK | SDHC_IRQSTATEN_CCSEN_MASK;

    /* 80 initial clocks */
    esdhc_ptr->SYSCTL |= SDHC_SYSCTL_INITA_MASK;
    while (esdhc_ptr->SYSCTL & SDHC_SYSCTL_INITA_MASK)
        { };

    /* Check card */
    if (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_CINS_MASK)
    {
        esdhc_info_ptr->CARD = ESDHC_CARD_UNKNOWN;
    }
    esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_CRM_MASK;

    return ESDHC_OK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_send_command
* Returned Value   : 0 on success, 1 on error, -1 on timeout
* Comments         :
*    One ESDHC command transaction.
*
*END*********************************************************************/
static int_32 _esdhc_send_command
    (
        /* [IN/OUT] Module registry pointer */
        SDHC_MemMapPtr          esdhc_ptr,

        /* [IN/OUT] Command specification */
        ESDHC_COMMAND_STRUCT_PTR command
    )
{
    uint_32                      xfertyp;
    uint_32                      blkattr;

    /* Check command */
    xfertyp = command->COMMAND;

    if (ESDHC_XFERTYP_CMDTYP_RESUME == ((xfertyp & SDHC_XFERTYP_CMDTYP_MASK) >> SDHC_XFERTYP_CMDTYP_SHIFT))
    {
        /* DPSEL shall always be set for resume type commands */
        xfertyp |= SDHC_XFERTYP_DPSEL_MASK;
    }

    if ((0 != command->BLOCKS) && (0 != command->BLOCKSIZE))
    {
        xfertyp |= SDHC_XFERTYP_DPSEL_MASK;
        if (command->BLOCKS != 1)
        {
            /* multiple block transfer */
            xfertyp |= SDHC_XFERTYP_MSBSEL_MASK;
        }
        if ((uint_32)-1 == command->BLOCKS)
        {
            /* infinite transfer */
            blkattr = SDHC_BLKATTR_BLKSIZE(command->BLOCKSIZE) | SDHC_BLKATTR_BLKCNT(0xFFFF);
        }
        else
        {
            blkattr = SDHC_BLKATTR_BLKSIZE(command->BLOCKSIZE) | SDHC_BLKATTR_BLKCNT(command->BLOCKS);
            xfertyp |= SDHC_XFERTYP_BCEN_MASK;
        }
    }
    else
    {
        blkattr = 0;
    }

    /* Card removal check preparation */
    esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_CRM_MASK;

    /* Wait for cmd line idle */
    while (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_CIHB_MASK)
        { };

    /* Setup command */
    esdhc_ptr->CMDARG = command->ARGUMENT;
    esdhc_ptr->BLKATTR = blkattr;
    esdhc_ptr->DSADDR = 0;

    /* Issue command */
    esdhc_ptr->XFERTYP = xfertyp;

    /* Wait for response */
    if (_esdhc_status_wait (esdhc_ptr, SDHC_IRQSTAT_CIE_MASK | SDHC_IRQSTAT_CEBE_MASK | SDHC_IRQSTAT_CCE_MASK | SDHC_IRQSTAT_CC_MASK) != SDHC_IRQSTAT_CC_MASK)
    {
        esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_CTOE_MASK | SDHC_IRQSTAT_CIE_MASK | SDHC_IRQSTAT_CEBE_MASK | SDHC_IRQSTAT_CCE_MASK | SDHC_IRQSTAT_CC_MASK;
        return 1;
    }

    /* Check card removal */
    if (esdhc_ptr->IRQSTAT & SDHC_IRQSTAT_CRM_MASK)
    {
        esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_CTOE_MASK | SDHC_IRQSTAT_CC_MASK;
        return 1;
    }

    /* Get response, if available */
    if (esdhc_ptr->IRQSTAT & SDHC_IRQSTAT_CTOE_MASK)
    {
        esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_CTOE_MASK | SDHC_IRQSTAT_CC_MASK;
        return -1;
    }
    if ((xfertyp & SDHC_XFERTYP_RSPTYP_MASK) != SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_NO))
    {
        command->RESPONSE[0] = esdhc_ptr->CMDRSP[0];
        if ((xfertyp & SDHC_XFERTYP_RSPTYP_MASK) == SDHC_XFERTYP_RSPTYP(ESDHC_XFERTYP_RSPTYP_136))
        {
            command->RESPONSE[1] = esdhc_ptr->CMDRSP[1];
            command->RESPONSE[2] = esdhc_ptr->CMDRSP[2];
            command->RESPONSE[3] = esdhc_ptr->CMDRSP[3];
        }
    }
    esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_CC_MASK;

    return 0;
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_install
* Returned Value   : MQX error code
* Comments         :
*    Install an ESDHC device.
*
*END*********************************************************************/
_mqx_int _esdhc_install
    (
        /* [IN] A string that identifies the device for fopen */
        char_ptr               identifier,

        /* [IN] The I/O init data pointer */
        ESDHC_INIT_STRUCT_CPTR esdhc_init_ptr
    )
{
    ESDHC_DEVICE_STRUCT_PTR    esdhc_device_ptr;
    _mqx_uint                  result;

    /* Check parameters */
    if ((NULL == identifier) || (NULL == esdhc_init_ptr))
    {
        return MQX_INVALID_PARAMETER;
    }

    /* Check previous installation */
    _int_disable();

    /* Create device context */
    esdhc_device_ptr = _mem_alloc_system_zero ((_mem_size) sizeof (ESDHC_DEVICE_STRUCT));
    if (NULL == esdhc_device_ptr)
    {
        _int_enable();
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type (esdhc_device_ptr, MEM_TYPE_IO_ESDHC_DEVICE_STRUCT);

    /* Install device */
    result = _io_dev_install_ext(identifier,
        _esdhc_open,
        _esdhc_close,
        _esdhc_read,
        _esdhc_write,
        _esdhc_ioctl,
        _esdhc_uninstall,
        (pointer)esdhc_device_ptr);

    /* Context initialization or cleanup */
    if (MQX_OK == result)
    {
        esdhc_device_ptr->INIT = esdhc_init_ptr;
        esdhc_device_ptr->COUNT = 0;
    }
    else
    {
        _mem_free (esdhc_device_ptr);
    }
    _int_enable();

    return result;
}


/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_uninstall
* Returned Value   : MQX error code
* Comments         :
*    Uninstall an ESDHC device.
*
*END**********************************************************************/

_mqx_int _esdhc_uninstall
    (
        /* [IN/OUT] The device to uninstall */
        IO_DEVICE_STRUCT_PTR dev_ptr
    )
{
    ESDHC_DEVICE_STRUCT_PTR  esdhc_device_ptr;

    /* Check parameters */
    if (NULL == dev_ptr)
    {
        return IO_DEVICE_DOES_NOT_EXIST;
    }
    esdhc_device_ptr = dev_ptr->DRIVER_INIT_PTR;
    if (NULL == esdhc_device_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    /* Uninstall only when not opened */
    if (esdhc_device_ptr->COUNT)
    {
        return IO_ERROR_DEVICE_BUSY;
    }

    /* Cleanup */
    _mem_free (esdhc_device_ptr);
    dev_ptr->DRIVER_INIT_PTR = NULL;

    return IO_OK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_open
* Returned Value   : MQX error code
* Comments         :
*    This function exclusively opens the ESDHC device.
*
*END*********************************************************************/
_mqx_int _esdhc_open
    (
        /* [IN/OUT] ESDHC file descriptor */
        MQX_FILE_PTR        esdhc_fd_ptr,

        /* [IN] The remaining portion of the name of the device */
        char_ptr            open_name_ptr,

        /* [IN] The flags to be used during operation */
        char_ptr            open_flags_ptr
    )
{
    IO_DEVICE_STRUCT_PTR    io_dev_ptr;
    ESDHC_INFO_STRUCT_PTR   esdhc_info_ptr;
    ESDHC_DEVICE_STRUCT_PTR esdhc_device_ptr;
    ESDHC_INIT_STRUCT_CPTR  esdhc_init_ptr;
    SDHC_MemMapPtr          esdhc_ptr;

    /* Check parameters */
    if (NULL == esdhc_fd_ptr)
    {
        return MQX_INVALID_PARAMETER;
    }
    io_dev_ptr = esdhc_fd_ptr->DEV_PTR;
    if (NULL == io_dev_ptr)
    {
        return IO_DEVICE_DOES_NOT_EXIST;
    }
    esdhc_device_ptr = io_dev_ptr->DRIVER_INIT_PTR;
    if (NULL == esdhc_device_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }
    esdhc_init_ptr = esdhc_device_ptr->INIT;
    if (NULL == esdhc_init_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    /* Get register base */
    esdhc_ptr = _bsp_get_esdhc_base_address (esdhc_init_ptr->CHANNEL);
    if (NULL == esdhc_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    /* Exclusive access till close */
    _int_disable();
    if (esdhc_device_ptr->COUNT)
    {
        /* Device is already opened */
        _int_enable();
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    esdhc_device_ptr->COUNT = 1;
    _int_enable();

    /* Set device info */
    esdhc_info_ptr = (ESDHC_INFO_STRUCT_PTR)_mem_alloc_system_zero ((_mem_size) sizeof (ESDHC_INFO_STRUCT));
    if (NULL == esdhc_info_ptr)
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type (esdhc_info_ptr, MEM_TYPE_IO_ESDHC_INFO_STRUCT);
    esdhc_fd_ptr->DEV_DATA_PTR = esdhc_info_ptr;

    return _esdhc_init (esdhc_ptr, esdhc_info_ptr, esdhc_init_ptr);
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_close
* Returned Value   : MQX error code
* Comments         :
*    This function closes opened ESDHC device.
*
*END*********************************************************************/
_mqx_int _esdhc_close
    (
        /* [IN/OUT] Opened file pointer for ESDHC */
        MQX_FILE_PTR        esdhc_fd_ptr
    )
{
    IO_DEVICE_STRUCT_PTR    io_dev_ptr;
    ESDHC_DEVICE_STRUCT_PTR esdhc_device_ptr;
    ESDHC_INIT_STRUCT_CPTR  esdhc_init_ptr;
    SDHC_MemMapPtr         esdhc_ptr;

    /* Check parameters */
    if (NULL == esdhc_fd_ptr)
    {
        return MQX_INVALID_PARAMETER;
    }
    io_dev_ptr = (IO_DEVICE_STRUCT_PTR)esdhc_fd_ptr->DEV_PTR;
    if (NULL == io_dev_ptr)
    {
        return IO_DEVICE_DOES_NOT_EXIST;
    }
    esdhc_device_ptr = io_dev_ptr->DRIVER_INIT_PTR;
    if (NULL == esdhc_device_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }
    esdhc_init_ptr = esdhc_device_ptr->INIT;
    if (NULL == esdhc_init_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    /* Get register base */
    esdhc_ptr = _bsp_get_esdhc_base_address (esdhc_init_ptr->CHANNEL);
    if (NULL == esdhc_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    /* Disable ESDHC device */
    _int_disable();
    if (--esdhc_device_ptr->COUNT == 0)
    {
        esdhc_ptr->SYSCTL = SDHC_SYSCTL_RSTA_MASK | SDHC_SYSCTL_SDCLKFS(0x80);
        while (esdhc_ptr->SYSCTL & SDHC_SYSCTL_RSTA_MASK)
            { };

        _mem_free (esdhc_fd_ptr->DEV_DATA_PTR);
        esdhc_fd_ptr->DEV_DATA_PTR = NULL;
    }
    _int_enable();

    return ESDHC_OK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_ioctl
* Returned Value   : MQX error code
* Comments         :
*    This function performs miscellaneous services for the ESDHC I/O device.
*
*END*********************************************************************/
_mqx_int _esdhc_ioctl
    (
        /* [IN] Opened file pointer for ESDHC */
        MQX_FILE_PTR        esdhc_fd_ptr,

        /* [IN] The command to perform */
        uint_32             cmd,

        /* [IN/OUT] Parameters for the command */
        pointer             param_ptr
    )
{
    IO_DEVICE_STRUCT_PTR    io_dev_ptr;
    ESDHC_INFO_STRUCT_PTR   esdhc_info_ptr;
    ESDHC_DEVICE_STRUCT_PTR esdhc_device_ptr;
    ESDHC_INIT_STRUCT_CPTR  esdhc_init_ptr;
    SDHC_MemMapPtr          esdhc_ptr;
    ESDHC_COMMAND_STRUCT    command;
    boolean                 mem, io, mmc, ceata, mp, hc;
    int_32                  val;
    uint_32                 result = ESDHC_OK;
    uint_32_ptr             param32_ptr = param_ptr;

    /* Check parameters */
    if (NULL == esdhc_fd_ptr)
    {
        return MQX_INVALID_PARAMETER;
    }
    io_dev_ptr = (IO_DEVICE_STRUCT_PTR)esdhc_fd_ptr->DEV_PTR;
    if (NULL == io_dev_ptr)
    {
        return IO_DEVICE_DOES_NOT_EXIST;
    }
    esdhc_info_ptr = (ESDHC_INFO_STRUCT_PTR)esdhc_fd_ptr->DEV_DATA_PTR;
    if (NULL == esdhc_info_ptr)
    {
        return IO_DEVICE_DOES_NOT_EXIST;
    }
    esdhc_device_ptr = io_dev_ptr->DRIVER_INIT_PTR;
    if (NULL == esdhc_device_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }
    esdhc_init_ptr = esdhc_device_ptr->INIT;
    if (NULL == esdhc_init_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    /* Get register base */
    esdhc_ptr = _bsp_get_esdhc_base_address (esdhc_init_ptr->CHANNEL);
    if (NULL == esdhc_ptr)
    {
        return IO_ERROR_DEVICE_INVALID;
    }

    switch (cmd)
    {
        case IO_IOCTL_ESDHC_INIT:

            result = _esdhc_init (esdhc_ptr, esdhc_info_ptr, esdhc_init_ptr);
            if (ESDHC_OK != result)
            {
                break;
            }

            mem = FALSE;
            io = FALSE;
            mmc = FALSE;
            ceata = FALSE;
            hc = FALSE;
            mp = FALSE;

            /* CMD0 - Go to idle - reset card */
            command.COMMAND = ESDHC_CMD0;
            command.ARGUMENT = 0;
            command.BLOCKS = 0;
            if (_esdhc_send_command (esdhc_ptr, &command))
            {
                result = ESDHC_ERROR_INIT_FAILED;
                break;
            }

            /* CMD8 - Send interface condition - check HC support */
            command.COMMAND = ESDHC_CMD8;
            command.ARGUMENT = 0x000001AA;
            command.BLOCKS = 0;
            val = _esdhc_send_command (esdhc_ptr, &command);
            if (val > 0)
            {
                result = ESDHC_ERROR_INIT_FAILED;
                break;
            }
            if (val == 0)
            {
                if (command.RESPONSE[0] != command.ARGUMENT)
                {
                    result = ESDHC_ERROR_INIT_FAILED;
                    break;
                }
                hc = TRUE;
            }

            /* CMD5 - Send operating conditions - test IO */
            command.COMMAND = ESDHC_CMD5;
            command.ARGUMENT = 0;
            command.BLOCKS = 0;
            val = _esdhc_send_command (esdhc_ptr, &command);
            if (val > 0)
            {
                result = ESDHC_ERROR_INIT_FAILED;
                break;
            }
            if (val == 0)
            {
                if (((command.RESPONSE[0] >> 28) & 0x07) && (command.RESPONSE[0] & 0x300000))
                {
                    /* CMD5 - Send operating conditions - init IO */
                    command.COMMAND = ESDHC_CMD5;
                    command.ARGUMENT = 0x300000;
                    command.BLOCKS = 0;
                    val = 0;
                    do
                    {
                        _time_delay (BSP_ALARM_RESOLUTION);
                        val++;
                        if (_esdhc_send_command (esdhc_ptr, &command))
                        {
                            result = ESDHC_ERROR_INIT_FAILED;
                            break;
                        }
                    } while ((0 == (command.RESPONSE[0] & 0x80000000)) && (val < BSP_ALARM_FREQUENCY));
                    if (ESDHC_OK != result)
                    {
                        break;
                    }
                    if (command.RESPONSE[0] & 0x80000000)
                    {
                        io = TRUE;
                    }
                    if (command.RESPONSE[0] & 0x08000000)
                    {
                        mp = TRUE;
                    }
                }
            }
            else
            {
                mp = TRUE;
            }

            if (mp)
            {
                /* CMD55 - Application specific command - check MMC */
                command.COMMAND = ESDHC_CMD55;
                command.ARGUMENT = 0;
                command.BLOCKS = 0;
                val = _esdhc_send_command (esdhc_ptr, &command);
                if (val > 0)
                {
                    result = ESDHC_ERROR_INIT_FAILED;
                    break;
                }
                if (val < 0)
                {
                    /* MMC or CE-ATA */
                    io = FALSE;
                    mem = FALSE;
                    hc = FALSE;

                    /* CMD1 - Send operating conditions - check HC */
                    command.COMMAND = ESDHC_CMD1;
                    command.ARGUMENT = 0x40300000;
                    command.BLOCKS = 0;
                    if (_esdhc_send_command (esdhc_ptr, &command))
                    {
                        result = ESDHC_ERROR_INIT_FAILED;
                        break;
                    }
                    if (0x20000000 == (command.RESPONSE[0] & 0x60000000))
                    {
                        hc = TRUE;
                    }
                    mmc = TRUE;

                    /* CMD39 - Fast IO - check CE-ATA signature CE */
                    command.COMMAND = ESDHC_CMD39;
                    command.ARGUMENT = 0x0C00;
                    command.BLOCKS = 0;
                    if (_esdhc_send_command (esdhc_ptr, &command))
                    {
                        result = ESDHC_ERROR_INIT_FAILED;
                        break;
                    }
                    if (0xCE == ((command.RESPONSE[0] >> 8) & 0xFF))
                    {
                        /* CMD39 - Fast IO - check CE-ATA signature AA */
                        command.COMMAND = ESDHC_CMD39;
                        command.ARGUMENT = 0x0D00;
                        command.BLOCKS = 0;
                        if (_esdhc_send_command (esdhc_ptr, &command))
                        {
                            result = ESDHC_ERROR_INIT_FAILED;
                            break;
                        }
                        if (0xAA == ((command.RESPONSE[0] >> 8) & 0xFF))
                        {
                            mmc = FALSE;
                            ceata = TRUE;
                        }
                    }
                }
                else
                {
                    /* SD */
                    /* ACMD41 - Send Operating Conditions */
                    command.COMMAND = ESDHC_ACMD41;
                    command.ARGUMENT = 0;
                    command.BLOCKS = 0;
                    if (_esdhc_send_command (esdhc_ptr, &command))
                    {
                        result = ESDHC_ERROR_INIT_FAILED;
                        break;
                    }
                    if (command.RESPONSE[0] & 0x300000)
                    {
                        val = 0;
                        do
                        {
                            _time_delay (BSP_ALARM_RESOLUTION);
                            val++;

                            /* CMD55 + ACMD41 - Send OCR */
                            command.COMMAND = ESDHC_CMD55;
                            command.ARGUMENT = 0;
                            command.BLOCKS = 0;
                            if (_esdhc_send_command (esdhc_ptr, &command))
                            {
                                result = ESDHC_ERROR_INIT_FAILED;
                                break;
                            }

                            command.COMMAND = ESDHC_ACMD41;
                            if (hc)
                            {
                                command.ARGUMENT = 0x40300000;
                            }
                            else
                            {
                                command.ARGUMENT = 0x00300000;
                            }
                            command.BLOCKS = 0;
                            if (_esdhc_send_command (esdhc_ptr, &command))
                            {
                                result = ESDHC_ERROR_INIT_FAILED;
                                break;
                            }
                        } while ((0 == (command.RESPONSE[0] & 0x80000000)) && (val < BSP_ALARM_FREQUENCY));
                        if (ESDHC_OK != result)
                        {
                            break;
                        }
                        if (val >= BSP_ALARM_FREQUENCY)
                        {
                            hc = FALSE;
                        }
                        else
                        {
                            mem = TRUE;
                            if (hc)
                            {
                                hc = FALSE;
                                if (command.RESPONSE[0] & 0x40000000)
                                {
                                    hc = TRUE;
                                }
                            }
                        }
                    }
                }
            }
            if (mmc)
            {
                esdhc_info_ptr->CARD = ESDHC_CARD_MMC;
            }
            if (ceata)
            {
                esdhc_info_ptr->CARD = ESDHC_CARD_CEATA;
            }
            if (io)
            {
                esdhc_info_ptr->CARD = ESDHC_CARD_SDIO;
            }
            if (mem)
            {
                esdhc_info_ptr->CARD = ESDHC_CARD_SD;
                if (hc)
                {
                    esdhc_info_ptr->CARD = ESDHC_CARD_SDHC;
                }
            }
            if (io && mem)
            {
                esdhc_info_ptr->CARD = ESDHC_CARD_SDCOMBO;
                if (hc)
                {
                    esdhc_info_ptr->CARD = ESDHC_CARD_SDHCCOMBO;
                }
            }

            /* De-Init GPIO */
            if (_bsp_esdhc_io_init (esdhc_init_ptr->CHANNEL, 0) == -1)
            {
                return IO_ERROR_DEVICE_INVALID;
            }

            /* Set the ESDHC default baud rate */
            _esdhc_set_baudrate (esdhc_ptr, esdhc_init_ptr->CLOCK_SPEED, esdhc_init_ptr->BAUD_RATE);

            /* Init GPIO */
            if (_bsp_esdhc_io_init (esdhc_init_ptr->CHANNEL, 0xFFFF) == -1)
            {
                return IO_ERROR_DEVICE_INVALID;
            }
            break;
        case IO_IOCTL_ESDHC_SEND_COMMAND:
            val = _esdhc_send_command (esdhc_ptr, (ESDHC_COMMAND_STRUCT_PTR)param32_ptr);
            if (val > 0)
            {
                result = ESDHC_ERROR_COMMAND_FAILED;
            }
            if (val < 0)
            {
                result = ESDHC_ERROR_COMMAND_TIMEOUT            ;
            }
            break;
        case IO_IOCTL_ESDHC_GET_BAUDRATE:
            if (NULL == param32_ptr)
            {
                result = MQX_INVALID_PARAMETER;
            }
            else
            {
                /* Get actual baudrate */
                val = ((esdhc_ptr->SYSCTL & SDHC_SYSCTL_SDCLKFS_MASK) >> SDHC_SYSCTL_SDCLKFS_SHIFT) << 1;
                val *= ((esdhc_ptr->SYSCTL & SDHC_SYSCTL_DVS_MASK) >> SDHC_SYSCTL_DVS_SHIFT) + 1;
                *param32_ptr = (uint_32)((esdhc_init_ptr->CLOCK_SPEED) / val);
            }
            break;
        case IO_IOCTL_ESDHC_SET_BAUDRATE:
            if (NULL == param32_ptr)
            {
                result = MQX_INVALID_PARAMETER;
            }
            else if (0 == (*param32_ptr))
            {
                result = MQX_INVALID_PARAMETER;
            }
            else
            {
                if (! _esdhc_is_running (esdhc_ptr))
                {
                    /* De-Init GPIO */
                    if (_bsp_esdhc_io_init (esdhc_init_ptr->CHANNEL, 0) == -1)
                    {
                        result = IO_ERROR_DEVICE_INVALID;
                        break;
                    }

                    /* Set closest baudrate */
                    _esdhc_set_baudrate (esdhc_ptr, esdhc_init_ptr->CLOCK_SPEED, *param32_ptr);

                    /* Init GPIO */
                    if (_bsp_esdhc_io_init (esdhc_init_ptr->CHANNEL, 0xFFFF) == -1)
                    {
                        result = IO_ERROR_DEVICE_INVALID;
                        break;
                    }
                }
                else
                {
                    result = IO_ERROR_DEVICE_BUSY;
                }
            }
            break;
        case IO_IOCTL_ESDHC_GET_BUS_WIDTH:
            if (NULL == param32_ptr)
            {
                result = MQX_INVALID_PARAMETER;
            }
            else
            {
                /* Get actual ESDHC bus width */
                val = (esdhc_ptr->PROCTL & SDHC_PROCTL_DTW_MASK) >> SDHC_PROCTL_DTW_SHIFT;
                if (ESDHC_PROCTL_DTW_1BIT == val)
                {
                    *param32_ptr = ESDHC_BUS_WIDTH_1BIT;
                }
                else if (ESDHC_PROCTL_DTW_4BIT == val)
                {
                    *param32_ptr = ESDHC_BUS_WIDTH_4BIT;
                }
                else if (ESDHC_PROCTL_DTW_8BIT == val)
                {
                    *param32_ptr = ESDHC_BUS_WIDTH_8BIT;
                }
                else
                {
                    result = ESDHC_ERROR_INVALID_BUS_WIDTH;
                }
            }
            break;
        case IO_IOCTL_ESDHC_SET_BUS_WIDTH:
            if (NULL == param32_ptr)
            {
                result = MQX_INVALID_PARAMETER;
            }
            else
            {
                /* Set actual ESDHC bus width */
                if (! _esdhc_is_running (esdhc_ptr))
                {
                    if (ESDHC_BUS_WIDTH_1BIT == *param32_ptr)
                    {
                        esdhc_ptr->PROCTL &= (~ SDHC_PROCTL_DTW_MASK);
                        esdhc_ptr->PROCTL |= SDHC_PROCTL_DTW(ESDHC_PROCTL_DTW_1BIT);
                    }
                    else if (ESDHC_BUS_WIDTH_4BIT == *param32_ptr)
                    {
                        esdhc_ptr->PROCTL &= (~ SDHC_PROCTL_DTW_MASK);
                        esdhc_ptr->PROCTL |= SDHC_PROCTL_DTW(ESDHC_PROCTL_DTW_4BIT);
                    }
                    else if (ESDHC_BUS_WIDTH_8BIT == *param32_ptr)
                    {
                        esdhc_ptr->PROCTL &= (~ SDHC_PROCTL_DTW_MASK);
                        esdhc_ptr->PROCTL |= SDHC_PROCTL_DTW(ESDHC_PROCTL_DTW_8BIT);
                    }
                    else
                    {
                        result = ESDHC_ERROR_INVALID_BUS_WIDTH;
                    }
                }
                else
                {
                    result = IO_ERROR_DEVICE_BUSY;
                }
            }
            break;
        case IO_IOCTL_ESDHC_GET_CARD:
            if (NULL == param32_ptr)
            {
                result = MQX_INVALID_PARAMETER;
            }
            else
            {
                /* 80 clocks to update levels */
                esdhc_ptr->SYSCTL |= SDHC_SYSCTL_INITA_MASK;
                while (esdhc_ptr->SYSCTL & SDHC_SYSCTL_INITA_MASK)
                    { };

                /* Update and return actual card status */
                if (esdhc_ptr->IRQSTAT & SDHC_IRQSTAT_CRM_MASK)
                {
                    esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_CRM_MASK;
                    esdhc_info_ptr->CARD = ESDHC_CARD_NONE;
                }
                if (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_CINS_MASK)
                {
                    if (ESDHC_CARD_NONE == esdhc_info_ptr->CARD)
                    {
                        esdhc_info_ptr->CARD = ESDHC_CARD_UNKNOWN;
                    }
                }
                else
                {
                    esdhc_info_ptr->CARD = ESDHC_CARD_NONE;
                }
                *param32_ptr = esdhc_info_ptr->CARD;
            }
            break;
        case IO_IOCTL_DEVICE_IDENTIFY:
            /* Get ESDHC device parameters */
            param32_ptr[IO_IOCTL_ID_PHY_ELEMENT]  = IO_DEV_TYPE_PHYS_ESDHC;
            param32_ptr[IO_IOCTL_ID_LOG_ELEMENT]  = IO_DEV_TYPE_LOGICAL_MFS;
            param32_ptr[IO_IOCTL_ID_ATTR_ELEMENT] = IO_ESDHC_ATTRIBS;
            if (esdhc_fd_ptr->FLAGS & IO_O_RDONLY)
            {
                param32_ptr[IO_IOCTL_ID_ATTR_ELEMENT] &= (~ IO_DEV_ATTR_WRITE);
            }
            break;
        case IO_IOCTL_FLUSH_OUTPUT:
            /* Wait for transfer complete */
            _esdhc_status_wait (esdhc_ptr, SDHC_IRQSTAT_TC_MASK);
            if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
            {
                esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK;
                result = ESDHC_ERROR_DATA_TRANSFER;
            }
            esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_TC_MASK | SDHC_IRQSTAT_BRR_MASK | SDHC_IRQSTAT_BWR_MASK;
            break;
        default:
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }
    return result;
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_read
* Returned Value   : Returns the number of bytes received or IO_ERROR
* Comments         :
*   Reads the data into provided array.
*
*END*********************************************************************/
_mqx_int _esdhc_read
    (
        /* [IN] Opened file pointer for ESDHC */
        FILE_DEVICE_STRUCT_PTR esdhc_fd_ptr,

        /* [OUT] Where the characters are to be stored */
        char_ptr               data_ptr,

        /* [IN] The number of bytes to read */
        _mqx_int               n
    )
{
    IO_DEVICE_STRUCT_PTR    io_dev_ptr;
    ESDHC_INFO_STRUCT_PTR   esdhc_info_ptr;
    ESDHC_DEVICE_STRUCT_PTR esdhc_device_ptr;
    ESDHC_INIT_STRUCT_CPTR  esdhc_init_ptr;
    SDHC_MemMapPtr          esdhc_ptr;
    uint_32                 buffer;
    _mqx_int                remains;
    
    /* Check parameters */
    if (NULL == esdhc_fd_ptr)
    {
        return IO_ERROR;
    }
    io_dev_ptr = (IO_DEVICE_STRUCT_PTR)esdhc_fd_ptr->DEV_PTR;
    if (NULL == io_dev_ptr)
    {
        return IO_ERROR;
    }
    esdhc_info_ptr = (ESDHC_INFO_STRUCT_PTR)esdhc_fd_ptr->DEV_DATA_PTR;
    if (NULL == esdhc_info_ptr)
    {
        return IO_ERROR;
    }
    esdhc_device_ptr = io_dev_ptr->DRIVER_INIT_PTR;
    if (NULL == esdhc_device_ptr)
    {
        return IO_ERROR;
    }
    esdhc_init_ptr = esdhc_device_ptr->INIT;
    if (NULL == esdhc_init_ptr)
    {
        return IO_ERROR;
    }

    /* Get register base */
    esdhc_ptr = _bsp_get_esdhc_base_address (esdhc_init_ptr->CHANNEL);
    if (NULL == esdhc_ptr)
    {
        return IO_ERROR;
    }

    remains = n;
    if (((uint_32)data_ptr & 0x03) == 0)
    {
        /* data is word aligned, maximize speed by copying directly from the register */      

        while (remains >= 4)
        {
            if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
            {
                esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BRR_MASK;
                return IO_ERROR;
            }

            /* wait until amount of available data reaches the watermark or the transfer is finished */
            while ((0 == (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_BREN_MASK)) && (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_DLA_MASK))
                { };

            *((uint_32 *)data_ptr) = esdhc_ptr->DATPORT;
            data_ptr += 4;
            remains -= 4;
        }
    }
    else
    {
        /* missaligned data, read to temporary location and copy byte by byte */

        while (remains >= 4)
        {
            if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
            {
                esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BRR_MASK;
                return IO_ERROR;
            }

            /* wait until amount of available data reaches the watermark or the transfer is finished */
            while ((0 == (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_BREN_MASK)) && (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_DLA_MASK))
                { };

            buffer = esdhc_ptr->DATPORT;
#if PSP_ENDIAN == MQX_BIG_ENDIAN
            *data_ptr++ = (buffer >> 24) & 0xFF;
            *data_ptr++ = (buffer >> 16) & 0xFF;
            *data_ptr++ = (buffer >> 8) & 0xFF;
            *data_ptr++ = buffer & 0xFF;
#else
            *data_ptr++ = buffer & 0xFF;
            *data_ptr++ = (buffer >> 8) & 0xFF;
            *data_ptr++ = (buffer >> 16) & 0xFF;
            *data_ptr++ = (buffer >> 24) & 0xFF;
#endif
            remains -= 4;
        }      
    }

    if (remains)
    {
        /* there is less than a single word left for sure */
      
        if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
        {
            esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BRR_MASK;
            return IO_ERROR;
        }

        /* wait until amount of available data reaches the watermark or the transfer is finished */
        while ((0 == (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_BREN_MASK)) && (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_DLA_MASK))
            { };
        
        buffer = esdhc_ptr->DATPORT;
        while (remains)
        {
#if PSP_ENDIAN == MQX_BIG_ENDIAN
            /* assumes left justified data */
            *data_ptr++ = (buffer >> 24) & 0xFF;
            buffer <<= 8;
#else
            *data_ptr++ = buffer & 0xFF;
            buffer >>= 8;
#endif
            remains--;
        }
    }

    if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
    {
        esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BRR_MASK;
        return IO_ERROR;
    }

    return (n - remains);
}

/*FUNCTION****************************************************************
*
* Function Name    : _esdhc_write
* Returned Value   : return number of byte transmitted or IO_ERROR
* Comments         :
*   Writes the provided data buffer to the device.
*
*END*********************************************************************/
_mqx_int _esdhc_write
    (
        /* [IN] Opened file pointer for ESDHC */
        FILE_DEVICE_STRUCT_PTR esdhc_fd_ptr,

        /* [OUT] Where the characters are to be taken from */
        char_ptr               data_ptr,

        /* [IN] The number of bytes to read */
        _mqx_int               n
    )
{
    IO_DEVICE_STRUCT_PTR    io_dev_ptr;
    ESDHC_INFO_STRUCT_PTR   esdhc_info_ptr;
    ESDHC_DEVICE_STRUCT_PTR esdhc_device_ptr;
    ESDHC_INIT_STRUCT_CPTR  esdhc_init_ptr;
    SDHC_MemMapPtr          esdhc_ptr;
    uint_8_ptr              udata_ptr;
    uint_32                 buffer;
    _mqx_int                remains;

    /* Check parameters */
    if (NULL == esdhc_fd_ptr)
    {
        return IO_ERROR;
    }
    io_dev_ptr = (IO_DEVICE_STRUCT_PTR)esdhc_fd_ptr->DEV_PTR;
    if (NULL == io_dev_ptr)
    {
        return IO_ERROR;
    }
    esdhc_info_ptr = (ESDHC_INFO_STRUCT_PTR)esdhc_fd_ptr->DEV_DATA_PTR;
    if (NULL == esdhc_info_ptr)
    {
        return IO_ERROR;
    }
    esdhc_device_ptr = io_dev_ptr->DRIVER_INIT_PTR;
    if (NULL == esdhc_device_ptr)
    {
        return IO_ERROR;
    }
    esdhc_init_ptr = esdhc_device_ptr->INIT;
    if (NULL == esdhc_init_ptr)
    {
        return IO_ERROR;
    }

    /* Get register base */
    esdhc_ptr = _bsp_get_esdhc_base_address (esdhc_init_ptr->CHANNEL);
    if (NULL == esdhc_ptr)
    {
        return IO_ERROR;
    }

    /* pointer to unsigned data */
    udata_ptr = (uint_8_ptr)data_ptr;

    remains = n;
    if (((uint_32)udata_ptr & 0x03) == 0)
    {
        /* data is word aligned, maximize speed by copying directly to the register */      

        while (remains >= 4)
        {
            if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
            {
                esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BWR_MASK;
                return IO_ERROR;
            }

            /* wait until at least watermark space is available */
            while (0 == (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_BWEN_MASK))
                { };

            esdhc_ptr->DATPORT = *((uint_32 *)udata_ptr);
            udata_ptr += 4;
            remains -= 4;
        }
    }
    else
    {
        /* missaligned data, read to temporary location and copy byte by byte */

        while (remains >= 4)
        {
            if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
            {
                esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BWR_MASK;
                return IO_ERROR;
            }

            /* wait until at least watermark space is available */
            while (0 == (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_BWEN_MASK))
                { };

#if PSP_ENDIAN == MQX_BIG_ENDIAN
            buffer  = (*udata_ptr++) << 24;
            buffer |= (*udata_ptr++) << 16;
            buffer |= (*udata_ptr++) << 8;
            buffer |= (*udata_ptr++);
#else
            buffer  = (*udata_ptr++);
            buffer |= (*udata_ptr++) << 8;
            buffer |= (*udata_ptr++) << 16;
            buffer |= (*udata_ptr++) << 24;
#endif

            /* wait until at least watermark space is available */
            while (0 == (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_BWEN_MASK))
                { };
            
            esdhc_ptr->DATPORT = buffer;
            remains -= 4;
        }      
    }
    
    if (remains)
    {
        /* there is less than a single word left for sure */
  
        if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
        {
            esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BWR_MASK;
            return IO_ERROR;
        }
      
        buffer = 0xFFFFFFFF;
        while (remains)
        {
#if PSP_ENDIAN == MQX_BIG_ENDIAN
            /* assumes left justified data */
            buffer >>= 8;
            buffer |= (udata_ptr[remains] << 24);
#else
            buffer <<= 8;
            buffer |= udata_ptr[remains];
#endif
            remains--;
        }

        /* wait until at least watermark space is available */
        while (0 == (esdhc_ptr->PRSSTAT & SDHC_PRSSTAT_BWEN_MASK))
            { };

        esdhc_ptr->DATPORT = buffer;        
    }

    if (esdhc_ptr->IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))
    {
        esdhc_ptr->IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BWR_MASK;
        return IO_ERROR;
    }

    return (n - remains);
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_API.h<|end_filename|>
/***********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
*********************************************************************************************************************//*!
*
* @file   TSS_API.h
*
* @brief  This header defines the structs, constants, Types and registers of the TSS library 
*
* @version 1.0.84.0
* 
* @date Sep-19-2012
* 
*
***********************************************************************************************************************/


#ifndef TSS_API_H
  #define TSS_API_H

  #include "TSS_SystemSetup.h"  
  #include "TSS_StatusCodes.h" /* Defines The Return Status Codes Used By The Library */
  #include "TSS_DataTypes.h"   /* Defines The Data Types */
  #include "TSS_Sensor.h"      /* Includes TSS Sensor */
  
  /*******************************************************
  ******************* Version Control ********************
  *******************************************************/
  #define __TSS__             3
  #define __TSS_MINOR__       0
  #define __TSS_PATCHLEVEL__  1

  /* Version = VVRRPP */
  #if defined(__TSS__)
  #if defined(__TSS_PATCHLEVEL__)
  #define __TSS_VERSION__ ( __TSS__ * 10000 \
                          + __TSS_MINOR__ *100 \
                          + __TSS_PATCHLEVEL__)
  #else
  #define __TSS_VERSION__ ( __TSS__ * 10000 \
                          + __TSS_MINOR__ *100 \
                          )
  #endif
  #endif 
  /*******************************************************
   ****************** Types Definitions ******************
   *******************************************************/

  /* Electrode Control Types */
  #define TSS_CT_KEYPAD               1u
  #define TSS_CT_SLIDER               2u
  #define TSS_CT_ROTARY               3u
  #define TSS_CT_ASLIDER              4u
  #define TSS_CT_AROTARY              5u  
  #define TSS_CT_MATRIX               6u

  /*******************************************************
   *********************** Macros ************************
   *******************************************************/

  /* Keypad Decoder Macros */

  #define TSS_KEYPAD_BUFFER_READ(destvar,kpcsStruct)      destvar = (kpcsStruct).BufferPtr[(kpcsStruct).BufferReadIndex]; \
                                                          (kpcsStruct).BufferReadIndex = (UINT8) (((kpcsStruct).BufferReadIndex + 1) & 0x0Fu)
  #define TSS_KEYPAD_BUFFER_EMPTY(kpcsStruct)             ((kpcsStruct).BufferReadIndex == (kpcsStruct).BufferWriteIndex)

  /*******************************************************
   ************* Data structures enumerations ************
   *******************************************************/

  enum TSS_CSSystem_REGISTERS{
      System_Faults_Register = 0,
      System_SystemConfig_Register = 1,
      System_NSamples_Register = 4,
      System_DCTrackerRate_Register = 5,
      System_ResponseTime_Register = 6,
      System_StuckKeyTimeout_Register = 7,
      System_LowPowerScanPeriod_Register = 8,
      System_LowPowerElectrode_Register = 9,
      System_LowPowerElectrodeSensitivity_Register = 10,
      System_SystemTrigger_Register = 11,
      System_AutoTriggerModuloValue_Register = 12,      
      System_Sensitivity_Register = 13,                                                    
      System_ElectrodeEnablers_Register = System_Sensitivity_Register + TSS_N_ELECTRODES, 
      System_ElectrodeStatus_Register = System_ElectrodeEnablers_Register + (((TSS_N_ELECTRODES - 1) / 8) + 1),
      System_ConfigCheckSum_Register = System_ElectrodeStatus_Register + (((TSS_N_ELECTRODES - 1) / 8) + 1)
  };

  enum TSS_CSKeypad_REGISTERS{
      Keypad_ControlId_Register = 0,
      Keypad_ControlConfig_Register = 1,
      Keypad_BufferReadIndex_Register = 2,
      Keypad_BufferWriteIndex_Register = 3,
      Keypad_Events_Register = 4,
      Keypad_MaxTouches_Register = 5,
      Keypad_AutoRepeatRate_Register = 6,
      Keypad_AutoRepeatStart_Register = 7,
      Keypad_BufferPtr_Register = 8
  };

  enum TSS_CSSlider_REGISTERS{
      Slider_ControlId_Register = 0,
      Slider_ControlConfig_Register = 1,
      Slider_DynamicStatus_Register = 2,
      Slider_StaticStatus_Register = 3,
      Slider_Events_Register = 4,
      Slider_AutoRepeatRate_Register = 5,
      Slider_MovementTimeout_Register = 6
  };

  enum TSS_CSRotary_REGISTERS{
      Rotary_ControlId_Register = 0,
      Rotary_ControlConfig_Register = 1,
      Rotary_DynamicStatus_Register = 2,
      Rotary_StaticStatus_Register = 3,
      Rotary_Events_Register = 4,
      Rotary_AutoRepeatRate_Register = 5,
      Rotary_MovementTimeout_Register = 6
  };
  
  enum TSS_CSASlider_REGISTERS{
      ASlider_ControlId_Register = 0,
      ASlider_ControlConfig_Register = 1,
      ASlider_DynamicStatus_Register = 2,
      ASlider_Position_Register = 3,
      ASlider_Events_Register = 4,
      ASlider_AutoRepeatRate_Register = 5,
      ASlider_MovementTimeout_Register = 6,
      ASlider_Range_Register = 7
  };

  enum TSS_CSARotary_REGISTERS{
      ARotary_ControlId_Register = 0,
      ARotary_ControlConfig_Register = 1,
      ARotary_DynamicStatus_Register = 2,
      ARotary_Position_Register = 3,
      ARotary_Events_Register = 4,
      ARotary_AutoRepeatRate_Register = 5,
      ARotary_MovementTimeout_Register = 6,
      ARotary_Range_Register = 7
  };

  enum TSS_CSMatrix_REGISTERS{
      Matrix_ControlId_Register = 0,
      Matrix_ControlConfig_Register = 1,
      Matrix_Events_Register = 2,
      Matrix_AutoRepeatRate_Register = 3,
      Matrix_MovementTimeout_Register = 4,
      Matrix_DynamicStatusX_Register = 5,
      Matrix_DynamicStatusY_Register = 6,
      Matrix_PositionX_Register = 7,
      Matrix_PositionY_Register = 8,
      Matrix_GestureDistanceX_Register = 9,
      Matrix_GestureDistanceY_Register = 10,      
      Matrix_RangeX_Register = 11,
      Matrix_RangeY_Register = 12        
  };
  
  /*******************************************************
   *********** Library Constants Definitions *************
   *******************************************************/
   
  /* System Register Constants */
  #define TSS_SYSTEM_EN_BIT                      15u    /* Bit 15 at SystemConfig */
  #define TSS_SWI_EN_BIT                         14u    /* Bit 14 at SystemConfig */
  #define TSS_DC_TRACKER_EN_BIT                  13u    /* Bit 13 at SystemConfig */
  #define TSS_STUCK_KEY_EN_BIT                   12u    /* Bit 12 at SystemConfig */
  #define TSS_WATER_TOLERANCE_EN_BIT             8u     /* Bit 8 at SystemConfig */  
  #define TSS_PROXIMITY_EN_BIT                   7u     /* Bit 7 at SystemConfig */  
  #define TSS_LOWPOWER_EN_BIT                    6u     /* Bit 6 at SystemConfig */  
  #define TSS_HW_RECA_START_BIT                  2u     /* Bit 2 at SystemConfig */  
  #define TSS_SYSTEM_RESET_BIT                   1u     /* Bit 1 at SystemConfig */
  #define TSS_MANUAL_RECA_START_BIT              0u     /* Bit 0 at SystemConfig */

  #define TSS_SWTRIGGER_BIT                      2u     /* Bit 2 at SystemTrigger */
  #define TSS_TRIGGER_MODE_BIT                   0u     /* Bit 0-1 at SystemTrigger */  
  
  #define TSS_SYSTEM_EN_MASK                     ((UINT16)(1u << TSS_SYSTEM_EN_BIT))
  #define TSS_SWI_EN_MASK                        ((UINT16)(1u << TSS_SWI_EN_BIT))
  #define TSS_DC_TRACKER_EN_MASK                 ((UINT16)(1u << TSS_DC_TRACKER_EN_BIT))
  #define TSS_STUCK_KEY_EN_MASK                  ((UINT16)(1u << TSS_STUCK_KEY_EN_BIT))
  #define TSS_WATER_TOLERANCE_EN_MASK            ((UINT16)(1u << TSS_WATER_TOLERANCE_EN_BIT))
  #define TSS_PROXIMITY_EN_MASK                  ((UINT16)(1u << TSS_PROXIMITY_EN_BIT))
  #define TSS_LOWPOWER_EN_MASK                   ((UINT16)(1u << TSS_LOWPOWER_EN_BIT))  
  #define TSS_HW_RECA_START_MASK                 ((UINT16)(1u << TSS_HW_RECA_START_BIT))  
  #define TSS_SYSTEM_RESET_MASK                  ((UINT16)(1u << TSS_SYSTEM_RESET_BIT))
  #define TSS_MANUAL_RECA_START_MASK             ((UINT16)(1u << TSS_MANUAL_RECA_START_BIT))
  
  #define TSS_SWTRIGGER_MASK                     ((UINT16)(1u << TSS_SWTRIGGER_BIT))
  #define TSS_TRIGGER_MODE_MASK                  ((UINT16)(3u << TSS_TRIGGER_MODE_BIT))
  
  #define TSS_TRIGGER_MODE_AUTO                  0u
  #define TSS_TRIGGER_MODE_ALWAYS                1u
  #define TSS_TRIGGER_MODE_SW                    2u

  /* KeyPad Constants */
  #define TSS_KEYPAD_CONTROL_EN_BIT              7u     /* Bit 7 at Keypad Control Config */
  #define TSS_KEYPAD_CALLBACK_EN_BIT             6u     /* Bit 6 at Keypad Control Config */
  #define TSS_KEYPAD_IDLE_EN_BIT                 5u     /* Bit 5 at Keypad Control Config */

  #define TSS_KEYPAD_MAXTOUCHES_FLAG_BIT         7u     /* Bit 7 at Keypad Events */
  #define TSS_KEYPAD_BUFFER_OVF_FLAG_BIT         6u     /* Bit 6 at Keypad Events */
  #define TSS_KEYPAD_MAXTOUCHES_EN_BIT           4u     /* Bit 4 at Keypad Events */
  #define TSS_KEYPAD_BUFFER_OVF_EN_BIT           3u     /* Bit 3 at Keypad Events */
  #define TSS_KEYPAD_AUTOREPEAT_EN_BIT           2u     /* Bit 2 at Keypad Events */
  #define TSS_KEYPAD_RELEASE_EVENT_EN_BIT        1u     /* Bit 1 at Keypad Events */
  #define TSS_KEYPAD_TOUCH_EVENT_EN_BIT          0u     /* Bit 0 at Keypad Events */

  #define TSS_KEYPAD_CONTROL_EN_MASK             ((UINT8)(1u << TSS_KEYPAD_CONTROL_EN_BIT))
  #define TSS_KEYPAD_CALLBACK_EN_MASK            ((UINT8)(1u << TSS_KEYPAD_CALLBACK_EN_BIT))
  #define TSS_KEYPAD_IDLE_EN_MASK                ((UINT8)(1u << TSS_KEYPAD_IDLE_EN_BIT)) 

  #define TSS_KEYPAD_MAXTOUCHES_FLAG_MASK        ((UINT8)(1u << TSS_KEYPAD_MAXTOUCHES_FLAG_BIT))
  #define TSS_KEYPAD_BUFFER_OVF_FLAG_MASK        ((UINT8)(1u << TSS_KEYPAD_BUFFER_OVF_FLAG_BIT))
  #define TSS_KEYPAD_MAXTOUCHES_EN_MASK          ((UINT8)(1u << TSS_KEYPAD_MAXTOUCHES_EN_BIT))
  #define TSS_KEYPAD_BUFFER_OVF_EN_MASK          ((UINT8)(1u << TSS_KEYPAD_BUFFER_OVF_EN_BIT))
  #define TSS_KEYPAD_AUTOREPEAT_EN_MASK          ((UINT8)(1u << TSS_KEYPAD_AUTOREPEAT_EN_BIT))
  #define TSS_KEYPAD_RELEASE_EVENT_EN_MASK       ((UINT8)(1u << TSS_KEYPAD_RELEASE_EVENT_EN_BIT))
  #define TSS_KEYPAD_TOUCH_EVENT_EN_MASK         ((UINT8)(1u << TSS_KEYPAD_TOUCH_EVENT_EN_BIT))

  #define TSS_KEYPAD_BUFFER_EVENT_FLAG_BIT       7u

  #define TSS_KEYPAD_BUFFER_EVENT_FLAG_MASK      ((UINT8)(1u << TSS_KEYPAD_BUFFER_EVENT_FLAG_BIT))
  #define TSS_KEYPAD_BUFFER_RELEASE_FLAG         ((UINT8)(1u << TSS_KEYPAD_BUFFER_EVENT_FLAG_BIT))
  #define TSS_KEYPAD_BUFFER_TOUCH_FLAG           0
  
  #define TSS_KEYPAD_BUFFER_KEY_MASK             0x0F  
  
   /* Slider Constants */
  #define TSS_SLIDER_CONTROL_EN_BIT               7u     /* Bit 7 at Control Config */
  #define TSS_SLIDER_CALLBACK_EN_BIT              6u     /* Bit 6 at Slider Control Config */
  #define TSS_SLIDER_IDLE_SCAN                    5u     /* Bit 5 at Slider Control Config */

  #define TSS_SLIDER_RELEASE_EN_BIT               4u     /* Bit 4 at Slider Events */
  #define TSS_SLIDER_HOLD_AUTOREPEAT_EN_BIT       3u     /* Bit 3 at Slider Events */
  #define TSS_SLIDER_HOLD_EN_BIT                  2u     /* Bit 2 at Slider Events */
  #define TSS_SLIDER_MOVEMENT_EVENT_EN_BIT        1u     /* Bit 1 at Slider Events */
  #define TSS_SLIDER_INITIAL_TOUCH_EVENT_EN_BIT   0u     /* Bit 0 at Slider Events */

  #define TSS_SLIDER_CONTROL_EN_MASK              ((UINT8)(1u << TSS_SLIDER_CONTROL_EN_BIT))
  #define TSS_SLIDER_CALLBACK_EN_MASK             ((UINT8)(1u << TSS_SLIDER_CALLBACK_EN_BIT))
  #define TSS_SLIDER_IDLE_EN_MASK                 ((UINT8)(1u << TSS_SLIDER_IDLE_SCAN)) 

  #define TSS_SLIDER_RELEASE_EVENT_EN_MASK        ((UINT8)(1u << TSS_SLIDER_RELEASE_EN_BIT))
  #define TSS_SLIDER_AUTOREPEAT_EN_MASK           ((UINT8)(1u << TSS_SLIDER_HOLD_AUTOREPEAT_EN_BIT))
  #define TSS_SLIDER_HOLD_EN_MASK                 ((UINT8)(1u << TSS_SLIDER_HOLD_EN_BIT))
  #define TSS_SLIDER_MOVEMENT_EVENT_EN_MASK       ((UINT8)(1u << TSS_SLIDER_MOVEMENT_EVENT_EN_BIT))
  #define TSS_SLIDER_INITIAL_TOUCH_EVENT_EN_MASK  ((UINT8)(1u << TSS_SLIDER_INITIAL_TOUCH_EVENT_EN_BIT))

   /* Rotary Constants */
  #define TSS_ROTARY_CONTROL_EN_BIT               7u     /* Bit 7 at Slider Control Config */
  #define TSS_ROTARY_CALLBACK_EN_BIT              6u     /* Bit 6 at Slider Control Config */
  #define TSS_ROTARY_IDLE_SCAN                    5u     /* Bit 5 at Slider Control Config */

  #define TSS_ROTARY_RELEASE_EN_BIT               4u     /* Bit 4 at Slider Events */
  #define TSS_ROTARY_HOLD_AUTOREPEAT_EN_BIT       3u     /* Bit 3 at Slider Events */
  #define TSS_ROTARY_HOLD_EN_BIT                  2u     /* Bit 2 at Slider Events */
  #define TSS_ROTARY_MOVEMENT_EVENT_EN_BIT        1u     /* Bit 1 at Slider Events */
  #define TSS_ROTARY_INITIAL_TOUCH_EVENT_EN_BIT   0u     /* Bit 0 at Slider Events */

  #define TSS_ROTARY_CONTROL_EN_MASK              ((UINT8)(1u << TSS_ROTARY_CONTROL_EN_BIT))
  #define TSS_ROTARY_CALLBACK_EN_MASK             ((UINT8)(1u << TSS_ROTARY_CALLBACK_EN_BIT))
  #define TSS_ROTARY_IDLE_EN_MASK                 ((UINT8)(1u << TSS_ROTARY_IDLE_SCAN)) 

  #define TSS_ROTARY_RELEASE_EVENT_EN_MASK        ((UINT8)(1u << TSS_ROTARY_RELEASE_EN_BIT))
  #define TSS_ROTARY_AUTOREPEAT_EN_MASK           ((UINT8)(1u << TSS_ROTARY_HOLD_AUTOREPEAT_EN_BIT))
  #define TSS_ROTARY_HOLD_EN_MASK                 ((UINT8)(1u << TSS_ROTARY_HOLD_EN_BIT))
  #define TSS_ROTARY_MOVEMENT_EVENT_EN_MASK       ((UINT8)(1u << TSS_ROTARY_MOVEMENT_EVENT_EN_BIT))
  #define TSS_ROTARY_INITIAL_TOUCH_EVENT_EN_MASK  ((UINT8)(1u << TSS_ROTARY_INITIAL_TOUCH_EVENT_EN_BIT))
  
  /* Analog Slider Constants */
  #define TSS_ASLIDER_CONTROL_EN_BIT               7u     /* Bit 7 at Analog Slider Control Config */
  #define TSS_ASLIDER_CALLBACK_EN_BIT              6u     /* Bit 6 at Analog Slider Control Config */
  #define TSS_ASLIDER_IDLE_SCAN                    5u     /* Bit 5 at Analog Slider Control Config */

  #define TSS_ASLIDER_RELEASE_EN_BIT               4u     /* Bit 4 at Analog Slider Events */
  #define TSS_ASLIDER_HOLD_AUTOREPEAT_EN_BIT       3u     /* Bit 3 at Analog Slider Events */
  #define TSS_ASLIDER_HOLD_EN_BIT                  2u     /* Bit 2 at Analog Slider Events */
  #define TSS_ASLIDER_MOVEMENT_EVENT_EN_BIT        1u     /* Bit 1 at Analog Slider Events */
  #define TSS_ASLIDER_INITIAL_TOUCH_EVENT_EN_BIT   0u     /* Bit 0 at Analog Slider Events */

  #define TSS_ASLIDER_CONTROL_EN_MASK              ((UINT8)(1u << TSS_ASLIDER_CONTROL_EN_BIT))
  #define TSS_ASLIDER_CALLBACK_EN_MASK             ((UINT8)(1u << TSS_ASLIDER_CALLBACK_EN_BIT))
  #define TSS_ASLIDER_IDLE_EN_MASK                 ((UINT8)(1u << TSS_ASLIDER_IDLE_SCAN)) 

  #define TSS_ASLIDER_RELEASE_EVENT_EN_MASK        ((UINT8)(1u << TSS_ASLIDER_RELEASE_EN_BIT))
  #define TSS_ASLIDER_AUTOREPEAT_EN_MASK           ((UINT8)(1u << TSS_ASLIDER_HOLD_AUTOREPEAT_EN_BIT))
  #define TSS_ASLIDER_HOLD_EN_MASK                 ((UINT8)(1u << TSS_ASLIDER_HOLD_EN_BIT))
  #define TSS_ASLIDER_MOVEMENT_EVENT_EN_MASK       ((UINT8)(1u << TSS_ASLIDER_MOVEMENT_EVENT_EN_BIT))
  #define TSS_ASLIDER_INITIAL_TOUCH_EVENT_EN_MASK  ((UINT8)(1u << TSS_ASLIDER_INITIAL_TOUCH_EVENT_EN_BIT))

  /* Analog Rotary Constants */
  #define TSS_AROTARY_CONTROL_EN_BIT               7u     /* Bit 7 at Analog Rotary Control Config */
  #define TSS_AROTARY_CALLBACK_EN_BIT              6u     /* Bit 6 at Analog Rotary Control Config */
  #define TSS_AROTARY_IDLE_SCAN                    5u     /* Bit 5 at Analog Rotary Control Config */

  #define TSS_AROTARY_RELEASE_EN_BIT               4u     /* Bit 4 at Analog Rotary Events */
  #define TSS_AROTARY_HOLD_AUTOREPEAT_EN_BIT       3u     /* Bit 3 at Analog Rotary Events */
  #define TSS_AROTARY_HOLD_EN_BIT                  2u     /* Bit 2 at Analog Rotary Events */
  #define TSS_AROTARY_MOVEMENT_EVENT_EN_BIT        1u     /* Bit 1 at Analog Rotary Events */
  #define TSS_AROTARY_INITIAL_TOUCH_EVENT_EN_BIT   0u     /* Bit 0 at Analog Rotary Events */

  #define TSS_AROTARY_CONTROL_EN_MASK              ((UINT8)(1u << TSS_AROTARY_CONTROL_EN_BIT))
  #define TSS_AROTARY_CALLBACK_EN_MASK             ((UINT8)(1u << TSS_AROTARY_CALLBACK_EN_BIT))
  #define TSS_AROTARY_IDLE_EN_MASK                 ((UINT8)(1u << TSS_AROTARY_IDLE_SCAN)) 

  #define TSS_AROTARY_RELEASE_EVENT_EN_MASK        ((UINT8)(1u << TSS_AROTARY_RELEASE_EN_BIT))
  #define TSS_AROTARY_AUTOREPEAT_EN_MASK           ((UINT8)(1u << TSS_AROTARY_HOLD_AUTOREPEAT_EN_BIT))
  #define TSS_AROTARY_HOLD_EN_MASK                 ((UINT8)(1u << TSS_AROTARY_HOLD_EN_BIT))
  #define TSS_AROTARY_MOVEMENT_EVENT_EN_MASK       ((UINT8)(1u << TSS_AROTARY_MOVEMENT_EVENT_EN_BIT))
  #define TSS_AROTARY_INITIAL_TOUCH_EVENT_EN_MASK  ((UINT8)(1u << TSS_AROTARY_INITIAL_TOUCH_EVENT_EN_BIT))

  /* Matrix Constants */
  #define TSS_MATRIX_CONTROL_EN_BIT               7u     /* Bit 7 at Matrix Control Config */
  #define TSS_MATRIX_CALLBACK_EN_BIT              6u     /* Bit 6 at Matrix Control Config */
  #define TSS_MATRIX_IDLE_SCAN                    5u     /* Bit 5 at Matrix Control Config */

  #define TSS_MATRIX_GESTURES_EN_BIT              5u     /* Bit 5 at Matrix Events */
  #define TSS_MATRIX_RELEASE_EN_BIT               4u     /* Bit 4 at Matrix Events */
  #define TSS_MATRIX_HOLD_AUTOREPEAT_EN_BIT       3u     /* Bit 3 at Matrix Events */
  #define TSS_MATRIX_HOLD_EN_BIT                  2u     /* Bit 2 at Matrix Events */
  #define TSS_MATRIX_MOVEMENT_EVENT_EN_BIT        1u     /* Bit 1 at Matrix Events */
  #define TSS_MATRIX_INITIAL_TOUCH_EVENT_EN_BIT   0u     /* Bit 0 at Matrix Events */

  #define TSS_MATRIX_CONTROL_EN_MASK              ((UINT8)(1u << TSS_MATRIX_CONTROL_EN_BIT))
  #define TSS_MATRIX_CALLBACK_EN_MASK             ((UINT8)(1u << TSS_MATRIX_CALLBACK_EN_BIT))
  #define TSS_MATRIX_IDLE_EN_MASK                 ((UINT8)(1u << TSS_MATRIX_IDLE_SCAN)) 

  #define TSS_MATRIX_GESTURES_EVENT_EN_MASK       ((UINT8)(1u << TSS_MATRIX_GESTURES_EN_BIT))
  #define TSS_MATRIX_RELEASE_EVENT_EN_MASK        ((UINT8)(1u << TSS_MATRIX_RELEASE_EN_BIT))
  #define TSS_MATRIX_AUTOREPEAT_EN_MASK           ((UINT8)(1u << TSS_MATRIX_HOLD_AUTOREPEAT_EN_BIT))
  #define TSS_MATRIX_HOLD_EN_MASK                 ((UINT8)(1u << TSS_MATRIX_HOLD_EN_BIT))
  #define TSS_MATRIX_MOVEMENT_EVENT_EN_MASK       ((UINT8)(1u << TSS_MATRIX_MOVEMENT_EVENT_EN_BIT))
  #define TSS_MATRIX_INITIAL_TOUCH_EVENT_EN_MASK  ((UINT8)(1u << TSS_MATRIX_INITIAL_TOUCH_EVENT_EN_BIT))
  
  /* System Setup Constants */
  
  #define TSS_KEYPAD_EVENTS_BUFFER_SIZE           16u
  #define TSS_KEYPAD_CONTCONF_INIT                {0u,0u,0u,0u}
  #define TSS_KEYPAD_EVENTS_INIT                  {0u,0u,0u,0u,0u,0u,0u}
  
  #define TSS_SLIDER_CONTROL_INIT                 {0u,0u,0u,0u}
  #define TSS_SLIDER_DYN_INIT                     {0u,0u,0u}
  #define TSS_SLIDER_STAT_INIT                    {0u,0u,0u}
  #define TSS_SLIDER_EVENTS_INIT                  {0u,0u,0u,0u,0u}
  
  #define TSS_ASLIDER_CONTROL_INIT                {0u,0u,0u,0u}
  #define TSS_ASLIDER_DYN_INIT                    {0u,0u,0u}
  #define TSS_ASLIDER_EVENTS_INIT                 {0u,0u,0u,0u,0u,0u,0u}

  #define TSS_MATRIX_CONTROL_INIT                 {0u,0u,0u,0u}
  #define TSS_MATRIX_DYN_INIT                     {0u,0u,0u}
  #define TSS_MATRIX_EVENTS_INIT                  {0u,0u,0u,0u,0u,0u,0u,0u}  

  /*******************************************************
   ************* Data structures definitions *************
   *******************************************************/

  /***** Definition of CS structure's register types *****/
  #ifdef __HCS08__
    #pragma MESSAGE DISABLE C1106 /* WARNING C1106: Non-standard bitfield type */
  #endif
  /******* Definition of system's CS structure type ******/

  typedef struct{
      volatile const TSS_SYSTEM_FAULTS Faults;
      volatile const TSS_SYSTEM_SYSCONF SystemConfig;
      volatile const UINT8 Reserved;
      volatile const UINT8 NSamples;
      volatile const UINT8 DCTrackerRate;
      volatile const UINT8 ResponseTime;
      volatile const UINT8 StuckKeyTimeout;
      volatile const UINT8 LowPowerScanPeriod;         
      volatile const UINT8 LowPowerElectrode;    
      volatile const UINT8 LowPowerElectrodeSensitivity; 
      volatile const TSS_SYSTEM_TRIGGER SystemTrigger;
      volatile const UINT8 AutoTriggerModuloValue;    
  } TSS_CSSystem;

  /****** Definitions of decoder's CS structure types ****/

  /* Keypad CS structure */
  typedef struct {                                /* MAIN Struct for KeyPad Decoder */
      const TSS_CONTROL_ID ControlId;
      const TSS_KEYPAD_CONTCONF ControlConfig;
            UINT8 BufferReadIndex;                /* KeyPad Buffer Read Index     */
      const UINT8 BufferWriteIndex;               /* KeyPad Buffer Write Index    */
      const TSS_KEYPAD_EVENTS Events;
      const UINT8 MaxTouches;
      const UINT8 AutoRepeatRate;
      const UINT8 AutoRepeatStart;
      const UINT8 * const BufferPtr;              /* KeyPad Buffer pointer        */
  } TSS_CSKeypad;

  /* Slider CS structure */
  typedef struct{
      const TSS_CONTROL_ID ControlId;
      const TSS_SLIDER_CONTROL ControlConfig;
      const TSS_SLIDER_DYN DynamicStatus;
      const TSS_SLIDER_STAT StaticStatus;
      const TSS_SLIDER_EVENTS Events;
      const UINT8 AutoRepeatRate;
      const UINT8 MovementTimeout;
  } TSS_CSSlider;

  /* Public Rotary CS structure */
  typedef struct{
      const TSS_CONTROL_ID ControlId;
      const TSS_SLIDER_CONTROL ControlConfig;
      const TSS_SLIDER_DYN DynamicStatus;
      const TSS_SLIDER_STAT StaticStatus;
      const TSS_SLIDER_EVENTS Events;
      const UINT8 AutoRepeatRate;
      const UINT8 MovementTimeout;
  } TSS_CSRotary;

  /* Analog Slider CS structure */
  typedef struct{
      const TSS_CONTROL_ID ControlId;
      const TSS_ASLIDER_CONTROL ControlConfig;
      const TSS_ASLIDER_DYN DynamicStatus;
      const UINT8 Position;
      const TSS_ASLIDER_EVENTS Events;
      const UINT8 AutoRepeatRate;
      const UINT8 MovementTimeout;
      const UINT8 Range;
  } TSS_CSASlider;

  /* Analog Rotary CS structure */
  typedef struct{
      const TSS_CONTROL_ID ControlId;
      const TSS_ASLIDER_CONTROL ControlConfig;
      const TSS_ASLIDER_DYN DynamicStatus;
      const UINT8 Position;
      const TSS_ASLIDER_EVENTS Events;
      const UINT8 AutoRepeatRate;
      const UINT8 MovementTimeout;
      const UINT8 Range;
  } TSS_CSARotary;

  /* Matrix CS structure */
  typedef struct{
      const TSS_CONTROL_ID ControlId;
      const TSS_MATRIX_CONTROL ControlConfig;
      const TSS_MATRIX_EVENTS Events;
      const UINT8 AutoRepeatRate;
      const UINT8 MovementTimeout;
      const TSS_MATRIX_DYN DynamicStatusX;  
      const TSS_MATRIX_DYN DynamicStatusY;      
      const UINT8 PositionX;
      const UINT8 PositionY;
      const UINT8 GestureDistanceX;
      const UINT8 GestureDistanceY;      
      const UINT8 RangeX;
      const UINT8 RangeY;      
  } TSS_CSMatrix;
 
  /*******************************************************
   ********* Control's CS Structures Prototypes **********
   *******************************************************/
   
  /*
  *  This section includes the extern control structures that will ve used. 
  *  Only the Structures needed are compiled according with the number of declared
  *  controls in SystemSetup.h.
  */

  #if TSS_N_CONTROLS > 0                          /* Includes one extern control estructure per decoder declared */
      #if (TSS_C0_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C0_STRUCTURE;   /* If a KeyPad control is used includes the KeyPad struct*/
      #elif (TSS_C0_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C0_STRUCTURE;   /* If a Slider control is used includes the Slider struct*/
      #elif (TSS_C0_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C0_STRUCTURE;   /* If a Rotary control is used incluldes the Rotary struct*/
      #elif (TSS_C0_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C0_STRUCTURE;   /* If a Analog Slider control is used includes the Slider struct*/
      #elif (TSS_C0_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C0_STRUCTURE;   /* If a Analog Rotary control is used incluldes the Rotary struct*/
      #else          
          extern TSS_CSMatrix TSS_C0_STRUCTURE;   /* If a Matrix control is used incluldes the Matrix struct*/
      #endif
  #endif

  #if TSS_N_CONTROLS > 1
      #if (TSS_C1_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C1_STRUCTURE;
      #elif (TSS_C1_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C1_STRUCTURE;
      #elif (TSS_C1_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C1_STRUCTURE;
      #elif (TSS_C1_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C1_STRUCTURE;
      #elif (TSS_C1_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C1_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C1_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 2
      #if (TSS_C2_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C2_STRUCTURE;
      #elif (TSS_C2_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C2_STRUCTURE;
      #elif (TSS_C2_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C2_STRUCTURE;
      #elif (TSS_C2_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C2_STRUCTURE;
      #elif (TSS_C2_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C2_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C2_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 3
      #if (TSS_C3_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C3_STRUCTURE;
      #elif (TSS_C3_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C3_STRUCTURE;
      #elif (TSS_C3_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C3_STRUCTURE;
      #elif (TSS_C3_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C3_STRUCTURE;
      #elif (TSS_C3_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C3_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C3_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 4
      #if (TSS_C4_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C4_STRUCTURE;
      #elif (TSS_C4_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C4_STRUCTURE;
      #elif (TSS_C4_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C4_STRUCTURE;
      #elif (TSS_C4_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C4_STRUCTURE;
      #elif (TSS_C4_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C4_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C4_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 5
      #if (TSS_C5_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C5_STRUCTURE;
      #elif (TSS_C5_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C5_STRUCTURE;
      #elif (TSS_C5_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C5_STRUCTURE;
      #elif (TSS_C5_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C5_STRUCTURE;
      #elif (TSS_C5_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C5_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C5_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 6
      #if (TSS_C6_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C6_STRUCTURE;
      #elif (TSS_C6_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C6_STRUCTURE;
      #elif (TSS_C6_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C6_STRUCTURE;
      #elif (TSS_C6_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C6_STRUCTURE;
      #elif (TSS_C6_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C6_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C6_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 7
      #if (TSS_C7_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C7_STRUCTURE;
      #elif (TSS_C7_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C7_STRUCTURE;
      #elif (TSS_C7_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C7_STRUCTURE;
      #elif (TSS_C7_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C7_STRUCTURE;
      #elif (TSS_C7_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C7_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C7_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 8
      #if (TSS_C8_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C8_STRUCTURE;
      #elif (TSS_C8_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C8_STRUCTURE;
      #elif (TSS_C8_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C8_STRUCTURE;
      #elif (TSS_C8_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C8_STRUCTURE;
      #elif (TSS_C8_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C8_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C8_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 9
      #if (TSS_C9_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C9_STRUCTURE;
      #elif (TSS_C9_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C9_STRUCTURE;
      #elif (TSS_C9_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C9_STRUCTURE;
      #elif (TSS_C9_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C9_STRUCTURE;
      #elif (TSS_C9_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C9_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C9_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 10
      #if (TSS_C10_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C10_STRUCTURE;
      #elif (TSS_C10_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C10_STRUCTURE;
      #elif (TSS_C10_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C10_STRUCTURE;
      #elif (TSS_C10_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C10_STRUCTURE;
      #elif (TSS_C10_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C10_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C10_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 11
      #if (TSS_C11_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C11_STRUCTURE;
      #elif (TSS_C11_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C11_STRUCTURE;
      #elif (TSS_C11_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C11_STRUCTURE;
      #elif (TSS_C11_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C11_STRUCTURE;
      #elif (TSS_C11_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C11_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C11_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 12
      #if (TSS_C12_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C12_STRUCTURE;
      #elif (TSS_C12_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C12_STRUCTURE;
      #elif (TSS_C12_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C12_STRUCTURE;
      #elif (TSS_C12_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C12_STRUCTURE;
      #elif (TSS_C12_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C12_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C12_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 13
      #if (TSS_C13_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C13_STRUCTURE;
      #elif (TSS_C13_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C13_STRUCTURE;
      #elif (TSS_C13_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C13_STRUCTURE;
      #elif (TSS_C13_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C13_STRUCTURE;
      #elif (TSS_C13_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C13_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C13_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 14
      #if (TSS_C14_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C14_STRUCTURE;
      #elif (TSS_C14_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C14_STRUCTURE;
      #elif (TSS_C14_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C14_STRUCTURE;
      #elif (TSS_C14_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C14_STRUCTURE;
      #elif (TSS_C14_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C14_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C14_STRUCTURE;
      #endif
  #endif

  #if TSS_N_CONTROLS > 15
      #if (TSS_C15_TYPE == TSS_CT_KEYPAD)
          extern TSS_CSKeypad TSS_C15_STRUCTURE;
      #elif (TSS_C15_TYPE == TSS_CT_SLIDER)
          extern TSS_CSSlider TSS_C15_STRUCTURE;
      #elif (TSS_C15_TYPE == TSS_CT_ROTARY)
          extern TSS_CSRotary TSS_C15_STRUCTURE;
      #elif (TSS_C15_TYPE == TSS_CT_ASLIDER)
          extern TSS_CSASlider TSS_C15_STRUCTURE;
      #elif (TSS_C15_TYPE == TSS_CT_AROTARY)
          extern TSS_CSARotary TSS_C15_STRUCTURE;
      #else
          extern TSS_CSMatrix TSS_C15_STRUCTURE;
      #endif
  #endif

  /*******************************************************
   ********** TSS Library Function Prototypes ************
   *******************************************************/
   
  UINT8 TSS_Task(void);
  /*
  function    TSS_Task
  brief:      Performs all the task related to the TSS library  
  param:      void                            
  return:     Status Code (TSS_STATUS_OK, TSS_STATUS_PROCESSING)                             
  */

  UINT8 TSS_TaskSeq(void);
  /*
  function    TSS_TaskSeq
  brief:      Performs all the task related to the TSS library  
  param:      void                            
  return:     Status Code (TSS_STATUS_OK, TSS_STATUS_PROCESSING)                             
  */

  UINT8 TSS_Init(void);
  /*
  function:   TSSInit   
  brief:      Initializes all the hardware required for the TSS library
  param:      void
  return:     Status Code (TSS_STATUS_OK, TSS_STATUS_RECALIBRATION_FAULT)
  */

  UINT8 TSS_SetSystemConfig(UINT8 u8Parameter, UINT16 u16Value);
  /*
  function:   TSS_SetSystemConfig
  brief:      Configures one parameter of the TSS library
  param:      u8Parameter - Parameter that will be modified
              u16Value    - New value of the parameter                            
  return:     Status code                             
  */
  
  UINT16 TSS_GetSystemConfig(UINT8 u8Parameter);
  /*
  function:   TSS_GetSystemConfig
  brief:      Read one parameter of the proximity library
  param:      u8Parameter - Requested Parameter for reading
  return:     Desired result Value
  */

  UINT8 TSS_SetKeypadConfig(TSS_CONTROL_ID u8ControlId, UINT8 u8Parameter, UINT8 u8Value);
  /*
  function:   TSS_SetKeypadConfig 
  brief:      Configures one parameter of the KeyPad control
  param:      u8ControlId - Control identifier
              u8Parameter - Parameter that will be modified
              u8Value     - New value of the parameter                            
  return:     Status code                             
  */
  
  UINT8 TSS_GetKeypadConfig(TSS_CONTROL_ID u8CtrlId, UINT8 u8Parameter);
  /*
  function    TSS_SetKeypadConfig
  brief:      Configurates a parameter of a Keypad Decoder   
  param:      u8Ctrld     - Control Identifier
  param:      u8Parameter - Parameter that will be modified
  param:      u8Value     - New value                      
  return:     Read Value                             
  */ 

  UINT8 TSS_SetSliderConfig(TSS_CONTROL_ID u8ControlId, UINT8 u8Parameter, UINT8 u8Value);
  /*
  function:   TSS_SetSliderConfig
  brief:      Configures one parameter of the Slider control
  param:      u8ControlId - Control identifier
              u8Parameter - Parameter that will be modified
              u8Value     - New value of the parameter                            
  return:     Status code                              
  */
  
  UINT8 TSS_GetSliderConfig(TSS_CONTROL_ID u8CtrlId, UINT8 u8Parameter);
  /*
  function    TSS_GetSliderConfig
  brief:      Read a parameter of a Slider Decoder   
  param:      u8Ctrld     - Control Identifier
  param:      u8Parameter - Parameter that will be modified
  return:     Read Value                             
  */

  #define TSS_SetRotaryConfig(u8ControlId, u8Parameter, u8Value) TSS_SetSliderConfig(u8ControlId, u8Parameter, u8Value)
  /* The same function is used for Slider and Rotary configuration */

  #define TSS_GetRotaryConfig(u8ControlId, u8Parameter) TSS_GetSliderConfig(u8ControlId, u8Parameter)
  /* The same function is used for Slider and Rotary configuration */

  UINT8 TSS_SetASliderConfig(TSS_CONTROL_ID u8CtrlId, UINT8 u8Parameter, UINT8 u8Value);
  /*
  function    TSS_SetASliderConfig
  brief:      Configurates a parameter of a Analog Slider Decoder   
  param:      u8Ctrld     - Control Identifier
  param:      u8Parameter - Parameter that will be modified
  param:      u8Value     - New value                      
  return:     Configuration Status                             
  */  
    
  UINT8 TSS_GetASliderConfig(TSS_CONTROL_ID u8CtrlId, UINT8 u8Parameter);
  /*
  function    TSS_GetASliderConfig
  brief:      Read a parameter of an Analog Slider Decoder   
  param:      u8Ctrld     - Control Identifier
  param:      u8Parameter - Parameter that will be modified                     
  return:     Read Value                             
  */  

  #define TSS_SetARotaryConfig(u8ControlId, u8Parameter, u8Value) TSS_SetASliderConfig(u8ControlId, u8Parameter, u8Value)
  /* The same function is used for Analog Slider and Analog Rotary configuration */

  UINT8 TSS_SetMatrixConfig(TSS_CONTROL_ID u8CtrlId, UINT8 u8Parameter, UINT8 u8Value);
  /*
  function    TSS_SetMatrixConfig
  brief:      Configurates a parameter of a Matrix Decoder   
  param:      u8Ctrld     - Control Identifier
  param:      u8Parameter - Parameter that will be modified
  param:      u8Value     - New value                      
  return:     Configuration Status                             
  */  
    
  UINT8 TSS_GetMatrixConfig(TSS_CONTROL_ID u8CtrlId, UINT8 u8Parameter);
  /*
  function    TSS_GetMatrixConfig
  brief:      Read a parameter of a Matrix Decoder   
  param:      u8Ctrld     - Control Identifier
  param:      u8Parameter - Parameter that will be modified                     
  return:     Read Value                             
  */   
  
  /**************** Back Compatibility Macros ****************/
  
  #define TSS_SystemConfig(u8Parameter, u8Value) TSS_SetSystemConfig(u8Parameter, u8Value)
  #define TSS_KeypadConfig(u8ControlId, u8Parameter, u8Value) TSS_SetKeypadConfig(u8ControlId, u8Parameter, u8Value)
  #define TSS_SliderConfig(u8ControlId, u8Parameter, u8Value) TSS_SetSliderConfig(u8ControlId, u8Parameter, u8Value)
  #define TSS_RotaryConfig(u8ControlId, u8Parameter, u8Value) TSS_SetRotaryConfig(u8ControlId, u8Parameter, u8Value)    
  
  /***********************************************************
  **************** Automatic Macro control  ******************
  ***********************************************************/  

  /* Push enabling of TSS_USE_DELTA_LOG if Analogue Control is used */
  #define TSS_DETECT_ASLIDER_CONTROL_USAGE(control)    (TSS_C##control##_TYPE == TSS_CT_ASLIDER)
  #define TSS_DETECT_AROTARY_CONTROL_USAGE(control)     (TSS_C##control##_TYPE == TSS_CT_AROTARY)
  #define TSS_DETECT_MATRIX_CONTROL_USAGE(control)     (TSS_C##control##_TYPE == TSS_CT_MATRIX)  

  #if (defined(TSS_N_CONTROLS) & (TSS_N_CONTROLS > 0))  
  
    #if TSS_N_CONTROLS > 0
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0))
    #endif
    #if TSS_N_CONTROLS > 1
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1))
    #endif
    #if TSS_N_CONTROLS > 2
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2))
    #endif
    #if TSS_N_CONTROLS > 3
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3))
    #endif
    #if TSS_N_CONTROLS > 4
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4))
    #endif
    #if TSS_N_CONTROLS > 5
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5))
    #endif
    #if TSS_N_CONTROLS > 6
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6))
    #endif
    #if TSS_N_CONTROLS > 7
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7))
    #endif
    #if TSS_N_CONTROLS > 8
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7) || TSS_DETECT_ASLIDER_CONTROL_USAGE(8))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7) || TSS_DETECT_AROTARY_CONTROL_USAGE(8))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7) || TSS_DETECT_MATRIX_CONTROL_USAGE(8))
    #endif
    #if TSS_N_CONTROLS > 9
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7) || TSS_DETECT_ASLIDER_CONTROL_USAGE(8) || TSS_DETECT_ASLIDER_CONTROL_USAGE(9))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7) || TSS_DETECT_AROTARY_CONTROL_USAGE(8) || TSS_DETECT_AROTARY_CONTROL_USAGE(9))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7) || TSS_DETECT_MATRIX_CONTROL_USAGE(8) || TSS_DETECT_MATRIX_CONTROL_USAGE(9))
    #endif
    #if TSS_N_CONTROLS > 10
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7) || TSS_DETECT_ASLIDER_CONTROL_USAGE(8) || TSS_DETECT_ASLIDER_CONTROL_USAGE(9) || TSS_DETECT_ASLIDER_CONTROL_USAGE(10))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7) || TSS_DETECT_AROTARY_CONTROL_USAGE(8) || TSS_DETECT_AROTARY_CONTROL_USAGE(9) || TSS_DETECT_AROTARY_CONTROL_USAGE(10))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7) || TSS_DETECT_MATRIX_CONTROL_USAGE(8) || TSS_DETECT_MATRIX_CONTROL_USAGE(9) || TSS_DETECT_MATRIX_CONTROL_USAGE(10))
    #endif
    #if TSS_N_CONTROLS > 11
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7) || TSS_DETECT_ASLIDER_CONTROL_USAGE(8) || TSS_DETECT_ASLIDER_CONTROL_USAGE(9) || TSS_DETECT_ASLIDER_CONTROL_USAGE(10) || TSS_DETECT_ASLIDER_CONTROL_USAGE(11))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7) || TSS_DETECT_AROTARY_CONTROL_USAGE(8) || TSS_DETECT_AROTARY_CONTROL_USAGE(9) || TSS_DETECT_AROTARY_CONTROL_USAGE(10) || TSS_DETECT_AROTARY_CONTROL_USAGE(11))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7) || TSS_DETECT_MATRIX_CONTROL_USAGE(8) || TSS_DETECT_MATRIX_CONTROL_USAGE(9) || TSS_DETECT_MATRIX_CONTROL_USAGE(10) || TSS_DETECT_MATRIX_CONTROL_USAGE(11))
    #endif
    #if TSS_N_CONTROLS > 12
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7) || TSS_DETECT_ASLIDER_CONTROL_USAGE(8) || TSS_DETECT_ASLIDER_CONTROL_USAGE(9) || TSS_DETECT_ASLIDER_CONTROL_USAGE(10) || TSS_DETECT_ASLIDER_CONTROL_USAGE(11) || TSS_DETECT_ASLIDER_CONTROL_USAGE(12))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7) || TSS_DETECT_AROTARY_CONTROL_USAGE(8) || TSS_DETECT_AROTARY_CONTROL_USAGE(9) || TSS_DETECT_AROTARY_CONTROL_USAGE(10) || TSS_DETECT_AROTARY_CONTROL_USAGE(11) || TSS_DETECT_AROTARY_CONTROL_USAGE(12))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7) || TSS_DETECT_MATRIX_CONTROL_USAGE(8) || TSS_DETECT_MATRIX_CONTROL_USAGE(9) || TSS_DETECT_MATRIX_CONTROL_USAGE(10) || TSS_DETECT_MATRIX_CONTROL_USAGE(11) || TSS_DETECT_MATRIX_CONTROL_USAGE(12))
    #endif
    #if TSS_N_CONTROLS > 13
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7) || TSS_DETECT_ASLIDER_CONTROL_USAGE(8) || TSS_DETECT_ASLIDER_CONTROL_USAGE(9) || TSS_DETECT_ASLIDER_CONTROL_USAGE(10) || TSS_DETECT_ASLIDER_CONTROL_USAGE(11) || TSS_DETECT_ASLIDER_CONTROL_USAGE(12) || TSS_DETECT_ASLIDER_CONTROL_USAGE(13))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7) || TSS_DETECT_AROTARY_CONTROL_USAGE(8) || TSS_DETECT_AROTARY_CONTROL_USAGE(9) || TSS_DETECT_AROTARY_CONTROL_USAGE(10) || TSS_DETECT_AROTARY_CONTROL_USAGE(11) || TSS_DETECT_AROTARY_CONTROL_USAGE(12) || TSS_DETECT_AROTARY_CONTROL_USAGE(13))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7) || TSS_DETECT_MATRIX_CONTROL_USAGE(8) || TSS_DETECT_MATRIX_CONTROL_USAGE(9) || TSS_DETECT_MATRIX_CONTROL_USAGE(10) || TSS_DETECT_MATRIX_CONTROL_USAGE(11) || TSS_DETECT_MATRIX_CONTROL_USAGE(12) || TSS_DETECT_MATRIX_CONTROL_USAGE(13))
    #endif
    #if TSS_N_CONTROLS > 14
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7) || TSS_DETECT_ASLIDER_CONTROL_USAGE(8) || TSS_DETECT_ASLIDER_CONTROL_USAGE(9) || TSS_DETECT_ASLIDER_CONTROL_USAGE(10) || TSS_DETECT_ASLIDER_CONTROL_USAGE(11) || TSS_DETECT_ASLIDER_CONTROL_USAGE(12) || TSS_DETECT_ASLIDER_CONTROL_USAGE(13) || TSS_DETECT_ASLIDER_CONTROL_USAGE(14))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7) || TSS_DETECT_AROTARY_CONTROL_USAGE(8) || TSS_DETECT_AROTARY_CONTROL_USAGE(9) || TSS_DETECT_AROTARY_CONTROL_USAGE(10) || TSS_DETECT_AROTARY_CONTROL_USAGE(11) || TSS_DETECT_AROTARY_CONTROL_USAGE(12) || TSS_DETECT_AROTARY_CONTROL_USAGE(13) || TSS_DETECT_AROTARY_CONTROL_USAGE(14))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7) || TSS_DETECT_MATRIX_CONTROL_USAGE(8) || TSS_DETECT_MATRIX_CONTROL_USAGE(9) || TSS_DETECT_MATRIX_CONTROL_USAGE(10) || TSS_DETECT_MATRIX_CONTROL_USAGE(11) || TSS_DETECT_MATRIX_CONTROL_USAGE(12) || TSS_DETECT_MATRIX_CONTROL_USAGE(13) || TSS_DETECT_MATRIX_CONTROL_USAGE(14))
    #endif
    #if TSS_N_CONTROLS > 15
        #undef TSS_ASLIDER_USED
        #undef TSS_AROTARY_USED
        #undef TSS_MATRIX_USED
        #define TSS_ASLIDER_USED                (TSS_DETECT_ASLIDER_CONTROL_USAGE(0) || TSS_DETECT_ASLIDER_CONTROL_USAGE(1) || TSS_DETECT_ASLIDER_CONTROL_USAGE(2) || TSS_DETECT_ASLIDER_CONTROL_USAGE(3) || TSS_DETECT_ASLIDER_CONTROL_USAGE(4) || TSS_DETECT_ASLIDER_CONTROL_USAGE(5) || TSS_DETECT_ASLIDER_CONTROL_USAGE(6) || TSS_DETECT_ASLIDER_CONTROL_USAGE(7) || TSS_DETECT_ASLIDER_CONTROL_USAGE(8) || TSS_DETECT_ASLIDER_CONTROL_USAGE(9) || TSS_DETECT_ASLIDER_CONTROL_USAGE(10) || TSS_DETECT_ASLIDER_CONTROL_USAGE(11) || TSS_DETECT_ASLIDER_CONTROL_USAGE(12) || TSS_DETECT_ASLIDER_CONTROL_USAGE(13) || TSS_DETECT_ASLIDER_CONTROL_USAGE(14) || TSS_DETECT_ASLIDER_CONTROL_USAGE(15))
        #define TSS_AROTARY_USED                (TSS_DETECT_AROTARY_CONTROL_USAGE(0) || TSS_DETECT_AROTARY_CONTROL_USAGE(1) || TSS_DETECT_AROTARY_CONTROL_USAGE(2) || TSS_DETECT_AROTARY_CONTROL_USAGE(3) || TSS_DETECT_AROTARY_CONTROL_USAGE(4) || TSS_DETECT_AROTARY_CONTROL_USAGE(5) || TSS_DETECT_AROTARY_CONTROL_USAGE(6) || TSS_DETECT_AROTARY_CONTROL_USAGE(7) || TSS_DETECT_AROTARY_CONTROL_USAGE(8) || TSS_DETECT_AROTARY_CONTROL_USAGE(9) || TSS_DETECT_AROTARY_CONTROL_USAGE(10) || TSS_DETECT_AROTARY_CONTROL_USAGE(11) || TSS_DETECT_AROTARY_CONTROL_USAGE(12) || TSS_DETECT_AROTARY_CONTROL_USAGE(13) || TSS_DETECT_AROTARY_CONTROL_USAGE(14) || TSS_DETECT_AROTARY_CONTROL_USAGE(15))
        #define TSS_MATRIX_USED                 (TSS_DETECT_MATRIX_CONTROL_USAGE(0) || TSS_DETECT_MATRIX_CONTROL_USAGE(1) || TSS_DETECT_MATRIX_CONTROL_USAGE(2) || TSS_DETECT_MATRIX_CONTROL_USAGE(3) || TSS_DETECT_MATRIX_CONTROL_USAGE(4) || TSS_DETECT_MATRIX_CONTROL_USAGE(5) || TSS_DETECT_MATRIX_CONTROL_USAGE(6) || TSS_DETECT_MATRIX_CONTROL_USAGE(7) || TSS_DETECT_MATRIX_CONTROL_USAGE(8) || TSS_DETECT_MATRIX_CONTROL_USAGE(9) || TSS_DETECT_MATRIX_CONTROL_USAGE(10) || TSS_DETECT_MATRIX_CONTROL_USAGE(11) || TSS_DETECT_MATRIX_CONTROL_USAGE(12) || TSS_DETECT_MATRIX_CONTROL_USAGE(13) || TSS_DETECT_MATRIX_CONTROL_USAGE(14) || TSS_DETECT_MATRIX_CONTROL_USAGE(15))
    #endif
    
    #define TSS_ACONTROL_USED   (TSS_ASLIDER_USED || TSS_AROTARY_USED || TSS_MATRIX_USED)
    
    #if (TSS_ACONTROL_USED && (TSS_USE_DELTA_LOG == 0))
      #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
        #warning TSS - TSS_USE_DELTA_LOG macro was enabled due to usage by Matrix or Analogue Slider/Rotary control
      #endif
      #undef TSS_USE_DELTA_LOG   
      #define TSS_USE_DELTA_LOG 1
    #endif
  
  #else
  
    #define TSS_ASLIDER_USED    0
    #define TSS_AROTARY_USED    0
    #define TSS_MATRIX_USED     0
    #define TSS_ACONTROL_USED   0
    
  #endif

  /* Define overall number of electrodes for each Matrix control */
  #ifdef TSS_N_CONTROLS 
  
    #if TSS_N_CONTROLS > 0
      #if defined(TSS_C0_ELECTRODES_X) && defined(TSS_C0_ELECTRODES_Y)
        #ifdef TSS_C0_ELECTRODES
          #undef TSS_C0_ELECTRODES
        #endif
        #define TSS_C0_ELECTRODES TSS_C0_ELECTRODES_X + TSS_C0_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 1
      #if defined(TSS_C1_ELECTRODES_X) && defined(TSS_C1_ELECTRODES_Y)
        #ifdef TSS_C1_ELECTRODES
          #undef TSS_C1_ELECTRODES
        #endif
        #define TSS_C1_ELECTRODES TSS_C1_ELECTRODES_X + TSS_C1_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 2
      #if defined(TSS_C2_ELECTRODES_X) && defined(TSS_C2_ELECTRODES_Y)
        #ifdef TSS_C2_ELECTRODES
          #undef TSS_C2_ELECTRODES
        #endif
        #define TSS_C2_ELECTRODES TSS_C2_ELECTRODES_X + TSS_C2_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 3
      #if defined(TSS_C3_ELECTRODES_X) && defined(TSS_C3_ELECTRODES_Y)
        #ifdef TSS_C3_ELECTRODES
          #undef TSS_C3_ELECTRODES
        #endif
        #define TSS_C3_ELECTRODES TSS_C3_ELECTRODES_X + TSS_C3_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 4
      #if defined(TSS_C4_ELECTRODES_X) && defined(TSS_C4_ELECTRODES_Y)
        #ifdef TSS_C4_ELECTRODES
          #undef TSS_C4_ELECTRODES
        #endif
        #define TSS_C4_ELECTRODES TSS_C4_ELECTRODES_X + TSS_C4_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 5
      #if defined(TSS_C5_ELECTRODES_X) && defined(TSS_C5_ELECTRODES_Y)
        #ifdef TSS_C5_ELECTRODES
          #undef TSS_C5_ELECTRODES
        #endif
        #define TSS_C5_ELECTRODES TSS_C5_ELECTRODES_X + TSS_C5_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 6
      #if defined(TSS_C6_ELECTRODES_X) && defined(TSS_C6_ELECTRODES_Y)
        #ifdef TSS_C6_ELECTRODES
          #undef TSS_C6_ELECTRODES
        #endif
        #define TSS_C6_ELECTRODES TSS_C6_ELECTRODES_X + TSS_C6_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 7
      #if defined(TSS_C7_ELECTRODES_X) && defined(TSS_C7_ELECTRODES_Y)
        #ifdef TSS_C7_ELECTRODES
          #undef TSS_C7_ELECTRODES
        #endif
        #define TSS_C7_ELECTRODES TSS_C7_ELECTRODES_X + TSS_C7_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 8
      #if defined(TSS_C8_ELECTRODES_X) && defined(TSS_C8_ELECTRODES_Y)
        #ifdef TSS_C8_ELECTRODES
          #undef TSS_C8_ELECTRODES
        #endif
        #define TSS_C8_ELECTRODES TSS_C8_ELECTRODES_X + TSS_C8_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 9
      #if defined(TSS_C9_ELECTRODES_X) && defined(TSS_C9_ELECTRODES_Y)
        #ifdef TSS_C9_ELECTRODES
          #undef TSS_C9_ELECTRODES
        #endif
        #define TSS_C9_ELECTRODES TSS_C9_ELECTRODES_X + TSS_C9_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 10
      #if defined(TSS_C10_ELECTRODES_X) && defined(TSS_C10_ELECTRODES_Y)
        #ifdef TSS_C10_ELECTRODES
          #undef TSS_C10_ELECTRODES
        #endif
        #define TSS_C10_ELECTRODES TSS_C10_ELECTRODES_X + TSS_C10_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 11
      #if defined(TSS_C11_ELECTRODES_X) && defined(TSS_C11_ELECTRODES_Y)
        #ifdef TSS_C11_ELECTRODES
          #undef TSS_C11_ELECTRODES
        #endif
        #define TSS_C11_ELECTRODES TSS_C11_ELECTRODES_X + TSS_C11_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 12
      #if defined(TSS_C12_ELECTRODES_X) && defined(TSS_C12_ELECTRODES_Y)
        #ifdef TSS_C12_ELECTRODES
          #undef TSS_C12_ELECTRODES
        #endif
        #define TSS_C12_ELECTRODES TSS_C12_ELECTRODES_X + TSS_C12_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 13
      #if defined(TSS_C13_ELECTRODES_X) && defined(TSS_C13_ELECTRODES_Y)
        #ifdef TSS_C13_ELECTRODES
          #undef TSS_C13_ELECTRODES
        #endif
        #define TSS_C13_ELECTRODES TSS_C13_ELECTRODES_X + TSS_C13_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 14
      #if defined(TSS_C14_ELECTRODES_X) && defined(TSS_C14_ELECTRODES_Y)
        #ifdef TSS_C14_ELECTRODES
          #undef TSS_C14_ELECTRODES
        #endif
        #define TSS_C14_ELECTRODES TSS_C14_ELECTRODES_X + TSS_C14_ELECTRODES_Y
      #endif
    #endif
    #if TSS_N_CONTROLS > 15
      #if defined(TSS_C15_ELECTRODES_X) && defined(TSS_C15_ELECTRODES_Y)
        #ifdef TSS_C15_ELECTRODES
          #undef TSS_C15_ELECTRODES
        #endif
        #define TSS_C15_ELECTRODES TSS_C15_ELECTRODES_X + TSS_C15_ELECTRODES_Y
      #endif
    #endif
  
  #endif
  
  /***********************************************************
   **************** Default Values definition ****************
   ***********************************************************/  

  #ifndef TSS_USE_PE_COMPONENT
    #define TSS_USE_PE_COMPONENT                           0
  #endif

  #ifndef TSS_USE_MQX
    #define TSS_USE_MQX                                    0
  #endif
  
  #ifndef TSS_USE_IIR_FILTER
    #define TSS_USE_IIR_FILTER                             0
  #endif    

  #ifndef TSS_USE_DELTA_LOG
    #define TSS_USE_DELTA_LOG                              0
  #endif
  
  #ifndef TSS_USE_SIGNAL_LOG
    #define TSS_USE_SIGNAL_LOG                             0
  #endif
  
  #ifndef TSS_USE_DATA_CORRUPTION_CHECK
    #define TSS_USE_DATA_CORRUPTION_CHECK                  1
  #endif

  #ifndef TSS_USE_FREEMASTER_GUI
     #define TSS_USE_FREEMASTER_GUI                        0
  #endif

  #ifndef TSS_ENABLE_DIAGNOSTIC_MESSAGES
     #define TSS_ENABLE_DIAGNOSTIC_MESSAGES                0
  #endif

  #ifndef TSS_USE_CONTROL_PRIVATE_DATA
     #define TSS_USE_CONTROL_PRIVATE_DATA                  0
  #endif

  #ifndef TSS_USE_SIGNAL_SHIELDING
     #define TSS_USE_SIGNAL_SHIELDING                      0
  #endif

  #ifndef TSS_USE_SIGNAL_DIVIDER
     #define TSS_USE_SIGNAL_DIVIDER                        0
  #endif

  #ifndef TSS_USE_SIGNAL_MULTIPLIER
     #define TSS_USE_SIGNAL_MULTIPLIER                     0
  #endif
  
  #ifndef TSS_USE_STUCK_KEY
     #define TSS_USE_STUCK_KEY                             1
  #endif

  #ifndef TSS_USE_NEGATIVE_BASELINE_DROP
     #define TSS_USE_NEGATIVE_BASELINE_DROP                1
  #endif
  
  #ifndef TSS_USE_AUTO_HW_RECALIBRATION
     #define TSS_USE_AUTO_HW_RECALIBRATION                 1
  #endif  

  #ifndef TSS_USE_BASELINE_INIT_DURATION
    #define TSS_USE_BASELINE_INIT_DURATION                 0
  #endif
  
  #ifndef TSS_USE_AUTO_SENS_CALIBRATION
     #define TSS_USE_AUTO_SENS_CALIBRATION                 0
  #endif
  
  #ifndef TSS_USE_AUTO_SENS_CALIB_INIT_DURATION
    #if TSS_USE_AUTO_SENS_CALIBRATION
      #define TSS_USE_AUTO_SENS_CALIB_INIT_DURATION        100
    #else
      #define TSS_USE_AUTO_SENS_CALIB_INIT_DURATION        0
    #endif
  #endif
  
  /* Default settings of TSS internal functions (Not mentioned in Reference Manual) */
  
  #ifndef TSS_USE_DELTA_NOISE_ANALYSIS_BUFFER_LENGTH
    #if TSS_USE_AUTO_SENS_CALIBRATION
      #define TSS_USE_DELTA_NOISE_ANALYSIS_BUFFER_LENGTH   0 /* Disabled by default */
    #else
      #define TSS_USE_DELTA_NOISE_ANALYSIS_BUFFER_LENGTH   0
    #endif
  #endif

  #ifndef TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT1
    #if TSS_USE_AUTO_SENS_CALIBRATION
      #define TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT1     3
      #ifndef TSS_USE_DELTA_NOISE_ANALYSIS_IIR
        #define TSS_USE_DELTA_NOISE_ANALYSIS_IIR           1
      #endif
    #else
      #define TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT1     0
      #ifndef TSS_USE_DELTA_NOISE_ANALYSIS_IIR
        #define TSS_USE_DELTA_NOISE_ANALYSIS_IIR           0
      #endif
    #endif
  #endif

  #ifndef TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT2
    #if TSS_USE_AUTO_SENS_CALIBRATION
      #define TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT2    -1
      #ifndef TSS_USE_DELTA_NOISE_ANALYSIS_IIR
        #define TSS_USE_DELTA_NOISE_ANALYSIS_IIR           1
      #endif
    #else
      #define TSS_USE_DELTA_NOISE_ANALYSIS_IIR_WEIGHT2     0
      #ifndef TSS_USE_DELTA_NOISE_ANALYSIS_IIR
        #define TSS_USE_DELTA_NOISE_ANALYSIS_IIR           0
      #endif
    #endif
  #endif
  
  #ifndef TSS_ASLIDER_POSITION_IIR_WEIGHT
    #define TSS_ASLIDER_POSITION_IIR_WEIGHT      15u
  #endif
  #if ((TSS_ASLIDER_POSITION_IIR_WEIGHT > 0) && (TSS_ASLIDER_USED || TSS_AROTARY_USED))
    #define TSS_ASLIDER_POSITION_IIR_USED        1
  #else
    #define TSS_ASLIDER_POSITION_IIR_USED        0
  #endif

  #ifndef TSS_ASLIDER_DELAY_BUFFER_LENGTH
    #define TSS_ASLIDER_DELAY_BUFFER_LENGTH      0     /* Disabled by default */
  #endif
  #if ((TSS_ASLIDER_DELAY_BUFFER_LENGTH > 0) && (TSS_ASLIDER_USED || TSS_AROTARY_USED))
    #define TSS_ASLIDER_DELAY_USED               1
  #else 
    #define TSS_ASLIDER_DELAY_USED               0
    #undef TSS_ASLIDER_DELAY_BUFFER_LENGTH
    #define TSS_ASLIDER_DELAY_BUFFER_LENGTH      1     /* The size of the buffer can not be 0 */
  #endif
  
  #ifndef TSS_ASLIDER_TREND_BUFFER_LENGTH
    #define TSS_ASLIDER_TREND_BUFFER_LENGTH      32u
  #endif
  #ifndef TSS_ASLIDER_TREND_THRESHOLD
    #define TSS_ASLIDER_TREND_THRESHOLD          0     /* Use Automatic Trend Treshold calculation */
  #endif
  #if ((TSS_ASLIDER_TREND_BUFFER_LENGTH > 0) && (TSS_ASLIDER_USED || TSS_AROTARY_USED))
    #define TSS_ASLIDER_TREND_USED               1
  #else
    #define TSS_ASLIDER_TREND_USED               0
    #undef TSS_ASLIDER_TREND_BUFFER_LENGTH
    #define TSS_ASLIDER_TREND_BUFFER_LENGTH      1     /* The size of the buffer can not be 0 */
  #endif
  
  #ifndef TSS_MATRIX_POSITION_IIR_WEIGHT 
    #define TSS_MATRIX_POSITION_IIR_WEIGHT       4u
  #endif
  #if ((TSS_MATRIX_POSITION_IIR_WEIGHT > 0) && (TSS_MATRIX_USED))
    #define TSS_MATRIX_POSITION_IIR_USED         1
  #else
    #define TSS_MATRIX_POSITION_IIR_USED         0
  #endif
  
  /***********************************************************
   ******* Extern Contants and Variables Declaration *********
   ***********************************************************/

  extern volatile UINT8 tss_u8SampleIntFlag;            /* Extern variable for Sample Interrupted Flag */
  extern const UINT8 * const tss_acpsCSStructs[];       /* Extern Constant Array to store the structures addresses */

  extern TSS_CSSystem tss_CSSys;                        /* System Control Extern Struct */
  extern UINT8 tss_au8Sensitivity[TSS_N_ELECTRODES];
  extern UINT8 tss_au8ElectrodeEnablers[((TSS_N_ELECTRODES - 1)/ 8) + 1];
  extern UINT8 tss_au8ElectrodeStatus[((TSS_N_ELECTRODES - 1)/ 8) + 1];

  #if TSS_USE_DELTA_LOG 
      extern INT8 tss_ai8InstantDelta[TSS_N_ELECTRODES];
  #endif
  
  #if TSS_USE_SIGNAL_LOG 
      extern UINT16 tss_au16InstantSignal[TSS_N_ELECTRODES];
  #endif

  #define TSS_SET_SAMPLE_INTERRUPTED()       tss_u8SampleIntFlag = 1u;
  
#endif /* TSS_API_H */


<|start_filename|>Firmware/Inverter_bootloader/APP/Diagnostic_print.c<|end_filename|>
#include "app_cfg.h"

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void Print_reset_source(void)
{
  RCM_MemMapPtr RCM = RCM_BASE_PTR;
  /* Determine the last cause(s) of reset */
  if ( RCM->SRS1 & BIT(2) )  printf_uart("Software Reset\r\n");
  if ( RCM->SRS1 & BIT(1) )  printf_uart("Core Lockup Event Reset\r\n");
  if ( RCM->SRS1 & BIT(0) )  printf_uart("JTAG Reset\r\n");
  if ( RCM->SRS0 & BIT(7) )	 printf_uart("Power-on Reset\r\n");
  if ( RCM->SRS0 & BIT(6) )	 printf_uart("External Pin Reset\r\n");
  if ( RCM->SRS0 & BIT(5) )	 printf_uart("Watchdog(COP) Reset\r\n");
  if ( RCM->SRS0 & BIT(2) )	 printf_uart("Loss of Clock Reset\r\n");
  if ( RCM->SRS0 & BIT(1) )	 printf_uart("Low-voltage Detect Reset\r\n");
  if ( RCM->SRS0 & BIT(0) )  printf_uart("LLWU Reset\r\n");
}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void Print_Flash_identify(void)
{
  FTFE_MemMapPtr FTFE = FTFE_BASE_PTR;
  int i;

  printf_uart("P-Flash IFR dump:\r\n");
  for (i = 0; i < 8; i++)
  {
    __disable_interrupt();
    /* Write the flash FCCOB registers with the values for a read resource command */
    FTFE->FCCOB0 = 0x03;
    FTFE->FCCOB1 = 0x00;
    FTFE->FCCOB2 = 0x00;
    FTFE->FCCOB3 = 0x00 + i * 8;
    FTFE->FCCOB4 = 0x00;

    FTFE->FSTAT = BIT(5);
    /* All required FCCOBx registers are written, so launch the command */
    FTFE->FSTAT = BIT(7);

    /* Wait for the command to complete */
    while (!(FTFE->FSTAT & BIT(7)));
    __enable_interrupt();

    printf_uart(" %02X %02X %02X %02X %02X %02X %02X %02X\r\n", FTFE->FCCOB4, FTFE->FCCOB5, FTFE->FCCOB6, FTFE->FCCOB7, FTFE->FCCOB8, FTFE->FCCOB9, FTFE->FCCOBA, FTFE->FCCOBB);
  }

  /* Get the flash version ID */

  return;

  // Команда ниже вызывает Core Lockup Event Reset
  __disable_interrupt();
  /* Write the flash FCCOB registers with the values for a read resource command */
  FTFE->FCCOB0 = 0x03;
  FTFE->FCCOB1 = 0x00;
  FTFE->FCCOB2 = 0x00;
  FTFE->FCCOB3 = 0x00;
  FTFE->FCCOB4 = 0x01;

  FTFE->FSTAT = BIT(5);
  /* All required FCCOBx registers are written, so launch the command */
  FTFE->FSTAT = BIT(7);
  ;

  /* Wait for the command to complete */
  while (!(FTFE->FSTAT & BIT(7)));
  __enable_interrupt();

  printf_uart("FSTAT=%02X. Flash version ID %d.%d.%d.%d.%d.%d.%d.%d\r\n", FTFE->FSTAT, FTFE->FCCOB4, FTFE->FCCOB5, FTFE->FCCOB6, FTFE->FCCOB7, FTFE->FCCOB8, FTFE->FCCOB9, FTFE->FCCOBA, FTFE->FCCOBB);
  /* Clear all of the flags in the flash status register */
  FTFE->FSTAT = BIT(5);
  FTFE->FSTAT = BIT(7);
}
//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void Print_CPU_identify(void)
{
  SIM_MemMapPtr  SIM  = SIM_BASE_PTR;
  unsigned int val;

  printf_uart("Chip: ");
  /* Determine the Kinetis family */
  switch ((SIM->SDID >> 4) & 0x7)
  {
  case 0x0:
    printf_uart("K10-");
    break;
  case 0x1:
    printf_uart("K20-");
    break;
  case 0x2:
    printf_uart("K30-");
    break;
  case 0x3:
    printf_uart("K40-");
    break;
  case 0x4:
    printf_uart("K60-");
    break;
  case 0x5:
    printf_uart("K70-");
    break;
  case 0x6:
    printf_uart("K50-");
    break;
  case 0x7:
    printf_uart("K53-");
    break;
  default:
    printf_uart("Unrecognized Kinetis family device. \r\n");
    break;
  }


  /* Determine the package size */
  switch (SIM->SDID & 0xF)
  {
  case 0x2:
    printf_uart(" 32pin , ");
    break;
  case 0x4:
    printf_uart(" 48pin , ");
    break;
  case 0x5:
    printf_uart(" 64pin , ");
    break;
  case 0x6:
    printf_uart(" 80pin , ");
    break;
  case 0x7:
    printf_uart(" 81pin , ");
    break;
  case 0x8:
    printf_uart(" 100pin, ");
    break;
  case 0x9:
    printf_uart(" 104pin, ");
    break;
  case 0xA:
    printf_uart(" 144pin, ");
    break;
  case 0xC:
    printf_uart(" 196pin, ");
    break;
  case 0xE:
    printf_uart(" 256pin, ");
    break;
  default:
    printf_uart("Unrecognized Kinetis package code. \r\n");
    break;
  }

  val = (SIM->SDID >> 12) & 0xF;
  printf_uart("Silicon rev.=%02X\r\n", val);


  /* Determine the P-flash size */
  switch ((SIM->FCFG1 >> 24) & 0x0F)
  {
  case 0x7:
    printf_uart("128 kBytes P-flash	\r\n");
    break;
  case 0x9:
    printf_uart("256 kBytes P-flash	\r\n");
    break;
  case 0xB:
    printf_uart("512 kBytes P-flash	\r\n");
    break;
  case 0xD:
    printf_uart("1024 kBytes P-flash	\r\n");
    break;
  case 0xF:
    printf_uart("1024 kBytes P-flash	\r\n");
    break;
  default:
    printf_uart("ERR!! Undefined P-flash size\r\n");
    break;
  }

  /* if part has FlexNVM determine the FlexNVM size*/
  switch ((SIM->FCFG1 >> 28) & 0xF)
  {
  case 0x0:
    printf_uart("0 kBytes of FlexNVM   \r\n");
    break;
  case 0x7:
    printf_uart("128 kBytes of FlexNVM \r\n");
    break;
  case 0x9:
    printf_uart("256 kBytes of FlexNVM \r\n");
    break;
  case 0xF:
    printf_uart("256 kBytes of FlexNVM \r\n");
    break;
  default:
    printf_uart("ERR!! Undefined FlexNVM size\r\n");
    break;
  }
  /* Determine the RAM size */
  switch ((SIM->SOPT1 >> 12) & 0xF)
  {
  case 0x5:
    printf_uart("32 kBytes of RAM  \n\n");
    break;
  case 0x7:
    printf_uart("64 kBytes of RAM  \n\n");
    break;
  case 0x8:
    printf_uart("96 kBytes of RAM  \n\n");
    break;
  case 0x9:
    printf_uart("128 kBytes of RAM \n\n");
    break;
  default:
    printf_uart("ERR!! Undefined RAM size \n\n");
    break;
  }

}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void Print_USB_FS_regs(void)
{
  USB_MemMapPtr USB = USB0_BASE_PTR;

  printf_uart("USB0 registers -------------------------------\n\n");
  printf_uart("PERID       (Peripheral ID Register             ) = %02X  \r\n", USB->PERID);
  printf_uart("IDCOMP      (Peripheral ID Complement Register  ) = %02X  \r\n", USB->IDCOMP);
  printf_uart("REV         (Revision number                    ) = %02X  \r\n", USB->REV);
  printf_uart("ADDINFO     (Peripheral Additional info Register) = %02X  \r\n", USB->ADDINFO);
  printf_uart("OTGISTAT    (OTG Interrupt Status Register      ) = %02X  \r\n", USB->OTGISTAT);
  printf_uart("OTGICR      (OTG Interrupt Control Register     ) = %02X  \r\n", USB->OTGICR);
  printf_uart("OTGSTAT     (OTG Status Register                ) = %02X  \r\n", USB->OTGSTAT);
  printf_uart("OTGCTL      (OTG Control Register               ) = %02X  \r\n", USB->OTGCTL);
  printf_uart("ISTAT       (Interrupt Status Register          ) = %02X  \r\n", USB->ISTAT);
  printf_uart("INTEN       (Interrupt Enable Register          ) = %02X  \r\n", USB->INTEN);
  printf_uart("ERRSTAT     (Error Interrupt Status Register    ) = %02X  \r\n", USB->ERRSTAT);
  printf_uart("STAT        (Status Register                    ) = %02X  \r\n", USB->STAT);
  printf_uart("CTL         (Control Register                   ) = %02X  \r\n", USB->CTL);
  printf_uart("ADDR        (Address Register                   ) = %02X  \r\n", USB->ADDR);
  printf_uart("BDTPAGE1    (BDT Page Register 1                ) = %02X  \r\n", USB->BDTPAGE1);
  printf_uart("FRMNUML     (Frame Number Register Low          ) = %02X  \r\n", USB->FRMNUML);
  printf_uart("FRMNUMH     (Frame Number Register High         ) = %02X  \r\n", USB->FRMNUMH);
  printf_uart("TOKEN       (Token Register                     ) = %02X  \r\n", USB->TOKEN);
  printf_uart("SOFTHLD     (SOF Threshold Register             ) = %02X  \r\n", USB->SOFTHLD);
  printf_uart("BDTPAGE2    (BDT Page Register 2                ) = %02X  \r\n", USB->BDTPAGE2);
  printf_uart("BDTPAGE3    (BDT Page Register 3                ) = %02X  \r\n", USB->BDTPAGE3);
  printf_uart("USBCTRL     (USB Control Register               ) = %02X  \r\n", USB->USBCTRL);
  printf_uart("OBSERVE     (USB OTG Observe Register           ) = %02X  \r\n", USB->OBSERVE);
  printf_uart("CONTROL     (USB OTG Control Register           ) = %02X  \r\n", USB->CONTROL);
  printf_uart("USBTRC0     (USB Transceiver Control Register 0 ) = %02X  \r\n", USB->USBTRC0);
  printf_uart("USBFRMADJUST(Frame Adjust Register              ) = %02X  \r\n", USB->USBFRMADJUST);
  printf_uart("ENDPT0      (Endpoint0  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[0].ENDPT);
  printf_uart("ENDPT1      (Endpoint1  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[1].ENDPT);
  printf_uart("ENDPT2      (Endpoint2  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[2].ENDPT);
  printf_uart("ENDPT3      (Endpoint3  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[3].ENDPT);
  printf_uart("ENDPT4      (Endpoint4  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[4].ENDPT);
  printf_uart("ENDPT5      (Endpoint5  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[5].ENDPT);
  printf_uart("ENDPT6      (Endpoint6  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[6].ENDPT);
  printf_uart("ENDPT7      (Endpoint7  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[7].ENDPT);
  printf_uart("ENDPT8      (Endpoint8  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[8].ENDPT);
  printf_uart("ENDPT9      (Endpoint9  Control Registers       ) = %02X  \r\n", USB->ENDPOINT[9].ENDPT);
  printf_uart("ENDPT10     (Endpoint10 Control Registers       ) = %02X  \r\n", USB->ENDPOINT[10].ENDPT);
  printf_uart("ENDPT11     (Endpoint11 Control Registers       ) = %02X  \r\n", USB->ENDPOINT[11].ENDPT);
  printf_uart("ENDPT12     (Endpoint12 Control Registers       ) = %02X  \r\n", USB->ENDPOINT[12].ENDPT);
  printf_uart("ENDPT13     (Endpoint13 Control Registers       ) = %02X  \r\n", USB->ENDPOINT[13].ENDPT); 
  printf_uart("ENDPT14     (Endpoint14 Control Registers       ) = %02X  \r\n", USB->ENDPOINT[14].ENDPT);
  printf_uart("ENDPT15     (Endpoint15 Control Registers       ) = %02X  \r\n", USB->ENDPOINT[15].ENDPT);
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mpc5643l.c<|end_filename|>
#include "flash_mpxs20.c"


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/lwlog.c<|end_filename|>
/*HEADER*********************************************************************
 *
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: lwlog.c$
 * $Version : 3.8.0.1$
 * $Date    : Feb-22-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Lightweight LOG component.
 *
 *END************************************************************************/

#include "mqx_inc.h"

#if MQX_USE_LWLOGS
#include "lwlog.h"
#include "lwlog_prv.h"

#if MQX_LITE_VERSION_NUMBER
LWLOG_COMPONENT_STRUCT lwlog_struct = {0};
#endif /* MQX_LITE_VERSION_NUMBER */

/*!
 * \brief This function creates a kernel component providing a lightweight log
 * service for all user tasks.
 *
 * The lightweight log component provides a maximum of 16 logs, all with the same
 * size of entries. Log number 0 is reserved for kernel log.
 * \n An application subsequently creates lightweight logs with _lwlog_create() or
 * _lwlog_create_at().
 *
 * \return MQX_OK
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 *
 * \warning Cannot be called from an ISR.
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see _klog_create
 * \see _klog_create_at
 */
_mqx_uint _lwlog_create_component(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        return MQX_CANNOT_CALL_FUNCTION_FROM_ISR;
    } /* Endif */
#endif

    _lwsem_wait((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM);

#if MQX_CHECK_ERRORS
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG] != NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM);
        return (MQX_OK);
    } /* Endif */
#endif

#if MQX_LITE_VERSION_NUMBER
    log_component_ptr = &lwlog_struct;
#else
    log_component_ptr = _mem_alloc_system_zero((_mem_size) sizeof(LWLOG_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (log_component_ptr == NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM);
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(log_component_ptr, MEM_TYPE_LWLOG_COMPONENT);
#endif /* MQX_LITE_VERSION_NUMBER */

    kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG] = log_component_ptr;
    log_component_ptr->VALID = LWLOG_VALID;

    _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM);

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Creates the lightweight log at the specified location.
 *
 * Each entry in the log is the same size and contains a sequence number, a timestamp,
 * and a seven-element array of application-defined data.
 * \n Use _lwlog_calculate_size() to determine amount of memory needed to create
 * log with requested number of entries.
 *
 * \param[in] log_number Log number to create ( 1 through 15; 0 is reserved for
 * kernel log).
 * \param[in] max_size   Maximum number of entries in the log.
 * \param[in] flags      LOG_OVERWRITE (when the log is full, write new entries
 * over oldest ones), NULL (when the log is full, do not write entries; the default
 * behavior).
 * \param[in] where      Where to create the lightweight log.
 *
 * \return MQX_OK
 * \return LOG_EXISTS (Lightweight log with log number log_number exists.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_INVALID_SIZE (Max_size is 0.)
 * \return MQX_INVALID_POINTER (Where is NULL.)
 * \return MQX_INVALID_COMPONENT_BASE (Data for the lightweight log component is
 * not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 *
 * \warning Creates the lightweight log component if it was not created.
 *
 * \see _lwlog_create
 * \see _lwlog_create_component
 * \see _klog_create
 * \see _klog_create_at
 */
_mqx_uint _lwlog_create_at
(
    _mqx_uint log_number,
    _mqx_uint max_size,
    _mqx_uint flags,
    pointer   where
)
{ /* Body */
    LWLOG_HEADER_STRUCT_PTR log_header_ptr = (LWLOG_HEADER_STRUCT_PTR) where;
    _mqx_uint               result;

#if MQX_CHECK_ERRORS
    if (max_size == 0)
    {
        return (LOG_INVALID_SIZE);
    } /* Endif */

    if (where == NULL)
    {
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    result = _lwlog_create_internal(log_number, max_size, flags, log_header_ptr);
    if (result == MQX_OK)
    {
        log_header_ptr->TYPE = LWLOG_STATIC;
    } /* Endif */

    return (result);

} /* Endbody */

/*!
 * \private
 *
 * \brief Creates the lightweight log.
 *
 * \param[in] log_number     Log number to create ( 1 through 15; 0 is reserved
 * for kernel log).
 * \param[in] max_size       Maximum number of entries in the log.
 * \param[in] flags          LOG_OVERWRITE (when the log is full, write new entries
 * over oldest ones), NULL (when the log is full, do not write entries; the default
 * behavior).
 * \param[in] log_header_ptr Pointer to lightweight log header.
 *
 * \return MQX_OK
 * \return LOG_INVALID (log_number is out of range.)
 * \return LOG_EXISTS (Lightweight log with log number log_number exists.)
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Data for the lightweight log component is
 * not valid.)
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see LWLOG_HEADER_STRUCT
 */
_mqx_uint _lwlog_create_internal
(
    _mqx_uint log_number,
    _mqx_uint max_size,
    _mqx_uint flags,
    LWLOG_HEADER_STRUCT_PTR log_header_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_ENTRY_STRUCT_PTR     entry_ptr;
    _mqx_uint                  i;
    _mqx_uint                  result = MQX_OK;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */
#endif

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];
    if (log_component_ptr == NULL)
    {
        result = _lwlog_create_component();
        log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (log_component_ptr == NULL)
        {
            return (result);
        } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    }
    else if (log_component_ptr->LOGS[log_number] != NULL)
    {
        return (LOG_EXISTS);
#endif
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif
    _mem_zero((pointer) log_header_ptr, (_mem_size) sizeof(LWLOG_HEADER_STRUCT));

    log_header_ptr->FLAGS = flags;
    log_header_ptr->FLAGS |= LWLOG_ENABLED;
    log_header_ptr->NUMBER = 1;
    log_header_ptr->MAX_ENTRIES = max_size;

    entry_ptr = &log_header_ptr->FIRST_ENTRY;

    log_header_ptr->READ_PTR = entry_ptr;
    log_header_ptr->OLDEST_PTR = entry_ptr;

    max_size--;
    for (i = 0; i < max_size; i++)
    {
        entry_ptr->NEXT_PTR = entry_ptr + 1;
        entry_ptr++;
    } /* Endfor */

    log_header_ptr->WRITE_PTR = entry_ptr;
    entry_ptr->NEXT_PTR = log_header_ptr->READ_PTR;

    _int_disable();
#if MQX_CHECK_ERRORS
    if (log_component_ptr->LOGS[log_number] != NULL)
    {
        _int_enable();
        return (LOG_EXISTS);
    } /* Endif */
#endif
    log_component_ptr->LOGS[log_number] = log_header_ptr;
    _int_enable();

    return (result);

} /* Endbody */


#if !MQX_LITE_VERSION_NUMBER
/*!
 * \brief Creates the lightweight log.
 *
 * Each entry in the log is the same size and contains a sequence number, a timestamp,
 * and a seven-element array of application-defined data.
 *
 * \param[in] log_number Log number to create ( 1 through 15; 0 is reserved for
 * kernel log).
 * \param[in] max_size   Maximum number of entries in the log.
 * \param[in] flags      LOG_OVERWRITE (when the log is full, write new entries
 * over oldest ones), NULL (when the log is full, do not write entries; the default
 * behavior).
 *
 * \return MQX_OK
 * \return LOG_EXISTS (Lightweight log with log number log_number exists.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_INVALID_SIZE (Max_size is 0.)
 * \return MQX_INVALID_COMPONENT_BASE (Data for the lightweight log component is
 * not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 *
 * \warning Creates the lightweight log component if it was not created.
 *
 * \see _lwlog_create_at
 * \see _lwlog_create_component
 * \see _klog_create
 * \see _klog_create_at
 */
_mqx_uint _lwlog_create
(
    _mqx_uint log_number,
    _mqx_uint max_size,
    _mqx_uint flags
)
{ /* Body */
    LWLOG_HEADER_STRUCT_PTR log_header_ptr;
    _mqx_uint               result;

#if MQX_CHECK_ERRORS
    if (max_size == 0)
    {
        return LOG_INVALID_SIZE;
    } /* Endif */
#endif

    log_header_ptr = _mem_alloc_system_zero((_mem_size) sizeof(LWLOG_HEADER_STRUCT) + (_mem_size) (max_size - 1)
                    * (_mem_size) sizeof(LWLOG_ENTRY_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (log_header_ptr == NULL)
    {
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(log_header_ptr, MEM_TYPE_LWLOG);

    result = _lwlog_create_internal(log_number, max_size, flags, log_header_ptr);
    if (result == MQX_OK)
    {
        log_header_ptr->TYPE = LWLOG_DYNAMIC;
    }
    else
    {
        _mem_free(log_header_ptr);
    } /* Endif */

    return (result);

} /* Endbody */
#endif /* MQX_LITE_VERSION_NUMBER */

/*!
 * \brief Destroys an existing lightweight log.
 *
 * \param[in] log_number Log number of a previously created lightweight log (if
 * log_number is 0, kernel log is destroyed).
 *
 * \return MQX_OK
 * \return LOG_DOES_NOT_EXIST (Log_number was not previously created.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Lightweight log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Lightweight log component data is not valid.)
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see _lwlog_create_component
 */
_mqx_uint _lwlog_destroy
(
    _mqx_uint log_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */
#endif

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];

#if MQX_CHECK_ERRORS
    if (log_component_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        return (MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _int_disable();

    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return (LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_component_ptr->LOGS[log_number] = NULL;
    _int_enable();

#if !MQX_LITE_VERSION_NUMBER
    if (log_header_ptr->TYPE == LWLOG_DYNAMIC)
    {
        _mem_free(log_header_ptr);
    } /* Endif */
#endif

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Stops logging to the selected lightweight log.
 *
 * \param[in] log_number Log number of a previously created lightweight log (if
 * log_number is 0, kernel log is disabled).
 *
 * \return MQX_OK
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Lightweight log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Lightweight log component data is not valid.)
 *
 * \see _lwlog_enable
 * \see _lwlog_read
 * \see _lwlog_reset
 * \see _lwlog_write
 */
_mqx_uint _lwlog_disable
(
    _mqx_uint log_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */
#endif

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];

#if MQX_CHECK_ERRORS
    if (log_component_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        return (MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _int_disable();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return (LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_header_ptr->FLAGS &= ~LWLOG_ENABLED;
    _int_enable();

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Starts logging to the selected lightweight log.
 *
 * \param[in] log_number Log number of a previously created lightweight log (if
 * log_number is 0, kernel log is enabled).
 *
 * \return MQX_OK
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Lightweight log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Lightweight log component data is not valid.)
 *
 * \see _lwlog_disable
 * \see _lwlog_read
 * \see _lwlog_reset
 * \see _lwlog_write
 */
_mqx_uint _lwlog_enable
(
    /* [IN] the log number to be used */
    _mqx_uint log_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */
#endif

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];

#if MQX_CHECK_ERRORS
    if (log_component_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        return (MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _int_disable();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return (LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_header_ptr->FLAGS |= LWLOG_ENABLED;
    _int_enable();

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Reads the information in the lightweight log.
 *
 * <table>
 *   <tr>
 *     <td><b>read_type</b></td>
 *     <td><b>Returns this entry in the log:</b></td>
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEWEST</td>
 *     <td>Newest.</td>
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEXT</td>
 *     <td>Next one after the previous one read (must be used with LOG_READ_OLDEST).</td>
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST</td>
 *     <td>Oldest.</td>
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST_AND_DELETE</td>
 *     <td>Oldest and deletes it.</td>
 *   </tr>
 * </table>
 *
 * \param[in] log_number Log number of a previously created lightweight log (if
 * log_number is 0, kernel log is read).
 * \param[in] read_type  Type of read operation.
 * \param[in] entry_ptr  Pointer to where to write the lightweight log entry.
 *
 * \return MQX_OK
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_ENTRY_NOT_AVAILABLE (Log entry is not available.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_INVALID_READ_TYPE (Read_type is not valid.)
 * \return MQX_INVALID_POINTER (Entry_ptr is NULL.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Lightweight log component data is not valid.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Lightweight log component is not created.)
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see _lwlog_write
 * \see _klog_display
 * \see LWLOG_ENTRY_STRUCT
 */
_mqx_uint _lwlog_read
(
    _mqx_uint               log_number,
    _mqx_uint               read_type,
    LWLOG_ENTRY_STRUCT_PTR  entry_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;
    LWLOG_ENTRY_STRUCT_PTR     log_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */
    if (entry_ptr == NULL)
    {
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];

#if MQX_CHECK_ERRORS
    if (log_component_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    _int_disable();
#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    log_header_ptr = log_component_ptr->LOGS[log_number];

#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return (LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    if (!log_header_ptr->CURRENT_ENTRIES)
    {
        /* No data available */
        _int_enable();
        return (LOG_ENTRY_NOT_AVAILABLE);
    } /* Endif */

    if (read_type == LOG_READ_OLDEST_AND_DELETE)
    {
        log_header_ptr->CURRENT_ENTRIES--;
        log_ptr = log_header_ptr->OLDEST_PTR;
        log_header_ptr->OLDEST_PTR = log_ptr->NEXT_PTR;
        log_header_ptr->READ_PTR = log_ptr->NEXT_PTR;
        log_header_ptr->READS = 0;
    }
    else if (read_type == LOG_READ_OLDEST)
    {
        log_ptr = log_header_ptr->OLDEST_PTR;
        log_header_ptr->READ_PTR = log_ptr->NEXT_PTR;
        log_header_ptr->READS = 1;
    }
    else if (read_type == LOG_READ_NEXT)
    {
        log_ptr = log_header_ptr->READ_PTR;
        if ((log_ptr == log_header_ptr->WRITE_PTR->NEXT_PTR) && (log_header_ptr->READS
                        >= log_header_ptr->CURRENT_ENTRIES))
        {
            _int_enable();
            return (LOG_ENTRY_NOT_AVAILABLE);
        } /* Endif */
        log_header_ptr->READ_PTR = log_ptr->NEXT_PTR;
        log_header_ptr->READS++;
    }
    else if (read_type == LOG_READ_NEWEST)
    {
        log_header_ptr->READS = log_header_ptr->CURRENT_ENTRIES;
        log_ptr = log_header_ptr->WRITE_PTR;
#if MQX_CHECK_ERRORS
    }
    else
    {
        _int_enable();
        return (LOG_INVALID_READ_TYPE);
#endif
    } /* Endif */

    *entry_ptr = *log_ptr;

    _int_enable();

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Resets the lightweight log to its initial state (remove all entries).
 *
 * \param[in] log_number Log number of a previously created lightweight log (if
 * log_number is 0, kernel log is reseted).
 *
 * \return MQX_OK
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 *
 * \see _lwlog_disable
 * \see _lwlog_enable
 */
_mqx_uint _lwlog_reset
(
    _mqx_uint log_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;
    LWLOG_ENTRY_STRUCT_PTR     entry_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */
#endif

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];

    if (log_component_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */

    _int_disable();

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        return (MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return (LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_header_ptr->READS = 0;
    log_header_ptr->CURRENT_ENTRIES = 0;
    log_header_ptr->NUMBER = 1;

    entry_ptr = &log_header_ptr->FIRST_ENTRY;

    log_header_ptr->WRITE_PTR = entry_ptr + (log_header_ptr->MAX_ENTRIES - 1);
    log_header_ptr->READ_PTR = entry_ptr;
    log_header_ptr->OLDEST_PTR = entry_ptr;

    _int_enable();

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Calculates the size required for the lightweight log with given number
 * of entries.
 *
 * The calculation takes into account size of lwlog entries and also the lwlog
 * header structure.
 *
 * \param[in] entries Maximum number of entries in the lightweight log.
 *
 * \return Number of single-addressable units required
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see _lwlog_create_component
 * \see _klog_create
 * \see _klog_create_at
 */
_mem_size _lwlog_calculate_size
(
    _mqx_uint entries
)
{ /* Body */
    _mem_size result;

#if MQX_CHECK_ERRORS
    if (entries == 0)
    {
        return 0;
    } /* Endif */
#endif

    result = (_mem_size) sizeof(LWLOG_HEADER_STRUCT) + (_mem_size) (entries - 1)
                    * (_mem_size) sizeof(LWLOG_ENTRY_STRUCT);

    return result;

} /* Endbody */

/*!
 * \brief Tests the lightweight log component for consistency.
 *
 * \param[out] log_error_ptr Pointer to the lightweight log if error is found (NULL
 * if no error is found).
 *
 * \return MQX_OK Lightweight log component data is valid (Log_error_ptr is NULL.).
 * \return LOG_INVALID Information for a specific lightweight log is not valid
 * (Log_error_ptr contains log number of the first invalid lightweight log.).
 * \return MQX_INVALID_POINTER Log_error_ptr is NULL.
 * \return MQX_INVALID_COMPONENT_BASE Lightweight log component data is not valid
 * (Log_error_ptr is NULL.).
 *
 * \see _lwlog_create_component
 * \see _lwlog_create
 * \see _lwlog_create_at
 */
_mqx_uint _lwlog_test
(
    _mqx_uint _PTR_ log_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;
    LWLOG_ENTRY_STRUCT_PTR     entry_ptr;
    uchar_ptr                  min_ptr;
    uchar_ptr                  max_ptr;
    _mqx_uint                  i, j;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if ((pointer) log_error_ptr == NULL)
    {
        return MQX_INVALID_POINTER;
    } /* Endif */
#endif

    *log_error_ptr = 0;
    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];
    if (log_component_ptr == NULL)
    {
        return (MQX_OK);
    } /* Endif */

    _int_disable();

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    for (i = 0; i < LOG_MAXIMUM_NUMBER; i++)
    {
        log_header_ptr = log_component_ptr->LOGS[i];
        if (log_header_ptr != NULL)
        {
            /* Verify the log pointers */
            min_ptr = (uchar_ptr) log_header_ptr + sizeof(LWLOG_HEADER_STRUCT_PTR);
            max_ptr = min_ptr + sizeof(LWLOG_ENTRY_STRUCT) * log_header_ptr->MAX_ENTRIES;

            if (((uchar_ptr) log_header_ptr->READ_PTR < min_ptr) || ((uchar_ptr) log_header_ptr->READ_PTR >= max_ptr)
                            || ((uchar_ptr) log_header_ptr->WRITE_PTR < min_ptr)
                            || ((uchar_ptr) log_header_ptr->WRITE_PTR >= max_ptr)
                            || ((uchar_ptr) log_header_ptr->OLDEST_PTR < min_ptr)
                            || ((uchar_ptr) log_header_ptr->OLDEST_PTR >= max_ptr))

            {
                _int_enable();
                *log_error_ptr = i;
                return (LOG_INVALID);
            } /* Endif */

            /* Check each entry in the log */
            entry_ptr = &log_header_ptr->FIRST_ENTRY;
            j = log_header_ptr->MAX_ENTRIES;
            while (entry_ptr->NEXT_PTR && j)
            {
                entry_ptr = entry_ptr->NEXT_PTR;
                --j;
                if (((uchar_ptr) entry_ptr < min_ptr) || ((uchar_ptr) entry_ptr >= max_ptr))
                {
                    _int_enable();
                    *log_error_ptr = i;
                    return (LOG_INVALID);
                } /* Endif */
            } /* Endwhile */
        } /* Endif */
    } /* Endfor */

    _int_enable();

    return (MQX_OK);

} /* Endbody */

/*!
 * \private
 *
 * \brief Writes data to the lightweight log.
 *
 * \param[in] log_number Log number of a previously created lightweight log.
 * \param[in] p1         Data to be written into the log entry.
 * \param[in] p2         Data to be written into the log entry.
 * \param[in] p3         Data to be written into the log entry.
 * \param[in] p4         Data to be written into the log entry.
 * \param[in] p5         Data to be written into the log entry.
 * \param[in] p6         Data to be written into the log entry.
 * \param[in] p7         Data to be written into the log entry.
 *
 * \return MQX_OK
 * \return LOG_FULL (Log is full and LOG_OVERWRITE is not set.)
 * \return LOG_DISABLED (Log is disabled.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 *
 * \see _lwlog_write
 */
_mqx_uint _lwlog_write_internal
(
    _mqx_uint     log_number,
    _mqx_max_type p1,
    _mqx_max_type p2,
    _mqx_max_type p3,
    _mqx_max_type p4,
    _mqx_max_type p5,
    _mqx_max_type p6,
    _mqx_max_type p7
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;
    _mqx_max_type _PTR_        data_ptr;
    LWLOG_ENTRY_STRUCT_PTR     log_ptr;
#if MQX_LWLOG_TIME_STAMP_IN_TICKS == 0
    TIME_STRUCT                time;
    MQX_TICK_STRUCT ticks;
#endif

    _GET_KERNEL_DATA(kernel_data);

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];
    log_header_ptr = log_component_ptr->LOGS[log_number];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        return (MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        return (LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    if (!(log_header_ptr->FLAGS & LWLOG_ENABLED))
    {
        return (LOG_DISABLED);
    } /* Endif */

    log_ptr = log_header_ptr->WRITE_PTR->NEXT_PTR;

    if (log_header_ptr->CURRENT_ENTRIES >= log_header_ptr->MAX_ENTRIES)
    {
        if (log_header_ptr->FLAGS & LOG_OVERWRITE)
        {
            if (log_ptr == log_header_ptr->READ_PTR)
            {
                log_header_ptr->READ_PTR = log_ptr->NEXT_PTR;
            } /* Endif */
            log_header_ptr->OLDEST_PTR = log_ptr->NEXT_PTR;
        }
        else
        {
            return (LOG_FULL);
        } /* Endif */
    }
    else
    {
        log_header_ptr->CURRENT_ENTRIES++;
    } /* Endif */

#if MQX_LWLOG_TIME_STAMP_IN_TICKS == 0
    log_ptr->MICROSECONDS = (uint_32)_time_get_microseconds();
    PSP_ADD_TICKS(&kernel_data->TIME, &kernel_data->TIME_OFFSET, &ticks);
    PSP_TICKS_TO_TIME(&ticks, &time);
    log_ptr->SECONDS = time.SECONDS;
    log_ptr->MILLISECONDS = time.MILLISECONDS;
#else
    log_ptr->TIMESTAMP = kernel_data->TIME;
    log_ptr->TIMESTAMP.HW_TICKS = _time_get_hwticks();
    PSP_ADD_TICKS(&log_ptr->TIMESTAMP, &kernel_data->TIME_OFFSET,
                    &log_ptr->TIMESTAMP);
#endif

    log_ptr->SEQUENCE_NUMBER = log_header_ptr->NUMBER++;

    data_ptr = &log_ptr->DATA[0];
    *data_ptr++ = p1;
    *data_ptr++ = p2;
    *data_ptr++ = p3;
    *data_ptr++ = p4;
    *data_ptr++ = p5;
    *data_ptr++ = p6;
    *data_ptr = p7;

    log_header_ptr->WRITE_PTR = log_ptr;

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Writes to the lightweight log.
 *
 * This function writes the log entry only if it returns MQX_OK.
 *
 * \param[in] log_number Log number of a previously created lightweight log.
 * \param[in] p1         Data to be written to the log entry. If log_number is 0
 * and p1 is >= 10 (0 through 9 are reserved for MQX), data specified by p2 through
 * p7 is written to kernel log.
 * \param[in] p2         Data to be written into the log entry.
 * \param[in] p3         Data to be written into the log entry.
 * \param[in] p4         Data to be written into the log entry.
 * \param[in] p5         Data to be written into the log entry.
 * \param[in] p6         Data to be written into the log entry.
 * \param[in] p7         Data to be written into the log entry.
 *
 * \return MQX_OK
 * \return LOG_FULL (Log is full and LOG_OVERWRITE is not set.)
 * \return LOG_DISABLED (Log is disabled.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see _lwlog_read
 * \see _lwlog_disable
 * \see _lwlog_enable
 */
_mqx_uint _lwlog_write
(
    _mqx_uint     log_number,
    _mqx_max_type p1,
    _mqx_max_type p2,
    _mqx_max_type p3,
    _mqx_max_type p4,
    _mqx_max_type p5,
    _mqx_max_type p6,
    _mqx_max_type p7
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint              result;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */

    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG] == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    _INT_DISABLE();

    result = _lwlog_write_internal(log_number, p1, p2, p3, p4, p5, p6, p7);

    _INT_ENABLE();

    return (result);

} /* Endbody */

#endif /* MQX_USE_LWLOGS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/_PE_LDD.h<|end_filename|>
/** ###################################################################
**
**     Filename  : PE_LDD.h
**     Date/Time : 2010-10-04, 14:31
**     Abstract  : Default PE_LDD.h header file.
**                 MQX BSP provides its own "empty" version of PE_LDD.h file 
**                 (used as the main include of the PE files).  
**                 Once the PE generates the file in <project>/Generated_Code folder, 
**                 the PE_LDD.h file should be taken from the new location. 
**                 The include search path order will be used to accomplish this behavior.
**     Copyright : 1997 - 2010 Freescale Semiconductor, Inc. All Rights Reserved.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/

#ifndef __PE_LDD_H
    #define __PE_LDD_H

    /* Empty version of PE_LDD.h */
    #undef PE_LDD_VERSION

#endif  /* __PE_LDD_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/spansion/s29ws64.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: s29ws64.c$
* $Version : 3.8.3.0$
* $Date    : Oct-7-2011$
*
* Comments:
*
*   The file contains the block definitions for the
*   flash device.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"

#define S28WS64_SECTOR_SIZE_8K      (0x2000)
#define S28WS64_NUM_SECTORS_1       (8)
#define S28WS64_SECTOR_SIZE_64K     (0x10000)
#define S28WS64_NUM_SECTORS_2       (126)
#define S28WS64_NUM_SECTORS_3       (8)
#define S28WS64_BANK0_START         (0)
#define S28WS64_BANK1_START         (S28WS64_NUM_SECTORS_1 * S28WS64_SECTOR_SIZE_8K)
#define S28WS64_BANK2_START         ((S28WS64_NUM_SECTORS_1 * S28WS64_SECTOR_SIZE_8K) + (S28WS64_NUM_SECTORS_2 * S28WS64_SECTOR_SIZE_64K))

const FLASHX_BLOCK_INFO_STRUCT _S28WS64_block_map_16bit[] =  {
{ S28WS64_NUM_SECTORS_1, 0, S28WS64_SECTOR_SIZE_8K},
{ S28WS64_NUM_SECTORS_2, S28WS64_BANK1_START,S28WS64_SECTOR_SIZE_64K},
{ S28WS64_NUM_SECTORS_3, S28WS64_BANK2_START,S28WS64_SECTOR_SIZE_8K},
{ 0, 0, 0 }
};

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/fujitsu/29dl3xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: 29dl3xx.c$
* $Version : 3.8.6.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions to program the Fujitsu
*   29DL322/323/324 flash devices.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "29dl3xx.h"
#include "29dl3xx_prv.h"
                                                      
#define FLASH_READY 1
#define FLASH_ERASE_SUSPENDED 2
#define FLASH_TIMEOUT 3
#define FLASH_BUSY 4
#define FLASH_ERROR 5

extern uint_32 _29dl3xx_status(IO_FLASHX_STRUCT_PTR, pointer);

const FLASHX_DEVICE_IF_STRUCT _29dl3xx_if = {
    _29dl3xx_erase,
    _29dl3xx_program,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29dl3xx_program
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs the prom devices listed below:
*       29DL322/29DL323/29DL324
* 
*END*----------------------------------------------------------------------*/

boolean _29dl3xx_program
   (  
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] where to copy data from */
      char_ptr             from_ptr,
      
      /* [OUT} where to copy data to */
      char_ptr             to_ptr,

      /* [IN] the size to copy in bytes */
      _mem_size            size
   )
{ /* Body */
   volatile uint_32 _PTR_  base32_ptr;
   volatile uint_32 _PTR_  dest32_ptr;
   uint_32_ptr             src32_ptr;
   volatile uint_16 _PTR_  base16_ptr;
   volatile uint_16 _PTR_  dest16_ptr;
   uint_16_ptr             src16_ptr;
   volatile uchar _PTR_    base8_ptr;
   volatile uchar _PTR_    dest8_ptr;
   uchar_ptr               src8_ptr;
   uint_32                 tmp1, tmp2;
   uint_32                 result = FLASH_READY;

//    if (!_29dl3xx_erase(flashx_ptr, to_ptr, size)){
//       return (FALSE);
//    } /* Endif */

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 64){

      src32_ptr  = (uint_32_ptr)from_ptr;         
      dest32_ptr = (volatile uint_32 _PTR_)to_ptr;
      base32_ptr = (volatile uint_32 _PTR_)to_ptr;
      while (size) {
         tmp1 = *src32_ptr++;
         if (tmp1 != 0xFFFFFFFF) {
            _int_disable();
            base32_ptr[0x555<<1] = 0xAAAAAAAA;
            base32_ptr[0x2AA<<1] = 0x55555555;
            base32_ptr[0x555<<1] = 0xA0A0A0A0;     /* Write command */
            dest32_ptr[0]        = tmp1;           /* write value */
            _int_enable();
            while ((result = _29dl3xx_status(flashx_ptr,
               (pointer)dest32_ptr)) == FLASH_BUSY)
            {
            }/* Endwhile */
            if (result != FLASH_READY) {
               break;
            } /* Endif */
         }/* Endif */
         tmp2 = *src32_ptr++;

         if (tmp2 != 0xFFFFFFFF) {
            _int_disable();
            base32_ptr[(0x555<<1)+1] = 0xAAAAAAAA;
            base32_ptr[(0x2AA<<1)+1] = 0x55555555;
            base32_ptr[(0x555<<1)+1] = 0xA0A0A0A0;   /* Write command */
            dest32_ptr[1]            = tmp2;         /* write value */
            _int_enable();
            while ((result = _29dl3xx_status(flashx_ptr,
               (pointer)dest32_ptr)) == FLASH_BUSY)
            {
            }/* Endwhile */
            if (result != FLASH_READY) {
               break;
            } /* Endif */
         }/* Endif */
         dest32_ptr++;
         dest32_ptr++;
         size -= 8;
      }/* Endwhile */
      base32_ptr[0] = 0xF0F0F0F0;
      base32_ptr[1] = 0xF0F0F0F0;
      
   } else if (flashx_ptr->WIDTH == 32) {

      src32_ptr  = (uint_32_ptr)from_ptr;         
      dest32_ptr = (volatile uint_32 _PTR_)to_ptr;
      base32_ptr = (volatile uint_32 _PTR_)to_ptr;
      while (size) {
         tmp1 = *src32_ptr++;
         if (tmp1 != 0xFFFFFFFF) {
            _int_disable();
            base32_ptr[0x555] = 0xAAAAAAAA;
            base32_ptr[0x2AA] = 0x55555555;
            base32_ptr[0x555] = 0xA0A0A0A0;     /* Write command */
            *dest32_ptr       = tmp1;           /* write value */
            _int_enable();
            while ((result = _29dl3xx_status(flashx_ptr,
               (pointer)dest32_ptr)) == FLASH_BUSY)
            {
            }/* Endwhile */
            if (result != FLASH_READY) {
               break;
            } /* Endif */
         }/* Endif */
         dest32_ptr++;
         size -= 4;
      }/* Endwhile */
      base32_ptr[0] = 0xF0F0F0F0;

   } else if (flashx_ptr->WIDTH == 16) {

      src16_ptr  = (uint_16_ptr)from_ptr;         
      dest16_ptr = (volatile uint_16 _PTR_)to_ptr;
      base16_ptr = (volatile uint_16 _PTR_)to_ptr;
      while (size) {
         tmp1 = (uint_32)*src16_ptr++;
         if (tmp1 != 0xFFFF) {
            _int_disable();
            base16_ptr[0x555] = 0xAAAA;
            base16_ptr[0x2AA] = 0x5555;
            base16_ptr[0x555] = 0xA0A0;        /* Write command */
            *dest16_ptr       = (uint_16)tmp1; /* write value */
           _int_enable();
            while ((result = _29dl3xx_status(flashx_ptr,
               (pointer)dest16_ptr)) == FLASH_BUSY)
            {
            }/* Endwhile */
            if (result != FLASH_READY) {
               break;
            } /* Endif */
         }/* Endif */
         size -= 2;
         dest16_ptr++;
      }/* Endwhile */
      base16_ptr[0] = 0xF0F0;

   } else if (flashx_ptr->WIDTH == 8) {

      src8_ptr  = (uchar_ptr)from_ptr;         
      dest8_ptr = (volatile uchar _PTR_)to_ptr;
      base8_ptr = (volatile uchar _PTR_)to_ptr;
      while (size) {
         tmp1 = (uint_32)*src8_ptr++;
         if (tmp1 != 0xFF) {
            _int_disable();
            base8_ptr[0x555] = 0xAA;
            base8_ptr[0x2AA] = 0x55;
            base8_ptr[0x555] = 0xA0;        /* Write command */
            *dest8_ptr       = (uchar)tmp1; /* write value */
           _int_enable();
            while ((result = _29dl3xx_status(flashx_ptr,
               (pointer)dest8_ptr)) == FLASH_BUSY)
            {
            }/* Endwhile */
            if (result != FLASH_READY) {
               break;
            } /* Endif */
         }/* Endif */
         size -= 1;
         dest8_ptr++;
      }/* Endwhile */
      base8_ptr[0] = 0xF0;

   } /* Endif */
   
   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */

   return result == FLASH_READY;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29dl3xx_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases 29DL prom devices listed below:
*       29dl3xx
* 
*END*----------------------------------------------------------------------*/

boolean _29dl3xx_erase
   (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] the sector to erase */
      char           _PTR_ input_sect_ptr,

      /* [IN] the sector size */
      _mem_size            sector_size
   )
{ /* Body */
   volatile uint_32 _PTR_ sect32_ptr;
   volatile uint_16 _PTR_ sect16_ptr;
   volatile uchar _PTR_   sect8_ptr;
   uint_32                result;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 64) {
      sect32_ptr = (volatile uint_32 _PTR_)input_sect_ptr;

      _int_disable();
      sect32_ptr[0x555<<1] = 0xAAAAAAAA;
      sect32_ptr[0x2AA<<1] = 0x55555555;
      sect32_ptr[0x555<<1] = 0x80808080;
      sect32_ptr[0x555<<1] = 0xAAAAAAAA;
      sect32_ptr[0x2AA<<1] = 0x55555555;
      sect32_ptr[0]        = 0x30303030;    /* Sector erase */
      _int_enable();
      while ((result = _29dl3xx_status(flashx_ptr, (pointer)sect32_ptr))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect32_ptr[0] = 0xF0F0F0F0;

      _int_disable();
      sect32_ptr[(0x555<<1)+1] = 0xAAAAAAAA;
      sect32_ptr[(0x2AA<<1)+1] = 0x55555555;
      sect32_ptr[(0x555<<1)+1] = 0x80808080;
      sect32_ptr[(0x555<<1)+1] = 0xAAAAAAAA;
      sect32_ptr[(0x2AA<<1)+1] = 0x55555555;
      sect32_ptr[1]            = 0x30303030;    /* Sector erase */
      _int_enable();
      while ((result = _29dl3xx_status(flashx_ptr, (pointer)&sect32_ptr[1]))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect32_ptr[1] = 0xF0F0F0F0;
   
   } else if (flashx_ptr->WIDTH == 32) {
      sect32_ptr = (volatile uint_32 _PTR_)input_sect_ptr;

      _int_disable();
      sect32_ptr[0x555] = 0xAAAAAAAA;
      sect32_ptr[0x2AA] = 0x55555555;
      sect32_ptr[0x555] = 0x80808080;
      sect32_ptr[0x555] = 0xAAAAAAAA;
      sect32_ptr[0x2AA] = 0x55555555;
      sect32_ptr[0]     = 0x30303030;    /* Sector erase */
      _int_enable();
      while ((result = _29dl3xx_status(flashx_ptr, (pointer)sect32_ptr))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect32_ptr[0] = 0xF0F0F0F0;

   } else if (flashx_ptr->WIDTH == 16) {
      sect16_ptr = (volatile uint_16 _PTR_)input_sect_ptr;

      _int_disable();
      sect16_ptr[0x555] = 0xAAAA;
      sect16_ptr[0x2AA] = 0x5555;
      sect16_ptr[0x555] = 0x8080;
      sect16_ptr[0x555] = 0xAAAA;
      sect16_ptr[0x2AA] = 0x5555;
      sect16_ptr[0]     = 0x3030;    /* Sector erase */
      _int_enable();
      while ((result = _29dl3xx_status(flashx_ptr, (pointer)sect16_ptr))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect16_ptr[0] = 0xF0F0;

   } else if (flashx_ptr->WIDTH == 8) {
      sect8_ptr = (volatile uchar _PTR_)input_sect_ptr;

      _int_disable();
      sect8_ptr[0x555] = 0xAA;
      sect8_ptr[0x2AA] = 0x55;
      sect8_ptr[0x555] = 0x80;
      sect8_ptr[0x555] = 0xAA;
      sect8_ptr[0x2AA] = 0x55;
      sect8_ptr[0]     = 0x30;    /* Sector erase */
      _int_enable();
      while ((result = _29dl3xx_status(flashx_ptr, (pointer)sect8_ptr))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect8_ptr[0] = 0xF0;

   }/* Endif */

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */

   return result == FLASH_READY;
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29dl3xx_status
* Returned Value   : uint_32 current status of operation
* Comments         : 
*
*END*----------------------------------------------------------------------*/

uint_32 _29dl3xx_status
   (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR flashx_ptr,
      
      /* [IN] address */
      pointer              addr
   )
{ /* Body */
   volatile uint_32 _PTR_ sect32_ptr;
   volatile uint_16 _PTR_ sect16_ptr;
   volatile uchar _PTR_   sect8_ptr;
   uint_32                tmp1;
   uint_32                tmp2;
   uint_32                toggle;
   uint_32                retry = 2;
   
   sect32_ptr = (volatile uint_32 _PTR_)addr;
   sect16_ptr = (volatile uint_16 _PTR_)addr;
   sect8_ptr  = (volatile uchar _PTR_)addr;

   while (retry--) {
      if (flashx_ptr->WIDTH == 64) {
         tmp1 = *sect32_ptr;
         tmp2 = *sect32_ptr;
         toggle = tmp1 ^ tmp2;   /* See what bits changed */
      } else if (flashx_ptr->WIDTH == 32) {
         tmp1 = *sect32_ptr;
         tmp2 = *sect32_ptr;
         toggle = tmp1 ^ tmp2;   /* See what bits changed */
      } else if (flashx_ptr->WIDTH == 16) {
         tmp1 = *sect16_ptr;
         tmp2 = *sect16_ptr;
         toggle = tmp1 ^ tmp2;   /* See what bits changed */
      } else if (flashx_ptr->WIDTH == 8) {
         tmp1 = *sect8_ptr;
         tmp2 = *sect8_ptr;
         toggle = tmp1 ^ tmp2;   /* See what bits changed */
      }/* Endif */
   
      if (toggle == 0) {
        return FLASH_READY;
      } /* Endif */

      if (toggle & 0x40) {
         if (tmp1 & 0x20) {
            if (retry) {
               continue;
            }/* Endif */
            return FLASH_TIMEOUT;
         }/* Endif */
         return FLASH_BUSY;
      } else {
         if ((toggle & 0x04) && (tmp1 & 0x80)) {
            if (retry) {
               continue;
            }/* Endif */
            return FLASH_ERASE_SUSPENDED;
         } /* Endif */
      }/* Endif */

   } /* Endwhile */

   return FLASH_ERROR;
   
} /* Endbody */
      
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/ipc.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: ipc.c$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains functions of the IPC 
 *   (Inter Processor Communication) component.
 *
 *END************************************************************************/

#include <stdarg.h>
#include <string.h>
#include "mqx_inc.h"
#if MQX_USE_IPC
#include "message.h"
#include "msg_prv.h"
#include "fio.h"
#include "io.h"
#include "io_pcb.h"
#include "name.h"
#include "name_prv.h"
#include "event.h"
#include "event_prv.h"
#include "ipc.h"
#include "ipc_prv.h"
#include "ipc_pcb.h"
#include "ipc_pcbv.h"
#include "ipcrtprv.h"

/* A list of current IPC PCB drivers that have been installed */
QUEUE_STRUCT _ipc_pcb_drivers =
{   NULL, NULL, 0, 0};

/* Dummy router table for the IPC. */
const IPC_ROUTING_STRUCT _ipc_routing_table[] =
{
    {   0, 0, 0}
};

/*
 * Definition of the field sizes in the IPC message data.
 * So that the ENDIAN-ness can be swapped by _msg_swap_endian_data
 */
static const uchar _ipc_msg_type_def[] =
{
    sizeof(_mqx_uint),
    0};

static const uchar _ipc_msg_def[] =
{
    sizeof(_mqx_uint), sizeof(_task_id),
    /* Parameters... number of these must equal IPC_MAX_PARAMETERS */
    sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint),
    sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint),
    sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint),
    sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint),
    0};

static const uchar _ipc_mqx_msg_def[] =
{
    sizeof(_mqx_uint), sizeof(_task_id), sizeof(_task_id), sizeof(_mqx_uint),
    sizeof(_mqx_uint), sizeof(void (_CODE_PTR_)(_mqx_uint)),
    sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(char _PTR_),
    sizeof(_mqx_uint), sizeof(_mqx_uint), sizeof(_mqx_uint),
    0};

const IPC_PROTOCOL_INIT_STRUCT _ipc_init_table[] =
{
    {   NULL, NULL, NULL, 0}
};

static const IPC_INIT_STRUCT _default_ipc_init =
{
    _ipc_routing_table,
    _ipc_init_table
};

/*!
 * \brief Adds an IPC handler for the MQX component.
 * 
 * The IPC task calls the function when an IPC message for the specified MQX 
 * component is received. The IPC task calls the function once for each component.
 * \n The parameter component can be one of:
 * \li KERNEL_EDS_SERIAL
 * \li KERNEL_EVENTS
 * \li KERNEL_IPC
 * \li KERNEL_IPC_MSG_ROUTING
 * \li KERNEL_LOG
 * \li KERNEL_LWLOG
 * \li KERNEL_MESSAGES
 * \li KERNEL_MUTEXES
 * \li KERNEL_NAME_MANAGEMENT
 * \li KERNEL_PARTITIONS
 * \li KERNEL_SEMAPHORES
 * \li KERNEL_TIMER
 * \li KERNEL_WATCHDOG
 * 
 * \param[in] handler   Pointer to the function that MQX calls when it receives 
 * an IPC request for the component.
 * \param[in] component MQX component that the handler is for (see Description).
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (IPC component was not created.)
 * \return MQX_IPC_SERVICE_NOT_AVAILABLE (IPC server has not been started.)
 * 
 * \see _ipc_add_io_ipc_handler   
 */ 
_mqx_uint _ipc_add_ipc_handler
(
    IPC_HANDLER_FPTR handler,
    _mqx_uint        component
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    IPC_COMPONENT_STRUCT_PTR ipc_component_ptr;

    _GET_KERNEL_DATA(kernel_data);

    ipc_component_ptr = kernel_data->IPC_COMPONENT_PTR;

#if MQX_CHECK_ERRORS
    if (!ipc_component_ptr)
    {
        return MQX_IPC_SERVICE_NOT_AVAILABLE;
    } /* Endif */

    if (component > MAX_KERNEL_COMPONENTS)
    {
        return MQX_COMPONENT_DOES_NOT_EXIST;
    } /* Endif */
#endif

    ipc_component_ptr->IPC_COMPONENT_HANDLER[component] = handler;

    return MQX_OK;

} /* Endif */

/*!
 * \brief Add an IPC handler for the I/O component.
 * 
 * The IPC task calls the function when an IPC message for the specified I/O 
 * component is received. The IPC task calls the function once for each component.
 * \n The parameter component can be one of:
 * \li IO_CAN_COMPONENT
 * \li IO_EDS_COMPONENT
 * \li IO_HDLC_COMPONENT
 * \li IO_LAPB_COMPONENT
 * \li IO_LAPD_COMPONENT
 * \li IO_MFS_COMPONENT
 * \li IO_PPP_COMPONENT
 * \li IO_RTCS_COMPONENT
 * \li IO_SDLC_COMPONENT
 * \li IO_SNMP_COMPONENT
 * \li IO_SUBSYSTEM_COMPONENT
 * 
 * \param[in] handler   Pointer to the function that MQX calls when it receives 
 * an IPC request for the component.
 * \param[in] component I/O component that the handler is for (see Description).
 * 
 * \return MQX_OK
 * \return MQX_IPC_SERVICE_NOT_AVAILABLE (IPC server has not been started.)
 * 
 * \see _ipc_add_ipc_handler 
 */ 
_mqx_uint _ipc_add_io_ipc_handler
(
    IPC_HANDLER_FPTR handler,
    _mqx_uint        component
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    IPC_COMPONENT_STRUCT_PTR ipc_component_ptr;

    _GET_KERNEL_DATA(kernel_data);

    ipc_component_ptr = kernel_data->IPC_COMPONENT_PTR;

#if MQX_CHECK_ERRORS
    if (!ipc_component_ptr)
    {
        return MQX_IPC_SERVICE_NOT_AVAILABLE;
    } /* Endif */
#endif

    ipc_component_ptr->IPC_IO_COMPONENT_HANDLER[component] = handler;

    return MQX_OK;

} /* Endbody */

/*!
 * \brief Handles multi-processor event requests.
 * 
 * \param[in] imsg_ptr The incoming message.
 * 
 * \return MQX_OK  
 */ 
_mqx_uint _event_ipc_handler
(
    pointer imsg_ptr
)
{ /* Body */
    IPC_MESSAGE_STRUCT_PTR ipc_msg_ptr = imsg_ptr;
    pointer                event_ptr;
    _mqx_uint              error_code;
    _mqx_uint              result = 0;

    switch (IPC_GET_TYPE(ipc_msg_ptr->MESSAGE_TYPE))
    {
        case IPC_EVENT_OPEN:
        error_code = _event_open((char _PTR_)&ipc_msg_ptr->PARAMETERS[0],
                        &event_ptr);
        result = (_mqx_uint)event_ptr;
        break;
        case IPC_EVENT_SET:
        event_ptr = (pointer)ipc_msg_ptr->PARAMETERS[0];
        error_code = _event_set(event_ptr, ipc_msg_ptr->PARAMETERS[1]);
        break;
        default:
        error_code = MQX_IPC_INVALID_MESSAGE;
        break;
    } /* Endswitch */

    _ipc_send_internal(FALSE,
                    PROC_NUMBER_FROM_QID(ipc_msg_ptr->HEADER.SOURCE_QID),
                    KERNEL_MESSAGES, IPC_ACTIVATE,
                    3, result, ipc_msg_ptr->REQUESTOR_ID,
                    error_code);
    _msg_free(ipc_msg_ptr);

    return MQX_OK;

} /* Endbody */

/*!
 * \brief Installs the handler for IPC events.
 */ 
void _event_install_ipc_handler(void)
{ /* Body */

    _ipc_add_ipc_handler( _event_ipc_handler, KERNEL_EVENTS);

} /* Endbody */

/*!
 * \brief Initializes an IPC for a PCB driver.
 * 
 * The function is used in structure of type IPC_PROTOCOL_STRUCT to initialize the 
 * Inter-Processor Communications over a serial port using the standard 
 * ASYNC_SERIAL driver. 
 * \n The IPC_PROTOCOL_INIT_DATA field in IPC_PROTOCOL_INIT_STRUCT must point to 
 * a structure of type IPC_PCB_INIT_STRUCT.
 * 
 * \param[in] init_ptr Pointer to an IPC protocol initialization structure
 * (IPC_PROTOCOL_INIT_STRUCT).
 * \param[in] data_ptr Pointer to an IPC protocol information structure 
 * (IPC_PROTOCOL_INFO_STRUCT).
 * 
 * \return MQX_OK
 * \return IPC_PCB_OUTPUT_PCB_POOL_CREATE_FAILED
 * \return IPC_PCB_INVALID_QUEUE
 * \return IPC_PCB_PACKET_POOL_CREATE_FAILED
 * \return IPC_PCB_DEVICE_OPEN_FAILED
 * \return IPC_PCB_INPUT_PCB_POOL_CREATE_FAILED
 * \return        
 */ 
_mqx_uint _ipc_pcb_init(
    const IPC_PROTOCOL_INIT_STRUCT * init_ptr,
    pointer                          data_ptr)
{
    IPC_PROTOCOL_INFO_STRUCT_PTR info_ptr;
    IPC_PCB_INFO_STRUCT_PTR      pcb_info_ptr;
    IPC_PCB_INIT_STRUCT_PTR      pcb_init_ptr;
    _io_pcb_pool_id              pcb_pool;
    _queue_id                    qid;
    _pool_id                     msg_pool;
    _mqx_uint                    result = MQX_OK;
    _psp_code_addr               _ipc_pcb_function_location = (_psp_code_addr) _ipc_pcb_input_notification;

    info_ptr = (IPC_PROTOCOL_INFO_STRUCT_PTR) data_ptr;
    pcb_info_ptr = (IPC_PCB_INFO_STRUCT_PTR) _mem_alloc_system_zero((_mem_size) sizeof(IPC_PCB_INFO_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (pcb_info_ptr == NULL)
    {
        return (_task_get_error());
    }
#endif
    info_ptr->IPC_PROTOCOL_INFO_PTR = pcb_info_ptr;

    pcb_init_ptr = (IPC_PCB_INIT_STRUCT_PTR) init_ptr->IPC_PROTOCOL_INIT_DATA;

    info_ptr->IPC_TYPE = IPC_PCB_PROTOCOL;
    info_ptr->IPC_INIT_PTR = init_ptr;

    /* CREATE OUTPUT PCB POOL */
    pcb_pool = _io_pcb_create_pool(1, 0, pcb_init_ptr->OUT_PCBS_INITIAL, pcb_init_ptr->OUT_PCBS_TO_GROW,
                    pcb_init_ptr->OUT_PCBS_MAX, 0, NULL, 0, NULL);
#if MQX_CHECK_ERRORS
    if (pcb_pool == IO_PCB_NULL_POOL_ID)
    {
        result = IPC_PCB_OUTPUT_PCB_POOL_CREATE_FAILED;
    }
    else
    {
#endif
        pcb_info_ptr->PCB_OUTPUT_POOL = pcb_pool;
#if MQX_CHECK_ERRORS
    }
#endif

    /* Create output message queue */
    if (result == MQX_OK)
    {
        qid = _msgq_open_system((_queue_number) info_ptr->IPC_INIT_PTR->IPC_OUT_QUEUE, 0, _ipc_pcb_output_notification,
                        info_ptr);
#if MQX_CHECK_ERRORS
        if (qid == MSGQ_NULL_QUEUE_ID)
        {
            result = IPC_PCB_INVALID_QUEUE;
        }
        else
        {
#endif
            pcb_info_ptr->OUT_MSG_QID = qid;
#if MQX_CHECK_ERRORS
        }
#endif
    }

    if (result == MQX_OK)
    {
        /* Create input message pool */
        msg_pool = _msgpool_create(pcb_init_ptr->IN_MESSAGES_MAX_SIZE, pcb_init_ptr->IN_MESSAGES_TO_ALLOCATE,
                        pcb_init_ptr->IN_MESSAGES_TO_GROW, pcb_init_ptr->IN_MESSAGES_MAX_ALLOCATE);
#if MQX_CHECK_ERRORS
        if (msg_pool == MSGPOOL_NULL_POOL_ID)
        {
            result = (IPC_PCB_PACKET_POOL_CREATE_FAILED);
        }
        else
        {
#endif
            pcb_info_ptr->MSG_INPUT_POOL = msg_pool;
#if MQX_CHECK_ERRORS
        }
#endif
    }

    if (result == MQX_OK)
    {
        if (pcb_init_ptr->DEVICE_INSTALL != NULL)
        {
            result = (*pcb_init_ptr->DEVICE_INSTALL)(pcb_init_ptr->IO_PCB_DEVICE_NAME,
                            pcb_init_ptr->DEVICE_INSTALL_PARAMETER);
        }
    }

    if (result == MQX_OK)
    {
        /* Open the IO PCB device */
        pcb_info_ptr->FD = fopen(pcb_init_ptr->IO_PCB_DEVICE_NAME, (char_ptr) 0);
#if MQX_CHECK_ERRORS
        if (pcb_info_ptr->FD == NULL)
        {
            result = IPC_PCB_DEVICE_OPEN_FAILED;
        }
#endif
    }

    if (result == MQX_OK)
    {
        pcb_pool = _io_pcb_create_pool(1, 0, pcb_init_ptr->IN_MESSAGES_TO_ALLOCATE, pcb_init_ptr->IN_MESSAGES_TO_GROW,
                        pcb_init_ptr->IN_MESSAGES_MAX_ALLOCATE, _ipc_pcb_alloc, info_ptr, 0, NULL);
#if MQX_CHECK_ERRORS
        if (pcb_pool == IO_PCB_NULL_POOL_ID)
        {
            result = IPC_PCB_INPUT_PCB_POOL_CREATE_FAILED;
        }
        else
        {
#endif
            pcb_info_ptr->PCB_INPUT_POOL = pcb_pool;
#if MQX_CHECK_ERRORS
        }
#endif
    }

    if (result == MQX_OK)
    {
        result = ioctl(pcb_info_ptr->FD, IO_PCB_IOCTL_READ_CALLBACK_SET, &_ipc_pcb_function_location);
    }

    if (result == MQX_OK)
    {
        result = ioctl(pcb_info_ptr->FD, IO_PCB_IOCTL_SET_INPUT_POOL, (pointer) &pcb_info_ptr->PCB_INPUT_POOL);
    }

    if (result == MQX_OK)
    {
        result = ioctl(pcb_info_ptr->FD, IO_PCB_IOCTL_START, NULL);
    }

#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        if (pcb_info_ptr->FD)
        {
            fclose(pcb_info_ptr->FD);
        }
        if (pcb_info_ptr->PCB_INPUT_POOL)
        {
            _io_pcb_destroy_pool(pcb_info_ptr->PCB_INPUT_POOL);
        }
        if (pcb_info_ptr->MSG_INPUT_POOL)
        {
            _msgpool_destroy(pcb_info_ptr->MSG_INPUT_POOL);
        }
        if (pcb_info_ptr->OUT_MSG_QID)
        {
            _msgq_close(pcb_info_ptr->OUT_MSG_QID);
        }
        if (pcb_info_ptr->PCB_OUTPUT_POOL)
        {
            _io_pcb_destroy_pool(pcb_info_ptr->PCB_OUTPUT_POOL);
        }
        _mem_free(pcb_info_ptr);
    }
    else
    {
#endif
        if (_ipc_pcb_drivers.NEXT == NULL)
        {
            _queue_init(&_ipc_pcb_drivers, 0);
        }
        _queue_enqueue(&_ipc_pcb_drivers, &pcb_info_ptr->QUEUE);
#if MQX_CHECK_ERRORS
    }
#endif

    return (result);
}

/*!
 * \brief This function is called whenever a message is to be sent offboard.
 * 
 * It packs the message into a PCB and sends it off to an IO PCB device driver.   
 * The function is called by _msg_send (it is an activation function).
 * Note that the PCB free function is set to _ipc_pcb_free.
 * 
 * \param[in] data_ptr Pointer to an IPC protocol information structure 
 * (IPC_PROTOCOL_INFO_STRUCT). 
 */                     
void _ipc_pcb_output_notification
(
    pointer data_ptr
)
{ /* Body */
    IPC_PROTOCOL_INFO_STRUCT_PTR info_ptr;
    IPC_PCB_INFO_STRUCT_PTR      pcb_info_ptr;
    IO_PCB_STRUCT_PTR            pcb_ptr;
    IPC_MESSAGE_STRUCT_PTR       msg_ptr;
#if PSP_MEMORY_ADDRESSING_CAPABILITY > 8
    boolean                      must_unpack;
    boolean                      success;
    uint_32                      frag_size;
    uint_32                      result;
#endif

    info_ptr = (IPC_PROTOCOL_INFO_STRUCT_PTR) data_ptr;
    pcb_info_ptr = (IPC_PCB_INFO_STRUCT_PTR) info_ptr->IPC_PROTOCOL_INFO_PTR;

#if PSP_MEMORY_ADDRESSING_CAPABILITY > 8
    /* Determine if we must unpack the messages */
    result = ioctl(pcb_info_ptr->FD, IO_PCB_IOCTL_UNPACKED_ONLY, &must_unpack);
    if (result != MQX_OK)
    {
        must_unpack = FALSE;
    }
#endif

    while (_msgq_get_count(info_ptr->IPC_OUT_QID))
    {
        pcb_ptr = _io_pcb_alloc(pcb_info_ptr->PCB_OUTPUT_POOL, FALSE);
        if (pcb_ptr == NULL)
        {
            return;
        }
        msg_ptr = (IPC_MESSAGE_STRUCT_PTR) _msgq_poll(info_ptr->IPC_OUT_QID);

#if PSP_MEMORY_ADDRESSING_CAPABILITY > 8
        if (must_unpack)
        {
            success = _ipc_pcb_unpack_message(msg_ptr, pcb_ptr);
            _msg_free(msg_ptr);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
            if (!success)
            {
                /* Toss the packet */
                _io_pcb_free_internal(pcb_ptr);
                return;
            }
#endif
        }
        else
        {
            pcb_ptr->FRAGMENTS[0].LENGTH = (uint_32)msg_ptr->HEADER.SIZE;
            pcb_ptr->FRAGMENTS[0].FRAGMENT = (uchar_ptr)msg_ptr;
            pcb_ptr->OWNER_PRIVATE_FLAGS = IPC_PCB_FRAG_IS_MSG;
        }
#else
        pcb_ptr->FRAGMENTS[0].LENGTH = (uint_32) msg_ptr->HEADER.SIZE;
        pcb_ptr->FRAGMENTS[0].FRAGMENT = (uchar_ptr) msg_ptr;
#endif
        pcb_ptr->FREE_PCB_FUNCTION_PTR = _ipc_pcb_free;

        _io_pcb_write(pcb_info_ptr->FD, pcb_ptr);

        pcb_info_ptr->OUTPUT_MESSAGE_COUNT++;

    }
}

/*!
 * \brief Frees a pcb sent via the ipc_pcb output task.
 *   
 * The message that is in the PCB must be freed.
 * 
 * \param[in] pcb_ptr The pcb that has finished. 
 */ 
_mqx_uint _ipc_pcb_free
(
    IO_PCB_STRUCT_PTR pcb_ptr
)
{
    _msg_free(pcb_ptr->FRAGMENTS[0].FRAGMENT);
    return (_io_pcb_free_internal(pcb_ptr));
}

/*!
 * \brief Obtains PCB from input PCB pool.
 * 
 * This function is called whenever a PCB is being allocated from the input PCB 
 * pool, by the input task. For example, when the input task is preparing to set 
 * up receive data, it would obtain a PCB from the input pool. At that point, 
 * this function will be called by the pcb alloc function. This function obtains 
 * a message and sets up the PCB to point to it.
 *  
 * \param[out] pcb_ptr  Pointer to the new PCB.
 * \param[in]  data_ptr Pointer to an IPC protocol information structure. 
 * (IPC_PROTOCOL_INFO_STRUCT).
 * 
 * \return Pointer to the PCB (or new PCB).
 * \return NULL (failure) 
 */ 

IO_PCB_STRUCT_PTR _ipc_pcb_alloc
(
    IO_PCB_STRUCT_PTR pcb_ptr,
    pointer           data_ptr
)
{
    IPC_PROTOCOL_INFO_STRUCT_PTR info_ptr;
    IPC_PCB_INFO_STRUCT_PTR      pcb_info_ptr;
    MESSAGE_HEADER_STRUCT_PTR    msg_ptr;

    info_ptr = (IPC_PROTOCOL_INFO_STRUCT_PTR) data_ptr;
    pcb_info_ptr = (IPC_PCB_INFO_STRUCT_PTR) info_ptr->IPC_PROTOCOL_INFO_PTR;

    msg_ptr = _msg_alloc(pcb_info_ptr->MSG_INPUT_POOL);
#if MQX_CHECK_ERRORS
    if (msg_ptr == NULL)
    {
        return (NULL);
    }
#endif
    pcb_ptr->FRAGMENTS[0].LENGTH = 0;
    pcb_ptr->FRAGMENTS[0].FRAGMENT = (uchar_ptr) msg_ptr;
    pcb_ptr->INSTANTIATOR_PRIVATE = info_ptr;

    return (pcb_ptr);
}

/*!
 * \brief This function is called by the underlying IO PCB device driver whenever 
 * an input message has been received.
 * 
 * \param[in] fd_ptr  The file descriptor used to set the notification function.
 * \param[in] pcb_ptr The pcb that has arrived. 
 */ 
void _ipc_pcb_input_notification
(
    MQX_FILE_PTR      fd_ptr,
    IO_PCB_STRUCT_PTR pcb_ptr
)
{
    KERNEL_DATA_STRUCT_PTR       kernel_data;
    IPC_PROTOCOL_INFO_STRUCT_PTR info_ptr;
    IPC_PCB_INFO_STRUCT_PTR      pcb_info_ptr;
    MESSAGE_HEADER_STRUCT_PTR    msg_ptr;

    _GET_KERNEL_DATA(kernel_data);

    info_ptr = (IPC_PROTOCOL_INFO_STRUCT_PTR) pcb_ptr->INSTANTIATOR_PRIVATE;
    pcb_info_ptr = (IPC_PCB_INFO_STRUCT_PTR) info_ptr->IPC_PROTOCOL_INFO_PTR;

    msg_ptr = (MESSAGE_HEADER_STRUCT_PTR) pcb_ptr->FRAGMENTS[0].FRAGMENT;
    if (MSG_MUST_CONVERT_HDR_ENDIAN(msg_ptr->CONTROL))
    {
        _msg_swap_endian_header(msg_ptr);
    }
    if (PROC_NUMBER_FROM_QID(msg_ptr->TARGET_QID) == 0)
    {
        /* This is a special message for this CPU */
        msg_ptr->TARGET_QID = BUILD_QID(kernel_data->INIT.PROCESSOR_NUMBER, QUEUE_FROM_QID(msg_ptr->TARGET_QID));
    }
    _msgq_send(msg_ptr);

    _io_pcb_free(pcb_ptr);

    pcb_info_ptr->INPUT_MESSAGE_COUNT++;
}

/*!
 * \brief Adds a route to the message routing table.
 * 
 * The IPC component must first be created.
 * 
 * \param[in] min_proc_number Minimum processor number in the range.
 * \param[in] max_proc_number Maximum processor number in the range.
 * \param[in] queue           Queue number of the IPC to use for processor numbers 
 * in the range.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (IPC component was not created.)
 * \return MQX_INVALID_PROCESSOR_NUMBER
 * \return MSGQ_INVALID_QUEUE_ID
 * \return IPC_ROUTE_EXISTS
 * \return MQX_OUT_OF_MEMORY
 * 
 * \see _ipc_msg_route_remove
 * \see _ipc_msg_processor_route_exists
 * \see IPC_ROUTING_STRUCT      
 */ 
_mqx_uint _ipc_msg_route_add
(
    _processor_number min_proc_number,
    _processor_number max_proc_number,
    _queue_number     queue
)
{
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR component_ptr;
    IPC_MSG_ROUTING_STRUCT_PTR           routing_ptr;
#if MQX_CHECK_ERRORS
    _processor_number                    i;
#endif

    _GET_KERNEL_DATA(kernel_data);
    component_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING];
#if MQX_CHECK_ERRORS
    if (component_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    }
    if ((min_proc_number < 1) || (max_proc_number > MQX_MAX_PROCESSOR_NUMBER) || (min_proc_number > max_proc_number))
    {
        return (MQX_INVALID_PROCESSOR_NUMBER);
    }
    if ((queue == 0) || (queue >= MAX_QNUMBERS))
    {
        return (MSGQ_INVALID_QUEUE_ID);
    }
    for (i = min_proc_number; i <= max_proc_number; ++i)
    {
        if (_ipc_msg_processor_route_exists(i))
        {
            return (IPC_ROUTE_EXISTS);
        }
    }
#endif
    routing_ptr = (IPC_MSG_ROUTING_STRUCT_PTR) _mem_alloc_system(sizeof(IPC_MSG_ROUTING_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (routing_ptr == NULL)
    {
        return (MQX_OUT_OF_MEMORY);
    }
#endif
    routing_ptr->MIN_PROC_NUMBER = min_proc_number;
    routing_ptr->MAX_PROC_NUMBER = max_proc_number;
    routing_ptr->QUEUE = queue;

    _QUEUE_ENQUEUE(&component_ptr->ROUTING_LIST, &routing_ptr->LINK);

    return (MQX_OK);
}

/*!
 * \brief Removes a route from the message routing table.
 * 
 * The IPC component must first be installed.
 * 
 * \param[in] min_proc_number Minimum processor number in the range.
 * \param[in] max_proc_number Maximum processor number in the range.
 * \param[in] queue           Queue number of the IPC to remove.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (IPC component was not created.)
 * \return MQX_INVALID_PROCESSOR_NUMBER  
 * 
 * \see _ipc_msg_route_add     
 * \see _ipc_msg_processor_route_exists  
 */ 
_mqx_uint _ipc_msg_route_remove
(
    _processor_number min_proc_number,
    _processor_number max_proc_number,
    _queue_number     queue
)
{
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR component_ptr;
    IPC_MSG_ROUTING_STRUCT_PTR           routing_ptr;
    IPC_MSG_ROUTING_STRUCT_PTR           next_ptr;
    uint_16                              i;

    _GET_KERNEL_DATA(kernel_data);
    component_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR)(
                    (pointer) kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING]);
#if MQX_CHECK_ERRORS
    if (component_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    }
    if ((min_proc_number < 1) || (max_proc_number > MQX_MAX_PROCESSOR_NUMBER) || (min_proc_number > max_proc_number))
    {
        return (MQX_INVALID_PROCESSOR_NUMBER);
    }
#endif

    routing_ptr = (IPC_MSG_ROUTING_STRUCT_PTR)((pointer) component_ptr->ROUTING_LIST.NEXT);

    /* Scan list for specified processors */
    for (i = 0; i < component_ptr->ROUTING_LIST.SIZE; i++)
    {
        next_ptr = (IPC_MSG_ROUTING_STRUCT_PTR)((pointer) routing_ptr->LINK.NEXT);
        if ((routing_ptr->MIN_PROC_NUMBER == min_proc_number) && (routing_ptr->MAX_PROC_NUMBER == max_proc_number))
        {
#if MQX_CHECK_ERRORS
            if (routing_ptr->QUEUE == queue)
            {
#endif
                _QUEUE_REMOVE(&component_ptr->ROUTING_LIST, &routing_ptr->LINK);
                _mem_free(routing_ptr);
#if MQX_CHECK_ERRORS
            }
#endif
        }
        routing_ptr = next_ptr;
    }

    return (MQX_OK);
}

/*!
 * \brief Checks whether a route to the specified processor exists.
 * 
 * \param[in] proc_number Processor number to check for a route.
 * 
 * \return Pointer to the route (a route exists).
 * \return NULL (Route does not exist.)
 * 
 * \see _ipc_msg_route_add
 * \see _ipc_msg_route_remove  
 */ 
pointer _ipc_msg_processor_route_exists
(
    _processor_number proc_number
)
{
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR component_ptr;
    IPC_MSG_ROUTING_STRUCT_PTR           routing_ptr;
    uint_16                              i;

    _GET_KERNEL_DATA(kernel_data);
    component_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING];
#if MQX_CHECK_ERRORS
    if (component_ptr == NULL)
    {
        return (NULL);
    }
#endif

    routing_ptr = (IPC_MSG_ROUTING_STRUCT_PTR)((pointer) component_ptr->ROUTING_LIST.NEXT);
    for (i = 0; i < component_ptr->ROUTING_LIST.SIZE; i++)
    {
        if ((proc_number >= routing_ptr->MIN_PROC_NUMBER) && (proc_number <= routing_ptr->MAX_PROC_NUMBER))
        {
            return ((pointer) routing_ptr);
        }
        routing_ptr = (IPC_MSG_ROUTING_STRUCT_PTR)((pointer) routing_ptr->LINK.NEXT);
    }

    /* Route not found */
    return (NULL);
}

/*!
 * \private
 * 
 * \brief This function is called from the _ipc_init to initialize the message
 * router.
 * 
 * \param[in] route_ptr Pointer to IPC routing structure (IPC_MSG_ROUTING_STRUCT_PTR).
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (IPC component was not created.)
 * \return MQX_INVALID_PROCESSOR_NUMBER
 * \return MSGQ_INVALID_QUEUE_ID
 * \return IPC_ROUTE_EXISTS
 * \return MQX_OUT_OF_MEMORY 
 */ 
_mqx_uint _ipc_msg_route_init_internal
(
    const IPC_ROUTING_STRUCT * route_ptr
)
{
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR component_ptr;

    _mqx_uint result;

    _GET_KERNEL_DATA(kernel_data);

    component_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR) _mem_alloc_system_zero(
                    (_mem_size) sizeof(IPC_MSG_ROUTING_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (component_ptr == NULL)
    {
        return (MQX_OUT_OF_MEMORY);
    }
#endif

    _QUEUE_INIT(&component_ptr->ROUTING_LIST, 0);

    /* Install the message routing handlers */
    kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING] = (pointer) component_ptr;

    while (route_ptr->QUEUE != 0)
    {
        result = _ipc_msg_route_add(route_ptr->MIN_PROC_NUMBER, route_ptr->MAX_PROC_NUMBER, route_ptr->QUEUE);
#if MQX_CHECK_ERRORS
        if (result != MQX_OK)
        {
            return (result);
        }
#endif
        route_ptr++;
    }

    component_ptr->MSG_ROUTER = _ipc_msg_route_internal;

    return (MQX_OK);
}

/*!
 * \private
 * 
 * \brief This function is called from _msg_send to route an inter-processor message.
 * 
 * \param[in] pnum     The processor to send the message to.
 * \param[in] message  The message to be sent.
 * \param[in] blocking Is this a blocking message.
 * 
 * \return TRUE or FALSE
 * 
 * \warning On failure, calls _task_set_error() to set the following task error code:
 * \li MSGQ_INVALID_QUEUE_ID 
 */ 
_mqx_uint _ipc_msg_route_internal
(
    _processor_number pnum,
    pointer           message,
    boolean           blocking
)
{
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR component_ptr;
    IPC_MSG_ROUTING_STRUCT_PTR           route_ptr;
    boolean                              result;
    _queue_number                        queue;

    _GET_KERNEL_DATA(kernel_data);
    component_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING];

    route_ptr = (IPC_MSG_ROUTING_STRUCT_PTR) _ipc_msg_processor_route_exists(pnum);
    if (!route_ptr)
    {
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
        return (FALSE);
    }
    queue = route_ptr->QUEUE;

    result = _msgq_send_queue(message, BUILD_QID(kernel_data->INIT.PROCESSOR_NUMBER, queue));
    if (result && blocking && (!kernel_data->IN_ISR))
    {
        _int_disable();
        kernel_data->ACTIVE_PTR->STATE = SEND_BLOCKED;
        _task_block();
        _int_enable();
    }

    return (result);
}

/*!
 * \brief Task that initializes IPCs and processes remote service requests.
 * 
 * For applications to use the IPC component, the task must be either specified 
 * in the task template list as an autostart task or explicitly created.
 * \n The task installs the IPCs that are listed in the IPC initialization 
 * structure. Pointer to this initialization structure (IPC_INIT_STRUCT_PTR) is 
 * provided as the creation parameter, otherwise default IPC_INIT_STRUCT is used 
 * (_default_ipc_init). When the initialization is finished it waits for service
 * requests from remote processors.
 *  
 * \param[in] parameter Pointer to the IPC_INIT_STRUCT (task creation parameter).
 * 
 * \see IPC_INIT_STRUCT
 */ 
void _ipc_task
(
    uint_32 parameter
)
{
    KERNEL_DATA_STRUCT_PTR         kernel_data;
    IPC_COMPONENT_STRUCT_PTR       ipc_component_ptr;
    const IPC_INIT_STRUCT          * ipc_init_ptr = (IPC_INIT_STRUCT_PTR) parameter;
    IPC_MESSAGE_STRUCT_PTR         msg_ptr;
    IPC_MQX_MESSAGE_STRUCT_PTR     ipc_msg_ptr;
    const IPC_PROTOCOL_INIT_STRUCT * protocol_init_ptr;
    IPC_PROTOCOL_INFO_STRUCT_PTR   info_ptr;
    TD_STRUCT_PTR                  td_ptr;
    IPC_HANDLER_FPTR               handler;
    _queue_id                      queue;
    _mqx_uint                      result;
    _mqx_uint                      component;

    _GET_KERNEL_DATA(kernel_data);

    if (ipc_init_ptr == NULL)
    {
        ipc_init_ptr = &_default_ipc_init;
    }

    /* Install the message routing handlers */
    result = _ipc_msg_route_init_internal(ipc_init_ptr->ROUTING_LIST_PTR);
#if MQX_CHECK_ERRORS
    if (result != MQX_OK)
    {
        _task_set_error(result);
        _task_block();
    }
#endif

    kernel_data->MY_IPC_TD_PTR = kernel_data->ACTIVE_PTR;
    kernel_data->MY_IPC_ID = kernel_data->ACTIVE_PTR->TASK_ID;

    /* Create the IPC component structure */
    ipc_component_ptr = (IPC_COMPONENT_STRUCT_PTR) _mem_alloc_zero((_mem_size) sizeof(IPC_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (ipc_component_ptr == NULL)
    {
        _task_block();
    }
#endif
    kernel_data->IPC_COMPONENT_PTR = ipc_component_ptr;

    /* Create a pool of messages for use by the ipc task. */
    kernel_data->IPC_NAMED_POOL = _msgpool_create(sizeof(IPC_MESSAGE_STRUCT), IPC_NUM_MESSAGES, IPC_GROW_MESSAGES,
                    IPC_LIMIT_MESSAGES);
#if MQX_CHECK_ERRORS || MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (kernel_data->IPC_NAMED_POOL == MSGPOOL_NULL_POOL_ID)
    {
        _task_block();
    }
#endif

    /* Open the ipc message queue */
    queue = _msgq_open(IPC_MESSAGE_QUEUE_NUMBER, 0);
#if MQX_CHECK_ERRORS
    if (queue == MSGQ_NULL_QUEUE_ID)
    {
        _task_block();
    }
#endif

    kernel_data->IPC = _ipc_send_internal;

    /* Initialize inter-processor communications protocols */
    protocol_init_ptr = ipc_init_ptr->PROTOCOL_LIST_PTR;
    while (protocol_init_ptr->IPC_PROTOCOL_INIT != NULL)
    {
#if MQX_CHECK_ERRORS
        if (((_queue_number) protocol_init_ptr->IPC_OUT_QUEUE) == 0
                        || ((_queue_number) protocol_init_ptr->IPC_OUT_QUEUE > MQX_MAX_PROCESSOR_NUMBER))
        {
            _task_block();
        }
#endif
        info_ptr = (IPC_PROTOCOL_INFO_STRUCT_PTR) _mem_alloc_zero((_mem_size) sizeof(IPC_PROTOCOL_INFO_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (info_ptr == NULL)
        {
            _task_block();
        }
#endif
        info_ptr->IPC_OUT_QUEUE = protocol_init_ptr->IPC_OUT_QUEUE;
        info_ptr->IPC_NAME = protocol_init_ptr->IPC_NAME;
        info_ptr->IPC_OUT_QID = _msgq_get_id(0, (_queue_number) protocol_init_ptr->IPC_OUT_QUEUE);
        info_ptr->IPC_INIT_PTR = protocol_init_ptr;

        (*protocol_init_ptr->IPC_PROTOCOL_INIT)(protocol_init_ptr, info_ptr);

        protocol_init_ptr++;
    }

    /*
     * The IPC Initialization is complete. Wait for messages to come in
     * and service them.
     */
    while (TRUE)
    {

        _task_set_error(MQX_OK);
        msg_ptr = (IPC_MESSAGE_STRUCT_PTR) _msgq_receive(MSGQ_ANY_QUEUE, 0L);
        if (MSG_MUST_CONVERT_DATA_ENDIAN(msg_ptr->HEADER.CONTROL))
        {
            _msg_swap_endian_data((uchar _PTR_) ((pointer) _ipc_msg_type_def), (MESSAGE_HEADER_STRUCT_PTR)(
                            (pointer) msg_ptr));
            if (msg_ptr->MESSAGE_TYPE & IPC_MQX_TYPE_MASK)
            {
                _mem_swap_endian((uchar _PTR_) _ipc_mqx_msg_def, &msg_ptr->NUMBER_OF_PARAMETERS);
            }
            else
            {
                _mem_swap_endian_len((uchar _PTR_) _ipc_msg_def, &msg_ptr->NUMBER_OF_PARAMETERS,
                                msg_ptr->NUMBER_OF_PARAMETERS + 2);
            }
        }

        if (msg_ptr->MESSAGE_TYPE & IPC_MQX_TYPE_MASK)
        {

            ipc_msg_ptr = (IPC_MQX_MESSAGE_STRUCT_PTR)((pointer) msg_ptr);
            switch (ipc_msg_ptr->MESSAGE_TYPE & IPC_MQX_TYPE_MASK)
            {

                case IPC_MQX_CREATE:
                    _KLOGE4(KLOG_task_create, 0, ipc_msg_ptr->TEMPLATE_INDEX,ipc_msg_ptr->CREATE_PARAMETER)
                    ;
                    if (ipc_msg_ptr->TEMPLATE_INDEX == 0)
                    {
                        td_ptr = _task_build_internal(0, (uint_32) &ipc_msg_ptr->TEMPLATE, NULL, 0, FALSE);
                    }
                    else
                    {
                        td_ptr = _task_build_internal(ipc_msg_ptr->TEMPLATE_INDEX,
                                        (uint_32) ipc_msg_ptr->CREATE_PARAMETER, NULL, 0, FALSE);
                    }

                    _KLOGX3(KLOG_task_create, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER)
                    ;
                    if (td_ptr != NULL)
                    {
                        td_ptr->PARENT = ipc_msg_ptr->REQUESTOR_ID;
                        _task_ready(td_ptr);
                        _KLOGX3(KLOG_task_create, td_ptr->TASK_ID, MQX_OK);
                    }
                    else
                    {
                        _KLOGX3(KLOG_task_create, MQX_NULL_TASK_ID, _task_get_error());
                    }
                    result = (_mqx_uint) td_ptr->TASK_ID;
                    _ipc_send_internal(FALSE, PROC_NUMBER_FROM_TASKID(msg_ptr->REQUESTOR_ID), KERNEL_MESSAGES,
                                    IPC_ACTIVATE, (_mqx_uint) 3, result, msg_ptr->REQUESTOR_ID,
                                    kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
                    break;

                case IPC_MQX_ABORT:
                    result = (_mqx_uint) _task_abort(ipc_msg_ptr->VICTIM_ID);
                    break;
                case IPC_MQX_RESTART:
                    result = (_mqx_uint) _task_restart(ipc_msg_ptr->VICTIM_ID, NULL, TRUE);
                    break;
                case IPC_MQX_DESTROY:
                    result = (_mqx_uint) _task_destroy(ipc_msg_ptr->VICTIM_ID);
                    break;

                case IPC_MQX_ACTIVATE:
                    /* Start the specified task, setting the INFO
                     * to the returned result.
                     */
                    td_ptr = (TD_STRUCT_PTR) _task_get_td(ipc_msg_ptr->REQUESTOR_ID);
                    if (td_ptr != NULL)
                    {
                        if (td_ptr->STATE == SEND_BLOCKED)
                        {
                            td_ptr->INFO = ipc_msg_ptr->VICTIM_ID;
                            _task_set_error_td_internal(td_ptr, ipc_msg_ptr->CREATE_PARAMETER);
                            _task_ready(td_ptr);
                        }
                    }
                    result = MQX_OK;
                    break;

            }

            _msg_free((pointer) msg_ptr);

        }
        else
        {

            component = IPC_GET_COMPONENT(msg_ptr->MESSAGE_TYPE);

            if (component < MAX_KERNEL_COMPONENTS)
            {
                handler = ipc_component_ptr->IPC_COMPONENT_HANDLER[component];
#if MQX_CHECK_ERRORS
                if (handler)
                {
#endif
                    _task_set_error(MQX_OK);
                    result = (*handler)((pointer) msg_ptr);
#if MQX_CHECK_ERRORS
                }
                else
                {
                    result = MQX_IPC_SERVICE_NOT_AVAILABLE;
                }
#endif
            }
            else if (component < (MAX_KERNEL_COMPONENTS + MAX_IO_COMPONENTS))
            {
                handler = ipc_component_ptr->IPC_IO_COMPONENT_HANDLER[component - MAX_KERNEL_COMPONENTS];
#if MQX_CHECK_ERRORS
                if (handler)
                {
#endif
                    _task_set_error(MQX_OK);
                    result = (*handler)((pointer) msg_ptr);
#if MQX_CHECK_ERRORS
                }
                else
                {
                    result = MQX_IPC_SERVICE_NOT_AVAILABLE;
                    _msg_free((pointer) msg_ptr);
                }
#endif
            }
            else
            {
                result = MQX_IPC_INVALID_MESSAGE;
                _msg_free((pointer) msg_ptr);
            }
        }
    }
}

/*!
 * \private
 * 
 * \brief Creates an IPC message and sends it.
 * 
 * \param[in] blocking         Specifies whether or not to block current task.
 * \param[in] processor_number The processor to send to.
 * \param[in] component        The component to receive the message.
 * \param[in] type             The type of component message.
 * \param[in] num_parameters   The number of parameters in the message.
 * 
 * \return MQX_OK
 * \return Task error code from ....  
 */ 
_mqx_uint _ipc_send_internal
(
    boolean           blocking,
    _processor_number processor_number,
    _mqx_uint         component,
    _mqx_uint         type,
    _mqx_uint         num_parameters,
    ...)
{
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    IPC_MESSAGE_STRUCT_PTR     msg_ptr;
    IPC_MQX_MESSAGE_STRUCT_PTR ipc_msg_ptr;
    va_list                    ap;
    _mqx_uint                  i;

    _GET_KERNEL_DATA(kernel_data);

    kernel_data->ACTIVE_PTR->TASK_ERROR_CODE = MQX_OK;

    msg_ptr = (IPC_MESSAGE_STRUCT_PTR) _msg_alloc((_pool_id) kernel_data->IPC_NAMED_POOL);
    while (msg_ptr == NULL)
    {
        _time_delay(kernel_data->KERNEL_ALARM_RESOLUTION * 2);
        msg_ptr = (IPC_MESSAGE_STRUCT_PTR) _msg_alloc((_pool_id) kernel_data->IPC_NAMED_POOL);
    }

    msg_ptr->HEADER.TARGET_QID = BUILD_QID(processor_number, IPC_MESSAGE_QUEUE_NUMBER);
    msg_ptr->HEADER.SOURCE_QID = BUILD_QID((_processor_number) kernel_data->INIT.PROCESSOR_NUMBER,
                    IPC_MESSAGE_QUEUE_NUMBER);

    va_start(ap, num_parameters);

    if (component == KERNEL_MESSAGES)
    {
        ipc_msg_ptr = (IPC_MQX_MESSAGE_STRUCT_PTR)((pointer) msg_ptr);
        ipc_msg_ptr->REQUESTOR_ID = kernel_data->ACTIVE_PTR->TASK_ID;
        switch (type)
        {
            case IPC_TASK_CREATE:
            case IPC_TASK_CREATE_WITH_TEMPLATE:
                ipc_msg_ptr->MESSAGE_TYPE = IPC_MQX_CREATE;
                if (type == IPC_TASK_CREATE_WITH_TEMPLATE)
                {
                    ipc_msg_ptr->TEMPLATE_INDEX = 0;
                    ipc_msg_ptr->TEMPLATE.TASK_TEMPLATE_INDEX = va_arg(ap, uint_32);
                    ipc_msg_ptr->TEMPLATE.TASK_ADDRESS = (TASK_FPTR)va_arg(ap, _psp_code_addr);
                    ipc_msg_ptr->TEMPLATE.TASK_STACKSIZE = va_arg(ap, _mem_size);
                    ipc_msg_ptr->TEMPLATE.TASK_PRIORITY = va_arg(ap, _mqx_uint);
                    ipc_msg_ptr->TEMPLATE.TASK_NAME = va_arg(ap, char_ptr);
                    ipc_msg_ptr->TEMPLATE.TASK_ATTRIBUTES = va_arg(ap, _mqx_uint);
                    ipc_msg_ptr->TEMPLATE.CREATION_PARAMETER = va_arg(ap, uint_32);
                    ipc_msg_ptr->CREATE_PARAMETER = ipc_msg_ptr->TEMPLATE.CREATION_PARAMETER;
                    ipc_msg_ptr->TEMPLATE.DEFAULT_TIME_SLICE = va_arg(ap, uint_32);
                    ipc_msg_ptr->HEADER.SIZE = sizeof(IPC_MQX_MESSAGE_STRUCT);
                }
                else
                {
                    i = va_arg(ap, _mqx_uint); /* Toss processor number */
                    ipc_msg_ptr->TEMPLATE_INDEX = va_arg(ap, _mqx_uint);
                    ipc_msg_ptr->CREATE_PARAMETER = (uint_32) va_arg(ap, uint_32);
                    ipc_msg_ptr->HEADER.SIZE = sizeof(IPC_MQX_MESSAGE_STRUCT) - sizeof(TASK_TEMPLATE_STRUCT);
                }
                break;
            case IPC_TASK_DESTROY:
                ipc_msg_ptr->MESSAGE_TYPE = IPC_MQX_DESTROY;
                ipc_msg_ptr->VICTIM_ID = va_arg(ap, _mqx_uint);
                ipc_msg_ptr->HEADER.SIZE = sizeof(IPC_MQX_MESSAGE_STRUCT) - sizeof(TASK_TEMPLATE_STRUCT);
                break;
            case IPC_TASK_ABORT:
                ipc_msg_ptr->MESSAGE_TYPE = IPC_MQX_ABORT;
                ipc_msg_ptr->VICTIM_ID = va_arg(ap, _mqx_uint);
                ipc_msg_ptr->HEADER.SIZE = sizeof(IPC_MQX_MESSAGE_STRUCT) - sizeof(TASK_TEMPLATE_STRUCT);
                break;
            case IPC_TASK_RESTART:
                ipc_msg_ptr->MESSAGE_TYPE = IPC_MQX_RESTART;
                ipc_msg_ptr->VICTIM_ID = va_arg(ap, _mqx_uint);
                ipc_msg_ptr->HEADER.SIZE = sizeof(IPC_MQX_MESSAGE_STRUCT) - sizeof(TASK_TEMPLATE_STRUCT);
                break;
            case IPC_ACTIVATE:
                ipc_msg_ptr->MESSAGE_TYPE = IPC_MQX_ACTIVATE;
                ipc_msg_ptr->VICTIM_ID = va_arg(ap, _mqx_uint);
                ipc_msg_ptr->REQUESTOR_ID = va_arg(ap, _mqx_uint);
                ipc_msg_ptr->CREATE_PARAMETER = (uint_32) va_arg(ap, uint_32);
                ipc_msg_ptr->HEADER.SIZE = sizeof(IPC_MQX_MESSAGE_STRUCT) - sizeof(TASK_TEMPLATE_STRUCT);
                break;
        }
    }
    else
    {
        msg_ptr->MESSAGE_TYPE = IPC_SET_COMPONENT(0, component);
        msg_ptr->MESSAGE_TYPE = IPC_SET_TYPE(msg_ptr->MESSAGE_TYPE, type);
        if (!blocking)
        {
            msg_ptr->MESSAGE_TYPE = IPC_SET_NON_BLOCKING(msg_ptr->MESSAGE_TYPE, 1);
        }

        msg_ptr->REQUESTOR_ID = kernel_data->ACTIVE_PTR->TASK_ID;

        if (num_parameters > IPC_MAX_PARAMETERS)
        {
            num_parameters = IPC_MAX_PARAMETERS;
        }

        if (type & IPC_STRING_PARAMETER)
        {
            --num_parameters;
            msg_ptr->HEADER.SIZE = (_msg_size) sizeof(IPC_MESSAGE_STRUCT);
        }
        else
        {
            msg_ptr->HEADER.SIZE = (_msg_size)(sizeof(IPC_MESSAGE_STRUCT) - (IPC_MAX_PARAMETERS * sizeof(uint_32))
                            + (num_parameters * sizeof(uint_32)));
        }

        msg_ptr->NUMBER_OF_PARAMETERS = (uint_32) num_parameters;

        for (i = 0; (i < num_parameters) && (i < IPC_MAX_PARAMETERS); ++i)
        {
            msg_ptr->PARAMETERS[i] = (uint_32) (va_arg(ap, uint_32));
        }

        if (type & IPC_STRING_PARAMETER)
        {
            char_ptr to_ptr = (char_ptr) &msg_ptr->PARAMETERS[i];
            char_ptr from_ptr = (char_ptr) va_arg(ap, pointer);
            uint_32 size = (IPC_MAX_PARAMETERS - i) * sizeof(uint_32);
            strncpy((pointer) to_ptr, (pointer) from_ptr, size);
            to_ptr[size - 1] = '\0';
        }
    }

    va_end(ap);

    if (blocking)
    {
        if (_msgq_send_blocked_internal(msg_ptr))
        {
            return MQX_OK;
        }
    }
    else
    {
        if (_msgq_send(msg_ptr))
        {
            return MQX_OK;
        }
    }

    return kernel_data->ACTIVE_PTR->TASK_ERROR_CODE;
}
#endif /* MQX_USE_IPC */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/Motor_control.h<|end_filename|>
#ifndef __MOTOR_CONTROL
  #define __MOTOR_CONTROL

#define  PWM_OE_RISE       BIT(0) // Подъем на сигнале разрешении сигналов PWM к драйверу двигателя
#define  PWM_OE_FALL       BIT(1) // Спад   на сигнале разрешении сигналов PWM к драйверу двигателя
#define  VFO_RISE          BIT(2) // Подъем на сигнале аварии драйвера
#define  VFO_FALL          BIT(3) // Спад   на сигнале аварии драйвера
#define  MOTOR_START_DOWN  BIT(4) // Старт  двигателя влево
#define  MOTOR_START_UP    BIT(5) // Старт  двигателя вправо
#define  MOTOR_STOP        BIT(6) // Остановка двигателя
#define  SMPL_ARR1_FULL    BIT(7) // Заполнен массив 1 отсчетов
#define  SMPL_ARR2_FULL    BIT(8) // Заполнен массив 2 отсчетов
#define  MEAS_RES_READY    BIT(9) // Готовность результатов статистических измерений сигналов


#define  MAX_MOT_FREQ       50
#define  PWM_FREQ           16000
#define  PWM_MODULO        (60000000UL/(2*PWM_FREQ))

// Поскольку обновление компараторов происходит при достижении счетчиком максимального значения,
// то для верхнего уровня самый короткий импульс будет в ситуации когда сразу после обновления выход обнулится
#define  PWM_MARGIN_HI_LEV  180// Импульс не короче 3 мкс

// Здесь в тактах даем в два раза меньшую величину поскольку в расчет берется импульс при убывании и его продолжение при нарастании
#define  PWM_MARGIN_LO_LEV  90 // Импульс не короче 3 мкс.

#define  PWM_SCALE_TRASITION_TIME 0.5 // Время в сек за которое коэффициент масштабирования PWM меняет значение

#define  MOVING_DOWN        1
#define  MOVING_UP          0

#define  MOT_IDLE           0   // Мотор остановлен или останавливается
#define  MOT_START_ACTION   1   // Идентификатор процесса старта движения
#define  MOT_STOP_ACTION    2   // Идентификатор процесса остановки движения
#define  MOT_UNIFORM_MOTION 3   // Равномерное движение

#define  MIN_FREQ           4   // Частота при снижении до которой происходит полная остановка двигателя
#define  START_FREQ         5   // Частота с которой стартует вращение двигателя



typedef struct PWM_CBL
{
  unsigned int       action;         // Фаза движения. 1- старт, 2- процесс торможения, 0 - равномерное движение
  unsigned int       direction;      // Направление вращения. Принимает значения MOVING_DOWN и MOVING_UP
  unsigned int       skew_cnt;       // Счетчик этапа изменения частоты вращения
  unsigned int       mot_freq;       // Частота вращения двигателя
  unsigned long long ll_mot_freq;    // Значение текущей частоты в 64-х битном формате 64,32
  signed long long   ll_step;        // Значение шага частоты в 64-х битном формате
  int                motor_drv_fail; // Флаг ошибки драйвера мотора.
  int                fail_cnt;       // Счетчик ошибок.

  float              up_accel_pwm_scale;  // Коэффициент масштабирования PWM при ускорении  и движении вверх . Более 0.5 означает насыщенную синусоиду
  float              up_decel_pwm_scale;  // Коэффициент масштабирования PWM при замедлении и движении вверх . Более 0.5 означает насыщенную синусоиду
  float              up_pwm_scale;        // Коэффициент масштабирования PWM при установившейся скорости и движении вверх . Более 0.5 означает насыщенную синусоиду
  int                up_move_freq;
  int                up_acceler_time;
  int                up_deceler_time;
  float              down_accel_pwm_scale;// Коэффициент масштабирования PWM при ускорении  и движении вниз . Более 0.5 означает насыщенную синусоиду
  float              down_decel_pwm_scale;// Коэффициент масштабирования PWM при замедлении и движении вниз . Более 0.5 означает насыщенную синусоиду
  float              down_pwm_scale;      // Коэффициент масштабирования PWM при установившейся скорости и движении вниз . Более 0.5 означает насыщенную синусоиду
  int                down_move_freq;
  int                down_acceler_time;
  int                down_deceler_time;
  float              pwm_scale;
  float              pwm_scale_delta;
  unsigned int       pwm_scale_cnt;
}
T_MC_CBL, _PTR_ T_MC_CBL_ptr;

typedef struct
{
  int pwm_a;
  int pwm_b;
  int pwm_c;
}
T_3ph_pwm;

void      Control_task(uint_32 initial_data);
void      Motor_ISR_task(uint_32 initial_data);
void      PWM_start(int dir, unsigned int freq);
void      PWM_stop(void);
int       PWM_state(void);
void      PWM_from_Cnt(T_3ph_pwm *pmp_3ph_ptr);
_mqx_uint MC_get_events(_mqx_uint *events, _mqx_uint ticks, _mqx_uint events_mask);
void      MC_create_event(void);
_mqx_uint MC_set_events(_mqx_uint evnt);

void MC_get_CBL(T_MC_CBL *cbl_ptr);
void MC_set_CBL(T_MC_CBL *cbl_ptr);

void      MC_start_motor_moving(INT8U dir,  INT32U target_freq, INT32U time);
void      MC_stop_motor_moving(INT32U time);
void      MC_emergency_stop_motor(void);
void      MC_init_PWM(void);
T_MC_CBL *MC_get_pcbl(void);

void      MC_init_speed_change(unsigned int action,  unsigned int target_freq, unsigned int target_time);

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcspcb.h<|end_filename|>
#ifndef __rtcspcb_h__
#define __rtcspcb_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcspcb.h$
* $Version : 3.8.8.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Constants and prototype declarations which are internal
*   to the PCB module.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

/*
** Number of PCBs to allocate
*/
#define RTCSPCB_LAYERS_MAX  6
/* The value RTCSPCB_FRAG_MAX MUST remain 4.  If it has to be changed, you
   will need to modify the code in AH.C and ESP.C to reflect the change. */
#define RTCSPCB_FRAG_MAX    4


/*
** The maximum header size, which includes:
**    A link layer header, one of
**       Ethernet 26
**       PPP      4
**    One or more network layer headers created by RTCS (IP over IP)
**       IP       20
**    A network layer header
**       IP       60
**    An IPSEC layer
**       AH       24
**       ESP      8
**    A transport layer header, one of
**       ICMP     8+60+8 [ICMP+IP+data]
**       UDP      8
**       TCP      60
*/

#define RTCSPCB_LL_DATA_MAX         (26)
 
#if RTCSCFG_ENABLE_IPIP
   #define RTCSPCB_IPIP_DATA_MAX    (20)
#else 
   #define RTCSPCB_IPIP_DATA_MAX    (0)
#endif

#define RTCSPCB_IP_DATA_MAX         (60)

#if RTCSCFG_ENABLE_IPSEC
   #define RTCSPCB_IPSEC_DATA_MAX   (24+8)
#else 
   #define RTCSPCB_IPSEC_DATA_MAX   (0)
#endif

#if RTCSCFG_ENABLE_ICMP
   #define RTCSPCB_TL_DATA_MAX      (8+60+8)
#elif RTCSCFG_ENABLE_TCP
   #define RTCSPCB_TL_DATA_MAX      (60)
#else
   #define RTCSPCB_TL_DATA_MAX      (8)
#endif

#define RTCSPCB_DATA_MAX    (RTCSPCB_LL_DATA_MAX+RTCSPCB_IPIP_DATA_MAX+RTCSPCB_IP_DATA_MAX+RTCSPCB_IPSEC_DATA_MAX+RTCSPCB_TL_DATA_MAX)

/*
** Packet transmission types
*/
#define RTCSPCB_TYPE_UNICAST        0x01
#define RTCSPCB_TYPE_BROADCAST      0x02
#define RTCSPCB_TYPE_MULTICAST      0x04
#define RTCSPCB_TYPE_ONLYCAST       0x07


/*
** Packet Internet Protocol version number definitions
*/
#define   IPV4     0x04
#define   IPV6     0x06



/***************************************
**
** Macros
**
*/

/*
** Returns total size of PCB
*/
#define RTCSPCB_SIZE(pcb)  ((pcb)->SIZE)

/*
** Returns pointer to beginning of packet data at current layer
*/
#define RTCSPCB_DATA(pcb)           ((pcb)->CURRENT_LAYER)
#define RTCSPCB_DATA_NETWORK(pcb)   ((pcb)->NETWORK_LAYER)
#define RTCSPCB_DATA_TRANSPORT(pcb) ((pcb)->TRANSPORT_LAYER)

#define RTCSPCB_TRANSPORT_PROTL(pcb) ((pcb)->TRANS_PROTL)
#define RTCSPCB_TRANSPORT_DELTA(pcb) ((pcb)->TRANS_DELTA)

#define RTCSPCB_SET_TRANS_PROTL(pcb, protl) ((pcb)->TRANS_PROTL = (protl))
#define RTCSPCB_SET_TRANS_DELTA(pcb, delta) ((pcb)->TRANS_DELTA = (delta))


/***************************************
**
** Type definitions
**
*/

/*
** Packet Control Block
**
**  General use structure, used within all protocol layers which deal
**  with datagram-like chunks of data.  It contains packet data, where the
**  beginning of data for each layer is pointed to by LAYER[]; CL
**  indicates which entry of LAYER[] corresponds to the layer currently being
**  processed, and SIZE is the 'current' amount of data within the whole
**  packet.  Currently the layers used are ordered as follows:
**
**   layer:     0           1       2       3
**           (Medium) -\-- ARP
**                      \- IP -\-- ICMP
**                              \- UCP --- Application
**                               \ TCP --- Application
**
*/
typedef struct rtcspcb {

   struct rtcspcb _PTR_ NEXT;       /* (must be first field)            */

   PCB_PTR     PCBPTR;             /* the actual packet                */

   /*
   ** These fields are managed by the RTCSPCB_* functions
   */
   uint_32     SIZE;                /* size of total packet             */

   uchar_ptr   CURRENT_LAYER;       /* start of current header          */
   uchar_ptr   NETWORK_LAYER;       /* the network (IP) header          */
   uchar_ptr   TRANSPORT_LAYER;     /* the transport (TCP/UDP) header   */

   void (_CODE_PTR_  PCB_FREE)(PCB_PTR);  /* PCB_PTR->FREE backup       */
   pointer           PCB_PRIVATE;         /* PCB_PTR->PRIVATE backup    */
   PCB_FRAGMENT      PCB_BUFFER;          /* PCB_PTR->FRAG[0] backup    */

   PCB_PTR           PCB_ORIG;            /* PCB_PTR backup (fork)      */

   struct rtcspcb _PTR_ DUPPTR;     /* pointer to original RTCSPCB      */
   _rtcs_sem            DUPCOUNT;   /* count of duplicated packets      */





   PCB            PCB;
   PCB_FRAGMENT   FRAG[RTCSPCB_FRAG_MAX]; /* (must follow PCB)          */

   uint_32        NUM_FRAGS;        // Number of fragments in use in the above PCB. Set to 0
                                    // when PCB_PTR does not reference this PCB.

   uint_32        FREE_FRAG_BITFIELD;  /* a bit field to determine which   **
                                    ** frags must be freed or not       */



   uint_32     HEADER_FRAG_USED;    /* used bytes in first fragment     */
   uint_32     HEADER_FRAG_FREE;    /* free bytes in first fragment     */
   
   uchar       HEADER_FRAG_BUFFER[RTCSPCB_DATA_MAX];
   uchar       _RESERVED[2];        // RTCSPCB_DATA_MAX is usually not longword aligned, 
                                    // because the ethernet header is 26 bytes, so add
                                    // two bytes to keep everything else aligned.


   /*
   ** The following information must be filled before sending the
   ** PCB to IP (whether from the link layer or the transport layer)
   */

   uint_32        TYPE;             /* unicast/multicast/broadcast      */
   pointer        IFSRC;            /* source interface                 */
   uint_32 (_CODE_PTR_ IP_COMPLETE)(pointer, struct rtcspcb _PTR_ _PTR_, _ip_address, _ip_address, uint_32);

   uint_32        IP_SUM;           /* transport layer checksum         */
   uchar_ptr      IP_SUM_PTR;       /* ptr to transport layer checksum  */
   /*
   ** Used exclusively by UDP:
   **    For blocking sends, a pointer to the application parms structure
   */
   pointer        UDP_REQUEST;


   struct {
      RTCS_LINKOPT_STRUCT  RX;
      RTCS_LINKOPT_STRUCT  TX;
   }                       LINK_OPTIONS;

   uchar                   TRANS_PROTL;
   uchar                   RESERVED[3];
   uint_32                 TRANS_DELTA;
#if RTCSCFG_ENABLE_IP6
    unsigned char *next_header_p;
#endif
#if RTCSCFG_ENABLE_IPIP && RTCSCFG_ENABLE_IP4
   /*
   ** Used by IP over IP:
   **    Used in IPIP_send to send the TCPIP task a message, from TCPIP context.
   */
   _ip_address             IPIP_SOURCE;
   _ip_address             IPIP_DEST;
#endif
} RTCSPCB, _PTR_ RTCSPCB_PTR;


/***************************************
**
** Prototypes
**
*/

uint_32 RTCSPCB_init(void);
RTCSPCB_PTR RTCSPCB_alloc(void);

RTCSPCB_PTR RTCSPCB_alloc_send(void);
RTCSPCB_PTR RTCSPCB_alloc_recv(PCB_PTR);
RTCSPCB_PTR RTCSPCB_alloc_dup(RTCSPCB_PTR);
#define RTCSPCB_free(p) PCB_free((p)->PCBPTR)

uint_32 RTCSPCB_fork       (RTCSPCB_PTR);
uint_32 RTCSPCB_insert_header     (RTCSPCB_PTR, uint_32);
uint_32 RTCSPCB_next       (RTCSPCB_PTR, uint_32);
uint_32 RTCSPCB_shrink     (RTCSPCB_PTR, uint_32);
uint_32 RTCSPCB_append_fragment       (RTCSPCB_PTR, uint_32, uchar_ptr);
uint_32 RTCSPCB_append_fragment_autofree (RTCSPCB_PTR, uint_32, uchar_ptr);
uint_32 RTCSPCB_depend     (RTCSPCB_PTR, RTCSPCB_PTR);

void RTCSPCB_memcopy (RTCSPCB_PTR, pointer, uint_32, uint_32);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Atan.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Atan.h
*
* @author   B04459
* 
* @version  1.0.1.0
* 
* @date     Dec-6-2012
* 
* @brief    Header file for #GFLIB_Atan function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef GFLIB_ATAN_H_
#define GFLIB_ATAN_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif
/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*!
  \def GFLIB_Atan
  Function alias.
*/
#define GFLIB_Atan(x) GFLIB_AtanANSIC((x), &gflibAtanCoef)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/

/*------------------------------------------------------------------------*//*!
@struct GFLIB_ATAN_TAYLOR_COEF_T "\GFLIB_Atan.h"

@brief      Structure containing four polynomial coefficients for one sub-interval.

@details    Output of \f$\arctan\left(f32In\right)\f$ for
            interval \f$\left[0,1\right)\f$ of the input ratio is divided
            into eight sub-sectors. Polynomial approximation is done using a 4th
            order polynomial, for each sub-sector respectively. Four coefficients
            for a single sub-interval are stored in this (#GFLIB_ATAN_TAYLOR_COEF_T)
            structure.
*//*-------------------------------------------------------------------------*/
typedef struct
{
	const Frac32  f32a[4];  /*!< Array of five 32-bit elements for storing
                            coefficients of the piece-wise polynomial. */
}GFLIB_ATAN_TAYLOR_COEF_T;

/*------------------------------------------------------------------------*//*!
@struct GFLIB_ATAN_TAYLOR_T "\GFLIB_Atan.h"

@brief      Structure containing eight sub-structures with polynomial
            coefficients to cover all sub-intervals.

@details    Output of \f$\arctan\left(f32In\right)\f$ for
            interval \f$\left[0,1\right)\f$ of the input ratio is divided
            into eight sub-sectors. Polynomial approximation is done using a 4th
            order polynomial, for each sub-sector respectively. Eight arrays,
            each including four polynomial coefficients for each sub-interval,
            are stored in this (#GFLIB_ATAN_TAYLOR_COEF_T) structure.

            \par
            By the calling function alias #GFLIB_Atan, default values of the
            coefficients are used. Polynomial coefficients can be modified by
            the user and in such a case the full function call shall be used, i.e.
            #GFLIB_AtanANSIC
*//*-------------------------------------------------------------------------*/

typedef struct
{
    const GFLIB_ATAN_TAYLOR_COEF_T  GFLIB_ATAN_SECTOR[8]; /*!< Array of eight
                                elements for storing eight sub-arrays (each
                                sub-array contains four 32-bit coefficients)
                                for all sub-intervals.*/
} GFLIB_ATAN_TAYLOR_T;

/******************************************************************************
* Exported Variables
******************************************************************************/

extern const GFLIB_ATAN_TAYLOR_T gflibAtanCoef;

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*! 
* @ingroup GFLIB_GROUP 
*/ 
extern Frac32 GFLIB_AtanANSIC(Frac32 f32In, const GFLIB_ATAN_TAYLOR_T *const pParam);

/******************************************************************************
* Inline functions
******************************************************************************/ 

#endif /*GFLIB_ATAN_H_*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/debug/iodebug_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: debug_prv.h$
* $Version : 3.8.2.0$
* $Date    : Sep-16-2011$
*
* Comments:
*
*   The file contains private functions prototype, defines, structure 
*   definitions private to debug driver.
*
*END************************************************************************/

#ifndef __iodebug_prv_h__
#define __iodebug_prv_h__

#include "iodebug.h"

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/*----------------------------------------------------------------------*/
/*
**                          DATATYPE DEFINITIONS
*/

typedef struct {
    char                        FLUSH_CHAR;
    char _PTR_                  BUFFER_PTR;
    uint_32                     BUFFER_POS;
    int_32                      COUNT;
    IODEBUG_INIT_STRUCT_PTR     DEV_INIT_DATA_PTR;
    LWSEM_STRUCT                LWSEM;
} IO_DEBUG_DEVICE_STRUCT, _PTR_ IO_DEBUG_DEVICE_STRUCT_PTR; 


/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

/* Internal debug functions */
#ifdef __cplusplus
extern "C" {
#endif

extern void _io_debug_semi_write_char(register char_ptr);
extern char _io_debug_semi_read_char(void);
extern void _io_debug_semi_write_string(register char_ptr);
extern void _io_debug_semi_buffer_flush(IO_DEBUG_DEVICE_STRUCT_PTR);
extern void _io_debug_semi_buffer_write(IO_DEBUG_DEVICE_STRUCT_PTR, char_ptr);

extern boolean _io_debug_itm_write_char(register char_ptr);

extern _mqx_int _io_debug_open(MQX_FILE_PTR, char_ptr, char_ptr);
extern _mqx_int _io_debug_close(MQX_FILE_PTR);
extern _mqx_int _io_debug_read(MQX_FILE_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_debug_write(MQX_FILE_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_debug_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);
extern void _io_debug_buffer_flush(IO_DEBUG_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/polled/i2c_pol_mcf52xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_pol_mcf52xx.c$
* $Version : 3.8.14.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains low level functions for the I2C polled device driver
*   for 52XX Coldfire family.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "i2c.h"
#include "i2c_pol_prv.h"
#include "i2c_mcf52xx_prv.h"


extern uint_32 _mcf52xx_i2c_polled_init (MCF52XX_I2C_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _mcf52xx_i2c_polled_deinit (IO_I2C_POLLED_DEVICE_STRUCT_PTR, VMCF52XX_I2C_INFO_STRUCT_PTR);
extern uint_32 _mcf52xx_i2c_polled_rx (IO_I2C_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _mcf52xx_i2c_polled_tx (IO_I2C_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _mcf52xx_i2c_polled_ioctl (VMCF52XX_I2C_INFO_STRUCT_PTR, uint_32, uint_32_ptr);
static uint_8  _mcf52xx_i2c_find_baud_index (uint_32);
static uint_32 _mcf52xx_i2c_polled_rx_tx (VMCF52XX_I2C_STRUCT_PTR, VMCF52XX_I2C_INFO_STRUCT_PTR, uchar_ptr, uint_32);


/* I2C frequency divider values taken from the MCF5282UM.pdf, Figure 24-3. */
/* duplicated items are commented out, if commented out value is wanted, uncoment it,
   comment out duplicated and rebuilt bsp */
static const MCF52XX_I2C_BAUDRATE_STRUCT _i2c_baudrate_tbl[] = {
   {BSP_I2C_CLOCK/3840, 0x1F},
   {BSP_I2C_CLOCK/3072, 0x1E},
   {BSP_I2C_CLOCK/2560, 0x1D},
   {BSP_I2C_CLOCK/2304, 0x1C},
   {BSP_I2C_CLOCK/2048, 0x3F},
   {BSP_I2C_CLOCK/1920, 0x1B},
   {BSP_I2C_CLOCK/1792, 0x3E},
   {BSP_I2C_CLOCK/1536, 0x1A},
//   {BSP_I2C_CLOCK/1536, 0x3D},
   {BSP_I2C_CLOCK/1280, 0x19},
//   {BSP_I2C_CLOCK/1280, 0x3C},
   {BSP_I2C_CLOCK/1152, 0x18},
   {BSP_I2C_CLOCK/1024, 0x3B},
   {BSP_I2C_CLOCK/960 , 0x17},
   {BSP_I2C_CLOCK/896 , 0x3A},
   {BSP_I2C_CLOCK/768 , 0x16},
//   {BSP_I2C_CLOCK/768 , 0x39},
   {BSP_I2C_CLOCK/640 , 0x15},
//   {BSP_I2C_CLOCK/640 , 0x38},
   {BSP_I2C_CLOCK/576 , 0x14},
   {BSP_I2C_CLOCK/512 , 0x37},
   {BSP_I2C_CLOCK/480 , 0x13},
   {BSP_I2C_CLOCK/448 , 0x36},
   {BSP_I2C_CLOCK/384 , 0x12},
//   {BSP_I2C_CLOCK/384 , 0x35},
   {BSP_I2C_CLOCK/320 , 0x11},
//   {BSP_I2C_CLOCK/320 , 0x34},
   {BSP_I2C_CLOCK/288 , 0x10},
   {BSP_I2C_CLOCK/256 , 0x33},
   {BSP_I2C_CLOCK/240 , 0x0F},
   {BSP_I2C_CLOCK/224 , 0x32},
//   {BSP_I2C_CLOCK/192 , 0x31},
   {BSP_I2C_CLOCK/192 , 0x0E},
   {BSP_I2C_CLOCK/160 , 0x0D},
//   {BSP_I2C_CLOCK/160 , 0x30},
   {BSP_I2C_CLOCK/144 , 0x0C},
   {BSP_I2C_CLOCK/128 , 0x0B},
//   {BSP_I2C_CLOCK/128 , 0x2F},
   {BSP_I2C_CLOCK/112 , 0x2E},
   {BSP_I2C_CLOCK/104 , 0x0A},
   {BSP_I2C_CLOCK/96  , 0x2D},
   {BSP_I2C_CLOCK/88  , 0x09},
//   {BSP_I2C_CLOCK/80  , 0x2C},
   {BSP_I2C_CLOCK/80  , 0x08},
   {BSP_I2C_CLOCK/72  , 0x2B},
   {BSP_I2C_CLOCK/68  , 0x07},
   {BSP_I2C_CLOCK/64  , 0x2A},
   {BSP_I2C_CLOCK/56  , 0x06},
//   {BSP_I2C_CLOCK/56  , 0x29},
   {BSP_I2C_CLOCK/48  , 0x05},
//   {BSP_I2C_CLOCK/48  , 0x28},
   {BSP_I2C_CLOCK/44  , 0x04},
   {BSP_I2C_CLOCK/40  , 0x03},
//   {BSP_I2C_CLOCK/40  , 0x27},
   {BSP_I2C_CLOCK/36  , 0x26},
   {BSP_I2C_CLOCK/34  , 0x02},
   {BSP_I2C_CLOCK/32  , 0x25},
   {BSP_I2C_CLOCK/30  , 0x01},
   {BSP_I2C_CLOCK/28  , 0x00},
//   {BSP_I2C_CLOCK/28  , 0x24},
   {BSP_I2C_CLOCK/26  , 0x23},
   {BSP_I2C_CLOCK/24  , 0x22},
   {BSP_I2C_CLOCK/22  , 0x21},
   {BSP_I2C_CLOCK/20  , 0x20},
};


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_find_baud_index
* Returned Value   : index into table of baudrate dividers
* Comments         :
*    Find best I2C setting for given baudrate.
*
*END*********************************************************************/

static uint_8 _mcf52xx_i2c_find_baud_index 
   (
      /* [IN] Desired baudrate */
      uint_32 input_baud
   )
{
   uint_8 low, high, i;
   
   low = 0; 
   high = sizeof(_i2c_baudrate_tbl)/sizeof(MCF52XX_I2C_BAUDRATE_STRUCT) - 1;
   do 
   {
      i = (low + high) >> 1;
      if (input_baud < _i2c_baudrate_tbl[i].BAUD_RATE)
      {
         high = i - 1;
      } else {
         low = i + 1;
      }
   } while ((_i2c_baudrate_tbl[i].BAUD_RATE != input_baud) && (high >= low));
   
   /* in case we did not found exact BAUD rate use nearest slower settings than requested */
   if ((_i2c_baudrate_tbl[i].BAUD_RATE > input_baud) && (i != 0))
   {
      i--;
   }
   
   return i;
}


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_polled_install
* Returned Value   : MQX error code
* Comments         :
*    Install an I2C device.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_polled_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr                     identifier,
  
      /* [IN] The I/O init data pointer */
      MCF52XX_I2C_INIT_STRUCT_CPTR init_data_ptr
   )
{ /* Body */

   return _io_i2c_polled_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, pointer _PTR_, char_ptr))_mcf52xx_i2c_polled_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_mcf52xx_i2c_polled_deinit,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_mcf52xx_i2c_polled_rx,
      (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_mcf52xx_i2c_polled_tx,
      (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_mcf52xx_i2c_polled_ioctl, 
      (pointer)init_data_ptr);

} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_polled_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an I2C device.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_polled_init
   (
      /* [IN] Initialization information for the device being opened */
      MCF52XX_I2C_INIT_STRUCT_PTR io_init_ptr,

      /* [OUT] Address to store device specific information */
      pointer _PTR_               io_info_ptr_ptr,
       
      /* [IN] The rest of the name of the device opened */
      char_ptr                    open_name_ptr

   )
{ /* Body */
   VMCF52XX_I2C_STRUCT_PTR        i2c_ptr;
   VMCF52XX_I2C_INFO_STRUCT_PTR   io_info_ptr;

   i2c_ptr = _bsp_get_i2c_base_address (io_init_ptr->CHANNEL);
   if (NULL == i2c_ptr)
   {
        return I2C_ERROR_CHANNEL_INVALID;
   }
  
   io_info_ptr = (VMCF52XX_I2C_INFO_STRUCT_PTR)_mem_alloc_system_zero ((uint_32)sizeof (MCF52XX_I2C_INFO_STRUCT));
   if (NULL == io_info_ptr) 
   {
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type ((pointer)io_info_ptr, MEM_TYPE_IO_I2C_INFO_STRUCT);

   /* I2C board specific initialization */
   _bsp_i2c_io_init (io_init_ptr->CHANNEL);

   *io_info_ptr_ptr                              = (pointer)io_info_ptr;
   io_info_ptr->INIT                             = *io_init_ptr;
   io_info_ptr->I2C_PTR                          = i2c_ptr;
   io_info_ptr->OLD_ISR                          = NULL;
   io_info_ptr->OLD_ISR_DATA                     = NULL;
   io_info_ptr->VECTOR                           = 0;
   io_info_ptr->MODE                             = io_init_ptr->MODE;
   io_info_ptr->STATE                            = I2C_STATE_READY;
   io_info_ptr->ADDRESSEE                        = 0;
   io_info_ptr->OPERATION                        = 0;
   io_info_ptr->RX_REQUEST                       = 0;
   io_info_ptr->RX_BUFFER                        = NULL;
   io_info_ptr->RX_IN                            = 0;
   io_info_ptr->RX_OUT                           = 0;
   io_info_ptr->TX_BUFFER                        = NULL;
   io_info_ptr->TX_IN                            = 0;
   io_info_ptr->TX_OUT                           = 0;
   io_info_ptr->STATISTICS.INTERRUPTS            = 0;
   io_info_ptr->STATISTICS.RX_PACKETS            = 0;
   io_info_ptr->STATISTICS.TX_PACKETS            = 0;
   io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS  = 0;
   io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE = 0;
   io_info_ptr->STATISTICS.TX_NAKS               = 0;

   /* Disable and clear I2C before initializing it */
   i2c_ptr->I2CR = 0x00;
  
   /* Clear out all I2C events */
   i2c_ptr->I2SR = 0x00;

   /* Set the station address for SLAVE receive operations */      
   i2c_ptr->I2ADR = io_init_ptr->STATION_ADDRESS << 1;
   
   /* Set the frequency divider for the nearest found baud rate */
   io_info_ptr->BAUD_INDEX = _mcf52xx_i2c_find_baud_index (io_init_ptr->BAUD_RATE);
   i2c_ptr->I2FDR = _i2c_baudrate_tbl[io_info_ptr->BAUD_INDEX].IC;
   
   /* Enable I2C */
   i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_IEN;

   return I2C_OK;
   
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_polled_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an I2C device.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_polled_deinit
   (
      /* [IN] the initialization information for the device being opened */
      IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] the address of the device specific information */
      VMCF52XX_I2C_INFO_STRUCT_PTR    io_info_ptr
   )
{ /* Body */
   VMCF52XX_I2C_STRUCT_PTR            i2c_ptr;

   if ((NULL == io_info_ptr) || (NULL == pol_io_dev_ptr)) 
   {
      return I2C_ERROR_INVALID_PARAMETER;
   }
      
   i2c_ptr = io_info_ptr->I2C_PTR;
   if (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IBB) 
   {
      return I2C_ERROR_DEVICE_BUSY;
   }
   
   /* Disable the I2C */
   i2c_ptr->I2CR = 0x00;

   /* Clear the I2C events */
   i2c_ptr->I2SR = 0x00; 
 
   /* Free info struct */
   _mem_free (pol_io_dev_ptr->DEV_INFO_PTR);
   pol_io_dev_ptr->DEV_INFO_PTR = NULL;

   return MQX_OK;

} /* Endbody */

 
/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_polled_ioctl
* Returned Value   : MQX error code.
* Comments         : 
*    This function performs miscellaneous services for
*    the I2C I/O device.  
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_polled_ioctl
   (
      /* [IN] the address of the device specific information */
      VMCF52XX_I2C_INFO_STRUCT_PTR io_info_ptr,

      /* [IN] The command to perform */
      uint_32                      cmd,

      /* [IN] Parameters for the command */
      uint_32_ptr                  param_ptr
   )
{ /* Body */
   VMCF52XX_I2C_STRUCT_PTR         i2c_ptr;
   uint_32                         result = MQX_OK;
   volatile uint_8                 tmp;
  
   i2c_ptr = io_info_ptr->I2C_PTR;
   
   switch (cmd) 
   {
      case IO_IOCTL_FLUSH_OUTPUT:
         do 
         {
            for (tmp = 0; tmp < 0xFF; tmp++) 
               { };
            tmp = i2c_ptr->I2SR;
         } while ((i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MTX) && ((MCF52XX_I2C_I2SR_IBB == (tmp & (MCF52XX_I2C_I2SR_ICF | MCF52XX_I2C_I2SR_IBB))) || (io_info_ptr->TX_IN != io_info_ptr->TX_OUT)));
         io_info_ptr->TX_IN = io_info_ptr->TX_OUT;
         if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (tmp & MCF52XX_I2C_I2SR_IBB)))
         {
             io_info_ptr->OPERATION = 0;
             io_info_ptr->RX_REQUEST = 0;
             io_info_ptr->STATE = I2C_STATE_FINISHED;
         }
         if (NULL != param_ptr) 
         {
            *param_ptr = tmp & MCF52XX_I2C_I2SR_RXAK;
         }
         break;
      case IO_IOCTL_I2C_REPEATED_START:
         result = I2C_ERROR_DEVICE_BUSY;
         if (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MSTA)
         {
            if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) && (io_info_ptr->TX_IN == io_info_ptr->TX_OUT))
               || ((I2C_STATE_RECEIVE == io_info_ptr->STATE) && (0 == io_info_ptr->RX_REQUEST))
               || (I2C_STATE_FINISHED == io_info_ptr->STATE))
            {
               io_info_ptr->STATE = I2C_STATE_REPEATED_START;
               result = MQX_OK;
            }
         }
         break;
      case IO_IOCTL_I2C_STOP:
         i2c_ptr->I2CR &= (~ (MCF52XX_I2C_I2CR_MTX | MCF52XX_I2C_I2CR_TXAK));
         i2c_ptr->I2SR &= (~ (MCF52XX_I2C_I2SR_IAL | MCF52XX_I2C_I2SR_IIF));
         io_info_ptr->RX_REQUEST = 0;
         io_info_ptr->OPERATION = 0;
         io_info_ptr->STATE = I2C_STATE_READY;
         io_info_ptr->RX_OUT = io_info_ptr->RX_IN;

         if (! (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MSTA))
         {
            /* As slave, release the bus */
            tmp = i2c_ptr->I2DR;
         }
         else
         {
            /* As master, send STOP condition */ 
            i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_MSTA);
         }
         for (tmp = 0; tmp < 0xFF; tmp++) 
            { };

         /* Wait for bus idle */
         tmp = i2c_ptr->I2SR;
         while (tmp & MCF52XX_I2C_I2SR_IBB)
         { 
            if (tmp & MCF52XX_I2C_I2SR_IIF)
            {
               i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
               tmp = (uint_8)i2c_ptr->I2DR;
            }
            tmp = i2c_ptr->I2SR;
         }
         break;
      case IO_IOCTL_I2C_SET_RX_REQUEST:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            io_info_ptr->RX_REQUEST = *param_ptr;
         }
         break;
      case IO_IOCTL_I2C_DISABLE_DEVICE:
         i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_IEN);
         break;
      case IO_IOCTL_I2C_ENABLE_DEVICE:
         i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_IEN;
         break;
      case IO_IOCTL_I2C_SET_MASTER_MODE:
         if (I2C_STATE_READY != io_info_ptr->STATE) 
         {
            result = I2C_ERROR_DEVICE_BUSY;
         } 
         else 
         {
            io_info_ptr->MODE = I2C_MODE_MASTER;
         }
         break;
      case IO_IOCTL_I2C_SET_SLAVE_MODE:
         if (I2C_STATE_READY != io_info_ptr->STATE) 
         {
            result = I2C_ERROR_DEVICE_BUSY;
         } 
         else 
         {
            io_info_ptr->MODE = I2C_MODE_SLAVE;
         }
         break;
      case IO_IOCTL_I2C_GET_MODE:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = io_info_ptr->MODE;
         }
         break;
      case IO_IOCTL_I2C_SET_BAUD:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else if (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IBB) 
         {
            result = I2C_ERROR_DEVICE_BUSY;
         } 
         else 
         {
            io_info_ptr->BAUD_INDEX = _mcf52xx_i2c_find_baud_index (*param_ptr);
            i2c_ptr->I2FDR = _i2c_baudrate_tbl[io_info_ptr->BAUD_INDEX].IC;
         }
         break;
      case IO_IOCTL_I2C_GET_BAUD:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = _i2c_baudrate_tbl[io_info_ptr->BAUD_INDEX].BAUD_RATE;
         }
         break;
      case IO_IOCTL_I2C_SET_DESTINATION_ADDRESS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            io_info_ptr->ADDRESSEE = *param_ptr;
         }
         break;
      case IO_IOCTL_I2C_GET_DESTINATION_ADDRESS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = io_info_ptr->ADDRESSEE;
         }
         break;
      case IO_IOCTL_I2C_SET_STATION_ADDRESS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            i2c_ptr->I2ADR = (*param_ptr) << 1;
         }
         break;
      case IO_IOCTL_I2C_GET_STATION_ADDRESS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = i2c_ptr->I2ADR >> 1;
         }
         break;
      case IO_IOCTL_I2C_GET_STATE:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *param_ptr = io_info_ptr->STATE;
         }
         break;
      case IO_IOCTL_I2C_GET_STATISTICS:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            *((I2C_STATISTICS_STRUCT_PTR)param_ptr) = io_info_ptr->STATISTICS;
         }
         break;         
      case IO_IOCTL_I2C_CLEAR_STATISTICS:
         io_info_ptr->STATISTICS.INTERRUPTS = 0;
         io_info_ptr->STATISTICS.RX_PACKETS = 0;
         io_info_ptr->STATISTICS.TX_PACKETS = 0;
         io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS = 0;
         io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE = 0;
         io_info_ptr->STATISTICS.TX_NAKS = 0;
         break;
      case IO_IOCTL_I2C_GET_BUS_AVAILABILITY:
         if (NULL == param_ptr) 
         {
            result = I2C_ERROR_INVALID_PARAMETER;
         } 
         else 
         {
            if (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IBB) 
            {
                *param_ptr = I2C_BUS_BUSY;
            } 
            else 
            {
                *param_ptr = I2C_BUS_IDLE;
            }
         }
         break;
      default:
         break;
   }
   return result;
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_polled_rx
* Returned Value   : number of bytes read
* Comments         : 
*   Returns the number of bytes received.
*   Reads the data into provided array when data is available.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_polled_rx
   (
      /* [IN] the address of the device specific information */
      IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] The array to copy data into */
      uchar_ptr                       buffer,
      
      /* [IN] number of bytes to read */
      uint_32                         length
   )
{ /* Body */
   VMCF52XX_I2C_INFO_STRUCT_PTR       io_info_ptr;
   VMCF52XX_I2C_STRUCT_PTR            i2c_ptr;   
   uint_8                             tmp;
         
   io_info_ptr = pol_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;

   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION |= I2C_OPERATION_READ;
   tmp = io_info_ptr->STATE;
   if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
   {
      io_info_ptr->STATE = I2C_STATE_RECEIVE;
      if (I2C_MODE_MASTER == io_info_ptr->MODE)
      {
         i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MTX;
         i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
         if (I2C_STATE_REPEATED_START == tmp)
         {
            i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_RSTA;
         }
         else
         {
            i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MSTA;
         }
         io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
         i2c_ptr->I2DR = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_READ;
         io_info_ptr->STATISTICS.TX_PACKETS++;
         while (0 == (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IIF)) 
            { };   /* wait for address transferred */
      }
   }

   return _mcf52xx_i2c_polled_rx_tx (i2c_ptr, io_info_ptr, buffer, length);
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_polled_tx
* Returned Value   : number of bytes transmitted
* Comments         : 
*   Writes the provided data buffer and loops until transmission complete.
*
*END*********************************************************************/

uint_32 _mcf52xx_i2c_polled_tx
   (
      /* [IN] the address of the device specific information */
      IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

      /* [IN] The array characters are to be read from */
      uchar_ptr                       buffer,
      
      /* [IN] number of bytes to output */
      uint_32                         length
   )
{ /* Body */
   VMCF52XX_I2C_INFO_STRUCT_PTR       io_info_ptr;
   VMCF52XX_I2C_STRUCT_PTR            i2c_ptr;   
   uint_8                             tmp;
   
   io_info_ptr  = pol_io_dev_ptr->DEV_INFO_PTR;
   i2c_ptr = io_info_ptr->I2C_PTR;

   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION &= (~ I2C_OPERATION_READ);
   tmp = io_info_ptr->STATE;
   if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
   {
      io_info_ptr->STATE = I2C_STATE_TRANSMIT;
      if (I2C_MODE_MASTER == io_info_ptr->MODE)
      {
         i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MTX;
         i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
         if (I2C_STATE_REPEATED_START == tmp)
         {
            i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_RSTA;
         }
         else
         {
            i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MSTA;
         }
         io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
         i2c_ptr->I2DR = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_WRITE;
         io_info_ptr->STATISTICS.TX_PACKETS++;
         while (0 == (i2c_ptr->I2SR & MCF52XX_I2C_I2SR_IIF))
            { };   /* wait for address transferred */
      }
   }

   return _mcf52xx_i2c_polled_rx_tx (i2c_ptr, io_info_ptr, buffer, length);
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_i2c_polled_rx_tx
* Returned Value   : number of bytes processed
* Comments         : 
*   Actual data transfer on I2C bus.
*
*END*********************************************************************/

static uint_32 _mcf52xx_i2c_polled_rx_tx
   (
      /* [IN] I2C register structure */
      VMCF52XX_I2C_STRUCT_PTR      i2c_ptr,

      /* [IN] I2C state structure */
      VMCF52XX_I2C_INFO_STRUCT_PTR io_info_ptr,
      
      /* [IN] The buffer for IO operation */
      uchar_ptr                    buffer,
      
      /* [IN] Number of bytes in buffer */
      uint_32                      length
   )
{ /* Body */
   uint_32                         i;
   uint_8                          i2csr;
   volatile uint_8                 tmp;

   for (i = 0; i <= length; i++)
   {
      do 
      {
         i2csr = i2c_ptr->I2SR;
         if (0 == (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MSTA))
         {
            if (i == length)
            {
               return i;
            }
            if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2csr & MCF52XX_I2C_I2SR_IBB)))
            {
               io_info_ptr->OPERATION = 0;
               io_info_ptr->RX_REQUEST = 0;
               io_info_ptr->STATE = I2C_STATE_FINISHED;
               return i;
            }
         }
      } while (0 == (i2csr & MCF52XX_I2C_I2SR_IIF));

      io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
   
      /* Master */
      if (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MSTA)
      {
         /* Transmit */
         if (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MTX)
         {
            /* Not ack */
            if (i2csr & MCF52XX_I2C_I2SR_RXAK)
            {
               i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
               io_info_ptr->STATE = I2C_STATE_FINISHED;
               io_info_ptr->STATISTICS.TX_NAKS++;
               length = i;
            }
            /* Ack */
            else
            {
               /* Transmit requested */
               if (I2C_STATE_TRANSMIT == io_info_ptr->STATE)
               {
                  if (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ))
                  {
                     /* Anything to transmit? */
                     if (i < length)
                     {
                        i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                        i2c_ptr->I2DR = *buffer++;   /* transmit data */
                        io_info_ptr->STATISTICS.TX_PACKETS++;
                     }
                  }
                  else
                  {
                     length = i;
                  }
               }
               /* Receive requested */
               else if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
               {
                  if (0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ))
                  {
                     i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_MTX);
                     if (1 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_TXAK;
                     }
                     else
                     {
                        i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_TXAK);
                     }
                     i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                     if (0 == io_info_ptr->RX_REQUEST)
                     {
                        io_info_ptr->STATE = I2C_STATE_FINISHED;
                        length = i;
                     }
                     else
                     {
                        tmp = i2c_ptr->I2DR;   /* dummy read to clock in 1st byte */
                        i--;
                     }
                  }
                  else
                  {
                     length = i;
                  }
               }
               /* Others are unwanted/not handled states */
               else
               {
                  length = i;
               }
            }
         }
         /* Receive */
         else
         {
            /* Receive requested */
            if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
            {
               if ((0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (0 != io_info_ptr->RX_REQUEST))
               {
                  if (i < length)
                  {
                     i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                     io_info_ptr->RX_REQUEST--;
                     if (1 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_TXAK;
                     }
                     else
                     {
                        i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_TXAK);
                     }
                     if (0 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MTX;  /* no more reading */
                     }
                     *buffer++ = i2c_ptr->I2DR;   /* receive data */
                     if (0 == io_info_ptr->RX_REQUEST)
                     {
                        i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_MTX);
                        io_info_ptr->STATE = I2C_STATE_FINISHED;
                        length = i + 1;
                        i = length;
                     }
                     io_info_ptr->STATISTICS.RX_PACKETS++;
                  }
               }
               else
               {
                  length = i;
               }
            }
            /* Others are unwanted/not handled states */
            else 
            {
               length = i;
            }
         }
      }
      /* Slave */
      else
      {
         /* Master arbitration lost */
         if (i2csr & MCF52XX_I2C_I2SR_IAL)
         {
            i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IAL);
            io_info_ptr->STATE = I2C_STATE_LOST_ARBITRATION;
            io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS++;
            length = i;
         }
         /* Addressed as slave */
         if (i2csr & MCF52XX_I2C_I2SR_IAAS)
         {
            if (I2C_MODE_MASTER == io_info_ptr->MODE)
            {
               io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE++;
            }
            /* Transmit requested */
            if (i2csr & MCF52XX_I2C_I2SR_SRW)
            {  
               io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_TX;
               if (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ))
               {
                  if (i < length)
                  {
                     i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_MTX;
                     i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                     i2c_ptr->I2DR = *buffer++;   /* transmit data */
                     io_info_ptr->STATISTICS.TX_PACKETS++;
                  }
               }
               else
               {
                  length = i;
               }
            }
            /* Receive requested */
            else
            {
               io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_RX;
               if ((0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (i == 0) && (0 != io_info_ptr->RX_REQUEST))
               {
                  i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_MTX);
                  i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                  if (1 == io_info_ptr->RX_REQUEST)
                  {
                     i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_TXAK;
                  }
                  else
                  {
                     i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_TXAK);
                  }
                  tmp = i2c_ptr->I2DR;   /* dummy read to release bus */
                  i--;
               }
               else
               {
                  length = i;
               }
            }
         }
         /* Normal slave operation */
         else
         {
            /* No master arbitration lost */
            if (! (i2csr & MCF52XX_I2C_I2SR_IAL))
            {
               /* Transmit */
               if (i2c_ptr->I2CR & MCF52XX_I2C_I2CR_MTX)
               {
                  /* Not ack */
                  if (i2csr & MCF52XX_I2C_I2SR_RXAK)
                  {
                     i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                     io_info_ptr->STATE = I2C_STATE_FINISHED;
                     io_info_ptr->STATISTICS.TX_NAKS++;
                     length = i;
                  }
                  /* Ack */
                  else
                  {
                     /* Transmit requested */
                     if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_TX == io_info_ptr->STATE))
                        && (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ)))
                     {
                        if (i < length)
                        {
                           i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                           i2c_ptr->I2DR = *buffer++;   /* transmit data */
                           io_info_ptr->STATISTICS.TX_PACKETS++;
                        }
                     }
                     else
                     {
                        length = i;
                     }
                  }
               }
               /* Receive */
               else
               {
                  /* Receive requested */
                  if (((I2C_STATE_RECEIVE == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_RX == io_info_ptr->STATE))
                     && (0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (0 != io_info_ptr->RX_REQUEST))
                  {
                     if (i < length)
                     {
                        i2c_ptr->I2SR &= (~ MCF52XX_I2C_I2SR_IIF);
                        io_info_ptr->RX_REQUEST--;
                        if (1 == io_info_ptr->RX_REQUEST)
                        {
                           i2c_ptr->I2CR |= MCF52XX_I2C_I2CR_TXAK;
                        }
                        else
                        {
                           i2c_ptr->I2CR &= (~ MCF52XX_I2C_I2CR_TXAK);
                        }
                        if (0 == io_info_ptr->RX_REQUEST)
                        {
                           io_info_ptr->STATE = I2C_STATE_FINISHED;
                        }
                        *buffer++ = i2c_ptr->I2DR;   /* receive data */
                        io_info_ptr->STATISTICS.RX_PACKETS++;
                     }
                  }
                  else
                  {
                     length = i;
                  }
               }
            }
            else
            {
               length = i;
            }
         }
      }
   }
   return length;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/tcp_buf.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcp_buf.c$
* $Version : 3.8.10.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   Buffer management routines for the TCP layer.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"      /* for TCP definitions */
#include "tcp_prv.h"    /* for TCP internal definitions */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Copy_to_ring
* Returned Values : error status
* Comments        :
*
*  General purpose routine to copy a block of memory
*   (`data',`size') to a circular block of memory (`ring',`rsize')
*   starting at offset `ringofs' from beginning of ring (may be negative
*   downto -rsize).
*
*  Note: it is up to the calling function to update the ring buffer
*        data length, and to ensure that enough space exists in the ring.
*
*END*-----------------------------------------------------------------*/

uint_32 TCP_Copy_to_ring
   (
            uchar _PTR_ data,    /* IN - source data buffer */
            uint_32     size,    /* IN - size of data */
   register int_32      ringofs, /* IN - where in ring to put data */
            uchar _PTR_ ring,    /* IN - start of ring buffer */
            uint_32     rsize    /* IN - total size of ring buffer */
   )
{ /* Body */
   register uint_32 atend;   /* nb of bytes available at end of ring */

   if ( rsize == 0 ) {
      RTCS_log_error(ERROR_TCP, RTCSERR_TCP_CTR_ZERO_RSIZE, 0, 0, 0);
      return RTCS_OK;
   } /* Endif */

   /*
   ** Bring `ringofs' within ring
   */
   while ( ringofs < 0 ) {
      ringofs += rsize;
   } /* Endwhile */

   while ( ringofs >= rsize ) {
      ringofs -= rsize;
   } /* Endwhile */

   atend = rsize - ringofs;

   /*
   ** Copy the data.  If the data will over-run the end of
   ** the ring, copy in two parts.
   */
   if ( size > atend ) {
      _mem_copy(data, ring + ringofs, atend);
      _mem_copy(data + atend, ring, size - atend);
   } else {
      _mem_copy(data, ring + ringofs, size);
   } /* Endif */

   return RTCS_OK;

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Copy_from_ring
* Returned Values : error status
* Comments        :
*
*  Complement of TCP_Copy_to_ring();
*
*  Copies `size' bytes of data starting at offset `ringofs' of circular
*   buffer `ring' of size `rsize', into `data'.  Note that the ring buffer
*   must be on-board.
*
*END*-----------------------------------------------------------------*/

uint_32 TCP_Copy_from_ring
   (
            uchar _PTR_ data,    /* IN - destination buffer */
            uint_32     size,    /* IN - size of data at ringofs */
   register int_32      ringofs, /* IN - offset within ring buffer */
            uchar _PTR_ ring,    /* IN - source ring buffer */
            uint_32     rsize    /* IN - ring buffer total size */
   )
{ /* Body */
   register uint_32 atend;   /* nb of bytes available at end of ring */

   if ( rsize == 0 ) {
      RTCS_log_error(ERROR_TCP, RTCSERR_TCP_CTR_ZERO_RSIZE, 1, 0, 0);
      return RTCS_OK;
   } /* Endif */

   /*
   ** Bring `ringofs' within ring
   */
   while ( ringofs < 0 ) {
      ringofs += rsize;
   } /* Endwhile */

   while ( ringofs >= rsize ) {
      ringofs -= rsize;
   } /* Endwhile */

   atend = rsize - ringofs;
   if ( size > atend ) {
      _mem_copy(ring + ringofs, data, atend);
      _mem_copy(ring, data + atend, size - atend);
   } else {
      _mem_copy(ring + ringofs, data, size);
   } /* Endif */

   return RTCS_OK;

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Copy_from_buffer
* Returned Values : error status
* Comments        :
*
*  Copies `size' bytes, to `data', starting at `offset' bytes from the
*  start of the transmit buffer of the given TCB.
*
*  If the transmit buffer is too short, only the available bytes are
*  copied.
*
*  Note: This function is only called within TCP_Send_packet().  Thus,
*  pcb_ptr is always allocated with RTCSPCB_alloc_send().
*
*END*-----------------------------------------------------------------*/

uint_32 TCP_Copy_from_buffer
   (
      TCB_STRUCT_PTR tcb,     /* IN - TCP context */
      uchar_ptr      data,    /* IN - destination buffer */
      uint_32_ptr    size_ptr,/* IN/OUT - number of bytes to copy */
      uint_32        offset,  /* IN - offset from start of transmit buffer */
      RTCSPCB_PTR    pcb_ptr  /* IN - PCB used to send the packet */
   )
{ /* Body */
   SbufNode _PTR_ buf = tcb->sndbuf;
   uint_32        ring_tail;
   int_32         ring_offs;
   uint_32        size = *size_ptr;

   /*
   ** Skip untouched buffer nodes
   */
   while ( buf != NULL && offset >= buf->size ) {
      offset -= buf->size;
      buf = buf->next;
   } /* Endwhile */

   if ( buf != NULL && size != 0 ) {

      if (size > buf->size - offset) size = buf->size - offset;

      if ( buf->use_cbuf ) {

         /*
         ** User buffer is in the SbufNode.  Use a second fragment
         ** to point to it.
         */
         RTCSPCB_append_fragment(pcb_ptr, size, buf->data + offset);

      } else {

         /*
         ** User buffer is in the send window.  Use one or two fragments
         ** to point to the ring (we need two fragments if the data
         ** wraps at the end of the ring).
         */
         ring_offs = (int_32)buf->data + offset;
         while (ring_offs <  0)               ring_offs += tcb->sndringlen;
         while (ring_offs >= tcb->sndringlen) ring_offs -= tcb->sndringlen;
         ring_tail = tcb->sndringlen - ring_offs;
         if (size > ring_tail) {
            RTCSPCB_append_fragment(pcb_ptr, ring_tail, tcb->sndringbuf + ring_offs);
            RTCSPCB_append_fragment(pcb_ptr, size - ring_tail, tcb->sndringbuf);
         } else {
            RTCSPCB_append_fragment(pcb_ptr, size , tcb->sndringbuf + ring_offs);
         } /* Endif */

      } /* Endif */

   } /* Endif */

   *size_ptr = size;
   return RTCS_OK;

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Copy_to_Rbuffer
* Returned Values : error status
* Comments        :
*
*  Copies `data' to `section' of the circular receive buffer (only where not
*   already filled); `section' is an offset from the start of the receive
*   buffer's current position (i.e., rcvbuf+rcvpos), and may wrap around the
*   buffer.
*
*  Assumes specified `size' bytes are properly contained within the
*   receive buffer.
*
*END*-----------------------------------------------------------------*/

uint_32 TCP_Copy_to_Rbuffer
   (
      TCB_STRUCT_PTR       tcb,        /* IN/OUT - TCP context */
      uint_32              section,    /* IN     - destination offset from
                                                    rcvpos in rcvbuf */
      uchar _PTR_          data,       /* IN     - source data */
      uint_32              size,       /* IN     - size of data */
      uchar _PTR_          rcvbuf,     /* IN     - receive buffer */
      uint_32              rcvbufsize, /* IN     - total size of rcv buffer */
      uint_32              rcvpos,     /* IN     - current position in rcvbuf */
      TCP_CFG_STRUCT_PTR   tcp_cfg     /* IN/OUT - TCP layer data */
   )
{ /* Body */
   Rchunk   _PTR_ h;
   Rchunk   _PTR_ last;
   Rchunk   _PTR_ nxt;
   uint_32  status;
   uint_32  mid_status;

   if ( size == 0 ) {
      return RTCS_OK;
   } /* Endif */

   /*
   ** Skip preceding chunk nodes
   */
   for ( last = NULL, h = tcb->rcvchunks;
       h != NULL && (h->used + h->size) < section;
       last = h, h = h->next)
   {
   } /* Endfor */

   /*
   ** See whether the current chunk node merges with the added section
   */
   if ( h != NULL && h->used <= section ) {  /* extend previous chunk */

      /*
      ** Merge, back-extend section to chunk node
      */
      size    += section - h->used;
      data    -= section - h->used;
      section = h->used;

      if ( h->size >= size ) {

         /*
         ** Have already copied these seq #'s to buf
         */
         return RTCS_OK;

      } /* Endif */

      status = RTCS_OK;

   } else if ( h != NULL && h->used <= section + size ) {

      /*
      ** Some duplicate data so extend next chunk backwards
      */
      status = TCP_Copy_to_ring( data,          /* source */
                           h->used - section,   /* size */
                           rcvpos + section,    /* offset */
                           rcvbuf,
                           rcvbufsize );

      /*
      ** Merge, back-extend chunk node to section
      */
      h->size += h->used - section;
      h->used = section;

   } else {

      /*
      ** Nothing merges with added section, create a new chunk node
      */
      status = TCP_Copy_to_ring( data,          /* source */
                           size,                /* size */
                           rcvpos + section,    /* offset */
                           rcvbuf,
                           rcvbufsize );

      if ( tcp_cfg->Rchunkfree != NULL ) {
         h = tcp_cfg->Rchunkfree;
         tcp_cfg->Rchunkfree = h->next;
      } else {
         h = (Rchunk _PTR_)RTCS_mem_alloc(sizeof(Rchunk));
         if (h == NULL)  {
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_MISSED++);
            RTCS_log_error( ERROR_TCP, RTCSERR_TCP_PR_OUT_OF_MEM, (uint_32)tcb, 0, 0 );
            return (uint_32) RTCS_ERROR;
         }
         _mem_set_type(h, MEM_TYPE_Rchunk);
         
      } /* Endif */

      h->size = size;
      h->used = section;

      if ( last != NULL ) {
         h->next = last->next;
         last->next = h;
      } else {
         h->next = tcb->rcvchunks;
         tcb->rcvchunks = h;
      } /* Endif */

      return status;

   } /* Endif */

   /*
   ** A chunk node, `h', was merged with the added section of data;
   **   this node now coincides with the beginning of the added `section';
   **   more nodes may merge, merge them now:
   */
   nxt = h->next;
   while ( nxt != NULL && nxt->used <= h->used+size ) {

      /*
      ** Merge node - copy gap between end of current RcvChunk
      **    and start of next.
      ** don't allow further copies if an error occurred,
      **    but keep ring in sync.
      */
      if ( status == RTCS_OK ) {
         status = TCP_Copy_to_ring( data + h->size,            /* source */
                              nxt->used - h->used - h->size,   /* size */
                              rcvpos + section + h->size,      /* offset */
                              rcvbuf,
                              rcvbufsize );
      } /* Endif */

      h->size = nxt->used - h->used + nxt->size;
      h->next = nxt->next;

      mid_status = _mem_free(nxt);
      if ( mid_status != MQX_OK ) {
         RTCS_log_error( ERROR_TCP, RTCSERR_TCP_DEALLOC_FAILED,
                              mid_status, (uint_32)nxt, 0 );
      } /* Endif */

      nxt = h->next;

   } /* Endwhile */

   /*
   ** Copy any remainder:
   */
   if ( h->size < size ) {

      if ( status == RTCS_OK ) {
         status = TCP_Copy_to_ring( data + h->size,
                              size - h->size,
                              rcvpos + section + h->size,
                              rcvbuf,
                              rcvbufsize );
      } /* Endif */

      h->size = size;

   } /* Endif */

   return status;

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Use_ringbuffer
* Returned Values : error status
* Comments        :
*
*  Switch from using user's buffer (because it was larger than ring buffer)
*   to using the ring buffer (since it has now more free space?); any
*   out-of-order (non-contiguous) data is copied from user buffer to ring
*   buffer; if there is too much to fit in the ring buffer, it is truncated
*   (this shouldn't normally happen, except when definitively closing a
*    connection (via TCP_Close_TCB())).
*
*  Note that this routine assumes that all contiguous data in the
*     user buffer is captured in the first receive chunk.
*
*END*-----------------------------------------------------------------*/

uint_32  TCP_Use_ringbuffer
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   Rchunk   _PTR_ chunk;
   Rchunk   _PTR_ nextchunk;
   int_32   n;                /* nb of bytes which remain in user buf */

   if ( tcb->rcvbuf != tcb->rcvuserbuf ) {
      return RTCS_OK;
   } /* Endif */

   tcb->rcvbuf = tcb->rcvringbuf;
   tcb->rcvlen = tcb->rcvringlen;
   tcb->rcvpos = 0;  /* ring buffer empty */

   chunk = tcb->rcvchunks;
   if ( chunk != NULL && chunk->used == 0 ) {

      n = chunk->size;

      /*
      ** Remove leading chunk, whose data will remain in user buffer only
      */
      tcb->rcvchunks = chunk->next;
      _mem_free(chunk);
      chunk = tcb->rcvchunks;

   } else {
      n = 0;
   } /* Endif */

   tcb->rcvusernxt = n;
   tcb->rcvbufseq += n;

   /*
   ** Copy all chunks that fit in the receive ring buffer
   */
   while ( chunk != NULL ) {

      chunk->used -= n;
      if ( chunk->used < tcb->rcvlen ) {

         if ( chunk->size > tcb->rcvlen - chunk->used ) {   /* Truncate */
            /*
            ** Throwing away received data!
            */
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_DISCARDED++);
            chunk->size = tcb->rcvlen - chunk->used;

         } /* Endif */

            _mem_copy(tcb->rcvuserbuf + n + chunk->used,
                      tcb->rcvringbuf + chunk->used, chunk->size);

      } else {

         /*
         ** Throwing away received data!
         */
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_DISCARDED++);
         break;   /* remaining chunks are extraneous... */

      } /* Endif */

      chunk = chunk->next;

   } /* Endwhile */

   /*
   ** Delete extraneous chunks
   */
   while ( chunk != NULL ) {

      nextchunk = chunk->next;
      if ( chunk == tcb->rcvchunks ) {
         tcb->rcvchunks = nextchunk;
      } /* Endif */

      _mem_free(chunk);
      chunk = nextchunk;

   } /* Endwhile */

   /*
   ** We now have all of the ring buffer space available (but we
   **    may have some out-of-order data in it).
   */
   TCP_Advertise_receive_window(tcb, tcp_cfg);

   return RTCS_OK;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/gen16.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: gen16.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file generates the lookup table for the CCITT-16
*   FCS.
*
*END************************************************************************/
#include <stdio.h>
#define SIZE 256
#define POLY 0x8408

#if RCTSCFG_GENERATE_HASH_TABLES && RTCSCFG_ENABLE_IP4
/* Start CR 1679 */
int RTCS_PPP_SUPPORT_gen16 (void)
/* End CR 1679 */
{ /* Body */
   int count = 0, i;
   register int carry;
   unsigned short crc;

   printf("/*\n** The CCITT-16 Lookup Table\n*/\n\n"
          "static uint_16 fcstab[] = {");

   for (;;) {
      if (!(count%8)) printf("\n  ");
      crc = count;
      for (i=8;i--;) {
         carry = crc & 1;
         crc >>= 1;
         if (carry) crc ^= POLY;
      } /* Endfor */
      printf(" 0x%04X", crc);
      if (++count == SIZE) break;
      printf(",");
   } /* Endfor */
   printf("\n};\n");

   return 0;
} /* Endbody */
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/ehci/callback_ehci.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: callback_ehci.c$
* $Version : 3.8.3.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the default callback function for the ehci 
*   and device.
*                                                               
*END*********************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "dev_cnfg.h"
#include "devapi.h"
#include "dev_main.h"
#include "mqx_dev.h"

#include "ehci_dev_main.h"
#include "ehci_usbprv.h"

const USB_DEV_CALLBACK_FUNCTIONS_STRUCT _usb_ehci_dev_callback_table =
{
   _usb_dci_usbhs_preinit,
   _usb_dci_usbhs_init,
   _usb_dci_usbhs_send_data,
   _usb_dci_usbhs_recv_data,
   _usb_dci_usbhs_cancel_transfer,
   _usb_dci_usbhs_init_endpoint,
   _usb_dci_usbhs_deinit_endpoint,
   _usb_dci_usbhs_unstall_endpoint,
   _usb_dci_usbhs_get_endpoint_status,
   _usb_dci_usbhs_set_endpoint_status,
   _usb_dci_usbhs_get_transfer_status,
   _usb_dci_usbhs_set_address,
   _usb_dci_usbhs_shutdown,
   _usb_dci_usbhs_get_setup_data,
   _usb_dci_usbhs_assert_resume,
   _usb_dci_usbhs_stall_endpoint,
};


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/dev_utl.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dev_utl.c$
* $Version : 3.8.4.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
*  This file contains USB device API specific utility functions.
*                                                               
*END*********************************************************************/
#include <mqx.h>

#include "usb.h"     //common public
#include "usb_prv.h" //common private

#include "dev_cnfg.h"
#include "devapi.h"  //device public
#include "dev_main.h" //device private

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_unstall_endpoint
*  Returned Value : USB_OK or error code
*  Comments       :
*     Unstalls the endpoint in specified direction
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_unstall_endpoint
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] direction */
      uint_8                     direction
   )
{ /* Body */
   USB_STATUS                        error = USB_OK;
   volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;
   
   if (handle  == NULL)
   {
      #if _DEBUG
         printf("_usb_device_unstall_endpoint: handle is NULL\n");
      #endif    
      return USBERR_ERROR;
   }
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

   USB_lock();
   

       if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
          usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_UNSTALL_ENDPOINT != NULL)
       {
          error= ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
          usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_UNSTALL_ENDPOINT(handle, ep_num, direction);   
       }
       else
       {
          return USBERR_ERROR;
       }
   USB_unlock();
   return error;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_device_get_status
* Returned Value : USB_OK or error code
* Comments       :
*     Provides API to access the USB internal state.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_device_get_status
   (
      /* [IN] Handle to the USB device */
      _usb_device_handle   handle,
      
      /* [IN] What to get the error of */
      uint_8               component,
      
      /* [OUT] The requested error */
      uint_16_ptr          error
   )
{ /* Body */
    volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;

    if((handle == NULL)||(error == NULL))
    {
        #if _DEBUG
            printf("_usb_device_get_status: NULL pointer\n");
        #endif  
        return USBERR_ERROR;
    }
    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   
    USB_lock();
    switch (component) 
    {
        case USB_STATUS_DEVICE_STATE:
            *error = usb_dev_ptr->USB_STATE;
            break;

        case USB_STATUS_DEVICE:
            *error = usb_dev_ptr->USB_DEVICE_STATE;
            break;
    
        case USB_STATUS_INTERFACE:
            break;
         
        case USB_STATUS_ADDRESS:
            *error = usb_dev_ptr->DEVICE_ADDRESS;
            break;
         
        case USB_STATUS_CURRENT_CONFIG:
            *error = usb_dev_ptr->USB_CURR_CONFIG;
            break;
        
        case USB_STATUS_SOF_COUNT:
            *error = usb_dev_ptr->USB_SOF_COUNT;
            break;
                 
        default:
            if (component & USB_STATUS_ENDPOINT) 
            {
                if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
                   usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_GET_ENDPOINT_STATUS != NULL)
                {
                    ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
                        usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_GET_ENDPOINT_STATUS(handle,
                        (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK),error);
                }
                else
                {
                    #if _DEBUG
                        printf("_usb_device_get_status: DEV_GET_ENDPOINT_STATUS is NULL\n");
                    #endif  
                    USB_unlock();
                    return USBERR_ERROR;
                }             
            } 
            else 
            {
                USB_unlock();
                return USBERR_BAD_STATUS;
            } 
         break;
   } /* Endswitch */
   USB_unlock();
   return USB_OK;   
}   
 
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_device_set_status
* Returned Value : USB_OK or error code
* Comments       :
*     Provides API to set internal state
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_device_set_status
   (
      /* [IN] Handle to the usb device */
      _usb_device_handle   handle,
      
      /* [IN] What to set the error of */
      uint_8               component,
      
      /* [IN] What to set the error to */
      uint_16              setting
   )
{ 
    volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;
    uint_8 error = USB_OK;
    uint_8 ep_num= (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK);
      
    if (handle == NULL)
    {
        #if _DEBUG
            printf("_usb_device_set_status: handle is NULL\n");
        #endif  
        return USBERR_ERROR;
    }
    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
    USB_lock();
    
    switch (component) 
    {
        case USB_STATUS_DEVICE_STATE:
            usb_dev_ptr->USB_STATE = setting;
            break;
        case USB_STATUS_DEVICE:
            usb_dev_ptr->USB_DEVICE_STATE = setting;
            break;
        case USB_STATUS_INTERFACE:
            break;
        case USB_STATUS_CURRENT_CONFIG:
            usb_dev_ptr->USB_CURR_CONFIG = setting;
            break;
        case USB_STATUS_SOF_COUNT:
            usb_dev_ptr->USB_SOF_COUNT = setting;
            break;
        case USB_STATUS_ADDRESS:
            usb_dev_ptr->DEVICE_ADDRESS = (uint_8)setting;      
            if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
                    usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SET_ADDRESS != NULL)
            {
                error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
                    usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SET_ADDRESS(
                    (pointer)usb_dev_ptr, (uint_8)(setting&0x00FF));
            }
            else
            {
                #if _DEBUG
                    printf("_usb_device_set_status: DEV_SET_ADDRESS is NULL\n");                
                #endif  
                error = USBERR_ERROR;
            }           
            break;
        default:
            if (component & USB_STATUS_ENDPOINT)
            {
                if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
                    usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SET_ENDPOINT_STATUS != NULL)
                {
                    error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
                        usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SET_ENDPOINT_STATUS(
                        handle, component, setting);
                }
                else
                {
                    #if _DEBUG
                        printf("_usb_device_set_status: DEV_SET_ENDPOINT_STATUS is NULL\n");                
                    #endif  
                    error = USBERR_ERROR;
                }
            }
            else 
            {
                USB_unlock();
                return USBERR_BAD_STATUS;
            } /* Endif */
        break;
   }/* Endswitch */

   USB_unlock();
   return error;   
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_stall_endpoint
*  Returned Value : USB_OK or error code
*  Comments       :
*     Stalls the endpoint.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_stall_endpoint
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] direction */
      uint_8                     direction
   )
{ /* Body */
   USB_STATUS                             error = 0;
   uint_8 component = (uint_8)(ep_num | (direction<<COMPONENT_PREPARE_SHIFT));
   volatile USB_DEV_STATE_STRUCT_PTR      usb_dev_ptr;
   
   if (handle == NULL)
   {
      #if _DEBUG
        printf("_usb_device_stall_endpoint: handle is NULL\n");
      #endif    
      return USBERR_ERROR;
   }
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
    usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_STALL_ENDPOINT
        != NULL)
    {
        error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
            usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_STALL_ENDPOINT(handle, 
            ep_num, direction);
    }
    else
    {
        #if _DEBUG
            printf("_usb_device_stall_endpoint: DEV_STALL_ENDPOINT is NULL\n");             
        #endif  
        error = USBERR_ERROR;
    }
    
    return  error;
} 

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_process_resume
*  Returned Value : USB_OK or error code
*  Comments       :
*        Process Resume event
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_assert_resume
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle
   )
{ /* Body */
   volatile USB_DEV_STATE_STRUCT_PTR      usb_dev_ptr;
   USB_STATUS                             error = USB_OK;
    
   if (handle == NULL)
   {
      #if _DEBUG
        printf("_usb_device_assert_resume: handle is NULL\n");
      #endif    
      return USBERR_ERROR;
   }
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
    usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_ASSERT_RESUME
        != NULL)
    {
        error= ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
            usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_ASSERT_RESUME(handle);
    }
    else
    {
        #if _DEBUG
            printf("_usb_device_assert_resume: DEV_ASSERT_RESUME is NULL\n");               
        #endif  
        error = USBERR_ERROR;
    }
    
    return error;
} 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb/usb_bsp.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_bsp.h$
* $Version : 3.8.15.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
*   Include this header file to use BSP-specific USB initialization code
*
*END************************************************************************/

#ifndef __usb_bsp_h__
#define __usb_bsp_h__ 1

//#include "../../../../usb/host/source/rtos/mqx/mqx_host.h"

#include "if_host_khci.h"
#include "if_host_ehci.h"
#include "if_dev_khci.h"
#include "if_dev_ehci.h"

/* Forward declaration of structure */
//struct usb_host_callback_functions_struct;

/* NOTE!!!: since both structures below are used in the array of structures for USB component, they must have the same size */
typedef struct usb_host_if_struct
{
   const struct usb_host_callback_functions_struct *HOST_IF;
   pointer                       HOST_INIT_PARAM;
   pointer                       HOST_HANDLE;
} USB_HOST_IF_STRUCT, _PTR_ USB_HOST_IF_STRUCT_PTR;

typedef struct usb_dev_if_struct
{
   const struct usb_dev_callback_functions_struct *DEV_IF;
   pointer                       DEV_INIT_PARAM;
   pointer                       DEV_HANDLE;
} USB_DEV_IF_STRUCT, _PTR_ USB_DEV_IF_STRUCT_PTR;

/* TODO: move to processor USB header files */
extern struct usb_dev_if_struct _bsp_usb_dev_ehci0_if;
extern struct usb_dev_if_struct _bsp_usb_dev_ehci1_if;

extern struct usb_dev_if_struct _bsp_usb_dev_khci0_if;
extern struct usb_dev_if_struct _bsp_usb_dev_khci1_if;

extern struct usb_host_if_struct _bsp_usb_host_ehci0_if;
extern struct usb_host_if_struct _bsp_usb_host_ehci1_if;

extern struct usb_host_if_struct _bsp_usb_host_khci0_if;
extern struct usb_host_if_struct _bsp_usb_host_khci1_if;


extern const USB_KHCI_HOST_INIT_STRUCT _khci0_host_init_param;
extern const USB_KHCI_HOST_INIT_STRUCT _khci1_host_init_param;

extern const USB_EHCI_HOST_INIT_STRUCT _ehci0_host_init_param;
extern const USB_EHCI_HOST_INIT_STRUCT _ehci1_host_init_param;

extern const USB_EHCI_DEV_INIT_STRUCT _ehci0_dev_init_param;
extern const USB_EHCI_DEV_INIT_STRUCT _ehci1_dev_init_param;

extern const USB_KHCI_DEV_INIT_STRUCT _khci0_dev_init_param;
extern const USB_KHCI_DEV_INIT_STRUCT _khci1_dev_init_param;

#ifdef __cplusplus
extern "C" {
#endif

_mqx_int _usb_host_driver_install(struct usb_host_if_struct *);
_mqx_int _usb_device_driver_install(struct usb_dev_if_struct *);
_mqx_int _usb_device_driver_uninstall(void);
_mqx_int _bsp_usb_dev_init(struct usb_dev_if_struct *);
_mqx_int _bsp_usb_host_init(struct usb_host_if_struct *);
pointer _usb_host_get_init(pointer host_handle);


#ifdef __cplusplus
}
#endif

#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb/usb_mk40_device.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_mk40_device.c$
* $Version : 3.8.2.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains board-specific USB initialization functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"

struct usb_dev_if_struct _bsp_usb_dev_khci0_if = {
    &_usb_khci_dev_callback_table,
    (pointer) &_khci0_dev_init_param,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_usb_dev_init
* Returned Value   : 0 for success, -1 for failure
* Comments         :
*    This function performs BSP-specific initialization related to USB
*
*END*----------------------------------------------------------------------*/
_mqx_int _bsp_usb_dev_init(struct usb_dev_if_struct *usb_if)
{
    _mqx_int result = _bsp_usb_io_init(); 
    
    if (result != MQX_OK) return result;
    
    /* Configure enable USB regulator for device */
    SIM_SOPT1_REG(SIM_BASE_PTR) |= SIM_SOPT1_USBREGEN_MASK;    

    /* reset USB CTRL register */
    USB_USBCTRL_REG(USB0_BASE_PTR) = 0;
    
    /* Enable internal pull-up resistor */
    USB_CONTROL_REG(USB0_BASE_PTR) = USB_CONTROL_DPPULLUPNONOTG_MASK;
    USB_USBTRC0_REG(USB0_BASE_PTR) |= 0x40; /* Software must set this bit to 1 */
    
    /* setup interrupt */
    _bsp_int_init(INT_USB0, BSP_USB_INT_LEVEL, 0, TRUE);
    
    return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/ipradix.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipradix.c$
* $Version : 3.8.4.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the IP
*   radix tree.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_IP4 

#include "rtcs_prv.h"
#include "tcpip.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IPRADIX_init
* Returned Value  : void
* Comments  :  Initializes the radix tree
*
*END*-----------------------------------------------------------------*/

void IPRADIX_init
   (
      IPRADIX_NODE_PTR  root
         /* [IN/OUT] the root of the radix tree */
   )
{ /* Body */

   root->IP       = 0x00000000;
   root->MASK     = 0x00000000;
   root->PARENT   = NULL;
   root->CHILD[0] = NULL;
   root->CHILD[1] = NULL;
   root->DATA     = NULL;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IPRADIX_findbest
* Returned Value  : void
* Comments  :  Searches the radix tree for a best IP network match
*
*END*-----------------------------------------------------------------*/

void IPRADIX_findbest
   (
      IPRADIX_NODE_PTR     root,    /* [IN] the root of the radix tree */
      _ip_address          ip,      /* [IN] the IP address to find */
      boolean (_CODE_PTR_  test)(pointer, pointer),
                                    /* [IN] application-specific filter */
      pointer              data     /* [IN] data for test() */
   )
{ /* Body */
   IPRADIX_NODE_PTR  node = root;
   IPRADIX_NODE_PTR  nextnode;
   _ip_address       bit;
   uint_32           child;

   /* First find the best match */
   for (;; node = nextnode) {
      bit = (~node->MASK >> 1) + 1;
      child = (ip & bit) ? 1 : 0;
      nextnode = node->CHILD[child];
      if (!nextnode) break;
      if ((ip & nextnode->MASK) != nextnode->IP) break;
   } /* Endfor */

   /* Now backtrack until we find a node that test() accepts */
   for (; node; node = node->PARENT) {
      if (node->DATA && test(node->DATA, data)) break;
   } /* Endfor */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IPRADIX_insert
* Returned Value  : void
* Comments  :  Searches the radix tree for an exact IP network match,
*              and if not found, creates a new node.
*
*END*-----------------------------------------------------------------*/

void IPRADIX_insert
   (
      IPRADIX_NODE_PTR     root,    /* [IN] the root of the radix tree */
      _ip_address          ip,      /* [IN] the IP address to insert */
      _ip_address          mask,    /* [IN] the IP network mask */
      _rtcs_part           part,    /* [IN] the node partition */
      void (_CODE_PTR_     insert)(pointer _PTR_, pointer),
                                    /* [IN] application-specific insert */
      pointer              data     /* [IN] data for insert() */
   )
{ /* Body */
   IPRADIX_NODE_PTR  node = root;
   IPRADIX_NODE_PTR  nextnode, newnode;
   _ip_address       bit;
   _ip_address       newmask;
   uint_32           child;

   /* First find the best match */
   for (;; node = nextnode) {
      bit = (~node->MASK >> 1) + 1;
      child = (ip & bit) ? 1 : 0;
      nextnode = node->CHILD[child];
      if (!nextnode) break;
      if (mask < nextnode->MASK) break;
      if ((ip & nextnode->MASK) != nextnode->IP) break;
   } /* Endfor */

   if (part) {

      /* The best match has a child that isn't a match.  Insert new node */
      if ((mask > node->MASK) && nextnode) {
         newmask = ~mask | (ip ^ nextnode->IP);
         newmask |= newmask >> 1;
         newmask |= newmask >> 2;
         newmask |= newmask >> 4;
         newmask |= newmask >> 8;
         newmask |= newmask >> 16;
         bit = (newmask >> 1) + 1;
         newmask = ~newmask;
         newnode = RTCS_part_alloc(part);
         if (!newnode) return;
         newnode->IP     = ip & newmask;
         newnode->MASK   = newmask;
         newnode->PARENT = node;
         if (nextnode->IP & bit) {
            newnode->CHILD[0] = NULL;
            newnode->CHILD[1] = nextnode;
         } else {
            newnode->CHILD[0] = nextnode;
            newnode->CHILD[1] = NULL;
         } /* Endif */
         newnode->DATA = NULL;
         node->CHILD[child] = newnode;
         nextnode->PARENT = newnode;
         node = newnode;
         child = (ip & bit) ? 1 : 0;
      } /* Endif */

      /* Now the best match has a NULL child.  Create new leaf */
      if (mask > node->MASK) {
         newnode = RTCS_part_alloc(part);
         if (newnode) {
            newnode->IP       = ip;
            newnode->MASK     = mask;
            newnode->PARENT   = node;
            newnode->CHILD[0] = NULL;
            newnode->CHILD[1] = NULL;
            newnode->DATA     = NULL;
            node->CHILD[child] = newnode;
            node = newnode;
         } /* Endif */
      } /* Endif */

   } /* Endif */

   /* If we have an exact match, call insert() */
   if (mask == node->MASK) {
      insert(&node->DATA, data);
   } /* Endif */

   /* insert() may have deleted DATA, so delete unnecessary node(s) */
   for (; node; node = nextnode) {
      if (node->DATA) break;
      nextnode = node->PARENT;
      if (!nextnode) break;
      if (node->CHILD[0] && node->CHILD[1]) break;
      child = (node == nextnode->CHILD[0]) ? 0 : 1;
      if (node->CHILD[0]) {
         nextnode->CHILD[child] = node->CHILD[0];
         node->CHILD[0]->PARENT = nextnode;
      } else if (node->CHILD[1]) {
         nextnode->CHILD[child] = node->CHILD[1];
         node->CHILD[1]->PARENT = nextnode;
      } else {
         nextnode->CHILD[child] = NULL;
      } /* Endif */
      RTCS_part_free(node);
   } /* Endfor */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IPRADIX_walk
* Returned Value  : void
* Comments  :  Traverses the entire radix tree.
*
*END*-----------------------------------------------------------------*/

void IPRADIX_walk
   (
      IPRADIX_NODE_PTR     root,    /* [IN] the root of the radix tree */
      boolean (_CODE_PTR_  test)(_ip_address, _ip_address, pointer, pointer),
                                    /* [IN] application-specific test */
      pointer              data     /* [IN] data for find() */
   )
{ /* Body */
   IPRADIX_NODE_PTR  node = root, lastnode = NULL;
   uint_32           next;

   for (; node;) {
      if (lastnode == node->PARENT) {
         if (test(node->IP, node->MASK, node->DATA, data)) break;
         if (node->CHILD[0]) {
            next = 0;
         } else if (node->CHILD[1]) {
            next = 1;
         } else {
            next = 2;
         } /* Endif */
      } else if (lastnode == node->CHILD[0]) {
         if (node->CHILD[1]) {
            next = 1;
         } else {
            next = 2;
         } /* Endif */
      } else {
            next = 2;
      } /* Endif */
      lastnode = node;
      switch (next) {
      case 0: node = node->CHILD[0]; break;
      case 1: node = node->CHILD[1]; break;
      case 2: node = node->PARENT;   break;
      } /* Endswitch */
   } /* Endfor */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/chap.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: chap.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation for the
*   Challenge Handshake Authentication Protocol.
*
*END************************************************************************/

#include <string.h>
#include <ppp.h>
#include "ppp_prv.h"


static void CHAP_timeout (pointer, PCB_PTR, boolean);
static void CHAP_up      (_ppp_handle);
static void CHAP_fail    (_ppp_handle);
static void CHAP_close   (pointer, PCB_PTR, boolean);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CHAP_init
* Returned Value  :  void
* Comments        :
*     Called by PPP_initialize.  Initializes the CHAP state.
*
*END*-----------------------------------------------------------------*/

void CHAP_init
   (
      _ppp_handle  handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

   ppp_ptr->CHAP_STATE.CLIENT_STATE = CHAP_STATE_CLOSED;
   ppp_ptr->CHAP_STATE.SERVER_STATE = CHAP_STATE_CLOSED;

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CHAP_timeout
* Returned Value  :  void
* Comments        :
*     Called by PPP_tx_task.  Timeout expired.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void CHAP_timeout
   (
      pointer        chap_data,
            /* [IN/OUT] - CHAP state */
      PCB_PTR        pcb,
            /* [IN] - expired packet */
      boolean        hard
            /* [IN] - TRUE if this is a hard timeout (TO- event) */
   )
{ /* Body */
   CHAP_DATA_PTR  chap_ptr = chap_data;
   uint_16 i;

   /* Increment the identifier */
   chap_ptr->CURID = (chap_ptr->CURID + 1) & 0xFF;
   pcb->FRAG[0].FRAGMENT[3] = chap_ptr->CURID;

   /* Generate a new challenge */
   for (i=0; i<CHAP_CHALLENGE_LEN; i++) {
      pcb->FRAG[0].FRAGMENT[i+7]= chap_ptr->MD5[i] = RTCS_rand() & 0xFF;
   } /* Endfor */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CHAP_open
* Returned Value  :  void
* Comments        :
*     Called by LCP_up.  Starts the CHAP client.
*
*END*-----------------------------------------------------------------*/

void CHAP_open
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

   ppp_ptr->CHAP_STATE.CLIENT_STATE = CHAP_STATE_INITIAL;

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CHAP_challenge
* Returned Value  :  void
* Comments        :
*     Called by LCP_up.  Sends a Challenge packet.
*
*END*-----------------------------------------------------------------*/

void CHAP_challenge
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR    ppp_ptr = handle;
   CHAP_DATA_PTR  chap_ptr = &ppp_ptr->CHAP_STATE;
   PCB_PTR        pcb;
   uchar_ptr      outp;
   uint_16        len;
   uint_16        i, idlen;

   chap_ptr->SERVER_STATE = CHAP_STATE_INITIAL;
   chap_ptr->CURID = RTCS_rand() & 0xFF;

   /* Acquire a message buffer */
   /* Start CR 2207 */
   idlen = strlen(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME));
   /* End CR 2207 */
   len = CHAP_HDR_LEN + 1 + CHAP_CHALLENGE_LEN + idlen;
   pcb = PPP_pcballoc(PPP_PROT_CHAP, len);
   if (pcb == NULL) {
      return;
   } /* Endif */

   /* Build a Challenge packet */
   outp = pcb->FRAG[0].FRAGMENT + 2;
   *outp++ = CHAP_CODE_CHALLENGE;
   *outp++ = chap_ptr->CURID;
   *outp++ = (len >> 8) & 0xFF;
   *outp++ =  len       & 0xFF;
   *outp++ = CHAP_CHALLENGE_LEN;
   for (i=0; i<CHAP_CHALLENGE_LEN; i++) {
      *outp++ = chap_ptr->MD5[i] = RTCS_rand() & 0xFF;
   } /* Endfor */
   /* Start CR 2207 */
   PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME), outp, idlen);
   /* End CR 2207 */
   /* Send the PCB */
   PPP_send_rexmit(ppp_ptr, PPP_PROT_CHAP, pcb, 0, CHAP_timeout, chap_ptr);

#endif /* RTCSCFG_ENABLE_IP4 */
   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CHAP_input
* Returned Value  :  void
* Comments        :
*     Called by PPP_rx_task.  Parses a CHAP packet.
* Side effects    :
*     Consumes (sends or frees) the packet.
*
*END*-----------------------------------------------------------------*/

void CHAP_input
   (
      PCB_PTR        pcb,
            /* [IN] - CHAP packet */
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR    ppp_ptr = handle;
   CHAP_DATA_PTR  chap_ptr = &ppp_ptr->CHAP_STATE;
   PPP_SECRET_PTR secret;
   uchar_ptr      inp = pcb->FRAG[0].FRAGMENT + 2;
   uchar_ptr      valp = NULL;
   uchar_ptr      idp = NULL;
   uchar          code, id;
   uchar          vallen = 0;
   uchar          idlen = 0;
   uchar          namelen;
   uint_16        len;
   boolean        delay = FALSE;

   /*
   ** Parse header (code, id and length).
   ** If packet too short, drop it.
   */
   if (pcb->FRAG[0].LENGTH < 2 + CHAP_HDR_LEN) {
      chap_ptr->ST_CHAP_SHORT++;
      PCB_free(pcb);
      return;
   } /* Endif */

   code = *inp++;
   id = *inp++;
   len = *inp++ << 8;
   len += *inp++;

   if ((len < CHAP_HDR_LEN) || (len > pcb->FRAG[0].LENGTH - 2)) {
      chap_ptr->ST_CHAP_SHORT++;
      PCB_free(pcb);
      return;
   } /* Endif */
   len -= CHAP_HDR_LEN;

   /*
   ** For Challenge and Response packets, also parse the
   ** value and name fields.
   */
   if ((code == CHAP_CODE_CHALLENGE) || (code == CHAP_CODE_RESPONSE)) {

      if (len < 1) {
         chap_ptr->ST_CHAP_SHORT++;
         PCB_free(pcb);
         return;
      } /* Endif */
      valp = inp;
      vallen = *valp++;
      len--;

      if (len < vallen) {
         chap_ptr->ST_CHAP_SHORT++;
         PCB_free(pcb);
         return;
      } /* Endif */
      idp = valp + vallen;
      idlen = len - vallen;

   } /* Endif */

   switch (code) {

   case CHAP_CODE_CHALLENGE:

      if (chap_ptr->CLIENT_STATE != CHAP_STATE_INITIAL) {
         chap_ptr->ST_CHAP_NOAUTH++;
         PCB_free(pcb);
         break;
      } /* Endif */

      /* OK -- Generate a Response packet */
      /* Start CR 2207 */
      secret = PPP_SECRET(ppp_ptr,_PPP_CHAP_LSECRETS);
      /* End CR 2207 */
      inp = pcb->FRAG[0].FRAGMENT + 2;
      *inp++ = CHAP_CODE_RESPONSE;
      inp++;                           /* Keep same ID */
      /* Start CR 2207 */
      namelen = strlen(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME));
      /* End CR 2207 */
      len = CHAP_HDR_LEN + 1 + 16 + namelen;
      *inp++ = (len >> 8) & 0xFF;
      *inp++ =  len       & 0xFF;
      *inp++ = 16;
      for (;;) {
         if ((secret->PPP_ID_LENGTH == 0)
          && (secret->PPP_PW_LENGTH == 0)) {
            /* Couldn't find a secret for this peer */
            chap_ptr->ST_CHAP_NOPW++;
            PPP_MD5(inp, (uint_32)1, &id,       /* id */
                         (uint_32)vallen, valp, /* challenge */
                         (uint_32)0);
            break;
         } /* Endif */
         if ((secret->PPP_ID_LENGTH == idlen)
          && (memcmp(secret->PPP_ID_PTR, idp, idlen) == 0)) {
            /* Found a secret; send response */
            PPP_MD5(inp, (uint_32)1, &id,                /* id */
                         (uint_32)secret->PPP_PW_LENGTH, /* secret */
                         secret->PPP_PW_PTR,
                         (uint_32)vallen, valp,          /* challenge */
                         (uint_32)0);
            break;
         } /* Endif */
         secret++;
      } /* Endfor */
      inp += 16;
      /* Start CR 2207 */
      PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME), inp, namelen);
      /* End CR 2207 */
      pcb->FRAG[0].LENGTH = len + 2;
      PPP_send_one(ppp_ptr, PPP_PROT_CHAP, pcb);
      break;

   case CHAP_CODE_RESPONSE:

      switch (chap_ptr->SERVER_STATE) {
      case CHAP_STATE_INITIAL:

         /* Check the ID against our last challenge */
         if (id != chap_ptr->CURID) {
            chap_ptr->ST_CHAP_ID++;
            PCB_free(pcb);
            break;
         } /* Endif */

         /* Stop the challenge, whether or not the response is correct */
         PPP_send_stop(ppp_ptr, PPP_PROT_CHAP);

         chap_ptr->SERVER_STATE = CHAP_STATE_FAILURE;

         if (vallen != 16) {
            delay = TRUE;
            CHAP_fail(handle);

         } else {
            /* Search for name in the secrets table */
            /* Start CR 2207 */
            secret = PPP_SECRET(ppp_ptr,_PPP_CHAP_RSECRETS);
            /* End CR 2207 */
            for (;;) {
               if ((secret->PPP_ID_LENGTH == 0)
                && (secret->PPP_PW_LENGTH == 0)) {
                     /* Couldn't find a secret for this peer */
                  delay = TRUE;
                  CHAP_fail(handle);
                  break;
               } /* Endif */
               if ((secret->PPP_ID_LENGTH == idlen)
                && (memcmp(secret->PPP_ID_PTR, idp, idlen) == 0)) {
                     /* Found a secret; compute hash */
                  uchar digest[16];

                  PPP_MD5(digest, (uint_32)1, &id,                /* id */
                                  (uint_32)secret->PPP_PW_LENGTH, /* secret */
                                  secret->PPP_PW_PTR,
                                  (uint_32)CHAP_CHALLENGE_LEN,    /* challenge */
                                  chap_ptr->MD5,
                                  (uint_32)0);

                  if (memcmp(digest, valp, vallen) == 0) {
                     chap_ptr->SERVER_STATE = CHAP_STATE_SUCCESS;
                     CHAP_up(handle);
                  } else {
                     delay = TRUE;
                     CHAP_fail(handle);
                  } /* Endif */
                  break;
               } /* Endif */
               secret++;
            } /* Endfor */
         } /* Endif */

         /* fall through */
      case CHAP_STATE_SUCCESS:
      case CHAP_STATE_FAILURE:
         /* Build a Success or Failure reply */
         inp = pcb->FRAG[0].FRAGMENT + 2;
         *inp++ = chap_ptr->SERVER_STATE;
         inp++;                              /* Keep same ID */
         *inp++ = 0;
         *inp++ = 4;
         pcb->FRAG[0].LENGTH = 6;
         if (delay) {
            PPP_send_rexmit(ppp_ptr, PPP_PROT_CHAP, pcb, 1, CHAP_close, handle);
         } else {
            PPP_send_one(ppp_ptr, PPP_PROT_CHAP, pcb);
         } /* Endif */
         break;

      default:
         chap_ptr->ST_CHAP_NOCHAL++;
         PCB_free(pcb);
         break;
      } /* Endswitch */
      break;

   case CHAP_CODE_SUCCESS:
       /* Authentication success */
       chap_ptr->CLIENT_STATE = CHAP_STATE_SUCCESS;
       CHAP_up(handle);
   case CHAP_CODE_FAILURE:
       /* Authentication failure */
      if (chap_ptr->CLIENT_STATE != CHAP_STATE_SUCCESS)
      {
          /* Change client state when authenticate failure */
          chap_ptr->CLIENT_STATE = CHAP_STATE_FAILURE;
          if (chap_ptr->CLIENT_STATE != CHAP_STATE_INITIAL)
          {
             chap_ptr->ST_CHAP_NOAUTH++;
          }
          CHAP_fail(handle);
      } /* Endif */
      PCB_free(pcb);
      break;

   default:
      chap_ptr->ST_CHAP_CODE++;
      PCB_free(pcb);
      break;
   } /* Endswitch */
   
#else
    
    PCB_free(pcb);
    
#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CHAP_up
* Returned Value  :  void
* Comments        :
*     Called by CHAP_input once the peer has been authenticated.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void CHAP_up
   (
      _ppp_handle   handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = handle;

   PPP_mutex_lock(&ppp_ptr->MUTEX);
   ppp_ptr->LINK_AUTH = TRUE;
   PPP_mutex_unlock(&ppp_ptr->MUTEX);

   PPP_up(handle);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CHAP_fail
* Returned Value  :  void
* Comments        :
*     Called by CHAP_Input if the peer's credentials are rejected.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void CHAP_fail
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = handle;
   PPP_CALL_INTERNAL_PTR call_ptr = &ppp_ptr->LCP_CALL[PPP_CALL_AUTH_FAIL];

   if (call_ptr->CALLBACK) {
      call_ptr->CALLBACK(call_ptr->PARAM);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CHAP_close
* Returned Value  :  void
* Comments        :
*     Called by the Tx task.  Terminates the link after a
*     Failure packet is sent.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void CHAP_close
   (
      pointer        handle,
            /* [IN] - the PPP state structure */
      PCB_PTR        pcb,
            /* [IN] - expired packet */
      boolean        hard
            /* [IN] - TRUE if this is a hard timeout (TO- event) */
   )
{ /* Body */

   PPP_close(handle);

} /* Endbody */


#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/CRC32.c<|end_filename|>
#include "..\bsp\bsp.h"

unsigned int crc_table[256];

/*
  Name  : CRC-32
  Poly  : 0x04C11DB7    x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 
                       + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
  Init  : 0xFFFFFFFF
  Revert: true
  XorOut: 0xFFFFFFFF
  Check : 0xCBF43926 ("123456789")
  MaxLen: 268 435 455 Byte 
*/
unsigned int Crc32(unsigned char *buf, unsigned int len)
{
  unsigned int crc; 
  int i, j;

  for ( i = 0; i < 256; i++ )
  {
    crc = i;
    for ( j = 0; j < 8; j++ )
      crc = crc & 1 ? (crc >> 1) ^ 0xEDB88320UL : crc >> 1;

    crc_table[i] = crc;
  };

  crc = 0xFFFFFFFFUL;

  while ( len-- )
    crc = crc_table[(crc ^ *buf++) & 0xFF] ^ (crc >> 8);

  return crc ^ 0xFFFFFFFFUL;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fputc.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fputc.c$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the functions for printing a character.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Writes a character (converted to an unsigned char).
 * 
 * \param[in] c        The character to print out.
 * \param[in] file_ptr The stream to print the character upon.
 * 
 * \return Written character.
 * \return IO_EOF (Failure.) 
 */ 
_mqx_int _io_fputc
   (
      _mqx_int     c,
      MQX_FILE_PTR file_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   dev_ptr;
   char                   tmp;

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(IO_EOF);
   } /* Endif */
#endif

   dev_ptr = file_ptr->DEV_PTR;
#if MQX_CHECK_ERRORS
   if (dev_ptr->IO_WRITE == NULL) {
      file_ptr->ERROR = MQX_IO_OPERATION_NOT_AVAILABLE;
      return(IO_EOF);
   } /* Endif */
#endif
   tmp = (char)c;

   if ((*dev_ptr->IO_WRITE)(file_ptr, &tmp, 1) != 1) {
      return(IO_EOF);
   } /* Endif */

   return(c);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/route.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: route.c$
* $Version : 3.8.7.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the
*   route core functions.
*
* TODO:
*  - when a aux route is added, how to set the metric ? especially hard
*  in case of a redirect route. i dont have to. a router must discard a
*  icmp redirect. rfc1812.4.2.2.2. i act as a router if IP_cfg_ptr->ROUTE_FN
*  is non null.
*  - even for the static route, a metric is required because rtcs will advertise
*  this route. how to choose the metric unit ? not the same for rip/ospf... 
*  a number between 0 and 64k. thus each protocol can handle it.
*  ospf will get it as is. and rip will divide it by 4096.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_IP4 

#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "route.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ROUTE_register
*  Parameters     :
*  Comments       :
*
*END*-----------------------------------------------------------------*/

void ROUTE_register
(
   IP_ROUTE_FN_PTR   fn
)
{ /* Body */
   IP_CFG_STRUCT_PTR    IP_cfg_ptr = RTCS_getcfg( IP );

   fn->NEXT = IP_cfg_ptr->ROUTE_FN;
   IP_cfg_ptr->ROUTE_FN = fn;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ROUTE_get
*  Parameters     :
*  Comments       :
*
*END*-----------------------------------------------------------------*/
struct ROUTE_get_struct  {
   _ip_address             netaddr;
   _ip_address             netmask;
   IP_ROUTE_INDIRECT_PTR   gate;
};

static boolean ROUTE_get_test
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   ) 
{ /* Body */
   struct ROUTE_get_struct _PTR_ testdata = data;
   IP_ROUTE_PTR                  route = node_data;
   
   if (route && testdata->netaddr == node_ip && 
      testdata->netmask == node_mask)  
   {
      if (route->DIRECT) {
         /* Start SPR P122-0266-20 remove all warnings from RTCS code. */
         /* testdata->gate = (IP_ROUTE_INDIRECT_PTR) route->DIRECT; */
         testdata->gate = (IP_ROUTE_INDIRECT_PTR)((void _PTR_)route->DIRECT);
         /* End SPR P122-0266-20. */
      /* Start CR 1135 */
      } else if (route->VIRTUAL) {
         testdata->gate = (IP_ROUTE_INDIRECT_PTR)route->VIRTUAL;
      /* End CR 1135 */
      } else if (route->INDIRECT) { 
         testdata->gate = route->INDIRECT;
      } /* Endif */
      
      return TRUE;   
   } /* Endif */
   
   return FALSE;
} /* Endbody */

IP_ROUTE_INDIRECT_PTR ROUTE_get
(
   _ip_address netaddr, /* [IN] the network address */
   _ip_address netmask  /* [IN] the network mask */
)
{ /* Body */
   IP_CFG_STRUCT_PTR             IP_cfg_ptr = RTCS_getcfg( IP );
   struct ROUTE_get_struct       testdata;
   
   testdata.netaddr = netaddr;
   testdata.netmask = netmask;
   testdata.gate    = NULL;
   
   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, ROUTE_get_test, &testdata);
   
   return testdata.gate;
} /* Endbody */

#if 1
#include <fio.h>

static  boolean ROUTE_walk_test
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   ) 
{ /* Body */
   IP_ROUTE_PTR                  route = node_data;
   IP_IF_PTR                     ip_if_ptr;

   if (route != NULL) {
      if (route->DIRECT) {
         printf("DIRECT Route: %d.%d.%d.%d, NetIF=%x,DestIF=%x\n", 
             IPBYTES(route->DIRECT->ADDRESS),route->DIRECT->NETIF->HANDLE, route->DIRECT->DESTIF->HANDLE );
      } else if (route->VIRTUAL) {
         printf("VIRTUAL Route: %d.%d.%d.%d, IS DIRECT=%x,DestIF=%x\n", 
             IPBYTES(route->VIRTUAL->ADDRESS), route->VIRTUAL->IS_DIRECT->HANDLE, route->VIRTUAL->DESTIF->HANDLE);
      } else if (route->INDIRECT) { 
         printf("INDIRECT Route: %d.%d.%d.%d", IPBYTES(route->INDIRECT->GATEWAY) );
         if (route->INDIRECT->IS_DIRECT) {
            ip_if_ptr = (IP_IF_PTR)route->INDIRECT->IS_DIRECT;
            printf(", IS DIRECT IF=%x\n", ip_if_ptr->HANDLE);
         } else {
            printf("\n");
         }
     } /* Endif */
   }

   return FALSE;
} /* Endbody */

#endif

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ROUTE_insert
*  Parameters     :
*  Comments       : 
*
*END*-----------------------------------------------------------------*/

struct ROUTE_insert_struct {
   IP_ROUTE_INDIRECT_PTR   route;
};

static void ROUTE_insert_indirect
   (
      pointer _PTR_  node,   /* ptr to address of the IPRADIX_NODE DATA ptr */
      pointer        data    /* ptr to an ip_route_insert_indirect struct   */
   )
{ /* Body */
   struct ROUTE_insert_struct _PTR_ insertdata = data;
   IP_ROUTE_PTR route;

   /* Make sure the node is initialized */
   if (!*node) {  
      *node = node;
      ((IP_ROUTE_PTR) *node)->DIRECT = NULL;
      ((IP_ROUTE_PTR) *node)->INDIRECT = NULL;      
      /* Start CR 1135 */
      ((IP_ROUTE_PTR) *node)->VIRTUAL = NULL;      
      /* End CR 1135 */
   } /* endif */
      
   route = *node;
   if (!route->INDIRECT) {                               
      insertdata->route->NEXT = insertdata->route;  
      route->INDIRECT = insertdata->route;            
   } else {
      insertdata->route->NEXT = route->INDIRECT->NEXT;
      route->INDIRECT->NEXT = insertdata->route;
   } /* Endif */

} /* Endbody */


uint_32 ROUTE_insert
(
   IP_ROUTE_INDIRECT_PTR   gate,    /* [IN] the route entry to insert */
   _ip_address             network,
   _ip_address             netmask  
)
{ /* Body */
   IP_CFG_STRUCT_PTR          IP_cfg_ptr = RTCS_getcfg(IP);
   struct ROUTE_insert_struct insertdata;
   
   insertdata.route = gate;
   
   /* Add to gateway list */
   IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, network & netmask, netmask,
                  IP_cfg_ptr->RADIX_PARTID,
                  ROUTE_insert_indirect, &insertdata);
   
   return RTCS_OK;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ROUTE_remove
*  Parameters     :
*  Comments       : 
*
*END*-----------------------------------------------------------------*/
struct ROUTE_remove_struct {
   IP_ROUTE_INDIRECT_PTR   gate;
   _ip_address             network;
   _ip_address             netmask;
   boolean                 found;
};

static boolean ROUTE_remove_test 
   (
      _ip_address node_ip,
      _ip_address node_mask,
      pointer     node_data,
      pointer     data
   )
{ /* Body */
   IP_ROUTE_PTR                     route = node_data;
   IP_ROUTE_INDIRECT_PTR            indirect;
   struct ROUTE_remove_struct _PTR_ testdata = data;
      
   if (route && route->INDIRECT) {
      indirect = route->INDIRECT;
      do {
         if (indirect == testdata->gate) {
            testdata->found = TRUE;
            testdata->network = node_ip;
            testdata->netmask = node_mask;
            return TRUE;
         } /* Endif */
         indirect = indirect->NEXT;
      } while(indirect != route->INDIRECT);
   } /* Endif */
   
   return FALSE;
} /* Endbody */

uint_32 ROUTE_remove
(
   IP_ROUTE_INDIRECT_PTR gate  /* [IN] the route entry to remove */
)
{ /* Body */
   IP_CFG_STRUCT_PTR             IP_cfg_ptr = RTCS_getcfg(IP);
   IP_ROUTE_FN_PTR               fn;
   struct ROUTE_remove_struct    testdata;
   
   fn = IP_cfg_ptr->ROUTE_FN;
   while (fn) {
      fn->REM_RT(gate);
      fn = fn->NEXT;
   } /* Endwhile */

   testdata.gate = gate;
   testdata.network = INADDR_ANY;
   testdata.netmask = INADDR_ANY;
   testdata.found = FALSE;
   
   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, ROUTE_remove_test, &testdata);
   
   if (testdata.found) {
      /* Start CR 1135 */
      IP_route_remove_indirect(gate->GATEWAY, testdata.netmask, 
         testdata.network, gate->FLAGS, gate->METRIC);
      /* End CR 1135 */
   } /* Endif */

   return RTCS_OK;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ROUTE_new_bindif
*  Parameters     :
*  Comments       : 
*
*END*-----------------------------------------------------------------*/

uint_32 ROUTE_new_bindif
(
   IP_ROUTE_DIRECT_PTR bindif  /* [IN] the outgoing binded interface */
)
{ /* Body */
   IP_CFG_STRUCT_PTR    IP_cfg_ptr = RTCS_getcfg(IP);
   IP_ROUTE_FN_PTR      fn;
   
   fn = IP_cfg_ptr->ROUTE_FN;
   while (fn) {
      fn->INIT_IF(bindif);
      fn = fn->NEXT;
   } /* Endwhile */

   return RTCS_OK;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */


_ip_address RTCS_get_route
(
   _ip_address netaddr, /* [IN] the network address */
   _ip_address netmask  /* [IN] the network mask */
)
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   IP_CFG_STRUCT_PTR             IP_cfg_ptr = RTCS_getcfg( IP );
   struct ROUTE_get_struct       testdata;
   
   testdata.netaddr = netaddr;
   testdata.netmask = netmask;
   testdata.gate    = NULL;
   
   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, ROUTE_get_test, &testdata);
   
   return testdata.gate->GATEWAY;

#else
   
   return 0;

#endif /* RTCSCFG_ENABLE_IP4 */
} /* Endbody */

void RTCS_walk_route(void)
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   IP_CFG_STRUCT_PTR             IP_cfg_ptr = RTCS_getcfg( IP );
   struct ROUTE_get_struct       testdata;
   
   testdata.netaddr = 0;
   testdata.netmask = 0;
   testdata.gate    = NULL;
   
   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, ROUTE_walk_test, &testdata);
   
#endif   
   
} /* Endbody */



/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/CAN_task.h<|end_filename|>
#ifndef __CAN_TASK_H
#define __CAN_TASK_H


#define COMCH_BLOCK_MAX_SZ 512



typedef enum
{
  STANDARD_FORMAT = 0, 
  EXTENDED_FORMAT
} CAN_FORMAT;


typedef enum
{
  DATA_FRAME = 0, 
  REMOTE_FRAME
} CAN_FRAME;

void CAN_loader(void);

void Get_block_CRC(INT8U *block, INT16U len, INT8U *dest);

#endif

<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/qpit.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: qpit.h$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*    This file contains definitions for the Qoriwa PIT registers
*
*END***********************************************************************/

#ifndef __qpit_h__
#define __qpit_h__


#define QPIT_NUM_TIMERS 4

#define QPIT_MCR_MDIS      (1<<1)
#define QPIT_MCR_FRZ       (1<<0)

#define QPIT_TCTRL_TIE     (1<<1)
#define QPIT_TCTRL_TEN     (1<<0)

#define QPIT_TFLG_TIF      (1<<0)


typedef struct qpit_timer_reg_struct {
   uint_32  LDVAL;
   uint_32  CVAL;
   uint_32  TCTRL;
   uint_32  TFLG;
} QPIT_TIMER_REG_STRUCT, * QPIT_TIMER_REG_STRUCT_PTR;

typedef volatile struct qpit_timer_reg_struct * VQPIT_TIMER_REG_STRUCT_PTR;

typedef struct qpit_reg_struct {
   uint_32                 MCR;
   RESERVED_REGISTER(0x0004,0x0100);
   QPIT_TIMER_REG_STRUCT   TIMERS[QPIT_NUM_TIMERS];
   RESERVED_REGISTER(0x0140,0x4000);
} QPIT_REG_STRUCT, * QPIT_REG_STRUCT_PTR;

typedef volatile struct qpit_reg_struct * VQPIT_REG_STRUCT_PTR;


#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mpxn20.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mpxn20.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the default initialization record for the
*   flash device. The 8313e-rdb uses a Spansion 29lv640 The
*   8323e-rdb uses a Intel Strata 28f128j3.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "flashx.h"
#include "flash_c90.h"
#include "flash_c90_prv.h"


const FLASHX_BLOCK_INFO_STRUCT _mpxn20_block_map[] =
{
    /* count, address, size */

    /* LAS */
    { 8,        0,  0x4000, C90_ASPACE_LAS|C90_WIDTH_128|C90_ALIGN_64 },    /* L0..L7    8*16 KB */
    { 2,  0x20000, 0x10000, C90_ASPACE_LAS|C90_WIDTH_128|C90_ALIGN_64 },    /* L8..L9    2*64 KB */
    
    /* MAS */    
    { 2,  0x40000, 0x20000, C90_ASPACE_MAS|C90_WIDTH_128|C90_ALIGN_64 },    /* M0..M1    2*128 KB */
    
    /* HAS */    
    { 6,  0x80000, 0x40000, C90_ASPACE_HAS|C90_WIDTH_128|C90_ALIGN_64 },    /* H0..H5    6*256 KB */
    
    /* Shadow row */
    { 1, 0xFFC000,  0x4000, C90_ASPACE_SHADOW|C90_WIDTH_128|C90_ALIGN_64 }, /* shadow row, 16 KB */

    { 0, 0, 0 }
};


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_c90_address
* Returned Value   : Address upon success
* Comments         :
*    This function returns the base register address of the C90 flash controller.
*
*END*----------------------------------------------------------------------*/

pointer _bsp_get_c90_address (uint_32 base_addr)
{
    return (pointer)MPXN20_PF_CONFIG_BASE;
}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/spansion/29glxxxN.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: 29glxxxN.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions to program the Spansion
*   S29GL128N flash devices.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "29glxxxN.h"
#include "29glxxxN_prv.h"
                                                      
#define FLASH_READY 1
#define FLASH_ERASE_SUSPENDED 2
#define FLASH_TIMEOUT 3
#define FLASH_BUSY 4
#define FLASH_ERROR 5

extern uint_32 _29glxxxN_status(IO_FLASHX_STRUCT_PTR, pointer);


const FLASHX_DEVICE_IF_STRUCT _flashx_29glxxxN_if = {
    _29glxxxN_erase,
    _29glxxxN_program,
    _29glxxxN_chip_erase,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29glxxxN_program
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs the prom devices listed below:
*       29GL128N, 29GL256N and 29GL512N
* 
*END*----------------------------------------------------------------------*/

boolean _29glxxxN_program
   (  
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] where to copy data from */
      char_ptr             from_ptr,
      
      /* [OUT] where to copy data to */
      char_ptr             to_ptr,

      /* [IN] the size to copy in bytes */
      _mem_size            size
   )
{ /* Body */
   volatile uint_16 _PTR_  base16_ptr;
   volatile uint_16 _PTR_  dest16_ptr;
   uint_16_ptr             src16_ptr;
   volatile uchar _PTR_    base8_ptr;
   volatile uchar _PTR_    dest8_ptr;
   uchar_ptr               src8_ptr;
   uint_32                 tmp1;
   uint_32                 result = FLASH_READY;
   _mem_size               sector_addr;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   _io_flashx_phys_to_sector(flashx_ptr, (_mem_size)to_ptr, NULL, &sector_addr, NULL);

   if (flashx_ptr->WIDTH == 16) {
      src16_ptr  = (uint_16_ptr)from_ptr;         
      dest16_ptr = (volatile uint_16 _PTR_)to_ptr;
      base16_ptr = (volatile uint_16 _PTR_)sector_addr;
      while (size) {
         tmp1 = (uint_32)*src16_ptr++;
         if (tmp1 != 0xFFFF) {
            _int_disable();
            base16_ptr[0x555] = 0xAAAA;
            base16_ptr[0x2AA] = 0x5555;
            base16_ptr[0x555] = 0xA0A0;        /* Write command */            
            *dest16_ptr       = (uint_16)tmp1; /* write value */
           _int_enable();
            while ((result = _29glxxxN_status(flashx_ptr,
               (pointer)dest16_ptr)) == FLASH_BUSY)
            {
            }/* Endwhile */
            if (result != FLASH_READY) {
               break;
            } /* Endif */
         }/* Endif */
         size -= 2;
         dest16_ptr++;
      }/* Endwhile */
      base16_ptr[0] = 0xF0F0;

   } else if (flashx_ptr->WIDTH == 8) {
      src8_ptr  = (uchar_ptr)from_ptr;         
      dest8_ptr = (volatile uchar _PTR_)to_ptr;
      base8_ptr = (volatile uchar _PTR_)sector_addr;
      while (size) {
         tmp1 = (uint_32)*src8_ptr++;
         if (tmp1 != 0xFF) {
            _int_disable();
            base8_ptr[0xAAA] = 0xAA;
            base8_ptr[0x555] = 0x55;
            base8_ptr[0xAAA] = 0xA0;        /* Write command */           
            *dest8_ptr       = (uchar)tmp1; /* write value */
           _int_enable();
            while ((result = _29glxxxN_status(flashx_ptr,
               (pointer)dest8_ptr)) == FLASH_BUSY)
            {
            }/* Endwhile */
            if (result != FLASH_READY) {
               break;
            } /* Endif */
         }/* Endif */
         size -= 1;
         dest8_ptr++;
      }/* Endwhile */
      base8_ptr[0] = 0xF0;

   } /* Endif */
   
   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */

   return result == FLASH_READY;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29glxxxN_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases (sector) the prom devices listed below:
*       29GL128N, 29GL256N and 29GL512N
* 
*END*----------------------------------------------------------------------*/

boolean _29glxxxN_erase
   (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] the sector to erase */
      char           _PTR_ input_sect_ptr,

      /* [IN] the sector size */
      _mem_size            sector_size
   )
{ /* Body */
   volatile uint_16 _PTR_ sect16_ptr;
   volatile uchar _PTR_   sect8_ptr;
   uint_32                result;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 16) {
      sect16_ptr = (volatile uint_16 _PTR_)input_sect_ptr;
      _int_disable();     
      sect16_ptr[0x555] = 0xAAAA;
      sect16_ptr[0x2AA] = 0x5555;
      sect16_ptr[0x555] = 0x8080;
      sect16_ptr[0x555] = 0xAAAA;
      sect16_ptr[0x2AA] = 0x5555;
      sect16_ptr[0]     = 0x3030;    /* Sector erase */
      _int_enable();
      while ((result = _29glxxxN_status(flashx_ptr, (pointer)sect16_ptr))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect16_ptr[0] = 0xF0F0;

   } else if (flashx_ptr->WIDTH == 8) {
      sect8_ptr = (volatile uchar _PTR_)input_sect_ptr;
      _int_disable();
      sect8_ptr[0xAAA] = 0xAA;
      sect8_ptr[0x555] = 0x55;
      sect8_ptr[0xAAA] = 0x80;
      sect8_ptr[0xAAA] = 0xAA;
      sect8_ptr[0x555] = 0x55;
      sect8_ptr[0]     = 0x30;    /* Sector erase */
      _int_enable();
      while ((result = _29glxxxN_status(flashx_ptr, (pointer)sect8_ptr))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect8_ptr[0] = 0xF0;

   }/* Endif */

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */

   return result == FLASH_READY;
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29glxxxN_chip_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases all the prom devices. listed below:
*       29GL128N, 29GL256N and 29GL512N
* 
*END*----------------------------------------------------------------------*/

boolean _29glxxxN_chip_erase
   (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR flashx_ptr
   )
{ /* Body */
   volatile uint_16 _PTR_ sect16_ptr;
   volatile uchar _PTR_   sect8_ptr;
   uint_32                result;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 16) {
      sect16_ptr = (volatile uint_16 _PTR_)flashx_ptr->BASE_ADDR;
      _int_disable();
      sect16_ptr[0xAAA] = 0xAAAA;
      sect16_ptr[0x555] = 0x5555;
      sect16_ptr[0xAAA] = 0x8080;
      sect16_ptr[0xAAA] = 0xAAAA;
      sect16_ptr[0x555] = 0x5555;
      sect16_ptr[0xAAA] = 0x1010;    /* chip erase */
      _int_enable();
      while ((result = _29glxxxN_status(flashx_ptr, (pointer)sect16_ptr))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect16_ptr[0] = 0xF0F0;

   } else if (flashx_ptr->WIDTH == 8) {
      sect8_ptr = (volatile uchar _PTR_)flashx_ptr->BASE_ADDR;
      _int_disable();
      sect8_ptr[0xAAA] = 0xAA;
      sect8_ptr[0x555] = 0x55;
      sect8_ptr[0xAAA] = 0x80;
      sect8_ptr[0xAAA] = 0xAA;
      sect8_ptr[0x555] = 0x55;
      sect8_ptr[0xAAA] = 0x10;    /* chip erase */
      _int_enable();
      while ((result = _29glxxxN_status(flashx_ptr, (pointer)sect8_ptr))
         == FLASH_BUSY)
      {
      }/* Endwhile */
      sect8_ptr[0] = 0xF0;

   }/* Endif */

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   }/* Endif */

   return result == FLASH_READY;
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29glxxxN_status
* Returned Value   : uint_32 current status of operation
* Comments         : 
*
*END*----------------------------------------------------------------------*/

uint_32 _29glxxxN_status
   (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR flashx_ptr,
      
      /* [IN] address */
      pointer              addr
   )
{ /* Body */
   volatile uint_16 _PTR_ sect16_ptr;
   volatile uchar _PTR_   sect8_ptr;
   uint_32                tmp1;
   uint_32                tmp2;
   uint_32                toggle;
   uint_32                retry = 2;
   
   sect16_ptr = (volatile uint_16 _PTR_)addr;
   sect8_ptr  = (volatile uchar _PTR_)addr;

   while (retry--) {
      if (flashx_ptr->WIDTH == 16) {
         tmp1 = *sect16_ptr;
         tmp2 = *sect16_ptr;
         toggle = tmp1 ^ tmp2;   /* See what bits changed */
      } else if (flashx_ptr->WIDTH == 8) {
         tmp1 = *sect8_ptr;
         tmp2 = *sect8_ptr;
         toggle = tmp1 ^ tmp2;   /* See what bits changed */
      }/* Endif */
   
      if (toggle == 0) {
        return FLASH_READY;
      } /* Endif */

      if (toggle & 0x40) {
         if (tmp1 & 0x20) {
            if (retry) {
               continue;
            }/* Endif */
            return FLASH_TIMEOUT;
         }/* Endif */
         return FLASH_BUSY;
      } else {
         if ((toggle & 0x04) && (tmp1 & 0x80)) {
            if (retry) {
               continue;
            }/* Endif */
            return FLASH_ERASE_SUSPENDED;
         } /* Endif */
      }/* Endif */

   } /* Endwhile */

   return FLASH_ERROR;
   
} /* Endbody */
      
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/klog.h<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: klog.h$
* $Version : 3.8.15.0$
* $Date    : Aug-30-2011$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   kernel log.  It defines what entries in the kernel
*   log look like.  It also identifies the meaning of the bits in the
*   LOG_CONTROL field of mqx.h.
*
*END************************************************************************/
#ifndef __klog_h__
#define __klog_h__ 1

#include <mqx_cnfg.h>

#if (! MQX_KERNEL_LOGGING) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error KERNEL LOGGING functionality is currently disabled in MQX kernel. Please set MQX_KERNEL_LOGGING to 1 in user_config.h and recompile kernel.
#endif


/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* What type of entry in the log */
#define KLOG_FUNCTION_ENTRY   (_mqx_max_type)(1)
#define KLOG_FUNCTION_EXIT    (_mqx_max_type)(2)
#define KLOG_INTERRUPT        (_mqx_max_type)(3)
#define KLOG_INTERRUPT_END    (_mqx_max_type)(4)
#define KLOG_CONTEXT_SWITCH   (_mqx_max_type)(5)
#define KLOG_FUNCTION_ADDRESS (_mqx_max_type)(6)
#define KLOG_RTCS_PCB         (_mqx_max_type)(7)
#define KLOG_RTCS_TIMER       (_mqx_max_type)(8)
#define KLOG_RTCS_ERROR       (_mqx_max_type)(9)

#define KLOG_BSP_IO           (_mqx_max_type)(10)

/*
 * The following control bits are kept in the control variable
 * LOG_CONTROL, and can be modified by the application.
 *
 * Task qualification means that the TD_STRUCT FLAGS field is checked.
 * Only if logging has been enabled for this task are logs generated.
 */

/* The following bits control logging details */

/*
 * The _klog_control variable needs to be modified to set one or more
 * of these bits.
 */

/* Overall enable/disable of kernel logging. */
#define KLOG_ENABLED                  (uint_32)(0x00000001)

/* Enable logging of function entry/exit points. */
#define KLOG_FUNCTIONS_ENABLED        (uint_32)(0x00000002)

/* Enable logging of interrupts. */
#define KLOG_INTERRUPTS_ENABLED       (uint_32)(0x00000004)

/* Enable logging of system clock tick interrupt. */
#define KLOG_SYSTEM_CLOCK_INT_ENABLED (uint_32)(0x00000008)

/* Enable logging of context switches. */
#define KLOG_CONTEXT_ENABLED          (uint_32)(0x00000010)

/* Enable task qualification checking of logs. */
#define KLOG_TASK_QUALIFIED           (uint_32)(0x00000020)

/*
 * The following bits control what functions actually log information.
 * _klog_control variable needs to be modified to set one or more
 * of the following bits.
 *
 * If the KLOG_FUNCTIONS_ENABLED bit is set, then when a function entry
 * or exit point is reached, the function TYPE is checked.  Only those
 * functions for whom logging has been enabled for their TYPE are logged.
 *
 * NOTE: the user can add his own functions to be logged into the kernel
 * log, using the upper bits that are available
 */
#define KLOG_TASKING_FUNCTIONS        (uint_32)(0x00000100)
#define KLOG_ERROR_FUNCTIONS          (uint_32)(0x00000200)
#define KLOG_MESSAGE_FUNCTIONS        (uint_32)(0x00000400)
#define KLOG_INTERRUPT_FUNCTIONS      (uint_32)(0x00000800)
#define KLOG_MEMORY_FUNCTIONS         (uint_32)(0x00001000)
#define KLOG_TIME_FUNCTIONS           (uint_32)(0x00002000)
#define KLOG_EVENT_FUNCTIONS          (uint_32)(0x00004000)
#define KLOG_NAME_FUNCTIONS           (uint_32)(0x00008000)
#define KLOG_MUTEX_FUNCTIONS          (uint_32)(0x00010000)
#define KLOG_SEMAPHORE_FUNCTIONS      (uint_32)(0x00020000)
#define KLOG_WATCHDOG_FUNCTIONS       (uint_32)(0x00040000)
#define KLOG_PARTITION_FUNCTIONS      (uint_32)(0x00080000)
#define KLOG_IO_FUNCTIONS             (uint_32)(0x00100000)
#define KLOG_EDS_FUNCTIONS            (uint_32)(0x00200000)
#define KLOG_RTCS_FUNCTIONS           (uint_32)(0x02000000)

#define KLOG_FUNCTION_MASK            (uint_32)(0xFFFFFF00)

/* For a function, the following are the function identifiers: */

/* Tasking functions */
#define KLOG_task_ready                        (KLOG_TASKING_FUNCTIONS+1)
#define KLOG_task_block                        (KLOG_TASKING_FUNCTIONS+2)
#define KLOG_task_execute_scheduler            (KLOG_TASKING_FUNCTIONS+3)
#define KLOG_task_create                       (KLOG_TASKING_FUNCTIONS+4)
#define KLOG_task_create_block                 (KLOG_TASKING_FUNCTIONS+5)
#define KLOG_task_destroy                      (KLOG_TASKING_FUNCTIONS+6)
#define KLOG_time_dequeue                      (KLOG_TASKING_FUNCTIONS+7)
#define KLOG_sched_setscheduler                (KLOG_TASKING_FUNCTIONS+8)
#define KLOG_sched_yield                       (KLOG_TASKING_FUNCTIONS+9)
#define KLOG_sched_setparam                    (KLOG_TASKING_FUNCTIONS+10)
#define KLOG_sched_setparam_td                 (KLOG_TASKING_FUNCTIONS+11)
#define KLOG_sched_boost_priority              (KLOG_TASKING_FUNCTIONS+12)
#define KLOG_sched_unboost_priority            (KLOG_TASKING_FUNCTIONS+13)
#define KLOG_task_exit_function                (KLOG_TASKING_FUNCTIONS+14)
#define KLOG_taskq_create                      (KLOG_TASKING_FUNCTIONS+15)
#define KLOG_taskq_destroy                     (KLOG_TASKING_FUNCTIONS+16)
#define KLOG_taskq_suspend                     (KLOG_TASKING_FUNCTIONS+17)
#define KLOG_taskq_resume                      (KLOG_TASKING_FUNCTIONS+18)
#define KLOG_sched_set_policy                  (KLOG_TASKING_FUNCTIONS+19)
#define KLOG_sched_set_rr_interval             (KLOG_TASKING_FUNCTIONS+20)
#define KLOG_sched_set_rr_interval_ticks       (KLOG_TASKING_FUNCTIONS+21)
#define KLOG_taskq_suspend_task                (KLOG_TASKING_FUNCTIONS+22)
#define KLOG_task_set_priority                 (KLOG_TASKING_FUNCTIONS+23)
#define KLOG_time_dequeue_td                   (KLOG_TASKING_FUNCTIONS+24)
#define KLOG_task_abort                        (KLOG_TASKING_FUNCTIONS+25)
#define KLOG_task_set_environment              (KLOG_TASKING_FUNCTIONS+26)
#define KLOG_task_enable_fp                    (KLOG_TASKING_FUNCTIONS+27)
#define KLOG_task_disable_fp                   (KLOG_TASKING_FUNCTIONS+28)
#define KLOG_task_set_parameter                (KLOG_TASKING_FUNCTIONS+29)
#define KLOG_task_set_parameter_for            (KLOG_TASKING_FUNCTIONS+30)
#define KLOG_task_stop_preemption              (KLOG_TASKING_FUNCTIONS+31)
#define KLOG_task_start_preemption             (KLOG_TASKING_FUNCTIONS+32)
#define KLOG_task_set_exception_handler        (KLOG_TASKING_FUNCTIONS+33)
#define KLOG_task_set_exit_handler             (KLOG_TASKING_FUNCTIONS+34)
#define KLOG_taskq_test                        (KLOG_TASKING_FUNCTIONS+35)
#define KLOG_io_set_handle                     (KLOG_TASKING_FUNCTIONS+36)
#define KLOG_task_restart                      (KLOG_TASKING_FUNCTIONS+37)
#define KLOG_task_create_at                    (KLOG_TASKING_FUNCTIONS+38)

/* System error functions */
#define KLOG_mqx_exit                          (KLOG_ERROR_FUNCTIONS+1)
#define KLOG_int_default_isr                   (KLOG_ERROR_FUNCTIONS+2)
#define KLOG_task_set_error                    (KLOG_ERROR_FUNCTIONS+3)
#define KLOG_log_test                          (KLOG_ERROR_FUNCTIONS+4)
#define KLOG_mqx_set_exit_handler              (KLOG_ERROR_FUNCTIONS+5)
#define KLOG_mqx_fatal_error                   (KLOG_ERROR_FUNCTIONS+6)

/* Message queue functions */
#define KLOG_msgq_close                        (KLOG_MESSAGE_FUNCTIONS+1)
#define KLOG_msgpool_create_system             (KLOG_MESSAGE_FUNCTIONS+2)
#define KLOG_msgpool_create                    (KLOG_MESSAGE_FUNCTIONS+3)
#define KLOG_msgpool_destroy                   (KLOG_MESSAGE_FUNCTIONS+4)
#define KLOG_msg_free                          (KLOG_MESSAGE_FUNCTIONS+5)
#define KLOG_msg_alloc_system                  (KLOG_MESSAGE_FUNCTIONS+6)
#define KLOG_msg_alloc                         (KLOG_MESSAGE_FUNCTIONS+7)
#define KLOG_msgq_get_owner                    (KLOG_MESSAGE_FUNCTIONS+8)
#define KLOG_msgq_open                         (KLOG_MESSAGE_FUNCTIONS+9)
#define KLOG_msgq_open_system                  (KLOG_MESSAGE_FUNCTIONS+10)
#define KLOG_msgq_receive                      (KLOG_MESSAGE_FUNCTIONS+11)
#define KLOG_msgq_receive_for                  (KLOG_MESSAGE_FUNCTIONS+12)
#define KLOG_msgq_receive_ticks                (KLOG_MESSAGE_FUNCTIONS+13)
#define KLOG_msgq_receive_until                (KLOG_MESSAGE_FUNCTIONS+14)
#define KLOG_msgq_poll                         (KLOG_MESSAGE_FUNCTIONS+15)
#define KLOG_msgq_get_count                    (KLOG_MESSAGE_FUNCTIONS+16)
#define KLOG_msgq_send                         (KLOG_MESSAGE_FUNCTIONS+17)
#define KLOG_msgq_send_blocked                 (KLOG_MESSAGE_FUNCTIONS+18)
#define KLOG_msgq_send_queue                   (KLOG_MESSAGE_FUNCTIONS+19)
#define KLOG_msgq_send_urgent                  (KLOG_MESSAGE_FUNCTIONS+20)
#define KLOG_msgq_send_broadcast               (KLOG_MESSAGE_FUNCTIONS+21)
#define KLOG_msgq_set_notification_function    (KLOG_MESSAGE_FUNCTIONS+22)
#define KLOG_msgq_peek                         (KLOG_MESSAGE_FUNCTIONS+23)
#define KLOG_msgq_send_priority                (KLOG_MESSAGE_FUNCTIONS+24)
#define KLOG_msg_create_component              (KLOG_MESSAGE_FUNCTIONS+25)
#define KLOG_msgpool_test                      (KLOG_MESSAGE_FUNCTIONS+26)
#define KLOG_msgq_test                         (KLOG_MESSAGE_FUNCTIONS+27)
#define KLOG_lwmsgq_init                       (KLOG_MESSAGE_FUNCTIONS+28)
#define KLOG_lwmsgq_send                       (KLOG_MESSAGE_FUNCTIONS+29)
#define KLOG_lwmsgq_receive                    (KLOG_MESSAGE_FUNCTIONS+30)

/* Interrupt management functions */
#define KLOG_int_install_kernel_isr            (KLOG_INTERRUPT_FUNCTIONS+1)
#define KLOG_int_install_isr                   (KLOG_INTERRUPT_FUNCTIONS+2)
#define KLOG_int_install_default_isr           (KLOG_INTERRUPT_FUNCTIONS+3)
#define KLOG_int_set_isr_data                  (KLOG_INTERRUPT_FUNCTIONS+4)
#define KLOG_int_set_exception_handler         (KLOG_INTERRUPT_FUNCTIONS+5)

/* Memory management functions */
#define KLOG_mem_free                          (KLOG_MEMORY_FUNCTIONS+1)
#define KLOG_mem_alloc                         (KLOG_MEMORY_FUNCTIONS+2)
#define KLOG_mem_alloc_from                    (KLOG_MEMORY_FUNCTIONS+3)
#define KLOG_mem_test                          (KLOG_MEMORY_FUNCTIONS+4)
#define KLOG_mem_test_pool                     (KLOG_MEMORY_FUNCTIONS+5)
#define KLOG_mem_alloc_zero                    (KLOG_MEMORY_FUNCTIONS+6)
#define KLOG_mem_alloc_system                  (KLOG_MEMORY_FUNCTIONS+7)
#define KLOG_mem_alloc_system_from             (KLOG_MEMORY_FUNCTIONS+8)
#define KLOG_mem_alloc_system_zero             (KLOG_MEMORY_FUNCTIONS+9)
#define KLOG_mem_alloc_system_zero_from        (KLOG_MEMORY_FUNCTIONS+10)
#define KLOG_mem_extend                        (KLOG_MEMORY_FUNCTIONS+11)
#define KLOG_mem_extend_pool                   (KLOG_MEMORY_FUNCTIONS+12)
#define KLOG_mem_transfer                      (KLOG_MEMORY_FUNCTIONS+13)
#define KLOG_mem_free_part                     (KLOG_MEMORY_FUNCTIONS+14)
#define KLOG_mem_create_pool                   (KLOG_MEMORY_FUNCTIONS+15)

#define KLOG_lwmem_alloc                       (KLOG_MEMORY_FUNCTIONS+16)
#define KLOG_lwmem_alloc_from                  (KLOG_MEMORY_FUNCTIONS+17)
#define KLOG_lwmem_alloc_zero                  (KLOG_MEMORY_FUNCTIONS+18)
#define KLOG_lwmem_alloc_zero_from             (KLOG_MEMORY_FUNCTIONS+19)
#define KLOG_lwmem_create_pool                 (KLOG_MEMORY_FUNCTIONS+20)
#define KLOG_lwmem_free                        (KLOG_MEMORY_FUNCTIONS+21)
#define KLOG_lwmem_alloc_system                (KLOG_MEMORY_FUNCTIONS+22)
#define KLOG_lwmem_alloc_system_from           (KLOG_MEMORY_FUNCTIONS+23)
#define KLOG_lwmem_transfer                    (KLOG_MEMORY_FUNCTIONS+24)
#define KLOG_lwmem_alloc_system_zero           (KLOG_MEMORY_FUNCTIONS+25)
#define KLOG_lwmem_alloc_system_zero_from      (KLOG_MEMORY_FUNCTIONS+26)
#define KLOG_lwmem_get_free                    (KLOG_MEMORY_FUNCTIONS+27)
#define KLOG_lwmem_get_free_from               (KLOG_MEMORY_FUNCTIONS+28)

#define KLOG_mem_alloc_align                   (KLOG_MEMORY_FUNCTIONS+29)
#define KLOG_mem_alloc_at                      (KLOG_MEMORY_FUNCTIONS+30)

#define KLOG_lwmem_alloc_at                    (KLOG_MEMORY_FUNCTIONS+31)
#define KLOG_lwmem_alloc_align                 (KLOG_MEMORY_FUNCTIONS+32)
#define KLOG_lwmem_alloc_align_from            (KLOG_MEMORY_FUNCTIONS+33)

#define KLOG_usr_lwmem_alloc                   (KLOG_MEMORY_FUNCTIONS+34)

/* Partition functions */
#define KLOG_partition_create                  (KLOG_PARTITION_FUNCTIONS+1)
#define KLOG_partition_create_at               (KLOG_PARTITION_FUNCTIONS+2)
#define KLOG_partition_alloc                   (KLOG_PARTITION_FUNCTIONS+3)
#define KLOG_partition_alloc_zero              (KLOG_PARTITION_FUNCTIONS+4)
#define KLOG_partition_alloc_system            (KLOG_PARTITION_FUNCTIONS+5)
#define KLOG_partition_alloc_system_zero       (KLOG_PARTITION_FUNCTIONS+6)
#define KLOG_partition_extend                  (KLOG_PARTITION_FUNCTIONS+7)
#define KLOG_partition_free                    (KLOG_PARTITION_FUNCTIONS+8)
#define KLOG_partition_test                    (KLOG_PARTITION_FUNCTIONS+9)
#define KLOG_partition_transfer                (KLOG_PARTITION_FUNCTIONS+10)
#define KLOG_partition_destroy                 (KLOG_PARTITION_FUNCTIONS+11)
#define KLOG_partition_create_component        (KLOG_PARTITION_FUNCTIONS+12)

/* Time functions */
#define KLOG_time_set                          (KLOG_TIME_FUNCTIONS+1)
#define KLOG_time_set_ticks                    (KLOG_TIME_FUNCTIONS+2)
#define KLOG_time_delay                        (KLOG_TIME_FUNCTIONS+3)
#define KLOG_time_delay_for                    (KLOG_TIME_FUNCTIONS+4)
#define KLOG_time_delay_ticks                  (KLOG_TIME_FUNCTIONS+5)
#define KLOG_time_delay_until                  (KLOG_TIME_FUNCTIONS+6)
#define KLOG_timer_create_component            (KLOG_TIME_FUNCTIONS+7)
#define KLOG_timer_cancel                      (KLOG_TIME_FUNCTIONS+8)
#define KLOG_timer_start_oneshot_after         (KLOG_TIME_FUNCTIONS+9)
#define KLOG_timer_start_oneshot_at            (KLOG_TIME_FUNCTIONS+10)
#define KLOG_timer_start_periodic_every        (KLOG_TIME_FUNCTIONS+11)
#define KLOG_timer_start_periodic_at           (KLOG_TIME_FUNCTIONS+12)
#define KLOG_timer_test                        (KLOG_TIME_FUNCTIONS+13)
#define KLOG_timer_start_oneshot_after_ticks   (KLOG_TIME_FUNCTIONS+14)
#define KLOG_timer_start_oneshot_at_ticks      (KLOG_TIME_FUNCTIONS+15)
#define KLOG_timer_start_periodic_every_ticks  (KLOG_TIME_FUNCTIONS+16)
#define KLOG_timer_start_periodic_at_ticks     (KLOG_TIME_FUNCTIONS+17)
#define KLOG_lwtimer_create_periodic_queue     (KLOG_TIME_FUNCTIONS+18)
#define KLOG_lwtimer_add_timer_to_queue        (KLOG_TIME_FUNCTIONS+19)
#define KLOG_lwtimer_cancel_period             (KLOG_TIME_FUNCTIONS+20)
#define KLOG_lwtimer_cancel_timer              (KLOG_TIME_FUNCTIONS+21)
#define KLOG_lwtimer_test                      (KLOG_TIME_FUNCTIONS+22)

/* Event functions */
#define KLOG_event_create_component            (KLOG_EVENT_FUNCTIONS+1)
#define KLOG_event_create                      (KLOG_EVENT_FUNCTIONS+2)
#define KLOG_event_destroy                     (KLOG_EVENT_FUNCTIONS+3)
#define KLOG_event_open                        (KLOG_EVENT_FUNCTIONS+4)
#define KLOG_event_close                       (KLOG_EVENT_FUNCTIONS+5)
#define KLOG_event_wait_all                    (KLOG_EVENT_FUNCTIONS+6)
#define KLOG_event_wait_all_ticks              (KLOG_EVENT_FUNCTIONS+7)
#define KLOG_event_wait_all_for                (KLOG_EVENT_FUNCTIONS+8)
#define KLOG_event_wait_all_until              (KLOG_EVENT_FUNCTIONS+9)
#define KLOG_event_wait_any                    (KLOG_EVENT_FUNCTIONS+10)
#define KLOG_event_wait_any_ticks              (KLOG_EVENT_FUNCTIONS+11)
#define KLOG_event_wait_any_for                (KLOG_EVENT_FUNCTIONS+12)
#define KLOG_event_wait_any_until              (KLOG_EVENT_FUNCTIONS+13)
#define KLOG_event_set                         (KLOG_EVENT_FUNCTIONS+14)
#define KLOG_event_clear                       (KLOG_EVENT_FUNCTIONS+15)
#define KLOG_event_create_fast                 (KLOG_EVENT_FUNCTIONS+16)
#define KLOG_event_open_fast                   (KLOG_EVENT_FUNCTIONS+17)
#define KLOG_event_destroy_fast                (KLOG_EVENT_FUNCTIONS+18)
#define KLOG_event_test                        (KLOG_EVENT_FUNCTIONS+19)
#define KLOG_lwevent_clear                     (KLOG_EVENT_FUNCTIONS+20)
#define KLOG_lwevent_create                    (KLOG_EVENT_FUNCTIONS+21)
#define KLOG_lwevent_destroy                   (KLOG_EVENT_FUNCTIONS+22)
#define KLOG_lwevent_set                       (KLOG_EVENT_FUNCTIONS+23)
#define KLOG_lwevent_test                      (KLOG_EVENT_FUNCTIONS+24)
#define KLOG_lwevent_wait                      (KLOG_EVENT_FUNCTIONS+25)
#define KLOG_lwevent_wait_for                  (KLOG_EVENT_FUNCTIONS+26)
#define KLOG_lwevent_wait_until                (KLOG_EVENT_FUNCTIONS+27)
#define KLOG_lwevent_wait_ticks                (KLOG_EVENT_FUNCTIONS+28)
#define KLOG_lwevent_set_auto_clear            (KLOG_EVENT_FUNCTIONS+29)
#define KLOG_lwevent_get_signalled             (KLOG_EVENT_FUNCTIONS+30)

/* Naming functions */
#define KLOG_name_create_component             (KLOG_NAME_FUNCTIONS+1)
#define KLOG_name_add                          (KLOG_NAME_FUNCTIONS+2)
#define KLOG_name_delete                       (KLOG_NAME_FUNCTIONS+3)
#define KLOG_name_find                         (KLOG_NAME_FUNCTIONS+4)
#define KLOG_name_find_name                    (KLOG_NAME_FUNCTIONS+5)
#define KLOG_name_test                         (KLOG_NAME_FUNCTIONS+6)

/* Mutex functions */
#define KLOG_mutatr_init                       (KLOG_MUTEX_FUNCTIONS+1)
#define KLOG_mutatr_destroy                    (KLOG_MUTEX_FUNCTIONS+2)
#define KLOG_mutatr_set_sched_protocol         (KLOG_MUTEX_FUNCTIONS+3)
#define KLOG_mutatr_set_priority_ceiling       (KLOG_MUTEX_FUNCTIONS+4)

#define KLOG_mutex_create_component            (KLOG_MUTEX_FUNCTIONS+5)
#define KLOG_mutex_init                        (KLOG_MUTEX_FUNCTIONS+6)
#define KLOG_mutex_set_priority_ceiling        (KLOG_MUTEX_FUNCTIONS+7)
#define KLOG_mutex_destroy                     (KLOG_MUTEX_FUNCTIONS+8)
#define KLOG_mutex_lock                        (KLOG_MUTEX_FUNCTIONS+9)
#define KLOG_mutex_try_lock                    (KLOG_MUTEX_FUNCTIONS+10)
#define KLOG_mutex_unlock                      (KLOG_MUTEX_FUNCTIONS+11)

#define KLOG_mutatr_set_wait_protocol          (KLOG_MUTEX_FUNCTIONS+12)
#define KLOG_mutatr_set_spin_limit             (KLOG_MUTEX_FUNCTIONS+13)
#define KLOG_mutex_test                        (KLOG_MUTEX_FUNCTIONS+14)

/* Semaphore functions */
#define KLOG_sem_create_component              (KLOG_SEMAPHORE_FUNCTIONS+1)
#define KLOG_sem_create                        (KLOG_SEMAPHORE_FUNCTIONS+2)
#define KLOG_sem_destroy                       (KLOG_SEMAPHORE_FUNCTIONS+3)
#define KLOG_sem_open                          (KLOG_SEMAPHORE_FUNCTIONS+4)
#define KLOG_sem_close                         (KLOG_SEMAPHORE_FUNCTIONS+5)
#define KLOG_sem_post                          (KLOG_SEMAPHORE_FUNCTIONS+6)
#define KLOG_sem_create_fast                   (KLOG_SEMAPHORE_FUNCTIONS+7)
#define KLOG_sem_open_fast                     (KLOG_SEMAPHORE_FUNCTIONS+8)
#define KLOG_sem_destroy_fast                  (KLOG_SEMAPHORE_FUNCTIONS+9)
#define KLOG_sem_test                          (KLOG_SEMAPHORE_FUNCTIONS+10)
#define KLOG_sem_wait                          (KLOG_SEMAPHORE_FUNCTIONS+11)
#define KLOG_sem_wait_for                      (KLOG_SEMAPHORE_FUNCTIONS+12)
#define KLOG_sem_wait_ticks                    (KLOG_SEMAPHORE_FUNCTIONS+13)
#define KLOG_sem_wait_until                    (KLOG_SEMAPHORE_FUNCTIONS+14)
#define KLOG_lwsem_create                      (KLOG_SEMAPHORE_FUNCTIONS+15)
#define KLOG_lwsem_wait                        (KLOG_SEMAPHORE_FUNCTIONS+16)
#define KLOG_lwsem_post                        (KLOG_SEMAPHORE_FUNCTIONS+17)
#define KLOG_lwsem_destroy                     (KLOG_SEMAPHORE_FUNCTIONS+18)
#define KLOG_lwsem_test                        (KLOG_SEMAPHORE_FUNCTIONS+19)
#define KLOG_lwsem_poll                        (KLOG_SEMAPHORE_FUNCTIONS+20)
#define KLOG_lwsem_wait_for                    (KLOG_SEMAPHORE_FUNCTIONS+21)
#define KLOG_lwsem_wait_ticks                  (KLOG_SEMAPHORE_FUNCTIONS+22)
#define KLOG_lwsem_wait_until                  (KLOG_SEMAPHORE_FUNCTIONS+23)

/* Watchdog functions */
#define KLOG_watchdog_create_component         (KLOG_WATCHDOG_FUNCTIONS+1)
#define KLOG_watchdog_stop                     (KLOG_WATCHDOG_FUNCTIONS+2)
#define KLOG_watchdog_start                    (KLOG_WATCHDOG_FUNCTIONS+3)
#define KLOG_watchdog_start_ticks              (KLOG_WATCHDOG_FUNCTIONS+4)
#define KLOG_watchdog_test                     (KLOG_WATCHDOG_FUNCTIONS+5)

/* EDS functions */
#define KLOG_eds_create_component              (KLOG_EDS_FUNCTIONS+1)
#define KLOG_eds_remove                        (KLOG_EDS_FUNCTIONS+2)


#define KLOG_ENET_send                         (KLOG_IO_FUNCTIONS + 1)


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ip6.h<|end_filename|>
#ifndef __ip6_h__
#define __ip6_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip6.h$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Definitions for the Internet Protocol 6.
*
*END************************************************************************/

#include "rtcspcb.h"
/******************************************************************
* Constants
*******************************************************************/
#define IP6_HEADSIZE            40      /* sizeof(IP6_HEADER)                 */

#define IP6_DEFAULT_MTU         1280    /* Minimum IPv6 datagram size which    */
                                        /* must be supported by all IPv6 hosts */
#define IP6_DEFAULT_HOPLIMIT    64      /* Default Hop Limit. */

/* IPIF_*() params.*/
typedef struct ip6_if_parm
{
   TCPIP_PARM           COMMON;    
   _rtcs_if_handle      ihandle;
   struct in6_addr      ip_addr;
   ip6_if_addr_type     ip_addr_type;
} 
IP6_IF_PARM, _PTR_ IP6_IF_PARM_PTR;

/******************************************************************
* Function Prototypes
*******************************************************************/
extern uint_32 IP6_init(void);
ICB_STRUCT_PTR IP6_open (uchar  protocol, IP_SERVICE_FN service, pointer private, uint_32_ptr status);
extern void IP6_service (RTCSPCB_PTR);
extern uint_32 IP6_send (RTCSPCB_PTR rtcs_pcb, uint_32 protocol, in6_addr *ipsrc, in6_addr *ipdest, _rtcs_if_handle ihandle_dest, uint_32 flags);
extern void IP6_IF_bind_addr  (IP6_IF_PARM_PTR);
extern void IP6_IF_unbind_addr (IP6_IF_PARM_PTR);

#endif



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/select.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: select.c$
* $Version : 3.8.10.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the RTCS select() support functions.
*
*END************************************************************************/

#include <rtcs.h>

#include <rtcs.h>
#include <select.h>

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_FD_CLR
* Returned Values :
* Comments  :
*     Removes an fd (socket) from a set
*
*END*-----------------------------------------------------------------*/

boolean RTCS_FD_CLR(uint_32 fd, fd_set _PTR_ set_ptr ) 
{ 
    uint_32 i;
    boolean cleared = FALSE;
    
   if ((fd==0) || (set_ptr == NULL)) return FALSE;
    
    for(i=0;i<set_ptr->COUNT;i++) { 
        if (set_ptr->FDS[i] == fd) {
 /* Start CR 2143 */       
            set_ptr->FDS[i] = set_ptr->FDS[--set_ptr->COUNT];
            set_ptr->FDS[set_ptr->COUNT] = 0;
 /* End CR 2143 */           
            cleared = TRUE;   
        }
    }
    return cleared;
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_FD_ISSET
* Returned Values :
* Comments  :
*     Determines if an fd (socket) is in a set
*
*END*-----------------------------------------------------------------*/

boolean RTCS_FD_ISSET(uint_32 fd, fd_set _PTR_ set_ptr ) 
{ 
   uint_32 i;
   if ((fd==0) || (set_ptr == NULL)) return FALSE;
   
    for(i=0;i<set_ptr->COUNT;i++) { 
        if (set_ptr->FDS[i] == fd) {
            return TRUE;   
        }
    }
    return FALSE;
}
    
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_FD_SET
* Returned Values :
* Comments  :
*     Adds an fd (socket) to a set.
*
*END*-----------------------------------------------------------------*/

boolean RTCS_FD_SET(uint_32 fd, fd_set _PTR_ set_ptr ) 
{ 
   uint_32  i;
   
   if ((fd==0) || (set_ptr == NULL)) return FALSE;
   
   for(i=0;i<set_ptr->COUNT;i++) { 
      if (set_ptr->FDS[i] == fd) {
         return TRUE;   
      }
   }
   if (set_ptr->COUNT<RTCS_SELECT_MAX_FDS)  {
      set_ptr->FDS[set_ptr->COUNT++] = fd;
      return TRUE;
   } else  {
      return FALSE;
   }
}
    
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_FD_ZERO
* Returned Values :
* Comments  :
*     Zeros an fd set.
*
*END*-----------------------------------------------------------------*/

boolean RTCS_FD_ZERO(fd_set _PTR_ set_ptr ) 
{ 
   uint_32 i;
    
   if (set_ptr == NULL) return FALSE;
   
   set_ptr->COUNT = 0;
   for(i=0;i<RTCS_SELECT_MAX_FDS;i++) { 
      set_ptr->FDS[i] = 0;   
   }
   return TRUE;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_FD_COPY
* Returned Values :
* Comments  :
*     Copies an fd set.
*
*END*-----------------------------------------------------------------*/

boolean RTCS_FD_COPY(fd_set _PTR_ src_ptr, fd_set _PTR_ dest_ptr ) 
{ 
   uint_32 i;
    
   if ((src_ptr == NULL) || (src_ptr == NULL)) return FALSE;
   
   dest_ptr->COUNT = src_ptr->COUNT;
   for(i=0;i<RTCS_SELECT_MAX_FDS;i++) { 
      dest_ptr->FDS[i] = src_ptr->FDS[i];   
   }
   return TRUE;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_select
* Returned Values :
* Comments  :
*     RTCS version of BSD select call.
*
*END*-----------------------------------------------------------------*/
int_32 RTCS_select
   (
      int_32         n, 
      fd_set _PTR_   readfds, 
      fd_set _PTR_   writefds, 
      fd_set _PTR_   exceptfds, 
      struct timeval *timeout
    )  
{
   fd_set iread_set, iwrite_set;
   uint_32  milliseconds = 0;
   uint_32  sock;
   int i;
   
   // readfds and writefds are supported, only
   if (((readfds != NULL) || (writefds != NULL)) && (exceptfds != NULL)) {
      return RTCS_SELECT_ERROR;
   }
   
   RTCS_FD_ZERO(&iread_set);
   RTCS_FD_ZERO(&iwrite_set);

   if (readfds != NULL) {
      RTCS_FD_COPY(readfds, &iread_set);
   }

   if (writefds != NULL) {
      RTCS_FD_COPY(writefds, &iwrite_set);
   }
   
   if (timeout == NULL)  {
      /* Block indefinetly */
      milliseconds = 0;
   } else if ((timeout->tv_sec==0) && (timeout->tv_usec==0)) {
      /* Poll */
      milliseconds = (uint_32)-1;
   } else  {
      milliseconds = timeout->tv_sec*1000 + (timeout->tv_usec+999)/1000;
   }
   
   sock = _RTCS_select(&iread_set.FDS[0], iread_set.COUNT, &iwrite_set.FDS[0], iwrite_set.COUNT, milliseconds);
   
   if (sock == 0)  {
      return 0;
   } else if (sock == RTCS_SOCKET_ERROR )  {
      return RTCS_SELECT_ERROR;
   }
   
   RTCS_FD_ZERO(readfds);
   RTCS_FD_ZERO(writefds);
   
   for (i = 0; i < iread_set.COUNT; i++) {
      if (iread_set.FDS[i]) {
         RTCS_FD_SET(iread_set.FDS[i], readfds);
      }
   }
   
   for (i = 0; i < iwrite_set.COUNT; i++) {
      if (iwrite_set.FDS[i]) {
         RTCS_FD_SET(iwrite_set.FDS[i], writefds);
      }
   }
   
   return 1;
} 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/media/arp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: arp.c$
* $Version : 3.8.15.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains the implementation of the
*   ARP server.
*   Limitations:  Although ARP can be used over any multiple-access
*   medium, this implementation will work only over an
*   Ethernet link layer.
*
*END************************************************************************/

#include <rtcs.h>

#include <enet.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "arp.h"
#include "arp_prv.h"
#include "ip-e.h"
#include "arpif.h"

#if RTCSCFG_ENABLE_IP4

/* Functions for accessing the ARP cache */
static ARP_ENTRY_PTR ARP_find   (IP_IF_PTR, _ip_address);
static ARP_ENTRY_PTR ARP_insert (IP_IF_PTR, _ip_address);
static void          ARP_delete (ARP_ENTRY_PTR);

/* The various timer events */
static boolean ARP_send   (TCPIP_EVENT_PTR);
static boolean ARP_age    (TCPIP_EVENT_PTR);
static boolean ARP_expire (TCPIP_EVENT_PTR);

/* Macros */


#define ARP_REFRESH(a)                                         \
         (a)->RESEND_INTERVAL = RTCSCFG_ARPTIME_RESEND_MIN;            \
         (a)->RESEND_TIMER.TIME = 0;                           \
         (a)->EXPIRE_TIMER.TIME = RTCSCFG_ARPTIME_EXPIRE_INCOMPLETE;   \
         TCPIP_Event_add(&(a)->RESEND_TIMER);                  \
         TCPIP_Event_add(&(a)->EXPIRE_TIMER)

#define ARP_COMPLETE(a,l)                                      \
         _mem_copy(l, (a)->LADDR, sizeof((a)->LADDR));         \
         (a)->COMPLETE = TRUE;                                 \
         (a)->AGED     = FALSE;                                \
         (a)->HIT      = FALSE;                                \
         (a)->AGE_TIMER.TIME = RTCSCFG_ARPTIME_EXPIRE_COMPLETE         \
                             - RTCSCFG_ARPTIME_EXPIRE_INCOMPLETE;      \
         (a)->EXPIRE_TIMER.TIME = RTCSCFG_ARPTIME_EXPIRE_COMPLETE;     \
         TCPIP_Event_add(&(a)->AGE_TIMER);                     \
         TCPIP_Event_add(&(a)->EXPIRE_TIMER)

/*
** Each ARP cache entry basically has four states:
** complete, aged/quiet, aged/active, incomplete.
**
** For every entry, there exists three timers.
**
**    The resend timer periodically causes an ARP request
**    to be sent.
**
**    The age timer causes complete->aged/quiet and
**    aged->incomplete transitions.
**
**    The expire timer deletes an entry.
**
** For each state, the following timers are active.
**
**    complete       age, expire
**    aged/quiet     age, expire
**    aged/active    resend, age, expire
**    incomplete     resend, expire
**
** Additionally, you can determine the state of an entry from the
** following fields:
**
**                   COMPLETE    AGED     HIT
**    complete       TRUE        FALSE    xx
**    aged/quiet     TRUE        TRUE     FALSE
**    aged/active    TRUE        TRUE     TRUE
**    incomplete     FALSE       xx       xx
**
**
** Here's how it works:
**
** Each entry starts as either complete or incomplete, depending
** on who initiated communication (us or the peer).
**
** Complete entries become aged/quiet after 17 minutes, and
** expire after 20 minutes.
** Aged entries become incomplete after 3 minutes.
**
** When an entry becomes aged, we try to refresh it before it expires.
** However, we don't want to keep entries for unused hosts.
**
** Once the entry ages, if it is not used in the next 3 minutes, it
** will be deleted when the expire timer fires.
**
** If the entry is used in the next 3 minutes, it becomes aged/active.
** We start the resend timer and reset the expire timer to 3 minutes
** after the first hit to give the peer a reasonable chance to reply.
** The age timer remains unchanged -- it will still fire at the same
** time, and make the entry incomplete.
**
** Finally, incomplete entries periodically send ARP requests until
** they expire.
*/

#if (ARP_ENTRY_MAX_QUEUED_PCBS!=1)

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _arp_entry_queue_init
*  Returned Value : pcb or NULL
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/
boolean       _arp_entry_queue_init(ARP_ENTRY_PTR entry_ptr)
{
   uint_32  i;

   for (i=0;i<ARP_ENTRY_MAX_QUEUED_PCBS;i++) {
      entry_ptr->WAITING[i] = NULL;
   }
   entry_ptr->QUEUED_PCBS=0;

   return TRUE;
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _arp_entry_enqueue_pcb
*  Returned Value : boolean
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/
boolean   _arp_entry_enqueue_pcb(ARP_ENTRY_PTR entry_ptr,RTCSPCB_PTR rtcs_pcb)
{
   uint_32 i;

   if (entry_ptr->QUEUED_PCBS == ARP_ENTRY_MAX_QUEUED_PCBS) {
      return FALSE;
   } 

   for (i=entry_ptr->QUEUED_PCBS;i>0;i--) {
      entry_ptr->WAITING[i] = entry_ptr->WAITING[i-1];
   }
   entry_ptr->WAITING[0]=rtcs_pcb;
   entry_ptr->QUEUED_PCBS++;

   return TRUE;
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _arp_entry_queue_peek
*  Returned Value : pcb or NULL
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/
RTCSPCB_PTR   _arp_entry_queue_peek(ARP_ENTRY_PTR entry_ptr)
{
   RTCSPCB_PTR rtcs_pcb = NULL;

   if (entry_ptr->QUEUED_PCBS) {
      rtcs_pcb = entry_ptr->WAITING[entry_ptr->QUEUED_PCBS-1];
   }

   return rtcs_pcb;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _arp_entry_dequeue_pcb
*  Returned Value : oldest pcb or NULL
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

RTCSPCB_PTR   _arp_entry_dequeue_pcb(ARP_ENTRY_PTR entry_ptr)
{
   RTCSPCB_PTR rtcs_pcb = NULL;

   if (entry_ptr->QUEUED_PCBS) {
      entry_ptr->QUEUED_PCBS--;
      rtcs_pcb = entry_ptr->WAITING[entry_ptr->QUEUED_PCBS];
      entry_ptr->WAITING[entry_ptr->QUEUED_PCBS]=NULL;
   }

   return rtcs_pcb;
}

#endif

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_open
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Initializes the ARP Server on an interface.
*
*END*-----------------------------------------------------------------*/

uint_32 ARP_open
   (
      IP_IF_PTR   if_ptr
         /* [IN] IP interface structure */
   )
{ /* Body */
   ARP_CFG_PTR    arp_cfg;
   ARP_PACKET_PTR packet;

   /* Allocate an ARP cache and a statistics structure */
   arp_cfg = RTCS_mem_alloc_zero(sizeof(ARP_CFG));
   if (!arp_cfg) {
      return RTCSERR_ARP_CFG;
   } /* Endif */
   _mem_set_type(arp_cfg, MEM_TYPE_ARP_CFG);

   /* Get the interface's Ethernet address */
   #if BSP_ENET_DEVICE_COUNT > 0
   ENET_get_address(if_ptr->HANDLE, arp_cfg->LADDR);
   #endif
   /* Prebuild an ARP request */
   packet = &arp_cfg->ARP_REQUEST;
   htons(packet->LINKTYPE, ARPLINK_ETHERNET);
   htons(packet->PROTTYPE, ARPPROT_IP);
   htonc(packet->LINKLEN,  6);
   htonc(packet->PROTLEN,  4);
   htons(packet->OPCODE,   ARPOP_REQUEST);
   htone(packet->LINKSRC,  arp_cfg->LADDR);
   _mem_zero(packet->LINKDEST, 6);

   if_ptr->ARP = arp_cfg;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_close
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Shuts down the ARP Server on an interface.
*
*END*-----------------------------------------------------------------*/

uint_32 ARP_close
   (
      IP_IF_PTR   if_ptr
         /* [IN] IP interface structure */
   )
{ /* Body */
   ARP_CFG_PTR    arp_cfg;
   uint_32        hash;
   ARP_ENTRY_PTR  entry, nextentry;

   arp_cfg = if_ptr->ARP;
   for (hash = 0; hash < ARPCACHE_SIZE; hash++) {
      entry = arp_cfg->CACHE[hash];
      while (entry) {

         /*
         ** Note: this could be replaced with
         **    TCPIP_Event_cancel(&entry->EXPIRE_TIMER);
         **    ARP_expire(&entry->EXPIRE_TIMER);
         ** but this is faster
         */

         /* Cancel all timers, free all packets */
         TCPIP_Event_cancel(&entry->RESEND_TIMER);
         TCPIP_Event_cancel(&entry->AGE_TIMER);
         TCPIP_Event_cancel(&entry->EXPIRE_TIMER);

         while (ARP_ENTRY_QUEUE_SIZE(entry)) {
            RTCSPCB_PTR rtcs_pcb = ARP_ENTRY_DEQUEUE_PCB(entry);
            RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_ARP_CANT_RESOLVE);
            RTCSPCB_free(rtcs_pcb);
         } /* Endif */
         /* Enqueue the entry onto the free list */
         nextentry = entry->NEXT;
         entry->NEXT = ARP_freelist;
         ARP_freelist = entry;
         entry = nextentry;
      } /* Endwhile */
   } /* Endfor */

   _mem_free(arp_cfg);
   if_ptr->ARP = NULL;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_find
*  Returned Value : the ARP entry if found, NULL otherwise
*  Comments       :
*        Searches the ARP cache for an entry.
*
*END*-----------------------------------------------------------------*/

static ARP_ENTRY_PTR ARP_find
   (
      IP_IF_PTR      if_ptr,
         /* [IN] IP interface structure */
      _ip_address    paddr
         /* [IN] protocol address */
   )
{ /* Body */
   ARP_CFG_PTR    arp_cfg = if_ptr->ARP;
   ARP_ENTRY_PTR  arp_ptr;
   uint_32        hash;

   /* Locate the IP address in the cache */
   hash = ARPCACHE_HASH(paddr);
   for (arp_ptr = arp_cfg->CACHE[hash];
        arp_ptr;
        arp_ptr = arp_ptr->NEXT) {
      if (arp_ptr->PADDR == paddr) {
         break;
      } /* Endif */
   } /* Endfor */

   return arp_ptr;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_is_complete
*  Returned Value : TRUE if the ARP entry was found, FALSE otherwise
*  Comments       :
*        Searches the ARP cache for an entry.
*
*END*-----------------------------------------------------------------*/

boolean  ARP_is_complete
   (
      IP_IF_PTR      if_ptr,
         /* [IN] IP interface structure */
      _ip_address    addr
         /* [IN] the IP address to test */
   )
{ /* Body */

    ARP_ENTRY_PTR  arp_ptr;
  
  arp_ptr = ARP_find (if_ptr, addr);
  
  if (arp_ptr) {    
    return (arp_ptr->COMPLETE);
  }
  return FALSE;
 
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_kill_entry
*  Returned Value : Always returns FALSE (inherited from ARP_expire)
*  Comments       :
*        Searches the ARP cache for an entry. Removes it (and its PCB)
*        if found.
*
*END*-----------------------------------------------------------------*/

boolean  ARP_kill_entry
   (
      IP_IF_PTR      if_ptr,
         /* [IN] IP interface structure */
      _ip_address    addr
         /* [IN] the IP address to test */
   )
{ /* Body */

    ARP_ENTRY_PTR   arp_ptr;
    TCPIP_EVENT     dummy_event;
  
  arp_ptr = ARP_find (if_ptr, addr);
  
  if (arp_ptr) {      
     dummy_event.TIME       = 0;
     dummy_event.EVENT      = NULL;
     dummy_event.PRIVATE    = arp_ptr;
     dummy_event.NEXT       = NULL;
     
     return (ARP_expire(&dummy_event));
  }  
  return FALSE;
 
} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_find_waiting
*  Returned Value : a pointer to the PCB waiting to be sent for the ARP 
*                 : table entry related to if_ptr and paddr.
*                 
*  Comments       :
*        Searches the ARP cache for an entry. Returns a pointer to the 
*        related waiting, outbound packet or NULL if none exists
*
*        It is important that the calling application consider this
*        PCB read only. The arp system has the responsibility to 
*        expire and release the PCB. If you want to free the waiting 
*        PCB, you should use ARP_kill_entry()
*
END*-----------------------------------------------------------------*/

RTCSPCB_PTR  ARP_find_waiting
   (
      IP_IF_PTR      if_ptr,
         /* [IN] IP interface structure */
      _ip_address    addr
         /* [IN] the IP address to test */
   )
{ /* Body */

   ARP_ENTRY_PTR   arp_ptr;
  
   arp_ptr = ARP_find (if_ptr, addr);

   if (arp_ptr) {
      return (RTCSPCB_PTR)ARP_ENTRY_QUEUE_PEEK(arp_ptr);
   }
  
   return NULL;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_insert
*  Returned Value : the new ARP entry
*  Comments       :
*        Create an ARP entry.  Note: it is the caller's responsibility
*        to initialize the ARP_ENTRY's fields.
*
*END*-----------------------------------------------------------------*/

static ARP_ENTRY_PTR ARP_insert
   (
      IP_IF_PTR      if_ptr,
         /* [IN] IP interface structure */
      _ip_address    paddr
         /* [IN] protocol address */
   )
{ /* Body */
   ARP_CFG_PTR    arp_cfg = if_ptr->ARP;
   ARP_ENTRY_PTR  arp_ptr;
   uint_32        i, hash;

   /* Allocate a block of entries if none are left */
   if (!ARP_freelist) {
      arp_ptr = RTCS_mem_alloc_zero(ARPALLOC_SIZE * sizeof(ARP_ENTRY));
      if (arp_ptr) {
         _mem_set_type(arp_ptr, MEM_TYPE_ARP_ENTRY);
         for (i = 0; i < ARPALLOC_SIZE; i++) {
            arp_ptr->NEXT = ARP_freelist;
            ARP_freelist = arp_ptr;
            arp_ptr++;
         } /* Endfor */
      } /* Endif */
   } /* Endif */

   /* Dequeue a free entry */
   arp_ptr = ARP_freelist;
   if (!arp_ptr) {
      IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_ALLOCS_FAILED++);
      return NULL;
   } /* Endif */
   ARP_freelist = arp_ptr->NEXT;

   arp_ptr->PADDR                = paddr;
   arp_ptr->RESEND_TIMER.EVENT   = ARP_send;
   arp_ptr->RESEND_TIMER.PRIVATE = arp_ptr;
   arp_ptr->AGE_TIMER.EVENT      = ARP_age;
   arp_ptr->AGE_TIMER.PRIVATE    = arp_ptr;
   arp_ptr->EXPIRE_TIMER.EVENT   = ARP_expire;
   arp_ptr->EXPIRE_TIMER.PRIVATE = arp_ptr;

   /* Enqueue the new entry in the two-way list */
   hash = ARPCACHE_HASH(paddr);
   arp_ptr->HEAD = if_ptr;
   arp_ptr->PREV = NULL;
   arp_ptr->NEXT = arp_cfg->CACHE[hash];
   if (arp_ptr->NEXT) {
      arp_ptr->NEXT->PREV = arp_ptr;
   } /* Endif */
   arp_cfg->CACHE[hash] = arp_ptr;

   ARP_ENTRY_QUEUE_INIT(arp_ptr);
   return arp_ptr;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_delete
*  Returned Value : void
*  Comments       :
*        Delete an ARP entry.
*
*END*-----------------------------------------------------------------*/

static void ARP_delete
   (
      ARP_ENTRY_PTR  arp_ptr
         /* [IN] ARP entry */
   )
{ /* Body */
   ARP_CFG_PTR    arp_cfg = arp_ptr->HEAD->ARP;
   uint_32        hash;

   /* Dequeue the entry from the two-way list */
   hash = ARPCACHE_HASH(arp_ptr->PADDR);
   if (arp_ptr->NEXT) {
      arp_ptr->NEXT->PREV = arp_ptr->PREV;
   } /* Endif */
   if (arp_ptr->PREV) {
      arp_ptr->PREV->NEXT = arp_ptr->NEXT;
   } /* Endif */
   if (arp_cfg->CACHE[hash] == arp_ptr) {
      arp_cfg->CACHE[hash] = arp_ptr->NEXT;
   } /* Endif */

   /* Enqueue the entry onto the free list */
   arp_ptr->NEXT = ARP_freelist;
   ARP_freelist = arp_ptr;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_send
*  Returned Value :
*  Comments       :
*        Called by the Timer.  Send an ARP request
*
*END*-----------------------------------------------------------------*/

static boolean ARP_send
   (
      TCPIP_EVENT_PTR   event
         /* [IN/OUT] the refresh event */
   )
{ /* Body */
   ARP_ENTRY_PTR  arp_ptr = event->PRIVATE;
   ARP_CFG_PTR    arp_cfg = arp_ptr->HEAD->ARP;
   RTCSPCB_PTR    rtcs_pcb;
   ARP_PACKET_PTR packet;
   uint_32        error;

   IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_TOTAL++);
   IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_TX_REQUESTS++);

   /*
   ** Obviously, the gotos below aren't necessary; they're there to
   ** prevent the indentation level from getting ridiculously deep.
   */

   rtcs_pcb = RTCSPCB_alloc_send();
   if (!rtcs_pcb) {
      IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_MISSED++);
      goto arpsend_fail;
   } /* Endif */

   error = RTCSPCB_insert_header(rtcs_pcb, sizeof(ARP_PACKET));
   if (error) {
      IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_ERRORS++);
      IF_ARP_STATS_ENABLED(RTCS_seterror(&arp_cfg->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
      RTCSLOG_PCB_FREE(rtcs_pcb, error);
      RTCSPCB_free(rtcs_pcb);
      goto arpsend_fail;
   } /* Endif */

   RTCSLOG_PCB_WRITE(rtcs_pcb, RTCS_LOGCTRL_ARP(IPIFTYPE_ETHERNET), 0);

   packet = (ARP_PACKET_PTR)RTCSPCB_DATA(rtcs_pcb);
   _mem_copy(&arp_cfg->ARP_REQUEST, packet, sizeof(*packet));
   htonl(packet->PROTSRC,  arp_ptr->WAITADDR);
   htonl(packet->PROTDEST, arp_ptr->PADDR);

   rtcs_pcb->LINK_OPTIONS.TX = arp_ptr->WAITOPT;
   #if BSP_ENET_DEVICE_COUNT > 0
   error = IPE_send_ARP_bcast(arp_ptr->HEAD, rtcs_pcb);
   #endif
   if (error) {
      IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_ERRORS++);
      IF_ARP_STATS_ENABLED(RTCS_seterror(&arp_cfg->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
      goto arpsend_fail;
   } /* Endif */

arpsend_fail:
   arp_ptr->RESEND_INTERVAL *= 2;
   if (arp_ptr->RESEND_INTERVAL > RTCSCFG_ARPTIME_RESEND_MAX) {
      arp_ptr->RESEND_INTERVAL = RTCSCFG_ARPTIME_RESEND_MAX;
   } /* Endif */
   event->TIME = arp_ptr->RESEND_INTERVAL;
   return TRUE;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_age
*  Returned Value :
*  Comments       :
*        Called by the Timer.  Age an ARP cache entry.
*
*END*-----------------------------------------------------------------*/

static boolean ARP_age
   (
      TCPIP_EVENT_PTR   event
         /* [IN/OUT] the aging event */
   )
{ /* Body */
   ARP_ENTRY_PTR  arp_ptr = event->PRIVATE;

   /* Complete entries become aged/quiet */
   if (!arp_ptr->AGED) {
      arp_ptr->AGED = TRUE;
      arp_ptr->HIT  = FALSE;
      event->TIME   = RTCSCFG_ARPTIME_EXPIRE_INCOMPLETE;
      return TRUE;

   /* Aged entries become incomplete */
   } else {
      arp_ptr->COMPLETE = FALSE;
      return FALSE;

   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_expire
*  Returned Value :
*  Comments       :
*        Called by the Timer.  Expire an ARP cache entry.
*
*END*-----------------------------------------------------------------*/

static boolean ARP_expire
   (
      TCPIP_EVENT_PTR   event
         /* [IN/OUT] the expiration event */
   )
{ /* Body */
   ARP_ENTRY_PTR  arp_ptr = event->PRIVATE;
   ARP_CFG_PTR    arp_cfg = arp_ptr->HEAD->ARP;

   /* When an entry expires, free it and any packets queued on it */
   while (ARP_ENTRY_QUEUE_SIZE(arp_ptr)) {
      RTCSPCB_PTR rtcs_pcb = ARP_ENTRY_DEQUEUE_PCB(arp_ptr);

      IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_PKT_DISCARDS++);
      IF_ARP_STATS_ENABLED(arp_ptr->HEAD->STATS.COMMON.ST_TX_DISCARDED++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_ARP_CANT_RESOLVE);

      // pass error back to application
      if (rtcs_pcb->UDP_REQUEST) {
         RTCS_cmd_complete(rtcs_pcb->UDP_REQUEST, RTCSERR_ARP_CANT_RESOLVE);
         rtcs_pcb->UDP_REQUEST = NULL;
      } /* Endif */

      RTCSPCB_free(rtcs_pcb);
   } /* Endif */

   TCPIP_Event_cancel(&arp_ptr->RESEND_TIMER);
   TCPIP_Event_cancel(&arp_ptr->AGE_TIMER);
   
   /* 
   ** NOTE: ARP_expire may be called either from the ARP_expire timer event
   ** or possibly from ARP_kill_entry(). If we are called from ARP_kill_entry()
   ** then we MUST cancel the ARP_expire timer event. If we are called from 
   ** the ARP_expire timer event, then canceling the ARP_expire timer event 
   ** here is useless but harmless.
   ** So leave the cancle(expire timer) here even though it may look odd.
   */
   TCPIP_Event_cancel(&arp_ptr->EXPIRE_TIMER);
   
   ARP_delete(arp_ptr);

   return FALSE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_resolve
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Called by IP-E.  Translates an IP address to a physical address.
*
*END*-----------------------------------------------------------------*/

uint_32 ARP_resolve
   (
      IP_IF_PTR      if_ptr,
         /* [IN] IP interface structure */
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] packet to send */
      _ip_address    isrc,
         /* [IN] source address */
      _ip_address    idest
         /* [IN] destination address */
   )
{ /* Body */
   ARP_CFG_PTR    arp_cfg = if_ptr->ARP;
   ARP_ENTRY_PTR  arp_ptr;

   /* First check the ARP cache */
   arp_ptr = ARP_find(if_ptr, idest);

   /* If there's no entry, create an incomplete one */
   if (!arp_ptr) {

      arp_ptr = ARP_insert(if_ptr, idest);
      if (!arp_ptr) {
         IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_PKT_DISCARDS++);
         RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_ARP_CANT_RESOLVE);
         RTCSPCB_free(rtcs_pcb);

      } else {
         ARP_ENTRY_ENQUEUE_PCB(arp_ptr, rtcs_pcb);
         arp_ptr->WAITADDR = isrc;
         arp_ptr->WAITOPT  = rtcs_pcb->LINK_OPTIONS.TX;
         arp_ptr->COMPLETE = FALSE;
         ARP_REFRESH(arp_ptr);
      } /* Endif */

      IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_CACHE_MISSES++);
      return RTCS_OK;

   /* If there's an incomplete entry, queue the packet */
   } else if (!arp_ptr->COMPLETE) {

      if (ARP_ENTRY_QUEUE_FULL(arp_ptr)) {
         RTCSPCB_PTR oldest_rtcs_pcb = ARP_ENTRY_DEQUEUE_PCB(arp_ptr);

         IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_PKT_DISCARDS++);
         IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_DISCARDED++);
         RTCSLOG_PCB_FREE(oldest_rtcs_pcb, RTCSERR_ARP_CANT_RESOLVE);
         RTCSPCB_free(oldest_rtcs_pcb);
      } /* Endif */
      ARP_ENTRY_ENQUEUE_PCB(arp_ptr, rtcs_pcb);
      arp_ptr->WAITADDR = isrc;
      arp_ptr->WAITOPT  = rtcs_pcb->LINK_OPTIONS.TX;
      IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_CACHE_MISSES++);
      return RTCS_OK;
   
   } /* Endif */
   
   /* If there's a complete entry, send the packet */
   /* If the entry is about to expire, try to refresh it */
   if (arp_ptr->AGED && !arp_ptr->HIT) {
      arp_ptr->HIT = TRUE;
      TCPIP_Event_cancel(&arp_ptr->EXPIRE_TIMER);
      arp_ptr->WAITADDR = isrc;
      arp_ptr->WAITOPT  = rtcs_pcb->LINK_OPTIONS.TX;
      ARP_REFRESH(arp_ptr);
   } /* Endif */

   IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_CACHE_HITS++);
   #if BSP_ENET_DEVICE_COUNT > 0
   return IPE_send_IP_ucast(if_ptr, rtcs_pcb, arp_ptr->LADDR);
   #else
   return RTCS_OK;
   #endif 
} /* Endbody */


/*FUNCTION*------------------------------------------------------------- *
 * Function Name : ARP_gratuitous_send
 * Returned Value :
 * Comments :
 * Send a gratuitous ARP reply
 * 
 *END*-----------------------------------------------------------------*/ 
 
static boolean ARP_gratuitous_send 
( 
   TCPIP_EVENT_PTR event 
   /* [IN/OUT] the refresh event */ ) 
{ /* Body */ 
   ARP_ENTRY_PTR arp_ptr = event->PRIVATE; 
   ARP_CFG_PTR arp_cfg = arp_ptr->HEAD->ARP; 
   RTCSPCB_PTR rtcs_pcb; 
   ARP_PACKET_PTR packet; 
   uint_32 error; 

   IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_TOTAL++); 
   IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_TX_REQUESTS++); 

   do {
      rtcs_pcb = RTCSPCB_alloc_send(); 
      if (!rtcs_pcb) { 
         IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_MISSED++); 
         break; 
      } /* Endif */ 
   
      error = RTCSPCB_insert_header(rtcs_pcb, sizeof(ARP_PACKET)); 
      if (error) { 
         IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_ERRORS++); 
         IF_ARP_STATS_ENABLED(RTCS_seterror(&arp_cfg->STATS.ERR_TX, error, (uint_32)rtcs_pcb)); 
         RTCSLOG_PCB_FREE(rtcs_pcb, error); 
         RTCSPCB_free(rtcs_pcb); 
         break; 
      } /* Endif */ 
   
      RTCSLOG_PCB_WRITE(rtcs_pcb, RTCS_LOGCTRL_ARP(IPIFTYPE_ETHERNET), 0); 
      packet = (ARP_PACKET_PTR)RTCSPCB_DATA(rtcs_pcb); 
      _mem_copy(&arp_cfg->ARP_REQUEST, packet, sizeof(*packet));
      
      htonl(packet->PROTSRC, arp_ptr->WAITADDR); 
      htonl(packet->PROTDEST, arp_ptr->PADDR); 
      rtcs_pcb->LINK_OPTIONS.TX = arp_ptr->WAITOPT; 
   
      // Change opcode to a reply and send. 
      htons(packet->OPCODE, ARPOP_REPLY);
      #if BSP_ENET_DEVICE_COUNT > 0
      error = IPE_send_ARP_bcast(arp_ptr->HEAD, rtcs_pcb); 
      #endif
   
      if (error) { 
         IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_ERRORS++); 
         IF_ARP_STATS_ENABLED(RTCS_seterror(&arp_cfg->STATS.ERR_TX, error, (uint_32)rtcs_pcb)); 
         break; 
      } /* Endif */ 
   } while (0);
    
   arp_ptr->RESEND_INTERVAL *= 2; 
   
   if (arp_ptr->RESEND_INTERVAL > RTCSCFG_ARPTIME_RESEND_MAX) { 
      arp_ptr->RESEND_INTERVAL = RTCSCFG_ARPTIME_RESEND_MAX; 
   } /* Endif */ 
   
   event->TIME = arp_ptr->RESEND_INTERVAL; 

   return TRUE; 
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_request
*  Returned Value : RTCS_OK or error code
*  Comments       :
*                 : send an arp request for a given IP.
*
*END*-----------------------------------------------------------------*/

uint_32 ARP_request
   (
      IP_IF_PTR      if_ptr,
         /* [IN] IP interface structure */
      _ip_address    isrc,
         /* [IN] source address */
      _ip_address    idest
         /* [IN] destination address */
   )
{ /* Body */
   ARP_CFG_PTR    arp_cfg = if_ptr->ARP;
   ARP_ENTRY_PTR  arp_ptr;
 
   /* First check the ARP cache */
   arp_ptr = ARP_find(if_ptr, idest);

   /* If there's no entry, create an incomplete one */
   if (!arp_ptr) {
   
      IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_CACHE_MISSES++);
      arp_ptr = ARP_insert(if_ptr, idest);
      if (!arp_ptr) {
         IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_MISSED++);
         return RTCSERR_OUT_OF_MEMORY;
      } else {
         ARP_ENTRY_QUEUE_INIT(arp_ptr);  
         arp_ptr->WAITADDR = isrc;     
         arp_ptr->COMPLETE = FALSE;         
         
         /* send request now (don't queue it for later) */                                  
         ARP_send(&(arp_ptr->RESEND_TIMER));
      } /* Endif */   
   } /* Endif */

   /* Check if we should also do a gratuitous send of a reply packet */
   if (isrc == idest) {
      /* send request now (don't queue it for later) */ 
      ARP_gratuitous_send(&(arp_ptr->RESEND_TIMER)); 
   } /* Endif */ 
   
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_service
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Processes received ARP packets.
*
*END*-----------------------------------------------------------------*/

void ARP_service
   (
      RTCSPCB_PTR    rtcs_pcb
         /* [IN] ARP packet */
   )
{ /* Body */
   IP_IF_PTR      if_ptr;
   ARP_CFG_PTR    arp_cfg;
   ARP_ENTRY_PTR  arp_ptr;
   ARP_PACKET_PTR packet;
   uint_16        opcode;
   uchar          rladdr[6];
   _ip_address    lpaddr, rpaddr;
   boolean        merge;
   uint_32        error;

   if_ptr = rtcs_pcb->IFSRC;
   arp_cfg = if_ptr->ARP;
   IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_RX_TOTAL++);
   packet = (ARP_PACKET_PTR)RTCSPCB_DATA(rtcs_pcb);
   opcode = ntohs(packet->OPCODE);

   RTCSLOG_PCB_READ(rtcs_pcb, RTCS_LOGCTRL_ARP(IPIFTYPE_ETHERNET), 0);

   /* Validate the packet */
   if ((ntohs(packet->LINKTYPE) != ARPLINK_ETHERNET)
    || (ntohs(packet->PROTTYPE) != ARPPROT_IP)
    || (ntohc(packet->LINKLEN)  != 6)
    || (ntohc(packet->PROTLEN)  != 4)
    || ((opcode != ARPOP_REQUEST)
     && (opcode != ARPOP_REPLY))) {
      IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_RX_DISCARDED++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_ARP_BAD_HEADER);
      RTCSPCB_free(rtcs_pcb);
      return;
   } /* Endif */

   ntohe(packet->LINKSRC, rladdr);
   rpaddr = ntohl(packet->PROTSRC);
   lpaddr = ntohl(packet->PROTDEST);

   /* If we have an entry, update it */
   arp_ptr = ARP_find(if_ptr, rpaddr);
   if (!arp_ptr) {
      merge = FALSE;
   } else {
      TCPIP_Event_cancel(&arp_ptr->RESEND_TIMER);
      TCPIP_Event_cancel(&arp_ptr->AGE_TIMER);
      TCPIP_Event_cancel(&arp_ptr->EXPIRE_TIMER);
      ARP_COMPLETE(arp_ptr, rladdr);

      while (ARP_ENTRY_QUEUE_SIZE(arp_ptr)) {
         RTCSPCB_PTR queued_rtcs_pcb = ARP_ENTRY_DEQUEUE_PCB(arp_ptr);

         #if BSP_ENET_DEVICE_COUNT > 0
         error = IPE_send_IP_ucast(if_ptr,queued_rtcs_pcb, rladdr);
         #endif
      } /* Endif */

      merge = TRUE;
   } /* Endif */

   if (IP_is_local(if_ptr, lpaddr) || ARP_do_proxy(if_ptr, lpaddr)) {

      /* If we're the target and we don't have an entry, create one */
      if (!merge) {
         arp_ptr = ARP_insert(if_ptr, rpaddr);
         if (arp_ptr) {
            ARP_COMPLETE(arp_ptr, rladdr);
            ARP_ENTRY_QUEUE_INIT(arp_ptr);
         } else {
            IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_RX_MISSED++);
         } /* Endif */
      } /* Endif */

      /* If it's a request for us, reply */
    if (opcode == ARPOP_REQUEST)
    {
        IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_RX_REQUESTS++);
        IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_TOTAL++);
        IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_TX_REPLIES++);

        RTCSLOG_PCB_WRITE(rtcs_pcb, RTCS_LOGCTRL_ARP(IPIFTYPE_ETHERNET), 0);

        htons(packet->OPCODE, ARPOP_REPLY);
        htone(packet->LINKSRC,  arp_cfg->LADDR);
        htonl(packet->PROTSRC,  lpaddr);
        htone(packet->LINKDEST, rladdr);
        htonl(packet->PROTDEST, rpaddr);
        
        /* rtcs_pcb was allocated for receiving, we need to convert it for sending.
        * RTCSPCB_fork() failing isn't a serious error, so we don't check
        * the error code.*/ 
        RTCSPCB_fork(rtcs_pcb); 
        
        #if BSP_ENET_DEVICE_COUNT > 0 
        error = IPE_send_ARP_ucast(if_ptr, rtcs_pcb, rladdr);
        if (error) {
            IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_TX_ERRORS++);
            IF_ARP_STATS_ENABLED(RTCS_seterror(&arp_cfg->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
            return;
        } 
        #endif
    } 
    else
    {
        IF_ARP_STATS_ENABLED(arp_cfg->STATS.ST_RX_REPLIES++);
        RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
        RTCSPCB_free(rtcs_pcb);
    } 

   } else {
      IF_ARP_STATS_ENABLED(arp_cfg->STATS.COMMON.ST_RX_DISCARDED++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
      RTCSPCB_free(rtcs_pcb);
   } /* Endif */

} /* Endbody */


#if 1

#include <fio.h>
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_display_entry
*  Returned Value : 
*  Comments       :
*        Display the ARP cache for an interface.
*
*END*-----------------------------------------------------------------*/


static void ARP_display_entry
   (
      ARP_ENTRY_PTR  arp_ptr
   )
{
   uint_32 i;

   printf("%03d.%03d.%03d.%03d ",IPBYTES(arp_ptr->PADDR));
   for (i=0;i<6;i++) printf("%02x%c",arp_ptr->LADDR[i],(i==5?' ':':'));

    if (arp_ptr->COMPLETE) {
       printf("C%c%c ", arp_ptr->AGED?'A':' ',arp_ptr->HIT?'H':' ' ); 
   } else {
       printf("I--" );
   }

    printf("Resend=%d, Age=%d, Expire=%d\n", 
        arp_ptr->RESEND_TIMER.TIME, arp_ptr->AGE_TIMER.TIME, arp_ptr->EXPIRE_TIMER.TIME);
}



void ARPIF_add
   (
      ARPIF_PARM_PTR  parms
   )
{
    ARP_ENTRY_PTR  arp_ptr; 
   
    if (parms->ihandle==NULL)
    { 
        RTCSCMD_complete(parms, RTCS_HANDLE_ERROR); 
    } 
  
    arp_ptr = ARP_find(parms->ihandle, parms->PADDR); 
    if (!arp_ptr)
    { 
        arp_ptr = ARP_insert(parms->ihandle, parms->PADDR); 
        if (!arp_ptr)
        { 
            RTCSCMD_complete(parms, RTCSERR_OUT_OF_MEMORY); 
        } 
    } 
    else
    { 
        /* Merge. */
        TCPIP_Event_cancel(&arp_ptr->RESEND_TIMER); 
        TCPIP_Event_cancel(&arp_ptr->AGE_TIMER); 
        TCPIP_Event_cancel(&arp_ptr->EXPIRE_TIMER); 
    } 
    ARP_COMPLETE(arp_ptr, parms->LADDR);   
    
    RTCSCMD_complete(parms, RTCS_OK);
}

void ARPIF_delete
   (
      ARPIF_PARM_PTR  parms
   )
{
    if (parms->ihandle==NULL) {
       RTCSCMD_complete(parms, RTCS_HANDLE_ERROR);
    }
  
    if (!ARP_kill_entry(parms->ihandle, parms->PADDR)) {
      RTCSCMD_complete(parms, RTCSERR_INVALID_ADDRESS);
    }
    RTCSCMD_complete(parms, RTCS_OK);
}
#endif


#endif /* RTCSCFG_ENABLE_IP4 */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ARP_display_if_table
*  Returned Value : 
*  Comments       :
*        Display the ARP cache for an interface.
*
*END*-----------------------------------------------------------------*/

void ARP_display_if_table(_rtcs_if_handle   ihandle)
{ /* Body */
   
   #if RTCSCFG_ENABLE_IP4
   
   IP_IF_PTR      if_ptr = (IP_IF_PTR) ihandle;
   ARP_CFG_PTR    arp_cfg ;
   ARP_ENTRY_PTR  arp_ptr;
   uint_32        i;

   if (if_ptr==NULL) return;

   arp_cfg = if_ptr->ARP;
   for (i=0;i<ARPCACHE_SIZE;i++) {
      arp_ptr = arp_cfg->CACHE[i];
      while (arp_ptr != NULL) {
         ARP_display_entry(arp_ptr);
         arp_ptr = arp_ptr->NEXT;
       }
   }
   
   #endif /* RTCSCFG_ENABLE_IP4 */
   
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/audio/usb_host_audio.h<|end_filename|>
#ifndef __usb_host_audio_h__
#define __usb_host_audio_h__
/**HEADER********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_audio.h$
* $Version :
* $Date    :
*
* Comments:
*
*   This file defines a template structure for Audio Class Driver.
*
*END************************************************************************/
#include <mqx.h>
#include <lwevent.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_main.h"
#include "host_snd.h"
#include "host_rcv.h"
#include "host_ch9.h"

#define SET_REQUEST_ITF                  (0x21)
#define SET_REQUEST_EP                   (0x22)
#define GET_REQUEST_ITF                  (0xA1)
#define GET_REQUEST_EP                   (0xA2)

/* Audio class codes */
#define REQUEST_CODE_UNDEFINED           (0x00)
#define SET_CUR                          (0x01)
#define GET_CUR                          (0x81)
#define SET_MIN                          (0x02)
#define GET_MIN                          (0x82)
#define SET_MAX                          (0x03)
#define GET_MAX                          (0x83)
#define SET_RES                          (0x04)
#define GET_RES                          (0x84)
#define SET_MEM                          (0x05)
#define GET_MEM                          (0x85)
#define GET_STAT                         (0xFF)

/* FU Command codes*/
#define USB_AUDIO_GET_CUR_MUTE           (0x00)
#define USB_AUDIO_SET_CUR_MUTE           (0x01)
#define USB_AUDIO_GET_CUR_VOLUME         (0x02)
#define USB_AUDIO_SET_CUR_VOLUME         (0x03)
#define USB_AUDIO_GET_MIN_VOLUME         (0x04)
#define USB_AUDIO_SET_MIN_VOLUME         (0x05)
#define USB_AUDIO_GET_MAX_VOLUME         (0x06)
#define USB_AUDIO_SET_MAX_VOLUME         (0x07)
#define USB_AUDIO_GET_RES_VOLUME         (0x08)
#define USB_AUDIO_SET_RES_VOLUME         (0x09)
#define USB_AUDIO_GET_CUR_BASS           (0x0A)
#define USB_AUDIO_SET_CUR_BASS           (0x0B)
#define USB_AUDIO_GET_MIN_BASS           (0x0C)
#define USB_AUDIO_SET_MIN_BASS           (0x0D)
#define USB_AUDIO_GET_MAX_BASS           (0x0E)
#define USB_AUDIO_SET_MAX_BASS           (0x0F)
#define USB_AUDIO_GET_RES_BASS           (0x10)
#define USB_AUDIO_SET_RES_BASS           (0x11)
#define USB_AUDIO_GET_CUR_MID            (0x12)
#define USB_AUDIO_SET_CUR_MID            (0x13)
#define USB_AUDIO_GET_MIN_MID            (0x14)
#define USB_AUDIO_SET_MIN_MID            (0x15)
#define USB_AUDIO_GET_MAX_MID            (0x16)
#define USB_AUDIO_SET_MAX_MID            (0x17)
#define USB_AUDIO_GET_RES_MID            (0x18)
#define USB_AUDIO_SET_RES_MID            (0x19)
#define USB_AUDIO_GET_CUR_TREBLE         (0x1A)
#define USB_AUDIO_SET_CUR_TREBLE         (0x1B)
#define USB_AUDIO_GET_MIN_TREBLE         (0x1C)
#define USB_AUDIO_SET_MIN_TREBLE         (0x1D)
#define USB_AUDIO_GET_MAX_TREBLE         (0x1E)
#define USB_AUDIO_SET_MAX_TREBLE         (0x1F)
#define USB_AUDIO_GET_RES_TREBLE         (0x20)
#define USB_AUDIO_SET_RES_TREBLE         (0x21)
#define USB_AUDIO_GET_CUR_AGC            (0x22)
#define USB_AUDIO_SET_CUR_AGC            (0x23)
#define USB_AUDIO_GET_CUR_DELAY          (0x24)
#define USB_AUDIO_SET_CUR_DELAY          (0x25)
#define USB_AUDIO_GET_MIN_DELAY          (0x26)
#define USB_AUDIO_SET_MIN_DELAY          (0x27)
#define USB_AUDIO_GET_MAX_DELAY          (0x28)
#define USB_AUDIO_SET_MAX_DELAY          (0x29)
#define USB_AUDIO_GET_RES_DELAY          (0x2A)
#define USB_AUDIO_SET_RES_DELAY          (0x2B)
#define USB_AUDIO_GET_CUR_BASS_BOOST     (0x2C)
#define USB_AUDIO_SET_CUR_BASS_BOOST     (0x2D)

/* Terminal Control Selectors */
#define TE_CONTROL_UNDEFINED             (0x00)
#define COPY_PROTECT_CONTROL             (0x01)

/* Endpoint Control Selectors */
#define EP_CONTROL_UNDEFINED             (0x00)
#define SAMPLING_FREQ_CONTROL            (0x01)
#define PITCH_CONTROL                    (0x02)

#define SAMPLING_FREQ_MASK               (0x01)
#define PITCH_MASK                       (0x02)

/* Endpoint Command Codes*/
#define USB_AUDIO_GET_CUR_PITCH          (0x00)
#define USB_AUDIO_SET_CUR_PITCH          (0x01)
#define USB_AUDIO_GET_CUR_SAMPLING_FREQ  (0x02)
#define USB_AUDIO_SET_CUR_SAMPLING_FREQ  (0x03)
#define USB_AUDIO_GET_MIN_SAMPLING_FREQ  (0x04)
#define USB_AUDIO_SET_MIN_SAMPLING_FREQ  (0x05)
#define USB_AUDIO_GET_MAX_SAMPLING_FREQ  (0x06)
#define USB_AUDIO_SET_MAX_SAMPLING_FREQ  (0x07)
#define USB_AUDIO_GET_RES_SAMPLING_FREQ  (0x08)
#define USB_AUDIO_SET_RES_SAMPLING_FREQ  (0x09)

#define NUMBER_OF_FEATURE_COMMANDS       (0x2E)
#define NUMBER_OF_ENDPOINT_COMMANDS      (0x0A)

/* audio command struct */
typedef struct {
    uint_8   control_mask;
    uint_8   request_type;
    uint_8   request_code;
    uint_8   request_value;
    uint_8   length;
} USB_AUDIO_COMMAND, _PTR_ USB_AUDIO_COMMAND_PTR;


/* Receive interrupt state */
typedef struct {
    uint_8       Status;
    uint_8		 Originator;
} USB_AUDIO_CONTROL_STATUS, _PTR_ USB_AUDIO_CONTROL_STATUS_PTR;


/* Audio Control Subclass */
/* Header descriptor */
#define USB_DESC_SUBTYPE_AUDIO_CS_HEADER           0x01
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bcdCDC[2];
    uint_8	 wTotalLength[2];
    uint_8   bInCollection;
} USB_AUDIO_CTRL_DESC_HEADER, _PTR_ USB_AUDIO_CTRL_DESC_HEADER_PTR;

/* Input Terminal descriptor */
#define USB_DESC_SUBTYPE_AUDIO_CS_IT               0x02
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bTerminalID;
    uint_8   wTerminalType[2];
    uint_8   bAssocTerminal;
    uint_8   bNrChannels;
    uint_8   wChannelConfig[2];
    uint_8   iChannelNames;
    uint_8   iTerminal;
} USB_AUDIO_CTRL_DESC_IT, _PTR_ USB_AUDIO_CTRL_DESC_IT_PTR;

/* Output Terminal descriptor */
#define USB_DESC_SUBTYPE_AUDIO_CS_OT               0x03
typedef struct {
    uint_8   bFunctionLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bTerminalID;
    uint_8   wTerminalType[2];
    uint_8   bAssocTerminal;
    uint_8   bSourceID;
    uint_8   iTerminal;
} USB_AUDIO_CTRL_DESC_OT, _PTR_ USB_AUDIO_CTRL_DESC_OT_PTR;

/* Feature Unit descriptor */
#define USB_DESC_SUBTYPE_AUDIO_CS_FU               0x06
typedef struct {
    uint_8   bLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bUnitID;
    uint_8   bSourceID;
    uint_8   bControlSize;
#define USB_AUDIO_CTRL_FU_MUTE              0x01
#define USB_AUDIO_CTRL_FU_VOLUME            0x02
#define USB_AUDIO_CTRL_FU_BASS              0x03
#define USB_AUDIO_CTRL_FU_MID               0x04
#define USB_AUDIO_CTRL_FU_TREBLE            0x05
#define USB_AUDIO_CTRL_FU_GRAPHIC_EQ        0x06
#define USB_AUDIO_CTRL_FU_AGC               0x07
#define USB_AUDIO_CTRL_FU_DELAY             0x08
#define USB_AUDIO_CTRL_FU_BASS_BOOST        0x09


#define FU_MUTE_MASK                        0x01
#define FU_VOLUME_MASK                      0x02
#define FU_BASS_MASK                        0x04
#define FU_MID_MASK                         0x08
#define FU_TREBLE_MASK                      0x10
#define FU_GRAPHIC_EQ_MASK                  0x20
#define FU_AGC_MASK                         0x40
#define FU_DELAY_MASK                       0x80
#define FU_BASS_BOOST_MASK                  0x01
    uint_8 	 bmaControls[];
    //uint_8 	 iFeature;
} USB_AUDIO_CTRL_DESC_FU, _PTR_ USB_AUDIO_CTRL_DESC_FU_PTR;

/* Audio Control function descriptor */
typedef union {
    USB_AUDIO_CTRL_DESC_HEADER         header;
    USB_AUDIO_CTRL_DESC_IT             it;
    USB_AUDIO_CTRL_DESC_OT             ot;
    USB_AUDIO_CTRL_DESC_FU             fu;
} USB_AUDIO_CTRL_FUNC_DESC, _PTR_ USB_AUDIO_CTRL_FUNC_DESC_PTR;

/*
** Audio Class Interface structure. This structure will be passed to
** all commands to this class driver.
*/
typedef struct usb_audio_general_class {
    /* Each class must start with a GENERAL_CLASS struct */
    GENERAL_CLASS                             G;

    /* Higher level callback and parameter */
    tr_callback                               USER_CALLBACK;
    pointer                                   USER_PARAM;

    uint_8                                    IFNUM;

} USB_AUDIO_GENERAL_CLASS, _PTR_ USB_AUDIO_GENERAL_CLASS_PTR;

/* Audio control subclass structure */
typedef struct {
    /* Each audio subclass must start with a USB_AUDIO_GENERAL_CLASS struct */
    USB_AUDIO_GENERAL_CLASS                   AUDIO_G;

    USB_AUDIO_CTRL_DESC_HEADER_PTR            header_desc;
    USB_AUDIO_CTRL_DESC_IT_PTR                it_desc;
    USB_AUDIO_CTRL_DESC_OT_PTR                ot_desc;
    USB_AUDIO_CTRL_DESC_FU_PTR                fu_desc;

    _usb_pipe_handle                          interrupt_pipe;
    USB_AUDIO_CONTROL_STATUS                  interrupt_buffer;

    tr_callback                               interrupt_callback;
    pointer                                   interrupt_callback_param;

#define USB_AUDIO_CTRL_DETACH           0x01
#define USB_AUDIO_CTRL_PIPE_FREE        0x02
#define USB_AUDIO_CTRL_INT_PIPE_FREE    0x04
    LWEVENT_STRUCT                            control_event;

} AUDIO_CONTROL_INTERFACE_STRUCT, _PTR_ AUDIO_CONTROL_INTERFACE_STRUCT_PTR;

/* Audio Stream Subclass */
/* Class-specific Audio stream interface descriptor */
#define USB_DESC_SUBTYPE_AS_CS_GENERAL 		0x01
typedef struct {
    uint_8   bLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bTerminalLink;
    uint_8	 bDelay;
    uint_8	 wFormatTag[2];
} USB_AUDIO_STREAM_DESC_SPEPIFIC_AS_IF, _PTR_ USB_AUDIO_STREAM_DESC_SPEPIFIC_AS_IF_PTR;

/* Format type descriptor */
#define USB_DESC_SUBTYPE_AS_CS_FORMAT_TYPE       0x02
typedef struct {
    uint_8   bLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bFormatType;
    uint_8   bNrChannels;
    uint_8   bSubFrameSize;
    uint_8   bBitResolution;
    uint_8   bSamFreqType;
    uint_8   tSamFreq[3];
} USB_AUDIO_STREAM_DESC_FORMAT_TYPE, _PTR_ USB_AUDIO_STREAM_DESC_FORMAT_TYPE_PTR;

/* Class-specific Isochronous Audio Data Endpoint Descriptor */
#define USB_DESC_CLASS_ENDPOINT_GENERAL          0x01
typedef struct {
    uint_8   bLength;
    uint_8   bDescriptorType;
    uint_8   bDescriptorSubtype;
    uint_8   bmAttributes;
    uint_8   bLockDlayUnits;
    uint_8   wLockDelay[2];
} USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP, _PTR_ USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP_PTR;


typedef struct {
	uint_8 bLength;
	uint_8 bDescriptorType;
	uint_8 bEndpointAddress;
	uint_8 bmAttributes;
	uint_8 wMaxPacketSize[2];
	uint_8 bInterval;
	uint_8 bRefresh;
} USB_AUDIO_STREAM_DESC_SYNCH_ENDP, _PTR_ USB_AUDIO_STREAM_DESC_SYNCH_ENDP_PTR;

/* Audio stream interface descriptor */
typedef union {
    USB_AUDIO_STREAM_DESC_SPEPIFIC_AS_IF         as_general;
    USB_AUDIO_STREAM_DESC_FORMAT_TYPE            frm_type;
    USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP      iso_endp_specific;
} USB_AUDIO_STREAM_FUNC_DESC, _PTR_ USB_AUDIO_STREAM_FUNC_DESC_PTR;

typedef struct {
    /* Each Audio subclass must start with a USB_AUDIO_GENERAL_CLASS struct */
    USB_AUDIO_GENERAL_CLASS                     AUDIO_G;

    USB_AUDIO_STREAM_DESC_SPEPIFIC_AS_IF_PTR    as_itf_desc;
    USB_AUDIO_STREAM_DESC_FORMAT_TYPE_PTR       frm_type_desc;
    USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP_PTR iso_endp_spec_desc;

    PIPE_STRUCT_PTR                             iso_in_pipe;
    PIPE_STRUCT_PTR                             iso_out_pipe;

#define USB_DATA_DETACH            0x01
#define USB_DATA_READ_COMPLETE     0x02
#define USB_DATA_READ_PIPE_FREE    0x04
#define USB_DATA_SEND_COMPLETE     0x08
#define USB_DATA_SEND_PIPE_FREE    0x10
    LWEVENT_STRUCT                            stream_event;

} AUDIO_STREAM_INTERFACE_STRUCT, _PTR_ AUDIO_STREAM_INTERFACE_STRUCT_PTR;

/* Audio Command */
typedef struct {
    CLASS_CALL_STRUCT_PTR   CLASS_PTR;
    tr_callback             CALLBACK_FN;
    pointer                 CALLBACK_PARAM;
} AUDIO_COMMAND, _PTR_ AUDIO_COMMAND_PTR;

#ifdef __cplusplus
extern "C" {
#endif

extern void usb_class_audio_control_init(PIPE_BUNDLE_STRUCT_PTR, CLASS_CALL_STRUCT_PTR);
extern void usb_class_audio_stream_init(PIPE_BUNDLE_STRUCT_PTR, CLASS_CALL_STRUCT_PTR);

extern CLASS_CALL_STRUCT_PTR usb_class_audio_get_ctrl_interface(pointer);

extern USB_STATUS usb_class_audio_control_get_descriptors(_usb_device_instance_handle, _usb_interface_descriptor_handle, USB_AUDIO_CTRL_DESC_HEADER_PTR _PTR_, USB_AUDIO_CTRL_DESC_IT_PTR _PTR_, USB_AUDIO_CTRL_DESC_OT_PTR _PTR_, USB_AUDIO_CTRL_DESC_FU_PTR _PTR_);
extern USB_STATUS usb_class_audio_stream_get_descriptors(_usb_device_instance_handle, _usb_interface_descriptor_handle, USB_AUDIO_STREAM_DESC_SPEPIFIC_AS_IF_PTR _PTR_,       USB_AUDIO_STREAM_DESC_FORMAT_TYPE_PTR _PTR_, USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP_PTR _PTR_);
extern USB_STATUS usb_class_audio_stream_set_descriptors(CLASS_CALL_STRUCT_PTR, USB_AUDIO_STREAM_DESC_SPEPIFIC_AS_IF_PTR, USB_AUDIO_STREAM_DESC_FORMAT_TYPE_PTR, USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP_PTR);
extern USB_STATUS usb_class_audio_control_set_descriptors(CLASS_CALL_STRUCT_PTR, USB_AUDIO_CTRL_DESC_HEADER_PTR, USB_AUDIO_CTRL_DESC_IT_PTR, USB_AUDIO_CTRL_DESC_OT_PTR, USB_AUDIO_CTRL_DESC_FU_PTR);

extern USB_STATUS usb_audio_recv_data(CLASS_CALL_STRUCT_PTR, CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uint_32, uchar_ptr);
extern USB_STATUS usb_audio_send_data(CLASS_CALL_STRUCT_PTR, CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uint_32, uchar_ptr);

extern USB_STATUS usb_class_audio_init_ipipe(CLASS_CALL_STRUCT_PTR,tr_callback,pointer);

extern USB_STATUS usb_class_audio_get_copy_protect(AUDIO_COMMAND_PTR,pointer);
extern USB_STATUS usb_class_audio_set_copy_protect(AUDIO_COMMAND_PTR,pointer);

extern USB_STATUS usb_class_audio_feature_command(AUDIO_COMMAND_PTR,uint_8,pointer,uint_32);

extern USB_STATUS usb_class_audio_get_cur_graphic_eq(AUDIO_COMMAND_PTR,uint_16,uint_8,pointer);
extern USB_STATUS usb_class_audio_set_cur_graphic_eq(AUDIO_COMMAND_PTR,uint_16,uint_8,pointer);

extern USB_STATUS usb_class_audio_get_min_graphic_eq(AUDIO_COMMAND_PTR,uint_16,uint_8,pointer);
extern USB_STATUS usb_class_audio_set_min_graphic_eq(AUDIO_COMMAND_PTR,uint_16,uint_8,pointer);

extern USB_STATUS usb_class_audio_get_max_graphic_eq(AUDIO_COMMAND_PTR,uint_16,uint_8,pointer);
extern USB_STATUS usb_class_audio_set_max_graphic_eq(AUDIO_COMMAND_PTR,uint_16,uint_8,pointer);

extern USB_STATUS usb_class_audio_get_res_graphic_eq(AUDIO_COMMAND_PTR,uint_16,uint_8,pointer);
extern USB_STATUS usb_class_audio_set_res_graphic_eq(AUDIO_COMMAND_PTR,uint_16,uint_8,pointer);

extern USB_STATUS usb_class_audio_endpoint_command(AUDIO_COMMAND_PTR,pointer,uint_32);

extern USB_STATUS usb_class_audio_get_mem_endpoint(AUDIO_COMMAND_PTR,uint_16,uint_16,pointer);
extern USB_STATUS usb_class_audio_set_mem_endpoint(AUDIO_COMMAND_PTR,uint_16,uint_16,pointer);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/rtos/mqx/mqx_host.h<|end_filename|>
#ifndef __mqx_host_h__
#define __mqx_host_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mqx_host.h$
* $Version : 3.8.12.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains generic and OHCI-specific implementations of USB
*   interfaces
*
*END************************************************************************/

#include "host_common.h"
#include "usb_mqx.h"
#include "usb_bsp.h"

/*
**
** Low-level function list structure for USB
**
** This is the structure used to store chip specific functions to be called 
** by generic layer
*/
typedef struct usb_host_callback_functions_struct
{
   /* The Host/Device pre-init function */
   USB_STATUS (_CODE_PTR_ HOST_PREINIT)(_usb_host_handle _PTR_);

   /* The Host/Device init function */
   USB_STATUS (_CODE_PTR_ HOST_INIT)(_usb_host_handle);

   /* The function to shutdown the host/device */
   USB_STATUS (_CODE_PTR_ HOST_SHUTDOWN)(_usb_host_handle);

   /* The function to send data */
   USB_STATUS (_CODE_PTR_ HOST_SEND)(_usb_host_handle, struct pipe_struct _PTR_, struct tr_struct _PTR_);

   /* The function to send setup data */
   USB_STATUS (_CODE_PTR_ HOST_SEND_SETUP)(_usb_host_handle, struct pipe_struct _PTR_, struct tr_struct _PTR_);

   /* The function to receive data */
   USB_STATUS (_CODE_PTR_ HOST_RECV)(_usb_host_handle, struct pipe_struct _PTR_, struct tr_struct _PTR_);
   
   /* The function to cancel the transfer */
   USB_STATUS (_CODE_PTR_ HOST_CANCEL)(_usb_host_handle, struct pipe_struct _PTR_, struct tr_struct _PTR_);
   
   /* The function for USB bus control */
   USB_STATUS (_CODE_PTR_ HOST_BUS_CONTROL)(_usb_host_handle, uint_8);

   USB_STATUS (_CODE_PTR_ HOST_ALLOC_BANDWIDTH)(_usb_host_handle, struct pipe_struct _PTR_);

   USB_STATUS (_CODE_PTR_ HOST_FREE_CONTROLLER_RESOURCE)(_usb_host_handle, struct pipe_struct _PTR_);
  
   uint_32 (_CODE_PTR_ HOST_GET_FRAME_NUM)(_usb_host_handle);   
   
   uint_32 (_CODE_PTR_ HOST_GET_MICRO_FRAME_NUM)(_usb_host_handle);   
   
   USB_STATUS (_CODE_PTR_ HOST_OPEN_PIPE)(_usb_host_handle, struct pipe_struct _PTR_);
   
   USB_STATUS (_CODE_PTR_ HOST_UPDATE_MAX_PACKET_SIZE)(_usb_host_handle, struct pipe_struct _PTR_);
   
   USB_STATUS (_CODE_PTR_ HOST_UPDATE_DEVICE_ADDRESS)(_usb_host_handle, struct pipe_struct _PTR_);

} USB_HOST_CALLBACK_FUNCTIONS_STRUCT, _PTR_ USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR;

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sdcard/sdcard_prv.h<|end_filename|>
#ifndef __sdcard_prv_h__
#define __sdcard_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sdcard_prv.h$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions private to the SD card.
*
*END************************************************************************/


#include "sdcard.h"


/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/


/* Properties of device */
#define IO_SDCARD_ATTRIBS  (IO_DEV_ATTR_READ | IO_DEV_ATTR_REMOVE | IO_DEV_ATTR_SEEK | IO_DEV_ATTR_WRITE | IO_DEV_ATTR_BLOCK_MODE)


/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/

/*
** IO_SDCARD STRUCT
**
** The address of this structure is used to maintain SD card specific 
** information.
*/
typedef struct io_sdcard_struct
{
   /* Init struct pointer */
   SDCARD_INIT_STRUCT_PTR INIT;

   /* The low level SD communication file descriptor */
   MQX_FILE_PTR           COM_DEVICE;

   /* Light weight semaphore struct */
   LWSEM_STRUCT           LWSEM;

   /* The low level response timeout >= 250 ms */
   uint_32                TIMEOUT;

   /* The number of blocks for the device */
   uint_32                NUM_BLOCKS;

   /* High capacity = block addressing */
   boolean                SDHC;

   /* Specification 2 or later card = different CSD register */
   boolean                VERSION2;

   /* Card address */
   uint_32                ADDRESS;

} SDCARD_STRUCT, _PTR_ SDCARD_STRUCT_PTR;


/* Internal functions to SD */
#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_sdcard_open(MQX_FILE_PTR, char_ptr, char_ptr);
extern _mqx_int _io_sdcard_close(MQX_FILE_PTR);
extern _mqx_int _io_sdcard_write_blocks(MQX_FILE_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_sdcard_read_blocks (MQX_FILE_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_sdcard_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);

extern uint_32  _io_sdcard_csd_capacity(uint_8 *);
extern uint_32  _io_sdcard_csd_baudrate(uint_8 *);

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/include/khci/khci_usbprv.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: khci_usbprv.h$
* $Version : 3.8.8.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the private defines, externs and data structure
*   definitions required by the Full Speed USB Device driver.
*
*END************************************************************************/

#ifndef __khci_dev_usbprv_h__
#define __khci_dev_usbprv_h__ 1

#include "dev_cnfg.h"
#include "devapi.h"
#include "dev_main.h"

#if PSP_MQX_CPU_IS_MCF51JM
   #define  USB_MAX_ENDPOINTS                (4)
   #define  MAX_XDS_FOR_TR_CALLS             (8) 
#else
   #define  USB_MAX_ENDPOINTS                (16) 
   #define  MAX_XDS_FOR_TR_CALLS             (32) 
#endif

#define  MAX_USB_DEVICES                     (1)
#define ODD_BUFF                             (1)
#define EVEN_BUFF                            (0)

#define BDT_BASE                ((uint_32*)(bdt))
#define BD_PTR(ep, rxtx, odd)   (((uint_32)BDT_BASE) & 0xfffffe00 | ((ep & 0x0f) << 5) | ((rxtx & 1) << 4) | ((odd & 1) << 3))

#define BD_CTRL(ep,rxtx,odd)    (*((uint_32*)BD_PTR(ep, rxtx, odd)))
#define BD_CTRL_RX(ep, odd)     (*((uint_32*)BD_PTR(ep, 0, odd)))
#define BD_CTRL_TX(ep, odd)     (*((uint_32*)BD_PTR(ep, 1, odd)))

#define BD_ADDR(ep,rxtx,odd)    (*((uint_32*)BD_PTR(ep, rxtx, odd) + 1))
#define BD_ADDR_RX(ep, odd)     (*((uint_32*)BD_PTR(ep, 0, odd) + 1))
#define BD_ADDR_TX(ep, odd)     (*((uint_32*)BD_PTR(ep, 1, odd) + 1))

/* Define USB buffer descriptor definitions in case of their lack */
#ifndef USB_BD_BC
#   define USB_BD_BC(n)                 ((n & 0x3ff) << 16)
#   define USB_BD_OWN                   0x80
#   define USB_BD_DATA01(n)             ((n & 1) << 6)
#   define USB_BD_DATA0                 USB_BD_DATA01(0)
#   define USB_BD_DATA1                 USB_BD_DATA01(1)
#   define USB_BD_KEEP                  0x20
#   define USB_BD_NINC                  0x10
#   define USB_BD_DTS                   0x08
#   define USB_BD_STALL                 0x04
#   define USB_BD_PID(n)                ((n & 0x0f) << 2)
#endif

#ifndef USB_TOKEN_TOKENPID_SETUP
#   define USB_TOKEN_TOKENPID_OUT                   USB_TOKEN_TOKENPID(0x1)
#   define USB_TOKEN_TOKENPID_IN                    USB_TOKEN_TOKENPID(0x9)
#   define USB_TOKEN_TOKENPID_SETUP                 USB_TOKEN_TOKENPID(0xD)
#endif

typedef struct khci_xd_struct 
{
   struct xd_struct G;

   boolean      ZERO_PACKET;
   uint_32      WPOSITION;       /* current position of the buffer */
   uint_32      FIFO_SIZE;       /* To keep track of FIFO length for this ep */
   uint_32      IN_FIFO_ADDR;    /* To keep track of FIFO start address for this ep */
   uint_32      OUT_FIFO_ADDR;   /* To keep track of FIFO start address for this ep */   
   uint_8       VECTOR;          /* Vector of this endpoint */
   uchar        SETUP[8];        /* Just maintain SETUP packet */

   pointer      MY_XDPTR;        /* This will save the xd_ptr send by API during send/ recv request */
   uchar_ptr    OUT_TEMP_BUFFER; /* This is required during OUT interrupt to store OUT data */
   boolean      IS_SETUP_PACKET; /* To identify SETUP packet. this is required when 
                                 ** there is setup packet and upper driver does not want 
                                 ** to send the data in the  data phase, we still need to 
                                 ** set the CMD_OVER to indicate that the processing of 
                                 ** class/vendor specific request is completed.
                                 */
   uint_16      PENDING_XD; /* counter */
   
   SCRATCH_STRUCT_PTR SCRATCH_PTR;
} KHCI_XD_STRUCT, _PTR_ KHCI_XD_STRUCT_PTR;

typedef struct _usb_xd_queue
{
   struct xd_struct _PTR_ xd_head_ptr;
   struct xd_struct _PTR_ xd_tail_ptr;
} USB_XD_QUEUE, _PTR_ USB_XD_QUEUE_PTR;

typedef struct _usb_ep_info_struct
{
   USB_XD_QUEUE xd_queue_send;  /* FIFO queue for all XDs on this endpoint */   
   USB_XD_QUEUE xd_queue_recv;
   uint_8 type;
   uint_8 direction; /* for _usb_device_call_service */
   uint_16 max_packet_size;
   uint_16 fifo_length;
   
   uint_8 tx_data0;
   uint_8 rx_data0;
   
   uint_8 tx_buf_odd;
   uint_8 rx_buf_odd;   /* next buffer is odd */
   uint_8_ptr data_buffer;
   uint_16 endpoint_status;
   boolean stall_flag;
   /* Endpoint initialization flag for both direction */
   boolean ep_init_flag[2]; 
   uint_32 save_recv_addr;
} USB_EP_INFO_STRUCT, _PTR_ USB_EP_INFO_STRUCT_PTR;

/* The USB Device State Structure */
typedef struct _usb_device_state_struct 
{
   USB_DEV_STATE_STRUCT             G;
   USB_EP_INFO_STRUCT               EP_INFO[USB_MAX_ENDPOINTS];
} USB_KHCI_DEV_STATE_STRUCT, _PTR_ USB_KHCI_DEV_STATE_STRUCT_PTR;

#define USB_XD_QADD(head,tail,XD)            \
   if ((head) == NULL) {                     \
      (head) = (XD);                         \
   } else {                                  \
      (tail)->SCRATCH_PTR->PRIVATE = (XD);   \
   } /* Endif */                             \
   (tail) = (XD);                            \
   (XD)->SCRATCH_PTR->PRIVATE = NULL
   
#define USB_XD_QGET(head,tail,XD)                              \
   (XD) = (head);                                              \
   if (head) {                                                 \
      (head) = (XD_STRUCT_PTR)((head)->SCRATCH_PTR->PRIVATE);  \
      if ((head) == NULL) {                                    \
         (tail) = NULL;                                        \
      } /* Endif */                                            \
   } /* Endif */
  
#define USB_XD_QUEUE_INIT(xd_queue_ptr)                        \
   (xd_queue_ptr)->xd_head_ptr = 0x0;                          \
   (xd_queue_ptr)->xd_tail_ptr = 0x0

#define USB_XD_QUEUE_ENQUEUE(xd_queue_ptr, xd_ptr)  \
   USB_XD_QADD ((xd_queue_ptr)->xd_head_ptr, (xd_queue_ptr)->xd_tail_ptr, (xd_ptr))
   
#define USB_XD_QUEUE_DEQUEUE(xd_queue_ptr, xd_ptr_ptr)  \
   USB_XD_QGET ((xd_queue_ptr)->xd_head_ptr, (xd_queue_ptr)->xd_tail_ptr, *(xd_ptr_ptr))
   
#define USB_XD_QUEUE_ENQUEUE_SAFE(xd_queue_ptr, xd_ptr)  \
   _int_disable ();  \
   USB_XD_QUEUE_ENQUEUE (xd_queue_ptr, xd_ptr); \
   _int_enable ();

#define USB_XD_QUEUE_DEQUEUE_SAFE(xd_queue_ptr, xd_ptr)  \
   _int_disable ();  \
   USB_XD_QUEUE_DEQUEUE (xd_queue_ptr, xd_ptr); \
   _int_enable ();

#define USB_XD_QUEUE_GET_HEAD(xd_queue_ptr, xd_ptr_ptr)  \
   *(xd_ptr_ptr) = (xd_queue_ptr)->xd_head_ptr

#define USB_XD_QUEUE_GET_TAIL(xd_queue_ptr, xd_ptr_ptr)  \
   *(xd_ptr_ptr) = (xd_queue_ptr)->xd_tail_ptr

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_writetest.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_writetest.c$
* $Version : 3.8.18.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <shell.h>
#include <mfs.h>
#include <sh_mfs.h>
#include "sh_prv.h"
#if SHELLCFG_USES_MFS
extern const char MFS_File_test_data[] ;
extern const uint_32 MFS_File_test_data_size;

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_write_test
* Returned Value   :  int_32 error code
* Comments  :  Reads from a file .
*
*END*---------------------------------------------------------------------*/
#ifndef min
   #define min(a,b) ((a)<(b)?(a):(b))
#endif

int_32  Shell_write_test(int_32 argc, char_ptr argv[] )
{
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   MQX_FILE_PTR      fd = NULL;
   char_ptr          read_buffer = NULL;
   uint_32           test_size = MFS_File_test_data_size;
   uint_32           write_size = 1,num,size,bytes_written;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   char_ptr             abs_path = NULL, filename = NULL;
   int_32               error = 0;


   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc != 2) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else  {
         read_buffer = _mem_alloc(test_size + 1);
         _mem_zero (read_buffer, test_size + 1);

         if (read_buffer==NULL)  {
            printf("Error, unable to allocate read buffer\n");
            return_code = SHELL_EXIT_ERROR;
         } else {
            if (MFS_alloc_2paths(&abs_path,&filename) != MFS_NO_ERROR) {
               printf("Error, unable to allocate memory for paths\n" );
               return_code = SHELL_EXIT_ERROR;
            }
            else
            {
               for (write_size=8;write_size<test_size;write_size=write_size<<1) {
                  printf("Test Iteration #%d ", write_size);
                  sprintf(filename,"%s_%d",argv[1],write_size);
                  error = _io_rel2abs(abs_path,shell_ptr->CURRENT_DIR,(char *) filename,PATHNAME_SIZE,shell_ptr->CURRENT_DEVICE_NAME);
                  if(!error)
                  {
                     fd = fopen(abs_path, "w");
                  }
                  if (fd == NULL || error) {
                     printf("Error, unable to open file to write\n");
                     return_code = SHELL_EXIT_ERROR;
                     break;
                  }
                  fseek(fd,0,IO_SEEK_SET);
                  bytes_written = 0;
                  while ( bytes_written<test_size) {
                     size = min(write_size,test_size-bytes_written);
                     num = write(fd, (pointer) &MFS_File_test_data[bytes_written],size);
                     if (num) {
                        bytes_written+=num;
                     } else {
                        printf("Write failed, offset = %d", bytes_written);
                       break;
                     }
                  }
                  fclose(fd);
                  fd = fopen(abs_path, "r");
                  if (fd == NULL) {
                     printf("Error, unable to open file to read\n");
                     return_code = SHELL_EXIT_ERROR;
                     break;
                  }
                  if ( read(fd,read_buffer,test_size) != test_size) {
                     printf("Error, unable to read all test data\n");
                     return_code = SHELL_EXIT_ERROR;
                     break;
                  }

                  if (strcmp(MFS_File_test_data,read_buffer)==0) {
                     printf("Passed\n");
                  } else {
                     printf("Failed\n");
                     break;
                  }
                  fclose(fd);
               }
               _mem_free(read_buffer);
               MFS_free_path(abs_path);
               MFS_free_path(filename);
            }
         }
      }
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <filename> \n", argv[0]);
      } else  {
         printf("Usage: %s <filename> \n", argv[0]);
         printf("   <filename>   = filename to verify\n");
      }
   }
   return return_code;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_write_test
* Returned Value   :  int_32 error code
* Comments  :  Reads from a file .
*
*END*---------------------------------------------------------------------*/

int_32  Shell_append_test(int_32 argc, char_ptr argv[] )
{
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   MQX_FILE_PTR      fd;
   char              filename[SHELL_MAX_FILELEN];
   char_ptr          read_buffer = NULL;
   uint_32           test_size = MFS_File_test_data_size;
   uint_32           write_size = 1,num,size,bytes_written;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   char                 abs_path[SHELL_PATHNAME_LEN];
   int_32               error = 0;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc != 2) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else  {
         read_buffer = _mem_alloc(test_size);

         if (read_buffer==NULL)  {
            printf("Error, unable to allocate read buffer\n");
            return_code = SHELL_EXIT_ERROR;
         } else {
            for (write_size=512;write_size<test_size;write_size=write_size*2) {
               printf("\nTest Iteration #%d", write_size);
               sprintf(filename,"%s_%d",argv[1],write_size);
               error = _io_rel2abs(abs_path,shell_ptr->CURRENT_DIR,(char *) filename,PATHNAME_SIZE,shell_ptr->CURRENT_DEVICE_NAME);
               bytes_written = 0;
               while ( bytes_written<test_size) {
                  fd = fopen(abs_path, "a");
                  if (fd == NULL || error) {
                     printf("Error, unable to open file to write\n");
                     return_code = SHELL_EXIT_ERROR;
                     break;
                  }
                  fseek(fd,bytes_written,IO_SEEK_SET);
                  size = min(write_size,test_size-bytes_written);
                  num = write(fd, (pointer) &MFS_File_test_data[bytes_written],size);
                  fclose(fd);
                  if (num) {
                     bytes_written+=num;
                  } else {
                     printf(" read failed, offset = %d", bytes_written);
                    break;
                  }
               }
               fd = fopen(abs_path, "r");
               if (fd == NULL || error) {
                  printf("Error, unable to open file to read\n");
                  return_code = SHELL_EXIT_ERROR;
                  break;
               }
               if ( read(fd,read_buffer,test_size) != test_size) {
                  printf("Error, unable to read all test data\n");
                  return_code = SHELL_EXIT_ERROR;
                  break;
               }

               if (strcmp(MFS_File_test_data,read_buffer)==0) {
                  printf("Passed");
               } else {
                  printf("Failed");
                  break;
               }
               fclose(fd);
            }
            _mem_free(read_buffer);
         }
      }
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <filename> \n", argv[0]);
      } else  {
         printf("Usage: %s <filename> \n", argv[0]);
         printf("   <filename>   = filename to verify\n");
      }
   }
   return return_code;
} /* Endbody */
#endif //SHELLCFG_USES_MFS


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcflash/apcflshpr.h<|end_filename|>
#ifndef _apcflshpr_h_
#define _apcflshpr_h_
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: apcflshpr.h$
* $Version : 3.8.8.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   The file contains functions prototype, defines, structure
*   definitions private to the advanced PC Card flash drivers
*
*END************************************************************************/

#include "bsp.h"
#include "ata.h"

/* Default values used unless definition is provided by apccard layer */
#ifndef APCCARD_BUS_WIDTH
#define APCCARD_BUS_WIDTH     1
#endif

#ifndef APCCARD_ADDR_SHIFT
#define APCCARD_ADDR_SHIFT    0
#endif

/* Register offsets taking address bus shift into account */
#define PCFLASH_REG_BASE            (ATA_REG_BASE << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_ERROR           (ATA_ERROR << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_FEATURES        (ATA_FEATURES << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_SECTOR_COUNT    (ATA_SECTOR_COUNT << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_SECTOR          (ATA_SECTOR << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_CYLINDER_LOW    (ATA_CYLINDER_LOW << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_CYLINDER_HIGH   (ATA_CYLINDER_HIGH << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_CARD_DRIVE_HEAD (ATA_CARD_DRIVE_HEAD << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_STATUS          (ATA_STATUS << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_COMMAND         (ATA_COMMAND << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_DUP_RDE_DATA    (ATA_DUP_RDE_DATA << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_DUP_RDO_DATA    (ATA_DUP_RDO_DATA << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_ALT_STATUS_CMD  (ATA_ALT_STATUS_CMD << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_DEV_CNTRL       (ATA_DEV_CNTRL << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG_DATA_BUF        (ATA_DATA_BUF << APCCARD_ADDR_SHIFT)


#define PCFLASH_REG16_SECTOR        (ATA_REG16_SECTOR << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG16_CYLINDER      (ATA_REG16_CYLINDER << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG16_DHC           (ATA_REG16_DHC << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG16_STATUS        (ATA_REG16_STATUS << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG16_DATA          (ATA_REG16_DATA << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG16_ERROR         (ATA_REG16_ERROR << APCCARD_ADDR_SHIFT)
#define PCFLASH_REG16_DEV_CNTRL     (ATA_REG16_DEV_CNTRL << APCCARD_ADDR_SHIFT)


/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/* Error codes from lower layers */
#define PCFLASH_NO_ERROR             (0)
#define PCFLASH_ERROR_NO_CARD        (PCFLASH_ERROR_BASE | 0x01)
#define PCFLASH_INVALID_SECTOR       (PCFLASH_ERROR_BASE | 0x02)
#define PCFLASH_INVALID_CARD         (PCFLASH_ERROR_BASE | 0x03)
#define PCFLASH_INVALID_DRIVE        (PCFLASH_ERROR_BASE | 0x04)
#define PCFLASH_INVALID_VOLTAGE      (PCFLASH_ERROR_BASE | 0x05)
#define PCFLASH_INVALID_HANDLE       (PCFLASH_ERROR_BASE | 0x06)
#define PCFLASH_HARDWARE_ERROR       (PCFLASH_ERROR_BASE | 0x07)
#define PCFLASH_READ_ERROR           (PCFLASH_ERROR_BASE | 0x08)
#define PCFLASH_WRITE_ERROR          (PCFLASH_ERROR_BASE | 0x09)

/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/


/*
** PC_FLASH_INFO_STRUCT
** Run time state information for each PC Card Flash device
*/
typedef struct io_pcflash_info_struct
{
   /* Handle for PCCard calls */
   MQX_FILE_PTR  PCCARD_STREAM;

   /* Drive number to associate with this slot */
   uint_32       DRIVE;

   /* Sector size in bytes */
   uint_32       SECTOR_SIZE;

   /* The total number of sectors in the device */
   uint_32       NUM_SECTORS;

   /* Total size of flash card in bytes */
   uint_32       SIZE;

   /* The number of heads as reported by the ATA ident command */
   uint_32       NUMBER_OF_HEADS;

   /* The number of tracks as reported by the ATA ident command */
   uint_32       NUMBER_OF_TRACKS;

   /* The number of sectos per cylinder as reported by the ATA ident command */
   uint_32       SECTORS_PER_TRACK;

   /* ATA Register location */
   uchar_ptr     ATA_REG_PTR;

   /* ATA Data Register location */
   uint_16_ptr   ATA_DATA_PTR;

   /* Light weight semaphore struct */
   LWSEM_STRUCT  LWSEM;

   /* The address of temp buffer */
   uchar_ptr     TEMP_BUFF_PTR;

   /* The current error code for the device */
   uint_32       ERROR_CODE;

   /* Indicates if the device is running in block mode or character mode */
   boolean       BLOCK_MODE;


} IO_PCFLASH_STRUCT, _PTR_ IO_PCFLASH_STRUCT_PTR;

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_apcflash_open(FILE_DEVICE_STRUCT_PTR, char _PTR_, char _PTR_);
extern _mqx_int _io_apcflash_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_apcflash_read (FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_apcflash_write(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_apcflash_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);

extern uint_32 _io_apcflash_read_sector(IO_PCFLASH_STRUCT_PTR, uint_32,
   uchar_ptr);
extern int_32  _io_apcflash_read_partial_sector(IO_PCFLASH_STRUCT_PTR, uint_32,
   uint_32, uint_32, uchar_ptr);
extern uint_32 _io_apcflash_write_sector(IO_PCFLASH_STRUCT_PTR, uint_32,
   uchar_ptr);
extern int_32  _io_apcflash_write_partial_sector(IO_PCFLASH_STRUCT_PTR,
   uint_32, uint_32, uint_32, uchar_ptr);
extern uint_32 _io_apcflash_identify_device(IO_PCFLASH_STRUCT_PTR, uchar_ptr);
extern uint_32 _io_apcflash_reset(IO_PCFLASH_STRUCT_PTR);
extern boolean _io_apcflash_status_timeout(IO_PCFLASH_STRUCT_PTR, uint_32, uchar);
/* Start CR 812 */
extern _mqx_int _io_apcflash_read_write_blocks(FILE_DEVICE_STRUCT_PTR,
   IO_PCFLASH_STRUCT_PTR, char_ptr, _mqx_int, boolean);
/* End   CR 812 */

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi_legacy/spi_mcf5xxx_qspi.h<|end_filename|>
#ifndef __spi_mcf5xxx_qspi_h__
#define __spi_mcf5xxx_qspi_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_mcf5xxx_qspi.h$
* $Version : 3.5.5.0$
* $Date    : Dec-2-2009$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the SPI driver
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                    CONSTANT DEFINITIONS
*/

#define MCF5XXX_QSPI_CS_COUNT (4)


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** MCF5XXX_QSPI_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a spi port is initialized.
*/
typedef struct mcf5xxx_qspi_init_struct
{
   /* spi channel number */
   uint_32 CHANNEL;

   /* The SPI default chip select */
   uint_32 CS; 
   
   /* The SPI transfer mode */
   uint_32 TRANSFER_MODE;

   /* The Baud rate for the channel */
   uint_32 BAUD_RATE;

   /* The clock speed of CPU */
   uint_32 CLOCK_SPEED;

   /* The SPI clock phase and polarity mode */
   uint_32 CLOCK_POL_PHASE; 

   /* The maximum size of each receive */
   uint_32 RX_BUFFER_SIZE;

   /* The maximum size of each transmit */
   uint_32 TX_BUFFER_SIZE;
   
} MCF5XXX_QSPI_INIT_STRUCT, _PTR_ MCF5XXX_QSPI_INIT_STRUCT_PTR;

typedef const MCF5XXX_QSPI_INIT_STRUCT _PTR_ MCF5XXX_QSPI_INIT_STRUCT_CPTR;

/*--------------------------------------------------------------------------*/
/* 
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_uint _mcf5xxx_qspi_polled_install(char_ptr, MCF5XXX_QSPI_INIT_STRUCT_CPTR);
extern _mqx_uint _mcf5xxx_qspi_int_install(char_ptr, MCF5XXX_QSPI_INIT_STRUCT_CPTR);
extern pointer _bsp_get_qspi_base_address(uint_8);
extern uint_32 _bsp_get_qspi_vector(uint_8);

#ifdef __cplusplus
}
#endif


#endif 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/name.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: name.c$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Name component.
 *
 *END************************************************************************/

#include <string.h>
#include "mqx_inc.h"
#if MQX_USE_NAME
#include "name.h"
#include "name_prv.h"
#include "mqx_str.h"

/*!
 * \private
 *
 * \brief This function adds a name to the name component along with the 
 * _mqx_max_type number to be associate with the name.
 * 
 * \param[in] name_handle The handle returned by _name_internal_create.
 * \param[in] name        The name to be associated with the number.
 * \param[in] number      The number to be associated with the name.
 * \param[in] index       The index in the name table.
 * 
 * \return MQX_OK
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the name component.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data is not valid.)
 * \return NAME_TABLE_FULL (Names database is full.)
 * \return NAME_EXISTS (Name is already in the names database.)
 */ 
_mqx_uint _name_add_internal_by_index
(
    pointer       name_handle,
    char _PTR_    name,
    _mqx_max_type number,
    _mqx_uint     index
)
{ /* Body */
    NAME_COMPONENT_STRUCT_PTR          base_name_manager_ptr;
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    register NAME_STRUCT_PTR           name_ptr;
    _mqx_uint                          result = MQX_OK;

    name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) name_handle;
#if MQX_CHECK_ERRORS
    if (name_manager_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
#if MQX_CHECK_VALIDITY
    if (name_manager_ptr->VALID != NAME_VALID)
    {
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    base_name_manager_ptr = name_manager_ptr;

    /* We are modifying the table, so lets get exclusive access */
    _int_disable();
#if MQX_CHECK_VALIDITY
    if (base_name_manager_ptr->VALID != NAME_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    _lwsem_wait((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));
    _int_enable();

    /* Scan to correct location in table, and if not found, insert it */
    while (index >= name_manager_ptr->NUMBER_IN_BLOCK)
    {
        index -= name_manager_ptr->NUMBER_IN_BLOCK;
        if (name_manager_ptr->NEXT_TABLE == NULL)
        {
            if (name_manager_ptr->GROW_NUMBER && ((name_manager_ptr->TOTAL_NUMBER + name_manager_ptr->GROW_NUMBER)
                            <= name_manager_ptr->MAX_NUMBER))
            {
                result = _name_create_handle_internal((pointer _PTR_) &name_manager_ptr->NEXT_TABLE,
                                name_manager_ptr->GROW_NUMBER, name_manager_ptr->GROW_NUMBER,
                                name_manager_ptr->MAX_NUMBER, (name_manager_ptr->TOTAL_NUMBER
                                                + name_manager_ptr->GROW_NUMBER));
                if (result != MQX_OK)
                {
                    break;
                }/* Endif */
            }
            else
            {
                result = NAME_TABLE_FULL;
                break;
            } /* Endif */
        } /* Endif */
        name_manager_ptr = name_manager_ptr->NEXT_TABLE;
#if MQX_CHECK_VALIDITY
        if (name_manager_ptr->VALID != NAME_VALID)
        {
            result = MQX_INVALID_COMPONENT_BASE;
            break;
        } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    } /* Endwhile */

    if (result == MQX_OK)
    {
        name_ptr = &name_manager_ptr->NAMES[index];
        if (name_ptr->NAME[0] == '\0')
        {
            strncpy(name_ptr->NAME, name, (_mqx_uint) NAME_MAX_NAME_SIZE - 1);
            name_ptr->NAME[NAME_MAX_NAME_SIZE - 1] = '\0';
            name_ptr->NUMBER = number;
            base_name_manager_ptr->NUMBER++;
        }
        else
        {
            result = NAME_EXISTS;
        } /* Endif */
    } /* Endif */

    _lwsem_post((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));

    return (result);
} /* Endbody */

/*!
 * \brief Adds the name and its associated number to the names database.
 * 
 * \param[in] name   The name to add.
 * \param[in] number The number to be associated with the name.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the name component.)
 * \return NAME_EXISTS (Name is already in the names database.)
 * \return NAME_TABLE_FULL (Names database is full.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * 
 * \warning Creates the name component with default values if it was not previously 
 * created.
 * \warning Cannot be called from an ISR.
 * 
 * \see _name_create_component
 * \see _name_delete
 * \see _name_find   
 */ 
_mqx_uint _name_add
(
    char _PTR_    name,
    _mqx_max_type number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                handle;
    _mqx_uint              result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_name_add, name, number);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_name_add, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    handle = kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT];
    if (handle == NULL)
    {
        result = _name_create_component(NAME_DEFAULT_INITIAL_NUMBER, NAME_DEFAULT_GROW_NUMBER,
                        NAME_DEFAULT_MAXIMUM_NUMBER);
        handle = kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (handle == NULL)
        {
            _KLOGX2(KLOG_name_add, result);
            return (result);
        } /* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */
    } /* Endif */

    result = _name_add_internal(handle, name, number);
    _KLOGX2(KLOG_name_add, result);
    return (result);

} /* Endbody */

/*!
 * \private
 * 
 * \brief This function adds a name to the name component along with the 
 * _mqx_max_type number associated with the name.
 * 
 * \param[in] name_handle The handle returned by _name_internal_create.
 * \param[in] name        The name to be associated with the number.
 * \param[in] number      The number to be associated with the name.
 * 
 * \return MQX_OK
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the name component.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data is not valid.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * \return NAME_EXISTS (Name is already in the names database.)
 * \return NAME_TABLE_FULL (Names database is full.) 
 */ 
_mqx_uint _name_add_internal
(
    pointer       name_handle,
    char _PTR_    name,
    _mqx_max_type number
)
{ /* Body */
    NAME_COMPONENT_STRUCT_PTR          base_name_manager_ptr;
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    register NAME_STRUCT_PTR           name_ptr;
    register NAME_STRUCT_PTR           saved_name_ptr;
    register _mqx_uint                 i;
    _mqx_uint                          result = MQX_OK;

#if MQX_CHECK_ERRORS
    if (*name == '\0')
    {
        /* Cannot add 0 length string name */
        return (NAME_TOO_SHORT);
    } /* Endif */
    if (_strnlen(name, NAME_MAX_NAME_SIZE) >= NAME_MAX_NAME_SIZE)
    {
        return (NAME_TOO_LONG);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) name_handle;
#if MQX_CHECK_ERRORS
    if (name_manager_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
    base_name_manager_ptr = name_manager_ptr;

    /* We are modifying the table, so lets get exclusive access */
    _int_disable();
#if MQX_CHECK_VALIDITY
    if ((name_manager_ptr->VALID != NAME_VALID) || (base_name_manager_ptr->VALID != NAME_VALID))
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    _lwsem_wait((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));
    _int_enable();

    /* 
     * Scan to end of table, looking for a duplicate name..
     * simultaneously, remember the first empty slot found
     */
    saved_name_ptr = NULL;
    while (TRUE)
    {
        i = name_manager_ptr->NUMBER_IN_BLOCK + 1;
        name_ptr = &name_manager_ptr->NAMES[0];
        while (--i)
        {
            if (name_ptr->NAME[0] == '\0')
            {
                if (saved_name_ptr == NULL)
                {
                    saved_name_ptr = name_ptr;
                } /* Endif */
            }
            else
            {
                if (strncmp(name_ptr->NAME, name, (_mqx_uint) NAME_MAX_NAME_SIZE - 1) == 0)
                { /* MATCH */
                    result = NAME_EXISTS;
                    break;
                } /* Endif */
            } /* Endif */
            name_ptr++;
        } /* Endwhile */
        if ((name_manager_ptr->NEXT_TABLE == NULL) || (result != MQX_OK))
        {
            break;
        } /* Endif */
        name_manager_ptr = name_manager_ptr->NEXT_TABLE;
    } /* Endwhile */

    if (result == MQX_OK)
    {
        /* We have scanned the whole table, and the original name was not found */

        if (saved_name_ptr == NULL)
        {
            /* 
             * An empty slot was not found in the table so we must try to
             * grow the name table
             */
            if (base_name_manager_ptr->GROW_NUMBER && ((name_manager_ptr->TOTAL_NUMBER
                            + base_name_manager_ptr->GROW_NUMBER) <= base_name_manager_ptr->MAX_NUMBER))
            {
                result = _name_create_handle_internal((pointer _PTR_) &name_manager_ptr->NEXT_TABLE,
                                base_name_manager_ptr->GROW_NUMBER, base_name_manager_ptr->GROW_NUMBER,
                                base_name_manager_ptr->MAX_NUMBER, (name_manager_ptr->TOTAL_NUMBER
                                                + base_name_manager_ptr->GROW_NUMBER));
                if (result == MQX_OK)
                {
                    name_manager_ptr = name_manager_ptr->NEXT_TABLE;
                    saved_name_ptr = &name_manager_ptr->NAMES[0];
                } /* Endif */
            }
            else
            {
                result = NAME_TABLE_FULL;
            } /* Endif */
        } /* Endif */

        if (saved_name_ptr != NULL)
        {
            strncpy(saved_name_ptr->NAME, name, (_mqx_uint) NAME_MAX_NAME_SIZE - 1);
            saved_name_ptr->NAME[NAME_MAX_NAME_SIZE - 1] = '\0';
            saved_name_ptr->NUMBER = number;
            base_name_manager_ptr->NUMBER++;
        }/* Endif */
    }/* Endif */

    _lwsem_post((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));

    return (result);
} /* Endbody */

/*!
 * \private
 * 
 * \brief This function completely removes the specified name table.
 * 
 * \param[in] name_handle The name data structure pointer.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data is not valid.)
 */ 
_mqx_uint _name_destroy_handle_internal
(
    pointer name_handle
)
{ /* Body */
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    register NAME_COMPONENT_STRUCT_PTR next_ptr;

    name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) name_handle;
#if MQX_CHECK_ERRORS
    if (name_manager_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    _int_disable();
#if MQX_CHECK_VALIDITY
    if (name_manager_ptr->VALID != NAME_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    _lwsem_wait((LWSEM_STRUCT_PTR) (&name_manager_ptr->SEM));
    name_manager_ptr->VALID = 0;
    _int_enable();

    _lwsem_destroy((LWSEM_STRUCT_PTR) (&name_manager_ptr->SEM));

    while (name_manager_ptr)
    {
        next_ptr = name_manager_ptr->NEXT_TABLE;
        name_manager_ptr->VALID = 0;
        _mem_free(name_manager_ptr);
        name_manager_ptr = next_ptr;
    } /* Endwhile */

    return (MQX_OK);

} /* Endbody */

/*!
 * \brief Creates the name component.
 * 
 * If an application previously called the function and maximum_number is greater 
 * than what was specified, MQX changes the maximum number of names to 
 * maximum_number.
 * \n If an application does not explicitly create the name component, MQX does 
 * so with the following default values the first time that a task calls _name_add().
 * \n Parameter default values:
 * \li Initial_number = 8(default)
 * \li Grow_number = 8(default)
 * \li Maximum_number = 0(unlimited) 
 *  
 * \param[in] initial_number Initial number of names that can be stored.
 * \param[in] grow_number    The number of names to be added when table is full.
 * \param[in] maximum_number The maximum number of names that can be stored.
 * 
 * \return MQX_OK (Success; one of:
 * \li Name component is created.
 * \li Name component was already created.)
 * \return MQX_OUT_OF_MEMORY (Failure: MQX cannot allocate memory for the name 
 * component.)
 * 
 * \see _name_add
 * \see _name_delete
 * \see _name_find   
 */ 
_mqx_uint _name_create_component
(
    _mqx_uint initial_number,
    _mqx_uint grow_number,
    _mqx_uint maximum_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR    kernel_data;
    _mqx_uint                 result;
    pointer                   handle;
    NAME_COMPONENT_STRUCT_PTR component_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_name_create_component, initial_number, grow_number, maximum_number);

    component_ptr = (NAME_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT];
    if (component_ptr != NULL)
    {
        if (maximum_number > component_ptr->MAX_NUMBER)
        {
            component_ptr->MAX_NUMBER = maximum_number;
        } /* Endif */
        _KLOGX2(KLOG_name_create_component, MQX_OK);
        return (MQX_OK);
    } /* Endif */

    result = _name_create_handle_internal(&handle, initial_number, grow_number, maximum_number, initial_number);

    /* We must exclude all ISRs at this point */
    if (result == MQX_OK)
    {
        _int_disable();
        if (kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT] != NULL)
        {
            _int_enable();
            _name_destroy_handle_internal(handle);
            component_ptr = (NAME_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT];
            if (maximum_number > component_ptr->MAX_NUMBER)
            {
                component_ptr->MAX_NUMBER = maximum_number;
            } /* Endif */
            _KLOGX2(KLOG_name_create_component, MQX_OK);
            return (MQX_OK);
        } /* Endif */
        kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT] = handle;
        _int_enable();
    } /* Endif */

    _KLOGX2(KLOG_name_create_component, result);
    return (result);

} /* Endbody */
/*!
 * \private
 * 
 * \brief Initializes a name component.
 * 
 * This function provides the storage and retrieval of a name associated with a 
 * number.
 * \n The name component can be used by any other kernel components. Each may have 
 * a separate set of names.
 * 
 * \param[out] name_handle    An address where the name data structure pointer is 
 * to be stored.
 * \param[in]  initial_number The initial number of names that can be stored.
 * \param[in]  grow_number    The number of names to be added when table is full.
 * \param[in]  maximum_number The maximum number of names that can be stored.
 * \param[in]  total_so_far   The total number of name spaces in all chained pools.
 * 
 * \return MQX_OK
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the name component.) 
 */ 
_mqx_uint _name_create_handle_internal
(
    pointer _PTR_ name_handle,
    _mqx_uint     initial_number,
    _mqx_uint     grow_number,
    _mqx_uint     maximum_number,
    _mqx_uint     total_so_far
)
{ /* Body */
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;

    name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) _mem_alloc_system_zero((_mem_size) (sizeof(NAME_COMPONENT_STRUCT)
                    + ((initial_number - 1) * sizeof(NAME_STRUCT))));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (name_manager_ptr == NULL)
    {
        return (MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */
    _mem_set_type(name_manager_ptr, MEM_TYPE_NAME_COMPONENT);

    /* The name component has been created, so we must create the semaphore */
    if (initial_number == total_so_far)
    {
        /* Initialize the semaphore for this name component */
        _lwsem_create((LWSEM_STRUCT_PTR) (&name_manager_ptr->SEM), 1);
    } /* Endif */

    name_manager_ptr->GROW_NUMBER = grow_number;
    if (maximum_number == 0)
    {
        name_manager_ptr->MAX_NUMBER = MAX_MQX_UINT;
    }
    else if (maximum_number < initial_number)
    {
        name_manager_ptr->MAX_NUMBER = initial_number;
    }
    else
    {
        name_manager_ptr->MAX_NUMBER = maximum_number;
    } /* Endif */
    name_manager_ptr->NUMBER_IN_BLOCK = initial_number;
    name_manager_ptr->TOTAL_NUMBER = total_so_far;
    name_manager_ptr->VALID = NAME_VALID;

    *(NAME_COMPONENT_STRUCT_PTR _PTR_) name_handle = name_manager_ptr;

    return (MQX_OK);
} /* Endbody */

/*!
 * \private
 *
 * \brief This function removes a name from the name component.
 * 
 * \param[in] name_handle The handle returned by _name_internal_create.
 * \param[in] index       The index in the name table.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data is not valid.)    
 */ 
_mqx_uint _name_delete_internal_by_index
(
    pointer   name_handle,
    _mqx_uint index
)
{ /* Body */
    register NAME_COMPONENT_STRUCT_PTR base_name_manager_ptr;
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    register NAME_STRUCT_PTR           name_ptr;
    _mqx_uint                          result = MQX_OK;

    base_name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) name_handle;
#if MQX_CHECK_ERRORS
    if (base_name_manager_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    _int_disable();
#if MQX_CHECK_VALIDITY
    if (base_name_manager_ptr->VALID != NAME_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    _lwsem_wait((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));
    _int_enable();

    /* Scan to end of table, and if the name found, delete it */
    name_manager_ptr = base_name_manager_ptr;
    /* Scan to end of table, if found, return number */
    while (index >= name_manager_ptr->NUMBER_IN_BLOCK)
    {
        index -= name_manager_ptr->NUMBER_IN_BLOCK;
        if (name_manager_ptr->NEXT_TABLE == NULL)
        {
            result = NAME_NOT_FOUND;
            break;
        } /* Endif */
        name_manager_ptr = name_manager_ptr->NEXT_TABLE;
#if MQX_CHECK_VALIDITY
        if (name_manager_ptr->VALID != NAME_VALID)
        {
            result = MQX_INVALID_COMPONENT_BASE;
            break;
        } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    }/* Endwhile */

    if (result == MQX_OK)
    {
        name_ptr = (NAME_STRUCT_PTR) & name_manager_ptr->NAMES[index];
        name_ptr->NAME[0] = '\0';
        name_ptr->NUMBER = 0;
        base_name_manager_ptr->NUMBER--;
    } /* Endif */

    _lwsem_post((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));

    return (MQX_OK);
} /* Endbody */

/*!
 * \brief Deletes the name and its associated number from the names database.
 * 
 * \param[in] name The name to be deleted.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an 
 * ISR.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data is not valid.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * \return NAME_NOT_FOUND (Name is not in the names database.)
 * 
 * \warning Cannot be called from an ISR.
 * 
 * \see _name_add
 * \see _name_create_component
 * \see _name_find     
 */ 
_mqx_uint _name_delete
(
    char_ptr name
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                handle;
    _mqx_uint              result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_name_delete, name);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_name_delete, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    handle = kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT];
#if MQX_CHECK_ERRORS
    if (handle == NULL)
    {
        _KLOGX2(KLOG_name_delete, MQX_COMPONENT_DOES_NOT_EXIST);
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
    result = _name_delete_internal(handle, name);
    _KLOGX2(KLOG_name_delete, result);
    return (result);
} /* Endbody */

/*!
 * \private
 * 
 * \brief This function removes a name from the name component.
 * 
 * \param[in] name_handle The handle returned by _name_internal_create.
 * \param[in] name        The name to be deleted.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * \return NAME_NOT_FOUND (Name is not in the names database.) 
 */ 
_mqx_uint _name_delete_internal
(
    pointer  name_handle,
    char_ptr name
)
{ /* Body */
    NAME_COMPONENT_STRUCT_PTR          base_name_manager_ptr;
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    register NAME_STRUCT_PTR           name_ptr;
    register _mqx_uint                 i;

    name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) name_handle;
#if MQX_CHECK_ERRORS
    if (name_manager_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    base_name_manager_ptr = name_manager_ptr;

    /* We are modifying the table, so lets get exclusive access */
    _int_disable();
#if MQX_CHECK_VALIDITY
    if (name_manager_ptr->VALID != NAME_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
#if MQX_CHECK_ERRORS
    if (*name == '\0')
    {
        /* Cannot delete 0 length string name */
        _int_enable();
        return (NAME_TOO_SHORT);
    } /* Endif */
    if (_strnlen(name, NAME_MAX_NAME_SIZE) >= NAME_MAX_NAME_SIZE)
    {
        _int_enable();
        return (NAME_TOO_LONG);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
#if MQX_CHECK_VALIDITY
    if (base_name_manager_ptr->VALID != NAME_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    _lwsem_wait((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));

    _int_enable();

    /* Scan to end of table, and if the name found, delete it */
    while (TRUE)
    {
        i = name_manager_ptr->NUMBER_IN_BLOCK + 1;
        name_ptr = &name_manager_ptr->NAMES[0];
        while (--i)
        {
            if (name_ptr->NAME[0] != '\0')
            {
                if (strncmp(name_ptr->NAME, name, (_mqx_uint) NAME_MAX_NAME_SIZE - 1) == 0)
                { /* MATCH */
                    name_ptr->NAME[0] = '\0';
                    name_ptr->NUMBER = 0;
                    base_name_manager_ptr->NUMBER--;
                    _lwsem_post((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));
                    return (MQX_OK);
                } /* Endif */
            } /* Endif */
            name_ptr++;
        } /* Endwhile */
        if (name_manager_ptr->NEXT_TABLE == NULL)
        {
            _lwsem_post((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));
            return (NAME_NOT_FOUND);
        }
        else
        {
            name_manager_ptr = name_manager_ptr->NEXT_TABLE;
#if MQX_CHECK_VALIDITY
            if (name_manager_ptr->VALID != NAME_VALID)
            {
                _lwsem_post((LWSEM_STRUCT_PTR) (&base_name_manager_ptr->SEM));
                return (MQX_INVALID_COMPONENT_BASE);
            } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
        } /* Endif */
    } /* Endwhile */
} /* Endbody */

/*!
 * \private
 * 
 * \brief This function looks up a name in the name component, and returns the
 * _mqx_max_type quantity associated with the name.
 * 
 * \param[in]  name_handle The handle returned by _name_internal_create.
 * \param[in]  index       The nth name to locate.
 * \param[out] number_ptr  The location where the number is to be returned.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.)
 * \return NAME_NOT_FOUND (Name is not in the names database.)
 */ 
_mqx_uint _name_find_internal_by_index
(
    pointer           name_handle,
    _mqx_uint         index,
    _mqx_max_type_ptr number_ptr
)
{ /* Body */
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    register NAME_STRUCT_PTR           name_ptr;

    name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) name_handle;
#if MQX_CHECK_ERRORS
    if (name_manager_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
#if MQX_CHECK_VALIDITY
    if (name_manager_ptr->VALID != NAME_VALID)
    {
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    /* Scan to end of table, if found, return number */
    while (index >= name_manager_ptr->NUMBER_IN_BLOCK)
    {
        index -= name_manager_ptr->NUMBER_IN_BLOCK;
        if (name_manager_ptr->NEXT_TABLE == NULL)
        {
            return (NAME_NOT_FOUND);
        } /* Endif */
        name_manager_ptr = name_manager_ptr->NEXT_TABLE;
#if MQX_CHECK_VALIDITY
        if (name_manager_ptr->VALID != NAME_VALID)
        {
            return (MQX_INVALID_COMPONENT_BASE);
        } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    }/* Endwhile */
    name_ptr = (NAME_STRUCT_PTR) & name_manager_ptr->NAMES[index];
    if (name_ptr->NAME[0] == '\0')
    {
        return (NAME_NOT_FOUND);
    } /* Endif */
    *number_ptr = name_ptr->NUMBER;

    return (MQX_OK);
} /* Endbody */

/*!
 * \brief Gets the number that is associated with the name in the names database.
 * 
 * \param[in]  name       Pointer to the name for which to get the associated number.
 * \param[out] number_ptr Pointer to the number.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.)
 * \return NAME_NOT_FOUND (Name is not in the names database.)   
 * 
 * \see _name_add
 * \see _name_create_component
 * \see _name_delete 
 */ 
_mqx_uint _name_find
(
    char_ptr          name,
    _mqx_max_type_ptr number_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                handle;
    _mqx_uint              result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_name_find, name, number_ptr);

    handle = kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT];
#if MQX_CHECK_ERRORS
    if (handle == NULL)
    {
        _KLOGX2(KLOG_name_find, MQX_COMPONENT_DOES_NOT_EXIST);
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
    result = _name_find_internal(handle, name, number_ptr);

    _KLOGX3(KLOG_name_find, result, *number_ptr);

    return (result);
} /* Endbody */

/*!
 * \private
 * 
 * \brief Gets the number that is associated with the name in the names database.
 * 
 * \param[in]  name_handle The handle returned by _name_internal_create.
 * \param[in]  name        The name to be looked up.
 * \param[out] number_ptr  The location where the number is to be returned.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return NAME_TOO_SHORT (Name is 0 length string.)
 * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.)
 * \return NAME_NOT_FOUND (Name is not in the names database.) 
 */ 
_mqx_uint _name_find_internal
(
    pointer           name_handle,
    char_ptr          name,
    _mqx_max_type_ptr number_ptr
)
{ /* Body */
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    register NAME_STRUCT_PTR           name_ptr;
    register _mqx_uint                 i;

    name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) name_handle;
#if MQX_CHECK_ERRORS
    if (name_manager_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
    if (*name == '\0')
    {
        /* Cannot find 0 length string name */
        return (NAME_TOO_SHORT);
    } /* Endif */
    if (_strnlen(name, NAME_MAX_NAME_SIZE) >= NAME_MAX_NAME_SIZE)
    {
        return (NAME_TOO_LONG);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
#if MQX_CHECK_VALIDITY
    if (name_manager_ptr->VALID != NAME_VALID)
    {
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    /* Scan to end of table, if found, return number */
    while (TRUE)
    {
        i = name_manager_ptr->NUMBER_IN_BLOCK + 1;
        name_ptr = (NAME_STRUCT_PTR) & name_manager_ptr->NAMES[0];
        while (--i)
        {
            if (name_ptr->NAME[0] != '\0')
            {
                if (strncmp(name_ptr->NAME, name, (_mqx_uint) NAME_MAX_NAME_SIZE - 1) == 0)
                { /* MATCH */
                    *number_ptr = name_ptr->NUMBER;
                    return (MQX_OK);
                } /* Endif */
            } /* Endif */
            name_ptr++;
        } /* Endwhile */
        if (name_manager_ptr->NEXT_TABLE == NULL)
        {
            return (NAME_NOT_FOUND);
        } /* Endif */
        name_manager_ptr = name_manager_ptr->NEXT_TABLE;
#if MQX_CHECK_VALIDITY
        if (name_manager_ptr->VALID != NAME_VALID)
        {
            return (MQX_INVALID_COMPONENT_BASE);
        } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    } /* Endwhile */
} /* Endbody */

/*!
 * \brief Gets the name that is associated with the number in the names database.
 * 
 * The function finds the first entry in the database that matches the number 
 * and returns its name.
 * 
 * \param[in]  number   Number for which to get the associated name.
 * \param[out] name_ptr Pointer to the name.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.)
 * \return NAME_NOT_FOUND (Name is not in the names database.) 
 * 
 * \see _name_add
 * \see _name_create_component
 * \see _name_delete 
 */ 
_mqx_uint _name_find_by_number
(
    _mqx_max_type number,
    char_ptr      name_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer                handle;
    _mqx_uint              result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_name_find_name, number, name_ptr);

    handle = kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT];
    if (handle == NULL)
    {
        _KLOGX2(KLOG_name_find_name, MQX_COMPONENT_DOES_NOT_EXIST);
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */

    result = _name_find_name_internal(handle, number, name_ptr);

    _KLOGX2(KLOG_name_find_name, result);
    return (result);
} /* Endbody */

/*!
 * \private
 * 
 * \brief This function looks up a number in the name component, and returns the
 * name associated with the number.
 * 
 * \param[in]  name_handle     The handle returned by _name_internal_create.
 * \param[in]  number          Number for which to get the associated name.
 * \param[out] name_string_ptr Pointer to the name. 
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.)
 * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.)
 * \return NAME_NOT_FOUND (Name is not in the names database.) 
 */ 
_mqx_uint _name_find_name_internal
(
    pointer       name_handle,
    _mqx_max_type number,
    char_ptr      name_string_ptr
)
{ /* Body */
    register NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    register NAME_STRUCT_PTR           name_ptr;
    register _mqx_uint                 i;

    name_manager_ptr = (NAME_COMPONENT_STRUCT_PTR) name_handle;
#if MQX_CHECK_ERRORS
    if (name_manager_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
#if MQX_CHECK_VALIDITY
    if (name_manager_ptr->VALID != NAME_VALID)
    {
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    /* Scan to end of table, if found, return number */
    while (TRUE)
    {
        i = name_manager_ptr->NUMBER_IN_BLOCK + 1;
        name_ptr = (NAME_STRUCT_PTR) & name_manager_ptr->NAMES[0];
        while (--i)
        {
            if (name_ptr->NAME[0] != '\0')
            {
                if (number == name_ptr->NUMBER)
                { /* MATCH */
                    strncpy(name_string_ptr, name_ptr->NAME, (_mqx_uint) NAME_MAX_NAME_SIZE - 1);
                    name_string_ptr[NAME_MAX_NAME_SIZE - 1] = '\0';
                    return (MQX_OK);
                } /* Endif */
            } /* Endif */
            name_ptr++;
        } /* Endwhile */

        if (name_manager_ptr->NEXT_TABLE == NULL)
        {
            return (NAME_NOT_FOUND);
        }
        else
        {
            name_manager_ptr = name_manager_ptr->NEXT_TABLE;
        } /* Endif */
#if MQX_CHECK_VALIDITY
        if (name_manager_ptr->VALID != NAME_VALID)
        {
            return (MQX_INVALID_COMPONENT_BASE);
        } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
    } /* Endwhile */
} /* Endbody */

/*!
 * \brief Tests name component for consistency.
 * 
 * The function tests the data structures that are associated with the name 
 * component.
 * <table>
 *   <tr>
 *     <td><b>Return</b></td>
 *     <td><b>name_error_ptr</b></td>
 *     <td><b>name_extension_error_ptr</b></td>  
 *   </tr>
 *   <tr>
 *     <td><b>MQX_CORRUPT_QUEUE</b>
 *     (Task queue that is associated with the name component is incorrect)</td>
 *     <td>NULL</td>
 *     <td>NULL</td>  
 *   </tr>
 *   <tr>
 *     <td><b>MQX_INVALID_COMPONENT_BASE</b>
 *     (MQX found an error in a name component data structure)</td>
 *     <td>Pointer to the name table that has an error.</td>
 *     <td>Pointer to the name table that has an error.</td>  
 *   </tr>   
 * </table>  
 *  
 * \param[out] name_error_ptr           The address of the base name component 
 * in error.
 * \param[out] name_extension_error_ptr The address of the name component 
 * extension in error.
 * 
 * \return MQX_OK
 * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.)
 * \return MQX_CORRUPT_QUEUE (An error was found.) 
 * \return MQX_INVALID_LWSEM (Results of _queue_test().)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * 
 * \warning Disables and enables interrupts, cannot be called from ISR.
 * 
 * \see _name_add
 * \see _name_create_component
 * \see _name_delete   
 */ 
_mqx_uint _name_test
(
    pointer _PTR_ name_error_ptr,
    pointer _PTR_ name_extension_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR    kernel_data;
    NAME_COMPONENT_STRUCT_PTR name_component_ptr;
    _mqx_uint                 result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_name_test, name_error_ptr, name_extension_error_ptr);

    *name_error_ptr = NULL;
    *name_extension_error_ptr = NULL;

    name_component_ptr = (NAME_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT];
    if (name_component_ptr == NULL)
    {
        _KLOGX2(KLOG_name_test, MQX_OK);
        return (MQX_OK);
    } /* Endif */

    result = _name_test_internal(name_component_ptr, name_error_ptr, name_extension_error_ptr);

    _KLOGX2(KLOG_name_test, result);
    return (result);
} /* Endbody */

/*!
 * \private
 * 
 * \brief This function tests the specified name component for consistency.
 * 
 * \param[in]  base_name_manager_ptr    The name component to test.
 * \param[out] name_error_ptr           The address of the base name component 
 * in error.
 * \param[out] name_extension_error_ptr The address of the name component 
 * extension in error.
 * 
 * \return MQX_OK
 * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.)
 * \return MQX_CORRUPT_QUEUE (An error was found.) 
 * \return MQX_INVALID_LWSEM (Results of _queue_test().)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)   
 */            
_mqx_uint _name_test_internal
(
    NAME_COMPONENT_STRUCT_PTR base_name_manager_ptr,
    pointer _PTR_             name_error_ptr,
    pointer _PTR_             name_extension_error_ptr
)
{ /* Body */
    NAME_COMPONENT_STRUCT_PTR name_manager_ptr;
    pointer                   sem_in_err_ptr;
    pointer                   td_in_err_ptr;
    _mqx_uint                 result;
    _mqx_uint                 total;
    _mqx_uint                 i;

    if (base_name_manager_ptr == NULL)
    {
        return (MQX_OK);
    } /* Endif */

    *name_error_ptr = base_name_manager_ptr;
    if (base_name_manager_ptr->VALID != NAME_VALID)
    {
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    result = _lwsem_test(&sem_in_err_ptr, &td_in_err_ptr);
    if (result != MQX_OK)
    {
        return (result);
    } /* Endif */

    name_manager_ptr = base_name_manager_ptr;
    total = 0;
    _int_disable();
    while (name_manager_ptr != NULL)
    {
#if MQX_CHECK_VALIDITY
        if (name_manager_ptr->VALID != NAME_VALID)
        {
            _int_enable();
            *name_extension_error_ptr = name_manager_ptr;
            return (MQX_INVALID_COMPONENT_BASE);
        } /* Endif */
#endif /* MQX_CHECK_VALIDITY */
        for (i = 0; i < name_manager_ptr->NUMBER_IN_BLOCK; ++i)
        {
            if (name_manager_ptr->NAMES[i].NAME[0] != '\0')
            {
                ++total;
            } /* Endif */
        } /* Endfor */
        name_manager_ptr = name_manager_ptr->NEXT_TABLE;
    } /* Endwhile */
    _int_enable();

    if (total != base_name_manager_ptr->NUMBER)
    {
        *name_extension_error_ptr = name_manager_ptr;
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    return (MQX_OK);

} /* Endbody */
#endif /* MQX_USE_NAME */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcflash/ata.h<|end_filename|>
#ifndef _ata_h_
#define _ata_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ata.h$
* $Version : 3.8.6.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   This file contains 
*
*END************************************************************************/


/* -------------------------------------------------------------------------*/
/*
**                              CONSTANT DEFINITIONS
*/

/* The size of one sector (in bytes), as defined by the ATA standard */
#define ATA_SECTOR_SIZE       512

#define ATA_REG_SIZE          (15)

/*
 * Byte Offsets to ATA Register Set
 */
#define ATA_REG_BASE          (0)
#define ATA_ERROR             (1)   /* read only */
#define ATA_FEATURES          (1)   /* write only */
#define ATA_SECTOR_COUNT      (2)
#define ATA_SECTOR            (3)
#define ATA_CYLINDER_LOW      (4)
#define ATA_CYLINDER_HIGH     (5)
#define ATA_CARD_DRIVE_HEAD   (6)
#define ATA_STATUS            (7)   /* read only: reading clears interrupt */
#define ATA_COMMAND           (7)   /* write only */
#define ATA_DUP_RDE_DATA      (8)
#define ATA_DUP_RDO_DATA      (9)
#define ATA_ALT_STATUS_CMD    (0xe) /* reading does NOT clear interrupt */
#define ATA_DEV_CNTRL         (0xe) /* write only */
#define ATA_DATA_BUF          (0x400)

/*
 * Word Offsets to ATA Register Set (16-bit access)
 */
#define ATA_REG16_SECTOR      (1)
#define ATA_REG16_CYLINDER    (2)
#define ATA_REG16_DHC         (3)
#define ATA_REG16_STATUS      (3) /* read only */
#define ATA_REG16_DATA        (4)
#define ATA_REG16_ERROR       (6) /* high byte */
#define ATA_REG16_DEV_CNTRL   (7)


/*
 * ATA Commands -- See ATA Command/Status Register
 */
#define ATA_NOP                                    (0x00)
#define ATA_RECALIBRATE                            (0x10) /* 0x1x */
#define ATA_READ_SECTOR_WITH_RETRY                 (0x20)
#define ATA_READ_SECTOR                            (0x21)
#define ATA_READ_LONG_WITH_RETRY                   (0x22)
#define ATA_READ_LONG                              (0x23)
#define ATA_WRITE_SECTOR_WITH_RETRY                (0x30)
#define ATA_WRITE_SECTOR                           (0x31)
#define ATA_WRITE_LONG_WITH_RETRY                  (0x32)
#define ATA_WRITE_LONG                             (0x33)
#define ATA_WRITE_VERIFY                           (0x3C)
#define ATA_READ_VERIFY_SECTOR_WITH_RETRY          (0x40)
#define ATA_READ_VERIFY_SECTOR                     (0x41)
#define ATA_FORMAT_TRACK                           (0x50)
#define ATA_SEEK                                   (0x70) /* 0x7x */
#define ATA_VENDOR_SPECIFIC_8X                     (0x80) /* 0x8x */
#define ATA_EXECUTE_DEVICE_DIAGNOSTIC              (0x90)
#define ATA_INITIALIZE_DEVICE_PARAMETERS           (0x91)
#define ATA_DOWNLOAD_MICROCODE                     (0x92)
#define ATA_VENDOR_SPECIFIC_9A                     (0x9A)
#define ATA_VENDOR_SPECIFIC_C0                     (0xC0)
#define ATA_VENDOR_SPECIFIC_C1                     (0xC1)
#define ATA_VENDOR_SPECIFIC_C2                     (0xC2)
#define ATA_VENDOR_SPECIFIC_C3                     (0xC3)
#define ATA_READ_MULTIPLE                          (0xC4)
#define ATA_WRITE_MULTIPLE                         (0xC5)
#define ATA_SET_MULTIPLE_MODE                      (0xC6)
#define ATA_READ_DMA_WITH_RETRY                    (0xC8)
#define ATA_READ_DMA                               (0xC9)
#define ATA_WRITE_DMA_WITH_RETRY                   (0xCA)
#define ATA_WRITE_DMA                              (0xCB)
#define ATA_ACKNOWLEDGE_MEDIA_CHANGE               (0xDB)
#define ATA_BOOT_POST_BOOT                         (0xDC)
#define ATA_BOOT_PRE_BOOT                          (0xDD)
#define ATA_DOOR_LOCK                              (0xDE)
#define ATA_DOOR_UNLOCK                            (0xDF)
#define ATA_STANDBY_IMMEDIATE                      (0xE0)   /* 94h */
#define ATA_IDLE_IMMEDIATE                         (0xE1)   /* 95h */
#define ATA_STANDBY                                (0xE2)   /* 96h */
#define ATA_IDLE                                   (0xE3)   /* 97h */
#define ATA_READ_BUFFER                            (0xE4)
#define ATA_CHECK_POWER_MODE                       (0xE5)   /* 98h */
#define ATA_SLEEP                                  (0xE6)   /* 99h */
#define ATA_WRITE_BUFFER                           (0xE8)
#define ATA_WRITE_SAME                             (0xE9)
#define ATA_IDENTIFY_DEVICE                        (0xEC)
#define ATA_MEDIA_EJECT                            (0xED)
#define ATA_SET_FEATURES                           (0xEF)
#define ATA_VENDOR_SPECIFIC_FX                     (0xf0)  /* 0xfx */  

/*
 * Defines for the ATA drive/head register
 */
#define ATA_DRIVE_REG_LBA       (0x40)
#define ATA_DRIVE_REG_CARD0     (0x10)
#define ATA_DRIVE_REG_ADDR_MASK (0x0F)

/*
 * Defines for the ATA status register
 */
#define ATA_STAT_BSY   (0x80)
#define ATA_STAT_DRDY  (0x40)
#define ATA_STAT_DWF   (0x20)
#define ATA_STAT_DSC   (0x10)
#define ATA_STAT_DRQ   (0x08)
#define ATA_STAT_CORR  (0x04)
#define ATA_STAT_IDX   (0x02)
#define ATA_STAT_ERR   (0x01)

/*
 * Defines for the ATA error register
 */
#define ATA_ERR_RES    (0x80)
#define ATA_ERR_UNC    (0x40)
#define ATA_ERR_MC     (0x20)
#define ATA_ERR_IDNF   (0x10)
#define ATA_ERR_MCR    (0x08)
#define ATA_ERR_ABRT   (0x04)
#define ATA_ERR_TKONF  (0x02)
#define ATA_ERR_AMNF   (0x01)

#define ATA_ERR_MASK \
   ( ATA_ERR_RES | ATA_ERR_UNC | ATA_ERR_IDNF | ATA_ERR_ABRT | \
     ATA_ERR_TKONF | ATA_ERR_AMNF )

/*
 * Defines for the ATA device control register
 */
#define ATA_DEV_CNTL_SRST (0x04)

/*
 * Busy timeout values
 */

/* The maximum time to wait for reset to complete in seconds */
#define ATA_RST_TIMEOUT (31)

/* Default timeout in seconds */
#define ATA_BSY_DEFAULT_TIMEOUT (5)


/* -------------------------------------------------------------------------*/
/*
**                              DATATYPE DECLARATIONS
*/

/*
** ATA DATA RECORD STRUCT
*/
typedef struct ata_data_record_struct {
    uint_32    CARD_DATA;  /* PC Card Data */
    uchar      DRIVE;     /* Drive 0 -- Card A; Drive 1 Card B */
} ATA_DATA_RECORD_STRUCT, _PTR_ ATA_DATA_PTR ;

/*
** ATA IDENTIFY DEVICE RESULTS STRUCTURE
*/
typedef struct ata_identify_device_struct {
   uint_16     GENERAL_CONFIG;           /* Word 0 */
   uint_16     NUMBER_CYLINDERS;         /* Word 1 */
   uint_16     RESERVED1;                /* Word 2 */
   uint_16     NUMBER_HEADS;             /* Word 3 */
   uint_16     VENDOR1;                  /* Word 4 */
   uint_16     VENDOR2;                  /* Word 5 */
   uint_16     SECTORS_PER_TRACK;        /* Word 6 */
   uint_16     VENDOR3[3];               /* Word 7-9 */
   uint_16     SERIAL_NUMBER[10];        /* Word 10-19 */
   uint_16     VENDOR4;                  /* Word 20 */
   uint_16     VENDOR5;                  /* Word 21 */
   uint_16     BYTES_AVAIL_RW_LONG;      /* Word 22 */
   uint_16     FIRMWARE_REV[4];          /* Word 23-26 */
   uint_16     MODEL_NUMBER[20];         /* Word 27-46 */
   uint_16     VENDOR_MAX_SEC_NUM;       /* Word 47 */
   uint_16     RESERVED2;                /* Word 48 */
   uint_16     CAPABILITIES;             /* Word 49 */
   uint_16     RESERVED3;                /* Word 50 */
   uint_16     PIO_TIMING_MODE;          /* Word 51 */
   uint_16     DMA_TIMING_MODE;          /* Word 52 */
   uint_16     FIELD_64_70_VALID;        /* Word 53 */
   uint_16     CURRENT_CYLS;             /* Word 54 */
   uint_16     CURRENT_HEADS;            /* Word 55 */
   uint_16     CURRENT_SECTS_PER_TR;     /* Word 56 */
   uint_16     CURRENT_SECT_CAPACITY[2]; /* Word 57-58 */
   uint_16     MULTIPLE_SECTOR_SETTING;  /* Word 59 */
   uint_16     TOTAL_SECTORS_LBA[2];     /* Word 60-61 */
   uint_16     SINGLE_WRD_DMA;           /* Word 62 */
   uint_16     MULTI_WRD_DMA;            /* Word 63 */
   uint_16     ADVANCED_PIO_MODE;        /* Word 64 */
   uint_16     MIN_MW_DMA_CYCLE_TIME;    /* Word 65 */
   uint_16     REC_MW_DMA_CYCLE_TIME;    /* Word 66 */
   uint_16     MIN_PIO_TIME_NO_FLOW;     /* Word 67 */
   uint_16     MIN_PIO_TIME_IORDY_FLOW;  /* Word 68 */
   uint_16     RESERVED4[2];             /* Word 69-70 */
   uint_16     RESERVED5[57];            /* Word 71-127 */
   uint_16     VENDOR6[32];              /* Word 128-159 */
   uint_16     RESERVED6[96];            /* Word 160-255 */
} ATA_IDENTIFY_DEVICE_STRUCT, _PTR_ ATA_IDENTIFY_DEVICE_STRUCT_PTR;

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_Sensor.c<|end_filename|>
/***********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
*********************************************************************************************************************//*!
*
* @file   TSS_Sensor.c
*
* @brief  Contains functions to Perform the sensing ot the electrodes and set the status for each electrode
*
* @version 1.0.79.0
* 
* @date Aug-9-2012
* 
*
***********************************************************************************************************************/

  #include "TSS_SensorGPIO.h"
  #include "TSS_SensorTSI.h"
  #include "TSS_SensorTSIL.h"

  #if TSS_HW_GPIO_USED
    #include "TSS_GPIO.h"
  #endif
  #if TSS_HW_TIMER_USED
    #include "TSS_Timer.h"
  #endif

  #include "TSS_Sensor.h"

  volatile UINT8 tss_u8SampleIntFlag;
  volatile UINT8 tss_u8HWTimerFlag = 0u;
  
  #if TSS_HCS08_MCU || TSS_CFV1_MCU
    #if TSS_USE_SIMPLE_LOW_LEVEL
      #if (TSS_GPIO_VERSION == 2)
        volatile UINT8 *tss_pu8ElectrodePortAdr;
        volatile UINT8 *tss_pu8ElectrodePortControlAdr;
        volatile UINT8 tss_u8ElectrodePortMask;
      #else 
        volatile UINT8 *tss_pu8ElectrodePortAdr;
        volatile UINT8 tss_u8ElectrodePortMask;
      #endif
    #else /* TSS_USE_SIMPLE_LOW_LEVEL == 0 */
      #if (TSS_GPIO_VERSION == 2)
        volatile UINT8 *tss_psElectrodeTimertAdr;
        volatile UINT8 *tss_pu8ElectrodePortAdr;
        volatile UINT8 *tss_pu8ElectrodePortControlAdr;
        volatile UINT8 tss_u8ElectrodePortMask;
      #else
        volatile UINT8 *tss_psElectrodeTimertAdr;
        volatile UINT8 *tss_pu8ElectrodePortAdr;
        volatile UINT8 tss_u8ElectrodePortMask;
      #endif
    #endif /* End of TSS_USE_SIMPLE_LOW_LEVEL == 0 */
  #elif TSS_KINETIS_MCU
    volatile UINT32 *tss_psElectrodeTimertAdr;
    volatile UINT32 *tss_psElectrodeRGPIOAdr;
    volatile UINT8 tss_u8ElectrodeBitNum;
  #elif TSS_CFM_MCU
    volatile UINT32 *tss_psElectrodeTimertAdr;
    volatile UINT32 *tss_psElectrodePortAdr;
    volatile UINT32 *tss_psElectrodePCTLAdr;
    volatile UINT8 tss_u8ElectrodeBitNum;
  #endif
    
  #if TSS_AUTOTRIGGER_SOURCE_USED
    volatile UINT8 tss_u8TriggerCounter;
  #endif
    
  /* 
  *  Array that contains pointers to the TSS Mehod functions.  
  *  The array is defined depending on the number of electrodes stablished by the user
  */
  UINT8 (* const tss_faSampleElectrode[TSS_N_ELECTRODES])(UINT8 u8ElecNum, UINT8 u8Command) = {
  #if TSS_N_ELECTRODES > 0
    TSS_E0_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 1
    TSS_E1_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 2
    TSS_E2_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 3
    TSS_E3_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 4
    TSS_E4_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 5
    TSS_E5_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 6
    TSS_E6_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 7
    TSS_E7_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 8
    TSS_E8_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 9
    TSS_E9_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 10
    TSS_E10_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 11
    TSS_E11_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 12
    TSS_E12_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 13
    TSS_E13_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 14
    TSS_E14_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 15
    TSS_E15_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 16
    TSS_E16_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 17
    TSS_E17_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 18
    TSS_E18_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 19
    TSS_E19_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 20
    TSS_E20_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 21
    TSS_E21_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 22
    TSS_E22_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 23
    TSS_E23_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 24
    TSS_E24_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 25
    TSS_E25_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 26
    TSS_E26_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 27
    TSS_E27_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 28
    TSS_E28_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 29
    TSS_E29_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 30
    TSS_E30_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 31
    TSS_E31_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 32
    TSS_E32_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 33
    TSS_E33_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 34
    TSS_E34_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 35
    TSS_E35_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 36
    TSS_E36_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 37
    TSS_E37_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 38
    TSS_E38_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 39
    TSS_E39_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 40
    TSS_E40_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 41
    TSS_E41_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 42
    TSS_E42_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 43
    TSS_E43_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 44
    TSS_E44_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 45
    TSS_E45_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 46
    TSS_E46_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 47
    TSS_E47_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 48
    TSS_E48_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 49
    TSS_E49_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 50
    TSS_E50_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 51
    TSS_E51_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 52
    TSS_E52_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 53
    TSS_E53_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 54
    TSS_E54_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 55
    TSS_E55_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 56
    TSS_E56_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 57
    TSS_E57_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 58
    TSS_E58_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 59
    TSS_E59_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 60
    TSS_E60_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 61
    TSS_E61_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 62
    TSS_E62_SAMPLE_ELECTRODE(),
  #endif
  #if TSS_N_ELECTRODES > 63
    TSS_E63_SAMPLE_ELECTRODE(),
  #endif
  };

  /* 
  *  Array that contains pointers to the TSS sensing functions.  
  *  The array is defined depending on the number of electrodes stablished by the user
  */
  UINT16 (* const tss_faSampleElectrodeLow[TSS_N_ELECTRODES])(void) = 
  {
  #if TSS_N_ELECTRODES > 0
    TSS_SampleElectrodeLowE0,
  #endif
  #if TSS_N_ELECTRODES > 1
    TSS_SampleElectrodeLowE1,
  #endif
  #if TSS_N_ELECTRODES > 2
    TSS_SampleElectrodeLowE2,
  #endif
  #if TSS_N_ELECTRODES > 3
    TSS_SampleElectrodeLowE3,
  #endif
  #if TSS_N_ELECTRODES > 4
    TSS_SampleElectrodeLowE4,
  #endif
  #if TSS_N_ELECTRODES > 5
    TSS_SampleElectrodeLowE5,
  #endif
  #if TSS_N_ELECTRODES > 6
    TSS_SampleElectrodeLowE6,
  #endif
  #if TSS_N_ELECTRODES > 7
    TSS_SampleElectrodeLowE7,
  #endif
  #if TSS_N_ELECTRODES > 8
    TSS_SampleElectrodeLowE8,
  #endif
  #if TSS_N_ELECTRODES > 9
    TSS_SampleElectrodeLowE9,
  #endif
  #if TSS_N_ELECTRODES > 10
    TSS_SampleElectrodeLowE10,
  #endif
  #if TSS_N_ELECTRODES > 11
    TSS_SampleElectrodeLowE11,
  #endif
  #if TSS_N_ELECTRODES > 12
    TSS_SampleElectrodeLowE12,
  #endif
  #if TSS_N_ELECTRODES > 13
    TSS_SampleElectrodeLowE13,
  #endif
  #if TSS_N_ELECTRODES > 14
    TSS_SampleElectrodeLowE14,
  #endif
  #if TSS_N_ELECTRODES > 15
    TSS_SampleElectrodeLowE15,
  #endif
  #if TSS_N_ELECTRODES > 16
    TSS_SampleElectrodeLowE16,
  #endif
  #if TSS_N_ELECTRODES > 17
    TSS_SampleElectrodeLowE17,
  #endif
  #if TSS_N_ELECTRODES > 18
    TSS_SampleElectrodeLowE18,
  #endif
  #if TSS_N_ELECTRODES > 19
    TSS_SampleElectrodeLowE19,
  #endif
  #if TSS_N_ELECTRODES > 20
    TSS_SampleElectrodeLowE20,
  #endif
  #if TSS_N_ELECTRODES > 21
    TSS_SampleElectrodeLowE21,
  #endif
  #if TSS_N_ELECTRODES > 22
    TSS_SampleElectrodeLowE22,
  #endif
  #if TSS_N_ELECTRODES > 23
    TSS_SampleElectrodeLowE23,
  #endif
  #if TSS_N_ELECTRODES > 24
    TSS_SampleElectrodeLowE24,
  #endif
  #if TSS_N_ELECTRODES > 25
    TSS_SampleElectrodeLowE25,
  #endif
  #if TSS_N_ELECTRODES > 26
    TSS_SampleElectrodeLowE26,
  #endif
  #if TSS_N_ELECTRODES > 27
    TSS_SampleElectrodeLowE27,
  #endif
  #if TSS_N_ELECTRODES > 28
    TSS_SampleElectrodeLowE28,
  #endif
  #if TSS_N_ELECTRODES > 29
    TSS_SampleElectrodeLowE29,
  #endif
  #if TSS_N_ELECTRODES > 30
    TSS_SampleElectrodeLowE30,
  #endif
  #if TSS_N_ELECTRODES > 31
    TSS_SampleElectrodeLowE31,
  #endif
  #if TSS_N_ELECTRODES > 32
    TSS_SampleElectrodeLowE32,
  #endif
  #if TSS_N_ELECTRODES > 33
    TSS_SampleElectrodeLowE33,
  #endif
  #if TSS_N_ELECTRODES > 34
    TSS_SampleElectrodeLowE34,
  #endif
  #if TSS_N_ELECTRODES > 35
    TSS_SampleElectrodeLowE35,
  #endif
  #if TSS_N_ELECTRODES > 36
    TSS_SampleElectrodeLowE36,
  #endif
  #if TSS_N_ELECTRODES > 37
    TSS_SampleElectrodeLowE37,
  #endif
  #if TSS_N_ELECTRODES > 38
    TSS_SampleElectrodeLowE38,
  #endif
  #if TSS_N_ELECTRODES > 39
    TSS_SampleElectrodeLowE39,
  #endif
  #if TSS_N_ELECTRODES > 40
    TSS_SampleElectrodeLowE40,
  #endif
  #if TSS_N_ELECTRODES > 41
    TSS_SampleElectrodeLowE41,
  #endif
  #if TSS_N_ELECTRODES > 42
    TSS_SampleElectrodeLowE42,
  #endif
  #if TSS_N_ELECTRODES > 43
    TSS_SampleElectrodeLowE43,
  #endif
  #if TSS_N_ELECTRODES > 44
    TSS_SampleElectrodeLowE44,
  #endif
  #if TSS_N_ELECTRODES > 45
    TSS_SampleElectrodeLowE45,
  #endif
  #if TSS_N_ELECTRODES > 46
    TSS_SampleElectrodeLowE46,
  #endif
  #if TSS_N_ELECTRODES > 47
    TSS_SampleElectrodeLowE47,
  #endif
  #if TSS_N_ELECTRODES > 48
    TSS_SampleElectrodeLowE48,
  #endif
  #if TSS_N_ELECTRODES > 49
    TSS_SampleElectrodeLowE49,
  #endif
  #if TSS_N_ELECTRODES > 50
    TSS_SampleElectrodeLowE50,
  #endif
  #if TSS_N_ELECTRODES > 51
    TSS_SampleElectrodeLowE51,
  #endif
  #if TSS_N_ELECTRODES > 52
    TSS_SampleElectrodeLowE52,
  #endif
  #if TSS_N_ELECTRODES > 53
    TSS_SampleElectrodeLowE53,
  #endif
  #if TSS_N_ELECTRODES > 54
    TSS_SampleElectrodeLowE54,
  #endif
  #if TSS_N_ELECTRODES > 55
    TSS_SampleElectrodeLowE55,
  #endif
  #if TSS_N_ELECTRODES > 56
    TSS_SampleElectrodeLowE56,
  #endif
  #if TSS_N_ELECTRODES > 57
    TSS_SampleElectrodeLowE57,
  #endif
  #if TSS_N_ELECTRODES > 58
    TSS_SampleElectrodeLowE58,
  #endif
  #if TSS_N_ELECTRODES > 59
    TSS_SampleElectrodeLowE59,
  #endif
  #if TSS_N_ELECTRODES > 60
    TSS_SampleElectrodeLowE60,
  #endif
  #if TSS_N_ELECTRODES > 61
    TSS_SampleElectrodeLowE61,
  #endif
  #if TSS_N_ELECTRODES > 62
    TSS_SampleElectrodeLowE62,
  #endif
  #if TSS_N_ELECTRODES > 63
    TSS_SampleElectrodeLowE63,
  #endif
  };

  /***************** Global ROM Data definition *********************/

  const UINT8 * const tss_acp8ElectrodeROMData[TSS_N_ELECTRODES] = {
    #if TSS_N_ELECTRODES > 0
      (UINT8 *) &TSS_E0_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 1
      (UINT8 *) &TSS_E1_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 2
      (UINT8 *) &TSS_E2_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 3
      (UINT8 *) &TSS_E3_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 4
      (UINT8 *) &TSS_E4_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 5
      (UINT8 *) &TSS_E5_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 6
      (UINT8 *) &TSS_E6_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 7
      (UINT8 *) &TSS_E7_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 8
      (UINT8 *) &TSS_E8_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 9
      (UINT8 *) &TSS_E9_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 10
      (UINT8 *) &TSS_E10_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 11
      (UINT8 *) &TSS_E11_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 12
      (UINT8 *) &TSS_E12_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 13
      (UINT8 *) &TSS_E13_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 14
      (UINT8 *) &TSS_E14_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 15
      (UINT8 *) &TSS_E15_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 16
      (UINT8 *) &TSS_E16_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 17
      (UINT8 *) &TSS_E17_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 18
      (UINT8 *) &TSS_E18_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 19
      (UINT8 *) &TSS_E19_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 20
      (UINT8 *) &TSS_E20_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 21
      (UINT8 *) &TSS_E21_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 22
      (UINT8 *) &TSS_E22_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 23
      (UINT8 *) &TSS_E23_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 24
      (UINT8 *) &TSS_E24_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 25
      (UINT8 *) &TSS_E25_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 26
      (UINT8 *) &TSS_E26_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 27
      (UINT8 *) &TSS_E27_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 28
      (UINT8 *) &TSS_E28_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 29
      (UINT8 *) &TSS_E29_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 30
      (UINT8 *) &TSS_E30_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 31
      (UINT8 *) &TSS_E31_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 32
      (UINT8 *) &TSS_E32_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 33
      (UINT8 *) &TSS_E33_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 34
      (UINT8 *) &TSS_E34_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 35
      (UINT8 *) &TSS_E35_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 36
      (UINT8 *) &TSS_E36_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 37
      (UINT8 *) &TSS_E37_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 38
      (UINT8 *) &TSS_E38_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 39
      (UINT8 *) &TSS_E39_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 40
      (UINT8 *) &TSS_E40_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 41
      (UINT8 *) &TSS_E41_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 42
      (UINT8 *) &TSS_E42_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 43
      (UINT8 *) &TSS_E43_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 44
      (UINT8 *) &TSS_E44_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 45
      (UINT8 *) &TSS_E45_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 46
      (UINT8 *) &TSS_E46_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 47
      (UINT8 *) &TSS_E47_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 48
      (UINT8 *) &TSS_E48_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 49
      (UINT8 *) &TSS_E49_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 50
      (UINT8 *) &TSS_E50_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 51
      (UINT8 *) &TSS_E51_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 52
      (UINT8 *) &TSS_E52_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 53
      (UINT8 *) &TSS_E53_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 54
      (UINT8 *) &TSS_E54_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 55
      (UINT8 *) &TSS_E55_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 56
      (UINT8 *) &TSS_E56_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 57
      (UINT8 *) &TSS_E57_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 58
      (UINT8 *) &TSS_E58_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 59
      (UINT8 *) &TSS_E59_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 60
      (UINT8 *) &TSS_E60_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 61
      (UINT8 *) &TSS_E61_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 62
      (UINT8 *) &TSS_E62_ROMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 63
      (UINT8 *) &TSS_E63_ROMDATA_CONTEXT,
    #endif
  };

  /***************** Global RAM Data definition ********************/

  const UINT8 * tss_acp8ElectrodeRAMData[TSS_N_ELECTRODES] = {
    #if TSS_N_ELECTRODES > 0
      (UINT8 *) &TSS_E0_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 1
      (UINT8 *) &TSS_E1_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 2
      (UINT8 *) &TSS_E2_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 3
      (UINT8 *) &TSS_E3_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 4
      (UINT8 *) &TSS_E4_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 5
      (UINT8 *) &TSS_E5_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 6
      (UINT8 *) &TSS_E6_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 7
      (UINT8 *) &TSS_E7_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 8
      (UINT8 *) &TSS_E8_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 9
      (UINT8 *) &TSS_E9_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 10
      (UINT8 *) &TSS_E10_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 11
      (UINT8 *) &TSS_E11_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 12
      (UINT8 *) &TSS_E12_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 13
      (UINT8 *) &TSS_E13_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 14
      (UINT8 *) &TSS_E14_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 15
      (UINT8 *) &TSS_E15_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 16
      (UINT8 *) &TSS_E16_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 17
      (UINT8 *) &TSS_E17_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 18
      (UINT8 *) &TSS_E18_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 19
      (UINT8 *) &TSS_E19_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 20
      (UINT8 *) &TSS_E20_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 21
      (UINT8 *) &TSS_E21_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 22
      (UINT8 *) &TSS_E22_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 23
      (UINT8 *) &TSS_E23_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 24
      (UINT8 *) &TSS_E24_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 25
      (UINT8 *) &TSS_E25_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 26
      (UINT8 *) &TSS_E26_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 27
      (UINT8 *) &TSS_E27_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 28
      (UINT8 *) &TSS_E28_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 29
      (UINT8 *) &TSS_E29_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 30
      (UINT8 *) &TSS_E30_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 31
      (UINT8 *) &TSS_E31_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 32
      (UINT8 *) &TSS_E32_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 33
      (UINT8 *) &TSS_E33_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 34
      (UINT8 *) &TSS_E34_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 35
      (UINT8 *) &TSS_E35_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 36
      (UINT8 *) &TSS_E36_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 37
      (UINT8 *) &TSS_E37_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 38
      (UINT8 *) &TSS_E38_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 39
      (UINT8 *) &TSS_E39_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 40
      (UINT8 *) &TSS_E40_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 41
      (UINT8 *) &TSS_E41_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 42
      (UINT8 *) &TSS_E42_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 43
      (UINT8 *) &TSS_E43_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 44
      (UINT8 *) &TSS_E44_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 45
      (UINT8 *) &TSS_E45_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 46
      (UINT8 *) &TSS_E46_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 47
      (UINT8 *) &TSS_E47_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 48
      (UINT8 *) &TSS_E48_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 49
      (UINT8 *) &TSS_E49_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 50
      (UINT8 *) &TSS_E50_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 51
      (UINT8 *) &TSS_E51_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 52
      (UINT8 *) &TSS_E52_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 53
      (UINT8 *) &TSS_E53_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 54
      (UINT8 *) &TSS_E54_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 55
      (UINT8 *) &TSS_E55_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 56
      (UINT8 *) &TSS_E56_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 57
      (UINT8 *) &TSS_E57_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 58
      (UINT8 *) &TSS_E58_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 59
      (UINT8 *) &TSS_E59_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 60
      (UINT8 *) &TSS_E60_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 61
      (UINT8 *) &TSS_E61_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 62
      (UINT8 *) &TSS_E62_RAMDATA_CONTEXT,
    #endif
    #if TSS_N_ELECTRODES > 63
      (UINT8 *) &TSS_E63_RAMDATA_CONTEXT,
    #endif
  };
    
    /* 
  * Functions are defined according to the number of declared electrodes,
  * this way only the functions needed are compiled
  */

  /* Samples EX electrode */
  #if TSS_N_ELECTRODES > 0
  UINT16 TSS_SampleElectrodeLowE0(void)
  {
    UINT16 u16Result = 0u;

    TSS_E0_SAMPLE_ELECTRODE_LOW();
    
    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 1
  UINT16 TSS_SampleElectrodeLowE1(void)
  {
    UINT16 u16Result = 0u;

    TSS_E1_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 2
  UINT16 TSS_SampleElectrodeLowE2(void)
  {
    UINT16 u16Result = 0u;

    TSS_E2_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 3
  UINT16 TSS_SampleElectrodeLowE3(void)
  {
    UINT16 u16Result = 0u;

    TSS_E3_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 4
  UINT16 TSS_SampleElectrodeLowE4(void)
  {
    UINT16 u16Result = 0u;

    TSS_E4_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 5
  UINT16 TSS_SampleElectrodeLowE5(void)
  {
    UINT16 u16Result = 0u;

    TSS_E5_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 6
  UINT16 TSS_SampleElectrodeLowE6(void)
  {
    UINT16 u16Result = 0u;

    TSS_E6_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 7
  UINT16 TSS_SampleElectrodeLowE7(void)
  {
    UINT16 u16Result = 0u;

    TSS_E7_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 8
  UINT16 TSS_SampleElectrodeLowE8(void)
  {
    UINT16 u16Result = 0u;

    TSS_E8_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 9
  UINT16 TSS_SampleElectrodeLowE9(void)
  {
    UINT16 u16Result = 0u;

    TSS_E9_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 10
  UINT16 TSS_SampleElectrodeLowE10(void)
  {
    UINT16 u16Result = 0u;

    TSS_E10_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 11
  UINT16 TSS_SampleElectrodeLowE11(void)
  {
    UINT16 u16Result = 0u;

    TSS_E11_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 12
  UINT16 TSS_SampleElectrodeLowE12(void)
  {
    UINT16 u16Result = 0u;

    TSS_E12_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 13
  UINT16 TSS_SampleElectrodeLowE13(void)
  {
    UINT16 u16Result = 0u;

    TSS_E13_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 14
  UINT16 TSS_SampleElectrodeLowE14(void)
  {
    UINT16 u16Result = 0u;

    TSS_E14_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 15
  UINT16 TSS_SampleElectrodeLowE15(void)
  {
    UINT16 u16Result = 0u;

    TSS_E15_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 16
  UINT16 TSS_SampleElectrodeLowE16(void)
  {
    UINT16 u16Result = 0u;

    TSS_E16_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 17
  UINT16 TSS_SampleElectrodeLowE17(void)
  {
    UINT16 u16Result = 0u;

    TSS_E17_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 18
  UINT16 TSS_SampleElectrodeLowE18(void)
  {
    UINT16 u16Result = 0u;

    TSS_E18_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 19
  UINT16 TSS_SampleElectrodeLowE19(void)
  {
    UINT16 u16Result = 0u;

    TSS_E19_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 20
  UINT16 TSS_SampleElectrodeLowE20(void)
  {
    UINT16 u16Result = 0u;

    TSS_E20_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 21
  UINT16 TSS_SampleElectrodeLowE21(void)
  {
    UINT16 u16Result = 0u;

    TSS_E21_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 22
  UINT16 TSS_SampleElectrodeLowE22(void)
  {
    UINT16 u16Result = 0u;

    TSS_E22_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 23
  UINT16 TSS_SampleElectrodeLowE23(void)
  {
    UINT16 u16Result = 0u;

    TSS_E23_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 24
  UINT16 TSS_SampleElectrodeLowE24(void)
  {
    UINT16 u16Result = 0u;

    TSS_E24_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 25
  UINT16 TSS_SampleElectrodeLowE25(void)
  {
    UINT16 u16Result = 0u;

    TSS_E25_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 26
  UINT16 TSS_SampleElectrodeLowE26(void)
  {
    UINT16 u16Result = 0u;

    TSS_E26_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 27
  UINT16 TSS_SampleElectrodeLowE27(void)
  {
    UINT16 u16Result = 0u;

    TSS_E27_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 28
  UINT16 TSS_SampleElectrodeLowE28(void)
  {
    UINT16 u16Result = 0u;

    TSS_E28_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 29
  UINT16 TSS_SampleElectrodeLowE29(void)
  {
    UINT16 u16Result = 0u;

    TSS_E29_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 30
  UINT16 TSS_SampleElectrodeLowE30(void)
  {
    UINT16 u16Result = 0u;

    TSS_E30_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 31
  UINT16 TSS_SampleElectrodeLowE31(void)
  {
    UINT16 u16Result = 0u;

    TSS_E31_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 32
  UINT16 TSS_SampleElectrodeLowE32(void)
  {
    UINT16 u16Result = 0u;

    TSS_E32_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 33
  UINT16 TSS_SampleElectrodeLowE33(void)
  {
    UINT16 u16Result = 0u;

    TSS_E33_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 34
  UINT16 TSS_SampleElectrodeLowE34(void)
  {
    UINT16 u16Result = 0u;

    TSS_E34_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 35
  UINT16 TSS_SampleElectrodeLowE35(void)
  {
    UINT16 u16Result = 0u;

    TSS_E35_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 36
  UINT16 TSS_SampleElectrodeLowE36(void)
  {
    UINT16 u16Result = 0u;

    TSS_E36_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 37
  UINT16 TSS_SampleElectrodeLowE37(void)
  {
    UINT16 u16Result = 0u;

    TSS_E37_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 38
  UINT16 TSS_SampleElectrodeLowE38(void)
  {
    UINT16 u16Result = 0u;

    TSS_E38_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 39
  UINT16 TSS_SampleElectrodeLowE39(void)
  {
    UINT16 u16Result = 0u;

    TSS_E39_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 40
  UINT16 TSS_SampleElectrodeLowE40(void)
  {
    UINT16 u16Result = 0u;

    TSS_E40_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 41
  UINT16 TSS_SampleElectrodeLowE41(void)
  {
    UINT16 u16Result = 0u;

    TSS_E41_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 42
  UINT16 TSS_SampleElectrodeLowE42(void)
  {
    UINT16 u16Result = 0u;

    TSS_E42_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 43
  UINT16 TSS_SampleElectrodeLowE43(void)
  {
    UINT16 u16Result = 0u;

    TSS_E43_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 44
  UINT16 TSS_SampleElectrodeLowE44(void)
  {
    UINT16 u16Result = 0u;

    TSS_E44_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 45
  UINT16 TSS_SampleElectrodeLowE45(void)
  {
    UINT16 u16Result = 0u;

    TSS_E45_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 46
  UINT16 TSS_SampleElectrodeLowE46(void)
  {
    UINT16 u16Result = 0u;

    TSS_E46_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 47
  UINT16 TSS_SampleElectrodeLowE47(void)
  {
    UINT16 u16Result = 0u;

    TSS_E47_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 48
  UINT16 TSS_SampleElectrodeLowE48(void)
  {
    UINT16 u16Result = 0u;

    TSS_E48_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 49
  UINT16 TSS_SampleElectrodeLowE49(void)
  {
    UINT16 u16Result = 0u;

    TSS_E49_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 50
  UINT16 TSS_SampleElectrodeLowE50(void)
  {
    UINT16 u16Result = 0u;

    TSS_E50_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 51
  UINT16 TSS_SampleElectrodeLowE51(void)
  {
    UINT16 u16Result = 0u;

    TSS_E51_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 52
  UINT16 TSS_SampleElectrodeLowE52(void)
  {
    UINT16 u16Result = 0u;

    TSS_E52_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 53
  UINT16 TSS_SampleElectrodeLowE53(void)
  {
    UINT16 u16Result = 0u;

    TSS_E53_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 54
  UINT16 TSS_SampleElectrodeLowE54(void)
  {
    UINT16 u16Result = 0u;

    TSS_E54_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 55
  UINT16 TSS_SampleElectrodeLowE55(void)
  {
    UINT16 u16Result = 0u;

    TSS_E55_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 56
  UINT16 TSS_SampleElectrodeLowE56(void)
  {
    UINT16 u16Result = 0u;

    TSS_E56_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 57
  UINT16 TSS_SampleElectrodeLowE57(void)
  {
    UINT16 u16Result = 0u;

    TSS_E57_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 58
  UINT16 TSS_SampleElectrodeLowE58(void)
  {
    UINT16 u16Result = 0u;

    TSS_E58_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 59
  UINT16 TSS_SampleElectrodeLowE59(void)
  {
    UINT16 u16Result = 0u;

    TSS_E59_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 60
  UINT16 TSS_SampleElectrodeLowE60(void)
  {
    UINT16 u16Result = 0u;

    TSS_E60_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 61
  UINT16 TSS_SampleElectrodeLowE61(void)
  {
    UINT16 u16Result = 0u;

    TSS_E61_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 62
  UINT16 TSS_SampleElectrodeLowE62(void)
  {
    UINT16 u16Result = 0u;

    TSS_E62_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

  #if TSS_N_ELECTRODES > 63
  UINT16 TSS_SampleElectrodeLowE63(void)
  {
    UINT16 u16Result = 0u;

    TSS_E63_SAMPLE_ELECTRODE_LOW();

    return u16Result;
  }
  #endif

#if TSS_HCS08_MCU || TSS_CFV1_MCU

  #if TSS_USE_SIMPLE_LOW_LEVEL  

    /***************************************************************************//*!
    *
    * @brief  Initializes the modules for the sensing of the electrodes
    *
    * @param  Nothing
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 TSS_SensorInit(UINT8 u8Command)
    {
        UINT8 u8result = TSS_INIT_STATUS_OK;
  
        if ((u8Command == TSS_INIT_COMMAND_INIT_MODULES) || (u8Command == TSS_INIT_COMMAND_ENABLE_ELECTRODES) || (u8Command == TSS_INIT_COMMAND_RECALIBRATE))
        {
        /* Global Timer Initialization */
        #if TSS_HW_TIMER_USED
          TSS_HW_TIMER_STOP();                                   /* Stops the timer */
          TSS_HW_TIMER_RESET();                                  /* Resets the timer */
          #ifdef TSS_ONPROXIMITY_CALLBACK          
            if (tss_CSSys.SystemConfig.ProximityEn)
            {
              TSS_HW_TIMER_SET_PRESCALE(TSS_SENSOR_PROX_PRESCALER);  /* Sets a preescaler value */
              TSS_HW_TIMER_SET_MOD(TSS_SENSOR_PROX_TIMEOUT);         /* Sets the timeout value */            
            }else{
              TSS_HW_TIMER_SET_PRESCALE(TSS_SENSOR_PRESCALER);       /* Sets a preescaler value */
              TSS_HW_TIMER_SET_MOD(TSS_SENSOR_TIMEOUT);              /* Sets the timeout value */            
            }                
          #else
              TSS_HW_TIMER_SET_PRESCALE(TSS_SENSOR_PRESCALER);       /* Sets a preescaler value */
              TSS_HW_TIMER_SET_MOD(TSS_SENSOR_TIMEOUT);              /* Sets the timeout value */            
          #endif
          TSS_HW_TIMER_ENABLE_INT();                             /* Enable Timer interrupt */          
        #endif
        
        /* GPIO Method Initialization */
        #if TSS_DETECT_METHOD(GPIO)
          (void) GPIO_SensorInit();  
        #endif
        }
      
        /* TSIL Initialization */
        #if TSS_DETECT_METHOD(TSIL)
          u8result = TSIL_SensorInit(u8Command);
        #endif
   
        return u8result;
    }
  
    /***************************************************************************//*!
    *
    * @brief  Performs a valid reading of one electrode stores the timer values 
    *         and returns a status code
    *
    * @param  u8ElecNum Electrode number to be scanned
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    #if TSS_HW_GPIO_USED
      
      UINT8 UNI_SampleElectrode(UINT8 u8ElecNum, UINT8 u8Command)
      {
          UINT8 u8NSamp;
          UINT8 u8ElectrodeStatus;  
          UINT16 u16CapSubSample;
          UINT8 u8FaultCnt;
    
          #if TSS_USE_NOISE_AMPLITUDE_FILTER
            INT8 i8AmplitudeFilterDeltaLimitTemp;
            UINT16 *pu16AmplitudeFilterBaseTemp;        
          #endif
          
          if (u8Command == TSS_SAMPLE_COMMAND_RESTART) 
          {
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;           
          } else if (u8Command == TSS_SAMPLE_COMMAND_PROCESS) 
          {  
            /* Initialization of variables */
            tss_u8HWTimerFlag = 0u;
            tss_u16CapSample = 0u;
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;                  /* Sets status */
            u8FaultCnt = 0u;
    
            u8NSamp = tss_CSSys.NSamples;
    
            #if TSS_USE_NOISE_AMPLITUDE_FILTER
              pu16AmplitudeFilterBaseTemp = &(((TSS_GENERIC_ELECTRODE_RAMDATA *) (tss_acp8ElectrodeRAMData[u8ElecNum]))->gen_u16AmplitudeFilterBase);
              
              if (*pu16AmplitudeFilterBaseTemp == 0u) {
                i8AmplitudeFilterDeltaLimitTemp = 127;
              } else {
                i8AmplitudeFilterDeltaLimitTemp = ((TSS_GENERIC_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElecNum]))->gen_ci8AmplitudeFilterDeltaLimit;            
              }
            #endif
    
            /* Main oversampling measurement loop */
            while(u8NSamp)
            {
                #if TSS_HW_TIMER_USED
                  TSS_HW_TIMER_STOP();                          /* Stops the HW Timer  */
                  TSS_HW_TIMER_RESET();                         /* Resets the HW Timer */
                #endif  
                TSS_CLEAR_SAMPLE_INTERRUPTED_FLAG();            /* Clears the interrupt sample flag */
                
                u16CapSubSample = tss_faSampleElectrodeLow[u8ElecNum]();             /* Samples one electrode */
                
                if(!TSS_FAULT_DETECTED)                     /* Verifies that no fault has occurred */
                {            
                    if(!TSS_SAMPLE_INTERRUPTED)             /* Verifies that the sample has not been inturrupted*/
                    {
                      #if TSS_USE_NOISE_AMPLITUDE_FILTER
                        if (TSS_u16NoiseAmplitudeFilter(u16CapSubSample, pu16AmplitudeFilterBaseTemp, i8AmplitudeFilterDeltaLimitTemp)) 
                        {
                          u8FaultCnt++;                                      
                        } 
                        else 
                        { 
                          tss_u16CapSample += u16CapSubSample;
                          u8NSamp--;
                          u8FaultCnt = 0u;                 /* Restart Fault counter due long cyclic interrupts */
                        }
                        
                      #else
                        tss_u16CapSample += u16CapSubSample;
                        u8NSamp--;
                        u8FaultCnt = 0u;                   /* Restart Fault counter due long cyclic interrupts */
                      #endif  
                    }
                    else
                    {    
                      /* Do nothing if interrupt occured and do sample again in next loop*/
                      u8FaultCnt++; 
                    }
                }
                else
                {
                    TSS_SET_ELECTRODE_OUTPUT_LOW();               /* Sets the electrode to OUTPUT LOW default value bacause short was detected there */
                    u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT; /* If a fault has occurred sets the return status code error */
                    u8NSamp = 0u;                                  
                }
                
                if(u8FaultCnt >= TSS_FAULT_TIMEOUT) {
                    u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT; /* If a fault has occurred sets the return status code error */
                    u8NSamp = 0u; 
                }        
            }
    
            if ((tss_u16CapSample < TSS_KEYDETECT_CAP_LOWER_LIMIT) && (u8ElectrodeStatus != TSS_SAMPLE_ERROR_CHARGE_TIMEOUT)) 
            {
              u8ElectrodeStatus = TSS_SAMPLE_ERROR_SMALL_CAP;
            }
    
            #if TSS_USE_NOISE_AMPLITUDE_FILTER
              if (u8ElectrodeStatus == TSS_SAMPLE_STATUS_OK) {
                if (*pu16AmplitudeFilterBaseTemp == 0u) {
                  *pu16AmplitudeFilterBaseTemp = (UINT16) (tss_u16CapSample / tss_CSSys.NSamples);
                }
              } else {
                *pu16AmplitudeFilterBaseTemp = 0u; /* Initiate Amplitude Filter Base refresh */
              }
            #endif
          } else if (u8Command == TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE) 
          {
            /* Return the same electrode number because there is no more electrodes in the module */
            u8ElectrodeStatus = u8ElecNum;
          } else if (u8Command == TSS_SAMPLE_COMMAND_RECALIB) 
          {
            /* Do Nothing because the Command is no relevant for GPIO Method */
            u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
          } 
    
          return u8ElectrodeStatus;   /* Return status code */ 
      }
    #endif
  
    /***************************************************************************//*!
    *
    * @brief  HW Timer Overflow Interrupt handlers. Occurrs when there has been 
    *         a timeout in the SampleElectrode Function
    *
    * @param  void
    *
    * @return void
    *
    * @remarks
    *
    ****************************************************************************/
    #if TSS_HW_TIMER_USED
      interrupt 
      #if !TSS_USE_PE_COMPONENT
        TSS_HW_TIMER_VECTOR
      #endif
      void TSS_HWTimerIsr(
        #if TSS_USE_MQX
          void* _isrParameter
        #else
          void
        #endif
        )
      {
        TSS_HW_TIMER_CLEARFLAG();              /* TSS TPM/FTM/MTIM Clear Flag */
        tss_u8HWTimerFlag = 1u;                /* Set measurement Overflow Flag variable */
        TSS_SET_ELECTRODE_OUTPUT_HIGH();       /* For escape from measurement loop */
      }
    #endif

  #else /* TSS_USE_SIMPLE_LOW_LEVEL == 0 */ 
  
    UINT8 TSS_SensorInit(UINT8 u8Command)
    {
        UINT8 u8Result = TSS_INIT_STATUS_OK;
        UINT8 u8ElCounter1;
        UINT8 u8ElCounter2;
        UINT8 tss_au8ElectrodeInitialized[((TSS_N_ELECTRODES - 1)/ 8) + 1];
  
        TSS_GENERIC_METHOD_ROMDATA *psMethodROMDataStruct;
  
        /* Erase tss_au8ElectrodeInitialized array */
        for(u8ElCounter1 = 0; u8ElCounter1 < (((TSS_N_ELECTRODES - 1U) / 8U) + 1U); u8ElCounter1++)
        {
          tss_au8ElectrodeInitialized[u8ElCounter1] = 0u;  
        }
        /* Execute Init of all Modules */
        for(u8ElCounter1 = 0; u8ElCounter1 < TSS_N_ELECTRODES; u8ElCounter1++)
        {
          if (!(tss_au8ElectrodeInitialized[u8ElCounter1 >> 3u] & (1u << (u8ElCounter1 & 0x07u)))) /* Do each module just once */
          {  
            psMethodROMDataStruct = (TSS_GENERIC_METHOD_ROMDATA *) (((TSS_GENERIC_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter1]))->gen_cpsMethodROMData);
            /* Execute MethodControl Function*/
            u8Result |= (psMethodROMDataStruct->gen_cpfMethodControl) (u8ElCounter1, u8Command);
            /* Check if another the same modules are there */
            for(u8ElCounter2 = u8ElCounter1; u8ElCounter2 < TSS_N_ELECTRODES; u8ElCounter2++)
            {
              if (psMethodROMDataStruct == (TSS_GENERIC_METHOD_ROMDATA *) (((TSS_GENERIC_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter2]))->gen_cpsMethodROMData)) 
              {
                tss_au8ElectrodeInitialized[u8ElCounter2 >> 3u] |= (1u << (u8ElCounter2 & 0x07u)); /* Mark all the same modules */
              }
            }
          }  
        }
              
        return u8Result;
    }
  
    /***************************************************************************//*!
    *
    * @brief  HW Timer Overflow Interrupt handlers. Occurs when there has been 
    *         a timeout in the SampleElectrode Function
    *
    * @param  void
    *
    * @return void
    *
    * @remarks
    *
    ****************************************************************************/
    #if TSS_HW_TIMER_USED
      interrupt 
      #if !TSS_USE_PE_COMPONENT
        TSS_HW_TIMER_VECTOR
      #endif
      void TSS_HWTimerIsr(
        #if TSS_USE_MQX
          void* _isrParameter
        #else
          void
        #endif
        )
      {
        /* Clear HW Timer Flag */
        ((TSS_TPMFTM_MemMapPtr) tss_psElectrodeTimertAdr)->SC &= TSS_HW_TPMFTM_FLAG_ACK;
        /* Set Overflow Flag */
        tss_u8HWTimerFlag = 1u;                /* Set measurement Overflow Flag variable */
        /* For escape from measurement loop */
        TSS_SET_ELECTRODE_OUTPUT_HIGH();       
      }
    #endif
  
  #endif /* End of TSS_USE_SIMPLE_LOW_LEVEL == 0 */

#elif TSS_KINETIS_MCU || TSS_CFM_MCU
  
  UINT8 TSS_SensorInit(UINT8 u8Command)
  {
      UINT8 u8Result = TSS_INIT_STATUS_OK;
      UINT8 u8ElCounter1;
      UINT8 u8ElCounter2;
      UINT8 tss_au8ElectrodeInitialized[((TSS_N_ELECTRODES - 1)/ 8) + 1];
      
      TSS_GENERIC_METHOD_ROMDATA *psMethodROMDataStruct;

      /* Erase tss_au8ElectrodeInitialized array */
      for(u8ElCounter1 = 0; u8ElCounter1 < (((TSS_N_ELECTRODES - 1U) / 8U) + 1U); u8ElCounter1++)
      {
        tss_au8ElectrodeInitialized[u8ElCounter1] = 0u;  
      }
      /* Execute Init of all Modules */
      for(u8ElCounter1 = 0; u8ElCounter1 < TSS_N_ELECTRODES; u8ElCounter1++)
      {
        if (!(tss_au8ElectrodeInitialized[u8ElCounter1 / 8u] & (1u << (u8ElCounter1 % 8u)))) /* Do each module just once */
        {  
          psMethodROMDataStruct = (TSS_GENERIC_METHOD_ROMDATA *) ((TSS_GENERIC_ELECTRODE_ROMDATA *)tss_acp8ElectrodeROMData[u8ElCounter1])->gen_cpsMethodROMData;
          /* Execute MethodControl Function*/
          u8Result |= (psMethodROMDataStruct->gen_cpfMethodControl) (u8ElCounter1, u8Command);           
          /* Check if another the same modules are there */
          for(u8ElCounter2 = u8ElCounter1; u8ElCounter2 < TSS_N_ELECTRODES; u8ElCounter2++)
          {
            if (psMethodROMDataStruct == ((TSS_GENERIC_METHOD_ROMDATA *) ((TSS_GENERIC_ELECTRODE_ROMDATA *)tss_acp8ElectrodeROMData[u8ElCounter2])->gen_cpsMethodROMData)) 
            {
              tss_au8ElectrodeInitialized[u8ElCounter2 / 8u] |= (1u << (u8ElCounter2 % 8u)); /* Mark all the same modules */
            } 
          }  
        }  
      }        
      
      return u8Result;
  }

  /***************************************************************************//*!
  *
  * @brief  HW Timer Overflow Interrupt handlers. Occurrs when there has been 
  *         a timeout in the SampleElectrode Function
  *
  * @param  void
  *
  * @return void
  *
  * @remarks
  *
  ****************************************************************************/
  #if TSS_HW_TIMER_USED
    #if TSS_ENABLE_DIAGNOSTIC_MESSAGES
      #warning TSS - Please assign ISR function TSS_HWTimerIsr to TSS_HW_TIMER vector  
    #endif
	#if TSS_CFM_MCU
   	  interrupt 
	#endif
      void TSS_HWTimerIsr(
        #if TSS_USE_MQX
          void* _isrParameter
        #else
          void
        #endif
        )
    {
      /* Clear HW Timer Flag */
      ((TSS_TPMFTM_MemMapPtr) tss_psElectrodeTimertAdr)->SC &= TSS_HW_TPMFTM_FLAG_ACK;         /* Clear HW TImer Flag */
      /* Set Overflow Flag */
      tss_u8HWTimerFlag = 1u;                /* Set measurement Overflow Flag variable */
    }
  #endif

#else /* End of TSS_KINETIS_MCU || TSS_CFM_MCU */
  #error "TSS - Not supported MCU used"  
#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/ftpd_cmd.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpd_cmd.c$
* $Version : 3.8.28.0$
* $Date    : Aug-7-2012$
*
* Comments:
*
*   This file contains an implementation of an
*   FTP server.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <rtcs.h>
#include <fio.h>
#include "ftpd.h"
#include "ftpd_msg.h"

#if FTPDCFG_USES_MFS
#include <mfs.h>
#endif

#define hexnum(c)  ((c<='9')?(c-'0'):((c<='F')?(c-'A'+10) :(c-'a'+10))) 

// Set externally to define a user file
char_ptr FTPd_userfile = NULL;
#define fs_get_default( ) session_ptr->FS

static uint_16  FTPd_pasv_port = FTPD_PASV_PORT_START;

/*
static char_ptr months[] =  
{
   "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 
};
*/

static void FTPd_convert_percents( char_ptr arg_ptr)
{
   char_ptr   sptr = arg_ptr, dptr = arg_ptr;
   
   while (*sptr)  {
      if ((*sptr == '%') && isxdigit(sptr[1]) && isxdigit(sptr[2]))  {
         *dptr++ = (hexnum(sptr[1]) << 4) + hexnum(sptr[2]);
         sptr+=3;
      } else  {
         *dptr++ = *sptr++;
      }
   }
   *dptr = '\0';
}

static char_ptr FTPd_strip_path_delimiters( char_ptr arg_ptr)
{
   char_ptr   ptr;
   uint_32    len;
    
   ptr = arg_ptr;
   len = strlen(ptr);
   if (len > 2)  {
      if ((ptr[0] == '/') &&  (ptr[1] == '\\') && (ptr[2] == '/'))  {
         ptr +=2;
         len -=2;
      }
   }
   if (len > 2)  {
      if (ptr[len-1] == '/') ptr[len-1] = '\0';   
   }
   
   return ptr;
}


#if FTPDCFG_USES_MFS

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_cd
* Returned Value   :  int_32 error code
* Comments  :  mount a filesystem on a device.
*
* Usage:  cd <directory>
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_cd(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   int_32      error;
   char_ptr    ptr;
   char_ptr    abs_path = NULL;
   uint_16     rootdir_len,fsname_len;
   
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   

   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   } 

   FTPd_convert_percents(arg_ptr);
   ptr = FTPd_strip_path_delimiters(arg_ptr);

   if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      return FTPd_ERROR;
   }
   
   // convert to absolute path
   error = _io_rel2abs(abs_path,
                      session_ptr->CURRENT_FS_DIR,
                      ptr,
                      min(PATHNAME_SIZE, FTPD_PATHLEN),
                      session_ptr->CURRENT_FS_NAME);   
   
   // check if path exist
   if(!error)
   {
     error = ioctl(session_ptr->CURRENT_FS, IO_IOCTL_CHECK_DIR_EXIST,(pointer)abs_path );
   }

   // calculate root dir length
   rootdir_len = session_ptr->CURRENT_FTP_DIR - session_ptr->CURRENT_FS_DIR;
   fsname_len = strlen(session_ptr->CURRENT_FS_NAME);
   
   // check if there is an error and  check if we are still uder FTP root   
   if (error || strncmp(session_ptr->CURRENT_FS_DIR,abs_path + fsname_len,rootdir_len)) {
      FTPd_send_msg(session_ptr, ftpmsg_cd_error);
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   }

   // change current dir(skip device name)
   strcpy(session_ptr->CURRENT_FS_DIR,abs_path+(strlen(session_ptr->CURRENT_FS_NAME)));

   MFS_free_path(abs_path);
   return FTPd_pwd(session_ptr,"pwd" , "");
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_cdup
* Returned Value   :  int_32 error code
* Comments  :  change to parent directory.
*
* Usage:  cdup
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_cdup(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   char tmp_cmd[] = "..";
   return FTPd_cd(session_ptr,cmd_ptr,tmp_cmd);
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_feat
* Returned Value   :  int_32 error code
* Comments  :  Returns supported feature.
*
* Usage:  feat
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_feat(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ 
   FTPd_send_msg(session_ptr, "211-Features:\r\n");
   FTPd_send_msg(session_ptr, " SIZE\r\n");
   FTPd_send_msg(session_ptr, "211 End\r\n");

   return FTPd_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_dele
* Returned Value   :  int_32 error code
* Comments  :  mount a filesystem on a device.
*
* Usage:  dele <file>
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_dele(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   int_32      error;
   char_ptr    ptr,abs_path = NULL;

   
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   FTPd_convert_percents(arg_ptr);
   ptr = FTPd_strip_path_delimiters(arg_ptr);
 
   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   } 

   if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      return FTPd_ERROR;
   }

   error = _io_rel2abs(abs_path,
                      session_ptr->CURRENT_FS_DIR,
                      ptr,
                      min(PATHNAME_SIZE, FTPD_PATHLEN),
                      session_ptr->CURRENT_FS_NAME);       
   if(!error)
   {
      error = ioctl(session_ptr->CURRENT_FS, IO_IOCTL_DELETE_FILE, (pointer) abs_path);
   }
   
   if(error)  {
      FTPd_send_msg(session_ptr, ftpmsg_delete_error );
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   }

   sprintf(session_ptr->DATA_BUFFER_PTR, "257 \"%s\" deleted.\r\n",arg_ptr);
   FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);
   MFS_free_path(abs_path);
   return FTPd_OK;
}

#endif

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_help
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

#define FTPD_HELP_SPACE_NEEDED 16
int_32  FTPd_help(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{
   FTPd_COMMAND_PTR     command_ptr; 
   uint_32              i,len;
   
   FTPd_send_msg(session_ptr, ftpmsg_help_start);
   
   command_ptr = (FTPd_COMMAND_PTR) FTPd_commands; 
   for (i=0,len=0; command_ptr->COMMAND != NULL; i++,command_ptr++)   {
      // make sure there is room.
      if ((len +FTPD_HELP_SPACE_NEEDED) > session_ptr->DATA_BUFFER_SIZE) {
         FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);
         len = 0;
      }
   
      len += sprintf(&session_ptr->DATA_BUFFER_PTR[len],"%-10s ", command_ptr->COMMAND);
      if ((i%6)==5) len+= sprintf(&session_ptr->DATA_BUFFER_PTR[len],"\n");        
   } /* Endwhile */        
   if ((i%6)!=0) len+= sprintf(&session_ptr->DATA_BUFFER_PTR[len],"\n");        
   FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);

   FTPd_send_msg(session_ptr, ftpmsg_help_end);

   return FTPd_OK;
}



#if FTPDCFG_USES_MFS

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_list
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_list(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   uint_32              data_sock;
   int_32               len, error;
   char_ptr             path_ptr;
   pointer              dir_ptr;
   

#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   if (*arg_ptr == '\0')  {
      path_ptr = "*.*";
   } else  {
      FTPd_convert_percents(arg_ptr);
      path_ptr = FTPd_strip_path_delimiters(arg_ptr);
   }
   
   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   } 
   
   error = ioctl(session_ptr->CURRENT_FS, IO_IOCTL_CHANGE_CURRENT_DIR, session_ptr->CURRENT_FS_DIR);
   if(error)
   {
      FTPd_send_msg(session_ptr, ftpmsg_cd_error);
      return FTPd_ERROR;
   }   
   
   dir_ptr = _io_mfs_dir_open( session_ptr->CURRENT_FS, path_ptr, "u*");
   
   if (dir_ptr == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_file);
      return FTPd_ERROR;
   } 
   
   FTPd_send_msg(session_ptr, ftpmsg_opening_datacon);
   if (session_ptr->PASV_MODE)  {
      data_sock = session_ptr->PASV_SOCK;
   } else  {
      data_sock = FTPd_open_active_data_connection(session_ptr);
   }
   
   if (data_sock == RTCS_SOCKET_ERROR)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_datacon);
      return FTPd_ERROR;
   } 
   
   while ((len = _io_mfs_dir_read(dir_ptr, session_ptr->DATA_BUFFER_PTR, session_ptr->DATA_BUFFER_SIZE))>0)  {
      if (send(data_sock, session_ptr->DATA_BUFFER_PTR, len, 0) != len) { 
         FTPd_send_msg(session_ptr, ftpmsg_writefail);
         break;
      }
   } 
         
   _io_mfs_dir_close(dir_ptr);      
 
   shutdown(data_sock, FTPDCFG_DATA_SHUTDOWN_OPTION );
   session_ptr->PASV_MODE = FALSE;
   session_ptr->PASV_SOCK = RTCS_SOCKET_ERROR;
   FTPd_send_msg(session_ptr, ftpmsg_tx_complete);
            
   return FTPd_OK;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_mkdir
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  mkdir <directory>
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_mkdir(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   int_32      error;
   char_ptr    path_ptr,abs_path = NULL;

   
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   FTPd_convert_percents(arg_ptr);
   path_ptr = FTPd_strip_path_delimiters(arg_ptr);
   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   } 

   if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      return FTPd_ERROR;
   }

   error = _io_rel2abs(abs_path,
                      session_ptr->CURRENT_FS_DIR,
                      path_ptr,
                      min(PATHNAME_SIZE, FTPD_PATHLEN),
                      session_ptr->CURRENT_FS_NAME);       
   if(!error)
   {
      error = ioctl(session_ptr->CURRENT_FS, IO_IOCTL_CREATE_SUBDIR, (pointer) abs_path);
   }

   if(error)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   }
      
   sprintf(session_ptr->DATA_BUFFER_PTR, "257 \"%s\" directory created.\r\n",arg_ptr);
   FTPd_send_msg(session_ptr,  session_ptr->DATA_BUFFER_PTR );

   MFS_free_path(abs_path);

   return FTPd_OK;
}

   
   
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_nlst
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_nlst(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   uint_32              data_sock;
   int                  len;
   char_ptr             path_ptr;
   pointer              dir_ptr;
   

#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   if (*arg_ptr == '\0')  {
      path_ptr = "*.*";
   } else  {
      FTPd_convert_percents(arg_ptr);
      path_ptr = FTPd_strip_path_delimiters(arg_ptr);
   }
   
   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   } 

   ioctl(session_ptr->CURRENT_FS, IO_IOCTL_CHANGE_CURRENT_DIR, session_ptr->CURRENT_FS_DIR);
   
   dir_ptr = _io_mfs_dir_open(session_ptr->CURRENT_FS,path_ptr, "f*");
   
   if (dir_ptr == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_file);
      return FTPd_ERROR;
   } 
   
   FTPd_send_msg(session_ptr, ftpmsg_opening_datacon);
   if (session_ptr->PASV_MODE)  {
      data_sock = session_ptr->PASV_SOCK;
   } else  {
      data_sock = FTPd_open_active_data_connection(session_ptr);
   }
   
   if (data_sock == RTCS_SOCKET_ERROR)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_datacon);
      return FTPd_ERROR;
   } 
   
   while ((len = _io_mfs_dir_read(dir_ptr, session_ptr->DATA_BUFFER_PTR, session_ptr->DATA_BUFFER_SIZE))>0)  {
      send(data_sock, session_ptr->DATA_BUFFER_PTR, len, 0);
   } 
         
   _io_mfs_dir_close(dir_ptr);      
 
   shutdown(data_sock, FTPDCFG_DATA_SHUTDOWN_OPTION );
   session_ptr->PASV_MODE = FALSE;
   session_ptr->PASV_SOCK = RTCS_SOCKET_ERROR;
   FTPd_send_msg(session_ptr, ftpmsg_tx_complete);
   
   return FTPd_OK;
} /* Endbody */


#endif

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_noop
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_noop(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{
   FTPd_send_msg(session_ptr, ftpmsg_ok);
   return FTPd_OK;
}



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_opts
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_opts(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{
   FTPd_send_msg(session_ptr, ftpmsg_bad_option);
   return FTPd_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_pass
* Returned Value   :  int_32 error code
* Comments  :  .
*
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_pass(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */

#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE == FTPD_NEED_PASSWORD)  {
      if (strcmp(arg_ptr, session_ptr->PASSWORD) == 0)  {
         session_ptr->LOGIN_STATE = FTPD_LOGGED_IN;
         session_ptr->LOGIN_ATTEMPTS = 0;
      } else  {
         session_ptr->LOGIN_STATE = FTPD_LOGGED_OUT;
         session_ptr->LOGIN_ATTEMPTS++;
         if (session_ptr->LOGIN_ATTEMPTS >= FTPD_MAX_LOGIN_ATTEMPTS)  {
            session_ptr->CONNECTED = FALSE;   
            FTPd_send_msg(session_ptr, ftpmsg_bye); 
            return FTPd_ERROR;  
         }
      }
   }
   
   if (session_ptr->LOGIN_STATE == FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_logged);   
   } else  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);   
   }
#else
   FTPd_send_msg(session_ptr, ftpmsg_logged);   
#endif
   return FTPd_OK;
}   

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_pasv
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_pasv(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   session_ptr->SERVER_PASV_SOCKADDR.sin_family      = AF_INET;
   session_ptr->SERVER_PASV_SOCKADDR.sin_addr.s_addr =  session_ptr->LOCAL_ADDR;
   session_ptr->SERVER_PASV_SOCKADDR.sin_port = FTPd_pasv_port++;
   if (FTPd_pasv_port == FTPD_PASV_PORT_END)  {
      FTPd_pasv_port = FTPD_PASV_PORT_START;   
   }
   
   sprintf(session_ptr->DATA_BUFFER_PTR, ftpmsg_pasv_mode,
      ((session_ptr->SERVER_PASV_SOCKADDR.sin_addr.s_addr >> 24) & 0xff),
      ((session_ptr->SERVER_PASV_SOCKADDR.sin_addr.s_addr >> 16) & 0xff),
      ((session_ptr->SERVER_PASV_SOCKADDR.sin_addr.s_addr >> 8) & 0xff),
      (session_ptr->SERVER_PASV_SOCKADDR.sin_addr.s_addr & 0xff),
      ((session_ptr->SERVER_PASV_SOCKADDR.sin_port >> 8) & 0xff),
      (session_ptr->SERVER_PASV_SOCKADDR.sin_port & 0xff));

   FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);
       
   if (FTPd_open_passive_data_connection(session_ptr) != RTCS_SOCKET_ERROR) {
      session_ptr->PASV_MODE = TRUE;
   } else  {
      FTPd_send_msg(session_ptr, ftpmsg_no_datacon);
   }
   
   return FTPd_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_port
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_port(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
/* Begin CR 2302 */
   uint_32     i,n;
   uint_16     p;
/* End CR 2302 */
   char_ptr    arg;


#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   n = 0;
   arg = arg_ptr;
   for ( i=0; i<4; i++ ) {
      n = _io_atoi(arg) + (n << 8);
      if ( (arg = strpbrk(arg, ",")) == NULL ) {
         FTPd_send_msg(session_ptr,  ftpmsg_badport );
         return FTPd_ERROR;
      } /* Endif */
      arg++;
   } /* Endfor */
   p = (uint_16) _io_atoi(arg);
   if ( (arg = strpbrk(arg, ",")) == NULL ) {
      FTPd_send_msg(session_ptr, ftpmsg_badport );
      return FTPd_ERROR;
   } /* Endif */
   arg++;
   p = (uint_16) _io_atoi(arg) + (p << 8);
   
   session_ptr->USER_DATA_SOCKADDR.sin_family = AF_INET;
   session_ptr->USER_DATA_SOCKADDR.sin_addr.s_addr = n;
   session_ptr->USER_DATA_SOCKADDR.sin_port = p;
   FTPd_send_msg(session_ptr, ftpmsg_portok );
   
   return FTPd_OK;
} /* Endbody */


#if FTPDCFG_USES_MFS

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_pwd
* Returned Value   :  int_32 error code
* Comments  :  .
*
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_pwd(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   }
   
   sprintf(session_ptr->DATA_BUFFER_PTR, "257 \"%s\" is the current directory\n", session_ptr->CURRENT_FTP_DIR);
   FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);
   return FTPd_OK;
}
#endif

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_quit
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_quit(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   session_ptr->LOGIN_STATE = FTPD_LOGGED_OUT;
   session_ptr->PASSWORD[0] = <PASSWORD>';
#endif
   FTPd_send_msg(session_ptr, ftpmsg_goodbye);
   session_ptr->CONNECTED = FALSE;
   return FTPd_OK;
}


#if FTPDCFG_USES_MFS

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_retr
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_retr(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   MQX_FILE_PTR      fd;
   uint_32           data_sock;
   uint_32           start_time, end_time, bytes_moved;
   int_32            count,error;
   char_ptr          ptr, abs_path = NULL;


#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   FTPd_convert_percents(arg_ptr);
   ptr = FTPd_strip_path_delimiters(arg_ptr);

   if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      return FTPd_ERROR;
   }
   error = _io_rel2abs(abs_path,
                      session_ptr->CURRENT_FS_DIR,
                      ptr,
                      min(PATHNAME_SIZE, FTPD_PATHLEN),
                      session_ptr->CURRENT_FS_NAME);       
   if(error)
   {
      FTPd_send_msg(session_ptr, ftpmsg_no_file);
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   }

   fd = fopen(abs_path, "r");
   if (fd == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_file);
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   }
   

   FTPd_send_msg(session_ptr, ftpmsg_opening_datacon);
   if (session_ptr->PASV_MODE)  {
      data_sock = session_ptr->PASV_SOCK;
   } else  {
      data_sock = FTPd_open_active_data_connection(session_ptr);
      #if 0
         sprintf(session_ptr->DATA_BUFFER_PTR, ftpmsg_sending,
                 (FTPd_user_data_port.sin_addr.s_addr >> 24) & 0xFF,
                 (FTPd_user_data_port.sin_addr.s_addr >> 16) & 0xFF,
                 (FTPd_user_data_port.sin_addr.s_addr >>  8) & 0xFF,
                  FTPd_user_data_port.sin_addr.s_addr        & 0xFF,
                   FTPd_user_data_port.sin_port);
         FTPd_send_msg(session_ptr,  session_ptr->DATA_BUFFER_PTR );
      #endif
   }
   if (data_sock == RTCS_SOCKET_ERROR)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_datacon);
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   } 

   bytes_moved = 0;
   start_time = RTCS_time_get();
   do  {
      count = read(fd, session_ptr->DATA_BUFFER_PTR, session_ptr->DATA_BUFFER_SIZE);
      if (count > 0)  {
         count = send(data_sock, session_ptr->DATA_BUFFER_PTR, count, 0);
      }
      bytes_moved += count;
   } while (count > 0);
   
   end_time = RTCS_time_get();

   shutdown(data_sock, FTPDCFG_DATA_SHUTDOWN_OPTION);

   sprintf(session_ptr->DATA_BUFFER_PTR, ftpmsg_txok, bytes_moved,
      RTCS_timer_get_interval(start_time, end_time) / 1000,
      RTCS_timer_get_interval(start_time, end_time) % 1000);
   FTPd_send_msg(session_ptr,  session_ptr->DATA_BUFFER_PTR );

   fclose(fd);
   MFS_free_path(abs_path);
   return FTPd_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_rmdir
* Returned Value   :  int_32 error code
* Comments  :  mount a filesystem on a device.
*
* Usage:  rmdir <directory>
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_rmdir(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   int_32      error;
   char_ptr    ptr,abs_path = NULL;
   
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   FTPd_convert_percents(arg_ptr);
   ptr = FTPd_strip_path_delimiters(arg_ptr);

   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   } 

   if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      return FTPd_ERROR;
   }

   error = _io_rel2abs(abs_path,
                      session_ptr->CURRENT_FS_DIR,
                      ptr,
                      min(PATHNAME_SIZE, FTPD_PATHLEN),
                      session_ptr->CURRENT_FS_NAME);       
   // change mfs internal current dir
   ioctl(session_ptr->CURRENT_FS, IO_IOCTL_CHANGE_CURRENT_DIR, session_ptr->CURRENT_FS_DIR);
   
   if(!error)
   {
      error = ioctl(session_ptr->CURRENT_FS, IO_IOCTL_REMOVE_SUBDIR, (pointer) abs_path);
   }

   if(error)  {
      FTPd_send_msg(session_ptr, ftpmsg_rmdir_error );
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   } 
   
   sprintf(session_ptr->DATA_BUFFER_PTR, "257 \"%s\" directory removed.\r\n",arg_ptr);
   FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);

   MFS_free_path(abs_path);
   return FTPd_OK;
}

#if FTPDCFG_ENABLE_RENAME

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_rnfr
* Returned Value   :  int_32 error code
* Comments  :  specify rename from file.
*
* Usage:  rnfr <file>
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_rnfr(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   int_32      error;
   char_ptr    ptr;
   MFS_FILE_ATTR_PARAM  param;
   uchar attr;


   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   }
    
   if (session_ptr->RENAME_FROM) {
      MFS_free_path(session_ptr->RENAME_FROM);
      session_ptr->RENAME_FROM=NULL;
   }
   
   
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   
   FTPd_convert_percents(arg_ptr);
   ptr = FTPd_strip_path_delimiters(arg_ptr);


   if (MFS_alloc_path(&session_ptr->RENAME_FROM) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      return FTPd_ERROR;
   }

   error = _io_rel2abs(session_ptr->RENAME_FROM,
                     session_ptr->CURRENT_FS_DIR,
                     ptr,
                     min(PATHNAME_SIZE, FTPD_PATHLEN),
                     session_ptr->CURRENT_FS_NAME); 
   param.PATHNAME = session_ptr->RENAME_FROM;
   param.ATTRIBUTE_PTR = &attr;
   error = ioctl(session_ptr->CURRENT_FS, IO_IOCTL_GET_FILE_ATTR, (pointer) &param);
   if(error)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_file );
      return FTPd_ERROR;
   } 



   sprintf(session_ptr->DATA_BUFFER_PTR, "350 File exists, ready for destination name.\r\n");
   FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);
   return FTPd_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_rnto
* Returned Value   :  int_32 error code
* Comments  :  specify rename to file.
*
* Usage:  rnto <file>
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_rnto(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   int_32            error;
   char_ptr          ptr, abs_path ;
   MFS_RENAME_PARAM  param;

   
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   

   if (session_ptr->RENAME_FROM==NULL) {
      FTPd_send_msg(session_ptr, "550 Rename from file not specified.\r\n");
      return FTPd_ERROR;
   }
   
   
   FTPd_convert_percents(arg_ptr);
   ptr = FTPd_strip_path_delimiters(arg_ptr);

  if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      MFS_free_path(session_ptr->RENAME_FROM);
      session_ptr->RENAME_FROM = NULL;      
      return FTPd_ERROR;
   }

   error = _io_rel2abs(abs_path,
                     session_ptr->CURRENT_FS_DIR,
                     ptr,
                     min(PATHNAME_SIZE, FTPD_PATHLEN),
                     session_ptr->CURRENT_FS_NAME); 

   param.OLD_PATHNAME = session_ptr->RENAME_FROM;
   param.NEW_PATHNAME = abs_path;
   error = ioctl(session_ptr->CURRENT_FS, IO_IOCTL_RENAME_FILE, (pointer) &param);
   
   if(error)  {
      sprintf(session_ptr->DATA_BUFFER_PTR, "550 unable to rename \"%s\" to %s.\r\n",session_ptr->RENAME_FROM,arg_ptr);
      error = FTPd_ERROR;
   } else {
      sprintf(session_ptr->DATA_BUFFER_PTR, "250 \"%s\" renamed to \"%s\".\r\n",session_ptr->RENAME_FROM,arg_ptr);
      error = FTPd_OK;
   } 

   MFS_free_path(session_ptr->RENAME_FROM);
   session_ptr->RENAME_FROM = NULL;
   MFS_free_path(abs_path);   

   FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);
   return error;
}

#endif
#endif

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_site
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_site(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{

   FTPd_send_msg(session_ptr, ftpmsg_site_info);
   return FTPd_OK;
}


#if FTPDCFG_USES_MFS

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_size
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_size(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   MQX_FILE_PTR         fp;
   char_ptr             ptr,abs_path;
   int_32               size=0,error;
   
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   FTPd_convert_percents(arg_ptr);
   ptr = FTPd_strip_path_delimiters(arg_ptr);
   
   if (session_ptr->CURRENT_FS == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_fs );
      return FTPd_ERROR;
   } 


   if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      return FTPd_ERROR;
   }

   error = _io_rel2abs(abs_path,
                      session_ptr->CURRENT_FS_DIR,
                      ptr,
                      min(PATHNAME_SIZE, FTPD_PATHLEN),
                      session_ptr->CURRENT_FS_NAME);       
   if(error)
   {
      FTPd_send_msg(session_ptr, ftpmsg_no_file );
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   } 

   fp = fopen(abs_path,"r");
   if (fp==NULL) {
      FTPd_send_msg(session_ptr, ftpmsg_no_file );
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   } 

   fseek(fp,0,IO_SEEK_END);
   size = ftell(fp);
   fclose(fp);

   if (size == IO_ERROR)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_file);
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   } 
   
   sprintf (session_ptr->DATA_BUFFER_PTR, ftpmsg_size,  size );
   FTPd_send_msg(session_ptr, session_ptr->DATA_BUFFER_PTR);
   
   MFS_free_path(abs_path);
   return FTPd_OK;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_retr
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_stor(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{ /* Body */
   MQX_FILE_PTR fd;
   uint_32     data_sock,error;
   uint_32     start_time, end_time, bytes_moved;
   int_32      rx_count, write_count=0;
   char_ptr    ptr,abs_path;

#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   FTPd_convert_percents(arg_ptr);
   ptr = FTPd_strip_path_delimiters(arg_ptr);

   if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
      FTPd_send_msg(session_ptr, ftpmsg_no_memory );
      return FTPd_ERROR;
   }
   error = _io_rel2abs(abs_path,
                      session_ptr->CURRENT_FS_DIR,
                      ptr,
                      min(PATHNAME_SIZE, FTPD_PATHLEN),
                      session_ptr->CURRENT_FS_NAME);       
   if(error)
   {
      FTPd_send_msg(session_ptr, ftpmsg_no_file);
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   }


   fd = fopen(abs_path, "w");
   if (fd == NULL)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_file);
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   }
   
   FTPd_send_msg(session_ptr, ftpmsg_opening_datacon);
   if (session_ptr->PASV_MODE)  {
      data_sock = session_ptr->PASV_SOCK;
   } else  {
      data_sock = FTPd_open_active_data_connection(session_ptr);
   }
   if (data_sock == RTCS_SOCKET_ERROR)  {
      FTPd_send_msg(session_ptr, ftpmsg_no_datacon);
      MFS_free_path(abs_path);
      return FTPd_ERROR;
   } 
   MFS_free_path(abs_path);
   
   bytes_moved = 0;
   start_time = RTCS_time_get();
   do {
         
      rx_count = recv(data_sock, session_ptr->DATA_BUFFER_PTR, session_ptr->DATA_BUFFER_SIZE, 0);
      
      if (rx_count > 0)  {
         write_count = write(fd, session_ptr->DATA_BUFFER_PTR, rx_count );
         if (write_count != rx_count)  {
            shutdown(data_sock, FLAG_ABORT_CONNECTION);
            data_sock = RTCS_SOCKET_ERROR;
            if (write_count == IO_ERROR ) {
               FTPd_send_msg(session_ptr, ftpmsg_writefail);
            } else {
               FTPd_send_msg(session_ptr, ftpmsg_writeeof);
            }
            break;
         }
         bytes_moved += write_count;
      }
   } while ((rx_count > 0) && (write_count == rx_count));
   
   if (data_sock != RTCS_SOCKET_ERROR) {
      end_time = RTCS_time_get();
      shutdown(data_sock, FLAG_CLOSE_TX);
      sprintf(session_ptr->DATA_BUFFER_PTR, ftpmsg_txok, bytes_moved, RTCS_timer_get_interval(start_time, end_time) / 1000, RTCS_timer_get_interval(start_time, end_time) % 1000);
      FTPd_send_msg(session_ptr,  session_ptr->DATA_BUFFER_PTR );
   }

   fclose(fd);

   return FTPd_OK;
} /* Endbody */

#endif

   
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_syst
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_syst(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{
   FTPd_send_msg(session_ptr, ftpmsg_syst);

   return FTPd_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_type
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_type(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{

#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   if (session_ptr->LOGIN_STATE != FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      return FTPd_ERROR;
   }
#endif   
   
   switch ( *arg_ptr ) {
      case 'a':   /* Ascii */
      case 'A':   /* Ascii */
         FTPd_send_msg(session_ptr, ftpmsg_type_ascii );
         break;
      case 'b':   /* Binary */
      case 'B':   /* Binary */
      case 'i':   /* Image */
      case 'I':   /* Image */
         FTPd_send_msg(session_ptr, ftpmsg_type_image );
         break;
      default:   /* Invalid */
         FTPd_send_msg(session_ptr, ftpmsg_type_unknown );
         return FTPd_ERROR;
   } /* End Switch */

   return FTPd_OK;
}




/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_user
* Returned Value   :  int_32 error code
* Comments  :  
*
* Usage:  
*
*END*---------------------------------------------------------------------*/
   
int_32  FTPd_user(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{

#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD && FTPDCFG_USES_MFS
/* Begin CR 2296 */
   uint_32      i=0,j,error;
/* End CR 2296 */
   boolean      found = FALSE;
   MQX_FILE_PTR fd;
   char_ptr     ptr;
   char_ptr     abs_path = NULL;
   
   ptr = session_ptr->DATA_BUFFER_PTR;

   // Any attempt to log in logs previous user out.
   session_ptr->LOGIN_STATE = FTPD_LOGGED_OUT;
   session_ptr->PASSWORD[0] = <PASSWORD>';

   if (FTPd_userfile != NULL)  {
  
      if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) {
         FTPd_send_msg(session_ptr, ftpmsg_no_memory );
         FTPd_send_msg(session_ptr, ftpmsg_bye); 
         return FTPd_ERROR;
      }
      error = _io_rel2abs(abs_path,
                         session_ptr->CURRENT_FS_DIR,
                         FTPd_userfile,
                         min(PATHNAME_SIZE, FTPD_PATHLEN),
                         session_ptr->CURRENT_FS_NAME);       
      if(error)
      {
         FTPd_send_msg(session_ptr, ftpmsg_bye);
         MFS_free_path(abs_path);
         return FTPd_ERROR;  
      }
      
      fd=fopen(abs_path, "r");
      if (fd)  {
         while (fgets(ptr, FTPD_LINELEN, fd))  {
         
            if (*ptr == '\0') continue;
            for (i=0;(i<FTPD_LINELEN) && (ptr[i] != ':') && (ptr[i] != '\0'); i++)  {
            }
            if ((arg_ptr[i]=='\0') && (strncmp(ptr, arg_ptr, i)==0))  {
               found = TRUE;
               break;
            }
         }
         if (found)  {
            strncpy(session_ptr->USERNAME,&ptr[0], i); 
            session_ptr->USERNAME[i]='\0';
            //check if there is only username or also password (:)
            if (session_ptr->DATA_BUFFER_PTR[i] == '\0')  {
               session_ptr->LOGIN_STATE = FTPD_LOGGED_IN;
            } else  {
               //there is : delimiter - check if there is valid password
               for (j=i+1;(j<FTPD_LINELEN) && (ptr[j] != ':') && (ptr[j] != '\0'); j++)  {
               }
               if (j==(i+1))  {
                  session_ptr->LOGIN_STATE = FTPD_LOGGED_IN;
               } else  {
                  session_ptr->LOGIN_STATE = FTPD_NEED_PASSWORD;
                  strncpy(session_ptr->PASSWORD,&ptr[i+1], j-i-1); 
                  session_ptr->PASSWORD[j-i-1]='\0';
               }
               // todo - here add code for FTP ROOTDIR
            }
         } else  {
            session_ptr->LOGIN_ATTEMPTS++;
            if (session_ptr->LOGIN_ATTEMPTS >= FTPD_MAX_LOGIN_ATTEMPTS)  {
               session_ptr->CONNECTED = FALSE;   
               FTPd_send_msg(session_ptr, ftpmsg_bye);
               MFS_free_path(abs_path);
               return FTPd_ERROR;  
            }
         } 
         fclose(fd);     
      }
   } else  {
      session_ptr->LOGIN_STATE = FTPD_LOGGED_IN;
   }
   
   if (session_ptr->LOGIN_STATE == FTPD_LOGGED_IN)  {
      FTPd_send_msg(session_ptr, ftpmsg_logged);
   } else  {
      if (session_ptr->LOGIN_STATE == FTPD_NEED_PASSWORD)  {
         FTPd_send_msg(session_ptr, ftpmsg_need_password);
      } else  {
         FTPd_send_msg(session_ptr, ftpmsg_not_logged);
      }
   }
   if (abs_path != NULL)
   {
      MFS_free_path(abs_path);
   }  
#else
   FTPd_send_msg(session_ptr, ftpmsg_logged);
#endif // FTPDCFG_ENABLE_USERNAME_AND_PASSWORD || FTPDCFG_USES_MFS

      return FTPd_OK;
}



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPd_unimplemented
* Returned Value   :  int_32 error code
* Comments  :  .
*
*
*END*---------------------------------------------------------------------*/

int_32  FTPd_unimplemented(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr )
{
   FTPd_send_msg(session_ptr, ftpmsg_unimp);
   return FTPd_ERROR;
}

/*FUNCTION*--------------------------------------------------------------
*
*Function Name  :FTPd_open_active_data_connection
*Returned Value :Boolean Operation Successful or not
*Comments       :
*   This function opens the DataConnection to send the list Information
*
*END*---------------------------------------------------------------------*/

uint_32 FTPd_open_active_data_connection(FTPd_SESSION_PTR session_ptr)
{
   uint_32      data_connection;
   uint_32      error_code; 
   uint_32      option;
  
   data_connection = socket(PF_INET, SOCK_STREAM, 0);

   if (data_connection != RTCS_SOCKET_ERROR) {

      option = FTPd_window_size;   
      error_code = setsockopt(data_connection, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));
 
      option = FTPd_window_size;   
      error_code = setsockopt(data_connection, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));

      option = FTPDCFG_SEND_TIMEOUT;   
      error_code = setsockopt(data_connection, SOL_TCP, OPT_SEND_TIMEOUT, &option, sizeof(option));

      option = FTPDCFG_CONNECT_TIMEOUT;   
      error_code = setsockopt(data_connection, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));

      option = FTPDCFG_TIMEWAIT_TIMEOUT;   
      error_code = setsockopt(data_connection, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));

      option = TRUE;   
      error_code = setsockopt(data_connection, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &option, sizeof(option));


      error_code = bind(data_connection, (const sockaddr *)(&session_ptr->SERVER_DATA_SOCKADDR), sizeof(session_ptr->SERVER_DATA_SOCKADDR));
      if (error_code == RTCS_OK) {
         error_code = connect(data_connection, (const sockaddr *)(&session_ptr->USER_DATA_SOCKADDR), sizeof(session_ptr->USER_DATA_SOCKADDR));
      } 

      if (error_code != RTCS_OK) {
         shutdown(data_connection, FTPDCFG_SHUTDOWN_OPTION);
         data_connection = RTCS_SOCKET_ERROR; 
      } 
   } 
      
   return data_connection;

} /* Endbody */

/*FUNCTION*--------------------------------------------------------------
*
*Function Name  :FTPd_open_passive_data_connection
*Returned Value :Boolean Operation Successful or not
*Comments       :
*   This function opens the DataConnection to send the list Information
*
*END*---------------------------------------------------------------------*/

uint_32 FTPd_open_passive_data_connection(FTPd_SESSION_PTR session_ptr)
{
   uint_32      listen_connection, result=RTCS_SOCKET_ERROR;
   uint_32      error_code;
   sockaddr_in  remote_addr;
   uint_16      remote_addr_len;
   uint_32      option;
    
   
   listen_connection = socket(PF_INET, SOCK_STREAM, 0);
   if (listen_connection != RTCS_SOCKET_ERROR) {

      option = FTPd_window_size;   
      error_code = setsockopt(listen_connection, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));

      option = FTPd_window_size;   
      error_code = setsockopt(listen_connection, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));

      option = FTPDCFG_SEND_TIMEOUT;   
      error_code = setsockopt(listen_connection, SOL_TCP, OPT_SEND_TIMEOUT, &option, sizeof(option));

      option = FTPDCFG_CONNECT_TIMEOUT;   
      error_code = setsockopt(listen_connection, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));

      option = FTPDCFG_TIMEWAIT_TIMEOUT;   
      error_code = setsockopt(listen_connection, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));

      option = TRUE;   
      error_code = setsockopt(listen_connection, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &option, sizeof(option));      

      error_code = bind(listen_connection,(const sockaddr *)(&session_ptr->SERVER_PASV_SOCKADDR), sizeof(session_ptr->SERVER_PASV_SOCKADDR));
      if (error_code == RTCS_OK) {
         error_code = listen(listen_connection, 0);
         if (error_code == RTCS_OK) {
            remote_addr_len = sizeof(remote_addr);
            session_ptr->PASV_SOCK = accept(listen_connection,(sockaddr *) &remote_addr, &remote_addr_len);
            if (session_ptr->PASV_SOCK)  {
               result = session_ptr->PASV_SOCK;
            }  
         }  
      }  
      shutdown(listen_connection, FTPDCFG_SHUTDOWN_OPTION);
   }  
      
   return result;
}  

/*
void FTPd_send_msg(FTPd_SESSION_PTR p,char* m)  
{
    send(p->CONTROL_SOCK, m, strlen(m), 0); 
}*/

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mpxs30.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mpxs30.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the default initialization record for the
*   flash device.
*
*END************************************************************************/
#ifndef __flash_mpxs30_h__
#define __flash_mpxs30_h__


#include "flashx.h"

#define MPXS30_CFLASH_LAS_SIZE      (256*1024)
#define MPXS30_CFLASH_MAS_SIZE      (256*1024)
#define MPXS30_CFLASH_HAS_SIZE      (512*1024)
#define MPXS30_CFLASH_SHADOW_SIZE   (16*1024)
#define MPXS30_DFLASH_LAS_SIZE      (64*1024)

#define MPXS30_CFLASH0_LAS_ADDR     (0x000000)
#define MPXS30_CFLASH1_LAS_ADDR     (0x040000)
#define MPXS30_CFLASH_MAS_ADDR      (0x080000)
#define MPXS30_CFLASH_HAS_ADDR      (0x100000)
#define MPXS30_CFLASH0_SHADOW_ADDR  (0x200000)
#define MPXS30_CFLASH1_SHADOW_ADDR  (0x280000)

/*----------------------------------------------------------------------*/
/*
**              DEFINED VARIABLES
*/

extern const FLASHX_BLOCK_INFO_STRUCT _mpxs30_data_flash_block_map[];
extern const FLASHX_BLOCK_INFO_STRUCT _mpxs30_code_flash_block_map[];

extern const FLASHX_DEVICE_IF_STRUCT _flashx_c90i_code_if;

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio_kgpio.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio_kgpio.c$
* $Version : 3.8.6.0$
* $Date    : Sep-22-2011$
*
* Comments:
*
*   This file contains the GPIO standard functions used on boards
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "lwgpio.h"

const volatile uint32_t *pcr_reg_arr[] = { 
    &PORT_PCR_REG(PORTA_BASE_PTR, 0),
    &PORT_PCR_REG(PORTB_BASE_PTR, 0),
    &PORT_PCR_REG(PORTC_BASE_PTR, 0),
    &PORT_PCR_REG(PORTD_BASE_PTR, 0),
    &PORT_PCR_REG(PORTE_BASE_PTR, 0)
#ifdef PORTF_BASE_PTR 
    ,&PORT_PCR_REG(PORTF_BASE_PTR, 0)
#endif
};

const static GPIO_MemMapPtr gpio_ptr_arr[] = {
    PTA_BASE_PTR,
    PTB_BASE_PTR,
    PTC_BASE_PTR,
    PTD_BASE_PTR,
    PTE_BASE_PTR
#ifdef PTF_BASE_PTR 
    ,PTF_BASE_PTR
#endif
};

#define LWGPIO_PIN_FROM_ID(id) (((id) & LWGPIO_PIN_MASK) >> LWGPIO_PIN_SHIFT)

#define LWGPIO_PORT_FROM_ID(id) (((id) & LWGPIO_PORT_MASK) >> LWGPIO_PORT_SHIFT)

/* Interrupt mode definitions */
#define LWGPIO_INT_MODE_SHIFT (16) /* place it here to have on the same place as PCR_IRQC */
#define LWGPIO_INT_MODE_MASK (0x0F << LWGPIO_INT_MODE_SHIFT)
#define LWGPIO_INT_MODE(x) (((x) << LWGPIO_INT_MODE_SHIFT) & LWGPIO_INT_MODE_MASK)
#define LWGPIO_INT_MODE_FROM_ID(id) (((id) & LWGPIO_INT_MODE_MASK) >> LWGPIO_INT_MODE_SHIFT)

/* Direction field definitions */
#define LWGPIO_DIR_SHIFT (20)
#define LWGPIO_DIR_MASK (0x01 << LWGPIO_DIR_SHIFT)

#define MUX_GPIO 0x01 /* GPIO is in Alternative 1 peripheral mode */

/* Flags for Pull-up/down */
#define LWGPIO_PULL_UP_SHIFT    (21)
#define LWGPIO_PULL_DOWN_SHIFT  (22)
#define LWGPIO_PULL_UP_MASK     (0x01 << LWGPIO_PULL_UP_SHIFT)
#define LWGPIO_PULL_DOWN_MASK   (0x01 << LWGPIO_PULL_DOWN_SHIFT)

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_init
* Returned Value   : TRUE if succesfull, FALSE otherwise
* Comments         :
*    Decodes ID to HW specific struct and then performs pin initialization
*
*END*********************************************************************/
boolean lwgpio_init
(
    /* Pointer to LWGPIO internal structure to be filled in */
    LWGPIO_STRUCT_PTR handle,
    /* Pin ID, bitmask integer value */
    LWGPIO_PIN_ID     id,
    /* Direction to be set within initialization */
    LWGPIO_DIR        dir,
    /* Value to be set within initialization */
    LWGPIO_VALUE      value
)
{ /* Body */
    uint_32 port_idx, pin_idx;
    PORT_MemMapPtr port_ptr;

    port_idx = LWGPIO_PORT_FROM_ID(id);
    pin_idx = LWGPIO_PIN_FROM_ID(id);

    handle->flags = id;
    handle->pcr_reg = (uint_32 *) pcr_reg_arr[port_idx] + pin_idx;
    handle->gpio_ptr = gpio_ptr_arr[port_idx];
    handle->pinmask = 1 << pin_idx;

    /* Set value prior to set to output */
    if (value != LWGPIO_VALUE_NOCHANGE) {
        /* Note: there is no check for values not defined as LWGPIO_VALUE enum */
        lwgpio_set_value(handle, value);
    }

    if (dir != LWGPIO_DIR_NOCHANGE) {
        /* Note: there is no check for values not defined as LWGPIO_DIR enum */
        lwgpio_set_direction(handle, dir);
    }

    return TRUE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_attribute
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    Sets attributes
*
*END*********************************************************************/
boolean lwgpio_set_attribute
(
    /* Pin handle to get function from */
    LWGPIO_STRUCT_PTR  handle,
    /* PORT attribute */
    uint_32 attribute_id,
    /* Attribute value */
    uint_32 value
)
{
    switch (attribute_id) 
    {
        case(LWGPIO_ATTR_PULL_UP):
        {
            if (value == LWGPIO_AVAL_ENABLE) 
            {
                *handle->pcr_reg |= (PORT_PCR_PS_MASK | PORT_PCR_PE_MASK);
                handle->flags |=  LWGPIO_PULL_UP_MASK;
                handle->flags &= ~LWGPIO_PULL_DOWN_MASK;
            } 
            /* disable only if pull down is not enabled */
            else  
            {
                if ((value == LWGPIO_AVAL_DISABLE) && !(handle->flags & LWGPIO_PULL_DOWN_MASK))
                {
                    *handle->pcr_reg &= ~PORT_PCR_PE_MASK;
                    handle->flags &= ~LWGPIO_PULL_UP_MASK;
                }
            }
            break;
        }
        case(LWGPIO_ATTR_PULL_DOWN):
        {
            if (value == LWGPIO_AVAL_ENABLE) 
            {
                *handle->pcr_reg &= ~(PORT_PCR_PS_MASK);
                *handle->pcr_reg |= (PORT_PCR_PE_MASK);
                handle->flags &= ~LWGPIO_PULL_UP_MASK;
                handle->flags |=  LWGPIO_PULL_DOWN_MASK;
            } 
            /* disable only if pull up is not enabled */
            else 
            {
                if ((value == LWGPIO_AVAL_DISABLE) && !(handle->flags & LWGPIO_PULL_UP_MASK))
                {
                    *handle->pcr_reg &= ~PORT_PCR_PE_MASK;
                    handle->flags &= ~LWGPIO_PULL_DOWN_MASK;
                }
            }
            break;
        }
        case(LWGPIO_ATTR_SLEW_RATE):
        {
            if (value == LWGPIO_AVAL_SLEW_RATE_SLOW)
            {
                *handle->pcr_reg |= PORT_PCR_SRE_MASK;
            }
            else
            {
                *handle->pcr_reg &= ~(PORT_PCR_SRE_MASK);
            }
            break;
        }
        case(LWGPIO_ATTR_FILTER):
        {
            if (value == LWGPIO_AVAL_ENABLE)
            {
                *handle->pcr_reg |= PORT_PCR_PFE_MASK;
            }
            else
            {
                *handle->pcr_reg &= ~(PORT_PCR_PFE_MASK);
            }
            break;
        }
        case(LWGPIO_ATTR_OPEN_DRAIN):
        {
            if (value == LWGPIO_AVAL_ENABLE)
            {
                *handle->pcr_reg |= PORT_PCR_ODE_MASK;
            }
            else
            {
                *handle->pcr_reg &= ~(PORT_PCR_ODE_MASK);
            }
            break;
        }
        case(LWGPIO_ATTR_DRIVE_STRENGTH):
        {
            if (value == LWGPIO_AVAL_DRIVE_STRENGTH_HIGH)
            {
                *handle->pcr_reg |= PORT_PCR_DSE_MASK;
            }
            else
            {
                *handle->pcr_reg &= ~(PORT_PCR_DSE_MASK);
            }
            break;
        }
        default:
            return FALSE;
    }
    return TRUE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_functionality
* Returned Value   : void
* Comments         :
*    Sets functionality (peripheral mode) of the pin
*
*END*********************************************************************/
void lwgpio_set_functionality
(
    /* Pin handle to set function on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Function to be set (integer value) */
    uint_32            function
)
{
    *handle->pcr_reg &= ~PORT_PCR_MUX_MASK;
    *handle->pcr_reg |= PORT_PCR_MUX(function);
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_functionality
* Returned Value   : void
* Comments         :
*    Gets functionality (peripheral mode) of the pin
*
*END*********************************************************************/
uint_32 lwgpio_get_functionality
(
    /* Pin handle to get function from */
    LWGPIO_STRUCT_PTR  handle
)
{
    return (*handle->pcr_reg & PORT_PCR_MUX_MASK) >> PORT_PCR_MUX_SHIFT;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_direction
* Returned Value   : void
* Comments         :
*    Sets direction of the pin
*
*END*********************************************************************/
void lwgpio_set_direction
(
    /* Pin handle to set direction on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Direction to be set */
    LWGPIO_DIR         dir
)
{
    if (dir == LWGPIO_DIR_INPUT) {
        handle->gpio_ptr->PDDR &= ~handle->pinmask;
        handle->flags |= LWGPIO_DIR_MASK; /* mark the pin is input */
    }
    else if (dir == LWGPIO_DIR_OUTPUT) {
        handle->gpio_ptr->PDDR |= handle->pinmask;
        handle->flags &= ~LWGPIO_DIR_MASK; /* mark the pin is output */
    }
    else { /* LWGPIO_DIR_NOCHANGE or other value */
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_value
* Returned Value   : void
* Comments         :
*    Sets value (output latch) of the pin
*
*END*********************************************************************/
void lwgpio_set_value
(
    /* Pin handle to set value on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Direction to be set */
    LWGPIO_VALUE       out_value
)
{
    if (out_value == LWGPIO_VALUE_LOW) {
        handle->gpio_ptr->PDOR &= ~handle->pinmask;
    }
    else if (out_value == LWGPIO_VALUE_HIGH) {
        handle->gpio_ptr->PDOR |= handle->pinmask;
    }
    else { /* LWGPIO_VALUE_NOCHANGE or other value */
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_toggle_value
* Returned Value   : void
* Comments         :
*    Toggles value of output latch of the pin
*
*END*********************************************************************/
void lwgpio_toggle_value
(
    /* Pin handle to toggle value on */
    LWGPIO_STRUCT_PTR  handle
)
{
    handle->gpio_ptr->PTOR = handle->pinmask;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_value
* Returned Value   : LWGPIO_VALUE of pin status
* Comments         :
*    Returns value (output latch or read data) of the pin
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_value
(
    /* Pin handle to get value from */
    LWGPIO_STRUCT_PTR  handle
)
{
    /* if the pin is set to output */
    if (handle->gpio_ptr->PDDR & handle->pinmask) /* alternative: (handle->flags & LWGPIO_DIR_MASK == 0) */
        return (handle->gpio_ptr->PDOR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
    else
        return (handle->gpio_ptr->PDIR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_raw
* Returned Value   : LWGPIO_VALUE of pin status
* Comments         :
*    Returns read level of the pin
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_raw
(
    /* Pin handle to get value from */
    LWGPIO_STRUCT_PTR  handle
)
{
    return (handle->gpio_ptr->PDIR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_init
* Returned Value   : TRUE if succesfull, FALSE otherwise
* Comments         :
*    Initializes pin to generate interrupt
*
*END*********************************************************************/
boolean lwgpio_int_init
(
    /* Pin handle to initialize interrupt on */
    LWGPIO_STRUCT_PTR handle,
    /* Interrupt mode */
    LWGPIO_INT_MODE   mode
)
{ /* Body */
    /*
    Settings of PORT_PCR_IRQC according mode:
    PORT_PCR_IRQC | LOW | HIGH | FALLING | RISING | mode
    ----------------------------------------------------
               0  |   0 |    0 |       0 |      0 |    0
     0x08 + 0x01  |   0 |    0 |       0 |      1 |    1
     0x08 + 0x02  |   0 |    0 |       1 |      0 |    2
     0x08 + 0x03  |   0 |    0 |       1 |      1 |    3
     0x08 + 0x04  |   0 |    1 |       0 |      0 |    4
     unsupported  |   0 |    1 |       0 |      1 |    5
     unsupported  |   0 |    1 |       1 |      0 |    6
     unsupported  |   0 |    1 |       1 |      1 |    7
     0x08 + 0x00  |   1 |    0 |       0 |      0 |    8
     unsupported  |   1 |    0 |       0 |      1 |    9
     unsupported  |   1 |    0 |       1 |      0 |   10
     unsupported  |   1 |    0 |       1 |      1 |   11
     unsupported  |   1 |    1 |       0 |      0 |   12
     unsupported  |   1 |    1 |       0 |      1 |   13
     unsupported  |   1 |    1 |       1 |      0 |   14
     unsupported  |   1 |    1 |       1 |      1 |   15
    */

    if (mode > 4 && mode != LWGPIO_INT_MODE_LOW)
        return FALSE;

    if (mode) {
        /* Store mode value and use it when enabling interrupt */
        handle->flags &= ~LWGPIO_INT_MODE_MASK;
        handle->flags |= LWGPIO_INT_MODE(0x08 | mode & 0x07); /* see PCR_IRQC register field definition */
    }

    return TRUE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_enable
* Returned Value   : void
* Comments         :
*    Enables / disables interrupts for specified pin
*
*END*********************************************************************/
void lwgpio_int_enable
(
    /* Pin handle to enable interrupt on */
    LWGPIO_STRUCT_PTR handle,
    /* Enable or disable interrupt? TRUE = enable */
    boolean           ena
)
{ /* Body */
    if (ena) {
        /* enable pin interrupts */
        *handle->pcr_reg &= ~PORT_PCR_IRQC_MASK;
        *handle->pcr_reg |= handle->flags & PORT_PCR_IRQC_MASK; /* the IRQ mode flags are on the same place as PCR_IRQC */
    }
    else {
        /* disable pin interrupts */
        *handle->pcr_reg &= ~PORT_PCR_IRQC_MASK;
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_get_flag
* Returned Value   : TRUE if interrupt flag is set
* Comments         :
*    Checks if there is pending interrupt flag for specified pin
*
*END*********************************************************************/
boolean lwgpio_int_get_flag
(
    /* Pin handle to get interrupt flag on */
    LWGPIO_STRUCT_PTR handle
)
{ /* Body */
    return (*handle->pcr_reg & PORT_PCR_ISF_MASK) ? TRUE : FALSE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_clear_flag
* Returned Value   : void
* Comments         :
*    Clears pending interrupt flag on peripheral
*
*END*********************************************************************/
void lwgpio_int_clear_flag
(
    /* Pin handle to clear interrupt flag on */
    LWGPIO_STRUCT_PTR handle
)
{ /* Body */
    /* Clear interrupt flag. Note that if an interrupt was acknowledged by NVIC,
    it will generate interrupt anyway. Interrupts on NVIC are grouped for each
    port */
    *handle->pcr_reg |= PORT_PCR_ISF_MASK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_gpio_base_address
* Returned Value   : pointer to base of GPIO registers
* Comments         :
*    This function returns base address of GPIO related register space.
*
*END*********************************************************************/
uint_32 lwgpio_int_get_vector
(
    /* Pin handle to get vector of */
    LWGPIO_STRUCT_PTR  handle
)
{
    return INT_PORTA + LWGPIO_PORT_FROM_ID(handle->flags);
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/ftpd.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpd.c$
* $Version : 172.16.58.3$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains an implementation of an FTP server.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <rtcs.h>
#include <fio.h>

#include "ftpd.h"
#include "ftpd_msg.h"

#if FTPDCFG_USES_MFS
#include <mfs.h>
#endif

_rtcs_taskid FTPd_task_id = 0;
uint_32 FTPd_window_size = FTPDCFG_WINDOW_SIZE;
uint_32 FTPd_buffer_size = FTPDCFG_BUFFER_SIZE;

typedef struct ftpd_context  {
   uint_32     LISTENSOCK;
} FTPd_CONTEXT, _PTR_ FTPd_CONTEXT_PTR;


#ifdef __MQX__ 
void FTPd_Exit_handler(void);
#endif

extern void FTPd_child(pointer, pointer);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTPd_init
* Returned Value   : error code
* Comments  :  Start the FTP server.
*
*END*-----------------------------------------------------------------*/

uint_32 FTPd_init
   (
      char_ptr name,
      uint_32  priority,
      uint_32  stacksize
   )
{ /* Body */
   if (FTPd_task_id == 0)  {
      return RTCS_task_create(name, priority, stacksize, FTPd_task, NULL);
   } else  {
      return RTCSERR_SERVER_ALREADY_RUNNING;
   }
} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name    : FTPd_task
* Returned Value   : none
* Comments  :  FTP server.
*
*END*-----------------------------------------------------------------*/

void FTPd_task
   (
      pointer  init_ptr,
      pointer creator
   )
{ /* Body */
   FTPd_CONTEXT               ftpd_context =  { 0 };
   sockaddr_in                laddr;
   uint_32                    sock, listensock;
   uint_32                    error=RTCS_OK;
   uint_16                    remote_addr_len;
   sockaddr_in                remote_addr = {0};
#if FTPDCFG_ENABLE_MULTIPLE_CLIENTS   
   TASK_TEMPLATE_STRUCT_PTR   t_ptr;
#endif   
   FTPd_SESSION_PTR           session_ptr;
   uint_32                    option;
   boolean                    dev_in_path = FALSE;
   int_16                     devlen = 0, rootdirlen = 0;

   FTPd_task_id = RTCS_task_getid();
#ifdef __MQX__ 
   /* Set up exit handler and context so that we can clean up if the FTP Server is terminated */
   _task_set_environment( _task_get_id(), (pointer) &ftpd_context );
   _task_set_exit_handler( _task_get_id(), FTPd_Exit_handler );
#endif 

   laddr.sin_family      = AF_INET;
   laddr.sin_port        = IPPORT_FTP;
   laddr.sin_addr.s_addr = INADDR_ANY;

   /* Listen on TCP port */
   ftpd_context.LISTENSOCK = socket(PF_INET, SOCK_STREAM, 0);
   listensock = ftpd_context.LISTENSOCK;
   if (listensock == RTCS_SOCKET_ERROR) {
      error = RTCSERR_OUT_OF_SOCKETS;
   } 
   
   if (!error) {
      option = FTPd_window_size;   
      error = setsockopt(listensock, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));
   }
   
   if (!error) {
      option = FTPd_window_size;   
      error = setsockopt(listensock, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));
   }      

   if (!error) {
      option = FTPDCFG_SEND_TIMEOUT;   
      error = setsockopt(listensock, SOL_TCP, OPT_SEND_TIMEOUT, &option, sizeof(option));
   }   

   if (!error) {
      option = FTPDCFG_CONNECT_TIMEOUT;   
      error = setsockopt(listensock, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));
   }   

   if (!error) {
      option = FTPDCFG_TIMEWAIT_TIMEOUT;   
      error = setsockopt(listensock, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));
   }   

   if (!error) {
      error = bind(listensock, (const sockaddr *)&laddr, sizeof(laddr));
   } 

   if (!error) {
      error = listen(listensock, 0);
   } 

   if (error) {
      RTCS_task_exit(creator, error);
   } 
   RTCS_task_resume_creator(creator, RTCS_OK);

   for (;;) {

      /* Connection requested; accept it */
      remote_addr_len = sizeof(remote_addr);
      sock = accept(listensock,(sockaddr *)&remote_addr, &remote_addr_len);
      
      if ((sock != 0) && (sock!=RTCS_SOCKET_ERROR)) {
         session_ptr = (FTPd_SESSION_PTR) RTCS_mem_alloc_zero(sizeof (FTPd_SESSION_STRUCT));

         if ( session_ptr ) {
            _mem_set_type(session_ptr, MEM_TYPE_FTPd_SESSION_PTR);
 
            session_ptr->DATA_BUFFER_SIZE = FTPd_buffer_size;
            session_ptr->DATA_BUFFER_PTR = RTCS_mem_alloc_zero(session_ptr->DATA_BUFFER_SIZE);
            if (session_ptr->DATA_BUFFER_PTR == NULL) {
               _mem_free(session_ptr);
               session_ptr = NULL;
            } else {
               _mem_set_type(session_ptr->DATA_BUFFER_PTR, MEM_TYPE_FTPd_DATA_BUFFER);
            }
         }
            
            
         if (session_ptr == NULL) {
            shutdown((uint_32)sock, FTPDCFG_SHUTDOWN_OPTION);
         } else  {
      

            session_ptr->CONTROL_SOCK = (uint_32) sock;
            session_ptr->CONNECTED = TRUE;
            /* set default data ports */
            session_ptr->SERVER_DATA_SOCKADDR.sin_family      = AF_INET;
            session_ptr->SERVER_DATA_SOCKADDR.sin_port        = IPPORT_FTPDATA;
            session_ptr->SERVER_DATA_SOCKADDR.sin_addr.s_addr = INADDR_ANY;

            session_ptr->USER_DATA_SOCKADDR.sin_family      = remote_addr.sin_family;
            session_ptr->USER_DATA_SOCKADDR.sin_port        = remote_addr.sin_port;
            session_ptr->USER_DATA_SOCKADDR.sin_addr.s_addr = remote_addr.sin_addr.s_addr;

#if FTPDCFG_USES_MFS
            //initialize current directory and current filesystem
            devlen = _io_get_dev_for_path(session_ptr->CURRENT_FS_NAME,
                        &dev_in_path,
                        FTPD_DEVLEN,
                        (char *)FTPd_rootdir,
                        NULL);
                        
            session_ptr->CURRENT_FS = _io_get_fs_by_name(session_ptr->CURRENT_FS_NAME);
            
            error = ioctl(session_ptr->CURRENT_FS, IO_IOCTL_CHECK_DIR_EXIST,(pointer)FTPd_rootdir );  
            
            if (error)  {
#endif            
               session_ptr->CURRENT_FS = NULL;
               session_ptr->CURRENT_FTP_DIR = NULL;
               session_ptr->CURRENT_FS_DIR[0] = '\0';
#if FTPDCFG_USES_MFS               
            } else {
               // set current fs dir (including root dir)
               strcpy(session_ptr->CURRENT_FS_DIR,FTPd_rootdir+devlen);
               
               rootdirlen = strlen(session_ptr->CURRENT_FS_DIR);

               // set current FTP dir 
               session_ptr->CURRENT_FTP_DIR = session_ptr->CURRENT_FS_DIR + rootdirlen - 1; 
               
               //check if there is / at the end of root dir name
               if(*(session_ptr->CURRENT_FTP_DIR) != '\\' &&
                  *(session_ptr->CURRENT_FTP_DIR) != '/') 
               {
                  session_ptr->CURRENT_FTP_DIR++;
               } 
             session_ptr->CURRENT_FTP_DIR[0] = '\\';
             session_ptr->CURRENT_FTP_DIR[1] = '\0';
            } 
#endif                     
            #if FTPDCFG_ENABLE_MULTIPLE_CLIENTS
               /* Create a task to look after it */
               RTCS_detachsock(sock);
               t_ptr = _task_get_template_ptr(MQX_NULL_TASK_ID); 
               if (RTCS_task_create("FTPd_child", t_ptr->TASK_PRIORITY, t_ptr->TASK_STACKSIZE, FTPd_child, (pointer) session_ptr) != RTCS_OK ) {
                  RTCS_attachsock(sock);
                  shutdown(sock, FLAG_ABORT_CONNECTION);
                  _mem_free(session_ptr->DATA_BUFFER_PTR);
                  _mem_free(session_ptr);
               }
            #else
               FTPd_child((pointer) session_ptr,0);
            #endif

         }         
      }
   } 
} 


/*TASK*-----------------------------------------------------------------
*
* Function Name    : FTPd_child
* Returned Value   : none
* Comments  :  FTP server.
*
*END*-----------------------------------------------------------------*/

void FTPd_child
   (
      pointer  session,
      pointer  creator
   )
{ /* Body */
   FTPd_SESSION_PTR           session_ptr = (FTPd_SESSION_PTR) session;
   FTPd_COMMAND_PTR           command_ptr;
   char_ptr                   cmd_ptr, arg_ptr, ptr;
   int_32                     len;
   uint_32                    i,bi,ci,arglen;
   boolean                    got_a_line;
   uint_32                    iplen;


   #if FTPDCFG_ENABLE_MULTIPLE_CLIENTS
   _mem_transfer( session, _task_get_creator(), _task_get_id() ); 
   _mem_transfer( session_ptr->DATA_BUFFER_PTR, _task_get_creator(), _task_get_id() );
   RTCS_task_resume_creator(creator, RTCS_OK);
   #endif  
   
   iplen = sizeof(_ip_address);
   getsockopt(session_ptr->CONTROL_SOCK, SOL_IP, RTCS_SO_IP_LOCAL_ADDR, &session_ptr->LOCAL_ADDR, &iplen);
   

   FTPd_send_msg(session_ptr, ftpmsg_banner);

   bi=0;
   len=0;   
   while (session_ptr->CONNECTED) {
      got_a_line = FALSE;
      ci=0;
      while (session_ptr->CONNECTED && !got_a_line) {
         if (bi>=(uint_32)len)  {
            len = recv(session_ptr->CONTROL_SOCK, session_ptr->CMD_BUFFER, 
               sizeof(session_ptr->CMD_BUFFER), 0);    
            if (len == RTCS_ERROR) {
               session_ptr->CONNECTED = FALSE;
            } else  {
               bi=0;
            }
         } else  {
            session_ptr->CMD_LINE[ci++] = session_ptr->CMD_BUFFER[bi++];
            if (session_ptr->CMD_BUFFER[bi] == '\n')  {
               session_ptr->CMD_LINE[ci++] = 0; 
               got_a_line=TRUE;  
            }
         }
         if (ci >= FTPD_LINELEN) {
               got_a_line=TRUE;  
         }
      }
      
      if (session_ptr->CONNECTED)  {
         if (*session_ptr->CMD_LINE == '\0') continue;
   
         ptr = session_ptr->CMD_LINE;
         while (*ptr && ! isgraph(*ptr)) ptr++;
         cmd_ptr = ptr;
         while (*ptr && isgraph(*ptr)) ptr++;
         if (*ptr)  {
            *ptr++ = '\0';
         
            while (*ptr && ! isgraph(*ptr)) ptr++;
            arg_ptr = ptr;
          //  while (*ptr && isgraph(*ptr)) ptr++;
          //  *ptr++ = '\0';
         } else  {
            arg_ptr = ptr;
         }
         if (arg_ptr) {
            arglen = strlen(arg_ptr);
            while (arglen > 0) {
               if ((arg_ptr[arglen-1] == '\r') || (arg_ptr[arglen-1] == '\n')) {
                  arg_ptr[arglen-1] = 0;
                  arglen--;
               } else {
                  break;
               }
            }
         }
         
         if (*cmd_ptr != '\0') { 
      
            i=0;
            while (cmd_ptr[i])  {
               cmd_ptr[i] = (char)tolower(cmd_ptr[i]);
               i++;
            }
      
            command_ptr = (FTPd_COMMAND_PTR) FTPd_commands; 
            while (command_ptr->COMMAND != NULL)  {
               if (strcmp(cmd_ptr, command_ptr->COMMAND) == 0)  {
                  (void)(*command_ptr->FTPd_FUNC)(session_ptr, cmd_ptr, arg_ptr);
                  break;   
               }
               command_ptr++;        
            } /* Endwhile */
            if (command_ptr->COMMAND == NULL)  {
               FTPd_send_msg(session_ptr, ftpmsg_badcmd);
            } /* Endif */
         } /* Endif */
      }
   } /* Endwhile */

   shutdown(session_ptr->CONTROL_SOCK, FTPDCFG_SHUTDOWN_OPTION );
   _mem_free(session_ptr->DATA_BUFFER_PTR);
   _mem_free(session_ptr); 
} /* Endbody */


#ifdef __MQX__ 
/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTPd_stop
* Returned Value   : error code
* Comments  :  Start the FTPd task.
*
*END*-----------------------------------------------------------------*/

uint_32 FTPd_stop( void )
{ /* Body */
   if (FTPd_task_id == 0)  {
      return RTCSERR_SERVER_NOT_RUNNING;
   }
   RTCS_task_abort(FTPd_task_id);
   FTPd_task_id = 0;
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : FTPd_Exit_handler
* Returned Value   : error code
* Comments  :  Stop the FTPd task.
*
*END*-----------------------------------------------------------------*/

void FTPd_Exit_handler( void )
{ /* Body */
   FTPd_CONTEXT_PTR    ftpd_context_ptr;
   
   ftpd_context_ptr = (FTPd_CONTEXT_PTR) _task_get_environment( _task_get_id() );
   if (ftpd_context_ptr != NULL)  {
      if (ftpd_context_ptr->LISTENSOCK)  {
         shutdown(ftpd_context_ptr->LISTENSOCK, FLAG_ABORT_CONNECTION);   
         ftpd_context_ptr->LISTENSOCK = 0;   
      }   
   }
   FTPd_task_id = 0;
} /* Endbody */
#endif

void FTPd_send_msg(pointer p, const char * m)
{
   send((((FTPd_SESSION_PTR)p)->CONTROL_SOCK), (pointer)m, strlen(m), 0);
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/Tests.c<|end_filename|>
#include <mqx.h>
#include <bsp.h>
#include <fio.h>
#include "App.h"

static int test_cnt;

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
static void Test_space_vector_modulator(void)
{
  int                            i;
  int                            angle_int;
  float                          angle_flt;
  MCLIB_2_COOR_SYST_ALPHA_BETA_T tr32InVoltage;
  MCLIB_3_COOR_SYST_T            tr32PwmABC;
  UWord32                        u32SvmSector;

  printf("Space vector modulation test.\r\n");
  for (i = 0; i < 360; i++)
  {
    int rem, c;


    Led_control(LED1, 1);
    angle_int = i % 180;
    c     = i / 180;
    if ( c & 1 )
    {
      // Нечетное
      angle_int = -180 + angle_int;
    }
    angle_flt = angle_int / 180.0;

    tr32InVoltage.f32Alpha = GFLIB_Cos(FRAC32(angle_flt));
    tr32InVoltage.f32Beta  = GFLIB_Sin(FRAC32(angle_flt));
    u32SvmSector = GMCLIB_SvmStd(&tr32PwmABC, &tr32InVoltage);
    Led_control(LED1, 0);

    {
      float alpha, beta, f32A, f32B, f32C;
      alpha = tr32InVoltage.f32Alpha / (float)0x80000000;
      beta  = tr32InVoltage.f32Beta / (float)0x80000000;

      f32A  = tr32PwmABC.f32A / (float)0x80000000;
      f32B  = tr32PwmABC.f32B / (float)0x80000000;
      f32C  = tr32PwmABC.f32C / (float)0x80000000;
      printf("Angle=%03d alpha=%6.3f beta=%6.3f s=%d A=%6.3f B=%6.3f C=%6.3f\r\n", i, alpha, beta, u32SvmSector, f32A, f32B, f32C);
    }
  }
}




<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_ioctl.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_ioctl.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the function _io_ioctl.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Performs specified io_ctl command.
 * 
 * \param[in] file_ptr  The stream to perform the operation on.
 * \param[in] cmd       The ioctl command.
 * \param[in] param_ptr The ioctl parameters.
 * 
 * \return MQX_OK (Succes.)
 * \return IO_EOF
 * \return MQX error code.  
 */ 
_mqx_int _io_ioctl
   ( 
      MQX_FILE_PTR file_ptr,
      _mqx_uint   cmd,
      pointer     param_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   dev_ptr;
   _mqx_uint_ptr          tmp_ptr;
   _mqx_uint              result = MQX_OK;

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(IO_EOF);
   } /* Endif */
#endif

   tmp_ptr = (_mqx_uint_ptr)param_ptr;

   switch (cmd) {
      case IO_IOCTL_GET_FLAGS:
         *tmp_ptr = file_ptr->FLAGS;
         break;
      case IO_IOCTL_SET_FLAGS:
         file_ptr->FLAGS = *tmp_ptr;
         break;
      default:
         dev_ptr = file_ptr->DEV_PTR;
         if (dev_ptr->IO_IOCTL != NULL) {
            result = (*dev_ptr->IO_IOCTL)(file_ptr, cmd, param_ptr);
         }
         else
            result = IO_ERROR_INVALID_IOCTL_CMD;
         
         break;
   } /* Endswitch */

   return(result);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hwtimer/hwtimer_kinetis.c<|end_filename|>
/*HEADER********************************************************************
 *
 * Copyright (c) 2013 Freescale Semiconductor;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: hwtimer_kinetis.c$
 * $Version : 4.0.1$
 * $Date : Jan-18-2013$
 *
 * Comments:
 *
 *   This file contains kinetis specific functions of the hwtimer component.
 *
 *END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "hwtimer.h"

/*!
 * \cond DOXYGEN_PRIVATE
 * Macro return number of item in pit_vectors_table array
 */
#define PIT_INTERRUPT_COUNT 4

/* Array of PIT interrupt vectors*/
/*!
 * \cond DOXYGEN_PRIVATE
 * \brief Array of PIT interrupt vectors
 */
const _mqx_uint pit_vectors_table[] =
    {
        INT_PIT0,
        INT_PIT1,
        INT_PIT2,
        INT_PIT3
    };

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief This function performs BSP-specific initialization related to pit
 *
 * \param dev_num[in]   Number of PIT module.
 *
 * \return MQX_OK Success.
 *
 * \see pit_get_vectors
 * \see pit_get_hwtimers_array
 */
_mqx_int pit_io_init
(
    uint_32 dev_num
)
{
    SIM_MemMapPtr sim = SIM_BASE_PTR;

    switch (dev_num)
    {
        case 0:
            SIM_SCGC6 |= SIM_SCGC6_PIT_MASK;    /* PIT clock enablement */
            break;
        default:
            /* Do nothing if bad dev_num was selected */
            return -1;
    }

    return MQX_OK;
}

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief This function get array of vectors and count of items in this array.
 *
 * \param pit_vectors_table_ptr[out]  Used to get pit_vectors_table.
 *
 * \return PIT_INTERRUPT_COUNT Count of interrupt vectors for PIT module.
 *
 * \see pit_io_init
 * \see pit_get_hwtimers_array
 */
uint_32 pit_get_vectors
(
    uint_32 pit_number,
    const _mqx_uint **pit_vectors_table_ptr
)
{
    switch (pit_number)
    {
        case 0:
            *pit_vectors_table_ptr = pit_vectors_table;
            break;
        default:
            *pit_vectors_table_ptr = NULL;
    }

    return PIT_INTERRUPT_COUNT;
}

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief This function is useless for this platform
 *
 * \param hwtimers_array[out] Array of hwtimers. Filled by NULL for this platform
 *
 * \return 0 This platform doesnt need hwtimers_array.
 *
 * \see pit_io_init
 * \see pit_get_vectors
 */
uint_32 pit_get_hwtimers_array
(
    HWTIMER_PTR ** hwtimers_array
)
{
    *hwtimers_array = NULL;
    return 0;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/nandflash/nfc/nfc.h<|end_filename|>
#ifndef _nfc_h_
#define _nfc_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nfc.h$
* $Version : 3.8.11.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains defines and functions prototype for the  
*   NAND Flash aController (NFC) low level driver.
*
*END************************************************************************/

#include "nandflash.h"

#define MAX_WAIT_COMMAND                       0x00100000


/*----------------------------------------------------------------------*/
/*
**                     FUNCTION PROTOTYPES
*/
#ifdef __cplusplus
extern "C" {
#endif

pointer _bsp_get_nfc_address(void);

extern void    nfc_io_init(void);

extern uint_32 nfc_init( IO_NANDFLASH_STRUCT_PTR );

extern void    nfc_deinit( IO_NANDFLASH_STRUCT_PTR );

extern uint_32 nfc_erase_flash( IO_NANDFLASH_STRUCT_PTR );

extern uint_32 nfc_erase_block( IO_NANDFLASH_STRUCT_PTR, uint_32, boolean );

extern uint_32 nfc_read_page( IO_NANDFLASH_STRUCT_PTR, uchar_ptr, 
    uint_32, uint_32 );

extern uint_32 nfc_write_page( IO_NANDFLASH_STRUCT_PTR, uchar_ptr, 
    uint_32, uint_32 );
    
extern uint_32 nfc_reset( IO_NANDFLASH_STRUCT_PTR );

extern uint_32 nfc_check_block( IO_NANDFLASH_STRUCT_PTR, uint_32 );
    
extern uint_32 nfc_mark_block_as_bad( IO_NANDFLASH_STRUCT_PTR, uint_32);
    
extern uint_32 nfc_read_ID( IO_NANDFLASH_STRUCT_PTR, uchar_ptr, _mem_size );
    
extern _mqx_int nfc_ioctl(IO_NANDFLASH_STRUCT_PTR, _mqx_uint, pointer);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/LCD_control.h<|end_filename|>
#ifndef __LCD_CONTROL
  #define __LCD_CONTROL

void LCD_init(void);
void LCD_wr_data(int data);
void LCD_wr_cmd(int cmd);
void LCD_print_char(char ch, int x, int y);
void LCD_set_pos(int x, int y);
void LCD_print_str(char *str, int x, int y);
void LCD_clear_row(int row);


#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_shand.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_shand.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the function for setting the default I/O stream.
*   in the kernel data structure, or for a task.
*
*END************************************************************************/


#include "mqx_inc.h"
#include "fio.h"
#include "io.h"

#if MQX_USE_IO

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_set_handle
* Returned Value   : MQX_FILE_PTR (BUT as a pointer)
* Comments         : 
*    This function changes the address of a default I/O handle, and returns
*    the previous one.  If an incorrect type is given, or the I/O handle was
*    uninitialized, 0 is returned.
*
*END*----------------------------------------------------------------------*/

pointer _io_set_handle
   (
      /* [IN] which I/O handle to modify */
      _mqx_uint stdio_type,

      /* [IN] the new I/O handle */    
      pointer new_file_ptr
   )
{ /* Body */
   register KERNEL_DATA_STRUCT_PTR  kernel_data;
   register TD_STRUCT_PTR           active_ptr;
   register pointer                 old_file_ptr;
   
   _GET_KERNEL_DATA(kernel_data);
   _KLOGE3(KLOG_io_set_handle, stdio_type, new_file_ptr);
   
   switch ( (uint_16)stdio_type ) {

      case IO_PROC_STDIN:
         old_file_ptr = kernel_data->PROCESSOR_STDIN;
         kernel_data->PROCESSOR_STDIN = new_file_ptr;
         break;

      case IO_PROC_STDOUT:
         old_file_ptr = kernel_data->PROCESSOR_STDOUT;
         kernel_data->PROCESSOR_STDOUT = new_file_ptr;
         break;

      case IO_PROC_STDERR:
         old_file_ptr = kernel_data->PROCESSOR_STDERR;
         kernel_data->PROCESSOR_STDERR = new_file_ptr;
         break;

      case IO_STDIN:
         active_ptr = kernel_data->ACTIVE_PTR;
         old_file_ptr = active_ptr->STDIN_STREAM;
         active_ptr->STDIN_STREAM = new_file_ptr;
         break;

      case IO_STDOUT:
         active_ptr = kernel_data->ACTIVE_PTR;
         old_file_ptr = active_ptr->STDOUT_STREAM;
         active_ptr->STDOUT_STREAM = new_file_ptr;
         break;

      case IO_STDERR:
         active_ptr = kernel_data->ACTIVE_PTR;
         old_file_ptr = active_ptr->STDERR_STREAM;
         active_ptr->STDERR_STREAM = new_file_ptr;
         break;

      default:
         old_file_ptr = NULL;

   } /* Endswitch */

   _KLOGX2(KLOG_io_set_handle, old_file_ptr);
   return (old_file_ptr);

} /* Endbody */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/ehci/ehci_bw.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_bw.c$
* $Version : 3.8.16.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
*   This file contains the low-level Host API functions for bandwidth 
*   allocation.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "hostapi.h"
#include "host_cnfg.h"

#include "ehci_main.h"
#include "ehci_prv.h"

/*******************************************************************
Routines not exported by this file
*******************************************************************/
                        
static uint_32 _usb_ehci_commit_bandwidth_slots(_usb_host_handle, EHCI_PIPE_STRUCT_PTR, uint_32, uint_32, uint_8_ptr, uint_32);
                                                  
static void link_interrupt_qh_to_periodiclist(_usb_host_handle, EHCI_QH_STRUCT_PTR, EHCI_PIPE_STRUCT_PTR, uint_32);

static uint_32 allocate_ss_cs_bandwidth(_usb_host_handle, EHCI_PIPE_STRUCT_PTR, uint_32, uint_32, uint_32);

static uint_32 split_combinations(_usb_host_handle, EHCI_PIPE_STRUCT_PTR, uint_8 [], int, int, int, int);
                                   
      
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_calculate_uframe_tr_time
*  Returned Value : bus time in nanoseconds or -1 if error
*  Comments       :
*        Calculate the high speed bus transaction time (USB2.0 Spec 5.11.3)
* in micro seconds for given number of bytes and type of pipe. Handshake
time is included in this and worst case bt stuffing time is take in to 
account.
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_ehci_calculate_uframe_tr_time (

      uint_32     bytes,
      
      uint_8      pipetype
      
   )
{ /* Body */
   uint_32  uframe_tr_time=0;

   /******************************************************************
   The following formulae taken from USB specification are used
   Non-Isochronous Transfer (Handshake Included)
   = (55 * 8 * 2.083) + (2.083 * Floor(3.167 + BitStuffTime(Data_bc))) +
   Host_Delay
   Isochronous Transfer (No Handshake)
   = (38 * 8 * 2.083) + (2.083 * Floor(3.167 + BitStuffTime(Data_bc))) +
   Host_Delay
   ******************************************************************/

   if (pipetype == USB_ISOCHRONOUS_PIPE) 
   {

      /******************************************************************
      Host delay has been taken as 3 nano seconds (3000 pico seconds to guess).
      Linux code takes a rough guess of 5 nano seconds.
      ******************************************************************/
   
      uframe_tr_time = 38 * 8 * 2083 + 
                       2083 * ((3167 + BitStuffTime(1000*bytes))/1000) +
                       VUSB_HS_DELAY;
                                
      uframe_tr_time = uframe_tr_time/1000; /*back to nano seconds */                               

   } 
   else 
   {

      /******************************************************************
      Host delay has been taken as 3 nano seconds (3000 pico seconds to guess).
      Linux code takes a rough guess of 5 nano seconds.
      ******************************************************************/
   
      uframe_tr_time = 55 * 8 * 2083 + 
                       2083 * ((3167 + BitStuffTime(1000*bytes))/1000) +
                       VUSB_HS_DELAY;
                                
      uframe_tr_time = uframe_tr_time/1000; /*back to nano seconds */                               


   }

   /******************************************************************
   convert the times back to micro seconds      
   ******************************************************************/
   uframe_tr_time = uframe_tr_time/1000;
   
   /******************************************************************
   if time is less than 1 micro seconds we take an assumption of 1 Micro sec.
   This is true for transfers that are few bytes esp. Interrupt transfers.
   Actually if the bytes are less than 36 bytes, it will always be less than
   1 Micro seconds.
   ******************************************************************/


   if(uframe_tr_time < 1)  uframe_tr_time = 1;
   
   return uframe_tr_time;
   
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_get_frame_number
*  Returned Value : uint_32
*  Comments       :
*        Get the frame number
*END*-----------------------------------------------------------------*/

uint_32 _usb_ehci_get_frame_number
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle              handle
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR              usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                  dev_ptr;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;   
   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->DEV_PTR;

   /* Get the frame number (not the uframe number */   
   return((EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_FRINDEX) & 0x1FFF)>> 3);

} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_get_micro_frame_number
*  Returned Value : uint_32
*  Comments       :
*        Get the micro frame number
*END*-----------------------------------------------------------------*/

uint_32 _usb_ehci_get_micro_frame_number
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle              handle
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR              usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                  dev_ptr;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;   
   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->DEV_PTR;

   /* Get the uframe number */   
   return(EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_FRINDEX) & 0x07);
} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_allocate_bandwidth
*  Returned Value : USB_OK or error
*  Comments       :
*        Allocates the slots for scheduling transactions on this pipe. 
   This routine looks at the type of transfer (Iso or Periodic) and 
   allocatest the slots in periodic list. Once all slots are found,
   it updates the bandwidth list to reflect the change.
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_ehci_allocate_bandwidth
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* The pipe descriptor to queue */            
      PIPE_STRUCT_PTR                  pipe_ptr
   )
{ /* Body */

   uint_32                             i;
   uint_32                             interval;
   uint_32                             max_ss_slots;
   USB_STATUS                          status = USB_OK;
   USB_EHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   uint_32_ptr                         temp_periodic_list_ptr = NULL;
   EHCI_ITD_STRUCT_PTR                 ITD_ptr;
   pointer                             prev_ptr;
   LIST_NODE_STRUCT_PTR                temp_itd_node_ptr,temp_sitd_node_ptr;
   EHCI_SITD_STRUCT_PTR                SITD_ptr;
   EHCI_PIPE_STRUCT_PTR                pipe_descr_ptr = (EHCI_PIPE_STRUCT_PTR) pipe_ptr;


   /*******************************************************************************
   Initialize the periodic list if it is not initialized already. Note that
   this code could have been put under Host_init routine but since host must
   initialze witthin 1 mili second under OTG timing restrictions, this code
   has been moved here.
   *******************************************************************************/
    if(!usb_host_ptr->PERIODIC_LIST_INITIALIZED)
    {
        /* Set T-Bits of all elements in periodic frame list to 1 */
        temp_periodic_list_ptr = (uint_32_ptr)usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR;

        for (i=0;i<usb_host_ptr->FRAME_LIST_SIZE; i++) 
        {

            EHCI_MEM_WRITE(*temp_periodic_list_ptr,EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT);
            temp_periodic_list_ptr++;

        }

        /************************************************
        Cache must be flushed to update the RAM
        ************************************************/
        USB_dcache_flush_mlines((void *)usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR, (usb_host_ptr->FRAME_LIST_SIZE * sizeof(uint_32_ptr)));
         
        usb_host_ptr->PERIODIC_LIST_INITIALIZED = TRUE; 
    }
   
   /*******************************************************************************
   Initialize the ITDS list if this is High speed pipe.
   *******************************************************************************/
   if ((!usb_host_ptr->ITD_LIST_INITIALIZED) && 
      (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH))  
   {
         /* Enqueue all the ITDs */   
         ITD_ptr = usb_host_ptr->ITD_ALIGNED_BASE_PTR;

         /* Enqueue all the ITDs */   
         for (i=0;i<USBCFG_EHCI_MAX_ITD_DESCRS;i++) 
         {
            /* Set the dTD to be invalid */
            EHCI_MEM_WRITE(ITD_ptr->NEXT_LINK_PTR,EHCI_ITD_T_BIT);
            /* Set the Reserved fields to 0 */
            ITD_ptr->SCRATCH_PTR = (pointer)usb_host_ptr;
            _usb_ehci_free_ITD((pointer)usb_host_ptr, (pointer)ITD_ptr);
            ITD_ptr++;
         }

      
         /* initialize all nodes and link them */
         temp_itd_node_ptr =  (LIST_NODE_STRUCT_PTR) usb_host_ptr->ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR;
         prev_ptr = NULL;
         for(i=0;i<USBCFG_EHCI_MAX_ITD_DESCRS;i++)
         {
             /* next node is not an active node */
             temp_itd_node_ptr->next_active = FALSE;
             
             /* previous node connetcion */
             temp_itd_node_ptr->prev = prev_ptr;
             
             /* move pointer */
             prev_ptr =  temp_itd_node_ptr;
             
             /* move next */
             temp_itd_node_ptr++;
             
             /* store the next pointer in previous node */
             ((LIST_NODE_STRUCT_PTR) prev_ptr)->next = temp_itd_node_ptr;
         }

      usb_host_ptr->ITD_LIST_INITIALIZED = TRUE;
   }
   /*******************************************************************************
   Initialize the SITDS list if this is full speed or low speed pipe.
   *******************************************************************************/
   if ((!usb_host_ptr->SITD_LIST_INITIALIZED) &&
      (pipe_descr_ptr->G.SPEED != USB_SPEED_HIGH))   
   {
         SITD_ptr = usb_host_ptr->SITD_ALIGNED_BASE_PTR;
   
         /* Enqueue all the SITDs */   
         for (i = 0; i < USBCFG_EHCI_MAX_SITD_DESCRS; i++) 
         {
            /* Set the dTD to be invalid */
            EHCI_MEM_WRITE(SITD_ptr->NEXT_LINK_PTR,EHCI_SITD_T_BIT);
            /* Set the Reserved fields to 0 */
            SITD_ptr->SCRATCH_PTR = (pointer)usb_host_ptr;
            _usb_ehci_free_SITD((pointer)usb_host_ptr, (pointer)SITD_ptr);
            SITD_ptr++;
         }

         
         /* initialize all nodes and link them */
         temp_sitd_node_ptr =  
            (LIST_NODE_STRUCT_PTR) usb_host_ptr->ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR;
         prev_ptr = NULL;
         for(i = 0; i < USBCFG_EHCI_MAX_SITD_DESCRS; i++)
         {
             /* next node is not an active node */
             temp_sitd_node_ptr->next_active = FALSE;
             
             /* previous node connection */
             temp_sitd_node_ptr->prev = prev_ptr;
             
             /* move pointer */
             prev_ptr =  temp_sitd_node_ptr;
             
             /* move next */
             temp_sitd_node_ptr++;
             
             /* store the next pointer in previous node */
             ((LIST_NODE_STRUCT_PTR) prev_ptr)->next = temp_sitd_node_ptr;
         }

         usb_host_ptr->SITD_LIST_INITIALIZED = TRUE;
   }
   
   /*******************************************************************************
   Go Through the  PERIODIC_FRAME_LIST_BW record to find the available slots. Here
   starts the complexity of the process. See the following from USB specifications.
   
   An isochronous endpoint must specify its required bus access period. Full-/high-speed
   endpoints must specify a desired period as (2^(bInterval-1)) x F, where bInterval is
   in the range one to (and including) 16 and F is 125 µs for high-speed and 1ms for
   full-speed. This allows full-/high-speed isochronous transfers to have rates slower
   than one transaction per (micro)frame.
   
   An endpoint for an interrupt pipe specifies its desired bus access period. A
   full-speed endpoint can specify a desired period from 1 ms to 255 ms. Low-speed
   endpoints are limited to specifying only 10 ms to 255 ms. High-speed endpoints can
   specify a desired period (2^(bInterval-1))x125 µs, where bInterval is in the range 1 to
   (including) 16. 


   For high speed interrupts, Since we must have slots available at uframe_interval
   periods, if we can not find any slot starting from anywhere in Micro frame number
   1 to Micro frame number equal to uframe_interval....till the end of
   periodic list we are out of bandwidth. For low and full speed device we do the same
   starting from frame 1 to frame frame_interval.

   ********************************************************************************/

   /*************************************************************************
   If it is a high speed interrupt, allocate the slots at micro frame interval.
   Or if low or full speed, allocate slots at frame intervals. Note that
   the possible values of the interval for high speed are 1,2,4,8,16.
   **************************************************************************/
   interval = pipe_descr_ptr->G.INTERVAL;
   i = 0;

   if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) 
   {
      
      do
      {
         status = _usb_ehci_commit_bandwidth_slots(handle, pipe_descr_ptr, i, interval, NULL, 0);
      
         if(status != USBERR_BANDWIDTH_ALLOC_FAILED)
         {
            /* Slot allocation was either successful or there was some other error. */
            break;
         }
      
         i++;   
      } while ((i < interval) | (i < usb_host_ptr->FRAME_LIST_SIZE * 8));

   } 
   else 
   {
   
      /***************************************************************************
      Find the possible SS and CS that this endpoint could have. Check  the
      periodic list for each such slot. If it fails, restart searching the periodic
      list for new slot.
      ****************************************************************************/
      /********************************************************************
      It is no simple game as it sounds in the code here. We should consider
      the time taken by the transaction and set the start split and complete
      split transactions for low and full speed devices. Read the following
      rules carefully to understand the code simplifying assumptions. 
      ********************************************************************/ 

      /********************************************************************
      We are allowed to use only 80% of a frame for full speed and low speed
      periodic transfers. This is to provide space for Bulk and Control
      transfers. This means that if a frame slot exceeds .8x1000 micro seconds
      ,it is out of space. Since this transaction is a low or full speed
      transaction we need to find which start split and complete split could
      be scheduled. The following rules are followed in this code. See section
      11.18 in USB specs for details. Y0-Y7 refers to micro frames on B bus
      which is 1 Microframe behind H Bus.

      1) Host never schedules a start split in Y6.

       If We can not schedule the SS in H0-H6 for OUT, we will move to next frame.
       For IN transactions we must schedule SS early enough to ensure that
       all CS are scheduled within H7. Simplification is that we don't want to
       cross the microframe boundry in our implementation of CS.

      ISO OUT
      ========             
      2) for Iso OUTs we must determine how many 188 bytes chunks it will
      take and schedule each of them in a Microframe. Each such microframe
      (also called budgeted microframe) should have a SS in previous
      micro frame. We always try to do a SS in H0-H6.
      If this is not possible we just move over to next frame.

      3) There is no complete split scheduled for Iso OUT


      ISO IN
      =======

      4) For ISO IN, we must schedule a complete split in each micro frame
      following the micro frame in which transaction is budgeted. Also
      if the last micro frame in which complete-split is scheduled is
      less that Y6, we schedule two more in Y6 and Y7.

      5)We take a simplyfying assumption that we budget the transaction
      between H0-H5 and schedule a complete split in rest of the
      micro frames till H7.


      Interrupt IN/OUT
      ================
      6)For interrupt IN/OUT host must schedule a complete split in the
      next two micro frames after transaction is budgeted. An additional
      complete split must be scheduled in the 3rd micro frame unless the 
      transaction was budgeted to start in Y6.

      7)We make a simplyfying assumption that if the trasnaction is not
      within H0-H4, we will go to the next frame. This will allow us to
      schedule 3 CS in H5-H7

      8)Max data size for low speed interrupt is  8 bytes
       Max data size for full speed interrupt is 64 bytes
       
       This means that we will never need more than a Microframe for
       an Interrupt OUT or IN.
       
       
      9) Host never schedules for than 16 SS (start splits) in a Micro
      frame for a given TT.

      ********************************************************************/ 

      switch(pipe_descr_ptr->G.PIPETYPE) 
      {
         case USB_ISOCHRONOUS_PIPE:
         
            max_ss_slots = 
               (uint_32)(pipe_descr_ptr->G.MAX_PACKET_SIZE/ EHCI_START_SPLIT_MAX_BUDGET);
            
            /* add 1 if some bytes are remaining to be scheduled*/
            max_ss_slots =  ((pipe_descr_ptr->G.MAX_PACKET_SIZE%EHCI_START_SPLIT_MAX_BUDGET) > 0)? \
                           (max_ss_slots +1):max_ss_slots;
                                    
            switch(pipe_descr_ptr->G.DIRECTION) 
            {
            
               case USB_SEND: /*ISO OUT*/
                  /***********************************************************
                  For ISO OUT we want to schedule the SS in H0-H6.
                  See the rules above. This means that we can do
                  188*7 = 1316 Max packetsize in one frame, return fail if this
                  is not the case.
                  ***********************************************************/
                  if(max_ss_slots > 7)
                  {
                     return USB_log_error(__FILE__,__LINE__,USBERR_BANDWIDTH_ALLOC_FAILED); 
                  }
                        
                  /***********************************************************************
                  If the packet size is within budget, try to allocate bandwidth for
                  all possible start split combinations starting from microframe 0 to 
                  7. 
                  ************************************************************************/
                  status = allocate_ss_cs_bandwidth(handle,pipe_descr_ptr,max_ss_slots,0,7);
                  
                  break;
               case USB_RECV:
               
                  /***********************************************************************
                  For ISO IN, we want to schedule SS between H0-H5 so that complete splits
                  could be scheduled latest by H6. In best case we will have 7 slots
                  to complete split transaction.
                  ************************************************************************/
                  if(max_ss_slots > 7)
                  {
                     return USB_log_error(__FILE__,__LINE__,USBERR_BANDWIDTH_ALLOC_FAILED); 
                  }
                  
                  /* Note that ideally we should start SS as late as possible in this
                  case because we want to minimize the number of slots when a complete
                  transaction is scheduled but in this case we start from 0 always
                  for simplicity. This should be addressed if we run in bandwidth
                  problems because of more ISO IN pipes.*/

                  /* schedule a SS from 0 to as late as 7-max_ss_slots */
                  status = allocate_ss_cs_bandwidth(handle,pipe_descr_ptr,1,0,(7-max_ss_slots));

                  break;
               default:
                  break;
            }
            break;
         case USB_INTERRUPT_PIPE:
            /*****************************************************************************
            For interrupt pipes, life is cool because we need only 1 microframe max to
            send all data (see the data limits on interrupt pipes in comments above).
            We still make a simplifying assumption to schedule SS in Y0-Y3.
            *****************************************************************************/
               
            switch(pipe_descr_ptr->G.DIRECTION) 
            {
               case USB_SEND:
                  /* 1 slot required between microframes 0-3 to send data and we
                  can schedule CS in next 3 of them*/
                  status = allocate_ss_cs_bandwidth(handle,pipe_descr_ptr,1,0,3);
                  break;
               
               case USB_RECV:
                  /* 1 slot required between microframes 0-3 to so SS and we
                  can schedule CS in next 3 of them*/
                  status = allocate_ss_cs_bandwidth(handle,pipe_descr_ptr,1,0,3);
                  break;
                  
               default:
                  break;
            }
            break;
         default:
            //DEBUG_PRINT("_usb_ehci_commit_bandwidth_slots: Unknown Pipe type\n");
            break;

      }/*end switch (pipe_descr_ptr->PIPETYPE) */
            
    }

   return status;

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_commit_bandwidth_slots
*  Returned Value : USB_OK or error
*  Comments       :
*        Allocates the slots for scheduling transactions on this pipe. 
   This routine looks at the BW list and finds regular slots at the
   asked interval starting from 'start' slot number. 
*END*-----------------------------------------------------------------*/

static uint_32 _usb_ehci_commit_bandwidth_slots
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,
      
      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR             pipe_descr_ptr,

      /* The starting slot from the periodic list*/            
      uint_32                          start,
      
      /* The interval for the pipe              */            
      uint_32                          interval,
      
      /* start split slots asked for this pipe, NULL for high speed pipe*/            
      uint_8_ptr                       ss,
      
      /* Max number of SS slots required*/            
      uint_32                          max_ss_slots
      
      
)
{
      USB_EHCI_HOST_STATE_STRUCT_PTR      usb_host_ptr;
      uint_8_ptr                          frame_list_bw_ptr;
      EHCI_QH_STRUCT_PTR                  QH_ptr = NULL;
      uint_32                             i,j,count,frame,uframe;
      uint_32                             status = USB_OK,time_for_action;
      boolean                             bandwidth_slots[8] = {FALSE,FALSE,FALSE,FALSE, \
                                                                FALSE,FALSE,FALSE,FALSE};
      uint_8                              ss_slots[8] = {0,0,0,0,0,0,0,0};
      uint_8                              cs_slots[8] = {0,0,0,0,0,0,0,0};
                                                                
         
      usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
      
      
      //ASSERT("_usb_ehci_commit_bandwidth_slots",(pipe_descr_ptr == NULL))
      //ASSERT("_usb_ehci_commit_bandwidth_slots",(handle == NULL))
      
      
      
      /****************************************************************************
      Here is the important note. We want to keep a record of how much bandwidth
      has been allocated in the periodic list. We use this two dimension array
      called   PERIODIC_FRAME_LIST_BW_PTR to keep a record. This array is
      a  SIZEx8 (SIZE for periodic list size and 8 for each micro frame in a frame).
      It knows how much time has been consumed in each micro frame. We look at 
      that time and find if we can allocate this new transfer or not. When a
      pipe is closed we update and adjust this array to reflect the available
      slots. There could be very complex schemes to manage bandwidth and we need
      to improve the adjusting algorithms so that this array provides the best shot
      for bandwidth but current code does a simple but workable solution for
      periodic transfers.
      ****************************************************************************/

      frame_list_bw_ptr = usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR;

      
      /*********************************************************************************
      Start looking in the bandwidth frame list for the slots. We will
      do two iterations. In first we will find if slots are available and
      in second we will update our bandwidth list to commit slots for this pipe.
      *********************************************************************************/
      
      
      /**************************************************************************
      If the speed is high, we just look at micro frames and we don't need to
      worry about the split transations. So go through the periodic list and
      find available micro frames at regular interval. Return if not available.
      ***************************************************************************/
      
      if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) 
      {
      
         /*************************************************************************
         Calculate the time required in microseconds for a transaction on this
         pipe. Note that we are scheduling on high speed bus and times are
         calculated as recommended for high speed by USB 2.0 specification.
         **************************************************************************/

         time_for_action = _usb_ehci_calculate_uframe_tr_time(
                                 pipe_descr_ptr->G.MAX_PACKET_SIZE,
                                 pipe_descr_ptr->G.PIPETYPE);
                                    

      
         /* FIX ME: The high speed interrupts are not tested yet */
          for(i = start; i < usb_host_ptr->FRAME_LIST_SIZE * 8; i+= interval)
         {
            /********************************************************************
            We are allowed to use only 80% of a micro frame and 80% of frame
            periodic transfers. This is to provide space for Bulk and Control
            transfers. This means that if a micro frame slot exceeds 
            .8 * 125 = 100 micro seconds, it is out of space.
            ********************************************************************/
            frame  = i / 8;
            uframe = i % 8;
            
            /*******************************************************************
            The interval in HS can have value one of 1, 2, 4, 8, 16, 32 ...
            From which implies the uframe offset: 1, 2, 4, 0, 0, 0, 0, ...
            So some optimization can be applied here, but we will not do that for now.
            ********************************************************************/
            bandwidth_slots[uframe] = TRUE ;
            
            if((frame_list_bw_ptr[i] + time_for_action) > 100)
            {
               return  USB_log_error(__FILE__,__LINE__,USBERR_BANDWIDTH_ALLOC_FAILED);
            }
         }
         
      }
      else
      {
         /**************************************************************************
         If the speed is low or full,we have to find slots where we can issue
         split transactions. Read the following from USB 2.0 specs.
         
         11.18.2 TT Microframe Pipeline
         
         The TT implements a microframe pipeline of split transactions in support of
         a full-/low-speed bus. Startsplit transactions are scheduled a microframe
         before the earliest time that their corresponding full-/lowspeed transaction
         is expected to start. Complete-split transactions are scheduled in
         microframes that the full-/low-speed transaction can finish.
         
         This clearly says that we must check the budget in next microframe for
         Start splits and same microframe for complete splits.
         ***************************************************************************/

         /*************************************************************************
         If this pipe takes less than 188 bytes of time, we use lower number to
         save bandwidth time.
         **************************************************************************/
         if (max_ss_slots <= 1) //max_ss_slots should be always > 0
         {
            /* splitted transaction will have size less than MAX_PACKET_SIZE */
            time_for_action = _usb_ehci_calculate_uframe_tr_time(
                                 pipe_descr_ptr->G.MAX_PACKET_SIZE,
                                 pipe_descr_ptr->G.PIPETYPE);
               
         }
         else
         {
            /* splitted transaction will have size less than EHCI_START_SPLIT_MAX_BUDGET */
            time_for_action = _usb_ehci_calculate_uframe_tr_time(
                                                         EHCI_START_SPLIT_MAX_BUDGET,
                                                         pipe_descr_ptr->G.PIPETYPE
                                                         );
         }
   

         /**********************************************************
         Check bandwidth in periodic list for the asked combination
         of start split transaction.
         ***********************************************************/ 
         for (i = start; i < usb_host_ptr->FRAME_LIST_SIZE; i += interval)
         {

               /**********************************************************
               Interrupt OUT budget the next microframe after SS
               ***********************************************************/ 

               if((pipe_descr_ptr->G.PIPETYPE == USB_INTERRUPT_PIPE) &&
                 (pipe_descr_ptr->G.DIRECTION == USB_SEND))
               {
                    for(j = 1; j <= max_ss_slots; j++)
                   {
                      /* we never allocate last microframe for the slot so ss[j] is always less than 7 */
                     bandwidth_slots[ss[j]+1] = TRUE ;
                     if((frame_list_bw_ptr[8 * i + ss[j] + 1] + time_for_action) > 100)
                     {
                        status =  USB_log_error(__FILE__,__LINE__,USBERR_BANDWIDTH_ALLOC_FAILED);
                        return status;
                     }

                   }
               }
               /* for interrupt IN check  3 micro frames (starting from second) for CS*/
               else if((pipe_descr_ptr->G.PIPETYPE == USB_INTERRUPT_PIPE) &&
                 (pipe_descr_ptr->G.DIRECTION == USB_RECV))
                 
               {
                    for(j = 1; j <= max_ss_slots; j++)
                   {
               
                     bandwidth_slots[ss[j]+2] = TRUE ;
                     bandwidth_slots[ss[j]+3] = TRUE ;
                     bandwidth_slots[ss[j]+4] = TRUE ;
                     
                     /* look for the budget in the microframe*/
                     if(((frame_list_bw_ptr[i+ss[j]+2] + time_for_action) > 100) ||
                        ((frame_list_bw_ptr[i+ss[j]+3] + time_for_action) > 100) ||
                        ((frame_list_bw_ptr[i+ss[j]+4] + time_for_action) > 100))
                     {
                        status =  USB_log_error(__FILE__,__LINE__,USBERR_BANDWIDTH_ALLOC_FAILED);
                        return status;
                     }

                   }

               }
            
               /* for ISO OUT check next micro frame */
               else if((pipe_descr_ptr->G.PIPETYPE == USB_ISOCHRONOUS_PIPE) &&
                 (pipe_descr_ptr->G.DIRECTION == USB_SEND))
                 
               {
                     for(j = 1; j <= max_ss_slots; j++)
                   {
                     bandwidth_slots[ss[j]+1] = TRUE ;
                     if((frame_list_bw_ptr[8 * i + ss[j] + 1] + time_for_action) > 100)
                     {
                        status =  USB_log_error(__FILE__,__LINE__,USBERR_BANDWIDTH_ALLOC_FAILED);
                        return status;
                     }

                   }
               }

               /* for ISO IN check next all micro frames after first SS*/
               else if((pipe_descr_ptr->G.PIPETYPE == USB_ISOCHRONOUS_PIPE) &&
                     (pipe_descr_ptr->G.DIRECTION == USB_RECV))
                 
               {
                    for(j = ss[1]; j < 8; j++) /*ss[1] is first SS */
                   {
                      bandwidth_slots[j+1] = TRUE;
                      if((frame_list_bw_ptr[8 * i + j + 1] + time_for_action) > 100)
                     {
                        status =  USB_log_error(__FILE__,__LINE__,USBERR_BANDWIDTH_ALLOC_FAILED);
                        return status;
                     }

                   }

               }

            
            
         } /*for */
         
         

      } /*else*/
      


      /********************************************************************
      store the time for action in the pipe descriptor
      ********************************************************************/

      pipe_descr_ptr->BWIDTH = (uint_16)time_for_action;


      /********************************************************************
      store the bandwidth slots in pipe descriptor pointer.
      ********************************************************************/
      
      for(j = 0; j < 8; j++)
      {
            pipe_descr_ptr->BWIDTH_SLOTS[j] = (uint_8)bandwidth_slots[j];
      }

      /***********************************************************************
      store the start frame or micro frame number in pipe descriptor structure
      ************************************************************************/
      if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) 
      {
          pipe_descr_ptr->START_UFRAME = start;
      }
      else
      {
          pipe_descr_ptr->START_FRAME = start;
      }
      

      /********************************************************************
      When Bandwidth is available,
      For ISOCHRONOUS full speed TRANSACTIONS, we just need to store the
      SS and CS positions inside frames.
      ********************************************************************/
      if ((pipe_descr_ptr->G.SPEED != USB_SPEED_HIGH) && 
         (pipe_descr_ptr->G.PIPETYPE == USB_ISOCHRONOUS_PIPE)) 
      {
         
         switch(pipe_descr_ptr->G.DIRECTION)
         {
            case USB_SEND: /* ISO OUT pipe */
            
               count = 0; /* used to find how many start splits are needed */
               for(j=0;j<8;j++)
               {
                    if(bandwidth_slots[j])
                    {
                     /* bandwidth is allocated at next position to SS so
                     we use j-1 to start a split */
                       pipe_descr_ptr->START_SPLIT |=  (1 << (j-1));
                       count++; 
                    }
               }
               
               /* there is no complete split on a ISO OUT so we set the field to 0 */
               pipe_descr_ptr->COMPLETE_SPLIT = 0;
               pipe_descr_ptr->NO_OF_START_SPLIT = count;

               break;
            
            case USB_RECV: /* ISO IN pipe */
            
               /* we have only 1 start split on a ISO IN */
               pipe_descr_ptr->START_SPLIT = (uint_8)(1 << ss[1]);

               /* we do complete split on all positions after first SS */               
               for(j=0;j<8;j++)
               {
                     if(bandwidth_slots[j])
                    {
                     /* CS is scheduled in the next micro frame in which
                     transaction is budgeted so we use j+1 */
                     
                       pipe_descr_ptr->COMPLETE_SPLIT |=  (1 << (j+1)); 
                    }

               }

               break;
         }

      }  
      /********************************************************************
      Since bandwidth is available, letus make the life easy for interrupt
      transfers. We will allocate a QH here and link it to the available
      slots in periodic slots. This is the best place to do it since we
      already know the slots (micro frames) that are available. We will however
      keep the QH inactive until a transfer is really queued on it. Life is
      not easy for Iso transfers however because they have no queue heads.
      In case of Iso transfers we should remember the slots available inside
      the pipe decriptor and use them when a transfer is queued.
      ********************************************************************/
      if(pipe_descr_ptr->G.PIPETYPE == USB_INTERRUPT_PIPE) 
      {
         
               /******************************************************************
               Allocate a new queue head
               *******************************************************************/
         
               EHCI_QH_QGET(usb_host_ptr->QH_HEAD, usb_host_ptr->QH_TAIL, QH_ptr);

               if (!QH_ptr) {
                  return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
               } /* Endif */

               usb_host_ptr->QH_ENTRIES--;

               //printf("\nQH Get 0x%x, #entries=%d",QH_ptr,usb_host_ptr->QH_ENTRIES);
               
               /******************************************************************
               Initialize the interrupt Queue head
               *******************************************************************/
               _usb_ehci_init_Q_HEAD(handle,
                                     pipe_descr_ptr,/*pipe that uses this QH */ 
                                     QH_ptr,        /*QH to initialize*/
                                     NULL,          /*Previous QH to link*/
                                     NULL);         /*first QTD to link */
                                     
               /******************************************************************
               Depending upon the speed and direction of the transfer update the
               QH with the micro frame numbers that are allocated
               ******************************************************************/
         
               if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) 
               {
                  /* store the micro frame in QH in which this pipe will have its tranfers done */
                  for (i = 0; i < 8; i++)
                  {
                      /*set a 1 at the position of the micro frame which interrupt transfer
                      is scheduled. */
                     if(bandwidth_slots[i])
                     {
                           pipe_descr_ptr->START_SPLIT |=  (1 << i);
                     }
               
                  }
               }
               else  /*full and low speed interrupt IN and OUT*/
               {
         
                  for(j = 1; j <= max_ss_slots; j++)
                  {
                     /*schedule a SS */
                     pipe_descr_ptr->START_SPLIT |=  (1 << ss[j]);
               
                     /*schedule a CS at the next three positions*/
                     pipe_descr_ptr->COMPLETE_SPLIT |=  (1 << (ss[j]+2));
                     pipe_descr_ptr->COMPLETE_SPLIT |=  (1 << (ss[j]+3));
                     pipe_descr_ptr->COMPLETE_SPLIT |=  (1 << (ss[j]+4));
               
                  }
               }
         
               /*set the interrupt mask schedule field in QH */
               EHCI_MEM_CLEAR_BITS(QH_ptr->EP_CAPAB_CHARAC2, 0x000000ff); /*zero last byte*/
               EHCI_MEM_SET_BITS(QH_ptr->EP_CAPAB_CHARAC2,pipe_descr_ptr->START_SPLIT);

               /*set the interrupt complete schedule field in QH */
               EHCI_MEM_CLEAR_BITS(QH_ptr->EP_CAPAB_CHARAC2,0x0000ff00); /*zero second byte*/
               EHCI_MEM_SET_BITS(QH_ptr->EP_CAPAB_CHARAC2,pipe_descr_ptr->COMPLETE_SPLIT << 8);
         
      }
      
      
      
      /********************************************************************
      if status is fine we should commit the slots now by updating the 
      bandwidth list.
      ********************************************************************/

      if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) 
      {
          for(i = start; i < usb_host_ptr->FRAME_LIST_SIZE * 8; i+= interval)
         {
            /********************************************************************
            We are allowed to use only 80% of a micro frame for 
            periodic transfers. This is to provide space for Bulk and Control
            transfers. This means that if a micro frame slot exceeds .8 * 125 = 100
            micro seconds, it is out of space.
            ********************************************************************/
            frame  = i / 8;
            uframe = i % 8;
            
            frame_list_bw_ptr[i] += time_for_action;
              
         
            /******************************************************************
            if this is for an interrupt pipe, we can link the QH here itself
            *******************************************************************/
            if(pipe_descr_ptr->G.PIPETYPE == USB_INTERRUPT_PIPE) 
            {

               link_interrupt_qh_to_periodiclist(handle,
                                                 QH_ptr,
                                                 pipe_descr_ptr,
                                                 i);
            }
         }
      
      }
      else
      {
          for(i = start; i < usb_host_ptr->FRAME_LIST_SIZE; i+= interval)
         {
               /********************************************************************
               Update the bandwidth in all frames in which transaction is scheduled.
               ********************************************************************/

               for(j = 0; j < 8; j++)
               {

                  if(bandwidth_slots[j])
                  {
                     frame_list_bw_ptr[8 * i + j] += time_for_action;
                  }
                     
               }

                /******************************************************************
               if this is for an interrupt pipe, we can link the QH here itself
               *******************************************************************/
               if(pipe_descr_ptr->G.PIPETYPE == USB_INTERRUPT_PIPE) 
               {

                  link_interrupt_qh_to_periodiclist(handle,
                                                    QH_ptr,
                                                    pipe_descr_ptr,
                                                    i);
               }

          }
          
      }
               
      return status;
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : link_interrupt_qh_to_periodiclist
*  Returned Value : USB_OK or error
*  Comments       :
*        Links the QH to the given slot in periodic list. If pipe is
a high speed, slot number is the micro frame number to link QH in. If
pipe is a low speed, slot number is the frame number to link QH in. In
all cases, we link in frame except that we also update the microframe
schedule mask number.
*END*-----------------------------------------------------------------*/

static void link_interrupt_qh_to_periodiclist
   (

      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,
   
      /* QH that will be scheduled. */
      EHCI_QH_STRUCT_PTR               QH_ptr,
      
      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR             pipe_descr_ptr,

      /* slot in which this QH should be scheduled */            
      uint_32                          slot_number
      
   )
{     
      USB_EHCI_HOST_STATE_STRUCT_PTR      usb_host_ptr;
      uint_32                             frame_index;
      EHCI_ITD_STRUCT_PTR                 ITD_ptr;
      EHCI_SITD_STRUCT_PTR                SITD_ptr;
      uint_32                             item_type = EHCI_FRAME_LIST_ELEMENT_TYPE_QH;
      uint_32                             status = USB_OK;
      #if 1
      USB_Uncached uint_32 _PTR_          transfer_data_struct_ptr = NULL;
      USB_Uncached uint_32 _PTR_          prev_transfer_data_struct_ptr = NULL;
      #else
      USB_Uncached uint_32_ptr            transfer_data_struct_ptr = NULL;
      USB_Uncached uint_32_ptr            prev_transfer_data_struct_ptr = NULL;
      #endif
      EHCI_QH_STRUCT_PTR                  temp_QH_ptr = NULL;
      EHCI_FSTN_STRUCT_PTR                FSTN_ptr=NULL;

      usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR) handle;
      
      /*****************************************************************
      Calculate the frame and micro frame index in the periodic list      
      *****************************************************************/
      if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) 
      {
         frame_index  = slot_number >> 3; /*divide by 8 */
      }
      else
      {
         frame_index  = slot_number; /* already slot is in frame*/
      }

      /*****************************************************************
      traverse the list for the choosen frame and link the QH at the end.
      *****************************************************************/
      transfer_data_struct_ptr = (USB_Uncached uint_32 _PTR_)(usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR);
      transfer_data_struct_ptr += frame_index;

      /*****************************************************************
      loop through the frame list elements till we reach the end
      *****************************************************************/
      prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
      if ((transfer_data_struct_ptr != NULL)
          && !(EHCI_MEM_READ(*transfer_data_struct_ptr) & EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT))
      {
            switch (EHCI_GET_TYPE(prev_transfer_data_struct_ptr))
            {
               case EHCI_ELEMENT_TYPE_ITD:
                  ITD_ptr = (EHCI_ITD_STRUCT_PTR)(((uint_32) prev_transfer_data_struct_ptr));
                  prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
                  transfer_data_struct_ptr = (pointer)ITD_ptr->NEXT_LINK_PTR;
                  break;
               case EHCI_ELEMENT_TYPE_QH:
                  temp_QH_ptr = (EHCI_QH_STRUCT_PTR)(((uint_32) prev_transfer_data_struct_ptr));
                  prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
                  transfer_data_struct_ptr = (pointer)(temp_QH_ptr->HORIZ_LINK_PTR & EHCI_HORIZ_PHY_ADDRESS_MASK);
                  if ((EHCI_QH_STRUCT_PTR) transfer_data_struct_ptr == QH_ptr)
                     return;
                  break;
               case EHCI_ELEMENT_TYPE_SITD:
                  SITD_ptr = (EHCI_SITD_STRUCT_PTR)(((uint_32) prev_transfer_data_struct_ptr));
                  prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
                  transfer_data_struct_ptr = (pointer)SITD_ptr->NEXT_LINK_PTR;
                  break;
               case EHCI_ELEMENT_TYPE_FSTN:
                  FSTN_ptr = (EHCI_FSTN_STRUCT_PTR)(((uint_32) prev_transfer_data_struct_ptr));
                  prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
                  transfer_data_struct_ptr = (pointer)FSTN_ptr->NORMAL_PATH_LINK_PTR;
                  break;
               default:
                  break;
            } /* EndSwitch */
      }
      prev_transfer_data_struct_ptr = transfer_data_struct_ptr;      
      while (!(EHCI_MEM_READ(*transfer_data_struct_ptr) & EHCI_QUEUE_HEAD_POINTER_T_BIT)) 
      {

            switch (EHCI_GET_TYPE(prev_transfer_data_struct_ptr)) 
            {
               case EHCI_ELEMENT_TYPE_ITD:
                  ITD_ptr = (EHCI_ITD_STRUCT_PTR)(((uint_32) prev_transfer_data_struct_ptr) & 
                                                      EHCI_HORIZ_PHY_ADDRESS_MASK);
                  prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
                  transfer_data_struct_ptr = (pointer)EHCI_MEM_READ(ITD_ptr->NEXT_LINK_PTR);
               break;
               case EHCI_ELEMENT_TYPE_QH:
                  temp_QH_ptr = (EHCI_QH_STRUCT_PTR)(((uint_32) prev_transfer_data_struct_ptr) & 
                                                      EHCI_HORIZ_PHY_ADDRESS_MASK);
                  prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
                  transfer_data_struct_ptr = (pointer)(EHCI_MEM_READ(temp_QH_ptr->HORIZ_LINK_PTR) & EHCI_HORIZ_PHY_ADDRESS_MASK);
                  if ((EHCI_QH_STRUCT_PTR) transfer_data_struct_ptr == QH_ptr)
                     return;
               break;
               case EHCI_ELEMENT_TYPE_SITD:
                  SITD_ptr = (EHCI_SITD_STRUCT_PTR)(((uint_32) prev_transfer_data_struct_ptr) & 
                                                      EHCI_HORIZ_PHY_ADDRESS_MASK);
                  prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
                  transfer_data_struct_ptr = (pointer)EHCI_MEM_READ(SITD_ptr->NEXT_LINK_PTR);
               break;
               case EHCI_ELEMENT_TYPE_FSTN:
                  FSTN_ptr = (EHCI_FSTN_STRUCT_PTR)(((uint_32) prev_transfer_data_struct_ptr) & 
                                                      EHCI_HORIZ_PHY_ADDRESS_MASK);
                  prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
                  transfer_data_struct_ptr = (pointer)EHCI_MEM_READ(FSTN_ptr->NORMAL_PATH_LINK_PTR);
               break;
               default:
                  /**************************************************************
                  Should never some here ..clearly means bug or memory corruption
                  ***************************************************************/
                  break;
            } /* EndSwitch */
      } /* EndWhile */
      

      /*****************************************************************
      time to link with previous data structure.
      *****************************************************************/
      if (prev_transfer_data_struct_ptr != transfer_data_struct_ptr)
      {
         switch (EHCI_GET_TYPE(prev_transfer_data_struct_ptr))
         {
      
            case EHCI_ELEMENT_TYPE_ITD:
               ITD_ptr = (EHCI_ITD_STRUCT_PTR) transfer_data_struct_ptr;
               EHCI_MEM_WRITE(ITD_ptr->NEXT_LINK_PTR,((uint_32)QH_ptr | (item_type << EHCI_QH_ELEMENT_TYPE_BIT_POS)));
               break;
            case EHCI_ELEMENT_TYPE_QH:
               temp_QH_ptr = (EHCI_QH_STRUCT_PTR) transfer_data_struct_ptr;
               EHCI_MEM_WRITE(temp_QH_ptr->HORIZ_LINK_PTR,((uint_32)QH_ptr | (item_type << EHCI_QH_ELEMENT_TYPE_BIT_POS)));

               break;
            case EHCI_ELEMENT_TYPE_SITD:
               SITD_ptr = (EHCI_SITD_STRUCT_PTR) transfer_data_struct_ptr;
               EHCI_MEM_WRITE(SITD_ptr->NEXT_LINK_PTR ,((uint_32)QH_ptr | (item_type << EHCI_QH_ELEMENT_TYPE_BIT_POS)));
               break;
               
            case EHCI_ELEMENT_TYPE_FSTN:
               FSTN_ptr = (EHCI_FSTN_STRUCT_PTR) transfer_data_struct_ptr;
               EHCI_MEM_WRITE(FSTN_ptr->NORMAL_PATH_LINK_PTR ,((uint_32)QH_ptr | (item_type << EHCI_QH_ELEMENT_TYPE_BIT_POS)));
               break;
            default:
               break;
         } /* EndSwitch */
         
      } /* endif */

      /*******************************
      It means new list is starting out                                 
      ********************************/
      else 
      {
         EHCI_MEM_WRITE(*transfer_data_struct_ptr,((uint_32)QH_ptr | (item_type << EHCI_QH_ELEMENT_TYPE_BIT_POS)));
      }
               
      
      return;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : unlink_periodic_data_structure_from_frame
*  Returned Value : None
*  Comments       :
*        unlinks the data structure from periodic list 
*END*-----------------------------------------------------------------*/
void unlink_periodic_data_structure_from_frame(
                                          USB_Uncached uint_32 _PTR_ prev_transfer_data_struct_ptr,
                                          USB_Uncached uint_32 _PTR_ transfer_data_struct_ptr
)
{
         EHCI_ITD_STRUCT_PTR                          ITD_ptr;
         EHCI_SITD_STRUCT_PTR                         SITD_ptr;
         EHCI_FSTN_STRUCT_PTR                         FSTN_ptr;
         EHCI_QH_STRUCT_PTR                          QH_ptr;
         uint_32                                      next;

         /**************************************************************
          Find the pointer to the next structure to be pointed in the list
         **************************************************************/
         
         switch (EHCI_GET_TYPE(transfer_data_struct_ptr))
         {
      
            case EHCI_ELEMENT_TYPE_ITD:
               ITD_ptr = (EHCI_ITD_STRUCT_PTR)((EHCI_MEM_READ(*transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
               next  = EHCI_MEM_READ(ITD_ptr->NEXT_LINK_PTR);
               break;
            case EHCI_ELEMENT_TYPE_QH:
               QH_ptr = (EHCI_QH_STRUCT_PTR)((EHCI_MEM_READ(*transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
               next = EHCI_MEM_READ(QH_ptr->HORIZ_LINK_PTR);

               break;
            case EHCI_ELEMENT_TYPE_SITD:
               SITD_ptr = (EHCI_SITD_STRUCT_PTR)((EHCI_MEM_READ(*transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
               next = EHCI_MEM_READ(SITD_ptr->NEXT_LINK_PTR);
               break;
               
            case EHCI_ELEMENT_TYPE_FSTN:
               FSTN_ptr = (EHCI_FSTN_STRUCT_PTR)((EHCI_MEM_READ(*transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
               next = EHCI_MEM_READ(FSTN_ptr->NORMAL_PATH_LINK_PTR);
               break;
            default:
               break;
         }
         

          /**************************************************************
            Assign the previous to new one
          **************************************************************/
         if(prev_transfer_data_struct_ptr != transfer_data_struct_ptr)
         {
               switch (EHCI_GET_TYPE(prev_transfer_data_struct_ptr))
               {
      
                  case EHCI_ELEMENT_TYPE_ITD:
                     ITD_ptr = (EHCI_ITD_STRUCT_PTR)((EHCI_MEM_READ(*prev_transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
                     EHCI_MEM_WRITE(ITD_ptr->NEXT_LINK_PTR,next);
                     break;
                  case EHCI_ELEMENT_TYPE_QH:
                     QH_ptr = (EHCI_QH_STRUCT_PTR)((EHCI_MEM_READ(*prev_transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
                     EHCI_MEM_WRITE(QH_ptr->HORIZ_LINK_PTR,next);

                     break;
                  case EHCI_ELEMENT_TYPE_SITD:
                     SITD_ptr = (EHCI_SITD_STRUCT_PTR)((EHCI_MEM_READ(*prev_transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
                     EHCI_MEM_WRITE(SITD_ptr->NEXT_LINK_PTR,next);
                     break;
               
                  case EHCI_ELEMENT_TYPE_FSTN:
                     FSTN_ptr = (EHCI_FSTN_STRUCT_PTR)((EHCI_MEM_READ(*prev_transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
                     EHCI_MEM_WRITE(FSTN_ptr->NORMAL_PATH_LINK_PTR,next);
                     break;
                  default:
                     break;
               }
           }
           else
           {
                 EHCI_MEM_WRITE(*prev_transfer_data_struct_ptr,next); 
           }
          
          return;
   
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : reclaim_band_width
*  Returned Value : None
*  Comments       :
*        updates the bandwidth list with released time 
*END*-----------------------------------------------------------------*/

void reclaim_band_width(
         /* [IN] the USB Host state structure */
         _usb_host_handle                 handle,
         
        /*Frame number that will get the bandwidth*/
        uint_32                           frame_number,
    
        /*data structure that is releasing the bandwidth */
        USB_Uncached uint_32 _PTR_        transfer_data_struct_ptr,
        
        /* The pipe descriptor to queue */            
        EHCI_PIPE_STRUCT_PTR              pipe_descr_ptr
    
)
{
      USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
      EHCI_ITD_STRUCT_PTR                          ITD_ptr;
      EHCI_SITD_STRUCT_PTR                         SITD_ptr;
      EHCI_FSTN_STRUCT_PTR                         FSTN_ptr;
      EHCI_QH_STRUCT_PTR                           QH_ptr;
      uint_32                                      time_for_action,uframe_index;
      uint_8_ptr                                   frame_list_bw_ptr;

      
      usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
      frame_list_bw_ptr = usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR;

      /**************************************************************
       Find the pointer to the next structure to be pointed in the list
      **************************************************************/
      
      switch (EHCI_GET_TYPE(transfer_data_struct_ptr))
      {
   
         case EHCI_ELEMENT_TYPE_ITD:
            ITD_ptr = (EHCI_ITD_STRUCT_PTR)((EHCI_MEM_READ(*transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK); 
            break;
         case EHCI_ELEMENT_TYPE_QH:
            QH_ptr = (EHCI_QH_STRUCT_PTR)((EHCI_MEM_READ(*transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
            time_for_action =  pipe_descr_ptr->BWIDTH;
            
            if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH){
               uframe_index = frame_number % 8;
               if (pipe_descr_ptr->BWIDTH_SLOTS[uframe_index]) {
                  frame_list_bw_ptr[frame_number] -= time_for_action;
               }
            }
            else {
               for (uframe_index = 0; uframe_index < 8; uframe_index++) {
                  /* if bandwidth is allocated in this microframe subtract (free) it */
                  if (pipe_descr_ptr->BWIDTH_SLOTS[uframe_index]) {
                      frame_list_bw_ptr[8 * frame_number + uframe_index] -= time_for_action; 
                  }
               }
            }
            break;
         case EHCI_ELEMENT_TYPE_SITD:
            SITD_ptr = (EHCI_SITD_STRUCT_PTR)((EHCI_MEM_READ(*transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
            break;
         case EHCI_ELEMENT_TYPE_FSTN:
            FSTN_ptr = (EHCI_FSTN_STRUCT_PTR)((EHCI_MEM_READ(*transfer_data_struct_ptr)) & EHCI_HORIZ_PHY_ADDRESS_MASK);
            break;
         default:
            break;
      }
      
   
      return;
}



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : allocate_ss_cs_bandwidth
*  Returned Value : None
*  Comments       :
*  Allocates the slots for scheduling split transactions on this pipe. 
*END*-----------------------------------------------------------------*/

static uint_32 allocate_ss_cs_bandwidth (

     /* [IN] the USB Host state structure */
        _usb_host_handle                  handle,

     /* [IN] The pipe descriptor to queue */            
        EHCI_PIPE_STRUCT_PTR              pipe_descr_ptr,
         
        /*Number of slots required by this pipe*/
        uint_32                           slots_asked,
        
        /* starting slot out of 8 */
        uint_32                           start_slot,
    
        /* ending slot out of 8 */
        uint_32                           end_slot
    
)
{
   uint_8  microframes[8] = {0,0,0,0,0,0,0,0};
   
   /**********************************************************
   Generate all start split combinations for this pipe and
   check the bandwidth allocation for each of them. If this
   fails return bandwidth alloctaion failed. Notice that by
   nature of the work, this is time consuming part of the code
   because of several combinations available and huge
   periodic list to iterate through to find if a combination
   is available. If it is not, we go to the next one.In general
   this code will take time when more devices are plugged in.
   *************************************************************/
   return split_combinations(handle,
                      pipe_descr_ptr,
                      microframes,
                      (int)start_slot,
                      (int)end_slot,
                      1,
                      (int)slots_asked);
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : split_combinations
*  Returned Value : None
*  Comments       :
*  Finds all combinations for k elements from a set of n elements format. 
*END*-----------------------------------------------------------------*/

static uint_32 split_combinations (

     /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

     /* [IN] The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR             pipe_descr_ptr,
         
     /* [IN] Array to use to generate combinations */            
      uint_8   v[], 
      
     /* generate combinations starting from */            
      int start, 

     /* generate combinations until */            
      int n, 

     /* counter start until maxk combinations are generated */ 
      int k, 

     /* Each combination is how many elements */            
      int maxk) 

{
        int i;
        uint_32 frame_number;
        uint_32                             status = USB_OK;
        USB_EHCI_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;


/*        uint_8  ss[8] = {0,0,0,0,0,0,0,0}; array which holds the combination */

        /* k here counts through positions in the maxk-element v.
         * if k > maxk, then the v is complete and we can use it.
         */
        if (k > maxk) 
        {
                  /* fill up the SS array with the combination found 
                   for (i=1; i<=maxk; i++)  
                   {
                     ss[v[i]] = 1; set 1 at the microframe which needs to be used.
                   }
                   */

                   /* we found a combination so we now check if this is
                     available in periodic list if bandwidth is not already allocated.*/
                     if(pipe_descr_ptr->BWIDTH <= 0)
                     {
                           frame_number =0;
                                         
                           do
                           {
                              status = _usb_ehci_commit_bandwidth_slots(handle,
                                                                        pipe_descr_ptr, 
                                                                        frame_number,
                                                                        pipe_descr_ptr->G.INTERVAL,
                                                                        v, /*combination to try*/
                                                                        (uint_32)maxk /*number of SS slots */
                                                                        );
      
                              if(status != USBERR_BANDWIDTH_ALLOC_FAILED)
                              {

                                 /***************************************************************************
                                 Slot allocation was either successful or there was some other error.
                                 ****************************************************************************/
                                 return status;
                              }
      
                              frame_number++;   
                           } while ((frame_number < pipe_descr_ptr->G.INTERVAL) | (frame_number < usb_host_ptr->FRAME_LIST_SIZE));

                     }
                
        }

        /* for this k'th element of the v, try all start..n
         * elements in that position
         */
        for (i=start; i<=n; i++) {

                v[k] = (uint_8)i;

                /* recursively generate combinations of integers
                 * from i+1..n
                 */
                split_combinations (handle,pipe_descr_ptr,v, i+1, n, k+1, maxk);
        }
        
        
        return status;
}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/bsp.h<|end_filename|>
/**HEADER***********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
********************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************
*
* $FileName: bsp.h$
* $Version : 3.8.2.0$
* $Date    : Aug-20-2012$
*
* Comments:
*
*   This file includes all include files specific to this target system.
*
*END***************************************************************************/

#ifndef __bsp_h__
#define __bsp_h__   1

#include <app_types.h>
#include <psp.h>

/* Processor Expert files */
#include <PE_LDD.h>
#ifdef PE_LDD_VERSION
#include <Events.h>
#endif

#include <bsp_rev.h>
#include <INV1_K60F120.h>

/* Clock manager */
#include <cm_kinetis.h>
#include <bsp_cm.h>
#include <cm.h>
/* Low power manager*/
#include <init_lpm.h>
#include <lpm_kinetis.h>
#include <lpm.h>

#include <fio.h>
#include <io.h>
#include <serial.h>
#include <serl_kuart.h>
#include <spi.h>
#include <spi_dspi.h>
#include <i2c.h>
#include <i2c_ki2c.h>
#include <io_mem.h>
#include <io_null.h>
#include <enet.h>
#include <macnet_mk60.h>
#include <lwgpio_kgpio.h>
#include <lwgpio.h>
#include <io_gpio.h>
#include <esdhc.h>
#include <sdcard.h>
#include <sdcard_spi.h>
#include <sdcard_esdhc.h>
#include <iodebug.h>
#include <apccard.h>
#include <pccardflexbus.h>
#include <pcflash.h>
#include <adc_mk60.h>
#include <adc.h>
#include <adc_kadc.h>
#include <kinetis_fcan.h>
#include <kflexcan.h>
#include <flashx.h>
#include <flash_ftfe.h>
#include <flash_mk60.h>
#include <krtc.h>
#include <krtc_ext.h>
#include <rtc.h>
#include <nandflash.h>
#include <usb_dcd.h>
#include <usb_dcd_kn.h>
#include <usb_dcd_kn_prv.h>
#include <tchres.h>
#include <timer_lpt.h>
#include <timer_qpit.h>
#include <usb_bsp.h>
#include <sai.h>
#include <sai_ksai.h>

#ifdef __cplusplus
extern "C" {
#endif

_mqx_int _bsp_chip_pins_init(void);
_mqx_int _bsp_adc_io_init(_mqx_uint adc_num);
_mqx_int _bsp_adc_channel_io_init(uint_16 source);
_mqx_int _bsp_dspi_io_init(uint_32 dev_num);
_mqx_int _bsp_flexcan_io_init (uint_8);
_mqx_int _bsp_i2c_io_init( uint_32 );
_mqx_int _bsp_gpio_io_init( void );
_mqx_int _bsp_esdhc_io_init (uint_8, uint_16);
_mqx_int _bsp_rtc_io_init( void );
_mqx_int _bsp_serial_io_init(uint_8 dev_num,  uint_8 flags);
_mqx_int _bsp_serial_rts_init( uint_32 );
_mqx_int _bsp_usb_host_io_init(struct usb_host_if_struct *);
_mqx_int _bsp_usb_dev_io_init(struct usb_dev_if_struct *);
_mqx_int _bsp_enet_io_init(_mqx_uint);
boolean  _bsp_get_mac_address(uint_32,uint_32,_enet_address);
_mqx_int _bsp_nandflash_io_init(void);
_mqx_int _bsp_ftfx_io_init(_mqx_uint);
_mqx_int _bsp_sai_io_init(uint_32);

extern const SDCARD_INIT_STRUCT _bsp_sdcard0_init;
extern const LPM_CPU_OPERATION_MODE LPM_CPU_OPERATION_MODES[];

#define _bsp_int_init(num, prior, subprior, enable)     _nvic_int_init(num, prior, enable)
#define _bsp_int_enable(num)                            _nvic_int_enable(num)
#define _bsp_int_disable(num)                           _nvic_int_disable(num)

#ifdef __cplusplus
}
#endif

#endif  /* _bsp_h_ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/mqxa/pcbmqxav.h<|end_filename|>
#ifndef __pcbmqxav_h__
#define __pcbmqxav_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pcbmqxav.h$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the private definitions for the MQX packet format
*   PCB packet drivers operating on serial async drivers.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                          CONSTANT DECLARATIONS
*/

#define IO_PCB_MQXA_STACK_SIZE   (750 * sizeof(_mem_size))

/* IO PROTOCOL DEFINITIONS */

#define AP_SYNC            (0x7e)

#define AP_STATE_SYNC         (1)
#define AP_STATE_SYNC_SKIP    (2)
#define AP_STATE_READING      (3)
#define AP_STATE_DONE         (4)
#define AP_STATE_CS0          (5)
#define AP_STATE_CS1          (6)

/* OUTPUT STATES */
#define AP_CRC_NONE           (0)
#define AP_CRC_0              (1)
#define AP_CRC_1              (2)

/*
** The following macro is used to calculate the checksums
*/
#if (PSP_MEMORY_ADDRESSING_CAPABILITY != 8)
   #define AP_CHECKSUM(c, cs0, cs1) \
      cs0 = (cs0 + (c)) & 0xFF; cs1 = ((cs1) + (cs0)) & 0xFF
#else
   #define AP_CHECKSUM(c, cs0, cs1) \
      cs0 += (c); cs1 += (cs0)
#endif

#define IO_PCB_MQXA_CNTL_OFFSET \
   (FIELD_OFFSET(IO_PCB_MQXA_PACKET_HEADER_STRUCT, CONTROL))

#define PKTIZE(data_ptr) ((IO_PCB_MQXA_PACKET_HEADER_STRUCT_PTR)(data_ptr))

#define MQXA_MSG_CONTROL_OFFSET  (6)
#define MQXA_MSG_LENGTH_OFFSET   (0)

#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
#define GET_LENGTH(data_ptr) \
   ( IO_PCB_MQX_MUST_CONVERT_HDR_ENDIAN( ((uchar_ptr)(data_ptr))[MQXA_MSG_CONTROL_OFFSET] ) \
     ? \
     ((((uchar_ptr)(data_ptr))[MQXA_MSG_LENGTH_OFFSET]) & 0xFF) | \
     (((((uchar_ptr)(data_ptr))[MQXA_MSG_LENGTH_OFFSET+1]) & 0xFF) << 8) \
     : \
     ((((uchar_ptr)(data_ptr))[MQXA_MSG_LENGTH_OFFSET+1]) & 0xFF) | \
     (((((uchar_ptr)(data_ptr))[MQXA_MSG_LENGTH_OFFSET]) & 0xFF) << 8) \
   )
#else
#define GET_LENGTH(data_ptr) \
   ( IO_PCB_MQX_MUST_CONVERT_HDR_ENDIAN( ((uchar_ptr)(data_ptr))[MQXA_MSG_CONTROL_OFFSET] ) \
     ? \
     ((((uchar_ptr)(data_ptr))[MQXA_MSG_LENGTH_OFFSET+1]) & 0xFF) | \
     (((((uchar_ptr)(data_ptr))[MQXA_MSG_LENGTH_OFFSET]) & 0xFF) << 8) \
     : \
     ((((uchar_ptr)(data_ptr))[MQXA_MSG_LENGTH_OFFSET]) & 0xFF) | \
     (((((uchar_ptr)(data_ptr))[MQXA_MSG_LENGTH_OFFSET+1]) & 0xFF) << 8) \
   )
#endif

/*--------------------------------------------------------------------------*/
/*
**                          DATATYPE DECLARATIONS
*/

/*
** IO_PCB_MQXA_INFO_STRUCT
** This structure contains standard Bspio protocol information
**
*/
typedef struct io_pcb_mqxa_info_struct
{

   /* Serial ASYNC IO port to use */
   MQX_FILE_PTR    FD;

   /* Tasks created */
   _task_id        INPUT_TASK;
   _task_id        OUTPUT_TASK;
   
   /*  INPUT DEFINITIONS */
   LWSEM_STRUCT    READ_LWSEM;
   QUEUE_STRUCT    READ_QUEUE;
   
   /* Start CR 398 */
   MQX_FILE_PTR    CALLBACK_FD;/* CALLBACK File descriptor to use */
   /* End CR */
    void (_CODE_PTR_ READ_CALLBACK_FUNCTION)(FILE_DEVICE_STRUCT_PTR, 
      IO_PCB_STRUCT_PTR);
   _io_pcb_pool_id READ_PCB_POOL;
 
   /* OUTPUT DEFINITIONS */
   LWSEM_STRUCT    WRITE_LWSEM;
   QUEUE_STRUCT    WRITE_QUEUE;

   /* STATISTICAL INFORMATION */
   _mqx_uint       RX_PACKETS;
   _mqx_uint       RX_PACKETS_TOO_LONG;
   _mqx_uint       RX_PACKETS_BAD_CRC;
   _mqx_uint       RX_PACKETS_NO_MEMORY;
   _mqx_uint       TX_PACKETS;

   /* A copy of the initialization info */
   IO_PCB_MQXA_INIT_STRUCT INIT;

} IO_PCB_MQXA_INFO_STRUCT, _PTR_ IO_PCB_MQXA_INFO_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                          C PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILER__
extern _mqx_int _io_pcb_mqxa_open(FILE_DEVICE_STRUCT_PTR, char _PTR_, char _PTR_);
extern _mqx_int _io_pcb_mqxa_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_pcb_mqxa_read(FILE_DEVICE_STRUCT_PTR, IO_PCB_STRUCT_PTR _PTR_);
extern _mqx_int _io_pcb_mqxa_write(FILE_DEVICE_STRUCT_PTR, IO_PCB_STRUCT_PTR);
extern _mqx_int _io_pcb_mqxa_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);
extern _mqx_int _io_pcb_mqxa_uninstall(IO_PCB_DEVICE_STRUCT_PTR);

extern void _io_pcb_mqxa_read_task(uint_32);
extern void _io_pcb_mqxa_write_task(uint_32);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/aes.h<|end_filename|>
#ifndef __AES_H
  #define __AES_H


  #define KEY_COUNT 3

extern void aesInit(void);
extern void aesDecrypt(unsigned char *buffer, unsigned char *chainBlock);

#endif



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/icmp6_prv.h<|end_filename|>
#ifndef __icmp6_prv_h__
#define __icmp6_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: icmp6_prv.h$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Private definitions for the ICMP6 protocol layer.
*
*END************************************************************************/

#include "icmp6.h"
#include "ip6_prv.h"     /* For IP_HEADER */

#if RTCSCFG_ENABLE_ICMP6_STATS 
   #define IF_ICMP6_STATS_ENABLED(x) x
#else
   #define IF_ICMP6_STATS_ENABLED(x)
#endif

/***********************************************************************
*
* Type definitions
*
***********************************************************************/

/***********************************************************************
 * Generic ICMP packet header
 ***********************************************************************
 *
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |     Type      |     Code      |          Checksum             |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                                                               |
 * +                         Message Body                          +
 * |                                                               |
 *
 ***********************************************************************/      
typedef struct icmp6_header
{
   uchar    TYPE[1];
   uchar    CODE[1];
   uchar    CHECKSUM[2];
} ICMP6_HEADER, _PTR_ ICMP6_HEADER_PTR;


/***********************************************************************
 * ICMPv6 Echo packet
 ***********************************************************************
 * RFC4443 4:
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |    Type       |       Code    |             Checksum          |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |             Identifier        |       Sequence Number         |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * | Data ...
 * +-+-+-+-+- 
 ***********************************************************************/
typedef struct icmp6_echo_header
{
   ICMP6_HEADER HEAD;
   uchar       ID[2];
   uchar       SEQ[2];
} ICMP6_ECHO_HEADER, _PTR_ ICMP6_ECHO_HEADER_PTR;

/***********************************************************************
 * ICMPv6 Error packet
 ***********************************************************************/
typedef struct icmp6_err_header
{
   ICMP6_HEADER HEAD;
   uchar        DATA[4];
} ICMP6_ERR_HEADER, _PTR_ ICMP6_ERR_HEADER_PTR;

/***********************************************************************
 * ICMP Configuration.  This information is persistent for the ICMP layer.
 ***********************************************************************/
typedef struct icmp6_cfg_struct
{
#if RTCSCFG_ENABLE_ICMP6_STATS 
   ICMP6_STATS      STATS;
#endif
   ICMP6_PARM_PTR   ECHO_PARM_HEAD;
   uint_16          ECHO_SEQ;
   uint_16          RESERVED;
} ICMP6_CFG_STRUCT, _PTR_ ICMP6_CFG_STRUCT_PTR;

/*
* Error messages are identified as such by a
* zero in the high-order bit of their message Type field values. Thus,
* error messages have message types from 0 to 127; informational
* messages have message types from 128 to 255.
*/
#define ICMP6_TYPE_IS_ERROR(t) (((t) & 0x80) == 0x00)

#endif /* __icmp6_prv_h__ */




<|start_filename|>Firmware/Inverter_firmware/shell/source/mqx/sh_pause.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_pause.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include <fio.h>
#include "shell.h"


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_pause
*  Returned Value:  none
*  Comments  :  SHELL utility to pause the shell for specified time
*
*END*-----------------------------------------------------------------*/

int_32  Shell_pause(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;
   uint_32              pause=10*60*1000;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc == 1)  {
         printf("Pausing for 5 minutes...\n");
        _time_delay(5*60*1000);
          printf("Done\n");
      } else if (argc==2) {
         if (!Shell_parse_uint_32(argv[1], &pause  )) {
            printf("Error, invalid rule priority\n");
            return_code = SHELL_EXIT_ERROR;
         }
          printf("Pausing for %d minutes...\n",pause);
          _time_delay(pause*60*1000);
          printf("Done\n");
      } else {
         printf("Error, %s invoked with incorrect number of arguments\n", argv[0]);
         return_code = SHELL_EXIT_ERROR;
         print_usage = TRUE;
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s [<minutes>]\n", argv[0]);
      } else  {
         printf("Usage: %s <minutes>\n", argv[0]);
         printf("   <minutes>   = minutes to pause for\n");
      }
   }
   return return_code;
} /* Endbody */



/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mcf51qm.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mcf51qm.h$
* $Version : 3.8.2.1$
* $Date    : Jul-19-2012$
*
* Comments:
*
*   The file contains functions prototype, defines for the internal 
*   flash driver.
*
*END************************************************************************/

#ifndef __flash_mcf51qm_h__
#define __flash_mcf51qm_h__

/* FlexNVM partition code values */
#define FLEXNVM_PART_CODE_DATA32_EE0        (0)
#define FLEXNVM_PART_CODE_DATA24_EE8        (1)
#define FLEXNVM_PART_CODE_DATA16_EE16       (2)
#define FLEXNVM_PART_CODE_DATA8_EE24        (9)
#define FLEXNVM_PART_CODE_DATA0_EE32        (3)
#define FLEXNVM_PART_CODE_NOPART            (0x0f)

/* FlexNVM EEPROM size values */
#define FLEXNVM_EE_SIZE_2048                (3)
#define FLEXNVM_EE_SIZE_1024                (4)
#define FLEXNVM_EE_SIZE_512                 (5)
#define FLEXNVM_EE_SIZE_256                 (6)
#define FLEXNVM_EE_SIZE_128                 (7)
#define FLEXNVM_EE_SIZE_64                  (8)
#define FLEXNVM_EE_SIZE_32                  (9)
#define FLEXNVM_EE_SIZE_0                   (0x0f)

/* FlexNVM EEPROM Data Size Code 5:4 bits (FCCOB4[5:4]) */
#define FLEXNVM_EE_SPLIT                    (0x30)

/*----------------------------------------------------------------------*/
/*
** FUNCTION PROTOTYPES
*/
#ifdef __cplusplus
extern "C" {
#endif

pointer _bsp_get_ftfl_address(void);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_bootloader/BSP/PIT.c<|end_filename|>
#include "app_types.h"
#include <MK60F15.h>
#include "app_cfg.h"


volatile INT32U  g_1ms_cnt;
volatile INT32U led_cnt;
//-------------------------------------------------------------------------------------------------------
//  Periodic interrupt timer 0 initialisation
//   
//  period - задается в мкс
//-------------------------------------------------------------------------------------------------------
void PIT0_init(unsigned int period )
{
  SIM_MemMapPtr SIM = SIM_BASE_PTR;
  PIT_MemMapPtr PIT = PIT_BASE_PTR;

  /* Timer 0.1ms */
  PIT->CHANNEL[0].LDVAL = (PERIPH_CLOCK/(1000000u))*period;

  PIT->CHANNEL[0].TFLG = BIT(0); // Сбросит флаг прерывания 

  PIT->CHANNEL[0].TCTRL  = 0
              + LSHIFT(0x01, 1) // TIE | Timer Interrupt Enable Bit.| 1 Interrupt will be requested whenever TIF is set.
              + LSHIFT(0x01, 0) // TEN | Timer Enable Bit.          | 1 Timer n is active.
  ;

  Set_VIC_chanel(INT_PIT0, 2, 0);
}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void PIT0_int_enable(void)
{
  PIT_MemMapPtr PIT = PIT_BASE_PTR;

  PIT->CHANNEL[0].TCTRL  = 0
              + LSHIFT(0x01, 1) // TIE | Timer Interrupt Enable Bit.| 1 Interrupt will be requested whenever TIF is set.
              + LSHIFT(0x01, 0) // TEN | Timer Enable Bit.          | 1 Timer n is active.
  ;
  return;
}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void PIT0_int_disable(void)
{
  PIT_MemMapPtr PIT = PIT_BASE_PTR;

  PIT->CHANNEL[0].TCTRL  = 0
              + LSHIFT(0x00, 1) // TIE | Timer Interrupt Enable Bit.| 
              + LSHIFT(0x00, 0) // TEN | Timer Enable Bit.          | 
  ;
  PIT->CHANNEL[0].TFLG = BIT(0); // Сбросит флаг прерывания 
  return;
}


//-------------------------------------------------------------------------------------------------------
//  Periodic interrupt timer 0 initialisation
//   
//  period - задается в мкс
//-------------------------------------------------------------------------------------------------------
void PIT1_init(unsigned int period )
{
  SIM_MemMapPtr SIM = SIM_BASE_PTR;
  PIT_MemMapPtr PIT = PIT_BASE_PTR;

  /* Timer 0.1ms */
  PIT->CHANNEL[1].LDVAL = (PERIPH_CLOCK/(1000000u))*period;

  PIT->CHANNEL[1].TFLG = BIT(0); // Сбросит флаг прерывания 

  PIT->CHANNEL[1].TCTRL  = 0
              + LSHIFT(0x01, 1) // TIE | Timer Interrupt Enable Bit.| 1 Interrupt will be requested whenever TIF is set.
              + LSHIFT(0x01, 0) // TEN | Timer Enable Bit.          | 1 Timer n is active.
  ;

  Set_VIC_chanel(INT_PIT1, 0, 0);
}


//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void PIT1_IRQHandler(void)
{
  PIT_MemMapPtr PIT = PIT_BASE_PTR;


  if ( PIT->CHANNEL[1].TFLG & BIT(0) )
  {
    
    PIT->CHANNEL[1].TFLG = BIT(0); // Сбросит флаг прерывания 
    
    g_1ms_cnt++;

    led_cnt++;
    if ( led_cnt> 100 )
    {
      Led_control(1, Led_state(1));
      led_cnt = 0;
    }

  }
}


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/rtos/mqx/mqx_dll.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mqx_dll.c$
* $Version : 3.8.3.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for the doubly-linked list library.
*
*END************************************************************************/

#include "mqx_dll.h"

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_node_init
* Returned Value   : void
* Comments         :
*    Constructor for MQX_DLL_NODE structures.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_node_init
(
   MQX_DLL_NODE_PTR node_ptr
)
{
   /* nodes not on a list must not point to nodes on a list */
   node_ptr->next_ptr = 0;
   node_ptr->prev_ptr = 0;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_list_init
* Returned Value   : void
* Comments         :
*    Constructor for MQX_DLL_LIST structures.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_list_init
(
   MQX_DLL_LIST_PTR list_ptr
)
{
   /* empty lists do not point to any nodes */
   list_ptr->head_ptr = 0;
   list_ptr->tail_ptr = 0;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_insert_at_head
* Returned Value   : void
* Comments         :
*    Given a list and a node, insert the node at the head of the list.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_insert_at_head
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr
)
{
   /* is list empty? */
   if (list_ptr->head_ptr != 0)
   {
      node_ptr->next_ptr = list_ptr->head_ptr;
      list_ptr->head_ptr->prev_ptr = node_ptr;
   }
   else
   {
      list_ptr->tail_ptr = node_ptr;
   }

   /* no need to zero node_ptr->prev_ptr here */
   list_ptr->head_ptr = node_ptr;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_insert_at_tail
* Returned Value   : void
* Comments         :
*    Given a list and a node, insert the node at the tail of the list.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_insert_at_tail
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr
)
{
   /* is list empty? */
   if (list_ptr->tail_ptr != 0)
   {
      node_ptr->prev_ptr = list_ptr->tail_ptr;
      list_ptr->tail_ptr->next_ptr = node_ptr;
   }
   else
   {
      list_ptr->head_ptr = node_ptr;
   }

   /* no need to zero node_ptr->next_ptr here */   
   list_ptr->tail_ptr = node_ptr;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_insert_after_node
* Returned Value   : void
* Comments         :
*    Given a list, a reference node on the list, and a node to insert, insert
* the node after the reference node.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_insert_after_node
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr,
   MQX_DLL_NODE_PTR next_ptr
)
{
   /* is node_ptr at the tail? */
   if (node_ptr->next_ptr != 0)
   {
      next_ptr->next_ptr = node_ptr->next_ptr;
      node_ptr->next_ptr->prev_ptr = next_ptr;
   }
   else
   {
      /* no need to zero next_ptr->next_ptr here */
      list_ptr->tail_ptr = next_ptr;
   }
   
   node_ptr->next_ptr = next_ptr;
   next_ptr->prev_ptr = node_ptr;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_insert_before_node
* Returned Value   : void
* Comments         :
*    Given a list, a reference node on the list, and a node to insert, insert
* the node before the reference node.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_insert_before_node
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr,
   MQX_DLL_NODE_PTR prev_ptr
)
{
   /* is node_ptr at the head? */
   if (node_ptr->prev_ptr != 0)
   {
      prev_ptr->prev_ptr = node_ptr->prev_ptr;
      node_ptr->prev_ptr->next_ptr = prev_ptr;
   }
   else
   {
      /* no need to zero prev_ptr->prev_ptr here */
      list_ptr->head_ptr = prev_ptr;
   }
   
   node_ptr->prev_ptr = prev_ptr;
   prev_ptr->next_ptr = node_ptr;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_remove_node
* Returned Value   : void
* Comments         :
*    Given a list and a node on the list, remove the node from the list.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_remove_node
(
   MQX_DLL_LIST_PTR list_ptr,
   MQX_DLL_NODE_PTR node_ptr
)
{
   /* is the node at the tail? */
   if (node_ptr->next_ptr == 0)
   {
      list_ptr->tail_ptr = node_ptr->prev_ptr;
   }
   else
   {
      node_ptr->next_ptr->prev_ptr = node_ptr->prev_ptr;
   }
   
   /* is the node at the head? */
   if (node_ptr->prev_ptr == 0)
   {
      list_ptr->head_ptr = node_ptr->next_ptr;
   }
   else
   {
      node_ptr->prev_ptr->next_ptr = node_ptr->next_ptr;
   }
   
   /* nodes not on a list must not point to nodes on a list */
   node_ptr->next_ptr = 0;
   node_ptr->prev_ptr = 0;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_create_sublist
* Returned Value   : void
* Comments         :
*    Given a list and a range of consecutive nodes on the list, remove all
* nodes within the range (inclusive) and place them on a new list.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_create_sublist
(
   MQX_DLL_LIST_PTR  list_ptr,
   MQX_DLL_NODE_PTR  sublist_head_ptr,    /* must not be null */
   MQX_DLL_NODE_PTR  sublist_tail_ptr,    /* must not be null */
   MQX_DLL_LIST_PTR  sublist_ptr          /* output */
)
{
   /* create the sublist */
   sublist_ptr->head_ptr = sublist_head_ptr;
   sublist_ptr->tail_ptr = sublist_tail_ptr;
   
   /* update the head pointer if needed */
   if (sublist_head_ptr == list_ptr->head_ptr)
   {
      list_ptr->head_ptr = sublist_tail_ptr->next_ptr;
      
      if (list_ptr->head_ptr != 0)
      {
         list_ptr->head_ptr->prev_ptr = 0;
         sublist_tail_ptr->next_ptr = 0;
      }
      else
      {
         /* update the tail pointer */
         list_ptr->tail_ptr = 0;
      }
   }
   else
   {
      if (sublist_tail_ptr->next_ptr == 0)
      {
         /* update the tail pointer */
         list_ptr->tail_ptr = sublist_head_ptr->prev_ptr;
         list_ptr->tail_ptr->next_ptr = 0;
      }
      else
      {
         /* update the head node's previous pointer */
         sublist_tail_ptr->next_ptr->prev_ptr = sublist_head_ptr->prev_ptr;
         sublist_head_ptr->prev_ptr->next_ptr = sublist_tail_ptr->next_ptr;
         
         sublist_tail_ptr->next_ptr = 0;
      }
      
      sublist_head_ptr->prev_ptr = 0;
   }
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_insert_sublist_at_tail
* Returned Value   : void
* Comments         :
*    Given a list and a sublist, remove all nodes on the sublist and insert
* them at the tail of the list.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_insert_sublist_at_tail
(
   MQX_DLL_LIST_PTR  sublist_ptr,
   MQX_DLL_LIST_PTR  list_ptr
)
{
   if (list_ptr->tail_ptr == 0)
   {
      list_ptr->head_ptr = sublist_ptr->head_ptr;
   }
   else
   {
      list_ptr->tail_ptr->next_ptr = sublist_ptr->head_ptr;
      sublist_ptr->head_ptr->prev_ptr = list_ptr->tail_ptr;
   }
   
   list_ptr->tail_ptr = sublist_ptr->tail_ptr;
   
   sublist_ptr->tail_ptr = 0;
   sublist_ptr->head_ptr = 0;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _mqx_dll_insert_sublist_at_head
* Returned Value   : void
* Comments         :
*    Given a list and a sublist, remove all nodes on the sublist and insert
* them at the head of the list.
*
*END*----------------------------------------------------------------------*/
void _mqx_dll_insert_sublist_at_head
(
   MQX_DLL_LIST_PTR  sublist_ptr,
   MQX_DLL_LIST_PTR  list_ptr
)
{
   if (list_ptr->head_ptr == 0)
   {
      list_ptr->tail_ptr = sublist_ptr->tail_ptr;
   }
   else
   {
      list_ptr->head_ptr->prev_ptr = sublist_ptr->tail_ptr;
      sublist_ptr->tail_ptr->next_ptr = list_ptr->head_ptr;
   }
   
   list_ptr->head_ptr = sublist_ptr->head_ptr;
   
   sublist_ptr->tail_ptr = 0;
   sublist_ptr->head_ptr = 0;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GMCLIB/GMCLIB_ElimDcBusRip.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GMCLIB_ElimDcBusRip.h
*
* @author   B04459, R29302
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GMCLIB_ElimDcBusRip function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GMCLIB_ELIMDCBUSRIP_H
#define _GMCLIB_ELIMDCBUSRIP_H

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif


/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GMCLIB_ElimDcBusRipANSIC function.*/
#define GMCLIB_ElimDcBusRip(pOut, pIn, pParams) GMCLIB_ElimDcBusRipANSIC(pOut, pIn, pParams)

/*! Macro containing default values for the parameter structure of the #GMCLIB_ElimDcBusRip
 * function.*/
#define GMCLIB_ELIMDCBUSRIP_DEFAULT   {0,0}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/

/*------------------------------------------------------------------------*//*!
@struct GMCLIB_ELIM_DC_BUS_RIP_T "\GMCLIB_ElimDcBusRip.h"

@brief  Structure containing the PWM modulation index and the measured value of
        the DC bus voltage for calculation of the DC bus ripple elimination.

*//*-------------------------------------------------------------------------*/

typedef struct
{
    Frac32 f32ModIndex;    /*!< Inverse Modulation Index, fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$, must be 0 or positive. */
    Frac32 f32ArgDcBusMsr; /*!< Measured DC bus voltage, fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$, must be 0 or positive. */
} GMCLIB_ELIM_DC_BUS_RIP_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*!
* @ingroup GMCLIB_GROUP
*/
extern void GMCLIB_ElimDcBusRipANSIC(MCLIB_2_COOR_SYST_ALPHA_BETA_T *pOut,
                                     const MCLIB_2_COOR_SYST_ALPHA_BETA_T *const pIn,
                                     const GMCLIB_ELIM_DC_BUS_RIP_T *const pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GMCLIB_ELIMDCBUSRIP_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/ethernet.h<|end_filename|>
#ifndef __ethernet_h__
#define __ethernet_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ethernet.h$
* $Version : 3.8.2.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the defines and data structure definitions that
*   reperesent ethernet packets.
*
*END************************************************************************/



#define ENET_FRAMESIZE_HEAD       sizeof(ENET_HEADER)
#define ENET_FRAMESIZE_HEAD_VLAN  (sizeof(ENET_HEADER)+sizeof(ENET_8021QTAG_HEADER))
#define ENET_FRAMESIZE_MAXDATA    (1500)
#define ENET_FRAMESIZE_MIN        (64)
#define ENET_FRAMESIZE_TAIL       (4)

#define ENET_FRAMESIZE            ENET_FRAMESIZE_HEAD+ENET_FRAMESIZE_MAXDATA+ENET_FRAMESIZE_TAIL
#define ENET_FRAMESIZE_VLAN       ENET_FRAMESIZE_HEAD_VLAN+ENET_FRAMESIZE_MAXDATA+ENET_FRAMESIZE_TAIL

/***************************************
**
** Ethernet protocols
**
*/
#define ENETPROT_LENGTH_TYPE_BOUNDARY ENET_FRAMESIZE_MAXDATA
#define ENETPROT_IP     0x800
#define ENETPROT_ARP    0x806
#define ENETPROT_8021Q  0x8100
#define ENETPROT_IP6    0x86DD


#define ENET_OPT_8023             0x0001
#define ENET_OPT_8021QTAG         0x0002
#define ENET_SETOPT_8021QPRIO(p)  (ENET_OPT_8021QTAG | (((uint_32)(p) & 0x7) << 2))
#define ENET_GETOPT_8021QPRIO(f)  (((f) >> 2) & 0x7)

#define eaddrcpy(p,x)   ((p)[0] = (x)[0], \
                         (p)[1] = (x)[1], \
                         (p)[2] = (x)[2], \
                         (p)[3] = (x)[3], \
                         (p)[4] = (x)[4], \
                         (p)[5] = (x)[5]  \
                        )
                        
#define htone(p,x) eaddrcpy(p,x)

#define ntohe(p,x)   ((x)[0] = (p)[0] & 0xFF, \
                      (x)[1] = (p)[1] & 0xFF, \
                      (x)[2] = (p)[2] & 0xFF, \
                      (x)[3] = (p)[3] & 0xFF, \
                      (x)[4] = (p)[4] & 0xFF, \
                      (x)[5] = (p)[5] & 0xFF  \
                     )
                     

typedef uchar   _enet_address[6];

/*
** Ethernet packet header
*/
typedef struct enet_header {
   _enet_address    DEST;
   _enet_address    SOURCE;
   uchar            TYPE[2];
} ENET_HEADER, _PTR_ ENET_HEADER_PTR;

typedef struct enet_8021qtag_header {
   uchar    TAG[2];
   uchar    TYPE[2];
} ENET_8021QTAG_HEADER, _PTR_ ENET_8021QTAG_HEADER_PTR;

typedef struct enet_8022_header {
   uchar    DSAP[1];
   uchar    SSAP[1];
   uchar    COMMAND[1];
   uchar    OUI[3];
   uchar    TYPE[2];
} ENET_8022_HEADER, _PTR_ ENET_8022_HEADER_PTR;


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/PORT_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type PORT
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(PORT_PDD_H_)
#define PORT_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error PORT PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK10D5) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK10D7) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK10F12) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK10DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK11D5) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK11D5WS) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK12D5) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK20D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK20D5) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK20D7) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK20F12) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK20DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK21D5) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK21D5WS) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK22D5) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK30D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK30D7) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK30DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK40D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK40D7) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK40DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK40X256VMD100) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK50D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK50D7) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK50DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK51D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK51D7) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK51DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK52D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK52DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK53D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK53DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK60D10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK60F12) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK60F15) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK60DZ10) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK60N512VMD100) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MK61F12) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK61F15) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK61F12WS) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK61F15WS) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK70F12) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK70F15) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK70F12WS) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MK70F15WS) /* PORTA, PORTB, PORTC, PORTD, PORTE, PORTF */ && \
      !defined(MCU_MKL02Z4) /* PORTA, PORTB */ && \
      !defined(MCU_MKL04Z4) /* PORTA, PORTB */ && \
      !defined(MCU_MKL05Z4) /* PORTA, PORTB */ && \
      !defined(MCU_MKL14Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MKL15Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MKL16Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MKL24Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MKL25Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MKL26Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MKL34Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MKL36Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_MKL46Z4) /* PORTA, PORTB, PORTC, PORTD, PORTE */ && \
      !defined(MCU_PCK20L4) /* PORTA, PORTB, PORTC, PORTD, PORTE */
  // Unsupported MCU is active
  #error PORT PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Pin masks */
#define PORT_PDD_PIN_0  0x1U                     /**< Pin 0 mask */
#define PORT_PDD_PIN_1  0x2U                     /**< Pin 1 mask */
#define PORT_PDD_PIN_2  0x4U                     /**< Pin 2 mask */
#define PORT_PDD_PIN_3  0x8U                     /**< Pin 3 mask */
#define PORT_PDD_PIN_4  0x10U                    /**< Pin 4 mask */
#define PORT_PDD_PIN_5  0x20U                    /**< Pin 5 mask */
#define PORT_PDD_PIN_6  0x40U                    /**< Pin 6 mask */
#define PORT_PDD_PIN_7  0x80U                    /**< Pin 7 mask */
#define PORT_PDD_PIN_8  0x100U                   /**< Pin 8 mask */
#define PORT_PDD_PIN_9  0x200U                   /**< Pin 9 mask */
#define PORT_PDD_PIN_10 0x400U                   /**< Pin 10 mask */
#define PORT_PDD_PIN_11 0x800U                   /**< Pin 11 mask */
#define PORT_PDD_PIN_12 0x1000U                  /**< Pin 12 mask */
#define PORT_PDD_PIN_13 0x2000U                  /**< Pin 13 mask */
#define PORT_PDD_PIN_14 0x4000U                  /**< Pin 14 mask */
#define PORT_PDD_PIN_15 0x8000U                  /**< Pin 15 mask */
#define PORT_PDD_PIN_16 0x10000U                 /**< Pin 16 mask */
#define PORT_PDD_PIN_17 0x20000U                 /**< Pin 17 mask */
#define PORT_PDD_PIN_18 0x40000U                 /**< Pin 18 mask */
#define PORT_PDD_PIN_19 0x80000U                 /**< Pin 19 mask */
#define PORT_PDD_PIN_20 0x100000U                /**< Pin 20 mask */
#define PORT_PDD_PIN_21 0x200000U                /**< Pin 21 mask */
#define PORT_PDD_PIN_22 0x400000U                /**< Pin 22 mask */
#define PORT_PDD_PIN_23 0x800000U                /**< Pin 23 mask */
#define PORT_PDD_PIN_24 0x1000000U               /**< Pin 24 mask */
#define PORT_PDD_PIN_25 0x2000000U               /**< Pin 25 mask */
#define PORT_PDD_PIN_26 0x4000000U               /**< Pin 26 mask */
#define PORT_PDD_PIN_27 0x8000000U               /**< Pin 27 mask */
#define PORT_PDD_PIN_28 0x10000000U              /**< Pin 28 mask */
#define PORT_PDD_PIN_29 0x20000000U              /**< Pin 29 mask */
#define PORT_PDD_PIN_30 0x40000000U              /**< Pin 30 mask */
#define PORT_PDD_PIN_31 0x80000000U              /**< Pin 31 mask */

/* Constants for pull type selection */
#define PORT_PDD_PULL_DOWN 0U                    /**< Pull down */
#define PORT_PDD_PULL_UP   0x1U                  /**< Pull up */

/* Constants for pull enabling/disabling */
#define PORT_PDD_PULL_DISABLE 0U                 /**< Pull resistor disabled */
#define PORT_PDD_PULL_ENABLE  0x2U               /**< Pull resistor enabled */

/* Constants for slew rate setting */
#define PORT_PDD_SLEW_RATE_FAST 0U               /**< Fast slew rate */
#define PORT_PDD_SLEW_RATE_SLOW 0x4U             /**< Slow slew rate */

/* Constants for slew rate setting */
#define PORT_PDD_PASSIVE_FILTER_DISABLE 0U       /**< Passive filter disabled */
#define PORT_PDD_PASSIVE_FILTER_ENABLE  0x10U    /**< Passive filter enabled */

/* Constants for open drain setting */
#define PORT_PDD_OPEN_DRAIN_DISABLE 0U           /**< Open drain disabled */
#define PORT_PDD_OPEN_DRAIN_ENABLE  0x20U        /**< Open drain enabled */

/* Constants for drive strength setting */
#define PORT_PDD_DRIVE_STRENGTH_LOW  0U          /**< Low drive strength */
#define PORT_PDD_DRIVE_STRENGTH_HIGH 0x40U       /**< High drive strength */

/* Constants for mux control setting */
#define PORT_PDD_MUX_CONTROL_DISABLE 0U          /**< Mux control disabled */
#define PORT_PDD_MUX_CONTROL_ALT1    0x100U      /**< Pin used with alternate 1 functionality */
#define PORT_PDD_MUX_CONTROL_ALT2    0x200U      /**< Pin used with alternate 2 functionality */
#define PORT_PDD_MUX_CONTROL_ALT3    0x300U      /**< Pin used with alternate 3 functionality */
#define PORT_PDD_MUX_CONTROL_ALT4    0x400U      /**< Pin used with alternate 4 functionality */
#define PORT_PDD_MUX_CONTROL_ALT5    0x500U      /**< Pin used with alternate 5 functionality */
#define PORT_PDD_MUX_CONTROL_ALT6    0x600U      /**< Pin used with alternate 6 functionality */
#define PORT_PDD_MUX_CONTROL_ALT7    0x700U      /**< Pin used with alternate 7 functionality */

/* Constants for pin lock setting */
#define PORT_PDD_PIN_CONTROL_UNLOCK 0U           /**< Pin control unlocked */
#define PORT_PDD_PIN_CONTROL_LOCK   0x8000U      /**< Pin control locked */

/* Constants for interrupt configuration setting */
#define PORT_PDD_INTERRUPT_DMA_DISABLED      0U  /**< Interrupt and DMA disabled */
#define PORT_PDD_DMA_ON_RISING               0x10000U /**< DMA enabled on rising edge */
#define PORT_PDD_DMA_ON_FALLING              0x20000U /**< DMA enabled on falling edge */
#define PORT_PDD_DMA_ON_RISING_FALLING       0x30000U /**< DMA enabled on rising and falling edges */
#define PORT_PDD_INTERRUPT_ON_ZERO           0x80000U /**< Interrupt enabled on low level */
#define PORT_PDD_INTERRUPT_ON_RISING         0x90000U /**< Interrupt enabled on rising edge */
#define PORT_PDD_INTERRUPT_ON_FALLING        0xA0000U /**< Interrupt enabled on falling edge */
#define PORT_PDD_INTERRUPT_ON_RISING_FALLING 0xB0000U /**< Interrupt enabled on rising and falling edges */
#define PORT_PDD_INTERRUPT_ON_ONE            0xC0000U /**< Interrupt enabled on high level */

/* Constants for digital clock source setting */
#define PORT_PDD_BUS_CLOCK 0U                    /**< Bus clock as filter clock source */
#define PORT_PDD_LPO_CLOCK 0x1U                  /**< LPO clock as filter clock source */


/* ----------------------------------------------------------------------------
   -- GetPinPullSelect
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets which pull resistor is selected.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for pull type selection" type. The
 *         value is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinPullSelect(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinPullSelect(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_PS_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinPullSelect
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets pull type.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param Type Pull type. This parameter is of "Constants for pull type
 *        selection" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_SetPinPullSelect(deviceID, periphID, PORT_PDD_PULL_DOWN);
 *      @endcode
 */
#define PORT_PDD_SetPinPullSelect(PeripheralBase, PinIndex, Type) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_PS_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(Type))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinPullEnable
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets whether pull resistor is enabled.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for pull enabling/disabling" type. The
 *         value is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinPullEnable(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinPullEnable(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_PE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinPullEnable
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets pull type.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param State Requested state of pull enable. This parameter is of "Constants
 *        for pull enabling/disabling" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_SetPinPullEnable(deviceID, periphID, PORT_PDD_PULL_DISABLE);
 *      @endcode
 */
#define PORT_PDD_SetPinPullEnable(PeripheralBase, PinIndex, State) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_PE_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinSlewRate
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets how slew rate is set.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for slew rate setting" type. The value
 *         is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinSlewRate(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinSlewRate(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_SRE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinSlewRate
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets slew rate.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param State Requested state of slew rate. This parameter is of "Constants
 *        for slew rate setting" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_SetPinSlewRate(deviceID, periphID, PORT_PDD_SLEW_RATE_FAST);
 *      @endcode
 */
#define PORT_PDD_SetPinSlewRate(PeripheralBase, PinIndex, State) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_SRE_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinPassiveFilter
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets whether passive filter is enabled.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for slew rate setting" type. The value
 *         is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinPassiveFilter(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinPassiveFilter(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_PFE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinPassiveFilter
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets passive filter.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param State Requested state of passive filter. This parameter is of
 *        "Constants for slew rate setting" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_SetPinPassiveFilter(deviceID, periphID,
 *      PORT_PDD_PASSIVE_FILTER_DISABLE);
 *      @endcode
 */
#define PORT_PDD_SetPinPassiveFilter(PeripheralBase, PinIndex, State) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_PFE_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinOpenDrain
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets whether open drain is enabled.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for open drain setting" type. The value
 *         is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinOpenDrain(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinOpenDrain(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_ODE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinOpenDrain
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets open drain.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param State Requested state of open drain. This parameter is of "Constants
 *        for open drain setting" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_SetPinOpenDrain(deviceID, periphID,
 *      PORT_PDD_OPEN_DRAIN_DISABLE);
 *      @endcode
 */
#define PORT_PDD_SetPinOpenDrain(PeripheralBase, PinIndex, State) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_ODE_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinDriverStrength
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets how drive strength is set.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for drive strength setting" type. The
 *         value is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinDriverStrength(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinDriverStrength(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_DSE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinDriveStrength
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets drive strength.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param State Requested state of drive strength. This parameter is of
 *        "Constants for drive strength setting" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_SetPinDriveStrength(deviceID, periphID,
 *      PORT_PDD_DRIVE_STRENGTH_LOW);
 *      @endcode
 */
#define PORT_PDD_SetPinDriveStrength(PeripheralBase, PinIndex, State) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_DSE_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinMuxControl
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets how mux control is set.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for mux control setting" type. The
 *         value is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinMuxControl(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinMuxControl(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_MUX_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinMuxControl
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets mux control.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param State Requested state of Mux control. This parameter is of "Constants
 *        for mux control setting" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_SetPinMuxControl(deviceID, periphID,
 *      PORT_PDD_MUX_CONTROL_DISABLE);
 *      @endcode
 */
#define PORT_PDD_SetPinMuxControl(PeripheralBase, PinIndex, State) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_MUX_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinControlLock
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets how pin lock is set.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for pin lock setting" type. The value
 *         is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinControlLock(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinControlLock(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_LK_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- LockPinControl
   ---------------------------------------------------------------------------- */

/**
 * @brief Locks pin control such as settings of pull, slew rate, passive filter,
 * open drain, mux control and pin lock.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param State Requested state of pin lock. This parameter is of "Constants for
 *        pin lock setting" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_LockPinControl(deviceID, periphID,
 *      PORT_PDD_PIN_CONTROL_UNLOCK);
 *      @endcode
 */
#define PORT_PDD_LockPinControl(PeripheralBase, PinIndex, State) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_LK_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinInterruptConfiguration
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets how interupt configuration is set.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of "Constants for interrupt configuration setting"
 *         type. The value is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinInterruptConfiguration(deviceID,
 *      periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinInterruptConfiguration(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_IRQC_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinInterruptConfiguration
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets interrupt configuration.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @param State Requested state of interrupt configuration. This parameter is of
 *        "Constants for interrupt configuration setting" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_SetPinInterruptConfiguration(deviceID, periphID,
 *      PORT_PDD_INTERRUPT_DMA_DISABLED);
 *      @endcode
 */
#define PORT_PDD_SetPinInterruptConfiguration(PeripheralBase, PinIndex, State) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PORT_PCR_REG(PeripheralBase,(PinIndex))) & (( \
       (uint32_t)(~(uint32_t)PORT_PCR_IRQC_MASK)) & ( \
       (uint32_t)(~(uint32_t)PORT_PCR_ISF_MASK))))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPinInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt flags.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetPinInterruptFlag(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_GetPinInterruptFlag(PeripheralBase, PinIndex) ( \
    (uint32_t)(PORT_PCR_REG(PeripheralBase,(PinIndex)) & PORT_PCR_ISF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetInterruptFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt flags.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: PORTA_ISFR, PORTB_ISFR,
 *          PORTC_ISFR, PORTD_ISFR, PORTE_ISFR, PORTF_ISFR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetInterruptFlags(deviceID);
 *      @endcode
 */
#define PORT_PDD_GetInterruptFlags(PeripheralBase) ( \
    PORT_ISFR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ClearPinInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @param PinIndex Pin index inside the port. This parameter is of index type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PCR[PinIndex].
 * @par Example:
 *      @code
 *      PORT_PDD_ClearPinInterruptFlag(deviceID, periphID);
 *      @endcode
 */
#define PORT_PDD_ClearPinInterruptFlag(PeripheralBase, PinIndex) ( \
    PORT_PCR_REG(PeripheralBase,(PinIndex)) |= \
     PORT_PCR_ISF_MASK \
  )

/* ----------------------------------------------------------------------------
   -- ClearInterruptFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears interrupt flag bits defined by mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of pins to clearing theirs interrupt flags. Use constants
 *        from group "Pin masks". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PORTA_ISFR, PORTB_ISFR,
 *          PORTC_ISFR, PORTD_ISFR, PORTE_ISFR, PORTF_ISFR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      PORT_PDD_ClearInterruptFlags(deviceID, PORT_PDD_PIN_0);
 *      @endcode
 */
#define PORT_PDD_ClearInterruptFlags(PeripheralBase, Mask) ( \
    PORT_ISFR_REG(PeripheralBase) = \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- SetGlobalPinControl
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets required pin control for required pins of whole port.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of pins in port where the bit 0 corresponds with the pin
 *        which has index 0 within the port and the bit 31 corresponds with the pin
 *        which has index 31 within the port. This parameter is a 32-bit value.
 * @param Value Settings of pull, slew rate, passive filter, open drain, mux
 *        control and pin lock . This parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PORTA_GPCLR,
 *          PORTA_GPCHR, PORTB_GPCLR, PORTB_GPCHR, PORTC_GPCLR, PORTC_GPCHR, PORTD_GPCLR,
 *          PORTD_GPCHR, PORTE_GPCLR, PORTE_GPCHR, PORTF_GPCLR, PORTF_GPCHR
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      PORT_PDD_SetGlobalPinControl(deviceID, 1, 1);
 *      @endcode
 */
#define PORT_PDD_SetGlobalPinControl(PeripheralBase, Mask, Value) ( \
    (PORT_GPCLR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)((uint32_t)((uint32_t)(Mask) & 0xFFFFU) << PORT_GPCLR_GPWE_SHIFT)) | ( \
      (uint32_t)(Value)))), \
    (PORT_GPCHR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)((uint32_t)(Mask) & (uint32_t)(~(uint32_t)0xFFFFU))) | ( \
      (uint32_t)(Value)))) \
  )

/* ----------------------------------------------------------------------------
   -- SetGlobalPinControlLow
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets required pin control for required pins from low part of port.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of pins in port where the bit 0 corresponds with the pin
 *        which has index 0 within the port and the bit 15 corresponds with the pin
 *        which has index 15 within the port. This parameter is a 16-bit value.
 * @param Value Settings of pull, slew rate, passive filter, open drain, mux
 *        control and pin lock . This parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PORTA_GPCLR,
 *          PORTB_GPCLR, PORTC_GPCLR, PORTD_GPCLR, PORTE_GPCLR, PORTF_GPCLR (depending on
 *          the peripheral).
 * @par Example:
 *      @code
 *      PORT_PDD_SetGlobalPinControlLow(deviceID, 1, 1);
 *      @endcode
 */
#define PORT_PDD_SetGlobalPinControlLow(PeripheralBase, Mask, Value) ( \
    PORT_GPCLR_REG(PeripheralBase) = \
     (uint32_t)((uint32_t)((uint32_t)(Mask) << PORT_GPCLR_GPWE_SHIFT) | (uint32_t)(Value)) \
  )

/* ----------------------------------------------------------------------------
   -- SetGlobalPinControlHigh
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets required pin control for required pins from high part of port.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of pins in port where the bit 0 corresponds with the pin
 *        which has index 16 within the port and the bit 15 corresponds with the pin
 *        which has index 31 within the port. This parameter is a 16-bit value.
 * @param Value Settings of pull, slew rate, passive filter, open drain, mux
 *        control and pin lock . This parameter is a 16-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PORTA_GPCHR,
 *          PORTB_GPCHR, PORTC_GPCHR, PORTD_GPCHR, PORTE_GPCHR, PORTF_GPCHR (depending on
 *          the peripheral).
 * @par Example:
 *      @code
 *      PORT_PDD_SetGlobalPinControlHigh(deviceID, 1, 1);
 *      @endcode
 */
#define PORT_PDD_SetGlobalPinControlHigh(PeripheralBase, Mask, Value) ( \
    PORT_GPCHR_REG(PeripheralBase) = \
     (uint32_t)((uint32_t)((uint32_t)(Mask) << PORT_GPCHR_GPWE_SHIFT) | (uint32_t)(Value)) \
  )

/* ----------------------------------------------------------------------------
   -- GetEnableDigitalFilterStatusMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns enable status of digital filter for whole port.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: PORTA_DFER, PORTB_DFER,
 *          PORTC_DFER, PORTD_DFER, PORTE_DFER, PORTF_DFER (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetEnableDigitalFilterStatusMask(deviceID);
 *      @endcode
 */
#define PORT_PDD_GetEnableDigitalFilterStatusMask(PeripheralBase) ( \
    PORT_DFER_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- EnableDigitalFilters
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables digital filters.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of pins. Use constants from group "Pin masks". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PORTA_DFER, PORTB_DFER,
 *          PORTC_DFER, PORTD_DFER, PORTE_DFER, PORTF_DFER (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      PORT_PDD_EnableDigitalFilters(deviceID, PORT_PDD_PIN_0);
 *      @endcode
 */
#define PORT_PDD_EnableDigitalFilters(PeripheralBase, Mask) ( \
    PORT_DFER_REG(PeripheralBase) |= \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- DisableDigitalFilters
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables digital filters.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of pins. Use constants from group "Pin masks". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PORTA_DFER, PORTB_DFER,
 *          PORTC_DFER, PORTD_DFER, PORTE_DFER, PORTF_DFER (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      PORT_PDD_DisableDigitalFilters(deviceID, PORT_PDD_PIN_0);
 *      @endcode
 */
#define PORT_PDD_DisableDigitalFilters(PeripheralBase, Mask) ( \
    PORT_DFER_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- GetFilterClockSource
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets how filter clock source is set.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of "Constants for digital clock source setting" type.
 *         The value is cast to "uint32_t".
 * @remarks The macro accesses the following registers: PORTA_DFCR, PORTB_DFCR,
 *          PORTC_DFCR, PORTD_DFCR, PORTE_DFCR, PORTF_DFCR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetFilterClockSource(deviceID);
 *      @endcode
 */
#define PORT_PDD_GetFilterClockSource(PeripheralBase) ( \
    (uint32_t)(PORT_DFCR_REG(PeripheralBase) & PORT_DFCR_CS_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetFilterClockSource
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets filter clock source.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of filter clock source. This parameter is of
 *        "Constants for digital clock source setting" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PORTA_DFCR, PORTB_DFCR,
 *          PORTC_DFCR, PORTD_DFCR, PORTE_DFCR, PORTF_DFCR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      PORT_PDD_SetFilterClockSource(deviceID, PORT_PDD_BUS_CLOCK);
 *      @endcode
 */
#define PORT_PDD_SetFilterClockSource(PeripheralBase, State) ( \
    PORT_DFCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(PORT_DFCR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)PORT_DFCR_CS_MASK))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetFilterLength
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns filter length in clock cycles.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: PORTA_DFWR, PORTB_DFWR,
 *          PORTC_DFWR, PORTD_DFWR, PORTE_DFWR, PORTF_DFWR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = PORT_PDD_GetFilterLength(deviceID);
 *      @endcode
 */
#define PORT_PDD_GetFilterLength(PeripheralBase) ( \
    PORT_DFWR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- SetFilterLength
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets filter length in clock cycles.
 * @param PeripheralBase Peripheral base address.
 * @param Value Parameter specifying new value. This parameter is a 5-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PORTA_DFWR, PORTB_DFWR,
 *          PORTC_DFWR, PORTD_DFWR, PORTE_DFWR, PORTF_DFWR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      PORT_PDD_SetFilterLength(deviceID, 1);
 *      @endcode
 */
#define PORT_PDD_SetFilterLength(PeripheralBase, Value) ( \
    PORT_DFWR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )
#endif  /* #if defined(PORT_PDD_H_) */

/* PORT_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/msd/usb_host_msd_bo.h<|end_filename|>
#ifndef __usb_host_msd_bo_h__
#define __usb_host_msd_bo_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_msd_bo.h$
* $Version : 3.8.17.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file is a header file which defines all necessary structure to
*   be used for sending commands to mass storage devices.
*
*END************************************************************************/
#include <mqx.h>
#include <fio.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_snd.h"
#include "host_rcv.h"
#include "host_ch9.h"

/*******************************************************************
**
** Values specific to CLEAR FEATURE commands (must go to common.h later)
*/



/*******************************************************************
**
** Mass Storage definitions
*/

/* Error codes */
#define USB_TRANSFER_CANCELLED         0xF1
#define USB_MASS_INVALID_CBW           -1
#define USB_MASS_QUEUE_FULL            -2
#define USB_MASS_NO_MATCHING_REQUEST   -4
#define USB_MASS_INVALID_INTF_HANDLE   -5
#define USB_MASS_INVALID_BUFFER        -6
#define USB_MASS_FAILED_IN_COMMAND     -7
#define USB_MASS_FAILED_IN_DATA        -8
#define USB_MASS_FAILED_IN_STATUS      -9

/* Constants */
#define MAX_CBWCB_SIZE            16
#define CBW_DIRECTION_IN         0x80
#define CBW_DIRECTION_OUT        0x00
#define MAX_RETRIAL_ATTEMPTS     1
#define QUEUE_SIZE               4
#define DIRECTION_OUT            0x00
#define DIRECTION_IN             0x80
#define MASK_NON_DIRECTION_BITS  0x80

/* Command Status Wrapper Signature 'USBS'*/
#define CBW_SIGNATURE               0x43425355
#define CSW_SIGNATURE               0x53425355
#define CSW_STATUS_GOOD             0x00
#define CSW_STATUS_FAILED           0x01
#define CSW_STATUS_PHASE_ERROR      0x02

/* some useful defines */
#define ZERO_BIT0      0xFE
#define BE_HIGH_BYTE   0    /* LSB last in UFI specs (big endian)    */
#define BE_LOW_BYTE    1    /* LSB last in UFI specs (big endian)    */
#define LE_HIGH_BYTE   1    /* LSB last in UFI specs (little endian) */
#define LE_LOW_BYTE    0    /* LSB last in UFI specs (little endian) */

/*
** high nibble in x should be 1111
** transfer the low nibble of x to low nibble of a
*/
#define TRANSFER_LOW_NIBBLE(x,a)   (a) = (uint_8)(((x) & 0x0F) | ((a) & 0xF0))

#define CSW_SIZE  0x0C
#define CBW_SIZE  0x1F
#define GET_MAX_LUN   0xFE
#define MASS_STORAGE_RESET 0xFF


#define USB_CLASS_MASS_IS_Q_EMPTY(intf_ptr)      (boolean)(intf_ptr->QUEUE.COUNT==0)


/*********************************************************************
**
** Typedefs
*/

/* UFI Typical Command Block Wrapper for Most commands */
PACKED_STRUCT_BEGIN 
struct _UFI_CBWCB
{
    uint_8      BUFIOPCODE;                 /* 0 */
    uint_8      BUFILUN;                    /* 1 */
    uint_8      BUFILOGICALBLOCKADDRESS[4]; /* 2,3,4,5 */
    uint_8      RESERVED6;                  /* 6 Reserved */
    uint_8      BLENGTH[2];                 /* 7,8 length of the data block */
    uint_8      RESERVED9;                  /* 9 Reserved */
    uint_8      RESERVED10;                 /* 10 Reserved */
    uint_8      RESERVED11;                 /* 11 Reserved */
} PACKED_STRUCT_END;

typedef struct _UFI_CBWCB UFI_CBWCB_STRUCT, _PTR_ UFI_CBWCB_STRUCT_PTR;

/* UFI Typical Command Block Wrapper for Extended commands */
PACKED_STRUCT_BEGIN 
struct _UFI_CBWCB_EXTENDED
{
    uint_8      BUFIOPCODE;                 /* 0 */
    uint_8      BUFILUN;                    /* 1 */
    uint_8      BUFILOGICALBLOCKADDRESS[4]; /* 2,3,4,5 */
    uint_8      BLENGTH[4];                 /* 6,7,8,9 length of the data block */
    uint_8      RESERVED10;                 /* 10 Reserved */
    uint_8      RESERVED11;                 /* 11 Reserved */
} PACKED_STRUCT_END;

typedef struct _UFI_CBWCB_EXTENDED UFI_CBWCB_EXTENDED, _PTR_ UFI_CBWCB_EXTENDED_STRUCT_PTR;


/* define a union that covers all supported protocols.  */

PACKED_UNION_BEGIN 
union _cbwcb {
   UFI_CBWCB_STRUCT     UFI_CBWCB;
   UFI_CBWCB_EXTENDED   UFI_CBWCB_EXT;
   uint_8               MAX_COMMAND[16];
} PACKED_UNION_END;

typedef union _cbwcb CBWCB, _PTR_ CBWCB_PTR;

/* State machine constants of Class driver */
enum USB_CLASS_MASS_COMMAND_STATUS {
   STATUS_COMPLETED = USB_OK,
   STATUS_CANCELLED,
   STATUS_QUEUED_IN_DRIVER,
   STATUS_QUEUED_CBW_ON_USB,
   STATUS_FINISHED_CBW_ON_USB,
   STATUS_QUEUED_DPHASE_ON_USB,
   STATUS_FINISHED_DPHASE_ON_USB,
   STATUS_QUEUED_CSW_ON_USB,
   STATUS_FINISHED_CSW_ON_USB,
   STATUS_FAILED_IN_CSW,
   STATUS_RESET_BULK_IN,
   STATUS_RESET_BULK_OUT,
   STATUS_RESET_INTERFACE,
   STATUS_RESET_DEVICE,
   STATUS_CLEAR_BULK_PIPE
};

typedef enum USB_CLASS_MASS_COMMAND_STATUS USB_CLASS_MASS_COMMAND_STATUS;


/* Define the representation of a circular queue */
typedef struct _MASS_QUEUE_STRUCT
{
   pointer     ELEMENTS[QUEUE_SIZE]; /* storage for the queue*/
   // CR TBD
   uint_32     COUNT;
   uint_8      FIRST;         /* index of the first element in the queue*/
   uint_8      LAST;          /* index of the last element in the queue*/
} MASS_QUEUE_STRUCT, _PTR_ MASS_QUEUE_STRUCT_PTR;

/* Command Block Wrapper (see USB Mass Storage specs) */
PACKED_STRUCT_BEGIN 
struct _cbw_struct
{
   uint_8      DCBWSIGNATURE[4];            /* 0-3   */
   uint_8      DCBWTAG[4];                  /* 4-7   */
   uint_8      DCBWDATATRANSFERLENGTH[4];   /* 8-11  */
   uint_8      BMCBWFLAGS;                  /* 12    */
   uint_8      BCBWLUN;                     /* 13    */
   uint_8      BCBWCBLENGTH;                /* 14    */
   CBWCB       CMD_BLOCK;                    /* 15-31 */
}
PACKED_STRUCT_END;

typedef struct _cbw_struct CBW_STRUCT, _PTR_ CBW_STRUCT_PTR;

/* Command Status Wrapper   (see USB Mass Storage specs) */
typedef struct _csw_struct
{
    uint_8     DCSWSIGNATURE[4];         /* 0-3    */
    uint_8     DCSWTAG[4];               /* 4-7    */
    uint_8     DCSWDATARESIDUE[4];       /* 8-11   */
    uchar      BCSWSTATUS;                /* 12     */
} CSW_STRUCT, _PTR_ CSW_STRUCT_PTR;


/* USB Mass Class  One Single Command Object for all protocols */
typedef struct _COMMAND_OBJECT {
   CLASS_CALL_STRUCT_PTR             CALL_PTR;      /* Class intf data pointer and key    */
   uint_32                           LUN;           /* Logical unit number on device      */
   CBW_STRUCT_PTR                    CBW_PTR;       /* current CBW being constructed      */
   CSW_STRUCT_PTR                    CSW_PTR;       /* CSW for this command               */
   void (_CODE_PTR_                  CALLBACK)
      (USB_STATUS,                            /* status of this command                       */
       pointer,                               /* pointer to USB_MASS_BULK_ONLY_REQUEST_STRUCT */
       pointer,                               /* pointer to the command object                */
       uint_32                                /* length of the data transfered if any         */
      );

   pointer                           DATA_BUFFER;   /* buffer for IN/OUT for the command  */
   uint_32                           BUFFER_LEN;    /* length of data buffer              */
   USB_CLASS_MASS_COMMAND_STATUS     STATUS;        /* current status of this command     */
   USB_CLASS_MASS_COMMAND_STATUS     PREV_STATUS;   /* previous status of this command    */
   uint_32                           TR_BUF_LEN;    /* length of the buffer received in
                                                       currently executed TR              */
   uint_8                            RETRY_COUNT;   /* Number of times this commad tried  */
   uint_8                            TR_INDEX;      /* TR_INDEX of the TR used for search */
} COMMAND_OBJECT_STRUCT, _PTR_ COMMAND_OBJECT_PTR;


/*
** USB Mass Class Interface structure. This structure will be passed to all
** commands to this class driver. The structure holds all information
** pertaining to an interface on storage device. This allows the class driver
** to know which interface the command is directed for.
*/

typedef struct _Usb_Mass_Intf_Struct {
   GENERAL_CLASS                       G;                 // This is general class containing following
   _usb_pipe_handle                    CONTROL_PIPE;      /* control pipe handle*/
   _usb_pipe_handle                    BULK_IN_PIPE;      /* Bulk in pipe handle*/
   _usb_pipe_handle                    BULK_OUT_PIPE;     /* Bulk out pipe handle*/
   MASS_QUEUE_STRUCT                   QUEUE;             /* structure that queues requests*/
   uint_8                              INTERFACE_NUM;     /* interface number*/
   uint_8                              ALTERNATE_SETTING; /* Alternate setting*/
   CLASS_CALL_STRUCT_PTR               APP;               /* Store app handle, can help finding if lost */
} USB_MASS_CLASS_INTF_STRUCT, _PTR_ USB_MASS_CLASS_INTF_STRUCT_PTR;


/* Prototypes */

#ifdef __cplusplus
extern "C" {
#endif

USB_STATUS usb_class_mass_get_app(_usb_device_instance_handle, _usb_interface_descriptor_handle, CLASS_CALL_STRUCT_PTR _PTR_);
int_32 usb_class_mass_q_insert(USB_MASS_CLASS_INTF_STRUCT_PTR, COMMAND_OBJECT_PTR);
void usb_class_mass_deleteq(USB_MASS_CLASS_INTF_STRUCT_PTR);
void usb_class_mass_get_pending_request(USB_MASS_CLASS_INTF_STRUCT_PTR, COMMAND_OBJECT_PTR _PTR_);
void usb_class_mass_q_init(USB_MASS_CLASS_INTF_STRUCT_PTR);
void usb_class_mass_init(PIPE_BUNDLE_STRUCT_PTR, CLASS_CALL_STRUCT_PTR);
void usb_class_mass_exit(void);
USB_STATUS usb_class_mass_storage_device_command(CLASS_CALL_STRUCT_PTR, COMMAND_OBJECT_PTR);
boolean usb_class_mass_storage_device_command_cancel(CLASS_CALL_STRUCT_PTR, COMMAND_OBJECT_PTR);
USB_STATUS usb_class_mass_getmaxlun_bulkonly(CLASS_CALL_STRUCT_PTR, uint_8_ptr, tr_callback, pointer);
USB_STATUS usb_class_mass_reset_recovery_on_usb(USB_MASS_CLASS_INTF_STRUCT_PTR);
boolean usb_class_mass_cancelq(USB_MASS_CLASS_INTF_STRUCT_PTR intf_ptr, COMMAND_OBJECT_PTR pCmd);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/snmp/mqxmib.c<|end_filename|>
/*HEADER****************************************************************
*
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2009 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************** 
*
* Comments:  This file was generated by "gawk -f def2c.awk" script.
*
*END*******************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include "snmpcfg.h"
#include "asn1.h"
#include "snmp.h"


#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4

extern RTCSMIB_NODE MIBNODE_enterprises;

extern RTCSMIB_NODE MIBNODE_freescale;
extern const RTCSMIB_NODE MIBNODE_mqx;
extern const RTCSMIB_NODE MIBNODE_mqxKernel;
extern const RTCSMIB_NODE MIBNODE_mqxVersion;
extern const RTCSMIB_NODE MIBNODE_mqxRevision;
extern const RTCSMIB_NODE MIBNODE_mqxRevKernel;
extern const RTCSMIB_NODE MIBNODE_mqxRevPSP;
extern const RTCSMIB_NODE MIBNODE_mqxRevIO;
extern const RTCSMIB_NODE MIBNODE_mqxRevBSP;
extern const RTCSMIB_NODE MIBNODE_mqxCopyright;
extern const RTCSMIB_NODE MIBNODE_mqxDate;
extern const RTCSMIB_NODE MIBNODE_mqxCPU;
extern const RTCSMIB_NODE MIBNODE_mqxCPUType;
extern const RTCSMIB_NODE MIBNODE_mqxCPUEndian;
extern const RTCSMIB_NODE MIBNODE_mqxCPUAddressing;
extern const RTCSMIB_NODE MIBNODE_mqxProcessorNum;
extern const RTCSMIB_NODE MIBNODE_mqxConfig;
extern const RTCSMIB_NODE MIBNODE_mqxConfigFloatingPointIO;
extern const RTCSMIB_NODE MIBNODE_mqxConfigInlineMacros;
extern const RTCSMIB_NODE MIBNODE_mqxConfigKernelLogging;
extern const RTCSMIB_NODE MIBNODE_mqxConfigMonitorStack;
extern const RTCSMIB_NODE MIBNODE_mqxConfigTaskCreationBlocks;
extern const RTCSMIB_NODE MIBNODE_mqxConfigTaskDestruction;
extern const RTCSMIB_NODE MIBNODE_mqxConfigComponentDestruction;
extern const RTCSMIB_NODE MIBNODE_mqxConfigCheckErrors;
extern const RTCSMIB_NODE MIBNODE_mqxConfigCheckValidity;
extern const RTCSMIB_NODE MIBNODE_mqxConfigCheckAlloc;
extern const RTCSMIB_NODE MIBNODE_mqxConfig64BitInts;
extern const RTCSMIB_NODE MIBNODE_mqxConfigPspKernelLogging;
extern const RTCSMIB_NODE MIBNODE_mqxConfigPspFPRegisters;
extern const RTCSMIB_NODE MIBNODE_mqxConfig32BitQIDs;
extern const RTCSMIB_NODE MIBNODE_mqxTask;
extern const RTCSMIB_NODE MIBNODE_mqxTaskTable;
extern const RTCSMIB_NODE MIBNODE_mqxTaskEntry;
extern const RTCSMIB_NODE MIBNODE_mqxTaskID;
extern const RTCSMIB_NODE MIBNODE_mqxTaskCreator;
extern const RTCSMIB_NODE MIBNODE_mqxTaskName;
extern const RTCSMIB_NODE MIBNODE_mqxTaskState;
extern const RTCSMIB_NODE MIBNODE_mqxTaskErrorCode;
extern const RTCSMIB_NODE MIBNODE_mqxTaskSched;
extern const RTCSMIB_NODE MIBNODE_mqxTaskSchedPriority;
extern const RTCSMIB_NODE MIBNODE_mqxTaskSchedHomePriority;
extern const RTCSMIB_NODE MIBNODE_mqxTaskSchedPolicy;
extern const RTCSMIB_NODE MIBNODE_mqxTaskSchedTimeSlice;
extern const RTCSMIB_NODE MIBNODE_mqxTaskStackSize;
extern const RTCSMIB_NODE MIBNODE_mqxTaskStackUsed;
extern const RTCSMIB_NODE MIBNODE_mqxTaskIO;
extern const RTCSMIB_NODE MIBNODE_mqxTaskIOstdin;
extern const RTCSMIB_NODE MIBNODE_mqxTaskIOstdout;
extern const RTCSMIB_NODE MIBNODE_mqxTaskIOstderr;
extern const RTCSMIB_NODE MIBNODE_mqxTaskFlag;
extern const RTCSMIB_NODE MIBNODE_mqxTaskFlagFloatingPoint;
extern const RTCSMIB_NODE MIBNODE_mqxTaskFlagLoggingEnabled;
extern const RTCSMIB_NODE MIBNODE_mqxTaskFlagWatchdogEnabled;
extern const RTCSMIB_NODE MIBNODE_mqxTaskFlagPreemptionDisabled;
extern const RTCSMIB_NODE MIBNODE_mqxComponent;
extern const RTCSMIB_NODE MIBNODE_mqxComponentName;
extern const RTCSMIB_NODE MIBNODE_mqxComponentSem;
extern const RTCSMIB_NODE MIBNODE_mqxComponentEvent;
extern const RTCSMIB_NODE MIBNODE_mqxComponentMutex;
extern const RTCSMIB_NODE MIBNODE_mqxComponentTimer;
extern const RTCSMIB_NODE MIBNODE_mqxComponentLog;
extern const RTCSMIB_NODE MIBNODE_mqxComponentWatchdog;
extern const RTCSMIB_NODE MIBNODE_mqxComponentMessage;
extern const RTCSMIB_NODE MIBNODE_mqxComponentPart;
extern const RTCSMIB_NODE MIBNODE_mqxComponentIPC;
extern const RTCSMIB_NODE MIBNODE_mqxComponentQlog;
extern const RTCSMIB_NODE MIBNODE_mqxComponentEDS;
extern const RTCSMIB_NODE MIBNODE_mqxIOC;
extern const RTCSMIB_NODE MIBNODE_mqxIOCIO;
extern const RTCSMIB_NODE MIBNODE_mqxIOCRTCS;
extern const RTCSMIB_NODE MIBNODE_mqxIOCLAPB;
extern const RTCSMIB_NODE MIBNODE_mqxIOCLAPD;
extern const RTCSMIB_NODE MIBNODE_mqxIOCSDLC;
extern const RTCSMIB_NODE MIBNODE_mqxIOCHDLC;
extern const RTCSMIB_NODE MIBNODE_mqxIOCMFS;
extern const RTCSMIB_NODE MIBNODE_mqxIOCCAN;
extern const RTCSMIB_NODE MIBNODE_mqxIOCPPP;
extern const RTCSMIB_NODE MIBNODE_mqxIOCSNMP;
extern const RTCSMIB_NODE MIBNODE_mqxIOCENET;

extern const RTCSMIB_VALUE MIBVALUE_freescale;
extern const RTCSMIB_VALUE MIBVALUE_mqx;
extern const RTCSMIB_VALUE MIBVALUE_mqxKernel;
extern const RTCSMIB_VALUE MIBVALUE_mqxVersion;
extern const RTCSMIB_VALUE MIBVALUE_mqxRevision;
extern const RTCSMIB_VALUE MIBVALUE_mqxRevKernel;
extern const RTCSMIB_VALUE MIBVALUE_mqxRevPSP;
extern const RTCSMIB_VALUE MIBVALUE_mqxRevIO;
extern const RTCSMIB_VALUE MIBVALUE_mqxRevBSP;
extern const RTCSMIB_VALUE MIBVALUE_mqxCopyright;
extern const RTCSMIB_VALUE MIBVALUE_mqxDate;
extern const RTCSMIB_VALUE MIBVALUE_mqxCPU;
extern const RTCSMIB_VALUE MIBVALUE_mqxCPUType;
extern const RTCSMIB_VALUE MIBVALUE_mqxCPUEndian;
extern const RTCSMIB_VALUE MIBVALUE_mqxCPUAddressing;
extern const RTCSMIB_VALUE MIBVALUE_mqxProcessorNum;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfig;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigFloatingPointIO;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigInlineMacros;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigKernelLogging;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigMonitorStack;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigTaskCreationBlocks;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigTaskDestruction;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigComponentDestruction;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigCheckErrors;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigCheckValidity;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigCheckAlloc;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfig64BitInts;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigPspKernelLogging;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfigPspFPRegisters;
extern const RTCSMIB_VALUE MIBVALUE_mqxConfig32BitQIDs;
extern const RTCSMIB_VALUE MIBVALUE_mqxTask;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskTable;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskEntry;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskID;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskCreator;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskName;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskState;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskErrorCode;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskSched;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskSchedPriority;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskSchedHomePriority;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskSchedPolicy;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskSchedTimeSlice;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskStackSize;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskStackUsed;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskIO;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskIOstdin;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskIOstdout;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskIOstderr;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskFlag;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskFlagFloatingPoint;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskFlagLoggingEnabled;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskFlagWatchdogEnabled;
extern const RTCSMIB_VALUE MIBVALUE_mqxTaskFlagPreemptionDisabled;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponent;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentName;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentSem;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentEvent;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentMutex;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentTimer;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentLog;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentWatchdog;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentMessage;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentPart;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentIPC;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentQlog;
extern const RTCSMIB_VALUE MIBVALUE_mqxComponentEDS;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOC;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCIO;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCRTCS;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCLAPB;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCLAPD;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCSDLC;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCHDLC;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCMFS;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCCAN;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCPPP;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCSNMP;
extern const RTCSMIB_VALUE MIBVALUE_mqxIOCENET;

boolean MIB_find_mqxTaskEntry        (uint_32, pointer, pointer _PTR_);

static boolean MIB_instance_mqxTaskEntry        (RTCSMIB_WALK_PTR, uint_32, boolean (_CODE_PTR_)(uint_32, pointer, pointer _PTR_), boolean _PTR_, pointer _PTR_);


RTCSMIB_NODE MIBNODE_freescale = {
   33118,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqx,
   (RTCSMIB_NODE_PTR)&MIBNODE_enterprises,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqx = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxKernel,
   (RTCSMIB_NODE_PTR)&MIBNODE_freescale,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxKernel = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTask,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxVersion,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqx,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxVersion = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevision,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxKernel,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxVersion,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxRevision = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxCopyright,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevKernel,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxKernel,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxRevision,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxRevKernel = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevPSP,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevision,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxRevKernel,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxRevPSP = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevIO,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevision,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxRevPSP,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxRevIO = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevBSP,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevision,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxRevIO,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxRevBSP = {
   4,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxRevision,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxRevBSP,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxCopyright = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxDate,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxKernel,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxCopyright,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxDate = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxCPU,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxKernel,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxDate,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxCPU = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxProcessorNum,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxCPUType,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxKernel,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxCPU,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxCPUType = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxCPUEndian,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxCPU,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxCPUType,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxCPUEndian = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxCPUAddressing,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxCPU,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxCPUEndian,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxCPUAddressing = {
   3,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxCPU,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxCPUAddressing,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxProcessorNum = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxKernel,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxProcessorNum,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfig = {
   7,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigFloatingPointIO,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxKernel,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfig,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigFloatingPointIO = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigInlineMacros,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigFloatingPointIO,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigInlineMacros = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigKernelLogging,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigInlineMacros,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigKernelLogging = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigMonitorStack,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigKernelLogging,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigMonitorStack = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigTaskCreationBlocks,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigMonitorStack,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigTaskCreationBlocks = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigTaskDestruction,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigTaskCreationBlocks,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigTaskDestruction = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigComponentDestruction,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigTaskDestruction,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigComponentDestruction = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigCheckErrors,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigComponentDestruction,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigCheckErrors = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigCheckValidity,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigCheckErrors,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigCheckValidity = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigCheckAlloc,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigCheckValidity,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigCheckAlloc = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig64BitInts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigCheckAlloc,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfig64BitInts = {
   11,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigPspKernelLogging,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfig64BitInts,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigPspKernelLogging = {
   12,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfigPspFPRegisters,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigPspKernelLogging,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfigPspFPRegisters = {
   13,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig32BitQIDs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfigPspFPRegisters,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxConfig32BitQIDs = {
   14,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxConfig,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxConfig32BitQIDs,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTask = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskTable,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqx,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskTable = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTask,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskTable,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskEntry = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskID,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskTable,

   0,
   MIB_find_mqxTaskEntry,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskEntry,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskID = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskCreator,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskID,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskCreator = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskName,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskCreator,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskName = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskState,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskName,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskState = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskErrorCode,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskState,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskErrorCode = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSched,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskErrorCode,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskSched = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskStackSize,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSchedPriority,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   0,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskSched,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskSchedPriority = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSchedHomePriority,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSched,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskSchedPriority,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskSchedHomePriority = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSchedPolicy,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSched,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskSchedHomePriority,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskSchedPolicy = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSchedTimeSlice,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSched,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskSchedPolicy,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskSchedTimeSlice = {
   4,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskSched,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskSchedTimeSlice,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskStackSize = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskStackUsed,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskStackSize,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskStackUsed = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskIO,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskStackUsed,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskIO = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlag,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskIOstdin,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   0,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskIO,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskIOstdin = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskIOstdout,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskIO,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskIOstdin,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskIOstdout = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskIOstderr,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskIO,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskIOstdout,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskIOstderr = {
   3,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskIO,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskIOstderr,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskFlag = {
   10,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlagFloatingPoint,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskEntry,

   0,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskFlag,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskFlagFloatingPoint = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlagLoggingEnabled,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlag,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskFlagFloatingPoint,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskFlagLoggingEnabled = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlagWatchdogEnabled,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlag,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskFlagLoggingEnabled,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskFlagWatchdogEnabled = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlagPreemptionDisabled,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlag,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskFlagWatchdogEnabled,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxTaskFlagPreemptionDisabled = {
   4,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxTaskFlag,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_mqxTaskEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_mqxTaskFlagPreemptionDisabled,
   NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponent = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentName,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqx,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentName = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentSem,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentSem = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentEvent,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentEvent = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentMutex,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentMutex = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentTimer,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentTimer = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentLog,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentLog = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentWatchdog,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentWatchdog = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentMessage,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentMessage = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentPart,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentPart = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentIPC,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentIPC = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentQlog,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentQlog = {
   11,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponentEDS,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxComponentEDS = {
   12,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxComponent,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOC = {
   4,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCIO,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqx,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCIO = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCRTCS,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCRTCS = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCLAPB,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCLAPB = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCLAPD,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCLAPD = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCSDLC,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCSDLC = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCHDLC,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCHDLC = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCMFS,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCMFS = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCCAN,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCCAN = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCPPP,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCPPP = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCSNMP,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCSNMP = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOCENET,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_mqxIOCENET = {
   11,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mqxIOC,

   0,
   NULL,
   NULL, 0, NULL, NULL
};


static boolean MIB_instance_mqxTaskEntry
   (
      RTCSMIB_WALK_PTR     mib,
      uint_32              op,
      boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
      boolean _PTR_        found,
      pointer _PTR_        instance
   )
{ /* Body */
   struct {
      uint_32 mqxTaskID;
   } index;

   *found = FALSE;
   *instance = NULL;

   switch (op) {

   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:

      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read32(mib, &index.mqxTaskID)) return FALSE;
      if (mib->inlen != 0) break;
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETNEXT:
      if (mib->inlen == 0) {
         index.mqxTaskID = 0;
      } else {
         if (!RTCSMIB_id_read32(mib, &index.mqxTaskID)) return FALSE;
         if(index.mqxTaskID < 0xffffffff) // 4294967295
            index.mqxTaskID++;
      } /* Endif */
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETFIRST:
      index.mqxTaskID = 0;
      *found = find(RTCSMIB_OP_GETNEXT, &index, instance);
      break;
   } /* Endswitch */

   if (*found && (op != RTCSMIB_OP_SET)) {
      if (!RTCSMIB_id_write32 (mib, index.mqxTaskID)) return FALSE;
   } /* Endif */

   return TRUE;
} /* Endbody */


#endif

/****************************************************************************/

#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4

#include <rtcs_prv.h>
#include "tcpip.h"

#include <mqx.h>
#include <fio.h>
#include <psp.h>
#include <mem_prv.h>
#include <mqx_prv.h>
#include <gen_rev.h>
#include <psp_rev.h>
#include <bsp_rev.h>
#include <stdlib.h>
#include <stddef.h>

extern uint_32 MIB_get_mqxConfig64BitInts(pointer dummy);
extern uint_32 MIB_get_mqxRevKernel(pointer dummy);
extern uint_32 MIB_get_mqxRevPSP(pointer dummy);
extern uint_32 MIB_get_mqxRevIO(pointer dummy);
extern uint_32 MIB_get_mqxRevBSP(pointer dummy);
extern uchar_ptr MIB_get_mqxCopyright(pointer td);
extern uchar_ptr MIB_get_mqxDate(pointer td);
extern uint_32 MIB_get_mqxCPUEndian(pointer dummy);
extern uint_32 MIB_get_mqxCPUAddressing(pointer dummy);
extern uint_32 MIB_get_mqxProcessorNum(pointer dummy);
static uint_32 MIB_get_mqxTaskID(pointer td);
static uint_32 MIB_get_mqxTaskCreator(pointer td);
static uchar_ptr MIB_get_mqxTaskName(pointer td);
static uint_32 MIB_get_mqxTaskState(pointer td);
static uint_32 MIB_get_mqxTaskErrorCode(pointer td);
static uint_32 MIB_get_mqxTaskSchedPriority(pointer td);
static uint_32 MIB_get_mqxTaskSchedHomePriority(pointer td);
static uint_32 MIB_get_mqxTaskSchedPolicy(pointer td);
static uint_32 MIB_get_mqxTaskSchedTimeSlice(pointer td);
static uint_32 MIB_get_mqxTaskStackSize(pointer dummy);
static uint_32 MIB_get_mqxTaskStackUsed(pointer dummy);
static uchar_ptr MIB_get_mqxTaskIOstdin(pointer td);
static uchar_ptr MIB_get_mqxTaskIOstdout(pointer td);
static uchar_ptr MIB_get_mqxTaskIOstderr(pointer td);
static uint_32 MIB_get_mqxTaskFlagFloatingPoint(pointer td);
static uint_32 MIB_get_mqxTaskFlagLoggingEnabled(pointer td);
static uint_32 MIB_get_mqxTaskFlagWatchdogEnabled(pointer td);
static uint_32 MIB_get_mqxTaskFlagPreemptionDisabled(pointer td);

/****************************************************************************/

uint_32 MIB_get_mqxConfig64BitInts(pointer dummy)
{
	return(0);	
}

boolean MIB_find_mqxTaskEntry
   (
      uint_32        op,
      pointer        index,
      pointer _PTR_  instance
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR  kd_ptr = _mqx_get_kernel_data();
   _task_id                tid = (_task_id)*(uint_32_ptr)index;
   TD_STRUCT_PTR           td_ptr = NULL;
   QUEUE_ELEMENT_STRUCT_PTR search_ptr;
   uint_32                  td_num;

   if (op == RTCSMIB_OP_GET) {
      *instance = _task_get_td(tid);
      return (*instance != NULL);
   } /* Endif */

   search_ptr = kd_ptr->TD_LIST.NEXT;
   td_num = 0;
   for (;;) {
     td_ptr = (TD_STRUCT_PTR)((char_ptr)search_ptr - offsetof(TD_STRUCT, TD_LIST_INFO));
     if (td_ptr->TASK_ID >= tid) {
        break;
    } /* Endif */
    td_num++;
    if (td_num >= kd_ptr->TD_LIST.SIZE) {
        td_ptr = NULL;
        break;
    } /* Endif */
    search_ptr = search_ptr->NEXT;
   } /* Endfor */

   if (!td_ptr) {
      return FALSE;
   } /* Endif */

   *(uint_32_ptr)index = td_ptr->TASK_ID;
   *instance = td_ptr;
   return (td_ptr != NULL);

} /* Endbody */

static uint_32   MIB_get_mqxTaskID                     (pointer td) {return ((TD_STRUCT_PTR)td)->TASK_ID;}
static uint_32   MIB_get_mqxTaskCreator                (pointer td) {return ((TD_STRUCT_PTR)td)->PARENT;}
static uint_32   MIB_get_mqxTaskSchedTimeSlice         (pointer td) {uint_32 ms; _sched_get_rr_interval(((TD_STRUCT_PTR)td)->TASK_ID,&ms); return ms;}
static uchar_ptr MIB_get_mqxTaskName                   (pointer td) {return (uchar_ptr)((TD_STRUCT_PTR)td)->TASK_TEMPLATE_PTR->TASK_NAME;}
static uint_32   MIB_get_mqxTaskState                  (pointer td) {return ((TD_STRUCT_PTR)td)->STATE;}
static uint_32   MIB_get_mqxTaskErrorCode              (pointer td) {return ((TD_STRUCT_PTR)td)->TASK_ERROR_CODE;}
static uint_32   MIB_get_mqxTaskSchedPriority          (pointer td) {return ((TD_STRUCT_PTR)td)->MY_QUEUE->PRIORITY;}
static uint_32   MIB_get_mqxTaskSchedHomePriority      (pointer td) {return ((TD_STRUCT_PTR)td)->HOME_QUEUE->PRIORITY;}
static uint_32   MIB_get_mqxTaskSchedPolicy            (pointer td) {
#if MQX_TIME_SLICE_TASK
return (((TD_STRUCT_PTR)td)->FLAGS & MQX_TIME_SLICE_TASK) ? MQX_SCHED_RR : MQX_SCHED_FIFO;
#else
return 0;
#endif
}
#if MQX_KERNEL_LOGGING
static uint_32   MIB_get_mqxTaskStackSize              (pointer td) {uint_32 ss,su; _klog_get_task_stack_usage(((TD_STRUCT_PTR)td)->TASK_ID,&ss,&su); return ss;}
static uint_32   MIB_get_mqxTaskStackUsed              (pointer td) {uint_32 ss,su; _klog_get_task_stack_usage(((TD_STRUCT_PTR)td)->TASK_ID,&ss,&su); return su;}
#endif
static uchar_ptr MIB_get_mqxTaskIOstdin                (pointer td) {return (((TD_STRUCT_PTR)td)->STDIN_STREAM)  ? (uchar_ptr)((MQX_FILE_PTR)((TD_STRUCT_PTR)td)->STDIN_STREAM)->DEV_PTR->IDENTIFIER  : NULL;}
static uchar_ptr MIB_get_mqxTaskIOstdout               (pointer td) {return (((TD_STRUCT_PTR)td)->STDOUT_STREAM) ? (uchar_ptr)((MQX_FILE_PTR)((TD_STRUCT_PTR)td)->STDOUT_STREAM)->DEV_PTR->IDENTIFIER : NULL;}
static uchar_ptr MIB_get_mqxTaskIOstderr               (pointer td) {return (((TD_STRUCT_PTR)td)->STDERR_STREAM) ? (uchar_ptr)((MQX_FILE_PTR)((TD_STRUCT_PTR)td)->STDERR_STREAM)->DEV_PTR->IDENTIFIER : NULL;}
#if PSP_HAS_FPU
static uint_32   MIB_get_mqxTaskFlagFloatingPoint      (pointer td) {return (((TD_STRUCT_PTR)td)->FLAGS & MQX_FLOATING_POINT_TASK)  ? 1 : 0;}
#endif
static uint_32   MIB_get_mqxTaskFlagLoggingEnabled     (pointer td) {return (((TD_STRUCT_PTR)td)->FLAGS & TASK_LOGGING_ENABLED)     ? 1 : 0;}
static uint_32   MIB_get_mqxTaskFlagWatchdogEnabled    (pointer td) {return (((TD_STRUCT_PTR)td)->FLAGS & TASK_WATCHDOG_STARTED)    ? 1 : 0;}
static uint_32   MIB_get_mqxTaskFlagPreemptionDisabled (pointer td) {return (((TD_STRUCT_PTR)td)->FLAGS & TASK_PREEMPTION_DISABLED) ? 1 : 0;}


uint_32 MIB_get_mqxRevKernel(pointer dummy)
{
	return(GEN_REVISION);
}

uint_32 MIB_get_mqxRevPSP(pointer dummy)
{
	return(PSP_REVISION);
}

uint_32 MIB_get_mqxRevIO(pointer dummy)
{
	return(IO_REVISION);
}

uint_32 MIB_get_mqxRevBSP(pointer dummy)
{
	return(BSP_REVISION);
}

uchar_ptr MIB_get_mqxCopyright(pointer td)
{
	return((uchar_ptr)_mqx_copyright);
}

uchar_ptr MIB_get_mqxDate(pointer td)
{
	return((uchar_ptr)_mqx_date );	
}

uint_32 MIB_get_mqxCPUEndian(pointer dummy)
{
	return(PSP_ENDIAN);	
}

uint_32 MIB_get_mqxCPUAddressing(pointer dummy)
{
	return(PSP_MEMORY_ADDRESSING_CAPABILITY);
}

uint_32 MIB_get_mqxProcessorNum(pointer dummy)
{
	//TBD KERNEL_DATA_STRUCT_PTR kd_ptr = _mqx_get_kernel_data();
	return 0;//((uint_32)kd_ptr->PROCESSOR_NUMBER);	
}

/****************************************************************************/

const RTCSMIB_VALUE MIBVALUE_mqxVersion = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_VERSION
};

const RTCSMIB_VALUE MIBVALUE_mqxRevKernel = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxRevKernel
};

const RTCSMIB_VALUE MIBVALUE_mqxRevPSP = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxRevPSP
};

const RTCSMIB_VALUE MIBVALUE_mqxRevIO = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxRevIO
};

const RTCSMIB_VALUE MIBVALUE_mqxRevBSP = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxRevBSP
};

const RTCSMIB_VALUE MIBVALUE_mqxCopyright = {
	RTCSMIB_NODETYPE_DISPSTR_FN,
	(void _PTR_)MIB_get_mqxCopyright 
};

const RTCSMIB_VALUE MIBVALUE_mqxDate = {
	RTCSMIB_NODETYPE_DISPSTR_FN,
	(void _PTR_)MIB_get_mqxDate 
};

const RTCSMIB_VALUE MIBVALUE_mqxCPUEndian = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxCPUEndian
};

const RTCSMIB_VALUE MIBVALUE_mqxCPUAddressing = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxCPUAddressing
};

const RTCSMIB_VALUE MIBVALUE_mqxProcessorNum = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxProcessorNum
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigFloatingPointIO = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_INCLUDE_FLOATING_POINT_IO
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigInlineMacros = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_USE_INLINE_MACROS
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigKernelLogging = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_KERNEL_LOGGING
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigMonitorStack = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_MONITOR_STACK
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigTaskCreationBlocks = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_TASK_CREATION_BLOCKS
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigTaskDestruction = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_TASK_DESTRUCTION
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigComponentDestruction = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_COMPONENT_DESTRUCTION
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigCheckErrors = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_CHECK_ERRORS
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigCheckValidity = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_CHECK_VALIDITY
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigCheckAlloc = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_CHECK_MEMORY_ALLOCATION_ERRORS
};

const RTCSMIB_VALUE MIBVALUE_mqxConfig64BitInts = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxConfig64BitInts
};

const RTCSMIB_VALUE MIBVALUE_mqxConfig32BitQIDs = {
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)MQX_USE_32BIT_MESSAGE_QIDS
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskID = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskID
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskCreator = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskCreator
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskName = {
	RTCSMIB_NODETYPE_DISPSTR_FN,
	(void _PTR_)MIB_get_mqxTaskName 
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskState = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskState
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskErrorCode = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskErrorCode
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskSchedPriority = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskSchedPriority
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskSchedHomePriority = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskSchedHomePriority
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskSchedPolicy = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskSchedPolicy
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskSchedTimeSlice = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskSchedTimeSlice
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskStackSize = {
	#if MQX_KERNEL_LOGGING
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskStackSize
	#else
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)NULL
	#endif
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskStackUsed = {
	#if MQX_KERNEL_LOGGING
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskStackUsed
	#else
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)NULL
	#endif	
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskIOstdin = {
	RTCSMIB_NODETYPE_DISPSTR_FN,
	(void _PTR_)MIB_get_mqxTaskIOstdin 
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskIOstdout = {
	RTCSMIB_NODETYPE_DISPSTR_FN,
	(void _PTR_)MIB_get_mqxTaskIOstdout 
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskIOstderr = {
	RTCSMIB_NODETYPE_DISPSTR_FN,
	(void _PTR_)MIB_get_mqxTaskIOstderr 
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskFlagFloatingPoint = {
#if PSP_HAS_FPU
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskFlagFloatingPoint
#else
	RTCSMIB_NODETYPE_UINT_CONST,
	(void _PTR_)NULL
#endif	
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskFlagLoggingEnabled = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskFlagLoggingEnabled
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskFlagWatchdogEnabled = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskFlagWatchdogEnabled
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskFlagPreemptionDisabled = {
	RTCSMIB_NODETYPE_UINT_FN,
	(void _PTR_)MIB_get_mqxTaskFlagPreemptionDisabled
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCLAPB = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigPspFPRegisters = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCPPP = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentPart = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskTable = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxTask = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxCPU = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxKernel = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCENET = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};


const RTCSMIB_VALUE MIBVALUE_mqxIOCLAPD = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentSem = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentEDS = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentQlog = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCHDLC = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCMFS = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentTimer = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponent = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentIPC = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentMutex = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskIO = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxConfigPspKernelLogging = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxConfig = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCSNMP = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCSDLC = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskSched = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxCPUType = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_freescale = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCCAN = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentLog = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskFlag = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxTaskEntry = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCRTCS = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxRevision = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqx = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOCIO = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxIOC = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentMessage = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentWatchdog = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentEvent = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

const RTCSMIB_VALUE MIBVALUE_mqxComponentName = {
	RTCSMIB_NODETYPE_INT_CONST,
	NULL
};

#endif /* RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4 */

/****************************************************************************/
 
void MIBMQX_init(void)
{
#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4
   RTCSMIB_mib_add(&MIBNODE_freescale);
#endif
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5225_fec.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5225_fec.h$
* $Version : 3.0.1.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the ethernet drivers for the MCF5225x processor
*
*END************************************************************************/
#ifndef _mcf5225_fec_h
#define _mcf5225_fec_h 1

#define MCF5225_FEC0 0

#define MCF5XXX_FEC_DEVICE_COUNT 1
   
#define MCF5XXX_FEC_RX_BUFFER_ALIGNMENT   16  
#define MCF5XXX_FEC_TX_BUFFER_ALIGNMENT   4   
#define MCF5XXX_FEC_BD_ALIGNMENT          16 // may be 4.

// Needs to be here, because a SMALL packet must be a multiple of the RX_BUFFER_ALIGNMENT
#define MCF5XXX_SMALL_PACKET_SIZE         ENET_ALIGN(64,MCF5XXX_FEC_RX_BUFFER_ALIGNMENT)
       
// temporary - these should be generic PSP functions.
#define _psp_set_int_prio_and_level _mcf52xx_int_init
#define _psp_int_mask(x)            _mcf52xx_int_mask(x)

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/FTM0.h<|end_filename|>
/* ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : FTM0.h
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : Init_FTM
**     Version     : Component 01.006, Driver 01.06, CPU db: 3.00.000
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-16, 17:36, # CodeGen: 13
**     Abstract    :
**          This file implements the FTM (FTM0) module initialization
**          according to the Peripheral Initialization settings, and
**          defines interrupt service routines prototypes.
**     Settings    :
**          Component name                                 : FTM0
**          Device                                         : FTM0
**          Settings                                       : 
**            Clock gate                                   : Enabled
**            Clock settings                               : 
**              Clock source                               : System clock
**              Prescaler                                  : divide by 1
**              Counter init                               : 0
**              Modulo counter                             : 1875
**              Period                                     : 62.500 us
**              Deadtime                                   : 
**                Deadtime prescaler                       : divide by 1
**                Deadtime value                           : 1
**                Deadtime delay                           : 0.017 us
**              Num of timer overflows                     : 0
**            FTM mode                                     : Disabled
**            BDM mode                                     : FTM counter stopped; output pins remain the same
**            Global time base                             : Disabled
**            Global time base output                      : Disabled
**            Write protection                             : Disabled
**            Combined channels                            : 
**              Channels 0 and 1                           : 
**                Complementary mode                       : Enabled
**                Fault control                            : Enabled
**                Synchronization                          : Enabled
**                Deadtime                                 : Enabled
**                Inverting                                : Disabled
**              Channels 2 and 3                           : 
**                Complementary mode                       : Enabled
**                Fault control                            : Enabled
**                Synchronization                          : Enabled
**                Deadtime                                 : Enabled
**                Inverting                                : Disabled
**              Channels 4 and 5                           : 
**                Complementary mode                       : Enabled
**                Fault control                            : Enabled
**                Synchronization                          : Enabled
**                Deadtime                                 : Enabled
**                Inverting                                : Disabled
**              Channels 6 and 7                           : 
**                Complementary mode                       : Disabled
**                Fault control                            : Disabled
**                Synchronization                          : Disabled
**                Deadtime                                 : Disabled
**                Inverting                                : Disabled
**            Synchronization                              : 
**              Synchronization mode                       : Disabled
**                Counter reinitialization                 : Disabled
**              HW trigger mode                            : Enabled
**              CNTIN synchronization                      : Disabled
**              INVCTRL synchronization                    : Disabled
**              SWOCTRL synchronization                    : Disabled
**              Software Trigger                           : Disabled
**              OUTMASK synchronization                    : Disabled
**              Minimum loading point                      : Disabled
**              Maximum loading point                      : Disabled
**            External triggers                            : 
**              Counter init trigger                       : Disabled
**              Channel 0 trigger                          : Disabled
**              Channel 1 trigger                          : Disabled
**              Channel 2 trigger                          : Disabled
**              Channel 3 trigger                          : Disabled
**              Channel 4 trigger                          : Disabled
**              Channel 5 trigger                          : Disabled
**            Fault control settings                       : 
**              Fault control mode                         : Disabled
**              Fault input filter value                   : Disabled
**              Fault input 0 filter                       : Disabled
**              Fault input 0 polarity                     : High
**              Fault input 1 filter                       : Disabled
**              Fault input 1 polarity                     : High
**              Fault input 2 filter                       : Disabled
**              Fault input 2 polarity                     : High
**              Fault input 3 filter                       : Disabled
**              Fault input 3 polarity                     : High
**          Channels                                       : 
**            Channel 0                                    : Enabled
**              Channel mode                               : Center-aligned PWM
**                PWM polarity                             : High-true
**                Channel value register                   : 800
**              Input capture filter                       : Disabled
**              Software output control                    : Disabled
**              Pin                                        : Enabled
**                Pin                                      : ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/FBa_AD13/NFC_DATA10/I2S0_TXD0
**                Pin signal                               : 
**              Interrupt/DMA                              : 
**                Interrupt                                : INT_FTM0
**                Channel interrupt                        : Disabled
**                DMA request                              : Disabled
**            Channel 1                                    : Enabled
**              Channel mode                               : Center-aligned PWM
**                PWM polarity                             : High-true
**                Channel value register                   : 800
**              Input capture filter                       : Disabled
**              Software output control                    : Disabled
**              Pin                                        : Enabled
**                Pin                                      : ADC0_SE4b/CMP1_IN0/TSI0_CH15/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/NFC_DATA9/I2S0_TX_FS
**                Pin signal                               : 
**              Interrupt/DMA                              : 
**                Interrupt                                : INT_FTM0
**                Channel interrupt                        : Disabled
**                DMA request                              : Disabled
**            Channel 2                                    : Enabled
**              Channel mode                               : Center-aligned PWM
**                PWM polarity                             : High-true
**                Channel value register                   : 800
**              Input capture filter                       : Disabled
**              Software output control                    : Disabled
**              Pin                                        : Enabled
**                Pin                                      : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUTa/I2S0_TX_BCLK
**                Pin signal                               : 
**              Interrupt/DMA                              : 
**                Interrupt                                : INT_FTM0
**                Channel interrupt                        : Disabled
**                DMA request                              : Disabled
**            Channel 3                                    : Enabled
**              Channel mode                               : Center-aligned PWM
**                PWM polarity                             : High-true
**                Channel value register                   : 800
**              Input capture filter                       : Disabled
**              Software output control                    : Disabled
**              Pin                                        : Enabled
**                Pin                                      : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/NFC_DATA8/CMP1_OUT/I2S1_TX_BCLK
**                Pin signal                               : 
**              Interrupt/DMA                              : 
**                Interrupt                                : INT_FTM0
**                Channel interrupt                        : Disabled
**                DMA request                              : Disabled
**            Channel 4                                    : Enabled
**              Channel mode                               : Center-aligned PWM
**                PWM polarity                             : High-true
**                Channel value register                   : 800
**              Software output control                    : Disabled
**              Pin                                        : Enabled
**                Pin                                      : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/FBa_AD2/NFC_DATA1/EWM_IN
**                Pin signal                               : 
**              Interrupt/DMA                              : 
**                Interrupt                                : INT_FTM0
**                Channel interrupt                        : Disabled
**                DMA request                              : Disabled
**            Channel 5                                    : Enabled
**              Channel mode                               : Center-aligned PWM
**                PWM polarity                             : High-true
**                Channel value register                   : 800
**              Software output control                    : Disabled
**              Pin                                        : Enabled
**                Pin                                      : ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/UART0_COL_b/FTM0_CH5/FBa_AD1/NFC_DATA0/EWM_OUT_b
**                Pin signal                               : 
**              Interrupt/DMA                              : 
**                Interrupt                                : INT_FTM0
**                Channel interrupt                        : Disabled
**                DMA request                              : Disabled
**            Channel 6                                    : Disabled
**            Channel 7                                    : Disabled
**          Pins                                           : 
**            Fault pins                                   : 
**              Fault pin 0                                : Disabled
**              Fault pin 1                                : Disabled
**              Fault pin 2                                : Disabled
**              Fault pin 3                                : Disabled
**            External clock pin                           : Disabled
**            HW Synchronization triggers                  : 
**              Hardware Trigger 0                         : Disabled
**              Hardware Trigger 1                         : Disabled
**              Hardware Trigger 2                         : Disabled
**          Interrupts                                     : 
**            Channels / Timer overflow / Fault            : 
**              Interrupt                                  : INT_FTM0
**              Interrupt request                          : Enabled
**              Interrupt priority                         : 0 (Highest)
**              ISR Name                                   : PWM_interrupt
**              Channels interrupt/DMA                     : See the respective Channel settings
**              Timer overflow interrupt                   : Disabled
**              Fault interrupt                            : Disabled
**          Initialization                                 : 
**            Initialize the Channels Output               : yes
**            Load enable                                  : yes
**            Channel 0 load select                        : yes
**            Channel 1 load select                        : yes
**            Channel 2 load select                        : yes
**            Channel 3 load select                        : yes
**            Channel 4 load select                        : yes
**            Channel 5 load select                        : yes
**            Channel 6 load select                        : no
**            Channel 7 load select                        : no
**            Call Init method                             : yes
**     Contents    :
**         Init - void FTM0_Init(void);
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file FTM0.h
** @version 01.06
** @brief
**          This file implements the FTM (FTM0) module initialization
**          according to the Peripheral Initialization settings, and
**          defines interrupt service routines prototypes.
*/         
/*!
**  @addtogroup FTM0_module FTM0 module documentation
**  @{
*/         

#ifndef FTM0_H_
#define FTM0_H_

/* MODULE FTM0. */

/* Including shared modules, which are used in the whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
#include "Cpu.h"

/* Peripheral base address parameter */
#define FTM0_DEVICE FTM0_BASE_PTR


/*
** ===================================================================
**     Method      :  FTM0_Init (component Init_FTM)
**     Description :
**         This method initializes registers of the FTM module
**         according to the Peripheral Initialization settings.
**         Call this method in user code to initialize the module. By
**         default, the method is called by PE automatically; see "Call
**         Init method" property of the component for more details.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void FTM0_Init(void);
/*
** ===================================================================
** The interrupt service routine must be implemented by user in one
** of the user modules (see FTM0.c file for more information).
** ===================================================================
*/
//PE_ISR(PWM_interrupt);


/* END FTM0. */
#endif /* #ifndef __FTM0_H_ */
/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/tcp_prv.h<|end_filename|>
#ifndef __tcp_prv_h__
#define __tcp_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcp_prv.h$
* $Version : 3.8.10.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Internal definitions for the Transmission Control Protocol layer.
*
*END************************************************************************/


/************************************************************************/
/* Constants                                                            */
/************************************************************************/

/* bits of 'flags' of TCP_HEADER */
#define DATAOFS_MASK          0xf000
#define DATAOFS_SHIFT         12
#define URG                   0x0020
#define ACK                   0x0010
#define PSH                   0x0008
#define RST                   0x0004
#define SYN                   0x0002
#define FIN                   0x0001
#define TCP_RSRV_FIELD_MASK   0xF03F   /* mask off reserved field */

/* option kinds (following header; see RFC 793) - see also ip.h */
                              /* total length */

#define OPT_PAD           0
#define OPT_NOOP          1
#define OPT_MSS           2   /* 4 ; maximum segment size */
#define OPT_WINSCALE      3   /* 3 ; window scale (RFC 1072); unimplemented */
#define OPT_SACKPERM      4   /* 2 ; sack permit. (RFC 1072); unimplemented */
#define OPT_SACK          5   /* ? ; selective ack (RFC 1072); unimplemented*/
#define OPT_ECHO          6   /* 6 ; echo (RFC 1072); unimplemented */
#define OPT_ECHOREPLY     7   /* 6 ; echo reply (RFC 1072); unimplemented */
#define OPT_ALTCHK       14   /* 3 ; altern. checksum (RFC 1146); unimplem. */
#define OPT_ALTCHKDATA   15   /* ? ; alt chksum data (RFC 1146); unimplem. */

/* Delta of the user buffer size above the ring buffer size at which      */
/* to use the user buffer instead of the ring buffer.  This allows larger */
/* window sizes to be given to the remote host.  See comments in          */
/* TCP_Process_receive.                                                        */

#define TCP_SWITCH_THRESHOLD    1024   /* ring buffers are often around 4k */

/*  2k isn't quite enough, since it isn't even twice as big as the maximum
 *   segment size on an Ethernet (about 1400)
 */
#ifndef TCP_DEFAULT_SBSIZE
#define TCP_DEFAULT_SBSIZE      4380   /* Default TCB send buffer size */
#endif
#ifndef TCP_DEFAULT_RBSIZE
#define TCP_DEFAULT_RBSIZE      4380   /* Default TCB receive buffer size */
#endif

#define TCP_MSS_DEFAULT          536   /* Default Maximum segment size,
                                          per RFC 1122 section 4.2.2.6 */

#define TCP_WINDOW_MAX        0xFFFF   /* Largest possible send window */

/* all times in msecs */
#define TCP_INITIAL_RTO_DEFAULT 3000   /* Retransmission timeout when opening
                                          a connection, default 3 seconds
                                          as per RFC1122 */

#define TCP_RTO_MIN  (TICK_LENGTH*3)   /* Wait at least two ticks before
                                          retransmitting a packet; imposed
                                          by granularity of timer hardware
                                          (if we waited only one tick, the
                                          tick might expire right away...) */


#define TCP_MSL               120000L  /* Maximum Segment Lifetime; the
                                          longest time that a packet can
                                          travel in the Internet (2 min) */
#define TCP_WAITTIMEOUT (2 * TCP_MSL)  /* timeout for TIME_WAIT state, defined
                                          as 2 * MSL (4 min) */
#define TCP_SENDTIMEOUT_MIN   100000L  /* as per RFC1122 4.2.3.5 */
#define TCP_OPENTIMEOUT_MIN   180000L  /* as per RFC1122 4.2.3.5 */


#define TCP_SWSDELAY               80   /* TCP_Delay before sending less-than-full
                                         data packet [...] */

#define TCP_DEFAULT_SECUREDRAFT_0  FALSE /* default choice about wether to invoke behaviour 
                                            of draft-ietf-tcpm-tcpsecure-00.txt */

/*  We don't currently send any IP options (but should be able to);
 *   upper limit for IP header size is 64, so TCP_IPOPTIONS_MAX can be
 *   at most 64 - IP_HEADSIZE = 44
 */
#define TCP_IPOPTIONS_MAX          0
#define TCP_HEADSIZE              20
#define TCP_OPTIONS_MAX            4   /* we only add the MSS option (and
                                          then, only when sending SYN);
                                          upper limit for TCP header size
                                          is 64, so this can be at most
                                          64-TCP_HEADSIZE = 44 */

/* TCB states */
#define LISTEN         0
#define SYN_SENT       1
#define SYN_RECEIVED   2
#define ESTABLISHED    3
#define FINWAIT_1      4
#define FINWAIT_2      5
#define CLOSE_WAIT     6
#define CLOSING        7
#define LAST_ACK       8
#define TIME_WAIT      9
#define CLOSED        10
#define BOUND         11

/* a TCB (in this implem.) is never in CLOSED state "before" being opened; once closed,
a TCB may be deleted, but not reused */

#define UNKNOWNSTATE  12 /* must be greater than any state nb */

/* TCP output processing states */
#define TCP_IDLE     0
#define TCP_PROBE    1
#define TCP_XMIT     2

/************************************************************************/
/* Macros                                                               */
/************************************************************************/

/* Comparisons in modulo 2**32 sequence-number arithmetic: (RFC sec.3.3)
 *  assumes parameters are 32-bit sequence numbers
 *
 * Since you may find modulo comparisons ambiguous:  when comparing
 *  against a 32-bit number x, the 32-bit sequence space is divided in
 *  three with respect to x, that is:
 *
 *    range  x+1 to x+0x7fffffff ,        (said to be "greater than x")
 *    range  x+0x80000000 to x-1 , and    (said to be "less than x")
 *    x itself                            (said to be "equal to x" :-) ).
 *
 * For example, if x is 0xe1112131:
 *
 *    0xe1112132 to 0xffffffff and 0 to 0x61112130 (are "greater than x")
 *    0x61112131 to 0xe1112130                     (are "less than x").
 *
 * All this is perfectly ok since windows are of maximum size 64K which
 *  is many orders of magnitude smaller than 2^31...  (there's a bit more
 *  to this but that's basically it)
 */
#define GT32(a,b)      ((int_32)((a)-(b)) >  0)    /* a >  b */
#define GE32(a,b)      ((int_32)((a)-(b)) >= 0)    /* a >= b */
#define LT32(a,b)      ((int_32)((a)-(b)) <  0)    /* a <  b */
#define LE32(a,b)      ((int_32)((a)-(b)) <= 0)    /* a <= b */

/*  Security and precedence are not implemented; these are macros that
 *   are called where something must be done to implement them.
 */

/* if packet's security/compartment doesn't match
 *  that of tcb, send reset and return
 */
#define CHECK_SECURITY  DEBUGTCP(printf("\nTCP: Check Security");)

/* if packet's security/compartment doesn't match
 *  that of tcb, send reset, delete tcb with ECONNRESET and return
 */
#define CHECK_TIGHT_SECURITY  DEBUGTCP(printf("\nTCP: Check Tight Security");)

/* if packet's precedence is greater than tcb's, and system & user allow it,
 *  set tcb's precedence to that of packet; if not allowed, send reset & return.
 * (do nothing if packet's precedence is equal or lower)
 */
#define CHECK_PRECEDENCE   DEBUGTCP(printf("\nTCP: Check Precedence");)

/* if packet's precedence doesn't exactly match tcb's, send reset & return.
 */
#define CHECK_EXACT_PRECEDENCE   DEBUGTCP(printf("\nTCP: Check Exact Precedence");)

/*  Events which are not "state", and may occur more than once, and thus
 *   should automatically be cleared (from tcb->options) after being
 *   returned to client task.
 */
#define TCPS_REOCCURRING  (TCPS_TREADY | TCPS_TACKED | TCPS_TIMEOUT | \
                           TCPS_SOFTERROR | TCPS_NOWAIT | TCPS_DEFER)

/*  Events which are "state", and are only set once during connection lifetime,
 *   then never cleared.
 */
#define TCPS_SETONCE      (TCPS_STARTED | TCPS_FINACKED | TCPS_FINRECV |\
                           TCPS_FINDONE | TCPS_FINTOSEND)

/*  Useful state groups.
 */
#define TCPSTATE_FINSENT(state)  ((state)==FINWAIT_1 || (state)==FINWAIT_2|| \
                                  (state)==CLOSING   || (state)==TIMEWAIT || \
                                  (state)==CLOSED)
#define TCPSTATE_FINACKED(state) ((state)==FINWAIT_2 || (state)==TIMEWAIT || \
                                  (state)==CLOSED)
#define TCPSTATE_FINRECV(state)  ((state)==CLOSEWAIT || (state)==LASTACK  || \
                                  (state)==CLOSING   || (state)==TIMEWAIT || \
                                  (state)==CLOSED)
#define TCPSTATE_TCLOSED(state)  ((state)==FINWAIT_2 || (state)==TIMEWAIT || \
                                  (state)==CLOSED)
#define TCPSTATE_RCLOSED(state)  TCPSTATE_FINRECV(state)
#define TCPSTATE_STARTED(state)  ((state)==ESTABLISHED || \
                                  (state)==FINWAIT_1 || (state)==FINWAIT_2|| \
                                  (state)==CLOSEWAIT || (state)==LASTACK  || \
                                  (state)==CLOSING   || (state)==TIMEWAIT || \
                                  (state)==CLOSED)

#define TCP_DROP     {IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_DISCARDED++); /* Used in TCP_Service_packet*/ \
                      DEBUGTCP(printf("\nTCP_Service_packet: Dropping packet")); \
                      goto tcp_sp_drop; }

#define TCP_PP_DROP  {IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_DISCARDED++); /* Used in TCP_Process_packet */ \
                      DEBUGTCP(printf("\nTCP_Process_packet: Dropping packet")); \
                      goto tcp_pp_drop; }

#define TCP_PO_FAIL(ecode)  { result = (ecode); /* Used in TCP_Process_open */ \
                              DEBUGTCP(printf("\nTCP_Process_open: Failing")); \
                              goto failopen; }

#define TCP_PS_REPLY(ecode) { result = (ecode); /* Used in TCP_Process_send */ \
                              DEBUGTCP(printf("\nTCP_Process_send: Replying (result=%x)",result)); \
                              goto reply_send; }

#define TCB_HALF_OPEN_DROP { \
                              uint_32 tcb_cnt; \
                              for (tcb_cnt = 0; tcb_cnt < tcp_cfg->HALF_OPEN_TCB_COUNT; tcb_cnt++) { \
                                 if (tcb == tcp_cfg->HALF_OPEN_TCB_LIST[tcb_cnt]) { \
                                    tcp_cfg->HALF_OPEN_TCB_COUNT--; \
                                    tcp_cfg->HALF_OPEN_TCB_LIST[tcb_cnt] = \
                                    tcp_cfg->HALF_OPEN_TCB_LIST[tcp_cfg->HALF_OPEN_TCB_COUNT]; \
                                    break; \
                                 } /* Endif */ \
                              } /* Endfor */ \
                           }


/************************************************************************/
/* Typedefs                                                             */
/************************************************************************/

/*  Header of a TCP packet
 */
typedef struct tcp_header {              /* see RFC sec.3.1 */

   uchar    source_port[2];   /* source TCP port number */
   uchar    dest_port[2];     /* destination TCP port number */
   uchar    seq[4];           /* of 1st data octet or 1st-1 if (flags & SYN)*/
   uchar    ack[4];           /* valid if (flags & ACK) */
   uchar    flags[2];         /* see flags values above */
   uchar    window[2];        /* nb of bytes recipient of packet can send */
   uchar    checksum[2];      /* (see RFC) */
   uchar    urgent[2];        /* offset from seq, valid if (flags & URG) */
                              /* then follow options in 4-byte multiples, */
                              /* then data  */

} TCP_HEADER, _PTR_ TCP_HEADER_PTR; /* 20 bytes */

/************************************************************************/
/* Functions                                                            */
/************************************************************************/

/*******************************/
/* From tcp.c                  */
/*******************************/

extern void TCP_Event
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   int_16                  /* IN     - event that occurred */
);

extern void TCP_Return_open
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   uint_32              ,  /* IN     - reason code for returning */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer constants */
);

extern TCB_STRUCT_PTR TCP_Clone_tcb
(
   TCB_STRUCT_PTR          /* IN = the listening TCB to clone */
);

extern void TCP_Process_packet
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   RTCSPCB_PTR          ,  /* IN/OUT - the incoming packet */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer constants */
);

#if RTCSCFG_ENABLE_IP6 
extern void TCP6_Process_packet
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   RTCSPCB_PTR          ,  /* IN/OUT - the incoming packet */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer constants */
);
#endif




/*******************************/
/* From tcp_buf.c              */
/*******************************/

extern uint_32 TCP_Copy_to_ring
(
            uchar _PTR_ ,  /* IN - source data buffer */
            uint_32     ,  /* IN - size of data */
   register int_32      ,  /* IN - where in ring to put data */
            uchar _PTR_ ,  /* IN - start of ring buffer */
            uint_32        /* IN - total size of ring buffer */
);

extern uint_32 TCP_Copy_from_ring
(
            uchar _PTR_ ,  /* IN - destination buffer */
            uint_32     ,  /* IN - size of data at ringofs */
   register int_32      ,  /* IN - offset within ring buffer */
            uchar _PTR_ ,  /* IN - source ring buffer */
            uint_32        /* IN - ring buffer total size */
);

extern uint_32 TCP_Copy_from_buffer
(
   TCB_STRUCT_PTR tcb,     /* IN - TCP context */
   uchar_ptr      data,    /* IN - destination buffer */
   uint_32_ptr    size_ptr,/* IN/OUT - number of bytes to copy */
   uint_32        offset,  /* IN - offset from start of transmit buffer */
   RTCSPCB_PTR    pcb_ptr  /* IN - PCB used to send the packet */
);

extern uint_32 TCP_Copy_to_Rbuffer
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   uint_32              ,  /* IN     - destination offset from
                                       rcvpos in rcvbuf */
   uchar _PTR_          ,  /* IN     - source data */
   uint_32              ,  /* IN     - size of data */
   uchar _PTR_          ,  /* IN     - receive buffer */
   uint_32              ,  /* IN     - total size of rcv buffer */
   uint_32              ,  /* In     - current position in rcvbuf */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer data */
);

extern uint_32 TCP_Use_ringbuffer
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer data */
);

/*******************************/
/* From tcp_rcv.c              */
/*******************************/

extern void  TCP_Must_send_ack
(
   TCB_STRUCT_PTR       ,     /* IN/OUT - TCP layer context */
   TCP_CFG_STRUCT_PTR         /* IN     - TCP layer data */
);

extern void TCP_Advance_receive_user
(
   TCB_STRUCT_PTR       ,     /* IN/OUT - TCP context */
   int_32                     /* IN     - no. of bytes given to user */
);

extern void TCP_Truncate_receive_chunks
(
   TCB_STRUCT_PTR       ,     /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR   ,     /* IN/OUT - TCP layer data */
   int_32                     /* IN     - length of data to remove */
);

extern void TCP_Advertise_receive_window
(
   TCB_STRUCT_PTR       ,     /* IN/OUT - TCP layer context */
   TCP_CFG_STRUCT_PTR         /* IN/OUT - TCP layer data */
);

extern void TCP_Start_receiving
(
   TCB_STRUCT_PTR       ,     /* IN/OUT - TCP layer context */
   uint_32              ,     /* IN     - initial receive sequence */
   TCP_CFG_STRUCT_PTR         /* IN/OUT - TCP layer data */
);

extern void TCP_Reply_receive
(
   TCB_STRUCT_PTR       ,     /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR   ,     /* IN/OUT - TCP layer data */
   int_32                     /* IN     - error code to return */
);

extern boolean TCP_Test_done_receive
(
   TCB_STRUCT_PTR          tcb,     /* IN/OUT - TCP context */
   uint_32                 status,  /* IN     - error code  */
   TCP_CFG_STRUCT_PTR      tcp_cfg  /* IN/OUT - TCP layer data */
);

extern void TCP_Process_data
(
   TCB_STRUCT_PTR       ,     /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR   ,     /* IN/OUT - TCP layer data */
   TCP_HEADER _PTR_     ,     /* IN     - data within packet */
   RTCSPCB_PTR                /* IN     - the packet */
);

extern boolean  TCP_Setup_receive
(
   TCP_PARM_PTR            ,  /* IN/OUT - the Receive request */
   TCB_STRUCT_PTR          ,  /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR         /* IN/OUT - TCP layer data */
);

/*******************************/
/* From tcp_send.c             */
/*******************************/

extern void TCP_Update_send_window
(
   TCB_STRUCT_PTR    ,     /* IN/OUT - TCP context */
   TCP_HEADER _PTR_        /* IN     - the incoming ACK packet */
);

extern SndClock _PTR_ TCP_Process_RTT_measure
(
   TCB_STRUCT_PTR    ,     /* IN/OUT - TCP context */
   int_32                  /* IN     - time packet was received */
);

#if RTCSCFG_ENABLE_IP6 
extern uint_32 TCP6_Send_IP_packet
(
   RTCSPCB_PTR          pcb,         /* IN/OUT - packet to send */
   in6_addr            *srchost,    /* IN     - IPv6 source address */
   in6_addr            *desthost,   /* IN     - IPv6 dest address */
   boolean              bypass      /* IN     - TRUE to bypass checksum */
);
#endif

extern uint_32 TCP_Send_IP_packet
(
   RTCSPCB_PTR          rtcs_pcb,   /* IN/OUT - packet to send */
   _ip_address          srchost,    /* IN     - source address */
   _ip_address          desthost,   /* IN     - dest address */
   boolean              bypass      /* IN     - TRUE to bypass checksum */
);

extern void TCP_Send_packet
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP layer context */
   uint_32              ,  /* IN     - data sequence number */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer constants */
);

extern void TCP_Send_reply_reset
(
   TCB_STRUCT_PTR       tcb,        /* IN/OUT - TCP context */
   _ip_address          source,     /* IN     - destination for reset */
   TCP_HEADER _PTR_     received,   /* IN     - received TCP packet */
   uint_16              rlen,       /* IN     - length of received packet */
   TCP_CFG_STRUCT_PTR   tcp_cfg,    /* IN/OUT - TCP layer constants */
   boolean              bypass_chk  /* IN     - TRUE to bypass checksum */
);

#if RTCSCFG_ENABLE_IP6
extern void TCP6_Send_reply_reset
(
   TCB_STRUCT_PTR       tcb,        /* IN/OUT - TCP context */
   in6_addr            *source,     /* IN     - IPv6 destination for reset */
   TCP_HEADER _PTR_     received,   /* IN     - received TCP packet */
   uint_16              rlen,       /* IN     - length of received packet */
   TCP_CFG_STRUCT_PTR   tcp_cfg,    /* IN/OUT - TCP layer constants */
   boolean              bypass_chk  /* IN     - TRUE to bypass checksum */
);
#endif

extern void TCP_Send_reset
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer constants */
);

extern void TCP_Send_keepalive
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer constants */
);

extern void TCP_Transmit
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP layer context */
   TCP_CFG_STRUCT_PTR   ,  /* IN/OUT - TCP layer constants */
   boolean              ,  /* IN     - Should reset trans. ptr? */
   boolean                 /* IN     - Guarantee send? */
);

extern void TCP_Start_sending
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP layer context */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer data */
);

extern void TCP_Process_ack
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   TCP_HEADER _PTR_     ,  /* IN     - packet header */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer data */
);

/*******************************/
/* From tcp_clos.c             */
/*******************************/

extern void TCP_Free_TCB
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer data */
);

extern void TCP_Close_TCB
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   int_32               ,  /* IN     - error code to return */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer data */
);

extern void TCP_Process_effective_close
(
   TCB_STRUCT_PTR       ,  /* IN/OUT - TCP context */
   TCP_CFG_STRUCT_PTR      /* IN     - TCP layer data */
);

extern void TCP_Process_release
(
   TCB_STRUCT_PTR       ,  /* IN     - TCP context */
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer data */
);

void TCP_half_open_TCB_close
(
   TCP_CFG_STRUCT_PTR      /* IN/OUT - TCP layer data */
);

#endif

/*******************************/
/* DEBUGGING Macros            */
/*******************************/
#define dprintf(x)  printf x

/*
** Uncomment to enable TCP Debugging

#define DO_TCP_STATE_DEBUG 0
#define DO_TCP_TCB_DEBUG 0

*/

#ifdef DO_TCP_STATE_DEBUG
#define TCP_STATE_DEBUG(x) { printf ("TCPSTATE %s(%d): ", __FUNCTION__, __LINE__); printf x ;}
#else
#define TCP_STATE_DEBUG(x) 
#endif


#ifdef DO_TCP_TCB_DEBUG
#define TCP_TCB_DEBUG(x) { printf ("TCP:TCB %s(%d): ", __FUNCTION__, __LINE__); printf x ;}
#else
#define TCP_TCB_DEBUG(x) 
#endif



/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/serplprv.h<|end_filename|>
#ifndef __serplprv_h__
#define __serplprv_h__
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serplprv.h$
* $Version : 3.8.7.0$
* $Date    : Sep-1-2011$
*
* Comments:
*
*   This file includes the private definitions for the polled serial I/O
*   drivers.
*
*END************************************************************************/

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/*
** Xon/Xoff protocol characters
*/
#define CNTL_S   ((char) 0x13)  /* Control S == XOFF.   */
#define CNTL_Q   ((char) 0x11)  /* Control Q == XON.    */

/*--------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/


/*---------------------------------------------------------------------
**
** IO SERIAL POLLED DEVICE STRUCT
**
** This structure used to store information about a polled serial io device
** for the IO device table.
*/
typedef struct io_serial_polled_device_struct
{

   /* The I/O init function */
   _mqx_uint (_CODE_PTR_ DEV_INIT)(pointer, pointer _PTR_, char _PTR_);

   /* The I/O deinit function */
   _mqx_uint (_CODE_PTR_ DEV_DEINIT)(pointer, pointer);

   /* The input function */
   char    (_CODE_PTR_ DEV_GETC)(pointer);

   /* The output function */
   void    (_CODE_PTR_ DEV_PUTC)(pointer, char);

   /* The status function, (character available) */
   boolean (_CODE_PTR_ DEV_STATUS)(pointer);

   /* The ioctl function, (change bauds etc) */
   _mqx_uint (_CODE_PTR_ DEV_IOCTL)(pointer, _mqx_uint, pointer);

   /* The I/O channel initialization data */
   pointer             DEV_INIT_DATA_PTR;

   /* Device specific information */
   pointer             DEV_INFO_PTR;

   /* The queue size to use */
   _mqx_uint             QUEUE_SIZE;

   /* Open count for number of accessing file descriptors */
   _mqx_uint             COUNT;

   /* Open flags for this channel */
   _mqx_uint             FLAGS;

   /* The Character Queue Ring buffer, for input buffering */
   CHARQ_STRUCT_PTR    CHARQ;

#if MQX_ENABLE_LOW_POWER

   /* Low power related state information */
   IO_SERIAL_LPM_STRUCT LPM_INFO;

#endif

} IO_SERIAL_POLLED_DEVICE_STRUCT, _PTR_ IO_SERIAL_POLLED_DEVICE_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

/*
** Polled I/O prototypes
*/
extern _mqx_int _io_serial_polled_open(MQX_FILE_PTR, char _PTR_, char _PTR_);
extern _mqx_int _io_serial_polled_close(MQX_FILE_PTR);
extern _mqx_int _io_serial_polled_read(MQX_FILE_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_serial_polled_write(MQX_FILE_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_serial_polled_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);
extern _mqx_int _io_serial_polled_uninstall(IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio_kgpio.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio_kgpio.h$
* $Version : 3.8.6.0$
* $Date    : Sep-22-2011$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/
#ifndef __lwgpio_kgpio_h__
#define __lwgpio_kgpio_h__ 1

#define LWGPIO_PIN_VALID (0x80000000) /* Note: this is for backwards compatibility with GPIO driver only */

/* Pin field definitions */
#define LWGPIO_PIN_SHIFT (0)
#define LWGPIO_PIN_MASK (0x1F << LWGPIO_PIN_SHIFT)

#define LWGPIO_PIN(x) (((x) << LWGPIO_PIN_SHIFT) & LWGPIO_PIN_MASK)

/* Pin attributes */
#define LWGPIO_ATTR_BASE            (0x100)
#define LWGPIO_ATTR_SLEW_RATE       (LWGPIO_ATTR_BASE+1)
#define LWGPIO_ATTR_FILTER          (LWGPIO_ATTR_BASE+2)
#define LWGPIO_ATTR_DRIVE_STRENGTH  (LWGPIO_ATTR_BASE+3)

/*attributes value*/
#define LWGPIO_AVAL_SLEW_RATE_FAST          (0)
#define LWGPIO_AVAL_SLEW_RATE_SLOW          (1)
#define LWGPIO_AVAL_DRIVE_STRENGTH_HIGH     (1)
#define LWGPIO_AVAL_DRIVE_STRENGTH_LOW      (0)

/* Port field definitions */
#define LWGPIO_PORT_SHIFT (5)
#define LWGPIO_PORT_MASK (0xFF << LWGPIO_PORT_SHIFT)
#define LWGPIO_PORT(x) (((x) << LWGPIO_PORT_SHIFT) & LWGPIO_PORT_MASK)
#define LWGPIO_PORT_A (LWGPIO_PORT(0) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_B (LWGPIO_PORT(1) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_C (LWGPIO_PORT(2) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_D (LWGPIO_PORT(3) | LWGPIO_PIN_VALID)
#define LWGPIO_PORT_E (LWGPIO_PORT(4) | LWGPIO_PIN_VALID)

#define LWGPIO_PIN0   (0)
#define LWGPIO_PIN1   (1)
#define LWGPIO_PIN2   (2)
#define LWGPIO_PIN3   (3)
#define LWGPIO_PIN4   (4)
#define LWGPIO_PIN5   (5)
#define LWGPIO_PIN6   (6)
#define LWGPIO_PIN7   (7)
#define LWGPIO_PIN8   (8)
#define LWGPIO_PIN9   (9)
#define LWGPIO_PIN10  (10)
#define LWGPIO_PIN11  (11)
#define LWGPIO_PIN12  (12)
#define LWGPIO_PIN13  (13)
#define LWGPIO_PIN14  (14)
#define LWGPIO_PIN15  (15)
#define LWGPIO_PIN16  (16)
#define LWGPIO_PIN17  (17)
#define LWGPIO_PIN18  (18)
#define LWGPIO_PIN19  (19)
#define LWGPIO_PIN20  (20)
#define LWGPIO_PIN21  (21)
#define LWGPIO_PIN22  (22)
#define LWGPIO_PIN23  (23)
#define LWGPIO_PIN24  (24)
#define LWGPIO_PIN25  (25)
#define LWGPIO_PIN26  (26)
#define LWGPIO_PIN27  (27)
#define LWGPIO_PIN28  (28)
#define LWGPIO_PIN29  (29)
#define LWGPIO_PIN30  (30)
#define LWGPIO_PIN31  (31)

typedef struct {
    uint_32_ptr    pcr_reg;
    GPIO_MemMapPtr gpio_ptr;
    uint_32 pinmask; /* since struct holds one pin, pinmask will have only one bit set */
    uint_32 flags;
} LWGPIO_STRUCT, _PTR_ LWGPIO_STRUCT_PTR;

#define LWGPIO_MUX_A0_GPIO  (1)
#define LWGPIO_MUX_A1_GPIO  (1)
#define LWGPIO_MUX_A2_GPIO  (1)
#define LWGPIO_MUX_A3_GPIO  (1)
#define LWGPIO_MUX_A4_GPIO  (1)
#define LWGPIO_MUX_A5_GPIO  (1)
#define LWGPIO_MUX_A6_GPIO  (1)
#define LWGPIO_MUX_A7_GPIO  (1)
#define LWGPIO_MUX_A8_GPIO  (1)
#define LWGPIO_MUX_A9_GPIO  (1)
#define LWGPIO_MUX_A10_GPIO (1)
#define LWGPIO_MUX_A11_GPIO (1)
#define LWGPIO_MUX_A12_GPIO (1)
#define LWGPIO_MUX_A13_GPIO (1)
#define LWGPIO_MUX_A14_GPIO (1)
#define LWGPIO_MUX_A15_GPIO (1)
#define LWGPIO_MUX_A16_GPIO (1)
#define LWGPIO_MUX_A17_GPIO (1)
#define LWGPIO_MUX_A18_GPIO (1)
#define LWGPIO_MUX_A19_GPIO (1)
#define LWGPIO_MUX_A20_GPIO (1)
#define LWGPIO_MUX_A21_GPIO (1)
#define LWGPIO_MUX_A22_GPIO (1)
#define LWGPIO_MUX_A23_GPIO (1)
#define LWGPIO_MUX_A24_GPIO (1)
#define LWGPIO_MUX_A25_GPIO (1)
#define LWGPIO_MUX_A26_GPIO (1)
#define LWGPIO_MUX_A27_GPIO (1)
#define LWGPIO_MUX_A28_GPIO (1)
#define LWGPIO_MUX_A29_GPIO (1)
#define LWGPIO_MUX_A30_GPIO (1)
#define LWGPIO_MUX_A31_GPIO (1)

#define LWGPIO_MUX_B0_GPIO  (1)
#define LWGPIO_MUX_B1_GPIO  (1)
#define LWGPIO_MUX_B2_GPIO  (1)
#define LWGPIO_MUX_B3_GPIO  (1)
#define LWGPIO_MUX_B4_GPIO  (1)
#define LWGPIO_MUX_B5_GPIO  (1)
#define LWGPIO_MUX_B6_GPIO  (1)
#define LWGPIO_MUX_B7_GPIO  (1)
#define LWGPIO_MUX_B8_GPIO  (1)
#define LWGPIO_MUX_B9_GPIO  (1)
#define LWGPIO_MUX_B10_GPIO (1)
#define LWGPIO_MUX_B11_GPIO (1)
#define LWGPIO_MUX_B12_GPIO (1)
#define LWGPIO_MUX_B13_GPIO (1)
#define LWGPIO_MUX_B14_GPIO (1)
#define LWGPIO_MUX_B15_GPIO (1)
#define LWGPIO_MUX_B16_GPIO (1)
#define LWGPIO_MUX_B17_GPIO (1)
#define LWGPIO_MUX_B18_GPIO (1)
#define LWGPIO_MUX_B19_GPIO (1)
#define LWGPIO_MUX_B20_GPIO (1)
#define LWGPIO_MUX_B21_GPIO (1)
#define LWGPIO_MUX_B22_GPIO (1)
#define LWGPIO_MUX_B23_GPIO (1)
#define LWGPIO_MUX_B24_GPIO (1)
#define LWGPIO_MUX_B25_GPIO (1)
#define LWGPIO_MUX_B26_GPIO (1)
#define LWGPIO_MUX_B27_GPIO (1)
#define LWGPIO_MUX_B28_GPIO (1)
#define LWGPIO_MUX_B29_GPIO (1)
#define LWGPIO_MUX_B30_GPIO (1)
#define LWGPIO_MUX_B31_GPIO (1)

#define LWGPIO_MUX_C0_GPIO  (1)
#define LWGPIO_MUX_C1_GPIO  (1)
#define LWGPIO_MUX_C2_GPIO  (1)
#define LWGPIO_MUX_C3_GPIO  (1)
#define LWGPIO_MUX_C4_GPIO  (1)
#define LWGPIO_MUX_C5_GPIO  (1)
#define LWGPIO_MUX_C6_GPIO  (1)
#define LWGPIO_MUX_C7_GPIO  (1)
#define LWGPIO_MUX_C8_GPIO  (1)
#define LWGPIO_MUX_C9_GPIO  (1)
#define LWGPIO_MUX_C10_GPIO (1)
#define LWGPIO_MUX_C11_GPIO (1)
#define LWGPIO_MUX_C12_GPIO (1)
#define LWGPIO_MUX_C13_GPIO (1)
#define LWGPIO_MUX_C14_GPIO (1)
#define LWGPIO_MUX_C15_GPIO (1)
#define LWGPIO_MUX_C16_GPIO (1)
#define LWGPIO_MUX_C17_GPIO (1)
#define LWGPIO_MUX_C18_GPIO (1)
#define LWGPIO_MUX_C19_GPIO (1)
#define LWGPIO_MUX_C20_GPIO (1)
#define LWGPIO_MUX_C21_GPIO (1)
#define LWGPIO_MUX_C22_GPIO (1)
#define LWGPIO_MUX_C23_GPIO (1)
#define LWGPIO_MUX_C24_GPIO (1)
#define LWGPIO_MUX_C25_GPIO (1)
#define LWGPIO_MUX_C26_GPIO (1)
#define LWGPIO_MUX_C27_GPIO (1)
#define LWGPIO_MUX_C28_GPIO (1)
#define LWGPIO_MUX_C29_GPIO (1)
#define LWGPIO_MUX_C30_GPIO (1)
#define LWGPIO_MUX_C31_GPIO (1)

#define LWGPIO_MUX_D0_GPIO  (1)
#define LWGPIO_MUX_D1_GPIO  (1)
#define LWGPIO_MUX_D2_GPIO  (1)
#define LWGPIO_MUX_D3_GPIO  (1)
#define LWGPIO_MUX_D4_GPIO  (1)
#define LWGPIO_MUX_D5_GPIO  (1)
#define LWGPIO_MUX_D6_GPIO  (1)
#define LWGPIO_MUX_D7_GPIO  (1)
#define LWGPIO_MUX_D8_GPIO  (1)
#define LWGPIO_MUX_D9_GPIO  (1)
#define LWGPIO_MUX_D10_GPIO (1)
#define LWGPIO_MUX_D11_GPIO (1)
#define LWGPIO_MUX_D12_GPIO (1)
#define LWGPIO_MUX_D13_GPIO (1)
#define LWGPIO_MUX_D14_GPIO (1)
#define LWGPIO_MUX_D15_GPIO (1)
#define LWGPIO_MUX_D16_GPIO (1)
#define LWGPIO_MUX_D17_GPIO (1)
#define LWGPIO_MUX_D18_GPIO (1)
#define LWGPIO_MUX_D19_GPIO (1)
#define LWGPIO_MUX_D20_GPIO (1)
#define LWGPIO_MUX_D21_GPIO (1)
#define LWGPIO_MUX_D22_GPIO (1)
#define LWGPIO_MUX_D23_GPIO (1)
#define LWGPIO_MUX_D24_GPIO (1)
#define LWGPIO_MUX_D25_GPIO (1)
#define LWGPIO_MUX_D26_GPIO (1)
#define LWGPIO_MUX_D27_GPIO (1)
#define LWGPIO_MUX_D28_GPIO (1)
#define LWGPIO_MUX_D29_GPIO (1)
#define LWGPIO_MUX_D30_GPIO (1)
#define LWGPIO_MUX_D31_GPIO (1)

#define LWGPIO_MUX_E0_GPIO  (1)
#define LWGPIO_MUX_E1_GPIO  (1)
#define LWGPIO_MUX_E2_GPIO  (1)
#define LWGPIO_MUX_E3_GPIO  (1)
#define LWGPIO_MUX_E4_GPIO  (1)
#define LWGPIO_MUX_E5_GPIO  (1)
#define LWGPIO_MUX_E6_GPIO  (1)
#define LWGPIO_MUX_E7_GPIO  (1)
#define LWGPIO_MUX_E8_GPIO  (1)
#define LWGPIO_MUX_E9_GPIO  (1)
#define LWGPIO_MUX_E10_GPIO (1)
#define LWGPIO_MUX_E11_GPIO (1)
#define LWGPIO_MUX_E12_GPIO (1)
#define LWGPIO_MUX_E13_GPIO (1)
#define LWGPIO_MUX_E14_GPIO (1)
#define LWGPIO_MUX_E15_GPIO (1)
#define LWGPIO_MUX_E16_GPIO (1)
#define LWGPIO_MUX_E17_GPIO (1)
#define LWGPIO_MUX_E18_GPIO (1)
#define LWGPIO_MUX_E19_GPIO (1)
#define LWGPIO_MUX_E20_GPIO (1)
#define LWGPIO_MUX_E21_GPIO (1)
#define LWGPIO_MUX_E22_GPIO (1)
#define LWGPIO_MUX_E23_GPIO (1)
#define LWGPIO_MUX_E24_GPIO (1)
#define LWGPIO_MUX_E25_GPIO (1)
#define LWGPIO_MUX_E26_GPIO (1)
#define LWGPIO_MUX_E27_GPIO (1)
#define LWGPIO_MUX_E28_GPIO (1)
#define LWGPIO_MUX_E29_GPIO (1)
#define LWGPIO_MUX_E30_GPIO (1)
#define LWGPIO_MUX_E31_GPIO (1)

#endif


<|start_filename|>Firmware/Inverter_bootloader/BSP/PE/Cpu.c<|end_filename|>
#include "app_cfg.h"
#include "CPU.h"
#include "PE_Error.h"

#ifdef __cplusplus
extern "C"
{
#endif

/* Symbols representing MCG modes */
#define MCG_MODE_FBI                    0x00U
#define MCG_MODE_BLPI                   0x01U
#define MCG_MODE_FBE                    0x02U
#define MCG_MODE_PBE                    0x03U
#define MCG_MODE_PEE                    0x04U
static const uint8_t MCGTransitionMatrix[5][5] = {
/* This matrix defines which mode is next in the MCG Mode state diagram in transitioning from the
   current mode to a target mode*/
  {  MCG_MODE_FBI,  MCG_MODE_BLPI,  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_FBE }, /* FBI */
  {  MCG_MODE_FBI,  MCG_MODE_BLPI,  MCG_MODE_FBI,  MCG_MODE_FBI,  MCG_MODE_FBI }, /* BLPI */
  {  MCG_MODE_FBI,  MCG_MODE_FBI,  MCG_MODE_FBE,  MCG_MODE_PBE,  MCG_MODE_PBE }, /* FBE */
  {  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_PBE,  MCG_MODE_PEE }, /* PBE */
  {  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PEE }  /* PEE */
};

/* Global variables */
volatile uint8_t SR_reg;               /* Current value of the FAULTMASK register */
volatile uint8_t SR_lock = 0x00U;      /* Lock */
static uint8_t ClockConfigurationID = CPU_CLOCK_CONFIG_0; /* Active clock configuration */

/*
** ===================================================================
**     Method      :  Cpu_LDD_SetClockConfiguration (component MK60FN1M0LQ15)
*/
/*!
**     @brief
**         Changes the clock configuration of all LDD components in a 
**         project.
**     @param
**       ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method.
*/
/* ===================================================================*/
extern void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration);

/*
** ===================================================================
**     Method      :  Cpu_SetBASEPRI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the BASEPRI core register.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
void Cpu_SetBASEPRI(uint32_t Level);

/*
** ===================================================================
**     Method      :  Cpu_MCGAutoTrim (component MK60FN1M0LQ15)
**     Description :
**         This method uses MCG auto trim feature to trim internal
**         reference clock. This method can be used only in a clock
**         configuration which derives its bus clock from external
**         reference clock (<MCG mode> must be one of the following
**         modes - FEE, FBE, BLPE, PEE, PBE) and if value of <Bus clock>
**         is in the range <8; 16>MHz.
**         The slow internal reference clock is trimmed to the value
**         selected by <Slow internal reference clock [kHz]> property. 
**         The fast internal reference clock will be trimmed to value
**         4MHz.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ClockSelect     - Selects which internal
**                           reference clock will be trimmed.
**                           0 ... slow (32kHz) internal reference clock
**                           will be trimmed
**                           > 0 ... fast (4MHz) internal reference
**                           clock will be trimmed
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_SPEED - The method does not work in the
**                           active clock configuration.
**                           ERR_FAILED - Autotrim process failed.
** ===================================================================
*/
LDD_TError Cpu_MCGAutoTrim(uint8_t ClockSelect)
{
  switch (ClockConfigurationID)
  {
  case CPU_CLOCK_CONFIG_1:
    if ( ClockSelect == 0x00U )
    {
      /* Slow internal reference clock */
      MCG_ATCVH = 0x1EU;
      MCG_ATCVL = 0x0AU;
    }
    else
    {
      /* Fast internal reference clock */
      MCG_ATCVH = 0x1FU;
      MCG_ATCVL = 0x80U;
    }
    break;
  default:
    return ERR_SPEED;
  }
  if ( ClockSelect == 0x00U )
  {
    /* MCG_SC: ATME=1,ATMS=0 */
    MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                                                     MCG_SC_ATMS_MASK
                                                     )) | (uint8_t)(
                                                                    MCG_SC_ATME_MASK
                                                                    ));                       /* Start trimming of the slow internal reference clock */
  }
  else
  {
    /* MCG_SC: ATME=1,ATMS=1 */
    MCG_SC |= (MCG_SC_ATME_MASK | MCG_SC_ATMS_MASK); /* Start trimming of the fast internal reference clock */
  }
  while ((MCG_SC & MCG_SC_ATME_MASK) != 0x00U) /* Wait until autotrim completes */
  {}
  if ( (MCG_SC & MCG_SC_ATMF_MASK) == 0x00U )
  {
    return ERR_OK;                     /* Trim operation completed successfully */
  }
  else
  {
    return ERR_FAILED;                 /* Trim operation failed */
  }
}

/*
** ===================================================================
**     Method      :  Cpu_GetLLSWakeUpFlags (component MK60FN1M0LQ15)
**     Description :
**         This method returns the current status of the LLWU wake-up
**         flags indicating which wake-up source caused the MCU to exit
**         LLS or VLLSx low power mode.
**         The following predefined constants can be used to determine
**         the wake-up source:
**         LLWU_EXT_PIN0, ... LLWU_EXT_PIN15 - external pin 0 .. 15
**         caused the wake-up
**         LLWU_INT_MODULE0 .. LLWU_INT_MODULE7 - internal module 0..15
**         caused the wake-up.
**     Parameters  : None
**     Returns     :
**         ---             - Returns the current status of the LLWU
**                           wake-up flags indicating which wake-up
**                           source caused the MCU to exit LLS or VLLSx
**                           low power mode.
** ===================================================================
*/
uint32_t Cpu_GetLLSWakeUpFlags(void)
{
  uint32_t Flags;

  Flags = LLWU_F1;
  Flags |= (uint32_t)((uint32_t)LLWU_F2 << 8U);
  Flags |= (uint32_t)((uint32_t)LLWU_F3 << 16U);
  if ( (LLWU_FILT1 & 0x80U) != 0x00U )
  {
    Flags |= LLWU_FILTER1;
  }
  if ( (LLWU_FILT2 & 0x80U) != 0x00U )
  {
    Flags |= LLWU_FILTER2;
  }
  return Flags;
}

static void Cpu_SetMCGModePEE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePEE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PEE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModePBE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeFBE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeBLPI(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeBLPI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to BLPI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeFBI(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCG(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCG (component MK60FN1M0LQ15)
**
**     Description :
**         This method updates the MCG according the requested clock 
**         source setting.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static uint8_t Cpu_GetCurrentMCGMode(void);
/*
** ===================================================================
**     Method      :  Cpu_GetCurrentMCGMode (component MK60FN1M0LQ15)
**
**     Description :
**         This method returns the active MCG mode
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/


/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePEE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PEE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModePEE(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 0U:
    /* Switch to PEE Mode */
    /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
    OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
    /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = OSC_CR_ERCLKEN_MASK;
    /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_HGO0_MASK |
             MCG_C2_EREFS0_MASK |
             MCG_C2_IRCS_MASK;
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
    MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));
    while ((MCG_S & 0x0CU) != 0x0CU) /* Wait until output of the PLL is selected */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModePBE(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 0U:
    /* Switch to PBE Mode */
    /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
    OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
    /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = OSC_CR_ERCLKEN_MASK;
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_HGO0_MASK |
             MCG_C2_EREFS0_MASK |
             MCG_C2_IRCS_MASK;
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
    MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));
    while ((MCG_S & 0x0CU) != 0x08U) /* Wait until external reference clock is selected as MCG output */
    {}
    while ((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) /* Wait until PLL locked */
    {}
    break;
  case 1U:
    /* Switch to PBE Mode */
    /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
    OSC0_CR = (OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
    /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = 0x00U;
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_HGO0_MASK |
             MCG_C2_EREFS0_MASK |
             MCG_C2_IRCS_MASK;
    while ((MCG_S & 0x0CU) != 0x08U) /* Wait until external reference clock is selected as MCG output */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeFBE(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 0U:
    /* Switch to FBE Mode */
    /* MCG_C7: OSCSEL=0 */
    MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_HGO0_MASK |
             MCG_C2_EREFS0_MASK |
             MCG_C2_IRCS_MASK;
    /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
    OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
    /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = OSC_CR_ERCLKEN_MASK;
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
    MCG_C6 = MCG_C6_VDIV0(0x0E);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);
    while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) /* Check that the oscillator is running */
    {}
    while ((MCG_S & MCG_S_IREFST_MASK) != 0x00U) /* Check that the source of the FLL reference clock is the external reference clock. */
    {}
    while ((MCG_S & 0x0CU) != 0x08U) /* Wait until external reference clock is selected as MCG output */
    {}
    break;
  case 1U:
    /* Switch to FBE Mode */
    /* MCG_C7: OSCSEL=0 */
    MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_HGO0_MASK |
             MCG_C2_EREFS0_MASK |
             MCG_C2_IRCS_MASK;
    /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
    OSC0_CR = (OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
    /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = 0x00U;
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
    MCG_C6 = MCG_C6_VDIV0(0x00);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);
    while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) /* Check that the oscillator is running */
    {}
    while ((MCG_S & MCG_S_IREFST_MASK) != 0x00U) /* Check that the source of the FLL reference clock is the external reference clock. */
    {}
    while ((MCG_S & 0x0CU) != 0x08U) /* Wait until external reference clock is selected as MCG output */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeBLPI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to BLPI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeBLPI(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 1U:
    /* Switch to BLPI Mode */
    /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = MCG_C1_CLKS(0x01) |
             MCG_C1_FRDIV(0x00) |
             MCG_C1_IREFS_MASK |
             MCG_C1_IRCLKEN_MASK;
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=1,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_HGO0_MASK |
             MCG_C2_EREFS0_MASK |
             MCG_C2_LP_MASK |
             MCG_C2_IRCS_MASK;
    /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
    OSC0_CR = (OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
    /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = 0x00U;
    while ((MCG_S & MCG_S_IREFST_MASK) == 0x00U) /* Check that the source of the FLL reference clock is the internal reference clock. */
    {}
    while ((MCG_S & MCG_S_IRCST_MASK) == 0x00U) /* Check that the fast external reference clock is selected. */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeFBI(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 0U:
    /* Switch to FBI Mode */
    /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = MCG_C1_CLKS(0x01) |
             MCG_C1_FRDIV(0x00) |
             MCG_C1_IREFS_MASK |
             MCG_C1_IRCLKEN_MASK;
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_HGO0_MASK |
             MCG_C2_EREFS0_MASK |
             MCG_C2_IRCS_MASK;
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
    /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
    OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
    /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = OSC_CR_ERCLKEN_MASK;
    /* MCG_C7: OSCSEL=0 */
    MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
    MCG_C6 = MCG_C6_VDIV0(0x0E);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);       /* 7 */
    while ((MCG_S & MCG_S_IREFST_MASK) == 0x00U) /* Check that the source of the FLL reference clock is the internal reference clock. */
    {}
    while ((MCG_S & 0x0CU) != 0x04U) /* Wait until internal reference clock is selected as MCG output */
    {}
    break;
  case 1U:
    /* Switch to FBI Mode */
    /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = MCG_C1_CLKS(0x01) |
             MCG_C1_FRDIV(0x00) |
             MCG_C1_IREFS_MASK |
             MCG_C1_IRCLKEN_MASK;
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_HGO0_MASK |
             MCG_C2_EREFS0_MASK |
             MCG_C2_IRCS_MASK;
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
    /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
    OSC0_CR = (OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
    /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = 0x00U;
    /* MCG_C7: OSCSEL=0 */
    MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
    MCG_C6 = MCG_C6_VDIV0(0x00);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);       /* 7 */
    while ((MCG_S & MCG_S_IREFST_MASK) == 0x00U) /* Check that the source of the FLL reference clock is the internal reference clock. */
    {}
    while ((MCG_S & 0x0CU) != 0x04U) /* Wait until internal reference clock is selected as MCG output */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCG (component MK60FN1M0LQ15)
**
**     Description :
**         This method updates the MCG according the requested clock 
**         source setting.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCG(uint8_t CLKMode)
{
  uint8_t TargetMCGMode = 0x00U;
  uint8_t NextMCGMode;

  switch (CLKMode)
  {
  case 0U:
    TargetMCGMode = MCG_MODE_PEE;
    break;
  case 1U:
    TargetMCGMode = MCG_MODE_BLPI;
    break;
  default:
    break;
  }
  NextMCGMode = Cpu_GetCurrentMCGMode(); /* Identify the currently active MCG mode */
  do
  {
    NextMCGMode = MCGTransitionMatrix[NextMCGMode][TargetMCGMode]; /* Get the next MCG mode on the path to the target MCG mode */
    switch (NextMCGMode)             /* Set the next MCG mode on the path to the target MCG mode */
    {
    case MCG_MODE_FBI:
      Cpu_SetMCGModeFBI(CLKMode);
      break;
    case MCG_MODE_BLPI:
      Cpu_SetMCGModeBLPI(CLKMode);
      break;
    case MCG_MODE_FBE:
      Cpu_SetMCGModeFBE(CLKMode);
      break;
    case MCG_MODE_PBE:
      Cpu_SetMCGModePBE(CLKMode);
      break;
    case MCG_MODE_PEE:
      Cpu_SetMCGModePEE(CLKMode);
      break;
    default:
      break;
    }
  }
  while (TargetMCGMode != NextMCGMode); /* Loop until the target MCG mode is set */
}

/*
** ===================================================================
**     Method      :  Cpu_GetCurrentMCGMode (component MK60FN1M0LQ15)
**
**     Description :
**         This method returns the active MCG mode
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
uint8_t Cpu_GetCurrentMCGMode(void)
{
  switch (MCG_C1  & MCG_C1_CLKS_MASK)
  {
  case  0x00U:
    return MCG_MODE_PEE;
  case 0x40U:
    /* Internal reference clock is selected */
    if ( (MCG_C2 & MCG_C2_LP_MASK) == 0x00U )
    {
      /* Low power mode is disabled */
      return MCG_MODE_FBI;
    }
    else
    {
      /* Low power mode is enabled */
      return MCG_MODE_BLPI;
    }
  case 0x80U:
    if ( (MCG_C6 & MCG_C6_PLLS_MASK) == 0x00U )
    {
      /* FLL is selected */
      return MCG_MODE_FBE;
    }
    else
    {
      /* PLL is selected */
      return MCG_MODE_PBE;
    }
  default:
    return 0x00U;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetClockConfiguration (component MK60FN1M0LQ15)
**     Description :
**         Calling of this method will cause the clock configuration
**         change and reconfiguration of all components according to
**         the requested clock configuration setting.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ModeID          - Clock configuration identifier
**     Returns     :
**         ---             - ERR_OK - OK.
**                           ERR_RANGE - Mode parameter out of range
** ===================================================================
*/
LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID)
{
  if ( ModeID > 0x02U )
  {
    return ERR_RANGE;                  /* Undefined clock configuration requested requested */
  }
  switch (ModeID)
  {
  case CPU_CLOCK_CONFIG_0:
    if ( ClockConfigurationID == 2U )
    {
      /* Clock configuration 0 and clock configuration 2 use different clock configuration */
      /* MCG_C6: CME0=0 */
      MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
      /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
      SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                    SIM_CLKDIV1_OUTDIV2(0x03) |
                    SIM_CLKDIV1_OUTDIV3(0x07) |
                    SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
      if ( (MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U )
      {
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(MCG_SC_FCRDIV(0x06))) | (uint8_t)(MCG_SC_FCRDIV(0x01)));
      }
      else
      {
        /* MCG_C2: IRCS=0 */
        MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(MCG_SC_FCRDIV(0x06))) | (uint8_t)(MCG_SC_FCRDIV(0x01)));
        /* MCG_C2: IRCS=1 */
        MCG_C2 |= MCG_C2_IRCS_MASK;
      }
      Cpu_SetMCG(0U);                /* Update clock source setting */
      /* MCG_C6: CME0=1 */
      MCG_C6 |= MCG_C6_CME0_MASK;    /* Enable the clock monitor */
    }
    /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=2,OUTDIV4=5,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) |
                  SIM_CLKDIV1_OUTDIV2(0x01) |
                  SIM_CLKDIV1_OUTDIV3(0x02) |
                  SIM_CLKDIV1_OUTDIV4(0x05); /* Update system prescalers */
    /* SIM_SOPT2: PLLFLLSEL=1 */
    SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL(0x02))) | (uint32_t)(SIM_SOPT2_PLLFLLSEL(0x01)));                  /* Select PLL 0 as a clock source for various peripherals */
    /* SIM_SOPT1: OSC32KSEL=1 */
    SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; /* RTC oscillator drives 32 kHz clock for various peripherals */
    break;
  case CPU_CLOCK_CONFIG_1:
    if ( ClockConfigurationID == 2U )
    {
      /* Clock configuration 1 and clock configuration 2 use different clock configuration */
      /* MCG_C6: CME0=0 */
      MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
      /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
      SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                    SIM_CLKDIV1_OUTDIV2(0x03) |
                    SIM_CLKDIV1_OUTDIV3(0x07) |
                    SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
      if ( (MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U )
      {
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(MCG_SC_FCRDIV(0x06))) | (uint8_t)(MCG_SC_FCRDIV(0x01)));
      }
      else
      {
        /* MCG_C2: IRCS=0 */
        MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(MCG_SC_FCRDIV(0x06))) | (uint8_t)(MCG_SC_FCRDIV(0x01)));
        /* MCG_C2: IRCS=1 */
        MCG_C2 |= MCG_C2_IRCS_MASK;
      }
      Cpu_SetMCG(0U);                /* Update clock source setting */
      /* MCG_C6: CME0=1 */
      MCG_C6 |= MCG_C6_CME0_MASK;    /* Enable the clock monitor */
    }
    /* SIM_CLKDIV1: OUTDIV1=9,OUTDIV2=9,OUTDIV3=9,OUTDIV4=9,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x09) |
                  SIM_CLKDIV1_OUTDIV2(0x09) |
                  SIM_CLKDIV1_OUTDIV3(0x09) |
                  SIM_CLKDIV1_OUTDIV4(0x09); /* Update system prescalers */
    /* SIM_SOPT2: PLLFLLSEL=1 */
    SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL(0x02))) | (uint32_t)(SIM_SOPT2_PLLFLLSEL(0x01)));                  /* Select PLL 0 as a clock source for various peripherals */
    /* SIM_SOPT1: OSC32KSEL=1 */
    SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; /* RTC oscillator drives 32 kHz clock for various peripherals */
    break;
  case CPU_CLOCK_CONFIG_2:
    /* MCG_C6: CME0=0 */
    MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
    /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                  SIM_CLKDIV1_OUTDIV2(0x03) |
                  SIM_CLKDIV1_OUTDIV3(0x07) |
                  SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
    if ( (MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U )
    {
      /* MCG_SC: FCRDIV=1 */
      MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(MCG_SC_FCRDIV(0x06))) | (uint8_t)(MCG_SC_FCRDIV(0x01)));
    }
    else
    {
      /* MCG_C2: IRCS=0 */
      MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);
      /* MCG_SC: FCRDIV=1 */
      MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(MCG_SC_FCRDIV(0x06))) | (uint8_t)(MCG_SC_FCRDIV(0x01)));
      /* MCG_C2: IRCS=1 */
      MCG_C2 |= MCG_C2_IRCS_MASK;
    }
    Cpu_SetMCG(1U);                  /* Update clock source setting */
    /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV3=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) |
                  SIM_CLKDIV1_OUTDIV2(0x00) |
                  SIM_CLKDIV1_OUTDIV3(0x00) |
                  SIM_CLKDIV1_OUTDIV4(0x03); /* Update system prescalers */
    /* SIM_SOPT2: PLLFLLSEL=3 */
    SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x03); /* Select Core clock as a clock source for various peripherals */
    /* SIM_SOPT1: OSC32KSEL=0 */
    SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL_MASK); /* System oscillator drives 32 kHz clock for various peripherals */
    break;
  default:
    break;
  }
  //LDD_SetClockConfiguration(ModeID);   /* Call all LDD components to update the clock configuration */
  ClockConfigurationID = ModeID;       /* Store clock configuration identifier */
  return ERR_OK;
}

/*
** ===================================================================
**     Method      :  Cpu_GetClockConfiguration (component MK60FN1M0LQ15)
**     Description :
**         Returns the active clock configuration identifier. The
**         method is enabled only if more than one clock configuration
**         is enabled in the component.
**     Parameters  : None
**     Returns     :
**         ---             - Active clock configuration identifier
** ===================================================================
*/
uint8_t Cpu_GetClockConfiguration(void)
{
  return ClockConfigurationID;         /* Return the actual clock configuration identifier */
}

/*
** ===================================================================
**     Method      :  Cpu_SetOperationMode (component MK60FN1M0LQ15)
**     Description :
**         This method requests to change the component's operation
**         mode (RUN, WAIT, SLEEP, STOP). The target operation mode
**         will be entered immediately. 
**         See <Operation mode settings> for further details of the
**         operation modes mapping to low power modes of the cpu.
**     Parameters  :
**         NAME            - DESCRIPTION
**         OperationMode   - Requested driver
**                           operation mode
**         ModeChangeCallback - Callback to
**                           notify the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**       * ModeChangeCallbackParamPtr 
**                           - Pointer to callback parameter to notify
**                           the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_PARAM_MODE - Invalid operation mode
** ===================================================================
*/
LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr)
{
  (void)ModeChangeCallback;           /* Parameter is not used, suppress unused argument warning */
  (void)ModeChangeCallbackParamPtr;   /* Parameter is not used, suppress unused argument warning */
  switch (OperationMode)
  {
  case DOM_RUN:
    /* SCB_SCR: SLEEPDEEP=0,SLEEPONEXIT=0 */
    SCB_SCR &= (uint32_t)~(uint32_t)(
                                     SCB_SCR_SLEEPDEEP_MASK |
                                       SCB_SCR_SLEEPONEXIT_MASK
                                     );
    if  ( ClockConfigurationID != 2U )
    {
      if ( (MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3) ) /* If in PBE mode, switch to PEE. PEE to PBE transition was caused by wakeup from low power mode. */
      {
        /* MCG_C1: CLKS=0,IREFS=0 */
        MCG_C1 &= (uint8_t)~(uint8_t)((MCG_C1_CLKS(0x03) | MCG_C1_IREFS_MASK));
        while ((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) /* Wait for PLL lock */
        {}
      }
    }
    break;
  case DOM_WAIT:
    /* SCB_SCR: SLEEPDEEP=0 */
    SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPDEEP_MASK);
    /* SCB_SCR: SLEEPONEXIT=0 */
    SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPONEXIT_MASK);
    PE_WFI();
    break;
  case DOM_SLEEP:
    /* SCB_SCR: SLEEPDEEP=1 */
    SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;
    /* SMC_PMCTRL: STOPM=0 */
    SMC_PMCTRL &= (uint8_t)~(uint8_t)(SMC_PMCTRL_STOPM(0x07));
    (void)(SMC_PMCTRL == 0U);        /* Dummy read of SMC_PMCTRL to ensure the register is written before enterring low power mode */
    /* SCB_SCR: SLEEPONEXIT=1 */
    SCB_SCR |= SCB_SCR_SLEEPONEXIT_MASK;
    PE_WFI();
    break;
  case DOM_STOP:
    /* Clear LLWU flags */
    /* LLWU_F1: WUF7=1,WUF6=1,WUF5=1,WUF4=1,WUF3=1,WUF2=1,WUF1=1,WUF0=1 */
    LLWU_F1 = LLWU_F1_WUF7_MASK |
              LLWU_F1_WUF6_MASK |
              LLWU_F1_WUF5_MASK |
              LLWU_F1_WUF4_MASK |
              LLWU_F1_WUF3_MASK |
              LLWU_F1_WUF2_MASK |
              LLWU_F1_WUF1_MASK |
              LLWU_F1_WUF0_MASK;
    /* LLWU_F2: WUF15=1,WUF14=1,WUF13=1,WUF12=1,WUF11=1,WUF10=1,WUF9=1,WUF8=1 */
    LLWU_F2 = LLWU_F2_WUF15_MASK |
              LLWU_F2_WUF14_MASK |
              LLWU_F2_WUF13_MASK |
              LLWU_F2_WUF12_MASK |
              LLWU_F2_WUF11_MASK |
              LLWU_F2_WUF10_MASK |
              LLWU_F2_WUF9_MASK |
              LLWU_F2_WUF8_MASK;
    /* LLWU_F3: MWUF7=1,MWUF6=1,MWUF5=1,MWUF4=1,MWUF3=1,MWUF2=1,MWUF1=1,MWUF0=1 */
    LLWU_F3 = LLWU_F3_MWUF7_MASK |
              LLWU_F3_MWUF6_MASK |
              LLWU_F3_MWUF5_MASK |
              LLWU_F3_MWUF4_MASK |
              LLWU_F3_MWUF3_MASK |
              LLWU_F3_MWUF2_MASK |
              LLWU_F3_MWUF1_MASK |
              LLWU_F3_MWUF0_MASK;
    /* LLWU_FILT1: FILTF=1 */
    LLWU_FILT1 |= LLWU_FILT1_FILTF_MASK;
    /* LLWU_FILT2: FILTF=1 */
    LLWU_FILT2 |= LLWU_FILT2_FILTF_MASK;
    /* SCB_SCR: SLEEPONEXIT=0 */
    SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPONEXIT_MASK);
    /* SCB_SCR: SLEEPDEEP=1 */
    SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;
    /* SMC_PMCTRL: STOPM=3 */
    SMC_PMCTRL = (uint8_t)((SMC_PMCTRL & (uint8_t)~(uint8_t)(SMC_PMCTRL_STOPM(0x04))) | (uint8_t)(SMC_PMCTRL_STOPM(0x03)));
    (void)(SMC_PMCTRL == 0U);        /* Dummy read of SMC_PMCTRL to ensure the register is written before enterring low power mode */
    PE_WFI();
    break;
  default:
    return ERR_PARAM_MODE;
  }
  return ERR_OK;
}

/*
** ===================================================================
**     Method      :  Cpu_EnableInt (component MK60FN1M0LQ15)
**     Description :
**         Enables all maskable interrupts.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_EnableInt(void)
{
  __EI();
}

/*
** ===================================================================
**     Method      :  Cpu_DisableInt (component MK60FN1M0LQ15)
**     Description :
**         Disables all maskable interrupts.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_DisableInt(void)
{
  __DI();
}


extern INT32U ___VECTOR_RAM[];         //Get vector table that was copied to RAM
//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void Init_cpu(void)
{
  SCB_MemMapPtr  SCB  = SystemControl_BASE_PTR;
  NVIC_MemMapPtr NVIC = NVIC_BASE_PTR;
  SIM_MemMapPtr  SIM  = SIM_BASE_PTR;
  RTC_MemMapPtr  RTC  = RTC_BASE_PTR;
  MCG_MemMapPtr  MCG  = MCG_BASE_PTR;
  PIT_MemMapPtr  PIT  = PIT_BASE_PTR;
  FMC_MemMapPtr  FMC  = FMC_BASE_PTR;
  CRC_MemMapPtr  CRC  = CRC_BASE_PTR;      

  MPU_BASE_PTR->CESR = 0;    // 0 MPU is disabled. All accesses from all bus masters are allowed.

  SCB->VTOR = (INT32U)___VECTOR_RAM;



  //--------------------------------------------------------------------------------------------------------------------------------------
  SIM->SCGC6 |= BIT(29); // RTC | RTC clock gate control | 1 Clock is enabled.
  if ( (RTC->CR & BIT(8)) == 0u ) // If 0, 32.768 kHz oscillator is disabled.
  {
    RTC->CR = 0
              + LSHIFT(0x00, 13) // SC2P | Oscillator 2pF load configure  | 0 Disable the load.
              + LSHIFT(0x00, 12) // SC4P | Oscillator 4pF load configure  | 0 Disable the load.
              + LSHIFT(0x00, 11) // SC8P | Oscillator 8pF load configure  | 0 Disable the load.
              + LSHIFT(0x00, 10) // SC16P| Oscillator 16pF load configure | 0 Disable the load.
              + LSHIFT(0x01, 9)  // CLKO | Clock Output                   | 1 The 32kHz clock is not output to other peripherals
              + LSHIFT(0x01, 8)  // OSCE | Oscillator Enable              | 1 32.768 kHz oscillator is enabled.
              + LSHIFT(0x00, 3)  // UM   | Update Mode                    | 0 Registers cannot be written when locked.
              + LSHIFT(0x00, 2)  // SUP  | Supervisor Access              | 0 Non-supervisor mode write accesses are not supported and generate a bus error.
              + LSHIFT(0x00, 1)  // WPE  | Wakeup Pin Enable              | 0 Wakeup pin is disabled.
              + LSHIFT(0x00, 0)  // SWR  | Software Reset                 | 0 No effect
    ;
  }




  //--------------------------------------------------------------------------------------------------------------------------------------
  // Загрузка регистров из области чипа с заводскими установками
  if ( *((uint8_t *)0x03FFU) != 0xFFU )
  {
    MCG->C3 = *((uint8_t *)0x03FFU);
    MCG->C4 = (MCG_C4 & 0xE0U) | ((*((uint8_t *)0x03FEU)) & 0x1FU);
  }

  //--------------------------------------------------------------------------------------------------------------------------------------
  SIM->CLKDIV1 = 0
                 + LSHIFT(0x00, 28) // OUTDIV1 | Divide value for the core/system clock                                  | 0000 Divide-by-1.
                 + LSHIFT(0x01, 24) // OUTDIV2 | Divide value for the peripheral clock                                   | 0001 Divide-by-2.
                 + LSHIFT(0x02, 20) // OUTDIV3 | Divide value for the FlexBus clock driven to the external pin (FB_CLK). | 0010 Divide-by-3.
                 + LSHIFT(0x05, 16) // OUTDIV4 | Divide value for the flash clock                                        | 0101 Divide-by-6.
  ;

  //
  SIM->SOPT2 = 0
               + LSHIFT(0x01, 30) // NFCSRC      | NFC Flash clock source select         | 01 MCGPLL0CLK
               + LSHIFT(0x00, 28) // ESDHCSRC    | ESDHC perclk source select            | 00 Core/system clock
               + LSHIFT(0x01, 22) // USBFSRC     | USB FS clock source select            | 01 MCGPLL0CLK
               + LSHIFT(0x00, 20) // TIMESRC     | Ethernet timestamp clock source select| 00 System platform clock
               + LSHIFT(0x01, 18) // USBF_CLKSEL | USB FS clock select                   | 1 Clock divider USB FS clock
               + LSHIFT(0x01, 16) // PLLFLLSEL   | PLL/FLL clock select                  | 01 MCGPLL0CLK !!!
               + LSHIFT(0x00, 15) // NFC_CLKSEL  | NFC Flash clock select                | 0 Clock divider NFC clock
               + LSHIFT(0x01, 12) // TRACECLKSEL | Debug trace clock select              | 0 MCGCLKOUT
               + LSHIFT(0x00, 11) // CMTUARTPAD  | CMT/UART pad drive strength           | 0 Single-pad drive strength for CMT IRO or UART0_TXD.
               + LSHIFT(0x00, 8)  // FBSL        | Flexbus security level                | 00 All off-chip accesses (op code and data) via the FlexBus are disallowed.
               + LSHIFT(0x02, 5)  // CLKOUTSEL   | Clock out select                      | 010 Flash ungated clock
               + LSHIFT(0x00, 4)  // RTCCLKOUTSEL| RTC clock out select                  | 0 RTC 1 Hz clock drives RTC CLKOUT.
               + LSHIFT(0x01, 2)  // USBHSRC     | USB HS clock source select            | 01 MCGPLL0CLK
  ;
  SIM->SOPT1 = 0
               + LSHIFT(0x00, 31) // USBREGEN  | USB voltage regulator enable
               + LSHIFT(0x00, 30) // USBSSTBY  | UUSB voltage regulator in standby mode during Stop, VLPS, LLS or VLLS
               + LSHIFT(0x00, 29) // USBVSTBY  | USB voltage regulator in standby mode during VLPR or VLPW
               + LSHIFT(0x01, 19) // OSC32KSEL | 32 kHz oscillator clock select
  ;


  SIM->SCGC1 |= BIT(5); // OSC1 | OSC1 clock gate control | 1 Clock is enabled.


  /* PORTA_PCR18: ISF=0,MUX=0 */
  //PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
  /* PORTA_PCR19: ISF=0,MUX=0 */
  //PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));


  /* Switch to FBE Mode */
  //--------------------------------------------------------------------------------------------------------------------------------------

  MCG->C7 = 0; // OSCSEL | MCG OSC Clock Select | 0 Selects System Oscillator (OSCCLK).

  MCG->C2 = 0
            + LSHIFT(0x00, 7) // LOCRE0 | Loss of Clock Reset Enable     | 0 Interrupt request is generated on a loss of OSC0 external reference clock.
            + LSHIFT(0x02, 4) // RANGE0 | Frequency Range Select         | 1X Encoding 2 — Very high frequency range selected for the crystal oscillator .
            + LSHIFT(0x01, 3) // HGO0   | High Gain Oscillator Select    | 1 Configure crystal oscillator for high-gain operation.
            + LSHIFT(0x01, 2) // EREFS0 | External Reference Select      | 1 Oscillator requested.
            + LSHIFT(0x00, 1) // LP     | Low Power Select               | 0 FLL (or PLL) is not disabled in bypass modes.
            + LSHIFT(0x01, 0) // IRCS   | Internal Reference Clock Select| 1 Fast internal reference clock selected.
  ;



  /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
  OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
  /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
  OSC1_CR = OSC_CR_ERCLKEN_MASK;
  /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
  MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
  /* MCG_C4: DMX32=0,DRST_DRS=0 */
  MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
  /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
  MCG_C5 = MCG_C5_PRDIV0(0x00);
  /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
  MCG_C6 = MCG_C6_VDIV0(0x0E);
  /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
  MCG_C11 = MCG_C11_PRDIV1(0x00);
  /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
  MCG_C12 = MCG_C12_VDIV1(0x00);
  while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) /* Check that the oscillator is running */
  {}
  while ((MCG_S & MCG_S_IREFST_MASK) != 0x00U) /* Check that the source of the FLL reference clock is the external reference clock. */
  {}
  while ((MCG_S & 0x0CU) != 0x08U)    /* Wait until external reference clock is selected as MCG output */
  {}
  /* Switch to PBE Mode */
  /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
  MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));
  while ((MCG_S & 0x0CU) != 0x08U)    /* Wait until external reference clock is selected as MCG output */
  {}
  while ((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) /* Wait until PLL locked */
  {}
  /* Switch to PEE Mode */
  /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
  MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
  while ((MCG_S & 0x0CU) != 0x0CU)    /* Wait until output of the PLL is selected */
  {}
  /* MCG_C6: CME0=1 */
  MCG_C6 |= MCG_C6_CME0_MASK;          /* Enable the clock monitor */


  //--------------------------------------------------------------------------------------------------------------------------------------
  // Настройка частоты тактирования USB FS. Частота должна быть точно выставлена на 48 МГц
  // При частоте шины 120 МГц делитель равен 2.5  Формула Divider output clock = Divider input clock ? [(USBFSFRAC+1) / (USBFSDIV+1)]
  SIM->CLKDIV2 = 0
                 + LSHIFT(0x00, 9) // USBHSDIV  | USB HS clock divider divisor  |
                 + LSHIFT(0x00, 8) // USBHSFRAC | USB HS clock divider fraction |
                 + LSHIFT(0x04, 1) // USBFSDIV  | USB FS clock divider divisor  | = (4+1) =5
                 + LSHIFT(0x01, 0) // USBFSFRAC | USB FS clock divider fraction | = (1+1) =2 , 120*(2/5) = 48 МГц
  ;
  SIM->SOPT1CFG |= BIT(24);  // URWE | USB voltage regulator enable write enable | 1 SOPT1[USBREGEN] can be written.
  SIM->SOPT1    &= ~BIT(31); // USBREGEN | Controls whether the USB voltage regulator is enabled | 0 USB voltage regulator is disabled.
  SIM->SCGC4    |= BIT(18);  // USBFS | USB FS clock gate control | 1 Clock is enabled.
                             //--------------------------------------------------------------------------------------------------------------------------------------



  //--------------------------------------------------------------------------------------------------------------------------------------
  // Установки  Reset Control Module (RCM)
  RCM_BASE_PTR->RPFW = 0
                       + LSHIFT(0x1F, 0) // RSTFLTSEL | Selects the reset pin bus clock filter width.| 11111 Bus clock filter count is 32
  ;
  RCM_BASE_PTR->RPFC = 0
                       + LSHIFT(0x00, 2) // RSTFLTSS  | Selects how the reset pin filter is enabled in STOP and VLPS modes. | 0 All filtering disabled
                       + LSHIFT(0x01, 0) // RSTFLTSRW | Selects how the reset pin filter is enabled in run and wait modes.  | 01 Bus clock filter enabled for normal operation
  ;

  // Установки Power Management Controller (PMC)
  PMC_BASE_PTR->REGSC = 0
                        + LSHIFT(0x00, 3) // ACKISO | Acknowledge Isolation | 0 Peripherals and I/O pads are in normal run state|
                                          //          Writing one to this bit when it is set releases the I/O pads and certain peripherals to their normal run mode state
                        + LSHIFT(0x00, 0) // BGBE   | Bandgap Buffer Enable | 0 Bandgap buffer not enabled
  ;


  PMC_BASE_PTR->LVDSC1 = 0
                         + LSHIFT(0x01, 6) // LVDACK | Low-Voltage Detect Acknowledge     | This write-only bit is used to acknowledge low voltage detection errors (write 1 to clear LVDF). Reads always return 0.
                         + LSHIFT(0x00, 5) // LVDIE  | Low-Voltage Detect Interrupt Enable| 0 Hardware interrupt disabled (use polling)
                         + LSHIFT(0x01, 4) // LVDRE  | Low-Voltage Detect Reset Enable    | 1 Force an MCU reset when LVDF = 1
                         + LSHIFT(0x00, 0) // LVDV   | Low-Voltage Detect Voltage Select  | 00 Low trip point selected (V LVD = V LVDL )
  ;

  PMC_BASE_PTR->LVDSC2 = 0
                         + LSHIFT(0x01, 6) // LVWACK | Low-Voltage Warning Acknowledge      |
                         + LSHIFT(0x00, 5) // LVWIE  | Low-Voltage Warning Interrupt Enable | 0 Hardware interrupt disabled (use polling)
                         + LSHIFT(0x00, 0) // LVWV   | Low-Voltage Warning Voltage Select   | 00 Low trip point selected (V LVW = V LVW1 )
  ;

  //--------------------------------------------------------------------------------------------------------------------------------------
  // Инициализация Periodic Interrupt timer
  SIM->SCGC6 |= BIT(23); // PIT | PIT clock gate control | 1 Clock is enabled.

  PIT->MCR  = 0
              + LSHIFT(0x00, 1) // MDIS | Module Disable | 0 Clock for PIT Timers is enabled.
              + LSHIFT(0x01, 0) // FRZ  | Freeze         | 1 Timers are stopped in debug mode.
  ;

  //--------------------------------------------------------------------------------------------------------------------------------------
  // Инициализация Flash Access Protection Register для разрешения доступа к Flash по DMA и от прочих мастеров
  FMC->PFAPR = 0
               + LSHIFT(0x01, 23) // M7PFD     | 1 Prefetching for this master is disabled.   (Ethernet)
               + LSHIFT(0x01, 22) // M6PFD     | 1 Prefetching for this master is disabled.   (USB HS)
               + LSHIFT(0x01, 21) // M5PFD     | 1 Prefetching for this master is disabled.   () 
               + LSHIFT(0x01, 20) // M4PFD     | 1 Prefetching for this master is disabled.   ()
               + LSHIFT(0x00, 19) // M3PFD     | 0 Prefetching for this master is enabled.    (SDHC, NFC, USB FS)
               + LSHIFT(0x00, 18) // M2PFD     | 0 Prefetching for this master is enabled.    (DMA, EzPort) 
               + LSHIFT(0x00, 17) // M1PFD     | 0 Prefetching for this master is enabled.    (ARM core system bus)
               + LSHIFT(0x00, 16) // M0PFD     | 0 Prefetching for this master is enabled.    (ARM core code bus)
               + LSHIFT(0x00, 14) // M7AP[1:0] | 00 No access may be performed by this master.
               + LSHIFT(0x00, 12) // M6AP[1:0] | 00 No access may be performed by this master.
               + LSHIFT(0x00, 10) // M5AP[1:0] | 00 No access may be performed by this master.
               + LSHIFT(0x00, 8)  // M4AP[1:0] | 00 No access may be performed by this master.
               + LSHIFT(0x03, 6)  // M3AP[1:0] | 11 Both read and write accesses may be performed by this master
               + LSHIFT(0x03, 4)  // M2AP[1:0] | 11 Both read and write accesses may be performed by this master
               + LSHIFT(0x03, 2)  // M1AP[1:0] | 11 Both read and write accesses may be performed by this master
               + LSHIFT(0x03, 0)  // M0AP[1:0] | 11 Both read and write accesses may be performed by this master
  ;

  SIM->SCGC6 |= BIT(18) ; // Включаем модуль CRC


  __set_BASEPRI(BASEPRI << 4);
  __enable_interrupt();
}

/*
** ===================================================================
**     Method      :  Cpu_SetBASEPRI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the BASEPRI core register.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
/*lint -save  -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */
#ifdef _lint
  #define Cpu_SetBASEPRI(Level)  /* empty */
#else
void Cpu_SetBASEPRI(uint32_t Level)
{
  asm("msr basepri, %[input]"::[input] "r" (Level):);
}
#endif
/*lint -restore Enable MISRA rule (2.1,1.1) checking. */





#ifdef __cplusplus
}  /* extern "C" */
#endif



<|start_filename|>Firmware/Inverter_firmware/mfs/source/include/mfs_cnfg.h<|end_filename|>
#ifndef __mfs_cnfg_h__
#define __mfs_cnfg_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_cnfg.h$
* $Version : 3.8.11.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the structure definitions and constants for a
*   user who will be compiling programs that will use the Embedded MS-DOS
*   File System (MFS)
*
*END************************************************************************/

/* 
** Can be modified to customize MFS 
*/

/***************************************
**
** Code and Data configuration options
**
** MGCT: <category name="Code and Data configuration options">
**
*/

/*
** Define MFSCFG_MINIMUM_FOOTPRINT to reducte MFS memory requirements.
** MGCT: <option type="bool"/>
*/
#ifndef MFSCFG_MINIMUM_FOOTPRINT
   #define MFSCFG_MINIMUM_FOOTPRINT 0
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef MFSCFG_READ_ONLY
   #define MFSCFG_READ_ONLY 0
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef MFSCFG_READ_ONLY_CHECK
   #define MFSCFG_READ_ONLY_CHECK 1
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef MFSCFG_READ_ONLY_CHECK_ALWAYS
   #define MFSCFG_READ_ONLY_CHECK_ALWAYS 0
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef MFSCFG_CALCULATE_FREE_SPACE_ON_OPEN
   #define MFSCFG_CALCULATE_FREE_SPACE_ON_OPEN 0 
#endif



/*
** Only used if formatting. Value must be 1 or 2. 2 is the standard.
** MGCT: <option type="list">
** <item name="1" value="1"/>
** <item name="2" value="2"/>
** </option>
*/
#ifndef MFSCFG_NUM_OF_FATS
   #define MFSCFG_NUM_OF_FATS 1 
#endif

/*
** Number of fat sectors in FAT cache. Minimum value of 2 required.
** MGCT: <option type="number"/>
*/           
#ifndef MFSCFG_FAT_CACHE_SIZE
   #if MFSCFG_MINIMUM_FOOTPRINT
      #define MFSCFG_FAT_CACHE_SIZE 2 
   #else
      #define MFSCFG_FAT_CACHE_SIZE 2 // use the same value; though we don't need to save RAM space, we need to save read/write cycles
   #endif
#endif
 
/* 
** The amount of times MFS will attempt to read or write to the device 
** unsuccessfully before reporting an error.
** MGCT: <option type="number"/>
*/
#ifndef MFSCFG_MAX_WRITE_RETRIES
   #define MFSCFG_MAX_WRITE_RETRIES    1
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef MFSCFG_MAX_READ_RETRIES
   #define MFSCFG_MAX_READ_RETRIES  1
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef MFSCFG_HANDLE_INITIAL
   #if MFSCFG_MINIMUM_FOOTPRINT
      #define MFSCFG_HANDLE_INITIAL 4
   #else
      #define MFSCFG_HANDLE_INITIAL 16
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef MFSCFG_HANDLE_GROW
   #if MFSCFG_MINIMUM_FOOTPRINT
      #define MFSCFG_HANDLE_GROW 4 
   #else
      #define MFSCFG_HANDLE_GROW 16
   #endif
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef MFSCFG_HANDLE_MAX
   #if MFSCFG_MINIMUM_FOOTPRINT
      #define MFSCFG_HANDLE_MAX  0 
   #else
      #define MFSCFG_HANDLE_MAX  0
   #endif
#endif

/*
** Maximum # of times to try to rewrite a bad cluster.
** MGCT: <option type="number"/>
*/
#ifndef MFSCFG_MAX_CLUSTER_REMAP_ATTEMPTS
   #define MFSCFG_MAX_CLUSTER_REMAP_ATTEMPTS       0
#endif

/*
** MGCT: <option type="number"/>
*/
#ifndef MFSCFG_FIND_TEMP_TRIALS
   #define MFSCFG_FIND_TEMP_TRIALS      300
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef MFSCFG_ENABLE_FORMAT
    #if MFSCFG_MINIMUM_FOOTPRINT
        #define MFSCFG_ENABLE_FORMAT 0
    #else
        #define MFSCFG_ENABLE_FORMAT 1
    #endif
#endif

/*
** MGCT: <option type="bool"/>
*/
#ifndef MFSCFG_DEPRICATED_UNINSTALL
   #define MFSCFG_DEPRICATED_UNINSTALL         1
#endif

/** MGCT: </category> */

#endif


<|start_filename|>Firmware/Inverter_firmware/usb/common/include/usb_misc_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_misc_prv.h$
* $Version : 3.8.2.0$
* $Date    : Jul-30-2012$
*
* Comments:
*
*   This file contains USB Device API defines for state and function
*   returns.
*
*END************************************************************************/
#ifndef __usb_misc_prv_h__
#define __usb_misc_prv_h__ 1

#define USB_lock()                           _int_disable()
#define USB_unlock()                         _int_enable()
#define USB_install_isr(vector, isr, data)   _int_install_isr(vector, isr, data)

#if PSP_HAS_DATA_CACHE
// Not needed if we are allocating everything out of uncached memory
#define USB_dcache_invalidate()              _DCACHE_INVALIDATE()
#define USB_dcache_invalidate_line(p)        _DCACHE_INVALIDATE_LINE(p)
/* Based on the targets it should be modified, for coldfire it is MBYTES */
#define USB_dcache_invalidate_mlines(p,n)    _DCACHE_INVALIDATE_MBYTES(p, n)
#define USB_dcache_flush_line(p)             _DCACHE_FLUSH_LINE(p)
/* Based on the targets it should be modified, for coldfire it is MBYTES */
#define USB_dcache_flush_mlines(p,n)         _DCACHE_FLUSH_MBYTES(p, n)

#else

#define USB_dcache_invalidate()
#define USB_dcache_invalidate_line(p)
/* Based on the targets it should be modified, for coldfire it is MBYTES */
#define USB_dcache_invalidate_mlines(p,n)
#define USB_dcache_flush_line(p)
/* Based on the targets it should be modified, for coldfire it is MBYTES */
#define USB_dcache_flush_mlines(p,n)

#endif // PSP_HAS_DATA_CACHE

#if PSP_HAS_DATA_CACHE
    #define USB_mem_alloc_uncached(n)         _mem_alloc_system_uncached(n)
    #define USB_mem_alloc_uncached_zero(n)    _mem_alloc_system_zero_uncached(n)
    #define USB_mem_alloc_align_uncached(n,a) _mem_alloc_align_uncached(n, a)
#else
    #define USB_mem_alloc_uncached(n)         _mem_alloc_system(n)
    #define USB_mem_alloc_uncached_zero(n)    _mem_alloc_system_zero(n)
    #define USB_mem_alloc_align_uncached(n,a) _mem_alloc_align(n, a)
#endif // PSP_HAS_DATA_CACHE

#define USB_mem_alloc(n)                      _mem_alloc_system(n)
#define USB_mem_alloc_zero(n)                 _mem_alloc_system_zero(n)
#define USB_mem_free(ptr)                     _mem_free(ptr)
#define USB_mem_zero(ptr,n)                   _mem_zero(ptr,n)
#define USB_mem_copy(src,dst,n)               _mem_copy(src,dst,n)

#define USB_uncached                          volatile

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/msgpool.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: msgpool.c$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Message component.
 *
 *END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_MESSAGES
#include "message.h"
#include "msg_prv.h"

/*!
 * \brief Destroys the private message pool.
 * 
 * Any task can destroy the private message pool as long as all its messages have 
 * been freed.
 * 
 * \param[in] pool_id Pool to destroy.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \return MSGPOOL_INVALID_POOL_ID (Pool_id does not represent a message pool 
 * that was created by _msgpool_create().)
 * \return MSGPOOL_ALL_MESSAGES_NOT_FREE (All messages in the message pool have 
 * not been freed.)
 * 
 * \warning Calls _mem_free(), which on error sets the task error code.
 * 
 * \see _msgpool_create
 * \see _msg_free
 * \see _msg_alloc
 * \see _mem_free      
 */ 
_mqx_uint _msgpool_destroy
(
    _pool_id pool_id
)
{ /* Body */
#if MQX_KERNEL_LOGGING || MQX_CHECK_ERRORS
    KERNEL_DATA_STRUCT_PTR   kernel_data;
#endif
#if MQX_CHECK_ERRORS
    MSG_COMPONENT_STRUCT_PTR msg_component_ptr;
#endif
    MSGPOOL_STRUCT_PTR       msgpool_ptr;
    MSGPOOL_BLOCK_STRUCT_PTR msgpool_block_ptr;
    MSGPOOL_BLOCK_STRUCT_PTR next_block_ptr;

#if MQX_KERNEL_LOGGING || MQX_CHECK_ERRORS
    _GET_KERNEL_DATA(kernel_data);
#endif

    _KLOGE2(KLOG_msgpool_destroy, pool_id);

#if MQX_CHECK_ERRORS
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
    if (msg_component_ptr == NULL)
    {
        _KLOGX2(KLOG_msgpool_destroy, MQX_COMPONENT_DOES_NOT_EXIST);
        return MQX_COMPONENT_DOES_NOT_EXIST;
    } /* Endif */
#endif

    msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool_id;
#if MQX_CHECK_VALIDITY
    if ( msgpool_ptr->VALID != MSG_VALID )
    {
        _KLOGX2(KLOG_msgpool_destroy, MSGPOOL_INVALID_POOL_ID);
        return MSGPOOL_INVALID_POOL_ID;
    } /* Endif */
#endif

    _int_disable();
    if (msgpool_ptr->SIZE == msgpool_ptr->MAX)
    {
        /* All messages currently returned, lets delete them */
        msgpool_ptr->SIZE = 0;
        msgpool_ptr->GROW_NUMBER = 0;
        _int_enable();

        msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR;
        while (msgpool_block_ptr != NULL)
        {
            next_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR;
            _mem_free((pointer)msgpool_block_ptr);
            msgpool_block_ptr = next_block_ptr;
        } /* Endwhile */

        msgpool_ptr->MSGPOOL_BLOCK_PTR = NULL;
        msgpool_ptr->VALID = 0;
        msgpool_ptr->MSGPOOL_TYPE = 0;
        _KLOGX2(KLOG_msgpool_destroy, MQX_OK);
        return MQX_OK;
    }
    else
    {
        _int_enable();
        _KLOGX2(KLOG_msgpool_destroy, MSGPOOL_ALL_MESSAGES_NOT_FREE);
        return MSGPOOL_ALL_MESSAGES_NOT_FREE;
    } /* Endif */

} /* Endbody */

/*!
 * \brief Creates a private message pool.
 * 
 * Any task can allocate messages from the pool by calling _msg_alloc() with the 
 * pool ID.
 * 
 * \param[in] message_size Size (in single-addressable units) of the messages 
 * (including the message header) to be created for the message pool.
 * \param[in] num_messages Initial number of messages to be created for the 
 * message pool.
 * \param[in] grow_number  Number of messages to be added if all the messages 
 * are allocated.
 * \param[in] grow_limit   If grow_number is not equal to 0; one of the following:
 * \li Maximum number of messages that the pool can have.
 * \li 0 (Unlimited growth.)
 * 
 * \return Pool ID to access the message pool (success).
 * \return 0 (Failure.)  
 * 
 * \warning Creates the message component if it was not previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MSGPOOL_MESSAGE_SIZE_TOO_SMALL (Message_size is less than the size of the 
 * message header structure.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory to create the message pool).
 * \li MSGPOOL_OUT_OF_POOLS (Maximum number of message pools have been created, 
 * where the number is defined at initialization time in MAX_MSGPOOLS in the MQX 
 * initialization structure.)
 * \li Task error codes from _mem_alloc_system()
 * \li Task error codes from _msg_create_component()
 * 
 * \see _msgpool_create_system
 * \see _msgpool_destroy
 * \see _msg_alloc
 * \see _task_set_error
 * \see _mem_alloc
 * \see _mem_alloc_from
 * \see _mem_alloc_system
 * \see _mem_alloc_system_from
 * \see _mem_alloc_system_zero
 * \see _mem_alloc_system_zero_from
 * \see _mem_alloc_zero
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align
 * \see _mem_alloc_align_from
 * \see _mem_alloc_at
 * \see _msg_create_component
 * \see MQX_INITIALIZATION_STRUCT  
 */ 
_pool_id _msgpool_create
(
    uint_16 message_size,
    uint_16 num_messages,
    uint_16 grow_number,
    uint_16 grow_limit
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _pool_id result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE5(KLOG_msgpool_create, message_size, num_messages, grow_number, grow_limit);

    result = _msgpool_create_internal(message_size, num_messages, grow_number,
                    grow_limit, MSG_POOL);

    _KLOGX2(KLOG_msgpool_create, result);
    return(result);

} /* Endbody */

/*!
 * \private
 *  
 * \brief Internal function that creates a private message pool.
 * 
 * \param[in] message_size Size (in single-addressable units) of the messages 
 * (including the message header) to be created for the message pool.
 * \param[in] num_messages Initial number of messages to be created for the 
 * message pool.
 * \param[in] grow_number  Number of messages to be added if all the messages 
 * are allocated.
 * \param[in] grow_limit   If grow_number is not equal to 0; one of the following:
 * \li Maximum number of messages that the pool can have.
 * \li 0 (Unlimited growth.)
 * \param[in] pool_type     Selects a system pool or a regular pool.
 * 
 * \return Pool ID to access the message pool (success).
 * \return 0 (Failure.)  
 * 
 * \warning Creates the message component if it was not previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MSGPOOL_MESSAGE_SIZE_TOO_SMALL (Message_size is less than the size of the 
 * message header structure.)
 * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory to create the message pool).
 * \li MSGPOOL_OUT_OF_POOLS (Maximum number of message pools have been created, 
 * where the number is defined at initialization time in MAX_MSGPOOLS in the MQX 
 * initialization structure.)
 * \li Task error codes from _mem_alloc_system()
 * \li Task error codes from _msg_create_component()
 *   
 * \see _msgpool_create 
 * \see _msgpool_add_internal 
 */ 
_pool_id _msgpool_create_internal
(
    uint_16 message_size,
    uint_16 num_messages,
    uint_16 grow_number,
    uint_16 grow_limit,
    _mqx_uint pool_type
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
    register MSGPOOL_STRUCT_PTR msgpool_ptr;
    register MSGPOOL_STRUCT_PTR temp_msgpool_ptr;
    register MSGPOOL_STRUCT_PTR prev_msgpool_ptr;
    register _mqx_uint          i;
    _mqx_uint                   result;

    _GET_KERNEL_DATA(kernel_data);
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);

#if MQX_CHECK_ERRORS
    if (message_size < sizeof(MESSAGE_HEADER_STRUCT))
    {
        _task_set_error(MSGPOOL_MESSAGE_SIZE_TOO_SMALL);
        return ((_pool_id) 0);
    } /* Endif */
#endif

    /*
     * Try to find an available slot in the array of msgpools for a new pool
     * if MAX_MSGPOOLS_EVER has not yet reached MAX_MSGPOOLS then
     * simply use MAX_MSGPOOLS_EVER as an index value and then increment it
     * but if MAX_MSGPOOLS_EVER has reached MAX_MSGPOOLS then
     * go back and search through the previously assigned headers to see
     * if one has been deallocated and is available for use
     */
    if (msg_component_ptr == NULL)
    {
        result = _msg_create_component();
        msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (msg_component_ptr == NULL)
        {
            _task_set_error(result);
            return ((_pool_id)0);
        } /* Endif */
#endif
    } /* Endif */

    _int_disable();
    if (msg_component_ptr->MAX_MSGPOOLS_EVER >= msg_component_ptr->MAX_MSGPOOLS)
    {
        msgpool_ptr = &msg_component_ptr->MSGPOOLS_PTR[0];
        for ( i=0; i < msg_component_ptr->MAX_MSGPOOLS; i++ )
        {
            if (msgpool_ptr->VALID != MSG_VALID)
            {
                break;
            } /* Endif */
            msgpool_ptr++;
        } /* Endfor */
        if (i == msg_component_ptr->MAX_MSGPOOLS)
        {
            _int_enable();
            _task_set_error(MSGPOOL_OUT_OF_POOLS);
            return ((_pool_id)0);
        } /* Endif */
    }
    else
    {
        msgpool_ptr = &msg_component_ptr->MSGPOOLS_PTR[
        msg_component_ptr->MAX_MSGPOOLS_EVER++];
    } /* Endif */

    msgpool_ptr->VALID = MSG_VALID;
    msgpool_ptr->MESSAGE_SIZE = message_size;
    msgpool_ptr->GROW_NUMBER = 0;
    _int_enable();

    msgpool_ptr->MSGPOOL_BLOCK_PTR = NULL;
    msgpool_ptr->MSG_FREE_LIST_PTR = NULL;
    msgpool_ptr->NEXT_MSGPOOL_PTR = NULL;
    msgpool_ptr->SIZE = 0;
    msgpool_ptr->MAX = 0;
    if ( grow_number == 0 )
    {
        msgpool_ptr->GROW_LIMIT = num_messages;
    }
    else if (grow_limit == 0)
    {
        msgpool_ptr->GROW_LIMIT = 0xFFFF;
    }
    else
    {
        msgpool_ptr->GROW_LIMIT = grow_limit;
    } /* Endif */
    msgpool_ptr->MSGPOOL_TYPE = pool_type;

    if (num_messages)
    {
        _msgpool_add_internal(msgpool_ptr, num_messages);

        /* no messages could be created, so abort pool creation */
        if (msgpool_ptr->SIZE == 0)
        {
            msgpool_ptr->VALID = 0;
            _task_set_error(MQX_OUT_OF_MEMORY);
            return ((_pool_id)0);
        } /* Endif */
    } /* Endif */

    msgpool_ptr->GROW_NUMBER = grow_number;

    if ( pool_type == SYSTEM_MSG_POOL )
    {
        /* We must insert the pool into the link list of system message pools,
         * by order of size, smallest first.
         */

        _int_disable();
        prev_msgpool_ptr = msg_component_ptr->SMALLEST_MSGPOOL_PTR;
        if (prev_msgpool_ptr == NULL)
        {
            /* first entry in list */
            msg_component_ptr->SMALLEST_MSGPOOL_PTR = msgpool_ptr;
            msg_component_ptr->LARGEST_MSGPOOL_PTR = msgpool_ptr;
        }
        else if (prev_msgpool_ptr->MESSAGE_SIZE >= msgpool_ptr->MESSAGE_SIZE)
        {
            /* The new pool is smaller than that at head of list */
            msgpool_ptr->NEXT_MSGPOOL_PTR = prev_msgpool_ptr;
            msg_component_ptr->SMALLEST_MSGPOOL_PTR = msgpool_ptr;
        }
        else
        {
            temp_msgpool_ptr = prev_msgpool_ptr->NEXT_MSGPOOL_PTR;
            while (temp_msgpool_ptr != NULL)
            {
                /* check the relative message sizes */
                if (temp_msgpool_ptr->MESSAGE_SIZE < msgpool_ptr->MESSAGE_SIZE)
                {
                    /* continue to walk down linked list */
                    prev_msgpool_ptr = temp_msgpool_ptr;
                    temp_msgpool_ptr = prev_msgpool_ptr->NEXT_MSGPOOL_PTR;
                }
                else
                {
                    /* this entry belongs between prev_ptr and temp_msgpool_ptr */
                    prev_msgpool_ptr->NEXT_MSGPOOL_PTR = msgpool_ptr;
                    msgpool_ptr->NEXT_MSGPOOL_PTR = temp_msgpool_ptr;
                    break;
                } /* Endif */
            } /* Endwhile */
            if (temp_msgpool_ptr == NULL)
            {
                /* searched the list and this entry belongs at the bottom */
                prev_msgpool_ptr->NEXT_MSGPOOL_PTR = msgpool_ptr;
                msg_component_ptr->LARGEST_MSGPOOL_PTR = msgpool_ptr;
            }/* Endif */
        } /* Endif */
        _int_enable();

    } /* Endif */

    return ((_pool_id)msgpool_ptr);

} /* Endbody */
/*!
 * \private
 * 
 * \brief Creates a new block of messages, and adds the block to the msgpool.
 * 
 * The messages in the block are linked together onto the free list.
 * 
 * \param[in] msgpool_ptr  A pointer to the message pool.
 * \param[in] num_messages The number of messages to attempt to add. 
 */ 
void _msgpool_add_internal
(
    MSGPOOL_STRUCT_PTR msgpool_ptr,
    uint_16            num_messages
)
{ /* Body */
    INTERNAL_MESSAGE_STRUCT_PTR first_imsg_ptr;
    INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    MSGPOOL_BLOCK_STRUCT_PTR    msgpool_block_ptr;
    _mqx_int                    raw_message_size;
    _mqx_uint                   count;

    raw_message_size = sizeof(INTERNAL_MESSAGE_STRUCT) -
    sizeof(MESSAGE_HEADER_STRUCT) + msgpool_ptr->MESSAGE_SIZE;
    _MEMORY_ALIGN_VAL_LARGER(raw_message_size);

    msgpool_block_ptr = (MSGPOOL_BLOCK_STRUCT_PTR)_mem_alloc_system((_mem_size)
                    ((raw_message_size*num_messages) + sizeof(MSGPOOL_BLOCK_STRUCT) +
                                    PSP_MEMORY_ALIGNMENT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (msgpool_block_ptr == NULL)
    {
        return;
    } /* Endif */
#endif
    _mem_set_type(msgpool_block_ptr, MEM_TYPE_MESSAGE_POOL_BLOCKS);

    msgpool_block_ptr->NEXT_BLOCK_PTR = NULL;
    msgpool_block_ptr->RAW_MESSAGE_SIZE = raw_message_size;
    msgpool_block_ptr->NUM_MESSAGES = num_messages;

    first_imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR)
    ((uchar _PTR_)msgpool_block_ptr + sizeof(MSGPOOL_BLOCK_STRUCT));
    first_imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR)
    _ALIGN_ADDR_TO_HIGHER_MEM(first_imsg_ptr);

    msgpool_block_ptr->FIRST_IMSG_PTR = first_imsg_ptr;

    imsg_ptr = first_imsg_ptr;
    count = num_messages + 1;
    while (--count)
    {
        imsg_ptr->NEXT = NULL; /* Free list pointer */
        imsg_ptr->VALID = MSG_VALID;
        imsg_ptr->FREE = TRUE;
        imsg_ptr->QUEUED = FALSE;
        imsg_ptr->MSGPOOL_PTR = msgpool_ptr;
        imsg_ptr->TD_PTR = NULL;
        if (count > 1)
        {
            /* imsg is in the middle of the list */
            imsg_ptr->NEXT = (INTERNAL_MESSAGE_STRUCT_PTR)
            ((uchar _PTR_)imsg_ptr + raw_message_size);
            imsg_ptr = imsg_ptr->NEXT;
        }/* Endif */
    } /* Endwhile */

    /* Now make the pool entries available */
    _int_disable();
    msgpool_block_ptr->NEXT_BLOCK_PTR = msgpool_ptr->MSGPOOL_BLOCK_PTR;
    msgpool_ptr->MSGPOOL_BLOCK_PTR = msgpool_block_ptr;

    /* imsg_ptr here is the last message on the list */
    imsg_ptr->NEXT = msgpool_ptr->MSG_FREE_LIST_PTR;
    msgpool_ptr->MSG_FREE_LIST_PTR = first_imsg_ptr;
    msgpool_ptr->SIZE += num_messages;
    msgpool_ptr->MAX += num_messages;
    _int_enable();

} /* Endbody */

/*!
 * \brief Creates a system message pool.
 * 
 * Tasks can subsequently allocate messages from the pool by calling 
 * _msg_alloc_system().
 * 
 * \param[in] message_size Size (in single-addressable units) of the messages 
 * (including the message header) to be created for the message pool.
 * \param[in] num_messages Initial number of messages to be created for the 
 * message pool.
 * \param[in] grow_number  Number of messages to be added if all the messages 
 * are allocated.
 * \param[in] grow_limit   If grow_number is not equal to 0; one of the following:
 * \li Maximum number of messages that the pool can have.
 * \li 0 (Unlimited growth.)  
 * 
 * \return TRUE (Success.) or FALSE (Failure.)
 * 
 * \warning Creates the message component if it was not previously created.
 * \warning On failure, calls _task_set_error() to set the task error code as 
 * described for _msgpool_create().
 * 
 * \see _msgpool_create
 * \see _msgpool_destroy
 * \see _msg_alloc_system
 * \see _task_set_error
 * \see MQX_INITIALIZATION_STRUCT  
 */ 
boolean _msgpool_create_system
(
    uint_16 message_size,
    uint_16 num_messages,
    uint_16 grow_number,
    uint_16 grow_limit
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    _pool_id ret_value;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE5(KLOG_msgpool_create_system, message_size, num_messages, grow_number, grow_limit);

    ret_value = _msgpool_create_internal(message_size, num_messages, grow_number,
                    grow_limit, SYSTEM_MSG_POOL);

    _KLOGX2(KLOG_msgpool_create_system, ret_value == (_pool_id)0 );

    if ( ret_value == (_pool_id)0 )
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    } /* Endif */

} /* Endbody */

/*!
 * \brief Tests all the message poolsin the system for consistency and validity.
 *  
 * The function checks the validity of each message in each private and system 
 * message pool. It reports the first error that it finds.
 *  
 * \param[out] pool_error_ptr (Initialized only if an error is found.) If the 
 * message in a message pool has an error; one of the following:
 * \li A pointer to a pool ID if the message is from a private message pool.
 * \li A pointer to a system message pool if the message is from a system 
 * message pool.
 * \param[out] msg_error_ptr  Pointer to the message that has an error 
 * (initialized only if an error is found).
 * 
 * \return MQX_OK (all messages in all message pools passed)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \return MSGQ_INVALID_MESSAGE (At least one message in at least one message 
 * pool failed.)
 * 
 * \warning Disables and enables interrupts.
 *  
 * \see _msgpool_create
 * \see _msgpool_create_system   
 */ 
_mqx_uint _msgpool_test
(
    pointer _PTR_ pool_error_ptr,
    pointer _PTR_ msg_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
    MSGPOOL_STRUCT_PTR          msgpool_ptr;
    MSGPOOL_BLOCK_STRUCT_PTR    msgpool_block_ptr;
    INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    _mqx_uint                   i,j,raw_message_size;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_msgpool_test, pool_error_ptr, msg_error_ptr);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _KLOGX2(KLOG_msgpool_test, MQX_COMPONENT_DOES_NOT_EXIST);
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    /* Check all the message pools */
    msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR;
    i = msg_component_ptr->MAX_MSGPOOLS + 1;
    while (--i)
    {
        _int_disable();
        if (msgpool_ptr->VALID == MSG_VALID)
        {
            /* The pool has been created */

            /* Search through all of the message pool blocks for this pool */
            msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR;
            while (msgpool_block_ptr != NULL)
            {
                raw_message_size = msgpool_block_ptr->RAW_MESSAGE_SIZE;
                imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR)
                msgpool_block_ptr->FIRST_IMSG_PTR;
                j = msgpool_block_ptr->NUM_MESSAGES + 1;
                while (--j)
                {
                    if ((imsg_ptr->VALID != MSG_VALID) ||
                                    (imsg_ptr->MSGPOOL_PTR != msgpool_ptr))
                    {
                        _int_enable();
                        *pool_error_ptr = msgpool_ptr;
                        *msg_error_ptr = imsg_ptr;
                        _KLOGX4(KLOG_msgpool_test, MSGQ_INVALID_MESSAGE, msgpool_ptr,
                                        imsg_ptr);
                        return(MSGQ_INVALID_MESSAGE);
                    } /* Endif */
                    imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR)
                    ((uchar _PTR_)imsg_ptr + raw_message_size);
                } /* Endwhile */

                msgpool_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR;
            } /* Endwhile */

        } /* Endif */
        _int_enable();
        msgpool_ptr++;
    } /* Endwhile */

    _KLOGX2(KLOG_msgpool_test, MQX_OK);
    return(MQX_OK);

} /* Endbody */

#endif /* MQX_USE_MESSAGES */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/config/INV1_K60F120/user_config.h<|end_filename|>
/**HEADER**********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* $FileName: user_config.h$
* $Version : 3.8.4.0$
* $Date    : Sep-5-2012$
*
* Comments:
*
*   User configuration for MQX components
*
*END**************************************************************************/

#ifndef __user_config_h__
#define __user_config_h__

/* mandatory CPU identification */
#define MQX_CPU                 PSP_CPU_MK60DF120M


/* MGCT: <generated_code> */
#define BSPCFG_ENABLE_TTYA       1
#define BSPCFG_ENABLE_ITTYA      0
#define BSPCFG_ENABLE_TTYB       0
#define BSPCFG_ENABLE_ITTYB      0
#define BSPCFG_ENABLE_TTYC       0
#define BSPCFG_ENABLE_ITTYC      0
#define BSPCFG_ENABLE_TTYD       0
#define BSPCFG_ENABLE_ITTYD      0
#define BSPCFG_ENABLE_TTYE       0
#define BSPCFG_ENABLE_ITTYE      0
#define BSPCFG_ENABLE_TTYF       0
#define BSPCFG_ENABLE_ITTYF      0
#define BSPCFG_ENABLE_I2C0       1
#define BSPCFG_ENABLE_II2C0      0
#define BSPCFG_ENABLE_I2C1       0
#define BSPCFG_ENABLE_II2C1      0
#define BSPCFG_ENABLE_SPI0       0
#define BSPCFG_ENABLE_ISPI0      0
#define BSPCFG_ENABLE_SPI1       0
#define BSPCFG_ENABLE_ISPI1      0
#define BSPCFG_ENABLE_SPI2       0
#define BSPCFG_ENABLE_ISPI2      0
#define BSPCFG_ENABLE_RTCDEV     1
#define BSPCFG_ENABLE_PCFLASH    0
#define BSPCFG_ENABLE_ADC0       0
#define BSPCFG_ENABLE_ADC1       0
#define BSPCFG_ENABLE_ADC2       0
#define BSPCFG_ENABLE_ADC3       0
#define BSPCFG_ENABLE_FLASHX     0
#define BSPCFG_ENABLE_ESDHC      0
#define BSPCFG_ENABLE_IODEBUG    0
#define BSPCFG_ENABLE_NANDFLASH  0
#define BSPCFG_ENABLE_USBDCD     0
#define BSPCFG_ENABLE_CRC        0
#define BSPCFG_ENABLE_SAI        0
#define BSPCFG_HAS_SRAM_POOL     1
#define BSPCFG_ENET_SRAM_BUF     1

#define MQX_USE_IDLE_TASK               1
#define MQX_ENABLE_LOW_POWER            0
#define MQXCFG_ENABLE_FP                1
#define MQX_INCLUDE_FLOATING_POINT_IO   1

#define RTCSCFG_ENABLE_ICMP      1
#define RTCSCFG_ENABLE_UDP       1
#define RTCSCFG_ENABLE_TCP       1
#define RTCSCFG_ENABLE_STATS     1
#define RTCSCFG_ENABLE_GATEWAYS  1
#define FTPDCFG_USES_MFS         1
#define RTCSCFG_ENABLE_SNMP      0

#define TELNETDCFG_NOWAIT        FALSE

#define MQX_TASK_DESTRUCTION     1

#define HTTPDCFG_POLL_MODE       0
#define HTTPDCFG_STATIC_TASKS    0
#define HTTPDCFG_DYNAMIC_TASKS   1
/* MGCT: </generated_code> */



/*
** include common settings
*/


/* use the rest of defaults from small-RAM-device profile */
#include "small_ram_config.h"

/* and enable verification checks in kernel */
#include "verif_enabled_config.h"

#endif /* __user_config_h__ */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_init.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_init.c$
* $Version : 3.8.34.0$
* $Date    : Jun-27-2012$
*
* Comments:
*
*   This file contains the functions that are used to initialize MFS
*   It also contains the MFS driver functions.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <io_prv.h>



#include "mfs.h"
#include "mfs_prv.h"
#include "part_mgr.h"

_mem_pool_id _MFS_pool_id;
uint_32 _MFS_handle_pool_init = MFSCFG_HANDLE_INITIAL;
uint_32 _MFS_handle_pool_grow = MFSCFG_HANDLE_GROW;
uint_32 _MFS_handle_pool_max  = MFSCFG_HANDLE_MAX;

static int_32 _io_mfs_uninstall_internal(IO_DEVICE_STRUCT_PTR);                                                                                                                                       

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_mfs_install
* Returned Value   : error code
* Comments  :   Initialize the MSDOS File System.
*
*END*---------------------------------------------------------------------*/

uint_32 _io_mfs_install
    (
    MQX_FILE_PTR dev_fd,        /*[IN] the device on which to install MFS */
    char_ptr     identifier,    /*[IN] the name that should be given to mfs (ex: "C:", "MFS1:", etc..) */
    uint_32      partition_num  /*[IN] the partition number to install MFS on. 0 for no partitions */  
    )
{
    MFS_DRIVE_STRUCT_PTR         drive_ptr;
    uint_32                      error_code;

    drive_ptr = MFS_mem_alloc_system_zero( sizeof(MFS_DRIVE_STRUCT) );
    if ( drive_ptr == NULL )
    {
        return( MFS_INSUFFICIENT_MEMORY );
    }
    _mem_set_type(drive_ptr, MEM_TYPE_MFS_DRIVE_STRUCT);

    _int_disable();

    error_code = _io_dev_install_ext( identifier, 
        _io_mfs_open,                     
        _io_mfs_close, 
        _io_mfs_read,                      
        _io_mfs_write,                     
        (_mqx_int(_CODE_PTR_)(MQX_FILE_PTR,_mqx_uint,pointer))_io_mfs_ioctl,
        _io_mfs_uninstall_internal,
        (pointer)drive_ptr);

    if ( error_code != IO_OK )
    {
        _mem_free(drive_ptr);
        _int_enable();      
        return error_code;
    }

    /*
    ** create a light weight semaphore
    */
    _lwsem_create(&drive_ptr->SEM,1);

    drive_ptr->DEV_FILE_PTR = dev_fd;
    drive_ptr->DRV_NUM = partition_num;
    drive_ptr->HANDLE_PARTITION = _partition_create(sizeof(MFS_HANDLE), _MFS_handle_pool_init, _MFS_handle_pool_grow, _MFS_handle_pool_max );

    // Inform Kernel that MFS is installed
    _mqx_set_io_component_handle(IO_MFS_COMPONENT,(pointer)MFS_VERSION);

    _int_enable();

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_mfs_uninstall_internal
* Returned Value   : uint_32 error code
* Comments  :   Uninstalls the MSDOS File System and frees all memory allocated
*               to it.
*
*END*---------------------------------------------------------------------*/

static int_32 _io_mfs_uninstall_internal
    (
    IO_DEVICE_STRUCT_PTR   dev_ptr  /* [IN] The device to uninstall */            
    )
{
    MFS_DRIVE_STRUCT_PTR   drive_ptr;
    int_32                 error;

    drive_ptr = (MFS_DRIVE_STRUCT_PTR)dev_ptr->DRIVER_INIT_PTR;
    if ( !drive_ptr->MFS_FILE_PTR )
    {
        error = IO_OK;
        _lwsem_destroy(&drive_ptr->SEM);
        _mfs_partition_destroy(drive_ptr->HANDLE_PARTITION);
        _mem_free(drive_ptr);
    }
    else
    {
        error = MFS_SHARING_VIOLATION;
    }  

    return error;
}  


#if MFSCFG_DEPRICATED_UNINSTALL
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_mfs_uninstall
* Returned Value   : uint_32 error code
* Comments  :   Uninstalls the MSDOS File System and frees all memory allocated
*               to it.
*
*END*---------------------------------------------------------------------*/

uint_32 _io_mfs_uninstall
    (
    char_ptr     identifier /* [IN] A string that identifies the device to uninstall */            
    )
{
    return(uint_32)_io_dev_uninstall(identifier);
}  
#endif


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mfs_open
* Returned Value   : MQX_OK or an error
* Comments         : Opens and initializes MFS driver.
* 
*END*----------------------------------------------------------------------*/

int_32 _io_mfs_open
    (
    MQX_FILE_PTR             fd_ptr,        /* [IN] the file handle for the device being opened */
    char_ptr                 open_name_ptr, /* [IN] the remaining portion of the name of the device */
    char_ptr                 flags_str      /* [IN] the flags to specify file type:
                                            ** w  write 
                                            ** r  read
                                            ** a append
                                            ** x for temp file
                                            ** n for new file
                                            ** etc... 
                                            */
    )
{
    MFS_DRIVE_STRUCT_PTR        drive_ptr;
    uchar                       flags = 0;
    uint_32                     error_code = MFS_NO_ERROR;

    drive_ptr = (MFS_DRIVE_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR;

    if ( drive_ptr->MFS_FILE_PTR == NULL )
    {
        /* This means we are opening MFS and not a file . */
        error_code = MFS_Open_Device(fd_ptr, drive_ptr);
        if ( error_code == MFS_NOT_A_DOS_DISK )
        {
            /* 
            ** This error is OK. It just means the disk probably has to be 
            ** formatted 
            */
            fd_ptr->ERROR = error_code;
            error_code = MFS_NO_ERROR;
        }
      /* */
      if (error_code == MFS_NO_ERROR) {
         _io_register_file_system(fd_ptr,open_name_ptr);
      }
    }
    else
    {
        /* We are opening a file */
        if ( !drive_ptr->DOS_DISK )
        {
            return MFS_NOT_A_DOS_DISK;
        }

        open_name_ptr = MFS_Parse_Out_Device_Name(open_name_ptr);

        /* Check for a filename, if none, then check for the temp flag */
        if ( *(open_name_ptr-1) != ':' )
        {
            error_code = MFS_PATH_NOT_FOUND;         
        }
        else if ( *open_name_ptr == '\0' )
        {
            error_code = MFS_PATH_NOT_FOUND;
        }
        else
        {
            /* 
            ** When opening a file, only read-only attributes are set. The other
            ** attributes (such as hidden, system, etc..) must be set afterwards
            ** with an ioctl call.
            */  
            switch ( *flags_str )
            {
                case 'r':
                    if ( *(flags_str + 1) == '+' )
                    {
                        flags |= MFS_ACCESS_READ_WRITE;
                    }
                    else
                    {
                        flags |= MFS_ACCESS_READ_ONLY;
                    } 

                    fd_ptr->DEV_DATA_PTR = (pointer) MFS_Open_file(drive_ptr->MFS_FILE_PTR, open_name_ptr, flags, &error_code);
                    break;
#if !MFSCFG_READ_ONLY
                case 'x':
#if MFSCFG_READ_ONLY_CHECK
                    if (MFS_is_read_only (NULL, drive_ptr))
                    {
                        error_code = MFS_DISK_IS_WRITE_PROTECTED;
                    }
#endif
                    if (error_code == MFS_NO_ERROR) 
                    {
                        fd_ptr->DEV_DATA_PTR = (pointer) MFS_Create_temp_file(drive_ptr->MFS_FILE_PTR, flags, open_name_ptr, &error_code);      
                    }
                    break;
                case 'w':
#if MFSCFG_READ_ONLY_CHECK
                    if (MFS_is_read_only (NULL, drive_ptr))
                    {
                        error_code = MFS_DISK_IS_WRITE_PROTECTED;
                    }
#endif
                    if (error_code == MFS_NO_ERROR) 
                    {
                        if ( *(flags_str + 1) == '+' )
                        {
                            flags |= MFS_ACCESS_READ_WRITE;
                        }
                        else
                        {
                            flags |= MFS_ACCESS_WRITE_ONLY;
                        } 

                        fd_ptr->DEV_DATA_PTR = (pointer) MFS_Create_file(drive_ptr->MFS_FILE_PTR, 0, open_name_ptr, &error_code);
                        if ( error_code == MFS_NO_ERROR )
                        {
                            ((MFS_HANDLE_PTR)fd_ptr->DEV_DATA_PTR)->ACCESS = flags;
                        }
                    }
                    break;
                case 'a':
#if MFSCFG_READ_ONLY_CHECK
                    if (MFS_is_read_only (NULL, drive_ptr))
                    {
                        error_code = MFS_DISK_IS_WRITE_PROTECTED;
                    }
#endif
                    if (error_code == MFS_NO_ERROR) 
                    {
                        if ( *(flags_str + 1) == '+' )
                        {
                            flags |= MFS_ACCESS_READ_WRITE;
                        }
                        else
                        {
                            flags |= MFS_ACCESS_WRITE_ONLY;     
                        } 

                        fd_ptr->DEV_DATA_PTR = (pointer) MFS_Open_file(drive_ptr->MFS_FILE_PTR, open_name_ptr, flags, &error_code);
                        if ( error_code == MFS_FILE_NOT_FOUND )
                        {
                            error_code = MFS_NO_ERROR;
                            fd_ptr->DEV_DATA_PTR = (pointer) MFS_Create_file(drive_ptr->MFS_FILE_PTR, 0, open_name_ptr, &error_code);
                            if ( error_code == MFS_NO_ERROR )
                            {
                                ((MFS_HANDLE_PTR)fd_ptr->DEV_DATA_PTR)->ACCESS = flags;
                            }
                        }
                    }
                    break;
                case 'n':
#if MFSCFG_READ_ONLY_CHECK
                    if (MFS_is_read_only (NULL, drive_ptr))
                    {
                        error_code = MFS_DISK_IS_WRITE_PROTECTED;
                    }
#endif
                    if (error_code == MFS_NO_ERROR) 
                    {
                        if ( *(flags_str + 1) == '+' )
                        {
                            flags |= MFS_ACCESS_READ_WRITE;
                        }
                        else
                        {
                            flags |= MFS_ACCESS_WRITE_ONLY;
                        } 

                        fd_ptr->DEV_DATA_PTR = (pointer) MFS_Create_new_file(drive_ptr->MFS_FILE_PTR, 0, open_name_ptr, &error_code);
                        if ( error_code == MFS_NO_ERROR )
                        {
                            ((MFS_HANDLE_PTR)fd_ptr->DEV_DATA_PTR)->ACCESS = flags;
                        }
                    }
                    break;
#endif
                default:
                    error_code = MFS_INVALID_PARAMETER;
                    break;
            }  
        }  

        /* Check to make sure the error code is OK */
        if ( error_code == MFS_NO_ERROR )
        {
            /* Initialise the file information fields */
            fd_ptr->LOCATION = 0;     
            ((MFS_HANDLE_PTR)fd_ptr->DEV_DATA_PTR)->SAVED_POSITION = 0;     
            fd_ptr->SIZE = dtohl(((MFS_HANDLE_PTR)fd_ptr->DEV_DATA_PTR)->DIR_ENTRY.FILE_SIZE);

            /* If we are appending, go to end of file */
            if ( *flags_str == 'a' )
            {
                fseek(fd_ptr, 0, IO_SEEK_END);
            }
        }
        else
        {
            // An error occured, so the calling function (_io_fopen) will
            // free the MQX_FILE_PTR. Need to release the handle
            if ( fd_ptr->DEV_DATA_PTR )
            {
                MFS_Close_file(fd_ptr);
            }
        } 
    } 

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mfs_close
* Returned Value   : ERROR CODE
* Comments         : Closes MFS driver
* 
*END*----------------------------------------------------------------------*/

int_32 _io_mfs_close
    (
    MQX_FILE_PTR                   fd_ptr   /* [IN] the file handle for the device being closed */
    )
{
    uint_32                 result = MQX_OK;
   // unregister file system from handle table
   _io_unregister_file_system(fd_ptr);

    if ( fd_ptr->DEV_DATA_PTR == NULL )
    {
        /* We are closing the mfs_fd_ptr, and not a normal file */
        result = MFS_Close_Device(fd_ptr);
    }
    else
    {
        /* We are closing a normal file */
        result = MFS_Close_file(fd_ptr);   
    } 

    return(result);
}  



/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mfs_read
* Returned Value   : number of characters read
* Comments         : Reads data from MFS driver
* 
*END*----------------------------------------------------------------------*/

int_32 _io_mfs_read
    (
    MQX_FILE_PTR file_ptr,   /* [IN] the stream to perform the operation on */
    char_ptr    data_ptr,   /* [IN] the data location to read to */
    int_32      num         /* [IN] the number of bytes to read */
    )
{
    int_32 result;

    result = MFS_Read(file_ptr, num, data_ptr, &(file_ptr->ERROR));

    /* Check for EOF. The MFS EOF must be translated to the standard EOF */
    if ( file_ptr->ERROR == MFS_EOF )
    {
        file_ptr->FLAGS |= IO_FLAG_AT_EOF;
    }

    return (file_ptr->ERROR == 0 || file_ptr->ERROR == MFS_EOF) ? result : IO_ERROR;    
}   


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mfs_write
* Returned Value   : number of characters written
* Comments         : Writes data to the fdv_ram device
* 
*END*----------------------------------------------------------------------*/

int_32 _io_mfs_write
    (
    MQX_FILE_PTR file_ptr,   /* [IN] the stream to perform the operation on */
    char_ptr    data_ptr,   /* [IN] the data location to read to */
    int_32      num         /* [IN] the number of bytes to read */
    )
{
#if MFSCFG_READ_ONLY
    return IO_ERROR;
#else
    int_32 result;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (file_ptr, NULL))
    {
        return IO_ERROR;
    }
#endif

    result = MFS_Write(file_ptr, num, data_ptr, &(file_ptr->ERROR));
    return (file_ptr->ERROR == 0) ? result : IO_ERROR;
#endif
}    


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_mfs_ioctl
* Returned Value   : int_32 
* Comments         :
*    The returned value is IO_EOF or a MQX error code.
*
*END*----------------------------------------------------------------------*/

int_32 _io_mfs_ioctl
    (
    MQX_FILE_PTR file_ptr,   /* [IN] the stream to perform the operation on */
    uint_32     cmd,        /* [IN] the ioctl command */
    uint_32_ptr param_ptr   /* [IN] the ioctl parameters */
    )
{
    MFS_DRIVE_STRUCT_PTR   drive_ptr;
    uint_32                result = MQX_OK;

    switch ( cmd )
    {
        case IO_IOCTL_SEEK:
            MFS_Move_file_pointer(file_ptr, &result);
            if ( result == MFS_EOF )
                file_ptr->FLAGS |= IO_FLAG_AT_EOF;
            break;

        case IO_IOCTL_CHAR_AVAIL:
            /* 
            ** Location is one smaller than file size. We want to know if 
            ** we can read one extra character 
            */
            *param_ptr = (file_ptr->LOCATION  >= dtohl(((MFS_HANDLE_PTR)file_ptr->DEV_DATA_PTR)->DIR_ENTRY.FILE_SIZE))?FALSE:TRUE;
            break;

        case IO_IOCTL_BAD_CLUSTERS:
            result = MFS_Bad_clusters(file_ptr);
            break;
        case IO_IOCTL_LAST_CLUSTER:
            result = MFS_Last_cluster(file_ptr);
            break;
        case IO_IOCTL_FREE_SPACE:
            {
                uint_64 bytes_free = MFS_Get_disk_free_space(file_ptr);
                result = (bytes_free > MAX_UINT_32) ? MAX_UINT_32 : bytes_free;
                if (param_ptr) *((uint_64*)param_ptr) = bytes_free;
            }
            break;
        case IO_IOCTL_FREE_CLUSTERS:
            MFS_lock(file_ptr, &drive_ptr);
            result = MFS_Get_disk_free_space_internal(drive_ptr,NULL);
            MFS_unlock(drive_ptr,FALSE);
            break;
        case IO_IOCTL_GET_CLUSTER_SIZE:
            MFS_lock(file_ptr, &drive_ptr);
            *param_ptr = (uint_32)drive_ptr->CLUSTER_SIZE_BYTES;
            MFS_unlock(drive_ptr,FALSE);
            break;
        case IO_IOCTL_GET_CURRENT_DIR:
            result = MFS_Get_current_dir(file_ptr, (char_ptr) param_ptr);
            break;
        case IO_IOCTL_CHANGE_CURRENT_DIR:
            param_ptr = (uint_32_ptr) MFS_Parse_Out_Device_Name((char_ptr) param_ptr);
            result = MFS_Change_current_dir(file_ptr, (char_ptr) param_ptr);
            break;
        case IO_IOCTL_CHECK_DIR_EXIST:
            param_ptr = (uint_32_ptr) MFS_Parse_Out_Device_Name((char_ptr) param_ptr);
            result = MFS_Check_dir_exist(file_ptr, (char_ptr) param_ptr);
            break;
            
        case IO_IOCTL_FIND_FIRST_FILE:
            result = MFS_Find_first_file(file_ptr, ((MFS_SEARCH_PARAM_PTR) param_ptr)->ATTRIBUTE,
                MFS_Parse_Out_Device_Name(((MFS_SEARCH_PARAM_PTR) param_ptr)->WILDCARD), 
                ((MFS_SEARCH_PARAM_PTR) param_ptr)->SEARCH_DATA_PTR); 
            break;
        case IO_IOCTL_FIND_NEXT_FILE:
            result = MFS_Find_next_file(file_ptr, (MFS_SEARCH_DATA_PTR) param_ptr);
            break;
        case IO_IOCTL_GET_FILE_ATTR:
            result = MFS_Get_file_attributes(file_ptr,
                MFS_Parse_Out_Device_Name(
                ((MFS_FILE_ATTR_PARAM_PTR) param_ptr)->PATHNAME),
                ((MFS_FILE_ATTR_PARAM_PTR) param_ptr)->ATTRIBUTE_PTR);            
            break;
        case IO_IOCTL_GET_DATE_TIME:
            result = MFS_Get_date_time(file_ptr, 
                ((MFS_DATE_TIME_PARAM_PTR) param_ptr)->DATE_PTR,
                ((MFS_DATE_TIME_PARAM_PTR) param_ptr)->TIME_PTR);
            break;      

        case IO_IOCTL_GET_LFN:
            MFS_lock(file_ptr, &drive_ptr);
            {
                MFS_GET_LFN_STRUCT_PTR  lfn_ptr = ((MFS_GET_LFN_STRUCT_PTR) param_ptr);
                char_ptr pathname = MFS_Parse_Out_Device_Name(lfn_ptr->PATHNAME);
                result = MFS_get_lfn(drive_ptr, pathname, lfn_ptr->LONG_FILENAME);
#if 0
                //            _mfs_error result;
                MFS_DIR_ENTRY_PTR       entry_ptr;

                if ( lfn_ptr->SEARCH_DATA_PTR )
                {
                    entry_ptr = 
                        MFS_Read_directory_sector(drive_ptr,lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.CURRENT_CLUSTER, 
                        INDEX_TO_SECTOR(lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX), &result);
                    if ( (result== MFS_NO_ERROR && entry_ptr!=NULL) )
                    {
                        entry_ptr += INDEX_TO_OFFSET (lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX);

                        result = MFS_get_lfn_of_entry(drive_ptr,entry_ptr,
                            lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.CURRENT_CLUSTER,
                            lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.DIR_ENTRY_INDEX,
                            lfn_ptr->SEARCH_DATA_PTR->INTERNAL_SEARCH_DATA.PREV_CLUSTER,
                            lfn_ptr->LONG_FILENAME);
                    }

                }
                else
                {
                    result = MFS_get_lfn(drive_ptr, pathname, lfn_ptr->LONG_FILENAME);
                }
#endif
            }
            MFS_unlock(drive_ptr,FALSE);
            break;
        case IO_IOCTL_GET_VOLUME:
            result = MFS_Get_volume(file_ptr, (char_ptr) param_ptr);
            break;

#if MFSCFG_READ_ONLY
        case IO_IOCTL_DELETE_FILE:
        case IO_IOCTL_CREATE_SUBDIR:
        case IO_IOCTL_REMOVE_SUBDIR:
        case IO_IOCTL_RENAME_FILE:
        case IO_IOCTL_SET_FILE_ATTR:
        case IO_IOCTL_FLUSH_OUTPUT:
        case IO_IOCTL_SET_DATE_TIME:
        case IO_IOCTL_SET_VOLUME:
        case IO_IOCTL_FORMAT:
        case IO_IOCTL_DEFAULT_FORMAT:
        case IO_IOCTL_FORMAT_TEST:
        case IO_IOCTL_WRITE_CACHE_ON:
        case IO_IOCTL_WRITE_CACHE_OFF:
        case IO_IOCTL_FAT_CACHE_ON:
        case IO_IOCTL_FAT_CACHE_OFF:
        case IO_IOCTL_FLUSH_FAT:
        case IO_IOCTL_TEST_UNUSED_CLUSTERS:
        case IO_IOCTL_SET_FAT_CACHE_MODE:
        case IO_IOCTL_SET_WRITE_CACHE_MODE:
        case IO_IOCTL_VERIFY_WRITES:
            result = MFS_OPERATION_NOT_ALLOWED;
            break;


        case IO_IOCTL_GET_FAT_CACHE_MODE:
        case IO_IOCTL_GET_WRITE_CACHE_MODE:
            if ( param_ptr )
            {
                *(_mfs_cache_policy *)param_ptr = MFS_WRITE_THROUGH_CACHE;
            }
            else
            {
                result = MQX_INVALID_POINTER;
            }
            break;
#else

        case IO_IOCTL_DELETE_FILE:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                param_ptr = (uint_32_ptr) 
                MFS_Parse_Out_Device_Name((char_ptr) param_ptr);
                result = MFS_Delete_file(file_ptr, (char_ptr) param_ptr);
            }
            break;
        case IO_IOCTL_CREATE_SUBDIR:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                param_ptr = (uint_32_ptr) MFS_Parse_Out_Device_Name((char_ptr) param_ptr);
                result = MFS_Create_subdir(file_ptr, (char_ptr) param_ptr);
            }
            break;
        case IO_IOCTL_REMOVE_SUBDIR:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                param_ptr = (uint_32_ptr) MFS_Parse_Out_Device_Name((char_ptr) param_ptr);
                result = MFS_Remove_subdir(file_ptr, (char_ptr) param_ptr);      
            }
            break;

        case IO_IOCTL_RENAME_FILE:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                result = MFS_Rename_file(file_ptr, 
                    MFS_Parse_Out_Device_Name( ((MFS_RENAME_PARAM_PTR) param_ptr)->OLD_PATHNAME),
                    MFS_Parse_Out_Device_Name( ((MFS_RENAME_PARAM_PTR) param_ptr)->NEW_PATHNAME));
            }
            break;
        case IO_IOCTL_SET_FILE_ATTR:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                result = MFS_Set_file_attributes(file_ptr, 
                    MFS_Parse_Out_Device_Name( ((MFS_FILE_ATTR_PARAM_PTR) param_ptr)->PATHNAME),
                    ((MFS_FILE_ATTR_PARAM_PTR) param_ptr)->ATTRIBUTE_PTR);            
            }
            break;                                                   

        case IO_IOCTL_SET_DATE_TIME:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                result = MFS_Set_date_time(file_ptr, 
                    ((MFS_DATE_TIME_PARAM_PTR) param_ptr)->DATE_PTR,
                    ((MFS_DATE_TIME_PARAM_PTR) param_ptr)->TIME_PTR);
            }
            break;      

        case IO_IOCTL_SET_VOLUME:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                result = MFS_Set_volume(file_ptr, (char_ptr) param_ptr);
            }
            break;

        case IO_IOCTL_WRITE_CACHE_ON:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                MFS_lock(file_ptr, &drive_ptr);
                drive_ptr->WRITE_CACHE_POLICY = MFS_WRITE_BACK_CACHE;
                MFS_unlock(drive_ptr,FALSE);
            }
            break;

        case IO_IOCTL_WRITE_CACHE_OFF:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                MFS_lock(file_ptr, &drive_ptr);
                drive_ptr->WRITE_CACHE_POLICY = MFS_WRITE_THROUGH_CACHE;
                MFS_unlock(drive_ptr,FALSE);      
            }
            break;

        case IO_IOCTL_FLUSH_OUTPUT:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                MFS_HANDLE_PTR handle;

                /* lock the filesystem and obtain file handle */
                result = MFS_lock_handle(file_ptr, &drive_ptr, &handle);
                if (result == MFS_ERROR_INVALID_FILE_HANDLE)
                {
                    /* file_ptr is not associated with a particular file, at least try to lock the filesystem */
                    handle = NULL;
                    result = MFS_lock(file_ptr, &drive_ptr);
                }

                if ( result == MFS_NO_ERROR )
                {
                    if (handle != NULL && handle->TOUCHED)
                    {
                        TIME_STRUCT time;
                        DATE_STRUCT clk_time;

                        _time_get(&time);
                        _time_to_date(&time, &clk_time);
                        NORMALIZE_DATE(&clk_time);
                        htods(handle->DIR_ENTRY.TIME, PACK_TIME(clk_time));
                        htods(handle->DIR_ENTRY.DATE, PACK_DATE(clk_time));
                        result = MFS_Update_entry(drive_ptr, handle);
                    }

                    MFS_Flush_caches(drive_ptr);
                    MFS_unlock(drive_ptr,FALSE);
                }
            }
            break;

        case IO_IOCTL_SET_WRITE_CACHE_MODE:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                if ( param_ptr )
                {
                    _mfs_cache_policy    policy = *((_mfs_cache_policy *)param_ptr);
                    if ( (policy==MFS_WRITE_THROUGH_CACHE) || (policy==MFS_MIXED_MODE_CACHE) || (policy==MFS_WRITE_BACK_CACHE) )
                    {
                        MFS_lock(file_ptr, &drive_ptr);
                        drive_ptr->WRITE_CACHE_POLICY = policy;
                        MFS_unlock(drive_ptr,TRUE);
                    }
                    else
                    {
                        result = MFS_INVALID_PARAMETER;
                    }
                }
                else
                {
                    result = MQX_INVALID_POINTER;
                }
            }
            break;


        case IO_IOCTL_GET_WRITE_CACHE_MODE:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                if ( param_ptr )
                {
                    drive_ptr = file_ptr->DEV_PTR->DRIVER_INIT_PTR;
                    *((_mfs_cache_policy *)param_ptr) = drive_ptr->WRITE_CACHE_POLICY ;
                }
                else
                {
                    result = MQX_INVALID_POINTER;
                }
            }
            break;

        case IO_IOCTL_FAT_CACHE_ON:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                MFS_lock(file_ptr, &drive_ptr);
                drive_ptr->FAT_CACHE_POLICY = MFS_WRITE_BACK_CACHE;
                MFS_unlock(drive_ptr,FALSE);
            }
            break;

        case IO_IOCTL_FAT_CACHE_OFF:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                MFS_lock(file_ptr, &drive_ptr);
                drive_ptr->FAT_CACHE_POLICY = MFS_WRITE_THROUGH_CACHE;
                MFS_unlock(drive_ptr,FALSE);      
            }
            break;

        case IO_IOCTL_FLUSH_FAT:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                MFS_lock(file_ptr, &drive_ptr);
                MFS_Flush_fat_cache(drive_ptr);
                MFS_unlock(drive_ptr,FALSE);
            }
            break;

        case IO_IOCTL_SET_FAT_CACHE_MODE:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                if ( param_ptr )
                {
                    _mfs_cache_policy    policy = *((_mfs_cache_policy *)param_ptr);
                    if ( (policy==MFS_WRITE_THROUGH_CACHE) || (policy==MFS_MIXED_MODE_CACHE) || (policy==MFS_WRITE_BACK_CACHE) )
                    {
                        MFS_lock(file_ptr, &drive_ptr);
                        drive_ptr->FAT_CACHE_POLICY = policy;
                        MFS_unlock(drive_ptr,TRUE);
                    }
                    else
                    {
                        result = MFS_INVALID_PARAMETER;
                    }
                }
                else
                {
                    result = MQX_INVALID_POINTER;
                }
            }
            break;

        case IO_IOCTL_GET_FAT_CACHE_MODE:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                if ( param_ptr )
                {
                    drive_ptr = file_ptr->DEV_PTR->DRIVER_INIT_PTR;
                    *((_mfs_cache_policy *)param_ptr) = drive_ptr->FAT_CACHE_POLICY;
                }
                else
                {
                    result = MQX_INVALID_POINTER;
                }
            }
            break;

        case IO_IOCTL_TEST_UNUSED_CLUSTERS:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                result = MFS_Test_unused_clusters(file_ptr, param_ptr);
            }
            break;

        case IO_IOCTL_VERIFY_WRITES:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                MFS_lock(file_ptr, &drive_ptr);
                if (param_ptr) {
                   if (!drive_ptr->READBACK_SECTOR_PTR && drive_ptr->BPB.SECTOR_SIZE ) {
                      drive_ptr->READBACK_SECTOR_PTR = MFS_mem_alloc(drive_ptr->BPB.SECTOR_SIZE);
                      _mem_set_type(drive_ptr->READBACK_SECTOR_PTR, MEM_TYPE_MFS_DATA_SECTOR); 
                   }   
                   result =  (drive_ptr->READBACK_SECTOR_PTR != NULL)?MQX_OK:MQX_OUT_OF_MEMORY; 
                } else {
                   if (drive_ptr->READBACK_SECTOR_PTR) {
                      _mem_free(drive_ptr->READBACK_SECTOR_PTR);
                      drive_ptr->READBACK_SECTOR_PTR = NULL;
                   }
                   result = MQX_OK;   
                }
                MFS_unlock(drive_ptr,FALSE);
            }
            break;

#ifdef MFSCFG_ENABLE_FORMAT

        case IO_IOCTL_FORMAT:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                result = MFS_Format(file_ptr, ((MFS_IOCTL_FORMAT_PARAM_PTR) param_ptr)->FORMAT_PTR);
            }
            break;
            
        case IO_IOCTL_DEFAULT_FORMAT:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                result = MFS_Default_Format(file_ptr);
            }
            break;
            
        case IO_IOCTL_FORMAT_TEST:
#if MFSCFG_READ_ONLY_CHECK
            if (MFS_is_read_only (file_ptr, NULL))
            {
                result = MFS_DISK_IS_WRITE_PROTECTED;
            }
#endif
            if (result == MQX_OK)
            {
                result = MFS_Format_and_test(file_ptr,
                    ((MFS_IOCTL_FORMAT_PARAM_PTR) param_ptr)->FORMAT_PTR, 
                    ((MFS_IOCTL_FORMAT_PARAM_PTR) param_ptr)->COUNT_PTR); 
            }
            break;
#else
        case IO_IOCTL_FORMAT:
        case IO_IOCTL_DEFAULT_FORMAT:
        case IO_IOCTL_FORMAT_TEST:
            result = MFS_OPERATION_NOT_ALLOWED;
            break;

#endif

#endif

        case IO_IOCTL_GET_DEVICE_HANDLE:
            drive_ptr = (MFS_DRIVE_STRUCT_PTR) file_ptr->DEV_PTR->DRIVER_INIT_PTR;
            *param_ptr = (uint_32)drive_ptr->DEV_FILE_PTR;
            result = MQX_OK;
            break;

        default:
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }  

    return( (int_32) result);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_free_drive_data
* Returned Value   : 
* Comments  :   
*
*END*---------------------------------------------------------------------*/

static void MFS_free_drive_data( MFS_DRIVE_STRUCT_PTR drive_ptr, boolean all)
{
    if ( (drive_ptr->DIR_SECTOR_PTR != NULL) && all )
    {
        _mem_free(drive_ptr->DIR_SECTOR_PTR);
        drive_ptr->DIR_SECTOR_PTR = NULL;
    }

    if ( drive_ptr->DATA_SECTOR_PTR != NULL )
    {
        _mem_free(drive_ptr->DATA_SECTOR_PTR);
        drive_ptr->DATA_SECTOR_PTR = NULL;
    }

    if ( drive_ptr->FAT_CACHE_PTR != NULL )
    {
        _mem_free(drive_ptr->FAT_CACHE_PTR);
        drive_ptr->FAT_CACHE_PTR = NULL;
    }
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Mount_drive_internal
* Returned Value   : error code
* Comments  :   Used to set the MFS drive parameters for a unit.  
*   This function assumes that the boot sector of the drive is stored in
*   the drive's sector buffer.  This function is called after MFS is 
*   initialized, or after the drive has been formatted.
*
*   NOTE: It is assumed that the drive is locked by the 
*   calling function.
*
*END*---------------------------------------------------------------------*/

uint_32 MFS_Mount_drive_internal
    (
    MFS_DRIVE_STRUCT_PTR         drive_ptr
    )
{
    BIOS_PARAM_STRUCT_DISK_PTR   bpb_ptr;
    BIOS_PARAM32_STRUCT_DISK_PTR bpb32_ptr;
    FILESYSTEM_INFO_DISK_PTR     fsinfo_ptr;
    uint_32                      k,fat_size, root_dir_sectors,
        data_sectors, cluster_count, 
        error_code = MFS_NO_ERROR;
    uint_32                      temp[3];

    /*
    ** First, deallocate the FAT and CLUSTER buffers previously allocated.  
    ** If the unit has changed or been reformated, these may not be the same 
    ** size.
    */
    MFS_free_drive_data(drive_ptr, FALSE);

    /*
    ** Next, check  to see that the BOOT record is that of a DOS disk.  If  not,
    ** the drive will have to be formatted by the upper layer before the drive
    ** can be 'mounted'.
    */
    if ( (*drive_ptr->DIR_SECTOR_PTR != (char) MFS_DOS30_JMP) && 
        (*drive_ptr->DIR_SECTOR_PTR != (char)MFS_DOS30_B) )
    {
        drive_ptr->DOS_DISK = FALSE;
        return MFS_NOT_A_DOS_DISK;
    }


    /*
    ** Extract the drive parameters (BIOS Parameter Block) from the BOOT Record.
    */
    bpb_ptr = (BIOS_PARAM_STRUCT_DISK_PTR) drive_ptr->DIR_SECTOR_PTR;

    drive_ptr->BPB.SECTOR_SIZE =         dtohs(bpb_ptr->SECTOR_SIZE);
    drive_ptr->BPB.SECTORS_PER_CLUSTER = dtohc(bpb_ptr->SECTORS_PER_CLUSTER);
    drive_ptr->BPB.RESERVED_SECTORS =    dtohs(bpb_ptr->RESERVED_SECTORS);
    drive_ptr->BPB.NUMBER_OF_FAT =       dtohc(bpb_ptr->NUMBER_OF_FAT);
    drive_ptr->BPB.ROOT_ENTRIES =        dtohs(bpb_ptr->ROOT_ENTRIES);
    drive_ptr->BPB.NUMBER_SECTORS =      dtohs(bpb_ptr->NUMBER_SECTORS);
    drive_ptr->BPB.MEDIA_TYPE =          dtohc(bpb_ptr->MEDIA_TYPE);
    drive_ptr->BPB.SECTORS_PER_FAT =     dtohs(bpb_ptr->SECTORS_PER_FAT);
    drive_ptr->BPB.SECTORS_PER_TRACK =   dtohs(bpb_ptr->SECTORS_PER_TRACK);
    drive_ptr->BPB.NUM_HEADS =           dtohs(bpb_ptr->NUM_HEADS);
    drive_ptr->BPB.HIDDEN_SECTORS =      dtohl(bpb_ptr->HIDDEN_SECTORS);
    drive_ptr->BPB.MEGA_SECTORS =        dtohl(bpb_ptr->MEGA_SECTORS);

    if ( drive_ptr->BPB.NUMBER_SECTORS != 0 )
    {
        drive_ptr->BPB.MEGA_SECTORS = drive_ptr->BPB.NUMBER_SECTORS;
    }

    /* Determine FAT type by calculating the count of clusters on disk */
    root_dir_sectors = ((drive_ptr->BPB.ROOT_ENTRIES * sizeof(MFS_DIR_ENTRY))
        + (drive_ptr->BPB.SECTOR_SIZE - 1)) / drive_ptr->BPB.SECTOR_SIZE;

    bpb32_ptr = (BIOS_PARAM32_STRUCT_DISK_PTR) (drive_ptr->DIR_SECTOR_PTR + sizeof(BIOS_PARAM_STRUCT_DISK));
    if ( drive_ptr->BPB.SECTORS_PER_FAT == 0 )
    {
        fat_size = dtohl(bpb32_ptr->FAT_SIZE);
    }
    else
    {
        fat_size = drive_ptr->BPB.SECTORS_PER_FAT; 
    }  

    data_sectors = drive_ptr->BPB.MEGA_SECTORS - (drive_ptr->BPB.RESERVED_SECTORS + 
        (drive_ptr->BPB.NUMBER_OF_FAT * fat_size) + root_dir_sectors);

    cluster_count = data_sectors / drive_ptr->BPB.SECTORS_PER_CLUSTER;

    /* Now we have cluster count, so we can determine FAT type */
    if ( cluster_count < 4085 )
    {
        drive_ptr->FAT_TYPE = MFS_FAT12;
    }
    else if ( cluster_count < 65525 )
    {
        drive_ptr->FAT_TYPE = MFS_FAT16;
    }
    else
    {
        drive_ptr->FAT_TYPE = MFS_FAT32;
    }  

    /*
    ** Calculate the rest of the drive data.
    */
    k = drive_ptr->BPB.SECTORS_PER_CLUSTER;
    for ( drive_ptr->CLUSTER_POWER_SECTORS = 0; !(k & 1); drive_ptr->CLUSTER_POWER_SECTORS++ )
    {
        k>>=1;
    }  

    drive_ptr->CLUSTER_SIZE_BYTES = drive_ptr->BPB.SECTORS_PER_CLUSTER * drive_ptr->BPB.SECTOR_SIZE;

    k = drive_ptr->BPB.SECTOR_SIZE;
    for ( drive_ptr->SECTOR_POWER = 0; !(k & 1); drive_ptr->SECTOR_POWER++ )
    {
        k>>=1;
    }  

    drive_ptr->CLUSTER_POWER_BYTES = drive_ptr->SECTOR_POWER + drive_ptr->CLUSTER_POWER_SECTORS;

    drive_ptr->CUR_DIR_CLUSTER = 0;
    drive_ptr->FREE_COUNT = FSI_UNKNOWN; /* This is the unknown value */
    drive_ptr->NEXT_FREE_CLUSTER = FSI_UNKNOWN; /* MFS will calculate it later */
    drive_ptr->CURRENT_DIR[0] = '\\'; /* Root dir */
    drive_ptr->CURRENT_DIR[1] = '\0';
    drive_ptr->ENTRIES_PER_SECTOR = drive_ptr->BPB.SECTOR_SIZE / sizeof(MFS_DIR_ENTRY);

    drive_ptr->FAT_START_SECTOR =  drive_ptr->BPB.RESERVED_SECTORS;

    drive_ptr->DATA_SECTOR_PTR = MFS_mem_alloc_system_zero(drive_ptr->BPB.SECTOR_SIZE);
    if ( drive_ptr->DATA_SECTOR_PTR == NULL )
    {
        error_code = MFS_INSUFFICIENT_MEMORY;
    }
    else
    {
        _mem_set_type(drive_ptr->DATA_SECTOR_PTR, MEM_TYPE_MFS_DATA_SECTOR);
        
        /* Determine if we should enable the FAT and write caches */
        if ( (ioctl(drive_ptr->DEV_FILE_PTR, IO_IOCTL_DEVICE_IDENTIFY, temp) != MQX_OK) || !(temp[IO_IOCTL_ID_ATTR_ELEMENT] & IO_DEV_ATTR_REMOVE) )
        {
            /* 
            ** Device either doesn't support the identify command or is not removable.
            ** Assume we can enable both caches
            */
            drive_ptr->WRITE_CACHE_POLICY = MFS_WRITE_BACK_CACHE;
            drive_ptr->FAT_CACHE_POLICY   = MFS_WRITE_BACK_CACHE;
            drive_ptr->READ_ONLY = FALSE;
        }
        else
        {
            // Device is removable. Disable FAT cache to ensure device is not removed without
            // fat cache flush. Enable Mixed mode write cache (only cache during consecitive file writes)
            drive_ptr->WRITE_CACHE_POLICY = MFS_MIXED_MODE_CACHE;
            drive_ptr->FAT_CACHE_POLICY   = MFS_WRITE_THROUGH_CACHE;   //
            drive_ptr->READ_ONLY = (temp[IO_IOCTL_ID_ATTR_ELEMENT] & IO_DEV_ATTR_WRITE) == 0;
        }  
        
        if ( drive_ptr->FAT_TYPE != MFS_FAT32 )
        {
            drive_ptr->ROOT_START_SECTOR = drive_ptr->FAT_START_SECTOR + (drive_ptr->BPB.SECTORS_PER_FAT * drive_ptr->BPB.NUMBER_OF_FAT);
            drive_ptr->DATA_START_SECTOR = drive_ptr->ROOT_START_SECTOR + drive_ptr->BPB.ROOT_ENTRIES/drive_ptr->ENTRIES_PER_SECTOR;
        }
        else
        {
            if ( !error_code )
            {
                drive_ptr->BPB32.FAT_SIZE = dtohl(bpb32_ptr->FAT_SIZE);
                drive_ptr->BPB32.EXT_FLAGS = dtohs(bpb32_ptr->EXT_FLAGS);
                drive_ptr->BPB32.FS_VER = dtohs(bpb32_ptr->FS_VER);
                drive_ptr->BPB32.ROOT_CLUSTER = dtohl(bpb32_ptr->ROOT_CLUSTER);
                drive_ptr->BPB32.FS_INFO = dtohs(bpb32_ptr->FS_INFO);
                drive_ptr->BPB32.BK_BOOT_SEC = dtohs(bpb32_ptr->BK_BOOT_SEC);

                drive_ptr->ROOT_START_SECTOR = 0;
                drive_ptr->DATA_START_SECTOR = drive_ptr->FAT_START_SECTOR + (drive_ptr->BPB32.FAT_SIZE * drive_ptr->BPB.NUMBER_OF_FAT);
                drive_ptr->CUR_DIR_CLUSTER = drive_ptr->BPB32.ROOT_CLUSTER;

                /* 
                ** Reset the FSInfo->Free_Count and the FSInfo->Next_Free to 
                ** unknown (0xFFFFFFFF). MFS uses it's own internal version of these
                ** fields. If Windows uses the same disk, it will recalculate the 
                ** correct fields the first time it mounts the drive.
                */

                /* Check filesystem version for FAT32 */
                if ( drive_ptr->BPB32.FS_VER > MFS_FAT32_VER )
                {
                    error_code = MFS_ERROR_UNKNOWN_FS_VERSION;
                }

                if ( !error_code )
                {
                    fsinfo_ptr = (FILESYSTEM_INFO_DISK_PTR) drive_ptr->DATA_SECTOR_PTR;
                    error_code = MFS_Read_device_sector(drive_ptr, FSINFO_SECTOR, (char_ptr)fsinfo_ptr);

                    if ( (dtohl(fsinfo_ptr->LEAD_SIG) == FSI_LEADSIG) &&  (dtohl(fsinfo_ptr->STRUCT_SIG) == FSI_STRUCTSIG) &&
                         (dtohl(fsinfo_ptr->TRAIL_SIG) == FSI_TRAILSIG) )
                    {
                        drive_ptr->FREE_COUNT = dtohl(fsinfo_ptr->FREE_COUNT);
                        drive_ptr->NEXT_FREE_CLUSTER = dtohl(fsinfo_ptr->NEXT_FREE);
                    }

                    htodl(fsinfo_ptr->LEAD_SIG, FSI_LEADSIG);
                    htodl(fsinfo_ptr->STRUCT_SIG, FSI_STRUCTSIG);
                    htodl(fsinfo_ptr->FREE_COUNT, FSI_UNKNOWN);   /* compute it */
                    htodl(fsinfo_ptr->NEXT_FREE, FSI_UNKNOWN);  /* compute it */
                    htodl(fsinfo_ptr->TRAIL_SIG, FSI_TRAILSIG);
#if !MFSCFG_READ_ONLY
#if MFSCFG_READ_ONLY_CHECK
                    if (! MFS_is_read_only (NULL, drive_ptr))
                    {
#endif
                        if (error_code == MFS_NO_ERROR)
                        {
                            error_code = MFS_Write_device_sector(drive_ptr, FSINFO_SECTOR, (char_ptr)fsinfo_ptr);
                        }
#if MFSCFG_READ_ONLY_CHECK
                    }
#endif
#endif
                }
            }
        }  

        drive_ptr->LAST_CLUSTER   = (drive_ptr->BPB.MEGA_SECTORS - drive_ptr->DATA_START_SECTOR) / drive_ptr->BPB.SECTORS_PER_CLUSTER + 1;

        if ( !error_code )
        {
            /* Set the fat buffer size */
            if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
                drive_ptr->FAT_CACHE_SIZE = drive_ptr->BPB32.FAT_SIZE;
            else
                drive_ptr->FAT_CACHE_SIZE = drive_ptr->BPB.SECTORS_PER_FAT;

            if ( drive_ptr->FAT_CACHE_SIZE > MFSCFG_FAT_CACHE_SIZE )
            {
                drive_ptr->FAT_CACHE_SIZE = (MFSCFG_FAT_CACHE_SIZE < 2 ? 2 : MFSCFG_FAT_CACHE_SIZE);
            }
            
            drive_ptr->FAT_CACHE_PTR = MFS_mem_alloc_system_zero( drive_ptr->FAT_CACHE_SIZE * drive_ptr->BPB.SECTOR_SIZE);

            if ( drive_ptr->FAT_CACHE_PTR == NULL )
            {
                error_code = MFS_INSUFFICIENT_MEMORY;
            }
            else
            {
                _mem_set_type(drive_ptr->FAT_CACHE_PTR, MEM_TYPE_MFS_FAT_BUFFER);

                drive_ptr->FAT_CACHE_DIRTY = FALSE;
                drive_ptr->FAT_CACHE_START = 1;
                /*
                ** force ignorance of 0, so the first fat sector can be
                ** read in
                */

                error_code = MFS_Read_fat(drive_ptr, 0);
                
                drive_ptr->DOS_DISK = TRUE;
                MFS_Invalidate_data_sector(drive_ptr);
  
            }  
        }
    }

    if ( error_code )
    {
        MFS_free_drive_data(drive_ptr, TRUE);
    }

    return error_code;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Parse_Out_Device_name
* Returned Value   : A pointer to character following the semi-colon (':')
* Comments  :   Isolates the pathname and filename
*
*END*---------------------------------------------------------------------*/

char_ptr MFS_Parse_Out_Device_Name
    (
    char_ptr          name_ptr
    )
{
    char_ptr             start_path_ptr;

    start_path_ptr = name_ptr;

    /* Parse out the device name */
    while ( (*start_path_ptr  != ':') && (*start_path_ptr != '\0') )
    {
        start_path_ptr = start_path_ptr + 1;   
    }  

    if ( *start_path_ptr == '\0' )
    {
        start_path_ptr = name_ptr;
    }
    else
    {
        start_path_ptr++;
    } 

    return(start_path_ptr );
}  


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : MFS_Open_Device
* Returned Value   : MQX_OK or an error
* Comments         : Opens and initializes MFS driver.
* 
*END*----------------------------------------------------------------------*/

int_32 MFS_Open_Device
    (
    MQX_FILE_PTR             fd_ptr,        /* [IN] the MFS file handle for the device being opened */
    MFS_DRIVE_STRUCT_PTR     drive_ptr
    )
{
    MQX_FILE_PTR dev_fd;
    uint_32     sector_size, k;
    int_32      error_code;

    dev_fd = drive_ptr->DEV_FILE_PTR;

    fd_ptr->DEV_DATA_PTR = NULL;
    drive_ptr->MFS_FILE_PTR = fd_ptr;

    /* Select partition, if desired */
    if (drive_ptr->DRV_NUM)
    {
        error_code = ioctl(dev_fd, IO_IOCTL_SEL_PART, &drive_ptr->DRV_NUM);
        if (error_code)
        {
            return error_code;
        }
    }

    /*
    ** obtain the buffer for configuration data and for storing general
    ** sector reads
    */
    error_code = _mfs_validate_device(dev_fd, &sector_size, &drive_ptr->BLOCK_MODE);

    if ( error_code )
    {
        /* Device isn't valid */
        drive_ptr->MFS_FILE_PTR = NULL;      
        return error_code;
    }

    _lwsem_wait(&drive_ptr->SEM);

    drive_ptr->BPB.SECTOR_SIZE = (uint_16) sector_size; 
    drive_ptr->DIR_SECTOR_PTR = MFS_mem_alloc_system_zero(sector_size);
    MFS_Invalidate_directory_sector(drive_ptr);

    if ( drive_ptr->DIR_SECTOR_PTR == NULL )
    {
        _lwsem_post(&drive_ptr->SEM);
        drive_ptr->MFS_FILE_PTR = NULL;      
        return MFS_INSUFFICIENT_MEMORY;
    }

    _mem_set_type(drive_ptr->DIR_SECTOR_PTR, MEM_TYPE_MFS_DIRECTORY_SECTOR); 
    _queue_init(&drive_ptr->HANDLE_LIST, 0);

    k = drive_ptr->BPB.SECTOR_SIZE;
    for ( drive_ptr->SECTOR_POWER = 0; !(k & 1);
        drive_ptr->SECTOR_POWER++ )
    {
        k>>=1;
    } 

    /*
    ** read boot sector and get the BIOS Parameter Block
    */
    error_code = MFS_Read_device_sector(drive_ptr, BOOT_SECTOR, drive_ptr->DIR_SECTOR_PTR);

    if ( error_code == MFS_NO_ERROR )
    {
        drive_ptr->DIR_SECTOR_NUMBER = BOOT_SECTOR;
        error_code = MFS_Mount_drive_internal(drive_ptr);
    }

    if ( !error_code )
    {
        /* Determine the real sector size */
        if ( sector_size != drive_ptr->BPB.SECTOR_SIZE )
        {
            _mem_free(drive_ptr->DIR_SECTOR_PTR);
            drive_ptr->DIR_SECTOR_PTR = MFS_mem_alloc_system_zero(drive_ptr->BPB.SECTOR_SIZE);
            MFS_Invalidate_directory_sector(drive_ptr);
            if ( drive_ptr->DIR_SECTOR_PTR == NULL )
            {
                error_code = MFS_INSUFFICIENT_MEMORY;
                drive_ptr->MFS_FILE_PTR = NULL;
            }
            else
            {
                _mem_set_type(drive_ptr->DIR_SECTOR_PTR, MEM_TYPE_MFS_DIRECTORY_SECTOR); 
            }
        }

        /* Calculate the free space on disk */
#if MFSCFG_CALCULATE_FREE_SPACE_ON_OPEN
        if ( !error_code )
        {
            MFS_Get_disk_free_space_internal(drive_ptr,(uint_32_ptr)&error_code);
        }
#endif
    }

    _lwsem_post(&drive_ptr->SEM);

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : MFS_Close_Device
* Returned Value   : MQX_OK or an error
* Comments         : Closes MFS driver.
* 
*END*----------------------------------------------------------------------*/

int_32 MFS_Close_Device
    (
    MQX_FILE_PTR             fd_ptr /* [IN] the MFS file handle for the device being closed */
    )
{
    MFS_DRIVE_STRUCT_PTR      drive_ptr;
    FILESYSTEM_INFO_DISK_PTR  fsinfo_ptr;
    int_32                    result = MFS_NO_ERROR;

#if !MFSCFG_READ_ONLY
#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (fd_ptr, NULL))
    {
        result = MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif
    if (result != MFS_DISK_IS_WRITE_PROTECTED)
    {
        result = _io_ioctl(fd_ptr, IO_IOCTL_FLUSH_OUTPUT, NULL); 
    }
#endif

    MFS_lock(fd_ptr, &drive_ptr);

#if !MFSCFG_READ_ONLY
    if (result != MFS_DISK_IS_WRITE_PROTECTED)
    {
        MFS_Flush_caches(drive_ptr);
    }
#endif

    if ( _queue_is_empty(&drive_ptr->HANDLE_LIST) )
    {
        if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
        {
#if !MFSCFG_READ_ONLY
            if (result != MFS_DISK_IS_WRITE_PROTECTED)
            {
                fsinfo_ptr = (FILESYSTEM_INFO_DISK_PTR)drive_ptr->DATA_SECTOR_PTR;
                if ( fsinfo_ptr != NULL )
                {
                    htodl(fsinfo_ptr->LEAD_SIG,   FSI_LEADSIG);
                    htodl(fsinfo_ptr->STRUCT_SIG, FSI_STRUCTSIG);
                    htodl(fsinfo_ptr->FREE_COUNT, drive_ptr->FREE_COUNT);
                    htodl(fsinfo_ptr->NEXT_FREE,  drive_ptr->NEXT_FREE_CLUSTER);
                    htodl(fsinfo_ptr->TRAIL_SIG,  FSI_TRAILSIG);

                    MFS_Write_device_sector(drive_ptr, FSINFO_SECTOR, (char_ptr)fsinfo_ptr);
                }
            }
#endif
        }

        MFS_free_drive_data(drive_ptr, TRUE);

        drive_ptr->MFS_FILE_PTR = NULL;
        result = MFS_NO_ERROR;
    }
    else
    {
        result = MFS_SHARING_VIOLATION;
    }  

    MFS_unlock(drive_ptr,FALSE);

    return result;

}  


/*FUNCTION*--------------------------------------------------------------
* 
* Function Name    : _mfs_partition_destroy
* Returned Value   : MQX_OK or an error code
* Comments         :
*    Destroys a partition allocated in kernel memory
*
*END*-----------------------------------------------------------------*/

uint_32 _mfs_partition_destroy
    (
    _partition_id partition /* [IN] the partition to destory */
    )
{
    return _partition_destroy(partition);
}


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/include/usb_phdc.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_phdc.h$
* $Version : 3.8.5.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
* @brief The file contains USB stack PHDC class layer api header function.
*
*****************************************************************************/

#ifndef _USB_PHDC_H
#define _USB_PHDC_H 1

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "devapi.h" 
#include "usb_class.h"
#include "usb_stack_config.h"
/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/

#define MAX_QOS_BIN_ELEMS                 (4) 
 /* the num of recieve endpoints */ 
#define PHDC_RX_ENDPOINTS                 (1)  
/* the num of transmit endpoints */ 
#define PHDC_TX_ENDPOINTS                 (2)   
#define SET_FEATURE_REQUEST               (3)
#define CLEAR_FEATURE_REQUEST             (1)
#define GET_STATUS_REQUEST                (0)
#define INVALID_VAL                       (0xFF)

#define PHDC_BULK_OUT_QOS         (0x88)
#define PHDC_BULK_IN_QOS          (0x88)
#define PHDC_INT_OUT_QOS          (0x88)
#define PHDC_INT_IN_QOS           (0x88)

#define  USB_SET_REQUEST_MASK             (0x02)

#define USB_APP_META_DATA_PARAMS_CHANGED  (0xF2)
#define USB_APP_FEATURE_CHANGED           (0xF3)
#define MAX_PHDC_OBJECT                   (0x01)

#if USB_METADATA_SUPPORTED
    #define META_DATA_MSG_PRE_IMPLEMENTED    (1)/*TRUE:1; FALSE:0*/
#else
    #define META_DATA_MSG_PRE_IMPLEMENTED    (0)/*TRUE:1; FALSE:0*/
#endif

#define USB_Class_PHDC_Periodic_Task USB_Class_Periodic_Task

/******************************************************************************
 * Types
 *****************************************************************************/
 
typedef uint_32 PHDC_HANDLE;

/* structure to hold a request in the endpoint QOS bin */

PACKED_STRUCT_BEGIN
struct _usb_class_phdc_qos_bin 
{
    uint_8 channel;       /* endpoint num */
    boolean meta_data;    /* packet is a meta data or not */
    uint_8 num_tfr;       /* num of transfers that follow the meta data packet.
                             used only when meta_data is TRUE */                               
    uint_8 qos;           /* qos of the transfers that follow the meta data 
                             packet */
    uint_8_ptr app_buff;  /* buffer to send */
    uint_32 size; /* size of the transfer */ 
} 
PACKED_STRUCT_END;

typedef struct _usb_class_phdc_qos_bin USB_CLASS_PHDC_QOS_BIN, *PTR_USB_CLASS_PHDC_QOS_BIN;

/* USB class phdc endpoint data */
  
typedef struct _usb_class_phdc_tx_endpoint 
{
    uint_8 endpoint;                     /* from the application */
    uint_8 type;                         /* from the application */
    uint_32 size;                         /* from the application */
    uint_8 qos;                          /* from the application */
    uint_8 current_qos;               /*from received meta data */
    uint_8 transfers_left;            /*from application meta data */
    uint_8 bin_consumer;              /* num of dequeued transfers */
    uint_8 bin_producer;              /* num of queued transfers */
    USB_CLASS_PHDC_QOS_BIN qos_bin[MAX_QOS_BIN_ELEMS]; 
}USB_CLASS_PHDC_TX_ENDPOINT;

typedef struct _usb_class_phdc_rx_endpoint 
{
    uint_8 endpoint;                     /* from the application */
    uint_8 type;                         /* from the application */
    uint_32 size;                         /* from the application */
    uint_8 qos;                          /* from the application */
    uint_8 current_qos;                  /*from received meta data */    
    uint_8 transfers_left;               /*from received meta data */
    uint_16 buffer_size;
    uint_8_ptr buff_ptr;
}USB_CLASS_PHDC_RX_ENDPOINT;
  
typedef struct _usb_class_phdc_endpoint_data 
{
    _usb_device_handle handle;
    uint_8 count_rx;
    uint_8 count_tx;    
    USB_CLASS_PHDC_RX_ENDPOINT ep_rx[PHDC_RX_ENDPOINTS];  
    USB_CLASS_PHDC_TX_ENDPOINT ep_tx[PHDC_TX_ENDPOINTS];      
}USB_CLASS_PHDC_ENDPOINT_DATA, *PTR_USB_CLASS_PHDC_ENDPOINT_DATA; 

typedef struct _usb_class_phdc_rx_buff 
{
    uint_8_ptr in_buff;  /* Pointer to input Buffer */
    uint_32 in_size; /* Length of Input Buffer*/
    uint_16 out_size; /* Size of Output Buffer */
    uint_8_ptr out_buff; /* Pointer to Output Buffer */
    uint_16 transfer_size;
#if USB_METADATA_SUPPORTED
    boolean meta_data_packet;/* meta data packet flag */
#endif
}USB_CLASS_PHDC_RX_BUFF, *PTR_USB_CLASS_PHDC_RX_BUFF;
  
/* event structures */ 
typedef struct _usb_app_event_send_complete 
{
    uint_8 qos;
    uint_8_ptr buffer_ptr;
    uint_32 size;
}USB_APP_EVENT_SEND_COMPLETE, *PTR_USB_APP_EVENT_SEND_COMPLETE;


typedef struct _usb_app_event_data_recieved 
{
    uint_8 qos;
    uint_8_ptr buffer_ptr;
    uint_32 size;
}USB_APP_EVENT_DATA_RECIEVED, *PTR_USB_APP_EVENT_DATA_RECIEVED;
  
#if USB_METADATA_SUPPORTED
    #define METADATA_PREAMBLE_SIGNATURE     (16)
    #define METADATA_QOSENCODING_VERSION    (1)
    #define METADATA_HEADER_SIZE            (21)
    /* structure for meta_data msg preamble */
    typedef struct _usb_meta_data_msg_preamble 
    {
        char signature[METADATA_PREAMBLE_SIGNATURE];
        uint_8 num_tfr;
        uint_8 version;
        uint_8 qos;
        uint_8 opaque_data_size;
        uint_8 opaque_data[1];
    }USB_META_DATA_MSG_PREAMBLE;

    typedef struct _usb_app_event_metadata_params 
    {
        uint_8 channel;
        uint_8 num_tfr;
        uint_8 qos;
        uint_8_ptr metadata_ptr;
        uint_32 size;
    }USB_APP_EVENT_METADATA_PARAMS, *PTR_USB_APP_EVENT_METADATA_PARAMS;
#endif

/* Structure Representing PHDC class */
typedef struct _phdc_struct
{
     _usb_device_handle  controller_handle;
    PHDC_HANDLE phdc_handle;
    USB_CLASS_HANDLE class_handle;
    USB_CLASS_CALLBACK_STRUCT phdc_callback;
    USB_REQ_CALLBACK_STRUCT vendor_callback; 
    /* RAM buffer for configuring next receive */
    uint_8_ptr service_buff_ptr; 
    USB_CLASS_PHDC_ENDPOINT_DATA ep_data;
    #if META_DATA_MSG_PRE_IMPLEMENTED
        USB_META_DATA_MSG_PREAMBLE meta_data_msg_preamble; 
    #endif
    #if USB_METADATA_SUPPORTED
        /* used to store whether meta-data feature is active or not */
        boolean phdc_metadata;
    #endif 
    /* used to store a bit map of the active endpoints */
    uint_16 phdc_ep_has_data;
}PHDC_STRUCT, _PTR_ PHDC_STRUCT_PTR;

/* Structures used to configure PHDC class by  APP*/
typedef struct _config_phdc_struct
{
    //uint_32 desc_endpoint_cnt;
    USB_CLASS_CALLBACK_STRUCT phdc_callback;
    USB_REQ_CALLBACK_STRUCT vendor_callback; 
    DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr;  
    USB_ENDPOINTS * info;  
}PHDC_CONFIG_STRUCT,_PTR_ PHDC_CONFIG_STRUCT_PTR;
 
/******************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Class_PHDC_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param  phdc_config_ptr[IN]  : Phdc configuration structure pointer
 * @return PHDC_HANDLE      : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 * This function initializes the PHDC Class layer and layers it is dependednt on 
 *****************************************************************************/                          
extern PHDC_HANDLE USB_Class_PHDC_Init
(
   PHDC_CONFIG_STRUCT_PTR phdc_config_ptr
);
/**************************************************************************//*!
 *
 * @name  USB_PHDC_Class_Recv_Data
 *
 * @brief This fucntion is used by Application to receive data through PHDC class
 *
 * @param phdc_handle     :   Handle returned by USB_Class_PHDC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 * This fucntion is used by Application to send data through PHDC class 
 *****************************************************************************/  
extern uint_8 USB_Class_PHDC_Recv_Data
(
    PHDC_HANDLE         phdc_handle,
    uint_8              qos, 
    uint_8_ptr          buff_ptr,      /* [IN] buffer to send */      
    uint_32             size           /* [IN] length of the transfer */
);
/**************************************************************************//*!
 *
 * @name  USB_Class_PHDC_Send_Data
 *
 * @brief This fucntion is used by Application to send data through PHDC class
 *
 * @param handle          :   handle returned by USB_Class_PHDC_Init
 * @param meta_data       :   packet is meta data or not
 * @param num_tfr         :   no. of transfers
 * @param qos             :   current qos of the transfer
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 * This fucntion is used by Application to send data through PHDC class 
 *****************************************************************************/  
extern uint_8 USB_Class_PHDC_Send_Data
(
    PHDC_HANDLE      handle,    
    boolean          meta_data,    /* opaque meta data in app buffer */
    uint_8           num_tfr,      /* no. of transfers to follow with given 
                                      channel--only valid if meta data is 
                                      true */
    uint_8           current_qos,  /* qos of the transfers to follow--only 
                                      valid if meta data is true */
    uint_8_ptr       app_buff,     /* buffer holding application data */
    uint_32  size           /* [IN] length of the transfer */
);
                               

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcslog.h<|end_filename|>
#ifndef __rtcslog_h__
#define __rtcslog_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcslog.h$
* $Version : 3.8.9.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the definitions for RTCS logging.
*
*END************************************************************************/

#include "mqx_cnfg.h"
#include "rtcscfg.h"

/*
** Code macros
*/

//#define RTCSLOG_NONE(t,p1,p2,p3,p4,p5)

#if RTCSCFG_LOGGING
#define RTCSLOG_LOG(t,p1,p2,p3,p4,p5) RTCS_log(t,p1,p2,p3,p4,p5)
#else
#define RTCSLOG_LOG(t,p1,p2,p3,p4,p5)
#endif 

#if RTCSCFG_LOG_SOCKET_API
#define RTCSLOG_API(t,p1,p2)     RTCS_log(t,(uint_32)(p1),(uint_32)(p2),0,0,0)
#else
#define RTCSLOG_API(t,p1,p2)      
#endif

#if RTCSCFG_LOG_PCB
#define RTCSLOG_PCB(t,p1,p2)     RTCS_log(t,p1,p2,0,0,0)
#else
#define RTCSLOG_PCB(t,p1,p2)     
#endif

#define RTCSLOG_PCB_ALLOC(pcb)            RTCSLOG_PCB( RTCSLOG_TYPE_PCB, \
                                                       RTCSLOG_PCBCMD_ALLOC, \
                                                       (uint_32)pcb)

#define RTCSLOG_PCB_FREE(pcb,err)         RTCSLOG_PCB( RTCSLOG_TYPE_PCB, \
                                                       RTCSLOG_PCBCMD_FREE | (err), \
                                                       (uint_32)pcb)

#define RTCSLOG_PCB_READ(pcb,prot,vers)   RTCSLOG_PCB( RTCSLOG_TYPE_PCB, \
                                                       RTCSLOG_PCBCMD_READ | ((vers) << 16) | (prot), \
                                                       (uint_32)pcb)

#define RTCSLOG_PCB_WRITE(pcb,prot,vers)  RTCSLOG_PCB( RTCSLOG_TYPE_PCB, \
                                                       RTCSLOG_PCBCMD_WRITE | ((vers) << 16) | (prot), \
                                                       (uint_32)pcb)

#define RTCSLOG_TIMER   RTCSLOG_NONE

#define RTCSLOG_FNE1(f)             RTCSLOG_LOG(RTCSLOG_TYPE_FNENTRY, f, 0, 0, 0, 0)
#define RTCSLOG_FNE2(f, a)          RTCSLOG_LOG(RTCSLOG_TYPE_FNENTRY, f, (uint_32)(a), 0, 0, 0)
#define RTCSLOG_FNE3(f, a, b)       RTCSLOG_LOG(RTCSLOG_TYPE_FNENTRY, f, (uint_32)(a), (uint_32)(b), 0, 0)
#define RTCSLOG_FNE4(f, a, b, c)    RTCSLOG_LOG(RTCSLOG_TYPE_FNENTRY, f, (uint_32)(a), (uint_32)(b), (uint_32)(c), 0)
#define RTCSLOG_FNE5(f, a, b, c, d) RTCSLOG_LOG(RTCSLOG_TYPE_FNENTRY, f, (uint_32)(a), (uint_32)(b), (uint_32)(c), (uint_32)(d))

#define RTCSLOG_FNX1(f)             RTCSLOG_LOG(RTCSLOG_TYPE_FNEXIT, f, 0, 0, 0, 0)
#define RTCSLOG_FNX2(f, a)          RTCSLOG_LOG(RTCSLOG_TYPE_FNEXIT, f, (uint_32)(a), 0, 0, 0)
#define RTCSLOG_FNX3(f, a , b)      RTCSLOG_LOG(RTCSLOG_TYPE_FNEXIT, f, (uint_32)(a), (uint_32)(b), 0, 0)
#define RTCSLOG_FNX4(f, a , b, c)   RTCSLOG_LOG(RTCSLOG_TYPE_FNEXIT, f, (uint_32)(a), (uint_32)(b), (uint_32)(c), 0)

/*
** Obsolete macros
*/

#define DEBUGTCP(x)     /*x*/

/*
** PCB actions
*/

#define RTCSLOG_PCBCMD_ALLOC     0x00000000
#define RTCSLOG_PCBCMD_FREE      0x40000000
#define RTCSLOG_PCBCMD_READ      0x80000000
#define RTCSLOG_PCBCMD_WRITE     0xC0000000
#define RTCSLOG_PCBCMD_MASK      0xC0000000


/*
** Function numbers
*/
#define RTCSLOG_FNBASE                 (KLOG_RTCS_FUNCTIONS)

#define RTCSLOG_FN_SOCKET              (RTCSLOG_FNBASE   )
#define RTCSLOG_FN_DGRAM_BIND          (RTCSLOG_FNBASE+ 1)
#define RTCSLOG_FN_DGRAM_CONNECT       (RTCSLOG_FNBASE+ 2)
#define RTCSLOG_FN_DGRAM_LISTEN        (RTCSLOG_FNBASE+ 3)
#define RTCSLOG_FN_DGRAM_ACCEPT        (RTCSLOG_FNBASE+ 4)
#define RTCSLOG_FN_DGRAM_GETSOCKNAME   (RTCSLOG_FNBASE+ 5)
#define RTCSLOG_FN_DGRAM_GETPEERNAME   (RTCSLOG_FNBASE+ 6)
#define RTCSLOG_FN_DGRAM_RECV          (RTCSLOG_FNBASE+ 7)
#define RTCSLOG_FN_DGRAM_RECVFROM      (RTCSLOG_FNBASE+ 8)
#define RTCSLOG_FN_DGRAM_RECVMSG       (RTCSLOG_FNBASE+ 9)
#define RTCSLOG_FN_DGRAM_SEND          (RTCSLOG_FNBASE+10)
#define RTCSLOG_FN_DGRAM_SENDTO        (RTCSLOG_FNBASE+11)
#define RTCSLOG_FN_DGRAM_SENDMSG       (RTCSLOG_FNBASE+12)
#define RTCSLOG_FN_DGRAM_SOCKATMARK    (RTCSLOG_FNBASE+13)
#define RTCSLOG_FN_DGRAM_SHUTDOWN      (RTCSLOG_FNBASE+14)
#define RTCSLOG_FN_STREAM_BIND         (RTCSLOG_FNBASE+15)
#define RTCSLOG_FN_STREAM_CONNECT      (RTCSLOG_FNBASE+16)
#define RTCSLOG_FN_STREAM_LISTEN       (RTCSLOG_FNBASE+17)
#define RTCSLOG_FN_STREAM_ACCEPT       (RTCSLOG_FNBASE+18)
#define RTCSLOG_FN_STREAM_GETSOCKNAME  (RTCSLOG_FNBASE+19)
#define RTCSLOG_FN_STREAM_GETPEERNAME  (RTCSLOG_FNBASE+20)
#define RTCSLOG_FN_STREAM_RECV         (RTCSLOG_FNBASE+21)
#define RTCSLOG_FN_STREAM_RECVFROM     (RTCSLOG_FNBASE+22)
#define RTCSLOG_FN_STREAM_RECVMSG      (RTCSLOG_FNBASE+23)
#define RTCSLOG_FN_STREAM_SEND         (RTCSLOG_FNBASE+24)
#define RTCSLOG_FN_STREAM_SENDTO       (RTCSLOG_FNBASE+25)
#define RTCSLOG_FN_STREAM_SENDMSG      (RTCSLOG_FNBASE+26)
#define RTCSLOG_FN_STREAM_SOCKATMARK   (RTCSLOG_FNBASE+27)
#define RTCSLOG_FN_STREAM_SHUTDOWN     (RTCSLOG_FNBASE+28)
#define RTCSLOG_FN_SOCKET_GETSOCKOPT   (RTCSLOG_FNBASE+29)
#define RTCSLOG_FN_SOCKET_SETSOCKOPT   (RTCSLOG_FNBASE+30)
#define RTCSLOG_FN_UDP_GETSOCKOPT      (RTCSLOG_FNBASE+31)
#define RTCSLOG_FN_UDP_SETSOCKOPT      (RTCSLOG_FNBASE+32)
#define RTCSLOG_FN_TCP_GETSOCKOPT      (RTCSLOG_FNBASE+33)
#define RTCSLOG_FN_TCP_SETSOCKOPT      (RTCSLOG_FNBASE+34)
#define RTCSLOG_FN_IP_GETSOCKOPT       (RTCSLOG_FNBASE+35)
#define RTCSLOG_FN_IP_SETSOCKOPT       (RTCSLOG_FNBASE+36)
#define RTCSLOG_FN_IGMP_GETSOCKOPT     (RTCSLOG_FNBASE+37)
#define RTCSLOG_FN_IGMP_SETSOCKOPT     (RTCSLOG_FNBASE+38)
#define RTCSLOG_FN_LINK_GETSOCKOPT     (RTCSLOG_FNBASE+39)
#define RTCSLOG_FN_LINK_SETSOCKOPT     (RTCSLOG_FNBASE+40)
#define RTCSLOG_FN_NAT_GETSOCKOPT      (RTCSLOG_FNBASE+41)
#define RTCSLOG_FN_NAT_SETSOCKOPT      (RTCSLOG_FNBASE+42)

#define RTCSLOG_FN_TCP_Must_send_ack                (RTCSLOG_FNBASE + 43)
#define RTCSLOG_FN_TCP_Process_data                 (RTCSLOG_FNBASE + 44)
#define RTCSLOG_FN_TCP_Advertise_receive_window     (RTCSLOG_FNBASE + 45)
#define RTCSLOG_FN_TCP_Start_receiving              (RTCSLOG_FNBASE + 46)
#define RTCSLOG_FN_TCP_Process_packet               (RTCSLOG_FNBASE + 47)
#define RTCSLOG_FN_TCP_Process_effective_close      (RTCSLOG_FNBASE + 48)
#define RTCSLOG_FN_TCP_Service_packet               (RTCSLOG_FNBASE + 49)
#define RTCSLOG_FN_IPLOCAL_service                  (RTCSLOG_FNBASE + 50)
#define RTCSLOG_FN_IPLOCAL_send                     (RTCSLOG_FNBASE + 51)
#define RTCSLOG_FN_IP_send_dgram                    (RTCSLOG_FNBASE + 52)
#define RTCSLOG_FN_IP_route                         (RTCSLOG_FNBASE + 53)
#define RTCSLOG_FN_IP_service                       (RTCSLOG_FNBASE + 54)
#define RTCSLOG_FN_TCPIP_task                       (RTCSLOG_FNBASE + 55)
#define RTCSLOG_FN_TCP_Event                        (RTCSLOG_FNBASE + 56)
#define RTCSLOG_FN_TCP_Process_signal               (RTCSLOG_FNBASE + 57)
#define RTCSLOG_FN_TCP_Tick_server                  (RTCSLOG_FNBASE + 58)
#define RTCSLOG_FN_TCP_Timer_expire                 (RTCSLOG_FNBASE + 59)
#define RTCSLOG_FN_TCP_Timer_schedule               (RTCSLOG_FNBASE + 60)
#define RTCSLOG_FN_TCP_Timer_remove                 (RTCSLOG_FNBASE + 61)
#define RTCSLOG_FN_TCP_Timer_stop                   (RTCSLOG_FNBASE + 62)
#define RTCSLOG_FN_TCP_Timer_start                  (RTCSLOG_FNBASE + 63)
#define RTCSLOG_FN_TCP_Timer_advance                (RTCSLOG_FNBASE + 64)
#define RTCSLOG_FN_TCP_Timer_oneshot_max            (RTCSLOG_FNBASE + 65)

#define RTCSLOG_FN_IPE_recv                         (RTCSLOG_FNBASE + 66)
#define RTCSLOG_FN_IPE_recv_IP                      (RTCSLOG_FNBASE + 67)
#define RTCSLOG_FN_IPE_send                         (RTCSLOG_FNBASE + 68)
#define RTCSLOG_FN_IPE_send_IP                      (RTCSLOG_FNBASE + 69)
#define RTCSLOG_FN_TCP_Transmit                     (RTCSLOG_FNBASE + 70)
#define RTCSLOG_FN_TCP_Send_packet                  (RTCSLOG_FNBASE + 71)

#define RTCSLOG_FN_IP6E_recv                        (RTCSLOG_FNBASE + 72)
#define RTCSLOG_FN_IP6E_recv_IP                     (RTCSLOG_FNBASE + 73)
#define RTCSLOG_FN_IP6_service                      (RTCSLOG_FNBASE + 74)
#define RTCSLOG_FN_IP6_send_dgram                   (RTCSLOG_FNBASE + 75)    


/*
** Prototypes
*/

#ifdef __cplusplus
extern "C" {
#endif

#if RTCSCFG_LOGGING
void RTCS_log (uint_32 logtype, uint_32 p1, uint_32 p2,uint_32 p3, uint_32 p4, uint_32 p5);

void RTCSLOG_enable       (uint_32 logtype);
void RTCSLOG_disable      (uint_32 logtype);
void RTCSLOG_enable_prot  (uint_32 logtype, uint_32 protocol);
void RTCSLOG_disable_prot (uint_32 logtype, uint_32 protocol);
#else
#define RTCS_log(t,p1,p2,p3,p4,p5)
#define RTCSLOG_enable(x)
#define RTCSLOG_disable(x)
#define RTCSLOG_enable_prot(t, x)
#define RTCSLOG_disable_prot(t, x)
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/nandflash/nandflash.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nandflash.c$
* $Version : 3.8.13.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains NAND flash driver functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "nandflash.h"
#include "nandflashprv.h"

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_nandflash_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a NAND flash driver.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_nandflash_install
   (
      /* [IN] The initialization structure for the device */
      NANDFLASH_INIT_STRUCT_CPTR  init_ptr
   )
{ /* Body */
   IO_NANDFLASH_STRUCT_PTR     dev_ptr;
  
   dev_ptr = (IO_NANDFLASH_STRUCT_PTR)_mem_alloc_system_zero(
      (_mem_size)sizeof(IO_NANDFLASH_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL) {
      return MQX_OUT_OF_MEMORY;
   } /* Endif */
#endif

   dev_ptr->INIT                 = init_ptr->INIT;
   dev_ptr->DEINIT               = init_ptr->DEINIT;
   dev_ptr->CHIP_ERASE           = init_ptr->CHIP_ERASE;
   dev_ptr->BLOCK_ERASE          = init_ptr->BLOCK_ERASE;
   dev_ptr->PAGE_READ            = init_ptr->PAGE_READ;
   dev_ptr->PAGE_PROGRAM         = init_ptr->PAGE_PROGRAM;
   dev_ptr->WRITE_PROTECT        = init_ptr->WRITE_PROTECT;
   dev_ptr->IS_BLOCK_BAD         = init_ptr->IS_BLOCK_BAD;
   dev_ptr->MARK_BLOCK_AS_BAD    = init_ptr->MARK_BLOCK_AS_BAD;
   dev_ptr->IOCTL                = init_ptr->IOCTL;
   dev_ptr->NANDFLASH_INFO_PTR   = init_ptr->NANDFLASH_INFO_PTR;
   dev_ptr->VIRTUAL_PAGE_SIZE    = BSP_VIRTUAL_PAGE_SIZE;
   dev_ptr->NUM_VIRTUAL_PAGES    = (init_ptr->NANDFLASH_INFO_PTR->BLOCK_SIZE / BSP_VIRTUAL_PAGE_SIZE) * init_ptr->NANDFLASH_INFO_PTR->NUM_BLOCKS;
   dev_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO    
                                 = (init_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE / BSP_VIRTUAL_PAGE_SIZE);
   dev_ptr->ECC_SIZE             = BSP_ECC_SIZE;
   dev_ptr->WRITE_VERIFY         = init_ptr->WRITE_VERIFY;
   dev_ptr->DEVICE_SPECIFIC_DATA = init_ptr->DEVICE_SPECIFIC_DATA;

   _lwsem_create(&dev_ptr->LWSEM, 1);
    
   return (_io_dev_install_ext(
      init_ptr->ID_PTR,
      _io_nandflash_open,
      _io_nandflash_close,
      _io_nandflash_read,
      _io_nandflash_write,
      _io_nandflash_ioctl,
      _io_nandflash_uninstall, 
      (pointer)dev_ptr)); 
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_nandflash_uninstall
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Uninstalls a NAND flash driver.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_nandflash_uninstall
   (
      /* [IN] The IO device structure for the device */
      IO_DEVICE_STRUCT_PTR   io_dev_ptr
   )
{ /* Body */
   IO_NANDFLASH_STRUCT_PTR handle_ptr = 
      (IO_NANDFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   if (handle_ptr->COUNT == 0) {
      _mem_free((pointer)handle_ptr);
      io_dev_ptr->DRIVER_INIT_PTR = NULL;
      return IO_OK;
   } else {
      return IO_ERROR_DEVICE_BUSY;
   } /* Endif */  
   
}  /* Endbody */    

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_nandflash_open
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         : Opens and initializes NAND flash driver.
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_nandflash_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR fd_ptr,
      
      /* [IN] the remaining portion of the name of the device */
      char_ptr   open_name_ptr,

      /* [IN] the flags to be used during operation: */
      char_ptr   flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR      io_dev_ptr = fd_ptr->DEV_PTR;
   IO_NANDFLASH_STRUCT_PTR   handle_ptr = 
      (IO_NANDFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   uint_32                   chip_initialized = NANDFLASHERR_NO_ERROR;
   uint_32                   num_ecc_bytes;
   
   if (handle_ptr->COUNT) {
      /* Device is already opened */
      fd_ptr->FLAGS = handle_ptr->FLAGS;
      handle_ptr->COUNT++;
      return MQX_OK;
   } /* Endif */
      
   if (handle_ptr->INIT) {
      chip_initialized = (*handle_ptr->INIT)(handle_ptr);
   }/* Endif */

#if MQX_CHECK_ERRORS
   if (chip_initialized != NANDFLASHERR_NO_ERROR) {
      return(IO_ERROR);
   } /* Endif */
#endif   
 
   /* Check if the sum of virtual page size (incl. ECC bytes) per one physical page 
      is not greater than the physical page size plus the number of physical spare bytes. */
   num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(handle_ptr->ECC_SIZE);
#if !(BSP_M5329EVB || BSP_TWRMPC5125)
   if(((handle_ptr->VIRTUAL_PAGE_SIZE + num_ecc_bytes) * handle_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO) > 
      (handle_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE + handle_ptr->NANDFLASH_INFO_PTR->SPARE_AREA_SIZE))
   {
      return ((_mqx_int)NANDFLASHERR_IMPROPER_ECC_SIZE);
   }
#endif
  
   handle_ptr->COUNT++;   
      
   return MQX_OK;  

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_nandflash_close
* Returned Value   : MQX_OK
* Comments         : Closes NAND flash driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_nandflash_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
   IO_NANDFLASH_STRUCT_PTR handle_ptr = 
      (IO_NANDFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   
   if (--handle_ptr->COUNT == 0) {
      if (handle_ptr->DEINIT) {
         (*handle_ptr->DEINIT)(handle_ptr);
      } /* Endif */
   } /* Endif */

   return MQX_OK;  
   
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_nandflash_read
* Returned Value   : number of pages read
* Comments         : Reads data from NAND flash memory device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_nandflash_read
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,
   
      /* [IN] where the data is to be stored */
      char_ptr   data_ptr,
   
      /* [IN] the number of pages to input */
      _mqx_int   num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
   IO_NANDFLASH_STRUCT_PTR handle_ptr  = 
      (IO_NANDFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   uint_32 error;

   fd_ptr->ERROR = IO_OK;
   if (NULL == handle_ptr->PAGE_READ)
   {
      fd_ptr->ERROR = IO_ERROR_READ;
      return IO_ERROR;
   } /* Endif */
   
   if ( (num + fd_ptr->LOCATION) > handle_ptr->NUM_VIRTUAL_PAGES ) 
   {
      fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
      num = (_mqx_int)(handle_ptr->NUM_VIRTUAL_PAGES - fd_ptr->LOCATION);
   } /* Endif */
   
   
   _lwsem_wait(&handle_ptr->LWSEM);
   
   error = (*handle_ptr->PAGE_READ)(handle_ptr, (uchar_ptr)data_ptr, fd_ptr->LOCATION, num);

   if (error == NANDFLASHERR_NO_ERROR)
   {
      fd_ptr->LOCATION += num;
   }
   else if (error == NANDFLASHERR_ECC_CORRECTED)
   {
      fd_ptr->LOCATION += num;
   }
   else
   {
      fd_ptr->ERROR = IO_ERROR_READ;
      num = IO_ERROR;
   } /* Endif */

   _lwsem_post(&handle_ptr->LWSEM);

   return num;
      
} /* Endbody */

 
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_nandflash_write
* Returned Value   : number of pages written
* Comments         : Writes data to the NAND flash memory device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_nandflash_write
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,
   
      /* [IN] where the data is stored */
      char_ptr   data_ptr,
   
      /* [IN] the number of pages to output */
      _mqx_int   num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
   IO_NANDFLASH_STRUCT_PTR handle_ptr  = 
      (IO_NANDFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

   fd_ptr->ERROR = IO_OK;
   if (NULL == handle_ptr->PAGE_PROGRAM)
   {
      fd_ptr->ERROR = IO_ERROR_WRITE;
      return IO_ERROR;
   } /* Endif */
   
   if (fd_ptr->FLAGS & IO_O_RDONLY)
   {
      fd_ptr->ERROR = IO_ERROR_WRITE_PROTECTED;
      return IO_ERROR;
   } /* Endif */
   
   if ( (num + fd_ptr->LOCATION) > handle_ptr->NUM_VIRTUAL_PAGES ) 
   {
      fd_ptr->FLAGS |= IO_FLAG_AT_EOF;
      num = (_mqx_int)(handle_ptr->NUM_VIRTUAL_PAGES - fd_ptr->LOCATION);
   } /* Endif */
   
   
   _lwsem_wait(&handle_ptr->LWSEM);
   
   if (((*handle_ptr->PAGE_PROGRAM)(handle_ptr, (uchar_ptr)data_ptr, fd_ptr->LOCATION, num)) == NANDFLASHERR_NO_ERROR)
   {
      fd_ptr->LOCATION += num;
   }
   else
   {
      fd_ptr->ERROR = IO_ERROR_WRITE;
      num = IO_ERROR;
   } /* Endif */

   _lwsem_post(&handle_ptr->LWSEM);

   return num;
      
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_nandflash_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_nandflash_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,
   
      /* [IN] the ioctl command */
      _mqx_uint  cmd,
   
      /* [IN/OUT] the ioctl parameters */
      pointer    param_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR               io_dev_ptr = fd_ptr->DEV_PTR;
   IO_NANDFLASH_STRUCT_PTR            handle_ptr = 
      (IO_NANDFLASH_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   _mqx_int                           result = MQX_OK;
   _mqx_uint                          i;
   _mqx_uint_ptr                      uparam_ptr;
   
   switch (cmd) {

      case NANDFLASH_IOCTL_GET_PHY_PAGE_SIZE:
         uparam_ptr = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = handle_ptr->NANDFLASH_INFO_PTR->PHY_PAGE_SIZE;
         break;

      case NANDFLASH_IOCTL_GET_SPARE_AREA_SIZE:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = handle_ptr->NANDFLASH_INFO_PTR->SPARE_AREA_SIZE;
         break;

      case NANDFLASH_IOCTL_GET_BLOCK_SIZE:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = handle_ptr->NANDFLASH_INFO_PTR->BLOCK_SIZE;
         break;

      case NANDFLASH_IOCTL_GET_NUM_BLOCKS:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = handle_ptr->NANDFLASH_INFO_PTR->NUM_BLOCKS;
         break;

      case NANDFLASH_IOCTL_GET_WIDTH:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = handle_ptr->NANDFLASH_INFO_PTR->WIDTH;
         break;

      case NANDFLASH_IOCTL_GET_NUM_VIRT_PAGES:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = handle_ptr->NUM_VIRTUAL_PAGES;
         break;

      case NANDFLASH_IOCTL_GET_VIRT_PAGE_SIZE:
         uparam_ptr  = (_mqx_uint_ptr)param_ptr;
         *uparam_ptr = handle_ptr->VIRTUAL_PAGE_SIZE;
         break;

      case NANDFLASH_IOCTL_ERASE_BLOCK:
         if (handle_ptr->BLOCK_ERASE) {
            if (NANDFLASHERR_NO_ERROR == (*handle_ptr->BLOCK_ERASE)(handle_ptr, (uint_32)param_ptr,FALSE)) {
               result = MQX_OK;
            } else {
               result = IO_ERROR;
            } /* Endif */
         } else {
            result = IO_ERROR_INVALID_IOCTL_CMD;
         } /* Endif */   
         break;

      case NANDFLASH_IOCTL_ERASE_BLOCK_FORCE:
         if (handle_ptr->BLOCK_ERASE) {
            if (NANDFLASHERR_NO_ERROR == (*handle_ptr->BLOCK_ERASE)(handle_ptr, (uint_32)param_ptr,TRUE)) {
               result = MQX_OK;
            } else {
               result = IO_ERROR;
            } /* Endif */
         } else {
            result = IO_ERROR_INVALID_IOCTL_CMD;
         } /* Endif */   
         break;

      case NANDFLASH_IOCTL_ERASE_CHIP:
         if (handle_ptr->CHIP_ERASE) {
            if (NANDFLASHERR_NO_ERROR == (*handle_ptr->CHIP_ERASE)(handle_ptr)) {
               result = MQX_OK;
            } else {
               result = IO_ERROR;
            } /* Endif */
         } else {
            result = IO_ERROR_INVALID_IOCTL_CMD;
         } /* Endif */   
         break;

      case NANDFLASH_IOCTL_WRITE_PROTECT:
         if (handle_ptr->WRITE_PROTECT) {
            if (NANDFLASHERR_NO_ERROR == (*handle_ptr->WRITE_PROTECT)(handle_ptr, *(_mqx_uint_ptr)param_ptr)) {
               result = MQX_OK;
            } else {
               result = IO_ERROR;
            } /* Endif */
         } else {
            result = IO_ERROR_INVALID_IOCTL_CMD;
         } /* Endif */   
         break;

      case NANDFLASH_IOCTL_CHECK_BLOCK:
         if (handle_ptr->IS_BLOCK_BAD) {
            result = (*handle_ptr->IS_BLOCK_BAD)(handle_ptr, (uint_32)param_ptr);
         } else {
            result = IO_ERROR_INVALID_IOCTL_CMD;
         } /* Endif */   
         break;

      case NANDFLASH_IOCTL_MARK_BLOCK_AS_BAD:
         if (handle_ptr->MARK_BLOCK_AS_BAD) {
            if (NANDFLASHERR_NO_ERROR == (*handle_ptr->MARK_BLOCK_AS_BAD)(handle_ptr, (uint_32)param_ptr)) {
               result = MQX_OK;
            } else {
               result = IO_ERROR;
            } /* Endif */
         } else {
            result = IO_ERROR_INVALID_IOCTL_CMD;
         } /* Endif */   
         break;

      case NANDFLASH_IOCTL_GET_BAD_BLOCK_TABLE:
         for (i=0; i<handle_ptr->NANDFLASH_INFO_PTR->NUM_BLOCKS; i++)
         {
            if(NANDFLASHERR_BLOCK_NOT_BAD == (*handle_ptr->IS_BLOCK_BAD)(handle_ptr, (uint_32)i))
            {
                *(uint_8*)param_ptr = 1;    /* block is good */
            }
            else
            {
                *(uint_8*)param_ptr = 0;    /* block is bad */
            }
            param_ptr = (pointer)((uint_8*)param_ptr + sizeof(uint_8));
         }
         break;

      case NANDFLASH_IOCTL_GET_ID:
         if (handle_ptr->IOCTL) {
            if (NANDFLASHERR_NO_ERROR == (*handle_ptr->IOCTL)(handle_ptr,NANDFLASH_IOCTL_GET_ID,param_ptr)) {
               result = MQX_OK;
            } else {
               result = IO_ERROR;
            } /* Endif */
         } else {
            result = IO_ERROR_INVALID_IOCTL_CMD;
         } /* Endif */   
         break;

      case IO_IOCTL_DEVICE_IDENTIFY:
         uparam_ptr  = (uint_32_ptr)param_ptr;
         uparam_ptr[IO_IOCTL_ID_PHY_ELEMENT]  = IO_DEV_TYPE_PHYS_NANDFLASH;
         uparam_ptr[IO_IOCTL_ID_LOG_ELEMENT]  = IO_DEV_TYPE_LOGICAL_MFS;
         uparam_ptr[IO_IOCTL_ID_ATTR_ELEMENT] = IO_NANDFLASH_ATTRIBS;
         /*if (fd_ptr->FLAGS & IO_O_RDONLY)
         {
             uparam_ptr[IO_IOCTL_ID_ATTR_ELEMENT] &= (~ IO_DEV_ATTR_WRITE);
         }*/
         break;

      default:
         if(handle_ptr->IOCTL != NULL){
            result = (*handle_ptr->IOCTL)(handle_ptr, cmd, param_ptr);
         } else {
            result = IO_ERROR_INVALID_IOCTL_CMD;    
         }         
         break;
   } /* Endswitch */
   return result;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/snmp/1213.c<|end_filename|>
/*HEADER****************************************************************
*
* Copyright (c) 2008-2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2009 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************** 
*
* Comments:  This file was generated by "gawk -f def2c.awk" script.
*
*END*******************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include "snmpcfg.h"
#include "asn1.h"
#include "snmp.h"


#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4

extern RTCSMIB_NODE MIBNODE_mgmt;

extern RTCSMIB_NODE MIBNODE_mib2;
extern const RTCSMIB_NODE MIBNODE_system;
extern const RTCSMIB_NODE MIBNODE_interfaces;
extern const RTCSMIB_NODE MIBNODE_ip;
extern const RTCSMIB_NODE MIBNODE_icmp;
extern const RTCSMIB_NODE MIBNODE_tcp;
extern const RTCSMIB_NODE MIBNODE_udp;
extern const RTCSMIB_NODE MIBNODE_transmission;
extern const RTCSMIB_NODE MIBNODE_snmp;
extern const RTCSMIB_NODE MIBNODE_sysDescr;
extern const RTCSMIB_NODE MIBNODE_sysObjectID;
extern const RTCSMIB_NODE MIBNODE_sysUpTime;
extern const RTCSMIB_NODE MIBNODE_sysContact;
extern const RTCSMIB_NODE MIBNODE_sysName;
extern const RTCSMIB_NODE MIBNODE_sysLocation;
extern const RTCSMIB_NODE MIBNODE_sysServices;
extern const RTCSMIB_NODE MIBNODE_ifNumber;
extern const RTCSMIB_NODE MIBNODE_ifTable;
extern const RTCSMIB_NODE MIBNODE_ifEntry;
extern const RTCSMIB_NODE MIBNODE_ifIndex;
extern const RTCSMIB_NODE MIBNODE_ifDescr;
extern const RTCSMIB_NODE MIBNODE_ifType;
extern const RTCSMIB_NODE MIBNODE_ifMtu;
extern const RTCSMIB_NODE MIBNODE_ifSpeed;
extern const RTCSMIB_NODE MIBNODE_ifPhysAddress;
extern const RTCSMIB_NODE MIBNODE_ifAdminStatus;
extern const RTCSMIB_NODE MIBNODE_ifOperStatus;
extern const RTCSMIB_NODE MIBNODE_ifLastChange;
extern const RTCSMIB_NODE MIBNODE_ifInOctets;
extern const RTCSMIB_NODE MIBNODE_ifInUcastPkts;
extern const RTCSMIB_NODE MIBNODE_ifInNUcastPkts;
extern const RTCSMIB_NODE MIBNODE_ifInDiscards;
extern const RTCSMIB_NODE MIBNODE_ifInErrors;
extern const RTCSMIB_NODE MIBNODE_ifInUnknownProtos;
extern const RTCSMIB_NODE MIBNODE_ifOutOctets;
extern const RTCSMIB_NODE MIBNODE_ifOutUcastPkts;
extern const RTCSMIB_NODE MIBNODE_ifOutNUcastPkts;
extern const RTCSMIB_NODE MIBNODE_ifOutDiscards;
extern const RTCSMIB_NODE MIBNODE_ifOutErrors;
extern const RTCSMIB_NODE MIBNODE_ifOutQLen;
extern const RTCSMIB_NODE MIBNODE_ifSpecific;
extern const RTCSMIB_NODE MIBNODE_ipForwarding;
extern const RTCSMIB_NODE MIBNODE_ipDefaultTTL;
extern const RTCSMIB_NODE MIBNODE_ipInReceives;
extern const RTCSMIB_NODE MIBNODE_ipInHdrErrors;
extern const RTCSMIB_NODE MIBNODE_ipInAddrErrors;
extern const RTCSMIB_NODE MIBNODE_ipForwDatagrams;
extern const RTCSMIB_NODE MIBNODE_ipInUnknownProtos;
extern const RTCSMIB_NODE MIBNODE_ipInDiscards;
extern const RTCSMIB_NODE MIBNODE_ipInDelivers;
extern const RTCSMIB_NODE MIBNODE_ipOutRequests;
extern const RTCSMIB_NODE MIBNODE_ipOutDiscards;
extern const RTCSMIB_NODE MIBNODE_ipOutNoRoutes;
extern const RTCSMIB_NODE MIBNODE_ipReasmTimeout;
extern const RTCSMIB_NODE MIBNODE_ipReasmReqds;
extern const RTCSMIB_NODE MIBNODE_ipReasmOKs;
extern const RTCSMIB_NODE MIBNODE_ipReasmFails;
extern const RTCSMIB_NODE MIBNODE_ipFragOKs;
extern const RTCSMIB_NODE MIBNODE_ipFragFails;
extern const RTCSMIB_NODE MIBNODE_ipFragCreates;
extern const RTCSMIB_NODE MIBNODE_ipAddrTable;
extern const RTCSMIB_NODE MIBNODE_ipAddrEntry;
extern const RTCSMIB_NODE MIBNODE_ipAdEntAddr;
extern const RTCSMIB_NODE MIBNODE_ipAdEntIfIndex;
extern const RTCSMIB_NODE MIBNODE_ipAdEntNetMask;
extern const RTCSMIB_NODE MIBNODE_ipAdEntBcastAddr;
extern const RTCSMIB_NODE MIBNODE_ipAdEntReasmMaxSize;
extern const RTCSMIB_NODE MIBNODE_ipRouteTable;
extern const RTCSMIB_NODE MIBNODE_ipRouteEntry;
extern const RTCSMIB_NODE MIBNODE_ipRouteDest;
extern const RTCSMIB_NODE MIBNODE_ipRouteIfIndex;
extern const RTCSMIB_NODE MIBNODE_ipRouteMetric1;
extern const RTCSMIB_NODE MIBNODE_ipRouteMetric2;
extern const RTCSMIB_NODE MIBNODE_ipRouteMetric3;
extern const RTCSMIB_NODE MIBNODE_ipRouteMetric4;
extern const RTCSMIB_NODE MIBNODE_ipRouteNextHop;
extern const RTCSMIB_NODE MIBNODE_ipRouteType;
extern const RTCSMIB_NODE MIBNODE_ipRouteProto;
extern const RTCSMIB_NODE MIBNODE_ipRouteAge;
extern const RTCSMIB_NODE MIBNODE_ipRouteMask;
extern const RTCSMIB_NODE MIBNODE_ipRouteMetric5;
extern const RTCSMIB_NODE MIBNODE_ipRouteInfo;
extern const RTCSMIB_NODE MIBNODE_ipNetToMediaTable;
extern const RTCSMIB_NODE MIBNODE_ipNetToMediaEntry;
extern const RTCSMIB_NODE MIBNODE_ipNetToMediaIfIndex;
extern const RTCSMIB_NODE MIBNODE_ipNetToMediaPhysAddress;
extern const RTCSMIB_NODE MIBNODE_ipNetToMediaNetAddress;
extern const RTCSMIB_NODE MIBNODE_ipNetToMediaType;
extern const RTCSMIB_NODE MIBNODE_ipRoutingDiscards;
extern const RTCSMIB_NODE MIBNODE_icmpInMsgs;
extern const RTCSMIB_NODE MIBNODE_icmpInErrors;
extern const RTCSMIB_NODE MIBNODE_icmpInDestUnreachs;
extern const RTCSMIB_NODE MIBNODE_icmpInTimeExcds;
extern const RTCSMIB_NODE MIBNODE_icmpInParmProbs;
extern const RTCSMIB_NODE MIBNODE_icmpInSrcQuenchs;
extern const RTCSMIB_NODE MIBNODE_icmpInRedirects;
extern const RTCSMIB_NODE MIBNODE_icmpInEchos;
extern const RTCSMIB_NODE MIBNODE_icmpInEchoReps;
extern const RTCSMIB_NODE MIBNODE_icmpInTimestamps;
extern const RTCSMIB_NODE MIBNODE_icmpInTimestampReps;
extern const RTCSMIB_NODE MIBNODE_icmpInAddrMasks;
extern const RTCSMIB_NODE MIBNODE_icmpInAddrMaskReps;
extern const RTCSMIB_NODE MIBNODE_icmpOutMsgs;
extern const RTCSMIB_NODE MIBNODE_icmpOutErrors;
extern const RTCSMIB_NODE MIBNODE_icmpOutDestUnreachs;
extern const RTCSMIB_NODE MIBNODE_icmpOutTimeExcds;
extern const RTCSMIB_NODE MIBNODE_icmpOutParmProbs;
extern const RTCSMIB_NODE MIBNODE_icmpOutSrcQuenchs;
extern const RTCSMIB_NODE MIBNODE_icmpOutRedirects;
extern const RTCSMIB_NODE MIBNODE_icmpOutEchos;
extern const RTCSMIB_NODE MIBNODE_icmpOutEchoReps;
extern const RTCSMIB_NODE MIBNODE_icmpOutTimestamps;
extern const RTCSMIB_NODE MIBNODE_icmpOutTimestampReps;
extern const RTCSMIB_NODE MIBNODE_icmpOutAddrMasks;
extern const RTCSMIB_NODE MIBNODE_icmpOutAddrMaskReps;
extern const RTCSMIB_NODE MIBNODE_tcpRtoAlgorithm;
extern const RTCSMIB_NODE MIBNODE_tcpRtoMin;
extern const RTCSMIB_NODE MIBNODE_tcpRtoMax;
extern const RTCSMIB_NODE MIBNODE_tcpMaxConn;
extern const RTCSMIB_NODE MIBNODE_tcpActiveOpens;
extern const RTCSMIB_NODE MIBNODE_tcpPassiveOpens;
extern const RTCSMIB_NODE MIBNODE_tcpAttemptFails;
extern const RTCSMIB_NODE MIBNODE_tcpEstabResets;
extern const RTCSMIB_NODE MIBNODE_tcpCurrEstab;
extern const RTCSMIB_NODE MIBNODE_tcpInSegs;
extern const RTCSMIB_NODE MIBNODE_tcpOutSegs;
extern const RTCSMIB_NODE MIBNODE_tcpRetransSegs;
extern const RTCSMIB_NODE MIBNODE_tcpConnTable;
extern const RTCSMIB_NODE MIBNODE_tcpConnEntry;
extern const RTCSMIB_NODE MIBNODE_tcpConnState;
extern const RTCSMIB_NODE MIBNODE_tcpConnLocalAddress;
extern const RTCSMIB_NODE MIBNODE_tcpConnLocalPort;
extern const RTCSMIB_NODE MIBNODE_tcpConnRemAddress;
extern const RTCSMIB_NODE MIBNODE_tcpConnRemPort;
extern const RTCSMIB_NODE MIBNODE_tcpInErrs;
extern const RTCSMIB_NODE MIBNODE_tcpOutRsts;
extern const RTCSMIB_NODE MIBNODE_udpInDatagrams;
extern const RTCSMIB_NODE MIBNODE_udpNoPorts;
extern const RTCSMIB_NODE MIBNODE_udpInErrors;
extern const RTCSMIB_NODE MIBNODE_udpOutDatagrams;
extern const RTCSMIB_NODE MIBNODE_udpTable;
extern const RTCSMIB_NODE MIBNODE_udpEntry;
extern const RTCSMIB_NODE MIBNODE_udpLocalAddress;
extern const RTCSMIB_NODE MIBNODE_udpLocalPort;
extern const RTCSMIB_NODE MIBNODE_snmpInPkts;
extern const RTCSMIB_NODE MIBNODE_snmpOutPkts;
extern const RTCSMIB_NODE MIBNODE_snmpInBadVersions;
extern const RTCSMIB_NODE MIBNODE_snmpInBadCommunityNames;
extern const RTCSMIB_NODE MIBNODE_snmpInBadCommunityUses;
extern const RTCSMIB_NODE MIBNODE_snmpInASNParseErrs;
extern const RTCSMIB_NODE MIBNODE_snmpInTooBigs;
extern const RTCSMIB_NODE MIBNODE_snmpInNoSuchNames;
extern const RTCSMIB_NODE MIBNODE_snmpInBadValues;
extern const RTCSMIB_NODE MIBNODE_snmpInReadOnlys;
extern const RTCSMIB_NODE MIBNODE_snmpInGenErrs;
extern const RTCSMIB_NODE MIBNODE_snmpInTotalReqVars;
extern const RTCSMIB_NODE MIBNODE_snmpInTotalSetVars;
extern const RTCSMIB_NODE MIBNODE_snmpInGetRequests;
extern const RTCSMIB_NODE MIBNODE_snmpInGetNexts;
extern const RTCSMIB_NODE MIBNODE_snmpInSetRequests;
extern const RTCSMIB_NODE MIBNODE_snmpInGetResponses;
extern const RTCSMIB_NODE MIBNODE_snmpInTraps;
extern const RTCSMIB_NODE MIBNODE_snmpOutTooBigs;
extern const RTCSMIB_NODE MIBNODE_snmpOutNoSuchNames;
extern const RTCSMIB_NODE MIBNODE_snmpOutBadValues;
extern const RTCSMIB_NODE MIBNODE_snmpOutGenErrs;
extern const RTCSMIB_NODE MIBNODE_snmpOutGetRequests;
extern const RTCSMIB_NODE MIBNODE_snmpOutGetNexts;
extern const RTCSMIB_NODE MIBNODE_snmpOutSetRequests;
extern const RTCSMIB_NODE MIBNODE_snmpOutGetResponses;
extern const RTCSMIB_NODE MIBNODE_snmpOutTraps;
extern const RTCSMIB_NODE MIBNODE_snmpEnableAuthenTraps;

extern const RTCSMIB_VALUE MIBVALUE_mib2;
extern const RTCSMIB_VALUE MIBVALUE_system;
extern const RTCSMIB_VALUE MIBVALUE_interfaces;
extern const RTCSMIB_VALUE MIBVALUE_ip;
extern const RTCSMIB_VALUE MIBVALUE_icmp;
extern const RTCSMIB_VALUE MIBVALUE_tcp;
extern const RTCSMIB_VALUE MIBVALUE_udp;
extern const RTCSMIB_VALUE MIBVALUE_transmission;
extern const RTCSMIB_VALUE MIBVALUE_snmp;
extern const RTCSMIB_VALUE MIBVALUE_sysDescr;
extern const RTCSMIB_VALUE MIBVALUE_sysObjectID;
extern const RTCSMIB_VALUE MIBVALUE_sysUpTime;
extern const RTCSMIB_VALUE MIBVALUE_sysContact;
extern const RTCSMIB_VALUE MIBVALUE_sysName;
extern const RTCSMIB_VALUE MIBVALUE_sysLocation;
extern const RTCSMIB_VALUE MIBVALUE_sysServices;
extern const RTCSMIB_VALUE MIBVALUE_ifNumber;
extern const RTCSMIB_VALUE MIBVALUE_ifTable;
extern const RTCSMIB_VALUE MIBVALUE_ifEntry;
extern const RTCSMIB_VALUE MIBVALUE_ifIndex;
extern const RTCSMIB_VALUE MIBVALUE_ifDescr;
extern const RTCSMIB_VALUE MIBVALUE_ifType;
extern const RTCSMIB_VALUE MIBVALUE_ifMtu;
extern const RTCSMIB_VALUE MIBVALUE_ifSpeed;
extern const RTCSMIB_VALUE MIBVALUE_ifPhysAddress;
extern const RTCSMIB_VALUE MIBVALUE_ifAdminStatus;
extern const RTCSMIB_VALUE MIBVALUE_ifOperStatus;
extern const RTCSMIB_VALUE MIBVALUE_ifLastChange;
extern const RTCSMIB_VALUE MIBVALUE_ifInOctets;
extern const RTCSMIB_VALUE MIBVALUE_ifInUcastPkts;
extern const RTCSMIB_VALUE MIBVALUE_ifInNUcastPkts;
extern const RTCSMIB_VALUE MIBVALUE_ifInDiscards;
extern const RTCSMIB_VALUE MIBVALUE_ifInErrors;
extern const RTCSMIB_VALUE MIBVALUE_ifInUnknownProtos;
extern const RTCSMIB_VALUE MIBVALUE_ifOutOctets;
extern const RTCSMIB_VALUE MIBVALUE_ifOutUcastPkts;
extern const RTCSMIB_VALUE MIBVALUE_ifOutNUcastPkts;
extern const RTCSMIB_VALUE MIBVALUE_ifOutDiscards;
extern const RTCSMIB_VALUE MIBVALUE_ifOutErrors;
extern const RTCSMIB_VALUE MIBVALUE_ifOutQLen;
extern const RTCSMIB_VALUE MIBVALUE_ifSpecific;
extern const RTCSMIB_VALUE MIBVALUE_ipForwarding;
extern const RTCSMIB_VALUE MIBVALUE_ipDefaultTTL;
extern const RTCSMIB_VALUE MIBVALUE_ipInReceives;
extern const RTCSMIB_VALUE MIBVALUE_ipInHdrErrors;
extern const RTCSMIB_VALUE MIBVALUE_ipInAddrErrors;
extern const RTCSMIB_VALUE MIBVALUE_ipForwDatagrams;
extern const RTCSMIB_VALUE MIBVALUE_ipInUnknownProtos;
extern const RTCSMIB_VALUE MIBVALUE_ipInDiscards;
extern const RTCSMIB_VALUE MIBVALUE_ipInDelivers;
extern const RTCSMIB_VALUE MIBVALUE_ipOutRequests;
extern const RTCSMIB_VALUE MIBVALUE_ipOutDiscards;
extern const RTCSMIB_VALUE MIBVALUE_ipOutNoRoutes;
extern const RTCSMIB_VALUE MIBVALUE_ipReasmTimeout;
extern const RTCSMIB_VALUE MIBVALUE_ipReasmReqds;
extern const RTCSMIB_VALUE MIBVALUE_ipReasmOKs;
extern const RTCSMIB_VALUE MIBVALUE_ipReasmFails;
extern const RTCSMIB_VALUE MIBVALUE_ipFragOKs;
extern const RTCSMIB_VALUE MIBVALUE_ipFragFails;
extern const RTCSMIB_VALUE MIBVALUE_ipFragCreates;
extern const RTCSMIB_VALUE MIBVALUE_ipAddrTable;
extern const RTCSMIB_VALUE MIBVALUE_ipAddrEntry;
extern const RTCSMIB_VALUE MIBVALUE_ipAdEntAddr;
extern const RTCSMIB_VALUE MIBVALUE_ipAdEntIfIndex;
extern const RTCSMIB_VALUE MIBVALUE_ipAdEntNetMask;
extern const RTCSMIB_VALUE MIBVALUE_ipAdEntBcastAddr;
extern const RTCSMIB_VALUE MIBVALUE_ipAdEntReasmMaxSize;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteTable;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteEntry;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteDest;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteIfIndex;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteMetric1;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteMetric2;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteMetric3;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteMetric4;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteNextHop;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteType;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteProto;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteAge;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteMask;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteMetric5;
extern const RTCSMIB_VALUE MIBVALUE_ipRouteInfo;
extern const RTCSMIB_VALUE MIBVALUE_ipNetToMediaTable;
extern const RTCSMIB_VALUE MIBVALUE_ipNetToMediaEntry;
extern const RTCSMIB_VALUE MIBVALUE_ipNetToMediaIfIndex;
extern const RTCSMIB_VALUE MIBVALUE_ipNetToMediaPhysAddress;
extern const RTCSMIB_VALUE MIBVALUE_ipNetToMediaNetAddress;
extern const RTCSMIB_VALUE MIBVALUE_ipNetToMediaType;
extern const RTCSMIB_VALUE MIBVALUE_ipRoutingDiscards;
extern const RTCSMIB_VALUE MIBVALUE_icmpInMsgs;
extern const RTCSMIB_VALUE MIBVALUE_icmpInErrors;
extern const RTCSMIB_VALUE MIBVALUE_icmpInDestUnreachs;
extern const RTCSMIB_VALUE MIBVALUE_icmpInTimeExcds;
extern const RTCSMIB_VALUE MIBVALUE_icmpInParmProbs;
extern const RTCSMIB_VALUE MIBVALUE_icmpInSrcQuenchs;
extern const RTCSMIB_VALUE MIBVALUE_icmpInRedirects;
extern const RTCSMIB_VALUE MIBVALUE_icmpInEchos;
extern const RTCSMIB_VALUE MIBVALUE_icmpInEchoReps;
extern const RTCSMIB_VALUE MIBVALUE_icmpInTimestamps;
extern const RTCSMIB_VALUE MIBVALUE_icmpInTimestampReps;
extern const RTCSMIB_VALUE MIBVALUE_icmpInAddrMasks;
extern const RTCSMIB_VALUE MIBVALUE_icmpInAddrMaskReps;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutMsgs;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutErrors;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutDestUnreachs;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutTimeExcds;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutParmProbs;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutSrcQuenchs;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutRedirects;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutEchos;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutEchoReps;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutTimestamps;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutTimestampReps;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutAddrMasks;
extern const RTCSMIB_VALUE MIBVALUE_icmpOutAddrMaskReps;
extern const RTCSMIB_VALUE MIBVALUE_tcpRtoAlgorithm;
extern const RTCSMIB_VALUE MIBVALUE_tcpRtoMin;
extern const RTCSMIB_VALUE MIBVALUE_tcpRtoMax;
extern const RTCSMIB_VALUE MIBVALUE_tcpMaxConn;
extern const RTCSMIB_VALUE MIBVALUE_tcpActiveOpens;
extern const RTCSMIB_VALUE MIBVALUE_tcpPassiveOpens;
extern const RTCSMIB_VALUE MIBVALUE_tcpAttemptFails;
extern const RTCSMIB_VALUE MIBVALUE_tcpEstabResets;
extern const RTCSMIB_VALUE MIBVALUE_tcpCurrEstab;
extern const RTCSMIB_VALUE MIBVALUE_tcpInSegs;
extern const RTCSMIB_VALUE MIBVALUE_tcpOutSegs;
extern const RTCSMIB_VALUE MIBVALUE_tcpRetransSegs;
extern const RTCSMIB_VALUE MIBVALUE_tcpConnTable;
extern const RTCSMIB_VALUE MIBVALUE_tcpConnEntry;
extern const RTCSMIB_VALUE MIBVALUE_tcpConnState;
extern const RTCSMIB_VALUE MIBVALUE_tcpConnLocalAddress;
extern const RTCSMIB_VALUE MIBVALUE_tcpConnLocalPort;
extern const RTCSMIB_VALUE MIBVALUE_tcpConnRemAddress;
extern const RTCSMIB_VALUE MIBVALUE_tcpConnRemPort;
extern const RTCSMIB_VALUE MIBVALUE_tcpInErrs;
extern const RTCSMIB_VALUE MIBVALUE_tcpOutRsts;
extern const RTCSMIB_VALUE MIBVALUE_udpInDatagrams;
extern const RTCSMIB_VALUE MIBVALUE_udpNoPorts;
extern const RTCSMIB_VALUE MIBVALUE_udpInErrors;
extern const RTCSMIB_VALUE MIBVALUE_udpOutDatagrams;
extern const RTCSMIB_VALUE MIBVALUE_udpTable;
extern const RTCSMIB_VALUE MIBVALUE_udpEntry;
extern const RTCSMIB_VALUE MIBVALUE_udpLocalAddress;
extern const RTCSMIB_VALUE MIBVALUE_udpLocalPort;
extern const RTCSMIB_VALUE MIBVALUE_snmpInPkts;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutPkts;
extern const RTCSMIB_VALUE MIBVALUE_snmpInBadVersions;
extern const RTCSMIB_VALUE MIBVALUE_snmpInBadCommunityNames;
extern const RTCSMIB_VALUE MIBVALUE_snmpInBadCommunityUses;
extern const RTCSMIB_VALUE MIBVALUE_snmpInASNParseErrs;
extern const RTCSMIB_VALUE MIBVALUE_snmpInTooBigs;
extern const RTCSMIB_VALUE MIBVALUE_snmpInNoSuchNames;
extern const RTCSMIB_VALUE MIBVALUE_snmpInBadValues;
extern const RTCSMIB_VALUE MIBVALUE_snmpInReadOnlys;
extern const RTCSMIB_VALUE MIBVALUE_snmpInGenErrs;
extern const RTCSMIB_VALUE MIBVALUE_snmpInTotalReqVars;
extern const RTCSMIB_VALUE MIBVALUE_snmpInTotalSetVars;
extern const RTCSMIB_VALUE MIBVALUE_snmpInGetRequests;
extern const RTCSMIB_VALUE MIBVALUE_snmpInGetNexts;
extern const RTCSMIB_VALUE MIBVALUE_snmpInSetRequests;
extern const RTCSMIB_VALUE MIBVALUE_snmpInGetResponses;
extern const RTCSMIB_VALUE MIBVALUE_snmpInTraps;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutTooBigs;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutNoSuchNames;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutBadValues;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutGenErrs;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutGetRequests;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutGetNexts;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutSetRequests;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutGetResponses;
extern const RTCSMIB_VALUE MIBVALUE_snmpOutTraps;
extern const RTCSMIB_VALUE MIBVALUE_snmpEnableAuthenTraps;

boolean MIB_find_ipAddrEntry         (uint_32, pointer, pointer _PTR_);
boolean MIB_find_ifEntry             (uint_32, pointer, pointer _PTR_);
boolean MIB_find_udpEntry            (uint_32, pointer, pointer _PTR_);
boolean MIB_find_ipRouteEntry        (uint_32, pointer, pointer _PTR_);
boolean MIB_find_tcpConnEntry        (uint_32, pointer, pointer _PTR_);
boolean MIB_find_ipNetToMediaEntry   (uint_32, pointer, pointer _PTR_);

static boolean MIB_instance_ipAddrEntry         (RTCSMIB_WALK_PTR, uint_32, boolean (_CODE_PTR_)(uint_32, pointer, pointer _PTR_), boolean _PTR_, pointer _PTR_);
static boolean MIB_instance_ifEntry             (RTCSMIB_WALK_PTR, uint_32, boolean (_CODE_PTR_)(uint_32, pointer, pointer _PTR_), boolean _PTR_, pointer _PTR_);
static boolean MIB_instance_udpEntry            (RTCSMIB_WALK_PTR, uint_32, boolean (_CODE_PTR_)(uint_32, pointer, pointer _PTR_), boolean _PTR_, pointer _PTR_);
static boolean MIB_instance_ipRouteEntry        (RTCSMIB_WALK_PTR, uint_32, boolean (_CODE_PTR_)(uint_32, pointer, pointer _PTR_), boolean _PTR_, pointer _PTR_);
static boolean MIB_instance_tcpConnEntry        (RTCSMIB_WALK_PTR, uint_32, boolean (_CODE_PTR_)(uint_32, pointer, pointer _PTR_), boolean _PTR_, pointer _PTR_);
static boolean MIB_instance_ipNetToMediaEntry   (RTCSMIB_WALK_PTR, uint_32, boolean (_CODE_PTR_)(uint_32, pointer, pointer _PTR_), boolean _PTR_, pointer _PTR_);

static uint_32 MIB_set_sysContact          (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_sysName             (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_sysLocation         (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ifAdminStatus       (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipForwarding        (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipDefaultTTL        (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteDest         (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteIfIndex      (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteMetric1      (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteMetric2      (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteMetric3      (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteMetric4      (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteNextHop      (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteType         (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteAge          (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteMask         (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipRouteMetric5      (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipNetToMediaIfIndex (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipNetToMediaPhysAddress(pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipNetToMediaNetAddress(pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_ipNetToMediaType    (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_tcpConnState        (pointer, uchar_ptr, uint_32);
static uint_32 MIB_set_snmpEnableAuthenTraps(pointer, uchar_ptr, uint_32);

RTCSMIB_NODE MIBNODE_mib2 = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_system,
   (RTCSMIB_NODE_PTR)&MIBNODE_mgmt,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_system = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_interfaces,
   (RTCSMIB_NODE_PTR)&MIBNODE_sysDescr,
   (RTCSMIB_NODE_PTR)&MIBNODE_mib2,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_interfaces = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_ip,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifNumber,
   (RTCSMIB_NODE_PTR)&MIBNODE_mib2,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_ip = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipForwarding,
   (RTCSMIB_NODE_PTR)&MIBNODE_mib2,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_icmp = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInMsgs,
   (RTCSMIB_NODE_PTR)&MIBNODE_mib2,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_tcp = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_udp,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpRtoAlgorithm,
   (RTCSMIB_NODE_PTR)&MIBNODE_mib2,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_udp = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_transmission,
   (RTCSMIB_NODE_PTR)&MIBNODE_udpInDatagrams,
   (RTCSMIB_NODE_PTR)&MIBNODE_mib2,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_transmission = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_mib2,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_snmp = {
   11,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInPkts,
   (RTCSMIB_NODE_PTR)&MIBNODE_mib2,

   0,
   NULL,
   NULL, 0, NULL, NULL
};

const RTCSMIB_NODE MIBNODE_sysDescr = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_sysObjectID,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_system,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_sysDescr,
   NULL
};

const RTCSMIB_NODE MIBNODE_sysObjectID = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_sysUpTime,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_system,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OBJECT,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_sysObjectID,
   NULL
};

const RTCSMIB_NODE MIBNODE_sysUpTime = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_sysContact,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_system,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_TimeTicks,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_sysUpTime,
   NULL
};

const RTCSMIB_NODE MIBNODE_sysContact = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_sysName,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_system,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_sysContact,
   MIB_set_sysContact
};

const RTCSMIB_NODE MIBNODE_sysName = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_sysLocation,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_system,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_sysName,
   MIB_set_sysName
};

const RTCSMIB_NODE MIBNODE_sysLocation = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_sysServices,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_system,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_zero, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_sysLocation,
   MIB_set_sysLocation
};

const RTCSMIB_NODE MIBNODE_sysServices = {
   7,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_system,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_sysServices,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifNumber = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifTable,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_interfaces,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifNumber,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifTable = {
   2,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,
   (RTCSMIB_NODE_PTR)&MIBNODE_interfaces,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifTable,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifEntry = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifIndex,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifTable,

   0,
   MIB_find_ifEntry,
   MIB_instance_ifEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifEntry,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifIndex = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifDescr,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifIndex,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifDescr = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifType,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifDescr,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifType = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifMtu,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifType,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifMtu = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifSpeed,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifMtu,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifSpeed = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifPhysAddress,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Gauge,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifSpeed,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifPhysAddress = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifAdminStatus,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifPhysAddress,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifAdminStatus = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifOperStatus,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifAdminStatus,
   MIB_set_ifAdminStatus
};

const RTCSMIB_NODE MIBNODE_ifOperStatus = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifLastChange,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifOperStatus,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifLastChange = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifInOctets,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_TimeTicks,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifLastChange,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifInOctets = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifInUcastPkts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifInOctets,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifInUcastPkts = {
   11,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifInNUcastPkts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifInUcastPkts,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifInNUcastPkts = {
   12,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifInDiscards,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifInNUcastPkts,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifInDiscards = {
   13,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifInErrors,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifInDiscards,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifInErrors = {
   14,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifInUnknownProtos,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifInErrors,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifInUnknownProtos = {
   15,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifOutOctets,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifInUnknownProtos,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifOutOctets = {
   16,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifOutUcastPkts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifOutOctets,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifOutUcastPkts = {
   17,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifOutNUcastPkts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifOutUcastPkts,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifOutNUcastPkts = {
   18,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifOutDiscards,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifOutNUcastPkts,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifOutDiscards = {
   19,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifOutErrors,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifOutDiscards,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifOutErrors = {
   20,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifOutQLen,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifOutErrors,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifOutQLen = {
   21,

   (RTCSMIB_NODE_PTR)&MIBNODE_ifSpecific,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_Gauge,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifOutQLen,
   NULL
};

const RTCSMIB_NODE MIBNODE_ifSpecific = {
   22,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ifEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ifEntry, ASN1_TYPE_OBJECT,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ifSpecific,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipForwarding = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipDefaultTTL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipForwarding,
   MIB_set_ipForwarding
};

const RTCSMIB_NODE MIBNODE_ipDefaultTTL = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipInReceives,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipDefaultTTL,
   MIB_set_ipDefaultTTL
};

const RTCSMIB_NODE MIBNODE_ipInReceives = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipInHdrErrors,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipInReceives,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipInHdrErrors = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipInAddrErrors,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipInHdrErrors,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipInAddrErrors = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipForwDatagrams,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipInAddrErrors,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipForwDatagrams = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipInUnknownProtos,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipForwDatagrams,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipInUnknownProtos = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipInDiscards,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipInUnknownProtos,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipInDiscards = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipInDelivers,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipInDiscards,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipInDelivers = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipOutRequests,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipInDelivers,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipOutRequests = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipOutDiscards,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipOutRequests,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipOutDiscards = {
   11,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipOutNoRoutes,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipOutDiscards,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipOutNoRoutes = {
   12,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipReasmTimeout,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipOutNoRoutes,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipReasmTimeout = {
   13,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipReasmReqds,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipReasmTimeout,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipReasmReqds = {
   14,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipReasmOKs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipReasmReqds,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipReasmOKs = {
   15,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipReasmFails,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipReasmOKs,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipReasmFails = {
   16,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipFragOKs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipReasmFails,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipFragOKs = {
   17,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipFragFails,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipFragOKs,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipFragFails = {
   18,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipFragCreates,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipFragFails,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipFragCreates = {
   19,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipAddrTable,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipFragCreates,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipAddrTable = {
   20,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteTable,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipAddrEntry,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipAddrTable,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipAddrEntry = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipAdEntAddr,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipAddrTable,

   0,
   MIB_find_ipAddrEntry,
   MIB_instance_ipAddrEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipAddrEntry,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipAdEntAddr = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipAdEntIfIndex,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipAddrEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ipAddrEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipAdEntAddr,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipAdEntIfIndex = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipAdEntNetMask,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipAddrEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ipAddrEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipAdEntIfIndex,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipAdEntNetMask = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipAdEntBcastAddr,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipAddrEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ipAddrEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipAdEntNetMask,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipAdEntBcastAddr = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipAdEntReasmMaxSize,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipAddrEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ipAddrEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipAdEntBcastAddr,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipAdEntReasmMaxSize = {
   5,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipAddrEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ipAddrEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipAdEntReasmMaxSize,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipRouteTable = {
   21,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaTable,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteTable,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipRouteEntry = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteDest,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteTable,

   0,
   MIB_find_ipRouteEntry,
   MIB_instance_ipRouteEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteEntry,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipRouteDest = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteIfIndex,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteDest,
   MIB_set_ipRouteDest
};

const RTCSMIB_NODE MIBNODE_ipRouteIfIndex = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteMetric1,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteIfIndex,
   MIB_set_ipRouteIfIndex
};

const RTCSMIB_NODE MIBNODE_ipRouteMetric1 = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteMetric2,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteMetric1,
   MIB_set_ipRouteMetric1
};

const RTCSMIB_NODE MIBNODE_ipRouteMetric2 = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteMetric3,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteMetric2,
   MIB_set_ipRouteMetric2
};

const RTCSMIB_NODE MIBNODE_ipRouteMetric3 = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteMetric4,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteMetric3,
   MIB_set_ipRouteMetric3
};

const RTCSMIB_NODE MIBNODE_ipRouteMetric4 = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteNextHop,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteMetric4,
   MIB_set_ipRouteMetric4
};

const RTCSMIB_NODE MIBNODE_ipRouteNextHop = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteType,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteNextHop,
   MIB_set_ipRouteNextHop
};

const RTCSMIB_NODE MIBNODE_ipRouteType = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteProto,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteType,
   MIB_set_ipRouteType
};

const RTCSMIB_NODE MIBNODE_ipRouteProto = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteAge,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteProto,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipRouteAge = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteMask,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteAge,
   MIB_set_ipRouteAge
};

const RTCSMIB_NODE MIBNODE_ipRouteMask = {
   11,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteMetric5,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteMask,
   MIB_set_ipRouteMask
};

const RTCSMIB_NODE MIBNODE_ipRouteMetric5 = {
   12,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteInfo,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteMetric5,
   MIB_set_ipRouteMetric5
};

const RTCSMIB_NODE MIBNODE_ipRouteInfo = {
   13,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipRouteEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_ipRouteEntry, ASN1_TYPE_OBJECT,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRouteInfo,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipNetToMediaTable = {
   22,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipRoutingDiscards,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaEntry,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipNetToMediaTable,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipNetToMediaEntry = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaIfIndex,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaTable,

   0,
   MIB_find_ipNetToMediaEntry,
   MIB_instance_ipNetToMediaEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipNetToMediaEntry,
   NULL
};

const RTCSMIB_NODE MIBNODE_ipNetToMediaIfIndex = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaPhysAddress,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipNetToMediaEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipNetToMediaIfIndex,
   MIB_set_ipNetToMediaIfIndex
};

const RTCSMIB_NODE MIBNODE_ipNetToMediaPhysAddress = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaNetAddress,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipNetToMediaEntry, ASN1_TYPE_OCTET,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipNetToMediaPhysAddress,
   MIB_set_ipNetToMediaPhysAddress
};

const RTCSMIB_NODE MIBNODE_ipNetToMediaNetAddress = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaType,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipNetToMediaEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipNetToMediaNetAddress,
   MIB_set_ipNetToMediaNetAddress
};

const RTCSMIB_NODE MIBNODE_ipNetToMediaType = {
   4,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ipNetToMediaEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_ipNetToMediaEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipNetToMediaType,
   MIB_set_ipNetToMediaType
};

const RTCSMIB_NODE MIBNODE_ipRoutingDiscards = {
   23,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_ip,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_ipRoutingDiscards,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInMsgs = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInErrors,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInMsgs,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInErrors = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInDestUnreachs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInErrors,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInDestUnreachs = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInTimeExcds,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInDestUnreachs,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInTimeExcds = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInParmProbs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInTimeExcds,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInParmProbs = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInSrcQuenchs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInParmProbs,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInSrcQuenchs = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInRedirects,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInSrcQuenchs,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInRedirects = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInEchos,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInRedirects,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInEchos = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInEchoReps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInEchos,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInEchoReps = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInTimestamps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInEchoReps,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInTimestamps = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInTimestampReps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInTimestamps,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInTimestampReps = {
   11,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInAddrMasks,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInTimestampReps,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInAddrMasks = {
   12,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpInAddrMaskReps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInAddrMasks,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpInAddrMaskReps = {
   13,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutMsgs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpInAddrMaskReps,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutMsgs = {
   14,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutErrors,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutMsgs,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutErrors = {
   15,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutDestUnreachs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutErrors,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutDestUnreachs = {
   16,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutTimeExcds,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutDestUnreachs,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutTimeExcds = {
   17,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutParmProbs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutTimeExcds,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutParmProbs = {
   18,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutSrcQuenchs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutParmProbs,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutSrcQuenchs = {
   19,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutRedirects,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutSrcQuenchs,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutRedirects = {
   20,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutEchos,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutRedirects,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutEchos = {
   21,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutEchoReps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutEchos,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutEchoReps = {
   22,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutTimestamps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutEchoReps,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutTimestamps = {
   23,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutTimestampReps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutTimestamps,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutTimestampReps = {
   24,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutAddrMasks,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutTimestampReps,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutAddrMasks = {
   25,

   (RTCSMIB_NODE_PTR)&MIBNODE_icmpOutAddrMaskReps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutAddrMasks,
   NULL
};

const RTCSMIB_NODE MIBNODE_icmpOutAddrMaskReps = {
   26,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_icmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_icmpOutAddrMaskReps,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpRtoAlgorithm = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpRtoMin,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpRtoAlgorithm,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpRtoMin = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpRtoMax,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpRtoMin,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpRtoMax = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpMaxConn,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpRtoMax,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpMaxConn = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpActiveOpens,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpMaxConn,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpActiveOpens = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpPassiveOpens,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpActiveOpens,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpPassiveOpens = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpAttemptFails,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpPassiveOpens,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpAttemptFails = {
   7,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpEstabResets,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpAttemptFails,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpEstabResets = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpCurrEstab,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpEstabResets,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpCurrEstab = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpInSegs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Gauge,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpCurrEstab,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpInSegs = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpOutSegs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpInSegs,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpOutSegs = {
   11,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpRetransSegs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpOutSegs,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpRetransSegs = {
   12,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnTable,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpRetransSegs,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpConnTable = {
   13,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpInErrs,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnEntry,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpConnTable,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpConnEntry = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnState,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnTable,

   0,
   MIB_find_tcpConnEntry,
   MIB_instance_tcpConnEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpConnEntry,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpConnState = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnLocalAddress,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnEntry,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_tcpConnEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpConnState,
   MIB_set_tcpConnState
};

const RTCSMIB_NODE MIBNODE_tcpConnLocalAddress = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnLocalPort,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_tcpConnEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpConnLocalAddress,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpConnLocalPort = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnRemAddress,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_tcpConnEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpConnLocalPort,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpConnRemAddress = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnRemPort,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_tcpConnEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpConnRemAddress,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpConnRemPort = {
   5,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcpConnEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_tcpConnEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpConnRemPort,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpInErrs = {
   14,

   (RTCSMIB_NODE_PTR)&MIBNODE_tcpOutRsts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpInErrs,
   NULL
};

const RTCSMIB_NODE MIBNODE_tcpOutRsts = {
   15,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_tcp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_tcpOutRsts,
   NULL
};

const RTCSMIB_NODE MIBNODE_udpInDatagrams = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_udpNoPorts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_udp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_udpInDatagrams,
   NULL
};

const RTCSMIB_NODE MIBNODE_udpNoPorts = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_udpInErrors,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_udp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_udpNoPorts,
   NULL
};

const RTCSMIB_NODE MIBNODE_udpInErrors = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_udpOutDatagrams,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_udp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_udpInErrors,
   NULL
};

const RTCSMIB_NODE MIBNODE_udpOutDatagrams = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_udpTable,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_udp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_udpOutDatagrams,
   NULL
};

const RTCSMIB_NODE MIBNODE_udpTable = {
   5,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_udpEntry,
   (RTCSMIB_NODE_PTR)&MIBNODE_udp,

   0,
   NULL,
   MIB_instance_zero, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_udpTable,
   NULL
};

const RTCSMIB_NODE MIBNODE_udpEntry = {
   1,

   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_udpLocalAddress,
   (RTCSMIB_NODE_PTR)&MIBNODE_udpTable,

   0,
   MIB_find_udpEntry,
   MIB_instance_udpEntry, ASN1_TYPE_SEQUENCE,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_udpEntry,
   NULL
};

const RTCSMIB_NODE MIBNODE_udpLocalAddress = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_udpLocalPort,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_udpEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_udpEntry, ASN1_TYPE_IpAddress,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_udpLocalAddress,
   NULL
};

const RTCSMIB_NODE MIBNODE_udpLocalPort = {
   2,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_udpEntry,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_udpEntry, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_udpLocalPort,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInPkts = {
   1,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutPkts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInPkts,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutPkts = {
   2,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInBadVersions,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutPkts,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInBadVersions = {
   3,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInBadCommunityNames,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInBadVersions,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInBadCommunityNames = {
   4,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInBadCommunityUses,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInBadCommunityNames,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInBadCommunityUses = {
   5,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInASNParseErrs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInBadCommunityUses,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInASNParseErrs = {
   6,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInTooBigs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInASNParseErrs,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInTooBigs = {
   8,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInNoSuchNames,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInTooBigs,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInNoSuchNames = {
   9,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInBadValues,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInNoSuchNames,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInBadValues = {
   10,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInReadOnlys,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInBadValues,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInReadOnlys = {
   11,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInGenErrs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInReadOnlys,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInGenErrs = {
   12,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInTotalReqVars,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInGenErrs,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInTotalReqVars = {
   13,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInTotalSetVars,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInTotalReqVars,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInTotalSetVars = {
   14,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInGetRequests,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInTotalSetVars,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInGetRequests = {
   15,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInGetNexts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInGetRequests,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInGetNexts = {
   16,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInSetRequests,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInGetNexts,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInSetRequests = {
   17,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInGetResponses,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInSetRequests,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInGetResponses = {
   18,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpInTraps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInGetResponses,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpInTraps = {
   19,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutTooBigs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpInTraps,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutTooBigs = {
   20,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutNoSuchNames,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutTooBigs,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutNoSuchNames = {
   21,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutBadValues,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutNoSuchNames,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutBadValues = {
   22,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutGenErrs,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutBadValues,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutGenErrs = {
   24,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutGetRequests,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutGenErrs,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutGetRequests = {
   25,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutGetNexts,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutGetRequests,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutGetNexts = {
   26,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutSetRequests,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutGetNexts,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutSetRequests = {
   27,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutGetResponses,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutSetRequests,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutGetResponses = {
   28,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpOutTraps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutGetResponses,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpOutTraps = {
   29,

   (RTCSMIB_NODE_PTR)&MIBNODE_snmpEnableAuthenTraps,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ,
   NULL,
   MIB_instance_zero, ASN1_TYPE_Counter,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpOutTraps,
   NULL
};

const RTCSMIB_NODE MIBNODE_snmpEnableAuthenTraps = {
   30,

   NULL,
   NULL,
   (RTCSMIB_NODE_PTR)&MIBNODE_snmp,

   RTCSMIB_ACCESS_READ | RTCSMIB_ACCESS_WRITE,
   NULL,
   MIB_instance_zero, ASN1_TYPE_INTEGER,
   (RTCSMIB_VALUE_PTR)&MIBVALUE_snmpEnableAuthenTraps,
   MIB_set_snmpEnableAuthenTraps
};


static boolean MIB_instance_ipAddrEntry
   (
      RTCSMIB_WALK_PTR     mib,
      uint_32              op,
      boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
      boolean _PTR_        found,
      pointer _PTR_        instance
   )
{ /* Body */
   struct {
      uchar   ipAdEntAddr[4];
   } index;

   *found = FALSE;
   *instance = NULL;

   switch (op) {

   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:

      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipAdEntAddr[0])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipAdEntAddr[1])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipAdEntAddr[2])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipAdEntAddr[3])) return FALSE;
      if (mib->inlen != 0) break;
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETNEXT:
      if (mib->inlen == 0) {
         index.ipAdEntAddr[0] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipAdEntAddr[0])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipAdEntAddr[1] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipAdEntAddr[1])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipAdEntAddr[2] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipAdEntAddr[2])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipAdEntAddr[3] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipAdEntAddr[3])) return FALSE;
         if(index.ipAdEntAddr[3] < 255)
            index.ipAdEntAddr[3]++;
      } /* Endif */
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETFIRST:
      index.ipAdEntAddr[0] = 0;
      index.ipAdEntAddr[1] = 0;
      index.ipAdEntAddr[2] = 0;
      index.ipAdEntAddr[3] = 0;
      *found = find(RTCSMIB_OP_GETNEXT, &index, instance);
      break;
   } /* Endswitch */

   if (*found && (op != RTCSMIB_OP_SET)) {
      if (!RTCSMIB_id_write8  (mib, index.ipAdEntAddr[0])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipAdEntAddr[1])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipAdEntAddr[2])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipAdEntAddr[3])) return FALSE;
   } /* Endif */

   return TRUE;
} /* Endbody */

static boolean MIB_instance_ifEntry
   (
      RTCSMIB_WALK_PTR     mib,
      uint_32              op,
      boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
      boolean _PTR_        found,
      pointer _PTR_        instance
   )
{ /* Body */
   struct {
      uint_32 ifIndex;
   } index;

   *found = FALSE;
   *instance = NULL;

   switch (op) {

   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:

      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read32(mib, &index.ifIndex)) return FALSE;
      if (mib->inlen != 0) break;
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETNEXT:
      if (mib->inlen == 0) {
         index.ifIndex = 0;
      } else {
         if (!RTCSMIB_id_read32(mib, &index.ifIndex)) return FALSE;
         if(index.ifIndex < 0xffffffff) // 4294967295
            index.ifIndex++;
      } /* Endif */
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETFIRST:
      index.ifIndex = 0;
      *found = find(RTCSMIB_OP_GETNEXT, &index, instance);
      break;
   } /* Endswitch */

   if (*found && (op != RTCSMIB_OP_SET)) {
      if (!RTCSMIB_id_write32 (mib, index.ifIndex)) return FALSE;
   } /* Endif */

   return TRUE;
} /* Endbody */

static boolean MIB_instance_udpEntry
   (
      RTCSMIB_WALK_PTR     mib,
      uint_32              op,
      boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
      boolean _PTR_        found,
      pointer _PTR_        instance
   )
{ /* Body */
   struct {
      uchar   udpLocalAddress[4];
      uint_32 udpLocalPort;
   } index;

   *found = FALSE;
   *instance = NULL;

   switch (op) {

   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:

      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.udpLocalAddress[0])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.udpLocalAddress[1])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.udpLocalAddress[2])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.udpLocalAddress[3])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read32(mib, &index.udpLocalPort)) return FALSE;
      if (mib->inlen != 0) break;
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETNEXT:
      if (mib->inlen == 0) {
         index.udpLocalAddress[0] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.udpLocalAddress[0])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.udpLocalAddress[1] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.udpLocalAddress[1])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.udpLocalAddress[2] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.udpLocalAddress[2])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.udpLocalAddress[3] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.udpLocalAddress[3])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.udpLocalPort = 0;
      } else {
         if (!RTCSMIB_id_read32(mib, &index.udpLocalPort)) return FALSE;
         if(index.udpLocalPort < 0xffffffff) // 4294967295
            index.udpLocalPort++;
      } /* Endif */
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETFIRST:
      index.udpLocalAddress[0] = 0;
      index.udpLocalAddress[1] = 0;
      index.udpLocalAddress[2] = 0;
      index.udpLocalAddress[3] = 0;
      index.udpLocalPort = 0;
      *found = find(RTCSMIB_OP_GETNEXT, &index, instance);
      break;
   } /* Endswitch */

   if (*found && (op != RTCSMIB_OP_SET)) {
      if (!RTCSMIB_id_write8  (mib, index.udpLocalAddress[0])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.udpLocalAddress[1])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.udpLocalAddress[2])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.udpLocalAddress[3])) return FALSE;
      if (!RTCSMIB_id_write32 (mib, index.udpLocalPort)) return FALSE;
   } /* Endif */

   return TRUE;
} /* Endbody */

static boolean MIB_instance_ipRouteEntry
   (
      RTCSMIB_WALK_PTR     mib,
      uint_32              op,
      boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
      boolean _PTR_        found,
      pointer _PTR_        instance
   )
{ /* Body */
   struct {
      uchar   ipRouteDest[4];
   } index;

   *found = FALSE;
   *instance = NULL;

   switch (op) {

   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:

      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipRouteDest[0])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipRouteDest[1])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipRouteDest[2])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipRouteDest[3])) return FALSE;
      if (mib->inlen != 0) break;
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETNEXT:
      if (mib->inlen == 0) {
         index.ipRouteDest[0] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipRouteDest[0])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipRouteDest[1] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipRouteDest[1])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipRouteDest[2] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipRouteDest[2])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipRouteDest[3] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipRouteDest[3])) return FALSE;
         if(index.ipRouteDest[3] < 255)
            index.ipRouteDest[3]++;
      } /* Endif */
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETFIRST:
      index.ipRouteDest[0] = 0;
      index.ipRouteDest[1] = 0;
      index.ipRouteDest[2] = 0;
      index.ipRouteDest[3] = 0;
      *found = find(RTCSMIB_OP_GETNEXT, &index, instance);
      break;
   } /* Endswitch */

   if (*found && (op != RTCSMIB_OP_SET)) {
      if (!RTCSMIB_id_write8  (mib, index.ipRouteDest[0])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipRouteDest[1])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipRouteDest[2])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipRouteDest[3])) return FALSE;
   } /* Endif */

   return TRUE;
} /* Endbody */

static boolean MIB_instance_tcpConnEntry
   (
      RTCSMIB_WALK_PTR     mib,
      uint_32              op,
      boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
      boolean _PTR_        found,
      pointer _PTR_        instance
   )
{ /* Body */
   struct {
      uchar   tcpConnLocalAddress[4];
      uint_32 tcpConnLocalPort;
      uchar   tcpConnRemAddress[4];
      uint_32 tcpConnRemPort;
   } index;

   *found = FALSE;
   *instance = NULL;

   switch (op) {

   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:

      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.tcpConnLocalAddress[0])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.tcpConnLocalAddress[1])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.tcpConnLocalAddress[2])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.tcpConnLocalAddress[3])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read32(mib, &index.tcpConnLocalPort)) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.tcpConnRemAddress[0])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.tcpConnRemAddress[1])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.tcpConnRemAddress[2])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.tcpConnRemAddress[3])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read32(mib, &index.tcpConnRemPort)) return FALSE;
      if (mib->inlen != 0) break;
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETNEXT:
      if (mib->inlen == 0) {
         index.tcpConnLocalAddress[0] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.tcpConnLocalAddress[0])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnLocalAddress[1] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.tcpConnLocalAddress[1])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnLocalAddress[2] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.tcpConnLocalAddress[2])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnLocalAddress[3] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.tcpConnLocalAddress[3])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnLocalPort = 0;
      } else {
         if (!RTCSMIB_id_read32(mib, &index.tcpConnLocalPort)) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnRemAddress[0] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.tcpConnRemAddress[0])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnRemAddress[1] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.tcpConnRemAddress[1])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnRemAddress[2] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.tcpConnRemAddress[2])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnRemAddress[3] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.tcpConnRemAddress[3])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.tcpConnRemPort = 0;
      } else {
         if (!RTCSMIB_id_read32(mib, &index.tcpConnRemPort)) return FALSE;
         if(index.tcpConnRemPort < 0xffffffff) // 4294967295
            index.tcpConnRemPort++;
      } /* Endif */
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETFIRST:
      index.tcpConnLocalAddress[0] = 0;
      index.tcpConnLocalAddress[1] = 0;
      index.tcpConnLocalAddress[2] = 0;
      index.tcpConnLocalAddress[3] = 0;
      index.tcpConnLocalPort = 0;
      index.tcpConnRemAddress[0] = 0;
      index.tcpConnRemAddress[1] = 0;
      index.tcpConnRemAddress[2] = 0;
      index.tcpConnRemAddress[3] = 0;
      index.tcpConnRemPort = 0;
      *found = find(RTCSMIB_OP_GETNEXT, &index, instance);
      break;
   } /* Endswitch */

   if (*found && (op != RTCSMIB_OP_SET)) {
      if (!RTCSMIB_id_write8  (mib, index.tcpConnLocalAddress[0])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.tcpConnLocalAddress[1])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.tcpConnLocalAddress[2])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.tcpConnLocalAddress[3])) return FALSE;
      if (!RTCSMIB_id_write32 (mib, index.tcpConnLocalPort)) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.tcpConnRemAddress[0])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.tcpConnRemAddress[1])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.tcpConnRemAddress[2])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.tcpConnRemAddress[3])) return FALSE;
      if (!RTCSMIB_id_write32 (mib, index.tcpConnRemPort)) return FALSE;
   } /* Endif */

   return TRUE;
} /* Endbody */

static boolean MIB_instance_ipNetToMediaEntry
   (
      RTCSMIB_WALK_PTR     mib,
      uint_32              op,
      boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
      boolean _PTR_        found,
      pointer _PTR_        instance
   )
{ /* Body */
   struct {
      uint_32 ipNetToMediaIfIndex;
      uchar   ipNetToMediaNetAddress[4];
   } index;

   *found = FALSE;
   *instance = NULL;

   switch (op) {

   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:

      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read32(mib, &index.ipNetToMediaIfIndex)) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipNetToMediaNetAddress[0])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipNetToMediaNetAddress[1])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipNetToMediaNetAddress[2])) return FALSE;
      if (mib->inlen == 0) break;
      if (!RTCSMIB_id_read8(mib, &index.ipNetToMediaNetAddress[3])) return FALSE;
      if (mib->inlen != 0) break;
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETNEXT:
      if (mib->inlen == 0) {
         index.ipNetToMediaIfIndex = 0;
      } else {
         if (!RTCSMIB_id_read32(mib, &index.ipNetToMediaIfIndex)) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipNetToMediaNetAddress[0] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipNetToMediaNetAddress[0])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipNetToMediaNetAddress[1] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipNetToMediaNetAddress[1])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipNetToMediaNetAddress[2] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipNetToMediaNetAddress[2])) return FALSE;
      } /* Endif */
      if (mib->inlen == 0) {
         index.ipNetToMediaNetAddress[3] = 0;
      } else {
         if (!RTCSMIB_id_read8(mib, &index.ipNetToMediaNetAddress[3])) return FALSE;
         if(index.ipNetToMediaNetAddress[3] < 255)
            index.ipNetToMediaNetAddress[3]++;
      } /* Endif */
      *found = find(op, &index, instance);
      break;

   case RTCSMIB_OP_GETFIRST:
      index.ipNetToMediaIfIndex = 0;
      index.ipNetToMediaNetAddress[0] = 0;
      index.ipNetToMediaNetAddress[1] = 0;
      index.ipNetToMediaNetAddress[2] = 0;
      index.ipNetToMediaNetAddress[3] = 0;
      *found = find(RTCSMIB_OP_GETNEXT, &index, instance);
      break;
   } /* Endswitch */

   if (*found && (op != RTCSMIB_OP_SET)) {
      if (!RTCSMIB_id_write32 (mib, index.ipNetToMediaIfIndex)) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipNetToMediaNetAddress[0])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipNetToMediaNetAddress[1])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipNetToMediaNetAddress[2])) return FALSE;
      if (!RTCSMIB_id_write8  (mib, index.ipNetToMediaNetAddress[3])) return FALSE;
   } /* Endif */

   return TRUE;
} /* Endbody */


#endif


/********************************************************/

#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4

#include <rtcs_prv.h>
#include "tcpip.h"
#include "ip_prv.h"
#include "arp_prv.h"
#include "tcp_prv.h"
#include "udp_prv.h"

extern boolean MIB_find_ifEntry(uint_32, pointer, pointer _PTR_);
extern uint_32 MIB_get_ifIndex (pointer interface);
extern uint_32 MIB_get_sysUpTime(pointer);

static uchar IpAddress[4];

static uint_32 MIB_get_snmpInPkts(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->COMMON.ST_RX_TOTAL);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutPkts(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->COMMON.ST_TX_TOTAL);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInBadVersions(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_BAD_VERSION);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInBadCommunityNames(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_BAD_COMMUNITY);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInASNParseErrs(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_BAD_PARSE);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInTotalReqVars(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_VAR_GETS);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInTotalSetVars(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_VAR_SETS);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInGetRequests(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_GETREQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInGetNexts(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_GETNEXTREQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInSetRequests(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_SETREQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInGetResponses(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_RESPONSE);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpInTraps(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_RX_TRAP);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutTooBigs(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_TOOBIG);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutNoSuchNames(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_NOSUCHNAME);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutBadValues(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_BADVALUE);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutGenErrs(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_GENERR);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutGetRequests(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_GETREQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutGetNexts(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_GETNEXTREQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutSetRequests(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_SETREQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutGetResponses(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_RESPONSE);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_snmpOutTraps(pointer dummy)
{
    #if RTCSCFG_ENABLE_SNMP_STATS
    SNMP_STATS_PTR    SNMP_stats_ptr   = SNMP_get_data();
    return(SNMP_stats_ptr->ST_TX_TRAP);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_udpNoPorts(pointer dummy)
{
    #if RTCSCFG_ENABLE_UDP_STATS    
    UDP_STATS_PTR    UDP_stats_ptr   = UDP_stats();
    return(UDP_stats_ptr->ST_RX_NO_PORT);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_udpOutDatagrams(pointer dummy)
{
    #if RTCSCFG_ENABLE_UDP_STATS    
    UDP_STATS_PTR    UDP_stats_ptr   = UDP_stats();
    return(UDP_stats_ptr->COMMON.ST_TX_TOTAL);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_tcpActiveOpens(pointer dummy)
{
    #if RTCSCFG_ENABLE_TCP_STATS
    TCP_STATS_PTR    TCP_stats_ptr   = TCP_stats();
    return(TCP_stats_ptr->ST_CONN_ACTIVE);
    #else
    return(0);  
    #endif
}
 
static uint_32 MIB_get_tcpAttemptFails(pointer dummy)
{
    #if RTCSCFG_ENABLE_TCP_STATS
    TCP_STATS_PTR    TCP_stats_ptr   = TCP_stats();
    return(TCP_stats_ptr->ST_CONN_FAILED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_tcpEstabResets(pointer dummy)
{
    #if RTCSCFG_ENABLE_TCP_STATS
    TCP_STATS_PTR    TCP_stats_ptr   = TCP_stats();
    return(TCP_stats_ptr->ST_CONN_RESET);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_tcpInSegs(pointer dummy)
{
    #if RTCSCFG_ENABLE_TCP_STATS
    TCP_STATS_PTR    TCP_stats_ptr   = TCP_stats();
    return(TCP_stats_ptr->COMMON.ST_RX_TOTAL);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_tcpRetransSegs(pointer dummy)
{
    #if RTCSCFG_ENABLE_TCP_STATS
    TCP_STATS_PTR    TCP_stats_ptr   = TCP_stats();
    return(TCP_stats_ptr->ST_TX_DATA_DUP);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_tcpRtoMin(pointer dummy)
{
    return(TCP_RTO_MIN);
}

static uint_32 MIB_get_tcpRtoMax(pointer dummy)
{
    return(2 * TCP_MSL);
}

static uint_32 MIB_get_icmpInMsgs(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->COMMON.ST_RX_TOTAL);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInErrors(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->COMMON.ST_RX_DISCARDED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInDestUnreachs(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_DESTUNREACH);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInTimeExcds(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_TIMEEXCEED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInParmProbs(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_PARMPROB);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInSrcQuenchs(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_SRCQUENCH);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInRedirects(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_REDIRECT);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInEchos(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_ECHO_REQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInEchoReps(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_ECHO_REPLY);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInTimestamps(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_TIME_REQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInTimestampReps(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_TIME_REPLY);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInAddrMasks(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_INFO_REQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpInAddrMaskReps(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_RX_INFO_REPLY);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutMsgs(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->COMMON.ST_TX_TOTAL);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutErrors(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->COMMON.ST_TX_DISCARDED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutDestUnreachs(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_DESTUNREACH);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutTimeExcds(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_TIMEEXCEED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutParmProbs(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_PARMPROB);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutSrcQuenchs(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_SRCQUENCH);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutRedirects(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_REDIRECT);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutEchos(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_ECHO_REQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutEchoReps(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_ECHO_REPLY);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutTimestamps(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_TIME_REQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutTimestampReps(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_TIME_REPLY);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutAddrMasks(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_INFO_REQ);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_icmpOutAddrMaskReps(pointer dummy)
{
    #if RTCSCFG_ENABLE_ICMP_STATS
    ICMP_STATS_PTR    ICMP_stats_ptr   = ICMP_stats();
    return(ICMP_stats_ptr->ST_TX_INFO_REPLY);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipReasmTimeout(pointer dummy)
{
    return(IPREASM_TTL);
}

static uint_32 MIB_get_ipInReceives(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->COMMON.ST_RX_TOTAL);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipInHdrErrors(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_RX_HDR_ERRORS);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipInAddrErrors(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_RX_ADDR_ERRORS);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipForwDatagrams(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_RX_FORWARDED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipInUnknownProtos(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_RX_NO_PROTO);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipInDiscards(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->COMMON.ST_RX_MISSED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipInDelivers(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_RX_DELIVERED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipOutRequests(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->COMMON.ST_TX_TOTAL);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipOutDiscards(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->COMMON.ST_TX_MISSED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipReasmReqds(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_RX_FRAG_RECVD);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipReasmOKs(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_RX_FRAG_REASMD);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipReasmFails(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_RX_FRAG_DISCARDED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipFragOKs(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_TX_FRAG_FRAGD);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipFragFails(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_TX_FRAG_DISCARDED);
    #else
    return(0);  
    #endif
}

static uint_32 MIB_get_ipFragCreates(pointer dummy)
{
    #if RTCSCFG_ENABLE_IP_STATS
    IP_STATS_PTR    IP_stats_ptr   = IP_stats();
    return(IP_stats_ptr->ST_TX_FRAG_SENT);
    #else
    return(0);  
    #endif
}

uint_32 MIB_get_sysUpTime (pointer dummy)
{ /* Body */
   TIME_STRUCT uptime;
   _time_get_elapsed(&uptime);
   return (uptime.SECONDS * 100) + (uptime.MILLISECONDS / 10);
} /* Endbody */

static uint_32 MIB_set_dispstr
   (
      uchar_ptr _PTR_ dest,
      uchar_ptr       varptr,
      uint_32         varlen
   )
{ /* Body */
   uchar_ptr dispstr = NULL;

   /* SIZE for DisplayString in MIB is between 0 to 255 */
   if ((varlen + 1) >= 255)
      return SNMP_ERROR_wrongLength;

   if (varlen) {
      dispstr = RTCS_mem_alloc(varlen+1);
      if (!dispstr) {
         return SNMP_ERROR_resourceUnavailable;
      } /* Endif */
      _mem_copy(varptr, dispstr, varlen);
      dispstr[varlen] = '\0';
   } /* Endif */

   if (*dest) {
      _mem_free(*dest);
   } /* Endif */

   *dest = dispstr;
   return SNMP_ERROR_noError;

} /* Endbody */

static uint_32 MIB_set_sysContact (pointer dummy, uchar_ptr varptr, uint_32 varlen)
{ /* Body */
   return MIB_set_dispstr((unsigned char **)(&MIBVALUE_sysContact.PARAM), varptr, varlen);
} /* Endbody */

static uint_32 MIB_set_sysName (pointer dummy, uchar_ptr varptr, uint_32 varlen)
{ /* Body */
   return MIB_set_dispstr((unsigned char **)(&MIBVALUE_sysName.PARAM), varptr, varlen);
} /* Endbody */

static uint_32 MIB_set_sysLocation (pointer dummy, uchar_ptr varptr, uint_32 varlen)
{ /* Body */
   return MIB_set_dispstr((unsigned char **)(&MIBVALUE_sysLocation.PARAM), varptr, varlen);
} /* Endbody */


struct MIB_get_ifNumber_struct {
   uint_32                 current_index;
   IP_CFG_STRUCT_PTR       IP_cfg_ptr;
   IP_ROUTE_DIRECT_PTR     direct;
};

static boolean MIB_get_ifNumber_test2
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   IP_ROUTE_PTR                  route = node_data;
   struct MIB_get_ifNumber_struct _PTR_ testdata = data;

   /* Check only leaves, which have a DESTIF of LOCALHOST */
   if (route && route->DIRECT &&
      route->DIRECT->DESTIF == RTCS_IF_LOCALHOST_PRV)
   {
      if (testdata->direct == route->DIRECT) {
         testdata->current_index++;
      } /* Endif */

      if (testdata->direct->NETIF == route->DIRECT->NETIF) {
         return TRUE;
      }
   } /* Endif */

   return FALSE;

} /* Endbody */

static boolean MIB_get_ifNumber_test1
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   IP_ROUTE_PTR                  route = node_data;
   struct MIB_get_ifNumber_struct _PTR_ testdata = data;

   /* Check only leaves, which have a DESTIF of LOCALHOST */
   if (route && route->DIRECT &&
      route->DIRECT->DESTIF == RTCS_IF_LOCALHOST_PRV)
   {
      testdata->direct = route->DIRECT;
      IPRADIX_walk(&testdata->IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_get_ifNumber_test2,
         testdata);
   } /* Endif */

   return FALSE;
} /* Body */

static uint_32 MIB_get_ifNumber (pointer dummy)
{ /* Body */
   IP_CFG_STRUCT_PTR                IP_cfg_ptr = RTCS_getcfg(IP);
   struct MIB_get_ifNumber_struct   testdata;

   testdata.current_index  = 0;
   testdata.IP_cfg_ptr     = IP_cfg_ptr;
   testdata.direct         = NULL;

   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_get_ifNumber_test1, &testdata);

   return testdata.current_index;

} /* Endbody */

struct MIB_get_ifif_struct {
   uint_32                 current_index;
   IP_CFG_STRUCT_PTR       IP_cfg_ptr;
   IP_ROUTE_DIRECT_PTR     direct;
   IP_IF_PTR               interface;
   uint_32                 ifindex;
};

static boolean MIB_get_ifif_test2
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   IP_ROUTE_PTR                     route = node_data;
   struct MIB_get_ifif_struct _PTR_ testdata = data;

   /* Check only leaves, which have a DESTIF of LOCALHOST */
   if (route && route->DIRECT &&
      route->DIRECT->DESTIF == RTCS_IF_LOCALHOST_PRV)
   {
      if (testdata->direct == route->DIRECT) {
         testdata->current_index++;
         if (testdata->ifindex == testdata->current_index) {
            testdata->interface = testdata->direct->NETIF;
            return TRUE;
         } /* Endif */
      } /* Endif */

      if (testdata->direct->NETIF == route->DIRECT->NETIF) {
         return TRUE;
      }
   } /* Endif */

   return FALSE;

} /* Endbody */

static boolean MIB_get_ifif_test1
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   IP_ROUTE_PTR                     route = node_data;
   struct MIB_get_ifif_struct _PTR_ testdata = data;

   /* Check only leaves, which have a DESTIF of LOCALHOST */
   if (route && route->DIRECT &&
      route->DIRECT->DESTIF == RTCS_IF_LOCALHOST_PRV)
   {
      testdata->direct = route->DIRECT;
      IPRADIX_walk(&testdata->IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_get_ifif_test2,
         testdata);
      if (testdata->interface) {
         return TRUE;
      } /* Endif */
   } /* Endif */

   return FALSE;
} /* Body */

static pointer MIB_get_ifif (uint_32 ifindex)
{ /* Body */
   IP_CFG_STRUCT_PTR          IP_cfg_ptr = RTCS_getcfg(IP);
   struct MIB_get_ifif_struct testdata;

   testdata.current_index  = 0;
   testdata.IP_cfg_ptr     = IP_cfg_ptr;
   testdata.direct         = NULL;
   testdata.ifindex        = ifindex;
   testdata.interface      = NULL;

   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_get_ifif_test1, &testdata);

   return testdata.interface;
} /* Endbody */

struct MIB_get_ifIndex_struct {
   uint_32                 current_index;
   IP_CFG_STRUCT_PTR       IP_cfg_ptr;
   IP_ROUTE_DIRECT_PTR     direct;
   IP_IF_PTR               interface;
   uint_32                 ifindex;
};

static boolean MIB_get_ifIndex_test2
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   IP_ROUTE_PTR                        route = node_data;
   struct MIB_get_ifIndex_struct _PTR_ testdata = data;

   /* Check only leaves, which have a DESTIF of LOCALHOST */
   if (route && route->DIRECT &&
      route->DIRECT->DESTIF == RTCS_IF_LOCALHOST_PRV)
   {
      if (testdata->direct == route->DIRECT) {
         testdata->current_index++;
         if (testdata->interface == testdata->direct->NETIF) {
            testdata->ifindex = testdata->current_index;
            return TRUE;
         } /* Endif */
      } /* Endif */

      if (testdata->direct->NETIF == route->DIRECT->NETIF) {
         return TRUE;
      }
   } /* Endif */

   return FALSE;

} /* Endbody */

static boolean MIB_get_ifIndex_test1
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   IP_ROUTE_PTR                        route = node_data;
   struct MIB_get_ifIndex_struct _PTR_ testdata = data;

   /* Check only leaves, which have a DESTIF of LOCALHOST */
   if (route && route->DIRECT &&
      route->DIRECT->DESTIF == RTCS_IF_LOCALHOST_PRV)
   {
      testdata->direct = route->DIRECT;
      IPRADIX_walk(&testdata->IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_get_ifIndex_test2,
         testdata);
      if (testdata->ifindex) {
         return TRUE;
      } /* Endif */
   } /* Endif */

   return FALSE;
} /* Body */

uint_32 MIB_get_ifIndex (pointer interface)
{ /* Body */
   IP_CFG_STRUCT_PTR             IP_cfg_ptr = RTCS_getcfg(IP);
   struct MIB_get_ifIndex_struct testdata;

   testdata.current_index  = 0;
   testdata.IP_cfg_ptr     = IP_cfg_ptr;
   testdata.direct         = NULL;
   testdata.ifindex        = 0;
   testdata.interface      = interface;

   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_get_ifIndex_test1, &testdata);

   return testdata.ifindex;
} /* Endbody */

static uint_32 MIB_get_ifType (pointer interface) {return ((IP_IF_PTR)interface)->SNMP_IF_TYPE;}
static uint_32 MIB_get_ifMtu  (pointer interface) {return ((IP_IF_PTR)interface)->MTU;}

static uint_32 MIB_get_ifSpeed (pointer interface)
{ /* Body */
   switch (((IP_IF_PTR)interface)->SNMP_IF_TYPE) {
   case IPIFTYPE_ETHERNET:     return 10000000;
   case IPIFTYPE_FASTETHERNET: return 100000000;
   default:                    return 0;
   } /* Endswitch */
} /* Endbody */

static uchar_ptr MIB_get_ifPhysAddress (pointer interface, uint_32 _PTR_ len)
{ /* Body */
   *len = ((IP_IF_PTR)interface)->DEV_ADDRLEN;
   return ((IP_IF_PTR)interface)->DEV_ADDR;
} /* Endbody */

#if RTCSCFG_ENABLE_IPIF_STATS
static uint_32 MIB_get_ifInOctets      (pointer interface) {return ((IP_IF_PTR)interface)->STATS.ST_RX_OCTETS;}
static uint_32 MIB_get_ifInUcastPkts   (pointer interface) {return ((IP_IF_PTR)interface)->STATS.ST_RX_UNICAST;}
static uint_32 MIB_get_ifInNUcastPkts  (pointer interface) {return ((IP_IF_PTR)interface)->STATS.ST_RX_MULTICAST + ((IP_IF_PTR)interface)->STATS.ST_RX_BROADCAST;}
static uint_32 MIB_get_ifInDiscards    (pointer interface) {return ((IP_IF_PTR)interface)->STATS.COMMON.ST_RX_MISSED;}
static uint_32 MIB_get_ifInErrors      (pointer interface) {return ((IP_IF_PTR)interface)->STATS.COMMON.ST_RX_ERRORS;}
static uint_32 MIB_get_ifOutOctets     (pointer interface) {return ((IP_IF_PTR)interface)->STATS.ST_TX_OCTETS;}
static uint_32 MIB_get_ifOutUcastPkts  (pointer interface) {return ((IP_IF_PTR)interface)->STATS.ST_TX_UNICAST;}
static uint_32 MIB_get_ifOutNUcastPkts (pointer interface) {return ((IP_IF_PTR)interface)->STATS.ST_TX_MULTICAST + ((IP_IF_PTR)interface)->STATS.ST_TX_BROADCAST;}
static uint_32 MIB_get_ifOutDiscards   (pointer interface) {return ((IP_IF_PTR)interface)->STATS.COMMON.ST_TX_MISSED;}
static uint_32 MIB_get_ifOutErrors     (pointer interface) {return ((IP_IF_PTR)interface)->STATS.COMMON.ST_TX_ERRORS;}
#else
static uint_32 MIB_get_ifInOctets      (pointer interface) {return 0;}
static uint_32 MIB_get_ifInUcastPkts   (pointer interface) {return 0;}
static uint_32 MIB_get_ifInNUcastPkts  (pointer interface) {return 0;}
static uint_32 MIB_get_ifInDiscards    (pointer interface) {return 0;}
static uint_32 MIB_get_ifInErrors      (pointer interface) {return 0;}
static uint_32 MIB_get_ifOutOctets     (pointer interface) {return 0;}
static uint_32 MIB_get_ifOutUcastPkts  (pointer interface) {return 0;}
static uint_32 MIB_get_ifOutNUcastPkts (pointer interface) {return 0;}
static uint_32 MIB_get_ifOutDiscards   (pointer interface) {return 0;}
static uint_32 MIB_get_ifOutErrors     (pointer interface) {return 0;}
#endif

static RTCSMIB_NODE_PTR MIB_get_ifSpecific (pointer interface)
{ /* Body */
   switch (((IP_IF_PTR)interface)->SNMP_IF_TYPE) {
   default: return NULL;
   } /* Endswitch */
} /* Endbody */

boolean MIB_find_ifEntry
   (
      uint_32        op,
      pointer        index,
      pointer _PTR_  instance
   )
{ /* Body */
   uint_32           ifindex = *(uint_32_ptr)index;
   pointer           interface;

   if ((op == RTCSMIB_OP_GETNEXT) && (ifindex == 0)) {
      ifindex = 1;
   } /* Endif */

   interface = MIB_get_ifif(ifindex);
   if (!interface) {
      return FALSE;
   } /* Endif */
   *(uint_32_ptr)index = ifindex;
   *instance = interface;
   return TRUE;

} /* Endbody */

static uint_32 MIB_set_ifAdminStatus (pointer dummy, uchar_ptr varptr, uint_32 varlen)
{ /* Body */
   int_32 varval = RTCSMIB_int_read(varptr, varlen);
   switch (varval) {
   case 1:  return SNMP_ERROR_noError;
   case 2:
   case 3:  return SNMP_ERROR_inconsistentValue;
   default: return SNMP_ERROR_wrongValue;
   } /* Endswitch */
} /* Endbody */

static uint_32 MIB_get_ipForwarding (pointer dummy) {return _IP_forward ? 1 : 2;}

static uint_32 MIB_get_ipDefaultTTL (pointer dummy)
{ /* Body */
   IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP);
   return IP_cfg_ptr->DEFAULT_TTL;
} /* Endbody */

static uchar_ptr MIB_get_ipAdEntAddr (pointer ipaddr, uint_32 _PTR_ len)
{ /* Body */
   IP_ROUTE_DIRECT_PTR ipaddr_ptr = ipaddr;
   htonl(IpAddress, ipaddr_ptr->ADDRESS);
   *len = 4;
   return IpAddress;
} /* Endbody */

static uint_32 MIB_get_ipAdEntIfIndex (pointer ipaddr)
{ /* Body */
   IP_ROUTE_DIRECT_PTR ipaddr_ptr = ipaddr;
   return MIB_get_ifIndex(ipaddr_ptr->NETIF);
} /* Endbody */

static uchar_ptr MIB_get_ipAdEntNetMask (pointer ipaddr, uint_32 _PTR_ len)
{ /* Body */
   IP_ROUTE_DIRECT_PTR ipaddr_ptr = ipaddr;
   _ip_address         netmask;

   if (IP_get_netmask(ipaddr_ptr->NETIF, ipaddr_ptr->ADDRESS, &netmask)) {
      htonl(IpAddress, netmask);
      *len = 4;
      return IpAddress;
   } /* Endif */

   htonl(IpAddress, 0xFFFFFFFF);
   *len = 4;
   return IpAddress;
} /* Endbody */

struct MIB_get_ipRouteDest_struct {
   _ip_address             netaddr;
   _ip_address             netmask;
   pointer                 iproute;
};

static boolean MIB_get_ipRouteDest_test
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct MIB_get_ipRouteDest_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                              route = node_data;
   IP_ROUTE_INDIRECT_PTR                     indirect;
   IP_ROUTE_DIRECT_PTR                       direct;

   if (route && route->DIRECT) {
      direct = route->DIRECT;
      do {
         if (direct == testdata->iproute) {
            testdata->netaddr = route->NODE.IP;
            testdata->netmask = route->NODE.MASK;
            return TRUE;
         } /* Endif */
         direct = direct->NEXT;
      } while (direct != route->DIRECT);
   } /* Endif */

   if (route && route->INDIRECT) {
      indirect = route->INDIRECT;
      do {
         if (indirect == testdata->iproute) {
            testdata->netaddr = route->NODE.IP;
            testdata->netmask = route->NODE.MASK;
            return TRUE;
         } /* Endif */
         indirect = indirect->NEXT;
      } while(indirect != route->INDIRECT);
   } /* Endif */

   return FALSE;
} /* Endbody */


static uchar_ptr MIB_get_ipRouteDest (pointer iproute, uint_32 _PTR_ len)
{ /* Body */
   IP_CFG_STRUCT_PTR                   IP_cfg_ptr = RTCS_getcfg(IP);
   struct MIB_get_ipRouteDest_struct   testdata;

   testdata.netaddr = INADDR_ANY;
   testdata.iproute = iproute;

   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_get_ipRouteDest_test, &testdata);

   htonl(IpAddress, testdata.netaddr);
   *len = 4;
   return IpAddress;
} /* Endbody */


static uint_32 MIB_get_ipRouteIfIndex (pointer iproute)
{ /* Body */
   IP_ROUTE_DIRECT_PTR                    direct = iproute;
   IP_ROUTE_INDIRECT_PTR                  indirect = iproute;
   IP_IF_PTR                              ip_interface;
   _ip_address                            if_ip;

   /* If it is a directly connected route */
   if (((IP_ROUTE_INDIRECT_PTR) iproute)->IS_DIRECT) {
      return MIB_get_ifIndex(direct->NETIF);
   } /* Endif */

   /* If it is an indirectly connected route */
   if_ip = IP_route_find(indirect->GATEWAY, IPROUTEOPT_GATE);
   if (if_ip != INADDR_ANY) {
      ip_interface = IP_find_if(if_ip);
      if (ip_interface) {
         return MIB_get_ifIndex(ip_interface);
      } /* Endif */
   } /* Endif */

   return 0;

} /* Endbody */


static uchar_ptr MIB_get_ipRouteNextHop (pointer iproute, uint_32 _PTR_ len)
{ /* Body */
   IP_ROUTE_INDIRECT_PTR iproute_ptr = iproute;
   htonl(IpAddress, iproute_ptr->GATEWAY);
   *len = 4;
   return IpAddress;
} /* Endbody */

static uint_32 MIB_get_ipRouteType (pointer iproute)
{ /* Body */
   IP_ROUTE_INDIRECT_PTR iproute_ptr = iproute;
   if (iproute_ptr->IS_DIRECT)   return 3;
   else                          return 4;
} /* Endbody */

static uchar_ptr MIB_get_ipRouteMask (pointer iproute, uint_32 _PTR_ len)
{ /* Body */
   IP_CFG_STRUCT_PTR                   IP_cfg_ptr = RTCS_getcfg(IP);
   struct MIB_get_ipRouteDest_struct   testdata;

   testdata.netmask = INADDR_ANY;
   testdata.iproute = iproute;

   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_get_ipRouteDest_test, &testdata);

   htonl(IpAddress, testdata.netmask);
   *len = 4;
   return IpAddress;
} /* Endbody */

static uint_32 MIB_get_ipNetToMediaIfIndex (pointer arp)
{ /* Body */
   ARP_ENTRY_PTR arp_ptr = arp;
   return MIB_get_ifIndex(arp_ptr->HEAD);
} /* Endbody */

static uchar_ptr MIB_get_ipNetToMediaPhysAddress (pointer arp, uint_32 _PTR_ len)
{ /* Body */
   ARP_ENTRY_PTR arp_ptr = arp;
   *len = 6;
   return arp_ptr->LADDR;
} /* Endbody */

static uchar_ptr MIB_get_ipNetToMediaNetAddress (pointer arp, uint_32 _PTR_ len)
{ /* Body */
   ARP_ENTRY_PTR arp_ptr = arp;
   htonl(IpAddress, arp_ptr->PADDR);
   *len = 4;
   return IpAddress;
} /* Endbody */

struct MIB_find_ipAddrEntry_struct {
   _ip_address             addr;
   IP_ROUTE_DIRECT_PTR     direct;
   _ip_address             netaddr;
   IP_IF_PTR               localhost;
};

static boolean MIB_find_ipAddrEntry_test
   (
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct MIB_find_ipAddrEntry_struct _PTR_  testdata = data;
   IP_ROUTE_PTR                              route = node_data;

   /* Check only leaves, which have a DESTIF of LOCALHOST */
   if (route->DIRECT && route->DIRECT->DESTIF == testdata->localhost) {
      if (route->DIRECT->ADDRESS == testdata->addr) {
         testdata->direct = route->DIRECT;
         return TRUE;
      } /* Endif */
   } /* Endif */

   return FALSE;
} /* Endbody */

static boolean MIB_find_ipAddrEntry_walk
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct MIB_find_ipAddrEntry_struct _PTR_  testdata = data;
   IP_ROUTE_PTR                              route = node_data;

   /* Check only leaves, which have a DESTIF of LOCALHOST */
   if (route && route->DIRECT &&
      route->DIRECT->DESTIF == testdata->localhost)
   {
      if (route->DIRECT->ADDRESS >= testdata->addr) {
         if (testdata->direct == NULL ||
            route->DIRECT->ADDRESS < testdata->direct->ADDRESS)
         {
            testdata->addr = route->DIRECT->ADDRESS;
            testdata->direct = route->DIRECT;
         } /* Endif */
      } /* Endif */
   } /* Endif */

   return FALSE;
} /* Endbody */

boolean MIB_find_ipAddrEntry
   (
      uint_32        op,
      pointer        index,
      pointer _PTR_  instance
   )
{ /* Body */
   IP_CFG_STRUCT_PTR                   IP_cfg_ptr = RTCS_getcfg(IP);
   struct MIB_find_ipAddrEntry_struct  testdata;

   struct {
      uchar   ipAdEntAddr[4];
   } _PTR_ realindex = index;

   testdata.addr        = ntohl(realindex->ipAdEntAddr);
   testdata.localhost   = RTCS_IF_LOCALHOST_PRV;
   testdata.direct      = NULL;

   switch (op) {
   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:
      IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, testdata.addr,
         MIB_find_ipAddrEntry_test, &testdata);
      break;

   case RTCSMIB_OP_GETNEXT:
      IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_find_ipAddrEntry_walk, &testdata);
      break;
   } /* Endswitch */

   if (!testdata.direct) {
      return FALSE;
   } /* Endif */

   htonl(realindex->ipAdEntAddr, testdata.direct->ADDRESS);
   *instance = testdata.direct;
   return TRUE;

} /* Endbody */

static boolean MIB_find_ipRouteEntry_test1
   (
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct MIB_find_ipAddrEntry_struct _PTR_  testdata = data;
   IP_ROUTE_PTR                              route = node_data;

   if (route->NODE.IP == testdata->addr) {
      testdata->direct = route->DIRECT;
      if (testdata->direct == NULL) {
         testdata->direct = (IP_ROUTE_DIRECT_PTR)((void _PTR_)route->INDIRECT);
         return TRUE;
      } /* Endif */
   } /* Endif */

   return FALSE;
} /* Enbody */

static boolean MIB_find_ipRouteEntry_walk1
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct MIB_find_ipAddrEntry_struct _PTR_  testdata = data;
   IP_ROUTE_PTR                              route = node_data;

   if (route) {
      if (node_ip >= testdata->addr) {
         if (testdata->direct == NULL || node_ip < testdata->netaddr) {
            testdata->netaddr = node_ip;
            testdata->direct = route->DIRECT;
            if (testdata->direct == NULL) {
               testdata->direct =
                  (IP_ROUTE_DIRECT_PTR)((void _PTR_)route->INDIRECT);
            } /* Endif */
         }  /* Endif */
      } /* Endif */
   } /* Endif */

   return FALSE;
} /* Endbody */

boolean MIB_find_ipRouteEntry
   (
      uint_32        op,
      pointer        index,
      pointer _PTR_  instance
   )
{ /* Body */
   IP_CFG_STRUCT_PTR                   IP_cfg_ptr = RTCS_getcfg(IP);
   struct MIB_find_ipAddrEntry_struct  testdata;
   struct {
      uchar   ipRouteDest[4];
   } _PTR_ realindex = index;

   testdata.addr = ntohl(realindex->ipRouteDest);
   testdata.direct = NULL;
   testdata.netaddr = INADDR_ANY;

   switch (op) {
   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:
      /* CR 1822 */
      /*
      IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, testdata.addr,
         MIB_find_ipRouteEntry_test1, &testdata);
      break;
      */
      /* End CR 1822 */

   case RTCSMIB_OP_GETNEXT:
      IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, MIB_find_ipRouteEntry_walk1, &testdata);
      break;
   } /* Endswitch */

   if (!testdata.direct) {
      return FALSE;
   } /* Endif */

   htonl(realindex->ipRouteDest, testdata.netaddr);
   *instance = testdata.direct;
   return TRUE;

} /* Endbody */

boolean MIB_find_ipNetToMediaEntry
   (
      uint_32        op,
      pointer        index,
      pointer _PTR_  instance
   )
{ /* Body */
   IP_IF_PTR         interface;
   ARP_CFG_PTR       arp_cfg_ptr;
   ARP_ENTRY_PTR     arp_ptr, search_ptr;
   uint_32           ifindex, maxindex, arphash;
   _ip_address       netaddr;
   struct {
      uint_32 ipNetToMediaIfIndex;
      uchar   ipNetToMediaNetAddress[4];
   } _PTR_ realindex = index;

   ifindex = realindex->ipNetToMediaIfIndex;
   netaddr = ntohl(realindex->ipNetToMediaNetAddress);
   maxindex = MIB_get_ifNumber(NULL);

   arp_ptr = NULL;
   switch (op) {
   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:
      interface = MIB_get_ifif(ifindex);
      if (!interface) {
         return FALSE;
      } /* Endif */
      arp_cfg_ptr = interface->ARP;
      if (!arp_cfg_ptr) {
         return FALSE;
      } /* Endif */
      for (arp_ptr = arp_cfg_ptr->CACHE[ARPCACHE_HASH(netaddr)];
           arp_ptr;
           arp_ptr = arp_ptr->NEXT) {
         if (arp_ptr->PADDR == netaddr) {
            break;
         } /* Endif */
      } /* Endfor */
      break;

   case RTCSMIB_OP_GETNEXT:
      for (; ifindex <= maxindex; ifindex++) {
         interface = MIB_get_ifif(ifindex);
         if (!interface) {
            continue;
         } /* Endif */
         arp_cfg_ptr = interface->ARP;
         if (!arp_cfg_ptr) {
            continue;
         } /* Endif */

         for (arphash = 0; arphash < ARPCACHE_SIZE; arphash++) {
            for (search_ptr = arp_cfg_ptr->CACHE[arphash];
                 search_ptr;
                 search_ptr = search_ptr->NEXT) {
               if (search_ptr->PADDR >= netaddr) {
                  if (arp_ptr == NULL) {
                     arp_ptr = search_ptr;
                  } else if (search_ptr->PADDR < arp_ptr->PADDR) {
                     arp_ptr = search_ptr;
                  } /* Endif */
               } /* Endif */
            } /* Endfor */
         } /* Endfor */

         if (arp_ptr) {
            break;
         } /* Endif */

      } /* Endfor */
      break;

   } /* Endswitch */

   if (!arp_ptr) {
      return FALSE;
   } /* Endif */

   realindex->ipNetToMediaIfIndex = ifindex;
   htonl(realindex->ipNetToMediaNetAddress, arp_ptr->PADDR);
   *instance = arp_ptr;
   return TRUE;

} /* Endbody */

uint_32 MIB_set_ipForwarding (pointer dummy, uchar_ptr varptr, uint_32 varlen)
{ /* Body */
   int_32 varval = RTCSMIB_int_read(varptr, varlen);
   switch (varval) {
   case 1: _IP_forward = TRUE;  return SNMP_ERROR_noError;
   case 2: _IP_forward = FALSE; return SNMP_ERROR_noError;
   default: return SNMP_ERROR_wrongValue;
   } /* Endswitch */
} /* Endbody */

uint_32 MIB_set_ipDefaultTTL (pointer dummy, uchar_ptr varptr, uint_32 varlen)
{ /* Body */
   IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP);
   int_32            varval = RTCSMIB_int_read(varptr, varlen);

   if (varval >= 1 && varval <= 255) {
      IP_cfg_ptr->DEFAULT_TTL = varval;
      return SNMP_ERROR_noError;
   } else {
      return SNMP_ERROR_wrongValue;
   } /* Endif */
} /* Endbody */

uint_32 MIB_set_ipRouteDest            (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteIfIndex         (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteMetric1         (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteMetric2         (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteMetric3         (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteMetric4         (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteMetric5         (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteNextHop         (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteType            (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteAge             (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipRouteMask            (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipNetToMediaIfIndex    (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipNetToMediaPhysAddress(pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipNetToMediaNetAddress (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}
uint_32 MIB_set_ipNetToMediaType       (pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}

static uint_32 MIB_get_tcpPassiveOpens (pointer dummy)
{ /* Body */
#if RTCSCFG_ENABLE_TCP_STATS
   TCP_CFG_STRUCT_PTR   TCP_cfg_ptr = RTCS_getcfg(TCP);
   TCB_STRUCT_PTR       tcb_ptr;
   uint_32              var;

   var = TCP_cfg_ptr->STATS.ST_CONN_PASSIVE;
   for (tcb_ptr = TCP_cfg_ptr->TCBhead;
        tcb_ptr;
        tcb_ptr = tcb_ptr->next) {
      if (tcb_ptr->state == LISTEN) var--;
   } /* Endfor */
   return var;
#else
   return 0;
#endif
} /* Endbody */

static uint_32 MIB_get_tcpCurrEstab (pointer dummy)
{ /* Body */
   TCP_CFG_STRUCT_PTR   TCP_cfg_ptr = RTCS_getcfg(TCP);
   TCB_STRUCT_PTR       tcb_ptr;
   uint_32              var;

   var = 0;
   for (tcb_ptr = TCP_cfg_ptr->TCBhead;
        tcb_ptr;
        tcb_ptr = tcb_ptr->next) {
      if (tcb_ptr->state == ESTABLISHED) var++;
   } /* Endfor */
   return var;

} /* Endbody */

static  uint_32 MIB_get_tcpOutSegs (pointer dummy)
{ /* Body */
 #if RTCSCFG_ENABLE_TCP_STATS
  TCP_STATS_PTR TCP_stats_ptr = TCP_stats();
   return TCP_stats_ptr->COMMON.ST_TX_TOTAL - TCP_stats_ptr->ST_TX_DATA_DUP;
#else
   return 0;
#endif
} /* Endbody */

static uint_32 MIB_get_tcpConnState (pointer tcb)
{ /* Body */
   switch (((TCB_STRUCT_PTR)tcb)->state) {
   case LISTEN:         return 2;
   case SYN_SENT:       return 3;
   case SYN_RECEIVED:   return 4;
   case ESTABLISHED:    return 5;
   case FINWAIT_1:      return 6;
   case FINWAIT_2:      return 7;
   case CLOSE_WAIT:     return 8;
   case LAST_ACK:       return 9;
   case CLOSING:        return 10;
   case TIME_WAIT:      return 11;
   default:             return 1;
   } /* Endswitch */
} /* Endbody */

static uchar_ptr MIB_get_tcpConnLocalAddress (pointer tcb, uint_32 _PTR_ len)
{ /* Body */
   TCB_STRUCT_PTR tcb_ptr = tcb;
   htonl(IpAddress, tcb_ptr->local_host);
   *len = 4;
   return IpAddress;
} /* Endbody */

static uint_32 MIB_get_tcpConnLocalPort (pointer tcb)
{ /* Body */
   return ((TCB_STRUCT_PTR)tcb)->local_port;
} /* Endbody */

static uchar_ptr MIB_get_tcpConnRemAddress (pointer tcb, uint_32 _PTR_ len)
{ /* Body */
   TCB_STRUCT_PTR tcb_ptr = tcb;
   htonl(IpAddress, tcb_ptr->remote_host);
   *len = 4;
   return IpAddress;
} /* Endbody */

static uint_32 MIB_get_tcpConnRemPort (pointer tcb)
{ /* Body */
   return ((TCB_STRUCT_PTR)tcb)->remote_port;
} /* Endbody */

boolean MIB_find_tcpConnEntry
   (
      uint_32        op,
      pointer        index,
      pointer _PTR_  instance
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   TCP_cfg_ptr = RTCS_getcfg(TCP);
   TCB_STRUCT_PTR       tcb_ptr, search_ptr;
   _ip_address          locaddr, remaddr;
   uint_16              locport, remport;
   struct {
      uchar   tcpConnLocalAddress[4];
      uint_32 tcpConnLocalPort;
      uchar   tcpConnRemAddress[4];
      uint_32 tcpConnRemPort;
   } _PTR_ realindex = index;

   locaddr = ntohl(realindex->tcpConnLocalAddress);
   locport = realindex->tcpConnLocalPort;
   remaddr = ntohl(realindex->tcpConnRemAddress);
   remport = realindex->tcpConnRemPort;

   tcb_ptr = NULL;
   switch (op) {
   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:
      for (tcb_ptr = TCP_cfg_ptr->TCBhead;
           tcb_ptr;
           tcb_ptr = tcb_ptr->next) {

         if ((tcb_ptr->local_host  == locaddr)
          && (tcb_ptr->local_port  == locport)
          && (tcb_ptr->remote_host == remaddr)
          && (tcb_ptr->remote_port == remport)) {

            break;
         } /* Endif */
      } /* Endfor */
      break;

   case RTCSMIB_OP_GETNEXT:
      for (search_ptr = TCP_cfg_ptr->TCBhead;
           search_ptr;
           search_ptr = search_ptr->next) {

         if ( (search_ptr->local_host >  locaddr)

          || ((search_ptr->local_host == locaddr)
           && (search_ptr->local_port >  locport))

          || ((search_ptr->local_host  == locaddr)
           && (search_ptr->local_port  == locport)
           && (search_ptr->remote_host >  remaddr))

          || ((search_ptr->local_host  == locaddr)
           && (search_ptr->local_port  == locport)
           && (search_ptr->remote_host == remaddr)
           && (search_ptr->remote_port >= remport)) ) {

            if (tcb_ptr == NULL) {
               tcb_ptr = search_ptr;
            } else if ( (search_ptr->local_host <  tcb_ptr->local_host)

                    || ((search_ptr->local_host == tcb_ptr->local_host)
                     && (search_ptr->local_port <  tcb_ptr->local_port))

                    || ((search_ptr->local_host  == tcb_ptr->local_host)
                     && (search_ptr->local_port  == tcb_ptr->local_port)
                     && (search_ptr->remote_host <  tcb_ptr->remote_host))

                    || ((search_ptr->local_host  == tcb_ptr->local_host)
                     && (search_ptr->local_port  == tcb_ptr->local_port)
                     && (search_ptr->remote_host == tcb_ptr->remote_host)
                     && (search_ptr->remote_port <  tcb_ptr->remote_port)) ) {
               tcb_ptr = search_ptr;
            } /* Endif */
         } /* Endif */
      } /* Endfor */
      break;

   } /* Endswitch */

   if (!tcb_ptr) {
      return FALSE;
   } /* Endif */

   htonl(realindex->tcpConnLocalAddress, tcb_ptr->local_host);
   realindex->tcpConnLocalPort = tcb_ptr->local_port;
   htonl(realindex->tcpConnRemAddress, tcb_ptr->remote_host);
   realindex->tcpConnRemPort = tcb_ptr->remote_port;
   *instance = tcb_ptr;
   return TRUE;

} /* Endbody */

static uint_32 MIB_set_tcpConnState(pointer dummy, uchar_ptr varptr, uint_32 varlen) {return SNMP_ERROR_inconsistentValue;}

static uint_32 MIB_get_udpInDatagrams (pointer dummy)
{ /* Body */
#if RTCSCFG_ENABLE_UDP_STATS
   UDP_STATS_PTR UDP_stats_ptr = UDP_stats();
   return UDP_stats_ptr->COMMON.ST_RX_TOTAL - UDP_stats_ptr->COMMON.ST_RX_DISCARDED;
#else
   return 0;
#endif
} /* Endbody */

static uint_32 MIB_get_udpInErrors (pointer dummy)
{ /* Body */
 #if RTCSCFG_ENABLE_UDP_STATS
  UDP_STATS_PTR UDP_stats_ptr = UDP_stats();
   return UDP_stats_ptr->COMMON.ST_RX_DISCARDED - UDP_stats_ptr->ST_RX_NO_PORT;
#else
   return 0;
#endif
} /* Endbody */

static uchar_ptr MIB_get_udpLocalAddress (pointer ucb, uint_32 _PTR_ len)
{ /* Body */
   UCB_STRUCT_PTR ucb_ptr = ucb;
   htonl(IpAddress, ucb_ptr->IPADDR);
   *len = 4;
   return IpAddress;
} /* Endbody */

static uint_32 MIB_get_udpLocalPort (pointer ucb)
{ /* Body */
   return ((UCB_STRUCT_PTR)ucb)->PORT;
} /* Endbody */

boolean MIB_find_udpEntry
   (
      uint_32        op,
      pointer        index,
      pointer _PTR_  instance
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr = RTCS_getcfg(UDP);
   UCB_STRUCT_PTR       ucb_ptr, search_ptr;
   _ip_address          locaddr;
   uint_16              locport;
   struct {
      uchar   udpLocalAddress[4];
      uint_32 udpLocalPort;
   } _PTR_ realindex = index;

   locaddr = ntohl(realindex->udpLocalAddress);
   locport = realindex->udpLocalPort;

   ucb_ptr = NULL;
   switch (op) {
   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:
      RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr) {
         if ((search_ptr->IPADDR == locaddr)
          && (search_ptr->PORT   == locport)) {
            ucb_ptr = search_ptr;
            break;
         } /* Endif */
      } /* End SEARCH */

      RTCS_LIST_SEARCH(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr) {
         if ((search_ptr->IPADDR == locaddr)
          && (search_ptr->PORT   == locport)) {
            ucb_ptr = search_ptr;
            break;
         } /* Endif */
      } /* End SEARCH */

      RTCS_LIST_SEARCH(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr) {
         if ((search_ptr->IPADDR == locaddr)
          && (search_ptr->PORT   == locport)) {
            ucb_ptr = search_ptr;
            break;
         } /* Endif */
      } /* End SEARCH */
      break;
   case RTCSMIB_OP_GETNEXT:
      RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr) {
         if ((search_ptr->IPADDR >  locaddr)
         || ((search_ptr->IPADDR == locaddr)
          && (search_ptr->PORT   >= locport))) {
            if (ucb_ptr == NULL) {
               ucb_ptr = search_ptr;
            } else if ((search_ptr->IPADDR <  ucb_ptr->IPADDR)
                   || ((search_ptr->IPADDR == ucb_ptr->IPADDR)
                    && (search_ptr->PORT   <  ucb_ptr->PORT))) {
               ucb_ptr = search_ptr;
            } /* Endif */
         } /* Endif */
      } /* End SEARCH */

      RTCS_LIST_SEARCH(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr) {
         if ((search_ptr->IPADDR >  locaddr)
         || ((search_ptr->IPADDR == locaddr)
          && (search_ptr->PORT   >= locport))) {
            if (ucb_ptr == NULL) {
               ucb_ptr = search_ptr;
            } else if ((search_ptr->IPADDR <  ucb_ptr->IPADDR)
                   || ((search_ptr->IPADDR == ucb_ptr->IPADDR)
                    && (search_ptr->PORT   <  ucb_ptr->PORT))) {
               ucb_ptr = search_ptr;
            } /* Endif */
         } /* Endif */
      } /* End SEARCH */

      RTCS_LIST_SEARCH(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr) {
         if ((search_ptr->IPADDR >  locaddr)
         || ((search_ptr->IPADDR == locaddr)
          && (search_ptr->PORT   >= locport))) {
            if (ucb_ptr == NULL) {
               ucb_ptr = search_ptr;
            } else if ((search_ptr->IPADDR <  ucb_ptr->IPADDR)
                   || ((search_ptr->IPADDR == ucb_ptr->IPADDR)
                    && (search_ptr->PORT   <  ucb_ptr->PORT))) {
               ucb_ptr = search_ptr;
            } /* Endif */
         } /* Endif */
      } /* End SEARCH */

      break;
   } /* Endswitch */

   if (!ucb_ptr) {
      return FALSE;
   } /* Endif */

   htonl(realindex->udpLocalAddress, ucb_ptr->IPADDR);
   realindex->udpLocalPort = ucb_ptr->PORT;
   *instance = ucb_ptr;
   return TRUE;

} /* Endbody */

uint_32 MIB_set_snmpEnableAuthenTraps
   (
      pointer     dummy,
      uchar_ptr   varptr,
      uint_32     varlen
   )
{ /* Body */
   /* CR 850 */
   int_32 varval = RTCSMIB_int_read(varptr, varlen);
   /* End CR 850 */
   switch (varval) {
   case 1:  return SNMP_ERROR_inconsistentValue;
   case 2:  return SNMP_ERROR_noError;
   default: return SNMP_ERROR_wrongValue;
   } /* Endswitch */
} /* Endbody */

/****************************************************************************/

const RTCSMIB_VALUE MIBVALUE_mib2 = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

/* system */
const RTCSMIB_VALUE MIBVALUE_system = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_sysDescr = {
    RTCSMIB_NODETYPE_DISPSTR_PTR,
    (void _PTR_)SNMPCFG_SYSDESCR
};

const RTCSMIB_VALUE MIBVALUE_sysObjectID = {
    RTCSMIB_NODETYPE_OID_PTR,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_sysUpTime = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_sysUpTime
};

const RTCSMIB_VALUE MIBVALUE_sysContact = {
    RTCSMIB_NODETYPE_DISPSTR_PTR,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_sysName = {
    RTCSMIB_NODETYPE_DISPSTR_PTR,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_sysLocation = {
    RTCSMIB_NODETYPE_DISPSTR_PTR,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_sysServices = {
    RTCSMIB_NODETYPE_UINT_CONST,
    (void _PTR_)SNMPCFG_SYSSERVICES
};

/* interfaces */
const RTCSMIB_VALUE MIBVALUE_interfaces = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ifNumber = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifNumber
};

const RTCSMIB_VALUE MIBVALUE_ifTable = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ifEntry = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ifIndex = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ifDescr = {
    RTCSMIB_NODETYPE_DISPSTR_PTR,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ifType = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifType
};

const RTCSMIB_VALUE MIBVALUE_ifMtu = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifMtu
};

const RTCSMIB_VALUE MIBVALUE_ifSpeed = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifSpeed
};

const RTCSMIB_VALUE MIBVALUE_ifPhysAddress = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ifPhysAddress
};

const RTCSMIB_VALUE MIBVALUE_ifAdminStatus = {
    RTCSMIB_NODETYPE_UINT_CONST,
    (void _PTR_)1
};

const RTCSMIB_VALUE MIBVALUE_ifOperStatus = {
    RTCSMIB_NODETYPE_UINT_CONST,
    (void _PTR_)1
};

const RTCSMIB_VALUE MIBVALUE_ifLastChange = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ifInOctets = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifInOctets
};

const RTCSMIB_VALUE MIBVALUE_ifInUcastPkts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifInUcastPkts
};

const RTCSMIB_VALUE MIBVALUE_ifInNUcastPkts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifInNUcastPkts
};

const RTCSMIB_VALUE MIBVALUE_ifInDiscards = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifInDiscards
};

const RTCSMIB_VALUE MIBVALUE_ifInErrors = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifInErrors
};

const RTCSMIB_VALUE MIBVALUE_ifInUnknownProtos = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ifOutOctets = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifOutOctets
};

const RTCSMIB_VALUE MIBVALUE_ifOutUcastPkts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifOutUcastPkts
};

const RTCSMIB_VALUE MIBVALUE_ifOutNUcastPkts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifOutNUcastPkts
};

const RTCSMIB_VALUE MIBVALUE_ifOutDiscards = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifOutDiscards
};

const RTCSMIB_VALUE MIBVALUE_ifOutErrors = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ifOutErrors
};

const RTCSMIB_VALUE MIBVALUE_ifOutQLen = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ifSpecific = {
    RTCSMIB_NODETYPE_OID_FN,
    (void _PTR_)(RTCSMIB_OID_FN_PTR)MIB_get_ifSpecific
};

/* IP */
const RTCSMIB_VALUE MIBVALUE_ip = {
    RTCSMIB_NODETYPE_INT_CONST,
    (void _PTR_)(RTCSMIB_OID_FN_PTR)MIB_get_ifSpecific
};

const RTCSMIB_VALUE MIBVALUE_ipForwarding = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_OID_FN_PTR)MIB_get_ipForwarding
};

const RTCSMIB_VALUE MIBVALUE_ipDefaultTTL = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_OID_FN_PTR)MIB_get_ipDefaultTTL
};

const RTCSMIB_VALUE MIBVALUE_ipInReceives = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipInReceives
};

const RTCSMIB_VALUE MIBVALUE_ipInHdrErrors = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipInHdrErrors
};

const RTCSMIB_VALUE MIBVALUE_ipInAddrErrors = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipInAddrErrors
};

const RTCSMIB_VALUE MIBVALUE_ipForwDatagrams = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipForwDatagrams
};

const RTCSMIB_VALUE MIBVALUE_ipInUnknownProtos = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipInUnknownProtos
};

const RTCSMIB_VALUE MIBVALUE_ipInDelivers = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipInDelivers
};

const RTCSMIB_VALUE MIBVALUE_ipOutRequests = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipOutRequests
};

const RTCSMIB_VALUE MIBVALUE_ipOutDiscards = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipOutDiscards
};

const RTCSMIB_VALUE MIBVALUE_ipOutNoRoutes = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipReasmTimeout = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipReasmTimeout
};

const RTCSMIB_VALUE MIBVALUE_ipReasmReqds = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipReasmReqds
};

const RTCSMIB_VALUE MIBVALUE_ipReasmOKs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipReasmOKs
};

const RTCSMIB_VALUE MIBVALUE_ipReasmFails = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipReasmFails
};

const RTCSMIB_VALUE MIBVALUE_ipFragOKs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipFragOKs
};

const RTCSMIB_VALUE MIBVALUE_ipFragFails = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipFragFails
};

const RTCSMIB_VALUE MIBVALUE_ipFragCreates = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipFragCreates
};

const RTCSMIB_VALUE MIBVALUE_ipAddrTable = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipAddrEntry = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipAdEntAddr = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ipAdEntAddr
};

const RTCSMIB_VALUE MIBVALUE_ipAdEntIfIndex = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipAdEntIfIndex
};

const RTCSMIB_VALUE MIBVALUE_ipAdEntNetMask = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ipAdEntNetMask
};

const RTCSMIB_VALUE MIBVALUE_ipAdEntBcastAddr = {
    RTCSMIB_NODETYPE_UINT_CONST,
    (void _PTR_)1
};

const RTCSMIB_VALUE MIBVALUE_ipAdEntReasmMaxSize = {
    RTCSMIB_NODETYPE_UINT_CONST,
    (void _PTR_)65535
};

const RTCSMIB_VALUE MIBVALUE_ipRouteTable = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRouteEntry = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRouteDest = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ipRouteDest
};

const RTCSMIB_VALUE MIBVALUE_ipRouteIfIndex = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipRouteIfIndex
};

const RTCSMIB_VALUE MIBVALUE_ipRouteMetric1 = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRouteMetric2 = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRouteMetric3 = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRouteMetric4 = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRouteNextHop = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ipRouteNextHop
};

const RTCSMIB_VALUE MIBVALUE_ipRouteType = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipRouteType
};

const RTCSMIB_VALUE MIBVALUE_ipRouteProto = {
    RTCSMIB_NODETYPE_UINT_CONST,
    (void _PTR_)2
};

const RTCSMIB_VALUE MIBVALUE_ipRouteAge = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRouteMask = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ipRouteMask
};

const RTCSMIB_VALUE MIBVALUE_ipRouteMetric5 = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRouteInfo = {
    RTCSMIB_NODETYPE_OID_PTR,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipNetToMediaIfIndex = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ipNetToMediaIfIndex
};

const RTCSMIB_VALUE MIBVALUE_ipNetToMediaPhysAddress = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ipNetToMediaPhysAddress
};

const RTCSMIB_VALUE MIBVALUE_ipNetToMediaNetAddress = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_ipNetToMediaNetAddress
};

const RTCSMIB_VALUE MIBVALUE_ipNetToMediaType = {
    RTCSMIB_NODETYPE_UINT_CONST,
    (void _PTR_)3
};

const RTCSMIB_VALUE MIBVALUE_ipNetToMediaTable = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipNetToMediaEntry = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_ipRoutingDiscards = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_icmp = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_icmpInMsgs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipInReceives
};

const RTCSMIB_VALUE MIBVALUE_icmpInErrors = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInErrors
};

const RTCSMIB_VALUE MIBVALUE_icmpInDestUnreachs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInDestUnreachs
};

const RTCSMIB_VALUE MIBVALUE_icmpInTimeExcds = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInTimeExcds
};

const RTCSMIB_VALUE MIBVALUE_icmpInParmProbs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInParmProbs
};

const RTCSMIB_VALUE MIBVALUE_icmpInSrcQuenchs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInSrcQuenchs
};

const RTCSMIB_VALUE MIBVALUE_icmpInRedirects = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInRedirects
};

const RTCSMIB_VALUE MIBVALUE_icmpInEchos = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInEchos
};

const RTCSMIB_VALUE MIBVALUE_icmpInEchoReps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInEchoReps
};

const RTCSMIB_VALUE MIBVALUE_icmpInTimestamps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInTimestamps
};

const RTCSMIB_VALUE MIBVALUE_icmpInTimestampReps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInTimestampReps
};

const RTCSMIB_VALUE MIBVALUE_icmpInAddrMasks = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInAddrMasks
};

const RTCSMIB_VALUE MIBVALUE_icmpInAddrMaskReps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpInAddrMaskReps
};

const RTCSMIB_VALUE MIBVALUE_icmpOutMsgs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutMsgs
};

const RTCSMIB_VALUE MIBVALUE_icmpOutErrors = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutErrors
};

const RTCSMIB_VALUE MIBVALUE_icmpOutDestUnreachs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutDestUnreachs
};

const RTCSMIB_VALUE MIBVALUE_icmpOutTimeExcds = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutTimeExcds
};

const RTCSMIB_VALUE MIBVALUE_icmpOutParmProbs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutParmProbs
};

const RTCSMIB_VALUE MIBVALUE_icmpOutSrcQuenchs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutSrcQuenchs
};

const RTCSMIB_VALUE MIBVALUE_icmpOutRedirects = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutRedirects
};

const RTCSMIB_VALUE MIBVALUE_icmpOutEchos = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutEchos
};

const RTCSMIB_VALUE MIBVALUE_icmpOutEchoReps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutEchoReps
};

const RTCSMIB_VALUE MIBVALUE_icmpOutTimestamps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutTimestamps
};

const RTCSMIB_VALUE MIBVALUE_icmpOutTimestampReps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutTimestampReps
};

const RTCSMIB_VALUE MIBVALUE_icmpOutAddrMasks = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutAddrMasks
};

const RTCSMIB_VALUE MIBVALUE_icmpOutAddrMaskReps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_icmpOutAddrMaskReps
};

const RTCSMIB_VALUE MIBVALUE_tcp = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_tcpRtoAlgorithm = {
    RTCSMIB_NODETYPE_UINT_CONST,
    (void _PTR_)4
};

const RTCSMIB_VALUE MIBVALUE_tcpRtoMin = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpRtoMin
};

const RTCSMIB_VALUE MIBVALUE_tcpRtoMax = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpRtoMax 
};

const RTCSMIB_VALUE MIBVALUE_tcpMaxConn = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_tcpActiveOpens = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpActiveOpens
};

const RTCSMIB_VALUE MIBVALUE_tcpPassiveOpens = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpPassiveOpens
};

const RTCSMIB_VALUE MIBVALUE_tcpAttemptFails = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpAttemptFails
};

const RTCSMIB_VALUE MIBVALUE_tcpEstabResets = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpEstabResets
};

const RTCSMIB_VALUE MIBVALUE_tcpCurrEstab = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpCurrEstab
};

const RTCSMIB_VALUE MIBVALUE_tcpInSegs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpInSegs
};

const RTCSMIB_VALUE MIBVALUE_tcpOutSegs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpOutSegs
};

const RTCSMIB_VALUE MIBVALUE_tcpRetransSegs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpRetransSegs
};

const RTCSMIB_VALUE MIBVALUE_tcpConnState = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpConnState
};

const RTCSMIB_VALUE MIBVALUE_tcpConnLocalAddress = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_tcpConnLocalAddress
};

const RTCSMIB_VALUE MIBVALUE_tcpConnLocalPort = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpConnLocalPort
};

const RTCSMIB_VALUE MIBVALUE_tcpConnRemAddress = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_tcpConnRemAddress
};

const RTCSMIB_VALUE MIBVALUE_tcpConnRemPort = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_tcpConnRemPort
};

const RTCSMIB_VALUE MIBVALUE_tcpConnTable = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_tcpConnEntry = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_tcpInErrs = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_tcpOutRsts = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_udp = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_udpInDatagrams = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_udpInDatagrams
};

const RTCSMIB_VALUE MIBVALUE_udpNoPorts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_udpNoPorts
};

const RTCSMIB_VALUE MIBVALUE_udpInErrors = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_udpInErrors
};

const RTCSMIB_VALUE MIBVALUE_udpOutDatagrams = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_udpOutDatagrams
};

const RTCSMIB_VALUE MIBVALUE_udpLocalAddress = {
    RTCSMIB_NODETYPE_OCTSTR_FN,
    (void _PTR_)(RTCSMIB_OCTSTR_FN_PTR)MIB_get_udpLocalAddress
};

const RTCSMIB_VALUE MIBVALUE_udpLocalPort = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_udpLocalPort
};

const RTCSMIB_VALUE MIBVALUE_udpTable = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_udpEntry = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_transmission = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_snmp = {
    RTCSMIB_NODETYPE_INT_CONST,
    NULL
};

const RTCSMIB_VALUE MIBVALUE_snmpInPkts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInPkts
};

const RTCSMIB_VALUE MIBVALUE_snmpOutPkts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutPkts
};

const RTCSMIB_VALUE MIBVALUE_snmpInBadVersions = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInBadVersions
};

const RTCSMIB_VALUE MIBVALUE_snmpInBadCommunityNames = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInBadCommunityNames
};

const RTCSMIB_VALUE MIBVALUE_snmpInBadCommunityUses = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL  
};

const RTCSMIB_VALUE MIBVALUE_snmpInASNParseErrs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInASNParseErrs
};

const RTCSMIB_VALUE MIBVALUE_snmpInTooBigs = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL  
};

const RTCSMIB_VALUE MIBVALUE_snmpInNoSuchNames = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL  
};

const RTCSMIB_VALUE MIBVALUE_snmpInBadValues = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL  
};

const RTCSMIB_VALUE MIBVALUE_snmpInReadOnlys = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL  
};

const RTCSMIB_VALUE MIBVALUE_snmpInGenErrs = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL  
};

const RTCSMIB_VALUE MIBVALUE_snmpInTotalReqVars = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInTotalReqVars
};

const RTCSMIB_VALUE MIBVALUE_snmpInTotalSetVars = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInTotalSetVars
};

const RTCSMIB_VALUE MIBVALUE_snmpInGetRequests = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInGetRequests
};

const RTCSMIB_VALUE MIBVALUE_snmpInGetNexts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInGetNexts
};

const RTCSMIB_VALUE MIBVALUE_snmpInSetRequests = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInSetRequests
};

const RTCSMIB_VALUE MIBVALUE_snmpInGetResponses = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInGetResponses
};

const RTCSMIB_VALUE MIBVALUE_snmpInTraps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpInTraps
};

const RTCSMIB_VALUE MIBVALUE_snmpOutTooBigs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutTooBigs
};

const RTCSMIB_VALUE MIBVALUE_snmpOutNoSuchNames = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutNoSuchNames
};

const RTCSMIB_VALUE MIBVALUE_snmpOutBadValues = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutBadValues
};

const RTCSMIB_VALUE MIBVALUE_snmpOutGenErrs = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutGenErrs
};

const RTCSMIB_VALUE MIBVALUE_snmpOutGetRequests = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutGetRequests
};

const RTCSMIB_VALUE MIBVALUE_snmpOutGetNexts = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutGetNexts
};

const RTCSMIB_VALUE MIBVALUE_snmpOutSetRequests = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutSetRequests
};

const RTCSMIB_VALUE MIBVALUE_snmpOutGetResponses = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutGetResponses
};

const RTCSMIB_VALUE MIBVALUE_snmpOutTraps = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_snmpOutTraps
};

const RTCSMIB_VALUE MIBVALUE_snmpEnableAuthenTraps = {
    RTCSMIB_NODETYPE_UINT_CONST,
    NULL  
};

const RTCSMIB_VALUE MIBVALUE_ipInDiscards = {
    RTCSMIB_NODETYPE_UINT_FN,
    (void _PTR_)(RTCSMIB_UINT_FN_PTR)MIB_get_ipInDiscards
};

#endif /* RTCSCFG_ENABLE_SNMP  && RTCSCFG_ENABLE_IP4*/

/****************************************************************************/
 
void MIB1213_init(void)
{
#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4
   RTCSMIB_mib_add(&MIBNODE_mib2);
#endif
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Sin.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Sin.h
*
* @author   B04459
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_Sin function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_SIN_H
#define _GFLIB_SIN_H

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*! Function alias for the #GFLIB_SinANSIC function.*/
#define GFLIB_Sin(w32In) GFLIB_SinANSIC(w32In, &gflibSinCoef)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_SINTLR_T "\GFLIB_Sin.h"

@brief      Structure containing one array of five 32-bit elements for storing
            coefficients of a Taylor polynomial.

@details    By calling the function alias #GFLIB_Sin, default values of the coefficients
            are used. Polynomial coefficients can be modified by the user
            and in such a case the full function call shall be used, i.e. #GFLIB_SinANSIC.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32  f32A[5];  /*!< Array of five 32-bit elements for storing coefficients
                            of the Taylor polynomial. */
}GFLIB_SINTLR_T;

/******************************************************************************
* Exported Variables
******************************************************************************/
extern const GFLIB_SINTLR_T gflibSinCoef;

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*!
* @ingroup GFLIB_GROUP
*/
extern Frac32 GFLIB_SinANSIC(Frac32 f32In, const GFLIB_SINTLR_T * const pParam);

/******************************************************************************
* Inline functions
******************************************************************************/

#endif /* _GFLIB_SIN_H */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sdcard/sdcard_spi/sdcard_spi.h<|end_filename|>
#ifndef __sdcard_spi_h__
#define __sdcard_spi_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sdcard_spi.h$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototypes, defines, structure 
*   definitions private to the SD SPI communication.
*
*END************************************************************************/


/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/


#define SDCARD_SPI_RETRIES                 (3000)


#define SDCARD_SPI_START                   (0xFE)
#define SDCARD_SPI_MULTI_START             (0xFC)
#define SDCARD_SPI_MULTI_STOP              (0xFD)
#define SDCARD_SPI_IDLE                    (0xFF)
#define SDCARD_SPI_BUSY                    (0x00)
#define SDCARD_SPI_DATA_RESPONSE_MASK      (0x1F)
#define SDCARD_SPI_DATA_RESPONSE_OK        (0x05)
#define SDCARD_SPI_DATA_ERROR_MASK         (0x0F)
#define SDCARD_SPI_END_BIT                 (0x01)

#define SDCARD_SPI_IF_COND_VHS_MASK        (0x00000F00L)
#define SDCARD_SPI_IF_COND_VHS_27_36       (0x00000100L)

#define SDCARD_SPI_OCR_VOLTAGE_3_3V        (0x00300000L)
#define SDCARD_SPI_OCR_CCS                 (0x40000000L)
#define SDCARD_SPI_OCR_POWER_UP_STATUS     (0x80000000L)

#define SDCARD_SPI_ACMD41_HCS              (0x40000000L)


#define SDCARD_SPI_CMD0_GO_IDLE_STATE      ( 0 | 0x40)
#define SDCARD_SPI_CMD8_SEND_IF_COND       ( 8 | 0x40)
#define SDCARD_SPI_CMD9_SEND_CSD           ( 9 | 0x40)
#define SDCARD_SPI_CMD12_STOP              (12 | 0x40)
#define SDCARD_SPI_CMD13_SEND_STATUS       (13 | 0x40)
#define SDCARD_SPI_CMD16_SET_BLOCKLEN      (16 | 0x40)
#define SDCARD_SPI_CMD17_READ_BLOCK        (17 | 0x40)
#define SDCARD_SPI_CMD18_READ_MULTI_BLOCK  (18 | 0x40)
#define SDCARD_SPI_CMD24_WRITE_BLOCK       (24 | 0x40)
#define SDCARD_SPI_CMD25_WRITE_MULTI_BLOCK (25 | 0x40)
#define SDCARD_SPI_ACMD41_SEND_OP_COND     (41 | 0x40)
#define SDCARD_SPI_CMD55_APP_CMD           (55 | 0x40)
#define SDCARD_SPI_CMD58_READ_OCR          (58 | 0x40)
#define SDCARD_SPI_CMD59_CRC_ON            (59 | 0x40)
#define SDCARD_SPI_ACMD13_SEND_STATUS      SDCARD_SPI_CMD13_SEND_STATUS
#define SDCARD_SPI_ACMD22_SEND_NUM_WR_BLOCKS (22 | 0x40)


#define SDCARD_SPI_R1_IDLE_STATE           (1 << 0)
#define SDCARD_SPI_R1_ERASE_RESET          (1 << 1)
#define SDCARD_SPI_R1_ILLEGAL_CMD          (1 << 2)
#define SDCARD_SPI_R1_CRC_ERROR            (1 << 3)
#define SDCARD_SPI_R1_ERASE_SEQ            (1 << 4)
#define SDCARD_SPI_R1_ADDRESS_ERROR        (1 << 5)
#define SDCARD_SPI_R1_PARAM_ERROR          (1 << 6)
#define SDCARD_SPI_R1_START_MASK           (1 << 7)
#define SDCARD_SPI_R1_ERROR_MASK           (0x7E)


/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/


/* Internal functions to SD SPI communication */
#ifdef __cplusplus
extern "C" {
#endif


extern   boolean _io_sdcard_spi_init(MQX_FILE_PTR);
extern  _mqx_int _io_sdcard_spi_read_block(MQX_FILE_PTR, uchar_ptr, uint_32, uint_32);
extern  _mqx_int _io_sdcard_spi_write_block(MQX_FILE_PTR, uchar_ptr, uint_32, uint_32);


#ifdef __cplusplus
}
#endif


#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lpm/lpm_mc.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*****************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: lpm_mc.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains Low Power Manager functionality specific to Kinetis.
*
*END************************************************************************/


#include "mqx.h"
#include "bsp.h"


#if MQX_ENABLE_LOW_POWER


#ifndef PE_LDD_VERSION


static const LPM_CPU_POWER_MODE LPM_CPU_POWER_MODES_KINETIS[LPM_CPU_POWER_MODES] = 
{
    // Kinetis RUN
    {
        MC_PMCTRL_LPWUI_MASK,                       // Mode PMCTRL register == voltage regulator ON after wakeup
        0,                                          // Mode flags == clear settings
    },
    // Kinetis WAIT
    {
        MC_PMCTRL_LPWUI_MASK,                       // Mode PMCTRL register == voltage regulator ON after wakeup
        LPM_CPU_POWER_MODE_FLAG_USE_WFI,            // Mode flags == execute WFI
    },
    // Kinetis STOP
    {
        MC_PMCTRL_LPWUI_MASK,                       // Mode PMCTRL register == voltage regulator ON after wakeup
        LPM_CPU_POWER_MODE_FLAG_DEEP_SLEEP | LPM_CPU_POWER_MODE_FLAG_USE_WFI,   // Mode flags == deepsleep, execute WFI
    },
    // Kinetis VLPR
    {
        MC_PMCTRL_RUNM(2),                          // Mode PMCTRL register == VLPR
        0,                                          // Mode flags == clear settings
    },
    // Kinetis VLPW
    {
        MC_PMCTRL_RUNM(2),                          // Mode PMCTRL register == VLPW
        LPM_CPU_POWER_MODE_FLAG_USE_WFI,            // Mode flags == execute WFI
    },
    // Kinetis VLPS
    {
        MC_PMCTRL_LPLLSM(2),                        // Mode PMCTRL register == VLPS
        LPM_CPU_POWER_MODE_FLAG_DEEP_SLEEP | LPM_CPU_POWER_MODE_FLAG_USE_WFI,   // Mode flags == deepsleep, execute WFI
    },
    // Kinetis LLS
    {
        MC_PMCTRL_LPWUI_MASK | MC_PMCTRL_LPLLSM(3), // Mode PMCTRL register == voltage regulator ON after wakeup, LLS
        LPM_CPU_POWER_MODE_FLAG_DEEP_SLEEP | LPM_CPU_POWER_MODE_FLAG_USE_WFI,   // Mode flags == deepsleep, execute WFI
    }
};


#else


static const LDD_TDriverOperationMode LPM_PE_OPERATION_MODE_MAP[LPM_OPERATION_MODES] =
{
    DOM_RUN,
    DOM_WAIT,
    DOM_SLEEP,
    DOM_STOP
};


#endif


/*FUNCTION*------------------------------------------------------------------
*
* Function Name    : _lpm_set_cpu_operation_mode
* Returned Value   : MQX error code
* Comments         :
*    This function changes operation mode of the CPU core.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _lpm_set_cpu_operation_mode
    (
        /* [IN] Specification of CPU core low power operation modes available */
        const LPM_CPU_OPERATION_MODE _PTR_ operation_modes,

        /* [IN] Low power operation mode identifier */
        LPM_OPERATION_MODE                 target_mode
    )
{

#ifndef PE_LDD_VERSION

    const LPM_CPU_POWER_MODE _PTR_         mode_ptr;
    _mqx_uint                              scr, flags, mcg, index;

    /* Check parameters */
    if ((NULL == operation_modes) || (LPM_OPERATION_MODES <= (_mqx_uint)target_mode))
    {
        return MQX_INVALID_PARAMETER;
    }
    index = operation_modes[target_mode].MODE_INDEX;

    if (LPM_CPU_POWER_MODES <= index)
    {
        return MQX_INVALID_CONFIGURATION;
    }
    mode_ptr = &(LPM_CPU_POWER_MODES_KINETIS[index]);
    flags = mode_ptr->FLAGS | (operation_modes[target_mode].FLAGS & LPM_CPU_POWER_MODE_FLAG_USER_MASK);

    /* Go through Kinetis Run */
    scr = (SCB_SCR & (~ (SCB_SCR_SLEEPDEEP_MASK | SCB_SCR_SLEEPONEXIT_MASK)));
    SCB_SCR = scr;
    MC_PMCTRL = LPM_CPU_POWER_MODES_KINETIS[LPM_CPU_POWER_MODE_RUN].PMCTRL;
    while (0 == (PMC_REGSC & PMC_REGSC_REGONS_MASK))
        { };

    /* Go to VLPW through VLPR */
    if (LPM_CPU_POWER_MODE_VLPW == index)
    {
        MC_PMCTRL = LPM_CPU_POWER_MODES_KINETIS[LPM_CPU_POWER_MODE_VLPR].PMCTRL;
        while (0 == (PMC_REGSC & PMC_REGSC_VLPRS_MASK))
            { };
    }

    /* Setup ARM System control register */
    if (flags & LPM_CPU_POWER_MODE_FLAG_DEEP_SLEEP)
    {
        scr |= SCB_SCR_SLEEPDEEP_MASK;
    }
    if (flags & LPM_CPU_POWER_MODE_FLAG_SLEEP_ON_EXIT)
    {
        scr |= SCB_SCR_SLEEPONEXIT_MASK;
    }
    SCB_SCR = scr;

    /* Setup wakeup unit for LLS mode */
    if (LPM_CPU_POWER_MODE_LLS == index)
    {

        LLWU_PE1 = operation_modes[target_mode].PE1;
        LLWU_PE2 = operation_modes[target_mode].PE2;
        LLWU_PE3 = operation_modes[target_mode].PE3;
        LLWU_PE4 = operation_modes[target_mode].PE4;
        LLWU_ME = operation_modes[target_mode].ME;
        LLWU_F1 = 0xFF;
        LLWU_F2 = 0xFF;
        LLWU_F3 = 0xFF;
    }
	
    /* Keep status of MCG before mode change */
    mcg = MCG_S & MCG_S_CLKST_MASK;

    /* Operation mode setup */
    MC_PMCTRL = mode_ptr->PMCTRL;

    /* Wait for proper setup of VLPR */
    if (LPM_CPU_POWER_MODE_VLPR == index)
    {

        /* K40 P2.2, K60 P2.2 and K20 P1 use different macro from previous chips */
       while (0 == (PMC_REGSC & PMC_REGSC_VLPRS_MASK))
            { };
    }

    /* Go to sleep if required */
    if (flags & LPM_CPU_POWER_MODE_FLAG_USE_WFI)
    {
        _ASM_SLEEP();
    }

    /* After stop modes, reconfigure MCG if needed */
    if ( (LPM_CPU_POWER_MODE_STOP == index)
      || (LPM_CPU_POWER_MODE_VLPS == index)
      || (LPM_CPU_POWER_MODE_LLS == index) )
    {
        if ((MCG_S_CLKST(3) == mcg) && (MCG_S_CLKST(2) == (MCG_S & MCG_S_CLKST_MASK)))
        {
            MCG_C1 &= (~ (MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK));
            while (0 == (MCG_S & MCG_S_LOCK_MASK))
                { };
        }
    }

    return MQX_OK;

#else

#ifdef Cpu_SetOperationMode_METHOD_ENABLED
    if (LPM_OPERATION_MODES <= (_mqx_uint)target_mode)
    {
        return MQX_INVALID_PARAMETER;
    }
    return Cpu_SetOperationMode (LPM_PE_OPERATION_MODE_MAP[target_mode], NULL, NULL);
#else
    #error Undefined method Cpu_SetOperationMode() in PE CPU component!
#endif

#endif

}

/*FUNCTION*------------------------------------------------------------------
*
* Function Name    : _lpm_wakeup_core
* Returned Value   : None
* Comments         :
*    This function must be called from ISR not to let the core to return to sleep again.
*
*END*----------------------------------------------------------------------*/

void _lpm_wakeup_core
    (
        void
    )
{
    SCB_SCR &= (~ (SCB_SCR_SLEEPONEXIT_MASK));
}


/*FUNCTION*------------------------------------------------------------------
* 
* Function Name    : _lpm_idle_sleep_check
* Returned Value   : TRUE if idle sleep possible, FALSE otherwise
* Comments         :
*    This function checks whether cpu core can sleep during execution of idle task
*    in current power mode. 
*
*END*----------------------------------------------------------------------*/

boolean _lpm_idle_sleep_check
    ( 
        void
    )
{
    _mqx_uint pmctrl, stop;
    
    pmctrl = MC_PMCTRL;
    stop = SCB_SCR & SCB_SCR_SLEEPDEEP_MASK;
    
    /* Idle sleep is available only in normal RUN/WAIT and VLPR/VLPW with LPWUI disabled */
    if ((0 == stop) && (0 == (pmctrl & MC_PMCTRL_LPLLSM_MASK)) && (! ((MC_PMCTRL_LPWUI_MASK | MC_PMCTRL_RUNM(2)) == (pmctrl & (MC_PMCTRL_LPWUI_MASK | MC_PMCTRL_RUNM_MASK)))))
    {
        return TRUE;
    }
    
    return FALSE;
}


#endif


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fung.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fung.c$
* $Version : 3.8.6.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the function for ungetting a character.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Pushes back a character.
 *  
 * Pushed character will be returned on next read. Only 1 pushback character is
 * allowed.
 * 
 * \param[in] character The character to return.
 * \param[in] file_ptr  The stream to push character back to.
 * 
 * \return Pushed back character.
 * \return IO_EOF (Failure.)  
 */ 
_mqx_int _io_fungetc
   (
      _mqx_int     character,
      MQX_FILE_PTR file_ptr
   )
{ /* Body */

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(IO_EOF);
   } /* Endif */
#endif

   if (file_ptr->HAVE_UNGOT_CHARACTER) {
      return(IO_EOF);
   } /* Endif */

   if (character != IO_EOF) {
       /* Clear EOF flag */
       file_ptr->UNGOT_CHARACTER      = character;
       file_ptr->HAVE_UNGOT_CHARACTER = TRUE;
       file_ptr->FLAGS &= ~((_mqx_uint) IO_FLAG_AT_EOF);
   }
   return(character);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/include/khci/khci_dev_main.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: khci_dev_main.h$
* $Version : 3.8.9.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the macros, function prototypes and data structure
*   definitions required by the Full Speed USB Device Controller driver.
*
*END************************************************************************/

#ifndef __khci_dev_main_h__
#define __khci_dev_main_h__

#include "khci_usbprv.h"

#define EP_DISABLE              (0)
#define ASSERT_RESUME_DELAY_COUNT       (8000)/* Delay for assert resume */

#define BYTES_512                 (512)
#define BYTES_1024                (1024)
#define ENDPOINT_NUMBER_SHIFT     (4)   /* endpoint shift & mask to */
#define ENDPOINT_NUMBER_MASK      (0xf0)/* use in setting and getting status */
#define MAX_EP_BUFFER_SIZE        (64)
#define ZERO_LENGTH               (0)
#define USB_SETUP_TOKEN           (0x0d)/* Setup Token PID */
#define FRAME_HIGH_BYTE_SHIFT     (8)

/***************************************
**
** Prototypes
**/
#ifdef __cplusplus
extern "C" {
#endif

USB_STATUS _usb_dci_usbfs_preinit(_usb_device_handle _PTR_);
USB_STATUS _usb_dci_usbfs_init(_usb_device_handle);
USB_STATUS _usb_dci_usbfs_send(_usb_device_handle, XD_STRUCT_PTR);
USB_STATUS _usb_dci_usbfs_recv(_usb_device_handle, XD_STRUCT_PTR);
USB_STATUS _usb_dci_usbfs_cancel(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_dci_usbfs_set_addr(_usb_device_handle, uint_8);
USB_STATUS _usb_dci_usbfs_shutdown(_usb_device_handle);
USB_STATUS _usb_dci_usbfs_get_setup_data(_usb_device_handle, uint_8, uchar_ptr);
USB_STATUS _usb_dci_usbfs_assert_resume(_usb_device_handle);
USB_STATUS _usb_dci_usbfs_init_endpoint(_usb_device_handle, XD_STRUCT_PTR);
USB_STATUS _usb_dci_usbfs_stall_endpoint(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_dci_usbfs_unstall_endpoint(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_dci_usbfs_deinit_endpoint(_usb_device_handle, uint_8, uint_8);
USB_STATUS _usb_dci_usbfs_get_endpoint_status(_usb_device_handle, uint_8, uint_16_ptr);
USB_STATUS _usb_dci_usbfs_set_endpoint_status(_usb_device_handle, uint_8, uint_16);
USB_STATUS _usb_dci_usbfs_get_transfer_status(_usb_device_handle,uint_8,uint_8);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/shmem/pcb_shm.h<|end_filename|>
#ifndef __pcb_shm_h__
#define __pcb_shm_h__
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pcb_shm.h$
* $Version : 3.8.6.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This file contains the definitions for the PCB device driver that
*   sends and receives packets over a asynchrnous serial device.  The
*   packets are in MQX IPC async packet format.
*
*END************************************************************************/

#include "bsp.h"

/*--------------------------------------------------------------------------*/
/*
**                          CONSTANT DECLARATIONS
*/

/*
** Initialization errors
*/
#define IO_PCB_SHM_DEVICE_ALREADY_OPEN         (IO_PCB_ERROR_BASE|0x90)
#define IO_PCB_SHM_INCORRECT_SERIAL_DEVICE     (IO_PCB_ERROR_BASE|0x91)

#if 0
/*
**             PACKET STRUCTURE CONTROL FIELD BIT DEFINITIONS
*/

#define IO_PCB_SHM_HDR_LITTLE_ENDIAN           (0x40)
#define IO_PCB_SHM_DATA_LITTLE_ENDIAN          (0x20)

#define IO_PCB_SHM_HDR_BIG_ENDIAN              (0x00)
#define IO_PCB_SHM_DATA_BIG_ENDIAN             (0x00)
#endif

/*--------------------------------------------------------------------------*/
/*
**                          DATATYPE DECLARATIONS
*/

/*
** IO_PCB_SHM_INIT_STRUCT
** This structure contains the initialization information for the
** async shared memory protocol
**
*/
typedef struct io_pcb_shm_init_struct
{

   /* Shared memory base address */
   pointer    TX_BD_ADDR;

   /* TX ring limit */
   pointer    TX_LIMIT_ADDR;

   /* Shared memory base address */
   pointer    RX_BD_ADDR;

   /* RX ring limit */
   pointer    RX_LIMIT_ADDR;

   /* Maximum size of input packet */
   _mem_size  INPUT_MAX_LENGTH;

   /* interrupt vector */
   uint_32    RX_VECTOR;
   uint_32    TX_VECTOR;
   uint_32    REMOTE_RX_VECTOR;
   uint_32    REMOTE_TX_VECTOR;

   /* The address of function to trigger interrupts */
   void (_CODE_PTR_ INT_TRIGGER)(uint_32);

} IO_PCB_SHM_INIT_STRUCT, _PTR_ IO_PCB_SHM_INIT_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                          C PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern pointer _bsp_vtop(pointer ptr);
extern pointer _bsp_ptov(pointer ptr);

extern _mqx_uint _io_pcb_shm_install(char _PTR_, pointer);
#if BSPCFG_IO_PCB_SHM_SUPPORT
extern void _bsp_io_pcb_shm_int_trigger(uint_32 vector);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/alggen.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: alggen.c$
* $Version : 3.0.2.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the generic NAT ALG code.
*
*END************************************************************************/

#include <rtcs.h>
#include <rtcs_prv.h>
#include <fio.h>
#include <tftp.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"


/* 
** List of function pointers used to free ALG specific data 
** Index into table is ALG_TYPE.
*/
NAT_ALG_FREE_FUNC NAT_alg_free_func_table[] =  {
   NULL,                /* NAT_ALG_TFTP_TYPE */
   RTCS_part_free       /* NAT_ALG_FTP_TYPE */
};

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_init_algs
* Returned Value  : error code
* Comments        :
*        Initializes all of the ALGs in the NAT_alg_table.
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_init_algs
   (
      NAT_CFG_STRUCT_PTR   nat_cfg_ptr     /* [IN] NAT config struct */
   )
{ /* Body */
   NAT_ALG _PTR_           table_ptr = NAT_alg_table;
   NAT_ALG_CFG_STRUCT_PTR  cfg_ptr, next_cfg_ptr;
   uint_32                 error = RTCS_OK;
   
   while ((*table_ptr != NAT_ALG_ENDLIST) && (error==RTCS_OK))  {
      error = (*table_ptr)(nat_cfg_ptr);   
      table_ptr++;   
   } /* Endfor */

   if (error != RTCS_OK)  {
      /* An error occured. Free memory associated with ALGs */
      cfg_ptr = nat_cfg_ptr->ALG_INFO_PTR;
      while (cfg_ptr)  {
         next_cfg_ptr = cfg_ptr->NEXT;     
         _mem_free(cfg_ptr);
         cfg_ptr = next_cfg_ptr;  
      } /* Endwhile */
      
      nat_cfg_ptr->ALG_INFO_PTR = NULL;   
   } /* Endif */

   return error;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : NAT_ALG_TCP_checksum
* Returned Value : void
* Comments       : Clears current value in the checksum field and
*                  recalculates it.
*
*END------------------------------------------------------------------*/

void NAT_ALG_TCP_checksum
   (
      IP_HEADER_PTR    ip_header_ptr    /* [IN]  pointer to IP header */
   )
{ /* Body */
   TRANSPORT_UNION    transport;
   uint_16           checksum;
   uint_16           protocol;
   uint_16           iplen = IPH_LEN(ip_header_ptr);
   uint_16           len = ntohs(ip_header_ptr->LENGTH) - iplen; 
   
   /* Get TCP header */
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);

   htons(transport.TCP_PTR->checksum, 0);    /* Clear checksum field */
   protocol = ntohc(ip_header_ptr->PROTOCOL); /* PROTOCOL */
   checksum = (uint_16) _mem_sum_ip(protocol, 8, ip_header_ptr->SOURCE);  /* IP SRC and DST ADDR */
   checksum = (uint_16) _mem_sum_ip(checksum, len, transport.PTR);

   /* TCP LENGTH */
   checksum = IP_Sum_immediate(checksum, len);
   
   checksum = IP_Sum_invert(checksum);
   htons(transport.TCP_PTR->checksum, checksum);   

} /* Endbody */

#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/core_mutex/core_mutex_sema4.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: core_mutex_sema4.c$
* $Version : 3.8.3.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains the source functions for functions required to
*   control the PBRIDGE.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include <core_mutex.h>
#include <core_mutex_sema4.h>

#define _sema4_int_disable() _int_disable()
#define _sema4_int_enable()  _int_enable()


/*FUNCTION****************************************************************
*
* Function Name    : _sema4_isr
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    This function sets the appropriate access control for the specified
*    register number.
*
*END*********************************************************************/
#if PSP_MQX_CPU_IS_VYBRID
static const int idx[16] = {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12};
#else
static const int idx[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
#endif

static void _sema4_isr(pointer p)
{
    CORE_MUTEX_DEVICE_PTR   device_ptr = (CORE_MUTEX_DEVICE_PTR) p;
    uint_32                 i;
    vuchar_ptr              gate_ptr;
    uchar                   lock = _psp_core_num()+1;
    uint_16                 mask = 0x8000;
    boolean                 waiting;

    for (i=0;i<SEMA4_NUM_GATES;i++) {
        if (*device_ptr->CPNTF_PTR & mask ) {
            // An interrupt is pending on this mutex, the only way to clear it is to lock it (either
            // by this core or another)
            gate_ptr = device_ptr->MUTEX_PTR[idx[i]]->GATE_PTR;
            *gate_ptr = lock;
            if (*gate_ptr == lock) {
                // Now, check to see if any task is waiting for it
                waiting = FALSE;
                if (device_ptr->MUTEX_PTR[idx[i]]) {
                    if (_taskq_get_value(device_ptr->MUTEX_PTR[idx[i]]->WAIT_Q)) {
                        _taskq_resume(device_ptr->MUTEX_PTR[idx[i]]->WAIT_Q, FALSE);
                        waiting = TRUE;
                    }
                }
                if (!waiting) {
                    // No task was waiting, give it back - this can occur due to a failed trylock
                    *gate_ptr = SEMA4_UNLOCK;
                }
            }
        }
        mask >>= 1;
   }
}

/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_install
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    This function sets the appropriate access control for the specified
*    register number.
*
*END*********************************************************************/

uint_32 _core_mutex_install( const CORE_MUTEX_INIT_STRUCT *init_ptr )
{
   CORE_MUTEX_COMPONENT_PTR   component_ptr = _core_mutext_get_component_ptr();
   PSP_INTERRUPT_TABLE_INDEX  vector;
   uint_32                    i;

#if MQX_CHECK_ERRORS
   if (component_ptr!=NULL) {
      return MQX_COMPONENT_EXISTS;
   }
#endif

   component_ptr = _mem_alloc_system_zero(sizeof(*component_ptr));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (component_ptr==NULL) {
       return MQX_OUT_OF_MEMORY;
   }
#endif

   for (i=0;i<SEMA4_NUM_DEVICES;i++) {
       vector = _bsp_get_sema4_vector(i);
       component_ptr->DEVICE[i].SEMA4_PTR = _bsp_get_sema4_base_address(i);
       if (_psp_core_num()==0) {
           component_ptr->DEVICE[i].CPNTF_PTR = &(component_ptr->DEVICE[i].SEMA4_PTR->CP0NTF);
       } else {
           component_ptr->DEVICE[i].CPNTF_PTR = &(component_ptr->DEVICE[i].SEMA4_PTR->CP1NTF);
       }
#if MQX_CHECK_ERRORS
       if ((component_ptr->DEVICE[i].SEMA4_PTR == NULL) || (vector==0)) {
           _mem_free(component_ptr);
           return MQX_INVALID_DEVICE;
       }
#endif
   }

   _int_disable();
#if MQX_CHECK_ERRORS
   if (_core_mutext_get_component_ptr()) {
       _int_enable();
       _mem_free(component_ptr);
       return MQX_COMPONENT_EXISTS;
   }
#endif

   _core_mutext_set_component_ptr(component_ptr);
   _int_enable();


   for (i=0;i<SEMA4_NUM_DEVICES;i++) {
       vector = _bsp_get_sema4_vector(i);
       _int_install_isr(vector, _sema4_isr, &component_ptr->DEVICE[i]);
       _bsp_int_init(vector, init_ptr->INT_PRIORITY, 0, TRUE);
   }

   return COREMUTEX_OK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_create_internal
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    This function creates a core mutex at the specified location.
*
*END*********************************************************************/

uint_32 _core_mutex_create_internal(CORE_MUTEX_PTR mutex_ptr, uint_32 core_num, uint_32 mutex_num, uint_32 policy, boolean allocated )
{
    CORE_MUTEX_COMPONENT_PTR component_ptr = _core_mutext_get_component_ptr();

#if MQX_CHECK_ERRORS
    if (component_ptr == NULL) {
        return MQX_COMPONENT_DOES_NOT_EXIST;
    }

    // range check mutex_id
    if (mutex_num>=SEMA4_NUM_GATES) {
        return (MQX_INVALID_PARAMETER);
    }

    if (core_num>=PSP_NUM_CORES) {
        return (MQX_INVALID_PARAMETER);
    }

    if (mutex_ptr==NULL) {
        return MQX_INVALID_PARAMETER;
    }
#endif

    mutex_ptr->VALID    = CORE_MUTEX_VALID;
    mutex_ptr->GATE_NUM = mutex_num;
    mutex_ptr->GATE_PTR = &(component_ptr->DEVICE[core_num].SEMA4_PTR->GATE[mutex_ptr->GATE_NUM]);
    mutex_ptr->WAIT_Q   = _taskq_create(policy);
#if MQX_CHECK_ERRORS
    if (mutex_ptr->WAIT_Q==NULL) {
        return MQX_TASKQ_CREATE_FAILED;
    }
#endif

    _int_disable();
#if MQX_CHECK_ERRORS
    if (component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num] !=NULL) {
        _int_enable();
        _taskq_destroy(mutex_ptr->WAIT_Q);
        return MQX_COMPONENT_EXISTS;
    }
#endif
    component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num]=mutex_ptr;

    // Need to remember if we allocated this mutex, or user did
    if (allocated) {
       component_ptr->DEVICE[core_num].ALLOCED |= (1<<mutex_num);
    }

    // Enable 'unlocked' interrupt for this core
    if (_psp_core_num()==0) {
        component_ptr->DEVICE[core_num].SEMA4_PTR->CP0INE |= 1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]);	//1 << (SEMA4_NUM_GATES-1-mutex_num);
    } else {
        component_ptr->DEVICE[core_num].SEMA4_PTR->CP1INE |= 1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]);	//1 << (SEMA4_NUM_GATES-1-mutex_num);
    }
    _int_enable();

    return COREMUTEX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_create
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    This function allocates and creates a core mutex.
*
*END*********************************************************************/

CORE_MUTEX_PTR _core_mutex_create(uint_32 core_num, uint_32 mutex_num, uint_32 policy )
{
    CORE_MUTEX_PTR mutex_ptr;
    uint_32        result;

    mutex_ptr = _mem_alloc_system_zero(sizeof(*mutex_ptr));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (mutex_ptr==NULL) {
        _task_set_error(MQX_OUT_OF_MEMORY);
        return NULL;
    }
#endif

    result = _core_mutex_create_internal(mutex_ptr, core_num, mutex_num, policy, TRUE );
#if MQX_CHECK_ERRORS
    if (result != COREMUTEX_OK) {
        _mem_free(mutex_ptr);
        _task_set_error(result);
        mutex_ptr = NULL;
    }
#endif
    return mutex_ptr;
}


/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_create_at
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    This function creates a core mutex at the specified location.
*
*END*********************************************************************/


uint_32 _core_mutex_create_at( CORE_MUTEX_PTR mutex_ptr, uint_32 core_num, uint_32 mutex_num, uint_32 policy )
{
#if MQX_CHECK_ERRORS
    if (mutex_ptr==NULL) {
        return MQX_INVALID_PARAMETER;
    }
#endif

    return _core_mutex_create_internal(mutex_ptr, core_num, mutex_num, policy, FALSE );
}

/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_destroy
* Returned Value   : MQX error code
* Comments         :
*    This function creates a core mutex at the specified location.
*
*END*********************************************************************/


uint_32 _core_mutex_destroy( CORE_MUTEX_PTR mutex_ptr )
{
    CORE_MUTEX_COMPONENT_PTR    component_ptr = _core_mutext_get_component_ptr();
    SEMA4_MemMapPtr sema4_ptr;
    pointer                     tq;
    uint_32                     core_num, mutex_num,i;

#if MQX_CHECK_ERRORS
    if (component_ptr == NULL) {
       return MQX_COMPONENT_DOES_NOT_EXIST;
    }

    if (mutex_ptr==NULL) {
        return MQX_INVALID_POINTER;
    }

    if (mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    mutex_num = mutex_ptr->GATE_NUM;

    // figure out which device this mutex is associated with
    for (i=0;i<SEMA4_NUM_DEVICES;i++) {
        sema4_ptr = _bsp_get_sema4_base_address(i);
        if (&sema4_ptr->GATE[mutex_num] == mutex_ptr->GATE_PTR) {
            core_num = i;
            break;
        }
    }

    _int_disable();
#if MQX_CHECK_ERRORS
    if (component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num] == NULL) {
       _int_enable();
       return MQX_COMPONENT_DOES_NOT_EXIST;
    }
#endif

    component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num] = NULL;

    if (_psp_core_num()==0) {
        component_ptr->DEVICE[core_num].SEMA4_PTR->CP0INE &= ~(1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]));	//~(1 << (SEMA4_NUM_GATES-1-mutex_num));
    } else {
        component_ptr->DEVICE[core_num].SEMA4_PTR->CP1INE &= ~(1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]));	//~(1 << (SEMA4_NUM_GATES-1-mutex_num));
    }
    tq = mutex_ptr->WAIT_Q;
    mutex_ptr->VALID=0;
    _int_enable();

    if (component_ptr->DEVICE[core_num].ALLOCED & (1<<mutex_num)) {
        component_ptr->DEVICE[core_num].ALLOCED &=  ~(1<<mutex_num);
    } else {
        mutex_ptr=NULL;
    }
    _taskq_destroy(tq);
    if (mutex_ptr) {
        _mem_free(mutex_ptr);
    }

    return COREMUTEX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_get
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    This function sets the appropriate access control for the specified
*    register number.
*
*END*********************************************************************/

CORE_MUTEX_PTR _core_mutex_get(uint_32 core_num, uint_32 mutex_num )
{
   CORE_MUTEX_COMPONENT_PTR component_ptr = _core_mutext_get_component_ptr();
#if MQX_CHECK_ERRORS
   if (component_ptr == NULL) {
      _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
      return NULL;
   }

   if (mutex_num>=SEMA4_NUM_GATES) {
      _task_set_error(MQX_INVALID_PARAMETER);
      return NULL;
   }

   if (core_num>=PSP_NUM_CORES) {
      _task_set_error(MQX_INVALID_PARAMETER);
      return NULL;
   }
#endif
   return component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num];
}


/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_lock
* Returned Value   : COREMUTEX_OK if successful, error code otherwise
* Comments         :
*    This function locks the specified core mutex.
*
*END*********************************************************************/

uint_32 _core_mutex_lock( CORE_MUTEX_PTR core_mutex_ptr )
{
    uchar lock = _psp_core_num()+1;
#if MQX_CHECK_ERRORS
    if (core_mutex_ptr == NULL) {
        return MQX_INVALID_POINTER;
    }

    if (core_mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    _sema4_int_disable();
#if BSPCFG_CORE_MUTEX_STATS
    core_mutex_ptr->LOCKS++;
#endif

    // Check to see if this core already own it
    if (*core_mutex_ptr->GATE_PTR == lock) {
        // Yes, then we have to wait for owning task to release it
        #if BSPCFG_CORE_MUTEX_STATS
            core_mutex_ptr->WAITS++;
        #endif
        _taskq_suspend(core_mutex_ptr->WAIT_Q);

    } else {
        // can only try to lock the mutex if another task is not waiting  otherwise we need to get in line
        if (_taskq_get_value(core_mutex_ptr->WAIT_Q)==0) {
            *core_mutex_ptr->GATE_PTR = lock;
        }
        if (*core_mutex_ptr->GATE_PTR != lock) {
            #if BSPCFG_CORE_MUTEX_STATS
                core_mutex_ptr->WAITS++;
            #endif
            _taskq_suspend(core_mutex_ptr->WAIT_Q);
            // Our turn now
        }
    }
    _sema4_int_enable();

    return COREMUTEX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_trylock
* Returned Value   : COREMUTEX_LOCKED if locked, COREMUTEX_UNLOCKED if unlocked
* Comments         :
*    This function tries to lock the specified core mutex.
*
*END*********************************************************************/

uint_32 _core_mutex_trylock( CORE_MUTEX_PTR core_mutex_ptr )
{
    vuchar_ptr  gate_ptr;
    uchar       lock = _psp_core_num()+1;
    boolean     locked = FALSE;

#if MQX_CHECK_ERRORS
    if (core_mutex_ptr == NULL) {
        return MQX_INVALID_POINTER;
    }

    if (core_mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    gate_ptr = core_mutex_ptr->GATE_PTR;

    _sema4_int_disable();
    // If any other task is pending on the semaphore, then it's already locked
    if (_taskq_get_value(core_mutex_ptr->WAIT_Q)==0) {
        // Or if it's not unlocked...
        if (*gate_ptr == SEMA4_UNLOCK) {
            *gate_ptr = lock;
            // double check to ensure another core didn't lock it before we could
            locked = (*gate_ptr == lock);
        }
    }
    _sema4_int_enable();

    if(locked) {
        return COREMUTEX_LOCKED;
    }
    else {
        return COREMUTEX_UNLOCKED;
    }
}


/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_unlock
* Returned Value   : COREMUTEX_OK if successful, error code otherwise
* Comments         :
*    This function unlocks a core mutex.
*
*END*********************************************************************/

uint_32 _core_mutex_unlock( CORE_MUTEX_PTR core_mutex_ptr )
{
    uchar lock = _psp_core_num()+1;
    vuchar_ptr gate_ptr;

#if MQX_CHECK_ERRORS
    if (core_mutex_ptr == NULL) {
        return MQX_INVALID_POINTER;
    }

    if (core_mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    gate_ptr = core_mutex_ptr->GATE_PTR;

    // Make sure it is locked by this core
    if ( *gate_ptr != lock) {
        return MQX_NOT_RESOURCE_OWNER;
    }

#if BSPCFG_CORE_MUTEX_STATS
    core_mutex_ptr->UNLOCKS++;
#endif

    // Unlock if
    *gate_ptr = SEMA4_UNLOCK;


    // See if this core has any other tasks waiting for this lock
    if (_taskq_get_value(core_mutex_ptr->WAIT_Q)) {

        // if so, have to queue the next request
        _sema4_int_disable();
        *gate_ptr = lock;
        if (*gate_ptr == lock) {
            // if we got it, wake up the next task
            _taskq_resume(core_mutex_ptr->WAIT_Q, FALSE);
        }
        _sema4_int_enable();
    }

    return COREMUTEX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _core_mutex_owner
* Returned Value   : core id of mutex owner, -1 if no owner
* Comments         :
*
*END*********************************************************************/

int_32 _core_mutex_owner( CORE_MUTEX_PTR core_mutex_ptr )
{
#if MQX_CHECK_ERRORS
    if (core_mutex_ptr == NULL) {
        return MQX_INVALID_POINTER;
    }

    if (core_mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    return *core_mutex_ptr->GATE_PTR - 1;
}


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/msd/usb_host_msd_bo.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_msd_bo.c$
* $Version : 3.8.19.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   Implementation of mass storage class specification.
*
*END************************************************************************/
#include "usb_host_msd_bo.h"

/* Linked list of instances of mass storage interfaces */
static USB_MASS_CLASS_INTF_STRUCT_PTR mass_anchor = NULL;

/* Private functions */
static void usb_class_mass_call_back_cbw(pointer, pointer, uchar_ptr, uint_32, USB_STATUS);
static void usb_class_mass_call_back_dphase(pointer, pointer, uchar_ptr, uint_32, USB_STATUS);
static void usb_class_mass_call_back_csw(pointer, pointer, uchar_ptr, uint_32, USB_STATUS);
static void usb_class_mass_reset_callback(_usb_pipe_handle, pointer, uchar_ptr, uint_32, USB_STATUS);
static USB_STATUS usb_class_mass_pass_on_usb(USB_MASS_CLASS_INTF_STRUCT_PTR);
static USB_STATUS usb_class_mass_clear_bulk_pipe_on_usb(USB_MASS_CLASS_INTF_STRUCT_PTR);


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_init
* Returned Value : None
* Comments       :
*     This function initializes the mass storage class
*
*END*--------------------------------------------------------------------*/

void usb_class_mass_init
   (
      /* [IN] structure with USB pipe information on the interface */
      PIPE_BUNDLE_STRUCT_PTR      pbs_ptr,

      /* [IN] printer call struct pointer */
      CLASS_CALL_STRUCT_PTR       ccs_ptr
   )
{ /* Body */
   USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr = ccs_ptr->class_intf_handle;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_init");
   #endif

   USB_lock(); //not needed as init is called from "already locked" function

   /* Pointer validity-checking, clear memory, init header of intf_ptr */
   if (USB_OK != usb_host_class_intf_init(pbs_ptr, intf_ptr, &mass_anchor, NULL)) 
   {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_init");
      #endif
      return;
   }

   ccs_ptr->code_key = 0;
   ccs_ptr->code_key = usb_host_class_intf_validate( ccs_ptr );

   /* Start filling up the members of interface handle (general class already filled) */
   intf_ptr->CONTROL_PIPE = usb_hostdev_get_pipe_handle(pbs_ptr,
      USB_CONTROL_PIPE, 0);
   intf_ptr->BULK_IN_PIPE = usb_hostdev_get_pipe_handle(pbs_ptr,
      USB_BULK_PIPE, USB_RECV);
   intf_ptr->BULK_OUT_PIPE = usb_hostdev_get_pipe_handle(pbs_ptr,
      USB_BULK_PIPE, USB_SEND);

   if (intf_ptr->CONTROL_PIPE    &&
      intf_ptr->BULK_IN_PIPE     &&
      intf_ptr->BULK_OUT_PIPE)  
   {
      /* Initialize the queue for storing the local copy of interface handles */
      usb_class_mass_q_init(intf_ptr);

      /* Store application handle */
      intf_ptr->APP = ccs_ptr;

      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_init, SUCCESSFULL");
      #endif
      
      return;
   } /* Endif */

Bad_Exit:
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_init, bad exit");
   #endif
   USB_mem_zero(intf_ptr, sizeof(USB_MASS_CLASS_INTF_STRUCT_PTR));
   ccs_ptr->class_intf_handle = NULL;
   ccs_ptr->code_key = 0;
   USB_unlock();
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_get_app
* Returned Value : CLASS_CALL_STRUCT_PTR if class found
* Comments       :
*     This function returns stored application handle as it was passed as
*     a param in select_interface.
*
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_mass_get_app
   (
      /* [IN] handle of device */
      _usb_device_instance_handle dev_ptr,

      /* [IN] pointer to interface descriptor */
      _usb_interface_descriptor_handle intf_ptr,

      /* [OUT] pointer to CLASS_CALL_STRUCT to be filled in */
      CLASS_CALL_STRUCT_PTR   _PTR_ ccs_ptr
   )
{
    USB_STATUS                    error;
    GENERAL_CLASS_PTR             parser;

    USB_lock();
 
    error = usb_hostdev_validate (dev_ptr);
    if (error != USB_OK) {
        USB_unlock();
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_class_hub_get_app, FAILED");
        #endif
        return USB_log_error(__FILE__,__LINE__,error);
    } /* EndIf */
    
    for (parser = (GENERAL_CLASS_PTR) mass_anchor; parser != NULL; parser = parser->next) {
        if (parser->dev_handle == dev_ptr && parser->intf_handle == intf_ptr)
            break;
    }
    
    if (parser != NULL) {
        USB_MASS_CLASS_INTF_STRUCT_PTR msd = (USB_MASS_CLASS_INTF_STRUCT_PTR) parser;
        *ccs_ptr = msd->APP;
    }
    else {
        USB_unlock();
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_class_mass_get_app, not found");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_NOT_FOUND);
    }
    
    USB_unlock();
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_mass_get_app, SUCCESSFUL");
    #endif
    return USB_OK;
    
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_mass_storage_device_command
* Returned Value : ERROR STATUS error code
*                  USB_OK - means that command has been succefully queued in class
*                  driver queue (or has been passed to USB, if there is not other
*                  command pending)
* Comments       :
*     This routine is called by the protocol layer to execute the command
*     defined in protocol API. It can also be directly called by a user
*     application if they wish to make their own commands (vendor specific) for
*     sending to a mass storage device.
END*--------------------------------------------------------------------*/

USB_STATUS usb_class_mass_storage_device_command
   (
      /* Handle to class struct with the key */
      CLASS_CALL_STRUCT_PTR      ccs_ptr,

      /*Command */
      COMMAND_OBJECT_PTR         cmd_ptr
   )
{ /* Body */
   USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr;
   int                              temp;
   USB_STATUS                       error = USBERR_NO_INTERFACE;
   CBW_STRUCT_PTR                   pCbw = (CBW_STRUCT_PTR) cmd_ptr->CBW_PTR;
   boolean                          empty;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_storage_device_command");
   #endif
   
   /* Pointer validity-checking, clear memory, init header */
   USB_lock();
   if (usb_host_class_intf_validate(ccs_ptr)) {
      intf_ptr = (USB_MASS_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle;
      error = usb_hostdev_validate (intf_ptr->G.dev_handle);
   } /* Endif */

   if ((error == USB_OK) || (error == USB_STATUS_TRANSFER_QUEUED)) {
      /* Fill in the remaining CBW fields as per the USB Mass Storage specs */
      *(uint_32_ptr)pCbw->DCBWSIGNATURE = HOST_TO_LE_LONG_CONST(CBW_SIGNATURE);

      /* CBW is ready so queue it and update status */
      empty = USB_CLASS_MASS_IS_Q_EMPTY(intf_ptr);
      temp = usb_class_mass_q_insert(intf_ptr, cmd_ptr);
      if (temp >= 0) {
         cmd_ptr->STATUS = STATUS_QUEUED_IN_DRIVER;
         
         /* The tag for the command packet is its queue number. */
         *(uint_32_ptr)pCbw->DCBWTAG = HOST_TO_LE_LONG(temp);

         /*
         ** If queue was empty send CBW to USB immediately, otherwise it will be
         ** taken from queue later by a callback function
         */
         if (empty) {
            error = usb_class_mass_pass_on_usb(intf_ptr);
         } /* Endif */
      } else {
         error = (USB_STATUS)USB_MASS_QUEUE_FULL;
      } /* Endif */
   } /* Endif */
   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_storage_device_command, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,error);
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_storage_device_command_cancel
* Returned Value : ERROR STATUS error code
*                  USB_OK - means that command has been succefullyde queued in class
*                  driver queue 

* Comments       :
END*--------------------------------------------------------------------*/

boolean usb_class_mass_storage_device_command_cancel
   (
      /* Handle to class struct with the key */
      CLASS_CALL_STRUCT_PTR      ccs_ptr,

      /*Command */
      COMMAND_OBJECT_PTR         cmd_ptr
   )
{ /* Body */
   USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr;
   USB_STATUS                       error = USBERR_NO_INTERFACE;
   boolean                          result = FALSE;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_storage_device_command_cancel");
   #endif
   
   /* Pointer validity-checking, clear memory, init header */
   USB_lock();
   if (usb_host_class_intf_validate(ccs_ptr)) {
      intf_ptr = (USB_MASS_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle;
      error = usb_hostdev_validate (intf_ptr->G.dev_handle);
   } /* Endif */

   if ((error == USB_OK) || (error == USB_STATUS_TRANSFER_QUEUED)) {
      result = usb_class_mass_cancelq(intf_ptr, cmd_ptr);
   }
   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_storage_device_command_cancel, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,result);
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_call_back_cbw
* Returned Value : None
* Comments       :
*     This routine is called when the CBW phase of the currently pending command
*     has finished.
*
*END*--------------------------------------------------------------------*/

void usb_class_mass_call_back_cbw
   (
      /* [IN] Pipe on which CBW call was made */
      _usb_pipe_handle pipe_handle,

      /* [IN] Pointer to the class instance */
      pointer          user_parm,

      /* [IN] Pointer to data buffer */
      uchar_ptr        buffer,

      /* [IN] Length of data transfered */
      uint_32          length_data_transfered,

      /* [IN] Status of the transfer */
      USB_STATUS       status
   )
{ /* Body */
   USB_MASS_CLASS_INTF_STRUCT_PTR   plocal_intf;
   COMMAND_OBJECT_PTR               cmd_ptr = NULL;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_cbw");
   #endif

   if (user_parm) {
      /* Get the pointer to the pending request */
      plocal_intf = (USB_MASS_CLASS_INTF_STRUCT_PTR)user_parm;
      usb_class_mass_get_pending_request(plocal_intf, &cmd_ptr);
   } /* Endif */

   /* If there is no user_parm or cmd_ptr we return */
   if (!cmd_ptr) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_call_back_cbw, bad parameter");
      #endif
      return;
   } /* Endif */

   /* Check status of CBW phase and go to the next phase (Data or Status) */
   if (status == USB_OK || status == USB_STATUS_TRANSFER_QUEUED) {
      /* Verify if the length of the data transferred was correct */
      if (length_data_transfered != CBW_SIZE) {
         if (cmd_ptr->RETRY_COUNT < MAX_RETRIAL_ATTEMPTS) {
            cmd_ptr->RETRY_COUNT++;
            cmd_ptr->STATUS = STATUS_QUEUED_IN_DRIVER;
            cmd_ptr->PREV_STATUS =  cmd_ptr->STATUS; /* preserve the status */
            status = usb_class_mass_reset_recovery_on_usb(plocal_intf);
         } else {
            status = STATUS_CANCELLED; /* cannot keep repeating */
         } /* Endif */
      } else {
         /* Everything is normal, go to next phase of pending request */
         cmd_ptr->STATUS = STATUS_FINISHED_CBW_ON_USB;
         status = usb_class_mass_pass_on_usb(plocal_intf);
      } /* Endif */
   } /* Endif */

   if ((status != USB_OK) && (status != USBERR_TRANSFER_IN_PROGRESS) && (status != USB_STATUS_TRANSFER_QUEUED)) {
      /*
      ** Host must do a reset recovery for the device as per the spec. We also
      ** notify the application of the failure, remove the command from the
      ** queue and move on the the next command queued
      */
      cmd_ptr->STATUS = STATUS_CANCELLED;
      cmd_ptr->CALLBACK((USB_STATUS)USB_MASS_FAILED_IN_COMMAND, plocal_intf, cmd_ptr,
         cmd_ptr->TR_BUF_LEN);
      usb_class_mass_deleteq(plocal_intf);
      status = usb_class_mass_pass_on_usb(plocal_intf);
   } /* Endif */
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_cbw, SUCCESSFUL");
   #endif
   
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_call_back_dphase
* Returned Value : None
* Comments       :
*     This routine is called by the bus driver when the data phase completes.
*     If status is USB_OK, this routine will pass on the next routine called
*     usb_class_mass_pass_on_usb() which will queue the status phase. If failure
*     the routine will either try to dequeue the packet, or send a Reset device
*     command or will try to requeue the packet for next phase.
*
*END*--------------------------------------------------------------------*/

void usb_class_mass_call_back_dphase
   (
      /* [IN] Pipe on which CBW call was made */
      _usb_pipe_handle pipe_handle,

      /* [IN] Pointer to the class instance */
      pointer          user_parm,

      /* [IN] Pointer to data buffer */
      uchar_ptr        buffer,

      /* [IN] Length of data transfered */
      uint_32          length_data_transfered,

      /* [IN] Status of the transfer */
      USB_STATUS       status
   )
{ /* Body */
   USB_MASS_CLASS_INTF_STRUCT_PTR   plocal_intf;
   COMMAND_OBJECT_PTR               cmd_ptr = NULL;
   USB_STATUS                       return_code;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_dphase");
   #endif

   if (user_parm) {
      /* Get the pointer to the pending request */
      plocal_intf = (USB_MASS_CLASS_INTF_STRUCT_PTR) user_parm;
      usb_class_mass_get_pending_request(plocal_intf, &cmd_ptr);
   } /* Endif */

   if (!cmd_ptr) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_call_back_dphase, bad parameter");
      #endif
      return;
   } /* Endif */

   /* Save length transferred during data phase */
   cmd_ptr->TR_BUF_LEN = length_data_transfered;

   /* Test if full or partial data received */
   if (status == USB_OK || status == USB_STATUS_TRANSFER_QUEUED ||
      ((status == USBERR_TR_FAILED) && (buffer != NULL)))
   {
      /* Everything is OK, update status and go to next phase */
      cmd_ptr->STATUS = STATUS_FINISHED_DPHASE_ON_USB;
      status = usb_class_mass_pass_on_usb(plocal_intf);

   } else if (status == USBERR_ENDPOINT_STALLED) {

      if (cmd_ptr->RETRY_COUNT < MAX_RETRIAL_ATTEMPTS) {
         cmd_ptr->RETRY_COUNT++;
         //cmd_ptr->STATUS = STATUS_QUEUED_IN_DRIVER; /* this is redundant as clearing pipe will change the status */
         cmd_ptr->PREV_STATUS = STATUS_QUEUED_IN_DRIVER; /* preserve the status */

         return_code = usb_class_mass_clear_bulk_pipe_on_usb(plocal_intf);
         
         if (return_code != USB_OK && return_code != USB_STATUS_TRANSFER_QUEUED) {
            status = STATUS_CANCELLED;
         }
         else {
            cmd_ptr->PREV_STATUS = STATUS_FINISHED_DPHASE_ON_USB; /* Force the returning status from pipe clear to continue after data phase */
            status = usb_class_mass_pass_on_usb(plocal_intf);
         }
      } else {
         //cmd_ptr->STATUS = STATUS_FINISHED_DPHASE_ON_USB; /* this is redundant as clearing pipe will change the status */
         cmd_ptr->PREV_STATUS =  STATUS_FINISHED_DPHASE_ON_USB; /* preserve the status */

         return_code = usb_class_mass_clear_bulk_pipe_on_usb(plocal_intf);
         
         if (return_code != USB_OK && return_code != USB_STATUS_TRANSFER_QUEUED)
         {
            status = STATUS_CANCELLED;
         }
      } /* Endif */
   } /* Endif */

   if ((status != USB_OK) && (status != USBERR_ENDPOINT_STALLED) &&
      (status != USBERR_TRANSFER_IN_PROGRESS) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      /* Command didn't succeed. Notify application and cleanup */
      cmd_ptr->STATUS =STATUS_CANCELLED;
      cmd_ptr->CALLBACK((USB_STATUS)USB_MASS_FAILED_IN_DATA, plocal_intf, cmd_ptr,
         cmd_ptr->TR_BUF_LEN);
      usb_class_mass_deleteq(plocal_intf);

      /* Go to the next command, if any */
      status = usb_class_mass_pass_on_usb(plocal_intf);
   } /* Endif */
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_dphase, SUCCESSFUL");
   #endif
   
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_call_back_csw
* Returned Value : None
* Comments       : This routine is called by the bus driver when the
*      status phase completes on mass storage device. Please see the specs of
*      USB storage device to check what actions should be taken depending upon
*      the status returned by the device.
*
*END*--------------------------------------------------------------------*/

void usb_class_mass_call_back_csw
   (
      /* [IN] Pipe on which CBW call was made */
      _usb_pipe_handle pipe_handle,

      /* [IN] Pointer to the class instance */
      pointer          user_parm,

      /* [IN] Pointer to data buffer */
      uchar_ptr        buffer,

      /* [IN] Length of data transfered */
      uint_32          length_data_transfered,

      /* [IN] Status of the transfer */
      USB_STATUS       status
   )
{ /* Body */
   USB_MASS_CLASS_INTF_STRUCT_PTR   plocal_intf = NULL;
   COMMAND_OBJECT_PTR               cmd_ptr = NULL;
   CSW_STRUCT_PTR                   pCsw = NULL;
   uint_32                          tmp1, tmp2, tmp3;
   boolean                          proc_next = FALSE;
   USB_STATUS                       return_code;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_csw");
   #endif

   if (user_parm) {
      /* Get the pointer to the pending request */
      plocal_intf = (USB_MASS_CLASS_INTF_STRUCT_PTR) user_parm;
      usb_class_mass_get_pending_request(plocal_intf, &cmd_ptr);
   } /* Endif */

   if (cmd_ptr == NULL) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_call_back_csw, bad param");
      #endif
      return;
   } /* Endif */

   /* Finish transaction and queue next command */
   if (status == USB_OK) {
      pCsw = (CSW_STRUCT_PTR) cmd_ptr->CSW_PTR;
      tmp1 = LONG_UNALIGNED_LE_TO_HOST(pCsw->DCSWTAG);
      tmp2 = LONG_UNALIGNED_LE_TO_HOST(cmd_ptr->CBW_PTR->DCBWTAG);
      tmp3 = LONG_UNALIGNED_LE_TO_HOST(pCsw->DCSWSIGNATURE);

      /* Size must be verified, as well as the signature and the tags */
      if ((length_data_transfered != sizeof(CSW_STRUCT)) ||
         (tmp3 != CSW_SIGNATURE) || (tmp1 != tmp2))
      {
         if (cmd_ptr->RETRY_COUNT < MAX_RETRIAL_ATTEMPTS) {
            cmd_ptr->RETRY_COUNT++;
            //cmd_ptr->STATUS = STATUS_FINISHED_DPHASE_ON_USB; /* this is redundant as reseting will change the status */
            cmd_ptr->PREV_STATUS = STATUS_FINISHED_DPHASE_ON_USB; /* preserve the status */

            status = usb_class_mass_reset_recovery_on_usb(plocal_intf);
         } else {
            status = STATUS_CANCELLED; /* cannot keep repeating */
         } /* Endif */

         if ((status != USB_OK)  && (status != USBERR_TRANSFER_IN_PROGRESS) &&
             (status != USB_STATUS_TRANSFER_QUEUED))
         {
            proc_next = TRUE;
         } /* Endif */
      } else {
         /* Check value of status field in CSW */
         switch (pCsw->BCSWSTATUS) {
            case CSW_STATUS_GOOD:
               /* Command succeed. Notify application and cleanup */
               cmd_ptr->STATUS = STATUS_COMPLETED;
               proc_next = TRUE;
               break;

            case CSW_STATUS_FAILED:
               /* Command failed. Notify application and cleanup */
               cmd_ptr->STATUS = STATUS_FAILED_IN_CSW;
               proc_next = TRUE;
               break;

            default:
               break;
         } /* Endswitch */
      } /* Endif */
   }
   else if (status == USBERR_ENDPOINT_STALLED) {
      if (cmd_ptr->RETRY_COUNT < MAX_RETRIAL_ATTEMPTS) {
         cmd_ptr->RETRY_COUNT++;
         //cmd_ptr->STATUS = STATUS_FINISHED_DPHASE_ON_USB;  /* this is redundant as clearing pipe will change the status */
         cmd_ptr->PREV_STATUS = STATUS_FINISHED_DPHASE_ON_USB; /* preserve the status */

         return_code = usb_class_mass_clear_bulk_pipe_on_usb(plocal_intf);
         
         if (return_code != USB_OK && return_code != USB_STATUS_TRANSFER_QUEUED)
         {
            status = USBERR_TRANSFER_IN_PROGRESS;
         }
      } else {
         status = STATUS_CANCELLED; /* cannot keep repeating */
      } /* Endif */

      if ((status != USB_OK) && (status != USBERR_TRANSFER_IN_PROGRESS)) {
         /* Command didn't succeed. Notify application and cleanup */
         cmd_ptr->STATUS = STATUS_CANCELLED;
         proc_next = TRUE;
      } /* Endbody */
   }
   else if (status == USBERR_TR_FAILED) {
      /* after getting NAKs, we should retry the CSW (status) phase */
      status = usb_class_mass_pass_on_usb(plocal_intf);
      proc_next = FALSE;
   }
   else {
      /* Command didn't succeed. Notify application and cleanup */
      cmd_ptr->STATUS = STATUS_CANCELLED;
      proc_next = TRUE;
   } /* Endif */

   /* Should we cleanup and process the next command? */
   if (proc_next) {
      cmd_ptr->CALLBACK(status, plocal_intf, cmd_ptr, cmd_ptr->TR_BUF_LEN);
      usb_class_mass_deleteq(plocal_intf);

      /* Send next command, if any */
      if (!USB_CLASS_MASS_IS_Q_EMPTY(plocal_intf)) {
         status = usb_class_mass_pass_on_usb(plocal_intf);
      } /* Endbody */
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_csw, SUCCESSFUL");
   #endif
   
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_pass_on_usb
* Returned Value : ERROR STATUS of the command
* Comments       :
*     This routine gets the pending request from class driver queue and finds
*     what needs to be done by looking at the status (cmd_ptr->STATUS). If a
*     phase has been completed, it will queue the next phase. If there is no
*     pending request in the queue, it will just return.
*     NOTE: This functions should only be called by a callback or withing a
*     USB_lock() USB_unlock() block!
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_mass_pass_on_usb
   (
      /* [IN] Interface handle */
      USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr
   )
{ /* Body */
   COMMAND_OBJECT_PTR      cmd_ptr = NULL;
   TR_INIT_PARAM_STRUCT    tr_init;
   USB_STATUS              status = USB_OK;
   uint_8                  tmp;
   uint_32                 data_len;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb");
   #endif
   
   /* Nothing can be done if there is nothing pending */
   usb_class_mass_get_pending_request(intf_ptr, &cmd_ptr);
   if (cmd_ptr == NULL) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb, no matching request");
      #endif
      return (USB_STATUS)USB_MASS_NO_MATCHING_REQUEST;
   } /* Endif */

   /* Determine the appropriate action based on the phase */
   switch (cmd_ptr->STATUS) {
      case STATUS_QUEUED_IN_DRIVER:
         /* means that CBW needs to be sent.*/
         usb_hostdev_tr_init(&tr_init, usb_class_mass_call_back_cbw, (pointer)intf_ptr);
         tr_init.G.TX_BUFFER = (uchar_ptr)cmd_ptr->CBW_PTR;
         tr_init.G.TX_LENGTH = sizeof(CBW_STRUCT);

         status = _usb_host_send_data(intf_ptr->G.host_handle,
            intf_ptr->BULK_OUT_PIPE, &tr_init);
         break;

      case STATUS_FINISHED_CBW_ON_USB:
         /* Determine next phase (DATA or STATUS), length and direction */
         data_len = LONG_UNALIGNED_LE_TO_HOST(cmd_ptr->CBW_PTR->DCBWDATATRANSFERLENGTH);

         if (data_len > 0) {
            /* Commen TR setup for IN or OUT direction */
            usb_hostdev_tr_init(&tr_init,usb_class_mass_call_back_dphase, (pointer)intf_ptr);

            tmp = (uint_8)((cmd_ptr->CBW_PTR->BMCBWFLAGS) & MASK_NON_DIRECTION_BITS);
            switch(tmp) {
               case DIRECTION_OUT:
                  /* Make a TR with DATA Phase call back.*/
                  tr_init.G.TX_BUFFER = (uchar_ptr)cmd_ptr->DATA_BUFFER;
                  tr_init.G.TX_LENGTH = cmd_ptr->BUFFER_LEN;

                  status = _usb_host_send_data(intf_ptr->G.host_handle, intf_ptr->BULK_OUT_PIPE, &tr_init);
                  break;

               case DIRECTION_IN:
                  /* Make a TR with DATA call back.*/
                  tr_init.G.RX_BUFFER = (uchar_ptr)cmd_ptr->DATA_BUFFER;
                  tr_init.G.RX_LENGTH = cmd_ptr->BUFFER_LEN;

                  status = _usb_host_recv_data(intf_ptr->G.host_handle, intf_ptr->BULK_IN_PIPE, &tr_init);
                  break;

               default:
                  break;
            } /* Endswitch */
            break;
         } /* Endif */

         /*
         ** else case:
         ** No data transfer is expected of the request. Fall through to
         ** STATUS phase
         */

      case STATUS_FINISHED_DPHASE_ON_USB:
         /* Make a TR and send it with STATUS call back */
         usb_hostdev_tr_init(&tr_init,usb_class_mass_call_back_csw, (pointer)intf_ptr);
         tr_init.G.RX_BUFFER = (uchar_ptr)cmd_ptr->CSW_PTR;
         tr_init.G.RX_LENGTH = sizeof(CSW_STRUCT);

         status = _usb_host_recv_data(intf_ptr->G.host_handle, intf_ptr->BULK_IN_PIPE, &tr_init);
            
         break;

      case STATUS_FINISHED_CSW_ON_USB: /* No action */
      case STATUS_FAILED_IN_CSW:       /* Should never happen */
      default:
         break;
   } /* Endswitch */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,status);
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_getmaxlun_bulkonly
* Returned Value : ERROR STATUS of the command
* Comments       :
*     This is a class specific command. See the documentation of the USB
*     mass storage specifictaion to learn how this command works. This command
*     is used the get the Number of Logical Units on the device. Caller will
*     use the LUN number to direct the commands (as a part of CBW)
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_mass_getmaxlun_bulkonly
   (
      CLASS_CALL_STRUCT_PTR      ccs_ptr,
      uint_8_ptr                 pLUN,
      tr_callback                callback,
      pointer                    callback_param
   )
{ /* Body */
   USB_STATUS                       status = USBERR_NO_INTERFACE;
   USB_SETUP                        request;
   USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_getmaxlun_bulkonly");
   #endif
   
   /* Pointer validity-checking, clear memory, init header */
   USB_lock();
   if (usb_host_class_intf_validate(ccs_ptr)) {
      intf_ptr = (USB_MASS_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle;
      status = usb_hostdev_validate(intf_ptr->G.dev_handle);
   } /* Endif */

   if (status) {
      USB_unlock();

      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_getmaxlun_bulkonly, error status");
      #endif
   return USB_log_error(__FILE__,__LINE__,status);
   } /* Endif */

   /* Get the number of logical units on the device */
   request.BMREQUESTTYPE = REQ_TYPE_CLASS | REQ_TYPE_INTERFACE | REQ_TYPE_IN;
   request.BREQUEST = GET_MAX_LUN;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT_CONST(0);
   *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(((INTERFACE_DESCRIPTOR_PTR)intf_ptr->G.intf_handle)->bInterfaceNumber);
   *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT_CONST(1);

   /* Send request */
   status = _usb_hostdev_cntrl_request (intf_ptr->G.dev_handle,
      &request, (uchar_ptr)pLUN, callback, callback_param);
   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_getmaxlun_bulkonly, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,status);
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_clear_bulk_pipe_on_usb
* Returned Value : ERROR STATUS of the command
* Comments       :
*     This routine gets the pending request from class driver queue and sends
      the CLEAR_FEATURE command on control pipe. This routine is called when
      status phase of the pending command fails and class driver decides to
      clear the pipes. If there is no pending request in the queue, it will
      just return.
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_mass_clear_bulk_pipe_on_usb
   (
      USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr
   )
{ /* Body */
   USB_STATUS                    status = USB_OK;
   PIPE_INIT_PARAM_STRUCT_PTR    pBulk_pipe = NULL;
   COMMAND_OBJECT_PTR            cmd_ptr = NULL;
   uint_8                        direction;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_clear_bulk_pipe_on_usb");
   #endif
   
   /* Nothing can be done if there is nothing pending */
   usb_class_mass_get_pending_request(intf_ptr, &cmd_ptr);
   if (cmd_ptr == NULL) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_clear_bulk_pipe_on_usb, no matching request");
      #endif
      return USB_log_error(__FILE__,__LINE__,(USB_STATUS)USB_MASS_NO_MATCHING_REQUEST);
   } /* Endif */

   /* Determine pipe (Bulk IN or Bulk OUT) to clear */
   if ((cmd_ptr->CBW_PTR->BMCBWFLAGS & MASK_NON_DIRECTION_BITS) == DIRECTION_IN) {
      pBulk_pipe = (PIPE_INIT_PARAM_STRUCT_PTR)intf_ptr->BULK_IN_PIPE;
      direction = REQ_TYPE_IN;
   } else {
      pBulk_pipe = (PIPE_INIT_PARAM_STRUCT_PTR)intf_ptr->BULK_OUT_PIPE;
      direction = REQ_TYPE_OUT;
   } /* Endif */

   status = _usb_host_register_ch9_callback(intf_ptr->G.dev_handle,
      usb_class_mass_reset_callback, (pointer)intf_ptr);

   if (status == USB_OK || status == USB_STATUS_TRANSFER_QUEUED) {
      /* Send a CLEAR PIPE command */
      cmd_ptr->STATUS = STATUS_CLEAR_BULK_PIPE;
      status = _usb_host_ch9_clear_feature(intf_ptr->G.dev_handle,
         REQ_TYPE_ENDPOINT, (uint_8)(pBulk_pipe->G.ENDPOINT_NUMBER | direction), ENDPOINT_HALT);
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_clear_bulk_pipe_on_usb, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,status);
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_reset_recovery_on_usb
* Returned Value : ERROR STATUS of the command
* Comments       :
*     This routine gets the pending request from class driver queue and sends
*     the RESET command on control pipe. This routine is called when
*     a phase of the pending command fails and class driver decides to
*     reset the device. If there is no pending request in the queue, it will
*     just return. This routine registers a call back for control pipe commands
*     to ensure that pending command is queued again.
*     NOTE: This functions should only be called by a callback or withing a
*     USB_lock() USB_unlock() block!
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_mass_reset_recovery_on_usb
   (
      USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr
   )
{ /* Body */
   COMMAND_OBJECT_PTR         cmd_ptr = NULL;
   USB_STATUS                 status = USB_OK;
   USB_SETUP                  request;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_reset_recovery_on_usb");
   #endif
   
   /* Nothing can be done if there is nothing pending*/
   usb_class_mass_get_pending_request(intf_ptr,&cmd_ptr);
   if(cmd_ptr == NULL) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_reset_recovery_on_usb,no matching request");
      #endif
      return (USB_STATUS) USB_MASS_NO_MATCHING_REQUEST;
   } /* Endif */

   /* BULK device mass storage reset */
   request.BMREQUESTTYPE   = REQ_TYPE_CLASS | REQ_TYPE_INTERFACE | REQ_TYPE_OUT;
   request.BREQUEST        = MASS_STORAGE_RESET;
   *(uint_16*)request.WVALUE = HOST_TO_LE_SHORT_CONST(0);
   *(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(((INTERFACE_DESCRIPTOR_PTR)intf_ptr->G.intf_handle)->bInterfaceNumber);
   *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT_CONST(0);

   cmd_ptr->STATUS = STATUS_RESET_DEVICE;
   status = _usb_hostdev_cntrl_request (intf_ptr->G.dev_handle, &request, NULL,
      usb_class_mass_reset_callback, (pointer)intf_ptr);

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_reset_recovery_on_usb,SUCCESSFUL");
   #endif
      
   return USB_log_error(__FILE__,__LINE__,status);
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_mass_reset_callback
* Returned Value : None
* Comments       : 
*     Callback used when resetting and clearing endpoints. It is also
*     state machine for reset recovery.
*
*END*--------------------------------------------------------------------*/

static void usb_class_mass_reset_callback
   (
      /* [IN] pointer to pipe */
      _usb_pipe_handle  pipe_handle,

      /* [IN] user-defined parameter */
      pointer           user_parm,

      /* [IN] buffer address */
      uchar_ptr         buffer,

      /* [IN] length of data transferred */
      uint_32           length_data_transfered,

      /* [IN] status, hopefully USB_OK or USB_DONE */
      USB_STATUS        status
   )
{ /* Body */

   USB_MASS_CLASS_INTF_STRUCT_PTR   plocal_intf;
   PIPE_STRUCT_PTR                  pPipe;
   COMMAND_OBJECT_PTR               cmd_ptr = NULL;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_reset_callback");
   #endif

   if (user_parm) {
      /* Get the pointer to the pending request */
      plocal_intf = (USB_MASS_CLASS_INTF_STRUCT_PTR)user_parm;
      usb_class_mass_get_pending_request(plocal_intf, &cmd_ptr);
   } /* Endif */

   if (!cmd_ptr) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_reset_callback, bad param");
      #endif
      return;
   } /* Endif */

   /* Check the status of the reset and act accordingly */
   if (status == USB_OK || status == USB_STATUS_TRANSFER_QUEUED) {
      switch (cmd_ptr->STATUS) {
         case STATUS_RESET_DEVICE:
            /* Reset the Bulk IN pipe */
            pPipe = (PIPE_STRUCT_PTR)plocal_intf->BULK_IN_PIPE;
            if (!_usb_host_register_ch9_callback(plocal_intf->G.dev_handle,
               usb_class_mass_reset_callback, plocal_intf))
            {
               status = _usb_host_ch9_clear_feature(plocal_intf->G.dev_handle,
                  REQ_TYPE_ENDPOINT, (uint_8)(pPipe->ENDPOINT_NUMBER | REQ_TYPE_IN), ENDPOINT_HALT);
               cmd_ptr->STATUS = STATUS_RESET_BULK_IN;
            } /* Endif */
            break;

         case STATUS_RESET_BULK_IN:
            /* Reset the Bulk OUT pipe*/
            pPipe = (PIPE_STRUCT_PTR)plocal_intf->BULK_OUT_PIPE;
            if (!_usb_host_register_ch9_callback(plocal_intf->G.dev_handle,
               usb_class_mass_reset_callback, plocal_intf))
            {
               status = _usb_host_ch9_clear_feature(plocal_intf->G.dev_handle,
                  REQ_TYPE_ENDPOINT, (uint_8)(pPipe->ENDPOINT_NUMBER | REQ_TYPE_OUT), ENDPOINT_HALT);
               cmd_ptr->STATUS   =   STATUS_RESET_BULK_OUT;
            } /* Endif */
            break;

         case STATUS_RESET_BULK_OUT:
         case STATUS_CLEAR_BULK_PIPE:
            pPipe = (PIPE_STRUCT_PTR)plocal_intf->BULK_IN_PIPE;
            pPipe->NEXTDATA01 = 0; /* reset the NEXTDATA toggle bit */
            cmd_ptr->STATUS = cmd_ptr->PREV_STATUS; /* restore status set prior to call reset function */
            status = usb_class_mass_pass_on_usb(plocal_intf);
            break;

         default:
            /* we should never appear here, however this case is handled by resetting the device */
            status = usb_class_mass_reset_recovery_on_usb(plocal_intf);
            break;
      } /* Endswitch */

   } else if (status == USBERR_ENDPOINT_STALLED) {

      cmd_ptr->STATUS = STATUS_CANCELLED;
      cmd_ptr->CALLBACK(status, plocal_intf, cmd_ptr, cmd_ptr->TR_BUF_LEN);
      usb_class_mass_deleteq(plocal_intf);

      /* go to the next packet if any */
      usb_class_mass_pass_on_usb(plocal_intf);
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_reset_callback, SUCCESSFUL");
   #endif
   
} /* Endbody */

/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fputs.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fputs.c$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the functions for printing a string
*
*END************************************************************************/

#include <string.h>
#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Writes a sting.
 * 
 * \param[in] string_ptr The string to print out.
 * \param[in] file_ptr   The stream upon which to print out the string.
 * 
 * \return Written string.
 * \return IO_EOF (Failure.)    
 */ 
_mqx_int _io_fputs
   (
      const char _PTR_  string_ptr,
      MQX_FILE_PTR      file_ptr
   )
{ /* Body */
   _mqx_int result;

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(IO_EOF);
   } /* Endif */
#endif

   result = _io_write(file_ptr, (char _PTR_)string_ptr, strlen(string_ptr));

   return(result);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5xxx_fec_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2009 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5xxx_fec_prv.h$
* $Version : 3.5.6.0$
* $Date    : Nov-30-2009$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the ethernet drivers for the ColdFire 32-bit FEC 
*
*END************************************************************************/
#ifndef _mcf5xxx_fec_prv_h
#define _mcf5xxx_fec_prv_h 1

//#define MCF5XXX_FEC_MII_TIMEOUT         (0x10000)
#define MCF5XXX_FEC_RESET_TIMEOUT       (0x10000)

#define MCF5XXX_FEC_RX_ALIGN(n) ENET_ALIGN(n,MCF5XXX_FEC_RX_BUFFER_ALIGNMENT)
#define MCF5XXX_FEC_TX_ALIGN(n) ENET_ALIGN(n,MCF5XXX_FEC_TX_BUFFER_ALIGNMENT)
#define MCF5XXX_FEC_BD_ALIGN(n) ENET_ALIGN(n,MCF5XXX_FEC_BD_ALIGNMENT)

#define MCF5XXX_NUM_ISRS      5

#define MCF5XXX_MAX_FRAGS     6     // Assumes RX_BUFFER_SIZE >= 256, so that 256*6=1536, set higher for smaller RX_BUFFER_SIZE

#define FEC_int_disable()       _int_disable()
#define FEC_int_enable()        _int_enable()
                                 


// Set ENETCFG_SUPPORT_FRAGMENTED_PCBS to 1 if the upper layer can support receive PCBs with multiple
// fragments.  NOTE: RTCS currently does not support this.
#ifndef ENETCFG_SUPPORT_FRAGMENTED_PCBS
   #define ENETCFG_SUPPORT_FRAGMENTED_PCBS 0
#endif

#define BD_INC(index,maxnum)   if (++index == maxnum) index = 0


#ifdef __cplusplus
extern "C" {
#endif

typedef uint_16 bd_index_t;


#if ENETCFG_SUPPORT_FRAGMENTED_PCBS

   typedef struct mcf5xxx_fec_rx_pcb
   {
      PCB            _FRAG0;
      PCB_FRAGMENT   _FRAGS[MCF5XXX_MAX_FRAGS];
      PCB_FRAGMENT   _FREE_FRAG;
   } MCF5XXX_FEC_RX_PCB, _PTR_ MCF5XXX_FEC_RX_PCB_PTR;
#else
   typedef PCB2 MCF5XXX_FEC_RX_PCB, _PTR_ MCF5XXX_FEC_RX_PCB_PTR;
#endif



/* The Ethernet initialization structure */
typedef struct {
   uint_32            BUS_CLOCK;     
   _int_level         ERX_LEVEL;      // Receive interrupt level
   _int_priority      ERX_SUBLEVEL;   // Receive interrupt sublevel
   _int_level         ETX_LEVEL;      // Transmit interrupt level
   _int_priority      ETX_SUBLEVEL;   // Transmit interrupt sublevel
} MCF5XXX_FEC_INIT_STRUCT, _PTR_ MCF5XXX_FEC_INIT_STRUCT_PTR;


typedef struct mcf_fec_context_struct {
   VMCF5XXX_FEC_STRUCT_PTR FEC_ADDRESS;
   VMCF5XXX_FEC_STRUCT_PTR PHY_PTR;

   uint_16                 AlignedRxBufferSize;
   uint_16                 AlignedTxBufferSize;
   
   /*
   **    The Receive-Side State
   **
   ** RxPCBHead and RxPCBTail are the head and tail of a linked list
   ** of available PCBs for receiving packets.  RxEntries is
   ** the length of this list.
   **
   ** NextRxBD points to the 'first' queued receive descriptor, i.e., usually
   ** the one that RBPTR is pointing to.  When an RXF interrupt occurs,
   ** NextRxBD is pointing to the first descriptor with a received packet.
   ** The packets is forwarded to the upper layers, and NextRxBD is incremented.
   **
   ** LastRxBD points to the 'last' queued receive descriptor, i.e., the last
   ** one with E=1.  The LastRxBD descriptor usually precedes the LastRxBD descriptor.
   ** When the upper layers free a received packet, it gets placed at LastRxBD
   ** (with E=1), and LastRxBD is incremented.
   */

   PCB_PTR                       RxPCBHead;
   PCB_PTR                       RxPCBTail;
   
   uint_32                       CurrentRxFrag;
   ENET_ECB_STRUCT_PTR           CurrentRxECB;
#if ENETCFG_SUPPORT_FRAGMENTED_PCBS
   PCB_PTR                       CurrentRxPCB;     // The PCB that is currently being built
   boolean                       RxDiscarding;
#else
   PCB_FRAGMENT                  FRAGS[MCF5XXX_MAX_FRAGS];
#endif


   bd_index_t                    ActiveRxBDs;
   bd_index_t                    NextRxBD;
   bd_index_t                    LastRxBD;
   bd_index_t                    NumRxBDs;

   /*
   **    The Transmit-Side State
   **
   ** TxPCBS_PTR is an array of pointers to the PCBs queued on the transmit ring.
   ** AvailableTxBDs is the number of free entries on the ring.
   **
   ** NextTxBD points to the first available transmit descriptor (when AvailableTxBDs>0),
   ** or to LastTxBD (when AvailableTxBDs==NumTxBDs).  It is the descriptor that will next
   ** be queued onto the transmit ring, as soon as there's a packet to send
   ** and room on the transmit ring.
   **
   ** LastTxBD points to the 'last' queued transmit descriptor, i.e., the one
   ** that TBPTR is pointing to.  When a TXB interrupt occurs, LastTxBD is
   ** pointing to the transmitted buffer.  The buffer is freed, and LastTxBD is
   ** incremented.
   **
   ** TxErrors keeps track of all the errors that occur during transmission
   ** of a frame comprised of multiple buffers.
   */

   PCB_PTR *                     TxPCBS_PTR;
   bd_index_t                    AvailableTxBDs;
   bd_index_t                    NextTxBD;
   bd_index_t                    LastTxBD;
   bd_index_t                    NumTxBDs;
   uint_32                       TxErrors;



   MCF5XXX_FEC_RX_PCB_PTR        RX_PCB_BASE;
   pointer                       UNALIGNED_RING_PTR;        
   VMCF5XXX_FEC_BD_STRUCT_PTR    FEC_RX_RING_PTR; 
   VMCF5XXX_FEC_BD_STRUCT_PTR    FEC_TX_RING_PTR; 
   pointer                       UNALIGNED_BUFFERS;  
   uchar_ptr                     RX_BUFFERS;  
   uchar_ptr                     TX_BUFFERS;  
   uchar_ptr                     SMALL_BUFFERS;  
   uchar_ptr                     LARGE_BUFFERS;  
   uint_32                       FREE_TX;
   uint_32                       FREE_TX_SMALL;
   
#if BSPCFG_ENET_RESTORE
   /* These fields are kept only for ENET_shutdown() */
   INT_ISR_FPTR                  OLDISR_PTR[MCF5XXX_NUM_ISRS];
   pointer                       OLDISR_DATA[MCF5XXX_NUM_ISRS];
#endif
      
} MCF5XXX_FEC_CONTEXT_STRUCT, * MCF5XXX_FEC_CONTEXT_STRUCT_PTR;


extern const   MCF5XXX_FEC_INIT_STRUCT MCF5XXX_FEC_device[];
extern const   ENET_MAC_IF_STRUCT MCF5xxx_FEC_IF;
extern const   uint_32 MCF5XXX_FEC_vectors[MCF5XXX_FEC_DEVICE_COUNT][MCF5XXX_FEC_NUM_INTS];

extern boolean MCF5XXX_FEC_install_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr, MCF5XXX_FEC_INIT_STRUCT const * enet_init_ptr  ); 
extern void    MCF5XXX_FEC_add_buffers_to_rx_ring(MCF5XXX_FEC_CONTEXT_STRUCT_PTR fec_context_ptr);
extern uint_32 MCF5XXX_FEC_initialize(ENET_CONTEXT_STRUCT_PTR);
extern uint_32 MCF5XXX_FEC_shutdown( ENET_CONTEXT_STRUCT_PTR );
extern uint_32 MCF5XXX_FEC_send( ENET_CONTEXT_STRUCT_PTR, PCB_PTR packet, uint_32 size, uint_32 frags, uint_32 flags );
extern uint_32 MCF5XXX_FEC_join( ENET_CONTEXT_STRUCT_PTR, ENET_MCB_STRUCT_PTR mcb_ptr );
extern uint_32 MCF5XXX_FEC_rejoin( ENET_CONTEXT_STRUCT_PTR );
extern void    MCF5XXX_FEC_mask_interrupts( ENET_CONTEXT_STRUCT_PTR enet_ptr ); 
extern void    MCF5XXX_FEC_uninstall_all_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr );
extern void    MCF5XXX_FEC_TX_ISR(pointer);
extern void    MCF5XXX_FEC_RX_ISR(pointer);
extern pointer MCF5XXX_FEC_get_base_address (uint_32);
extern uint_32 MCF5XXX_FEC_get_vector(uint_32,uint_32);
extern void    MCF5XXX_FEC_io_init(uint_32);
extern void    MCF5XXX_FEC_free_context( MCF5XXX_FEC_CONTEXT_STRUCT_PTR fec_context_ptr );

boolean MCF5XXX_FEC_read_mii(ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 reg_index, uint_32_ptr data, uint_32 timeout);
boolean MCF5XXX_FEC_write_mii(ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 reg_index, uint_32 data, uint_32 timeout);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/host_common.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_common.c$
* $Version : 3.8.36.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains common functions for USB class drivers
*   Implementation Notes:
*   An interface is supported by two data structures on the
*   owning device's list of allocated memory:-
*   (1) a pipe bundle struct with pointers to open pipes for
*   all endpoints on the interface
*   (2) a class-interface struct with queues for TR logging,
*   pipe handles, and other class-specific status etc.
*   Each <class_name>.h must define its interface struct, which must
*   begin with the fields in GENERAL_CLASS (see common.h),
*   if common routines are going to be used.
*   It is strongly recommended that all class init functions
*   call usb_host_class_intf_init (pointer to pipe bundle,
*   pointer to class-intf, (pointer)&class_anchor ).  This
*   will verify correct pointers, zero the interface struct,
*   and set up the header pointers + key correctly.
*   All class usage of the pointers etc. in the struct
*   must be protected against detach (which occurs without
*   advance notice):-
*   USB_lock();
*   if (usb_host_class_intf_validate(class-call-struct pointer)) {
*       Issue commands / Use pipes etc.
*   }
*   USB_unlock();
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_common.h"
#include "host_main.h"
#include "host_dev_list.h"
#include "host_ch9.h"

extern CLASS_MAP class_interface_map[];

/* Unique non-zero key to assure valid interface use. */
static uint_32 Class_Key_Generator = 0;

/* Prototypes, copy to stack frames for each use instance */

const static TR_INIT_PARAM_STRUCT tr_prototype =
{
   NULL, /* pointer to next */
   USB_STATUS_IDLE, /* status of the transfer */
   0,    /* transaction index */
   NULL, /* TX buffer */
   NULL, /* RX buffer */
   0,    /* TX/data phase length */
   0,    /* RX/data phase length */
   NULL, /* callback pointer */
   NULL, /* callback param */
   /* all the other structure members are filled during transaction setup */
};

static uint_32 tr_index = 0;

/* Unpublished functions, not intended for application use */
static USB_STATUS usb_hostdev_get_class(_usb_device_instance_handle, uint_16, pointer _PTR_ );
static uint_32 usb_hostdev_mask_class_etc(uint_8_ptr , uint_8_ptr);
static USB_STATUS  usb_hostdev_open_pipe(_usb_device_instance_handle, _usb_interface_descriptor_handle, uint_32, uint_8, _usb_pipe_handle _PTR_);
static boolean  usb_host_driver_info_match(DEV_INSTANCE_PTR, INTERFACE_DESCRIPTOR_PTR, USB_HOST_DRIVER_INFO_PTR);
static void  usb_host_driver_info_scan(DEV_INSTANCE_PTR, INTERFACE_DESCRIPTOR_PTR, uint_32);
static boolean usb_host_driver_info_nonzero(USB_HOST_DRIVER_INFO_PTR);
static CLASS_MAP_PTR  usb_host_map_class_intf(PIPE_BUNDLE_STRUCT_PTR);

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hostdev_attach_detach
* Returned Value : none
* Comments       :
*     Scan device config for interfaces that may need callbacks
*     for matching classes etc. from each interface. This function is
*     called when there configuration change or attach or detach event
*
*END*--------------------------------------------------------------------*/
void  usb_hostdev_attach_detach
   (
      /* [IN] USB device */
      DEV_INSTANCE_PTR           dev_ptr,

      /* [IN] event causing callback */
      uint_32                    event_code
   )
{ /* Body */
   DESCRIPTOR_UNION desc;
   uint_32          cfg_end;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_attach_detach");
   #endif

   USB_lock();

   /* FIXME: it is presumed that memlist points to the config descriptor */
   desc.pntr = dev_ptr->memlist->payload.data + dev_ptr->memlist->offset;
   cfg_end = desc.word + SHORT_LE_TO_HOST((desc.cfig->wTotalLength[1] << 8) | (desc.cfig->wTotalLength[0] << 0));

   /* We will always start with config desc so update the search pointer */
   desc.word += desc.cfig->bLength;

   /* Scan through all the interface descriptors for this configuration */
   do {
      /* Scan through all the other descriptors for this interface */
      do {
        
      } while (0);
      if (desc.intf->bDescriptorType == USB_DESC_TYPE_IF)
         usb_host_driver_info_scan(dev_ptr, desc.intf, event_code);
      desc.word += desc.intf->bLength; /* next descriptor */
      
      // EAI
      if (desc.intf->bLength==0) break;
      
   } while (desc.word < cfg_end);

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_attach_detach SUCCESSFUL");
   #endif
} /* EndBody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hostdev_busy_check
* Returned Value : USB_OK or
*                    USBERR_DEVICE_NOT_FOUND
*                    USBERR_DEVICE_BUSY
* Comments       :
*     Function to verify pointer is address of an instance on device list.
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
USB_STATUS  usb_hostdev_busy_check
   (
      _usb_device_instance_handle  device_handle
   )
{ /* Body */
   DEV_INSTANCE_PTR           dev_ptr = (DEV_INSTANCE_PTR)device_handle;
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)dev_ptr->host;
   DEV_INSTANCE_PTR           test_ptr = (DEV_INSTANCE_PTR)usb_host_ptr->DEVICE_LIST_PTR;
   USB_STATUS                 error;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_busy_check");
   #endif

   while ((test_ptr != dev_ptr) && (test_ptr != NULL))
   {
      test_ptr = test_ptr->next;
   }

   if (test_ptr == NULL)
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_hostdev_busy_check device not found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   }

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_busy_check SUCCESSFUL");
   #endif

   error = (USB_STATUS)((test_ptr->memlist->next != NULL) ? USBERR_DEVICE_BUSY : USB_OK);
   return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hostdev_validate
* Returned Value : USB_OK or USBERR_DEVICE_NOT_FOUND
* Comments       :
*     Function to verify pointer is address of an instance on device list.
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
USB_STATUS  usb_hostdev_validate
   (
      _usb_device_instance_handle  device_handle
   )
{ /* Body */
   DEV_INSTANCE_PTR           dev_ptr = (DEV_INSTANCE_PTR)device_handle;
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
   USB_HOST_IF_STRUCT_PTR     usb_c;
   DEV_INSTANCE_PTR           test_ptr;
   USB_STATUS                 error;
   _mqx_uint                  i;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_validate");
   #endif

   if (device_handle == NULL) {
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_validate FAILED, invalid device number");
   #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_DEVICE_NUM);
   }
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)dev_ptr->host;

   USB_lock();
   usb_c = _mqx_get_io_component_handle(IO_USB_COMPONENT);

   /* Check if the interface is registered */
   if (!usb_c) {
      /* No interface was registered yet */
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_hostdev_validate FAILED, no controller installed");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   }
   /* Find out if the host controller interface has been installed */
   for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
      if (usb_c[i].HOST_HANDLE == usb_host_ptr) {
         /* Found installed device */
         break;
      }
   }
   if (i == USBCFG_MAX_DRIVERS) {
      /* No such controller was initialized yet */
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_hostdev_validate FAILED, no controller inited");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   }

   /* usb_host_ptr is valid host state structure, check for list of attached device instances */
   test_ptr = (DEV_INSTANCE_PTR)usb_host_ptr->DEVICE_LIST_PTR;
   while ((test_ptr != dev_ptr) && (test_ptr != NULL))
   {
      test_ptr = test_ptr->next;
   }

   USB_unlock();

   #ifdef _HOST_DEBUG_
      if(test_ptr == NULL) 
      {
         DEBUG_LOG_TRACE("usb_hostdev_validate null device handle");
      }
      else
      {  
         DEBUG_LOG_TRACE("usb_hostdev_validate SUCCESSFUL");
      }
   #endif

   error = (test_ptr == NULL) ? USBERR_DEVICE_NOT_FOUND : USB_OK;
   return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_hostdev_get_buffer
*  Returned Value : pointer to the buffer, or NULL + error
*  Comments       :
*        Applications should use this function to get I/O buffers and
*        other work areas that stay allocated until the device is
*        detached.  At that time, these are all freed by the system.
*        Another approach is to use _usb_hostdev_free_buffer
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_hostdev_get_buffer
   (
      /* [IN] the device instance */
      _usb_device_instance_handle   dev_handle,

      /* [IN] buffer size to get */
      uint_32                       buffer_size,

      /* [OUT] pointer to the buffer, or NULL */
      pointer               _PTR_ buffer_ptr
   )
{ /* Body */

#ifdef USB_DMA_ALIGN
    return _usb_hostdev_get_buffer_aligned(dev_handle, buffer_size, USB_DMA_ALIGN(1), buffer_ptr);
#else
    return _usb_hostdev_get_buffer_aligned(dev_handle, buffer_size, 1, buffer_ptr);
#endif

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_hostdev_get_buffer_aligned
*  Returned Value : pointer to the buffer, or NULL + error
*  Comments       :
*        Applications should use this function to get I/O buffers and
*        other work areas that stay allocated until the device is
*        detached.  At that time, these are all freed by the system.
*        Another approach is to use _usb_hostdev_free_buffer
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_hostdev_get_buffer_aligned
   (
      /* [IN] the device instance */
      _usb_device_instance_handle   dev_handle,

      /* [IN] buffer size to get */
      uint_32                       buffer_size,

      /* [IN] alignment vlaue (e.g. 8 for 8B alignment) */
      uint_32                       align,

      /* [OUT] pointer to the buffer, or NULL */
      pointer                 _PTR_ buffer_ptr
   )
{ /* Body */
   DEV_MEMORY_PTR    dev_mem;
   DEV_INSTANCE_PTR  dev_ptr;
   USB_STATUS        error;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_get_buffer");
   #endif
   
   USB_lock();

   error = usb_hostdev_validate(dev_handle);
   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_get_buffer invalid device handle");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   } /* Endif */

   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;

   error =  usb_dev_list_get_mem(dev_ptr, buffer_size,
      USB_MEMTYPE_BUFFER, align, &dev_mem);

   if (error != USB_OK)
      *buffer_ptr = NULL;
   else
      *buffer_ptr = dev_mem->payload.data + dev_mem->offset;

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_get_buffer SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_hostdev_free_buffer
*  Returned Value : USB_OK if buffer block found
*  Comments       :
*        Applications should use this function to free I/O buffer.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_hostdev_free_buffer
   (
      /* [IN] the device instance */
      _usb_device_instance_handle   dev_handle,

      /* [IN] pointer to the buffer */
      pointer                       buffer_ptr
   )
{ /* Body */
   DEV_MEMORY_PTR    dev_mem;
   DEV_INSTANCE_PTR  dev_ptr;
   USB_STATUS        error;
   uint_32           offset;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_free_buffer");
   #endif
   
   USB_lock();

   error = usb_hostdev_validate(dev_handle);
   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_free_buffer invalid device handle");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   } /* Endif */

   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;
   /* Get the offset of real payload within device memory. */
   offset = *((uchar_ptr) buffer_ptr - 1);
   /* Find device memory pointer. */
   dev_mem = (DEV_MEMORY_PTR) ((uchar_ptr) buffer_ptr - offset - MEM_HEADER_LEN);

   error = usb_dev_list_free_mem(dev_ptr, dev_mem);

   USB_unlock();

   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_free_buffer FAILED");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_get_buffer SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : usb_hostdev_get_class
*  Returned Value : pointer to class/interface struct, or NULL + error
*  Comments       :
*        This wrapper is for _usb_hostdev_select_interface use only.
*
*END*-----------------------------------------------------------------*/
static USB_STATUS usb_hostdev_get_class
   (
      /* [IN] the device instance */
      _usb_device_instance_handle   dev_handle,

      /* [IN] buffer size to get */
      uint_16                       struct_size,

      /* [OUT] pointer to the buffer, or NULL */
      pointer                 _PTR_ struct_ptr
   )
{ /* Body */
   DEV_MEMORY_PTR    memory_block;
   DEV_INSTANCE_PTR  dev_ptr;
   USB_STATUS        error;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_get_class");
   #endif
   
   USB_lock();
   error = usb_hostdev_validate(dev_handle);
   if (error != USB_OK) {
      USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_get_class invalid device handle");
   #endif
      return USB_log_error(__FILE__,__LINE__,error);
   } /* Endif */

   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;

   error =  usb_dev_list_get_mem
      (dev_ptr,
      struct_size,
      USB_MEMTYPE_CLASS,
      1,
      &memory_block);

   if (error != USB_OK)
      *struct_ptr = NULL;
   else
      *struct_ptr = memory_block->payload.data + memory_block->offset;

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_get_class SUCCESSFUL");
   #endif
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_hostdev_get_descriptor
*  Returned Value : handle of the descriptor, or NULL + error
*  Comments       :
*     If the intf_handle is NULL, then the descriptor is searched within
*     the whole device. If the intf_handle is not NULL, the descriptor is
*     searched within specified interface (ignored if desc_type is
*     USB_DESC_TYPE_DEV, USB_DESC_TYPE_CFG or USB_DESC_TYPE_IF and required
*     for USB_DESC_TYPE_EP).
*
*  It is presumed that this function is called with interrupts disabled.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_hostdev_get_descriptor
   (
      /* [IN] the device instance */
      _usb_device_instance_handle   dev_handle,

      /* [IN] the device instance or NULL to search the device config */
      _usb_interface_descriptor_handle intf_handle,

      /* [IN] the type of descriptor to get */
      descriptor_type               desc_type,

      /* [IN] the index of desc_type decriptor, or 0 */
      uint_8                        desc_index,

      /* [IN] the interface alternate, or 0 */
      uint_8                        intf_alt,

      /* [OUT] handle of the descriptor, or NULL */
      pointer                 _PTR_ descriptor
   )
{ /* Body */

   DEV_INSTANCE_PTR  dev_ptr;
   DESCRIPTOR_UNION  ptr1, ptr2;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor");
   #endif
   
   *descriptor = NULL; /* Assume the worst */

   /* Check that device handle points to a device */
   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;

   if (dev_ptr->state < DEVSTATE_CFG_READ) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor device busy");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_BUSY);
   } /* Endif */

   /* Device descriptor is in the instance struct */
   if (desc_type == USB_DESC_TYPE_DEV) {
      *descriptor = &dev_ptr->dev_descriptor;
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor SUCCESSFUL");
      #endif
      return USB_OK;
   } /* EndIf */

   /*--------------------------------------------------------**
   ** If descriptor type is Configuration, the pointer is    **
   **    found in ptr1.  Other types of descriptor need      **
   **    to be found by stepping through the config one      **
   **    descriptor at a time.                               **
   ** To prevent parsing past the config buffer, ptr2 is     **
   **    set to the starting address plus its total size.    **
   **--------------------------------------------------------*/

   ptr1.pntr = dev_ptr->memlist->payload.data + dev_ptr->memlist->offset; /* offset for alignment */

   if (desc_type != USB_DESC_TYPE_CFG) {
      ptr2.word = ptr1.word + SHORT_UNALIGNED_LE_TO_HOST(ptr1.cfig->wTotalLength);

      #define  HOSTDEV_GET_NEXT_DESCRIPTOR\
      ptr1.word += ptr1.cfig->bLength;    \
      if (ptr1.word >= ptr2.word) {       \
         return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);     \
      } /* Endif */

      switch (desc_type) {
         case USB_DESC_TYPE_IF:
            if (ptr1.cfig->bNumInterfaces < desc_index) {
               #ifdef _HOST_DEBUG_
                  DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor no INTF descriptor");
               #endif
               return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);
            } /* Endif */

            do {
               HOSTDEV_GET_NEXT_DESCRIPTOR
            } while (
               (ptr1.intf->bDescriptorType != USB_DESC_TYPE_IF) ||
               (ptr1.intf->bInterfaceNumber != desc_index) ||
               (ptr1.intf->bAlternateSetting != intf_alt));

            //dev_ptr->intf_recently = ptr1.intf; /* use for endpoints, deprecated */
            break;
         case USB_DESC_TYPE_EP:
            /* Endpoints must follow a known valid interface --
            ** the pointer cannot be NULL, and must point to
            ** the type & length for interface descriptors */
            ptr1.intf = intf_handle;

            if (ptr1.intf == NULL) {
               #ifdef _HOST_DEBUG_
                  DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor no EP descriptor");
               #endif
               return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);
            } /* Endif */

            if ((ptr1.intf->bDescriptorType != USB_DESC_TYPE_IF) ||
               (ptr1.intf->bLength != 9) )
            {
               #ifdef _HOST_DEBUG_
                  DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor no descriptor");
               #endif
               return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);
            } /* EndIf */

            /* Endpoint 0 is NOT included in the count, and
            ** there is no descriptor for it after interface
            */
            if ((desc_index == 0) ||
               (desc_index > ptr1.intf->bNumEndpoints)) {
               #ifdef _HOST_DEBUG_
                  DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor no EP0 descriptor");
               #endif
               return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);
            } /* Endif */

            do {
               HOSTDEV_GET_NEXT_DESCRIPTOR
               switch (ptr1.ndpt->bDescriptorType) {
                  case USB_DESC_TYPE_EP:
                     desc_index--;
                     break ;
                  case USB_DESC_TYPE_IF:
                     #ifdef _HOST_DEBUG_
                        DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor no EP descriptor");
                     #endif
                     return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);
                  default:
                     break ;
               } /* EndCase */
            } while (desc_index > 0);
            break;
         case USB_DESC_TYPE_STR:   /* Not in config, use Ch. 9 call */
            #ifdef _HOST_DEBUG_
               DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor no STRING descriptor read");
            #endif
            return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);
         case USB_DESC_TYPE_DEV_QUALIFIER:
         case USB_DESC_TYPE_OTHER_SPEED_CFG:
         case USB_DESC_TYPE_IF_POWER:
            do {
               HOSTDEV_GET_NEXT_DESCRIPTOR
            } while (ptr1.cfig->bDescriptorType != desc_type);
            break;
         default:
            if (intf_handle != NULL) {
               /* These descriptors must follow a known valid interface --
               ** the pointer cannot be NULL, and must point to
               ** the type & length for interface descriptors */
               ptr1.intf = intf_handle;
            }
         
            if (ptr1.intf == NULL) {
               #ifdef _HOST_DEBUG_
                  DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor no INTF descriptor");
               #endif
               return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);
            } /* Endif */

            for (; ;) {
               HOSTDEV_GET_NEXT_DESCRIPTOR
               /* test if we reached next interface and search scope was only interface */
               if ((ptr1.cfig->bDescriptorType == USB_DESC_TYPE_IF) &&
                  (intf_handle != NULL)) {
                  #ifdef _HOST_DEBUG_
                     DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor no requested descriptor");
                  #endif
                  return USB_log_error(__FILE__,__LINE__,USBERR_NO_DESCRIPTOR);
               }
               if (ptr1.cfig->bDescriptorType == desc_type)
                  if (!desc_index--)
                     break;
            }
            break;
      } /* EndSwitch */
   } /* EndIf */
      #undef  HOSTDEV_GET_NEXT_DESCRIPTOR

   *descriptor = ptr1.pntr;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor SUCCESSFUL");
   #endif
   return USB_OK;

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_hostdev_find_pipe_handle
* Returned Value : pipe handle, or NULL if not found
* Comments       :
*     Function to find a pipe with specified type and direction
*
*END*--------------------------------------------------------------------*/
_usb_pipe_handle  _usb_hostdev_find_pipe_handle
   (
      /* [IN] the device instance */
      _usb_device_instance_handle      dev_handle,

      /* interface handle */
      _usb_interface_descriptor_handle intf_handle,

      /* Pipe type = one of:
      ** USB_ISOCHRONOUS_PIPE
      ** USB_INTERRUPT_PIPE
      ** USB_CONTROL_PIPE
      ** USB_BULK_PIPE
      */
      uint_8                           pipe_type,

      /* Pipe direction (ignored for control pipe) = one of:
      ** USB_RECV
      ** USB_SEND
      */
      uint_8                           pipe_direction
   )
{ /* Body */
   DESCRIPTOR_UNION           desc;
   DEV_INSTANCE_PTR           dev_ptr;
   DEV_MEMORY_PTR             dev_mem;
   PIPE_BUNDLE_STRUCT_PTR     pbs_ptr;
   _usb_pipe_handle           pipe_ptr;
   uint_8                     index;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_find_pipe_handle");
   #endif

   USB_lock();
   /* Verify that the intf_handle points to an interface descriptor */
   desc.pntr = intf_handle;
   if ((desc.intf->bDescriptorType != USB_DESC_TYPE_IF)
      || (desc.intf->bLength != 9)) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_find_pipe_handle invalid interface");
      #endif
      return NULL;
   } /* Endif */

   /* Scan device instance for the interface */
   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;

   /* The device may have several interfaces selected */
   for (index = 0; index < dev_ptr->num_of_interfaces; index++) {
      if (desc.intf == dev_ptr->intf_descriptor[index]) {
         /* Bundle structs are linked into the memory list */
         dev_mem = dev_ptr->memlist;
         do {
            if (dev_mem->blktype == USB_MEMTYPE_PIPES) {
               /* A bundle is owned by a device & interface */
               pbs_ptr = (PIPE_BUNDLE_STRUCT_PTR) (dev_mem->payload.data + dev_mem->offset);
               if ((pbs_ptr->dev_handle == (_usb_device_instance_handle)dev_ptr)
                  && (pbs_ptr->intf_handle == desc.pntr))
               {
                  pipe_ptr = usb_hostdev_get_pipe_handle(pbs_ptr,
                     pipe_type, pipe_direction);
                  USB_unlock();
                  #ifdef _HOST_DEBUG_
                     DEBUG_LOG_TRACE("_usb_hostdev_find_pipe_handle SUCCESSFUL");
                  #endif
                  return pipe_ptr;
               } /* Endif */
            } /* EndIf */
            dev_mem = dev_mem->next;
         } while (dev_mem != NULL);
      } /* EndIf */
   } /* EndFor */

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_find_pipe_handle error");
   #endif
   return NULL;

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hostdev_get_pipe_handle
* Returned Value : pipe handle, or NULL if none in bundle
* Comments       :
*     Function to map a particular pipe type and direction in
*     the given bundle (which contains device/interface).
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
_usb_pipe_handle usb_hostdev_get_pipe_handle
   (
      /* pointer to pipe bundle struct */
      PIPE_BUNDLE_STRUCT_PTR     pbs_ptr,

      /* Pipe type = one of: USB_ISOCHRONOUS_PIPE, USB_INTERRUPT_PIPE, USB_CONTROL_PIPE, USB_BULK_PIPE */
      uint_8                     pipe_type,

      /* Pipe direction (ignored for control pipe) = one of: USB_RECV, USB_SEND */
      uint_8                     pipe_direction
   )
{ /* Body */

   DESCRIPTOR_UNION           desc;
   PIPE_STRUCT_PTR            pipe_ptr;
   uint_8                     m, n;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_get_pipe_handle");
   #endif

   if (USB_OK != usb_hostdev_validate(pbs_ptr->dev_handle))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_hostdev_get_pipe_handle invalid device handle");
      #endif
      return NULL;

   }

   switch (pipe_type) {
      case USB_CONTROL_PIPE:
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_hostdev_get_pipe_handle SUCCESSFUL");
         #endif
         return ((DEV_INSTANCE_PTR)pbs_ptr->dev_handle)->control_pipe;
      case USB_BULK_PIPE:
      case USB_INTERRUPT_PIPE:
      case USB_ISOCHRONOUS_PIPE:
         break;
      default:
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_hostdev_get_pipe_handle FAILED");
         #endif
         return NULL;
   } /* EndSwitch */

   switch (pipe_direction) {
      case USB_RECV:
      case USB_SEND:
         break;
      default:
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_hostdev_get_pipe_handle invalid direction");
         #endif
         return NULL;
   } /* EndSwitch */

   desc.intf = (INTERFACE_DESCRIPTOR_PTR)pbs_ptr->intf_handle;

   if ((desc.intf->bDescriptorType != USB_DESC_TYPE_IF) ||
      (desc.intf->bLength != 9))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_hostdev_get_pipe_handle invalid interface");
      #endif
      return NULL;
   } /* Endif */

   m = desc.intf->bNumEndpoints;

   for (n = 0 ;  n < m ;  n++) {
      pipe_ptr = (PIPE_STRUCT_PTR)pbs_ptr->pipe_handle[n];
      if ((pipe_ptr->PIPETYPE == pipe_type) &&
         (pipe_ptr->DIRECTION == pipe_direction))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_hostdev_get_pipe_handle SUCCESSFUL");
         #endif
         return (pointer)pipe_ptr;
      } /* Endif */
   } /* EndFor */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_get_pipe_handle FAILED");
   #endif
   return NULL;
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_class_intf_init
* Returned Value : USB_OK or error
* Comments       :
*     Initialize header of class interface info struct.
*     Incoming params are checked to catch errors early
*     before attempts to use the struct.
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_host_class_intf_init
   (
      /* [IN] device/descriptor/pipe handles */
      PIPE_BUNDLE_STRUCT_PTR  pbs_ptr,

      /* [IN] class-interface handle */
      pointer                 class_intf_handle,

      /* [IN] address of class's instance list anchor */
      pointer                 anchor_ptr,

      /* [IN] function for deinitialization */
      INTF_DEINIT_CALL        deinit_fcn

   )
{ /* Body */

   DEV_INSTANCE_PTR              dev_ptr;
   GENERAL_CLASS_PTR             class_ptr = NULL;
   INTERFACE_DESCRIPTOR_PTR      intf_desc;
   DEV_MEMORY_PTR                mem_ptr;
   USB_STATUS                    error;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_class_intf_init");
   #endif

   USB_lock();

   error = usb_hostdev_validate (pbs_ptr->dev_handle);

   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_class_intf_init invalid device");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   } /* EndIf */

   dev_ptr = (DEV_INSTANCE_PTR)pbs_ptr->dev_handle;
   intf_desc = (INTERFACE_DESCRIPTOR_PTR)pbs_ptr->intf_handle;

   if ((intf_desc->bDescriptorType != USB_DESC_TYPE_IF) ||
         (intf_desc->bLength != USB_DESC_LEN_IF))
   {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_class_intf_init interface not found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_NO_INTERFACE);
   } /* EndIf */

   for (mem_ptr = dev_ptr->memlist; ;mem_ptr = mem_ptr->next)  {

      if (mem_ptr == NULL) {
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_class_intf_init no interface memory");
         #endif
         return USB_log_error(__FILE__,__LINE__,USBERR_NO_INTERFACE);
      } /* EndIf */

      if ((mem_ptr->blktype == USB_MEMTYPE_CLASS) &&
         ((mem_ptr->payload.data + mem_ptr->offset) == class_intf_handle))
      {
         break;
      } /* Endif */

   } /* EndFor */

   if (anchor_ptr == NULL) {
      USB_unlock ();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_class_intf_init invalid parameter");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_ANCHOR);
   } /* Endif */

   USB_mem_zero(class_intf_handle, mem_ptr->blksize);

   /* Find last item already on list, add new item at end */
   class_ptr = (GENERAL_CLASS_PTR)anchor_ptr;

   while (class_ptr->next != NULL)
   {
      class_ptr = class_ptr->next;
   }

   class_ptr->next = (GENERAL_CLASS_PTR)class_intf_handle;

   /* Initialize header fields of new item */
   class_ptr = (GENERAL_CLASS_PTR)class_intf_handle;
   class_ptr->next = NULL;
   class_ptr->anchor = (GENERAL_CLASS_PTR)anchor_ptr;
   class_ptr->dev_handle = pbs_ptr->dev_handle;
   class_ptr->intf_handle = pbs_ptr->intf_handle;
   class_ptr->host_handle = dev_ptr->host;
   class_ptr->class_deinit = deinit_fcn;

   Class_Key_Generator++;

   class_ptr->key_code = Class_Key_Generator;

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_class_intf_init SUCCESSFUL");
   #endif
   return USB_OK;
} /* EndBody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_class_intf_validate
* Returned Value : uint_32, depends on coded_key in the parameter
*                    coded_key = 0, retrieve intf's key value
*                    coded key > 0, TRUE if intf OK to use
* Comments       :
*     This routine should be used by all classes using pointers
*     or other values kept in the struct:
*     USB_lock();
*     if (usb_host_class_intf_validate(class_intf_ptr) )
*        {
*           Issue commands / Use pipes etc.
*        }
*     USB_unlock();
*     It is presumed that this function is called with interrupts disabled
*
*END*--------------------------------------------------------------------*/
uint_32  usb_host_class_intf_validate
   (
      /* [IN] class-interface handle */
      pointer  class_intf_handle
   )
{ /* Body */
   CLASS_CALL_STRUCT_PTR   cc_ptr;
   GENERAL_CLASS_PTR       gen_ptr;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_class_intf_validate");
   #endif

   cc_ptr = (CLASS_CALL_STRUCT_PTR)class_intf_handle;
   if (NULL == cc_ptr) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_class_intf_validate FAILED, NULL class handle");
      #endif
      return 0;
   }

   gen_ptr = (GENERAL_CLASS_PTR)cc_ptr->class_intf_handle;
   /* TODO: check if the gen_ptr is registered class in the stack */

   /* Match key to caller's value */
   if (cc_ptr->code_key != 0 ) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_class_intf_validate SUCCESSFUL");
      #endif
      return (uint_32)(cc_ptr->code_key == gen_ptr->key_code);
   } else {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_class_intf_validate SUCCESSFUL");
      #endif
      return (uint_32)(cc_ptr->code_key = gen_ptr->key_code);
   } /* EndIf */

} /* EndBody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_driver_info_match
* Returned Value : TRUE for driver match, else FALSE
* Comments       :
*     Match device driver info with class etc. in device/interface
*     following the ordering in "USB Common Class Specification"
*     Rev. 1.0, August 18, 1998, p. 7
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
static boolean  usb_host_driver_info_match
   (
      /* [IN] USB device */
      DEV_INSTANCE_PTR           dev_ptr,

      /* [IN] Configuration number */
      INTERFACE_DESCRIPTOR_PTR   intf_ptr,

      /* [IN] TRUE=attach, FALSE=detach */
      USB_HOST_DRIVER_INFO_PTR   info_ptr
   )
{ /* Body */
   uint_16  info_Vendor, info_Product, dev_Vendor, dev_Product;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_driver_info_match");
   #endif
   
   info_Vendor = SHORT_UNALIGNED_LE_TO_HOST(info_ptr->idVendor);
   info_Product = SHORT_UNALIGNED_LE_TO_HOST(info_ptr->idProduct);

   /* If vendor and product are listed in table (non-zero) */
   if ((info_Vendor | info_Product) != 0) {
      dev_Vendor = SHORT_UNALIGNED_LE_TO_HOST(dev_ptr->dev_descriptor.idVendor);
      dev_Product = SHORT_UNALIGNED_LE_TO_HOST(dev_ptr->dev_descriptor.idProduct);

      if ((info_Vendor == dev_Vendor) &&
         (info_Product == dev_Product))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match PID, VID match");
         #endif
         return TRUE;
      } /* Endif */
   }

   /* note: zero value class in the device descriptor means
   ** that the class is defined in interface descriptor
   */
   if ((info_ptr->bDeviceClass == 0xFF) || /* if the device class is any OR */
      ((info_ptr->bDeviceClass ==             /* or the device class matches */
      dev_ptr->dev_descriptor.bDeviceClass) && 
      (dev_ptr->dev_descriptor.bDeviceClass != 0x00))) /* but it is not zero-value match */
   {
      if ((info_ptr->bDeviceSubClass ==
         dev_ptr->dev_descriptor.bDeviceSubClass) &&
         (info_ptr->bDeviceProtocol ==
         dev_ptr->dev_descriptor.bDeviceProtocol))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match class, match subclass, match protocol");
         #endif
         return TRUE;
      } /* Endif */
      
      if ((info_ptr->bDeviceSubClass ==
         dev_ptr->dev_descriptor.bDeviceSubClass) &&
         (info_ptr->bDeviceProtocol == 0xFF))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match class, match subclass");
         #endif
         return TRUE;
      }

      if ((info_ptr->bDeviceSubClass == 0xFF) && 
         (info_ptr->bDeviceProtocol ==
         dev_ptr->dev_descriptor.bDeviceProtocol))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match class, match protocol");
         #endif
         return TRUE;
      }

      if ((info_ptr->bDeviceSubClass == 0xFF) && 
         (info_ptr->bDeviceProtocol == 0xFF))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match class");
         #endif
         return TRUE;
      }
   }
   
   /* No Device match, try Interface */
   if ((info_ptr->bDeviceClass == 0xFF) || /* if the device class is any OR */
      ((info_ptr->bDeviceClass == /* or the class matches interface class */
      intf_ptr->bInterfaceClass)))
   {
      if ((info_ptr->bDeviceSubClass ==
         intf_ptr->bInterfaceSubClass) &&
         (info_ptr->bDeviceProtocol ==
         intf_ptr->bInterfaceProtocol))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface subclass, match interface protocol");
         #endif
         return TRUE;
      } /* Endif */
      
      if ((info_ptr->bDeviceSubClass ==
         intf_ptr->bInterfaceSubClass) &&
         (info_ptr->bDeviceProtocol == 0xFF))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface subclass, match interface protocol");
         #endif
         return TRUE;
      }

      if ((info_ptr->bDeviceSubClass == 0xFF) && 
         (info_ptr->bDeviceProtocol ==
         intf_ptr->bInterfaceProtocol))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface protocol");
         #endif
         return TRUE;
      }

      if ((info_ptr->bDeviceSubClass == 0xFF) && 
         (info_ptr->bDeviceProtocol == 0xFF))
      {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match interface class");
         #endif
         return TRUE;
      }
   }

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_driver_info_match interface No Match");
   #endif

   return FALSE;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_driver_info_scan
* Returned Value : none
* Comments       :
*     Call attach/detach callbacks for interfaces matching user-list items.
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
static void  usb_host_driver_info_scan
   (
      /* [IN] USB device */
      DEV_INSTANCE_PTR           dev_ptr,

      /* [IN] Configuration number */
      INTERFACE_DESCRIPTOR_PTR   intf_ptr,

      /* [IN] event causing this call */
      uint_32                    event_code
   )
{ /* Body */
   boolean                          match, matched = FALSE;
   USB_HOST_DRIVER_INFO_PTR         info_ptr;
   USB_HOST_STATE_STRUCT_PTR        host_struct_ptr;
   _usb_device_instance_handle      dev_handle;
   _usb_interface_descriptor_handle intf_handle;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_driver_info_scan");
   #endif

   if (dev_ptr->host == NULL)
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_host_driver_info_scan NULL host pointer");
      #endif
      return;

   }

   /* Get the host handle on which this device is on */
   host_struct_ptr = (USB_HOST_STATE_STRUCT_PTR)dev_ptr->host;

   /* Get the driver info for attach callback when a match occurs */
   info_ptr = host_struct_ptr->DEVICE_INFO_TABLE;
   dev_handle = (_usb_device_instance_handle)dev_ptr;
   intf_handle = (_usb_interface_descriptor_handle)intf_ptr;

   if (info_ptr) {

      while (usb_host_driver_info_nonzero(info_ptr) == TRUE) {
         match = usb_host_driver_info_match(dev_ptr, intf_ptr, info_ptr);

         if (match == TRUE) {
            matched = TRUE;
            /* The match has occurred so notify the application of such
            ** interface
            */
            info_ptr->attach_call(dev_handle, intf_handle, event_code);
         } /* Endif */

         info_ptr++;
      } /* EndWhile */

      if (!matched) {
         /* None of the registered driver info matched so check if a 
         ** default driver is installed 
         */
         if (info_ptr->attach_call) {
            /* The match has not occurred so notify the application of such
            ** interface via the default callback function
            */
            info_ptr->attach_call(dev_handle, intf_handle, event_code);
         } /* Endif */
      } /* Endif */
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_driver_info_scan SUCCESSFUL");
   #endif
   
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_driver_info_nonzero
* Returned Value : none
* Comments       :
*     Function to detect the all-zero end-of-list item.
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
static boolean  usb_host_driver_info_nonzero
   (
      /* [IN] USB device */
      USB_HOST_DRIVER_INFO_PTR           info_ptr
   )
{ /* Body */
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_driver_info_nonzero");
   #endif

   if (info_ptr->bDeviceClass != 0)
   {
      return TRUE;
   }

   if (info_ptr->bDeviceProtocol != 0)
   {
      return TRUE;
   }

   if (info_ptr->bDeviceSubClass != 0)
   {
      return TRUE;
   }

   if (info_ptr->idVendor[0] != 0)
   {
      return TRUE;
   }

   if (info_ptr->idVendor[1] != 0)
   {
      return TRUE;
   }

   if (info_ptr->idProduct[0] != 0)
   {
      return TRUE;
   }

   if (info_ptr->idProduct[1] != 0)
   {
      return TRUE;
   }

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_driver_info_nonzero FAILURE");
   #endif

   return FALSE;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_map_class_intf
* Returned Value : pointer to matching class map item, or NULL
* Comments       :
*           Map interface class etc. to a class driver table item.
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
static CLASS_MAP_PTR  usb_host_map_class_intf
   (
      /* interface's device/descriptor/pipe bundle */
      PIPE_BUNDLE_STRUCT_PTR  pbs_ptr
   )
{ /* Body */
   CLASS_MAP_PTR              map_ptr;
   INTERFACE_DESCRIPTOR_PTR   intf_desc;
   uint_32                    intf_class, map_class;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_map_class_intf");
   #endif

   intf_desc = (INTERFACE_DESCRIPTOR_PTR)pbs_ptr->intf_handle;

   for (map_ptr = &class_interface_map[0]; ; map_ptr++) {
      if (map_ptr->class_init == NULL) {
         map_ptr = NULL;
         break;
      } /* EndIf */
      intf_class = usb_hostdev_mask_class_etc(&intf_desc->bInterfaceClass,
         &map_ptr->class_code_mask);

      map_class = usb_hostdev_mask_class_etc(&map_ptr->class_code,
         &map_ptr->class_code_mask);

      if (intf_class != 0)
      {
         if (intf_class == map_class)
         {
            break;
         }
      }

   } /* EndFor */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_host_map_class_intf SUCCESSFUL");
   #endif

   return map_ptr;

} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_host_driver_info_register
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to register user's desired-interfaces array of structs.
*
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_host_driver_info_register
   (
      /* usb host */
      _usb_host_handle     host_handle,

      /* Device info table */
      pointer              info_table_ptr
   )
{ /* Body */

   USB_HOST_STATE_STRUCT_PTR host_struct_ptr;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_driver_info_register");
   #endif

   USB_lock();
   if (host_handle == NULL || info_table_ptr == NULL) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_driver_info_register, NULL pointers");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_UNKNOWN_ERROR);
   } /* Endif */

   host_struct_ptr = (USB_HOST_STATE_STRUCT_PTR)host_handle;
   host_struct_ptr->DEVICE_INFO_TABLE = info_table_ptr;

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_driver_info_register SUCCESSFUL");
   #endif
   return USB_OK;
} /* EndBody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_hostdev_select_config
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to tear down an old configuration, and set up
*     a new configuration with the same or different index.
*
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_hostdev_select_config
   (
      /* [IN] USB device */
      _usb_device_instance_handle   dev_handle,

      /* [IN] Configuration number */
      uint_8                        config_no
   )
{ /* Body */
   USB_STATUS              error;
   DEV_INSTANCE_PTR        dev;

   USB_lock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_select_config");
   #endif

   error = usb_hostdev_validate(dev_handle);
   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_select_config invalid device");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   } /* Endif */

   dev = (DEV_INSTANCE_PTR)dev_handle;

   if (config_no > dev->dev_descriptor.bNumConfigurations) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_select_config invalid config no.");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_CFIG_NUM);
   } /* Endif */

   if (dev->memlist != NULL){
      usb_dev_list_free_memlist(dev_handle);
   }

   dev->cfg_value = config_no;   /* requested config. number */
   dev->new_config = 1;          /* new config flag */
   dev->state = DEVSTATE_SET_CFG;
   error = _usb_host_ch9_set_configuration((_usb_device_instance_handle)dev, dev->cfg_value);

   if (error != USB_STATUS_TRANSFER_QUEUED) {
      dev->state = DEVSTATE_INITIAL;
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_select_config FAILED");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   }
   else
   {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_select_config SUCCESSFUL");
      #endif
      return USB_OK;
   }
} /* EndBody */



/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hostdev_delete_interface
* Returned Value : none
* Comments       :
*     Function to tear down an existing interface.
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
void  usb_hostdev_delete_interface
   (
      /* [IN] USB device */
      DEV_INSTANCE_PTR         dev,

      /* [IN] Interface */
      INTERFACE_DESCRIPTOR_PTR intf
   )
{ /* Body */
   DESCRIPTOR_UNION         desc;
   DEV_MEMORY_PTR           mem1, mem2;
   GENERAL_CLASS_PTR        class_ptr1, class_ptr2;
   PIPE_BUNDLE_STRUCT_PTR   pbs_ptr;
   uint_8                   intf_no;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_delete_interface");
   #endif
   
   for (intf_no = 0; intf_no < dev->num_of_interfaces; intf_no++) {
      desc.intf = dev->intf_descriptor[intf_no];

      if (desc.intf == NULL)
      {
         continue;
      }

      /* Equal interface numbers (alternates don't count here) */
      if (intf->bInterfaceNumber != desc.intf->bInterfaceNumber)
      {
         continue;
      }

      /* Find pipe bundle for this interface on memory list */
      for (mem1 = dev->memlist; mem1 != NULL; mem1 = mem1->next) {
         if (mem1->blktype != USB_MEMTYPE_PIPES)
         {
            continue;
         }

         pbs_ptr = (PIPE_BUNDLE_STRUCT_PTR) (mem1->payload.data + mem1->offset);

         if (intf != pbs_ptr->intf_handle)
         {
            continue;
         }

         /* Unlink pipe bundle from memory list */
         mem2 = dev->memlist;
         if (mem1 == mem2) {
            dev->memlist = mem1->next;
         } else {

            while (mem2->next != mem1)
            {
               mem2 = mem2->next;
            }

            mem2->next = mem1->next;
         } /* EndIf */

         /* Close pipes, free memory list item */
         usb_dev_list_close_pipe_bundle(pbs_ptr);
         USB_mem_free(mem1);
         dev->intf_descriptor[intf_no] = NULL;
         intf_no = dev->num_of_interfaces;
         break;
      } /* EndFor */

      /* Find class-interface on memory list */
      for (mem1 = dev->memlist; mem1 != NULL; mem1 = mem1->next) {
         if (mem1->blktype != USB_MEMTYPE_CLASS)
         {
            continue;
         }

         class_ptr1 = (GENERAL_CLASS_PTR) (mem1->payload.data + mem1->offset);

         if (intf != class_ptr1->intf_handle)
         {
            continue;
         }

         /* Call deinit */
         if (class_ptr1->class_deinit != NULL) {
             class_ptr1->class_deinit((_usb_class_intf_handle)class_ptr1);
         }

         /* Invalidate class_intf */
         class_ptr1->key_code = 0;
         /* Unlink class-intf from memory list */
         mem2 = dev->memlist;
         if (mem1 == mem2) {
            dev->memlist = mem1->next;
         } else {

            while (mem2->next != mem1)
            {
               mem2 = mem2->next;
            }

            mem2->next = mem1->next;
         } /* EndIf */

         /* TODO: delete interface event */

         /* Unlink class-intf from class's list */
         class_ptr2 = class_ptr1->anchor; /* A(anchor) */
         if (class_ptr2->next == class_ptr1) {
            class_ptr2->next = class_ptr1->next;
         } else {

            while (class_ptr2->next != class_ptr1)
            {
               class_ptr2 = class_ptr2->next;
            }

            class_ptr2->next = class_ptr1->next;
         } /* EndIf */

         /* Free memory list item */
         USB_mem_free(mem1);
         intf_no = dev->num_of_interfaces;
         break;
      } /* EndFor */

   } /* EndFor */
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_delete_interface SUCCESSFUL");
   #endif
   
} /* EndBody */



/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hostdev_mask_class_etc
* Returned Value : masked class/sub-class/protocol
* Comments       :
*     It is assumed that class, sub-class, and protocol are
*     successive uint-8 values (as in a USB descriptor),
*     and likewise the masks to be ANDed with them.
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
static uint_32  usb_hostdev_mask_class_etc
   (
      /* [IN] pointer to class etc. */
      uint_8_ptr      csp_ptr,

      /* [IN] pointer to masks */
      uint_8_ptr      msk_ptr
   )
{ /* Body */
   uint_32  res;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_mask_class_etc");
   #endif

   /* MSB of result = class */
   res = (uint_32)((*csp_ptr++) & (*msk_ptr++));

   /* 2nd byte of result = sub-class */
   res = (res << 8);
   res |= (uint_32) ((*csp_ptr++) & (*msk_ptr++));

   /* LSB of result = sub-class */
   res = (res << 8);
   res |= (uint_32) ((*csp_ptr) & (*msk_ptr));

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_mask_class_etc SUCCESSFUL");
   #endif
   
   return res;

} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hostdev_open_pipe
* Returned Value : pipe handle + USB_OK, or error status
* Comments       :
*     Function to open a pipe for an endpoint.  Note that endpoints
*     following an interface are numbered 1, 2, 3, ... bNumEndpoints,
*     where the number of endpoints is in the interface descriptor.
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
static USB_STATUS  usb_hostdev_open_pipe
   (
      /* [IN] USB device */
      _usb_device_instance_handle    dev_handle,

      /* [IN] the device instance or NULL to search the device config */
      _usb_interface_descriptor_handle intf_handle,

      /* [IN] Only FLAG=1 is presently defined (= dont't send empty packet) */
      uint_32                        flags,

      /* [IN] Endpoint number 0, 1, ... N */
      uint_8                         ep_num,

      /* [OUT] Handle of opened pipe */
      _usb_pipe_handle _PTR_         pipe_handle_ptr
   )
{ /* Body */
   DESCRIPTOR_UNION         desc;
   DEV_INSTANCE_PTR         dev;
   PIPE_INIT_PARAM_STRUCT   pipe_init_params;
   USB_STATUS               error;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_open_pipe");
   #endif

   error = _usb_hostdev_get_descriptor(dev_handle,
      intf_handle,
      USB_DESC_TYPE_EP,
      ep_num,
      0,
      (pointer _PTR_)&desc);

   if (error != USB_OK)
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_hostdev_open_pipe failed");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   }

   dev = (DEV_INSTANCE_PTR)dev_handle;

   pipe_init_params.G.DEV_INSTANCE = dev_handle;
   pipe_init_params.G.MAX_PACKET_SIZE = (uint_16)(SHORT_UNALIGNED_LE_TO_HOST(desc.ndpt->wMaxPacketSize) & PACKET_SIZE_MASK);
   pipe_init_params.G.NAK_COUNT = USBCFG_DEFAULT_MAX_NAK_COUNT;
   pipe_init_params.G.FIRST_FRAME = pipe_init_params.G.FIRST_UFRAME = 0;
   pipe_init_params.G.FLAGS = flags;
   pipe_init_params.G.DEVICE_ADDRESS = ((DEV_INSTANCE_PTR)dev_handle)->address;
   pipe_init_params.G.ENDPOINT_NUMBER = (uint_8)(desc.ndpt->bEndpointAddress & ENDPOINT_MASK);
   pipe_init_params.G.DIRECTION = (uint_8)((desc.ndpt->bEndpointAddress & IN_ENDPOINT) ? USB_RECV : USB_SEND);
   pipe_init_params.G.tr_list_ptr = NULL;

   switch (desc.ndpt->bmAttributes & EP_TYPE_MASK) {
      case ISOCH_ENDPOINT:
         pipe_init_params.G.PIPETYPE = USB_ISOCHRONOUS_PIPE;
         break;
      case BULK_ENDPOINT:
         pipe_init_params.G.PIPETYPE = USB_BULK_PIPE;
         break;
      case IRRPT_ENDPOINT:
         pipe_init_params.G.PIPETYPE = USB_INTERRUPT_PIPE;
         break;
      case CONTROL_ENDPOINT:
      default:
         pipe_init_params.G.PIPETYPE = USB_CONTROL_PIPE;
         break;
   } /* EndSwitch */

   pipe_init_params.G.SPEED = dev->speed;

   /* Following is taken from the USB 2.0 Specification, bInterval field description of endpoint descriptor */
   if (pipe_init_params.G.PIPETYPE == USB_ISOCHRONOUS_PIPE) {
      pipe_init_params.G.INTERVAL = 1 << (desc.ndpt->iInterval - 1);
   }
   else if ((pipe_init_params.G.PIPETYPE == USB_INTERRUPT_PIPE) && (pipe_init_params.G.SPEED == USB_SPEED_HIGH)) {
      pipe_init_params.G.INTERVAL = 1 << (desc.ndpt->iInterval - 1);
   }
   else {
      pipe_init_params.G.INTERVAL = desc.ndpt->iInterval;
   }

   pipe_init_params.G.TRS_PER_UFRAME = 1;
   if ((pipe_init_params.G.PIPETYPE == USB_ISOCHRONOUS_PIPE) ||
      (pipe_init_params.G.PIPETYPE == USB_INTERRUPT_PIPE))
   {
      switch (SHORT_UNALIGNED_LE_TO_HOST(desc.ndpt->wMaxPacketSize) & ADDITIONAL_MASK) {
         case TWO_ADDITIONAL:
            pipe_init_params.G.TRS_PER_UFRAME++;
         case ONE_ADDITIONAL:
            pipe_init_params.G.TRS_PER_UFRAME++;
            break;
         default:
            break;
      } /* EndSwitch */
   } /* Endif */

   pipe_init_params.G.HUB_DEVICE_ADDR = 0;
   pipe_init_params.G.HUB_PORT_NUM = 0;
   if (dev->hub_no !=0 && dev->speed != USB_SPEED_HIGH)
   {
       pipe_init_params.G.HUB_DEVICE_ADDR = dev->hub_no;
       pipe_init_params.G.HUB_PORT_NUM = dev->port_no;
   }
   error = _usb_host_open_pipe(dev->host, &pipe_init_params, pipe_handle_ptr);

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_open_pipe SUCCESSFUL");
   #endif
      
   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_hostdev_select_interface
* Returned Value : interface struct + USB_OK, or error status
* Comments       :
*     Function to tear down old interface, and set up
*     a new one with the same or different index/alternate.
*     For each interface, only one of its alternates
*     can be selected per USB spec.  Also per spec, an endpoint
*     can be in only one interface (though it may exist in
*     several alternates of that interface).
*
*END*--------------------------------------------------------------------*/
USB_STATUS  _usb_hostdev_select_interface
   (
      /* [IN] USB device */
      _usb_device_instance_handle      dev_handle,

      /* [IN] Interface to be selected */
      _usb_interface_descriptor_handle intf_handle,

      /* [OUT] Initialized class-specific interface struct */
      pointer                          class_intf_ptr
   )
{ /* Body */
   CLASS_CALL_STRUCT_PTR         class_ptr = NULL;
   DESCRIPTOR_UNION              desc;
   DEV_INSTANCE_PTR              dev;
   USB_HOST_DRIVER_INFO_PTR      info_ptr;
   USB_HOST_STATE_STRUCT_PTR     host_struct_ptr;
   DEV_MEMORY_PTR                mem1, mem2;
   INTERFACE_DESCRIPTOR_PTR      intf;
   CLASS_MAP_PTR                 class_map;
   _usb_pipe_handle              pipe_handle;
   PIPE_BUNDLE_STRUCT_PTR        pbs_ptr;
   USB_STATUS                    error;
   uint_32                       block_size;
   uint_8                        ep_num, intf_no;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_select_interface");
   #endif
   
   USB_lock();
   error = usb_hostdev_validate (dev_handle);

   if (error != USB_OK) {
      goto BadExit;
   }

   dev = (DEV_INSTANCE_PTR)dev_handle;
   intf = (INTERFACE_DESCRIPTOR_PTR)intf_handle;

   /* Get the host handle on which this device is on */
   host_struct_ptr = (USB_HOST_STATE_STRUCT_PTR)dev->host;

   /* Get the driver info for attach callback when a match occurs */
   info_ptr = (USB_HOST_DRIVER_INFO_PTR)\
      host_struct_ptr->DEVICE_INFO_TABLE;

   if ((intf->bDescriptorType != USB_DESC_TYPE_IF) ||
         (intf->bLength != USB_DESC_LEN_IF))
   {
      error = USBERR_NO_INTERFACE;
      goto BadExit;
   } /* EndIf */

   /* If an interface was previously selected, tear it down */
   usb_hostdev_delete_interface(dev, intf);

   /* Check that there is an available interface pointer */
   for (intf_no = 0; ;intf_no++) {
      if (intf_no >= dev->num_of_interfaces) {
         error = USBERR_NO_INTERFACE;
         goto BadExit;
      } /* EndIf */

      if (dev->intf_descriptor[intf_no] == NULL) {
         break;
      }

   } /* EndFor */

   /* Create pipe bundle for memory list */
   mem1 = dev->memlist;

   if (mem1 == NULL) { /* Must be at least config on list */
      error = USBERR_NO_INTERFACE;
      goto BadExit;
   } /* EndIf */

   while (mem1->next != NULL) /* Scan to last existing item */
   {
      mem1 = mem1->next;
   }

   block_size = sizeof(PIPE_BUNDLE_STRUCT) +
      sizeof(_usb_pipe_handle) * (intf->bNumEndpoints - 1);

   error = usb_dev_list_get_mem(dev,
      block_size,
      USB_MEMTYPE_PIPES,
      1,
      &mem2);

   if (error != USB_OK) {
      error = USBERR_GET_MEMORY_FAILED;
      goto BadExit;
   } /* EndIf */

   /* Locate interface/alternate in devices configuration */
   error = _usb_hostdev_get_descriptor(dev_handle,
      NULL,
      USB_DESC_TYPE_IF,
      intf->bInterfaceNumber,
      intf->bAlternateSetting,
      (pointer _PTR_)&desc);

   if (error != USB_OK){
      goto BadExit;
   }

   /* Locate each endpoint descriptor, open a pipe for it */
   pbs_ptr = (PIPE_BUNDLE_STRUCT_PTR) (mem2->payload.data + mem2->offset);
   for (ep_num = 1; ep_num <= intf->bNumEndpoints; ep_num++) {
      error = usb_hostdev_open_pipe (dev_handle, intf_handle,
         0, ep_num, &pipe_handle);

      /* If pipe not OK, unlink bundle from list and delete it */
      if (error != USB_OK) {
         mem1->next = NULL;  /* snip off list */
         USB_mem_free(mem2);
         goto BadExit;
      } /* EndIf */
      pbs_ptr->pipe_handle[ep_num-1] = pipe_handle;
   } /* EndFor */

   pbs_ptr->dev_handle = dev_handle;
   pbs_ptr->intf_handle = intf_handle;
   dev->intf_descriptor[intf_no] = intf;

   if (usb_host_driver_info_nonzero(info_ptr)) {

      /* Map interface to class driver, get & initialize driver struct */
      error = USBERR_NO_DEVICE_CLASS;  /* Assume the worst */

      class_map = usb_host_map_class_intf(pbs_ptr);
      if (class_map == NULL) {
         goto BadExit;
      }

      class_ptr = (CLASS_CALL_STRUCT_PTR)class_intf_ptr;
      if (class_ptr == NULL) {
         goto BadExit;
      }

      /* Don't get new struct for associated interfaces */
      error = usb_hostdev_get_class (dev_handle,
         class_map->intf_struct_size,
         (pointer _PTR_)&class_ptr->class_intf_handle);

      if (error != USB_OK) {
         goto BadExit;
      }

      class_map->class_init(pbs_ptr, class_ptr);

      if (class_ptr->code_key == 0){
         goto BadExit;
      }

   } /* Endif */

   /* Set interface on the device */
   dev->state = DEVSTATE_SET_INTF;
   error = _usb_host_ch9_set_interface((_usb_device_instance_handle)dev, intf->bAlternateSetting,
      intf->bInterfaceNumber);
      
   if (error != USB_STATUS_TRANSFER_QUEUED)
   {
      dev->state = DEVSTATE_INITIAL;
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_select_interface FAILED");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   }
   else
   {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_select_interface SUCCESSFUL");
      #endif
      return USB_OK;
   }

BadExit:
   if (error ==USB_OK) {
      error = USBERR_NO_DEVICE_CLASS;
   }
   
   if (class_ptr != NULL) {
      class_ptr->class_intf_handle = NULL;
      class_ptr->code_key = 0;
   }
   
   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_hostdev_select_interface bad exit");
   #endif

   return USB_log_error(__FILE__,__LINE__,error);

} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_hostdev_tr_init
* Returned Value : Initialize TR with globally unique index
* Comments       :
*     To ensure that a new TR_STRUCT is used by the system for
*     each new transaction, it is essential to have a distinct
*     TR_INDEX value.  Completed transactions have TR_INDEX
*     cleared to zero, it is invalid for a new transaction.
*
*END*--------------------------------------------------------------------*/
void usb_hostdev_tr_init
   (
      /* [OUT] initialized TR_INIT_PARAM_STRUCT */
      TR_INIT_PARAM_STRUCT_PTR   tr_ptr,

      /* [IN] callback to call after completion */
      tr_callback                callback,

      /* [IN] the param to pass back to the callback function */
      pointer                    callback_param
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_tr_init");
   #endif
   USB_lock();

   do {
      tr_index++;
   } while (tr_index == 0);

   *tr_ptr = tr_prototype;
   tr_ptr->G.TR_INDEX = tr_index;
   tr_ptr->G.CALLBACK = callback;
   tr_ptr->G.CALLBACK_PARAM = callback_param;

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_tr_init SUCCESSFUL");
   #endif
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_hostdev_get_speed
* Returned Value : Device speed
* Comments       :
*     Returns USB_SPEED_LOW, USB_SPEED_HIGH or USB_SPEED_FULL
*
*END*--------------------------------------------------------------------*/

uint_32 _usb_hostdev_get_speed
   (
      /* [IN] USB device */
      _usb_device_instance_handle      dev_handle
   )
{ /* Body */
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_hostdev_get_speed SUCCESSFUL");
   #endif
   return ((DEV_INSTANCE_PTR)dev_handle)->speed;
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/tcp.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcp.c$
* $Version : 3.8.17.0$
* $Date    : Jun-27-2012$
*
* Comments:
*
*   For more details, refer to RFC793 (which contains some errors)
*   and RFC1122 (which documents those errors and adds lots more
*   useful details).
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "ticker.h"     /* for timer definitions */
#include "tcpip.h"      /* for TCPIP definitions */
#include "ip_prv.h"     /* for IP internal definitions */
#include "tcp_prv.h"    /* for TCP internal definitions */
#include "socket.h"     /* used by TCP_Process_getname */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Init
* Returned Values : int_32
* Comments        :
*
*  Initialize the TCP layer.
*  Returns 0 or positive error number
*
*END*-----------------------------------------------------------------*/

uint_32 TCP_Init
   (
      void
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;

    uint_32              status;

   tcp_cfg = RTCS_mem_alloc_zero(sizeof(TCP_CFG_STRUCT));
   if (tcp_cfg == NULL)  {
      return RTCSERR_OUT_OF_MEMORY;
   }

   _mem_set_type(tcp_cfg, MEM_TYPE_TCP_CFG_STRUCT);

   RTCS_setcfg(TCP,tcp_cfg);

   tcp_cfg->qh           = NULL;
   tcp_cfg->qhead        = &tcp_cfg->qh;
   tcp_cfg->lasttime     = 0;
   tcp_cfg->TCBhead      = NULL;
   tcp_cfg->Rchunkhead   = NULL;
   tcp_cfg->SbufNodehead = NULL;
   tcp_cfg->Rchunkfree   = NULL;
   tcp_cfg->SbufNodefree = NULL;
   tcp_cfg->next_port    = IPPORT_USERRESERVED;
   tcp_cfg->acktq        = NULL;
   tcp_cfg->xmittq       = NULL;
   tcp_cfg->sndtq        = NULL;
   tcp_cfg->rcvtq        = NULL;

   tcp_cfg->DEFER_TAIL   = &tcp_cfg->DEFER_HEAD;

   tcp_cfg->CONN_COUNT   = 0;
   tcp_cfg->HALF_OPEN_TCB_COUNT = 0;

    /*
    ** Global used for TCP_RTO_MIN because we may want to let our
    ** users adjust this.
    */
     _TCP_rto_min = TCP_RTO_MIN;

    /*
    ** Install the TCP tick server
    */
    TCP_tick = TCP_Tick_server;

#if RTCSCFG_ENABLE_IP4
    IP_open(IPPROTO_TCP, TCP4_Service_packet, tcp_cfg, &status);
    if(status != RTCS_OK)
    {
        return status;
    }
#endif /* RTCSCFG_ENABLE_IP4 */


#if RTCSCFG_ENABLE_IP6
    IP6_open(IPPROTO_TCP, TCP6_Service_packet, tcp_cfg, &status);
#endif /* RTCSCFG_ENABLE_IP6 */


    return status;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Event
* Returned Values : None.
* Comments        :
*
*  Signal the occurrence of an event
*   (of the type which the user (control/wait task) may wait upon).
*
*  This is used for non-error events; error/terminating events should
*   call TCP_Close_TCB(), closing the connection.
*
*END*-----------------------------------------------------------------*/

void TCP_Event
   (
      TCB_STRUCT_PTR tcb,     /* IN/OUT - TCP context */
      int_16         event    /* IN     - event that occurred */
   )
{ /* Body */
    RTCSLOG_FNE3(RTCSLOG_FN_TCP_Event, tcb, event);

   tcb->status |= event;
   switch ( event ) {

      case TCPS_FINRECV:
      case TCPS_FINACKED:
         if ( (~tcb->status & (TCPS_FINRECV|TCPS_FINACKED)) == 0 ) {
            tcb->status |= TCPS_FINDONE;
            event |= TCPS_FINDONE;      /* for Signal()'s */
         } /* Endif */
         break;

      default:
         /* Do nothing */
         break;

   } /* End Switch */

    RTCSLOG_FNX1(RTCSLOG_FN_TCP_Event);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_create
* Returned Values : None.
* Comments        :
*
*  Called when the application creates a SOCK_STREAM socket.
*
*  This function allocates a TCB.
*
*END*-----------------------------------------------------------------*/

void TCP_Process_create
   (
      TCP_PARM_PTR   req_ptr     /* IN/OUT - the open request */
   )
{ /* Body */
   TCB_STRUCT_PTR tcb;     /* New TCB */

   tcb = (TCB_STRUCT_PTR)RTCS_mem_alloc_zero(sizeof(TCB_STRUCT));

   if (tcb == NULL) {
      RTCS_log_error(ERROR_TCP, RTCSERR_TCP_OPEN_FAILED, 0, 0, 0);
      RTCSCMD_complete(req_ptr, RTCSERR_OUT_OF_MEMORY);
      return;
   } /* Endif */

   _mem_set_type(tcb, MEM_TYPE_TCB);

   tcb->VALID = TCB_VALID_ID;
   tcb->SOCKET = req_ptr->SOCKET;

   /* Local and remote ports */
   tcb->local_port = 0;
   tcb->local_host = INADDR_ANY;
   tcb->remote_port= 0;
   tcb->remote_host = INADDR_ANY;

#if RTCSCFG_ENABLE_IP6
   IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(tcb->local_ipv6_host));
   IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(tcb->remote_ipv6_host));
#endif

   req_ptr->TCB_PTR = tcb;
   RTCSCMD_complete(req_ptr, RTCS_OK);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_bind46
* Returned Values : None.
* Comments        :
*
*  Called when the application binds a SOCK_STREAM socket.
*
*  This function chooses a local port for a TCB.
*
*END*-----------------------------------------------------------------*/


void TCP_Process_bind
    (
        TCP_PARM_PTR   req_ptr     /* IN/OUT - the bind request */
    )
{ /* Body */
    TCP_CFG_STRUCT_PTR   tcp_cfg;          /* TCP Layer constants */
    TCB_STRUCT_PTR       tcb,
                         tcb2;             /* Temporary pointer */


    boolean             local_host_zero =0;
    boolean             local_host_eq=0;
    boolean             local_port_eq=0;
    boolean             remote_port_zero=0;
    boolean             local_result =1;

    tcp_cfg = RTCS_getcfg(TCP);
    tcb = req_ptr->TCB_PTR;

    if ( tcb == NULL )
    {
        RTCSCMD_complete(req_ptr, RTCSERR_TCP_CONN_RLSD);
        return;
    }


    /* setup tcb localhost address */
#if RTCSCFG_ENABLE_IP6
    if(req_ptr->AF == AF_INET)
    {
#endif

        tcb->local_host = req_ptr->IP_ADDR;

#if RTCSCFG_ENABLE_IP6
    }
    else if(req_ptr->AF == AF_INET6)
    {
        IN6_ADDR_COPY(&(req_ptr->IPV6_ADDR),&(tcb->local_ipv6_host));
        /* add binded scope_id here */
        tcb->if_scope_id = req_ptr->IF_SCOPE_ID;
    }
    else
    {
        RTCS_log_error(ERROR_TCP, RTCSERR_TCPIP_INVALID_ARGUMENT, 0, 0, 0);
    }
#endif

    /* setup tcb localhost port */
    tcb->local_port = req_ptr->TCP_PORT;

   /*
   ** Scan for available port if none specified
   */
   if ( tcb->local_port == 0 ) {
      uint_16  first_port = tcp_cfg->next_port;

        do {

            tcb->local_port = tcp_cfg->next_port;
            if (--tcp_cfg->next_port < IPPORT_RESERVED)
            {
                tcp_cfg->next_port = IPPORT_USERRESERVED;
            } /* Endif */

            if (tcp_cfg->next_port == first_port)
            {
                RTCS_log_error(ERROR_TCP, RTCSERR_TCP_NO_MORE_PORTS, 0, 0, 0);
                RTCSCMD_complete(req_ptr, RTCSERR_TCP_NO_MORE_PORTS);
                return;
            } /* Endif */

            /* is port used? */
#if RTCSCFG_ENABLE_IP6
            if(req_ptr->AF == AF_INET)
            {
#endif
                for (
                        tcb2=tcp_cfg->TCBhead;
                  (tcb2 != NULL) &&((tcb2->local_host &&(tcb2->local_host != tcb->local_host)) || (tcb2->local_port != tcb->local_port)||(tcb2->af != req_ptr->AF ));
                        tcb2=tcb2->next
                    )
                {
                } /* Endfor */

#if RTCSCFG_ENABLE_IP6
            }
            else if(req_ptr->AF == AF_INET6)
            {
                for (
                        tcb2=tcp_cfg->TCBhead;

                        (tcb2 != NULL) &&
                        (
                            (

                                (!IN6_ARE_ADDR_EQUAL(&(tcb2->local_ipv6_host),            &in6addr_any )) &&
                                (!IN6_ARE_ADDR_EQUAL(&(tcb2->local_ipv6_host), &(tcb->local_ipv6_host) ))
                            )||
                            (tcb2->local_port != tcb->local_port)||
                            (tcb2->af != req_ptr->AF )||
                            (tcb2->if_scope_id != req_ptr->IF_SCOPE_ID)
                        );
                        tcb2=tcb2->next
                   )
                {
                } /* Endfor */
            }
#endif

      } while (tcb2 != NULL);

      /*
      ** assuming no more than (IPPORT_USERRESERVED -
      **  IPPORT_RESERVED) ports will ever be opened at once,
      **  this is currently 5000-1024 = 3976 ports    (+1)
      */

    }
    else
    {

      /* is requested port used? */
#if RTCSCFG_ENABLE_IP6
        if(req_ptr->AF == AF_INET)
        {
#endif
            for(
                    tcb2=tcp_cfg->TCBhead;
                    tcb2 != NULL &&
                    (
                        (
                            tcb2->local_host &&
                            tcb2->local_host != tcb->local_host
                        )                                       ||
                        (tcb2->local_port != tcb->local_port)   ||
                        (tcb2->remote_port != 0)                ||
                        (tcb2->af != req_ptr->AF )
                    );
                    tcb2=tcb2->next
               )
            {
            } /* Endfor */
#if RTCSCFG_ENABLE_IP6
        }
        else if(req_ptr->AF == AF_INET6)
        {


            for(
                    tcb2=tcp_cfg->TCBhead;
                    (tcb2 != NULL) &&
                    (
                        (
                            (!IN6_ARE_ADDR_EQUAL(&(tcb2->local_ipv6_host),            &in6addr_any ))&&
                            (!IN6_ARE_ADDR_EQUAL(&(tcb2->local_ipv6_host), &(tcb->local_ipv6_host) ))
                        ) ||
                        (tcb2->local_port != tcb->local_port) ||
                        (tcb2->remote_port != 0)||
                        (tcb2->af != req_ptr->AF )||
                        (tcb2->if_scope_id != req_ptr->IF_SCOPE_ID)
                    );
                    tcb2=tcb2->next
               )
            {
            }

        }
#endif


      if (tcb2 != NULL) {
         RTCS_log_error(ERROR_TCP, RTCSERR_TCP_ADDR_IN_USE, 0, 0, 0);
         RTCSCMD_complete(req_ptr, RTCSERR_TCP_ADDR_IN_USE);
         return;
      } /* Endif */

   } /* Endif */

   tcb->state = BOUND;
   /*BIND table will provide bind family information */
   tcb->af = req_ptr->AF;
   tcb->next = tcp_cfg->TCBhead;
   tcp_cfg->TCBhead = tcb;

   RTCSCMD_complete(req_ptr, RTCS_OK);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_open
* Returned Values : None.
* Comments        :
*
*  Process TcpOpen() requests, within TCP server. Support IPv4 and IPv6
*
*  On successful creation of the TCB and associated buffers:
*
*     if this is an active open, the TCB state is set to SYN_SENT;
*     if this is a passive open, the TCB state is set to LISTEN.
*
*END*-----------------------------------------------------------------*/
void TCP_Process_open
   (
      TCP_PARM_PTR   req_ptr     /* IN/OUT - the open request */
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;          /* TCP Layer constants */
   TCP_OPTIONS_PTR      coptions;         /* list of TCP options */
   TCB_STRUCT_PTR       tcb,              /* Newly allocated TCB */
                        tcb2;             /* Temporary pointer */
   uint_32              sbsize,           /* Send buffer size (bytes) */
                        rbsize;           /* Receive buffer size (bytes) */
   _ip_address          remote_host_v4;   /* remote IPv4 address */
   #if RTCSCFG_ENABLE_IP6
   in6_addr             remote_host_v6;   /* remote IPv6 address */
   #endif
   uint_32              result;           /* Returned status */

   tcp_cfg = RTCS_getcfg(TCP);
   tcb = req_ptr->TCB_PTR;

   if ( tcb == NULL ) {
      TCP_PO_FAIL (RTCSERR_TCP_CONN_RLSD);
   }

   tcp_cfg->CONN_COUNT++;

   /*
   ** Process TCP options
   */
   coptions = req_ptr->OPTIONS_PTR;

   tcb->sndrtomax = 2 * TCP_MSL;

   /*
   ** determine if the bypass of checksums are set
   */
   tcb->bypass_rx_chksum = _TCP_bypass_rx;
   tcb->bypass_tx_chksum = _TCP_bypass_tx;

   /* tcpsecure advice in draft-ietf-tcpm-tcpsecure-00.txt */
    tcb->tcpsecuredraft0 = coptions->tcpsecuredraft0;

    /* Send ring buffer size */
   if ( coptions->tbsize >= 0 ) {
      sbsize = (uint_32)coptions->tbsize;
   } else {
      sbsize = TCP_DEFAULT_SBSIZE;
   } /* Endif */

   /* Receive ring buffer size */
   if ( coptions->rbsize >= 0 ) {
      rbsize = (uint_32)coptions->rbsize;
   } else {
      rbsize = TCP_DEFAULT_RBSIZE;
   } /* Endif */

   /* User timeout (R1) */
   if ( coptions->utimeout >= 0 ) {
      tcb->sndto_1 = coptions->utimeout;
   } else {
      tcb->sndto_1 = 0;
   } /* Endif */

   /* Connection timeout (R2) */
   if ( coptions->timeout > 0 ) {
      tcb->sndto_2 = coptions->timeout;
   } else {
      tcb->sndto_2 = 2 * tcb->sndrtomax;
   } /* Endif */

   /* Initial retransmission timeout */
   if ( coptions->rto > 0 ) {
      tcb->sndrto = coptions->rto;
   } else {
      tcb->sndrto = TCP_INITIAL_RTO_DEFAULT;
   } /* Endif */

   /* Maximum retransmission timeout */
   if ( coptions->maxrto > 0 ) {
      tcb->sndrtomax = coptions->maxrto;
   } /* Endif */

   /* Maximum receive window size */
   if ( coptions->maxrcvwnd > 0 ) {
      tcb->rcvwndmax = coptions->maxrcvwnd;
   } else {
      tcb->rcvwndmax = 0xffff;
   } /* Endif */

   /* INTERNET type of service */
   if ( coptions->tos > 0 ) {
      tcb->tos = coptions->tos & 7;
   } else {
      tcb->tos = 0;
   } /* Endif */

   /* INTERNET precedence */
   if ( coptions->precede != 0xFF ) {
      tcb->tos &= 0xE0;
      tcb->tos |= coptions->precede << 5;
   } /* Endif */

   /* Remote host and port */
#if RTCSCFG_ENABLE_IP4
   if(req_ptr->AF == AF_INET)
   {
        remote_host_v4 = coptions->remhost;
   }
   #if RTCSCFG_ENABLE_IP6
   else
   #endif
#endif
#if RTCSCFG_ENABLE_IP6
   if(req_ptr->AF == AF_INET6)
   {
        IN6_ADDR_COPY(&(coptions->remhost_ipv6),&(remote_host_v6));
   }
#endif /* RTCSCFG_ENABLE_IP6 */

   tcb->remote_port = coptions->remport;
   /* Keepalive timeout */
   if ( coptions->keepalive > 0 ) {
      tcb->keepaliveto = coptions->keepalive * 60000L;
   } else {
      tcb->keepaliveto = 0;
   } /* Endif */

   /* TIME_WAIT timeout */
   if ( coptions->timewaitto ) {
      tcb->timewaitto = coptions->timewaitto;
   } else {
      tcb->timewaitto = TCP_WAITTIMEOUT;
   } /* Endif */

   /* Active or passive open? */
   if ( coptions->active ) {
      tcb->options |= TCPO_ACTIVE;
   } else {
      tcb->options &= ~TCPO_ACTIVE;
   } /* Endif */

   /* Non-blocking or blocking commands */
   if ( coptions->nowait ) {
      tcb->options |= TCPO_NOWAIT;
   } else {
      tcb->options &= ~TCPO_NOWAIT;
   } /* Endif */

   /* Use Nagle algorithm? */
   if ( coptions->nonagle ) {
      tcb->options |= TCPO_NONAGLE;
   } else {
      tcb->options &= ~TCPO_NONAGLE;
   } /* Endif */

   /* Allow switch from ring buffer to user buffer? */
   if ( coptions->noswrbuf ) {
      tcb->options |= TCPO_NOSWITCH;
   } else {
      tcb->options &=~TCPO_NOSWITCH;
   } /* Endif */

   /* delay ack timeout */
   tcb->delayackto = coptions->delayackto;

   /* Process option results */

    if ( tcb->options & TCPO_ACTIVE )
    {
#if RTCSCFG_ENABLE_IP4
        if(req_ptr->AF == AF_INET)
        {
            if ( remote_host_v4 == INADDR_ANY || tcb->remote_port == 0 )
            {
                TCP_PO_FAIL(RTCSERR_TCPIP_DESTADDR_REQUIRED);
            } /* Endif */
            if ( IN_MULTICAST(remote_host_v4) )
            {
                TCP_PO_FAIL(RTCSERR_TCP_ADDR_NA);
            } /* Endif */
        }
    #if RTCSCFG_ENABLE_IP6
        else
    #endif
#endif
#if RTCSCFG_ENABLE_IP6
        if(req_ptr->AF == AF_INET6)
        {
            if (IN6_ARE_ADDR_EQUAL(&remote_host_v6, &in6addr_any)|| (tcb->remote_port == 0))
            {
                TCP_PO_FAIL(RTCSERR_TCPIP_DESTADDR_REQUIRED);
            } /* Endif */
            if (IN6_IS_ADDR_MULTICAST(&remote_host_v6))
            {
                TCP_PO_FAIL(RTCSERR_TCP_ADDR_NA);
            } /* Endif */
        }
#endif /* RTCSCFG_ENABLE_IP6 */
   } /* Endif */



   /*  Supports windows of up to 16 bits in size*/
   if ( tcb->rcvwndmax > 0xffff ) {
      tcb->rcvwndmax = 0xffff;
   } /* Endif */



   /*
   ** Verify that requested ports/hosts combination, if fully
   **  specified, isn't already used
   */
#if RTCSCFG_ENABLE_IP4
    if(req_ptr->AF == AF_INET)
    {
        if ( tcb->local_port != 0 && tcb->remote_port != 0 && remote_host_v4 != INADDR_ANY)
        {
            for (   tcb2=tcp_cfg->TCBhead;
                    tcb2 != NULL &&                            /*   Can ignore this TCB if its:  */
                  ( tcb2->local_port != tcb->local_port    ||  /*   Local port not a match    OR */
                    tcb2->remote_port == 0                 ||  /*   Remote port not specified OR */
                    tcb2->remote_port != tcb->remote_port  ||  /*   Remote port not a match   OR */
                    tcb2->remote_host == INADDR_ANY        ||  /*   Remote host not specified OR */
                    tcb2->remote_host != remote_host_v4    ||  /*   Remote host not a match   OR */
                    tcb2->local_host != tcb->local_host );     /*   Local address not a match    */
                    tcb2 = tcb2->next)                         /*   Otherwise, comb. is in use   */
            {
            } /* Endfor */

            if ( tcb2 != NULL )
            {
                RTCS_log_error( ERROR_TCP, RTCSERR_TCP_OPEN_FAILED,RTCSERR_TCP_ADDR_IN_USE, 0, 0);
                TCP_PO_FAIL(RTCSERR_TCP_ADDR_IN_USE);
            } /* Endif */

        } /* Endif */
   }
   #if RTCSCFG_ENABLE_IP6
   else
   #endif
#endif
#if RTCSCFG_ENABLE_IP6
   if(req_ptr->AF == AF_INET6)
   {

        if (
            (tcb->local_port != 0)    &&
            (tcb->remote_port != 0)   &&
            (!IN6_ARE_ADDR_EQUAL(&remote_host_v6, &in6addr_any))
           )
        {

            for (   tcb2=tcp_cfg->TCBhead;
                    tcb2 != NULL &&                                                           /* Can ignore this TCB if its:    */
                  ( tcb2->local_port != tcb->local_port                             ||        /*   Local port not a match    OR */
                    tcb2->remote_port == 0                                          ||        /*   Remote port not specified OR */
                    tcb2->remote_port != tcb->remote_port                           ||        /*   Remote port not a match   OR */
                    IN6_ARE_ADDR_EQUAL(&(tcb2->remote_ipv6_host), &in6addr_any)     ||        /*   Remote host not specified OR */
                   !IN6_ARE_ADDR_EQUAL(&(tcb2->remote_ipv6_host), &remote_host_v6)  ||        /*   Remote host not a match   OR */

                   !IN6_ARE_ADDR_EQUAL(&(tcb2->local_ipv6_host), &(tcb->local_ipv6_host)) /*   Local address not a match    */
                  );
                    tcb2 = tcb2->next)                                                    /* Otherwise, comb. is in use     */
            {
            } /* Endfor */

            if ( tcb2 != NULL )
            {
                RTCS_log_error( ERROR_TCP,RTCSERR_TCP_OPEN_FAILED,RTCSERR_TCP_ADDR_IN_USE,0, 0);
                TCP_PO_FAIL(RTCSERR_TCP_ADDR_IN_USE);
            } /* Endif */

        } /* Endif */
    }
#endif /* RTCSCFG_ENABLE_IP6 */

   /*  Allocate send buffer */
   if ((sbsize != 0) && (tcb->options & TCPO_ACTIVE)) {

      tcb->sndringbuf = (uchar _PTR_)RTCS_mem_alloc(sbsize);
      if ( tcb->sndringbuf == NULL ) {
         RTCS_log_error( ERROR_TCP, RTCSERR_TCP_OPEN_FAILED, RTCSERR_TCPIP_NO_BUFFS, 0, 0);
         TCP_PO_FAIL(RTCSERR_TCPIP_NO_BUFFS);
      } /* Endif */
       _mem_set_type(tcb->sndringbuf, MEM_TYPE_TCP_TX_WINDOW);

   } /* Endif */
   tcb->sndringlen = sbsize;

   /*  Allocate receive buffer */
   if ((rbsize != 0) && (tcb->options & TCPO_ACTIVE)) {

      tcb->rcvringbuf = (uchar _PTR_)RTCS_mem_alloc(rbsize);
      if ( tcb->rcvringbuf == NULL ) {
         RTCS_log_error( ERROR_TCP, RTCSERR_TCP_OPEN_FAILED, RTCSERR_TCPIP_NO_BUFFS, 0, 0);
         TCP_PO_FAIL(RTCSERR_TCPIP_NO_BUFFS);
      } /* Endif */
       _mem_set_type(tcb->rcvringbuf, MEM_TYPE_TCP_RX_WINDOW);

      /*  Use ring buffer by default  */
      tcb->rcvbuf = tcb->rcvringbuf;

   } /* Endif */
   tcb->rcvringlen = rbsize;
   tcb->rcvlen     = rbsize;

   /*  Fill remainder of new TCB;
    */

   tcb->state        = LISTEN;

#if RTCSCFG_ENABLE_IP4
    if(req_ptr->AF == AF_INET)
    {
        if ( remote_host_v4 != INADDR_ANY )
        {
            tcb->rcvmss = IP_MTU(tcb->local_host, remote_host_v4) - (uint_16) (IP_HEADSIZE + TCP_HEADSIZE);
        } /* Endif */
    }
    #if RTCSCFG_ENABLE_IP6
    else
    #endif
#endif
#if RTCSCFG_ENABLE_IP6
    if(req_ptr->AF == AF_INET6)
    {
        if (!IN6_ARE_ADDR_EQUAL(&remote_host_v6, &in6addr_any))
        {
            tcb->rcvmss = IP6_MTU(&(tcb->local_ipv6_host),&remote_host_v6) - (uint_16) (IP6_HEADSIZE + TCP_HEADSIZE);
        } /* Endif */
    }
#endif /* RTCSCFG_ENABLE_IP6 */

   tcb->sndmss    = TCP_MSS_DEFAULT;   /* default, as per RFC1122, 4.2.2.6 */
   tcb->sndmax    = tcb->sndmss;       /* - options */
                                       /* options is length of any IP and  */
                                       /* TCP options sent */

   tcb->rcvmax    = 1;
   tcb->rcv2full  = 1;                 /* this way we ACK a SYN */

   if ( tcb->sndrto < _TCP_rto_min ) {
      tcb->sndrto = _TCP_rto_min;
   } /* Endif */

   tcb->sndrtta   = 0;                 /* initial RTT, as per RFC1122, */
                                       /*   4.2.3.1 */

   tcb->sndrttd   = tcb->sndrto << 1;  /* because rto == rtta + 2*rttd, and */
                                       /*   rttd is scaled by 2^2 (by 4) */

   tcb->sndcwnd   = tcb->sndmax;       /* init. cwnd to 1 packet  */


   tcb->sndcwndmax = tcb->sndcwnd;     /* for debugging statistics... */
   tcb->sndstresh = TCP_WINDOW_MAX;    /* at least as big as any eventual */
                                       /*   send window*/

   /*  Soft timeout (R1) must occur *before* hard timeout (R2) (see RFC1122
   **   section 4.2.3.5 for more details on these timeouts)
   */
   if ( tcb->sndto_2 != 0 ) {

      if ( tcb->sndto_2 < TCP_SENDTIMEOUT_MIN ) {
         tcb->sndto_2 = TCP_SENDTIMEOUT_MIN;
      } /* Endif */

      /*  If sndto_2 is set, sndto_1 must also be set; if it isn't, set it
       *   to half of sndto_2 (user can always ignore soft timeout events)
       *  Either way, sndto_1 may never exceed half of sndto_2
       */
      if ( (tcb->sndto_1 == 0) || (tcb->sndto_1 > (tcb->sndto_2 >> 1)) ) {
         tcb->sndto_1 = tcb->sndto_2 >> 1;
      } /* Endif */

      tcb->sndto_2 -= tcb->sndto_1;    /* store delta only */

   } /* Endif */


   tcb->sndprobeto = tcb->sndrto;
   tcb->sndprobetomax = tcb->sndrtomax;

   /*  Keep-alive packets should be sent *very* infrequently, usually at
    *   least 2 hours apart; here just do a reasonableness check;
    *   10 times RTO seems a reasonable minimum.
    */
   if ( tcb->keepaliveto != 0 && tcb->keepaliveto < 10 * tcb->sndrto ) {
      tcb->keepaliveto = 10 * tcb->sndrto;
   } /* Endif */

   /* init timers */
   tcb->sndacktq.t.donelist   = (TimeQ _PTR_ _PTR_)&(tcp_cfg->acktq);
   tcb->sndacktq.tcb          = tcb;
   tcb->sndxmittq.t.donelist  = (TimeQ _PTR_ _PTR_)&(tcp_cfg->xmittq);
   tcb->sndxmittq.tcb         = tcb;
   tcb->sndtq.t.donelist      = (TimeQ _PTR_ _PTR_)&(tcp_cfg->sndtq);
   tcb->sndtq.tcb             = tcb;
   tcb->rcvtq.t.donelist      = (TimeQ _PTR_ _PTR_)&(tcp_cfg->rcvtq);
   tcb->rcvtq.tcb             = tcb;

   /*  Allocate space for storing timestamps of sent packets;
    *   pointers are used for the circular queue because they are faster
    *   than indexes (which require multiplies)
    */

   tcb->sndclks = 2 * sbsize / tcb->sndmax + 1;
                                       /* max nb of clock samples */

   if ( tcb->sndclks < 3 ) {           /* minimum reasonable nb */
      tcb->sndclks = 3;
   } /* Endif */

   tcb->sndclkavail = tcb->sndclks;
   tcb->sndclk = (SndClock _PTR_)RTCS_mem_alloc(tcb->sndclks*sizeof(SndClock));
   if ( tcb->sndclk == NULL ) {
      RTCS_log_error( ERROR_TCP, RTCSERR_OUT_OF_MEMORY,
         tcb->sndclks*sizeof(SndClock), 3, 0);
      TCP_PO_FAIL(RTCSERR_OUT_OF_MEMORY);
   } /* Endif */

   _mem_set_type(tcb->sndclk, MEM_TYPE_TCP_SEND_CLOCK);

   tcb->sndclkhead = tcb->sndclk;
   tcb->sndclktail = tcb->sndclk;
   tcb->sndclkend  = tcb->sndclk + tcb->sndclks;

#if RTCSCFG_ENABLE_IP4
        if(req_ptr->AF == AF_INET)
        {
            tcb->remote_host = remote_host_v4;
        }
    #if RTCSCFG_ENABLE_IP6
        else
    #endif
#endif
#if RTCSCFG_ENABLE_IP6
        if(req_ptr->AF == AF_INET6)
        {
            IN6_ADDR_COPY(&(remote_host_v6),&(tcb->remote_ipv6_host));
            /* add scope_id here */
            tcb->if_scope_id = req_ptr->IF_SCOPE_ID;
        }
#endif /* RTCSCFG_ENABLE_IP6 */

   tcb->conn_pending = 0;

   /* TcpOpen succeeded */
#if RTCSCFG_ENABLE_TCP_STATS
   tcp_cfg->STATS.ST_CONN_OPEN++;
   if ( tcb->options & TCPO_ACTIVE )
   {
      tcp_cfg->STATS.ST_CONN_ACTIVE++;
   }
   else
   {
      tcp_cfg->STATS.ST_CONN_PASSIVE++;
   } /* Endif */
#endif

    if( tcb->options & TCPO_ACTIVE )
    {
      /* Looking for the best local interface to connection to remote host. */
#if RTCSCFG_ENABLE_IP4
        if(req_ptr->AF == AF_INET)
        {
            if (tcb->local_host == INADDR_ANY)
            {
                tcb->local_host = IP_route_find(remote_host_v4, 0);
                if (tcb->local_host == INADDR_ANY)
                {
                    TCP_PO_FAIL(RTCSERR_TCP_HOST_UNREACH);
                } /* Endif */
            } /* Endif */
        }
    #if RTCSCFG_ENABLE_IP6
        else
    #endif
#endif

#if RTCSCFG_ENABLE_IP6
        if(req_ptr->AF == AF_INET6)
        {
            if (IN6_ARE_ADDR_EQUAL(&(tcb->local_ipv6_host), &in6addr_any))
            {
                IN6_ADDR_COPY((in6_addr*)IP6_route_find(&remote_host_v6, 0),&(tcb->local_ipv6_host));
                if (IN6_ARE_ADDR_EQUAL(&(tcb->local_ipv6_host), &in6addr_any))
                {
                    TCP_PO_FAIL(RTCSERR_TCP_HOST_UNREACH);
                } /* Endif */
            } /* Endif */
        }
#endif /* RTCSCFG_ENABLE_IP6 */

        /* Hang on to open requests until established */
        req_ptr->NEXT = tcp_cfg->OPENS;
        tcp_cfg->OPENS = req_ptr;


        tcb->state = SYN_SENT;

    /*set inet family*/
        tcb->af = req_ptr->AF;

      TCP_Start_sending(tcb, tcp_cfg);
   }
   else
   {
        RTCSCMD_complete(req_ptr, RTCS_OK);
   } /* Endif */

   return;

   failopen:

      if ( tcb != NULL ) {

         if ( tcb->sndringbuf != NULL ) {
            _mem_free(tcb->sndringbuf);
            tcb->sndringbuf = NULL;
         } /* Endif */

         if ( tcb->rcvringbuf != NULL ) {
            _mem_free(tcb->rcvringbuf);
            tcb->rcvringbuf = NULL;
         } /* Endif */

         if ( tcb->sndclk != NULL ) {
            _mem_free(tcb->sndclk);
            tcb->sndclk = NULL;
         } /* Endif */

      } /* Endif */

      RTCSCMD_complete(req_ptr, result);
      return;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_accept
* Returned Values : None.
* Comments        :
*
*  Called when the application accept()s a new connection.
*
*END*-----------------------------------------------------------------*/

void TCP_Process_accept
   (
      TCP_PARM_PTR   req_ptr     /* IN/OUT - the accept request */
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;          /* TCP Layer constants */
   TCB_STRUCT_PTR       tcb;
   TCB_STRUCT_PTR _PTR_ search_ptr;

   tcp_cfg = RTCS_getcfg(TCP);
   tcb = req_ptr->TCB_PTR;

   if ( tcb == NULL ) {
      RTCSCMD_complete(req_ptr, RTCSERR_TCP_CONN_RLSD);
      return;
   }

   search_ptr = &tcp_cfg->NOSOCK_TCB;

   if (tcb->conn_pending) {
      tcb->conn_pending--;

      /* Check if a listening TCB has spawned another TCB */
      while (*search_ptr) {
         if ((*search_ptr)->LISTEN_TCB == tcb &&
             (*search_ptr)->conn_pending)
         {
            /* Found a match */
            (*search_ptr)->conn_pending--;
            req_ptr->TCB_PTR = *search_ptr;
            *search_ptr = (*search_ptr)->NOSOCK_NEXT;
            req_ptr->TCB_PTR->SOCKET = req_ptr->SOCKET;
            ((SOCKET_STRUCT_PTR)req_ptr->SOCKET)->TCB_PTR = req_ptr->TCB_PTR;
            req_ptr->TCB_PTR->LISTEN_TCB = NULL;
            RTCSCMD_complete(req_ptr, RTCS_OK);
            return;
         } /* Endif */

         search_ptr = &(*search_ptr)->NOSOCK_NEXT;
      } /* Endwhile */

      /* Didn't find any TCBs. The TCB must have been released by a RST */
      RTCSCMD_complete(req_ptr, RTCSERR_TCP_CONN_RESET);
   } else {

      /* Hang on to open requests until established */
      req_ptr->NEXT = tcp_cfg->OPENS;
      tcp_cfg->OPENS = req_ptr;

   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_signal
* Returned Values : None.
* Comments        :
*
*  Process TCP timeouts.
*
*END*-----------------------------------------------------------------*/
void TCP_Process_signal
   (
      void
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;
   TCB_STRUCT_PTR       tcb;
   TcbTimeQ _PTR_       tq;
   int_32               result;

   tcp_cfg = RTCS_getcfg(TCP);

   RTCSLOG_FNE5(RTCSLOG_FN_TCP_Process_signal, tcp_cfg->xmittq, tcp_cfg->acktq, tcp_cfg->rcvtq, tcp_cfg->sndtq);

   /*
   ** Process any (re)transmission timeouts
   */
   while (1) {

      tq = tcp_cfg->xmittq;
      if ( tq == NULL ) {
         break;
      } /* Endif */
      TCP_Timer_remove(&tq->t);                /* remove from its list */

      tcb = tq->tcb;
      DEBUGTCP(printf("\nTCP: (re)transmission timeout, tcb @ %p", tcb));

      if ( tcb->VALID == TCB_VALID_ID ) {

         if ( tcb->state == TIME_WAIT ) {     /* was it a time-wait timer? */

            /*
            ** 2MSL timeout expired
            */
            TCP_Close_TCB(tcb, RTCS_OK, tcp_cfg);
            TCP_Process_release(tcb, tcp_cfg);

            continue;   /* at start of LOOP */

         } /* Endif */

         /*
         ** Are we probing a zero-sized send window?
         */
         if ( tcb->sndxmitwhat == TCP_PROBE ) {

            /*
            ** exponential backoff, clamped
            */
            if ( (tcb->sndprobeto <<= 1) > tcb->sndprobetomax ) {
               tcb->sndprobeto = tcb->sndprobetomax;
            } /* Endif */
            TCP_Transmit(tcb, tcp_cfg, FALSE, TRUE);
            /* will restart xmittq with probeto */

         } else {  /* else we must be retransmitting (sndxmitwhat EQ TCP_XMIT) */

            if ( tcb->sndxmitwhat != TCP_XMIT ) {
               RTCS_log_error( ERROR_TCP, RTCSERR_TCP_REXMIT_PROBLEM,
                  (uint_32)tcb->sndxmitwhat, (uint_32)tcb, 0 );
            } /* Endif */


            /* congestion avoidance */
            if ( tcb->sndwnd < tcb->sndcwnd ) {
               tcb->sndstresh = tcb->sndwnd >> 1;
            } else {
               tcb->sndstresh = tcb->sndcwnd >> 1;
            } /* Endif */
            tcb->sndcwnd = tcb->sndmax;           /* slow-start */

            if ( (tcb->sndrto <<= 1) > tcb->sndrtomax ) {

               /*
               ** exponential backoff
               */
               tcb->sndrto = tcb->sndrtomax;   /* clamped */

            } /* Endif */

            TCP_Transmit(tcb, tcp_cfg, TRUE, TRUE); /* force retransmission */
            tcb->rexmts++;
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_TX_DATA_DUP++);

            /*
            ** restart the timeout
            */
            result =
               TCP_Timer_start( &tq->t,      /* the timer */
                           tcb->sndrto,      /* the timeout value */
                           0,                /* no reload */
                           tcp_cfg->qhead ); /* the timer queue head */

            if ( result != RTCS_OK ) {
               RTCS_log_error( ERROR_TCP, RTCSERR_TCP_TIMER_FAILURE,
                  (uint_32)result, (uint_32)tcb, 0 );
            } /* Endif */

         } /* Endif */

      } /* Endif */

   } /* EndWhile */

   /*
   ** Then, process any ACK timers (Ack's to send)
   */
   while (1) {

      tq = tcp_cfg->acktq;
      if ( tq == NULL ) {
         break;
      } /* Endif */

      TCP_Timer_remove(&tq->t);      /* remove from its list */

      tcb = tq->tcb;

      if ( tcb->VALID == TCB_VALID_ID ) {

         DEBUGTCP(printf("\nTCP: ACK timer, tcb @ %p", tcb));
         TCP_Transmit(tcb, tcp_cfg, FALSE, TRUE);

         /*
         ** If sender idle, restart keep-alive timer
         */
         if ( tcb->sndlen == 0 && tcb->keepaliveto != 0 ) {
            TCP_Send_keepalive(tcb,tcp_cfg);
         } /* Endif */

      } /* Endif */

   } /* EndWhile */

   /*
   ** Process receive timers
   */
   while (1) {

      tq = tcp_cfg->rcvtq;
      if ( tq == NULL ) {
         break;
      } /* Endif */

      TCP_Timer_remove(&tq->t);             /* remove from its list */

      tcb = tq->tcb;
      DEBUGTCP(printf("\nTCP: receive timer, tcb @ %p", tcb));

      if ( tcb->VALID == TCB_VALID_ID ) {

         if ( tcb->rcvHead != NULL ) {   /* should be true, but check anyway */
            TCP_Reply_receive(tcb, tcp_cfg, RTCSERR_TCP_TIMED_OUT);

            /*
            ** Setup next receive
            */
            while ( tcb->rcvHead != NULL &&
                  ! TCP_Setup_receive(tcb->rcvHead, tcb, tcp_cfg)
            ) {
            } /* Endwhile */

         } /* Endif */

      } /* Endif */

   } /* EndWhile */

   /*
   ** Finally, process any Send timers (transmission not ack'd
   **  within timeout)
   */
   while (1) {

      tq = tcp_cfg->sndtq;
      if ( tq == NULL ) {
         break;
      } /* Endif */

      TCP_Timer_remove(&tq->t);                /* remove from its list */

      tcb = tq->tcb;
      DEBUGTCP(printf("\nTCP: send timer, tcb @ %p", tcb));

      if ( tcb->VALID == TCB_VALID_ID ) {

         if ( tcb->state != CLOSED && tcb->sndtohard ) {

            /*
            ** hard timeout reached
            */
            TCP_Close_TCB(tcb, RTCSERR_TCP_TIMED_OUT, tcp_cfg);
            if (tcb->SOCKET == 0) {   /* Free TCB if unused */
               TCP_Process_release(tcb, tcp_cfg);
            } /* Endif */

         } else {                                /* soft timeout reached */

            /*
            ** User timeout; sent data not acked in time
            */
            TCP_Event(tq->tcb, TCPS_TIMEOUT);
            if ( tcb->sndto_2 != 0 ) {        /* start hard timeout... */
               result =
                  TCP_Timer_start( &tq->t,      /* the timer */
                              tcb->sndto_2,     /* the timeout value */
                              0,                /* no reload */
                              tcp_cfg->qhead ); /* the timer queue head */
               if ( result != RTCS_OK ) {
                  RTCS_log_error( ERROR_TCP, RTCSERR_TCP_TIMER_FAILURE,
                     (uint_32)result, (uint_32)tcb, 1 );
               } /* Endif */
               tcb->sndtohard = TRUE;
            } /* Endif */

            /*
            ** Tell IP about it...
            */
/*          IP_Advise_delivery_problem( 0,tcb->icb,tcb->rem_host,tcb->tos );
*/
            tcb->sndtmouts++;
            /* tcp_cfg->STATS.ST_SNDTMOUTS++; */

         } /* Endif */

      } /* Endif */

   }

   RTCSLOG_FNX1(RTCSLOG_FN_TCP_Process_signal);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Return_open
* Returned Values : None.
* Comments        :
*
*  Finds and returns the TcpOpen or TcpListen request back to the
*     upper layer.
*
*END*-----------------------------------------------------------------*/

void TCP_Return_open
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      uint_32              errnum,  /* IN     - reason for returning */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer constants */
   )
{ /* Body */
   TCP_PARM_PTR  req_ptr;     /* upper layer request */
   TCP_PARM_PTR  prev_ptr;    /* previous upper layer request */
   TCB_STRUCT_PTR _PTR_ search_ptr = &tcp_cfg->NOSOCK_TCB;

   /* Return open request to upper layer */

   prev_ptr = NULL;
   req_ptr = tcp_cfg->OPENS;
   while (req_ptr != NULL &&
          tcb != req_ptr->TCB_PTR &&
          tcb->LISTEN_TCB != req_ptr->TCB_PTR) {
      prev_ptr = req_ptr;
      req_ptr = req_ptr->NEXT;
   } /* Endwhile */

   if (req_ptr != NULL) {
      if (prev_ptr == NULL) {
         tcp_cfg->OPENS = req_ptr->NEXT;
      } else {
         prev_ptr->NEXT = req_ptr->NEXT;
      } /* Endif */
      req_ptr->NEXT = NULL;

      /* Remove the TCB from the list of TCBS spawned by the listening TCB */
      while (*search_ptr) {
         if (*search_ptr == tcb) {
            *search_ptr = (*search_ptr)->NOSOCK_NEXT;
            tcb->SOCKET = req_ptr->SOCKET;
            ((SOCKET_STRUCT_PTR)req_ptr->SOCKET)->TCB_PTR = tcb;
            tcb->LISTEN_TCB = NULL;
            break;
         } /* Endif */
         search_ptr = &(*search_ptr)->NOSOCK_NEXT;
      } /* Endwhile */

      req_ptr->TCB_PTR = tcb;
      RTCSCMD_complete(req_ptr, errnum);

   } else {
      if (tcb->state != CLOSED) { /* Only increment count if we receive a new connection */
         tcb->conn_pending++;
      } /* Endid */

      if (tcb->LISTEN_TCB == NULL) {
         SOCK_select_signal(tcb->SOCKET, tcb->state);
      } else {
         if (tcb->state != CLOSED) {
            /* Only increment count if we receive a new connection */
            tcb->LISTEN_TCB->conn_pending++;
         } /* Endif */
         SOCK_select_signal(tcb->LISTEN_TCB->SOCKET, tcb->state);
      } /* Endif */

   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Clone_tcb
* Returned Values : A new TCB in the SYN_RECEIVED state (or NULL)
* Comments        :
*
*  Takes a listening TCB in the listen state and creates a new TCB to be
*  placed in the SYN_RECEIVED state.
*
*END*-----------------------------------------------------------------*/


TCB_STRUCT_PTR TCP_Clone_tcb
   (
      TCB_STRUCT_PTR    listen_ptr  /* IN - the TCB to clone */
   )
{ /* Body */
   TCB_STRUCT_PTR       new_tcb;
   TCP_CFG_STRUCT_PTR   tcp_cfg = RTCS_getcfg(TCP);

   new_tcb = RTCS_mem_alloc_zero(sizeof(TCB_STRUCT));

   /* Make sure memory allocation succeeded */
   if (new_tcb == NULL) {
      return NULL;
   } /* Endif */
   _mem_set_type(new_tcb, MEM_TYPE_TCB);

   /* Clone the TCB */
   _mem_copy(listen_ptr, new_tcb, sizeof(TCB_STRUCT));
   new_tcb->sndringbuf     = (uchar _PTR_)RTCS_mem_alloc(new_tcb->sndringlen);
   new_tcb->rcvringbuf     = (uchar _PTR_)RTCS_mem_alloc(new_tcb->rcvringlen);
   new_tcb->sndclk         = RTCS_mem_alloc(new_tcb->sndclks*sizeof(SndClock));

   /* Check if memory allocation succeeded */
   if (new_tcb->sndringbuf == NULL ||
       new_tcb->rcvringbuf == NULL ||
       new_tcb->sndclk     == NULL)
   {
      /* Free memory */
      if (new_tcb->sndringbuf) {
         _mem_free(new_tcb->sndringbuf);
      } /* Endif */

      if (new_tcb->rcvringbuf) {
         _mem_free(new_tcb->rcvringbuf);
      } /* Endif */

      if (new_tcb->sndclk) {
         _mem_free(new_tcb->sndclk);
      } /* Endif */

      _mem_free(new_tcb);
      return NULL;
   } /* Endif */

   _mem_set_type(new_tcb->sndclk, MEM_TYPE_TCP_SEND_CLOCK);
   _mem_set_type(new_tcb->sndringbuf, MEM_TYPE_TCP_TX_WINDOW);
   _mem_set_type(new_tcb->rcvringbuf, MEM_TYPE_TCP_RX_WINDOW);


   /* Initialize new TCB */
   new_tcb->next           = tcp_cfg->TCBhead;
   tcp_cfg->TCBhead        = new_tcb;
   new_tcb->SOCKET         = 0;
   new_tcb->LISTEN_TCB     = listen_ptr;
   new_tcb->rcvbuf         = new_tcb->rcvringbuf;
   new_tcb->conn_pending   = 0;
   tcp_cfg->CONN_COUNT++;
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_CONN_OPEN++);
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_CONN_PASSIVE++);

   /* Setup timer queues */
   new_tcb->rcvtq.tcb      = new_tcb;
   new_tcb->sndxmittq.tcb  = new_tcb;
   new_tcb->sndacktq.tcb   = new_tcb;
   new_tcb->sndtq.tcb      = new_tcb;

   /* Setup send clocks */
   new_tcb->sndclkhead     = new_tcb->sndclk;
   new_tcb->sndclktail     = new_tcb->sndclk;
   new_tcb->sndclkend      = new_tcb->sndclk + new_tcb->sndclks;

   new_tcb->NOSOCK_NEXT = tcp_cfg->NOSOCK_TCB;
   tcp_cfg->NOSOCK_TCB = new_tcb;
#if RTCSCFG_TCP_MAX_HALF_OPEN
   new_tcb->tcb_spawn_time = RTCS_time_get();
   /* The first element will be stored in index 0 */
   tcp_cfg->HALF_OPEN_TCB_LIST[tcp_cfg->HALF_OPEN_TCB_COUNT] = new_tcb;
   tcp_cfg->HALF_OPEN_TCB_COUNT++;
#endif

   /* New TCB needs to inherit the TX options */
   new_tcb->TX = listen_ptr->TX;

   return new_tcb;
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP6_Process_packet
* Returned Values : None.
* Comments        :
*
*  Process an incoming TCP packet.  Note that the PCB is freed by
*   the routine it is consumed in.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6

void TCP6_Process_packet
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      RTCSPCB_PTR          pcb,     /* IN/OUT - the incoming packet */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer constants */
   )
{ /* Body */
   TCP_HEADER_PTR    seg;
   uint_16           seglen;
   uint_16           flags;
   uint_16           optlen;
   uchar _PTR_       opt;
   uint_32           seq,ack;
   uint_16           urg;
   int_32            result;     /* returned result */
   boolean           seg_okay;
   /*IPv6*/
   in6_addr         ipv6_source;



   seg_okay = TRUE;

   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   flags = ntohs(seg->flags);

   RTCSLOG_FNE5(RTCSLOG_FN_TCP_Process_packet, tcb, pcb, tcp_cfg, flags);

   RTCSPCB_next(pcb, (flags & DATAOFS_MASK) >> (DATAOFS_SHIFT - 2));

   /*
   ** Drop packets that have illegal/abnormal flag combinations, as these
   ** are almost certainly malicious.
   **
   ** - SYN FIN is probably the best known illegal combination. Remember
   **   that SYN is used to start a connection, while FIN is used to end
   **   an existing connection. It is nonsensical to perform both actions
   **   at the same time. Many scanning tools use SYN FIN packets, because
   **   many intrusion detection systems did not catch these in the past,
   **   although most do so now. You can safely assume that any SYN FIN
   **   packets you see are malicious.
   **
   ** - SYN FIN PSH, SYN FIN RST, SYN FIN RST PSH, and other variants on
   **   SYN FIN also exist. These packets may be used by attackers who are
   **   aware that intrusion detection systems may be looking for packets
   **   with just the SYN and FIN bits set, not additional bits set. Again,
   **   these are clearly malicious.
   **
   ** - Packets should never contain just a FIN flag. FIN packets are
   **   frequently used for port scans, network mapping and other stealth
   **   activities.
   **
   ** - Some packets have absolutely no flags set at all; these are referred
   **   to as "null" packets. It is illegal to have a packet with no flags set.
   */
   if ( ((flags & SYN) && (flags & FIN)) ||
        (flags == FIN) ||
        (flags == 0) ) {
      TCP_PP_DROP;
   }

   /*
   ** compute SEG.LEN
   */
   seglen = RTCSPCB_SIZE(pcb);   /* socket layer data size */
   if ( flags & SYN ) {
      seglen++;
   } /* Endif */

   if ( flags & FIN ) {
      seglen++;
   } /* Endif */

   /* using IPv6 copy macros to copy the IPv6 address structure */
   IN6_ADDR_COPY((in6_addr *)((IP6_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb))->SOURCE, &ipv6_source);

   /*
   ** Process options
   */
   opt = (uchar _PTR_)seg + sizeof(TCP_HEADER);
   while ( opt < RTCSPCB_DATA(pcb) ) {

      switch ( (ntohc(opt)) ) {

         case OPT_PAD:
            opt = RTCSPCB_DATA(pcb);
            break;

         case OPT_NOOP:
            opt++;
            break;

         case OPT_MSS:

            { /* Scope */

               uint_16 mss;

               optlen = ntohc(opt+1);
               if ( optlen == 0 ) {

                  IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_OPTION++);
                  TCP_PP_DROP;

               } /* Endif */
               mss = ntohs(opt+2);

               /*
               ** Compare with tcb->rcvmss since it is set to
               **  our maximum allowable, and doesn't change:
               */
               if ( tcb->rcvmss != 0 && mss > tcb->rcvmss ) {
                  mss = tcb->rcvmss;
               } /* Endif */

               tcb->sndmss = mss;
               tcb->sndmax = mss; /* minus length of any IP and TCP options; */

               if ( mss < tcb->rcvmax ) {

                  tcb->rcvmax = mss;

                  /*
                  ** Will reply after 1.75*mss bytes have been received.
                  */
                  tcb->rcv2full = mss + (mss>>1) + (mss>>2);

               } /* Endif */

               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_OPT_MSS++);
               opt += optlen;
               break;

            } /* Endscope */

         default:

            /*
            ** All options will have a length byte
            */
            optlen = ntohc(opt+1);
            if ( optlen == 0 ) {

               /*
               ** should send ICMP parameter problem
               */
               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_OPTION++);
               TCP_PP_DROP;

            } /* Endif */
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_OPT_OTHER++);
            opt += optlen;

      } /* End Switch */

   } /* Endwhile */

   /*
   **  Process packet:
   **
   **  (RFC 793 sec.3.9, 'SEGMENT ARRIVES' (pages 65-76);
   **   steps are indicated as FIRST, SECOND, THIRD, etc. as in the RFC)
   */

   seq = ntohl(seg->seq);
   ack = ntohl(seg->ack);
   urg = ntohs(seg->urgent);

   switch ( tcb->state ) {

      /*
      **   This case is executed only when in a invalid state, since
      **   packets aren't queued on CLOSED connections, and closing
      **   connections (see TCP_Close_TCB()) disown their queued packets...
      */
      case CLOSED:
         if( (flags & RST) == 0 )
         {
            TCP_STATE_DEBUG(("state = CLOSED, replying with RST on tcb %p\n", tcb));
            TCP6_Send_reply_reset(tcb,
                           &ipv6_source,        /* source address */
                           seg,           /* received packet */
                           seglen,        /* length of received packet */
                           tcp_cfg,       /* TCP layer data */
                           FALSE
                          );
         } /* Endif */
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_LATE_DATA++);
         TCP_PP_DROP;

      case LISTEN:

         if ( (flags & RST) != 0 ) {                         /* FIRST */
            TCP_STATE_DEBUG(("state = LISTEN, heard reset on tcb %p, dropping.\n", tcb));
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
            TCP_PP_DROP;
         } /* Endif */

         if( (flags & ACK) != 0 )
         {                         /* SECOND */
            TCP6_Send_reply_reset(tcb,
                           &ipv6_source,        /* source address */
                           seg,           /* received packet */
                           seglen,        /* length of received packet */
                           tcp_cfg,       /* TCP layer data */
                           tcb->bypass_tx_chksum
                          );
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
            TCP_PP_DROP;
         } /* Endif */

         if ( (flags & SYN) != 0 ) {                         /* THIRD */
#if RTCSCFG_TCP_MAX_HALF_OPEN
            if ((tcp_cfg->HALF_OPEN_TCB_COUNT >= RTCSCFG_TCP_MAX_HALF_OPEN)
#if RTCSCFG_TCP_MAX_CONNECTIONS
             || (tcp_cfg->CONN_COUNT >= RTCSCFG_TCP_MAX_CONNECTIONS)
#endif
               ) {
               TCP_half_open_TCB_close(tcp_cfg);
            } /* Endif */
#endif

#if RTCSCFG_TCP_MAX_CONNECTIONS
            if (tcp_cfg->CONN_COUNT >= RTCSCFG_TCP_MAX_CONNECTIONS) {
               TCP_PP_DROP;
            } /* Endif */
#endif

            CHECK_SECURITY;
            CHECK_PRECEDENCE;

            tcb = TCP_Clone_tcb(tcb);
            if (tcb == NULL) {
               TCP_PP_DROP;
            } /* Endif */
            if ( IN6_ARE_ADDR_EQUAL(&tcb->local_ipv6_host, &in6addr_any))
            {
               IN6_ADDR_COPY((in6_addr *)((IP6_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb))->DEST, &(tcb->local_ipv6_host));
            } /* Endif */
            if ( IN6_ARE_ADDR_EQUAL(&tcb->remote_ipv6_host, &in6addr_any) )
            {
                 IN6_ADDR_COPY(&ipv6_source,&(tcb->remote_ipv6_host));
                 tcb->rcvmss = IP6_MTU(&(tcb->local_ipv6_host),&ipv6_source) - (uint_16) (IP6_HEADSIZE + TCP_HEADSIZE);
               if(tcb->sndmss > tcb->rcvmss)
               {
                    tcb->sndmss = tcb->rcvmss;
               }
               tcb->sndmax = tcb->sndmss;
            } /* Endif */
            tcb->remote_port = ntohs(seg->source_port);
            /*
            ** TCP_Start_receiving sets state to SYN_RECEIVED
            */
            TCP_Start_receiving(tcb, seq, tcp_cfg);
            /*
            ** also below, in case SYN_SENT
            */
            TCP_Start_sending(tcb, tcp_cfg);
            /*
            ** Release the packet
            */
            RTCSLOG_PCB_FREE(pcb, RTCS_OK);
            RTCSPCB_free(pcb);

         }
         else
         {
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_SYN_EXPECTED++);
            TCP_PP_DROP;                                    /* FOURTH */
         } /* Endif */

         break;

      case SYN_SENT:

         if ( (flags & ACK) != 0 ) {                                /* FIRST */

            if ( LE32(ack, tcb->sndiss) ||
               GT32(ack, tcb->sndnxt) )
            {

               /*
               ** invalid ACK: drop, and reply if reset
               */
               if ( ! (flags & RST) ) {
                  TCP_STATE_DEBUG(("state = SYN_SENT, heard invalid ACK on tcb %p, sending RST\n", tcb));
                  TCP6_Send_reply_reset(
                                 tcb,
                                &ipv6_source,   /* source address */
                                 seg,           /* received packet */
                                 seglen,        /* length of received packet */
                                 tcp_cfg,       /* TCP layer data */
                                 tcb->bypass_tx_chksum
                                );
               } /* Endif */
               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
               TCP_PP_DROP;

            } /* Endif */

            if ( LT32(ack, tcb->snduna) ) {

               /*
               ** unnacceptable ACK (already ack'ed): drop
               */
               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
               TCP_PP_DROP;

            } /* Endif */

         } /* Endif */

         if ( (flags & RST) != 0 ) {                                /* SECOND */

             TCP_STATE_DEBUG(("state = SYN_SENT, heard RST on tcb %p\n", tcb));
            if ( (flags & ACK) != 0 ) {
               TCP_STATE_DEBUG(("state = SYN_SENT, heard RST+ACK on tcb %p, closing&dropping\n", tcb));
               TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_RESET, tcp_cfg);
               TCP_Process_release(tcb, tcp_cfg);
            } else {
               TCP_STATE_DEBUG(("state = SYN_SENT, ACK was not set so not closing & yes dropping on tcb %p\n", tcb));
            }/* Endif */

            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
            TCP_PP_DROP;

         } /* Endif */

         CHECK_SECURITY;            /* else reset & DROP */ /* THIRD */

         if ( (flags & ACK) != 0 ) {
            CHECK_EXACT_PRECEDENCE; /* else reset & DROP */
         } else {
            CHECK_PRECEDENCE;       /* may raise; if can't, reset & DROP */
         } /* Endif */

         if ( (flags & SYN) != 0 ) {                         /* FOURTH */

            TCP_Start_receiving(tcb, seq, tcp_cfg);   /* State=>SYN_RCVD */

            if ( (flags & ACK) != 0 ) {
               if ( GE32(ack, tcb->snduna) ) {
                  TCP_Process_ack(tcb, seg, tcp_cfg);
               } /* Endif */
            } /* Endif */

            if ( GT32(tcb->snduna, tcb->sndiss) ) {
               tcb->state = ESTABLISHED;
               TCP_Update_send_window(tcb,seg);
               TCP_Return_open(tcb, RTCS_OK, tcp_cfg);
               TCP_Event(tcb, TCPS_STARTED);
               TCP_Transmit(tcb, tcp_cfg, FALSE, TRUE);
               goto step6;             /* named from RFC793... */

            } else {
               /* force retransmit of SYN */
               TCP_Transmit(tcb, tcp_cfg, TRUE, TRUE);

            } /* Endif */

            /*
            **  any data or other controls are ignored, not queued
            **  for processing after state becomes ESTABLISHED
            */

            /*
            ** Free the packet
            */
            RTCSLOG_PCB_FREE(pcb, RTCS_OK);
            RTCSPCB_free(pcb);

         } else {
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_SYN_EXPECTED++);
            TCP_PP_DROP;                                    /* FIFTH */

         } /* Endif */

         break;

      /* all included in default
      ** case SYN_RECEIVED:
      ** case ESTABLISHED:
      ** case FINWAIT_1:
      ** case FINWAIT_2:
      ** case CLOSE_WAIT:
      ** case CLOSING:
      ** case LAST_ACK:
      ** case TIME_WAIT:
      */
      default:

        /**
         ** From RFC 793:
         **
         ** There are four cases for the acceptability test for an incoming
         ** segment:
         **
         ** Segment Receive  Test
         ** Length  Window
         ** ------- -------  -------------------------------------------
         **
         **    0       0     SEG.SEQ = RCV.NXT
         **
         **    0      >0     RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
         **
         **   >0       0     not acceptable
         **
         **   >0      >0     RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
         **               or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
         **
         ** If the RCV.WND is zero, no segments will be acceptable, but
         ** special allowance should be made to accept valid ACKs, URGs and
         ** RSTs.
         **
         ** If an incoming segment is not acceptable, an acknowledgment
         ** should be sent in reply (unless the RST bit is set, if so drop
         ** the segment and return):
         **
         **   <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
         **
         ** After sending the acknowledgment, drop the unacceptable segment
         ** and return.
         */

         /*
         ** Handles all cases explicitly.  seg_okay is used later in this procedure
         ** to drop an un-acceptable segment after processing its RST/ACK/URG fields
         ** in the case where the window is 0. Note, seglen may have been set to 1 to
         ** handle SYN or FIN flags.
         */
         { /* Scope */
            uint_16  rwindow;
            boolean  okay;

            rwindow = tcb->rcvwndedge - tcb->rcvnxt;

            if ( (rwindow == 0) &&                     /* Case 1 */
               (seglen == 0 || (flags & SYN && seglen == 1))  &&
               (seq == tcb->rcvnxt))
            {
               okay = TRUE;
               seg_okay = TRUE;

            } else if ( (rwindow > 0) &&                 /* Case 2 */
                  (seglen == 0 || (flags & SYN && seglen == 1))  &&
                   (LE32(tcb->rcvnxt,seq) &&
                    LT32(seq,tcb->rcvwndedge)))
            {
               okay = TRUE;
               seg_okay = TRUE;

            } else if ((flags & FIN) &&
                       LT32(tcb->rcvnxt,seq))
            {
              okay = TRUE;
              seg_okay = FALSE;

            } else if ( (seglen > 0)  &&                 /* Case 4 */
                   (rwindow > 0) &&
                   ((LE32(tcb->rcvnxt,seq) &&
                     LT32(seq,tcb->rcvwndedge)) ||
                    (LE32(tcb->rcvnxt,seq+seglen-1) &&
                     LT32(seq+seglen-1,tcb->rcvwndedge))))
            {
               okay = TRUE;
               seg_okay = TRUE;

            } else {                                      /* Case 3 or others failed */
               seg_okay = FALSE;
               if ( (rwindow == 0) && (flags & (RST | URG | ACK)) != 0 ) {
                  RTCSPCB_SIZE(pcb) = 0;
                  okay = TRUE;
                  /*tcp_cfg->STATS.ST_RX_ACC_BADSEGS++;*/
               } else {
                  okay = FALSE;
               } /* Endif */

            } /* Endif */

            if ( ! okay ) {
               /*
               ** segment unacceptable, sent ACK
               */
               if ( (flags & RST) == 0 ) {
                  TCP_Must_send_ack(tcb, tcp_cfg);
               } /* Endif */
               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_DATA++);
               TCP_PP_DROP;
            } /* Endif */

         } /* Endscope */

         /*
         ** Process the RST
         */
         if ( (flags & RST) != 0 ) {                                /* SECOND */
            TCP_STATE_DEBUG(("state = default(%d), heard reset on tcb %p, ", tcb->state, tcb));

            /* draft-ietf-tcpm-tcpsecure-00.txt section 2.2 */
            if (tcb->tcpsecuredraft0) {
                if (seq == tcb->rcvnxt) {
                   TCP_STATE_DEBUG(("RST is valid, closing&dropping.\n"));
                   TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_RESET, tcp_cfg); /* aborted */
                   TCP_Process_release(tcb, tcp_cfg);
                   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
                   TCP_PP_DROP;
                }
                else
                {
                   TCP_STATE_DEBUG(("RST is suspicious, acking&dropping\n"));
                   TCP_Must_send_ack(tcb, tcp_cfg);
                   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
                   TCP_PP_DROP;
                } /* Endif */
            } else {

            TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_RESET, tcp_cfg); /* aborted */
            TCP_Process_release(tcb, tcp_cfg);
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
            TCP_PP_DROP;

            }
            TCP_STATE_DEBUG(("\n"));
         } /* Endif */

         if ( tcb->state == SYN_RECEIVED ) {                 /* THIRD */
            CHECK_SECURITY; /* else reset & DROP */
         } else {
            CHECK_TIGHT_SECURITY;
            /*
            ** else reset & TCP_Close_TCB(tcb,RTCSERR_TCP_CONN_RESET) & DROP
            */
         } /* Endif */

         /*
         ** Process the SYN
         */
         if ( (flags & SYN) != 0 ) {                         /* FOURTH */
             if (tcb->tcpsecuredraft0) {
             /*
             ** draft-ietf-tcpm-tcpsecure-00.txt section 3.2
             */
                if (seq == tcb->rcvnxt) { /* SYN and seq is exact match */
                   tcb->ackmodifier = 1; /* ack number of ack pkt will be decremented by 1 later */
                }
                else /* SYN and seq is acceptable even though not exact */
                {
                   tcb->ackmodifier = 0;
                }
                TCP_Must_send_ack(tcb, tcp_cfg);
                IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_SYN_NOT_EXPECTED++);
                TCP_PP_DROP;
             }
             else
             {
                  /*
                  ** shouldn't receive SYN
                  */
               TCP6_Send_reply_reset(
                               tcb,
                              &ipv6_source,   /* source address */
                               seg,     /* received packet */
                               seglen,  /* length of received packet */
                               tcp_cfg, /* TCP layer data */
                               tcb->bypass_tx_chksum
                              );
                if ( tcb->state != LISTEN ) {

                   TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_RESET, tcp_cfg); /* state=>CLOSED */
                   if (tcb->SOCKET == 0) {
                      TCP_Process_release(tcb, tcp_cfg);
                   } /* Endif */

                } /* Endif */
                IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_SYN_NOT_EXPECTED++);
                TCP_PP_DROP;
             } /* Endif */
         } /* Endif */

         /*
         ** Process the ACK
         */
         if ( (flags & ACK) == 0 ) {                          /* FIFTH */
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_ACK_EXPECTED++);
            if ( ! seg_okay ) {
               TCP_Must_send_ack(tcb, tcp_cfg);
            } /* Endif */
            TCP_PP_DROP;
         } /* Endif */

         switch ( tcb->state ) {

            case SYN_RECEIVED:

               if ( LT32(ack, tcb->snduna) ||
                  GT32(ack, tcb->sndnxt) )
               {

                  TCP6_Send_reply_reset(
                                 tcb,
                                &ipv6_source, /* source address */
                                 seg,         /* received packet */
                                 seglen,      /* length of received packet */
                                 tcp_cfg,     /* TCP layer data */
                                 tcb->bypass_tx_chksum
                                );
                  IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
                  TCP_PP_DROP;

               } /* Endif */

               tcb->state = ESTABLISHED;
#if RTCSCFG_TCP_MAX_HALF_OPEN
               TCB_HALF_OPEN_DROP;
#endif

               TCP_Update_send_window(tcb, seg);
               TCP_Return_open(tcb, RTCS_OK, tcp_cfg);
               TCP_Event(tcb, TCPS_STARTED);

               /*FALLTHROUGH*/

            case ESTABLISHED:
            case CLOSE_WAIT:
            case FINWAIT_1:
            case FINWAIT_2:
            case CLOSING:

               if ( GT32(ack, tcb->sndnxt) ) {
                  /*
                  ** ACK of unsent data
                  */
                  TCP_Must_send_ack(tcb, tcp_cfg);
                  IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
                  TCP_PP_DROP;
               } /* Endif */

               if ( GE32(ack, tcb->snduna) ) {

                  /*
                  ** Update send window
                  */
                  if ( LT32(tcb->sndwl1, seq) ||
                     (tcb->sndwl1 == seq && LE32(tcb->sndwl2,ack))
                  ) {
                     TCP_Update_send_window(tcb, seg);
                  } /* Endif */

                  TCP_Process_ack(tcb, seg, tcp_cfg);

               } /* Endif */

               switch ( tcb->state ) {

                  case FINWAIT_1:
                     /*
                     ** if FIN is acked...
                     */
                     if ( GT32(ack, tcb->sndbufseq + tcb->sndlen) ) {
                        tcb->state = FINWAIT_2;
                     } else {
                        break;
                     } /* Endif */

                     /*FALLTHROUGH*/

                  case FINWAIT_2:
                     /*
                     ** acknowledge Close() if transmit queue empty
                     **  (should already be empty)
                     */
                     TCP_Event(tcb, TCPS_FINACKED);
                     break;

                  case CLOSING:
                     /* if FIN is acked... */
                     if ( GT32(ack, tcb->sndbufseq + tcb->sndlen) ) {
                        tcb->state = TIME_WAIT;
                        tcb->sndxmitwhat = TCP_IDLE;  /* Ensure we're not probing */

                        result =
                           TCP_Timer_start( &tcb->sndxmittq.t,   /* the timer */
                                       tcb->timewaitto,     /* the timeout */
                                       0,                   /* no reload */
                                       tcp_cfg->qhead );    /* timer q head */
                        if ( result != RTCS_OK ) {
                           RTCS_log_error( ERROR_TCP,
                                                RTCSERR_TCP_TIMER_FAILURE,
                                                (uint_32)result,
                                                (uint_32)tcb,
                                                2 );
                        } /* Endif */
                     } else {
                        IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
                        TCP_PP_DROP;
                     } /* Endif */
                     break;

                  default:
                     break;

               } /* End Switch */

               break;

            case LAST_ACK:
               /*
               ** if FIN is acked...
               */
               if ( ack == tcb->sndnxt ) {  /* all data acked */
                  TCP_Event(tcb, TCPS_FINACKED);
                  TCP_Close_TCB(tcb, RTCS_OK, tcp_cfg);
                  TCP_Process_release(tcb, tcp_cfg);
                  TCP_PP_DROP;
               } /* Endif */
               break;

            case TIME_WAIT:
               break;

         } /* End Switch */

   step6:                                                   /* SIXTH */

         switch ( tcb->state ) {

            case ESTABLISHED:
            case FINWAIT_1:
            case FINWAIT_2:

               /*
               ** Check URG
               */
               if ( (flags & URG) != 0 ) {
                  if ( (tcb->status & TCPS_RURGENT) == 0 ||
                     GE32(seq + urg, tcb->rcvup)
                  ) {
                     tcb->rcvup = seq + urg + 1;
                     TCP_Event(tcb, TCPS_RURGENT);

                  } /* Endif */
               } /* Endif */

               if ( ! seg_okay ) { /* Handled all URG/RST/ACK so drop it */
                  TCP_Must_send_ack(tcb, tcp_cfg);
                  TCP_PP_DROP;
               } /* Endif */

               TCP_Process_data(tcb, tcp_cfg, seg, pcb);         /* SEVENTH */
               break;

            default:
               break;

         } /* End Switch */

         if ( ! seg_okay ) { /* Handled all URG/RST/ACK so drop it */
            TCP_Must_send_ack(tcb, tcp_cfg);
            TCP_PP_DROP;
         } /* Endif */

         switch ( tcb->state ) {

            /*
            ** do not process FIN for these states:
            */
            case SYN_SENT:
               TCP_PP_DROP;

            default:
               break;

         } /* End Switch */

         if ( (flags & FIN) != 0 ) {                                /* EIGHTH */

            /*
            ** Record receipt of FIN, if this is the first time we get it
            */
            if ( (tcb->status & TCPS_FINRECV) == 0 ) {
               tcb->rcvnxt++;
            } /* Endif */

            /*
            ** Signal 'connection closing' (receiving side)
            */
            TCP_Event(tcb,TCPS_FINRECV);

            /*
            ** FIN implies PUSHing undelivered received data to user,
            **   So terminate any Receive requests
            */
            while ( tcb->rcvHead != NULL ) {

               TCP_Reply_receive(tcb, tcp_cfg, RTCSERR_TCP_CONN_CLOSING);

               /*
               ** Setup next receive
               */
               while ( tcb->rcvHead != NULL &&
                     ! TCP_Setup_receive(tcb->rcvHead, tcb, tcp_cfg)
               ) {
               } /* Endwhile */

            } /* Endwhile */

            /*
            ** Notify socket layer in case some task is blocked on select()
            ** waiting for data on this socket.
            */
            SOCK_select_signal(tcb->SOCKET, tcb->state);
            tcb->rcvwndedge = tcb->rcvnxt;   /* zero receive window */

            TCP_Must_send_ack(tcb, tcp_cfg);       /* ACK the FIN */

            if (tcb->keepaliveto) {
               tcb->keepaliveto = 0;
            }

            switch ( tcb->state ) {

               case SYN_RECEIVED:
               case ESTABLISHED:
                  tcb->state = CLOSE_WAIT;
                  break;

               case FINWAIT_1:
                  /*
                  ** if FIN is ACKed
                  */
                  if ( GT32(ack, tcb->sndbufseq + tcb->sndlen) ) {

                     /*FALLTHROUGH*/

                  } else {
                     tcb->state = CLOSING;
                     TCP_PP_DROP;
                  } /* Endif */

                  /*FALLTHROUGH*/

               case FINWAIT_2:
                  tcb->state = TIME_WAIT;
                  tcb->sndxmitwhat = TCP_IDLE;  /* Ensure we're not probing */

                  result = TCP_Timer_start( &tcb->sndxmittq.t,   /* the timer */
                                       tcb->timewaitto,     /* the timeout */
                                       0,                   /* no reload */
                                       tcp_cfg->qhead );    /* queue head */
                  if ( result != RTCS_OK ) {
                     RTCS_log_error( ERROR_TCP, RTCSERR_TCP_TIMER_FAILURE,
                        (uint_32)result, (uint_32)tcb, 3 );
                  } /* Endif */
                  TCP_PP_DROP;

               default:
                  break;

            } /* End Switch */

         } /* Endif */

         RTCSLOG_PCB_FREE(pcb, RTCS_OK);
         RTCSPCB_free(pcb);

         RTCSLOG_FNX3(RTCSLOG_FN_TCP_Process_packet, tcb, 0);

         return;


   } /* End Switch */

   RTCSLOG_FNX3(RTCSLOG_FN_TCP_Process_packet, tcb, 1);

   return;

   tcp_pp_drop:
      RTCSLOG_PCB_FREE(pcb, RTCS_OK);
      RTCSPCB_free(pcb);

      RTCSLOG_FNX3(RTCSLOG_FN_TCP_Process_packet, tcb, 2);

      return;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP6 */











/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_packet
* Returned Values : None.
* Comments        :
*
*  Process an incoming TCP packet.  Note that the PCB is freed by
*   the routine it is consumed in.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
void TCP_Process_packet
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      RTCSPCB_PTR          pcb,     /* IN/OUT - the incoming packet */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer constants */
   )
{ /* Body */
   _ip_address       source;
   TCP_HEADER_PTR    seg;
   uint_16           seglen;
   uint_16           flags;
   uint_16           optlen;
   uchar _PTR_       opt;
   uint_32           seq,ack;
   uint_16           urg;
   int_32            result;     /* returned result */
   boolean           seg_okay;

   seg_okay = TRUE;

   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   flags = ntohs(seg->flags);

   RTCSLOG_FNE5(RTCSLOG_FN_TCP_Process_packet, tcb, pcb, tcp_cfg, flags);

   RTCSPCB_next(pcb, (flags & DATAOFS_MASK) >> (DATAOFS_SHIFT - 2));

   /*
   ** Drop packets that have illegal/abnormal flag combinations, as these
   ** are almost certainly malicious.
   **
   ** - SYN FIN is probably the best known illegal combination. Remember
   **   that SYN is used to start a connection, while FIN is used to end
   **   an existing connection. It is nonsensical to perform both actions
   **   at the same time. Many scanning tools use SYN FIN packets, because
   **   many intrusion detection systems did not catch these in the past,
   **   although most do so now. You can safely assume that any SYN FIN
   **   packets you see are malicious.
   **
   ** - SYN FIN PSH, SYN FIN RST, SYN FIN RST PSH, and other variants on
   **   SYN FIN also exist. These packets may be used by attackers who are
   **   aware that intrusion detection systems may be looking for packets
   **   with just the SYN and FIN bits set, not additional bits set. Again,
   **   these are clearly malicious.
   **
   ** - Packets should never contain just a FIN flag. FIN packets are
   **   frequently used for port scans, network mapping and other stealth
   **   activities.
   **
   ** - Some packets have absolutely no flags set at all; these are referred
   **   to as "null" packets. It is illegal to have a packet with no flags set.
   */
   if ( ((flags & SYN) && (flags & FIN)) ||
        (flags == FIN) ||
        (flags == 0) ) {
      TCP_PP_DROP;
   }

   /*
   ** compute SEG.LEN
   */
   seglen = RTCSPCB_SIZE(pcb);   /* socket layer data size */
   if ( flags & SYN ) {
      seglen++;
   } /* Endif */

   if ( flags & FIN ) {
      seglen++;
   } /* Endif */

   source = IP_source(pcb);

   /*
   ** Process options
   */
   opt = (uchar _PTR_)seg + sizeof(TCP_HEADER);
   while ( opt < RTCSPCB_DATA(pcb) ) {

      switch ( (ntohc(opt)) ) {

         case OPT_PAD:
            opt = RTCSPCB_DATA(pcb);
            break;

         case OPT_NOOP:
            opt++;
            break;

         case OPT_MSS:

            { /* Scope */

               uint_16 mss;

               optlen = ntohc(opt+1);
               if ( optlen == 0 ) {

                  IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_OPTION++);
                  TCP_PP_DROP;

               } /* Endif */
               mss = ntohs(opt+2);

               /*
               ** Compare with tcb->rcvmss since it is set to
               **  our maximum allowable, and doesn't change:
               */
               if ( tcb->rcvmss != 0 && mss > tcb->rcvmss ) {
                  mss = tcb->rcvmss;
               } /* Endif */

               tcb->sndmss = mss;
               tcb->sndmax = mss; /* minus length of any IP and TCP options; */

               if ( mss < tcb->rcvmax ) {

                  tcb->rcvmax = mss;

                  /*
                  ** Will reply after 1.75*mss bytes have been received.
                  */
                  tcb->rcv2full = mss + (mss>>1) + (mss>>2);

               } /* Endif */

               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_OPT_MSS++);
               opt += optlen;
               break;

            } /* Endscope */

         default:

            /*
            ** All options will have a length byte
            */
            optlen = ntohc(opt+1);
            if ( optlen == 0 ) {

               /*
               ** should send ICMP parameter problem
               */
               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_OPTION++);
               TCP_PP_DROP;

            } /* Endif */
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_OPT_OTHER++);
            opt += optlen;

      } /* End Switch */

   } /* Endwhile */

   /*
   **  Process packet:
   **
   **  (RFC 793 sec.3.9, 'SEGMENT ARRIVES' (pages 65-76);
   **   steps are indicated as FIRST, SECOND, THIRD, etc. as in the RFC)
   */

   seq = ntohl(seg->seq);
   ack = ntohl(seg->ack);
   urg = ntohs(seg->urgent);

   switch ( tcb->state ) {

      /*
      **   This case is executed only when in a invalid state, since
      **   packets aren't queued on CLOSED connections, and closing
      **   connections (see TCP_Close_TCB()) disown their queued packets...
      */
      case CLOSED:
         if ( (flags & RST) == 0 ) {
            TCP_STATE_DEBUG(("state = CLOSED, replying with RST on tcb %p\n", tcb));
            TCP_Send_reply_reset(tcb,
                           source,        /* source address */
                           seg,           /* received packet */
                           seglen,        /* length of received packet */
                           tcp_cfg,       /* TCP layer data */
                           FALSE
                          );
         } /* Endif */
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_LATE_DATA++);
         TCP_PP_DROP;

      case LISTEN:

         if ( (flags & RST) != 0 ) {                         /* FIRST */
            TCP_STATE_DEBUG(("state = LISTEN, heard reset on tcb %p, dropping.\n", tcb));
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
            TCP_PP_DROP;
         } /* Endif */

         if ( (flags & ACK) != 0 ) {                         /* SECOND */
            TCP_Send_reply_reset(tcb,
                           source,        /* source address */
                           seg,           /* received packet */
                           seglen,        /* length of received packet */
                           tcp_cfg,       /* TCP layer data */
                           tcb->bypass_tx_chksum
                          );
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
            TCP_PP_DROP;
         } /* Endif */

         if ( (flags & SYN) != 0 ) {                         /* THIRD */
#if RTCSCFG_TCP_MAX_HALF_OPEN
            if ((tcp_cfg->HALF_OPEN_TCB_COUNT >= RTCSCFG_TCP_MAX_HALF_OPEN)
#if RTCSCFG_TCP_MAX_CONNECTIONS
             || (tcp_cfg->CONN_COUNT >= RTCSCFG_TCP_MAX_CONNECTIONS)
#endif
               ) {
               TCP_half_open_TCB_close(tcp_cfg);
            } /* Endif */
#endif

#if RTCSCFG_TCP_MAX_CONNECTIONS
            if (tcp_cfg->CONN_COUNT >= RTCSCFG_TCP_MAX_CONNECTIONS) {
               TCP_PP_DROP;
            } /* Endif */
#endif

            CHECK_SECURITY;
            CHECK_PRECEDENCE;

            tcb = TCP_Clone_tcb(tcb);
            if (tcb == NULL) {
               TCP_PP_DROP;
            } /* Endif */

            if ( tcb->local_host == INADDR_ANY ) {
               tcb->local_host = IP_dest(pcb);
            } /* Endif */

            if ( tcb->remote_host == INADDR_ANY ) {
               tcb->remote_host = source;
               tcb->rcvmss = IP_MTU(tcb->local_host, source)
                  - (uint_16) (IP_HEADSIZE + TCP_HEADSIZE);
                if (tcb->sndmss > tcb->rcvmss)  {
                  tcb->sndmss = tcb->rcvmss;
               }
               tcb->sndmax = tcb->sndmss;
            } /* Endif */

            tcb->remote_port = ntohs(seg->source_port);

            /*
            ** TCP_Start_receiving sets state to SYN_RECEIVED
            */
            TCP_Start_receiving(tcb, seq, tcp_cfg);

            /*
            ** also below, in case SYN_SENT
            */
            TCP_Start_sending(tcb, tcp_cfg);

            /*
            ** Release the packet
            */
            RTCSLOG_PCB_FREE(pcb, RTCS_OK);
            RTCSPCB_free(pcb);

         } else {
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_SYN_EXPECTED++);
            TCP_PP_DROP;                                    /* FOURTH */

         } /* Endif */

         break;

      case SYN_SENT:

         if ( (flags & ACK) != 0 ) {                                /* FIRST */

            if ( LE32(ack, tcb->sndiss) ||
               GT32(ack, tcb->sndnxt) )
            {

               /*
               ** invalid ACK: drop, and reply if reset
               */
               if ( ! (flags & RST) ) {
                  TCP_STATE_DEBUG(("state = SYN_SENT, heard invalid ACK on tcb %p, sending RST\n", tcb));
                  TCP_Send_reply_reset(tcb,
                                 source,        /* source address */
                                 seg,           /* received packet */
                                 seglen,        /* length of received packet */
                                 tcp_cfg,       /* TCP layer data */
                                 tcb->bypass_tx_chksum
                                );
               } /* Endif */
               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
               TCP_PP_DROP;

            } /* Endif */

            if ( LT32(ack, tcb->snduna) ) {

               /*
               ** unnacceptable ACK (already ack'ed): drop
               */
               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
               TCP_PP_DROP;

            } /* Endif */

         } /* Endif */

         if ( (flags & RST) != 0 ) {                                /* SECOND */

             TCP_STATE_DEBUG(("state = SYN_SENT, heard RST on tcb %p\n", tcb));
            if ( (flags & ACK) != 0 ) {
               TCP_STATE_DEBUG(("state = SYN_SENT, heard RST+ACK on tcb %p, closing&dropping\n", tcb));
               TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_RESET, tcp_cfg);
               TCP_Process_release(tcb, tcp_cfg);
            } else {
               TCP_STATE_DEBUG(("state = SYN_SENT, ACK was not set so not closing & yes dropping on tcb %p\n", tcb));
            }/* Endif */

            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
            TCP_PP_DROP;

         } /* Endif */

         CHECK_SECURITY;            /* else reset & DROP */ /* THIRD */

         if ( (flags & ACK) != 0 ) {
            CHECK_EXACT_PRECEDENCE; /* else reset & DROP */
         } else {
            CHECK_PRECEDENCE;       /* may raise; if can't, reset & DROP */
         } /* Endif */

         if ( (flags & SYN) != 0 ) {                         /* FOURTH */

            TCP_Start_receiving(tcb, seq, tcp_cfg);   /* State=>SYN_RCVD */

            if ( (flags & ACK) != 0 ) {
               if ( GE32(ack, tcb->snduna) ) {
                  TCP_Process_ack(tcb, seg, tcp_cfg);
               } /* Endif */
            } /* Endif */

            if ( GT32(tcb->snduna, tcb->sndiss) ) {
               tcb->state = ESTABLISHED;
               TCP_Update_send_window(tcb,seg);
               TCP_Return_open(tcb, RTCS_OK, tcp_cfg);
               TCP_Event(tcb, TCPS_STARTED);
               TCP_Transmit(tcb, tcp_cfg, FALSE, TRUE);
               goto step6;             /* named from RFC793... */

            } else {
               /* force retransmit of SYN */
               TCP_Transmit(tcb, tcp_cfg, TRUE, TRUE);

            } /* Endif */

            /*
            **  any data or other controls are ignored, not queued
            **  for processing after state becomes ESTABLISHED
            */

            /*
            ** Free the packet
            */
            RTCSLOG_PCB_FREE(pcb, RTCS_OK);
            RTCSPCB_free(pcb);

         } else {
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_SYN_EXPECTED++);
            TCP_PP_DROP;                                    /* FIFTH */

         } /* Endif */

         break;

      /* all included in default
      ** case SYN_RECEIVED:
      ** case ESTABLISHED:
      ** case FINWAIT_1:
      ** case FINWAIT_2:
      ** case CLOSE_WAIT:
      ** case CLOSING:
      ** case LAST_ACK:
      ** case TIME_WAIT:
      */
      default:

        /**
         ** From RFC 793:
         **
         ** There are four cases for the acceptability test for an incoming
         ** segment:
         **
         ** Segment Receive  Test
         ** Length  Window
         ** ------- -------  -------------------------------------------
         **
         **    0       0     SEG.SEQ = RCV.NXT
         **
         **    0      >0     RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
         **
         **   >0       0     not acceptable
         **
         **   >0      >0     RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
         **               or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
         **
         ** If the RCV.WND is zero, no segments will be acceptable, but
         ** special allowance should be made to accept valid ACKs, URGs and
         ** RSTs.
         **
         ** If an incoming segment is not acceptable, an acknowledgment
         ** should be sent in reply (unless the RST bit is set, if so drop
         ** the segment and return):
         **
         **   <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
         **
         ** After sending the acknowledgment, drop the unacceptable segment
         ** and return.
         */

         /*
         ** Handles all cases explicitly.  seg_okay is used later in this procedure
         ** to drop an un-acceptable segment after processing its RST/ACK/URG fields
         ** in the case where the window is 0. Note, seglen may have been set to 1 to
         ** handle SYN or FIN flags.
         */
         { /* Scope */
            uint_16  rwindow;
            boolean  okay;

            rwindow = tcb->rcvwndedge - tcb->rcvnxt;

            if ( (rwindow == 0) &&                     /* Case 1 */
               (seglen == 0 || (flags & SYN && seglen == 1))  &&
               (seq == tcb->rcvnxt))
            {
               okay = TRUE;
               seg_okay = TRUE;

            } else if ( (rwindow > 0) &&                 /* Case 2 */
                  (seglen == 0 || (flags & SYN && seglen == 1))  &&
                   (LE32(tcb->rcvnxt,seq) &&
                    LT32(seq,tcb->rcvwndedge)))
            {
               okay = TRUE;
               seg_okay = TRUE;

            } else if ((flags & FIN) &&
                       LT32(tcb->rcvnxt,seq))
            {
              okay = TRUE;
              seg_okay = FALSE;

            } else if ( (seglen > 0)  &&                 /* Case 4 */
                   (rwindow > 0) &&
                   ((LE32(tcb->rcvnxt,seq) &&
                     LT32(seq,tcb->rcvwndedge)) ||
                    (LE32(tcb->rcvnxt,seq+seglen-1) &&
                     LT32(seq+seglen-1,tcb->rcvwndedge))))
            {
               okay = TRUE;
               seg_okay = TRUE;

            } else {                                      /* Case 3 or others failed */
               seg_okay = FALSE;
               if ( (rwindow == 0) && (flags & (RST | URG | ACK)) != 0 ) {
                  RTCSPCB_SIZE(pcb) = 0;
                  okay = TRUE;
                  /*tcp_cfg->STATS.ST_RX_ACC_BADSEGS++;*/
               } else {
                  okay = FALSE;
               } /* Endif */

            } /* Endif */

            if ( ! okay ) {
               /*
               ** segment unacceptable, sent ACK
               */
               if ( (flags & RST) == 0 ) {
                  TCP_Must_send_ack(tcb, tcp_cfg);
               } /* Endif */
               IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_DATA++);
               TCP_PP_DROP;
            } /* Endif */

         } /* Endscope */

         /*
         ** Process the RST
         */
         if ( (flags & RST) != 0 ) {                                /* SECOND */
            TCP_STATE_DEBUG(("state = default(%d), heard reset on tcb %p, ", tcb->state, tcb));

            /* draft-ietf-tcpm-tcpsecure-00.txt section 2.2 */
            if (tcb->tcpsecuredraft0) {
                if (seq == tcb->rcvnxt) {
                   TCP_STATE_DEBUG(("RST is valid, closing&dropping.\n"));
                   TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_RESET, tcp_cfg); /* aborted */
                   TCP_Process_release(tcb, tcp_cfg);
                   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
                   TCP_PP_DROP;
                }
                else
                {
                   TCP_STATE_DEBUG(("RST is suspicious, acking&dropping\n"));
                   TCP_Must_send_ack(tcb, tcp_cfg);
                   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
                   TCP_PP_DROP;
                } /* Endif */
            } else {

            TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_RESET, tcp_cfg); /* aborted */
            TCP_Process_release(tcb, tcp_cfg);
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
            TCP_PP_DROP;

            }
            TCP_STATE_DEBUG(("\n"));
         } /* Endif */

         if ( tcb->state == SYN_RECEIVED ) {                 /* THIRD */
            CHECK_SECURITY; /* else reset & DROP */
         } else {
            CHECK_TIGHT_SECURITY;
            /*
            ** else reset & TCP_Close_TCB(tcb,RTCSERR_TCP_CONN_RESET) & DROP
            */
         } /* Endif */

         /*
         ** Process the SYN
         */
         if ( (flags & SYN) != 0 ) {                         /* FOURTH */
             if (tcb->tcpsecuredraft0) {
             /*
             ** draft-ietf-tcpm-tcpsecure-00.txt section 3.2
             */
                if (seq == tcb->rcvnxt) { /* SYN and seq is exact match */
                   tcb->ackmodifier = 1; /* ack number of ack pkt will be decremented by 1 later */
                }
                else /* SYN and seq is acceptable even though not exact */
                {
                   tcb->ackmodifier = 0;
                }
                TCP_Must_send_ack(tcb, tcp_cfg);
                IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_SYN_NOT_EXPECTED++);
                TCP_PP_DROP;
             }
             else
             {
                  /*
                  ** shouldn't receive SYN
                  */
               TCP_Send_reply_reset(tcb,
                              source,   /* source address */
                               seg,     /* received packet */
                               seglen,  /* length of received packet */
                               tcp_cfg, /* TCP layer data */
                               tcb->bypass_tx_chksum
                              );
                if ( tcb->state != LISTEN ) {

                   TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_RESET, tcp_cfg); /* state=>CLOSED */
                   if (tcb->SOCKET == 0) {
                      TCP_Process_release(tcb, tcp_cfg);
                   } /* Endif */

                } /* Endif */
                IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_SYN_NOT_EXPECTED++);
                TCP_PP_DROP;
             } /* Endif */
         } /* Endif */

         /*
         ** Process the ACK
         */
         if ( (flags & ACK) == 0 ) {                          /* FIFTH */
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_ACK_EXPECTED++);
            if ( ! seg_okay ) {
               TCP_Must_send_ack(tcb, tcp_cfg);
            } /* Endif */
            TCP_PP_DROP;
         } /* Endif */

         switch ( tcb->state ) {

            case SYN_RECEIVED:

               if ( LT32(ack, tcb->snduna) ||
                  GT32(ack, tcb->sndnxt) )
               {

                  TCP_Send_reply_reset(tcb,
                                 source,        /* source address */
                                 seg,     /* received packet */
                                 seglen,  /* length of received packet */
                                 tcp_cfg, /* TCP layer data */
                                 tcb->bypass_tx_chksum
                                );
                  IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
                  TCP_PP_DROP;

               } /* Endif */

               tcb->state = ESTABLISHED;
#if RTCSCFG_TCP_MAX_HALF_OPEN
               TCB_HALF_OPEN_DROP;
#endif

               TCP_Update_send_window(tcb, seg);
               TCP_Return_open(tcb, RTCS_OK, tcp_cfg);
               TCP_Event(tcb, TCPS_STARTED);

               /*FALLTHROUGH*/

            case ESTABLISHED:
            case CLOSE_WAIT:
            case FINWAIT_1:
            case FINWAIT_2:
            case CLOSING:

               if ( GT32(ack, tcb->sndnxt) ) {
                  /*
                  ** ACK of unsent data
                  */
                  TCP_Must_send_ack(tcb, tcp_cfg);
                  IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
                  TCP_PP_DROP;
               } /* Endif */

               if ( GE32(ack, tcb->snduna) ) {

                  /*
                  ** Update send window
                  */
                  if ( LT32(tcb->sndwl1, seq) ||
                     (tcb->sndwl1 == seq && LE32(tcb->sndwl2,ack))
                  ) {
                     TCP_Update_send_window(tcb, seg);
                  } /* Endif */

                  TCP_Process_ack(tcb, seg, tcp_cfg);

               } /* Endif */

               switch ( tcb->state ) {

                  case FINWAIT_1:
                     /*
                     ** if FIN is acked...
                     */
                     if ( GT32(ack, tcb->sndbufseq + tcb->sndlen) ) {
                        tcb->state = FINWAIT_2;
                     } else {
                        break;
                     } /* Endif */

                     /*FALLTHROUGH*/

                  case FINWAIT_2:
                     /*
                     ** acknowledge Close() if transmit queue empty
                     **  (should already be empty)
                     */
                     TCP_Event(tcb, TCPS_FINACKED);
                     break;

                  case CLOSING:
                     /* if FIN is acked... */
                     if ( GT32(ack, tcb->sndbufseq + tcb->sndlen) ) {
                        tcb->state = TIME_WAIT;
                        tcb->sndxmitwhat = TCP_IDLE;  /* Ensure we're not probing */

                        result =
                           TCP_Timer_start( &tcb->sndxmittq.t,   /* the timer */
                                       tcb->timewaitto,     /* the timeout */
                                       0,                   /* no reload */
                                       tcp_cfg->qhead );    /* timer q head */
                        if ( result != RTCS_OK ) {
                           RTCS_log_error( ERROR_TCP,
                                                RTCSERR_TCP_TIMER_FAILURE,
                                                (uint_32)result,
                                                (uint_32)tcb,
                                                2 );
                        } /* Endif */
                     } else {
                        IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_ACK++);
                        TCP_PP_DROP;
                     } /* Endif */
                     break;

                  default:
                     break;

               } /* End Switch */

               break;

            case LAST_ACK:
               /*
               ** if FIN is acked...
               */
               if ( ack == tcb->sndnxt ) {  /* all data acked */
                  TCP_Event(tcb, TCPS_FINACKED);
                  TCP_Close_TCB(tcb, RTCS_OK, tcp_cfg);
                  TCP_Process_release(tcb, tcp_cfg);
                  TCP_PP_DROP;
               } /* Endif */
               break;

            case TIME_WAIT:
               break;

         } /* End Switch */

   step6:                                                   /* SIXTH */

         switch ( tcb->state ) {

            case ESTABLISHED:
            case FINWAIT_1:
            case FINWAIT_2:

               /*
               ** Check URG
               */
               if ( (flags & URG) != 0 ) {
                  if ( (tcb->status & TCPS_RURGENT) == 0 ||
                     GE32(seq + urg, tcb->rcvup)
                  ) {
                     tcb->rcvup = seq + urg + 1;
                     TCP_Event(tcb, TCPS_RURGENT);

                  } /* Endif */
               } /* Endif */

               if ( ! seg_okay ) { /* Handled all URG/RST/ACK so drop it */
                  TCP_Must_send_ack(tcb, tcp_cfg);
                  TCP_PP_DROP;
               } /* Endif */

               TCP_Process_data(tcb, tcp_cfg, seg, pcb);         /* SEVENTH */
               break;

            default:
               break;

         } /* End Switch */

         if ( ! seg_okay ) { /* Handled all URG/RST/ACK so drop it */
            TCP_Must_send_ack(tcb, tcp_cfg);
            TCP_PP_DROP;
         } /* Endif */

         switch ( tcb->state ) {

            /*
            ** do not process FIN for these states:
            */
            case SYN_SENT:
               TCP_PP_DROP;

            default:
               break;

         } /* End Switch */

         if ( (flags & FIN) != 0 ) {                                /* EIGHTH */

            /*
            ** Record receipt of FIN, if this is the first time we get it
            */
            if ( (tcb->status & TCPS_FINRECV) == 0 ) {
               tcb->rcvnxt++;
            } /* Endif */

            /*
            ** Signal 'connection closing' (receiving side)
            */
            TCP_Event(tcb,TCPS_FINRECV);

            /*
            ** FIN implies PUSHing undelivered received data to user,
            **   So terminate any Receive requests
            */
            while ( tcb->rcvHead != NULL ) {

               TCP_Reply_receive(tcb, tcp_cfg, RTCSERR_TCP_CONN_CLOSING);

               /*
               ** Setup next receive
               */
               while ( tcb->rcvHead != NULL &&
                     ! TCP_Setup_receive(tcb->rcvHead, tcb, tcp_cfg)
               ) {
               } /* Endwhile */

            } /* Endwhile */

            /*
            ** Notify socket layer in case some task is blocked on select()
            ** waiting for data on this socket.
            */
            SOCK_select_signal(tcb->SOCKET, tcb->state);
            tcb->rcvwndedge = tcb->rcvnxt;   /* zero receive window */

            TCP_Must_send_ack(tcb, tcp_cfg);       /* ACK the FIN */

            if (tcb->keepaliveto) {
               tcb->keepaliveto = 0;
            }

            switch ( tcb->state ) {

               case SYN_RECEIVED:
               case ESTABLISHED:
                  tcb->state = CLOSE_WAIT;
                  break;

               case FINWAIT_1:
                  /*
                  ** if FIN is ACKed
                  */
                  if ( GT32(ack, tcb->sndbufseq + tcb->sndlen) ) {

                     /*FALLTHROUGH*/

                  } else {
                     tcb->state = CLOSING;
                     TCP_PP_DROP;
                  } /* Endif */

                  /*FALLTHROUGH*/

               case FINWAIT_2:
                  tcb->state = TIME_WAIT;
                  tcb->sndxmitwhat = TCP_IDLE;  /* Ensure we're not probing */

                  result = TCP_Timer_start( &tcb->sndxmittq.t,   /* the timer */
                                       tcb->timewaitto,     /* the timeout */
                                       0,                   /* no reload */
                                       tcp_cfg->qhead );    /* queue head */
                  if ( result != RTCS_OK ) {
                     RTCS_log_error( ERROR_TCP, RTCSERR_TCP_TIMER_FAILURE,
                        (uint_32)result, (uint_32)tcb, 3 );
                  } /* Endif */
                  TCP_PP_DROP;

               default:
                  break;

            } /* End Switch */

         } /* Endif */

         RTCSLOG_PCB_FREE(pcb, RTCS_OK);
         RTCSPCB_free(pcb);

         RTCSLOG_FNX3(RTCSLOG_FN_TCP_Process_packet, tcb, 0);

         return;


   } /* End Switch */

   RTCSLOG_FNX3(RTCSLOG_FN_TCP_Process_packet, tcb, 1);

   return;

   tcp_pp_drop:
      RTCSLOG_PCB_FREE(pcb, RTCS_OK);
      RTCSPCB_free(pcb);

      RTCSLOG_FNX3(RTCSLOG_FN_TCP_Process_packet, tcb, 2);

      return;

} /* Endbody */
#endif //RTCSCFG_ENABLE_IP4



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP6_Service_packet
* Returned Values : int_32
* Comments        :
*
*  Process incoming TCP6 packets, possibly forward them
*   to the TCP6 server.  This is called from IP6.
*
*  Checks:
*     - for multicast packets (discards)
*     - for invalid source address
*     - that a valid TCB exists for this packet
*     - for bad checksums
*     - for TCB in CLOSED state
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6

void TCP6_Service_packet
   (
      RTCSPCB_PTR    pcb,     /* IN/OUT - the receive packet */
      void _PTR_     cfg      /* IN/OUT - TCP layer constants */
   )
{ /* Body */
   TCP_HEADER _PTR_     seg;
   int_32               chksum;
   uint_16              seglen;
   uint_16              flags;
   uint_16              dataofs;
   TCB_STRUCT_PTR       tcb;
   TCP_CFG_STRUCT_PTR   tcp_cfg;   /* TCP layer constants */

      /*IPv6 part************/
    in6_addr                ipv6source;
    in6_addr                ipv6dest;

   /**/
    uchar in_family=0;
   /**/

   RTCSLOG_FNE3(RTCSLOG_FN_TCP_Service_packet, pcb, cfg);

   tcp_cfg = (TCP_CFG_STRUCT_PTR)cfg;
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_TOTAL++);

   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   RTCSPCB_DATA_TRANSPORT(pcb) = RTCSPCB_DATA(pcb);

   /* Extracting family type from packet*/
   in_family = ntohc((pcb)->NETWORK_LAYER);
   in_family = (in_family&0xF0)>>4;

   /* using IPv6 copy macros to copy the IPv6 address structure */
   IN6_ADDR_COPY((in6_addr *)((IP6_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb))->SOURCE, &ipv6source);
   IN6_ADDR_COPY((in6_addr *)((IP6_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb))->DEST, &ipv6dest);
   if (IN6_IS_ADDR_MULTICAST(&ipv6dest))
   {  /* also check for invld dest addr */
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_MULTICASTS++);
      RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
      TCP_DROP;
   } /* Endif */
   if (IN6_ARE_ADDR_EQUAL(&ipv6source, &in6addr_any))
   {
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_SOURCE++);
      RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
      TCP_DROP;
   } /* Endif */

   flags = ntohs(seg->flags);

   /*
   ** Find a receiving TCB;
   **  Assuming this is much quicker than computing the checksum, do this
   **   first; this way we might not have to compute checksum for packets
   **   we don't want (but may have to reply a RST anyway)...
   */
   { /* Scope */
      register uint_16        rport, dport, sport;
      in6_addr                ipv6_rhost;
      in6_addr                ipv6_lhost;
      TCB_STRUCT_PTR          tcbany = NULL;
      TCB_STRUCT_PTR          tcbspec = NULL;

      dport = ntohs(seg->dest_port);
      sport = ntohs(seg->source_port);

      for ( tcb = tcp_cfg->TCBhead; tcb != NULL; tcb = tcb->next ) {

         rport = tcb->remote_port;
         /* if we inside TCP6_servece_packet function, we need set family type to AF_INET6  */
         /* it will be used for  transmit answer                                            */
      IN6_ADDR_COPY(&tcb->remote_ipv6_host, &ipv6_rhost);
      IN6_ADDR_COPY(&tcb->local_ipv6_host, &ipv6_lhost);

         if (       tcb->local_port != dport            ||
                    (rport != 0 && rport != sport)      ||
                    (
                        (!IN6_ARE_ADDR_EQUAL(&ipv6_rhost, &in6addr_any)) &&
                        (!IN6_ARE_ADDR_EQUAL(&ipv6_rhost, &ipv6source))
                    )                                   ||
                    (
                        (!IN6_ARE_ADDR_EQUAL(&ipv6_lhost, &in6addr_any)) &&
                        (!IN6_ARE_ADDR_EQUAL(&ipv6_lhost, &ipv6dest))
                    )                                   ||
                    tcb->state == BOUND
            )
         {
            continue;
         } /* Endif */

         /*
         ** Found candidate TCB...
         */
         if(rport != 0 && (!IN6_ARE_ADDR_EQUAL(&ipv6_rhost, &in6addr_any)))
         {   /* is conn'n all specified? */
            if(tcb->state == TIME_WAIT)
            {
               tcbspec = NULL;
               tcbany = NULL;
               TCP_STATE_DEBUG(("setting RST flag in %p\n", tcb));
               flags |= RST;
               htons(seg->flags, flags);
               break;
            }
            else
            {
               tcbspec = tcb;
               continue;
            }
         } /* Endif */
         /*
         ** Connection not completely specified in TCB, there might be a TCB
         **   which is more specific;
         **
         **  Give priority to TCB's which have specified one of rport
         **   or rhost, over a TCB which specified neither:
         */
         if(
                (
                    rport != 0 ||
                    (!IN6_ARE_ADDR_EQUAL(&ipv6_rhost, &in6addr_any)) ||
                    tcbany == NULL ||
                    (tcb->af == AF_INET6)
                ) &&
                (
                    (tcb->if_scope_id ==0)||
                    (tcb->if_scope_id == ip6_if_get_scope_id(pcb->IFSRC))
                )
           )
         {
            tcbany = tcb;
         } /* Endif */

      } /* Endfor */

      tcb = tcbspec;

      if ( tcb == NULL ) {
         tcb = tcbany;
      } /* Endif */

   } /* Endscope */

   RTCSLOG_PCB_READ(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_TCP), 0);
   if ( tcb == NULL ) {

      /*tcp_cfg->STATS.ST_NOCLIENTS++; */
      if ( flags & RST ) {
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_DISCARDED++);
         RTCSLOG_PCB_FREE(pcb, RTCS_OK);
         TCP_DROP;
      } /* Endif */

      /*
      ** otherwise must reply with a RST (below)...
      */

   } /* Endif */

   /*
   ** Check the checksum unless we're directed to bypass it.
   */
   if(!tcb || !tcb->bypass_rx_chksum)
   {
     /*IP6 use different method for calculation checksum*/
      chksum = IP6_Sum_pseudo(RTCSPCB_SIZE(pcb), pcb);
      chksum = IP_Sum_PCB(chksum, pcb);
      if (chksum != 0xFFFF) {

         /*
         ** bad chksum, discarding packet
         */
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_CHECKSUM++);
         RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_CHECKSUM);
         TCP_DROP;

      } /* Endif */
   } /* Endif */

   /*
   ** skip header
   */
   dataofs = (flags & DATAOFS_MASK) >> (DATAOFS_SHIFT - 2);

   /*
   ** Also check for CLOSED state, because we mustn't queue a packet
   **   on a closed connection (it may be lost).
   */
   if (tcb == NULL || tcb->state == CLOSED || tcb->state == TIME_WAIT) {

      if ( flags & RST ) {
         TCP_STATE_DEBUG(("state = CLOSED || TIME_WAIT, heard reset on tcb %p, dropping.\n", tcb));
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
         RTCSLOG_PCB_FREE(pcb, RTCS_OK);
         TCP_DROP;
      } /* Endif */

      seglen = RTCSPCB_SIZE(pcb) - dataofs;
      if ( flags & SYN ) {
         seglen++;
      } /* Endif */

      if ( flags & FIN ) {
         seglen++;
      } /* Endif */

      TCP6_Send_reply_reset(tcb,
                            &ipv6source,        /* source address */
                             seg,               /* received packet */
                             seglen,            /* length of received packet */
                             tcp_cfg,           /* TCP layer data */
                             tcb ? tcb->bypass_tx_chksum : FALSE
                           );
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_LATE_DATA++);
      RTCSLOG_PCB_FREE(pcb, RTCS_OK);
      TCP_DROP;
   } /* Endif */

   /*
   ** Packet may now be processed, so send upwards.
   */
   TCP6_Process_packet(tcb, pcb, tcp_cfg);  /* (frees the PCB) */

   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Service_packet, 0);

   return;

   tcp_sp_drop:
      RTCSPCB_free(pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Service_packet, 1);
      return;

} /* Endbody */

#endif //RTCSCFG_ENABLE_IP6


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Service_packet
* Returned Values : int_32
* Comments        :
*
*  Process incoming TCP packets, possibly forward them
*   to the TCP server.  This is called from IP.
*
*  Checks:
*     - for multicast packets (discards)
*     - for invalid source address
*     - that a valid TCB exists for this packet
*     - for bad checksums
*     - for TCB in CLOSED state
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
void TCP4_Service_packet
   (
      RTCSPCB_PTR    pcb,     /* IN/OUT - the receive packet */
      void _PTR_     cfg      /* IN/OUT - TCP layer constants */
   )
{ /* Body */
   _ip_address          source,
                        dest;
   TCP_HEADER _PTR_     seg;
   int_32               chksum;
   uint_16              seglen;
   uint_16              flags;
   uint_16              dataofs;
   TCB_STRUCT_PTR       tcb;
   TCP_CFG_STRUCT_PTR   tcp_cfg;   /* TCP layer constants */

   RTCSLOG_FNE3(RTCSLOG_FN_TCP_Service_packet, pcb, cfg);

   tcp_cfg = (TCP_CFG_STRUCT_PTR)cfg;
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_TOTAL++);

   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   RTCSPCB_DATA_TRANSPORT(pcb) = RTCSPCB_DATA(pcb);

   source = IP_source(pcb);
   dest   = IP_dest(pcb);

   if (IN_MULTICAST(dest)) {       /* also check for invld dest addr */
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_MULTICASTS++);
      RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
      TCP_DROP;
   } /* Endif */

   if (source == INADDR_ANY)  {
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_SOURCE++);
      RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
      TCP_DROP;
   } /* Endif */

   flags = ntohs(seg->flags);

   /*
   ** Find a receiving TCB;
   **  Assuming this is much quicker than computing the checksum, do this
   **   first; this way we might not have to compute checksum for packets
   **   we don't want (but may have to reply a RST anyway)...
   */
   { /* Scope */

      register uint_16        rport, dport, sport;
      register _ip_address    rhost, lhost;
      TCB_STRUCT_PTR          tcbany = NULL;
      TCB_STRUCT_PTR          tcbspec = NULL;

      dport = ntohs(seg->dest_port);
      sport = ntohs(seg->source_port);

      for ( tcb = tcp_cfg->TCBhead; tcb != NULL; tcb = tcb->next ) {

         rport = tcb->remote_port;
         rhost = tcb->remote_host;
         lhost = tcb->local_host;

         if ( tcb->local_port != dport ||
             (rport != 0 && rport != sport) ||
             (rhost != INADDR_ANY && rhost != source) ||
             (lhost != INADDR_ANY && lhost != dest) ||
              tcb->state == BOUND)
         {
            continue;
         } /* Endif */

         /*
         ** Found candidate TCB...
         */
         if ( rport != 0 && rhost != INADDR_ANY ) {   /* is conn'n all specified? */
            if (tcb->state == TIME_WAIT) {
               tcbspec = NULL;
               tcbany = NULL;
               TCP_STATE_DEBUG(("setting RST flag in %p\n", tcb));
               flags |= RST;
               htons(seg->flags, flags);
               break;
            } else {
               tcbspec = tcb;
               continue;
            }
         } /* Endif */

         /*
         ** Connection not completely specified in TCB, there might be a TCB
         **   which is more specific;
         **
         **  Give priority to TCB's which have specified one of rport
         **   or rhost, over a TCB which specified neither:
         */
         if ( rport != 0 || rhost != INADDR_ANY || tcbany == NULL || (tcb->af == AF_INET) ) {
            tcbany = tcb;
         } /* Endif */
      } /* Endfor */
      tcb = tcbspec;
      if ( tcb == NULL )
      {
         tcb = tcbany;
      } /* Endif */
   } /* Endscope */

   RTCSLOG_PCB_READ(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_TCP), 0);
   if ( tcb == NULL ) {
      /*tcp_cfg->STATS.ST_NOCLIENTS++; */
      if ( flags & RST ) {
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_DISCARDED++);
         RTCSLOG_PCB_FREE(pcb, RTCS_OK);
         TCP_DROP;
      } /* Endif */

      /*
      ** otherwise must reply with a RST (below)...
      */

   } /* Endif */

   /*
   ** Check the checksum unless we're directed to bypass it.
   */
   if (!tcb || !tcb->bypass_rx_chksum) {
      chksum = IP_Sum_pseudo(RTCSPCB_SIZE(pcb), pcb, -1);
      chksum = IP_Sum_PCB(chksum, pcb);
      if (chksum != 0xFFFF) {

         /*
         ** bad chksum, discarding packet
         */
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_CHECKSUM++);
         RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_CHECKSUM);
         TCP_DROP;

      } /* Endif */
   } /* Endif */

   /*
   ** skip header
   */
   dataofs = (flags & DATAOFS_MASK) >> (DATAOFS_SHIFT - 2);

   /*
   ** Also check for CLOSED state, because we mustn't queue a packet
   **   on a closed connection (it may be lost).
   */
   if (tcb == NULL || tcb->state == CLOSED || tcb->state == TIME_WAIT) {

      if ( flags & RST ) {
         TCP_STATE_DEBUG(("state = CLOSED || TIME_WAIT, heard reset on tcb %p, dropping.\n", tcb));
         IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
         RTCSLOG_PCB_FREE(pcb, RTCS_OK);
         TCP_DROP;
      } /* Endif */

      seglen = RTCSPCB_SIZE(pcb) - dataofs;
      if ( flags & SYN ) {
         seglen++;
      } /* Endif */

      if ( flags & FIN ) {
         seglen++;
      } /* Endif */

      TCP_Send_reply_reset(
                           tcb,
                           source,  /* source address */
                           seg,     /* received packet */
                           seglen,  /* length of received packet */
                           tcp_cfg, /* TCP layer data */
                           tcb ? tcb->bypass_tx_chksum : FALSE
                          );
      IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_LATE_DATA++);
      RTCSLOG_PCB_FREE(pcb, RTCS_OK);
      TCP_DROP;

   } /* Endif */

   /*
   ** Packet may now be processed, so send upwards.
   */
   TCP_Process_packet(tcb, pcb, tcp_cfg);  /* (frees the PCB) */

   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Service_packet, 0);

   return;

   tcp_sp_drop:
      RTCSPCB_free(pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Service_packet, 1);
      return;

} /* Endbody */

#endif //RTCSCFG_ENABLE_IP4



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP6_Service_packet
* Returned Values : int_32
* Comments        :
*
*  Process incoming TCP6 or TCP4 packets, possibly forward them
*   to the TCP server.  This function support IPv6  and IPv4.
*
*  Checks:
*     - for multicast packets (discards)
*     - for invalid source address
*     - that a valid TCB exists for this packet
*     - for bad checksums
*     - for TCB in CLOSED state
*
*END*-----------------------------------------------------------------*/
void TCP_Service_packet
   (
      RTCSPCB_PTR    pcb,     /* IN/OUT - the receive packet */
      void _PTR_     cfg      /* IN/OUT - TCP layer constants */
   )
{ /* Body */
   TCP_HEADER _PTR_     seg;
   int_32               chksum;
   uint_16              seglen;
   uint_16              flags;
   uint_16              dataofs;
   TCB_STRUCT_PTR       tcb;
   TCP_CFG_STRUCT_PTR   tcp_cfg;   /* TCP layer constants */

    /* IPv4 part */
#if RTCSCFG_ENABLE_IP4
    _ip_address         ipv4source;
    _ip_address         ipv4dest;
#endif
    /* IPv6 part */
#if RTCSCFG_ENABLE_IP6
    in6_addr            ipv6source;
    in6_addr            ipv6dest;
#endif
   /*-/\-*/
    uchar       in_family   =   0;
    uint_32     error       =   0;
   /*-\/-*/

   RTCSLOG_FNE3(RTCSLOG_FN_TCP_Service_packet, pcb, cfg);

   tcp_cfg = (TCP_CFG_STRUCT_PTR)cfg;
   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_RX_TOTAL++);

   seg = (TCP_HEADER _PTR_)RTCSPCB_DATA(pcb);
   RTCSPCB_DATA_TRANSPORT(pcb) = RTCSPCB_DATA(pcb);


   /* Extracting family type from packet*/
    in_family = ntohc((pcb)->NETWORK_LAYER);
    in_family = (in_family&0xF0)>>4;

    /* Checking family type*/
    error = 1;
#if RTCSCFG_ENABLE_IP4
    if (in_family == IPV4)
    {
        error = 0;
    }
#endif
#if RTCSCFG_ENABLE_IP6
    if (in_family == IPV6)
    {
        error = 0;
    }
#endif
    if (error)
    {   /* If inet protocol is not IPv4 or IPv6 go out with error. */
        IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_SOURCE++);
        RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
        TCP_DROP;
    }

    /* copy the IP address from packet */
#if RTCSCFG_ENABLE_IP4
    if(in_family == IPV4)
    {
        ipv4source = IP_source(pcb);
        ipv4dest   = IP_dest(pcb);

        if (IN_MULTICAST(ipv4dest))
        {       /* also check for invld dest addr */
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_MULTICASTS++);
            RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
            TCP_DROP;
        } /* Endif */
        if (ipv4source == INADDR_ANY)
        {
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_SOURCE++);
            RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
            TCP_DROP;
        } /* Endif */

    }
#endif
#if RTCSCFG_ENABLE_IP6
    if(in_family == IPV6)
    {
        IN6_ADDR_COPY((in6_addr *)((IP6_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb))->SOURCE, &ipv6source);
        IN6_ADDR_COPY((in6_addr *)((IP6_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb))->DEST, &ipv6dest);

        if (IN6_IS_ADDR_MULTICAST(&ipv6dest))
        {       /* also check for invld dest addr */
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_MULTICASTS++);
            RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
            TCP_DROP;
        } /* Endif */
        if (IN6_ARE_ADDR_EQUAL(&ipv6source, &in6addr_any))
        {
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_SOURCE++);
            RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_HEADER);
            TCP_DROP;
        } /* Endif */

    }
#endif

   flags = ntohs(seg->flags);

   /*
   ** Find a receiving TCB;
   **  Assuming this is much quicker than computing the checksum, do this
   **   first; this way we might not have to compute checksum for packets
   **   we don't want (but may have to reply a RST anyway)...
   */
    { /* Scope */

      register uint_16        rport, dport, sport;
#if RTCSCFG_ENABLE_IP4
      register _ip_address      ipv4_rhost;
      register _ip_address      ipv4_lhost;
#endif

#if RTCSCFG_ENABLE_IP6
      in6_addr                  ipv6_rhost;
      in6_addr                  ipv6_lhost;
#endif

      TCB_STRUCT_PTR          tcbany = NULL;
      TCB_STRUCT_PTR          tcbspec = NULL;

      dport = ntohs(seg->dest_port);
      sport = ntohs(seg->source_port);


#if RTCSCFG_ENABLE_IP4
      if(in_family == IPV4)
      {
        for ( tcb = tcp_cfg->TCBhead; tcb != NULL; tcb = tcb->next )
        {

             /* We need check SOCKET family.If SOCKET was opened for another family,try another socket */
             if((tcb->SOCKET))
             {
                if(((SOCKET_STRUCT_PTR)(tcb->SOCKET))->AF != AF_INET)
                {
                    continue;
                }
             }

            rport = tcb->remote_port;
            /* we need setup family type to AF_INET */
            /* it will be used for  transmit answer */
            tcb->af = AF_INET;

            ipv4_rhost = tcb->remote_host;
            ipv4_lhost = tcb->local_host;

            if (        tcb->local_port != dport            ||
                        (rport != 0 && rport != sport)      ||
                        (
                            ipv4_rhost != INADDR_ANY &&
                            ipv4_rhost != ipv4source
                        )                                   ||
                        (
                            ipv4_lhost != INADDR_ANY &&
                            ipv4_lhost != ipv4dest
                        )                                   ||
                        tcb->state == BOUND
                )
            {
                continue;
            } /* Endif */

            /*
            ** Found candidate TCB...
            */
            if ( rport != 0 && ipv4_rhost != INADDR_ANY )
            {   /* is conn'n all specified? */
                if(tcb->state == TIME_WAIT)
                {
                    tcbspec = NULL;
                    tcbany = NULL;
                    TCP_STATE_DEBUG(("setting RST flag in %p\n", tcb));
                    flags |= RST;
                    htons(seg->flags, flags);
                    break;
                }
                else
                {
                    tcbspec = tcb;
                    continue;
                }
            } /* Endif */

            /*
            ** Connection not completely specified in TCB, there might be a TCB
            **   which is more specific;
            **
            **  Give priority to TCB's which have specified one of rport
            **   or rhost, over a TCB which specified neither:
            */
            if( rport != 0 || ipv4_rhost != INADDR_ANY || tcbany == NULL || (tcb->af == AF_INET))
            {
                tcbany = tcb;
            } /* Endif */
        } /* Endfor */
      }/*End if IPV4*/
#endif

#if RTCSCFG_ENABLE_IP6
      if(in_family == IPV6)
      {
        for ( tcb = tcp_cfg->TCBhead; tcb != NULL; tcb = tcb->next )
        {
            /* We need check SOCKET family.If SOCKET was opened for another family, try another socket. */
            if((tcb->SOCKET))
            {
                if(((SOCKET_STRUCT_PTR)(tcb->SOCKET))->AF != AF_INET6)
                {
                    continue;
                }
            }

            rport = tcb->remote_port;
            /* if we inside TCP6_servece_packet function, we need set family type to AF_INET6  */
            /* it will be used for  transmit answer                                            */
            tcb->af = AF_INET6;
            IN6_ADDR_COPY(&tcb->remote_ipv6_host, &ipv6_rhost);
            IN6_ADDR_COPY(&tcb->local_ipv6_host, &ipv6_lhost);

            if (       tcb->local_port != dport            ||
                        (rport != 0 && rport != sport)      ||
                        (
                            (!IN6_ARE_ADDR_EQUAL(&ipv6_rhost, &in6addr_any)) &&
                            (!IN6_ARE_ADDR_EQUAL(&ipv6_rhost, &ipv6source))

                        )                                   ||

                        (
                            (!IN6_ARE_ADDR_EQUAL(&ipv6_lhost, &in6addr_any)) &&
                            (!IN6_ARE_ADDR_EQUAL(&ipv6_lhost, &ipv6dest))

                        )                                   ||
                        tcb->state == BOUND
                )
            {
                continue;
            } /* Endif */

            /*
            ** Found candidate TCB...
            */
            if(rport != 0 && (!IN6_ARE_ADDR_EQUAL(&ipv6_rhost, &in6addr_any)))
            {   /* is conn'n all specified? */
                if(tcb->state == TIME_WAIT)
                {
                    tcbspec = NULL;
                    tcbany = NULL;
                    TCP_STATE_DEBUG(("setting RST flag in %p\n", tcb));
                    flags |= RST;
                    htons(seg->flags, flags);
                    break;
                }
                else
                {
                    tcbspec = tcb;
                    continue;
                }
            } /* Endif */

            /*
            ** Connection not completely specified in TCB, there might be a TCB
            **   which is more specific;
            **
            **  Give priority to TCB's which have specified one of rport
            **   or rhost, over a TCB which specified neither:
            */
            if( rport != 0 || (!IN6_ARE_ADDR_EQUAL(&ipv6_rhost, &in6addr_any)) || tcbany == NULL || (tcb->af == AF_INET6))
            {
                tcbany = tcb;
            } /* Endif */
        } /* Endfor */
      }/*End if IPV6*/
#endif

        tcb = tcbspec;
        if ( tcb == NULL )
        {
            tcb = tcbany;
        } /* Endif */

    } /* Endscope */

    RTCSLOG_PCB_READ(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_TCP), 0);

    if ( tcb == NULL )
    {
        /*tcp_cfg->STATS.ST_NOCLIENTS++; */
        if ( flags & RST )
        {
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.COMMON.ST_TX_DISCARDED++);
            RTCSLOG_PCB_FREE(pcb, RTCS_OK);
            TCP_DROP;
        }
        /*
        ** otherwise must reply with a RST (below)...
        */

    }
   /*
   ** Check the checksum unless we're directed to bypass it.
   */
    if(!tcb || !tcb->bypass_rx_chksum)
    {

#if RTCSCFG_ENABLE_IP4
        if(in_family == IPV4)
        {
            chksum = IP_Sum_pseudo(RTCSPCB_SIZE(pcb), pcb, -1);
        }
#endif
#if RTCSCFG_ENABLE_IP6
        if(in_family == IPV6)
        {
            /*IP6 use different method for calculation checksum*/
            chksum = IP6_Sum_pseudo(RTCSPCB_SIZE(pcb), pcb);
        }
#endif
        chksum = IP_Sum_PCB(chksum, pcb);
        if (chksum != 0xFFFF)
        {
            /*
            ** bad chksum, discarding packet
            */
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_BAD_CHECKSUM++);
            RTCSLOG_PCB_FREE(pcb, RTCSERR_TCP_BAD_CHECKSUM);
            TCP_DROP;
        } /* Endif */
    } /* Endif */

   /*
   ** skip header
   */
    dataofs = (flags & DATAOFS_MASK) >> (DATAOFS_SHIFT - 2);

   /*
   ** Also check for CLOSED state, because we mustn't queue a packet
   **   on a closed connection (it may be lost).
   */
    if (tcb == NULL || tcb->state == CLOSED || tcb->state == TIME_WAIT)
    {
        if ( flags & RST )
        {
            TCP_STATE_DEBUG(("state = CLOSED || TIME_WAIT, heard reset on tcb %p, dropping.\n", tcb));
            IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_RESET++);
            RTCSLOG_PCB_FREE(pcb, RTCS_OK);
            TCP_DROP;
        } /* Endif */

        seglen = RTCSPCB_SIZE(pcb) - dataofs;
        if( flags & SYN )
        {
            seglen++;
        } /* Endif */

        if( flags & FIN )
        {
            seglen++;
        } /* Endif */

#if RTCSCFG_ENABLE_IP4
        if(in_family == IPV4)
        {

            TCP_Send_reply_reset    (   tcb,
                                        ipv4source,        /* source address */
                                        seg,     /* received packet */
                                        seglen,  /* length of received packet */
                                        tcp_cfg, /* TCP layer data */
                                        tcb ? tcb->bypass_tx_chksum : FALSE
                                    );
        }
#endif
#if RTCSCFG_ENABLE_IP6
        if(in_family == IPV6)
        {

            TCP6_Send_reply_reset   (   tcb,
                                        &ipv6source,        /* source address */
                                        seg,     /* received packet */
                                        seglen,  /* length of received packet */
                                        tcp_cfg, /* TCP layer data */
                                        tcb ? tcb->bypass_tx_chksum : FALSE
                                    );
        }
#endif
        IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_RX_LATE_DATA++);
        RTCSLOG_PCB_FREE(pcb, RTCS_OK);
        TCP_DROP;
    } /* Endif */
    /*
    ** Packet may now be processed, so send upwards.
    */

#if RTCSCFG_ENABLE_IP4
    if(in_family == IPV4)
    {
        TCP_Process_packet(tcb, pcb, tcp_cfg);  /* (frees the PCB) */
    }
#endif
#if RTCSCFG_ENABLE_IP6
    if(in_family == IPV6)
    {
        TCP6_Process_packet(tcb, pcb, tcp_cfg);  /* (frees the PCB) */
    }
#endif


   RTCSLOG_FNX2(RTCSLOG_FN_TCP_Service_packet, 0);

   return;

   tcp_sp_drop:
      RTCSPCB_free(pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_TCP_Service_packet, 1);
      return;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/msgq.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: msgq.c$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Message component.
 *
 *END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_MESSAGES
#include "message.h"
#include "msg_prv.h"
#if MQX_USE_IPC
#include "ipc.h"
#include "ipcrtprv.h"
#endif
#define DEQUEUE_TOP_MSG_ENTRY(mq, im, m, td) \
               --(mq->NO_OF_ENTRIES); \
               im = mq->FIRST_MSG_PTR; \
               mq->FIRST_MSG_PTR = im->NEXT; \
               if ( mq->FIRST_MSG_PTR == NULL ) { \
                  mq->LAST_MSG_PTR = NULL; \
               } else { \
                  (mq->FIRST_MSG_PTR)->PREV = NULL; \
               } \
               if ( mq->TD_PTR ) { \
                  --(mq->TD_PTR->MESSAGES_AVAILABLE); \
               } \
               m = &im->MESSAGE; \
               im->QUEUED = FALSE; \
               im->TD_PTR = td;

/*!
 * \brief Sends the message to multiple message queues.
 * 
 * For conditions on the message, see _msgq_send().
 * \n The function sends a priority 0 message.
 * \n For each copy of the message, the function sets the target queue ID in the 
 * message header with a queue ID from the array of queue IDs.
 * \n The function does not block.
 * \n If the function returns successfully, the message is no longer a resource 
 * of the task.
 * \n It is the responsibility of the application to handle the consequences of 
 * messages being lost.
 * 
 * \param[in] input_msg_ptr Pointer to the message to be sent.
 * \param[in] qid_ptr       An array of _queue_ids, MSGQ_NULL_QUEUE_ID terminated
 * to which the message is to be sent.  A successfull message send will result in 
 * the queue id being overwritten with a MSGQ_NULL_QUEUE_ID.
 * \param[in] pool          One of the following:
 * \li Pool ID to allocate messages from.
 * \li MSGPOOL_NULL_POOL_ID (Messages will be allocated from a system message pool.)
 * 
 * \return Number that represents the size of the array of queue IDs (success).
 * \return Number less than the size of the array of queue IDs (failure).
 * 
 * \warning Calls _mem_copy()
 * \warning Calls _mem_alloc() or _mem_alloc_system() depending on whether pool_id 
 * represents a private or system message pool.
 * \warning Might dispatch one or more tasks.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_INVALID_PARAMETER (Qid_ptr does not point to a valid queue ID.)
 * \li MSGPOOL_OUT_OF_MESSAGES (MQX could not allocate a message from the message 
 * pool.)
 * \li MSGQ_INVALID_MESSAGE (Msg_ptr does not point to a message that was allocated 
 * as described for _msgq_send().)
 * \li Task error codes from _msg_alloc() (If pool_id represents a private 
 * message pool.)
 * \li Task error codes from _msg_alloc_system() (If pool_id represents a system 
 * message pool.) 
 * 
 * \see _msgq_send   
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks
 * \see _msgq_receive_until
 * \see _msgq_poll
 * \see _msgq_send_priority
 * \see _msgq_send_urgent
 * \see _task_set_error
 * \see _mem_alloc
 * \see _mem_alloc_from
 * \see _mem_alloc_system
 * \see _mem_alloc_system_from
 * \see _mem_alloc_system_zero
 * \see _mem_alloc_system_zero_from
 * \see _mem_alloc_zero
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align
 * \see _mem_alloc_align_from
 * \see _mem_alloc_at
 * \see _mem_copy
 * \see MESSAGE_HEADER_STRUCT   
 */ 
_mqx_uint _msgq_send_broadcast
(
    pointer         input_msg_ptr,
    _queue_id _PTR_ qid_ptr,
    _pool_id        pool
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    MESSAGE_HEADER_STRUCT_PTR msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)
    input_msg_ptr;
    MESSAGE_HEADER_STRUCT_PTR sending_msg_ptr;
#if MQX_CHECK_ERRORS
    INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
#endif
    _mqx_uint size;
    _mqx_uint count;
    _mqx_uint error;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE4(KLOG_msgq_send_broadcast, msg_ptr, qid_ptr, pool);

    count = 0;

#if MQX_CHECK_ERRORS
    if (msg_ptr == NULL )
    {
        _task_set_error(MSGQ_INVALID_MESSAGE);
        _KLOGX2(KLOG_msgq_send_broadcast, count);
        return(count);
    }/* Endif */
    if (qid_ptr == NULL )
    {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_msgq_send_broadcast, count);
        return(count);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);
    if (imsg_ptr->VALID != MSG_VALID)
    {
        /* An invalid message was input by the application. */
        _task_set_error(MSGQ_INVALID_MESSAGE);
        return(count);
    } /* Endif */
#endif

    if (*qid_ptr == MSGQ_NULL_QUEUE_ID )
    {
        /* Nothing to do */
        _KLOGX2(KLOG_msgq_send_broadcast, count);
        return(count);
    } /* Endif */

    size = msg_ptr->SIZE;

    while (*(qid_ptr + 1) != MSGQ_NULL_QUEUE_ID)
    {
        if (pool == MSGPOOL_NULL_POOL_ID)
        {
            sending_msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)
            _msg_alloc_system((_msg_size)size);
        }
        else
        {
            sending_msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)_msg_alloc(pool);
        } /* Endif */
        
        if (sending_msg_ptr != NULL)
        {
            _mem_copy(msg_ptr, sending_msg_ptr, (_mem_size)size);
            sending_msg_ptr->TARGET_QID = *qid_ptr;
            error = _task_get_error();
            if (_msgq_send_internal(sending_msg_ptr, FALSE, *qid_ptr++) )
            {
                count++;
            } /* Endif */
            _task_set_error(error);
        } /* Endif */
        else {
            // out of messages, stop sending loop
            // task error is set to MSGPOOL_OUT_OF_MESSAGES in _msg_alloc
            break;
        }
    } /* Endwhile */

    msg_ptr->TARGET_QID = *qid_ptr;
    error = _task_get_error();
    if (_msgq_send_internal(msg_ptr, FALSE, *qid_ptr))
    {
        count++;
    } /* Endif */
    _task_set_error(error);
    _KLOGX2(KLOG_msgq_send_broadcast, count);
    return(count);

} /* Endbody */

/*!
 * \brief Closes the message queue.
 * 
 * Only the task that opens a private message queue (_msgq_open()) can close it. 
 * Any task can close an opened system message queue (_msgq_open_system()).
 * \li If _msgq_close() closes the message queue, it frees any messages that are 
 * in the queue.
 * \li If _msgq_close() closes the message queue, a task can no longer use 
 * queue_id to access the message queue.
 * \li The message queue can subsequently be opened again with _msgq_open() or
 * _msgq_open_system().
 * 
 * \param[in] queue_id Queue ID of the message queue to be closed.
 * 
 * \return TRUE (Success.) or FALSE (Failure.)
 * 
 * \warning Calls _msg_free() to free messages that are in the queue.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is not valid for this processor.)
 * \li MSGQ_NOT_QUEUE_OWNER (Task that got queue_id did so by opening a private 
 * message queue (_msgq_open()) and is not the task calling _msgq_close().)
 * \li MSGQ_QUEUE_IS_NOT_OPEN (Queue_id does not represent a queue that is open.)
 * \li Task error codes from _msg_free() (If MQX cannot free messages that are 
 * in the queue.)
 * 
 * \see _msgq_open_system
 * \see _msgq_open
 * \see _msg_free
 * \see _msgq_send
 * \see _task_set_error       
 */ 
boolean _msgq_close
(
    _queue_id queue_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    register TD_STRUCT_PTR               td_ptr;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register MSGQ_STRUCT_PTR             msgq_ptr;
    register MSGQ_STRUCT_PTR             td_msgq_ptr;
    register MSGQ_STRUCT_PTR             qprev_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR tmp_imsg_ptr;
    register uint_16                     queue;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msgq_close, queue_id);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msgq_close, FALSE, MQX_COMPONENT_DOES_NOT_EXIST);
        return(FALSE);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if ( PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER )
    {
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
        _KLOGX3(KLOG_msgq_close, FALSE, MSGQ_INVALID_QUEUE_ID);
        return FALSE;
    } /* Endif */
#endif

    queue = QUEUE_FROM_QID(queue_id);

#if MQX_CHECK_ERRORS
    if ( ! VALID_QUEUE(queue) )
    {
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
        _KLOGX3(KLOG_msgq_close, FALSE, MSGQ_INVALID_QUEUE_ID);
        return FALSE;
    } /* Endif */
#endif

    msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];

#if MQX_CHECK_ERRORS
    if ( msgq_ptr->QUEUE != (queue) )
    {
        _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
        _KLOGX3(KLOG_msgq_close, FALSE, MSGQ_QUEUE_IS_NOT_OPEN);
        return FALSE;
    } /* Endif */
#endif

    td_ptr = kernel_data->ACTIVE_PTR;
    if ( ((msgq_ptr->TD_PTR == NULL) || (msgq_ptr->TD_PTR == td_ptr)))
    {
        /*
         *  this queue is currently active and is owned by
         *  the requesting task so DELETE the queue.
         */
        _int_disable();
        if ( msgq_ptr->TD_PTR != NULL )
        {
            td_ptr->MESSAGES_AVAILABLE -= msgq_ptr->NO_OF_ENTRIES;
        } /* Endif */
        imsg_ptr = msgq_ptr->FIRST_MSG_PTR;
        while ( imsg_ptr != NULL )
        {
            tmp_imsg_ptr = imsg_ptr->NEXT;
            imsg_ptr->QUEUED = FALSE;
            _msg_free((pointer)&imsg_ptr->MESSAGE);
            imsg_ptr = tmp_imsg_ptr;
        } /* Endwhile */
        msgq_ptr->FIRST_MSG_PTR = NULL;

        if ( msgq_ptr->TD_PTR )
        {
            /* Remove the queue from the Task descriptors linked list */
            td_msgq_ptr = (MSGQ_STRUCT_PTR)td_ptr->MSG_QUEUE_HEAD;
            if ( td_msgq_ptr == msgq_ptr )
            {
                td_ptr->MSG_QUEUE_HEAD = (pointer)td_msgq_ptr->NEXT_MSGQ_PTR;
                if ( td_ptr->MSG_QUEUE_HEAD == NULL )
                {
                    td_ptr->MSG_QUEUE_TAIL = NULL;
                } /* Endif */
            }
            else
            {
                qprev_ptr = td_msgq_ptr;
                td_msgq_ptr = qprev_ptr->NEXT_MSGQ_PTR;
                while ( td_msgq_ptr != msgq_ptr )
                {
                    qprev_ptr = td_msgq_ptr;
                    td_msgq_ptr = qprev_ptr->NEXT_MSGQ_PTR;
                } /* Endwhile */
                qprev_ptr->NEXT_MSGQ_PTR = td_msgq_ptr->NEXT_MSGQ_PTR;
                if ( td_ptr->MSG_QUEUE_TAIL == (pointer)td_msgq_ptr )
                {
                    td_ptr->MSG_QUEUE_TAIL = (pointer)qprev_ptr;
                } /* Endif */
            } /* Endif */
        } /* Endif */
        msgq_ptr->QUEUE = 0;
        _int_enable();
        _KLOGX3(KLOG_msgq_close, TRUE, 0);
        return TRUE;
    }
    else
    {
        _task_set_error(MSGQ_NOT_QUEUE_OWNER);
        _KLOGX3(KLOG_msgq_close, FALSE, MSGQ_NOT_QUEUE_OWNER);
        return FALSE;
    } /* Endif */

} /* Endbody */

/*!
 * \brief Gets the number of messages in the message queue.
 * 
 * The message queue must be previously opened on this processor.
 * 
 * \param[in] queue_id One of the following:
 * \li Queue ID of the queue to be checked.
 * \li MSGQ_ANY_QUEUE (Get the number of messages waiting in all message queues 
 * that the task has open.)
 * 
 * \return Number of messages (Success.)
 * \return 0 (Success: queue is empty.)
 * \return 0 (Failure.)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is not valid for this processor.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN (Queue_id does not represent a message queue that 
 * is open.)
 * 
 * \see _msgq_open
 * \see _msgq_open_system
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks
 * \see _msgq_receive_until
 * \see _msgq_poll
 * \see _task_set_error    
 */ 
_mqx_uint _msgq_get_count
(
    _queue_id queue_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
    register MSGQ_STRUCT_PTR    msgq_ptr;
    INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register _mqx_uint          pending;
    register uint_16            queue;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msgq_get_count, queue_id);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msgq_get_count, MQX_COMPONENT_DOES_NOT_EXIST, 0);
        return(0);
    } /* Endif */
#endif

    if (queue_id == MSGQ_ANY_QUEUE)
    {
        _KLOGX3(KLOG_msgq_get_count, MQX_OK, kernel_data->ACTIVE_PTR->MESSAGES_AVAILABLE);
        return(kernel_data->ACTIVE_PTR->MESSAGES_AVAILABLE );
    } /* Endif */

    pending = 0;
    queue = QUEUE_FROM_QID(queue_id);
    if ( (PROC_NUMBER_FROM_QID(queue_id) == kernel_data->INIT.PROCESSOR_NUMBER) &&
                    VALID_QUEUE(queue) )
    {
        msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
        if ( msgq_ptr->QUEUE == (queue) )
        {
            pending = msgq_ptr->NO_OF_ENTRIES;

            /* Check for short-cutted message ie not on q but could have been */
            if (msgq_ptr->TD_PTR != NULL)
            {
                imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR)msgq_ptr->TD_PTR->MESSAGE;
                if ((imsg_ptr != NULL) &&
                                (QUEUE_FROM_QID(imsg_ptr->MESSAGE.TARGET_QID) == queue))
                {
                    ++pending;
                } /* Endif */
            } /* Endif */
        }
        else
        {
            _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
        } /* Endif */
    }
    else
    {
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
    } /* Endif */

    _KLOGX2(KLOG_msgq_get_count, pending);
    return(pending);

} /* Endbody */

/*!
 * \brief Converts a message-queue number and processor number to a queue ID.
 * 
 * The queue ID might not represent an open message queue. The queue ID can be 
 * used with functions that access message queues.
 * 
 * \param[in] processor_number One of the following:
 * \li Processor on which the message queue resides.
 * \li 0 (Indicates the local processor.)
 * \param[in] queue_number     Image-wide unique number that identifies the 
 * message queue.
 * 
 * \return Queue ID for the queue (Success.)
 * \return MSGQ_NULL_QUEUE_ID (Failure: _processor_number is not valid.)
 * 
 * \see _msgq_open_system
 * \see _msgq_open 
 */ 
_queue_id _msgq_get_id
(
    _processor_number processor_number,
    _queue_number     queue_number
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (processor_number > MQX_MAX_PROCESSOR_NUMBER)
    {
        return(MSGQ_NULL_QUEUE_ID);
    }/* Endif */
#endif   
    if ( processor_number == 0 )
    {
        processor_number = (_processor_number)kernel_data->INIT.PROCESSOR_NUMBER;
    } /* Endif */
    return BUILD_QID(processor_number, queue_number);

} /* Endbody */

/*!
 * \brief Sets the notification function for the private or the system message queue.
 * 
 * If the message queue is a system message queue, the function replaces the 
 * notification function and data that were installed with _msgq_open_system().
 * \n The notification function for a system message queue can get messages from 
 * the queue with _msgq_poll().
 * \n The notification function for a private message queue cannot get messages 
 * from the queue.
 *  
 * \param[in] qid                   Private or system message queue for which to 
 * install the notification function. 
 * \param[in] notification_function Function that MQX calls when MQX puts a 
 * message in the queue.
 * \param[in] notification_data     Data that MQX passes when it calls 
 * notification_function.
 * 
 * \return Pointer to the previous notification function (Success.) Notification function installed.
 * \return NULL (Success: Previous notification function was NULL.) Notification function installed.
 * \return NULL (Failure.) Notification function NOT installed.
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_OK (Notification function is installed; the previous function was NULL.)
 * \li MSGQ_INVALID_QUEUE_ID (Qid is not valid.) 
 * \li MSGQ_QUEUE_IS_NOT_OPEN (Queue is not open.)
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * 
 * \see _msgq_open_system
 * \see _msgq_open
 * \see _msgq_poll
 * \see _msgq_get_notification_function
 * \see _task_set_error
 */ 
MSGQ_NOTIFICATION_FPTR _msgq_set_notification_function
(
    _queue_id              qid,
    MSGQ_NOTIFICATION_FPTR notification_function,
    pointer                notification_data
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    MSG_COMPONENT_STRUCT_PTR msg_component_ptr;
    MSGQ_STRUCT_PTR          msgq_ptr;
    MSGQ_NOTIFICATION_FPTR   result;
    _queue_number            queue;
#if MQX_CHECK_ERRORS
    _processor_number        pnum;
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_msgq_set_notification_function, qid, notification_function, notification_data);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        result = NULL;
        _KLOGX2(KLOG_msgq_set_notification_function, result);
        return(result);
    } /* Endif */
#endif

    queue = QUEUE_FROM_QID(qid);

#if MQX_CHECK_ERRORS
    pnum = PROC_NUMBER_FROM_QID(qid);
    if (( pnum != kernel_data->INIT.PROCESSOR_NUMBER) || ( ! VALID_QUEUE(queue)))
    {
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
        result = NULL;
        _KLOGX2(KLOG_msgq_set_notification_function, result);
        return result;
    } /* Endif */
#endif

    msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
    if ( msgq_ptr->QUEUE != (queue) )
    {
        _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
        result = NULL;
    }
    else
    {
        result = msgq_ptr->NOTIFICATION_FUNCTION;
        msgq_ptr->NOTIFICATION_FUNCTION = notification_function;
        msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER = notification_data;
    } /* Endif */

    _KLOGX2(KLOG_msgq_set_notification_function, result);
    return result;

} /* Endbody */
/*!
 * \brief Gets the notification function and its data that are associated with 
 * the private or the system message queue.
 * 
 * \param[in]  qid                   Queue ID of the message queue for which to 
 * get the notification function.
 * \param[out] notification_function Pointer (which might be NULL) to the function 
 * that MQX calls when it puts a message in the message queue.
 * \param[out] notification_data     Pointer (which might be NULL) to data that 
 * MQX passes to the notification function.
 * 
 * \return MQX_OK
 * \return MSGQ_INVALID_QUEUE_ID (Queue_id does not represent a valid message 
 * queue on this processor.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \return MSGQ_QUEUE_IS_NOT_OPEN (Queue_id does not represent an open message 
 * queue.)
 * 
 * \warning On error, does not initialize notification_function or notification_data.
 * 
 * \see _msgq_open_system      
 * \see _msgq_open
 * \see _msgq_set_notification_function   
 */ 
_mqx_uint _msgq_get_notification_function
(
    _queue_id                    qid,
    MSGQ_NOTIFICATION_FPTR _PTR_ notification_function,
    pointer _PTR_                notification_data
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    MSG_COMPONENT_STRUCT_PTR msg_component_ptr;
    MSGQ_STRUCT_PTR          msgq_ptr;
    _mqx_uint                result = MQX_OK;
    _queue_number            queue;
#if MQX_CHECK_ERRORS
    _processor_number        pnum;
#endif

    _GET_KERNEL_DATA(kernel_data);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    queue = QUEUE_FROM_QID(qid);

#if MQX_CHECK_ERRORS
    pnum = PROC_NUMBER_FROM_QID(qid);
    if (( pnum != kernel_data->INIT.PROCESSOR_NUMBER) || ( ! VALID_QUEUE(queue)))
    {
        result = MSGQ_INVALID_QUEUE_ID;
    } /* Endif */
#endif

    if (result == MQX_OK)
    {
        msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
        if ( msgq_ptr->QUEUE != (queue) )
        {
            result = MSGQ_QUEUE_IS_NOT_OPEN;
        }
        else
        {
            *notification_function = msgq_ptr->NOTIFICATION_FUNCTION;
            *notification_data = msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER;
        } /* Endif */
    } /* Endif */

    return result;

} /* Endbody */

/*!
 * \brief Opens the private message queue.
 * 
 * The open message queue has a NULL notification function.
 * \n Only the task that opens a private message queue can receive messages from 
 * the queue.
 * \n A task can subsequently attach a notification function and notification data 
 * to the message queue with _msgq_set_notification_function().
 * 
 * \param[in] queue One of the following:
 * \li Queue number of the message queue to be opened on this processor (min. 8, 
 * max. as defined in the MQX initialization structure).
 * \li MSGQ_FREE_QUEUE (MQX opens an unopened message queue.)
 * \param[in] max_queue_size One of the following:
 * \li Maximum queue size.
 * \li 0 (Unlimited size.)
 * 
 * \return Queue ID (Success.)
 * \return MSGQ_NULL_QUEUE_ID (Failure.)
 * 
 * \warning Creates the message component if it was not previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MSGQ_INVALID_QUEUE_ID (Queue_number is out of range)
 * \li MSGQ_INVALID_QUEUE_NUMBER
 * \li MSGQ_QUEUE_IN_USE One of the following: message queue is already open or 
 * MQX cannot get a queue number for an unopened queue.
 * 
 * \see _msgq_close  
 * \see _msgq_open_system
 * \see _msg_create_component
 * \see _msgq_set_notification_function
 * \see _task_set_error 
 */ 
_queue_id _msgq_open
(
    _queue_number queue,
    uint_16       max_queue_size
)
{ /* Body */
    _queue_id result;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE3(KLOG_msgq_open, queue, max_queue_size);

    result = _msgq_open_internal(queue, max_queue_size, MSG_QUEUE,
                    (MSGQ_NOTIFICATION_FPTR)NULL, NULL);

    _KLOGX2(KLOG_msgq_open, result);

    return result;

} /* Endbody */

/*!
 * \private
 *  
 * \brief This is an internal function used to open a message queue.
 * 
 * \param[in] queue                 The queue being opened.
 * \param[in] max_queue_size        The maximum number of entries allowed in this 
 * queue.
 * \param[in] queue_type            The type of queue, NORMAL or SYSTEM.
 * \param[in] notification_function The function to be called when an entry is 
 * put on the queue.
 * \param[in] notification_data     Information to pass to the notification 
 * function.
 * 
 * \return Queue ID (Success.)
 * \return MSGQ_NULL_QUEUE_ID (Failure.)
 * 
 * \see _msgq_open   
 */ 
_queue_id _msgq_open_internal
(
    _queue_number          queue,
    uint_16                max_queue_size,
    _mqx_uint              queue_type,
    MSGQ_NOTIFICATION_FPTR notification_function,
    pointer                notification_data
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    TD_STRUCT_PTR            td_ptr;
    MSG_COMPONENT_STRUCT_PTR msg_component_ptr;
    register MSGQ_STRUCT_PTR temp_msgq_ptr;
    register MSGQ_STRUCT_PTR msgq_ptr;
    register _queue_id       qid;
    register _mqx_uint       i;
    _mqx_uint                result;

    _GET_KERNEL_DATA(kernel_data);
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
    qid = (_queue_id)0;

    if (msg_component_ptr == NULL)
    {
        result = _msg_create_component();
        msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (msg_component_ptr == NULL)
        {
            _task_set_error(result);
            return(qid);
        } /* Endif */
#endif      
    } /* Endif */

    _int_disable();
    if (queue == MSGQ_FREE_QUEUE)
    {
        /* Lets find a free queue entry */
        msgq_ptr = &msg_component_ptr->MSGQS_PTR[MSGQ_FIRST_USER_QUEUE];
        for (i = MSGQ_FIRST_USER_QUEUE; i <= msg_component_ptr->MAX_MSGQS; ++i)
        {
            if (msgq_ptr->QUEUE != (_queue_number)i)
            {
                queue = (_queue_number)i;
                break;
                /* Found one! */
            } /* Endif */
            ++msgq_ptr;
        } /* Endfor */
        if (queue == MSGQ_FREE_QUEUE)
        {
            /* Did not get one */
            _int_enable();
            _task_set_error(MSGQ_QUEUE_IN_USE);
            return(qid);
        }/* Endif */
    }
    else
    {
        if (queue >= msg_component_ptr->MAX_MSGQS)
        {
            _int_enable();
            _task_set_error(MSGQ_INVALID_QUEUE_NUMBER);
            return(qid);
        }
    }

#if MQX_CHECK_ERRORS
    if ( !VALID_QUEUE(queue))
    {
        _int_enable();
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
        return(qid);
    } /* Endif */
#endif

    msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];

#if MQX_CHECK_ERRORS
    if (msgq_ptr->QUEUE == queue)
    {
        _int_enable();
        _task_set_error(MSGQ_QUEUE_IN_USE);
        return(qid);
    } /* Endif */
#endif

    msgq_ptr->QUEUE = queue;
    msgq_ptr->FIRST_MSG_PTR = NULL;
    msgq_ptr->LAST_MSG_PTR = NULL;
    msgq_ptr->NEXT_MSGQ_PTR = NULL;
    msgq_ptr->NO_OF_ENTRIES = 0;
    msgq_ptr->TYPE = (uint_16)queue_type;
    msgq_ptr->MAX_ENTRIES = max_queue_size;
    msgq_ptr->NOTIFICATION_FUNCTION = notification_function;
    msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER = notification_data;

    if ( queue_type == MSG_QUEUE )
    {
        td_ptr = kernel_data->ACTIVE_PTR;
        msgq_ptr->TD_PTR = td_ptr;
        if ( td_ptr->MSG_QUEUE_HEAD == NULL )
        {
            td_ptr->MSG_QUEUE_HEAD = (pointer)msgq_ptr;
            td_ptr->MSG_QUEUE_TAIL = (pointer)msgq_ptr;
            td_ptr->MESSAGES_AVAILABLE = 0;
        }
        else
        {
            temp_msgq_ptr = (MSGQ_STRUCT_PTR)(td_ptr->MSG_QUEUE_TAIL);
            temp_msgq_ptr->NEXT_MSGQ_PTR = msgq_ptr;
            td_ptr->MSG_QUEUE_TAIL = (pointer)msgq_ptr;
        } /* Endif */
    }
    else
    {
        msgq_ptr->TD_PTR = NULL;
    } /* Endif */

    _INT_ENABLE();
    qid = BUILD_QID(kernel_data->INIT.PROCESSOR_NUMBER, queue);
    return (qid);

} /* Endbody */

/*!
 * \brief Gets the task ID of the task that owns the message queue.
 * 
 * \param[in] queue_id Queue ID of the message queue.
 * 
 * \return Task ID (Success.)
 * \return MQX_NULL_TASK_ID (Failure.)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MQX_INVALID_PROCESSOR_NUMBER (Processor number that queue_id specifies is 
 * not valid.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN (Message queue with queue ID queue_id is not open.)
 * 
 * \see _msgq_open
 * \see _msgq_open_system
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks
 * \see _msgq_receive_until
 * \see _msgq_send family
 * \see _task_set_error 
 */ 
_task_id _msgq_get_owner
(
    _queue_id queue_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    MSG_COMPONENT_STRUCT_PTR msg_component_ptr;
    register MSGQ_STRUCT_PTR msgq_ptr;
    _queue_number            queue;
    _task_id                 task_id;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msgq_get_owner, queue_id);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MQX_COMPONENT_DOES_NOT_EXIST);
        return(MQX_NULL_TASK_ID);
    } /* Endif */
#endif

    queue = QUEUE_FROM_QID(queue_id);

#if MQX_CHECK_ERRORS
    if ((PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER) ||
                    (! VALID_QUEUE(queue)) )
    {
        _task_set_error(MQX_INVALID_PROCESSOR_NUMBER);
        _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER);
        return (MQX_NULL_TASK_ID);
    } /* Endif */
#endif

    msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
    if (msgq_ptr->QUEUE != (queue))
    {
        _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
        _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MSGQ_QUEUE_IS_NOT_OPEN);
        return (MQX_NULL_TASK_ID);
    } /* Endif */

    task_id = msgq_ptr->TD_PTR->TASK_ID;
    _KLOGX3(KLOG_msgq_get_owner, task_id, MQX_OK);
    return (task_id);

} /* Endbody */

/*!
 * \brief Gets a pointer to the message that is at the start of the message 
 * queue, but do not remove the message.
 * 
 * Call _msgq_get_count() first to determine whether there are messages in the 
 * queue. If there are no messages, _msgq_peek() calls _task_set_error() with 
 * MSGQ_MESSAGE_NOT_AVAILABLE.
 * 
 * \param[in] queue_id The queue to look at.
 * 
 * \return Pointer to the message that is at the start of the message queue 
 * (Success.)
 * \return NULL (Failure.) 
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is not valid.)
 * \li MSGQ_MESSAGE_NOT_AVAILABLE (There are no messages in the message queue.)
 * \li MSGQ_NOT_QUEUE_OWNER (Task is not the owner of the private message queue.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN (Queue is not open.)
 * 
 * \see _msgq_get_count
 * \see _msgq_open_system
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks
 * \see _msgq_receive_until
 * \see _msgq_send
 * \see _task_set_error
 * \see _msg_create_component
 * \see MESSAGE_HEADER_STRUCT  
 */ 
pointer _msgq_peek
(
    _queue_id queue_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGQ_STRUCT_PTR             msgq_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    _queue_number                        queue;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msgq_peek, queue_id);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msgq_peek, NULL, MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
#endif

    message_ptr = NULL;
    queue = QUEUE_FROM_QID(queue_id);

#if MQX_CHECK_ERRORS
    if ((PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER) ||
                    (! VALID_QUEUE(queue)) )
    {
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
        _KLOGX3(KLOG_msgq_peek, NULL, MSGQ_INVALID_QUEUE_ID);
        return (pointer)message_ptr;
    } /* Endif */
#endif

    msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
    if (msgq_ptr->QUEUE != (queue))
    {
        _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
        _KLOGX3(KLOG_msgq_poll, NULL, MSGQ_QUEUE_IS_NOT_OPEN);
        return((pointer)message_ptr);
    } /* Endif */

#if MQX_CHECK_ERRORS
    if (msgq_ptr->TD_PTR != NULL)
    {
        if (msgq_ptr->TD_PTR != kernel_data->ACTIVE_PTR)
        {
            _task_set_error(MSGQ_NOT_QUEUE_OWNER);
            _KLOGX3(KLOG_msgq_poll, NULL, MSGQ_NOT_QUEUE_OWNER);
            return((pointer)message_ptr);
        } /* Endif */
    } /* Endif */
#endif

    /* check the specified queue for an entry */
    _INT_DISABLE();
    if ( msgq_ptr->NO_OF_ENTRIES == 0 )
    {
        _INT_ENABLE();
#if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR
        _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE);
#endif
        _KLOGX3(KLOG_msgq_peek, NULL, MSGQ_MESSAGE_NOT_AVAILABLE);
    }
    else
    {
        /* Return the top entry, but keep it on the queue */
        imsg_ptr = msgq_ptr->FIRST_MSG_PTR;
        message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;

        _INT_ENABLE();
        _KLOGX5(KLOG_msgq_peek, message_ptr, message_ptr->TARGET_QID, message_ptr->SOURCE_QID, *(_mqx_uint_ptr)((uchar_ptr)message_ptr+sizeof(MESSAGE_HEADER_STRUCT)));
    } /* Endif */
    return (pointer)message_ptr;

} /* Endbody */

/*!
 * \brief Polls the message queue for a message, but do not wait if a message is 
 * not in the queue. The function is a non-blocking alternative to _msgq_receive(); 
 * therefore, ISRs can use it.
 * 
 * The function is the only way for tasks to receive messages from a system 
 * message queue.
 * \li If a system message queue has a notification function, the function can get 
 * messages from the queue with _msgq_poll().
 * \li If a message is returned, the message becomes a resource of the task.
 * 
 * \param[in] queue_id Private or system message queue from which to receive a 
 * message.
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)  
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is not valid or is not on this processor.)
 * \li MSGQ_MESSAGE_NOT_AVAILABLE (There are no messages in the message queue.)
 * \li MSGQ_NOT_QUEUE_OWNER (Queue is a private message queue that the task does 
 * not own.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN (Queue is not open.)
 * 
 * \see _msgq_get_count
 * \see _msgq_open_system
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks
 * \see _msgq_receive_until
 * \see _msgq_send
 * \see _task_set_error
 * \see _msg_create_component
 * \see MESSAGE_HEADER_STRUCT  
 */ 
pointer _msgq_poll
(
    _queue_id queue_id
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MSGQ_STRUCT_PTR             msgq_ptr;
    _queue_number                        queue;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msgq_poll, queue_id);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msgq_poll, NULL, MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
#endif

    message_ptr = NULL;
    queue = QUEUE_FROM_QID(queue_id);

#if MQX_CHECK_ERRORS
    if ((PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER) ||
                    (! VALID_QUEUE(queue)) )
    {
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
        _KLOGX3(KLOG_msgq_poll, NULL, MSGQ_INVALID_QUEUE_ID);
        return (pointer)message_ptr;
    } /* Endif */
#endif

    msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
    if (msgq_ptr->QUEUE != (queue))
    {
        _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
        _KLOGX3(KLOG_msgq_poll, NULL, MSGQ_QUEUE_IS_NOT_OPEN);
        return((pointer)message_ptr);
    } /* Endif */

#if MQX_CHECK_ERRORS
    if (msgq_ptr->TD_PTR != NULL)
    {
        if (msgq_ptr->TD_PTR != kernel_data->ACTIVE_PTR)
        {
            _task_set_error(MSGQ_NOT_QUEUE_OWNER);
            _KLOGX3(KLOG_msgq_poll, NULL, MSGQ_NOT_QUEUE_OWNER);
            return((pointer)message_ptr);
        } /* Endif */
    } /* Endif */
#endif

    /* check the specified queue for an entry */
    _INT_DISABLE();
    if ( msgq_ptr->NO_OF_ENTRIES == 0 )
    {
        _INT_ENABLE();
#if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR
        _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE);
#endif
        _KLOGX3(KLOG_msgq_poll, NULL, MSGQ_MESSAGE_NOT_AVAILABLE);
    }
    else
    {

        --(msgq_ptr->NO_OF_ENTRIES);
        imsg_ptr = msgq_ptr->FIRST_MSG_PTR;
        msgq_ptr->FIRST_MSG_PTR = imsg_ptr->NEXT;
        if ( msgq_ptr->FIRST_MSG_PTR == NULL )
        {
            msgq_ptr->LAST_MSG_PTR = NULL;
        }
        else
        {
            (msgq_ptr->FIRST_MSG_PTR)->PREV = NULL;
        } /* Endif */

        if ( msgq_ptr->TD_PTR )
        {
            --(msgq_ptr->TD_PTR->MESSAGES_AVAILABLE);
        } /* Endif */
        message_ptr = &imsg_ptr->MESSAGE;
        imsg_ptr->QUEUED = FALSE;
        imsg_ptr->TD_PTR = NULL;

        _INT_ENABLE();
        _KLOGX2(KLOG_msgq_poll, message_ptr);
    } /* Endif */
    return (pointer)message_ptr;

} /* Endbody */

/*!
 * \brief Wait for a message from the private message queue for the specified 
 * number of milliseconds.
 * 
 * The function removes the first message from the queue and returns a pointer to 
 * the message. The message becomes a resource of the task.
 * \n The function cannot be used to receive messages from system message queues; 
 * this must be done with _msgq_poll().
 * 
 * \param[in] queue_id One of the following:
 * \li Private message queue from which to receive a message.
 * \li MSGQ_ANY_QUEUE (Any queue that the task owns.)
 * \param[in] timeout  One of the following:
 * \li Maximum number of milliseconds to wait.
 * \li 0 (Unlimited wait.)
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)
 * 
 * \warning If no message is available, blocks the task until the message queue 
 * gets a message or the timeout expires.
 * \warning Cannot be called from an ISR.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is for a specific queue, but the ID is 
 * not valid.)
 * \li MSGQ_MESSAGE_NOT_AVAILABLE (No messages were in the message queue before 
 * the timeout expired.)
 * \li MSGQ_NOT_QUEUE_OWNER (Message is not a resource of the task.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN One of the following: specific queue is not open 
 * or queue_id is MSGQ_ANY_QUEUE, but the task has no queues open.
 * 
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks
 * \see _msgq_receive_until
 * \see _msgq_get_count
 * \see _msgq_open
 * \see _msgq_poll
 * \see _msgq_send
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT    
 */ 
pointer _msgq_receive
(
    _queue_id queue_id,
    uint_32   timeout
)
{ /* Body */
    /* TIME_STRUCT                 time; */
    MQX_TICK_STRUCT           ticks;
#if MQX_KERNEL_LOGGING
    KERNEL_DATA_STRUCT_PTR    kernel_data;
#endif
    MESSAGE_HEADER_STRUCT_PTR message_ptr;
    _mqx_uint                 error;

#if MQX_KERNEL_LOGGING
    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_msgq_receive, queue_id, timeout);
#endif

    if (timeout)
    {
        /* Convert milliseconds to ticks */
        /* time.MILLISECONDS = timeout % 1000; */
        /* time.SECONDS      = timeout / 1000; */
        /*                                     */
        /* PSP_TIME_TO_TICKS(&time, &ticks);   */
        PSP_MILLISECONDS_TO_TICKS_QUICK(timeout, &ticks);

        message_ptr = _msgq_receive_internal(queue_id, &ticks,
                        MSG_TIMEOUT_RELATIVE, &error);
    }
    else
    {
        message_ptr = _msgq_receive_internal(queue_id, &ticks,
                        MSG_TIMEOUT_NONE, &error);
    } /* Endif */

#if MQX_KERNEL_LOGGING
    if ( (error == MQX_OK) && (message_ptr == NULL) )
    {
        _KLOGX3(KLOG_msgq_receive, message_ptr, MSGQ_MESSAGE_NOT_AVAILABLE);
    }
    else if (error == MQX_OK)
    {
        _KLOGX5(KLOG_msgq_receive, message_ptr, message_ptr->TARGET_QID,
                        message_ptr->SOURCE_QID, *(_mqx_uint_ptr)((uchar_ptr)message_ptr+
                                        sizeof(MESSAGE_HEADER_STRUCT)));
    }
    else
    {
        _KLOGX3(KLOG_msgq_receive, message_ptr, error);
    } /* Endif */
#endif

    return (pointer)message_ptr;

} /* Endbody */

/*!
 * \brief Wait for a message from the private message queue for the specified 
 * number of ticks (in tick time).
 * 
 * The function removes the first message from the queue and returns a pointer to 
 * the message. The message becomes a resource of the task.
 * \n The function cannot be used to receive messages from system message queues; 
 * this must be done with _msgq_poll().
 * 
 * \param[in] queue_id One of the following:
 * \li Private message queue from which to receive a message.
 * \li MSGQ_ANY_QUEUE (Any queue that the task owns.)
 * \param[in] tick_ptr  One of the following:
 * \li Pointer to the maximum number of ticks to wait.
 * \li NULL (Unlimited wait.)
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)
 * 
 * \warning If no message is available, blocks the task until the message queue 
 * gets a message or the timeout expires.
 * \warning Cannot be called from an ISR.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is for a specific queue, but the ID is 
 * not valid.)
 * \li MSGQ_MESSAGE_NOT_AVAILABLE (No messages were in the message queue before 
 * the timeout expired.)
 * \li MSGQ_NOT_QUEUE_OWNER (Message is not a resource of the task.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN One of the following: specific queue is not open 
 * or queue_id is MSGQ_ANY_QUEUE, but the task has no queues open.
 * 
 * \see _msgq_receive
 * \see _msgq_receive_ticks
 * \see _msgq_receive_until
 * \see _msgq_get_count
 * \see _msgq_open
 * \see _msgq_poll
 * \see _msgq_send
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT    
 */
pointer _msgq_receive_for
(
    _queue_id           queue_id,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
#if MQX_KERNEL_LOGGING
    KERNEL_DATA_STRUCT_PTR    kernel_data;
#endif
    MESSAGE_HEADER_STRUCT_PTR message_ptr;
    _mqx_uint                 error;

#if MQX_KERNEL_LOGGING
    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_msgq_receive_for, queue_id, tick_ptr);
#endif

    message_ptr = _msgq_receive_internal(queue_id, tick_ptr,
                    MSG_TIMEOUT_RELATIVE, &error);

#if MQX_KERNEL_LOGGING
    if ( (error == MQX_OK) && (message_ptr == NULL) )
    {
        _KLOGX3(KLOG_msgq_receive_for, message_ptr, MSGQ_MESSAGE_NOT_AVAILABLE);
    }
    else if (error == MQX_OK)
    {
        _KLOGX5(KLOG_msgq_receive_for, message_ptr, message_ptr->TARGET_QID,
                        message_ptr->SOURCE_QID, *(_mqx_uint_ptr)((uchar_ptr)message_ptr+
                                        sizeof(MESSAGE_HEADER_STRUCT)));
    }
    else
    {
        _KLOGX3(KLOG_msgq_receive_for, message_ptr, error);
    } /* Endif */
#endif

    return (pointer)message_ptr;

} /* Endbody */

/*!
 * \private
 * 
 * \brief Dequeue the first item from the specified queue.
 * 
 * \param[in]  queue_id         ID of the queue from which a message is to be 
 * received.
 * \param[in]  timeout_tick_ptr Indication of the number of ticks which can expire 
 * before this request times out.
 * \param[in]  mode             Relative or absolute time specified in tick_ptr.
 * \param[out] error_ptr        Where the error code is to be stored.   
 *  
 * \return Pointer to the message (Success).
 * \return NULL (Failure.)   
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_CANNOT_CALL_FUNCTION_FROM_ISR
 * \li MQX_COMPONENT_DOES_NOT_EXIST
 * \li MSGQ_QUEUE_IS_NOT_OPEN
 * \li MSGQ_INVALID_QUEUE_ID
 * \li MSGQ_NOT_QUEUE_OWNER
 * \li MSGQ_MESSAGE_NOT_AVAILABLE
 * \li MSGQ_INVALID_MESSAGE  
 */ 
MESSAGE_HEADER_STRUCT_PTR _msgq_receive_internal
(
    _queue_id           queue_id,
    MQX_TICK_STRUCT_PTR timeout_tick_ptr,
    _mqx_uint           mode,
    _mqx_uint_ptr       error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register TD_STRUCT_PTR               td_ptr;
    MESSAGE_HEADER_STRUCT_PTR            message_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MSGQ_STRUCT_PTR             msgq_ptr;
    _queue_number                        queue;

    *error_ptr = MQX_OK;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _task_set_error(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        *error_ptr = MQX_CANNOT_CALL_FUNCTION_FROM_ISR;
        return(NULL);
    }/* Endif */
#endif

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        *error_ptr = MQX_COMPONENT_DOES_NOT_EXIST;
        return(NULL);
    } /* Endif */
#endif

    message_ptr = NULL;
    td_ptr = kernel_data->ACTIVE_PTR;

    if (queue_id == MSGQ_ANY_QUEUE)
    {
        /* if queue_id is 0 than a receive from any queue is performed */

        /* Does the task own a queue */
        if (td_ptr->MSG_QUEUE_HEAD == NULL)
        {
            /* Does NOT */
            _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
            *error_ptr = MSGQ_QUEUE_IS_NOT_OPEN;
            return NULL;
        } /* Endif */

        _INT_DISABLE();
        if (td_ptr->MESSAGES_AVAILABLE == 0)
        {
            td_ptr->STATE = RCV_ANY_BLOCKED;
            td_ptr->INFO = queue_id;
            td_ptr->MESSAGE = NULL;

            if (mode == MSG_TIMEOUT_NONE)
            {
                _task_block();
            }
            else if (mode == MSG_TIMEOUT_RELATIVE)
            {
                _time_delay_for(timeout_tick_ptr);
            }
            else
            {
                _time_delay_until(timeout_tick_ptr);
            } /* Endif */

            /* 
             * SHORTCUT...
             * The message send routine does not queue up a message in this case.
             * the message is deposited directly into the task descriptor
             */
            message_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE;
            if (message_ptr == NULL)
            {
                /* A timeout has occurred */
#if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR
                _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE);
#endif
            } /* Endif */
            td_ptr->MESSAGE = NULL;

        }
        else
        {

            /*  Check all queues for an available entry .. There must be at least
             *  one entry available
             */
            msgq_ptr = (MSGQ_STRUCT_PTR)td_ptr->MSG_QUEUE_HEAD;
            while (msgq_ptr != NULL)
            {

                if (msgq_ptr->NO_OF_ENTRIES)
                {
                    /* dequeue the top entry */
                    DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr);
                    break;
                } /* Endif */
                msgq_ptr = msgq_ptr->NEXT_MSGQ_PTR;

            } /* Endwhile */
        } /* Endif */

    }
    else
    {

        /* RECEIVE from a specific qid */
        queue = QUEUE_FROM_QID(queue_id);
#if MQX_CHECK_ERRORS
        if ( (PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER) ||
                        (! VALID_QUEUE(queue)) )
        {
            _task_set_error(MSGQ_INVALID_QUEUE_ID);
            *error_ptr = MSGQ_INVALID_QUEUE_ID;
            return (pointer)message_ptr;
        } /* Endif */
#endif

        msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
#if MQX_CHECK_ERRORS
        if ( msgq_ptr->QUEUE != queue )
        {
            _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
            *error_ptr = MSGQ_QUEUE_IS_NOT_OPEN;
            return message_ptr;
        } /* Endif */
        if ( (msgq_ptr->TD_PTR != NULL) && (msgq_ptr->TD_PTR != td_ptr) )
        {
            _task_set_error(MSGQ_NOT_QUEUE_OWNER);
            *error_ptr = MSGQ_NOT_QUEUE_OWNER;
            return message_ptr;
        } /* Endif */
#endif

        /*
         * check the specified queue for an entry
         * if not entry, then block until an entry is received or
         * timeout occurs
         */
        _INT_DISABLE();
        if (msgq_ptr->NO_OF_ENTRIES == 0)
        {
            if (msgq_ptr->TD_PTR == NULL)
            {
                /* A system message queue, indicate none available */
                message_ptr = NULL;
            }
            else
            {
                td_ptr->STATE = RCV_SPECIFIC_BLOCKED;
                td_ptr->INFO = queue;
                td_ptr->MESSAGE = NULL;

                if (mode == MSG_TIMEOUT_NONE)
                {
                    _task_block();
                }
                else if (mode == MSG_TIMEOUT_RELATIVE)
                {
                    _time_delay_for(timeout_tick_ptr);
                }
                else
                {
                    _time_delay_until(timeout_tick_ptr);
                } /* Endif */

                message_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE;
                if ( message_ptr == NULL )
                {
#if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR
                    _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE);
#endif
                }
                else if ((message_ptr->TARGET_QID != queue_id) &&
                                (msgq_ptr->NO_OF_ENTRIES > 0))
                {
                    /* The original msg was swapped out in msgq_sendi() for 
                     * a higher priority msg with a different target_qid.
                     * Enqueue this msg, and then dequeue the msg we need.
                     */
                    register MSGQ_STRUCT_PTR tmp_msgq_ptr;
                    register _queue_number tmp_queue;

                    /* Get the msg's queue */
                    tmp_queue = QUEUE_FROM_QID(message_ptr->TARGET_QID);
                    tmp_msgq_ptr = &msg_component_ptr->MSGQS_PTR[tmp_queue];

                    if ((tmp_msgq_ptr->MAX_ENTRIES == 0) ||
                                    (tmp_msgq_ptr->NO_OF_ENTRIES < tmp_msgq_ptr->MAX_ENTRIES))
                    {
                        /* the msg's queue has room */
                        imsg_ptr = GET_INTERNAL_MESSAGE_PTR(message_ptr);

#if MQX_CHECK_ERRORS
                        if (imsg_ptr->VALID != MSG_VALID)
                        {
                            /* An invalid message was input by the application. */
                            _task_set_error(MSGQ_INVALID_MESSAGE);
                            message_ptr = NULL;
                        }
                        else
#endif
                        {
                            /* enqueue the msg */
                            _msgq_insert_message_internal(tmp_msgq_ptr, imsg_ptr, TRUE);

                            if (tmp_msgq_ptr->TD_PTR)
                            {
                                ++(tmp_msgq_ptr->TD_PTR->MESSAGES_AVAILABLE);
                            } /* Endif */

                            /* now dequeue our queue's top entry */
                            DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr);
                        }
                    }
                    else
                    {
                        /* Queue full, error - this should not happen 
                         * since msgq_sendi() checks for room on the queue 
                         * for all msgs, including short-cut msgs. 
                         */
                        _task_set_error(MSGQ_QUEUE_FULL);
                        message_ptr = NULL;
                    }
                } /* Endif */
                td_ptr->MESSAGE = NULL;
            } /* Endif */
        }
        else
        {
            /* dequeue the top entry */
            DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr);
        } /* Endif */
    } /* Endif */

    _INT_ENABLE();

    return message_ptr;

} /* Endbody */

/*!
 * \brief Wait for a message from the private message queue for the specified 
 * number of ticks.
 * 
 * The function removes the first message from the queue and returns a pointer to 
 * the message. The message becomes a resource of the task.
 * \n The function cannot be used to receive messages from system message queues; 
 * this must be done with _msgq_poll().
 * 
 * \param[in] queue_id One of the following:
 * \li Private message queue from which to receive a message.
 * \li MSGQ_ANY_QUEUE (Any queue that the task owns.)
 * \param[in] time_in_ticks  One of the following:
 * \li Maximum number of ticks to wait.
 * \li 0 (Unlimited wait.)
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)
 * 
 * \warning If no message is available, blocks the task until the message queue 
 * gets a message or the timeout expires.
 * \warning Cannot be called from an ISR.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is for a specific queue, but the ID is 
 * not valid.)
 * \li MSGQ_MESSAGE_NOT_AVAILABLE (No messages were in the message queue before 
 * the timeout expired.)
 * \li MSGQ_NOT_QUEUE_OWNER (Message is not a resource of the task.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN One of the following: specific queue is not open 
 * or queue_id is MSGQ_ANY_QUEUE, but the task has no queues open.
 * 
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_until
 * \see _msgq_get_count
 * \see _msgq_open
 * \see _msgq_poll
 * \see _msgq_send
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT    
 */ 
pointer _msgq_receive_ticks
(
    _queue_id queue_id,
    _mqx_uint time_in_ticks
)
{ /* Body */
    MQX_TICK_STRUCT ticks;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    MESSAGE_HEADER_STRUCT_PTR message_ptr;
    _mqx_uint error;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE3(KLOG_msgq_receive_ticks, queue_id, time_in_ticks);

    if (time_in_ticks)
    {
        _time_init_ticks(&ticks, time_in_ticks);

        message_ptr = _msgq_receive_internal(queue_id, &ticks,
                        MSG_TIMEOUT_RELATIVE, &error);
    }
    else
    {
        message_ptr = _msgq_receive_internal(queue_id, &ticks,
                        MSG_TIMEOUT_NONE, &error);
    } /* Endif */

#if MQX_KERNEL_LOGGING
    if ( (error == MQX_OK) && (message_ptr == NULL) )
    {
        _KLOGX3(KLOG_msgq_receive_ticks, message_ptr, MSGQ_MESSAGE_NOT_AVAILABLE);
    }
    else if (error == MQX_OK)
    {
        _KLOGX5(KLOG_msgq_receive_ticks, message_ptr, message_ptr->TARGET_QID,
                        message_ptr->SOURCE_QID, *(_mqx_uint_ptr)((uchar_ptr)message_ptr+
                                        sizeof(MESSAGE_HEADER_STRUCT)));
    }
    else
    {
        _KLOGX3(KLOG_msgq_receive_ticks, message_ptr, error);
    } /* Endif */
#endif

    return (pointer)message_ptr;

} /* Endbody */

/*!
 * \brief Wait for a message from the private message queue until the specified 
 * time (in tick time).
 * 
 * The function removes the first message from the queue and returns a pointer to 
 * the message. The message becomes a resource of the task.
 * \n The function cannot be used to receive messages from system message queues; 
 * this must be done with _msgq_poll().
 * 
 * \param[in] queue_id One of the following:
 * \li Private message queue from which to receive a message.
 * \li MSGQ_ANY_QUEUE (Any queue that the task owns.)
 * \param[in] tick_ptr One of the following:
 * \li Pointer to the time (in tick time) until which to wait.
 * \li NULL (Unlimited wait)
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)
 * 
 * \warning If no message is available, blocks the task until the message queue 
 * gets a message or the timeout expires.
 * \warning Cannot be called from an ISR.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is for a specific queue, but the ID is 
 * not valid.)
 * \li MSGQ_MESSAGE_NOT_AVAILABLE (No messages were in the message queue before 
 * the timeout expired.)
 * \li MSGQ_NOT_QUEUE_OWNER (Message is not a resource of the task.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN One of the following: specific queue is not open 
 * or queue_id is MSGQ_ANY_QUEUE, but the task has no queues open.
 * 
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks
 * \see _msgq_get_count
 * \see _msgq_open
 * \see _msgq_poll
 * \see _msgq_send
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT    
 */
pointer _msgq_receive_until
(
    _queue_id           queue_id,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
#if MQX_KERNEL_LOGGING
    KERNEL_DATA_STRUCT_PTR    kernel_data;
#endif
    MESSAGE_HEADER_STRUCT_PTR message_ptr;
    _mqx_uint                 error;

#if MQX_KERNEL_LOGGING
    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_msgq_receive_for, queue_id, tick_ptr);
#endif

    message_ptr = _msgq_receive_internal(queue_id, tick_ptr,
                    MSG_TIMEOUT_ABSOLUTE, &error);

#if MQX_KERNEL_LOGGING
    if ( (error == MQX_OK) && (message_ptr == NULL) )
    {
        _KLOGX3(KLOG_msgq_receive_until, message_ptr, MSGQ_MESSAGE_NOT_AVAILABLE);
    }
    else if (error == MQX_OK)
    {
        _KLOGX5(KLOG_msgq_receive_until, message_ptr, message_ptr->TARGET_QID,
                        message_ptr->SOURCE_QID, *(_mqx_uint_ptr)((uchar_ptr)message_ptr+
                                        sizeof(MESSAGE_HEADER_STRUCT)));
    }
    else
    {
        _KLOGX3(KLOG_msgq_receive_until, message_ptr, error);
    } /* Endif */
#endif

    return (pointer)message_ptr;

} /* Endbody */

/*!
 * \brief Sends the message to the message queue.
 * 
 * The function sends a message (priority 0) to a private message queue or a system 
 * message queue. The function does not block. The message must be from one of:
 * \li _msg_alloc()
 * \li _msg_alloc_system()
 * \li _msgq_poll()
 * \li _msgq_receive()
 * The message must be overlaid with MESSAGE_HEADER_STRUCT, with the data portion 
 * following the header. In the header, the sending task sets:
 * \li TARGET_ID to a valid queue ID for the local processor or for a remote 
 * processor (if TARGET_ID is for a remote processor, the function cannot verify 
 * the ID or determine whether the maximum size of the queue is reached).
 * \li SIZE to the number of single-addressable units in the message, including 
 * the header. If the message is for a meesage queue on a local processor, then MQX send the 
 * message to the message queue. Otherwise, it is sent to the remote processor. 
 * If the function returns successfully, the message is no longer a resource 
 * of the task.
 *  
 * \param[in] input_msg_ptr Pointer to the message to be sent.
 * 
 * \return TRUE (Success: see Description.) or FALSE (Failure.)
 * 
 * \warning Might dispatch a task.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * 
 * <table>
 *   <tr>
 *     <td><b>Task error code</b></td>
 *     <td><b>Meaning</b></td>
 *     <td><b>Message accepted</b></td>
 *     <td><b>Message freed</b></td>    
 *   </tr>
 *   <tr>
 *     <td>MQX_COMPONENT_DOES_NOT_EXIST</td>
 *     <td>Message component is not created.</td>
 *     <td>No</td>
 *     <td>No</td>    
 *   </tr>
 *   <tr>
 *     <td>MSGQ_INVALID_MESSAGE</td>
 *     <td>msg_ptr is NULL or points to a message that is one of:
 *     \li not valid
 *     \li on a message queue
 *     \li free</td>
 *     <td>No</td>
 *     <td>No</td>    
 *   </tr>
 *   <tr>
 *     <td>MSGQ_INVALID_QUEUE_ID</td>
 *     <td>Target ID is not a valid queue ID.</td>
 *     <td>No</td>
 *     <td>Yes</td>    
 *   </tr>
 *   <tr>
 *     <td>MSGQ_QUEUE_FULL</td>
 *     <td>Target message queue has reached its maximum size.</td>
 *     <td>No</td>
 *     <td>Yes</td>    
 *   </tr>
 *   <tr>
 *     <td>MSGQ_QUEUE_IS_NOT_OPEN</td>
 *     <td>Target ID does not represent an open message queue.</td>
 *     <td>No</td>
 *     <td>Yes</td>    
 *   </tr>
 *   <tr>
 *     <td>Task error codes from _msg_free()</td>
 *     <td>(If message needs to be freed.)</td>
 *     <td>Yes</td>
 *     <td>No</td>    
 *   </tr>        
 * </table>   
 * 
 * \see _msg_alloc_system
 * \see _msg_alloc
 * \see _msgq_open
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks 
 * \see _msgq_receive_until
 * \see _msgq_poll
 * \see _msgq_send_priority
 * \see _msgq_send_urgent
 * \see _msg_free
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT  
 */ 
boolean _msgq_send
(
    pointer input_msg_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    MESSAGE_HEADER_STRUCT_PTR msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)
    input_msg_ptr;
    boolean result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_msgq_send, msg_ptr, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->TARGET_QID, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->SOURCE_QID);

    result = _msgq_send_internal(msg_ptr, FALSE, msg_ptr->TARGET_QID);

    _KLOGX2(KLOG_msgq_send, result);

    return(result);

} /* Endbody */
/*!
 * \private
 *  
 * \brief Verify the input queue_id and try to send the message directly.
 *
 * This can only be used by tasks.
 * \n The calling task is blocked after the send.
 * 
 * \param[in] input_msg_ptr Pointer to the message being sent by application.
 * 
 * \return TRUE (Success.) or FALSE (Failure.)
 * 
 * \see _msgq_send_internal  
 */ 
boolean _msgq_send_blocked_internal
(
    pointer input_msg_ptr
)
{ /* Body */
    boolean result;
    MESSAGE_HEADER_STRUCT_PTR msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)
    input_msg_ptr;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE4(KLOG_msgq_send_blocked, msg_ptr, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->TARGET_QID, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->SOURCE_QID);

    result = _msgq_send_internal(msg_ptr, TRUE, msg_ptr->TARGET_QID);

    _KLOGX2(KLOG_msgq_send_blocked, result);
    return(result);

} /* Endbody */

/*!
 * \private
 * 
 * \brief Verify the input queue_id and try to send the message directly.
 * 
 * \param[in] msg_ptr    Pointer to the message being sent by application.
 * \param[in] blocking   Is the calling task to be blocked after the call.
 * \param[in] target_qid The queue to put the message onto.
 * 
 * \return TRUE (Success.) or FALSE (Failure.)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_MESSAGE (Msg_ptr is NULL or points to a message that is: not 
 * valid, on a message queue or free}.
 * \li MSGQ_INVALID_QUEUE_ID (Target ID is not a valid queue ID.)
 * \li MSGQ_QUEUE_FULL (Target message queue has reached its maximum size.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN (Target ID does not represent an open message queue.)
 * \li Task error codes from _msg_free() (If message needs to be freed.) 
 */ 
boolean _msgq_send_internal
(
    MESSAGE_HEADER_STRUCT_PTR msg_ptr,
    boolean                   blocking,
    _queue_id                 target_qid
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MSGQ_STRUCT_PTR             msgq_ptr;
    register TD_STRUCT_PTR               td_ptr;
    MESSAGE_HEADER_STRUCT_PTR            tmp_msg_ptr;
    register _mqx_uint                   state;
    register _queue_number               queue;
    register _processor_number           pnum;
    boolean                              swapped_msg;

    _GET_KERNEL_DATA(kernel_data);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        return(FALSE);
    } /* Endif */
    if (msg_ptr == NULL)
    {
        _task_set_error(MSGQ_INVALID_MESSAGE);
        return(FALSE);
    } /* Endif */
#endif

    imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);

#if MQX_CHECK_ERRORS
    if (imsg_ptr->VALID != MSG_VALID)
    {
        /* An invalid message was input by the application. */
        _task_set_error(MSGQ_INVALID_MESSAGE);
        return FALSE;
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (imsg_ptr->FREE || imsg_ptr->QUEUED)
    {
        /* Trying to send a free message, or one on a message queue. */
        _task_set_error(MSGQ_INVALID_MESSAGE);
        return FALSE;
    } /* Endif */
#endif

    pnum = PROC_NUMBER_FROM_QID(target_qid);

    /* If processor number is zero then the message is for this processor */
    if (pnum == 0)
    {
        /* Fix up the target QID in the message header */
        msg_ptr->TARGET_QID = BUILD_QID(kernel_data->INIT.PROCESSOR_NUMBER,
                        msg_ptr->TARGET_QID);
    }
    else if (pnum != kernel_data->INIT.PROCESSOR_NUMBER)
    {
#if MQX_IS_MULTI_PROCESSOR
        IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR ipc_msg_comp_ptr;
        ipc_msg_comp_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING];
        if (ipc_msg_comp_ptr && ipc_msg_comp_ptr->MSG_ROUTER)
        {
            return( (*ipc_msg_comp_ptr->MSG_ROUTER)(pnum, msg_ptr, blocking));
        }
        else
        {
#endif
            _msg_free(msg_ptr);
            _task_set_error(MSGQ_INVALID_QUEUE_ID);
            return FALSE;
#if MQX_IS_MULTI_PROCESSOR
        }/* Endif */
#endif
    } /* Endif */

    queue = QUEUE_FROM_QID(target_qid);

#if MQX_CHECK_ERRORS
    if ( ! VALID_QUEUE(queue))
    {
        _msg_free(msg_ptr);
        _task_set_error(MSGQ_INVALID_QUEUE_ID);
        return FALSE;
    } /* Endif */
#endif

    msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
    if (msgq_ptr->QUEUE != queue)
    {
        msgq_ptr = NULL;
    } /* Endif */

#if MQX_CHECK_ERRORS
    if (msgq_ptr == NULL)
    {
        _msg_free(msg_ptr);
        _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
        return FALSE;
    } /* Endif */
#endif

    _INT_DISABLE();

    if ((msgq_ptr->MAX_ENTRIES == 0) ||
                    (msgq_ptr->NO_OF_ENTRIES < msgq_ptr->MAX_ENTRIES))
    {

        /* There is room on the queue, so add the msg.  We 
         * need to check for room here even if the msg ends up
         * being short-cutted to the receiver (via td_ptr->MESSAGE)
         * in case msg_receive needs to enqueue the msg.
         */

        if (msgq_ptr->TYPE == MSG_QUEUE)
        {
            /* THIS MESSAGE QUEUE IS ATTACHED TO A TASK */

            /* check for pending receive
             * if a receive is pending then satisfy the request
             * and add the receiving task onto the ready-to-run queue
             */

            td_ptr = msgq_ptr->TD_PTR;
            state = td_ptr->STATE & STATE_MASK;
            if ( (state == RCV_ANY_BLOCKED) ||
                            ((state == RCV_SPECIFIC_BLOCKED) && (td_ptr->INFO == queue)))
            {
                /* The task is blocked, waiting for a message */
                td_ptr->MESSAGE = &imsg_ptr->MESSAGE;
                imsg_ptr->TD_PTR = td_ptr;
                _TIME_DEQUEUE(td_ptr,kernel_data);
                _TASK_READY(td_ptr,kernel_data);

                /* Now run the notification function */
                if (msgq_ptr->NOTIFICATION_FUNCTION != NULL)
                {
                    (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER);
                } /* Endif */

                if (blocking)
                {
                    if ( ! kernel_data->IN_ISR)
                    {
                        td_ptr = kernel_data->ACTIVE_PTR;
                        td_ptr->STATE = SEND_BLOCKED;
                        _task_block();
                    } /* Endif */
                }
                else
                {
                    /*
                     *  if the highest priority ready task is not the
                     *  same priority as the sending task, then a higher
                     *  priority task was made ready and it has to be allowed
                     *  to run.
                     */
                    _CHECK_RUN_SCHEDULER(); /* Let a higher priority task run */
                } /* Endif */

            }
            else
            {
                /* The task is ready to run and pre-empted OR blocked and
                 * on a different queue.
                 */

                swapped_msg = FALSE;
                if ((msg_ptr->CONTROL & MSG_PRIORITY_MASK) &&
                                (td_ptr->MESSAGE != NULL))
                {
                    /* Check the message in the TD */
                    tmp_msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE;
                    if ( (msg_ptr->CONTROL & MSG_HDR_URGENT) ||
                                    /* Urgent messages first */
                                    ( (! (tmp_msg_ptr->CONTROL & MSG_HDR_URGENT)) &&
                                                    ( (_mqx_uint)(tmp_msg_ptr->CONTROL & MSG_HDR_PRIORITY_MASK) <
                                                                    (_mqx_uint)(msg_ptr->CONTROL & MSG_HDR_PRIORITY_MASK))
                                    )
                    )
                    /* Higher priority messages first */
                    {
                        /* Put new message into TD */
                        td_ptr->MESSAGE = msg_ptr;

                        /* Set the new message's ownership to the receiving queue's TD */
                        imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);
                        imsg_ptr->TD_PTR = td_ptr;

                        /* Old message which we pulled from TD, need to add to queue, below */
                        msg_ptr = tmp_msg_ptr;
                        imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);

                        /* Don't know the sender's TD for the swapped out msg,
                         * so set it to NULL; 
                         */
                        imsg_ptr->TD_PTR = NULL;
                        /* Indicate that a swap occurred */
                        swapped_msg = TRUE;
                        /* Set the queue to the swapped msg's queue. */
                        if (target_qid != msg_ptr->TARGET_QID)
                        {
                            queue = QUEUE_FROM_QID(msg_ptr->TARGET_QID);
                            msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];

                            /* This msg's queue was not full when it was short-cut,
                             * so we should not get here.  Check anyway. 
                             */
                            if ((msgq_ptr->MAX_ENTRIES != 0) &&
                                            (msgq_ptr->NO_OF_ENTRIES >= msgq_ptr->MAX_ENTRIES))
                            {
                                /* Queue full, error */
                                _INT_ENABLE();
                                _msg_free(msg_ptr);
                                _task_set_error(MSGQ_QUEUE_FULL);
                                return FALSE;
                            } /* Endif */
                        } /* Endif */
                    } /* Endif */
                } /* Endif */

                /* add the message */
                _msgq_insert_message_internal(msgq_ptr, imsg_ptr, swapped_msg);

                if (msgq_ptr->TD_PTR)
                {
                    ++(msgq_ptr->TD_PTR->MESSAGES_AVAILABLE);
                } /* Endif */

                /* Now run the notification function */
                if (msgq_ptr->NOTIFICATION_FUNCTION != NULL)
                {
                    (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER);
                } /* Endif */

                if (blocking && ! kernel_data->IN_ISR )
                {
                    td_ptr = kernel_data->ACTIVE_PTR;
                    td_ptr->STATE = SEND_BLOCKED;
                    _task_block();
                } /* Endif */

            } /* Endif */

        }
        else
        {
            /* THIS IS A SYSTEM QUEUE NOT ATTACHED TO A TASK */

            /* add the message to the queue */
            _msgq_insert_message_internal(msgq_ptr, imsg_ptr, FALSE);

            /* Run the notification function. */
            if ( msgq_ptr->NOTIFICATION_FUNCTION != NULL )
            {
                (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER);
            } /* Endif */

        } /* Endif */

    }
    else
    {
        /* Queue full, error */
        _INT_ENABLE();
        _task_set_error(MSGQ_QUEUE_FULL);
        _msg_free(&imsg_ptr->MESSAGE);
        return FALSE;
    } /* Endif */

    _INT_ENABLE();
    return TRUE; /* Message sent MQX_OK */

} /* Endbody */

/*!
 * \private
 * 
 * \brief Inserts the message into the message queue according to its priority 
 * and urgency.
 * 
 * \param[in] msgq_ptr    The message queue to put the message onto.
 * \param[in] imsg_ptr    The message which is to be inserted.
 * \param[in] swapped_msg Was this message swapped out from the TD?
 */ 
void _msgq_insert_message_internal
(
    register MSGQ_STRUCT_PTR             msgq_ptr,
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr,
    register boolean                     swapped_msg
)
{ /* Body */
    register INTERNAL_MESSAGE_STRUCT_PTR prev_imsg_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR next_imsg_ptr;
    _mqx_uint                            control;
    _mqx_uint                            priority;

    if (msgq_ptr->FIRST_MSG_PTR == NULL)
    {
        imsg_ptr->PREV = NULL;
        imsg_ptr->NEXT = NULL;
        msgq_ptr->FIRST_MSG_PTR = imsg_ptr;
        msgq_ptr->LAST_MSG_PTR = imsg_ptr;
    }
    else
    {
        if (imsg_ptr->MESSAGE.CONTROL & MSG_HDR_URGENT || swapped_msg)
        {
            /* Insert at front if urgent 
             * OR if we are dealing with message previously in TD that was pulled 
             * out by a higher priority message. 
             */
            imsg_ptr->NEXT = msgq_ptr->FIRST_MSG_PTR;
            imsg_ptr->PREV = NULL;
            (msgq_ptr->FIRST_MSG_PTR)->PREV = imsg_ptr;
            msgq_ptr->FIRST_MSG_PTR = imsg_ptr;
        }
        else if (imsg_ptr->MESSAGE.CONTROL & MSG_HDR_PRIORITY_MASK)
        {
            /* We must insert the message into the queue */
            priority = imsg_ptr->MESSAGE.CONTROL & MSG_HDR_PRIORITY_MASK;
            prev_imsg_ptr = NULL;
            next_imsg_ptr = msgq_ptr->FIRST_MSG_PTR;
            while (next_imsg_ptr)
            {
                control = next_imsg_ptr->MESSAGE.CONTROL & MSG_HDR_PRIORITY_MASK;
                if (priority > control)
                {
                    break;
                } /* Endif */
                prev_imsg_ptr = next_imsg_ptr;
                next_imsg_ptr = next_imsg_ptr->NEXT;
            } /* Endwhile */

            if (prev_imsg_ptr == NULL)
            {
                /* Insert at front */
                imsg_ptr->NEXT = msgq_ptr->FIRST_MSG_PTR;
                imsg_ptr->PREV = NULL;
                (msgq_ptr->FIRST_MSG_PTR)->PREV = imsg_ptr;
                msgq_ptr->FIRST_MSG_PTR = imsg_ptr;
            }
            else if (next_imsg_ptr == NULL)
            {
                /* Insert at end */
                imsg_ptr->PREV = msgq_ptr->LAST_MSG_PTR;
                imsg_ptr->NEXT = NULL;
                (msgq_ptr->LAST_MSG_PTR)->NEXT = imsg_ptr;
                msgq_ptr->LAST_MSG_PTR = imsg_ptr;
            }
            else
            {
                /* Insert in middle */
                imsg_ptr->PREV = prev_imsg_ptr;
                imsg_ptr->NEXT = next_imsg_ptr;
                prev_imsg_ptr->NEXT = imsg_ptr;
                next_imsg_ptr->PREV = imsg_ptr;
            } /* Endif */
        }
        else
        {
            /* Tack on to end */
            imsg_ptr->PREV = msgq_ptr->LAST_MSG_PTR;
            imsg_ptr->NEXT = NULL;
            (msgq_ptr->LAST_MSG_PTR)->NEXT = imsg_ptr;
            msgq_ptr->LAST_MSG_PTR = imsg_ptr;
        } /* Endif */
    } /* Endif */

    ++(msgq_ptr->NO_OF_ENTRIES);
    imsg_ptr->QUEUED = TRUE;

} /* Endbody */

/*!
 * \brief Sends the priority message to the message queue.
 * 
 * The function inserts the message in a message queue based on the priority of 
 * the message; it inserts higher-priority messages ahead of lower-priority ones. 
 * Messages with the same priority are inserted in FIFO order.
 * \n If the function returns successfully, the message is no longer a resource 
 * of the task.
 * \n Messages sent with _msgq_send() and _msgq_send_broadcast() are priority 0 
 * messages.
 * 
 * \param[in] input_msg_ptr Pointer to the message to be sent.
 * \param[in] priority      Priority of the message, between:
 * \li 0 (Lowest.)
 * \li MSG_MAX_PRIORITY (highest; 15.)
 * 
 * \return TRUE (Success.) or FALSE (Failure.)
 * 
 * \warning Might dispatch a task.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li See _msgq_send() for error codes.
 * \li MSGQ_INVALID_MESSAGE_PRIORITY (Priority is greater than MSG_MAX_PRIORITY 
 * (message is not accepted and is not freed).)
 * 
 * \see _msgq_send   
 * \see _msg_alloc_system
 * \see _msg_alloc
 * \see _msgq_send_broadcast
 * \see _msgq_send_urgent
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks 
 * \see _msgq_receive_until
 * \see _msgq_poll
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT     
 */ 
boolean _msgq_send_priority
(
    pointer   input_msg_ptr,
    _mqx_uint priority

)
{ /* Body */
    boolean result;
    MESSAGE_HEADER_STRUCT_PTR msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)
    input_msg_ptr;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE6(KLOG_msgq_send_priority, msg_ptr, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->TARGET_QID, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->SOURCE_QID, priority, urgent);

    if (priority > MSG_MAX_PRIORITY)
    {
        _task_set_error(MSGQ_INVALID_MESSAGE_PRIORITY);
        _KLOGX2(KLOG_msgq_send_priority, FALSE);
        return FALSE;
    } /* Endif */

    msg_ptr->CONTROL &= 0xF0;
    msg_ptr->CONTROL |= (priority & 0xF);

    result = _msgq_send_internal(msg_ptr, FALSE, msg_ptr->TARGET_QID);

    _KLOGX2(KLOG_msgq_send_priority, result);
    return(result);

} /* Endbody */

/*!
 * \brief Sends the message directly to the private or system message queue.
 * 
 * The function uses qid instead of the target queue ID that the message header 
 * specifies and sends the message as described for _msgq_send().
 * \n If the function returns successfully, the message is no longer a resource 
 * of the task.
 * 
 * \param[in] msg_ptr Pointer to the message to be sent.
 * \param[in] qid     Message queue into which to put the message.
 * 
 * \return TRUE (Success.) or FALSE (Failure.)
 * 
 * \warning Might dispatch a task
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li See _msgq_send() for error codes.
 * 
 * \see _msgq_send   
 * \see _msgq_send_broadcast
 * \see _msgq_send_urgent
 * \see _msgq_send_priority
 * \see _msg_alloc_system
 * \see _msg_alloc
 * \see _msgq_open
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks 
 * \see _msgq_receive_until
 * \see _msgq_poll
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT
 */ 
boolean _msgq_send_queue
(
    pointer   msg_ptr,
    _queue_id qid
)
{ /* Body */
    boolean result;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE4(KLOG_msgq_send_queue, msg_ptr, qid, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->SOURCE_QID);

    result = _msgq_send_internal((MESSAGE_HEADER_STRUCT_PTR)msg_ptr, FALSE, qid);

    _KLOGX2(KLOG_msgq_send_queue, result);
    return(result);

} /* Endbody */

/*!
 * \brief Sends the urgent message to the message queue.
 * 
 * The function sends the message as described for _msgq_send().
 * \n The function puts the message at the start of the message queue, ahead of 
 * any other urgent messages.
 * \n If the function returns successfully, the message is no longer a resource 
 * of the task.
 * 
 * \param[in] input_msg_ptr Pointer to the message to be sent.
 * 
 * \return TRUE (Success.) or FALSE (Failure.)
 * 
 * \warning Might dispatch a task
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li See _msgq_send() for error codes.
 * 
 * \see _msgq_send   
 * \see _msgq_send_priority
 * \see _msgq_send_queue
 * \see _msg_alloc_system
 * \see _msg_alloc
 * \see _msgq_receive
 * \see _msgq_receive_for
 * \see _msgq_receive_ticks 
 * \see _msgq_receive_until
 * \see _msgq_poll
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT    
 */ 
boolean _msgq_send_urgent
(
    pointer input_msg_ptr
)
{ /* Body */
    boolean result;
    MESSAGE_HEADER_STRUCT_PTR msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)
    input_msg_ptr;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE4(KLOG_msgq_send_urgent, msg_ptr, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->TARGET_QID, ((MESSAGE_HEADER_STRUCT_PTR)msg_ptr)->SOURCE_QID);

    msg_ptr->CONTROL |= MSG_HDR_URGENT;

    result = _msgq_send_internal(msg_ptr, FALSE, msg_ptr->TARGET_QID);

    _KLOGX2(KLOG_msgq_send_urgent, result);
    return(result);

} /* Endbody */

/*!
 * \brief Opens the system message queue.
 * 
 * Once a system message queue is opened, any task can use the queue ID to receive 
 * messages with _msgq_poll().
 * \li Tasks cannot receive messages from system message queues with _msgq_receive().
 * \li The notification function can get messages from the message queue with 
 * _msgq_poll().
 * \li A task can change the notification function and its data with 
 * _msgq_set_notification_function().
 * 
 * \param[in] queue                 One of the following:
 * \li System message queue to be opened (min. 8, max. as defined in the MQX 
 * initialization structure).
 * \li MSGQ_FREE_QUEUE (MQX chooses an unopened system queue number.)
 * \param[in] max_queue_size        One of the following:
 * \li Maximum queue size.
 * \li 0 (Unlimited size.)
 * \param[in] notification_function One of the following:              
 * \li Pointer to the function that MQX calls when it puts a message in the queue.
 * \li NULL (MQX does not call a function when it puts a message in the queue.)
 * \param[in] notification_data     Data that MQX passes when it calls 
 * notification_function.
 * 
 * \return Queue ID (Success.)
 * \return 0 (Failure.)
 * 
 * \warning Creates the message component if it was not previously created.
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li See _msgq_open() for error codes
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGQ_INVALID_QUEUE_ID (Queue_id is not valid.)
 * \li MSGQ_MESSAGE_NOT_AVAILABLE (There are no messages in the message queue.)
 * \li MSGQ_NOT_QUEUE_OWNER (Task is not the owner of the private message queue.)
 * \li MSGQ_QUEUE_IS_NOT_OPEN Queue is not open.  
 * 
 * \see _msgq_close
 * \see _msgq_open
 * \see _msgq_poll
 * \see _msgq_set_notification_function
 * \see _task_set_error  
 */ 
_queue_id _msgq_open_system
(
    _queue_number          queue,
    uint_16                max_queue_size,
    MSGQ_NOTIFICATION_FPTR notification_function,
    pointer                notification_data
)
{ /* Body */
    _queue_id result;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE5(KLOG_msgq_open_system, queue, max_queue_size, notification_function, notification_data);

    result = _msgq_open_internal(queue, max_queue_size, SYSTEM_MSG_QUEUE,
                    notification_function, notification_data);

    _KLOGX2(KLOG_msgq_open_system, result);

    return(result);

} /* Endbody */

/*!
 * \brief Tests all messages in all open message queues for validity and consistency.
 * 
 * The function checks the consistency and validity of all messages in all 
 * private and system message queues that are open.
 * 
 * \param[out] queue_error_ptr Pointer to the message queue that has a message 
 * with an error (initialized only if an error is found).
 * \param[out] msg_error_ptr   Pointer to the message that has an error 
 * (initialized only if an error is found).
 * 
 * \return MQX_OK (Success: no errors are found.)
 * \return MSGQ_INVALID_MESSAGE (Success: an error is found.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Failure: Message component is not created.)
 * 
 * \warning Disables and enables interrupts.
 * 
 * \see _msgq_open
 * \see _msgq_open_system 
 */ 
_mqx_uint _msgq_test
(
    pointer _PTR_ queue_error_ptr,
    pointer _PTR_ msg_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
    MSGQ_STRUCT_PTR             msgq_ptr;
    INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    _mqx_uint                   i,j;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_msgq_test, queue_error_ptr, msg_error_ptr);
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _KLOGX2(KLOG_msgq_test, MQX_COMPONENT_DOES_NOT_EXIST);
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    /* test the message queues */
    msgq_ptr = &msg_component_ptr->MSGQS_PTR[MSGQ_FIRST_USER_QUEUE];
    for (i = 1; i <= msg_component_ptr->MAX_MSGQS; i++)
    {
        _int_disable();
        if (msgq_ptr->QUEUE == i)
        {
            /* Queue is open */
            imsg_ptr = msgq_ptr->FIRST_MSG_PTR;
            for (j = 0; j < msgq_ptr->NO_OF_ENTRIES; ++j)
            {
                if ((imsg_ptr->VALID != MSG_VALID) && (!imsg_ptr->QUEUED))
                {
                    _int_enable();
                    *queue_error_ptr = msgq_ptr;
                    *msg_error_ptr = imsg_ptr;
                    _KLOGX4(KLOG_msgq_test, MSGQ_INVALID_MESSAGE, msgq_ptr,
                                    imsg_ptr);
                    return(MSGQ_INVALID_MESSAGE);
                } /* Endif */
                imsg_ptr = imsg_ptr->NEXT;
            } /* Endfor */
        } /* Endif */
        _int_enable();
        ++msgq_ptr;
    } /* Endfor */

    _KLOGX2(KLOG_msgq_test, MQX_OK);
    return(MQX_OK);

} /* Endbody */

#endif /* MQX_USE_MESSAGES */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/gpio/mcf5225/io_gpio_mcf5225.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_gpio_mcf5225.c$
* $Version : 3.8.43.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   This file contains the GPIO standard functions used on boards
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "../io_gpio.h"
#include "../io_gpio_prv.h"
#include <string.h>

/* This structure will hold 'used pins'. If somebody would like to open 'already used pin',
** the operation will fail. All open pins within all GPIO driver files will be written here.
** We can predefine this structure with 'already used' bits for those bits, which are not
** used at all - so we will prevent open operation to be successful.
*/
GPIO_PIN_MAP  gpio_global_pin_map = {
    0x00, /* portte */
    0x00, /* porttf */
    0x00, /* porttg */
    0x00, /* portth */
    0x00, /* portti */
    0xff, /* unusedA */
    0x00, /* porttj */
    0xff, /* unusedB */
    0x01, /* portnq */
    0xff, /* unusedC */
    0x00, /* portan */
    0xf8, /* portas */
    0x80, /* portqs */
    0xff, /* unusedD */
    0xf0, /* portta */
    0xf0, /* porttc */
    0xff, /* unusedE */
    0xf0, /* portua */
    0xf0, /* portub */
    0xf0, /* portuc */
    0x00, /* portdd */
    {
        0xff, 0xff, 0xff /* unusedF[] */
    }
};

GPIO_PIN_MAP  gpio_global_irq_map = {
    0xff, /* portte */
    0xff, /* porttf */
    0xff, /* porttg */
    0xff, /* portth */
    0xff, /* portti */
    0xff, /* unusedA */
    0xff, /* porttj */
    0xff, /* unusedB */
    0x55, /* portnq */
    0xff, /* unusedC */
    0xff, /* portan */
    0xff, /* portas */
    0xff, /* portqs */
    0xff, /* unusedD */
    0xff, /* portta */
    0xff, /* porttc */
    0xff, /* unusedE */
    0xff, /* portua */
    0xff, /* portub */
    0xff, /* portuc */
    0xff, /* portdd */
    {
        0xff, 0xff, 0xff /* unusedF[] */
    }
};

extern MQX_INITIALIZATION_STRUCT MQX_init_struct;

extern GPIO_DEV_DATA_PTR first_irq; /* first file having used IRQ */

/* pointer to the start of GPIO registers */
VMCF5225_GPIO_STRUCT_PTR mcf5225_gpio_ptr;
VMCF522XX_EPORT_STRUCT_PTR mcf5225_eport_ptr;

void gpio_cpu_configure(GPIO_DEV_DATA_PTR);
_mqx_int gpio_cpu_init();
_mqx_int gpio_cpu_open(MQX_FILE_PTR, char_ptr, char_ptr);
_mqx_int gpio_cpu_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);

static void gpio_eport_irq (pointer param);

/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_configure
* Returned Value   : IO_OK
* Comments         :
*    Configures pins to be GPIO based on pin map
*
*END*********************************************************************/
void gpio_cpu_configure
   (
      /* [IN] pointer to file data */
      GPIO_DEV_DATA_PTR   dev_data_ptr
   )
{ /* Body */
    if (dev_data_ptr->type == DEV_OUTPUT) { /* set GPIO output behavior */
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 0) |= dev_data_ptr->pin_map.memory32[0];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 1) |= dev_data_ptr->pin_map.memory32[1];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 2) |= dev_data_ptr->pin_map.memory32[2];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 3) |= dev_data_ptr->pin_map.memory32[3];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 4) |= dev_data_ptr->pin_map.memory32[4];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 5) |= dev_data_ptr->pin_map.memory32[5];
    }
    else { /* DEV_INPUT type is supposed */
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 0) &= ~dev_data_ptr->pin_map.memory32[0];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 1) &= ~dev_data_ptr->pin_map.memory32[1];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 2) &= ~dev_data_ptr->pin_map.memory32[2];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 3) &= ~dev_data_ptr->pin_map.memory32[3];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 4) &= ~dev_data_ptr->pin_map.memory32[4];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->DDRTE)) + 5) &= ~dev_data_ptr->pin_map.memory32[5];
    }
 
    /* set pin functionality to be GPIO for the whole file */
    mcf5225_gpio_ptr->PTEPAR = mcf5225_gpio_ptr->PTEPAR & ~dev_data_ptr->pin_map.reg.portte;
    mcf5225_gpio_ptr->PTFPAR = mcf5225_gpio_ptr->PTFPAR & ~dev_data_ptr->pin_map.reg.porttf;
    mcf5225_gpio_ptr->PTGPAR = mcf5225_gpio_ptr->PTGPAR & ~dev_data_ptr->pin_map.reg.porttg;
    mcf5225_gpio_ptr->PTIPAR = mcf5225_gpio_ptr->PTIPAR & ~dev_data_ptr->pin_map.reg.portti;
    mcf5225_gpio_ptr->PTJPAR = mcf5225_gpio_ptr->PTJPAR & ~dev_data_ptr->pin_map.reg.porttj;
    mcf5225_gpio_ptr->PANPAR = mcf5225_gpio_ptr->PANPAR & ~dev_data_ptr->pin_map.reg.portan;
    mcf5225_gpio_ptr->PDDPAR = mcf5225_gpio_ptr->PDDPAR & ~dev_data_ptr->pin_map.reg.portdd;
    mcf5225_gpio_ptr->PTHPAR = mcf5225_gpio_ptr->PTHPAR & ~(
        ( dev_data_ptr->pin_map.reg.portth & 0x01 ? 0x0003 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portth & 0x02 ? 0x000C : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portth & 0x04 ? 0x0030 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portth & 0x08 ? 0x00C0 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portth & 0x10 ? 0x0300 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portth & 0x20 ? 0x0C00 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portth & 0x40 ? 0x3000 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portth & 0x80 ? 0xC000 : 0x0000 ));
    mcf5225_gpio_ptr->PQSPAR = mcf5225_gpio_ptr->PQSPAR & ~(
        ( dev_data_ptr->pin_map.reg.portqs & 0x01 ? 0x0003 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portqs & 0x02 ? 0x000C : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portqs & 0x04 ? 0x0030 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portqs & 0x08 ? 0x00C0 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portqs & 0x10 ? 0x0300 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portqs & 0x20 ? 0x0C00 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portqs & 0x40 ? 0x3000 : 0x0000 ));
    mcf5225_gpio_ptr->PASPAR = mcf5225_gpio_ptr->PASPAR & ~(
        ( dev_data_ptr->pin_map.reg.portas & 0x01 ? 0x03 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portas & 0x02 ? 0x0C : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portas & 0x04 ? 0x30 : 0x00 ));
    mcf5225_gpio_ptr->PTAPAR = mcf5225_gpio_ptr->PTAPAR & ~(
        ( dev_data_ptr->pin_map.reg.portta & 0x01 ? 0x03 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portta & 0x02 ? 0x0C : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portta & 0x04 ? 0x30 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portta & 0x08 ? 0xC0 : 0x00 ));
    mcf5225_gpio_ptr->PTCPAR = mcf5225_gpio_ptr->PTCPAR & ~(
        ( dev_data_ptr->pin_map.reg.porttc & 0x01 ? 0x03 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.porttc & 0x02 ? 0x0C : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.porttc & 0x04 ? 0x30 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.porttc & 0x08 ? 0xC0 : 0x00 ));
    mcf5225_gpio_ptr->PUAPAR = mcf5225_gpio_ptr->PUAPAR & ~(
        ( dev_data_ptr->pin_map.reg.portua & 0x01 ? 0x03 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portua & 0x02 ? 0x0C : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portua & 0x04 ? 0x30 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portua & 0x08 ? 0xC0 : 0x00 ));
    mcf5225_gpio_ptr->PUBPAR = mcf5225_gpio_ptr->PUBPAR & ~(
        ( dev_data_ptr->pin_map.reg.portub & 0x01 ? 0x03 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portub & 0x02 ? 0x0C : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portub & 0x04 ? 0x30 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portub & 0x08 ? 0xC0 : 0x00 ));
    mcf5225_gpio_ptr->PUCPAR = mcf5225_gpio_ptr->PUCPAR & ~(
        ( dev_data_ptr->pin_map.reg.portuc & 0x01 ? 0x03 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portuc & 0x02 ? 0x0C : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portuc & 0x04 ? 0x30 : 0x00 ) |
        ( dev_data_ptr->pin_map.reg.portuc & 0x08 ? 0xC0 : 0x00 ));
    mcf5225_gpio_ptr->PNQPAR = mcf5225_gpio_ptr->PNQPAR & ~(
        ( dev_data_ptr->pin_map.reg.portnq & 0x02 ? 0x000C : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portnq & 0x04 ? 0x0030 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portnq & 0x08 ? 0x00C0 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portnq & 0x10 ? 0x0300 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portnq & 0x20 ? 0x0C00 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portnq & 0x40 ? 0x3000 : 0x0000 ) |
        ( dev_data_ptr->pin_map.reg.portnq & 0x80 ? 0xC000 : 0x0000 )) | (
        ( dev_data_ptr->irqp_map.reg.portnq & 0x02 ? 0x0004 : 0x0000 ) |
        ( dev_data_ptr->irqp_map.reg.portnq & 0x08 ? 0x0040 : 0x0000 ) |
        ( dev_data_ptr->irqp_map.reg.portnq & 0x20 ? 0x0400 : 0x0000 ) |
        ( dev_data_ptr->irqp_map.reg.portnq & 0x80 ? 0x4000 : 0x0000 ) |
        ( dev_data_ptr->irqn_map.reg.portnq & 0x02 ? 0x0004 : 0x0000 ) |
        ( dev_data_ptr->irqn_map.reg.portnq & 0x08 ? 0x0040 : 0x0000 ) |
        ( dev_data_ptr->irqn_map.reg.portnq & 0x20 ? 0x0400 : 0x0000 ) |
        ( dev_data_ptr->irqn_map.reg.portnq & 0x80 ? 0x4000 : 0x0000 ));

    /* configure EPORT module */
    mcf5225_eport_ptr->EPDDR = 0x00; /* all eport irqs are inputs */
    mcf5225_eport_ptr->EPPAR |= /* react on rising / falling edge */
        ( dev_data_ptr->irqp_map.reg.portnq & 0x02 ? 0x0004 : 0x0000 ) |
        ( dev_data_ptr->irqp_map.reg.portnq & 0x08 ? 0x0040 : 0x0000 ) |
        ( dev_data_ptr->irqp_map.reg.portnq & 0x20 ? 0x0400 : 0x0000 ) |
        ( dev_data_ptr->irqp_map.reg.portnq & 0x80 ? 0x4000 : 0x0000 ) |
        ( dev_data_ptr->irqn_map.reg.portnq & 0x02 ? 0x0008 : 0x0000 ) |
        ( dev_data_ptr->irqn_map.reg.portnq & 0x08 ? 0x0080 : 0x0000 ) |
        ( dev_data_ptr->irqn_map.reg.portnq & 0x20 ? 0x0800 : 0x0000 ) |
        ( dev_data_ptr->irqn_map.reg.portnq & 0x80 ? 0x8000 : 0x0000 );
    mcf5225_eport_ptr->EPIER |= (dev_data_ptr->irqp_map.reg.portnq | dev_data_ptr->irqn_map.reg.portnq); /* set interrupt enable */

} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_install
* Returned Value   : IO_OK
* Comments         :
*    Performs basic initialization specific to board
*
*END*********************************************************************/

_mqx_int gpio_cpu_init()
{ /* Body */
    VMCF5225_STRUCT_PTR  mcf5225_ptr;
 
    mcf5225_ptr = _PSP_GET_IPSBAR();
    mcf5225_gpio_ptr = &mcf5225_ptr->GPIO;
    mcf5225_eport_ptr = &mcf5225_ptr->EPORT[0];
 
    return IO_OK;
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_open
* Returned Value   : IO_OK or error
* Comments         :
*    Implements initialization for DATA GPIO
*
*END*********************************************************************/

_mqx_int gpio_cpu_open
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the file name */
      char_ptr   file_name,

      /* [IN] pointer to parameters */
      char_ptr   param_ptr
   )
{ /* Body */
    _mqx_int i;
    GPIO_DEV_DATA_PTR dev_data_ptr = (GPIO_DEV_DATA_PTR) fd_ptr->DEV_DATA_PTR;
 
    /* if file_name is used, then the user wants to open peripheral */
    if ((file_name != NULL) && (*file_name != 0)) {
        if (!strncmp(file_name, "gpio:write", 11))  /* user wants write access to GPIO */
            dev_data_ptr->type = DEV_OUTPUT;
        else if (!strncmp(file_name, "gpio:output", 12))  /* user wants write access to GPIO */
            dev_data_ptr->type = DEV_OUTPUT;
        else if (!strncmp(file_name, "gpio:read", 10)) /* user wants read access to GPIO */
            dev_data_ptr->type = DEV_INPUT;
        else if (!strncmp(file_name, "gpio:input", 11)) /* user wants read access to GPIO */
            dev_data_ptr->type = DEV_INPUT;
        else
        /* peripherals not used yet */
            return IO_ERROR;
    }
    else
        return IO_ERROR;
 
    /* check which irq pin to be opened and prepare interrupt service routine */
    for (i = 1; i < 8; i++) {
        if ((i & 0x01) == 0)
            continue;
        if ((dev_data_ptr->irqp_map.reg.portnq | dev_data_ptr->irqn_map.reg.portnq) & (1 << i)) {
            if (MQX_init_struct.MQX_HARDWARE_INTERRUPT_LEVEL_MAX < i)
                return IO_ERROR; /* hardware level must be higher than interrupt level */
            if (NULL == _int_install_isr(MCF5225_INT_EPORT0_EPF1 - 1 + i, gpio_eport_irq, NULL))
                return IO_ERROR; /* could not install interrupt routine */
            /* this is only to enable the interrupt source, level and sublevel values are hardwired */                
            _mcf5225_int_init(MCF5225_INT_EPORT0_EPF1 - 1 + i, i, BSP_EPORT_EPFX_INT_SUBLEVEL_MIDPOINT, TRUE);
        }
    }

    if ((param_ptr != NULL) && (dev_data_ptr->type == DEV_OUTPUT)) { /* set pins status before selecting GPIO function */
        /* note that this is similar to GPIO_IOCTL_WRITE function, but no checking is performed
           (was done in io_gpio_open function) */
        GPIO_PIN_STRUCT _PTR_  pin_table;
        uint_32        addr;
        uint_8         pin;
        GPIO_PIN_MAP_PTR    temp_pin0_map_ptr;
        GPIO_PIN_MAP_PTR    temp_pin1_map_ptr;

        if (NULL == (temp_pin0_map_ptr = (GPIO_PIN_MAP_PTR) _mem_alloc_system_zero(sizeof(GPIO_PIN_MAP))))
            return IO_ERROR;

        if (NULL == (temp_pin1_map_ptr = (GPIO_PIN_MAP_PTR) _mem_alloc_system_zero(sizeof(GPIO_PIN_MAP)))) {
            _mem_free(temp_pin0_map_ptr);
            return IO_ERROR;
        }

        /* prepare pin map */
        for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) {
            addr = (*pin_table & GPIO_PIN_ADDR) >> 3; /* prepare address of port */ 
            pin = 1 << (*pin_table & 0x07);  /* prepare bit mask */
            if (*pin_table & GPIO_PIN_STATUS)
                temp_pin1_map_ptr->memory8[addr] |= pin;
            else
                temp_pin0_map_ptr->memory8[addr] |= pin;
        }
        /* ok, now we can apply new map */
        /* note: applying the map after collecting pins is due to have pins applied in one instruction */
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 0) = temp_pin1_map_ptr->memory32[0];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 0) = ~temp_pin0_map_ptr->memory32[0];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 1) = temp_pin1_map_ptr->memory32[1];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 1) = ~temp_pin0_map_ptr->memory32[1];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 2) = temp_pin1_map_ptr->memory32[2];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 2) = ~temp_pin0_map_ptr->memory32[2];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 3) = temp_pin1_map_ptr->memory32[3];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 3) = ~temp_pin0_map_ptr->memory32[3];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 4) = temp_pin1_map_ptr->memory32[4];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 4) = ~temp_pin0_map_ptr->memory32[4];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 5) = temp_pin1_map_ptr->memory32[5];
        * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 5) = ~temp_pin0_map_ptr->memory32[5];

        _mem_free(temp_pin1_map_ptr);
        _mem_free(temp_pin0_map_ptr);
    }

    gpio_cpu_configure(dev_data_ptr);
    return IO_OK;
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : gpio_cpu_ioctl
* Returned Value   : depends on IOCTL command
* Comments         :
*    Implements all ioctl for GPIO
*
*END*********************************************************************/

_mqx_int gpio_cpu_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint  cmd,

      /* [IN] the ioctl parameters */
      pointer    param_ptr
   )
{ /* Body */
    GPIO_DEV_DATA_PTR  dev_data_ptr = (GPIO_DEV_DATA_PTR) fd_ptr->DEV_DATA_PTR;
 
    switch (cmd) {
        case GPIO_IOCTL_ADD_PINS: {
        /* Add pins to this file. Params: table with pin addresses */
            GPIO_PIN_STRUCT _PTR_  pin_table;
            uint_32        addr;
            uint_8         pin;

            /* check pin_table if they are not in global pin_map */
            _int_disable();
            for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) {
                if (*pin_table & GPIO_PIN_VALID) { /* check pin validity bit */
                    addr = (*pin_table & GPIO_PIN_ADDR) >> 3; /* prepare address of port */ 
                    pin = 1 << (*pin_table & 0x07);  /* prepare bit mask */
                    if (addr < sizeof(GPIO_PIN_MAP)) /* pin address out of map scope? */
                        if (! (gpio_global_pin_map.memory8[addr] & pin)) /* pin address already used? */
                            continue; /* manage next pin */
                }
                /* some problem occured */
                _int_enable();
                return IO_ERROR;
            }
            /* check successful, now we have to copy these bits to local pin map */
            for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) {
                addr = (*pin_table & GPIO_PIN_ADDR)  >> 3; /* prepare address of port */ 
                pin = 1 << (*pin_table & 0x07);  /* prepare bit mask */
                dev_data_ptr->pin_map.memory8[addr] |= pin; /* mark pin as used by this file */
                gpio_global_pin_map.memory8[addr] |= pin; /* mark pin as used globally */
            }
            gpio_cpu_configure(dev_data_ptr);
            _int_enable();
        }
        break;

        case GPIO_IOCTL_WRITE_LOG1: {
        /* If this file is configured as output, sets every pin to 1. Params:
           list of pin addresses to be used or NULL for every pin in the file */
            if (dev_data_ptr->type != DEV_OUTPUT)
                return IO_ERROR;
            if (param_ptr == NULL) { /* apply command to whole file */
                _int_disable(); /* _lwsem_wait(&gpio_sem) replacement */
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 0) = dev_data_ptr->pin_map.memory32[0];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 1) = dev_data_ptr->pin_map.memory32[1];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 2) = dev_data_ptr->pin_map.memory32[2];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 3) = dev_data_ptr->pin_map.memory32[3];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 4) = dev_data_ptr->pin_map.memory32[4];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 5) = dev_data_ptr->pin_map.memory32[5];
                _int_enable(); /* _int_enable(); */
                break;
            }
            else {
                GPIO_PIN_STRUCT _PTR_  pin_table;
                uint_32        addr;
                uint_8         pin;
                GPIO_PIN_MAP_PTR    temp_pin_map_ptr;

                if (NULL == (temp_pin_map_ptr = (GPIO_PIN_MAP_PTR) _mem_alloc_system_zero(sizeof(GPIO_PIN_MAP))))
                    return IO_ERROR;
    
                _int_disable();
                /* check if there is not pin in the list which this file does not contain */
                for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) {
                    if (*pin_table & GPIO_PIN_VALID) { /* check pin validity bit */
                        addr = (*pin_table & GPIO_PIN_ADDR) >> 3; /* prepare address of port */ 
                        pin = 1 << (*pin_table & 0x07);  /* prepare bit mask */
                        if (addr < sizeof(GPIO_PIN_MAP)) /* pin address out of map scope? */
                            if (dev_data_ptr->pin_map.memory8[addr] & pin) { /* pin address already used? */
                                temp_pin_map_ptr->memory8[addr] |= pin;
                                continue; /* manage next pin */
                            }
                    }
                    /* some problem occured */
                    _int_enable();
                    _mem_free(temp_pin_map_ptr);
                    return IO_ERROR;
                }
                /* ok, now we can apply new map */
                /* note: applying the map after collecting pins is due to have pins applied in one instruction */
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 0) = temp_pin_map_ptr->memory32[0];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 1) = temp_pin_map_ptr->memory32[1];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 2) = temp_pin_map_ptr->memory32[2];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 3) = temp_pin_map_ptr->memory32[3];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 4) = temp_pin_map_ptr->memory32[4];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 5) = temp_pin_map_ptr->memory32[5];
                _int_enable();
                _mem_free(temp_pin_map_ptr);
            }
        }
        break;

        case GPIO_IOCTL_WRITE_LOG0: {
        /* If this file is configured as output, clears every pin to 0. Params:
           list of pin addresses to be used or NULL for every pin in the file */
            if (dev_data_ptr->type != DEV_OUTPUT)
                return IO_ERROR;
            if (param_ptr == NULL) { /* apply command to whole file */
                _int_disable(); /* _lwsem_wait(&gpio_sem) replacement */
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 0) = ~dev_data_ptr->pin_map.memory32[0];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 1) = ~dev_data_ptr->pin_map.memory32[1];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 2) = ~dev_data_ptr->pin_map.memory32[2];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 3) = ~dev_data_ptr->pin_map.memory32[3];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 4) = ~dev_data_ptr->pin_map.memory32[4];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 5) = ~dev_data_ptr->pin_map.memory32[5];
                _int_enable(); /* _int_enable(); */
                break;
            }
            else {
                GPIO_PIN_STRUCT _PTR_  pin_table;
                uint_32        addr;
                uint_8         pin;
                GPIO_PIN_MAP_PTR    temp_pin_map_ptr;

                if (NULL == (temp_pin_map_ptr = (GPIO_PIN_MAP_PTR) _mem_alloc_system_zero(sizeof(GPIO_PIN_MAP))))
                    return IO_ERROR;
    
                _int_disable();
                /* check if there is not pin in the list which this file does not contain */
                for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) {
                    if (*pin_table & GPIO_PIN_VALID) { /* check pin validity bit */
                        addr = (*pin_table & GPIO_PIN_ADDR) >> 3; /* prepare address of port */ 
                        pin = 1 << (*pin_table & 0x07);  /* prepare bit mask */
                        if (addr < sizeof(GPIO_PIN_MAP)) /* pin address out of map scope? */
                            if (dev_data_ptr->pin_map.memory8[addr] & pin) { /* pin address already used? */
                                temp_pin_map_ptr->memory8[addr] |= pin;
                                continue; /* manage next pin */
                            }
                    }
                    /* some problem occured */
                    _int_enable();
                    _mem_free(temp_pin_map_ptr);
                    return IO_ERROR;
                }
                /* ok, now we can apply new map */
                /* note: applying the map after collecting pins is due to have pins applied in one instruction */
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 0) = ~temp_pin_map_ptr->memory32[0];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 1) = ~temp_pin_map_ptr->memory32[1];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 2) = ~temp_pin_map_ptr->memory32[2];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 3) = ~temp_pin_map_ptr->memory32[3];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 4) = ~temp_pin_map_ptr->memory32[4];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 5) = ~temp_pin_map_ptr->memory32[5];
                _int_enable();
                _mem_free(temp_pin_map_ptr);
            }
        }
        break;

        case GPIO_IOCTL_WRITE: {
        /* If this file is configured as output, sets every pin to the state defined in GPIO_PIN_STATUS. Params:
           list of pin addresses to be used or NULL for every pin in the file */
            if (dev_data_ptr->type != DEV_OUTPUT)
                return IO_ERROR;
            if (param_ptr == NULL) /* no param specified , but must be */
                return IO_ERROR;
            else {
                GPIO_PIN_STRUCT _PTR_  pin_table;
                uint_32        addr;
                uint_8         pin;
                GPIO_PIN_MAP_PTR    temp_pin0_map_ptr;
                GPIO_PIN_MAP_PTR    temp_pin1_map_ptr;

                if (NULL == (temp_pin0_map_ptr = (GPIO_PIN_MAP_PTR) _mem_alloc_system_zero(sizeof(GPIO_PIN_MAP))))
                    return IO_ERROR;
    
                if (NULL == (temp_pin1_map_ptr = (GPIO_PIN_MAP_PTR) _mem_alloc_system_zero(sizeof(GPIO_PIN_MAP)))) {
                    _mem_free(temp_pin0_map_ptr);
                    return IO_ERROR;
                }

                _int_disable();
                /* check if there is not pin in the list which this file does not contain */
                for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) {
                    if (*pin_table & GPIO_PIN_VALID) { /* check pin validity bit */
                        addr = (*pin_table & GPIO_PIN_ADDR) >> 3; /* prepare address of port */ 
                        pin = 1 << (*pin_table & 0x07);  /* prepare bit mask */
                        if (addr < sizeof(GPIO_PIN_MAP)) /* pin address out of map scope? */
                            if (dev_data_ptr->pin_map.memory8[addr] & pin) { /* pin address already used? */
                                if (*pin_table & GPIO_PIN_STATUS)
                                    temp_pin1_map_ptr->memory8[addr] |= pin;
                                else
                                    temp_pin0_map_ptr->memory8[addr] |= pin;
                                continue; /* manage next pin */
                            }
                    }
                    /* some problem occured */
                    _int_enable();
                    _mem_free(temp_pin1_map_ptr);
                    _mem_free(temp_pin0_map_ptr);
                    return IO_ERROR;
                }
                /* ok, now we can apply new map */
                /* note: applying the map after collecting pins is due to have pins applied in one instruction */
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 0) = temp_pin1_map_ptr->memory32[0];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 0) = ~temp_pin0_map_ptr->memory32[0];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 1) = temp_pin1_map_ptr->memory32[1];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 1) = ~temp_pin0_map_ptr->memory32[1];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 2) = temp_pin1_map_ptr->memory32[2];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 2) = ~temp_pin0_map_ptr->memory32[2];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 3) = temp_pin1_map_ptr->memory32[3];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 3) = ~temp_pin0_map_ptr->memory32[3];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 4) = temp_pin1_map_ptr->memory32[4];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 4) = ~temp_pin0_map_ptr->memory32[4];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->PORTTEP_SETTE)) + 5) = temp_pin1_map_ptr->memory32[5];
                * (((uint_32 _PTR_) (&mcf5225_gpio_ptr->CLRTE)) + 5) = ~temp_pin0_map_ptr->memory32[5];
                _int_enable();
                _mem_free(temp_pin1_map_ptr);
                _mem_free(temp_pin0_map_ptr);
            }
        }
        break;

        case GPIO_IOCTL_READ: {
        /* Read status of pins, if configured as input. Params: pointer to predefined table where data will be written */
            GPIO_PIN_STRUCT _PTR_  pin_table;
            uint_32        addr;
            uint_8         pin;

            if (dev_data_ptr->type != DEV_INPUT)
                return IO_ERROR;
            if (param_ptr == NULL) /* no list defined */
                return IO_ERROR;
            _int_disable();
            /* check if there is not pin in the list which this file does not contain */
            for (pin_table = (GPIO_PIN_STRUCT _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) {
                if (*pin_table & GPIO_PIN_VALID) { /* check pin validity bit */
                    addr = (*pin_table & GPIO_PIN_ADDR) >> 3; /* prepare address of port */ 
                    pin = 1 << (*pin_table & 0x07);  /* prepare bit mask */
                    if (addr < sizeof(GPIO_PIN_MAP)) /* pin address out of map scope? */
                        if (dev_data_ptr->pin_map.memory8[addr] & pin) { /* pin address already used? */
                            if ((addr == 8) && (gpio_global_irq_map.memory8[addr] & 0xAA & pin)) { /* EPORT port and pin 1, 3, 5, or 7 */
                                if ( *(((uint_8 _PTR_) &mcf5225_eport_ptr->EPPDR)) & pin) /* check pin status */
                                    *pin_table |= GPIO_PIN_STATUS; /* set pin status to 1 in the list */
                                else
                                    *pin_table &= ~GPIO_PIN_STATUS; /* clear pin status to 0 in the list */
                                continue;
                            }
                            else { /* GPIO port */
                                if ( *(((uint_8 _PTR_) &mcf5225_gpio_ptr->PORTTEP_SETTE) + addr) & pin) /* check pin status */
                                    *pin_table |= GPIO_PIN_STATUS; /* set pin status to 1 in the list */
                                else
                                    *pin_table &= ~GPIO_PIN_STATUS; /* clear pin status to 0 in the list */
                                continue; /* manage next pin */
                            }
                    }
                }
                /* some problem occured */
                _int_enable();
                return IO_ERROR;
            }
            _int_enable();
        }
        break;

        case GPIO_IOCTL_ENABLE_IRQ:
            mcf5225_eport_ptr->EPIER |= (dev_data_ptr->irqp_map.reg.portnq | dev_data_ptr->irqn_map.reg.portnq); /* set interrupt enable */
            break;

        case GPIO_IOCTL_DISABLE_IRQ:
            mcf5225_eport_ptr->EPIER &= ~(dev_data_ptr->irqp_map.reg.portnq | dev_data_ptr->irqn_map.reg.portnq); /* set interrupt disable */
            break;

        case GPIO_IOCTL_SET_IRQ_FUNCTION: {
            if (dev_data_ptr->type == DEV_OUTPUT)
                return IO_ERROR; /* cannot set IRQ for output devices */

            dev_data_ptr->irq_func = (IRQ_FUNC)param_ptr;
            _int_disable();
            
            if (param_ptr == NULL) {  /* remove function from list */
                if (first_irq != NULL) {
                    GPIO_DEV_DATA_PTR gptr = first_irq;
                    while (gptr->NEXT != NULL) {
                        if (gptr == dev_data_ptr)
                            break;
                        if (gptr->NEXT == dev_data_ptr)
                            break;
                        gptr = gptr->NEXT;
                    }
                    if (gptr == dev_data_ptr) /* found as first in the list */
                        first_irq = first_irq->NEXT;
                    else if (gptr->NEXT == dev_data_ptr) /* found in the middle or at the end of list */
                        gptr->NEXT = gptr->NEXT->NEXT;
                }
            }
            else { /* add new function to the list */
                if (first_irq == NULL) {
                    first_irq = dev_data_ptr;
                }
                else {
                    GPIO_DEV_DATA_PTR gptr = first_irq;
                    while (gptr->NEXT != NULL) {
                        if (gptr == dev_data_ptr)
                            break;
                        gptr = gptr->NEXT;
                    }
                    if (gptr != dev_data_ptr)
                        gptr->NEXT = dev_data_ptr;
                }
            }
            _int_enable();
        }
        break;

        default:
            return IO_ERROR_INVALID_IOCTL_CMD;
    }
 
    return IO_OK;
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : gpio_eport_irq
* Returned Value   : 
* Comments         : GPIO IRQ handler
*    
*
*END*********************************************************************/
static void gpio_eport_irq (pointer param) {
    GPIO_DEV_DATA_PTR gptr = first_irq;
    
    while (gptr) { /* list through all irq files */
        if ((gptr->irqp_map.reg.portnq | gptr->irqn_map.reg.portnq) & mcf5225_eport_ptr->EPFR)
            gptr->irq_func(NULL);
        gptr = gptr->NEXT;
    }
    mcf5225_eport_ptr->EPFR = 0xFF; /* clear flag(s) */
}

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_gpio_base_address
* Returned Value   : pointer to base of GPIO registers
* Comments         :
*    This function returns base address of GPIO related register space.
*
*END*********************************************************************/
pointer _bsp_get_gpio_base_address
(
    void
)
{
    return (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO);
}

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/aeskeys.c<|end_filename|>
const unsigned char AESKey[32] = 
{
	0xed, 0x7d, 0xb4, 0xc7, 0x15, 0x88, 0x4a, 0x1e,
	0x04, 0x1f, 0x9a, 0x33, 0xff, 0xc2, 0x32, 0x25,
	0xe0, 0x61, 0xf7, 0xd7, 0x7f, 0x20, 0x22, 0x5e,
	0x31, 0xdd, 0xa7, 0x0e, 0xf8, 0x88, 0xdd, 0xfc,
};

const unsigned char AES_init_vector[16] = 
{
  0xF4,0xE7,0x40,0x0C,0xCF,0xFF,0x34,0xBB,0x63,0xA0,0x79,0xAE,0x81,0xA6,0x8F,0x3A
};


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd.c$
* $Version : 3.8.33.0$
* $Date    : Sep-21-2012$
*
* Comments:
*
*   This file contains the HTTPD implementation.
*
*END************************************************************************/

#include "httpd.h"
#include "httpd_supp.h"
#include "httpd_prv.h"

#if HTTPDCFG_POLL_MODE
#include <select.h>
#endif

#include <string.h>
#include <stdlib.h>

HTTPD_PARAMS_STRUCT* httpd_default_params(HTTPD_PARAMS_STRUCT *params) {
    HTTPD_PARAMS_STRUCT *ptr = NULL;
    uint_32 stack;

    if (params) {
        ptr = params;
    }
    else {
       ptr = HTTPD_MALLOC(sizeof(HTTPD_PARAMS_STRUCT));
       HTTPD_MEMTYPE(ptr,MEM_TYPE_HTTPD_PARAMS);
    }
    if (ptr) {
        HTTPD_MEMZERO(ptr, sizeof(HTTPD_PARAMS_STRUCT));

        ptr->port = HTTPDCFG_DEF_PORT;
        ptr->address = HTTPDCFG_DEF_ADDR;//default listen address

#if RTCSCFG_ENABLE_IP6
        IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(ptr->ipv6_address)); //set listen address to ANY
#endif
        ptr->max_uri = HTTPDCFG_DEF_URL_LEN;
        ptr->max_auth = HTTPDCFG_DEF_AUTH_LEN;

        ptr->cgi_lnk_tbl = 0;
        ptr->fn_lnk_tbl = 0;

        ptr->auth_fn = 0;

        ptr->root_dir = NULL;
        ptr->index_page = HTTPDCFG_DEF_INDEX_PAGE;

        ptr->max_ses = HTTPDCFG_DEF_SES_CNT;

#if HTTPDCFG_POLL_MODE
        ptr->max_line = HTTPD_MAX_LEN;
        stack = MAX(MAX(HTTPD_MAX_LEN, HTTPDCFG_MAX_BYTES_TO_SEND), HTTPDCFG_MAX_SCRIPT_LN) + 10 * sizeof(void*);
        stack = MAX(3 * stack, HTTPD_MIN_SES_STACK_SIZE);
#else
        stack = HTTPD_SERVER_STACK_SIZE;
#endif

        ptr->server_stack = stack;
        ptr->server_prio = HTTPDCFG_DEF_SERVER_PRIO;

#if !HTTPDCFG_POLL_MODE
        ptr->ses_prio = HTTPDCFG_DEF_SESSION_PRIO;

        stack = MAX(MAX(HTTPD_MAX_LEN, HTTPDCFG_MAX_BYTES_TO_SEND), HTTPDCFG_MAX_SCRIPT_LN) + 10 * sizeof(void*);
        stack = MAX(3 * stack, HTTPD_MIN_SES_STACK_SIZE);
        ptr->ses_stack = stack;
#endif
    }

    return ptr;
}

_mqx_int httpd_set_index_page(HTTPD_STRUCT *server, char *index_page)
{
    HTTPD_ASSERT(server && server->params && index_page);
    if (server && server->params && index_page)
    {
        server->params->index_page = index_page;
        return 0;
    }

    return 1;
}

HTTPD_STRUCT* httpd_init(HTTPD_PARAMS_STRUCT *params)
{
    sockaddr sin_sock_v4;
    sockaddr sin_sock_v6;

    HTTPD_STRUCT *server = NULL;
    int option, error;
  #if  HTTPDCFG_POLL_MODE /* FSL AB */
    int si;
  #endif  /* HTTPDCFG_POLL_MODE */

    HTTPD_ASSERT(params);

    if (params == NULL)
        return NULL;

    if ((server = HTTPD_MALLOC(sizeof(HTTPD_STRUCT))) == NULL) {
        HTTPD_DEBUG(1, "server: main structure allocation error\n");
        return NULL;
    }

    _mem_zero(server, sizeof(HTTPD_STRUCT));
    HTTPD_MEMTYPE(server,MEM_TYPE_HTTPD_STRUCT);
    server->params = params;

#if HTTPDCFG_POLL_MODE
    // session table allocation
    if ((server->session = HTTPD_MALLOC(sizeof(HTTPD_SESSION_STRUCT*) * server->params->max_ses)) == NULL) {
        HTTPD_DEBUG(1, "server: session table allocation error\n");
        goto ERROR_ALLOC;
    }

    HTTPD_MEMTYPE(server->session, MEM_TYPE_HTTPD_SESSION_STRUCT);

    // sessions allocation and sessions table initialization
    for (si = 0; si < server->params->max_ses; si++) {
        server->session[si] = httpd_ses_alloc(server);

        if (server->session[si] == NULL) {
            while (--si) {
                HTTPD_FREE(server->session[si]);
            }

            HTTPD_DEBUG(1, "server: session allocation error\n");
            goto ERROR_ALLOC;
        }
    }
#endif

    /* Init socket. */
    /* Open socket for IPv4. */
#if RTCSCFG_ENABLE_IP4
    if( ((params->af)&AF_INET) == AF_INET)
    {

        if ((server->sock_v4 = socket(AF_INET, SOCK_STREAM, 0)) == RTCS_ERROR)
        {
            HTTPD_DEBUG(1, "socket_v4: creation error\n");
            goto ERROR_ALLOC;
        }
        option = 500;
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_SEND_TIMEOUT, &option, sizeof(option));
        option = 5000;
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));
        option = 1000;
        option = 1000;
        option = HTTPCFG_TIMEWAIT_TIMEOUT;
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));
    #if HTTPDCFG_POLL_MODE
        option = 500;
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_RECEIVE_TIMEOUT, &option, sizeof(option));
        option = TRUE;
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, sizeof(option));
        option = TRUE;
    #else
        option = 0;     // 0 - RTCS default
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_RECEIVE_TIMEOUT, &option, sizeof(option));
        option = FALSE; // FALSE - RTCS default
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, sizeof(option));
        option = TRUE;  // TRUE - RTCS default
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_RECEIVE_PUSH, &option, sizeof(option));
    #endif
        option = TRUE;
        option = TRUE;
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &option, sizeof(option));
        option = HTTPCFG_TX_WINDOW_SIZE;
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));
        option = HTTPCFG_RX_WINDOW_SIZE;
        error = setsockopt(server->sock_v4, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));
        ((sockaddr_in *)&sin_sock_v4)->sin_port = server->params->port;
        ((sockaddr_in *)&sin_sock_v4)->sin_addr.s_addr = server->params->address;
        ((sockaddr_in *)&sin_sock_v4)->sin_family = AF_INET;
        error = (int_32) bind(server->sock_v4, &sin_sock_v4, sizeof(sin_sock_v4));
        if(error != 0)
        {
            HTTPD_DEBUG(1, "bind error\n");
            goto ERROR;
        }
        /* listen */
        error = (int_32)listen(server->sock_v4, 5);
        if (error != 0)
        {
            HTTPD_DEBUG(1, "socket: listen error\n");
            goto ERROR;
        }
    }
#endif
    /* Open socket for IPv6. */
#if RTCSCFG_ENABLE_IP6
    if( ((params->af)&AF_INET6) == AF_INET6)
    {

        if ((server->sock_v6 = socket(AF_INET6, SOCK_STREAM, 0)) == RTCS_ERROR)
        {
            HTTPD_DEBUG(1, "socket_v6: creation error\n");
            goto ERROR_ALLOC;
        }
        option = 500;
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_SEND_TIMEOUT, &option, sizeof(option));
        option = 5000;
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));
        option = 1000;
        option = 1000;
        option = HTTPCFG_TIMEWAIT_TIMEOUT;
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));
    #if HTTPDCFG_POLL_MODE
        option = 500;
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_RECEIVE_TIMEOUT, &option, sizeof(option));
        option = TRUE;
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, sizeof(option));
        option = TRUE;
    #else
        option = 0;     // 0 - RTCS default
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_RECEIVE_TIMEOUT, &option, sizeof(option));
        option = FALSE; // FALSE - RTCS default
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, sizeof(option));
        option = TRUE;  // TRUE - RTCS default
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_RECEIVE_PUSH, &option, sizeof(option));
    #endif
        option = TRUE;
        option = TRUE;
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &option, sizeof(option));
        option = HTTPCFG_TX_WINDOW_SIZE;
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));
        option = HTTPCFG_RX_WINDOW_SIZE;
        error = setsockopt(server->sock_v6, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));
        ((sockaddr_in6 *)&sin_sock_v6)->sin6_port      = server->params->port;
        ((sockaddr_in6 *)&sin_sock_v6)->sin6_family    = AF_INET6;
        /* add here scope_id for our server */
        ((sockaddr_in6 *)&sin_sock_v6)->sin6_scope_id  = server->params->if_scope_id;
        IN6_ADDR_COPY(&(server->params->ipv6_address), &(((sockaddr_in6 *)&sin_sock_v6)->sin6_addr));
        error = (int_32)bind(server->sock_v6, &sin_sock_v6, sizeof(sin_sock_v6));
        if(error != 0)
        {
            HTTPD_DEBUG(1, "bind error\n");
            goto ERROR;
        }
        /* listen*/
        error = (int_32)listen(server->sock_v6, 5);
        if (error != 0)
        {
            HTTPD_DEBUG(1, "socket: listen error\n");
            goto ERROR;
        }
    }
#endif

#if (RTCSCFG_ENABLE_IP4 || RTCSCFG_ENABLE_IP6)
    if (((params->af & AF_INET6) != AF_INET6) && (params->af & AF_INET) != AF_INET)
    {
        /* Wrong IP familly detected. */
        HTTPD_DEBUG(1, "Wrong IP familly detected.\n");
        goto ERROR_ALLOC;
    }


    server->run = 1;

    HTTPD_DEBUG(1, "------------------------------------------\n");
    HTTPD_DEBUG(1, " HTTP 1.0 server has been started.\n");
    HTTPD_DEBUG(1, "------------------------------------------\n\n");

    return server;

    ERROR:
    printf("error 0x%X\n", error);

    shutdown(server->sock_v4, FLAG_ABORT_CONNECTION);
    shutdown(server->sock_v6, FLAG_ABORT_CONNECTION);
#endif

ERROR_ALLOC:

    HTTPD_FREE(server);

    return NULL;
}


_mqx_int httpd_release(HTTPD_STRUCT *server)
{
    _mqx_int res = 0;

    if (server->run == 0 && server)
    {
        /* Shutdown all sockets from server. */
        shutdown(server->sock, FLAG_ABORT_CONNECTION);
        shutdown(server->sock_v4, FLAG_ABORT_CONNECTION);
        shutdown(server->sock_v6, FLAG_ABORT_CONNECTION);

        memset(server->params, 0, sizeof(HTTPD_PARAMS_STRUCT));
    }
    else
        res = -1;

    return res;
}


/** Close session
 * \param session < pointer to session
 */
static void httpd_ses_close(HTTPD_SESSION_STRUCT *session) {
    HTTPD_ASSERT(session);
    HTTPD_DEBUG(1, "session closed (%p)\n", session);

    if (session->response.file) {
        fclose(session->response.file);
    }

    session->valid = HTTPD_SESSION_INVALID;

    shutdown(session->sock, FLAG_CLOSE_TX);
}

/** Read http request.
 * \param session < pointer to session structure
 * \return
 */
static int httpd_readreq(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
#if HTTPDCFG_POLL_MODE
    char *buf;
#else
    char buf[HTTPD_MAX_LEN + 1];
#endif

    char *cp, *cp2;
    int max_len, res;


    HTTPD_ASSERT(server && session);

    // standard response
    strcpy(session->response.header, "Server: MQX HTTP - Freescale Embedded Web Server\n");
    session->response.contenttype = CONTENT_TYPE_HTML;
    session->response.statuscode = 200;
    session->response.hdrsent = 0;
    session->response.file = NULL;
    session->response.data = 0;
    session->response.script_token = 0;

    HTTPD_DEBUG(4, "request BEGIN\n");


#if HTTPDCFG_POLL_MODE
    buf = &session->line[session->line_used];
    max_len = server->params->max_line - session->line_used;
#else
    max_len = HTTPD_MAX_LEN;
#endif

    // read the request
    while (0 < (res = httpd_readln(session, buf, max_len)))
    {
        HTTPD_DEBUG(4, "request (%p): %s\n", session, buf);
        session->req_lines++;

#if HTTPDCFG_POLL_MODE
        buf = session->line;
        res = server->params->max_line;
#endif

        if (1 == session->req_lines) {  // first line = start-line
            if ((cp = strstr(buf, "GET"))!=0)
            {
                session->request.method = HTTPD_REQ_GET;
            }
            else if ((cp = strstr(buf, "POST"))!=0)
            {
                session->request.method = HTTPD_REQ_POST;
            }
            else {  // unknown method
                session->request.method = HTTPD_REQ_UNKNOWN;
                return -1;
            }

            // parse remain part of 1. line
            cp = strchr(cp, ' ') + 1;
            cp2 = strchr(cp, ' ');
            *cp2 = 0;

            strncpy(session->request.path, cp, server->params->max_uri);
            continue;
        }

        if (session->header) {
            if (buf[0] == '\r' && buf[1] == '\n') {        // header end - \r\n\r\n
                session->header = 0;

                res = 0;
                break;
            }
            else if (strncmp(buf, "Connection: ", 12) == 0)
            {
                cp = strchr(buf, ':') + 2;

                if ( (strncmp(cp, "keep-alive", 10) == 0)||(strncmp(cp, "Keep-Alive", 10) == 0) )
                {
                    /* You should remember that HTTP 1.0 do not support keep alive */
                    /* It is only work around */
                    session->keep_alive = 1;
                    HTTPD_DEBUG(4, "Connection: keep-alive = 1\n");
                }
            }
            else if (strncmp(buf, "Content-Length: ", 16) == 0) {
                cp = strchr(buf, ':') + 2;
                if (cp)
                {
                    session->request.content_len = _io_atoi(cp);
                    HTTPD_DEBUG(4, "Content-Length: %u\n", session->request.content_len);
                }
            }
            else if (strncmp(buf, "Authorization: ", 15) == 0) {
                cp = strchr(buf, ':') + 2;

                if (strncmp(cp, "Basic ", 6) == 0) {
                    cp = strchr(cp, ' ') + 1;

                    httpd_decode_base64(session->request.auth, cp, (int)server->params->max_auth);

                    cp = strchr(session->request.auth, ':');
                    if (cp)
                    {
                        *cp = 0;
                        session->request.authPasswd = cp + 1;
                    }

                    HTTPD_DEBUG(4, "Authorization - Basic: %s:%s\n", session->request.auth, session->request.authPasswd);
                }
                else
                {
                    HTTPD_DEBUG(4, "Authorization - unknown method\n");
                }
            }

            continue;
        }
    }

#if HTTPDCFG_POLL_MODE
    session->line_used += res;
#endif

    if (!session->header)
    {
        // process any URL data
        cp = strchr(session->request.path, '?');
        if (0 != cp)
        {
            *cp = 0;
            cp++;
            session->request.urldata = cp;
        }
    }

    HTTPD_DEBUG(4, "request END res = %d\n", res);

    return (0 > res) ? res : 0;
}

/** Http request process.
 * \param server < pointer to server
 * \param session < pointer to session data structure
 */
static void httpd_processreq(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session)
{
    char buf[HTTPD_MAX_LEN + 1];
    char *cp, *cp1;
    int cgi = 0, res = 0, auth = 0; // authorization required flag
    HTTPD_ROOT_DIR_STRUCT *root_dir;

    HTTPD_ASSERT(server && session);

    // check request path
    cp = strrchr(session->request.path, '/');
    if (0 == cp)
    {
        HTTPD_DEBUG(1, "Invalid request path '%s'\n", session->request.path);
        return;
    }

    if (session->request.path[0] == '/' && session->request.path[1] == 0)
        strcpy(session->request.path, server->params->index_page);

    // check if request is script request

    // if request contain data
    res = -1;

    if ((cp1 = strrchr(cp, '.')) != 0)
    {
        if (0 == strcasecmp(cp1, ".cgi"))   // file extension is cgi, maybe cgi script
        {
            cgi = 1;

            // search cgi script
            *cp1 = 0;
            res = httpd_cgi(server, session, cp + 1);   // cp + 1 = cgi script name begin
            *cp1 = '.';
        }
    }

    if (cgi || session->request.content_len)
    {
        if (res < 0)
        {
            if (res != -2)
            	cgi = 0;

            // cgi script not found - read data from socket - discard it
            while (session->request.content_len)
            {
                res = httpd_read(session, buf, (int)((res > sizeof(buf))? sizeof(buf) : session->request.content_len));

                session->request.content_len -= res;

                // TODO add timeout - can be deadlock

                // temporary solution
                if (res == 0)
                    break;
            }

        }
        else {
            // cgi script found - decrease content len
            session->request.content_len -= res;

            if (session->request.content_len == 0)  // whole content procesed
                session->state = HTTPD_SES_END_REQ;
        }
    }

    // send regular file(document) - if is not cgi script
    if (!cgi) {
        // get correct root dir (by alias)

        if (server->params->root_dir[1].alias) {
            // more root dir pressents, find alias
            root_dir = server->params->root_dir;

            cp = strchr(session->request.path, '/');

            if (cp) {
                cp++;
                cp1 = strchr(cp, '/');

                if (cp1) {
                    while (root_dir->alias) {
                        if (strncmp(root_dir->alias, cp, cp1 - cp) == 0) {
                            strcpy(buf, root_dir->path);
                            strcat(buf, cp1);
                            break;
                        }

                        root_dir++;
                    }
                }
            }

            if (!cp || !cp1 || !root_dir->alias) {
                strcpy(buf, server->params->root_dir->path);
                strcat(buf, session->request.path);
            }
        }
        else {
            strcpy(buf, server->params->root_dir[0].path);
            strcat(buf, session->request.path);
        }

        // correct slash
        cp = buf;
        while (*cp) {
            if ('/' == *cp)
                *cp = '\\';

            cp++;
        }

        session->response.file = fopen(buf, "rb");
        session->response.len = 0;

        if (session->response.file) {
        }
        else {
            session->response.statuscode = 404;
        }

        session->state = HTTPD_SES_RESP;
    }

    if (auth && server->params->auth_fn)
    {
        if (*session->request.auth)
        {
            // check authorization
            if (server->params->auth_fn(session))
            {
                session->response.statuscode = 401;
                strncat(session->response.header, "WWW-Authenticate: Basic realm=\"test\"\n", HTTPDCFG_MAX_HEADER_LEN);
            }
        }
        else
        {
            session->response.statuscode = 401;
            strncat(session->response.header, "WWW-Authenticate: Basic realm=\"test\"\n", HTTPDCFG_MAX_HEADER_LEN);
        }
    }
}

/** http response
 * \param server < pointer to server data structure
 * \param session < pointer to session data structure
 */
static void httpd_response(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    HTTPD_ASSERT(server && session);

    switch (session->response.statuscode) {
    case 200:
        httpd_sendfile(server, session);
        break;
    case 401:
        httpd_send401(server, session);
        session->state = HTTPD_SES_END_REQ;
        break;
    default:
        httpd_send404(server, session);
        session->state = HTTPD_SES_END_REQ;
        break;
    }
}

/** HTTPD session state machine
 * \param server < pointer to server
 * \param session < session number
 */
void httpd_ses_process(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    HTTPD_TIME_STRUCT time;
    int res;
    HTTPD_ASSERT(server && session);

    if (HTTPD_SESSION_VALID == session->valid)
    {
        // check timeout
        HTTPD_GET_TIME(&time);
        if (HTTPD_DIFF_TIME_MS(session->time, time) > HTTPDCFG_SES_TO) {
            HTTPD_DEBUG(1, "session %p timeout\n", session);
            session->state = HTTPD_SES_CLOSE;
        }

        switch (session->state) {
        case HTTPD_SES_WAIT_REQ:
            res = httpd_readreq(server, session);
            if (0 > res) {
                session->state = HTTPD_SES_END_REQ;
            }
            else {
                if (session->header == 0) {
                    session->state = HTTPD_SES_PROCESS_REQ;
                }
            }

            break;
        case HTTPD_SES_PROCESS_REQ:
            httpd_processreq(server, session);
            break;

        case HTTPD_SES_RESP:
            httpd_response(server, session);
            break;

        case HTTPD_SES_END_REQ:
            if (!session->keep_alive)
            {
                session->state = HTTPD_SES_CLOSE;
            }
            else
            {
                // init session
                session->state = HTTPD_SES_WAIT_REQ;
                if (session->response.file)
                {
                    fclose(session->response.file);
                    /* To be sure that file handle will not used. */
                    session->response.file = NULL;
                }
                session->header = 1;
                session->req_lines = 0;
                session->remain = 0;

                /*
                  To avoid problem with keep- alive, just added receive time out.
                  If client fast enough, it can use opened connection. If not,
                  server will close connection after timeout.
                */
                ((SOCKET_STRUCT_PTR)session->sock)->RECEIVE_TIMEOUT =HTTPD_RECEIVE_TIMEOUT;

#if HTTPDCFG_POLL_MODE
                session->recv_used = 0;
#endif

                HTTPD_GET_TIME(&session->time);

                session->keep_alive--;
                break;
            }

        case HTTPD_SES_CLOSE:
            httpd_ses_close(session);
            break;

        default:
            // invalid state
            session->valid = HTTPD_SESSION_INVALID;
            break;
        }
    }
}

/** Allocate session.
 * \param server < pointer to server
 * \return pointer to allocated session
 */
HTTPD_SESSION_STRUCT* httpd_ses_alloc(HTTPD_STRUCT *server) {
    HTTPD_SESSION_STRUCT *session = NULL;

    HTTPD_ASSERT(server);

    if (server) {
        session = HTTPD_MALLOC(sizeof(HTTPD_SESSION_STRUCT));
        if (session) {
            HTTPD_MEMTYPE(session,MEM_TYPE_HTTPD_SESSION_STRUCT);

            HTTPD_MEMZERO(session, sizeof(HTTPD_SESSION_STRUCT));

            session->request.path = HTTPD_MALLOC(server->params->max_uri + 1);
            if (NULL == session->request.path)
                goto ERROR;

            HTTPD_MEMTYPE(session->request.path,MEM_TYPE_HTTPD_URI);

            session->request.auth = HTTPD_MALLOC(server->params->max_auth + 1);
            if (NULL == session->request.auth)
                goto ERROR;

            HTTPD_MEMTYPE(session->request.auth,MEM_TYPE_HTTPD_AUTH);

#if HTTPDCFG_POLL_MODE
            session->recv_used = 0;

            session->line = HTTPD_MALLOC(server->params->max_line + 1);;
            HTTPD_MEMTYPE(session->line, MEM_TYPE_HTTPD_LINE);
            session->line_used = 0;
#endif
        }
    }

    return session;

ERROR:
    if (session->request.path)
        HTTPD_FREE(session->request.path);

    HTTPD_FREE(session);

    return NULL;
}

void httpd_ses_free(HTTPD_SESSION_STRUCT *session) {
    HTTPD_ASSERT(session);

    if (session) {
        HTTPD_FREE(session->request.path);
        HTTPD_FREE(session->request.auth);
        HTTPD_FREE(session);
    }
}

void httpd_ses_init(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session, const int sock) {
    HTTPD_ASSERT(server && session && sock != RTCS_ERROR);

    HTTPD_DEBUG(5, "httpd_ses_init: server(%p) session(%p) sock(0x%x)\n", server, session, sock);

    if (server && session) {
        // init session
        session->state = HTTPD_SES_WAIT_REQ;
        session->sock = sock;
        session->keep_alive = 0;
        session->valid = HTTPD_SESSION_VALID;

        session->header = 1;
        session->req_lines = 0;
        session->remain = 0;

        /* The auth data must be initialized when a new session
         * is init. Otherwise a new session may profit from a previous authenticated session. */
        HTTPD_MEMZERO(session->request.auth, server->params->max_auth);

#if HTTPDCFG_POLL_MODE
        session->recv_used = 0;
        session->line_used = 0;
#endif

        HTTPD_GET_TIME(&session->time);
    }
}

void httpd_ses_poll(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    int s;
    unsigned short len;
    struct sockaddr_in sin;

    HTTPD_ASSERT(server && session);

#if !HTTPDCFG_POLL_MODE
    // loop - when server run in task mode, loop until flag run is nonzero
    do {
#endif
        if (HTTPD_SESSION_VALID != session->valid) {
            len = sizeof(sin);

            s = accept(server->sock,(sockaddr *) &sin, &len);
            if (s && s != RTCS_SOCKET_ERROR) {
                HTTPD_DEBUG(1, "request from (%p): %d.%d.%d.%d; port: %d.\n", session, (sin.sin_addr.s_addr >> 24) & 0xff, (sin.sin_addr.s_addr >> 16) & 0xff, (sin.sin_addr.s_addr >> 8) & 0xff, sin.sin_addr.s_addr & 0xff, sin.sin_port);

                httpd_ses_init(server, session, s);
            }
        }

#if HTTPDCFG_POLL_MODE
        // in poll mode, session is partial processed
        if (HTTPD_SESSION_VALID == session->valid)
#else
        // in task mode, loop until session is valid
        while (HTTPD_SESSION_VALID == session->valid)
#endif
        {
            httpd_ses_process(server, session);
        }
#if !HTTPDCFG_POLL_MODE
        // task mode - loop until server run (run flag is nonzero)
    } while (server->run);
#endif

}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/lwmsgq.h<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwmsgq.h$
* $Version : 3.8.9.1$
* $Date    : Feb-22-2012$
*
* Comments:
*
*   This file containts definitions for use with light weight message queues
*
*END************************************************************************/

#ifndef __lwmsq_h__
#define __lwmsq_h__ 1

#include <mqx_cnfg.h>

#if (! MQX_USE_LWMSGQ) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#warning LWMSGQ component is currently disabled in MQX kernel. Please set MQX_USE_LWMSGQ to 1 in user_config.h and recompile kernel.
#endif

/*--------------------------------------------------------------------------*/
/*
 *                            MACRO DEFINITIONS
 */

/* control bits for lwmsgq_send */

/* Block writing task if msgq if full */
#define LWMSGQ_SEND_BLOCK_ON_FULL           (0x01)

/* Block the sending task once message has been sent */
#define LWMSGQ_SEND_BLOCK_ON_SEND           (0x02)

/* Block the reading task if msgq is empty */
#define LWMSGQ_RECEIVE_BLOCK_ON_EMPTY       (0x04)

/* Perform a timeout using the tick structure as the absolute time */
#define LWMSGQ_TIMEOUT_UNTIL                (0x08)

/* Perform a timeout using the tick structure as the relative time */
#define LWMSGQ_TIMEOUT_FOR                  (0x10)

/* Error messages */
#define LWMSGQ_INVALID                      (MSG_ERROR_BASE | 0x80)
#define LWMSGQ_FULL                         (MSG_ERROR_BASE | 0x81)
#define LWMSGQ_EMPTY                        (MSG_ERROR_BASE | 0x82)
#define LWMSGQ_TIMEOUT                      (MSG_ERROR_BASE | 0x83)

/* Helpful macros */

#define LWMSGQ_SIZE(lwq) (((LWMSGQ_STRUCT_PTR)(lwq))->CURRENT_SIZE)


/* Return whether the queue is empty */
#define LWMSGQ_IS_EMPTY(lwq) (((LWMSGQ_STRUCT_PTR)(lwq))->CURRENT_SIZE == 0)


/* Return whether the queue is full */
#define LWMSGQ_IS_FULL(q) \
   (((LWMSGQ_STRUCT_PTR)(q))->CURRENT_SIZE >= ((LWMSGQ_STRUCT_PTR)(q))->MAX_SIZE)

/*--------------------------------------------------------------------------*/
/*
 *                            DATATYPE DECLARATIONS
 */

/*---------------------------------------------------------------------*/

/* LWMSGQ STRUCTURE */

/*! 
 * \brief This structure is used to store a circular long word queue.
 *  
 * The structure must be the LAST if it is included into another data structure,
 * as the queue falls off of the end of this structure.
 */
typedef struct lwmsgq_struct
{
   /*! \brief Queue data structures. */
   QUEUE_ELEMENT_STRUCT LINK;

   /*! \brief A Queue of task descriptors waiting to write. */
   QUEUE_STRUCT WAITING_WRITERS;

   /*! \brief A Queue of task descriptors waiting to read. */
   QUEUE_STRUCT WAITING_READERS;

   /*! \brief The validity check field. */
   _mqx_uint    VALID;

   /*! \brief The size of the message chunk in the queue in _mqx_max_type's. */
   _mqx_uint    MSG_SIZE;

   /*!
    * \brief The maximum number of msgs for the queue, as specified in queue's
    * initialization.
    */
   _mqx_uint     MAX_SIZE;

   /*! \brief The current number of messages in the queue. */
   _mqx_uint    CURRENT_SIZE;

   /*! \brief Next message location to write to. */
   _mqx_max_type_ptr MSG_WRITE_LOC;

   /*! \brief Next message location to read from. */
   _mqx_max_type_ptr MSG_READ_LOC;

   /*! \brief Starting location of messages. */
   _mqx_max_type_ptr MSG_START_LOC;

   /*! \brief Location past end of messages. */
   _mqx_max_type_ptr MSG_END_LOC;

} LWMSGQ_STRUCT, _PTR_ LWMSGQ_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
 * FUNCTION PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

_mqx_uint _lwmsgq_init(pointer, _mqx_uint, _mqx_uint);
_mqx_uint _lwmsgq_send(pointer, _mqx_max_type_ptr, _mqx_uint);
_mqx_uint _lwmsgq_receive(pointer, _mqx_max_type_ptr, _mqx_uint, _mqx_uint, MQX_TICK_STRUCT_PTR);

#if MQX_ENABLE_USER_MODE
_mqx_uint _usr_lwmsgq_init(pointer, _mqx_uint, _mqx_uint);
_mqx_uint _usr_lwmsgq_send(pointer, _mqx_max_type_ptr, _mqx_uint);
_mqx_uint _usr_lwmsgq_receive(pointer, _mqx_max_type_ptr, _mqx_uint, _mqx_uint, MQX_TICK_STRUCT_PTR);

_mqx_uint _lwmsgq_usr_check(pointer);
#endif // MQX_ENABLE_USER_MODE

#ifdef __cplusplus
}
#endif

#endif /* __lwmsq_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/GPIO_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type GPIO
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(GPIO_PDD_H_)
#define GPIO_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error GPIO PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK10D5) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK10D7) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK10F12) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK10DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK11D5) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK11D5WS) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK12D5) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK20D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK20D5) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK20D7) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK20F12) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK20DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK21D5) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK21D5WS) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK22D5) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK30D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK30D7) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK30DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK40D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK40D7) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK40DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK40X256VMD100) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK50D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK50D7) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK50DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK51D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK51D7) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK51DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK52D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK52DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK53D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK53DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK60D10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK60F12) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK60F15) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK60DZ10) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK60N512VMD100) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MK61F12) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK61F15) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK61F12WS) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK61F15WS) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK70F12) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK70F15) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK70F12WS) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MK70F15WS) /* PTA, PTB, PTC, PTD, PTE, PTF */ && \
      !defined(MCU_MKL02Z4) /* PTA, PTB */ && \
      !defined(MCU_MKL04Z4) /* PTA, PTB */ && \
      !defined(MCU_MKL05Z4) /* PTA, PTB */ && \
      !defined(MCU_MKL14Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MKL15Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MKL16Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MKL24Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MKL25Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MKL26Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MKL34Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MKL36Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_MKL46Z4) /* PTA, PTB, PTC, PTD, PTE */ && \
      !defined(MCU_PCK20L4) /* PTA, PTB, PTC, PTD, PTE */
  // Unsupported MCU is active
  #error GPIO PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   -- GetPortDataInput
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets port data input independently of current direction setting.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: GPIOA_PDIR, GPIOB_PDIR,
 *          GPIOC_PDIR, GPIOD_PDIR, GPIOE_PDIR, GPIOF_PDIR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = GPIO_PDD_GetPortDataInput(deviceID);
 *      @endcode
 */
#define GPIO_PDD_GetPortDataInput(PeripheralBase) ( \
    GPIO_PDIR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- SetPortDataOutput
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets port data output.
 * @param PeripheralBase Peripheral base address.
 * @param Value Parameter specifying new data output value. This parameter is a
 *        32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: GPIOA_PDOR, GPIOB_PDOR,
 *          GPIOC_PDOR, GPIOD_PDOR, GPIOE_PDOR, GPIOF_PDOR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      GPIO_PDD_SetPortDataOutput(deviceID, 1);
 *      @endcode
 */
#define GPIO_PDD_SetPortDataOutput(PeripheralBase, Value) ( \
    GPIO_PDOR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- GetPortDataOutput
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets port data output independently of current direction setting.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: GPIOA_PDOR, GPIOB_PDOR,
 *          GPIOC_PDOR, GPIOD_PDOR, GPIOE_PDOR, GPIOF_PDOR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = GPIO_PDD_GetPortDataOutput(deviceID);
 *      @endcode
 */
#define GPIO_PDD_GetPortDataOutput(PeripheralBase) ( \
    GPIO_PDOR_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ClearPortDataOutputMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears required bits of port data output.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Parameter specifying port pins which should be cleared. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: GPIOA_PCOR, GPIOB_PCOR,
 *          GPIOC_PCOR, GPIOD_PCOR, GPIOE_PCOR, GPIOF_PCOR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      GPIO_PDD_ClearPortDataOutputMask(deviceID, 1);
 *      @endcode
 */
#define GPIO_PDD_ClearPortDataOutputMask(PeripheralBase, Mask) ( \
    GPIO_PCOR_REG(PeripheralBase) = \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- SetPortDataOutputMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets required bits of port data output.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Parameter specifying port pins which should be set. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: GPIOA_PSOR, GPIOB_PSOR,
 *          GPIOC_PSOR, GPIOD_PSOR, GPIOE_PSOR, GPIOF_PSOR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      GPIO_PDD_SetPortDataOutputMask(deviceID, 1);
 *      @endcode
 */
#define GPIO_PDD_SetPortDataOutputMask(PeripheralBase, Mask) ( \
    GPIO_PSOR_REG(PeripheralBase) = \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- TogglePortDataOutputMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Toggles required bits of port data output.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Parameter specifying port pins which should be inverted. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: GPIOA_PTOR, GPIOB_PTOR,
 *          GPIOC_PTOR, GPIOD_PTOR, GPIOE_PTOR, GPIOF_PTOR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      GPIO_PDD_TogglePortDataOutputMask(deviceID, 1);
 *      @endcode
 */
#define GPIO_PDD_TogglePortDataOutputMask(PeripheralBase, Mask) ( \
    GPIO_PTOR_REG(PeripheralBase) = \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- SetPortInputDirectionMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets required pins as input.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Parameter specifying port pins which should be set as input. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: GPIOA_PDDR, GPIOB_PDDR,
 *          GPIOC_PDDR, GPIOD_PDDR, GPIOE_PDDR, GPIOF_PDDR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      GPIO_PDD_SetPortInputDirectionMask(deviceID, 1);
 *      @endcode
 */
#define GPIO_PDD_SetPortInputDirectionMask(PeripheralBase, Mask) ( \
    GPIO_PDDR_REG(PeripheralBase) &= \
     (uint32_t)(~(uint32_t)(Mask)) \
  )

/* ----------------------------------------------------------------------------
   -- SetPortOutputDirectionMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets required pins as output.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Parameter specifying port pins which should be set as output.
 *        This parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: GPIOA_PDDR, GPIOB_PDDR,
 *          GPIOC_PDDR, GPIOD_PDDR, GPIOE_PDDR, GPIOF_PDDR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      GPIO_PDD_SetPortOutputDirectionMask(deviceID, 1);
 *      @endcode
 */
#define GPIO_PDD_SetPortOutputDirectionMask(PeripheralBase, Mask) ( \
    GPIO_PDDR_REG(PeripheralBase) |= \
     (uint32_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- SetPortDirection
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets direction of every pin in the port.
 * @param PeripheralBase Peripheral base address.
 * @param Value Parameter specifying new direction for port pins. This parameter
 *        is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: GPIOA_PDDR, GPIOB_PDDR,
 *          GPIOC_PDDR, GPIOD_PDDR, GPIOE_PDDR, GPIOF_PDDR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      GPIO_PDD_SetPortDirection(deviceID, 1);
 *      @endcode
 */
#define GPIO_PDD_SetPortDirection(PeripheralBase, Value) ( \
    GPIO_PDDR_REG(PeripheralBase) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- GetPortDirection
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets direction of every pin in the port.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: GPIOA_PDDR, GPIOB_PDDR,
 *          GPIOC_PDDR, GPIOD_PDDR, GPIOE_PDDR, GPIOF_PDDR (depending on the
 *          peripheral).
 * @par Example:
 *      @code
 *      uint32_t result = GPIO_PDD_GetPortDirection(deviceID);
 *      @endcode
 */
#define GPIO_PDD_GetPortDirection(PeripheralBase) ( \
    GPIO_PDDR_REG(PeripheralBase) \
  )
#endif  /* #if defined(GPIO_PDD_H_) */

/* GPIO_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/icmp.h<|end_filename|>
#ifndef __icmp_h__
#define __icmp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: icmp.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   Definitions for the ICMP protocol layer.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

/*
** ICMP message types
*/
#define ICMPTYPE_ECHO_REPLY   0
#define ICMPTYPE_DESTUNREACH  3
#define ICMPTYPE_SRCQUENCH    4
#define ICMPTYPE_REDIRECT     5
#define ICMPTYPE_ECHO_REQ     8
#define ICMPTYPE_TIMEEXCEED   11
#define ICMPTYPE_PARMPROB     12
#define ICMPTYPE_TIME_REQ     13
#define ICMPTYPE_TIME_REPLY   14
#define ICMPTYPE_INFO_REQ     15    /* obsolete */
#define ICMPTYPE_INFO_REPLY   16    /* obsolete */
#define ICMPTYPE_AM_REQ       17
#define ICMPTYPE_AM_REPLY     18

/*
** Destination Unreachable codes
*/
#define ICMPCODE_DU_NET_UNREACH     0
#define ICMPCODE_DU_HOST_UNREACH    1
#define ICMPCODE_DU_PROTO_UNREACH   2
#define ICMPCODE_DU_PORT_UNREACH    3
#define ICMPCODE_DU_NEEDFRAG        4
#define ICMPCODE_DU_SRCROUTE        5
#define ICMPCODE_DU_NET_UNKNOWN     6
#define ICMPCODE_DU_HOST_UNKNOWN    7
#define ICMPCODE_DU_HOST_ISOLATED   8
#define ICMPCODE_DU_NET_PROHIB      9
#define ICMPCODE_DU_HOST_PROHIB     10
#define ICMPCODE_DU_NET_TOS         11
#define ICMPCODE_DU_HOST_TOS        12

/*
** Redirect codes
*/
#define ICMPCODE_RD_NET             0
#define ICMPCODE_RD_HOST            1
#define ICMPCODE_RD_NET_TOS         2
#define ICMPCODE_RD_HOST_TOS        3

/*
** Time Exceeded codes
*/
#define ICMPCODE_TE_TTL             0
#define ICMPCODE_TE_REASM           1


/***************************************
**
** Type definitions
**
*/

/*
** ICMP echo parameters
*/

typedef struct icmp_parm
{
    TCPIP_PARM                      COMMON;
    struct icmp_parm _PTR_          NEXT;
    struct icmp_parm _PTR_ _PTR_    PREV;
    TCPIP_EVENT                     EXPIRE;
    _ip_address                     ipaddress;
    uint_32                         timeout;
    uint_16                         id;
    uint_16                         seq;
    uint_8                          hop_limit;          /* Hop limit orr TTL.*/ 
    pointer                         data_buffer;        /* Pointer to a data buffer (optional). */
    uint_32                         data_buffer_size;   /* Size of a buffer (optional).    */
} ICMP_PARM, _PTR_ ICMP_PARM_PTR;


/***************************************
**
** Prototypes
**
*/

extern uint_32 ICMP_init
(
   void
);

extern void ICMP_send_echo
(
   ICMP_PARM_PTR
);

extern void ICMP_send_error
(
   uint_8         type,    /* [IN] the type to send */
   uint_8         code,    /* [IN] the code to send */
   uint_32        param,   /* [IN] the icmp parameter */
   RTCSPCB_PTR    pcb,     /* [IN] the packet which caused the error */
   int_32         layer    /* [IN] IP layer, relative to current */
);

extern void ICMP_service
(
   RTCSPCB_PTR,
   pointer
);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_mat1.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_mat1.c$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*   This file contains the math functions.
*
*END************************************************************************/

#include "mqx_inc.h"


/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_mul_128_by_32
* Returned Value   : uint_32 - overflow
* Comments         :
*    This function multiplies a 128 bit quantity by a 32 bit quantity and 
* stores the result in a 128 bit quantity
*
*END*----------------------------------------------------------------------*/

uint_32 _psp_mul_128_by_32
   (
      /* 
      ** [IN] Pointer to a 4 long word array in which the value to be multiplied
      ** is stored 
      */
      PSP_128_BIT_UNION_PTR   m_ptr,

      /* [IN] The multiplier */
      uint_32                 mul,

      /* [OUT] Pointer to a 4 long word array where the result will be stored */
      PSP_128_BIT_UNION_PTR   r_ptr

   )
{ /* Body */
   PSP_128_BIT_UNION tmp;
   uint_64           w,r;
   uint_32           w0;
   _mqx_uint         i;

#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
   tmp.LLW[0] = 0;
   r = 0;
   if (!mul || (!m_ptr->LLW[0] && !m_ptr->LLW[1])) {
      tmp.LLW[1] = 0;
   } else if (mul == 1) {
      *r_ptr = *m_ptr;
      return r;
   } else {
      for ( i = 0; i < 3; i++ ) {
         w  = (uint_64)mul * (uint_64)m_ptr->LW[i];
         w0 = (uint_32)w;
         tmp.LW[i] += w0;
         tmp.LW[i+1] = (w >> 32) + (tmp.LW[i] < w0);
      } /* Endfor */

      w = (uint_64)mul * (uint_64)m_ptr->LW[3];
      w0 = (uint_32)w;
      tmp.LW[3] += w0;
      r = (w >> 32) + (tmp.LW[3] < w0);
   } /* Endif */
   
   *r_ptr = tmp;
   return r;
#else
   tmp.LLW[1] = 0;
   r = 0;
   if (!mul || (!m_ptr->LLW[0] && !m_ptr->LLW[1])) {
      tmp.LLW[0] = 0;
   } else if (mul == 1) {
      *r_ptr = *m_ptr;
      return r;
   } else {
      for ( i = 3; i > 0; i-- ) {
         w  = (uint_64)mul * (uint_64)m_ptr->LW[i];
         w0 = (uint_32)w;
         tmp.LW[i] += w0;
         tmp.LW[i-1] = (w >> 32) + (tmp.LW[i] < w0);
      } /* Endfor */

      w = (uint_64)mul * (uint_64)m_ptr->LW[0];
      w0 = (uint_32)w;
      tmp.LW[0] += w0;
      r = (w >> 32) + (tmp.LW[0] < w0);
   } /* Endif */
   
   *r_ptr = tmp;
   return r;
#endif

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/hmi_tss_provider.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hmi_tss_provider.c$
* $Version : 3.8.2.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This contains functions for TSS provider.
*
*END************************************************************************/
#include "mqx.h"
#include "bsp.h"
#include "hmi_tss_provider.h"
#include "btnled.h"
#include "TSS_API.h"

#define HMI_TSS_OFFSET_ELECTRODES   ((TSS_N_ELECTRODES/8)+1)

/* Functions prototypes */
static void hmi_tss_attach_client(HMI_PROVIDER_STRUCT_PTR , HMI_CLIENT_STRUCT_PTR );
static void hmi_tss_poll(HMI_PROVIDER_STRUCT_PTR );
static void tss_add_element(const HMI_TSS_INIT_STRUCT _PTR_ , HMI_TSS_INIT_STRUCT_PTR );
static HMI_TSS_CONTEXT_STRUCT_PTR hmi_tss_provider_init(const HMI_TSS_INIT_STRUCT _PTR_ , HMI_PROVIDER_STRUCT_PTR _PTR_ );
static boolean hmi_tss_get_value(HMI_PROVIDER_STRUCT_PTR, uint_32, uint_32_ptr);
static void hmi_tss_set_electrodes(uint_8, boolean);
void hmi_tss_keypad_callback(TSS_CONTROL_ID);
void hmi_tss_rotary_callback(TSS_CONTROL_ID);
void hmi_tss_slider_callback(TSS_CONTROL_ID);

/* TSS functions prototypes (TSS library) */
pointer TSS_GetControlPrivateData(uint_8);
uint_8  TSS_GetControlFirstElectrodeIndex(uint_8);
uint_8  TSS_GetControlLastElectrodeIndex(uint_8);
uint_8  TSS_GetControlElectrodeNumber(uint_8);
void    TSS_SetControlPrivateData(uint_8, pointer);
uint_16 TSS_GetSystemConfig(uint_8);
uint_8  TSS_SetSystemConfig(uint_8, uint_16);
uint_8  TSS_SetSliderConfig(TSS_CONTROL_ID, uint_8, uint_8);
uint_8  TSS_SetKeypadConfig(TSS_CONTROL_ID, uint_8, uint_8);
uint_8 _PTR_ TSS_GetControlStruct(uint_8);

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_keypad_callback
* Returned Value   : void
* Comments         :
*   This function is callback for TSS buttons.
*
*END*--------------------------------------------------------------------*/
void hmi_tss_keypad_callback(TSS_CONTROL_ID u8ControlId)
{    /* get provider structure from TSS private data */
    HMI_PROVIDER_STRUCT_PTR     provider_struct = (HMI_PROVIDER_STRUCT_PTR)TSS_GetControlPrivateData(u8ControlId.ControlNumber);    
    /* get context data */
    HMI_TSS_CONTEXT_STRUCT_PTR  context_struct = (HMI_TSS_CONTEXT_STRUCT_PTR)provider_struct->CONTEXT_PTR;                            
    /* get keypad structure pointer */
    TSS_CSKeypad _PTR_          keypad_structure = ((TSS_CSKeypad *)TSS_GetControlStruct(context_struct->CONTROL_NUMBER));            
    uint_8                      u8Event;    /* 8 bits local variable used to store the event information */                                                                                            
    uint_8                      flag;       /* push / release flag */

    /* check if client is attached to provider */
    if (context_struct == NULL || context_struct->CLIENT_HANDLE == NULL)        
    {
        return;
    }
    /* While unread events are in the buffer */
    while (!TSS_KEYPAD_BUFFER_EMPTY(_PTR_ keypad_structure))          
    {
        /* Read the buffer and store the event in the u8Event variable */
        TSS_KEYPAD_BUFFER_READ(u8Event, _PTR_ keypad_structure);     
        
        if (u8Event & TSS_KEYPAD_BUFFER_RELEASE_FLAG)
        {
            u8Event = (uint_8)(u8Event & TSS_KEYPAD_BUFFER_KEY_MASK);    /* Get key index */
            flag = HMI_VALUE_RELEASE; 
        }
        else
        {
            flag = HMI_VALUE_PUSH;
        }
        /* check if key index is registered in provider */
        if (u8Event >= context_struct->TSS_COUNT)
        {
            return;
        }
        context_struct->CLIENT_HANDLE->ON_CHANGE(context_struct->CLIENT_HANDLE, context_struct->TSS_TABLE[u8Event].UID, flag);
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_rotary_callback
* Returned Value   : void
* Comments         :
*   This function is rotary callback.
*
*
*END*--------------------------------------------------------------------*/
void hmi_tss_rotary_callback(TSS_CONTROL_ID u8ControlId)
{    /* get provider structure from TSS private data */
    HMI_PROVIDER_STRUCT_PTR     provider_struct = (HMI_PROVIDER_STRUCT_PTR)TSS_GetControlPrivateData(u8ControlId.ControlNumber);    
     /* get context data */
    HMI_TSS_CONTEXT_STRUCT_PTR  context_struct = (HMI_TSS_CONTEXT_STRUCT_PTR) provider_struct->CONTEXT_PTR;

    /* check if client is attached to provider */
    if (context_struct == NULL || context_struct->CLIENT_HANDLE == NULL)        
    {
        return;
    }
    
    if ((*(TSS_CSRotary *)TSS_GetControlStruct(context_struct->CONTROL_NUMBER)).DynamicStatus.Movement)
    {
        context_struct->CLIENT_HANDLE->ON_CHANGE(context_struct->CLIENT_HANDLE, context_struct->TSS_TABLE[0].UID, HMI_VALUE_MOVEMENT);    
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_slider_callback
* Returned Value   : void
* Comments         :
*   This function is slider callback.
*
*END*--------------------------------------------------------------------*/
void hmi_tss_slider_callback(TSS_CONTROL_ID u8ControlId)
{    /* get provider struct from TSS private data */
    HMI_PROVIDER_STRUCT_PTR     provider_struct = (HMI_PROVIDER_STRUCT_PTR)TSS_GetControlPrivateData(u8ControlId.ControlNumber);    
    /* get context data */
    HMI_TSS_CONTEXT_STRUCT_PTR  context_struct = (HMI_TSS_CONTEXT_STRUCT_PTR) provider_struct->CONTEXT_PTR;
    
    /* check if client is attached to provider */
    if (context_struct == NULL || context_struct->CLIENT_HANDLE == NULL)        
    {
        return;
    }
    
    if ((*(TSS_CSSlider *)TSS_GetControlStruct(context_struct->CONTROL_NUMBER)).DynamicStatus.Movement)
    {
        context_struct->CLIENT_HANDLE->ON_CHANGE(context_struct->CLIENT_HANDLE, context_struct->TSS_TABLE[0].UID, HMI_VALUE_MOVEMENT);
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_get_value
* Returned Value   : boolean
* Comments         :
*   This function gets value of requested TSS element.
*
*END*--------------------------------------------------------------------*/
static boolean hmi_tss_get_value(HMI_PROVIDER_STRUCT_PTR provider_struct, uint_32 uid, uint_32_ptr value)
{    /* get context structure */
    HMI_TSS_CONTEXT_STRUCT_PTR  context_struct = (HMI_TSS_CONTEXT_STRUCT_PTR) provider_struct->CONTEXT_PTR;    

    uint_8      i;
    boolean     result = FALSE;
    uint_8      electrodes_status;
    uint_8      electrode_index;
    /* get TSS control structure */
    uint_8_ptr     tss_control_struct_ptr = (uint_8_ptr)TSS_GetControlStruct(context_struct->CONTROL_NUMBER);

    if (tss_control_struct_ptr == NULL || context_struct == NULL)
    {
        return result;
    }
    if ((((TSS_CSRotary *)tss_control_struct_ptr)->ControlId.ControlType) == TSS_CT_ROTARY)        /* rotary */
    {
        if (context_struct->TSS_TABLE[0].UID == uid)
        {
            *value = (*(TSS_CSRotary *)tss_control_struct_ptr).StaticStatus.Position;            /* actual absolute position */
            result = TRUE;
        }
    }
    else if ((((TSS_CSSlider *)tss_control_struct_ptr)->ControlId.ControlType) == TSS_CT_SLIDER)    /* slider */
    {
        if (context_struct->TSS_TABLE[0].UID == uid)
        {
            *value = (*(TSS_CSSlider *)tss_control_struct_ptr).StaticStatus.Position;            /* actual absolute position */
            result = TRUE;
        }
    }
    else if ((((TSS_CSKeypad *)tss_control_struct_ptr)->ControlId.ControlType) == TSS_CT_KEYPAD)    /* keypad */
    {
        for (i=0; i<context_struct->TSS_COUNT; i++)
        {
            if (context_struct->TSS_TABLE[i].UID == uid)
            {
                /* get index */
                electrode_index = (TSS_GetControlFirstElectrodeIndex(context_struct->CONTROL_NUMBER) + i);            
                /* electrodes status */    
                electrodes_status = TSS_GetSystemConfig(System_ElectrodeStatus_Register + (electrode_index/8u));    
                /* status of requested electrode */
                *value = (uint_32)(electrodes_status >> (electrode_index % 8u)) & 0x1;                                        
                result = TRUE;
                break;
            }
        }
    }
    return result;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : TSS_fOnFault
* Returned Value   : void
* Comments         :
*   This function clears the fault flag of an electrode if fault was detected.
*   User can add his action if fault occurs.
*END*--------------------------------------------------------------------*/
void hmi_tss_on_fault(uint_8 electrode_number)
{

    /* If fault occurs, electrode is re-enabled here */
    if(tss_CSSys.Faults.ChargeTimeout || tss_CSSys.Faults.SmallCapacitor)    /* if large or small capacitor fault  */
    {
        /* clear the fault flag */
        (void) TSS_SetSystemConfig(System_Faults_Register, 0x00); 

    /* User can write code here when faul is detected */        
    }
    
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_attach_client
* Returned Value   : void
* Comments         :
*    This function attaches client to provider.
*
*END*--------------------------------------------------------------------*/
static void hmi_tss_attach_client(HMI_PROVIDER_STRUCT_PTR provider_struct, HMI_CLIENT_STRUCT_PTR client_struct)
{
    HMI_TSS_CONTEXT_STRUCT_PTR context = (HMI_TSS_CONTEXT_STRUCT_PTR)provider_struct->CONTEXT_PTR;
    
    context->CLIENT_HANDLE = client_struct;        /* attach client to provider */
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_poll
* Returned Value   : void
* Comments         :
*   This function calls TSS task.
*
*END*--------------------------------------------------------------------*/
static void hmi_tss_poll(HMI_PROVIDER_STRUCT_PTR provider_struct)
{
    while (TSS_Task() != TSS_STATUS_OK)        /* TSS Task */
    {
        
    }    
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : tss_add_element
* Returned Value   : void
* Comments         :
*   This function adds TSS element.
*
*END*--------------------------------------------------------------------*/
static void tss_add_element(const HMI_TSS_INIT_STRUCT _PTR_ init_table, HMI_TSS_INIT_STRUCT_PTR tss_struct)
{
    /* saves data from init table to init structure */
    tss_struct->UID = init_table->UID;        
    tss_struct->FLAG = init_table->FLAG;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_init
* Returned Value   : void
* Comments         :
*   This function initializes TSS.
*
*END*--------------------------------------------------------------------*/
void hmi_tss_init(const HMI_TSS_SYSTEM_CONTROL_STRUCT system_control)
{
    uint_8  i;
    
    TSS_Init();                         /* TSS initialize */
    
    for (i=0; i<TSS_N_ELECTRODES; i++)    
    {
        (void)TSS_SetSystemConfig(System_Sensitivity_Register + i, system_control.SENSITIVITY_VALUES[i]);    /* set sensitivity values */
    }
    (void)TSS_SetSystemConfig(System_NSamples_Register, system_control.NUMBER_OF_SAMPLES);                   /* set number of samples */
    (void)TSS_SetSystemConfig(System_SystemTrigger_Register, system_control.SYSTEM_TRIGGER);                 /* TSS system trigger */
    (void)TSS_SetSystemConfig(System_AutoTriggerModuloValue_Register, 0xFF);                                 /* set auto trigger modulo value */
    (void)TSS_SetSystemConfig(System_SystemConfig_Register, system_control.SYSTEM_CONFIG);                   /* set system config */
        
    for(i=0; i<HMI_TSS_OFFSET_ELECTRODES; i++)
    {
        TSS_SetSystemConfig(System_ElectrodeEnablers_Register + i, 0x00);                                    /* disable all electrodes */
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_provider_init
* Returned Value   : void
* Comments         :
*   This function allocates provider .
*
*END*--------------------------------------------------------------------*/
static HMI_TSS_CONTEXT_STRUCT_PTR hmi_tss_provider_init(const HMI_TSS_INIT_STRUCT _PTR_ init_table, HMI_PROVIDER_STRUCT_PTR _PTR_ provider_struct)
{
    uint_8                         i=0;
    HMI_TSS_CONTEXT_STRUCT_PTR     context_struct;
    
     /* allocate provider structure */
    _PTR_ provider_struct = _mem_alloc_system(sizeof(HMI_PROVIDER_STRUCT));        
    if(provider_struct == NULL)
    {
        return NULL;
    }
    /* allocate providers context structure */
    context_struct = _mem_alloc_system(sizeof(HMI_TSS_CONTEXT_STRUCT));            
    if(context_struct == NULL)
    {
        _mem_free(provider_struct);
        return NULL;
    }
    
    while(init_table[i].UID != 0)
    {
        i++;
    }
    /* number of  tss provider elements */
    context_struct->TSS_COUNT = i;                    
    /* allocate providers table */
    context_struct->TSS_TABLE = _mem_alloc_system_zero(sizeof(HMI_TSS_INIT_STRUCT)*(i));    
    if (context_struct->TSS_TABLE == NULL)
    {
        _mem_free(provider_struct);
        _mem_free(context_struct);
        return NULL;
    }
    i=0;
    while(init_table[i].UID != 0)
    {
        tss_add_element(&init_table[i], &context_struct->TSS_TABLE[i]);            /* Add TSS element */
        i++;
    }
    
    return context_struct;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_set_electrodes
* Returned Value   : void
* Comments         :
*   This function enables/disables electrodes.
*
*END*--------------------------------------------------------------------*/
static void hmi_tss_set_electrodes(uint_8 control_number, boolean enable_electrodes)
{
    uint_8  i;
    uint_8  offset;
    uint_8  result;
    uint_8  first_electrode;
    uint_8  last_electrode;

    /* first electrode for a control */
    first_electrode = TSS_GetControlFirstElectrodeIndex(control_number);
    /* last electrode for a control */
    last_electrode = TSS_GetControlLastElectrodeIndex(control_number);
    /* get offset in which first electrode is */
    offset = first_electrode/8;                                                
    /* get for this offset electrodes en/dis status */
    result = TSS_GetSystemConfig(System_ElectrodeEnablers_Register + offset);    
    
    for (i=first_electrode; i<=last_electrode; i++)
    {
        if (enable_electrodes)
        {
            result |= 1 << (i%8);        /* enable electrode */
        }
        else
        {
            result &= ~(1 << (i%8));    /* disable electrode */
        }
        if (((i+1)%8) == 0)
        {
            (void)TSS_SetSystemConfig(System_ElectrodeEnablers_Register + offset, result);    /* store enable config */
            offset++;
            result = TSS_GetSystemConfig(System_ElectrodeEnablers_Register + offset);        /* get en/dis status */        
        }
    }
    if ((i%8) != 0)
    {
        (void)TSS_SetSystemConfig(System_ElectrodeEnablers_Register + offset, result);        /* store rest of enable config */
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_keypad_provider_init
* Returned Value   : HMI_PROVIDER_STRUCT_PTR
* Comments         :
*   This function initializes TSS provider.
*
*
*END*--------------------------------------------------------------------*/
HMI_PROVIDER_STRUCT_PTR hmi_tss_keypad_provider_init(const HMI_TSS_INIT_STRUCT _PTR_  init_table, uint_8 control_number)
{
    HMI_PROVIDER_STRUCT_PTR         provider_struct;
    HMI_TSS_CONTEXT_STRUCT_PTR      context_struct;
    uint_8_ptr                      tss_control_struct_ptr = (uint_8_ptr)TSS_GetControlStruct(control_number);

    /* allocate memory and add tss elements */
    context_struct = hmi_tss_provider_init(init_table, &provider_struct);        
    /* enable electrodes */
    hmi_tss_set_electrodes(control_number, TRUE);                                
    /* store TSS control number in the context structure */
    context_struct->CONTROL_NUMBER = control_number;                            
    context_struct->CLIENT_HANDLE = NULL;    
    provider_struct->GET_VALUE_PTR = (boolean(_CODE_PTR_)(pointer, uint_32, uint_32_ptr))hmi_tss_get_value;        /* provider structure function pointers */
    provider_struct->INSTALL_INTERRUPT_PTR = NULL;
    provider_struct->ATTACH_CLIENT =(void(_CODE_PTR_)(pointer, pointer ))hmi_tss_attach_client;
    provider_struct->POLL_PTR =(void (_CODE_PTR_ )(pointer))hmi_tss_poll;
    provider_struct->SET_VALUE_PTR = NULL;
    provider_struct->UNINSTALL_INTERRUPT_PTR = NULL;
    provider_struct->CONTEXT_PTR = context_struct;
    
    (void)TSS_SetKeypadConfig(((TSS_CSKeypad *)tss_control_struct_ptr)->ControlId, Keypad_Events_Register, (TSS_KEYPAD_TOUCH_EVENT_EN_MASK | TSS_KEYPAD_RELEASE_EVENT_EN_MASK));
    (void)TSS_SetKeypadConfig(((TSS_CSKeypad *)tss_control_struct_ptr)->ControlId, Keypad_ControlConfig_Register, (TSS_KEYPAD_CALLBACK_EN_MASK | TSS_KEYPAD_CONTROL_EN_MASK));
    TSS_SetControlPrivateData(control_number, provider_struct);        /* set private data in TSS */
    
    return provider_struct;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_rotary_provider_init
* Returned Value   : HMI_PROVIDER_STRUCT_PTR
* Comments         :
*   This function initializes TSS provider.
*
*
*END*--------------------------------------------------------------------*/
HMI_PROVIDER_STRUCT_PTR hmi_tss_rotary_provider_init(const HMI_TSS_INIT_STRUCT _PTR_  init_table, uint_8 control_number)
{
    HMI_PROVIDER_STRUCT_PTR         provider_struct;
    HMI_TSS_CONTEXT_STRUCT_PTR      context_struct;
    uint_8_ptr                      tss_control_struct_ptr = (uint_8_ptr)TSS_GetControlStruct(control_number);

    /* allocate memory and add tss elements */
    context_struct = hmi_tss_provider_init(init_table, &provider_struct);            
    /* enable electrodes */
    hmi_tss_set_electrodes(control_number, TRUE);                                
    /* store TSS control number in the context structure */
    context_struct->CONTROL_NUMBER = control_number;                            
    context_struct->CLIENT_HANDLE = NULL;
    /* provider structure function pointers */
    provider_struct->GET_VALUE_PTR =  (boolean(_CODE_PTR_)(pointer, uint_32, uint_32_ptr))hmi_tss_get_value;        
    provider_struct->INSTALL_INTERRUPT_PTR = NULL;
    provider_struct->ATTACH_CLIENT = (void(_CODE_PTR_)(pointer, pointer ))hmi_tss_attach_client;
    provider_struct->POLL_PTR = (void (_CODE_PTR_ )(pointer))hmi_tss_poll;
    provider_struct->SET_VALUE_PTR = NULL;
    provider_struct->UNINSTALL_INTERRUPT_PTR = NULL;
    provider_struct->CONTEXT_PTR = context_struct;
    
    (void)TSS_SetRotaryConfig(((TSS_CSRotary *)tss_control_struct_ptr)->ControlId, Rotary_Events_Register, (TSS_ROTARY_MOVEMENT_EVENT_EN_MASK | TSS_ROTARY_INITIAL_TOUCH_EVENT_EN_MASK));
    (void)TSS_SetRotaryConfig(((TSS_CSRotary *)tss_control_struct_ptr)->ControlId, Rotary_ControlConfig_Register, (TSS_ROTARY_CONTROL_EN_MASK | TSS_ROTARY_CALLBACK_EN_MASK));
    TSS_SetControlPrivateData(control_number, provider_struct);        /* set private data in TSS */
    
    return provider_struct;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_slider_provider_init
* Returned Value   : HMI_PROVIDER_STRUCT_PTR
* Comments         :
*   This function initializes TSS provider.
*
*
*END*--------------------------------------------------------------------*/
HMI_PROVIDER_STRUCT_PTR hmi_tss_slider_provider_init(const HMI_TSS_INIT_STRUCT _PTR_ init_table, uint_8 control_number)
{
    HMI_PROVIDER_STRUCT_PTR         provider_struct;
    HMI_TSS_CONTEXT_STRUCT_PTR      context_struct;
    uint_8_ptr                      tss_control_struct_ptr = (uint_8_ptr)TSS_GetControlStruct(control_number);

    /* allocate memory and add tss elements */
    context_struct = hmi_tss_provider_init(init_table,&provider_struct);    
    /* enable electrodes */
    hmi_tss_set_electrodes(control_number, TRUE);                            
    /* store TSS control number in the context structure */
    context_struct->CONTROL_NUMBER = control_number;                            
    context_struct->CLIENT_HANDLE = NULL;
    /* provider structure function pointers */
    provider_struct->GET_VALUE_PTR =  (boolean(_CODE_PTR_)(pointer, uint_32, uint_32_ptr))hmi_tss_get_value;
    provider_struct->INSTALL_INTERRUPT_PTR = NULL;
    provider_struct->ATTACH_CLIENT = (void(_CODE_PTR_)(pointer, pointer ))hmi_tss_attach_client;
    provider_struct->POLL_PTR = (void (_CODE_PTR_ )(pointer))hmi_tss_poll;
    provider_struct->SET_VALUE_PTR = NULL;
    provider_struct->UNINSTALL_INTERRUPT_PTR = NULL;
    provider_struct->CONTEXT_PTR = context_struct;
    
    (void)TSS_SetSliderConfig(((TSS_CSSlider *)tss_control_struct_ptr)->ControlId, Slider_Events_Register, (TSS_SLIDER_MOVEMENT_EVENT_EN_MASK | TSS_SLIDER_INITIAL_TOUCH_EVENT_EN_MASK));
    (void)TSS_SetSliderConfig(((TSS_CSSlider *)tss_control_struct_ptr)->ControlId, Slider_ControlConfig_Register, (TSS_SLIDER_CONTROL_EN_MASK | TSS_SLIDER_CALLBACK_EN_MASK));
    TSS_SetControlPrivateData(control_number, provider_struct);        /* set private data in TSS */
    
    return provider_struct;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : _hmi_tss_provider_deinit
* Returned Value   : uint_32
* Comments         :
*   This function deallocates all resources and disables provider electrodes.
*
*END*--------------------------------------------------------------------*/
uint_32 hmi_tss_provider_deinit(HMI_PROVIDER_STRUCT_PTR provider)
{
    uint_32 result = MQX_OK;
    HMI_TSS_CONTEXT_STRUCT_PTR context_struct = (HMI_TSS_CONTEXT_STRUCT_PTR) (provider)->CONTEXT_PTR;
    
    /* disable providers electrodes */
    hmi_tss_set_electrodes(context_struct->CONTROL_NUMBER, FALSE);            
    result = _mem_free(context_struct->TSS_TABLE);
    if(result != MQX_OK)
    {
        return result;
    }
    result = _mem_free(provider->CONTEXT_PTR);
    if(result != MQX_OK)
    {
        return result;
    }
    provider = NULL;

    return result;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_tss_empty_function
* Returned Value   :
* Comments         :
*   Function definition for TSS_SystemSetup.h .
*
*END*--------------------------------------------------------------------*/
void hmi_tss_empty_function(void)
{
    /* TSS On init ,replaced with _bsp_hmi_init() */
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/ftpc_cmd.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpc_cmd.c$
* $Version : 3.8.6.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <rtcs.h>
#include <fio.h>
#include "ftpc.h"

               
               
               
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_help
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_help(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] ) 
{
   uint_32               i;
   
   for (i=0; FTPc_commands[i].COMMAND != NULL; i++)   {
      printf("%-10s ", FTPc_commands[i].COMMAND);
      if ((i%6)==5) printf("\n");        
   } /* Endwhile */        
   if ((i%6)!=0) printf("\n");        

   return 0;
}
                 
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_ascii
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_ascii(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc != 1) {
      printf("Usage: ascii\n");
   } else {
      response = FTP_command(context_ptr->HANDLE,"TYPE A\r\n",stdout);
   }
   
   return response;
}
              
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_binary
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_binary(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc != 1) {
      printf("Usage: binary\n");
   } else {
      response = FTP_command(context_ptr->HANDLE,"TYPE I\r\n",stdout);
   }
   
   return response;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_bye
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_bye(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE != NULL)  {
      response = FTP_close(context_ptr->HANDLE,stdout);
      context_ptr->HANDLE = NULL;
      context_ptr->HOSTADDR = 0;
   }
   context_ptr->EXIT=TRUE; 
   
   return response;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_cd
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_cd(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc > 2) {
      printf("Usage: cd <directory>\n");
   } else  {
      sprintf(context_ptr->BUFFER,"CWD %s\r\n", (argc > 1)?argv[1]:"" );
      response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);
   }
   
   return response;
}
         
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_close
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_close(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc != 1) {
      printf("Usage: close\n");
   } else {
      response = FTP_close(context_ptr->HANDLE, stdout);
      context_ptr->HANDLE = NULL;
      context_ptr->HOSTADDR = 0;
   }
   
   return response;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_delete
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_delete(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
               
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc != 2) {
      printf("Usage: delete <filename>\n");
   } else {
      sprintf(context_ptr->BUFFER,"DELE %s\r\n", context_ptr->ARGV[1] );
      response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);
   }
   
   return response;
}
            

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_get
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_get(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32      response=0;
   MQX_FILE_PTR fd;
      
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc < 2) {
      printf("Usage: get <remotename> [<localname>]\n");
   } else  {
      if (argc == 3) {
         fd = fopen(argv[2], "w");
      } else  {
         fd = fopen(argv[1], "w");
      }
      if (!fd)  {
         printf("Unable to open local file: %s\n",argv[1]);
      } else {
         sprintf(context_ptr->BUFFER,"RETR %s\r\n", argv[1] );
         response = FTP_command_data(context_ptr->HANDLE, context_ptr->BUFFER, stdout, fd, FTPMODE_PORT | FTPDIR_RECV);
         fclose(fd);
      }
   }
   
   return response;
}
         
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_ls
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_ls(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc > 2) {
      printf("Usage: ls <filespec>\n");
   } else  {
      sprintf(context_ptr->BUFFER,"LIST %s\r\n", (argc > 1)?argv[1]:"" );
      response = FTP_command_data(context_ptr->HANDLE,context_ptr->BUFFER,stdout,stdout, FTPMODE_PORT | FTPDIR_RECV);
   }
   
   return response;
}
         
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_mkdir
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_mkdir(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc != 2) {
      printf("Usage: mkdir <dir>\n");
   } else  {
      sprintf(context_ptr->BUFFER,"MKD %s\r\n", argv[1] );
      response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);
   }
   
   return response;
}
         
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_open
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_open(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (argc != 2)  {
      printf("Usage: open <host>\n");
   } else if (context_ptr->HANDLE != NULL) {
      printf("Already connected to %s. Use close first.\n",context_ptr->HOSTNAME);
   } else {
               
      RTCS_resolve_ip_address( argv[1], &context_ptr->HOSTADDR, context_ptr->HOSTNAME, RTCS_SNAME_LEN ); 

      if (!context_ptr->HOSTADDR)  {
         printf("Unable to resolve host.\n");
      } else  {
         printf("Connecting to: %s [%ld.%ld.%ld.%ld]\n",
               context_ptr->HOSTNAME, IPBYTES(context_ptr->HOSTADDR));
   
         response = FTP_open(&context_ptr->HANDLE,context_ptr->HOSTADDR,stdout);
         if (response == RTCS_ERROR)  {
            printf("Unable to open %s\n",context_ptr->HOSTNAME);
            response = 0;
            context_ptr->HOSTADDR = 0;
            context_ptr->HANDLE = NULL;   
         }
      }
   }
   
   return response;
}
            
               
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_pass
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_pass(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32   response=0;
   char_ptr param_ptr;
   char     string[64];
   
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc > 2) {
      printf("Usage: pass <password>\n");
   } else  {
      if (argc == 1) {
         printf("Password: ");
         if (!fgets(string, sizeof(string), stdin)) {
            context_ptr->EXIT = TRUE;
            return 0;
         }
         param_ptr = string;
      } else  {
         param_ptr = argv[1];
      }
      sprintf(context_ptr->BUFFER,"PASS %s\r\n", param_ptr );
      response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);
      printf("response = %d\n", response );
   }
   
   return response;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_put
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_put(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32      response=0;
   MQX_FILE_PTR fd;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if ((argc<2) || (argc>3)) {
      printf("Usage: put <local filename> [<remote filename>]\n");
   } else {
      fd = fopen(argv[1],"r");
      if (!fd)  {
         printf("Unable to open local file: %s\n",argv[1]);
      } else  {
         sprintf(context_ptr->BUFFER,"STOR %s\r\n", (argc==2)?argv[1]:argv[2] );
         response = FTP_command_data(context_ptr->HANDLE,context_ptr->BUFFER,stdout, fd, FTPMODE_PORT | FTPDIR_SEND);
         fclose(fd);
      }
   }
   
   return response;
}
         
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_pwd
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_pwd(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc != 1) {
      printf("Usage: pwd\n");
   } else {
      response = FTP_command(context_ptr->HANDLE,"PWD \r\n",stdout);
   }
   
   return response;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_remotehelp
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_remotehelp(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32      response=0;
   char_ptr    param_ptr;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc > 2 ) {
      printf("Usage: remotehelp <command>\n");
   } else {
      if (argc == 1) {
         param_ptr = "";
      } else  {
         param_ptr = argv[1];
      }

      sprintf(context_ptr->BUFFER,"HELP %s\r\n", param_ptr );
      response = FTP_command_data(context_ptr->HANDLE,context_ptr->BUFFER,
         stdout, stdin, FTPMODE_PORT | FTPDIR_RECV );
   }
   
   return response;
}
         
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_rename
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_rename(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc != 3) {
      printf("Usage: rename <oldname> <newname>\n");
   } else  {
      sprintf(context_ptr->BUFFER,"RNFR %s\r\n", argv[1] );
      response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);

      if ((response >= 300) && (response < 400))  {
         sprintf(context_ptr->BUFFER,"RNTO %s\r\n", argv[2] );
         response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);
      }
   }
   
   return response;
}
               
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_rmdir
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_rmdir(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32    response=0;
   
   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc != 2) {
      printf("Usage: rmdir <dir>\n");
   } else  {
      sprintf(context_ptr->BUFFER,"RMD %s\r\n", argv[1] );
      response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);
   }
   
   return response;
}
         
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   FTPc_user
* Returned Value   :  int_32 error code
* Comments  : 
*
* Usage:  
*
*END*---------------------------------------------------------------------*/

int_32  FTPc_user(FTPc_CONTEXT_PTR context_ptr, int_32 argc, char_ptr argv[] )
{
   int_32   response = 0;
   char_ptr param_ptr = NULL;
   char     string[64];

   if (context_ptr->HANDLE == NULL)  {
      printf("Not connected.\n");
   } else if (argc > 2) {
      printf("Usage: user <username>\n");
   } else if (argc == 1) {
      printf("User: ");
      if (!fgets(string, sizeof(string), stdin)) {
         context_ptr->EXIT = TRUE;
      } else {
        param_ptr = string;
      }
   } else  {
      param_ptr = argv[1];
   }

   if (param_ptr != NULL) {
      sprintf(context_ptr->BUFFER,"USER %s\r\n", param_ptr );
      response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);

      if ((response >= 300) && (response < 400))  {
         printf("Password: " );
         // call ioctl to echo off
         if (!fgets(string, sizeof(string), stdin)) {
            context_ptr->EXIT = TRUE;
            response = 0;
         } else {
            // call ioctl to echo on
            sprintf(context_ptr->BUFFER,"PASS %s\r\n", string);
            response = FTP_command(context_ptr->HANDLE,context_ptr->BUFFER,stdout);
         }
      }
   }

   return response;
}

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/iopcbprv.h<|end_filename|>
#ifndef __iopcbprv_h__
#define __iopcbprv_h__ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iopcbprv.h$
* $Version : 3.8.5.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This include file is used to provide private definitions for the
*   io pcb package.
*
*END************************************************************************/

#include <partition.h>

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/* PCB Definitions */
#define IO_PCB_VALID ((_mqx_uint)(0x69706362))   /* "ipcb" */


/*--------------------------------------------------------------------------*/
/*
**                            MACRO DEFINITIONS
*/

#define IO_PCB_CREATE_POOL_ID(ptr) (_io_pcb_pool_id)((uchar_ptr)(ptr)-1)

#define IO_PCB_GET_POOL_PTR(id) (IO_PCB_POOL_STRUCT_PTR)((uchar_ptr)(id)+1)

/*--------------------------------------------------------------------------*/
/*
**                            DATATYPES
*/

/* 
** IO PCB POOL STRUCT
** This structure defines what a pcb pool structure contains.
*/
typedef struct io_pcb_pool_struct
{
   /* queue element for queueing */
   QUEUE_ELEMENT_STRUCT          QUEUE;

   /* Validity field */
   _mqx_uint                     VALID;

   /* Number of fragments */
   _mqx_uint                     NUM_FRAGS;
   
   /* Size of extra data */
   _mem_size                     EXTRA_DATA_SIZE;

   /* The function to call when a pcb is allocated */
   IO_PCB_STRUCT_PTR (_CODE_PTR_ PCB_ALLOC_FUNCTION_PTR)
      (IO_PCB_STRUCT_PTR, pointer);
   
   /* An additional pointer to pass to the allocation function */
   pointer                       ALLOC_FUNCTION_DATA_PTR;
   
   /* The function to call when a pcb is freed */
   IO_PCB_STRUCT_PTR (_CODE_PTR_ PCB_FREE_FUNCTION_PTR)
      (IO_PCB_STRUCT_PTR, pointer);

   /* An additional pointer to pass to the free function */
   pointer                       FREE_FUNCTION_DATA_PTR;

   /* Partition ID */
   _partition_id                 PARTITION;

   /* Blocking wait semaphore */
   LWSEM_STRUCT                  PCB_LWSEM;
   
} IO_PCB_POOL_STRUCT, _PTR_ IO_PCB_POOL_STRUCT_PTR;


/*
**
** IO PCB DEVICE STRUCT
**
** This is the structure used to store device information for an
** installed PCB I/O driver
*/
typedef struct io_pcb_device_struct
{

   /* Used to link io_device_structs together */
   QUEUE_ELEMENT_STRUCT QUEUE_ELEMENT;

   /*
   ** A string that identifies the device.  This string is matched
   ** by fopen, then the other information is used to initialize a
   ** FILE struct for standard I/O.  This string is also provided in
   ** the kernel initialization record for the default I/O channel
   */
   char_ptr             IDENTIFIER;
  
   /* The I/O init function */
   _mqx_int (_CODE_PTR_ IO_OPEN)(MQX_FILE_PTR, char _PTR_, char _PTR_);

   /* The I/O deinit function */
   _mqx_int (_CODE_PTR_ IO_CLOSE)(MQX_FILE_PTR);

   /* The I/O read function */
   _mqx_int (_CODE_PTR_ IO_READ)(MQX_FILE_PTR, IO_PCB_STRUCT_PTR _PTR_);

   /* The I/O write function */
   _mqx_int (_CODE_PTR_ IO_WRITE)(MQX_FILE_PTR, IO_PCB_STRUCT_PTR);

   /* The I/O ioctl function */
   _mqx_int (_CODE_PTR_ IO_IOCTL)(MQX_FILE_PTR, _mqx_uint, pointer);

   /* The I/O uninstall function */
   _mqx_int (_CODE_PTR_ IO_UNINSTALL)(struct io_pcb_device_struct _PTR_);

   /* The I/O channel specific initialization data */
   pointer              DRIVER_INIT_PTR;

   /* 
   ** Used to keep track of the number of times the pcb device 
   ** has been opened
   */

   _mqx_uint            NUMBER_OF_OPENS;

} IO_PCB_DEVICE_STRUCT, _PTR_ IO_PCB_DEVICE_STRUCT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                      FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
/* IO PCB Device functions */
extern _mqx_uint    _io_pcb_free_internal(IO_PCB_STRUCT _PTR_);
extern _mqx_uint _io_pcb_dev_install(
      char_ptr, 
      _mqx_int (_CODE_PTR_)(FILE_DEVICE_STRUCT_PTR, char _PTR_, char _PTR_),
      _mqx_int (_CODE_PTR_)(FILE_DEVICE_STRUCT_PTR),
      _mqx_int (_CODE_PTR_)(FILE_DEVICE_STRUCT_PTR, IO_PCB_STRUCT _PTR_ _PTR_),
      _mqx_int (_CODE_PTR_)(FILE_DEVICE_STRUCT_PTR, IO_PCB_STRUCT _PTR_),
      _mqx_int (_CODE_PTR_)(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer),
      _mqx_int (_CODE_PTR_)(IO_PCB_DEVICE_STRUCT_PTR),
      pointer);
extern _mqx_uint _io_pcb_dev_uninstall(char_ptr);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/can/flexcan/flexcan_mk40.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008-2010  Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flexcan_mk40.c$
* $Version : 3.6.1.0$
* $Date    : Nov-3-2010$
*
* Comments:
*
*   Processor family specific file needed for flexcan module.
*   Revision History:
*   Date             Version  Changes
*   ---------        -------  -------
*   Sep 26/10        3.60     Initial version
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_flexcan_base_address  
* Returned Value   : Pointer to desired CAN device or NULL if not present
* Comments         :
*    This function returns pointer to base address of address space of the 
*    desired CAN device. Returns NULL otherwise.
*
*END*********************************************************************/
pointer _bsp_get_flexcan_base_address
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{ /* Body */
   pointer addr;
    
   switch(dev_num) {
   case 0:
      addr = (pointer)CAN0_BASE_PTR;
      break;
   case 1:
      addr = (pointer)CAN1_BASE_PTR;
      break;
   default:
      addr = NULL;
   }
    
   return addr;
} /* EndBody */

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_flexcan_vector
* Returned Value   : MQX vector number for specified interrupt
* Comments         :
*    This function returns index into MQX interrupt vector table for
*    specified flexcan interrupt. If not known, returns 0.
*
*END*********************************************************************/
IRQInterruptIndex _bsp_get_flexcan_vector 
(
   /* [IN] FlexCAN device number */
    uint_8 dev_num,
   /* [IN] FlexCAN interrupt vector type */
    uint_8 vector_type,
   /* [IN] FlexCAN interrupt vector index */
    uint_32 vector_index
)
{ /* Body */
   IRQInterruptIndex index = (IRQInterruptIndex)0;
   
   switch (dev_num)
   {
      case 0: 
         switch (vector_type)
         {
            case FLEXCAN_INT_BUF:
                 index = INT_CAN0_ORed_Message_buffer;
                 break;
            case FLEXCAN_INT_ERR:
                 index = INT_CAN0_Error;
                 break;
            case FLEXCAN_INT_BOFF:
                 index = INT_CAN0_Bus_Off;
                 break;
            default:
                 break;
         }
         break;
      case 1:    
         switch (vector_type)
         {
            case FLEXCAN_INT_BUF:
                 index = INT_CAN1_ORed_Message_buffer;
                 break;
            case FLEXCAN_INT_ERR:
                 index = INT_CAN1_Error;
                 break;
            case FLEXCAN_INT_BOFF:
                 index = INT_CAN1_Bus_Off;
                 break;
            default:
                 break;
         }
         break;
      default: break;
   }
   
   return index;
} /* EndBody */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/krtc_ext.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: krtc_ext.h$
* $Version : 3.8.2.0$
* $Date    : Oct-7-2011$
*
* Comments:
*
*   Processor family specific file needed for RTC module.
*
*END************************************************************************/

#ifndef __krtc_ext_h__
    #define __krtc_ext_h__


typedef uint_32 RTC_TAMPER_TYPE;

#ifdef __cplusplus
extern "C" {
#endif

/* Function prototypes */
void            _rtc_inc_upcounter(void);
uint_32         _rtc_get_upcounter(void);

_mqx_int        _rtc_tamper_enable(RTC_TAMPER_TYPE  enable_mask);
_mqx_int        _rtc_tamper_disable(RTC_TAMPER_TYPE disable_mask);
void            _rtc_get_tamper_timestamp( RTC_TIME_STRUCT_PTR time);
RTC_TAMPER_TYPE _rtc_get_tamper_status(void);
    
#ifdef __cplusplus
}
#endif

#endif  /* __krtc_ext_h__ */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_delete.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_delete.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the file specific interface functions
*   of MFS which need a filename as an input parameter.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


#if !MFSCFG_READ_ONLY


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Delete_file
* Returned Value   : error_code
* Comments  :   Delete a specific file.
*
*END*---------------------------------------------------------------------*/

_mfs_error  MFS_Delete_file
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] the MFS device on which to operate */
    char_ptr                pathname    /*[IN] directory and file name of the file to delete */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    _mfs_error              error_code, saved_code;
    uint_32                 dir_cluster, dir_index;
    uint_32                 first_cluster;
    uint_32                 prev_cluster= CLUSTER_INVALID;


    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        return MFS_INVALID_PARAMETER;
    }

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }

    dir_entry_ptr = MFS_Find_entry_on_disk(drive_ptr, pathname, &error_code, &dir_cluster, &dir_index, &prev_cluster);

    if ( dir_entry_ptr != NULL )
    {
        if (dtohc(dir_entry_ptr->ATTRIBUTE) & (MFS_ATTR_DIR_NAME | MFS_ATTR_VOLUME_NAME | MFS_ATTR_READ_ONLY))
        {
            /* Not a file or a read only file */
            error_code = MFS_ACCESS_DENIED;
        }
        else if (MFS_Find_handle(drive_ptr, dir_cluster, dir_index) != NULL)
        {
            /* File is currently open */
            error_code = MFS_SHARING_VIOLATION;
        }
        else
        {
            first_cluster = clustoh(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER);

            if (first_cluster)
            {
                error_code = MFS_Release_chain(drive_ptr, first_cluster);
            }

            if (error_code == MFS_NO_ERROR || error_code == MFS_LOST_CHAIN)
            {
                *dir_entry_ptr->NAME = MFS_DEL_FILE;
                drive_ptr->DIR_SECTOR_DIRTY = TRUE;

                saved_code = MFS_remove_lfn_entries(drive_ptr,dir_cluster,dir_index, prev_cluster);
                if (error_code == MFS_NO_ERROR)
                {
                    error_code = saved_code;
                }
            }
        }
    }
    MFS_unlock(drive_ptr,TRUE);

    return(error_code);
}

#endif


<|start_filename|>Firmware/Inverter_firmware/Main/Sin_Cos_generator.h<|end_filename|>
#ifndef __SIN_COS_GENERATOR
  #define __SIN_COS_GENERATOR

#define PH_MAX    0x100000000ull

void Gen_start(unsigned int freq);
void Gen_update_freq(unsigned int freq);
void Get_generator_sample(Frac32 *psin, Frac32 *pcos);

#endif

<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi/spi_dspi_prv.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_dspi_prv.h$
* $Version : 3.8.2.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This file contains definitions private to the SPI driver.
*
*END************************************************************************/

#ifndef __spi_dspi_prv_h__
#define __spi_dspi_prv_h__

#include "spi.h"
#include "spi_dspi.h"


/*--------------------------------------------------------------------------*/
/* Peripheral register access */

typedef struct dspi_reg_struct {
  uint_32 MCR;                                    /*!< DSPI Module Configuration Register, offset: 0x0 */
  uint_32 HCR;                                    /* silicon dependent */
  uint_32 TCR;                                    /*!< DSPI Transfer Count Register, offset: 0x8 */
  uint_32 CTAR[8];                                /*!< DSPI Clock and Transfer Attributes Register, array offset: 0xC, array step: 0x4, actual count depends on chip */
  uint_32 SR;                                     /*!< DSPI Status Register, offset: 0x2C */
  uint_32 RSER;                                   /*!< DSPI DMA/Interrupt Request Select and Enable Register, offset: 0x30 */
  uint_32 PUSHR;                                  /*!< DSPI PUSH TX FIFO Register In Master Mode, offset: 0x34 */
  uint_32 POPR;                                   /*!< DSPI POP RX FIFO Register, offset: 0x38 */
  uint_32 TXFR[16];                               /*!< DSPI Transmit FIFO Registers, offset: 0x3C, actual count depends on chip */
  uint_32 RXFR[16];                               /*!< DSPI Receive FIFO Registers, offset: 0x7C, actual count depends on chip */
} DSPI_REG_STRUCT, * DSPI_REG_STRUCT_PTR;

typedef volatile struct dspi_reg_struct * VDSPI_REG_STRUCT_PTR;


/* MCR Bit Fields */
#define DSPI_MCR_HALT_MASK                        0x1u
#define DSPI_MCR_SMPL_PT_MASK                     0x300
#define DSPI_MCR_SMPL_PT_SHIFT                    8
#define DSPI_MCR_CLR_RXF_MASK                     0x400u
#define DSPI_MCR_CLR_TXF_MASK                     0x800u
#define DSPI_MCR_DIS_RXF_MASK                     0x1000u
#define DSPI_MCR_DIS_TXF_MASK                     0x2000u
#define DSPI_MCR_MDIS_MASK                        0x4000u
#define DSPI_MCR_DOZE_MASK                        0x8000u
#define DSPI_MCR_PCSIS_MASK                       0xFF0000u
#define DSPI_MCR_PCSIS_SHIFT                      16
#define DSPI_MCR_ROOE_MASK                        0x1000000u
#define DSPI_MCR_PCSSE_MASK                       0x2000000u
#define DSPI_MCR_MTFE_MASK                        0x4000000u
#define DSPI_MCR_FRZ_MASK                         0x8000000u
#define DSPI_MCR_DCONF_MASK                       0x30000000u
#define DSPI_MCR_DCONF_SHIFT                      28
#define DSPI_MCR_CONT_SCKE_MASK                   0x40000000u
#define DSPI_MCR_MSTR_MASK                        0x80000000u

/* TCR Bit Fields */
#define DSPI_TCR_SPI_TCNT_MASK                    0xFFFF0000u
#define DSPI_TCR_SPI_TCNT_SHIFT                   16

/* CTAR Bit Fields */
#define DSPI_CTAR_BR_MASK                         0xFu
#define DSPI_CTAR_BR_SHIFT                        0
#define DSPI_CTAR_DT_MASK                         0xF0u
#define DSPI_CTAR_DT_SHIFT                        4
#define DSPI_CTAR_ASC_MASK                        0xF00u
#define DSPI_CTAR_ASC_SHIFT                       8
#define DSPI_CTAR_CSSCK_MASK                      0xF000u
#define DSPI_CTAR_CSSCK_SHIFT                     12
#define DSPI_CTAR_PBR_MASK                        0x30000u
#define DSPI_CTAR_PBR_SHIFT                       16
#define DSPI_CTAR_PDT_MASK                        0xC0000u
#define DSPI_CTAR_PDT_SHIFT                       18
#define DSPI_CTAR_PASC_MASK                       0x300000u
#define DSPI_CTAR_PASC_SHIFT                      20
#define DSPI_CTAR_PCSSCK_MASK                     0xC00000u
#define DSPI_CTAR_PCSSCK_SHIFT                    22
#define DSPI_CTAR_LSBFE_MASK                      0x1000000u
#define DSPI_CTAR_CPHA_MASK                       0x2000000u
#define DSPI_CTAR_CPOL_MASK                       0x4000000u
#define DSPI_CTAR_FMSZ_MASK                       0x78000000u
#define DSPI_CTAR_FMSZ_SHIFT                      27
#define DSPI_CTAR_DBR_MASK                        0x80000000u
#define DSPI_CTAR_DBR_SHIFT                       31
#define DSPI_CTAR_SLAVE_FMSZ_MASK                 0xF8000000u
#define DSPI_CTAR_SLAVE_FMSZ_SHIFT                27

/* SR Bit Fields */
#define DSPI_SR_POPNXTPTR_MASK                    0xFu
#define DSPI_SR_POPNXTPTR_SHIFT                   0
#define DSPI_SR_RXCTR_MASK                        0xF0u
#define DSPI_SR_RXCTR_SHIFT                       4
#define DSPI_SR_TXNXTPTR_MASK                     0xF00u
#define DSPI_SR_TXNXTPTR_SHIFT                    8
#define DSPI_SR_TXCTR_MASK                        0xF000u
#define DSPI_SR_TXCTR_SHIFT                       12
#define DSPI_SR_RFDF_MASK                         0x20000u
#define DSPI_SR_RFOF_MASK                         0x80000u
#define DSPI_SR_TFFF_MASK                         0x2000000u
#define DSPI_SR_TFUF_MASK                         0x8000000u
#define DSPI_SR_EOQF_MASK                         0x10000000u
#define DSPI_SR_TXRXS_MASK                        0x40000000u
#define DSPI_SR_TCF_MASK                          0x80000000u

/* RSER Bit Fields */
#define DSPI_RSER_RFDF_DIRS_MASK                  0x10000u
#define DSPI_RSER_RFDF_RE_MASK                    0x20000u
#define DSPI_RSER_RFOF_RE_MASK                    0x80000u
#define DSPI_RSER_TFFF_DIRS_MASK                  0x1000000u
#define DSPI_RSER_TFFF_RE_MASK                    0x2000000u
#define DSPI_RSER_TFUF_RE_MASK                    0x8000000u
#define DSPI_RSER_EOQF_RE_MASK                    0x10000000u
#define DSPI_RSER_TCF_RE_MASK                     0x80000000u

/* PUSHR Bit Fields */
#define DSPI_PUSHR_TXDATA_MASK                    0xFFFFu
#define DSPI_PUSHR_TXDATA_SHIFT                   0
#define DSPI_PUSHR_PCS_MASK                       0x3F0000u
#define DSPI_PUSHR_PCS_SHIFT                      16
#define DSPI_PUSHR_CTCNT_MASK                     0x4000000u
#define DSPI_PUSHR_EOQ_MASK                       0x8000000u
#define DSPI_PUSHR_CTAS_MASK                      0x70000000u
#define DSPI_PUSHR_CTAS_SHIFT                     28
#define DSPI_PUSHR_CONT_MASK                      0x80000000u

/* POPR Bit Fields */
#define DSPI_POPR_RXDATA_MASK                     0xFFFFFFFFu
#define DSPI_POPR_RXDATA_SHIFT                    0


#define DSPI_MCR_PCSIS(x)        (((x) << DSPI_MCR_PCSIS_SHIFT) & DSPI_MCR_PCSIS_MASK)
#define DSPI_CTAR_BR(x)          (((x) << DSPI_CTAR_BR_SHIFT) & DSPI_CTAR_BR_MASK)
#define DSPI_CTAR_DT(x)          (((x) << DSPI_CTAR_DT_SHIFT) & DSPI_CTAR_DT_MASK)
#define DSPI_CTAR_ASC(x)         (((x) << DSPI_CTAR_ASC_SHIFT) & DSPI_CTAR_ASC_MASK)
#define DSPI_CTAR_CSSCK(x)       (((x) << DSPI_CTAR_CSSCK_SHIFT) & DSPI_CTAR_CSSCK_MASK)
#define DSPI_CTAR_PBR(x)         (((x) << DSPI_CTAR_PBR_SHIFT) & DSPI_CTAR_PBR_MASK)
#define DSPI_CTAR_PDT(x)         (((x) << DSPI_CTAR_PDT_SHIFT) & DSPI_CTAR_PDT_MASK)
#define DSPI_CTAR_PASC(x)        (((x) << DSPI_CTAR_PASC_SHIFT) & DSPI_CTAR_PASC_MASK)
#define DSPI_CTAR_PCSSCK(x)      (((x) << DSPI_CTAR_PCSSCK_SHIFT) & DSPI_CTAR_PCSSCK_MASK)
#define DSPI_CTAR_FMSZ(x)        (((x) << DSPI_CTAR_FMSZ_SHIFT) & DSPI_CTAR_FMSZ_MASK)
#define DSPI_PUSHR_TXDATA(x)     (((x) << DSPI_PUSHR_TXDATA_SHIFT) & DSPI_PUSHR_TXDATA_MASK)
#define DSPI_PUSHR_PCS(x)        (((x) << DSPI_PUSHR_PCS_SHIFT) & DSPI_PUSHR_PCS_MASK)
#define DSPI_PUSHR_CTAS(x)       (((x) << DSPI_PUSHR_CTAS_SHIFT) & DSPI_PUSHR_CTAS_MASK)

#define DSPI_CTAR_FMSZ_GET(x)    (((x) & DSPI_CTAR_FMSZ_MASK) >> DSPI_CTAR_FMSZ_SHIFT)
#define DSPI_CTAR_PBR_GET(x)     (((x) & DSPI_CTAR_PBR_MASK) >> DSPI_CTAR_PBR_SHIFT)
#define DSPI_CTAR_BR_GET(x)      (((x) & DSPI_CTAR_BR_MASK) >> DSPI_CTAR_BR_SHIFT)
#define DSPI_SR_TXCTR_GET(x)     (((x) & DSPI_SR_TXCTR_MASK) >> DSPI_SR_TXCTR_SHIFT)
#define DSPI_PUSHR_PCS_GET(x)    (((x) & DSPI_PUSHR_PCS_MASK) >> DSPI_PUSHR_PCS_SHIFT)
#define DSPI_PUSHR_CTAS_GET(x)   (((x) & DSPI_PUSHR_CTAS_MASK) >> DSPI_PUSHR_CTAS_SHIFT)
#define DSPI_PUSHR_TXDATA_GET(x) (((x) & DSPI_PUSHR_TXDATA_MASK) >> DSPI_PUSHR_TXDATA_SHIFT)
#define DSPI_MCR_PCSIS_GET(x)    (((x) & DSPI_MCR_PCSIS_MASK) >> DSPI_MCR_PCSIS_SHIFT)
#define DSPI_POPR_RXDATA_GET(x)  (((x) & DSPI_POPR_RXDATA_MASK) >> DSPI_POPR_RXDATA_SHIFT)


/* Max number of different IRQs the peripheral can generate */
#define DSPI_MAX_VECTORS 6


/* Max. number of frames on the way to prevent RX overruns in master mode */
#define DSPI_FIFO_DEPTH 4


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** DSPI_INFO_STRUCT
** Run time state information for each spi channel
*/
typedef struct dspi_info_struct
{
    /* SPI channel number */
    uint_32                           CHANNEL;

    /* The input clock source of the module */
    CM_CLOCK_SOURCE                   CLOCK_SOURCE;

    /* Most recently used clock configuration (cached value) */
    BSP_CLOCK_CONFIGURATION           CLOCK_CONFIG;

    /* Most recently used baudrate */
    uint_32                           BAUDRATE;

    /* Most recently calculated timing parameters for CTAR register */
    uint_32                           CTAR_TIMING;

    /* The spi device registers */
    VDSPI_REG_STRUCT_PTR              DSPI_PTR;

    /* CS signal(s) to activate for the transfer */
    uint_32                           CS;

    /* Pattern to transmit during half-duplex rx transfer */
    uint_32                           DUMMY_PATTERN;

    /* Additional attributes for the transfer */
    uint_32                           ATTR;

    /* Pointer to the buffer to use for RX data */
    uint_8_ptr                        RX_BUF;

    /* One DMA RX transfer byte count */
    uint_32                           RX_LEN;

    /* Pointer to the buffer to use for TX data */
    uint_8_ptr                        TX_BUF;

    /* One TX transfer byte count */
    uint_32                           TX_LEN;

    /* Event to signal ISR job done */
    LWSEM_STRUCT                      EVENT_IO_FINISHED;

    /* The previous vector, interrupt handler and data */
    uint_32                           NUM_VECTORS;
    void                  (_CODE_PTR_ OLD_ISR[DSPI_MAX_VECTORS])(pointer);
    pointer                           OLD_ISR_DATA[DSPI_MAX_VECTORS];

} DSPI_INFO_STRUCT, _PTR_ DSPI_INFO_STRUCT_PTR;

typedef volatile struct dspi_info_struct * VDSPI_INFO_STRUCT_PTR;


#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/queue.c<|end_filename|>
/*HEADER**********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *****************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************
 *
 * $FileName: queue.c$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains the queue functions.
  *
 *END************************************************************************/

#define MQX_FORCE_USE_INLINE_MACROS     1

#include "mqx_inc.h"
/*!
 * \brief Initializes the provided queue.
 * 
 * \param[in] q_ptr Pointer to the queue to initialize.
 * \param[in] size  One of the following:
 * \li Maximum number of elements that the queue can hold.
 * \li 0 (Unlimited number.)
 * 
 * \warning If q_ptr is not a pointer to QUEUE_STRUCT, the function might behave
 * unpredictably.
 * 
 * \see _queue_enqueue
 * \see _queue_dequeue
 * \see QUEUE_STRUCT
 */ 
void _queue_init
(
    QUEUE_STRUCT_PTR q_ptr,
    uint_16          size
)
{ /* Body */

    _QUEUE_INIT(q_ptr, size);

} /* Endbody */
/*!
 * \brief Adds the element to the end of the queue.
 * 
 * \param[in] q_ptr Pointer to the queue to which to add the element; initialized 
 * with _queue_init().
 * \param[in] e_ptr Pointer to the element to add.
 * 
 * \return TRUE (success) or FALSE (Failure: the queue is full.)
 * 
 * \warning The function might behave unpredictably if either:
 * \li Q_ptr is not a pointer to QUEUE_STRUCT.
 * \li E_ptr is not a pointer to QUEUE_ELEMENT_STRUCT.
 * 
 * \see _queue_init 
 * \see _queue_dequeue
 * \see _queue_init
 * \see QUEUE_STRUCT
 * \see QUEUE_ELEMENT_STRUCT 
 */ 
boolean _queue_enqueue
(
    QUEUE_STRUCT_PTR         q_ptr,
    QUEUE_ELEMENT_STRUCT_PTR e_ptr
)
{ /* Body */

    _int_disable();
    if ((q_ptr->MAX != 0) && (q_ptr->SIZE >= q_ptr->MAX))
    {
        _int_enable();
        return (FALSE);
    } /* Endif */

    _QUEUE_ENQUEUE(q_ptr, e_ptr);
    _int_enable();
    return (TRUE);

} /* Endbody */

/*!
 * \brief Removes the first element from the queue.
 * 
 * \param[in] q_ptr Pointer to the queue from which to remove the first element; 
 * initialized with _queue_init().
 * 
 * \return Pointer to the removed first queue element.
 * \return NULL (Queue is empty.)
 * 
 * \warning If q_ptr is not a pointer to QUEUE_STRUCT, the function might behave
 * unpredictably.
 * 
 * \see _queue_enqueue
 * \see _queue_init
 * \see QUEUE_STRUCT
 * \see QUEUE_ELEMENT_STRUCT 
 */ 
QUEUE_ELEMENT_STRUCT_PTR _queue_dequeue
(
    QUEUE_STRUCT_PTR            q_ptr
)
{ /* Body */
    QUEUE_ELEMENT_STRUCT_PTR    e_ptr;

    _int_disable();
    if (q_ptr->SIZE == 0)
    {
        _int_enable();
        return (NULL);
    } /* Endif */

    _QUEUE_DEQUEUE(q_ptr, e_ptr);
    _int_enable();
    return (e_ptr);

} /* Endbody */

/*!
 * \brief Gets a pointer to the element at the start of the queue, but do not 
 * remove the element.
 * 
 * \param[in] q_ptr Pointer to the queue to use; initialized with _queue_init().
 * 
 * \return Pointer to the element that is at the start of the queue.
 * \return NULL (Queue is empty.)
 * 
 * \warning If q_ptr is not a pointer to QUEUE_STRUCT, the function might behave
 * unpredictably.
 * 
 * \see _queue_dequeue
 * \see _queue_init
 * \see QUEUE_STRUCT
 * \see QUEUE_ELEMENT_STRUCT 
 */ 
QUEUE_ELEMENT_STRUCT_PTR _queue_head
(
    QUEUE_STRUCT_PTR q_ptr
)
{ /* Body */
    QUEUE_ELEMENT_STRUCT_PTR e_ptr;

    _int_disable();
    if (q_ptr->SIZE == 0)
    {
        _int_enable();
        return (NULL);
    } /* Endif */

    e_ptr = q_ptr->NEXT;
    _int_enable();
    return (e_ptr);

} /* Endbody */

/*!
 * \brief Inserts the element in the queue.
 * 
 * \param[in] q_ptr  Pointer to the queue to insert into; initialized with 
 * _queue_init().
 * \param[in] qe_ptr One of the following:
 * \li Pointer to the element after which to insert the new element.
 * \li NULL (Insert the element at the start of the queue.)
 * \param[in] e_ptr  Pointer to the element to insert.
 * 
 * \return TRUE (success) or FALSE (Failure: queue is full.)
 * 
 * \warning The function might behave unpredictably if either:
 * \li Q_ptr is not a pointer to QUEUE_STRUCT.
 * \li E_ptr is not a pointer to QUEUE_ELEMENT_STRUCT.
 * 
 * \see _queue_init 
 * \see QUEUE_STRUCT
 * \see QUEUE_ELEMENT_STRUCT  
 */ 
boolean _queue_insert
(
    QUEUE_STRUCT_PTR         q_ptr,
    QUEUE_ELEMENT_STRUCT_PTR qe_ptr,
    QUEUE_ELEMENT_STRUCT_PTR e_ptr
)
{ /* Body */

    if (qe_ptr == NULL)
    {
        /* Insert at the front */
        qe_ptr = (QUEUE_ELEMENT_STRUCT_PTR) ((pointer) q_ptr);
    } /* Endif */
    _int_disable();
    if ((q_ptr->MAX != 0) && (q_ptr->SIZE >= q_ptr->MAX))
    {
        _int_enable();
        return (FALSE);
    } /* Endif */

    _QUEUE_INSERT(q_ptr, qe_ptr, e_ptr);
    _int_enable();
    return (TRUE);

} /* Endbody */

/*!
 * \brief Gets a pointer to the element after the provided one in the queue, but 
 * do not remove the element.
 * 
 * This function returns NULL if either:
 * \li E_ptr is NULL.
 * \li E_ptr is a pointer to the last element.
 * 
 * \param[in] q_ptr Pointer to the queue for which to get info; initialized with 
 * _queue_init().
 * \param[in] e_ptr Get the element after this one.
 * 
 * \return Pointer to the next queue element (success).
 * \return NULL (Failure: see Description.)
 * 
 * \warning The function might behave unpredictably if either:
 * \li Q_ptr is not a pointer to QUEUE_STRUCT.
 * \li E_ptr is not a pointer to QUEUE_ELEMENT_STRUCT.
 * 
 * \see _queue_init 
 * \see _queue_dequeue
 * \see QUEUE_STRUCT
 * \see QUEUE_ELEMENT_STRUCT  
 */ 
QUEUE_ELEMENT_STRUCT_PTR _queue_next
(
    QUEUE_STRUCT_PTR         q_ptr,
    QUEUE_ELEMENT_STRUCT_PTR e_ptr
)
{ /* Body */
    QUEUE_ELEMENT_STRUCT_PTR    next_ptr;

    if (e_ptr == NULL)
    {
        return NULL;
    } /* Endif */
    _int_disable();
    next_ptr = e_ptr->NEXT;
    _int_enable();
    if (next_ptr == (QUEUE_ELEMENT_STRUCT_PTR) ((pointer) q_ptr))
    {
        /* At end of queue */
        next_ptr = NULL;
    } /* Endif */
    return (next_ptr);

} /* Endbody */

/*!
 * \brief Tests the queue for consitstency and validity.
 * 
 * This function checks the queue pointers to ensure that they form a circular, 
 * double linked list, with the same number of elements that the queue header 
 * specifies.
 * 
 * \param[in]  q_ptr                Pointer to the queue to test; initialized 
 * with _queue_init().
 * \param[out] element_in_error_ptr Pointer to the first element with an error 
 * (initialized only if an error is found).
 * 
 * \return MQX_OK (No errors were found.)
 * \return MQX_CORRUPT_QUEUE (An error was found.)
 * 
 * \see _queue_init 
 * \see QUEUE_STRUCT
 * \see QUEUE_ELEMENT_STRUCT 
 */ 
_mqx_uint _queue_test
(
    QUEUE_STRUCT_PTR q_ptr,
    pointer _PTR_    element_in_error_ptr
)
{ /* Body */
    QUEUE_ELEMENT_STRUCT_PTR element_ptr;
    QUEUE_ELEMENT_STRUCT_PTR prev_ptr;
    _mqx_uint size;

    _int_disable();
    size = _QUEUE_GET_SIZE(q_ptr) + 1;
    element_ptr = q_ptr->NEXT;
    prev_ptr = (QUEUE_ELEMENT_STRUCT_PTR)((pointer)q_ptr);
    while (--size)
    {
        if (element_ptr == (pointer)q_ptr)
        {
            _int_enable();
            /* Size too big for # elements on queue */
            *element_in_error_ptr = element_ptr;
            return(MQX_CORRUPT_QUEUE);
        } /* Endif */
        if (element_ptr->PREV != prev_ptr)
        {
            _int_enable();
            *element_in_error_ptr = element_ptr;
            return(MQX_CORRUPT_QUEUE);
        } /* Endif */
        prev_ptr = element_ptr;
        element_ptr = element_ptr->NEXT;
    } /* Endwhile */

    /* Does the last element in the ring point back to the queue head */
    if ((pointer)element_ptr != (pointer)q_ptr)
    {
        _int_enable();
        *element_in_error_ptr = element_ptr;
        return(MQX_CORRUPT_QUEUE);
    } /* Endif */

    /* Is the last element in ring pointed to by queues PREV field */
    if (q_ptr->PREV != prev_ptr)
    {
        _int_enable();
        *element_in_error_ptr = element_ptr;
        return(MQX_CORRUPT_QUEUE);
    } /* Endif */

    _int_enable();
    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Removes a specified element from the queue.
 * 
 * \param[in] q_ptr Pointer to the queue from which to remove the element; 
 * initialized with _queue_init().
 * \param[in] e_ptr Pointer to the element to remove.
 * 
 * \warning The function might behave unpredictably if either:
 * \li Q_ptr is not a pointer to QUEUE_STRUCT.
 * \li E_ptr is not a pointer to QUEUE_ELEMENT_STRUCT.
 * 
 * \see _queue_init 
 * \see _queue_dequeue
 * \see QUEUE_STRUCT
 * \see QUEUE_ELEMENT_STRUCT
 */ 
void _queue_unlink
(
    QUEUE_STRUCT_PTR         q_ptr,
    QUEUE_ELEMENT_STRUCT_PTR e_ptr
)
{ /* Body */

    _int_disable();
    _QUEUE_REMOVE(q_ptr, e_ptr);
    _int_enable();

} /* Endbody */

/*!
 * \brief Gets the number of elements in the queue.
 * 
 * \param[in] q_ptr Pointer to the queue for which to get info; initialized with 
 * _queue_init().
 * 
 * \return Number of elements in the queue.
 * 
 * \warning If q_ptr is not a pointer to QUEUE_STRUCT, the function might behave
 * unpredictably.
 * 
 * \see _queue_enqueue
 * \see _queue_init
 * \see QUEUE_STRUCT
 */ 
_mqx_uint _queue_get_size
(
    QUEUE_STRUCT_PTR        q_ptr
)
{ /* Body */

    return _QUEUE_GET_SIZE(q_ptr);

} /* Endbody */

/*!
 * \brief Determines whether the queue is empty.
 * 
 * \param[in] q_ptr Pointer to the queue for which to get info; initialized with 
 * _queue_init().
 * 
 * \return TRUE (Queue is empty.) or FALSE (Queue is not empty.)
 * 
 * \warning If q_ptr is not a pointer to QUEUE_STRUCT, the function might behave
 * unpredictably.
 * 
 * \see _queue_init
 * \see QUEUE_STRUCT 
 */ 
boolean _queue_is_empty
(
    QUEUE_STRUCT_PTR            q_ptr
)
{ /* Body */

    return _QUEUE_IS_EMPTY(q_ptr);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/nandflash/nand_devices/MT29F2G16.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: MT29F2G16.c$
* $Version : 3.8.4.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains the definitions for the MT29F2G16 flash device.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "nandflash.h"


/* MT29F2G16AABWP organization */
#define MT29F2G16_PHYSICAL_PAGE_SIZE      2048
#define MT29F2G16_SPARE_AREA_SIZE         64
#define MT29F2G16_BLOCK_SIZE              131072 /* 128kB */
#define MT29F2G16_NUM_BLOCKS              2048
#define MT29F2G16_WIDTH                   16


NANDFLASH_INFO_STRUCT _MT29F2G16_organization_16bit[] =  {
  MT29F2G16_PHYSICAL_PAGE_SIZE,
  MT29F2G16_SPARE_AREA_SIZE, 
  MT29F2G16_BLOCK_SIZE,
  MT29F2G16_NUM_BLOCKS,
  MT29F2G16_WIDTH
};

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/core_mutex/core_mutex.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: core_mutex.h$
* $Version : 3.8.2.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains the type definitions for the core mutex driver.
*
*END************************************************************************/

#ifndef __core_mutex_h__
#define __core_mutex_h__

#define __core_mutex_h__version "$Version:3.8.2.0$"
#define __core_mutex_h__date    "$Date:Sep-24-2012$"

#include <core_mutex_sema4.h>

/* Core Mutex driver error codes */
#define COREMUTEX_OK         (0)
#define COREMUTEX_LOCKED     (COREMUTEX_ERROR_BASE | 0x01) /* CM locked */
#define COREMUTEX_UNLOCKED   (COREMUTEX_ERROR_BASE | 0x02) /* CM unlocked */


#define CORE_MUTEX_VALID  (('c'<<24)|('m'<<24)|('t'<<24)|'x')

typedef struct core_mutex_component {
   CORE_MUTEX_DEVICE  DEVICE[PSP_NUM_CORES];
} CORE_MUTEX_COMPONENT, * CORE_MUTEX_COMPONENT_PTR;


typedef struct core_mutex_init_struct {
   uint_32     INT_PRIORITY;
} CORE_MUTEX_INIT_STRUCT, * CORE_MUTEX_INIT_STRUCT_PTR;


#ifdef __cplusplus
extern "C" {
#endif

extern CORE_MUTEX_COMPONENT_PTR _core_mutext_get_component_ptr(void);
extern void                     _core_mutext_set_component_ptr(CORE_MUTEX_COMPONENT_PTR p);
extern uint_32                  _core_mutex_install( const CORE_MUTEX_INIT_STRUCT * init_ptr );
extern CORE_MUTEX_PTR           _core_mutex_create( uint_32 core_num, uint_32 mutex_num, uint_32 policy );
extern uint_32                  _core_mutex_create_at( CORE_MUTEX_PTR mutex_ptr, uint_32 core_num, uint_32 mutex_num, uint_32 policy );
extern uint_32                  _core_mutex_destroy( CORE_MUTEX_PTR mutex_ptr );
extern CORE_MUTEX_PTR           _core_mutex_get( uint_32 core_num, uint_32 mutex_num );
extern uint_32                  _core_mutex_lock( CORE_MUTEX_PTR core_mutex_ptr );
extern uint_32                  _core_mutex_trylock( CORE_MUTEX_PTR core_mutex_ptr );
extern uint_32                  _core_mutex_unlock( CORE_MUTEX_PTR core_mutex_ptr );
extern int_32                   _core_mutex_owner( CORE_MUTEX_PTR core_mutex_ptr );


#ifdef __cplusplus
}
#endif


#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/nat.h<|end_filename|>
#ifndef __nat_h__
#define __nat_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nat.h$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   Network Address Translator definitions.
*
*END************************************************************************/


#if RTCS_VERSION < 0x00029600L
#error "This version of NAT requires RTCS 2.96.00 or higher"
#endif


/*************************************
**
** NAT constants
*/
#define NAT_DEFAULT_TIMEOUT_TCP     (15 * 60 * 1000)  /* 15 minutes */
#define NAT_DEFAULT_TIMEOUT_UDP     ( 5 * 60 * 1000)  /*  5 minutes */
#define NAT_DEFAULT_TIMEOUT_FIN     ( 2 * 60 * 1000)  /*  2 minutes */
/*
 * ICMP specific NAT extension
 * NAT Default ICMP session timeout. It should be small in order
 * to minimized the system resources, each PING creates a new NAT
 * session
 */
#define NAT_DEFAULT_TIMEOUT_ICMP    ( 1 * 60 * 1000)  /*  1 minutes */

// IANA Port Ranges
#define NAT_WELL_KNOWN_PORT_MIN     0
#define NAT_WELL_KNOWN_PORT_MAX     1023
#define NAT_REGISTERED_PORT_MIN     1024
#define NAT_REGISTERED_PORT_MAX     49151
#define NAT_DYNAMIC_PORT_MIN        49152
#define NAT_DYNAMIC_PORT_MAX        65535

#define NAT_DEFAULT_PORT_MIN        10000
#define NAT_DEFAULT_PORT_MAX        20000

#define SNAT 0 
#define DNAT 1 

#define NAT_MAX_PRIVATE_NETWORKS    16    // maximum number of supported private networks


/**************************************
**
** NAT setsockopt 
*/

extern const RTCS_SOCKOPT_CALL_STRUCT  SOL_NAT_CALL;




/* 
** NAT Timeout structure (for NAT configuration)
*/
typedef struct nat_timeouts_struct {
   uint_32  timeout_tcp;
   uint_32  timeout_fin;
   uint_32  timeout_udp;
   uint_32  timeout_icmp;     // NAT ICMP session timeout extension 
} nat_timeouts, NAT_TIMEOUTS_STRUCT, _PTR_ NAT_TIMEOUTS_STRUCT_PTR;


/* 
** NAT Port structure (for NAT configuration)
*/
typedef struct nat_ports_struct {
   uint_16  port_min;
   uint_16  port_max;
} nat_ports, NAT_PORTS_STRUCT, _PTR_ NAT_PORTS_STRUCT_PTR;


/* 
** NAT_STATS:
**    A structure used for statistics 
*/
typedef struct nat_stats {
   uint_32  ST_SESSIONS;            /* total amount of sessions created to date */
   uint_32  ST_SESSIONS_OPEN;       /* amount of sessions currently open */
   uint_32  ST_SESSIONS_OPEN_MAX;   /* max amount of sessions simult. open */   
   uint_32  ST_PACKETS_TOTAL;       /* amount of packets processed by NAT */
   uint_32  ST_PACKETS_BYPASS;      /* amount of unmodified packets */
   uint_32  ST_PACKETS_PUB_PRV;     /* packets from public to private */
   uint_32  ST_PACKETS_PUB_PRV_ERR; /* packets from public to private with errs */
   uint_32  ST_PACKETS_PRV_PUB;     /* packets from private to public */
   uint_32  ST_PACKETS_PRV_PUB_ERR; /* packets from private to public with errs */

   uint_32  ST_PACKETS_FRAGMENTS;
   uint_32  ST_PACKETS_REASSEMBLED;
   uint_32  ST_PACKETS_REASSSEMBLY_ERR;

   uint_32  ST_SESSIONS_SNAT;       /* total amount of SNAT sessions created to date */
   uint_32  ST_SESSIONS_DNAT;       /* total amount of DNAT sessions created to date */

} NAT_STATS, _PTR_ NAT_STATS_PTR;


typedef struct nat_network_struct {
   uint_32                 NUM_PRV_NETS;              /* Number of initialized private networks */
   _ip_address             PRV_NET[NAT_MAX_PRIVATE_NETWORKS];  /* List of private networks      */
   _ip_address             PRV_MASK[NAT_MAX_PRIVATE_NETWORKS]; /* Corresponding network masks   */
} NAT_NETWORK_STRUCT, _PTR_ NAT_NETWORK_STRUCT_PTR;

typedef uint_32 (_CODE_PTR_ NAT_ALG)(pointer);

/*
** NAT_alg_table:
**    NULL terminated table which specifies enabled ALGs 
*/

#define NAT_ALG_TFTP    NAT_ALG_tftp
#define NAT_ALG_FTP     NAT_ALG_ftp
#define NAT_ALG_ENDLIST NULL
extern NAT_ALG NAT_alg_table[];

/***************************************
**
** Function definitions
**
*/
extern uint_32 NAT_init
(
   _ip_address,         /* [IN] private network IP */
   _ip_address          /* [IN] private network netmask */
);

extern uint_32 NAT_add_network
(
   _ip_address    private_network,
   _ip_address    private_netmask
);

extern uint_32 NAT_remove_network
(
   _ip_address    private_network,
   _ip_address    private_netmask
);

extern uint_32 NAT_close
(  
   void
);

extern NAT_STATS_PTR NAT_stats
(
   void
);

extern NAT_NETWORK_STRUCT_PTR NAT_networks
(
   void
);

extern pointer NAT_find_next_session
(
   pointer  session,
   uint_32  tree
);

extern uint_32 NAT_ALG_tftp(pointer);
extern uint_32 NAT_ALG_ftp(pointer);

/***************************************
**
** Function definitions for DNAT
**
*/
extern uint_32 DNAT_add_rule
(
   uint_32,       /* [IN] */    
   uint_16,       /* [IN] */
   uint_16,       /* [IN] */
   uint_16,       /* [IN] */
   _ip_address,   /* [IN] */
   uint_16        /* [IN] */
);

extern uint_32 DNAT_delete_rule
(
      uint_32
);

extern uint_32  DNAT_get_next_rule
(
   uint_32_ptr,    /* [IN/OUT] */   
   uint_16_ptr,    /* [OUT */
   uint_16_ptr,    /* [OUT] */
   uint_16_ptr,     /* [OUT] */
   _ip_address _PTR_,/* [OUT]   */
   uint_16_ptr       /* [OUT] */
);

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd_supp.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd_supp.h$
* $Version : 3.7.8.0$
* $Date    : Mar-9-2011$
*
* Comments:
*
*   HTTPD support functions header.
*
*END************************************************************************/

#ifndef HTTP_SUPP_H_
#define HTTP_SUPP_H_

#include "httpd_types.h"

/** Send string to socket.
 * \param s < socket
 * \param str < pointer to string
 * \return length of sent data
 */
_mqx_int httpd_sendstr(_mqx_int s, char *str);

/** Read data from tcp/ip stack.
 * \param session < pointer to session
 * \param dest < pointer to destination buffer
 * \param len < requested read length
 * \return real read length
 */
_mqx_int httpd_read(HTTPD_SESSION_STRUCT *session, char *dst, _mqx_int len);

/** Read line from tcp/ip stack.
 * \param session < pointer to session
 * \param dest < pointer to destination buffer
 * \param len < maximal read length
 * \return nonzero - read success
 */
_mqx_int httpd_readln(HTTPD_SESSION_STRUCT *session, char *dst, _mqx_int max_len);

/** send header
 * \param session < pointer to evaluated session
 * \param content_len < content len
 * \param mod_time < modification time
 */
void httpd_sendhdr(HTTPD_SESSION_STRUCT *session, _mqx_int content_len, _mqx_int mod_time);

/** send file
 * \param server < pointer to server configuration structure
 * \param session < pointer to evaluated session
 */
void httpd_sendfile(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session);

/** HTTP find cgi and call it.
 * \param session < pointer to session
 * \param cgi_name < cgi script name
 * \return
 *      < 0 - not found or cgi script request flush stack
 *      other - readed length from stack
 */
_mqx_int httpd_cgi(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session, char *cgi_name);

/** send 401 error page. Find page file or generate standard page.
 * \param server < pointer to server
 * \param session < pointer to session
 */
void httpd_send401(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session);

/** send 403 error page. Find page file or generate standard page.
 * \param server < pointer to server
 * \param session < pointer to session
 */
void httpd_send403(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session);

/** send 404 error page. Find page file or generate standard page.
 * \param server < pointer to server
 * \param session < pointer to session
 */
void httpd_send404(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session);

/** decode base64 block
 * \param dst < destination string buffer
 * \param src < source string buffer
 * \param dst_size < maximal destination string length
 * \return
 */
_mqx_int httpd_decode_base64(char *dst, char *src, _mqx_int dst_size);

/** Get variable from URL link - GET method.
 * \param session < pointer to session data
 * \param var_str < variables string - string for parsing
 * \param var_name < variable name
 * \param var_val < pointer to buffer for variable value (string)
 * \param var_val_len < maximal length for variable value
 * \return
 */
_mqx_int httpd_get_varval(HTTPD_SESSION_STRUCT *session, char *var_str, char *var_name, char *var_val, _mqx_int var_val_len);

#endif /* HTTP_SUPP_H_ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_util.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_util.c$
* $Version : 3.8.10.0$
* $Date    : Jul-31-2012$
*
* Comments:
*
*   This file contains the MACNET util functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "macnet_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_install_isr
*  Returned Value : ENET_OK or error code
*  Comments       :
*         
*
*END*-----------------------------------------------------------------*/

boolean MACNET_install_isr( 
   ENET_CONTEXT_STRUCT_PTR enet_ptr, 
   uint_32                 int_num, 
   uint_32                 int_index, 
   INT_ISR_FPTR            isr, 
   uint_32                 level, 
   uint_32                 sublevel  ) 
{
   uint_32  vector = MACNET_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, int_index);
 
#if BSPCFG_ENET_RESTORE
   MACNET_CONTEXT_STRUCT_PTR    macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;


   /* Save old ISR and data */
   macnet_context_ptr->OLDISR_PTR[int_num]   = _int_get_isr(vector);
   macnet_context_ptr->OLDISR_DATA[int_num] = _int_get_isr_data(vector);
#endif

   if (_int_install_isr(vector, isr, (pointer)enet_ptr)==NULL) {
      return FALSE;
   }

   /* Initialize interrupt priority and level */
   _bsp_int_init((PSP_INTERRUPT_TABLE_INDEX)vector, level, sublevel, TRUE);

   return TRUE;
}


#if PSP_MQX_CPU_IS_VYBRID
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_RX_TX_ISR
*  Returned Value : none
*  Comments       : function for macnet interrupt servicing on Vybrid 
*                   platform
*
*END*-----------------------------------------------------------------*/
void MACNET_RX_TX_ISR 
   (
      /* [IN] the Ethernet state structure */
      pointer  enet
   )
{
	ENET_CONTEXT_STRUCT_PTR    enet_ptr           = (ENET_CONTEXT_STRUCT_PTR)enet;
	MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
	ENET_MemMapPtr             macnet_ptr         = macnet_context_ptr->MACNET_ADDRESS;
   /* If receive ISR flag is set and interrupt is unmasked */
	if (macnet_ptr->EIMR & (ENET_EIMR_RXB_MASK | ENET_EIMR_RXF_MASK))
	{
		MACNET_RX_ISR(enet);
	}
   /* If transmit ISR flag is set and interrupt is unmasked */
	if (macnet_ptr->EIMR & (ENET_EIMR_TXB_MASK | ENET_EIMR_TXF_MASK))
	{
		MACNET_TX_ISR(enet);
	}
}

#endif // PSP_MQX_CPU_IS_VYBRID

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_install_isrs
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

boolean MACNET_install_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr, MACNET_INIT_STRUCT const * enet_init_ptr  ) 
{
   boolean bOK;

#if PSP_MQX_CPU_IS_VYBRID
   bOK = MACNET_install_isr (enet_ptr, 0, ENET_INT_RX_TX, MACNET_RX_TX_ISR, enet_init_ptr->ETX_LEVEL, enet_init_ptr->ETX_SUBLEVEL);
#else
   bOK = MACNET_install_isr(enet_ptr, 0, ENET_INT_TX_INTB, MACNET_TX_ISR, enet_init_ptr->ETX_LEVEL,enet_init_ptr->ETX_SUBLEVEL  ) ;
   
   if (bOK) {
      bOK = MACNET_install_isr(enet_ptr, 1, ENET_INT_TX_INTF, MACNET_TX_ISR, enet_init_ptr->ETX_LEVEL,enet_init_ptr->ETX_SUBLEVEL  ) ;
   }
   if (bOK) {
      bOK = MACNET_install_isr(enet_ptr, 2, ENET_INT_RX_INTB, MACNET_RX_ISR, enet_init_ptr->ERX_LEVEL,enet_init_ptr->ERX_SUBLEVEL  ) ;
   }
   if (bOK) {
      bOK = MACNET_install_isr(enet_ptr, 3, ENET_INT_RX_INTF, MACNET_RX_ISR, enet_init_ptr->ERX_LEVEL,enet_init_ptr->ERX_SUBLEVEL  ) ;
   }
#endif // PSP_MQX_CPU_IS_VYBRID
#if ENETCFG_SUPPORT_PTP
   if (bOK) {
      bOK = MACNET_ptp_install_ts_avail_isr(enet_ptr, enet_init_ptr ) ;
   }
   /* Just one MACNET module handles 1588timer and incrementation of seconds */
   if (bOK && (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_MASTER_CLK)) {
      bOK = MACNET_ptp_install_ts_timer_isr(enet_ptr, enet_init_ptr ) ;
   }
#endif /* ENETCFG_SUPPORT_PTP */

   return bOK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_mask_interrupts
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

void MACNET_mask_interrupts( ENET_CONTEXT_STRUCT_PTR enet_ptr ) 
{
   uint_32  i;
   
   for (i = 0; i < ENET_NUM_INTS; i++)
   {
      _bsp_int_disable((PSP_INTERRUPT_TABLE_INDEX)(MACNET_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER,i)));
   }
}


#if BSPCFG_ENET_RESTORE

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_uninstall_isr
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

static void MACNET_uninstall_isr( ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 int_num, uint_32 int_index  ) 
{
   uint_32  vector = MACNET_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, int_index);
   MACNET_CONTEXT_STRUCT_PTR    macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
 
   _bsp_int_disable((PSP_INTERRUPT_TABLE_INDEX)vector);
   if (macnet_context_ptr->OLDISR_PTR[int_num]) 
   {
      _int_install_isr(vector, macnet_context_ptr->OLDISR_PTR[int_num], macnet_context_ptr->OLDISR_DATA[int_num]);
      macnet_context_ptr->OLDISR_PTR[int_num] = (INT_ISR_FPTR)NULL;
   }
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_uninstall_all_isrs
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

void MACNET_uninstall_all_isrs (ENET_CONTEXT_STRUCT_PTR enet_ptr) 
{
#if PSP_MQX_CPU_IS_VYBRID
   MACNET_uninstall_isr(enet_ptr, 0, ENET_INT_RX_TX);
#else
   MACNET_uninstall_isr(enet_ptr, 0, ENET_INT_TX_INTB);
   MACNET_uninstall_isr(enet_ptr, 1, ENET_INT_TX_INTF);
   MACNET_uninstall_isr(enet_ptr, 2, ENET_INT_RX_INTB);
   MACNET_uninstall_isr(enet_ptr, 3, ENET_INT_RX_INTF);
#endif // PSP_MQX_CPU_IS_VYBRID

}
#endif


/*FUNCTION*-------------------------------------------------------------
* 
* Function Name    : MACNET_get_vector
* Returned Value   : MQX vector number for specified interrupt
* Comments         :
*    This function returns index into MQX interrupt vector table for
*    specified enet interrupt. If not known, returns 0.
*
*END*-----------------------------------------------------------------*/


uint_32 MACNET_get_vector 
(
    uint_32 device,
    uint_32 vector_index
)
{ 
    uint_32 index = 0;

    if ((device < MACNET_DEVICE_COUNT) && (vector_index < ENET_NUM_INTS)) {
      index = MACNET_vectors[device][vector_index];
    }

    return index;
} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_free_context
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

void MACNET_free_context( MACNET_CONTEXT_STRUCT_PTR macnet_context_ptr ) 
{
   if (macnet_context_ptr) {
      if (macnet_context_ptr->UNALIGNED_BUFFERS) {
         _mem_free((pointer)macnet_context_ptr->UNALIGNED_BUFFERS);
      }
      if (macnet_context_ptr->RX_PCB_BASE) {
         _mem_free((pointer)macnet_context_ptr->RX_PCB_BASE);
      }
      if (macnet_context_ptr->TxPCBS_PTR) {
         _mem_free((pointer)macnet_context_ptr->TxPCBS_PTR);
      }
      if (macnet_context_ptr->UNALIGNED_RING_PTR) {
         _mem_free((pointer)macnet_context_ptr->UNALIGNED_RING_PTR);
      }
   
      _mem_free((pointer)macnet_context_ptr);
   }
}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_qpit.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: timer_qpit.h$
* $Version : 3.8.9.0$
* $Date    : Aug-9-2012$
*
* Comments:
*
*    This file contains definitions for the Qoriwa PIT Driver
*
*END***********************************************************************/

#ifndef __timer_qpit_h__
#define __timer_qpit_h__

#include "qpit.h"

#ifdef __cplusplus
extern "C" {
#endif


extern VQPIT_REG_STRUCT_PTR _bsp_get_qpit_base_address(uint_32 device);
extern PSP_INTERRUPT_TABLE_INDEX _bsp_get_qpit_vector(uint_32  device, uint_32 channel);
extern boolean _bsp_qpit_enable_access(uint_32 device);
extern void _bsp_qpit_clk_en (uint_32 timer);

extern uint_32 _qpit_timer_install(uint_32 device, uint_32 channel, uint_32 tickfreq, uint_32 clk, uint_32 priority, void (_CODE_PTR_ isr_ptr)(void *));
extern uint_32 _qpit_timer_install_kernel(uint_32 device, uint_32 channel, uint_32 tickfreq, uint_32 clk, uint_32 priority);
extern uint_32 _qpit_timer_stop(uint_32 device, uint_32 channel);


uint_32 _qpit_init_freq(uint_32, uint_32, uint_32, uint_32, boolean);
void _qpit_clear_int(uint_32, uint_32);
void _qpit_unmask_int(uint_32, uint_32);
void _qpit_mask_int(uint_32, uint_32);

#ifdef __cplusplus
}
#endif


#endif


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_search.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_search.c$
* $Version : 3.8.9.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains functions that search for specific directory entries
*   on the disk.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Find_directory_entry
* Returned Value   :  pointer to a directory entry
* Comments  :  Search the directory starting at start_cluster for an entry
*    with the name of filename satisfying the attributes specified.
*   IF file_ptr = NULL, it returns the first entry at clust/index.
*   If file_ptr = "", it returns the next empty or deleted entry.
*END*---------------------------------------------------------------------*/

MFS_DIR_ENTRY_PTR MFS_Find_directory_entry
    (
    MFS_DRIVE_STRUCT_PTR  drive_ptr,            /*[IN] drive context */
    char_ptr              file_ptr,             /*[IN] specific name to search for, if NULL then first dir entry */
    uint_32_ptr           start_cluster_ptr,    /*[IN] start searching in this cluster
                                                **[OUT] set to the cluster number in which search was satisfied */
    uint_32_ptr           dir_index_ptr,        /*[IN] start searching at this directory entry
                                                **[OUT] if entry is found the index of the next entry is returned */
    uint_32_ptr           prev_cluster_ptr,     /* [IN] set to the cluster number previous to start_cluster
                                                ** [OUT] set to the cluster number previous to *dir_cluster_ptr */
    uchar                 attribute,            /*[IN] search attribute, as per Find_first_file */
    _mfs_error_ptr           error_ptr          /* The pointer carries the error infomation */
    )
{
    MFS_DIR_ENTRY_PTR     dir_entry_ptr = NULL;
    char_ptr              lfn_ptr = NULL;
    boolean               found;
    boolean               lfn_flag;
    boolean               maybe = FALSE;
    boolean               found_lfn = FALSE;
    uint_32               current_cluster, current_index;
    _mfs_error            error_code;
    uint_32               lfn_len = 0;  
    uint_16               entries_per_sector;
    uint_16               k, i;
    char                  lfn_entry[SFILENAME_SIZE + 1];
    char                  fs_file[SFILENAME_SIZE + 1]; 
    uint_32               prev_cluster = *prev_cluster_ptr; 
    uint_32               dirname = 0;


    error_code = MFS_NO_ERROR;

    entries_per_sector = drive_ptr->ENTRIES_PER_SECTOR;
    current_cluster = *start_cluster_ptr;
    current_index = *dir_index_ptr;

    found = FALSE;
    lfn_flag = FALSE;

    /* If the name is a LFN, it will be treated differently */
    if ( file_ptr && *file_ptr && !MFS_Dirname_valid(file_ptr) )
    {
        lfn_flag = TRUE;
        lfn_len = _strnlen(file_ptr, PATHNAME_SIZE);
        /* Get pointer to the begining of last block of 13 chars in string */
        lfn_ptr = file_ptr + ((lfn_len - 1) / 13) * 13;   
        maybe = TRUE;
        found_lfn = FALSE;
        /* We also need special treatement for a directory name */
        if ( attribute == (ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME) )
        {
            attribute = MFS_ATTR_LFN;
            dirname = 1;
        }
    }
    else if ( file_ptr && *file_ptr )
    {
        MFS_Expand_dotfile(file_ptr, fs_file);
    }
    /*
    ** Search in all clusters within this directory
    */

    do
    {
        /*
        ** Search in all sectors within this cluster
        */
        for ( k = (uint_16) INDEX_TO_SECTOR(current_index); 
            ((current_cluster == 0) || (k < drive_ptr->BPB.SECTORS_PER_CLUSTER)) && found == FALSE && current_cluster != CLUSTER_EOF;
            k++ )
        {
            dir_entry_ptr = MFS_Read_directory_sector(drive_ptr,current_cluster, k, &error_code);
            if ( dir_entry_ptr == NULL )
            {
                break;
            }

            /*
            ** Search in all entries within this sector
            */
            for ( i = (uint_16) INDEX_TO_OFFSET(current_index), dir_entry_ptr += i ; i < entries_per_sector && found == FALSE; i++ )
            {
                if ( *dir_entry_ptr->NAME == '\0' ) /* if NEVER USED entry */
                {
                    if ( file_ptr )      /* If not NULL                    */
                    {
                        if ( !*file_ptr )      /* but ""                         */
                        {
                            /* we found it */
                            found = TRUE;
                            break;
                        }
                    }
                    return(NULL);       /* Anyway, stop here-never used entry */
                                        /* if the entry is relevant at all    */

                }
                else if ( (uchar) *dir_entry_ptr->NAME == MFS_DEL_FILE )
                {
                    /* If DELETED */ 
                    if ( file_ptr )      /* If not NULL   */
                    {
                        if ( !*file_ptr )      /* but ""  */
                        {
                            found = TRUE;       /* we found it  */
                            break;
                        }
                    }
                }
                else                        /* If REGULAR ENTRY */
                {
                    if ( file_ptr == NULL || *file_ptr )
                    {
                        if ( MFS_Attribute_match(dtohc(dir_entry_ptr->ATTRIBUTE), 
                            attribute) == TRUE )
                        {
                            if ( !file_ptr )
                            {
                                found = TRUE;
                                break;
                            }
                            else if ( lfn_flag ) /* Searching for a long name */
                            {
                                if ( found_lfn )
                                {
                                    found = TRUE;
                                    break;
                                }
                                if ( !MFS_Attribute_match(dtohc(dir_entry_ptr->ATTRIBUTE),
                                    MFS_ATTR_LFN) )
                                {
                                    maybe = TRUE; /* Reset maybe */
                                    dir_entry_ptr++;
                                    current_index++;
                                    continue;   /* Not an LFN entry, skip it */ 
                                }
                                if ( !maybe )
                                {
                                    dir_entry_ptr++;
                                    current_index++;
                                    continue;
                                }

                                MFS_lfn_extract((MFS_LNAME_ENTRY_PTR)dir_entry_ptr, lfn_entry);
                                if ( strncmp(lfn_entry, lfn_ptr, 13) )
                                {
                                    lfn_ptr = file_ptr + ((lfn_len - 1) / 13) * 13; /* reset ptr */
                                    maybe = FALSE;
                                    dir_entry_ptr++;
                                    current_index++;
                                    continue; /* Strings don't match */
                                }
                                if ( lfn_ptr > file_ptr )
                                {
                                    lfn_ptr -= 13;
                                }
                                else if ( lfn_ptr == file_ptr )
                                {
                                    /* We found the name. The next entry contains the file info */
                                    found_lfn = TRUE;
                                    if ( dirname )
                                    {
                                        attribute = ATTR_EXCLUSIVE | MFS_ATTR_DIR_NAME; 
                                    }
                                }
                                else
                                {
                                    /* Pointer is a begining of string, and no match */
                                    maybe = FALSE;
                                    lfn_ptr = file_ptr + ((lfn_len - 1) / 13) * 13; /* reset ptr */
                                }                            
                            }
                            else /* Searching for a short name */
                            {
                                found = MFS_Wildcard_match(fs_file, dir_entry_ptr->NAME);
                            }  
                        }
                        else
                        {
                            if ( lfn_flag )
                            {
                                attribute = MFS_ATTR_LFN;
                                lfn_ptr = file_ptr + ((lfn_len - 1) / 13) * 13; /* reset ptr */
                                maybe = TRUE;
                                found_lfn = FALSE;
                            }
                        }  
                    }
                }  

                if ( found == FALSE )
                {
                    dir_entry_ptr++;
                    current_index++;
                }
            }  
        }  

        if ( found == FALSE )
        {
            error_code = MFS_Increment_dir_index(drive_ptr, &current_cluster, &current_index, &prev_cluster); 
            if ( error_code )
            {
                break;
            }
        }

    } while ( found == FALSE && dir_entry_ptr && current_cluster != CLUSTER_EOF && current_cluster != CLUSTER_INVALID );

    if ( found == FALSE )
    {
        dir_entry_ptr      = NULL;
    }
    else
    {
        *start_cluster_ptr = current_cluster;
        *prev_cluster_ptr = prev_cluster;  
        *dir_index_ptr = current_index;
    }  

    if ( error_ptr )
    {
        *error_ptr = error_code;
    }

    return(dir_entry_ptr);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Find_directory
* Returned Value   :  starting_cluster of the specified directory
* Comments  :  Search through the file structure to find the specified
*  directory.  Will search either from the current directory or from the
*  root directory.  Returns the starting cluster number of the specified
*  directory.  If the specified directory cannot be found, then 
*  CLUSTER_INVALID  is returned.
*
*END*---------------------------------------------------------------------*/
uint_32 MFS_Find_directory
    (
    MFS_DRIVE_STRUCT_PTR  drive_ptr,    /*[IN] drive context */
    char_ptr              path_ptr,     /*[IN] specific directory to search for */
    uint_32               first_cluster /*[IN] start searching in this cluster, used for a relative search*/
    )
{
    MFS_DIR_ENTRY_PTR     dir_entry_ptr;
    char_ptr              directory;
    uint_32               current_cluster;
    uint_32               dir_index;
    _mfs_error            error_code;
    boolean               flag;
    uint_32               prev_cluster = CLUSTER_INVALID; 
    uchar                 attribute;


    if ( MFS_alloc_path(&directory)!= MFS_NO_ERROR )
    {
        return( CLUSTER_INVALID );
    }

    if ( *path_ptr == '\\' || *path_ptr == '/' )
    {
        current_cluster = ROOT_CLUSTER(drive_ptr);
        path_ptr++;
    }
    else
    {
        current_cluster = first_cluster;
    }  

    while ( path_ptr )
    {
        if ( *path_ptr )
        {
            path_ptr = MFS_Parse_next_filename(path_ptr, directory);

            if ( !MFS_lfn_dirname_valid(directory) )
            {
                current_cluster = CLUSTER_INVALID;
                break;
            }

            flag = FALSE;
            if ( current_cluster == 0 )  flag = TRUE;
            if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
            {
                if ( current_cluster == drive_ptr->BPB32.ROOT_CLUSTER )
                {
                    flag = TRUE;
                }
            }

            if ( flag )
            {
                /*
                ** Special treatment for '.' and '..' in root directory
                */
                dir_index = MFS_Is_dot_directory(directory);
                if ( dir_index == 1 )
                {
                    /* Return the value of the root cluster */
                    MFS_free_path(directory);
                    return ROOT_CLUSTER(drive_ptr);
                }
                else if ( dir_index == 2 )
                {
                    MFS_free_path(directory);
                    return(CLUSTER_INVALID);
                }
            }

            dir_index = 0;

            dir_entry_ptr = MFS_Find_directory_entry( drive_ptr, directory,
                &current_cluster, &dir_index,  &prev_cluster, (~ATTR_EXCLUSIVE),  
                &error_code);

            if ( dir_entry_ptr == NULL )
            {
                current_cluster = CLUSTER_INVALID;
                break;
            }
            else
            {
                attribute = dtohc(dir_entry_ptr->ATTRIBUTE);

                if ( attribute & MFS_ATTR_DIR_NAME )
                {
                    current_cluster = clustoh(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER);
                    if ( current_cluster == 0 && drive_ptr->FAT_TYPE == MFS_FAT32 )
                    {
                        current_cluster = drive_ptr->BPB32.ROOT_CLUSTER;
                    }
                }
                else
                {
                    // Found an entry, but it is not a directory
                    MFS_free_path(directory);
                    return(CLUSTER_INVALID);
                }
            }  
        }
        else
        {
            break;
        }  
    }  
    MFS_free_path(directory);

    return(current_cluster);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Find_entry_on_disk
* Returned Value   : pointer to the entry's MFS_DIR_ENTRY in the
*                    sector_buffer
* Comments  :  Find an entry anywhere on disk (exact filename).
*
*END*---------------------------------------------------------------------*/

MFS_DIR_ENTRY_PTR MFS_Find_entry_on_disk
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,          /*[IN] drive context */
    char _PTR_              pathname,           /*[IN] pathname of the file */
    _mfs_error_ptr             error_ptr,       /*[IN/OUT] resulting error code is written to this address*/
    uint_32_ptr             dir_cluster_ptr,    /*[OUT] the cluster in which the dir entry is located */
    uint_32_ptr             dir_index_ptr,      /*[OUT] the index within the dir cluster where the entry is located */
    uint_32_ptr             prev_cluster_ptr    /*[OUT] the cluster previous to dir cluster */    
    )
{
    MFS_DIR_ENTRY_PTR    dir_entry_ptr;
    char_ptr             temp_dirname;
    char_ptr             temp_filename;
    uint_32              first_cluster;

    *error_ptr = MFS_alloc_2paths(&temp_dirname,&temp_filename);
    if ( *error_ptr != MFS_NO_ERROR )
    {
        return( NULL );
    }

    *error_ptr = MFS_NO_ERROR;
    dir_entry_ptr = NULL;

    if ( pathname )
    {
        MFS_Parse_pathname(temp_dirname, temp_filename, pathname);

        /*
        ** Is this a relative or an absolute file search ?
        */
        if ( *pathname == '\\' || *pathname == '/' )
        {
            first_cluster = ROOT_CLUSTER(drive_ptr);
        }
        else
        {
            first_cluster = drive_ptr->CUR_DIR_CLUSTER;
        }  

        /* first_cluster will now store the current_cluster # */
        first_cluster = MFS_Find_directory(drive_ptr, temp_dirname, first_cluster);
        *prev_cluster_ptr = CLUSTER_INVALID; 

        if ( first_cluster == CLUSTER_INVALID )
        {
            *error_ptr = MFS_PATH_NOT_FOUND;
        }
        else
        {
            *dir_index_ptr = 0;
            *dir_cluster_ptr = first_cluster;
            /*
            ** Checking for the superset of filename chars will allow
            ** finding something like \mydir\..
            */
            if ( !MFS_lfn_dirname_valid(temp_filename) )
            {
                dir_entry_ptr = NULL;
                *error_ptr = MFS_INVALID_PARAMETER;
            }
            else
            {
                dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, temp_filename,
                    dir_cluster_ptr, dir_index_ptr, prev_cluster_ptr, MFS_ATTR_ANY, error_ptr);  
                if ( dir_entry_ptr == NULL && !*error_ptr )
                {
                    *error_ptr = MFS_FILE_NOT_FOUND;
                }
            }  
        }  
    }
    else
    {
        *error_ptr = MFS_INVALID_PARAMETER;
    }  
    MFS_free_path(temp_dirname);
    MFS_free_path(temp_filename);

    return(dir_entry_ptr);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Find_next_slave
* Returned Value   : error_code
* Comments  :   Find the next file that matches the input criteria. Must
*    follow a Find_first_file and the search data block from the search
*    must be supplied.
*    This is called by find_first and find_next, and assumes the drive 
*    semaphore is obtained.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Find_next_slave
    (
    MFS_DRIVE_STRUCT_PTR  drive_ptr,    /*[IN] drive context */
    pointer   search_next_ptr           /*[IN] address of search data block indicating the current criteria and the results 
                                        ** of the last search results of this search are placed in this data block */
    )
{
    MFS_SEARCH_DATA_PTR        transfer_ptr;
    MFS_INTERNAL_SEARCH_PTR    internal_search_ptr;
    MFS_DIR_ENTRY_PTR          dir_entry_ptr;
    _mfs_error                 error_code;
    uint_32                    len;
    boolean                    found;
    boolean                    match_all;
    boolean                    eightdotthree = FALSE;
    char_ptr                   lfn;
    char                       sname[SFILENAME_SIZE+1]; 
    uint_32                    dotfile = 0;
    MFS_DIR_ENTRY  saved_dir_entry;  

    transfer_ptr = (MFS_SEARCH_DATA_PTR) search_next_ptr;
    error_code = MFS_NO_ERROR;
    found = FALSE;

    if ( transfer_ptr )
    {
        internal_search_ptr = &transfer_ptr->INTERNAL_SEARCH_DATA;

        if ( MFS_alloc_path(&lfn)!= MFS_NO_ERROR )
        {
            return MFS_INSUFFICIENT_MEMORY;
        }

        match_all = MFS_Check_search_string_for_all(internal_search_ptr->SRC_PTR);
        if ( !match_all )
        {
            dotfile = MFS_Is_dot_directory(internal_search_ptr->SRC_PTR);
            if ( dotfile == 0 )
            {
                eightdotthree = MFS_Check_search_string_for_8dot3( internal_search_ptr->SRC_PTR);
            }
        }
        do
        {
            dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &internal_search_ptr->CURRENT_CLUSTER, &internal_search_ptr->DIR_ENTRY_INDEX,
                &internal_search_ptr->PREV_CLUSTER, internal_search_ptr->ATTRIBUTE & (~ATTR_EXCLUSIVE), &error_code);

            if ( dir_entry_ptr == NULL && !error_code )
            {
                error_code = MFS_FILE_NOT_FOUND;
                break;
            }

            if ( internal_search_ptr->CURRENT_CLUSTER == CLUSTER_INVALID )
            {
                error_code = MFS_FILE_NOT_FOUND;
                break;
            }

            if ( dir_entry_ptr == NULL )
            {
                break;
            }
            saved_dir_entry=*dir_entry_ptr; 

            /* Make sure the entry is not an LFN entry */
            if ( *dir_entry_ptr->ATTRIBUTE != MFS_ATTR_LFN )
            {
                MFS_Compress_nondotfile (dir_entry_ptr->NAME, sname);

                if ( match_all )
                {
                    found = TRUE;
                }
                else
                {
                    if ( dotfile != 0 )
                    {
                        if ( dotfile == 1 )
                        {
                            found = internal_search_ptr->FULLNAME[0] == dir_entry_ptr->NAME[0];
                        }
                        else if ( dotfile == 2 )
                        {
                            found = (internal_search_ptr->FULLNAME[0] == dir_entry_ptr->NAME[0]) &&
                                    (internal_search_ptr->FULLNAME[1] == dir_entry_ptr->NAME[1]);
                        }
                        else
                        {
                            found = FALSE; /* This shouldn't happen */
                        }
                    }
                    else if ( eightdotthree )
                    {
                        found = MFS_Wildcard_match(internal_search_ptr->FILENAME, dir_entry_ptr->NAME);
                    }
                    else
                    {
                        if ( MFS_get_lfn_dir_cluster(drive_ptr, search_next_ptr, sname, lfn) == MFS_NO_ERROR )
                        {
                            found = MFS_lfn_match(internal_search_ptr->SRC_PTR, lfn, 0);
                        }
                        else
                        {
                            found = MFS_lfn_match(internal_search_ptr->SRC_PTR, sname, 0);
                        }  
                    }  
                }  
            }

            if ( !error_code )
            {
                error_code = MFS_Increment_dir_index(drive_ptr, &internal_search_ptr->CURRENT_CLUSTER,
                    &internal_search_ptr->DIR_ENTRY_INDEX, &internal_search_ptr->PREV_CLUSTER);  
            }

        } while ( (error_code == MFS_NO_ERROR) && (found  == FALSE) );

        if ( error_code == MFS_NO_ERROR )
        {
            transfer_ptr->ATTRIBUTE = dtohc(saved_dir_entry.ATTRIBUTE);
            transfer_ptr->TIME      = dtohs(saved_dir_entry.TIME);
            transfer_ptr->DATE      = dtohs(saved_dir_entry.DATE);
            transfer_ptr->FILE_SIZE = dtohl(saved_dir_entry.FILE_SIZE);

            /* Transfer the filename */
            len = _strnlen(sname,13);
            if ( sname[len-1] == '.' )
            {
                sname[len-1] = '\0';
            }
            strncpy(transfer_ptr->NAME, sname, 13);
        }

        MFS_free_path((pointer)lfn);
    }
    else
    {
        error_code = MFS_INVALID_MEMORY_BLOCK_ADDRESS;
    }  

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Check_search_string_all
* Returned Value   : boolean - TRUE if seach string indicates all files are
*    to be matched
* Comments  :   Examines the search string to see if all files are to be
*    matched.
*
*END*---------------------------------------------------------------------*/

boolean MFS_Check_search_string_for_all
    (
    char_ptr      search_ptr /*[IN] search string to check */
    )
{
    boolean need_star;
    char    c = *search_ptr;

    if ( (c != '*') && (c != '?') )
    {
        return FALSE;
    }

    need_star = (c == '?');

    while ( c )
    {
        if ( c == '*' )
        {
            need_star = FALSE;
        }
        else if ( c == '.' )
        {
            if ( need_star )
            {
                return FALSE;
            }
            need_star = TRUE;
        }
        else if ( c != '?' )
        {
            return FALSE;
        }
        search_ptr++;
        c = *search_ptr;
    }  

    return !need_star;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Check_search_string_8dot3
* Returned Value   : boolean - TRUE if seach string is an 8.3 string
* Comments  :   Examines the search string to see if it is an 8.3 string
*
*END*---------------------------------------------------------------------*/

boolean MFS_Check_search_string_for_8dot3
    (

    char_ptr      search_ptr    /*[IN] search string to check */
    )
{
    uint_32 namecount = 0;
    uint_32 typecount = 0;
    boolean dotfound  = FALSE;
    boolean starfound = FALSE;
    char    c         = *search_ptr;

    while ( c )
    {
        if ( c == '*' )
        {
            starfound = TRUE;
        }
        else if ( c == '.' )
        {
            if ( dotfound )
            {
                return FALSE;
            }
            dotfound  = TRUE;
            starfound = FALSE;
        }
        else if ( starfound )
        {
            return FALSE;
        }
        if ( dotfound )
        {
            typecount++;
            if ( typecount > 4 )
            {
                return FALSE;
            }
        }
        else
        {
            namecount++;
            if ( namecount > 8 )
            {
                return FALSE;
            }
        }  
        search_ptr++;
        c = *search_ptr;
    }  

    return TRUE;
}


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_attribute.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_attribute.c$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the file specific interface functions
*   of MFS which need a filename as an input parameter.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Get_file_attributes
* Returned Value   : error_code
* Comments  :   Get the attribute byte of the specified file.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Get_file_attributes
    (
    MQX_FILE_PTR            mfs_fd_ptr,     /*[IN] pathname of the file */
    char _PTR_              pathname,
    uchar_ptr               attribute_ptr
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    uint_32                 dir_cluster,dir_index;
    _mfs_error              error_code;
    uchar                   attribute;
    uint_32                 prev_cluster= CLUSTER_INVALID; 


    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        return MFS_INVALID_PARAMETER;
    }

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        return(error_code);
    }

    dir_entry_ptr = MFS_Find_entry_on_disk(drive_ptr, pathname, &error_code, &dir_cluster, &dir_index, &prev_cluster);  

    /*
    ** When a function locks MFS device, on any error it should not return 
    ** without unlocking it. This can create a deadlock.
    */   
    if ( error_code == MFS_NO_ERROR )
    {
        attribute = dtohc(dir_entry_ptr->ATTRIBUTE);
        *attribute_ptr = attribute;
    }

    MFS_unlock(drive_ptr,FALSE);
    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Set_file_attributes
* Returned Value   : error code
* Comments  :   Change the attribute of the specified file.
*
*END*---------------------------------------------------------------------*/
#if !MFSCFG_READ_ONLY
_mfs_error MFS_Set_file_attributes
    (
    MQX_FILE_PTR            mfs_fd_ptr,  
    char _PTR_              pathname,       /*[IN] pathname of the specific file */
    uchar_ptr               attribute_ptr   /*[IN] attribute of file */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    _mfs_error              error_code;
    uint_32                 dir_cluster, dir_index;
    uchar                   at, attrib;
    uint_32                 prev_cluster= CLUSTER_INVALID; 

    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        return MFS_INVALID_PARAMETER;
    }

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }
    attrib = *attribute_ptr;
    attrib &= MFS_ATTR_ARCHIVE | MFS_ATTR_READ_ONLY | MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE;
    dir_entry_ptr = MFS_Find_entry_on_disk(drive_ptr, pathname, &error_code, &dir_cluster, &dir_index, &prev_cluster);  
    if ( error_code == MFS_NO_ERROR )
    {
        at = dtohc(dir_entry_ptr->ATTRIBUTE);
        if ( at != *attribute_ptr )
        {
            /*
            ** The volume-label and the directory-name are mutually exclusive.
            ** The volume-label cannot act as a directory-name. Check whether
            ** you are trying to set the attributes to a volume.
            */
            if ( ! ((at & MFS_ATTR_VOLUME_NAME) || (*attribute_ptr & MFS_ATTR_VOLUME_NAME)) )
            {
                htodc(dir_entry_ptr->ATTRIBUTE, *attribute_ptr);
                drive_ptr->DIR_SECTOR_DIRTY = TRUE;
            }
            else
            {
                error_code = MFS_ACCESS_DENIED;
            }  
        }
    }

    MFS_unlock(drive_ptr,TRUE);

    return(error_code);
}  
#endif



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/telnetio.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: telnetio.c$
* $Version : 3.8.14.3$
* $Date    : May-30-2012$
*
* Comments:
*
*   This file contains the implementation of an MQX
*   telnet I/O device.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include <serial.h>
#include "telnet.h"

#define CRLF_MODE(io_ptr)        (io_ptr->TERMINAL_OPTIONS & TEROPT_CRLF_MODE)
#define RAW_MODE(io_ptr)         (io_ptr->TERMINAL_OPTIONS & TEROPT_RAW_MODE)

typedef struct io_telnet {
    MQX_FILE_PTR  NETWORK_FD;
    MQX_FILE_PTR  CONSOLE_FD;
    uchar         REMOTE_OPTIONS[TELNET_MAX_OPTS];
    uchar         LOCAL_OPTIONS[TELNET_MAX_OPTS];
    uint_32       TERMINAL_OPTIONS;
    uint_32       FLAGS;
    int_32        STATE;
} IO_TELNET, _PTR_ IO_TELNET_PTR;


_mqx_int _io_telnet_open  (MQX_FILE_PTR, char _PTR_,  char _PTR_);
_mqx_int _io_telnet_close (MQX_FILE_PTR);
_mqx_int _io_telnet_read  (MQX_FILE_PTR, char _PTR_, _mqx_int);
_mqx_int _io_telnet_write (MQX_FILE_PTR, char _PTR_, _mqx_int);
_mqx_int _io_telnet_ioctl (MQX_FILE_PTR, _mqx_uint, pointer);

_mqx_int _io_telnet_process_char (char _PTR_, MQX_FILE_PTR);
boolean _io_telnet_echo(IO_TELNET_PTR io_ptr, char c);

/*
** Telnet Response strings
*/

static _mqx_int TELNET_go_ahead(MQX_FILE_PTR fd) {
    char buf[] = {TELCMD_IAC, TELCMD_GA};
    return _io_write(fd, buf, 2);
}

static _mqx_int TELNET_will(MQX_FILE_PTR fd, char c) {
    char buf[3] = {TELCMD_IAC, TELCMD_WILL};
    buf[2] = c;
    return _io_write(fd, buf, 3);
}

static _mqx_int TELNET_wont(MQX_FILE_PTR fd, char c) {
    char buf[3] = {TELCMD_IAC, TELCMD_WONT};
    buf[2] = c;
    return _io_write(fd, buf, 3);

}

static _mqx_int TELNET_do(MQX_FILE_PTR fd, char c) {
    char buf[3] = {TELCMD_IAC, TELCMD_DO};
    buf[2] = c;
    return _io_write(fd, buf, 3);
}

static _mqx_int TELNET_dont(MQX_FILE_PTR fd, char c) {
    char buf[3] = {TELCMD_IAC, TELCMD_DONT};
    buf[2] = c;
    return _io_write(fd, buf, 3);
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_telnet_install
* Returned Value : int_32 a task error code or MQX_OK
* Comments       : Install the telnet device
*
*END*-----------------------------------------------------------------*/

int_32 _io_telnet_install
   (
      char_ptr identifier
   )
{ /* Body */

   return _io_dev_install(identifier,
                          _io_telnet_open,
                          _io_telnet_close,
                          _io_telnet_read,
                          _io_telnet_write,
#if MQX_VERSION < 250
                          (int_32(_CODE_PTR_)(MQX_FILE_PTR, uint_32, uint_32_ptr))
#endif
                          _io_telnet_ioctl,
                          NULL );
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_telnet_open
* Returned Value : int_32 a task error code or MQX_OK
* Comments       : Open the telnet device
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_telnet_open
   (
      MQX_FILE_PTR fd_ptr,
      char _PTR_ open_name_ptr,
      char _PTR_ flags_ptr
   )
{ /* Body */
   IO_TELNET_PTR io_ptr;

   io_ptr = RTCS_mem_alloc_zero(sizeof(*io_ptr));
   if (io_ptr == NULL) {
      return MQX_OUT_OF_MEMORY;
   } /* Endif */

   _mem_set_type(io_ptr, MEM_TYPE_IO_TELNET);

   fd_ptr->DEV_DATA_PTR = io_ptr;

   io_ptr->NETWORK_FD = (MQX_FILE_PTR)flags_ptr;
   io_ptr->CONSOLE_FD = NULL;
#ifdef __MQX__
   fd_ptr->FLAGS = IO_SERIAL_ECHO;  /* To work around a bug in fgetline() */
#endif

   io_ptr->TERMINAL_OPTIONS = TEROPT_CRLF_MODE;

   /*
   ** Send WILL SGA and DO SGA options
   */
   TELNET_will (io_ptr->NETWORK_FD, TELOPT_SGA);
   TELNET_do   (io_ptr->NETWORK_FD, TELOPT_SGA);

   return MQX_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  :  _io_telnet_close
* Returned Value :  int_32 Error Code
* Comments       :  Close the telnet device
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_telnet_close
   (
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */
   IO_TELNET_PTR  io_ptr;
   _mqx_uint      flags;

   io_ptr = fd_ptr->DEV_DATA_PTR;
   if (io_ptr != NULL) {

      /* Reenable local echo */
      if (io_ptr->CONSOLE_FD) {
         ioctl(io_ptr->CONSOLE_FD, IO_IOCTL_SERIAL_GET_FLAGS, &flags);
         flags |= IO_SERIAL_ECHO;
         ioctl(io_ptr->CONSOLE_FD, IO_IOCTL_SERIAL_SET_FLAGS, &flags);
      } /* Endif */

      _mem_free(io_ptr);
      fd_ptr->DEV_DATA_PTR = NULL;
   } /* Endif */

   return MQX_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  :  _io_telnet_read
* Returned Value :  Number of characters read
* Comments       :  Read data from the Telnet device
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_telnet_read
   (
      MQX_FILE_PTR fd_ptr,
      char _PTR_  data_ptr,
      _mqx_int    num
   )
{ /* Body */
   IO_TELNET_PTR  io_ptr;
   _mqx_int       count, read_count, write_count, ret;
   char_ptr       read_ptr, write_ptr;
   char           c;

   io_ptr = fd_ptr->DEV_DATA_PTR;

   write_ptr = data_ptr;
   write_count = 0;
   for (;;) {

      read_ptr = write_ptr;
      count = _io_read(io_ptr->NETWORK_FD, read_ptr, num-write_count);
      if (count == IO_EOF) {
         return IO_EOF;
      } /* Endif */

      for (read_count = 0; read_count < count; read_count++) {
         c = *read_ptr++;
         if ((ret = _io_telnet_process_char(&c, fd_ptr)) == IO_ERROR) {
             return ret;
         } else if (ret) {
            *write_ptr++ = c;
            write_count++;
         } /* Endif */
      } /* Endfor */

      if (write_count >= num) {
         break;
      } /* Endif */
      if (write_count && !_io_fstatus(io_ptr->NETWORK_FD)) {
         break;
      } /* Endif */

   } /* Endfor */

   return write_count;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_telnet_write
* Returned Value : Number of characters written
* Comments       : Writes the data to the Telnet device
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_telnet_write
   (
      MQX_FILE_PTR fd_ptr,
      char _PTR_  data_ptr,
      _mqx_int    num
   )
 { /* Body */
    IO_TELNET_PTR io_ptr;
    _mqx_int count;
    _mqx_int towrite = 0;
    char_ptr scan_ptr;

    io_ptr = fd_ptr->DEV_DATA_PTR;
    for (count = 0, scan_ptr = data_ptr; count < num; count++, scan_ptr++) {
        //transmitting data in real binary mode and avoiding workarounds
        //in handling EOLs (different CR LF combinations) valid only for character based terminals
        if (RAW_MODE(io_ptr)) {
            if (io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) {
                if (*scan_ptr == TELCMD_IAC) {
                    if (fputc(TELCMD_IAC, io_ptr->NETWORK_FD) == IO_EOF) {
                        return count;
                    }
                    if (fputc(TELCMD_IAC, io_ptr->NETWORK_FD) == IO_EOF) {
                        return count;
                    }
                } else {
                    if (fputc(*scan_ptr, io_ptr->NETWORK_FD) == IO_EOF) {
                        return count;
                    }
                }
            } else { //sending binary data to ASCII remote end should never happen
                return IO_ERROR;
            }
            continue;
        }

        //handle transmissions for character based terminals including CR LF workarounds
        switch (*scan_ptr) {
            case TELCMD_IAC:
            if (io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) {
                if (fputc(TELCMD_IAC, io_ptr->NETWORK_FD) == IO_EOF) {
                    return count;
                }
                if (fputc(TELCMD_IAC, io_ptr->NETWORK_FD) == IO_EOF) {
                    return count;
                }
            } // else character is not valid USASCII so filter it
            break;

            case TELCC_LF:
                if (fputc(TELCC_CR, io_ptr->NETWORK_FD) == IO_EOF) {
                    return count;
                }
                if (io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) {
                    if (fputc(TELCC_LF, io_ptr->NETWORK_FD) == IO_EOF) {
                        return count;
                    }
                } else if (CRLF_MODE(io_ptr)) {//in ascii mode CR should be followed by either NULL or LF
                    if (fputc(TELCC_LF, io_ptr->NETWORK_FD) == IO_EOF) {
                        return count;
                    }
                } else {
                    if (fputc(TELCC_NULL, io_ptr->NETWORK_FD) == IO_EOF) {
                        return count;
                    }
                }
                break;

            case TELCC_CR:
                //in character based terminal in CRLF mode is possible to transmit stand-alone CRs
                if (CRLF_MODE(io_ptr) && !RAW_MODE(io_ptr)) {
                    if ((count < num) && (*(scan_ptr + 1) != TELCC_LF)) {
                        if (fputc(TELCC_CR, io_ptr->NETWORK_FD) == IO_EOF) {
                            return count;
                        }
                        if (fputc(TELCC_NULL, io_ptr->NETWORK_FD) == IO_EOF) {
                            return count;
                        }
                    }
                }
                break;

            default:
                if (io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) {
                    if (fputc(*scan_ptr, io_ptr->NETWORK_FD) == IO_EOF) {
                        return count;
                    }
                } else if (!(*scan_ptr & 0x80)) {
                    if (fputc(*scan_ptr, io_ptr->NETWORK_FD) == IO_EOF) {
                        return count;
                    }
                } //else filter it
                break;
        }
    }

    return count;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_telnet_ioctl
* Returned Value : int_32
* Comments       : Returns result of ioctl operation.
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_telnet_ioctl
   (
      MQX_FILE_PTR fd_ptr,
      _mqx_uint   cmd,
      pointer     param_ptr
   )
{ /* Body */
   IO_TELNET_PTR  io_ptr;
   int_32         result;
   _mqx_uint      flags;
   int_32         rawc;
   char           c;

   result = IO_ERROR;
   io_ptr = (IO_TELNET_PTR) fd_ptr->DEV_DATA_PTR;

   if (io_ptr == NULL) {
      return (_mqx_int)result;
   } /* Endif */

   switch (cmd) {

   case IO_IOCTL_CHAR_AVAIL:

      while (1) {
         *(boolean _PTR_)param_ptr = fstatus(io_ptr->NETWORK_FD);
         if (!*(boolean _PTR_)param_ptr) {
            break;
         } /* Endif */
         rawc = (int_32)fgetc(io_ptr->NETWORK_FD);
         if (rawc == IO_EOF) {
            break;
         } /* Endif */
         c = (char)rawc;
         result = _io_telnet_process_char(&c, fd_ptr);
         if (result == IO_ERROR) {
             return result;
         } else if (result) {
            fungetc(c, fd_ptr);
            break;
         } /* Endif */
      } /* Endwhile */
      result = MQX_OK;
      break;

   case IO_IOCTL_SET_STREAM:
      io_ptr->CONSOLE_FD = (MQX_FILE_PTR)param_ptr;

      /* Clear or set echoing by server */
      if (io_ptr->REMOTE_OPTIONS[TELOPT_ECHO])
      {
        ioctl(io_ptr->CONSOLE_FD, IO_IOCTL_SERIAL_GET_FLAGS, &flags);
        flags &= ~IO_SERIAL_ECHO;
        ioctl(io_ptr->CONSOLE_FD, IO_IOCTL_SERIAL_SET_FLAGS, &flags);
      } /* Endif */

      result = MQX_OK;
      break;

   case IO_IOCTL_SERIAL_GET_FLAGS:
      *(_mqx_uint_ptr)param_ptr = io_ptr->FLAGS;
      result = MQX_OK;
      break;

   case IO_IOCTL_SERIAL_SET_FLAGS:
      io_ptr->FLAGS = *(_mqx_uint_ptr)param_ptr;
      /* Handle defaults */

      /* Echo */
      if (!io_ptr->LOCAL_OPTIONS[TELOPT_ECHO] && io_ptr->REMOTE_OPTIONS[TELOPT_ECHO])
      {
        TELNET_dont(io_ptr->NETWORK_FD, TELOPT_ECHO);
      } /* Endif */

      if (io_ptr->FLAGS & IO_SERIAL_ECHO)
      {
        TELNET_will(io_ptr->NETWORK_FD, TELOPT_ECHO);
      }
      else
      {
        TELNET_dont(io_ptr->NETWORK_FD, TELOPT_ECHO);
      }

      /* Binary mode */
      if (!io_ptr->LOCAL_OPTIONS[TELOPT_BINARY]) { //inbinary
          TELNET_will(io_ptr->NETWORK_FD, TELOPT_BINARY);
      }
      if (!io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) { //outbinary
          TELNET_do(io_ptr->NETWORK_FD, TELOPT_BINARY);
      }
      result = MQX_OK;
      break;

   case IO_IOCTL_SET_ECHO:
       break;

   case IO_IOCTL_GET_ECHO:
       break;

   case IO_IOCTL_SET_INBINARY:
       if (!io_ptr->LOCAL_OPTIONS[TELOPT_BINARY]) { //inbinary
           TELNET_will(io_ptr->NETWORK_FD, TELOPT_BINARY);
           *(boolean _PTR_)param_ptr = TRUE;
       } else {
           *(boolean _PTR_)param_ptr = FALSE;
       }
       result = MQX_OK;
       break;

   case IO_IOCTL_GET_INBINARY:
       *(boolean _PTR_)param_ptr = io_ptr->LOCAL_OPTIONS[TELOPT_BINARY];
       result = MQX_OK;
       break;

   case IO_IOCTL_SET_OUTBINARY:
       if (!io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) { //outbinary
           TELNET_do(io_ptr->NETWORK_FD, TELOPT_BINARY);
           *(boolean _PTR_)param_ptr = TRUE;
       } else {
           *(boolean _PTR_)param_ptr = FALSE;
       }
       result = MQX_OK;
       break;

   case IO_IOCTL_GET_OUTBINARY:
       *(boolean _PTR_)param_ptr = io_ptr->REMOTE_OPTIONS[TELOPT_BINARY];
       result = MQX_OK;
       break;

   case IO_IOCTL_SET_BINARY:
       *(boolean _PTR_)param_ptr = FALSE;
       if (!io_ptr->LOCAL_OPTIONS[TELOPT_BINARY]) { //inbinary
           TELNET_will(io_ptr->NETWORK_FD, TELOPT_BINARY);
           *(boolean _PTR_)param_ptr = TRUE;
       }
       if (!io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) { //outbinary
           TELNET_do(io_ptr->NETWORK_FD, TELOPT_BINARY);
           *(boolean _PTR_)param_ptr = TRUE;
       }
       result = MQX_OK;
       break;

   case IO_IOCTL_GET_BINARY:
       *(boolean _PTR_)param_ptr = io_ptr->LOCAL_OPTIONS[TELOPT_BINARY] && io_ptr->REMOTE_OPTIONS[TELOPT_BINARY];
       result = MQX_OK;
       break;

   case IO_IOCTL_SET_CRLF:
       if (*(boolean _PTR_)param_ptr) {
           io_ptr->TERMINAL_OPTIONS |= TEROPT_CRLF_MODE;
       } else {
           io_ptr->TERMINAL_OPTIONS &= ~TEROPT_CRLF_MODE;
       }
       result = MQX_OK;
       break;

   case IO_IOCTL_GET_CRLF:
       *(boolean _PTR_)param_ptr = (io_ptr->TERMINAL_OPTIONS & TEROPT_CRLF_MODE) > 0;
       result = MQX_OK;
       break;

   case IO_IOCTL_SET_RAW:
       if (*(boolean _PTR_)param_ptr) {
           io_ptr->TERMINAL_OPTIONS |= TEROPT_RAW_MODE;
       } else {
           io_ptr->TERMINAL_OPTIONS &= ~TEROPT_RAW_MODE;
       }
       result = MQX_OK;
       break;

   case IO_IOCTL_GET_RAW:
       *(boolean _PTR_)param_ptr = (io_ptr->TERMINAL_OPTIONS & TEROPT_RAW_MODE) > 0;
       result = MQX_OK;
       break;

   case IO_IOCTL_FLUSH_OUTPUT:
      result =ioctl(io_ptr->NETWORK_FD, IO_IOCTL_FLUSH_OUTPUT, param_ptr);
      break;

   } /* Endswitch */

   return (_mqx_int)result;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_telnet_echo
* Returned Value : TRUE when character was successfully echoed, FALSE otherwise
* Comments       : Echoes given character if server echo is set
*
*
*END*-----------------------------------------------------------------*/
boolean _io_telnet_echo(IO_TELNET_PTR io_ptr, char c) {
    //echoing received character
    if (io_ptr->LOCAL_OPTIONS[TELOPT_ECHO]) {
        if (c == '\b') {
            fputs("\b ", io_ptr->NETWORK_FD);
        } /* Endif */
        if (fputc(c, io_ptr->NETWORK_FD) != c) {
            return FALSE;
        }
        fflush(io_ptr->NETWORK_FD);
        return TRUE;
    } /* Endif */
    return FALSE;
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_telnet_process_char
* Returned Value : IO_ERROR, TRUE or FALSE
* Comments       : process the arrived characters, including negotiated options
*       TRUE is returned when valid ASCII character has been processed.
*       FALSE is returned for either IAC, commands or CR which should be combined
*       with next character.
*       IO_ERROR is returned when received bytes doesn't follow RFC 854, i.e. CR
*       followed neither by LF nor by NULL.
*
*END*-----------------------------------------------------------------*/
_mqx_int _io_telnet_process_char
   (
      char _PTR_  cp,
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */
   char           c = *cp;
   _mqx_uint      flags;
   IO_TELNET_PTR  io_ptr;
   MQX_FILE_PTR   console_stream;

   io_ptr = fd_ptr->DEV_DATA_PTR;
   console_stream = io_ptr->CONSOLE_FD;

   switch (io_ptr->STATE) {

   case 0: /* Start state */
        //receiving data in real binary mode so avoiding workarounds
        //in handling EOLs (different CR LF combinations) valid only for character based terminals
        if (RAW_MODE(io_ptr) && io_ptr->LOCAL_OPTIONS[TELOPT_BINARY]) {
            switch (c) {
            case TELCMD_IAC:
                io_ptr->STATE = 1;
                return FALSE;
            default:
                if (io_ptr->REMOTE_OPTIONS[TELOPT_BINARY] || !(c & 0x80)) {
                    _io_telnet_echo(io_ptr, c);
                    return TRUE;
                } else {
                    return FALSE; //filter character
                }
            }
        }

        if (io_ptr->LOCAL_OPTIONS[TELOPT_BINARY]) { //receiving in binary mode
            switch (c) {
            case TELCMD_IAC:
                io_ptr->STATE = 1;
                return FALSE;
            case TELCC_CR:
                _io_telnet_echo(io_ptr, c);
                _io_telnet_echo(io_ptr, TELCC_LF);
                *cp = TELCC_LF; //application character mapping to LF
                return TRUE;
            default:
                if (io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) {
                    //strip extra LF because in binary mode each CR is echoed as CR LF
                    if (!CRLF_MODE(io_ptr) || (CRLF_MODE(io_ptr) && (c != TELCC_LF))) {
                        _io_telnet_echo(io_ptr, c);
                    } else {
                        return FALSE;
                    }
                } else if (c & 80) { //remote end is in ASCII mode but we have illegal data to send
                    return FALSE;
                } else {
                    _io_telnet_echo(io_ptr, c);
                }
                return TRUE;
            }
        } else { //ASCII mode
            switch (c) {
            case TELCMD_IAC:
                io_ptr->STATE = 1;
                return FALSE;
            case TELCC_CR:
                _io_telnet_echo(io_ptr, c);
                io_ptr->STATE = 6;
                return FALSE;
            default:
                if (c & 0x80) { //in ASCII only USASCII codes could be send
                    return FALSE;
                } else {
                    _io_telnet_echo(io_ptr, c);
                    return TRUE;
                }
            }
        }

      /* Start SPR P122-0266-33 remove all warnings from RTCS code. */
      /* break; */
      /* End SPR P122-0266-33. */
   case 1: /* IAC */
      switch (c) {

      case TELCMD_AYT:
         /*
         ** Request to send a string to prove we're alive.
         ** Send back comforting message.
         */
         fputs("\nRTCS Telnet server online.\n", fd_ptr);
         io_ptr->STATE = 0;
         return FALSE;

      case TELCMD_EC:
         /*
         ** Request to erase the last character before this command.
         */
         *cp = '\b';
         io_ptr->STATE = 0;
         return TRUE;

      case TELCMD_WILL:
         io_ptr->STATE = 2;
         return FALSE;

      case TELCMD_DO:
         io_ptr->STATE = 3;
         return FALSE;

      case TELCMD_WONT:
         io_ptr->STATE = 4;
         return FALSE;

      case TELCMD_DONT:
         io_ptr->STATE = 5;
         return FALSE;

      case TELCMD_IAC:
        /* Second IAC is not interpreted as command, it's data */
        if (io_ptr->LOCAL_OPTIONS[TELOPT_BINARY] && io_ptr->REMOTE_OPTIONS[TELOPT_BINARY]) { //BINARY mode
            _io_telnet_echo(io_ptr, TELCMD_IAC);
            _io_telnet_echo(io_ptr, TELCMD_IAC);
            io_ptr->STATE = 0;
            return TRUE;
        } //else filter it (continue with default state)

      default:
         /* Ignore all other telnet commands (e.g GA) */
         io_ptr->STATE = 0;
         return FALSE;
      } /* Endswitch */

   case 2: /* IAC WILL */
      switch (c) {

      case TELOPT_ECHO:
        if (!io_ptr->REMOTE_OPTIONS[TELOPT_ECHO])
        {
          if ((io_ptr->LOCAL_OPTIONS[TELOPT_ECHO]) || !(io_ptr->FLAGS & IO_SERIAL_ECHO))
          {
            TELNET_dont(io_ptr->NETWORK_FD, TELOPT_ECHO);
          }
          else
          {
            /* Clear the echo bit */
            ioctl(console_stream, IO_IOCTL_SERIAL_GET_FLAGS, &flags);
            flags &= ~IO_SERIAL_ECHO;
            ioctl(console_stream, IO_IOCTL_SERIAL_SET_FLAGS, &flags);
            io_ptr->REMOTE_OPTIONS[TELOPT_ECHO] = TRUE;
            TELNET_do(io_ptr->NETWORK_FD, TELOPT_ECHO);
          } /* Endif */
        } /* Endif */
        else if (!(io_ptr->FLAGS & IO_SERIAL_ECHO))
        {
          TELNET_dont(io_ptr->NETWORK_FD, TELOPT_ECHO);
        }
        break;

      case TELOPT_SGA:
      case TELOPT_BINARY:
          /* ACK only */
          if (!io_ptr->REMOTE_OPTIONS[c]) {
             io_ptr->REMOTE_OPTIONS[c] = TRUE;
             TELNET_do(io_ptr->NETWORK_FD, c);
          } /* Endif */
          break;

      default:
         TELNET_dont(io_ptr->NETWORK_FD, c);
         break;
      }  /* Endswitch */

      io_ptr->STATE = 0;
      return FALSE;

   case 3: /* IAC DO */
      switch (c) {

      case TELOPT_ECHO:
        /* ACK only */
        if (!io_ptr->LOCAL_OPTIONS[TELOPT_ECHO])
        {
          if (io_ptr->REMOTE_OPTIONS[TELOPT_ECHO])
          {
            if (io_ptr->FLAGS & IO_SERIAL_ECHO)
            {
              TELNET_wont(io_ptr->NETWORK_FD, TELOPT_ECHO);
            }
            else
            {
              TELNET_dont(io_ptr->NETWORK_FD, TELOPT_ECHO);
            }
          }
          else
          {
            if (io_ptr->FLAGS & IO_SERIAL_ECHO)
            {
              io_ptr->LOCAL_OPTIONS[TELOPT_ECHO] = TRUE;
              TELNET_will(io_ptr->NETWORK_FD, TELOPT_ECHO);
            }
            else
            {
              TELNET_dont(io_ptr->NETWORK_FD, TELOPT_ECHO);
            }
          } /* Endif */
        } /* Endif */
        break;

      case TELOPT_SGA:
      case TELOPT_BINARY:
          /* ACK only */
          if (!io_ptr->LOCAL_OPTIONS[c]) {
             io_ptr->LOCAL_OPTIONS[c] = TRUE;
             TELNET_will(io_ptr->NETWORK_FD, c);
          } /* Endif */
          break;

      default:
         TELNET_wont(io_ptr->NETWORK_FD, c);
         break;
      } /* Endswitch */

      io_ptr->STATE = 0;
      return FALSE;

   case 4: /* IAC WONT */
      switch (c) {

      case TELOPT_ECHO:
         if (io_ptr->REMOTE_OPTIONS[TELOPT_ECHO])
            {
            if (io_ptr->FLAGS & IO_SERIAL_ECHO)
               {
               /* Set the echo bit */
               ioctl(console_stream, IO_IOCTL_SERIAL_GET_FLAGS, &flags);
               flags |= IO_SERIAL_ECHO;
               ioctl(console_stream, IO_IOCTL_SERIAL_SET_FLAGS, &flags);
               }

            io_ptr->REMOTE_OPTIONS[TELOPT_ECHO] = FALSE;
            TELNET_dont(io_ptr->NETWORK_FD, TELOPT_ECHO);
            } /* Endif */
         break;

      case TELOPT_BINARY:
      default:
         if (c < TELNET_MAX_OPTS) {
            /* ACK only */
            if (io_ptr->REMOTE_OPTIONS[c]) {
               TELNET_dont(io_ptr->NETWORK_FD, c);
               io_ptr->REMOTE_OPTIONS[c] = FALSE;
            } /* Endif */
         } /* Endif */
         break;
      } /* Endswitch */

      io_ptr->STATE = 0;
      return FALSE;

   case 5: /* IAC DONT */

      if (c < TELNET_MAX_OPTS) {
         /* ACK only */
         if (io_ptr->LOCAL_OPTIONS[c]) {
            io_ptr->LOCAL_OPTIONS[c] = FALSE;
            TELNET_wont(io_ptr->NETWORK_FD, c);
         } /* Endif */
      } /* Endif */

      io_ptr->STATE = 0;
      return FALSE;

   case 6: /* CR received in ASCII mode */
       switch (c) {
       case TELCC_NULL:
           if (CRLF_MODE(io_ptr)) {
               *cp = TELCC_CR; //application character mapping to CR
           } else {
               *cp = TELCC_LF; //application character mapping to LF
           }
           _io_telnet_echo(io_ptr, *cp);
           break;
       case TELCC_LF:
           _io_telnet_echo(io_ptr, c);
           *cp = TELCC_LF; //application character mapping to LF
           break;
       default:
           return IO_ERROR;
       }
       io_ptr->STATE = 0;
       return TRUE;
   } /* Endswitch */

   /* Start SPR P122-0266-33 remove all warnings from RTCS code. */
   /* Will never reach here, this is just for compiler warning. */
   return FALSE;
   /* End SPR P122-0266-33. */
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_mem/iomemprv.h<|end_filename|>
#ifndef __iomemprv_h__
#define __iomemprv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iomemprv.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions private to the ram disk.
*
*END************************************************************************/

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/
/* Start CR 810 */
/* These are used to determine how memory was allocated for the RAM drive */
#define MEM_TYPE_DYNAMIC   (1)
#define MEM_TYPE_STATIC    (2)

/* Define the block size when driver is opened in block mode */
/* Defines size as a power of 2 */
#define IO_MEM_BLOCK_SIZE_POWER   (9)
#define IO_MEM_BLOCK_SIZE         (1 << IO_MEM_BLOCK_SIZE_POWER)

/* Properties of device */
#define IO_MEM_ATTRIBS  (IO_DEV_ATTR_READ | IO_DEV_ATTR_REMOVE | \
   IO_DEV_ATTR_SEEK | IO_DEV_ATTR_WRITE)
/* End   CR 810 */

/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/

/*
** IO_MEM STRUCT
**
** The address of this structure is used to maintain ramdisk specific 
** information.
*/
typedef struct io_mem_struct
{
   /* Type of memory, dynamic or static */
   _mqx_uint        TYPE;

   /* Address of the fdv_ram device */
   uchar_ptr        BASE_ADDR;

   /* The total size of memory in the ram disk */
   _file_size       SIZE;

   /* Light weight semaphore struct */
   LWSEM_STRUCT     LWSEM;
   
   /* The current error code for the device */
   _mqx_uint        ERROR_CODE;

   /* Start CR 810 */
   /* The current mode for the device */
   boolean          BLOCK_MODE;

   /* The number of blocks for the device */
   _file_size       NUM_BLOCKS;
   /* End   CR 810 */

} IO_MEM_STRUCT, _PTR_ IO_MEM_STRUCT_PTR;


/* Internal functions to IO_MEM */
#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_mem_open(FILE_DEVICE_STRUCT_PTR, char_ptr, char_ptr);
extern _mqx_int _io_mem_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_mem_write(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_mem_read (FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_mem_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);
extern _mqx_int _io_mem_uninstall(IO_DEVICE_STRUCT_PTR);

/* Start CR 810 */
extern _mqx_int _io_mem_write_blocks(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_mem_read_blocks (FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
/* End   CR 810 */

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Sign.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Sign.h
*
* @author   B04459,R29302
* 
* @version  1.0.1.0
* 
* @date     Dec-6-2012
* 
* @brief    Header file for #GFLIB_Sign function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef GFLIB_SIGN_H_
#define GFLIB_SIGN_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/

/*!
  \def GFLIB_Sign
  Function alias for the #GFLIB_SignANSIC function.
*/
#define GFLIB_Sign(x) GFLIB_SignANSIC(x)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/

/******************************************************************************
* Exported Variables
******************************************************************************/

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*! 
* @ingroup GFLIB_GROUP 
*/ 
extern Frac32 GFLIB_SignANSIC(Frac32 f32In);

/******************************************************************************
* Inline functions
******************************************************************************/ 

#endif /*GFLIB_SIGN_H_*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/timer/timer_lpt.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: timer_lpt.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   Low power timer public header file.
*
*END************************************************************************/


#ifndef __timer_lpt_h__
#define __timer_lpt_h__


#include <mqx.h>
#include <bsp.h>


/*-------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

#define LPT_FLAG_CLOCK_SOURCE_MCGIRCLK      (0x00000001)
#define LPT_FLAG_CLOCK_SOURCE_LPO           (0x00000002)
#define LPT_FLAG_CLOCK_SOURCE_ERCLK32K      (0x00000004)
#define LPT_FLAG_CLOCK_SOURCE_OSCERCLK      (0x00000008)
#define LPT_FLAG_CLOCK_SOURCE_ALL           (0x0000000F)


/*-------------------------------------------------------------------------*/
/*
**                            MACRO DECLARATIONS
*/


/*-------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/


/*-------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/


#ifdef __cplusplus
extern "C" {
#endif


extern pointer  _bsp_get_lpt_base_address (uint_8);
extern uint_32  _bsp_get_lpt_vector (uint_8);
extern uint_32  _bsp_get_lpt_clock_frequency (uint_8, uint_32);
extern uint_32  _bsp_enable_lpt_clock (uint_8);

extern _mqx_int _lpt_install (uint_8, uint_32, uint_32, uint_32, void (_CODE_PTR_ isr_ptr)(void *), boolean);
extern _mqx_int _lpt_install_kernel (uint_8, uint_32, uint_32, uint_32, boolean);
extern uint_32  _lpt_init (uint_8, uint_32, uint_32, boolean);

extern uint_32  _lpt_get_hwticks (pointer);

extern void     _lpt_mask_int (uint_8);
extern void     _lpt_unmask_int (uint_8);
extern void     _lpt_clear_int (uint_8);
extern void     _lpt_run (uint_8, boolean);


#ifdef __cplusplus
}
#endif


#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_UpperLimit.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GFLIB_UpperLimit.h
* 
* @author    r29302 
* 
* @version   1.0.1.0
* 
* @date      Dec-6-2012
* 
* @brief     Header file for the Upper-Limit function
*
*******************************************************************************
*
* Function impemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_UPPERLIMIT_H_
#define _GFLIB_UPPERLIMIT_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/************************************************************************
| defines and macros (scope: module-local)
|-----------------------------------------------------------------------*/

/*! Function alias for the #GFLIB_UpperLimitANSIC function.*/
#define GFLIB_UpperLimit(f32In, pParam) GFLIB_UpperLimitANSIC((f32In),(pParam))

/************************************************************************
| typedefs and structures (scope: module-local)
|-----------------------------------------------------------------------*/

/*------------------------------------------------------------------------*//*!
@struct		GFLIB_UPPERLIMIT_T "\GFLIB_UpperLimit.h"

@brief		Structure containing the upper limit.
*
*//*-------------------------------------------------------------------------*/

typedef struct  
{    
     Frac32 f32UpperLimit; /*!<Upper Limit. */
} GFLIB_UPPERLIMIT_T;

/************************************************************************
| exported variables
|-----------------------------------------------------------------------*/

/************************************************************************
| exported function prototypes
|-----------------------------------------------------------------------*/
/*! 
* @ingroup GFLIB_GROUP 
*/
extern Frac32 GFLIB_UpperLimitANSIC (Frac32 f32In,
                                      const GFLIB_UPPERLIMIT_T *const pParam);
#ifdef __cplusplus
}
#endif
#endif /* _GFLIB_UPPERLIMIT_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/lcp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lcp.c$
* $Version : 3.8.10.0$
* $Date    : Aug-27-2012$
*
* Comments:
*
*   This file contains the implementation for the
*   Link Control Protocol.
*
*END************************************************************************/

/*
** lcp.c - PPP Link Control Protocol.
**
** Copyright (c) 1989 Carnegie Mellon University.
** All rights reserved.
**
** Redistribution and use in source and binary forms are permitted
** provided that the above copyright notice and this paragraph are
** duplicated in all such forms and that any documentation,
** advertising materials, and other materials related to such
** distribution and use acknowledge that the software was developed
** by Carnegie Mellon University.  The name of the
** University may not be used to endorse or promote products derived
** from this software without specific prior written permission.
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
** WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

/*
** Things to do:
**
** We need a way to let the application specify which configuration
** options to request (in order of preference), and which options to
** allow the peer (unordered set).
**
** Currently, the following are hard coded for both sides:
**
**       MRU <= 1500            (1500 preferred, Receive side)
**       MRU >= 68              (Send side)
**       ACCM = _PPP_ACCM
**       PFC = TRUE or FALSE    (TRUE preferred)
**       ACFC = TRUE or FALSE   (TRUE preferred)
**       FCS = CCITT-32, CCITT-16 or NULL
**                              (CCITT-16 preferred)
**
** The choice of authentication protocols depends on the
** existence of secrets.  The following are supported
**
**       AP = none or PAP
**
*/

#include <ppp.h>
#include "ppp_prv.h"

#if RTCSCFG_ENABLE_IP4

static boolean LCP_up(PPPFSM_CFG_PTR);
static void    LCP_down(PPPFSM_CFG_PTR);

static void    LCP_resetconfreq(PPPFSM_CFG_PTR);
static uint_32 LCP_buildconfreq(PPPFSM_CFG_PTR, uchar_ptr, uint_32);

static uint_32 LCP_recvconfreq(PPPFSM_CFG_PTR, boolean);
static boolean LCP_recvconfack(PPPFSM_CFG_PTR);
static boolean LCP_recvconfnak(PPPFSM_CFG_PTR);
static boolean LCP_recvconfrej(PPPFSM_CFG_PTR);
static boolean LCP_recvcoderej(PPPFSM_CFG_PTR);
static boolean LCP_recvextcode(PPPFSM_CFG_PTR);

static PPPFSM_CALL LCP_CALL = {
   /* PROTOCOL    */    PPP_PROT_LCP,
   /* linkup()    */    LCP_up,
   /* linkdown()  */    LCP_down,
   /* resetreq()  */    LCP_resetconfreq,
   /* buildreq()  */    LCP_buildconfreq,
   /* recvreq()   */    LCP_recvconfreq,
   /* recvack()   */    LCP_recvconfack,
   /* recvnak()   */    LCP_recvconfnak,
   /* recvrej()   */    LCP_recvconfrej,
   /* testcode()  */    LCP_recvcoderej,
   /* recvcode()  */    LCP_recvextcode
};

static LCP_NEG LCP_DEFAULT_NEG = {
   /* NEG_* */    0,1,0,0,0,1,1,0,
   /* MRU   */    DEFAULT_MRU,
   /* ACCM  */    0xFFFFFFFFl,
   /* AP    */    0
};

static LCP_NEG LCP_DEFAULT_NEG_PPPOE = {
   /* NEG_* */    1,0,0,0,0,0,0,0,
   /* MRU   */    1492,
   /* ACCM  */    0,
   /* AP    */    0
};

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_init
* Returned Value  :  error code
* Comments        :
*     Called by PPP_init.  Initializes the LCP Finite State Machine.
*
*END*-----------------------------------------------------------------*/

uint_32 LCP_init
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

   ppp_ptr->LCP_STATE.DEVICE = ppp_ptr->DEVICE;
/* Start CR 2207 */
#if PPP_SECRETS_NOT_SHARED
   ppp_ptr->LCP_STATE.HANDLE = handle;
#endif
/* End CR 2207 */
      /* Initialize the FSM */
   return PPPFSM_init(&ppp_ptr->LCP_FSM, handle, &LCP_CALL, &ppp_ptr->LCP_STATE);

#else
   
   return RTCSERR_IP_IS_DISABLED;
   
#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_destroy
* Returned Value  :  error code
* Comments        :
*     Called by PPP_init.  Destroys the LCP Finite State Machine.
*     Assumes the Finite State Machine has been initialized.
*
*END*-----------------------------------------------------------------*/

uint_32 LCP_destroy
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

      /* Destroy the FSM */
   return PPPFSM_destroy(&ppp_ptr->LCP_FSM);

#else
   
   return RTCSERR_IP_IS_DISABLED;
   
#endif /* RTCSCFG_ENABLE_IP4 */   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_lowerup
* Returned Value  :  void
* Comments        :
*     Called by application.  Lower layer is up.
*
*END*-----------------------------------------------------------------*/

void PPP_lowerup
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

   PPPFSM_lowerup(&ppp_ptr->LCP_FSM);

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_lowerdown
* Returned Value  :  void
* Comments        :
*     Called by application.  Lower layer is down.
*
*END*-----------------------------------------------------------------*/

void PPP_lowerdown
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

   PPPFSM_lowerdown(&ppp_ptr->LCP_FSM);

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_open
* Returned Value  :  error code
* Comments        :
*     Called by application.  Begin negotiating PPP.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_open
   (
      _ppp_handle    handle,
            /* [IN] - the PPP state structure */
      uint_32        options
            /* [IN] - Startup options */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

      /* Do some error checking */
   if (ppp_ptr->VALID != PPP_VALID) {
      return RTCSERR_PPP_INVALID_HANDLE;
   } /* Endif */

   PPPFSM_open(&ppp_ptr->LCP_FSM, options);
   return PPP_OK;

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */  

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_close
* Returned Value  :  error code
* Comments        :
*     Called by application.  Begin closing PPP.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_close
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = handle;

      /* Do some error checking */
   if (ppp_ptr->VALID != PPP_VALID) {
      return RTCSERR_PPP_INVALID_HANDLE;
   } /* Endif */

   PPPFSM_close(&ppp_ptr->LCP_FSM);
   return PPP_OK;

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */  

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_recvextcode
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_Input.  Parses an LCP packet with an extended
*     code.  Consumes fsm->PACKET if TRUE is returned.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean LCP_recvextcode
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = fsm->HANDLE;
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   PPP_CALL_INTERNAL_PTR call_ptr = &ppp_ptr->LCP_CALL[PPP_CALL_ECHO_REPLY];

   switch (fsm->CODE) {
   case LCP_CODE_PROT_REJ:
      lcp_ptr->ST_LCP_RX_REJECT++;

      /*
      ** We should notify the rejected protocol, but there
      ** currently isn't any way to do this.  What we'll do
      ** instead is to send a STOP message to the Tx task on
      ** behalf of the protocol.
      **
      ** This will usually be sufficient, since the rejected
      ** protocol isn't likely to send another packet until
      ** either it receives a packet (in which case it's OK to
      ** reply) or the retransmission timer kicks in (which
      ** we're about to disable).
      **
      ** Thus, this will effectively stop the rejected protocol.
      */

      if (fsm->LENGTH >= 2) {
         uint_16 protocol = ntohs(fsm->DATA);
         PPP_send_stop(ppp_ptr, protocol);
      } /* Endif */
      PCB_free(fsm->PACKET);
      break;

   case LCP_CODE_ECHO_REQ:
      lcp_ptr->ST_LCP_RX_ECHO++;
      if (fsm->STATE < PPP_STATE_OPENED) {
         PCB_free(fsm->PACKET);
      } else {
         htonc(fsm->DATA - CP_HDR_LEN, LCP_CODE_ECHO_REP);
         htonl(fsm->DATA, 0);                      /* Set magic field to 0 */
         lcp_ptr->ST_LCP_TX_REPLY++;
         PPP_send_one(ppp_ptr, PPP_PROT_LCP, fsm->PACKET);
      } /* Endif */
      break;

   case LCP_CODE_ECHO_REP:
      lcp_ptr->ST_LCP_RX_REPLY++;
      if (call_ptr->CALLBACK) {
         call_ptr->CALLBACK(call_ptr->PARAM, fsm->ID, fsm->PACKET);
      } /* Endif */
      PCB_free(fsm->PACKET);
      break;

   case LCP_CODE_DISC_REQ:
      lcp_ptr->ST_LCP_RX_DISCARD++;
      PCB_free(fsm->PACKET);
      break;

   default:
      return FALSE;
   } /* Endswitch */

   return TRUE;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_sendprotrej
* Returned Value  :  void
* Comments        :
*     Called by PPP_rx_task.  Sends a ProtRej packet for some protocol.
*     Consumes (sends) 'pcb'.
*
*END*-----------------------------------------------------------------*/

void LCP_sendprotrej
   (
      PCB_PTR           pcb,
            /* [IN] - packet to reject */
      PPPFSM_CFG_PTR    fsm
            /* [IN/OUT] - State Machine */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR ppp_ptr = fsm->HANDLE;
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   uchar_ptr   packet, src, dst;
   uint_16     length;
   uint_16     size = ppp_ptr->SEND_OPTIONS->MRU - CP_HDR_LEN;

   length = pcb->FRAG[0].LENGTH;
   packet = pcb->FRAG[0].FRAGMENT;

   /* Truncate the packet if necessary */
   if (length > size) {
      length = size;
   } /* Endif */

   /* Make room for a Code-Reject header */
   size = length + CP_HDR_LEN;

   /* Copy the received packet (including protocol field) to the */
   /* data portion of the Protocol-Reject                        */
   src = packet + length;
   dst = src + 2 + CP_HDR_LEN;
   while (length--) *--dst = *--src;

   /* Build a Code-Reject packet */
   htons(packet, PPP_PROT_LCP); packet += 2;
   *packet++ = LCP_CODE_PROT_REJ;
   *packet++ = fsm->CURID;
   fsm->CURID = (fsm->CURID + 1) & 0xFF;
   htons(packet, size); packet += 2;
   pcb->FRAG[0].LENGTH = size + 2;

   lcp_ptr->ST_LCP_TX_REJECT++;
   PPP_send_one(ppp_ptr, PPP_PROT_LCP, pcb);

#else

    PCB_free(pcb);

#endif /* RTCSCFG_ENABLE_IP4  */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_resetconfreq
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_Sendconfreq when starting negotiation.
*     Initializes the Send Options.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void LCP_resetconfreq
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   uint_32     if_type;
/* Start CR 2207 */
#if PPP_SECRETS_NOT_SHARED
   PPP_CFG_PTR    ppp_ptr = lcp_ptr->HANDLE;
#endif
/* End CR 2207 */

   _iopcb_ioctl(lcp_ptr->DEVICE, IOPCB_IOCTL_GET_IFTYPE, &if_type);
   if (if_type == IPIFTYPE_ETHERNET) {
      lcp_ptr->SEND_OPT = PPP_DEFAULT_OPTIONS_PPPOE;
      lcp_ptr->RECV_OPT = PPP_DEFAULT_OPTIONS_PPPOE;
      lcp_ptr->RECV_NEG = LCP_DEFAULT_NEG_PPPOE;
   } else {
      lcp_ptr->SEND_OPT = PPP_DEFAULT_OPTIONS;
      lcp_ptr->RECV_OPT = PPP_DEFAULT_OPTIONS;
      lcp_ptr->RECV_NEG = LCP_DEFAULT_NEG;
      lcp_ptr->RECV_NEG.ACCM = _PPP_ACCM;
   } /* Endif */

/* Start CR 2207 */
   if (PPP_SECRET(ppp_ptr,_PPP_CHAP_RSECRETS)) {
/* End CR 2207 */
      lcp_ptr->RECV_NEG.NEG_AP = 1;
      lcp_ptr->RECV_NEG.AP = PPP_PROT_CHAP;
/* Start CR 2207 */
   } else if (PPP_SECRET(ppp_ptr,_PPP_PAP_RSECRETS)) {
/* End CR 2207 */
      lcp_ptr->RECV_NEG.NEG_AP = 1;
      lcp_ptr->RECV_NEG.AP = PPP_PROT_PAP;
   } else {
      lcp_ptr->RECV_NEG.NEG_AP = 0;
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_buildconfreq
* Returned Value  :  number of bytes written
* Comments        :
*     Called by PPPFSM_Sendconfreq.  Builds a ConfReq packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 LCP_buildconfreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN] - State Machine */
      uchar_ptr         outp,
            /* [IN] - free packet */
      uint_32           sizeleft
            /* [IN] - size of packet */
   )
{ /* Body */
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   uint_32     totlen = 0;
   uint_32     aplen;

#define LCP_BREQ(ci,len) \
         *outp++ = LCP_CI_ ## ci; \
         *outp++ = len;           \
         totlen += len

   /*
   ** Generate configuration information for each option
   ** we want to negotiate.
   */

   if (lcp_ptr->RECV_NEG.NEG_MRU) {
      if (sizeleft >= totlen+4) {
         LCP_BREQ(MRU,4);
         htons(outp, lcp_ptr->RECV_NEG.MRU); outp += 2;
      } /* Endif */
   } /* Endif */

   if (lcp_ptr->RECV_NEG.NEG_ACCM) {
      if (sizeleft >= totlen+6) {
         LCP_BREQ(ACCM,6);
         htonl(outp, lcp_ptr->RECV_NEG.ACCM); outp += 4;
      } /* Endif */
   } /* Endif */

   if (lcp_ptr->RECV_NEG.NEG_AP) {
      switch (lcp_ptr->RECV_NEG.AP) {
      case PPP_PROT_CHAP: aplen = 5; break;
      default:            aplen = 4; break;
      } /* Endswitch */
      if (sizeleft >= totlen+aplen) {
         LCP_BREQ(AP,aplen);
         htons(outp, lcp_ptr->RECV_NEG.AP); outp += 2;
         switch (lcp_ptr->RECV_NEG.AP) {
         case PPP_PROT_CHAP:
            htonc(outp, 5); outp++;          /* Only MD5 supported */
            break;
         } /* Endswitch */
      } /* Endif */
   } /* Endif */

   if (lcp_ptr->RECV_NEG.NEG_PFC) {
      if (sizeleft >= totlen+2) {
         LCP_BREQ(PFC,2);
      } /* Endif */
   } /* Endif */

   if (lcp_ptr->RECV_NEG.NEG_ACFC) {
      if (sizeleft >= totlen+2) {
         LCP_BREQ(ACFC,2);
      } /* Endif */
   } /* Endif */

   return totlen;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_recvconfack
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_Recvconfack.  Parses a ConfAck packet.
*     This function should not modify any state if the ack is bad.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean LCP_recvconfack
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   uchar_ptr   inp = fsm->DATA;
   uint_32     sizeleft = fsm->LENGTH;
   uint_32     aplen;
   PPP_OPT     ack_opt = lcp_ptr->RECV_OPT;

#define LCP_RACK(ci,len) \
      if (sizeleft < len) goto badack;          \
      if (*inp++ != LCP_CI_ ## ci) goto badack; \
      if (*inp++ != len)           goto badack; \
      sizeleft -= len


   /*
   ** The ack must be identical to the last ConfReq we sent
   */
    /*
    ** This situation can happend when size of data in our request packet is "0"
    ** So, size of received data in "ack" packet will be "0" too.
    ** As example: We send "REQ" packet with field PFC an ACFC "ON", modem send "NAK" 
    ** for that field. We turn of that field, but we have not what negotiate else,
    ** so we send "REQ" packed,it looks like "7E FF 03 C0 21 01 6D 00 04 3F 15 7E"
    ** As you see size of data field is "0". But modem agree and send us "ACK" looks like
    ** "7E FF 03 C0 21 02 6D 00 04 F2 30 7E" and will be ready to start next stage of communication.
    ** In received packet from modem you can se size of data field is "0" too.
    */
    if(sizeleft ==0)
    {
        return TRUE; 
    }
    

   if (lcp_ptr->RECV_NEG.NEG_MRU) {
      LCP_RACK(MRU,4);
      ack_opt.MRU = ntohs(inp); inp += 2;
      if (ack_opt.MRU != lcp_ptr->RECV_NEG.MRU) goto badack;
   } /* Endif */

   if (lcp_ptr->RECV_NEG.NEG_ACCM) {
      LCP_RACK(ACCM,6);
      ack_opt.ACCM = ntohl(inp); inp += 4;
      if (ack_opt.ACCM != lcp_ptr->RECV_NEG.ACCM) goto badack;
   } /* Endif */

   if (lcp_ptr->RECV_NEG.NEG_AP) {
      switch (lcp_ptr->RECV_NEG.AP) {
      case PPP_PROT_CHAP: aplen = 5; break;
      default:            aplen = 4; break;
      } /* Endswitch */
      LCP_RACK(AP,aplen);
      ack_opt.AP = ntohs(inp); inp += 2;
      if (ack_opt.AP != lcp_ptr->RECV_NEG.AP) goto badack;
      switch (ack_opt.AP) {
      case PPP_PROT_CHAP:
         if (ntohc(inp) != 5) goto badack;   /* Only MD5 supported */
         inp++;
         ack_opt.AP_Start = CHAP_challenge;
         break;
      case PPP_PROT_PAP:
         ack_opt.AP_Start = PAP_open;
         break;
      default:
         ack_opt.AP = 0;
         break;
      } /* Endswitch */
   } /* Endif */

   if (lcp_ptr->RECV_NEG.NEG_PFC) {
      LCP_RACK(PFC,2);
      ack_opt.PFC = TRUE;
   } /* Endif */

   if (lcp_ptr->RECV_NEG.NEG_ACFC) {
      LCP_RACK(ACFC,2);
      ack_opt.ACFC = TRUE;
   } /* Endif */

   if (sizeleft) goto badack;

   if (fsm->STATE < PPP_STATE_OPENED) {
      lcp_ptr->RECV_OPT = ack_opt;
   } /* Endif */
   return TRUE;

badack:
   return FALSE;

} /* Endbody */


#endif /* RTCSCFG_ENABLE_IP4 */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_recvconfnak
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_recvconfnak.  Parses a ConfNak packet.
*     This function should not modify any state if the nak is bad.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean LCP_recvconfnak
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   uchar_ptr   inp = fsm->DATA;
   uint_32     sizeleft = fsm->LENGTH;
   LCP_NEG     req_neg = lcp_ptr->RECV_NEG;
   uchar       code;
/* Start CR 2207 */
#if PPP_SECRETS_NOT_SHARED
   PPP_CFG_PTR    ppp_ptr = lcp_ptr->HANDLE;
#endif
/* End CR 2207 */

#define LCP_RNAK(len) \
      if (sizeleft < len) goto badnak; \
      if (*inp++ != len)  goto badnak; \
      sizeleft -= len

   /*
   ** Nak'd codes must be in the same order as they were in the ConfReq
   */

   code = *inp++;

   if (sizeleft && req_neg.NEG_MRU && code == LCP_CI_MRU) {
      LCP_RNAK(4);

         /* We are prepared to accept maximum MRU of 1500 */
      req_neg.MRU = ntohs(inp); inp += 2;
      if (req_neg.MRU > DEFAULT_MRU) {
         req_neg.MRU = DEFAULT_MRU;
      } /* Endif */

      code = *inp++;
   } /* Endif */

   if (sizeleft && req_neg.NEG_ACCM && code == LCP_CI_ACCM) {
      LCP_RNAK(6);

         /* Add any characters they want to our ACCM */
      req_neg.ACCM |= ntohl(inp); inp += 4;

      code = *inp++;
   } /* Endif */

   if (sizeleft && req_neg.NEG_AP && code == LCP_CI_AP) {
      if (sizeleft < *inp || *inp < 4) goto badnak;
      sizeleft -= *inp;

         /*
         ** If AP is nak'd, we don't care what they want --
         ** we choose the next most desirable protocol.  If there
         ** aren't any more to choose, we keep the last one we tried.
         */
      inp += *inp - 1;
      
      if (PPP_SECRET(ppp_ptr,_PPP_CHAP_RSECRETS)) {
          req_neg.AP = PPP_PROT_CHAP;
      } else {
        switch (req_neg.AP) {
        case PPP_PROT_CHAP:
             /* CHAP was NAKed, try PAP */ 
             if (PPP_SECRET(ppp_ptr,_PPP_PAP_RSECRETS)) {
                req_neg.AP = PPP_PROT_PAP;            
             } /* Endif */
             break;
        
        case PPP_PROT_PAP:
           /* no other authentication protocols known */
           break;
           
        default:
            /* Unknown protocol NAKed, try CHAP */
            if (PPP_SECRET(ppp_ptr,_PPP_CHAP_RSECRETS)) {
                req_neg.AP = PPP_PROT_CHAP;
            }
            break;

        } /* Endswitch */
      }
      code = *inp++;
   } /* Endif */

   /*
   ** If we advertised PFC and/or ACFC and the peer doesn't
   ** want it, they should send a ConfRej rather than a ConfNak,
   ** so we're not going to check for them here (if they are
   ** here, the switch statement below will catch it).
   */


#define LCP_RNAK_ADD(ci,len) \
         if (req_neg.NEG_ ## ci || sizeleft < len || *inp++ != len) goto badnak; \
         sizeleft -= len;                                                        \
         req_neg.NEG_ ## ci = 1

   /*
   ** There may be remaining codes if the peer wants us to
   ** negotiate an option we didn't include.
   */

   while (sizeleft) {
      switch (code) {
      case LCP_CI_MRU:
         LCP_RNAK_ADD(MRU,4);
         req_neg.MRU = ntohs(inp); inp += 2;
         if (req_neg.MRU > DEFAULT_MRU) {
            req_neg.MRU = DEFAULT_MRU;
         } /* Endif */
         break;
      case LCP_CI_ACCM:
         LCP_RNAK_ADD(ACCM,6);
         req_neg.ACCM |= ntohl(inp); inp += 4;
         break;
      case LCP_CI_AP:
         if (req_neg.NEG_AP || sizeleft < *inp || *inp < 4) goto badnak;
         sizeleft -= *inp;
            /*
            ** If AP is nak'd, we don't care what they want --
            ** we still don't negotiate
            */
         inp += *inp - 1;
         break;
      case LCP_CI_PFC:
         LCP_RNAK_ADD(PFC,2);
         break;
      case LCP_CI_ACFC:
         LCP_RNAK_ADD(ACFC,2);
         break;
      default:
         if (sizeleft < *inp || *inp < 2) goto badnak;
         sizeleft -= *inp;
         inp += *inp - 1;
      } /* Endswtich */
      code = *inp++;
   } /* Endwhile */

   if (fsm->STATE < PPP_STATE_OPENED) {
      lcp_ptr->RECV_NEG = req_neg;
   } /* Endif */
   return TRUE;

badnak:
   return FALSE;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_recvconfrej
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_recvconfnak.  Parses a ConfRej packet.
*     This function should not modify any state if the rej is bad.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean LCP_recvconfrej
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   uchar_ptr   inp = fsm->DATA;
   uint_32     sizeleft = fsm->LENGTH;
   uint_32     aplen;
   PPP_OPT     req_opt = lcp_ptr->RECV_OPT;
   LCP_NEG     req_neg = lcp_ptr->RECV_NEG;
   uchar       code;

#define LCP_RREJ(ci,len) \
      if (sizeleft < len) goto badrej; \
      if (*inp++ != len)  goto badrej; \
      sizeleft -= len;                 \
      req_neg.NEG_ ## ci = 0;          \
      req_opt.ci = PPP_DEFAULT_OPTIONS.ci

   /*
   ** Rej'd codes must be in the same order as they were in the ConfReq
   */

   code = *inp++;

   if (sizeleft && req_neg.NEG_MRU && (code == LCP_CI_MRU)) {
      LCP_RREJ(MRU,4);
      if (req_neg.MRU != ntohs(inp)) goto badrej; inp += 2;
      code = *inp++;
   } /* Endif */

   if (sizeleft && req_neg.NEG_ACCM && (code == LCP_CI_ACCM)) {
      LCP_RREJ(ACCM,6);
      if (req_neg.ACCM != ntohl(inp)) goto badrej; inp += 4;
      code = *inp++;
   } /* Endif */

   if (sizeleft && req_neg.NEG_AP && (code == LCP_CI_AP)) {
      switch (req_neg.AP) {
      case PPP_PROT_CHAP: aplen = 5; break;
      default:            aplen = 4; break;
      } /* Endswitch */
      LCP_RREJ(AP,aplen);
      if (req_neg.AP != ntohs(inp)) goto badrej; inp += 2;
      switch (req_neg.AP) {
      case PPP_PROT_CHAP:
         if (5 != ntohc(inp)) goto badrej;   /* Only MD5 supported */
         inp++;
         break;
      } /* Endswitch */
      req_opt.AP_Start = PPP_DEFAULT_OPTIONS.AP_Start;
      code = *inp++;
   } /* Endif */

   if (sizeleft && req_neg.NEG_PFC && (code == LCP_CI_PFC)) {
      LCP_RREJ(PFC,2);
      code = *inp++;
   } /* Endif */

   if (sizeleft && req_neg.NEG_ACFC && (code == LCP_CI_ACFC)) {
      LCP_RREJ(ACFC,2);
      code = *inp++;
   } /* Endif */

   if (sizeleft) goto badrej;

   if (fsm->STATE < PPP_STATE_OPENED) {
      lcp_ptr->RECV_OPT = req_opt;
      lcp_ptr->RECV_NEG = req_neg;
   } /* Endif */
   return TRUE;

badrej:
   return FALSE;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_recvconfreq
* Returned Value  :  number of bytes written
* Comments        :
*     Called by PPPFSM_recvconfreq.  Parses a ConfReq packet.
*     Builds a ConfAck/ConfNak/ConfRej packet out of fsm->PACKET,
*     and sets fsm->CODE appropriately.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 LCP_recvconfreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN] - State Machine */
      boolean           reject
            /* [IN] - whether to ConfRej if we disagree */
   )
{ /* Body */
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   uchar_ptr   inp = fsm->DATA;
   uchar_ptr   nakp, rejp;
   uint_32     sizeleft = fsm->LENGTH;
   uint_32     naklen, rejlen;
   boolean     apneg = FALSE;
   PPP_OPT     req_opt = lcp_ptr->SEND_OPT;
   uchar       code;
   uchar       cicode, cilen;
/* Start CR 2207 */
#if PPP_SECRETS_NOT_SHARED
   PPP_CFG_PTR    ppp_ptr = lcp_ptr->HANDLE;
#endif
/* End CR 2207 */

#define CI_REJECT(n)                   \
   inp -= n;                           \
   code = CP_CODE_CONF_REJ;            \
   rejlen += cilen;                    \
   while (cilen--) *rejp++ = *inp++

#define CI_NAK                               \
   if (code != CP_CODE_CONF_REJ) {           \
      code = CP_CODE_CONF_NAK;               \
      if (reject) {                          \
         inp -= cilen;                       \
         naklen += cilen;                    \
         while (cilen--) *nakp++ = *inp++;   \
      } else {                               \
         apneg = FALSE;

#define CI_ENDNAK                            \
      } /* Endif */                          \
   } /* Endif */

#define CI_NAKAP(n)                          \
   if (code != CP_CODE_CONF_REJ) {           \
      code = CP_CODE_CONF_NAK;               \
      if (reject) {                          \
         inp -= n;                           \
         naklen += cilen;                    \
         while (cilen--) *nakp++ = *inp++;   \
      } else {                               \
         apneg = TRUE;                       \
         inp += cilen - n;                   \
      } /* Endif */                          \
   } else {                                  \
      inp += cilen - n;                      \
   } /* Endif */

   /*
   ** Process all requested codes
   */

   rejp = nakp = inp;
   rejlen = naklen = 0;
   code = CP_CODE_CONF_ACK;

   while (sizeleft) {
         /* check remaining length */
      if (sizeleft < inp[1] || inp[1] < 2) {
         code = CP_CODE_CONF_REJ;
         rejlen += sizeleft;
         while (sizeleft--) *rejp++ = *inp++;
         break;
      } /* Endif */

      cicode = *inp++;
      sizeleft -= cilen = *inp++;

      switch (cicode) {
      case LCP_CI_MRU:
         if (cilen != 4) {
            CI_REJECT(2);
            break;
         } /* Endif */

            /* Accept any MRU no smaller than 68 bytes */
         req_opt.MRU = ntohs(inp); inp += 2;
         if (req_opt.MRU > DEFAULT_MRU) {
            req_opt.MRU = DEFAULT_MRU;
         } else if (req_opt.MRU < MINIMUM_MRU) {
            CI_NAK {
               *nakp++ = LCP_CI_MRU;
               naklen += *nakp++ = 4;
               req_opt.MRU = MINIMUM_MRU;
               htons(nakp, req_opt.MRU); nakp += 2;
            } CI_ENDNAK;
         } /* Endif */
         break;

      case LCP_CI_ACCM:
         if (cilen != 6) {
            CI_REJECT(2);
            break;
         } /* Endif */

            /* If we want any characters not in their ACCM, nak it */
         req_opt.ACCM = ntohl(inp); inp += 4;
         if ((req_opt.ACCM & _PPP_ACCM) != _PPP_ACCM) {
            CI_NAK {
               *nakp++ = LCP_CI_ACCM;
               naklen += *nakp++ = 6;
               req_opt.ACCM |= _PPP_ACCM;
               htonl(nakp, req_opt.ACCM); nakp += 4;
            } CI_ENDNAK;
         } /* Endif */
         break;

         /*
         ** AP is unusual in that it is a variable length
         ** option.  Thus it is possible that we may want
         ** to nak AP and make a suggestion longer than
         ** the peer's request.
         **
         ** This is bad.
         **
         ** It's bad because this function wants to reuse
         ** the incoming ConfReq to build the reply, and
         ** in this case, it is possible for nakp to
         ** overtake inp, thus overwriting an option not
         ** yet parsed.
         **
         ** So we do the following:  If we decide to nak
         ** the requested AP, we just set apneg=TRUE and
         ** append the nak'd AP at the end of our ConfNak
         ** after we've completed parsing the ConfReq.
         **
         ** Note that we won't nak AP if we generate
         ** nak's for other options afterward, because
         ** the RFC states that nak'd options MUST be in
         ** the same order that they were in the ConfReq.
         */

      case LCP_CI_AP:
         if (cilen < 4) {
            CI_REJECT(2);
            break;
         } /* Endif */

            /* If we don't have any secrets, reject AP */
/* Start CR 2207 */
         if (!(PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET) || PPP_SECRET(ppp_ptr,_PPP_CHAP_LSECRETS))) {
/* End CR 2207 */
            CI_REJECT(2);
            break;
         } /* Endif */

            /* Check the desired authentication protocol */
         req_opt.AP = ntohs(inp); inp += 2;
         switch (req_opt.AP) {

            /* Accept PAP only if we have a secret */
         case PPP_PROT_PAP:
            if (cilen != 4) {
               CI_REJECT(4);
               break;
/* Start CR 2207 */
            } else if (PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET) == NULL) {
/* End CR 2207 */
               CI_NAKAP(4);
               break;
            } /* Endif */
            req_opt.AP_Start = PAP_send;
            break;

            /* Accept CHAP only if we have a secrets table */
         case PPP_PROT_CHAP:
            if (cilen != 5) {
               CI_REJECT(4);
               break;
/* Start CR 2207 */
            } else if (PPP_SECRET(ppp_ptr,_PPP_CHAP_LSECRETS) == NULL) {
/* End CR 2207 */
               CI_NAKAP(4);
               break;
            } else if (*inp++ != 5) {     /* Only MD5 supported */
               CI_NAKAP(5);
               break;
            } /* Endif */
            req_opt.AP_Start = CHAP_open;
            break;

         default:
            CI_NAKAP(4);
            break;
         } /* Endswitch */
         break;

      case LCP_CI_MAGIC:
         if (cilen != 6) {
            CI_REJECT(2);
            break;
         } /* Endif */

         inp += 4;
         break;

      case LCP_CI_PFC:
         if (cilen != 2) {
            CI_REJECT(2);
            break;
         } /* Endif */

         req_opt.PFC = TRUE;
         break;

      case LCP_CI_ACFC:
         if (cilen != 2) {
            CI_REJECT(2);
            break;
         } /* Endif */

         req_opt.ACFC = TRUE;
         break;

      default:
         CI_REJECT(2);
         break;
      } /* Endswitch */
   } /* Endwhile */

   /*
   ** If we wanted to send additional naks for unsent codes, they
   ** would go here, at *nakp.
   */

   if (code == CP_CODE_CONF_ACK) {
      lcp_ptr->SEND_OPT = req_opt;
      sizeleft = fsm->LENGTH;
   } else if (code == CP_CODE_CONF_REJ) {
      sizeleft = rejlen;
   } else if (reject) {
      code = CP_CODE_CONF_REJ;
      sizeleft = naklen;
   } else { /* if code == NAK */

         /* We want to nak AP, and we didn't nak anything else after it */
      if (apneg) {
/* Start CR 2207 */
         if (PPP_SECRET(ppp_ptr,_PPP_CHAP_LSECRETS)) {
/* End CR 2207 */
            *nakp++ = LCP_CI_AP;
            naklen += *nakp++ = 5;
            htons(nakp, PPP_PROT_CHAP); nakp += 2;
            *nakp++ = 5;                  /* Only MD5 supported */
/* Start CR 2207 */
         } else if (PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET)) {
/* End CR 2207 */
            *nakp++ = LCP_CI_AP;
            naklen += *nakp++ = 4;
            htons(nakp, PPP_PROT_PAP); nakp += 2;
         } /* Endif */
      } /* Endif */

      sizeleft = naklen;
   } /* Endif */

   fsm->CODE = code;
   return sizeleft;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_recvcoderej
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_Recvcoderej.  Returns TRUE if the rejected
*     code is catastrophic.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean LCP_recvcoderej
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   uchar code = *fsm->DATA;
   return (code >= 1 && code <= 7);
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_up
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by the FSM when entering the OPENED state.  Returns
*     TRUE if the link can be allowed to remain up.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean LCP_up
   (
      PPPFSM_CFG_PTR          fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = fsm->HANDLE;
   LCP_CFG_PTR lcp_ptr = fsm->PRIVATE;
   PPP_CALL_INTERNAL_PTR callauth_ptr = &ppp_ptr->LCP_CALL[PPP_CALL_AUTH_FAIL];

/* Start CR 2207 */
   if ((PPP_SECRET(ppp_ptr,_PPP_PAP_RSECRETS) || PPP_SECRET(ppp_ptr,_PPP_CHAP_RSECRETS))
/* End CR 2207 */
       && !lcp_ptr->RECV_OPT.AP) {
      if (callauth_ptr->CALLBACK) {
         (*callauth_ptr->CALLBACK)(callauth_ptr->PARAM);
      } /* Endif */
      return FALSE;
   } /* Endif */

      /* Initialize the authentication protocols */
   PAP_init(fsm->HANDLE);
   CHAP_init(fsm->HANDLE);

   PPP_mutex_lock(&ppp_ptr->MUTEX);
   ppp_ptr->LINK_STATE = TRUE;
   ppp_ptr->LINK_AUTH = (lcp_ptr->RECV_OPT.AP == 0);
   ppp_ptr->RECV_OPTIONS = &lcp_ptr->RECV_OPT;
   ppp_ptr->SEND_OPTIONS = &lcp_ptr->SEND_OPT;
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_S_ACCM, &lcp_ptr->SEND_OPT.ACCM);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_R_ACCM, &lcp_ptr->RECV_OPT.ACCM);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_S_PFC,  &lcp_ptr->SEND_OPT.PFC);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_R_PFC,  &lcp_ptr->RECV_OPT.PFC);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_S_ACFC, &lcp_ptr->SEND_OPT.ACFC);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_R_ACFC, &lcp_ptr->RECV_OPT.ACFC);
   PPP_mutex_unlock(&ppp_ptr->MUTEX);

   /* Start CR 2158 */
   if ((lcp_ptr->SEND_OPT.AP != 0) || (lcp_ptr->RECV_OPT.AP != 0)) {
      /* The link requires authentication */
         
      /* If the peer requested authentication, send it */
      if (lcp_ptr->SEND_OPT.AP != 0) {
         (*lcp_ptr->SEND_OPT.AP_Start)(fsm->HANDLE);
      } /* Endif */

      /*
      ** Note: we really should call RECV_OPT.AP_Start() before
      ** setting LINK_STATE (but still call PPP_LINK_UP() after),
      ** but, LCP_up() is always called from the context of the
      ** PPP rx task, so there isn't a problem.
      **
      ** (There would be a problem if an AP packet could be processed
      ** after setting LINK_STATE=TRUE, LINK_AUTH=FALSE and before
      ** AP_Start() could initialize the AP's state.  But there isn't
      ** a problem because we're always in the context of the only task
      ** that does this processing.)
      */

      /* If we requested authentication, wait for it */
      if (lcp_ptr->RECV_OPT.AP != 0) {
         (*lcp_ptr->RECV_OPT.AP_Start)(fsm->HANDLE);
      }

   } else {
   /* Otherwise, call the application's PPP_LINK_UP callback */
      PPP_up(ppp_ptr);
   /* End CR 2158 */
   } /* Endif */

   return TRUE;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_down
* Returned Value  :  void
* Comments        :
*     Called by the FSM when leaving the OPENED state.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void LCP_down
   (
      PPPFSM_CFG_PTR          fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = fsm->HANDLE;
   PPP_CALL_INTERNAL_PTR calldown_ptr = &ppp_ptr->LCP_CALL[PPP_CALL_LINK_DOWN];
   boolean linkauth;

      /* Stop compression */
   CCP_lowerdown(fsm->HANDLE);

   PPP_mutex_lock(&ppp_ptr->MUTEX);
   ppp_ptr->LINK_STATE = FALSE;
   linkauth = ppp_ptr->LINK_AUTH;
   ppp_ptr->RECV_OPTIONS = &PPP_DEFAULT_OPTIONS;
   ppp_ptr->SEND_OPTIONS = &PPP_DEFAULT_OPTIONS;
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_S_ACCM, &PPP_DEFAULT_OPTIONS.ACCM);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_R_ACCM, &PPP_DEFAULT_OPTIONS.ACCM);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_S_PFC,  &PPP_DEFAULT_OPTIONS.PFC);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_R_PFC,  &PPP_DEFAULT_OPTIONS.PFC);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_S_ACFC, &PPP_DEFAULT_OPTIONS.ACFC);
   _iopcb_ioctl(ppp_ptr->DEVICE, IOPCB_IOCTL_R_ACFC, &PPP_DEFAULT_OPTIONS.ACFC);
   PPP_mutex_unlock(&ppp_ptr->MUTEX);

      /* Call the application's PPP_LINK_DOWN callback */
   if (calldown_ptr->CALLBACK && linkauth) {
      (*calldown_ptr->CALLBACK)(calldown_ptr->PARAM);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_up
* Returned Value  :  void
* Comments        :
*     Called when the PPP link goes up.  Called either by LCP
*     when entering the OPENED state, or by an authentication
*     protocol once the peer has authenticated itself.
*
*END*-----------------------------------------------------------------*/

void PPP_up
   (
      _ppp_handle   handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   PPP_CFG_PTR           ppp_ptr    = handle;
   PPP_CALL_INTERNAL_PTR callup_ptr = &ppp_ptr->LCP_CALL[PPP_CALL_LINK_UP];

   if (callup_ptr->CALLBACK) {
      (*callup_ptr->CALLBACK)(callup_ptr->PARAM);
   } /* Endif */

   /* Try to negotiate compression */
   CCP_lowerup(handle);

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/rtcsdela.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcsdela.c$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the interface to the RTCS
*   time delay services.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "rtcstime.h"


typedef struct rtcstime_delay_parm {
   TCPIP_PARM     COMMON;
   TCPIP_EVENT    EXPIRE;
   uint_32        milliseconds;
} RTCSTIME_DELAY_PARM, _PTR_ RTCSTIME_DELAY_PARM_PTR;


static void RTCSTIME_delay(RTCSTIME_DELAY_PARM_PTR);
static boolean RTCSTIME_delay_expire(TCPIP_EVENT_PTR);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_delay
* Returned Value  : void
* Comments        :
*
*  Blocks the calling task until the time (specified in milliseconds)
*  expires.
*
*END*-----------------------------------------------------------------*/

void RTCS_delay
   (
      /*[IN] time length in milliseconds to block task */
      uint_32 milliseconds
   )
{ /* Body */
   RTCSTIME_DELAY_PARM   parms;

   if (milliseconds) {
      parms.milliseconds = milliseconds;
      RTCSCMD_issue(parms, RTCSTIME_delay);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSTIME_delay
* Returned Value  : void
* Comments        :
*
*  Adds an event to the TCPIP timer queue.
*
*END*-----------------------------------------------------------------*/

static void RTCSTIME_delay
   (
      RTCSTIME_DELAY_PARM_PTR     parms
   )
{ /* Body */

   parms->EXPIRE.TIME    = parms->milliseconds;
   parms->EXPIRE.EVENT   = RTCSTIME_delay_expire;
   parms->EXPIRE.PRIVATE = parms;
   TCPIP_Event_add(&parms->EXPIRE);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSTIME_delay_expire
* Returned Value  : FALSE
* Comments        :
*
*  Unblocks the task that called RTCS_time_delay
*
*END*-----------------------------------------------------------------*/

static boolean RTCSTIME_delay_expire
   (
      TCPIP_EVENT_PTR   event
   )
{ /* Body */
   RTCSTIME_DELAY_PARM_PTR  parms = event->PRIVATE;

   RTCSCMD_complete(parms, RTCS_OK);
   return FALSE;

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/istrata/istrata2.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: istrata2.c$
* $Version : 3.8.8.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions to program Intel's StrataFlash 
*   devices
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "istrata.h"
#include "istrataprv.h"

                                          
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_program_2byte
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs a sector of flash for 8 bit devices
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_program_2byte
   (  
      /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR  handle_ptr,

      /* [IN] where to copy data from */
      uint_16_ptr           from_ptr,
      
      /* [OUT} where to copy data to */
      uint_16_ptr           to_ptr,

      /* [IN] the sector size to copy */
      _mem_size             sector_size,

      /* [IN] the offset to start at */
      _mem_size             offset
   )
{ /* Body */
   boolean                 erase;
   boolean                 success;
   boolean                 timeout;
   _mqx_uint               j;
   MQX_TICK_STRUCT         start_ticks;
   _mem_size               size = sector_size >> 1;

   /* 
   ** Check to see if flash needs erasing.
   */ 
   erase    = FALSE;
   offset >>= 1;

   for (j = offset; !erase && (j < size); j++) {
      erase = ISTRATA_ERASE_UNIT(to_ptr[j], from_ptr[j]);
   } /* Endfor */

   if (erase) {
      success = _intel_strata_erase_2byte(handle_ptr, to_ptr, size, 
         &start_ticks);
      if (!success) {
         return success;
      } /* Endif */
      /* 
      ** We erased the whole sector so we must program from the beginning of
      ** the sector
      */
      offset = 0;
   } else {
      success = TRUE;
   } /* Endif */

   if (handle_ptr->DEVICES == 1) {
      volatile uint_16 _PTR_  dest_ptr = (volatile uint_16 _PTR_)to_ptr;
      uint_16 _PTR_           src_ptr  = (uint_16 _PTR_)from_ptr;
      uint_16                 tmp, status;

      dest_ptr = dest_ptr + offset;
      src_ptr  = src_ptr  + offset;

      ISTRATA_PROGRAM(ISTRATA_READ_MODE_CMD_16X1, ISTRATA_WRITE_CMD_16X1, 
         ISTRATA_STATUS_BUSY_16X1);
   } else {
      volatile uint_32 _PTR_  dest_ptr = (volatile uint_32 _PTR_)((pointer)to_ptr);
      uint_32 _PTR_           src_ptr  = (uint_32 _PTR_)((pointer)from_ptr);
      uint_32                 tmp, status;

      size   >>= 1;
      offset >>= 1;
      dest_ptr = dest_ptr + offset;
      src_ptr  = src_ptr  + offset;

      ISTRATA_PROGRAM(ISTRATA_READ_MODE_CMD_16X2, ISTRATA_WRITE_CMD_16X2, 
         ISTRATA_STATUS_BUSY_16X2);
   } /* Endif */

   if ( success ) {
      /* Verify sector is written correctly */
      for( j = 0; j < size; j++ ) {
         if ( from_ptr[j] != to_ptr[j] ) {
            success = FALSE;
            break;
         } /* Endif */
      } /* Endfor */
   } /* Endif */

   return success;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_erase_2byte
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases a sector
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_erase_2byte
   (
      /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR handle_ptr,

      /* [IN] the sector to erase */
      uint_16_ptr          input_sect_ptr,

      /* [IN] the size of the sector */
      _mem_size            sect_size,

      /* [IN/OUT] place to store start time */
      MQX_TICK_STRUCT_PTR  start_ticks_ptr
   )
{ /* Body */
   boolean timeout = FALSE;
   boolean success = TRUE;

   if (handle_ptr->DEVICES == 1) {
      volatile uint_16 _PTR_  dest_ptr = (volatile uint_16 _PTR_)input_sect_ptr;
      uint_16                 status;

      ISTRATA_ERASE(ISTRATA_READ_MODE_CMD_16X1, ISTRATA_ERASE_CMD1_16X1, 
         ISTRATA_ERASE_CMD2_16X1, ISTRATA_STATUS_BUSY_16X1, 0xFFFF);

   } else if (handle_ptr->DEVICES == 2) {
      volatile uint_32 _PTR_  dest_ptr = (volatile uint_32 _PTR_)
         ((pointer)input_sect_ptr);
      uint_32                 status;

      ISTRATA_ERASE(ISTRATA_READ_MODE_CMD_16X2, ISTRATA_ERASE_CMD1_16X2, 
         ISTRATA_ERASE_CMD2_16X2, ISTRATA_STATUS_BUSY_16X2, 0xFFFFFFFF);

   } else {
      success = FALSE;
   } /* Endif */

   return success;

} /* Endbody */


/* Start CR 871 */
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_clearlockbits_2byte
* Returned Value   : TRUE if successful
* Comments         : 
*    This function unlocks all sectors
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_clearlockbits_2byte
   (
      /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR handle_ptr,

      /* [IN/OUT] place to store start time */
      MQX_TICK_STRUCT_PTR  start_ticks_ptr
   )
{ /* Body */
   /* Start CR 2077 */
   FLASHX_BLOCK_INFO_STRUCT_PTR   hw_block;
   uint_32 block_size;
   uint_32 num_blocks;
   uint_32 i;
   boolean timeout = FALSE;
   boolean success = TRUE;

   hw_block = handle_ptr->HW_BLOCK;

   /*
   ** All blocks default to the locked state after initial power-up or reset.
   ** The blocks are unlocked individually.
   */
   while (hw_block->NUM_SECTORS) {
         
      num_blocks = hw_block->NUM_SECTORS; /* sector == block */
      block_size = hw_block->SECTOR_SIZE;      

   if (handle_ptr->DEVICES == 1) {
      volatile uint_16 _PTR_  dest_ptr;
      uint_16                 status;

      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uint_16 _PTR_)(handle_ptr->BASE_ADDR + hw_block->START_ADDR + i * block_size);

         ISTRATA_CLEAR_LOCKBITS(ISTRATA_READ_MODE_CMD_16X1, ISTRATA_CLEAR_CMD1_16X1, 
            ISTRATA_CLEAR_CMD2_16X1, ISTRATA_STATUS_BUSY_16X1);
      } /* Endfor */
      
   } else if (handle_ptr->DEVICES == 2) {
      volatile uint_32 _PTR_  dest_ptr;
      uint_32                 status;
      
      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uint_32 _PTR_)(handle_ptr->BASE_ADDR + hw_block->START_ADDR + i * block_size);
         
         ISTRATA_CLEAR_LOCKBITS(ISTRATA_READ_MODE_CMD_16X2, ISTRATA_CLEAR_CMD1_16X2, 
            ISTRATA_CLEAR_CMD2_16X2, ISTRATA_STATUS_BUSY_16X2);
      } /* Endfor */

   } else {
      success = FALSE;
   } /* Endif */
      
      hw_block++;      
   } /* Endwhile */
   /* End CR 2077 */

   return success;

} /* Endbody */
/* End CR 871 */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_setlockbits_2byte
* Returned Value   : TRUE if successful
* Comments         : 
*    This function locks all sectors
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_setlockbits_2byte
   (
      /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR handle_ptr,

      /* [IN/OUT] place to store start time */
      MQX_TICK_STRUCT_PTR  start_ticks_ptr
   )
{ /* Body */
   uint_32 block_size;
   uint_32 num_blocks;
   uint_32 i;
   boolean timeout = FALSE;
   boolean success = TRUE;

   num_blocks = handle_ptr->HW_BLOCK->NUM_SECTORS; /* sector == block */
   block_size = handle_ptr->HW_BLOCK->SECTOR_SIZE;

   /*
   ** The blocks are locked individually.
   */
   if (handle_ptr->DEVICES == 1) {
      volatile uint_16 _PTR_  dest_ptr;
      uint_16                 status;

      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uint_16 _PTR_)(handle_ptr->BASE_ADDR + handle_ptr->HW_BLOCK[0].START_ADDR + i * block_size);
         
         ISTRATA_SET_LOCKBITS(ISTRATA_READ_MODE_CMD_16X1, ISTRATA_SET_CMD1_16X1, 
            ISTRATA_SET_CMD2_16X1, ISTRATA_STATUS_BUSY_16X1);
      } /* Endfor */
      
   } else if (handle_ptr->DEVICES == 2) {
      volatile uint_32 _PTR_  dest_ptr;
      uint_32                 status;
      
      for(i = 0; i < num_blocks; i++) {
         dest_ptr = (volatile uint_32 _PTR_)(handle_ptr->BASE_ADDR + handle_ptr->HW_BLOCK[0].START_ADDR + i * block_size);

         ISTRATA_SET_LOCKBITS(ISTRATA_READ_MODE_CMD_16X2, ISTRATA_SET_CMD1_16X2, 
            ISTRATA_SET_CMD2_16X2, ISTRATA_STATUS_BUSY_16X2);
      } /* Endfor */

   } else {
      success = FALSE;
   } /* Endif */

   return success;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_inst.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_inst.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the function for installing a dynamic device
*   driver.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#ifdef NULL
  #undef NULL
#endif
#include <string.h>
#ifndef NULL
  #define NULL ((pointer)0)
#endif

#if MQX_USE_IO

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dev_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a device dynamically, so tasks can fopen to it.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_dev_install
(
 /* [IN] A string that identifies the device for fopen */
 char_ptr      identifier,

 /* [IN] The I/O open function */
 IO_OPEN_FPTR  io_open,

 /* [IN] The I/O close function */
 IO_CLOSE_FPTR io_close,

 /* [IN] The I/O read function */
 IO_READ_FPTR  io_read,

 /* [IN] The I/O write function */
 IO_WRITE_FPTR io_write,

 /* [IN] The I/O ioctl function */
 IO_IOCTL_FPTR io_ioctl,

 /* [IN] The I/O initialization data */
 pointer       io_init_data_ptr
 )
{ /* Body */

  return (_io_dev_install_ext(identifier, io_open, io_close, io_read, io_write,
                              io_ioctl, (IO_UNINSTALL_FPTR)NULL, io_init_data_ptr));

} /* Endbody */
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/snmp/trap_receivers.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: trap_receivers.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   
*
*END************************************************************************/
#include <rtcs.h>
#include "rtcs_prv.h"
#include "snmpcfg.h"
#include "asn1.h"
#include "snmp.h"

#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4 
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCS_insert_trap_receiver_internal
*  Parameters     :
*
*     _ip_address          address     will be inserted into 
*                                      RTCS_trap_receivers_table
*
*  Comments       :
*        Registers an SNMP trap receiver with RTCS.
*
*END*-----------------------------------------------------------------*/

void RTCS_insert_trap_receiver_internal
   (
      TRAP_PARM _PTR_ parm
   )
{ /* Body */
   volatile SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   _ip_address       ip_addr = parm->address;
   _mqx_uint         i;
   
   /* Find an empty entry in the receivers list */
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] == 0) {
         /* Found a space */
         snmpcfg->trap_receiver_list[i] = ip_addr;
         break;
      } /* Endif */     
   } /* Endfor */
      
   if (i < SNMPCFG_MAX_TRAP_RECEIVERS) {
      RTCSCMD_complete(parm, RTCS_OK);
   } else {
      RTCSCMD_complete(parm, RTCSERR_TRAP_INSERT_FAILED);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCS_remove_trap_receiver_internal
*  Parameters     :
*
*     _ip_address          address     will be removed from 
*                                      RTCS_trap_receivers_table
*
*  Comments       :
*        Unregisters an SNMP trap receiver from RTCS.
*
*END*-----------------------------------------------------------------*/

void RTCS_remove_trap_receiver_internal
   (
      TRAP_PARM _PTR_ parm
   )
{ /* Body */
   volatile SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
   _ip_address       ip_addr = parm->address;
   _mqx_uint         i;
   
   /* Traverse the receivers list looking for our entry */
   for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
      if (snmpcfg->trap_receiver_list[i] == ip_addr) {
         /* Found it */
         snmpcfg->trap_receiver_list[i] = 0;
         break;
      } /* Endif */     
   } /* Endfor */
      
   if (i < SNMPCFG_MAX_TRAP_RECEIVERS) {
      RTCSCMD_complete(parm, RTCS_OK);
   } else {
      RTCSCMD_complete(parm, RTCSERR_TRAP_REMOVE_FAILED);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCS_count_trap_receivers_internal
*  Parameters     :
*  Comments       : Returns the number of receivers installed
*
*END*-----------------------------------------------------------------*/

_mqx_uint RTCS_count_trap_receivers_internal
   (
      void
   )
{ /* Body */
    volatile SNMP_PARSE_PTR    snmpcfg = SNMP_get_data();
    _mqx_uint         i;
    _mqx_uint         count = 0;

    for (i = 0; i < SNMPCFG_MAX_TRAP_RECEIVERS; i++) {
       if (snmpcfg->trap_receiver_list[i] != 0) {
         count++;
       } /* Endif */     
    } /* Endfor */
   
   return count;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4 */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/dhcpsrv.h<|end_filename|>
#ifndef __dhcpsrv_h__
#define __dhcpsrv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dhcpsrv.h$
* $Version : 3.6.6.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   Dynamic Host Configuration Protocol definitions.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

#define DHCPTIME_OFFER  10       /* 10 seconds */

/* Start CR 1547 */
#define DHCPSVR_FLAG_DO_PROBE   0x00000001
/* End CR 1547 */

/***************************************
**
** Type definitions
**
*/

typedef struct dhcpsrv_options_struct {

   uint_32        COUNT;

   _ip_address    SERVERID;
   uint_32        LEASE;
   uint_32        MASK;

   uchar_ptr      OPTION_PTR;
   uint_32        OPTION_LEN;

   _ip_address    SADDR;
   uchar          SNAME[64];
   uchar          FILE[128];

} DHCPSRV_OPTIONS_STRUCT, _PTR_ DHCPSRV_OPTIONS_STRUCT_PTR;

typedef struct dhcpsrv_addr_struct {

   struct dhcpsrv_addr_struct  _PTR_ NEXT;
   uint_32                    EXPIRE;
   uint_32                    OFFER;
   uint_32                    CLIENTID_LEN;
   uchar_ptr                  CLIENTID_PTR;

   _ip_address                IP_ADDR;
   DHCPSRV_OPTIONS_STRUCT_PTR OPTIONS;

} DHCPSRV_ADDR_STRUCT, _PTR_ DHCPSRV_ADDR_STRUCT_PTR;

typedef struct dhcpsrv_state_struct {

   uchar                   SND_BUFFER[DHCP_MSGSIZE_MIN];
   uchar                   RCV_BUFFER[DHCP_MSGSIZE_MIN];
   uint_32                 SND_BUFFER_LEN;
   uint_32                 RCV_BUFFER_LEN;
   uint_32                 SOCKET;
   uint_32                 TIME;
   _rtcs_mutex             IPLIST_SEM;
   /* Start CR 1547 */
   uint_32                 FLAGS;
   /* End CR 1547 */
   DHCPSRV_ADDR_STRUCT_PTR IP_AVAIL;
   DHCPSRV_ADDR_STRUCT_PTR IP_OFFERED;
   DHCPSRV_ADDR_STRUCT_PTR IP_LEASED;
   /* Start CR 1547 */
   DHCPSRV_ADDR_STRUCT_PTR IP_TAKEN;
   /* End CR 1547 */

} DHCPSRV_STATE_STRUCT, _PTR_ DHCPSRV_STATE_STRUCT_PTR;


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/USB_DRIVER/usb_framework.h<|end_filename|>
/******************************************************************************
 *
 * Freescale Semiconductor Inc.
 * (c) Copyright 2004-2009 Freescale Semiconductor, Inc.
 * ALL RIGHTS RESERVED.
 *
 ******************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************//*!
 *
 * @file usb_framwork.h
 *
 * @author
 *
 * @version
 *
 * @date May-28-2009
 *
 * @brief The file contains USB Framework module API header function.
 *
 *****************************************************************************/

#ifndef _USB_FRAMEWORK_H
#define _USB_FRAMEWORK_H

/******************************************************************************
 * Includes
 *****************************************************************************/

#include "usb_class.h"
#include "usb_descriptor.h"

/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
#define MAX_STRD_REQ                (13)  /* Max value of standard request */
/* size of data to be returned for various Get Desc calls */
#define DEVICE_STATUS_SIZE          (2)
#ifdef OTG_BUILD
#define OTG_STATUS_SIZE             (2)
#endif
#define INTERFACE_STATUS_SIZE       (1)
#define CONFIG_SIZE                 (1)
#define FRAME_SIZE                  (2)
#define ENDP_STATUS_SIZE            (2)

#ifdef OTG_BUILD
#define DEVICE_SET_FEATURE_B_HNP_ENABLE   (0x0003) /* B HNP enable  SET/CLEAR feature value */
#define DEVICE_SET_FEATURE_A_HNP_SUPPORT  (0x0004) /* A HNP support SET/CLEAR feature value */
#endif

#define DEVICE_FEATURE_REMOTE_WAKEUP      (0x0001)
#define DEVICE_SET_FEATURE_MASK           ((INT16U)(1<<(DEVICE_FEATURE_REMOTE_WAKEUP)))
#define DEVICE_CLEAR_FEATURE_MASK         ((INT16U)(1<<(DEVICE_FEATURE_REMOTE_WAKEUP)))


#define REPORT_DESCRIPTOR_TYPE      (0x22)
#define STRING_DESCRIPTOR_TYPE      (0x03)

/* masks and values for provides of Get Desc information */
#define USB_REQUEST_SRC_MASK        (0x03)
#define USB_REQUEST_SRC_DEVICE      (0x00)
#define USB_REQUEST_SRC_INTERFACE   (0x01)
#define USB_REQUEST_SRC_ENDPOINT    (0x02)

#define  USB_SET_REQUEST_MASK       (0x02)

/* wIndex values for GET_Status */
#ifdef OTG_BUILD
#define USB_WINDEX_OTG_STATUS_SEL   (0xF000)
#endif

/* for transfer direction check */
#define USB_DATA_TO_HOST            (0x80)
#define USB_DATA_TO_DEVICE          (0x00)
#define USB_DATA_DIREC_MASK         (0x80)

#define USB_uint_16_low(x)  ((INT8U)x)       /* lsb byte */
#define USB_uint_16_high(x) ((INT8U)(x>>8))  /* msb byte */

#define BYTE_SWAP16(a) 	(a)

/******************************************************************************
 * Types
 *****************************************************************************/

/******************************************************************************
 * Global Functions
 *****************************************************************************/
extern BOOLEAN USB_Frame_Remote_Wakeup(INT8U controller_ID);

#define USB_Frame_Remote_Wakeup USB_Desc_Remote_Wakeup

extern INT8U USB_Framework_Init (
    INT8U              controller_ID,
    USB_CLASS_CALLBACK  callback,
    USB_REQ_FUNC        other_req_callback
);

extern INT8U USB_Framework_DeInit
(
    INT8U controller_ID      
);

extern INT8U USB_Framework_Reset (
    INT8U    controller_ID
);
#ifdef DELAYED_PROCESSING
extern void USB_Framework_Periodic_Task(void);
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_AtanYXShifted.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_AtanYXShifted.h
*
* @author   <NAME>
* 
* @version  1.0.1.0
* 
* @date     Dec-6-2012
* 
* @brief    Header file for #GFLIB_AtanYXShifted function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GFLIB_ATANYXSHIFTED_H_
#define _GFLIB_ATANYXSHIFTED_H_

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif
/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*!
  \def GFLIB_AtanYXShifted
  Function alias for the #GFLIB_AtanYXShiftedANSIC function.
*/
#define GFLIB_AtanYXShifted(y, x, p) GFLIB_AtanYXShiftedANSIC((y), (x), (p))

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/

/*------------------------------------------------------------------------*//*!
@struct		GFLIB_ATANYXSHIFTED_T "\GFLIB_AtanYXShiftedANSIC.h"

@brief		Structure containing the parameter for the AtanYXShifted
            function.

*//*-------------------------------------------------------------------------*/

typedef struct
{    
    Frac32     f32Ky;  /*!<Multiplication coefficient for the y-signal. */
    Frac32     f32Kx;  /*!<Multiplication coefficient for the x-signal. */
    Word32     w32Ny;  /*!<Scaling coefficient for the y-signal. */
    Word32     w32Nx;  /*!<Scaling coefficient for the x-signal. */
    Frac32     f32ThetaAdj; /*!<Adjusting angle. */
    
} GFLIB_ATANYXSHIFTED_T;

/******************************************************************************
* Exported Variables
******************************************************************************/

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*! 
* @ingroup GFLIB_GROUP 
*/ 
extern Frac32 GFLIB_AtanYXShiftedANSIC(Frac32 f32InY, Frac32 f32InX,
                const GFLIB_ATANYXSHIFTED_T * const pParam);

/******************************************************************************
* Inline functions
******************************************************************************/ 

#endif /* _GFLIB_ATANYXSHIFTED_H_*/


<|start_filename|>Firmware/Inverter_firmware/Main/CAN_control.h<|end_filename|>
#ifndef __CAN_CONTROL
  #define __CAN_CONTROL

  #define CAN_DEVICE  0

  #define CAN_SPEED   100000

  #define CAN_MIN_TQ  8
  #define CAN_MAX_TQ  25

  #define CAN_MAX_PROPSEG 8
  #define CAN_MAX_RJW 4
  #define CAN_MIN_PSEG2 2


  // Майлбоксы на чтение
  #define CAN_RX_MB1     0
  #define CAN_RX_MB2     1
  #define CAN_RX_MB3     2
  #define CAN_RX_MB4     3
  #define CAN_RX_MB5     4
  #define CAN_RX_MB6     5
  #define CAN_RX_MB7     6
  #define CAN_RX_MB8     7
  // Всего майлбоксов на чтение
  #define RX_MBOX_CNT    8

  // Майлбоксы на передачу
  #define CAN_TX_MB1     8

  // Количество сообщений в логе приемника
  #define CAN_RX_LOG_SZ  128



typedef struct
{
  INT32U pseg1;
  INT32U pseg2;
  INT32U propseg;
  INT32U rjw;
  INT32U presdiv;
}
T_can_ctrl;


typedef struct
{
  INT32U canid;   //Полученый идентификатор CAN пакета
  INT8U  data[8]; //Буффер с данными длинной 8 байт
  INT8U  len;     //Длина данных
  INT8U  ext;     //Формат идентификатора(расширенный = 1, стандартный = 0)
  INT8U  rtr;     //Признак  Remote Request Frame
  INT8U  code;
}
T_can_rx;

typedef struct
{
  INT8U  mb_num;
  INT32U canid;
  INT32U canid_mask;

} T_can_rx_config;


int  CAN_init(CAN_MemMapPtr ptr, INT32U bitrate);
void CAN_Tx_Task(uint_32 parameter);
void CAN_Rx_Task(uint_32 parameter);

_mqx_uint CAN_wait_log_rec(_mqx_uint ticks);
_mqx_uint CAN_pop_log_rec(T_can_rx  *rx);

#endif


<|start_filename|>Firmware/Inverter_firmware/mfs/source/include/part_mgr.h<|end_filename|>
#ifndef __part_mgr_h__
#define __part_mgr_h__
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: part_mgr.h$
* $Version : 3.8.10.0$
* $Date    : Aug-23-2012$
*
* Comments:
*
*   This file contains internal data structures and constants
*   used to manage partitions.
*
*END************************************************************************/


/*
**  Defines constant for partiton
*/
#define  PMGR_VALID_STATE              1
#define  PMGR_INVALID_STATE            0

#define  PMGR_PARTITION_TABLE_OFFSET   0x01BE
#define  PMGR_MAX_PARTITIONS           0x04
#define  PMGR_ENTRY_SIZE               0x10

/* The 2 extra bytes store a validation signature */
#define  PMGR_PART_TABLE_SIZE          PMGR_ENTRY_SIZE * PMGR_MAX_PARTITIONS + 2


/*
** Partition types
*/
#define  PMGR_PARTITION_NOT_USED        0x00
#define  PMGR_PARTITION_FAT_12_BIT      0x01
#define  PMGR_PARTITION_FAT_16_BIT      0x04
#define  PMGR_PARTITION_HUGE            0x06
#define  PMGR_PARTITION_FAT32           0x0B
#define  PMGR_PARTITION_FAT32_LBA       0x0C
#define  PMGR_PARTITION_HUGE_LBA        0x0E


/* Structure of a partition entry on the disk */
typedef struct pmgr_part_entry_struct
{
   /* Active flag (0 = not bootable, 0x80 = bootable) */
   uchar     ACTIVE_FLAG;

   /* Starting head */
   uchar     START_HEAD;

   /* Starting sector/cylinder */
   uchar     START_SECT_CYL;

   /* Starting cylinder */
   uchar     START_CYLINDER;

   /* Partition type (0 not used, 1 FAT 12 bit, 4 FAT 16 bit, 5 extended,
   **                 6 huge - DOS 4.0+, 0x0B FAT32, 0x0C FAT32 LBA,
   **                 0x0E FAT16 LBA)
   */
   uchar     TYPE;

   /* Ending head */
   uchar     ENDING_HEAD;

   /* Ending sector/cylinder */
   uchar     ENDING_SECT_CYL;

   /* Ending cylinder */
   uchar     ENDING_CYLINDER;

   /* Starting sector for partition, relative to beginning of disk */
   uchar     START_SECTOR[4];

   /* Partition length in sectors */
   uchar     LENGTH[4];

} PMGR_PART_ENTRY_STRUCT, _PTR_ PMGR_PART_ENTRY_STRUCT_PTR;


/* Structure passed to/from ioctl call IO_IOCTL_GET_PARTITION and IO_IOCTL_SET_PARTITION */
typedef struct pmgr_part_info_struct
{
   /* Partition slot (1 to 4) */
   uchar     SLOT;

   /* Partition type */
   uchar     TYPE;

   /* Active flag (0 = not bootable, 0x80 = bootable) */
   uchar     ACTIVE_FLAG;

   /* Padding */
   uint_8    RESERVED;

   /* Starting sector for partition, relative to beginning of disk */
   uint_32   START_SECTOR;

   /* Partition length in sectors */
   uint_32   LENGTH;

   /* Heads per Cylinder */
   uchar     HEADS;

   /* Sectors per head */
   uchar     SECTORS;

   /* Cylinders on the device */
   uint_16   CYLINDERS;

} PMGR_PART_INFO_STRUCT, _PTR_ PMGR_PART_INFO_STRUCT_PTR;


typedef struct part_mgr_struct
{
    MQX_FILE_PTR                     DEV_FILE_PTR;
    LWSEM_STRUCT                     SEM;
    uint_32                          DEV_SECTOR_SIZE;
    uint_32                          DEV_NUM_SECTORS;
    boolean                          BLOCK_MODE;
    uint_32                          INSTANCES;
} PART_MGR_STRUCT, _PTR_ PART_MGR_STRUCT_PTR;


/* Macros for byte exchange between disk and host */
#if (PSP_MEMORY_ADDRESSING_CAPABILITY == 8)
#define pmgr_htodl(p,x) \
                   ((p)[3] = (uchar) ((x) >> 24) , \
                    (p)[2] = (uchar) ((x) >> 16) , \
                    (p)[1] = (uchar) ((x) >>  8) , \
                    (p)[0] = (uchar) ((x)      )  \
                    )

#define pmgr_htods(p,x) \
                   ((p)[1] = (uchar) ((x) >>  8) , \
                    (p)[0] = (uchar) ((x)      )  \
                   )

#define pmgr_htodc(p,x) \
                   ((p)[0] = ((x)      ) , \
                    )

#define pmgr_dtohl(p)   \
                   ((((uint_32)(p)[3] ) << 24) | \
                    (((uint_32)(p)[2] ) << 16) | \
                    (((uint_32)(p)[1] ) <<  8) | \
                    (((uint_32)(p)[0] )      ))

#define pmgr_dtohs(p)  \
                  ((((uint_16)(p)[1] ) <<  8) | \
                   (((uint_16)(p)[0] )      ))

#define pmgr_dtohc(p)   ((((  uchar)(p)[0] )      ))
#else
#define pmgr_htodl(p,x) \
                   ((p)[3] = ((x) >> 24) & 0xFF, \
                    (p)[2] = ((x) >> 16) & 0xFF, \
                    (p)[1] = ((x) >>  8) & 0xFF, \
                    (p)[0] = ((x)      ) & 0xFF \
                    )

#define pmgr_htods(p,x) \
                   ((p)[1] = ((x) >>  8) & 0xFF, \
                    (p)[0] = ((x)      ) & 0xFF \
                   )

#define pmgr_htodc(p,x) \
                   ((p)[0] = ((x)      ) & 0xFF, \
                    )

#define pmgr_dtohl(p)   \
                   ((((uint_32)(p)[3] & 0xFF) << 24) | \
                    (((uint_32)(p)[2] & 0xFF) << 16) | \
                    (((uint_32)(p)[1] & 0xFF) <<  8) | \
                    (((uint_32)(p)[0] & 0xFF)      ))

#define pmgr_dtohs(p)  \
                  ((((uint_16)(p)[1] & 0xFF) <<  8) | \
                   (((uint_16)(p)[0] & 0xFF)      ))

#define pmgr_dtohc(p)   ((((  uchar)(p)[0] & 0xFF)      ))
#endif



#ifdef __cplusplus
extern "C" {
#endif

extern int_32
   _io_part_mgr_install(
      MQX_FILE_PTR                  dev_fd,
      char_ptr                      identifier,
      uint_32                       sector_size);

extern int_32
   _io_part_mgr_uninstall(
      char_ptr                      identifier);

extern int_32
   _io_part_mgr_open(
      MQX_FILE_PTR                  fd_ptr,
      char_ptr                      open_name_ptr,
      char_ptr                      flags_str);

extern int_32
   _io_part_mgr_close(
      MQX_FILE_PTR                  fd_ptr);

extern int_32
   _io_part_mgr_read(
      MQX_FILE_PTR                  file_ptr,
      char_ptr                      data_ptr,
      int_32                        num);

extern int_32
   _io_part_mgr_write(
      MQX_FILE_PTR                  file_ptr,
      char_ptr                      data_ptr,
      int_32                        num);

extern int_32
   _io_part_mgr_ioctl(
      MQX_FILE_PTR                  file_ptr,
      uint_32                       cmd,
      uint_32_ptr                   param_ptr);

extern int_32
    _pmgr_check_part_type(
        uint_32                     part_type);

extern int_32
   _pmgr_validate_mbr(
      char_ptr                      mbr_ptr);

extern int_32
   _pmgr_get_part_info(
      PART_MGR_STRUCT_PTR           part_mgr_ptr,
      PMGR_PART_INFO_STRUCT_PTR     host_entry);

extern int_32
   _pmgr_set_part_info(
      PART_MGR_STRUCT_PTR           part_mgr_ptr,
      PMGR_PART_INFO_STRUCT_PTR     host_entry);

extern int_32
   _pmgr_clear_part_info(
      PART_MGR_STRUCT_PTR           part_mgr_ptr,
      uchar                         part_num);

extern void
   _pmgr_disk_to_host(
      PMGR_PART_ENTRY_STRUCT_PTR    disk_entry,
      PMGR_PART_INFO_STRUCT_PTR     part_entry);

extern void
   _pmgr_host_to_disk(
      PMGR_PART_INFO_STRUCT_PTR     part_entry,
      PMGR_PART_ENTRY_STRUCT_PTR    disk_entry);


#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ccp.h<|end_filename|>
#ifndef __ccp_h__
#define __ccp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ccp.h$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the defines and data structure
*   definitions required by CCP.
*
*END************************************************************************/

/*
** CCP-specific packet types
*/

#define CCP_CODE_RESET_REQ 14      /* Reset Request */
#define CCP_CODE_RESET_ACK 15      /* Reset Ack */


/*
** CCP Configuration Options
*/

#define CCP_CI_PRED1    1     /* Predictor type 1 */
#define CCP_CI_LZS      17    /* Stac LZS */


struct ccp_opt;
struct ppp_opt;
struct ppp_cfg;

/*
** The Compression Protocol Data Union.  This union contains the private
** data required by each supported compression method.
*/

typedef union cp_data {
   uint_32     DUMMY;
} CP_DATA, _PTR_ CP_DATA_PTR;

/*
** The Compression Procotol Call Table structure.  This structure
** contains pointers to functions that compress and decompress packets.
*/

typedef struct cp_call {
   void    (_CODE_PTR_ CP_init)  (CP_DATA_PTR, struct ccp_opt _PTR_);
   PCB_PTR (_CODE_PTR_ CP_comp)  (CP_DATA_PTR, PCB_PTR,
                                  struct ppp_cfg _PTR_, struct ppp_opt _PTR_);
   PCB_PTR (_CODE_PTR_ CP_decomp)(CP_DATA_PTR, PCB_PTR,
                                  struct ppp_cfg _PTR_, struct ppp_opt _PTR_);

   void    (_CODE_PTR_ CP_resetreq) (CP_DATA_PTR, PCB_PTR);
   void    (_CODE_PTR_ CP_resetack) (CP_DATA_PTR, PCB_PTR);
} CP_CALL, _PTR_ CP_CALL_PTR;

/*
** The CCP Options structure.  This structure contains all the
** negotiated options for an open CCP link.
*/

typedef struct ccp_opt {
   CP_CALL_PTR    CP;
   union {
      uint_32     DUMMY;
#ifdef PPP_CP_LZS
      struct {
         uint_16  HIST;
         uchar    CHECK;
      }           LZS;
#endif
   }              DATA;
} CCP_OPT, _PTR_ CCP_OPT_PTR;

/*
** The CCP Options state used during negotiation
*/

typedef struct ccp_neg {
   unsigned NEG_PRED1 : 1;    /* Not used */
   unsigned NEG_LZS   : 1;    /* Not used */
   unsigned           : 0;
#ifdef PPP_CP_LZS
   uint_16  LZS_HIST;
   uchar    LZS_CHECK;
#endif
} CCP_NEG, _PTR_ CCP_NEG_PTR;

/*
** The CCP Configuration structure
*/

typedef struct ccp_cfg {

   /* Statistics counters */
   uint_32  ST_CCP_RX_RESET;
   uint_32  ST_CCP_RX_ACK;

   CCP_OPT  SEND_OPT;
   CCP_OPT  RECV_OPT;
   CCP_NEG  RECV_NEG;
   CP_DATA  SEND_DATA;
   CP_DATA  RECV_DATA;
} CCP_CFG, _PTR_ CCP_CFG_PTR;


/*
** Prototypes
*/

extern uint_32 CCP_init    (_ppp_handle);
extern uint_32 CCP_destroy (_ppp_handle);

#define CCP_lowerup(handle)   PPPFSM_lowerup(&((PPP_CFG_PTR)(handle))->CCP_FSM)
#define CCP_lowerdown(handle) PPPFSM_lowerdown(&((PPP_CFG_PTR)(handle))->CCP_FSM)
#define CCP_open(handle)      PPPFSM_open(&((PPP_CFG_PTR)(handle))->CCP_FSM, 0)
#define CCP_close(handle)     PPPFSM_close(&((PPP_CFG_PTR)(handle))->CCP_FSM)
#define CCP_input             PPPFSM_input

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/btnled.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: btnled.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines, structure
*   definitions for HMI btn_led driver
*
*END************************************************************************/
#ifndef __btnled_h__
#define __btnled_h__ 1

#include "psptypes.h"
#include "mqx.h"
#include "bsp.h"
#include "hmi_client.h"


typedef struct btnled_clbreg
{
    uint_32 STATE;                              /* callback register state */
    uint_32 UID;                                /* UID */
    pointer CALLBACK_PARAMETER;                 /* callback parameter */
    void(_CODE_PTR_ CLBFUNCTION) (pointer);     /* callback function */
    struct btnled_clbreg _PTR_ NEXT_CALLBACK;   /* next callback */
}BTNLED_CLBREG_STRUCT, _PTR_ BTNLED_CLBREG_STRUCT_PTR;

typedef struct btnled_context
{
    BTNLED_CLBREG_STRUCT_PTR    CLBREG;             /* pointer to callback register structure */
    LWSEM_STRUCT                LOCK_BTNLED_SEM;    /* semaphore structure */
}BTNLED_CONTEXT_STRUCT, _PTR_ BTNLED_CONTEXT_STRUCT_PTR;

#ifdef __cplusplus
extern "C" {
#endif
HMI_CLIENT_STRUCT_PTR btnled_init(void);
void btnled_poll(HMI_CLIENT_STRUCT_PTR);
boolean btnled_get_value(HMI_CLIENT_STRUCT_PTR, uint_32, uint_32_ptr);
boolean btnled_set_value(HMI_CLIENT_STRUCT_PTR, uint_32, uint_32);
boolean btnled_toogle(HMI_CLIENT_STRUCT_PTR, uint_32);
BTNLED_CLBREG_STRUCT_PTR btnled_add_clb(HMI_CLIENT_STRUCT_PTR, uint_32, uint_32, void(CODE_PTR)(pointer), pointer);
boolean btnled_remove_clb(HMI_CLIENT_STRUCT_PTR, BTNLED_CLBREG_STRUCT_PTR);
uint_32 btnled_deinit(HMI_CLIENT_STRUCT_PTR);
#ifdef __cplusplus
}
#endif
#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/flashxprv.h<|end_filename|>
#ifndef _flashxprv_h_
#define _flashxprv_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flashxprv.h$
* $Version : 3.8.10.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions private to the flash drivers
*
*END************************************************************************/


/*----------------------------------------------------------------------*/
/*
**                    Structure Definitions
*/

/*
** The address of this structure is used to maintain flash specific 
** information.
*/
typedef struct io_flashx_struct
{
    /* The function to call to erase a sector on the device */
    boolean (_CODE_PTR_           SECTOR_ERASE)(struct io_flashx_struct *, char_ptr, _mem_size);

    /* The function to call to program a sector on the device */
    boolean (_CODE_PTR_           SECTOR_PROGRAM)(struct io_flashx_struct *, char_ptr, char_ptr, _mem_size);
   
    /* The function to call to erase the entire device */
    boolean (_CODE_PTR_           CHIP_ERASE)(struct io_flashx_struct *);
   
    /* The function to call to read data from flash */
    _mqx_int (_CODE_PTR_          READ)(struct io_flashx_struct *, char_ptr, char_ptr, _mem_size);

    /* The function to call to initialize the device */
    boolean (_CODE_PTR_           INIT)(struct io_flashx_struct *);
   
    /* The function to call to disable the device */
    void (_CODE_PTR_              DEINIT)(struct io_flashx_struct *);

    /* The function to call to write enable or protect the device */
    boolean (_CODE_PTR_           WRITE_PROTECT)(struct io_flashx_struct *, _mqx_uint);
   
    /* The ioctl function to call */
    _mqx_int (_CODE_PTR_          IOCTL)(struct io_flashx_struct *, _mqx_uint, pointer);

    /* Base address of the flash device. Useful for external flash devices
    ** whose address space is determined by BSP.
    */
    _mem_size                     BASE_ADDR;

    /* This array of strutures provides the description of HW flash configuration */ 
    FLASHX_BLOCK_INFO_STRUCT_PTR  HW_BLOCK;
   
    /* This array of strutures provides the description of HW flash configuration */ 
    FLASHX_FILE_BLOCK_PTR         FILE_BLOCK;
   
    /* The bus width of the device (in bytes, i.e. WIDTH = 4 for 32 bits) */
    _mqx_uint                     WIDTH;
   
    /* The number of parallel devices */
    _mqx_uint                     DEVICES;
   
    /* Light weight semaphore for HW access exclusion */
    LWSEM_STRUCT                  HW_ACCESS;

    /* Number of files opened */
    _mqx_uint                     FILES;
   
    /* Flags */
    _mqx_uint                     FLAGS;
   
    /* When finished programming, should a comparison of data be made
    ** to verify that the write worked correctly.
    */
    _mqx_uint                     WRITE_VERIFY;

    /* The address of device specific structure got in init phase */ 
    pointer                       DEVICE_SPECIFIC_INIT;

    /* The address of device specific structure */ 
    pointer                       DEVICE_SPECIFIC_DATA;

} IO_FLASHX_STRUCT, _PTR_ IO_FLASHX_STRUCT_PTR;

typedef struct io_flashx_file_struct
{
    /* HW block reference */
    FLASHX_FILE_BLOCK const _PTR_ FILE_BLOCK;

    /* Next four are needed for caching data */
    _mqx_uint                     DIRTY_DATA;
    _mqx_int                      CACHE_BLOCK;
    _mqx_int                      CACHE_SECTOR;
    _mqx_int                      CACHE_FILE_SECTOR;
    /* One sector cache memory of size MAX_SECT_SIZE */
    char_ptr                      CACHE_PTR;

    /* The maximum sector size of this file: useful for allocating cache space */
    _mem_size                     MAX_SECT_SIZE;

    /* The size of the erase array in bytes */
    _mqx_uint                     ERASE_ARRAY_MAX;

    /* The address of erase check array */
    uint_8 _PTR_                  ERASE_ARRAY;

    /* Flags */
    _mqx_uint                     FLAGS;
   
} IO_FLASHX_FILE_STRUCT, _PTR_ IO_FLASHX_FILE_STRUCT_PTR;

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

_mqx_int  _io_flashx_flush_buffer(MQX_FILE_PTR); 
_mqx_int  _io_flashx_flush_sector_buffer(MQX_FILE_PTR); 
 boolean  _io_flashx_erase_sector(MQX_FILE_PTR, _mqx_uint, _mqx_uint, _mqx_uint);
FLASHX_BLOCK_INFO_STRUCT_PTR _io_flashx_phys_to_sector(IO_FLASHX_STRUCT_PTR, _mem_size, _mqx_uint _PTR_, _mem_size _PTR_, _mem_size _PTR_);
 void     _io_flashx_find_correct_sectors(MQX_FILE_PTR, _mqx_uint, _mqx_uint _PTR_, _mqx_uint _PTR_, _mqx_uint _PTR_, _mqx_uint _PTR_);
_mqx_int  _io_flashx_open(MQX_FILE_PTR, char_ptr, char_ptr);
_mqx_int  _io_flashx_close(MQX_FILE_PTR);
_mqx_int  _io_flashx_write(MQX_FILE_PTR, char_ptr, _mqx_int);
_mqx_int  _io_flashx_read(MQX_FILE_PTR, char_ptr, _mqx_int);
_mqx_int  _io_flashx_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);
_mem_size _io_flashx_write_partial_sector(MQX_FILE_PTR, _mqx_uint, _mqx_uint, _mem_size, _mem_size, _mqx_uint, char_ptr);
_mem_size _io_flashx_check_free_space(char_ptr, _mem_size);
void      _io_flashx_wait_us(_mqx_int);

boolean _allocate_sector_cache(MQX_FILE_PTR);
   
#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mpxs30.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mpxs30.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the default initialization record for the
*   flash device.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "flash_c90_prv.h"
#include "flash_c90i_prv.h"

#define K1      (1024)
#define K16     (16*K1)
#define K32     (32*K1)
#define K64     (64*K1)
#define K128    (128*K1)
#define K256    (256*K1)


const FLASHX_BLOCK_INFO_STRUCT _mpxs30_data_flash_block_map[] =
{
    /* count, offset, size */

    /* LAS */
    { 4, 0,                                                 K16,  C90_ASPACE_LAS|C90_CONTROLLER_0|C90_WIDTH_32|C90_ALIGN_32 }, /* D0 L0..L3 4*16 KB */

    { 0, 0, 0 }
};

const FLASHX_BLOCK_INFO_STRUCT _mpxs30_code_flash_block_map[] =
{
    /* count, offset, size */
    /* LAS */
    { 2,  0,                                                K16,  C90_ASPACE_LAS|C90_CONTROLLER_0|C90_WIDTH_64 }, /* C0 L0..L1 2*16 KB */
    { 2,  2*K16,                                            K32,  C90_ASPACE_LAS|C90_CONTROLLER_0|C90_WIDTH_64 }, /* C0 L2..L3 2*32 KB */
    { 2,  2*K16+2*K32,                                      K16,  C90_ASPACE_LAS|C90_CONTROLLER_0|C90_WIDTH_64 }, /* C0 L4..L5 2*16 KB */
    { 2,  4*K16+2*K32,                                      K64,  C90_ASPACE_LAS|C90_CONTROLLER_0|C90_WIDTH_64 }, /* C0 L6..L7 2*64 KB */
    { 2,  K256+0,                                           K16,  C90_ASPACE_LAS|C90_CONTROLLER_1|C90_WIDTH_64 }, /* C1 L0..L1 2*16 KB */
    { 2,  K256+2*K16,                                       K32,  C90_ASPACE_LAS|C90_CONTROLLER_1|C90_WIDTH_64 }, /* C1 L2..L3 2*32 KB */
    { 2,  K256+2*K16+2*K32,                                 K16,  C90_ASPACE_LAS|C90_CONTROLLER_1|C90_WIDTH_64 }, /* C1 L4..L5 2*16 KB */
    { 2,  K256+4*K16+2*K32,                                 K64,  C90_ASPACE_LAS|C90_CONTROLLER_1|C90_WIDTH_64 }, /* C1 L6..L7 2*64 KB */

    /* MAS */
    { 2,   MPXS30_CFLASH_MAS_ADDR-MPXS30_CFLASH0_MEM_BASE,  K256, C90_ASPACE_MAS|C90_INTERLEAVED|C90_WIDTH_64 }, /* C0/C1 M0..M1 2*128 KB */

    /* HAS */
    { 4,   MPXS30_CFLASH_HAS_ADDR-MPXS30_CFLASH0_MEM_BASE,  K256, C90_ASPACE_HAS|C90_INTERLEAVED|C90_WIDTH_64 }, /* C0/C1 H0..H3 4*128 KB */

    { 0, 0, 0 }
};


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_c90_address
* Returned Value   : Address upon success
* Comments         :
*    This function returns the base register address of the default C90 flash
*    controller. It is for use with the single controller version of the c90
*    driver.
*
*END*----------------------------------------------------------------------*/

pointer _bsp_get_c90_address (uint_32 base_addr)
{
    return (pointer)MPXS30_DFLASH0_BASE;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_c90i_address
* Returned Value   : Address upon success
* Comments         :
*    This function returns the base register address of the specified C90 flash
*    controller. It is for use with the multiple controller version of the c90
*    driver.
*
*END*----------------------------------------------------------------------*/

pointer _bsp_get_c90i_address (uint_32 base_addr, uint_32 controller)
{
    if (controller == 0) {
        // Asking for base address of the main controller associated with the specified
        // address
        switch (base_addr) {
            case  MPXS30_CFLASH0_MEM_BASE: return (pointer)MPXS30_CFLASH0_BASE;
            case  MPXS30_CFLASH1_MEM_BASE: return (pointer)MPXS30_CFLASH1_BASE;
            case  MPXS30_DFLASH_MEM_BASE:  return (pointer)MPXS30_DFLASH0_BASE;
        }
    } else if ((controller == 1) && (base_addr == MPXS30_CFLASH0_MEM_BASE) ){
        // Asking for base address of the alternate controller associated with the specified
        // address. Only CFLASH0 has an alternate controller.
        return (pointer)MPXS30_CFLASH1_BASE;
    }
    return NULL;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/udp_prv.h<|end_filename|>
#ifndef __udp_prv_h__
#define __udp_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: udp_prv.h$
* $Version : 3.0.6.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the private User Datagram Protocol
*   definitions.  For more details, refer to RFC768.
*
*END************************************************************************/

/*
** This is used to signal the waiting task after 
** socket closed by other tasks. 
*/
#define UDP_SOCKET_ENQUEUED      20
#define UDP_SOCKET_CLOSE         21

#if RTCSCFG_ENABLE_UDP_STATS
#define IF_UDP_STATS_ENABLED(x) x
#else
#define IF_UDP_STATS_ENABLED(x)
#endif

/***************************************
**
** Type definitions
**
*/

typedef struct udp_header {
   uchar    SRC_PORT[2];
   uchar    DEST_PORT[2];
   uchar    LENGTH[2];
   uchar    CHECKSUM[2];
} UDP_HEADER, _PTR_ UDP_HEADER_PTR;

/*
** UDP Configuration.  This information is persistent for the UDP layer.
*/
typedef struct udp_cfg_struct {
#if RTCSCFG_ENABLE_UDP_STATS
   UDP_STATS      STATS;
#endif
   UCB_STRUCT_PTR BOUND_UCB_HEAD;   /* The head of the bound UCB chain      */
   uint_16        LAST_PORT;        /* Last used UDP port                   */
   uint_16        RESERVED0;

   UCB_STRUCT_PTR GROUND_UCB_HEAD;  /* The head of the ground UCB chain     */
   UCB_STRUCT_PTR LBOUND_UCB_HEAD;  /* The head of local IP bound UCB chain */
   UCB_STRUCT_PTR OPEN_UCB_HEAD;    /* The head of the open UCB chain       */

} UDP_CFG_STRUCT, _PTR_ UDP_CFG_STRUCT_PTR;


/***************************************
**
** Prototypes
**
*/

uint_16 UDP_source
(
   RTCSPCB_PTR                /* [IN] packet to find source of */
);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/dhcp_prv.h<|end_filename|>
#ifndef __dhcp_prv_h__
#define __dhcp_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dhcp_prv.h$
* $Version : 3.0.7.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   Dynamic Host Configuration Protocol definitions.
*
*END************************************************************************/

#include "ip_prv.h"



/***************************************
**
** Constants
**
*/

#define DHCP_TIMEOUT_MIN       4000     /* 4 sec */
#define DHCP_TIMEOUT_MAX       64000    /* 64 sec */
#define DHCP_SAVED_ARRAY_SIZE  4
#define DHCP_SITE_SPEC_MIN     128
#define DHCP_SITE_SPEC_MAX     254

/* Internal DHCP Error codes - backward compatibility */

#define DHCP_PACKET_ERROR          RTCSERR_DHCP_PACKET_ERROR
#define DHCPCLNT_ERROR_DECLINED    RTCSERR_DHCPCLNT_ERROR_DECLINED
#define DHCPCLNT_XID_MISMATCH      RTCSERR_DHCPCLNT_XID_MISMATCH
#define DHCPCLNT_PACKET_SIZE_ERROR RTCSERR_DHCPCLNT_PACKET_SIZE_ERROR

/*
** This value can actually be 0x418937 before a rollover occurs, but the
** Diab compiler treats it as signed, so an overflow warning occurs unless
** you use 0x20C49B.
*/
#define DHCP_TCPIP_MAX_TIMED_EVENT_VALUE  0x20C49B

/*
** Standard port assignments
*/

#define DHCP_SERVER_PORT            67
#define DHCP_CLIENT_PORT            68


/* DHCP State definitions  */

#define DHCP_INITIALIZE    1
#define DHCP_BOUND         2
#define DHCP_RENEWING      3
#define DHCP_REBINDING     4
#define DHCP_REQUESTING    5
#define DHCP_DECLINING     6
#define DHCP_RELEASING     7
#define DHCP_INFORMED      8


/* 5 percent of total lease, there's no standard, use whatever's appropriate */
#define DHCP_RENEWALL_RANGE         0x14

/* The renewall and rebinding biases are suggested in RFC1541 */
#define DHCP_RENEWALL_BIAS(T)     (T/2)
#define DHCP_REBINDING_BIAS(T)    (T * 7/8)

/* Wait ten seconds before re-trying */
#define DHCP_TERMINATION_RETRY       10000
#define DHCP_OFFER_CHECK_EXPIRY_TIME 3000

/***************************************
**
** DHCP Macros
**
*/

#define DHCP_OPTION(type,len,val) \
            htonc(optptr, DHCPOPT_  ## type); optptr++; optlen++; \
            htonc(optptr, DHCPSIZE_ ## type); optptr++; optlen++; \
            hton ## len(optptr, val);                             \
            optptr += DHCPSIZE_ ## type;                          \
            optlen += DHCPSIZE_ ## type

#define DHCP_FILL(opt, cond) \
            opt_ptr = DHCP_find_option(parms->OPT_BUFF,                        \
                                       parms->OPT_BUFF_SIZE, DHCPOPT_ ## opt); \
            if (opt_ptr) { len = ntohc(opt_ptr + 1) + 2;                       \
               if (cond) { _mem_copy(opt_ptr, outp, len); outp += len;}        \
               for (i = 0; i < len; i++) {htonc(opt_ptr, 0); opt_ptr++;}}

#define DHCP_SET_RENEWALL_RANGE(l, r) \
            r = l / DHCP_RENEWALL_RANGE


#define DHCPCLNT_TIME_OVERFLOW_CHECK(r, t) if ( t > DHCP_TCPIP_MAX_TIMED_EVENT_VALUE ) { \
            t -= DHCP_TCPIP_MAX_TIMED_EVENT_VALUE;                                       \
            r = DHCP_TCPIP_MAX_TIMED_EVENT_VALUE * 1000;} else {                         \
            r = t * 1000;                                                                \
            t = 0;}

/***************************************
**
** Type definitions
**
*/

/***************************************
**
** Function-specific type definitions
**
*/

/* DHCP_open() */
typedef struct tcpip_parm_if_dhcp {

   TCPIP_PARM           COMMON;
   _rtcs_if_handle      HANDLE;
   uint_32              FLAGS;

   uchar_ptr            OPT_BUFF;
   uint_32              OPT_BUFF_SIZE;
   DHCP_DATA_STRUCT_PTR OPTIONS;
   _ip_address          CLNT_IP_ADDR;
   _ip_address          CLNT_IP_MASK;
   _ip_address          SERVER_IP_ADDR;
   uint_32              LEASE;
   uint_32              TIMEOUT;

} TCPIP_PARM_IF_DHCP, _PTR_ TCPIP_PARM_IF_DHCP_PTR;

/* DHCPCLNT_release() */
typedef struct tcpip_parm_if_dhcp_release {

   TCPIP_PARM           COMMON;
   _rtcs_if_handle      HANDLE;

} TCPIP_PARM_IF_DHCP_RELEASE, _PTR_ TCPIP_PARM_IF_DHCP_RELEASE_PTR;

/* Kept for backwards compatibility, still use internally */
typedef struct dhcp_lease_struct 
{
   uint_32     LEASE;
   _ip_address ServerIp;
   _ip_address ClientIPaddress;
   _ip_address Netmask;
   _ip_address SADDR;
   uchar       SNAME[64];
   uchar       BOOTFILE[128];

} DHCP_LEASE_STRUCT, _PTR_ DHCP_LEASE_STRUCT_PTR;

typedef struct dhcp_stats {

   RTCS_STATS_STRUCT COMMON;

   RTCS_ERROR_STRUCT ERR_RX;
   RTCS_ERROR_STRUCT ERR_TX;

   uint_32 ST_TX_DISCOVER;
   uint_32 ST_TX_DECLINE;
   uint_32 ST_TX_REQUEST;
   uint_32 ST_RX_OFFER;
   uint_32 ST_RX_ACK;
   uint_32 ST_RX_NAK;

} DHCP_STATS, _PTR_ DHCP_STATS_PTR;

typedef struct dhcp_clnt_struct  {

   IP_IF            _PTR_ HANDLE;  /* [IN] the RTCS interface state structure */
   UCB_STRUCT       _PTR_ UCB;
   uchar            _PTR_ SERVERID_PTR;
   uchar            _PTR_ MSGTYPE_PTR;
   uchar            _PTR_ PACKET;
   uchar            _PTR_ REQUEST_OPT_PTR;
   DHCP_LEASE_STRUCT      DATA;    /* [IN/OUT] DHCP parameters for callback */
   DHCP_LEASE_STRUCT      NEW_DATA; /* [IN] DHCP parameters for initialization*/
   TCPIP_EVENT            RENEW;
   TCPIP_EVENT            RESEND;
   TCPIP_EVENT            TERMINATE;
   boolean                BOUND;
   uint_32                STATE;
   uint_32                INIT_TIMEOUT;
   uint_32                NEW_RENEW_TIME;
   uint_32                RENEW_TIME;
   uint_32                NEW_REBIND_TIME;
   uint_32                REBIND_TIME;
   uint_32                RETRY_TIMEOUT;
   uint_32                TERMINATE_TIME;
   uint_32                R_EVENTS_TIME_LEFT;
   uint_32                S_EVENT_TIME_LEFT;
   uint_32                SECS;
   uint_32                TOTAL_PACKET_SIZE;
   uint_32                CURRENT_PACKET_SIZE;
   uint_32                FLAGS;
   int_32                 (_CODE_PTR_ CHOICE_FUNC)(uchar _PTR_, uint_32);
   void                   (_CODE_PTR_ BIND_FUNC)  (uchar _PTR_, uint_32, _rtcs_if_handle);
   boolean                (_CODE_PTR_ UNBIND_FUNC)(_rtcs_if_handle);
   boolean                (_CODE_PTR_ FAILURE_FUNC)(_rtcs_if_handle);
   boolean                (_CODE_PTR_ NAK_FUNC)  (uchar _PTR_, uint_32, _rtcs_if_handle);
   DHCP_STATS             STATS;
   IPIF_PARM              PARMS_BIND;
   IPIF_PARM              NEW_PARMS_BIND;

} DHCP_CLNT_STRUCT, _PTR_ DHCP_CLNT_STRUCT_PTR;

/***************************************
**
** Prototypes
**
*/

void DHCPCLNT_init ( TCPIP_PARM_IF_DHCP _PTR_ );
void DHCPCLNT_reinit ( TCPIP_PARM_IF_DHCP _PTR_ );
void DHCPCLNT_service ( RTCSPCB _PTR_, UCB_STRUCT _PTR_);
boolean DHCPCLNT_send ( TCPIP_EVENT _PTR_ );

uint_32 DHCPCLNT_start ( TCPIP_PARM_IF_DHCP _PTR_, DHCP_CLNT_STRUCT _PTR_ );
void DHCPCLNT_release_internal(TCPIP_PARM_IF_DHCP_RELEASE _PTR_ );

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/polled/i2c_pol_qi2c.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_pol_qi2c.c$
* $Version : 3.8.7.0$
* $Date    : Sep-26-2012$
*
* Comments:
*
*   This file contains low level functions for the I2C polled device driver
*   for PPC family.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "i2c_pol_prv.h"
#include "i2c_qi2c_prv.h"


extern uint_32 _qi2c_polled_init (QI2C_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _qi2c_polled_deinit (IO_I2C_POLLED_DEVICE_STRUCT_PTR, VQI2C_INFO_STRUCT_PTR);
extern uint_32 _qi2c_polled_rx (IO_I2C_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _qi2c_polled_tx (IO_I2C_POLLED_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _qi2c_polled_ioctl (VQI2C_INFO_STRUCT_PTR, uint_32, uint_32_ptr);
static uint_8  _qi2c_find_baud_index (uint_32);
static uint_32 _qi2c_polled_rx_tx (VQI2C_REG_STRUCT_PTR, VQI2C_INFO_STRUCT_PTR, uchar_ptr, uint_32);


// I2C frequency divider values taken from the MPC5675K User's manual
// Duplicated items are commented out, if you need a commented out value, un-comment
// the value you need, comment out the duplicate, and rebuild the BSP
static const QI2C_BAUDRATE_STRUCT _i2c_baudrate_tbl[] = {
    {BSP_I2C_CLOCK/3840,   0x3F },
    {BSP_I2C_CLOCK/3072,   0x3E },
    {BSP_I2C_CLOCK/2560,   0x3D },
    {BSP_I2C_CLOCK/2304,   0x3C },
    {BSP_I2C_CLOCK/2048,   0x3B },
    {BSP_I2C_CLOCK/1920,   0x37 },
    {BSP_I2C_CLOCK/1792,   0x3A },
    {BSP_I2C_CLOCK/1536,   0x39 },
    //{BSP_I2C_CLOCK/1536,   0x36 },
    {BSP_I2C_CLOCK/1280,   0x38 },
    //{BSP_I2C_CLOCK/1280,   0x35 },
    {BSP_I2C_CLOCK/1192,   0x21 },
    //{BSP_I2C_CLOCK/1152,   0x34 },
    {BSP_I2C_CLOCK/1024,   0x33 },
    {BSP_I2C_CLOCK/960 ,   0x2F },
    {BSP_I2C_CLOCK/896 ,   0x32 },
    {BSP_I2C_CLOCK/768 ,   0x31 },
    //{BSP_I2C_CLOCK/768 ,   0x2E },
    {BSP_I2C_CLOCK/640 ,   0x30 },
    //{BSP_I2C_CLOCK/640 ,   0x2D },
    {BSP_I2C_CLOCK/576 ,   0x2C },
    {BSP_I2C_CLOCK/512 ,   0x2B },
    {BSP_I2C_CLOCK/480 ,   0x27 },
    {BSP_I2C_CLOCK/448 ,   0x2A },
    {BSP_I2C_CLOCK/384 ,   0x29 },
    //{BSP_I2C_CLOCK/384 ,   0x26 },
    {BSP_I2C_CLOCK/320 ,   0x28 },
    //{BSP_I2C_CLOCK/320 ,   0x25 },
    {BSP_I2C_CLOCK/288 ,   0x24 },
    {BSP_I2C_CLOCK/256 ,   0x23 },
    {BSP_I2C_CLOCK/240 ,   0x1F },
    {BSP_I2C_CLOCK/224 ,   0x22 },
    {BSP_I2C_CLOCK/192 ,   0x1E },
    {BSP_I2C_CLOCK/160 ,   0x20 },
    //{BSP_I2C_CLOCK/160 ,   0x1D },
    {BSP_I2C_CLOCK/144 ,   0x1C },
    {BSP_I2C_CLOCK/128 ,   0x1B },
    //{BSP_I2C_CLOCK/128 ,   0x17 },
    {BSP_I2C_CLOCK/112 ,   0x1A },
    {BSP_I2C_CLOCK/104 ,   0x16 },
    {BSP_I2C_CLOCK/96  ,   0x19 },
    {BSP_I2C_CLOCK/88  ,   0x15 },
    {BSP_I2C_CLOCK/80  ,   0x18 },
    //{BSP_I2C_CLOCK/80  ,   0x14 },
    {BSP_I2C_CLOCK/72  ,   0x13 },
    {BSP_I2C_CLOCK/68  ,   0x0F },
    {BSP_I2C_CLOCK/64  ,   0x12 },
    {BSP_I2C_CLOCK/56  ,   0x11 },
    //{BSP_I2C_CLOCK/56  ,   0x0E },
    {BSP_I2C_CLOCK/48  ,   0x10 },
    //{BSP_I2C_CLOCK/48  ,   0x0D },
    {BSP_I2C_CLOCK/44  ,   0x0C },
    {BSP_I2C_CLOCK/40  ,   0x0B },
    //{BSP_I2C_CLOCK/40  ,   0x07 },
    {BSP_I2C_CLOCK/36  ,   0x0A },
    {BSP_I2C_CLOCK/34  ,   0x06 },
    {BSP_I2C_CLOCK/32  ,   0x09 },
    {BSP_I2C_CLOCK/30  ,   0x05 },
    {BSP_I2C_CLOCK/28  ,   0x08 },
    //{BSP_I2C_CLOCK/28  ,   0x04 },
    {BSP_I2C_CLOCK/26  ,   0x03 },
    {BSP_I2C_CLOCK/24  ,   0x02 },
    {BSP_I2C_CLOCK/22  ,   0x01 },
    {BSP_I2C_CLOCK/20  ,   0x00 }
};


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_find_baud_index
* Returned Value   : index into table of baudrate dividers
* Comments         :
*    Find best I2C setting for given baudrate.
*
*END*********************************************************************/

static uint_8 _qi2c_find_baud_index
    (
        /* [IN] Desired baudrate */
        uint_32 input_baud
    )
{
    uint_8 low, high, i;

    low = 0;
    high = sizeof(_i2c_baudrate_tbl)/sizeof(QI2C_BAUDRATE_STRUCT) - 1;
    do
    {
        i = (low + high) >> 1;
        if (input_baud < _i2c_baudrate_tbl[i].BAUD_RATE)
        {
            high = i - 1;
        } else {
            low = i + 1;
        }
    } while ((_i2c_baudrate_tbl[i].BAUD_RATE != input_baud) && (high >= low));

    /* in case we did not found exact BAUD rate use nearest slower settings than requested */
    if ((_i2c_baudrate_tbl[i].BAUD_RATE > input_baud) && (i != 0))
    {
        i--;
    }

    return i;
}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_polled_install
* Returned Value   : MQX error code
* Comments         :
*    Install an I2C device.
*
*END*********************************************************************/

uint_32 _qi2c_polled_install
    (
        /* [IN] A string that identifies the device for fopen */
        char_ptr              identifier,

        /* [IN] The I/O init data pointer */
        QI2C_INIT_STRUCT_CPTR init_data_ptr
    )
{

    return _io_i2c_polled_install(identifier,
        (uint_32 (_CODE_PTR_)(pointer, pointer _PTR_, char_ptr))_qi2c_polled_init,
        (uint_32 (_CODE_PTR_)(pointer, pointer))_qi2c_polled_deinit,
        (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_qi2c_polled_rx,
        (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_qi2c_polled_tx,
        (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_qi2c_polled_ioctl,
        (pointer)init_data_ptr);

}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_polled_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an I2C device.
*
*END*********************************************************************/

uint_32 _qi2c_polled_init
    (
        /* [IN] Initialization information for the device being opened */
        QI2C_INIT_STRUCT_PTR io_init_ptr,

        /* [OUT] Address to store device specific information */
        pointer _PTR_        io_info_ptr_ptr,

        /* [IN] The rest of the name of the device opened */
        char_ptr             open_name_ptr

    )
{
    VQI2C_REG_STRUCT_PTR     i2c_ptr;
    VQI2C_INFO_STRUCT_PTR    io_info_ptr;

   #if PSP_HAS_DEVICE_PROTECTION
   if (!_bsp_i2c_enable_access(io_init_ptr->CHANNEL)) {
       return I2C_ERROR_CHANNEL_INVALID;
   }
   #endif

    i2c_ptr = _bsp_get_i2c_base_address (io_init_ptr->CHANNEL);
    if (NULL == i2c_ptr)
    {
          return I2C_ERROR_CHANNEL_INVALID;
    }

    io_info_ptr = (VQI2C_INFO_STRUCT_PTR)_mem_alloc_system_zero ((uint_32)sizeof (QI2C_INFO_STRUCT));
    if (NULL == io_info_ptr)
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type ((pointer)io_info_ptr, MEM_TYPE_IO_I2C_INFO_STRUCT);

    /* I2C board specific initialization */
    _bsp_i2c_io_init (io_init_ptr->CHANNEL);

    *io_info_ptr_ptr                              = (pointer)io_info_ptr;
    io_info_ptr->INIT                             = *io_init_ptr;
    io_info_ptr->I2C_PTR                          = i2c_ptr;
    io_info_ptr->OLD_ISR                          = NULL;
    io_info_ptr->OLD_ISR_DATA                     = NULL;
    io_info_ptr->VECTOR                           = 0;
    io_info_ptr->MODE                             = io_init_ptr->MODE;
    io_info_ptr->STATE                            = I2C_STATE_READY;
    io_info_ptr->ADDRESSEE                        = 0;
    io_info_ptr->OPERATION                        = 0;
    io_info_ptr->INT_REQUEST                      = 0;
    io_info_ptr->RX_REQUEST                       = 0;
    io_info_ptr->RX_BUFFER                        = NULL;
    io_info_ptr->RX_IN                            = 0;
    io_info_ptr->RX_OUT                           = 0;
    io_info_ptr->TX_BUFFER                        = NULL;
    io_info_ptr->TX_IN                            = 0;
    io_info_ptr->TX_OUT                           = 0;
    io_info_ptr->STATISTICS.INTERRUPTS            = 0;
    io_info_ptr->STATISTICS.RX_PACKETS            = 0;
    io_info_ptr->STATISTICS.TX_PACKETS            = 0;
    io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS  = 0;
    io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE = 0;
    io_info_ptr->STATISTICS.TX_NAKS               = 0;

    /* Disable and clear I2C before initializing it */
    i2c_ptr->I2CR = QI2C_I2CR_MDIS;
   _PSP_SYNC();

    /* Clear out all I2C events */
    i2c_ptr->I2SR |= (QI2C_I2SR_IBIF | QI2C_I2SR_IBAL);
    _PSP_SYNC();

    /* Set the station address for SLAVE receive operations */
    i2c_ptr->I2ADR = io_init_ptr->STATION_ADDRESS << 1;
   _PSP_SYNC();

    /* Set the frequency divider for the nearest found baud rate */
    io_info_ptr->BAUD_INDEX = _qi2c_find_baud_index (io_init_ptr->BAUD_RATE);
    i2c_ptr->I2FDR = _i2c_baudrate_tbl[io_info_ptr->BAUD_INDEX].IC;
   _PSP_SYNC();

    /* Enable I2C */
    i2c_ptr->I2CR = 0;
   _PSP_SYNC();

    return I2C_OK;

}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_polled_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an I2C device.
*
*END*********************************************************************/

uint_32 _qi2c_polled_deinit
    (
        /* [IN] the initialization information for the device being opened */
        IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

        /* [IN] the address of the device specific information */
        VQI2C_INFO_STRUCT_PTR           io_info_ptr
    )
{
    VQI2C_REG_STRUCT_PTR                i2c_ptr;

    if ((NULL == io_info_ptr) || (NULL == pol_io_dev_ptr))
    {
        return I2C_ERROR_INVALID_PARAMETER;
    }

    i2c_ptr = io_info_ptr->I2C_PTR;
    _PSP_SYNC();
    if (i2c_ptr->I2SR & QI2C_I2SR_IBB)
    {
        return I2C_ERROR_DEVICE_BUSY;
    }

    /* Disable the I2C */
    i2c_ptr->I2CR = QI2C_I2CR_MDIS;
    _PSP_SYNC();

    /* Clear the I2C events */
    i2c_ptr->I2SR |= (QI2C_I2SR_IBIF | QI2C_I2SR_IBAL);
    _PSP_SYNC();

    /* Free info struct */
    _mem_free (pol_io_dev_ptr->DEV_INFO_PTR);
    pol_io_dev_ptr->DEV_INFO_PTR = NULL;

    return MQX_OK;

}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_polled_ioctl
* Returned Value   : MQX error code.
* Comments         :
*    This function performs miscellaneous services for
*    the I2C I/O device.
*
*END*********************************************************************/

uint_32 _qi2c_polled_ioctl
    (
        /* [IN] the address of the device specific information */
        VQI2C_INFO_STRUCT_PTR io_info_ptr,

        /* [IN] The command to perform */
        uint_32               cmd,

        /* [IN] Parameters for the command */
        uint_32_ptr           param_ptr
    )
{
    VQI2C_REG_STRUCT_PTR      i2c_ptr;
    uint_32                   result = MQX_OK;
    volatile uint_8           tmp;

    i2c_ptr = io_info_ptr->I2C_PTR;

    switch (cmd)
    {
        case IO_IOCTL_FLUSH_OUTPUT:
            do
            {
                for (tmp = 0; tmp < 0xFF; tmp++) 
                    { };
                tmp = i2c_ptr->I2SR;
                _PSP_SYNC();
            } while ((i2c_ptr->I2CR & QI2C_I2CR_TX) && ((QI2C_I2SR_IBB == (tmp & (QI2C_I2SR_TCF | QI2C_I2SR_IBB))) || (io_info_ptr->TX_IN != io_info_ptr->TX_OUT)));
            io_info_ptr->TX_IN = io_info_ptr->TX_OUT;
            if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (tmp & QI2C_I2SR_IBB)))
            {
                io_info_ptr->OPERATION = 0;
                io_info_ptr->RX_REQUEST = 0;
                io_info_ptr->STATE = I2C_STATE_FINISHED;
            }
            if (NULL != param_ptr)
            {
                *param_ptr = tmp & QI2C_I2SR_RXAK;
            }
            break;
        case IO_IOCTL_I2C_REPEATED_START:
            result = I2C_ERROR_DEVICE_BUSY;
            if (i2c_ptr->I2CR & QI2C_I2CR_MS)
            {
                if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) && (io_info_ptr->TX_IN == io_info_ptr->TX_OUT))
                   || ((I2C_STATE_RECEIVE == io_info_ptr->STATE) && (0 == io_info_ptr->RX_REQUEST))
                   || (I2C_STATE_FINISHED == io_info_ptr->STATE))
                {
                    io_info_ptr->STATE = I2C_STATE_REPEATED_START;
                    result = MQX_OK;
                }
            }
            break;
        case IO_IOCTL_I2C_STOP:
            i2c_ptr->I2CR &= (~ (QI2C_I2CR_TX | QI2C_I2CR_NOAK));
            _PSP_SYNC();
            i2c_ptr->I2SR |= (QI2C_I2SR_IBAL | QI2C_I2SR_IBIF);
            _PSP_SYNC();
            io_info_ptr->RX_REQUEST = 0;
            io_info_ptr->OPERATION = 0;
            io_info_ptr->STATE = I2C_STATE_READY;
            io_info_ptr->RX_OUT = io_info_ptr->RX_IN;

            if (! (i2c_ptr->I2CR & QI2C_I2CR_MS))
            {
                /* As slave, release the bus */
                tmp = i2c_ptr->I2DR;
            }
            else
            {
                /* As master, send STOP condition */
                i2c_ptr->I2CR &= (~ QI2C_I2CR_MS);
            }
            _PSP_SYNC();
            for (tmp = 0; tmp < 0xFF; tmp++) 
                { };

            /* Wait for bus idle */
            tmp = i2c_ptr->I2SR;
            _PSP_SYNC();
            while (tmp & QI2C_I2SR_IBB)
            {
                if ((tmp & QI2C_I2SR_IBIF) || (io_info_ptr->INT_REQUEST))
                {
                    i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                    _PSP_SYNC();
                    io_info_ptr->INT_REQUEST = 0;
                    tmp = i2c_ptr->I2DR;
                    _PSP_SYNC();
                }
                tmp = i2c_ptr->I2SR;
                _PSP_SYNC();
            }
            io_info_ptr->INT_REQUEST = 0;
            break;
        case IO_IOCTL_I2C_SET_RX_REQUEST:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                io_info_ptr->RX_REQUEST = *param_ptr;
            }
            break;
        case IO_IOCTL_I2C_DISABLE_DEVICE:
            i2c_ptr->I2CR |= QI2C_I2CR_MDIS;
            _PSP_SYNC();
            break;
        case IO_IOCTL_I2C_ENABLE_DEVICE:
            i2c_ptr->I2CR &= (~ QI2C_I2CR_MDIS);
            _PSP_SYNC();
            break;
        case IO_IOCTL_I2C_SET_MASTER_MODE:
            if (I2C_STATE_READY != io_info_ptr->STATE)
            {
                result = I2C_ERROR_DEVICE_BUSY;
            }
            else
            {
                io_info_ptr->MODE = I2C_MODE_MASTER;
            }
            break;
        case IO_IOCTL_I2C_SET_SLAVE_MODE:
            if (I2C_STATE_READY != io_info_ptr->STATE)
            {
                result = I2C_ERROR_DEVICE_BUSY;
            }
            else
            {
                io_info_ptr->MODE = I2C_MODE_SLAVE;
            }
            break;
        case IO_IOCTL_I2C_GET_MODE:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *param_ptr = io_info_ptr->MODE;
            }
            break;
        case IO_IOCTL_I2C_SET_BAUD:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else if (i2c_ptr->I2SR & QI2C_I2SR_IBB)
            {
                result = I2C_ERROR_DEVICE_BUSY;
            }
            else
            {
                io_info_ptr->BAUD_INDEX = _qi2c_find_baud_index (*param_ptr);
                i2c_ptr->I2FDR = _i2c_baudrate_tbl[io_info_ptr->BAUD_INDEX].IC;
                _PSP_SYNC();
            }
            break;
        case IO_IOCTL_I2C_GET_BAUD:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *param_ptr = _i2c_baudrate_tbl[io_info_ptr->BAUD_INDEX].BAUD_RATE;
            }
            break;
        case IO_IOCTL_I2C_SET_DESTINATION_ADDRESS:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                io_info_ptr->ADDRESSEE = *param_ptr;
            }
            break;
        case IO_IOCTL_I2C_GET_DESTINATION_ADDRESS:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *param_ptr = io_info_ptr->ADDRESSEE;
            }
            break;
        case IO_IOCTL_I2C_SET_STATION_ADDRESS:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                i2c_ptr->I2ADR = (*param_ptr) << 1;
                _PSP_SYNC();
            }
            break;
        case IO_IOCTL_I2C_GET_STATION_ADDRESS:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *param_ptr = i2c_ptr->I2ADR >> 1;
                _PSP_SYNC();
            }
            break;
        case IO_IOCTL_I2C_GET_STATE:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *param_ptr = io_info_ptr->STATE;
            }
            break;
        case IO_IOCTL_I2C_GET_STATISTICS:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((I2C_STATISTICS_STRUCT_PTR)param_ptr) = io_info_ptr->STATISTICS;
            }
            break;
        case IO_IOCTL_I2C_CLEAR_STATISTICS:
            io_info_ptr->STATISTICS.INTERRUPTS = 0;
            io_info_ptr->STATISTICS.RX_PACKETS = 0;
            io_info_ptr->STATISTICS.TX_PACKETS = 0;
            io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS = 0;
            io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE = 0;
            io_info_ptr->STATISTICS.TX_NAKS = 0;
            break;
        case IO_IOCTL_I2C_GET_BUS_AVAILABILITY:
            if (NULL == param_ptr)
            {
                result = I2C_ERROR_INVALID_PARAMETER;
            }
            else
            {
                if (i2c_ptr->I2SR & QI2C_I2SR_IBB)
                {
                     *param_ptr = I2C_BUS_BUSY;
                }
                else
                {
                     *param_ptr = I2C_BUS_IDLE;
                }
            }
            break;
        default:
            break;
    }
    return result;
}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_polled_rx
* Returned Value   : number of bytes read
* Comments         :
*   Returns the number of bytes received.
*   Reads the data into provided array when data is available.
*
*END*********************************************************************/

uint_32 _qi2c_polled_rx
    (
        /* [IN] the address of the device specific information */
        IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

        /* [IN] The array to copy data into */
        uchar_ptr                       buffer,

        /* [IN] number of bytes to read */
        uint_32                         length
    )
{
    VQI2C_INFO_STRUCT_PTR               io_info_ptr;
    VQI2C_REG_STRUCT_PTR                i2c_ptr;
    uint_8                              tmp;

    io_info_ptr = pol_io_dev_ptr->DEV_INFO_PTR;
    i2c_ptr = io_info_ptr->I2C_PTR;

    /* If beginning of transmission, set state and send address (master only) */
    io_info_ptr->OPERATION |= I2C_OPERATION_READ;
    tmp = io_info_ptr->STATE;
    if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
    {
        io_info_ptr->STATE = I2C_STATE_RECEIVE;
        if (I2C_MODE_MASTER == io_info_ptr->MODE)
        {
            i2c_ptr->I2CR |= QI2C_I2CR_TX;
            _PSP_SYNC();
            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
            _PSP_SYNC();
            if (I2C_STATE_REPEATED_START == tmp)
            {
                i2c_ptr->I2CR |= QI2C_I2CR_RSTA;
            }
            else
            {
                i2c_ptr->I2CR |= QI2C_I2CR_MS;
            }
            _PSP_SYNC();
            io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
            i2c_ptr->I2DR = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_READ;
            _PSP_SYNC();
            io_info_ptr->STATISTICS.TX_PACKETS++;
            while (0 == (i2c_ptr->I2SR & QI2C_I2SR_IBIF))
               {_PSP_SYNC();};   /* wait for address transferred */
        }
    }

    return _qi2c_polled_rx_tx (i2c_ptr, io_info_ptr, buffer, length);
}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_polled_tx
* Returned Value   : number of bytes transmitted
* Comments         :
*   Writes the provided data buffer and loops until transmission complete.
*
*END*********************************************************************/

uint_32 _qi2c_polled_tx
    (
        /* [IN] the address of the device specific information */
        IO_I2C_POLLED_DEVICE_STRUCT_PTR pol_io_dev_ptr,

        /* [IN] The array characters are to be read from */
        uchar_ptr                       buffer,

        /* [IN] number of bytes to output */
        uint_32                         length
    )
{
    VQI2C_INFO_STRUCT_PTR               io_info_ptr;
    VQI2C_REG_STRUCT_PTR                i2c_ptr;
    uint_8                              tmp;

    io_info_ptr  = pol_io_dev_ptr->DEV_INFO_PTR;
    i2c_ptr = io_info_ptr->I2C_PTR;

    /* If beginning of transmission, set state and send address (master only) */
    io_info_ptr->OPERATION &= (~ I2C_OPERATION_READ);
    tmp = io_info_ptr->STATE;
    if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
    {
        io_info_ptr->STATE = I2C_STATE_TRANSMIT;
        if (I2C_MODE_MASTER == io_info_ptr->MODE)
        {
            i2c_ptr->I2CR |= QI2C_I2CR_TX;
            _PSP_SYNC();
            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
            _PSP_SYNC();
            if (I2C_STATE_REPEATED_START == tmp)
            {
                i2c_ptr->I2CR |= QI2C_I2CR_RSTA;
            }
            else
            {
                i2c_ptr->I2CR |= QI2C_I2CR_MS;
            }
            _PSP_SYNC();
            io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
            i2c_ptr->I2DR = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_WRITE;
            _PSP_SYNC();
            io_info_ptr->STATISTICS.TX_PACKETS++;
            while (0 == (i2c_ptr->I2SR & QI2C_I2SR_IBIF))
               {_PSP_SYNC();};   /* wait for address transferred */
        }
    }

    return _qi2c_polled_rx_tx (i2c_ptr, io_info_ptr, buffer, length);
}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_polled_rx_tx
* Returned Value   : number of bytes processed
* Comments         :
*   Actual data transfer on I2C bus.
*
*END*********************************************************************/

static uint_32 _qi2c_polled_rx_tx
    (
        /* [IN] I2C register structure */
        VQI2C_REG_STRUCT_PTR  i2c_ptr,

        /* [IN] I2C state structure */
        VQI2C_INFO_STRUCT_PTR io_info_ptr,

        /* [IN] The buffer for IO operation */
        uchar_ptr             buffer,

        /* [IN] Number of bytes in buffer */
        uint_32               length
    )
{
    uint_32                   i;
    uint_8                    i2csr;
    volatile uint_8           tmp;

    for (i = 0; i <= length; i++)
    {
        do
        {
            i2csr = i2c_ptr->I2SR;
            _PSP_SYNC();
            if (0 == (i2c_ptr->I2CR & QI2C_I2CR_MS))
            {
                if (i == length)
                {
                    return i;
                }
                if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2csr & QI2C_I2SR_IBB)))
                {
                    io_info_ptr->OPERATION = 0;
                    io_info_ptr->RX_REQUEST = 0;
                    io_info_ptr->STATE = I2C_STATE_FINISHED;
                    return i;
                }
            }
        } while (0 == (i2csr & QI2C_I2SR_IBIF));

        io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;

        /* Master */
        if (i2c_ptr->I2CR & QI2C_I2CR_MS)
        {
            /* Transmit */
            if (i2c_ptr->I2CR & QI2C_I2CR_TX)
            {
                /* Not ack */
                if (i2csr & QI2C_I2SR_RXAK)
                {
                    i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                    _PSP_SYNC();
                    io_info_ptr->STATE = I2C_STATE_FINISHED;
                    io_info_ptr->STATISTICS.TX_NAKS++;
                    length = i;
                }
                /* Ack */
                else
                {
                    /* Transmit requested */
                    if (I2C_STATE_TRANSMIT == io_info_ptr->STATE)
                    {
                        if (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ))
                        {
                            /* Anything to transmit? */
                            if (i < length)
                            {
                                i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                                _PSP_SYNC();
                                i2c_ptr->I2DR = *buffer++;   /* transmit data */
                                _PSP_SYNC();
                                io_info_ptr->STATISTICS.TX_PACKETS++;
                            }
                        }
                        else
                        {
                            length = i;
                        }
                    }
                    /* Receive requested */
                    else if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
                    {
                        if (0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ))
                        {
                            i2c_ptr->I2CR &= (~ QI2C_I2CR_TX);
                            _PSP_SYNC();
                            if (1 == io_info_ptr->RX_REQUEST)
                            {
                                i2c_ptr->I2CR |= QI2C_I2CR_NOAK;
                            }
                            else
                            {
                                i2c_ptr->I2CR &= (~ QI2C_I2CR_NOAK);
                            }
                            _PSP_SYNC();
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                            _PSP_SYNC();
                            if (0 == io_info_ptr->RX_REQUEST)
                            {
                                io_info_ptr->STATE = I2C_STATE_FINISHED;
                                length = i;
                            }
                            else
                            {
                                tmp = i2c_ptr->I2DR;   // dummy read to clock in 1st byte
                                _PSP_SYNC();
                                i--;
                            }
                        }
                        else
                        {
                            length = i;
                        }
                    }
                    /* Others are unwanted/not handled states */
                    else
                    {
                        length = i;
                    }
                }
            }
            /* Receive */
            else
            {
                /* Receive requested */
                if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
                {
                    if ((0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (0 != io_info_ptr->RX_REQUEST))
                    {
                        if (i < length)
                        {
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                            _PSP_SYNC();
                            io_info_ptr->RX_REQUEST--;
                            if (1 == io_info_ptr->RX_REQUEST)
                            {
                                i2c_ptr->I2CR |= QI2C_I2CR_NOAK;
                            }
                            else
                            {
                                i2c_ptr->I2CR &= (~ QI2C_I2CR_NOAK);
                            }
                            _PSP_SYNC();
                            if (0 == io_info_ptr->RX_REQUEST)
                            {
                                i2c_ptr->I2CR |= QI2C_I2CR_TX;    /* no more reading */
                                _PSP_SYNC();
                            }
                            *buffer++ = i2c_ptr->I2DR;   /* receive data */
                            _PSP_SYNC();
                            if (0 == io_info_ptr->RX_REQUEST)
                            {
                                i2c_ptr->I2CR &= (~ QI2C_I2CR_TX);
                                _PSP_SYNC();
                                io_info_ptr->STATE = I2C_STATE_FINISHED;
                                length = i + 1;
                                i = length;
                            }
                            io_info_ptr->STATISTICS.RX_PACKETS++;
                        }
                    }
                    else
                    {
                        length = i;
                    }
                }
                /* Others are unwanted/not handled states */
                else
                {
                    length = i;
                }
            }
        }
        /* Slave */
        else
        {
            /* Master arbitration lost */
            if (i2csr & QI2C_I2SR_IBAL)
            {
                i2c_ptr->I2SR |= QI2C_I2SR_IBAL;
                _PSP_SYNC();
                io_info_ptr->STATE = I2C_STATE_LOST_ARBITRATION;
                io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS++;
                length = i;
            }
            /* Addressed as slave */
            if (i2csr & QI2C_I2SR_IAAS)
            {
                if (I2C_MODE_MASTER == io_info_ptr->MODE)
                {
                    io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE++;
                }
                /* Transmit requested */
                if (i2csr & QI2C_I2SR_SRW)
                {
                    io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_TX;
                    if (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ))
                    {
                        if (i < length)
                        {
                            i2c_ptr->I2CR |= QI2C_I2CR_TX;
                            _PSP_SYNC();
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                            _PSP_SYNC();
                            i2c_ptr->I2DR = *buffer++;   /* transmit data */
                            _PSP_SYNC();
                            io_info_ptr->STATISTICS.TX_PACKETS++;
                        }
                    }
                    else
                    {
                        length = i;
                    }
                }
                /* Receive requested */
                else
                {
                    io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_RX;
                    if ((0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (i == 0) && (0 != io_info_ptr->RX_REQUEST))
                    {
                        i2c_ptr->I2CR &= (~ QI2C_I2CR_TX);
                        _PSP_SYNC();
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        _PSP_SYNC();
                        if (1 == io_info_ptr->RX_REQUEST)
                        {
                            i2c_ptr->I2CR |= QI2C_I2CR_NOAK;
                        }
                        else
                        {
                            i2c_ptr->I2CR &= (~ QI2C_I2CR_NOAK);
                        }
                        _PSP_SYNC();
                        tmp = i2c_ptr->I2DR;   /* dummy read to release bus */
                        _PSP_SYNC();
                        i--;
                    }
                    else
                    {
                        length = i;
                    }
                }
            }
            /* Normal slave operation */
            else
            {
                /* No master arbitration lost */
                if (! (i2csr & QI2C_I2SR_IBAL))
                {
                    /* Transmit */
                    if (i2c_ptr->I2CR & QI2C_I2CR_TX)
                    {
                        /* Not ack */
                        if (i2csr & QI2C_I2SR_RXAK)
                        {
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                            _PSP_SYNC();
                            io_info_ptr->STATE = I2C_STATE_FINISHED;
                            io_info_ptr->STATISTICS.TX_NAKS++;
                            length = i;
                        }
                        /* Ack */
                        else
                        {
                            /* Transmit requested */
                            if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_TX == io_info_ptr->STATE))
                               && (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ)))
                            {
                                if (i < length)
                                {
                                    i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                                    _PSP_SYNC();
                                    i2c_ptr->I2DR = *buffer++;   /* transmit data */
                                    _PSP_SYNC();
                                    io_info_ptr->STATISTICS.TX_PACKETS++;
                                }
                            }
                            else
                            {
                                length = i;
                            }
                        }
                    }
                    /* Receive */
                    else
                    {
                        /* Receive requested */
                        if (((I2C_STATE_RECEIVE == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_RX == io_info_ptr->STATE))
                           && (0 != (io_info_ptr->OPERATION & I2C_OPERATION_READ)) && (0 != io_info_ptr->RX_REQUEST))
                        {
                            if (i < length)
                            {
                                i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                                _PSP_SYNC();
                                io_info_ptr->RX_REQUEST--;
                                if (1 == io_info_ptr->RX_REQUEST)
                                {
                                    i2c_ptr->I2CR |= QI2C_I2CR_NOAK;
                                }
                                else
                                {
                                    i2c_ptr->I2CR &= (~ QI2C_I2CR_NOAK);
                                }
                                _PSP_SYNC();
                                if (0 == io_info_ptr->RX_REQUEST)
                                {
                                    io_info_ptr->STATE = I2C_STATE_FINISHED;
                                }
                                *buffer++ = i2c_ptr->I2DR;   // receive data
                                _PSP_SYNC();
                                io_info_ptr->STATISTICS.RX_PACKETS++;
                            }
                        }
                        else
                        {
                            length = i;
                        }
                    }
                }
                else
                {
                    length = i;
                }
            }
        }
    }
    return length;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sai/sai.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sai.h$
* $Version : 3.8.3.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the SAI I/O functions.
*
*END************************************************************************/

/*
** TODO:
** 1. Extend driver API, so it supports clock hooking combinations RX0->TX0, 
**    TX0->RX1 etc and bit clock swapping between TX and RX.
** 2. Separate channel selection for TX and RX - Extend init and info struct.
**
*/

#ifndef __SAI_H__
#define __SAI_H__

#include <ioctl.h>

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/* Enable floating point operations in I2S */
#ifndef I2S_USE_FLOAT
#define I2S_USE_FLOAT   0
#endif

#define I2S_CHAR_BIT    (0x08)

/*
** SAI Clock sources
*/
#define I2S_CLK_INT     (0x00)
#define I2S_CLK_EXT     (0x01)

/*
** SAI Bus Modes
*/
#define I2S_MODE_MASTER (0x01)
#define I2S_MODE_SLAVE  (0x02)

/*
** SAI I/O Mode
*/
#define I2S_IO_READ     (0x04)
#define I2S_IO_WRITE    (0x08)

/*
** SAI RX/TX clock modes
*/
#define I2S_TX_ASYNCHRONOUS (0x01)
#define I2S_TX_SYNCHRONOUS  (0x02)
#define I2S_RX_ASYNCHRONOUS (0x04)
#define I2S_RX_SYNCHRONOUS  (0x08)

#define I2S_TX_BCLK_NORMAL  (0x10)
#define I2S_TX_BCLK_SWAPPED (0x20)
#define I2S_RX_BCLK_NORMAL  (0x40)
#define I2S_RX_BCLK_SWAPPED (0x80)

#define I2S_TX_MASTER       (I2S_MODE_MASTER << 4)
#define I2S_TX_SLAVE        (I2S_MODE_SLAVE  << 4)

#define I2S_RX_MASTER       (I2S_MODE_MASTER)
#define I2S_RX_SLAVE        (I2S_MODE_SLAVE)

#define I2S_DEBUG       0

#if I2S_DEBUG
#define I2S_LOG(...)  \
        {   \
            printf("\nI2S_LOG: %s: %d", __FILE__, __LINE__);  \
            printf(__VA_ARGS__);    \
        }
#else
#define I2S_LOG(...) {}
#endif

/*
** SAI Error Codes
*/
#define I2S_ERROR_BASE                      (DRIVER_ERROR_BASE | 0x0FF0)
#define I2S_OK                              (0x00)
#define I2S_ERROR_INVALID_PARAMETER         (I2S_ERROR_BASE | 0x01)
#define I2S_ERROR_CHANNEL_INVALID           (I2S_ERROR_BASE | 0x02)
#define I2S_ERROR_MODE_INVALID              (I2S_ERROR_BASE | 0x03)
#define I2S_ERROR_WORD_LENGTH_UNSUPPORTED   (I2S_ERROR_BASE | 0x04)
#define I2S_ERROR_CLK_INVALID               (I2S_ERROR_BASE | 0x05)
#define I2S_ERROR_DIVIDER_VALUE_INVALID     (I2S_ERROR_BASE | 0x06)
#define I2S_ERROR_FREQUENCY_INVALID         (I2S_ERROR_BASE | 0x07)
#define I2S_ERROR_BUFFER_SMALL              (I2S_ERROR_BASE | 0x08)
#define I2S_ERROR_DEVICE_BUSY               (I2S_ERROR_BASE | 0x09)
#define I2S_ERROR_PARAM_OUT_OF_RANGE        (I2S_ERROR_BASE | 0x0A)
#define I2S_ERROR_INVALID_BCLK              (I2S_ERROR_BASE | 0x0B)
#define I2S_ERROR_INVALID_TX_CHANNEL        (I2S_ERROR_BASE | 0x0C)
#define I2S_ERROR_INVALID_RX_CHANNEL        (I2S_ERROR_BASE | 0x0D)

/*
** IOCTL calls specific to I2S
*/
#define IO_TYPE_I2S                                 0x15
#define IO_IOCTL_I2S_SET_MODE_MASTER                _IO(IO_TYPE_I2S, 0x01)
#define IO_IOCTL_I2S_SET_MODE_SLAVE                 _IO(IO_TYPE_I2S, 0x02)
#define IO_IOCTL_I2S_SET_CLOCK_SOURCE_INT           _IO(IO_TYPE_I2S, 0x03)
#define IO_IOCTL_I2S_SET_CLOCK_SOURCE_EXT           _IO(IO_TYPE_I2S, 0x04)
#define IO_IOCTL_I2S_SET_DATA_BITS                  _IO(IO_TYPE_I2S, 0x05)
#define IO_IOCTL_I2S_DISABLE_DEVICE                 _IO(IO_TYPE_I2S, 0x06)
#define IO_IOCTL_I2S_ENABLE_DEVICE                  _IO(IO_TYPE_I2S, 0x07)
#define IO_IOCTL_I2S_SET_MCLK_FREQ                  _IO(IO_TYPE_I2S, 0x08)
#define IO_IOCTL_I2S_SET_FS_FREQ                    _IO(IO_TYPE_I2S, 0x09)
#define IO_IOCTL_I2S_TX_DUMMY_ON                    _IO(IO_TYPE_I2S, 0x0A)
#define IO_IOCTL_I2S_TX_DUMMY_OFF                   _IO(IO_TYPE_I2S, 0x0B)
#define IO_IOCTL_I2S_GET_MODE                       _IO(IO_TYPE_I2S, 0x0C)
#define IO_IOCTL_I2S_GET_CLOCK_SOURCE               _IO(IO_TYPE_I2S, 0x0D)
#define IO_IOCTL_I2S_GET_DATA_BITS                  _IO(IO_TYPE_I2S, 0x0E)
#define IO_IOCTL_I2S_GET_MCLK_FREQ                  _IO(IO_TYPE_I2S, 0x0F)
#define IO_IOCTL_I2S_GET_BCLK_FREQ                  _IO(IO_TYPE_I2S, 0x10)
#define IO_IOCTL_I2S_GET_TX_DUMMY                   _IO(IO_TYPE_I2S, 0x11)
#define IO_IOCTL_I2S_GET_FS_FREQ                    _IO(IO_TYPE_I2S, 0x12)
#define IO_IOCTL_I2S_GET_STATISTICS                 _IO(IO_TYPE_I2S, 0x13)
#define IO_IOCTL_I2S_SET_TXFIFO_WATERMARK           _IO(IO_TYPE_I2S, 0x14)
#define IO_IOCTL_I2S_SET_RXFIFO_WATERMARK           _IO(IO_TYPE_I2S, 0x15)
#define IO_IOCTL_I2S_GET_TXFIFO_WATERMARK           _IO(IO_TYPE_I2S, 0x16)
#define IO_IOCTL_I2S_GET_RXFIFO_WATERMARK           _IO(IO_TYPE_I2S, 0x17)
#define IO_IOCTL_I2S_SET_CLK_ALWAYS_ENABLED_ON      _IO(IO_TYPE_I2S, 0x18)
#define IO_IOCTL_I2S_SET_CLK_ALWAYS_ENABLED_OFF     _IO(IO_TYPE_I2S, 0x19)
#define IO_IOCTL_I2S_GET_CLK_ALWAYS_ENABLED         _IO(IO_TYPE_I2S, 0x1A)
#define IO_IOCTL_I2S_CLEAR_STATISTICS               _IO(IO_TYPE_I2S, 0x1B)
#define IO_IOCTL_I2S_SET_CLOCK_MODE                 _IO(IO_TYPE_I2S, 0x1C)
#define IO_IOCTL_I2S_GET_CLOCK_MODE                 _IO(IO_TYPE_I2S, 0x1D)

/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** I2S_STATISTICS_STRUCT
** SAI run time statistics structure
*/

typedef struct i2s_statistics_struct
{
    /* Number of SAI interrupts so far */
    uint_32 INTERRUPTS;

    /* FIFO error */
    uint_32 FIFO_ERROR;

    /* FIFO sync error */
    uint_32 BUFFER_ERROR;

    /* Number of valid bytes received (not dummy receives) */
    uint_32 RX_PACKETS;

    /* Number of valid bytes transmitted (not dummy transmits) */
    uint_32 TX_PACKETS;

    /* Number of bytes currently read or wrote */
    uint_32 PACKETS_PROCESSED;

    /* Number of bytes currently buffered */
    uint_32 PACKETS_QUEUED;

    /* Number of bytes requested for reading or writing */
    uint_32 PACKETS_REQUESTED;

} I2S_STATISTICS_STRUCT, _PTR_ I2S_STATISTICS_STRUCT_PTR;

typedef struct sai_init_struct
{
    /* A pointer to a string that identifies the device for fopen */
    char_ptr                ID_PTR;

    _mqx_int (_CODE_PTR_    INIT)(pointer);

    _mqx_int (_CODE_PTR_    DEINIT)(pointer, pointer);

    _mqx_int (_CODE_PTR_    RX)(pointer, char_ptr, uint_32);

    _mqx_int (_CODE_PTR_    TX)(pointer, char_ptr, uint_32);

    /* The ioctl function to call */
    _mqx_int (_CODE_PTR_    IOCTL)(pointer, _mqx_int, pointer);
    
    /* The I/O channel initialization data */
    pointer                 INIT_DATA_PTR;
} SAI_INIT_STRUCT, _PTR_ SAI_INIT_STRUCT_PTR;

typedef const SAI_INIT_STRUCT _PTR_ SAI_INIT_STRUCT_CPTR; 

/*
** FUNCTION PROTOTYPE
*/

#ifdef __cplusplus
extern "C" 
{
#endif

    _mqx_uint _io_sai_int_install(SAI_INIT_STRUCT_CPTR);

#ifdef __cplusplus
}
#endif

#endif /* __SAI_H__ */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/cpu/kinetis_fcan.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008-2010 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: kxx_fcan.h$
* $Version : 3.6.1.0$
* $Date    : Nov-2-2010$
*
* Comments:
*
*   This file contains the type definitions for the kxx FlexCAN module.
*
*END************************************************************************/

#include <psp.h>

#ifndef __kxx_fcan_h__
#define __kxx_fcan_h__

#define __kxx_fcan_h__version "$Version:3.6.1.0$"
#define __kxx_fcan_h__date    "$Date:Nov-2-2010$"

#ifdef __cplusplus
extern "C" {
#endif

/*
** Message buffer codes for Rx Buffers
*/
#define CAN_RX_MSG_BUFFER_NOT_ACTIVE   (0x0)
#define CAN_RX_MSG_BUFFER_EMPTY        (0x4)
#define CAN_RX_MSG_BUFFER_FULL         (0x2)
#define CAN_RX_MSG_BUFFER_OVERRUN      (0x6)
#define CAN_RX_MSG_BUFFER_BUSY         (0x1)

/*
** Message buffer codes for Rx Buffers
*/
#define CAN_TX_MSG_BUFFER_NOT_ACTIVE       (0x8)
#define CAN_MESSAGE_TRANSMIT_ONCE          (0xC)
#define CAN_MESSAGE_TRANSMIT_REMOTE        (0xC)
#define CAN_MESSAGE_TRANSMIT_RESPONED      (0xA)
#define CAN_MESSAGE_TRANSMIT_RESPONED_ONLY (0xE)


/* Message buffer memory map */
#define FLEXCAN_MSGCTRL_RTR                     (CAN_CS_RTR_MASK)
#define FLEXCAN_MSGCTRL_IDE                     (CAN_CS_IDE_MASK)
#define FLEXCAN_MSGCTRL_SRR                     (CAN_CS_SRR_MASK)
#define FLEXCAN_MSGCRTL_CODE                    (CAN_CS_CODE_MASK)
#define FLEXCAN_MSG_CTRL_DLEN                   (CAN_CS_DLC_MASK)
#define FLEXCAN_MSG_DISABLE                     (~ FLEXCAN_MSGCRTL_CODE)

/*
** Message Buffer Codes for Rx Buffers
*/
#define FLEXCAN_RX_MSG_BUFFER_NOT_ACTIVE        CAN_CS_CODE(CAN_RX_MSG_BUFFER_NOT_ACTIVE)
#define FLEXCAN_RX_MSG_BUFFER_EMPTY             CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY)
#define FLEXCAN_RX_MSG_BUFFER_FULL              CAN_CS_CODE(CAN_RX_MSG_BUFFER_FULL)
#define FLEXCAN_RX_MSG_BUFFER_OVERRUN           CAN_CS_CODE(CAN_RX_MSG_BUFFER_OVERRUN)
#define FLEXCAN_RX_MSG_BUFFER_BUSY              CAN_CS_CODE(CAN_RX_MSG_BUFFER_BUSY)

/* Message Buffer Codes for Tx Buffers */
#define FLEXCAN_TX_MSG_BUFFER_NOT_ACTIVE        CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE)
#define FLEXCAN_MESSAGE_TRANSMIT_ONCE           CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_ONCE)
#define FLEXCAN_MESSAGE_TRANSMIT_REMOTE         CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_REMOTE)
#define FLEXCAN_MESSAGE_TRANSMIT_RESPONED       CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_RESPONED)
#define FLEXCAN_MESSAGE_TRANSMIT_RESPONED_ONLY  CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_RESPONED_ONLY)

/* Interrupt masks */
#define FLEXCAN_WAKEUP_INT              CAN_ESR1_WAKINT_MASK
#define FLEXCAN_ERROR_INT               CAN_ESR1_ERRINT_MASK
#define FLEXCAN_BUSOFF_INT              CAN_ESR1_BOFFINT_MASK
#define FLEXCAN_ALL_INT                 (CAN_ESR1_WAKINT_MASK | CAN_ESR1_ERRINT_MASK | CAN_ESR1_BOFFINT_MASK)
#define FLEXCAN_TX_RX_INT               (~ FLEXCAN_ALL_INT)
#define FLEXCAN_IMASK_VALUE             CAN_IMASK2_BUFHM_MASK

/*------------------------------------------------------------------------*/
/*
** FCAN registers bit set GENERALIZED
*/

#define FLEXCAN_CANMCR_MAXMB                  CAN_MCR_MAXMB
#define FLEXCAN_CANMCR_FRZACK                 CAN_MCR_FRZACK_MASK
#define FLEXCAN_CANMCR_SOFTRST                CAN_MCR_SOFTRST_MASK
#define FLEXCAN_CANMCR_HALT                   CAN_MCR_HALT_MASK
#define FLEXCAN_CANMCR_FRZ                    CAN_MCR_FRZ_MASK
#define FLEXCAN_CANMCR_MDIS                   CAN_MCR_MDIS_MASK
#define FLEXCAN_CANMCR_LPMACK                 CAN_MCR_LPMACK_MASK
#define FLEXCAN_CANMCR_NOTRDY                 CAN_MCR_NOTRDY_MASK

#define FLEXCAN_CANCTRL_LOM                   CAN_CTRL1_LOM_MASK
#define FLEXCAN_CANCTRL_TSYNC                 CAN_CTRL1_TSYN_MASK
#define FLEXCAN_CANCTRL_LPB                   CAN_CTRL1_LPB_MASK
#define FLEXCAN_CANCTRL_BOFFREC               CAN_CTRL1_BOFFREC_MASK
#define FLEXCAN_CANCTRL_SAMP                  CAN_CTRL1_SMP_MASK
#define FLEXCAN_CANCTRL_CLK_SRC               CAN_CTRL1_CLKSRC_MASK
#define FLEXCAN_CANCTRL_ERRMSK                CAN_CTRL1_ERRMSK_MASK
#define FLEXCAN_CANCTRL_BOFFMSK               CAN_CTRL1_BOFFMSK_MASK

#define FLEXCAN_CANCTRL_PROPSEG               CAN_CTRL1_PROPSEG
#define FLEXCAN_CANCTRL_PSEG2                 CAN_CTRL1_PSEG2
#define FLEXCAN_CANCTRL_PSEG1                 CAN_CTRL1_PSEG1
#define FLEXCAN_CANCTRL_RJW                   CAN_CTRL1_RJW
#define FLEXCAN_CANCTRL_PRESDIV               CAN_CTRL1_PRESDIV

#define FLEXCAN_STANDARD_ID_MASK              CAN_ID_STD
#define FLEXCAN_EXTENDED_ID_MASK              CAN_ID_EXT

#define _flexcan_int_init                     _bsp_int_init

#ifdef __cplusplus
}
#endif

#endif  //__kxx_fcan_h__


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/include/host_cnfg.h<|end_filename|>
#ifndef __usbhost_cnfg_h__
#define __usbhost_cnfg_h__

#include <bsp.h>        // also includes user_config.h

/** MGCT: <category name="USB Host Settings"> */

#ifndef USBCFG_REGISTER_ENDIANNESS
#define USBCFG_REGISTER_ENDIANNESS MQX_BIG_ENDIAN
#endif

#ifndef USBCFG_MEMORY_ENDIANNESS
#define USBCFG_MEMORY_ENDIANNESS MQX_BIG_ENDIAN
#endif

/*
** Maximum number of pipes.
** MGCT: <option type="number"/>
*/  
#ifndef USBCFG_MAX_PIPES
    #ifdef USBCFG_KHCI
    #define USBCFG_MAX_PIPES                   (16)
    #else
        #define USBCFG_MAX_PIPES               (24)
    #endif
#endif

/*
** Maximum number of usb interfaces.
** MGCT: <option type="number"/>
*/  
#ifndef USBCFG_MAX_INTERFACE
#define USBCFG_MAX_INTERFACE                    (1) //deprecated, should be removed (TODO), stays here for comaptibility
#endif

#ifndef USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS
#define USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS  (0)
#endif

#ifndef USBCFG_MAX_DRIVERS
extern const pointer _bsp_usb_table[];
#define USBCFG_MAX_DRIVERS                      (sizeof(_bsp_usb_table) / sizeof(_bsp_usb_table[0]))
#endif

/*
** MGCT: <option type="number"/>
*/  
#ifndef USBCFG_DEFAULT_MAX_NAK_COUNT
#define USBCFG_DEFAULT_MAX_NAK_COUNT            (15)
#endif

/*
** MGCT: <option type="string"/>
*/  
#ifndef USBCFG_MFS_OPEN_READ_CAPACITY_RETRY_DELAY
#define USBCFG_MFS_OPEN_READ_CAPACITY_RETRY_DELAY   (_time_get_ticks_per_sec() * 1)
#endif

/*
** MGCT: <option type="string"/>
*/  
#ifndef USBCFG_MFS_LWSEM_TIMEOUT
#define USBCFG_MFS_LWSEM_TIMEOUT                    (_time_get_ticks_per_sec() * 20)
#endif

/*
** MGCT: <option type="number"/>
*/  
#ifndef USBCFG_MFS_MAX_RETRIES
#define USBCFG_MFS_MAX_RETRIES                  (5)
#endif

/*
** MGCT: <option type="number"/>
*/  
#ifndef USBCFG_CTRL_RETRY
#define USBCFG_CTRL_RETRY                       (4)
#endif

/*
** Maximum number of selected interfaces (= with open pipes).
** MGCT: <option type="number"/>
*/
#ifndef USBCFG_MAX_DEV_INTFS
#define USBCFG_MAX_DEV_INTFS                    (2)
#endif

/** MGCT: </category> */

#ifdef USBCFG_KHCI

    #define __USB_HOST_KHCI__

    /** MGCT: <category name="KHCI Driver Specific Settings"> */
    
    /*
    ** KHCI task priority
    ** MGCT: <option type="number"/>
    */  
    #ifndef USBCFG_KHCI_TASK_PRIORITY
    #define USBCFG_KHCI_TASK_PRIORITY               (8)
    #endif

    /*
    ** Wait time in tick for events - must be above 1.
    ** MGCT: <option type="string"/>
    */
    #ifndef USBCFG_KHCI_WAIT_TICK
    #define USBCFG_KHCI_WAIT_TICK                   (_time_get_ticks_per_sec() / 10)    // 100ms
    #endif

    /*
    ** Maximum message count for KHCI.
    ** MGCT: <option type="number"/>
    */
    #ifndef USBCFG_KHCI_TR_QUE_MSG_CNT
    #define USBCFG_KHCI_TR_QUE_MSG_CNT              (10)
    #endif

    /*
    ** Maximum interrupt transaction count.
    ** MGCT: <option type="number"/>
    */
    #ifndef USBCFG_KHCI_MAX_INT_TR
    #define USBCFG_KHCI_MAX_INT_TR                  (10)
    #endif
    
    /** MGCT: </category> */

#endif // USBCFG_KHCI

#ifdef USBCFG_EHCI

    
    /** MGCT: <category name="EHCI Driver Specific Settings"> */
    /*
    ** MGCT: <option type="number"/>
    */
    #ifndef USBCFG_EHCI_USE_SW_TOGGLING
    #define USBCFG_EHCI_USE_SW_TOGGLING         (0)
    #endif

    /*
    ** Maximum number of allocated QH descriptors.
    ** MGCT: <option type="number"/>
    */
    #ifndef USBCFG_EHCI_MAX_QH_DESCRS
    #define USBCFG_EHCI_MAX_QH_DESCRS           (8)
    #endif

    /*
    ** Maximum number of allocated QTD descriptors.
    ** MGCT: <option type="number"/>
    */
    #ifndef USBCFG_EHCI_MAX_QTD_DESCRS
    #define USBCFG_EHCI_MAX_QTD_DESCRS          (16)
    #endif

    /*
    ** Maximum number of allocated ISO descriptors.
    ** MGCT: <option type="number"/>
    */
    #ifndef USBCFG_EHCI_MAX_ITD_DESCRS
    #define USBCFG_EHCI_MAX_ITD_DESCRS          (16)
    #endif

    /*
    ** Maximum number of allocated SSPLIT descriptors.
    ** MGCT: <option type="number"/>
    */
    #ifndef USBCFG_EHCI_MAX_SITD_DESCRS
    #define USBCFG_EHCI_MAX_SITD_DESCRS         (32)
    #endif

    /*
    ** MGCT: <option type="number"/>
    */
    #ifndef USBCFG_EHCI_PIPE_TIMEOUT
    #define USBCFG_EHCI_PIPE_TIMEOUT            (300)
    #endif
    
    /** MGCT: </category> */

#endif // USBCFG_EHCI

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/mqx.c<|end_filename|>
/*HEADER**********************************************************************
*
* Copyright (c) 2008-2010 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* $FileName: mqx.c$
* $Version : 3.8.35.0$
* $Date    : Jun-28-2012$
*
* Comments:
*
*   This file contains the source for the main MQX function _mqx().
*
*END************************************************************************/

#ifndef __NO_SETJMP
#include <setjmp.h>
#endif

#include "mqx_inc.h"
#include "gen_rev.h"
#include "psp_rev.h"

/*
 * A global zero initialized MQX tick structure.
 * It is used by various MQX functions that need
 * to zero initialize local tick structures. An
 * extern to it is provided in MQX.H so applications
 * can use it as well.
 */
const MQX_TICK_STRUCT _mqx_zero_tick_struct = {0};

/* version/vendor identification also used by TAD to determine paths to its context files */
const uint_32          _mqx_version_number = 0x04000001;
const char _PTR_ const _mqx_vendor         = "Freescale/Freescale MQX";

/* Identify the product */
#if MQX_CRIPPLED_EVALUATION
const char _PTR_ const _mqx_version        = "4.0.1c";
#else
const char _PTR_ const _mqx_version        = "4.0.1";
#endif

/* version strings */
const char _PTR_ const _mqx_generic_revision = REAL_NUM_TO_STR(GEN_REVISION);
const char _PTR_ const _mqx_psp_revision     = REAL_NUM_TO_STR(PSP_REVISION);
const char _PTR_ const _mqx_copyright = "(c) 2013 Freescale Semiconductor. All rights reserved.";
const char _PTR_ const _mqx_date      = __DATE__ " at " __TIME__;

/* A global pointer to the location of the kernel data structure */
KERNEL_ACCESS struct kernel_data_struct _PTR_ _mqx_kernel_data = (pointer)-1;
KERNEL_ACCESS volatile pointer _mqx_system_stack;

/* Error return jump buffer for kernel errors */
#if MQX_EXIT_ENABLED || MQX_CRIPPLED_EVALUATION
jmp_buf _mqx_exit_jump_buffer_internal;
#endif

/* TODO copied from monitor.c find suitable place */
volatile _WEAK_SYMBOL(_mqx_uint _mqx_monitor_type) = MQX_MONITOR_TYPE_NONE;

/*!
 * \brief Initializes and starts MQX on the processor.
 * 
 * The function does the following:
 * \li Initializes the default memory pool and memory components.
 * \li Initializes kernel data.
 * \li Performs BSP-specific initialization, which includes installing the 
 * periodic timer.
 * \li Performs PSP-specific initialization.
 * \li Creates the interrupt stack.
 * \li Creates the ready queues.
 * \li Starts MQX tasks.
 * \li Starts autostart application tasks.
 * 
 * \param[in] mqx_init Pointer to the MQX initialization structure for the 
 * processor.
 * 
 * \return Does not return (Success.)
 * \return If application called _mqx_exit(), error code that it passed to 
 * _mqx_exit() (Success.)
 * \return Errors from _int_install_isr() (MQX cannot install the interrupt 
 *  subsystem.)
 * \return Errors from _io_init() (MQX cannot install the I/O subsystem.)
 * \return Errors from _mem_alloc_system() (There is not enough memory to 
 * allocate either the interrupt stack or the interrupt table.)
 * \return Errors from _mem_alloc_zero() (There is not enough memory to allocate 
 * the ready queues.)
 * \return MQX_KERNEL_MEMORY_TOO_SMALL (Init_struct_ptr does not specify enough 
 * kernel memory.)
 * \return MQX_OUT_OF_MEMORY (There is not enough memory to allocate either the 
 * ready queues, the interrupt stack, or the interrupt table.)
 * \return MQX_TIMER_ISR_INSTALL_FAIL (MQX cannot install the periodic timer ISR.)
 * 
 * \warning Must be called exactly once per processor.
 * 
 * \see _mqx_exit
 * \see _int_install_isr
 * \see _mem_alloc() 
 * \see _mem_alloc_from()
 * \see _mem_alloc_system()
 * \see _mem_alloc_system_from()
 * \see _mem_alloc_system_zero()
 * \see _mem_alloc_system_zero_from()
 * \see _mem_alloc_zero()
 * \see _mem_alloc_zero_from()
 * \see _mem_alloc_align()
 * \see _mem_alloc_align_from()
 * \see _mem_alloc_at()
 * \see MQX_INITIALIZATION_STRUCT
 * \see TASK_TEMPLATE_STRUCT        
 */ 
_mqx_uint _mqx
(
    register MQX_INITIALIZATION_STRUCT_PTR mqx_init
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TASK_TEMPLATE_STRUCT_PTR template_ptr;
    TD_STRUCT_PTR td_ptr;
    _mqx_uint result;
    pointer stack_ptr;
    pointer sys_td_stack_ptr;
    uchar_ptr sys_stack_base_ptr;

#if MQX_EXIT_ENABLED || MQX_CRIPPLED_EVALUATION
    /* Setup a longjmp buffer using setjmp, so that if an error occurs
     * in mqx initialization, we can perform a longjmp to this location.
     *
     * Also _mqx_exit will use this jumpbuffer to longjmp to here in order
     * to cleanly exit MQX.
     */
    if ( MQX_SETJMP( _mqx_exit_jump_buffer_internal ) ) {
        _GET_KERNEL_DATA(kernel_data);
        _int_set_vector_table(kernel_data->USERS_VBR);
        return kernel_data->USERS_ERROR;
    } /* Endif */
#endif

    /*
     * The kernel data structure starts at the start of kernel memory,
     * as specified in the initialization structure. Make sure address
     * specified is aligned
     */
    kernel_data = (KERNEL_DATA_STRUCT_PTR) _ALIGN_ADDR_TO_HIGHER_MEM(mqx_init->START_OF_KERNEL_MEMORY);

    /* Set the global pointer to the kernel data structure */
    _SET_KERNEL_DATA(kernel_data);

    /* The following assignments are done to force the linker to include
     * the symbols, which are required by TAD.
     * Note that we should use address of the variable so it is not optimized
     * as direct constant assignment when optimization level is high.
     * Note that counter will be immediately reset to zero on the subsequent
     * _mem_zero call. */
    *(volatile pointer*) kernel_data = (pointer) & _mqx_version_number;
    *(volatile pointer*) kernel_data = (pointer) & _mqx_vendor;

    /* Initialize the kernel data to zero. */
    _mem_zero((pointer) kernel_data, (_mem_size) sizeof(KERNEL_DATA_STRUCT));

#if MQX_CHECK_ERRORS && MQX_VERIFY_KERNEL_DATA
    /* Verify that kernel data can be read and written correcly without
     * errors.  This is necessary during BSP development to validate the
     * DRAM controller is initialized properly.
     */

#ifndef PSP_KERNEL_DATA_VERIFY_ENABLE
#define PSP_KERNEL_DATA_VERIFY_ENABLE   0
#endif /* PSP_KERNEL_DATA_VERIFY_ENABLE */
    if (PSP_KERNEL_DATA_VERIFY_ENABLE) {
        /* This memory check is dangerous, because can destroy boot stack
         * stack which is used !!! -> MQX will failed !
         * Set PSP_KERNEL_DATA_VERIFY_ENABLE to 1
         * only if your boot stack is out of MQX memory heap
         */

        result = _mem_verify((uchar_ptr)kernel_data + sizeof(KERNEL_DATA_STRUCT),
                        mqx_init->END_OF_KERNEL_MEMORY);
        if ( result != MQX_OK ) {
            _mqx_exit(result); /* RETURN TO USER */
        }
    }
#endif /* MQX_CHECK_ERRORS && MQX_VERIFY_KERNEL_DATA */
    /* Copy the MQX initialization structure into kernel data. */
    kernel_data->INIT = *mqx_init;
    kernel_data->INIT.START_OF_KERNEL_MEMORY = (pointer) kernel_data;
    kernel_data->INIT.END_OF_KERNEL_MEMORY = (pointer) _ALIGN_ADDR_TO_LOWER_MEM(kernel_data->INIT.END_OF_KERNEL_MEMORY);

    /* init kernel data structures */
    _mqx_init_kernel_data_internal();

    /* Initialize the memory resource manager for the kernel */
    result = _mem_init_internal();
#if MQX_CHECK_ERRORS
    if ( result != MQX_OK ) {
        _mqx_exit(result); /* RETURN TO USER */
    } /* Endif */
#endif

#if MQX_USE_INTERRUPTS

    /* Now obtain the interrupt stack */
    if (kernel_data->INIT.INTERRUPT_STACK_LOCATION) {
        stack_ptr = kernel_data->INIT.INTERRUPT_STACK_LOCATION;
        result = kernel_data->INIT.INTERRUPT_STACK_SIZE;
    }
    else {
        if ( kernel_data->INIT.INTERRUPT_STACK_SIZE < PSP_MINSTACKSIZE ) {
            kernel_data->INIT.INTERRUPT_STACK_SIZE = PSP_MINSTACKSIZE;
        } /* Endif */
#if PSP_STACK_ALIGNMENT
        result = kernel_data->INIT.INTERRUPT_STACK_SIZE + PSP_STACK_ALIGNMENT + 1;
#else
        result = kernel_data->INIT.INTERRUPT_STACK_SIZE;
#endif
        stack_ptr = _mem_alloc_system((_mem_size)result);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (stack_ptr == NULL) {
            _mqx_exit(MQX_OUT_OF_MEMORY); /* RETURN TO USER */
        } /* Endif */
#endif
        _mem_set_type(stack_ptr, MEM_TYPE_INTERRUPT_STACK);
    } /* Endif */

#if MQX_MONITOR_STACK
    _task_fill_stack_internal((_mqx_uint_ptr)stack_ptr, result);
#endif

    kernel_data->INTERRUPT_STACK_PTR = _GET_STACK_BASE(stack_ptr, result);

#endif

    /*
     * Set the stack for the system TD, in case the idle task gets blocked
     * by an exception or if idle task is not used.
     */
    result = PSP_MINSTACKSIZE;
    sys_td_stack_ptr = _mem_alloc_system((_mem_size) result);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (sys_td_stack_ptr == NULL) {
        _mqx_exit(MQX_OUT_OF_MEMORY); /* RETURN TO USER */
    } /* Endif */
#endif
    _mem_set_type(sys_td_stack_ptr, MEM_TYPE_SYSTEM_STACK);

    sys_stack_base_ptr = (uchar_ptr) _GET_STACK_BASE(sys_td_stack_ptr, result);
    td_ptr = SYSTEM_TD_PTR(kernel_data);
    td_ptr->STACK_PTR = (pointer)(sys_stack_base_ptr - sizeof(PSP_STACK_START_STRUCT));
    td_ptr->STACK_BASE = sys_stack_base_ptr;
#if MQX_TD_HAS_STACK_LIMIT
    td_ptr->STACK_LIMIT = _GET_STACK_LIMIT(sys_td_stack_ptr, result);
#endif
    _mqx_system_stack = td_ptr->STACK_PTR;

    /* Build the MQX ready to run queues */
    result = _psp_init_readyqs();
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if ( result != MQX_OK ) {
        _mqx_exit(result); /* RETURN TO USER */
    } /* Endif */
#endif

#if MQX_USE_COMPONENTS

    /* Create a light wait semaphore for component creation */
    _lwsem_create((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM, 1);
#endif

    /* Create a light wait semaphore for task creation/destruction creation */
    _lwsem_create((LWSEM_STRUCT_PTR) & kernel_data->TASK_CREATE_LWSEM, 1);

    /* Call bsp to enable timers and other devices */
    result = _bsp_enable_card();
#if MQX_CHECK_ERRORS
    if ( result != MQX_OK ) {
        _mqx_exit(result); /* RETURN TO USER */
    } /* Endif */
#endif

#if MQX_HAS_TIME_SLICE
    /* Set the kernel default time slice value */
    PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->SCHED_TIME_SLICE,
                    MQX_DEFAULT_TIME_SLICE, &kernel_data->SCHED_TIME_SLICE);
#endif

    /* Create the idle task */
#if MQX_USE_IDLE_TASK
    td_ptr = _task_init_internal(
                    (TASK_TEMPLATE_STRUCT_PTR)&kernel_data->IDLE_TASK_TEMPLATE,
                    kernel_data->ACTIVE_PTR->TASK_ID, MQX_IDLE_TASK_PARAMETER, TRUE, NULL, 0);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (td_ptr == NULL) {
        _mqx_exit(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _task_ready_internal(td_ptr);
#endif

    /* Check here for auto-create tasks, and create them here */
    template_ptr = kernel_data->INIT.TASK_TEMPLATE_LIST;
    while (template_ptr->TASK_TEMPLATE_INDEX) {
        if (template_ptr->TASK_ATTRIBUTES & MQX_AUTO_START_TASK) {
            td_ptr = _task_init_internal(template_ptr, kernel_data->ACTIVE_PTR->TASK_ID,
                            template_ptr->CREATION_PARAMETER, FALSE, NULL, 0);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
            if (td_ptr == NULL) {
                _mqx_exit(MQX_OUT_OF_MEMORY);
            } /* Endif */
#endif
            _task_ready_internal(td_ptr);
        } /* Endif */
        ++template_ptr;
    } /* Endwhile */

    _sched_start_internal(); /* WILL NEVER RETURN FROM HERE */

    return MQX_OK; /* To satisfy lint */

} /* Endbody */

/*!
 * \brief Terminate the MQX application and return to the environment that 
 * started the application.
 * 
 * The function returns back to the environment that called _mqx(). If the 
 * application has installed the MQX exit handler (_mqx_set_exit_handler()), 
 * _mqx_exit() calls the MQX exit handler before it exits. By default, 
 * _bsp_exit_handler is installed as the MQX exit handler in each BSP.
 * 
 * \note It is important to ensure that the environment (boot call stack) the 
 * MQX is returning to is in the consistent state. This is not provided by 
 * distributed MQX BSPs, because the boot stack is reused (rewritten) by MQX 
 * Kernel data. Set the boot stack outside of Kernel data section to support 
 * correct _mqx_exit() functionality.
 * 
 * \param[in] error Error code to return to the function that called _mqx().
 * 
 * \warning Behavior depends on the BSP.
 * 
 * \see _mqx  
 */ 
void _mqx_exit
(
    _mqx_uint error
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _int_disable();

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mqx_exit, error);

#if MQX_EXIT_ENABLED || MQX_CRIPPLED_EVALUATION
    kernel_data->USERS_ERROR = error;
    if (kernel_data->EXIT_HANDLER) {
        (*kernel_data->EXIT_HANDLER)();
    }/* Endif */
    MQX_LONGJMP( _mqx_exit_jump_buffer_internal, 1 );
#else
    while (TRUE) {
    } /* Endwhile */
#endif
} /* Endbody */

/*!
 * \brief Gets a pointer to kernel data.
 * 
 * The address of kernel data corresponds to START_OF_KERNEL_MEMORY in the MQX 
 * initialization structure that the application used to start MQX on the 
 * processor.
 * 
 * \return Pointer to kernel data
 * 
 * \see _mqx
 * \see MQX_INITIALIZATION_STRUCT 
 */ 
pointer _mqx_get_kernel_data
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    return (pointer) kernel_data;

} /* Endbody */

/*!
 * \brief Indicates that an error occurred that is so severe that MQX or the 
 * application can no longer function.
 * 
 * The function logs an error in kernel log (if it has been created and 
 * configured to log errors) and calls _mqx_exit().
 * \n MQX calls _mqx_fatal_error() if it detects an unhandled interrupt while it 
 * is in _int_exception_isr().
 * \n If an application calls _mqx_fatal_error() when it detects a serious error, 
 * you can use this to help you debug by setting a breakpoint in the function.
 * 
 * \param[in] error Error code.
 * 
 * \warning Terminates the application by calling _mqx_exit().
 * 
 * \see _mqx_exit
 * \see _mqx
 * \see _int_exception_isr 
 */ 
void _mqx_fatal_error
(
    _mqx_uint error
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE2(KLOG_mqx_fatal_error, error);
    _mqx_exit(error);
    _KLOGX1( KLOG_mqx_fatal_error);

} /* Endbody */

#if MQX_KD_HAS_COUNTER
/*!
 * \brief Gets a unique number.
 * 
 * This function increments the counter and then returns value of the counter.
 * \n This provides a unique number for whoever requires it.
 * \n Note that this unique number will never be 0.
 *  
 * \return 16-bit number for 16-bit processors or a 32-bit number for 32-bit 
 * processors (unique for the processor and never 0).
 */ 
_mqx_uint _mqx_get_counter
(
    void
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint return_value;

    _GET_KERNEL_DATA(kernel_data);
    _INT_DISABLE();

    /*
     * Increment counter, and ensure it is not zero.
     * If it is zero, set it to one.
     */
    if ( ++kernel_data->COUNTER == 0 ) {
        kernel_data->COUNTER = 1;
    } /* Endif */
    return_value = kernel_data->COUNTER;
    _INT_ENABLE();
    return (return_value);

} /* Endbody */
#endif /* MQX_KD_HAS_COUNTER */

/*!
 * \brief Gets number of loops of the idle task since restart.
 * 
 * \param[out] loop Pointer to idle loop structure.
 * 
 * \return MQX_OK
 * \return MQX_IO_OPERATION_NOT_AVAILABLE (Idle loop was not created.)  
 */ 
_mqx_uint _mqx_get_idle_loop_count
(
    IDLE_LOOP_STRUCT_PTR loop
)
{
#if MQX_USE_IDLE_TASK
    register KERNEL_DATA_STRUCT_PTR  kernel_data;
    _GET_KERNEL_DATA(kernel_data);

    *loop = kernel_data->IDLE_LOOP; 
    return MQX_OK;
#else /* MQX_USE_IDLE_TASK */
    return MQX_IO_OPERATION_NOT_AVAILABLE;
#endif /* MQX_USE_IDLE_TASK */
}

/*!
 * \brief Gets the type of CPU in the CPU_TYPE field of the kernel data.
 * 
 * CPU types begin with PSP_CPU_TYPE_ and are defined in 
 * "source\psp\cpu_family\cpu_family.h".
 *  
 * \return CPU type.
 * 
 * \see _mqx_set_cpu_type
 */ 
_mqx_uint _mqx_get_cpu_type
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return kernel_data->CPU_TYPE;
} /* Endbody */

/*!
 * \brief Sets the type of CPU in the CPU_TYPE field of the kernel data.
 * 
 * The function sets CPU_TYPE in kernel data. The MQX Host Tools family of 
 * products uses CPU type. CPU types begin with PSP_CPU_TYPE_ and are defined in 
 * "source\psp\cpu_family\cpu_family.h".
 * 
 * \param[in] cpu_type CPU type to set.
 * 
 * \warning Does not verify that cpu_type is valid.
 * 
 * \see _mqx_get_cpu_type
 * \see MQX_INITIALIZATION_STRUCT 
 */ 
void _mqx_set_cpu_type
(
    _mqx_uint cpu_type
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    kernel_data->CPU_TYPE = cpu_type;

} /* Endbody */

/*!
 * \brief Gets the address of the MQX initialization structure for this processor.
 * 
 * \return Pointer to the MQX initialization structure in kernel data.
 * 
 * \see _mqx
 * \see MQX_INITIALIZATION_STRUCT 
 */ 
MQX_INITIALIZATION_STRUCT_PTR _mqx_get_initialization
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return ((MQX_INITIALIZATION_STRUCT_PTR) & kernel_data->INIT);

} /* Endbody */

#if  MQX_TAD_RESERVED_ENABLE
/*!
 * \brief Gets the TAD_RESERVED field from the task descriptor.
 * 
 * Third-party compilers can use the functions in their runtime libraries.
 *  
 * \param[in] td Task descriptor to use.
 * 
 * \return TAD_RESERVED for Task Descriptor.
 */ 
pointer _mqx_get_tad_data
(
    pointer td
)
{ /* Body */
    TD_STRUCT_PTR td_ptr = (TD_STRUCT_PTR)td;

    return td_ptr->TAD_RESERVED;

} /* Endbody */

/*!
 * \brief Sets the TAD_RESERVED field in the task descriptor.
 * 
 * Third-party compilers can use the functions in their runtime libraries.
 * 
 * \param[in] td       Task descriptor to use.
 * \param[in] tad_data New value for TAD_RESERVED. 
 */ 
void _mqx_set_tad_data
(
    pointer td,
    pointer tad_data
)
{ /* Body */
    TD_STRUCT_PTR td_ptr = (TD_STRUCT_PTR)td;

    td_ptr->TAD_RESERVED = tad_data;

} /* Endbody */

#endif /* MQX_TAD_RESERVED_ENABLE */

/*!
 * \brief Gets the address of the mqx exit handler function, called when MQX exits.
 * 
 * \return Pointer to the MQX exit handler.
 * \return NULL (Exit disabled.) 
 * 
 * \see _mqx_exit
 * \see _mqx_set_exit_handler
 */ 
MQX_EXIT_FPTR _mqx_get_exit_handler (void)
{ /* Body */
#if MQX_EXIT_ENABLED
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return (kernel_data->EXIT_HANDLER);

#else
    return NULL;
#endif /* MQX_EXIT_ENABLED */
} /* Endbody */

/*!
 * \brief Sets the address of the MQX exit handler, which MQX calls when it exits.
 * 
 * \param[in] entry Pointer to the exit handler.
 * 
 * \see _mqx_get_exit_handler
 * \see _mqx_exit
 */ 
void _mqx_set_exit_handler
(
    MQX_EXIT_FPTR entry
)
{ /* Body */
#if MQX_EXIT_ENABLED
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_mqx_set_exit_handler, entry);
    kernel_data->EXIT_HANDLER = entry;
    _KLOGX1(KLOG_mqx_set_exit_handler);

#endif /* MQX_EXIT_ENABLED */
} /* Endbody */

#if MQX_USE_IO_COMPONENTS

/*!
 * \brief Gets the I/O Component handle for the specified I/O component.
 * 
 * \param[in] component The component number.
 * 
 * \return Component handle.
 * \return NULL (Failure.)
 * 
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li MQX_INVALID_PARAMETER  
 * 
 * \see _mqx_set_io_component_handle
 */ 
pointer _mqx_get_io_component_handle
(
    _mqx_uint component
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (component >= MAX_IO_COMPONENTS) {
        _task_set_error(MQX_INVALID_PARAMETER);
        return(NULL);
    } /* Endif */
#endif

    return kernel_data->IO_COMPONENTS[component];

} /* Endbody */

/*!
 * \brief Sets the I/O Component handle for the specified I/O component and 
 * returns the previous value.
 * 
 * \param[in] component The component number.
 * \param[in] handle    The new handle.
 * 
 * \return Old component handle.
 * \return NULL (Failure.)
 * 
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li MQX_INVALID_PARAMETER  
 * 
 * \see _mqx_get_io_component_handle
 */ 
pointer _mqx_set_io_component_handle
(
    _mqx_uint component,
    pointer   handle
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    pointer old_handle;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (component >= MAX_IO_COMPONENTS) {
        _task_set_error(MQX_INVALID_PARAMETER);
        return(NULL);
    } /* Endif */
#endif

    _int_disable();
    old_handle = kernel_data->IO_COMPONENTS[component];
    if (old_handle == NULL) {
        kernel_data->IO_COMPONENTS[component] = handle;
    }
    else {
        if (handle == NULL) {
            kernel_data->IO_COMPONENTS[component] = handle;
        } /* Endif */
    } /* Endif */
    _int_enable();
    return old_handle;

} /* Endbody */

/*!
 * \brief Gets the task ID of the System Task.
 * 
 * System resources are owned by System Task.
 * 
 * \return Task ID of System Task
 * 
 * \see _mem_transfer  
 */ 
_task_id _mqx_get_system_task_id
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return(kernel_data->SYSTEM_TD.TASK_ID);

} /* Endbody */

/*!
 * \brief Adds new component handle.
 * 
 * \param[in] component      The component number.
 * \param[in] handle         The handle.
 * \param[in] next_field_ptr Pointer to the next field.
 * 
 * \return MQX_OK
 * \return MQX_INVALID_PARAMETER
 * \return MQX_INVALID_COMPONENT_HANDLE
 * 
 * \see _mqx_unlink_io_component_handle    
 */ 
_mqx_uint _mqx_link_io_component_handle
(
    _mqx_uint component,
    pointer   handle,
    pointer * next_field_ptr
)
{
    pointer old_handle;
    KERNEL_DATA_STRUCT_PTR kernel_data;
#if MQX_CHECK_ERRORS
    pointer * prev_ptr,next_ptr;
    uint_32 offset = (uint_32) next_field_ptr - (uint_32) handle;
#endif

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if ((component >= MAX_IO_COMPONENTS) || (handle==NULL) || (next_field_ptr==NULL)) {
        _task_set_error(MQX_INVALID_PARAMETER);
        return(MQX_INVALID_PARAMETER);
    } /* Endif */
#endif

    _int_disable();

#if MQX_CHECK_ERRORS
    if (kernel_data->IO_COMPONENTS[component] == handle) {
        _int_enable();
        return MQX_INVALID_COMPONENT_HANDLE;
    }
    else {

        prev_ptr = kernel_data->IO_COMPONENTS[component];

        while (prev_ptr) {
            next_ptr = *((pointer *)((uint_32)prev_ptr + offset));
            if (next_ptr == handle) {
                _int_enable();
                return MQX_INVALID_COMPONENT_HANDLE;
            }
            else {
                prev_ptr = next_ptr;
            }
        }
    }

#endif

    old_handle = kernel_data->IO_COMPONENTS[component];
    kernel_data->IO_COMPONENTS[component] = handle;
    *next_field_ptr = old_handle;
    _int_enable();
    return MQX_OK;
}

/*!
 * \brief Removes specified component handle.
 * 
 * \param[in] component      The component number.
 * \param[in] handle         The handle to remove.
 * \param[in] next_field_ptr Pointer to the next field.
 * 
 * \return MQX_OK
 * \return MQX_INVALID_PARAMETER  
 *  
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li MQX_INVALID_PARAMETER 
 *  
 * \see _mqx_link_io_component_handle
 */ 
_mqx_uint _mqx_unlink_io_component_handle
(
    _mqx_uint component,
    pointer   handle,
    pointer * next_field_ptr
)
{
    uint_32 offset = (uint_32) next_field_ptr - (uint_32) handle;
    pointer prev_ptr,next_ptr;
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint result = MQX_INVALID_COMPONENT_HANDLE;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if ((component >= MAX_IO_COMPONENTS) || (handle==NULL) || (next_field_ptr==NULL)) {
        _task_set_error(MQX_INVALID_PARAMETER);
        return(MQX_INVALID_PARAMETER);
    } /* Endif */
#endif

    _int_disable();

    if (kernel_data->IO_COMPONENTS[component] == handle) {
        kernel_data->IO_COMPONENTS[component] = *((pointer *)((uint_32)handle + offset));
        *((pointer *) ((uint_32)handle + offset)) = NULL;
        result = MQX_OK;
    }
    else {

        prev_ptr = kernel_data->IO_COMPONENTS[component];

        while (prev_ptr) {
            next_ptr = *((pointer *)((uint_32)prev_ptr + offset));
            if (next_ptr == handle) {
                *((pointer *) ((uint_32)prev_ptr + offset)) = *((pointer *)((uint_32)next_ptr + offset));
                *((pointer *) ((uint_32)next_ptr + offset)) = NULL;
                result = MQX_OK;
                break;
            }
            else {
                prev_ptr = next_ptr;
            }
        }
    }

    _int_enable();
    return result;
}
#endif

/*!
 * \private
 * 
 * \brief Initialize the static parts of the kernel data structure. 
 * 
 * Care has to be taken when calling functions within this file, as the kernel 
 * is not running yet. Specifically, functions which rely on _mqx_get_kernel_data 
 * can not be called. 
 */ 
void _mqx_init_kernel_data_internal
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TASK_TEMPLATE_STRUCT_PTR task_template_ptr;
    TD_STRUCT_PTR td_ptr;
    _mqx_uint priority_levels;
    _mqx_uint i;

    _GET_KERNEL_DATA(kernel_data);

    /* Store the configuration used when the kernel was compiled */
    kernel_data->CONFIG1 = MQX_CNFG1;
    kernel_data->CONFIG2 = MQX_CNFG2;

    /* Store the addressability of the processor. How many bits in a byte. */
    kernel_data->ADDRESSING_CAPABILITY = PSP_MEMORY_ADDRESSING_CAPABILITY;

    /* Indicate the endianess of the target */
    kernel_data->ENDIANESS = PSP_ENDIAN;

    /* Store PSP memory alignment information */

#if PSP_MEM_STOREBLOCK_ALIGNMENT != 0
    kernel_data->PSP_CFG_MEM_STOREBLOCK_ALIGNMENT = PSP_MEM_STOREBLOCK_ALIGNMENT;
#endif

    kernel_data->PSP_CFG_MEMORY_ALIGNMENT = PSP_MEMORY_ALIGNMENT;
    kernel_data->PSP_CFG_STACK_ALIGNMENT = PSP_STACK_ALIGNMENT;

    /*
     * Fill in fields of the kernel data structure from the initialization
     * structure.
     */
    /*kernel_data->PROCESSOR_NUMBER =  kernel_data->INIT.PROCESSOR_NUMBER;*/

    /* Set IPC id for compatibility */
#if MQX_USE_IPC
    kernel_data->MY_IPC_ID = BUILD_TASKID(kernel_data->INIT.PROCESSOR_NUMBER, 1);
#endif

    /* Store location of current interrupt vector table */
#if MQX_EXIT_ENABLED
    kernel_data->USERS_VBR = (_mqx_max_type)_int_get_vector_table();
#endif

#if MQX_CHECK_ERRORS
    if (kernel_data->INIT.TASK_TEMPLATE_LIST == NULL) {
        _mqx_exit(MQX_INVALID_POINTER);
    } /* Endif */
#endif

#if MQX_HAS_TIME_SLICE
    /* Set the default scheduling policy for created tasks */
    kernel_data->SCHED_POLICY = MQX_SCHED_FIFO;
#endif

#if MQX_KD_HAS_COUNTER
    /* Initialize the kernel counter. */
    kernel_data->COUNTER = 1U;
#endif

    /* Set up the disable and enable priority levels */
    _psp_set_kernel_disable_level();

    /*
     * Initialize the system task so that functions which update the
     * task error code can be called.
     * The system task never runs, but it's TD is used for error codes
     * during initialization, and for storage of memory blocks assigned
     * to the system.
     */
    td_ptr = (TD_STRUCT_PTR) & kernel_data->SYSTEM_TD;
    kernel_data->ACTIVE_PTR = td_ptr;
    kernel_data->ACTIVE_SR = kernel_data->DISABLE_SR;
    td_ptr->TASK_SR = kernel_data->DISABLE_SR;
    td_ptr->TASK_ID = BUILD_TASKID(kernel_data->INIT.PROCESSOR_NUMBER, SYSTEM_TASK_NUMBER);
    td_ptr->STATE = BLOCKED;

    /* Initialize the light weight semaphores queue */
    _QUEUE_INIT(&kernel_data->LWSEM, 0);

#if MQX_ENABLE_USER_MODE
    _QUEUE_INIT(&kernel_data->USR_LWSEM, 0);
#endif

#if MQX_HAS_TICK
    /* Set up the timeout queue */
    _QUEUE_INIT(&kernel_data->TIMEOUT_QUEUE, 0);
#endif

    /*
     * Compute the number of MQX priority levels needed. This is done
     * by determining the task that has the lowest priority (highest number)
     */
    priority_levels = 0;
    task_template_ptr = kernel_data->INIT.TASK_TEMPLATE_LIST;
    for (i = 0; task_template_ptr->TASK_TEMPLATE_INDEX && (i < MQX_MAXIMUM_NUMBER_OF_TASK_TEMPLATES); ++i, ++task_template_ptr) {
        if (priority_levels < task_template_ptr->TASK_PRIORITY) {
            priority_levels = task_template_ptr->TASK_PRIORITY;
        } /* Endif */
    } /* Endfor */
    kernel_data->LOWEST_TASK_PRIORITY = priority_levels;

#if MQX_USE_IDLE_TASK
    /*
     * Initialize the task template for the IDLE Task.
     * NOTE that the idle task runs at 1 level lower than any user task.
     */
    task_template_ptr = (TASK_TEMPLATE_STRUCT_PTR)
    &kernel_data->IDLE_TASK_TEMPLATE;
    task_template_ptr->TASK_TEMPLATE_INDEX = IDLE_TASK;
    task_template_ptr->TASK_STACKSIZE      = PSP_IDLE_STACK_SIZE;
    task_template_ptr->TASK_NAME           = MQX_IDLE_TASK_NAME;
    task_template_ptr->TASK_ADDRESS        = _mqx_idle_task;
    task_template_ptr->TASK_PRIORITY       = priority_levels + 1;
#endif

    /*
     * Initialize the linked list of all TDs in the system.
     * Initially zero. Not including system TD
     */
    _QUEUE_INIT(&kernel_data->TD_LIST, 0);

    /* Set the TD counter */
    /* Start SPR P171-0014-02       */
    /* kernel_data->TD_COUNTER = 1; */
    kernel_data->TASK_NUMBER = 1;
    /* End SPR P171-0014-02         */

} /* Endbody */

/*!
 * \brief This function gets the address of the TD_STRUCT.CRT_TLS field.
 * 
 * \return Adress of the TD_STRUCT.CRT_TLS field.
 * \return NULL (Local storage thread disabled or kernel_data->IN_ISR is not set.) 
 */ 
pointer _crt_tls_reference(void)
{ /* Body */
#if MQX_THREAD_LOCAL_STORAGE_ENABLE
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _GET_KERNEL_DATA(kernel_data);

    if (kernel_data->IN_ISR)
    {
        return NULL;
    } /* Endif */

    return &kernel_data->ACTIVE_PTR->CRT_TLS;
#else
    return NULL;
#endif
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/watchdog.c<|end_filename|>
/*HEADER*********************************************************************
 * 
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *************************************************************************** 
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: watchdog.c$
 * $Version : 3.8.2.0$
 * $Date    : Jun-25-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Watchdog component.
 *
 *END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_SW_WATCHDOGS
#include "watchdog.h"
#include "watchdog_prv.h"

/*!
 * \brief Creates the watchdog component.
 * 
 * An application must explicitly create the watchdog component before tasks can 
 * use watchdogs.
 * \n The function returns MQX_OK if either:
 * \li Watchdog component is created.
 * \li Watchdog component was previously created and the configuration is not 
 * changed.
 * 
 * \param[in] timer_interrupt_vector Periodic timer interrupt vector number.
 * \param[in] error_function         Function that MQX calls when a watchdog 
 * expires.
 * 
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return WATCHDOG_INVALID_ERROR_FUNCTION (Error_function is NULL.)
 * \return WATCHDOG_INVALID_INTERRUPT_VECTOR (MQX cannot install the periodic 
 * timer interrupt vector.)
 * \return MQX_OUT_OF_MEMORY (MQX cannot allocate memory for watchdog component 
 * data.)
 * 
 * \warning Cannot be called from an ISR. 
 * 
 * \see _watchdog_start
 * \see _watchdog_start_ticks
 * \see _watchdog_stop     
 */ 
_mqx_uint _watchdog_create_component
(
    _mqx_uint           timer_interrupt_vector,
    WATCHDOG_ERROR_FPTR error_function
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR        kernel_data;
    WATCHDOG_COMPONENT_STRUCT_PTR watchdog_component_ptr;
    pointer                       interrupt_data;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_watchdog_create_component, timer_interrupt_vector, error_function);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_watchdog_create_component, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    _lwsem_wait((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG] != NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
        _KLOGX2(KLOG_watchdog_create_component, MQX_OK);
        return(MQX_OK);
    } /* Endif */

#if MQX_CHECK_ERRORS
    if (!error_function)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
        _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_ERROR_FUNCTION);
        return(WATCHDOG_INVALID_ERROR_FUNCTION);
    } /* Endif */
    if ((timer_interrupt_vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
                    (timer_interrupt_vector > kernel_data->LAST_USER_ISR_VECTOR))
    {
        _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
        _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_INTERRUPT_VECTOR);
        return(WATCHDOG_INVALID_INTERRUPT_VECTOR);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    /* Get the watchdog component data structure */
    watchdog_component_ptr = (WATCHDOG_COMPONENT_STRUCT_PTR)
    _mem_alloc_system_zero((_mem_size)sizeof(WATCHDOG_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (watchdog_component_ptr == NULL)
    {
        _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
        _KLOGX2(KLOG_watchdog_create_component, MQX_OUT_OF_MEMORY);
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif /* MQX_CHECK_MEMORY_ALLOCATION_ERRORS */
    _mem_set_type(watchdog_component_ptr, MEM_TYPE_WATCHDOG_COMPONENT);

    watchdog_component_ptr->ERROR_FUNCTION = error_function;
    watchdog_component_ptr->VALID = WATCHDOG_VALID;
    watchdog_component_ptr->INTERRUPT_VECTOR = timer_interrupt_vector;

    interrupt_data = _int_get_isr_data(timer_interrupt_vector);
    _INT_DISABLE();
    watchdog_component_ptr->TIMER_INTERRUPT_HANDLER = _int_install_isr(
                    timer_interrupt_vector, _watchdog_isr, interrupt_data);
#if MQX_CHECK_ERRORS
    if (!watchdog_component_ptr->TIMER_INTERRUPT_HANDLER)
    {
        _int_enable();
        _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
        _mem_free(watchdog_component_ptr);
        _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_INTERRUPT_VECTOR);
        return(WATCHDOG_INVALID_INTERRUPT_VECTOR);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */

    kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG] = watchdog_component_ptr;
#if MQX_COMPONENT_DESTRUCTION
    kernel_data->COMPONENT_CLEANUP[KERNEL_WATCHDOG] = _watchdog_cleanup;
#endif /* MQX_COMPONENT_DESTRUCTION */
    _INT_ENABLE();
    _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));

    _KLOGX2(KLOG_watchdog_create_component, MQX_OK);

    return(MQX_OK);

} /* Endbody */

/*!
 * \brief This function takes over from the timer interrupt handler in order to 
 * process watchdog timeouts.
 * 
 * \param[in] parameter The parameter passed by the kernel. 
 */ 
void _watchdog_isr
(
    pointer parameter
)
{ /* Body */
    MQX_TICK_STRUCT                 kd_time;
    KERNEL_DATA_STRUCT_PTR          kernel_data;
    TD_STRUCT_PTR                   td_ptr;
    WATCHDOG_COMPONENT_STRUCT_PTR   watchdog_component_ptr;
    WATCHDOG_ALARM_TABLE_STRUCT_PTR table_ptr;
    _mqx_uint                       i;
    _mqx_int                        result;

    _GET_KERNEL_DATA(kernel_data);
    watchdog_component_ptr = (WATCHDOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG];

    /* execute standard timer routine (in case of BSP timer, the 
     _time_notify_kernel() may get invoked now) */
    (*watchdog_component_ptr->TIMER_INTERRUPT_HANDLER)(parameter);

#if MQX_CHECK_ERRORS
    if (watchdog_component_ptr == NULL)
    {
        (*kernel_data->DEFAULT_ISR)((pointer)kernel_data->SYSTEM_CLOCK_INT_NUMBER);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
#if MQX_CHECK_VALIDITY
    if (watchdog_component_ptr->VALID != WATCHDOG_VALID)
    {
        (*kernel_data->DEFAULT_ISR)((pointer)kernel_data->SYSTEM_CLOCK_INT_NUMBER);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    table_ptr = &watchdog_component_ptr->ALARM_ENTRIES;
    while (table_ptr != NULL)
    {
        for (i = 0; i < WATCHDOG_TABLE_SIZE; ++i)
        {
            td_ptr = table_ptr->TD_PTRS[i];
            if (td_ptr != NULL)
            {
#if MQX_TASK_DESTRUCTION
                if (! (td_ptr->FLAGS & TASK_WATCHDOG_STARTED))
                {
                    /* The td has been destroyed and re-created */
                    table_ptr->TD_PTRS[i] = NULL;
                }
                else if (td_ptr->TASK_ID == 0)
                {
                    /* The task has been destroyed */
                    table_ptr->TD_PTRS[i] = NULL;
                }
                else
#endif /* MQX_TASK_DESTRUCTION */
                if (td_ptr->FLAGS & TASK_WATCHDOG_RUNNING)
                {
                    /* An enabled watchdog */

                    /* A timer interrupt is about to fire so increment kernel time */
                    kd_time = kernel_data->TIME;
                    result = PSP_CMP_TICKS(&kd_time, &td_ptr->WATCHDOG_TIME);
                    if (result >= 0)
                    {
                        /* EXPIRED */
                        td_ptr->FLAGS &= ~TASK_WATCHDOG_RUNNING;
                        (*watchdog_component_ptr->ERROR_FUNCTION)(td_ptr);
                    } /* Endif */
                } /* Endif */
            } /* Endif */
        } /* Endfor */
        table_ptr = table_ptr->NEXT_TABLE_PTR;

    } /* Endwhile */

} /* Endbody */

/*!
 * \brief Starts or restart the watchdog.
 * 
 * The function returns FALSE if either of these conditions is true:
 * \li Watchdog component was not previously created.
 * \li Watchdog component data is no longer valid.
 * 
 * \param[in] time Time in milliseconds until the watchdog expires.
 * 
 * \return TRUE (success) or FALSE (Failure: see Description.) 
 *  
 * \see _watchdog_start_ticks
 * \see _time_to_ticks
 * \see _usr_lwevent_clear
 * \see _watchdog_stop
 * \see MQX_TICK_STRUCT
 */ 
boolean _watchdog_start
(
    uint_32 time
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    boolean         result;
    MQX_TICK_STRUCT start_time;
    /* TIME_STRUCT                     tmp; */

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE2(KLOG_watchdog_start, time);

    /* tmp.MILLISECONDS = time;              */
    /* tmp.SECONDS      = 0;                 */
    /*                                       */
    /* PSP_TIME_TO_TICKS(&tmp, &start_time); */
    PSP_MILLISECONDS_TO_TICKS_QUICK(time, &start_time);

    result = _watchdog_start_internal((MQX_TICK_STRUCT_PTR)&start_time);

    _KLOGX2(KLOG_watchdog_start, result);

    return(result);

} /* Endbody */

/*!
 * \brief Stops the watchdog.
 * 
 * The function returns FALSE if any of these conditions is true:
 * \li Watchdog component was not previously created.
 * \li Watchdog component data is no longer valid.
 * \li Watchdog was not started.
 * 
 * \return TRUE (success) or FALSE (Failure: see Description.)
 * 
 * \see _usr_lwevent_clear            
 * \see _watchdog_start
 * \see _watchdog_start_ticks   
 */ 
boolean _watchdog_stop(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR          td_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE1(KLOG_watchdog_stop);

    td_ptr = kernel_data->ACTIVE_PTR;
    if (td_ptr->FLAGS & TASK_WATCHDOG_STARTED)
    {
        _INT_DISABLE();
        /* td_ptr->FLAGS &= ~(TASK_WATCHDOG_STARTED | TASK_WATCHDOG_RUNNING); */
        td_ptr->FLAGS &= ~TASK_WATCHDOG_RUNNING;
        _INT_ENABLE();
        _KLOGX2(KLOG_watchdog_stop, TRUE);
        return(TRUE);
    } /* Endif */

    _KLOGX2(KLOG_watchdog_stop, FALSE);
    return(FALSE);

} /* Endbody */

/*!
 * \private
 *  
 * \brief This function starts a software watchdog for the current task.
 * 
 * The timer will expire at the specified number of ticks in the future.
 * 
 * \param[in] tick_ptr The time in ticks at which the watchdog expires.
 *  
 * \return TRUE (success) or FALSE (Failure: see Description.)
 */ 
boolean _watchdog_start_internal
(
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR          kernel_data;
    TD_STRUCT_PTR                   td_ptr;
    WATCHDOG_COMPONENT_STRUCT_PTR   watchdog_component_ptr;
    WATCHDOG_ALARM_TABLE_STRUCT_PTR table_ptr;
    MQX_TICK_STRUCT                 kd_time;
    _mqx_uint                       i;

    _GET_KERNEL_DATA(kernel_data);

    td_ptr = kernel_data->ACTIVE_PTR;

    kd_time = kernel_data->TIME;

    if (td_ptr->FLAGS & TASK_WATCHDOG_STARTED)
    {
        _INT_DISABLE();
        PSP_ADD_TICKS(tick_ptr, &kd_time, &td_ptr->WATCHDOG_TIME);
        td_ptr->FLAGS |= TASK_WATCHDOG_RUNNING;
        _INT_ENABLE();
        return(TRUE);
    } /* Endif */

    watchdog_component_ptr = (WATCHDOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG];
#if MQX_CHECK_ERRORS
    if (watchdog_component_ptr == NULL)
    {
        return(FALSE);
    } /* Endif */
#endif /* MQX_CHECK_ERRORS */
#if MQX_CHECK_VALIDITY
    if (watchdog_component_ptr->VALID != WATCHDOG_VALID)
    {
        return(FALSE);
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    table_ptr = &watchdog_component_ptr->ALARM_ENTRIES;

    _INT_DISABLE();
    while (table_ptr != NULL)
    {
        for (i = 0; i < WATCHDOG_TABLE_SIZE; ++i)
        {
            if (table_ptr->TD_PTRS[i] == NULL)
            {
                table_ptr->TD_PTRS[i] = td_ptr;
                PSP_ADD_TICKS(tick_ptr, &kd_time, &td_ptr->WATCHDOG_TIME);
                td_ptr->FLAGS |= TASK_WATCHDOG_STARTED | TASK_WATCHDOG_RUNNING;
                _INT_ENABLE();
                return(TRUE);
            } /* Endif */
        } /* Endwhile */
        if (table_ptr->NEXT_TABLE_PTR == NULL)
        {
            table_ptr->NEXT_TABLE_PTR = (WATCHDOG_ALARM_TABLE_STRUCT_PTR)
            _mem_alloc_system_zero((_mem_size)sizeof(WATCHDOG_ALARM_TABLE_STRUCT));
            _mem_set_type(table_ptr->NEXT_TABLE_PTR, MEM_TYPE_WATCHDOG_ALARM);
        } /* Endif */
        table_ptr = table_ptr->NEXT_TABLE_PTR;
    } /* Endwhile */

    _int_enable();
    return(FALSE);

} /* Endbody */

/*!
 * \brief Starts or restart the watchdog.
 * 
 * The function returns FALSE if either of these conditions is true:
 * \li Watchdog component was not previously created.
 * \li Watchdog component data is no longer valid.
 * 
 * \param[in] tick_ptr Pointer to the number of ticks until the watchdog expires.
 * 
 * \return TRUE (success) or FALSE (Failure: see Description.) 
 *  
 * \see _watchdog_start
 * \see _time_to_ticks
 * \see _usr_lwevent_clear
 * \see _watchdog_stop
 * \see MQX_TICK_STRUCT
 */ 
boolean _watchdog_start_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    boolean result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE2(KLOG_watchdog_start_ticks, tick_ptr);

    result = _watchdog_start_internal(tick_ptr);

    _KLOGX2(KLOG_watchdog_start_ticks, result);

    return(result);

} /* Endbody */
/*!
 * \brief Used during task destruction to clean up any watchdogs started by this 
 * task.
 * 
 * \param[in] td_ptr The task being destroyed. 
 */ 
void _watchdog_cleanup
(
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR          kernel_data;
    WATCHDOG_COMPONENT_STRUCT_PTR   watchdog_component_ptr;
    WATCHDOG_ALARM_TABLE_STRUCT_PTR table_ptr;
    _mqx_uint                       i;

    _GET_KERNEL_DATA(kernel_data);

    watchdog_component_ptr = (WATCHDOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG];
    if (watchdog_component_ptr == NULL)
    {
        return; /* No work to do */
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (watchdog_component_ptr->VALID != WATCHDOG_VALID)
    {
        return;
    } /* Endif */
#endif /* MQX_CHECK_VALIDITY */

    table_ptr = &watchdog_component_ptr->ALARM_ENTRIES;

    _INT_DISABLE();
    while (table_ptr != NULL)
    {
        for (i = 0; i < WATCHDOG_TABLE_SIZE; ++i)
        {
            if (table_ptr->TD_PTRS[i] == td_ptr)
            {
                table_ptr->TD_PTRS[i] = NULL;
                td_ptr->FLAGS &= ~(TASK_WATCHDOG_STARTED | TASK_WATCHDOG_RUNNING);
                _INT_ENABLE();
                return;
            } /* Endif */
        } /* Endfor */
        table_ptr = table_ptr->NEXT_TABLE_PTR;
    } /* Endwhile */
    _INT_ENABLE();

} /* Endbody */

/*!
 * \brief Tests the watchdog component data for consistency and validity.
 * 
 * The function returns MQX_OK if either:      
 * \li It did not find an error in watchdog component data.
 * \li Watchdog component was not previously created.
 * 
 * \param[out] watchdog_error_ptr       Pointer to the watchdog component base 
 * that has an error (NULL if no errors are found).
 * \param[out] watchdog_table_error_ptr Pointer to the watchdog table that has 
 * an error (always NULL).
 * 
 * \return MQX_OK (see Description)
 * \return MQX_INVALID_COMPONENT_BASE (An error was found.)
 * 
 * \see _usr_lwevent_clear
 * \see _watchdog_start
 * \see _watchdog_start_ticks
 * \see _watchdog_stop  
 */ 
_mqx_uint _watchdog_test
(
    pointer _PTR_ watchdog_error_ptr,
    pointer _PTR_ watchdog_table_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR        kernel_data;
    WATCHDOG_COMPONENT_STRUCT_PTR watchdog_component_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_watchdog_test, watchdog_error_ptr, watchdog_table_error_ptr);

    *watchdog_error_ptr = NULL;
    *watchdog_table_error_ptr = NULL;

    watchdog_component_ptr = (WATCHDOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG];
    if (watchdog_component_ptr == NULL)
    {
        _KLOGX2(KLOG_watchdog_test, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    *watchdog_error_ptr = watchdog_component_ptr;
    if (watchdog_component_ptr->VALID != WATCHDOG_VALID)
    {
        _KLOGX2(KLOG_watchdog_test, MQX_INVALID_COMPONENT_BASE);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    _KLOGX2(KLOG_watchdog_test, MQX_OK);
    return(MQX_OK);

} /* Endbody */

#endif /* MQX_USE_SW_WATCHDOGS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/nat_apply.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nat_apply.c$
* $Version : 3.8.5.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   This file contains the NAT implementation.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_apply
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Modifies a packet according to NAT if applicable. If an error
*     code is returned, the packet should be dropped. 
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_apply
   (
      RTCSPCB_PTR _PTR_    pcb_ptr  /* [IN/OUT] PCB containing the packet */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   NAT_ALG_CFG_STRUCT_PTR  nat_alg_cfg_ptr;
   NAT_SESSION_STRUCT_PTR  nat_session_ptr = NULL;
   IP_HEADER_PTR           ip_header_ptr = (IP_HEADER_PTR)(pointer)RTCSPCB_DATA(*pcb_ptr);
   _ip_address             ipsrc, ipdest;
   uint_32                 error, ip_protocol;
   uint_16                 packet_len, icmp_type, tcp_flags;
   TRANSPORT_UNION         transport;
   boolean                 dest_is_local, icmperr = FALSE, reset = FALSE;
   boolean                 source_is_private, dest_is_private;
   uint_16                 destination_port;

   nat_cfg_ptr->STATS.ST_PACKETS_TOTAL++;

   // Start CR TBD
   ipsrc = ntohl(ip_header_ptr->SOURCE);
   ipdest = ntohl(ip_header_ptr->DEST);
   source_is_private = NAT_is_private_addr(&nat_cfg_ptr->PRIVATE_NETWORKS, ipsrc);
   dest_is_private = NAT_is_private_addr(&nat_cfg_ptr->PRIVATE_NETWORKS, ipdest);
   dest_is_local = IP_is_local(NULL, ipdest);      
   if (!source_is_private && !dest_is_local) {
      /*
      ** Case #1:public(external) or public(local) to public(external)
      */
      nat_cfg_ptr->STATS.ST_PACKETS_BYPASS++;
      return RTCS_OK;
   }
   // End CR TBD

   if (ntohs(ip_header_ptr->FRAGMENT) & (IP_FRAG_MF | IP_FRAG_MASK)) {
#if RTCSCFG_ENABLE_IP_REASSEMBLY
      #if RTCS_VERSION <= 0x00029600L
      #ifndef __MSVC__
      #warning "This version of NAT requires a modified version of RTCS, see Release notes"
      #endif
      #endif
      nat_cfg_ptr->STATS.ST_PACKETS_FRAGMENTS++;

      error = IP_reasm(*pcb_ptr,pcb_ptr); 
      if (error != RTCS_OK) {
         nat_cfg_ptr->STATS.ST_PACKETS_REASSSEMBLY_ERR++;
         return error;
      }
      if (*pcb_ptr == NULL) {
         // Reassembly queued the PCB - there is nothing to do yet.
         return RTCS_OK;
      }
      // We now have a reassembled packet - however the PCB is new, so 
      // update packet address
      ip_header_ptr = (IP_HEADER_PTR)(pointer)RTCSPCB_DATA(*pcb_ptr);
      nat_cfg_ptr->STATS.ST_PACKETS_REASSEMBLED++;
#else
    nat_cfg_ptr->STATS.ST_PACKETS_REASSSEMBLY_ERR++;
    return RTCSERR_FEATURE_NOT_ENABLED;
#endif /* RTCSCFG_ENABLE_IP_REASSEMBLY */
   } /* Endif */

   
   /* Get the frequently accessed fields from the IP Header */
   packet_len = ntohs(ip_header_ptr->LENGTH);
   ipsrc = ntohl(ip_header_ptr->SOURCE);
   ipdest = ntohl(ip_header_ptr->DEST);
   ip_protocol = ntohc(ip_header_ptr->PROTOCOL);
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);
   
   /* determine if source and/or destination is for a private network */
   source_is_private = NAT_is_private_addr(&nat_cfg_ptr->PRIVATE_NETWORKS, ipsrc);
   dest_is_private = NAT_is_private_addr(&nat_cfg_ptr->PRIVATE_NETWORKS, ipdest);
   dest_is_local = IP_is_local(NULL, ipdest);      


   /* 
   ** There are four possible cases:
   **    1. Packet is staying in the same network (public->public or private->private) no translation
   **    2. Move packet from private network to public network (will involve translation)
   **    3. Packet is for an unreachable destination (explicit public->private). 
   **    4. Move packet from public network to private network after translation
   **
   */
   if (source_is_private) {
      /*
      ** Source is private (either local or external)
      ** It can send to other hosts on the private network, which includes the 
      ** private network interface of the NAT router.
      */
      if (dest_is_private /* || dest_is_local */ ) {  
         /*
         ** Case #1: private(external) or private(local) to private(external), private(local) or public(local)
         ** No processing required, Not going onto the public network
         */
         nat_cfg_ptr->STATS.ST_PACKETS_BYPASS++;
         return RTCS_OK;                      
      } 

      /*
      ** Case #2: private(external) or private(local) to public(external)
      */

   } else {

      /* Source is public (either local or external) */
      if (dest_is_private) {     
         /*
         ** Case #3: public(external) or public(local) to private(external) or private(local)
         ** The source is a host on the public network, the destination is private.
         **  This packet should not be forwarded into the private network because the public host shouldn't 
         ** know about such an address. 
         */
         nat_cfg_ptr->STATS.ST_PACKETS_PUB_PRV_ERR++;      
         return RTCSERR_IP_UNREACH;                
      
      } else if (!dest_is_local)  {   
         /*
         ** Case #1:public(external) or public(local) to public(external)
         */
         nat_cfg_ptr->STATS.ST_PACKETS_BYPASS++;
         return RTCS_OK;
      } /* Endif */

      /* 
      ** Case #4: public(external) or public(local) to public(local)               
      ** The source is a host on the public network. The destination is not private.
      ** This packet might be for the private network or the NAT router. 
      */
      
   } /* Endif */

   /* NAT only supports ICMP, UDP and TCP transport layer protocols */
   switch (ip_protocol) {
      case IPPROTO_TCP:
         if (packet_len < sizeof(TCP_HEADER))  {
            NAT_UPDATE_ERR_STATS(nat_cfg_ptr,source_is_private);
            return RTCSERR_TCP_BAD_HEADER;
         } /* Endif */
         destination_port = ntohs(transport.TCP_PTR->dest_port);
         break;

      case IPPROTO_UDP:
         if (packet_len < sizeof(UDP_HEADER))  {
            NAT_UPDATE_ERR_STATS(nat_cfg_ptr,source_is_private);
            return RTCSERR_UDP_BAD_HEADER;
         } /* Endif */
         destination_port = ntohs(transport.UDP_PTR->DEST_PORT);
         break;

      case IPPROTO_ICMP:
         if (packet_len < sizeof(ICMP_ECHO_HEADER)) {
            NAT_UPDATE_ERR_STATS(nat_cfg_ptr,source_is_private);
            return RTCSERR_ICMP_BAD_HEADER;
         } /* Endif */
          
         /* Get the icmp message type */
         icmp_type = ntohc(transport.ICMP_PTR->TYPE);
         if (icmp_type==ICMPTYPE_REDIRECT) {
            /* Never modify REDIRECTs */
            nat_cfg_ptr->STATS.ST_PACKETS_BYPASS++;
            return RTCS_OK;
         } 
                  
         icmperr = !ICMPTYPE_ISQUERY(icmp_type);
         break;        
          
      default:
         if (source_is_private) {
            nat_cfg_ptr->STATS.ST_PACKETS_PRV_PUB_ERR++;
            return RTCSERR_NAT_UNSUPPORTED_PROTOCOL;
         } else {
            nat_cfg_ptr->STATS.ST_PACKETS_BYPASS++;
            return RTCS_OK;
         } /* Endif */
   } /* Endswitch */


   /* Apply NAT ALGs and then do lookup */
   if (!icmperr) {
      nat_session_ptr = NAT_lookup(ip_header_ptr, FALSE, FALSE, &error);
      for (nat_alg_cfg_ptr = nat_cfg_ptr->ALG_INFO_PTR; nat_alg_cfg_ptr; nat_alg_cfg_ptr = nat_alg_cfg_ptr->NEXT) {
         error = nat_alg_cfg_ptr->ALG_EXEC(
            pcb_ptr, 
            !source_is_private, 
            nat_alg_cfg_ptr,
            (pointer _PTR_)&nat_session_ptr);

         /* If the ALG returns an error, we discard the packet */
         if (error) {
            NAT_UPDATE_ERR_STATS(nat_cfg_ptr,source_is_private);
            return error;
         } /* Endif */
      } /* Endfor */

      /* 
      ** Update pointers in case the PCB was modifed. 
      */
      ip_header_ptr = (IP_HEADER_PTR)(pointer)RTCSPCB_DATA(*pcb_ptr);
      transport.PTR = TRANSPORT_PTR(ip_header_ptr);
   } /* Endif */
   

   if ((nat_session_ptr == NULL) && (!icmperr)) {

      /* If a public host sent the message, don't create a new session - 
      ** Send the packet on to the  local public interface */
      if (!source_is_private) { 
         nat_cfg_ptr->STATS.ST_PACKETS_BYPASS++;      
         return RTCS_OK;
      } /* Endif */
       
      /*
      ** Normally we would only create a new TCP session if the first packet 
      ** of the session is a SYN packet. We will create a session and forward 
      ** the packet anyway, and the receiver will send a RST back, which we 
      ** will forward to the originator. 
      */
      tcp_flags = ntohs(transport.TCP_PTR->flags);
      reset = ((ip_protocol == IPPROTO_TCP) && (!(tcp_flags & SYN) || (tcp_flags & ACK)));

      /* Create a new session if necessary and save information */
      nat_session_ptr = NAT_insert(ip_header_ptr, &error);
      if (nat_session_ptr == NULL) {
         nat_cfg_ptr->STATS.ST_PACKETS_PRV_PUB_ERR++;        
         return error;
      } /* Endif */

   } /* Endif */
   
   /* Modify the transport level header */   
   switch (ip_protocol) {
      case IPPROTO_TCP:
      case IPPROTO_UDP:
         NAT_mod_tcpudp(transport, nat_session_ptr, !source_is_private, reset);
         break;
         
      case IPPROTO_ICMP:
         dest_is_local = FALSE;
         error = NAT_mod_icmp(ip_header_ptr, &nat_session_ptr, !source_is_private, &dest_is_local);
         
         if (dest_is_local) {  /* ICMP Error meant for NAT router */
            nat_cfg_ptr->STATS.ST_PACKETS_BYPASS++;
            return RTCS_OK;
         } /* Endif */
         
         if (error) {   /* Can only happen with ICMP error packets */
            nat_cfg_ptr->STATS.ST_PACKETS_PRV_PUB_ERR++;
            return error;
         } /* Endif */
         break;
         
      default:    /* Can never get here */
         break;
   } /* Endswitch */
   
   /* Modify the IP header */
   NAT_mod_ip(ip_header_ptr, nat_session_ptr, !source_is_private);
      
   if (source_is_private) {
      nat_cfg_ptr->STATS.ST_PACKETS_PRV_PUB++;
   } else {
      nat_cfg_ptr->STATS.ST_PACKETS_PUB_PRV++;
   }

   return RTCS_OK;   /* Continue routing as normal */
   
} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_chksum_mod
* Returned Value  : New chksum (uint_16)
* Comments        :
*        Takes current chksum and calculates a new one based the data being
*        replaced and on the new data.
*
*END*-----------------------------------------------------------------*/

uint_16 NAT_chksum_mod
   (
      uint_16  oldchk,     /* [IN] The old checksum */
      uint_16  old16,      /* [IN] The old data being replaced */
      uint_16  new16       /* [IN] The new replacement data */
   )
{ /* Body */
  
   uint_32 newchk;

   newchk = oldchk + (0xFFFF - new16) + old16;
   newchk = (newchk >> 16) + (newchk & 0xFFFF);
   newchk = (newchk >> 16) + (newchk & 0xFFFF);
   
   return (uint_16)newchk;
   
} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_mod_ip
* Returned Value  : void
* Comments        :
*     Modifies the IP header 
*
*END*-----------------------------------------------------------------*/

void NAT_mod_ip
   (
      IP_HEADER_PTR              ip_header_ptr,       /* [IN/OUT] IP datagram */
      NAT_SESSION_STRUCT_PTR     nat_session_ptr,     /* [IN]     NAT session */
      boolean                    pub_to_prv           /* [IN]     Direction   */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   uint_16                 checksum_mod;
   _ip_address             new_ip_addr, old_ip_addr;
   uchar_ptr               replacement_ptr;
   
   if (pub_to_prv) { /* reply */
      new_ip_addr = nat_session_ptr->PRV_HST;
      old_ip_addr = nat_session_ptr->NAT_HST;
      replacement_ptr = ip_header_ptr->DEST;
   } else { /* request */
      new_ip_addr = nat_session_ptr->NAT_HST; 
      old_ip_addr = nat_session_ptr->PRV_HST; 
      replacement_ptr = ip_header_ptr->SOURCE; 
   } /* Endif */
   
   checksum_mod = ntohs(ip_header_ptr->CHECKSUM);
   
   checksum_mod = NAT_chksum_mod(checksum_mod,   /* old chksum */
      (uint_16)(old_ip_addr & 0xFFFF),           /* old data */
      (uint_16)(new_ip_addr & 0xFFFF));          /* new data */

   checksum_mod = NAT_chksum_mod(checksum_mod,   /* old chksum */
      (uint_16)((old_ip_addr >> 16) & 0xFFFF),   /* old data */
      (uint_16)((new_ip_addr >> 16) & 0xFFFF));  /* new data */
  
   htonl(replacement_ptr, new_ip_addr);    
   htons(ip_header_ptr->CHECKSUM, checksum_mod);
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_mod_tcpudp
* Returned Value  : void
* Comments        :
*     Modifies the TCP/UDP header 
*
*END*-----------------------------------------------------------------*/

void NAT_mod_tcpudp
   (
      TRANSPORT_UNION         transport,    /* [IN/OUT] Transport protocol header */ 
      NAT_SESSION_STRUCT_PTR  nat_session_ptr,  /* [IN] The session struct            */
      boolean                 pub_prv,  /* [IN] Direction of packet           */
      boolean                 finrst    /* [IN] Will it go on the FINRST Q?   */
   )
{ /* Body */
   TCPIP_EVENT_PTR      event_ptr;
   NAT_CFG_STRUCT_PTR   nat_cfg_ptr = RTCS_getcfg(NAT);
   uchar_ptr            chksum_ptr, port_ptr;
   _ip_address          new_ip_addr, old_ip_addr;
   uint_32              timeout;
   uint_16              tcp_flags, new_port, old_port, orig;
   uint_16              checksum_mod;
 
   

   /* Read checksum and prepare timeouts */
   if (nat_session_ptr->IP_PROT == IPPROTO_TCP) {

      chksum_ptr = transport.TCP_PTR->checksum;
      /* Check if the packet is a FIN or RST packet */
      tcp_flags = ntohs(transport.TCP_PTR->flags);
      if (finrst || ((tcp_flags & RST) || (tcp_flags & FIN))) {
         /* Use the FIN timeout queue because a FIN or RST was detected */
         event_ptr = &nat_cfg_ptr->FIN_TOUT;
         timeout = nat_cfg_ptr->TIMEOUT_FIN;
      } else { 
         event_ptr = &nat_cfg_ptr->TCP_TOUT;
         timeout = nat_cfg_ptr->TIMEOUT_TCP;
      } /* Endif */
   } else { 
      chksum_ptr = transport.UDP_PTR->CHECKSUM;
      event_ptr = &nat_cfg_ptr->UDP_TOUT;
      timeout = nat_cfg_ptr->TIMEOUT_UDP;
   } /* Endif */
       
   if (pub_prv) { /* reply */
      new_ip_addr = nat_session_ptr->PRV_HST;
      old_ip_addr = nat_session_ptr->NAT_HST;
      new_port = nat_session_ptr->PRV_PORT;
      old_port = nat_session_ptr->NAT_PORT;
      port_ptr = transport.TCP_PTR->dest_port;   
   } else { /* request */
      new_ip_addr = nat_session_ptr->NAT_HST;
      old_ip_addr = nat_session_ptr->PRV_HST;
      new_port = nat_session_ptr->NAT_PORT;
      old_port = nat_session_ptr->PRV_PORT;
      nat_cfg_ptr->GLOBAL_PORT = old_port;
      port_ptr = transport.TCP_PTR->source_port;
   } /* Endif */
   
   /* Modify header and adjust checksum */
   orig = ntohs(chksum_ptr);
   checksum_mod = NAT_chksum_mod(orig,          /* old chksum */
      (uint_16)(old_ip_addr & 0xFFFF),           /* old data */
      (uint_16)(new_ip_addr & 0xFFFF));          /* new data */

   checksum_mod = NAT_chksum_mod(checksum_mod,         /* old chksum */
      (uint_16)((old_ip_addr >> 16) & 0xFFFF),   /* old data */
      (uint_16)((new_ip_addr >> 16) & 0xFFFF));  /* new data */
      
   checksum_mod = NAT_chksum_mod(checksum_mod, old_port, new_port);
   htons(port_ptr, new_port);
      
   
   /* Write final checksum */
   if (orig || nat_session_ptr->IP_PROT != IPPROTO_UDP) {
      htons(chksum_ptr, checksum_mod);
   } /* Endif */
   
   
   /* Reset timeouts */
   NAT_event_del(&nat_session_ptr->TIMEOUT); 
   nat_session_ptr->TIMEOUT.TIME = timeout;
   NAT_event_add(event_ptr, &nat_session_ptr->TIMEOUT);
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_mod_icmp
* Returned Value  : RTCS_OK or uint_32 error code 
* Comments        :
*     Modifies the ICMP header 
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_mod_icmp
   (
      IP_HEADER_PTR                 ip_header_ptr,          /* [IN/OUT] IP datagram       */
      NAT_SESSION_STRUCT_PTR _PTR_  nat_session_ptr_ptr,    /* [IN]     NAT session       */
      boolean                       pub_to_prv,             /* [IN]     Direction         */
      boolean _PTR_                 islocal                 /* [OUT] DEST is NAT router?  */
   )
{ /* Body */
   NAT_SESSION_STRUCT_PTR  nat_session_ptr = *nat_session_ptr_ptr;
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   IP_HEADER_PTR           embedded_ip_header_ptr;
   TRANSPORT_UNION         transport, embedded_transport;
   uchar_ptr               embedded_checksum_ptr = NULL, port_ptr, replacement_ptr;
   _ip_address             new_ip, old_ip;
   boolean                 icmpicmp = FALSE;
   uint_16                 checksum, embedded_checksum, data_len, new_port, old_port;
   uint_16                 checksum_mod;
   uchar                   embedded_ip_protocol;
   uint_32                 error;

   transport.PTR = TRANSPORT_PTR(ip_header_ptr);

   checksum = ntohs(transport.ICMP_PTR->CHECKSUM);
   
   switch (ntohc(transport.ICMP_PTR->TYPE)) {
      case ICMPTYPE_DESTUNREACH:    
      case ICMPTYPE_SRCQUENCH:      /* In all of these cases there is  */
      case ICMPTYPE_TIMEEXCEED:     /* an embedded IP header to modify */
      case ICMPTYPE_PARMPROB:       
         
         /* Calcute data length after embedded IP header */
         embedded_ip_header_ptr = &transport.ERR_PTR->IP;
         embedded_transport.PTR = TRANSPORT_PTR(embedded_ip_header_ptr);

         data_len = ntohs(ip_header_ptr->LENGTH);
         data_len -= (uint_16)((uchar_ptr)embedded_ip_header_ptr - (uchar_ptr)ip_header_ptr);
         data_len -= (uint_16)IPH_LEN(embedded_ip_header_ptr);
         
         embedded_ip_protocol = ntohc(embedded_ip_header_ptr->PROTOCOL);
         
         /* Make sure size is long enough for a lookup */ 
         if ((data_len < 4) || ((data_len < 8) && (embedded_ip_protocol == IPPROTO_ICMP))) {
            return RTCSERR_NAT_NO_SESSION;         
         } /* Endif */        

         /* Try to find the corresponding session struct */
         nat_session_ptr = NAT_lookup(embedded_ip_header_ptr, TRUE, FALSE, &error);
         *nat_session_ptr_ptr=nat_session_ptr;
         
         if (nat_session_ptr == NULL) {
            if (pub_to_prv) {    /* Destination might be NAT router */
               *islocal = TRUE;
               return RTCS_OK;
            } else {             /* Cant find a session, silently discard */
               return RTCSERR_NAT_NO_SESSION;
            } /* Endif */
         } /* Endif */
         
         switch(embedded_ip_protocol) { 
            case IPPROTO_TCP:
               /* ICMP errors don't always contain the whole transport header */
               if (data_len >= 18) {
                  embedded_checksum_ptr = embedded_transport.TCP_PTR->checksum;
               } /* Endif */
               break;
               
            case IPPROTO_UDP:
               if (data_len >= 8 && ntohs(embedded_transport.UDP_PTR->CHECKSUM)) {
                  embedded_checksum_ptr = embedded_transport.UDP_PTR->CHECKSUM;
               } /* Endif */
               break;
               
            case IPPROTO_ICMP:
               embedded_checksum_ptr = embedded_transport.ICMP_PTR->CHECKSUM;
               icmpicmp = TRUE;
               break;
               
            default:
               /* Should never get here */
               return RTCSERR_NAT_UNSUPPORTED_PROTOCOL;
         } /* Endswitch */

         /* The error is in response to a packet going in opposite direction */
         if (pub_to_prv) {
            new_ip = nat_session_ptr->PRV_HST;
            old_ip = nat_session_ptr->NAT_HST;
            replacement_ptr = embedded_ip_header_ptr->SOURCE;
            new_port = nat_session_ptr->PRV_PORT;
            old_port = nat_session_ptr->NAT_PORT;
            port_ptr = embedded_transport.TCP_PTR->source_port;
         } else { 
            new_ip = nat_session_ptr->NAT_HST;
            old_ip = nat_session_ptr->PRV_HST;
            replacement_ptr = embedded_ip_header_ptr->DEST;
            new_port = nat_session_ptr->NAT_PORT;
            old_port = nat_session_ptr->PRV_PORT;
            port_ptr = embedded_transport.TCP_PTR->dest_port;   
         } /* Endif */ 
         
         if (icmpicmp) {
            port_ptr = embedded_transport.ECHO_PTR->SEQ;
         } /* Endif */
         
         if (embedded_checksum_ptr) {
            embedded_checksum = ntohs(embedded_checksum_ptr);

            if (!icmpicmp) {
               /* Modify header and adjust checksum */
               embedded_checksum = NAT_chksum_mod(embedded_checksum,     /* old chksum */
                  (uint_16)(old_ip & 0xFFFF),           /* old data */
                  (uint_16)(new_ip & 0xFFFF));          /* new data */

               embedded_checksum = NAT_chksum_mod(embedded_checksum,     /* old chksum */
                  (uint_16)((old_ip >> 16) & 0xFFFF),   /* old data */
                  (uint_16)((new_ip >> 16) & 0xFFFF));  /* new data */
            } /* Endif */

            embedded_checksum = NAT_chksum_mod(embedded_checksum, old_port, new_port);
            checksum = NAT_chksum_mod(checksum, ntohs(embedded_checksum_ptr), embedded_checksum);
            htons(embedded_checksum_ptr, embedded_checksum);
         } else {
            embedded_checksum = 0;
         } /* Endif */
         
         
         checksum = NAT_chksum_mod(checksum, old_port, new_port);         
         
         /* Write new port number */
         htons(port_ptr, new_port);
            
         checksum_mod = ntohs(embedded_ip_header_ptr->CHECKSUM);
         
         checksum_mod = NAT_chksum_mod(checksum_mod,           /* old chksum */
            (uint_16)(old_ip & 0xFFFF),           /* old data */
            (uint_16)(new_ip & 0xFFFF));          /* new data */
         
         checksum_mod = NAT_chksum_mod(checksum_mod,           /* old chksum */
            (uint_16)((old_ip >> 16) & 0xFFFF),   /* old data */
            (uint_16)((new_ip >> 16) & 0xFFFF));  /* new data */
        
         htonl(replacement_ptr, new_ip);    
         htons(embedded_ip_header_ptr->CHECKSUM, checksum_mod);

         break;
         
      default:       
         /* Modify Query SEQ */
         if (pub_to_prv) {
            checksum = NAT_chksum_mod(checksum, nat_session_ptr->NAT_PORT, 
               nat_session_ptr->PRV_PORT);
            htons(transport.ECHO_PTR->SEQ, nat_session_ptr->PRV_PORT);
         } else { 
            checksum = NAT_chksum_mod(checksum, nat_session_ptr->PRV_PORT, 
               nat_session_ptr->NAT_PORT);
            htons(transport.ECHO_PTR->SEQ, nat_session_ptr->NAT_PORT);
         } /* Endif */
         
         /* Reset timeouts */
         NAT_event_del(&nat_session_ptr->TIMEOUT); 
         nat_cfg_ptr = RTCS_getcfg(NAT);
         
            nat_session_ptr->TIMEOUT.TIME = nat_cfg_ptr->TIMEOUT_ICMP;
            NAT_event_add(&nat_cfg_ptr->ICMP_TOUT, &nat_session_ptr->TIMEOUT);
         
         break;
   } /* Endswitch */
   
   /* Rewrite the checksum */
   htons(transport.ICMP_PTR->CHECKSUM, checksum);
   
   return RTCS_OK;
} /* Endbody */     

#endif
 
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/ehci/ehci_intr.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_intr.c$
* $Version : 3.8.14.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the low-level Host API functions specific to the VUSB 
*   chip for interrupt transfer
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "hostapi.h"
#include "ehci_prv.h"

#include "ehci_bw.h"
#include "ehci_main.h"
#include "ehci_intr.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_add_interrupt_xfer_to_periodic_list
*  Returned Value : None
*  Comments       :
*        Queue the transfer in the EHCI hardware Periodic schedule list
*END*-----------------------------------------------------------------*/
uint_32 _usb_ehci_add_interrupt_xfer_to_periodic_list
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR             pipe_descr_ptr,
      
      /* [IN] the transfer parameters struct */
      EHCI_TR_STRUCT_PTR               pipe_tr_ptr
   )
{ /* Body */
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   VUSB20_REG_STRUCT_PTR                        dev_ptr;
   ACTIVE_QH_MGMT_STRUCT_PTR                    active_list_member_ptr, temp_list_ptr;

   EHCI_QH_STRUCT_PTR                           QH_ptr = NULL;
   EHCI_QH_STRUCT_PTR                           prev_QH_ptr = NULL;
   EHCI_QTD_STRUCT_PTR                          first_QTD_ptr, temp_QTD_ptr;
   PIPE_STRUCT_PTR                              pipe_for_queue = NULL;
   uint_32                                      cmd_val,sts_val;
   uint_32                                      H_bit = 1;
   uint_32                                      interrupt_sched_mask = 1;
   boolean                                      init_periodic_list = FALSE;
   boolean                                      found_existing_q_head = FALSE;

   /* QH initialization fields */
   uint_32                       control_ep_flag = 0;
   uint_32                       split_completion_mask = 1;
   uint_32                       data_toggle_control = 0, item_type = 0;
   uint_8                        mult = 0, period = 0;
   uint_32_ptr                   temp_frame_list_ptr = NULL;


   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;
   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->G.DEV_PTR;

   /****************************************************************************
   QTD MAKING    
   ****************************************************************************/

   /* Initialize the QTDs for the Queue Head */
   first_QTD_ptr = (EHCI_QTD_STRUCT_PTR)_usb_ehci_init_Q_element(
                                          handle,pipe_descr_ptr, pipe_tr_ptr
                                          );

#ifdef DEBUG_INFO
      {
         uint_32 token = EHCI_MEM_READ(first_QTD_ptr->TOKEN);
         
         printf("QTD queued Top QTD Token=%x\n"
            "   Status=%x,PID code=%x,error code=%x,page=%x,IOC=%x,Bytes=%x,Toggle=%x\n",
          token
          (token&0xFF),
          (token >> 8)&0x3,
          (token >> 10) &0x3,
          (token >> 12)&0x7,
          (token >> 15)&0x1,
          (token >> 16)&0x7FFF,
          (token&EHCI_QTD_DATA_TOGGLE) >>31);
      }
#endif


   /****************************************************************************
   Obtain the QH for this pipe
   ****************************************************************************/
   QH_ptr = (EHCI_QH_STRUCT_PTR) pipe_descr_ptr->QH_FOR_THIS_PIPE;
   

   /****************************************************************************
   Ensure that this QH is in the list of active QHs for interrupt pipe
   ****************************************************************************/

   /******************************************************************
   If active list does not exist, we make a new list and this is the
   first member of the list. Otherwise we append the list at the end.
   *******************************************************************/
   if(usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR == NULL)
   {

      active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR)USB_mem_alloc_zero(sizeof(ACTIVE_QH_MGMT_STRUCT));

      if (!active_list_member_ptr) 
      {
         return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
      }

      _mem_set_type((pointer)active_list_member_ptr, MEM_TYPE_USB_INTR_TMP_BUFF);
      usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR = active_list_member_ptr;

      /****************************************************************
      Connect the QH with the active list
      ****************************************************************/
      active_list_member_ptr->QH_PTR = (EHCI_QH_STRUCT_PTR)QH_ptr;
      active_list_member_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR)first_QTD_ptr;

      /****************************************************************
      Connect the QH with the QTD
      ****************************************************************/
      EHCI_MEM_WRITE(QH_ptr->ALT_NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
      EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,(uint_32)first_QTD_ptr);

   }
   else
   {

      /****************************************************************
      search the list to find if this QH aleady exists in the list. If
      not, allocate a new list member and add to the list or else move
      on with no action.
      ****************************************************************/
      
      temp_list_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \
                        usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR;
                        

       while (temp_list_ptr!=NULL) {
         if(temp_list_ptr->QH_PTR == QH_ptr) 
         {
            found_existing_q_head = TRUE;
            break;
         }
         if (temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR == NULL)
            break;
         
         temp_list_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
      }

      if (temp_list_ptr==NULL) {
         return USB_log_error(__FILE__,__LINE__,USBERR_ERROR);
      }
   

      /****************************************************************
      If no QH not found a new list memeber or connect QTDs to the existing one
      ****************************************************************/

         
      if(!found_existing_q_head)
      {
   
         active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR)USB_mem_alloc_zero(sizeof(ACTIVE_QH_MGMT_STRUCT));

         if (!active_list_member_ptr) 
         {
            return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
         }

         _mem_set_type((pointer)active_list_member_ptr, MEM_TYPE_USB_INTR_TMP_BUFF);
         temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR = active_list_member_ptr;

         /****************************************************************
         Connect the QH with the active list
         ****************************************************************/
         active_list_member_ptr->QH_PTR = (EHCI_QH_STRUCT_PTR)QH_ptr;
         active_list_member_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR)first_QTD_ptr;

         /****************************************************************
         Connect the QH with the QTD
         ****************************************************************/
         EHCI_MEM_WRITE(QH_ptr->ALT_NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
         EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,(uint_32)first_QTD_ptr);

      }
      else
      {
         /****************************************************************
         update the active interrupt list now.
         ****************************************************************/
         temp_QTD_ptr = (EHCI_QTD_STRUCT_PTR)temp_list_ptr->FIRST_QTD_PTR;
      
         if (( ((uint_32)temp_QTD_ptr) & EHCI_QTD_T_BIT) || (temp_QTD_ptr == NULL)) {
            temp_list_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR)first_QTD_ptr;
         } else {
            while (!(EHCI_MEM_READ(temp_QTD_ptr->NEXT_QTD_PTR) & EHCI_QTD_T_BIT)) {
               temp_QTD_ptr = (EHCI_QTD_STRUCT_PTR)EHCI_MEM_READ(temp_QTD_ptr->NEXT_QTD_PTR);
            }

            EHCI_MEM_WRITE(temp_QTD_ptr->NEXT_QTD_PTR,(uint_32)first_QTD_ptr);

         } /*else*/

         /****************************************************************
         This case is arrived when the QH is active and there is a 
         possibility that it may also have active QTDs.
         ****************************************************************/
         if (EHCI_MEM_READ(QH_ptr->NEXT_QTD_LINK_PTR) & EHCI_QTD_T_BIT) {
            EHCI_MEM_WRITE(QH_ptr->ALT_NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
            EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,(uint_32)first_QTD_ptr);
          }
          
         
       
      }/*else*/
   
   } /*else */

#ifdef DEBUG_INFO
   { 
      uint_32 token = EHCI_MEM_READ(first_QTD_ptr->TOKEN);
      printf("_usb_ehci_add_interrupt_xfer_to_periodic_list: QH =%x\n"
             "  Status=%x,PID code=%x,error code=%x,page=%x,IOC=%x,Bytes=%x,Toggle=%x\n",
             token,
             (token&0xFF),
             (token >> 8)&0x3,
             (token >> 10) &0x3,
             (token >> 12)&0x7,
             (token >> 15)&0x1,
             (token>> 16)&0x7FFF,
             (token)&EHCI_QTD_DATA_TOGGLE) >>31);
   }
#endif


   /****************************************************************************
   if periodic schedule is not already enabled, enable it.
   ****************************************************************************/
   sts_val = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS);

   if(!(sts_val & EHCI_STS_PERIODIC_SCHEDULE))
   {

         cmd_val = EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD);

      /****************************************************************************
      write the address of the periodic list in to the periodic base register
      ****************************************************************************/
         EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.PERIODIC_LIST_BASE_ADDR, 
                        (uint_32) usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR);

      /****************************************************************************
      wait until we can enable  the periodic schedule.
      ****************************************************************************/
         while ((cmd_val & EHCI_USBCMD_PERIODIC_SCHED_ENABLE) !=
                (EHCI_REG_READ(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_STS) & EHCI_STS_PERIODIC_SCHEDULE)) {
      }
         

      /****************************************************************************
      enable the schedule now.
      ****************************************************************************/
            
      EHCI_REG_WRITE(dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD,(cmd_val | EHCI_USBCMD_PERIODIC_SCHED_ENABLE)); 
   }
   return USB_OK;

} /* EndBody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_ehci_close_interrupt_pipe
*  Returned Value : None
*  Comments       :
*        Close the Interrupt pipe and update the bandwidth list.
Here are the notes. In EHCI, closing an interrupt pipe involves removing
the queue head from the periodic list to make sure that none of the
frames refer to this queue head any more. It is also important to remember
that we must start removing the queue head link from a safe place which
is not currently being executed by EHCi controller. Apart from this we
should free all QTDs associated with it and QH Managements structure.
*END*-----------------------------------------------------------------*/

void _usb_ehci_close_interrupt_pipe (

      /* [IN] the USB Host state structure */
      _usb_host_handle                 handle,

      /* The pipe descriptor to queue */            
      EHCI_PIPE_STRUCT_PTR             pipe_descr_ptr

)
{
   USB_EHCI_HOST_STATE_STRUCT_PTR               usb_host_ptr;
   EHCI_QH_STRUCT_PTR                           QH_ptr,temp_QH_ptr;
   ACTIVE_QH_MGMT_STRUCT_PTR                    active_list_member_ptr;
   ACTIVE_QH_MGMT_STRUCT_PTR                    temp_active_list_member_ptr,prev_active_list_member_ptr;
   EHCI_QTD_STRUCT_PTR                          QTD_ptr, temp_QTD_ptr;
   uint_8_ptr                                   frame_list_bw_ptr;
   USB_Uncached uint_32 _PTR_                   periodic_list_base_ptr;
   USB_Uncached uint_32 _PTR_                   transfer_data_struct_ptr;
   USB_Uncached uint_32 _PTR_                   prev_transfer_data_struct_ptr;
   EHCI_ITD_STRUCT_PTR                          ITD_ptr;
   EHCI_SITD_STRUCT_PTR                         SITD_ptr;
   EHCI_FSTN_STRUCT_PTR                         FSTN_ptr;
   int                                          i;
   boolean                                      unlinked;
   uint_32                                      frame_list_size, interval, frame_number;
   
   usb_host_ptr = (USB_EHCI_HOST_STATE_STRUCT_PTR)handle;

   /****************************************************************************
   Obtain the QH for this pipe
   ****************************************************************************/
   QH_ptr = (EHCI_QH_STRUCT_PTR) pipe_descr_ptr->QH_FOR_THIS_PIPE;

   if(QH_ptr == NULL) return;
   
      
   /****************************************************************************
   First Search the periodic list and unlink this QH from the list.
   ****************************************************************************/
   
   frame_list_bw_ptr       = usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR;   
   periodic_list_base_ptr  = (USB_Uncached uint_32 _PTR_)(usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR);
   
   /*******************************************************************
   Start from fram 0 till end of the list and unlink the QH if found. Note
   that we should not unlink when the QH is active but current code does
   not take this in account.
   ********************************************************************/

   /* Get frame list size and interval */
   if( pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) {
      frame_list_size = usb_host_ptr->FRAME_LIST_SIZE * 8;
   } 
   else {
      frame_list_size = usb_host_ptr->FRAME_LIST_SIZE;
   }
   interval = pipe_descr_ptr->G.INTERVAL;
   
   for (i = 0; i < frame_list_size; i += interval) {
      if (pipe_descr_ptr->G.SPEED == USB_SPEED_HIGH) {
         frame_number = i / 8;
      }
      else {
         frame_number = i;
      }
      
      transfer_data_struct_ptr = (USB_Uncached uint_32 _PTR_) periodic_list_base_ptr + frame_number;
      prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
      unlinked = FALSE;

      /* updates the bandwidth list with released time */
      reclaim_band_width(
                        handle,
                        (uint_32)i,
                        (USB_Uncached uint_32 _PTR_) transfer_data_struct_ptr,
                        pipe_descr_ptr);

      /*******************************************************************
      Traverse the frame i and unlink the QH if found in it.
      ********************************************************************/
      while ((transfer_data_struct_ptr)
             && (!(EHCI_MEM_READ(*transfer_data_struct_ptr) & EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT))
              && (unlinked == FALSE)) {

         switch (EHCI_GET_TYPE(transfer_data_struct_ptr))
         {
            case EHCI_ELEMENT_TYPE_ITD:
               ITD_ptr = (EHCI_ITD_STRUCT_PTR)(EHCI_MEM_READ(*transfer_data_struct_ptr)& EHCI_HORIZ_PHY_ADDRESS_MASK);
               prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
               transfer_data_struct_ptr = (pointer) (EHCI_MEM_READ(ITD_ptr->NEXT_LINK_PTR) & EHCI_HORIZ_PHY_ADDRESS_MASK);
               break;
            case EHCI_ELEMENT_TYPE_QH:

               temp_QH_ptr = (EHCI_QH_STRUCT_PTR)(EHCI_MEM_READ(*transfer_data_struct_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK);

                                                   
               if(temp_QH_ptr ==  QH_ptr) 
               {
                  /*************************************************************
                  Unlink this QH now.                  
                  *************************************************************/
                  USB_lock();
                  unlink_periodic_data_structure_from_frame (
                                 (USB_Uncached uint_32 _PTR_) prev_transfer_data_struct_ptr,
                                 (USB_Uncached uint_32 _PTR_) transfer_data_struct_ptr);
                  USB_unlock();
                  /*exit out of loop since there can be only 1 QH of same pipe in this frame */
                  unlinked = TRUE;
               }
               prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
               transfer_data_struct_ptr = (pointer) (EHCI_MEM_READ(temp_QH_ptr->HORIZ_LINK_PTR) & EHCI_HORIZ_PHY_ADDRESS_MASK);
               break;
            case EHCI_ELEMENT_TYPE_SITD:
               SITD_ptr = (EHCI_SITD_STRUCT_PTR)(EHCI_MEM_READ(*transfer_data_struct_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK);
               prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
               transfer_data_struct_ptr = (pointer) (EHCI_MEM_READ(SITD_ptr->NEXT_LINK_PTR) & EHCI_HORIZ_PHY_ADDRESS_MASK);
               break;
            case EHCI_ELEMENT_TYPE_FSTN:
               FSTN_ptr = (EHCI_FSTN_STRUCT_PTR)(EHCI_MEM_READ(*transfer_data_struct_ptr) &  EHCI_HORIZ_PHY_ADDRESS_MASK);
               prev_transfer_data_struct_ptr = transfer_data_struct_ptr;
               transfer_data_struct_ptr = (pointer) (EHCI_MEM_READ(FSTN_ptr->NORMAL_PATH_LINK_PTR)  & EHCI_HORIZ_PHY_ADDRESS_MASK);
               break;
            default:
               break;
         } /* EndSwitch */

      } /*while */

   }  /* for */
   

   
   /****************************************************************************
   Search the list of active interrupt transfers to find if this QH aleady exists
   in the list. If it exists we should free QH and all QTD associated with it.
   **************************************************************************/
      
   active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) 
                             usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR;
                             
   /*point to itself to start with */                             
   prev_active_list_member_ptr = active_list_member_ptr;
   
   /*count the number of elements in the list, if None, set the list to NULL*/
   i=0;                            
                        
   while (active_list_member_ptr)
   {
      if(active_list_member_ptr->QH_PTR == QH_ptr) 
      {

         /* don't want to get interrupted when changing the QTD and QH list */
         USB_lock();
         /***********************************************
         Do the freeing stuff         
         disable this QH so that there are no more QTDs executed.
         ***********************************************************/
         EHCI_MEM_WRITE(QH_ptr->NEXT_QTD_LINK_PTR,EHCI_QTD_T_BIT);
         
         /***********************************************
         free all the QTDs if any.
         ************************************************/
         QTD_ptr = active_list_member_ptr->FIRST_QTD_PTR;
         while (((!((uint_32)QTD_ptr) & EHCI_QTD_T_BIT)) &&  (QTD_ptr != NULL)) { 
            temp_QTD_ptr = QTD_ptr;
            QTD_ptr = (EHCI_QTD_STRUCT_PTR)EHCI_MEM_READ(QTD_ptr->NEXT_QTD_PTR);
           _usb_ehci_free_QTD(handle, (pointer)temp_QTD_ptr);
         }

         /*free QH */
         _usb_ehci_free_QH(handle, (pointer) QH_ptr);
         QH_ptr=NULL;
         /*ensure that all pointers are NULL in this structure */
         active_list_member_ptr->QH_PTR = NULL;
         active_list_member_ptr->FIRST_QTD_PTR = NULL;
         
         /* store the pointer temporarily before freeing it */
         temp_active_list_member_ptr = active_list_member_ptr;
         
         /* move on to the next member of the list */
         active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \
                                   active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;

         /*connect previous to next */
         ((ACTIVE_QH_MGMT_STRUCT_PTR)prev_active_list_member_ptr)->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR = active_list_member_ptr;

         /* we should free this ACTIVE Q MGMT structure */
         USB_mem_free(temp_active_list_member_ptr);                   
         
         USB_unlock();
         break;
      }
      else 
      {
         prev_active_list_member_ptr = active_list_member_ptr;
         active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \
                                   active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
         i++;                                   
      }
      
   }
   
   if(i == 0) /* if list is empty make sure to initialize the pointer */ 
   {
      usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR = NULL;
   }

   if (QH_ptr != NULL) {
      _usb_ehci_free_QH(handle, (pointer) QH_ptr);
   }
   
   return;

}


 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_supp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_supp.c$
* $Version : 3.8.11.0$
* $Date    : Sep-24-2012$
*
* Comments:
*   This file contains the support functions for byte/word and others 
*   manipulations.
*
*END************************************************************************/

#include "mqx_inc.h"

#ifdef __CODEWARRIOR__

asm uint_16 _psp_swap2byte(uint_16 n) {
	rev16 r0, r0
	bx lr
}

asm uint_32 _psp_swap4byte(uint_32 n) {
	rev r0, r0
	bx lr
}

asm void __set_BASEPRI(uint_32 basePri) {
    msr basepri, r0
    bx lr
}

#elif defined(__GNUC__) /* gcc */


/*FUNCTION*-------------------------------------------------------------------
 * 
 * Function Name    : _psp_swap2byte
 * Returned Value   : uint_16
 * Comments         : Swap 2 bytes
 *   ticks
 *
 *END*----------------------------------------------------------------------*/
 
uint_16 _psp_swap2byte(uint_16 n)
{ /* Body */
    uchar temp[2];

    temp[1] = *((uchar *)&n);
    temp[0] = ((uchar *)&n)[1];
    return (*(uint_16 *)temp);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
 * 
 * Function Name    : _psp_swap4byte
 * Returned Value   : uint_32
 * Comments         : Swap 4 bytes
 *   ticks
 *
 *END*----------------------------------------------------------------------*/
 
uint_32 _psp_swap4byte(uint_32 n)
{ /* Body */
    uchar temp[4];

    temp[3] = *((uchar *)&n);
    temp[2] = ((uchar *)&n)[1];
    temp[1] = ((uchar *)&n)[2];
    temp[0] = ((uchar *)&n)[3];
    return (*(uint_32 *)temp);
} /* Endbody */

#elif defined(__CC_ARM) /* Keil */

__asm void __set_BASEPRI(uint_32 basePri)   
{   
  msr basepri, r0   
  bx lr   
}   

/*FUNCTION*-------------------------------------------------------------------
 * 
 * Function Name    : _psp_swap2byte
 * Returned Value   : uint_16
 * Comments         : Swap 2 bytes
 *   ticks
 *
 *END*----------------------------------------------------------------------*/
 
uint_16 _psp_swap2byte(uint_16 n)
{ /* Body */
    uchar temp[2];

    temp[1] = *((uchar *)&n);
    temp[0] = ((uchar *)&n)[1];
    return (*(uint_16 *)temp);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
 * 
 * Function Name    : _psp_swap4byte
 * Returned Value   : uint_32
 * Comments         : Swap 4 bytes
 *   ticks
 *
 *END*----------------------------------------------------------------------*/
 
uint_32 _psp_swap4byte(uint_32 n)
{ /* Body */
    uchar temp[4];

    temp[3] = *((uchar *)&n);
    temp[2] = ((uchar *)&n)[1];
    temp[1] = ((uchar *)&n)[2];
    temp[0] = ((uchar *)&n)[3];
    return (*(uint_32 *)temp);
} /* Endbody */

#elif defined(__ICCARM__)

/* IAR EWARM library contains all needed code */

#else /* __CODEWARRIOR__, __ICCARM__ */

/*FUNCTION*-------------------------------------------------------------------
 * 
 * Function Name    : _psp_swap2byte
 * Returned Value   : uint_16
 * Comments         : Swap 2 bytes
 *   ticks
 *
 *END*----------------------------------------------------------------------*/
 
uint_16 _psp_swap2byte(uint_16 n)
{ /* Body */
    uchar temp[2];

    temp[1] = *((uchar *)&n);
    temp[0] = ((uchar *)&n)[1];
    return (*(uint_16 *)temp);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
 * 
 * Function Name    : _psp_swap4byte
 * Returned Value   : uint_32
 * Comments         : Swap 4 bytes
 *   ticks
 *
 *END*----------------------------------------------------------------------*/
 
uint_32 _psp_swap4byte(uint_32 n)
{ /* Body */
    uchar temp[4];

    temp[3] = *((uchar *)&n);
    temp[2] = ((uchar *)&n)[1];
    temp[1] = ((uchar *)&n)[2];
    temp[0] = ((uchar *)&n)[3];
    return (*(uint_32 *)temp);
} /* Endbody */

#endif /* __CODE_WARRIOR__, __ICCARM__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/kadc/adc_mk60.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_mk60.h$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END************************************************************************/

#ifndef __adc_mk60_h__
#define __adc_mk60_h__


#define ADC_HAS_16BIT_RESOLUTION           1
#define ADC_HAS_DIFFERENTIAL_CHANNELS      1
#define ADC_HAS_PGA                        1


#define ADC0_SOURCE_ADPM0       (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0) | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_ADPM1       (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1) | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_ADPM2       (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2) | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_ADPM3       (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3) | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_AD0         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0))
#define ADC0_SOURCE_AD1         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1))
#define ADC0_SOURCE_AD2         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2))
#define ADC0_SOURCE_AD3         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3))
#define ADC0_SOURCE_AD4A        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD5A        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD6A        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD7A        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD4B        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD5B        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(5))
#define ADC0_SOURCE_AD6B        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(6))
#define ADC0_SOURCE_AD7B        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(7))
#define ADC0_SOURCE_AD8         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(8))
#define ADC0_SOURCE_AD9         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(9))
#define ADC0_SOURCE_AD10        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(10))
#define ADC0_SOURCE_AD11        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(11))
#define ADC0_SOURCE_AD12        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(12))
#define ADC0_SOURCE_AD13        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(13))
#define ADC0_SOURCE_AD14        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(14))
#define ADC0_SOURCE_AD15        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(15))
#define ADC0_SOURCE_AD16        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(16))
#define ADC0_SOURCE_AD17        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(17))
#define ADC0_SOURCE_AD18        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(18))
#define ADC0_SOURCE_AD19        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(19))
#define ADC0_SOURCE_AD20        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(20))
#define ADC0_SOURCE_AD21        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(21))
#define ADC0_SOURCE_AD22        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(22))
#define ADC0_SOURCE_AD23        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(23))
#define ADC0_SOURCE_AD24        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(24))
#define ADC0_SOURCE_AD25        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(25))
#define ADC0_SOURCE_AD26        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC0_SOURCE_AD27        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(27))
#define ADC0_SOURCE_AD28        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(28))
#define ADC0_SOURCE_AD29        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(29))
#define ADC0_SOURCE_AD30        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(30))



#define ADC0_SOURCE_DAC0            (ADC0_SOURCE_AD23)
#define ADC0_SOURCE_TEMP            (ADC0_SOURCE_AD26)
#define ADC0_SOURCE_TEMP_DIFF       (ADC0_SOURCE_AD26 | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_BANDGAP         (ADC0_SOURCE_AD27)
#define ADC0_SOURCE_BANDGAP_DIFF    (ADC0_SOURCE_AD27 | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_VREFH           (ADC0_SOURCE_AD29)
#define ADC0_SOURCE_VREFH_DIFF      (ADC0_SOURCE_AD29 | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_VREFL           (ADC0_SOURCE_AD30)

#define ADC1_SOURCE_ADPM0       (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0) | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_ADPM1       (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1) | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_ADPM2       (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2) | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_ADPM3       (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3) | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_AD0         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0))
#define ADC1_SOURCE_AD1         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1))
#define ADC1_SOURCE_AD2         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2))
#define ADC1_SOURCE_AD3         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3))
#define ADC1_SOURCE_AD4A        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC1_SOURCE_AD5A        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(5))
#define ADC1_SOURCE_AD6A        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(6))
#define ADC1_SOURCE_AD7A        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(7))
#define ADC1_SOURCE_AD4B        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(4))
#define ADC1_SOURCE_AD5B        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(5))
#define ADC1_SOURCE_AD6B        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(6))
#define ADC1_SOURCE_AD7B        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(7))
#define ADC1_SOURCE_AD8         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(8))
#define ADC1_SOURCE_AD9         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(9))
#define ADC1_SOURCE_AD10        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(10))
#define ADC1_SOURCE_AD11        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(11))
#define ADC1_SOURCE_AD12        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(12))
#define ADC1_SOURCE_AD13        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(13))
#define ADC1_SOURCE_AD14        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(14))
#define ADC1_SOURCE_AD15        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(15))
#define ADC1_SOURCE_AD16        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(16))
#define ADC1_SOURCE_AD17        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(17))
#define ADC1_SOURCE_AD18        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(18))
#define ADC1_SOURCE_AD19        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(19))
#define ADC1_SOURCE_AD20        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(20))
#define ADC1_SOURCE_AD21        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(21))
#define ADC1_SOURCE_AD22        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(22))
#define ADC1_SOURCE_AD23        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(23))
#define ADC1_SOURCE_AD24        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(24))
#define ADC1_SOURCE_AD25        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(25))
#define ADC1_SOURCE_AD26        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC1_SOURCE_AD27        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(27))
#define ADC1_SOURCE_AD28        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC1_SOURCE_AD29        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(29))
#define ADC1_SOURCE_AD30        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(30))

#define ADC1_SOURCE_VREF            (ADC1_SOURCE_AD18)

#define ADC1_SOURCE_DAC1            (ADC1_SOURCE_AD23)
#define ADC1_SOURCE_TEMP            (ADC1_SOURCE_AD26)
#define ADC1_SOURCE_TEMP_DIFF       (ADC1_SOURCE_AD26 | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_BANDGAP         (ADC1_SOURCE_AD27)
#define ADC1_SOURCE_BANDGAP_DIFF    (ADC1_SOURCE_AD27 | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_VREFH           (ADC1_SOURCE_AD29)
#define ADC1_SOURCE_VREFH_DIFF      (ADC1_SOURCE_AD29 | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_VREFL           (ADC1_SOURCE_AD30)

#if BSP_TWR_K60F120M
#define ADC2_SOURCE_ADPM0       (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0) | ADC_SOURCE_DIFF)
#define ADC2_SOURCE_ADPM1       (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1) | ADC_SOURCE_DIFF)
#define ADC2_SOURCE_ADPM2       (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2) | ADC_SOURCE_DIFF)
#define ADC2_SOURCE_ADPM3       (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3) | ADC_SOURCE_DIFF)
#define ADC2_SOURCE_AD0         (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0))
#define ADC2_SOURCE_AD1         (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1))
#define ADC2_SOURCE_AD2         (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2))
#define ADC2_SOURCE_AD3         (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3))
#define ADC2_SOURCE_AD4A        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC2_SOURCE_AD5A        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(5))
#define ADC2_SOURCE_AD6A        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(6))
#define ADC2_SOURCE_AD7A        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(7))
#define ADC2_SOURCE_AD4B        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(4))
#define ADC2_SOURCE_AD5B        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(5))
#define ADC2_SOURCE_AD6B        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(6))
#define ADC2_SOURCE_AD7B        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(7))
#define ADC2_SOURCE_AD8         (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(8))
#define ADC2_SOURCE_AD9         (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(9))
#define ADC2_SOURCE_AD10        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(10))
#define ADC2_SOURCE_AD11        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(11))
#define ADC2_SOURCE_AD12        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(12))
#define ADC2_SOURCE_AD13        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(13))
#define ADC2_SOURCE_AD14        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(14))
#define ADC2_SOURCE_AD15        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(15))
#define ADC2_SOURCE_AD16        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(16))
#define ADC2_SOURCE_AD17        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(17))
#define ADC2_SOURCE_AD18        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(18))
#define ADC2_SOURCE_AD19        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(19))
#define ADC2_SOURCE_AD20        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(20))
#define ADC2_SOURCE_AD21        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(21))
#define ADC2_SOURCE_AD22        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(22))
#define ADC2_SOURCE_AD23        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(23))
#define ADC2_SOURCE_AD24        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(24))
#define ADC2_SOURCE_AD25        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(25))
#define ADC2_SOURCE_AD26        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC2_SOURCE_AD27        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(27))
#define ADC2_SOURCE_AD28        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC2_SOURCE_AD29        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(29))
#define ADC2_SOURCE_AD30        (ADC_SOURCE_MODULE(3) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(30))


#define ADC2_SOURCE_VREF            (ADC2_SOURCE_AD18)

#define ADC2_SOURCE_DAC1            (ADC2_SOURCE_AD23)
#define ADC2_SOURCE_TEMP            (ADC2_SOURCE_AD26)
#define ADC2_SOURCE_TEMP_DIFF       (ADC2_SOURCE_AD26 | ADC_SOURCE_DIFF)
#define ADC2_SOURCE_BANDGAP         (ADC2_SOURCE_AD27)
#define ADC2_SOURCE_BANDGAP_DIFF    (ADC2_SOURCE_AD27 | ADC_SOURCE_DIFF)
#define ADC2_SOURCE_VREFH           (ADC2_SOURCE_AD29)
#define ADC2_SOURCE_VREFH_DIFF      (ADC2_SOURCE_AD29 | ADC_SOURCE_DIFF)
#define ADC2_SOURCE_VREFL           (ADC2_SOURCE_AD30)


#define ADC3_SOURCE_ADPM0       (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0) | ADC_SOURCE_DIFF)
#define ADC3_SOURCE_ADPM1       (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1) | ADC_SOURCE_DIFF)
#define ADC3_SOURCE_ADPM2       (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2) | ADC_SOURCE_DIFF)
#define ADC3_SOURCE_ADPM3       (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3) | ADC_SOURCE_DIFF)
#define ADC3_SOURCE_AD0         (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0))
#define ADC3_SOURCE_AD1         (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1))
#define ADC3_SOURCE_AD2         (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2))
#define ADC3_SOURCE_AD3         (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3))
#define ADC3_SOURCE_AD4A        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC3_SOURCE_AD5A        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(5))
#define ADC3_SOURCE_AD6A        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(6))
#define ADC3_SOURCE_AD7A        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(7))
#define ADC3_SOURCE_AD4B        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(4))
#define ADC3_SOURCE_AD5B        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(5))
#define ADC3_SOURCE_AD6B        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(6))
#define ADC3_SOURCE_AD7B        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(7))
#define ADC3_SOURCE_AD8         (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(8))
#define ADC3_SOURCE_AD9         (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(9))
#define ADC3_SOURCE_AD10        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(10))
#define ADC3_SOURCE_AD11        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(11))
#define ADC3_SOURCE_AD12        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(12))
#define ADC3_SOURCE_AD13        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(13))
#define ADC3_SOURCE_AD14        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(14))
#define ADC3_SOURCE_AD15        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(15))
#define ADC3_SOURCE_AD16        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(16))
#define ADC3_SOURCE_AD17        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(17))
#define ADC3_SOURCE_AD18        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(18))
#define ADC3_SOURCE_AD19        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(19))
#define ADC3_SOURCE_AD20        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(20))
#define ADC3_SOURCE_AD21        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(21))
#define ADC3_SOURCE_AD22        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(22))
#define ADC3_SOURCE_AD23        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(23))
#define ADC3_SOURCE_AD24        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(24))
#define ADC3_SOURCE_AD25        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(25))
#define ADC3_SOURCE_AD26        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC3_SOURCE_AD27        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(27))
#define ADC3_SOURCE_AD28        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC3_SOURCE_AD29        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(29))
#define ADC3_SOURCE_AD30        (ADC_SOURCE_MODULE(4) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(30))


#define ADC3_SOURCE_VREF            (ADC3_SOURCE_AD18)

#define ADC3_SOURCE_DAC1            (ADC3_SOURCE_AD23)
#define ADC3_SOURCE_TEMP            (ADC3_SOURCE_AD26)
#define ADC3_SOURCE_TEMP_DIFF       (ADC3_SOURCE_AD26 | ADC_SOURCE_DIFF)
#define ADC3_SOURCE_BANDGAP         (ADC3_SOURCE_AD27)
#define ADC3_SOURCE_BANDGAP_DIFF    (ADC3_SOURCE_AD27 | ADC_SOURCE_DIFF)
#define ADC3_SOURCE_VREFH           (ADC3_SOURCE_AD29)
#define ADC3_SOURCE_VREFH_DIFF      (ADC3_SOURCE_AD29 | ADC_SOURCE_DIFF)
#define ADC3_SOURCE_VREFL           (ADC3_SOURCE_AD30)
#endif /* BSP_TWR_K60F120M */

#endif /* __adc_mk60_h__ */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/iwcfg.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iwcfg.c$
* $Version : 3.8.4.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   configure a wireless network interface.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <enet.h>
#include <rtcs.h>
#include <dns.h> 
#include <string.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "ipcfg.h"
#include "ipcfg_prv.h"
#include "enet_wifi.h"
#include "iwcfg.h"

#ifdef BSP_ENET_DEVICE_COUNT
#if  (BSP_ENET_DEVICE_COUNT > 0) 

RSSI_QUANTA g_rssiTable[MAX_RSSI_TABLE_SZ] = {    
                                                  {200,181},
                                                  {180,161},
                                                  {160,141},
                                                  {140,121},
                                                  {121,100} 
                                             };

#define RSSI_TBL_ENTRY_MIN(x)    g_rssiTable[x].min
#define RSSI_TBL_ENTRY_MAX(x)    g_rssiTable[x].max

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : iwcfg_set_ssid()
* Returned Value  : ENET_OK if ESSID set successfully else ERROR CODE
* Comments        : Sets the ESSID. ESSID comes into effect only when 
*                   user commits his changes.
*
*END*-----------------------------------------------------------------*/

uint_32 iwcfg_set_essid
    (
        uint_32 dev_num,
        char_ptr essid
    )
{
    _rtcs_if_handle ihandle;
    ENET_ESSID  inout_param;
    uint_32 error,dev_status;
    
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }
        if (!essid)
          inout_param.flags = 0;
        else
         inout_param.flags = 1;
        
        inout_param.essid = essid;
        inout_param.length = strlen(essid);
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }

        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_SET_MEDIACTL_ESSID,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        return ENET_OK;
    }
    printf("IWCONFIG_ERROR: Invalid Device number\n");
    return ENETERR_INVALID_DEVICE;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : iwcfg_get_ssid()
* Returned Value  : ENET_OK if ESSID set successfully else ERROR CODE
* Comments        : Sets the ESSID. ESSID comes into effect only when 
*                   user commits his changes.
*
*END*-----------------------------------------------------------------*/

uint_32 iwcfg_get_essid
    (
        uint_32 dev_num,
        char_ptr essid /*[OUT]*/
    )
{
    _rtcs_if_handle ihandle;
    ENET_MEDIACTL_PARAM  inout_param;
    uint_32 error,dev_status;
    
    
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }

        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }

        inout_param.data = (pointer)essid;
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_GET_MEDIACTL_ESSID,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        
        if (!inout_param.flags)
            return ENET_ERROR;
        
        essid[inout_param.length] = '\0';
        return ENET_OK;
    }
    printf("IWCONFIG_ERROR: Invalid Device number\n");
    return ENETERR_INVALID_DEVICE;
}



/*FUNCTION*--------------------------------------------------------------------
*
* Function Name   : iwcfg_commit()
* Returned Value  : ENET_OK if commit is successfull else ERROR CODE
* Comments        : Commits the requested change. It also associates
*                   with the requested AP with SSID set by iwcfg_set_essid 
*
*END*------------------------------------------------------------------------*/

uint_32 iwcfg_commit
    (
        uint_32 dev_num
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error,dev_status;
    
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }

        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_SET_MEDIACTL_COMMIT,NULL);
        if (ENET_OK != error)
        {
            return error;
        }
        return ENET_OK;
    }
    
    return ENETERR_INVALID_DEVICE;
}

/*FUNCTION*--------------------------------------------------------------------
*
* Function Name   : iwcfg_set_mode()
* Returned Value  : ENET_CODE if mode set successfull else ERROR CODE
* Comments        : Sets the Mode for Wifi Device. 
*
*END*------------------------------------------------------------------------*/

uint_32 iwcfg_set_mode
    (
        uint_32 dev_num,
        char_ptr mode
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error;
    uint_32 inout_param,dev_status;
 
    if (!strcmp(mode,"managed")) 
    {
        inout_param = ENET_MEDIACTL_MODE_INFRA;
    }
    else if (!strcmp(mode,"adhoc")) 
    {
        inout_param = ENET_MEDIACTL_MODE_ADHOC;
    }
    else
    {
        printf("Invalid Mode parameter %s. Refer help\n",mode);
        return ENET_ERROR;
    }
        
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }
        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_SET_MEDIACTL_MODE,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        return ENET_OK;
    }
    
    return ENETERR_INVALID_DEVICE;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : iwcfg_get_mode()
* Returned Value  : ENET_OK if ESSID set successfully else ERROR CODE
* Comments        : Sets the ESSID. ESSID comes into effect only when 
*                   user commits his changes.
*
*END*-----------------------------------------------------------------*/

uint_32 iwcfg_get_mode
    (
        uint_32 dev_num,
        char_ptr mode /*[OUT]*/
    )
{
    _rtcs_if_handle ihandle;
    uint_32  inout_param;
    uint_32 error,dev_status;
    
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }

        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }

        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_GET_MEDIACTL_MODE,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        
        if (inout_param == ENET_MEDIACTL_MODE_INFRA)  
           strcpy(mode,"managed");
        else if (inout_param == ENET_MEDIACTL_MODE_ADHOC)
           strcpy(mode,"adhoc");
        else
        {
           mode = NULL;
           return ENET_ERROR;   
        }
        
        return ENET_OK;
    }
    printf("IWCONFIG_ERROR: Invalid Device number\n");
    return ENETERR_INVALID_DEVICE;
}
/*FUNCTION*--------------------------------------------------------------------
*
* Function Name   : iwcfg_set_wep_key()
* Returned Value  : ENET_OK if mode set successfull else ERROR CODE
* Comments        : Sets the Mode for Wifi Device. 
*
*END*------------------------------------------------------------------------*/

uint_32 iwcfg_set_wep_key 
    (
        uint_32 dev_num,
        char_ptr wep_key,
        uint_32 key_len,
        uint_32 key_index
        
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error,dev_status;
    uint_32 flags = 0;
    ENET_MEDIACTL_PARAM  inout_param;

   if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }
        
        if (wep_key == NULL)
         flags |= ENET_MEDIACTL_ENCODE_DISABLED|ENET_MEDIACTL_ENCODE_MODE;
        else
         flags |= ENET_MEDIACTL_ENCODE_ENABLED;
        
        flags |= (key_index & 0xFF); 
        inout_param.data = wep_key;
        inout_param.length = key_len;
        inout_param.flags = flags;
        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_SET_MEDIACTL_ENCODE,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        return ENET_OK;
    }   
    return ENETERR_INVALID_DEVICE;  
}

/*FUNCTION*--------------------------------------------------------------------
*
* Function Name   : iwcfg_get_wep_key()
* Returned Value  : ENET_OK if mode set successfull else ERROR CODE
* Comments        : Sets the Mode for Wifi Device. 
*
*END*------------------------------------------------------------------------*/

uint_32 iwcfg_get_wep_key 
    (
        uint_32 dev_num,
        char_ptr wep_key,
        uint_32_ptr key_index
  
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error,dev_status;
    uint_32 flags = 0;
    ENET_MEDIACTL_PARAM  inout_param;

   if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }
        
        inout_param.data = (pointer)wep_key;
                
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_GET_MEDIACTL_ENCODE,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        wep_key[inout_param.length] = '\0';
        if (key_index)
           *key_index = inout_param.flags & 0xFF;
        return ENET_OK;
    }   
    return ENETERR_INVALID_DEVICE;  
}

/*FUNCTION*--------------------------------------------------------------------
*
* Function Name   : iwcfg_get_passphrase()
* Returned Value  : ENET_OK if mode set successfull else ERROR CODE
* Comments        : Sets the Mode for Wifi Device. 
*
*END*------------------------------------------------------------------------*/

uint_32 iwcfg_get_passphrase 
    (
        uint_32 dev_num,
        char_ptr passphrase
         
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error,dev_status;
    uint_32 flags = 0;
    ENET_MEDIACTL_PARAM  inout_param;

   if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }
        
        inout_param.data = (pointer)passphrase;
                
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_GET_MEDIACTL_PASSPHRASE,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        
        passphrase[inout_param.length] = '\0';
        
        return ENET_OK;
    }   
    return ENETERR_INVALID_DEVICE;  
}
/*FUNCTION*--------------------------------------------------------------------
*
* Function Name   : iwcfg_set_wep_key()
* Returned Value  : ENET_OK if mode set successfull else ERROR CODE
* Comments        : Sets the Mode for Wifi Device. 
*
*END*------------------------------------------------------------------------*/

uint_32 iwcfg_set_sec_type 
    (
        uint_32 dev_num,
        char_ptr  sec_type
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error,inout_param,dev_status;

   if (strcmp(sec_type,"none") == 0)
   {
      inout_param = ENET_MEDIACTL_SECURITY_TYPE_NONE;
   }
   else if (strcmp(sec_type,"wep") == 0)
   {
     inout_param = ENET_MEDIACTL_SECURITY_TYPE_WEP;
   }
   else if (strcmp(sec_type,"wpa") == 0)
   {
     inout_param = ENET_MEDIACTL_SECURITY_TYPE_WPA;
   }
   else if (strcmp(sec_type,"wpa2") == 0)
   {
     inout_param = ENET_MEDIACTL_SECURITY_TYPE_WPA2;
   }
   else
   {
     printf("%s sectype passed is incorrect. refer help\n",sec_type);
     return ENET_ERROR;
   }
   
   if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_SET_MEDIACTL_SEC_TYPE,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        return ENET_OK;
    }   
    return ENETERR_INVALID_DEVICE;  
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : iwcfg_get_sectype()
* Returned Value  : ENET_OK if ESSID set successfully else ERROR CODE
* Comments        : Sets the ESSID. ESSID comes into effect only when 
*                   user commits his changes.
*
*END*-----------------------------------------------------------------*/

uint_32 iwcfg_get_sectype
    (
        uint_32 dev_num,
        char_ptr sectype /*[OUT]*/
    )
{
    _rtcs_if_handle ihandle;
    uint_32  inout_param;
    uint_32 error,dev_status;
    
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }

        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }

        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_GET_MEDIACTL_SEC_TYPE,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        
        if (inout_param == ENET_MEDIACTL_SECURITY_TYPE_NONE)  
           strcpy(sectype,"none");
        else if (inout_param == ENET_MEDIACTL_SECURITY_TYPE_WEP)
           strcpy(sectype,"wep");
        else if (inout_param == ENET_MEDIACTL_SECURITY_TYPE_WPA)
           strcpy(sectype,"wpa");
        else if (inout_param == ENET_MEDIACTL_SECURITY_TYPE_WPA2)
           strcpy(sectype,"wpa2");
        else
        {
           sectype = NULL;
           return ENET_ERROR;   
        }
        
        return ENET_OK;
    }
    printf("IWCONFIG_ERROR: Invalid Device number\n");
    return ENETERR_INVALID_DEVICE;
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : iwcfg_set_passphrase()
* Returned Value  : ENET_OK if ESSID set successfully else ERROR CODE
* Comments        : Sets the ESSID. ESSID comes into effect only when 
*                   user commits his changes.
*
*END*-----------------------------------------------------------------*/

uint_32 iwcfg_set_passphrase
    (
        uint_32 dev_num,
        char_ptr passphrase
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error,dev_status;
    ENET_MEDIACTL_PARAM param;
    
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        param.data = passphrase;
        param.length = strlen(passphrase);
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }
        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_SET_MEDIACTL_PASSPHRASE,&param);
        if (ENET_OK != error)
        {
            return error;
        }
        return ENET_OK;
    }
    printf("IWCONFIG_ERROR: Invalid Device number\n");
    return ENETERR_INVALID_DEVICE;
}

/*FUNCTION*--------------------------------------------------------------------
*
* Function Name   : iwcfg_set_wep_key()
* Returned Value  : ENET_OK if mode set successfull else ERROR CODE
* Comments        : Sets the Mode for Wifi Device. 
*
*END*------------------------------------------------------------------------*/

uint_32 iwcfg_set_power 
    (
        uint_32 dev_num,
        uint_32 pow_val,
        uint_32 flags
        
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error,dev_status;
    ENET_MEDIACTL_PARAM  inout_param;

   if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }
        
        inout_param.value = pow_val;
        inout_param.disabled = flags;
        inout_param.flags = ENET_MEDIACTL_POWER_PERIOD;
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_SET_MEDIACTL_POWER,&inout_param);
        if (ENET_OK != error)
        {
            return error;
        }
        return ENET_OK;
    }   
    return ENETERR_INVALID_DEVICE;  
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : iwcfg_set_scan()
* Returned Value  : ENET_OK if ESSID set successfully else ERROR CODE
* Comments        : Sets the ESSID. ESSID comes into effect only when 
*                   user commits his changes.
*
*END*-----------------------------------------------------------------*/

uint_32 iwcfg_set_scan
    (
        uint_32 dev_num,
        char_ptr ssid
    )
{
    _rtcs_if_handle ihandle;
    uint_32 error,dev_status,i=0;
    ENET_SCAN_LIST  param;
    
    if (dev_num < IPCFG_DEVICE_COUNT)
    {
        ihandle = ipcfg_get_ihandle(dev_num);
        if (ihandle == NULL)
        {
            printf("Initialize Wifi Device Using ipconfig\n");
            return ENET_ERROR;
        }        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_MEDIACTL_IS_INITIALIZED,&dev_status);
        if (ENET_OK != error)
        {
            return error;
        }
        if (dev_status == FALSE)
        {
            return ENET_ERROR;
        }
        
        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_SET_MEDIACTL_SCAN,NULL);
        if (ENET_OK != error)
        {
            return error;
        }

        error = ENET_mediactl (((IP_IF_PTR)ihandle)->HANDLE,ENET_GET_MEDIACTL_SCAN,&param);
        if (ENET_OK != error)
        {
            return error;
        }
   
        for (i = 0;i<param.num_scan_entries;i++)
        {
            uint_8 j = MAX_RSSI_TABLE_SZ-1;
            
            printf("\n\r");
            if (param.scan_info_list[i].ssid_len == 1)
               printf("ssid = SSID Not available\n");
            else
               printf ("ssid = %s\n",param.scan_info_list[i].ssid);
            printf ("bssid = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",param.scan_info_list[i].bssid[0],param.scan_info_list[i].bssid[1],param.scan_info_list[i].bssid[2],param.scan_info_list[i].bssid[3],param.scan_info_list[i].bssid[4],param.scan_info_list[i].bssid[5]);
            printf ("channel = %d\n",param.scan_info_list[i].channel);
            printf("strength = ");
             do {    
      
                if ( RSSI_TBL_ENTRY_MIN(j) < param.scan_info_list[i].rssi )
                  printf("#");
                else
                  printf(".");
                  
            } while ( j-- > 0 );
            printf("\nindicator = %d",param.scan_info_list[i].rssi);
            printf("\n\r");
        }
        return ENET_OK;
    }
    printf("IWCONFIG_ERROR: Invalid Device number\n");
    return ENETERR_INVALID_DEVICE;
}

#endif /* (BSP_ENET_DEVICE_COUNT > 0) */
#endif /* BSP_ENET_DEVICE_COUNT */
/*EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/kinetis_mpu.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: kinetis_mpu.h$
* $Version : 3.8.4.0$
* $Date    : Aug-30-2011$
*
* Comments:
*
*   This file contains header for basic mpu settings.
*
*END************************************************************************/

#ifndef __kinetis_mpu_h__
#define __kinetis_mpu_h__

#ifdef __cplusplus
extern "C" {
#endif
    
_mqx_uint _kinetis_mpu_init(void);
_mqx_uint _kinetis_mpu_enable(void);
_mqx_uint _kinetis_mpu_disable(void);
_mqx_uint _kinetis_mpu_add_region(uchar_ptr start, uchar_ptr end, _mqx_uint flags);
_mqx_uint _kinetis_mpu_sw_check(uint_32 addr, _mem_size size, uint_32 flags);
_mqx_uint _kinetis_mpu_sw_check_mask(uint_32 addr, _mem_size size, uint_32 flags, uint_32 mask);
    
#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/can/flexcan/flexcan.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flexcan.h$
* $Version : 3.8.19.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This include file is used to provide constant and structure definitions
*   specific to the FlexCAN Serial Communications Controller
*   Revision History:
*   Apr 21, 2003   2.50          Initial version
*
*END************************************************************************/

#ifndef __flexcan_h__
#define __flexcan_h__ 1


// CAN constants

#define CAN_MIN_TQ  8
#define CAN_MAX_TQ  25

#define CAN_MAX_PROPSEG 8
#define CAN_MAX_RJW 4
#define CAN_MIN_PSEG2 2


// concrete HW settings:

#define FLEXCAN_MESSBUF_INT_LEVEL       (3)
#define FLEXCAN_MESSBUF_INT_SUBLEVEL    (4)

#define FLEXCAN_ERROR_INT_LEVEL         (3)
#define FLEXCAN_ERROR_INT_SUBLEVEL      (2)

#define FLEXCAN_BUSOFF_INT_LEVEL        (3)
#define FLEXCAN_BUSOFF_INT_SUBLEVEL     (3)

#define FLEXCAN_WAKEUP_INT_LEVEL        (3)
#define FLEXCAN_WAKEUP_INT_SUBLEVEL     (1)

#define FLEXCAN_MSG_BUFADDR_OFFSET      (128)
#define FLEXCAN_MSG_BUFF_MAXDATA_SIZE   (8)

#ifndef FLEXCAN_IPBUS_CLK
   #define FLEXCAN_IPBUS_CLK            (BSP_SYSTEM_CLOCK / 2)   /* Indicates internal clock source */
#endif

#ifndef FLEXCAN_OSC_CLK
   #define FLEXCAN_OSC_CLK              (0)   /* Must be set to external clock frequency, different to FLEXCAN_IPBUS_CLK! */ 
#endif


// interface provided:

/*
** CAN interrupt types enum
*/
#define FLEXCAN_INT_BUF                 (0)
#define FLEXCAN_INT_ERR                 (1)
#define FLEXCAN_INT_BOFF                (2)
#define FLEXCAN_INT_WAKEUP              (3)

/*
** CAN commands
*/
#define FLEXCAN_TX                      (0xFF)
#define FLEXCAN_RX                      (0x00)
#define FLEXCAN_EXTENDED                (0xFF)
#define FLEXCAN_STANDARD                (0x00)
#define FLEXCAN_ENABLE                  (0xFF)
#define FLEXCAN_DISABLE                 (0x00)

/*
** Module mode
*/
#define FLEXCAN_NORMAL_MODE             (0)
#define FLEXCAN_LISTEN_MODE             (1)
#define FLEXCAN_TIMESYNC_MODE           (2)
#define FLEXCAN_LOOPBK_MODE             (3)
#define FLEXCAN_BOFFREC_MODE            (4)
#define FLEXCAN_FREEZE_MODE             (5)
#define FLEXCAN_DISABLE_MODE            (6)

/*
** FLEXCAN error codes
*/
#define FLEXCAN_OK                       (0x00)
#define FLEXCAN_UNDEF_ERROR              (FLEXCAN_ERROR_BASE | 0x01)
#define FLEXCAN_MESSAGE14_TX             (FLEXCAN_ERROR_BASE | 0x02)
#define FLEXCAN_MESSAGE15_TX             (FLEXCAN_ERROR_BASE | 0x03)
#define FLEXCAN_MESSAGE_OVERWRITTEN      (FLEXCAN_ERROR_BASE | 0x04)
#define FLEXCAN_NO_MESSAGE               (FLEXCAN_ERROR_BASE | 0x05)
#define FLEXCAN_MESSAGE_LOST             (FLEXCAN_ERROR_BASE | 0x06)
#define FLEXCAN_MESSAGE_BUSY             (FLEXCAN_ERROR_BASE | 0x07)
#define FLEXCAN_MESSAGE_ID_MISSMATCH     (FLEXCAN_ERROR_BASE | 0x08)
#define FLEXCAN_MESSAGE14_START          (FLEXCAN_ERROR_BASE | 0x09)
#define FLEXCAN_MESSAGE15_START          (FLEXCAN_ERROR_BASE | 0x0A)
#define FLEXCAN_INVALID_ADDRESS          (FLEXCAN_ERROR_BASE | 0x0B)
#define FLEXCAN_INVALID_MAILBOX          (FLEXCAN_ERROR_BASE | 0x0C)
#define FLEXCAN_TIMEOUT                  (FLEXCAN_ERROR_BASE | 0x0D)
#define FLEXCAN_INVALID_FREQUENCY        (FLEXCAN_ERROR_BASE | 0x0E)
#define FLEXCAN_INT_ENABLE_FAILED        (FLEXCAN_ERROR_BASE | 0x0F)
#define FLEXCAN_INT_DISABLE_FAILED       (FLEXCAN_ERROR_BASE | 0x10)
#define FLEXCAN_INT_INSTALL_FAILED       (FLEXCAN_ERROR_BASE | 0x11)
#define FLEXCAN_REQ_MAILBOX_FAILED       (FLEXCAN_ERROR_BASE | 0x12)
#define FLEXCAN_DATA_SIZE_ERROR          (FLEXCAN_ERROR_BASE | 0x13)
#define FLEXCAN_MESSAGE_FORMAT_UNKNOWN   (FLEXCAN_ERROR_BASE | 0x14)
#define FLEXCAN_INVALID_DIRECTION        (FLEXCAN_ERROR_BASE | 0x15)
#define FLEXCAN_RTR_NOT_SET              (FLEXCAN_ERROR_BASE | 0x16)
#define FLEXCAN_SOFTRESET_FAILED         (FLEXCAN_ERROR_BASE | 0x17)
#define FLEXCAN_INVALID_MODE             (FLEXCAN_ERROR_BASE | 0x18)
#define FLEXCAN_START_FAILED             (FLEXCAN_ERROR_BASE | 0x19)
#define FLEXCAN_CLOCK_SOURCE_INVALID     (FLEXCAN_ERROR_BASE | 0x1A)
#define FLEXCAN_INIT_FAILED              (FLEXCAN_ERROR_BASE | 0x1B)
#define FLEXCAN_ERROR_INT_ENABLE_FAILED  (FLEXCAN_ERROR_BASE | 0x1C)
#define FLEXCAN_ERROR_INT_DISABLE_FAILED (FLEXCAN_ERROR_BASE | 0x1D)
#define FLEXCAN_FREEZE_FAILED            (FLEXCAN_ERROR_BASE | 0x1E)
#define FLEXCAN_INVALID_DEVICE           (FLEXCAN_ERROR_BASE | 0x1F)



#ifdef __cplusplus
extern "C" {
#endif

extern pointer _bsp_get_flexcan_base_address(uint_8);
extern PSP_INTERRUPT_TABLE_INDEX _bsp_get_flexcan_vector (uint_8,uint_8,uint_32);
extern boolean _bsp_flexcan_enable_access(uint_32 device);

extern uint_32 FLEXCAN_Softreset(uint_8);
extern uint_32 FLEXCAN_Start(uint_8);
extern pointer FLEXCAN_Get_msg_object(uint_8,uint_32);
extern uint_32 FLEXCAN_Select_mode(uint_8,uint_32);
extern uint_32 FLEXCAN_Select_clk(uint_8,uint_32);
extern uint_32 FLEXCAN_Initialize(uint_8,uint_32,uint_32,uint_32,uint_32);
extern uint_32 FLEXCAN_Initialize_mailbox(uint_8,uint_32,uint_32, uint_32,uint_32,uint_32,uint_32);
extern uint_32 FLEXCAN_Request_mailbox(uint_8,uint_32,uint_32);
extern uint_32 FLEXCAN_Activate_mailbox(uint_8,uint_32,uint_32);
extern uint_32 FLEXCAN_Lock_mailbox(uint_8,uint_32);
extern uint_32 FLEXCAN_Unlock_mailbox(uint_8);
extern uint_32 FLEXCAN_Set_global_extmask(uint_8,uint_32);
extern uint_32 FLEXCAN_Set_buf14_extmask(uint_8,uint_32);
extern uint_32 FLEXCAN_Set_buf15_extmask(uint_8,uint_32);
extern uint_32 FLEXCAN_Set_global_stdmask(uint_8,uint_32);
extern uint_32 FLEXCAN_Set_buf14_stdmask(uint_8,uint_32);
extern uint_32 FLEXCAN_Set_buf15_stdmask(uint_8,uint_32);
extern boolean FLEXCAN_Tx_successful(uint_8);
extern uint_32 FLEXCAN_Tx_mailbox(uint_8,uint_32,pointer);
extern uint_32 FLEXCAN_Rx_mailbox(uint_8,uint_32,pointer);
extern uint_32 FLEXCAN_Disable_mailbox(uint_8,uint_32);
extern uint_32 FLEXCAN_Request_message(uint_8,uint_32,uint_32);
extern uint_32 FLEXCAN_Rx_message(uint_8,uint_32,uint_32_ptr,uint_32,uint_32_ptr,pointer,uint_32);
extern uint_32 FLEXCAN_Tx_message(uint_8,uint_32,uint_32,uint_32,uint_32,pointer);
extern uint_32 FLEXCAN_Read(uint_8,uint_32,uint_32_ptr);
extern uint_32 FLEXCAN_Write(uint_8,uint_32,uint_32);
extern uint_32 FLEXCAN_Get_status(uint_8,uint_32_ptr);
extern uint_32 FLEXCAN_Update_message(uint_8,pointer,uint_32,uint_32,uint_32);
extern uint_32 FLEXCAN_Int_enable(uint_8,uint_32);
extern uint_32 FLEXCAN_Error_int_enable(uint_8);
extern uint_32 FLEXCAN_Int_disable(uint_8,uint_32);
extern uint_32 FLEXCAN_Error_int_disable(uint_8);
extern uint_32 FLEXCAN_Install_isr(uint_8,uint_32,INT_ISR_FPTR);
extern uint_32 FLEXCAN_Install_isr_ex(uint_8,uint_32,INT_ISR_FPTR,pointer);
extern uint_32 FLEXCAN_Install_isr_err_int(uint_8,INT_ISR_FPTR);
extern uint_32 FLEXCAN_Install_isr_boff_int(uint_8,INT_ISR_FPTR);
extern uint_32 FLEXCAN_Install_isr_wake_int(uint_8,INT_ISR_FPTR);
extern  void   _FLEXCAN_ISR(pointer);
extern uint_32 FLEXCAN_Int_status(uint_8);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ifbootp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifbootp.c$
* $Version : 3.8.7.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the interface functions for the
*   BOOTP client.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "bootp.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_bind_BOOTP
* Returned Values : uint_32 (error code)
* Comments        :
*     Initialize a hardware interface using BOOTP.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_bind_BOOTP
   (
      _rtcs_if_handle         handle,
         /* [IN] the RTCS interface state structure */
      BOOTP_DATA_STRUCT_PTR   data_ptr
         /* [IN/OUT] BOOTP parameters */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   TCPIP_PARM_BOOTP        parms;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }
   
   parms.handle = handle;
   parms.data   = data_ptr;

   return RTCSCMD_issue(parms, BOOTP_open);

#else

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4 */     

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/rtcsrand.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcsrand.c$
* $Version : 3.0.4.0$
* $Date    : Mar-5-2009$
*
* Comments:
*
*   This file contains the implementation of a random
*   number generator.
*
*END************************************************************************/

#include <rtcs.h>


#if RTCSCFG_USE_KISS_RNG 

/*
 * Probably the simplest RNG to pass all of the common RNG tests (and many 
 * others) is the KISS generator proposed by <NAME> (called KISS99 in 
 * the L’Ecuyer paper).
 *
 * This generator combines 3 different simple generators and has a period of 
 * around 10^38, i.e. it will start repeating the same sequence of numbers 
 * after that many calls. Plenty for pretty much any conceivable application. 
 * 
 * Note that you need to set the seed values (at least x, y and z need to be 
 * changed) to random starting values else you will always generate the same 
 * sequence of numbers in your program. Avoid setting the seeds to zero or 
 * small numbers in general. Try to choose large complex seed values.
 */
 
static uint_32 seed_x = 123456789;
static uint_32 seed_y = 362436000;
static uint_32 seed_z = 521288629;
static uint_32 seed_c = 7654321;

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_gen_seed
* Returned Values : uint_32
* Comments        :
*     Add randomness to the seed.
*
*END*-----------------------------------------------------------------*/

static uint_32 kiss_gen_seed(x, y)
{
   x = x + y;
   x = (x << 15) | (x >> 17);
   return (x & 0xFFFFFFFFUL);
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_rand_seed
* Returned Values : uint_32
* Comments        :
*     Seed the KISS RNG.  Y _must_ not be zero, but good practice to make 
*     sure they are all not zero.
*
*END*-----------------------------------------------------------------*/

void RTCS_rand_seed
   (
      uint_32 newseed
   )
{ /* Body */
   do {
      seed_x = kiss_gen_seed(seed_x, newseed);
   } while (seed_x == 0);

   do {
      seed_y = kiss_gen_seed(seed_y, newseed);
   } while (seed_y == 0);
   
   do {
      seed_z = kiss_gen_seed(seed_z, newseed);
   } while (seed_z == 0);
   
   /* Don’t really need to seed c as well but if you really want to,
      make sure it is less than 698769069 */
   do {
      seed_c = (kiss_gen_seed(seed_c, newseed) % 698769069);
   } while (seed_c == 0);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_rand
* Returned Values : uint_32
* Comments        :
*     Output 32 random bits.  Based on <NAME>aglia's KISS RNG
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_rand
   (
      void
   )
{ /* Body */
  uint_64 t, a=698769069LL;

  seed_x = 69069 * seed_x + 12345;
  seed_y ^= (seed_y<<13); 
  seed_y ^= (seed_y>>17); 
  seed_y ^= (seed_y<<5);
  t = a * seed_z + seed_c; 
  seed_c = (t>>32);
  
  return seed_x + seed_y + (seed_z = t);

} /* Endbody */

#else

// Original RTCS RNG 

#define P 0x6C77
#define Q 0x12E1B

static uint_32 seed   = 0;
static uint_32 reseed = 0;
static uint_32 state  = 4;


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_rand_seed
* Returned Values : void
* Comments        :
*     Add randomness to the seed.
*
*END*-----------------------------------------------------------------*/

void RTCS_rand_seed
   (
      uint_32 newseed
   )
{ /* Body */
   uint_32 realseed = seed;

   realseed = realseed + newseed;
   realseed = (realseed << 15) | (realseed >> 17);
   realseed = realseed & 0xFFFFFFFFUL;

   seed = realseed;
   reseed = 1;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_rand
* Returned Values : uint_32
* Comments        :
*     Output 32 random bits.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_rand
   (
      void
   )
{ /* Body */
   uint_32 i,j;
   uint_32 pq = P*Q;
   uint_32 square;
   uint_32 randnum;

   if (reseed) {
      uint_32 realseed = seed ^ state;
      uint_32 resp, resq;
      while (realseed >= pq) {
         realseed -= pq;
      } /* Endwhile */
      for (;;) {
         resp = realseed % P;
         resq = realseed % Q;
         if ((resp != 0) && (resp != 1) && (resp != P-1)
          && (resq != 0) && (resq != 1) && (resq != Q-1)) {
            break;
         } /* Endif */
         realseed += 3;
         if (realseed >= pq) realseed -= pq;
      } /* Endfor */
      state = realseed;
      reseed = 0;
   } /* Endif */

   randnum = 0;
   for (i=0; i<32; i++) {
      /* square = state*state mod pq */
      square = 0;
      for (j=0x40000000UL; j; j>>=1) {
         square <<= 1;
         if (square >= pq) square -= pq;
         if (state & j)    square += state;
         if (square >= pq) square -= pq;
      } /* Endfor */
      state = square;
      randnum = (randnum << 1) | (state & 1);
   } /* Endfor */

   return randnum;
} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/include/sh_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_prv.h$
* $Version : 3.6.7.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#ifndef __sh_prv_h__
#define __sh_prv_h__

#define SHELL_MAX_CMDLEN     80

#define Shell_get_context(ptr) ((SHELL_CONTEXT_PTR)(pointer) ptr)


typedef struct {
   char_ptr             ARGV[SHELL_MAX_ARGS];           // MUST BE FIRST !!
   int_32               ARGC;
   char                 CMD_LINE[SHELL_MAX_CMDLEN];
   char                 HISTORY[SHELL_MAX_CMDLEN];
   SHELL_COMMAND_PTR    COMMAND_LIST_PTR;
   MQX_FILE_PTR         COMMAND_FP;
   boolean              EXIT;
#if SHELLCFG_USES_MFS   
   char                 CURRENT_DEVICE_NAME[SHELL_MAX_DEVLEN]; 
   MQX_FILE_PTR         CURRENT_DEVICE_FP;
   char                 CURRENT_DIR[SHELL_PATHNAME_LEN + 1];
#endif   
} SHELL_CONTEXT, _PTR_ SHELL_CONTEXT_PTR;

/*
** Function prototypes 
*/
#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif

#endif
/*EOF*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/nattftp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nattftp.c$
* $Version : 3.6.3.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the NAT TFTP ALG.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include <rtcs_prv.h>
#include <tftp.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_ALG_tftp
* Returned Value  : error code
* Comments        :
*        Initializes the NAT TFTP ALG.
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_ALG_tftp
   (
      pointer ptr       /* [IN] pointer to NAT config struct */
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = ptr;
   NAT_ALG_CFG_STRUCT_PTR  tftp_ptr;

   tftp_ptr = _mem_alloc_system(sizeof(NAT_ALG_CFG_STRUCT));
   
   if (tftp_ptr)  {
      tftp_ptr->NEXT = nat_cfg_ptr->ALG_INFO_PTR;
      nat_cfg_ptr->ALG_INFO_PTR = tftp_ptr;  
      tftp_ptr->ALG_TYPE = NAT_ALG_TFTP_TYPE;
      tftp_ptr->ALG_EXEC = NAT_ALG_tftp_apply;   
      return RTCS_OK;
   } /* Endif */
   
   return RTCSERR_OUT_OF_MEMORY;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_ALG_tftp_apply
* Returned Value  : error code
* Comments        :
*        Applies the NAT TFTP ALG to a packet.
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_ALG_tftp_apply
   (
      RTCSPCB_PTR _PTR_    pcb_ptr_ptr,               /* [IN/OUT] PCB containing packet   */
      boolean              pub_to_prv,                /* [IN] Direction of packet         */
      pointer              alg_cfg_ptr,               /* [IN] Pointer to TFTP config      */
      pointer _PTR_        session_ptr_ptr   /* [OUT] Pointer to session         */
   )
{ /* Body */
   NAT_SESSION_STRUCT_PTR  nat_session_ptr = *((NAT_SESSION_STRUCT_PTR *)session_ptr_ptr);
   uchar_ptr               data_ptr = (pointer)RTCSPCB_DATA(*pcb_ptr_ptr);
   IP_HEADER_PTR           ip_header_ptr = (IP_HEADER_PTR)(pointer)data_ptr;
   TRANSPORT_UNION         transport;
   TFTP_HEADER_PTR         tftp_header_ptr;
   uint_16                 opcode, block;
 
   if (nat_session_ptr == NULL) {
      return RTCS_OK;
   } /* Endif */
   
   
   /* TFTP uses UDP */
   if (ntohc(ip_header_ptr->PROTOCOL) != IPPROTO_UDP) {
      return RTCS_OK;
   } /* Endif */
      
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);
   
   /* The UDP length should be long enough to contain a TFTP header */
   if (ntohs(transport.UDP_PTR->LENGTH) < sizeof(UDP_HEADER) + sizeof(TFTP_HEADER)) {
      return RTCS_OK;
   } /* Endif */         
   
   tftp_header_ptr = (TFTP_HEADER_PTR)(pointer)(transport.UDP_PTR + 1);

   opcode = ntohs(tftp_header_ptr->OP);
   block = ntohs(tftp_header_ptr->BLOCK);
   
   /*
   ** A normal reply should have:  OP 3 (DATA) and BLOCK 1 (first block) or
   ** an OP 4 and BLOCK 0. Error replies should have: OP 5, and a variable 
   ** error code 
   */
   if ((opcode != 3 || block != 1) &&
       (opcode != 4 || block != 0) &&
       (opcode != 5))   
   {
      return RTCS_OK;
   } /* Endif */      

   if (nat_session_ptr->SNAT_OR_DNAT == SNAT) {
      /* We only need to consider the first packet returned by the server */
      if (!pub_to_prv) {
         return RTCS_OK;
      } /* Endif */

      /* Make sure port number is the TFTP port number */
      if (nat_session_ptr->PUB_PORT != IPPORT_TFTP) {
         return RTCS_OK;
      } /* Endif */
      
      /* Set new server port number */
      nat_session_ptr->PUB_PORT = ntohs(transport.UDP_PTR->SRC_PORT);
   } else {
      /* We only need to consider the first packet returned by the server */
      if (pub_to_prv){
         return RTCS_OK;
      } /* Endif */

      /* Make sure port number is the TFTP port number */
      if (nat_session_ptr->PRV_PORT != IPPORT_TFTP) {
         return RTCS_OK;
      } /* Endif */
      
      /* Set new server port number */
      nat_session_ptr->PRV_PORT = ntohs(transport.UDP_PTR->SRC_PORT);       
   } /* Endif */
   
   return RTCS_OK;   
} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fscan.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fscan.c$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the function fscanf.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief This function performs similarly to the scanf function of 'C'.
 * 
 * \param[in] file_ptr The stream to scan from.
 * \param[in] fmt_ptr  The format string to use when scanning.
 * 
 * \return Number of input items converted and assigned.
 * \return IO_EOF  
 */ 
_mqx_int _io_fscanf
   (
      MQX_FILE_PTR     file_ptr,
      const char _PTR_ fmt_ptr, 
      ...
   )
{ /* Body */
   char    temp_buf[IO_MAXLINE];
   va_list ap;
   _mqx_int result;
   
#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(IO_EOF);
   } /* Endif */
#endif

   va_start(ap, fmt_ptr);
   /* get a line of input from user */
   if (_io_fgetline( file_ptr, temp_buf, IO_MAXLINE) == IO_EOF) {
      return(IO_EOF);
   } /* Endif */
   result = _io_scanline( temp_buf, (char _PTR_)fmt_ptr, ap );
   va_end(ap);
   return result;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/core_mutex/sema4.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sema4.h$
* $Version : 3.8.2.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*  This file contains the type definitions for the MPXxxx SEMA4 module.
*
*END************************************************************************/

#ifndef __sema4_h__
#define __sema4_h__

#define __sema4_h__version "$Version:3.8.2.0$"
#define __sema4_h__date    "$Date:Sep-24-2012$"


#define SEMA4_NUM_GATES 16

#define SEMA4_UNLOCK    0

/* PPC dont have SEMA4 register structure */
#if PSP_MQX_CPU_IS_PPC
typedef volatile struct sema4_reg_struct
{
   uchar    GATE[SEMA4_NUM_GATES];
   RESERVED_REGISTER(0x10,0x40);
   uint_16  CP0INE;
   RESERVED_REGISTER(0x42,0x48);
   uint_16  CP1INE;
   RESERVED_REGISTER(0x4a,0x80);
   uint_16  CP0NTF;
   RESERVED_REGISTER(0x82,0x88);
   uint_16  CP1NTF;
   RESERVED_REGISTER(0x8a,0x100);
   uint_16  RSTGT;
   RESERVED_REGISTER(0x102,0x104);
   uint_16  RSTNTF;
   RESERVED_REGISTER(0x106,0x400);
} SEMA4_REG_STRUCT;

typedef volatile struct sema4_reg_struct *SEMA4_MemMapPtr;
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/iptunnel.h<|end_filename|>
#ifndef __iptunnel_h__
#define __iptunnel_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iptunnel.h$
* $Version : 3.5.5.0$
* $Date    : Dec-8-2009$
*
* Comments:
*
*   This file contains the defines, externs and data
*   structure definitions required by IP over IP encapsulation.
*
*END************************************************************************/

#include "ip_prv.h"


/*********************************************************
**
** IPIP CONSTANTS
*/

#define IPIP_INITIAL_COUNT  4
#define IPIP_GROW_COUNT     4


/*********************************************************
**
** IPIP Structures
*/

/*
** IPIP_TUNNEL
**    Contains information about an IP over IP tunnel
*/
typedef struct ipip_tunnel {
   struct ipip_tunnel _PTR_ NEXT;       /* Points to next node in list */
   _ip_address    INNER_SOURCE;           /* Embedded header source */
   _ip_address    INNER_SOURCE_NETMASK;   /* Embedded header source mask */
   _ip_address    INNER_DEST;             /* Embedded header destination */
   _ip_address    INNER_DEST_NETMASK;     /* Embedded header dest mask */
   _ip_address    OUTER_SOURCE;           /* Source for outer header */
   _ip_address    OUTER_DEST;             /* Destination for outer header */
   uint_32        FLAGS;                  /* Behaviour flags */
} IPIP_TUNNEL, _PTR_ IPIP_TUNNEL_PTR;


/*
** IPIP_PARM
**    Used to pass information from the application to RTCS
*/
typedef struct  ipip_parm {
   TCPIP_PARM     COMMON;                 /* Common to all parm structs */
   IPIP_TUNNEL    TUNNEL;
} IPIP_PARM, _PTR_ IPIP_PARM_PTR;


/*
** IPIP_CFG_STRUCT
**    Contains the configuration information for the IP Tunnel device
*/
typedef struct ipip_cfg_struct {
   IPIP_TUNNEL_PTR   NEXT;             /* Linked list of tunnels */
   _rtcs_part        IPIP_PART;        /* Tunnel information part */
   IP_IF_PTR         IPIP_IF;          /* IPIP interface pointer */
   uint_32           TUNNELS;          /* Number of tunnels */
} IPIP_CFG_STRUCT,  _PTR_ IPIP_CFG_STRUCT_PTR;



#ifdef __cplusplus
extern "C" {
#endif

extern uint_32 IPIP_init (void);

extern void IPIP_service (RTCSPCB_PTR pcb_ptr, pointer dummy);

extern void IPIP_insert (IPIP_PARM_PTR);
extern void IPIP_delete (IPIP_PARM_PTR);

extern uint_32 IPIP_open  (IP_IF_PTR);
extern uint_32 IPIP_close (IP_IF_PTR);

extern uint_32 IPIP_send (IP_IF_PTR, RTCSPCB_PTR, _ip_address, _ip_address, pointer);

extern void IPIP_send_internal (RTCSPCB_PTR);

extern uint_32 IPIP_MTU (pointer);

#ifdef __cplusplus
}
#endif


#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/lcp.h<|end_filename|>
#ifndef __lcp_h__
#define __lcp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lcp.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the defines and data structure
*   definitions required by LCP.
*
*END************************************************************************/

/*
** lcp.h - Link Control Protocol definitions.
**
** Copyright (c) 1989 Carnegie Mellon University.
** All rights reserved.
**
** Redistribution and use in source and binary forms are permitted
** provided that the above copyright notice and this paragraph are
** duplicated in all such forms and that any documentation,
** advertising materials, and other materials related to such
** distribution and use acknowledge that the software was developed
** by Carnegie Mellon University.  The name of the
** University may not be used to endorse or promote products derived
** from this software without specific prior written permission.
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
** WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/


/*
** LCP-specific packet types
*/

#define LCP_CODE_PROT_REJ  8       /* Protocol Reject */
#define LCP_CODE_ECHO_REQ  9       /* Echo Request */
#define LCP_CODE_ECHO_REP  10      /* Echo Reply */
#define LCP_CODE_DISC_REQ  11      /* Discard Request */


/*
** LCP Configuration Options
*/

#define LCP_CI_MRU      1     /* Maximum Receive Unit */
#define LCP_CI_ACCM     2     /* Async Control Character Map */
#define LCP_CI_AP       3     /* Authentication Protocol */
#define LCP_CI_QP       4     /* Quality Protocol */
#define LCP_CI_MAGIC    5     /* Magic Number */
#define LCP_CI_PFC      7     /* Protocol Field Compression */
#define LCP_CI_ACFC     8     /* Address and Control Field Compression */
#define LCP_CI_FCS      9     /* Frame Check Sequence Method */


/*
** Prototypes
*/

extern uint_32 LCP_init    (_ppp_handle);
extern uint_32 LCP_destroy (_ppp_handle);

extern void LCP_sendprotrej (PCB_PTR, PPPFSM_CFG_PTR);

#define LCP_input PPPFSM_input

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/nd6.h<|end_filename|>
#ifndef __nd6_h__
#define __nd6_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nd6.h$
* $Version : 3.8.2.0$
* $Date    : Aug-16-2012$
*
* Comments:
*
*   Definitions for the Neighbor Discovery for IP6.
*
*END************************************************************************/
#include "rtcspcb.h"
#include "rtcstime.h"
#include "icmp6_prv.h"


/**************************************************************
* RFC4861. 10. Protocol Constants.
***************************************************************
*    Host constants:
*        MAX_RTR_SOLICITATION_DELAY 1 second
*        RTR_SOLICITATION_INTERVAL 4 seconds
*        MAX_RTR_SOLICITATIONS 3 transmissions
*    Node constants:
*        MAX_MULTICAST_SOLICIT 3 transmissions
*        MAX_UNICAST_SOLICIT 3 transmissions
*        MAX_ANYCAST_DELAY_TIME 1 second
*        MAX_NEIGHBOR_ADVERTISEMENT 3 transmissions
*        REACHABLE_TIME 30,000 milliseconds
*        RETRANS_TIMER 1,000 milliseconds
*        DELAY_FIRST_PROBE_TIME 5 seconds
*        MIN_RANDOM_FACTOR .5
*        MAX_RANDOM_FACTOR 1.5
***************************************************************/

/* If a host sends MAX_RTR_SOLICITATIONS solicitations, and receives no
 * Router Advertisements after having waited MAX_RTR_SOLICITATION_DELAY
 * seconds after sending the last solicitation, the host concludes that
 * there are no routers on the link for the purpose of [ADDRCONF].
 * However, the host continues to receive and process Router
 * Advertisements messages in the event that routers appear on the link.
 */
#define ND6_MAX_RTR_SOLICITATIONS       (3)         /* transmissions */
#define ND6_MAX_RTR_SOLICITATION_DELAY  (1000)      /* ms */
#define ND6_RTR_SOLICITATION_INTERVAL   (4000)      /* ms */


/* If no Neighbor Advertisement is received after MAX_MULTICAST_SOLICIT
* solicitations, address resolution has failed. The sender MUST return
* ICMP destination unreachable indications with code 3 (Address
* Unreachable) for each packet queued awaiting address resolution.
*/
#define ND6_MAX_MULTICAST_SOLICIT       (3)     /* transmissions */

/*
 * Default value of the time between retransmissions of Neighbor
 * Solicitation messages to a neighbor when
 * resolving the address or when probing the
 * reachability of a neighbor. Also used during Duplicate
 * Address Detection (RFC4862).
 */
#define ND6_RETRANS_TIMER               (1000)  /* ms */

/*
 * Default value of the time a neighbor is considered reachable after
 * receiving a reachability confirmation.
 *
 * This value should be a uniformly distributed
 * random value between MIN_RANDOM_FACTOR and
 * MAX_RANDOM_FACTOR times BaseReachableTime
 * milliseconds. A new random value should be
 * calculated when BaseReachableTime changes (due to
 * Router Advertisements) or at least every few
 * hours even if
 */
#define ND6_REACHABLE_TIME              (30000) /* ms */

/*
 * If no reachability confirmation is received
 * within DELAY_FIRST_PROBE_TIME seconds of entering the
 * DELAY state, send a Neighbor Solicitation and change
 * the state to PROBE.
 */
#define ND6_DELAY_FIRST_PROBE_TIME      (5000)  /*ms*/

/*
 * If no response is
 * received after waiting RetransTimer milliseconds after sending the
 * MAX_UNICAST_SOLICIT solicitations, retransmissions cease and the
 * entry SHOULD be deleted.
 */
#define ND6_MAX_UNICAST_SOLICIT         (3)     /*times*/

/*
 * ND6 general timer resolution.
 */
#define ND6_TIMER_PERIOD                (100)   /* ms */


/* Real Sizes:*/
#define ND6_NEIGHBOR_CACHE_SIZE         (RTCSCFG_ND6_NEIGHBOR_CACHE_SIZE + RTCSCFG_ND6_ROUTER_LIST_SIZE) /* Neighbor Cache and Default Router List combined to one list.*/
#define ND6_PREFIX_LIST_SIZE            (RTCSCFG_ND6_PREFIX_LIST_SIZE + 1) /* One more for link-local prefix.*/
#define ND6_REDIRECT_TABLE_SIZE         (4) /* TBD config parameter.*/


#define ND6_PREFIX_LENGTH_DEFAULT       (64)            /* Default prefix length, in bits.*/
#define ND6_PREFIX_LIFETIME_INFINITE    (0xFFFFFFFF)    /* A lifetime value of all one bits (0xffffffff) represents infinity. */


/**************************************************************
* Neighbor’s reachability state., based on RFC4861.
**************************************************************/
typedef enum nd6_neighbor_state
{
    ND6_NEIGHBOR_STATE_NOTUSED = 0,     /* The entry is not used - free.*/
    ND6_NEIGHBOR_STATE_INCOMPLETE = 1,  /* Address resolution is in progress and the link-layer
                                         * address of the neighbor has not yet been determined.*/
    ND6_NEIGHBOR_STATE_REACHABLE = 2,   /* Roughly speaking, the neighbor is known to have been
                                         * reachable recently (within tens of seconds ago).*/
    ND6_NEIGHBOR_STATE_STALE = 3,       /* The neighbor is no longer known to be reachable but
                                         * until traffic is sent to the neighbor, no attempt
                                         * should be made to verify its reachability.*/                                         
    ND6_NEIGHBOR_STATE_DELAY = 4,       /* The neighbor is no longer known to be reachable, and
                                         * traffic has recently been sent to the neighbor.
                                         * Rather than probe the neighbor immediately, however,
                                         * delay sending probes for a short while in order to
                                         * give upper-layer protocols a chance to provide
                                         * reachability confirmation.*/                                          
    ND6_NEIGHBOR_STATE_PROBE = 5        /* The neighbor is no longer known to be reachable, and
                                         * unicast Neighbor Solicitation probes are being sent to
                                         * verify reachability.*/                                          
} nd6_neighbor_state_t;

/**********************************************************************
* Neighbor Solicitation Message Format
***********************************************************************
* Nodes send Neighbor Solicitations to request the link-layer address
* of a target node while also providing their own link-layer address to
* the target.
*
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |     Type      |     Code      |          Checksum             |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                           Reserved                            |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                                                               |
*    +                                                               +
*    |                                                               |
*    +                       Target Address                          +
*    |                                                               |
*    +                                                               +
*    |                                                               |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |   Options ...
*    +-+-+-+-+-+-+-+-+-+-+-+-
***********************************************************************/
typedef struct nd6_ns_header
{
   ICMP6_HEADER HEAD;
   uchar       	RESERVED[4];
   uchar		TARGET_ADDR[16];
} ND6_NS_HEADER, _PTR_ ND6_NS_HEADER_PTR;

/**********************************************************************
* Neighbor Advertisement Message Format
***********************************************************************
* A node sends Neighbor Advertisements in response to Neighbor
* Solicitations and sends unsolicited Neighbor Advertisements in order
* to (unreliably) propagate new information quickly.
*
*	 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |     Type      |     Code      |          Checksum             |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |R|S|O|                     Reserved                            |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                                                               |
*    +                                                               +
*    |                                                               |
*    +                       Target Address                          +
*    |                                                               |
*    +                                                               +
*    |                                                               |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |   Options ...
*    +-+-+-+-+-+-+-+-+-+-+-+-
***********************************************************************/
typedef struct nd6_na_header
{
   ICMP6_HEADER HEAD;
   uchar        FLAG[1];
   uchar       	RESERVED[3];
   uchar		TARGET_ADDR[16];
} ND6_NA_HEADER, _PTR_ ND6_NA_HEADER_PTR;

/* NA flags.*/
#define ND6_NA_FLAG_ROUTER      (0x80)  /* Router flag. When set, the R-bit indicates that
                                         * the sender is a router. The R-bit is used by
                                         * Neighbor Unreachability Detection to detect a
                                         * router that changes to a host.*/
#define ND6_NA_FLAG_SOLICITED   (0x40)  /* Solicited flag. When set, the S-bit indicates that
                                         * the advertisement was sent in response to a
                                         * Neighbor Solicitation from the Destination address.
                                         * The S-bit is used as a reachability confirmation
                                         * for Neighbor Unreachability Detection. It MUST NOT
                                         * be set in multicast advertisements or in
                                         * unsolicited unicast advertisements.*/
#define ND6_NA_FLAG_OVERRIDE    (0x20)  /* Override flag. When set, the O-bit indicates that
                                         * the advertisement should override an existing cache
                                         * entry and update the cached link-layer address.
                                         * When it is not set the advertisement will not
                                         * update a cached link-layer address though it will
                                         * update an existing Neighbor Cache entry for which
                                         * no link-layer address is known. It SHOULD NOT be
                                         * set in solicited advertisements for anycast
                                         * addresses and in solicited proxy advertisements.
                                         * It SHOULD be set in other solicited advertisements
                                         * and in unsolicited advertisements.*/                                                  

/**********************************************************************
* Redirect Message Format (RFC 4861)
***********************************************************************
* Routers send Redirect packets to inform a host of a better first-hop
* node on the path to a destination.
*
*	 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |     Type      |     Code      |          Checksum             |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                           Reserved                            |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                                                               |
*    +                                                               +
*    |                                                               |
*    +                       Target Address                          +
*    |                                                               |
*    +                                                               +
*    |                                                               |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                                                               |
*    +                                                               +
*    |                                                               |
*    +                    Destination Address                        +
*    |                                                               |
*    +                                                               +
*    |                                                               |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |   Options ...
*    +-+-+-+-+-+-+-+-+-+-+-+-
***********************************************************************/
typedef struct nd6_rd_header
{
   ICMP6_HEADER HEAD;
   uchar       	RESERVED[4];
   uchar		TARGET_ADDR[16];
   uchar		DESTINATION_ADDR[16];
} ND6_RD_HEADER, _PTR_ ND6_RD_HEADER_PTR;

/**********************************************************************
* Router Solicitation Message Format
***********************************************************************
* Hosts send Router Solicitations in order to prompt routers to
* generate Router Advertisements quickly.
*
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |     Type      |     Code      |          Checksum             |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                           Reserved                            |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |   Options ...
*    +-+-+-+-+-+-+-+-+-+-+-+-
***********************************************************************/
typedef struct nd6_rs_header
{
   ICMP6_HEADER HEAD;           /* ICMPv6 header.*/
   uchar       	RESERVED[4];
} ND6_RS_HEADER, _PTR_ ND6_RS_HEADER_PTR;

/**********************************************************************
* Router Advertisement Message Format
***********************************************************************
* Routers send out Router Advertisement messages periodically, or in
* response to Router Solicitations.
*
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |     Type      |     Code      |          Checksum             |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    | Cur Hop Limit |M|O|  Reserved |       Router Lifetime         |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                      Reachable Time                           |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |                      Retrans Timer                            |
*    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*    |   Options ...
*    +-+-+-+-+-+-+-+-+-+-+-+-
***********************************************************************/
typedef struct nd6_ra_header
{
   ICMP6_HEADER HEAD;                   /* ICMPv6 header.*/
   uchar       	CUR_HOP_LIMIT[1];       /* 8-bit unsigned integer. The default value that
                                         * should be placed in the Hop Count field of the IP
                                         * header for outgoing IP packets. A value of zero
                                         * means unspecified (by this router). */
   uchar       	FLAG[1];                /* ND6_RS_FLAG_M and/or ND6_RS_FLAG_O flags.*/
   uchar       	ROUTER_LIFETIME[2];     /* 16-bit unsigned integer. The lifetime associated
                                         * with the default router in units of seconds. The
                                         * field can contain values up to 65535 and receivers
                                         * should handle any value, while the sending rules in
                                         * Section 6 limit the lifetime to 9000 seconds. A
                                         * Lifetime of 0 indicates that the router is not a
                                         * default router and SHOULD NOT appear on the default
                                         * router list. The Router Lifetime applies only to
                                         * the router’s usefulness as a default router; it
                                         * does not apply to information contained in other
                                         * message fields or options. Options that need time
                                         * limits for their information include their own
                                         * lifetime fields.*/
    uchar       REACHABLE_TIME[4];      /* 32-bit unsigned integer. The time, in
                                         * milliseconds, that a node assumes a neighbor is
                                         * reachable after having received a reachability
                                         * confirmation. Used by the Neighbor Unreachability
                                         * Detection algorithm (see Section 7.3). A value of
                                         * zero means unspecified (by this router). */                                       
    uchar       RETRANS_TIMER[4];       /* 32-bit unsigned integer. The time, in
                                         * milliseconds, between retransmitted Neighbor
                                         * Solicitation messages. Used by address resolution
                                         * and the Neighbor Unreachability Detection algorithm
                                         * (see Sections 7.2 and 7.3). A value of zero means
                                         * unspecified (by this router).*/   
   
} ND6_RA_HEADER, _PTR_ ND6_RA_HEADER_PTR;

/* RA flags */
#define ND6_RA_FLAG_M   (0x80)  /* 1-bit "Managed address configuration" flag. When
                                 * set, it indicates that addresses are available via
                                 * Dynamic Host Configuration Protocol [DHCPv6].
                                 * If the M flag is set, the O flag is redundant and
                                 * can be ignored because DHCPv6 will return all
                                 * available configuration information.*/
#define ND6_RA_FLAG_O   (0x40)  /* 1-bit "Other configuration" flag. When set, it
                                 * indicates that other configuration information is
                                 * available via DHCPv6. Examples of such information
                                 * are DNS-related information or information on other
                                 * servers within the network.*/
                                /* Note: If neither M nor O flags are set, this indicates that no
                                 * information is available via DHCPv6.*/


/* Hop Limit when sending/receiving Neighbor Discovery messages. */
#define ND6_HOP_LIMIT                   255

/* ND option types (RFC4861). */
#define ND6_OPTION_SOURCE_LLA           1 /* Source Link-layer Address.*/
#define ND6_OPTION_TARGET_LLA           2 /* Target Link-layer Address.*/
#define ND6_OPTION_PREFIX               3 /* Prefix Information.*/
#define ND6_OPTION_REDIRECTED_HEADER    4 /* Redirected Header.*/
#define ND6_OPTION_MTU                  5 /* MTU */

/***********************************************************************
 * ND option header
 ***********************************************************************/
typedef struct nd6_option_header
{
    uchar TYPE[1];     /* Identifier of the type of option.*/
    uchar LENGTH[1];   /* The length of the option
                        * (including the type and length fields) in units of
                        * 8 octets.  The value 0 is invalid.  Nodes MUST
                        * silently discard an ND packet that contains an
                        * option with length zero.*/
} ND6_OPTION_HEADER, _PTR_ ND6_OPTION_HEADER_PTR;

/***********************************************************************
 * Source/Target Link-layer Address option header:
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |     Type      |     Length    |       Link-Layer Address ...
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
 ***********************************************************************/
typedef struct nd6_option_lla_header
{
    ND6_OPTION_HEADER HEAD; /* Option general header.*/
    uchar   addr[6];        /* The length of the option. Can be more or less than 6.*/
}ND6_OPTION_LLA_HEADER, _PTR_ ND6_OPTION_LLA_HEADER_PTR;

/***********************************************************************
 * MTU option header:
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |     Type      |     Length    |           Reserved            |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |                          MTU                                  |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 ***********************************************************************/
typedef struct nd6_option_mtu_header
{
    ND6_OPTION_HEADER HEAD; /* Option general header.*/
    uchar   RESEVED[2];
    uchar   MTU[4];         /* The recommended MTU for the link.*/
}ND6_OPTION_MTU_HEADER, _PTR_ ND6_OPTION_MTU_HEADER_PTR;

/***********************************************************************
 * Prefix Information option header:
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |     Type      |     Length    | Prefix Length |L|A| Reserved1 |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |                         Valid Lifetime                        |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |                       Preferred Lifetime                      |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |                           Reserved2                           |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |                                                               |
 *  +                                                               +
 *  |                                                               |
 *  +                             Prefix                            +
 *  |                                                               |
 *  +                                                               +
 *  |                                                               |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 ***********************************************************************/
typedef struct nd6_option_prefix_header
{
    ND6_OPTION_HEADER HEAD;     /* Option general header.*/
    uchar   PREFIX_LENGTH[1];   /* The number of leading bits
                                 * in the Prefix that are valid. The value ranges
                                 * from 0 to 128. The prefix length field provides
                                 * necessary information for on-link determination
                                 * (when combined with the L flag in the prefix
                                 * information option). It also assists with address
                                 * autoconfiguration as specified in [ADDRCONF], for
                                 * which there may be more restrictions on the prefix
                                 * length.*/
    uchar   FLAG[1];            /* ND6_OPTION_FLAG_L and/or ND6_OPTION_FLAG_O flags.*/
    uchar   VALID_LIFETIME[4];  /* The length of time in
                                 * seconds (relative to the time the packet is sent)
                                 * that the prefix is valid for the purpose of on-link
                                 * determination. A value of all one bits
                                 * (0xffffffff) represents infinity. The Valid
                                 * Lifetime is also used by [ADDRCONF].*/
    uchar   PREFERED_LIFETIME[4];/* The length of time in
                                 * seconds (relative to the time the packet is sent)
                                 * that addresses generated from the prefix via
                                 * stateless address autoconfiguration remain
                                 * preferred [ADDRCONF]. A value of all one bits
                                 * (0xffffffff) represents infinity. See [ADDRCONF].
                                 * Note that the value of this field MUST NOT exceed
                                 * the Valid Lifetime field to avoid preferring
                                 * addresses that are no longer valid.*/  
    uchar   RESERVED[4];        
    uchar   PREFIX[16];          /* An IP address or a prefix of an IP address. The
                                 * Prefix Length field contains the number of valid
                                 * leading bits in the prefix. The bits in the prefix
                                 * after the prefix length are reserved and MUST be
                                 * initialized to zero by the sender and ignored by
                                 * the receiver. A router SHOULD NOT send a prefix
                                 * option for the link-local prefix and a host SHOULD
                                 * ignore such a prefix option.*/                                    
                                                                
}ND6_OPTION_PREFIX_HEADER, _PTR_ ND6_OPTION_PREFIX_HEADER_PTR;

#define ND6_OPTION_FLAG_L   0x80    /* 1-bit on-link flag. When set, indicates that this
                                     * prefix can be used for on-link determination. When
                                     * not set the advertisement makes no statement about
                                     * on-link or off-link properties of the prefix. In
                                     * other words, if the L flag is not set a host MUST
                                     * NOT conclude that an address derived from the
                                     * prefix is off-link. That is, it MUST NOT update a
                                     * previous indication that the address is on-link.*/    
#define ND6_OPTION_FLAG_A   0x40    /* 1-bit autonomous address-configuration flag. When
                                     * set indicates that this prefix can be used for
                                     * stateless address configuration as specified in
                                     * [ADDRCONF].*/                                     

/***********************************************************************
* Neighbor Cache entry, based on RFC4861.
***********************************************************************/
typedef struct nd6_neighbor_entry
{
 
    in6_addr        ip_addr;            /* Neighbor’s on-link unicast IP address. */
    ll_addr_t       ll_addr;            /* Its link-layer address. Actual size is defiined by IP_IF->DEV_ADDRLEN. */
    nd6_neighbor_state_t state;         /* Neighbor’s reachability state.*/
    uint_32         state_time;         /* Time of last state event.*/
    RTCSPCB_PTR     waiting_pcb;        /* Pointer to any queued packet/PCB waiting for address resolution to complete.*/
                                        /* RFC 4861 7.2.2: While waiting for address resolution to complete, the sender MUST,
                                         * for each neighbor, retain a small queue of packets waiting for
                                         * address resolution to complete. The queue MUST hold at least one
                                         * packet, and MAY contain more.
                                         * When a queue  overflows, the new arrival SHOULD replace the oldest entry.*/
    int            solicitation_send_counter;  /* Counter - how many soicitations where sent.*/
    in6_addr       solicitation_src_ip_addr;   /* IP address used during AR solicitation messages. */
    uint_32         creation_time;      /* Time of entry creation, in seconds.*/
           
    /* Default Router list entry info.*/
    uchar           is_router;          /* A flag indicating whether the neighbor is a router or a host.*/
    uint_32         router_lifetime;    /* The lifetime associated
                                         * with the default router in units of seconds. The
                                         * field can contain values up to 65535 and receivers
                                         * should handle any value, while the sending rules in
                                         * Section 6 limit the lifetime to 9000 seconds. A
                                         * Lifetime of 0 indicates that the router is not a
                                         * default router and SHOULD NOT appear on the default router list.
                                         * It is used only if "is_router" is 1.*/

} ND6_NEIGHBOR_ENTRY, _PTR_ ND6_NEIGHBOR_ENTRY_PTR;

/***********************************************************************
* Redirect Table entry.
***********************************************************************/
typedef struct nd6_redirect_entry
{
    in6_addr     destination_addr;   /* Destination Address. The IP address of the destination that is
                                      * redirected to the target. */
    in6_addr     target_addr;        /* Target Address. An IP address that is a better first hop to use for
                                      * the ICMP Destination Address. When the target is
                                      * the actual endpoint of communication, i.e., the
                                      * destination is a neighbor, the Target Address field
                                      * MUST contain the same value as the ICMP Destination
                                      * Address field. Otherwise, the target is a better
                                      * first-hop router and the Target Address MUST be the
                                      * router’s link-local address so that hosts can
                                      * uniquely identify routers. */
    uint_32       creation_time;     /* Time of entry creation.*/
} ND6_REDIRECT_ENTRY, _PTR_ ND6_REDIRECT_ENTRY_PTR;


/***********************************************************************
* Prefix state.
***********************************************************************/
typedef enum nd6_prefix_state
{
    ND6_PREFIX_STATE_NOTUSED = 0,   /* The entry is not used - free.*/
    ND6_PREFIX_STATE_USED = 1       /* The entry is used.*/
} nd6_prefix_state_t;

/***********************************************************************
* Prefix List entry, based on RFC4861.
* Prefix List entries are created from information received in Router
* Advertisements.
***********************************************************************/
typedef struct nd6_prefix_entry
{
 
    in6_addr    prefix;             /* Prefix of an IP address. */
    uint_32     prefix_length;      /* Prefix length (in bits). The number of leading bits
                                     * in the Prefix that are valid. */
    nd6_prefix_state_t state;       /* Prefix state.*/                                 
    uint_32     lifetime;           /* Valid Lifetime
                                     * 32-bit unsigned integer. The length of time in
                                     * seconds (relative to the time the packet is sent)
                                     * that the prefix is valid for the purpose of on-link
                                     * determination. A value of all one bits
                                     * (0xffffffff) represents infinity. The Valid
                                     * Lifetime is also used by [ADDRCONF].*/
    uint_32      creation_time;     /* Time of entry creation, in seconds.*/                                     
} ND6_PREFIX_ENTRY, _PTR_ ND6_PREFIX_ENTRY_PTR;

/***********************************************************************
* Router state.
***********************************************************************/
typedef enum nd6_router_state
{
    ND6_ROUTER_STATE_NOTUSED = 0,   /* The entry is not used - free.*/
    ND6_ROUTER_STATE_USED = 1       /* The entry is used.*/
} nd6_router_state_t;

/***********************************************************************
* Forward declaration. Just to avoid header conflicts.
***********************************************************************/
struct ip_if; 
struct ip6_if_addr_info;

/***********************************************************************
* Neighbor Discovery API function
***********************************************************************/
typedef struct nd6_if
{
    uint_32 (*neighbor_solicitation_receive)(RTCSPCB_PTR rtcs_pcb);
    uint_32 (*neighbor_advertisement_receive)(RTCSPCB_PTR rtcs_pcb);
    uint_32 (*router_advertisement_receive)(RTCSPCB_PTR rtcs_pcb);
    uint_32 (*redirect_receive)(RTCSPCB_PTR rtcs_pcb);
    void (*dad_start)(struct ip_if *if_ptr, struct ip6_if_addr_info *addr_info);
} ND6_IF, _PTR_ ND6_IF_PTR;

/***********************************************************************
* Neighbor Discovery Configuration
***********************************************************************/
typedef struct nd6_cfg
{
    /*************************************************************
    * Neighbor Cache.
    * RFC4861 5.1: A set of entries about individual neighbors to 
    * which traffic has been sent recently. 
    **************************************************************/
    /*************************************************************
    * Combined with Default Router List.
    * RFC4861 5.1: A list of routers to which packets may be sent.. 
    **************************************************************/    
    ND6_NEIGHBOR_ENTRY  neighbor_cache [ND6_NEIGHBOR_CACHE_SIZE];
    
    /*************************************************************
    * Prefix List.
    * RFC4861 5.1: A list of the prefixes that define a set of
    * addresses that are on-link. 
    **************************************************************/
    ND6_PREFIX_ENTRY    prefix_list [ND6_PREFIX_LIST_SIZE]; 

    /* Redirect Table. Used only when target address != destination address. */
    ND6_REDIRECT_ENTRY  redirect_table[ND6_REDIRECT_TABLE_SIZE];  
   
    TCPIP_EVENT         timer;                  /* General ND timer.*/
    
    /* Router Discovery variables.*/
    uint_32             rd_transmit_counter;    /* Counter used by RD. Equals to the number 
                                                 * of RS transmits till RD is finished.*/                                                    
    uint_32             rd_time;                /* Time of last RS transmit.*/    
    
    /* Interface variables */  
    uint_32             mtu;                    /* The recommended MTU for the link.
                                                 * Updated by RA messages.*/
    uint_8              cur_hop_limit;          /* The default value that
                                                 * should be placed in the Hop Count field of the IP
                                                 * header for outgoing IP packets.*/
    uint_32             reachable_time;         /* The time, in milliseconds,
                                                 * that a node assumes a neighbor is
                                                 * reachable after having received a reachability
                                                 * confirmation. Used by the Neighbor Unreachability
                                                 * Detection algorithm.*/ 
    uint_32             retrans_timer;          /* The time, in milliseconds,
                                                 * between retransmitted Neighbor
                                                 * Solicitation messages. Used by address resolution
                                                 * and the Neighbor Unreachability Detection algorithm
                                                 * (see Sections 7.2 and 7.3).*/ 
    int                 ip6_disabled;           /* IP operation on the interface is disabled.*/
    const ND6_IF        *nd6_interface;         /* Pointer to ND6 interface functions.*/
} ND6_CFG, _PTR_ ND6_CFG_PTR;

/***********************************************************************
* Globals
***********************************************************************/
extern const ND6_IF nd6_if_standard;

/***********************************************************************
* Function Prototypes
***********************************************************************/
uint_32 nd6_open(struct ip_if *if_ptr);
void nd6_close (struct ip_if *if_ptr);
ND6_NEIGHBOR_ENTRY_PTR nd6_neighbor_cache_get(struct ip_if *if_ptr, in6_addr *ip_addr);
ND6_NEIGHBOR_ENTRY_PTR nd6_neighbor_cache_add(struct ip_if *if_ptr, in6_addr *ip_addr, ll_addr_t ll_addr, nd6_neighbor_state_t state);
void nd6_neighbor_cache_del(struct ip_if *if_ptr, ND6_NEIGHBOR_ENTRY_PTR neighbor_entry);
ND6_PREFIX_ENTRY_PTR nd6_prefix_list_get(struct ip_if *if_ptr, in6_addr *prefix);
ND6_PREFIX_ENTRY_PTR nd6_prefix_list_add(struct ip_if *if_ptr, in6_addr *prefix, uint_32 prefix_length, uint_32 lifetime);
void nd6_prefix_list_del(ND6_PREFIX_ENTRY_PTR prefix_entry);
boolean nd6_addr_is_onlink(struct ip_if *if_ptr, in6_addr *addr);
void nd6_router_list_add( ND6_NEIGHBOR_ENTRY_PTR neighbor_entry, uint_32 invalidation_time);
void nd6_router_list_del( ND6_NEIGHBOR_ENTRY_PTR neighbor_entry);
ND6_NEIGHBOR_ENTRY_PTR nd6_default_router_get(struct ip_if *if_ptr);
uint_32 nd6_neighbor_advertisement_send(struct ip_if *if_ptr, in6_addr *ipsrc, in6_addr *ipdest, uint_8 flags);
uint_32 nd6_neighbor_advertisement_receive(RTCSPCB_PTR rtcs_pcb);
uint_32 nd6_neighbor_solicitation_send(struct ip_if *if_ptr, in6_addr *ipsrc, in6_addr *ipdest, in6_addr *target_addr);
uint_32 nd6_neighbor_solicitation_receive(RTCSPCB_PTR rtcs_pcb);
uint_32 nd6_redirect_receive(RTCSPCB_PTR rtcs_pcb);
void nd6_redirect_addr(struct ip_if *if_ptr, in6_addr **destination_addr_p);
uint_32 nd6_router_solicitation_send(struct ip_if *if_ptr);
uint_32 nd6_router_advertisement_receive(RTCSPCB_PTR rtcs_pcb);
void nd6_neighbor_enqueue_waiting_pcb(ND6_NEIGHBOR_ENTRY_PTR neighbor_entry, RTCSPCB_PTR  waiting_pcb);
void nd6_neighbor_send_waiting_pcb(struct ip_if *if_ptr, ND6_NEIGHBOR_ENTRY_PTR neighbor_entry);
void nd6_dad_start(struct ip_if *if_ptr, struct ip6_if_addr_info *addr_info);
void nd6_rd_start(struct ip_if *if_ptr);

/* For Debug needs only */
void nd6_debug_print_prefix_list(struct ip_if *if_ptr );
void nd6_debug_print_neighbor_cache(struct ip_if *if_ptr );

#endif /* __nd6_h__ */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/ensend.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ensend.c$
* $Version : 3.7.12.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the Ethernet send
*   interface function.
*
*END************************************************************************/

#include <mqx_inc.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_send
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Sends a packet.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_send
   (
      /* [IN] the Ethernet state structure */
      _enet_handle   handle,

      /* [IN] the packet to send */
      PCB_PTR        packet,

      /* [IN] the protocol */
      uint_16        type,

      /* [IN] the destination Ethernet address */
      _enet_address  dest,

      /* [IN] optional flags, zero = default */
      uint_32        flags
   )
{ 
   ENET_CONTEXT_STRUCT_PTR  enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;
   ENET_HEADER_PTR         packet_ptr;
   uchar_ptr               type_ptr;
   PCB_FRAGMENT_PTR        frag_ptr;
   uint_32                 swhdr, size, frags;
   uint_32                 error;
   _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
   
   _KLOGM(_GET_KERNEL_DATA(kernel_data);)
   _KLOGE6(KLOG_ENET_send, handle, packet, type, dest, flags);

   if (flags & ENET_OPT_8021QTAG) {
       swhdr = ENET_FRAMESIZE_HEAD_VLAN;
   } else {
       swhdr = ENET_FRAMESIZE_HEAD;
   } 

   /*
   ** Make sure the first fragment is long enough for the Ethernet
   ** frame header.  This isn't strictly necessary, but it's impractical
   ** to split a 14-26 byte header over multiple fragments.
   */
#if MQX_CHECK_ERRORS
   if (packet->FRAG[0].LENGTH < swhdr) {
      ENET_INC_STATS(COMMON.ST_TX_DISCARDED);
      error = ENETERR_SEND_SHORT;
      goto ERROR;
   }
#endif

   /*
   ** Make sure that no fragment exceeds a maximum packet length.
   ** We check every fragment because we want to prevent something
   ** like FRAG[0].LENGTH = 2000, FRAG[1].LENGTH = -1000.  This
   ** situation would not be detected if we only check the total
   ** length.
   */
   size = frags = 0;
   for (frag_ptr = packet->FRAG; frag_ptr->LENGTH; frag_ptr++) {
#if MQX_CHECK_ERRORS
      if (frag_ptr->LENGTH > enet_ptr->MaxTxFrameSize) {   
         ENET_INC_STATS(COMMON.ST_TX_DISCARDED);
         error = ENETERR_SEND_LONG;
         goto ERROR;
      } 
#endif
      size += frag_ptr->LENGTH;
      frags++;
   } 

   /*
   ** Make sure that the total sum of the fragments doesn't exceed
   ** a maximum packet length.
   */
#if MQX_CHECK_ERRORS
   if (size > enet_ptr->MaxTxFrameSize) {
      ENET_INC_STATS(COMMON.ST_TX_DISCARDED);
      error = ENETERR_SEND_LONG;
      goto ERROR;
   } 
#endif

   /*
   ** Everything checks out -- fill in the header.
   */
   packet_ptr = (ENET_HEADER_PTR)packet->FRAG[0].FRAGMENT;
   htone(packet_ptr->DEST, dest);
   htone(packet_ptr->SOURCE, enet_ptr->ADDRESS);
   type_ptr = packet_ptr->TYPE;

   if (flags & ENET_OPT_8021QTAG) {
      ENET_8021QTAG_HEADER_PTR tag_ptr = (ENET_8021QTAG_HEADER_PTR)(type_ptr+2);
      uint_16 tag;
      tag = ENET_GETOPT_8021QPRIO(flags) << 13;
      htons(type_ptr, ENETPROT_8021Q);
      htons(tag_ptr->TAG, tag);
      type_ptr = tag_ptr->TYPE;
   } 

   if (flags & ENET_OPT_8023) {
      ENET_8022_HEADER_PTR llc_ptr = (ENET_8022_HEADER_PTR)(type_ptr+2);
      htons(type_ptr, size - swhdr);
      htonc(llc_ptr->DSAP, 0xAA);
      htonc(llc_ptr->SSAP, 0xAA);
      htonc(llc_ptr->COMMAND, 0x03);
      htonc(&llc_ptr->OUI[0], 0x00);
      htonc(&llc_ptr->OUI[1], 0x00);
      htonc(&llc_ptr->OUI[2], 0x00);
      type_ptr = llc_ptr->TYPE;
   } 

   htons(type_ptr, type);

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself, and with ENET_ISR().
   */
   ENET_lock_context(enet_ptr);
   error = (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->SEND)(handle, packet, size, frags, flags);
   ENET_unlock_context(enet_ptr);

   if (error) {
   ERROR:
      PCB_free(packet);
   }
   
   _KLOGX4(KLOG_ENET_send, handle, packet, error);
   
   return error;
}  



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_send_raw
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Sends a packet.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_send_raw
   (
      /* [IN] the Ethernet state structure */
      _enet_handle   handle,

      /* [IN] the packet to send */
      PCB_PTR        packet
   )
{ /* Body */
   ENET_CONTEXT_STRUCT_PTR    enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;
   PCB_FRAGMENT_PTR           frag_ptr;
   uint_32                    size, frags;
   uint_32                    error;

   /*
   ** Make sure that no fragment exceeds a maximum packet length.
   ** We check every fragment because we want to prevent something
   ** like FRAG[0].LENGTH = 2000, FRAG[1].LENGTH = -1000.  This
   ** situation would not be detected if we only check the total
   ** length.
   */
   size = frags = 0;
   for (frag_ptr = packet->FRAG; frag_ptr->LENGTH; frag_ptr++) {
#if MQX_CHECK_ERRORS
      if (frag_ptr->LENGTH > enet_ptr->MaxTxFrameSize) {   
         ENET_INC_STATS(COMMON.ST_TX_DISCARDED);
         error = ENETERR_SEND_LONG;
         goto ERROR;
      } 
#endif
      size += frag_ptr->LENGTH;
      frags++;
   } 

   /*
   ** Make sure that the total sum of the fragments doesn't exceed
   ** a maximum packet length.
   */
#if MQX_CHECK_ERRORS
   if (size > enet_ptr->MaxTxFrameSize) {
      ENET_INC_STATS(COMMON.ST_TX_DISCARDED);
      error = ENETERR_SEND_LONG;
      goto ERROR;
   } 
#endif

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself, and with ENET_ISR().
   */
   ENET_lock_context(enet_ptr);
   error = (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->SEND)(handle, packet, size, frags, 0);
   ENET_unlock_context(enet_ptr);

   if (error) {
   ERROR:
      PCB_free(packet);
   }  

   return error;

}  

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi_legacy/int/spi_int_mcf5xxx_qspi.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_int_mcf5xxx_qspi.c$
* $Version : 3.8.18.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   The file contains low level QSPI interrupt driver functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "spi.h"
#include "spi_pol_prv.h"
#include "spi_int_prv.h"
#include "spi_mcf5xxx_qspi_prv.h"

extern uint_32 _mcf5xxx_qspi_polled_init(MCF5XXX_QSPI_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _mcf5xxx_qspi_polled_ioctl(MCF5XXX_QSPI_INFO_STRUCT_PTR, uint_32, uint_32_ptr, uint_32);

static uint_32 _mcf5xxx_qspi_int_init(IO_SPI_INT_DEVICE_STRUCT_PTR, char_ptr);
static uint_32 _mcf5xxx_qspi_int_deinit(IO_SPI_INT_DEVICE_STRUCT_PTR, MCF5XXX_QSPI_INFO_STRUCT_PTR);
static uint_32 _mcf5xxx_qspi_int_rx(IO_SPI_INT_DEVICE_STRUCT_PTR, uchar_ptr, int_32);
static uint_32 _mcf5xxx_qspi_int_tx(IO_SPI_INT_DEVICE_STRUCT_PTR, uchar_ptr, int_32);
static uint_32 _mcf5xxx_qspi_int_enable(MCF5XXX_QSPI_INFO_STRUCT_PTR io_info_ptr);
static void _mcf5xxx_qspi_int_isr(pointer parameter);
                       
/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_int_install
* Returned Value   : MQX error code
* Comments         :
*    Install an SPI device.
*
*END*********************************************************************/
uint_32 _mcf5xxx_qspi_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr           identifier,
  
      /* [IN] The I/O init data pointer */
      MCF5XXX_QSPI_INIT_STRUCT_CPTR init_data_ptr
   )
{
   return _io_spi_int_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer,char_ptr))_mcf5xxx_qspi_int_init,
      (uint_32 (_CODE_PTR_)(pointer))_mcf5xxx_qspi_int_enable,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_mcf5xxx_qspi_int_deinit,
      (_mqx_int (_CODE_PTR_)(pointer, char_ptr, int_32))_mcf5xxx_qspi_int_rx,
      (_mqx_int (_CODE_PTR_)(pointer, char_ptr, int_32))_mcf5xxx_qspi_int_tx,
      (_mqx_int (_CODE_PTR_)(pointer, uint_32, _mqx_uint_ptr, _mqx_uint))_mcf5xxx_qspi_polled_ioctl, 
      (pointer)init_data_ptr);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_int_init  
* Returned Value   : MQX error code
* Comments         :
*    This function initializes the SPI module 
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_int_init
  (
     /* [IN] The address of the device specific information */
     IO_SPI_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

     /* [IN] The rest of the name of the device opened */
     char_ptr                     open_name_ptr
  )
{
   MCF5XXX_QSPI_INFO_STRUCT_PTR   io_info_ptr;
   MCF5XXX_QSPI_INIT_STRUCT_PTR   spi_init_ptr;
   uint_32                        result = SPI_OK;

   /* Initialization as in polled mode */
   spi_init_ptr = (MCF5XXX_QSPI_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
   result = _mcf5xxx_qspi_polled_init(spi_init_ptr,
                                     &(int_io_dev_ptr->DEV_INFO_PTR),
                                     open_name_ptr);
   if (result)
   {
      return result;
   }
   
   result = _bsp_get_qspi_vector(spi_init_ptr->CHANNEL);
   if (0 == result)
   {
      _mem_free (int_io_dev_ptr->DEV_INFO_PTR);
      int_io_dev_ptr->DEV_INFO_PTR = NULL;
      return MQX_INVALID_VECTORED_INTERRUPT;
   }
   
   io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   
   /* Allocate buffers */
   io_info_ptr->RX_BUFFER = (pointer)_mem_alloc_system(spi_init_ptr->RX_BUFFER_SIZE & (~ 1));
   if (NULL == io_info_ptr->RX_BUFFER) 
   {
      _mem_free (int_io_dev_ptr->DEV_INFO_PTR);
      int_io_dev_ptr->DEV_INFO_PTR = NULL;
      return MQX_OUT_OF_MEMORY;
   }
   io_info_ptr->TX_BUFFER = (pointer)_mem_alloc_system(spi_init_ptr->TX_BUFFER_SIZE & (~ 1));
   if (NULL == io_info_ptr->TX_BUFFER) 
   {
      _mem_free (int_io_dev_ptr->DEV_INFO_PTR);
      int_io_dev_ptr->DEV_INFO_PTR = NULL;
      _mem_free (io_info_ptr->RX_BUFFER);
      io_info_ptr->RX_BUFFER = NULL;
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type(io_info_ptr->RX_BUFFER,MEM_TYPE_IO_SPI_IN_BUFFER);       
   _mem_set_type(io_info_ptr->TX_BUFFER,MEM_TYPE_IO_SPI_OUT_BUFFER);       
   
   /* Install ISR */ 
   io_info_ptr->OLD_ISR_DATA = _int_get_isr_data(result);
   io_info_ptr->OLD_ISR = _int_install_isr(result, _mcf5xxx_qspi_int_isr, int_io_dev_ptr);
   
   return SPI_OK; 
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_int_deinit  
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes the SPI module 
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_int_deinit
   (
      /* [IN] The address of the device specific information */
      IO_SPI_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The address of the channel specific information */
      MCF5XXX_QSPI_INFO_STRUCT_PTR io_info_ptr
   )
{
   VMCF5XXX_QSPI_STRUCT_PTR        qspi_ptr;
   MCF5XXX_QSPI_INIT_STRUCT_PTR    qspi_init_ptr;
   uint_32                         index;
   
   if ((NULL == io_info_ptr) || (NULL == int_io_dev_ptr)) 
   {
      return SPI_ERROR_DEINIT_FAILED;
   }
   
   /* Disable and clear SPI */
   qspi_ptr = io_info_ptr->QSPI_PTR;
   qspi_ptr->QIR = MCF5XXX_QSPI_QIR_WCEF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_SPIF;
   qspi_ptr->QWR = MCF5XXX_QSPI_QWR_HALT | MCF5XXX_QSPI_QWR_CSIV | MCF5XXX_QSPI_QWR_NEWQP(0) | MCF5XXX_QSPI_QWR_ENDQP(0);
   while (qspi_ptr->QDLYR & MCF5XXX_QSPI_QDLYR_SPE) 
      {};
   qspi_ptr->QIR = MCF5XXX_QSPI_QIR_WCEF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_SPIF;
   
   /* Disable all chip selects */
   for (index = 0; index < MCF5XXX_QSPI_CS_COUNT; index++)
   {
      if ((NULL != io_info_ptr->CS_CALLBACK[index]) && (0 != (io_info_ptr->CS_ACTIVE & (1 << index))))
      {
         io_info_ptr->CS_CALLBACK[index] (1 << index, 1, io_info_ptr->CS_USERDATA[index]);
      }                
   }
   io_info_ptr->CS_ACTIVE = 0;
   
   /* Return original interrupt vector */
   qspi_init_ptr = (MCF5XXX_QSPI_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
   _int_install_isr(_bsp_get_qspi_vector(qspi_init_ptr->CHANNEL), io_info_ptr->OLD_ISR, io_info_ptr->OLD_ISR_DATA);

   /* Release buffers */
   _mem_free(int_io_dev_ptr->DEV_INFO_PTR);
   int_io_dev_ptr->DEV_INFO_PTR = NULL;
   _mem_free(io_info_ptr->RX_BUFFER);
   io_info_ptr->RX_BUFFER = NULL;
   _mem_free(io_info_ptr->TX_BUFFER);
   io_info_ptr->TX_BUFFER = NULL;
      
   return SPI_OK;
}

/*FUNCTION****************************************************************
*
* Function Name    : _mcf5xxx_qspi_int_enable
* Returned Value   : MQX error code
* Comments         :
*    This function enables receive and error interrupt.
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_int_enable
   ( 
   /* [IN] The address of the channel specific information */
      MCF5XXX_QSPI_INFO_STRUCT_PTR io_info_ptr
   )
{

   if (NULL == io_info_ptr)   
   {
      return SPI_ERROR_INVALID_PARAMETER;   
   }

   _bsp_int_init((PSP_INTERRUPT_TABLE_INDEX)_bsp_get_qspi_vector(io_info_ptr->INIT.CHANNEL), BSP_QSPI_INT_LEVEL, BSP_QSPI_INT_SUBLEVEL, TRUE);

   return SPI_OK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_int_rx
* Returned Value   : Returns the number of bytes received
* Comments         : 
*   Reads the data into provided array.
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_int_rx
   (
      /* [IN] The address of the device specific information */
      IO_SPI_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The array characters are to be read from */
      uchar_ptr                    buffer,
      
      /* [IN] Number of char's to transmit */
      int_32                       size
   )
{
   MCF5XXX_QSPI_INFO_STRUCT_PTR    io_info_ptr;
   VMCF5XXX_QSPI_STRUCT_PTR        qspi_ptr;
   uint_32                         num, index;
   uchar_ptr                       rx_ptr;

   io_info_ptr  = int_io_dev_ptr->DEV_INFO_PTR;
   qspi_ptr = io_info_ptr->QSPI_PTR;

   /* Check whether new data in rx buffer */
   rx_ptr = (uchar_ptr)(io_info_ptr->RX_BUFFER);
   for (num = 0; num < size; num++) 
   {
      index = io_info_ptr->RX_OUT;
      if (index == io_info_ptr->RX_IN) break;
      *buffer++ = rx_ptr[index++];
      if (index >= io_info_ptr->INIT.RX_BUFFER_SIZE) index = 0;
      io_info_ptr->RX_OUT = index;
   }
   index = size - num;

   if (0 != index)
   {
      /* Not enough data, assert chip selects and enable further transfer, if none */
      io_info_ptr->RX_REQUEST = index;
      if (0 == (qspi_ptr->QIR & MCF5XXX_QSPI_QIR_SPIFE))
      {
         if (io_info_ptr->CS ^ io_info_ptr->CS_ACTIVE)
         {
             for (index = 0; index < MCF5XXX_QSPI_CS_COUNT; index++)
             {
                if ((0 != ((io_info_ptr->CS ^ io_info_ptr->CS_ACTIVE) & (1 << index))) && (NULL != io_info_ptr->CS_CALLBACK[index]))
                {
                   io_info_ptr->CS_CALLBACK[index] (1 << index, (io_info_ptr->CS_ACTIVE >> index) & 1, io_info_ptr->CS_USERDATA[index]);
                }
             }
             io_info_ptr->CS_ACTIVE = io_info_ptr->CS;
         }
         _mcf5xxx_qspi_int_isr (int_io_dev_ptr);
         qspi_ptr->QIR |= MCF5XXX_QSPI_QIR_SPIFE;
      }
   }
   return num;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_int_tx
* Returned Value   : return number of byte transmitted
* Comments         : 
*   Writes the provided data into trasmit buffer
*
*END*********************************************************************/
static uint_32 _mcf5xxx_qspi_int_tx
   (
      /* [IN] The address of the device specific information */
      IO_SPI_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] The array to store data */
      uchar_ptr                    buffer,
      
      /* [IN] Number of char's to transmit */
      int_32                       size
   )
{
   MCF5XXX_QSPI_INFO_STRUCT_PTR    io_info_ptr;
   VMCF5XXX_QSPI_STRUCT_PTR        qspi_ptr;
   uint_32                         num, index, tmp;
   uchar_ptr                       tx_ptr;
    
   io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   qspi_ptr = io_info_ptr->QSPI_PTR;

   /* Fill new data into transmit buffer */
   tx_ptr = (uchar_ptr)(io_info_ptr->TX_BUFFER);
   index = io_info_ptr->TX_IN;
   for (num = 0; num < size; num++) 
   {
      tmp = index + 1;
      if (tmp >= io_info_ptr->INIT.TX_BUFFER_SIZE) tmp = 0;
      if (tmp == io_info_ptr->TX_OUT) break;
      tx_ptr[index] = *buffer++;
      index = tmp;
   }
   io_info_ptr->TX_IN = index;
   
   if (0 != num) 
   {
      /* At least one byte to transmit, assert chip selects and enable transfer, if none */
      if (0 == (qspi_ptr->QIR & MCF5XXX_QSPI_QIR_SPIFE))
      {
         if (io_info_ptr->CS ^ io_info_ptr->CS_ACTIVE)
         {
             for (index = 0; index < MCF5XXX_QSPI_CS_COUNT; index++)
             {
                if ((0 != ((io_info_ptr->CS ^ io_info_ptr->CS_ACTIVE) & (1 << index))) && (NULL != io_info_ptr->CS_CALLBACK[index]))
                {
                   io_info_ptr->CS_CALLBACK[index] (1 << index, (io_info_ptr->CS_ACTIVE >> index) & 1, io_info_ptr->CS_USERDATA[index]);
                }
             }
             io_info_ptr->CS_ACTIVE = io_info_ptr->CS;
         }
         _mcf5xxx_qspi_int_isr (int_io_dev_ptr);
         qspi_ptr->QIR |= MCF5XXX_QSPI_QIR_SPIFE;
      }
   }
   return num;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf5xxx_qspi_int_isr
* Returned Value   : SPI interrupt routine
* Comments         : 
*   Reads/writes bytes transmitted from/to buffers.
*
*END*********************************************************************/
static void _mcf5xxx_qspi_int_isr
   (
      /* [IN] The address of the device specific information */
      pointer                   parameter
   )
{
   MCF5XXX_QSPI_INFO_STRUCT_PTR io_info_ptr;
   VMCF5XXX_QSPI_STRUCT_PTR     qspi_ptr;
   uint_32                      state;
   uint_16                      index, tmp;
   boolean                      tx_and_rx;
   uint_16                      reg_tmp;
   
   tx_and_rx = (((IO_SPI_INT_DEVICE_STRUCT_PTR)parameter)->FLAGS & SPI_FLAG_FULL_DUPLEX) != 0;
   io_info_ptr = ((IO_SPI_INT_DEVICE_STRUCT_PTR)parameter)->DEV_INFO_PTR;
   qspi_ptr = (VMCF5XXX_QSPI_STRUCT_PTR)(io_info_ptr->QSPI_PTR);
   
   /* Read interrupt state */
   state = qspi_ptr->QIR;
   qspi_ptr->QIR |= MCF5XXX_QSPI_QIR_SPIF | MCF5XXX_QSPI_QIR_ABRT | MCF5XXX_QSPI_QIR_WCEF;
   io_info_ptr->STATS.INTERRUPTS++;

   /* Receive */
   if (state & MCF5XXX_QSPI_QIR_SPIF) 
   {
      qspi_ptr->QAR = 0x0010;
      tmp = qspi_ptr->QDR;
      if (io_info_ptr->ONTHEWAY > 0) io_info_ptr->ONTHEWAY--;

      /* If request for receive and receive allowed (full duplex or first byte skipped already) */
      if ((tx_and_rx) || ((1 == io_info_ptr->RECEIVING) && (io_info_ptr->RX_REQUEST > 0)))
      {
         /* Actual receive into buffer, if overflow, incoming bytes are thrown away */
         index = io_info_ptr->RX_IN + 1;
         if (index >= io_info_ptr->INIT.RX_BUFFER_SIZE) index = 0;
         if (index != io_info_ptr->RX_OUT) 
         {
            if (MCF5XXX_QSPI_QMR_BITS_GET(qspi_ptr->QMR) != 8)
            {
               io_info_ptr->RX_BUFFER[io_info_ptr->RX_IN] = (uint_8)(tmp >> 8);
               io_info_ptr->RX_IN = index++;
               if (index >= io_info_ptr->INIT.RX_BUFFER_SIZE) index = 0;
            }
            io_info_ptr->RX_BUFFER[io_info_ptr->RX_IN] = (uint_8)tmp;
            io_info_ptr->RX_IN = index;
            io_info_ptr->STATS.RX_PACKETS++;
         } else {
            io_info_ptr->STATS.RX_OVERFLOWS++;
         }
         if (io_info_ptr->RX_REQUEST)
         {
            if (--io_info_ptr->RX_REQUEST == 0) 
            {
               io_info_ptr->RECEIVING = 0;
            }
         }
      } 
      /* Skipping bytes sent before receive */
      if (io_info_ptr->RECEIVING > 1) io_info_ptr->RECEIVING--;
   }

   /* Transmit */
   index = io_info_ptr->RX_IN + 1;
   if (index >= io_info_ptr->INIT.RX_BUFFER_SIZE) index = 0;
   if ((tx_and_rx) || (io_info_ptr->RECEIVING == 0)) 
   {
      if (io_info_ptr->TX_OUT != io_info_ptr->TX_IN)
      {
         // Actual transmit
         tmp = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];
         if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
         if (MCF5XXX_QSPI_QMR_BITS_GET(qspi_ptr->QMR) != 8)
         {
            tmp = (tmp << 8) | io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];
            if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
         }
         qspi_ptr->QAR = 0x0020;
         qspi_ptr->QDR = (MCF5XXX_QSPI_QDR_CONT | MCF5XXX_QSPI_QDR_BITSE | MCF5XXX_QSPI_QDR_CS(~ io_info_ptr->CS)) & 0xFF00;
         qspi_ptr->QAR = 0x0000;
         qspi_ptr->QDR = tmp;
         reg_tmp = qspi_ptr->QWR & (~ (MCF5XXX_QSPI_QWR_NEWQP(0xF) | MCF5XXX_QSPI_QWR_ENDQP(0xF)));
         qspi_ptr->QWR = reg_tmp | MCF5XXX_QSPI_QWR_NEWQP(0) | MCF5XXX_QSPI_QWR_ENDQP(0);
         qspi_ptr->QDLYR |= MCF5XXX_QSPI_QDLYR_SPE;
         /* If keeping CS low is needed between transfers */
         if (io_info_ptr->CSIV_ACTIVE)
         {
             /* CS inactive low for tranfers longer than 16 frames */
             qspi_ptr->QWR &= (~ MCF5XXX_QSPI_QWR_CSIV);
         }
         io_info_ptr->STATS.TX_PACKETS++;
         io_info_ptr->ONTHEWAY++;            
      } 
      else 
      {
         if ((index != io_info_ptr->RX_OUT) && (io_info_ptr->RX_REQUEST > 0))
         {
            // Dummy transmit, setup receive
            qspi_ptr->QAR = 0x0020;
            qspi_ptr->QDR = (MCF5XXX_QSPI_QDR_CONT | MCF5XXX_QSPI_QDR_BITSE | MCF5XXX_QSPI_QDR_CS(~ io_info_ptr->CS)) & 0xFF00;
            qspi_ptr->QAR = 0x0000;
            qspi_ptr->QDR = 0xFFFF;
            reg_tmp = qspi_ptr->QWR & (~ (MCF5XXX_QSPI_QWR_NEWQP(0xF) | MCF5XXX_QSPI_QWR_ENDQP(0xF)));
            qspi_ptr->QWR = reg_tmp | MCF5XXX_QSPI_QWR_NEWQP(0) | MCF5XXX_QSPI_QWR_ENDQP(0);
            qspi_ptr->QDLYR |= MCF5XXX_QSPI_QDLYR_SPE;
            /* If keeping CS low is needed between transfers */
            if (io_info_ptr->CSIV_ACTIVE)
            {
                /* CS inactive low for tranfers longer than 16 frames */
                qspi_ptr->QWR &= (~ MCF5XXX_QSPI_QWR_CSIV);
            }
            io_info_ptr->ONTHEWAY++;
            io_info_ptr->RECEIVING = io_info_ptr->ONTHEWAY;
         } 
         else
         {
            // No reason for transmit, block transmit interrupt
            qspi_ptr->QIR &= (~ MCF5XXX_QSPI_QIR_SPIFE);
         }
      }
   } 
   else 
   {
      if ((index != io_info_ptr->RX_OUT) && (io_info_ptr->RX_REQUEST > io_info_ptr->ONTHEWAY - (io_info_ptr->RECEIVING - 1)))
      {
         // Dummy transmit for receiving
         qspi_ptr->QAR = 0x0020;
         qspi_ptr->QDR = (MCF5XXX_QSPI_QDR_CONT | MCF5XXX_QSPI_QDR_BITSE | MCF5XXX_QSPI_QDR_CS(~ io_info_ptr->CS)) & 0xFF00;
         qspi_ptr->QAR = 0x0000;
         qspi_ptr->QDR = 0xFFFF;
         reg_tmp = qspi_ptr->QWR & (~ (MCF5XXX_QSPI_QWR_NEWQP(0xF) | MCF5XXX_QSPI_QWR_ENDQP(0xF)));
         qspi_ptr->QWR = reg_tmp | MCF5XXX_QSPI_QWR_NEWQP(0) | MCF5XXX_QSPI_QWR_ENDQP(0);
         qspi_ptr->QDLYR |= MCF5XXX_QSPI_QDLYR_SPE;
         /* If keeping CS low is needed between transfers */
         if (io_info_ptr->CSIV_ACTIVE)
         {
             /* CS inactive low for tranfers longer than 16 frames */
             qspi_ptr->QWR &= (~ MCF5XXX_QSPI_QWR_CSIV);
         }
         io_info_ptr->ONTHEWAY++;
      } 
      else
      {
         // No reason for transmit, block transmit interrupt
         qspi_ptr->QIR &= (~ MCF5XXX_QSPI_QIR_SPIFE);
      }
   }
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/rtcslog0.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcslog0.c$
* $Version : 3.7.9.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the RTCS logging functions.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"

#if RTCSCFG_LOGGING
#if RTCSCFG_LOG_SOCKET_API || RTCSCFG_LOG_PCB || RTCSCFG_LOGGING
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_log
* Returned Value  : void
* Comments  :  Logs an RTCS event
*
*END*-----------------------------------------------------------------*/

void RTCS_log
   (
      uint_32     logtype,    /* [IN] specifies the type of log entry */
         
      uint_32     p1,         /* [IN] first parameter */
      uint_32     p2,         /* [IN] second parameter */
      uint_32     p3,         /* [IN] third parameter */
      uint_32     p4,         /* [IN] fourth parameter */
      uint_32     p5          /* [IN] fifth parameter */
   )
{ /* Body */
   RTCS_DATA_PTR rtcs = RTCS_get_data();
   uint_32       i;

   switch (logtype) {
   case RTCSLOG_TYPE_FNENTRY:
   case RTCSLOG_TYPE_FNEXIT:
      if (!(rtcs->RTCS_LOG_CONTROL & RTCS_LOGCTRL_FUNCTION)) {
         return;
      } /* Endif */
      break;

   case RTCSLOG_TYPE_PCB:
      if (!(rtcs->RTCS_LOG_CONTROL & RTCS_LOGCTRL_PCB)) {
         return;
      } /* Endif */
      for (i = 0; i < RTCSLOG_PROT_MAX; i++) {
         if (rtcs->RTCS_LOG_PCB[i] == (p1 & 0xFFFF)) {
            break;
         } /* Endif */
      } /* Endfor */
      if (i == RTCSLOG_PROT_MAX) {
         return;
      } /* Endif */
      break;

   case RTCSLOG_TYPE_TIMER:
      if (!(rtcs->RTCS_LOG_CONTROL & RTCS_LOGCTRL_TIMER)) {
         return;
      } /* Endif */
      for (i = 0; i < RTCSLOG_PROT_MAX; i++) {
         if (rtcs->RTCS_LOG_TIMER[i] == (p1 & 0xFFFF)) {
            break;
         } /* Endif */
      } /* Endfor */
      if (i == RTCSLOG_PROT_MAX) {
         return;
      } /* Endif */
      break;

   default:
      return;
   } /* Endswitch */

   RTCS_log_internal(logtype,p1,p2,p3,p4,p5);

} /* Endbody */
#endif
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/posix.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: posix.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This include file provides defines to allow for MQX2.40 functions to
*   be called with POSIX compliant names.
*
*END************************************************************************/
#ifndef __posix_h__
#define __posix_h__ 1

#define errno        _task_errno

#define EOK          MQX_EOK         
#define E2BIG        MQX_E2BIG       
#define EACCES       MQX_EACCES      
#define EAGAIN       MQX_EAGAIN      
#define EBADF        MQX_EBADF       
#define EBADMSG      MQX_EBADMSG     
#define EBUSY        MQX_EBUSY       
#define ECANCELED    MQX_ECANCELED   
#define ECHILD       MQX_ECHILD      
#define EDEADLK      MQX_EDEADLK     
#define EDOM         MQX_EDOM        
#define EEXIST       MQX_EEXIST      
#define EFAULT       MQX_EFAULT      
#define EFBIG        MQX_EFBIG       
#define EINPROGRESS  MQX_EINPROGRESS 
#define EINTR        MQX_EINTR       
#define EINVAL       MQX_EINVAL      
#define EIO          MQX_EIO         
#define EISDIR       MQX_EISDIR      
#define EMFILE       MQX_EMFILE      
#define EMLINK       MQX_EMLINK      
#define EMSGSIZE     MQX_EMSGSIZE    
#define ENAMETOOLONG MQX_ENAMETOOLONG
#define ENFILE       MQX_ENFILE      
#define ENODEV       MQX_ENODEV      
#define ENOENT       MQX_ENOENT      
#define ENOEXEC      MQX_ENOEXEC     
#define ENOLCK       MQX_ENOLCK      
#define ENOMEM       MQX_ENOMEM      
#define ENOSPC       MQX_ENOSPC      
#define ENOSYS       MQX_ENOSYS      
#define ENOTDIR      MQX_ENOTDIR     
#define ENOTEMPTY    MQX_ENOTEMPTY   
#define ENOTSUP      MQX_ENOTSUP     
#define ENOTTY       MQX_ENOTTY      
#define ENXIO        MQX_ENXIO       
#define EPERM        MQX_EPERM       
#define EPIPE        MQX_EPIPE       
#define ERANGE       MQX_ERANGE      
#define EROFS        MQX_EROFS       
#define ESPIPE       MQX_ESPIPE      
#define ESRCH        MQX_ESRCH       
#define ETIMEDOUT    MQX_ETIMEDOUT   
#define EXDEV        MQX_EXDEV       

#define pthread_mutex_create_component     _mutex_create_component
#define pthread_mutex_destroy              _mutex_destroy
#define pthread_mutex_getprioceiling       _mutex_get_max_priority
#define pthread_mutex_setprioceiling       _mutex_set_max_priority
#define pthread_mutex_init                 _mutex_init
#define pthread_mutex_lock                 _mutex_lock
#define pthread_mutex_try_lock             _mutex_try_lock
#define pthread_mutex_unlock               _mutex_unlock
#define pthread_mutex_task_wait_count      _mutex_get_wait_count
#define pthread_mutexattr_destroy          _mutatr_destroy
#define pthread_mutexattr_getlimitspin     _mutatr_get_spin_limit
#define pthread_mutexattr_setlimitspin     _mutatr_set_spin_limit
#define pthread_mutexattr_getprioceiling   _mutatr_get_max_priority
#define pthread_mutexattr_setprioceiling   _mutatr_set_max_priority
#define pthread_mutexattr_getprotocol      _mutatr_get_protocol
#define pthread_mutexattr_setprotocol      _mutatr_set_protocol
#define pthread_mutexattr_getwaitingpolicy _mutatr_get_policy
#define pthread_mutexattr_setwaitingpolicy _mutatr_set_policy
#define pthread_mutexattr_init             _mutatr_init

#define pthread_mutex_t                    MUTEX_STRUCT
#define pthread_mutex_attr_t               MUTEX_ATTR_STRUCT

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_1588.h<|end_filename|>
/**HEADER**********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*
*******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* $FileName: macnet_1588.h$
* $Version : 3.8.7.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   This file contains the definitions of constants,IOCTL'S and structures
*   required for the PTP functionality.
*
*END**************************************************************************/
#ifndef macnet_1588_h
#define macnet_1588_h 1

/* IOCTL calls */
#define MACNET_PTP_GET_TX_TIMESTAMP             _IO(IO_TYPE_MEDIACTL_PTP,0x01)
#define MACNET_PTP_GET_RX_TIMESTAMP             _IO(IO_TYPE_MEDIACTL_PTP,0x02)
#define MACNET_PTP_GET_CURRENT_TIME             _IO(IO_TYPE_MEDIACTL_PTP,0x03)
#define MACNET_PTP_SET_RTC_TIME                 _IO(IO_TYPE_MEDIACTL_PTP,0x04)
#define MACNET_PTP_SET_COMPENSATION             _IO(IO_TYPE_MEDIACTL_PTP,0x05)
#define MACNET_PTP_FLUSH_TIMESTAMP              _IO(IO_TYPE_MEDIACTL_PTP,0x06)
#define MACNET_PTP_GET_ORIG_COMP                _IO(IO_TYPE_MEDIACTL_PTP,0x07)
#define MACNET_PTP_REGISTER_ETHERTYPE_PTPV2     _IO(IO_TYPE_MEDIACTL_PTP,0x08)
#define MACNET_PTP_SEND_ETHERTYPE_PTPV2_PCK     _IO(IO_TYPE_MEDIACTL_PTP,0x09)
#define MACNET_PTP_RECV_ETHERTYPE_PTPV2_PCK     _IO(IO_TYPE_MEDIACTL_PTP,0x0A)
#define MACNET_PTP_IS_IN_INBAND_MODE            _IO(IO_TYPE_MEDIACTL_PTP,0x0B)
#define MACNET_PTP_UNREGISTER_ETHERTYPE_PTPV2   _IO(IO_TYPE_MEDIACTL_PTP,0x0C)

#define MACNET_PTP_RX_TIMESTAMP_SYNC            0x0
#define MACNET_PTP_RX_TIMESTAMP_DEL_REQ         0x1
#define MACNET_PTP_RX_TIMESTAMP_PDELAY_REQ      0x2
#define MACNET_PTP_RX_TIMESTAMP_PDELAY_RESP     0x3

#define MQX1588_PTP_ETHERTYPE_1588              0x88F7

#define MACNET_PTP_EVENT_MSG_FRAME_SIZE         0x56
#define MACNET_PTP_EVENT_MSG_PTP_SIZE           0x2C
#define MACNET_PTP_INBAND_SEC_OFFS              0x00
#define MACNET_PTP_INBAND_NANOSEC_OFFS          0x08

/* PTP message version */
#define MACNET_PTP_MSG_VER_1                    1
#define MACNET_PTP_MSG_VER_2                    2

/* PTP standard time representation structure */
typedef struct {
	uint_64 SEC;	/* seconds */
	uint_32 NSEC;	/* nanoseconds */
}MACNET_PTP_TIME;

/* interface for PTP driver command MACNET_PTP_GET_RX_TIMESTAMP/MACNET_PTP_GET_TX_TIMESTAMP */
typedef struct {
	/* PTP version */
	uint_8 VERSION;
	/* PTP source port ID */
	uint_8 SPID[10];
	/* PTP sequence ID */
	uint_16 SEQ_ID;
	/* PTP message type */
	uint_8 MESSAGE_TYPE;
	/* PTP timestamp */
	MACNET_PTP_TIME TS;
}MACNET_PTP_TS_DATA;

/* interface for PTP driver command MACNET_PTP_SET_RTC_TIME/MACNET_PTP_GET_CURRENT_TIME */
typedef struct {
	MACNET_PTP_TIME RTC_TIME;
}MACNET_PTP_RTC_TIME;

/* interface for PTP driver command MACNET_PTP_SET_COMPENSATION */
typedef struct {
	int_32 DRIFT;
}MACNET_PTP_SET_COMP;

/* interface for PTP driver command MACNET_PTP_GET_ORIG_COMP */
typedef struct {
	/* the initial compensation value */
	uint_32 DW_ORIGCOMP;
	/* the minimum compensation value */
	uint_32 DW_MINCOMP;
	/*the max compensation value*/
	uint_32 DW_MAXCOMP;
	/*the min drift applying min compensation value in ppm*/
	uint_32 DW_MINDRIFT;
	/*the max drift applying max compensation value in ppm*/
	uint_32 DW_MAXDRIFT;
}MACNET_PTP_GET_COMP;

/* interface for PTP driver command MACNET_PTP_SEND_ETHERTYPE_PTPV2_PCK */
typedef struct {
	/* pointer to the PTP message */
	uint_8* PTP_MSG;
	/* size of the PTP message */
	uint_16 LENGTH;
	/* destination MAC address */
	_enet_address DEST_MAC;
}MACNET_PTP_ETHERTYPE_PCK;


#endif
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/compiler/iar/comp.h<|end_filename|>
/**HEADER*********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* $FileName: comp.h$
* $Version : 3.8.14.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This file defines the IAR ARM build tools specific macros for MQX
*
*END*************************************************************************/
#ifndef __comp_h__
#define __comp_h__   1

#include <intrinsics.h>

#ifdef __cplusplus
extern "C" {
#endif

#define _ASM_NOP()    asm("nop")
#define _ASM_STOP(x)  asm("stop #(" #x ")")
#define _ASM_WFI()    asm("wfi")
#define _ASM_SLEEP    _ASM_WFI

#if PSP_MQX_CPU_IS_ARM_CORTEX_M4
#define _PSP_SET_ENABLE_SR(x)   __set_BASEPRI(x)
#define _PSP_SET_DISABLE_SR(x)  _PSP_SET_ENABLE_SR(x)
#elif PSP_MQX_CPU_IS_ARM_CORTEX_M0
#define _PSP_SET_ENABLE_SR(x)   __asm volatile ("cpsie i")
#define _PSP_SET_DISABLE_SR(x)  __asm volatile ("cpsid i")
#else
#error Invalid platform selected
#endif

#define _PSP_SYNC()


/* Kinetis User mode definitions */
#if MQX_ENABLE_USER_MODE
#define KERNEL_ACCESS  _Pragma("location=\".kernel_data\"")
#define USER_RW_ACCESS _Pragma("location=\".rwuser\"")
#define USER_RO_ACCESS _Pragma("location=\".rouser\"")
#define USER_NO_ACCESS _Pragma("location=\".nouser\"")

#else /* MQX_ENABLE_USER_MODE */

#define KERNEL_ACCESS
#define USER_RW_ACCESS
#define USER_RO_ACCESS
#define USER_NO_ACCESS

#endif /* MQX_ENABLE_USER_MODE */

/*
 *      DATATYPE MODIFIERS
 */

#define _WEAK_SYMBOL(x)     __weak x
#define _WEAK_FUNCTION(x)   __weak x

/* compiler dependent structure packing option */
#define PACKED_STRUCT_BEGIN __packed
#define PACKED_STRUCT_END

/* compiler dependent union packing option */
#define PACKED_UNION_BEGIN
#define PACKED_UNION_END

#ifdef __cplusplus
}
#endif

#endif   /* __comp_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwadc/lwadc_vadc.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2011 Embedded Access Inc
* All Rights Reserved
*
****************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwadc_vadc.c$
* $Version : 3.8.1.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This file contains the ADC driver CPU specific functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <lwadc_vadc_prv.h>

/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_restart
 * Returned Value   :
 * Comments         :
 * This function restarts the ADC after a parameter change.
 *
 *END*----------------------------------------------------------------------*/

static ADC_CONTEXT_PTR         context_ptr;

static void _lwadc_restart(LWADC_STRUCT_PTR lwadc_ptr)
{
    ADC_MemMapPtr adc_ptr = _bsp_get_adc_base_address(context_ptr->init_ptr->ADC_NUMBER);
    uint_32                 adc_status;
    _mqx_int ch_num;
    adc_ptr->HC1 |= ADC_HC1_AIEN1_MASK;
}

/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_init
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function initializes the ADC device with global parameters
 *    (conversion frequency, resolution, number format). It does  not start
 *    any conversions.
 *
 *END*----------------------------------------------------------------------*/

static ADC_CONTEXT adc_context[ADC_NUM_DEVICES] = {0};
uint_32 adc_max_frq;

uint_32  _lwadc_init( const LWADC_INIT_STRUCT *  init_ptr)
{
    ADC_MemMapPtr adc_ptr;
    uint_8  adc_max_frq_index;

    /* This table is made from datasheet values for ADC module in Kinetis */
    const static uint_32 adc_max_frq_table[] = {
        2500000,  /* 2.5 MHz  for low power,    normal speed, 12b resolution */
        5000000,  /* 5.0 MHz  for low power,    normal speed, lower resolution */
        5000000,  /* 5.0 MHz  for low power,    high speed,   12b resolution */
        8000000,  /* 8.0 MHz  for low power,    high speed,   lower resolution */
        8000000,  /* 8.0 MHz  for normal power, normal speed, 12b resolution */
        12000000, /* 12.0 MHz for normal power, normal speed, lower resolution */
        12000000, /* TBD MHz  for normal power, high speed,   12b resolution */
        22000000, /* TBD MHz  for normal power, high speed,   lower resolution */
    };
    #if PSP_HAS_DEVICE_PROTECTION
    if (!_bsp_adc_enable_access(init_ptr->ADC_NUMBER)) {
        return FALSE;
    }
    #endif

    adc_ptr = _bsp_get_adc_base_address(init_ptr->ADC_NUMBER);
    if (adc_ptr==NULL) {
         return FALSE;
    }

    context_ptr =  &adc_context[init_ptr->ADC_NUMBER];
    context_ptr->channels = 0;
    context_ptr->default_numerator   = init_ptr->reference;
    context_ptr->default_denominator = LWADC_RESOLUTION_DEFAULT;
    
    /* First, use 3 bit mask to create index to the max. frq. table */
    adc_max_frq_index = 0;
    switch (context_ptr->default_denominator) {
        case LWADC_RESOLUTION_12BIT:
            adc_max_frq_index |= 0x01;
            break;
        case LWADC_RESOLUTION_10BIT:
        case LWADC_RESOLUTION_8BIT:
            break;
        default:
            return FALSE; /* bad resolution set */
    }
    if (init_ptr->SPEED == LWADC_HSC_HIGH)
        adc_max_frq_index |= 0x02;
    if (init_ptr->POWER == LWADC_LPC_NORMAL)
        adc_max_frq_index |= 0x04;
    adc_max_frq = adc_max_frq_table[adc_max_frq_index];
    
    /* set AD clock to be as fast as possible */
     switch (init_ptr->CLOCK_SOURCE) {
         case LWADC_CLK_BUSCLK_ANY:
             if (init_ptr->CLOCK_DIV == LWADC_DIV_ANY) {
                 if(BSP_BUS_CLOCK <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_1 | LWADC_CFG_ADICLK_BUSCLK;
                 else if ((BSP_BUS_CLOCK / 2) <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_2 | LWADC_CFG_ADICLK_BUSCLK;
                 else if ((BSP_BUS_CLOCK / 4) <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_4 | LWADC_CFG_ADICLK_BUSCLK;
                 else if ((BSP_BUS_CLOCK / 8) <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_8 | LWADC_CFG_ADICLK_BUSCLK;
                 else if ((BSP_BUS_CLOCK / 16) <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_8 | LWADC_CFG_ADICLK_BUSCLK2;
                 else
                     return FALSE; /* cannot set ADC clock to be less than adc_max_frq */
             }
             else {
                 if ((BSP_BUS_CLOCK / (1 << init_ptr->CLOCK_DIV)) <= adc_max_frq)
                     adc_ptr->CFG = ADC_CFG_ADIV(init_ptr->CLOCK_DIV) | LWADC_CFG_ADICLK_BUSCLK;
                 else if ((BSP_BUS_CLOCK / 2 / (1 << init_ptr->CLOCK_DIV)) <= adc_max_frq)
                     adc_ptr->CFG = ADC_CFG_ADIV(init_ptr->CLOCK_DIV) | LWADC_CFG_ADICLK_BUSCLK2;
                 else
                     return FALSE; /* such clock combination is too fast for ADC */
             }
             break;

         case LWADC_CLK_BUSCLK:
             if (init_ptr->CLOCK_DIV == LWADC_DIV_ANY) {
                 if (BSP_BUS_CLOCK <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_1 | LWADC_CFG_ADICLK_BUSCLK;
                 else if ((BSP_BUS_CLOCK / 2) <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_2 | LWADC_CFG_ADICLK_BUSCLK;
                 else if ((BSP_BUS_CLOCK / 4) <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_4 | LWADC_CFG_ADICLK_BUSCLK;
                 else if ((BSP_BUS_CLOCK / 8) <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_8 | LWADC_CFG_ADICLK_BUSCLK;
                 else
                     return FALSE; /* cannot set ADC clock to be less than ADC max. frequency */
             }
             else if ((BSP_BUS_CLOCK / (1 << init_ptr->CLOCK_DIV)) <= adc_max_frq)
                 adc_ptr->CFG = ADC_CFG_ADIV(init_ptr->CLOCK_DIV) | LWADC_CFG_ADICLK_BUSCLK;
             else
                 return FALSE; /* such clock combination is too fast for ADC */
             break;

         case LWADC_CLK_BUSCLK2:
             if (init_ptr->CLOCK_DIV == LWADC_DIV_ANY) {
                 if ((BSP_BUS_CLOCK / 16) <= adc_max_frq)
                     adc_ptr->CFG = LWADC_CFG_ADIV_8 | LWADC_CFG_ADICLK_BUSCLK2;
                 if ((BSP_BUS_CLOCK / 16) <= adc_max_frq)
                     return FALSE; /* cannot set ADC clock to be less than ADC max. frequency */
             }
             else if ((BSP_BUS_CLOCK / 2 / (1 << init_ptr->CLOCK_DIV)) <= adc_max_frq)
                 adc_ptr->CFG = ADC_CFG_ADIV(init_ptr->CLOCK_DIV) | LWADC_CFG_ADICLK_BUSCLK2;
             else
                 return FALSE; /* such clock combination is too fast for ADC */
             break;

         case LWADC_CLK_ALTERNATE:
             if (init_ptr->CLOCK_DIV == LWADC_DIV_ANY)
                 return FALSE; /* alternate clock + any division is not supported now */
             adc_ptr->CFG = ADC_CFG_ADIV(init_ptr->CLOCK_DIV) | LWADC_CFG_ADICLK_ALTCLK;
             break;

         case LWADC_CLK_ASYNC:
             if (init_ptr->CLOCK_DIV == LWADC_DIV_ANY)
                 return FALSE; /* async clock + any division is not supported now */
             adc_ptr->CFG = ADC_CFG_ADIV(init_ptr->CLOCK_DIV) | LWADC_CFG_ADICLK_ADACK;
             break;

         default:
             return FALSE; /* invalid clock source */
             
     }
    adc_ptr->CFG |= ADC_CFG_ADLPC_MASK;
    adc_ptr->CFG |= ADC_CFG_MODE(0x02);
    adc_ptr->CFG |= LWADC_CFG_AVGS_32;
    adc_ptr->CFG &= ~ADC_CFG_ADTRG_MASK; /* set SW trigger */
    adc_ptr->GC |= ADC_GC_AVGE_MASK | ADC_GC_ADCO_MASK;
    context_ptr->init_ptr = init_ptr;

    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_init_input
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 * This function prepares and initialize the LWADC_STRUCT
 * with all data it will need later for quick control of the input.
 * The structure initialized here is used in all subsequent calls to any
 * LWADC driver and is uniquely identifying the input.
 * This function calls a BSP supplied function to enable the ADC input pin.
 * It adds the input to the list of channels being converted, and place the
 * ADC in continuous conversion mode if not already in this mode.
 *
 *END*----------------------------------------------------------------------*/

boolean  _lwadc_init_input( LWADC_STRUCT_PTR lwadc_ptr, uint_32 input )
{    
    ADC_MemMapPtr adc_ptr;
    uint_32 device, channel;
    uint32_t source_reg;
    device  = ADC_DEVICE(input);
    channel = ADC_CHANNEL(input);
    
    adc_ptr = _bsp_get_adc_base_address(device);
    source_reg = channel;

    /* Used as a validity check in other _lwadc functions */
    lwadc_ptr->context_ptr = NULL;
    
    /* Make sure channel & device is in range */
    if ((device > ADC_NUM_DEVICES ) ||(channel > ADC_HW_CHANNELS )) {
        return FALSE;
    } 
    adc_ptr->PCTL |=(1<<channel);
    /* Enable ADC I/O Pin */
    if ( _bsp_adc_io_init(input) != IO_OK) {
        return FALSE;
    }

    adc_ptr->HC1 = source_reg;

    /* set channel specific parameters */
    lwadc_ptr->input   = input;
    lwadc_ptr->context_ptr = &adc_context[device];
    lwadc_ptr->numerator   = context_ptr->init_ptr->reference;
    lwadc_ptr->denominator = LWADC_RESOLUTION_DEFAULT;
    /* Set channel to convert */
    _int_disable();
    lwadc_ptr->context_ptr->channels = channel;
    _lwadc_restart(lwadc_ptr);
    _int_enable();
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_read_raw
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function Read the current value of the ADC input and return
 *    the result without applying any scaling.
 *
 *END*----------------------------------------------------------------------*/


boolean _lwadc_read_raw( LWADC_STRUCT_PTR lwadc_ptr, LWADC_VALUE_PTR outSample)
{
    ADC_MemMapPtr adc_ptr = _bsp_get_adc_base_address(context_ptr->init_ptr->ADC_NUMBER);
    LWADC_VALUE sample;
    _mqx_int ch_num;
    if (lwadc_ptr->context_ptr == NULL) {
        return FALSE;
    }
    if ((adc_ptr->GC & ADC_GC_ADCO_MASK) == 0) {
        /* ADC is not in continuous mode. */
        adc_ptr->GC |= ADC_GC_ADCO_MASK;
    }
    sample = adc_ptr->R1;

    *outSample = sample & ADC_CDR_CDATA_MASK;

    /* Clear conversion complete */
    adc_ptr->HC1 &= ~ADC_HC1_AIEN1_MASK; 
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_read
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function Read the current value of the ADC input, applies any
 *    scaling, and return the result.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_read( LWADC_STRUCT_PTR lwadc_ptr, LWADC_VALUE_PTR outSample)
{
    LWADC_VALUE rawSample;

    if (lwadc_ptr->context_ptr == NULL) {
        return FALSE;
    }
    if (_lwadc_read_raw(lwadc_ptr,&rawSample)) {
        *outSample = ((rawSample*lwadc_ptr->numerator) + (lwadc_ptr->denominator>>1))/ lwadc_ptr->denominator;
        return TRUE;
    }

    *outSample = 0;
    return FALSE;
}



/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_wait_next
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function Waits for a new value to be available on the specified ADC input.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_wait_next( LWADC_STRUCT_PTR lwadc_ptr )
{
    ADC_MemMapPtr adc_ptr = _bsp_get_adc_base_address(context_ptr->init_ptr->ADC_NUMBER);
    if (lwadc_ptr->context_ptr == NULL) {
        return FALSE;
    }

    if ((adc_ptr->GC & ADC_GC_ADCO_MASK) == 0) {
        /* ADC is not in continuous mode. */
        adc_ptr->GC |= ADC_GC_ADCO_MASK;
    }
    while((adc_ptr->HS & ADC_HS_COCO1_MASK) == 0){}
    return TRUE;
}



/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_read_average
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function Read the current value of the ADC input, applies any
 *    scaling, and return the result.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_read_average( LWADC_STRUCT_PTR lwadc_ptr, uint_32 num_samples, LWADC_VALUE_PTR outSample)
{
    LWADC_VALUE rawSample,sum = 0;
    uint_32     i;

    if (num_samples > (MAX_UINT_32/LWADC_RESOLUTION_DEFAULT)) {
        return FALSE;
    }

    for (i=0;i<num_samples;i++) {
        if (!_lwadc_wait_next(lwadc_ptr)) {
            return FALSE;
        }

        if (!_lwadc_read_raw(lwadc_ptr,&rawSample)) {
            return FALSE;
        }
        sum += rawSample;
    }
 
    *outSample = (((sum/num_samples)*lwadc_ptr->numerator) + (lwadc_ptr->denominator>>1))/ lwadc_ptr->denominator;
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_set_attribute
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 * This function sets attributes for the specified ADC input. Attributes
 * could include single/differential mode, reference, scaling numerator or
 * denominator, etc.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_set_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute,  uint_32 value)
{
    boolean result = TRUE;
	ADC_MemMapPtr adc_ptr = _bsp_get_adc_base_address(context_ptr->init_ptr->ADC_NUMBER);

    if (lwadc_ptr->context_ptr == NULL) {
        return FALSE;
    }

    switch (attribute) {
        case LWADC_NUMERATOR:
            lwadc_ptr->numerator = value;
            break;

        case LWADC_DENOMINATOR:
            lwadc_ptr->denominator = value;
            break;

        case LWADC_DEFAULT_NUMERATOR:
            lwadc_ptr->context_ptr->default_numerator = value;
            break;

        case LWADC_DEFAULT_DENOMINATOR:
            lwadc_ptr->context_ptr->default_denominator = value;
            break;

        case LWADC_POWER_DOWN:
            if (value) {
                adc_ptr->CFG |= ADC_CFG_ADLPC_MASK;
            } else {
                _int_disable();
                _lwadc_restart(lwadc_ptr);
                _int_enable();
            }
            break;

        case LWADC_FORMAT:
            break;

        case LWADC_FREQUENCY:
            break;

        case LWADC_DIVIDER:
            /* We support a divider, as long as it is 1. */
            result = (value == 1)?TRUE:FALSE;
            break;

        case LWADC_DIFFERENTIAL:
            /* We don't support differential, so return FALSE if asked for it, TRUE otherwise */
            result = !value;
            break;

        case LWADC_INPUT_CONVERSION_ENABLE:
            break;

        default:
            return FALSE;
    }
    return result;
}


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_get_attribute
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function This function gets attributes for the specified ADC input,
 *    or for the ADC module as a whole. Attributes could include
 *    single/differential mode, reference, scaling numerator or denominator, etc.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_get_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute,  uint_32_ptr value_ptr)
{
    ADC_MemMapPtr adc_ptr = _bsp_get_adc_base_address(context_ptr->init_ptr->ADC_NUMBER);
    if ((lwadc_ptr->context_ptr == NULL) || (value_ptr == NULL)) {
        return FALSE;
    }

    switch (attribute) {
        case LWADC_NUMERATOR:
            *value_ptr = lwadc_ptr->numerator;
            break;

        case LWADC_DENOMINATOR:
            *value_ptr = lwadc_ptr->denominator;
            break;

        case LWADC_DEFAULT_NUMERATOR:
            *value_ptr = lwadc_ptr->context_ptr->default_numerator;
            break;

        case LWADC_DEFAULT_DENOMINATOR:
            *value_ptr = lwadc_ptr->context_ptr->default_denominator;
            break;

        case LWADC_POWER_DOWN:
            *value_ptr = (adc_ptr->CFG&ADC_CFG_ADLPC_MASK)?TRUE:FALSE;
            break;

        case LWADC_RESOLUTION:
            *value_ptr = LWADC_RESOLUTION_DEFAULT;
            break;

        case LWADC_REFERENCE:
            *value_ptr = context_ptr->init_ptr->reference;
            break;

        case LWADC_FREQUENCY:
            *value_ptr = adc_max_frq;
            break;

        case LWADC_DIVIDER:
            *value_ptr = 1;
            break;

        case LWADC_DIFFERENTIAL:
            *value_ptr = FALSE;
            break;

        case LWADC_FORMAT:
            *value_ptr = FALSE;
            break;

        case LWADC_INPUT_CONVERSION_ENABLE:
            *value_ptr = FALSE;
            break;

        default:
            return FALSE;
    }
    return TRUE;
}



/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_tixd.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_tixd.c$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*   This file contains the functions for converting between ticks
*   and the xdate structure.
*
*END************************************************************************/

#include "mqx_inc.h"

#if MQX_HAS_TICK

/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_ticks_to_xdate
* Returned Value   : boolean - Returns FALSE if ticks are out of range of 
*                    the xdate structure, TRUE otherwise
* Comments         :
*    This function converts ticks into the xdate structure
*
*END*----------------------------------------------------------------------*/

boolean _psp_ticks_to_xdate
   (
      /*  [IN]  pointer to tick structure  */
      PSP_TICK_STRUCT_PTR  tick_ptr,

      /*  [OUT]  pointer to a xdate structure  */
      MQX_XDATE_STRUCT_PTR xdate_ptr
   )
{ /* Body */
   PSP_TICK_STRUCT        tmp_ticks1;
   PSP_TICK_STRUCT        tmp_ticks2;
   uint_64                seconds;
   uint_64                leftover_ticks;
   KERNEL_DATA_STRUCT_PTR kernel_data;
   uint_32                days,years;
   uint_32                tps, tmp;
   boolean                over_flow;
   uint_16                leap;


   _GET_KERNEL_DATA(kernel_data);

   tps = kernel_data->TICKS_PER_SECOND;

   /* Convert ticks to seconds */
   seconds        = tick_ptr->TICKS[0] / tps;
   leftover_ticks = tick_ptr->TICKS[0] % tps;
      
   /* Convert to minutes */
   tmp = seconds / SECS_IN_MINUTE;
   xdate_ptr->SEC = seconds % SECS_IN_MINUTE;

   /* Convert to hours */
   xdate_ptr->MIN = tmp % MINUTES_IN_HOUR;
   tmp /= MINUTES_IN_HOUR;

   /* Convert to days */
   xdate_ptr->HOUR = tmp % HOURS_IN_DAY;
   days = tmp / HOURS_IN_DAY;


   /* Make an educated quess where to start in table */
   years = days / 366;
   if (years > 511) {
      /* This is out of range of the xdate structure */
      return FALSE;
   } /* Endif */

   xdate_ptr->YEAR = (uint_16)years;
   while (days >= _time_days_before_year_internal[xdate_ptr->YEAR + 1]) {
      xdate_ptr->YEAR++;
   } /* Endwhile */

   /* Jan 1, 1970 was a Thursday */
   xdate_ptr->WDAY  = (uint_16)((days + 3 + 1) % 7);

   /* Calculate the number of days since the beginning of the year */
   days -= _time_days_before_year_internal[xdate_ptr->YEAR];

   xdate_ptr->YEAR += (uint_16)1970;
   xdate_ptr->YDAY  = (uint_16)days;

   /*
   ** Find out if we are in a leap year.
   **
   ** if (the year is a century year not divisible by 400
   ** then it is not a leap year, otherwise if year divisible by
   ** four then it is a leap year
   */

   if ((xdate_ptr->YEAR % (uint_16)100) == (uint_16)0) {

      if ((xdate_ptr->YEAR % (uint_16)400) == (uint_16)0) {
         leap = (uint_16)LEAP_YEAR;
      } else {
         leap = (uint_16)NON_LEAP_YEAR;
      } /* Endif */
         
   } else {

      if ((xdate_ptr->YEAR % (uint_16)4) == (uint_16)0) {
         leap = (uint_16)LEAP_YEAR;
      } else {
         leap = (uint_16)NON_LEAP_YEAR;
      } /* Endif */

   } /* Endif */

   /* calculate the month */
   xdate_ptr->MONTH = days/31;
   while (days >= _time_days_before_month_internal[leap][xdate_ptr->MONTH]) {
      xdate_ptr->MONTH++;
   } /* Endwhile */
   days -= _time_days_before_month_internal[leap][xdate_ptr->MONTH - 1];

   /* calculate the day */
   xdate_ptr->MDAY = (uint_16)(days);

   /* first day is 1*/
   xdate_ptr->MDAY++;

   /* 
   ** Calculate ms, us, ns and ps from remaining ticks
   */
   tmp_ticks1.TICKS[0]    = leftover_ticks;
   tmp_ticks1.HW_TICKS[0] = tick_ptr->HW_TICKS[0];

   /* Calculate milliseconds */
   tmp = _psp_ticks_to_milliseconds_truncate(&tmp_ticks1, &over_flow);
   xdate_ptr->MSEC = (uint_16)tmp;

   _psp_msecs_to_ticks(tmp, &tmp_ticks2);
   PSP_SUB_TICKS(&tmp_ticks1, &tmp_ticks2, &tmp_ticks1);

   if ((tmp_ticks1.TICKS[0] == 0) && (tmp_ticks2.HW_TICKS[0] == 0)) {
      xdate_ptr->USEC = xdate_ptr->NSEC = xdate_ptr->PSEC = 0;
      return TRUE;
   } /* Endif */

   /* Calculate microseconds */
   tmp = _psp_ticks_to_microseconds_truncate(&tmp_ticks1, &over_flow);
   xdate_ptr->USEC = (uint_16)tmp;

   _psp_usecs_to_ticks(tmp, &tmp_ticks2);
   PSP_SUB_TICKS(&tmp_ticks1, &tmp_ticks2, &tmp_ticks1);

   if ((tmp_ticks1.TICKS[0] == 0) && (tmp_ticks2.HW_TICKS[0] == 0)) {
      xdate_ptr->NSEC = xdate_ptr->PSEC = 0;
      return TRUE;
   } /* Endif */

   /* Calculate nanoseconds */
   tmp = _psp_ticks_to_nanoseconds_truncate(&tmp_ticks1, &over_flow);
   xdate_ptr->NSEC = (uint_16)tmp;

   _psp_nsecs_to_ticks(tmp, &tmp_ticks2);
   PSP_SUB_TICKS(&tmp_ticks1, &tmp_ticks2, &tmp_ticks1);

   if ((tmp_ticks1.TICKS[0] == 0) && (tmp_ticks2.HW_TICKS[0] == 0)) {
      xdate_ptr->PSEC = 0;
      return TRUE;
   } /* Endif */

   /* Calculate picoseconds */
   tmp = _psp_ticks_to_microseconds_truncate(&tmp_ticks1, &over_flow);
   xdate_ptr->PSEC = (uint_16)tmp;

   return TRUE;

} /* Endbody */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_vybrid.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_vybrid.c$
* $Version : 3.8.B.3$
* $Date    : Oct-8-2012$
*
* Comments:
*
*   Processor family specific file needed for enet module.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <enet.h>
#include <enetprv.h>
#include <macnet_prv.h>

#if PSP_MQX_CPU_IS_VYBRID_A5
const uint_32 MACNET_vectors[MACNET_DEVICE_COUNT][ENET_NUM_INTS] = {
    {
    	INT_ENET_MAC0,
    },
    {
    	INT_ENET_MAC1,
    }
};
#elif PSP_MQX_CPU_IS_VYBRID_M4
const uint_32 MACNET_vectors[MACNET_DEVICE_COUNT][ENET_NUM_INTS] = {
    {
        NVIC_ENET_MAC0
    },
    {
        NVIC_ENET_MAC1
    }
};
#endif

#if ENETCFG_SUPPORT_PTP
extern uint_64  MACNET_PTP_seconds;
#endif /* ENETCFG_SUPPORT_PTP */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : MACNET_get_base_address  
* Returned Value   : Pointer to desired enem device or NULL if not present
* Comments         :
*    This function returns pointer to base address of address space of the 
*    desired enet device. Returns NULL otherwise.
*
*END*----------------------------------------------------------------------*/

pointer MACNET_get_base_address(uint_32 device) {
    pointer addr = NULL;
    
    switch (device) {
    case 0:
        addr = (pointer)ENET0_BASE_PTR;
        break;
    case 1:
        addr = (pointer)ENET1_BASE_PTR;
        break;
    }
    
    return addr;
}


 
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : MACNET_io_init
* Returned Value   : none
* Comments         :
*    This function performs BSP-specific initialization related to ENET
*
*END*----------------------------------------------------------------------*/

void MACNET_io_init( uint_32	device )
{

   if (device >= MACNET_DEVICE_COUNT) 
      return;

   _bsp_enet_io_init(device);
}

#if ENETCFG_SUPPORT_PTP
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : MACNET_ptp_install_ts_avail_isr
* Returned Value   : none
* Comments         :
*    This function initializes the TS_AVAIL interrupt
*
*END*----------------------------------------------------------------------*/

boolean MACNET_ptp_install_ts_avail_isr( ENET_CONTEXT_STRUCT_PTR enet_ptr, MACNET_INIT_STRUCT const * enet_init_ptr)
{
   return (MACNET_install_isr(enet_ptr, 4, ENET_INT_TS_AVAIL, MACNET_ptp_store_txstamp, enet_init_ptr->ERX_LEVEL,enet_init_ptr->ERX_SUBLEVEL)) ;
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : MACNET_ptp_install_ts_timer_isr
* Returned Value   : none
* Comments         :
*    This function initializes the TS_TIMER interrupt
*
*END*----------------------------------------------------------------------*/

boolean MACNET_ptp_install_ts_timer_isr( ENET_CONTEXT_STRUCT_PTR enet_ptr, MACNET_INIT_STRUCT const * enet_init_ptr)
{
   return (MACNET_install_isr(enet_ptr, 5, ENET_INT_TS_TIMER, MACNET_ptp_increment_seconds, enet_init_ptr->ETX_LEVEL - 1, 0)) ;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_increment_seconds
*  Returned Value :  
*  Comments       : 
*    This function is the TS_TIMER interrupt service routine
*
*END*-----------------------------------------------------------------*/
void MACNET_ptp_increment_seconds
   (
         /* [IN] the Ethernet state structure */
      pointer  enet
   )
{ /* Body */
   ENET_CONTEXT_STRUCT_PTR    enet_ptr = (ENET_CONTEXT_STRUCT_PTR)enet;
   MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   ENET_MemMapPtr             macnet_ptr= macnet_context_ptr->MACNET_ADDRESS;

   if (macnet_ptr == NULL) return;

   /* Load the output compare buffer */
   macnet_ptr->CHANNEL[MACNET_PTP_TIMER].TCCR = MACNET_1588_ATPER_VALUE - MACNET_1588_CLOCK_INC;
   
   /* Clear ENET_TCSRn[TF] flag by writing a logic one */
   macnet_ptr->CHANNEL[MACNET_PTP_TIMER].TCSR |= ENET_TCSR_TF_MASK;
   
   /* Clear ENET_TGSRn respective channel flag */
   macnet_ptr->TGSR |= 1<<MACNET_PTP_TIMER;
   
   /* Increment seconds */
   MACNET_PTP_seconds++;
}

#endif /* ENETCFG_SUPPORT_PTP */


<|start_filename|>Firmware/Inverter_firmware/Main/Pins_control.c<|end_filename|>
#include <mqx.h>
#include <bsp.h>
#include <fio.h>
#include "App.h"

/*-------------------------------------------------------------------------------------------------------------
  Установка состояния светодиодов
  led_num - номер светодиода (1...3)
  state   - состояние ( 1 - включен, 0 - выключен)
-------------------------------------------------------------------------------------------------------------*/
void Led_control(int led_num, int state)
{
  switch (led_num)
  {
  case 1:
    if ( (state & BIT(0)) != 0 ) PTA_BASE_PTR->PCOR = LSHIFT(1, 24);
    else PTA_BASE_PTR->PSOR = LSHIFT(1, 24);
    break;
  case 2:
    if ( (state & BIT(0)) != 0 ) PTA_BASE_PTR->PCOR = LSHIFT(1, 25);
    else PTA_BASE_PTR->PSOR = LSHIFT(1, 25);
    break;
  case 3:
    if ( (state & BIT(0)) != 0 ) PTA_BASE_PTR->PCOR = LSHIFT(1, 26);
    else PTA_BASE_PTR->PSOR = LSHIFT(1, 26);
    break;
  }
}

/*-------------------------------------------------------------------------------------------------------------
  1 - Вентилятор включен
  0 - Вентилятор выключен
-------------------------------------------------------------------------------------------------------------*/
void Fun_control(int state)
{
  if ( state == 0 ) PTE_BASE_PTR->PCOR = LSHIFT(1, 7);
  else PTE_BASE_PTR->PSOR = LSHIFT(1, 7);

}

/*-------------------------------------------------------------------------------------------------------------
  Возвращаем 1 если вентилятор включен
-------------------------------------------------------------------------------------------------------------*/
int Fun_state(void)
{
  if ( GPIOE_PDIR & BIT(7) ) return 1;
  else return 0;
}

/*-------------------------------------------------------------------------------------------------------------
  Управление регистром сигналов IGBT модуля   
  1 - Буффер включен, IGBT подключен к микроконтроллеру
  0 - Буффер выключен, IGBT отключен от микроконтроллера
-------------------------------------------------------------------------------------------------------------*/
void IGBT_reg_control(int state)
{
  if ( state == 1 ) PTA_BASE_PTR->PCOR = LSHIFT(1, 13);
  else PTA_BASE_PTR->PSOR = LSHIFT(1, 13);
}


/*-------------------------------------------------------------------------------------------------------------
  1 - NTC зашунтирован
  0 - NTC включен в цепь заряда
-------------------------------------------------------------------------------------------------------------*/
void NTC_bypass_control(int state)
{
  if ( state == 0 ) PTC_BASE_PTR->PCOR = LSHIFT(1, 13);
  else PTC_BASE_PTR->PSOR = LSHIFT(1, 13);
}

/*-------------------------------------------------------------------------------------------------------------
  Active LOW Reset Signal
-------------------------------------------------------------------------------------------------------------*/
void LCD_RST(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 11);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 11);
}

/*-------------------------------------------------------------------------------------------------------------
  Serial clock
-------------------------------------------------------------------------------------------------------------*/
void LCD_SCL(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 12);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 12);
}
/*-------------------------------------------------------------------------------------------------------------
  Input data
-------------------------------------------------------------------------------------------------------------*/
void LCD_SI(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 13);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 13);
}
/*-------------------------------------------------------------------------------------------------------------
  Register Select Signal. RS=0: instruction; RS=1: data
-------------------------------------------------------------------------------------------------------------*/
void LCD_RS(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 14);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 14);
}
/*-------------------------------------------------------------------------------------------------------------
  Active LOW Chip Select signal
-------------------------------------------------------------------------------------------------------------*/
void LCD_SCB(int state)
{
  if ( state == 0 ) PTD_BASE_PTR->PCOR = LSHIFT(1, 15);
  else PTD_BASE_PTR->PSOR = LSHIFT(1, 15);
}



/*-------------------------------------------------------------------------------------------------------------
  Возвращаем 1 если PWM разрешен
-------------------------------------------------------------------------------------------------------------*/
int Pin_PWM_OE_state(void)
{
  if ( GPIOA_PDIR & BIT(12) ) return 0;
  else return 1;
}

/*-------------------------------------------------------------------------------------------------------------
  Процедура обслуживания прерывания от порта A
  Используеться для слежения за состоянием сигнала PWM_OE
-------------------------------------------------------------------------------------------------------------*/
static void PORTA_isr(pointer user_isr_ptr)
{
  if ( PORTA_PCR(12) & BIT(24) )
  {
    // Прерывание от сигнала PWM_OE
    PORTA_PCR(12) |= BIT(24); // Сбрасываем флаг прерывания
    if ( GPIOA_PDIR & BIT(12) )
    {
      // Лог. 1.
      // PWM блокируется
      MC_set_events(PWM_OE_RISE);
    }
    else
    {
      // Лог. 0.
      // PWM разрешается
      MC_set_events(PWM_OE_FALL);
    }
  }
}

/*-------------------------------------------------------------------------------------------------------------
  Процедура обслуживания прерывания от порта B
  Используеться для слежения за состоянием сигнала VFO (уведомление о нештатной ситуации от драйвера двигателя)
-------------------------------------------------------------------------------------------------------------*/
static void PORTB_isr(pointer user_isr_ptr)
{
  if ( PORTB_PCR(3) & BIT(24) )
  {
    // Прерывание от сигнала PWM_OE
    PORTB_PCR(3) |= BIT(24); // Сбрасываем флаг прерывания
    if ( GPIOB_PDIR & BIT(3) )
    {
      // Лог. 1.
      // Уведомление снято
      MC_set_events(VFO_RISE);
    }
    else
    {
      // Лог. 0.
      // Уведомление активно
      MC_set_events(VFO_FALL);
    }
  }
}


/*-------------------------------------------------------------------------------------------------------------
  Установка прерывания для наблюдения за входом PWM_OE 
-------------------------------------------------------------------------------------------------------------*/
void Pin_PWM_OE_int_install(void)
{
  // Настроить фильтацию на порту A
  PORTA_PCR(12) |= LSHIFT(0xB, 16); // Тип прерывания на пине 12 - по фронту и по спаду
  PORTA_PCR(12) |= BIT(4);          // Включить фильтрацию на пине 12
  PORTA_DFER     = 0;               // Обнулим чтобы сконфигурировать тактирование фильтров
  PORTA_DFCR     = 1;               // Для тактирования фильтра на пине 12 используем частоту 1 КГц
  PORTA_DFWR     = 30;              // Не воспринимаем импульсы короче 30 мс
  PORTA_DFER    |= BIT(12);         // Включить фильтрацию на пине 12

  // Установить прерывание на порт
  _int_install_isr(INT_PORTA, PORTA_isr, 0);
  // Разрешить прерывание только после установки вектора! Иначе можем уйти в непрерывный вызов ISR по дефолтному вектору
  _bsp_int_init(INT_PORTA, 3, 0, TRUE);

}

/*-------------------------------------------------------------------------------------------------------------
  Установка прерывания для наблюдения за входом VFO 
-------------------------------------------------------------------------------------------------------------*/
void Pin_VFO_int_install(void)
{
  // Настроить фильтацию на порту B
  PORTB_PCR(3) |= LSHIFT(0xB, 16); // Тип прерывания на пине 3 - по фронту и по спаду
  PORTB_PCR(3) |= BIT(4);          // Включить фильтрацию на пине 3
  PORTB_DFER     = 0;               // Обнулим чтобы сконфигурировать тактирование фильтров
  PORTB_DFCR     = 0;               // Для тактирования фильтра на пине 3 используем частоту шины (60 МГц)
  PORTB_DFWR     = 12;              // Не воспринимаем импульсы короче 200 нс
  PORTB_DFER    |= BIT(3);          // Включить фильтрацию на пине 3

  // Установить прерывание на порт
  _int_install_isr(INT_PORTB, PORTB_isr, 0);
  // Разрешить прерывание только после установки вектора! Иначе можем уйти в непрерывный вызов ISR по дефолтному вектору
  _bsp_int_init(INT_PORTB, 3, 0, TRUE);

}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lpm/lpm_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: lpm_prv.h$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   Low Power Manager private definitions.
*
*END************************************************************************/

#ifndef __lpm_prv_h__
#define __lpm_prv_h__


/*-------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/


/*-------------------------------------------------------------------------*/
/*
**                            MACRO DECLARATIONS
*/


/*-------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/

typedef struct lpm_driver_entry_struct {
    /* Previous in the driver list */
    struct lpm_driver_entry_struct _PTR_ PREVIOUS;

    /* Next in the driver list */
    struct lpm_driver_entry_struct _PTR_ NEXT;
    
    /* Driver registration record */
    LPM_REGISTRATION_STRUCT              REGISTRATION;

    /* Driver specific data passed to callbacks */
    pointer                              DATA;
    
    /* Unique registration identification */
    _mqx_uint                            ID;

} LPM_DRIVER_ENTRY_STRUCT, _PTR_ LPM_DRIVER_ENTRY_STRUCT_PTR;

typedef struct lpm_state_struct {
    /* CPU core operation mode behavior specification */
    const LPM_CPU_OPERATION_MODE _PTR_ CPU_OPERATION_MODES;
    
    /* Current system operation mode */
    LPM_OPERATION_MODE                 OPERATION_MODE;
    
    /* List of registered drivers */
    LPM_DRIVER_ENTRY_STRUCT_PTR        DRIVER_ENTRIES;
    
    /* Unique ID counter */
    _mqx_uint                          COUNTER;
    
    /* LPM functions synchronization */
    LWSEM_STRUCT                       SEMAPHORE;
    
    /* Whether idle sleep is turned ON */
    boolean                            IDLE_SLEEP;
    
} LPM_STATE_STRUCT, _PTR_ LPM_STATE_STRUCT_PTR;


/*-------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif


#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/rtcs.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcs.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the interface functions to the
*   RTCS Communication Library.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "socket.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_socket
* Returned Value  : socket handle
* Comments  :  Routine to open a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  RTCS_socket
   (
      uint_32     pf,
         /*[IN] specifies the protocol family */
      uint_32     type,
         /*[IN] specifies the type of communication */
      uint_32     protocol
         /*[IN] select a specific protocol */
   )
{ /* Body */
   SOCKET_STRUCT_PTR socket_ptr;
   uint_32           error;

   RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_SOCKET, type);

   socket_ptr = SOCK_Get_sock_struct((RTCS_SOCKET_CALL_STRUCT_PTR)type,
                                     RTCS_task_getid());
   if (socket_ptr == NULL) {
      RTCSLOG_API(RTCSLOG_TYPE_FNEXIT, RTCSLOG_FN_SOCKET, RTCS_SOCKET_ERROR);
      return RTCS_SOCKET_ERROR;
   } /* Endif */

   if (socket_ptr->PROTOCOL->SOCK_SOCKET) {
      error = socket_ptr->PROTOCOL->SOCK_SOCKET((uint_32)socket_ptr);
      if (error) {
         SOCK_Free_sock_struct(socket_ptr);
         RTCSLOG_API(RTCSLOG_TYPE_FNEXIT, RTCSLOG_FN_SOCKET, RTCS_SOCKET_ERROR);
         return RTCS_SOCKET_ERROR;
      } /* Endif */
   } /* Endif */

   /*Setup internet family*/
   socket_ptr->AF = pf;

   RTCSLOG_API(RTCSLOG_TYPE_FNEXIT, RTCSLOG_FN_SOCKET, (uint_32)socket_ptr);
   return (uint_32)socket_ptr;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_shutdown
* Returned Value  : OK or error code
* Comments  :  Routine to close a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  RTCS_shutdown
   (
      uint_32     sock,
         /*[IN] socket handle for this socket */
      uint_32     how
         /*[IN] specifies whether or not connection should be immediate */
   )
{
   register SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)sock;
            uint_32           error;

   error = RTCS_OK;

   if ((sock==0) || (sock == RTCS_SOCKET_ERROR) || (socket_ptr->VALID != SOCKET_VALID))
   {
      return RTCSERR_SOCK_INVALID;
   }

   if (socket_ptr->PROTOCOL->SOCK_SHUTDOWN)
   {
      error = socket_ptr->PROTOCOL->SOCK_SHUTDOWN(sock, how);
   }
   SOCK_Free_sock_struct(socket_ptr);
   return error;
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_attachsock
* Returned Value  : socket handle or RTCS_ERROR
* Comments  :  Routine to take ownership of a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  RTCS_attachsock
   (
      uint_32     sock
         /*[IN] specifies the handle of the existing socket */
   )
{ /* Body */
   register SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)sock;

   if (!SOCK_Add_owner(socket_ptr, RTCS_task_getid())) {
      RTCS_setsockerror(sock, RTCSERR_OUT_OF_MEMORY);
      return RTCS_SOCKET_ERROR;
   } /* Endif */

   return sock;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_detachsock
* Returned Value  : error code
* Comments  :  Routine to relinquish ownership of a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  RTCS_detachsock
   (
      uint_32     sock
         /*[IN] specifies the handle of the existing socket */
   )
{ /* Body */
   register SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)sock;

   if (!SOCK_Remove_owner(socket_ptr, RTCS_task_getid())) {
      return RTCSERR_SOCK_NOT_OWNER;
   } /* Endif */

   return RTCS_OK;

} /*EndBody*/


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_geterror
* Returned Value  : error code
* Comments  :  Routine is used to get the last error code associated
*              with a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  RTCS_geterror
   (
      uint_32     sock
         /*[IN] socket handle for this socket */
   )
{ /* Body */
   register SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)sock;

   /*
   ** Verify the socket
   */
   if ((sock==0) || (sock==RTCS_SOCKET_ERROR)) {
      return RTCSERR_SOCK_INVALID;
   } /* Endif */


   if (socket_ptr->VALID != SOCKET_VALID) {
      return RTCSERR_SOCK_INVALID;
   } /* Endif */

   return socket_ptr->ERROR_CODE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_setsockerror
* Returned Value  : error code
* Comments  :  Routine is used to set the error code on a socket.
*              Used internally by RTCS.
*
*END*-----------------------------------------------------------------*/

void RTCS_setsockerror
   (
      uint_32     sock,
         /* [IN] socket handle for this socket */
      uint_32     error
   )
{ /* Body */
   register SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)sock;

   socket_ptr->ERROR_CODE = error;

} /* Endbody */

/* Begin CR 2248 */
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_transfersock
* Returned Value  : socket handle or RTCS_ERROR
* Comments  :  Routine to take ownership of a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  RTCS_transfersock
   (
      uint_32     in_sock,
         /*[IN] specifies the handle of the existing socket */
      _task_id    new_owner
   )
{ /* Body */
   SOCKET_STRUCT_PTR socket_ptr = (SOCKET_STRUCT_PTR)in_sock;
   _rtcs_taskid      old_owner_id;
   _rtcs_taskid      new_owner_id;
   uint_32           out_sock = RTCS_SOCKET_ERROR;

   old_owner_id = RTCS_task_getid();

   if (SOCK_Is_owner(socket_ptr, old_owner_id)) {

      new_owner_id = _task_get_td(new_owner);
      if (new_owner_id) {
         if (old_owner_id==new_owner_id) {
            out_sock=in_sock;
         } else if (SOCK_Add_owner(socket_ptr, new_owner_id)) {
            out_sock=in_sock;
            SOCK_Remove_owner(socket_ptr, old_owner_id);
         } else {
            RTCS_setsockerror(in_sock, RTCSERR_OUT_OF_MEMORY);
         } /* Endif */
      } else {
         RTCS_setsockerror(in_sock, RTCSERR_INVALID_PARAMETER);
      }
   } else {
      RTCS_setsockerror(in_sock, RTCSERR_SOCK_NOT_OWNER);
   } /* Endif */

   return out_sock;
} /* Endbody */
/* End CR 2248 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/fcs16.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: fcs16.h$
* $Version : 3.0.5.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   The CCITT-16 Lookup Table
*
*END************************************************************************/

/*
** The CCITT-16 Lookup Table
*/

static uint_16 fcstab[] = {
   0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
   0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
   0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
   0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
   0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
   0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
   0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
   0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
   0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
   0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
   0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
   0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
   0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
   0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
   0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
   0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
   0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
   0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
   0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
   0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
   0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
   0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
   0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
   0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
   0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
   0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
   0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
   0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
   0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
   0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
   0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
   0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
};


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fgets.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fgets.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the function for getting a string.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Reads the specified string
 * 
 * This function reads at most the next size-1 characters into the array 
 * tty_line_ptr, stopping if a newline is encountered; The newline is included 
 * in the array, which is terminated by '\0'.
 * 
 * \param[in,out] tty_line_ptr Where to store the input string.
 * \param[in]     size         The maximum length to store.
 * \param[in]     file_ptr     The stream to read from.
 * 
 * \return Pointer to the character array.
 * \return NULL  (End of file or error.) 
 */ 
char _PTR_ _io_fgets
   (
      char _PTR_  tty_line_ptr,
      _mqx_int    size,
      MQX_FILE_PTR file_ptr
   )
{ /* Body */
   _mqx_int result;

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(NULL);
   } /* Endif */
#endif

   /* Null terminate the buffer so we can tell if _io_fgetline() actually
      read any data... */

   tty_line_ptr[0] = '\0';

   /* Attempt to read a line of text from file_ptr */

   result = _io_fgetline(file_ptr, tty_line_ptr, size);

   /* If _io_fgetline() returned IO_EOF *and* no data was
      read into the tty_line_ptr buffer, return NULL... */

   if ((result == IO_EOF) && (tty_line_ptr[0] == '\0')) {
      return(NULL);
   } /* Endif */

   /* Otherwise, at least 1 byte was read so return the buffer pointer */

   return tty_line_ptr;

} /* Endbody */

/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/gpio/kgpio/io_gpio_kgpio_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_gpio_kgpio_prv.h$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/

#ifndef __io_gpio_cpu_prv_h__
#define __io_gpio_cpu_prv_h__

#ifdef __cplusplus
extern "C" {
#endif


/*----------------------------------------------------------------------*/
/*
**                          TYPE DEFINITIONS
*/

typedef enum devices {
     DEV_INPUT,
     DEV_OUTPUT
} DEVICE_TYPE;

typedef union pin_map_struct {
    struct {
        uint_32  porta;
        uint_32  portb;
        uint_32  portc;
        uint_32  portd;
        uint_32  porte;
    } reg;
    uint_32 memory32[5];
} GPIO_PIN_MAP, _PTR_ GPIO_PIN_MAP_PTR;

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/include/usb_framework.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_framework.h$
* $Version : 3.8.4.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
* @brief The file contains USB Framework module api header function.
*
*****************************************************************************/

#ifndef _USB_FRAMEWORK_H
#define _USB_FRAMEWORK_H 1

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_class.h"
/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
#define MAX_STRD_REQ            (13)  /* Max value of stadard request */
/* size of data to be returned for various Get Desc calls */
#define DEVICE_STATUS_SIZE      (2)
#define INTERFACE_STATUS_SIZE   (1)
#define CONFIG_SIZE             (1)
#define FRAME_SIZE              (2)
#define ENDP_STATUS_SIZE        (2)

#define DEVICE_REQUEST_MASK     (0x0003)
#define REPORT_DESCRIPTOR_TYPE  (0x22)
#define STRING_DESCRIPTOR_TYPE  (0x03)

/* masks and values for provides of Get Desc information */ 
#define USB_REQUEST_SRC_MASK      (0x03) 
#define USB_REQUEST_SRC_DEVICE    (0x00) 
#define USB_REQUEST_SRC_INTERFACE (0x01) 
#define USB_REQUEST_SRC_ENDPOINT  (0x02) 

#define  USB_SET_REQUEST_MASK     (0x02) 

/* for transfer direction check */
#define USB_DATA_TO_HOST          (0x80)
#define USB_DATA_TO_DEVICE        (0x00)
#define USB_DATA_DIREC_MASK       (0x80)
#define USB_MAX_CLASS_FW_OBJECT   (0x01)
 
/******************************************************************************
 * Types
 *****************************************************************************/
 typedef uint_32 USB_CLASS_FW_HANDLE;
 
/* Strucutre holding USB state information and handles.*/
typedef struct _usb_class_fw_object
{
   uint_16 std_framework_data;
   uint_16 assigned_address;
   _usb_device_handle controller_handle;
   USB_SETUP_STRUCT setup_packet;
   uint_8* ext_req_to_host;
   USB_REQ_CALLBACK_STRUCT  other_req_callback;
   USB_CLASS_CALLBACK_STRUCT class_callback; 
   DESC_CALLBACK_FUNCTIONS_STRUCT desc;
   USB_CLASS_HANDLE  class_handle;  
}USB_CLASS_FW_OBJECT_STRUCT,_PTR_ USB_CLASS_FW_OBJECT_STRUCT_PTR;

 /* callback function pointer structure to handle USB framework request */
typedef uint_8 (_CODE_PTR_ USB_FW_REQ_FUNC)(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                                            USB_SETUP_STRUCT * setup_packet, 
                                            uint_8_ptr *data, 
                                            uint_32 *size); 

/******************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Framework_Init
 *
 * @brief The funtion initializes the Class Module 
 *
 * @param handle :              handle to Identify the controller
 * @param class_callback:       event callback 
 * @param other_req_callback:   callback for vendor or usb framework class req    
 *
 * @return status       
 *         Framework Handle           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
USB_CLASS_FW_HANDLE USB_Framework_Init
(
    _usb_device_handle handle, /*[IN]*/
    USB_CLASS_CALLBACK class_callback,/*[IN]*/
    USB_REQ_FUNC other_req_callback,/*[IN]*/
    pointer callback_data,/*[IN]*/
    int_32 data,/*[IN]*/
    DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr /*[IN]*/
        
) ;
/**************************************************************************//*!
 *
 * @name  USB_Framework_Deinit
 *
 * @brief The funtion initializes the Class Module 
 *
 * @param handle :              handle to Identify the controller
 * @param fw_handle:       		framework handle
 * @return status       
 *         Framework Handle : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Framework_Deinit
(
    _usb_device_handle handle, /*[IN]*/
    USB_CLASS_FW_HANDLE fw_handle /*[IN]*/
        
);
/**************************************************************************//*!
 *
 * @name  USB_Framework_Periodic_Task
 *
 * @brief The funtion is called to respond to any control request
 *
 * @param None
 *
 * @return None       
 *
 *****************************************************************************/
#ifdef DELAYED_PROCESSING
extern void USB_Framework_Periodic_Task(void);
#endif
/**************************************************************************//*!
 *
 * @name  USB_Framework_Reset
 *
 * @brief The funtion resets the framework 
 *
 * @param handle: handle to Identify the controller
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
extern uint_8 USB_Framework_Reset
(
    _usb_device_handle handle /*[IN] the USB device controller to initialize*/ 
);

/**************************************************************************//*!
 *
 * @name  USB_Framework_GetDesc
 *
 * @brief  This function is called in to get the discriptor as specified in cmd.
 *
 * @param handle:           USB framework handle. Received from
 *                          USB_Framework_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param in_buff           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Framework_GetDesc(USB_CLASS_FW_HANDLE handle, /*[IN]*/
int_32 cmd,/*[IN]*/
uint_8 in_data,/*[IN]*/
uint_8_ptr * in_buff/*[OUT]*/
);

/**************************************************************************//*!
 *
 * @name  USB_Framework_SetDesc
 *
 * @brief  This function is called in to get the discriptor as specified in cmd.
 *
 * @param handle:           USB framework handle. Received from
 *                          USB_Framework_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param outBuf           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Framework_SetDesc(USB_CLASS_FW_HANDLE handle,/*[IN]*/
int_32 cmd,/*[IN]*/
uint_8 input_data,/*[IN]*/
uint_8_ptr * outBuf/*[IN]*/
);
/**************************************************************************//*!
 *
 * @name  USB_Framework_Remote_wakeup
 *
 * @brief  This function is called in to get the discriptor as specified in cmd.
 *
 * @param handle:           USB framework handle. Received from
 *                          USB_Framework_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param in_buff           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
boolean USB_Framework_Remote_wakeup(USB_CLASS_FW_HANDLE handle/*[IN]*/);

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_init.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_init.c$
* $Version : 3.8.15.0$
* $Date    : Aug-7-2012$
*
* Comments:
*
*   This file contains the MACNET initialization
*
*END************************************************************************/

#include "mqx.h"

#include "mqx_inc.h"

#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "bsp_prv.h"
#include "macnet_prv.h"          

extern _mem_pool_id _BSP_sram_pool;

const ENET_MAC_IF_STRUCT MACNET_IF = {
    MACNET_initialize,
    MACNET_shutdown,
    MACNET_send,
    MACNET_read_mii,
    MACNET_write_mii,

    #if BSPCFG_ENABLE_ENET_MULTICAST
    MACNET_join,
    MACNET_rejoin,
    #endif /* BSPCFG_ENABLE_ENET_MULTICAST */

    #if ENETCFG_SUPPORT_PTP
    MACNET_ptp_ioctl,
    #else
    NULL,
    #endif /* ENETCFG_SUPPORT_PTP */
};


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_initialize
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Initializes the chip (extended version).
*
*END*-----------------------------------------------------------------*/

#define IF_ERROR_EXIT(c,x) {if (c) { error = x; goto EXIT; }}

uint_32 MACNET_initialize
   (
      ENET_CONTEXT_STRUCT_PTR enet_ptr
   )
{ 
   MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr=NULL;
   ENET_MemMapPtr             macnet_ptr;
   VENET_BD_STRUCT_PTR        bd_ptr;
   uchar_ptr                  buf_ptr;
   MACNET_RX_PCB_PTR          pcb_ptr;
   uint_32                    i, rxsize, txsize, ssize, lsize, pcbsize,rx_pcb_size, large_packet_size, rcr;
   uint_32                    timeout, error = ENET_OK;
   boolean                    bOK;
#if ENETCFG_SUPPORT_PTP
   MACNET_PTP_PRIVATE_PTR     macnet_ptp_ptr = NULL;
#endif /* ENETCFG_SUPPORT_PTP */
   KERNEL_DATA_STRUCT_PTR     kernel_data;
   
   _GET_KERNEL_DATA(kernel_data);

   // Initialize the MACNET I/O Pins
   MACNET_io_init(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER);
   
   macnet_ptr = MACNET_get_base_address(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER);
   if (macnet_ptr == NULL) {
      return ENETERR_INVALID_DEVICE;
   }
   
   
   // currently limit number of TX BDs to 32, as a bitmask is used in the free function.
   if (enet_ptr->PARAM_PTR->NUM_TX_ENTRIES > 32) {
      return ENETERR_INVALID_INIT_PARAM;
   }
   
   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   MACNET_int_disable();

   macnet_context_ptr = _mem_alloc_system_zero(sizeof(MACNET_CONTEXT_STRUCT));
   IF_ERROR_EXIT((NULL==macnet_context_ptr), ENETERR_ALLOC_MAC_CONTEXT);
   _mem_set_type((pointer)macnet_context_ptr, MEM_TYPE_IO_ENET_MAC_CONTEXT_STRUCT);
   
   enet_ptr->MAC_CONTEXT_PTR = (pointer) macnet_context_ptr;  

   macnet_context_ptr->MACNET_ADDRESS = macnet_ptr;
   macnet_context_ptr->PHY_PTR = MACNET_get_base_address(enet_ptr->PARAM_PTR->ENET_IF->PHY_NUMBER);

   /* Stop the chip */
   macnet_ptr->ECR = ENET_ECR_RESET_MASK;

   /* wait until the initialization cycle completes */
   timeout = 0;
   while ((macnet_ptr->ECR & ENET_ECR_RESET_MASK) && (timeout<MACNET_RESET_TIMEOUT)){
      _time_delay(1);
      timeout++;
   } 
   IF_ERROR_EXIT((macnet_ptr->ECR & ENET_ECR_RESET_MASK), ENETERR_INIT_FAILED);
   
   /* Disable all MACNET interrupts */
   macnet_ptr->EIMR = 0;

   /* clear any pending interrpts */
   macnet_ptr->EIR = ENET_EIR_ALL_PENDING;

   macnet_context_ptr->NumRxBDs = enet_ptr->PARAM_PTR->NUM_RX_ENTRIES;
   macnet_context_ptr->NumTxBDs = enet_ptr->PARAM_PTR->NUM_TX_ENTRIES;
     
   // Compute aligned buffer sizes 
   if (enet_ptr->PARAM_PTR->TX_BUFFER_SIZE) {
      macnet_context_ptr->AlignedTxBufferSize = MACNET_TX_ALIGN(enet_ptr->PARAM_PTR->TX_BUFFER_SIZE);
   } else {
      macnet_context_ptr->AlignedTxBufferSize = MACNET_TX_ALIGN(enet_ptr->MaxTxFrameSize);
   }

   if (enet_ptr->PARAM_PTR->RX_BUFFER_SIZE) {
      macnet_context_ptr->AlignedRxBufferSize = MACNET_RX_ALIGN(enet_ptr->PARAM_PTR->RX_BUFFER_SIZE);
   } else {
      macnet_context_ptr->AlignedRxBufferSize = MACNET_RX_ALIGN(enet_ptr->MaxRxFrameSize);
   }

   // Allocate the Transmit and Receive buffer descriptors
   // TODO remake to using alloc_align fn
#if BSPCFG_HAS_SRAM_POOL && BSPCFG_ENET_SRAM_BUF
   bd_ptr = (VENET_BD_STRUCT_PTR)_mem_alloc_system_zero_from(_BSP_sram_pool, (sizeof(ENET_BD_STRUCT)*(macnet_context_ptr->NumRxBDs+macnet_context_ptr->NumTxBDs))+MACNET_BD_ALIGNMENT);
#else
   bd_ptr = (VENET_BD_STRUCT_PTR)_mem_alloc_system_zero_uncached((sizeof(ENET_BD_STRUCT)*(macnet_context_ptr->NumRxBDs+macnet_context_ptr->NumTxBDs))+MACNET_BD_ALIGNMENT);
#endif

   IF_ERROR_EXIT((NULL == bd_ptr), ENETERR_ALLOC_BD);
   _mem_set_type((pointer)bd_ptr, MEM_TYPE_IO_BD_STRUCT);

   macnet_context_ptr->UNALIGNED_RING_PTR = (pointer) bd_ptr;
   macnet_context_ptr->MACNET_RX_RING_PTR = (VENET_BD_STRUCT_PTR) MACNET_BD_ALIGN((uint_32)bd_ptr);
   macnet_context_ptr->MACNET_TX_RING_PTR = &macnet_context_ptr->MACNET_RX_RING_PTR[macnet_context_ptr->NumRxBDs];

   /* Set wrap bit in last BD */
   macnet_context_ptr->MACNET_RX_RING_PTR[macnet_context_ptr->NumRxBDs - 1].CONTROL = HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_RX_WRAP);
   macnet_context_ptr->MACNET_TX_RING_PTR[macnet_context_ptr->NumTxBDs - 1].CONTROL = HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_TX_WRAP);

   macnet_context_ptr->AvailableTxBDs = macnet_context_ptr->NumTxBDs;

   // Allocate array to hold Transmit PCB pointers while they are queued for transmission
   macnet_context_ptr->TxPCBS_PTR = (PCB_PTR *) _mem_alloc_system_zero(sizeof(PCB_PTR)*macnet_context_ptr->NumTxBDs);
   IF_ERROR_EXIT((NULL==macnet_context_ptr->TxPCBS_PTR), ENETERR_ALLOC_PCB);
   _mem_set_type((pointer)macnet_context_ptr->TxPCBS_PTR, MEM_TYPE_IO_PCB_PTR);

   // Allocate the Receive PCBs
   rx_pcb_size = sizeof(MACNET_RX_PCB);
   pcbsize = enet_ptr->PARAM_PTR->NUM_RX_PCBS * rx_pcb_size;
   macnet_context_ptr->RX_PCB_BASE = (MACNET_RX_PCB_PTR) _mem_alloc_system_zero(pcbsize);
   IF_ERROR_EXIT((NULL==macnet_context_ptr->RX_PCB_BASE), ENETERR_ALLOC_PCB);
   _mem_set_type((pointer)macnet_context_ptr->RX_PCB_BASE, MEM_TYPE_IO_PCB_STRUCT);
       
   // Allocate the Transmit and Receive buffers
   txsize = (enet_ptr->PARAM_PTR->NUM_TX_BUFFERS * macnet_context_ptr->AlignedTxBufferSize) + MACNET_TX_BUFFER_ALIGNMENT;
   rxsize = (enet_ptr->PARAM_PTR->NUM_RX_BUFFERS  * macnet_context_ptr->AlignedRxBufferSize) +MACNET_RX_BUFFER_ALIGNMENT;
   ssize  = (enet_ptr->PARAM_PTR->NUM_SMALL_BUFFERS * MACNET_SMALL_PACKET_SIZE);
   large_packet_size = enet_ptr->PARAM_PTR->OPTIONS&ENET_OPTION_VLAN ? ENET_FRAMESIZE_VLAN : ENET_FRAMESIZE;
   lsize  = (enet_ptr->PARAM_PTR->NUM_LARGE_BUFFERS * large_packet_size);

#if BSPCFG_HAS_SRAM_POOL && BSPCFG_ENET_SRAM_BUF
   buf_ptr = _mem_alloc_system_from(_BSP_sram_pool, rxsize + txsize + ssize + lsize);
#else
   buf_ptr = _mem_alloc_system_uncached(rxsize + txsize + ssize + lsize);  // temporary fix for cache problems... previously _mem_alloc_system
#endif
   
   IF_ERROR_EXIT((NULL==buf_ptr), ENETERR_ALLOC_BUFFERS);
   _mem_set_type(buf_ptr, MEM_TYPE_IO_ENET_BUFFERS);

   macnet_context_ptr->UNALIGNED_BUFFERS = buf_ptr;

   // Align to TX buffer boundary
   buf_ptr = (uchar_ptr)MACNET_TX_ALIGN((uint_32)buf_ptr);
   
   // Queue packets on TX Buffer Q.
   macnet_context_ptr->TX_BUFFERS = NULL;
   for (i=0;i<enet_ptr->PARAM_PTR->NUM_TX_BUFFERS;i++) {
      ENET_Enqueue_Buffer((pointer *)&macnet_context_ptr->TX_BUFFERS, buf_ptr);
      buf_ptr += macnet_context_ptr->AlignedTxBufferSize;
   }
   
   // Align to RX buffer boundary
   buf_ptr = (uchar_ptr)MACNET_RX_ALIGN((uint_32)buf_ptr);
  
   // Queue packets on RX Buffer Q.
   macnet_context_ptr->RX_BUFFERS = NULL;
   for (i=0;i<enet_ptr->PARAM_PTR->NUM_RX_BUFFERS;i++) {
      ENET_Enqueue_Buffer((pointer *)&macnet_context_ptr->RX_BUFFERS, buf_ptr);
      buf_ptr += macnet_context_ptr->AlignedRxBufferSize;
   }

   // Queue small packets on small buffer Q.
   for (i=0;i<enet_ptr->PARAM_PTR->NUM_SMALL_BUFFERS;i++) {
      ENET_Enqueue_Buffer((pointer *)&macnet_context_ptr->SMALL_BUFFERS, buf_ptr);
      buf_ptr += MACNET_SMALL_PACKET_SIZE;
   }

   // Queue large packets on large buffer Q.
   for (i=0;i<enet_ptr->PARAM_PTR->NUM_LARGE_BUFFERS;i++) {
      ENET_Enqueue_Buffer((pointer *)&macnet_context_ptr->LARGE_BUFFERS, buf_ptr);
      buf_ptr += large_packet_size;
   }

   // Enqueue the RX PCBs onto the receive PCB queue 
   pcb_ptr = macnet_context_ptr->RX_PCB_BASE;
   for (i = 0; i < enet_ptr->PARAM_PTR->NUM_RX_PCBS; i++) {
      QADD(macnet_context_ptr->RxPCBHead, macnet_context_ptr->RxPCBTail, (PCB_PTR) pcb_ptr);
      pcb_ptr++;
   } 

   // Fill up the receive ring 
   MACNET_add_buffers_to_rx_ring(macnet_context_ptr);

   /* Program this station's Ethernet physical address */
   macnet_ptr->PALR = (uint_32)((enet_ptr->ADDRESS[0] << 24)|(enet_ptr->ADDRESS[1] << 16)|(enet_ptr->ADDRESS[2] << 8)|(enet_ptr->ADDRESS[3] << 0));
   macnet_ptr->PAUR = (uint_32)((enet_ptr->ADDRESS[4] << 24)|(enet_ptr->ADDRESS[5] << 16));
   // Clear the individual hash table registers
   macnet_ptr->IAUR = 0;
   macnet_ptr->IALR = 0;

   // Clear the group hash table registers                                
   macnet_ptr->GAUR = 0;
   macnet_ptr->GALR = 0;  

   /* Program receive buffer size */
   macnet_ptr->MRBR = macnet_context_ptr->AlignedRxBufferSize;     

   // Configure start of Rx and Tx BD rings
   macnet_ptr->RDSR = (uint_32)(macnet_context_ptr->MACNET_RX_RING_PTR);
   macnet_ptr->TDSR = (uint_32)(macnet_context_ptr->MACNET_TX_RING_PTR);

   // Set Receive Frame size 
   // NOTE: Oddly, the Receive Control Register (RCR) afmacnetts the transmit side too.  The RCR is used to determine if the 
   //       transmitter is babbling, which means, if the RX buffer size < Tx Buffer size, we can get babling transmitter
   //       errors if we set RCR to the maximum Receive frame length.  We really have no choice but to set RCR to one
   //       of ENET_FRAMESIZE or ENET_FRAMESIZE_VLAN.
   //

   rcr = ENET_RCR_MII_MODE_MASK | (ENET_RCR_MAX_FL_MASK & (large_packet_size << ENET_RCR_MAX_FL_SHIFT));
   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_RMII) {
      rcr |= ENET_RCR_RMII_MODE_MASK;
   } else if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_7WIRE) {
      rcr &= ~ENET_RCR_MII_MODE_MASK;
   }
   macnet_ptr->RCR =  rcr;
   

   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_MAC_LOOPBACK) {
      macnet_ptr->RCR |= ENET_RCR_LOOP_MASK;
   }
   //  Set Full/Half duplex based on mode.
   if (enet_ptr->PARAM_PTR->MODE & ENET_HALF_DUPLEX) {
      macnet_ptr->TCR = 0; // half duplex
   } else {
      macnet_ptr->TCR = 4; // full duplex
   }
   
   // Enable MII_SPEED register 
   i = (MACNET_device[enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER].BUS_CLOCK / enet_ptr->PARAM_PTR->ENET_IF->PHY_MII_SPEED + 1) & ~1;
   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_NO_PREAMBLE) {
      i |= ENET_MSCR_DIS_PRE_MASK;
   }
   macnet_context_ptr->PHY_PTR->MSCR = i;

   // Zero counters
   macnet_ptr->MIBC |= ENET_MIBC_MIB_CLEAR_MASK;

   // Install the ISRs
   bOK = MACNET_install_isrs( enet_ptr, &MACNET_device[enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER] );
   IF_ERROR_EXIT(!bOK, ENETERR_INSTALL_ISR);
          
   // Unmask transmit/receive interrupts 
   // NOTE: need to enable both RXF and RXB, but only TXB, as RXB does not get generated with RXF, 
   //       but TXB does get generated with TXF
   // However, on 52259, enabling RXB is resulting in an HBERR interrupt. RXB is not required, so leave it disabled.
   macnet_ptr->EIMR = ENET_EIR_TXB_MASK | ENET_EIR_RXF_MASK; 

   // Enable MACNET 
   macnet_ptr->ECR = (ENET_ECR_ETHEREN_MASK | ENET_ECR_EN1588_MASK);// | 0x100;

   // Discover PHY address if PHY_DISCOVER option is set
   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PHY_DISCOVER) {
      bOK = (*enet_ptr->PARAM_PTR->ENET_IF->PHY_IF->DISCOVER)(enet_ptr);
      IF_ERROR_EXIT(!bOK, ENETERR_INIT_FAILED);
   } else {
      // Set Phy address from initialization parameter
      enet_ptr->PHY_ADDRESS = enet_ptr->PARAM_PTR->ENET_IF->PHY_ADDRESS;
   }
   
   // Enable STORE & FORWARD mode
   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_STORE_AND_FORW) {
      macnet_ptr->TFWR |= ENET_TFWR_STRFWD_MASK;
      macnet_ptr->RSFL |= ENET_RSFL_RX_SECTION_FULL(0);
   }
   
   // Perform Phy initialization
   bOK = (*enet_ptr->PARAM_PTR->ENET_IF->PHY_IF->INIT)(enet_ptr);
   IF_ERROR_EXIT(!bOK, ENETERR_INIT_FAILED);


   // Signals the MACNET that empty buffers are available.
   // It is NECESSARY to do this AFTER enabling the MACNET.
   macnet_ptr->RDAR = ENET_RDAR_RDAR_MASK;
   
   //jm _mem_copy((void*)0x400d0000, (void*)0x3f400000, 0x400);


#if ENETCFG_SUPPORT_PTP
   macnet_ptp_ptr = _mem_alloc_system_zero(sizeof(MACNET_PTP_PRIVATE));
   IF_ERROR_EXIT((NULL==macnet_context_ptr), ENETERR_ALLOC_MAC_CONTEXT);


   macnet_ptp_ptr->MACNET_PTR = macnet_context_ptr->MACNET_ADDRESS;
   macnet_ptp_ptr->PTIMER_PRESENT = 1;

   bOK = _lwevent_create(&(macnet_ptp_ptr->LWEVENT_PTP), 0);
   IF_ERROR_EXIT(bOK, ENETERR_1588_LWEVENT);
   
   macnet_ptp_ptr->TXSTAMP = (MACNET_PTP_TIME){0,0};
   macnet_ptp_ptr->L2PCKS_PTR = NULL;
   
   macnet_context_ptr->PTP_PRIV = macnet_ptp_ptr;
   MACNET_ptp_init(enet_ptr);
   
   if (macnet_ptp_ptr->PTIMER_PRESENT) {
      /* Set Timer count */
      MACNET_ptp_start(macnet_ptp_ptr, (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_MASTER_CLK));
      if(enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_MASTER_CLK)
          MACNET_ptp_set_master_base_address(macnet_ptr);
      macnet_ptp_ptr->MACNET_PTR->ECR |= ENET_ECR_EN1588_MASK;

   }
   /* Enable timer-relative interrupts */
   macnet_ptp_ptr->MACNET_PTR->EIMR |= (ENET_EIR_TS_TIMER_MASK | ENET_EIR_TS_AVAIL_MASK);
#endif /* ENETCFG_SUPPORT_PTP */


   // control transfers to this point on any error, with error set to error code.
EXIT:
   if (ENET_OK!=error) {
      #if BSPCFG_ENET_RESTORE
         MACNET_uninstall_all_isrs(enet_ptr);
      #endif
      MACNET_free_context(macnet_context_ptr);
   }
   MACNET_int_enable();
   return error;
} 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/include/shell.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: shell.h$
* $Version : 3.8.23.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the shell API.
*
*END************************************************************************/

#ifndef __shell_h__
#define __shell_h__

#include <fio.h>

#ifdef __rtcs_h__
#include <sh_rtcs.h>
#endif

#ifdef __mfs_h__
#include <sh_mfs.h>
#endif

/** MGCT: <category name="Shell Settings"> */

/*
** MGCT: <option type="bool"/>
*/  
#ifndef SHELLCFG_USES_MFS
#define SHELLCFG_USES_MFS   1
#endif

/*
** MGCT: <option type="bool"/>
*/  
#ifndef SHELLCFG_USES_RTCS
#define SHELLCFG_USES_RTCS  1
#endif

/** MGCT: </category> */

#ifdef BSP_DEFAULT_ENET_DEVICE
#include <sh_enet.h>
#endif

#define SHELL_MAX_ARGS       14

#define SHELL_EXIT_SUCCESS   0
#define SHELL_EXIT_ERROR    -1

#define SHELL_MAX_DEVLEN    8
#define SHELL_MAX_FILELEN   256
#define SHELL_PATHNAME_LEN  260
#define SHELL_BLOCK_SIZE    128

#define MEM_TYPE_SHELL_BASE                   ( (IO_SHELL_COMPONENT) << (MEM_TYPE_COMPONENT_SHIFT))
#define MEM_TYPE_SHELL_CONTEXT                (MEM_TYPE_SHELL_BASE+1)

#define hexnum(c)  ((c<='9')?(c-'0'):((c<='F')?(c-'A'+10) :(c-'a'+10))) 

#define SHELL_COMMAND(cmd) { #cmd, Shell_##cmd },

typedef struct shell_command_struct  {
   char_ptr  COMMAND;
   int_32      (*SHELL_FUNC)(int_32 argc, char_ptr argv[]);
} SHELL_COMMAND_STRUCT, _PTR_ SHELL_COMMAND_PTR; 


/*
** Function prototypes 
*/

#ifdef __cplusplus
extern "C" {
#endif

extern MQX_FILE_PTR Shell_default_fs;
extern char_ptr Shell_default_fs_name;

extern const SHELL_COMMAND_STRUCT Shell_commands[];

extern int_32  Shell( const SHELL_COMMAND_STRUCT[], char_ptr );
extern int_32  Shell_parse_command_line( char_ptr command_line_ptr, char_ptr argv[] );
extern boolean Shell_parse_number( char_ptr arg, uint_32_ptr num_ptr);
extern boolean Shell_check_help_request(int_32 argc, char_ptr argv[], boolean _PTR_ short_ptr );
extern boolean Shell_parse_uint_32( char_ptr arg, uint_32_ptr num_ptr);
extern boolean Shell_parse_uint_16( char_ptr arg, uint_16_ptr num_ptr);
extern boolean Shell_parse_int_32( char_ptr arg, int_32_ptr num_ptr);
extern boolean Shell_parse_hexnum( char_ptr arg, uint_32_ptr num_ptr);
extern void Shell_create_prefixed_filename( char_ptr new_ptr, char_ptr in_ptr,  pointer argv);
extern int_32 Shell_abort(int_32 argc, char_ptr argv[] ); 
extern int_32 Shell_command_list(int_32 argc, char_ptr argv[] );
extern int_32 Shell_exit(int_32 argc, char_ptr argv[] );
extern int_32 Shell_help(int_32 argc, char_ptr argv[] ); 
extern int_32 Shell_kill(int_32 argc, char_ptr argv[] ); 
extern int_32 Shell_pause(int_32 argc, char_ptr argv[] );
extern int_32 Shell_tad(int_32 argc, char_ptr argv[] );
extern int_32 Shell_sh(int_32 argc, char_ptr argv[] );
extern int_32 Shell_md(int_32 argc, char_ptr argv[] );

extern MQX_FILE_PTR Shell_get_current_filesystem(pointer argv);
extern char_ptr Shell_get_current_filesystem_name(pointer argv);

extern int_32 Shell_set_current_filesystem(pointer argv, MQX_FILE_PTR fp);
extern int_32 Shell_set_current_filesystem_by_name(pointer argv, char_ptr dev_name);


extern int_32 Shell_erase(int_32 argc, char_ptr argv[] );
extern int_32 Shell_write_block(int_32 argc, char_ptr argv[] );
extern int_32 Shell_read_block(int_32 argc, char_ptr argv[] );

#ifdef __cplusplus
}
#endif

#endif
/*EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/int/i2c_int_qi2c.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
**************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_int_qi2c.c$
* $Version : 3.8.4.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains low level functions for the I2C interrupt device driver
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <fio_prv.h>
#include "i2c_int_prv.h"
#include "i2c_qi2c_prv.h"


extern uint_32 _qi2c_polled_init (QI2C_INIT_STRUCT_PTR, pointer _PTR_, char_ptr);
extern uint_32 _qi2c_polled_ioctl (VQI2C_INFO_STRUCT_PTR, uint_32, uint_32_ptr);

extern uint_32 _qi2c_int_init (IO_I2C_INT_DEVICE_STRUCT_PTR, char_ptr);
extern uint_32 _qi2c_int_deinit (IO_I2C_INT_DEVICE_STRUCT_PTR, VQI2C_INFO_STRUCT_PTR);
extern uint_32 _qi2c_int_rx (IO_I2C_INT_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _qi2c_int_tx (IO_I2C_INT_DEVICE_STRUCT_PTR, uchar_ptr, uint_32);
static void    _qi2c_int_isr (pointer);


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_int_install
* Returned Value   : MQX error code
* Comments         :
*    Install an I2C device.
*
*END*********************************************************************/

uint_32 _qi2c_int_install
    (
        /* [IN] A string that identifies the device for fopen */
        char_ptr              identifier,

        /* [IN] The I/O init data pointer */
        QI2C_INIT_STRUCT_CPTR init_data_ptr
    )
{

    return _io_i2c_int_install(identifier,
        (uint_32 (_CODE_PTR_)(pointer, char_ptr))_qi2c_int_init,
        (uint_32 (_CODE_PTR_)(pointer, pointer))_qi2c_int_deinit,
        (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_qi2c_int_rx,
        (int_32 (_CODE_PTR_)(pointer, char_ptr, int_32))_qi2c_int_tx,
        (int_32 (_CODE_PTR_)(pointer, uint_32, uint_32_ptr))_qi2c_polled_ioctl,
        (pointer)init_data_ptr);

}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_int_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an I2C device.
*
*END*********************************************************************/

uint_32 _qi2c_int_init
    (
        /* [IN] Initialization information for the device being opened */
        IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

        /* [IN] The rest of the name of the device opened */
        char_ptr                     open_name_ptr

    )
{
    VQI2C_REG_STRUCT_PTR             i2c_ptr;
    VQI2C_INFO_STRUCT_PTR            io_info_ptr;
    QI2C_INIT_STRUCT_PTR             i2c_init_ptr;
    uint_32                          vector, result;

    i2c_init_ptr = (QI2C_INIT_STRUCT_PTR)(int_io_dev_ptr->DEV_INIT_DATA_PTR);
    result = _qi2c_polled_init (i2c_init_ptr, 
                                &(int_io_dev_ptr->DEV_INFO_PTR),  
                                open_name_ptr);
    if (result)
    {
        return result;
    }

    io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
    i2c_ptr = io_info_ptr->I2C_PTR;
    vector = _bsp_get_i2c_vector(i2c_init_ptr->CHANNEL);
    if (0 == vector)
    {
        return I2C_ERROR_CHANNEL_INVALID;
    }
    io_info_ptr->VECTOR = vector;

    /* Allocate buffers */
    io_info_ptr->RX_BUFFER = (pointer)_mem_alloc_system (i2c_init_ptr->RX_BUFFER_SIZE);
    if (NULL == io_info_ptr->RX_BUFFER)
    {
        return MQX_OUT_OF_MEMORY;
    }
    io_info_ptr->TX_BUFFER = (pointer)_mem_alloc_system (i2c_init_ptr->TX_BUFFER_SIZE);
    if (NULL == io_info_ptr->TX_BUFFER)
    {
        _mem_free (io_info_ptr->RX_BUFFER);
        io_info_ptr->RX_BUFFER = NULL;
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type (io_info_ptr->RX_BUFFER, MEM_TYPE_IO_I2C_IN_BUFFER);
    _mem_set_type (io_info_ptr->TX_BUFFER, MEM_TYPE_IO_I2C_OUT_BUFFER);

    /* Install new vectors and backup the old ones */
    io_info_ptr->OLD_ISR_DATA = _int_get_isr_data (vector);
    io_info_ptr->OLD_ISR = _int_install_isr (vector, _qi2c_int_isr, (pointer)io_info_ptr);


    _bsp_int_init(vector, io_info_ptr->INIT.LEVEL, 0, TRUE);

    /* Enable I2C interrupts */
    i2c_ptr->I2CR |= QI2C_I2CR_IBIE;
    _PSP_SYNC();

    return I2C_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_int_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an I2C device.
*
*END*********************************************************************/

uint_32 _qi2c_int_deinit
    (
        /* [IN] the initialization information for the device being opened */
        IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

        /* [IN] the address of the device specific information */
        VQI2C_INFO_STRUCT_PTR        io_info_ptr
    )
{
    VQI2C_REG_STRUCT_PTR             i2c_ptr;

    if ((NULL == io_info_ptr) || (NULL == int_io_dev_ptr))
    {
        return I2C_ERROR_INVALID_PARAMETER;
    }

    i2c_ptr = io_info_ptr->I2C_PTR;
    _PSP_SYNC();
    if (i2c_ptr->I2SR & QI2C_I2SR_IBB)
    {
        return I2C_ERROR_DEVICE_BUSY;
    }

    /* Disable the I2C */
    i2c_ptr->I2CR = QI2C_I2CR_MDIS;
    _PSP_SYNC();

    /* Clear the I2C events */
    i2c_ptr->I2SR    |= (QI2C_I2SR_IBIF | QI2C_I2SR_IBAL);
    _PSP_SYNC();

    /* Install original vectors */
    _bsp_int_init(io_info_ptr->VECTOR, io_info_ptr->INIT.LEVEL, 0, FALSE);
    _int_install_isr (io_info_ptr->VECTOR, io_info_ptr->OLD_ISR, io_info_ptr->OLD_ISR_DATA);

    /* Free buffers and info struct */
    _mem_free (int_io_dev_ptr->DEV_INFO_PTR);
    int_io_dev_ptr->DEV_INFO_PTR = NULL;
    _mem_free (io_info_ptr->RX_BUFFER);
    io_info_ptr->RX_BUFFER = NULL;
    _mem_free (io_info_ptr->TX_BUFFER);
    io_info_ptr->TX_BUFFER = NULL;

    return I2C_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_int_rx
* Returned Value   : number of bytes read
* Comments         :
*   Returns the number of bytes received.
*   Reads the data into provided array when data is available.
*
*END*********************************************************************/

uint_32 _qi2c_int_rx
    (
        /* [IN] the address of the device specific information */
        IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

        /* [IN] The array to copy data into */
        uchar_ptr                    buffer,

        /* [IN] number of bytes to read */
        uint_32                      length
    )
{
    VQI2C_INFO_STRUCT_PTR            io_info_ptr;
    VQI2C_REG_STRUCT_PTR             i2c_ptr;
    uint_32                          num;
    volatile uint_8                  tmp;

    io_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
    i2c_ptr = io_info_ptr->I2C_PTR;

    /* Critical section */
    _int_disable();

    /* Get data from input buffer */
    for (num = 0; num < length; num++)
    {
        if (io_info_ptr->RX_OUT == io_info_ptr->RX_IN) break;
        *buffer++ = io_info_ptr->RX_BUFFER[io_info_ptr->RX_OUT++];
        if (io_info_ptr->RX_OUT >= io_info_ptr->INIT.RX_BUFFER_SIZE) io_info_ptr->RX_OUT = 0;
    }

    /* Forced isr needed because of request gets always cleared on PPC (no interrupt disable) */
    if (io_info_ptr->INT_REQUEST)
    {
        _qi2c_int_isr ((pointer)io_info_ptr);
    }

    /* If beginning of transmission, set state and send address (master only) */
    io_info_ptr->OPERATION |= I2C_OPERATION_READ;
    tmp = io_info_ptr->STATE;
    if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
    {
        io_info_ptr->STATE = I2C_STATE_RECEIVE;
        if (I2C_MODE_MASTER == io_info_ptr->MODE)
        {
            i2c_ptr->I2CR |= QI2C_I2CR_TX;
            _PSP_SYNC();
            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
            _PSP_SYNC();
            if (I2C_STATE_REPEATED_START == tmp)
            {
                i2c_ptr->I2CR |= QI2C_I2CR_RSTA;
            }
            else
            {
                i2c_ptr->I2CR |= QI2C_I2CR_MS;
            }
            _PSP_SYNC();
            io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
            i2c_ptr->I2DR = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_READ;
            _PSP_SYNC();
            io_info_ptr->STATISTICS.TX_PACKETS++;
            while (0 == (i2c_ptr->I2SR & QI2C_I2SR_IBIF))
               {_PSP_SYNC();};   /* wait for address transferred */
        }
    }

    /* Check for bus idle in slave mode */
    _PSP_SYNC();
    if (0 == (i2c_ptr->I2CR & QI2C_I2CR_MS))
    {
        if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2c_ptr->I2SR & QI2C_I2SR_IBB)))
        {
            io_info_ptr->OPERATION = 0;
            io_info_ptr->RX_REQUEST = 0;
            io_info_ptr->STATE = I2C_STATE_FINISHED;
        }
    }
   
    /* Interrupt enable - end of critical section */
    _int_enable();
    return num;

}


/*FUNCTION****************************************************************
*
* Function Name    : _qi2c_int_tx
* Returned Value   : number of bytes written
* Comments         :
*   Returns the number of bytes written.
*   Writes the data provided into transmission buffer if available.
*
*END*********************************************************************/

uint_32 _qi2c_int_tx
    (
        /* [IN] the address of the device specific information */
        IO_I2C_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

        /* [IN] The array characters are to be read from */
        uchar_ptr                    buffer,

        /* [IN] number of bytes to output */
        uint_32                      length
    )
{
    VQI2C_INFO_STRUCT_PTR            io_info_ptr;
    VQI2C_REG_STRUCT_PTR             i2c_ptr;
    uint_32                          num, tmp;

    io_info_ptr  = int_io_dev_ptr->DEV_INFO_PTR;
    i2c_ptr = io_info_ptr->I2C_PTR;

    /* Critical section */
    _int_disable();

    /* Fill in the output buffer  */
    for (num = 0; num < length; num++)
    {
        tmp = io_info_ptr->TX_IN + 1;
        if (tmp >= io_info_ptr->INIT.TX_BUFFER_SIZE) tmp = 0;
        if (tmp == io_info_ptr->TX_OUT) break;
        io_info_ptr->TX_BUFFER[io_info_ptr->TX_IN] = *buffer++;
        io_info_ptr->TX_IN = tmp;
    }

    /* Forced isr needed because of request gets always cleared on PPC (no interrupt disable) */
    if (io_info_ptr->INT_REQUEST)
    {
        _qi2c_int_isr ((pointer)io_info_ptr);
    }

    /* If beginning of transmission, set state and send address (master only) */
    io_info_ptr->OPERATION &= (~ I2C_OPERATION_READ);
    tmp = io_info_ptr->STATE;
    if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
    {
        io_info_ptr->STATE = I2C_STATE_TRANSMIT;
        if (I2C_MODE_MASTER == io_info_ptr->MODE)
        {
            i2c_ptr->I2CR |= QI2C_I2CR_TX;
            _PSP_SYNC();
            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
            _PSP_SYNC();
            if (I2C_STATE_REPEATED_START == tmp)
            {
                i2c_ptr->I2CR |= QI2C_I2CR_RSTA;
            }
            else
            {
                i2c_ptr->I2CR |= QI2C_I2CR_MS;
            }
            _PSP_SYNC();
            io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
            i2c_ptr->I2DR = (io_info_ptr->ADDRESSEE << 1) | I2C_OPERATION_WRITE;
            _PSP_SYNC();
            io_info_ptr->STATISTICS.TX_PACKETS++;
            while (0 == (i2c_ptr->I2SR & QI2C_I2SR_IBIF))
               {_PSP_SYNC();};   /* wait for address transferred */
        }
    }

    /* Check for bus idle in slave mode */
    _PSP_SYNC();
    if (0 == (i2c_ptr->I2CR & QI2C_I2CR_MS))
    {
        if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2c_ptr->I2SR & QI2C_I2SR_IBB)))
        {
            io_info_ptr->OPERATION = 0;
            io_info_ptr->RX_REQUEST = 0;
            io_info_ptr->STATE = I2C_STATE_FINISHED;
        }
    }

    /* Interrupt enable - end of critical section */
    _int_enable();
    return num;

}


/*FUNCTION****************************************************************
*
* Function Name    :_qi2c_int_isr
* Returned Value   : none
*
*END*********************************************************************/
static void _qi2c_int_isr
    (
        pointer           parameter
    )
{
    VQI2C_INFO_STRUCT_PTR io_info_ptr = parameter;
    VQI2C_REG_STRUCT_PTR  i2c_ptr = io_info_ptr->I2C_PTR;
    uint_8                i2csr;
    volatile uint_8       tmp;

    i2csr = i2c_ptr->I2SR;
    _PSP_SYNC();
    if (i2csr & QI2C_I2SR_IBIF) 
    {
        io_info_ptr->STATISTICS.INTERRUPTS++;
    }
    io_info_ptr->INT_REQUEST = 0;

    /* Master */
    if (i2c_ptr->I2CR & QI2C_I2CR_MS)
    {
        /* Transmit */
        if (i2c_ptr->I2CR & QI2C_I2CR_TX)
        {
            /* Not ack */
            if (i2csr & QI2C_I2SR_RXAK)
            {
                i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                _PSP_SYNC();                
                io_info_ptr->TX_OUT = io_info_ptr->TX_IN;
                io_info_ptr->STATE = I2C_STATE_FINISHED;
                io_info_ptr->STATISTICS.TX_NAKS++;
            }
            /* Ack */
            else
            {
                /* Transmit requested */
                if (I2C_STATE_TRANSMIT == io_info_ptr->STATE)
                {
                    /* Anything to transmit? */
                    if ((io_info_ptr->TX_IN != io_info_ptr->TX_OUT) && (I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))))
                    {
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        _PSP_SYNC();
                        i2c_ptr->I2DR = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /* transmit data */
                        _PSP_SYNC();
                        if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
                        io_info_ptr->STATISTICS.TX_PACKETS++;
                    }
                    else
                    {
                        if (i2csr & QI2C_I2SR_IBIF)
                        {
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        }
                        io_info_ptr->INT_REQUEST = 1;
                    }
                }
                /* Receive requested */
                else if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
                {
                    if ((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED)))
                    {                
                        i2c_ptr->I2CR &= (~ QI2C_I2CR_TX);
                        _PSP_SYNC();
                        if (1 == io_info_ptr->RX_REQUEST)
                        {
                            i2c_ptr->I2CR |= QI2C_I2CR_NOAK;
                        }
                        else
                        {
                            i2c_ptr->I2CR &= (~ QI2C_I2CR_NOAK);
                        }
                        _PSP_SYNC();
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        _PSP_SYNC();
                        if (0 == io_info_ptr->RX_REQUEST)
                        {
                            io_info_ptr->STATE = I2C_STATE_FINISHED;
                        }
                        else
                        {
                            tmp = i2c_ptr->I2DR;   /* dummy read to clock in 1st byte */
                            _PSP_SYNC();
                        }
                    }
                    else
                    {
                        if (i2csr & QI2C_I2SR_IBIF)
                        {
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        }
                        io_info_ptr->INT_REQUEST = 1;
                    }
                }
                /* Others are unwanted/not handled states */
                else
                {
                    if (i2csr & QI2C_I2SR_IBIF)
                    {
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                    }
                    io_info_ptr->INT_REQUEST = 1;
                }
            }
        }
        /* Receive */
        else
        {
            /* Receive requested */
            if (I2C_STATE_RECEIVE == io_info_ptr->STATE)
            {
                if (((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (0 != io_info_ptr->RX_REQUEST))
                {
                    tmp = io_info_ptr->RX_IN + 1;
                    if (tmp >= io_info_ptr->INIT.RX_BUFFER_SIZE) tmp = 0;

                    /* Buffer full */
                    if (tmp == io_info_ptr->RX_OUT)
                    {
                        if (i2csr & QI2C_I2SR_IBIF)
                        {
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        }
                        io_info_ptr->INT_REQUEST = 1;
                    }
                    /* Buffer not full */
                    else
                    {
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        _PSP_SYNC();
                        io_info_ptr->RX_REQUEST--;
                        if (1 == io_info_ptr->RX_REQUEST)
                        {
                            i2c_ptr->I2CR |= QI2C_I2CR_NOAK;
                        }
                        else
                        {
                            i2c_ptr->I2CR &= (~ QI2C_I2CR_NOAK);
                        }
                        _PSP_SYNC();
                        if (0 == io_info_ptr->RX_REQUEST)
                        {
                            i2c_ptr->I2CR |= QI2C_I2CR_TX;   /* no more reading */
                            _PSP_SYNC();
                        }
                        io_info_ptr->RX_BUFFER[io_info_ptr->RX_IN] = i2c_ptr->I2DR;   /* receive data */
                        _PSP_SYNC();
                        io_info_ptr->RX_IN = tmp;
                        if (0 == io_info_ptr->RX_REQUEST)
                        {
                            i2c_ptr->I2CR &= (~ QI2C_I2CR_TX);
                            _PSP_SYNC();
                            io_info_ptr->STATE = I2C_STATE_FINISHED;
                        }
                        io_info_ptr->STATISTICS.RX_PACKETS++;
                    }
                }
                else
                {
                    if (i2csr & QI2C_I2SR_IBIF)
                    {
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                    }
                    io_info_ptr->INT_REQUEST = 1;
                }
            }
            /* Others are unwanted/not handled states */
            else
            {
                if (i2csr & QI2C_I2SR_IBIF)
                {
                    i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                }
                io_info_ptr->INT_REQUEST = 1;
            }
        }
    }
    /* Slave */
    else
    {
        /* Master arbitration lost */
        if (i2csr & QI2C_I2SR_IBAL)
        {
            i2c_ptr->I2SR |= QI2C_I2SR_IBAL;
            _PSP_SYNC();
            io_info_ptr->STATE = I2C_STATE_LOST_ARBITRATION;
            io_info_ptr->STATISTICS.TX_LOST_ARBITRATIONS++;
        }
        /* Addressed as slave */
        if (i2csr & QI2C_I2SR_IAAS)
        {
            if (I2C_MODE_MASTER == io_info_ptr->MODE)
            {
                io_info_ptr->STATISTICS.TX_ADDRESSED_AS_SLAVE++;
            }
            /* Transmit requested */
            if (i2csr & QI2C_I2SR_SRW)
            {
                io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_TX;
                if ((I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (io_info_ptr->TX_IN != io_info_ptr->TX_OUT))
                {
                    i2c_ptr->I2CR |= QI2C_I2CR_TX;
                    _PSP_SYNC();
                    i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                    _PSP_SYNC();
                    i2c_ptr->I2DR = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /* transmit data */
                    _PSP_SYNC();
                    if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
                    io_info_ptr->STATISTICS.TX_PACKETS++;
                }
                else
                {
                    if (i2csr & QI2C_I2SR_IBIF)
                    {
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                    }
                    io_info_ptr->INT_REQUEST = 1;
                }            
            }
            /* Receive requested */
            else
            {
                io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_RX;
                if (((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (io_info_ptr->RX_OUT == io_info_ptr->RX_IN) && (0 != io_info_ptr->RX_REQUEST))
                {
                    i2c_ptr->I2CR &= (~ QI2C_I2CR_TX);
                    _PSP_SYNC();
                    i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                    _PSP_SYNC();
                    if (1 == io_info_ptr->RX_REQUEST)
                    {
                        i2c_ptr->I2CR |= QI2C_I2CR_NOAK;
                    }
                    else
                    {
                        i2c_ptr->I2CR &= (~ QI2C_I2CR_NOAK);
                    }
                    _PSP_SYNC();
                    tmp = i2c_ptr->I2DR;   /* dummy read to release bus */
                    _PSP_SYNC();
                }
                else
                {
                    if (i2csr & QI2C_I2SR_IBIF)
                    {
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                    }
                    io_info_ptr->INT_REQUEST = 1;
                }
            }
        }
        /* Normal slave operation */
        else
        {
            /* No master arbitration lost */
            if (! (i2csr & QI2C_I2SR_IBAL))
            {
                /* Transmit */
                if (i2c_ptr->I2CR & QI2C_I2CR_TX)
                {
                    /* Not ack */
                    if (i2csr & QI2C_I2SR_RXAK)
                    {
                        i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        _PSP_SYNC();
                        io_info_ptr->TX_OUT = io_info_ptr->TX_IN;
                        io_info_ptr->STATE = I2C_STATE_FINISHED;
                        io_info_ptr->STATISTICS.TX_NAKS++;
                    }
                    /* Ack */
                    else
                    {
                        /* Transmit requested */
                        if (((I2C_STATE_TRANSMIT == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_TX == io_info_ptr->STATE)) 
                           && (io_info_ptr->TX_IN != io_info_ptr->TX_OUT) && (I2C_OPERATION_STARTED == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))))
                        {
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                            _PSP_SYNC();
                            i2c_ptr->I2DR = io_info_ptr->TX_BUFFER[io_info_ptr->TX_OUT++];   /* transmit data */
                            _PSP_SYNC();
                            if (io_info_ptr->TX_OUT >= io_info_ptr->INIT.TX_BUFFER_SIZE) io_info_ptr->TX_OUT = 0;
                            io_info_ptr->STATISTICS.TX_PACKETS++;
                        }
                        else
                        {
                            if (i2csr & QI2C_I2SR_IBIF)
                            {
                                i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                            }
                            io_info_ptr->INT_REQUEST = 1;
                        }
                    }
                }
                /* Receive */
                else
                {
                    /* Receive requested */
                    if (((I2C_STATE_RECEIVE == io_info_ptr->STATE) || (I2C_STATE_ADDRESSED_AS_SLAVE_RX == io_info_ptr->STATE)) 
                       && ((I2C_OPERATION_READ | I2C_OPERATION_STARTED) == (io_info_ptr->OPERATION & (I2C_OPERATION_READ | I2C_OPERATION_STARTED))) && (0 != io_info_ptr->RX_REQUEST))
                    {
                        tmp = io_info_ptr->RX_IN + 1;
                        if (tmp >= io_info_ptr->INIT.RX_BUFFER_SIZE) tmp = 0;
                        if (tmp == io_info_ptr->RX_OUT)
                        {
                            if (i2csr & QI2C_I2SR_IBIF)
                            {
                                i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                            }
                            io_info_ptr->INT_REQUEST = 1;
                        }
                        else
                        {
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                            _PSP_SYNC();
                            io_info_ptr->RX_REQUEST--;
                            if (1 == io_info_ptr->RX_REQUEST)
                            {
                                i2c_ptr->I2CR |= QI2C_I2CR_NOAK;
                            }
                            else
                            {
                                i2c_ptr->I2CR &= (~ QI2C_I2CR_NOAK);
                            }
                            _PSP_SYNC();
                            if (0 == io_info_ptr->RX_REQUEST)
                            {
                                io_info_ptr->STATE = I2C_STATE_FINISHED;
                            }
                            io_info_ptr->RX_BUFFER[io_info_ptr->RX_IN] = i2c_ptr->I2DR;   /* receive data */
                            _PSP_SYNC();
                            io_info_ptr->RX_IN = tmp;
                            io_info_ptr->STATISTICS.RX_PACKETS++;
                        }
                    }
                    else
                    {
                        if (i2csr & QI2C_I2SR_IBIF)
                        {
                            i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                        }
                        io_info_ptr->INT_REQUEST = 1;
                    }
                }
            }
            else
            {
                if (i2csr & QI2C_I2SR_IBIF)
                {
                    i2c_ptr->I2SR |= QI2C_I2SR_IBIF;
                }
                io_info_ptr->INT_REQUEST = 1;
            }
        }
    }
    if (i2csr & QI2C_I2SR_IBIF) 
    {
        io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
    }
}

/* EOF */

<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb_dcd/int/usb_dcd_int_prv.h<|end_filename|>
#ifndef _usb_dcd_int_prv_h_
#define _usb_dcd_int_prv_h_ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_dcd_int_prv.h$
* $Version : 3.8.1.0$
* $Date    : Jul-27-2011$
*
* Comments:
*
*   This file includes the private definitions for the interrupt USB DCD
*   I/O drivers.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/


/*---------------------------------------------------------------------
**
** IO USB DCD INT DEVICE STRUCT
**
** This structure used to store information about an USB DCD interrupt io device
** for the IO device table
*/
typedef struct io_usb_dcd_int_device_struct
{

   /* The I/O init function */
   _mqx_uint (_CODE_PTR_ DEV_INIT)(pointer, char_ptr);

   /* The I/O deinit function */
   _mqx_uint (_CODE_PTR_ DEV_DEINIT)(pointer, pointer);
   
   /* [IN] The READ function */
   _mqx_int  (_CODE_PTR_ DEV_READ)(pointer, char_ptr, _mqx_int);
      
   /* [IN] The WRITE function */
   _mqx_int  (_CODE_PTR_ DEV_WRITE)(pointer, char_ptr, _mqx_int);
   
   /* The ioctl function, (change bauds etc) */
   _mqx_int  (_CODE_PTR_ DEV_IOCTL)(pointer, _mqx_uint, _mqx_uint_ptr);

   /* The I/O channel initialization data */
   pointer               DEV_INIT_DATA_PTR;
   
   /* Device specific information */
   pointer               DEV_INFO_PTR;

   /* Open count for number of accessing file descriptors */
   _mqx_uint             COUNT;

   /* Open flags for this channel */
   _mqx_uint             FLAGS;

} IO_USB_DCD_INT_DEVICE_STRUCT, _PTR_ IO_USB_DCD_INT_DEVICE_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

/* I/O prototypes */
extern _mqx_int _io_usb_dcd_int_open(FILE_DEVICE_STRUCT_PTR, char_ptr, char_ptr);
extern _mqx_int _io_usb_dcd_int_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_usb_dcd_int_read(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_usb_dcd_int_write(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_usb_dcd_int_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);
extern _mqx_int _io_usb_dcd_int_uninstall(IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_SensorGPIO.c<|end_filename|>
/***********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
*********************************************************************************************************************//*!
*
* @file   TSS_SensorGPIO.c
*
* @brief  Contains functions to Perform the sensing of the electrodes and set the status for each electrode
*
* @version 1.0.30.0
* 
* @date Aug-9-2012
* 
*
***********************************************************************************************************************/

#include "TSS_SensorGPIO.h"

#if TSS_DETECT_METHOD(GPIO)

  #include "TSS_Timer.h"
  #include "TSS_GPIO.h"

  #if TSS_HCS08_MCU || TSS_CFV1_MCU             

    #if TSS_USE_SIMPLE_LOW_LEVEL

      /************************ Prototypes *******************************/
      #if TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW 
        void GPIO_ElectrodesSetStateLow(void);
      #else
        void GPIO_ElectrodesSetStateHigh(void);
      #endif
      #if TSS_USE_GPIO_STRENGTH
        UINT8 GPIO_SetPinStrength(void);
      #endif
      #if TSS_USE_GPIO_SLEW_RATE
        UINT8 GPIO_SetPinSlewRate(void);
      #endif
      #if TSS_USE_NOISE_AMPLITUDE_FILTER
        void GPIO_NoiseAmplitudeFilterInit(void); 
      #endif
      #ifdef TSS_ONPROXIMITY_CALLBACK
        void GPIO_ProximityInit(void); 
      #endif
      
      /***************** ROM & RAM Data definition ***********************/
    
      #if TSS_N_ELECTRODES > 0
        #if TSS_DETECT_EL_METHOD(0,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(0),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E0_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 1
        #if TSS_DETECT_EL_METHOD(1,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(1),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E1_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 2
        #if TSS_DETECT_EL_METHOD(2,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(2),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E2_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 3
        #if TSS_DETECT_EL_METHOD(3,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(3),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E3_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 4
        #if TSS_DETECT_EL_METHOD(4,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(4),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E4_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 5
        #if TSS_DETECT_EL_METHOD(5,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(5),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E5_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 6
        #if TSS_DETECT_EL_METHOD(6,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(6),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E6_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 7
        #if TSS_DETECT_EL_METHOD(7,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(7),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E7_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 8
        #if TSS_DETECT_EL_METHOD(8,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(8),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E8_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 9
        #if TSS_DETECT_EL_METHOD(9,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(9),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E9_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 10
        #if TSS_DETECT_EL_METHOD(10,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(10),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E10_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 11
        #if TSS_DETECT_EL_METHOD(11,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(11),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E11_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 12
        #if TSS_DETECT_EL_METHOD(12,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(12),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E12_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 13
        #if TSS_DETECT_EL_METHOD(13,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(13),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E13_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 14
        #if TSS_DETECT_EL_METHOD(14,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(14),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E14_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 15
        #if TSS_DETECT_EL_METHOD(15,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(15),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E15_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 16
        #if TSS_DETECT_EL_METHOD(16,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(16),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E16_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 17
        #if TSS_DETECT_EL_METHOD(17,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(17),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E17_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 18
        #if TSS_DETECT_EL_METHOD(18,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(18),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E18_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 19
        #if TSS_DETECT_EL_METHOD(19,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(19),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E19_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 20
        #if TSS_DETECT_EL_METHOD(20,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(20),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E20_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 21
        #if TSS_DETECT_EL_METHOD(21,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(21),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E21_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 22
        #if TSS_DETECT_EL_METHOD(22,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(22),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E22_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 23
        #if TSS_DETECT_EL_METHOD(23,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(23),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E23_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 24
        #if TSS_DETECT_EL_METHOD(24,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(24),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E24_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 25
        #if TSS_DETECT_EL_METHOD(25,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(25),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E25_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 26
        #if TSS_DETECT_EL_METHOD(26,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(26),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E26_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 27
        #if TSS_DETECT_EL_METHOD(27,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(27),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E27_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 28
        #if TSS_DETECT_EL_METHOD(28,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(28),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E28_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 29
        #if TSS_DETECT_EL_METHOD(29,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(29),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E29_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 30
        #if TSS_DETECT_EL_METHOD(30,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(30),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E30_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 31
        #if TSS_DETECT_EL_METHOD(31,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(31),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E31_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 32
        #if TSS_DETECT_EL_METHOD(32,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(32),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E32_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 33
        #if TSS_DETECT_EL_METHOD(33,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(33),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E33_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 34
        #if TSS_DETECT_EL_METHOD(34,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(34),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E34_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 35
        #if TSS_DETECT_EL_METHOD(35,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(35),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E35_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 36
        #if TSS_DETECT_EL_METHOD(36,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(36),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E36_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 37
        #if TSS_DETECT_EL_METHOD(37,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(37),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E37_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 38
        #if TSS_DETECT_EL_METHOD(38,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(38),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E38_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 39
        #if TSS_DETECT_EL_METHOD(39,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(39),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E39_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 40
        #if TSS_DETECT_EL_METHOD(40,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(40),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E40_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 41
        #if TSS_DETECT_EL_METHOD(41,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(41),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E41_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 42
        #if TSS_DETECT_EL_METHOD(42,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(42),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E42_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 43
        #if TSS_DETECT_EL_METHOD(43,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(43),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E43_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 44
        #if TSS_DETECT_EL_METHOD(44,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(44),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E44_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 45
        #if TSS_DETECT_EL_METHOD(45,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(45),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E45_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 46
        #if TSS_DETECT_EL_METHOD(46,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(46),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E46_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 47
        #if TSS_DETECT_EL_METHOD(47,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(47),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E47_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 48
        #if TSS_DETECT_EL_METHOD(48,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(48),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E48_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 49
        #if TSS_DETECT_EL_METHOD(49,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(49),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E49_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 50
        #if TSS_DETECT_EL_METHOD(50,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(50),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E50_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 51
        #if TSS_DETECT_EL_METHOD(51,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(51),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E51_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 52
        #if TSS_DETECT_EL_METHOD(52,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(52),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E52_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 53
        #if TSS_DETECT_EL_METHOD(53,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(53),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E53_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 54
        #if TSS_DETECT_EL_METHOD(54,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(54),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E54_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 55
        #if TSS_DETECT_EL_METHOD(55,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(55),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E55_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 56
        #if TSS_DETECT_EL_METHOD(56,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(56),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E56_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 57
        #if TSS_DETECT_EL_METHOD(57,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(57),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E57_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 58
        #if TSS_DETECT_EL_METHOD(58,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(58),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E58_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 59
        #if TSS_DETECT_EL_METHOD(59,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(59),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E59_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 60
        #if TSS_DETECT_EL_METHOD(60,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(60),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E60_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 61
        #if TSS_DETECT_EL_METHOD(61,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(61),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E61_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 62
        #if TSS_DETECT_EL_METHOD(62,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(62),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E62_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 63
        #if TSS_DETECT_EL_METHOD(63,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { TSS_GET_EL_MODULE_ID(63),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E63_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
  
      /***************************************************************************//*!
      *
      * @brief  Sets the electrode state as output low
      *
      * @param  void
      *
      * @return void
      *
      * @remarks
      *
      ****************************************************************************/
#if TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW
      void GPIO_ElectrodesSetStateLow(void)
      {
        #if TSS_N_ELECTRODES > 0
          #if TSS_DETECT_EL_METHOD(0,GPIO)
            TSS_ELECTRODE_LOW(0);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 1
          #if TSS_DETECT_EL_METHOD(1,GPIO)
            TSS_ELECTRODE_LOW(1);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 2
          #if TSS_DETECT_EL_METHOD(2,GPIO)
            TSS_ELECTRODE_LOW(2);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 3
          #if TSS_DETECT_EL_METHOD(3,GPIO)
            TSS_ELECTRODE_LOW(3);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 4
          #if TSS_DETECT_EL_METHOD(4,GPIO)
            TSS_ELECTRODE_LOW(4);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 5
          #if TSS_DETECT_EL_METHOD(5,GPIO)
            TSS_ELECTRODE_LOW(5);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 6
          #if TSS_DETECT_EL_METHOD(6,GPIO)
            TSS_ELECTRODE_LOW(6);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 7
          #if TSS_DETECT_EL_METHOD(7,GPIO)
            TSS_ELECTRODE_LOW(7);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 8
          #if TSS_DETECT_EL_METHOD(8,GPIO)
            TSS_ELECTRODE_LOW(8);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 9
          #if TSS_DETECT_EL_METHOD(9,GPIO)
            TSS_ELECTRODE_LOW(9);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 10
          #if TSS_DETECT_EL_METHOD(10,GPIO)
            TSS_ELECTRODE_LOW(10);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 11
          #if TSS_DETECT_EL_METHOD(11,GPIO)
            TSS_ELECTRODE_LOW(11);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 12
          #if TSS_DETECT_EL_METHOD(12,GPIO)
            TSS_ELECTRODE_LOW(12);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 13
          #if TSS_DETECT_EL_METHOD(13,GPIO)
            TSS_ELECTRODE_LOW(13);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 14
          #if TSS_DETECT_EL_METHOD(14,GPIO)
            TSS_ELECTRODE_LOW(14);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 15
          #if TSS_DETECT_EL_METHOD(15,GPIO)
            TSS_ELECTRODE_LOW(15);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 16
          #if TSS_DETECT_EL_METHOD(16,GPIO)
            TSS_ELECTRODE_LOW(16);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 17
          #if TSS_DETECT_EL_METHOD(17,GPIO)
            TSS_ELECTRODE_LOW(17);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 18
          #if TSS_DETECT_EL_METHOD(18,GPIO)
            TSS_ELECTRODE_LOW(18);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 19
          #if TSS_DETECT_EL_METHOD(19,GPIO)
            TSS_ELECTRODE_LOW(19);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 20
          #if TSS_DETECT_EL_METHOD(20,GPIO)
            TSS_ELECTRODE_LOW(20);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 21
          #if TSS_DETECT_EL_METHOD(21,GPIO)
            TSS_ELECTRODE_LOW(21);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 22
          #if TSS_DETECT_EL_METHOD(22,GPIO)
            TSS_ELECTRODE_LOW(22);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 23
          #if TSS_DETECT_EL_METHOD(23,GPIO)
            TSS_ELECTRODE_LOW(23);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 24
          #if TSS_DETECT_EL_METHOD(24,GPIO)
            TSS_ELECTRODE_LOW(24);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 25
          #if TSS_DETECT_EL_METHOD(25,GPIO)
            TSS_ELECTRODE_LOW(25);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 26
          #if TSS_DETECT_EL_METHOD(26,GPIO)
            TSS_ELECTRODE_LOW(26);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 27
          #if TSS_DETECT_EL_METHOD(27,GPIO)
            TSS_ELECTRODE_LOW(27);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 28
          #if TSS_DETECT_EL_METHOD(28,GPIO)
            TSS_ELECTRODE_LOW(28);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 29
          #if TSS_DETECT_EL_METHOD(29,GPIO)
            TSS_ELECTRODE_LOW(29);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 30
          #if TSS_DETECT_EL_METHOD(30,GPIO)
            TSS_ELECTRODE_LOW(30);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 31
          #if TSS_DETECT_EL_METHOD(31,GPIO)
            TSS_ELECTRODE_LOW(31);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 32
          #if TSS_DETECT_EL_METHOD(32,GPIO)
            TSS_ELECTRODE_LOW(32);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 33
          #if TSS_DETECT_EL_METHOD(33,GPIO)
            TSS_ELECTRODE_LOW(33);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 34
          #if TSS_DETECT_EL_METHOD(34,GPIO)
            TSS_ELECTRODE_LOW(34);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 35
          #if TSS_DETECT_EL_METHOD(35,GPIO)
            TSS_ELECTRODE_LOW(35);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 36
          #if TSS_DETECT_EL_METHOD(36,GPIO)
            TSS_ELECTRODE_LOW(36);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 37
          #if TSS_DETECT_EL_METHOD(37,GPIO)
            TSS_ELECTRODE_LOW(37);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 38
          #if TSS_DETECT_EL_METHOD(38,GPIO)
            TSS_ELECTRODE_LOW(38);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 39
          #if TSS_DETECT_EL_METHOD(39,GPIO)
            TSS_ELECTRODE_LOW(39);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 40
          #if TSS_DETECT_EL_METHOD(40,GPIO)
            TSS_ELECTRODE_LOW(40);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 41
          #if TSS_DETECT_EL_METHOD(41,GPIO)
            TSS_ELECTRODE_LOW(41);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 42
          #if TSS_DETECT_EL_METHOD(42,GPIO)
            TSS_ELECTRODE_LOW(42);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 43
          #if TSS_DETECT_EL_METHOD(43,GPIO)
            TSS_ELECTRODE_LOW(43);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 44
          #if TSS_DETECT_EL_METHOD(44,GPIO)
            TSS_ELECTRODE_LOW(44);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 45
          #if TSS_DETECT_EL_METHOD(45,GPIO)
            TSS_ELECTRODE_LOW(45);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 46
          #if TSS_DETECT_EL_METHOD(46,GPIO)
            TSS_ELECTRODE_LOW(46);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 47
          #if TSS_DETECT_EL_METHOD(47,GPIO)
            TSS_ELECTRODE_LOW(47);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 48
          #if TSS_DETECT_EL_METHOD(48,GPIO)
            TSS_ELECTRODE_LOW(48);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 49
          #if TSS_DETECT_EL_METHOD(49,GPIO)
            TSS_ELECTRODE_LOW(49);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 50
          #if TSS_DETECT_EL_METHOD(50,GPIO)
            TSS_ELECTRODE_LOW(50);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 51
          #if TSS_DETECT_EL_METHOD(51,GPIO)
            TSS_ELECTRODE_LOW(51);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 52
          #if TSS_DETECT_EL_METHOD(52,GPIO)
            TSS_ELECTRODE_LOW(52);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 53
          #if TSS_DETECT_EL_METHOD(53,GPIO)
            TSS_ELECTRODE_LOW(53);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 54
          #if TSS_DETECT_EL_METHOD(54,GPIO)
            TSS_ELECTRODE_LOW(54);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 55
          #if TSS_DETECT_EL_METHOD(55,GPIO)
            TSS_ELECTRODE_LOW(55);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 56
          #if TSS_DETECT_EL_METHOD(56,GPIO)
            TSS_ELECTRODE_LOW(56);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 57
          #if TSS_DETECT_EL_METHOD(57,GPIO)
            TSS_ELECTRODE_LOW(57);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 58
          #if TSS_DETECT_EL_METHOD(58,GPIO)
            TSS_ELECTRODE_LOW(58);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 59
          #if TSS_DETECT_EL_METHOD(59,GPIO)
            TSS_ELECTRODE_LOW(59);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 60
          #if TSS_DETECT_EL_METHOD(60,GPIO)
            TSS_ELECTRODE_LOW(60);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 61
          #if TSS_DETECT_EL_METHOD(61,GPIO)
            TSS_ELECTRODE_LOW(61);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 62
          #if TSS_DETECT_EL_METHOD(62,GPIO)
            TSS_ELECTRODE_LOW(62);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 63
          #if TSS_DETECT_EL_METHOD(63,GPIO)
            TSS_ELECTRODE_LOW(63);
          #endif
        #endif
      }
#else     
      /***************************************************************************//*!
      *
      * @brief  Sets the electrode state as output high
      *
      * @param  void
      *
      * @return void
      *
      * @remarks
      *
      ****************************************************************************/
      void GPIO_ElectrodesSetStateHigh(void)
      {
        #if TSS_N_ELECTRODES > 0
          #if TSS_DETECT_EL_METHOD(0,GPIO)
            TSS_ELECTRODE_HIGH(0);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 1
          #if TSS_DETECT_EL_METHOD(1,GPIO)
            TSS_ELECTRODE_HIGH(1);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 2
          #if TSS_DETECT_EL_METHOD(2,GPIO)
            TSS_ELECTRODE_HIGH(2);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 3
          #if TSS_DETECT_EL_METHOD(3,GPIO)
            TSS_ELECTRODE_HIGH(3);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 4
          #if TSS_DETECT_EL_METHOD(4,GPIO)
            TSS_ELECTRODE_HIGH(4);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 5
          #if TSS_DETECT_EL_METHOD(5,GPIO)
            TSS_ELECTRODE_HIGH(5);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 6
          #if TSS_DETECT_EL_METHOD(6,GPIO)
            TSS_ELECTRODE_HIGH(6);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 7
          #if TSS_DETECT_EL_METHOD(7,GPIO)
            TSS_ELECTRODE_HIGH(7);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 8
          #if TSS_DETECT_EL_METHOD(8,GPIO)
            TSS_ELECTRODE_HIGH(8);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 9
          #if TSS_DETECT_EL_METHOD(9,GPIO)
            TSS_ELECTRODE_HIGH(9);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 10
          #if TSS_DETECT_EL_METHOD(10,GPIO)
            TSS_ELECTRODE_HIGH(10);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 11
          #if TSS_DETECT_EL_METHOD(11,GPIO)
            TSS_ELECTRODE_HIGH(11);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 12
          #if TSS_DETECT_EL_METHOD(12,GPIO)
            TSS_ELECTRODE_HIGH(12);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 13
          #if TSS_DETECT_EL_METHOD(13,GPIO)
            TSS_ELECTRODE_HIGH(13);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 14
          #if TSS_DETECT_EL_METHOD(14,GPIO)
            TSS_ELECTRODE_HIGH(14);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 15
          #if TSS_DETECT_EL_METHOD(15,GPIO)
            TSS_ELECTRODE_HIGH(15);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 16
          #if TSS_DETECT_EL_METHOD(16,GPIO)
            TSS_ELECTRODE_HIGH(16);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 17
          #if TSS_DETECT_EL_METHOD(17,GPIO)
            TSS_ELECTRODE_HIGH(17);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 18
          #if TSS_DETECT_EL_METHOD(18,GPIO)
            TSS_ELECTRODE_HIGH(18);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 19
          #if TSS_DETECT_EL_METHOD(19,GPIO)
            TSS_ELECTRODE_HIGH(19);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 20
          #if TSS_DETECT_EL_METHOD(20,GPIO)
            TSS_ELECTRODE_HIGH(20);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 21
          #if TSS_DETECT_EL_METHOD(21,GPIO)
            TSS_ELECTRODE_HIGH(21);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 22
          #if TSS_DETECT_EL_METHOD(22,GPIO)
            TSS_ELECTRODE_HIGH(22);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 23
          #if TSS_DETECT_EL_METHOD(23,GPIO)
            TSS_ELECTRODE_HIGH(23);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 24
          #if TSS_DETECT_EL_METHOD(24,GPIO)
            TSS_ELECTRODE_HIGH(24);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 25
          #if TSS_DETECT_EL_METHOD(25,GPIO)
            TSS_ELECTRODE_HIGH(25);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 26
          #if TSS_DETECT_EL_METHOD(26,GPIO)
            TSS_ELECTRODE_HIGH(26);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 27
          #if TSS_DETECT_EL_METHOD(27,GPIO)
            TSS_ELECTRODE_HIGH(27);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 28
          #if TSS_DETECT_EL_METHOD(28,GPIO)
            TSS_ELECTRODE_HIGH(28);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 29
          #if TSS_DETECT_EL_METHOD(29,GPIO)
            TSS_ELECTRODE_HIGH(29);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 30
          #if TSS_DETECT_EL_METHOD(30,GPIO)
            TSS_ELECTRODE_HIGH(30);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 31
          #if TSS_DETECT_EL_METHOD(31,GPIO)
            TSS_ELECTRODE_HIGH(31);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 32
          #if TSS_DETECT_EL_METHOD(32,GPIO)
            TSS_ELECTRODE_HIGH(32);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 33
          #if TSS_DETECT_EL_METHOD(33,GPIO)
            TSS_ELECTRODE_HIGH(33);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 34
          #if TSS_DETECT_EL_METHOD(34,GPIO)
            TSS_ELECTRODE_HIGH(34);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 35
          #if TSS_DETECT_EL_METHOD(35,GPIO)
            TSS_ELECTRODE_HIGH(35);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 36
          #if TSS_DETECT_EL_METHOD(36,GPIO)
            TSS_ELECTRODE_HIGH(36);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 37
          #if TSS_DETECT_EL_METHOD(37,GPIO)
            TSS_ELECTRODE_HIGH(37);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 38
          #if TSS_DETECT_EL_METHOD(38,GPIO)
            TSS_ELECTRODE_HIGH(38);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 39
          #if TSS_DETECT_EL_METHOD(39,GPIO)
            TSS_ELECTRODE_HIGH(39);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 40
          #if TSS_DETECT_EL_METHOD(40,GPIO)
            TSS_ELECTRODE_HIGH(40);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 41
          #if TSS_DETECT_EL_METHOD(41,GPIO)
            TSS_ELECTRODE_HIGH(41);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 42
          #if TSS_DETECT_EL_METHOD(42,GPIO)
            TSS_ELECTRODE_HIGH(42);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 43
          #if TSS_DETECT_EL_METHOD(43,GPIO)
            TSS_ELECTRODE_HIGH(43);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 44
          #if TSS_DETECT_EL_METHOD(44,GPIO)
            TSS_ELECTRODE_HIGH(44);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 45
          #if TSS_DETECT_EL_METHOD(45,GPIO)
            TSS_ELECTRODE_HIGH(45);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 46
          #if TSS_DETECT_EL_METHOD(46,GPIO)
            TSS_ELECTRODE_HIGH(46);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 47
          #if TSS_DETECT_EL_METHOD(47,GPIO)
            TSS_ELECTRODE_HIGH(47);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 48
          #if TSS_DETECT_EL_METHOD(48,GPIO)
            TSS_ELECTRODE_HIGH(48);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 49
          #if TSS_DETECT_EL_METHOD(49,GPIO)
            TSS_ELECTRODE_HIGH(49);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 50
          #if TSS_DETECT_EL_METHOD(50,GPIO)
            TSS_ELECTRODE_HIGH(50);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 51
          #if TSS_DETECT_EL_METHOD(51,GPIO)
            TSS_ELECTRODE_HIGH(51);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 52
          #if TSS_DETECT_EL_METHOD(52,GPIO)
            TSS_ELECTRODE_HIGH(52);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 53
          #if TSS_DETECT_EL_METHOD(53,GPIO)
            TSS_ELECTRODE_HIGH(53);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 54
          #if TSS_DETECT_EL_METHOD(54,GPIO)
            TSS_ELECTRODE_HIGH(54);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 55
          #if TSS_DETECT_EL_METHOD(55,GPIO)
            TSS_ELECTRODE_HIGH(55);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 56
          #if TSS_DETECT_EL_METHOD(56,GPIO)
            TSS_ELECTRODE_HIGH(56);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 57
          #if TSS_DETECT_EL_METHOD(57,GPIO)
            TSS_ELECTRODE_HIGH(57);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 58
          #if TSS_DETECT_EL_METHOD(58,GPIO)
            TSS_ELECTRODE_HIGH(58);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 59
          #if TSS_DETECT_EL_METHOD(59,GPIO)
            TSS_ELECTRODE_HIGH(59);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 60
          #if TSS_DETECT_EL_METHOD(60,GPIO)
            TSS_ELECTRODE_HIGH(60);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 61
          #if TSS_DETECT_EL_METHOD(61,GPIO)
            TSS_ELECTRODE_HIGH(61);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 62
          #if TSS_DETECT_EL_METHOD(62,GPIO)
            TSS_ELECTRODE_HIGH(62);
          #endif
        #endif
        #if TSS_N_ELECTRODES > 63
          #if TSS_DETECT_EL_METHOD(63,GPIO)
            TSS_ELECTRODE_HIGH(63);
          #endif
        #endif
      }
#endif
      /***************************************************************************//*!
      *
      * @brief  Performs setting of Strength on each defined GPIO pin
      *
      * @param  Nothing
      *
      * @return Status Code
      *
      * @remarks If the setting is not possible the function shows a Warning
      *
      ****************************************************************************/
      #if TSS_USE_GPIO_STRENGTH
      UINT8 GPIO_SetPinStrength(void)
      {
        UINT8 u8result = TSS_STATUS_OK;                /* Sets return status code */
        
        #if TSS_N_ELECTRODES > 0
          #if TSS_DETECT_EL_METHOD(0,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(0)
              TSS_ELECTRODE_STRENGTH_SET(0);
            #else
              #warning "TSS - The electrode E0 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 1
          #if TSS_DETECT_EL_METHOD(1,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(1)
              TSS_ELECTRODE_STRENGTH_SET(1);
            #else
              #warning "TSS - The electrode E1 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 2
          #if TSS_DETECT_EL_METHOD(2,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(2)
              TSS_ELECTRODE_STRENGTH_SET(2);
            #else
              #warning "TSS - The electrode E2 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 3
          #if TSS_DETECT_EL_METHOD(3,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(3)
              TSS_ELECTRODE_STRENGTH_SET(3);
            #else
              #warning "TSS - The electrode E3 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 4
          #if TSS_DETECT_EL_METHOD(4,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(4)
              TSS_ELECTRODE_STRENGTH_SET(4);
            #else
              #warning "TSS - The electrode E4 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 5
          #if TSS_DETECT_EL_METHOD(5,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(5)
              TSS_ELECTRODE_STRENGTH_SET(5);
            #else
              #warning "TSS - The electrode E5 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 6
          #if TSS_DETECT_EL_METHOD(6,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(6)
              TSS_ELECTRODE_STRENGTH_SET(6);
            #else
              #warning "TSS - The electrode E6 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 7
          #if TSS_DETECT_EL_METHOD(7,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(7)
              TSS_ELECTRODE_STRENGTH_SET(7);
            #else
              #warning "TSS - The electrode E7 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 8
          #if TSS_DETECT_EL_METHOD(8,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(8)
              TSS_ELECTRODE_STRENGTH_SET(8);
            #else
              #warning "TSS - The electrode E8 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 9
          #if TSS_DETECT_EL_METHOD(9,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(9)
              TSS_ELECTRODE_STRENGTH_SET(9);
            #else
              #warning "TSS - The electrode E9 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 10
          #if TSS_DETECT_EL_METHOD(10,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(10)
              TSS_ELECTRODE_STRENGTH_SET(10);
            #else
              #warning "TSS - The electrode E10 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 11
          #if TSS_DETECT_EL_METHOD(11,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(11)
              TSS_ELECTRODE_STRENGTH_SET(11);
            #else
              #warning "TSS - The electrode E11 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 12
          #if TSS_DETECT_EL_METHOD(12,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(12)
              TSS_ELECTRODE_STRENGTH_SET(12);
            #else
              #warning "TSS - The electrode E12 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 13
          #if TSS_DETECT_EL_METHOD(13,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(13)
              TSS_ELECTRODE_STRENGTH_SET(13);
            #else
              #warning "TSS - The electrode E13 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 14
          #if TSS_DETECT_EL_METHOD(14,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(14)
              TSS_ELECTRODE_STRENGTH_SET(14);
            #else
              #warning "TSS - The electrode E14 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 15
          #if TSS_DETECT_EL_METHOD(15,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(15)
              TSS_ELECTRODE_STRENGTH_SET(15);
            #else
              #warning "TSS - The electrode E15 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 16
          #if TSS_DETECT_EL_METHOD(16,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(16)
              TSS_ELECTRODE_STRENGTH_SET(16);
            #else
              #warning "TSS - The electrode E16 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 17
          #if TSS_DETECT_EL_METHOD(17,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(17)
              TSS_ELECTRODE_STRENGTH_SET(17);
            #else
              #warning "TSS - The electrode E17 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 18
          #if TSS_DETECT_EL_METHOD(18,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(18)
              TSS_ELECTRODE_STRENGTH_SET(18);
            #else
              #warning "TSS - The electrode E18 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 19
          #if TSS_DETECT_EL_METHOD(19,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(19)
              TSS_ELECTRODE_STRENGTH_SET(19);
            #else
              #warning "TSS - The electrode E19 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 20
          #if TSS_DETECT_EL_METHOD(20,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(20)
              TSS_ELECTRODE_STRENGTH_SET(20);
            #else
              #warning "TSS - The electrode E20 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 21
          #if TSS_DETECT_EL_METHOD(21,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(21)
              TSS_ELECTRODE_STRENGTH_SET(21);
            #else
              #warning "TSS - The electrode E21 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 22
          #if TSS_DETECT_EL_METHOD(22,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(22)
              TSS_ELECTRODE_STRENGTH_SET(22);
            #else
              #warning "TSS - The electrode E22 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 23
          #if TSS_DETECT_EL_METHOD(23,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(23)
              TSS_ELECTRODE_STRENGTH_SET(23);
            #else
              #warning "TSS - The electrode E23 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 24
          #if TSS_DETECT_EL_METHOD(24,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(24)
              TSS_ELECTRODE_STRENGTH_SET(24);
            #else
              #warning "TSS - The electrode E24 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 25
          #if TSS_DETECT_EL_METHOD(25,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(25)
              TSS_ELECTRODE_STRENGTH_SET(25);
            #else
              #warning "TSS - The electrode E25 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 26
          #if TSS_DETECT_EL_METHOD(26,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(26)
              TSS_ELECTRODE_STRENGTH_SET(26);
            #else
              #warning "TSS - The electrode E26 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 27
          #if TSS_DETECT_EL_METHOD(27,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(27)
              TSS_ELECTRODE_STRENGTH_SET(27);
            #else
              #warning "TSS - The electrode E27 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 28
          #if TSS_DETECT_EL_METHOD(28,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(28)
              TSS_ELECTRODE_STRENGTH_SET(28);
            #else
              #warning "TSS - The electrode E28 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 29
          #if TSS_DETECT_EL_METHOD(29,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(29)
              TSS_ELECTRODE_STRENGTH_SET(29);
            #else
              #warning "TSS - The electrode E29 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 30
          #if TSS_DETECT_EL_METHOD(30,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(30)
              TSS_ELECTRODE_STRENGTH_SET(30);
            #else
              #warning "TSS - The electrode E30 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 31
          #if TSS_DETECT_EL_METHOD(31,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(31)
              TSS_ELECTRODE_STRENGTH_SET(31);
            #else
              #warning "TSS - The electrode E31 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 32
          #if TSS_DETECT_EL_METHOD(32,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(32)
              TSS_ELECTRODE_STRENGTH_SET(32);
            #else
              #warning "TSS - The electrode E32 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 33
          #if TSS_DETECT_EL_METHOD(33,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(33)
              TSS_ELECTRODE_STRENGTH_SET(33);
            #else
              #warning "TSS - The electrode E33 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 34
          #if TSS_DETECT_EL_METHOD(34,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(34)
              TSS_ELECTRODE_STRENGTH_SET(34);
            #else
              #warning "TSS - The electrode E34 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 35
          #if TSS_DETECT_EL_METHOD(35,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(35)
              TSS_ELECTRODE_STRENGTH_SET(35);
            #else
              #warning "TSS - The electrode E35 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 36
          #if TSS_DETECT_EL_METHOD(36,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(36)
              TSS_ELECTRODE_STRENGTH_SET(36);
            #else
              #warning "TSS - The electrode E36 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 37
          #if TSS_DETECT_EL_METHOD(37,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(37)
              TSS_ELECTRODE_STRENGTH_SET(37);
            #else
              #warning "TSS - The electrode E37 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 38
          #if TSS_DETECT_EL_METHOD(38,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(38)
              TSS_ELECTRODE_STRENGTH_SET(38);
            #else
              #warning "TSS - The electrode E38 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 39
          #if TSS_DETECT_EL_METHOD(39,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(39)
              TSS_ELECTRODE_STRENGTH_SET(39);
            #else
              #warning "TSS - The electrode E39 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 40
          #if TSS_DETECT_EL_METHOD(40,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(40)
              TSS_ELECTRODE_STRENGTH_SET(40);
            #else
              #warning "TSS - The electrode E40 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 41
          #if TSS_DETECT_EL_METHOD(41,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(41)
              TSS_ELECTRODE_STRENGTH_SET(41);
            #else
              #warning "TSS - The electrode E41 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 42
          #if TSS_DETECT_EL_METHOD(42,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(42)
              TSS_ELECTRODE_STRENGTH_SET(42);
            #else
              #warning "TSS - The electrode E42 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 43
          #if TSS_DETECT_EL_METHOD(43,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(43)
              TSS_ELECTRODE_STRENGTH_SET(43);
            #else
              #warning "TSS - The electrode E43 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 44
          #if TSS_DETECT_EL_METHOD(44,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(44)
              TSS_ELECTRODE_STRENGTH_SET(44);
            #else
              #warning "TSS - The electrode E44 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 45
          #if TSS_DETECT_EL_METHOD(45,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(45)
              TSS_ELECTRODE_STRENGTH_SET(45);
            #else
              #warning "TSS - The electrode E45 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 46
          #if TSS_DETECT_EL_METHOD(46,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(46)
              TSS_ELECTRODE_STRENGTH_SET(46);
            #else
              #warning "TSS - The electrode E46 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 47
          #if TSS_DETECT_EL_METHOD(47,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(47)
              TSS_ELECTRODE_STRENGTH_SET(47);
            #else
              #warning "TSS - The electrode E47 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 48
          #if TSS_DETECT_EL_METHOD(48,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(48)
              TSS_ELECTRODE_STRENGTH_SET(48);
            #else
              #warning "TSS - The electrode E48 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 49
          #if TSS_DETECT_EL_METHOD(49,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(49)
              TSS_ELECTRODE_STRENGTH_SET(49);
            #else
              #warning "TSS - The electrode E49 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 50
          #if TSS_DETECT_EL_METHOD(50,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(50)
              TSS_ELECTRODE_STRENGTH_SET(50);
            #else
              #warning "TSS - The electrode E50 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 51
          #if TSS_DETECT_EL_METHOD(51,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(51)
              TSS_ELECTRODE_STRENGTH_SET(51);
            #else
              #warning "TSS - The electrode E51 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 52
          #if TSS_DETECT_EL_METHOD(52,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(52)
              TSS_ELECTRODE_STRENGTH_SET(52);
            #else
              #warning "TSS - The electrode E52 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 53
          #if TSS_DETECT_EL_METHOD(53,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(53)
              TSS_ELECTRODE_STRENGTH_SET(53);
            #else
              #warning "TSS - The electrode E53 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 54
          #if TSS_DETECT_EL_METHOD(54,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(54)
              TSS_ELECTRODE_STRENGTH_SET(54);
            #else
              #warning "TSS - The electrode E54 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 55
          #if TSS_DETECT_EL_METHOD(55,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(55)
              TSS_ELECTRODE_STRENGTH_SET(55);
            #else
              #warning "TSS - The electrode E55 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 56
          #if TSS_DETECT_EL_METHOD(56,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(56)
              TSS_ELECTRODE_STRENGTH_SET(56);
            #else
              #warning "TSS - The electrode E56 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 57
          #if TSS_DETECT_EL_METHOD(57,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(57)
              TSS_ELECTRODE_STRENGTH_SET(57);
            #else
              #warning "TSS - The electrode E57 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 58
          #if TSS_DETECT_EL_METHOD(58,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(58)
              TSS_ELECTRODE_STRENGTH_SET(58);
            #else
              #warning "TSS - The electrode E58 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 59
          #if TSS_DETECT_EL_METHOD(59,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(59)
              TSS_ELECTRODE_STRENGTH_SET(59);
            #else
              #warning "TSS - The electrode E59 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 60
          #if TSS_DETECT_EL_METHOD(60,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(60)
              TSS_ELECTRODE_STRENGTH_SET(60);
            #else
              #warning "TSS - The electrode E60 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 61
          #if TSS_DETECT_EL_METHOD(61,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(61)
              TSS_ELECTRODE_STRENGTH_SET(61);
            #else
              #warning "TSS - The electrode E61 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 62
          #if TSS_DETECT_EL_METHOD(62,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(62)
              TSS_ELECTRODE_STRENGTH_SET(62);
            #else
              #warning "TSS - The electrode E62 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 63
          #if TSS_DETECT_EL_METHOD(63,GPIO)
            #if TSS_ELECTRODE_STRENGTH_CHECK(63)
              TSS_ELECTRODE_STRENGTH_SET(63);
            #else
              #warning "TSS - The electrode E63 does not provide STRENGTH feature"
            #endif
          #endif
        #endif
        
        return u8result;
      }
      #endif
      
      /***************************************************************************//*!
      *
      * @brief  Performs setting of Slew Rate on each defined GPIO pin
      *
      * @param  Nothing
      *
      * @return Status Code
      *
      * @remarks If the setting is not possible the function shows a Warning
      *
      ****************************************************************************/
      #if TSS_USE_GPIO_SLEW_RATE
      UINT8 GPIO_SetPinSlewRate(void)
      {
        UINT8 u8result = TSS_STATUS_OK;                /* Sets return status code */
        
        #if TSS_N_ELECTRODES > 0
          #if TSS_DETECT_EL_METHOD(0,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(0)
              TSS_ELECTRODE_SLEWRATE_SET(0);
            #else
              #warning "TSS - The electrode E0 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 1
          #if TSS_DETECT_EL_METHOD(1,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(1)
              TSS_ELECTRODE_SLEWRATE_SET(1);
            #else
              #warning "TSS - The electrode E1 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 2
          #if TSS_DETECT_EL_METHOD(2,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(2)
              TSS_ELECTRODE_SLEWRATE_SET(2);
            #else
              #warning "TSS - The electrode E2 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 3
          #if TSS_DETECT_EL_METHOD(3,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(3)
              TSS_ELECTRODE_SLEWRATE_SET(3);
            #else
              #warning "TSS - The electrode E3 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 4
          #if TSS_DETECT_EL_METHOD(4,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(4)
              TSS_ELECTRODE_SLEWRATE_SET(4);
            #else
              #warning "TSS - The electrode E4 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 5
          #if TSS_DETECT_EL_METHOD(5,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(5)
              TSS_ELECTRODE_SLEWRATE_SET(5);
            #else
              #warning "TSS - The electrode E5 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 6
          #if TSS_DETECT_EL_METHOD(6,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(6)
              TSS_ELECTRODE_SLEWRATE_SET(6);
            #else
              #warning "TSS - The electrode E6 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 7
          #if TSS_DETECT_EL_METHOD(7,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(7)
              TSS_ELECTRODE_SLEWRATE_SET(7);
            #else
              #warning "TSS - The electrode E7 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 8
          #if TSS_DETECT_EL_METHOD(8,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(8)
              TSS_ELECTRODE_SLEWRATE_SET(8);
            #else
              #warning "TSS - The electrode E8 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 9
          #if TSS_DETECT_EL_METHOD(9,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(9)
              TSS_ELECTRODE_SLEWRATE_SET(9);
            #else
              #warning "TSS - The electrode E9 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 10
          #if TSS_DETECT_EL_METHOD(10,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(10)
              TSS_ELECTRODE_SLEWRATE_SET(10);
            #else
              #warning "TSS - The electrode E10 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 11
          #if TSS_DETECT_EL_METHOD(11,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(11)
              TSS_ELECTRODE_SLEWRATE_SET(11);
            #else
              #warning "TSS - The electrode E11 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 12
          #if TSS_DETECT_EL_METHOD(12,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(12)
              TSS_ELECTRODE_SLEWRATE_SET(12);
            #else
              #warning "TSS - The electrode E12 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 13
          #if TSS_DETECT_EL_METHOD(13,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(13)
              TSS_ELECTRODE_SLEWRATE_SET(13);
            #else
              #warning "TSS - The electrode E13 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 14
          #if TSS_DETECT_EL_METHOD(14,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(14)
              TSS_ELECTRODE_SLEWRATE_SET(14);
            #else
              #warning "TSS - The electrode E14 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 15
          #if TSS_DETECT_EL_METHOD(15,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(15)
              TSS_ELECTRODE_SLEWRATE_SET(15);
            #else
              #warning "TSS - The electrode E15 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 16
          #if TSS_DETECT_EL_METHOD(16,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(16)
              TSS_ELECTRODE_SLEWRATE_SET(16);
            #else
              #warning "TSS - The electrode E16 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 17
          #if TSS_DETECT_EL_METHOD(17,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(17)
              TSS_ELECTRODE_SLEWRATE_SET(17);
            #else
              #warning "TSS - The electrode E17 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 18
          #if TSS_DETECT_EL_METHOD(18,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(18)
              TSS_ELECTRODE_SLEWRATE_SET(18);
            #else
              #warning "TSS - The electrode E18 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 19
          #if TSS_DETECT_EL_METHOD(19,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(19)
              TSS_ELECTRODE_SLEWRATE_SET(19);
            #else
              #warning "TSS - The electrode E19 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 20
          #if TSS_DETECT_EL_METHOD(20,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(20)
              TSS_ELECTRODE_SLEWRATE_SET(20);
            #else
              #warning "TSS - The electrode E20 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 21
          #if TSS_DETECT_EL_METHOD(21,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(21)
              TSS_ELECTRODE_SLEWRATE_SET(21);
            #else
              #warning "TSS - The electrode E21 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 22
          #if TSS_DETECT_EL_METHOD(22,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(22)
              TSS_ELECTRODE_SLEWRATE_SET(22);
            #else
              #warning "TSS - The electrode E22 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 23
          #if TSS_DETECT_EL_METHOD(23,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(23)
              TSS_ELECTRODE_SLEWRATE_SET(23);
            #else
              #warning "TSS - The electrode E23 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 24
          #if TSS_DETECT_EL_METHOD(24,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(24)
              TSS_ELECTRODE_SLEWRATE_SET(24);
            #else
              #warning "TSS - The electrode E24 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 25
          #if TSS_DETECT_EL_METHOD(25,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(25)
              TSS_ELECTRODE_SLEWRATE_SET(25);
            #else
              #warning "TSS - The electrode E25 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 26
          #if TSS_DETECT_EL_METHOD(26,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(26)
              TSS_ELECTRODE_SLEWRATE_SET(26);
            #else
              #warning "TSS - The electrode E26 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 27
          #if TSS_DETECT_EL_METHOD(27,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(27)
              TSS_ELECTRODE_SLEWRATE_SET(27);
            #else
              #warning "TSS - The electrode E27 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 28
          #if TSS_DETECT_EL_METHOD(28,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(28)
              TSS_ELECTRODE_SLEWRATE_SET(28);
            #else
              #warning "TSS - The electrode E28 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 29
          #if TSS_DETECT_EL_METHOD(29,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(29)
              TSS_ELECTRODE_SLEWRATE_SET(29);
            #else
              #warning "TSS - The electrode E29 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 30
          #if TSS_DETECT_EL_METHOD(30,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(30)
              TSS_ELECTRODE_SLEWRATE_SET(30);
            #else
              #warning "TSS - The electrode E30 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 31
          #if TSS_DETECT_EL_METHOD(31,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(31)
              TSS_ELECTRODE_SLEWRATE_SET(31);
            #else
              #warning "TSS - The electrode E31 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 32
          #if TSS_DETECT_EL_METHOD(32,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(32)
              TSS_ELECTRODE_SLEWRATE_SET(32);
            #else
              #warning "TSS - The electrode E32 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 33
          #if TSS_DETECT_EL_METHOD(33,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(33)
              TSS_ELECTRODE_SLEWRATE_SET(33);
            #else
              #warning "TSS - The electrode E33 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 34
          #if TSS_DETECT_EL_METHOD(34,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(34)
              TSS_ELECTRODE_SLEWRATE_SET(34);
            #else
              #warning "TSS - The electrode E34 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 35
          #if TSS_DETECT_EL_METHOD(35,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(35)
              TSS_ELECTRODE_SLEWRATE_SET(35);
            #else
              #warning "TSS - The electrode E35 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 36
          #if TSS_DETECT_EL_METHOD(36,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(36)
              TSS_ELECTRODE_SLEWRATE_SET(36);
            #else
              #warning "TSS - The electrode E36 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 37
          #if TSS_DETECT_EL_METHOD(37,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(37)
              TSS_ELECTRODE_SLEWRATE_SET(37);
            #else
              #warning "TSS - The electrode E37 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 38
          #if TSS_DETECT_EL_METHOD(38,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(38)
              TSS_ELECTRODE_SLEWRATE_SET(38);
            #else
              #warning "TSS - The electrode E38 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 39
          #if TSS_DETECT_EL_METHOD(39,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(39)
              TSS_ELECTRODE_SLEWRATE_SET(39);
            #else
              #warning "TSS - The electrode E39 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 40
          #if TSS_DETECT_EL_METHOD(40,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(40)
              TSS_ELECTRODE_SLEWRATE_SET(40);
            #else
              #warning "TSS - The electrode E40 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 41
          #if TSS_DETECT_EL_METHOD(41,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(41)
              TSS_ELECTRODE_SLEWRATE_SET(41);
            #else
              #warning "TSS - The electrode E41 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 42
          #if TSS_DETECT_EL_METHOD(42,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(42)
              TSS_ELECTRODE_SLEWRATE_SET(42);
            #else
              #warning "TSS - The electrode E42 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 43
          #if TSS_DETECT_EL_METHOD(43,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(43)
              TSS_ELECTRODE_SLEWRATE_SET(43);
            #else
              #warning "TSS - The electrode E43 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 44
          #if TSS_DETECT_EL_METHOD(44,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(44)
              TSS_ELECTRODE_SLEWRATE_SET(44);
            #else
              #warning "TSS - The electrode E44 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 45
          #if TSS_DETECT_EL_METHOD(45,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(45)
              TSS_ELECTRODE_SLEWRATE_SET(45);
            #else
              #warning "TSS - The electrode E45 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 46
          #if TSS_DETECT_EL_METHOD(46,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(46)
              TSS_ELECTRODE_SLEWRATE_SET(46);
            #else
              #warning "TSS - The electrode E46 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 47
          #if TSS_DETECT_EL_METHOD(47,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(47)
              TSS_ELECTRODE_SLEWRATE_SET(47);
            #else
              #warning "TSS - The electrode E47 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 48
          #if TSS_DETECT_EL_METHOD(48,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(48)
              TSS_ELECTRODE_SLEWRATE_SET(48);
            #else
              #warning "TSS - The electrode E48 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 49
          #if TSS_DETECT_EL_METHOD(49,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(49)
              TSS_ELECTRODE_SLEWRATE_SET(49);
            #else
              #warning "TSS - The electrode E49 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 50
          #if TSS_DETECT_EL_METHOD(50,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(50)
              TSS_ELECTRODE_SLEWRATE_SET(50);
            #else
              #warning "TSS - The electrode E50 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 51
          #if TSS_DETECT_EL_METHOD(51,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(51)
              TSS_ELECTRODE_SLEWRATE_SET(51);
            #else
              #warning "TSS - The electrode E51 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 52
          #if TSS_DETECT_EL_METHOD(52,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(52)
              TSS_ELECTRODE_SLEWRATE_SET(52);
            #else
              #warning "TSS - The electrode E52 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 53
          #if TSS_DETECT_EL_METHOD(53,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(53)
              TSS_ELECTRODE_SLEWRATE_SET(53);
            #else
              #warning "TSS - The electrode E53 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 54
          #if TSS_DETECT_EL_METHOD(54,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(54)
              TSS_ELECTRODE_SLEWRATE_SET(54);
            #else
              #warning "TSS - The electrode E54 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 55
          #if TSS_DETECT_EL_METHOD(55,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(55)
              TSS_ELECTRODE_SLEWRATE_SET(55);
            #else
              #warning "TSS - The electrode E55 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 56
          #if TSS_DETECT_EL_METHOD(56,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(56)
              TSS_ELECTRODE_SLEWRATE_SET(56);
            #else
              #warning "TSS - The electrode E56 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 57
          #if TSS_DETECT_EL_METHOD(57,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(57)
              TSS_ELECTRODE_SLEWRATE_SET(57);
            #else
              #warning "TSS - The electrode E57 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 58
          #if TSS_DETECT_EL_METHOD(58,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(58)
              TSS_ELECTRODE_SLEWRATE_SET(58);
            #else
              #warning "TSS - The electrode E58 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 59
          #if TSS_DETECT_EL_METHOD(59,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(59)
              TSS_ELECTRODE_SLEWRATE_SET(59);
            #else
              #warning "TSS - The electrode E59 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 60
          #if TSS_DETECT_EL_METHOD(60,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(60)
              TSS_ELECTRODE_SLEWRATE_SET(60);
            #else
              #warning "TSS - The electrode E60 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 61
          #if TSS_DETECT_EL_METHOD(61,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(61)
              TSS_ELECTRODE_SLEWRATE_SET(61);
            #else
              #warning "TSS - The electrode E61 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 62
          #if TSS_DETECT_EL_METHOD(62,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(62)
              TSS_ELECTRODE_SLEWRATE_SET(62);
            #else
              #warning "TSS - The electrode E62 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        #if TSS_N_ELECTRODES > 63
          #if TSS_DETECT_EL_METHOD(63,GPIO)
            #if TSS_ELECTRODE_SLEWRATE_CHECK(63)
              TSS_ELECTRODE_SLEWRATE_SET(63);
            #else
              #warning "TSS - The electrode E63 does not provide SLEWRATE feature"
            #endif
          #endif
        #endif
        
        return u8result;
      }
      #endif
    
      /***************************************************************************//*!
      *
      * @brief  Initializes the Noise Amplitude Filter variables 
      *
      * @param  Nothing
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      #if TSS_USE_NOISE_AMPLITUDE_FILTER
        void GPIO_NoiseAmplitudeFilterInit(void) 
        {
            UINT8 u8counter; 
    
            for (u8counter = 0; u8counter < TSS_N_ELECTRODES; u8counter++) 
            {
              /* Do except TSI module since it does not use Amplitude filter */
              if (TSS_CONVERT_MODULE_ID_TO_METHOD_ID(((TSS_GENERIC_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8counter]))->gen_cu8ModuleID) == TSS_GET_METHOD_ID(GPIO))                
              {
                ((TSS_GENERIC_ELECTRODE_RAMDATA *) (tss_acp8ElectrodeRAMData[u8counter]))->gen_u16AmplitudeFilterBase = 0u; /* Set default value */
              }
            }
        }
      #endif
      
      /***************************************************************************//*!
      *
      * @brief  Initializes the Proximity function 
      *
      * @param  Nothing
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      #ifdef TSS_ONPROXIMITY_CALLBACK
        void GPIO_ProximityInit(void) 
        {
            UINT8 u8counter; 
    
            if (tss_CSSys.SystemConfig.ProximityEn) 
            {
              for (u8counter = 0; u8counter < TSS_N_ELECTRODES; u8counter++) 
              {
                /* Do except TSI module since it does not use Amplitude filter */
                if (TSS_CONVERT_MODULE_ID_TO_METHOD_ID(((TSS_GENERIC_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8counter]))->gen_cu8ModuleID) == TSS_GET_METHOD_ID(GPIO))
                {
                  /* Measure signal on Proximity Electrode */  
                  if (u8counter == tss_CSSys.LowPowerElectrode)
                  {
                    (void) UNI_SampleElectrode(u8counter, TSS_SAMPLE_COMMAND_PROCESS);
                  }
                }
              }
            }
        }
      #endif
      
      /***************************************************************************//*!
      *
      * @brief  Initializes the modules for the sensing of the electrodes
      *
      * @param  Nothing
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 GPIO_SensorInit(void)
      {
          UINT8 u8result = TSS_INIT_STATUS_OK;
  
          #if TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW
            GPIO_ElectrodesSetStateLow();
          #else
            GPIO_ElectrodesSetStateHigh();
          #endif
          #if TSS_USE_GPIO_STRENGTH
            (void) GPIO_SetPinStrength();
          #endif
          #if TSS_USE_GPIO_SLEW_RATE
            (void) GPIO_SetPinSlewRate();
          #endif
          #if TSS_USE_NOISE_AMPLITUDE_FILTER
            (void) GPIO_NoiseAmplitudeFilterInit(); 
          #endif
          #ifdef TSS_ONPROXIMITY_CALLBACK
            (void) GPIO_ProximityInit();
          #endif
  
          return u8result;
      }
      
    #else /* TSS_USE_SIMPLE_LOW_LEVEL == 0 */

      /************************** Prototypes ***************************/

      UINT8 GPIO_MethodControl(UINT8 u8ElNum, UINT8 u8Command);     

      /**********************  Modules definition **********************/
      #if (TSS_GPIO_VERSION == 2)
        #if TSS_DETECT_PORT_METHOD(A,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTA_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTAD, (UINT8*) &PORT_PTAOE}; 
        #endif
        #if TSS_DETECT_PORT_METHOD(B,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTB_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTBD, (UINT8*) &PORT_PTBOE}; 
        #endif
        #if TSS_DETECT_PORT_METHOD(C,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTC_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTCD, (UINT8*) &PORT_PTCOE}; 
        #endif
        #if TSS_DETECT_PORT_METHOD(D,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTD_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTDD, (UINT8*) &PORT_PTDOE}; 
        #endif
        #if TSS_DETECT_PORT_METHOD(E,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTE_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTED, (UINT8*) &PORT_PTEOE}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(F,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTF_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTFD, (UINT8*) &PORT_PTFOE}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(G,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTG_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTGD, (UINT8*) &PORT_PTGOE}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(H,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTH_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTHD, (UINT8*) &PORT_PTHOE}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(I,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTI_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTID, (UINT8*) &PORT_PTIOE}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(J,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTJ_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PORT_PTJD, (UINT8*) &PORT_PTJOE}; 
        #endif
      #else /* (TSS_GPIO_VERSION == 1) */
        #if TSS_DETECT_PORT_METHOD(A,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTA_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTAD}; 
        #endif
        #if TSS_DETECT_PORT_METHOD(B,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTB_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTBD}; 
        #endif
        #if TSS_DETECT_PORT_METHOD(C,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTC_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTCD}; 
        #endif
        #if TSS_DETECT_PORT_METHOD(D,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTD_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTDD}; 
        #endif
        #if TSS_DETECT_PORT_METHOD(E,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTE_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTED}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(F,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTF_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTFD}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(G,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTG_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTGD}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(H,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTH_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTHD}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(I,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTI_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTID}; 
        #endif  
        #if TSS_DETECT_PORT_METHOD(J,GPIO) 
          const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTJ_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) &PTJD}; 
        #endif
      #endif /* End of (TSS_GPIO_VERSION == 1) */
          
      /********************* Method Memory Data Decoding Macros **********/
          
      #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_RESULT(memory,res)     TSS_GPIO_PORT##res##_METHOD_##memory##DATA_CONTEXT
      #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_CONV(memory,text)      TSS_GET_GPIO_METHOD_DATA_CONTEXT_RESULT(memory,text)
      #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_TYPE(memory,elec)      TSS_GET_GPIO_METHOD_DATA_CONTEXT_CONV(memory,elec)

      #define TSS_GET_GPIO_METHOD_DATA_CONTEXT(memory,el)             TSS_GET_GPIO_METHOD_DATA_CONTEXT_TYPE(memory,TSS_E##el##_P)
          
      /***************** ROM & RAM Data definition ***********************/
    
      #if TSS_N_ELECTRODES > 0
        #if TSS_DETECT_EL_METHOD(0,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,0), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(0), TSS_ELECTRODE_BIT_NUM(0),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E0_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 1
        #if TSS_DETECT_EL_METHOD(1,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,1), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(1), TSS_ELECTRODE_BIT_NUM(1),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E1_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 2
        #if TSS_DETECT_EL_METHOD(2,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,2), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(2), TSS_ELECTRODE_BIT_NUM(2),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E2_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 3
        #if TSS_DETECT_EL_METHOD(3,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,3), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(3), TSS_ELECTRODE_BIT_NUM(3),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E3_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 4
        #if TSS_DETECT_EL_METHOD(4,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,4), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(4), TSS_ELECTRODE_BIT_NUM(4),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E4_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 5
        #if TSS_DETECT_EL_METHOD(5,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,5), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(5), TSS_ELECTRODE_BIT_NUM(5),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E5_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 6
        #if TSS_DETECT_EL_METHOD(6,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,6), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(6), TSS_ELECTRODE_BIT_NUM(6),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E6_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 7
        #if TSS_DETECT_EL_METHOD(7,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,7), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(7), TSS_ELECTRODE_BIT_NUM(7),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E7_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 8
        #if TSS_DETECT_EL_METHOD(8,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,8), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(8), TSS_ELECTRODE_BIT_NUM(8),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E8_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 9
        #if TSS_DETECT_EL_METHOD(9,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,9), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(9), TSS_ELECTRODE_BIT_NUM(9),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E9_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 10
        #if TSS_DETECT_EL_METHOD(10,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,10), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(10), TSS_ELECTRODE_BIT_NUM(10),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E10_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 11
        #if TSS_DETECT_EL_METHOD(11,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,11), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(11), TSS_ELECTRODE_BIT_NUM(11),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E11_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 12
        #if TSS_DETECT_EL_METHOD(12,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,12), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(12), TSS_ELECTRODE_BIT_NUM(12),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E12_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 13
        #if TSS_DETECT_EL_METHOD(13,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,13), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(13), TSS_ELECTRODE_BIT_NUM(13),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E13_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 14
        #if TSS_DETECT_EL_METHOD(14,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,14), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(14), TSS_ELECTRODE_BIT_NUM(14),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E14_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 15
        #if TSS_DETECT_EL_METHOD(15,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,15), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(15), TSS_ELECTRODE_BIT_NUM(15),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E15_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 16
        #if TSS_DETECT_EL_METHOD(16,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,16), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(16), TSS_ELECTRODE_BIT_NUM(16),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E16_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 17
        #if TSS_DETECT_EL_METHOD(17,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,17), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(17), TSS_ELECTRODE_BIT_NUM(17),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E17_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 18
        #if TSS_DETECT_EL_METHOD(18,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,18), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(18), TSS_ELECTRODE_BIT_NUM(18),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E18_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 19
        #if TSS_DETECT_EL_METHOD(19,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,19), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(19), TSS_ELECTRODE_BIT_NUM(19),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E19_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 20
        #if TSS_DETECT_EL_METHOD(20,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,20), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(20), TSS_ELECTRODE_BIT_NUM(20),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E20_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 21
        #if TSS_DETECT_EL_METHOD(21,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,21), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(21), TSS_ELECTRODE_BIT_NUM(21),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E21_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 22
        #if TSS_DETECT_EL_METHOD(22,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,22), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(22), TSS_ELECTRODE_BIT_NUM(22),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E22_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 23
        #if TSS_DETECT_EL_METHOD(23,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,23), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(23), TSS_ELECTRODE_BIT_NUM(23),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E23_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 24
        #if TSS_DETECT_EL_METHOD(24,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,24), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(24), TSS_ELECTRODE_BIT_NUM(24),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E24_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 25
        #if TSS_DETECT_EL_METHOD(25,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,25), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(25), TSS_ELECTRODE_BIT_NUM(25),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E25_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 26
        #if TSS_DETECT_EL_METHOD(26,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,26), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(26), TSS_ELECTRODE_BIT_NUM(26),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E26_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 27
        #if TSS_DETECT_EL_METHOD(27,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,27), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(27), TSS_ELECTRODE_BIT_NUM(27),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E27_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 28
        #if TSS_DETECT_EL_METHOD(28,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,28), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(28), TSS_ELECTRODE_BIT_NUM(28),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E28_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 29
        #if TSS_DETECT_EL_METHOD(29,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,29), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(29), TSS_ELECTRODE_BIT_NUM(29),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E29_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 30
        #if TSS_DETECT_EL_METHOD(30,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,30), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(30), TSS_ELECTRODE_BIT_NUM(30),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E30_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 31
        #if TSS_DETECT_EL_METHOD(31,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,31), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(31), TSS_ELECTRODE_BIT_NUM(31),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E31_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 32
        #if TSS_DETECT_EL_METHOD(32,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,32), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(32), TSS_ELECTRODE_BIT_NUM(32),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E32_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 33
        #if TSS_DETECT_EL_METHOD(33,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,33), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(33), TSS_ELECTRODE_BIT_NUM(33),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E33_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 34
        #if TSS_DETECT_EL_METHOD(34,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,34), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(34), TSS_ELECTRODE_BIT_NUM(34),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E34_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 35
        #if TSS_DETECT_EL_METHOD(35,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,35), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(35), TSS_ELECTRODE_BIT_NUM(35),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E35_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 36
        #if TSS_DETECT_EL_METHOD(36,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,36), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(36), TSS_ELECTRODE_BIT_NUM(36),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E36_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 37
        #if TSS_DETECT_EL_METHOD(37,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,37), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(37), TSS_ELECTRODE_BIT_NUM(37),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E37_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 38
        #if TSS_DETECT_EL_METHOD(38,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,38), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(38), TSS_ELECTRODE_BIT_NUM(38),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E38_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 39
        #if TSS_DETECT_EL_METHOD(39,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,39), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(39), TSS_ELECTRODE_BIT_NUM(39),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E39_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 40
        #if TSS_DETECT_EL_METHOD(40,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,40), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(40), TSS_ELECTRODE_BIT_NUM(40),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E40_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 41
        #if TSS_DETECT_EL_METHOD(41,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,41), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(41), TSS_ELECTRODE_BIT_NUM(41),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E41_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 42
        #if TSS_DETECT_EL_METHOD(42,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,42), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(42), TSS_ELECTRODE_BIT_NUM(42),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E42_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 43
        #if TSS_DETECT_EL_METHOD(43,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,43), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(43), TSS_ELECTRODE_BIT_NUM(43),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E43_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 44
        #if TSS_DETECT_EL_METHOD(44,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,44), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(44), TSS_ELECTRODE_BIT_NUM(44),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E44_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 45
        #if TSS_DETECT_EL_METHOD(45,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,45), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(45), TSS_ELECTRODE_BIT_NUM(45),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E45_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 46
        #if TSS_DETECT_EL_METHOD(46,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,46), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(46), TSS_ELECTRODE_BIT_NUM(46),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E46_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 47
        #if TSS_DETECT_EL_METHOD(47,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,47), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(47), TSS_ELECTRODE_BIT_NUM(47),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E47_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 48
        #if TSS_DETECT_EL_METHOD(48,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,48), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(48), TSS_ELECTRODE_BIT_NUM(48),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E48_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 49
        #if TSS_DETECT_EL_METHOD(49,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,49), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(49), TSS_ELECTRODE_BIT_NUM(49),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E49_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 50
        #if TSS_DETECT_EL_METHOD(50,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,50), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(50), TSS_ELECTRODE_BIT_NUM(50),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E50_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 51
        #if TSS_DETECT_EL_METHOD(51,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,51), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(51), TSS_ELECTRODE_BIT_NUM(51),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E51_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 52
        #if TSS_DETECT_EL_METHOD(52,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,52), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(52), TSS_ELECTRODE_BIT_NUM(52),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E52_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 53
        #if TSS_DETECT_EL_METHOD(53,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,53), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(53), TSS_ELECTRODE_BIT_NUM(53),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E53_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 54
        #if TSS_DETECT_EL_METHOD(54,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,54), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(54), TSS_ELECTRODE_BIT_NUM(54),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E54_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 55
        #if TSS_DETECT_EL_METHOD(55,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,55), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(55), TSS_ELECTRODE_BIT_NUM(55),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E55_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 56
        #if TSS_DETECT_EL_METHOD(56,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,56), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(56), TSS_ELECTRODE_BIT_NUM(56),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E56_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 57
        #if TSS_DETECT_EL_METHOD(57,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,57), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(57), TSS_ELECTRODE_BIT_NUM(57),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E57_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 58
        #if TSS_DETECT_EL_METHOD(58,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,58), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(58), TSS_ELECTRODE_BIT_NUM(58),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E58_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 59
        #if TSS_DETECT_EL_METHOD(59,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,59), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(59), TSS_ELECTRODE_BIT_NUM(59),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E59_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 60
        #if TSS_DETECT_EL_METHOD(60,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,60), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(60), TSS_ELECTRODE_BIT_NUM(60),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E60_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 61
        #if TSS_DETECT_EL_METHOD(61,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,61), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(61), TSS_ELECTRODE_BIT_NUM(61),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E61_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 62
        #if TSS_DETECT_EL_METHOD(62,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,62), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(62), TSS_ELECTRODE_BIT_NUM(62),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E62_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif
    
      #if TSS_N_ELECTRODES > 63
        #if TSS_DETECT_EL_METHOD(63,GPIO)
          const TSS_GPIO_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,63), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(63), TSS_ELECTRODE_BIT_NUM(63),
                                                                     #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                       TSS_E63_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                     #endif
                                                                     };
                TSS_GPIO_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
        #endif
      #endif

      /***************************************************************************//*!
      *
      * @brief  Initializes the modules for the sensing of the electrodes
      *
      * @param  Nothing
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 GPIO_MethodControl(UINT8 u8ElNum, UINT8 u8Command)
      {
        UINT8 u8result = TSS_INIT_STATUS_OK;
        UINT8 u8ElCounter;
        
        TSS_GPIO_METHOD_ROMDATA *psMethodROMDataStruct;
        TSS_GPIO_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;

        TSS_TPMFTM_MemMapPtr psTimerStruct;
        #if (TSS_GPIO_VERSION == 2)
          UINT8 *psPort;
          UINT8 *psPortOE;
          UINT8 *psPortIE;
        #else /*(TSS_GPIO_VERSION == 1)*/          
          TSS_GPIO_MemMapPtr psPort;
        #endif
        
        /* Pointers Decoding */      
        psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElNum]);
        psMethodROMDataStruct = (TSS_GPIO_METHOD_ROMDATA *) (psElectrodeROMDataStruct->gpio_cpsu8MethodROMData);
        
        psTimerStruct = (TSS_TPMFTM_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu8Timer);
        #if (TSS_GPIO_VERSION == 2)
          psPort = (UINT8 *) (psMethodROMDataStruct->gpio_cpsu8Port);
          psPortOE = (UINT8 *) (psMethodROMDataStruct->gpio_cpsu8PortControl);
          psPortIE = (UINT8 *) (psPortOE + 8u);
        #else /*(TSS_GPIO_VERSION == 1)*/          
          psPort = (TSS_GPIO_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu8Port);
        #endif

        /************* Do GPIO Init *******************/
        if ((u8Command == TSS_INIT_COMMAND_INIT_MODULES) || (u8Command == TSS_INIT_COMMAND_ENABLE_ELECTRODES) || (u8Command == TSS_INIT_COMMAND_RECALIBRATE))
        {    
          /* HW Timer Init */        
          psTimerStruct->SC = 0u; /* Reset Timer */
          psTimerStruct->CNT.Word = 0u; /* Reset Counter */
          psTimerStruct->SC |= TSS_HW_TPMFTM_IE; /* Enable Interrupt */
          if (tss_CSSys.SystemConfig.ProximityEn)
          {
            psTimerStruct->SC |= (TSS_SENSOR_PROX_PRESCALER & TSS_HW_TPMFTM_PRESCALE_MASK); /* Set Prescaler */
            psTimerStruct->MOD.Word = TSS_SENSOR_PROX_TIMEOUT; /* Set MOD Register */
          }else{
            psTimerStruct->SC |= (TSS_SENSOR_PRESCALER & TSS_HW_TPMFTM_PRESCALE_MASK); /* Set Prescaler */
            psTimerStruct->MOD.Word = TSS_SENSOR_TIMEOUT; /* Set MOD Register */
          }
          /* Find all with the same module */            
          for(u8ElCounter = 0; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) 
          {
            if ((TSS_GENERIC_METHOD_ROMDATA *) psMethodROMDataStruct == (TSS_GENERIC_METHOD_ROMDATA *) (((TSS_GENERIC_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]))->gen_cpsMethodROMData))            
            {
              /* Handle only enabled electrode */
              if ((tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter % 8u))) || ((u8ElCounter == tss_CSSys.LowPowerElectrode) && (tss_CSSys.SystemConfig.ProximityEn)))
              {
                /* Noise Amplitude Filter Initialization */
                #if TSS_USE_NOISE_AMPLITUDE_FILTER
                  ((TSS_GPIO_ELECTRODE_RAMDATA *) (tss_acp8ElectrodeRAMData[u8ElCounter]))->gpio_u16AmplitudeFilterBase = 0u;
                #endif
                
                /* Calculate Pointer to the Module */ 
                psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]);
                #if (TSS_GPIO_VERSION == 2)
                  /* Set PIN Strength if enabled */
                  #if TSS_USE_GPIO_STRENGTH
                    #warning "TSS - GPIO pin Strength function is not available on the MCU" 
                  #endif
                  /* Set PIN SlewRate if enabled */
                  #if TSS_USE_GPIO_SLEW_RATE
                    #warning "TSS - GPIO pin SlewRate function is not available on the MCU" 
                  #endif
                  /* Set Default PIN State */
                  *psPortIE &= ~(1 << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set PIN to OUTPUT */
                  *psPortOE |= (1 << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set PIN to OUTPUT */
                  #if TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW
                    *psPort &= ~(1 << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set LOG0 to OUTPUT pin */ 
                  #else
                    *psPort |= (1 << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set LOG1 to OUTPUT pin */
                  #endif
                #else /*(TSS_GPIO_VERSION == 1)*/
                  /* Set PIN Strength if enabled */
                  #if TSS_USE_GPIO_STRENGTH
                    #warning "TSS - GPIO pin Strength function is not available on the MCU" 
                  #endif
                  /* Set PIN SlewRate if enabled */
                  #if TSS_USE_GPIO_SLEW_RATE
                    #warning "TSS - GPIO pin SlewRate function is not available on the MCU" 
                  #endif
                  /* Only for enabled electrodes */
                  if (tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter % 8u)))
                  {
                    /* Set Default PIN State */
                    psPort->DD |= (1 << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set PIN to OUTPUT */
                    #if TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW
                      psPort->D &= ~(1 << psElectrodeROMDataStruct->gpio_cu8PortBit);  /* Set LOG0 to OUTPUT pin */      
                    #else
                      psPort->D |= (1 << psElectrodeROMDataStruct->gpio_cu8PortBit);  /* Set LOG1 to OUTPUT pin */      
                    #endif
                  }
                #endif /*End of (TSS_GPIO_VERSION == 1)*/
                /* Measure signal on Proximity Electrode */    
                if ((u8ElCounter == tss_CSSys.LowPowerElectrode) && (tss_CSSys.SystemConfig.ProximityEn))
                {
                  (void) GPIO_SampleElectrode(u8ElCounter, TSS_SAMPLE_COMMAND_PROCESS);
                }
              }
            } 
          }
        } 

        /* Exit */                   
        return u8result;
      }

      /***************************************************************************//*!
      *
      * @brief  Performs a valid reading of one electrode stores the timer values 
      *         and returns a status code
      *
      * @param  u8ElecNum Electrode number to be scanned
      *
      * @return Status Code
      *
      * @remarks
      *
      ****************************************************************************/
      UINT8 GPIO_SampleElectrode(UINT8 u8ElecNum, UINT8 u8Command)
      {
        UINT8 u8NSamp;
        UINT8 u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;   /* Sets default status */
        UINT16 u16CapSubSample;
        UINT8 u8FaultCnt;
        TSS_GPIO_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
        TSS_GPIO_METHOD_ROMDATA *psMethodROMDataStruct;
        TSS_TPMFTM_MemMapPtr psTimerStruct;
        #if TSS_USE_NOISE_AMPLITUDE_FILTER
          INT8 i8AmplitudeFilterDeltaLimitTemp;
          TSS_GPIO_ELECTRODE_RAMDATA *psElectrodeRAMDataStruct;
        #endif

        if (u8Command == TSS_SAMPLE_COMMAND_RESTART) 
        {
          u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;           
        } else if (u8Command == TSS_SAMPLE_COMMAND_PROCESS) 
        {
          /* Pointers Decoding */      
          psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElecNum]);
          psMethodROMDataStruct = (TSS_GPIO_METHOD_ROMDATA *) (psElectrodeROMDataStruct->gpio_cpsu8MethodROMData);
          #if TSS_USE_NOISE_AMPLITUDE_FILTER
            psElectrodeRAMDataStruct = (TSS_GPIO_ELECTRODE_RAMDATA *) (tss_acp8ElectrodeRAMData[u8ElecNum]);
          #endif
          
          psTimerStruct = (TSS_TPMFTM_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu8Timer);
          tss_psElectrodeTimertAdr = (UINT8 *) psTimerStruct;
          tss_pu8ElectrodePortAdr = (UINT8 *) (psMethodROMDataStruct->gpio_cpsu8Port);
          #if (TSS_GPIO_VERSION == 2)
            tss_pu8ElectrodePortControlAdr = (UINT8 *) (psMethodROMDataStruct->gpio_cpsu8PortControl);;
          #endif
          tss_u8ElectrodePortMask = (UINT8) (1u << psElectrodeROMDataStruct->gpio_cu8PortBit);
          
          /* Initialization of variables */
          tss_u8HWTimerFlag = 0u;
          tss_u16CapSample = 0u;
          u8FaultCnt = 0u;
          u8NSamp = tss_CSSys.NSamples;

          #if TSS_USE_NOISE_AMPLITUDE_FILTER
            if (psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase == 0u) {
              i8AmplitudeFilterDeltaLimitTemp = 127;
            } else {
              i8AmplitudeFilterDeltaLimitTemp = psElectrodeROMDataStruct->gpio_ci8AmplitudeFilterDeltaLimit;
            }
          #endif

          /* Main oversampling measurement loop */
          while(u8NSamp)
          {
              psTimerStruct->SC &= TSS_HW_TPMFTM_OFF; /* Stop Timer */
              psTimerStruct->CNT.Word = 0u; /* Reset Counter i.e. Reset Timer*/

              TSS_CLEAR_SAMPLE_INTERRUPTED_FLAG();        /* Clears the interrupt sample flag */

              u16CapSubSample = (psElectrodeROMDataStruct->gpio_fSampleElectrodeLow)();    /* Samples one electrode */
              
              if(!TSS_FAULT_DETECTED)                     /* Verifies that no fault has occur */
              {            
                  if(!TSS_SAMPLE_INTERRUPTED)             /* Verifies that the sample has not been inturrupted*/
                  {
                    #if TSS_USE_NOISE_AMPLITUDE_FILTER
                      if (TSS_u16NoiseAmplitudeFilter(u16CapSubSample, &(psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase), i8AmplitudeFilterDeltaLimitTemp)) 
                      {
                        u8FaultCnt++;                                      
                      } 
                      else 
                      { 
                        tss_u16CapSample += u16CapSubSample;
                        u8NSamp--;
                        u8FaultCnt = 0u;                 /* Restart Fault counter due long cyclic interrupts */
                      }
                      
                    #else
                      tss_u16CapSample += u16CapSubSample;
                      u8NSamp--;
                      u8FaultCnt = 0u;                   /* Restart Fault counter due long cyclic interrupts */
                    #endif  
                  }
                  else
                  {    
                    /* Do nothing if interrupt occured and do sample again in next loop*/
                    u8FaultCnt++; 
                  }
              }
              else
              {
                /* Set PIN to OUTPUT LOW State */
                TSS_SET_ELECTRODE_OUTPUT_LOW();               /* Sets the electrode to OUTPUT LOW default value bacause short was detected there */
                u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT; /* If a fault has occurred sets the return status code error */
                u8NSamp = 0u;                                  
              }
              
              if(u8FaultCnt >= TSS_FAULT_TIMEOUT) {
                  u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT; /* If a fault has occurred sets the return status code error */
                  u8NSamp = 0u; 
              }        
          }

          if ((tss_u16CapSample < TSS_KEYDETECT_CAP_LOWER_LIMIT) && (u8ElectrodeStatus != TSS_SAMPLE_ERROR_CHARGE_TIMEOUT)) 
          {
            u8ElectrodeStatus = TSS_SAMPLE_ERROR_SMALL_CAP;
          }
          
          #if TSS_USE_NOISE_AMPLITUDE_FILTER
            if (u8ElectrodeStatus == TSS_SAMPLE_STATUS_OK) {
              if (psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase == 0u) {
                psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase = (UINT16) (tss_u16CapSample / tss_CSSys.NSamples);
              }
            } else {
              psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase = 0u; /* Initiate Amplitude Filter Base refresh */
            }
          #endif
        } else if (u8Command == TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE) 
        {
          /* Return the same electrode number because there is no more electrodes in the module */
          u8ElectrodeStatus = u8ElecNum;
        } else if (u8Command == TSS_SAMPLE_COMMAND_RECALIB) 
        {
          /* Do Nothing because the Command is no relevant for GPIO Method */
          u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
        } 
        
        return u8ElectrodeStatus;   /* Return status code */ 
      }
      
    #endif /* End of TSS_USE_SIMPLE_LOW_LEVEL == 0 */
      
  #elif TSS_KINETIS_MCU

    /************************** Prototypes ***************************/

    UINT8 GPIO_MethodControl(UINT8 u8ElNum, UINT8 u8Command);     

    /**********************  Modules definition **********************/
    
    #if TSS_DETECT_PORT_METHOD(A,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTA_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTA_BASE_PTR, (UINT32*) PTA_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif
    #if TSS_DETECT_PORT_METHOD(B,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTB_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTB_BASE_PTR, (UINT32*) PTB_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif
    #if TSS_DETECT_PORT_METHOD(C,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTC_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTC_BASE_PTR, (UINT32*) PTC_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif
    #if TSS_DETECT_PORT_METHOD(D,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTD_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTD_BASE_PTR, (UINT32*) PTD_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif
    #if TSS_DETECT_PORT_METHOD(E,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTE_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTE_BASE_PTR, (UINT32*) PTE_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif  
    #if TSS_DETECT_PORT_METHOD(F,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTF_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTF_BASE_PTR, (UINT32*) PTF_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif  
    #if TSS_DETECT_PORT_METHOD(G,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTG_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTG_BASE_PTR, (UINT32*) PTG_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif  
    #if TSS_DETECT_PORT_METHOD(H,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTH_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTH_BASE_PTR, (UINT32*) PTH_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif  
    #if TSS_DETECT_PORT_METHOD(I,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTI_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTI_BASE_PTR, (UINT32*) PTI_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif  
    #if TSS_DETECT_PORT_METHOD(J,GPIO) 
      const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTJ_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT32*) TSS_HW_TIMER_PTR, (UINT32*) PORTJ_BASE_PTR, (UINT32*) PTJ_BASE_PTR, TSS_HW_TIMER_VECTOR-16}; 
    #endif  
        
    /********************* Method Memory Data Decoding Macros **********/
        
    #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_RESULT(memory,res)     TSS_GPIO_PORT##res##_METHOD_##memory##DATA_CONTEXT
    #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_CONV(memory,text)      TSS_GET_GPIO_METHOD_DATA_CONTEXT_RESULT(memory,text)
    #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_TYPE(memory,elec)      TSS_GET_GPIO_METHOD_DATA_CONTEXT_CONV(memory,elec)

    #define TSS_GET_GPIO_METHOD_DATA_CONTEXT(memory,el)             TSS_GET_GPIO_METHOD_DATA_CONTEXT_TYPE(memory,TSS_E##el##_P)
        
    /***************** ROM & RAM Data definition ***********************/
  
    #if TSS_N_ELECTRODES > 0
      #if TSS_DETECT_EL_METHOD(0,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,0), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(0), TSS_ELECTRODE_BIT_NUM(0),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E0_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 1
      #if TSS_DETECT_EL_METHOD(1,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,1), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(1), TSS_ELECTRODE_BIT_NUM(1),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E1_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 2
      #if TSS_DETECT_EL_METHOD(2,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,2), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(2), TSS_ELECTRODE_BIT_NUM(2),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E2_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 3
      #if TSS_DETECT_EL_METHOD(3,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,3), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(3), TSS_ELECTRODE_BIT_NUM(3),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E3_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 4
      #if TSS_DETECT_EL_METHOD(4,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,4), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(4), TSS_ELECTRODE_BIT_NUM(4),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E4_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 5
      #if TSS_DETECT_EL_METHOD(5,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,5), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(5), TSS_ELECTRODE_BIT_NUM(5),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E5_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 6
      #if TSS_DETECT_EL_METHOD(6,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,6), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(6), TSS_ELECTRODE_BIT_NUM(6),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E6_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 7
      #if TSS_DETECT_EL_METHOD(7,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,7), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(7), TSS_ELECTRODE_BIT_NUM(7),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E7_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 8
      #if TSS_DETECT_EL_METHOD(8,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,8), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(8), TSS_ELECTRODE_BIT_NUM(8),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E8_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 9
      #if TSS_DETECT_EL_METHOD(9,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,9), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(9), TSS_ELECTRODE_BIT_NUM(9),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E9_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 10
      #if TSS_DETECT_EL_METHOD(10,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,10), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(10), TSS_ELECTRODE_BIT_NUM(10),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E10_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 11
      #if TSS_DETECT_EL_METHOD(11,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,11), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(11), TSS_ELECTRODE_BIT_NUM(11),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E11_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 12
      #if TSS_DETECT_EL_METHOD(12,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,12), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(12), TSS_ELECTRODE_BIT_NUM(12),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E12_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 13
      #if TSS_DETECT_EL_METHOD(13,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,13), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(13), TSS_ELECTRODE_BIT_NUM(13),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E13_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 14
      #if TSS_DETECT_EL_METHOD(14,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,14), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(14), TSS_ELECTRODE_BIT_NUM(14),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E14_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 15
      #if TSS_DETECT_EL_METHOD(15,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,15), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(15), TSS_ELECTRODE_BIT_NUM(15),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E15_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 16
      #if TSS_DETECT_EL_METHOD(16,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,16), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(16), TSS_ELECTRODE_BIT_NUM(16),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E16_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 17
      #if TSS_DETECT_EL_METHOD(17,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,17), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(17), TSS_ELECTRODE_BIT_NUM(17),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E17_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 18
      #if TSS_DETECT_EL_METHOD(18,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,18), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(18), TSS_ELECTRODE_BIT_NUM(18),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E18_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 19
      #if TSS_DETECT_EL_METHOD(19,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,19), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(19), TSS_ELECTRODE_BIT_NUM(19),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E19_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 20
      #if TSS_DETECT_EL_METHOD(20,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,20), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(20), TSS_ELECTRODE_BIT_NUM(20),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E20_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 21
      #if TSS_DETECT_EL_METHOD(21,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,21), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(21), TSS_ELECTRODE_BIT_NUM(21),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E21_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 22
      #if TSS_DETECT_EL_METHOD(22,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,22), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(22), TSS_ELECTRODE_BIT_NUM(22),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E22_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 23
      #if TSS_DETECT_EL_METHOD(23,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,23), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(23), TSS_ELECTRODE_BIT_NUM(23),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E23_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 24
      #if TSS_DETECT_EL_METHOD(24,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,24), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(24), TSS_ELECTRODE_BIT_NUM(24),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E24_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 25
      #if TSS_DETECT_EL_METHOD(25,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,25), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(25), TSS_ELECTRODE_BIT_NUM(25),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E25_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 26
      #if TSS_DETECT_EL_METHOD(26,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,26), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(26), TSS_ELECTRODE_BIT_NUM(26),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E26_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 27
      #if TSS_DETECT_EL_METHOD(27,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,27), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(27), TSS_ELECTRODE_BIT_NUM(27),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E27_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 28
      #if TSS_DETECT_EL_METHOD(28,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,28), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(28), TSS_ELECTRODE_BIT_NUM(28),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E28_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 29
      #if TSS_DETECT_EL_METHOD(29,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,29), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(29), TSS_ELECTRODE_BIT_NUM(29),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E29_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 30
      #if TSS_DETECT_EL_METHOD(30,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,30), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(30), TSS_ELECTRODE_BIT_NUM(30),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E30_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 31
      #if TSS_DETECT_EL_METHOD(31,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,31), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(31), TSS_ELECTRODE_BIT_NUM(31),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E31_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 32
      #if TSS_DETECT_EL_METHOD(32,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,32), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(32), TSS_ELECTRODE_BIT_NUM(32),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E32_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 33
      #if TSS_DETECT_EL_METHOD(33,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,33), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(33), TSS_ELECTRODE_BIT_NUM(33),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E33_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 34
      #if TSS_DETECT_EL_METHOD(34,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,34), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(34), TSS_ELECTRODE_BIT_NUM(34),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E34_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 35
      #if TSS_DETECT_EL_METHOD(35,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,35), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(35), TSS_ELECTRODE_BIT_NUM(35),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E35_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 36
      #if TSS_DETECT_EL_METHOD(36,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,36), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(36), TSS_ELECTRODE_BIT_NUM(36),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E36_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 37
      #if TSS_DETECT_EL_METHOD(37,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,37), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(37), TSS_ELECTRODE_BIT_NUM(37),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E37_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 38
      #if TSS_DETECT_EL_METHOD(38,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,38), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(38), TSS_ELECTRODE_BIT_NUM(38),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E38_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 39
      #if TSS_DETECT_EL_METHOD(39,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,39), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(39), TSS_ELECTRODE_BIT_NUM(39),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E39_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 40
      #if TSS_DETECT_EL_METHOD(40,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,40), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(40), TSS_ELECTRODE_BIT_NUM(40),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E40_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 41
      #if TSS_DETECT_EL_METHOD(41,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,41), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(41), TSS_ELECTRODE_BIT_NUM(41),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E41_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 42
      #if TSS_DETECT_EL_METHOD(42,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,42), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(42), TSS_ELECTRODE_BIT_NUM(42),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E42_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 43
      #if TSS_DETECT_EL_METHOD(43,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,43), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(43), TSS_ELECTRODE_BIT_NUM(43),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E43_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 44
      #if TSS_DETECT_EL_METHOD(44,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,44), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(44), TSS_ELECTRODE_BIT_NUM(44),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E44_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 45
      #if TSS_DETECT_EL_METHOD(45,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,45), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(45), TSS_ELECTRODE_BIT_NUM(45),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E45_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 46
      #if TSS_DETECT_EL_METHOD(46,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,46), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(46), TSS_ELECTRODE_BIT_NUM(46),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E46_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 47
      #if TSS_DETECT_EL_METHOD(47,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,47), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(47), TSS_ELECTRODE_BIT_NUM(47),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E47_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 48
      #if TSS_DETECT_EL_METHOD(48,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,48), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(48), TSS_ELECTRODE_BIT_NUM(48),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E48_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 49
      #if TSS_DETECT_EL_METHOD(49,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,49), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(49), TSS_ELECTRODE_BIT_NUM(49),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E49_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 50
      #if TSS_DETECT_EL_METHOD(50,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,50), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(50), TSS_ELECTRODE_BIT_NUM(50),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E50_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 51
      #if TSS_DETECT_EL_METHOD(51,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,51), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(51), TSS_ELECTRODE_BIT_NUM(51),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E51_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 52
      #if TSS_DETECT_EL_METHOD(52,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,52), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(52), TSS_ELECTRODE_BIT_NUM(52),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E52_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 53
      #if TSS_DETECT_EL_METHOD(53,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,53), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(53), TSS_ELECTRODE_BIT_NUM(53),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E53_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 54
      #if TSS_DETECT_EL_METHOD(54,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,54), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(54), TSS_ELECTRODE_BIT_NUM(54),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E54_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 55
      #if TSS_DETECT_EL_METHOD(55,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,55), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(55), TSS_ELECTRODE_BIT_NUM(55),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E55_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 56
      #if TSS_DETECT_EL_METHOD(56,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,56), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(56), TSS_ELECTRODE_BIT_NUM(56),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E56_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 57
      #if TSS_DETECT_EL_METHOD(57,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,57), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(57), TSS_ELECTRODE_BIT_NUM(57),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E57_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 58
      #if TSS_DETECT_EL_METHOD(58,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,58), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(58), TSS_ELECTRODE_BIT_NUM(58),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E58_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 59
      #if TSS_DETECT_EL_METHOD(59,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,59), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(59), TSS_ELECTRODE_BIT_NUM(59),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E59_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 60
      #if TSS_DETECT_EL_METHOD(60,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,60), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(60), TSS_ELECTRODE_BIT_NUM(60),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E60_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 61
      #if TSS_DETECT_EL_METHOD(61,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,61), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(61), TSS_ELECTRODE_BIT_NUM(61),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E61_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 62
      #if TSS_DETECT_EL_METHOD(62,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,62), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(62), TSS_ELECTRODE_BIT_NUM(62),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E62_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif
  
    #if TSS_N_ELECTRODES > 63
      #if TSS_DETECT_EL_METHOD(63,GPIO)
        const TSS_GPIO_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,63), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(63), TSS_ELECTRODE_BIT_NUM(63),
                                                                   #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                     TSS_E63_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                   #endif
                                                                   };
              TSS_GPIO_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
      #endif
    #endif

    /***************************************************************************//*!
    *
    * @brief  Initializes the modules for the sensing of the electrodes
    *
    * @param  Nothing
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 GPIO_MethodControl(UINT8 u8ElNum, UINT8 u8Command)
    {
      UINT8 u8result = TSS_INIT_STATUS_OK;
      UINT8 u8ElCounter;
      
      TSS_GPIO_METHOD_ROMDATA *psMethodROMDataStruct;
      TSS_GPIO_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;

      TSS_TPMFTM_MemMapPtr psTimerStruct;
      PORT_MemMapPtr psPortStruct;
      RGPIO_MemMapPtr psRGPIOStruct;
      NVIC_MemMapPtr psNVICStruct = NVIC_BASE_PTR;

      /* Pointers Decoding */      
      psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElNum]);
      psMethodROMDataStruct = (TSS_GPIO_METHOD_ROMDATA *) (psElectrodeROMDataStruct->gpio_cpsu32MethodROMData);
      
      psTimerStruct = (TSS_TPMFTM_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu32Timer);
      psPortStruct = (PORT_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu32Port);
      psRGPIOStruct = (RGPIO_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu32RGPIO);

      /************* Do GPIO Init *******************/
      if ((u8Command == TSS_INIT_COMMAND_INIT_MODULES) || (u8Command == TSS_INIT_COMMAND_ENABLE_ELECTRODES) || (u8Command == TSS_INIT_COMMAND_RECALIBRATE))
      {    
        /* HW Timer Init */        
        psTimerStruct->SC = 0u; /* Reset Timer */
        psTimerStruct->CNT = 0u; /* Reset Counter */
        psTimerStruct->SC |= TSS_HW_TPMFTM_IE; /* Enable Interrupt */
        if (tss_CSSys.SystemConfig.ProximityEn)
        {
          psTimerStruct->SC |= (TSS_SENSOR_PROX_PRESCALER & TSS_HW_TPMFTM_PRESCALE_MASK); /* Set Prescaler */
          psTimerStruct->MOD = TSS_SENSOR_PROX_TIMEOUT; /* Set MOD Register */
        }else{
          psTimerStruct->SC |= (TSS_SENSOR_PRESCALER & TSS_HW_TPMFTM_PRESCALE_MASK); /* Set Prescaler */
          psTimerStruct->MOD = TSS_SENSOR_TIMEOUT; /* Set MOD Register */
        }          
        /* Enable HW Timer Interrupt */
     #if defined(NVICISER1)        
        psNVICStruct->ISER[psMethodROMDataStruct->gpio_u8TimerIRQNum / 32] = 1 << (psMethodROMDataStruct->gpio_u8TimerIRQNum % 32);
     #else   
        psNVICStruct->ICPR |= (1u << (psMethodROMDataStruct->gpio_u8TimerIRQNum % 32u));
        psNVICStruct->ISER |= (1u << (psMethodROMDataStruct->gpio_u8TimerIRQNum % 32u));
     #endif   

        for(u8ElCounter = 0; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) /* Find all with the same module */
        {
          if ((UINT32**) psMethodROMDataStruct == (UINT32 **) ((UINT32 *)tss_acp8ElectrodeROMData[u8ElCounter])[0]) 
          {
            /* Handle only enabled electrode */
            if ((tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter % 8u))) || ((u8ElCounter == tss_CSSys.LowPowerElectrode) && (tss_CSSys.SystemConfig.ProximityEn)))
            {
              /* Noise Amplitude Filter Initialization */
              #if TSS_USE_NOISE_AMPLITUDE_FILTER
                ((TSS_GPIO_ELECTRODE_RAMDATA *) (tss_acp8ElectrodeRAMData[u8ElCounter]))->gpio_u16AmplitudeFilterBase = 0u;
              #endif
              
              /* Calculate Pointer to the Module */ 
              psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]);
              /* Init GPIO settings */    
              psPortStruct->PCR[psElectrodeROMDataStruct->gpio_cu32PortBit] = 0u; /* Erase PCR */
              /* Set PIN as GPIO */
              psPortStruct->PCR[psElectrodeROMDataStruct->gpio_cu32PortBit] |= PORT_PCR_MUX(0x01u); /* Set GPIO function for PIN */
              /* Set PIN Strength if enabled */
              #if TSS_USE_GPIO_STRENGTH
                psPortStruct->PCR[psElectrodeROMDataStruct->gpio_cu32PortBit] |= PORT_PCR_DSE_MASK; /* Set PIN Strength*/
              #endif
              /* Set PIN SlewRate if enabled */
              #if TSS_USE_GPIO_SLEW_RATE
                psPortStruct->PCR[psElectrodeROMDataStruct->gpio_cu32PortBit] |= PORT_PCR_SRE_MASK; /* Set PIN SlewRate*/
              #endif
              /* Set Default PIN State */
              psRGPIOStruct->PDDR |= (1 << psElectrodeROMDataStruct->gpio_cu32PortBit); /* Set PIN to OUTPUT */
              #if TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW
                psRGPIOStruct->PCOR = (1 << psElectrodeROMDataStruct->gpio_cu32PortBit);  /* Set LOG0 to OUTPUT pin */      
              #else
                psRGPIOStruct->PSOR = (1 << psElectrodeROMDataStruct->gpio_cu32PortBit);  /* Set LOG1 to OUTPUT pin */      
              #endif
              /* Measure signal on Proximity Electrode */    
              if ((u8ElCounter == tss_CSSys.LowPowerElectrode) && (tss_CSSys.SystemConfig.ProximityEn))
              {
                (void) GPIO_SampleElectrode(u8ElCounter, TSS_SAMPLE_COMMAND_PROCESS);
              }
            }
          } 
        }
      } 

      /* Exit */                   
      return u8result;
    }

    /***************************************************************************//*!
    *
    * @brief  Performs a valid reading of one electrode stores the timer values 
    *         and returns a status code
    *
    * @param  u8ElecNum Electrode number to be scanned
    *
    * @return Status Code
    *
    * @remarks
    *
    ****************************************************************************/
    UINT8 GPIO_SampleElectrode(UINT8 u8ElecNum, UINT8 u8Command)
    {
      UINT8 u8NSamp;
      UINT8 u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;   /* Sets default status */
      UINT16 u16CapSubSample;
      UINT8 u8FaultCnt;
      TSS_GPIO_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
      TSS_TPMFTM_MemMapPtr psTimerStruct;
      RGPIO_MemMapPtr psRGPIOStruct;
      #if TSS_USE_NOISE_AMPLITUDE_FILTER
        INT8 i8AmplitudeFilterDeltaLimitTemp;
        TSS_GPIO_ELECTRODE_RAMDATA *psElectrodeRAMDataStruct;
      #endif

      if (u8Command == TSS_SAMPLE_COMMAND_RESTART) 
      {
        u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;           
      } else if (u8Command == TSS_SAMPLE_COMMAND_PROCESS) 
      {  
        /* Pointers Decoding */      
        psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElecNum]);
        psTimerStruct = (TSS_TPMFTM_MemMapPtr) (((TSS_GPIO_METHOD_ROMDATA *) (psElectrodeROMDataStruct->gpio_cpsu32MethodROMData))->gpio_cpsu32Timer);
        psRGPIOStruct = (RGPIO_MemMapPtr) (((TSS_GPIO_METHOD_ROMDATA *) (psElectrodeROMDataStruct->gpio_cpsu32MethodROMData))->gpio_cpsu32RGPIO);
        #if TSS_USE_NOISE_AMPLITUDE_FILTER
          psElectrodeRAMDataStruct = (TSS_GPIO_ELECTRODE_RAMDATA *) (tss_acp8ElectrodeRAMData[u8ElecNum]);
        #endif
       
        tss_psElectrodeTimertAdr = (UINT32 *) psTimerStruct;
        tss_psElectrodeRGPIOAdr = (UINT32 *) psRGPIOStruct;
        tss_u8ElectrodeBitNum = psElectrodeROMDataStruct->gpio_cu32PortBit;
        
        /* Initialization of variables */
        tss_u8HWTimerFlag = 0u;
        tss_u16CapSample = 0u;
        u8FaultCnt = 0u;
        u8NSamp = tss_CSSys.NSamples;

        #if TSS_USE_NOISE_AMPLITUDE_FILTER
          if (psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase == 0u) {
            i8AmplitudeFilterDeltaLimitTemp = 127;
          } else {
            i8AmplitudeFilterDeltaLimitTemp = psElectrodeROMDataStruct->gpio_ci8AmplitudeFilterDeltaLimit;
          }
        #endif

        /* Main oversampling measurement loop */
        while(u8NSamp)
        {
            psTimerStruct->SC &= TSS_HW_TPMFTM_OFF; /* Stop Timer */
            psTimerStruct->CNT = 0u; /* Reset Counter i.e. Reset Timer*/

            TSS_CLEAR_SAMPLE_INTERRUPTED_FLAG();        /* Clears the interrupt sample flag */

            u16CapSubSample = (psElectrodeROMDataStruct->gpio_fSampleElectrodeLow)();    /* Samples one electrode */
            
            if(!TSS_FAULT_DETECTED)                     /* Verifies that no fault has occur */
            {            
                if(!TSS_SAMPLE_INTERRUPTED)             /* Verifies that the sample has not been inturrupted*/
                {
                  #if TSS_USE_NOISE_AMPLITUDE_FILTER
                    if (TSS_u16NoiseAmplitudeFilter(u16CapSubSample, &(psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase), i8AmplitudeFilterDeltaLimitTemp)) 
                    {
                      u8FaultCnt++;                                      
                    } 
                    else 
                    { 
                      tss_u16CapSample += u16CapSubSample;
                      u8NSamp--;
                      u8FaultCnt = 0u;                 /* Restart Fault counter due long cyclic interrupts */
                    }
                    
                  #else
                    tss_u16CapSample += u16CapSubSample;
                    u8NSamp--;
                    u8FaultCnt = 0u;                   /* Restart Fault counter due long cyclic interrupts */
                  #endif  
                }
                else
                {    
                  /* Do nothing if interrupt occured and do sample again in next loop*/
                  u8FaultCnt++; 
                }
            }
            else
            {
              /* Set PIN to OUTPUT LOW State */
              psRGPIOStruct->PDDR |= (1 << psElectrodeROMDataStruct->gpio_cu32PortBit); /* Set PIN to OUTPUT */
              psRGPIOStruct->PCOR = (1 << psElectrodeROMDataStruct->gpio_cu32PortBit);  /* Set LOG0 to OUTPUT pin */      

              u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT; /* If a fault has occurred sets the return status code error */
              u8NSamp = 0u;                                  
            }
            
            if(u8FaultCnt >= TSS_FAULT_TIMEOUT) {
                u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT; /* If a fault has occurred sets the return status code error */
                u8NSamp = 0u; 
            }        
        }

        if ((tss_u16CapSample < TSS_KEYDETECT_CAP_LOWER_LIMIT) && (u8ElectrodeStatus != TSS_SAMPLE_ERROR_CHARGE_TIMEOUT)) 
        {
          u8ElectrodeStatus = TSS_SAMPLE_ERROR_SMALL_CAP;
        }
        
        #if TSS_USE_NOISE_AMPLITUDE_FILTER
          if (u8ElectrodeStatus == TSS_SAMPLE_STATUS_OK) {
            if (psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase == 0u) {
              psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase = (UINT16) (tss_u16CapSample / tss_CSSys.NSamples);
            }
          } else {
            psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase = 0u; /* Initiate Amplitude Filter Base refresh */
          }
        #endif
      } else if (u8Command == TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE) 
      {
        /* Return the same electrode number because there is no more electrodes in the module */
        u8ElectrodeStatus = u8ElecNum;
      } else if (u8Command == TSS_SAMPLE_COMMAND_RECALIB) 
      {
        /* Do Nothing because the Command is no relevant for GPIO Method */
        u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
      } 
      
      return u8ElectrodeStatus;   /* Return status code */ 
    }
    
#elif TSS_CFM_MCU

  /************************** Prototypes ***************************/

  UINT8 GPIO_MethodControl(UINT8 u8ElNum, UINT8 u8Command);     

  /**********************  Modules definition **********************/
  
  #if TSS_DETECT_PORT_METHOD(A,GPIO) 
    const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTA_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) PCTLA_BASE_PTR, (UINT8*) PTA_BASE_PTR, (UINT8*) &MXC_PTAPF1}; 
  #endif
  #if TSS_DETECT_PORT_METHOD(B,GPIO) 
    const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTB_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) PCTLB_BASE_PTR, (UINT8*) PTB_BASE_PTR, (UINT8*) &MXC_PTBPF1}; 
  #endif
  #if TSS_DETECT_PORT_METHOD(C,GPIO) 
    const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTC_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) PCTLC_BASE_PTR, (UINT8*) PTC_BASE_PTR, (UINT8*) &MXC_PTCPF1}; 
  #endif
  #if TSS_DETECT_PORT_METHOD(D,GPIO) 
    const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTD_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) PCTLD_BASE_PTR, (UINT8*) PTD_BASE_PTR, (UINT8*) &MXC_PTDPF1}; 
  #endif
  #if TSS_DETECT_PORT_METHOD(E,GPIO) 
    const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTE_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) PCTLE_BASE_PTR, (UINT8*) PTE_BASE_PTR, (UINT8*) &MXC_PTEPF1}; 
  #endif  
  #if TSS_DETECT_PORT_METHOD(F,GPIO) 
    const    TSS_GPIO_METHOD_ROMDATA TSS_GPIO_PORTF_METHOD_ROMDATA_CONTEXT = {GPIO_MethodControl, (UINT8*) TSS_HW_TIMER_PTR, (UINT8*) PCTLF_BASE_PTR, (UINT8*) PTF_BASE_PTR, (UINT8*) &MXC_PTFPF1}; 
  #endif  
      
  /********************* Method Memory Data Decoding Macros **********/
      
  #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_RESULT(memory,res)     TSS_GPIO_PORT##res##_METHOD_##memory##DATA_CONTEXT
  #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_CONV(memory,text)      TSS_GET_GPIO_METHOD_DATA_CONTEXT_RESULT(memory,text)
  #define TSS_GET_GPIO_METHOD_DATA_CONTEXT_TYPE(memory,elec)      TSS_GET_GPIO_METHOD_DATA_CONTEXT_CONV(memory,elec)

  #define TSS_GET_GPIO_METHOD_DATA_CONTEXT(memory,el)             TSS_GET_GPIO_METHOD_DATA_CONTEXT_TYPE(memory,TSS_E##el##_P)
      
  /***************** ROM & RAM Data definition ***********************/

  #if TSS_N_ELECTRODES > 0
    #if TSS_DETECT_EL_METHOD(0,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E0_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,0), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(0), TSS_ELECTRODE_BIT_NUM(0),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E0_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E0_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 1
    #if TSS_DETECT_EL_METHOD(1,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E1_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,1), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(1), TSS_ELECTRODE_BIT_NUM(1),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E1_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E1_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 2
    #if TSS_DETECT_EL_METHOD(2,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E2_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,2), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(2), TSS_ELECTRODE_BIT_NUM(2),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E2_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E2_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 3
    #if TSS_DETECT_EL_METHOD(3,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E3_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,3), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(3), TSS_ELECTRODE_BIT_NUM(3),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E3_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E3_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 4
    #if TSS_DETECT_EL_METHOD(4,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E4_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,4), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(4), TSS_ELECTRODE_BIT_NUM(4),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E4_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E4_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 5
    #if TSS_DETECT_EL_METHOD(5,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E5_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,5), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(5), TSS_ELECTRODE_BIT_NUM(5),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E5_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E5_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 6
    #if TSS_DETECT_EL_METHOD(6,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E6_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,6), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(6), TSS_ELECTRODE_BIT_NUM(6),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E6_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E6_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 7
    #if TSS_DETECT_EL_METHOD(7,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E7_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,7), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(7), TSS_ELECTRODE_BIT_NUM(7),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E7_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E7_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 8
    #if TSS_DETECT_EL_METHOD(8,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E8_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,8), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(8), TSS_ELECTRODE_BIT_NUM(8),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E8_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E8_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 9
    #if TSS_DETECT_EL_METHOD(9,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E9_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,9), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(9), TSS_ELECTRODE_BIT_NUM(9),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E9_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E9_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 10
    #if TSS_DETECT_EL_METHOD(10,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E10_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,10), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(10), TSS_ELECTRODE_BIT_NUM(10),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E10_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E10_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 11
    #if TSS_DETECT_EL_METHOD(11,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E11_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,11), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(11), TSS_ELECTRODE_BIT_NUM(11),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E11_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E11_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 12
    #if TSS_DETECT_EL_METHOD(12,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E12_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,12), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(12), TSS_ELECTRODE_BIT_NUM(12),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E12_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E12_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 13
    #if TSS_DETECT_EL_METHOD(13,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E13_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,13), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(13), TSS_ELECTRODE_BIT_NUM(13),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E13_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E13_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 14
    #if TSS_DETECT_EL_METHOD(14,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E14_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,14), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(14), TSS_ELECTRODE_BIT_NUM(14),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E14_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E14_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 15
    #if TSS_DETECT_EL_METHOD(15,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E15_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,15), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(15), TSS_ELECTRODE_BIT_NUM(15),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E15_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E15_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 16
    #if TSS_DETECT_EL_METHOD(16,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E16_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,16), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(16), TSS_ELECTRODE_BIT_NUM(16),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E16_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E16_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 17
    #if TSS_DETECT_EL_METHOD(17,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E17_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,17), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(17), TSS_ELECTRODE_BIT_NUM(17),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E17_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E17_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 18
    #if TSS_DETECT_EL_METHOD(18,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E18_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,18), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(18), TSS_ELECTRODE_BIT_NUM(18),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E18_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E18_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 19
    #if TSS_DETECT_EL_METHOD(19,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E19_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,19), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(19), TSS_ELECTRODE_BIT_NUM(19),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E19_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E19_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 20
    #if TSS_DETECT_EL_METHOD(20,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E20_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,20), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(20), TSS_ELECTRODE_BIT_NUM(20),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E20_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E20_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 21
    #if TSS_DETECT_EL_METHOD(21,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E21_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,21), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(21), TSS_ELECTRODE_BIT_NUM(21),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E21_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E21_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 22
    #if TSS_DETECT_EL_METHOD(22,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E22_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,22), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(22), TSS_ELECTRODE_BIT_NUM(22),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E22_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E22_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 23
    #if TSS_DETECT_EL_METHOD(23,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E23_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,23), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(23), TSS_ELECTRODE_BIT_NUM(23),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E23_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E23_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 24
    #if TSS_DETECT_EL_METHOD(24,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E24_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,24), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(24), TSS_ELECTRODE_BIT_NUM(24),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E24_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E24_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 25
    #if TSS_DETECT_EL_METHOD(25,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E25_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,25), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(25), TSS_ELECTRODE_BIT_NUM(25),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E25_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E25_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 26
    #if TSS_DETECT_EL_METHOD(26,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E26_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,26), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(26), TSS_ELECTRODE_BIT_NUM(26),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E26_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E26_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 27
    #if TSS_DETECT_EL_METHOD(27,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E27_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,27), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(27), TSS_ELECTRODE_BIT_NUM(27),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E27_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E27_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 28
    #if TSS_DETECT_EL_METHOD(28,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E28_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,28), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(28), TSS_ELECTRODE_BIT_NUM(28),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E28_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E28_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 29
    #if TSS_DETECT_EL_METHOD(29,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E29_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,29), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(29), TSS_ELECTRODE_BIT_NUM(29),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E29_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E29_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 30
    #if TSS_DETECT_EL_METHOD(30,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E30_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,30), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(30), TSS_ELECTRODE_BIT_NUM(30),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E30_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E30_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 31
    #if TSS_DETECT_EL_METHOD(31,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E31_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,31), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(31), TSS_ELECTRODE_BIT_NUM(31),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E31_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E31_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 32
    #if TSS_DETECT_EL_METHOD(32,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E32_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,32), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(32), TSS_ELECTRODE_BIT_NUM(32),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E32_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E32_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 33
    #if TSS_DETECT_EL_METHOD(33,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E33_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,33), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(33), TSS_ELECTRODE_BIT_NUM(33),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E33_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E33_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 34
    #if TSS_DETECT_EL_METHOD(34,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E34_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,34), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(34), TSS_ELECTRODE_BIT_NUM(34),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E34_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E34_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 35
    #if TSS_DETECT_EL_METHOD(35,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E35_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,35), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(35), TSS_ELECTRODE_BIT_NUM(35),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E35_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E35_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 36
    #if TSS_DETECT_EL_METHOD(36,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E36_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,36), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(36), TSS_ELECTRODE_BIT_NUM(36),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E36_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E36_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 37
    #if TSS_DETECT_EL_METHOD(37,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E37_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,37), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(37), TSS_ELECTRODE_BIT_NUM(37),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E37_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E37_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 38
    #if TSS_DETECT_EL_METHOD(38,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E38_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,38), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(38), TSS_ELECTRODE_BIT_NUM(38),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E38_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E38_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 39
    #if TSS_DETECT_EL_METHOD(39,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E39_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,39), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(39), TSS_ELECTRODE_BIT_NUM(39),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E39_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E39_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 40
    #if TSS_DETECT_EL_METHOD(40,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E40_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,40), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(40), TSS_ELECTRODE_BIT_NUM(40),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E40_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E40_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 41
    #if TSS_DETECT_EL_METHOD(41,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E41_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,41), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(41), TSS_ELECTRODE_BIT_NUM(41),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E41_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E41_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 42
    #if TSS_DETECT_EL_METHOD(42,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E42_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,42), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(42), TSS_ELECTRODE_BIT_NUM(42),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E42_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E42_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 43
    #if TSS_DETECT_EL_METHOD(43,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E43_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,43), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(43), TSS_ELECTRODE_BIT_NUM(43),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E43_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E43_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 44
    #if TSS_DETECT_EL_METHOD(44,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E44_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,44), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(44), TSS_ELECTRODE_BIT_NUM(44),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E44_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E44_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 45
    #if TSS_DETECT_EL_METHOD(45,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E45_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,45), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(45), TSS_ELECTRODE_BIT_NUM(45),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E45_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E45_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 46
    #if TSS_DETECT_EL_METHOD(46,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E46_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,46), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(46), TSS_ELECTRODE_BIT_NUM(46),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E46_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E46_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 47
    #if TSS_DETECT_EL_METHOD(47,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E47_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,47), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(47), TSS_ELECTRODE_BIT_NUM(47),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E47_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E47_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 48
    #if TSS_DETECT_EL_METHOD(48,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E48_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,48), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(48), TSS_ELECTRODE_BIT_NUM(48),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E48_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E48_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 49
    #if TSS_DETECT_EL_METHOD(49,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E49_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,49), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(49), TSS_ELECTRODE_BIT_NUM(49),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E49_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E49_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 50
    #if TSS_DETECT_EL_METHOD(50,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E50_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,50), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(50), TSS_ELECTRODE_BIT_NUM(50),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E50_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E50_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 51
    #if TSS_DETECT_EL_METHOD(51,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E51_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,51), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(51), TSS_ELECTRODE_BIT_NUM(51),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E51_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E51_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 52
    #if TSS_DETECT_EL_METHOD(52,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E52_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,52), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(52), TSS_ELECTRODE_BIT_NUM(52),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E52_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E52_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 53
    #if TSS_DETECT_EL_METHOD(53,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E53_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,53), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(53), TSS_ELECTRODE_BIT_NUM(53),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E53_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E53_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 54
    #if TSS_DETECT_EL_METHOD(54,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E54_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,54), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(54), TSS_ELECTRODE_BIT_NUM(54),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E54_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E54_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 55
    #if TSS_DETECT_EL_METHOD(55,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E55_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,55), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(55), TSS_ELECTRODE_BIT_NUM(55),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E55_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E55_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 56
    #if TSS_DETECT_EL_METHOD(56,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E56_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,56), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(56), TSS_ELECTRODE_BIT_NUM(56),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E56_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E56_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 57
    #if TSS_DETECT_EL_METHOD(57,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E57_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,57), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(57), TSS_ELECTRODE_BIT_NUM(57),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E57_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E57_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 58
    #if TSS_DETECT_EL_METHOD(58,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E58_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,58), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(58), TSS_ELECTRODE_BIT_NUM(58),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E58_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E58_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 59
    #if TSS_DETECT_EL_METHOD(59,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E59_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,59), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(59), TSS_ELECTRODE_BIT_NUM(59),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E59_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E59_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 60
    #if TSS_DETECT_EL_METHOD(60,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E60_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,60), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(60), TSS_ELECTRODE_BIT_NUM(60),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E60_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E60_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 61
    #if TSS_DETECT_EL_METHOD(61,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E61_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,61), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(61), TSS_ELECTRODE_BIT_NUM(61),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E61_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E61_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 62
    #if TSS_DETECT_EL_METHOD(62,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E62_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,62), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(62), TSS_ELECTRODE_BIT_NUM(62),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E62_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E62_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  #if TSS_N_ELECTRODES > 63
    #if TSS_DETECT_EL_METHOD(63,GPIO)
      const TSS_GPIO_ELECTRODE_ROMDATA TSS_E63_ROMDATA_CONTEXT = { &TSS_GET_GPIO_METHOD_DATA_CONTEXT(ROM,63), TSS_GET_SAMPLE_ELECTRODE_LOW_ROUTINE(63), TSS_ELECTRODE_BIT_NUM(63),
                                                                 #if TSS_USE_NOISE_AMPLITUDE_FILTER
                                                                   TSS_E63_NOISE_AMPLITUDE_FILTER_HALF_SIZE,
                                                                 #endif
                                                                 };
            TSS_GPIO_ELECTRODE_RAMDATA TSS_E63_RAMDATA_CONTEXT = { 0u };
    #endif
  #endif

  /***************************************************************************//*!
  *
  * @brief  Initializes the modules for the sensing of the electrodes
  *
  * @param  Nothing
  *
  * @return Status Code
  *
  * @remarks
  *
  ****************************************************************************/
  UINT8 GPIO_MethodControl(UINT8 u8ElNum, UINT8 u8Command)
  {
    UINT8 u8result = TSS_INIT_STATUS_OK;
    UINT8 u8ElCounter;
    typedef UINT8 * TSS_MXC_MemMapPtr;
    
    TSS_GPIO_METHOD_ROMDATA *psMethodROMDataStruct;
    TSS_GPIO_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;

    TSS_TPMFTM_MemMapPtr psTimerStruct;
    PCTL_MemMapPtr psPCTLStruct;
    PT_MemMapPtr psPortStruct;
    TSS_MXC_MemMapPtr psMXCStruct;

    /* Pointers Decoding */      
    psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElNum]);
    psMethodROMDataStruct = (TSS_GPIO_METHOD_ROMDATA *) (psElectrodeROMDataStruct->gpio_cpsu8MethodROMData);
    
    psTimerStruct = (TSS_TPMFTM_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu8Timer);
    psPCTLStruct = (PCTL_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu8PCTL);
    psPortStruct = (PT_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu8Port);
    psMXCStruct = (TSS_MXC_MemMapPtr) (psMethodROMDataStruct->gpio_cpsu8MXC);
    
    /************* Do GPIO Init *******************/
    if ((u8Command == TSS_INIT_COMMAND_INIT_MODULES) || (u8Command == TSS_INIT_COMMAND_ENABLE_ELECTRODES) || (u8Command == TSS_INIT_COMMAND_RECALIBRATE))
    {    
      /* HW Timer Init */        
      psTimerStruct->SC = 0u; /* Reset Timer */
      psTimerStruct->CNT.Word = 0u; /* Reset Counter */
      psTimerStruct->SC |= TSS_HW_TPMFTM_IE; /* Enable Interrupt */
      if (tss_CSSys.SystemConfig.ProximityEn)
      {
        psTimerStruct->SC |= (TSS_SENSOR_PROX_PRESCALER & TSS_HW_TPMFTM_PRESCALE_MASK); /* Set Prescaler */
        psTimerStruct->MOD.Word = TSS_SENSOR_PROX_TIMEOUT; /* Set MOD Register */
      }else{
        psTimerStruct->SC |= (TSS_SENSOR_PRESCALER & TSS_HW_TPMFTM_PRESCALE_MASK); /* Set Prescaler */
        psTimerStruct->MOD.Word = TSS_SENSOR_TIMEOUT; /* Set MOD Register */
      }      
      /* Find all with the same module */
      for(u8ElCounter = 0; u8ElCounter < TSS_N_ELECTRODES; u8ElCounter++) 
      {
        if ((UINT32**) psMethodROMDataStruct == (UINT32 **) ((UINT32 *)tss_acp8ElectrodeROMData[u8ElCounter])[0]) 
        {
          /* Handle only enabled electrode */
          if ((tss_au8ElectrodeEnablers[u8ElCounter >> 3u] & (1u << (u8ElCounter % 8u))) || ((u8ElCounter == tss_CSSys.LowPowerElectrode) && (tss_CSSys.SystemConfig.ProximityEn)))
          {
            /* Noise Amplitude Filter Initialization */
            #if TSS_USE_NOISE_AMPLITUDE_FILTER
              ((TSS_GPIO_ELECTRODE_RAMDATA *) (tss_acp8ElectrodeRAMData[u8ElCounter]))->gpio_u16AmplitudeFilterBase = 0u;
            #endif
            
            /* Calculate Pointer to the Module */ 
            psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElCounter]);
            /* Init MXC settings */    
            if (psElectrodeROMDataStruct->gpio_cu8PortBit % 2u)
            {	  
              /* Erase PCR */
              psMXCStruct[3u-(psElectrodeROMDataStruct->gpio_cu8PortBit / 2u)] &= 0x0Fu;
              /* Set PIN as GPIO */
              psMXCStruct[3u-(psElectrodeROMDataStruct->gpio_cu8PortBit / 2u)] |= 0x10u; /* Set GPIO function for PIN */
            } else {
              /* Erase PCR */        	  
              psMXCStruct[3u-(psElectrodeROMDataStruct->gpio_cu8PortBit / 2u)] &= 0xF0u; /* Erase PCR */
              /* Set PIN as GPIO */
              psMXCStruct[3u-(psElectrodeROMDataStruct->gpio_cu8PortBit / 2u)] |= 0x01u; /* Set GPIO function for PIN */
            } 	
            /* Set PIN Strength if enabled */
            #if TSS_USE_GPIO_STRENGTH
              psPCTLStruct->DS |= (1u << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set PIN Strength*/ 
            #endif
            /* Set PIN SlewRate if enabled */
            #if TSS_USE_GPIO_SLEW_RATE
              psPCTLStruct->SRE |= (1u << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set PIN SlewRate*/ 
            #endif
            /* Set Default PIN State */
            psPortStruct->DD |= (1u << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set PIN to OUTPUT */
            #if TSS_USE_DEFAULT_ELECTRODE_LEVEL_LOW
              psPortStruct->D &= ~(1u << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set LOG0 to OUTPUT pin */      
            #else
              psPortStruct->D |= (1u << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set LOG1 to OUTPUT pin */      
            #endif
            /* Measure signal on Proximity Electrode */   
            if ((u8ElCounter == tss_CSSys.LowPowerElectrode) && (tss_CSSys.SystemConfig.ProximityEn))
            {
              (void) GPIO_SampleElectrode(u8ElCounter, TSS_SAMPLE_COMMAND_PROCESS);
            }
          }
        } 
      }
    } 

    /* Exit */                   
    return u8result;
  }

  /***************************************************************************//*!
  *
  * @brief  Performs a valid reading of one electrode stores the timer values 
  *         and returns a status code
  *
  * @param  u8ElecNum Electrode number to be scanned
  *
  * @return Status Code
  *
  * @remarks
  *
  ****************************************************************************/
  UINT8 GPIO_SampleElectrode(UINT8 u8ElecNum, UINT8 u8Command)
  {
    UINT8 u8NSamp;
    UINT8 u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;   /* Sets default status */
    UINT16 u16CapSubSample;
    UINT8 u8FaultCnt;
    TSS_GPIO_ELECTRODE_ROMDATA *psElectrodeROMDataStruct;
    TSS_TPMFTM_MemMapPtr psTimerStruct;
    PT_MemMapPtr psPortStruct;
    #if TSS_USE_NOISE_AMPLITUDE_FILTER
      INT8 i8AmplitudeFilterDeltaLimitTemp;
      TSS_GPIO_ELECTRODE_RAMDATA *psElectrodeRAMDataStruct;
    #endif

    if (u8Command == TSS_SAMPLE_COMMAND_RESTART) 
    {
      u8ElectrodeStatus = TSS_SAMPLE_STATUS_PROCESSING;           
    } else if (u8Command == TSS_SAMPLE_COMMAND_PROCESS) 
    {  
      /* Pointers Decoding */      
      psElectrodeROMDataStruct = (TSS_GPIO_ELECTRODE_ROMDATA *) (tss_acp8ElectrodeROMData[u8ElecNum]);
      psTimerStruct = (TSS_TPMFTM_MemMapPtr) (((TSS_GPIO_METHOD_ROMDATA *) (psElectrodeROMDataStruct->gpio_cpsu8MethodROMData))->gpio_cpsu8Timer);
      psPortStruct = (PT_MemMapPtr) (((TSS_GPIO_METHOD_ROMDATA *) (psElectrodeROMDataStruct->gpio_cpsu8MethodROMData))->gpio_cpsu8Port);
      #if TSS_USE_NOISE_AMPLITUDE_FILTER
        psElectrodeRAMDataStruct = (TSS_GPIO_ELECTRODE_RAMDATA *) (tss_acp8ElectrodeRAMData[u8ElecNum]);
      #endif
     
      tss_psElectrodeTimertAdr = (UINT32 *) psTimerStruct;
      tss_psElectrodePortAdr = (UINT32 *) psPortStruct;
      tss_u8ElectrodeBitNum = psElectrodeROMDataStruct->gpio_cu8PortBit;
      
      /* Initialization of variables */
      tss_u8HWTimerFlag = 0u;
      tss_u16CapSample = 0u;
      u8FaultCnt = 0u;
      u8NSamp = tss_CSSys.NSamples;

      #if TSS_USE_NOISE_AMPLITUDE_FILTER
        if (psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase == 0u) {
          i8AmplitudeFilterDeltaLimitTemp = 127;
        } else {
          i8AmplitudeFilterDeltaLimitTemp = psElectrodeROMDataStruct->gpio_ci8AmplitudeFilterDeltaLimit;
        }
      #endif

      /* Main oversampling measurement loop */
      while(u8NSamp)
      {
          psTimerStruct->SC &= TSS_HW_TPMFTM_OFF; /* Stop Timer */
          psTimerStruct->CNT.Word = 0u; /* Reset Counter i.e. Reset Timer*/

          TSS_CLEAR_SAMPLE_INTERRUPTED_FLAG();        /* Clears the interrupt sample flag */

          u16CapSubSample = (psElectrodeROMDataStruct->gpio_fSampleElectrodeLow)();    /* Samples one electrode */          
          
          if(!TSS_FAULT_DETECTED)                     /* Verifies that no fault has occur */
          {            
              if(!TSS_SAMPLE_INTERRUPTED)             /* Verifies that the sample has not been inturrupted*/
              {
                #if TSS_USE_NOISE_AMPLITUDE_FILTER
                  if (TSS_u16NoiseAmplitudeFilter(u16CapSubSample, &(psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase), i8AmplitudeFilterDeltaLimitTemp)) 
                  {
                    u8FaultCnt++;                                      
                  } 
                  else 
                  { 
                    tss_u16CapSample += u16CapSubSample;
                    u8NSamp--;
                    u8FaultCnt = 0u;                 /* Restart Fault counter due long cyclic interrupts */
                  }
                  
                #else
                  tss_u16CapSample += u16CapSubSample;
                  u8NSamp--;
                  u8FaultCnt = 0u;                   /* Restart Fault counter due long cyclic interrupts */
                #endif  
              }
              else
              {    
                /* Do nothing if interrupt occured and do sample again in next loop*/
                u8FaultCnt++; 
              }
          }
          else
          {
            /* Set PIN to OUTPUT LOW State */
            psPortStruct->DD |= (1 << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set PIN to OUTPUT */
            psPortStruct->D &= ~(1 << psElectrodeROMDataStruct->gpio_cu8PortBit); /* Set LOG0 to OUTPUT pin */      

            u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT; /* If a fault has occurred sets the return status code error */
            u8NSamp = 0u;                                  
          }
          
          if(u8FaultCnt >= TSS_FAULT_TIMEOUT) {
              u8ElectrodeStatus = TSS_SAMPLE_ERROR_CHARGE_TIMEOUT; /* If a fault has occurred sets the return status code error */
              u8NSamp = 0u; 
          }        
      }

      if ((tss_u16CapSample < TSS_KEYDETECT_CAP_LOWER_LIMIT) && (u8ElectrodeStatus != TSS_SAMPLE_ERROR_CHARGE_TIMEOUT)) 
      {
        u8ElectrodeStatus = TSS_SAMPLE_ERROR_SMALL_CAP;
      }
      
      #if TSS_USE_NOISE_AMPLITUDE_FILTER
        if (u8ElectrodeStatus == TSS_SAMPLE_STATUS_OK) {
          if (psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase == 0u) {
            psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase = (UINT16) (tss_u16CapSample / tss_CSSys.NSamples);
          }
        } else {
          psElectrodeRAMDataStruct->gpio_u16AmplitudeFilterBase = 0u; /* Initiate Amplitude Filter Base refresh */
        }
      #endif
    } else if (u8Command == TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE) 
    {
      /* Return the same electrode number because there is no more electrodes in the module */
      u8ElectrodeStatus = u8ElecNum;
    } else if (u8Command == TSS_SAMPLE_COMMAND_RECALIB) 
    {
      /* Do Nothing because the Command is no relevant for GPIO Method */
      u8ElectrodeStatus = TSS_SAMPLE_STATUS_OK;
    } 
    
    return u8ElectrodeStatus;   /* Return status code */ 
  }
  #else /* End of TSS_CFM_MCU */
    #error "TSS - Not supported MCU used"  
  #endif    
  
#endif /* End of TSS_DETECT_METHOD(GPIO) */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5xxx_fec_util.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5xxx_fec_util.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the MCF5xxx Coldfire processor
*   Ethernet initialization
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enetprv.h"
#include "mcf5xxx_fec_prv.h"          


/*NOTIFIER*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_Error_ISR
*  Returned Value : void
*  Comments       :
*        Interrupt service routine for Tx.
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_Error_ISR 
   (
         /* [IN] the Ethernet state structure */
      pointer  enet
   )
{    
   ENET_CONTEXT_STRUCT_PTR          enet_ptr = (ENET_CONTEXT_STRUCT_PTR)enet;
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   VMCF5XXX_FEC_STRUCT_PTR          fec_ptr= fec_context_ptr->FEC_ADDRESS;
   uint_32                          events;
   
   if (fec_ptr == NULL) return;
   
   events = fec_ptr->EIR;
   while (events & MCF5XXX_FEC_EIR_HBERR) {

      /* clear the interrupt */
      fec_ptr->EIR = MCF5XXX_FEC_EIR_HBERR;

      events = fec_ptr->EIR;
   } 
} 

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_install_isr
*  Returned Value : ENET_OK or error code
*  Comments       :
*         
*
*END*-----------------------------------------------------------------*/

static boolean MCF5XXX_FEC_install_isr( 
   ENET_CONTEXT_STRUCT_PTR enet_ptr, 
   uint_32                 int_num, 
   uint_32                 int_index, 
   INT_ISR_FPTR            isr, 
   uint_32                 level, 
   uint_32                 sublevel  ) 
{
   uint_32  vector = MCF5XXX_FEC_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, int_index);
 
#if BSPCFG_ENET_RESTORE
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR    fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;


   // Save old ISR and data
   fec_context_ptr->OLDISR_PTR[int_num]   = _int_get_isr(vector);
   fec_context_ptr->OLDISR_DATA[int_num] = _int_get_isr_data(vector);
#endif

   if (_int_install_isr(vector, isr, (pointer)enet_ptr)==NULL) {
      return FALSE;
   }

   // Initialize interrupt priority and level
   _psp_set_int_prio_and_level((PSP_INTERRUPT_TABLE_INDEX)vector, level, sublevel, TRUE);

   return TRUE;
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_install_isrs
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

boolean MCF5XXX_FEC_install_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr, MCF5XXX_FEC_INIT_STRUCT const * enet_init_ptr  ) 
{
   boolean bOK;
   bOK = MCF5XXX_FEC_install_isr(enet_ptr, 0, MCF5XXX_FEC_INT_TX_INTB, MCF5XXX_FEC_TX_ISR, enet_init_ptr->ETX_LEVEL,enet_init_ptr->ETX_SUBLEVEL  ) ;
   if (bOK) {
      bOK = MCF5XXX_FEC_install_isr(enet_ptr, 1, MCF5XXX_FEC_INT_TX_INTF, MCF5XXX_FEC_TX_ISR, enet_init_ptr->ETX_LEVEL,enet_init_ptr->ETX_SUBLEVEL  ) ;
   }
   if (bOK) {
      bOK = MCF5XXX_FEC_install_isr(enet_ptr, 2, MCF5XXX_FEC_INT_RX_INTB, MCF5XXX_FEC_RX_ISR, enet_init_ptr->ERX_LEVEL,enet_init_ptr->ERX_SUBLEVEL  ) ;
   }
   if (bOK) {
      bOK = MCF5XXX_FEC_install_isr(enet_ptr, 3, MCF5XXX_FEC_INT_RX_INTF, MCF5XXX_FEC_RX_ISR, enet_init_ptr->ERX_LEVEL,enet_init_ptr->ERX_SUBLEVEL  ) ;
   }
   
#if !PSP_MQX_CPU_IS_MCF5441X
   if (bOK) {
      bOK = MCF5XXX_FEC_install_isr(enet_ptr, 4, MCF5XXX_FEC_INT_HBERR, MCF5XXX_FEC_Error_ISR, enet_init_ptr->ERX_LEVEL,enet_init_ptr->ERX_SUBLEVEL  ) ;
   }
#endif 

   return bOK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_mask_interrupts
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

void MCF5XXX_FEC_mask_interrupts( ENET_CONTEXT_STRUCT_PTR enet_ptr ) 
{
   uint_32  i;
   
   for (i=0;i<MCF5XXX_FEC_NUM_INTS;i++) {
      _psp_int_mask((PSP_INTERRUPT_TABLE_INDEX)(MCF5XXX_FEC_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER,i)) );
   }
}


#if BSPCFG_ENET_RESTORE

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_uninstall_isr
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_uninstall_isr( ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 int_num, uint_32 int_index  ) 
{
   uint_32  vector = MCF5XXX_FEC_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, int_index);
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR    fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
 
   _psp_int_mask((PSP_INTERRUPT_TABLE_INDEX)vector);
   if (fec_context_ptr->OLDISR_PTR[int_num]) {
      _int_install_isr(vector, fec_context_ptr->OLDISR_PTR[int_num], fec_context_ptr->OLDISR_DATA[int_num]);
      fec_context_ptr->OLDISR_PTR[int_num] = (INT_ISR_FPTR)NULL;
   }
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_uninstall_all_isrs
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

void MCF5XXX_FEC_uninstall_all_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr ) 
{
   MCF5XXX_FEC_uninstall_isr(enet_ptr, 0, MCF5XXX_FEC_INT_TX_INTB) ;
   MCF5XXX_FEC_uninstall_isr(enet_ptr, 1, MCF5XXX_FEC_INT_TX_INTF) ;
   MCF5XXX_FEC_uninstall_isr(enet_ptr, 2, MCF5XXX_FEC_INT_RX_INTB) ;
   MCF5XXX_FEC_uninstall_isr(enet_ptr, 3, MCF5XXX_FEC_INT_RX_INTF) ;
   MCF5XXX_FEC_uninstall_isr(enet_ptr, 4, MCF5XXX_FEC_INT_RX_INTF) ;
}
#endif


/*FUNCTION*-------------------------------------------------------------
* 
* Function Name    : MCF5XXX_FEC_get_vector
* Returned Value   : MQX vector number for specified interrupt
* Comments         :
*    This function returns index into MQX interrupt vector table for
*    specified enet interrupt. If not known, returns 0.
*
*END*-----------------------------------------------------------------*/


uint_32 MCF5XXX_FEC_get_vector 
(
    uint_32 device,
    uint_32 vector_index
)
{ 
    uint_32 index = 0;

    if ((device < MCF5XXX_FEC_DEVICE_COUNT) && (vector_index < MCF5XXX_FEC_NUM_INTS)) {
      index = MCF5XXX_FEC_vectors[device][vector_index];
    }

    return index;
} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_free_context
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

void MCF5XXX_FEC_free_context( MCF5XXX_FEC_CONTEXT_STRUCT_PTR fec_context_ptr ) 
{
   if (fec_context_ptr) {
      if (fec_context_ptr->UNALIGNED_BUFFERS) {
         _mem_free((pointer)fec_context_ptr->UNALIGNED_BUFFERS);
      }
      if (fec_context_ptr->RX_PCB_BASE) {
         _mem_free((pointer)fec_context_ptr->RX_PCB_BASE);
      }
      if (fec_context_ptr->TxPCBS_PTR) {
         _mem_free((pointer)fec_context_ptr->TxPCBS_PTR);
      }
      if (fec_context_ptr->UNALIGNED_RING_PTR) {
         _mem_free((pointer)fec_context_ptr->UNALIGNED_RING_PTR);
      }
   
      _mem_free((pointer)fec_context_ptr);
   }
}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/LCD_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type LCD
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(LCD_PDD_H_)
#define LCD_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error LCD PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK30D10) /* LCD */ && \
      !defined(MCU_MK30D7) /* LCD */ && \
      !defined(MCU_MK30DZ10) /* LCD */ && \
      !defined(MCU_MK40D10) /* LCD */ && \
      !defined(MCU_MK40D7) /* LCD */ && \
      !defined(MCU_MK40DZ10) /* LCD */ && \
      !defined(MCU_MK40X256VMD100) /* LCD */ && \
      !defined(MCU_MK51D10) /* LCD */ && \
      !defined(MCU_MK51D7) /* LCD */ && \
      !defined(MCU_MK51DZ10) /* LCD */ && \
      !defined(MCU_MK53D10) /* LCD */ && \
      !defined(MCU_MK53DZ10) /* LCD */ && \
      !defined(MCU_MKL34Z4) /* LCD */ && \
      !defined(MCU_MKL36Z4) /* LCD */ && \
      !defined(MCU_MKL46Z4) /* LCD */
  // Unsupported MCU is active
  #error LCD PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/* Interrupt masks (for EnableInterrupts, DisableInterrupts macros). */
  #define LCD_PDD_FAULT_DETECT_COMPLETE LCD_GCR_FDCIEN_MASK /**< Fault detect complete interrupt mask */

#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/* Interrupt masks (for EnableInterrupts, DisableInterrupts macros). */
  #define LCD_PDD_FRAME_FREQUENCY       LCD_GCR_LCDIEN_MASK /**< Frame frequency interrupt mask */
  #define LCD_PDD_FAULT_DETECT_COMPLETE LCD_GCR_FDCIEN_MASK /**< Fault detect complete interrupt mask */

#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/* Load adjust constants (for SetLoadAdjust macro). */
#define LCD_PDD_LOW_LOAD_RESISTOR_NET  0U        /**< Low load (LCD glass capacitance 2nF or lower), resistor net. */
#define LCD_PDD_HIGH_LOAD_RESISTOR_NET 0x1U      /**< High Load (LCD glass capacitance 8nF or lower), resistor net. */
#define LCD_PDD_FAST_CLK_CHPUMP_8NF    0x2U      /**< Fastest clock source for charge pump (LCD glass capacitance 8nF or lower). */
#define LCD_PDD_MIDDLE_CLK_CHPUMP_6NF  0x3U      /**< Intermediate clock source for charge pump (LCD glass capacitance 6nF or lower). */
#define LCD_PDD_MIDDLE_CLK_CHPUMP_4NF  0x4U      /**< Intermediate clock source for charge pump (LCD glass capacitance 4nF or lower). */
#define LCD_PDD_SLOW_CLK_CHPUMP_2NF    0x5U      /**< Slowest clock source for charge pump (LCD glass capacitance 2nF or lower). */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/* Voltage supply constants (for SetVoltageSupplyControl macro). */
  #define LCD_PDD_VLL3_FROM_VDD   0U               /**< Drive VLL3 internally from VDD. */
  #define LCD_PDD_VLL3_FROM_VIREG 0x1U             /**< Drive VLL3 externally from VDD or drive VLL1 internally from VIREG. */

#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/* Voltage supply constants (for SetVoltageSupplyControl macro). */
  #define LCD_PDD_VLL2_FROM_VDD   0U               /**< Drive VLL2 internally from VDD. */
  #define LCD_PDD_VLL3_FROM_VDD   0x1U             /**< Drive VLL3 internally from VDD. */
  #define LCD_PDD_VLL3_FROM_VIREG 0x3U             /**< Drive VLL3 externally from VDD or drive VLL1 internally from VIREG. */

#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/* Alternate Clk divider constants (for SetAlternateClkDivider macro) */
#define LCD_PDD_DIVIDE_FACTOR_1   0U             /**< LCD alternate clock divider factor 1. */
#define LCD_PDD_DIVIDE_FACTOR_8   0x1U           /**< LCD alternate clock divider factor 8. */
#define LCD_PDD_DIVIDE_FACTOR_64  0x2U           /**< LCD alternate clock divider factor 64. */
#define LCD_PDD_DIVIDE_FACTOR_512 0x3U           /**< LCD alternate clock divider factor 512. */

/* Clock source constants (for SetClkSource macro). */
#define LCD_PDD_DEFAULT_CLK   0U                 /**< Default clock(system or RTC OSC output) as the LCD clock source. */
#define LCD_PDD_ALTERNATE_CLK 0x40U              /**< Alternate clock (e.g. MCGIRCLK output) as the LCD clock source. */

/* Blink mode constants (for SetBlinkMode macro). */
#define LCD_PDD_BLANK_BLINK     0U               /**< Blank during the blink period. */
#define LCD_PDD_ALTERNATE_BLINK 0x8U             /**< Alternate display during blink period. */

/* Fault detect clock prescaler constants (for SetFaultDetectClkPrescaler
   macro). */
#define LCD_PDD_FAULT_DETECT_PRESCALER_1   0U    /**< Fault detect clock prescaler 1. */
#define LCD_PDD_FAULT_DETECT_PRESCALER_2   0x1U  /**< Fault detect clock prescaler 2. */
#define LCD_PDD_FAULT_DETECT_PRESCALER_4   0x2U  /**< Fault detect clock prescaler 4. */
#define LCD_PDD_FAULT_DETECT_PRESCALER_8   0x3U  /**< Fault detect clock prescaler 8. */
#define LCD_PDD_FAULT_DETECT_PRESCALER_16  0x4U  /**< Fault detect clock prescaler 16. */
#define LCD_PDD_FAULT_DETECT_PRESCALER_32  0x5U  /**< Fault detect clock prescaler 32. */
#define LCD_PDD_FAULT_DETECT_PRESCALER_64  0x6U  /**< Fault detect clock prescaler 64. */
#define LCD_PDD_FAULT_DETECT_PRESCALER_128 0x7U  /**< Fault detect clock prescaler 128. */

/* Fault detect sample width constants (for SetFaultDetectSampleWidth macro). */
#define LCD_PDD_SAMPLE_WIDTH_CLK_4   0U          /**< Sample window width is 4 sample clock cycles. */
#define LCD_PDD_SAMPLE_WIDTH_CLK_8   0x1U        /**< Sample window width is 8 sample clock cycles. */
#define LCD_PDD_SAMPLE_WIDTH_CLK_16  0x2U        /**< Sample window width is 16 sample clock cycles. */
#define LCD_PDD_SAMPLE_WIDTH_CLK_32  0x3U        /**< Sample window width is 32 sample clock cycles. */
#define LCD_PDD_SAMPLE_WIDTH_CLK_64  0x4U        /**< Sample window width is 64 sample clock cycles. */
#define LCD_PDD_SAMPLE_WIDTH_CLK_128 0x5U        /**< Sample window width is 128 sample clock cycles. */
#define LCD_PDD_SAMPLE_WIDTH_CLK_256 0x6U        /**< Sample window width is 256 sample clock cycles. */
#define LCD_PDD_SAMPLE_WIDTH_CLK_512 0x7U        /**< Sample window width is 512 sample clock cycles. */

/* Pin type mode constants (for SetFaultDetectPinType macro). */
#define LCD_PDD_FAULT_FRONTPLANE 0U              /**< Type of the selected pin under fault detect test is frontplane. */
#define LCD_PDD_FAULT_BACKPLANE  0x40U           /**< Type of the selected pin under fault detect test is backplane. */

/* Register index constants (for EnablePinMask, SetPinAsBackplaneMask macros). */
#define LCD_PDD_PIN_RANGE_7_0   0U               /**< Register 0, 7..0 range of LCDx pin. */
#define LCD_PDD_PIN_RANGE_15_8  0x1U             /**< Register 1, 15..8 range of LCDx pin. */
#define LCD_PDD_PIN_RANGE_23_16 0x2U             /**< Register 2, 23..16 range of LCDx pin. */
#define LCD_PDD_PIN_RANGE_31_24 0x3U             /**< Register 3, 31..24 range of LCDx pin. */
#define LCD_PDD_PIN_RANGE_39_32 0x4U             /**< Register 4, 39..32 range of LCDx pin. */
#define LCD_PDD_PIN_RANGE_47_40 0x5U             /**< Register 5, 47..40 range of LCDx pin. */
#define LCD_PDD_PIN_RANGE_55_48 0x6U             /**< Register 6, 55..48 range of LCDx pin. */
#define LCD_PDD_PIN_RANGE_63_56 0x7U             /**< Register 7, 63..56 range of LCDx pin. */

/* Clock source constants (for SetClkSource macro). */
#define LCD_PDD_CLK1 0U                          /**< Alternate clock source 1 (MCGIRCLK) as the LCD clock source. */
#define LCD_PDD_CLK2 0x800U                      /**< Alternate clock source 2 (OSC0ERCLK) as the LCD clock source. */


/* ----------------------------------------------------------------------------
   -- EnableRegulatedVoltage
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables or disables internal voltage regulator.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of regulated voltage. This parameter is of
 *        "Global enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableRegulatedVoltage(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define LCD_PDD_EnableRegulatedVoltage(PeripheralBase, State) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_RVEN_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)((uint32_t)(State) << LCD_GCR_RVEN_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetRegulatedVoltageTrim
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets to adjust the regulated input. The regulated input is changed by
 * 1.5% for each count.
 * @param PeripheralBase Peripheral base address.
 * @param TrimValue Regulated voltage trim value[0..15]. This parameter is a
 *        4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetRegulatedVoltageTrim(deviceID, 1);
 *      @endcode
 */
#define LCD_PDD_SetRegulatedVoltageTrim(PeripheralBase, TrimValue) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_RVTRIM_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)((uint32_t)(TrimValue) << LCD_GCR_RVTRIM_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetLoadAdjust
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the LCD module charge pump or a resistor network to supply the
 * LCD voltages and handle different LCD glass capacitance.
 * @param PeripheralBase Peripheral base address.
 * @param LoadAdjust Load adjust value. The user should use one from the
 *        enumerated values. This parameter is of "Load adjust constants (for
 *        SetLoadAdjust macro)." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetLoadAdjust(deviceID, LCD_PDD_LOW_LOAD_RESISTOR_NET);
 *      @endcode
 */
#define LCD_PDD_SetLoadAdjust(PeripheralBase, LoadAdjust) ( \
    ((LoadAdjust) == LCD_PDD_LOW_LOAD_RESISTOR_NET) ? ( \
      LCD_GCR_REG(PeripheralBase) &= \
       (uint32_t)(( \
        (uint32_t)(~(uint32_t)LCD_GCR_LADJ_MASK)) & (( \
        (uint32_t)(~(uint32_t)LCD_GCR_CPSEL_MASK)) & ( \
        (uint32_t)(~(uint32_t)0x40000U))))) : (((LoadAdjust) == LCD_PDD_HIGH_LOAD_RESISTOR_NET) ? ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_GCR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_GCR_LADJ_MASK)) & (( \
         (uint32_t)(~(uint32_t)LCD_GCR_CPSEL_MASK)) & ( \
         (uint32_t)(~(uint32_t)0x40000U)))))) | ( \
        (uint32_t)((uint32_t)0x2U << LCD_GCR_LADJ_SHIFT)))) : (((LoadAdjust) == LCD_PDD_FAST_CLK_CHPUMP_8NF) ? ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_GCR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_GCR_LADJ_MASK)) & ( \
         (uint32_t)(~(uint32_t)0x40000U))))) | ( \
        LCD_GCR_CPSEL_MASK))) : (((LoadAdjust) == LCD_PDD_MIDDLE_CLK_CHPUMP_6NF) ? ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_GCR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_GCR_LADJ_MASK)) & ( \
         (uint32_t)(~(uint32_t)0x40000U))))) | (( \
        (uint32_t)((uint32_t)0x1U << LCD_GCR_LADJ_SHIFT)) | ( \
        LCD_GCR_CPSEL_MASK)))) : (((LoadAdjust) == LCD_PDD_MIDDLE_CLK_CHPUMP_4NF) ? ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_GCR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_GCR_LADJ_MASK)) & ( \
         (uint32_t)(~(uint32_t)0x40000U))))) | (( \
        (uint32_t)((uint32_t)0x2U << LCD_GCR_LADJ_SHIFT)) | ( \
        LCD_GCR_CPSEL_MASK)))) : ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_GCR_REG(PeripheralBase) | (LCD_GCR_LADJ_MASK | LCD_GCR_CPSEL_MASK))) & ( \
        (uint32_t)(~(uint32_t)0x40000U)))) \
    )))) \
  )

/* ----------------------------------------------------------------------------
   -- SetVoltageSupplyControl
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Sets the LCD module on external or internal power supply.
 * @param PeripheralBase Peripheral base address.
 * @param VoltageSupply Voltage supply control value. The user should use one
 *        from the enumerated values. This parameter is a 1-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetVoltageSupplyControl(deviceID, 1);
 *      @endcode
 */
  #define LCD_PDD_SetVoltageSupplyControl(PeripheralBase, VoltageSupply) ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_GCR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_GCR_VSUPPLY_MASK)) & ( \
         (uint32_t)(~(uint32_t)0x40000U))))) | ( \
        (uint32_t)((uint32_t)(VoltageSupply) << LCD_GCR_VSUPPLY_SHIFT))) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Sets the LCD module on external or internal power supply.
 * @param PeripheralBase Peripheral base address.
 * @param VoltageSupply Voltage supply control value. The user should use one
 *        from the enumerated values. This parameter is a 2-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetVoltageSupplyControl(deviceID, 1);
 *      @endcode
 */
  #define LCD_PDD_SetVoltageSupplyControl(PeripheralBase, VoltageSupply) ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_GCR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_GCR_VSUPPLY_MASK)) & ( \
         (uint32_t)(~(uint32_t)0x40000U))))) | ( \
        (uint32_t)((uint32_t)(VoltageSupply) << LCD_GCR_VSUPPLY_SHIFT))) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- EnableInterrupts
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Enables module frame frequency or fault detection complete interrupt.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of interrupts to enable. Use constants from group "Interrupt
 *        masks (for EnableInterrupts, DisableInterrupts macros).". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableInterrupts(deviceID, LCD_PDD_FAULT_DETECT_COMPLETE);
 *      @endcode
 */
  #define LCD_PDD_EnableInterrupts(PeripheralBase, Mask) ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_GCR_REG(PeripheralBase) | (uint32_t)(Mask))) & ( \
        (uint32_t)(~(uint32_t)0x40000U))) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Enables module frame frequency or fault detection complete interrupt.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of interrupts to enable. Use constants from group "Interrupt
 *        masks (for EnableInterrupts, DisableInterrupts macros).". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableInterrupts(deviceID, LCD_PDD_FRAME_FREQUENCY);
 *      @endcode
 */
  #define LCD_PDD_EnableInterrupts(PeripheralBase, Mask) ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_GCR_REG(PeripheralBase) | (uint32_t)(Mask))) & ( \
        (uint32_t)(~(uint32_t)0x40000U))) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- DisableInterrupts
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Disables module frame frequency or fault detection complete interrupt.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of interrupts to disable. Use constants from group
 *        "Interrupt masks (for EnableInterrupts, DisableInterrupts macros).". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_DisableInterrupts(deviceID, LCD_PDD_FAULT_DETECT_COMPLETE);
 *      @endcode
 */
  #define LCD_PDD_DisableInterrupts(PeripheralBase, Mask) ( \
      LCD_GCR_REG(PeripheralBase) &= \
       (uint32_t)((uint32_t)(~(uint32_t)(Mask)) & (uint32_t)(~(uint32_t)0x40000U)) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Disables module frame frequency or fault detection complete interrupt.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of interrupts to disable. Use constants from group
 *        "Interrupt masks (for EnableInterrupts, DisableInterrupts macros).". This
 *        parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_DisableInterrupts(deviceID, LCD_PDD_FRAME_FREQUENCY);
 *      @endcode
 */
  #define LCD_PDD_DisableInterrupts(PeripheralBase, Mask) ( \
      LCD_GCR_REG(PeripheralBase) &= \
       (uint32_t)((uint32_t)(~(uint32_t)(Mask)) & (uint32_t)(~(uint32_t)0x40000U)) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- SetAlternateClkDivider
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the LCD module on external or internal power supply.
 * @param PeripheralBase Peripheral base address.
 * @param Divider Divide factor value. The user should use one from the
 *        enumerated values. This parameter is of "Alternate Clk divider constants (for
 *        SetAlternateClkDivider macro)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetAlternateClkDivider(deviceID, LCD_PDD_DIVIDE_FACTOR_1);
 *      @endcode
 */
#define LCD_PDD_SetAlternateClkDivider(PeripheralBase, Divider) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_ALTDIV_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)((uint32_t)(Divider) << LCD_GCR_ALTDIV_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInWaitMode
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Enables or disables module driver, charge pump, resistor bias network,
 * and voltage regulator stop while in Wait mode.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state in wait mode. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableInWaitMode(deviceID, PDD_DISABLE);
 *      @endcode
 */
  #define LCD_PDD_EnableInWaitMode(PeripheralBase, State) ( \
      ((State) == PDD_DISABLE) ? ( \
        LCD_GCR_REG(PeripheralBase) = \
         (uint32_t)(( \
          (uint32_t)(LCD_GCR_REG(PeripheralBase) | LCD_GCR_LCDDOZE_MASK)) & ( \
          (uint32_t)(~(uint32_t)0x40000U)))) : ( \
        LCD_GCR_REG(PeripheralBase) &= \
         (uint32_t)((uint32_t)(~(uint32_t)LCD_GCR_LCDDOZE_MASK) & (uint32_t)(~(uint32_t)0x40000U))) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Enables or disables module driver, charge pump, resistor bias network,
 * and voltage regulator stop while in Wait mode.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state in wait mode. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableInWaitMode(deviceID, PDD_DISABLE);
 *      @endcode
 */
  #define LCD_PDD_EnableInWaitMode(PeripheralBase, State) ( \
      ((State) == PDD_DISABLE) ? ( \
        LCD_GCR_REG(PeripheralBase) = \
         (uint32_t)(( \
          (uint32_t)(LCD_GCR_REG(PeripheralBase) | LCD_GCR_LCDWAIT_MASK)) & ( \
          (uint32_t)(~(uint32_t)0x40000U)))) : ( \
        LCD_GCR_REG(PeripheralBase) &= \
         (uint32_t)((uint32_t)(~(uint32_t)LCD_GCR_LCDWAIT_MASK) & (uint32_t)(~(uint32_t)0x40000U))) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- EnableInStopMode
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables or disables module driver, charge pump, resistor bias network,
 * and voltage regulator while in Stop mode.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state in stop mode. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableInStopMode(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define LCD_PDD_EnableInStopMode(PeripheralBase, State) ( \
    ((State) == PDD_DISABLE) ? ( \
      LCD_GCR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_GCR_REG(PeripheralBase) | LCD_GCR_LCDSTP_MASK)) & ( \
        (uint32_t)(~(uint32_t)0x40000U)))) : ( \
      LCD_GCR_REG(PeripheralBase) &= \
       (uint32_t)((uint32_t)(~(uint32_t)LCD_GCR_LCDSTP_MASK) & (uint32_t)(~(uint32_t)0x40000U))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableDevice
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables LCD module driver system.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of segment LCD device. This parameter is of
 *        "Global enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableDevice(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define LCD_PDD_EnableDevice(PeripheralBase, State) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_LCDEN_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)((uint32_t)(State) << LCD_GCR_LCDEN_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetClkSource
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets clock the default or alternate as the LCD clock source.
 * @param PeripheralBase Peripheral base address.
 * @param ClkSource Clock source value. The user should use one from the
 *        enumerated values. This parameter is of "Clock source constants (for
 *        SetClkSource macro)." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetClkSource(deviceID, LCD_PDD_DEFAULT_CLK);
 *      @endcode
 */
#define LCD_PDD_SetClkSource(PeripheralBase, ClkSource) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_SOURCE_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)(ClkSource))) \
  )

/* ----------------------------------------------------------------------------
   -- SetClkPrescaler
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets a clock divider to generate the LCD module frame frequency.
 * @param PeripheralBase Peripheral base address.
 * @param ClkPrescaler Clock prescaler value[0..7]. This parameter is a 3-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetClkPrescaler(deviceID, 1);
 *      @endcode
 */
#define LCD_PDD_SetClkPrescaler(PeripheralBase, ClkPrescaler) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_LCLK_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)((uint32_t)(ClkPrescaler) << LCD_GCR_LCLK_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetDutyCycle
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the duty cycle of the LCD module driver.
 * @param PeripheralBase Peripheral base address.
 * @param DutyCycle Duty cycle value[0..7]. This parameter is a 3-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetDutyCycle(deviceID, 1);
 *      @endcode
 */
#define LCD_PDD_SetDutyCycle(PeripheralBase, DutyCycle) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_DUTY_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)(DutyCycle))) \
  )

/* ----------------------------------------------------------------------------
   -- GetFrameFreqInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Return non-zero if frame frequency interrupt flag is set, otherwise
 * returns zero.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      uint32_t result = LCD_PDD_GetFrameFreqInterruptFlag(deviceID);
 *      @endcode
 */
#define LCD_PDD_GetFrameFreqInterruptFlag(PeripheralBase) ( \
    (uint32_t)(LCD_AR_REG(PeripheralBase) & LCD_AR_LCDIF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClearFrameFreqInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears interrupt flag of frame frequency.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_ClearFrameFreqInterruptFlag(deviceID);
 *      @endcode
 */
#define LCD_PDD_ClearFrameFreqInterruptFlag(PeripheralBase) ( \
    LCD_AR_REG(PeripheralBase) |= \
     LCD_AR_LCDIF_MASK \
  )

/* ----------------------------------------------------------------------------
   -- EnableBlinking
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Enables or disables LCD module blinking.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of segment LCD. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableBlinking(deviceID, PDD_DISABLE);
 *      @endcode
 */
  #define LCD_PDD_EnableBlinking(PeripheralBase, State) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_AR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_AR_BLINK_MASK))) | ( \
        (uint32_t)((uint32_t)(State) << LCD_AR_BLINK_SHIFT))) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Enables or disables LCD module blinking.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of segment LCD. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableBlinking(deviceID, PDD_DISABLE);
 *      @endcode
 */
  #define LCD_PDD_EnableBlinking(PeripheralBase, State) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_AR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_AR_BLINK_MASK)) & ( \
         (uint32_t)(~(uint32_t)LCD_AR_LCDIF_MASK))))) | ( \
        (uint32_t)((uint32_t)(State) << LCD_AR_BLINK_SHIFT))) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- EnableAlternateMode
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Enables or disables alternate display mode.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of segment LCD. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableAlternateMode(deviceID, PDD_DISABLE);
 *      @endcode
 */
  #define LCD_PDD_EnableAlternateMode(PeripheralBase, State) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_AR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_AR_ALT_MASK))) | ( \
        (uint32_t)((uint32_t)(State) << LCD_AR_ALT_SHIFT))) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Enables or disables alternate display mode.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of segment LCD. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableAlternateMode(deviceID, PDD_DISABLE);
 *      @endcode
 */
  #define LCD_PDD_EnableAlternateMode(PeripheralBase, State) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_AR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_AR_ALT_MASK)) & ( \
         (uint32_t)(~(uint32_t)LCD_AR_LCDIF_MASK))))) | ( \
        (uint32_t)((uint32_t)(State) << LCD_AR_ALT_SHIFT))) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- EnableBlankDisplayMode
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Enables or disables blank display mode.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of segment LCD. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableBlankDisplayMode(deviceID, PDD_DISABLE);
 *      @endcode
 */
  #define LCD_PDD_EnableBlankDisplayMode(PeripheralBase, State) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_AR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_AR_BLANK_MASK))) | ( \
        (uint32_t)((uint32_t)(State) << LCD_AR_BLANK_SHIFT))) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Enables or disables blank display mode.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of segment LCD. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableBlankDisplayMode(deviceID, PDD_DISABLE);
 *      @endcode
 */
  #define LCD_PDD_EnableBlankDisplayMode(PeripheralBase, State) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_AR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_AR_BLANK_MASK)) & ( \
         (uint32_t)(~(uint32_t)LCD_AR_LCDIF_MASK))))) | ( \
        (uint32_t)((uint32_t)(State) << LCD_AR_BLANK_SHIFT))) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- SetBlinkMode
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Sets blink mode displayed during the blink period.
 * @param PeripheralBase Peripheral base address.
 * @param BlinkMode Blink mode value. The user should use one from the
 *        enumerated values. This parameter is of "Blink mode constants (for SetBlinkMode
 *        macro)." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetBlinkMode(deviceID, LCD_PDD_BLANK_BLINK);
 *      @endcode
 */
  #define LCD_PDD_SetBlinkMode(PeripheralBase, BlinkMode) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_AR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_AR_BMODE_MASK))) | ( \
        (uint32_t)(BlinkMode))) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Sets blink mode displayed during the blink period.
 * @param PeripheralBase Peripheral base address.
 * @param BlinkMode Blink mode value. The user should use one from the
 *        enumerated values. This parameter is of "Blink mode constants (for SetBlinkMode
 *        macro)." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetBlinkMode(deviceID, LCD_PDD_BLANK_BLINK);
 *      @endcode
 */
  #define LCD_PDD_SetBlinkMode(PeripheralBase, BlinkMode) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_AR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_AR_BMODE_MASK)) & ( \
         (uint32_t)(~(uint32_t)LCD_AR_LCDIF_MASK))))) | ( \
        (uint32_t)(BlinkMode))) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- SetBlinkRate
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)))
/**
 * @brief Sets speed at which the LCD blinks.
 * @param PeripheralBase Peripheral base address.
 * @param BlinkRate Blink rate value[0..7]. This parameter is a 3-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetBlinkRate(deviceID, 1);
 *      @endcode
 */
  #define LCD_PDD_SetBlinkRate(PeripheralBase, BlinkRate) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(LCD_AR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_AR_BRATE_MASK))) | ( \
        (uint32_t)(BlinkRate))) \
    )
#else /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */
/**
 * @brief Sets speed at which the LCD blinks.
 * @param PeripheralBase Peripheral base address.
 * @param BlinkRate Blink rate value[0..7]. This parameter is a 3-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_AR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetBlinkRate(deviceID, 1);
 *      @endcode
 */
  #define LCD_PDD_SetBlinkRate(PeripheralBase, BlinkRate) ( \
      LCD_AR_REG(PeripheralBase) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_AR_REG(PeripheralBase)) & (( \
         (uint32_t)(~(uint32_t)LCD_AR_BRATE_MASK)) & ( \
         (uint32_t)(~(uint32_t)LCD_AR_LCDIF_MASK))))) | ( \
        (uint32_t)(BlinkRate))) \
    )
#endif /* (defined(MCU_MK30D10)) || (defined(MCU_MK30D7)) || (defined(MCU_MK30DZ10)) || (defined(MCU_MK40D10)) || (defined(MCU_MK40D7)) || (defined(MCU_MK40DZ10)) || (defined(MCU_MK40X256VMD100)) || (defined(MCU_MK51D10)) || (defined(MCU_MK51D7)) || (defined(MCU_MK51DZ10)) || (defined(MCU_MK53D10)) || (defined(MCU_MK53DZ10)) */

/* ----------------------------------------------------------------------------
   -- SetFaultDetectClkPrescaler
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets fault detect clock prescaler.
 * @param PeripheralBase Peripheral base address.
 * @param FaultClkPrescaler Fault detect clock prescaler value[0..7]. This
 *        parameter is a 3-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_FDCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetFaultDetectClkPrescaler(deviceID, 1);
 *      @endcode
 */
#define LCD_PDD_SetFaultDetectClkPrescaler(PeripheralBase, FaultClkPrescaler) ( \
    LCD_FDCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(LCD_FDCR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_FDCR_FDPRS_MASK))) | ( \
      (uint32_t)((uint32_t)(FaultClkPrescaler) << LCD_FDCR_FDPRS_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetFaultDetectSampleWidth
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the sample window width of fault detection in number of cycles.
 * @param PeripheralBase Peripheral base address.
 * @param SampleWidth Sample window width value[0..7]. This parameter is a 3-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_FDCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetFaultDetectSampleWidth(deviceID, 1);
 *      @endcode
 */
#define LCD_PDD_SetFaultDetectSampleWidth(PeripheralBase, SampleWidth) ( \
    LCD_FDCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(LCD_FDCR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_FDCR_FDSWW_MASK))) | ( \
      (uint32_t)((uint32_t)(SampleWidth) << LCD_FDCR_FDSWW_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableFaultDetect
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables or disables fault detection.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of fault detection. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_FDCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableFaultDetect(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define LCD_PDD_EnableFaultDetect(PeripheralBase, State) ( \
    LCD_FDCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(LCD_FDCR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_FDCR_FDEN_MASK))) | ( \
      (uint32_t)((uint32_t)(State) << LCD_FDCR_FDEN_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetFaultDetectPinType
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the LCD pin to be checked by pull-up or run-time fault detection.
 * @param PeripheralBase Peripheral base address.
 * @param PinType Requested pin type. This parameter is of "Pin type mode
 *        constants (for SetFaultDetectPinType macro)." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_FDCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetFaultDetectPinType(deviceID, LCD_PDD_FAULT_FRONTPLANE);
 *      @endcode
 */
#define LCD_PDD_SetFaultDetectPinType(PeripheralBase, PinType) ( \
    LCD_FDCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(LCD_FDCR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_FDCR_FDBPEN_MASK))) | ( \
      (uint32_t)(PinType))) \
  )

/* ----------------------------------------------------------------------------
   -- SetFaultDetectPinID
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the LCD pin to be checked by pull-up or run-time fault detection.
 * @param PeripheralBase Peripheral base address.
 * @param DetectPinID Fault detect pin ID value[0..63]. This parameter is a
 *        6-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_FDCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SetFaultDetectPinID(deviceID, 1);
 *      @endcode
 */
#define LCD_PDD_SetFaultDetectPinID(PeripheralBase, DetectPinID) ( \
    LCD_FDCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(LCD_FDCR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)LCD_FDCR_FDPINID_MASK))) | ( \
      (uint32_t)(DetectPinID))) \
  )

/* ----------------------------------------------------------------------------
   -- GetFaultDetectInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Return value of fault detection complete flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: LCD_FDSR.
 * @par Example:
 *      @code
 *      uint32_t result = LCD_PDD_GetFaultDetectInterruptFlag(deviceID);
 *      @endcode
 */
#define LCD_PDD_GetFaultDetectInterruptFlag(PeripheralBase) ( \
    (uint32_t)(LCD_FDSR_REG(PeripheralBase) & LCD_FDSR_FDCF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClearFaultDetectInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears flag of fault detection complete.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_FDSR.
 * @par Example:
 *      @code
 *      LCD_PDD_ClearFaultDetectInterruptFlag(deviceID);
 *      @endcode
 */
#define LCD_PDD_ClearFaultDetectInterruptFlag(PeripheralBase) ( \
    LCD_FDSR_REG(PeripheralBase) |= \
     LCD_FDSR_FDCF_MASK \
  )

/* ----------------------------------------------------------------------------
   -- GetFaultDetectValue
   ---------------------------------------------------------------------------- */

/**
 * @brief Return how many "one/high" are sampled inside the fault detect sample
 * window.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: LCD_FDSR.
 * @par Example:
 *      @code
 *      uint8_t result = LCD_PDD_GetFaultDetectValue(deviceID);
 *      @endcode
 */
#define LCD_PDD_GetFaultDetectValue(PeripheralBase) ( \
    (uint8_t)(LCD_FDSR_REG(PeripheralBase) & LCD_FDSR_FDCNT_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnablePinMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables pins for LCD operation.
 * @param PeripheralBase Peripheral base address.
 * @param RegIndex The user should use one from the enumerated values. This
 *        parameter is of index type.
 * @param PinMask 8 bits mask of pins what are arranged according RegIndex
 *        parameter. This parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PEN[].
 * @par Example:
 *      @code
 *      LCD_PDD_EnablePinMask(deviceID, periphID, 1);
 *      @endcode
 */
#define LCD_PDD_EnablePinMask(PeripheralBase, RegIndex, PinMask) ( \
    ((uint8_t)((uint8_t)(RegIndex) & 0x4U) == 0U) ? ( \
      LCD_PEN_REG(PeripheralBase,0U) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_PEN_REG(PeripheralBase,0U)) & ( \
         (uint32_t)(~(uint32_t)((uint32_t)0xFFU << (uint8_t)((uint8_t)((uint8_t)(RegIndex) & 0x3U) << 3U)))))) | ( \
        (uint32_t)((uint32_t)(PinMask) << (uint8_t)((uint8_t)((uint8_t)(RegIndex) & 0x3U) << 3U))))) : ( \
      LCD_PEN_REG(PeripheralBase,1U) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_PEN_REG(PeripheralBase,1U)) & ( \
         (uint32_t)(~(uint32_t)((uint32_t)0xFFU << (uint8_t)((uint8_t)((uint8_t)(RegIndex) & 0x3U) << 3U)))))) | ( \
        (uint32_t)((uint32_t)(PinMask) << (uint8_t)((uint8_t)((uint8_t)(RegIndex) & 0x3U) << 3U))))) \
  )

/* ----------------------------------------------------------------------------
   -- SetPinAsBackplaneMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets pins as Enables or disables fault detection.
 * @param PeripheralBase Peripheral base address.
 * @param RegIndex The user should use one from the enumerated values. This
 *        parameter is of index type.
 * @param PinMask 8 bits mask of pins what are arranged according RegIndex
 *        parameter. This parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: BPEN[].
 * @par Example:
 *      @code
 *      LCD_PDD_SetPinAsBackplaneMask(deviceID, periphID, 1);
 *      @endcode
 */
#define LCD_PDD_SetPinAsBackplaneMask(PeripheralBase, RegIndex, PinMask) ( \
    ((uint8_t)((uint8_t)(RegIndex) & 0x4U) == 0U) ? ( \
      LCD_BPEN_REG(PeripheralBase,0U) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_BPEN_REG(PeripheralBase,0U)) & ( \
         (uint32_t)(~(uint32_t)((uint32_t)0xFFU << (uint8_t)((uint8_t)((uint8_t)(RegIndex) & 0x3U) << 3U)))))) | ( \
        (uint32_t)((uint32_t)(PinMask) << (uint8_t)((uint8_t)((uint8_t)(RegIndex) & 0x3U) << 3U))))) : ( \
      LCD_BPEN_REG(PeripheralBase,1U) = \
       (uint32_t)(( \
        (uint32_t)(( \
         LCD_BPEN_REG(PeripheralBase,1U)) & ( \
         (uint32_t)(~(uint32_t)((uint32_t)0xFFU << (uint8_t)((uint8_t)((uint8_t)(RegIndex) & 0x3U) << 3U)))))) | ( \
        (uint32_t)((uint32_t)(PinMask) << (uint8_t)((uint8_t)((uint8_t)(RegIndex) & 0x3U) << 3U))))) \
  )

/* ----------------------------------------------------------------------------
   -- SetWaveform
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets value of the frontplanes pins for the backplane phase.
 * @param PeripheralBase Peripheral base address.
 * @param FrontplanePinIndex Wave form register index[0..63]. This parameter is
 *        of index type.
 * @param Waveform Wave form value[0..255]. This parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WF[].
 * @par Example:
 *      @code
 *      LCD_PDD_SetWaveform(deviceID, periphID, 1);
 *      @endcode
 */
#define LCD_PDD_SetWaveform(PeripheralBase, FrontplanePinIndex, Waveform) ( \
    LCD_WF_REG(PeripheralBase,(uint8_t)((uint8_t)(FrontplanePinIndex) >> 2U)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_WF_REG(PeripheralBase,(uint8_t)((uint8_t)(FrontplanePinIndex) >> 2U))) & ( \
       (uint32_t)(~(uint32_t)(( \
        (uint32_t)0xFFU) << ( \
        (uint8_t)((uint8_t)((uint8_t)(FrontplanePinIndex) & 0x3U) << 3U))))))) | ( \
      (uint32_t)(( \
       (uint32_t)(Waveform)) << ( \
       (uint8_t)((uint8_t)((uint8_t)(FrontplanePinIndex) & 0x3U) << 3U))))) \
  )

/* ----------------------------------------------------------------------------
   -- GetWaveform
   ---------------------------------------------------------------------------- */

/**
 * @brief Return value of the frontplanes pins for the backplane phase.
 * @param PeripheralBase Peripheral base address.
 * @param FrontplanePinIndex Wave form register index[0..63]. This parameter is
 *        of index type.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: WF[].
 * @par Example:
 *      @code
 *      uint8_t result = LCD_PDD_GetWaveform(deviceID, periphID);
 *      @endcode
 */
#define LCD_PDD_GetWaveform(PeripheralBase, FrontplanePinIndex) ( \
    (uint8_t)(( \
     LCD_WF_REG(PeripheralBase,(uint8_t)((uint8_t)(FrontplanePinIndex) >> 2U))) >> ( \
     (uint8_t)((uint8_t)((uint8_t)(FrontplanePinIndex) & 0x3U) << 3U))) \
  )

/* ----------------------------------------------------------------------------
   -- SetAlternateWaveform
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets value of the alternate frontplanes pins for the backplane phase.
 * @param PeripheralBase Peripheral base address.
 * @param FrontplanePinIndex Wave form register index[0..63]. This parameter is
 *        of index type.
 * @param Waveform Wave form value[0..15]. This parameter is a 4-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: WF[].
 * @par Example:
 *      @code
 *      LCD_PDD_SetAlternateWaveform(deviceID, periphID, 1);
 *      @endcode
 */
#define LCD_PDD_SetAlternateWaveform(PeripheralBase, FrontplanePinIndex, Waveform) ( \
    LCD_WF_REG(PeripheralBase,(uint8_t)((uint8_t)(FrontplanePinIndex) >> 2U)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_WF_REG(PeripheralBase,(uint8_t)((uint8_t)(FrontplanePinIndex) >> 2U))) & ( \
       (uint32_t)(~(uint32_t)(( \
        (uint32_t)0xFU) << ( \
        (uint8_t)((uint8_t)((uint8_t)(FrontplanePinIndex) & 0x3U) << 3U) + 4U)))))) | ( \
      (uint32_t)(( \
       (uint32_t)(Waveform)) << ( \
       (uint8_t)((uint8_t)((uint8_t)(FrontplanePinIndex) & 0x3U) << 3U) + 4U)))) \
  )

/* ----------------------------------------------------------------------------
   -- GetAlternateWaveform
   ---------------------------------------------------------------------------- */

/**
 * @brief Return value of the alternate frontplanes pins for the backplane phase.
 * @param PeripheralBase Peripheral base address.
 * @param FrontplanePinIndex Wave form register index[0..63]. This parameter is
 *        of index type.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: WF[].
 * @par Example:
 *      @code
 *      uint8_t result = LCD_PDD_GetAlternateWaveform(deviceID, periphID);
 *      @endcode
 */
#define LCD_PDD_GetAlternateWaveform(PeripheralBase, FrontplanePinIndex) ( \
    (uint8_t)(( \
     (uint8_t)(( \
      (uint8_t)(( \
       LCD_WF_REG(PeripheralBase,(uint8_t)((uint8_t)(FrontplanePinIndex) >> 2U))) >> ( \
       (uint8_t)((uint8_t)((uint8_t)(FrontplanePinIndex) & 0x3U) << 3U)))) >> ( \
      4U))) & ( \
     0xFU)) \
  )

/* ----------------------------------------------------------------------------
   -- EnableFastFrameRate
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables fast frame rate.
 * @param PeripheralBase Peripheral base address.
 * @param State Requested state of fast frame rate function. This parameter is
 *        of "Global enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_EnableFastFrameRate(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define LCD_PDD_EnableFastFrameRate(PeripheralBase, State) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_FFR_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)((uint32_t)(State) << LCD_GCR_FFR_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SelectAlternateClkSource
   ---------------------------------------------------------------------------- */

/**
 * @brief Select which alternate clock is used as LCD clock source.
 * @param PeripheralBase Peripheral base address.
 * @param ClkSource Alternate clock source selection. This parameter is of
 *        "Clock source constants (for SetClkSource macro)." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LCD_GCR.
 * @par Example:
 *      @code
 *      LCD_PDD_SelectAlternateClkSource(deviceID, LCD_PDD_CLK1);
 *      @endcode
 */
#define LCD_PDD_SelectAlternateClkSource(PeripheralBase, ClkSource) ( \
    LCD_GCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(( \
       LCD_GCR_REG(PeripheralBase)) & (( \
       (uint32_t)(~(uint32_t)LCD_GCR_ALTSOURCE_MASK)) & ( \
       (uint32_t)(~(uint32_t)0x40000U))))) | ( \
      (uint32_t)(ClkSource))) \
  )
#endif  /* #if defined(LCD_PDD_H_) */

/* LCD_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enjoin.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enjoin.c$
* $Version : 3.5.9.0$
* $Date    : Nov-24-2009$
*
* Comments:
*
*   This file contains the Ethernet multicasting
*   interface function.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

#if BSPCFG_ENABLE_ENET_MULTICAST

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_join
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Joins a multicast group on an Ethernet channel.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_join
   (
      /* [IN] the Ethernet state structure */
      _enet_handle      handle,

      /* [IN] the protocol */
      uint_16           type,

      /* [IN] the multicast group */
      _enet_address     address
   )
{ 
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;
   ENET_ECB_STRUCT_PTR     ecb_ptr;
   ENET_MCB_STRUCT_PTR     mcb_ptr;
   #ifdef ENET_ALLMCAST
      boolean  needjoin;
   #endif

   /*
   ** Make sure it's a multicast group
   */
   #if MQX_CHECK_ERRORS
      if ((address[0] & 1) == 0) {
         return ENETERR_JOIN_MULTICAST;
      } /* Endif */
   #endif

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself and with ENET_leave.
   */
   ENET_lock_context(enet_ptr);

   /*
   ** Make sure it's an open protocol
   */
   for (ecb_ptr = enet_ptr->ECB_HEAD;
        ecb_ptr;
        ecb_ptr = ecb_ptr->NEXT) {

      if (ecb_ptr->TYPE == type) {
         /* Found an existing entry */
         break;
      } 
   } 

   /*
   ** No existing entry found
   */
   if (!ecb_ptr) {
      ENET_unlock_context(enet_ptr);
      return ENETERR_CLOSE_PROT;
   } 

   /*
   ** Create an entry for this group
   */
   mcb_ptr = _mem_alloc_system_zero(sizeof(ENET_MCB_STRUCT));
   if (!mcb_ptr) {
      ENET_unlock_context(enet_ptr);
      return ENETERR_ALLOC_MCB;
   } /* Endif */
   _mem_set_type(mcb_ptr, MEM_TYPE_IO_ENET_MCB);
   
   eaddrcpy(mcb_ptr->GROUP,address);

   mcb_ptr->NEXT = ecb_ptr->MCB_HEAD;
   ecb_ptr->MCB_HEAD = mcb_ptr;

#if BSPCFG_ENABLE_ENET_MULTICAST
   #ifdef ENET_ALLMCAST
      needjoin = enet_ptr->MCOUNT < ENET_ALLMCAST;
      enet_ptr->MCOUNT++;
      if (needjoin) {
   #endif
   
         (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->JOIN)(handle, mcb_ptr);
   
   #ifdef ENET_ALLMCAST
      } 
   #endif
#endif

   ENET_unlock_context(enet_ptr);

   return ENET_OK;

} 

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/btnled.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: btnled.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the implementation of HMI client for buttons and LEDs.
*
*END************************************************************************/
#include "btnled.h"
#include "hmi_client.h"

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_poll
* Returned Value   : void
* Comments         :
*   This function calls poll function of all added providers.
*
*END*--------------------------------------------------------------------*/
void btnled_poll(HMI_CLIENT_STRUCT_PTR handle)
{
    uint_32 i;

    if(handle == NULL)
    {
        return;
    }
    for(i=0; i<handle->MAX_PROVIDER_COUNT; i++)
    {
        if((handle->PROVIDER_TABLE[i] != NULL) && (handle->PROVIDER_TABLE[i]->POLL_PTR != NULL))
        {
            handle->PROVIDER_TABLE[i]->POLL_PTR(handle->PROVIDER_TABLE[i]);
        }
    }
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_get_value
* Returned Value   : TRUE if UID exist, else FALSE
* Comments         :
*   This function calls get function of all added provider.
*
*END*--------------------------------------------------------------------*/
boolean btnled_get_value(HMI_CLIENT_STRUCT_PTR handle, uint_32 uid, uint_32_ptr value)
{
    uint_32 i;
    boolean result = FALSE;

    if(handle == NULL)
    {
        return FALSE;
    }
    for(i=0; i<handle->MAX_PROVIDER_COUNT; i++)
    {
        if((handle->PROVIDER_TABLE[i] != NULL) && (handle->PROVIDER_TABLE[i]->GET_VALUE_PTR != NULL))
        {
            result |= handle->PROVIDER_TABLE[i]->GET_VALUE_PTR(handle->PROVIDER_TABLE[i], uid, value);
        }
    }
    return result;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_set_value
* Returned Value   : TRUE if UID exist, else FALSE
* Comments         :
*   This function calls set function of all added provider.
*
*END*--------------------------------------------------------------------*/
boolean btnled_set_value(HMI_CLIENT_STRUCT_PTR handle, uint_32 uid, uint_32 value)
{
    uint_32 i;
    boolean result = FALSE;

    if(handle == NULL)
    {
        return FALSE;
    }
    for(i=0; i<handle->MAX_PROVIDER_COUNT; i++)
    {
        if((handle->PROVIDER_TABLE[i] != NULL) && (handle->PROVIDER_TABLE[i]->SET_VALUE_PTR != NULL))
        {
            result |= handle->PROVIDER_TABLE[i]->SET_VALUE_PTR(handle->PROVIDER_TABLE[i], uid, value);
        }
    }
    return result;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_toogle
* Returned Value   : TRUE if UID exist, else FALSE
* Comments         :
*   This function is for toogling a value of UID.
*
*END*--------------------------------------------------------------------*/
boolean btnled_toogle(HMI_CLIENT_STRUCT_PTR handle, uint_32 uid)
{
    uint_32 value;
    boolean result = FALSE;

    result = btnled_get_value(handle, uid, &value);
    result = btnled_set_value(handle, uid, !value);
    return result;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_add_clb
* Returned Value   : BTNLED_CLBREG_STRUCT_PTR
* Comments         :
*   This function is for callback registration.
*
*END*--------------------------------------------------------------------*/
BTNLED_CLBREG_STRUCT_PTR btnled_add_clb(HMI_CLIENT_STRUCT_PTR handle, uint_32 uid, uint_32 state, void (_CODE_PTR_ function)(pointer), pointer callback_parameter)
{
    BTNLED_CONTEXT_STRUCT_PTR   context;
    BTNLED_CLBREG_STRUCT_PTR    clbreg_struct;
    BTNLED_CLBREG_STRUCT_PTR    new_clbreg_struct;

    if(handle == NULL)
    {
        return NULL;
    }
    /* allocate btnled_clb_structure */
    new_clbreg_struct = _mem_alloc_system_zero(sizeof(BTNLED_CLBREG_STRUCT));
    if(new_clbreg_struct == NULL)
    {
        return NULL;
    }
    /* fill new new_clbreg_structure */
    new_clbreg_struct->STATE = state;
    new_clbreg_struct->UID = uid;
    new_clbreg_struct->CALLBACK_PARAMETER = callback_parameter;
    new_clbreg_struct->CLBFUNCTION = function;
    new_clbreg_struct->NEXT_CALLBACK = NULL;

    /* find last callback */
    context = (BTNLED_CONTEXT_STRUCT_PTR) handle->CONTEXT_PTR;
    /* wait semaphore */
    _lwsem_wait(&context->LOCK_BTNLED_SEM);
    clbreg_struct = context->CLBREG;
    if(clbreg_struct == NULL)
    {
        context->CLBREG = new_clbreg_struct;
    }
    else
    {
        while(clbreg_struct->NEXT_CALLBACK!=NULL)
        {
            clbreg_struct = clbreg_struct->NEXT_CALLBACK;
        }
        clbreg_struct->NEXT_CALLBACK = new_clbreg_struct;
    }
    /* post semaphore */
    _lwsem_post(&context->LOCK_BTNLED_SEM);
    return new_clbreg_struct;
}
/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_remove_clb
* Returned Value   : TRUE if removed, FALSE otherwise.
* Comments         :
*   This function is for callback unregistration.
*
*END*--------------------------------------------------------------------*/
boolean btnled_remove_clb(HMI_CLIENT_STRUCT_PTR handle, BTNLED_CLBREG_STRUCT_PTR comp_clbreg)
{
    BTNLED_CONTEXT_STRUCT_PTR   context;
    BTNLED_CLBREG_STRUCT_PTR    step_clbreg;
    BTNLED_CLBREG_STRUCT_PTR    tmp_clbreg;

    if((handle == NULL) || (comp_clbreg == NULL))
    {
        return FALSE;
    }
    context = (BTNLED_CONTEXT_STRUCT_PTR)handle->CONTEXT_PTR;
    /* wait semaphore */
    _lwsem_wait(&context->LOCK_BTNLED_SEM);
    step_clbreg = context->CLBREG;
    if(step_clbreg == NULL)
    {
        /* post semaphore */
        _lwsem_post(&context->LOCK_BTNLED_SEM);
        return FALSE;
    }
    /* only one clbreg_struct is in a queue */
    if(step_clbreg == comp_clbreg)    
    {
        context->CLBREG = step_clbreg->NEXT_CALLBACK;
        if(_mem_free(step_clbreg) != MQX_OK)
        {
            _lwsem_post(&context->LOCK_BTNLED_SEM);
            return FALSE;
        }
        _lwsem_post(&context->LOCK_BTNLED_SEM);
        return TRUE;
    }
    /* more than one clbreg_struct is in a queue */
    while(step_clbreg->NEXT_CALLBACK!=NULL)    
    {
        if(step_clbreg->NEXT_CALLBACK == comp_clbreg)
        {
            tmp_clbreg = step_clbreg->NEXT_CALLBACK;
            step_clbreg->NEXT_CALLBACK = step_clbreg->NEXT_CALLBACK->NEXT_CALLBACK;
            if(_mem_free(tmp_clbreg)!=MQX_OK)
            {
                _lwsem_post(&context->LOCK_BTNLED_SEM);
                return FALSE;
            }
            _lwsem_post(&context->LOCK_BTNLED_SEM);
            return TRUE;
        }
        step_clbreg = step_clbreg->NEXT_CALLBACK;
    }
    _lwsem_post(&context->LOCK_BTNLED_SEM);
    return FALSE;
}
/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_on_change
* Returned Value   : void
* Comments         :
*   This function is for callback processing.
*
*END*--------------------------------------------------------------------*/
static void btnled_on_change(HMI_CLIENT_STRUCT_PTR client, uint_32 uid, uint_32 state)
{
    BTNLED_CONTEXT_STRUCT_PTR   context;
    BTNLED_CLBREG_STRUCT_PTR    clbreg;


    if(client == NULL)
    {
        return;
    }
    /* gets a context from a client */
    context = (BTNLED_CONTEXT_STRUCT_PTR) client->CONTEXT_PTR;

    clbreg = context->CLBREG;
    if(clbreg == NULL)
    {
        return;
    }

    do
    {
        /* UID and STATE must match */
        if((clbreg->UID == uid) && (clbreg->STATE == state) && (clbreg->CLBFUNCTION != NULL))
        {
            clbreg->CLBFUNCTION(clbreg->CALLBACK_PARAMETER);  /* calls callback */
        }
        clbreg = clbreg->NEXT_CALLBACK;
    }while(clbreg != NULL);
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_init
* Returned Value   : client struct HMI_CLIENT_STRUCT_PTR
* Comments         :
*   This function is for HMI BTNLED client initialization.
*
*END*--------------------------------------------------------------------*/
HMI_CLIENT_STRUCT_PTR btnled_init(void)
{
    HMI_CLIENT_STRUCT_PTR       btnled_struct;
    HMI_PROVIDER_STRUCT_PTR     provider_table;
    BTNLED_CONTEXT_STRUCT_PTR   context;

    /* allocate btnled structure */
    btnled_struct = hmi_client_init();
    provider_table = (pointer)btnled_struct->PROVIDER_TABLE;
    /* allocate context data */
    context = _mem_alloc_system_zero(sizeof(BTNLED_CONTEXT_STRUCT));
    if(context == NULL)
    {
        _mem_free(provider_table);
        _mem_free(btnled_struct);
        return NULL;
    }
    /* create a semaphore for callbacks */
    _lwsem_create(&context->LOCK_BTNLED_SEM, 1);
    btnled_struct->CONTEXT_PTR = context;
    btnled_struct->ON_CHANGE = (void ( _CODE_PTR_)(pointer, uint_32, uint_32))btnled_on_change;
    return btnled_struct;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : btnled_deinit
* Returned Value   : MQX_OK or an error code
* Comments         :
*   This function deallocates used memory.
*
*END*--------------------------------------------------------------------*/
uint_32 btnled_deinit(HMI_CLIENT_STRUCT_PTR handle)
{
    BTNLED_CONTEXT_STRUCT_PTR   context;
    uint_32                     result = MQX_OK;

    /* destroy callbacks and a semaphore */
    context = (BTNLED_CONTEXT_STRUCT_PTR) (handle)->CONTEXT_PTR;

    if(context->CLBREG != NULL)
    {
        do
        {
            btnled_remove_clb(handle, context->CLBREG);
        }
        while(context->CLBREG->NEXT_CALLBACK != NULL);
    }

    _lwsem_destroy(&context->LOCK_BTNLED_SEM);

    result =_mem_free(handle->PROVIDER_TABLE);
    if(result != MQX_OK)
    {
        return result;
    }
    result =_mem_free((handle)->CONTEXT_PTR);
    if(result != MQX_OK)
    {
        return result;
    }
    handle = NULL;
    return result;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/phy/phy_ksz8041.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: phy_ksz8041.c$
* $Version : 3.8.8.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*  This file contains definitions that belongs to the ksz8041 PHY chip
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"
#include "enet.h"
#include "enetprv.h"
#include "phy_ksz8041.h"

static boolean phy_ksz8041_discover_addr(ENET_CONTEXT_STRUCT_PTR enet_ptr);
static boolean phy_ksz8041_init(ENET_CONTEXT_STRUCT_PTR enet_ptr);
static uint_32 phy_ksz8041_get_speed(ENET_CONTEXT_STRUCT_PTR enet_ptr);
static boolean phy_ksz8041_get_link_status(ENET_CONTEXT_STRUCT_PTR enet_ptr);

const ENET_PHY_IF_STRUCT phy_ksz8041_IF = {
  phy_ksz8041_discover_addr,
  phy_ksz8041_init,
  phy_ksz8041_get_speed,
  phy_ksz8041_get_link_status
};
  
  

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : phy_ksz8041_discover_addr
*  Returned Value : none
*  Comments       :
*    Scan possible PHY addresses looking for a valid device
*
*END*-----------------------------------------------------------------*/

static boolean phy_ksz8041_discover_addr
   (
       ENET_CONTEXT_STRUCT_PTR     enet_ptr
   )
{ 
   uint_32              i;
   uint_32              id;

   for (i = 0; i < 32; i++) {
      id = 0;
      enet_ptr->PHY_ADDRESS = i;
      if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, PHY_MII_REG_PHYIR1, &id, MII_TIMEOUT)) 
      {
          if ((id != 0) && (id != 0xffff)) 
          {
                return TRUE;
          }
      } 
   } 
   
   return FALSE; 
} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : phy_ksz8041_init
*  Returned Value : boolean
*  Comments       :
*    Wait for PHY to automatically negotiate its configuration
*
*END*-----------------------------------------------------------------*/

static boolean phy_ksz8041_init
   (
       ENET_CONTEXT_STRUCT_PTR     enet_ptr
   )
{ 
   uint_32              phy_status=0;

   if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PHY_LOOPBACK) {
      if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, PHY_MII_REG_CR, &phy_status, MII_TIMEOUT)) {
         phy_status |= PHY_MII_REG_CR_LOOP;
         (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_WRITE)(enet_ptr, PHY_MII_REG_CR, phy_status, MII_TIMEOUT);
         return TRUE;
      }
   } else {
      if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, PHY_MII_REG_SR, &phy_status, MII_TIMEOUT)) {
         if (phy_status & PHY_MII_REG_SR_AN_ABLE) { 
            // Has auto-negotiate ability
            int i;
            for (i = 0; i < 3 * BSP_ALARM_FREQUENCY; i++) {
               if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, PHY_MII_REG_SR, &phy_status, MII_TIMEOUT)) 
                  if ((phy_status & PHY_MII_REG_SR_AN_COMPLETE) != 0) 
                     return TRUE;
               _time_delay(BSP_ALARM_RESOLUTION);
            }  
         }
         return TRUE;
      }  
   }  
   return FALSE;
}  


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : phy_ksz8041_get_speed
*  Returned Value : uint_32 - connection speed
*  Comments       :
*    Determine if connection speed is 10 or 100 Mbit
*
*END*-----------------------------------------------------------------*/

static uint_32 phy_ksz8041_get_speed
   (
       ENET_CONTEXT_STRUCT_PTR     enet_ptr
   )
{ 
   uint_32 speed_status;

   if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, PHY_MII_REG_PHYC2, &speed_status, MII_TIMEOUT)) {
      speed_status &= PHY_MII_REG_PHYC2_OP_MODE_MASK;
  
      if ((PHY_MII_REG_PHYC2_OP_MODE_10_HD==speed_status) || (PHY_MII_REG_PHYC2_OP_MODE_10_FD==speed_status)) {
         return 10;
      } else if ((PHY_MII_REG_PHYC2_OP_MODE_100_HD==speed_status) || (PHY_MII_REG_PHYC2_OP_MODE_100_FD==speed_status)) {
         return 100;
      }
   }
   return 0;
} 

  
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : phy_ksz8041_get_link_status
*  Returned Value : TRUE if link active, FALSE otherwise
*  Comments       : 
*    Get actual link status.
*
*END*-----------------------------------------------------------------*/

static boolean phy_ksz8041_get_link_status
   (
       ENET_CONTEXT_STRUCT_PTR     enet_ptr
   )
{ 
   uint_32 data;
   boolean res = FALSE;
   
   if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, PHY_MII_REG_CR, &data, MII_TIMEOUT))
   {
       /* After power up, when PHY does not fully initial PHY_MII_REG_SR_LINK_STATUS bit 
        * is '1'. So if we get link status in this case, the return result is always "Connected" 
        * even when we haven't plug the cable in yet. 
        * Check if PHY in normal operation -> ready to get link status */
       if ((data & PHY_MII_REG_CR_RESET) == 0 )
       {
           /* Some PHY (e.g.DP8340) returns "unconnected" and than "connected" state
           *  just to show that was transition event from one state to another.
           *  As we need only curent state,  read 2 times and return 
           *  the current/latest state. */
           if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, PHY_MII_REG_SR, &data, MII_TIMEOUT)) {
              if ((*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->PHY_READ)(enet_ptr, PHY_MII_REG_SR, &data, MII_TIMEOUT))
              {
                 res = ((data & PHY_MII_REG_SR_LINK_STATUS) != 0) ? TRUE : FALSE;
              }
           }
       }
   }

  return res;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/polled/serl_pol_kuart.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_pol_kuart.c$
* $Version : 3.8.13.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the functions for the polled serial I/O
*   low level functions for the MCF51XX SCI.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "io_prv.h"
#include "charq.h"
#include "fio_prv.h"
#include "serplprv.h"


/* Polled driver functions */
extern char    _kuart_polled_getc(KUART_INFO_STRUCT_PTR);
extern void    _kuart_polled_putc(KUART_INFO_STRUCT_PTR, char);
extern boolean _kuart_polled_status(KUART_INFO_STRUCT_PTR);
extern uint_32 _kuart_polled_ioctl(KUART_INFO_STRUCT_PTR, uint_32, uint_32_ptr);
extern uint_32 _kuart_polled_init(KUART_INIT_STRUCT_PTR, pointer _PTR_, char _PTR_);
extern uint_32 _kuart_polled_deinit(KUART_INIT_STRUCT_PTR, KUART_INFO_STRUCT_PTR);
extern uint_32 _kuart_change_baudrate(UART_MemMapPtr, uint_32, uint_32);


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_change_baudrate
* Returned Value   : MQX error code
* Comments         :
*    Calculates and sets new baudrate dividers for given SCI channel.
*
*END*----------------------------------------------------------------------*/

uint_32 _kuart_change_baudrate
    (
        /* [IN] SCI channel registers */
        UART_MemMapPtr sci_ptr,

        /* [IN] SCI input clock frequency */
        uint_32        clock_frequency,

        /* [IN] Requested baud rate */
        uint_32        baud_rate
    )
{
    uint_32            baud_divisor = 0, brfa = 0;

    if ((clock_frequency > 0) && (baud_rate > 0))
    {
        baud_divisor = clock_frequency / (baud_rate << 4);
        if (baud_divisor > 0)
        {
            brfa = ((((clock_frequency - baud_rate*(baud_divisor << 4)) << 1) + (baud_rate >> 1)) / baud_rate);
            if (brfa >= 32) {
                baud_divisor += 1;
                brfa = 0;
            }
        }
        if (baud_divisor > ((UART_BDH_SBR_MASK << 8) | UART_BDL_SBR_MASK))
        {
            return MQX_INVALID_CONFIGURATION;
        }
    }
    sci_ptr->BDH = (uchar)((baud_divisor >> 8) & UART_BDH_SBR_MASK);
    sci_ptr->BDL = (uchar)(baud_divisor & UART_BDL_SBR_MASK);
    sci_ptr->C4 &= (~ UART_C4_BRFA_MASK);
    sci_ptr->C4 |= UART_C4_BRFA(brfa);
    return MQX_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_polled_peripheral_enable
* Returned Value   : None
* Comments         :
*    Enables the SCI peripheral.
*
*END*----------------------------------------------------------------------*/

static void _kuart_polled_peripheral_enable
    (
        /* [IN] SCI channel registers */
        UART_MemMapPtr sci_ptr
    )
{
    /* Transmitter and receiver enable */
    sci_ptr->C2 |= UART_C2_RE_MASK | UART_C2_TE_MASK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_polled_peripheral_disable
* Returned Value   : None
* Comments         :
*    Disables the SCI peripheral.
*
*END*----------------------------------------------------------------------*/

static void _kuart_polled_peripheral_disable
    (
        /* [IN] SCI channel registers */
        UART_MemMapPtr sci_ptr
    )
{
    /* Transmitter and receiver disable */
    sci_ptr->C2 &= (~ (UART_C2_RE_MASK | UART_C2_TE_MASK));
}


#if MQX_ENABLE_LOW_POWER

extern LPM_NOTIFICATION_RESULT _io_serial_polled_clock_configuration_callback (LPM_NOTIFICATION_STRUCT_PTR, pointer);
extern LPM_NOTIFICATION_RESULT _io_serial_polled_operation_mode_callback (LPM_NOTIFICATION_STRUCT_PTR, pointer);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_serial_polled_clock_configuration_callback
* Returned Value   : Notification error code
* Comments         :
*    Low power clock configuration callback for polled serial.
*
*END*----------------------------------------------------------------------*/

LPM_NOTIFICATION_RESULT _io_serial_polled_clock_configuration_callback
    (
        /* [IN] Low power notification */
        LPM_NOTIFICATION_STRUCT_PTR      notification,

        /* [IN/OUT] Device specific data */
        pointer                          device_specific_data
    )
{
    IO_SERIAL_POLLED_DEVICE_STRUCT_PTR dev_ptr = device_specific_data;
    KUART_INIT_STRUCT_PTR              init_data = dev_ptr->DEV_INIT_DATA_PTR;
    uint_8                             flags;

    /* Get the device registers */
    UART_MemMapPtr sci_ptr = _bsp_get_serial_base_address (init_data->DEVICE);
    if (NULL == sci_ptr)
    {
        return LPM_NOTIFICATION_RESULT_ERROR;
    }

    if (LPM_NOTIFICATION_TYPE_PRE == notification->NOTIFICATION_TYPE)
    {
        /* Lock access from the higher level */
        _lwsem_wait (&(dev_ptr->LPM_INFO.LOCK));

        /* Enable module clocks to be able to write registers */
        _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_ENABLE);

        /* Flush output if enabled */
        if (sci_ptr->C2 & UART_C2_TE_MASK)
        {
            while (! (sci_ptr->SFIFO & UART_SFIFO_TXEMPT_MASK))
                { };
            while (! (sci_ptr->S1 & UART_S1_TC_MASK))
                { };
        }

        /* Turn off module */
        _kuart_polled_peripheral_disable (sci_ptr);
    }

    if (LPM_NOTIFICATION_TYPE_POST == notification->NOTIFICATION_TYPE)
    {
        /* Enable module clocks to be able to write registers */
        _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_ENABLE);

        /* Setup same baudrate for new clock frequency */
        _kuart_change_baudrate (sci_ptr, _cm_get_clock (notification->CLOCK_CONFIGURATION, init_data->CLOCK_SOURCE), init_data->BAUD_RATE);

        /* Turn on module if requested */
        flags = init_data->OPERATION_MODE[notification->OPERATION_MODE].FLAGS;
        if ((flags & IO_PERIPHERAL_MODULE_ENABLE)
          && (dev_ptr->COUNT > 0))
        {
            _kuart_polled_peripheral_enable (sci_ptr);
        }

        /* Disable module clocks if required */
        if (flags & IO_PERIPHERAL_CLOCK_DISABLE)
        {
            _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_DISABLE);
        }

        /* Unlock */
        _lwsem_post (&(dev_ptr->LPM_INFO.LOCK));
    }
    return LPM_NOTIFICATION_RESULT_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_serial_polled_operation_mode_callback
* Returned Value   : Notification error code
* Comments         :
*    Low power operation mode callback for polled serial.
*
*END*----------------------------------------------------------------------*/

LPM_NOTIFICATION_RESULT _io_serial_polled_operation_mode_callback
    (
        /* [IN] Low power notification */
        LPM_NOTIFICATION_STRUCT_PTR       notification,

        /* [IN/OUT] Device specific data */
        pointer                           device_specific_data
    )
{
    IO_SERIAL_POLLED_DEVICE_STRUCT_PTR  dev_ptr = device_specific_data;
    KUART_INIT_STRUCT_PTR               init_data = dev_ptr->DEV_INIT_DATA_PTR;
    uint_8                              flags, tmp, bits;

    if (LPM_NOTIFICATION_TYPE_PRE == notification->NOTIFICATION_TYPE)
    {
        /* Get the device registers */
        UART_MemMapPtr sci_ptr = _bsp_get_serial_base_address (init_data->DEVICE);
        if (NULL == sci_ptr)
        {
            return LPM_NOTIFICATION_RESULT_ERROR;
        }

        /* Lock access from the higher level */
        _lwsem_wait (&(dev_ptr->LPM_INFO.LOCK));

        /* Get required HW changes */
        flags = init_data->OPERATION_MODE[notification->OPERATION_MODE].FLAGS;

        /* Setup module clock to be able to write registers */
        _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_ENABLE);

        /* Flush output if enabled */
        if (sci_ptr->C2 & UART_C2_TE_MASK)
        {
            while (! (sci_ptr->SFIFO & UART_SFIFO_TXEMPT_MASK))
                { };
            while (! (sci_ptr->S1 & UART_S1_TC_MASK))
                { };
        }

        /* Setup pin mux */
        _bsp_serial_io_init (init_data->DEVICE, flags & (~ IO_PERIPHERAL_CLOCK_DISABLE));

        /* Setup wakeup */
        if (flags & IO_PERIPHERAL_WAKEUP_ENABLE)
        {
            bits = init_data->OPERATION_MODE[notification->OPERATION_MODE].WAKEUP_BITS;
            tmp = sci_ptr->C1 & (~ (UART_C1_WAKE_MASK | UART_C1_ILT_MASK));
            sci_ptr->C1 = tmp | (bits & (UART_C1_WAKE_MASK | UART_C1_ILT_MASK));
            tmp = sci_ptr->C4 & (~ (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
            sci_ptr->C4 = tmp | (bits & (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
            sci_ptr->MA1 = init_data->OPERATION_MODE[notification->OPERATION_MODE].MA1;
            sci_ptr->MA2 = init_data->OPERATION_MODE[notification->OPERATION_MODE].MA2;
            tmp = sci_ptr->C2 & (~ (UART_C2_RWU_MASK));
            sci_ptr->C2 = tmp | (bits & UART_C2_RWU_MASK);
        }
        else
        {
            sci_ptr->C2 &= (~ (UART_C2_RWU_MASK));
            sci_ptr->C1 &= (~ (UART_C1_WAKE_MASK | UART_C1_ILT_MASK));
            sci_ptr->C4 &= (~ (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
            sci_ptr->MA1 = 0;
            sci_ptr->MA2 = 0;
        }

        /* Enable/disable module according to both clock configuration and operation mode */
        if ((flags & IO_PERIPHERAL_MODULE_ENABLE) && (dev_ptr->COUNT > 0))
        {
            _kuart_polled_peripheral_enable (sci_ptr);
        }
        else
        {
            _kuart_polled_peripheral_disable (sci_ptr);
        }

        /* Disable module clocks if required */
        if (flags & IO_PERIPHERAL_CLOCK_DISABLE)
        {
            _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_DISABLE);
        }

        /* Unlock */
        _lwsem_post (&(dev_ptr->LPM_INFO.LOCK));
    }
    return LPM_NOTIFICATION_RESULT_OK;
}

#endif


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_polled_install
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    Install a polled sci device.
*
*END*----------------------------------------------------------------------*/

uint_32 _kuart_polled_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr           identifier,

      /* [IN] The I/O init data pointer */
      KUART_INIT_STRUCT_CPTR            init_data_ptr,

      /* [IN] The I/O queue size to use */
      uint_32            queue_size
   )
{ /* Body */

#if PE_LDD_VERSION
    if (PE_PeripheralUsed((uint_32)_bsp_get_serial_base_address(init_data_ptr->DEVICE)))
    {
        return IO_ERROR;
    }
#endif

    return _io_serial_polled_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, pointer _PTR_, char _PTR_))_kuart_polled_init,
      (uint_32 (_CODE_PTR_)(pointer, pointer))_kuart_polled_deinit,
      (char    (_CODE_PTR_)(pointer))_kuart_polled_getc,
      (void    (_CODE_PTR_)(pointer, char))_kuart_polled_putc,
      (boolean (_CODE_PTR_)(pointer))_kuart_polled_status,
      (uint_32 (_CODE_PTR_)(pointer, uint_32, pointer))_kuart_polled_ioctl,
      (pointer)init_data_ptr, queue_size);

} /* Endbody */



/*FUNCTION****************************************************************
*
* Function Name    : _kuart_polled_init
* Returned Value   : MQX_OK or a MQX error code.
* Comments         :
*    This function initializes the SCI
*
*END*********************************************************************/

uint_32 _kuart_polled_init
   (
      /* [IN] the initialization information for the device being opened */
      KUART_INIT_STRUCT_PTR               io_init_ptr,

      /* [OUT] the address to store device specific information */
      pointer _PTR_                       io_info_ptr_ptr,

      /* [IN] the rest of the name of the device opened */
      char _PTR_                          open_name_ptr
   )
{ /* Body */
   UART_MemMapPtr                       sci_ptr;
   KUART_INFO_STRUCT_PTR                sci_info_ptr;
   uint_32                              channel, clock, mode;
   uint_8                               flags;

   /* Get peripheral address */
   channel = io_init_ptr->DEVICE;

   sci_ptr = _bsp_get_serial_base_address(channel);
   if (sci_ptr == NULL)
   {
      return MQX_INVALID_IO_CHANNEL;
   }

   sci_info_ptr = _mem_alloc_system_zero((uint_32)sizeof(KUART_INFO_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if ( sci_info_ptr == NULL )
   {
      return MQX_OUT_OF_MEMORY;
   }
#endif

   *io_info_ptr_ptr = sci_info_ptr;

   sci_info_ptr->SCI_PTR = sci_ptr;

   /* Save initialization values */
   sci_info_ptr->INIT = *io_init_ptr;
   
   sci_info_ptr->FLAGS = IO_SERIAL_STOP_BITS_1;

   /* Setup HW according to low power mode, if enabled */
   clock = sci_info_ptr->INIT.CLOCK_SPEED;
   flags = IO_PERIPHERAL_PIN_MUX_ENABLE | IO_PERIPHERAL_CLOCK_ENABLE | IO_PERIPHERAL_MODULE_ENABLE;

#if MQX_ENABLE_LOW_POWER

   mode = _lpm_get_operation_mode ();
   if (mode >= LPM_OPERATION_MODES)
   {
      return MQX_INVALID_CONFIGURATION;
   }
   flags = io_init_ptr->OPERATION_MODE[mode].FLAGS;

   clock = _lpm_get_clock_configuration ();
   if (clock >= BSP_CLOCK_CONFIGURATIONS)
   {
      return MQX_INVALID_CONFIGURATION;
   }


   clock = _cm_get_clock ((BSP_CLOCK_CONFIGURATION)clock, io_init_ptr->CLOCK_SOURCE);

#endif

   /* Enable HW */
   _bsp_serial_io_init (channel, flags);

   /* Enable module clocks to be able to write registers */
   _bsp_serial_io_init (channel, IO_PERIPHERAL_CLOCK_ENABLE);

   /* Setup baudrate */
   _kuart_change_baudrate (sci_ptr, clock, sci_info_ptr->INIT.BAUD_RATE);

   /* 8-bit mode. Normal operation */
   sci_ptr->C1 = 0;

   /* Disable wakeups */
   sci_ptr->C2 &= (~ (UART_C2_RWU_MASK));
   sci_ptr->C4 &= (~ (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
   sci_ptr->MA1 = 0;
   sci_ptr->MA2 = 0;

   /* Disable all error interrupts */
   sci_ptr->C3 = 0;

   /* Set watermark in the almost full TX buffer */
   if (((sci_ptr->PFIFO & UART_PFIFO_TXFIFOSIZE_MASK) >> UART_PFIFO_TXFIFOSIZE_SHIFT) == 0)
   {
      /* 1 dataword in D */
      sci_ptr->TWFIFO = UART_TWFIFO_TXWATER(0);
   }
   else
   {
      uint_8 txsize = 1 << (((sci_ptr->PFIFO & UART_PFIFO_TXFIFOSIZE_MASK) >> UART_PFIFO_TXFIFOSIZE_SHIFT) + 1);

      /* Watermark for TX buffer generates interrupts below & equal to watermark */
      sci_ptr->TWFIFO = UART_TWFIFO_TXWATER(txsize - 1);
   }

   /* Watermark for RX buffer generates interrupts above & equal to watermark */
   sci_ptr->RWFIFO = UART_RWFIFO_RXWATER(1);

   /* both RE,TE must be disabled before enable FIFO */
   sci_ptr->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);

   /* Enable TX FIFO, enable RX FIFO */
   sci_ptr->PFIFO |= UART_PFIFO_TXFE_MASK | UART_PFIFO_RXFE_MASK;

   /* Flush RX / TX buffers */
   sci_ptr->CFIFO |= UART_CFIFO_RXFLUSH_MASK | UART_CFIFO_TXFLUSH_MASK;

   /* Module enable/disable */
   if (flags & IO_PERIPHERAL_MODULE_ENABLE)
   {
       _kuart_polled_peripheral_enable (sci_ptr);
   }
   else
   {
       _kuart_polled_peripheral_disable (sci_ptr);
   }

   /* Disable module clocks if required */
   if (flags & IO_PERIPHERAL_CLOCK_DISABLE)
   {
       _bsp_serial_io_init (channel, IO_PERIPHERAL_CLOCK_DISABLE);
   }

   return MQX_OK;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_polled_deinit
* Returned Value   : MQX_OK or a mqx error code.
* Comments         :
*    This function de-initializes the SCI.
*
*END*********************************************************************/

uint_32 _kuart_polled_deinit
   (
      /* [IN] the initialization information for the device being opened */
      KUART_INIT_STRUCT_PTR io_init_ptr,

      /* [IN] the address of the device specific information */
      KUART_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   uint_8 flags = IO_PERIPHERAL_CLOCK_ENABLE;

#if MQX_ENABLE_LOW_POWER

   uint_32 mode = _lpm_get_operation_mode ();
   if (mode >= LPM_OPERATION_MODES)
   {
      return MQX_INVALID_CONFIGURATION;
   }
   flags = io_info_ptr->INIT.OPERATION_MODE[mode].FLAGS;

#endif

   /* Enable module clocks to be able to write registers */
   _bsp_serial_io_init (io_init_ptr->DEVICE, IO_PERIPHERAL_CLOCK_ENABLE);

   /* Disable interrupts, transmitter, receiver */
   io_info_ptr->SCI_PTR->C2 = 0;

   /* Disable module clocks if required */
   if (flags & IO_PERIPHERAL_CLOCK_DISABLE)
   {
       _bsp_serial_io_init (io_init_ptr->DEVICE, IO_PERIPHERAL_CLOCK_DISABLE);
   }

   _mem_free(io_info_ptr);

   return(MQX_OK);
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_polled_getc
* Returned Value   : char
* Comments         :
*   Return a character when it is available.  This function polls the
* device for input.
*
*************************************************************************/

char _kuart_polled_getc
   (
      /* [IN] the address of the device specific information */
      KUART_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
    UART_MemMapPtr sci_ptr = io_info_ptr->SCI_PTR;

   /* Wait while buffer is empty */
   while (!(sci_ptr->S1 & UART_S1_RDRF_MASK)) {
      /* Wait while buffer is empty */
   } /* Endwhile */

   io_info_ptr->RX_CHARS++;

   return sci_ptr->D;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_polled_putc
* Returned Value   : void
* Comments         :
*   Writes the provided character.
*
*END*********************************************************************/

void _kuart_polled_putc
   (
      /* [IN] the address of the device specific information */
      KUART_INFO_STRUCT_PTR io_info_ptr,

      /* [IN] the character to write */
      char                               c
   )
{
   UART_MemMapPtr sci_ptr = io_info_ptr->SCI_PTR;
   
   while (!(sci_ptr->S1 & UART_S1_TDRE_MASK)) {
      /* Wait while buffer is full */
   } /* Endwhile */
   
   sci_ptr->D = c;

   io_info_ptr->TX_CHARS++;
}


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_polled_status
* Returned Value   : boolean
* Comments         :
*            This function returns TRUE if a character is available
*            on the on I/O device, otherwise it returns FALSE.
*
*END*********************************************************************/

boolean _kuart_polled_status
   (
      /* [IN] the address of the device specific information */
      KUART_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   KUART_INFO_STRUCT_PTR      sci_info_ptr = io_info_ptr;
   UART_MemMapPtr             sci_ptr = io_info_ptr->SCI_PTR;
   uint_16                    stat = sci_ptr->S1;

   if(stat & UART_S1_OR_MASK) {
      ++sci_info_ptr->RX_OVERRUNS;
   }
   if(stat & UART_S1_PF_MASK) {
      ++sci_info_ptr->RX_PARITY_ERRORS;
   }
   if(stat & UART_S1_NF_MASK) {
      ++sci_info_ptr->RX_NOISE_ERRORS;
   }
   if(stat & UART_S1_FE_MASK) {
      ++sci_info_ptr->RX_FRAMING_ERRORS;
   }

   /*
   if "framming error" or "overrun" error occours 
   perform 'S1' cleanup. if not, 'S1' cleanup will be 
   performed during regular reading of 'D' register.
   */
   if (stat & (UART_S1_OR_MASK | UART_S1_FE_MASK))
   {
      // reading register 'D' to cleanup 'S1' may cause 'RFIFO' underflow
      sci_ptr->D;
      // if 'RFIFO' underflow detected, perform flush to reinitialize 'RFIFO'
      if (sci_ptr->SFIFO & UART_SFIFO_RXUF_MASK)
      {
         sci_ptr->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
         sci_ptr->SFIFO |= UART_SFIFO_RXUF_MASK;
      }
      // set errno. some data may be still in 'RFIFO' so continue
      // TODO: add valid errno. IO_ERROR causes signed/unsigned assignment warning
      // _task_set_error(IO_ERROR);
   }

   if( (sci_ptr->SFIFO & UART_SFIFO_RXEMPT_MASK) == 0 )
        return TRUE;
   else
        return FALSE;
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_polled_ioctl
* Returned Value   : uint_32 MQX_OK or a mqx error code.
* Comments         :
*    This function performs miscellaneous services for
*    the I/O device.
*
*END*********************************************************************/

uint_32 _kuart_polled_ioctl
   (
      /* [IN] the address of the device specific information */
      KUART_INFO_STRUCT_PTR io_info_ptr,

      /* [IN] The command to perform */
      uint_32                    cmd,

      /* [IN] Parameters for the command */
      uint_32_ptr                param_ptr
   )
{ /* Body */
   UART_MemMapPtr sci_ptr = io_info_ptr->SCI_PTR;
   uint_32                  baud, tmp;

   switch (cmd) {
      case IO_IOCTL_SERIAL_GET_DATA_BITS:
         tmp = 8;
         /* if 9bit mode */
         if (sci_ptr->C1 & UART_C1_M_MASK)
         {
            /* and bit8 not used as second stop bit */
            if (IO_SERIAL_STOP_BITS_1 == (io_info_ptr->FLAGS & IO_SERIAL_STOP_BITS_1))
            {
               /* and bit8 not used as parity */
               if ((0 == (sci_ptr->C1 & UART_C1_PE_MASK)) || (sci_ptr->C4 & UART_C4_M10_MASK))
               {
                  tmp++;
               }
            }
         }
         *param_ptr = tmp;
         break;

      case IO_IOCTL_SERIAL_SET_DATA_BITS:
         if ((8 != (*param_ptr)) && (9 != (*param_ptr)))
         {
            return MQX_INVALID_PARAMETER;
         }
         if (8 == (*param_ptr))
         {
            /* 2 stop bits means already in 8bit mode */
            if (IO_SERIAL_STOP_BITS_1 == (io_info_ptr->FLAGS & IO_SERIAL_STOP_BITS_1))
            {
               /* disable 10th bit */
               sci_ptr->C4 &= (~ UART_C4_M10_MASK);
               
               /* if parity, enable 9th bit, else disable 9th bit */
               if (sci_ptr->C1 & UART_C1_PE_MASK)
               {
                  sci_ptr->C1 |= UART_C1_M_MASK;
               }
               else
               {
                  sci_ptr->C1 &= (~ UART_C1_M_MASK);
               }
            }
         }
         else
         {
            /* 9bit mode is available only when using 1 stop bit */
            if (IO_SERIAL_STOP_BITS_1 == (io_info_ptr->FLAGS & IO_SERIAL_STOP_BITS_1))
            {
               /* enable 9th bit */
               sci_ptr->C1 |= UART_C1_M_MASK;
               
               /* if parity, enable 10th bit, else disable 10th bit */
               if (sci_ptr->C1 & UART_C1_PE_MASK) 
               {
                  sci_ptr->C4 |= UART_C4_M10_MASK;
               }
               else
               {
                  sci_ptr->C4 &= (~ UART_C4_M10_MASK);
               }
            }
            else
            {
               return MQX_INVALID_CONFIGURATION;
            }
         }
         break;

      case IO_IOCTL_SERIAL_GET_BAUD:
         *param_ptr = io_info_ptr->INIT.BAUD_RATE;
         break;

      case IO_IOCTL_SERIAL_SET_BAUD:

#if MQX_ENABLE_LOW_POWER
         tmp = _lpm_get_clock_configuration ();
         if (tmp >= BSP_CLOCK_CONFIGURATIONS)
         {
            return MQX_INVALID_CONFIGURATION;
         }
         tmp = _cm_get_clock ((BSP_CLOCK_CONFIGURATION)tmp, io_info_ptr->INIT.CLOCK_SOURCE);
#else
         tmp = io_info_ptr->INIT.CLOCK_SPEED;
#endif

         tmp = _kuart_change_baudrate (sci_ptr, tmp, *param_ptr);
         if (MQX_OK != tmp)
         {
            return tmp;
         }
         io_info_ptr->INIT.BAUD_RATE = *param_ptr;
         break;

      case IO_IOCTL_SERIAL_GET_STATS:
         *param_ptr++ = io_info_ptr->INTERRUPTS;
         *param_ptr++ = io_info_ptr->RX_CHARS;
         *param_ptr++ = io_info_ptr->TX_CHARS;
         *param_ptr++ = io_info_ptr->RX_BREAKS;
         *param_ptr++ = io_info_ptr->RX_PARITY_ERRORS;
         *param_ptr++ = io_info_ptr->RX_FRAMING_ERRORS;
         *param_ptr++ = io_info_ptr->RX_OVERRUNS;
         *param_ptr++ = io_info_ptr->RX_DROPPED_INPUT;
         break;

      case IO_IOCTL_SERIAL_CLEAR_STATS:
         io_info_ptr->INTERRUPTS = 0;
         io_info_ptr->RX_CHARS = 0;
         io_info_ptr->TX_CHARS = 0;
         io_info_ptr->RX_BREAKS = 0;
         io_info_ptr->RX_PARITY_ERRORS = 0;
         io_info_ptr->RX_FRAMING_ERRORS = 0;
         io_info_ptr->RX_OVERRUNS = 0;
         io_info_ptr->RX_DROPPED_INPUT = 0;
         break;

      case IO_IOCTL_SERIAL_CAN_TRANSMIT:
         *param_ptr = sci_ptr->S1 & UART_S1_TDRE_MASK ? 1 : 0;
         break;

      case IO_IOCTL_SERIAL_CAN_RECEIVE:
         *param_ptr = sci_ptr->S1 & UART_S1_RDRF_MASK ? 1 : 0;
         break;

      case IO_IOCTL_SERIAL_GET_PARITY:
         tmp = IO_SERIAL_PARITY_NONE;
         if (sci_ptr->C1 & UART_C1_PE_MASK) {
            if (sci_ptr->C1 & UART_C1_PT_MASK) {
               tmp = IO_SERIAL_PARITY_ODD;
            } else {
               tmp = IO_SERIAL_PARITY_EVEN;
            }
         }
         *param_ptr = tmp;
         break;

      case IO_IOCTL_SERIAL_SET_PARITY:
         switch (*param_ptr) {
            case IO_SERIAL_PARITY_NONE:
               /* disable parity only if enabled (once) */
               if (sci_ptr->C1 & UART_C1_PE_MASK)
               {
                  sci_ptr->C1 &= (~ (UART_C1_PE_MASK | UART_C1_PT_MASK));
                  
                  /* disable parity bit */
                  if (sci_ptr->C4 & UART_C4_M10_MASK)
                  {
                     sci_ptr->C4 &= (~ UART_C4_M10_MASK);
                  }
                  else
                  {
                     sci_ptr->C1 &= (~ UART_C1_M_MASK);
                  }
               }
               break;
            case IO_SERIAL_PARITY_ODD:
               /* can't enable parity in 2 stop bits mode */
               if (IO_SERIAL_STOP_BITS_1 != (io_info_ptr->FLAGS & IO_SERIAL_STOP_BITS_1))
               {
                  return MQX_INVALID_CONFIGURATION;
               }

               /* if parity already enabled, just set the requested one */
               if (sci_ptr->C1 & UART_C1_PE_MASK)
               {
                  sci_ptr->C1 |= UART_C1_PT_MASK;
               }
               else
               {
                  /* enable odd parity */
                  sci_ptr->C1 |= (UART_C1_PE_MASK | UART_C1_PT_MASK);
                  
                  /* enable parity bit */
                  if (sci_ptr->C1 & UART_C1_M_MASK)
                  {
                     sci_ptr->C4 |= UART_C4_M10_MASK;
                  }
                  else
                  {
                     sci_ptr->C4 &= (~ UART_C4_M10_MASK);
                     sci_ptr->C1 |= UART_C1_M_MASK;
                  }
               }
               break;
            case IO_SERIAL_PARITY_EVEN:
                /* can't enable parity in 2 stop bits mode */
               if (IO_SERIAL_STOP_BITS_1 != (io_info_ptr->FLAGS & IO_SERIAL_STOP_BITS_1))
               {
                  return MQX_INVALID_CONFIGURATION;
               }
               
               /* if parity already enabled, just set the requested one */
               if (sci_ptr->C1 & UART_C1_PE_MASK)
               {
                  sci_ptr->C1 &= (~ UART_C1_PT_MASK);
               }
               else
               {
                  /* enable even parity */
                  sci_ptr->C1 |= UART_C1_PE_MASK;
                  sci_ptr->C1 &= (~ UART_C1_PT_MASK);
                  
                  /* enable parity bit */
                  if (sci_ptr->C1 & UART_C1_M_MASK)
                  {
                     sci_ptr->C4 |= UART_C4_M10_MASK;
                  }
                  else
                  {
                     sci_ptr->C4 &= (~ UART_C4_M10_MASK);
                     sci_ptr->C1 |= UART_C1_M_MASK;
                  }
               }
               break;
            default:
               return MQX_INVALID_PARAMETER;
         }
         break;

      case IO_IOCTL_SERIAL_SET_FLAGS:
         // automatic HW flow control
         if (*param_ptr & IO_SERIAL_HW_485_FLOW_CONTROL) {
             // RTS hw flow control - support for RS485
             
             /* get serial device index and set GPIO pin functionality to RTS */
             _bsp_serial_rts_init( io_info_ptr->INIT.DEVICE );
             /* enable hardware support for 485 RTS pin drive */
             sci_ptr->MODEM &= (~(UART_MODEM_RXRTSE_MASK | UART_MODEM_TXCTSE_MASK));
             sci_ptr->MODEM |= UART_MODEM_TXRTSE_MASK;
         }
         else if (*param_ptr & IO_SERIAL_HW_FLOW_CONTROL) {
             // RTS, CTS hw flow control
             sci_ptr->MODEM &= ~UART_MODEM_TXRTSE_MASK;
             sci_ptr->MODEM |= (UART_MODEM_RXRTSE_MASK | UART_MODEM_TXCTSE_MASK);
         }
         else {
             sci_ptr->MODEM &= (~(UART_MODEM_RXRTSE_MASK | UART_MODEM_TXCTSE_MASK | UART_MODEM_TXRTSE_MASK));
         }
         
         break;

      case IO_IOCTL_SERIAL_DISABLE_RX:
         if( *(boolean _PTR_)param_ptr == TRUE )
         {
            /* disable receiver */
            sci_ptr->C2 &=~UART_C2_RE_MASK;
         }
         else
         {
            /* enable receiver */
            sci_ptr->C2 |= UART_C2_RE_MASK;
         }
         break;

      case IO_IOCTL_SERIAL_WAIT_FOR_TC:
         /* wait for transmission end signal */
         while( ! sci_ptr->S1 & UART_S1_TC_MASK )
             { };
         break;

      case IO_IOCTL_FLUSH_OUTPUT:
         while (! (sci_ptr->SFIFO & UART_SFIFO_TXEMPT_MASK))
             { };
         while (! (sci_ptr->S1 & UART_S1_TC_MASK))
             { };
         break;

      case IO_IOCTL_SERIAL_GET_STOP_BITS:
         if (IO_SERIAL_STOP_BITS_1 == (io_info_ptr->FLAGS & IO_SERIAL_STOP_BITS_1))
         {
            *param_ptr = IO_SERIAL_STOP_BITS_1;
         }
         else
         {
            *param_ptr = IO_SERIAL_STOP_BITS_2;
         }
         break;

      case IO_IOCTL_SERIAL_SET_STOP_BITS:
         if (IO_SERIAL_STOP_BITS_1 == *param_ptr)
         {
            if (IO_SERIAL_STOP_BITS_1 != (io_info_ptr->FLAGS & IO_SERIAL_STOP_BITS_1))
            {
               /* back to initial 8bit settings */
               sci_ptr->C4 &= (~ UART_C4_M10_MASK);
               sci_ptr->C1 &= (~ UART_C1_M_MASK);
               sci_ptr->C3 &= (~ UART_C3_T8_MASK);
                 
               io_info_ptr->FLAGS |= IO_SERIAL_STOP_BITS_1;
            }
         } 
         else if (IO_SERIAL_STOP_BITS_2 == *param_ptr)
         {
            if (IO_SERIAL_STOP_BITS_1 == (io_info_ptr->FLAGS & IO_SERIAL_STOP_BITS_1))
            {
               /* 2 stop bits are impossible in 9bit data mode or with parity enabled */
               if ((sci_ptr->C1 & UART_C1_M_MASK) || (sci_ptr->C1 & UART_C1_PE_MASK))
               {
                  return MQX_INVALID_CONFIGURATION;
               }
                  
               /* enable 9bit mode */
               sci_ptr->C4 &= (~ UART_C4_M10_MASK);
               sci_ptr->C1 |= UART_C1_M_MASK;
                  
               /* last bit simulates second stop bit */
               sci_ptr->C3 |= UART_C3_T8_MASK;
                  
               io_info_ptr->FLAGS &= (~ IO_SERIAL_STOP_BITS_1);
            }
         }
         else
         {
            return MQX_INVALID_PARAMETER;
         }
         break;

      default:
         return IO_ERROR_INVALID_IOCTL_CMD;
   } /* Endswitch */

   return (MQX_OK);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/intrinsic_cw.h<|end_filename|>
/**************************************************************************//**
 * @file     intrinsic_cw.h
 * @brief    CMSIS Cortex-M4 DSP SIMD Header File
 * @version  V1.00.1.0
 * @date     Dec-6-2012
 *
 ******************************************************************************/

#ifndef __CW_CORTEX_M4_DSP_H__
#define __CW_CORTEX_M4_DSP_H__

/** @addtogroup CMSIS_CM4_DSP_intrinsics CM4 DSP Intrinsics
  This file defines all CMSIS CM4 DSP intrinsics
  @{
 */

#ifdef __cplusplus
 extern "C" {
#endif

/* ###################  Compiler specific Intrinsics  ########################### */
/*------ CM4 DSP Intrinsics ------------------------------------------------------*/
#define __SADD8                           __sadd8
#define __QADD8                           __qadd8
#define __SHADD8                          __shadd8
#define __UADD8                           __uadd8
#define __UQADD8                          __uqadd8
#define __UHADD8                          __uhadd8
#define __SSUB8                           __ssub8
#define __QSUB8                           __qsub8
#define __SHSUB8                          __shsub8
#define __USUB8                           __usub8
#define __UQSUB8                          __uqsub8
#define __UHSUB8                          __uhsub8
#define __SADD16                          __sadd16
#define __QADD16                          __qadd16
#define __SHADD16                         __shadd16
#define __UADD16                          __uadd16
#define __UQADD16                         __uqadd16
#define __UHADD16                         __uhadd16
#define __SSUB16                          __ssub16
#define __QSUB16                          __qsub16
#define __SHSUB16                         __shsub16
#define __USUB16                          __usub16
#define __UQSUB16                         __uqsub16
#define __UHSUB16                         __uhsub16
#define __SASX                            __sasx
#define __QASX                            __qasx
#define __SHASX                           __shasx
#define __UASX                            __uasx
#define __UQASX                           __uqasx
#define __UHASX                           __uhasx
#define __SSAX                            __ssax
#define __QSAX                            __qsax
#define __SHSAX                           __shsax
#define __USAX                            __usax
#define __UQSAX                           __uqsax
#define __UHSAX                           __uhsax
#define __USAD8                           __usad8
#define __USADA8                          __usada8
#define __UXTB16                          __uxtb16
#define __UXTAB16                         __uxtab16
#define __SXTB16                          __sxtb16
#define __SXTAB16                         __sxtab16
#define __SSAT16                          __ssat16
#define __USAT16                          __usat16
#define __SMUAD                           __smuad
#define __SMUADX                          __smuadx
#define __SMLAD                           __smlad
#define __SMLADX                          __smladx
#define __SMLALD                           __smlald
#define __SMLALDX                          __smlaldx
#define __SMUSD                           __smusd
#define __SMUSDX                          __smusdx
#define __SMLSD                           __smlsd
#define __SMLSDX                          __smlsdx
#define __SMLSLD                           __smlsld
#define __SMLSLDX                          __smlsldx
#define __SEL                             __sel
#define __QADD                          __qadd 
#define __QSUB                          __qsub 
/*-- End CM4 Intrinsics ----------------------------------------------------------*/

static inline unsigned int __SADD8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SADD8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                sadd8 res,op1,op2;
        }
	return res;
}

static inline unsigned int __QADD8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __QADD8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                qadd8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SHADD8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SHADD8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                shadd8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UADD8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UADD8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uadd8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UQADD8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UQADD8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uqadd8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UHADD8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UHADD8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uhadd8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SSUB8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SSUB8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                ssub8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __QSUB8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __QSUB8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                qsub8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SHSUB8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SHSUB8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                shsub8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __USUB8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __USUB8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                usub8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UQSUB8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UQSUB8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uqsub8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UHSUB8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UHSUB8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uhsub8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SADD16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SADD16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                sadd16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __QADD16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __QADD16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                qadd16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SHADD16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SHADD16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                shadd16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UADD16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UADD16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uadd16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UQADD16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UQADD16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uqadd16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UHADD16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UHADD16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uhadd16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SSUB16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SSUB16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                ssub16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __QSUB16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __QSUB16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                qsub16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SHSUB16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SHSUB16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                ssub16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __USUB16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __USUB16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                usub16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UQSUB16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UQSUB16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uqsub16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __UHSUB16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UHSUB16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uhsub16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SASX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SASX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                sasx res,op1,op2;
        }

        return res;
}

static inline unsigned int __QASX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __QASX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                qasx res,op1,op2;
        }

        return res;
}

static inline unsigned int __SHASX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SHASX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                shasx res,op1,op2;
        }

        return res;
}

static inline unsigned int __UASX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UASX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uasx res,op1,op2;
        }

        return res;
}

static inline unsigned int __UQASX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UQASX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uqasx res,op1,op2;
        }

        return res;
}

static inline unsigned int __UHASX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UHASX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uhasx res,op1,op2;
        }

        return res;
}

static inline unsigned int __SSAX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SSAX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                ssax res,op1,op2;
        }

        return res;
}

static inline unsigned int __QSAX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __QSAX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                qsax res,op1,op2;
        }

        return res;
}

static inline unsigned int __SHSAX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SHSAX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                shsax res,op1,op2;
        }

        return res;
}

static inline unsigned int __USAX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __USAX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                usax res,op1,op2;
        }

        return res;
}

static inline unsigned int __UQSAX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UQSAX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uqsax res,op1,op2;
        }

        return res;
}

static inline unsigned int __UHSAX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UHSAX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uhsax res,op1,op2;
        }

        return res;
}

static inline unsigned int __USAD8(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __USAD8(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                usad8 res,op1,op2;
        }

        return res;
}

static inline unsigned int __USADA8(register unsigned int op1, register unsigned int op2, register unsigned int op3) __attribute__((always_inline));
static inline unsigned int __USADA8(register unsigned int op1, register unsigned int op2, register unsigned int op3)
{
	register unsigned int res;
        asm {
                usada8 res,op1,op2,op3;
        }

        return res;
}

static inline unsigned int __SSAT16(register unsigned int op1, unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SSAT16(register unsigned int op1, unsigned int op2)
{
	register unsigned int res;
        asm ("ssat16 %0, %1, %2" : "=r" (res) :  "I" (op2), "r" (op1));

        return res;
}

static inline unsigned int __USAT16(register unsigned int op1, unsigned int op2) __attribute__((always_inline));
static inline unsigned int __USAT16(register unsigned int op1, unsigned int op2)
{
	register unsigned int res;
        asm ("usat16 %0, %1, %2" : "=r" (res) :  "I" (op2), "r" (op1));
        return res;
}
/*#define __SSAT16(ARG1,ARG2) \
({                          \
  unsigned int __RES, __ARG1 = (ARG1); \
  asm ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
  __RES; \
 })
*/
/*#define __USAT16(ARG1,ARG2) \
(                          \
  	asm {\
  	  	usat16 r0,#ARG2, ARG1\
		}\
 )
*/

static inline unsigned int __UXTB16(register unsigned int op1) __attribute__((always_inline));
static inline unsigned int __UXTB16(register unsigned int op1)
{
	register unsigned int res;
        asm {
                uxtb16 res,op1;
        }

        return res;
}

static inline unsigned int __UXTAB16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __UXTAB16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                uxtab16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SXTB16(register unsigned int op1) __attribute__((always_inline));
static inline unsigned int __SXTB16(register unsigned int op1)
{
	register unsigned int res;
        asm {
                sxtb16 res,op1;
        }

        return res;
}

static inline unsigned int __SXTAB16(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SXTAB16(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                sxtab16 res,op1,op2;
        }

        return res;
}

static inline unsigned int __SMUAD(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SMUAD(register unsigned int op1, register unsigned int op2)
{
	register signed int res;
        asm {
                smuad res,op1,op2;
        }

        return res;
}

static inline unsigned int __SMUADX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SMUADX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                smuadx res,op1,op2;
        }

        return res;
}

static inline unsigned int __SMLAD(register unsigned int op1, register unsigned int op2, register unsigned int op3) __attribute__((always_inline));
static inline unsigned int __SMLAD(register unsigned int op1, register unsigned int op2, register unsigned int op3)
{
	register unsigned int res;
        asm {
                smlad res,op1,op2,op3;
        }

        return res;
}

static inline unsigned int __SMLADX(register unsigned int op1, register unsigned int op2, register unsigned int op3) __attribute__((always_inline));
static inline unsigned int __SMLADX(register unsigned int op1, register unsigned int op2, register unsigned int op3)
{
	register unsigned int res;
        asm {
                smladx res,op1,op2,op3;
        }

        return res;
}
static inline unsigned long long __SMLALD(register unsigned int op1, register unsigned int op2, register unsigned long long op3) __attribute__((always_inline));
static inline unsigned long long __SMLALD(register unsigned int op1, register unsigned int op2, register unsigned long long op3)
{
	register unsigned int op3_H = (unsigned int)((op3) >> 32), op3_L = (unsigned int)((op3) & 0xFFFFFFFF);
	unsigned long long res ;
	asm {
		smlald op3_L, op3_H, op1, op2;
		}
        res = op3_H;
		return((res << 32) | op3_L);
}

static inline unsigned long long __SMLALDX(register unsigned int op1, register unsigned int op2, register unsigned long long op3) __attribute__((always_inline));
static inline unsigned long long __SMLALDX(register unsigned int op1, register unsigned int op2, register unsigned long long op3)
{
	register unsigned int op3_H = (unsigned int)((op3) >> 32), op3_L = (unsigned int)((op3) & 0xFFFFFFFF);
		unsigned long long res ;
		asm {
			smlaldx op3_L, op3_H, op1, op2;
		}

        res = op3_H;
		return((res << 32) | op3_L);
}

/*#define __SMLALD(ARG1,ARG2,ARG3) \
({\
	unsigned int __ARG1 = ARG1, __ARG2 = ARG2, __ARG3_H = (unsigned int)((ARG3) >> 32), __ARG3_L = (unsigned int)((ARG3) & 0xFFFFFFFF); \
	asm {	smlald __ARG3_L, __ARG3_H, __ARG1, __ARG2}\
	})

#define __SMLALDX(ARG1,ARG2,ARG3) \
({\
	unsigned int __ARG1 = ARG1, __ARG2 = ARG2, __ARG3_H = (unsigned int)((ARG3) >> 32), __ARG3_L = (unsigned int)((ARG3) & 0xFFFFFFFF); \
	asm {	smlaldx __ARG3_L, __ARG3_H, __ARG1, __ARG2}\
	})
*/
static inline unsigned int __SMUSD(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SMUSD(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                smusd res,op1,op2;
        }

        return res;
}

static inline unsigned int __SMUSDX(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __SMUSDX(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                smusdx res,op1,op2;
        }

        return res;
}

static inline unsigned int __SMLSD(register unsigned int op1, register unsigned int op2, register unsigned int op3) __attribute__((always_inline));
static inline unsigned int __SMLSD(register unsigned int op1, register unsigned int op2, register unsigned int op3)
{
	register unsigned int res;
        asm {
                smlsd res,op1,op2, op3;
        }

        return res;
}

static inline unsigned int __SMLSDX(register unsigned int op1, register unsigned int op2, register unsigned int op3) __attribute__((always_inline));
static inline unsigned int __SMLSDX(register unsigned int op1, register unsigned int op2, register unsigned int op3)
{
	register unsigned int res;
        asm {
                smlsdx res,op1,op2,op3;
        }

        return res;
}

static inline unsigned long long __SMLSLD(register unsigned int op1, register unsigned int op2, register unsigned long long op3) __attribute__((always_inline));
static inline unsigned long long __SMLSLD(register unsigned int op1, register unsigned int op2, register unsigned long long op3)
{
	register unsigned int op3_H = (unsigned int)((op3) >> 32), op3_L = (unsigned int)((op3) & 0xFFFFFFFF); \
	unsigned long long res ;
	asm {
		smlsld op3_L, op3_H, op1, op2;
		}
        res = op3_H;
		return((res << 32) | op3_L);
}

static inline unsigned long long __SMLSLDX(register unsigned int op1, register unsigned int op2, register unsigned long long op3) __attribute__((always_inline));
static inline unsigned long long __SMLSLDX(register unsigned int op1, register unsigned int op2, register unsigned long long op3)
{
	register unsigned int op3_H = (unsigned int)((op3) >> 32), op3_L = (unsigned int)((op3) & 0xFFFFFFFF); \
		unsigned long long res;
		asm {
			smlsldx op3_L, op3_H, op1, op2;
		}
		res = op3_H;
		return((res << 32) | op3_L);
}

/*#define __SMLSLD(ARG1,ARG2,ARG3) \
({\
	unsigned int __ARG1 = ARG1, __ARG2 = ARG2, __ARG3_H = (unsigned int)((ARG3) >> 32), __ARG3_L = (unsigned int)((ARG3) & 0xFFFFFFFF); \
	asm {	smlsld __ARG3_L, __ARG3_H, __ARG1, __ARG2}\
	})

#define __SMLSLDX(ARG1,ARG2,ARG3) \
({\
	unsigned int __ARG1 = ARG1, __ARG2 = ARG2, __ARG3_H = (unsigned int)((ARG3) >> 32), __ARG3_L = (unsigned int)((ARG3) & 0xFFFFFFFF); \
	asm {	smlsldx __ARG3_L, __ARG3_H, __ARG1, __ARG2}\
	})
*/
static inline unsigned int __SEL(register unsigned int op1, register unsigned int op2) __attribute__((always_inline));
static inline unsigned int __sel(register unsigned int op1, register unsigned int op2)
{
	register unsigned int res;
        asm {
                sel res,op1,op2;
        }

        return res;
}
/* ###################  adding functions QADD QSUB ########################### */

static inline long __QADD(register long op1, register long op2) __attribute__((always_inline));
static inline long __qadd(register long op1, register long op2)
{
	register long res;
        asm {
                QADD res,op1,op2;
        }

        return res;
}

static inline long __QSUB(register long op1, register long op2) __attribute__((always_inline));
static inline long __qsub(register long op1, register long op2)
{
	register long res;
        asm {
                QSUB res,op1,op2;
        }

        return res;
}

#endif


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_di.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_di.c$
* $Version : 3.8.10.0$
* $Date    : Sep-13-2012$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/


#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_mfs.h>

#if SHELLCFG_USES_MFS

#define SECTOR_SIZE MFS_DEFAULT_SECTOR_SIZE

typedef struct 
{
   uchar    JMP[3];
   uchar    OEMNAME[8];
   uchar    BPB_SECTOR_SIZE[2];
   uchar    SECTORS_PER_CLUSTER[1];
   uchar    RESERVED_SECTORS[2];
   uchar    NUMBER_OF_FAT[1];
   uchar    ROOT_ENTRIES[2];
   uchar    NUMBER_SECTORS[2];
   uchar    MEDIA_TYPE[1];
   uchar    SECTORS_PER_FAT[2];
   uchar    SECTORS_PER_TRACK[2];
   uchar    NUM_HEADS[2];
   uchar    HIDDEN_SECTORS[4];
   uchar    MEGA_SECTORS[4];

   uchar    FAT_SIZE[4];
   uchar    EXT_FLAGS[2];
   uchar    FS_VER[2];
   uchar    ROOT_CLUSTER[4];
   uchar    FS_INFO[2];
   uchar    BK_BOOT_SEC[2];
   uchar    RESERVED[12];
   uchar    DRVNUM[1];
   uchar    RESERVED1[1];
   uchar    BOOTSIG[1];
   uchar    VOLID[4];
   uchar    VOLLAB[11];
   uchar    FILSYSTYPE[8];
} BIOS_PARAM_STRUCT_DISK, _PTR_ BIOS_PARAM_STRUCT_DISK_PTR;

/* The file system info struct. For FAT32 only */
typedef struct filesystem_info_disk  {
   uchar    LEAD_SIG[4];
   uchar    RESERVED1[480];
   uchar    STRUCT_SIG[4];
   uchar    FREE_COUNT[4];
   uchar    NEXT_FREE[4];
   uchar    RESERVED2[12];
   uchar    TRAIL_SIG[4];  
} FILESYSTEM_INFO_DISK, _PTR_ FILESYSTEM_INFO_DISK_PTR;



static uint_32 print_bpb(pointer bpb) {
   BIOS_PARAM_STRUCT_DISK_PTR bpb_ptr = (BIOS_PARAM_STRUCT_DISK_PTR) bpb;
   uint_32 i,backup=0;


   printf("OEMNAME            = ");
   for(i=0;i<8;i++) printf("%c", bpb_ptr->OEMNAME[i]);  printf("\n");
   printf("SECTOR_SIZE        = %02x%02x\n",bpb_ptr->BPB_SECTOR_SIZE[1] ,bpb_ptr->BPB_SECTOR_SIZE[0] );
   printf("SECTORS_PER_CLUSTER= %02x%\n",(uint_32) bpb_ptr->SECTORS_PER_CLUSTER[0]  );
   printf("RESERVED_SECTORS   = %02x%02x\n",bpb_ptr->RESERVED_SECTORS[1] ,bpb_ptr->RESERVED_SECTORS[0] );
   printf("NUMBER_OF_FAT      = %02x\n",(uint_32) bpb_ptr->NUMBER_OF_FAT[0]  );
   printf("ROOT_ENTRIES       = %02x%02x\n",bpb_ptr->ROOT_ENTRIES[1] ,bpb_ptr->ROOT_ENTRIES[0] );
   printf("NUMBER_SECTORS     = %02x%02x\n",bpb_ptr->NUMBER_SECTORS[1] ,bpb_ptr->NUMBER_SECTORS[0] );
   printf("MEDIA_TYPE         = %02x\n",(uint_32) bpb_ptr->MEDIA_TYPE[0] );
   printf("SECTORS_PER_FAT    = %02x%02x\n",bpb_ptr->SECTORS_PER_FAT[1] ,bpb_ptr->SECTORS_PER_FAT[0] );
   printf("SECTORS_PER_TRACK  = %02x%02x\n",bpb_ptr->SECTORS_PER_TRACK[1] ,bpb_ptr->SECTORS_PER_TRACK[0] );
   printf("NUM_HEADS          = %02x%02x\n",bpb_ptr->NUM_HEADS[1] ,bpb_ptr->NUM_HEADS[0] );
   printf("HIDDEN_SECTORS     = %02x%02x%02x%02x\n",bpb_ptr->HIDDEN_SECTORS[3] ,bpb_ptr->HIDDEN_SECTORS[2],bpb_ptr->HIDDEN_SECTORS[1] ,bpb_ptr->HIDDEN_SECTORS[0] );
   printf("MEGA_SECTORS       = %02x%02x%02x%02x\n",bpb_ptr->MEGA_SECTORS[3] ,bpb_ptr->MEGA_SECTORS[2],bpb_ptr->MEGA_SECTORS[1] ,bpb_ptr->MEGA_SECTORS[0] );

   if ( bpb_ptr->SECTORS_PER_FAT[1]|| bpb_ptr->SECTORS_PER_FAT[0] ) {
      // FAT 12/16

   } else {
   
      // FAT 32
      printf("FAT_SIZE           = %02x%02x%02x%02x\n",bpb_ptr->FAT_SIZE[3] ,bpb_ptr->FAT_SIZE[2],bpb_ptr->FAT_SIZE[1] ,bpb_ptr->FAT_SIZE[0] );
      printf("EXT_FLAGS          = %02x%02x\n",bpb_ptr->EXT_FLAGS[1] ,bpb_ptr->EXT_FLAGS[0] );
      printf("FS_VER             = %02x%02x\n",bpb_ptr->FS_VER[1] ,bpb_ptr->FS_VER[0] );

      printf("ROOT_CLUSTER       = %02x%02x%02x%02x\n",bpb_ptr->ROOT_CLUSTER[3] ,bpb_ptr->ROOT_CLUSTER[2],bpb_ptr->ROOT_CLUSTER[1] ,bpb_ptr->ROOT_CLUSTER[0] );
      printf("FS_INFO            = %02x%02x\n",bpb_ptr->FS_INFO[1] ,bpb_ptr->FS_INFO[0] );
      printf("BK_BOOT_SEC        = %02x%02x\n",bpb_ptr->BK_BOOT_SEC[1] ,bpb_ptr->BK_BOOT_SEC[0] );

      backup = (bpb_ptr->BK_BOOT_SEC[1] << 8) | bpb_ptr->BK_BOOT_SEC[0];
      printf("DRVNUM             = %02x\n",(uint_32) bpb_ptr->DRVNUM[0] );
      printf("BOOTSIG            = %02x\n",(uint_32) bpb_ptr->BOOTSIG[0] );
      printf("VOLID              = %02x%02x%02x%02x\n",bpb_ptr->VOLID[3] ,bpb_ptr->VOLID[2],bpb_ptr->VOLID[1] ,bpb_ptr->VOLID[0] );
      printf("VOLLAB             = ");
      for(i=0;i<11;i++) printf("%c", bpb_ptr->VOLLAB[i]);  printf("\n");
      printf("FILSYSTYPE         = ");
      for(i=0;i<8;i++) printf("%c", bpb_ptr->FILSYSTYPE[i]);  printf("\n");

   }
   return backup;
}


static void print_fsi(pointer bpb) 
{
   FILESYSTEM_INFO_DISK_PTR bpb_ptr = (FILESYSTEM_INFO_DISK_PTR) bpb;
   
   printf("LEAD_SIG   = %02x%02x%02x%02x\n",bpb_ptr->LEAD_SIG[3],  bpb_ptr->LEAD_SIG[2],  bpb_ptr->LEAD_SIG[1],  bpb_ptr->LEAD_SIG[0] );
   printf("STRUCT_SIG = %02x%02x%02x%02x\n",bpb_ptr->STRUCT_SIG[3],bpb_ptr->STRUCT_SIG[2],bpb_ptr->STRUCT_SIG[1],bpb_ptr->STRUCT_SIG[0] );
   printf("FREE_COUNT = %02x%02x%02x%02x\n",bpb_ptr->FREE_COUNT[3],bpb_ptr->FREE_COUNT[2],bpb_ptr->FREE_COUNT[1],bpb_ptr->FREE_COUNT[0] );
   printf("NEXT_FREE  = %02x%02x%02x%02x\n",bpb_ptr->NEXT_FREE[3], bpb_ptr->NEXT_FREE[2], bpb_ptr->NEXT_FREE[1], bpb_ptr->NEXT_FREE[0] );
   printf("TRAIL_SIG  = %02x%02x%02x%02x\n",bpb_ptr->TRAIL_SIG[3], bpb_ptr->TRAIL_SIG[2], bpb_ptr->TRAIL_SIG[1], bpb_ptr->TRAIL_SIG[0] );
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_di
* Returned Value   :  int_32 error code
* Comments  :  Reads from a file .
*
*END*---------------------------------------------------------------------*/

int_32  Shell_di(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   int_32            offset;

   MQX_FILE_PTR      fd, fs;

   uint_32           backup=0;
   uchar_ptr         buffer=NULL;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if ((argc < 2 ) || (argc > 3)) {
         printf("Invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else if ( !Shell_parse_uint_32(argv[1], (uint_32_ptr) &offset ))  {
         printf("Error, invalid length\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else {
         buffer = _mem_alloc(SECTOR_SIZE);
         if (buffer==NULL) {
            printf("Error, unable to allocate sector buffer\n");
            return  SHELL_EXIT_ERROR;
         }

         if (argc==3) {
            fd = fopen(argv[2], "b");
         } else {   
            fs = Shell_get_current_filesystem(argv);
            _io_ioctl(fs, IO_IOCTL_GET_DEVICE_HANDLE, &fd);
         }
              

         if (fd)  {
            if (fseek(fd, offset, IO_SEEK_SET) == IO_ERROR)  {
               printf("Error, unable to seek to sector %s.\n", argv[1] );
               return_code = SHELL_EXIT_ERROR;
            } else if (_io_read(fd, (char_ptr) buffer, 1) != 1) {
               printf("Error, unable to read sector %s.\n", argv[1] );
               return_code = SHELL_EXIT_ERROR;
            }
            
            if (return_code == SHELL_EXIT_SUCCESS) {
               printf("\n");
               backup = print_bpb(buffer);
               if (backup) {
                  if (fseek(fd, backup, IO_SEEK_SET) == IO_ERROR)  {
                     printf("Error, unable to seek to sector %s.\n", argv[1] );
                     return_code = SHELL_EXIT_ERROR;
                  } else if (_io_read(fd, (char_ptr) buffer, 1) != 1) {
                     printf("Error, unable to read sector %s.\n", argv[1] );
                     return_code = SHELL_EXIT_ERROR;
                  }  
                  if (return_code == SHELL_EXIT_SUCCESS) {
                     printf("\n");
                     print_bpb(buffer);
                  }
               }
            }
            if (fseek(fd, 1, IO_SEEK_SET) == IO_ERROR)  {
               printf("Error, unable to seek to sector %s.\n", argv[1] );
               return_code = SHELL_EXIT_ERROR;
            } else if (_io_read(fd, (char_ptr) buffer, 1) != 1) {
               printf("Error, unable to read sector %s.\n", argv[1] );
               return_code = SHELL_EXIT_ERROR;
            }  
            if (return_code == SHELL_EXIT_SUCCESS) {
               printf("\n");
               print_fsi(buffer);
            }
            if (argc==3) {
               fclose(fd);
            }
         }
         _mem_free(buffer);
      }
   }
   
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <sector> [<device>]\n", argv[0]);
      } else  {
         printf("Usage: %s <sector> [<device>]\n", argv[0]);
         printf("   <sector>     = sector number\n");
         printf("   <device>     = low level device\n");
      }
   }
   return return_code;
} /* Endbody */

#endif //SHELLCFG_USES_MFS


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/binfile.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: binfile.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the binary file decoder for the
*   Exec function of the RTCS Communication Library.
*
*END************************************************************************/

#include <rtcs.h>


/* The binary file decoder information to pass to RTCS_load() */
uint_32 BIN_start  (pointer ff_data);
uint_32 BIN_decode (uint_32 size, uchar_ptr data);
uint_32 BIN_eod    (void);
void    BIN_exec   (void);

static FF_CALL_STRUCT ff_bin = {
   BIN_start,
   BIN_decode,
   BIN_eod,
   BIN_exec
};

const FF_CALL_STRUCT_PTR FF_BIN = &ff_bin;


/* Binary file decoder state information */
static uchar_ptr download_address;
static uchar_ptr execute_address;


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : BIN_start
* Returned Value : error code
* Comments       : Routine to begin loading a binary file.
*
*END*-----------------------------------------------------------------*/

uint_32 BIN_start
   (
      pointer  ff_data
   )
{ /* Body */

   download_address = ((BINFILE_DATA_STRUCT_PTR)ff_data)->DOWNLOAD_ADDR;
   execute_address  = ((BINFILE_DATA_STRUCT_PTR)ff_data)->EXEC_ADDR;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : BIN_decode
* Returned Value : status
* Comments       : Copy the transferred bytes to the target.
*
*END*-----------------------------------------------------------------*/

uint_32 BIN_decode
   (
      uint_32   size,
         /* [IN] number of bytes to decode */
      uchar_ptr data
         /* [IN] bytes to decode */
   )
{ /* Body */

   _mem_copy(data, download_address, size);
   download_address += size;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : BIN_eod
* Returned Value : error code
* Comments       : Routine to end decoding.
*
*END*-----------------------------------------------------------------*/

uint_32 BIN_eod
   (
      void
   )
{ /* Body */

   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : BIN_exec
* Returned Value : none
* Comments       : Routine to execute a decoded binary file.
*
*END*-----------------------------------------------------------------*/

void BIN_exec
   (
      void
   )
{ /* Body */

   (*(void(_CODE_PTR_)(void))(uint_32)execute_address)();

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/part_mgr.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: part_mgr.c$
* $Version : 3.8.18.0$
* $Date    : Jul-25-2012$
*
* Comments:
*
*   This file contains the functions for a partition manager device that is
*   is built to work under MFS1.40. These functions can also create or
*   remove partitions from a disk.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>


#include "mfs.h"
#include "part_mgr.h"

extern _mfs_error _mfs_validate_device(MQX_FILE_PTR dev_fd, uint_32_ptr sector_size_ptr, boolean _PTR_ block_mode_ptr);
static int_32 _io_part_mgr_uninstall_internal(IO_DEVICE_STRUCT_PTR dev_ptr);

/*FUNCTION*---------------------------------------------------------------
*
* Function Name  : _io_part_mgr_install
* Returned Value : int_32 error code
* Comments       : installs the partition manager device
*
*
*END*--------------------------------------------------------------------*/

int_32 _io_part_mgr_install
    (
    MQX_FILE_PTR dev_fd,     /*[IN] Handle of the device on which to install the partition manager */
    char_ptr    identifier, /*[IN] The new name of the partition manager device */
    uint_32     sector_size /*[IN] The size of sectors in bytes on the lower level device */
    )
{
    PART_MGR_STRUCT_PTR           pm_struct_ptr;
    int_32                        error_code;

    pm_struct_ptr = MFS_mem_alloc_system_zero( sizeof(PART_MGR_STRUCT));
    if ( pm_struct_ptr == NULL )
    {
        return( PMGR_INSUF_MEMORY );
    }

    _mem_set_type(pm_struct_ptr, MEM_TYPE_PART_MGR_STRUCT);

    /*
    ** Create a light weight semaphore
    */
    _lwsem_create(&(pm_struct_ptr->SEM), 0);

    /* Store the handle of the device in the lower layer */
    pm_struct_ptr->DEV_FILE_PTR = dev_fd;
    pm_struct_ptr->INSTANCES = 0;

    error_code = _io_dev_install_ext( identifier,
        _io_part_mgr_open,
        _io_part_mgr_close,
        _io_part_mgr_read,
        _io_part_mgr_write,
        (_mqx_int(_CODE_PTR_)(MQX_FILE_PTR,_mqx_uint,pointer))_io_part_mgr_ioctl,
        _io_part_mgr_uninstall_internal,
        (pointer) pm_struct_ptr );

    if ( error_code )
    {
        _lwsem_destroy(&pm_struct_ptr->SEM);
        _mem_free(pm_struct_ptr);
    }
    else
    {
        _lwsem_post(&(pm_struct_ptr->SEM));
    }

    return error_code;

}


/*FUNCTION*---------------------------------------------------------------
*
* Function Name  : _io_part_mgr_uninstall_internal
* Returned Value : int_32 error code
* Comments       : uninstalls the partition manager device
*
*
*END*--------------------------------------------------------------------*/

static int_32 _io_part_mgr_uninstall_internal
    (
    IO_DEVICE_STRUCT_PTR        dev_ptr     /*[IN] The identifier of the device */
    )
{
    PART_MGR_STRUCT_PTR pm_struct_ptr;

    pm_struct_ptr = (PART_MGR_STRUCT_PTR) dev_ptr->DRIVER_INIT_PTR;

    _lwsem_wait(&(pm_struct_ptr->SEM));

    if (pm_struct_ptr->INSTANCES)
    {
        _lwsem_post(&(pm_struct_ptr->SEM));
        return IO_ERROR_DEVICE_BUSY;
    }

    _lwsem_destroy(&pm_struct_ptr->SEM);
    _mem_free(pm_struct_ptr);

    return IO_OK;
}

#if MFSCFG_DEPRICATED_UNINSTALL
/*FUNCTION*---------------------------------------------------------------
*
* Function Name  : _io_part_mgr_uninstall
* Returned Value : int_32 error code
* Comments       : uninstalls the partition manager device
*
*
*END*--------------------------------------------------------------------*/

int_32 _io_part_mgr_uninstall
    (
    char_ptr          identifier    /*[IN] The identifier string of the device */
    )
{
    return _io_dev_uninstall(identifier);
}
#endif


/*FUNCTION*---------------------------------------------------------------
*
* Function Name  : _io_part_mgr_open
* Returned Value : MQX_OK
* Comments       : Does nothing. All the initialization is done in
*                  the io_part_mgr_install function
*
*END*--------------------------------------------------------------------*/

int_32 _io_part_mgr_open
    (
    MQX_FILE_PTR   fd_ptr,          /* [IN] the file pointer of the partition manager to open */
    char_ptr       open_name_ptr,   /* [IN] the name of the device that is being opened */
    char_ptr       open_mode_ptr    /* [IN] the flags that determine the open mode */
    )
{
    PART_MGR_STRUCT_PTR       pm_struct_ptr;
    PMGR_PART_INFO_STRUCT_PTR part_info_ptr;
    MQX_FILE_PTR              dev_fd;

    uint_32                   sector_size;
    int_32                    error;
    int_32                    part_num;

    char_ptr                  file_name_ptr;

    file_name_ptr = open_name_ptr;
    while (*file_name_ptr && *file_name_ptr++ != ':') {}

    if (file_name_ptr[0])
    {
        part_num = file_name_ptr[0] - '0';
        if (file_name_ptr[1] != '\0' || part_num<0 || part_num>PMGR_MAX_PARTITIONS)
            return PMGR_INVALID_PARTITION;
    }
    else
    {
        part_num = 0;
    }

    pm_struct_ptr = (PART_MGR_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    dev_fd = pm_struct_ptr->DEV_FILE_PTR;

    _lwsem_wait(&(pm_struct_ptr->SEM));

    /* Validate device (check block mode and size) if no other instances exist so far */
    if (pm_struct_ptr->INSTANCES == 0)
    {
        error = _mfs_validate_device(dev_fd, &sector_size, &pm_struct_ptr->BLOCK_MODE);
        if ( error )
        {
            _lwsem_post(&(pm_struct_ptr->SEM));
            return error;
        }
        pm_struct_ptr->DEV_SECTOR_SIZE = sector_size;
        pm_struct_ptr->DEV_NUM_SECTORS = 0;
        _io_ioctl(dev_fd, IO_IOCTL_GET_NUM_SECTORS, &(pm_struct_ptr->DEV_NUM_SECTORS));
    }

    part_info_ptr = MFS_mem_alloc_system_zero(sizeof(PMGR_PART_INFO_STRUCT));
    if (part_info_ptr == NULL )
    {
        _lwsem_post(&(pm_struct_ptr->SEM));
        return PMGR_INSUF_MEMORY;
    }

    /* Check whether to opening partition or operate on whole device (part_num==0) */
    if (part_num)
    {
        part_info_ptr->SLOT = part_num;
        if (_pmgr_get_part_info(pm_struct_ptr, part_info_ptr))
        {
            _mem_free(part_info_ptr);
            _lwsem_post(&(pm_struct_ptr->SEM));
            return PMGR_INVALID_PARTITION;
        }
    }
    else
    {
        /* Use size of device as length of the partition */
        part_info_ptr->LENGTH = pm_struct_ptr->DEV_NUM_SECTORS;
    }

    fd_ptr->DEV_DATA_PTR = part_info_ptr;
    pm_struct_ptr->INSTANCES++;

    _lwsem_post(&(pm_struct_ptr->SEM));
    return IO_OK;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : _io_part_mgr_close
* Returned Value : MQX_OK
* Comments       : Frees the memory allocated to hold the partition info
*
*END*--------------------------------------------------------------------*/

int_32 _io_part_mgr_close
    (

    MQX_FILE_PTR   fd_ptr   /* [IN] the file pointer of the partition manager to close */
    )
{
    PART_MGR_STRUCT_PTR   pm_struct_ptr;

    pm_struct_ptr = (PART_MGR_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR;

    _lwsem_wait(&(pm_struct_ptr->SEM));

    pm_struct_ptr->INSTANCES--;
    _mem_free(fd_ptr->DEV_DATA_PTR);

    _lwsem_post(&(pm_struct_ptr->SEM));

    return IO_OK;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : _io_part_mgr_read
* Returned Value : The number of bytes read from device
* Comments       : Calls the read function of the next layer
*
*END*--------------------------------------------------------------------*/

int_32 _io_part_mgr_read
    (
    MQX_FILE_PTR   fd_ptr,      /* [IN] the file pointer of the partition manager to read from */
    char_ptr       data_ptr,    /* [IN] the data location to read to */
    int_32         num          /* [IN] the number of bytes to read */
    )
{
    PART_MGR_STRUCT_PTR           pm_struct_ptr;
    PMGR_PART_INFO_STRUCT_PTR     part_info_ptr;
    uint_32    location;
    uint_32    part_start;
    uint_32    part_end;
    int_32     result;

    pm_struct_ptr = (PART_MGR_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    part_info_ptr = (PMGR_PART_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;

    /* If a partition is selected, also its start has to be defined */
    if (part_info_ptr->SLOT && part_info_ptr->START_SECTOR==0)
    {
        fd_ptr->ERROR = PMGR_INVALID_PARTITION;
        return IO_ERROR;
    }

    part_start = part_info_ptr->START_SECTOR;
    part_end = part_info_ptr->LENGTH ? part_start + part_info_ptr->LENGTH : 0;

    /* If not operating on a block device, multiply values by sector size */
    if (!(pm_struct_ptr->BLOCK_MODE))
    {
        part_start *= pm_struct_ptr->DEV_SECTOR_SIZE;
        part_end *= pm_struct_ptr->DEV_SECTOR_SIZE;
    }

    /* Calculate seek location for undelying device */
    location = part_start + fd_ptr->LOCATION;
    if (part_end)
    {
        /* Check whether lhe location points into the partition area */
        if (location >= part_end)
        {
            fd_ptr->ERROR = IO_ERROR_SEEK;
            return IO_ERROR;
        }
        /* Check whether the transfer would overflow the partition area and shorten it if necessary */
        if (location + num > part_end)
        {
            num = part_end - location;
        }
    }

    /* Lock to prevent concurrent access to underlying device */
    _lwsem_wait(&pm_struct_ptr->SEM);

    /* Perform seek and data transfer */
    result = fseek(pm_struct_ptr->DEV_FILE_PTR, location, IO_SEEK_SET);
    if (result == MQX_OK)
    {
        result = read( ((PART_MGR_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR)->DEV_FILE_PTR, data_ptr, num);
    }
    fd_ptr->ERROR = ((PART_MGR_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR)->DEV_FILE_PTR->ERROR;

    /* Unlock */
    _lwsem_post(&pm_struct_ptr->SEM);

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : _io_part_mgr_write
* Returned Value : the number of bytes writen to device
* Comments       : calls the write function of the next layer
*
*END*--------------------------------------------------------------------*/

int_32 _io_part_mgr_write
    (
    MQX_FILE_PTR   fd_ptr,      /* [IN] the file pointer of the partition manager to read from */
    char_ptr       data_ptr,    /* [IN] the data location to read from */
    int_32         num          /* [IN] the number of bytes to write */
    )
{
    PART_MGR_STRUCT_PTR           pm_struct_ptr;
    PMGR_PART_INFO_STRUCT_PTR     part_info_ptr;
    uint_32    location;
    uint_32    part_start;
    uint_32    part_end;
    int_32     result;

    pm_struct_ptr = (PART_MGR_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    part_info_ptr = (PMGR_PART_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;

    /* If a partition is selected, also its start has to be defined */
    if (part_info_ptr->SLOT && part_info_ptr->START_SECTOR==0)
    {
        fd_ptr->ERROR = PMGR_INVALID_PARTITION;
        return IO_ERROR;
    }

    part_start = part_info_ptr->START_SECTOR;
    part_end = part_info_ptr->LENGTH ? part_start + part_info_ptr->LENGTH : 0;

    /* If not operating on a block device, multiply values by sector size */
    if (!(pm_struct_ptr->BLOCK_MODE))
    {
        part_start *= pm_struct_ptr->DEV_SECTOR_SIZE;
        part_end *= pm_struct_ptr->DEV_SECTOR_SIZE;
    }

    /* Calculate seek location for undelying device */
    location = fd_ptr->LOCATION + part_start;
    if (part_info_ptr->LENGTH)
    {
        /* Check whether lhe location points into the partition area */
        if (location >= part_end)
        {
            fd_ptr->ERROR = IO_ERROR_SEEK;
            return IO_ERROR;
        }
        /* Check whether the transfer would overflow the partition area and shorten it if necessary */
        if (location + num > part_end)
        {
            num = part_end - location;
        }
    }

    /* Lock to prevent concurrent access to underlying device */
    _lwsem_wait(&pm_struct_ptr->SEM);

    /* Perform seek and data transfer */
    result = fseek(pm_struct_ptr->DEV_FILE_PTR, location, IO_SEEK_SET);
    if (result == MQX_OK)
    {
        result = write( ((PART_MGR_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR)->DEV_FILE_PTR, data_ptr, num);
    }
    fd_ptr->ERROR = ((PART_MGR_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR)->DEV_FILE_PTR->ERROR;

    /* Unlock */
    _lwsem_post(&pm_struct_ptr->SEM);

    return result;
}


/*FUNCTION*--------------------------------------------------------------
*
* Function Name  : _io_part_mgr_ioctl
* Returned Value : int_32 or error code
* Comments       : Executes ioctl commands
*
*END*--------------------------------------------------------------------*/

int_32 _io_part_mgr_ioctl
    (
    MQX_FILE_PTR   fd_ptr,      /* [IN] the stream to perform the operation on */
    uint_32        cmd,         /* [IN] the ioctl command */
    uint_32_ptr    param_ptr    /* [IN] the ioctl parameters */
    )
{
    PART_MGR_STRUCT_PTR           pm_struct_ptr;
    PMGR_PART_INFO_STRUCT_PTR     part_info_ptr;
    uint_32                       result = MQX_OK;

    pm_struct_ptr = (PART_MGR_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    part_info_ptr = (PMGR_PART_INFO_STRUCT_PTR)fd_ptr->DEV_DATA_PTR;

    switch ( cmd )
    {

        case IO_IOCTL_GET_BLOCK_SIZE:
            *param_ptr = pm_struct_ptr->DEV_SECTOR_SIZE;
            break;

        case IO_IOCTL_GET_NUM_SECTORS:
            *param_ptr = part_info_ptr->LENGTH;
            break;

        case IO_IOCTL_VAL_PART:
            if (param_ptr == NULL)
            {
                /* Validate current partition */
                if (part_info_ptr->START_SECTOR==0 || part_info_ptr->LENGTH==0)
                    result = PMGR_INVALID_PARTITION;
                else
                    result = _pmgr_check_part_type(part_info_ptr->TYPE);
            }
            else if (part_info_ptr->SLOT)
            {
                /* Available only if operating on whole device */
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                break;
            }
            else
            {
                PMGR_PART_INFO_STRUCT part_info;
                _mem_zero(&part_info, sizeof(PMGR_PART_INFO_STRUCT));
                /* In case partition number is 0 the _pmgr_get_part_info function performs just MBR validation */
                part_info.SLOT = *param_ptr;
                _lwsem_wait(&pm_struct_ptr->SEM);
                result = _pmgr_get_part_info(pm_struct_ptr, &part_info);
                _lwsem_post(&pm_struct_ptr->SEM);
                if (!result && part_info.SLOT)
                {
                    result = _pmgr_check_part_type(part_info.TYPE);
                }
            }
            break;

        case IO_IOCTL_SEL_PART:
            if (*param_ptr && part_info_ptr->SLOT)
            {
                /*
                 * Available only if operating on whole device.
                 * This prevents selecting partition multiple times through a single handle,
                 * e.g. if the handle is "recycled" for mutliple MFS instances, which is wrong.
                 * To select a different partition, partition 0 (whole device) has to be selected first
                 */
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                break;
            }
            _mem_zero(part_info_ptr, sizeof(PMGR_PART_INFO_STRUCT));
            if (*param_ptr == 0)
            {
                /* Use size of device as length of the partition */
                part_info_ptr->LENGTH = pm_struct_ptr->DEV_NUM_SECTORS;
            }
            else
            {
                part_info_ptr->SLOT = *param_ptr;
                _lwsem_wait(&pm_struct_ptr->SEM);
                result = _pmgr_get_part_info(pm_struct_ptr, part_info_ptr);
                _lwsem_post(&pm_struct_ptr->SEM);
            }
            /* Reset location to the beginning of the partition/device */
            fd_ptr->LOCATION = 0;
            break;

        case IO_IOCTL_GET_PARTITION:
            if (((PMGR_PART_INFO_STRUCT_PTR)param_ptr)->SLOT == 0)
            {
                /* Get info about current partition */
                _mem_copy(part_info_ptr, param_ptr, sizeof(PMGR_PART_INFO_STRUCT));
                break;
            }
            if (part_info_ptr->SLOT)
            {
                /* Available only if operating on whole device */
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                break;
            }
            _lwsem_wait(&pm_struct_ptr->SEM);
            result = _pmgr_get_part_info(pm_struct_ptr, (PMGR_PART_INFO_STRUCT_PTR) param_ptr);
            _lwsem_post(&pm_struct_ptr->SEM);
            break;

        case IO_IOCTL_SET_PARTITION:
            if (part_info_ptr->SLOT)
            {
                /* Available only if operating on whole device */
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                break;
            }
            _lwsem_wait(&pm_struct_ptr->SEM);
            if (pm_struct_ptr->INSTANCES)
            {
                /* Available if this is the only instance to avoid inconsistencies */
                result = IO_ERROR_DEVICE_BUSY;
            }
            else {
                result = _pmgr_set_part_info(pm_struct_ptr, (PMGR_PART_INFO_STRUCT_PTR) param_ptr);
            }
            _lwsem_post(&pm_struct_ptr->SEM);
            break;

        case IO_IOCTL_CLEAR_PARTITION:
            if (part_info_ptr->SLOT)
            {
                /* Available only if operating on whole device */
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                break;
            }
            _lwsem_wait(&pm_struct_ptr->SEM);
            if (pm_struct_ptr->INSTANCES)
            {
                /* Available if this is the only instance to avoid inconsistencies */
                result = IO_ERROR_DEVICE_BUSY;
            }
            else {
                result = _pmgr_clear_part_info(pm_struct_ptr, *param_ptr);
            }
            _lwsem_post(&pm_struct_ptr->SEM);
            break;

        case IO_IOCTL_USE_PARTITION:
            /*
             * Force switching to area defined by submitted PMGR_PART_INFO_STRUCT,
             * without storing anything to the partition table on the device.
             * This may be useful to divide the device to areas defined elsewhere.
             */
            if (part_info_ptr->SLOT)
            {
                /* Available only if operating on whole device */
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                break;
            }
            _mem_copy(param_ptr, part_info_ptr, sizeof(PMGR_PART_INFO_STRUCT));
            /* Reset location to the beginning of the partition/device */
            fd_ptr->LOCATION = 0;

            break;

        default:
            /* Pass IOCTL command to lower layer */
            result = _io_ioctl(pm_struct_ptr->DEV_FILE_PTR, cmd, param_ptr);
            break;
    }

    fd_ptr->ERROR = pm_struct_ptr->DEV_FILE_PTR->ERROR;

    return result;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  _pmgr_check_part_type
* Returned Value   :  int_32 error code
* Comments  :
*     Checks partition type, returns success if it matches one of the FAT types
*
*END*---------------------------------------------------------------------*/

int_32 _pmgr_check_part_type
    (
        uint_32 part_type
    )
{
    switch (part_type)
    {
        case PMGR_PARTITION_NOT_USED:
            return PMGR_INVALID_PARTITION;

        case PMGR_PARTITION_FAT_12_BIT:
        case PMGR_PARTITION_FAT_16_BIT:
        case PMGR_PARTITION_HUGE:
        case PMGR_PARTITION_HUGE_LBA:
        case PMGR_PARTITION_FAT32:
        case PMGR_PARTITION_FAT32_LBA:
            break;

        default:
            return PMGR_UNKNOWN_PARTITION;
    }
    return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  _pmgr_validate_mbr
* Returned Value   :  int_32 error code
* Comments  :
*     Validates MBR, checks signature and sanity of the partition table
*
*END*---------------------------------------------------------------------*/

int_32 _pmgr_validate_mbr
    (
    char_ptr mbr_ptr
    )
{
    int i, j;
    PMGR_PART_ENTRY_STRUCT_PTR disk_entry;

    uint_32 part_start[PMGR_MAX_PARTITIONS];
    uint_32 part_length[PMGR_MAX_PARTITIONS];

    /* Check partition table signature bytes */
    if (((uint_8_ptr)mbr_ptr)[510]!=0x55 || ((uint_8_ptr)mbr_ptr)[511]!=0xAA)
        return PMGR_INVALID_PARTTABLE;

    disk_entry = (PMGR_PART_ENTRY_STRUCT_PTR)(((uint_8_ptr)mbr_ptr) + PMGR_PARTITION_TABLE_OFFSET);

    for (i=0; i<PMGR_MAX_PARTITIONS; i++)
    {
        part_start[i] = pmgr_dtohl(disk_entry[i].START_SECTOR);
        part_length[i] = pmgr_dtohl(disk_entry[i].LENGTH);

        /* If type is zero, the whole partition entry should be unused (zero) */
        if ((disk_entry[i].TYPE == 0) && (part_length[i] != 0 || part_start[i] != 0))
            return PMGR_INVALID_PARTTABLE;

        /* If type is non-zero, the partition start and length shall contain meaningfull values */
        if ((disk_entry[i].TYPE != 0) && (part_length[i] == 0 || part_start[i] == 0))
            return PMGR_INVALID_PARTTABLE;

        if (part_length[i] == 0)
            continue; /* No overlap check necessary, go for next record */

        /* Check for overlaps */
        for (j=0; j<i; j++)
        {
            if (part_length[j] == 0)
                continue; /* No overlap check necessary, go for next record */

            /*
             * Two partitions do NOT overlap if: start of one is behind end of the other OR vice versa.
             * The condition below is negation of this sentence.
             */
            if ((part_start[i] < part_start[j] + part_length[j]) && (part_start[i] + part_length[i] > part_start[j]))
                return PMGR_INVALID_PARTTABLE;
        }
    }

    return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  _pmgr_get_part_info
* Returned Value   :  int_32 error code
* Comments  :
*     Read the partition table entry from disk
*
*END*---------------------------------------------------------------------*/

int_32 _pmgr_get_part_info
    (
    PART_MGR_STRUCT_PTR        pm_struct_ptr,   /*[IN] the partition manager information */
    PMGR_PART_INFO_STRUCT_PTR  host_entry       /*[IN]/[OUT] the entry to read from disk */
    )
{
    int_32                       error_code = MQX_OK;
    char_ptr                     mbr_ptr;
    int_32                       size;
    PMGR_PART_ENTRY_STRUCT_PTR   disk_entry;

    mbr_ptr =  MFS_mem_alloc_system(pm_struct_ptr->DEV_SECTOR_SIZE);
    if ( mbr_ptr == NULL )
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type(mbr_ptr, MEM_TYPE_PART_MGR_SECTOR);

    size = pm_struct_ptr->BLOCK_MODE ? 1 : pm_struct_ptr->DEV_SECTOR_SIZE;

    fseek(pm_struct_ptr->DEV_FILE_PTR, 0, IO_SEEK_SET);
    if (read(pm_struct_ptr->DEV_FILE_PTR, mbr_ptr, size) != size)
    {
        error_code = pm_struct_ptr->DEV_FILE_PTR->ERROR;
    }
    else
    {
        error_code = _pmgr_validate_mbr(mbr_ptr);
    }

    if (!error_code && host_entry && host_entry->SLOT)
    {
        if (host_entry->SLOT > PMGR_MAX_PARTITIONS)
        {
            error_code = PMGR_INVALID_PARTITION;
        }
        else {
            disk_entry = (PMGR_PART_ENTRY_STRUCT_PTR)(mbr_ptr + PMGR_PARTITION_TABLE_OFFSET);
            _pmgr_disk_to_host(disk_entry + host_entry->SLOT - 1, host_entry);
            if (host_entry->TYPE == 0 || host_entry->START_SECTOR == 0 || host_entry->LENGTH == 0)
            {
                error_code = PMGR_INVALID_PARTITION;
            }
        }
    }

    _mem_free(mbr_ptr);
    return error_code;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  _pmgr_set_part_info
* Returned Value   :  int_32 error code
* Comments  :
*     Will overwrite the partition table entry with the new information
*     received (if opcode == 0). If the opcode is a partition number, this
*     function will clear that partition. Will return error code upon error.
*
*END*---------------------------------------------------------------------*/

int_32 _pmgr_set_part_info
    (
    PART_MGR_STRUCT_PTR        pm_struct_ptr,   /*[IN] the partitionn manager information */
    PMGR_PART_INFO_STRUCT_PTR  host_entry       /*[IN] the entry to write to disk */
    )
{
    int_32                       error_code = MQX_OK;
    char_ptr                     mbr_ptr;
    int_32                       size;
    PMGR_PART_ENTRY_STRUCT_PTR   disk_entry;

    if (!host_entry || host_entry->SLOT==0 || host_entry->SLOT>PMGR_MAX_PARTITIONS)
    {
        return PMGR_INVALID_PARTITION;
    }

    mbr_ptr =  MFS_mem_alloc_system(pm_struct_ptr->DEV_SECTOR_SIZE);
    if ( mbr_ptr == NULL )
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type(mbr_ptr, MEM_TYPE_PART_MGR_SECTOR);

    size = pm_struct_ptr->BLOCK_MODE ? 1 : pm_struct_ptr->DEV_SECTOR_SIZE;

    fseek(pm_struct_ptr->DEV_FILE_PTR, 0, IO_SEEK_SET);
    if (read(pm_struct_ptr->DEV_FILE_PTR, mbr_ptr, size) != size)
    {
        error_code = pm_struct_ptr->DEV_FILE_PTR->ERROR;
    }
    else
    {
        error_code = _pmgr_validate_mbr(mbr_ptr);
    }

    if (!error_code)
    {
        disk_entry = (PMGR_PART_ENTRY_STRUCT_PTR)(mbr_ptr + PMGR_PARTITION_TABLE_OFFSET);
        _pmgr_host_to_disk(host_entry, disk_entry + host_entry->SLOT - 1);
        error_code = _pmgr_validate_mbr(mbr_ptr); /* Check sanity of modified MBR */
        if (!error_code)
        {
            fseek(pm_struct_ptr->DEV_FILE_PTR, 0, IO_SEEK_SET);
            if (write(pm_struct_ptr->DEV_FILE_PTR, mbr_ptr, size) != size)
            {
                error_code = pm_struct_ptr->DEV_FILE_PTR->ERROR;
            }
        }
    }

    _mem_free(mbr_ptr);
    return error_code;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  _pmgr_clear_part_info
* Returned Value   :  int_32 error code
* Comments  :
*     Clears partition information for given partition
*
*END*---------------------------------------------------------------------*/

int_32 _pmgr_clear_part_info
    (
    PART_MGR_STRUCT_PTR        pm_struct_ptr,   /*[IN] the partitionn manager information */
    uchar                      part_num         /*[IN] the partition to clear */
    )
{
    int_32                       error_code = MQX_OK;
    char_ptr                     mbr_ptr;
    int_32                       size;
    PMGR_PART_ENTRY_STRUCT_PTR   disk_entry;

    if (part_num>PMGR_MAX_PARTITIONS)
    {
        return PMGR_INVALID_PARTITION;
    }

    mbr_ptr =  MFS_mem_alloc_system(pm_struct_ptr->DEV_SECTOR_SIZE);
    if ( mbr_ptr == NULL )
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type(mbr_ptr, MEM_TYPE_PART_MGR_SECTOR);

    size = pm_struct_ptr->BLOCK_MODE ? 1 : pm_struct_ptr->DEV_SECTOR_SIZE;

    fseek(pm_struct_ptr->DEV_FILE_PTR, 0, IO_SEEK_SET);
    if (read(pm_struct_ptr->DEV_FILE_PTR, mbr_ptr, size) != size)
    {
        error_code = pm_struct_ptr->DEV_FILE_PTR->ERROR;
    }
    else
    {
        error_code = _pmgr_validate_mbr(mbr_ptr);
    }

    if (error_code == PMGR_INVALID_PARTITION && part_num == 0)
    {
        /* Create blank MBR */
        _mem_zero(mbr_ptr, pm_struct_ptr->DEV_SECTOR_SIZE);
        mbr_ptr[510] = 0x55;
        mbr_ptr[511] = 0xAA;
        error_code = 0;
    }
    else if (!error_code)
    {
        disk_entry = (PMGR_PART_ENTRY_STRUCT_PTR)(mbr_ptr + PMGR_PARTITION_TABLE_OFFSET);
        if (!part_num)
        {
            _mem_zero(disk_entry, PMGR_MAX_PARTITIONS*sizeof(PMGR_PART_ENTRY_STRUCT));
        }
        else
        {
            _mem_zero(disk_entry + part_num - 1, sizeof(PMGR_PART_ENTRY_STRUCT));
        }
    }

    if (!error_code)
    {
        fseek(pm_struct_ptr->DEV_FILE_PTR, 0, IO_SEEK_SET);
        if ( write(pm_struct_ptr->DEV_FILE_PTR, mbr_ptr, size) != size )
        {
            error_code = pm_struct_ptr->DEV_FILE_PTR->ERROR;
        }
    }

    _mem_free(mbr_ptr);
    return error_code;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  _pmgr_disk_to_host
* Returned Value   :  void
* Comments  :
*     Will copy a partition table entry from its disk format to a host format
*
*END*---------------------------------------------------------------------*/


void _pmgr_disk_to_host
    (
    PMGR_PART_ENTRY_STRUCT_PTR   disk_entry,  /*[IN] ptr to a partition table entry in disk format */
    PMGR_PART_INFO_STRUCT_PTR    part_entry   /*[OUT] ptr to a partition table entry in a more usable format */
    )
{
    part_entry->TYPE = disk_entry->TYPE;
    part_entry->ACTIVE_FLAG = disk_entry->ACTIVE_FLAG;
    part_entry->START_SECTOR = pmgr_dtohl(disk_entry->START_SECTOR);
    part_entry->LENGTH = pmgr_dtohl(disk_entry->LENGTH);
    part_entry->HEADS = 0;
    part_entry->SECTORS = 0;
    part_entry->CYLINDERS = 0;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  _pmgr_host_to_disk
* Returned Value   :  void
* Comments  :
*     Will copy a partition table entry from its host format to the disk format
*
*END*---------------------------------------------------------------------*/

void _pmgr_host_to_disk
    (
    PMGR_PART_INFO_STRUCT_PTR              part_entry,  /*[IN] ptr to a partition table entry in a usable format */
    PMGR_PART_ENTRY_STRUCT_PTR             disk_entry   /*[OUT] ptr to a partition table entry in disk format */
    )
{
    uint_32     temp,cyl,head,sec,hds_cyl,sct_trk,lba;

    disk_entry->ACTIVE_FLAG = 0;
    disk_entry->TYPE = part_entry->TYPE;
    pmgr_htodl(disk_entry->START_SECTOR, part_entry->START_SECTOR);
    pmgr_htodl(disk_entry->LENGTH, part_entry->LENGTH);

    /* Check if CHS is present and valid */
    if ( !part_entry->CYLINDERS || !part_entry->HEADS || !part_entry->SECTORS || part_entry->CYLINDERS>1024 || part_entry->SECTORS>63 )
    {
        disk_entry->START_HEAD = 0;
        disk_entry->START_SECT_CYL = 0;
        disk_entry->START_CYLINDER = 0;
        disk_entry->ENDING_HEAD = 0;
        disk_entry->ENDING_SECT_CYL = 0;
        disk_entry->ENDING_CYLINDER = 0;
    }
    else
    {
        /* setup info used for calculations */
        sct_trk = part_entry->SECTORS;
        hds_cyl = part_entry->HEADS;

        /* Calculate starting CHS */
        lba = part_entry->START_SECTOR;
        cyl = lba / (hds_cyl * sct_trk);
        temp = lba % (hds_cyl * sct_trk);
        head = temp / sct_trk;
        sec = temp % sct_trk + 1;

        if (cyl>1023)
        {
            /* Indicate invalid CHS entry */
            disk_entry->START_HEAD = 254;
            disk_entry->START_SECT_CYL = 0xFF;
            disk_entry->START_CYLINDER = 0xFF;
        }
        else
        {
            disk_entry->START_HEAD = (uchar) head;
            disk_entry->START_SECT_CYL = (uchar) ((sec & 0x3f) + ((cyl & 0x0300) >> 2));
            disk_entry->START_CYLINDER = (uchar) (cyl & 0x0FF);
        }

        /* Calculate the ending CHS */
        lba = part_entry->LENGTH + part_entry->START_SECTOR;
        cyl = lba / (hds_cyl * sct_trk);
        temp = lba % (hds_cyl * sct_trk);
        head = temp / sct_trk;
        sec = temp % sct_trk + 1;

        if (cyl>1023)
        {
            /* Indicate invalid CHS entry */
            disk_entry->ENDING_HEAD = 254;
            disk_entry->ENDING_SECT_CYL = 0xFF;
            disk_entry->ENDING_CYLINDER = 0xFF;
        }
        else
        {
            disk_entry->ENDING_HEAD = (uchar) head;
            disk_entry->ENDING_SECT_CYL = (uchar) ((sec & 0x3f) + ((cyl & 0x0300) >> 2));
            disk_entry->ENDING_CYLINDER = (uchar) (cyl & 0x0FF);
        }
    }
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_Timer.h<|end_filename|>
/***********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
*********************************************************************************************************************//*!
*
* @file   TSS_Timer.h
*
* @brief  Functions prototypes, constants, variables and macros for control and configuration of the HW timer 
*
* @version 1.0.42.0
* 
* @date Sep-12-2012
* 
*
***********************************************************************************************************************/


#ifndef TSS_TIMER_H
  #define TSS_TIMER_H

  #include "TSS_SensorGPIO.h"
  #include "TSS_SensorTSI.h"
  #include "TSS_SensorTSIL.h"

  #include "TSS_Sensor.h"

  /* Recognition if HW Timer is used */
  #if (TSS_HW_TIMER_USED == 0)
    #ifdef TSS_HW_TIMER
      #undef TSS_HW_TIMER
    #endif
    #define TSS_HW_TIMER              HW_TIMER_UNUSED
  #endif

  /*********** HW Timer Availability Macros **********/

  #define TSS_HW_TIMER_UNUSED_CHK       0xFF
  #define TSS_TPM_CHK                   0x01
  #define TSS_TPM1_CHK                  0x02
  #define TSS_TPM2_CHK                  0x03
  #define TSS_TPM3_CHK                  0x04
  #define TSS_TPM4_CHK                  0x05
  #define TSS_FTM_CHK                   0x06
  #define TSS_FTM1_CHK                  0x07
  #define TSS_FTM2_CHK                  0x08
  #define TSS_FTM3_CHK                  0x09
  #define TSS_FTM4_CHK                  0x0A
  #define TSS_MTIM_CHK                  0x0B
  #define TSS_MTIM1_CHK                 0x0C
  #define TSS_MTIM2_CHK                 0x0D
  #define TSS_MTIM3_CHK                 0x0E
  #define TSS_MTIM4_CHK                 0x0F
  #define TSS_TPM0_CHK                  0x10
  #define TSS_FTM0_CHK                  0x11
  #define TSS_MTIM0_CHK                 0x12
  
  /* Timer Availability Macros */
  #define TSS_HW_TIMER2NAME_RESULT(res)      TSS_##res##_CHK
  #define TSS_HW_TIMER2NAME_CONV(text)       TSS_HW_TIMER2NAME_RESULT(text)
  #define TSS_HW_TIMER_CHK(name)             TSS_HW_TIMER2NAME_CONV(name)

  /* Determination what Timer module is used for later conditional Timer module initialization */
  #define TSS_TPM_HW_TIMER_USED         (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_TPM_CHK)
  #define TSS_TPM0_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_TPM0_CHK)
  #define TSS_TPM1_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_TPM1_CHK)
  #define TSS_TPM2_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_TPM2_CHK)
  #define TSS_TPM3_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_TPM3_CHK)
  #define TSS_TPM4_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_TPM4_CHK)
  #define TSS_FTM_HW_TIMER_USED         (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_FTM_CHK)
  #define TSS_FTM0_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_FTM0_CHK)
  #define TSS_FTM1_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_FTM1_CHK)
  #define TSS_FTM2_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_FTM2_CHK)
  #define TSS_FTM3_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_FTM3_CHK)
  #define TSS_FTM4_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_FTM4_CHK)
  #define TSS_MTIM_HW_TIMER_USED        (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_MTIM_CHK)
  #define TSS_MTIM0_HW_TIMER_USED       (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_MTIM0_CHK)
  #define TSS_MTIM1_HW_TIMER_USED       (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_MTIM1_CHK)
  #define TSS_MTIM2_HW_TIMER_USED       (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_MTIM2_CHK)
  #define TSS_MTIM3_HW_TIMER_USED       (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_MTIM3_CHK)
  #define TSS_MTIM4_HW_TIMER_USED       (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_MTIM4_CHK)

  #define TSS_HW_TIMER_IS_MTIM          (TSS_MTIM_HW_TIMER_USED || TSS_MTIM0_HW_TIMER_USED || TSS_MTIM1_HW_TIMER_USED || TSS_MTIM2_HW_TIMER_USED || TSS_MTIM3_HW_TIMER_USED || TSS_MTIM4_HW_TIMER_USED)
  #define TSS_HW_TIMER_IS_TPM           (TSS_TPM_HW_TIMER_USED || TSS_TPM0_HW_TIMER_USED || TSS_TPM1_HW_TIMER_USED || TSS_TPM2_HW_TIMER_USED || TSS_TPM3_HW_TIMER_USED || TSS_TPM4_HW_TIMER_USED)
  #define TSS_HW_TIMER_IS_FTM           (TSS_FTM_HW_TIMER_USED || TSS_FTM0_HW_TIMER_USED || TSS_FTM1_HW_TIMER_USED || TSS_FTM2_HW_TIMER_USED || TSS_FTM3_HW_TIMER_USED || TSS_FTM4_HW_TIMER_USED)

  #define TSS_DETECT_HW_TIMER(name)     TSS_##name##_HW_TIMER_USED

  /*******************************************************
  ****          HW Timer Global defintions            ****
  *******************************************************/

  #if TSS_TPM_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              TPM_BASE_PTR
      #define TSS_HW_TIMER_VECTOR           INT_TPM
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vtpmovf
    #endif
  #elif TSS_TPM0_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              TPM0_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_TPM0
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vtpm0ovf
    #endif
  #elif TSS_TPM1_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              TPM1_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_TPM1
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vtpm1ovf
    #endif
  #elif TSS_TPM2_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              TPM2_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_TPM2
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vtpm2ovf
    #endif
  #elif TSS_TPM3_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              TPM3_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_TPM3
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vtpm3ovf
    #endif
  #elif TSS_TPM4_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              TPM4_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_TPM4
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vtpm4ovf
    #endif
  #elif TSS_FTM_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              FTM_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_FTM
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vftmovf
    #endif
  #elif TSS_FTM0_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              FTM0_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_FTM0
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vftm0ovf
    #endif
  #elif TSS_FTM1_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              FTM1_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_FTM1
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vftm1ovf
    #endif
  #elif TSS_FTM2_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              FTM2_BASE_PTR
      #define TSS_HW_TIMER_VECTOR           INT_FTM2
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vftm2ovf
    #endif
  #elif TSS_FTM3_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              FTM3_BASE_PTR
      #define TSS_HW_TIMER_VECTOR           INT_FTM3
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vftm3ovf
    #endif
  #elif TSS_FTM4_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              FTM4_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_TPM4
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vftm4ovf
    #endif
  #elif TSS_MTIM_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              MTIM_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_MTIM
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vmtim
    #endif
  #elif TSS_MTIM0_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              MTIM0_BASE_PTR
      #define TSS_HW_TIMER_VECTOR           INT_MTIM0
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vmtim0
    #endif
  #elif TSS_MTIM1_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU 
      #define TSS_HW_TIMER_PTR              MTIM1_BASE_PTR
      #define TSS_HW_TIMER_VECTOR           INT_MTIM1
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vmtim1
    #endif
  #elif TSS_MTIM2_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU
      #define TSS_HW_TIMER_PTR              MTIM2_BASE_PTR    
      #define TSS_HW_TIMER_VECTOR           INT_MTIM2
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vmtim2
    #endif
  #elif TSS_MTIM3_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU
      #define TSS_HW_TIMER_PTR              MTIM3_BASE_PTR        
      #define TSS_HW_TIMER_VECTOR           INT_MTIM3
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vmtim3
    #endif
  #elif TSS_MTIM4_HW_TIMER_USED
    #if TSS_KINETIS_MCU || TSS_CFM_MCU
      #define TSS_HW_TIMER_PTR              MTIM4_BASE_PTR        
      #define TSS_HW_TIMER_VECTOR           INT_MTIM4
    #else
      #define TSS_HW_TIMER_PTR              TSS_HW_TIMER_ADDRESS
      #define TSS_HW_TIMER_VECTOR           VectorNumber_Vmtim4
    #endif
  #endif

  /*******************************************************
   *** Validation of TSS_SystemSetup.h Timer Setttings ***
   *******************************************************/

  #if TSS_HW_TIMER_USED
    #ifndef TSS_HW_TIMER
      #error "TSS - Not defined TSS_HW_TIMER"
    #endif
  #endif

  #if TSS_USE_IIR_FILTER
    #if TSS_HW_TIMER_IS_MTIM
      #if (TSS_SENSOR_TIMEOUT > 0xFFu)
        #error "TSS - TSS_SENSOR_TIMEOUT exceeded maximum value 0xFF for MTIM timer"
      #endif
      #if (TSS_SENSOR_PROX_TIMEOUT > 0xFFu)
        #error "TSS - TSS_SENSOR_PROX_TIMEOUT exceeded maximum value 0xFF for MTIM timer"
      #endif
    #else
      #if TSS_HCS08_MCU
        #if (TSS_SENSOR_TIMEOUT > 0x1FFu)
          #error "TSS - TSS_SENSOR_TIMEOUT exceeded maximum value 0x1FF with IIR Filter enabled"
        #endif
        #if (TSS_SENSOR_PROX_TIMEOUT > 0x1FFu)
          #error "TSS - TSS_SENSOR_PROX_TIMEOUT exceeded maximum value 0x1FF with IIR Filter enabled"
        #endif
      #else
        #if (TSS_SENSOR_TIMEOUT > 0xFFFFu)
          #error "TSS - TSS_SENSOR_TIMEOUT exceeded maximum value 0xFFFF"
        #endif
        #if (TSS_SENSOR_PROX_TIMEOUT > 0xFFFFu)
          #error "TSS - TSS_SENSOR_PROX_TIMEOUT exceeded maximum value 0xFFFF"
        #endif
      #endif 
    #endif  
  #else 
    #if TSS_HW_TIMER_IS_MTIM
      #if (TSS_SENSOR_TIMEOUT > 0xFFu)
        #error "TSS - TSS_SENSOR_TIMEOUT exceeded maximum value 0xFF for MTIM timer"
      #endif
      #if (TSS_SENSOR_PROX_TIMEOUT > 0xFFu)
        #error "TSS - TSS_SENSOR_PROX_TIMEOUT exceeded maximum value 0xFF for MTIM timer"
      #endif
    #else
      #if TSS_HCS08_MCU
        #if (TSS_SENSOR_TIMEOUT > 0x7FFu)
          #error "TSS - TSS_SENSOR_TIMEOUT exceeded maximum value 0x7FF with IIR Filter disabled"
        #endif
        #if (TSS_SENSOR_PROX_TIMEOUT > 0x7FFu)
          #error "TSS - TSS_SENSOR_PROX_TIMEOUT exceeded maximum value 0x7FF with IIR Filter disabled"
        #endif
      #else
        #if (TSS_SENSOR_TIMEOUT > 0xFFFFu)
          #error "TSS - TSS_SENSOR_TIMEOUT exceeded maximum value 0xFFFF"
        #endif
        #if (TSS_SENSOR_PROX_TIMEOUT > 0xFFFFu)
          #error "TSS - TSS_SENSOR_PROX_TIMEOUT exceeded maximum value 0xFFFF"
        #endif
      #endif 
    #endif  
  #endif

  #if TSS_KINETIS_MCU  || TSS_CFM_MCU || (TSS_USE_SIMPLE_LOW_LEVEL == 0) /* Kinetis  || TSS_CFM_MCU */
    #if TSS_HW_TIMER_IS_MTIM
      #error "TSS - MTIM timer is not supported on the MCU "
    #endif
  #endif

  /*******************************************************
   ************ HW Timer Macros Definitions ***********
   *******************************************************/

  /* Timer name convert macros */
  #if TSS_KINETIS_MCU  || TSS_CFM_MCU /* Kinetis  || TSS_CFM_MCU */
    #define TSS_HW_TIMER_TO_SC(reg)          reg##_SC
  #else
    #if (TSS_TIMER_VERSION == 1)
      #define TSS_HW_TIMER_TO_SC(reg)        reg##SC
    #elif (TSS_TIMER_VERSION == 2)
      #define TSS_HW_TIMER_TO_SC(reg)        reg##_SC
    #endif    
  #endif

  #define TSS_GET_HW_TIMER_SC(name)          TSS_HW_TIMER_TO_SC(name)

  /* Addresses of all the configuration timer registers */
  #define TSS_HW_TIMER_ADDRESS               &TSS_GET_HW_TIMER_SC(TSS_HW_TIMER)  /* The address of the Timer is assigned by the compiler */

  /************** MCU Exceptions solving *************/
  
  /* QD4 exception */
  #ifdef TPMSC_TOF_MASK
    #ifndef TPM1SC_TOF_MASK
      #if (TSS_HW_TIMER_CHK(TSS_HW_TIMER) == TSS_TPM1_CHK)
        #undef TSS_HW_TIMER
        #define TSS_HW_TIMER                 TPM       
      #endif
    #endif
  #endif

  /********* Specific Timer related macros ***********/

  /* MTIM HW Timer configuration values */
  #define TSS_HW_MTIM_IE                   0x40U 
  #define TSS_HW_MTIM_FLAG                 0x80U 
  #define TSS_HW_MTIM_ON                   0xEFU 
  #define TSS_HW_MTIM_OFF                  0x10U 
  #define TSS_HW_MTIM_CNT_AND_FLAG_RESET   0x20U 
  #define TSS_HW_MTIM_PRESCALE_MASK        0x0FU 

  #define TSS_HW_MTIM_SC                   *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+0) 
  #define TSS_HW_MTIM_CLK                  *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+1)
  #define TSS_HW_MTIM_CNT                  *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+2)
  #define TSS_HW_MTIM_MOD                  *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+3)

  /* HW Timer configuration values */
  #define TSS_HW_TPMFTM_PRESCALE_MASK        0x07U
  #define TSS_HW_TPMFTM_IE                   0x40U
  #define TSS_HW_TPMFTM_FLAG                 0x80U
  #define TSS_HW_TPMFTM_ON                   0x08U
  #define TSS_HW_TPMFTM_OFF                  0xE7U
  #define TSS_HW_TPMFTM_FLAG_ACK             0x7FU

  #if TSS_KINETIS_MCU || TSS_CFM_MCU
    #define TSS_HW_TPMFTM_SC                 *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+0) 
    #define TSS_HW_TPMFTM_CNT                *(volatile UINT16 *)(TSS_HW_TIMER_ADDRESS+1)
    #define TSS_HW_TPMFTM_MOD                *(volatile UINT16 *)(TSS_HW_TIMER_ADDRESS+2)
  #else 
    #define TSS_HW_TPMFTM_SC                 *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+0) 
    #define TSS_HW_TPMFTM_CNT                *(volatile UINT16 *)(TSS_HW_TIMER_ADDRESS+1)
    #define TSS_HW_TPMFTM_CNTH               *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+1)
    #define TSS_HW_TPMFTM_CNTL               *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+2)
    #define TSS_HW_TPMFTM_MOD                *(volatile UINT16 *)(TSS_HW_TIMER_ADDRESS+3)
    #define TSS_HW_TPMFTM_MODH               *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+3)
    #define TSS_HW_TPMFTM_MODL               *(volatile UINT8  *)(TSS_HW_TIMER_ADDRESS+4)
  #endif

  /*! TPM and FTM - Peripheral register structure */
  #if TSS_HCS08_MCU || TSS_CFV1_MCU  || TSS_CFM_MCU
    #ifdef __COLDFIRE__
      #pragma pack(1) 
    #endif
    typedef struct TPMFTM_MemMap {
      UINT8 SC;
      union {
          UINT16 Word;
          UINT8 Byte[2];
      } CNT; 
      union {
          UINT16 Word;
         UINT8 Byte[2];
      } MOD; 
    } volatile *TSS_TPMFTM_MemMapPtr;
  #elif TSS_KINETIS_MCU
    typedef struct TPMFTM_MemMap {
      UINT32 SC;
      UINT32 CNT;
      UINT32 MOD;
    } volatile *TSS_TPMFTM_MemMapPtr;
  #endif
  
  #if (TSS_HW_TIMER_IS_MTIM)
    
    /*******************************************************
     ******************* MTIM HW Timer Macros **************
     *******************************************************/

    #define TSS_HW_TIMER_SET_PRESCALE(x)     (TSS_HW_MTIM_CLK = ((UINT8)(TSS_HW_MTIM_CLK & ((UINT8)(~(UINT8)TSS_HW_MTIM_PRESCALE_MASK)))) | (x))   /*Changed due to MISRA*/
    
    #define TSS_HW_TIMER_ENABLE_INT()        (TSS_HW_MTIM_SC |= TSS_HW_MTIM_IE)
    #define TSS_HW_TIMER_DISABLE_INT()       TSS_HW_MTIM_SC &= ~TSS_HW_MTIM_IE
    #define TSS_HW_TIMER_SET_MOD(x)          (TSS_HW_MTIM_MOD = x)
    #define TSS_HW_TIMER_GET_MOD()           TSS_HW_MTIM_MOD
    #define TSS_HW_TIMER_START()             (TSS_HW_MTIM_SC &= TSS_HW_MTIM_ON)
    #define TSS_HW_TIMER_STOP()              (TSS_HW_MTIM_SC |= TSS_HW_MTIM_OFF)
    #define TSS_HW_TIMER_RESET()             TSS_HW_MTIM_SC |= TSS_HW_MTIM_CNT_AND_FLAG_RESET
    #define TSS_HW_TIMER_GET_LOWCNT()        TSS_HW_MTIM_CNT             
    #define TSS_HW_TIMER_GET_CNT()           TSS_HW_MTIM_CNT

    #define TSS_HW_TIMER_CLEARFLAG()         TSS_HW_MTIM_SC |= TSS_HW_MTIM_CNT_AND_FLAG_RESET;
    #define TSS_HW_TIMER_OVF_FLAG()          (TSS_HW_MTIM_SC & TSS_HW_MTIM_FLAG)
    
  #else 

    /*******************************************************
     ************* TPM/FTM HW Timer Tasks Macros ***********
     *******************************************************/
    
    #define TSS_HW_TIMER_SET_PRESCALE(x)     (TSS_HW_TPMFTM_SC = (UINT8)((TSS_HW_TPMFTM_SC & (~TSS_HW_TPMFTM_PRESCALE_MASK)) | (x)))   /*Changed due to MISRA*/
    #define TSS_HW_TIMER_ENABLE_INT()        (TSS_HW_TPMFTM_SC |= TSS_HW_TPMFTM_IE)
    #define TSS_HW_TIMER_DISABLE_INT()       TSS_HW_TPMFTM_SC &= ~TSS_HW_TPMFTM_IE
    #define TSS_HW_TIMER_SET_MOD(x)          (TSS_HW_TPMFTM_MOD = x)
    #define TSS_HW_TIMER_GET_MOD()           TSS_HW_TPMFTM_MOD
    #define TSS_HW_TIMER_START()             (TSS_HW_TPMFTM_SC |= TSS_HW_TPMFTM_ON)
    #define TSS_HW_TIMER_STOP()              (TSS_HW_TPMFTM_SC &= TSS_HW_TPMFTM_OFF)
    #define TSS_HW_TIMER_RESET()             (TSS_HW_TPMFTM_CNT = 0x0000U)
    #define TSS_HW_TIMER_GET_LOWCNT()        TSS_HW_TPMFTM_CNTL             
    #define TSS_HW_TIMER_GET_HICNT()         TSS_HW_TPMFTM_CNTH             
    #define TSS_HW_TIMER_GET_CNT()           TSS_HW_TPMFTM_CNT

    #define TSS_HW_TIMER_CLEARFLAG()         TSS_HW_TPMFTM_SC &= TSS_HW_TPMFTM_FLAG_ACK;
    #define TSS_HW_TIMER_OVF_FLAG()          (TSS_HW_TPMFTM_SC & TSS_HW_TPMFTM_FLAG)

  #endif

#endif /* TSS_TIMER_H */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi_legacy/int/spi_int.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_int.c$
* $Version : 3.8.14.0$
* $Date    : Aug-30-2011$
*
* Comments:
*
*   This file contains the SPI interrupt I/O driver functions.
*
*END************************************************************************/

#include <mqx_inc.h>
#include <fio.h>
#include <fio_prv.h>
#include <io.h>
#include <io_prv.h>
#include "spi.h"
#include "spi_pol_prv.h"
#include "spi_int_prv.h"

/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_int_install
* Returned Value   : MQX error code
* Comments         :
*    Install the interrupt SPI device.
*
*END**********************************************************************/
_mqx_uint _io_spi_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr              identifier,
  
      /* [IN] The I/O init function */
      _mqx_uint (_CODE_PTR_ init)(pointer,char _PTR_),

      /* [IN] The enable interrupts function */
      _mqx_uint (_CODE_PTR_ enable_ints)(pointer),
      
      /* [IN] The I/O de-init function */
      _mqx_uint (_CODE_PTR_ deinit)(pointer, pointer),
      
      /* [IN] The input function */
      _mqx_int  (_CODE_PTR_ recv)(pointer, char _PTR_, _mqx_int),
     
      /* [IN] The output function */
      _mqx_int  (_CODE_PTR_ xmit)(pointer, char _PTR_, _mqx_int),

      /* [IN] The I/O ioctl function */
      _mqx_int  (_CODE_PTR_ ioctl)(pointer, _mqx_uint, _mqx_uint_ptr, _mqx_uint),

      /* [IN] The I/O init data pointer */
      pointer               init_data_ptr
      
   )
{ /* Body */
   IO_SPI_INT_DEVICE_STRUCT_PTR int_dev_ptr;

   int_dev_ptr = (IO_SPI_INT_DEVICE_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(IO_SPI_INT_DEVICE_STRUCT));
   if (int_dev_ptr == NULL) 
   {
      return(MQX_OUT_OF_MEMORY);
   }
   _mem_set_type(int_dev_ptr,MEM_TYPE_IO_SPI_INT_DEVICE_STRUCT);       

   int_dev_ptr->DEV_INIT          = init;
   int_dev_ptr->DEV_DEINIT        = deinit;
   int_dev_ptr->DEV_ENABLE_INTS   = enable_ints;
   int_dev_ptr->DEV_READ          = recv;
   int_dev_ptr->DEV_WRITE         = xmit;
   int_dev_ptr->DEV_IOCTL         = ioctl;
   int_dev_ptr->DEV_INIT_DATA_PTR = init_data_ptr;
   
   return (_io_dev_install_ext(identifier,
      _io_spi_int_open, _io_spi_int_close,
      _io_spi_int_read, 
      _io_spi_int_write, 
      _io_spi_int_ioctl, _io_spi_int_uninstall,
      (pointer)int_dev_ptr));
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_int_uninstall
* Returned Value   : MQX error code
* Comments         :
*    Uninstall the interrupt SPI device.
*
*END**********************************************************************/
_mqx_int _io_spi_int_uninstall
   (
      /* [IN] The IO device structure for the device */
      IO_DEVICE_STRUCT_PTR      io_dev_ptr
   )
{ /* Body */
   IO_SPI_INT_DEVICE_STRUCT_PTR int_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

   if (int_dev_ptr->COUNT == 0) 
   {
      if (int_dev_ptr->DEV_DEINIT) 
      {
         (*int_dev_ptr->DEV_DEINIT)(int_dev_ptr->DEV_INIT_DATA_PTR, int_dev_ptr->DEV_INFO_PTR);
      }
      _mem_free(int_dev_ptr);
      io_dev_ptr->DRIVER_INIT_PTR = NULL;
      return IO_OK;
   } 
   else 
   {
      return IO_ERROR_DEVICE_BUSY;
   }
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_int_open
* Returned Value   : MQX error code
* Comments         :
*    This routine initializes the SPI I/O channel. It acquires
*    memory, then stores information into it about the channel.
*    It then calls the hardware interface function to initialize the channel.
* 
*END**********************************************************************/
_mqx_int _io_spi_int_open
   (
      /* [IN] The file handle for the device being opened */
      FILE_DEVICE_STRUCT_PTR         fd_ptr,
       
      /* [IN] The remaining portion of the name of the device */
      char                     _PTR_ open_name_ptr,

      /* [IN] The flags to be used during operation */
      char                     _PTR_ flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR              io_dev_ptr;
   IO_SPI_INT_DEVICE_STRUCT_PTR      int_dev_ptr;
   _mqx_int                          result = MQX_OK;

   io_dev_ptr  = (IO_DEVICE_STRUCT_PTR)(fd_ptr->DEV_PTR);
   int_dev_ptr = (IO_SPI_INT_DEVICE_STRUCT_PTR)(io_dev_ptr->DRIVER_INIT_PTR);

   _int_disable();
   if (int_dev_ptr->COUNT) 
   {
      result = MQX_IO_OPERATION_NOT_AVAILABLE;
      _int_enable();
      return result;
   }
   int_dev_ptr->COUNT = 1;
   _int_enable();
      
   int_dev_ptr->FLAGS = (_mqx_uint)flags;
   fd_ptr->FLAGS      = (_mqx_uint)flags;
            
   result = (*int_dev_ptr->DEV_INIT)(int_dev_ptr, open_name_ptr);
   if (result == MQX_OK) 
   {
      result = (*int_dev_ptr->DEV_ENABLE_INTS)(int_dev_ptr->DEV_INFO_PTR);
   } 
   if (result != MQX_OK) 
   {
      int_dev_ptr->COUNT = 0;
   }
   return result;
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_int_close
* Returned Value   : MQX error code
* Comments         :
*    This routine closes the SPI I/O channel.
* 
*END**********************************************************************/
_mqx_int _io_spi_int_close
   (
      /* [IN] The file handle for the device being closed */
      FILE_DEVICE_STRUCT_PTR    fd_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR         io_dev_ptr;
   IO_SPI_INT_DEVICE_STRUCT_PTR int_dev_ptr;
   _mqx_int                     result = MQX_OK;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   int_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   _int_disable();
   if (--int_dev_ptr->COUNT == 0) 
   {
      if (int_dev_ptr->DEV_DEINIT) 
      {
         result = (*int_dev_ptr->DEV_DEINIT)(int_dev_ptr, int_dev_ptr->DEV_INFO_PTR);
      }
   }
   _int_enable();
   return result;
} /* Endbody */
  
/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_int_read
* Returned Value   : Number of bytes read
* Comments         :
*    Reads bytes into array from SPI input buffers.
*    Returns number of bytes received.
*
*END*********************************************************************/
_mqx_int _io_spi_int_read
   (
      /* [IN] The handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR          fd_ptr,

      /* [OUT] Where the characters are to be stored */
      char_ptr                        data_ptr,

      /* [IN] The number of bytes to read */
      _mqx_int                        n
   )
{  /* Body */
   IO_DEVICE_STRUCT_PTR               io_dev_ptr;
   IO_SPI_INT_DEVICE_STRUCT_PTR       int_dev_ptr;
   
   io_dev_ptr  = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   int_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   return (*int_dev_ptr->DEV_READ)(int_dev_ptr, data_ptr, n);
}  /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_int_write
* Returned Value   : Number of bytes written
* Comments         :
*    This routine calls the appropriate write routine.
*
*END**********************************************************************/
_mqx_int _io_spi_int_write
   (
      /* [IN] The handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR    fd_ptr,

      /* [IN] Where the bytes are stored */
      char_ptr                  data_ptr,

      /* [IN] The number of bytes to output */
      _mqx_int                  n
   )
{  /* Body */
   IO_DEVICE_STRUCT_PTR         io_dev_ptr;
   IO_SPI_INT_DEVICE_STRUCT_PTR int_dev_ptr;
   
   io_dev_ptr  = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   int_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
               
   return (*int_dev_ptr->DEV_WRITE)(int_dev_ptr, data_ptr, n);
} /* Endbody */
   
/*FUNCTION*****************************************************************
* 
* Function Name    : _io_spi_int_ioctl
* Returned Value   : MQX error code
* Comments         :
*    Returns result of SPI ioctl operation.
*
*END*********************************************************************/
_mqx_int _io_spi_int_ioctl
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR    fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint                 cmd,

      /* [IN] the ioctl parameters */
      pointer                   input_param_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR         io_dev_ptr;
   IO_SPI_INT_DEVICE_STRUCT_PTR int_dev_ptr;
   _mqx_int                     result = MQX_OK;
   _mqx_uint_ptr                param_ptr = (_mqx_uint_ptr)input_param_ptr;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   int_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   switch (cmd) {
      case IO_IOCTL_SPI_GET_FLAGS:
         *param_ptr = int_dev_ptr->FLAGS;
         break;
      
      case IO_IOCTL_SPI_SET_FLAGS:
         int_dev_ptr->FLAGS = *param_ptr;
         fd_ptr->FLAGS = *param_ptr;
         break;
      
      case IO_IOCTL_DEVICE_IDENTIFY :
          /* return the device identify */
          param_ptr[0] = IO_DEV_TYPE_PHYS_SPI;
          param_ptr[1] = 0;
          param_ptr[2] = IO_DEV_ATTR_INTERRUPT | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
          result = MQX_OK;  
          break;
          
     default:
        if (int_dev_ptr->DEV_IOCTL != NULL) 
        {
           result = (*int_dev_ptr->DEV_IOCTL)(int_dev_ptr->DEV_INFO_PTR, cmd, param_ptr, int_dev_ptr->FLAGS);
        }
        break;             
   }
   return result;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/addrinfo.h<|end_filename|>
#ifndef __addr_info_h__
#define __addr_info_h__



/*% INT16 Size */
#define NS_INT16SZ	 				2

/*% IPv4 Address Size */
#define NS_INADDRSZ	 				4

/*% IPv6 Address Size */
#define NS_IN6ADDRSZ				16

#define MAX_HOSTNAME_SIZE     64


#define NET_ORDER			"inet" /* set order inet or inet6 or inet : inet6   */

#define	EAI_BADFLAGS	 	3	/* invalid value for ai_flags 					*/
#define	EAI_FAIL	 4			/* non-recoverable failure in name resolution 	*/
#define	EAI_FAMILY	 		5	/* ai_family not supported 						*/
#define	EAI_MEMORY	 		6	/* memory allocation failure 					*/
#define	EAI_NODATA	 		7	/* no address associated with hostname 			*/
#define	EAI_NONAME	 		8	/* hostname nor servname provided, or not known */
#define	EAI_SERVICE	 		9	/* servname not supported for ai_socktype 		*/
#define	EAI_SOCKTYPE		10	/* ai_socktype not supported 					*/
#define	EAI_SYSTEM			11	/* system error returned in errno 				*/

#define API_SOCK_DGRAM      1
#define API_SOCK_STREAM     2
#define API_SOCK_RAW		3


/*
 * Constants for getnameinfo()
 */
#define LWRES_CONTEXT_SERVERMODE	0x00000001U
#define LWRES_CONTEXT_USEIPV4		0x00000002U
#define LWRES_CONTEXT_USEIPV6		0x00000004U

#define LWRES_R_SUCCESS			0
#define LWRES_R_NOMEMORY		1 
#define LWRES_R_NOTFOUND		3
 
#define LWRES_ADDRTYPE_V4		0x00000001U	/*%< ipv4 */
#define LWRES_ADDRTYPE_V6		0x00000002U	/*%< ipv6 */ 
//#define	NI_MAXHOST	1025
#define	NI_MAXHOST	100
#define	NI_MAXSERV	32

#define	NI_NOFQDN		0x00000001
#define	NI_NUMERICHOST	0x00000002
#define	NI_NAMEREQD		0x00000004
#define	NI_NUMERICSERV	0x00000008
#define	NI_DGRAM		0x00000010

/*
** Type definitions
*/
typedef unsigned int   socklen_t;
typedef	uint_16        sa_family_t;

/*!
 * Used to set various options such as timeout, authentication, etc
 */
#define LWRES_UDP_PORT		921	/*%< UDP Port Number */
#define LWRES_RECVLENGTH	16384 /*%< Maximum Packet Length */
#define LWRES_ADDR_MAXLEN	16	/*%< changing this breaks ABI */
#define LWRES_DEFAULT_TIMEOUT	120	/* 120 seconds for a reply */


typedef void *(*lwres_malloc_t)(void *arg, unsigned int length);
typedef void (*lwres_free_t)(void *arg, void *mem, unsigned int length); 


#define LWRES_LINK(lwres_addr_t) struct { lwres_addr_t *prev, *next; }
#define CTXMALLOC(len)		ctx->malloc(ctx->arg, (len))
#define CTXFREE(addr, len)	ctx->free(ctx->arg, (addr), (len))

#define LWRES_LIST_NEXT(elt, link) ((elt)->link.next)


typedef struct lwres_addr lwres_addr_t;

typedef struct lwres_addr {
	uint_32					    family;
	uint_16 					length;
	unsigned char				address[LWRES_ADDR_MAXLEN];
	LWRES_LINK(lwres_addr_t)	link;
} lwres_addr;


#define LWRES_CONFMAXNAMESERVERS 3	/*%< max 3 "nameserver" entries */
#define LWRES_CONFMAXLWSERVERS 1	/*%< max 1 "lwserver" entry */
#define LWRES_CONFMAXSEARCH 8		/*%< max 8 domains in "search" entry */
#define LWRES_CONFMAXLINELEN 256	/*%< max size of a line */
#define LWRES_CONFMAXSORTLIST 10	/*%< max 10 */



typedef struct lwres_context lwres_context_t;

#define LWRES_LIST(type) struct { type *head, *tail; }
typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
typedef uint_32 lwres_result_t;
#define LWRES_LIST_HEAD(list) ((list).head)

#define LWRES_LIST_UNLINK(list, elt, link) \
	do { \
		if ((elt)->link.next != NULL) \
			(elt)->link.next->link.prev = (elt)->link.prev; \
		else \
			(list).tail = (elt)->link.prev; \
		if ((elt)->link.prev != NULL) \
			(elt)->link.prev->link.next = (elt)->link.next; \
		else \
			(list).head = (elt)->link.next; \
		(elt)->link.prev = (void *)(-1); \
		(elt)->link.next = (void *)(-1); \
	} while (0)




typedef struct {
	lwres_context_t *lwctx;
	lwres_addr_t    nameservers[LWRES_CONFMAXNAMESERVERS];
	uint_8	nsnext;		/*%< index for next free slot */

	lwres_addr_t	lwservers[LWRES_CONFMAXLWSERVERS];
	uint_8	lwnext;		/*%< index for next free slot */

	char	       *domainname;

	char 	       *search[LWRES_CONFMAXSEARCH];
	uint_8	searchnxt;	/*%< index for next free slot */

	struct {
		lwres_addr_t addr;
		/*% mask has a non-zero 'family' and 'length' if set */
		lwres_addr_t mask;
	} sortlist[LWRES_CONFMAXSORTLIST];
	uint_8	sortlistnxt;

	uint_8	resdebug;      /*%< non-zero if 'options debug' set */
	uint_8	ndots;	       /*%< set to n in 'options ndots:n' */
	uint_8	no_tld_query;  /*%< non-zero if 'options no_tld_query' */
} lwres_conf_t;


struct lwres_context {
	unsigned int		r_timeout;	/*%< time to wait for reply */
	uint_32			    serial;		/*%< serial number state */
    /* For network I/O.*/
	int					sock;		/*%< socket to send on */
    lwres_addr_t		address;	/*%< address to send to */
	int					use_ipv4;	/*%< use IPv4 transaction */
	int					use_ipv6;	/*%< use IPv6 transaction */

	/*@{*/
	/*
	 * Function pointers for allocating memory.
	 */
	lwres_malloc_t		malloc;
	lwres_free_t		free;
	void		       *arg;
	/*@}*/

	/*%
	 * resolv.conf-like data
	 */
	lwres_conf_t		confdata;
};


/*% lwres_gnbaresponse_t */
typedef struct {
	/* public */
	uint_32 					flags;
	uint_16 					naliases;
	char			            *realname;
	char			            **aliases;
	uint_16 					realnamelen;
	uint_16 		            *aliaslen;
	/*! if base != NULL, it will be freed when this structure is freed. */
	void			            *base;
	unsigned int				baselen;
} lwres_gnbaresponse_t;



/*% lwres_gabnresponse_t */
typedef struct {
	/* public */
	uint_32 					flags;
	uint_16 					naliases;
	uint_16 					naddrs;
	char			       		*realname;
	char			     		**aliases;
	uint_16 					realnamelen;
	uint_16 		       		*aliaslen;
	lwres_addrlist_t			addrs;
	/*! if base != NULL, it will be freed when this structure is freed. */
	void			       		*base;
	unsigned int				baselen;
} lwres_gabnresponse_t;

struct servent {
	char	*s_name		;		/* official service name 	*/
	char	**s_aliases	;		/* alias list 				*/
	int		s_port		;		/* port # 					*/
	char	*s_proto	;		/* protocol to use 			*/
};


extern char * strdup( const char *s);


extern void *lwres_malloc
(
	void            *arg, 
	unsigned int    len
); 

void lwres_free
(
	void *arg, 
	void *mem, 
	unsigned int len
); 

void lwres_conf_init
(
	lwres_context_t *ctx
); 

void lwres_resetaddr
(
	lwres_addr_t *addr
); 



uint_32 lwres_context_create
(
	lwres_context_t 	  **contextp, 
	void 				   *arg,
	lwres_malloc_t 			malloc_function,
	lwres_free_t 			free_function,
	unsigned int 			flags
);

void lwres_gnbaresponse_free
(
	lwres_context_t   	   *ctx, 
	lwres_gnbaresponse_t  **structp
);

void lwres_conf_clear
(
	lwres_context_t 	   *ctx
); 

void lwres_context_destroy
(
	lwres_context_t **contextp
); 



#endif


<|start_filename|>Firmware/Inverter_bootloader/APP/Main.c<|end_filename|>
#include "app_cfg.h"
#include "USB_timer.h"
#include "LCD_control.h"

static INT32U  New_sp;
static INT32U  New_pc; /* stack pointer and program counter */


extern void Init_periodic_app_timer(void);
extern void USB_App_init(void);
extern void USB_App_task(void);
static void Init_Sys(void);
static void wdog_disable(void);

void Jump_to_app(void);

extern const unsigned char AES_init_vector[16];
INT8U   chainCipherBlock[16];   // Buffer for Cipher Block

unsigned char  block[HEADER_BLOCK_SZ+10];
T_Boot_record p_boot_rec1;
T_Boot_record p_boot_rec2;

md5_context ctx;
unsigned char md5sum[16];

/*
Для проверки расчета контрольной суммы
INT8U test_block[49] = {0x20, 0x0f, 0x48, 0x09, 0x3f, 0x68, 0x31, 0x8e, 0x1e, 0x40, 0x80, 0x69, 0xd3, 0xcf, 0xb7, 0x04, 0x73, 0x04, 0x40, 0x01, 0x00, 0x03, 0x02, 0x0e, 0x00, 0x2e, 0x2b, 0x0f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x01, 0x00, 0x11, 0x33, 0x55, 0xaa};
*/

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void main(void)
{
  INT8U  c;

//  UART_Init(UART0_BASE_PTR, 120000, 921600);
  UART_Init(UART0_BASE_PTR, 120000, 115200);
  CAN_init(CAN0_BASE_PTR, CAN_SPEED);


  //printf_uart("Bootloader start\r\n");
  //Print_reset_source();
  //Print_CPU_identify();
  //printf_uart("\r\n");

  LCD_init();
  LCD_print_str("...BOOTLOADER...", 0, 0);

  PIT1_init(1000); // Инициализируем счетчик времени, с тиком = 1мс
/*
  Проверка расчета контролдьной суммы
  {
    char str[16];
    INT32U res;
    Get_block_CRC(test_block, 49, (INT8U*)&res); // Должно быть 0x645ACAE9
                                                 // Получается  0x73485EE4
    sprintf(str, "%08X", res);
    LCD_print_str(str, 0, 1);

  }
*/


  Init_periodic_app_timer();

  // После включения вначале проверяем не подключен ли программатор по RS232 к устройству
  // Посылаем запрос по RS232 и ожидаем в течении 0.1 сек ответа от  программатора по протоколу Y-modem
  Send_byte(ACK);
  if ( Wait_byte(&c, 100) == SUCCESS )
  {
    if ( c == 0x0D )
    {
      DELAY_ms(10);
      Ymodem_programmator();
    }
  }



  // Если программатор не подключен, то переходим в режим управления программированием и стартом по CAN
  // CAN_loader();

  do
  {
    Check_and_Jump_to_App();
    Ymodem_programmator();
  }
  while (1);

//
//  Приложенние DFU программатора
//
//  (void)USB_App_init(); /* Initialize the USB Test Application */
//
//  while (TRUE)
//  {
//    Watchdog_refresh();
//    USB_App_task();
//  }
}


//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void Watchdog_refresh(void)
{
  (void)(WDOG_BASE_PTR->REFRESH = 0xA602, WDOG_BASE_PTR->REFRESH = 0xB480);
}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void LCD_show_programming_progress(INT32U addr, INT32U sz)
{
  char str[16];
  LCD_clear_row(1);
  sprintf(str, "%05X   %07d",addr, sz);
  LCD_print_str(str, 0, 1);
}

//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
void LCD_show_programming_end(int state)
{
  char str[16];
  LCD_clear_row(1);
  if ( state == SUCCESS )
  {
    sprintf(str, "Flashing done!");
  }
  else if ( state == ERROR )
  {
    sprintf(str, "Flashing error!");
  }
  LCD_print_str(str, 0, 1);
}

//--------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------
void Check_and_Jump_to_App(void)
{
  // Проверить образ программы во FLASH
  // Извлекаем из области FLASH микроконтроллера запись об имидже.
  memcpy(&p_boot_rec2, (void *)(FLASH_AREA_ADDR + FLASH_AREA_SIZE - sizeof(p_boot_rec2)),  sizeof(p_boot_rec2));
  // Вычисляем хэш данных в памяти
  md5_starts(&ctx);
  if ( p_boot_rec2.orig_img_size <= FLASH_AREA_SIZE )
  {
    md5_update(&ctx, (uint8 *)PROGRAMM_AREA_BEG_ADDR, p_boot_rec2.orig_img_size);
    md5_finish(&ctx, md5sum);
    if ( memcmp(p_boot_rec2.md5_hash, md5sum, 16) == 0 )
    {
      Jump_to_app();
    }
  }
}

//--------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------
void Jump_to_app(void)
{

  /* Get PC and SP of application region */
  New_sp  = IMAGE_START_ADDR[0];
  New_pc  = IMAGE_START_ADDR[1];
  /* Check switch is pressed*/
  if ( (New_sp != 0xffffffff) && (New_pc != 0xffffffff) )
  {
    /* Run the application */
    asm("mov32   r4,New_sp");
    asm("ldr     sp,[r4]");
    asm("mov32   r4,New_pc");
    asm("ldr     r5, [r4]");
    asm("blx     r5");
  }
}




<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GMCLIB/GMCLIB_DecouplingPMSM.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GMCLIB_DecouplingPMSM.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GMCLIB_DecouplingPMSM function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GMCLIB_DECOUPLINGPMSM_H
#define _GMCLIB_DECOUPLINGPMSM_H

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GMCLIB_DecouplingPMSMANSIC function.*/
#define GMCLIB_DecouplingPMSM(pUdqDec,pUdq,pIdq,f32AngularVel,pParam)\
        GMCLIB_DecouplingPMSMANSIC(pUdqDec,pUdq,pIdq,f32AngularVel,pParam)

/*! Macro containing reset values of the parameters for the decoupling algorithm implemented
 * in the #GMCLIB_DecouplingPMSM function.*/
#define GMCLIB_DECOUPLINGPMSM_DEFAULT   {0,0,0,0}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct MCLIB_DECOUPLING_PMSM_PARAM_T "\GMCLIB_DecouplingPMSM.h"

@brief  Structure containing coefficients for calculation of the decoupling algorithm
        implemented in the #GMCLIB_DecouplingPMSM function.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32 f32Kd;          /*!< Coefficient \f$k_{df}\f$, in fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ */
    Word16    w16KdShift;      /*!< Scaling coefficient \f$k_{d\_shift}\f$, integer format \f$\left[-31,31\right]\f$ */
    Frac32 f32Kq;          /*!< Coefficient \f$k_{qf}\f$, in fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ */
    Word16    w16KqShift;      /*!< Scaling coefficient \f$k_{q\_shift}\f$, integer format \f$\left[-31,31\right]\f$ */
}MCLIB_DECOUPLING_PMSM_PARAM_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*! 
* @ingroup GMCLIB_GROUP 
*/ 
extern void GMCLIB_DecouplingPMSMANSIC(MCLIB_2_COOR_SYST_D_Q_T *pUdqDec,
										const MCLIB_2_COOR_SYST_D_Q_T *const pUdq,
										const MCLIB_2_COOR_SYST_D_Q_T *const pIdq,
										Frac32      f32AngularVel,
										const MCLIB_DECOUPLING_PMSM_PARAM_T *const pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GMCLIB_DECOUPLINGPMSM_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/FTFE_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type FTFE
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(FTFE_PDD_H_)
#define FTFE_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error FTFE PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10F12) /* FTFE */ && \
      !defined(MCU_MK20F12) /* FTFE */ && \
      !defined(MCU_MK60F12) /* FTFE */ && \
      !defined(MCU_MK60F15) /* FTFE */ && \
      !defined(MCU_MK61F12) /* FTFE */ && \
      !defined(MCU_MK61F15) /* FTFE */ && \
      !defined(MCU_MK61F12WS) /* FTFE */ && \
      !defined(MCU_MK61F15WS) /* FTFE */ && \
      !defined(MCU_MK70F12) /* FTFE */ && \
      !defined(MCU_MK70F15) /* FTFE */ && \
      !defined(MCU_MK70F12WS) /* FTFE */ && \
      !defined(MCU_MK70F15WS) /* FTFE */
  // Unsupported MCU is active
  #error FTFE PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* ClearFlags constants */
#define FTFE_PDD_COMMAND_COMPLETE          FTFE_FSTAT_CCIF_MASK /**< Command complete flag mask */
#define FTFE_PDD_READ_COLLISION_ERROR      FTFE_FSTAT_RDCOLERR_MASK /**< Read collision error flag mask */
#define FTFE_PDD_ACCESS_ERROR              FTFE_FSTAT_ACCERR_MASK /**< Access error flag mask */
#define FTFE_PDD_PROTECTION_VIOLATION      FTFE_FSTAT_FPVIOL_MASK /**< Protection violation flag mask */
#define FTFE_PDD_COMMAND_COMPLETION_STATUS FTFE_FSTAT_MGSTAT0_MASK /**< Command completion ststus flag mask */

/* EnableInterrupts, DisableInterrupts constants */
#define FTFE_PDD_COMMAND_COMPLETE_INT     FTFE_FCNFG_CCIE_MASK /**< Command complete interrupt mask */
#define FTFE_PDD_READ_COLLISION_ERROR_INT FTFE_FCNFG_RDCOLLIE_MASK /**< Read collision error interrupt mask */

/* SetFCCOBCommand constants */
#define FTFE_PDD_READ_1S_BLOCK              0U   /**< Read 1s Block command value */
#define FTFE_PDD_READ_1S_SECTION            0x1U /**< Read 1s Section command value */
#define FTFE_PDD_PROGRAM_CHECK              0x2U /**< Program Check command value */
#define FTFE_PDD_READ_RESOURCE              0x3U /**< Read Resource command value */
#define FTFE_PDD_PROGRAM_PHRASE             0x7U /**< Program 8 bytes command value */
#define FTFE_PDD_ERASE_FLASH_BLOCK          0x8U /**< Erase Flash Block command value */
#define FTFE_PDD_ERASE_FLASH_SECTOR         0x9U /**< Erase Flash Sector command value */
#define FTFE_PDD_PROGRAM_SECTION            0xBU /**< Program Section command value */
#define FTFE_PDD_READ_1S_ALL_BLOCKS         0x40U /**< Read 1s All Blocks command value */
#define FTFE_PDD_PDD_READ_ONCE              0x41U /**< Read Once command value */
#define FTFE_PDD_PROGRAM_ONCE               0x43U /**< Program Once command value */
#define FTFE_PDD_ERASE_ALL_BLOCKS           0x44U /**< Erase All Blocks command value */
#define FTFE_PDD_VERIFY_BACKDOOR_ACCESS_KEY 0x45U /**< Verify Backdoor Access Key command value */
#define FTFE_PDD_PROGRAM_PARTITION          0x80U /**< Program Partition command value */
#define FTFE_PDD_SET_EERAM_FUCTION          0x81U /**< Set FlexRAM Function command value */

/* BackDoorKey constants */
#define FTFE_PDD_BACKDOOR_KEY_ENABLED  0U        /**< Backdoor key enable constant */
#define FTFE_PDD_BACKDOOR_KEY_DISABLED 0x1U      /**< Backdoor key disable constant */

/* Security state constants */
#define FTFE_PDD_UNSECURED 0U                    /**< Unsecure constant */
#define FTFE_PDD_SECURED   0x1U                  /**< Secure constant */

/* FlashProtection constants */
#define FTFE_PDD_UNPROTECTED 0U                  /**< Unprotect constant */
#define FTFE_PDD_PROTECTED   0x1U                /**< Protect constant */


/* ----------------------------------------------------------------------------
   -- ReadStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @return Use constants from group "ClearFlags constants" for processing return
 *         value.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadStatusReg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadStatusReg(PeripheralBase) ( \
    FTFE_FSTAT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the Flash status register. Use constants from
 *        group "ClearFlags constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteStatusReg(deviceID, FTFE_PDD_COMMAND_COMPLETE);
 *      @endcode
 */
#define FTFE_PDD_WriteStatusReg(PeripheralBase, Value) ( \
    FTFE_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ClearCommandCompleteFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Command complete flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      FTFE_PDD_ClearCommandCompleteFlag(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ClearCommandCompleteFlag(PeripheralBase) ( \
    FTFE_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFE_FSTAT_REG(PeripheralBase) | FTFE_FSTAT_CCIF_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_ACCERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_RDCOLERR_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearReadCollisionErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Read collision error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      FTFE_PDD_ClearReadCollisionErrorFlag(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ClearReadCollisionErrorFlag(PeripheralBase) ( \
    FTFE_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFE_FSTAT_REG(PeripheralBase) | FTFE_FSTAT_RDCOLERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_ACCERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearAccessErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Access error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      FTFE_PDD_ClearAccessErrorFlag(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ClearAccessErrorFlag(PeripheralBase) ( \
    FTFE_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFE_FSTAT_REG(PeripheralBase) | FTFE_FSTAT_ACCERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_RDCOLERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- ClearProtectionViolationErrorFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears Protection violation error flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      FTFE_PDD_ClearProtectionViolationErrorFlag(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ClearProtectionViolationErrorFlag(PeripheralBase) ( \
    FTFE_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(FTFE_FSTAT_REG(PeripheralBase) | FTFE_FSTAT_FPVIOL_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_ACCERR_MASK)) & (( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_RDCOLERR_MASK)) & ( \
      (uint8_t)(~(uint8_t)FTFE_FSTAT_CCIF_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- LaunchCommand
   ---------------------------------------------------------------------------- */

/**
 * @brief Starts new command.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      FTFE_PDD_LaunchCommand(deviceID);
 *      @endcode
 */
#define FTFE_PDD_LaunchCommand(PeripheralBase) ( \
    FTFE_FSTAT_REG(PeripheralBase) = \
     0x80U \
  )

/* ----------------------------------------------------------------------------
   -- ClearFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @param Flags Interrupt mask. This parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      FTFE_PDD_ClearFlags(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_ClearFlags(PeripheralBase, Flags) ( \
    FTFE_FSTAT_REG(PeripheralBase) = \
     (uint8_t)(Flags) \
  )

/* ----------------------------------------------------------------------------
   -- GetFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash status register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FSTAT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_GetFlags(deviceID);
 *      @endcode
 */
#define FTFE_PDD_GetFlags(PeripheralBase) ( \
    FTFE_FSTAT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadConfigReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns value of the Flash configuration register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCNFG.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadConfigReg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadConfigReg(PeripheralBase) ( \
    FTFE_FCNFG_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteConfigReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the Flash configuration register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the Flash configuration register. This
 *        parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCNFG.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteConfigReg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteConfigReg(PeripheralBase, Value) ( \
    FTFE_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables Command commplete end Read collision error interrupts.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "EnableInterrupts,
 *        DisableInterrupts constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCNFG.
 * @par Example:
 *      @code
 *      FTFE_PDD_EnableInterrupts(deviceID, FTFE_PDD_COMMAND_COMPLETE_INT);
 *      @endcode
 */
#define FTFE_PDD_EnableInterrupts(PeripheralBase, Mask) ( \
    FTFE_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(( \
       FTFE_FCNFG_REG(PeripheralBase)) & ( \
       (uint8_t)(~(uint8_t)(FTFE_FCNFG_CCIE_MASK | FTFE_FCNFG_RDCOLLIE_MASK))))) | ( \
      (uint8_t)(Mask))) \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupts
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables Command commplete end Read collision error interrupts.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "EnableInterrupts,
 *        DisableInterrupts constants". This parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCNFG.
 * @par Example:
 *      @code
 *      FTFE_PDD_DisableInterrupts(deviceID, FTFE_PDD_COMMAND_COMPLETE_INT);
 *      @endcode
 */
#define FTFE_PDD_DisableInterrupts(PeripheralBase, Mask) ( \
    FTFE_FCNFG_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(( \
       FTFE_FCNFG_REG(PeripheralBase)) & ( \
       (uint8_t)(~(uint8_t)(FTFE_FCNFG_CCIE_MASK | FTFE_FCNFG_RDCOLLIE_MASK))))) | ( \
      (uint8_t)(( \
       (uint8_t)(~(uint8_t)(Mask))) & ( \
       (uint8_t)(FTFE_FCNFG_CCIE_MASK | FTFE_FCNFG_RDCOLLIE_MASK))))) \
  )

/* ----------------------------------------------------------------------------
   -- SuspendErasing
   ---------------------------------------------------------------------------- */

/**
 * @brief Suspends the current Erase Flash Sector command execution.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCNFG.
 * @par Example:
 *      @code
 *      FTFE_PDD_SuspendErasing(deviceID);
 *      @endcode
 */
#define FTFE_PDD_SuspendErasing(PeripheralBase) ( \
    FTFE_FCNFG_REG(PeripheralBase) |= \
     FTFE_FCNFG_ERSSUSP_MASK \
  )

/* ----------------------------------------------------------------------------
   -- GetRAMReady
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Ram ready bit.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCNFG.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_GetRAMReady(deviceID);
 *      @endcode
 */
#define FTFE_PDD_GetRAMReady(PeripheralBase) ( \
    (uint8_t)(FTFE_FCNFG_REG(PeripheralBase) & FTFE_FCNFG_RAMRDY_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetEEEReady
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the EEE ready bit.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCNFG.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_GetEEEReady(deviceID);
 *      @endcode
 */
#define FTFE_PDD_GetEEEReady(PeripheralBase) ( \
    (uint8_t)(FTFE_FCNFG_REG(PeripheralBase) & FTFE_FCNFG_EEERDY_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ReadSecurityReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Security register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FSEC.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadSecurityReg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadSecurityReg(PeripheralBase) ( \
    FTFE_FSEC_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetBackdoorEnable
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the constant FTFL_PDD_BACKDOOR_KEY_ENABLED if backdoor key
 * access is enabled else returns the FTFL_PDD_BACKDOOR_KEY_DISABLED constant.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of "BackDoorKey constants" type. The value is cast to
 *         "uint16_t".
 * @remarks The macro accesses the following registers: FTFE_FSEC.
 * @par Example:
 *      @code
 *      uint16_t result = FTFE_PDD_GetBackdoorEnable(deviceID);
 *      @endcode
 */
#define FTFE_PDD_GetBackdoorEnable(PeripheralBase) ( \
    (( \
      (uint8_t)(( \
       (uint8_t)(FTFE_FSEC_REG(PeripheralBase) & FTFE_FSEC_KEYEN_MASK)) >> ( \
       FTFE_FSEC_KEYEN_SHIFT))) == ( \
      0x2U)) ? ( \
      FTFE_PDD_BACKDOOR_KEY_ENABLED) : ( \
      FTFE_PDD_BACKDOOR_KEY_DISABLED) \
  )

/* ----------------------------------------------------------------------------
   -- GetSecurityState
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the constant FTFL_PDD_SECURED if MCU is in secure state else
 * returns the FTFL_PDD_UNSECURED constant.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of "Security state constants" type. The value is cast
 *         to "uint16_t".
 * @remarks The macro accesses the following registers: FTFE_FSEC.
 * @par Example:
 *      @code
 *      uint16_t result = FTFE_PDD_GetSecurityState(deviceID);
 *      @endcode
 */
#define FTFE_PDD_GetSecurityState(PeripheralBase) ( \
    ((uint8_t)(FTFE_FSEC_REG(PeripheralBase) & FTFE_FSEC_SEC_MASK) == 0x2U) ? ( \
      FTFE_PDD_UNSECURED) : ( \
      FTFE_PDD_SECURED) \
  )

/* ----------------------------------------------------------------------------
   -- ReadOptionReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Optional register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FOPT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadOptionReg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadOptionReg(PeripheralBase) ( \
    FTFE_FOPT_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB0Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 0.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB0.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB0Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB0Reg(PeripheralBase) ( \
    FTFE_FCCOB0_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 1.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB1.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB1Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB1Reg(PeripheralBase) ( \
    FTFE_FCCOB1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 2.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB2.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB2Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB2Reg(PeripheralBase) ( \
    FTFE_FCCOB2_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB3Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 3.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB3.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB3Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB3Reg(PeripheralBase) ( \
    FTFE_FCCOB3_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB4Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 4.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB4.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB4Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB4Reg(PeripheralBase) ( \
    FTFE_FCCOB4_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB5Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 5.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB5.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB5Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB5Reg(PeripheralBase) ( \
    FTFE_FCCOB5_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB6Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 6.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB6.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB6Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB6Reg(PeripheralBase) ( \
    FTFE_FCCOB6_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB7Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 7.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB7.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB7Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB7Reg(PeripheralBase) ( \
    FTFE_FCCOB7_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB8Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 8.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB8.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB8Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB8Reg(PeripheralBase) ( \
    FTFE_FCCOB8_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOB9Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register 9.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOB9.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOB9Reg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOB9Reg(PeripheralBase) ( \
    FTFE_FCCOB9_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOBAReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register A.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOBA.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOBAReg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOBAReg(PeripheralBase) ( \
    FTFE_FCCOBA_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ReadFCCOBBReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the value of the Common command object register B.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FCCOBB.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_ReadFCCOBBReg(deviceID);
 *      @endcode
 */
#define FTFE_PDD_ReadFCCOBBReg(PeripheralBase) ( \
    FTFE_FCCOBB_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB0Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB0 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB0 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB0.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB0Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB0Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB0_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB1Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB1 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB1 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB1.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB1Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB1Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB1_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB2Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB2 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB2 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB2.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB2Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB2Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB2_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB3Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB3register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB3 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB3.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB3Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB3Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB3_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB4Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB4 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB4 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB4.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB4Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB4Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB5Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB5 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB5 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB5.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB5Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB5Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB6Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB6 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB6 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB6.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB6Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB6Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB7Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB7 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB7 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB7.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB7Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB7Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB8Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB8 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB8 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB8.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB8Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB8Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOB9Reg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB9 register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOB9 register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB9.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOB9Reg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOB9Reg(PeripheralBase, Value) ( \
    FTFE_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBAReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOBA register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOBA register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOBA.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBAReg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBAReg(PeripheralBase, Value) ( \
    FTFE_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBBReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOBB register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value written to the FCCOBB register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOBB.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBBReg(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBBReg(PeripheralBase, Value) ( \
    FTFE_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- SetFCCOBCommand
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB Command register.
 * @param PeripheralBase Peripheral base address.
 * @param Command Value written to the FCCOB Command register. This parameter is
 *        a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB0.
 * @par Example:
 *      @code
 *      FTFE_PDD_SetFCCOBCommand(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_SetFCCOBCommand(PeripheralBase, Command) ( \
    FTFE_FCCOB0_REG(PeripheralBase) = \
     (uint8_t)(Command) \
  )

/* ----------------------------------------------------------------------------
   -- SetFCCOBAddress
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes the value to the FCCOB Address register.
 * @param PeripheralBase Peripheral base address.
 * @param Address Value written to the FCCOB Address register. This parameter is
 *        a 24-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB3,
 *          FTFE_FCCOB2, FTFE_FCCOB1 (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFE_PDD_SetFCCOBAddress(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_SetFCCOBAddress(PeripheralBase, Address) ( \
    (FTFE_FCCOB3_REG(PeripheralBase) = \
     (uint8_t)(Address)), \
    ((FTFE_FCCOB2_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Address) >> 8U)), \
    (FTFE_FCCOB1_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Address) >> 16U))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData0
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 0.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 0 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB4.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBData0(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBData0(PeripheralBase, Data) ( \
    FTFE_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData1
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 1.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 1 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB5.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBData1(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBData1(PeripheralBase, Data) ( \
    FTFE_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData2
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 2.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 2 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB6.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBData2(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBData2(PeripheralBase, Data) ( \
    FTFE_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData3
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 3.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 3 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB7.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBData3(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBData3(PeripheralBase, Data) ( \
    FTFE_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData4
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 4.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 4 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB8.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBData4(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBData4(PeripheralBase, Data) ( \
    FTFE_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData5
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 5.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 5 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB9.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBData5(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBData5(PeripheralBase, Data) ( \
    FTFE_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData6
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 6.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 6 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOBA.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBData6(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBData6(PeripheralBase, Data) ( \
    FTFE_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBData7
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes Data byte 7.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the FCCOB Data 7 register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOBB.
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBData7(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBData7(PeripheralBase, Data) ( \
    FTFE_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Data) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB4,
 *          FTFE_FCCOB5, FTFE_FCCOB6, FTFE_FCCOB7 (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBLongWordData(PeripheralBase, Data) ( \
    (FTFE_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 24U)), \
    ((FTFE_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 16U)), \
    ((FTFE_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 8U)), \
    (FTFE_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Data)))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBFirstLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets first longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB4,
 *          FTFE_FCCOB5, FTFE_FCCOB6, FTFE_FCCOB7 (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBFirstLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBFirstLongWordData(PeripheralBase, Data) ( \
    (FTFE_FCCOB4_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 24U)), \
    ((FTFE_FCCOB5_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 16U)), \
    ((FTFE_FCCOB6_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 8U)), \
    (FTFE_FCCOB7_REG(PeripheralBase) = \
     (uint8_t)(Data)))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteFCCOBSecondLongWordData
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets second longword data to be programmed.
 * @param PeripheralBase Peripheral base address.
 * @param Data Value written to the Flash in the CPU native endian format. This
 *        parameter is a 32-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FCCOB8,
 *          FTFE_FCCOB9, FTFE_FCCOBA, FTFE_FCCOBB (depending on the peripheral).
 * @par Example:
 *      @code
 *      FTFE_PDD_WriteFCCOBSecondLongWordData(deviceID, 1);
 *      @endcode
 */
#define FTFE_PDD_WriteFCCOBSecondLongWordData(PeripheralBase, Data) ( \
    (FTFE_FCCOB8_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 24U)), \
    ((FTFE_FCCOB9_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 16U)), \
    ((FTFE_FCCOBA_REG(PeripheralBase) = \
     (uint8_t)((uint32_t)(Data) >> 8U)), \
    (FTFE_FCCOBB_REG(PeripheralBase) = \
     (uint8_t)(Data)))) \
  )

/* ----------------------------------------------------------------------------
   -- SetPFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets program Flash protection state.
 * @param PeripheralBase Peripheral base address.
 * @param Regions Protected regions. This parameter is a 32-bit value.
 * @param State Requested state. This parameter is of "FlashProtection
 *        constants" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FPROT3.
 * @par Example:
 *      @code
 *      FTFE_PDD_SetPFlashProtectionState(deviceID, 1, FTFE_PDD_UNPROTECTED);
 *      @endcode
 */
#define FTFE_PDD_SetPFlashProtectionState(PeripheralBase, Regions, State) ( \
    ((State) == FTFE_PDD_UNPROTECTED) ? ( \
      *(uint32_t *)(void *)&(FTFE_FPROT3_REG(PeripheralBase)) |= \
      (uint32_t)(Regions)) : ( \
      *(uint32_t *)(void *)&(FTFE_FPROT3_REG(PeripheralBase)) &= \
      (uint32_t)(~(uint32_t)(Regions))) \
  )

/* ----------------------------------------------------------------------------
   -- GetPFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns program falsh protection state.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: FTFE_FPROT3.
 * @par Example:
 *      @code
 *      uint32_t result = FTFE_PDD_GetPFlashProtectionState(deviceID);
 *      @endcode
 */
#define FTFE_PDD_GetPFlashProtectionState(PeripheralBase) ( \
    (uint32_t)(~(*(uint32_t *)(void *)&(FTFE_FPROT3_REG(PeripheralBase)))) \
  )

/* ----------------------------------------------------------------------------
   -- SetDFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets data Flash protection state.
 * @param PeripheralBase Peripheral base address.
 * @param Regions FTFL_PDD_PROTECTED or FTFL_PDD_UNPROTECTED. This parameter is
 *        a 8-bit value.
 * @param State Requested state. This parameter is of "FlashProtection
 *        constants" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FDPROT.
 * @par Example:
 *      @code
 *      FTFE_PDD_SetDFlashProtectionState(deviceID, 1, FTFE_PDD_UNPROTECTED);
 *      @endcode
 */
#define FTFE_PDD_SetDFlashProtectionState(PeripheralBase, Regions, State) ( \
    ((State) == FTFE_PDD_UNPROTECTED) ? ( \
      FTFE_FDPROT_REG(PeripheralBase) |= \
       (uint8_t)(Regions)) : ( \
      FTFE_FDPROT_REG(PeripheralBase) &= \
       (uint8_t)(~(uint8_t)(Regions))) \
  )

/* ----------------------------------------------------------------------------
   -- GetDFlashProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Each bit of the returned value represent 1/8 of the Data FLASH memory.
 * If the bit is set the region is protected else the region is unprotected.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FDPROT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_GetDFlashProtectionState(deviceID);
 *      @endcode
 */
#define FTFE_PDD_GetDFlashProtectionState(PeripheralBase) ( \
    (uint8_t)(~(uint8_t)FTFE_FDPROT_REG(PeripheralBase)) \
  )

/* ----------------------------------------------------------------------------
   -- SetEERAMProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Each bit of the Region parameter represent 1/8 of the EERPROM memory.
 * To change the protection state of the region(s) select requested regions
 * (Region param) and set new state (State param).
 * @param PeripheralBase Peripheral base address.
 * @param Regions Protected regions. This parameter is a 8-bit value.
 * @param State Requested state. This parameter is of "FlashProtection
 *        constants" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: FTFE_FEPROT.
 * @par Example:
 *      @code
 *      FTFE_PDD_SetEERAMProtectionState(deviceID, 1, FTFE_PDD_UNPROTECTED);
 *      @endcode
 */
#define FTFE_PDD_SetEERAMProtectionState(PeripheralBase, Regions, State) ( \
    ((State) == FTFE_PDD_UNPROTECTED) ? ( \
      FTFE_FEPROT_REG(PeripheralBase) |= \
       (uint8_t)(Regions)) : ( \
      FTFE_FEPROT_REG(PeripheralBase) &= \
       (uint8_t)(~(uint8_t)(Regions))) \
  )

/* ----------------------------------------------------------------------------
   -- GetEERAMProtectionState
   ---------------------------------------------------------------------------- */

/**
 * @brief Each bit of the returned value represent 1/8 of the EERPROM memory. If
 * the bit is set the region is protected else the region is unprotected.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: FTFE_FEPROT.
 * @par Example:
 *      @code
 *      uint8_t result = FTFE_PDD_GetEERAMProtectionState(deviceID);
 *      @endcode
 */
#define FTFE_PDD_GetEERAMProtectionState(PeripheralBase) ( \
    (uint8_t)(~(uint8_t)FTFE_FEPROT_REG(PeripheralBase)) \
  )
#endif  /* #if defined(FTFE_PDD_H_) */

/* FTFE_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/Main/Motor_control.c<|end_filename|>
#include <mqx.h>
#include <bsp.h>
#include <fio.h>
#include "App.h"
#include <math.h>

extern signed short   smpls[11][TST_SMPLS_ARR_SZ];
extern unsigned int   arr_pos;


static T_MC_CBL            mc_cbl;
volatile static uint32_t   dummy;
static LWEVENT_STRUCT      evt_grp;
static pointer             mc_is_taskr_queue;

Frac32 sinv, cosv;

static void ETM0_isr(pointer user_isr_ptr);


/*-------------------------------------------------------------------------------------------------------------
  Пересчет значения PWM из Frac32 в реальное целое значение с границей  PWM_MODULO
-------------------------------------------------------------------------------------------------------------*/
static unsigned int MC_scale_PWM_ch(Frac32 pwm)
{
  Word64  lltmp;
  lltmp = (Word64)pwm * (Word64)PWM_MODULO * 2 - (Word64)PWM_MODULO * FRAC32(0.5);
  lltmp = lltmp / 0x80000000ul;

  // Здесь предотвращаем появление слишком коротких импульсов
  if ( lltmp < PWM_MARGIN_LO_LEV ) lltmp = 0;
  else if ( lltmp > (PWM_MODULO - PWM_MARGIN_HI_LEV) ) lltmp = PWM_MODULO;

//  if ( lltmp < PWM_MARGIN_LO_LEV ) lltmp = PWM_MARGIN_LO_LEV;
//  else if ( lltmp > (PWM_MODULO - PWM_MARGIN_HI_LEV) ) lltmp = PWM_MODULO - PWM_MARGIN_HI_LEV;

  return (unsigned int)lltmp;
}
/*-------------------------------------------------------------------------------------------------------------
  Расчет параметров PWM 
-------------------------------------------------------------------------------------------------------------*/
#define KSCALE  1
void MC_calculate_PWM(T_3ph_pwm *pwm_3ph_ptr)
{
  float                          angle_flt;
  MCLIB_2_COOR_SYST_ALPHA_BETA_T in_voltage;
  MCLIB_3_COOR_SYST_T            pwm_abc;
  UWord32                        sector;
  Word64                         lltmp;
  Frac32                         x;

  Get_generator_sample(&in_voltage.f32Beta, &in_voltage.f32Alpha);

  // Промасштабировать амплитуду пропорционально частоте
  if ( mc_cbl.mot_freq < MAX_MOT_FREQ )
  {
    if ( mc_cbl.direction == MOVING_UP )
    {
      x = FRAC32((float)mc_cbl.ll_mot_freq * mc_cbl.pwm_scale / ((float)(MAX_MOT_FREQ) * (float)(1ull << 32))); // Уменьшаем амплитуду вектора пропорционально частоте
    }
    else
    {
      x = FRAC32((float)mc_cbl.ll_mot_freq * mc_cbl.pwm_scale / ((float)(MAX_MOT_FREQ) * (float)(1ull << 32))); // Уменьшаем амплитуду вектора пропорционально частоте
    }
  }
  else
  {
    if ( mc_cbl.direction == MOVING_UP )
    {
      x = FRAC32(mc_cbl.pwm_scale);
    }
    else
    {
      x = FRAC32(mc_cbl.pwm_scale);
    }
  }

  in_voltage.f32Beta  = F32Mul(x, in_voltage.f32Beta);
  in_voltage.f32Alpha = F32Mul(x, in_voltage.f32Alpha);

  sector = GMCLIB_SvmStd(&pwm_abc, &in_voltage);

  pwm_3ph_ptr->pwm_a = MC_scale_PWM_ch(pwm_abc.f32A);
  if ( mc_cbl.direction == 0 )
  {
    pwm_3ph_ptr->pwm_b = MC_scale_PWM_ch(pwm_abc.f32B);
    pwm_3ph_ptr->pwm_c = MC_scale_PWM_ch(pwm_abc.f32C);
  }
  else
  {
    pwm_3ph_ptr->pwm_b = MC_scale_PWM_ch(pwm_abc.f32C);
    pwm_3ph_ptr->pwm_c = MC_scale_PWM_ch(pwm_abc.f32B);
  }

  //printf("%d,%d,%d,%d,%d,%d,%d\r\n",mc_cbl.mot_freq, x, in_voltage.f32Beta, in_voltage.f32Alpha, pwm_3ph_ptr->pwm_a, pwm_3ph_ptr->pwm_b, pwm_3ph_ptr->pwm_c );
}

/*-------------------------------------------------------------------------------------------------------------
  Инициализация PWM
-------------------------------------------------------------------------------------------------------------*/
void MC_init_PWM(void)
{

  mc_cbl.up_accel_pwm_scale   = 0.6;
  mc_cbl.up_pwm_scale         = 0.65;
  mc_cbl.up_decel_pwm_scale   = 0.6;

  mc_cbl.down_accel_pwm_scale = 0.3;
  mc_cbl.down_pwm_scale       = 0.3;
  mc_cbl.down_decel_pwm_scale = 0.6;

  mc_cbl.up_move_freq         = 50;
  mc_cbl.up_acceler_time      = 10;
  mc_cbl.up_deceler_time      = 10;

  mc_cbl.down_move_freq       = 50;
  mc_cbl.down_acceler_time    = 10;
  mc_cbl.down_deceler_time    = 10;


  _int_install_isr(INT_FTM0, ETM0_isr, &mc_cbl);
  // Разрешить прерывание только после установки вектора! Иначе можем уйти в непрерывный вызов ISR по дефолтному вектору
  _bsp_int_init(INT_FTM0, ETM0_ISR_PRIO, 0, TRUE);

  // Разрешаем тактирование ETM0
  SIM_SCGC6 |= BIT(24);
  dummy =  FTM0_SC;

  // Остановка таймера и очистка флага прерывания
  FTM0_SC = 0
            + LSHIFT(1, 5) // CPWMS. 1 -FTM counter operates in up-down counting mode.
  ;

  // Очистка флагов прерываний в каждом канале
  dummy = FTM0_C0SC;
  dummy = FTM0_C1SC;
  dummy = FTM0_C2SC;
  dummy = FTM0_C3SC;
  dummy = FTM0_C4SC;
  dummy = FTM0_C5SC;
  FTM0_C0SC = 0x00U;
  FTM0_C1SC = 0x00U;
  FTM0_C2SC = 0x00U;
  FTM0_C3SC = 0x00U;
  FTM0_C4SC = 0x00U;
  FTM0_C5SC = 0x00U;
  FTM0_C6SC = 0x00U;
  FTM0_C7SC = 0x00U;

  FTM0_MODE |= BIT(2);  // WPDIS. 1 -Write protection is disabled.
  FTM0_MODE |= BIT(0);  // FTMEN. 1 -All registers including the FTM-specific registers (second set of registers) are available for use with no restrictions.

  FTM0_MOD      = PWM_MODULO; // Установка регистра перезагрузки. Частота PWM в режиме UP-DOWN будет равна Fsys/2*MOD = 60000000/2*1875 =   16000000
  FTM0_CNTIN    = 0;    // Начальное значение счетчика
  FTM0_OUTINIT  = BIT(5) + BIT(3) + BIT(1); // Начальное состояние выходов
  FTM0_CNT      = 0;    // Запись в регистр счетчка любого значения приводит к записи значения из CNTIN и установке начального состояния выходов
  FTM0_DEADTIME = 0;    // Установка мертвого времени в 0 тактов системной частоты (Драйвер FSBB30CH60CT имеет свои задержки мертвого времени)


  FTM0_COMBINE = 0
                 + LSHIFT(0, 30) // FAULTEN3. 1 The fault control in this pair of channels is enabled.
                 + LSHIFT(0, 29) // SYNCEN3.  1 The PWM synchronization in this pair of channels is enabled.
                 + LSHIFT(0, 28) // DTEN3.    0 The deadtime insertion in this pair of channels is disabled.
                 + LSHIFT(0, 27) // DECAP3.   0 The dual edge captures are inactive.
                 + LSHIFT(0, 26) // DECAPEN3  0 The dual edge capture mode in this pair of channels is disabled.
                 + LSHIFT(0, 25) // COMP3     1 The channel (n+1) output is the complement of the channel (n) output.
                 + LSHIFT(0, 24) // COMBINE3  1 Channels (n) and (n+1) are combined.
                 + LSHIFT(1, 22) // FAULTEN2  1 The fault control in this pair of channels is enabled.
                 + LSHIFT(1, 21) // SYNCEN2   1 The PWM synchronization in this pair of channels is enabled.
                 + LSHIFT(1, 20) // DTEN2     0 The deadtime insertion in this pair of channels is disabled.
                 + LSHIFT(0, 19) // DECAP2    0 The dual edge captures are inactive.
                 + LSHIFT(0, 18) // DECAPEN2  0 The dual edge capture mode in this pair of channels is disabled.
                 + LSHIFT(1, 17) // COMP2     1 The channel (n+1) output is the complement of the channel (n) output.
                 + LSHIFT(0, 16) // COMBINE2  1 Channels (n) and (n+1) are combined.
                 + LSHIFT(1, 14) // FAULTEN1  1 The fault control in this pair of channels is enabled.
                 + LSHIFT(1, 13) // SYNCEN1   1 The PWM synchronization in this pair of channels is enabled.
                 + LSHIFT(1, 12) // DTEN1     0 The deadtime insertion in this pair of channels is disabled.
                 + LSHIFT(0, 11) // DECAP1    0 The dual edge captures are inactive.
                 + LSHIFT(0, 10) // DECAPEN1  0 The dual edge capture mode in this pair of channels is disabled.
                 + LSHIFT(1,  9) // COMP1     1 The channel (n+1) output is the complement of the channel (n) output.
                 + LSHIFT(0,  8) // COMBINE1  1 Channels (n) and (n+1) are combined.
                 + LSHIFT(1,  6) // FAULTEN0  1 The fault control in this pair of channels is enabled.
                 + LSHIFT(1,  5) // SYNCEN0   1 The PWM synchronization in this pair of channels is enabled.
                 + LSHIFT(1,  4) // DTEN0     0 The deadtime insertion in this pair of channels is disabled.
                 + LSHIFT(0,  3) // DECAP0    0 The dual edge captures are inactive.
                 + LSHIFT(0,  2) // DECAPEN0  0 The dual edge capture mode in this pair of channels is disabled.
                 + LSHIFT(1,  1) // COMP0     1 The channel (n+1) output is the complement of the channel (n) output.
                 + LSHIFT(0,  0) // COMBINE0  1 Channels (n) and (n+1) are combined.
  ;

  FTM0_INVCTRL = 0; // Инверсия в каналах отключена

  FTM0_C0SC = 0
              + LSHIFT(0, 6) // CHIE. 0 Disable channel interrupts. Use software polling.
              + LSHIFT(1, 3) // ELSB. Edge or Level Select. ELSB=1,ELSA=0 - установка низкого уровня на входе при совпадении
              + LSHIFT(1, 2) // ELSA. Edge or Level Select  ELSB=1,ELSA=1 - установка высокого уровня на входе при совпадении
              + LSHIFT(0, 0) // DMA.  0 Disable DMA transfers.
  ;
  FTM0_C1SC = 0
              + LSHIFT(0, 6) // CHIE. 0 Disable channel interrupts. Use software polling.
              + LSHIFT(1, 3) // ELSB. Edge or Level Select
              + LSHIFT(1, 2) // ELSA. Edge or Level Select
              + LSHIFT(0, 0) // DMA.  0 Disable DMA transfers.
  ;
  FTM0_C2SC = 0
              + LSHIFT(0, 6) // CHIE. 0 Disable channel interrupts. Use software polling.
              + LSHIFT(1, 3) // ELSB. Edge or Level Select
              + LSHIFT(1, 2) // ELSA. Edge or Level Select
              + LSHIFT(0, 0) // DMA.  0 Disable DMA transfers.
  ;
  FTM0_C3SC = 0
              + LSHIFT(0, 6) // CHIE. 0 Disable channel interrupts. Use software polling.
              + LSHIFT(1, 3) // ELSB. Edge or Level Select
              + LSHIFT(1, 2) // ELSA. Edge or Level Select
              + LSHIFT(0, 0) // DMA.  0 Disable DMA transfers.
  ;
  FTM0_C4SC = 0
              + LSHIFT(0, 6) // CHIE. 0 Disable channel interrupts. Use software polling.
              + LSHIFT(1, 3) // ELSB. Edge or Level Select
              + LSHIFT(1, 2) // ELSA. Edge or Level Select
              + LSHIFT(0, 0) // DMA.  0 Disable DMA transfers.
  ;
  FTM0_C5SC = 0
              + LSHIFT(0, 6) // CHIE. 0 Disable channel interrupts. Use software polling.
              + LSHIFT(1, 3) // ELSB. Edge or Level Select
              + LSHIFT(1, 2) // ELSA. Edge or Level Select
              + LSHIFT(0, 0) // DMA.  0 Disable DMA transfers.
  ;
  FTM0_C6SC = 0;
  FTM0_C7SC = 0;

  FTM0_C0V = 0;
  FTM0_C1V = 0;
  FTM0_C2V = 0;
  FTM0_C3V = 0;
  FTM0_C4V = 0;
  FTM0_C5V = 0;

  FTM0_FILTER  = 0;   // Входные фильтры запрещены

  FTM0_FLTCTRL = 0;   // Подготовим регист к программированию фильтров для входов ошибок
  FTM0_FLTPOL  = 0;   // Не меняем полярности входов ошибок. Активные - в сост. 1
  FTM0_FLTCTRL = 0;   // Фильтры и входы ошибок не используем
  FTM0_SYNC    = 0
                 + LSHIFT(1, 1)  // 1 The maximum loading point is enabled.
                 + LSHIFT(0, 0)  // 1 The minimum loading point is enabled
  ;

  FTM0_EXTTRIG = BIT(6);   // Генерацию тригеров используем для запуска PDB0 который запускает ADC

  FTM0_MODE  = 0
               + LSHIFT(1, 2)     // WPDIS. 1 -Write protection is disabled.
               + LSHIFT(1, 1)     // INIT. When a 1 is written to INIT bit the channels output is initialized according to the state of their corresponding bit in the OUTINIT register.
               + LSHIFT(1, 0)     // FTMEN. 1 -All registers including the FTM-specific registers (second set of registers) are available for use with no restrictions.
  ;
  FTM0_SYNCONF = 0
                 + LSHIFT(0, 20) // HWSOC.      1 A hardware trigger activates the SWOCTRL register synchronization.
                 + LSHIFT(0, 19) // HWINVC.     1 A hardware trigger activates the INVCTRL register synchronization.
                 + LSHIFT(0, 18) // HWOM.       1 A hardware trigger activates the OUTMASK register synchronization.
                 + LSHIFT(0, 17) // HWWRBUF.    1 A hardware trigger activates MOD, CNTIN, and CV registers synchronization.
                 + LSHIFT(0, 16) // HWRSTCNT.   1 A hardware trigger activates the FTM counter synchronization.
                 + LSHIFT(0, 12) // SWSOC.      1 The software trigger activates the SWOCTRL register synchronization.
                 + LSHIFT(0, 11) // SWINVC.     1 The software trigger activates the INVCTRL register synchronization.
                 + LSHIFT(0, 10) // SWOM.       1 The software trigger activates the OUTMASK register synchronization.
                 + LSHIFT(1,  9) // SWWRBUF.    1 The software trigger activates MOD, CNTIN, and CV registers synchronization
                 + LSHIFT(0,  8) // SWRSTCNT.   1 обновления регистров MOD, CNTIN, and CV произойдет сразу после установки флага SWSYNC. Если 0, то в точке загрузки при установленном флаге SWSYNC.
                 + LSHIFT(1,  7) // SYNCMODE.   1 Enhanced PWM synchronization is selected.
                 + LSHIFT(0,  5) // SWOC.       1 SWOCTRL регистр будет обновлен в точке зугрузки при наличии флага синхронизации, если 0 то будет обновлен сразу
                 + LSHIFT(0,  4) // INVC.       1 INVCTRL регистр будет обновлен в точке зугрузки при наличии флага синхронизации, если 0 то будет обновлен сразу
                 + LSHIFT(0,  2) // CNTINC.     1 CNTIN регистр будет обновлен в точке зугрузки при наличии флага синхронизации, если 0 то будет обновлен сразу
                 + LSHIFT(0,  1) // HWTRIGMODE. 1 FTM does not clear the TRIGj bit when the hardware trigger j is detected.
  ;

  FTM0_QDCTRL  = 0;   // Квадратурный декодер не используем

  FTM0_FMS = 0;       // Не защищаем от записи


  FTM0_CONF = 0
              + LSHIFT(0, 10) // GTBEOUT. 0 A global time base signal generation is disabled.
              + LSHIFT(0,  9) // GTBEEN.  0 Use of an external global time base is disabled.
              + LSHIFT(1,  6) // BDMMODE. 01- The channels outputs are forced to their safe value according to POLn bit
              + LSHIFT(0,  0) // NUMTOF.  0 - The TOF bit is set for each counter overflow.
  ;
/*
  Нет необходимости обновлять PWM при событии совпадения счетчика с установкой канала
  FTM0_PWMLOAD = 0
                 + LSHIFT(1, 9) // LDOK. 1 Loading updated values is enabled.
                 + LSHIFT(1, 5) // CH5SEL. 1 Include the channel in the matching process.
                 + LSHIFT(1, 4) // CH4SEL. 1 Include the channel in the matching process.
                 + LSHIFT(1, 3) // CH3SEL. 1 Include the channel in the matching process.
                 + LSHIFT(1, 2) // CH2SEL. 1 Include the channel in the matching process.
                 + LSHIFT(1, 1) // CH1SEL. 1 Include the channel in the matching process.
                 + LSHIFT(1, 0) // CH0SEL. 1 Include the channel in the matching process.
  ;
*/


  FTM0_OUTMASK = BIT(6) + BIT(7); // Установка в 1 бита в этом регистре запрещает работу соответствующего выхода и он устанавливается в состояние 0

  FTM0_SWOCTRL = 0xAAFF; // Запись в регистр слова 0x0000 позволяет выходам работать в нормальном режиме PWM
                         // Запись в регистр слова 0x00FF приводит к программной установке нулей на вcех выходах
                         // Запись слова 0xFFFF или 0x55FF приводит к установке в 1 выходов для верхних ключей и в 0 выходов для нижних ключей
                         // Запись слова 0xAAFF приводит к установке в 0 выходов для верхних ключей и в 1 выходов для нижних ключей

  // Запускаем PWM, выхода остаються в запрограммированом статическом состоянии
  FTM0_SC = 0
            + LSHIFT(0, 6) // TOIE. 1 Enable TOF interrupts. An interrupt is generated when TOF equals one.
            + LSHIFT(1, 5) // CPWMS. 1 -FTM counter operates in up-down counting mode.
            + LSHIFT(1, 3) // CLKS. 01 System clock
            + LSHIFT(0, 0) // PS. Prescale Factor Selection. 000 Divide by 1
  ;

}


/*-------------------------------------------------------------------------------------------------------------
  Старт работы PWM
-------------------------------------------------------------------------------------------------------------*/
void PWM_start(int dir, unsigned int freq)
{
  T_3ph_pwm pwm_3ph;

  mc_cbl.mot_freq  = freq;
  mc_cbl.direction = dir;

  if ( dir == MOVING_UP )
  {
    mc_cbl.pwm_scale = mc_cbl.up_accel_pwm_scale;
  }
  else
  {
    mc_cbl.pwm_scale = mc_cbl.down_accel_pwm_scale;
  }

  mc_cbl.ll_mot_freq = (unsigned long long)mc_cbl.mot_freq << 32;
  Gen_start(mc_cbl.mot_freq);
  MC_calculate_PWM(&pwm_3ph);
  FTM0_C0V = pwm_3ph.pwm_a;
  FTM0_C1V = pwm_3ph.pwm_a;
  FTM0_C2V = pwm_3ph.pwm_b;
  FTM0_C3V = pwm_3ph.pwm_b;
  FTM0_C4V = pwm_3ph.pwm_c;
  FTM0_C5V = pwm_3ph.pwm_c;

  _int_disable();
  FTM0_SYNCONF |= LSHIFT(1,  8); // Выставляем флаг для немедленного обновления регистров по флагу синхронизации
  FTM0_SYNC    |= BIT(7);        // Запускаем синхронизацию
  FTM0_CNT      = 0;             // Запись в регистр счетчка любого значения приводит к записи значения из CNTIN и установке начального состояния выходов
  FTM0_SYNCONF &= ~LSHIFT(1,  8); // Снимаем флаг немедленного обновления регистров по флагу синхронизации
  FTM0_SWOCTRL  = 0x0000;        // Запись в регистр слова 0x0000 позволяет выходам работать в нормальном режиме PWM
  FTM0_SC      &= ~BIT(7);       // Сбросим TOF
  FTM0_SC      |= BIT(6);        // Разрешаем прерывания от PWM
  _int_enable();
}

/*-------------------------------------------------------------------------------------------------------------
  Остановка работы PWM 
-------------------------------------------------------------------------------------------------------------*/
void PWM_stop(void)
{
  FTM0_SC &= ~BIT(6);    // Запрещаем прерывания от PWM
  FTM0_SWOCTRL = 0xAAFF; // Запись слова 0xAAFF приводит к установке в 0 выходов для верхних ключей и в 1 выходов для нижних ключей
}

/*-------------------------------------------------------------------------------------------------------------
 Возвращает состояние PWM
 0 - запрещен
 1 - разрешен
-------------------------------------------------------------------------------------------------------------*/
int PWM_state(void)
{
  if ( FTM0_SC & BIT(6) ) return 1;
  else return 0;
}

/*-------------------------------------------------------------------------------------------------------------
  Ожидание любого события  
-------------------------------------------------------------------------------------------------------------*/
_mqx_uint MC_get_events(_mqx_uint *events, _mqx_uint ticks, _mqx_uint events_mask)
{
  _mqx_uint res;
  res = _lwevent_wait_ticks(&evt_grp, events_mask, FALSE, ticks);
  if ( res == MQX_OK )
  {
    *events = _lwevent_get_signalled();
    _lwevent_clear(&evt_grp, *events);
  }
  else
  {
    *events = 0;
  }
  return res;
}

/*-------------------------------------------------------------------------------------------------------------
  Передать событие в модуль управления двигателем  
-------------------------------------------------------------------------------------------------------------*/
_mqx_uint MC_set_events(_mqx_uint evnt)
{
  return _lwevent_set(&evt_grp, evnt);

}
/*-------------------------------------------------------------------------------------------------------------
  Создать объект для обмена событиями 
-------------------------------------------------------------------------------------------------------------*/
void MC_create_event(void)
{
  _lwevent_create(&evt_grp, 0);
}

/*-------------------------------------------------------------------------------------------------------------
  Старт движения
  dir - MOVING_DOWN или MOVING_UP
  target_freq - целевая частота вращения (об/сек)
  time - время (сек) в течении которого частота должна подняться  до target_freq
-------------------------------------------------------------------------------------------------------------*/
void MC_start_motor_moving(INT8U dir,  INT32U target_freq, INT32U time)
{
  // Не обрабатывать команд на пуск пока разорвана цепь безопасности
  if (( PWM_state() == 0 ) && (Pin_PWM_OE_state()!=0))
  {
    PWM_start(dir, START_FREQ);
    MC_init_speed_change(MOT_START_ACTION, target_freq, time);
  }
}
/*-------------------------------------------------------------------------------------------------------------
  Остановка движения
  dir - MOVING_DOWN или MOVING_UP
  time - время (сек) в течении которого частота должна опуститься до 0
-------------------------------------------------------------------------------------------------------------*/
void MC_stop_motor_moving(INT32U time)
{
  if ( PWM_state() != 0 )
  {
    MC_init_speed_change(MOT_STOP_ACTION, 0, time);
  }
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void MC_emergency_stop_motor(void)
{
  PWM_stop();
  _int_disable();
  mc_cbl.mot_freq    = 0;
  mc_cbl.ll_mot_freq = 0;
  mc_cbl.skew_cnt    = 0;
  mc_cbl.ll_step     = 0;
  mc_cbl.action      = MOT_IDLE;
  _int_enable();
  Reset_aver_curr(); 
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void MC_get_CBL(T_MC_CBL *cbl_ptr)
{
  _int_disable();
  memcpy(cbl_ptr, &mc_cbl, sizeof(mc_cbl));
  _int_enable();
}
/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void MC_set_CBL(T_MC_CBL *cbl_ptr)
{
  _int_disable();
  memcpy(&mc_cbl, cbl_ptr, sizeof(mc_cbl));
  _int_enable();
}
/*-------------------------------------------------------------------------------------------------------------
  action - STOP_ACTION, START_ACTION 
  target_freq - частотота вращение к которой должен быть приведен двигатель
  target_time - время за которое должно произойти изменение частоты вращения, задается в десятых долях секунды
-------------------------------------------------------------------------------------------------------------*/
void MC_init_speed_change(unsigned int action,  unsigned int target_freq, unsigned int target_time)
{
  T_MC_CBL          cbl;
  float             t;
  Frac32            x;
  unsigned int      current_freq;

  MC_get_CBL(&cbl);

  if ( action == MOT_START_ACTION )
  {
    cbl.action = MOT_START_ACTION;
  }
  else if ( action == MOT_STOP_ACTION )
  {
    cbl.action = MOT_STOP_ACTION;
  }

  current_freq = cbl.mot_freq;
  if ( target_freq != current_freq  )
  {
    if ( target_time != 0 )
    {
      if ( (cbl.direction == MOVING_UP) && (action == MOT_STOP_ACTION) )
      {
        // Торможение при движении вверх
        if ( Get_aver_curr() < 9.0 )
        {
          target_freq = 5; 
        }
        else
        {
          target_freq = 15; // Повышаем конечную скорость остановки в случае большого тока 
        }
      }
      if ( (cbl.direction == MOVING_DOWN) && (action == MOT_STOP_ACTION) )
      {
        // Торможение при движении вниз
        if ( target_time > 5 )
        {
          target_time = target_time ; // Убавляем время торможения
        }
      }

      t = (float)(target_time / 10.0);
      t = t * PWM_FREQ;
      cbl.skew_cnt = (unsigned int)t;
      t = ((float)target_freq - (float)current_freq) * 0x100000000 / t;
      cbl.ll_step = (signed long long)t;
    }
    else
    {
      cbl.skew_cnt = 1;
      cbl.ll_step  = (target_freq - current_freq) * 0x100000000;
    }


    // Расчитаем дельту коэффициента масштабирования PWM при переходе от равномерного движения к ускоренному
    // Переход расчитываем за заданное в макросе PWM_SCALE_TRASITION_TIME время
    // Определим тип перехода:
    // - Ускорение при движении  вверх : увеличиваем коэффициент PWM до максимума
    // - Замедление при движении вверх : увеличиваем коэффициент PWM до максимума
    // - Ускорение при движении  вниз  : коэффициент PWM до максимума не на многобольше чем при равномерном движении
    // - Замедление при движении вниз  : увеличиваем коэффициент PWM до максимума

    if ( cbl.direction == MOVING_UP )
    {
      if ( action == MOT_START_ACTION )
      {
        // - Ускорение при движении  вверх
        cbl.pwm_scale_delta = (cbl.up_pwm_scale - cbl.pwm_scale) / (PWM_SCALE_TRASITION_TIME * PWM_FREQ);
        cbl.pwm_scale_cnt = PWM_SCALE_TRASITION_TIME * PWM_FREQ;
      }
      else if ( action == MOT_STOP_ACTION  )
      {
        // - Замедление при движении вверх
        cbl.pwm_scale_delta = (cbl.up_decel_pwm_scale - cbl.pwm_scale) / (PWM_SCALE_TRASITION_TIME * PWM_FREQ);
        cbl.pwm_scale_cnt = PWM_SCALE_TRASITION_TIME * PWM_FREQ;
      }
    }
    else
    {
      if ( action == MOT_START_ACTION  )
      {
        // - Ускорение при движении  вниз
        cbl.pwm_scale_delta = (cbl.down_pwm_scale - cbl.pwm_scale) / (PWM_SCALE_TRASITION_TIME * PWM_FREQ);
        cbl.pwm_scale_cnt = PWM_SCALE_TRASITION_TIME * PWM_FREQ;

      }
      else if ( action == MOT_STOP_ACTION  )
      {
        // - Замедление при движении вниз
        cbl.pwm_scale_delta = (cbl.down_decel_pwm_scale - cbl.pwm_scale) / (PWM_SCALE_TRASITION_TIME * PWM_FREQ);
        cbl.pwm_scale_cnt = PWM_SCALE_TRASITION_TIME * PWM_FREQ;
      }
    }

    MC_set_CBL(&cbl);
  }

  Reset_aver_curr(); // Сбрасываем средний измеренный ток за прошлый период


}


/*-------------------------------------------------------------------------------------------------------------
  Процедура обслуживания прерывания PWM
  Процедура активизирует задачу Motor_ISR_task поскольку в самой процедуре ISR нельзя использовать вычисления с плавающей точкой
-------------------------------------------------------------------------------------------------------------*/
static void ETM0_isr(pointer user_isr_ptr)
{
  Led_control(LED3, 1);

  if ( FTM0_SC & BIT(7) )
  {
    FTM0_SC &= ~BIT(7); // Сбросим TOF
  }
  FTM0_EXTTRIG &= ~BIT(7); // Сбросим триггер идущий к PDB

  _taskq_resume(mc_is_taskr_queue, FALSE);

  Led_control(LED3, 0);
}

/*-------------------------------------------------------------------------------------------------------------
  Задача инициируемая прерываниями IBV модулятора для пересчета текущих параметров ШИМ 
-------------------------------------------------------------------------------------------------------------*/
void      Motor_ISR_task(uint_32 initial_data)
{
  T_3ph_pwm                      pwm_3ph;

  mc_is_taskr_queue = _taskq_create(MQX_TASK_QUEUE_FIFO);
  if ( mc_is_taskr_queue == NULL )
  {
    _mqx_exit(0);
  }

  for (;;)
  {
    _taskq_suspend(mc_is_taskr_queue);

    Led_control(LED3, 1);

    MC_calculate_PWM(&pwm_3ph);
    FTM0_C0V = pwm_3ph.pwm_a;
    FTM0_C1V = pwm_3ph.pwm_a;
    FTM0_C2V = pwm_3ph.pwm_b;
    FTM0_C3V = pwm_3ph.pwm_b;
    FTM0_C4V = pwm_3ph.pwm_c;
    FTM0_C5V = pwm_3ph.pwm_c;
    FTM0_SYNC |= BIT(7);   //

    if ( arr_pos < TST_SMPLS_ARR_SZ )
    {
      smpls[8][arr_pos] = pwm_3ph.pwm_a;
      smpls[9][arr_pos] = pwm_3ph.pwm_b;
      smpls[10][arr_pos] = pwm_3ph.pwm_c;
    }

    // Изменение скорости вращения задается счетчиком и шагом
    if ( mc_cbl.skew_cnt != 0 )
    {
      mc_cbl.ll_mot_freq = mc_cbl.ll_mot_freq + mc_cbl.ll_step;       // Добавляем шаг
      mc_cbl.mot_freq = (mc_cbl.ll_mot_freq + 0x80000000ll) >> 32;    // Приводим к 32-х битному целому c округлением
      Gen_update_freq(mc_cbl.mot_freq);
      mc_cbl.skew_cnt--;
      if ( mc_cbl.skew_cnt == 0 )
      {
        // Фиксируем переход от ускорения к  равномерному движению.
        // Здесь определяем максимальный действующий ток в прошедшей фазе движения и корректируем масштабирование PWM для последующего движения
        if ( (mc_cbl.direction == MOVING_UP) && (mc_cbl.action == MOT_START_ACTION) )
        {
          if ( Get_aver_curr() < 9.0 )
          {
            // Корректируем масштабирование PWM до 0.5 поскольку вес не большой
            mc_cbl.pwm_scale_delta = (0.5 - mc_cbl.pwm_scale) / (PWM_SCALE_TRASITION_TIME * PWM_FREQ);
            mc_cbl.pwm_scale_cnt = PWM_SCALE_TRASITION_TIME * PWM_FREQ;
          }
          Reset_aver_curr();
        }
        if (  mc_cbl.action == MOT_STOP_ACTION ) // Если это было не торможение, то это равномерное движение
        {
          MC_emergency_stop_motor();
        }
        mc_cbl.action = MOT_UNIFORM_MOTION;
      }
    }

    // Плавно изменяем коэффициент масштабирования PWM
    if ( mc_cbl.pwm_scale_cnt != 0 )
    {
      mc_cbl.pwm_scale += mc_cbl.pwm_scale_delta;
      mc_cbl.pwm_scale_cnt--;
    }


    // Останавливаем движение если скрость снизилась до минимальной
    if ( mc_cbl.mot_freq <= MIN_FREQ )
    {
      MC_emergency_stop_motor();
      
    }
    Led_control(LED3, 0);
  }
}

T_MC_CBL* MC_get_pcbl(void)
{
  return &mc_cbl;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rip.h<|end_filename|>
#ifndef __rip_h__
#define __rip_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rip.h$
* $Version : 3.0.6.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   Definitions for the RIP protocol layer.
*
*END************************************************************************/

#include "ip_prv.h"

#if RTCSCFG_ENABLE_RIP_STATS
#define IF_RIP_STATS_ENABLED(x) x
#else
#define IF_RIP_STATS_ENABLED(x)
#endif


/*
** RIP packet header
*/
typedef struct rip_header {
   uchar    COMMAND[1];
   uchar    VERSION[1];
   uchar    MBZ[2];
} RIP_HEADER, _PTR_ RIP_HEADER_PTR;

/*
** RIP packet entry
*/
typedef struct rip_entry {
   uchar    FAMILY[2];
   uchar    RT_TAG[2];
   uchar    NETADDR[4];
   uchar    NETMASK[4];
   uchar    NEXTHOP[4];
   uchar    METRIC[4];
} RIP_ENTRY, _PTR_ RIP_ENTRY_PTR;

/*
** RIP Configuration.  This information is persistent for the RIP layer.
*/
typedef struct rip_cfg_struct {
#if RTCSCFG_ENABLE_RIP_STATS
   RIP_STATS      STATS;
#endif

   TCPIP_EVENT    TIMER_PERIODIC; /* for periodic advertisement */
   TCPIP_EVENT    TIMER_TRIG_UPD; /* to avoid a excessive traffic with
                                  ** the trigger updates
                                  */

   boolean        RT_CHANGED_F;   /* TRUE if routes have been modified */

   UCB_STRUCT_PTR UCB; /* the struture to send/rcv udp packet */
} RIP_CFG_STRUCT, _PTR_ RIP_CFG_STRUCT_PTR;

/* list of rip commands */
#define RIPCMD_REQUEST          1       /* want info - from suppliers */
#define RIPCMD_RESPONSE         2       /* responding to request */
        /* unofficial commands (ie gated ones) */
#define RIPCMD_TRACEON          3       /* turn tracing on */
#define RIPCMD_TRACEOFF         4       /* turn it off */
#define RIPCMD_POLL             5       /* like request, but anyone answers */
#define RIPCMD_POLLENTRY        6       /* like poll, but for entire entry */

/* rip limits */
#define RIP_MAX_METRIC          16      /* per Xerox NS */
#define RIP_MIN_METRIC          1       /* per Xerox NS */
#define RIP_MAX_PKTLEN          512     /* max broadcast size */

/* rip timer */
#if 1   /* the official values */
# define RIP_TIMEOUT_DEL         (180*1000)  /* time to mark entry invalid */
# define RIP_TIMEOUT_GC          (120*1000)  /* time to garbage collect */
# define RIP_TIME_MIN_TRIG_UPD   (1*1000)    /* rfc2453.3.10.1 */
# define RIP_TIME_MAX_TRIG_UPD   (5*1000)
# define RIP_TIME_MIN_PERIODIC   (25*1000)   /* rfc2453.3.8 */
# define RIP_TIME_MAX_PERIODIC   (35*1000)
#else   /* the debug values */
# define RIP_TIMEOUT_DEL         (18*1000)   /* time to mark entry invalid */
# define RIP_TIMEOUT_GC          (12*1000)   /* time to garbage collect */
# define RIP_TIME_MIN_TRIG_UPD   (1*1000)    /* rfc2453.3.10.1 */
# define RIP_TIME_MAX_TRIG_UPD   (5*1000)
# define RIP_TIME_MIN_PERIODIC   (1*1000)    /* rfc2453.3.8 */
# define RIP_TIME_MAX_PERIODIC   (2*1000)
#endif


/* if the route will timeout in less than RIP_ALMOST_EXPIRED_TIME, it is
** considered as dying and can be replaced by an equal metric route.
** rfc2453.3.9.2
*/
#define RIP_ALMOST_EXPIRED_TIME (RIP_TIMEOUT_DEL/5)

#define RIP_V1  1
#define RIP_V2  2


void RIP_init_static_rt(IP_ROUTE_INDIRECT_PTR gate, uint_16 metric);
void RIP_remove_rt(IP_ROUTE_INDIRECT_PTR gate);
void RIP_new_bindif(IP_ROUTE_DIRECT_PTR bindif);

#endif  /* __rip_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/serl_mk40.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_mk40.c$
* $Version : 3.7.2.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains board-specific serial initialization functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "serl_kuart.h"

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_serial_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding UART
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_serial_base_address(uint_8 dev_num) {
    pointer addr;

    switch(dev_num) {
	case 0:
	    addr = (pointer)UART0_BASE_PTR;
	    break;
	case 1:
	    addr = (pointer)UART1_BASE_PTR;
	    break;
	case 2:
	    addr = (pointer)UART2_BASE_PTR;
	    break;	
	case 3:
	    addr = (pointer)UART3_BASE_PTR;
	    break;	
 	case 4:
	    addr = (pointer)UART4_BASE_PTR;
	    break;	
 	case 5:
	    addr = (pointer)UART5_BASE_PTR;
	    break;	
        default:
	    addr = 0;
    }
    
    return addr;
}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/mem_copy.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mem_copy.c$
*
* Comments:
*
*   This file contains the functions for copying memory.
*
*END************************************************************************/

#include "mqx_inc.h"

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _mem_copy
* Returned Value   : none
* Comments         :
*   This function copies the specified number of bytes from the
* source address to the destination address.  No attempt is made
* to handle overlapping copies to prevent loss of data.
*   The copying is optimized to avoid alignment problems, and attempts
* to copy 32bit numbers optimally
*
*END*----------------------------------------------------------------------*/

#if MQXCFG_MEM_COPY

void _mem_copy
   (
      /* [IN] address to copy data from */
      pointer  from_ptr,

      /* [IN] address to copy data to */
      pointer  to_ptr,

      /* [IN] number of bytes to copy */
      register _mem_size number_of_bytes
   )
{ /* Body */
#if MQX_USE_SMALL_MEM_COPY
   register uint_8_ptr from8_ptr = (uint_8_ptr) from_ptr;
   register uint_8_ptr to8_ptr = (uint_8_ptr) to_ptr;

   if (number_of_bytes) {
      while (number_of_bytes--) {
         *to8_ptr++ = *from8_ptr++;
      } /* Endwhile */      
   } /* Endif */
#else
   uint_8_ptr from8_ptr = (uint_8_ptr) from_ptr;
   uint_8_ptr to8_ptr = (uint_8_ptr) to_ptr;
   uint_16_ptr from16_ptr = (uint_16_ptr) from_ptr;
   uint_16_ptr to16_ptr = (uint_16_ptr) to_ptr;
   register uint_32_ptr from32_ptr = (uint_32_ptr) from_ptr;
   register uint_32_ptr to32_ptr = (uint_32_ptr) to_ptr;
   
   /* Target and source have the same offset of alignment address */
   if (number_of_bytes > 3 && (((uint_32)from_ptr & 0x03) == ((uint_32)to_ptr & 0x03))) {
      /* Try to align source on word */
      if ((uint_32)from_ptr & 1) {
         from8_ptr = (uint_8_ptr) from_ptr;
         to8_ptr = (uint_8_ptr) to_ptr;

         *to8_ptr++ = *from8_ptr++;

         from_ptr = from8_ptr;
         to_ptr = to8_ptr;
         --number_of_bytes;
      } /* Endif */

      /* Try to align source on longword */
      if ((uint_32)from_ptr & 2) {
         from16_ptr = (uint_16_ptr) from_ptr;
         to16_ptr = (uint_16_ptr) to_ptr;

         *to16_ptr++ = *from16_ptr++;

         from_ptr = from16_ptr;
         to_ptr = to16_ptr;
         number_of_bytes -= 2;
      } /* Endif */

      from32_ptr = (uint_32_ptr) from_ptr;
      to32_ptr = (uint_32_ptr) to_ptr;
#if MQX_USE_BLOCK_MEM_COPY
      /* 
      ** To increase performance a bit, we will copy 64 bytes (16 * longwords) sequentially
      ** This consumes more RAM, more flash, but gets less instruction cycles.
      */
      for (; number_of_bytes >= 0x40; number_of_bytes -= 0x40) {
         /* copy 16 longwords */
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
         *to32_ptr++ = *from32_ptr++;
      } /* Endwhile */
      
      /* Calculate number of remains 4B alignment bytes and write them */
      switch (number_of_bytes & 0x3c) {
         case (15 << 2): *to32_ptr++ = *from32_ptr++;
         case (14 << 2): *to32_ptr++ = *from32_ptr++;
         case (13 << 2): *to32_ptr++ = *from32_ptr++;
         case (12 << 2): *to32_ptr++ = *from32_ptr++;
         case (11 << 2): *to32_ptr++ = *from32_ptr++;
         case (10 << 2): *to32_ptr++ = *from32_ptr++;
         case (9  << 2): *to32_ptr++ = *from32_ptr++;
         case (8  << 2): *to32_ptr++ = *from32_ptr++;
         case (7  << 2): *to32_ptr++ = *from32_ptr++;
         case (6  << 2): *to32_ptr++ = *from32_ptr++;
         case (5  << 2): *to32_ptr++ = *from32_ptr++;
         case (4  << 2): *to32_ptr++ = *from32_ptr++;
         case (3  << 2): *to32_ptr++ = *from32_ptr++;
         case (2  << 2): *to32_ptr++ = *from32_ptr++;
         case (1  << 2): *to32_ptr++ = *from32_ptr++;
      } /* Endswitch */
      
      number_of_bytes = number_of_bytes & (0x03); /* Now get number of unaligned bytes */
#else /* MQX_USE_BLOCK_MEM_COPY */
      for (; number_of_bytes >= 0x4; number_of_bytes -= 0x4) {
         *to32_ptr++ = *from32_ptr++;
      }
#endif /* MQX_USE_BLOCK_MEM_COPY */
      from_ptr = from32_ptr;
      to_ptr = to32_ptr;
   } /* Endif */
   
   /* copy remains */
   if (number_of_bytes) {
      from8_ptr = (uint_8_ptr)from_ptr;
      to8_ptr = (uint_8_ptr)to_ptr;
      while (number_of_bytes--) {
         *to8_ptr++ = *from8_ptr++;
      }
   }
#endif
} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/cortex.h<|end_filename|>
/**HEADER*********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* $FileName: cortex.h$
* $Version : 3.8.15.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   This file contains the type definitions for the ARM Cortex processors.
*
*END************************************************************************/

#ifndef __cortex_h__
#define __cortex_h__

/*==========================================================================*/
/*
**                   MQX REQUIRED DEFINITIONS
**
** Other MQX kernel and component functions require these definitions to exist.
*/

/* Indicate which endian this PSP is */
#if defined(__ARM__) || defined(__GHS__)
    #ifdef __BIG_ENDIAN
        #define PSP_ENDIAN          MQX_BIG_ENDIAN
    #else
        #define PSP_ENDIAN          MQX_LITTLE_ENDIAN
    #endif
#elif defined(__MET__)
    #ifdef _BE
        #define PSP_ENDIAN          MQX_BIG_ENDIAN
    #else
        #define PSP_ENDIAN          MQX_LITTLE_ENDIAN
    #endif
#elif defined(__GNUC__)
    #ifdef BYTES_BIG_ENDIAN
        #define PSP_ENDIAN          MQX_BIG_ENDIAN
    #else
        #define PSP_ENDIAN          MQX_LITTLE_ENDIAN
    #endif
#else
    #define PSP_ENDIAN              MQX_LITTLE_ENDIAN
#endif

/*
** Memory alignment requirements.
** The alignment indicates how memory is to be aligned for all memory
** accesses.   This is to avoid mis-aligned transfers of data, thus
** optimizing memory accesses.
*/
#define PSP_MEMORY_ALIGNMENT        (PSP_CACHE_LINE_SIZE-1)
#define PSP_MEMORY_ALIGNMENT_MASK   (~PSP_MEMORY_ALIGNMENT)

/*
** Stack alignment requirements.
** The alignment indicates how the stack is to be initially aligned.
** This is to avoid mis-aligned types on the stack
*/
#define PSP_STACK_ALIGNMENT         PSP_MEMORY_ALIGNMENT
#define PSP_STACK_ALIGNMENT_MASK    PSP_MEMORY_ALIGNMENT_MASK

/*
** Indicate the direction of the stack
*/
#define PSP_STACK_GROWS_TO_LOWER_MEM                (1)

/*
** Indicate addressing capability of the CPU
** This is the memory width. i.e., the number of bits addressed
** by each memory location.
*/
#define PSP_MEMORY_ADDRESSING_CAPABILITY            (8)

/*
** Indicate alignment restrictions on memory accesses
** For an n-bit memory access,
**
** if n <  PSP_MEMORY_ACCESSING_CAPABILITY,
**         n-bit accesses must be n-bit-aligned
**
** if n >= PSP_MEMORY_ACCESSING_CAPABILITY,
**         n-bit accesses must be PSP_MEMORY_ACCESSING_CAPABILITY-bit-aligned
*/
#define PSP_MEMORY_ACCESSING_CAPABILITY             (32)

/*
** Define padding need to make the STOREBLOCK_STRUCT aligned properly
*/
#define PSP_MEM_STOREBLOCK_ALIGNMENT                (2)

/*
**   MINIMUM STACK SIZE FOR A TASK
*/

/*
** Memory overhead on users stack before switching over to the interrupt stack.

*/
#if PSP_MQX_CPU_IS_ARM_CORTEX_M4
    #define PSP_STACK_INTERRUPT_OVERHEAD            (116)
#else /* PSP_MQX_CPU_IS_ARM_CORTEX_M0 is assumed */
    #define PSP_STACK_INTERRUPT_OVERHEAD            (64)
#endif

/* This much extra stack is required for the logging of mqx functions */
#if MQX_KERNEL_LOGGING
    #define PSP_STACK_KLOG_OVERHEAD                 (128)
#else
    #define PSP_STACK_KLOG_OVERHEAD                 (0)
#endif

/* Minimum stack size for all tasks. */
#define PSP_MINSTACKSIZE                      \
            (sizeof(PSP_STACK_START_STRUCT) + \
            PSP_STACK_INTERRUPT_OVERHEAD    + \
            PSP_STACK_KLOG_OVERHEAD)

/* Minimum stack size for the Idle Task
**   Idle task written in C uses at most 8 bytes of stack:
**     1 Link Instruction, 1 local variable (pointer)
*/
#define PSP_IDLE_STACK_SIZE                         (PSP_MINSTACKSIZE + 8)

/* Motorola addresses do not need to be normalized
** (ie as for example the Intel chips in real mode do require this)
*/
#define _PSP_NORMALIZE_MEMORY(x)                    (x)

/*==========================================================================*/
/*
**                    PSP SPECIFIC DEFINITIONS
**
*/


/*
** The maximum number of hardware interrupt vectors
*/
#if PSP_MQX_CPU_IS_ARM_CORTEX_M4
    #define PSP_MAXIMUM_INTERRUPT_VECTORS           (0x100)
#else /* PSP_MQX_CPU_IS_ARM_CORTEX_M0 is assumed */
    #define PSP_MAXIMUM_INTERRUPT_VECTORS           (0x2F)
#endif


#ifndef __ASM__

/*
** PSP FUNCTION CALL STRUCT
**
** This structure defines what a function call pushes onto the stack
*/
typedef struct psp_function_call_struct
{

   /* Frame pointer (r11) pushed onto the stack for back tracing */
   pointer              FP_REGISTER;

   /* Pushed onto the stack by the JSR instruction */
   void     (_CODE_PTR_ RETURN_ADDRESS)(void);

} PSP_FUNCTION_CALL_STRUCT, _PTR_ PSP_FUNCTION_CALL_STRUCT_PTR;


/*==========================================================================*/
/*                         MQX DATA TYPES                                   */


/*-----------------------------------------------------------------------*/
/*
** PSP BLOCKED STACK STRUCT
**
** This is what a stack looks like for a task that is NOT the active
** task
*/
typedef struct psp_blocked_stack_struct
{
#if PSP_MQX_CPU_IS_ARM_CORTEX_M4
    uint_32 PENDSVPRIOR;
    uint_32 BASEPRI;
#endif
    uint_32 R4;
    uint_32 R5;
    uint_32 R6;
    uint_32 R7;
    uint_32 R8;
    uint_32 R9;
    uint_32 R10;
    uint_32 R11;
#if PSP_MQX_CPU_IS_ARM_CORTEX_M4
    uint_32 LR2;
#endif
    uint_32 R0;
    uint_32 R1;
    uint_32 R2;
    uint_32 R3;

    uint_32 R12;
    uint_32 LR;
    uint_32 PC;
    uint_32 PSR;
} PSP_BLOCKED_STACK_STRUCT, _PTR_ PSP_BLOCKED_STACK_STRUCT_PTR;

#if PSP_HAS_FPU
/*-----------------------------------------------------------------------*/
/*
** PSP BLOCKED FP STRUCT
**
** This structure defines the registers stored by MQX when a floating
** point task is blocked.  When the FLOATING_POINT_REGISTERS_STORED bit
** is set task's FLAGS, then this structure is valid.
*/
typedef struct psp_blocked_fp_struct {
    uint_32  FPCCR;     /* FP Context Control Register                  */
    uint_32  FPCAR;     /* FP Context Address Register                  */
    uint_32  FPDSCR;    /* FP Default Status Control Register           */
    uint_32  FPSCR;     /* FP Status Control Register                   */
    uint_32  TID;       /* Testing for correctness                      */
    float S[32];        /* The floating point computation registers     */
} PSP_BLOCKED_FP_STRUCT, _PTR_ PSP_BLOCKED_FP_STRUCT_PTR;

#endif

/*-----------------------------------------------------------------------*/
/*
** PSP INTERRUPT CONTEXT STRUCT
**
** This structure provides a "context" for mqx primitives to use while executing
** in an interrupt handler.  A link list of these contexts is built on the
** interrupt stack.  The head of this list (the current interrupt context) is
** pointed to by the INTERRUPT_CONTEXT_PTR field of the kernel data structure.
**
*/
typedef struct psp_int_context_struct
{
    /* Address of previous context, NULL if none */
    struct psp_int_context_struct _PTR_ PREV_CONTEXT;

    /* The exception number for this interrupt frame */
    uint_32                             EXCEPTION_NUMBER;

    /* Used by the _int_enable function while in the ISR */
    uint_32                             ENABLE_SR;

    /* The "task" error code for use by mqx functions while in the ISR */
    uint_32                             ERROR_CODE;
} PSP_INT_CONTEXT_STRUCT, _PTR_ PSP_INT_CONTEXT_STRUCT_PTR;


/*-----------------------------------------------------------------------*/
/*
** PSP BASIC INT FRAME STRUCT
**
** This structure is what is pushed onto the memory on the current stack
** when an interrupt occurs.
**
** For the first interrupt that interrupts a running task, this structure
** defines what the top of the stack for the task looks like,
** and the STACK_PTR field of the task descriptor will point to this structure.
**
** The rest of the interrupt frame is then built upon the interrupt stack.
**
** For a nested interrupt, this basic frame is also built upon the interrupt
** stack.
**
*/

typedef struct psp_basic_int_frame_struct {
    uint_32 R0;
    uint_32 R1;
    uint_32 R2;
    uint_32 R3;

    uint_32 R12;
    uint_32 LR;
    uint_32 PC;
    uint_32 PSR;
} PSP_BASIC_INT_FRAME_STRUCT, _PTR_ PSP_BASIC_INT_FRAME_STRUCT_PTR;

/*-----------------------------------------------------------------------*/
/*
** PSP STACK START STRUCT
**
** This structure is used during the initialization of a new task.
** It is overlaid on the bottom of the task's stack
**
*/
typedef struct psp_stack_start_struct
{
    /* The start up registers for the task */
    PSP_BLOCKED_STACK_STRUCT    INITIAL_CONTEXT;

    /* The end of INITIAL CONTEXT has to be aligned at 8B boundary. Presuming that the end of this structure is
    ** aligned at PSP_STACK_ALIGN boundary, we must add reserved bytes to achieve alignment.
    ** The reserved space is computed from the used space from the end (5 * 32-bit value).
    */
    uint_8                      RESERVED[(PSP_STACK_ALIGNMENT_MASK - 5 * sizeof(uint_32)) & 0x7];

    /* Previous stack pointer for exit return */
    pointer                     PREVIOUS_STACK_POINTER;

    /* The function to call when the task "returns" */
    void                        (_CODE_PTR_ EXIT_ADDRESS)();

    /* The task's parameter */
    uint_32                     PARAMETER;

    /* The following two fields are used to create a "bottom" of stack
    ** that debuggers will recognize
    */
    /* End stack pointer    */
    pointer                     ZERO_STACK_POINTER;

    /* close the stack frame with a return address of 0 */
    uint_32                     ZERO_RETURN_ADDRESS;

} PSP_STACK_START_STRUCT, _PTR_ PSP_STACK_START_STRUCT_PTR;

#define PSP_STACK_PARAMETER PARAMETER


/*--------------------------------------------------------------------------*/
/*
**                  PROTOTYPES OF PSP FUNCTIONS
*/


/*
** PROCESSOR MEMORY BOUNDS
*/
#define CORTEX_PERIPH_BASE                  (0x40000000ul)    // peripheral base address
#define CORTEX_PRI_PERIPH_IN_BASE           (0xe0000000ul)    // private peripheral internal base address

/* minimal implemented priority required by Cortex core */
#ifndef CORTEX_PRIOR_IMPL
    #if PSP_MQX_CPU_IS_ARM_CORTEX_M0P
        #define CORTEX_PRIOR_IMPL           (1)
    #elif PSP_MQX_CPU_IS_ARM_CORTEX_M4
        #define CORTEX_PRIOR_IMPL           (3)
    #endif
#endif /* CORTEX_PRIOR_IMPL */

#define CORTEX_PRIOR_SHIFT                  (8 - CORTEX_PRIOR_IMPL)
#define CORTEX_PRIOR_MASK                   ((0xff << CORTEX_PRIOR_SHIFT) & 0xff)
#define CORTEX_PRIOR(x)                     (((x) << CORTEX_PRIOR_SHIFT) & CORTEX_PRIOR_MASK)

#define CORTEX_INT_FIRST_INTERNAL       0

#ifndef CORTEX_INT_LAST_INTERNAL
#if PSP_MQX_CPU_IS_ARM_CORTEX_M0P
    #define CORTEX_INT_LAST_INTERNAL        (32)
#elif PSP_MQX_CPU_IS_ARM_CORTEX_M4
    #define CORTEX_INT_LAST_INTERNAL        (250)
#endif
#endif /* CORTEX_INT_LAST_INTERNAL */

#define PSP_INT_FIRST_INT_ROUTER		16

#define PSP_INT_FIRST_INTERNAL              (CORTEX_INT_FIRST_INTERNAL)
#define PSP_INT_LAST_INTERNAL               (CORTEX_INT_LAST_INTERNAL)

#define CORTEX_MPU_REC                      (12)

#define MPU_SM_RWX                          (0)
#define MPU_SM_RX                           (1)
#define MPU_SM_RW                           (2)
#define MPU_SM_AS_USER                      (3)

#define MPU_UM_R                            (4)
#define MPU_UM_W                            (2)
#define MPU_UM_X                            (1)

#define MPU_UM_RW                           (MPU_UM_R | MPU_UM_W)

/*
** CORTEX_SCS_STRUCT
** Reset and Clock Control
*/
typedef struct cortex_syst_struct {
    uint_32 CSR;      /* SysTick Control and Status */
    uint_32 RVR;      /* SysTick Reload value       */
    uint_32 CVR;      /* SysTick Current value      */
    uint_32 CALIB;    /* SysTick Calibration value  */
} CORTEX_SYST_STRUCT, _PTR_ CORTEX_SYST_STRUCT_PTR;
typedef volatile struct cortex_syst_struct _PTR_ VCORTEX_SYST_STRUCT_PTR;

/*
** CORTEX_NVIC_STRUCT
** Reset and Clock Control
*/
typedef struct cortex_nvic_struct {
    uint_32 ENABLE[32];
    uint_32 DISABLE[32];
    uint_32 SET[32];
    uint_32 CLR[32];
    uint_32 ACTIVE[32];
    uint_32 rsvd[32];
    uint_32 PRIORITY[32];
} CORTEX_NVIC_STRUCT, _PTR_ CORTEX_NVIC_STRUCT_PTR;
typedef volatile struct cortex_nvic_struct _PTR_ VCORTEX_NVIC_STRUCT_PTR;

/*
** CORTEX_SCB_STRUCT
** system control block
*/
typedef struct cortex_scb_struct {
    uint_32 CPUID;
    uint_32 ICSR;
    uint_32 VTOR;
    uint_32 AIRCR;
    uint_32 SCR;
    uint_32 CCR;
    uint_32 SHPR1;
    uint_32 SHPR2;
    uint_32 SHPR3;
    uint_32 SHCRS;
    uint_32 CFSR;
    uint_32 HFSR;
} CORTEX_SCB_STRUCT, _PTR_ CORTEX_SCB_STRUCT_PTR;
typedef volatile struct cortex_scb_struct _PTR_ VCORTEX_SCB_STRUCT_PTR;

/*
** CORTEX__SCS_STRUCT
** This structure defines the memory/registers provided by the CORTEX core
** 0xE0000000 - 0xE0100000
*/
typedef struct cortex_scs_struct
{
    uchar           filler0[0xe010];
    CORTEX_SYST_STRUCT      SYST;
    uchar           filler1[0xE000E100 - (0xE000E010 + sizeof(CORTEX_SYST_STRUCT))];
    CORTEX_NVIC_STRUCT      NVIC;
    uchar           filler2[0xE000ED00 - (0xE000E100 + sizeof(CORTEX_NVIC_STRUCT))];
    CORTEX_SCB_STRUCT       SCB;
} CORTEX_SCS_STRUCT, _PTR_ CORTEX_SCS_STRUCT_PTR;
typedef volatile struct cortex_scs_struct _PTR_ VCORTEX_SCS_STRUCT_PTR;

#define _PSP_GET_VTOR()     (_mqx_max_type)(((VCORTEX_SCS_STRUCT_PTR)CORTEX_PRI_PERIPH_IN_BASE)->SCB.VTOR);
#define _PSP_SET_VTOR(x)    ((VCORTEX_SCS_STRUCT_PTR)CORTEX_PRI_PERIPH_IN_BASE)->SCB.VTOR = ((uint_32)(x));



/* Interrupt Acknowledge Level and Priority Register
**
** Interrupt priority can range 0 (lowest) to 7 (highest priority) and
** a special value 8 (mid-point) for fixed level interrupts
*/
typedef uint_8 _int_level;
typedef uint_8 _int_priority;

/*--------------------------------------------------------------------------*/
/*
**                  PROTOTYPES OF PSP FUNCTIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

/* Generic PSP prototypes */
_mqx_uint _psp_int_init(_mqx_uint, _mqx_uint);
void _psp_int_install(void);
void __set_MSP(uint_32);

uint_32 _psp_core_num(void);

/* Enable and disable ALL interrupts on ARM CortexM processors.
  Some compilers export this function as pre-defined macro                    */
#ifndef __enable_interrupt
extern void         __enable_interrupt(void);
#endif
#ifndef __disable_interrupt
extern void         __disable_interrupt(void);
#endif

#endif // __ASM__

#ifdef __cplusplus
}
#endif

#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/usb/usb_vybrid.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_vybrid.c$
* $Version : 3.8.4.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains board-specific USB initialization functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "bsp_prv.h"

struct usb_host_if_struct _bsp_usb_host_ehci0_if = {
    &_usb_ehci_host_callback_table,
    (pointer) &_ehci0_host_init_param,
    NULL
};

struct usb_host_if_struct _bsp_usb_host_ehci1_if = {
    &_usb_ehci_host_callback_table,
    (pointer) &_ehci1_host_init_param,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_usb_host_init
* Returned Value   : 0 for success, -1 for failure
* Comments         :
*    This function performs BSP-specific initialization related to USB
*
*END*----------------------------------------------------------------------*/
_mqx_int _bsp_usb_host_init(struct usb_host_if_struct *usb_if)
{
    USB_MemMapPtr usb_ptr;
    USB_EHCI_HOST_INIT_STRUCT_PTR usb_init;
    _mqx_int result;

    if (usb_if == NULL) {
        return IO_ERROR;
    }

    if (usb_if->HOST_INIT_PARAM == &_ehci0_host_init_param) {
        usb_ptr = USB0_BASE_PTR;
    }
    else if (usb_if->HOST_INIT_PARAM == &_ehci1_host_init_param) {
        usb_ptr = USB1_BASE_PTR;
    }
    else {
        return IO_ERROR; /* unknown controller */
    }

    result = _bsp_usb_host_io_init(usb_if);

    if (result != MQX_OK)
        return result;

    USB_USBCMD_REG(usb_ptr) &= ~USB_USBCMD_RS_MASK;
    while (USB_USBCMD_REG(usb_ptr) & USB_USBCMD_RS_MASK);
    { /* delay while resetting USB controller */ }
    USB_USBCMD_REG(usb_ptr) |= USB_USBCMD_RST_MASK;
    while (USB_USBCMD_REG(usb_ptr) & USB_USBCMD_RST_MASK)
    { /* delay while resetting USB controller */ }

    USB_USBMODE_REG(usb_ptr) = USB_USBMODE_CM_MASK;
    USB_USBCMD_REG(usb_ptr) = USB_USBCMD_ASP(3) | USB_USBCMD_ITC(0);

    /* setup interrupt */
    usb_init = (USB_EHCI_HOST_INIT_STRUCT_PTR)usb_if->HOST_INIT_PARAM;
    result = _bsp_int_init(usb_init->VECTOR, BSP_USB_INT_LEVEL, 0, TRUE);

    return result;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_usb_base
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the address of USB OTG module
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_usb_base(uint_8 dev_num)
{
    if (dev_num == 0) {
        return (pointer)USB0_BASE_PTR;
    }
    else if (dev_num == 1) {
        return (pointer)USB1_BASE_PTR;
    }

    return NULL;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_usb_vector
* Returned Value   : Vector Number upon success, 0 upon failure
* Comments         :
*    This function returns the vector number of the VUSBHS Host Module
*
*END*----------------------------------------------------------------------*/
uint_8 _bsp_get_usb_vector
(
    uint_8 dev_num
)
{
    if (dev_num == 0) {
        return INT_USB0;
    }
    else if (dev_num == 1) {
        return INT_USB1;
    }
   
    return 0;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_usb_capability_register_base
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the address of the VUSBHS Capability Registers
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_usb_capability_register_base(uint_8 dev_num)
{
    if (dev_num == 0) {
        return (pointer) ((uchar *) USB0_BASE_PTR + 0x100);
    }
    else if (dev_num == 1) {
        return (pointer) ((uchar *) USB1_BASE_PTR + 0x100);
    }

    return NULL;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_usb_timer_register_base
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the address of the VUSBHS Timer Registers
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_usb_timer_register_base(uint_8 dev_num)
{
    if (dev_num == 0) {
        return (pointer) ((uchar *) USB0_BASE_PTR + 0x100);
    }
    else if (dev_num == 1) {
        return (pointer) ((uchar *) USB1_BASE_PTR + 0x80);
    }

    return NULL;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_usb_otg_csr
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the address of the U0CSR register
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_usb_otg_csr(uint_8 dev_num)
{
    return NULL;
}

void _bsp_usb_hs_disconnect_detection_enable(pointer host_handle)
{
    USB_EHCI_HOST_INIT_STRUCT_PTR host_init = (USB_EHCI_HOST_INIT_STRUCT_PTR)_usb_host_get_init(host_handle);

    if (&_ehci0_host_init_param == host_init) {
        USBPHY0_CTRL_SET = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
    }
    else if (&_ehci1_host_init_param == host_init) {
        USBPHY1_CTRL_SET = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
    }
}

void _bsp_usb_hs_disconnect_detection_disable(pointer host_handle)
{
    USB_EHCI_HOST_INIT_STRUCT_PTR host_init = (USB_EHCI_HOST_INIT_STRUCT_PTR)_usb_host_get_init(host_handle);

    if (&_ehci0_host_init_param == host_init) {
        USBPHY0_CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
    }
    else if (&_ehci1_host_init_param == host_init) {
        USBPHY1_CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
    }
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/snmp/mib.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mib.c$
* $Version : 3.8.19.0$
* $Date    : Sep-12-2012$
*
* Comments:
*
*   This file contains an implementation of a MIB
*   walker for the SNMP agent.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "snmpcfg.h"
#include "asn1.h"
#include "snmp.h"

#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4

static boolean RTCSMIB_output (RTCSMIB_WALK_PTR, RTCSMIB_NODE_PTR, pointer);

/***********************************************************
**
** BEGIN RFC1155-SMI, SNMPv2-SMI definitions
**
*/

extern RTCSMIB_NODE MIBNODE_iso_org;
extern RTCSMIB_NODE MIBNODE_dod;
extern RTCSMIB_NODE MIBNODE_internet;
extern RTCSMIB_NODE MIBNODE_directory;
extern RTCSMIB_NODE MIBNODE_mgmt;
extern RTCSMIB_NODE MIBNODE_experimental;
extern RTCSMIB_NODE MIBNODE_private;
extern RTCSMIB_NODE MIBNODE_enterprises;
extern RTCSMIB_NODE MIBNODE_security;
extern RTCSMIB_NODE MIBNODE_snmpV2;
extern RTCSMIB_NODE MIBNODE_snmpDomains;
extern RTCSMIB_NODE MIBNODE_snmpProxys;
extern RTCSMIB_NODE MIBNODE_snmpModules;

RTCSMIB_VALUE value_zero_config = {
    0,
    0
};

RTCSMIB_NODE MIBNODE_iso_org = {
   43,

   NULL,
   &MIBNODE_dod,
   NULL,

   0, NULL, NULL, 0, 
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_dod = {
   6,

   NULL,
   &MIBNODE_internet,
   &MIBNODE_iso_org,

   0, NULL, NULL, 0, 
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_internet = {
   1,

   NULL,
   &MIBNODE_directory,
   &MIBNODE_dod,

   0, NULL, NULL, 0,
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_directory = {
   1,

   &MIBNODE_mgmt,
   NULL,
   &MIBNODE_internet,

   0, NULL, NULL, 0, 
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_mgmt = {
   2,

   &MIBNODE_experimental,
   NULL,
   &MIBNODE_internet,

   0, NULL, NULL, 0,
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_experimental = {
   3,

   &MIBNODE_private,
   NULL,
   &MIBNODE_internet,

   0, NULL, NULL, 0, 
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_private = {
   4,

   &MIBNODE_security,
   &MIBNODE_enterprises,
   &MIBNODE_internet,

   0, NULL, NULL, 0, 
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_enterprises = {
   1,

   NULL,
   NULL,
   &MIBNODE_private,

   0, NULL, NULL, 0,
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_security = {
   5,

   &MIBNODE_snmpV2,
   NULL,
   &MIBNODE_internet,

   0, NULL, NULL, 0,
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_snmpV2 = {
   6,

   NULL,
   &MIBNODE_snmpDomains,
   &MIBNODE_internet,

   0, NULL, NULL, 0,
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_snmpDomains = {
   1,

   &MIBNODE_snmpProxys,
   NULL,
   &MIBNODE_snmpV2,

   0, NULL, NULL, 0,
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_snmpProxys = {
   2,

   &MIBNODE_snmpModules,
   NULL,
   &MIBNODE_snmpV2,

   0, NULL, NULL, 0,
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE MIBNODE_snmpModules = {
   3,

   NULL,
   NULL,
   &MIBNODE_snmpV2,

   0, NULL, NULL, 0,
   (RTCSMIB_VALUE *)&value_zero_config, NULL
};

RTCSMIB_NODE_PTR RTCSMIB_root = &MIBNODE_iso_org;

/*
**
** END RFC1155-SMI, SNMPv2-SMI definitions
**
***********************************************************/


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_int_read
* Returned Value  : an ASN.1 INTEGER
* Comments  :  Read an INTEGER at varptr, varlen bytes long.
*
*END*-----------------------------------------------------------------*/

int_32 RTCSMIB_int_read
   (
      uchar_ptr   varptr,
      uint_32     varlen
   )
{ /* Body */
   int_32 varval = 0;
   if (varlen) {
      varval = *(signed char _PTR_)varptr++;
      varlen--;
   } /* Endif */
   while (varlen--) {
      varval <<= 8;
      varval += *varptr++;
   } /* Endwhile */
   return varval;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_id_read8
* Returned Value  : TRUE if successful
* Comments  :  Read the next ID from an object ID into a uchar.
*
*END*-----------------------------------------------------------------*/

boolean RTCSMIB_id_read8
   (
      RTCSMIB_WALK_PTR  mib,
      uchar _PTR_       index
   )
{ /* Body */
   ASN1_READ_ID(mib,*index);
   return TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_id_read32
* Returned Value  : TRUE if successful
* Comments  :  Read the next ID from an object ID into a uint_32.
*
*END*-----------------------------------------------------------------*/

boolean RTCSMIB_id_read32
   (
      RTCSMIB_WALK_PTR  mib,
      uint_32 _PTR_     index
   )
{ /* Body */
   ASN1_READ_ID(mib,*index);
   return TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_id_write8
* Returned Value  : TRUE if successful
* Comments  :  Appends an ID (up to 8 bits) to an object ID.
*
*END*-----------------------------------------------------------------*/

boolean RTCSMIB_id_write8
   (
      RTCSMIB_WALK_PTR  mib,
      uchar             index
   )
{ /* Body */
   ASN1_WRITE_ID_OCTET(mib,index);
   return TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_id_write32
* Returned Value  : TRUE if successful
* Comments  :  Appends an ID (up to 32 bits) to an object ID.
*
*END*-----------------------------------------------------------------*/

boolean RTCSMIB_id_write32
   (
      RTCSMIB_WALK_PTR  mib,
      uint_32           index
   )
{ /* Body */
   ASN1_WRITE_ID_INT(mib,index);
   return TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_mib_add
* Returned Value  : void
* Comments  :  Dynamically adds a MIB to the tree.
*
*END*-----------------------------------------------------------------*/

void RTCSMIB_mib_add
   (
      RTCSMIB_NODE_PTR  mib
   )
{ /* Body */
   RTCSMIB_NODE_PTR _PTR_ node;

   for (node = &mib->PARENT->CHILD;
        *node && (*node)->ID < mib->ID;
        node = &(*node)->NEXT)
   {
        /* void */
   }

   mib->NEXT = *node;
   *node = mib;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : MIB_instance_zero
* Returned Value  : TRUE on successful parse, FALSE on parse error
* Comments  :  The default instance parser -- assume there is a
*              single instance with index 0.
*
*END*-----------------------------------------------------------------*/

boolean MIB_instance_zero
   (
      RTCSMIB_WALK_PTR     mib,
      uint_32              op,
      boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_),
      boolean _PTR_        found,
      pointer _PTR_        instance
   )
{ /* Body */
   uint_32 index;

   *found = FALSE;
   *instance = NULL;

   switch (op) {

   case RTCSMIB_OP_GET:
   case RTCSMIB_OP_SET:
      if (mib->inlen == 0) {
         break;
      } /* Endif */
      ASN1_READ_ID(mib,index);
      if ((mib->inlen == 0) && (index == 0)) {
         *found = TRUE;
      } /* Endif */
      break;

   case RTCSMIB_OP_GETNEXT:
      if (mib->inlen == 0) {
         *found = TRUE;
      } /* Endif */
      break;

   case RTCSMIB_OP_GETFIRST:
      *found = TRUE;
      break;

   } /* Endswitch */

   if (*found && (op != RTCSMIB_OP_SET)) {
      ASN1_WRITE_ID(mib, 0);
   } /* Endif */

   return TRUE;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_get
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments  :  Finds a VarBind in the MIB.
*
*END*-----------------------------------------------------------------*/

static boolean RTCSMIB_get
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   RTCSMIB_NODE_PTR     node = RTCSMIB_root;
   boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_) = NULL;
   uint_32              varlen;
   uint_32              id;
   pointer              instance;
   boolean              found;

   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
   mib->inlen = varlen;
   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_OBJECT, varlen);
   mib->inlen = varlen;

   mib->oidlen = 0;
   ASN1_READ_ID(mib,id);

   for (;;) {

      /*
      ** First, search the MIB for the requested leaf node.
      */

      if ((node->ID < id) && node->NEXT) {

         node = node->NEXT;
         continue;

      } else if (node->ID == id) {

         mib->oidlen += (id > 0x3FFF) ? 3 : (id > 0x7F) ? 2 : 1;
         
         if (node->CHILD) {
            if (mib->inlen == 0) {
               mib->errstat = SNMP_ERROR_noSuchObject;
               return FALSE;
            } /* Endif */
            ASN1_READ_ID(mib,id);
            if (node->FIND) find = node->FIND;
            node = node->CHILD;
            continue;
         } /* Endif */

      } else {
         mib->errstat = SNMP_ERROR_noSuchObject;
         return FALSE;

      } /* Endif */

      /*
      ** We've found our leaf node.  Parse the instance identifier.
      */

      if (!(node->ACCESS & RTCSMIB_ACCESS_READ) || !node->PARSE) {
         mib->errstat = SNMP_ERROR_noSuchObject;
         return FALSE;
      } /* Endif */

      if (mib->oidlen + 4 > mib->outlen) {
         mib->errstat = SNMP_ERROR_tooBig;
         return FALSE;
      } /* Endif */
      mib->outbuf += mib->oidlen + 4;
      mib->outlen -= mib->oidlen + 4;
      mib->oidp = mib->outbuf;

      if (!node->PARSE(mib, RTCSMIB_OP_GET, find, &found, &instance)) 
         return FALSE;

      if (!found) {
         mib->errstat = SNMP_ERROR_noSuchInstance;
         return FALSE;
      } /* Endif */

      /*
      ** The instance exists -- output the value.
      */

      return RTCSMIB_output(mib, node, instance);

   } /* Endfor */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_powerful_getnext
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments  :  Finds the VarBind in the MIB lexicographically greater
*              than the one provided.
*
*END*-----------------------------------------------------------------*/

static boolean RTCSMIB_powerful_getnext
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   RTCSMIB_NODE_PTR     node = RTCSMIB_root;
   boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_) = NULL;
   uint_32              varlen;
   uint_32              op, id;
   pointer              instance;
   boolean              found;

   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
   mib->inlen = varlen;
   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_OBJECT, varlen);
   mib->inlen = varlen;

   mib->oidlen = (node->ID > 0x3FFF) ? 3 : (node->ID > 0x7F) ? 2 : 1;
   ASN1_READ_ID(mib,id);

   op = RTCSMIB_OP_GETNEXT;

   for (;;) {

      /*
      ** First, search the MIB for the requested leaf node.
      */

      switch (op) {
      case RTCSMIB_OP_GETNEXT:

         if (node->ID < id) {

            if (node->NEXT) {
               if ((node->ID <= 0x7F) && (node->NEXT->ID > 0x7F)&&(node->NEXT->ID <= 0x3FFF)) //current is 1 byte and next is 2 bytes
                  mib->oidlen++;
               else
               if((node->ID <= 0x7F) && (node->NEXT->ID > 0x3FFF))//current is 1 byte and next is 3 bytes
                  mib->oidlen = mib->oidlen + 2;       
               else
               if ((node->ID <= 0x3FFF)&&(node->ID > 0x7F) && (node->NEXT->ID > 0x3FFF))//current is 2 bytes and next is 3 bytes 
                  mib->oidlen++;
               node = node->NEXT;
            } else {
               op = RTCSMIB_OP_FINDNEXT;
            } /* Endif */

            continue;

         } else if (node->ID == id) {

            if (node->CHILD) {
               if (mib->inlen == 0) {
                  op = RTCSMIB_OP_GETFIRST;
                  continue;
               } /* Endif */
               ASN1_READ_ID(mib,id);
               if (node->FIND) 
                  find = node->FIND;
               node = node->CHILD;
               mib->oidlen += (node->ID > 0x3FFF) ? 3 : (node->ID > 0x7F) ? 2 : 1;
               continue;
            } /* Endif */

            /* We might have found our leaf node -- break out of the switch */
            break;

         } else {
            op = RTCSMIB_OP_GETFIRST;
            continue;

         } /* Endif */

      case RTCSMIB_OP_GETFIRST:

         if (node->CHILD) {
            if (node->FIND) 
               find = node->FIND;
            node = node->CHILD;
            mib->oidlen += (node->ID > 0x3FFF) ? 3 : (node->ID > 0x7F) ? 2 : 1;
            continue;
         } /* Endif */

         /* We might have found our leaf node -- break out of the switch */
         break;

      case RTCSMIB_OP_FINDNEXT:

         if (node->NEXT) {
            if ((node->ID <= 0x7F) && (node->NEXT->ID > 0x7F)&&(node->NEXT->ID <= 0x3FFF)) //current is 1 byte and next is 2 bytes
                  mib->oidlen++;
               else
               if((node->ID <= 0x7F) && (node->NEXT->ID > 0x3FFF))//current is 1 byte and next is 3 bytes
                  mib->oidlen = mib->oidlen + 2;       
               else
               if ((node->ID <= 0x3FFF)&&(node->ID > 0x7F) && (node->NEXT->ID > 0x3FFF))//current is 2 bytes and next is 3 bytes michelle
               mib->oidlen++;
            node = node->NEXT;
            op = RTCSMIB_OP_GETFIRST;
            continue;
         } /* Endif */

         mib->oidlen -= (node->ID > 0x3FFF) ? 3 : (node->ID > 0x7F) ? 2 : 1;//reduce the corresponding bytes.
         node = node->PARENT;

         if (!node) {
            mib->errstat = SNMP_ERROR_endOfMibView;
            return FALSE;
         } /* Endif */

         continue;

      } /* Endswitch */

      /*
      ** We may have found our leaf node.  Parse the instance identifier.
      */

      if (!(node->ACCESS & RTCSMIB_ACCESS_READ) || !node->PARSE) {
         op = RTCSMIB_OP_FINDNEXT;
         continue;
      } /* Endif */

      if (mib->oidlen + 4 > mib->outlen) {
         mib->errstat = SNMP_ERROR_tooBig;
         return FALSE;
      } /* Endif */
      mib->outbuf += mib->oidlen + 4;
      mib->outlen -= mib->oidlen + 4;
      mib->oidp = mib->outbuf;

      if (!node->PARSE(mib, op, find, &found, &instance)) 
         return FALSE;

      if (!found) {
         mib->outbuf -= mib->oidlen + 4;
         mib->outlen += mib->oidlen + 4;
         op = RTCSMIB_OP_FINDNEXT;
         continue;
      } /* Endif */

      /*
      ** The instance exists -- output the value.
      */

      return RTCSMIB_output(mib, node, instance);

   } /* Endfor */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_set
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments  :  Writes a VarBind in the MIB.
*
*END*-----------------------------------------------------------------*/

static boolean RTCSMIB_set
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   RTCSMIB_NODE_PTR     node = RTCSMIB_root;
   uchar_ptr            oidptr, valptr;
   uint_32              oidlen, vallen, valtype;
   boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_) = NULL;
   uint_32              varlen;
   uint_32              id;
   pointer              instance;
   boolean              found;

   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
   mib->inlen = varlen;
   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_OBJECT, oidlen);
   oidptr = mib->inbuf;

   /* Read the variable's type and length */
   mib->inbuf += oidlen;
   mib->inlen -= oidlen;
   ASN1_READ_TYPELEN(mib, valtype, vallen);
   valptr = mib->inbuf;

   mib->inbuf = oidptr;
   mib->inlen = oidlen;

   ASN1_READ_ID(mib,id);

   for (;;) {

      /*
      ** First, search the MIB for the requested leaf node.
      */

      if ((node->ID < id) && node->NEXT) {

         node = node->NEXT;
         continue;

      } else if (node->ID == id) {

         if (node->CHILD) {
            if (mib->inlen == 0) {
               mib->errstat = SNMP_ERROR_notWritable;
               return FALSE;
            } /* Endif */
            ASN1_READ_ID(mib,id);
            if (node->FIND) find = node->FIND;
            node = node->CHILD;
            continue;
         } /* Endif */

      } else {
         mib->errstat = SNMP_ERROR_notWritable;
         return FALSE;

      } /* Endif */

      /*
      ** We've found our leaf node.  Parse the instance identifier.
      */

      if (!(node->ACCESS & RTCSMIB_ACCESS_WRITE) || !node->PARSE) {
         mib->errstat = SNMP_ERROR_notWritable;
         return FALSE;
      } /* Endif */

      if (node->ASN1_TYPE != valtype) {
         mib->errstat = SNMP_ERROR_wrongType;
         return FALSE;
      } /* Endif */

      if (!node->PARSE(mib, RTCSMIB_OP_SET, find, &found, &instance)) return FALSE;

      if (!found) {
         mib->errstat = SNMP_ERROR_noCreation;
         return FALSE;
      } /* Endif */

      /*
      ** The instance exists -- set the value.
      */

      mib->totlen = 0;
      mib->errstat = node->SET(instance, valptr, vallen);
      mib->outbuf += mib->oidlen + 4;
      mib->outlen -= mib->oidlen + 4;
      mib->oidp = mib->outbuf;
      return FALSE;
      
   } /* Endfor */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_check
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments  :  check a VarBind in the MIB before write
*
*END*-----------------------------------------------------------------*/

static boolean RTCSMIB_check
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   RTCSMIB_NODE_PTR     node = RTCSMIB_root;
   uchar_ptr            oidptr, valptr;
   uint_32              oidlen, vallen, valtype;
   boolean (_CODE_PTR_  find)(uint_32, pointer, pointer _PTR_) = NULL;
   uint_32              varlen;
   uint_32              id;
   pointer              instance;
   boolean              found;

   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
   mib->inlen = varlen;
   ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_OBJECT, oidlen);
   oidptr = mib->inbuf;

   /* Read the variable's type and length */
   mib->inbuf += oidlen;
   mib->inlen -= oidlen;
   ASN1_READ_TYPELEN(mib, valtype, vallen);
   valptr = mib->inbuf;

   mib->inbuf = oidptr;
   mib->inlen = oidlen;

   ASN1_READ_ID(mib,id);

   for (;;) {

      /*
      ** First, search the MIB for the requested leaf node.
      */

      if ((node->ID < id) && node->NEXT) {

         node = node->NEXT;
         continue;

      } else if (node->ID == id) {

         if (node->CHILD) {
            if (mib->inlen == 0) {
               mib->errstat = SNMP_ERROR_notWritable;
               return FALSE;
            } /* Endif */
            ASN1_READ_ID(mib,id);
            if (node->FIND) find = node->FIND;
            node = node->CHILD;
            continue;
         } /* Endif */

      } else {
         mib->errstat = SNMP_ERROR_notWritable;
         return FALSE;

      } /* Endif */

      /*
      ** We've found our leaf node.  Parse the instance identifier.
      */

      if (!(node->ACCESS & RTCSMIB_ACCESS_WRITE) || !node->PARSE) {
         mib->errstat = SNMP_ERROR_notWritable;
         return FALSE;
      } /* Endif */

      if (node->ASN1_TYPE != valtype) {
         mib->errstat = SNMP_ERROR_wrongType;
         return FALSE;
      } /* Endif */

      if (!node->PARSE(mib, RTCSMIB_OP_SET, find, &found, &instance)) return FALSE;

      if (!found) {
         mib->errstat = SNMP_ERROR_noCreation;
         return FALSE;
      } /* Endif */

      /*
      ** The instance exists -- the value can be set.
      */
      mib->totlen = 0;
      /* Start CR# 1866 */
      //return (mib->errstat == SNMP_ERROR_noError);
      mib->outbuf += mib->oidlen + 4;
      mib->outlen -= mib->oidlen + 4;
      mib->oidp = mib->outbuf;
      return FALSE;
   } /* Endfor */

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_output
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments  :  Writes a VarBind to outbuf.
*
*END*-----------------------------------------------------------------*/

boolean RTCSMIB_output
   (
      RTCSMIB_WALK_PTR  mib,
      RTCSMIB_NODE_PTR  node,
      pointer           instance
   )
{ /* Body */
   uint_32  oidlen, varlen, varheadlen, totlen, shiftlen;
   RTCSMIB_VALUE_PTR    mib_val;

   int_32           sinteger = 0;
   uint_32          uinteger = 0;
   uint_32          octlen;

#if SNMPCFG_HAVE_INT64
   int_64            sinteger64;
   uint_64           uinteger64;
#endif

   uchar_ptr         octstr = 0;
   RTCSMIB_NODE_PTR  oidptr = 0;
   RTCSMIB_NODE_PTR  tempoidptr;
   mib_val = (pointer)node->GET;

   switch (mib_val->TYPE) {  
   case RTCSMIB_NODETYPE_INT_CONST:
        sinteger = (int_32)(mib_val->PARAM); 
        break;  
   case RTCSMIB_NODETYPE_INT_PTR:  
        sinteger = *(int_32 *)(mib_val->PARAM); 
        break;
   case RTCSMIB_NODETYPE_INT_FN:       
        sinteger = ((RTCSMIB_INT_FN_PTR)mib_val->PARAM)(instance);
        break;
   case RTCSMIB_NODETYPE_UINT_CONST:
        uinteger = (uint_32)(mib_val->PARAM);
        break;   
   case RTCSMIB_NODETYPE_UINT_PTR:     
        uinteger = *(uint_32 *)(mib_val->PARAM);
        break;
   case RTCSMIB_NODETYPE_UINT_FN:      
        uinteger = ((RTCSMIB_UINT_FN_PTR)mib_val->PARAM)(instance);
        break;
   case RTCSMIB_NODETYPE_DISPSTR_PTR:  
        octstr = (uchar *)(mib_val->PARAM);
        break;
   case RTCSMIB_NODETYPE_DISPSTR_FN:   
        octstr = ((RTCSMIB_DISPSTR_FN_PTR)mib_val->PARAM)(instance);
        break;
   case RTCSMIB_NODETYPE_OCTSTR_FN:    
        octstr = ((RTCSMIB_OCTSTR_FN_PTR)mib_val->PARAM)(instance, &octlen);
        break;
   case RTCSMIB_NODETYPE_OID_PTR:      
        oidptr = (mib_val->PARAM);
        break;
   case RTCSMIB_NODETYPE_OID_FN:       
        oidptr  = ((RTCSMIB_OID_FN_PTR)mib_val->PARAM)(instance);            
        break;
#if SNMPCFG_HAVE_INT64
   case RTCSMIB_NODETYPE_INT64_CONST:  sinteger64 = node->GET.INT64_CONST;               break;
   case RTCSMIB_NODETYPE_INT64_PTR:    sinteger64 = *node->GET.INT64_PTR;                break;
   case RTCSMIB_NODETYPE_INT64_FN:     sinteger64 = node->GET.INT64_FN(instance);        break;
   case RTCSMIB_NODETYPE_UINT64_CONST: uinteger64 = node->GET.UINT64_CONST;              break;
   case RTCSMIB_NODETYPE_UINT64_PTR:   uinteger64 = *node->GET.UINT64_PTR;               break;
   case RTCSMIB_NODETYPE_UINT64_FN:    uinteger64 = node->GET.UINT64_FN(instance);       break;
#endif
   } /* Endswitch */

   switch (mib_val->TYPE) {
   case RTCSMIB_NODETYPE_INT_CONST:
   case RTCSMIB_NODETYPE_INT_PTR:
   case RTCSMIB_NODETYPE_INT_FN:
      if ((sinteger >= -0x80) && (sinteger < 0x80)) {
         varlen = 1;
      } else if ((sinteger >= -0x8000) && (sinteger < 0x8000)) {
         varlen = 2;
      } else if ((sinteger >= -0x800000) && (sinteger < 0x800000)) {
         varlen = 3;
      } else {
         varlen = 4;
      } /* Endif */

      break;

   case RTCSMIB_NODETYPE_UINT_CONST:
   case RTCSMIB_NODETYPE_UINT_PTR:
   case RTCSMIB_NODETYPE_UINT_FN:
      if (uinteger < 0x80) {
         varlen = 1;
      } else if (uinteger < 0x8000) {
         varlen = 2;
      } else if (uinteger < 0x800000) {
         varlen = 3;
      } else if (uinteger < 0x80000000) {
         varlen = 4;
      } else {
         varlen = 5;
      } /* Endif */

      break;

   case RTCSMIB_NODETYPE_DISPSTR_PTR:
   case RTCSMIB_NODETYPE_DISPSTR_FN:
      octlen = 0;
      if (octstr) {
         while (octstr[octlen] != '\0') {
            octlen++;
            if (octlen > mib->outlen) {
               mib->errstat = SNMP_ERROR_tooBig;
               return FALSE;
            } /* Endif */
         } /* Endwhile */
      } /* Endif */

      /* Fall through */
   case RTCSMIB_NODETYPE_OCTSTR_FN:
      varlen = octlen;
      break;

   case RTCSMIB_NODETYPE_OID_PTR:
   case RTCSMIB_NODETYPE_OID_FN:
      if (!oidptr) {
         varlen = 1;
      } else {
         tempoidptr = oidptr;
         varlen = 0;
         while (tempoidptr) {
            varlen += (tempoidptr->ID > 0x3FFF) ? 3 : (tempoidptr->ID > 0x7F) ? 2 : 1;
            tempoidptr = tempoidptr->PARENT;
         } /* Endwhile */
      } /* Endif */
      break;

#if SNMPCFG_HAVE_INT64
   case RTCSMIB_NODETYPE_INT64_CONST:
   case RTCSMIB_NODETYPE_INT64_PTR:
   case RTCSMIB_NODETYPE_INT64_FN:
      if ((sinteger64 >= -0x80LL) && (sinteger64 < 0x80LL)) {
         varlen = 1;
      } else if ((sinteger64 >= -0x8000LL) && (sinteger64 < 0x8000LL)) {
         varlen = 2;
      } else if ((sinteger64 >= -0x800000LL) && (sinteger64 < 0x800000LL)) {
         varlen = 3;
      } else if ((sinteger64 >= -0x80000000LL) && (sinteger64 < 0x80000000LL)) {
         varlen = 4;
      } else if ((sinteger64 >= -0x8000000000LL) && (sinteger64 < 0x8000000000LL)) {
         varlen = 5;
      } else if ((sinteger64 >= -0x800000000000LL) && (sinteger64 < 0x800000000000LL)) {
         varlen = 6;
      } else if ((sinteger64 >= -0x80000000000000LL) && (sinteger64 < 0x80000000000000LL)) {
         varlen = 7;
      } else {
         varlen = 8;
      } /* Endif */

      break;

   case RTCSMIB_NODETYPE_UINT64_CONST:
   case RTCSMIB_NODETYPE_UINT64_PTR:
   case RTCSMIB_NODETYPE_UINT64_FN:
      if (uinteger64 < 0x80ULL) {
         varlen = 1;
      } else if (uinteger64 < 0x8000ULL) {
         varlen = 2;
      } else if (uinteger64 < 0x800000ULL) {
         varlen = 3;
      } else if (uinteger64 < 0x80000000ULL) {
         varlen = 4;
      } else if (uinteger64 < 0x8000000000ULL) {
         varlen = 5;
      } else if (uinteger64 < 0x800000000000ULL) {
         varlen = 6;
      } else if (uinteger64 < 0x80000000000000ULL) {
         varlen = 7;
      } else if (uinteger64 < 0x8000000000000000ULL) {
         varlen = 8;
      } else {
         varlen = 9;
      } /* Endif */

      break;
#endif

   } /* Endswitch */

   /*
   ** The caller assumed that the entire VarBind would occupy at most
   ** 127 bytes.  This is usually (but not always) the case.  Now,
   ** node->PARSE() has already written the instance part of the
   ** object ID into outbuf, with the 127-byte assumption.
   **
   ** If it turns out that the VarBind will exceed 127 bytes, the
   ** instance number will have to be shifted to make room for the
   ** larger headers.
   */

   oidlen = mib->outbuf - mib->oidp;   /* oidlen = length of instance in OID */
   totlen = 4 + mib->oidlen + oidlen + varlen;
   shiftlen = 0;

   if (mib->oidlen + oidlen > 0x7F) {
      if (mib->oidlen + oidlen > 0x3FFF) {
         totlen++;
         shiftlen++;
      } /* Endif */
      totlen++;
      shiftlen++;
   } /* Endif */

   varheadlen = 2;
   if (varlen > 0x7F) {
      if (varlen > 0x3FFF) {
         varheadlen++;
         totlen++;
      } /* Endif */
      varheadlen++;
      totlen++;
   } /* Endif */

   if (totlen > 0x7F) {
      if (totlen > 0x3FFF) {
         shiftlen++;
      } /* Endif */
      shiftlen++;
   } /* Endif */

   if (shiftlen + varheadlen + varlen > mib->outlen) {
      mib->errstat = SNMP_ERROR_tooBig;
      return FALSE;
   } /* Endif */

   if (shiftlen) {
      uchar_ptr shiftp;

      for (shiftp = mib->outbuf; shiftp > mib->oidp;) {
         shiftp--;
         shiftp[shiftlen] = shiftp[0];
      } /* Endfor */

   } /* Endif */

   mib->outbuf += shiftlen + varheadlen + varlen;
   mib->oidp += shiftlen;

   /*
   ** Everything is in order.  Write out the response.
   */

   varlen = 0;
   switch (mib_val->TYPE) {
   case RTCSMIB_NODETYPE_INT_CONST:
   case RTCSMIB_NODETYPE_INT_PTR:
   case RTCSMIB_NODETYPE_INT_FN:
      ASN1_BKWRITE_TYPELEN_BIGINT(mib, varlen, node->ASN1_TYPE, sinteger);
      break;
   case RTCSMIB_NODETYPE_UINT_CONST:
   case RTCSMIB_NODETYPE_UINT_PTR:
   case RTCSMIB_NODETYPE_UINT_FN:
      ASN1_BKWRITE_TYPELEN_BIGUINT(mib, varlen, node->ASN1_TYPE, uinteger);
      break;
   case RTCSMIB_NODETYPE_DISPSTR_PTR:
   case RTCSMIB_NODETYPE_DISPSTR_FN:
   case RTCSMIB_NODETYPE_OCTSTR_FN:
      ASN1_BKWRITE_TYPELEN_BYTES(mib, varlen, node->ASN1_TYPE, octstr, octlen);
      break;
   case RTCSMIB_NODETYPE_OID_PTR:
   case RTCSMIB_NODETYPE_OID_FN:
      if (!oidptr) {
         ASN1_BKWRITE_ID(mib, varlen, 0);
      } else {
         while (oidptr) {
            ASN1_BKWRITE_ID(mib, varlen, oidptr->ID);
            oidptr = oidptr->PARENT;
         } /* Endwhile */
      } /* Endif */
      ASN1_BKWRITE_TYPELEN(mib, varlen, ASN1_TYPE_OBJECT, varlen);
      break;
#if SNMPCFG_HAVE_INT64
   case RTCSMIB_NODETYPE_INT64_CONST:
   case RTCSMIB_NODETYPE_INT64_PTR:
   case RTCSMIB_NODETYPE_INT64_FN:
      ASN1_BKWRITE_TYPELEN_BIGINT(mib, varlen, node->ASN1_TYPE, sinteger64);
      break;
   case RTCSMIB_NODETYPE_UINT64_CONST:
   case RTCSMIB_NODETYPE_UINT64_PTR:
   case RTCSMIB_NODETYPE_UINT64_FN:
      ASN1_BKWRITE_TYPELEN_BIGUINT(mib, varlen, node->ASN1_TYPE, uinteger64);
      break;
#endif
   } /* Endswitch */

   mib->outbuf = mib->oidp;
   while (node) {
      ASN1_BKWRITE_ID(mib, oidlen, node->ID);
      node = node->PARENT;
   } /* Endwhile */
   ASN1_BKWRITE_TYPELEN(mib, oidlen, ASN1_TYPE_OBJECT, oidlen);

   totlen = oidlen + varlen;
   ASN1_BKWRITE_TYPELEN(mib, totlen, ASN1_TYPE_SEQUENCE, totlen);

   mib->totlen = totlen;
   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_request_internal
* Parameters      :
*
*     uint_8            request     [IN] identification for echo message.
*     uchar_ptr         inbuf       [IN] pointer to requested VarBind
*     uint_32           inlen       [IN] length of requested VarBind
*     uchar_ptr         outbuf      [IN] where to write response
*     uint_32           outlen      [IN] available space for response
*     boolean           errstat     [OUT] whether or not an error occurred
*     uchar_ptr         oidp        not used
*     uint_32           oidlen      not used
*     uint_32           totlen      [OUT] actual length of response
*
* Comments        :
*     Service a single Get request.
*
*END*-----------------------------------------------------------------*/

// Start CR 2316
static boolean RTCSMIB_request_internal
   (
      RTCSMIB_WALK_PTR  mib
   )
{ /* Body */
   uchar_ptr inbuffer, nextvar,checkbuffer;
   uint_32 inbuf_length, nextlength,check_length;
   uint_32 varlen;
   boolean  ok = FALSE;
   uint_32  index =0;
   uint_32  errstat =0;
   uint_32 error_index;

   mib->errstat = SNMP_ERROR_noError;

   switch (mib->pdutype) {
   case ASN1_TYPE_PDU_GET:
      ok = RTCSMIB_get(mib);
      break;
   case ASN1_TYPE_PDU_GETNEXT:
      ok = RTCSMIB_powerful_getnext(mib);
      break;
   case ASN1_TYPE_PDU_SET:
        inbuffer = mib->inbuf;   
        inbuf_length = mib->inlen;
        
        checkbuffer = inbuffer;
        check_length = inbuf_length;
        
        error_index =0;
        
        //check first to ensure all variables in set request are valid
        if (check_length >= 5)  /* Minmum length for a set operation is 5 */
        {
            ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
            nextvar = (uchar_ptr) (mib->inbuf + varlen);
            nextlength = check_length - ((uint_32)(nextvar - checkbuffer));
            mib->inbuf = checkbuffer;
            mib->inlen = check_length; 
            mib->errstat = SNMP_ERROR_noError;
            ok = RTCSMIB_check(mib);
            index++;
            if(mib->errstat)
            {
              errstat = mib->errstat;
              error_index = index;
            }
            mib->inbuf = nextvar;
            checkbuffer = nextvar;
            mib->inlen = nextlength;
            check_length = nextlength;
        }
        
        if(error_index) //invalid variable in set request,stop set operation to all variables 
        {
           mib->errstat = errstat;
           break;
        }
        
        mib->inbuf = inbuffer;
        mib->inlen = inbuf_length;
        
        //all variables are valid, so set beginning
        while (inbuf_length >= 5)  /* Minmum length for a set operation is 5 */
        {
            ASN1_READ_TYPELEN_EXPECT(mib, ASN1_TYPE_SEQUENCE, varlen);
            nextvar = (uchar_ptr) (mib->inbuf + varlen);
            nextlength = inbuf_length - ((uint_32)(nextvar - inbuffer));
            mib->inbuf = inbuffer;
            mib->inlen = inbuf_length; 
            ok = RTCSMIB_set(mib);
            mib->inbuf = nextvar;
            inbuffer = nextvar;
            mib->inlen = nextlength;
            inbuf_length = nextlength;
            
            if(mib->errstat != SNMP_ERROR_noError)
                break;
            
        } /* Endwhile */
      break;
   } /* Endswitch */

   if (!ok && !mib->errstat) {
      mib->errstat = SNMP_ERROR_PARSE;
   } /* Endif */

/* Start CR 2162 */
#ifndef TRAVERSE_MIB_IN_SNMP_TASK
   RTCSCMD_complete(mib, RTCS_OK);
#endif
/* End CR 2162 */
return (ok);
} /* Endbody */
// End CR 2316


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSMIB_request
* Returned Value  : TRUE if successful, FALSE otherwise
* Comments  :
*     Issue a MIB request to the RTCS task.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCSMIB_request
   (
      uint_8         pdutype,
      uchar_ptr      invarp,
      uint_32        invarlen,
      uchar_ptr      outvarp,
      uint_32        outvarlen,
      uint_32 _PTR_  writelen
   )
{ /* Body */
   RTCSMIB_WALK   mib;

   mib.pdutype = pdutype;
   mib.inbuf   = invarp;
   mib.inlen   = invarlen;
   mib.outbuf  = outvarp;
   mib.outlen  = outvarlen;

#ifndef TRAVERSE_MIB_IN_SNMP_TASK
   if (RTCSCMD_issue(mib, RTCSMIB_request_internal)) {
      return SNMP_ERROR_genErr;
   } /* Endif */
#else
   RTCSMIB_request_internal(&mib);
#endif

   if (!mib.errstat) {
      *writelen = mib.totlen;
   } /* Endif */

   return mib.errstat;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4 */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/dev_shut.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dev_shut.c$
* $Version : 3.8.3.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*  This file contains USB device API specific function to shutdown 
*  the device.
*                                                               
*END*********************************************************************/
#include <mqx.h>

#include "usb.h"     //common public
#include "usb_prv.h" //common private

#include "dev_cnfg.h"
#include "devapi.h"  //device public
#include "dev_main.h" //device private

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_shutdown
*  Returned Value : USB_OK or error code
*  Comments       :
*        Shutdown an initialized USB device
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_shutdown
(
    /* [IN] the USB_USB_dev_initialize state structure */
    _usb_device_handle         handle
)
{ 
    USB_STATUS                        error;
    volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;
   
    if (handle == NULL)
    {
        #if _DEBUG
            printf("_usb_device_shutdown: handle is NULL\n");
        #endif  
        return USBERR_ERROR;
    }

    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    if ( ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
        usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SHUTDOWN != NULL)
    {
        error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
            usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SHUTDOWN(usb_dev_ptr);
    }
    else
    {
        #if _DEBUG
            printf("_usb_device_shutdown: DEV_SHUTDOWN is NULL\n");
        #endif  
        return USBERR_ERROR;
    }
      
    return  error;   
} /* EndBody */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/esdhc/esdhc_vf65gs10.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: esdhc_vf600.c$
* $Version : 3.8.2.0$
* $Date    : Aug-6-2012$
*
* Comments:
*
*   This file contains board-specific ESDHC initialization functions.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_esdhc_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding eSDHC
*    module.
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_esdhc_base_address
(
    uint_8 dev_num
)
{
    pointer addr = NULL;

    switch (dev_num)
    {
        case 0:
            addr = (pointer)SDHC0_BASE_PTR;
            break;
        case 1:
            addr = (pointer)SDHC1_BASE_PTR;
            break;
        default:
            break;
    }

    return addr;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_esdhc_vector
* Returned Value   : Vector number upon success, 0 upon failure
* Comments         :
*    This function returns desired interrupt vector table index for specified
*    ESDHC module and vector identifier.
*
*END*----------------------------------------------------------------------*/
uint_32 _bsp_get_esdhc_vector
(
    uint_8 dev_num
)
{
    uint_32 vector_index = 0;

    switch (dev_num)
    {
        case 0:
            vector_index = INT_SDHC0;
            break;
        case 1:
            vector_index = INT_SDHC1;
            break;
        default:
            break;
    }

    return vector_index;
}

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/BSP/PE/CPU.h<|end_filename|>
#ifndef __Cpu_H
#define __Cpu_H


#ifdef __cplusplus
extern "C" {
#endif 



#define CPU_CLOCK_CONFIG_NUMBER         0x03U /* Specifies number of defined clock configurations. */

/* CPU frequencies in clock configuration 0 */
#define CPU_CLOCK_CONFIG_0              0x00U /* Clock configuration 0 identifier */

/* CPU frequencies in clock configuration 1 */
#define CPU_CLOCK_CONFIG_1              0x01U /* Clock configuration 1 identifier */

/* CPU frequencies in clock configuration 2 */
#define CPU_CLOCK_CONFIG_2              0x02U /* Clock configuration 2 identifier */



#define LLWU_FILTER1                   0x01000000U /* WakeUp caused by digital filter 1 */
#define LLWU_FILTER2                   0x02000000U /* WakeUp caused by digital filter 2 */

/*lint -esym(765,SR_reg) Disable MISRA rule (8.10) checking for symbols (SR_reg). The SR_reg is used in inline assembler. */
extern volatile uint8_t SR_reg;        /* Current FAULTMASK register */
/*lint -esym(765,SR_lock) Disable MISRA rule (8.10) checking for symbols (SR_lock). The SR_reg is used in inline assembler. */
extern volatile uint8_t SR_lock;


typedef uint16_t  LDD_TError;           /*!< Error type. */
typedef uint8_t   LDD_TClockConfiguration; /*!< CPU clock configuration type. */

/*! Driver operation mode type. */
typedef enum {
  DOM_NONE,
  DOM_RUN,
  DOM_WAIT,
  DOM_SLEEP,
  DOM_STOP
} LDD_TDriverOperationMode;

typedef void LDD_TCallbackParam;       /*!< Pointer to this type specifies the user data to be passed as a callback parameter. */
typedef void (*LDD_TCallback)(LDD_TCallbackParam *CallbackParam); /*!< Callback type used for definition of callback functions. */



/*
** ===================================================================
**     Method      :  Cpu_MCGAutoTrim (component MK60FN1M0LQ15)
**     Description :
**         This method uses MCG auto trim feature to trim internal
**         reference clock. This method can be used only in a clock
**         configuration which derives its bus clock from external
**         reference clock (<MCG mode> must be one of the following
**         modes - FEE, FBE, BLPE, PEE, PBE) and if value of <Bus clock>
**         is in the range <8; 16>MHz.
**         The slow internal reference clock is trimmed to the value
**         selected by <Slow internal reference clock [kHz]> property. 
**         The fast internal reference clock will be trimmed to value
**         4MHz.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ClockSelect     - Selects which internal
**                           reference clock will be trimmed.
**                           0 ... slow (32kHz) internal reference clock
**                           will be trimmed
**                           > 0 ... fast (4MHz) internal reference
**                           clock will be trimmed
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_SPEED - The method does not work in the
**                           active clock configuration.
**                           ERR_FAILED - Autotrim process failed.
** ===================================================================
*/
LDD_TError Cpu_MCGAutoTrim(uint8_t ClockSelect);

/*
** ===================================================================
**     Method      :  Cpu_GetLLSWakeUpFlags (component MK60FN1M0LQ15)
**     Description :
**         This method returns the current status of the LLWU wake-up
**         flags indicating which wake-up source caused the MCU to exit
**         LLS or VLLSx low power mode.
**         The following predefined constants can be used to determine
**         the wake-up source:
**         LLWU_EXT_PIN0, ... LLWU_EXT_PIN15 - external pin 0 .. 15
**         caused the wake-up
**         LLWU_INT_MODULE0 .. LLWU_INT_MODULE7 - internal module 0..15
**         caused the wake-up.
**     Parameters  : None
**     Returns     :
**         ---             - Returns the current status of the LLWU
**                           wake-up flags indicating which wake-up
**                           source caused the MCU to exit LLS or VLLSx
**                           low power mode.
** ===================================================================
*/
uint32_t Cpu_GetLLSWakeUpFlags(void);

/*
** ===================================================================
**     Method      :  Cpu_SetClockConfiguration (component MK60FN1M0LQ15)
**     Description :
**         Calling of this method will cause the clock configuration
**         change and reconfiguration of all components according to
**         the requested clock configuration setting.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ModeID          - Clock configuration identifier
**     Returns     :
**         ---             - ERR_OK - OK.
**                           ERR_RANGE - Mode parameter out of range
** ===================================================================
*/
LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID);

/*
** ===================================================================
**     Method      :  Cpu_GetClockConfiguration (component MK60FN1M0LQ15)
**     Description :
**         Returns the active clock configuration identifier. The
**         method is enabled only if more than one clock configuration
**         is enabled in the component.
**     Parameters  : None
**     Returns     :
**         ---             - Active clock configuration identifier
** ===================================================================
*/
uint8_t Cpu_GetClockConfiguration(void);

/*
** ===================================================================
**     Method      :  Cpu_SetOperationMode (component MK60FN1M0LQ15)
**     Description :
**         This method requests to change the component's operation
**         mode (RUN, WAIT, SLEEP, STOP). The target operation mode
**         will be entered immediately. 
**         See <Operation mode settings> for further details of the
**         operation modes mapping to low power modes of the cpu.
**     Parameters  :
**         NAME            - DESCRIPTION
**         OperationMode   - Requested driver
**                           operation mode
**         ModeChangeCallback - Callback to
**                           notify the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**       * ModeChangeCallbackParamPtr 
**                           - Pointer to callback parameter to notify
**                           the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_PARAM_MODE - Invalid operation mode
** ===================================================================
*/
LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr);

/*
** ===================================================================
**     Method      :  Cpu_EnableInt (component MK60FN1M0LQ15)
**     Description :
**         Enables all maskable interrupts.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_EnableInt(void);

/*
** ===================================================================
**     Method      :  Cpu_DisableInt (component MK60FN1M0LQ15)
**     Description :
**         Disables all maskable interrupts.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void Cpu_DisableInt(void);

/*
** ===================================================================
**     Method      :  Cpu_INT_LLWInterrupt (component MK60FN1M0LQ15)
**
**     Description :
**         This ISR services the 'LLWU' interrupt.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

void Init_cpu(void);
/*
** ===================================================================
**     Method      :  Init_cpu_clock_subsystem (component MK60FN1M0LQ15)
**
**     Description :
**         Initializes the whole system like timing, external bus, etc.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

/* END Cpu. */

#ifdef __cplusplus
}  /* extern "C" */
#endif 

#endif
/* __Cpu_H */

/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/hub/usb_host_hub_sm.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_hub_sm.c$
* $Version : 3.8.24.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
*   This file contains the implementation of hub state machine on host.
*
*END************************************************************************/
#include "usb_host_hub.h"
#include "usb_host_hub_prv.h"
#include "usb_host_hub_sm.h"

static HUB_DEVICE_STRUCT_PTR  hubs = NULL;

static void usb_host_hub_device_sm(PIPE_STRUCT_PTR, pointer, pointer, uint_32, USB_STATUS);
static void usb_host_hub_int_callback(PIPE_STRUCT_PTR, pointer, pointer, uint_32, USB_STATUS);

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_hub_device_event
* Returned Value : None
* Comments       :
*     called when a hub has been attached, detached, etc.
*END*--------------------------------------------------------------------*/
void usb_host_hub_device_event
   (
      /* [IN] pointer to device instance */
      _usb_device_instance_handle      dev_handle,

      /* [IN] pointer to interface descriptor */
      _usb_interface_descriptor_handle intf_handle,

      /* [IN] code number for event causing callback */
      uint_32                          event_code
   )
{
    HUB_DEVICE_STRUCT_PTR hub_instance;

    switch (event_code) {
        case USB_CONFIG_EVENT:
            /* Drop through into attach, same processing */
        case USB_ATTACH_EVENT:
            /* Create 'unsafe' application struct */
            if (NULL != (hub_instance = USB_mem_alloc_zero(sizeof(HUB_DEVICE_STRUCT)))) {
                _usb_hostdev_select_interface(dev_handle, intf_handle, (pointer)&hub_instance->CCS);
            }
            break;
            
        case USB_INTF_EVENT:
            if (USB_OK != usb_class_hub_get_app(dev_handle, intf_handle, (CLASS_CALL_STRUCT_PTR *) &hub_instance))
                break;
            
            /* set we are in process of getting hub descriptor */
            hub_instance->STATE = HUB_GET_DESCRIPTOR_TINY_PROCESS;
                    
            /* here, we should retrieve information from the hub */
            usb_class_hub_get_descriptor(&hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, 7);
            break;

        case USB_DETACH_EVENT: {
            DEV_INSTANCE_PTR dev_ptr;
            _mqx_int  i;

            if (USB_OK != usb_class_hub_get_app(dev_handle, intf_handle, (CLASS_CALL_STRUCT_PTR *) &hub_instance))
                break;
            
            dev_ptr = (DEV_INSTANCE_PTR) dev_handle;
            /* detach all the devices connected to all the ports of found hub */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++) {
                if ((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED)
                    /* We will access dev_ptr without validation process (usb_hostdev_validate), because 
                    ** USB_DETACH_EVENT is synced call, so we can do that. dev_ptr is still valid pointer to device.
                    */
                    usb_dev_list_detach_device(dev_ptr->host, dev_ptr->address, i + 1);
            }
            if (hub_instance->HUB_PORTS != NULL)
                USB_mem_free(hub_instance->HUB_PORTS);
            }
            break;

        default:
            break;
   } /* EndSwitch */

} /* Enbbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_hub_device_sm
* Returned Value : None
* Comments       :
*     called when a hub changes state; sm = state machine
*END*--------------------------------------------------------------------*/
static void usb_host_hub_device_sm
   (
         /* [IN] structure with USB pipe information on the interface */
         PIPE_STRUCT_PTR   pipe,

         /* [IN] parameters */
         pointer           param,

         /* [IN] buffer of data from IN stage */
         pointer           buffer,

         /* [IN] length of data from IN stage */
         uint_32           len,

         /* [IN] status of transaction */
         USB_STATUS        status
   )
{ /* Body */
    register HUB_DEVICE_STRUCT_PTR hub_instance = (HUB_DEVICE_STRUCT_PTR) param;
    _mqx_int                       i;

    switch (hub_instance->STATE) {
        case HUB_GET_DESCRIPTOR_TINY_PROCESS: 

            /* here we get number of ports from USB data */
            hub_instance->HUB_PORT_NR = ((HUB_DESCRIPTOR_STRUCT_PTR) buffer)->BNRPORTS;
            hub_instance->STATE = HUB_GET_DESCRIPTOR_PROCESS;
            usb_class_hub_get_descriptor((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, 7 + hub_instance->HUB_PORT_NR / 8 + 1);
            break;

        case HUB_GET_DESCRIPTOR_PROCESS: 
            {
                /* here, we get information from the hub and fill info in hub_instance */
                HUB_DESCRIPTOR_STRUCT_PTR hub_desc = (HUB_DESCRIPTOR_STRUCT_PTR) buffer;

                hub_instance->HUB_PORTS = USB_mem_alloc_zero(hub_instance->HUB_PORT_NR * sizeof(HUB_PORT_STRUCT));
            
                for (i = 0; i < hub_instance->HUB_PORT_NR; i++) 
                {
                    /* get REMOVABLE bit from the desriptor for appropriate installed port */
                    (hub_instance->HUB_PORTS + i)->APP_STATUS = hub_desc->DEVICEREMOVABLE[(i + 1) / 8] & (0x01 << ((i + 1) % 8)) ? HUB_PORT_REMOVABLE : 0;
                }
            }

            /* pass fluently to HUB_SET_PORT_FEATURE_PROCESS */
            hub_instance->STATE = HUB_SET_PORT_FEATURE_PROCESS;
            hub_instance->port_iterator = 0;

        case HUB_SET_PORT_FEATURE_PROCESS: 
//              if (hub_instance->port_iterator)
                /* register, that the port is now powered */
//                hub_instance->HUB_PORTS[hub_instance->port_iterator - 1].POWERED = 1;
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) 
            {
                usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, PORT_POWER);
                break;
            } /* EndIf */
            /* else */

            /* pass fluently to HUB_CLEAR_PORT_FEATURE_PROCESS */
            hub_instance->STATE = HUB_CLEAR_PORT_FEATURE_PROCESS;
            hub_instance->port_iterator = 0;
        case HUB_CLEAR_PORT_FEATURE_PROCESS: 
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) 
            {
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, C_PORT_CONNECTION);
                break;
            } /* EndIf */
            /* else */

            /* pass fluently to HUB_GET_PORT_STATUS_PROCESS */
            hub_instance->STATE = HUB_GET_PORT_STATUS_PROCESS;
            hub_instance->port_iterator = 0;
        case HUB_GET_PORT_STATUS_PROCESS: 
            if (hub_instance->port_iterator)
                /* register the current status of the port, do the conversion LSB -> MSB */
                (hub_instance->HUB_PORTS + hub_instance->port_iterator - 1)->STATUS = SHORT_LE_TO_HOST(*(uint_16*)buffer);
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR)
            {
                usb_class_hub_get_port_status((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, 4);
                break;
            } /* EndIf */
            /* else */
            
            /* test if device is attached since startup */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if ((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
            
        case HUB_RESET_DEVICE_PORT_PROCESS:
            hub_instance->STATE = HUB_NONE;
            
            usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;

        case HUB_ADDRESS_DEVICE_PORT_PROCESS:
            /* compute speed */
            if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS & (1 << PORT_HIGH_SPEED))
                i = USB_SPEED_HIGH;
            else if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS & (1 << PORT_LOW_SPEED))
                i = USB_SPEED_LOW;
            else
                i = USB_SPEED_FULL;
            
            /* FIXME: accessing intf_handle directly without validation to get its host handle is not good method */
            usb_dev_list_attach_device(
                ((USB_HUB_CLASS_INTF_STRUCT_PTR) hub_instance->CCS.class_intf_handle)->G.host_handle,
                i, /* port speed */
                pipe->DEVICE_ADDRESS, /* hub address */
                hub_instance->port_iterator + 1 /* hub port */
                );

            /* test if there is still device which was not reset */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if (((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) && !((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
        
        case HUB_DETACH_DEVICE_PORT_PROCESS:
            /* FIXME: accessing intf_handle directly without validation to get its host handle is not good method */
            usb_dev_list_detach_device(
                ((USB_HUB_CLASS_INTF_STRUCT_PTR) hub_instance->CCS.class_intf_handle)->G.host_handle,
                pipe->DEVICE_ADDRESS, /* hub address */
                hub_instance->port_iterator + 1 /* hub port */
                );
            
            /* reset the app status */
            (hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS = 0x00;

            /* test if there is still device which was not reset */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if (((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) && !((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
            
        case HUB_GET_PORT_STATUS_ASYNC:
        {
            uint_32 stat = LONG_LE_TO_HOST(*(uint_32*)buffer);
            
            /* register the current status of the port */
            (hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS = stat;
    
            /* let's see what happened */
            if ((1 << C_PORT_CONNECTION) & stat)
            {
                /* get if a device on port was attached or detached */
                if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS & HUB_PORT_ATTACHED)
                {
                    hub_instance->STATE = HUB_DETACH_DEVICE_PORT_PROCESS;
                    usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_CONNECTION);
                }
                else 
                {
                    hub_instance->STATE = HUB_RESET_DEVICE_PORT_PROCESS;
                    usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_CONNECTION);
                }
                break;
            }
            else if ((1 << C_PORT_RESET) & stat)
            {
                hub_instance->STATE = HUB_ADDRESS_DEVICE_PORT_PROCESS;
                (hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS |= HUB_PORT_ATTACHED;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_RESET);
                break;
            }
            else if ((1 << C_PORT_ENABLE) & stat)
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_DETACH_DEVICE_PORT_PROCESS;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_ENABLE);
                break;
            }
            else if ((1 << C_PORT_OVER_CURRENT) & stat) 
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_OVER_CURRENT);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
                break;
            }
            else if ((1 << C_PORT_POWER) & stat) 
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_POWER);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
                break;
            }
            /* FIXME: handle more events */

            break;
        }

        case HUB_GET_STATUS_ASYNC:
        {
            HUB_STATUS_STRUCT_PTR hub_stat = (HUB_STATUS_STRUCT_PTR) buffer;
            uint_32 change = SHORT_LE_TO_HOST(hub_stat->WHUBCHANGE);

            if ((1 << C_HUB_LOCAL_POWER) & change) 
            {
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, C_HUB_LOCAL_POWER);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            }
            else if ((1 << C_HUB_OVER_CURRENT) & change) 
            {
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, C_HUB_OVER_CURRENT);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            }
            break;
        }
        
    } /* EndSwitch */
    return;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_hub_int_callback
* Returned Value : None
* Comments       :
*     Called on interrupt endpoint data reception
*END*--------------------------------------------------------------------*/

static void usb_host_hub_int_callback
   (
      /* [IN] pointer to pipe */
      PIPE_STRUCT_PTR   pipe,

      /* [IN] user-defined parameter */
      pointer           param,

      /* [IN] buffer address */
      pointer           buffer,

      /* [IN] length of data transferred */
      uint_32           len,

      /* [IN] status, hopefully USB_OK or USB_DONE */
      USB_STATUS        status
   )
{ /* Body */
    HUB_DEVICE_STRUCT_PTR          hub_instance = (HUB_DEVICE_STRUCT_PTR) param;
    USB_HUB_CLASS_INTF_STRUCT_PTR  if_ptr;
    _mqx_int                       i, j, port = 0;
    uint_8 _PTR_                   port_pattern= (uint_8 _PTR_) buffer;
   
    /* find which port changed its state */
    for (i = 0; i < len; i++) 
    {
        if (!port_pattern[i])
            continue;
        port = i * 8;
        for (j = 0; j < 8; j++, port++) 
        {
            if (port_pattern[i] & 0x01)
                break;
            port_pattern[i] >>= 1;
        }
        break;
    }

    /* The port number, which changed status, is written in variable "port"
    ** Note, that if there are more ports, which changed its status, these will
    ** be invoked later (in next interrupt)
    */

    if (port == 0) {
        hub_instance->STATE = HUB_GET_STATUS_ASYNC;
        usb_class_hub_get_status((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, 4);
    }
    else {
        hub_instance->STATE = HUB_GET_PORT_STATUS_ASYNC;
        hub_instance->port_iterator = port - 1;
        usb_class_hub_get_port_status((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, port, 4);
    }
} /*EndBody */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/arpcmd.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: arpcmd.c$
* $Version : 3.8.5.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains the interface functions to the
*   packet driver interface.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"

#include "arpif.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_arp_add
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Add an entry to an interfaces ARP cache.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_arp_add
   (
      _rtcs_if_handle _PTR_   ihandle,
         /* [IN] the RTCS interface state structure */
      _ip_address              paddr,
         /* [IN] the address to add */
      char           laddr[6]
   )
{

#if RTCSCFG_ENABLE_IP4

    ARPIF_PARM   parms;
    uint_32     error;

    parms.ihandle  = ihandle;
    parms.PADDR  = paddr;
    _mem_copy(laddr, parms.LADDR, 6); 

   error = RTCSCMD_issue(parms, ARPIF_add);

   return error;

   
#else

   return RTCSERR_IP_IS_DISABLED;
   
#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_arp_delete
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Add an entry to an interfaces ARP cache.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_arp_delete
   (
      _rtcs_if_handle _PTR_   ihandle,
         /* [IN] the RTCS interface state structure */
      _ip_address                paddr
         /* [IN] the address to add */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   ARPIF_PARM   parms;
   uint_32     error;

   parms.ihandle  = ihandle;
   parms.PADDR  = paddr;

   error = RTCSCMD_issue(parms, ARPIF_delete);

   return error;
   
#else

   return RTCSERR_IP_IS_DISABLED;
   
#endif /* RTCSCFG_ENABLE_IP4 */


} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/krtc.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: krtc.h$
* $Version : 3.8.7.0$
* $Date    : Oct-7-2011$
*
* Comments:
*
*   Processor family specific file needed for RTC module.
*
*END************************************************************************/

#ifndef __krtc_h__
#define __krtc_h__

/******************************************************************************
 * interrupt masks definitions (RTC_ISR and RTC_IER registers)                *
 ******************************************************************************/

#define RTC_INT_ALM_MASK    4
#define RTC_INT_TOF_MASK    2
#define RCT_INT_TIF_MASK    1

#define RTC_ISR_ALARM       (1 <<  0)
#define RTC_ISR_STOPWATCH   (1 <<  1)
#define RTC_ISR_TOF         (1 <<  2)
#define RTC_ISR_TIF         (1 <<  3)

#define DEVSPEC_RTC_RTCISR_SW   RTC_ISR_STOPWATCH
#define DEVSPEC_RTC_RTCISR_ALM  RTC_ISR_ALARM
#define DEVSPEC_RTC_RTCIENR_SW  RTC_ISR_STOPWATCH
#define DEVSPEC_RTC_RTCIENR_ALM RTC_ISR_ALARM
#define DEVSPEC_RTC_INT_ALL_MASK RTC_ISR_ALARM | RTC_ISR_STOPWATCH | RTC_ISR_TOF | RTC_ISR_TIF
#define STOPWATCH_OFF 0x3F

/* RTC time reperesentation */
typedef struct rtc_time_struct
{
    uint_32  seconds;
} RTC_TIME_STRUCT, _PTR_ RTC_TIME_STRUCT_PTR;

#endif   /* __krtc_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/UART0_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type UART0
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(UART0_PDD_H_)
#define UART0_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error UART0 PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MKL02Z4) /* UART0 */ && \
      !defined(MCU_MKL04Z4) /* UART0 */ && \
      !defined(MCU_MKL05Z4) /* UART0 */ && \
      !defined(MCU_MKL14Z4) /* UART0 */ && \
      !defined(MCU_MKL15Z4) /* UART0 */ && \
      !defined(MCU_MKL16Z4) /* UART0 */ && \
      !defined(MCU_MKL24Z4) /* UART0 */ && \
      !defined(MCU_MKL25Z4) /* UART0 */ && \
      !defined(MCU_MKL26Z4) /* UART0 */ && \
      !defined(MCU_MKL34Z4) /* UART0 */ && \
      !defined(MCU_MKL36Z4) /* UART0 */ && \
      !defined(MCU_MKL46Z4) /* UART0 */
  // Unsupported MCU is active
  #error UART0 PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Interrupt masks */
#define UART0_PDD_INTERRUPT_TRANSMITTER          UART0_C2_TIE_MASK /**< Transmitter interrupt enable mask */
#define UART0_PDD_INTERRUPT_TRANSMITTER_COMPLETE UART0_C2_TCIE_MASK /**< Transmitter complete interrupt enable mask */
#define UART0_PDD_INTERRUPT_RECEIVER             UART0_C2_RIE_MASK /**< Receiver interrupt enable mask */
#define UART0_PDD_INTERRUPT_IDLE                 UART0_C2_ILIE_MASK /**< Idle interrupt enable mask */
#define UART0_PDD_INTERRUPT_PARITY_ERROR         UART0_C3_PEIE_MASK /**< Parity error interrupt enable mask */
#define UART0_PDD_INTERRUPT_FRAMING_ERROR        UART0_C3_FEIE_MASK /**< Framing error interrupt enable mask */
#define UART0_PDD_INTERRUPT_NOISE_ERROR          UART0_C3_NEIE_MASK /**< Noise error interrupt enable mask */
#define UART0_PDD_INTERRUPT_OVERRUN_ERROR        UART0_C3_ORIE_MASK /**< Overrun error interrupt enable mask */

#if ((defined(MCU_MKL02Z4)) || (defined(MCU_MKL04Z4)) || (defined(MCU_MKL05Z4)))
/* Clock sources */
  #define UART0_PDD_DISABLE_CLOCK      0U          /**< Disable the clock. */
  #define UART0_PDD_FLL_CLOCK          0x1U        /**< MCG FLL clock. */
  #define UART0_PDD_EXTERNAL_REF_CLOCK 0x2U        /**< External reference clock. */
  #define UART0_PDD_INTERNAL_REF_CLOCK 0x3U        /**< Internal reference clock. */

#else /* (defined(MCU_MKL14Z4)) || (defined(MCU_MKL15Z4)) || (defined(MCU_MKL16Z4)) || (defined(MCU_MKL24Z4)) || (defined(MCU_MKL25Z4)) || (defined(MCU_MKL26Z4)) || (defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)) */
/* Clock sources */
  #define UART0_PDD_DISABLE_CLOCK      0U          /**< Disable the clock. */
  #define UART0_PDD_PLL_FLL_CLOCK      0x1U        /**< MCG PLL or FLL clock. */
  #define UART0_PDD_EXTERNAL_REF_CLOCK 0x2U        /**< External reference clock. */
  #define UART0_PDD_INTERNAL_REF_CLOCK 0x3U        /**< Internal reference clock. */

#endif /* (defined(MCU_MKL14Z4)) || (defined(MCU_MKL15Z4)) || (defined(MCU_MKL16Z4)) || (defined(MCU_MKL24Z4)) || (defined(MCU_MKL25Z4)) || (defined(MCU_MKL26Z4)) || (defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)) */
/* Parity types */
#define UART0_PDD_PARITY_NONE 0U                 /**< No parity */
#define UART0_PDD_PARITY_EVEN 0x2U               /**< Even parity */
#define UART0_PDD_PARITY_ODD  0x3U               /**< Even parity */

/* Data width */
#define UART0_PDD_WIDTH_8  0U                    /**< 8-bit communication */
#define UART0_PDD_WIDTH_9  0x1U                  /**< 9-bit communication */
#define UART0_PDD_WIDTH_10 0x2U                  /**< 10-bit communication */

/* Loop mode */
#define UART0_PDD_LOOP_MODE_NORMAL     0U        /**< Normal operation mode. No loopback selected. */
#define UART0_PDD_LOOP_MODE_LOCAL_LOOP 0x80U     /**< Local loopback mode. */

/* Stop bit lengths */
#define UART0_PDD_STOP_BIT_LEN_1 0U              /**< One stop bit. */
#define UART0_PDD_STOP_BIT_LEN_2 0x20U           /**< Two stop bits. */

/* Receiver power states. */
#define UART0_PDD_POWER_NORMAL  0U               /**< Normal operation. */
#define UART0_PDD_POWER_STANDBY 0x2U             /**< Standby mode (waiting for a wakeup condition). */


/* ----------------------------------------------------------------------------
   -- EnableTransmitter
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables UART transmitter.
 * @param PeripheralBase Peripheral base address.
 * @param State Enables or disables transmitter. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C2.
 * @par Example:
 *      @code
 *      UART0_PDD_EnableTransmitter(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define UART0_PDD_EnableTransmitter(PeripheralBase, State) ( \
    UART0_C2_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C2_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_C2_TE_MASK))) | ( \
      (uint8_t)((uint8_t)(State) << UART0_C2_TE_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableReceiver
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables UART receiver.
 * @param PeripheralBase Peripheral base address.
 * @param State Enables or disables receiver. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C2.
 * @par Example:
 *      @code
 *      UART0_PDD_EnableReceiver(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define UART0_PDD_EnableReceiver(PeripheralBase, State) ( \
    UART0_C2_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C2_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_C2_RE_MASK))) | ( \
      (uint8_t)((uint8_t)(State) << UART0_C2_RE_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- ReadDataReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Reads data register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: UART0_D.
 * @par Example:
 *      @code
 *      uint8_t result = UART0_PDD_ReadDataReg(deviceID);
 *      @endcode
 */
#define UART0_PDD_ReadDataReg(PeripheralBase) ( \
    UART0_D_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteDataReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes data specified by the Value parameter into data register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value to be written to the data register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_D.
 * @par Example:
 *      @code
 *      UART0_PDD_WriteDataReg(deviceID, 1);
 *      @endcode
 */
#define UART0_PDD_WriteDataReg(PeripheralBase, Value) ( \
    UART0_D_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- PutChar8
   ---------------------------------------------------------------------------- */

/**
 * @brief Puts 8-bits character into the transmit buffer.
 * @param PeripheralBase Peripheral base address.
 * @param Char 8-bits character to be written to the data register. This
 *        parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_D.
 * @par Example:
 *      @code
 *      UART0_PDD_PutChar8(deviceID, 1);
 *      @endcode
 */
#define UART0_PDD_PutChar8(PeripheralBase, Char) ( \
    UART0_D_REG(PeripheralBase) = \
     (uint8_t)(Char) \
  )

/* ----------------------------------------------------------------------------
   -- PutChar9
   ---------------------------------------------------------------------------- */

/**
 * @brief Puts 9-bits character into the transmit buffer.
 * @param PeripheralBase Peripheral base address.
 * @param Char 9-bits character to be written to the data register. This
 *        parameter is a 9-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C3, UART0_D
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      UART0_PDD_PutChar9(deviceID, 1);
 *      @endcode
 */
#define UART0_PDD_PutChar9(PeripheralBase, Char) ( \
    (UART0_C3_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C3_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_C3_R9T8_MASK))) | ( \
      (uint8_t)((uint8_t)((uint16_t)(Char) >> 8U) << UART0_C3_R9T8_SHIFT)))), \
    (UART0_D_REG(PeripheralBase) = \
     (uint8_t)(Char)) \
  )

/* ----------------------------------------------------------------------------
   -- PutChar10
   ---------------------------------------------------------------------------- */

/**
 * @brief Puts 10-bits character into the transmit buffer.
 * @param PeripheralBase Peripheral base address.
 * @param Char 10-bits character to be written to the data register. This
 *        parameter is a 10-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C3, UART0_D
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      UART0_PDD_PutChar10(deviceID, 1);
 *      @endcode
 */
#define UART0_PDD_PutChar10(PeripheralBase, Char) ( \
    (UART0_C3_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C3_REG(PeripheralBase) & (uint8_t)(~(uint8_t)((uint8_t)0x3U << 6U)))) | ( \
      (uint8_t)((uint8_t)((uint16_t)(Char) >> 8U) << 6U)))), \
    (UART0_D_REG(PeripheralBase) = \
     (uint8_t)(Char)) \
  )

/* ----------------------------------------------------------------------------
   -- GetChar8
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns a 8-bit character from the receive buffer.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: UART0_D.
 * @par Example:
 *      @code
 *      uint8_t result = UART0_PDD_GetChar8(deviceID);
 *      @endcode
 */
#define UART0_PDD_GetChar8(PeripheralBase) ( \
    UART0_D_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetChar9Bit
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the 9th bit of the character from the receive buffer shifted
 * to its bit position (9th). Must be called prior to calling GetChar8 to read the
 * whole 9-bit character.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 9-bit value. The value is cast to "uint16_t".
 * @remarks The macro accesses the following registers: UART0_C3.
 * @par Example:
 *      @code
 *      uint16_t result = UART0_PDD_GetChar9Bit(deviceID);
 *      @endcode
 */
#define UART0_PDD_GetChar9Bit(PeripheralBase) ( \
    (uint16_t)(( \
     (uint16_t)(( \
      (uint16_t)(UART0_C3_REG(PeripheralBase) & UART0_C3_R8T9_MASK)) >> ( \
      UART0_C3_R8T9_SHIFT))) << ( \
     8U)) \
  )

/* ----------------------------------------------------------------------------
   -- GetChar9To10thBit
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the 9th and 10th bit of the character from the receive buffer
 * shifted to their bit positions (9th and 10th). Must be called prior to calling
 * GetChar8 to read the whole 10-bit character.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 10-bit value. The value is cast to "uint16_t".
 * @remarks The macro accesses the following registers: UART0_C3.
 * @par Example:
 *      @code
 *      uint16_t result = UART0_PDD_GetChar9To10thBit(deviceID);
 *      @endcode
 */
#define UART0_PDD_GetChar9To10thBit(PeripheralBase) ( \
    (uint16_t)(( \
     (uint16_t)(( \
      (uint16_t)(( \
       (uint16_t)(UART0_C3_REG(PeripheralBase) & UART0_C3_R8T9_MASK)) >> ( \
       UART0_C3_R8T9_SHIFT))) | ( \
      (uint16_t)(( \
       (uint16_t)(( \
        (uint16_t)(UART0_C3_REG(PeripheralBase) & UART0_C3_R9T8_MASK)) >> ( \
        UART0_C3_R9T8_SHIFT))) << ( \
       1U))))) << ( \
     8U)) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables interrupts specified by the Mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "Interrupt masks". This
 *        parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C2, UART0_C3
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      UART0_PDD_EnableInterrupt(deviceID, UART0_PDD_INTERRUPT_TRANSMITTER);
 *      @endcode
 */
#define UART0_PDD_EnableInterrupt(PeripheralBase, Mask) ( \
    (UART0_C2_REG(PeripheralBase) |= \
     (uint8_t)((uint8_t)(Mask) & (uint8_t)(~(uint8_t)0xFU))), \
    (UART0_C3_REG(PeripheralBase) |= \
     (uint8_t)((uint8_t)(Mask) & 0xFU)) \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables interrupts specified by the Mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask. Use constants from group "Interrupt masks". This
 *        parameter is 8 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C2, UART0_C3
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      UART0_PDD_DisableInterrupt(deviceID, UART0_PDD_INTERRUPT_TRANSMITTER);
 *      @endcode
 */
#define UART0_PDD_DisableInterrupt(PeripheralBase, Mask) ( \
    (UART0_C2_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)((uint8_t)(Mask) & (uint8_t)(~(uint8_t)0xFU)))), \
    (UART0_C3_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)((uint8_t)(Mask) & 0xFU))) \
  )

/* ----------------------------------------------------------------------------
   -- GetTxCompleteInterruptMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets the status of the transmiter complete interrupt enable bit.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: UART0_C2.
 * @par Example:
 *      @code
 *      uint8_t result = UART0_PDD_GetTxCompleteInterruptMask(deviceID);
 *      @endcode
 */
#define UART0_PDD_GetTxCompleteInterruptMask(PeripheralBase) ( \
    (uint8_t)(UART0_C2_REG(PeripheralBase) & UART0_C2_TCIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetTxCompleteStatus
   ---------------------------------------------------------------------------- */

/**
 * @brief Gets the status of the transmiter complete interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: UART0_S1.
 * @par Example:
 *      @code
 *      uint8_t result = UART0_PDD_GetTxCompleteStatus(deviceID);
 *      @endcode
 */
#define UART0_PDD_GetTxCompleteStatus(PeripheralBase) ( \
    (uint8_t)(UART0_S1_REG(PeripheralBase) & UART0_S1_TC_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetParity
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets a communication parity type.
 * @param PeripheralBase Peripheral base address.
 * @param Parity Parity type. This parameter is of "Parity types" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C1.
 * @par Example:
 *      @code
 *      UART0_PDD_SetParity(deviceID, UART0_PDD_PARITY_NONE);
 *      @endcode
 */
#define UART0_PDD_SetParity(PeripheralBase, Parity) ( \
    UART0_C1_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C1_REG(PeripheralBase) & (uint8_t)(~(uint8_t)0x3U))) | ( \
      (uint8_t)(Parity))) \
  )

/* ----------------------------------------------------------------------------
   -- SetDataWidth
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the communication width.
 * @param PeripheralBase Peripheral base address.
 * @param Width Data width. This parameter is of "Data width" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C1, UART0_C4
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      UART0_PDD_SetDataWidth(deviceID, UART0_PDD_WIDTH_8);
 *      @endcode
 */
#define UART0_PDD_SetDataWidth(PeripheralBase, Width) ( \
    ( \
     ((Width) == UART0_PDD_WIDTH_8) ? ( \
      UART0_C1_REG(PeripheralBase) &= \
       (uint8_t)(~(uint8_t)UART0_C1_M_MASK)) : (((Width) == UART0_PDD_WIDTH_9) ? ( \
      UART0_C1_REG(PeripheralBase) |= \
       UART0_C1_M_MASK) : ( \
      UART0_C1_REG(PeripheralBase) &= \
       (uint8_t)(~(uint8_t)UART0_C1_M_MASK)) \
    )), \
    ( \
     ((Width) == UART0_PDD_WIDTH_8) ? ( \
      UART0_C4_REG(PeripheralBase) &= \
       (uint8_t)(~(uint8_t)UART0_C4_M10_MASK)) : (((Width) == UART0_PDD_WIDTH_9) ? ( \
      UART0_C4_REG(PeripheralBase) &= \
       (uint8_t)(~(uint8_t)UART0_C4_M10_MASK)) : ( \
      UART0_C4_REG(PeripheralBase) |= \
       UART0_C4_M10_MASK) \
    )) \
  )

/* ----------------------------------------------------------------------------
   -- SetLoopMode
   ---------------------------------------------------------------------------- */

/**
 * @brief Selects the loop mode operation.
 * @param PeripheralBase Peripheral base address.
 * @param LoopMode Loop mode. This parameter is of "Loop mode" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C1.
 * @par Example:
 *      @code
 *      UART0_PDD_SetLoopMode(deviceID, UART0_PDD_LOOP_MODE_NORMAL);
 *      @endcode
 */
#define UART0_PDD_SetLoopMode(PeripheralBase, LoopMode) ( \
    UART0_C1_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C1_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_C1_LOOPS_MASK))) | ( \
      (uint8_t)(LoopMode))) \
  )

/* ----------------------------------------------------------------------------
   -- ReadInterruptStatusReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the interrupt status register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: UART0_S1.
 * @par Example:
 *      @code
 *      uint8_t result = UART0_PDD_ReadInterruptStatusReg(deviceID);
 *      @endcode
 */
#define UART0_PDD_ReadInterruptStatusReg(PeripheralBase) ( \
    UART0_S1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- ClearInterruptFlags
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears the interrupt status flags specified by the Mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Mask of the flags to be cleared. This parameter is a 8-bit value.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: UART0_S1.
 * @par Example:
 *      @code
 *      uint8_t result = UART0_PDD_ClearInterruptFlags(deviceID, 1);
 *      @endcode
 */
#define UART0_PDD_ClearInterruptFlags(PeripheralBase, Mask) ( \
    UART0_S1_REG(PeripheralBase) = \
     (uint8_t)(Mask) \
  )

/* ----------------------------------------------------------------------------
   -- SetBaudRate
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets new baud rate value.
 * @param PeripheralBase Peripheral base address.
 * @param BaudRate New baud rate value. This parameter is a 13-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_BDH, UART0_BDL
 *          (depending on the peripheral).
 * @par Example:
 *      @code
 *      UART0_PDD_SetBaudRate(deviceID, 1);
 *      @endcode
 */
#define UART0_PDD_SetBaudRate(PeripheralBase, BaudRate) ( \
    (UART0_BDH_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_BDH_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_BDH_SBR_MASK))) | ( \
      (uint8_t)((uint16_t)(BaudRate) >> 8U)))), \
    (UART0_BDL_REG(PeripheralBase) = \
     (uint8_t)(BaudRate)) \
  )

/* ----------------------------------------------------------------------------
   -- SetOversamplingRatio
   ---------------------------------------------------------------------------- */

/**
 * @brief Set baud rate oversampling ratio.
 * @param PeripheralBase Peripheral base address.
 * @param Ratio Baud rate oversampling ratio. This parameter is a 5-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C4.
 * @par Example:
 *      @code
 *      UART0_PDD_SetOversamplingRatio(deviceID, 1);
 *      @endcode
 */
#define UART0_PDD_SetOversamplingRatio(PeripheralBase, Ratio) ( \
    UART0_C4_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C4_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_C4_OSR_MASK))) | ( \
      (uint8_t)(Ratio))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableSamplingOnBothEdges
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables receiver sampling on both edges.
 * @param PeripheralBase Peripheral base address.
 * @param State Enable or disable sampling on both edges. This parameter is of
 *        "Global enumeration used for specifying general enable/disable states
 *        (PDD_DISABLE and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C5.
 * @par Example:
 *      @code
 *      UART0_PDD_EnableSamplingOnBothEdges(deviceID, PDD_DISABLE);
 *      @endcode
 */
#define UART0_PDD_EnableSamplingOnBothEdges(PeripheralBase, State) ( \
    UART0_C5_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C5_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_C5_BOTHEDGE_MASK))) | ( \
      (uint8_t)((uint8_t)(State) << UART0_C5_BOTHEDGE_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- SetStopBitLength
   ---------------------------------------------------------------------------- */

/**
 * @brief Sets the number of stop bits.
 * @param PeripheralBase Peripheral base address.
 * @param Length Stop bit length. This parameter is of "Stop bit lengths" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_BDH.
 * @par Example:
 *      @code
 *      UART0_PDD_SetStopBitLength(deviceID, UART0_PDD_STOP_BIT_LEN_1);
 *      @endcode
 */
#define UART0_PDD_SetStopBitLength(PeripheralBase, Length) ( \
    UART0_BDH_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_BDH_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_BDH_SBNS_MASK))) | ( \
      (uint8_t)(Length))) \
  )

/* ----------------------------------------------------------------------------
   -- SetBreak
   ---------------------------------------------------------------------------- */

/**
 * @brief Set the break signal.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C2.
 * @par Example:
 *      @code
 *      UART0_PDD_SetBreak(deviceID);
 *      @endcode
 */
#define UART0_PDD_SetBreak(PeripheralBase) ( \
    UART0_C2_REG(PeripheralBase) |= \
     UART0_C2_SBK_MASK \
  )

/* ----------------------------------------------------------------------------
   -- ClearBreak
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears the break signal.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C2.
 * @par Example:
 *      @code
 *      UART0_PDD_ClearBreak(deviceID);
 *      @endcode
 */
#define UART0_PDD_ClearBreak(PeripheralBase) ( \
    UART0_C2_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)UART0_C2_SBK_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetBreak
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: UART0_S1.
 * @par Example:
 *      @code
 *      uint8_t result = UART0_PDD_GetBreak(deviceID);
 *      @endcode
 */
#define UART0_PDD_GetBreak(PeripheralBase) ( \
    (( \
      (uint8_t)(( \
       UART0_S1_REG(PeripheralBase)) & ( \
       (uint8_t)(UART0_S1_FE_MASK | UART0_S1_RDRF_MASK)))) == ( \
      (uint8_t)(UART0_S1_FE_MASK | UART0_S1_RDRF_MASK))) ? ( \
      0x1U) : ( \
      0U) \
  )

/* ----------------------------------------------------------------------------
   -- SendBreak
   ---------------------------------------------------------------------------- */

/**
 * @brief Send the break character.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C2.
 * @par Example:
 *      @code
 *      UART0_PDD_SendBreak(deviceID);
 *      @endcode
 */
#define UART0_PDD_SendBreak(PeripheralBase) ( \
    (UART0_C2_REG(PeripheralBase) |= \
     UART0_C2_SBK_MASK), \
    (UART0_C2_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)UART0_C2_SBK_MASK)) \
  )

/* ----------------------------------------------------------------------------
   -- SetReceiverPowerState
   ---------------------------------------------------------------------------- */

/**
 * @brief Places the receiver in a standby state where it waits for automatic
 * hardware detection of a selected wakeup condition.
 * @param PeripheralBase Peripheral base address.
 * @param State Receiver power state to be set. This parameter is of "Receiver
 *        power states." type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: UART0_C2.
 * @par Example:
 *      @code
 *      UART0_PDD_SetReceiverPowerState(deviceID, UART0_PDD_POWER_NORMAL);
 *      @endcode
 */
#define UART0_PDD_SetReceiverPowerState(PeripheralBase, State) ( \
    UART0_C2_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UART0_C2_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UART0_C2_RWU_MASK))) | ( \
      (uint8_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- SetClockSource
   ---------------------------------------------------------------------------- */

#if ((defined(MCU_MKL02Z4)) || (defined(MCU_MKL04Z4)) || (defined(MCU_MKL05Z4)))
/**
 * @brief Selects the clock source (in the SIM module).
 * @param PeripheralBase Peripheral base address.
 * @param Source Clock source. Possible values: DISABLE_CLOCK, FLL_CLOCK,
 *        EXTERNAL_REF_CLOCK, INTERNAL_REF_CLOCK. Use constants from group "Clock
 *        sources". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @par Example:
 *      @code
 *      UART0_PDD_SetClockSource(deviceID, UART0_PDD_DISABLE_CLOCK);
 *      @endcode
 */
  #define UART0_PDD_SetClockSource(PeripheralBase, Source) ( \
      SIM_SOPT2_REG(SIM_BASE_PTR) = \
       (( \
        (uint32_t)(SIM_SOPT2_REG(SIM_BASE_PTR) & (uint32_t)(~(uint32_t)SIM_SOPT2_UART0SRC_MASK))) | ( \
        (uint32_t)((uint32_t)(Source) << SIM_SOPT2_UART0SRC_SHIFT))) \
    )
#else /* (defined(MCU_MKL14Z4)) || (defined(MCU_MKL15Z4)) || (defined(MCU_MKL16Z4)) || (defined(MCU_MKL24Z4)) || (defined(MCU_MKL25Z4)) || (defined(MCU_MKL26Z4)) || (defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)) */
/**
 * @brief Selects the clock source (in the SIM module).
 * @param PeripheralBase Peripheral base address.
 * @param Source Clock source. Possible values: DISABLE_CLOCK, PLL_FLL_CLOCK,
 *        EXTERNAL_REF_CLOCK, INTERNAL_REF_CLOCK. Use constants from group "Clock
 *        sources". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @par Example:
 *      @code
 *      UART0_PDD_SetClockSource(deviceID, UART0_PDD_DISABLE_CLOCK);
 *      @endcode
 */
  #define UART0_PDD_SetClockSource(PeripheralBase, Source) ( \
      SIM_SOPT2_REG(SIM_BASE_PTR) = \
       (( \
        (uint32_t)(SIM_SOPT2_REG(SIM_BASE_PTR) & (uint32_t)(~(uint32_t)SIM_SOPT2_UART0SRC_MASK))) | ( \
        (uint32_t)((uint32_t)(Source) << SIM_SOPT2_UART0SRC_SHIFT))) \
    )
#endif /* (defined(MCU_MKL14Z4)) || (defined(MCU_MKL15Z4)) || (defined(MCU_MKL16Z4)) || (defined(MCU_MKL24Z4)) || (defined(MCU_MKL25Z4)) || (defined(MCU_MKL26Z4)) || (defined(MCU_MKL34Z4)) || (defined(MCU_MKL36Z4)) || (defined(MCU_MKL46Z4)) */
#endif  /* #if defined(UART0_PDD_H_) */

/* UART0_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_bootloader/USB_DRIVER/usb_dciapi.h<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/ /*!
  *
  * @file usb_dciapi.h
  *
  * @author 
  *
  * @version 
  *
  * @date Jun-05-2009
  *
  * @brief The file contains DCI api function definetions .
  *
  *****************************************************************************/

#ifndef _USB_DCIAPI_H
  #define _USB_DCIAPI_H

/******************************************************************************
 * Includes
 *****************************************************************************/
  
  #include "usb_devapi.h"

/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
  #define MAX_SUPPORTED_ENDPOINTS (USB_SERVICE_MAX_EP + 1)
/* Maximum endpoints supported */
  #define MIN_SUPPORTED_ENDPOINTS (1)        /* Minimum endpoints supported */
  #define DOUBLE_BUFFERED_ENPOINT_NUMBER (0) /* First double buffered endpoint */

/******************************************************************************
 * Types - None
 *****************************************************************************/

/*****************************************************************************
* Global Functions
*****************************************************************************/
extern INT8U USB_DCI_Init(
                           INT8U    controller_ID
                           );


extern INT8U USB_DCI_Init_EndPoint(
                                    INT8U              controller_ID,
                                    USB_EP_STRUCT_PTR   ep_ptr,
                                    BOOLEAN             double_buffered
                                    );

extern INT8U USB_DCI_Init_EndPoint(
                                    INT8U               controller_ID,
                                    USB_EP_STRUCT_PTR    ep_ptr,
                                    BOOLEAN              flag
                                    );

extern INT8U USB_DCI_Cancel_Transfer(
                                      INT8U    controller_ID,
                                      INT8U    ep_num,
                                      INT8U    direction
                                      );

extern INT8U USB_DCI_Deinit_EndPoint(
                                      INT8U    controller_ID,
                                      INT8U    ep_num,
                                      INT8U    direction
                                      );

extern void USB_DCI_Stall_EndPoint(
                                   INT8U    controller_ID,
                                   INT8U    ep_num,
                                   INT8U    direction
                                   );

extern void USB_DCI_Unstall_EndPoint(
                                     INT8U    controller_ID,
                                     INT8U    ep_num,
                                     INT8U    direction
                                     );

extern void USB_DCI_Get_Setup_Data(
                                   INT8U       controller_ID,
                                   INT8U       ep_num,
                                   INT8U_ptr    buff_ptr
                                   ); 

extern INT8U USB_DCI_Get_Transfer_Status(
                                          INT8U    controller_ID,
                                          INT8U    ep_num,
                                          INT8U    direction
                                          );

extern INT8U USB_DCI_Recv_Data(
                                INT8U           controller_ID,
                                INT8U           ep_num,
                                INT8U_ptr        buff_ptr,
                                INT16U  size
                                );

extern INT8U USB_DCI_Send_Data(
                                INT8U           controller_ID,
                                INT8U           ep_num,
                                INT8U_ptr        buff_ptr,
                                INT16U  size
                                );

extern void  USB_DCI_Set_Address(
                                 INT8U    controller_ID,
                                 INT8U    address
                                 );

extern void USB_DCI_Shutdown(
                             INT8U    controller_ID
                             );

extern void USB_DCI_Assert_Resume(
                                  INT8U    controller_ID
                                  );

extern void Clear_Mem(INT8U *start_addr, INT32U count, INT8U val);

  #define USB_DCI_Cancel_Transfer USB_Device_Cancel_Transfer

  #define USB_DCI_Recv_Data USB_Device_Recv_Data

  #define USB_DCI_Send_Data USB_Device_Send_Data

  #define USB_DCI_Shutdown USB_Device_Shutdown

  #define USB_DCI_Stall_EndPoint USB_Device_Stall_EndPoint

  #define USB_DCI_Unstall_EndPoint USB_Device_Unstall_EndPoint

  #define USB_DCI_Get_Transfer_Status USB_Device_Get_Transfer_Status

  #define USB_DCI_Get_Setup_Data USB_Device_Read_Setup_Data

  #define USB_DCI_Set_Address USB_Device_Set_Address

  #define USB_DCI_Assert_Resume USB_Device_Assert_Resume

#endif




<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio.c$
* $Version : 3.8.1.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   The file contains functions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/
#include "mqx.h"
#include "bsp.h"
#include "lwgpio.h"

/*FUNCTION*****************************************************************
* 
* Function Name    : LWGPIO_SET_PIN_OUTPUT
* Returned Value   : TRUE if successfull
* Comments         :
*    Set pin to output and set its state
*
*END*********************************************************************/
boolean lwgpio_set_pin_output(LWGPIO_PIN_ID id, LWGPIO_VALUE pin_state)
{
    LWGPIO_STRUCT tmp;
    return lwgpio_init(&tmp, id, LWGPIO_DIR_OUTPUT, pin_state);
}
        
/*FUNCTION*****************************************************************
* 
* Function Name    : LWGPIO_TOGGLE_PIN_OUTPUT
* Returned Value   : TRUE if succesfull 
* Comments         :
*    Toggles output pin state
*
*END*********************************************************************/
boolean lwgpio_toggle_pin_output(LWGPIO_PIN_ID id)
{
    LWGPIO_STRUCT tmp;
    if (lwgpio_init(&tmp, id, LWGPIO_DIR_OUTPUT, LWGPIO_VALUE_NOCHANGE)) {
        lwgpio_toggle_value(&tmp);
        return TRUE;
    }
    return FALSE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : LWGPIO_GET_PIN_INPUT
* Returned Value   : LWGPIO_VALUE, LWGPIO_VALUE_NOCHANGE if error
* Comments         :
*    Gets input pin state
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_pin_input(LWGPIO_PIN_ID id)
{
    LWGPIO_STRUCT tmp;
    if (lwgpio_init(&tmp, id, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE)) {
        return lwgpio_get_value(&tmp);
    }
    return LWGPIO_VALUE_NOCHANGE;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/spansion/29wsxxxN.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: 29wsxxxN.c$
* $Version : 3.8.12.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions to program the Spansion
*   S29ws128N flash devices.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "29wsxxxN.h"
#include "29wsxxxN_prv.h"
                                                      
#define FLASH_READY 1
#define FLASH_ERASE_SUSPENDED 2
#define FLASH_TIMEOUT 3
#define FLASH_BUSY 4
#define FLASH_ERROR 5
#define FLASH_UNSUPPORTED_BUS_SIZE 6
#define FLASH_WRITE_PROTECT 7

#define FLASH_RESET_CMD 0xF0

#define DQ0 0x01
#define DQ1 0x02
#define DQ2 0x04
#define DQ3 0x08
#define DQ4 0x10
#define DQ5 0x20
#define DQ6 0x40
#define DQ7 0x80

#define  UNLOCKED   0
#define  LOCKED     1

#define WS_BYTES_IN_WORD 2

uint_32 _29wsxxxN_test_erase_cmd( pointer, uint_16 );
uint_32 _29wsxxxN_test_program_cmd( pointer, uint_16 );

const FLASHX_DEVICE_IF_STRUCT _flashx_29wsxxxN_if = {
    _29wsxxxN_erase,
    _29wsxxxN_program,
    _29wsxxxN_chip_erase,
    NULL,
    NULL,
    NULL,
    _29wsxxxN_write_protect,
    _29wsxxxN_ioctl
};

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29wsxxxN_program
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs the prom devices listed below:
*       29ws128N, 29ws256N and 29ws512N
* 
*END*----------------------------------------------------------------------*/

boolean _29wsxxxN_program
   (  
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR dev_ptr,

      /* [IN] where to copy data from */
      char_ptr             from_ptr,
      
      /* [OUT] where to copy data to */
      char_ptr             to_ptr,

      /* [IN] the size to copy in bytes */
      _mem_size            size
   )
{ /* Body */
   volatile uint_16 _PTR_  base16_ptr;
   uint_32                 result = FLASH_READY;
   
   uint_16                 temp_data = 0xFFFF;
   uchar_ptr               temp_data_ptr;
   uchar                   byte_data_counter = 0;
   /* get the offset in write word */
   uint_16 offset = (uint_16)to_ptr & 0x0001;

    /* test for flash write protect */
    if (_29wsxxxN_test_lock_bits(dev_ptr) == LOCKED) {
        return  FLASH_WRITE_PROTECT;     
    }/* Endif */

   if (dev_ptr->WIDTH == 16) {

      (uint_16_ptr)temp_data_ptr =  &temp_data;
            
      /* if the start address !=  doesn't correspond with hardware, prepare
           variables for 1st word write */
      if(offset){
          /* Align pointer to writable address */
          to_ptr -= offset;
          /* jump over old data */
          byte_data_counter = offset;
      }
       
      /* set the flash base address */
      base16_ptr = (uint_16_ptr)dev_ptr->BASE_ADDR; 

      /* we have data to write */
      while (size) {
         /* read old data to write word */
          temp_data = *(uint_16_ptr)to_ptr;
         /* move data to write word byte by byte */
         while( byte_data_counter < WS_BYTES_IN_WORD && size ){
            *(uchar_ptr)(temp_data_ptr+byte_data_counter) = *from_ptr++;
            byte_data_counter++;
            size--;
         }
        /* flash program */
        _int_disable();
        /* unlock flash */
        *( base16_ptr + 0x555 ) = 0x00AA;
        *( base16_ptr + 0x2AA ) = 0x0055;
        /* Write command */            
        *( base16_ptr + 0x555 ) = 0x00A0;
        /* write value */        
        *(uint_16 _PTR_)to_ptr = temp_data;     
        _int_enable();

        /* test if the write operation complete */
        result = _29wsxxxN_test_program_cmd(to_ptr, temp_data);
        /* if write command failed, exit write command */ 
        if(result != FLASH_READY){
            break;
        }
         byte_data_counter = 0;
         temp_data = 0xFFFF;
         to_ptr += WS_BYTES_IN_WORD;
      }/* Endwhile */

   }
   else 
       result = FLASH_UNSUPPORTED_BUS_SIZE;

   return result;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29wsxxxN_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases (sector) the prom devices listed below:
*       29ws128N, 29ws256N and 29ws512N
* 
*END*----------------------------------------------------------------------*/

boolean _29wsxxxN_erase
   (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR dev_ptr,

      /* [IN] the sector to erase */
      char           _PTR_ input_sect_ptr,

      /* [IN] the sector size */
      _mem_size            sector_size
   )
{ /* Body */
   volatile uint_16 _PTR_ sect16_ptr;
   uint_32                result = FLASH_READY;
   
   uint_32 tmp1;
   uint_32 time0;

   /* test for flash write protect */
    if (_29wsxxxN_test_lock_bits(dev_ptr) == LOCKED) {
        return  FLASH_WRITE_PROTECT;     
    }/* Endif */

   if (dev_ptr->WIDTH == 16) {
      sect16_ptr = (volatile uint_16 _PTR_)input_sect_ptr;
      _int_disable();
      /* unlock flash */     
      *( sect16_ptr + 0x555 ) = 0x00AA;
      *( sect16_ptr + 0x2AA ) = 0x0055;
      /* setup command */
      *( sect16_ptr + 0x555 ) = 0x0080;
      /* unlock */
      *( sect16_ptr + 0x555 ) = 0x00AA;
      *( sect16_ptr +0x2AA ) = 0x0055;
      /* Sector erase */
      *( sect16_ptr )    = 0x0030;    
      _int_enable();

      /* erase check */ 
      tmp1 = *sect16_ptr; 
      /* wait, until DQ3 = 0 or tSEA=50us */  
      time0 = _time_get_microseconds(); 
      while(!(tmp1 & DQ3) && (_time_get_microseconds()-time0)<50){      
          tmp1 = *sect16_ptr;   
      }
      _io_flashx_wait_us(4);
      result = _29wsxxxN_test_erase_cmd(input_sect_ptr, (uint_16)0xFFFF);  
   } 
   else {
      result = FLASH_UNSUPPORTED_BUS_SIZE;
   }

   return result == FLASH_READY;
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29wsxxxN_chip_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases all the prom devices. listed below:
*       29ws128N, 29ws256N and 29ws512N
* 
*END*----------------------------------------------------------------------*/

boolean _29wsxxxN_chip_erase
   (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR dev_ptr
   )
{ /* Body */
   volatile uint_16 _PTR_ sect16_ptr;
   uint_32                result  = FLASH_READY;

   /* test for flash write protect */
    if (_29wsxxxN_test_lock_bits(dev_ptr) == LOCKED) {
        return  FLASH_WRITE_PROTECT;     
    }/* Endif */

   if (dev_ptr->WIDTH == 16) {
      sect16_ptr = (volatile uint_16 _PTR_)dev_ptr->BASE_ADDR;
      _int_disable();
      /* unlock */
      *( sect16_ptr + 0x555 ) = 0x00AA;
      *( sect16_ptr + 0x2AA ) = 0x0055;
      /* setup command */
      *( sect16_ptr + 0x555 ) = 0x0080;
      /* unlock */
      *( sect16_ptr + 0x555 ) = 0x00AA;
      *( sect16_ptr + 0x2AA ) = 0x0055;
      /* chip erase */
      *( sect16_ptr + 0x555 ) = 0x0010;    
      _int_enable();
     
      /* chip erase test */
      result = _29wsxxxN_test_erase_cmd((uchar_ptr)sect16_ptr, (uint_16)0xFFFF);     
   }
   else {
      result = FLASH_UNSUPPORTED_BUS_SIZE; 
   }

   return result == FLASH_READY;
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : 29wsxxxN_test_erase_cmd
* Returned Value   : uint_32 current status of operation
* Comments         : test, if the write flash command operation finished
*
*END*----------------------------------------------------------------------*/
uint_32 _29wsxxxN_test_erase_cmd
   (
      /* [IN] address */
      pointer              to_ptr,
      /* written data */
      uint_16              write_data
   ) 
{
    uint_16     test_data, test_data1;
    uchar       error_count = 0;
    uint_32     result =  FLASH_BUSY;   

    while(result == FLASH_BUSY){
        /* Read 1 */
        test_data = *(uint_16 _PTR_)to_ptr;
        /* DQ7 contain valid data? */
        if((test_data & DQ7) == (write_data & DQ7)){
            /* Read 2 */
            test_data1 = *(uint_16 _PTR_)to_ptr;
            /* Read 3 */
            test_data = *(uint_16 _PTR_)to_ptr;
            /* DQ6 toggling, device error */
            if((test_data & DQ6) != (test_data1 & DQ6) ){
                /* software flash reset */
                *(uint_16 _PTR_)to_ptr = FLASH_RESET_CMD;
                result = FLASH_ERROR;
            }
            /* Erase operation complete */
            if((test_data & DQ2) == (test_data1 & DQ2)){
                result = FLASH_READY;
            }
        }
        /* test for operation internal timeout */
        else {
            /* read 1 DQ5 = 1? */
            if(test_data & DQ5){
                /* read 2 */
                test_data1 = *(uint_16 _PTR_)to_ptr;
                /* read 3 */
                test_data = *(uint_16 _PTR_)to_ptr;
                /* DQ6 togling? Timeout occured */  
                if(test_data1 & DQ6 != test_data & DQ6){
                    result = FLASH_TIMEOUT;
                    /* software flash reset */
                    *(uint_16 _PTR_)to_ptr = FLASH_RESET_CMD;
                }
            }
        }
    }
    
    return result == FLASH_READY;       
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : 29wsxxxN_test_program_cmd
* Returned Value   : uint_32 current status of operation
* Comments         : test, if the write flash command operation finished
*
*END*----------------------------------------------------------------------*/
uint_32 _29wsxxxN_test_program_cmd
   (
      /* [IN] address */
      pointer              to_ptr,
      /* written data */
      uint_16              write_data
   ) 
{
    uint_16     test_data, test_data1;
    uint_16     cycle_counter = 5000;
    uchar       error_count = 0;
    uint_32     result =  FLASH_BUSY;   

    while(result == FLASH_BUSY){
        /* Read 1 */
        test_data = *(uint_16 _PTR_)to_ptr;
        /* DQ7 contain valid data? */
        if((test_data & DQ7) == (write_data & DQ7)){
            /* Read 2 */
            test_data1 = *(uint_16 _PTR_)to_ptr;
            /* Read 3 */
            test_data = *(uint_16 _PTR_)to_ptr;
            /* Read 3 valid data => Write operation complete */
            if(test_data == write_data){
                result = FLASH_READY;
            }
            /* Read 3 doesn't contain valid data, operation failed */
            else {                  
                if(error_count++>2){
                    result = FLASH_ERROR;
                    /* software flash reset */
                    *(uint_16 _PTR_)to_ptr = FLASH_RESET_CMD;
                }
            }
        }
        /* test for operation internal timeout */
        else {
            if(!(test_data & DQ5)){
                test_data1 = *(uint_16 _PTR_)to_ptr;
                test_data = *(uint_16 _PTR_)to_ptr;
                /* DQ6 togling? Timeout occured */  
                if(test_data1 & DQ6 != test_data & DQ6){
                    result = FLASH_TIMEOUT;
                    /* software flash reset */
                    *(uint_16 _PTR_)to_ptr = FLASH_RESET_CMD;
                }
            }
        }
        /* timeout test */
        if(!cycle_counter--){
            result = FLASH_TIMEOUT;
        }
    }
    
    return result;      
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29wsxxxN_test_lock_bits
* Returned Value   : uint_32 current status of operation
* Comments         : test, if flash is write protect
*
*END*----------------------------------------------------------------------*/
static boolean _29wsxxxN_test_lock_bits
    (
      /* [IN] the flash information structure */
      IO_FLASHX_STRUCT_PTR dev_ptr
    ) 
{
    uint_16_ptr base_address_ptr = (uint_16_ptr)dev_ptr->BASE_ADDR;
    uint_16_ptr sector_address_ptr; 
    int i;
    int sector_count;
    uint_16 data = 0;
        
    /* go over all blocks */
    for ( i = 0; dev_ptr->HW_BLOCK[i].NUM_SECTORS != 0 ; i++ ) {
        /* set the start block address */
        sector_address_ptr = (uint_16_ptr)dev_ptr->HW_BLOCK[i].START_ADDR; 
        /* go over all sectors in block */
        for ( sector_count = 0; sector_count < dev_ptr->HW_BLOCK[i].NUM_SECTORS; sector_count ++){
            /* enter DYB mode */
            _int_disable();
            *( base_address_ptr + 0x555 ) = 0x00AA; /* write unlock cycle 1 */
            *( base_address_ptr + 0x2AA ) = 0x0055; /* write unlock cycle 2 */
            *( sector_address_ptr + 0x555 ) = 0x00E0; /* write command entry */
            /* read sector lock bit */
            data = *sector_address_ptr;             
            /* exit DYB mode */
            *( base_address_ptr ) = 0x0090; /* command set exit */
            *( base_address_ptr ) = 0x0000; 
            _int_enable();
            /* is sector locked? 0 == locked */
            if( !(data & DQ0) ){    
                /* yes - exit locked */
                return LOCKED;
            }               
            /* no - incrememnt sector address */
            (uchar_ptr)sector_address_ptr += (dev_ptr->HW_BLOCK[i].SECTOR_SIZE); 
        }       
    }
    /* exit flash unlocked */
    return UNLOCKED;    
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29wsxxxN_write_protect
* Returned Value   : uint_32 current status of operation
* Comments         : lock/unlock flash for write
*
*END*----------------------------------------------------------------------*/
boolean _29wsxxxN_write_protect
    (
        /* [IN] the base address of the device */
      IO_FLASHX_STRUCT_PTR  dev_ptr,
      
      /* [IN]  */
      _mqx_uint             lock
    ) 
{
    volatile uint_16_ptr source_address_ptr;
    uint_16_ptr sector_address_ptr; 
    uint_16_ptr base_address_ptr = (uint_16_ptr)dev_ptr->BASE_ADDR;
    int i;
    int sector_count;
    uint_16 command = 0;

    /* set the lock/unlock command */
    if (lock == 1 ){
        /* lock sector command */
        command = 0;
    }
    else {
        /* unlock sector command */
        command = 1;
    }
    /* go over all blocks */
    for ( i = 0; dev_ptr->HW_BLOCK[i].NUM_SECTORS != 0; i++ ) {
        /* set the start block address */
        sector_address_ptr = (uint_16_ptr)dev_ptr->HW_BLOCK[i].START_ADDR; 
        /* go over all sectors in block */
        for ( sector_count = 0; sector_count < dev_ptr->HW_BLOCK[i].NUM_SECTORS; sector_count ++){
            /* enter DYB mode */
            _int_disable(); 
            *( base_address_ptr + 0x555 ) = 0x00AA; /* write unlock cycle 1 */
            *( base_address_ptr + 0x2AA ) = 0x0055; /* write unlock cycle 2 */
            *( sector_address_ptr + 0x555 ) = 0x00E0; /* write command */
            *( base_address_ptr ) = 0x00A0; 
            *( sector_address_ptr ) = command; 
            *( base_address_ptr ) = 0x0090; /* command set exit */
            *( base_address_ptr ) = 0x0000; 
            _int_enable();                      
            /* increment sector */
            (uchar_ptr)sector_address_ptr += (dev_ptr->HW_BLOCK[i].SECTOR_SIZE); 
        }       
    }
    /* reset device */
    * base_address_ptr = FLASH_RESET_CMD;
    
    return MQX_OK;  
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29wsxxxN_ioctl
* Returned Value   : TRUE if successful
* Comments         : 
*    flash ioctl function
* 
*END*----------------------------------------------------------------------*/
_mqx_int _29wsxxxN_ioctl
   (
      /* [IN] the handle returned from _fopen */
      IO_FLASHX_STRUCT_PTR handle_ptr,

      /* [IN] the ioctl command */
      _mqx_uint              cmd,

      /* [IN] the ioctl parameters */
      pointer                param_ptr
   )
{ /* Body */
    _mqx_uint                       result = MQX_OK;
    switch(cmd) {
        case FLASH_IOCTL_GET_WRITE_PROTECT:
            /* is the flash locked ? */
            if (_29wsxxxN_test_lock_bits(handle_ptr) ) {
                *((boolean _PTR_)param_ptr) = TRUE;
            } else {
                *((boolean _PTR_)param_ptr) = FALSE;
            }
            break;
        default:
            break;
    }
    return result;
}


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ip6_trace.h<|end_filename|>
#ifndef __ip6_trace_h__
#define __ip6_trace_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip6_trace.h$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the TCP/IP tracing feature.
*   It is based on FNET project.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "ethernet.h"
#include "icmp6_prv.h"

/******************************************************************
* Function Prototypes
*******************************************************************/
#if RTCSCFG_DEBUG_TRACE_ETH
    void trace_eth(char *str, ENET_HEADER_PTR eth_hdr);
#else
    #define trace_eth(str, eth_hdr)
#endif 

#if RTCSCFG_DEBUG_TRACE_IP6
    void trace_ip6(char *str, IP6_HEADER_PTR ip_hdr);
#else
    #define trace_ip6(str, ip_hdr)
#endif 

#if RTCSCFG_DEBUG_TRACE_ICMP6
    void trace_icmp6(char *str, ICMP6_HEADER_PTR icmp_hdr);
#else
    #define trace_icmp6(str, icmp_hdr)
#endif 


#endif /*__ip6_trace_h__*/



<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_create.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_create.c$
* $Version : 3.6.6.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the file specific interface functions
*   of MFS which need a filename as an input parameter.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"

#if !MFSCFG_READ_ONLY

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Create_file
* Returned Value   : file_handle
* Comments  :   Create a file.  If the file exists then truncate it to 0.
*
*END*---------------------------------------------------------------------*/

pointer  MFS_Create_file
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] the MFS device on which to operate */
    uchar                   attr,       /*[IN] attribute for created file*/
    char_ptr                pathname,   /*[IN] directory and filename of the file to be created */
    _mfs_error_ptr          error_ptr   /*[IN/OUT] error code is written to this address */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_HANDLE_PTR          handle,next_handle;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    TIME_STRUCT             time;
    DATE_STRUCT             clk_time;
    uint_32                 dir_cluster;
    uint_32                 dir_index;
    char                    access;
    _mfs_error              error_code, saved_code = 0;

    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        *error_ptr = MFS_INVALID_PARAMETER;
        return( NULL );
    }

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        *error_ptr = MFS_DISK_IS_WRITE_PROTECTED;
        return NULL;
    }
#endif

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        *error_ptr = error_code;
        return( NULL );
    }

    handle = NULL;

    attr &= (MFS_ATTR_READ_ONLY | MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE | MFS_ATTR_ARCHIVE | MFS_ATTR_VOLUME_NAME);
    attr |= MFS_ATTR_ARCHIVE;
    access = (attr & MFS_ATTR_READ_ONLY) ? MFS_ACCESS_READ_ONLY : MFS_ACCESS_READ_WRITE;
    dir_entry_ptr =  MFS_Create_entry_slave(drive_ptr, attr, pathname, &dir_cluster, &dir_index, &error_code, TRUE);

    if ( (dir_entry_ptr != NULL) && !(attr & MFS_ATTR_VOLUME_NAME) )
    {
        handle = MFS_Get_handle(drive_ptr,dir_entry_ptr);
        if ( handle != NULL )
        {
            handle->DIR_CLUSTER = dir_cluster;
            handle->DIR_INDEX = dir_index;
            handle->ACCESS = access;
            handle->CURRENT_CLUSTER = 0;
            handle->PREVIOUS_CLUSTER = 0;

            /*
            ** If file exists, overwrite and set size to 0
            */
            if ( error_code == MFS_FILE_EXISTS )
            {
                _time_get(&time);
                _time_to_date(&time, &clk_time);
                NORMALIZE_DATE(&clk_time);
                saved_code = MFS_Release_chain(drive_ptr, clustoh(handle->DIR_ENTRY.HFIRST_CLUSTER, handle->DIR_ENTRY.LFIRST_CLUSTER));
                if ( saved_code == MFS_NO_ERROR || saved_code == MFS_LOST_CHAIN )
                {
                    clustod(handle->DIR_ENTRY.HFIRST_CLUSTER, handle->DIR_ENTRY.LFIRST_CLUSTER, 0);
                    htodl(handle->DIR_ENTRY.FILE_SIZE, 0L);
                    htodc(handle->DIR_ENTRY.ATTRIBUTE, attr);
                    htods(handle->DIR_ENTRY.TIME, PACK_TIME(clk_time));
                    htods(handle->DIR_ENTRY.DATE, PACK_DATE(clk_time));
                    error_code = MFS_Update_entry(drive_ptr, handle);

                    /*
                    ** If the same file is already open, mark it as 'freshly
                    ** truncated' so reads and writes don't clobber any data.
                    */
                    if ( error_code == MFS_NO_ERROR )
                    {
                        next_handle =  (MFS_HANDLE_PTR) _queue_head(&drive_ptr->HANDLE_LIST);
                        while ( next_handle )
                        {
                            if ( next_handle->DIR_CLUSTER == dir_cluster && next_handle->DIR_INDEX == dir_index )
                            {
                                next_handle->CURRENT_CLUSTER = 0;
                                next_handle->PREVIOUS_CLUSTER = 0;
                            }
                            next_handle =  (MFS_HANDLE_PTR) _queue_next(&drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) next_handle);
                        }  
                    }
                }
            }

            /*
            ** No need to update the disk image if we didn't change anything.
            */
            if ( (dtohc(handle->DIR_ENTRY.ATTRIBUTE) != attr) && (error_code == MFS_NO_ERROR) )
            {
                htodc(handle->DIR_ENTRY.ATTRIBUTE, attr);
                error_code = MFS_Update_entry(drive_ptr, handle);
            }

        }
        else
        {
            error_code = MFS_INSUFFICIENT_MEMORY;
        }  
    }

    MFS_unlock(drive_ptr,FALSE);

    if ( error_code == MFS_NO_ERROR && saved_code == MFS_LOST_CHAIN )
    {
        *error_ptr = saved_code;
    }
    else
    {
        *error_ptr = error_code; 
    }  

    return((pointer)handle);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Create_new_file
* Returned Value   : file handle
* Comments  :   Create a file. If the file exists, then an error has occurred.
*
*END*---------------------------------------------------------------------*/

pointer  MFS_Create_new_file
    (
    MQX_FILE_PTR            mfs_fd_ptr,     /*[IN] the MFS device on which to operate */
    uchar                   attr,           /*[IN] attribute to be given to the new file */
    char_ptr                pathname,       /*[IN] directory and file name to be given to the new file */
    _mfs_error_ptr             error_ptr    /*[IN/OUT] error code is written to this address */
    )
{

    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_HANDLE_PTR          handle;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    uint_32                 dir_cluster, dir_index;
    _mfs_error              error_code;
    char                    access;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        *error_ptr = MFS_DISK_IS_WRITE_PROTECTED;
        return NULL;
    }
#endif

    handle = NULL;
    error_code = MFS_NO_ERROR;

    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        *error_ptr = MFS_INVALID_PARAMETER;
        return( NULL );

    }

    *error_ptr = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( *error_ptr != MFS_NO_ERROR )
    {
        return NULL;
    }

    attr &= (MFS_ATTR_READ_ONLY | MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE | MFS_ATTR_ARCHIVE);
    attr |= MFS_ATTR_ARCHIVE;   

    access = (attr & MFS_ATTR_READ_ONLY) ? MFS_ACCESS_READ_ONLY : MFS_ACCESS_READ_WRITE;

    dir_entry_ptr =  MFS_Create_entry_slave(drive_ptr, attr, pathname, &dir_cluster, &dir_index, &error_code, FALSE);

    if ( error_code == MFS_NO_ERROR && dir_entry_ptr != NULL )
    {
        handle = MFS_Get_handle(drive_ptr,dir_entry_ptr);

        if ( handle )
        {
            handle->ACCESS = access;
            handle->DIR_CLUSTER = dir_cluster;
            handle->DIR_INDEX = dir_index;
            handle->CURRENT_CLUSTER = 0;
            handle->PREVIOUS_CLUSTER = 0;
        }
        else
        {
            error_code = MFS_INSUFFICIENT_MEMORY;
        }  
    }

    MFS_unlock(drive_ptr,FALSE);

    if ( error_ptr )
    {
        *error_ptr = error_code;
    }

    return((pointer)handle);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Create_temp_file
* Returned Value   : MFS_HANDLE_PTR
* Comments  :   Create a temporary file with an internally generated name.
*
*END*---------------------------------------------------------------------*/

pointer  MFS_Create_temp_file
    (
    MQX_FILE_PTR            mfs_fd_ptr,     /*[IN] the MFS device on which to operate */
    uchar                   attr,           /*[IN] attribute to be given to the file when it is created */
    char_ptr                pathname,       /*[IN] provides the directory path where the file is to be created,
                                            **[OUT] the file name is appended to the directory name */
    _mfs_error_ptr             error_ptr    /*[OUT] Pointer for the MFS ERROR CODE location */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_HANDLE_PTR          handle;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    _mfs_error              error_code;
    uint_32                 dir_cluster, dir_index;
    uint_16                 trial;
    char_ptr                last_char;
    uint_16                 pathlen;
    uchar                   access;
    char_ptr                temp_file;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        *error_ptr = MFS_DISK_IS_WRITE_PROTECTED;
        return NULL;
    }
#endif

    trial = 0;
    error_code = MFS_FILE_NOT_FOUND;
    handle = NULL;

    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        *error_ptr = MFS_INVALID_PARAMETER;
        return( NULL );
    }

    *error_ptr  = MFS_alloc_path(&temp_file);
    if ( *error_ptr )
    {
        return( NULL );
    }

    *error_ptr = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( *error_ptr != MFS_NO_ERROR )
    {
        MFS_free_path(temp_file);
        return NULL;
    }

    attr &= (MFS_ATTR_READ_ONLY | MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE | MFS_ATTR_ARCHIVE | MFS_ATTR_VOLUME_NAME);
    attr |= MFS_ATTR_ARCHIVE;
    access = (attr & MFS_ATTR_READ_ONLY) ? MFS_ACCESS_READ_ONLY : MFS_ACCESS_READ_WRITE;

    dir_cluster = drive_ptr->CUR_DIR_CLUSTER;
    dir_cluster = MFS_Find_directory(drive_ptr, pathname, dir_cluster);

    if ( dir_cluster == CLUSTER_INVALID )
    {
        error_code = MFS_PATH_NOT_FOUND;
    }
    else
    {
        pathlen = strlen (pathname);
        last_char = pathname + pathlen;
        if ( pathlen )
        {
            last_char--;
        }

        do
        {
            sprintf(temp_file, (*last_char == '\\' || *last_char == '/' || pathlen == 0) ?
                "%sTMP%05.5lu.@@@" : "%s\\TMP%05.5lu.@@@", pathname, (uint_32) trial);
            dir_entry_ptr = MFS_Create_entry_slave(drive_ptr, attr, temp_file, &dir_cluster, &dir_index, &error_code, FALSE);
            trial++;
        } while ( (error_code == MFS_FILE_EXISTS) && (trial < MFSCFG_FIND_TEMP_TRIALS) );

        if ( error_code == MFS_NO_ERROR )
        {
            handle = MFS_Get_handle(drive_ptr,dir_entry_ptr);
            if ( handle )
            {
                _mem_copy (temp_file, pathname, strlen(temp_file) + 1);
                handle->DIR_CLUSTER = dir_cluster;
                handle->DIR_INDEX = dir_index;
                handle->ACCESS = access;
                handle->CURRENT_CLUSTER = 0;
                handle->PREVIOUS_CLUSTER = 0;
            }
            else
            {
                error_code = MFS_INSUFFICIENT_MEMORY;
            }  
        }
    }  

    MFS_free_path(temp_file);
    MFS_unlock(drive_ptr,FALSE);

    if ( error_ptr )
    {
        *error_ptr = error_code;
    }

    return((pointer) handle);
}  

#endif



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/soigmp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: soigmp.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of getsockopt()
*   and setsockopt() at the SOL_IGMP level.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "socket.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "udp_prv.h"

#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4

#define RTCS_ENTER(f,a) RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_IGMP_ ## f, a)

#define RTCS_EXIT(f,a)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_IGMP_ ## f, a); \
                        return a


uint_32 SOL_IGMP_getsockopt  (uint_32, uint_32, uint_32, pointer, uint_32 _PTR_);
uint_32 SOL_IGMP_setsockopt  (uint_32, uint_32, uint_32, pointer, uint_32);

extern uint_32 IGMP_leave_if_local (IP_IF_PTR, MC_MEMBER_PTR _PTR_);

const RTCS_SOCKOPT_CALL_STRUCT SOL_IGMP_CALL = {
   SOL_IGMP_getsockopt,
   SOL_IGMP_setsockopt
};

static void IGMP_getopt (IGMP_PARM_PTR);
static void IGMP_setopt (IGMP_PARM_PTR);

       uint_32 IGMP_join_if          (ip_mreq _PTR_);
       uint_32 IGMP_leave_if         (ip_mreq _PTR_);
       uint_32 IGMP_leave_if_all     (MC_MEMBER_PTR _PTR_);
static uint_32 IGMP_join_socket      (MC_MEMBER_PTR _PTR_, ip_mreq _PTR_, uint_32 (_CODE_PTR_ _PTR_)(MC_MEMBER_PTR _PTR_));
static uint_32 IGMP_leave_socket     (MC_MEMBER_PTR _PTR_, ip_mreq _PTR_, uint_32 (_CODE_PTR_ _PTR_)(MC_MEMBER_PTR _PTR_));
static uint_32 IGMP_leave_socket_all (ip_mreq _PTR_);

uint_32 IGMP_get_membership (IGMP_PARM_PTR);
uint_32 IGMP_ipif_unbind    (IP_IF_PTR, _ip_address);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_IGMP_getsockopt
* Returned Value  : error code
* Comments  :  Obtain the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_IGMP_getsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] buffer for the current value of the option */
      uint_32  _PTR_ optlen
         /* [IN/OUT] length of the option value, in bytes */
   )
{ /* Body */
   IGMP_PARM   parms;
   uint_32     error;

   RTCS_ENTER(GETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(GETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   parms.sock   = (SOCKET_STRUCT_PTR)sock;
   parms.option = optname;
   parms.optptr = optval;
   parms.optlen = *optlen;
   error = RTCSCMD_issue(parms, IGMP_getopt);
   if (error) {
      RTCS_EXIT(GETSOCKOPT, error);
   } /* Endif */

   *optlen = parms.optlen;
   RTCS_EXIT(GETSOCKOPT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_IGMP_setsockopt
* Returned Value  : error code
* Comments  :  Modify the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_IGMP_setsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] new value for the option */
      uint_32        optlen
         /* [IN] length of the option value, in bytes */
   )
{ /* Body */
   IGMP_PARM   parms;
   uint_32     error;

   RTCS_ENTER(SETSOCKOPT, sock);

#if RTCSCFG_CHECK_ERRORS
   if (sock == 0 || sock == RTCS_SOCKET_ERROR) {
      RTCS_EXIT(SETSOCKOPT, RTCSERR_SOCK_INVALID);
   } /* Endif */
#endif

   parms.sock   = (SOCKET_STRUCT_PTR)sock;
   parms.option = optname;
   parms.optptr = optval;
   parms.optlen = optlen;
   error = RTCSCMD_issue(parms, IGMP_setopt);
   if (error) {
      RTCS_EXIT(SETSOCKOPT, error);
   } /* Endif */

   RTCS_EXIT(SETSOCKOPT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_getopt
* Parameters      :
*
*     SOCKET_STRUCT_PTR sock        [IN] socket
*     uint_32           option      [IN] option
*     pointer           optptr      [OUT] option value
*     uint_32           optlen      [IN/OUT] size of optptr
*
* Comments        :
*     Retrieves the value of an IGMP option.
*
*END*-----------------------------------------------------------------*/

static void IGMP_getopt
   (
      IGMP_PARM_PTR     parms
   )
{ /* Body */
   uint_32     error = RTCS_OK;

   switch (parms->option) {

   case RTCS_SO_IGMP_GET_MEMBERSHIP:
      error = IGMP_get_membership(parms);
      break;

   default:
      error = RTCSERR_SOCK_INVALID_OPTION;
   } /* Endswitch */

   RTCSCMD_complete(parms, error);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_setopt
* Parameters      :
*
*     SOCKET_STRUCT_PTR sock        [IN] socket
*     uint_32           option      [IN] option
*     pointer           optptr      [IN] option value
*     uint_32           optlen      [IN] size of optptr
*
* Comments        :
*     Sets the value of an IGMP option.
*
*END*-----------------------------------------------------------------*/

static void IGMP_setopt
   (
      IGMP_PARM_PTR     parms
   )
{ /* Body */
   uint_32     error = RTCS_OK;

   if (parms->optlen < sizeof(ip_mreq)) {
      RTCSCMD_complete(parms, RTCSERR_SOCK_SHORT_OPTION);
      return;
   } /* Endif */

   switch (parms->option) {

   case RTCS_SO_IGMP_ADD_MEMBERSHIP:
      error = IGMP_join_group(parms->sock->MCB_PTR, parms->optptr, parms->sock->IGMP_LEAVEALL);
      break;

   case RTCS_SO_IGMP_DROP_MEMBERSHIP:
      error = IGMP_leave_group(parms->sock->MCB_PTR, parms->optptr, parms->sock->IGMP_LEAVEALL);
      break;

   default:
      error = RTCSERR_SOCK_INVALID_OPTION;
   } /* Endswitch */

   RTCSCMD_complete(parms, error);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_join_if
* Returned Values : error code
* Comments        :
*     join the group on a given interface
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_join_if
   (
      ip_mreq _PTR_ igrp  /* [IN] the group description */
   )
{ /* Body */
   MC_MEMBER_PTR _PTR_  pgroup;
   IP_IF_PTR            ipif;
   uint_32              status;

   /* get the interface pointer with the ip */
   ipif = IP_find_if(igrp->imr_interface.s_addr);
   if (!ipif) {
      return RTCSERR_IGMP_INVALID_IP;
   } /* Endif */

   /* test if the group is already joined */
   pgroup = IGMP_member_find(&ipif->IGMP_MEMBER, igrp);
   if (pgroup) {
      (*pgroup)->UCOUNT++;
      return RTCS_OK;
   } /* Endif */

   /* if it isn't already joined, join it */
   pgroup = IGMP_member_create(&ipif->IGMP_MEMBER, igrp);
   if (!pgroup) {
      return RTCSERR_IGMP_GROUP_ALLOC;
   } /* Endif */

   /* join the group on the physical interface */
   status = IGMP_filter_add(ipif, igrp->imr_multiaddr.s_addr);
   if (status != RTCS_OK) {
      IGMP_member_delete(pgroup);
      return status;
   } /* Endif */

   /*
   ** a local group is not routed, by definition. so we don't advertise it.
   */
   /* send the unsolicited report for nonlocal groups */
   if (!IN_LOCAL_MULTICAST(igrp->imr_multiaddr.s_addr)) {
      IGMP_init_timer(*pgroup);
      IGMP_launch_timer(*pgroup, 0);
   } /* Endif */

   ipif->IGMP_UNBIND = IGMP_ipif_unbind;
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_leave_if
* Returned Values : error code
* Comments        :
*     leave the group on a given interface
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_leave_if
   (
      ip_mreq _PTR_ igrp  /* [IN] the group description */
   )
{ /* Body */
   MC_MEMBER_PTR _PTR_  pmember;
   IP_IF_PTR            ipif;
   uint_32              status;
#ifdef IGMP_V2
   boolean              last_reporter;
#endif

   /* get the interface pointer of the interface */
   ipif = IP_find_if(igrp->imr_interface.s_addr);
   if (!ipif) {
      return RTCSERR_IGMP_INVALID_IP;
   } /* Endif */

   pmember = IGMP_member_find(&ipif->IGMP_MEMBER, igrp);
   if (!pmember) {
      return RTCSERR_IGMP_NOT_JOINED;
   } /* Endif */
   (*pmember)->UCOUNT--;
   if ((*pmember)->UCOUNT) {
      return RTCS_OK;
   } /* Endif */

#ifdef IGMP_V2
   last_reporter = (*pmember)->LAST_REPORTER;
#endif

   /* stop the timer if required */
   IGMP_stop_timer(*pmember);

   /* leave the group */
   status = IGMP_member_delete(pmember);

   /* leave the group on the physical interface */
   status = IGMP_filter_rm(ipif, igrp->imr_multiaddr.s_addr);
   if (status != RTCS_OK) {
      return status;
   } /* Endif */

#ifdef IGMP_V2
   /* send the leave report for the nonlocal group */
   if (last_reporter && !IN_LOCAL_MULTICAST(igrp->imr_multiaddr.s_addr)) {
   /* Start CR 2091 */
      IGMP_send_report(igrp, IGMPTYPE_LEAVE);
   /* End CR 2091 */   
   } /* Endif */
#endif

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_join_socket
* Returned Values : error code
* Comments        :
*     join the group on a given socket
*
*END*-----------------------------------------------------------------*/

static uint_32 IGMP_join_socket
   (
      MC_MEMBER_PTR _PTR_        phead,   /* [IN] head of group list */
      ip_mreq _PTR_              igrp,
      uint_32 (_CODE_PTR_ _PTR_  pfn)(MC_MEMBER_PTR _PTR_)
   )
{ /* Body */
   MC_MEMBER_PTR _PTR_  pgroup;

   /* test if the group is already joined */
   pgroup = IGMP_member_find(phead, igrp);
   if (pgroup) {
      (*pgroup)->UCOUNT++;
      return RTCS_OK;
   } /* Endif */

   /* if it isnt already joined, join it */
   pgroup = IGMP_member_create(phead, igrp);
   if (!pgroup) {
      return RTCSERR_IGMP_GROUP_ALLOC;
   } /* Endif */

   *pfn = IGMP_leave_if_all;
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_leave_socket
* Returned Values : error code
* Comments        :
*     leave the group on a given socket
*
*END*-----------------------------------------------------------------*/

static uint_32 IGMP_leave_socket
   (
      MC_MEMBER_PTR _PTR_        phead,   /* [IN] head of group list */
      ip_mreq _PTR_              igrp,
      uint_32 (_CODE_PTR_ _PTR_  pfn)(MC_MEMBER_PTR _PTR_)
   )
{ /* Body */
   MC_MEMBER_PTR _PTR_  pmember;
   uint_32              status;

   /* test if the group is joined */
   pmember = IGMP_member_find(phead, igrp);
   if (!pmember) {
      return RTCSERR_IGMP_NOT_JOINED;
   } /* Endif */
   (*pmember)->UCOUNT--;
   if ((*pmember)->UCOUNT) {
      return RTCS_OK;
   } /* Endif */

   status = IGMP_member_delete(pmember);

   if (!*phead) {
      *pfn = NULL;
   } /* Endif */
   return status;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_join_group
* Returned Values : error code
* Comments        :
*     Join a given group
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_join_group
   (
      MC_MEMBER_PTR _PTR_        phead,   /* [IN] head of group list */
      ip_mreq _PTR_              igrp,    /* [IN] group decriptor */
      uint_32 (_CODE_PTR_ _PTR_  pfn)(MC_MEMBER_PTR _PTR_)
   )
{ /* Body */
   uint_32  status;

   /* add the group in the socket list */
   status = IGMP_join_socket(phead, igrp, pfn);
   if (status != RTCS_OK) {
      return status;
   } /* Endif */

   /* join the group on the interface */
   status = IGMP_join_if(igrp);
   if (status != RTCS_OK) {
      /* leave the group on the socket */
      IGMP_leave_socket(phead, igrp, pfn);
      return status;
   } /* Endif */

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_leave_group
* Returned Values : error code
* Comments        :
*     Leave a given group
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_leave_group
   (
      MC_MEMBER_PTR _PTR_        phead,   /* [IN] head of group list */
      ip_mreq _PTR_              igrp,    /* [IN] group decriptor */
      uint_32 (_CODE_PTR_ _PTR_  pfn)(MC_MEMBER_PTR _PTR_)
   )
{ /* Body */
   uint_32  status, tmp;

   /* leave the group in the socket list */
   status = IGMP_leave_socket(phead, igrp, pfn);

   /* leave the group on the interface */
   tmp = IGMP_leave_if(igrp);
   if (tmp != RTCS_OK && status == RTCS_OK) {
      status = tmp;
   } /* Endif */

   return status;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_get_membership
* Returned Values : error code
* Comments        :
*     Get the list of all group memberships of a given socket
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_get_membership
   (
      IGMP_PARM_PTR     parms
   )
{ /* Body */
   ip_mreq _PTR_  igrp = parms->optptr;
   uint_32        i, j;
   MC_MEMBER_PTR  group;

   i = parms->optlen;
   j = 0;

   if (parms->sock->MCB_PTR) {
      for (group = *parms->sock->MCB_PTR;
           group;
           group = group->NEXT, j += sizeof(ip_mreq)) {

         if (i >= sizeof(ip_mreq)) {
            *igrp = group->IGRP;
            igrp++;
            i -= sizeof(ip_mreq);
         } else if (i > 0) {
            ip_mreq fullgroup;
            fullgroup = group->IGRP;
            _mem_copy(&fullgroup, igrp, i);
            i = 0;
         } /* Endif */

      } /* Endfor */
   } /* Endif */

   parms->optlen = j;
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_leave_if_all
* Returned Values : error code
* Comments        :
*     Leave all the groups.
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_leave_if_all
   (
      MC_MEMBER_PTR _PTR_        phead
   )
{ /* Body */
   ip_mreq  igrp;
   uint_32 (_CODE_PTR_ temp_pfn)(MC_MEMBER_PTR _PTR_);
   uint_32  status, tmp;

   status = RTCS_OK;

   /* leave all groups not still leaved */
   while (*phead) {
      igrp = (*phead)->IGRP;
      tmp = IGMP_leave_group(phead, &igrp, &temp_pfn);
      /* report only the first error, but leave the other groups anyway */
      if (tmp != RTCS_OK && status == RTCS_OK) {
         status = tmp;
      } /* Endif */
   } /* Endfor */

   return status;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_leave_socket_all
* Returned Values : error code
* Comments        :
*     leave the group on all the sockets
*
*END*-----------------------------------------------------------------*/

static uint_32 IGMP_leave_socket_all
   (
      ip_mreq _PTR_ igrp_ptr
   )
{ /* Body */
   ip_mreq              igrp;
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr = RTCS_getcfg(UDP);
   UCB_STRUCT_PTR       ucb;
   uint_32              status, tmp;

   status = RTCS_OK;

   /* copy it in the local stack to be not to removed it during the leave */
   igrp = *igrp_ptr;

   /* test all bound sockets and leave the group if needed */
   RTCS_LIST_SEARCH(UDP_cfg_ptr->BOUND_UCB_HEAD, ucb) {
      /* test if the socket has joined multicast groups */
      if (!ucb->MCB_PTR) {
         continue;
      } /* Endif */
      /* test if the socket has joined this group */
      if (IGMP_member_find(&ucb->MCB_PTR, &igrp)) {
         /* if so, leave it */
         tmp = IGMP_leave_group(&ucb->MCB_PTR, &igrp, &ucb->IGMP_LEAVEALL);
         /* report only the first error, but leave the other groups anyway */
         if (tmp != RTCS_OK && status == RTCS_OK) {
            status = tmp;
         } /* Endif */
      } /* Endif */
   } /* End SEARCH */

   RTCS_LIST_SEARCH(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb) {
      /* test if the socket has joined multicast groups */
      if (!ucb->MCB_PTR) {
         continue;
      } /* Endif */
      /* test if the socket has joined this group */
      if (IGMP_member_find(&ucb->MCB_PTR, &igrp)) {
         /* if so, leave it */
         tmp = IGMP_leave_group(&ucb->MCB_PTR, &igrp, &ucb->IGMP_LEAVEALL);
         /* report only the first error, but leave the other groups anyway */
         if (tmp != RTCS_OK && status == RTCS_OK) {
            status = tmp;
         } /* Endif */
      } /* Endif */
   } /* End SEARCH */

   /* test all open sockets and leave the group if needed */
   RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, ucb) {
      /* test if the socket has joined multicast groups */
      if (!ucb->MCB_PTR) {
         continue;
      } /* Endif */
      /* test if the socket has joined this group */
      if (IGMP_member_find(&ucb->MCB_PTR, &igrp)) {
         /* if so, leave it */
         tmp = IGMP_leave_group(&ucb->MCB_PTR, &igrp, &ucb->IGMP_LEAVEALL);
         /* report only the first error, but leave the other groups anyway */
         if (tmp != RTCS_OK && status == RTCS_OK) {
            status = tmp;
         } /* Endif */
      } /* Endif */
   } /* End SEARCH */

   return status;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_ipif_unbind
* Returned Values : error code
* Comments        :
*     unbind a address to an interface. called by IPIF_unbind.
*     leave the groups still joined on this address/interface on every socket.
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_ipif_unbind
   (
      IP_IF_PTR   ipif,        /* [IN] the interface descriptor */
      _ip_address ip_address  /* [IN] the ip address of the interface */
   )
{ /* Body */
   MC_MEMBER_PTR        member;
   MC_MEMBER_PTR _PTR_  pmember;
   ip_mreq              group;
   uint_32              status;

   status = RTCS_OK;

   /* leave the ALL_HOSTS group */
   group.imr_multiaddr.s_addr = INADDR_ALLHOSTS_GROUP;
   group.imr_interface.s_addr = ip_address;
   pmember = IGMP_member_find(&ipif->IGMP_MEMBER, &group);
   if (pmember) {
      IGMP_leave_if_local(ipif, pmember);
   } /* Endif */

   /* leave all joined groups */
   while (ipif->IGMP_MEMBER) {
      /* find a group which use this address */
      for (member = ipif->IGMP_MEMBER; member; member = member->NEXT) {
         if (member->IGRP.imr_interface.s_addr == ip_address) {
            break;
         } /* Endif */
      } /* Endfor */
      /* the interface address is no more used in a igmp group */
      if (!member) {
         break;
      } /* Endif */
      /* if it is still used, leave this group */
      status = IGMP_leave_socket_all(&member->IGRP);
      if (status != RTCS_OK) {
         return status;
      } /* Endif */
   } /* Endwhile */

   return status;
} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_sci.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_sci.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definition for the baud rate for the serial
*   channel
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"



#if MQX_ENABLE_LOW_POWER

const KUART_OPERATION_MODE_STRUCT _bsp_sci0_operation_modes[LPM_OPERATION_MODES] =
{
    /* LPM_OPERATION_MODE_RUN */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },
    /* LPM_OPERATION_MODE_WAIT */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },
    /* LPM_OPERATION_MODE_SLEEP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },
    /* LPM_OPERATION_MODE_STOP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    }
};

const KUART_OPERATION_MODE_STRUCT _bsp_sci1_operation_modes[LPM_OPERATION_MODES] =
{
    /* LPM_OPERATION_MODE_RUN */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },
    /* LPM_OPERATION_MODE_WAIT */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },
    /* LPM_OPERATION_MODE_SLEEP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },
    /* LPM_OPERATION_MODE_STOP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    }
};

const KUART_OPERATION_MODE_STRUCT _bsp_sci2_operation_modes[LPM_OPERATION_MODES] =
{
    /* LPM_OPERATION_MODE_RUN */
    {
        IO_PERIPHERAL_PIN_MUX_ENABLE | IO_PERIPHERAL_CLOCK_ENABLE | IO_PERIPHERAL_MODULE_ENABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_WAIT */
    {
        IO_PERIPHERAL_PIN_MUX_ENABLE | IO_PERIPHERAL_CLOCK_ENABLE | IO_PERIPHERAL_MODULE_ENABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_SLEEP */
    {
        IO_PERIPHERAL_PIN_MUX_ENABLE | IO_PERIPHERAL_CLOCK_ENABLE | IO_PERIPHERAL_MODULE_ENABLE | IO_PERIPHERAL_WAKEUP_ENABLE | IO_PERIPHERAL_WAKEUP_SLEEPONEXIT_DISABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_STOP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    }
};

const KUART_OPERATION_MODE_STRUCT _bsp_sci3_operation_modes[LPM_OPERATION_MODES] =
{
    /* LPM_OPERATION_MODE_RUN */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_WAIT */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_SLEEP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_STOP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    }
};


const KUART_OPERATION_MODE_STRUCT _bsp_sci4_operation_modes[LPM_OPERATION_MODES] =
{
    /* LPM_OPERATION_MODE_RUN */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_WAIT */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_SLEEP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_STOP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    }
};

const KUART_OPERATION_MODE_STRUCT _bsp_sci5_operation_modes[LPM_OPERATION_MODES] =
{
    /* LPM_OPERATION_MODE_RUN */
    {
        IO_PERIPHERAL_PIN_MUX_ENABLE | IO_PERIPHERAL_CLOCK_ENABLE | IO_PERIPHERAL_MODULE_ENABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_WAIT */
    {
        IO_PERIPHERAL_PIN_MUX_ENABLE | IO_PERIPHERAL_CLOCK_ENABLE | IO_PERIPHERAL_MODULE_ENABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_SLEEP */
    {
        IO_PERIPHERAL_PIN_MUX_ENABLE | IO_PERIPHERAL_CLOCK_ENABLE | IO_PERIPHERAL_MODULE_ENABLE | IO_PERIPHERAL_WAKEUP_ENABLE | IO_PERIPHERAL_WAKEUP_SLEEPONEXIT_DISABLE,
        0,
        0,
        0
    },

    /* LPM_OPERATION_MODE_STOP */
    {
        IO_PERIPHERAL_PIN_MUX_DISABLE | IO_PERIPHERAL_CLOCK_DISABLE,
        0,
        0,
        0
    }
};

#endif



const KUART_INIT_STRUCT _bsp_sci0_init = {
   /* queue size         */ BSPCFG_SCI0_QUEUE_SIZE,
   /* Channel            */ 0,
   /* Clock Speed        */ BSP_SYSTEM_CLOCK,       /* SCI0 operates only on system clock */
   /* Baud rate          */ BSPCFG_SCI0_BAUD_RATE,
   /* RX/TX Int vect     */ INT_UART0_RX_TX,
   /* ERR Int vect       */ INT_UART0_ERR,
   /* RX/TX priority     */ 3,
   /* ERR priority       */ 4
#if MQX_ENABLE_LOW_POWER
   ,
   /* Clock source       */ CM_CLOCK_SOURCE_CORE,
   /* LPM operation info */ _bsp_sci0_operation_modes
#endif
};

const KUART_INIT_STRUCT _bsp_sci1_init = {
   /* queue size         */ BSPCFG_SCI1_QUEUE_SIZE,
   /* Channel            */ 1,
   /* Clock Speed        */ BSP_SYSTEM_CLOCK,   	/* SCI1 operates only on system clock */
   /* Baud rate          */ BSPCFG_SCI1_BAUD_RATE,
   /* RX/TX Int vect     */ INT_UART1_RX_TX,
   /* ERR Int vect       */ INT_UART1_ERR,
   /* RX/TX priority     */ 3,
   /* ERR priority       */ 4
#if MQX_ENABLE_LOW_POWER
   ,
   /* Clock source       */ CM_CLOCK_SOURCE_CORE,
   /* LPM operation info */ _bsp_sci1_operation_modes
#endif
};

const KUART_INIT_STRUCT _bsp_sci2_init = {
   /* queue size         */ BSPCFG_SCI2_QUEUE_SIZE,
   /* Channel            */ 2,
   /* Clock Speed        */ BSP_BUS_CLOCK,       	/* SCI2 operates only on bus clock */
   /* Baud rate          */ BSPCFG_SCI2_BAUD_RATE,
   /* RX/TX Int vect     */ INT_UART2_RX_TX,
   /* ERR Int vect       */ INT_UART2_ERR,
   /* RX/TX priority     */ 3,
   /* ERR priority       */ 4
#if MQX_ENABLE_LOW_POWER
   ,
   /* Clock source       */ CM_CLOCK_SOURCE_BUS,
   /* LPM operation info */ _bsp_sci2_operation_modes
#endif
};

const KUART_INIT_STRUCT _bsp_sci3_init = {
   /* queue size         */ BSPCFG_SCI3_QUEUE_SIZE,
   /* Channel            */ 3,
   /* Clock Speed        */ BSP_BUS_CLOCK,       	/* SCI3 operates only on bus clock */
   /* Baud rate          */ BSPCFG_SCI3_BAUD_RATE,
   /* RX/TX Int vect     */ INT_UART3_RX_TX,
   /* ERR Int vect       */ INT_UART3_ERR,
   /* RX/TX priority     */ 3,
   /* ERR priority       */ 4
#if MQX_ENABLE_LOW_POWER
   ,
   /* Clock source       */ CM_CLOCK_SOURCE_BUS,
   /* LPM operation info */ _bsp_sci3_operation_modes
#endif
};

const KUART_INIT_STRUCT _bsp_sci4_init = {
   /* queue size         */ BSPCFG_SCI4_QUEUE_SIZE,
   /* Channel            */ 4,
   /* Clock Speed        */ BSP_BUS_CLOCK,       	/* SCI4 operates only on bus clock */
   /* Baud rate          */ BSPCFG_SCI4_BAUD_RATE,
   /* RX/TX Int vect     */ INT_UART4_RX_TX,
   /* ERR Int vect       */ INT_UART4_ERR,
   /* RX/TX priority     */ 3,
   /* ERR priority       */ 4
#if MQX_ENABLE_LOW_POWER
   ,
   /* Clock source       */ CM_CLOCK_SOURCE_BUS,
   /* LPM operation info */ _bsp_sci4_operation_modes
#endif
};

const KUART_INIT_STRUCT _bsp_sci5_init = {
   /* queue size         */ BSPCFG_SCI5_QUEUE_SIZE,
   /* Channel            */ 5,
   /* Clock Speed        */ BSP_BUS_CLOCK,       	/* SCI5 operates only on bus clock */
   /* Baud rate          */ BSPCFG_SCI5_BAUD_RATE,
   /* RX/TX Int vect     */ INT_UART5_RX_TX,
   /* ERR Int vect       */ INT_UART5_ERR,
   /* RX/TX priority     */ 3,
   /* ERR priority       */ 4
#if MQX_ENABLE_LOW_POWER
   ,
   /* Clock source       */ CM_CLOCK_SOURCE_BUS,
   /* LPM operation info */ _bsp_sci5_operation_modes
#endif
};

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_null/io_null.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_null.c$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the nulldisk driver functions
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_null.h"
#include "io_prv.h"
#include "ionulprv.h"


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_null_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a fdv_null driver.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_null_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr            identifier
   ) 
   
{ /* Body */
   _mqx_uint result;
   
   result = _io_dev_install(identifier,
      _io_null_open,
      _io_null_close,
      _io_null_read,
      _io_null_write,
      _io_null_ioctl,
      NULL); 

      return result;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_null_open
* Returned Value   : a null pointer
* Comments         : Opens and initializes fdv_null driver.
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_null_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR fd_ptr,
       
      /* [IN] the remaining portion of the name of the device */
      char_ptr   open_name_ptr,

      /* [IN] the flags to be used during operation:
      ** echo, translation, xon/xoff, encoded into a pointer.
      */
      char_ptr    flags
   )
{ /* Body */

   /* Nothing to do */
   return(MQX_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_null_close
* Returned Value   : ERROR CODE
* Comments         : Closes fdv_null driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_null_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */

   /* Nothing to do */
   return(MQX_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_null_read
* Returned Value   : number of characters read
* Comments         : Reads data from fdv_ram driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_null_read
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the characters are to be stored */
      char_ptr   data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int   num
   )
{ /* Body */
   return(0);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_null_write
* Returned Value   : number of characters written
* Comments         : Writes data to the fdv_ram device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_null_write
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the characters are */
      char_ptr   data_ptr,

      /* [IN] the number of characters to output */
      _mqx_int   num
   )
{ /* Body */
   return(num);
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_null_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_null_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint  cmd,

      /* [IN] the ioctl parameters */
      pointer    param_ptr
   )
{ /* Body */
     return IO_ERROR_INVALID_IOCTL_CMD;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ip.h<|end_filename|>
#ifndef __ip_h__
#define __ip_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip.h$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Definitions for the Internet protocol layer.
*
*END************************************************************************/

#include "rtcstime.h"

/***************************************
**
** Constants
**
*/

/*
** IP datagram sizes
*/

#define IP_HEADSIZE        20       /* sizeof(IP_HEADER)                 */

#define IP_DEFAULT_MTU     576      /* minimum IP datagram size which    */
                                    /* must be supported by all IP hosts */
#define IP_MAX_MTU         0xFFFF   /* size of largest IP datagram       */

/*
** default IP parameters for outgoing packets
*/
#define IP_VERSION         4        /* Version 4               */
#define IP_VERSION_4       4        /* Version 4               */
#define IP_VERSION_6       6        /* Version 6               */
/* Start CR 1899 */
#define IPTTL_DEFAULT      64       /* Time to Live (60 hops)  */
/* End CR 1899 */
#define IPTOS_DEFAULT      0        /* Type of Service         */

#define IP_HEADER_LENGTH_MASK  0x0F

#define IPTTL(ttl)         ((uint_32)(ttl) <<  8)
#define IPTOS(tos)         ((uint_32)(tos) << 16)
#define IPDF(df)           ((uint_32)(df)  << 24)

/*
**
** Ports < IPPORT_RESERVED are reserved for
**  privileged processes (e.g. root).
**
** Ports > IPPORT_USERRESERVED are reserved
**  for servers, not necessarily privileged.
*/
#define IPPORT_RESERVED          1024
#define IPPORT_USERRESERVED      5000


/***************************************
**
** Type definitions
**
*/

/*
** Multicast group members
*/

typedef struct mc_member {
   ip_mreq           IGRP;       /* the group description */
   uint_32           UCOUNT;     /* usage counter */
   struct mc_member _PTR_  NEXT;       /* pointer to the next in the list */

   /* used only by the interface part */
   TCPIP_EVENT TIMER;
   boolean     RUNNING_TIMER; /* true if the timer is running */
   boolean     LAST_REPORTER; /* true if we are the last host to report on this group */
   uint_32     UNSOLICITED_REPORT_COUNTER;   /* the number of unsolicited reports remaining to send */

   /*
   ** it's unnecessary to store a state (i.e. non-member, delaying-member, idle-member)
   ** because non-members don't have a MC_MEMBER, delaying-member is when
   ** the running_timer is true, and idle-member when running_timer is true
   */

} MC_MEMBER, _PTR_ MC_MEMBER_PTR;

/*
** Function for servicing packets
*/

typedef void (_CODE_PTR_ IP_SERVICE_FN)(RTCSPCB_PTR, pointer);

/*
** Internet Channel Block
*/
typedef struct icb_struct {

   struct icb_struct _PTR_  NEXT;          /* next ICB in the chain      */
   uint_32           PROTOCOL;      /* protocol for connection    */

   IP_SERVICE_FN     SERVICE;       /* Owner's service function    */
   pointer           PRIVATE;       /* Owner's configuration block */

} ICB_STRUCT, _PTR_ ICB_STRUCT_PTR;


/***************************************
**
** Prototypes
**
*/

extern uint_32 IP_init
(
   void
);

extern ICB_STRUCT_PTR IP_open
(
   uchar             ,     /* [IN]  Protocol to use */
   IP_SERVICE_FN     ,     /* [IN]  Packet receive function */
   pointer           ,     /* [IN]  Owner's config block */
   uint_32_ptr             /* [OUT] return code */
);

extern uint_32 IP_send
(
   RTCSPCB_PTR       ,     /* [IN] the packet to send */
   uint_32           ,     /* [IN] transport protocol, TTL and TOS */
   _ip_address       ,     /* [IN] the destination interface (0 = any) */
   _ip_address       ,     /* [IN] the ultimate destination */
   uint_32                 /* [IN] optional flags */
);

extern uint_32 IP_send_IF
(
   RTCSPCB_PTR       ,     /* [IN] the packet to send */
   uint_32           ,     /* [IN] transport protocol, TTL and TOS */
   pointer                 /* [IN] the destination interface */
);

extern void IP_service
(
   RTCSPCB_PTR             /* [IN] received packet */
);

extern _ip_address IP_source
(
   RTCSPCB_PTR             /* [IN] packet to find source of */
);

extern _ip_address IP_dest
(
   RTCSPCB_PTR             /* [IN] packet to find destination of */
);

#if RTCSCFG_ENABLE_IP6
    #include "ip6.h"
#endif


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/loadtc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: loadtc.c$
* $Version : 3.0.4.0$
* $Date    : Mar-5-2009$
*
* Comments:
*
*   This file contains the interface functions to RTCS_load()
*   for COFF files using TFTP.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_UDP

/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : RTCS_load_TFTP_COFF
* Returned Value   : RTCS_OK or error code
* Comments  :  Routine to load a bootimage from a server.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_load_TFTP_COFF
   (
      _ip_address          server,
         /* [IN] address of the TFTP server */
      char_ptr             filename
         /* [IN] file to retrieve */
   )
{ /* Body */
   TFTP_DATA_STRUCT     tftp_data;

   tftp_data.SERVER   = server;
   tftp_data.FILENAME = filename;
   tftp_data.FILEMODE = "octet";

   return RTCS_load(FT_TFTP, &tftp_data, FF_COFF, NULL, 0);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : RTCS_exec_TFTP_COFF
* Returned Value   : RTCS_OK or error code
* Comments  :  Routine to load and execute a bootimage from a server.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_exec_TFTP_COFF
   (
      _ip_address          server,
         /* [IN] address of the TFTP server */
      char_ptr             filename
         /* [IN] file to retrieve */
   )
{ /* Body */
   TFTP_DATA_STRUCT     tftp_data;

   tftp_data.SERVER   = server;
   tftp_data.FILENAME = filename;
   tftp_data.FILEMODE = "octet";

   return RTCS_load(FT_TFTP, &tftp_data, FF_COFF, NULL, RTCSLOADOPT_EXEC);

} /* Endbody */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_IntegratorTR.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_IntegratorTR.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_IntegratorTR function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GFLIB_INTEGRATOR_TR_H
#define _GFLIB_INTEGRATOR_TR_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif
     
/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GFLIB_IntegratorTRANSIC function.*/
#define GFLIB_IntegratorTR(in, pParam)  GFLIB_IntegratorTRANSIC(in, pParam)

/*! Macro containing default values of the integrator structure.*/
#define GFLIB_INTEGRATOR_TR_DEFAULT   {0,0,0,0}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_INTEGRATOR_TR_T "\GFLIB_IntegratorTR.h"

@brief  Structure containing integrator parameters and coefficients.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32 f32State;       /*!< integrator state value */
    Frac32 f32InK1;        /*!< input value in step k-1 */
    Frac32 f32C1;          /*!< integrator coefficient = \f$\frac{E_{MAX}\cdot T_s}{U_{MAX}\cdot 2} \cdot 2^{-u16NShift} \f$ */
    UWord16    u16NShift;      /*!< Scaling factor for the integrator coefficient f32C1, integer format \f$\left[0,31\right]\f$ */
}GFLIB_INTEGRATOR_TR_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*! 
* @ingroup GFLIB_GROUP 
*/

extern Frac32 GFLIB_IntegratorTRANSIC(Frac32 f32In, GFLIB_INTEGRATOR_TR_T *pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GFLIB_INTEGRATOR_TR_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/event_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: event_prv.h$
* $Version : 3.8.5.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This include file is used to define constants and data types private
*   to the event component.
*
*END************************************************************************/
#ifndef __event_prv_h__
#define __event_prv_h__ 1

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* Used to mark a block of memory as belonging to an event group */
#define EVENT_VALID                    ((_mqx_uint)(0x65766E74))   /* "evnt" */

/* Used to indicate that an event occurred */
#define EVENT_OCCURRED                 (2)
#define EVENT_WANTS_ALL                (1)

#define EVENT_MAX_WAITING_TASKS        ((uint_16)0)

/* IPC Message types for remote event access */
#define IPC_EVENT_OPEN                 (1)
#define IPC_EVENT_SET                  (2)

/*--------------------------------------------------------------------------*/
/*                      DATA STRUCTURE DEFINITIONS                          */

 
/* EVENT COMPONENT STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief This is the base structure pointed to by the kernel data structure 
 * COMPONENT field for events.
 */
typedef struct event_component_struct
{

   /*! \brief The maximum number of event instances allowed. */
   _mqx_uint        MAXIMUM_NUMBER;

   /*! \brief The number of event instances to grow by when table full. */
   _mqx_uint        GROW_NUMBER;

   /*! \brief A validation stamp allowing for checking of memory overwrite. */
   _mqx_uint        VALID;

   /*! \brief The handle to the naming table for events. */
   pointer         NAME_TABLE_HANDLE;

} EVENT_COMPONENT_STRUCT, _PTR_ EVENT_COMPONENT_STRUCT_PTR;
/*! \endcond */

/* EVENT STRUCTURE */
/*! 
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief This is the structure of an instance of an event. 
 * 
 * The address is kept in the event name table, associated with the name.
 */
typedef struct event_struct
{

   /*! 
    * \brief This is the queue of waiting tasks.
    *
    * What is queued is the address of the handle provided to the user 
    * (EVENT_COMPONENT_STRUCT).
    */
   QUEUE_STRUCT    WAITING_TASKS;

   /*! \brief This is a validation stamp for the event. */
   _mqx_uint       VALID;
   
   /*! \brief The actual event bits. */
   _mqx_uint       EVENT;

   /*! \brief Event type. */
   boolean         AUTO_CLEAR;
   
   /*! \brief The string name of the event, includes null. */
   char            NAME[NAME_MAX_NAME_SIZE];

} EVENT_STRUCT, _PTR_ EVENT_STRUCT_PTR;
/*! \endcond */

 
/* EVENT CONNECTION STRUCTURE */
/*!     
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief This is the structure whose address is returned to the user
 * as an event handle.
 */
typedef struct event_connection_struct
{
   /*! 
    * \brief Pointer to the next structure. It is used to link the connection
    * struct onto the WAITING TASK queue of the event. 
    */     
   pointer           NEXT;
   /*! 
    * \brief Pointer to the previous structure. It is used to link the connection
    * struct onto the WAITING TASK queue of the event. 
    */
   pointer           PREV;

   /*! \brief This is a validation stamp for the data structure. */
   _mqx_uint         VALID;

   /*! 
    * \brief Is this event on a remote procssor, if non-zero it is the processor 
    * number of the remote processor.
    */
   _mqx_uint         REMOTE_CPU;

   /*! \brief The bit mask of bits to wait for. */
   _mqx_uint         MASK;
   
   /*! 
    * \brief A flag indicating whether all bits are required, or whether an event 
    * has been set.
    */
   _mqx_uint         FLAGS;
   
   /*! \brief The address of the task descriptor that owns this connection. */
   TD_STRUCT_PTR     TD_PTR;

   /*! \brief The address of the event structure associated with this connection. */
   EVENT_STRUCT_PTR  EVENT_PTR;

    
} EVENT_CONNECTION_STRUCT, _PTR_ EVENT_CONNECTION_STRUCT_PTR;
/*! \endcond */

/* ANSI c prototypes */
#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern void      _event_cleanup(TD_STRUCT_PTR);
extern _mqx_uint _event_create_internal(char _PTR_, EVENT_STRUCT_PTR _PTR_);
extern _mqx_uint _event_create_fast_internal(_mqx_uint, EVENT_STRUCT_PTR _PTR_);
extern _mqx_uint _event_wait_internal(pointer, _mqx_uint, MQX_TICK_STRUCT_PTR, 
   boolean, boolean);
extern _mqx_uint _event_wait_any_internal(pointer, _mqx_uint, MQX_TICK_STRUCT_PTR, 
   boolean);  
#endif

#ifdef __cplusplus
}
#endif

#endif /* __event_prv_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi_legacy/spi.h<|end_filename|>
#ifndef __spi_h__
#define __spi_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi.h$
* $Version : 3.6.16.0$
* $Date    : Jun-22-2010$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the SPI driver
*
*END************************************************************************/

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/* 
** IOCTL calls specific to SPI 
*/
#define IO_IOCTL_SPI_GET_BAUD              _IO(IO_TYPE_SPI,0x01)
#define IO_IOCTL_SPI_SET_BAUD              _IO(IO_TYPE_SPI,0x02)
#define IO_IOCTL_SPI_GET_MODE              _IO(IO_TYPE_SPI,0x03)
#define IO_IOCTL_SPI_SET_MODE              _IO(IO_TYPE_SPI,0x04)
#define IO_IOCTL_SPI_ENABLE_MODF           _IO(IO_TYPE_SPI,0x05)
#define IO_IOCTL_SPI_DISABLE_MODF          _IO(IO_TYPE_SPI,0x06)
#define IO_IOCTL_SPI_GET_TRANSFER_MODE     _IO(IO_TYPE_SPI,0x07)
#define IO_IOCTL_SPI_SET_TRANSFER_MODE     _IO(IO_TYPE_SPI,0x08)
#define IO_IOCTL_SPI_GET_ENDIAN            _IO(IO_TYPE_SPI,0x09)
#define IO_IOCTL_SPI_SET_ENDIAN            _IO(IO_TYPE_SPI,0x0A)
#define IO_IOCTL_SPI_DEVICE_ENABLE         _IO(IO_TYPE_SPI,0x0B)
#define IO_IOCTL_SPI_DEVICE_DISABLE        _IO(IO_TYPE_SPI,0x0C)
#define IO_IOCTL_SPI_GET_FLAGS             _IO(IO_TYPE_SPI,0x0D)
#define IO_IOCTL_SPI_SET_FLAGS             _IO(IO_TYPE_SPI,0x0E)
#define IO_IOCTL_SPI_GET_STATS             _IO(IO_TYPE_SPI,0x0F)
#define IO_IOCTL_SPI_CLEAR_STATS           _IO(IO_TYPE_SPI,0x10)
#define IO_IOCTL_SPI_GET_FRAMESIZE         _IO(IO_TYPE_SPI,0x11)
#define IO_IOCTL_SPI_SET_FRAMESIZE         _IO(IO_TYPE_SPI,0x12)
#define IO_IOCTL_SPI_GET_CS                _IO(IO_TYPE_SPI,0x13)
#define IO_IOCTL_SPI_SET_CS                _IO(IO_TYPE_SPI,0x14)
#define IO_IOCTL_SPI_SET_CS_CALLBACK       _IO(IO_TYPE_SPI,0x15)
#define IO_IOCTL_SPI_READ_WRITE            _IO(IO_TYPE_SPI,0x16)
#define IO_IOCTL_SPI_FLUSH_DEASSERT_CS     _IO(IO_TYPE_SPI,0x17)
#define IO_IOCTL_SPI_KEEP_QSPI_CS_ACTIVE   _IO(IO_TYPE_SPI,0x18)

/* 
** SPI device modes of operation 
*/
#define SPI_DEVICE_MASTER_MODE             (0x00) 
#define SPI_DEVICE_SLAVE_MODE              (0x01) 
#define SPI_DEVICE_BIO_MASTER_MODE         (0x02) 
#define SPI_DEVICE_BIO_SLAVE_MODE          (0x03)

/*
** SPI data bits transferring format
*/
#define SPI_DEVICE_BIG_ENDIAN              (0x0001)
#define SPI_DEVICE_LITTLE_ENDIAN           (0x8000)

/*
** SPI clock polarity and phase
*/
#define SPI_CLK_POL_PHA_MODE0              (0x00)   /* Inactive SPICLK low & sample rising */
#define SPI_CLK_POL_PHA_MODE1              (0x01)   /* Inactive SPICLK low & sample falling */
#define SPI_CLK_POL_PHA_MODE2              (0x02)   /* Inactive SPICLK high & sample falling */
#define SPI_CLK_POL_PHA_MODE3              (0x03)   /* Inactive SPICLK high & sample rising */

/*
** SPI Open Flags
*/
#define SPI_FLAG_HALF_DUPLEX               (0 << IO_O_USER_SHIFT)
#define SPI_FLAG_FULL_DUPLEX               (1 << IO_O_USER_SHIFT)
#define SPI_FLAG_NO_DEASSERT_ON_FLUSH      (2 << IO_O_USER_SHIFT)

/* SPI Error Codes */
#define SPI_OK                             (0x00)
#define SPI_ERROR_MODE_INVALID             (SPI_ERROR_BASE | 0x01)
#define SPI_ERROR_TRANSFER_MODE_INVALID    (SPI_ERROR_BASE | 0x02)
#define SPI_ERROR_BAUD_RATE_INVALID        (SPI_ERROR_BASE | 0x03)
#define SPI_ERROR_ENDIAN_INVALID           (SPI_ERROR_BASE | 0x04)
#define SPI_ERROR_CHANNEL_INVALID          (SPI_ERROR_BASE | 0x05)
#define SPI_ERROR_DEINIT_FAILED            (SPI_ERROR_BASE | 0x06)
#define SPI_ERROR_INVALID_PARAMETER        (SPI_ERROR_BASE | 0x07)
 
/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/
 
typedef struct spi_statistics_struct 
{
   /* Number of SPI interrupts so far */
   uint_32                           INTERRUPTS;

   /* Number of valid bytes received (not dummy receives) */
   uint_32                           RX_PACKETS;

   /* Number of times data was rewritten in input HW buffer */
   uint_32                           RX_OVERFLOWS;

   /* Number of valid bytes transmitted (not dummy transmits) */
   uint_32                           TX_PACKETS;

   /* Number of master transmit aborts (master to master failure) */
   uint_32                           TX_ABORTS;

   /* Number of times data was not suplied before transfer (slave) */
   uint_32                           TX_UNDERFLOWS;
   
} SPI_STATISTICS_STRUCT, _PTR_ SPI_STATISTICS_STRUCT_PTR;
 

/*
** SPI_CS_CALLBACK
**
** This callback function is used to provide external CS handling funtionality.
*/

typedef void (_CODE_PTR_ SPI_CS_CALLBACK)(uint_32 cs_mask, uint_32 logic_level, pointer user_data);


/*
** SPI_CS_CALLBACK_STRUCT
**
** This structure defines the parameters of the external chip select callback.
*/

typedef struct spi_cs_callback_struct
{
   /* The SPI CS mask */
   uint_32          MASK;

   /* The SPI callback itself */
   SPI_CS_CALLBACK  CALLBACK;

   /* User data */
   pointer          USERDATA;

} SPI_CS_CALLBACK_STRUCT, _PTR_ SPI_CS_CALLBACK_STRUCT_PTR;


/*
** SPI_READ_WRITE_STRUCT
**
** This structure defines the parameters of the external chip select callback.
*/

typedef struct spi_read_write_struct
{
   /* Byte length of each buffer */
   uint_32          BUFFER_LENGTH;

   /* Buffer containing bytes to write */
   char_ptr         WRITE_BUFFER;

   /* Buffer containing bytes read after transfer */
   char_ptr         READ_BUFFER;

} SPI_READ_WRITE_STRUCT, _PTR_ SPI_READ_WRITE_STRUCT_PTR;
 
 
/*--------------------------------------------------------------------------*/
/* 
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif


extern _mqx_uint _io_spi_polled_install(
      char_ptr              identifier,
      _mqx_uint (_CODE_PTR_ init)(pointer, pointer _PTR_, char _PTR_),
      _mqx_uint (_CODE_PTR_ deinit)(pointer, pointer),
      _mqx_int (_CODE_PTR_ recv)(pointer, char _PTR_, _mqx_int),
      _mqx_int (_CODE_PTR_ xmit)(pointer, char _PTR_, _mqx_int),
      _mqx_int (_CODE_PTR_ ioctl)(pointer, _mqx_uint, _mqx_uint_ptr, _mqx_uint),
      pointer               init_data_ptr
      
   );

extern _mqx_uint _io_spi_int_install(
      char_ptr              identifier,
      _mqx_uint (_CODE_PTR_ init)(pointer, char _PTR_),
      _mqx_uint (_CODE_PTR_ enable_ints)(pointer),
      _mqx_uint (_CODE_PTR_ deinit)(pointer, pointer),
      _mqx_int (_CODE_PTR_ recv)(pointer, char _PTR_, _mqx_int),
      _mqx_int (_CODE_PTR_ xmit)(pointer, char _PTR_, _mqx_int),
      _mqx_int (_CODE_PTR_ ioctl)(pointer, _mqx_uint, _mqx_uint_ptr, _mqx_uint),
      pointer               init_data_ptr
      
   );


#ifdef __cplusplus
}
#endif


#endif 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/host_main.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_main.c$
* $Version : 3.8.30.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the USB Host API specific main functions.
*
*END************************************************************************/
#include <mqx.h>
#include <bsp.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_common.h"
#include "host_main.h"
#include "host_dev_list.h"

static TR_STRUCT_PTR _usb_host_new_tr_element (_usb_pipe_handle);

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_init_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_init_call_interface routine is used to initialize device
*  drivers when the USB host stack is initialized.  Device drivers may
*  perform device register, interrupt, and internal data structure
*  initialization.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_init_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle              handle
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
#ifdef USB_HOST_INCLUDE_TASK_SUPPORT
   error = _usb_rtos_host_init ();
   
   if (error != USB_OK)
   {
      return USB_log_error(__FILE__,__LINE__,error);
   }
#endif
   
   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_INIT != NULL)
   {
      error = temp_ptr->HOST_INIT (handle);
   }

#ifdef USB_HOST_INCLUDE_TASK_SUPPORT
   if (error != USB_OK)
   {
      error = _usb_rtos_host_shutdown();
   }
#endif

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_shutdown_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_shutdown_call_interface routine is used to shutdown device
*  drivers when the USB host stack is shutdown.  Device drivers may
*  perform host controller resets and/or free internal data structures.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_shutdown_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle              handle
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_SHUTDOWN != NULL)
   {
      error = temp_ptr->HOST_SHUTDOWN (handle);
   }
   
#ifdef USB_HOST_INCLUDE_TASK_SUPPORT
   if (error == USB_OK)
   {
      error = _usb_rtos_host_shutdown ();
   }
#endif

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_send_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_send_call_interface routine is used to send non-control data
*  to a USB device.  Device drivers may allocate internal data structures
*  and modify registers to initiate a bus transaction.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_send_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [IN] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr,
   
   /* [IN] Pipe transfer descriptor */
   struct tr_struct     _PTR_ tr_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_SEND != NULL)
   {
      error = temp_ptr->HOST_SEND (handle, pipe_ptr, tr_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_send_setup_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_send_setup_call_interface routine is used to send control
*  data to a USB device.  Device drivers may allocate internal data
*  structures and modify registers to initiate a bus transaction.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_send_setup_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [IN] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr,
   
   /* [IN] Pipe transfer descriptor */
   struct tr_struct     _PTR_ tr_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_SEND_SETUP != NULL)
   {
      error = temp_ptr->HOST_SEND_SETUP (handle, pipe_ptr, tr_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_recv_data_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_recv_data_call_interface routine is used to receive non-
*  control data from a USB device.  Device drivers may allocate internal
*  data structures and modify registers to initiate a bus transaction.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_recv_data_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [IN] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr,
   
   /* [IN] Pipe transfer descriptor */
   struct tr_struct     _PTR_ tr_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_RECV != NULL)
   {
      error = temp_ptr->HOST_RECV (handle, pipe_ptr, tr_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_cancel_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_cancel_call_interface routine is used to cancel pending
*  transactions.  Device drivers may update/free internal data structures
* and/or modify registers to cancel the transaction.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_cancel_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [IN] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr,
   
   /* [IN] Pipe transfer descriptor */
   struct tr_struct     _PTR_ tr_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_CANCEL != NULL)
   {
      error = temp_ptr->HOST_CANCEL (handle, pipe_ptr, tr_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_bus_control_data_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_bus_control_data_call_interface routine is used to perform
*  low-level operations on the USB bus (e.g. asserting/deasserting resume).
*  Device drivers may modify device registers to accomplish the requested
*  operation.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_bus_control_data_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle              handle,
   
   /* [IN] The operation to be performed on the bus */
   uint_8                        bcontrol
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_BUS_CONTROL != NULL)
   {
      error = temp_ptr->HOST_BUS_CONTROL (handle, bcontrol);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_alloc_bandwidth_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_alloc_bandwidth_call_interface routine is used to allocate
*  bandwidth for interrupt and isochronous transactions.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_alloc_bandwidth_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [IN] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_ALLOC_BANDWIDTH != NULL)
   {
      error = temp_ptr->HOST_ALLOC_BANDWIDTH (handle, pipe_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_close_pipe_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_close_pipe_call_interface routine is used to notify device drivers
*  when a pipe is closed.  Device drivers may reclaim internal data
*  structures allocated in _usb_host_open_pipe_call_interface when the pipe
*  was opened.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_close_pipe_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [OUT] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_FREE_CONTROLLER_RESOURCE != NULL)
   {
      error = temp_ptr->HOST_FREE_CONTROLLER_RESOURCE (handle, pipe_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_open_pipe_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_open_pipe_call_interface routine is used to notify device drivers
*  when a pipe is opened.  Device drivers may allocate internal data
*  structures and associate them with pipe descriptors for reclaimation
*  when the pipe is closed.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_open_pipe_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [OUT] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_OPEN_PIPE != NULL)
   {
      error = temp_ptr->HOST_OPEN_PIPE (handle, pipe_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_update_max_packet_size_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_update_max_packet_size_call_interface is used to notify device
*  drivers of the maximum packet size for a USB device.  Host controller
*  device drivers may update internal data structures associated with
*  open pipes on the device.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_update_max_packet_size_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [OUT] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_UPDATE_MAX_PACKET_SIZE != NULL)
   {
      error = temp_ptr->HOST_UPDATE_MAX_PACKET_SIZE (handle, pipe_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_update_device_address_call_interface
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_update_device_address_call_interface is used to notify device
*  drivers of the new device address for a USB device.  Host controller
*  device drivers may update internal data structures associated with
*  open pipes on the device.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_update_device_address_call_interface
(
   /* [IN] the USB Host state structure */
   _usb_host_handle     handle,
   
   /* [OUT] Pipe descriptor */
   struct pipe_struct   _PTR_ pipe_ptr
)
{
   USB_STATUS error = USB_OK;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR temp_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   temp_ptr = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_host_ptr->CALLBACK_STRUCT_PTR;

   if (temp_ptr->HOST_UPDATE_DEVICE_ADDRESS != NULL)
   {
      error = temp_ptr->HOST_UPDATE_DEVICE_ADDRESS (handle, pipe_ptr);
   }

   return USB_log_error(__FILE__,__LINE__,error);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_init
*  Returned Value : error or USB_OK
*  Comments       :
*        Initializes the USB hardware and installs the USB 
*  interrupt handler
*END*-----------------------------------------------------------------*/

USB_STATUS _usb_host_init
   (
      /* [IN] address if the callback functions structure */
      struct usb_host_if_struct    *usb_if,
     
      /* [OUT] the USB host handle */
      _usb_host_handle _PTR_  handle
   )
{ /* Body */
   USB_STATUS error = USB_OK;
   USB_HOST_IF_STRUCT_PTR usb_c;
   USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR host_if;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr = NULL;
   _mqx_int i;

#ifdef _HOST_DEBUG_
   DEBUG_LOG_TRACE("_usb_host_init");
#endif

   /* Check usb_if structure */
   if (usb_if == NULL) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_init no interface given");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   }
   if (usb_if->HOST_IF == NULL) {
      /* The interface does not support host functionality */
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_init interface not supporting host");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   }

   USB_lock();
   
   usb_c = _mqx_get_io_component_handle(IO_USB_COMPONENT);

   /* Check if the interface is registered */
   if (!usb_c) {
      /* No interface was registered yet */
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_init no interface registered");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   }
   else {
      /* Find out if the interface has been installed */
      for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
         if (usb_c[i].HOST_INIT_PARAM == usb_if->HOST_INIT_PARAM) {
            /* Found installed device */
            break;
         }
      }
   }

   if (i == USBCFG_MAX_DRIVERS) {
      /* The interface has not been registered, so it cannot be initialized */
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_init not installed");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   }
   else {
      /* check if the registered interface was already initialized */
      if (usb_c[i].HOST_HANDLE != NULL) {
         /* The interface was already installed- return handle and USBERR_DEVICE_BUSY value */
         *handle = (_usb_host_handle) usb_c[i].HOST_HANDLE;
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_init already initialized - returning handle");
         #endif
         return USBERR_DEVICE_BUSY;
      }
   }

   host_if = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR) usb_c[i].HOST_IF;
   /* Initialize the USB interface. */
   if (host_if->HOST_PREINIT != NULL)
   {
      error = host_if->HOST_PREINIT((_usb_host_handle _PTR_) &usb_host_ptr);
   }

   if (error != USB_OK || usb_host_ptr == NULL || usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR == NULL) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_init preinit failure");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
   } /* Endif */

   usb_host_ptr->CALLBACK_STRUCT_PTR = usb_c[i].HOST_IF;
   usb_host_ptr->INIT_PARAM = usb_c[i].HOST_INIT_PARAM;
   _mem_set_type(usb_host_ptr, MEM_TYPE_USB_HOST_STATE_STRUCT);
   _mem_set_type(usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR, MEM_TYPE_USB_HOST_PIPE_DESCRIPTORS);
   
   /* No devices attached yet */
   /*
   ** We should maintain device lists per controller handle
   */
   usb_host_ptr->DEVICE_LIST_PTR = NULL;

#if (USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS != 0)
   error = _usb_host_iso_packet_desc_pool_create(USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS);
   
   if (error != USB_OK)
   {
      USB_mem_free(usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR);
      USB_mem_free(usb_host_ptr);
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_init: isochronous packet descriptor pool allocation failure");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
   }
#endif

   error = _bsp_usb_host_init(&usb_c[i]);

   if (error != MQX_OK)
   {
#if (USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS != 0)
      _usb_host_iso_packet_desc_pool_destroy ();
#endif
      USB_mem_free(usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR);
      USB_mem_free(usb_host_ptr);
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_init: BSP-specific USB initialization failure");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_UNKNOWN_ERROR);
   }

   error = _usb_host_init_call_interface(usb_host_ptr);

   USB_unlock();
   
   if (error != USB_OK)
   {
#if (USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS != 0)
      _usb_host_iso_packet_desc_pool_destroy ();
#endif
      USB_mem_free(usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR);
      USB_mem_free(usb_host_ptr);
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_init returning error status");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   } /* Endif */
   
   usb_c[i].HOST_HANDLE = *handle = (_usb_host_handle)usb_host_ptr;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_init SUCCESSFULL");
   #endif
   return USB_OK;

} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_register_service
* Returned Value : USB_OK or error code
* Comments       :
*     Registers a callback routine for a specified event.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_host_register_service
   (
      /* [IN] Handle to the USB device */
      _usb_host_handle         handle,
      
      /* [IN] type of event or endpoint number to service */
      uint_8                   type,
      
      /* [IN] Pointer to the service's callback function */
      void(_CODE_PTR_ service)(pointer, uint_32)
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR           usb_host_ptr;
   USB_SERVICE_STRUCT_PTR              service_ptr;
   USB_SERVICE_STRUCT_PTR _PTR_        search_ptr;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_register_service");
   #endif

   /* Needs mutual exclusion */
   USB_lock();
   
   /* Search for an existing entry for type */
   for (search_ptr = &usb_host_ptr->SERVICE_HEAD_PTR;
      *search_ptr;
      search_ptr = &(*search_ptr)->NEXT) 
   {
      if ((*search_ptr)->TYPE == type) {
         /* Found an existing entry */
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_register_service USBERR_OPEN_SERVICE");
         #endif
         return USB_log_error(__FILE__,__LINE__,USBERR_OPEN_SERVICE);
      } /* Endif */
   } /* Endfor */
   
   /* No existing entry found - create a new one */
   service_ptr = (USB_SERVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(USB_SERVICE_STRUCT));
   
   if (!service_ptr) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_register_service memalloc failed");
      #endif

      return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC_SERVICE);
   } /* Endif */
   _mem_set_type(service_ptr, MEM_TYPE_USB_HOST_SERVICE_STRUCT);
   
   service_ptr->TYPE = type;
   service_ptr->SERVICE = service;
   service_ptr->NEXT = NULL;
   *search_ptr = service_ptr;
   
   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_register_service SUCCESSFUL");
   #endif
   
   return USB_OK;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_call_service
* Returned Value : USB_OK or error code
* Comments       :
*     Calls the appropriate service for the specified type, if one is
*     registered.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_host_call_service
   (
      /* [IN] Handle to the USB device */
      _usb_host_handle handle,

      /* [IN] Type of service or endpoint */
      uint_8           type,
      
      /* [IN] Number of bytes in transmission */
      uint_32          length
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR           usb_host_ptr;
   USB_SERVICE_STRUCT_PTR              service_ptr;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_call_service");
   #endif

   /* Needs mutual exclusion */
   USB_lock();
   
   /* Search for an existing entry for type */
   for (service_ptr = usb_host_ptr->SERVICE_HEAD_PTR;
      service_ptr;
      service_ptr = service_ptr->NEXT) 
   {
      if (service_ptr->TYPE == type) {
         if (service_ptr->SERVICE) {
            service_ptr->SERVICE(handle, length);
         }
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_call_service, service exists");
         #endif
         return USB_OK;
      } /* Endif */
      
   } /* Endfor */

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_call_service, service closed");
   #endif
   return USB_log_error(__FILE__,__LINE__,USBERR_CLOSED_SERVICE);
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_check_service
* Returned Value : USB_OK or error code
* Comments       :
*     Check if a service is registered or not.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_host_check_service
   (
      /* [IN] Handle to the USB device */
      _usb_host_handle handle,

      /* [IN] Type of service or endpoint */
      uint_8           type,
      
      /* [IN] Number of bytes in transmission */
      uint_32          length
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR           usb_host_ptr;
   USB_SERVICE_STRUCT_PTR              service_ptr;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   /* Needs mutual exclusion */
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_check_service");
   #endif

   USB_lock();
   
   /* Search for an existing entry for type */
   for (service_ptr = usb_host_ptr->SERVICE_HEAD_PTR;
      service_ptr;
      service_ptr = service_ptr->NEXT) 
   {
      if (service_ptr->TYPE == type) {
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_check_service service found");
         #endif

         USB_unlock();
         return USB_OK;
      } /* Endif */
   } /* Endfor */

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_check_service service closed");
   #endif

   return USB_log_error(__FILE__,__LINE__,USBERR_CLOSED_SERVICE);
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_host_unregister_service
* Returned Value : USB_OK or error code
* Comments       :
*     Unregisters a callback routine for a specified event or endpoint.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_host_unregister_service
   (
      /* [IN] Handle to the USB device */
      _usb_host_handle           handle,

      /* [IN] type of event or endpoint number to service */
      uint_8                     type
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR           usb_host_ptr;
   USB_SERVICE_STRUCT_PTR              service_ptr;
   USB_SERVICE_STRUCT_PTR _PTR_        search_ptr;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_unregister_service");
   #endif

   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   /* Needs mutual exclusion */
   USB_lock();
   
   /* Search for an existing entry for type */
   for (search_ptr = &usb_host_ptr->SERVICE_HEAD_PTR;
      *search_ptr;
      search_ptr = &(*search_ptr)->NEXT) 
   {
      if ((*search_ptr)->TYPE == type) {
         /* Found an existing entry - delete it */
         break;
      } /* Endif */
   } /* Endfor */
   
   /* No existing entry found */
   if (!*search_ptr) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_unregister_service no service found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_CLOSED_SERVICE);
   } /* Endif */
   
   service_ptr = *search_ptr;
   *search_ptr = service_ptr->NEXT;

   USB_unlock();
   
   USB_mem_free((pointer)service_ptr);
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_unregister_service SUCCESSFUL");
   #endif
   return USB_OK;

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_open_pipe
*  Returned Value : USB_OK or error
*  Comments       :
*  _usb_host_open_pipe routine initializes a new pipe descriptor and 
*  returns USB_OK or error and the pipe descriptor for the USB bus address, 
*  endpoint number, direction of transfer, maximum packet size, interval 
*  and the type of pipe
*
*END*-----------------------------------------------------------------*/

static void _usb_host_open_pipe_cleanup(_usb_host_handle, PIPE_STRUCT_PTR, boolean);
static void _usb_host_open_pipe_cleanup(
         /* [IN] the USB Host state structure */
      _usb_host_handle           handle,
      
      PIPE_STRUCT_PTR            pipe_ptr,
      
      boolean                    close_pipe_call
   )
{ /* Body */
   TR_STRUCT_PTR  temp;
   
   if (close_pipe_call) {
      _usb_host_close_pipe_call_interface (handle, pipe_ptr);
   }
   
   while  (pipe_ptr->tr_list_ptr != NULL) {
      temp = pipe_ptr->tr_list_ptr;
      pipe_ptr->tr_list_ptr = pipe_ptr->tr_list_ptr->NEXT;
      USB_mem_free((pointer)temp);
   }
   pipe_ptr->OPEN = FALSE;

   #ifdef _HOST_DEBUG_
   if (close_pipe_call) {
      DEBUG_LOG_TRACE("_usb_host_open_pipe bandwidth alloc failed");
   } else {
      DEBUG_LOG_TRACE("_usb_host_open_pipe callback failed");
   }
   #endif
}

USB_STATUS _usb_host_open_pipe
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle              handle,
      
      /* [IN] Pipe initialization parameters */
      PIPE_INIT_PARAM_STRUCT_PTR    pipe_init_params_ptr,

      /* [OUT] Pipe handle */
      _usb_pipe_handle _PTR_        pipe_handle
   )
{ /* Body */
   PIPE_STRUCT_PTR            pipe_ptr, pipe_bkp_ptr;
   PIPE_INIT_PARAM_STRUCT_PTR pipe_as_params;
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
   USB_STATUS                 error;
   _mqx_uint                  i = 0;
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_open_pipe");
   #endif
   USB_lock();

   for (pipe_ptr = usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR; pipe_ptr != NULL; pipe_ptr = pipe_ptr->NEXT) {
      /* Check if a pipe is not open */
      if (!pipe_ptr->OPEN) {
         break;
      } /* Endif */
      i++;
   } /* Endfor */

   USB_unlock();

   if (pipe_ptr == NULL) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_open_pipe failed");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_OPEN_PIPE_FAILED);
   }
   
   pipe_bkp_ptr = pipe_ptr->NEXT;
   pipe_as_params = (PIPE_INIT_PARAM_STRUCT_PTR)pipe_ptr;
   
   /* copy identical fields params --> descriptor */
   *pipe_as_params = *pipe_init_params_ptr;
   /* restore original NEXT field */
   pipe_as_params->G.NEXT = pipe_bkp_ptr;
   /* additional fields following identical header */
   pipe_as_params->G.NEXTDATA01 = 0;       /* Start DTC at Data0 */
   pipe_as_params->G.PIPE_ID = (int_16)i;
   pipe_as_params->G.OPEN = TRUE;

   pipe_as_params->G.HUB_DEVICE_ADDR = pipe_init_params_ptr->G.HUB_DEVICE_ADDR;
   pipe_as_params->G.HUB_PORT_NUM= pipe_init_params_ptr->G.HUB_PORT_NUM;
   error = _usb_host_open_pipe_call_interface (handle, pipe_ptr);
   
   if (error != USB_OK) {
      _usb_host_open_pipe_cleanup(handle, pipe_ptr, FALSE);
      return USB_log_error(__FILE__,__LINE__,USBERR_OPEN_PIPE_FAILED);
   }
   else {
       *pipe_handle = (pointer)pipe_ptr;
   }

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_open_pipe SUCCESSFUL");
   #endif

   return USB_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_new_tr_element
*  Returned Value : pointer to new host tr struct, NULL if error
*  Comments       :
*         This function will allocate and link a new TR element in the 
*  list of TRs for the specified pipe. It is assumed the caller has issued 
*  USB_lock() before entry.
*
*END*-----------------------------------------------------------------*/
static TR_STRUCT_PTR _usb_host_new_tr_element
   (
      /* [IN] the pipe handle */
      _usb_pipe_handle  pipe_handle
   )
{ /* Body */

   PIPE_STRUCT_PTR     pipe_ptr = (PIPE_STRUCT_PTR) pipe_handle;
   DEV_INSTANCE_PTR    dev_ptr = (DEV_INSTANCE_PTR) pipe_ptr->DEV_INSTANCE;
   USB_HOST_STATE_STRUCT_PTR host_ptr = (USB_HOST_STATE_STRUCT_PTR) dev_ptr->host;

   TR_STRUCT_PTR       tr_ptr, temp_tr_ptr;
   

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_new_tr_element");
   #endif

   if (pipe_ptr->PIPETYPE != USB_CONTROL_PIPE) {
      /* TODO: if not control pipe, then the setup packet is not needed to allocate here */
      tr_ptr = (TR_STRUCT_PTR)USB_mem_alloc_zero(host_ptr->TR_SIZE);
   }
   else {
      /* Contains the setup packet which should not be cached */
      tr_ptr = (TR_STRUCT_PTR)USB_mem_alloc_uncached_zero(host_ptr->TR_SIZE);
   }

   if (tr_ptr == NULL)
   {
      #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_new_tr_element malloc failed");
      #endif
      return NULL;
   }
   _mem_set_type(tr_ptr, MEM_TYPE_USB_HOST_PIPE_TR_STRUCT);

   /* Link pipe's TR structs in circular list of 1 or more items,
   ** where the pipe descriptor's tr list pointer holds the
   ** address of the next struct for scheduling (i.e. the
   ** "beginning" of the list).  
   */
   temp_tr_ptr = pipe_ptr->tr_list_ptr;

   if (temp_tr_ptr == NULL) { 
      /* No existing items, make a circle of one */
      pipe_ptr->tr_list_ptr = tr_ptr->NEXT = tr_ptr;
   } else {
      /* Add new item to the "end" of the existing list */
      while (temp_tr_ptr->NEXT != pipe_ptr->tr_list_ptr)
         temp_tr_ptr = temp_tr_ptr->NEXT;

      temp_tr_ptr->NEXT = tr_ptr;  
      tr_ptr->NEXT = pipe_ptr->tr_list_ptr;
   } /* EndIf */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_new_tr_element SUCCESSFUL");
   #endif
   return tr_ptr;

} /* Endbody */
 

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_get_tr_element
*  Returned Value : pointer to host's pipe TR struct, NULL if error
*  Comments       :
*     If the tr_index is zero or exists on the list, returns NULL
*     Otherwise initializes to zero a TR element with all linkages,
*       and sets its tr_index to the parameter value.  If no unused
*       tr_struct exists on the list (i.e. none has tr_index = 0),
*       a new struct is allocated and linked into the circular list.
*
*END*-----------------------------------------------------------------*/
TR_STRUCT_PTR _usb_host_get_tr_element
   (
      /* [IN] the pipe handle */
      _usb_pipe_handle  pipe_handle,

      /* [IN] transfer parameters */
      uint_32           tr_index
   )
{ /* Body */
   PIPE_STRUCT_PTR pipe_ptr;
   TR_STRUCT_PTR   tr_list, temp_tr_list;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_get_tr_element");
   #endif

   if (tr_index == 0)
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_get_tr_element error null tr_index");
      #endif
      return NULL;   /* zero is unused-TR flag */
   }

   pipe_ptr = (PIPE_STRUCT_PTR)pipe_handle;
   tr_list = pipe_ptr->tr_list_ptr;

   USB_lock();
   if (tr_list == NULL)  {  /* No list exists, start one */
      tr_list = _usb_host_new_tr_element(pipe_handle);
      if (tr_list == NULL) {
         USB_unlock();
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_host_get_tr_element error null pipe tr_list");
         #endif
         return NULL;
      } /* Endif */
   } else {  /* scan for unused TR's, and for index already in list */
      temp_tr_list = tr_list;
      for (; ;) {
         /* TR index is either unused, or */
         if (temp_tr_list->TR_INDEX == 0) {
            tr_list = temp_tr_list;
            break;
         } /* Endif */
         /* TR index is a duplicate (= error), or */
         if (temp_tr_list->TR_INDEX == tr_index) {
            USB_unlock();
            #ifdef _HOST_DEBUG_
               DEBUG_LOG_TRACE("_usb_host_get_tr_element error duplicate tr_index");
            #endif
            return NULL;
         } /* Endif */
         /* TR is last in list, so insert a new one, or */
         if (temp_tr_list->NEXT == tr_list) {
            tr_list = _usb_host_new_tr_element(pipe_handle);
         
            if (tr_list == NULL)
            {
               USB_unlock();
               #ifdef _HOST_DEBUG_
                  DEBUG_LOG_TRACE("_usb_host_new_tr_element FAILED");
               #endif
               return NULL;
            }
            
            break;
         } /* Endif */

         /* Step over item to next on the list */
         temp_tr_list = temp_tr_list->NEXT;

      } /* EndFor */
   } /* EndIf */
   tr_list->TR_INDEX = tr_index;  /* mark this TR busy */
   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_get_tr_element SUCCESSFUL");
   #endif
   return tr_list;   

} /* Endbody */
 
 
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_set_up_tr
*  Returned Value :
*     USBERR_INVALID_PIPE_HANDLE if the pipe is invalid
*     USBERR_ALLOC if unable to get a new TR
*     USB_STATUS_TRANSFER_QUEUED upon success
*
*  Comments       :
*     Sets up a TR from init parameters.
*
*END*-----------------------------------------------------------------*/
USB_STATUS  _usb_host_set_up_tr
   (
      /* [IN] the pipe handle */
      _usb_pipe_handle           pipe_handle,

      /* [IN] transfer parameters */
      TR_INIT_PARAM_STRUCT_PTR   tr_params_ptr,

      /* [OUT] the TR address on the pipe's TR list */
      TR_STRUCT_PTR _PTR_        tr_ptr_ptr
   )
{ /* Body */
   PIPE_STRUCT_PTR pipe_ptr;
   TR_STRUCT_PTR   pipe_tr_ptr;
   TR_STRUCT_PTR   tr_ptr;

   pipe_ptr = (PIPE_STRUCT_PTR)pipe_handle;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_set_up_tr");
   #endif

   /* Check if the pipe id is valid */
   if (pipe_ptr->PIPE_ID > USBCFG_MAX_PIPES) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_set_up_tr Invalid pipe handle");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_PIPE_HANDLE);
   } /* Endif */

   pipe_tr_ptr = _usb_host_get_tr_element(pipe_handle, tr_params_ptr->G.TR_INDEX);

   if (pipe_tr_ptr == NULL) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_set_up_tr NULL pipe handle");
      #endif

      return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC);
   } /* Endif */

   /* Backup original link */
   tr_ptr = pipe_tr_ptr->NEXT;
   /* Copy user-provided TR to system-linked TR */
   *pipe_tr_ptr = tr_params_ptr->G;
   /* Restore original link */
   pipe_tr_ptr->NEXT = tr_ptr;

   /* If TR's setup packet pointer is non-null, copy the packet */
   if (tr_params_ptr->DEV_REQ_PTR != NULL) {
      pipe_tr_ptr->setup_packet = *((USB_SETUP_PTR)tr_params_ptr->DEV_REQ_PTR);
   } /* Endif */

   /* return successful transfer initiation status */
   pipe_tr_ptr->STATUS = USB_STATUS_TRANSFER_QUEUED;
   *tr_ptr_ptr = pipe_tr_ptr;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_set_up_tr SUCCESSFUL");
   #endif

   return USB_STATUS_TRANSFER_QUEUED;

} /* EndBody */
 
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_get_transfer_status
*  Returned Value : Status
*  Comments       :
* _usb_host_get_transfer_status is a routine that returns status of a transfer. 
*
*END*-----------------------------------------------------------------*/
uint_32 _usb_host_get_transfer_status
   (
      /* [IN] the pipe handle */
      _usb_pipe_handle     pipe_handle,

      /* [IN] the transfer number */
      uint_32              tr_number
   )
{ /* Body */
   PIPE_STRUCT_PTR            pipe_ptr;
   TR_STRUCT_PTR              tr_list_ptr;
   uint_32                    status = USB_log_error(__FILE__,__LINE__,USBERR_INVALID_PIPE_HANDLE);

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_get_transfer_status");
   #endif
      
   USB_lock();

   pipe_ptr = (PIPE_STRUCT_PTR)pipe_handle;
   if (pipe_ptr!= NULL) {
      tr_list_ptr = pipe_ptr->tr_list_ptr;
      if (tr_list_ptr != NULL) {
         do {
            if (tr_list_ptr->TR_INDEX == tr_number) {
               status = tr_list_ptr->STATUS;
               break;
            } /* Endif */
            tr_list_ptr = tr_list_ptr->NEXT;   
         } while (tr_list_ptr != pipe_ptr->tr_list_ptr);
      } /* Endif */
      if (tr_list_ptr->TR_INDEX != tr_number) {
         /* Transaction done */
         status = USB_STATUS_IDLE;
      } /* Endif */
   } /* Endif */
   
   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_get_transfer_status SUCCESSFUL");
   #endif

   return status;
} /* Endbody */
  
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/common/usb_framework.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_framework.c$
* $Version : 3.8.6.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
* @brief The file contains USB stack framework module implimentation.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_class.h"
#include "usb_framework.h"
/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/
#define MAX_EXPECTED_CONTROL_OUT_SIZE       (76 + USB_SETUP_PKT_SIZE) 

/****************************************************************************
 * Global Variables
 ****************************************************************************/
 USB_CLASS_FW_OBJECT_STRUCT_PTR  usb_class_fw_object[USB_MAX_CLASS_FW_OBJECT];
 
#ifdef DELAYED_PROCESSING
    USB_EVENT_STRUCT g_f_event;
    boolean g_control_pending=FALSE;
#endif

boolean g_validate_request[MAX_STRD_REQ][3] = 
{ 
  TRUE,TRUE,FALSE, /*USB_Strd_Req_Get_Status*/
         /* configured state: valid for existing interfaces/endpoints
            address state   : valid only for interface or endpoint 0
            default state   : not specified
         */ 
  TRUE,TRUE,FALSE, /* Clear Feature */
         /* configured state: valid only for device in configured state
            address state   : valid only for device (in address state), 
                              interface and endpoint 0 
            default state   : not specified
         */
  FALSE,FALSE,FALSE, /*reserved for future use*/
         /* configured state: request not supported
            address state   : request not supported
            default state   : request not supported
         */ 
  TRUE,TRUE,FALSE, /* Set Feature */
        /*  configured state: valid only for device in configured state
            address state   : valid only for interface or endpoint 0
            default state   : not specified
        */ 
  FALSE,FALSE,FALSE,/*reserved for future use*/
        /*  configured state: request not supported            
            address state   : request not supported
            default state   : request not supported
         */ 
  FALSE,TRUE,TRUE, /*USB_Strd_Req_Set_Address*/
        /*  configured state: not specified            
            address state   : changes to default state if specified addr == 0,
                              but uses newly specified address
            default state   : changes to address state if specified addr != 0
         */
  TRUE,TRUE,TRUE, /*USB_Strd_Req_Get_Descriptor*/
         /* configured state: valid request            
            address state   : valid request
            default state   : valid request
         */
  FALSE,FALSE,FALSE, /*Set Descriptor*/
         /* configured state: request not supported
            address state   : request not supported
            default state   : request not supported
         */
  TRUE,TRUE,FALSE, /*USB_Strd_Req_Get_Config*/
         /* configured state: bConfiguration Value of current config returned
            address state   : value zero must be returned
            default state   : not specified            
         */
  TRUE,TRUE,FALSE, /*USB_Strd_Req_Set_Config*/
         /* configured state: If the specified configuration value is zero, 
                              then the device enters the Address state.If the 
                              specified configuration value matches the 
                              configuration value from a config descriptor, 
                              then that config is selected and the device
                              remains in the Configured state. Otherwise, the 
                              device responds with a Request Error.
         
            address state   : If the specified configuration value is zero, 
                              then the device remains in the Address state. If 
                              the specified configuration value matches the 
                              configuration value from a configuration 
                              descriptor, then that configuration is selected 
                              and the device enters the Configured state. 
                              Otherwise,response is Request Error.
            default state   : not specified
         */
  TRUE,FALSE,FALSE, /*USB_Strd_Req_Get_Interface*/
         /* configured state: valid request          
            address state   : request error
            default state   : not specified
         */
  TRUE,FALSE,FALSE, /*USB_Strd_Req_Set_Interface*/
         /* configured state: valid request
            address state   : request error
            default state   : not specified
         */
  TRUE,FALSE,FALSE /*USB_Strd_Req_Sync_Frame*/
         /* configured state: valid request
            address state   : request error
            default state   : not specified
         */ 
};
            
/****************************************************************************
 * Global Functions
 ****************************************************************************/

/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions
 *****************************************************************************/
USB_CLASS_FW_HANDLE USB_Framework_Init( _usb_device_handle handle, /*[IN]*/
										USB_CLASS_CALLBACK class_callback,/*[IN]*/
										USB_REQ_FUNC other_req_callback,/*[IN]*/
										pointer callback_data,/*[IN]*/
										int_32 data,/*[IN]*/
										DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr /*[IN]*/);
uint_8 USB_Framework_Deinit( _usb_device_handle handle, /*[IN]*/
						   USB_CLASS_FW_HANDLE fw_handle /*[IN]*/); 
uint_8 USB_Framework_Reset(_usb_device_handle handle);
void USB_Control_Service (PTR_USB_EVENT_STRUCT event,pointer arg );
void USB_Control_Service_Handler( USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                                  uint_8 error,
                                  USB_SETUP_STRUCT * setup_packet, 
                                  uint_8_ptr *data, 
                                  uint_32 *size);
                              
uint_8 USB_Strd_Req_Get_Status(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                               USB_SETUP_STRUCT * setup_packet,
                               uint_8_ptr *data, 
                               uint_32 *size);
uint_8 USB_Strd_Req_Feature(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                            USB_SETUP_STRUCT * setup_packet, 
                            uint_8_ptr *data, 
                            uint_32 *size);
uint_8 USB_Strd_Req_Set_Address(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                                USB_SETUP_STRUCT * setup_packet,
                                uint_8_ptr *data, 
                                uint_32 *size);
uint_8 USB_Strd_Req_Assign_Address(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr);
uint_8 USB_Strd_Req_Get_Config(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                               USB_SETUP_STRUCT * setup_packet, 
                               uint_8_ptr *data, 
                               uint_32 *size);
uint_8 USB_Strd_Req_Set_Config(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                               USB_SETUP_STRUCT * setup_packet, 
                               uint_8_ptr *data, 
                               uint_32 *size);
uint_8 USB_Strd_Req_Get_Interface(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                                  USB_SETUP_STRUCT * setup_packet, 
                                  uint_8_ptr *data, 
                                  uint_32 *size);
uint_8 USB_Strd_Req_Set_Interface(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                                  USB_SETUP_STRUCT * setup_packet, 
                                  uint_8_ptr *data, 
                                  uint_32 *size);
uint_8 USB_Strd_Req_Sync_Frame(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                               USB_SETUP_STRUCT * setup_packet, 
                               uint_8_ptr *data, 
                               uint_32 *size);
uint_8 USB_Strd_Req_Get_Descriptor(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                                   USB_SETUP_STRUCT * setup_packet, 
                                   uint_8_ptr *data, 
                                   uint_32 *size);

#ifdef DELAYED_PROCESSING
    void USB_Control_Service_Callback( PTR_USB_EVENT_STRUCT event,pointer arg );
#endif
/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
                                  
/*****************************************************************************
 * Local Variables 
 *****************************************************************************/

/*****************************************************************************
 * Global Functions
 *****************************************************************************/
 USB_FW_REQ_FUNC g_standard_request[MAX_STRD_REQ] = 
 { 
    USB_Strd_Req_Get_Status,
    USB_Strd_Req_Feature,
    NULL,
    USB_Strd_Req_Feature,
    NULL,
    USB_Strd_Req_Set_Address,
    USB_Strd_Req_Get_Descriptor,
    NULL,
    USB_Strd_Req_Get_Config,
    USB_Strd_Req_Set_Config,
    USB_Strd_Req_Get_Interface,
    USB_Strd_Req_Set_Interface,
    USB_Strd_Req_Sync_Frame
 };
 
  /*************************************************************************//*!
 *
 * @name  USB_Class_Allocate_Handle
 *
 * @brief The funtion reserves entry in device array and returns the index.
 *
 * @param none.
 * @return returns the reserved handle or if no entry found device busy.      
 *
 *****************************************************************************/
static USB_STATUS  USB_Class_Fw_Allocate_Handle(USB_CLASS_FW_HANDLE *handle)
{
    uint_32 cnt = 0;
    for (;cnt< USB_MAX_CLASS_FW_OBJECT;cnt++)
    {
       if (usb_class_fw_object[cnt] == NULL)
       {
          *handle = cnt;
          return USB_OK;
       }
    }
    return USBERR_DEVICE_BUSY;
}

 /*************************************************************************//*!
 *
 * @name  USB_Class_Free_Handle
 *
 * @brief The funtion releases entry in device array .
 *
 * @param handle  index in device array to be released..
 * @return returns and error code or USB_OK.      
 *
 *****************************************************************************/

static int_32 USB_Class_Fw_Free_Handle(USB_CLASS_FW_HANDLE handle)
{
    if (handle > USB_MAX_CLASS_FW_OBJECT)
        return USBERR_ERROR;
    
    USB_mem_free((void *)usb_class_fw_object[handle]);
    usb_class_fw_object[handle] = NULL;
    return USB_OK;
}
 /*************************************************************************//*!
 *
 * @name  Get_Usb_Class_Fw_Object_Ptr
 *
 * @brief The funtion gets the class object pointer from class array .
 *
 * @param handle  index in class object array.
 * @return returns returns pointer to USB Class FW Object structure..      
 *
 *****************************************************************************/
static USB_CLASS_FW_OBJECT_STRUCT_PTR Get_Usb_Class_Fw_Object_Ptr
(
   USB_CLASS_FW_HANDLE handle
)
{
     return usb_class_fw_object[handle]; 
}

/**************************************************************************//*!
 *
 * @name  USB_Framework_Init
 *
 * @brief The funtion initializes the Class Module 
 *
 * @param handle :              handle to Identify the controller
 * @param class_callback:       event callback 
 * @param other_req_callback:   callback for vendor or usb framework class req    
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
USB_CLASS_FW_HANDLE USB_Framework_Init
(
    _usb_device_handle handle, /*[IN]*/
    USB_CLASS_CALLBACK class_callback,/*[IN]*/
    USB_REQ_FUNC other_req_callback,/*[IN]*/
    pointer callback_data,/*[IN]*/
    int_32 data,/*[IN]*/
    DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr /*[IN]*/
        
) 
{   
    USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr = NULL;
    USB_CLASS_FW_HANDLE fw_handle;
    uint_8 error=USB_OK;
    
    usb_fw_ptr = (USB_CLASS_FW_OBJECT_STRUCT_PTR)USB_mem_alloc_zero(
        sizeof(USB_CLASS_FW_OBJECT_STRUCT));
    if (NULL == usb_fw_ptr)
    {
        #ifdef _DEV_DEBUG
            printf("USB_Framework_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }

     if (USBERR_DEVICE_BUSY == USB_Class_Fw_Allocate_Handle(&fw_handle))
     {
        USB_mem_free((void *)usb_fw_ptr);
        usb_fw_ptr = NULL;
        return USBERR_ERROR;
     }
    /* save input parameters */
    
    usb_fw_ptr->class_handle = data;
    usb_fw_ptr->ext_req_to_host = NULL;

    /* reserve memory for setup token and data received */
    usb_fw_ptr->ext_req_to_host = (uint_8*)USB_mem_alloc_zero(MAX_EXPECTED_CONTROL_OUT_SIZE);
    if (NULL == usb_fw_ptr->ext_req_to_host)
    {
        #ifdef _DEV_DEBUG
            printf("ext_req_to_host malloc failed: USB_Framework_Init\n");
        #endif  
        return USBERR_ALLOC;
    }

    usb_fw_ptr->controller_handle = handle;
    usb_fw_ptr->other_req_callback.callback = other_req_callback;
    usb_fw_ptr->other_req_callback.arg = callback_data;
    usb_fw_ptr->class_callback.callback = class_callback;
    usb_fw_ptr->class_callback.arg = callback_data;
    USB_mem_copy( desc_callback_ptr,&usb_fw_ptr->desc,
    sizeof(DESC_CALLBACK_FUNCTIONS_STRUCT));
   
    /* Register CONTROL service */      
    error = _usb_device_register_service(handle, USB_SERVICE_EP0, 

#ifdef DELAYED_PROCESSING    
                                                 USB_Control_Service_Callback,
#else
                                                          USB_Control_Service,
#endif                                                          
     (pointer)usb_fw_ptr );
     
    usb_class_fw_object[fw_handle] = usb_fw_ptr;
    return fw_handle;     
}

/**************************************************************************//*!
 *
 * @name  USB_Framework_Deinit
 *
 * @brief The funtion deinitializes the Class Module 
 *
 * @param handle :              handle to Identify the controller
 * @param fw_handle:       		Framework handle     
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Framework_Deinit
(
    _usb_device_handle handle, /*[IN]*/
    USB_CLASS_FW_HANDLE fw_handle /*[IN]*/
        
) 
{   
    USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr = NULL;
    uint_8 error = USB_OK;
    usb_fw_ptr = Get_Usb_Class_Fw_Object_Ptr(fw_handle);
    USB_mem_free((void *)(usb_fw_ptr->ext_req_to_host));
    error = _usb_device_unregister_service(handle, USB_SERVICE_EP0);
    USB_Class_Fw_Free_Handle(fw_handle);   
    return error;
}
#ifdef DELAYED_PROCESSING
/**************************************************************************//*!
 *
 * @name  USB_Framework_Periodic_Task
 *
 * @brief The funtion is called to respond to any control request
 *
 * @param None
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Framework_Periodic_Task(void)
{
    /* if control request pending to be completed */
    if(g_control_pending==TRUE) 
    {   /* handle pending control request */
        USB_Control_Service(&g_f_event);       
        g_control_pending=FALSE;
    }
} 
#endif
/**************************************************************************//*!
 *
 * @name  USB_Framework_Reset
 *
 * @brief The funtion resets the framework 
 *
 * @param handle: handle to Identify the controller
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Framework_Reset(_usb_device_handle handle)
{ 
    UNUSED_ARGUMENT(handle)
    return USB_OK; 
}

#ifdef DELAYED_PROCESSING
/**************************************************************************//*!
 *
 * @name  USB_Control_Service_Callback
 *
 * @brief The funtion can be used as a callback function to the service. 
 *
 * @param event:              from Service callback function
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Control_Service_Callback(PTR_USB_EVENT_STRUCT event,pointer arg ) 
{
    UNUSED_ARGUMENT(arg)
    /* save the event parameters */
    g_f_event.buffer_ptr = event->buffer_ptr;
    g_f_event.handle = event->handle; 
    g_f_event.ep_num = event->ep_num;
    g_f_event.setup  = event->setup;
    g_f_event.len = event->len;
    g_f_event.errors = event->errors;
    
    /* set the pending request flag */
    g_control_pending=TRUE;             
}
#endif

/**************************************************************************//*!
 *
 * @name  USB_Control_Service
 *
 * @brief Called upon a completed endpoint 0 (USB 1.1 Chapter 9) transfer 
 *
 * @param event:        from Service callback function
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Control_Service (PTR_USB_EVENT_STRUCT event,pointer arg )
{        
    uint_16    device_state = 0;
    uint_8     error = USBERR_INVALID_REQ_TYPE;
    uint_8_ptr data = NULL;
    uint_32 size; 
    USB_CLASS_FW_OBJECT_STRUCT_PTR    usb_fw_ptr;

    usb_fw_ptr = (USB_CLASS_FW_OBJECT_STRUCT_PTR)arg;
    
    /* get the device state  */
    (void)_usb_device_get_status(event->handle, (uint_8)USB_STATUS_DEVICE_STATE,
        &device_state);

    if (event->setup == TRUE) 
    {
        USB_mem_copy(event->buffer_ptr,&usb_fw_ptr->setup_packet,
        USB_SETUP_PKT_SIZE);        
        
        /* take care of endianess  of the 16 bit fields correctly */
        usb_fw_ptr->setup_packet.index = SHORT_LE_TO_HOST(usb_fw_ptr->setup_packet.index);
        usb_fw_ptr->setup_packet.value = SHORT_LE_TO_HOST(usb_fw_ptr->setup_packet.value);
        usb_fw_ptr->setup_packet.length = SHORT_LE_TO_HOST(usb_fw_ptr->setup_packet.length);
        /* if the request is standard request */
        if ((usb_fw_ptr->setup_packet.request_type & USB_REQUEST_CLASS_MASK) == 
            USB_REQUEST_CLASS_STRD) 
        {
            /* if callback is not NULL */
            if (g_standard_request[usb_fw_ptr->setup_packet.request] != NULL) 
            {
                /* if the request is valid in this device state */
                if((device_state < USB_STATE_POWERED) && 
                    (g_validate_request[usb_fw_ptr->setup_packet.request][device_state] 
                        ==TRUE)) 
                {                   
                    /* Standard Request function pointers */
                    error = g_standard_request[usb_fw_ptr->setup_packet.request]
                        (usb_fw_ptr,&usb_fw_ptr->setup_packet,&data,&size);
                }
            }
        }
        else /* for Class/Vendor requests */
        {  
            /*get the length from the setup_request*/
            size = usb_fw_ptr->setup_packet.length;

            if( (size != 0) && 
                ((usb_fw_ptr->setup_packet.request_type & USB_DATA_DIREC_MASK) == 
                    USB_DATA_TO_DEVICE))
            {                 
                /* we have gone for one time meory allocation of ext_req_to_host
                   to avoid memory fragmentation, as there was memory crunch in 
                   some of our Socs. */                                
                if((size + USB_SETUP_PKT_SIZE) > MAX_EXPECTED_CONTROL_OUT_SIZE)
                {
                    #ifdef _DEV_DEBUG
                        printf("MAX_EXPECTED_CONTROL_OUT_SIZE insufficient, needed %d\n", size + USB_SETUP_PKT_SIZE);
                        printf("Please change the macro!!!\n");
                    #endif  
                    return;
                }

                /* copy setup token to ext_req_to_host */
                USB_mem_copy(&usb_fw_ptr->setup_packet, usb_fw_ptr->ext_req_to_host, USB_SETUP_PKT_SIZE);
                #if PSP_HAS_DATA_CACHE
                   /* Workaround: the following call will do invalidate of cache lines. Since the last operation did a memory copy,
                   ** the copied bytes will be invalidated. To prevent that, do first flushing.
                   */
                    USB_dcache_flush_mlines(usb_fw_ptr->ext_req_to_host, USB_SETUP_PKT_SIZE);
                #endif
                /* expecting host to send data (OUT TRANSACTION)*/
                (void)_usb_device_recv_data(event->handle, 
                    USB_CONTROL_ENDPOINT,(usb_fw_ptr->ext_req_to_host + USB_SETUP_PKT_SIZE),
                        (uint_32)(size));
                return;                   
            }
            /*call class/vendor request*/
            else if(usb_fw_ptr->other_req_callback.callback != NULL)
            {            
                error = usb_fw_ptr->other_req_callback.callback(
                &usb_fw_ptr->setup_packet,&data,&size,usb_fw_ptr->other_req_callback.arg);
            }
        } 
        USB_Control_Service_Handler(usb_fw_ptr,error,&usb_fw_ptr->setup_packet,
            &data,&size);
    } 
    else if(device_state == USB_STATE_PENDING_ADDRESS)
    {   /* Device state is PENDING_ADDRESS */
        /* Assign the new adddress to the Device */
        (void)USB_Strd_Req_Assign_Address(usb_fw_ptr);
    }
    else if( ((usb_fw_ptr->setup_packet.request_type & USB_DATA_DIREC_MASK)==
              USB_DATA_TO_DEVICE) && (event->direction == USB_RECV) && 
              (usb_fw_ptr->setup_packet.length))
    {           
        /* execution enters Control Service because of 
           OUT transaction on USB_CONTROL_ENDPOINT*/
        if(usb_fw_ptr->other_req_callback.callback != NULL) 
        {   /* class or vendor request */
            size = event->len+USB_SETUP_PKT_SIZE;
            error = usb_fw_ptr->other_req_callback.callback(
            (USB_SETUP_STRUCT*) usb_fw_ptr->ext_req_to_host,
             &data,&size,usb_fw_ptr->other_req_callback.arg); 
        }
        USB_Control_Service_Handler(usb_fw_ptr,error,&usb_fw_ptr->setup_packet,
            &data,&size);
    }    
    return; 
}           

/**************************************************************************//*!
 *
 * @name  USB_Control_Service_Handler
 *
 * @brief The function is used to send a response to the Host based. 
 *
 * @param status:           status of Device e.g USB_OK,USBERR_INVALID_REQ_TYPE
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Control_Service_Handler
(
    USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
    uint_8 error,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
) 
{      
    if(error == USBERR_INVALID_REQ_TYPE)
    {   
        uint_8 direction = USB_SEND;
        uint_8 ep_num = USB_CONTROL_ENDPOINT;
        /* prepare the component to be sent in lower layer with 
           endpoint number and direction*/
        uint_8 component = (uint_8)(ep_num | (direction<<COMPONENT_PREPARE_SHIFT));
        
        /* incase of error Stall endpoint and update the status*/        
        (void)_usb_device_set_status(usb_fw_ptr->controller_handle,
            (uint_8)(component|USB_STATUS_ENDPOINT),
            (uint_16)USB_STATUS_STALLED);
    }
    else /* Need to send Data to the USB Host */
    {   
        /* send the data prepared by the handlers.*/
        if(*size > setup_packet->length) 
        {            
            *size = setup_packet->length;
        }
        
        /* send the data to the host */
        (void)USB_Class_Send_Data(usb_fw_ptr->class_handle,
            USB_CONTROL_ENDPOINT, *data, *size);

        if((setup_packet->request_type & USB_DATA_DIREC_MASK) ==     
            USB_DATA_TO_HOST)
        {   /* Request was to Get Data from device */          
            /* setup rcv to get status from host */
            (void)_usb_device_recv_data(usb_fw_ptr->controller_handle,
                USB_CONTROL_ENDPOINT,NULL,0);
        }
    }
    return;
}

/*************************************************************************//*!
 *
 * @name  USB_Strd_Req_Get_Status
 *
 * @brief  This function is called in response to Get Status request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Strd_Req_Get_Status(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                               USB_SETUP_STRUCT * setup_packet, 
                               uint_8_ptr *data, 
                               uint_32 *size)
{  
    uint_8 interface, endpoint;
    uint_8 error = USBERR_ERROR;
    
    if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == 
        USB_REQUEST_SRC_DEVICE) 
    {   /* request for Device */
        error = _usb_device_get_status(usb_fw_ptr->controller_handle,
            (uint_8)USB_STATUS_DEVICE, &usb_fw_ptr->std_framework_data);
            
        usb_fw_ptr->std_framework_data &= GET_STATUS_DEVICE_MASK; 
        usb_fw_ptr->std_framework_data = SHORT_LE_TO_HOST(usb_fw_ptr->std_framework_data);                                      
        *size=DEVICE_STATUS_SIZE;                                      
    }
    else if ((setup_packet->request_type & USB_REQUEST_SRC_MASK) == 
        USB_REQUEST_SRC_INTERFACE) 
    {    /* request for Interface */
        interface  = (uint_8) setup_packet->index;
        error =  usb_fw_ptr->desc.GET_DESC_INTERFACE(usb_fw_ptr->desc.handle,
            interface,(uint_8_ptr)&usb_fw_ptr->std_framework_data);
        *size=INTERFACE_STATUS_SIZE;
    }
    else if ((setup_packet->request_type & USB_REQUEST_SRC_MASK) == 
        USB_REQUEST_SRC_ENDPOINT)
    {   /* request for Endpoint */
        endpoint  =(uint_8)(((uint_8)setup_packet->index)|USB_STATUS_ENDPOINT);
        error =  _usb_device_get_status(usb_fw_ptr->controller_handle,
            (uint_8)endpoint, 
            &usb_fw_ptr->std_framework_data);
        usb_fw_ptr->std_framework_data = SHORT_LE_TO_HOST(usb_fw_ptr->std_framework_data);                                      
        *size=ENDP_STATUS_SIZE;
    }
   
    *data = (uint_8_ptr)&usb_fw_ptr->std_framework_data;
    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_Strd_Req_Feature
 *
 * @brief  This function is called in response to Clear or Set Feature request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Strd_Req_Feature(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
                            USB_SETUP_STRUCT * setup_packet, 
                            uint_8_ptr *data, 
                            uint_32 *size)
{   
    uint_16 device_status;
    uint_16 set_request;
    uint_8  error=USBERR_INVALID_REQ_TYPE;
    uint_8  epinfo;
    uint_8  event;
    UNUSED_ARGUMENT(data)
    *size=0;
    /* find whether its a clear feature request or a set feature request */
    set_request = (uint_16)((setup_packet->request & USB_SET_REQUEST_MASK)>>1);
         
    if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == 
        USB_REQUEST_SRC_DEVICE) 
    {
        if(setup_packet->value & DEVICE_REQUEST_MASK)
        {   /* request for Device */  
            error = _usb_device_get_status(usb_fw_ptr->controller_handle,
                (uint_8)USB_STATUS_DEVICE, &device_status);
            if(set_request == (uint_16)TRUE)  
            {  /* add the request to be cleared from device_status */
                device_status |= (1<<setup_packet->value); 
            }
            else   
            {   /* remove the request to be cleared from device_status */
                device_status &= ~(1<<setup_packet->value); 
            }
          
            /* set the status on the device */
            error = _usb_device_set_status(usb_fw_ptr->controller_handle, 
                (uint_8)USB_STATUS_DEVICE, 
                (uint_16)device_status);
        }         
    }
    else if ((setup_packet->request_type & USB_REQUEST_SRC_MASK) == 
        USB_REQUEST_SRC_ENDPOINT) /*request for Endpoint*/  
    {   /* request for Endpoint */
        epinfo = (uint_8)(setup_packet->index & 0x00FF);
        error = _usb_device_set_status(usb_fw_ptr->controller_handle,
            (uint_8)(epinfo|USB_STATUS_ENDPOINT), (uint_16)set_request);
        event = (uint_8)(set_request?USB_APP_EP_STALLED:USB_APP_EP_UNSTALLED);
        /* inform the upper layers of stall/unstall */
        if (usb_fw_ptr->class_callback.callback != NULL) 
        {
          usb_fw_ptr->class_callback.callback(event,(void*)&epinfo,
          usb_fw_ptr->class_callback.arg);  
        }
        
    }
           
    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_Strd_Req_Set_Address
 *
 * @brief  This function is called in response to Set Address request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Strd_Req_Set_Address
(   USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{  
    UNUSED_ARGUMENT(data)    
    *size=0;
    /* update device stae */
    (void)_usb_device_set_status(usb_fw_ptr->controller_handle,
        (uint_8)USB_STATUS_DEVICE_STATE,
        (uint_16)USB_STATE_PENDING_ADDRESS);
    /*store the address from setup_packet into assigned_address*/
    usb_fw_ptr->assigned_address = setup_packet->value;
 
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  USB_Strd_Req_Assign_Address
 *
 * @brief  This function assigns the address to the Device
 *
 * @param handle      
 *
 * @return status       
 *                       USB_OK: Always
 *
 *****************************************************************************/
uint_8 USB_Strd_Req_Assign_Address(USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr)
{     
    /* Set Device Address */
    (void)_usb_device_set_address(usb_fw_ptr->controller_handle,
        (uint_8)(usb_fw_ptr->assigned_address&0x00FF));
    /* Set Device state */
    (void)_usb_device_set_status(usb_fw_ptr->controller_handle, 
        (uint_8)USB_STATUS_DEVICE_STATE, 
        (uint_16)USB_STATE_ADDRESS);
    /* Set Device state */                                  
    (void)_usb_device_set_status(usb_fw_ptr->controller_handle,
    (uint_8)USB_STATUS_ADDRESS,
    (uint_16)usb_fw_ptr->assigned_address);
  
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  USB_Strd_Req_Get_Config
 *
 * @brief  This function is called in response to Get Config request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always
 *
 *****************************************************************************/ 
uint_8 USB_Strd_Req_Get_Config
(   
    USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{
    UNUSED_ARGUMENT(setup_packet)
    
    *size=CONFIG_SIZE;
    (void)_usb_device_get_status(usb_fw_ptr->controller_handle,
        (uint_8)USB_STATUS_CURRENT_CONFIG, &usb_fw_ptr->std_framework_data);
    usb_fw_ptr->std_framework_data = SHORT_LE_TO_HOST(usb_fw_ptr->std_framework_data);                                      
    *data= (uint_8_ptr)&usb_fw_ptr->std_framework_data;      

    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  USB_Strd_Req_Set_Config
 *
 * @brief  This function is called in response to Set Config request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/ 
uint_8 USB_Strd_Req_Set_Config
(   USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{
    uint_8 error = USBERR_INVALID_REQ_TYPE;
    uint_16 config_val;
    UNUSED_ARGUMENT(data)     
    *size=0;
    error = USB_STATUS_ERROR;
    config_val = setup_packet->value;
    
    if (usb_fw_ptr->desc.IS_DESC_VALID_CONFIGURATION(usb_fw_ptr->desc.handle, 
    config_val)) 
    /*if valid configuration (fn returns boolean value)*/
    {       
        uint_16 device_state = USB_STATE_CONFIG;

        if (!config_val) /* if config_val is 0 */ 
        {
            device_state = USB_STATE_ADDRESS ;
        }
        
        error = _usb_device_set_status(usb_fw_ptr->controller_handle, 
            (uint_8)USB_STATUS_DEVICE_STATE, 
            (uint_16)device_state);
        error = _usb_device_set_status(usb_fw_ptr->controller_handle, 
            (uint_8)USB_STATUS_CURRENT_CONFIG, 
            (uint_16)config_val);
       /* callback to the app. to let the application know about the new 
          Config */
        if (usb_fw_ptr->class_callback.callback!=NULL)  
        {
           usb_fw_ptr->class_callback.callback(USB_APP_CONFIG_CHANGED, 
            (void *)&config_val,usb_fw_ptr->class_callback.arg);
           usb_fw_ptr->class_callback.callback(USB_APP_ENUM_COMPLETE,NULL,
           usb_fw_ptr->class_callback.arg);     
        }
        
    }     
    return error;
 }

/**************************************************************************//*!
 *
 * @name  USB_Strd_Req_Get_Interface
 *
 * @brief  This function is called in response to Get Interface request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/  
uint_8 USB_Strd_Req_Get_Interface
(
    USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{
    uint_8 error;
      
    *size = INTERFACE_STATUS_SIZE;
    error = usb_fw_ptr->desc.GET_DESC_INTERFACE(usb_fw_ptr->desc.handle, 
        (uint_8)setup_packet->index, (uint_8_ptr)&usb_fw_ptr->std_framework_data);
    *data = (uint_8_ptr)&usb_fw_ptr->std_framework_data;

    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_Strd_Req_Set_Interface
 *
 * @brief  This function is called in response to Set Interface request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : Always       
 *
 *****************************************************************************/ 
uint_8 USB_Strd_Req_Set_Interface
(
    USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{     

    uint_8 error;
    UNUSED_ARGUMENT(data)
    *size=0;
    
    /* Request type not for interface */
    if ((setup_packet->request_type & 0x03) != 0x01) 
    {
        return USB_STATUS_ERROR;
    }
    
    /* Get Interface and alternate interface from setup_packet */
    error = usb_fw_ptr->desc.SET_DESC_INTERFACE(usb_fw_ptr->desc.handle, 
        (uint_8)setup_packet->index, (uint_8)setup_packet->value); 
                                                       
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  USB_Strd_Req_Sync_Frame
 *
 * @brief  This function is called in response to Sync Frame request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Strd_Req_Sync_Frame
(
    USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{
    uint_8 error;
    UNUSED_ARGUMENT(setup_packet)
    
    *size=FRAME_SIZE;
    
    /* Get the frame number */
    error = _usb_device_get_status(usb_fw_ptr->controller_handle,
        (uint_8)USB_STATUS_SOF_COUNT, 
        &usb_fw_ptr->std_framework_data);
    *data= (uint_8_ptr)&usb_fw_ptr->std_framework_data;      
    
    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_Std_Req_Get_Descriptor
 *
 * @brief  This function is called in response to Get Descriptor request
 *
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned 
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Strd_Req_Get_Descriptor
(
    USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr,
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size
)
{
    /*g_setup_packet.hValue*/
    uint_8 type = (setup_packet->value >> 8) & 0xFF ;
    uint_16 index = (uint_8)UNINITIALISED_VAL;
    uint_8 str_num = (uint_8)UNINITIALISED_VAL;
    uint_8 error;
    
    if (type == STRING_DESCRIPTOR_TYPE)
    {   /* for string descriptor set the language and string number */ 
        index = setup_packet->index;
        /*g_setup_packet.lValue*/
        str_num = setup_packet->value & 0xFF;
    }
    
    /* Call descriptor class to get descriptor */
    error = usb_fw_ptr->desc.GET_DESC(usb_fw_ptr->desc.handle,
        type,str_num,index,data,size);  
    return error;
}
/**************************************************************************//*!
 *
 * @name  USB_Framework_GetDesc
 *
 * @brief  This function is called in to get the discriptor as specified in cmd.
 *
 * @param handle:           USB framework handle. Received from
 *                          USB_Framework_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param in_buff           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Framework_GetDesc(
    USB_CLASS_FW_HANDLE handle, /*[IN]*/
    int_32 cmd,/*[IN]*/
    uint_8 in_data,/*[IN]*/
    uint_8_ptr * in_buff/*[OUT]*/
)
{
   USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr;
   uint_8 error; 
   if (handle > USB_MAX_CLASS_FW_OBJECT)
      return USBERR_ERROR;
   
   usb_fw_ptr = Get_Usb_Class_Fw_Object_Ptr(handle);
   if (usb_fw_ptr == NULL)
        return USBERR_ERROR;
   
   error = usb_fw_ptr->desc.DESC_GET_FEATURE(usb_fw_ptr->desc.handle,cmd,in_data,in_buff);
   return error;        
}

/**************************************************************************//*!
 *
 * @name  USB_Framework_SetDesc
 *
 * @brief  This function is called in to get the discriptor as specified in cmd.
 *
 * @param handle:           USB framework handle. Received from
 *                          USB_Framework_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param outBuf           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Framework_SetDesc(
    USB_CLASS_FW_HANDLE handle,/*[IN]*/
    int_32 cmd,/*[IN]*/
    uint_8 input_data,/*[IN]*/
    uint_8_ptr * outBuf/*[IN]*/
)
{
   USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr;
    
   if (handle > USB_MAX_CLASS_FW_OBJECT)
      return USBERR_ERROR;
   
   usb_fw_ptr = Get_Usb_Class_Fw_Object_Ptr(handle);
   if (usb_fw_ptr == NULL)
        return USBERR_ERROR;
   
  return usb_fw_ptr->desc.DESC_SET_FEATURE(usb_fw_ptr->desc.handle,cmd,
  input_data,outBuf);
            
}

/**************************************************************************//*!
 *
 * @name  USB_Framework_Remote_wakeup
 *
 * @brief  This function is called in to get the discriptor as specified in cmd.
 *
 * @param handle:           USB framework handle. Received from
 *                          USB_Framework_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param in_buff           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
boolean USB_Framework_Remote_wakeup(USB_CLASS_FW_HANDLE handle)
{
   USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr;
    
   if (handle > USB_MAX_CLASS_FW_OBJECT)
      return USBERR_ERROR;
   
   usb_fw_ptr = Get_Usb_Class_Fw_Object_Ptr(handle);
   if (usb_fw_ptr == NULL)
        return USBERR_ERROR;
   
   return usb_fw_ptr->desc.DESC_REMOTE_WAKEUP(usb_fw_ptr->desc.handle);
    
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/os/mqx25x/rtcsmsg.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcsmsg.c$
* $Version : 3.0.5.0$
* $Date    : Mar-5-2009$
*
* Comments:
*
*   This file contains the interface to the RTCS
*   message queue object.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#if 0
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_msgqueue_create
* Returned Values : error code
* Comments        :
*     Initialize a message queue.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_msgqueue_create
   (
      _rtcs_msgqueue _PTR_ msgq
   )
{ /* Body */

   _lwsem_create_hidden(&msgq->EMPTY, RTCSMQ_SIZE);
   _lwsem_create_hidden(&msgq->FULL, 0);
   msgq->HEAD = 0;
   msgq->TAIL = 0;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_msgqueue_send
* Returned Values : void
* Comments        :
*     Send a message, block if the message queue is full.
*
*END*-----------------------------------------------------------------*/

void RTCS_msgqueue_send
   (
      _rtcs_msgqueue _PTR_ msgq,
      pointer              msg
   )
{ /* Body */

   /* Wait for an empty slot in the queue */
   _lwsem_wait(&msgq->EMPTY);
   _int_disable();

   /* Dequeue the message */
   msgq->QUEUE[msgq->TAIL++] = msg;
   if (msgq->TAIL == RTCSMQ_SIZE) {
      msgq->TAIL = 0;
   } /* Endif */

   /* Unblock the receiver */
   _int_enable();
   _lwsem_post(&msgq->FULL);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_msgqueue_trysend
* Returned Values : RTCS_OK if successful, or RTCS_ERROR if the message
*                   queue is full.
* Comments        :
*     Send a message, fail if the message queue is full.
*
*END*-----------------------------------------------------------------*/

int_32 RTCS_msgqueue_trysend
   (
      _rtcs_msgqueue _PTR_ msgq,
      pointer              msg
   )
{ /* Body */

   /* Check for an empty slot in the queue */
   _int_disable();
   if (msgq->EMPTY.VALUE <= 0) {
      _int_enable();
      return RTCS_ERROR;
   } else {
      --msgq->EMPTY.VALUE;
   } /* Endif */

   /* Dequeue the message */
   msgq->QUEUE[msgq->TAIL++] = msg;
   if (msgq->TAIL == RTCSMQ_SIZE) {
      msgq->TAIL = 0;
   } /* Endif */

   /* Unblock the receiver */
   _int_enable();
   _lwsem_post(&msgq->FULL);

   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_msgqueue_receive
* Returned Values : message
* Comments        :
*     Receive a message, block if the message queue is empty.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_msgqueue_receive
   (
      _rtcs_msgqueue _PTR_ msgq,
      uint_32              timeout
   )
{ /* Body */
   pointer  msg;
   TIME_STRUCT     time;
   MQX_TICK_STRUCT ticks;

   if (!timeout) {
      _lwsem_wait(&msgq->FULL);
   } else {
      time.SECONDS      = timeout/1000;
      time.MILLISECONDS = timeout%1000;
      if (!_time_to_ticks(&time, &ticks)) {
         return NULL;
      } /* Endif */
      if (_lwsem_wait_for(&msgq->FULL, &ticks) != MQX_OK) {
         /* If we have a timeout, return */
         return NULL;
      } /* Endif */
   } /* Endif */

   _int_disable();
   msg = msgq->QUEUE[msgq->HEAD++];
   if (msgq->HEAD == RTCSMQ_SIZE) {
      msgq->HEAD = 0;
   } /* Endif */

   _int_enable();
   _lwsem_post(&msgq->EMPTY);

   return msg;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_msgqueue_close
* Returned Values : void
* Comments        :
*     Uninitialize a message queue.
*
*END*-----------------------------------------------------------------*/

void RTCS_msgqueue_close
   (
      _rtcs_msgqueue _PTR_ msgq
   )
{ /* Body */

   _lwsem_destroy(&msgq->FULL);
   _lwsem_destroy(&msgq->EMPTY);

} /* Endbody */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwadc/lwadc_mpxsxx.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2011 Embedded Access Inc
* All Rights Reserved
*
****************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwadc_mpxsxx.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the ADC driver CPU specific functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "pxadc.h"
#include "lwadc_mpxsxx.h"
#include "lwadc_mpxsxx_prv.h"
#include "lwadc.h"


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_restart
 * Returned Value   :
 * Comments         :
 * This function restarts the ADC after a parameter change.
 *
 *END*----------------------------------------------------------------------*/

static void _lwadc_restart(ADC_CONTEXT_PTR context_ptr)
{
    VPXADC_REG_STRUCT_PTR   adc_ptr = context_ptr->adc_ptr;
    uint_32                 adc_status;

    // Stop conversion
    adc_ptr->MCR &= ADC_MCR_NSTART;

    while (adc_ptr->MSR & ADC_MSR_NSTART) {};

    do {
        adc_status = adc_ptr->MSR & ADC_MSR_ADCSTATUS_MASK;
    } while ((adc_status == ADC_MSR_ADCSTATUS_SAMPLE) || (adc_status == ADC_MSR_ADCSTATUS_CONVERSION));

    if (context_ptr->mcr & ADC_MCR_ADCLKSEL) {
        // Power down the ADC
        adc_ptr->MCR = ADC_MCR_PWDN;
        while ((adc_ptr->MSR & ADC_MSR_ADCSTATUS_MASK) !=  ADC_MSR_ADCSTATUS_POWER_DOWN) {};
        _PSP_SYNC();

        // Need to set the clock in power down mode
        adc_ptr->MCR = ADC_MCR_PWDN | ADC_MCR_ADCLKSEL;
        _PSP_SYNC();

        // Now go to IDLE mode
        adc_ptr->MCR = ADC_MCR_ADCLKSEL;
    } else {
        adc_ptr->MCR = 0;
    }

    _PSP_SYNC();
     while ((adc_ptr->MSR & ADC_MSR_ADCSTATUS_MASK) !=  ADC_MSR_ADCSTATUS_IDLE) {};

    adc_ptr->CEOCFR0 = context_ptr->channels;
    _PSP_SYNC();

    // Set up continuous conversion on selected channels
    adc_ptr->NCMR0 =  context_ptr->channels;

    // Start conversions
    adc_ptr->MCR  = context_ptr->mcr; // ADC_MCR_OWREN|ADC_MCR_MODE_SCAN|ADC_MCR_NSTART; //

}

/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_init
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function initializes the ADC device with global parameters
 *    (conversion frequency, resolution, number format). It does  not start
 *    any conversions.
 *
 *END*----------------------------------------------------------------------*/

static ADC_CONTEXT adc_context[MPXSXX_ADC_NUM_DEVICES] = {0};

boolean  _lwadc_init( const LWADC_INIT_STRUCT *  init_ptr)
{
    VPXADC_REG_STRUCT_PTR   adc_ptr;
    uint_32                 mcr=ADC_MCR_OWREN|ADC_MCR_MODE_SCAN|ADC_MCR_NSTART;
    ADC_CONTEXT_PTR         context_ptr;

    #if PSP_HAS_DEVICE_PROTECTION
    if (!_bsp_adc_enable_access(init_ptr->device)) {
        return FALSE;
    }
    #endif

    adc_ptr = _bsp_get_adc_base_address(init_ptr->device);

    if (adc_ptr==NULL) {
         return FALSE;
    }

    context_ptr =  &adc_context[init_ptr->device];
    context_ptr->adc_ptr   = adc_ptr;
    context_ptr->channels = 0;

    if (init_ptr->format == LWADC_FORMAT_LEFT_JUSTIFIED) {
        mcr |= ADC_MCR_WLSIDE;
    } else if (init_ptr->format != LWADC_FORMAT_RIGHT_JUSTIFIED) {
        return FALSE;
    }

    if (init_ptr->clock == BSP_MOTC_CLOCK) {
        mcr |= ADC_MCR_ADCLKSEL;
    } else if (init_ptr->clock != BSP_MOTC_CLOCK/2) {
        return FALSE;
    }
    adc_ptr->MCR = ADC_MCR_PWDN;

    context_ptr->init_ptr = init_ptr;
    context_ptr->mcr = mcr;
    return TRUE;
}

/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_init_input
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 * This function prepares and initialize the LWADC_STRUCT
 * with all data it will need later for quick control of the input.
 * The structure initialized here is used in all subsequent calls to any
 * LWADC driver and is uniquely identifying the input.
 * This function calls a BSP supplied function to enable the ADC input pin.
 * It adds the input to the list of channels being converted, and place the
 * ADC in continuous conversion mode if not already in this mode.
 *
 *END*----------------------------------------------------------------------*/

boolean  _lwadc_init_input( LWADC_STRUCT_PTR lwadc_ptr, uint_32 input )
{
    uint_32 device, channel;

    device  = ADC_DEVICE(input);
    channel = ADC_CHANNEL(input);

    // Used as a validity check in other _lwadc functions
    lwadc_ptr->context_ptr = NULL;

    // Make sure channel & device is in range
    if ((device >= MPXSXX_ADC_NUM_DEVICES ) ||(channel >= ADC_HW_CHANNELS )) {
        return FALSE;
    }

    lwadc_ptr->mask = (1<<channel);

    // And that the ADC can convert this channel
    if ( (_bsp_get_adc_channel_mask(device) & lwadc_ptr->mask) == 0) {
        return FALSE;
    }

    // Enable ADC I/O Pin
    if ( _bsp_adc_io_init(input) != MQX_OK) {
        return FALSE;
    }

    // set channel specific parameters
    lwadc_ptr->input   = input;
    lwadc_ptr->context_ptr = &adc_context[device];
    lwadc_ptr->numerator   = lwadc_ptr->context_ptr->init_ptr->reference;
    lwadc_ptr->denominator = ADC_RESOLUTION_DEFAULT;

    // Set channel to convert
    _int_disable();
    lwadc_ptr->context_ptr->channels |= lwadc_ptr->mask;

    // start conversion
    _lwadc_restart(lwadc_ptr->context_ptr);
    _int_enable();
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_read_raw
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function Read the current value of the ADC input and return
 *    the result without applying any scaling.
 *
 *END*----------------------------------------------------------------------*/


boolean _lwadc_read_raw( LWADC_STRUCT_PTR lwadc_ptr, LWADC_VALUE_PTR outSample)
{
    LWADC_VALUE sample;

    if (lwadc_ptr->context_ptr == NULL) {
        return FALSE;
    }

    // Make sure this channel has not been disabled
    if ((lwadc_ptr->context_ptr->adc_ptr->NCMR0 & lwadc_ptr->mask) ==0) {
        return FALSE;
    }

    if ((lwadc_ptr->context_ptr->adc_ptr->MCR & ADC_MCR_MODE_SCAN) == 0) {
        // ADC is not in scan mode.
        _lwadc_restart(lwadc_ptr->context_ptr);
    }

    sample = lwadc_ptr->context_ptr->adc_ptr->CDR[ADC_CHANNEL(lwadc_ptr->input)];

    *outSample = sample & ADC_CDR_CDATA_MASK;

    // Clear conversion complete
    lwadc_ptr->context_ptr->adc_ptr->CEOCFR0 = lwadc_ptr->mask;
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_read
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function Read the current value of the ADC input, applies any
 *    scaling, and return the result.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_read( LWADC_STRUCT_PTR lwadc_ptr, LWADC_VALUE_PTR outSample)
{
    LWADC_VALUE rawSample;

    if (lwadc_ptr->context_ptr == NULL) {
        return FALSE;
    }

    if (_lwadc_read_raw(lwadc_ptr,&rawSample)) {
        *outSample = ((rawSample*lwadc_ptr->numerator) + (lwadc_ptr->denominator>>1))/ lwadc_ptr->denominator;
        return TRUE;
    }

    *outSample = 0;
    return FALSE;
}



/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_wait_next
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function Waits for a new value to be available on the specified ADC input.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_wait_next( LWADC_STRUCT_PTR lwadc_ptr )
{
    if (lwadc_ptr->context_ptr == NULL) {
        return FALSE;
    }

    if ((lwadc_ptr->context_ptr->adc_ptr->MCR & ADC_MCR_MODE_SCAN) == 0) {
        // ADC is not in scan mode.
        _lwadc_restart(lwadc_ptr->context_ptr);
    }

    while ((lwadc_ptr->context_ptr->adc_ptr->CEOCFR0 & lwadc_ptr->mask) == 0) {};

    return TRUE;
}



/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_read_average
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function Read the current value of the ADC input, applies any
 *    scaling, and return the result.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_read_average( LWADC_STRUCT_PTR lwadc_ptr, uint_32 num_samples, LWADC_VALUE_PTR outSample)
{
    LWADC_VALUE rawSample,sum = 0;
    uint_32     i;

    if (num_samples > (MAX_UINT_32/ADC_RESOLUTION_DEFAULT)) {
        return FALSE;
    }

    for (i=0;i<num_samples;i++) {
        if (!_lwadc_wait_next(lwadc_ptr)) {
            return FALSE;
        }

        if (!_lwadc_read_raw(lwadc_ptr,&rawSample)) {
            return FALSE;
        }
        sum += rawSample;
    }

    *outSample = (((sum/num_samples)*lwadc_ptr->numerator) + (lwadc_ptr->denominator>>1))/ lwadc_ptr->denominator;
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_set_attribute
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 * This function sets attributes for the specified ADC input. Attributes
 * could include single/differential mode, reference, scaling numerator or
 * denominator, etc.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_set_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute,  uint_32 value)
{
    VPXADC_REG_STRUCT_PTR adc_ptr;

    if (lwadc_ptr->context_ptr == NULL) {
        return FALSE;
    }

    adc_ptr = lwadc_ptr->context_ptr->adc_ptr;

    switch (attribute) {
        case LWADC_NUMERATOR:
            lwadc_ptr->numerator = value;
            break;

        case LWADC_DENOMINATOR:
            lwadc_ptr->denominator = value;
            break;

        case LWADC_POWER_DOWN:
            if (value) {
                adc_ptr->MCR = ADC_MCR_PWDN;
            } else {
                _int_disable();
                _lwadc_restart(lwadc_ptr->context_ptr);
                _int_enable();
            }
            break;

        case LWADC_FORMAT:
            _int_disable();
            if (value == LWADC_FORMAT_LEFT_JUSTIFIED) {
                lwadc_ptr->context_ptr->mcr |= ADC_MCR_WLSIDE;
            } else if (value == LWADC_FORMAT_RIGHT_JUSTIFIED) {
                lwadc_ptr->context_ptr->mcr  &= ~ADC_MCR_WLSIDE;
            } else {
                return FALSE;
            }
            if ((adc_ptr->MCR & ADC_MCR_PWDN) == 0) {
                _lwadc_restart(lwadc_ptr->context_ptr);
            }
            _int_enable();
           break;

        case LWADC_FREQUENCY:
            _int_disable();
            if (value == BSP_MOTC_CLOCK) {
                lwadc_ptr->context_ptr->mcr &= ~ADC_MCR_ADCLKSEL;
            } else if (value == BSP_MOTC_CLOCK/2) {
                lwadc_ptr->context_ptr->mcr |= ADC_MCR_ADCLKSEL;
            } else {
                _int_enable();
                return FALSE;
            }

            // If we are NOT powered down, AND we are switching clock frequencies,
            // then we need to power down to switch frequencies (otherwise we will do it when we power back up)
            if ( ((adc_ptr->MCR & ADC_MCR_PWDN) == 0)  &&
                 ( (adc_ptr->MCR & ADC_MCR_ADCLKSEL) != ( adc_ptr->MCR & ADC_MCR_ADCLKSEL)) )
            {
                _lwadc_restart(lwadc_ptr->context_ptr);
            }
            _int_enable();
            break;

        case LWADC_DIVIDER:
            // We support a divider, as long as it is 1.
            return (value == 1)?TRUE:FALSE;
            break;

        case LWADC_DIFFERENTIAL:
            // We don't support differential, so return FALSE if asked for it, TRUE otherwise
            return !value;
            break;

        case LWADC_INPUT_CONVERSION_ENABLE:
            _int_disable();
            if (value) {
                lwadc_ptr->context_ptr->channels |= lwadc_ptr->mask;
            } else {
                lwadc_ptr->context_ptr->channels &= ~lwadc_ptr->mask;
            }
            _lwadc_restart(lwadc_ptr->context_ptr);
            _int_enable();
            break;

        default:
            return FALSE;
    }
    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : _lwadc_get_attribute
 * Returned Value   : TRUE for success, FALSE for failure
 * Comments         :
 *    This function This function gets attributes for the specified ADC input,
 *    or for the ADC module as a whole. Attributes could include
 *    single/differential mode, reference, scaling numerator or denominator, etc.
 *
 *END*----------------------------------------------------------------------*/

boolean _lwadc_get_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute,  uint_32_ptr value_ptr)
{
    if ((lwadc_ptr->context_ptr == NULL) || (value_ptr == NULL)) {
        return FALSE;
    }

    switch (attribute) {
        case LWADC_NUMERATOR:
            *value_ptr = lwadc_ptr->numerator;
            break;

        case LWADC_DENOMINATOR:
            *value_ptr = lwadc_ptr->denominator;
            break;

        case LWADC_POWER_DOWN:
            *value_ptr = (lwadc_ptr->context_ptr->adc_ptr->MCR & ADC_MCR_PWDN)?TRUE:FALSE;
            break;

        case LWADC_RESOLUTION:
            *value_ptr = ADC_RESOLUTION_DEFAULT;
            break;

        case LWADC_REFERENCE:
            *value_ptr = lwadc_ptr->context_ptr->init_ptr->reference;
            break;

        case LWADC_FREQUENCY:
            if (lwadc_ptr->context_ptr->adc_ptr->MCR & ADC_MCR_ADCLKSEL) {
                *value_ptr = BSP_MOTC_CLOCK;
            } else {
                *value_ptr = BSP_MOTC_CLOCK/2;
            }
            break;

        case LWADC_DIVIDER:
            *value_ptr = 1;
            break;

        case LWADC_DIFFERENTIAL:
            *value_ptr = FALSE;
            break;

        case LWADC_FORMAT:
            if (lwadc_ptr->context_ptr->adc_ptr->MCR & ADC_MCR_WLSIDE) {
                *value_ptr = LWADC_FORMAT_LEFT_JUSTIFIED;
            } else {
                *value_ptr = LWADC_FORMAT_RIGHT_JUSTIFIED;
            }
            break;

        case LWADC_INPUT_CONVERSION_ENABLE:
            *value_ptr = (lwadc_ptr->context_ptr->adc_ptr->NCMR0 & lwadc_ptr->mask)?TRUE:FALSE;
            break;

        default:
            return FALSE;
    }
    return TRUE;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/watchdog.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: watchdog.h$
* $Version : 3.8.6.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   watchdog component.
*
*END************************************************************************/
#ifndef __watchdog_h__
#define __watchdog_h__ 1

#include <mqx_cnfg.h>
#if (! MQX_USE_SW_WATCHDOGS) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error WATCHDOG component is currently disabled in MQX kernel. Please set MQX_USE_SW_WATCHDOGS to 1 in user_config.h and recompile kernel.
#endif

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* Error codes */

#define WATCHDOG_INVALID_ERROR_FUNCTION   (WATCHDOG_ERROR_BASE|0x01)
#define WATCHDOG_INVALID_INTERRUPT_VECTOR (WATCHDOG_ERROR_BASE|0x02)

/*--------------------------------------------------------------------------*/
/*
 *                    TYPEDEFS FOR _CODE_PTR_ FUNCTIONS
 */
typedef void (_CODE_PTR_  WATCHDOG_ERROR_FPTR)(pointer);


/*--------------------------------------------------------------------------*/
/*                        DATA STRUCTURE DEFINITIONS                        */

/*
 *  external declarations for the interface procedures
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _watchdog_create_component(_mqx_uint, WATCHDOG_ERROR_FPTR);
extern boolean   _watchdog_stop(void);
extern boolean   _watchdog_start(uint_32);
extern boolean   _watchdog_start_ticks(MQX_TICK_STRUCT_PTR);
extern _mqx_uint _watchdog_test(pointer _PTR_, pointer _PTR_);
#endif

#ifdef __cplusplus
}
#endif

#endif /* __watchdog_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_1588.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_1588.c$
* $Version : 3.8.20.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains IEEE 1588 interface functions of the MACNET driver.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "enet.h"
#include "enetprv.h"
#include "macnet_prv.h"
#include "macnet_1588.h"
#include <string.h>

#if ENETCFG_SUPPORT_PTP

/* Global variables */
uint_64  MACNET_PTP_seconds = 0;
boolean  MACNET_PTP_set_rtc_time_flag = FALSE;

static ENET_MemMapPtr MACNET_PTP_master_addr;

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_swap8bytes
*  Returned Value : uint_64
*  Comments       : Swap 8 bytes
*
*END*-----------------------------------------------------------------*/
static uint_64 MACNET_ptp_swap8bytes(uint_64 n)
{
	uchar temp[8];

    temp[7] = *((uchar *)&n);
    temp[6] = ((uchar *)&n)[1];
    temp[5] = ((uchar *)&n)[2];
    temp[4] = ((uchar *)&n)[3];
    temp[3] = ((uchar *)&n)[4];
    temp[2] = ((uchar *)&n)[5];
    temp[1] = ((uchar *)&n)[6];
    temp[0] = ((uchar *)&n)[7];
    return (*(uint_64 *)temp);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_init_circ
*  Returned Value :
*  Comments       : Alloc the ring resource
*
*
*END*-----------------------------------------------------------------*/
static boolean MACNET_ptp_init_circ(MACNET_PTP_CIRCULAR *buf)
{
	buf->DATA_BUF = (MACNET_PTP_DATA *) _mem_alloc_system_zero((MACNET_PTP_DEFAULT_RX_BUF_SZ+1) *	sizeof(MACNET_PTP_DATA));

	if (!buf->DATA_BUF)
		return FALSE;
	buf->FRONT = 0;
	buf->END = 0;
	buf->SIZE = (MACNET_PTP_DEFAULT_RX_BUF_SZ + 1);

	return TRUE;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_calc_index
*  Returned Value :
*  Comments       : Calculate index of the element
*
*
*END*-----------------------------------------------------------------*/
static inline uint_32 MACNET_ptp_calc_index(uint_32 size, uint_32 curr_index, uint_32 offset)
{
	return ((curr_index + offset) % size);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_is_empty
*  Returned Value :
*  Comments       : Return TRUE if the buffer is empty
*
*
*END*-----------------------------------------------------------------*/
static boolean MACNET_ptp_is_empty(MACNET_PTP_CIRCULAR *buf)
{
	return (buf->FRONT == buf->END);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_nelems
*  Returned Value :
*  Comments       : Calculates the number of elements in the ring buffer
*
*
*END*-----------------------------------------------------------------*/
static uint_32 MACNET_ptp_nelems(MACNET_PTP_CIRCULAR *buf)
{
	const uint_32 FRONT = buf->FRONT;
	const uint_32 END = buf->END;
	const uint_32 SIZE = buf->SIZE;
	uint_32 n_items;

	if (END > FRONT)
		n_items = END - FRONT;
	else if (END < FRONT)
		n_items = SIZE - (FRONT - END);
	else
		n_items = 0;

	return n_items;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_is_full
*  Returned Value :
*  Comments       : Returns TRUE if the buffer is full
*
*
*END*-----------------------------------------------------------------*/
static boolean MACNET_ptp_is_full(MACNET_PTP_CIRCULAR *buf)
{
	if (MACNET_ptp_nelems(buf) == (buf->SIZE - 1))
		return TRUE;
	else
		return FALSE;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_insert
*  Returned Value :
*  Comments       : Inserts new element into the ring buffer
*
*
*END*-----------------------------------------------------------------*/
boolean MACNET_ptp_insert(MACNET_PTP_CIRCULAR *buf,
				          MACNET_PTP_DATA *data)
{
	MACNET_PTP_DATA *tmp;
	uint_32         index;

	if (MACNET_ptp_is_full(buf))
		return FALSE;

	tmp = (buf->DATA_BUF + buf->END);

	tmp->KEY = data->KEY;
	tmp->TS_TIME.SEC = data->TS_TIME.SEC;
	tmp->TS_TIME.NSEC = data->TS_TIME.NSEC;
	for(index=0;index<MACNET_PTP_CLOCKID_SIZE;index++)
        tmp->CLOCKID[index] = data->CLOCKID[index];

	buf->END = MACNET_ptp_calc_index(buf->SIZE, buf->END, 1);

	return TRUE;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_find_and_remove
*  Returned Value :
*  Comments       : Based on sequence ID and the clock ID
*                   find the element in the ring buffer and remove it
*
*END*-----------------------------------------------------------------*/
static int_32 MACNET_ptp_find_and_remove(MACNET_PTP_CIRCULAR *buf,
			                             uint_32 key,
			                             uint_8* clkid,
			                             MACNET_PTP_DATA *data)
{
	uint_32 i;
	uint_32 SIZE = buf->SIZE, END = buf->END;

	if (MACNET_ptp_is_empty(buf))
		return ENET_ERROR;

	i = buf->FRONT;
	while (i != END) {
		if (((buf->DATA_BUF + i)->KEY == key) && (0==(memcmp(((const void*)&(buf->DATA_BUF + i)->CLOCKID[0]), (const void*)clkid, MACNET_PTP_CLOCKID_SIZE))))
			break;
		i = MACNET_ptp_calc_index(SIZE, i, 1);
	}

	if (i == END) {
		buf->FRONT = buf->END;
		return ENET_ERROR;
	}

	data->TS_TIME.SEC = (buf->DATA_BUF + i)->TS_TIME.SEC;
	data->TS_TIME.NSEC = (buf->DATA_BUF + i)->TS_TIME.NSEC;

	buf->FRONT = MACNET_ptp_calc_index(SIZE, i, 1);

	return ENET_OK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_init
*  Returned Value :
*  Comments       : Initialize required ring buffers
*
*
*END*-----------------------------------------------------------------*/
uint_32 MACNET_ptp_init(ENET_CONTEXT_STRUCT_PTR enet_ptr)
{
	MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
	MACNET_PTP_PRIVATE         *priv = (MACNET_PTP_PRIVATE_PTR)macnet_context_ptr->PTP_PRIV;

    if(!(enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_INBAND)) {
        MACNET_ptp_init_circ(&(priv->RX_TIME_SYNC));
        MACNET_ptp_init_circ(&(priv->RX_TIME_DEL_REQ));
        MACNET_ptp_init_circ(&(priv->RX_TIME_PDEL_REQ));
        MACNET_ptp_init_circ(&(priv->RX_TIME_PDEL_RESP));
    }
    MACNET_ptp_init_circ(&(priv->TX_TIME));
    return 0;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_cleanup
*  Returned Value :
*  Comments       : Free all ring buffers
*
*
*END*-----------------------------------------------------------------*/
void MACNET_ptp_cleanup(ENET_CONTEXT_STRUCT_PTR enet_ptr)
{
	MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
	MACNET_PTP_PRIVATE         *priv = (MACNET_PTP_PRIVATE_PTR)macnet_context_ptr->PTP_PRIV;

    if(!(enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_INBAND)) {
    	if (priv->RX_TIME_SYNC.DATA_BUF)
    		_mem_free((pointer)priv->RX_TIME_SYNC.DATA_BUF);
    	if (priv->RX_TIME_DEL_REQ.DATA_BUF)
    		_mem_free((pointer)priv->RX_TIME_DEL_REQ.DATA_BUF);
    	if (priv->RX_TIME_PDEL_REQ.DATA_BUF)
    		_mem_free((pointer)priv->RX_TIME_PDEL_REQ.DATA_BUF);
    	if (priv->RX_TIME_PDEL_RESP.DATA_BUF)
    		_mem_free((pointer)priv->RX_TIME_PDEL_RESP.DATA_BUF);
    }
    if (priv->TX_TIME.DATA_BUF)
    	_mem_free((pointer)priv->TX_TIME.DATA_BUF);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_get_master_base_address
*  Returned Value :
*  Comments         :
*    This function returns pointer to base address of the MACNET device
*    in PTP master mode.
*
*END*-----------------------------------------------------------------*/
ENET_MemMapPtr MACNET_ptp_get_master_base_address(void)
{
    return MACNET_PTP_master_addr;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_set_master_base_address
*  Returned Value :
*  Comments         :
*    This function sets pointer to base address of the MACNET device
*    in PTP master mode.
*
*END*-----------------------------------------------------------------*/
void MACNET_ptp_set_master_base_address(ENET_MemMapPtr addr)
{
    MACNET_PTP_master_addr = addr;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_start
*  Returned Value :
*  Comments       : 1588 Module initialization
*
*
*END*-----------------------------------------------------------------*/
uint_32 MACNET_ptp_start(MACNET_PTP_PRIVATE *priv, boolean master_mode)
{
	MACNET_PTP_PRIVATE *fpp = priv;

#if defined(BSP_TWR_K60N512) || defined(BSP_TWR_K60D100M)
    /* Select the 1588 timer source clock - EXTAL clock */
    OSC_CR |= OSC_CR_ERCLKEN_MASK;
    SIM_SOPT2 = ((SIM_SOPT2) & ~SIM_SOPT2_TIMESRC_MASK) | SIM_SOPT2_TIMESRC(0x2);
#endif

	/* Enable module for starting Tmr Clock */
    fpp->MACNET_PTR->ATCR = ENET_ATCR_RESTART_MASK;
    fpp->MACNET_PTR->ATINC = MACNET_1588_CLOCK_INC;
    fpp->MACNET_PTR->ATPER = MACNET_1588_ATPER_VALUE;

#if (MK60_REV_1_0 || MK60_REV_1_1 || MK60_REV_1_2)
    /* Workaround for e2579: ENET: No support for IEEE 1588, TS_TIMER, timestamp timer overflow interrupt */
    fpp->MACNET_PTR->CHANNEL[MACNET_PTP_TIMER].TCCR = MACNET_1588_ATPER_VALUE - MACNET_1588_CLOCK_INC;
    fpp->MACNET_PTR->CHANNEL[MACNET_PTP_TIMER].TCSR = (((0x5)<<ENET_TCSR_TMODE_SHIFT)&ENET_TCSR_TMODE_MASK) |
                                                      ENET_TCSR_TIE_MASK;
    fpp->MACNET_PTR->CHANNEL[MACNET_PTP_TIMER].TCCR = MACNET_1588_ATPER_VALUE - MACNET_1588_CLOCK_INC;
#endif

    /* Period PIN & EVT bits must be set for rollover detect */
    fpp->MACNET_PTR->ATCR = ENET_ATCR_PEREN_MASK | ENET_ATCR_PINPER_MASK;

    /* Set the slave mode in case the MACNET is not handling the 1588timer */
    if(!master_mode)
	    fpp->MACNET_PTR->ATCR |= ENET_ATCR_SLAVE_MASK;

    /* Start counter */
    fpp->MACNET_PTR->ATCR |= ENET_ATCR_EN_MASK;
    return 0;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_stop
*  Returned Value :
*  Comments       : Cleanup routine for 1588 module.
*                   When PTP is disabled this routing is called.
*
*END*-----------------------------------------------------------------*/
void MACNET_ptp_stop(ENET_MemMapPtr macnet_ptr)
{
	macnet_ptr->ATCR = 0;
	macnet_ptr->ATCR |= ENET_ATCR_RESTART_MASK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_get_curr_cnt
*  Returned Value :
*  Comments       : Gets current value of the precise 1588 counter
*
*
*END*-----------------------------------------------------------------*/
static void MACNET_ptp_get_curr_cnt(ENET_MemMapPtr macnet_ptr,
                                    MACNET_PTP_TIME *curr_time)
{
 	curr_time->SEC = MACNET_PTP_seconds;
	/* To read the current value, issue a capture command (set
       ENETn_ATCR[CAPTURE]) prior to reading this register */
	macnet_ptr->ATCR |= ENET_ATCR_CAPTURE_MASK;
	macnet_ptr->ATCR |= ENET_ATCR_CAPTURE_MASK;
	curr_time->NSEC = macnet_ptr->ATVR;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_set_1588cnt
*  Returned Value :
*  Comments       : Set the precise 1588 counter
*
*
*END*-----------------------------------------------------------------*/
static void MACNET_ptp_set_1588cnt(ENET_MemMapPtr macnet_ptr,
			                       MACNET_PTP_TIME *fec_time)
{
	MACNET_int_disable();
	MACNET_PTP_seconds = fec_time->SEC;
	macnet_ptr->ATVR = fec_time->NSEC;
	MACNET_PTP_set_rtc_time_flag = TRUE;
	MACNET_int_enable();
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_set_correction
*  Returned Value :
*  Comments       : Sets 1588counter corrections
*                   to eliminate the clock drift
*
*END*-----------------------------------------------------------------*/
static void MACNET_ptp_set_correction(MACNET_PTP_PRIVATE *priv, int_32 drift)
{
	int_32  atcor_value;
	uint_32 atinc_tmp;
	int_8   inc;

	if(drift != 0) {
        /* Correction counter wrap-around value calculation */
        atcor_value = ((int_32)MACNET_1588_CLOCK_SRC)/drift;
        if(atcor_value == 0) {
            /* Drift is greater than the 1588 source clock;
	           the correction increment should be applied every tic of the 1588 timer
	           to speed up/slow very rapidly */
	        priv->MACNET_PTR->ATCOR  = ENET_ATCOR_COR(1);

            /* Calculate the correction increment to slow/speed up the clock
               more than +-1 per one tick */
            inc = MACNET_1588_CLOCK_INC + (drift/(int_32)MACNET_1588_CLOCK_SRC);
            if(inc<0)
                inc = 0;
            if(inc>(ENET_ATINC_INC_CORR_MASK>>ENET_ATINC_INC_CORR_SHIFT))
                inc = (ENET_ATINC_INC_CORR_MASK>>ENET_ATINC_INC_CORR_SHIFT);
            atinc_tmp = (priv->MACNET_PTR->ATINC) & (~ENET_ATINC_INC_CORR_MASK);
            priv->MACNET_PTR->ATINC = atinc_tmp | ENET_ATINC_INC_CORR(inc);
        } else {
	        /* Drift is less than the 1588 source clock;
	           the correction increment should be applied once per atcor_value tics
	           of the 1588 timer */
	        if(atcor_value > 0) {
	            priv->MACNET_PTR->ATCOR  = ENET_ATCOR_COR(atcor_value);
	            atinc_tmp = (priv->MACNET_PTR->ATINC) & (~ENET_ATINC_INC_CORR_MASK);
	            priv->MACNET_PTR->ATINC = atinc_tmp | ENET_ATINC_INC_CORR(MACNET_1588_CLOCK_INC+1);
	        } else {
	            priv->MACNET_PTR->ATCOR  = ENET_ATCOR_COR(-atcor_value);
	            atinc_tmp = (priv->MACNET_PTR->ATINC) & (~ENET_ATINC_INC_CORR_MASK);
	            priv->MACNET_PTR->ATINC = atinc_tmp | ENET_ATINC_INC_CORR(MACNET_1588_CLOCK_INC-1);
	        }
        }
	} else {
	    /* Clock drift is reset */
	    priv->MACNET_PTR->ATCOR  = ENET_ATCOR_COR(0);
	    atinc_tmp = (priv->MACNET_PTR->ATINC) & (~ENET_ATINC_INC_CORR_MASK);
	    priv->MACNET_PTR->ATINC = atinc_tmp | ENET_ATINC_INC_CORR(MACNET_1588_CLOCK_INC);
	}
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_store_txstamp
*  Returned Value :
*  Comments       : This interrupt service routine stores the captured
*                   tx timestamp in the MACNET context structure
*
*END*-----------------------------------------------------------------*/
void MACNET_ptp_store_txstamp
   (
         /* [IN] the Ethernet state structure */
      pointer  enet
   )
{ /* Body */

   ENET_CONTEXT_STRUCT_PTR    enet_ptr = (ENET_CONTEXT_STRUCT_PTR)enet;
   MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   ENET_MemMapPtr             macnet_ptr= macnet_context_ptr->MACNET_ADDRESS;
   uint_32                    events, master_macnet_events;
   ENET_MemMapPtr             master_macnet_ptr;
   MACNET_PTP_TIME            curr_time;

   if (macnet_ptr == NULL)
       return;

   events = macnet_ptr->EIR;
   while (events & ENET_EIR_TS_AVAIL_MASK) {

      /* Clear the TS_AVAIL interrupt */
      macnet_ptr->EIR = ENET_EIR_TS_AVAIL_MASK;

      /* Store nanoseconds */
      macnet_context_ptr->PTP_PRIV->TXSTAMP.NSEC = macnet_ptr->ATSTMP;

      /* Store seconds, correct/avoid seconds incrementation when timestamp
         captured at the edge between two seconds (nanoseconds counter overflow) */
      if(MACNET_PTP_set_rtc_time_flag == FALSE) {
          master_macnet_ptr = MACNET_ptp_get_master_base_address();
          MACNET_int_disable();
          MACNET_ptp_get_curr_cnt(master_macnet_ptr, &curr_time);
          master_macnet_events = master_macnet_ptr->EIR;
          if(curr_time.NSEC > macnet_context_ptr->PTP_PRIV->TXSTAMP.NSEC)
              macnet_context_ptr->PTP_PRIV->TXSTAMP.SEC  = MACNET_PTP_seconds;
          else if(master_macnet_events & ENET_EIR_TS_TIMER_MASK)
              macnet_context_ptr->PTP_PRIV->TXSTAMP.SEC  = MACNET_PTP_seconds;
          else
              macnet_context_ptr->PTP_PRIV->TXSTAMP.SEC  = MACNET_PTP_seconds - 1;
          MACNET_int_enable();
      } else {
          /* Do not check nanoseconds counter overflow in case MACNET_PTP_SET_RTC_TIME ioctl was called */
          macnet_context_ptr->PTP_PRIV->TXSTAMP.SEC  = MACNET_PTP_seconds;
          MACNET_PTP_set_rtc_time_flag = FALSE;
      }

      _lwevent_set(&(macnet_context_ptr->PTP_PRIV->LWEVENT_PTP), MACNET_PTP_LWEVENT_TX_TS_INTR);

      events = macnet_ptr->EIR;
   }
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_store_rxstamp
*  Returned Value :
*  Comments       : This routine is called from the MACNET RX ISR
*                   to store the captured rx timestamp
*                   in the adequate ring buffer
*END*-----------------------------------------------------------------*/
void MACNET_ptp_store_rxstamp(ENET_CONTEXT_STRUCT_PTR enet_ptr, PCB_PTR pcb_ptr, VENET_BD_STRUCT_PTR bdp)
{
	MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
	MACNET_PTP_PRIVATE         *priv = (MACNET_PTP_PRIVATE_PTR)macnet_context_ptr->PTP_PRIV;
	uint_32                    msg_type, control, index, master_macnet_events;
	MACNET_PTP_DATA            tmp_rx_time;
	boolean                    ptp_msg_received = FALSE;
    ENET_MemMapPtr             master_macnet_ptr;
    MACNET_PTP_TIME            curr_time;
    uchar_ptr                  skb = pcb_ptr->FRAG[0].FRAGMENT;
    uint_16                    chksum, len, num_added_bytes = HOST_TO_BE_SHORT_CONST(sizeof(MACNET_PTP_TIME));

	/* PTP over Ethernet: Check the PTPv2 over Ethernet type (identifier) */
	if (*(uint_16 *)(skb + MACNET_PTP_ETHER_PKT_TYPE_OFFS) == HOST_TO_BE_SHORT_CONST(MACNET_PACKET_TYPE_IEEE_802_3)) {
		tmp_rx_time.KEY = HOST_TO_BE_SHORT(*((uint_16 *)(skb + MACNET_PTP_ETHER_SEQ_ID_OFFS)));
        for(index=0;index<MACNET_PTP_CLOCKID_SIZE;index++)
            tmp_rx_time.CLOCKID[index] = *((uint_8 *)(skb + MACNET_PTP_ETHER_CLOCKID + index));
        control = *((uint_8 *)(skb + MACNET_PTP_ETHER_CTRL_OFFS));
	    msg_type = (*((uint_8 *)(skb + MACNET_PTP_ETHER_MSG_TYPE_OFFS))) & 0x0F;
        ptp_msg_received = TRUE;
    }
	/* PTP over UDP: Check if port is 319 for PTP Event, and check for UDP */
	else if (((*((uint_16 *)(skb + MACNET_PTP_UDP_PORT_OFFS))) == HOST_TO_BE_SHORT_CONST(MACNET_PTP_EVNT_PORT)) &&
	    (*(uchar_ptr)(skb + MACNET_PTP_UDP_PKT_TYPE_OFFS) == MACNET_PACKET_TYPE_UDP)) {
		tmp_rx_time.KEY = HOST_TO_BE_SHORT(*((uint_16 *)(skb + MACNET_PTP_UDP_SEQ_ID_OFFS)));
        for(index=0;index<MACNET_PTP_CLOCKID_SIZE;index++)
            tmp_rx_time.CLOCKID[index] = *((uint_8 *)(skb + MACNET_PTP_UDP_CLOCKID + index));
        control = *((uint_8 *)(skb + MACNET_PTP_UDP_CTRL_OFFS));
        msg_type = (*((uint_8 *)(skb + MACNET_PTP_UDP_MSG_TYPE_OFFS))) & 0x0F;
        ptp_msg_received = TRUE;
    }

    if(ptp_msg_received == TRUE) {
		/* Store nanoseconds */
		tmp_rx_time.TS_TIME.NSEC = LONG_BE_TO_HOST((uint_32)(bdp->TIMESTAMP));

		/* Store seconds, correct/avoid seconds incrementation when timestamp
           captured at the edge between two seconds (nanoseconds counter overflow) */
        if(MACNET_PTP_set_rtc_time_flag == FALSE) {
            master_macnet_ptr = MACNET_ptp_get_master_base_address();
            MACNET_int_disable();
            MACNET_ptp_get_curr_cnt(master_macnet_ptr, &curr_time);
            master_macnet_events = master_macnet_ptr->EIR;
            if(curr_time.NSEC > tmp_rx_time.TS_TIME.NSEC)
                tmp_rx_time.TS_TIME.SEC = MACNET_PTP_seconds;
            else if(master_macnet_events & ENET_EIR_TS_TIMER_MASK)
                tmp_rx_time.TS_TIME.SEC = MACNET_PTP_seconds;
            else
                tmp_rx_time.TS_TIME.SEC = MACNET_PTP_seconds - 1;
            MACNET_int_enable();
        } else {
            /* Do not check nanoseconds counter overflow in case MACNET_PTP_SET_RTC_TIME ioctl was called */
            tmp_rx_time.TS_TIME.SEC = MACNET_PTP_seconds;
            MACNET_PTP_set_rtc_time_flag = FALSE;
        }

		/* In INBAND mode, append the timestamp to the packet */
		if(enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_INBAND) {
		    /* Enlarge the msg. */
		    pcb_ptr->FRAG[0].LENGTH += sizeof(MACNET_PTP_TIME);

		    /* Copy timestamp at the end of the msg. */
#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
		    _mem_copy( &tmp_rx_time.TS_TIME, (pointer)(pcb_ptr->FRAG[0].FRAGMENT + MACNET_PTP_EVENT_MSG_FRAME_SIZE + MACNET_PTP_INBAND_SEC_OFFS), sizeof(MACNET_PTP_TIME) );
#else
		    *(uint_64 *)(pcb_ptr->FRAG[0].FRAGMENT + MACNET_PTP_EVENT_MSG_FRAME_SIZE + MACNET_PTP_INBAND_SEC_OFFS) = MACNET_ptp_swap8bytes(tmp_rx_time.TS_TIME.SEC);
		    *(uint_32 *)(pcb_ptr->FRAG[0].FRAGMENT + MACNET_PTP_EVENT_MSG_FRAME_SIZE + MACNET_PTP_INBAND_NANOSEC_OFFS	) = HOST_TO_BE_LONG(tmp_rx_time.TS_TIME.NSEC);
#endif
		    /* Change the lenght field in the IP header */
		    len = HOST_TO_BE_SHORT(*(uint_16 *)(skb + MACNET_PTP_UDP_IPLENGHT_OFFS));
		    len += sizeof(MACNET_PTP_TIME);
		    *(uint_16 *)(skb + MACNET_PTP_UDP_IPLENGHT_OFFS) = HOST_TO_BE_SHORT(len);
		    /* Correct the IP header checksum */
		    chksum = HOST_TO_BE_SHORT(*(uint_16 *)(skb + MACNET_PTP_UDP_IPCHECKSUM_OFFS));
		    chksum = (((chksum) == 0xFFFF) ? (chksum) : ~(chksum) & 0xFFFF);
		    chksum = _mem_sum_ip(chksum, sizeof(uint_16), &num_added_bytes);
		    chksum = (((chksum) == 0xFFFF) ? (chksum) : ~(chksum) & 0xFFFF);
		    *(uint_16 *)(skb + MACNET_PTP_UDP_IPCHECKSUM_OFFS) = HOST_TO_BE_SHORT(chksum);

		    /* Change the lenght field in the UDP header */
		    len = HOST_TO_BE_SHORT(*(uint_16 *)(skb + MACNET_PTP_UDP_UDPLENGHT_OFFS));
		    len += sizeof(MACNET_PTP_TIME);
		    *(uint_16 *)(skb + MACNET_PTP_UDP_UDPLENGHT_OFFS) = HOST_TO_BE_SHORT(len);
		    /* Correct the UDP header checksum */
		    chksum = HOST_TO_BE_SHORT(*(uint_16 *)(skb + MACNET_PTP_UDP_UDPCHECKSUM_OFFS));
		    chksum = (((chksum) == 0xFFFF) ? (chksum) : ~(chksum) & 0xFFFF);
		    chksum = _mem_sum_ip(chksum, sizeof(MACNET_PTP_TIME), (pcb_ptr->FRAG[0].FRAGMENT + MACNET_PTP_EVENT_MSG_FRAME_SIZE + MACNET_PTP_INBAND_SEC_OFFS));
		    chksum = _mem_sum_ip(chksum, sizeof(uint_16), &num_added_bytes);
		    chksum = _mem_sum_ip(chksum, sizeof(uint_16), &num_added_bytes);
		    chksum = (((chksum) == 0xFFFF) ? (chksum) : ~(chksum) & 0xFFFF);
		    *(uint_16 *)(skb + MACNET_PTP_UDP_UDPCHECKSUM_OFFS) = HOST_TO_BE_SHORT(chksum);
		} else {
		/* In OUTBAND mode, store the captured rx timestamp in the adequate ring buffer */
    		switch (control) {

    		case MACNET_PTP_MSG_SYNC:
    			MACNET_ptp_insert(&(priv->RX_TIME_SYNC), &tmp_rx_time);
    			break;

    		case MACNET_PTP_MSG_DEL_REQ:
    			MACNET_ptp_insert(&(priv->RX_TIME_DEL_REQ), &tmp_rx_time);
    			break;

    		case MACNET_PTP_MSG_ALL_OTHER:
    			switch (msg_type) {
    			case MACNET_PTP_MSG_P_DEL_REQ:
    				MACNET_ptp_insert(&(priv->RX_TIME_PDEL_REQ), &tmp_rx_time);
    				break;
    			case MACNET_PTP_MSG_P_DEL_RESP:
    				MACNET_ptp_insert(&(priv->RX_TIME_PDEL_RESP), &tmp_rx_time);
    				break;
    			default:
    				break;
    			}
    			break;
    		default:
    			break;
    		}
        }
	}
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_get_tx_timestamp
*  Returned Value :
*  Comments       : Returns tx timestamp of the message with the specific
*                   sequence ID and source clock ID
*
*END*-----------------------------------------------------------------*/
int_32 MACNET_ptp_get_tx_timestamp(MACNET_PTP_PRIVATE *priv,  pointer param_ptr,
                                   MACNET_PTP_TIME *tx_time)
{
	MACNET_PTP_DATA tmp;

	if(ENET_OK == MACNET_ptp_find_and_remove(&(priv->TX_TIME),
	                                         ((MACNET_PTP_TS_DATA *)param_ptr)->SEQ_ID,
	                                         &((MACNET_PTP_TS_DATA *)param_ptr)->SPID[0],
	                                         &tmp)) {

        tx_time->SEC = tmp.TS_TIME.SEC;
        tx_time->NSEC = tmp.TS_TIME.NSEC;
        return ENET_OK;
	} else {
	    return ENET_ERROR;
	}
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_get_rx_timestamp
*  Returned Value :
*  Comments       : Returns rx timestamp of the message with the specific
*                   sequence ID and source clock ID
*
*
*END*-----------------------------------------------------------------*/
int_32 MACNET_ptp_get_rx_timestamp(MACNET_PTP_PRIVATE *priv, pointer param_ptr,
		                           MACNET_PTP_TIME *rx_time)
{
	MACNET_PTP_DATA tmp;
	int_32  error;

	switch (((MACNET_PTP_TS_DATA *)param_ptr)->MESSAGE_TYPE) {
	case MACNET_PTP_RX_TIMESTAMP_SYNC:
		error = MACNET_ptp_find_and_remove(&(priv->RX_TIME_SYNC),
		                                   ((MACNET_PTP_TS_DATA *)param_ptr)->SEQ_ID,
		                                   &((MACNET_PTP_TS_DATA *)param_ptr)->SPID[0],
		                                   &tmp);
		break;
	case MACNET_PTP_RX_TIMESTAMP_DEL_REQ:
		error = MACNET_ptp_find_and_remove(&(priv->RX_TIME_DEL_REQ),
		                                   ((MACNET_PTP_TS_DATA *)param_ptr)->SEQ_ID,
		                                   &((MACNET_PTP_TS_DATA *)param_ptr)->SPID[0],
		                                   &tmp);
		break;

	case MACNET_PTP_RX_TIMESTAMP_PDELAY_REQ:
		error = MACNET_ptp_find_and_remove(&(priv->RX_TIME_PDEL_REQ),
		                                   ((MACNET_PTP_TS_DATA *)param_ptr)->SEQ_ID,
		                                   &((MACNET_PTP_TS_DATA *)param_ptr)->SPID[0],
		                                   &tmp);
		break;
	case MACNET_PTP_RX_TIMESTAMP_PDELAY_RESP:
		error = MACNET_ptp_find_and_remove(&(priv->RX_TIME_PDEL_RESP),
		                                   ((MACNET_PTP_TS_DATA *)param_ptr)->SEQ_ID,
		                                   &((MACNET_PTP_TS_DATA *)param_ptr)->SPID[0],
		                                   &tmp);
		break;

	default:
		error = ENET_ERROR;
		break;
	}

	if (error==ENET_OK) {
		rx_time->SEC = tmp.TS_TIME.SEC;
		rx_time->NSEC = tmp.TS_TIME.NSEC;
		return ENET_OK;
	} else {
		return error;
	}
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : MACNET_ptp_L2queue_init
* Returned Value : -
* Comments       : Initialize the queue for PTP-Ethernet packets
*
*END*-----------------------------------------------------------------*/
static void MACNET_ptp_L2queue_init(MACNET_PTP_L2QUEUE *ps_queue)
{
    uint_32 slot;
    ps_queue->WR_IDX = 0;
    ps_queue->RD_IDX = 0;
    for (slot = 0; slot < MACNET_PTP_DEFAULT_L2PCK_BUF_SZ; slot ++) {
        ps_queue->L2PCK[slot].LENGTH = 0;
    }
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : MACNET_ptp_L2queue_is_empty
* Returned Value : -
* Comments       : Checks if the queue is empty
*
*END*-----------------------------------------------------------------*/
static boolean MACNET_ptp_L2queue_is_empty(const MACNET_PTP_L2QUEUE *ps_queue)
{
    if (ps_queue->WR_IDX == ps_queue->RD_IDX) {
        return TRUE;
    }
    return FALSE;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : MACNET_ptp_L2queue_add_packet
* Returned Value : -
* Comments       : Insert the PTP-Ethernet packet to the queue
*
*END*-----------------------------------------------------------------*/
static void MACNET_ptp_L2queue_add_packet(MACNET_PTP_L2QUEUE *ps_queue,
                                          const uint_8 *pb_buf,
                                          uint_16 len)
{
    if (ps_queue->L2PCK[ps_queue->WR_IDX].LENGTH != 0) {
      /* No free slots in the queue */
        return;
    }

    /* Store the packet */
    ps_queue->L2PCK[ps_queue->WR_IDX].LENGTH = len;
    _mem_copy((pointer)pb_buf, (pointer)ps_queue->L2PCK[ps_queue->WR_IDX].PACKET, len);

    /* Get the next queue slot to write */
    ps_queue->WR_IDX = (ps_queue->WR_IDX + 1) % MACNET_PTP_DEFAULT_L2PCK_BUF_SZ;

    return;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : MACNET_ptp_L2queue_get_packet
* Returned Value : -
* Comments       : Gets the PTP-Ethernet packet from the queue
*
*END*-----------------------------------------------------------------*/
static boolean MACNET_ptp_L2queue_get_packet(MACNET_PTP_L2QUEUE *ps_queue,
                                             uint_8  *pb_buf,
                                             uint_16 *pLENGTH)
{
    boolean ret_val = FALSE;

    /* Check queue argument */
    if( ps_queue == NULL ) {
        return FALSE;
    }

    /* Disable MACNET interrupts in order to avoid buffer data overwrite */
    MACNET_int_disable();

    /* check queue empty */
    if(MACNET_ptp_L2queue_is_empty(ps_queue)) {
        ret_val = FALSE;
    } else {
        /* Get the packet */
        *pLENGTH = ps_queue->L2PCK[ps_queue->RD_IDX].LENGTH;
        _mem_copy((pointer)ps_queue->L2PCK[ps_queue->RD_IDX].PACKET, (pointer)pb_buf, *pLENGTH);

        /* Clear the queue slot */
        ps_queue->L2PCK[ps_queue->RD_IDX].LENGTH = 0;

        /* Get the next queue slot to read */
        ps_queue->RD_IDX = (ps_queue->RD_IDX + 1) % MACNET_PTP_DEFAULT_L2PCK_BUF_SZ;

        ret_val = TRUE;
    }

    MACNET_int_enable();

    return ret_val;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : MACNET_ptp_free_pcb
* Returned Value : -
* Comments       : This function enqueues the PCB allocated when seding
*                  layer2 packets (0x88F7 identifier).
*
*END*-----------------------------------------------------------------*/
static void MACNET_ptp_free_pcb
   (
         /* [IN] the PCB to enqueue */
      PCB_PTR  pcb_ptr
   )
{
   _mem_free((pointer)pcb_ptr);
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : MACNET_ptp_service_L2pckts
* Returned Value : -
* Comments       : This is the callback function for Ethernet 1588
*                  layer2 packets (0x88F7 identifier). It adds the
*                  PTP-Ethernet packet to the queue.
*
*END*-----------------------------------------------------------------*/
void MACNET_ptp_service_L2pckts
   (
      PCB_PTR  pcb,
         /* [IN] the received packet */
      pointer  handle
         /* [IN] the IP interface structure */
   )
{
    ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR) handle;
    MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR)enet_ptr->MAC_CONTEXT_PTR;
    MACNET_PTP_PRIVATE_PTR priv = macnet_context_ptr->PTP_PRIV;

    MACNET_ptp_L2queue_add_packet(priv->L2PCKS_PTR, pcb->FRAG[0].FRAGMENT, pcb->FRAG[0].LENGTH);

    PCB_free(pcb);
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : MACNET_ptp_send_L2pckts
* Returned Value : -
* Comments       : Sends PTP-Ethernet packets.
*
*END*-----------------------------------------------------------------*/
int_32 MACNET_ptp_send_L2pckts(_enet_handle handle, pointer param_ptr)
{
    PCB_PTR     pcb_ptr;
    uchar_ptr   mem_ptr;
    ENET_HEADER_PTR  packet_ptr;
    uint_16     len;

    len = ((MACNET_PTP_ETHERTYPE_PCK *)param_ptr)->LENGTH;

    /* Allocate memory */
    mem_ptr = _mem_alloc_system_zero(sizeof(PCB)+sizeof(PCB_FRAGMENT)+sizeof(ENET_HEADER)+len);
    if (mem_ptr==NULL) {
       return (ENETERR_ALLOC_PCB);
    }
    pcb_ptr = (PCB_PTR) mem_ptr;
    packet_ptr = (ENET_HEADER_PTR)&mem_ptr[sizeof(PCB)+sizeof(PCB_FRAGMENT)];

    /* Ethernet msg. header */
    htone(packet_ptr->DEST, ((MACNET_PTP_ETHERTYPE_PCK *)param_ptr)->DEST_MAC);
    htone(packet_ptr->SOURCE, ((ENET_CONTEXT_STRUCT_PTR)handle)->ADDRESS);
    htons(packet_ptr->TYPE, MQX1588_PTP_ETHERTYPE_1588);

    /* Payload */
    _mem_copy( (pointer)(((MACNET_PTP_ETHERTYPE_PCK *)param_ptr)->PTP_MSG), (pointer)&mem_ptr[sizeof(PCB)+sizeof(PCB_FRAGMENT)+sizeof(ENET_HEADER)], len );

    pcb_ptr->FREE = MACNET_ptp_free_pcb;
    pcb_ptr->FRAG[0].LENGTH = sizeof(ENET_HEADER) + len;
    pcb_ptr->FRAG[0].FRAGMENT = (uchar_ptr)packet_ptr;

    return(ENET_send_raw((ENET_CONTEXT_STRUCT_PTR)handle, pcb_ptr));
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : MACNET_ptp_recv_L2pckts
* Returned Value : -
* Comments       : Withdraw the PTP-Ethernet packets from the queue.
*
*END*-----------------------------------------------------------------*/
int_32 MACNET_ptp_recv_L2pckts(_enet_handle handle, pointer param_ptr)
{
    ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR) handle;
    MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR)enet_ptr->MAC_CONTEXT_PTR;
    MACNET_PTP_PRIVATE_PTR priv = macnet_context_ptr->PTP_PRIV;

    if (FALSE == MACNET_ptp_L2queue_get_packet(priv->L2PCKS_PTR,
                                               ((MACNET_PTP_ETHERTYPE_PCK *)param_ptr)->PTP_MSG,
                                               &((MACNET_PTP_ETHERTYPE_PCK *)param_ptr)->LENGTH)) {
        return ENET_ERROR;
    }
    eaddrcpy(((MACNET_PTP_ETHERTYPE_PCK *)param_ptr)->DEST_MAC, enet_ptr->ADDRESS);
    return ENET_OK;
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MACNET_ptp_ioctl
*  Returned Value :
*  Comments       :
*
*
*END*-----------------------------------------------------------------*/
uint_32 MACNET_ptp_ioctl(ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 command_id, pointer inout_param)
{
    MACNET_CONTEXT_STRUCT_PTR  macnet_context_ptr = (MACNET_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
    MACNET_PTP_PRIVATE *priv = macnet_context_ptr->PTP_PRIV;
    MACNET_PTP_TIME *cnt;
    MACNET_PTP_TIME rx_time, tx_time, curr_time;
    ENET_MemMapPtr master_macnet_ptr;
    int_32 retval = ENET_OK;

    master_macnet_ptr = MACNET_ptp_get_master_base_address();
    switch (command_id) {

    case MACNET_PTP_GET_RX_TIMESTAMP:
        /* Do not read rx timestamps from buffers in the inbound mode */
        if(enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_INBAND) {
            retval = ENET_ERROR;
            break;
        }
        retval = MACNET_ptp_get_rx_timestamp(priv, inout_param, &rx_time);
        if (retval == ENET_OK)
            ((MACNET_PTP_TS_DATA *)inout_param)->TS = rx_time;
    break;

    case MACNET_PTP_GET_TX_TIMESTAMP:
        retval = MACNET_ptp_get_tx_timestamp(priv, inout_param, &tx_time);
        if (retval == ENET_OK)
            ((MACNET_PTP_TS_DATA *)inout_param)->TS = tx_time;
    break;

    case MACNET_PTP_GET_CURRENT_TIME:
        MACNET_ptp_get_curr_cnt(master_macnet_ptr, &curr_time);
        ((MACNET_PTP_RTC_TIME *)inout_param)->RTC_TIME = curr_time;
    break;

    case MACNET_PTP_SET_RTC_TIME:
        cnt = &(((MACNET_PTP_RTC_TIME *)inout_param)->RTC_TIME);
        MACNET_ptp_set_1588cnt(master_macnet_ptr, cnt);
    break;

    case MACNET_PTP_FLUSH_TIMESTAMP:
        /* reset sync buffer */
        priv->RX_TIME_SYNC.FRONT = 0;
        priv->RX_TIME_SYNC.END = 0;
        priv->RX_TIME_SYNC.SIZE = (MACNET_PTP_DEFAULT_RX_BUF_SZ + 1);
        /* reset delay_req buffer */
        priv->RX_TIME_DEL_REQ.FRONT = 0;
        priv->RX_TIME_DEL_REQ.END = 0;
        priv->RX_TIME_DEL_REQ.SIZE = (MACNET_PTP_DEFAULT_RX_BUF_SZ + 1);
        /* reset pdelay_req buffer */
        priv->RX_TIME_PDEL_REQ.FRONT = 0;
        priv->RX_TIME_PDEL_REQ.END = 0;
        priv->RX_TIME_PDEL_REQ.SIZE = (MACNET_PTP_DEFAULT_RX_BUF_SZ + 1);
        /* reset pdelay_resp buffer */
        priv->RX_TIME_PDEL_RESP.FRONT = 0;
        priv->RX_TIME_PDEL_RESP.END = 0;
        priv->RX_TIME_PDEL_RESP.SIZE = (MACNET_PTP_DEFAULT_RX_BUF_SZ + 1);
    break;

    case MACNET_PTP_SET_COMPENSATION:
        MACNET_ptp_set_correction(priv, ((MACNET_PTP_SET_COMP *)inout_param)->DRIFT);
    break;

    case MACNET_PTP_GET_ORIG_COMP:
    break;

    case MACNET_PTP_REGISTER_ETHERTYPE_PTPV2:
        /* Registers the PTPV2 protocol type on an Ethernet channel */
        retval = ENET_open(enet_ptr, MQX1588_PTP_ETHERTYPE_1588, MACNET_ptp_service_L2pckts, enet_ptr);
        /* Allocate the queue for this type of messages */
        priv->L2PCKS_PTR = (MACNET_PTP_L2QUEUE_PTR) _mem_alloc_system_zero(sizeof(MACNET_PTP_L2QUEUE));
        MACNET_ptp_L2queue_init(priv->L2PCKS_PTR);
    break;

    case MACNET_PTP_UNREGISTER_ETHERTYPE_PTPV2:
        /* Un-registers the PTPV2 protocol type on an Ethernet channel */
        retval = ENET_close(enet_ptr, MQX1588_PTP_ETHERTYPE_1588);
        /* Free the queue for this type of messages */
        _mem_free(priv->L2PCKS_PTR);
    break;

    case MACNET_PTP_SEND_ETHERTYPE_PTPV2_PCK:
        retval = MACNET_ptp_send_L2pckts(enet_ptr, inout_param);
    break;

    case MACNET_PTP_RECV_ETHERTYPE_PTPV2_PCK:
        retval = MACNET_ptp_recv_L2pckts(enet_ptr, inout_param);
    break;
    case MACNET_PTP_IS_IN_INBAND_MODE:
        if(enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_INBAND) {
            *(uint_8*)inout_param = TRUE;
        } else {
            *(uint_8*)inout_param = FALSE;
        }
    break;
    default:
        return IO_ERROR_INVALID_IOCTL_CMD;
    }
    return retval;
}
#endif /* ENETCFG_SUPPORT_PTP */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/TSI_PDD.h<|end_filename|>
/* TSI PDD methods implementation file
 This file is static*/

#ifndef _TSI_PDD_H_
#define _TSI_PDD_H

/* --------------------------------------------------------------- */
/* --------- Test of support of active MCU */
/* --------------------------------------------------------------- */

/* Check if any supported MCU is active */
#if !defined(MCU_ACTIVE)
  /* No MCU is active */
  #error TSI PDD library: No derivative is active. Place proper #include "*_MCU.h" before including PDD library.
#endif

#include "PDD_Types.h"

/* ---------------------------------------------------------------
 --------- Type definitions
 --------------------------------------------------------------*/
/* PDD macro definitions*/

/* ---------------------------------------------------------------
// --------- EnableDevice
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_EnableDevice(Base) ( \
    setReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_TSIEN_MASK) \
  )

/* ---------------------------------------------------------------
// --------- DisableDevice
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_DisableDevice(Base) ( \
    clrReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_TSIEN_MASK) \
  )

/* ---------------------------------------------------------------
// --------- IsDeviceEnabled
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_IsDeviceEnabled(Base) ( \
    testReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_TSIEN_MASK) \
  )

/* ---------------------------------------------------------------
// --------- SetMask
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_SetMask(Base, mask) ( \
    clrSetReg32Bits(TSI_GENCS_REG(Base), TSI_AVAILABLE_INTERRUPT_MASK, mask) \
  )

/* ---------------------------------------------------------------
// --------- GetMask
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_GetMask(Base) ( \
    getReg32(TSI_GENCS_REG(Base)) & TSI_AVAILABLE_INTERRUPT_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_ScanMode
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_ScanMode(Base, mode) ( \
  clrSetReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_STM_MASK, mode) \
  )

/* ---------------------------------------------------------------
// --------- Get_ScanMode
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_ScanMode(Base) ( \
    getReg32(TSI_GENCS_REG(Base)) & TSI_GENCS_STM_MASK \
  )

/* ---------------------------------------------------------------
// --------- Stop_Enable
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Stop_Enable(Base) ( \
    setReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_STPE_MASK) \
  )

/* ---------------------------------------------------------------
// --------- Stop_Disable
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Stop_Disable(Base) ( \
    clrReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_STPE_MASK) \
  )

/* ---------------------------------------------------------------
// --------- GetInterruptFlags
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_GetInterruptFlags(Base) ( \
    getReg32(TSI_GENCS_REG(Base)) & TSI_AVAILABLE_FLAGS_MASK \
  )

/* ---------------------------------------------------------------
// --------- ClearInterruptFlags
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_ClearInterruptFlags(Base, mask) ( \
    setReg32Bits(TSI_GENCS_REG(Base), mask) \
  )

/* ---------------------------------------------------------------
// --------- IsScanInProgress
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_IsScanInProgress(Base) ( \
    getReg32(TSI_GENCS_REG(Base)) &  TSI_GENCS_SCNIP_MASK \
  )

/* ---------------------------------------------------------------
// --------- SoftwareTrigger
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_SoftwareTrigger(Base) ( \
    setReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_SWTS_MASK) \
  )

/* ---------------------------------------------------------------
// --------- Set_NumScansPerElectrode
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_NumScansPerElectrode(Base, scans) ( \
    clrSetReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_NSCN_MASK, scans) \
  )

/* ---------------------------------------------------------------
// --------- Get_NumScansPerElectrode
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_NumScansPerElectrode(Base) ( \
    getReg32(TSI_GENCS_REG(Base)) & TSI_GENCS_NSCN_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_ElectrodePrescaler
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_ElectrodePrescaler(Base, divider) ( \
    clrSetReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_PS_MASK, divider) \
  )

/* ---------------------------------------------------------------
// --------- Get_ElectrodePrescaler
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_ElectrodePrescaler(Base) ( \
    getReg32(TSI_GENCS_REG(Base)) & TSI_GENCS_PS_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_LPM_Clock
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_LPM_Clock(Base, clock) ( \
    clrSetReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_LPCLKS_MASK, clock) \
  )

/* ---------------------------------------------------------------
// --------- Get_LPM_Clock
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_LPM_Clock(Base) ( \
    getReg32(TSI_GENCS_REG(Base)) & TSI_GENCS_LPCLKS_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_LPM_ScanInterval
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_LPM_ScanInterval(Base, interval) ( \
    clrSetReg32Bits(TSI_GENCS_REG(Base), TSI_GENCS_LPSCNITV_MASK, interval) \
  )

/* ---------------------------------------------------------------
// --------- Get_LPM_ScanInterval
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_LPM_ScanInterval(Base) ( \
    getReg32(TSI_GENCS_REG(Base)) & TSI_GENCS_LPSCNITV_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_LPM_ScanPinSelection
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_LPM_ScanPinSelection(Base, pin) ( \
    clrSetReg32Bits(TSI_PEN_REG(Base), TSI_PEN_LPSP_MASK, pin) \
  )

/* ---------------------------------------------------------------
// --------- Get_LPM_ScanPinSelection
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_LPM_ScanPinSelection(Base) ( \
    getReg32(TSI_PEN_REG(Base)) & TSI_PEN_LPSP_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_ClockDivider
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_ClockDivider(Base, div) ( \
    clrSetReg32Bits(TSI_SCANC_REG(Base), TSI_SCANC_AMCLKDIV_MASK, div) \
  )

/* ---------------------------------------------------------------
// --------- Get_ClockDivider
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_ClockDivider(Base) ( \
    getReg32(TSI_SCANC_REG(Base)) & TSI_SCANC_AMCLKDIV_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_ClockSource
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_ClockSource(Base, source) ( \
    clrSetReg32Bits(TSI_SCANC_REG(Base), TSI_SCANC_AMCLKS_MASK, source) \
  )

/* ---------------------------------------------------------------
// --------- Get_ClockSource
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_ClockSource(Base) ( \
    getReg32(TSI_SCANC_REG(Base)) & TSI_SCANC_AMCLKS_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_Prescaler
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_Prescaler(Base, prescaler) ( \
    clrSetReg32Bits(TSI_SCANC_REG(Base), TSI_SCANC_AMPSC_MASK, prescaler) \
  )

/* ---------------------------------------------------------------
// --------- Get_Prescaler
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Prescaler(Base) ( \
    getReg32(TSI_SCANC_REG(Base)) & TSI_SCANC_AMPSC_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_ScanModule
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_ScanModule(Base, scan) ( \
    clrSetReg32Bits(TSI_SCANC_REG(Base), TSI_SCANC_SMOD_MASK, scan) \
  )

/* ---------------------------------------------------------------
// --------- Get_ScanModule
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_ScanModule(Base) ( \
    getReg32(TSI_SCANC_REG(Base)) & TSI_SCANC_SMOD_MASK \
  )

/* ---------------------------------------------------------------
// --------- Set_ExtOscChargeCurrent
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_ExtOscChargeCurrent(Base, current) ( \
    clrSetReg32Bits(TSI_SCANC_REG(Base), TSI_SCANC_EXTCHRG_MASK, current) \
  )

/* ---------------------------------------------------------------
// --------- Get_ExtOscChargeCurrent
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_ExtOscChargeCurrent(Base) ( \
    getReg32(TSI_SCANC_REG(Base)) & TSI_SCANC_EXTCHRG_MASK  \
  )

/* ---------------------------------------------------------------
// --------- Set_DeltaVoltage
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_DeltaVoltage(Base, delta) ( \
    clrSetReg32Bits(TSI_SCANC_REG(Base), TSI_SCANC_DELVOL_MASK, delta) \
  )

/* ---------------------------------------------------------------
// --------- Get_DeltaVoltage
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_DeltaVoltage(Base) ( \
    getReg32(TSI_SCANC_REG(Base)) & TSI_SCANC_DELVOL_MASK  \
  )

/* ---------------------------------------------------------------
// --------- Set_RefOscChargeCurrent
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_RefOscChargeCurrent(Base, current) ( \
    clrSetReg32Bits(TSI_SCANC_REG(Base), TSI_SCANC_REFCHRG_MASK, current) \
  )

/* ---------------------------------------------------------------
// --------- Get_RefOscChargeCurrent
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_RefOscChargeCurrent(Base) ( \
    getReg32(TSI_SCANC_REG(Base)) & TSI_SCANC_REFCHRG_MASK  \
  )

/* ---------------------------------------------------------------
// --------- Set_InternalCapacitance
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_InternalCapacitance(Base, farads) ( \
    clrSetReg32Bits(TSI_SCANC_REG(Base), TSI_SCANC_CAPTRM_MASK, farads) \
  )

/* ---------------------------------------------------------------
// --------- Get_InternalCapacitance
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_InternalCapacitance(Base) ( \
    getReg32(TSI_SCANC_REG(Base)) & TSI_SCANC_CAPTRM_MASK  \
  )

/* ---------------------------------------------------------------
// --------- Set_Pins
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_Pins(Base, pins_mask) ( \
    clrSetReg32Bits(TSI_PEN_REG(Base), TSI_PEN_PENX, pins_mask) \
  )

/* ---------------------------------------------------------------
// --------- Get_Pins
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Pins(Base) ( \
    getReg32(TSI_PEN_REG(Base)) & TSI_PEN_PENX  \
  )

/* ---------------------------------------------------------------
// --------- Clear_StatusFlags
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Clear_StatusFlags(Base, clear_mask) ( \
    setReg32Bits(TSI_STATUS_REG(Base), clear_mask) \
  )

/* ---------------------------------------------------------------
// --------- Get_StatusFlags
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_StatusFlags(Base) ( \
    getReg32(TSI_STATUS_REG(Base)) \
  )

/* ---------------------------------------------------------------
// --------- Get_Counter1Value
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Counter1Value(Base) ( \
    getReg32(TSI_CNTR1_REG(Base))  \
  )

/* ---------------------------------------------------------------
// --------- Get_Counter3Value
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Counter3Value(Base) ( \
    getReg32(TSI_CNTR3_REG(Base))  \
  )

/* ---------------------------------------------------------------
// --------- Get_Counter5Value
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Counter5Value(Base) ( \
    getReg32(TSI_CNTR5_REG(Base))  \
  )

/* ---------------------------------------------------------------
// --------- Get_Counter7Value
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Counter7Value(Base) ( \
    getReg32(TSI_CNTR7_REG(Base))  \
  )

/* ---------------------------------------------------------------
// --------- Get_Counter9Value
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Counter9Value(Base) ( \
    getReg32(TSI_CNTR9_REG(Base))  \
  )

/* ---------------------------------------------------------------
// --------- Get_Counter11Value
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Counter11Value(Base) ( \
    getReg32(TSI_CNTR11_REG(Base))  \
  )

/* ---------------------------------------------------------------
// --------- Get_Counter13Value
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Counter13Value(Base) ( \
    getReg32(TSI_CNTR13_REG(Base))  \
  )

/* ---------------------------------------------------------------
// --------- Get_Counter15Value
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Counter15Value(Base) ( \
    getReg32(TSI_CNTR15_REG(Base))  \
  )


/* ---------------------------------------------------------------
// --------- Set_Threshold
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Set_Threshold(Base, threshold, index) ( \
    setReg32(TSI_THRESHLD_REG(Base, index), threshold) \
  )

/* ---------------------------------------------------------------
// --------- Get_Threshold
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_Get_Threshold(Base, index) ( \
    getReg32(TSI_THRESHLD_REG(Base, index)) \
  )

/* ---------------------------------------------------------------
// --------- TSI_PDD_ClockGatingEnable
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_ClockGatingEnable(Base) ( \
    setReg32Bits(SIM_SCGC5_REG(Base), SIM_SCGC5_TSI_MASK) \
  )

/* ---------------------------------------------------------------
// --------- TSI_PDD_ClockGatingDisable
// ---------------------------------------------------------------
// Inputs are not checked (invalid value will cause undefined behavior).*/
#define TSI_PDD_ClockGatingDisable(Base) ( \
    clrReg32Bits(SIM_SCGC5_REG(Base), SIM_SCGC5_TSI_MASK) \
  )


#endif /* #if !defined(_TSI_PDD_H_) */

/* TSI_PDD.h, eof  */

<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd_wrapper.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd_wrapper.h$
* $Version : 3.7.4.0$
* $Date    : Mar-9-2011$
*
* Comments:
*
*   HTTPD wrapper for os specific functions.
*
*END************************************************************************/


#ifndef HTTPD_WRAPPER_H_
#define HTTPD_WRAPPER_H_

#include "httpd_mqx.h"

#ifndef HTTPD_MALLOC
#error HTTPD_MALLOC is not defined
#endif

#ifndef HTTPD_FREE
#error HTTPD_FREE is not defined
#endif

#ifndef HTTPD_TIME_GET
//#error HTTPD_TIME_GET is not defined
#endif

#ifndef HTTPD_SOCKET_INVALID
#error HTTPD_SOCKET_INVALID is not defined
#endif

#ifndef HTTP_MEMTYPE
#define HTTP_MEMTYPE(ptr,type)
#endif

#endif /* HTTPD_WRAPPER_H_ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/hmi_lwgpio_provider.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hmi_lwgpio_provider.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This header file is for HMI lwgpio provider. It contains  defines,
*   structures.
*
*END************************************************************************/
#ifndef __hmi_lwgpio_provider_h__
#define __hmi_lwgpio_provider_h__ 1

#include "hmi_provider.h"
#include "hmi_client.h"
#include "psptypes.h"
#include "mqx.h"
#include "bsp.h"

/* FLAG DEFINES */
#define HMI_LWGPIO_FLAG_DIRECTION_IN       (0x00000000)
#define HMI_LWGPIO_FLAG_DIRECTION_OUT      (0x00000001)
#define HMI_LWGPIO_FLAG_ACTIVE_STATE_0     (0x00000000)
#define HMI_LWGPIO_FLAG_ACTIVE_STATE_1     (0x00000002)
#define HMI_LWGPIO_FLAG_PULL_UP_OFF        (0x00000000)
#define HMI_LWGPIO_FLAG_PULL_UP_ON         (0x00000004)
#define HMI_LWGPIO_FLAG_PULL_DOWN_OFF      (0x00000000)
#define HMI_LWGPIO_FLAG_PULL_DOWN_ON       (0x00000008)
#define HMI_LWGPIO_FLAG_INT_OFF            (0x00000000)
#define HMI_LWGPIO_FLAG_INT_ON             (0x00000010)

/* GET FLAGS */
#define HMI_LWGPIO_GET_DIRECTION(x)        ((x)&0x1)
#define HMI_LWGPIO_GET_ACTIVE_STATE(x)     (((x)>>1)&0x1)
#define HMI_LWGPIO_GET_PULL_UP(x)          (((x)>>2)&0x1)
#define HMI_LWGPIO_GET_PULL_DOWN(x)        (((x)>>3)&0x1)
#define HMI_LWGPIO_GET_INT(x)              (((x)>>4)&0x1)

#define LWGPIO_PIN_FROM_ID(id)  (((id) & LWGPIO_PIN_MASK) >> LWGPIO_PIN_SHIFT)
#define LWGPIO_PORT_FROM_ID(id) (((id) & LWGPIO_PORT_MASK) >> LWGPIO_PORT_SHIFT)

/* LWGPIO INITIALIZATION STRUCTURE */
typedef struct hmi_lwgpio_init_struct
{
    uint_32 UID;                /* usage id */
    uint_32 PID;                /* pin id */
    uint_32 FUNC;               /* functionality of the pin */
    uint_32 FLAG;               /* polarity of the pin */
}HMI_LWGPIO_INIT_STRUCT, _PTR_ HMI_LWGPIO_INIT_STRUCT_PTR;

/* LWGPIO STRUCTURE */
typedef struct hmi_lwgpio_struct
{
    LWGPIO_VALUE            LAST_STATE;         /* last state */
    LWGPIO_STRUCT           HANDLE;             /* handle of LWGPIO */
    HMI_LWGPIO_INIT_STRUCT  INIT_STRUCT;        /* initialization struct */
    INT_ISR_FPTR            INIT_ISR;           /* pointer to ISR */
}HMI_LWGPIO_STRUCT, _PTR_ HMI_LWGPIO_STRUCT_PTR;

/* LWGPIO CONTEXT STRUCTURE */
typedef struct hmi_lwgpio_context_struct
{
    HMI_LWGPIO_STRUCT_PTR   BTNLED_TABLE;       /* btn led table */
    uint_32                 BTNLED_COUNT;       /* number of LWGPIO */
    HMI_CLIENT_STRUCT_PTR   CLIENT_HANDLE;
}HMI_LWGPIO_CONTEXT_STRUCT, _PTR_ HMI_LWGPIO_CONTEXT_STRUCT_PTR;


#ifdef __cplusplus
extern "C" {
#endif
HMI_PROVIDER_STRUCT_PTR hmi_lwgpio_provider_init(const HMI_LWGPIO_INIT_STRUCT _PTR_);
uint_32 hmi_lwgpio_provider_deinit(HMI_PROVIDER_STRUCT_PTR);
#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/gpio/io_gpio_prv.h<|end_filename|>
#ifndef __io_gpio_driver_h__
#define __io_gpio_driver_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_gpio_prv.h$
* $Version : 3.8.37.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions private to the gpio driver.
*
*END************************************************************************/

/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/

/* Internal functions to IO_GPIO */
#ifdef __cplusplus
extern "C" {
#endif

#if MQX_CPU == PSP_CPU_MCF5282
  #include "io_gpio_mcf5235_prv.h"
#elif PSP_MQX_CPU_IS_MCF5225X
  #include "io_gpio_mcf5225_prv.h"
#elif PSP_MQX_CPU_IS_MCF5227X
  #include "io_gpio_mcf5227_prv.h"
#elif PSP_MQX_CPU_IS_MCF51AC
  #include "io_gpio_mcf51ac_prv.h"   
#elif PSP_MQX_CPU_IS_MCF51JM
  #include "io_gpio_mcf51jm_prv.h"  
#elif PSP_MQX_CPU_IS_MCF51AG
  #include "io_gpio_mcf51ag_prv.h"  
#elif PSP_MQX_CPU_IS_MCF51CN
  #include "io_gpio_mcf51cn_prv.h"
#elif PSP_MQX_CPU_IS_MCF51EM
  #include "io_gpio_mcf51em_prv.h"
#elif PSP_MQX_CPU_IS_MCF51MM
  #include "io_gpio_mcf51mm_prv.h" 
#elif PSP_MQX_CPU_IS_MCF51JE
  #include "io_gpio_mcf51je_prv.h" 
#elif PSP_MQX_CPU_IS_MCF5222X
  #include "io_gpio_mcf5222_prv.h"
#elif PSP_MQX_CPU_IS_MCF5223X
  #include "io_gpio_mcf5223_prv.h"
#elif PSP_MQX_CPU_IS_MCF5441X
  #include "io_gpio_mcf5441_prv.h"
#elif PSP_MQX_CPU_IS_MCF5301X
  #include "io_gpio_mcf5301_prv.h"
#elif PSP_MQX_CPU_IS_MCF532X
  #include "io_gpio_mcf532_prv.h"
#elif PSP_MQX_CPU_IS_MCF520X
  #include "io_gpio_mcf520_prv.h"
#elif PSP_MQX_CPU_IS_KINETIS
  #include "io_gpio_kgpio_prv.h"  
#elif MQX_CPU==PSP_CPU_MPC8306
  #include "io_gpio_mpc8306_prv.h"
#elif MQX_CPU==PSP_CPU_MPC8308
  #include "io_gpio_mpc8308_prv.h"
#elif MQX_CPU==PSP_CPU_MPC8309
  #include "io_gpio_mpc8309_prv.h"
#elif PSP_MQX_CPU_IS_MCF51FD
  #include "io_gpio_mcf51fd_prv.h"
#elif PSP_MQX_CPU_IS_MCF51JF
  #include "io_gpio_mcf51jf_prv.h"
#elif PSP_MQX_CPU_IS_MCF51QM
  #include "io_gpio_mcf51qm_prv.h"
	#else
  #error IO_GPIO device driver not supported for processor.
#endif

typedef struct gpio_dev_data {
    struct gpio_dev_data _PTR_ NEXT;             /* this is used only to link IRQ maps */
    DEVICE_TYPE type;
    IRQ_FUNC         irq_func;
    GPIO_PIN_MAP     pin_map;
    GPIO_PIN_MAP     irqp_map;
    GPIO_PIN_MAP     irqn_map;
#if (defined PSP_MQX_CPU_IS_PIONEER2) || PSP_MQX_CPU_IS_KINETIS  
    GPIO_PIN_MAP     irql_map;
#endif    
} GPIO_DEV_DATA, _PTR_ GPIO_DEV_DATA_PTR;

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/init_i2c.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: init_i2c.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definition for the baud rate for the I2C
*   channel
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "i2c.h"
#include "i2c_ki2c.h"

const KI2C_INIT_STRUCT _bsp_i2c0_init = {
   0,                      /* I2C channel    */
   BSP_I2C0_MODE,          /* I2C mode       */ 
   BSP_I2C0_ADDRESS,       /* I2C address    */ 
   BSP_I2C0_BAUD_RATE,     /* I2C baud rate  */ 
   BSP_I2C0_INT_LEVEL,     /* I2C int level  */ 
   0,                      /* I2C int sublevel not available */ 
   BSP_I2C0_TX_BUFFER_SIZE,/* I2C int tx buf */
   BSP_I2C0_RX_BUFFER_SIZE /* I2C int rx buf */
};

const KI2C_INIT_STRUCT _bsp_i2c1_init = {
   1,                      /* I2C channel    */
   BSP_I2C1_MODE,          /* I2C mode       */
   BSP_I2C1_ADDRESS,       /* I2C address    */
   BSP_I2C1_BAUD_RATE,     /* I2C baud rate  */
   BSP_I2C1_INT_LEVEL,     /* I2C int level  */
   0,                      /* I2C int sublevel not available */ 
   BSP_I2C1_TX_BUFFER_SIZE,/* I2C int tx buf */
   BSP_I2C1_RX_BUFFER_SIZE /* I2C int rx buf */
};

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/lcpif.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lcpif.c$
* $Version : 3.8.6.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the LCP
*   interface routines.
*
*END************************************************************************/

#include <ppp.h>
#include "ppp_prv.h"


static uint_32 LCP_send(_ppp_handle, uchar, uchar, PCB_PTR);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_echo
* Returned Value  :  error code
* Comments        :
*     Sends an LCP Echo-Request packet.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_echo
   (
      _ppp_handle       handle,
            /* [IN] - the PPP state structure */
      uchar             id,
            /* [IN] - packet ID */
      PCB_PTR           packet
            /* [IN] - the packet to send */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   return LCP_send(handle, LCP_CODE_ECHO_REQ, id, packet);

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */  
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  PPP_discard
* Returned Value  :  error code
* Comments        :
*     Sends an LCP Discard-Request packet.
*
*END*-----------------------------------------------------------------*/

uint_32 PPP_discard
   (
      _ppp_handle       handle,
            /* [IN] - the PPP state structure */
      uchar             id,
            /* [IN] - packet ID */
      PCB_PTR           packet
            /* [IN] - the packet to send */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   return LCP_send(handle, LCP_CODE_DISC_REQ, id, packet);

#else

    return RTCSERR_IP_IS_DISABLED;    

#endif /* RTCSCFG_ENABLE_IP4 */  
   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  LCP_send
* Returned Value  :  error code
* Comments        :
*     Sends an LCP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uint_32 LCP_send
   (
      _ppp_handle       handle,
            /* [IN] - the PPP state structure */
      uchar             code,
            /* [IN] - LCP code */
      uchar             id,
            /* [IN] - packet ID */
      PCB_PTR           pcb
            /* [IN] - the packet to send */
   )
{ /* Body */
   PCB_FRAGMENT_PTR  frag_ptr;
   uchar_ptr         outp;
   uint_32           size;

   /*
   ** Make sure the first fragment is long enough for the PPP protocol
   ** field and the LCP header.  This isn't strictly necessary, but
   ** it's impractical to split a 10 byte field over multiple fragments.
   */
   if (pcb->FRAG[0].LENGTH < 10) {
      PCB_free(pcb);
      return RTCSERR_PPP_PACKET_TOO_SHORT;
   } /* Endif */

   size = 0;
   for (frag_ptr = pcb->FRAG; frag_ptr->LENGTH; frag_ptr++) {
      size += frag_ptr->LENGTH;
   } /* Endfor */
   size -= 2;

   outp = pcb->FRAG[0].FRAGMENT + 2;
   htonc(outp, code); outp++;
   htonc(outp, id);   outp++;
   htons(outp, size); outp += 2;
   htonl(outp, 0);    outp += 4;

   return PPP_send(handle, PPP_PROT_LCP, pcb);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/pppglob.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pppglob.c$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the various global PPP structures
*
*END************************************************************************/

#include <ppp.h>
#include "ppp_prv.h"


/*
** PPP task priority and extra stack size
*/

uint_32  _PPPTASK_priority   = 6;
uint_32  _PPPTASK_stacksize  = 0;

/*
** Variables used by the retransmission timer
*/

uint_32 _PPP_MIN_XMIT_TIMEOUT = 3000;        /* RFC 1661 4.6 */
uint_32 _PPP_MAX_XMIT_TIMEOUT = 10000l;
uint_32 _PPP_MAX_CONF_RETRIES = 10;          /* RFC 1661 4.6 */
uint_32 _PPP_MAX_TERM_RETRIES = 2;           /* RFC 1661 4.6 */
uint_32 _PPP_MAX_CONF_NAKS    = 5;           /* RFC 1661 4.6 */


/*
** The default PPP link options
*/

PPP_OPT PPP_DEFAULT_OPTIONS = {
   /* ACCM     */   0xFFFFFFFF,
   /* MRU      */   DEFAULT_MRU,
   /* AP       */   0,
   /* QP       */   0,
   /* AP_Start */   NULL,
   /* MAGIC    */   0,
   /* PFC      */   FALSE,
   /* ACFC     */   FALSE,
   /* CP       */   NULL
};

PPP_OPT PPP_DEFAULT_OPTIONS_PPPOE = {
   /* ACCM     */   0xFFFFFFFF,
   /* MRU      */   1492,
   /* AP       */   0,
   /* QP       */   0,
   /* AP_Start */   NULL,
   /* MAGIC    */   0,
   /* PFC      */   FALSE,
   /* ACFC     */   FALSE,
   /* CP       */   NULL
};


/*
** The default PPP call table
*/

PPP_CALL PPP_DEFAULT_CALL = {
   /* PARAM          */    0,
   /* PPP_Link_up    */    NULL,
   /* PPP_Link_down  */    NULL,
   /* PPP_Echo_reply */    NULL,
   /* PPP_Auth_fail  */    NULL
};



/*
** The minimal ACCM
*/

uint_32 _PPP_ACCM = 0xFFFFFFFFl;


/*
** The secrets.  These are the secrets used by PAP and CHAP.
** an xSECRET is a pointer to a single secret; an xSECRETS
** points to an array of secrets.
**
** LSECRET(S) points to the secret(s) to use when authenticating
** ourself to the peer (local secret(s)); RSECRET(S) points to
** the secret(s) to use when authenticating the peer (remote
** secret(s)).
**
** If an LSECRET(S) pointer is NULL, LCP will not allow the
** peer to request that authentication protocol.  If all LSECRET(S)
** are NULL, LCP will reject negotiation of the authentication
** protocol.
**
** If any RSECRET(S) are non-NULL, LCP will require that the peer
** authenticate itself.  If the peer rejects negotiation of the
** authentication protocol, LCP will terminate the link immediately
** upon reaching the OPENED state.
*/

PPP_SECRET_PTR _PPP_PAP_LSECRET = NULL;
PPP_SECRET_PTR _PPP_PAP_RSECRETS = NULL;
char_ptr       _PPP_CHAP_LNAME = "";
PPP_SECRET_PTR _PPP_CHAP_LSECRETS = NULL;
PPP_SECRET_PTR _PPP_CHAP_RSECRETS = NULL;


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/tfs/tfs.h<|end_filename|>
#ifndef __tfs_h__
#define __tfs_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tfs.h$
* $Version : 3.7.13.0$
* $Date    : Jan-28-2011$
*
* Comments:
*
*   This file contains the structure definitions and constants for a
*   user who will be compiling programs that will use the Embedded MS-DOS
*   File System (TFS)
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <ioctl.h>

/*
** Defines specific to TFS
*/

#define TFS_VERSION 1

#define TFS_FLAG_INDEX  1
#define TFS_FLAG_AUTH   2


/*
** error codes
*/
#define TFS_NO_ERROR                          FS_NO_ERROR
#define TFS_INVALID_FUNCTION_CODE             FS_INVALID_FUNCTION_CODE
#define TFS_FILE_NOT_FOUND                    FS_FILE_NOT_FOUND
#define TFS_PATH_NOT_FOUND                    FS_PATH_NOT_FOUND
#define TFS_ACCESS_DENIED                     FS_ACCESS_DENIED
#define TFS_INVALID_HANDLE                    FS_INVALID_HANDLE
#define TFS_INSUFFICIENT_MEMORY               FS_INSUFFICIENT_MEMORY
#define TFS_INVALID_MEMORY_BLOCK_ADDRESS      FS_INVALID_MEMORY_BLOCK_ADDRESS
#define TFS_ATTEMPT_TO_REMOVE_CURRENT_DIR     FS_ATTEMPT_TO_REMOVE_CURRENT_DIR
#define TFS_DISK_IS_WRITE_PROTECTED           FS_DISK_IS_WRITE_PROTECTED
#define TFS_BAD_DISK_UNIT                     FS_BAD_DISK_UNIT
#define TFS_INVALID_LENGTH_IN_DISK_OPERATION  FS_INVALID_LENGTH_IN_DISK_OPERATION
#define TFS_NOT_A_DOS_DISK                    FS_NOT_A_DOS_DISK
#define TFS_SECTOR_NOT_FOUND                  FS_SECTOR_NOT_FOUND 
#define TFS_WRITE_FAULT                       FS_WRITE_FAULT
#define TFS_READ_FAULT                        FS_READ_FAULT
#define TFS_SHARING_VIOLATION                 FS_SHARING_VIOLATION
#define TFS_FILE_EXISTS                       FS_FILE_EXISTS
#define TFS_ALREADY_ASSIGNED                  FS_ALREADY_ASSIGNED
#define TFS_INVALID_PARAMETER                 FS_INVALID_PARAMETER
#define TFS_DISK_FULL                         FS_DISK_FULL 
#define TFS_ROOT_DIR_FULL                     FS_ROOT_DIR_FULL 
#define TFS_EOF                               FS_EOF
#define TFS_CANNOT_CREATE_DIRECTORY           FS_CANNOT_CREATE_DIRECTORY
#define TFS_NOT_INITIALIZED                   FS_NOT_INITIALIZED
#define TFS_OPERATION_NOT_ALLOWED             FS_OPERATION_NOT_ALLOWED
#define TFS_ERROR_INVALID_DRIVE_HANDLE        FS_ERROR_INVALID_DRIVE_HANDLE
#define TFS_ERROR_INVALID_FILE_HANDLE         FS_ERROR_INVALID_FILE_HANDLE
#define TFS_ERROR_UNKNOWN_FS_VERSION          FS_ERROR_UNKNOWN_FS_VERSION
#define TFS_LOST_CHAIN                        FS_LOST_CHAIN
#define TFS_INVALID_DEVICE                    FS_INVALID_DEVICE
#define TFS_INVALID_CLUSTER_NUMBER            FS_INVALID_CLUSTER_NUMBER
#define TFS_FAILED_TO_DELETE_LFN              FS_FAILED_TO_DELETE_LFN
#define TFS_BAD_LFN_ENTRY                     FS_BAD_LFN_ENTRY

/*
** Extra IO_IOCTL codes
*/
#define IO_IOCTL_TFS_GET_NAME                     _IO(IO_TYPE_TFS,0x01)
#define IO_IOCTL_TFS_GET_ATTRIBUTES               _IO(IO_TYPE_TFS,0x02)
#define IO_IOCTL_TFS_GET_LENGTH                   _IO(IO_TYPE_TFS,0x03)
#define IO_IOCTL_TFS_GET_LAST_ERROR               _IO(IO_TYPE_TFS,0x04)
#define IO_IOCTL_TFS_GET_CURRENT_DATA_PTR         _IO(IO_TYPE_TFS,0x05)


/*
** TFS directory entry information
*/
typedef struct tfs_dir_entry
{
    char_ptr    NAME;
    uint_32     FLAGS;
    uchar_ptr   DATA;
    uint_32     SIZE;
} TFS_DIR_ENTRY, _PTR_ TFS_DIR_ENTRY_PTR;


/*
** extern statements for TFS
*/

#ifdef __cplusplus
extern "C" {
#endif

extern uint_32 _io_tfs_install (char_ptr, const TFS_DIR_ENTRY* );
extern int_32 _io_tfs_uninstall (IO_DEVICE_STRUCT_PTR);
extern int_32 _io_tfs_open (MQX_FILE_PTR, char_ptr, char_ptr);
extern int_32 _io_tfs_close (MQX_FILE_PTR);
extern int_32 _io_tfs_read (MQX_FILE_PTR, char_ptr, int_32);
extern int_32 _io_tfs_write (MQX_FILE_PTR, char_ptr, int_32);
extern _mqx_int _io_tfs_ioctl (MQX_FILE_PTR, _mqx_uint, pointer);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/phdc/usb_host_phdc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_phdc.c$
* $Version : 3.8.6.0$
* $Date    : Sep-13-2012$
*
* Comments:
*
*   This file contains  the USB PHDC class driver implementation
*
*END************************************************************************/
#include <string.h>

#include "usb_host_phdc.h"

/*--------------------------------------------------------------**
** This anchor points to the first class/interface in a linked  **
**   chain of structs, one for each functional phdc interface. **
**   Items are added by calling "select interface" and removed  **
**   by "delete interface".  Typically an application will call **
**   these select in its attach callback routine.  It may later **
**   call delete, or the call may be automatic during detach.   **
**--------------------------------------------------------------*/
USB_PHDC_CLASS_INTF_STRUCT  	*phdc_intf_anchor  = NULL;

/* String to give the metadata signature */
static char const msg_preamble_signature[] = "PhdcQoSSignature";

/* Private functions for use within this file only */
static void    usb_class_phdc_uninit_interface(CLASS_CALL_STRUCT_PTR   phdc_call_ptr);
static void    usb_class_phdc_free_qos_metadata_list(USB_PHDC_CLASS_INTF_STRUCT *phdc_intf);
static boolean usb_class_phdc_pipe_transfers_pending(_usb_pipe_handle pipe_handle);
static boolean usb_class_phdc_interface_transfers_pending(USB_PHDC_CLASS_INTF_STRUCT  *phdc_intf);
static void    usb_class_phdc_send_data_callback(pointer pipe_handle, pointer call_param_ptr, uchar_ptr data_ptr, uint_32 data_size, USB_STATUS usb_status);
static void    usb_class_phdc_send_control_callback(pointer pipeHandle, pointer callbackParam, uchar_ptr bBuff, uint_32 length, USB_STATUS usb_status);
static void    usb_class_phdc_recv_data_callback(_usb_pipe_handle pipe, USB_PHDC_PARAM* callback_param_ptr, uint_8* buff_ptr, uint_32 buff_size, USB_STATUS status);
static USB_PHDC_DESC_QOS_METADATA_LIST*  
               usb_class_phdc_search_endpoint_type(USB_PHDC_DESC_QOS_METADATA_LIST* phdcQosMetaList_ptr, uint_8 ep_type, uint_8 ep_dir);

/* Private macro definitions  */
#define   USB_PHDC_LATECNY_RELIABILITY_MASK   0x3F

/* PUBLIC FUNCTION*--------------------------------------------------------
* 
* Function Name  : usb_class_phdc_init
* Returned Value : none
* Comments       :
*     Initialize phdc-class interface info struct.
* 
*END*--------------------------------------------------------------------*/

void usb_class_phdc_init
   (
      /* [IN] device/descriptor/pipe handles */
      PIPE_BUNDLE_STRUCT_PTR  pbs_ptr,      
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR   phdc_call_ptr
   )
{ /* Body */
   USB_STATUS                  status;
   USB_PHDC_CLASS_INTF_STRUCT  *phdc_intf;
   USB_PHDC_CLASS_TYPE         *phdcClassDesc;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_phdc_init");
   #endif

   /* Pointer validity-checking, clear memory, init header */
   phdc_intf = phdc_call_ptr->class_intf_handle;

   USB_lock(); //not needed as init is called from "already locked" function

   if (USB_OK != usb_host_class_intf_init(pbs_ptr, (void*)phdc_intf, (void*)&phdc_intf_anchor, NULL))
   {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_phdc_init, error class init at interface select");
      #endif
      return;
   }

   /* Generate the code_key based on the attached device. This is used to
    * verify that the device has not been detached and replaced with another.
    */
   phdc_call_ptr->code_key = 0;
   phdc_call_ptr->code_key = usb_host_class_intf_validate (phdc_call_ptr);
   
   /* Initialize the pipes from the pipe bundle passed at function call */	
   /* Control Pipe */
   phdc_intf->controlPipe = usb_hostdev_get_pipe_handle (pbs_ptr, USB_CONTROL_PIPE, 0);
   /* Bulk In Pipe */
   phdc_intf->bulkInPipe = usb_hostdev_get_pipe_handle (pbs_ptr, USB_BULK_PIPE, USB_RECV);
   /* Bulk Out Pipe */
   phdc_intf->bulkOutPipe = usb_hostdev_get_pipe_handle (pbs_ptr, USB_BULK_PIPE, USB_SEND);
   /* Interrupt In Pipe (optional) */
   phdc_intf->intInPipe = usb_hostdev_get_pipe_handle (pbs_ptr, USB_INTERRUPT_PIPE, USB_RECV);
   /* Test for the mandatory pipes */
   if( (phdc_intf->controlPipe == NULL) ||
	   (phdc_intf->bulkInPipe == NULL)  ||
	   (phdc_intf->bulkOutPipe == NULL)
	 )
	 {
	     #ifdef _HOST_DEBUG_
			DEBUG_LOG_TRACE("usb_class_phdc_init, error class init at pipe initialization");
		 #endif	
	     usb_class_phdc_uninit_interface(phdc_call_ptr);
		 USB_unlock ();
	     return;
	 }
   
   /* Initialize the Function Extension Descriptor */
   status = _usb_hostdev_get_descriptor(phdc_intf->generalClass.dev_handle, 
										phdc_intf->generalClass.intf_handle,
										PHDC_11073PHD_FUNCTION_DESCRIPTOR,
										0,
										0,
										(void**)&(phdc_intf->fcnExtDesc)
									   );
   if(status != USB_OK)
   {
		#ifdef _HOST_DEBUG_
			DEBUG_LOG_TRACE("usb_class_phdc_init, error class init at function extension descriptor initialization");
		#endif  
	    usb_class_phdc_uninit_interface(phdc_call_ptr);
		USB_unlock ();
	    return;
   }
   if((phdc_intf->fcnExtDesc == NULL) ||      
      (phdc_intf->fcnExtDesc->bLength != (4 +  2 * phdc_intf->fcnExtDesc->bNumDevSpecs))
	 )
   {
	    #ifdef _HOST_DEBUG_
			DEBUG_LOG_TRACE("usb_class_phdc_init, error class init. function extension descriptor failed validity check");
		#endif  
	    usb_class_phdc_uninit_interface(phdc_call_ptr);		  
		USB_unlock ();
	    return;
   }
   
   /* Initialize the Function Extension Descriptor */
   status = _usb_hostdev_get_descriptor(phdc_intf->generalClass.dev_handle, 
										phdc_intf->generalClass.intf_handle,
										USB_PHDC_CLASSFUNCTION_DESCRIPTOR,
										0,
										0,
										(void**)&phdcClassDesc
									   );
   
   if((status != USB_OK) || (phdcClassDesc == NULL))
   {
		#ifdef _HOST_DEBUG_
			DEBUG_LOG_TRACE("usb_class_phdc_init, error class init at class descriptor initialization");
		#endif  
	    usb_class_phdc_uninit_interface(phdc_call_ptr);
		USB_unlock ();
	    return;
   }
   
   if(phdcClassDesc->bmCapability == 0x01)
   {
    phdc_intf->preambleCapability = TRUE;
   }
   else
   {
    phdc_intf->preambleCapability = FALSE;
   }
   
   phdc_intf->phdcDataCode = phdcClassDesc->bPHDCDataCode;
   
   /* Initialize the QoSMetadata List of descriptors */
   {
    uint_8 endpointCount = 0;
	USB_PHDC_DESC_QOS_METADATA_LIST *qosMetadata = NULL;
    USB_PHDC_DESC_QOS_METADATA_LIST *qosMetadataListTail = NULL;
	boolean noMoreEndpoints = FALSE;
	
	do
	{
	  /* Allocate memory for the structure member */	  
	  //status = _usb_hostdev_get_buffer(phdc_intf->generalClass.dev_handle, sizeof(USB_PHDC_DESC_QOS_METADATA_LIST), (void**)&qosMetadata);
	  
	  qosMetadata = (USB_PHDC_DESC_QOS_METADATA_LIST *)USB_mem_alloc_uncached_zero(sizeof(USB_PHDC_DESC_QOS_METADATA_LIST));
	  
	  if(qosMetadata == NULL)
	  {
	   	#ifdef _HOST_DEBUG_
			DEBUG_LOG_TRACE("usb_class_phdc_init, memory allocation failed to build the qos metdata descriptor list");
		#endif  
	    usb_class_phdc_uninit_interface(phdc_call_ptr);		  
		USB_unlock ();
	    return;
	  }
	  
	  /* Initialize the fields in the current list member */
	  qosMetadata->pNext = NULL;
	  status =  _usb_hostdev_get_descriptor(phdc_intf->generalClass.dev_handle, 
				 						    phdc_intf->generalClass.intf_handle,
				 						    USB_ENDPOINT_DESCRIPTOR,
                        endpointCount+1,  /* Index starts with 1 for endpoint descriptors (Endpoint 0 not includded in the count) */
										    0,
										    (void**)&(qosMetadata->pEndpointDesc)
									       );
									       
      status |= _usb_hostdev_get_descriptor(phdc_intf->generalClass.dev_handle, 
				 						    phdc_intf->generalClass.intf_handle,
				 						    USB_PHDC_QOS_DESCRIPTOR,
                        endpointCount,
										    0,
										    (void**)&qosMetadata->pQosDesc
									       );
									       
	  if((status != USB_OK) || (qosMetadata->pEndpointDesc == NULL) || (qosMetadata->pQosDesc == NULL))	  
	  {
	   
	   /* dealocate the memory for the qosMetadata pointer */
	   USB_mem_free(qosMetadata);
	   
	   /* PHDC is expecting minimum 2 endpoint descriptors (Bulk In and Bulk Out) */
     if(endpointCount < 2)
	   {
	    #ifdef _HOST_DEBUG_
			DEBUG_LOG_TRACE("usb_class_phdc_init, Less than 2 endpoint (or QoS) descriptors received");
		#endif  
	    usb_class_phdc_uninit_interface(phdc_call_ptr);	
		USB_unlock ();
	    return;
	   }
	   
	   /* End the loop */
	   noMoreEndpoints = TRUE;
	  }
      
	  /* First element in the list?	*/
    if(endpointCount == 0)
	  {
	    /* Save the reference in the interface struct */
	    phdc_intf->qosMetadataList = qosMetadata;
	    qosMetadataListTail = phdc_intf->qosMetadataList; /* Initialize the tail, pointing to the only element in the list */
	  }
	  else
	  {
	   if(!noMoreEndpoints)
	   {
	    /* Link it on the last element in the list */
	    qosMetadataListTail->pNext = qosMetadata;
	    /* Increment the tail */
	    qosMetadataListTail = qosMetadataListTail->pNext;
	   }
	  }
	  
	  if(!noMoreEndpoints)
	  {		  
	   /* Check the Qos descriptor fields */
	   if(qosMetadata->pQosDesc != NULL)
	   {
	    if(qosMetadata->pQosDesc->bQoSEncodingVersion != 0x01)
	    {
	     /* The encoding of the descriptor latancy reliability is not supported, Ignore this descriptor */
 		 qosMetadata->pQosDesc = NULL;
	    }
	    else
	    {
	     if(qosMetadata->pEndpointDesc != NULL)
	 	 {
		  switch(qosMetadata->pEndpointDesc->bmAttributes & 0x03)
		  {
		   case 0x02: /* Bulk endpoint */
		  		     if(qosMetadata->pQosDesc->bmLatencyReliability & 0x01)
					 {
					   qosMetadata->pQosDesc = NULL; /* Ignore this descriptor */
					 }
					 else
					 {
					  if(phdc_intf->preambleCapability == FALSE)
					  {
					   /* This interface does not support metadata. Only one of the b1-b7 bits can be set */
					   if(qosMetadata->pQosDesc->bmLatencyReliability & (qosMetadata->pQosDesc->bmLatencyReliability - 1))
					   {
					    qosMetadata->pQosDesc = NULL; /* Ignore this descriptor */
					   }
					  }
					 }
					 break; 
		   case 0x03: /* Interrupt endpoint */
				     if(qosMetadata->pQosDesc->bmLatencyReliability != 0x01) /* for this endpoint only the b0 should be set in the QoS bin.*/
					 {
					  qosMetadata->pQosDesc = NULL; /* Ignore this descriptor */
					 }
					 break;
		   default:  /* The endpoint is not supported */
					 qosMetadata->pQosDesc = NULL; /* Ignore this descriptor */	  
					 break;		  
		 }
		}
	   }
	  }
	  
  
	   /* Initialize the optional metadata descriptor */
	   status = _usb_hostdev_get_descriptor(phdc_intf->generalClass.dev_handle, 
	  			 						   phdc_intf->generalClass.intf_handle,
				 						   PHDC_METADATA_DESCRIPTOR,
                                           endpointCount,
										   0,
										   (void**)&(qosMetadata->pMetadataDesc)
									      );
       endpointCount++;
	 } /* if(!noMoreEndpoints) */
     									      	  
    }while(!noMoreEndpoints);
   
   }/* End block: Initialize the QoSMetadata List of descriptors */

   USB_unlock();
   #ifdef _HOST_DEBUG_
	   DEBUG_LOG_TRACE("usb_class_phdc_init, Init SUCCESSFUL");
   #endif 
   
} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_phdc_send_data
* Returned Value : error code
* Comments       :
*     Send data to a phdc device through a bulk-out pipe.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_phdc_send_data
   (
      /* [IN] phdc specific generic parameter structure pointer */
      USB_PHDC_PARAM* call_param_ptr
   )
{ /* Body */
  TR_INIT_PARAM_STRUCT             tr;
  USB_STATUS                       error;
  USB_PHDC_CLASS_INTF_STRUCT*      class_interface_handle;
  USB_PHDC_DESC_QOS_METADATA_LIST* qosListParser = NULL;
  uint_8                           numTransfers;
  uint_8                           latencyReliability;

  #ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_phdc_send_data");
  #endif
  
  if(NULL == call_param_ptr)
  {
    error = USBERR_ERROR;
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_phdc_send_data, NULL pointer parameter");
    #endif
    return error;
  }

  if( (NULL == call_param_ptr->ccs_ptr) || (NULL == call_param_ptr->buff_ptr) )
  {
    error = USBERR_ERROR;
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_phdc_send_data, NULL pointer parameter");
    #endif
    return error;
  }

  if( 0 == call_param_ptr->buff_size )
  {
    error = USBERR_ERROR;
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_phdc_send_data, data size is zero");
    #endif
    return error;
  }

  USB_lock ();

  if( 0 == usb_host_class_intf_validate(call_param_ptr->ccs_ptr) )
  {
    USB_unlock ();
    error = USBERR_NO_INTERFACE;
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_phdc_send_data, error verifying class");
    #endif
    return error;
  }

  class_interface_handle = (USB_PHDC_CLASS_INTF_STRUCT *)call_param_ptr->ccs_ptr->class_intf_handle;
  error = usb_hostdev_validate (class_interface_handle->generalClass.dev_handle);
  if(USB_OK != error)
  {
    USB_unlock ();
    #ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_phdc_send_data, hostdev_validate error");
    #endif
    return error;
  }

  /* check for pending transfers */
  if(TRUE == class_interface_handle->setClearRequestPending)
  {
    USB_unlock ();
    error = USBERR_TRANSFER_IN_PROGRESS;
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_phdc_send_data, control transfer in progress");
    #endif
    return error;
  }

  /* check for meta-data capability */
  if(class_interface_handle->preambleCapability && class_interface_handle->deviceFeatureSet)
  {
    /* meta-data and QOS checking */
    if(TRUE == call_param_ptr->metadata)
    {
      latencyReliability = ((USB_PHDC_METADATA_PREAMBLE *)call_param_ptr->buff_ptr)->bmLatencyReliability;
      if( (latencyReliability & latencyReliability - 1) || (0 == latencyReliability) || (latencyReliability & 0xC0) )
      {
        USB_unlock ();
        error = USBERR_INVALID_BMREQ_TYPE;
        #ifdef _HOST_DEBUG_
          DEBUG_LOG_TRACE("usb_phdc_send_data, invalid LatencyReliability");
        #endif
        return error;
      }
      
      /* Check if 'qos' bin is supported by the Bulk OUT endpoint's PHDC QoS Descriptor */
      /* Search in the USB_PHDC_DESC_QOS_METADATA_LIST the endpoint number corresponding to the Bulk OUT */
      qosListParser = usb_class_phdc_search_endpoint_type(class_interface_handle -> qosMetadataList, ENDPOINT_BULK, ENDPOINT_DIR_OUT);
         
      /* Compare the qos bin with 'bmLatencyReliability' field from the corresponding QoS Descriptor */
      if(qosListParser == NULL)
      {
        USB_unlock ();
        error = USBERR_ERROR;
        #ifdef _HOST_DEBUG_
          DEBUG_LOG_TRACE("usb_phdc_send_data, the required qos is not supported by Bulk OUT pipe");
        #endif
        return error;
      }

      /* Check if the requested QoS is supported */
      if(0 == (qosListParser -> pQosDesc -> bmLatencyReliability & latencyReliability))
      {
        USB_unlock ();
        error = USBERR_ERROR;
        #ifdef _HOST_DEBUG_
          DEBUG_LOG_TRACE("usb_phdc_send_data, the required qos is not supported by Bulk OUT pipe");
        #endif
        return error;
      }

      numTransfers = ((USB_PHDC_METADATA_PREAMBLE *)call_param_ptr->buff_ptr)->bNumTransfers;
      if( 0 == numTransfers )
      {
        USB_unlock ();
        error = USBERR_ERROR;
        #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_phdc_send_data, numTransfers must be greater than zero");
        #endif
        return error;
      }
      class_interface_handle->numTransfBulkOut = numTransfers;
    }
    else /* if not a meta-data send request */
    {
      if( 0 == class_interface_handle->numTransfBulkOut )
      {
        USB_unlock ();
        error = USBERR_ERROR;
        #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_phdc_send_data, meta-data expected");
        #endif
        return error;
      }
    }
  }

  /* prepare the transfer */
  usb_hostdev_tr_init (&tr, usb_class_phdc_send_data_callback, call_param_ptr);
  tr.G.TX_BUFFER = call_param_ptr->buff_ptr;
  tr.G.TX_LENGTH = call_param_ptr->buff_size;
  call_param_ptr->tr_index = tr.G.TR_INDEX;
  call_param_ptr->tr_pipe_handle = class_interface_handle->bulkOutPipe;

  error = _usb_host_send_data(
                                class_interface_handle->generalClass.host_handle,
                                class_interface_handle->bulkOutPipe,
                                &tr
                              );

  /* decrement the numTransfers for bulkOut pipe */
  if((class_interface_handle->numTransfBulkOut != 0) && (FALSE == call_param_ptr->metadata))
  {
    class_interface_handle->numTransfBulkOut--;
  }

  USB_unlock ();

  #ifdef _HOST_DEBUG_
     DEBUG_LOG_TRACE("usb_phdc_send_data, SUCCESSFUL");
  #endif

  return error;   

} /* Endbody */

/* PUBLIC FUNCTION*--------------------------------------------------------
* 
* Function Name  : usb_class_phdc_set_callbacks
* Returned Value : none
* Comments       :
*     Initializes the application callbacks for the current PHDC interface
* 
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_phdc_set_callbacks
(
    /* [IN] phdc call struct pointer */
    CLASS_CALL_STRUCT_PTR       ccs_ptr,
	/* [IN] phdc application-registered send Callback */
	phdc_callback  sendCallback,
	/* [IN] phdc application-registered receive Callback */
	phdc_callback  recvCallback,
	/* [IN] phdc application-registered control Callback */
	phdc_callback  ctrlCallback
)
{
   USB_STATUS returnStatus = USBERR_NO_INTERFACE;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_phdc_set_callbacks");
   #endif
   
   USB_lock();
   
   if(usb_host_class_intf_validate(ccs_ptr))
   {
     /* Ok, the interface is valid */
     USB_PHDC_CLASS_INTF_STRUCT  *phdc_intf = (USB_PHDC_CLASS_INTF_STRUCT  *)ccs_ptr->class_intf_handle;
     
     if(phdc_intf != NULL)
     {    	
       /* Check the pending transfers on the pipes */    
       returnStatus = USBERR_TRANSFER_IN_PROGRESS;     

       if(!usb_class_phdc_interface_transfers_pending(phdc_intf))
       {
           /* No transfers are pending in the interface. Set the callbacks */
           phdc_intf->sendCallback = sendCallback;
           phdc_intf->recvCallback = recvCallback;
           phdc_intf->ctrlCallback = ctrlCallback;           
           
           returnStatus = USB_OK;
       }
     }
   }
   
   USB_unlock();
   
   return returnStatus;   
}


/* PUBLIC FUNCTION*--------------------------------------------------------
* 
* Function Name  : usb_class_phdc_uninit
* Returned Value : none
* Comments       :
*     Uninitialize phdc-class interface info struct.
* 
*END*--------------------------------------------------------------------*/
void  usb_class_phdc_uninit(
     /* [IN] pointer to device instance */
    _usb_device_instance_handle dev_handle,
    /* [IN] pointer to interface descriptor */
    _usb_interface_descriptor_handle intf_handle
   )
{
 USB_PHDC_CLASS_INTF_STRUCT *phdcParser = phdc_intf_anchor;
 boolean interfaceFound = FALSE;
 
 USB_lock();
 /* Search the interface descriptor handle (intf_handle) and device descriptor handle (intf_handle) in the interface list */
 if(phdc_intf_anchor != NULL)
 {
  do
  {
   if( (phdcParser->generalClass.dev_handle == dev_handle) &&
       (phdcParser->generalClass.intf_handle == intf_handle)
     )
   {
    interfaceFound = TRUE;
   }
   else
   {
    /* Go to the next element in the list */
    phdcParser = (USB_PHDC_CLASS_INTF_STRUCT *)phdcParser->generalClass.next;
   }
  }
  while((interfaceFound == FALSE) && (phdcParser != NULL));
 }
 
 if(interfaceFound)
 {
   usb_class_phdc_free_qos_metadata_list(phdcParser);
 }
 
 USB_unlock();
}


/* PUBLIC FUNCTION*--------------------------------------------------------
* 
* Function Name  : usb_class_phdc_cancel_transfer
* Returned Value : none
* Comments       :
*     Attempts to cancel the indicated transfer (Send or Receive)
* 
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_phdc_cancel_transfer(CLASS_CALL_STRUCT_PTR ccs_ptr,
                                          uint_32               tr_index,
                                          _usb_pipe_handle      tr_pipe_handle
                                         )
{
   USB_STATUS returnStatus = USBERR_NO_INTERFACE;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_phdc_cancel_transfer");
   #endif
   
   USB_lock();
   
   if(usb_host_class_intf_validate(ccs_ptr))
   {
     /* Ok, the interface is valid */
     USB_PHDC_CLASS_INTF_STRUCT  *phdc_intf = (USB_PHDC_CLASS_INTF_STRUCT *)ccs_ptr->class_intf_handle;
     
     if(phdc_intf != NULL)
     {
      returnStatus = _usb_host_cancel_transfer(phdc_intf->generalClass.host_handle, tr_pipe_handle, tr_index);
     }
   }

   USB_unlock();
   return returnStatus;     
}



/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_class_phdc_recv_data
* Returned Value : none
* Comments       :
*     Receive printer data from either a bulk-in or an interrupt pipe.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_phdc_recv_data(USB_PHDC_PARAM* call_param_ptr) 
{ /* Body */

  _usb_pipe_handle             pipe;
  TR_INIT_PARAM_STRUCT         tr;
  USB_STATUS                   usb_status			= USBERR_NO_INTERFACE; 
  USB_PHDC_CLASS_INTF_STRUCT*  phdc_cis_ptr 	= (USB_PHDC_CLASS_INTF_STRUCT*)(call_param_ptr ->ccs_ptr ->class_intf_handle);
  DEV_INSTANCE_PTR             dev 				= (DEV_INSTANCE_PTR)(phdc_cis_ptr ->generalClass.dev_handle);	
  
  /* used to search a specific QoS descriptor in the linked list of Endpoint-QoS-Metadata descriptors */
  USB_PHDC_DESC_QOS_METADATA_LIST* phdcQosMetadataListParser = NULL;
  
   
  #ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_phdc_recv_data");
  #endif

  /* Function's input parameters checkings */
  if((NULL == call_param_ptr) || (NULL == call_param_ptr ->ccs_ptr) || (NULL == call_param_ptr ->buff_ptr) || !(call_param_ptr ->buff_size)) 
  {
    usb_status = USBERR_ERROR;
      
    #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_phdc_recv_data, ERROR: input parameters wrong");
    #endif      
    return usb_status;
  }
      
  /* Checks if QoS 'points' to the interrupt pipe and this pipe exists OR 'qos' contains valid value */
  if(call_param_ptr ->qos & 0x01) 
  {
     if((call_param_ptr ->qos & 0xFE) || (NULL == phdc_cis_ptr ->intInPipe))
     {
       usb_status = USBERR_ERROR; 
        
       #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_phdc_recv_data, ERROR: input parameter 'qos' wrong");
       #endif        
       return usb_status; 
     }      
  }
    
  /* Performs a class validity check in order to detect if device is still attached or it wasn't replaced by another */   
  #ifdef _HOST_DEBUG_
     DEBUG_LOG_TRACE("usb_phdc_class_verify");
  #endif
   
  USB_lock ();
  if(usb_host_class_intf_validate(call_param_ptr ->ccs_ptr)) 
  {           
     usb_status = usb_hostdev_validate (dev);
     
     if(USB_OK != usb_status) 
     {       
       #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_phdc_recv_data, error verifying class");
       #endif  
       USB_unlock ();        
       return usb_status;
     } 
     else
     {
       #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_phdc_recv_data, successfully verifying class");
       #endif 
     }
  }
      
               
  /* Get the pipe handle used for receive data (parameter passed in _usb_host_recv_data()), depending on the qos bin */ 
  pipe = (call_param_ptr ->qos & 0x01) ? (phdc_cis_ptr ->intInPipe) : (phdc_cis_ptr ->bulkInPipe);
   
  /* Checks if pipe selection is Bulk IN */
  if(pipe == phdc_cis_ptr ->bulkInPipe) 
  {
    /* Check if 'qos' bin is supported by the Bulk IN endpoint's PHDC QoS Descriptor */
    /* Search in the USB_PHDC_DESC_QOS_METADATA_LIST the endpoint number corresponding to the Bulk IN */
    phdcQosMetadataListParser = usb_class_phdc_search_endpoint_type(phdc_cis_ptr ->qosMetadataList, ENDPOINT_BULK, ENDPOINT_DIR_IN);
         
    /* Compare the qos bin with 'bmLatencyReliability' field from the corresponding QoS Descriptor */
    if((phdcQosMetadataListParser == NULL) || (!(call_param_ptr ->qos & phdcQosMetadataListParser ->pQosDesc ->bmLatencyReliability)))
    {
      usb_status = USBERR_ERROR;
      
      #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_phdc_recv_data, ERROR: required qos is not supported by Bulk IN pipe");
      #endif  
      USB_unlock ();        
      return usb_status;    
    }    
     
    /* Checks if any SET_FEATURE/CLEAR_FEATURE class command is pending; if it is, refuses the current transaction */
    if(TRUE == phdc_cis_ptr ->setClearRequestPending) 
    {
      usb_status = USBERR_TRANSFER_IN_PROGRESS;
       
      #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_phdc_recv_data, ERROR: transfer in progress");
      #endif
      USB_unlock ();         
      return usb_status;  
    }   
  }
    
  /* Populate the transfer structure */   
  usb_hostdev_tr_init (&tr, (tr_callback)usb_class_phdc_recv_data_callback, call_param_ptr); 
   
  tr.G.RX_BUFFER = call_param_ptr->buff_ptr;
  tr.G.RX_LENGTH = call_param_ptr->buff_size;   
  
  /* Save the transfer index and pipe handle */
  call_param_ptr->tr_index = tr.G.TR_INDEX;
  call_param_ptr->tr_pipe_handle = pipe;     
     
  /* Require Host API to post transaction */
  usb_status = _usb_host_recv_data(phdc_cis_ptr ->generalClass.host_handle, pipe, &tr); 

  USB_unlock ();
   
  if(USB_STATUS_TRANSFER_QUEUED == usb_status)
  {         
     #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_phdc_recv_data, SUCCESSFUL");
     #endif
  }
  else
  {
     #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_phdc_recv_data, ERROR");
     #endif   
  }
    
  return usb_status;               
} /* Endbody */                  



/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : phdc_receive_data_callback
* Returned Value : none
* Comments       :
*     Internal PHDC callback function when a posted receive transfer has been finished.
* 
*END*--------------------------------------------------------------------*/
static void  usb_class_phdc_recv_data_callback
   (
      /* [IN] pipe handle */
      _usb_pipe_handle          pipe,
      
      /* [IN] parameter specified by higher level */ 
      USB_PHDC_PARAM*  callback_param_ptr, 
      
      /* [IN] pointer to buffer containing data (Rx) */
      uint_8*                  buff_ptr, 
      
      /* [IN] length of data transferred */
      uint_32                   buff_size, 
      
      /* [IN] status, preferably USB_OK or USB_DONE */
      USB_STATUS                usb_status
   ) 
{ /* Body */
  
  USB_PHDC_CLASS_INTF_STRUCT* 	  	phdc_cis_ptr = (USB_PHDC_CLASS_INTF_STRUCT*)(callback_param_ptr ->ccs_ptr ->class_intf_handle); 
  DEV_INSTANCE_PTR             		dev = (DEV_INSTANCE_PTR)(phdc_cis_ptr ->generalClass.dev_handle);
  PIPE_STRUCT_PTR                   pipe_desc_ptr = (PIPE_STRUCT_PTR) phdc_cis_ptr ->bulkInPipe; 
 
  USB_PHDC_METADATA_PREAMBLE*   		 pMetaDataPreamble 	      = NULL;  
  USB_PHDC_DESC_QOS_METADATA_LIST*  phdcQosMetadataListParser = NULL;
  uint_8 						                metadata_packet;  
  USB_STATUS                        status;
    
    
  USB_lock ();
 
  if(usb_status != USB_STATUS_IDLE)
  {
    /* ERROR: error returned USB status  */
    callback_param_ptr ->usb_phdc_status = USB_PHDC_ERR;	              
  }
  else
  {
    if(usb_host_class_intf_validate(callback_param_ptr ->ccs_ptr)) 
    { 
   	  /* Check the type of pipe */
  	  if(pipe == phdc_cis_ptr ->intInPipe)
  	  { /* Pipe is Interrupt IN */      
  	      
  	    /* Packet received is assumed to be data (no metadata preamble check) */
  	    callback_param_ptr ->usb_phdc_status = USB_PHDC_RX_OK;  
  	  }
  	  else
  	  { /* Pipe is Bulk IN */
  	      
  	    /* Checks for the preamble capability feature and activation */
  	    if((phdc_cis_ptr ->preambleCapability == TRUE) && (phdc_cis_ptr ->deviceFeatureSet == TRUE))
  	    { /* Preamble feature supported and also enabled */
  	        
  	      /* Checks if packet expected is metadata preamble or not */
  	      if(phdc_cis_ptr ->numTransfBulkIn)
  	      { /* Packet expected: message data */
  	        
  	        /* Packet received is assumed to be data (no metadata preamble check) */
  	        callback_param_ptr ->usb_phdc_status = USB_PHDC_RX_OK;
  	        phdc_cis_ptr ->numTransfBulkIn--;   /* Decrements the number of data transfer left until a new metadata is expected */   
  	      }  
  	      else
  	      { /* Packet expected: metadata */
  	          
  	        /* 
  	          Compare the first 16 bytes of the received data with the preamble signature 
  	          in order to decide if metadata preamble has been received; if metadata_pachet = 0 
  	          the incoming packet is a metadata.                    
  	        */  
  	        metadata_packet = (uint_8) strncmp((const char *)buff_ptr, msg_preamble_signature, METADATA_PREAMBLE_SIGNATURE_SIZE);         
  	               
  	        /* Checks the incoming packet */
  	        if(!metadata_packet)
  	        { /* Metadata preamble received */
  	       
  	          /* Metadata expected and also received */
  	          /* Parse the buffer as it would be a metadata preamble */ 
  	          /* Checks for correctness of the rest of fields in preamble metadata (bNumTransfers, bQosEncodingVersion and bmLatencyReliability) */
  	          pMetaDataPreamble = (USB_PHDC_METADATA_PREAMBLE*)buff_ptr;
  	            
  	          if(
  	             !(pMetaDataPreamble ->bNumTransfers)               ||   /* bNumTrensfer should not be 0 */
  	              (pMetaDataPreamble ->bQoSEncodingVersion != 0x01) ||   /* if 'bQoSEncodingVersion' isn't 0x01 it would be considered that 'bmLatencyReliability' is not valid */
  	              (pMetaDataPreamble ->bmLatencyReliability & 0x01) ||   /* 'bmLatencyReliability' bitmap shouldn't contains a '1' in the bit 0 position */
  	             !(pMetaDataPreamble ->bmLatencyReliability)        ||   /* 'bmLatencyReliability' should not be 0 */                             
  	              (pMetaDataPreamble ->bmLatencyReliability & pMetaDataPreamble ->bmLatencyReliability - 1)  /* 'bmLatencyReliability' bitmap shall contains only one bit set */
  	            )
  	          {
  	            /* ERROR: metadata preamble expected and received BUT invalid 'bNumTransfer' or 'bmLatencyReliability' values */
  	            callback_param_ptr ->usb_phdc_status = USB_PHDC_RX_ERR_METADATA_EXPECTED;
  	             
  	            /* Performs a SetFeature(Endpoint_Halt) command  followed by a ClearFeature(Endpoint_Halt) */
  	            /* Prototype:  USB_STATUS  _usb_host_ch9_set/clear_feature(dev_handle, req_type, intf_endpt,feature) where: */
  	            /* REQ_TYPE_ENDPOINT = 0x02, ENDPOINT_HALT = 0x01 defined in "host_ch9.h" */               
  	            status = _usb_host_ch9_set_feature(dev, REQ_TYPE_ENDPOINT, (uint_8)(pipe_desc_ptr ->ENDPOINT_NUMBER | pipe_desc_ptr ->DIRECTION), ENDPOINT_HALT);
  	          
  	            if((USB_STATUS_TRANSFER_QUEUED != status) && (USB_OK != status))
  	            {
  	              callback_param_ptr ->usb_phdc_status = USB_PHDC_ERR_ENDP_CLEAR_STALL;  
  	            }
  	            else
  	            {	          	
  	              status = _usb_host_ch9_clear_feature(dev, REQ_TYPE_ENDPOINT, (uint_8)(pipe_desc_ptr ->ENDPOINT_NUMBER | pipe_desc_ptr ->DIRECTION), ENDPOINT_HALT);	          	
  	          	  if((USB_STATUS_TRANSFER_QUEUED != status) && (USB_OK != status)) 
  	              {
  	            	  callback_param_ptr ->usb_phdc_status = USB_PHDC_ERR_ENDP_CLEAR_STALL; 
  	              }
  	              else
  	              {
  	            	  /* Reset the 'numTransfBulkIn' parameter in order to expect a new metadata preamble */
  	             	  phdc_cis_ptr ->numTransfBulkIn = 0;              
  	              }
  	            } /* End checking the status of SetFeature/Clear Feature(Endpoint_Halt) operations */                
  	          }
  	          else
  	          { /* Metadata preamble packet is correct */
  	          
  	            /* Compare the 'bmLatencyReliability' of the incoming metadata preamble with the QoS Descriptor attached to device's Bulk IN endpoint */
  	            /* Search in the USB_PHDC_DESC_QOS_METADATA_LIST the endpoint number corresponding to the Bulk IN */
                phdcQosMetadataListParser = usb_class_phdc_search_endpoint_type(phdc_cis_ptr ->qosMetadataList, ENDPOINT_BULK, ENDPOINT_DIR_IN);
  	          	                                                     
  	            if(phdcQosMetadataListParser != NULL)
  	            { /* Descriptor was found */
  	                
  	              /* Compare the qos bin with 'bmLatencyReliability' field from the corresponding QoS Descriptor */
  	              if(!(pMetaDataPreamble ->bmLatencyReliability & phdcQosMetadataListParser ->pQosDesc ->bmLatencyReliability))
  	              {
  	                /* ERROR: Metadata preamble's 'bmLatencyReliability' is not supported by the Bulk IN PHDC QoS Descriptor */
  	                callback_param_ptr ->usb_phdc_status = USB_PHDC_ERR;   
  	              }
  	              else
  	              {
  	                /* Metadata preamble received correctly */
  	                callback_param_ptr ->usb_phdc_status = USB_PHDC_RX_OK; 
  	                 
  	                /* Reloads the 'numTransfBulkIn' parameter with the value stored in received metadata preamble */
  	                phdc_cis_ptr ->numTransfBulkIn = pMetaDataPreamble ->bNumTransfers;              
  	              }
  	            }
  	            else
  	            { /* Descriptor not found */                              
  	              callback_param_ptr ->usb_phdc_status = USB_PHDC_ERR;                
  	            }                    
  	          }            
  	        }
  	        else
  	        { /* Message data received */
  	          
  	          /* ERROR: metadata preamble expected but message data received */
  	          callback_param_ptr ->usb_phdc_status = USB_PHDC_RX_ERR_METADATA_EXPECTED;
  	                       
  	          /* Performs a  SetFeature(Endpoint_Halt) command  followed by a ClearFeature(Endpoint_Halt) */
  	          status = _usb_host_ch9_set_feature(dev, REQ_TYPE_ENDPOINT, (uint_8)(pipe_desc_ptr ->ENDPOINT_NUMBER | pipe_desc_ptr ->DIRECTION), ENDPOINT_HALT);
  	          if((USB_STATUS_TRANSFER_QUEUED != status) && (USB_OK != status))
  	          {
  	            callback_param_ptr ->usb_phdc_status = USB_PHDC_ERR_ENDP_CLEAR_STALL;  
  	          }
  	          else
  	          {
  	            status = _usb_host_ch9_clear_feature(dev, REQ_TYPE_ENDPOINT, (uint_8)(pipe_desc_ptr ->ENDPOINT_NUMBER | pipe_desc_ptr ->DIRECTION), ENDPOINT_HALT);
  	            if((USB_STATUS_TRANSFER_QUEUED != status) && (USB_OK != status))
  	            {
  	              callback_param_ptr ->usb_phdc_status = USB_PHDC_ERR_ENDP_CLEAR_STALL; 
  	            }
  	            else
  	            {
  	       	 	    /* Reset the 'numTransfBulkIn' parameter in order to expect a new metadata preamble */
  	          	  phdc_cis_ptr ->numTransfBulkIn = 0;              
  	            }
  	          } /* End checking the status of SetFeature/Clear Feature(Endpoint_Halt) operations */                          
  	        } /* End checking the incoming packet */
  	      } /* End checking the expectation of metadata */
  	    }
  	    else
  	    {
  	      if((phdc_cis_ptr ->preambleCapability == FALSE) && (phdc_cis_ptr ->deviceFeatureSet == FALSE))
  	      {  /* Neither preamble capability supported nor enabled */
  	         
  	        /* Packet received is assumed to be data (no metadata preamble check) */
  	        callback_param_ptr ->usb_phdc_status = USB_PHDC_RX_OK;
  	      }
  	    } /* End checking the preamble capability */   
  	  } /* End checking the type of pipe */ 
    } /* End checking the class validation */
  } /* End checking the returned USB status */
	 
	/* Populates the 'usb_status and buff_size' in the USB_PHDC_PARAM */
	callback_param_ptr ->usb_status 	 = usb_status;
	callback_param_ptr ->buff_size     = buff_size;
	

	/* Call the application callback function unless the callback pointer is NULL */
	if(NULL != phdc_cis_ptr ->recvCallback) 
	{
	  phdc_cis_ptr ->recvCallback(callback_param_ptr);
	}
 
 
  USB_unlock (); 
} /* EndBody */



/* PUBLIC FUNCTION*--------------------------------------------------------
* 
* Function Name  : usb_class_phdc_search_endpoint_type
* Returned Value : USB_STATUS
* Comments: This function search in the USB_PHDC_DESC_QOS_METADATA_LIST the endpoint
*           corresponding to the type given as argument 
* 
*END*--------------------------------------------------------------------*/
static USB_PHDC_DESC_QOS_METADATA_LIST*  usb_class_phdc_search_endpoint_type
  (
    USB_PHDC_DESC_QOS_METADATA_LIST* phdcQosMetaList_ptr, 
    uint_8 ep_type, 
    uint_8 ep_dir
  )
{ /* Body */
	          
  /* used to search a specific QoS descriptor in the linked list of Endpoint-QoS-Metadata descriptors */
  USB_PHDC_DESC_QOS_METADATA_LIST* 	phdcQosMetadataListParser = phdcQosMetaList_ptr;
            
  while(phdcQosMetadataListParser -> pNext != NULL) 
  {
    /* Check if the endpoint is Bulk IN */
    if(
       (((uint_8)(phdcQosMetadataListParser ->pEndpointDesc ->bmAttributes) & ENDPOINT_TRANSFER_TYPE) == ep_type) &&        /* Endpoint type */
       (((uint_8)(phdcQosMetadataListParser ->pEndpointDesc ->bEndpointAddress) & ENDPOINT_DIRECTION) == ep_dir)            /* Endpoint direction */
      )
    {
  		return phdcQosMetadataListParser; 
    }

    /* Points to the next element in the list */
    phdcQosMetadataListParser = phdcQosMetadataListParser -> pNext;             	                 
  }	
  
  return NULL;
} /* Endbody */


/* PUBLIC FUNCTION*--------------------------------------------------------
* 
* Function Name  : usb_class_phdc_send_control_request
* Returned Value : USB_STATUS
* Comments: This function implements class specific request: PHDC_GET_STATUS_BREQ, PHDC_SET_FEATURE_BREQ and      :
* PHDC_CLEAR_FEATURE_BREQ    
* 
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_phdc_send_control_request(USB_PHDC_PARAM* call_param_ptr)
{ /* Body */
  USB_STATUS                       status = USBERR_NO_INTERFACE;
  USB_SETUP                        request;
  USB_PHDC_CLASS_INTF_STRUCT*      intf_ptr;
  uint_16                          targetInterface;                        
  uint_8                           reqType; 

  #ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_phdc_send_control_request");
  #endif
  /* parameter checking*/
  if(call_param_ptr == NULL)
  {
    return USBERR_ERROR;
  }
     /*make sure that no USB event occurs until the function ends*/
  USB_lock();
  intf_ptr = (USB_PHDC_CLASS_INTF_STRUCT*)call_param_ptr->ccs_ptr->class_intf_handle;
  /* make sure that the interface is a valid one*/
  if (!usb_host_class_intf_validate(call_param_ptr->ccs_ptr)) 
  {
    USB_unlock();
    #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_phdc_send_control_request, error status");
    #endif
    return status;
  } /* Endif */
  reqType =  call_param_ptr->classRequestType;
  /* read interface number from the interface descriptor*/
  targetInterface = ((INTERFACE_DESCRIPTOR_PTR)intf_ptr->generalClass.intf_handle)->bInterfaceNumber;
  switch(reqType)
  {
    case PHDC_GET_STATUS_BREQ:
      /* status bytes are to be received from the device, so, make sure that buff_ptr isn't NULL */
     	if(call_param_ptr->buff_ptr == NULL)
     	{
     	  USB_unlock();
     	  return USBERR_ERROR;
     	}
     	/* populate the USB_SETUP structure for the status request */
     	request.BMREQUESTTYPE = PHDC_GET_STATUS_BMREQTYPE;   	
     	request.BREQUEST = PHDC_GET_STATUS_BREQ;
     	*(uint_16*)request.WVALUE  = 0;
     	*(uint_16*)request.WINDEX  = HOST_TO_LE_SHORT(targetInterface);  
        *(uint_16*)request.WLENGTH = HOST_TO_LE_SHORT(2);
      break;

    case PHDC_SET_FEATURE_BREQ:
    case PHDC_CLEAR_FEATURE_BREQ:
      /* make sure that the device supports metadata message preambul feature */
     	if(intf_ptr->preambleCapability == 0)
     	{
     	  USB_unlock();
     	  return USBERR_INVALID_REQ_TYPE;
     	}
     	/* make sure that no other set/clear feature request is in progress*/
     	if(intf_ptr->setClearRequestPending) 
      {
        USB_unlock();
     	  return USBERR_TRANSFER_IN_PROGRESS;
      }
      /* To avoid synchronization issues with preamble */ 
     	/* make sure that no send or receive transactions are pending  */
     	if(usb_class_phdc_interface_transfers_pending(intf_ptr))
     	{
     	  USB_unlock();
     	  return USBERR_TRANSFER_IN_PROGRESS;	
     	}
     	/* populate the USB_SETUP structure for the set/clear feature request */
     	if(reqType == PHDC_SET_FEATURE_BREQ)
     	{
     	  request.BMREQUESTTYPE = PHDC_SET_FEATURE_BMREQTYPE;
     	  request.BREQUEST = PHDC_SET_FEATURE_BREQ;	
     	}
     	else
     	{
     	  request.BMREQUESTTYPE = PHDC_CLEAR_FEATURE_BMREQTYPE;
     	  request.BREQUEST = PHDC_CLEAR_FEATURE_BREQ;	
     	}

     	request.WVALUE[0] = PHDC_FEATURE_METADATA;
     	request.WVALUE[1] = PHDC_QoS_ENCODING_VERSION;
     	*(uint_16*)request.WINDEX = HOST_TO_LE_SHORT(targetInterface);
     	*(uint_16*)request.WLENGTH = 0;
     	/* set the setClearRequestPending flag to indicate that  */
     	/* a set/clear feature request is in progress.This flag  */
     	/* will be cleared in the phdc send control request callback */
     	/* or later in this function if _usb_hostdev_cntrl_request returns error*/
     	intf_ptr->setClearRequestPending = TRUE;
     	break;

    default:
      USB_unlock(); 
     	return USBERR_INVALID_REQ_TYPE;   
  }
     /* call _usb_hostdev_cntrl_request function to send the control request over the USB */
  status = _usb_hostdev_cntrl_request (intf_ptr->generalClass.dev_handle,
        &request, call_param_ptr->buff_ptr, usb_class_phdc_send_control_callback, call_param_ptr);
        
  if((status != USB_STATUS_TRANSFER_QUEUED) && (status != USB_OK))
  {
    if((reqType == PHDC_SET_FEATURE_BREQ) || (reqType == PHDC_CLEAR_FEATURE_BREQ))
    {
      intf_ptr->setClearRequestPending = FALSE;	
    }
  }
  USB_unlock();
  #ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_phdc_send_control_request, SUCCESSFUL");
  #endif

  return status;
} /* Endbody */

/* PRIVATE FUNCTIONS *----------------------------------------------------*/

/* usb_class_phdc_send_data_callback
 * this function is called by USB host API
 * Parameters: pointer   pipe_handle
               pointer   call_param_ptr
               uchar_ptr data_ptr
               uint_32   data_size
               uint_32   usb_status
 * Returns: void
 */
static void usb_class_phdc_send_data_callback
(
    _usb_pipe_handle pipe_handle,
    pointer          call_param_ptr,
    uchar_ptr        data_ptr,
    uint_32          data_size,
    USB_STATUS       usb_status
)
{
  PIPE_STRUCT_PTR pipe_ptr = (PIPE_STRUCT_PTR) pipe_handle;
  USB_PHDC_CLASS_INTF_STRUCT* class_interface_handle;
  USB_PHDC_PARAM*             param_ptr;
  USB_STATUS                  status;

  /* exit if input pointer is NULL */
  if(NULL == call_param_ptr)
  {
    return;
  }
  param_ptr = call_param_ptr;

  /* make sure that no USB event occurs until the function end */
  USB_lock ();

  /* validate the interface */
  if( usb_host_class_intf_validate(param_ptr->ccs_ptr) )
  { /* populate the USB_PHDC_PARAM structure using the data provided by the host API */
    param_ptr->usb_status  = usb_status;
    class_interface_handle = (USB_PHDC_CLASS_INTF_STRUCT *)param_ptr->ccs_ptr->class_intf_handle;

    /* verify the USB error code and generate the PHDC specific error code */
    if(USB_OK == usb_status)
    {
      param_ptr->usb_phdc_status = USB_PHDC_TX_OK;
    }
    else
    {
      param_ptr->usb_phdc_status = USB_PHDC_ERR;
      /* if deivce's endpoint is stalled , try to clear this status */
      if(USBERR_ENDPOINT_STALLED == usb_status)
      { /* if the 'clear feature' operation fails, exit with error code */
        status = _usb_host_ch9_clear_feature
                 ( class_interface_handle->generalClass.dev_handle,
                   REQ_TYPE_ENDPOINT,
                   pipe_ptr->ENDPOINT_NUMBER | REQ_TYPE_OUT,
                   ENDPOINT_HALT );
        if( (status != USB_OK) && (status != USB_STATUS_TRANSFER_QUEUED))
        {
          param_ptr->usb_phdc_status = USB_PHDC_ERR_ENDP_CLEAR_STALL;
        }
      }
    }

    /* verify the callback pointer and if != NULL, launch the application's callback function */
    if(NULL != class_interface_handle->sendCallback)
    {
      class_interface_handle->sendCallback(param_ptr);
    }
  }
  USB_unlock();
}

/*------------------------------------------------------------------------*/

/* usb_class_phdc_interface_transfers_pending
 * this function checks if there are active transfers at the PHDC interface level
 * it checks all the pipes for transfers using the usb_class_phdc_pipe_transfers_pending function
 * WARNING: This function presumes that USB interrupts are disabled
 * Returns: TRUE  = the provided interface has active transfers
 *          FALSE = the provided interface does not have active transfers
 */
static boolean usb_class_phdc_interface_transfers_pending(USB_PHDC_CLASS_INTF_STRUCT  *phdc_intf)
{
 boolean returnValue = FALSE;
  
 if(phdc_intf != NULL)
 {
    returnValue = usb_class_phdc_pipe_transfers_pending(phdc_intf->controlPipe);
    if(returnValue == FALSE)
    {
      returnValue = usb_class_phdc_pipe_transfers_pending(phdc_intf->bulkInPipe);
      if(returnValue == FALSE)
      {
        returnValue = usb_class_phdc_pipe_transfers_pending(phdc_intf->bulkOutPipe);
        if(returnValue == FALSE)
        {
          returnValue = usb_class_phdc_pipe_transfers_pending(phdc_intf->intInPipe);
        }
      }
    }
 }

 return returnValue;
}
/*------------------------------------------------------------------------*/

/* usb_class_phdc_pipe_transfers_pending
 * this function checks if there are active transfers on a pipe
 * WARNING: This function presumes that USB interrupts are disabled
 * Returns: TRUE = the provided pipe has active transfers
 *          FALSE = the provided pipe does not have active transfers
 */
static boolean usb_class_phdc_pipe_transfers_pending
(
    _usb_pipe_handle pipe_handle
)
{
 PIPE_STRUCT_PTR pipe_ptr = (PIPE_STRUCT_PTR) pipe_handle;
 boolean returnValue = FALSE;
 

 if(pipe_ptr != NULL)
 {
  /* Search the pipe active transfer list */
  TR_STRUCT_PTR tr_ptr = pipe_ptr->tr_list_ptr;

  while((tr_ptr != NULL) && (tr_ptr->TR_INDEX == 0))
  {
   if(pipe_ptr->tr_list_ptr != tr_ptr->NEXT)
   {
    tr_ptr = tr_ptr->NEXT;
   }
   else
   {
    tr_ptr = NULL; /* End of the list reached */
   }
  }
  
  if(tr_ptr != NULL)
  {
   /* TR_INDEX found to be != 0. This pipe has queued transfers */
   returnValue = TRUE;
  }

 }

 return returnValue;
}

/*------------------------------------------------------------------------*/

static void usb_class_phdc_uninit_interface(CLASS_CALL_STRUCT_PTR   phdc_call_ptr)
{
 USB_PHDC_CLASS_INTF_STRUCT  *phdc_intf = phdc_call_ptr->class_intf_handle;
 
 usb_class_phdc_free_qos_metadata_list(phdc_intf);
 
 /* Invalidate the code_key */

 phdc_call_ptr->class_intf_handle = NULL;
 phdc_call_ptr->code_key = 0;
}

/*------------------------------------------------------------------------*/

static void usb_class_phdc_free_qos_metadata_list(USB_PHDC_CLASS_INTF_STRUCT *phdc_intf)
{
 /* Check for allocated memory inside the interface structure */
 USB_PHDC_DESC_QOS_METADATA_LIST *qosMetadataTail = phdc_intf->qosMetadataList; 
 
 while(qosMetadataTail != NULL)
 {
  /* Ok we got a location to be freed. Save this pointer location */
  USB_PHDC_DESC_QOS_METADATA_LIST *qosMetadataLast = qosMetadataTail;
  
  /* Increment the tail for the next iteration */
  qosMetadataTail = qosMetadataTail->pNext;
  
  /* Free the saved location */
  USB_mem_free(qosMetadataLast);
 }
 
 /* Clear the interface allocated memory */
 USB_mem_zero (phdc_intf, sizeof(USB_PHDC_CLASS_INTF_STRUCT)); 
}

/*------------------------------------------------------------------------*/
/* usb_class_phdc_send_control_callback
 * this function will be called when a phdc control request completes
 * 
 * 
 */
/*-------------------------------------------------------------**
** Transaction callback parameters:                            **
**    pointer     pipe handle                                  **
**    pointer     parameter specified by higher level          **
**    uchar_ptr   pointer to buffer containing data (TX or RX) **
**    uint_32     length of data transferred                   **
**    USB_STATUS  status, preferably USB_OK or USB_DONE etc.   **
**-------------------------------------------------------------*/

static void usb_class_phdc_send_control_callback(pointer pipeHandle, pointer callbackParam, uchar_ptr bBuff, uint_32 length, USB_STATUS usb_status)
{
  USB_PHDC_CLASS_INTF_STRUCT*      intf_ptr;
  USB_PHDC_PARAM *                 call_param_ptr;
  uint_8                           reqType; 
  uint_8                           phdc_status = USB_PHDC_ERR;
  USB_STATUS                       status;
  /* parameter checking*/
  if(callbackParam != NULL)
  {
    call_param_ptr = (USB_PHDC_PARAM *)callbackParam;
    /*make sure that no USB event occurs until the function ends*/
    USB_lock();
    intf_ptr = (USB_PHDC_CLASS_INTF_STRUCT*)call_param_ptr->ccs_ptr->class_intf_handle;
    /* make sure that the interface is a valid one*/
    if(usb_host_class_intf_validate(call_param_ptr->ccs_ptr))
    {
      reqType = call_param_ptr->classRequestType;
      if((reqType == PHDC_SET_FEATURE_BREQ) || (reqType == PHDC_CLEAR_FEATURE_BREQ))
      {
        /*clear the setClearRequestPending to enable another set/clear feature requests*/
        intf_ptr->setClearRequestPending = FALSE; 	
      }
      /* update the status of the deviceFeatureSet flag and the phdc status */
      /* if the _usb_hostdev_cntrl_request completes successfully */
      if(usb_status == USB_OK)
      {
        phdc_status = USB_PHDC_CTRL_OK;
        if(reqType == PHDC_SET_FEATURE_BREQ )
        {
          intf_ptr->deviceFeatureSet = TRUE;	
        }
        else if(reqType == PHDC_CLEAR_FEATURE_BREQ )
        {
          intf_ptr->deviceFeatureSet = FALSE;	
        }
      }
      /* clear the stall condition if the control endpoint is stalled  */
      else if(usb_status == USBERR_ENDPOINT_STALLED)	
      {
        status =  _usb_host_ch9_clear_feature(intf_ptr->generalClass.dev_handle,
                    REQ_TYPE_ENDPOINT, ((PIPE_STRUCT_PTR)pipeHandle)->ENDPOINT_NUMBER , ENDPOINT_HALT);
     	  if((status != USB_STATUS_TRANSFER_QUEUED ) && (status != USB_OK ))
     	  {
     	    phdc_status = USB_PHDC_ERR_ENDP_CLEAR_STALL;
     	  }
      }
      /* if a user control request callback was installed update the USB_PHDC_PARAM */
      /* structure and launch the callback*/
      if(*intf_ptr->ctrlCallback != NULL)
      {
        call_param_ptr->usb_phdc_status =  phdc_status;
        call_param_ptr->usb_status =   usb_status;
        if(usb_status == USB_OK)
        {
          call_param_ptr->buff_size =   length;	
        }
        (*intf_ptr->ctrlCallback)(call_param_ptr) ;	
      }
    }
    USB_unlock();
  }
}  /* Endbody */

/*------------------------------------------------------------------------*/

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/mqx/sh_tad.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved

*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_tad.c$
* $Version : 3.0.1.0$
* $Date    : Jun-9-2009$
*
* Comments:
*
*   This file contains the MQX shell command.
*
*END************************************************************************/


#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <tad.h>
#include "shell.h"


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_tad
*  Returned Value:  none
*  Comments  :  SHELL utility to print memory and stack usage.
*
*END*-----------------------------------------------------------------*/

int_32  Shell_tad (int_32 argc, char_ptr argv[])
{ /* Body */
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;

   print_usage = Shell_check_help_request (argc, argv, &shorthelp);

   if (! print_usage)  
   {
      if (argc == 1)  
      {
         _tad_stack_usage ();
         _tad_lightweight_memory_blocks ();
      } 
      else if (argc == 2) 
      {
         if (! strcmp ("stack", argv[1])) 
         {
            _tad_stack_usage ();
         }
         else if (! strcmp ("lwmemblock", argv[1])) 
         {
            _tad_lightweight_memory_blocks ();
         }
         else
         {
            printf("Error, %s invoked with unknown argument %s\n", argv[0], argv[1]);
            return_code = SHELL_EXIT_ERROR;
            print_usage = TRUE;
         }
      } 
      else 
      {
         printf("Error, %s invoked with incorrect number of arguments\n", argv[0]);
         return_code = SHELL_EXIT_ERROR;
         print_usage = TRUE;
      }
   }
   
   if (print_usage)  
   {
      if (shorthelp)  
      {
         printf("%s [stack | lwmemblock]\n", argv[0]);
      } 
      else  
      {
         printf("Usage: %s [stack | lwmemblock]\n", argv[0]);
         printf("   stack      = prints stack usage\n");
         printf("   lwmemblock = prints lightweight memory blocks\n");
      }
   }
   return return_code;
} /* Endbody */



/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/msd/mfs/usbmfs.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usbmfs.c$
* $Version : 3.8.34.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the USB MFS mass storage link driver.
*
*END************************************************************************/

#include <mqx.h>
#include "usb.h"
#include "usb_prv.h"
#include "host_common.h"

#include "host_dev_list.h" //see below: workaround 

#ifdef __USB_OTG__
#include "otgapi.h"
#include "devapi.h"
#else
#include "hostapi.h"
#endif

#include "../usb_host_msd_bo.h"
#include "../usb_host_msd_ufi.h"
#include "usbmfs.h"
#include "usbmfspr.h"

/* Function declaration */
static void _io_usb_mfs_callback
(
    USB_STATUS,  /*status of this command*/
    pointer,     /*pointer to USB_MASS_BULK_ONLY_REQUEST_STRUCT*/
    pointer,     /*pointer to the command object*/
    uint_32      /* length of the data transfered if any */
);


static int_32 _io_usb_mfs_open_internal(IO_USB_MFS_STRUCT_PTR info_ptr, CLASS_CALL_STRUCT_PTR ccs_ptr);
static _mqx_int _io_usb_mfs_ioctl_stop(IO_USB_MFS_STRUCT_PTR info_ptr);
static _mqx_int _io_usb_mfs_read_sector_internal(IO_USB_MFS_STRUCT_PTR info_ptr, uint_32 sector, uint_16 how_many_sectors, uchar_ptr data_ptr);
static _mqx_int _io_usb_mfs_read_sector_long_internal(IO_USB_MFS_STRUCT_PTR info_ptr, uint_32 sector, uint_32 how_many_sectors, uchar_ptr data_ptr);
static _mqx_int _io_usb_mfs_write_sector_internal(IO_USB_MFS_STRUCT_PTR info_ptr, uint_32 sector, uint_16 how_many_sectors, uchar_ptr data_ptr);
static _mqx_int _io_usb_mfs_write_sector_long_internal(IO_USB_MFS_STRUCT_PTR info_ptr, uint_32 sector, uint_32 how_many_sectors, uchar_ptr data_ptr);
static _mqx_int _io_usb_mfs_read_write_sectors_internal(IO_USB_MFS_STRUCT_PTR info_ptr, char_ptr data_ptr, uint_32 num, boolean write, MQX_FILE_PTR fd_ptr);
static void _io_usb_mfs_callback(USB_STATUS command_status, pointer p1, pointer p2, uint_32 len);
static void _io_usb_ctrl_callback(pointer, pointer, uchar_ptr, uint_32, USB_STATUS);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_install
* Returned Value   : uint_32 - a task error code or MQX_OK
* Comments         :
*    Install a  USB-MFS mass storage device driver.
*
*END*----------------------------------------------------------------------*/

uint_32 _io_usb_mfs_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr                      identifier,

      /* [IN] Logical unit number which driver need to install */
      uint_8                        logical_unit,

      /* [IN] Interface Handle */
      CLASS_CALL_STRUCT_PTR         ccs_ptr

   )
{ /* Body */
   IO_USB_MFS_STRUCT_PTR            info_ptr;
   USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr = NULL;
   USB_STATUS                       error = USBERR_ERROR;
   uint_8                           *block_ptr, offset;

   /* Pointer validity-checking, clear memory, init header */
   USB_lock();
   if (usb_host_class_intf_validate(ccs_ptr)) {
      intf_ptr = (USB_MASS_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle;
      if(intf_ptr != NULL) {
         error = usb_hostdev_validate (intf_ptr->G.dev_handle);
      }
   } /* Endif */

   if (USB_OK != error) { /* Device was already detached or intf_ptr is NULL */
      USB_unlock();
      return MQX_OUT_OF_MEMORY;
   }

   if (USB_OK != _usb_hostdev_get_buffer(intf_ptr->G.dev_handle, sizeof(IO_USB_MFS_STRUCT), (pointer *) &info_ptr)) {
      USB_unlock();
      return MQX_OUT_OF_MEMORY;
   }

   USB_unlock();
   _mem_zero(info_ptr, sizeof(IO_USB_MFS_STRUCT));

   /* Fill in the state structure with the info we know */
   info_ptr->LUN         = logical_unit;
   info_ptr->BLENGTH     = USB_MFS_DEFAULT_SECTOR_SIZE;
   info_ptr->ERROR_CODE  = IO_OK;
   info_ptr->BLOCK_MODE  = TRUE;

   info_ptr->COMMAND.CBW_PTR = (CBW_STRUCT_PTR) &info_ptr->CBW;
   info_ptr->COMMAND.CSW_PTR = (CSW_STRUCT_PTR) &info_ptr->CSW;
   info_ptr->COMMAND.CALL_PTR = ccs_ptr;
   info_ptr->COMMAND.LUN = logical_unit;
   info_ptr->COMMAND.CALLBACK = _io_usb_mfs_callback;
   info_ptr->COMMAND_STATUS = MQX_OK;
   _lwsem_create(&info_ptr->LWSEM, 1);
   _lwsem_create(&info_ptr->COMMAND_DONE, 0);

   /* Workaround for the issue with device file specific structure, which is later on accessed by the MFS:
   ** We will return pointer to allocated block rather than USB-host buffer pointer (see USB _usb_hostdev_get_buffer)
   */
   block_ptr = (uint_8 *)info_ptr;
   offset = *(block_ptr - 1);
   block_ptr = block_ptr - offset - MEM_HEADER_LEN;

   _mem_set_type(block_ptr, MEM_TYPE_USB_MFS_STRUCT);
   return (_io_dev_install_ext(identifier,
      (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR, char_ptr,  char_ptr))_io_usb_mfs_open,
      (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR)                     )_io_usb_mfs_close,
      (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR, char_ptr,  int_32)  )_io_usb_mfs_read,
      (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR, char_ptr,  int_32)  )_io_usb_mfs_write,
      (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR, _mqx_uint, pointer) ) _io_usb_mfs_ioctl,
      _io_usb_mfs_uninstall,
      (pointer)block_ptr /* instead of info_ptr */
      ));

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_uninstall_internal
* Returned Value   : uint_32 error code
* Comments  :   Uninstalls the MSDOS File System and frees all memory allocated
*               to it.
*
*END*---------------------------------------------------------------------*/
int_32 _io_usb_mfs_uninstall
   (
       /* [IN] The device to uninstall */            
      IO_DEVICE_STRUCT_PTR   io_dev_ptr
   )
{ 
   DEV_MEMORY_PTR block_ptr;
   IO_USB_MFS_STRUCT_PTR info_ptr;

   /* Workaround for the issue with device file specific structure, which is later on accessed by the MFS:
   ** We will return pointer to allocated block rather than USB-host buffer pointer (see USB _usb_hostdev_get_buffer)
   */
   block_ptr = (DEV_MEMORY_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   info_ptr = (IO_USB_MFS_STRUCT_PTR)(block_ptr->payload.data + block_ptr->offset);

   _lwsem_destroy(&info_ptr->COMMAND_DONE);
   _lwsem_destroy(&info_ptr->LWSEM);
   /* The info_ptr will be disposed after device detach */
   //USB_mem_free(info_ptr);
   return MQX_OK;
}
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_open_internal
* Returned Value   : An error code or MQX_OK
* Comments         : Opens and initializes a USB-MFS mass storage device driver.
*                    Mass storage device should be initialized to prior to this
*                    this call.
*END*----------------------------------------------------------------------*/
static _mqx_int _io_usb_mfs_open_internal
   (
   IO_USB_MFS_STRUCT_PTR            info_ptr,
   CLASS_CALL_STRUCT_PTR            ccs_ptr 
   )
{ /* Body */
   uint_32     i;
   USB_STATUS error;

   error = usb_class_mass_getmaxlun_bulkonly(info_ptr->COMMAND.CALL_PTR, (uchar_ptr) &info_ptr->INQUIRY_DATA, _io_usb_ctrl_callback, info_ptr);
   if ((error != MQX_OK) && (error != USB_STATUS_TRANSFER_QUEUED)) {
      return IO_ERROR;
   } /* Endif */
   if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) != MQX_OK) {
      /* Cancel the command */
      usb_mass_ufi_cancel(&info_ptr->COMMAND);
      return IO_ERROR_TIMEOUT;
   } /* Endif */

   error = usb_mass_ufi_inquiry(&info_ptr->COMMAND, (uchar_ptr) &info_ptr->INQUIRY_DATA, sizeof(INQUIRY_DATA_FORMAT));
   if ((error != MQX_OK) && (error != USB_STATUS_TRANSFER_QUEUED)) {
      return IO_ERROR_INQUIRE;
   } /* Endif */
   if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) != MQX_OK) {
      /* Cancel the command */
      usb_mass_ufi_cancel(&info_ptr->COMMAND);
      return IO_ERROR_TIMEOUT;
   } /* Endif */


   if (info_ptr->COMMAND_STATUS != MQX_OK) {
      return IO_ERROR_INQUIRE;
   } /* Endif */

   for (i = 0; i < USBCFG_MFS_MAX_RETRIES; i++) {
      if (i) {
         /* Delay for a user-specified amount of time */
         _time_delay_ticks(USBCFG_MFS_OPEN_READ_CAPACITY_RETRY_DELAY);
      }
      
      /* Send the call now */
      error = usb_mass_ufi_read_capacity(&info_ptr->COMMAND, (uchar_ptr) &info_ptr->CAPACITY,
         sizeof(MASS_STORAGE_READ_CAPACITY_CMD_STRUCT_INFO));

      if ((error!=MQX_OK) && (error!=USB_STATUS_TRANSFER_QUEUED)) {
         return IO_ERROR_READ;
      } /* Endif */

      if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) != MQX_OK) {
         usb_mass_ufi_cancel(&info_ptr->COMMAND);
         return IO_ERROR_TIMEOUT;
      } /* Endif */
      
      if (info_ptr->COMMAND_STATUS == MQX_OK)
         break;
      
      
      error = usb_mass_ufi_request_sense(&info_ptr->COMMAND, &info_ptr->SENSE, sizeof(REQ_SENSE_DATA_FORMAT));

      if ((error != MQX_OK) && (error != USB_STATUS_TRANSFER_QUEUED)) {
         return IO_ERROR_READ;
      }

      if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) != MQX_OK) {
         usb_mass_ufi_cancel(&info_ptr->COMMAND);
         return IO_ERROR_TIMEOUT;
      }
   }
   
   if (info_ptr->COMMAND_STATUS == MQX_OK) {
      info_ptr->BCOUNT = LONG_BE_TO_HOST(*(uint_32*)&info_ptr->CAPACITY.BLLBA);
      info_ptr->BLENGTH = LONG_BE_TO_HOST(*(uint_32*)&info_ptr->CAPACITY.BLENGTH);

      /* should read this to support  low level format */
      info_ptr->NUMBER_OF_HEADS   = 0;
      info_ptr->NUMBER_OF_TRACKS  = 0;
      info_ptr->SECTORS_PER_TRACK = 0;

      info_ptr->SIZE_BYTES = info_ptr->BLENGTH * info_ptr->BCOUNT;
   } /* Endif */
   
   return (_mqx_int)info_ptr->COMMAND_STATUS;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_open
* Returned Value   : An error code or MQX_OK
* Comments         : Opens and initializes a USB-MFS mass storage device driver.
*                    Mass storage device should be initialized to prior to this
*                    this call.
*END*----------------------------------------------------------------------*/
_mqx_int _io_usb_mfs_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR       fd_ptr,

      /* [IN] the remaining portion of the name of the device */
      char_ptr           open_name_ptr,

      /* [IN] USB mass storage class handle */
      char_ptr           flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR             io_dev_ptr = fd_ptr->DEV_PTR;
   CLASS_CALL_STRUCT_PTR            ccs_ptr = (CLASS_CALL_STRUCT_PTR)flags;
   _mqx_int                         io_error;
   DEV_MEMORY_PTR                   block_ptr;
   IO_USB_MFS_STRUCT_PTR            info_ptr;

   /* Workaround for the issue with device file specific structure, which is later on accessed by the MFS:
   ** We will return pointer to allocated block rather than USB-host buffer pointer (see USB _usb_hostdev_get_buffer)
   */
   block_ptr = (DEV_MEMORY_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   info_ptr = (IO_USB_MFS_STRUCT_PTR)(block_ptr->payload.data + block_ptr->offset);

   /* Save the mass storage class handle. */
   info_ptr->MSC_STREAM = (pointer) ccs_ptr;

   /* Send the call now */
   _lwsem_wait(&info_ptr->LWSEM);
   io_error = _io_usb_mfs_open_internal(info_ptr, ccs_ptr);
   _lwsem_post(&info_ptr->LWSEM);

   return io_error;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_close
* Returned Value   : ERROR CODE
* Comments         : Closes the USB mass storage link driver
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_usb_mfs_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */
   return(MQX_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_read
* Returned Value   : number of bytes read
* Comments         : Reads data from the USB mass storage device
*
*END*----------------------------------------------------------------------*/
_mqx_int _io_usb_mfs_read
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR         fd_ptr,
      /* [IN] where the outgoing data is store */
      char_ptr             data_ptr,
      /* [IN] the number of bytes to output */
      int_32               num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   io_dev_ptr = fd_ptr->DEV_PTR;
   _mqx_int               io_result;
   DEV_MEMORY_PTR         block_ptr;
   IO_USB_MFS_STRUCT_PTR  info_ptr;

   /* Workaround for the issue with device file specific structure, which is later on accessed by the MFS:
   ** We will return pointer to allocated block rather than USB-host buffer pointer (see USB _usb_hostdev_get_buffer)
   */
   block_ptr = (DEV_MEMORY_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   info_ptr = (IO_USB_MFS_STRUCT_PTR)(block_ptr->payload.data + block_ptr->offset);

   _lwsem_wait(&info_ptr->LWSEM);
   io_result = _io_usb_mfs_read_write_sectors_internal(info_ptr, data_ptr, (uint_32)num, FALSE, fd_ptr);
   _lwsem_post(&info_ptr->LWSEM);
   return io_result;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_write
* Returned Value   : number of bytes written
* Comments         : Writes data to the USB mass storage device
*
*END*----------------------------------------------------------------------*/
int_32 _io_usb_mfs_write
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR         fd_ptr,
      /* [IN] where the outgoing data is store */
      char_ptr             data_ptr,
      /* [IN] the number of bytes to output */
      int_32               num
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   io_dev_ptr = fd_ptr->DEV_PTR;
   int_32                  results;
   DEV_MEMORY_PTR         block_ptr;
   IO_USB_MFS_STRUCT_PTR  info_ptr;

   /* Workaround for the issue with device file specific structure, which is later on accessed by the MFS:
   ** We will return pointer to allocated block rather than USB-host buffer pointer (see USB _usb_hostdev_get_buffer)
   */
   block_ptr = (DEV_MEMORY_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   info_ptr = (IO_USB_MFS_STRUCT_PTR)(block_ptr->payload.data + block_ptr->offset);

   _lwsem_wait(&info_ptr->LWSEM);

    results = _io_usb_mfs_read_write_sectors_internal(info_ptr, data_ptr, (uint_32)num, TRUE, fd_ptr);

   _lwsem_post(&info_ptr->LWSEM);
   return(results);
} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*-------------------------------------------------------------------------*/
static _mqx_int _io_usb_mfs_ioctl_stop
   (
   IO_USB_MFS_STRUCT_PTR       info_ptr 
   )
{ /* Body */
   MASS_STORAGE_START_STOP_UNIT_STRUCT_INFO  start_stop;
   USB_STATUS  error;
   _mqx_int    io_result = IO_ERROR;

   start_stop.START = 0;
   start_stop.LOEJ  = 0;
   error = usb_mass_ufi_start_stop(&info_ptr->COMMAND, start_stop.LOEJ, start_stop.START);
   if ((error==MQX_OK) || (error==USB_STATUS_TRANSFER_QUEUED)) {
      if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) == MQX_OK) {
         if (info_ptr->COMMAND_STATUS == MQX_OK) {
            io_result =  MQX_OK;
         } /* Endif */
      } else {
         usb_mass_ufi_cancel(&info_ptr->COMMAND);
      } /* Endif */
   } /* Endif */
   return(io_result);

} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*-------------------------------------------------------------------------*/
int_32 _io_usb_mfs_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the ioctl command */
      int_32       command,

      /* [IN] the ioctl parameters */
      pointer      input_param_ptr
   )
{ /* Body */
   USB_MFS_DRIVE_INFO_STRUCT_PTR drive_info_ptr;
   IO_DEVICE_STRUCT_PTR          io_dev_ptr = fd_ptr->DEV_PTR;
   int_32                        result = MQX_OK;
   uint_32_ptr                   param_ptr = input_param_ptr;
   DEV_MEMORY_PTR                block_ptr;
   IO_USB_MFS_STRUCT_PTR         info_ptr;

   /* Workaround for the issue with device file specific structure, which is later on accessed by the MFS:
   ** We will return pointer to allocated block rather than USB-host buffer pointer (see USB _usb_hostdev_get_buffer)
   */
   block_ptr = (DEV_MEMORY_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   info_ptr = (IO_USB_MFS_STRUCT_PTR)(block_ptr->payload.data + block_ptr->offset);

   switch (command) {
      case IO_IOCTL_GET_NUM_SECTORS:
      case USB_MFS_IOCTL_GET_NUM_SECTORS:
         *param_ptr = info_ptr->BCOUNT;
         break;

      case IO_IOCTL_GET_BLOCK_SIZE:
         *param_ptr = info_ptr->BLENGTH;
         break;

      case IO_IOCTL_DEVICE_IDENTIFY:
         param_ptr[0] = IO_DEV_TYPE_PHYS_USB_MFS;
         param_ptr[1] = IO_DEV_TYPE_LOGICAL_MFS;
         param_ptr[2] = IO_DEV_ATTR_ERASE | IO_DEV_ATTR_POLL
                         | IO_DEV_ATTR_READ | IO_DEV_ATTR_REMOVE
                         | IO_DEV_ATTR_SEEK | IO_DEV_ATTR_WRITE;
         if (info_ptr->BLOCK_MODE) {
            param_ptr[2] |= IO_DEV_ATTR_BLOCK_MODE;
         } /* Endif */
         break;

      case USB_MFS_IOCTL_GET_DRIVE_PARAMS:
         drive_info_ptr = (USB_MFS_DRIVE_INFO_STRUCT_PTR)((pointer)param_ptr);
         drive_info_ptr->NUMBER_OF_HEADS   = info_ptr->NUMBER_OF_HEADS;
         drive_info_ptr->NUMBER_OF_TRACKS  = info_ptr->NUMBER_OF_TRACKS;
         drive_info_ptr->SECTORS_PER_TRACK = info_ptr->SECTORS_PER_TRACK;
         break;

      case IO_IOCTL_GET_VENDOR_INFO:
         *param_ptr = (uint_32)&(info_ptr->INQUIRY_DATA.BVID);
         break;

      case IO_IOCTL_GET_PRODUCT_ID:
         *param_ptr = (uint_32)&(info_ptr->INQUIRY_DATA.BPID);
         break;

      case IO_IOCTL_GET_PRODUCT_REV:
         *param_ptr = (uint_32)&(info_ptr->INQUIRY_DATA.BPRODUCT_REV);
         break;

      case USB_MFS_IOCTL_DEVICE_STOP:
         /* Send the call now */
         _lwsem_wait(&info_ptr->LWSEM);
         

         result = _io_usb_mfs_ioctl_stop(info_ptr);

            /* Wait for the completion*/
         _lwsem_post(&info_ptr->LWSEM);


         break;

         /* Start CR 812 */
      case IO_IOCTL_SET_BLOCK_MODE:
      case USB_MFS_IOCTL_SET_BLOCK_MODE:
         info_ptr->BLOCK_MODE = TRUE;
         break;
         /* End   CR 812 */

      default:
         result = IO_ERROR_INVALID_IOCTL_CMD;
         break;
   } /* Endswitch */
   return(result);

} /* Endbody */


/* Private functions */
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_read_sector
* Returned Value   : error code
* Comments         :
*
*
*END*----------------------------------------------------------------------*/
static _mqx_int _io_usb_mfs_read_sector_internal
   (
      /* [IN] USB MFS state structure */
      IO_USB_MFS_STRUCT_PTR  info_ptr,

      /* [IN] The sector number to read */
      uint_32                sector,

      /* [IN] How many sectors should read */
      uint_16                how_many_sectors,


      /* [IN] Location to read data into */
      uchar_ptr              data_ptr
   )
{ /* Body */
   uint_32        read_size;
   USB_STATUS     error;
   _mqx_int       io_result = IO_ERROR;
   uint_32        tries;

   /* UFI_READ10 command  */
   read_size = info_ptr->BLENGTH * how_many_sectors;

   /* Send the call now */
   for (tries=0;tries<USBCFG_MFS_MAX_RETRIES;tries++) {
      error = usb_mass_ufi_read_10(
         &info_ptr->COMMAND, sector, data_ptr, read_size, how_many_sectors);
      if ((error==MQX_OK) || (error==USB_STATUS_TRANSFER_QUEUED)) {
         if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) == MQX_OK) {
            if (info_ptr->COMMAND_STATUS == MQX_OK) {
               io_result = (_mqx_int)how_many_sectors;
               break;
            } /* Endif */
         } else {
            /* Wait for the completion*/
            usb_mass_ufi_cancel(&info_ptr->COMMAND);
         } /* Endif */
      }
      else 
      {
#ifdef _HOST_DEBUG_
          printf("\nUSBMFS retrying read sector");
#endif
      } /* Endif */

   } /* Endif */

   return(io_result);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_read_sector_long
* Returned Value   : error code
* Comments         :
*
*
*END*----------------------------------------------------------------------*/
static _mqx_int _io_usb_mfs_read_sector_long_internal
   (
      /* [IN] USB MFS state structure */
      IO_USB_MFS_STRUCT_PTR  info_ptr,

      /* [IN] The sector number to read */
      uint_32                sector,

      /* [IN] How many sectors should read */
      uint_32                how_many_sectors,

      /* [IN] Location to read data into */
      uchar_ptr              data_ptr
   )
{ /* Body */
   uint_32        read_size;
   USB_STATUS     error;
   _mqx_int       io_result = IO_ERROR;
   uint_32        tries;

   read_size = info_ptr->BLENGTH * how_many_sectors;

   /* Send the call now */
   for (tries=0;tries<USBCFG_MFS_MAX_RETRIES;tries++) {
      error = usb_mass_ufi_read_12(
         &info_ptr->COMMAND, sector, data_ptr, read_size, how_many_sectors);

      if ((error==MQX_OK) || (error==USB_STATUS_TRANSFER_QUEUED)) {
         if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) == MQX_OK) {
            if (info_ptr->COMMAND_STATUS == MQX_OK) {
               io_result = (_mqx_int) how_many_sectors;
               break;
   } /* Endif */
         } else {
            usb_mass_ufi_cancel(&info_ptr->COMMAND);
         } /* Endif */
      } /* Endif */
      //printf("\nUSBMFS retrying read sector long");
   } /* Endif */

   return (io_result);
} /* Endbody */




/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_write_sector
* Returned Value   : error code
* Comments         :
*
*
*END*----------------------------------------------------------------------*/
static _mqx_int _io_usb_mfs_write_sector_internal
   (
      /* [IN] USB MFS state structure */
      IO_USB_MFS_STRUCT_PTR  info_ptr,

      /* [IN] The sector number to write */
      uint_32                sector,

      /* [IN] How many sectors should read */
      uint_16                how_many_sectors,

      /* [IN] Source data location */
      uchar_ptr              data_ptr
   )
{ /* Body */
   uint_32        write_size;
   uint_32        tries;
   USB_STATUS     error;
   _mqx_int       io_result = IO_ERROR;

   if (sector <= info_ptr->BCOUNT) {

      write_size = info_ptr->BLENGTH * how_many_sectors;
      for (tries=0;tries<USBCFG_MFS_MAX_RETRIES;tries++) {
         error = usb_mass_ufi_write_10(&info_ptr->COMMAND,
               sector, data_ptr, write_size, how_many_sectors);
         if ((error==MQX_OK) || (error==USB_STATUS_TRANSFER_QUEUED)) {
            if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) == MQX_OK) {
               if (info_ptr->COMMAND_STATUS == MQX_OK) {
                  io_result = (_mqx_int) how_many_sectors;
                  break;
               } /* Endif */
            } else {

               /* Send the call now */

               /* Wait for the completion*/
               usb_mass_ufi_cancel(&info_ptr->COMMAND);
            } /* Endif */
         } /* Endif */
         //printf("\nUSBMFS retrying write sector");
      }
   } /* Endif */

   return (io_result);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_write_sector_long
* Returned Value   : error code
* Comments         :
*
*
*END*----------------------------------------------------------------------*/
static _mqx_int _io_usb_mfs_write_sector_long_internal
   (
      /* [IN] USB MFS state structure */
      IO_USB_MFS_STRUCT_PTR  info_ptr,

      /* [IN] The sector number to write */
      uint_32                sector,

      /* [IN] How many sectors should read */
      uint_32                how_many_sectors,

      /* [IN] Source data location */
      uchar_ptr              data_ptr
   )
{ /* Body */
   uint_32        write_size;
   USB_STATUS     error;
   _mqx_int       io_result = IO_ERROR;
   uint_32        tries;

   if (sector <= info_ptr->BCOUNT) {

      write_size = info_ptr->BLENGTH * how_many_sectors;
      for (tries=0;tries<USBCFG_MFS_MAX_RETRIES;tries++) {
         error = usb_mass_ufi_write_12(&info_ptr->COMMAND,
            sector, data_ptr, write_size, how_many_sectors);
         if ((error==MQX_OK) || (error==USB_STATUS_TRANSFER_QUEUED)) {
            if (_lwsem_wait_ticks(&info_ptr->COMMAND_DONE, USBCFG_MFS_LWSEM_TIMEOUT) == MQX_OK) {
               if (info_ptr->COMMAND_STATUS == MQX_OK) {
                  io_result = (_mqx_int) how_many_sectors;
                  break;
               } /* Endif */
            } else {

               /* Send the call now */
               usb_mass_ufi_cancel(&info_ptr->COMMAND);
            }
            /* Wait for the completion*/
         } /* Endif */
      }
   } /* Endif */

   return (io_result);
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_read_write_blocks
* Returned Value   : error or number of blocks read/written
* Comments         : This function is used to read/write blocks when driver
*   is in block mode
*
*END*----------------------------------------------------------------------*/
static _mqx_int _io_usb_mfs_read_write_sectors_internal
   (
      /* [IN] USB MFS state structure */
      IO_USB_MFS_STRUCT_PTR    info_ptr,

      /* [IN] where the newly-read bytes are to be stored */
      char_ptr                 data_ptr,

      /* [IN] the number of sectors to read */
      uint_32                  num,

      /* [IN] Read/write mode */
      boolean                  write,
      
      /* [IN] File pointer for checking file LOCATION and setting ERROR */
      MQX_FILE_PTR             fd_ptr
   )
{ /* Body */
   _mqx_int (_CODE_PTR_ rw_func_long)(IO_USB_MFS_STRUCT_PTR, uint_32, uint_32, uchar_ptr);
   _mqx_int (_CODE_PTR_ rw_func)(IO_USB_MFS_STRUCT_PTR, uint_32, uint_16, uchar_ptr);
   _mqx_int             io_result = IO_ERROR;
   _mqx_uint            io_error; 

   if (write) {
      io_error = IO_ERROR_WRITE_ACCESS;
      rw_func        = _io_usb_mfs_write_sector_internal;
      rw_func_long   = _io_usb_mfs_write_sector_long_internal;
   } else {
      io_error = IO_ERROR_READ_ACCESS;
      rw_func        = _io_usb_mfs_read_sector_internal;
      rw_func_long   = _io_usb_mfs_read_sector_long_internal;
   } /* Endif */


   if (fd_ptr->LOCATION >= info_ptr->BCOUNT) {
      fd_ptr->ERROR = io_error;
   } else {
      if ((num + fd_ptr->LOCATION) >= info_ptr->BCOUNT) {
         fd_ptr->ERROR = io_error;
         num = (uint_32)(info_ptr->BCOUNT - fd_ptr->LOCATION + 1);
      } /* Endif */

      /* Read all the sectors, one at a time */
      if (num > 0xFFFE) {
         /* Read all the sectors at once */
          io_result = rw_func_long(info_ptr, fd_ptr->LOCATION,
            num, (uchar_ptr)data_ptr);
      } else {
          io_result = rw_func(info_ptr, fd_ptr->LOCATION,
            (uint_16)num, (uchar_ptr)data_ptr);
      } /* Endif */
      if (io_result == IO_ERROR ) {
         fd_ptr->ERROR = io_error;
      } else {
         fd_ptr->LOCATION += num;
      } /* Endif */
   } /* Endif */
   return io_result;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_mfs_callback
* Returned Value   : None
* Comments         : This function is called by lowlevel drivers
when a command call back is set
*
*END*----------------------------------------------------------------------*/
static void _io_usb_mfs_callback
   (
      USB_STATUS command_status,      /*status of this command*/
      pointer p1,     /* pointer to USB_MASS_BULK_ONLY_REQUEST_STRUCT*/
      pointer p2,     /* pointer to the command object*/
      uint_32 len     /* length of the data transfered if any */
   )
{ /* Body */
   IO_USB_MFS_STRUCT_PTR info_ptr = (IO_USB_MFS_STRUCT_PTR)p2;

   if (command_status == (USB_STATUS)USB_MASS_FAILED_IN_DATA)
      info_ptr->COMMAND.CSW_PTR->BCSWSTATUS = CSW_STATUS_FAILED;
   if (info_ptr->COMMAND.CSW_PTR->BCSWSTATUS == CSW_STATUS_GOOD) {
      info_ptr->COMMAND_STATUS = command_status;   /* set the status */
   } else {
      info_ptr->COMMAND_STATUS = (uint_32)IO_ERROR;
   } 

   _lwsem_post(&info_ptr->COMMAND_DONE);
   
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_usb_ctrl_callback
* Returned Value   : None
* Comments         : This function is called by lowlevel drivers
* when a control pipe replies 
*
*END*----------------------------------------------------------------------*/
static void _io_usb_ctrl_callback(pointer pipe_handle, pointer user_param, uchar_ptr buffer, uint_32 size, USB_STATUS status)
{
   IO_USB_MFS_STRUCT_PTR info_ptr = (IO_USB_MFS_STRUCT_PTR)user_param;
   
   _lwsem_post(&info_ptr->COMMAND_DONE);
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/hub/usb_host_hub.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_hub.c$
* $Version : 3.8.15.0$
* $Date    : Sep-13-2012$
*
* Comments:
*
*   This file contains the implementation of class driver for hub devices.
*
*END************************************************************************/
#include "usb_host_hub.h"
#include "usb_host_hub_prv.h"

static USB_HUB_CLASS_INTF_STRUCT_PTR hub_anchor = NULL;

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_init
* Returned Value : None
* Comments       :
*     This function is called by common class to initialize the class driver. It
*     is called in response to a select interface call by application
*
*END*--------------------------------------------------------------------*/

void usb_class_hub_init
   (
      /* [IN] structure with USB pipe information on the interface */
      PIPE_BUNDLE_STRUCT_PTR      pbs_ptr,

      /* [IN] hub call struct pointer */
      CLASS_CALL_STRUCT_PTR       ccs_ptr
   )
{ /* Body */
   USB_STATUS                     status;
   USB_HUB_CLASS_INTF_STRUCT_PTR if_ptr = ccs_ptr->class_intf_handle;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_init");
   #endif
   
   /* Make sure the device is still attached */

   USB_lock(); //not needed as init is called from "already locked" function

   status = usb_host_class_intf_init(pbs_ptr, if_ptr, &hub_anchor, NULL);
   if (status == USB_OK) {
      /*
      ** We generate a code_key based on the attached device. This is used to
      ** verify that the device has not been detached and replaced with another.
      */
      ccs_ptr->code_key = 0;
      ccs_ptr->code_key = usb_host_class_intf_validate(ccs_ptr);

      /* Store application handle */
      if_ptr->APP = ccs_ptr;
         
      if_ptr->P_CONTROL = usb_hostdev_get_pipe_handle(pbs_ptr, USB_CONTROL_PIPE, 0);
      if_ptr->P_INT_IN = usb_hostdev_get_pipe_handle(pbs_ptr, USB_INTERRUPT_PIPE, USB_RECV);

   } /* Endif */

   /* Signal that an error has occured by setting the "code_key" to 0 */
   if (status || !if_ptr->P_INT_IN || !if_ptr->P_CONTROL) {
      ccs_ptr->code_key = 0;
   } /* Endif */

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_init, SUCCESSFUL");
   #endif
   
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_get_app
* Returned Value : CLASS_CALL_STRUCT_PTR if class found
* Comments       :
*     This function returns stored application handle as it was passed as
*     a param in select_interface.
*
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_hub_get_app
   (
      /* [IN] handle of device */
      _usb_device_instance_handle dev_ptr,

      /* [IN] pointer to interface descriptor */
      _usb_interface_descriptor_handle intf_ptr,

      /* [OUT] pointer to CLASS_CALL_STRUCT to be filled in */
      CLASS_CALL_STRUCT_PTR   _PTR_ ccs_ptr
   )
{
    USB_STATUS                    error;
    GENERAL_CLASS_PTR             parser;

    USB_lock();
 
    error = usb_hostdev_validate (dev_ptr);
    if (error != USB_OK) {
        USB_unlock();
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_class_mass_get_app, FAILED");
        #endif
        return USB_log_error(__FILE__,__LINE__,error);
    } /* EndIf */
    
    for (parser = (GENERAL_CLASS_PTR) hub_anchor; parser != NULL; parser = parser->next) {
        if (parser->dev_handle == dev_ptr && parser->intf_handle == intf_ptr)
            break;
    }
    
    if (parser != NULL) {
        USB_HUB_CLASS_INTF_STRUCT_PTR hub = (USB_HUB_CLASS_INTF_STRUCT_PTR) parser;
        *ccs_ptr = hub->APP;
    }
    else {
        USB_unlock();
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_class_hub_get_app, not found");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_NOT_FOUND);
    }
    
    USB_unlock();
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_hub_get_app, SUCCESSFUL");
    #endif
    return USB_OK;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_cntrl_callback
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This is the callback used when hub information is sent or received
*
*END*--------------------------------------------------------------------*/

void usb_class_hub_cntrl_callback
   (
      /* [IN] Unused */
      pointer     pipe,
      /* [IN] Pointer to the class interface instance */
      pointer     param,
      /* [IN] Data buffer */
      uchar_ptr   buffer,
      /* [IN] Length of buffer */
      uint_32     len,
      /* [IN] Error code (if any) */
      USB_STATUS  status
   )
{ /* Body */
   USB_HUB_CLASS_INTF_STRUCT_PTR      if_ptr;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_cntrl_callback");
   #endif

   /*
   ** There is no need for USB_lock in the callback function, and there is also no
   ** need to check if the device is still attached (otherwise this callback
   ** would never have been called!
   */

   /* Get class interface handle, reset IN_SETUP and call callback */
   if_ptr = (USB_HUB_CLASS_INTF_STRUCT_PTR)param;

   if_ptr->IN_SETUP = FALSE;

   if (if_ptr->CTRL_CALLBACK) {
      if_ptr->CTRL_CALLBACK(pipe, if_ptr->CTRL_PARAM, buffer, len, status);
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_cntrl_callback, SUCCESSFUL");
   #endif
   
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_cntrl_common
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is used to send a control request
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hub_cntrl_common
   (
      /* [IN] The class call struct for application */
      CLASS_CALL_STRUCT_PTR   ccs_ptr,
      /* [IN] The callback function */
      tr_callback             callback,
      /* [IN] The callback parameter */
      pointer                 param,
      /* [IN] Bitmask of the request type */
      uint_8                  bmrequesttype,
      /* [IN] Request code */
      uint_8                  brequest,
      /* [IN] Value to copy into WVALUE field of the REQUEST */
      uint_16                 wvalue,
      /* [IN] Length of the data associated with REQUEST */
      uint_16                 windex,
      /* [IN] Index field of CTRL packet */
      uint_16                 wlength
   )
{ /* Body */
   USB_HUB_CLASS_INTF_STRUCT_PTR    if_ptr;
   USB_SETUP                        req;
   USB_STATUS                       status = USBERR_NO_INTERFACE;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_cntrl_common");
   #endif
   
   USB_lock();
   /* Validity checking */
   if (usb_host_class_intf_validate(ccs_ptr)) {
      if_ptr =
         (USB_HUB_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle;
      status = usb_hostdev_validate(if_ptr->G.dev_handle);
   } /* Endif */

   if (!status && if_ptr->IN_SETUP) {
      status = USBERR_TRANSFER_IN_PROGRESS;
   } /* Endif */

   if (!status) {
      if (if_ptr->C_BUF != NULL && if_ptr->C_BUF_SIZE < wlength) {
         status = _usb_hostdev_free_buffer(if_ptr->G.dev_handle, if_ptr->C_BUF);
         if (!status) {
            /* Memory freed, assign NULL pointer */
            if_ptr->C_BUF = NULL;
         }
      }
      if (if_ptr->C_BUF == NULL) {
         /* Allocate new memory for control pipe request */
         status = _usb_hostdev_get_buffer(if_ptr->G.dev_handle, wlength, (pointer _PTR_)&if_ptr->C_BUF);
         if_ptr->C_BUF_SIZE = wlength;
      }
   }

   if (!status) {
      /* Save the higher level callback and ID */
      if_ptr->CTRL_CALLBACK = callback;
      if_ptr->CTRL_PARAM = param;

      /* Setup the request */
      req.BMREQUESTTYPE = bmrequesttype;
      req.BREQUEST = brequest;
      *(uint_16*)req.WVALUE = HOST_TO_LE_SHORT(wvalue);
      *(uint_16*)req.WINDEX = HOST_TO_LE_SHORT(windex);
      *(uint_16*)req.WLENGTH = HOST_TO_LE_SHORT(wlength);
      status = _usb_hostdev_cntrl_request(if_ptr->G.dev_handle, &req, (uchar_ptr) if_ptr->C_BUF,
         usb_class_hub_cntrl_callback, if_ptr);
      if (status == USB_STATUS_TRANSFER_QUEUED) {
         if_ptr->IN_SETUP = TRUE;
      } /* Endif */
   } /* Endif */
   USB_unlock();

   if (status != USB_STATUS_TRANSFER_QUEUED) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_hub_cntrl_common, FAILED");
      #endif
      return USB_log_error(__FILE__,__LINE__,status);
   }
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_cntrl_common, SUCCESSFUL");
   #endif

   return status;
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_get_descriptor
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is called by the application to read the descriptor
*     of hub device
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hub_get_descriptor
   (
      /* [IN] The class call struct for application */
      CLASS_CALL_STRUCT_PTR   ccs_ptr,
      /* [IN] The callback function */
      tr_callback             callback,
      /* [IN] The callback parameter */
      pointer                 param,
      /* [IN] buffer length (how many bytes to read) */
      uchar                   len
   )
{ /* Body */
   USB_STATUS error = USB_OK;

   #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_class_hub_get_descriptor");
   #endif

   USB_lock();

   error = usb_class_hub_cntrl_common(
      ccs_ptr, callback, param,
      REQ_TYPE_DEVICE | REQ_TYPE_IN | REQ_TYPE_CLASS,
      REQ_GET_DESCRIPTOR,
      0,
      0,
      len
   );

   USB_unlock();

   #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_class_hub_get_descriptor, SUCCESSFUL");
   #endif
   
   return error;

} /* EndBody */


/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_set_port_feature
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     Sets feature of specified hub port
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hub_set_port_feature
   (
      /* [IN] The class call struct for application */
      CLASS_CALL_STRUCT_PTR      ccs_ptr,
      /* [IN] The callback function */
      tr_callback                callback,
      /* [IN] The callback parameter */
      pointer                    param,
      /* [IN] port number */
      uint_8                     port_nr,
      /* [IN] feature ID */
      uint_8                     feature
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_set_port_feature, SUCCESSFUL");
   #endif

   return usb_class_hub_cntrl_common(
      ccs_ptr, callback, param,
      REQ_TYPE_OUT | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE | REQ_TYPE_ENDPOINT,
      REQ_SET_FEATURE,
      feature,
      port_nr,
      0);

} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_clear_feature
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     Clears hub feature
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hub_clear_feature
   (
      /* [IN] The class call struct for application */
      CLASS_CALL_STRUCT_PTR      ccs_ptr,
      /* [IN] The callback function */
      tr_callback                callback,
      /* [IN] The callback parameter */
      pointer                    param,
      /* [IN] feature ID */
      uint_8                     feature
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_clear_port_feature, SUCCESSFUL");
   #endif

   return usb_class_hub_cntrl_common(
      ccs_ptr, callback, param,
      REQ_TYPE_OUT | REQ_TYPE_CLASS,
      REQ_CLEAR_FEATURE,
      feature,
      0,
      0);

} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_clear_port_feature
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     Clears feature of selected hub port
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hub_clear_port_feature
   (
      /* [IN] The class call struct for application */
      CLASS_CALL_STRUCT_PTR      ccs_ptr,
      /* [IN] The callback function */
      tr_callback                callback,
      /* [IN] The callback parameter */
      pointer                    param,
      /* [IN] port number */
      uint_8                     port_nr,
      /* [IN] feature ID */
      uint_8                     feature
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_clear_port_feature, SUCCESSFUL");
   #endif

   return usb_class_hub_cntrl_common(
      ccs_ptr, callback, param,
      REQ_TYPE_OUT | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE | REQ_TYPE_ENDPOINT,
      REQ_CLEAR_FEATURE,
      feature,
      port_nr,
      0);

} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_get_status
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     Gets hub status
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hub_get_status
   (
      /* [IN] The class call struct for application */
      CLASS_CALL_STRUCT_PTR      ccs_ptr,
      /* [IN] The callback function */
      tr_callback                callback,
      /* [IN] The callback parameter */
      pointer                    param,
      /* [IN] buffer length (how many bytes to read) */
      uchar                      len
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_get_port_status, SUCCESSFUL");
   #endif

   return usb_class_hub_cntrl_common(
      ccs_ptr, callback, param,
      REQ_TYPE_IN | REQ_TYPE_CLASS,
      REQ_GET_STATUS,
      0,
      0,
      len);

} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_get_port_status
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     Gets the status of specified port
*
*END*--------------------------------------------------------------------*/

USB_STATUS usb_class_hub_get_port_status
   (
      /* [IN] The class call struct for application */
      CLASS_CALL_STRUCT_PTR      ccs_ptr,
      /* [IN] The callback function */
      tr_callback                callback,
      /* [IN] The callback parameter */
      pointer                    param,
      /* [IN] port number */
      uint_8                     port_nr,
      /* [IN] buffer length (how many bytes to read) */
      uchar                      len
   )
{ /* Body */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_get_port_status, SUCCESSFUL");
   #endif

   return usb_class_hub_cntrl_common(
      ccs_ptr, callback, param,
      REQ_TYPE_IN | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE | REQ_TYPE_ENDPOINT,
      REQ_GET_STATUS,
      0,
      port_nr,
      len);

} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_wait_for_interrupt
* Returned Value : None
* Comments       :
*     Starts interrupt endpoint to poll for interrupt on specified hub
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_hub_wait_for_interrupt
    (
      /* [IN] The class call struct for application */
      CLASS_CALL_STRUCT_PTR      ccs_ptr,
      /* [IN] The callback function */
      tr_callback                callback,
      /* [IN] The callback parameter */
      pointer                    param,
      /* size of buffer to be used */
      uchar                      len
    )
{ /* Body */
    USB_HUB_CLASS_INTF_STRUCT_PTR  if_ptr;
    TR_INIT_PARAM_STRUCT           tr;
    USB_STATUS                     status = USBERR_NO_INTERFACE;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_wait_for_interrupt");
   #endif

    USB_lock();
    /* Validity checking, always needed when passing data to lower API */
    if (usb_host_class_intf_validate(ccs_ptr)) {
        if_ptr = (USB_HUB_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle;
        status = usb_hostdev_validate(if_ptr->G.dev_handle);
    }

    if (!status && if_ptr->INT_PIPE) {
        status = USBERR_TRANSFER_IN_PROGRESS;
    }
    
    if (!status) {
        if (if_ptr->I_BUF != NULL && if_ptr->I_BUF_SIZE < len) {
            status = _usb_hostdev_free_buffer(if_ptr->G.dev_handle, if_ptr->I_BUF);
            if (!status) {
                /* Memory freed, assign NULL pointer */
                if_ptr->I_BUF = NULL;
            }
        }
        if (if_ptr->I_BUF == NULL) {
            /* Allocate new memory for control pipe request */
            status = _usb_hostdev_get_buffer(if_ptr->G.dev_handle, len, (pointer _PTR_) &if_ptr->I_BUF);
            if_ptr->I_BUF_SIZE = len;
        }
    }

    if (!status) {
        usb_hostdev_tr_init(&tr, usb_class_hub_int_callback, (pointer) if_ptr);
        tr.G.RX_BUFFER = if_ptr->I_BUF;
        tr.G.RX_LENGTH = len;
        status = _usb_host_recv_data(if_ptr->G.host_handle, if_ptr->P_INT_IN, &tr);
        if_ptr->INT_PIPE = 1; /* mark we are using interrupt pipe */
        if_ptr->INT_CALLBACK = callback;
        if_ptr->INT_PARAM = param;
   }

   USB_unlock();

   if (status != USB_STATUS_TRANSFER_QUEUED) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_hub_wait_for_interrupt, FAILED");
      #endif
      return USB_log_error(__FILE__,__LINE__,status);
   }
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_wait_for_interrupt, SUCCESSFUL");
   #endif

   return status;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_cntrl_callback
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This is the callback used when hub information is sent or received
*
*END*--------------------------------------------------------------------*/
void usb_class_hub_int_callback
   (
      /* [IN] Unused */
      pointer     pipe,
      /* [IN] Pointer to the class interface instance */
      pointer     param,
      /* [IN] Data buffer */
      uchar_ptr   buffer,
      /* [IN] Length of buffer */
      uint_32     len,
      /* [IN] Error code (if any) */
      USB_STATUS  status
   )
{ /* Body */
   USB_HUB_CLASS_INTF_STRUCT_PTR      if_ptr;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_int_callback");
   #endif

   /*
   ** There is no need for USB_lock in the callback function, and there is also no
   ** need to check if the device is still attached (otherwise this callback
   ** would never have been called!
   */

   /* Get class interface handle, reset IN_SETUP and call callback */
   if_ptr = (USB_HUB_CLASS_INTF_STRUCT_PTR)param;

   if_ptr->INT_PIPE = 0; /* mark we are not using interrupt pipe */

   if (if_ptr->INT_CALLBACK) {
      if_ptr->INT_CALLBACK(pipe, if_ptr->INT_PARAM, buffer, len, status);
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_hub_int_callback, SUCCESSFUL");
   #endif
   
} /* Endbody */



/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/dhcpclnt.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dhcpclnt.c$
* $Version : 3.8.12.0$
* $Date    : Aug-6-2012$
*
* Comments:
*
*   This file contains the implementation of the DHCP client
*   for the TCP/IP protocol suite.
*   For more information, refer to:
*   RFC 2131 (DHCP)
*   RPC 2132 (DHCP Options).
*   Limitations:  Although DHCP can be used over any medium, this
*   implementation will work only over an Ethernet
*   link layer.
*   Implementation Note:
*   The DHCP Client packet is set up in such a way that it may be re-used
*   for any message the DCHP Client needs to send.  Only DHCP_MAGIC is
*   required for a DHCPDISCOVER message, the other options may or may not
*   be present if the application did not specify them upon initialization.
*   If the option is passed to the DHCP Client, it will be placed in the
*   packet in the following order.  The Server and Client IP pads will be
*   used even if no other options are specified.
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |                       DHCP_MAGIC (4)                          |
*   +---------------------------------------------------------------+
*   |                                                               |
*   //                 ClIENT ID (variable, 6 - 255)               //
*   |                                                               |
*   +-----------------------------------------------+---------------+
*   |                  OVERLOAD (3)                 |
*   +-----------------------------------------------+--------------------------+
*   |                  SERVER IP PAD (6)  (zero, unless used)                  |
*   +--------------------------------------------------------------------------+
*   |                  CLIENT IP PAD (6)  (zero, unless used)                  |
*   +-------------------+------------------------------------------------------+
*   | BUFFER END PAD (1)|
*   +-------------------+-------------------------------------------+
*   |                                                               |
*   //                  PARAMETER LIST (variable, 3 - 255)         //
*   |                                                               |
*   +---------------------------------------------------------------+
*   |                   REQUESTED LEASE TIME (4)                    |
*   +---------------------------------------------------------------+
*   |                                                               |
*   //                  CLASS ID (variable, 6 -255)                //
*   |                                                               |
*   +---------------------------------------------------------------+
*   |                   MAX MESSAGE SIZE (4)                        |
*   +---------------------------------------------------------------+
*   |                                                               |
*   //                  SITE SPECIFIC OPTIONS (variable)           //
*   |                                                               |
*   +--------------------+------------------------------------------+
*   | BUFFER END PAD (1) |
*   +--------------------------------------------------------------------------+
*   |                   REQUESTED CLIENT IP PAD (6)                            |
*   +--------------------+-----------------------------------------------------+
*   | BUFFER END PAD (1) |
*   +--------------------+
*   Pointers are kept to modify the packet, depending on the current state.
*   Please refer to RFC 2131, pg 38, to see what options are allowed in
*   each situation.  As an example, if sending a DHCPDECLINE message, only the
*   Server IP is allowed.  Therefore, the Server IP pad section is filled using
*   the DHCPCLNT_modify_options() function and the first buffer end pad is
*   filled with 0xFF. Only this section of the buffer will be sent to the
*   Server.  When a state change occurs, these pads will be zeroed out and
*   the packet will be set up for the correct message type.
*   There are three timed events which may or may not be active depending on
*   the current state. If we are initializing for the first time, only the
*   RESEND event will be active. Once we have a lease and are in a bound state,
*   the RESEND event is cancelled and the RENEW and TERMINATE events are set.
*   If we are in a RESENDING state, all three events will be set until we are
*   re-bound. If we are in a REBINDING state, only the RESEND and TERMINATE
*   events will be active.  If we received a DHCPNAK message when renewing or
*   rebinding, we will try to get a new lease starting from the INITIALIZE
*   state. If the DHCP server does not wish to renew the current lease,
*   then only the TERMINATE event will be set for the remainder of the lease. SMR
*
*END************************************************************************/

#include <string.h>
#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "dhcp_prv.h"
#include "dhcpuprv.h"
#include "arp.h"

extern UCB_STRUCT_PTR   BOOT_port;


uint_32 DHCPCLNT_probe_address
   (
      _ip_address       ipaddress,
      pointer           interface
   );

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_init
* Returned Values : void
* Comments        :
*     Initialize the DHCP client. This function should only be called by the
*     user's application
*
*END*-----------------------------------------------------------------*/

void DHCPCLNT_init
   (
      TCPIP_PARM_IF_DHCP _PTR_ parms
         /* [IN/OUT] This is the DHCP Client structure from the application */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr;
   uint_32                buff_len;
   uint_32                error;

   buff_len = parms->OPT_BUFF_SIZE + sizeof(DHCP_HEADER) + 23;

   dhcp_ptr = RTCS_mem_alloc_zero(sizeof(DHCP_CLNT_STRUCT) + buff_len);
#if RTCSCFG_CHECK_MEMORY_ALLOCATION_ERRORS
   if ( dhcp_ptr == NULL ) {
      RTCSCMD_complete(parms, RTCSERR_OUT_OF_MEMORY);
      return;
   } /* Endif */
#endif
   _mem_set_type(dhcp_ptr, MEM_TYPE_DHCP_CLNT_STRUCT);

    RTCS_rand_seed(RTCS_time_get()); /* Just add more randomize  to Transition ID.*/
   
   error = DHCPCLNT_start(parms, dhcp_ptr);

#if RTCSCFG_CHECK_ERRORS
   if ( error ) {
      /* Self Destruct, can't do anything if the port isn't open */
      _mem_free( dhcp_ptr );
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */
#endif

   DHCPCLNT_open(dhcp_ptr);

   RTCSCMD_complete(parms, error);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);
    return;

#endif /* RTCSCFG_ENABLE_IP4 */  
   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_reinit
* Returned Values : void
* Comments        :
*     Initialize the DHCP client without the initial DHCP negotiation.
*
*END*-----------------------------------------------------------------*/

void DHCPCLNT_reinit
   (
      TCPIP_PARM_IF_DHCP _PTR_ parms
         /* [IN/OUT] This is the DHCP Client structure from the application */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4

   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr;
   uint_32                buff_len;
   uint_32                error;

   buff_len = parms->OPT_BUFF_SIZE + sizeof(DHCP_HEADER) + 23;

   dhcp_ptr = RTCS_mem_alloc_zero(sizeof(DHCP_CLNT_STRUCT) + buff_len);
#if RTCSCFG_CHECK_MEMORY_ALLOCATION_ERRORS
   if ( dhcp_ptr == NULL ) {
      RTCSCMD_complete(parms, RTCSERR_OUT_OF_MEMORY);
      return;
   } /* Endif */
#endif
   _mem_set_type(dhcp_ptr, MEM_TYPE_DHCP_CLNT_STRUCT);

   error = DHCPCLNT_start(parms, dhcp_ptr);

#if RTCSCFG_CHECK_ERRORS
   if ( error ) {
      /* Self Destruct, can't do anything if the port isn't open */
      _mem_free( dhcp_ptr );
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */
#endif

   dhcp_ptr->DATA.ServerIp        = parms->SERVER_IP_ADDR;
   dhcp_ptr->DATA.ClientIPaddress = parms->CLNT_IP_ADDR;
   dhcp_ptr->DATA.LEASE           = parms->LEASE;
   dhcp_ptr->DATA.Netmask         = parms->CLNT_IP_MASK;

   dhcp_ptr->PARMS_BIND.address = parms->CLNT_IP_ADDR;
   dhcp_ptr->PARMS_BIND.locmask = INADDR_BROADCAST;
   dhcp_ptr->PARMS_BIND.netmask = parms->CLNT_IP_MASK;
   dhcp_ptr->PARMS_BIND.probe   = FALSE;

   RTCSCMD_internal(dhcp_ptr->PARMS_BIND, IPIF_bind);

   dhcp_ptr->BOUND = TRUE;
   dhcp_ptr->STATE = DHCP_BOUND;

   dhcp_ptr->NEW_RENEW_TIME = 0;
   dhcp_ptr->NEW_REBIND_TIME = 0;
   DHCPCLNT_set_timed_events(dhcp_ptr);
   TCPIP_Event_add(&dhcp_ptr->RENEW);
   TCPIP_Event_add(&dhcp_ptr->TERMINATE);

   RTCSCMD_complete(parms, RTCS_OK);

#else

    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);
    return;

#endif /* RTCSCFG_ENABLE_IP4 */  
   

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_start
* Returned Values : error code
* Comments        :
*     Initialize the DHCP client state structure.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4

uint_32 DHCPCLNT_start
   (
      TCPIP_PARM_IF_DHCP _PTR_ parms,
         /* [IN/OUT] This is the DHCP Client structure from the application */
      DHCP_CLNT_STRUCT _PTR_ dhcp_ptr
         /* [IN/OUT] This is the DHCP Client control structure */
   )
{ /* Body */
   uint_32     buff_len;

   /*
   ** 23: 4 = Magic Cookie, 3 = Msg Type, 6 = ServerID, 6 = Requested IP,
   ** 4 = Various Ends
   */
   buff_len = parms->OPT_BUFF_SIZE + sizeof(DHCP_HEADER) + 23;

   if ( parms->FLAGS & DHCP_SEND_INFORM_MESSAGE ) {
      dhcp_ptr->STATE = DHCP_INFORMED;
      dhcp_ptr->DATA.ClientIPaddress = parms->CLNT_IP_ADDR;
      if ( parms->SERVER_IP_ADDR == INADDR_ANY ) {
         dhcp_ptr->DATA.ServerIp = INADDR_BROADCAST;
      } else  {
         dhcp_ptr->DATA.ServerIp = parms->SERVER_IP_ADDR;
      } /* Endif */
      dhcp_ptr->BOUND = TRUE;
   } else  {
      dhcp_ptr->STATE = DHCP_INITIALIZE;
   }/* Endif */
   dhcp_ptr->HANDLE             = (IP_IF _PTR_)parms->HANDLE;
   dhcp_ptr->PARMS_BIND.ihandle = parms->HANDLE;
   dhcp_ptr->HANDLE->BOOTFN     = NULL;
   dhcp_ptr->HANDLE->BOOT       = dhcp_ptr;
   dhcp_ptr->CHOICE_FUNC        = parms->OPTIONS->CHOICE_FUNC;
   dhcp_ptr->BIND_FUNC          = parms->OPTIONS->BIND_FUNC;
   dhcp_ptr->UNBIND_FUNC        = parms->OPTIONS->UNBIND_FUNC;
   dhcp_ptr->FAILURE_FUNC       = parms->OPTIONS->FAILURE_FUNC;
   dhcp_ptr->NAK_FUNC           = parms->OPTIONS->NAK_FUNC;
   dhcp_ptr->FLAGS              = parms->FLAGS;
   dhcp_ptr->PACKET             = (uchar _PTR_)(dhcp_ptr + 1);
   dhcp_ptr->TOTAL_PACKET_SIZE  = buff_len;
   dhcp_ptr->RESEND.EVENT       = DHCPCLNT_send;
   dhcp_ptr->RESEND.PRIVATE     = dhcp_ptr;
   dhcp_ptr->RENEW.EVENT        = DHCPCLNT_renew_lease;
   dhcp_ptr->RENEW.PRIVATE      = dhcp_ptr;
   dhcp_ptr->TERMINATE.EVENT    = DHCPCLNT_terminate_lease;
   dhcp_ptr->TERMINATE.PRIVATE  = dhcp_ptr;
   dhcp_ptr->INIT_TIMEOUT       = parms->TIMEOUT * 1000;

   DHCPCLNT_fill_header( dhcp_ptr );
   DHCPCLNT_fill_options( dhcp_ptr, parms );

   return BOOT_open(&DHCPCLNT_service);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_fill_header
* Returned Values : void
* Comments        :
*     Sets up the DHCP Client header structure.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_fill_header
   (
   DHCP_CLNT_STRUCT  _PTR_ dhcp_ptr
   /* [IN/OUT] This is the DHCP Client control structure */
   )
{ /* Body */
   DHCP_HEADER _PTR_      header_ptr;
   uint_32                xid;

   header_ptr = (DHCP_HEADER _PTR_)dhcp_ptr->PACKET;

   /* Build the DHCP HEADER  */
   htonc(header_ptr->OP,    DHCPOP_BOOTREQUEST);
   htonc(header_ptr->HTYPE, dhcp_ptr->HANDLE->DEV_TYPE);
   htonc(header_ptr->HLEN,  dhcp_ptr->HANDLE->DEV_ADDRLEN);
   htonc(header_ptr->HOPS,  0);
   /* Pick a random transaction ID */
   xid = RTCS_rand();
   htonl(header_ptr->XID, xid);

   /* htons(header_ptr->FLAGS, DHCPFLAG_BROADCAST); */
   htons(header_ptr->FLAGS, _DHCP_broadcast ? DHCPFLAG_BROADCAST : 0);
   
   if ( dhcp_ptr->STATE == DHCP_INFORMED ) {
      htonl(header_ptr->CIADDR, dhcp_ptr->DATA.ClientIPaddress);
   } else {
      htonl(header_ptr->CIADDR, INADDR_ANY);
   } /* Endif */
   htonl(header_ptr->YIADDR, INADDR_ANY);
   htonl(header_ptr->SIADDR, INADDR_ANY);
   htonl(header_ptr->GIADDR, INADDR_ANY);

   _mem_zero(header_ptr->CHADDR, sizeof(header_ptr->CHADDR));
   _mem_copy(dhcp_ptr->HANDLE->DEV_ADDR, header_ptr->CHADDR, dhcp_ptr->HANDLE->DEV_ADDRLEN);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_fill_options
* Returned Values : void
* Comments        :
*     Checks and fills in the DHCP Client options in the buffer. This
*     function should only be called once upon initialization. The DHCP_FILL
*     macro is defined in DHCP_PRV.H.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_fill_options
   (
   DHCP_CLNT_STRUCT  _PTR_ dhcp_ptr,
   /* [IN/OUT] This is the DHCP Client control structure */
   TCPIP_PARM_IF_DHCP _PTR_ parms
   /* [IN/OUT] This is the DHCP Client structure from the application */
   )
{ /* Body */
   uchar _PTR_ outp;
   uchar _PTR_ temp_ptr;
   uchar _PTR_ opt_ptr;
   uint_32     len;
   uint_32     i;
   uint_32     new_total_length;
   uchar       addr_buffer[6];
   uchar _PTR_ buffer_end   = parms->OPT_BUFF
                              + parms->OPT_BUFF_SIZE - 1;

   outp = dhcp_ptr->PACKET + sizeof(DHCP_HEADER);
   htonl(outp, DHCP_MAGIC);            outp += 4;
   htonc(outp, DHCPOPT_MSGTYPE);       outp++;
   htonc(outp, 1);                     outp++;
   dhcp_ptr->MSGTYPE_PTR = outp;
   if ( dhcp_ptr->STATE == DHCP_INFORMED ) {
      htonc(outp, DHCPTYPE_DHCPINFORM);
   } else  {
      htonc(outp, DHCPTYPE_DHCPDISCOVER);
   } /* Endif */
   outp++;
   /*
   ** Only the following options are allowed for a DHCP Client message.
   ** Client ID, Use 'file'/'sname' fields, Parameter request list,
   ** IP address lease time, Class Id, Max message size, Requested IP addr.
   ** DO NOT change the order of insertion into the buffer, as other
   ** functions will depend on the order given here.
   ** See pg. 33 of RFC 1541 for more details.
   */
   /* Minimum size allowed is 2 (added 2 for option and length fields) */
   DHCP_FILL(CLIENTID, (len >= 4))
   /*
   ** Allows 'file'/'sname' fields to be used in replies from DHCP server
   ** Since we also use these fields for BOOTP, we do not allow this
   ** functionality at this time.  However, if we are to offer it in the future,
   ** other functions depend on us filling in the overload option here.
   ** Leave the commented code here for potential future use. SMR
   */
   /* Minimum size allowed is 1 (added 2 for option and length fields) */
   /* DHCP_FILL(OVERLOAD, (len == 3)) */

   dhcp_ptr->SERVERID_PTR = outp;
   /* This is to pad for insertion of ServerID and Requested IP later */
   outp += 13;

   /* Minimum size allowed is 1 (added 2 for option and length fields) */
   DHCP_FILL(PARAMLIST, (len >= 3))
   if ( dhcp_ptr->STATE != DHCP_INFORMED ) {
      /* Size must be 4 (added 2 for option and length fields) */
      DHCP_FILL(LEASE, (len == 6))
   }/* Endif */
   /* Minimum size allowed is 1 (added 2 for option and length fields) */
   DHCP_FILL(CLASSID, (len >= 3))

   opt_ptr = DHCP_find_option(parms->OPT_BUFF,
                              parms->OPT_BUFF_SIZE,
                              DHCPOPT_MSGSIZE);
   if (opt_ptr) {
      /* 576 octets is an imposed minimum, RFC 2131 */
      if ( ntohs(opt_ptr + 2) < DHCP_MIN_MESSAGE_SIZE ) {
         htonc(outp, DHCPOPT_MSGSIZE);       outp++;
         htonc(outp, 2);                     outp++;
         htons(outp, DHCP_MIN_MESSAGE_SIZE); outp += 2;
      } else  {
         _mem_copy(opt_ptr, outp, 4);
         outp += 4;
      } /* Endif */
      for (i = 0; i < 4; i++) {
         htonc(opt_ptr, 0);
         opt_ptr++;
      } /* Endfor */
   } /* Endif */

   /*
   ** Have to parse out the ADDRESS option, as it goes after the site specific
   ** options in the packet.
   */
   opt_ptr = DHCP_find_option(parms->OPT_BUFF,
                              parms->OPT_BUFF_SIZE,
                              DHCPOPT_ADDRESS);
   if ( opt_ptr ) {
      for (i = 0; i < 6; i++) {
         addr_buffer[i] = ntohc(opt_ptr);
         htonc(opt_ptr, 0);
         opt_ptr++;
      } /* Endfor */
   }/* Endif */

   /*
   ** Remove all the remaining options and place in the site specific section.
   ** Break out of the while loop once all the options are parsed.
   */

   temp_ptr = parms->OPT_BUFF;
   while ( temp_ptr ) {
      temp_ptr = parms->OPT_BUFF;
      while ((ntohc(temp_ptr) == 0) && (temp_ptr < buffer_end)) {
         temp_ptr++;
      } /* Endwhile */
      if ( ntohc(temp_ptr) != 0 ) {
         new_total_length = buffer_end - temp_ptr + 1;
         len = ntohc(temp_ptr + 1) + 2;
         if ( len <= new_total_length ) {
            _mem_copy(temp_ptr, outp, len);
            outp += len;
         } else  {
            len = new_total_length;
         }/* Endif */
         for ( i = 0; i < len; i++) {
            htonc(temp_ptr, 0);
            temp_ptr++;
         } /* Endfor */
      } else  {
         temp_ptr = NULL;
      }/* Endif */
   } /* Endwhile */

   dhcp_ptr->REQUEST_OPT_PTR = outp;
   /* This pad is for DHCP REQUEST messages so we won't overwrite the addr */
   outp++;

   if (opt_ptr && (dhcp_ptr->STATE != DHCP_INFORMED)) {
      for ( i = 0; i < 6; i++ ) {
         htonc(outp, addr_buffer[i]);
         outp++;
      } /* Endfor */
   } /* Endif */

   /* Add the DHCPEND flag last */
   htonc(outp, DHCPOPT_END);
   outp++;
   dhcp_ptr->CURRENT_PACKET_SIZE = outp - dhcp_ptr->PACKET;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_open
* Returned Values : void
* Comments        : This function is used to open the DHCP Client Port
*                   and set up the RESEND event.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_open
   (
   DHCP_CLNT_STRUCT  _PTR_ dhcp_ptr
   /* [IN/OUT] This is the DHCP Client control structure */
   )
{ /* Body */
   DHCP_HEADER _PTR_   header_ptr = (DHCP_HEADER _PTR_)dhcp_ptr->PACKET;

   htons(header_ptr->SECS, 0);
   /* Set initial timeout */
   dhcp_ptr->RETRY_TIMEOUT = DHCP_TIMEOUT_MIN;
   dhcp_ptr->SECS = 0;
   /* Start the retransmission timer to start sending immediately */
   dhcp_ptr->RESEND.TIME    = 0;
   TCPIP_Event_add( &dhcp_ptr->RESEND );

   if (dhcp_ptr->INIT_TIMEOUT) {
      /* Set a cancellation event in case of failure to bind. */
      dhcp_ptr->TERMINATE.EVENT    = DHCPCLNT_bind_attempt_timeout;
      dhcp_ptr->TERMINATE.TIME     = dhcp_ptr->INIT_TIMEOUT;
      TCPIP_Event_add(&dhcp_ptr->TERMINATE);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_modify_options
* Returned Values : void
* Comments        :
*     Modifies the DHCP Client buffer for packet send, depending on the
*     current context. Allowed options change depending on the packet type.
*     NOTE: State MUST be checked BEFORE calling, this function is not used
*     in an initial or terminated state
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_modify_options
   (
   DHCP_CLNT_STRUCT  _PTR_ dhcp_ptr
   /* [IN/OUT] This is the DHCP Client control structure */
   )
{  /* Body */
   DHCP_HEADER _PTR_ header_ptr;
   uchar       _PTR_ outp;
   uint_32           i;

   header_ptr = (DHCP_HEADER _PTR_)dhcp_ptr->PACKET;
   outp       = dhcp_ptr->SERVERID_PTR;

   for ( i = 0 ; i < 13 ; i++ ) {
         htonc(outp, 0); outp++;
      } /* Endfor */
   outp -= 13;
   htonc(dhcp_ptr->REQUEST_OPT_PTR, 0);

   if ( dhcp_ptr->BOUND && dhcp_ptr->STATE != DHCP_REQUESTING ) {
      htonl(header_ptr->CIADDR, dhcp_ptr->DATA.ClientIPaddress);
   } else  {
      htonl(header_ptr->CIADDR, INADDR_ANY);
   }/* Endif */

   if ( dhcp_ptr->STATE == DHCP_INITIALIZE ) {
      htonc(dhcp_ptr->MSGTYPE_PTR, DHCPTYPE_DHCPDISCOVER);
      dhcp_ptr->CURRENT_PACKET_SIZE = dhcp_ptr->TOTAL_PACKET_SIZE;
   } else  {
      htonc(dhcp_ptr->MSGTYPE_PTR, DHCPTYPE_DHCPREQUEST);
      if ( dhcp_ptr->STATE == DHCP_REQUESTING ||
           dhcp_ptr->STATE == DHCP_DECLINING  ||
           dhcp_ptr->STATE == DHCP_RELEASING ) {
         htonc(outp, DHCPOPT_SERVERID); outp++;
         htonc(outp, 4); outp++;
         if ( dhcp_ptr->STATE == DHCP_RELEASING ) {
            htonc(dhcp_ptr->MSGTYPE_PTR, DHCPTYPE_DHCPRELEASE);
            htonl(outp, dhcp_ptr->DATA.ServerIp); outp += 4;
         } else  {
            htonl(outp, dhcp_ptr->NEW_DATA.ServerIp); outp += 4;
            htonc(outp, DHCPOPT_ADDRESS); outp++;
            htonc(outp, 4); outp++;
            htonl(outp, dhcp_ptr->NEW_DATA.ClientIPaddress); outp += 4;
            if (dhcp_ptr->STATE == DHCP_DECLINING ) {
               htonl(header_ptr->CIADDR, INADDR_ANY);
               htonc(dhcp_ptr->MSGTYPE_PTR, DHCPTYPE_DHCPDECLINE);
            } else  {
               outp = dhcp_ptr->REQUEST_OPT_PTR;
            }/* Endif */
         } /* Endif */
      } else  {
         /* We're Renewing or Rebinding */
         outp = dhcp_ptr->REQUEST_OPT_PTR;
      }/* Endif */
      htonc(outp, DHCPOPT_END); outp++;
      dhcp_ptr->CURRENT_PACKET_SIZE = outp - dhcp_ptr->PACKET;
   }/* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_send
* Returned Value  : boolean
* Comments        :
*     Called by the Timer.  Send a DHCP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

boolean DHCPCLNT_send
   (
   TCPIP_EVENT_PTR   event
   /* [IN/OUT] the resend event */
   )
{ /* Body */
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr = event->PRIVATE;
   DHCP_HEADER     _PTR_ header_ptr;
   RTCSPCB_PTR           pcb_ptr;
   _ip_address           destination_address;
   uint_32               retry_time;

   if ( dhcp_ptr->S_EVENT_TIME_LEFT ) {
      DHCPCLNT_TIME_OVERFLOW_CHECK(retry_time, dhcp_ptr->S_EVENT_TIME_LEFT)
      dhcp_ptr->RESEND.TIME = retry_time;
      return( TRUE );
   }/* Endif */

   switch ( dhcp_ptr->STATE ) {

      case DHCP_REQUESTING:
      case DHCP_INFORMED:
         /* Must retry 4 times before starting over, total is under 60 secs */
         if ( dhcp_ptr->RETRY_TIMEOUT != DHCP_TIMEOUT_MAX ) {
            /*Set the event to trigger for the next retransmission (+/- 1 sec)*/
            retry_time = dhcp_ptr->RETRY_TIMEOUT +
                         (RTCS_rand() & 0x7FF) - 0x400;
            if ( dhcp_ptr->RENEW_TIME &&
                 dhcp_ptr->RENEW_TIME < dhcp_ptr->REBIND_TIME )
            {
               dhcp_ptr->RENEW_TIME += (retry_time / 1000);
            } else  {
               /* We were rebinding, increment rebind time */
               dhcp_ptr->REBIND_TIME += (retry_time / 1000);
            }/* Endif */
            dhcp_ptr->RESEND.TIME = retry_time;
            /* Double the timeout */
            dhcp_ptr->RETRY_TIMEOUT <<= 1;
            if (dhcp_ptr->RETRY_TIMEOUT > DHCP_TIMEOUT_MAX) {
               dhcp_ptr->RETRY_TIMEOUT = DHCP_TIMEOUT_MAX;
            } /* Endif */
            dhcp_ptr->STATS.ST_TX_REQUEST++;
            break;
         } else  {
            if ( dhcp_ptr->STATE == DHCP_INFORMED ) {
               /*
               ** There was no response to our request for parameters, inform
               ** the application to use defaults and self destruct
               */
               if ( dhcp_ptr->BIND_FUNC != NULL ) {
                  dhcp_ptr->BIND_FUNC(NULL, 0,
                                      (_rtcs_if_handle)dhcp_ptr->HANDLE);
               } /* Endif */
               BOOT_close();
               dhcp_ptr->HANDLE->BOOT = NULL;
               /* Free the DHCP Structure */
               _mem_free(dhcp_ptr);
               return( FALSE );
            } else  {
               /* We were initializing from an unbound state before */
               dhcp_ptr->STATE = DHCP_INITIALIZE;
               dhcp_ptr->RETRY_TIMEOUT = DHCP_TIMEOUT_MIN;
               DHCPCLNT_modify_options( dhcp_ptr );
            } /* Endif */
         }/* Endif */

      case DHCP_INITIALIZE:
         /* Set the event to trigger for the next retransmission (+/- 1 sec) */
         retry_time = dhcp_ptr->RETRY_TIMEOUT + (RTCS_rand() & 0x7FF) - 0x400;

         dhcp_ptr->RESEND.TIME = retry_time;
         /* Double the timeout */
         dhcp_ptr->RETRY_TIMEOUT <<= 1;
         if (dhcp_ptr->RETRY_TIMEOUT > DHCP_TIMEOUT_MAX) {
            dhcp_ptr->RETRY_TIMEOUT = DHCP_TIMEOUT_MAX;
         } /* Endif */
         dhcp_ptr->STATS.ST_TX_DISCOVER++;
         break;

      case DHCP_RENEWING:
         retry_time = (dhcp_ptr->REBIND_TIME - dhcp_ptr->RENEW_TIME)/2;
         if ( retry_time < 60 ) {
            /* A 60 second minimum is imposed */
            retry_time = 60;
         }/* Endif */
         dhcp_ptr->RENEW_TIME += retry_time;

         dhcp_ptr->S_EVENT_TIME_LEFT = retry_time;
         DHCPCLNT_TIME_OVERFLOW_CHECK(retry_time, dhcp_ptr->S_EVENT_TIME_LEFT)

         dhcp_ptr->RESEND.TIME = retry_time;
         dhcp_ptr->STATS.ST_TX_REQUEST++;
         break;

      case DHCP_REBINDING:
         retry_time = (dhcp_ptr->DATA.LEASE - dhcp_ptr->REBIND_TIME)/2;
         if ( retry_time < 60 ) {
            /* A 60 second minimum is imposed */
            retry_time = 60;
         }/* Endif */
         if ((dhcp_ptr->REBIND_TIME + retry_time) < dhcp_ptr->DATA.LEASE) {
            dhcp_ptr->REBIND_TIME += retry_time;
         }/* Endif */

         dhcp_ptr->S_EVENT_TIME_LEFT = retry_time;
         DHCPCLNT_TIME_OVERFLOW_CHECK(retry_time, dhcp_ptr->S_EVENT_TIME_LEFT)

         dhcp_ptr->RESEND.TIME = retry_time;
         dhcp_ptr->STATS.ST_TX_REQUEST++;

   } /* Endswitch */

   /* Allocate a PCB */
   pcb_ptr = RTCSPCB_alloc_send();
   if (pcb_ptr == NULL) {
      return TRUE;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb_ptr);

   /* The only field that changes in DHCP packets is 'secs' */
   header_ptr = (DHCP_HEADER _PTR_)dhcp_ptr->PACKET;
   htons(header_ptr->SECS, dhcp_ptr->SECS);
   dhcp_ptr->SECS += (retry_time / 1000);

   /* Put the DHCP packet in the PCB */
   RTCSLOG_PCB_WRITE(pcb_ptr, RTCS_LOGCTRL_PORT(IPPORT_BOOTPC), 0);
   RTCSPCB_append_fragment(pcb_ptr, dhcp_ptr->CURRENT_PACKET_SIZE, dhcp_ptr->PACKET);

   if ( dhcp_ptr->BOUND ) {
      /* We already have an IP address available, we're renewing or rebinding */
      if ( dhcp_ptr->STATE == DHCP_RENEWING ||
           dhcp_ptr->STATE == DHCP_INFORMED )
      {
         /* Unicast the message to the server */
         destination_address = dhcp_ptr->DATA.ServerIp;
      } else {
         /* Broadcast the request */
         destination_address = INADDR_BROADCAST;
      } /* Endif */

      UDP_send_internal(BOOT_port,
                        dhcp_ptr->DATA.ClientIPaddress,
                        destination_address,
                        DHCP_SERVER_PORT,
                        pcb_ptr,
                        0);
   } else {
      /* Send the datagram */
      BOOT_send(pcb_ptr, dhcp_ptr->HANDLE);
   } /* Endif */

   return TRUE;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_send_one_shot
* Returned Values : void
* Comments        : Sends a single DHCP packet without resend.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_send_one_shot
   (
    DHCP_CLNT_STRUCT  _PTR_ dhcp_ptr
   /* [IN/OUT] This is the DHCP Client control structure */
   )
{ /* Body */
   RTCSPCB_PTR       pcb_ptr;

   /* Allocate a PCB */
   pcb_ptr = RTCSPCB_alloc_send();
   if (pcb_ptr == NULL) {
      return;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb_ptr);

   /* Put the DHCP packet in the PCB */
   RTCSLOG_PCB_WRITE(pcb_ptr, RTCS_LOGCTRL_PORT(IPPORT_BOOTPC), 0);
   RTCSPCB_append_fragment(pcb_ptr, dhcp_ptr->CURRENT_PACKET_SIZE, dhcp_ptr->PACKET);

   if ( dhcp_ptr->BOUND ) {
      /* We already have an IP address available */
      UDP_send_internal(BOOT_port,
                        dhcp_ptr->NEW_DATA.ClientIPaddress,
                        dhcp_ptr->NEW_DATA.ServerIp,
                        DHCP_SERVER_PORT,
                        pcb_ptr,
                        0);
   } else {
      /* Send the datagram */
      BOOT_send(pcb_ptr, dhcp_ptr->HANDLE);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_rebind_lease
* Returned Values : boolean
* Comments        :
*     Attempts to renew the current lease unicasting to the server.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean DHCPCLNT_rebind_lease
   (
   TCPIP_EVENT_PTR   event
   /* [IN/OUT] the renew event */
   )
{ /* Body */
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr = event->PRIVATE;
   uint_32                rebind_time;
   boolean                reset_event = FALSE;

   if ( dhcp_ptr->R_EVENTS_TIME_LEFT ) {
      DHCPCLNT_TIME_OVERFLOW_CHECK(rebind_time, dhcp_ptr->R_EVENTS_TIME_LEFT)
      dhcp_ptr->RENEW.TIME = rebind_time;
      reset_event = TRUE;
   } else {
      TCPIP_Event_cancel(&dhcp_ptr->RESEND);
      /*
      ** Need to make sure that the renew time is now greater than the rebind
      ** for use by DHCPCLNT_send to know the previous state if requests fail.
      */
      dhcp_ptr->RENEW_TIME = dhcp_ptr->DATA.LEASE;
      dhcp_ptr->STATE = DHCP_REBINDING;
      DHCPCLNT_modify_options( dhcp_ptr );
      DHCPCLNT_open( dhcp_ptr );
   } /* Endif */

   return( reset_event );
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_renew_lease
* Returned Values : boolean
* Comments        :
*     Attempts to renew the current lease unicasting to the server.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean DHCPCLNT_renew_lease
   (
   TCPIP_EVENT_PTR   event
   /* [IN/OUT] the renew event */
   )
{ /* Body */
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr = event->PRIVATE;
   uint_32                renew_time;

   if (!dhcp_ptr->R_EVENTS_TIME_LEFT ) {
      dhcp_ptr->STATE = DHCP_RENEWING;
      DHCPCLNT_modify_options( dhcp_ptr );

      dhcp_ptr->INIT_TIMEOUT = 0;

      DHCPCLNT_open( dhcp_ptr );

      /* Set up for DHCP Rebinding */
      dhcp_ptr->R_EVENTS_TIME_LEFT = dhcp_ptr->REBIND_TIME;
      dhcp_ptr->RENEW.EVENT = DHCPCLNT_rebind_lease;
   } /* Endif */

   DHCPCLNT_TIME_OVERFLOW_CHECK(renew_time, dhcp_ptr->R_EVENTS_TIME_LEFT);
   dhcp_ptr->RENEW_TIME = 0;

   dhcp_ptr->RENEW.TIME = renew_time;

   return( TRUE );
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_terminate_lease
* Returned Values : boolean
* Comments        :
*     If a lease expires, or a DHCPNAK message is received, this function
*     will broadcast another DHCPDISCOVER message.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean DHCPCLNT_terminate_lease
   (
   TCPIP_EVENT_PTR   event
   /* [IN/OUT] the termination event */
   )
{  /* Body */
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr = event->PRIVATE;
   uint_32                terminate_time;
   boolean                retry = FALSE;
   boolean                reset_event = FALSE;

   if ( dhcp_ptr->TERMINATE_TIME ) {
      DHCPCLNT_TIME_OVERFLOW_CHECK(terminate_time, dhcp_ptr->TERMINATE_TIME)
      dhcp_ptr->TERMINATE.TIME = terminate_time;
      reset_event = TRUE;
   } else {
      if (dhcp_ptr->BOUND) {
         RTCSCMD_internal( dhcp_ptr->PARMS_BIND, IPIF_unbind );
         if ( dhcp_ptr->UNBIND_FUNC != NULL ) {
            retry = dhcp_ptr->UNBIND_FUNC((_rtcs_if_handle)dhcp_ptr->HANDLE);
         } /* Endif */
      } else {
         if ( dhcp_ptr->FAILURE_FUNC != NULL ) {
            dhcp_ptr->FAILURE_FUNC((_rtcs_if_handle)dhcp_ptr->HANDLE);
         } /* Endif */   
      } /* Endif */

      TCPIP_Event_cancel(&dhcp_ptr->RENEW);
      TCPIP_Event_cancel(&dhcp_ptr->RESEND);

      if ( retry ) {
         dhcp_ptr->REBIND_TIME = 0;
         dhcp_ptr->BOUND = FALSE;
         dhcp_ptr->STATE = DHCP_INITIALIZE;
         DHCPCLNT_modify_options( dhcp_ptr );
         DHCPCLNT_open( dhcp_ptr );
      } else  {
         BOOT_close();
         dhcp_ptr->HANDLE->BOOT = NULL;
         /* Free the DHCP Structure */
         _mem_free(dhcp_ptr);
      }/* Endif */
   } /* Endif */

   return( reset_event );
}  /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_bind_attempt_timeout
* Returned Values : boolean
* Comments        :
*     This function will timeout a lease attempt if the binding is not
*     successful.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean DHCPCLNT_bind_attempt_timeout
   (
   TCPIP_EVENT_PTR   event
   /* [IN/OUT] the termination event */
   )
{  /* Body */
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr = event->PRIVATE;
   boolean                retry = FALSE;

   if ( dhcp_ptr->FAILURE_FUNC != NULL ) {
      retry = dhcp_ptr->FAILURE_FUNC((_rtcs_if_handle)dhcp_ptr->HANDLE);
   } /* Endif */

   TCPIP_Event_cancel(&dhcp_ptr->RESEND);

   if ( retry ) {
      dhcp_ptr->REBIND_TIME = 0;
      dhcp_ptr->BOUND = FALSE;
      dhcp_ptr->STATE = DHCP_INITIALIZE;
      DHCPCLNT_modify_options( dhcp_ptr );
      DHCPCLNT_open( dhcp_ptr );
   } else  {
      BOOT_close();
      dhcp_ptr->HANDLE->BOOT = NULL;
      /* Free the DHCP Structure */
      _mem_free(dhcp_ptr);
   }/* Endif */

   return FALSE;
}  /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_decline
* Returned Values : void
* Comments        :
*     Declines a lease, sends a message to the DCHP Server.
*     Add error code message later.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_decline
   (
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr,
   /* [IN/OUT] This is the DHCP Client control structure */
   uint_32     error
   /* [IN] The reason for rejection */
   )
{  /* Body */
    uint_32     old_state = dhcp_ptr->STATE;

    dhcp_ptr->STATE = DHCP_DECLINING;
    DHCPCLNT_modify_options( dhcp_ptr );

    DHCPCLNT_send_one_shot( dhcp_ptr );
    dhcp_ptr->STATS.ST_TX_DECLINE++;
    dhcp_ptr->STATE = old_state;
    DHCPCLNT_modify_options( dhcp_ptr );

}  /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_release_internal
* Returned Values : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

void DHCPCLNT_release_internal
   (
      TCPIP_PARM_IF_DHCP_RELEASE _PTR_ parms
         /* [IN/OUT] This is the DHCP Client structure from the application */
   )
{  /* Body */
   IP_IF_PTR              if_ptr = (IP_IF_PTR)parms->HANDLE;
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr;

   if ( if_ptr->BOOT != NULL ) {
      dhcp_ptr = (DHCP_CLNT_STRUCT _PTR_)if_ptr->BOOT;

      TCPIP_Event_cancel(&dhcp_ptr->RENEW);
      TCPIP_Event_cancel(&dhcp_ptr->RESEND);
      TCPIP_Event_cancel(&dhcp_ptr->TERMINATE);

      dhcp_ptr->STATE = DHCP_RELEASING;
      DHCPCLNT_modify_options( dhcp_ptr );

      DHCPCLNT_send_one_shot( dhcp_ptr );
      if ( dhcp_ptr->BOUND ) {
         RTCSCMD_internal( dhcp_ptr->PARMS_BIND, IPIF_unbind );
      }/* Endif */
      BOOT_close();
      /* Free the DHCP Structure */
      _mem_free(dhcp_ptr);
      if_ptr->BOOT = NULL;
   }/* Endif */

   RTCSCMD_complete(parms, RTCS_OK);
}  /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_parse_offer
* Returned Values : void
* Comments        : We only look for the options that affect us directly.
*                   It is assumed that the application will parse any
*                   site specific options.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_parse_offer
   (
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr,
   /* [IN/OUT] This is the DHCP Client control structure */
   RTCSPCB_PTR pcb_ptr
   /*[IN] The offer we're accepting */
   )
{ /* Body */
   DHCP_HEADER _PTR_ header_ptr;
   uchar       _PTR_ opt;
   uint_32           len;
   uint_32           optlen;
   uchar             optval;

   dhcp_ptr->NEW_RENEW_TIME = 0;
   dhcp_ptr->NEW_REBIND_TIME = 0;
   /* Make sure we have a server ID */
   header_ptr = (DHCP_HEADER _PTR_)RTCSPCB_DATA(pcb_ptr);

   /* Get our IP address, and pick the default netmask */
   dhcp_ptr->NEW_PARMS_BIND.address = ntohl(header_ptr->YIADDR);
   dhcp_ptr->NEW_DATA.ClientIPaddress = dhcp_ptr->NEW_PARMS_BIND.address;
   dhcp_ptr->NEW_PARMS_BIND.locmask = 0xFFFFFFFFL;
   dhcp_ptr->NEW_PARMS_BIND.netmask =
      IN_DEFAULT_NET(dhcp_ptr->NEW_PARMS_BIND.address);

   /* Parse the options field */

   opt = (uchar _PTR_)header_ptr + sizeof(DHCP_HEADER) + 4;
   len = RTCSPCB_SIZE(pcb_ptr) - (sizeof(DHCP_HEADER) + 4);

#define DHCP_NEXTOPT    opt += optlen; \
                        break

   while (len) {

      /* Get the next option code */
      optval = ntohc(opt);
      opt++;
      len--;

      /* Interpret the pad and end options */
      if (optval == DHCPOPT_END) break;
      if (optval == DHCPOPT_PAD) continue;

      /* All other codes have a length byte */
      if (len == 0) break;
      optlen = ntohc(opt);
      opt++;
      len--;
      if (len < optlen) break;
      len -= optlen;

      switch (optval) {

      case DHCPOPT_LEASE:
         if (optlen != 4) {DHCP_NEXTOPT;}
         dhcp_ptr->NEW_DATA.LEASE = ntohl(opt);
         opt += 4;
         break;

      case DHCPOPT_MASK:
         if (optlen != 4) {DHCP_NEXTOPT;}
         dhcp_ptr->NEW_PARMS_BIND.netmask = ntohl(opt);
         dhcp_ptr->NEW_DATA.Netmask = dhcp_ptr->NEW_PARMS_BIND.netmask;
         opt += 4;
         break;

      case DHCPOPT_SERVERNAME:

         _mem_copy(opt, dhcp_ptr->NEW_DATA.SNAME, optlen);
         opt+=optlen;
         break;

      case DHCPOPT_FILENAME:

         _mem_copy(opt, dhcp_ptr->NEW_DATA.BOOTFILE, optlen);
         opt+=optlen;
         break;

      case DHCPOPT_RENEWALL:
         if ( optlen != DHCPSIZE_LEASE ) {
            DHCP_NEXTOPT;
         } /* Endif */
         dhcp_ptr->NEW_RENEW_TIME = ntohl(opt);
         opt += DHCPSIZE_LEASE;
         break;

      case DHCPOPT_REBINDING:
         if ( optlen != DHCPSIZE_LEASE ) {
            DHCP_NEXTOPT;
         } /* Endif */
         dhcp_ptr->NEW_REBIND_TIME = ntohl(opt);
         opt += DHCPSIZE_LEASE;
         break;

      default:
         DHCP_NEXTOPT;
      } /* Endswitch */

   } /* Endwhile */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_copy_binding
* Returned Values : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_copy_binding
   (
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr
   /* [IN/OUT] This is the DHCP Client control structure */
   )
{  /* Body */
   dhcp_ptr->PARMS_BIND.address = dhcp_ptr->NEW_PARMS_BIND.address;
   dhcp_ptr->PARMS_BIND.locmask = dhcp_ptr->NEW_PARMS_BIND.locmask;
   dhcp_ptr->PARMS_BIND.netmask = dhcp_ptr->NEW_PARMS_BIND.netmask;
   dhcp_ptr->DATA.ServerIp = dhcp_ptr->NEW_DATA.ServerIp;
   dhcp_ptr->DATA.ClientIPaddress = dhcp_ptr->NEW_DATA.ClientIPaddress;
   dhcp_ptr->DATA.LEASE = dhcp_ptr->NEW_DATA.LEASE;
   dhcp_ptr->DATA.Netmask = dhcp_ptr->NEW_DATA.Netmask;
   dhcp_ptr->DATA.SADDR   = dhcp_ptr->NEW_DATA.SADDR;

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_verify_packet
* Returned Values : uchar
* Comments        :
*     Verifies the validity of an incoming DHCP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static uchar DHCPCLNT_verify_packet
 (
 DHCP_CLNT_STRUCT _PTR_ dhcp_ptr,
 RTCSPCB_PTR            pcb_ptr,
 uchar            _PTR_ bootreply,
 uint_32          _PTR_ packet_size,
 _ip_address      _PTR_ temp_addr,
 _ip_address      _PTR_ current_ip,
 uint_32          _PTR_ error
 )

{ /* Body */
   DHCP_HEADER      _PTR_ send_header_ptr;
   DHCP_HEADER      _PTR_ header_ptr;
   uchar            _PTR_ opt;
   uint_32                len;
   uchar            _PTR_ packet_option;

   /* Make sure the datagram is large enough for the magic cookie */
   if (RTCSPCB_SIZE(pcb_ptr) < sizeof(DHCP_HEADER) + 4) {
      *error = RTCSERR_DHCPCLNT_PACKET_SIZE_ERROR;
      return 0;
   } /* Endif */

   send_header_ptr = (DHCP_HEADER _PTR_)dhcp_ptr->PACKET;
   header_ptr = (DHCP_HEADER _PTR_)bootreply;
   /* Make sure the XID matches */
   if (ntohl(header_ptr->XID) != ntohl(send_header_ptr->XID)) {
      *error = RTCSERR_DHCPCLNT_XID_MISMATCH;
      return 0;
   } /* Endif */

   /* Parse the options field to find the message type */
   opt = bootreply + sizeof(DHCP_HEADER);
   *packet_size = RTCSPCB_SIZE(pcb_ptr);
   len = *packet_size - sizeof(DHCP_HEADER);
   if (ntohl(opt) != DHCP_MAGIC) {
      *error = RTCSERR_DHCP_PACKET_ERROR;
      return 0;
   } /* Endif */
   opt += 4;
   len -= 4;
   /* These are to avoid problems in DHCPCLNT_modify_options if we decline */
   *temp_addr = dhcp_ptr->NEW_DATA.ServerIp;
   dhcp_ptr->NEW_DATA.ServerIp = IP_source(pcb_ptr);
   dhcp_ptr->NEW_DATA.ClientIPaddress = ntohl(header_ptr->YIADDR);

   packet_option = DHCP_find_option(opt, len, DHCPOPT_SERVERID);
   if ( !packet_option || ntohc(packet_option + 1) != 4 ) {
      /* Server id option is required in all DHCP responses */
      DHCPCLNT_decline( dhcp_ptr, RTCSERR_DHCP_SERVER_OPTION_MISSING );
      dhcp_ptr->NEW_DATA.ServerIp = *temp_addr;
      *error = RTCSERR_DHCPCLNT_ERROR_DECLINED;
      return 0;
   } else  {
      packet_option += 2;
      *current_ip = ntohl(packet_option);
   } /* Endif */

   packet_option = DHCP_find_option(opt, len, DHCPOPT_MSGTYPE);
   if ( !packet_option || ntohc(packet_option + 1) != 1 ) {
      /* Message type option is required in all DHCP packets */
      DHCPCLNT_decline( dhcp_ptr, RTCSERR_DHCP_MESSAGE_OPTION_MISSING);
      dhcp_ptr->NEW_DATA.ServerIp = *temp_addr;
      *error = RTCSERR_DHCPCLNT_ERROR_DECLINED;
      return 0;
   } /* Endif */
   packet_option += 2;
   *error = RTCS_OK;
   return(ntohc(packet_option));
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_service_offer
* Returned Values : void
* Comments        :
*     Services an incoming DHCP offer packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_service_offer
 (
 DHCP_CLNT_STRUCT _PTR_ dhcp_ptr,
 RTCSPCB_PTR            pcb_ptr,
 uchar            _PTR_ bootreply,
 uint_32                packet_size,
 _ip_address            temp_addr,
 _ip_address            current_ip
  )

{  /* Body */

   dhcp_ptr->STATS.ST_RX_OFFER++;
   if ( dhcp_ptr->STATE == DHCP_INITIALIZE ) {
      if ( dhcp_ptr->CHOICE_FUNC != NULL ) {
         if (dhcp_ptr->CHOICE_FUNC(bootreply, packet_size) < 0) {
            /* It's been rejected */
            dhcp_ptr->NEW_DATA.ServerIp = temp_addr;
            return;
         }/* Endif */
      }/* Endif */
      
      /* start the probe - this needs to complete before we service the dhACK */
      if (dhcp_ptr->FLAGS & DHCP_SEND_PROBE) {
         DHCPCLNT_probe_address( dhcp_ptr->NEW_DATA.ClientIPaddress,  dhcp_ptr->HANDLE);
      }
      /* We're accepting this offer */
      TCPIP_Event_cancel(&dhcp_ptr->RESEND);
      dhcp_ptr->NEW_DATA.ServerIp = current_ip;
      DHCPCLNT_parse_offer( dhcp_ptr, pcb_ptr );
      dhcp_ptr->STATE = DHCP_REQUESTING;
      DHCPCLNT_modify_options( dhcp_ptr );
      dhcp_ptr->RETRY_TIMEOUT = DHCP_TIMEOUT_MIN;
      
      /* 
      ** put a bit of delay in before we send the REQEST. This is to give the
      ** probe (started above) a chance to compete.
      */
      dhcp_ptr->RESEND.TIME = 50;  /* 50 miliseconds */
      TCPIP_Event_add( &dhcp_ptr->RESEND );
   }/* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_set_timed_events
* Returned Values : void
* Comments        :
*     Sets the renewall, rebinding, and termination times.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_set_timed_events
(
DHCP_CLNT_STRUCT _PTR_ dhcp_ptr
)


{  /* Body */
   uint_32                random;
   uint_32                renewall_range;
   uint_32                renewall_time;
   uint_32                terminate_time;

   /* Set or reset the renewall event */
   if ( dhcp_ptr->NEW_RENEW_TIME ) {
      dhcp_ptr->RENEW_TIME = dhcp_ptr->NEW_RENEW_TIME;
   } else {
      /*
      ** The renewall time wasn't specified by the DHCP server,
      ** we need to set it ourselves.
      */
      DHCP_SET_RENEWALL_RANGE(dhcp_ptr->DATA.LEASE, renewall_range);
      random = RTCS_rand() % renewall_range;
      dhcp_ptr->RENEW_TIME =
         DHCP_RENEWALL_BIAS( dhcp_ptr->DATA.LEASE ) + random;
   } /* Endif */

   /* Set or reset rebinding event */
   if ( dhcp_ptr->NEW_REBIND_TIME ) {
      dhcp_ptr->REBIND_TIME = dhcp_ptr->NEW_REBIND_TIME
         - dhcp_ptr->RENEW_TIME;
   } else {
      /*
      ** The rebinding time wasn't specified by the DHCP server,
      ** we need to set it ourselves.
      */
      DHCP_SET_RENEWALL_RANGE(dhcp_ptr->DATA.LEASE, renewall_range);
      random = RTCS_rand() % renewall_range;
      dhcp_ptr->REBIND_TIME =
         (DHCP_REBINDING_BIAS(dhcp_ptr->DATA.LEASE) + random)
         - dhcp_ptr->RENEW_TIME;
   }/* Endif */

   dhcp_ptr->R_EVENTS_TIME_LEFT = dhcp_ptr->RENEW_TIME;
   DHCPCLNT_TIME_OVERFLOW_CHECK(renewall_time, dhcp_ptr->R_EVENTS_TIME_LEFT)
   dhcp_ptr->RENEW.TIME = renewall_time;
   dhcp_ptr->RENEW.EVENT = DHCPCLNT_renew_lease;
   dhcp_ptr->TERMINATE_TIME = dhcp_ptr->DATA.LEASE;

   DHCPCLNT_TIME_OVERFLOW_CHECK(terminate_time, dhcp_ptr->TERMINATE_TIME)
   dhcp_ptr->TERMINATE.TIME = terminate_time;
}  /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_service_ack
* Returned Values : void
* Comments        :
*     Services an incoming DHCP ack packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_service_ack
(
DHCP_CLNT_STRUCT _PTR_ dhcp_ptr,
RTCSPCB_PTR            pcb_ptr,
uchar            _PTR_ bootreply,
uint_32                packet_size,
IP_IF_PTR              if_ptr
)

{  /* Body */
   DHCP_HEADER      _PTR_ header_ptr;
   boolean                renew_again = TRUE;

   dhcp_ptr->STATS.ST_RX_ACK++;
   if ( dhcp_ptr->STATE == DHCP_INFORMED ) {
      /* Give the application the info and self destruct */
      TCPIP_Event_cancel(&dhcp_ptr->RESEND);
      if ( dhcp_ptr->BIND_FUNC != NULL ) {
         dhcp_ptr->BIND_FUNC(bootreply, packet_size, (_rtcs_if_handle)if_ptr);
      } /* Endif */
      BOOT_close();
      dhcp_ptr->HANDLE->BOOT = NULL;
      /* Free the DHCP Structure */
      _mem_free(dhcp_ptr);
      return;
   } /* Endif */

   header_ptr = (DHCP_HEADER _PTR_)bootreply;
   /* OK, we've got a valid lease */
   dhcp_ptr->DATA.SADDR = ntohl(header_ptr->SIADDR);
   dhcp_ptr->NEW_DATA.ClientIPaddress = ntohl(header_ptr->YIADDR);

   TCPIP_Event_cancel(&dhcp_ptr->TERMINATE);
   DHCPCLNT_parse_offer( dhcp_ptr, pcb_ptr );
   if ( dhcp_ptr->BOUND ) {
      if (dhcp_ptr->NEW_DATA.LEASE < dhcp_ptr->DATA.LEASE) {
         /* Our request was refused, wait for termination to bind again */
         renew_again = FALSE;
      }/* Endif */
      dhcp_ptr->DATA.LEASE = dhcp_ptr->NEW_DATA.LEASE;
      /* Cancel renewall and lease expiry events */
      TCPIP_Event_cancel(&dhcp_ptr->RENEW);
   } else {
      /* Bind the received IP address to this interface */
      DHCPCLNT_copy_binding( dhcp_ptr );
      RTCSCMD_internal( dhcp_ptr->PARMS_BIND, IPIF_bind );
      dhcp_ptr->TERMINATE.EVENT = DHCPCLNT_terminate_lease;
   } /* Endif */

   if ( dhcp_ptr->DATA.LEASE != DHCP_LEASE_INFINITE ) {
      DHCPCLNT_set_timed_events(dhcp_ptr);
   } /* Endif */

   TCPIP_Event_cancel(&dhcp_ptr->RESEND);
   dhcp_ptr->BOUND = TRUE;
   if ( DHCPCLNT_verify_address( dhcp_ptr )) {
      /* Address is in use by another host, decline and restart */
      DHCPCLNT_decline( dhcp_ptr, RTCSERR_DHCP_ADDR_IN_USE);
      RTCSCMD_internal( dhcp_ptr->PARMS_BIND, IPIF_unbind );
      dhcp_ptr->BOUND = FALSE;
      dhcp_ptr->RENEW_TIME = 0;
      dhcp_ptr->STATE = DHCP_INITIALIZE;
      DHCPCLNT_modify_options( dhcp_ptr );
      DHCPCLNT_open( dhcp_ptr );
   } else  {
      dhcp_ptr->STATE = DHCP_BOUND;
      if ( dhcp_ptr->BIND_FUNC != NULL ) {
         dhcp_ptr->BIND_FUNC(bootreply, packet_size,
            (_rtcs_if_handle)if_ptr);
      }/* Endif */

      if (dhcp_ptr->DATA.LEASE == DHCP_LEASE_INFINITE) {
         if(!(dhcp_ptr->FLAGS & DHCP_MAINTAIN_STATE_ON_INFINITE_LEASE)) {
            BOOT_close();
            dhcp_ptr->HANDLE->BOOT = NULL;
            /* Free the DHCP Structure */
            _mem_free(dhcp_ptr);
         } /* Endif */
      } else  {
         if (renew_again) {
            TCPIP_Event_add(&dhcp_ptr->RENEW);
         }/* Endif */
         TCPIP_Event_add(&dhcp_ptr->TERMINATE);
      } /* Endif */
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_service_nak
* Returned Values : void
* Comments        :
*     Services an incoming DHCP NAK packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static void DHCPCLNT_service_nak
(
DHCP_CLNT_STRUCT _PTR_ dhcp_ptr,
uchar            _PTR_ bootreply,
uint_32                packet_size
)
{ /* Body */
   boolean retry = FALSE;

   /* Our request was refused. Start request over */
   dhcp_ptr->STATS.ST_RX_NAK++;

   if ( dhcp_ptr->NAK_FUNC != NULL )
   {
      retry = dhcp_ptr->NAK_FUNC(bootreply, packet_size, (_rtcs_if_handle)dhcp_ptr->HANDLE);
   } /* Endif */

   if ( retry ) {
      dhcp_ptr->STATE = DHCP_REQUESTING;
      DHCPCLNT_modify_options( dhcp_ptr ); 
   } else {
      dhcp_ptr->RENEW_TIME = 0;
      dhcp_ptr->TERMINATE_TIME = 0;

      TCPIP_Event_cancel(&dhcp_ptr->TERMINATE);
      DHCPCLNT_terminate_lease(&dhcp_ptr->TERMINATE);
   } /* Endif */

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_service
* Returned Values : void
* Comments        :
*     Services an incoming DHCP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

void DHCPCLNT_service
   (
      RTCSPCB_PTR    pcb_ptr,     /* [IN] DHCP packet */
      UCB_STRUCT_PTR ucb_ptr      /* [IN]     target UCB       */
   )
{ /* Body */
   IP_IF_PTR              if_ptr   = (IP_IF_PTR)pcb_ptr->IFSRC;
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr = (DHCP_CLNT_STRUCT _PTR_)if_ptr->BOOT;
   uchar            _PTR_ bootreply;
   uchar                  msgtype;
   uint_32                packet_size;
   uint_32                error;
   _ip_address            current_ip;
   _ip_address            temp_addr;

   RTCSLOG_PCB_READ(pcb_ptr, RTCS_LOGCTRL_PORT(IPPORT_BOOTPC), 0);

   if ((dhcp_ptr != NULL) && (dhcp_ptr->STATE != DHCP_BOUND)) {
      bootreply = RTCSPCB_DATA(pcb_ptr);
      msgtype = DHCPCLNT_verify_packet(dhcp_ptr, pcb_ptr, bootreply,
         &packet_size, &temp_addr, &current_ip, &error);
      if (error) {
         RTCSLOG_PCB_FREE(pcb_ptr, error);
         RTCSPCB_free(pcb_ptr);
         return;
      } /* Endif */
      if ( msgtype == DHCPTYPE_DHCPOFFER ) {
         DHCPCLNT_service_offer(dhcp_ptr, pcb_ptr, bootreply, packet_size,
            temp_addr, current_ip);
      } else {
         /* It's an ACK or a NAK message */
         if ( dhcp_ptr->STATE != DHCP_INITIALIZE ) {
            if ( msgtype == DHCPTYPE_DHCPACK ) {
               DHCPCLNT_service_ack(dhcp_ptr, pcb_ptr, bootreply, packet_size,
                  if_ptr);
            } else if (msgtype == DHCPTYPE_DHCPNAK ) {
               DHCPCLNT_service_nak(dhcp_ptr, bootreply, packet_size);
            } /* Endif */
         } /* Endif */
      } /* Endif */
   } /* Endif */

   RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
   RTCSPCB_free(pcb_ptr);
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_verify_address
* Returned Values : boolean, TRUE if the address is in use by another host,
*                   FALSE otherwise
* Comments        :
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

static boolean DHCPCLNT_verify_address
   (
   DHCP_CLNT_STRUCT _PTR_ dhcp_ptr
   /* [IN] This is the DHCP Client control structure */
   )
{  /* Body */
   _ip_address      new_ip = dhcp_ptr->DATA.ClientIPaddress;
   IP_IF_PTR        if_ptr = dhcp_ptr->HANDLE;
   
   if (! dhcp_ptr->FLAGS & DHCP_SEND_PROBE) {
      /* we are configured to not probe, so don't try to verify */
      return FALSE;
   } 
   
   /* note: an arp probe was sent out during DHCPCLNT_service_offer.
      we expect that if an arp response was comming, it arrived by
      now.
    */
    
   return ARP_is_complete (if_ptr, new_ip);
}  /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_probe_address
* Returned Values : RTCS_OK meanse that probe was sent out the interface. 
* Parameters      :
*
*     _ip_address       probe_addr    [IN] IP address to probe the network for
*     pointer     :     src_interface [IN] interface we will send the probe from
* 
* Comments        :
*     Send out an arp reuest to ipaddress from interface. An arp reply will
*     be noted by the arp system on this interface and may be referenced later.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 DHCPCLNT_probe_address
   (
      _ip_address       probe_addr,
      pointer           src_interface
   )
{ /* Body */

    return( ARP_request(src_interface, probe_addr, probe_addr ));

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/gpio/io_gpio.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_gpio.c$
* $Version : 3.8.44.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the GPIO functions for MQX
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "fio.h"
#include "io.h"
#include "io_prv.h"
#include "io_gpio.h"
#include "io_gpio_prv.h"

_mqx_int _io_gpio_open(MQX_FILE_PTR, char_ptr, char_ptr);
_mqx_int _io_gpio_close(MQX_FILE_PTR);
_mqx_int _io_gpio_read (MQX_FILE_PTR, char_ptr, _mqx_int);
_mqx_int _io_gpio_write(MQX_FILE_PTR, char_ptr, _mqx_int);
_mqx_int _io_gpio_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);

extern _mqx_int gpio_cpu_init(void);
extern _mqx_int gpio_cpu_open(MQX_FILE_PTR, char_ptr, char_ptr);
extern _mqx_int gpio_cpu_ioctl(MQX_FILE_PTR, _mqx_uint, pointer);
extern GPIO_PIN_MAP  gpio_global_pin_map; /* extern because it usually contains initializated values to non-zero */
extern GPIO_PIN_MAP  gpio_global_irq_map; /* extern because it usually contains initializated values to non-zero */

GPIO_DEV_DATA_PTR first_irq = NULL; /* first map having some IRQ */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_gpio_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a gpio driver.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_gpio_install
   (
      /* [IN] A string that identifies the device for fopen */
      /* input values are those identifiers defined in io_gpio.h file */
      char_ptr            identifier
   ) 
{ /* Body */
    if (IO_OK == gpio_cpu_init())
        return _io_dev_install(identifier, 
            _io_gpio_open,
            _io_gpio_close,
            _io_gpio_read,
            _io_gpio_write,
            gpio_cpu_ioctl,
            NULL);
    return (_mqx_uint)IO_ERROR;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_gpio_open
* Returned Value   : a gpio pointer
* Comments         : 
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_gpio_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR fd_ptr,
       
      /* [IN] the remaining portion of the name of the device */
      char_ptr   open_name_ptr,

      /* [IN] the flags to be used during operation; pointer to pin table */
      char_ptr   flags
   )
{ /* Body */
    _mqx_int             i;
    uint_32              pin;
    uint_32              addr;
    GPIO_DEV_DATA_PTR    dev_data_ptr;
    GPIO_PIN_STRUCT _PTR_ pin_table = (GPIO_PIN_STRUCT _PTR_) flags;
 
    if (NULL == (dev_data_ptr = (GPIO_DEV_DATA_PTR) _mem_alloc_system_zero(sizeof(GPIO_DEV_DATA))))
        return IO_ERROR;
    _mem_set_type(dev_data_ptr, MEM_TYPE_IO_GPIO_DEV_DATA);  
 
    fd_ptr->DEV_DATA_PTR = (pointer) dev_data_ptr;
 
    _int_disable();
    if (pin_table != NULL) {
        /* rewrite pin_table to pin_map */
        for (; *pin_table != GPIO_LIST_END; pin_table++) {
            /* check pin validity bit */  
            if (*pin_table & GPIO_PIN_VALID) {
                /* prepare address of port */ 
                addr = GPIO_GET_PORT(*pin_table);
                /* prepare bit mask */
                pin = GPIO_GET_BIT_MASK(*pin_table); 
                /* pin address out of map scope? */
                if (addr < sizeof(GPIO_PIN_MAP) * 8 / (GPIO_PIN_BIT_MASK + 1)) {
                    /* pin address already used? */
                    if (! ( GPIO_GET_PIN_USED( gpio_global_pin_map, addr,  pin))) {
                        if (*pin_table & (GPIO_PIN_IRQ_LIST)) {
                            /* pin can be used as IRQ pin ? */
                            if (!( GPIO_GET_PIN_USED (gpio_global_irq_map, addr, pin ))) {
                                /* mark irq pin as used by this file by table
                                **       irqN_map   irqp_map    irql_map
                                ** RISING   0           1           0
                                ** FALLING  1           0           0
                                ** ZERO     1           0           1
                                ** ONE      0           1           1   */
                                _mqx_int error = 0;

                                switch( *pin_table & (GPIO_PIN_IRQ_LIST)) {
                                    case GPIO_PIN_IRQ_RISING:
                                        GPIO_SET_PIN_USED( dev_data_ptr->irqp_map, addr, pin);
                                        break;
                                    case GPIO_PIN_IRQ_FALLING:
                                        GPIO_SET_PIN_USED( dev_data_ptr->irqn_map, addr, pin);
                                        break;
                                    case GPIO_PIN_IRQ_RISING | GPIO_PIN_IRQ_FALLING:
                                        GPIO_SET_PIN_USED( dev_data_ptr->irqp_map, addr, pin);
                                        GPIO_SET_PIN_USED( dev_data_ptr->irqn_map, addr, pin);
                                        break;
                                    #if PSP_MQX_CPU_IS_KINETIS
                                    case GPIO_PIN_IRQ_ZERO:
                                        GPIO_SET_PIN_USED( dev_data_ptr->irqn_map, addr, pin);
                                        GPIO_SET_PIN_USED( dev_data_ptr->irql_map, addr, pin);
                                        break;
                                    case GPIO_PIN_IRQ_ONE:
                                        GPIO_SET_PIN_USED( dev_data_ptr->irqp_map, addr, pin);
                                        GPIO_SET_PIN_USED( dev_data_ptr->irql_map, addr, pin);
                                        break;
                                    #endif
                                    default:
                                        /* cannot handle another combination of IRQ flags */
                                        error = IO_ERROR;
                                        break;
                                }
                                if (!error) {
                                    /* mark pin as used by this file */
                                    GPIO_SET_PIN_USED( dev_data_ptr->pin_map, addr, pin );                                 
                                    continue; /* manage next pin */
                                }
                            }
                        }
                        else {
                            /* mark pin as used by this file */
                            GPIO_SET_PIN_USED( dev_data_ptr->pin_map, addr, pin );
                            continue; /* manage next pin */
                        }
                    }
                }
            }
            /* some error occured */
            _int_enable();
            _mem_free(dev_data_ptr);
            return IO_ERROR;
        }
    }
 
    if (IO_OK != gpio_cpu_open(fd_ptr, open_name_ptr, flags)) {
        _int_enable();
        _mem_free(dev_data_ptr);
        return IO_ERROR;
    }
 
    /* set bits in global pin maps that they are used by this file */
    for (i = 0; i < sizeof(gpio_global_pin_map) / sizeof(gpio_global_pin_map.memory32[0]); i++) {
        gpio_global_pin_map.memory32[i] |= dev_data_ptr->pin_map.memory32[i];
        gpio_global_irq_map.memory32[i] |= (dev_data_ptr->irqp_map.memory32[i] | dev_data_ptr->irqn_map.memory32[i]);
    }
 
    _int_enable();
    return IO_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_gpio_close
* Returned Value   : ERROR CODE
* Comments         : Closes gpio driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_gpio_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */
    _mqx_int           i;
    GPIO_DEV_DATA_PTR  dev_data_ptr = (GPIO_DEV_DATA_PTR) fd_ptr->DEV_DATA_PTR;

    _int_disable();
    
    ioctl(fd_ptr, GPIO_IOCTL_DISABLE_IRQ,      NULL); /* disable interrupts for pin list */
    ioctl(fd_ptr, GPIO_IOCTL_SET_IRQ_FUNCTION, NULL); /* remove any IRQ routine from list */
    
    /* exclude pins from global pin memory */
    for (i = 0; i < sizeof(gpio_global_pin_map) / sizeof(gpio_global_pin_map.memory32[0]); i++) {
        gpio_global_pin_map.memory32[i] &= ~dev_data_ptr->pin_map.memory32[i];
        gpio_global_irq_map.memory32[i] &= ~(dev_data_ptr->irqp_map.memory32[i] | dev_data_ptr->irqn_map.memory32[i]);
    }
    _int_enable();

/* At closing, we can revert to alternate function
** But for now, we do nothing
*/
    
   _mem_free(dev_data_ptr);

   return MQX_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_gpio_read
* Returned Value   : number of characters read
* Comments         : 
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_gpio_read
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the characters are to be stored */
      char_ptr   data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int   num
   )
{ /* Body */
   return 0;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_gpio_write
* Returned Value   : number of characters written
* Comments         : 
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_gpio_write
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the characters are */
      char_ptr   data_ptr,

      /* [IN] the number of characters to output */
      _mqx_int   num
   )
{ /* Body */
   return 0;
} /* Endbody */


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_gpio_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_gpio_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint  cmd,

      /* [IN] the ioctl parameters */
      pointer    param_ptr
   )
{ /* Body */
     return IO_ERROR_INVALID_IOCTL_CMD;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/igmp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: igmp.c$
* $Version : 3.8.12.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the Internet
*   Group Management Protocol.  For more details, refer
*   to RFC1112 for version 1 and RFC2236 for version 2.
*
*END************************************************************************/

/*
** - review the protocol compliance. drop timer and unsolicited counter when i leave.
**   require to send igmp query/report from another computer.
** - the application problem is: RTCS don't listen on a address/port but only
**   on a port, sending a pkt on a specified interface, supporting the classical
**   setsockopts i.e. NOLOOP(do not loopback the outgoing packet), SET_TTL
**   (set the ttl for the outgoing multicast packet), SET_OUTGOING_IF (set the
**   outgoing interface)
** - IGMPV2 is complete except the router alert ip option which must be added for
**   each igmp packet because ip_send doesnt support the ip option. rfc2236.10
**   (security consideration) a report without a router alert must be discarded.
*/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4

#ifdef IGMP_V2
#  define IGMP_DEFAULT_REPORT   IGMPTYPE_V2_REPORT
#else
#  define IGMP_DEFAULT_REPORT   IGMPTYPE_V1_REPORT
#endif

/* local prototypes */
static void IGMP_service(RTCSPCB_PTR pcb, pointer dummy);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_init
* Returned Values : uint_32
* Comments        :
*     Initialize the IGMP layer.
*
*END*-----------------------------------------------------------------*/

uint_32 IGMP_init
   (
      void
   )
{ /* Body */
   uint_32              error;
   IGMP_CFG_STRUCT_PTR  IGMP_cfg_ptr;

   /* alloc and init the configuration block */
   IGMP_cfg_ptr = RTCS_mem_alloc_zero(sizeof(IGMP_CFG_STRUCT));
   if (!IGMP_cfg_ptr) {
      return RTCSERR_IGMP_CFG;
   } /* Endif */

   /* register the configuration block */
   RTCS_setcfg(IGMP, IGMP_cfg_ptr);

   /* register the igmp protocol in the ip layer */
   IP_open(IPPROTO_IGMP, IGMP_service, NULL, &error);
   if (error != RTCS_OK) {
      return RTCSERR_IGMP_CFG;
   } /* Endif */

   /*
   ** When IGMP_init() is called, the only registered interface is the
   ** loopback interface, so we don't need to join the all-hosts group
   ** on any interface here.
   */

   return error;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_send_report
* Returned Values : uint_32
* Comments        :
*     send a report on the network
*
*END*-----------------------------------------------------------------*/

boolean IGMP_send_report
   (
      ip_mreq _PTR_ igrp,
      uint_16  type
   )
{ /* Body */
   IGMP_CFG_STRUCT_PTR  IGMP_cfg_ptr = RTCS_getcfg(IGMP);
   uint_32              error;
   uint_16              checksum;
   RTCSPCB_PTR          pcb;
   IGMP_HEADER_PTR      header;
   IP_IF_PTR            ipif;
   _ip_address          ipdst;

   IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);

   /* never send a report for the local groups */
   if (IN_LOCAL_MULTICAST(igrp->imr_multiaddr.s_addr)) {
      return TRUE;
   } /* Endif */

   /* get the interface with its ip address */
   ipif = IP_find_if(igrp->imr_interface.s_addr);
   if (ipif == NULL) {
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      return FALSE;
   } /* Endif */

   pcb = RTCSPCB_alloc_send();
   if (pcb == NULL) {
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      return FALSE;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb);

   error = RTCSPCB_insert_header(pcb, sizeof(IGMP_HEADER));
   if (error) {
      RTCSLOG_PCB_FREE(pcb, error);
      RTCSPCB_free(pcb);
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      return FALSE;
   } /* Endif */

   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_IGMP), 1);

#ifdef IGMP_V2
   /* check if routers igmpv1 are present or not */
   if (type == IGMPTYPE_V2_REPORT && ipif->IGMP_V1_ROUTER_FLAG) {
      uint_32 curTime = RTCS_time_get();
      /* WORK: handle the overflow (see tcp seq) */
      if (curTime < ipif->IGMP_V1_ROUTER_TIMEOUT) {
         type = IGMPTYPE_V1_REPORT;
      } else {
         /* if the timeout expired, clear the flag */
         ipif->IGMP_V1_ROUTER_FLAG = 0;
      } /* Endif */
   } /* Endif */
#endif   /* IGMP_V2 */

   /* build the igmp packet */
   header = (IGMP_HEADER_PTR)RTCSPCB_DATA(pcb);
   htonc(header->TYPE, type);
   htonc(header->MAX_RESP_TIME, 0);
   htons(header->CHECKSUM, 0);
   htonl(header->GROUP_ADDRESS, igrp->imr_multiaddr.s_addr);
   checksum = _mem_sum_ip(0, sizeof(IGMP_HEADER), header);
   checksum = IP_Sum_invert(checksum);
   htons(header->CHECKSUM, checksum);

   /* WORK: for IGMP_V2, add a router alert option but currently ip layer doesnt support ip options */

   /* send the igmp packet */
   ipdst = igrp->imr_multiaddr.s_addr;
#ifdef IGMP_V2
   if (type == IGMPTYPE_LEAVE) {
      ipdst = INADDR_ALLROUTERS_GROUP;
   } /* Endif */
#endif

   IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.ST_TX_REPORT++);    /* WORK: not always true for IGMP_V2 */
   error = IP_send(pcb, IPPROTO_IGMP | IPTTL(1), igrp->imr_interface.s_addr, ipdst, RTCS_MSG_NOLOOP);

   return TRUE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_expire
* Returned Values :
* Comments        :
*     Called by the Timer.  Expire a IGMP report datagram.
*
*END*-----------------------------------------------------------------*/

static boolean IGMP_expire
   (
      TCPIP_EVENT_PTR   event          /* [IN/OUT] the expiration event */
   )
{ /* Body */
   MC_MEMBER_PTR  member = event->PRIVATE;
   uint_32        error;

   member->RUNNING_TIMER = FALSE;

   error = IGMP_send_report(&member->IGRP, IGMP_DEFAULT_REPORT);

   /* an error occurs, retry later */
   if (!error) {
      member->TIMER.TIME = RTCS_rand()%IGMP_UNSOLICITED_REPORT_INTERVAL;
      member->RUNNING_TIMER = TRUE;
      return TRUE;
   } /* Endif */

   /* handle the unsolicited_report repetition */
   if (member->UNSOLICITED_REPORT_COUNTER) {
      member->UNSOLICITED_REPORT_COUNTER--;
      member->TIMER.TIME = IGMP_UNSOLICITED_REPORT_INTERVAL;
      member->RUNNING_TIMER = TRUE;
      return TRUE;
   } /* Endif */
#ifdef IGMP_V2
   member->LAST_REPORTER = TRUE;
#endif

   return FALSE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_init_timer
* Returned Values : void
* Comments        :
*     initialize the timer for one group
*
*END*-----------------------------------------------------------------*/

void IGMP_init_timer
   (
      MC_MEMBER_PTR  group
   )
{ /* Body */

   group->TIMER.EVENT = IGMP_expire;
   group->TIMER.PRIVATE = group;
   group->RUNNING_TIMER = FALSE;
#ifdef IGMP_V2
   group->LAST_REPORTER = FALSE;
#endif
   group->UNSOLICITED_REPORT_COUNTER = IGMP_UNSOLICITED_REPORT_COUNT;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_launch_timer
* Returned Values : void
* Comments        :
*     launch a timer for one group
*
*END*-----------------------------------------------------------------*/

void IGMP_launch_timer
   (
      MC_MEMBER_PTR  member,
      uint_32        delay
   )
{ /* Body */

   if (member->RUNNING_TIMER) {
      return;
   } /* Endif */

   member->TIMER.TIME = delay;
   member->RUNNING_TIMER = TRUE;
   TCPIP_Event_add(&member->TIMER);
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_stop_timer
* Returned Values : void
* Comments        :
*     stop a timer for one group
*
*END*-----------------------------------------------------------------*/

void IGMP_stop_timer
   (
      MC_MEMBER_PTR  member
   )
{ /* Body */

   if (!member->RUNNING_TIMER) {
      return;
   } /* Endif */

   TCPIP_Event_cancel(&member->TIMER);
   member->RUNNING_TIMER = FALSE;
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_rcv_report
* Returned Values :
* Comments        :
*     called when a report is received (from another computer)
*
*END*-----------------------------------------------------------------*/

static void IGMP_rcv_report
   (
      IP_IF_PTR   ipif,    /* [IN] the interface which receive the report */
      _ip_address group_ip /* [IN] the ip address of the multicast group */
   )
{ /* Body */
   MC_MEMBER_PTR  member;

   /* sanity check */
   if (IN_LOCAL_MULTICAST(group_ip) || !IN_MULTICAST(group_ip)) {
      return;
   } /* Endif */

   /* stop the running timer of this group */
   for (member = ipif->IGMP_MEMBER ; member ; member = member->NEXT) {
      if (member->IGRP.imr_multiaddr.s_addr == group_ip) {
         IGMP_stop_timer(member);
#ifdef IGMP_V2
         member->LAST_REPORTER = 0;
#endif
         member->UNSOLICITED_REPORT_COUNTER = 0;
         /* continue to scan the list in case of the same group_ip is joined
         ** with a different interface address. an given interface can have
         ** several ip address.
         */
      } /* Endif */
   } /* Endfor */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_rcv_query
* Returned Values :
* Comments        :
*     called when a query is received (from a router)
*
*END*-----------------------------------------------------------------*/

static void IGMP_rcv_query
   (
      IP_IF_PTR   ipif,          /* [IN] the interface which receive the report */
      _ip_address group_ip,      /* [IN] the ip address of the multicast group */
      uint_32     max_resp_time  /* [IN] the maximum response time of the query */
   )
{ /* Body */
   MC_MEMBER_PTR  member;


   /* sanity check */
   if (IN_LOCAL_MULTICAST(group_ip)) {
      return;
   } /* Endif */

#ifndef IGMP_V2
   max_resp_time = 0;   /* force a IGMP_V1 report */
#endif

   /* test if it is a IGMPv1 query */
   if (max_resp_time == 0) {
      max_resp_time = IGMP_V1_QUERY_RESPONSE_INTERVAL;
#ifdef IGMP_V2
      /* set the time out */
      ipif->IGMP_V1_ROUTER_FLAG = TRUE;
      ipif->IGMP_V1_ROUTER_TIMEOUT = RTCS_time_get()
                                     + IGMP_V1_ROUTER_TIMEOUT_VALUE;
#endif /* IGMP_V2 */
      group_ip = 0;  /* with IGMPv1, an query is always general (never group-specific) */
   } else  {
      /* convert IGMP_UNIT (1/10 sec) into the local unit (1/1000 sec) */
      max_resp_time = max_resp_time * (1000/10);
   } /* Endif */

   /* test if the group is already joined */
   for (member = ipif->IGMP_MEMBER ; member ; member = member->NEXT) {
      /* filter the suitable member(s) */
      if (group_ip && group_ip != member->IGRP.imr_multiaddr.s_addr) {
         continue;
      } /* Endif */

      /* never report a local group */
      if (IN_LOCAL_MULTICAST(member->IGRP.imr_multiaddr.s_addr)) {
         continue;
      } /* Endif */
      if (member->RUNNING_TIMER) {
         /* if a timer is running, check if the timer must be relaunched */
         if (TCPIP_Event_expire(&member->TIMER) > max_resp_time) {
            IGMP_stop_timer(member);
            IGMP_launch_timer(member, RTCS_rand() % max_resp_time);
         } /* Endif */
      } else {
         IGMP_init_timer(member);
         IGMP_launch_timer(member, RTCS_rand() % max_resp_time);
      } /* Endif */
   } /* Endfor */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IGMP_service
* Returned Values : void
* Comments        :
*     Process incoming IGMP packets.  Called from IP_service.
*
*END*-----------------------------------------------------------------*/

static void IGMP_service
   (
      RTCSPCB_PTR    pcb,        /* [IN/OUT] incoming packet */
      pointer        dummy       /* [IN]     not used        */
   )
{ /* Body */
   IGMP_HEADER_PTR      header;
   IGMP_CFG_STRUCT_PTR  IGMP_cfg_ptr;

   IGMP_cfg_ptr = RTCS_getcfg(IGMP);
   IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.COMMON.ST_RX_TOTAL++);

   header = (IGMP_HEADER_PTR)RTCSPCB_DATA(pcb);

   /* check if length >= sizeof(IGMP_HEADER) */
   if (RTCSPCB_SIZE(pcb) < sizeof(IGMP_HEADER)) {
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.ST_RX_SMALL_DGRAM++);
      RTCSLOG_PCB_FREE(pcb, RTCSERR_IGMP_BAD_HEADER);
      RTCSPCB_free(pcb);
      return;
   } /* Endif */

   /* Verify the checksum */
   if (IP_Sum_PCB(0, pcb) != 0xFFFF) {
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.ST_RX_BAD_CHECKSUM++);
      RTCSLOG_PCB_FREE(pcb, RTCSERR_IGMP_BAD_CHECKSUM);
      RTCSPCB_free(pcb);
      return;
   } /* Endif */

   if (ntohc(header->TYPE) == IGMPTYPE_V2_REPORT) {
      RTCSLOG_PCB_READ(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_IGMP), 2);
   } else {
      RTCSLOG_PCB_READ(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_IGMP), 1);
   } /* Endif */

   switch (ntohc(header->TYPE)) {
   case IGMPTYPE_QUERY:
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.ST_RX_QUERY++);
      IGMP_rcv_query(pcb->IFSRC, ntohl(header->GROUP_ADDRESS), ntohc(header->MAX_RESP_TIME));
      break;
   case IGMPTYPE_V1_REPORT:
   case IGMPTYPE_V2_REPORT:
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.ST_RX_REPORT++);
      IGMP_rcv_report(pcb->IFSRC, ntohl(header->GROUP_ADDRESS));
      break;
   default:
      IF_IGMP_STATS_ENABLED(IGMP_cfg_ptr->STATS.ST_RX_BAD_TYPE++);
   } /* Endswitch */

   RTCSLOG_PCB_FREE(pcb, RTCS_OK);
   RTCSPCB_free(pcb);

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_time.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_time.c$
* $Version : 3.6.8.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the file specific interface functions
*   of the MFS.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Get_date_time
* Returned Value   : error_code (MFS_NO_ERROR or MFS_INVALID_FILE_HANDLE)
* Comments  :   Get the date and time of last update of a specific file.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Get_date_time
    (
    MQX_FILE_PTR            fd_ptr,     /*[IN] get date/time of this file */
    uint_16_ptr             date_ptr,   /*[IN/OUT] file date is written to this address */
    uint_16_ptr             time_ptr    /*[IN/OUT] file time is written to this address */
    )
{
   
   MFS_DRIVE_STRUCT_PTR    drive_ptr;
   MFS_HANDLE_PTR          handle;
   _mfs_error              error_code;
   MFS_DIR_ENTRY_PTR       dir_entry_ptr;
   
   error_code = MFS_lock_handle( fd_ptr, &drive_ptr, &handle );
   if ( error_code != MFS_NO_ERROR )
   {
      return error_code;
   }
   
   dir_entry_ptr = ((MFS_DIR_ENTRY_PTR) drive_ptr->DIR_SECTOR_PTR) + INDEX_TO_OFFSET(handle->DIR_INDEX);
   /*
   ** Check the date and time ptrs; if any is NULL, don't write to it.
   */
   if ( date_ptr )
   {
      *date_ptr = dtohs(dir_entry_ptr->DATE);
   }
   if ( time_ptr )
   {
      *time_ptr = dtohs(dir_entry_ptr->TIME);
   }
   
   MFS_unlock(drive_ptr,FALSE);
   
   return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Set_date_time
* Returned Value   : error_code
* Comments  :   Set the date and time of last update of a specific file.
*
*END*---------------------------------------------------------------------*/
#if !MFSCFG_READ_ONLY

_mfs_error MFS_Set_date_time
   (
   MQX_FILE_PTR            fd_ptr,     /*[IN] get date/time of this file */
   uint_16_ptr             date_ptr,   /*[IN] file date to be written into this file's entry */
   uint_16_ptr             time_ptr    /*[IN] file time to be written into this file's entry */
   )
{
   MFS_DRIVE_STRUCT_PTR    drive_ptr;
   MFS_HANDLE_PTR          handle;
   _mfs_error              error_code;
   
#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif   
   
   error_code = MFS_lock_handle( fd_ptr, &drive_ptr, &handle );
   if ( error_code != MFS_NO_ERROR )
   {
      return error_code;
   }

   if ( handle->ACCESS == MFS_ACCESS_READ_ONLY )
   {
      MFS_unlock(drive_ptr,FALSE);
      return MFS_ACCESS_DENIED;
   }
   
   htods(handle->DIR_ENTRY.DATE, *date_ptr);
   htods(handle->DIR_ENTRY.TIME, *time_ptr);

   error_code = MFS_Update_entry(drive_ptr, handle);
   /* we do not want to set date and time in close, so set touched to 0 */
   if ( error_code == MFS_NO_ERROR )
   {
      handle->TOUCHED = 0;
   }
   MFS_unlock(drive_ptr,TRUE);
   
   return(error_code);
}  

#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/msg_prv.h<|end_filename|>
/*HEADER**********************************************************************
 *
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *****************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************
 *
 * $FileName: msg_prv.h$
 * $Version : 3.8.7.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *   This file contains private information for the message component
 *
 *END************************************************************************/
#ifndef __msg_prv_h__
#define __msg_prv_h__

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */
/* Timeout modes */
#define MSG_TIMEOUT_NONE                0
#define MSG_TIMEOUT_ABSOLUTE            1
#define MSG_TIMEOUT_RELATIVE            2

/* Used to mark a message as belonging to the message pool */
#define MSG_VALID                       (0x6D67)  /* "mg" */

/* Message pool types */
#define MSG_POOL                        (5)
#define SYSTEM_MSG_POOL                 (10)

/* What bits control the priority/urgency of the message */
#define MSG_PRIORITY_MASK               (0x1F)

/* Values used when building a QUEUE ID */
#define MSG32_PROC_MASK                 (0xffff)
#define MSG32_PROC_SHIFT                (16)
#define MSG32_QUEUE_MASK                (0xffff)
#define MSG32_MAX_PROCESSORS            (0x10000)
#define MSG32_MAX_QNUMBERS              (0x10000)

#define MSG16_PROC_MASK                 (0xff)
#define MSG16_PROC_SHIFT                (8)
#define MSG16_QUEUE_MASK                (0xff)
#define MSG16_MAX_PROCESSORS            (256)
#define MSG16_MAX_QNUMBERS              (256)

#if MQX_USE_32BIT_MESSAGE_QIDS
#define PROC_MASK                       MSG32_PROC_MASK
#define PROC_SHIFT                      MSG32_PROC_SHIFT
#define QUEUE_MASK                      MSG32_QUEUE_MASK
#define MAX_PROCESSORS                  MSG32_MAX_PROCESSORS
#define MAX_QNUMBERS                    MSG32_MAX_QNUMBERS
#else
#define PROC_MASK                       MSG16_PROC_MASK
#define PROC_SHIFT                      MSG16_PROC_SHIFT
#define QUEUE_MASK                      MSG16_QUEUE_MASK
#define MAX_PROCESSORS                  MSG16_MAX_PROCESSORS
#define MAX_QNUMBERS                    MSG16_MAX_QNUMBERS
#endif /* MQX_USE_32BIT_MESSAGE_QIDS */

/* the message queue is owned by a task */
#define MSG_QUEUE                       (1)

/* the message queue belongs to the system, not owned by a task. */
#define SYSTEM_MSG_QUEUE                (2)

/* How to build a Queue ID from the processor number and queue number */
#define BUILD_QID(processor_number,queue) \
    (_queue_id)((((processor_number) & PROC_MASK) << PROC_SHIFT) | \
    ((queue) & QUEUE_MASK))

/* Extract the processor number from a queue id */
#define PROC_NUMBER_FROM_QID(qid) \
    ((qid) >> PROC_SHIFT)

/* Extract the queue number from a queue id */
#define QUEUE_FROM_QID(qid) \
    ((qid) & QUEUE_MASK)

/* Is this a valid queue number */
#define  VALID_QUEUE(qnum) \
    ((qnum) > 0)

/*
 * QUEUE MACROS
 */
/*
 * Given a message pointer from an application program, locate where
 * the address of the internal message structure begins.
 */
#define  GET_INTERNAL_MESSAGE_PTR(msg_ptr) \
    (INTERNAL_MESSAGE_STRUCT_PTR)(((uchar _PTR_)(msg_ptr)) - \
    FIELD_OFFSET(INTERNAL_MESSAGE_STRUCT,MESSAGE))

/* Return the address of the message component structure */
#define  _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data) \
    ((MSG_COMPONENT_STRUCT_PTR)(kernel_data->KERNEL_COMPONENTS[KERNEL_MESSAGES]))

/*--------------------------------------------------------------------------*/
/*                        DATATYPE DEFINITIONS
 *
 */

/*-------------------------------------------------------------------------*/
/* MSGPOOL BLOCK STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief This structure is prepended to the beginning of each block of messages 
 * when they are allocated.
 *  
 * When the message pool grows, a new block of messages is created and is linked 
 * to the previous block of messages.
 */
typedef struct msgpool_block_struct
{
    /*! \brief The address of the next block of messages in this pool. */
    struct msgpool_block_struct _PTR_ NEXT_BLOCK_PTR;

    /*!
     * \brief The 'RAW' size of the messages in this block.
     *      
     * The message may be larger than requested in order to allow for memory 
     * alignment constraints.  Also this size includes the internal header for 
     * the message.
     */
    _mqx_uint RAW_MESSAGE_SIZE;

    /*! \brief The number of messages in this block. */
    _mqx_uint NUM_MESSAGES;

    /*! \brief The address of the first internal message in the pool. */
    pointer FIRST_IMSG_PTR;

}MSGPOOL_BLOCK_STRUCT, _PTR_ MSGPOOL_BLOCK_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/* MSGPOOL STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief This structure defines what a message pool looks like.
 *
 * The message pools are linked together via the NEXT_MSGPOOL_PTR field. The 
 * pools are sorted in size, with the smaller pools first.
 * \n The actual messages are allocated in blocks, and linked to the msgpool 
 * structure via the MSGPOOL_BLOCK_PTR.
 */
typedef struct msgpool_struct
{
    /*! \brief Pointer to the list of blocks of messages. */
    struct msgpool_block_struct _PTR_ MSGPOOL_BLOCK_PTR;

    /*! \brief Link to the next message pool, of larger size. */
    struct msgpool_struct _PTR_ NEXT_MSGPOOL_PTR;

    /*! \brief Current number of messages on the free list. */
    uint_16 SIZE;

    /*! \brief Maximum number of messages on the free list. */
    uint_16 MAX;

    /*! \brief Pointer to a list of FREE messages. */
    struct internal_message_struct _PTR_ MSG_FREE_LIST_PTR;

    /*!
     * \brief Size of the user message in bytes, as requested when the pool was 
     * allocated.
     */
    uint_16 MESSAGE_SIZE;

    /*! \brief Should the pool grow if empty. */
    uint_16 GROW_NUMBER;

    /*! \brief Validation stamp for message pools. */
    uint_16 VALID;

    /*! \brief The maximum number of messages allowed to be in the pool. */
    uint_16 GROW_LIMIT;

    /*! \brief The type of the message pool MSG_POOL or SYSTEM_MSG_POOL. */
    _mqx_uint MSGPOOL_TYPE;

}MSGPOOL_STRUCT, _PTR_ MSGPOOL_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/* INTERNAL MESSAGE STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure is the internal representation of a message.
 *
 * When a message is provided to an application task from the message pool, the 
 * application is provided with the address of the MESSAGE_HEADER_STRUCT found 
 * at the end of this structure.
 */
typedef struct internal_message_struct
{
    /*! 
     * \brief Link to the next message in the list. NEXT is used to link the 
     * message onto a free list.
     */     
    struct internal_message_struct _PTR_ NEXT;
    
    /*! \brief Link to previous message in the list. */ 
    struct internal_message_struct _PTR_ PREV;

    /*! \brief Validation stamp. */
    uint_16 VALID;

    /*! \brief Is this a free message. */
    uchar FREE;

    /*! \brief Is this a queued message. */
    uchar QUEUED;

    /*! \brief Address of the msgpool that this message is from. */
    MSGPOOL_STRUCT_PTR MSGPOOL_PTR;

    /*! \brief What task owns this message. */
    TD_STRUCT_PTR TD_PTR;

    /*! \brief The actual message whose address is given to the application. */
    MESSAGE_HEADER_STRUCT MESSAGE;

}INTERNAL_MESSAGE_STRUCT, _PTR_ INTERNAL_MESSAGE_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/* MSGQ STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This is the structure used to define a message queue.
 */
typedef struct msgq_struct
{
    /*! \brief The first message on the message queue. */
    INTERNAL_MESSAGE_STRUCT_PTR FIRST_MSG_PTR;

    /*! \brief The last message on the message queue. */
    INTERNAL_MESSAGE_STRUCT_PTR LAST_MSG_PTR;

    /*! \brief The current number of messages on the queue. */
    uint_16 NO_OF_ENTRIES;

    /*! \brief The maximum number of messages that can be placed on this queue. */
    uint_16 MAX_ENTRIES;

    /*! \brief Owner task (task which OPENED) the queue. */
    TD_STRUCT_PTR TD_PTR;

    /*! \brief Link to next message queue owned by the task. */
    struct msgq_struct _PTR_ NEXT_MSGQ_PTR;

    /*! \brief The queue number of this message queue. */
    uint_16 QUEUE;

    /*! \brief The type of this queue: MSG_QUEUE or SYSTEM_MSG_QUEUE. */
    uint_16 TYPE;

    /*!
     * \brief A function can be called asynchronously when a message is put onto
     * the message queue. This is called the notification function.
     */
    MSGQ_NOTIFICATION_FPTR NOTIFICATION_FUNCTION;
    /*! \brief Parameter passed to the notification function. */
    pointer NOTIFICATION_FUNCTION_PARAMETER;

}MSGQ_STRUCT, _PTR_ MSGQ_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/* MSG COMPONENT STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This is the base structure used by the message component to store all
 * component specific information.
 *  
 * It currently overlays the MSGQ_RESERVED fields of the kernel data structure.
 */
typedef struct msg_component_struct
{
    /*! The maximum number of message pools allowed in the system. */
    _mqx_uint MAX_MSGPOOLS;

    /*!
     * \brief The address of an array of msgpool structures allocated at 
     * component creation time. There is MAX_MSGPOOLS number of these structures 
     * in the array.
     */
    MSGPOOL_STRUCT_PTR MSGPOOLS_PTR;

    /*! 
     * \brief Pointer to smallest message pool. The message pools with smallest
     * messages are found first. 
     */ 
    MSGPOOL_STRUCT_PTR SMALLEST_MSGPOOL_PTR;
    /*! \brief Pointer to largest message pool. */
    MSGPOOL_STRUCT_PTR LARGEST_MSGPOOL_PTR;

    /*! \brief The maximum number of message pools created at any one time. */
    _mqx_uint MAX_MSGPOOLS_EVER;

    /*! \brief The maximum number of message queues allowed. */
    _mqx_uint MAX_MSGQS;

    /*!
     * \brief The address of an array of message queue structures allocated at 
     * component creation time. There are MAX_MSGQS number of these structures
     * in the array.
     */
    MSGQ_STRUCT_PTR MSGQS_PTR;

    /*! \brief A validation stamp for messages. */
    _mqx_uint VALID;

}MSG_COMPONENT_STRUCT, _PTR_ MSG_COMPONENT_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__

    extern void _msg_cleanup
    (
        TD_STRUCT_PTR
    );

    extern void _msgq_insert_message_internal
    (
        MSGQ_STRUCT_PTR,
        INTERNAL_MESSAGE_STRUCT_PTR,
        boolean
    );

    extern _queue_id _msgq_open_internal
    (
        _queue_number,
        uint_16,
        _mqx_uint,
        MSGQ_NOTIFICATION_FPTR,
        pointer
    );

    extern MESSAGE_HEADER_STRUCT_PTR _msgq_receive_internal
    (
        _queue_id,
        MQX_TICK_STRUCT_PTR,
        _mqx_uint,
        _mqx_uint_ptr
    );

    extern void _msgq_release_internal
    (
        uint_16
    );

    extern boolean _msgq_send_blocked_internal
    (
        pointer
    );

    extern boolean _msgq_send_internal
    (
        MESSAGE_HEADER_STRUCT_PTR,
        boolean,
        _queue_id
    );

    extern void _msgpool_add_internal
    (
        MSGPOOL_STRUCT_PTR,
        uint_16
    );

    extern _pool_id _msgpool_create_internal
    (
        uint_16,
        uint_16,
        uint_16,
        uint_16,
        _mqx_uint
    );

#endif /* __TAD_COMPILE__ */

#ifdef __cplusplus
}
#endif

#endif /* __msg_prv_h__ */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ftp.h<|end_filename|>
#ifndef __ftp_h__
#define __ftp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftp.h$
* $Version : 3.6.4.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the FTP server definitions.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

#define IMAGE_TYPE 0
#define ASCII_TYPE 1

/* Size configuration */
#define LINELEN      128   /* Length of command buffer */
#define BUF_SIZE     1460

/* Command table commands */
#define USER_CMD     0
#define ACCT_CMD     1
#define PASS_CMD     2
#define TYPE_CMD     3
#define NAME_CMD     4
#define QUIT_CMD     5
#define PORT_CMD     6
#define RETR_CMD     7
#define STOR_CMD     8
#define HELP_CMD     9
#define ABORT_CMD    10

/* Start CR 1415 */
#define CWD_CMD     0 
#define CDUP_CMD    1
#define LIST_CMD    2 
#define DELE_CMD    3
#define MKD_CMD     4
#define XMKD_CMD    5
#define PWD_CMD     6   
#define XPWD_CMD    7
#define RMD_CMD     8
#define XRMD_CMD    9
/* End CR 1415 */

/***************************************
**
** Prototypes
**
*/

extern void    FTPSRV_process_connection( uint_32, uint_32 );
extern boolean FTPSRV_r_ftp( uint_32 );
extern boolean FTPSRV_docommand( uint_32, char _PTR_);

extern boolean FTPSRV_r_ftpd(uint_32);
extern boolean FTPSRV_s_ftpd(uint_32);
extern int_32  FTPSRV_pport(sockaddr_in _PTR_, char _PTR_);
extern void    FTPSRV_print_help(uint_32);
extern void    FTPSRV_tputs( uint_32, char _PTR_);
/* Start CR 1415, 1802, 2137 */
extern void    FTPSRV_openDataConnection(uint_32, char _PTR_);
/* End CR 1415, 1802, 2137 */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ifdhcp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifdhcp.c$
* $Version : 3.8.8.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the interface functions for the
*   DHCP client.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "dhcp_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_bind_DHCP
* Returned Values : uint_32 (error code)
* Comments        :
*     Initialize a hardware interface using DHCP.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_bind_DHCP
   (
      _rtcs_if_handle         handle,
         /* [IN] the RTCS interface state structure */
      DHCP_DATA_STRUCT_PTR    params,
         /* [IN] optional parameters */
      uchar_ptr               optptr,
         /* [IN] the DHCP options the application wishes to use */
      uint_32                 optlen
         /* [IN] the size of the options buffer passed in */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   TCPIP_PARM_IF_DHCP         parms;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }
   
   parms.HANDLE        = handle;
   /* Start CR 1547 */
   parms.FLAGS         = DHCP_SEND_PROBE;
   /* End CR 1547 */
   parms.OPT_BUFF      = optptr;
   parms.OPT_BUFF_SIZE = optlen;
   parms.OPTIONS       = params;
   parms.TIMEOUT       = _RTCS_dhcp_term_timeout;

   /* We block the application until DHCP completes initialization. */
   return RTCSCMD_issue(parms, DHCPCLNT_init);

#else

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4 */   

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_rebind_DHCP
* Returned Values : uint_32 (error code)
* Comments        :
*     Initialize a hardware interface using DHCP.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_rebind_DHCP
   (
      _rtcs_if_handle         handle,
         /* [IN] the RTCS interface state structure */
      _ip_address             address,
         /* [IN] the IP address for the interface */
      _ip_address             netmask,
         /* [IN] the IP (sub)network mask for the interface */
      uint_32                 lease,
         /* [IN] the duration of the lease in seconds */
      _ip_address             server,
         /* [IN] the IP address of the DHCP server */
      DHCP_DATA_STRUCT_PTR    params,
         /* [IN] optional parameters */
      uchar_ptr               optptr,
         /* [IN] the DHCP options the application wishes to use */
      uint_32                 optlen
         /* [IN] the size of the options buffer passed in */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   TCPIP_PARM_IF_DHCP         parms;

   parms.HANDLE         = handle;
   parms.FLAGS         = 0;
   parms.OPT_BUFF       = optptr;
   parms.OPT_BUFF_SIZE  = optlen;
   parms.OPTIONS        = params;

   parms.CLNT_IP_ADDR   = address;
   parms.CLNT_IP_MASK   = netmask;
   parms.SERVER_IP_ADDR = server;
   parms.LEASE          = lease;
   /* Start CR 1066 */
   parms.TIMEOUT       = 0;
   /* End CR 1066 */

   /* We block the application until DHCP completes initialization. */
   return RTCSCMD_issue(parms, DHCPCLNT_reinit);

#else

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4 */     

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_request_DHCP_inform
* Returned Values : uint_32 (error code)
* Comments        :
*     Request the sending of a DHCP inform message.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_request_DHCP_inform
   (
      _rtcs_if_handle         handle,
         /* [IN] the RTCS interface state structure */
      uchar_ptr               optptr,
         /* [IN] the DHCP options the application wishes to use */
      uint_32                 optlen,
         /* [IN] the size of the options buffer passed in */
      _ip_address             client_addr,
        /* [IN] the IP address the application is bound to */
      _ip_address             server_addr,
        /* [IN] the IP address of the server we want parameters from */
      void (_CODE_PTR_ inform_func)(uchar _PTR_, uint_32, _rtcs_if_handle)
      /* The function to call when DHCP is finished */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   TCPIP_PARM_IF_DHCP parms;
   DHCP_DATA_STRUCT   options;

   options.BIND_FUNC    = inform_func;
   options.CHOICE_FUNC  = NULL;
   options.UNBIND_FUNC  = NULL;
   options.REBIND_FUNC  = NULL;

   parms.HANDLE         = handle;
   parms.FLAGS          = DHCP_SEND_INFORM_MESSAGE;
   parms.OPT_BUFF       = optptr;
   parms.OPT_BUFF_SIZE  = optlen;
   parms.OPTIONS        = &options;
   parms.CLNT_IP_ADDR   = client_addr;
   parms.SERVER_IP_ADDR = server_addr;

   /* We block the application until DHCP completes initialization. */
   return RTCSCMD_issue(parms, DHCPCLNT_init);

#else

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4 */  
   
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_bind_DHCP_timed
* Returned Values : uint_32 (error code)
* Comments        :
*     Initialize a hardware interface using DHCP.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_bind_DHCP_timed
   (
      _rtcs_if_handle         handle,
         /* [IN] the RTCS interface state structure */
      DHCP_DATA_STRUCT_PTR    params,
         /* [IN] optional parameters */
      uchar_ptr               optptr,
         /* [IN] the DHCP options the application wishes to use */
      uint_32                 optlen,
         /* [IN] the size of the options buffer passed in */
      uint_32                 timeout
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   TCPIP_PARM_IF_DHCP         parms;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }
   

   parms.HANDLE        = handle;
   /* Start CR 1547 */
   parms.FLAGS         = DHCP_SEND_PROBE;
   /* End CR 1547 */
   parms.OPT_BUFF      = optptr;
   parms.OPT_BUFF_SIZE = optlen;
   parms.OPTIONS       = params;
   parms.TIMEOUT       = timeout;

   /* We block the application until DHCP completes initialization. */
   return RTCSCMD_issue(parms, DHCPCLNT_init);

#else

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4 */     

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_bind_DHCP_flagged
* Returned Values : uint_32 (error code)
* Comments        :
*     Initialize a hardware interface using DHCP.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_bind_DHCP_flagged
   (
      _rtcs_if_handle         handle,
         /* [IN] the RTCS interface state structure */
      DHCP_DATA_STRUCT_PTR    params,
         /* [IN] optional parameters */
      uchar_ptr               optptr,
         /* [IN] the DHCP options the application wishes to use */
      uint_32                 optlen
         /* [IN] the size of the options buffer passed in */
   )
{ /* Body */

#if RTCSCFG_ENABLE_IP4 

   TCPIP_PARM_IF_DHCP         parms;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }
   

   parms.HANDLE        = handle;
   parms.FLAGS         = params->FLAGS;
   parms.OPT_BUFF      = optptr;
   parms.OPT_BUFF_SIZE = optlen;
   parms.OPTIONS       = params;
   parms.TIMEOUT       = 0;

   /* We block the application until DHCP completes initialization. */
   return RTCSCMD_issue(parms, DHCPCLNT_init);


#else

    return RTCSERR_IP_IS_DISABLED;

#endif /* RTCSCFG_ENABLE_IP4 */ 
   

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DHCPCLNT_release
* Returned Values : void
* Comments        :
*
*END*-----------------------------------------------------------------*/

void DHCPCLNT_release
   (
      _rtcs_if_handle    ihandle
         /* [IN] The pointer to the interface we no longer need */
   )
{  /* Body */

#if RTCSCFG_ENABLE_IP4 

   TCPIP_PARM_IF_DHCP_RELEASE dhcp_parms;

   dhcp_parms.HANDLE = ihandle;

   RTCSCMD_issue(dhcp_parms, DHCPCLNT_release_internal);

#endif /* RTCSCFG_ENABLE_IP4 */ 
   
   
}  /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/khci/callback_khci.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: callback_khci.c$
* $Version : 3.8.2.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "dev_cnfg.h"
#include "devapi.h"
#include "dev_main.h"
#include "mqx_dev.h"

#include "khci_dev_main.h"
#include "khci_usbprv.h"

const USB_DEV_CALLBACK_FUNCTIONS_STRUCT _usb_khci_dev_callback_table =
{
    _usb_dci_usbfs_preinit,
    _usb_dci_usbfs_init,
    _usb_dci_usbfs_send,
    _usb_dci_usbfs_recv,
    _usb_dci_usbfs_cancel,
    _usb_dci_usbfs_init_endpoint,
    _usb_dci_usbfs_deinit_endpoint,
    _usb_dci_usbfs_unstall_endpoint,
    _usb_dci_usbfs_get_endpoint_status,
    _usb_dci_usbfs_set_endpoint_status,
    _usb_dci_usbfs_get_transfer_status,
    _usb_dci_usbfs_set_addr,
    _usb_dci_usbfs_shutdown,
    _usb_dci_usbfs_get_setup_data,
    _usb_dci_usbfs_assert_resume,
    _usb_dci_usbfs_stall_endpoint
};


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_rename.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_rename.c$
* $Version : 3.8.12.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_prv.h>

#if SHELLCFG_USES_MFS

static int_32 Shell_mfs_rename(MQX_FILE_PTR fs_ptr,char_ptr old_ptr, char_ptr new_ptr)
{
   MFS_RENAME_PARAM           rename_struct;
   
   rename_struct.OLD_PATHNAME = old_ptr;
   rename_struct.NEW_PATHNAME = new_ptr;

   return ioctl(fs_ptr, IO_IOCTL_RENAME_FILE, (pointer) &rename_struct);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  Shell_rename
* Returned Value   :  uint_32 error code
* Comments  :  Renames or moves a file.
*
*END*---------------------------------------------------------------------*/

int_32  Shell_rename(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean                    print_usage, temp, shorthelp = FALSE;
   int_32                     error = 0, return_code = SHELL_EXIT_SUCCESS;
   MQX_FILE_PTR               fs_ptr;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   char_ptr              abs_path_old = NULL;
   char_ptr              abs_path_new = NULL;


   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc != 3)  {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else  {
         if (MFS_alloc_2paths(&abs_path_old,&abs_path_new) != MFS_NO_ERROR) {
            printf("Error, unable to allocate memory for paths\n" );
            return_code = SHELL_EXIT_ERROR;
         }
         else
         {
            _io_get_dev_for_path(abs_path_old,&temp,PATHNAME_SIZE,(char *)argv[1],Shell_get_current_filesystem_name(shell_ptr));
            _io_get_dev_for_path(abs_path_new,&temp,PATHNAME_SIZE,(char *)argv[2],Shell_get_current_filesystem_name(shell_ptr));            
            if (strcmp(abs_path_new,abs_path_old))
            {
               printf("Error, rename is possible only within one device\n" );
               return_code = SHELL_EXIT_ERROR;
            } else {
            fs_ptr = _io_get_fs_by_name(abs_path_new);
               if (fs_ptr == NULL)  {
                  printf("Error, file system not mounted\n" );
                  return_code = SHELL_EXIT_ERROR;
               } else {
                  error = _io_rel2abs(abs_path_old,shell_ptr->CURRENT_DIR,(char *) argv[1],PATHNAME_SIZE,Shell_get_current_filesystem_name(shell_ptr));
                  if(!error)
                  {
                     error = _io_rel2abs(abs_path_new,shell_ptr->CURRENT_DIR,(char *) argv[2],PATHNAME_SIZE,Shell_get_current_filesystem_name(shell_ptr));
                     if(!error)
                     {
                        error = Shell_mfs_rename(fs_ptr, abs_path_old, abs_path_new );
                     }
                  }
                  if (error)  {
                     printf("Error renaming file %s\n", argv[1]);
                  }
               }
            }
         }
      }
   }
   
   MFS_free_path(abs_path_old);
   MFS_free_path(abs_path_new);
      
      
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <oldname> <newname> \n", argv[0]);
      } else  {
         printf("Usage: %s <oldname> <newname>\n", argv[0]);
         printf("   <oldname> = name of file to change\n");
         printf("   <newname> = new name of file\n");
      }
   }
   return return_code;
} /* Endbody */

#endif //SHELLCFG_USES_MFS
/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/event.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: event.h$
* $Version : 3.0.5.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   event component.
*
*END************************************************************************/
#ifndef __event_h__
#define __event_h__ 1

#include <mqx_cnfg.h>
#if (! MQX_USE_EVENTS) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error EVENT component is currently disabled in MQX kernel. Please set MQX_USE_EVENTS to 1 in user_config.h and recompile kernel.
#endif

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* ERROR messages */

#define EVENT_MULTI_PROCESSOR_NOT_AVAILABLE     (EVENT_ERROR_BASE|0x00)
#define EVENT_DELETED                           (EVENT_ERROR_BASE|0x01)
#define EVENT_NOT_DELETED                       (EVENT_ERROR_BASE|0x02)
#define EVENT_INVALID_EVENT_HANDLE              (EVENT_ERROR_BASE|0x03)
#define EVENT_CANNOT_SET                        (EVENT_ERROR_BASE|0x04)
#define EVENT_CANNOT_GET_EVENT                  (EVENT_ERROR_BASE|0x05)
#define EVENT_INVALID_EVENT_COUNT               (EVENT_ERROR_BASE|0x06)
#define EVENT_WAIT_TIMEOUT                      (EVENT_ERROR_BASE|0x07)
#define EVENT_EXISTS                            (EVENT_ERROR_BASE|0x08)
#define EVENT_TABLE_FULL                        (EVENT_ERROR_BASE|0x09)
#define EVENT_NOT_FOUND                         (EVENT_ERROR_BASE|0x0A)
#define EVENT_INVALID_EVENT                     (EVENT_ERROR_BASE|0x0B)
#define EVENT_CANNOT_WAIT_ON_REMOTE_EVENT       (EVENT_ERROR_BASE|0x0C)

/* Default component creation parameters */
#define EVENT_DEFAULT_INITIAL_NUMBER            (8)
#define EVENT_DEFAULT_GROW_NUMBER               (8)
#define EVENT_DEFAULT_MAXIMUM_NUMBER            (0) /* Unlimited */

/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern _mqx_uint _event_clear(pointer, _mqx_uint);
extern _mqx_uint _event_close(pointer);
extern _mqx_uint _event_create_component(_mqx_uint, _mqx_uint, _mqx_uint);
extern _mqx_uint _event_create_fast(_mqx_uint);
extern _mqx_uint _event_create_fast_auto_clear(_mqx_uint);
extern _mqx_uint _event_create(char _PTR_);
extern _mqx_uint _event_create_auto_clear(char _PTR_);
extern _mqx_uint _event_destroy(char _PTR_);
extern _mqx_uint _event_destroy_fast(_mqx_uint);
extern _mqx_uint _event_get_value(pointer, _mqx_uint_ptr);
extern _mqx_uint _event_get_wait_count(pointer);
extern _mqx_uint _event_open(char _PTR_, pointer _PTR_);
extern _mqx_uint _event_open_fast(_mqx_uint, pointer _PTR_);
extern _mqx_uint _event_set(pointer, _mqx_uint);
extern _mqx_uint _event_test(pointer _PTR_);
extern _mqx_uint _event_wait_all(pointer, _mqx_uint, uint_32);
extern _mqx_uint _event_wait_all_for(pointer, _mqx_uint, MQX_TICK_STRUCT_PTR);
extern _mqx_uint _event_wait_all_ticks(pointer, _mqx_uint, _mqx_uint);
extern _mqx_uint _event_wait_all_until(pointer, _mqx_uint, MQX_TICK_STRUCT_PTR);
extern _mqx_uint _event_wait_any(pointer, _mqx_uint, uint_32);
extern _mqx_uint _event_wait_any_for(pointer, _mqx_uint, MQX_TICK_STRUCT_PTR);
extern _mqx_uint _event_wait_any_ticks(pointer, _mqx_uint, _mqx_uint);
extern _mqx_uint _event_wait_any_until(pointer, _mqx_uint, MQX_TICK_STRUCT_PTR);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_eds.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_eds.c$
* $Version : 3.7.4.0$
* $Date    : Feb-24-2011$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h" 

#define SHELL_EDS_PRIO        7
#define SHELL_EDS_STACK       1500

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_EDS
*  Returned Value:  none
*  Comments  :  SHELL utility to TFTP to or from a host
*  Usage:  tftp host get source [destination] [mode] 
*
*END*-----------------------------------------------------------------*/

int_32  Shell_EDS(int_32 argc, char_ptr argv[] )
{
   uint_32  result;
   boolean  print_usage, shorthelp = FALSE;
   int_32   return_code = SHELL_EXIT_SUCCESS;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc == 2)  {
         if (strcmp(argv[1], "start") == 0)  {
         
            result = EDS_init("EDS", SHELL_EDS_PRIO, SHELL_EDS_STACK );
            if (result ==  0)  {
               printf("EDS Started.\n");
            } else  {
               printf("Unable to start EDS, error = 0x%x\n",result);
               return_code = SHELL_EXIT_ERROR;
            }
         } else if (strcmp(argv[1], "stop") == 0)  {
            result = EDS_stop();
            if (result ==  0)  {
               printf("EDS Stopped.\n");
            } else  {
               printf("Unable to stop EDS, error = 0x%x\n",result);
               return_code = SHELL_EXIT_ERROR;
            }
         } else  {
         printf("Error, %s invoked with incorrect option\n", argv[0]);
            print_usage = TRUE;
         }
      } else  {
         printf("Error, %s invoked with incorrect number of arguments\n", argv[0]);
         print_usage = TRUE;
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s [start|stop]\n", argv[0]);
      } else  {
         printf("Usage: %s [start|stop]\n",argv[0]);
      }
   }
   return return_code;
} /* Endbody */

#endif /* SHELLCFG_USES_RTCS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/rtcssh.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcssh.c$
* $Version : 3.6.9.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <rtcs.h>
#include <serial.h>
#include <fio.h>


/*TASK*-----------------------------------------------------------------
*
* Function Name    : RTCS_netstat_task
* Returned Value   : none
* Comments  :  Start the RTCS shell
*
*END*-----------------------------------------------------------------*/

void RTCS_netstat_task
   (
      uint_32 console
   )
{ /* Body */
   MQX_FILE_PTR console_fd;

   if ((char_ptr)console != NULL) {
      console_fd = fopen((char_ptr)console, (char_ptr)(IO_SERIAL_XON_XOFF | IO_SERIAL_TRANSLATION | IO_SERIAL_ECHO));
      if (console_fd == NULL) {
         return;
      } /* Endif */
      _io_set_handle(IO_STDIN,  console_fd);
      _io_set_handle(IO_STDOUT, console_fd);
   } /* Endif */

   RTCS_shell();

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  RTCS_shell
*  Returned Value:  none
*  Comments  :  The RTCS shell
*
*END*-----------------------------------------------------------------*/

void RTCS_shell
   (
      void
   )
{ /* Body */
   char                 string[64];
   char_ptr             arg0, arg1, arg2;

#if RTCSCFG_ENABLE_DNS   
   HOSTENT_STRUCT_PTR   host_ptr;
   _ip_address          hostaddr;
   char                 addrstr[16];
   uint_16              pingid = 0; 
   int_32               error;  
   uint_32              i, time;   
#endif   
#if RTCSCFG_ENABLE_IP_STATS
   IP_STATS_PTR         ip   = IP_stats();
#endif
#if RTCSCFG_ENABLE_ICMP_STATS
   ICMP_STATS_PTR       icmp = ICMP_stats();
#endif
#if RTCSCFG_ENABLE_UDP_STATS
   UDP_STATS_PTR        udp  = UDP_stats();
#endif
#if RTCSCFG_ENABLE_TCP_STATS
   TCP_STATS_PTR        tcp  = TCP_stats();
#endif

   printf("\nRTCS v%d.%02d.%02d shell\n",
          RTCS_VERSION_MAJOR, RTCS_VERSION_MINOR, RTCS_VERSION_REV);

   while (TRUE) {

      printf("RTCS> ");

      if (!fgets(string, sizeof(string), stdin)) {
         break;
      } /* Endif */

      arg0 = string;
      while (*arg0 && !isgraph(*arg0)) arg0++;
      if (!*arg0) continue;

      arg1 = arg0;
      while (isgraph(*arg1)) arg1++;
      if (*arg1) *arg1++ = '\0';
      while (*arg1 && !isgraph(*arg1)) arg1++;

      if (!*arg1) {
         arg1 = NULL;
      } else {
         arg2 = arg1;
         while (isgraph(*arg2)) arg2++;
         *arg2 = '\0';
      } /* Endif */

      if (strcmp(arg0, "netstat") == 0) {

#if RTCSCFG_ENABLE_IP_STATS
       printf("\nIP:\n");
         printf("\t%ld packets received\n",                  ip->COMMON.ST_RX_TOTAL);
         printf("\t%ld packets delivered\n",                 ip->ST_RX_DELIVERED);
         printf("\t%ld packets forwarded\n",                 ip->ST_RX_FORWARDED);
         printf("\t%ld discarded for lack of resources\n",   ip->COMMON.ST_RX_MISSED);
         printf("\t%ld discarded due to internal errors\n",  ip->COMMON.ST_RX_ERRORS);
         printf("\t%ld discarded for other reasons:\n",      ip->COMMON.ST_RX_DISCARDED);
         printf("\t\t%ld with header errors\n",              ip->ST_RX_HDR_ERRORS);
         printf("\t\t%ld with an illegal destination\n",     ip->ST_RX_ADDR_ERRORS);
         printf("\t\t%ld with unknown protocols\n",          ip->ST_RX_NO_PROTO);
         printf("\t%ld fragments received\n",                ip->ST_RX_FRAG_RECVD);
         printf("\t%ld fragments reassembled\n",             ip->ST_RX_FRAG_REASMD);
         printf("\t%ld fragments discarded\n",               ip->ST_RX_FRAG_DISCARDED);
         printf("\t%ld packets sent\n",                      ip->COMMON.ST_TX_TOTAL);
         printf("\t%ld unsent for lack of resources\n",      ip->COMMON.ST_TX_MISSED);
         printf("\t%ld unsent due to internal errors\n",     ip->COMMON.ST_TX_ERRORS);
         printf("\t%ld destinations found unreachable\n",    ip->COMMON.ST_TX_DISCARDED);
         printf("\t%ld packets fragmented\n",                ip->ST_TX_FRAG_FRAGD);
         printf("\t%ld fragments sent\n",                    ip->ST_TX_FRAG_SENT);
         printf("\t%ld fragmentation failures\n",            ip->ST_TX_FRAG_DISCARDED);
         printf("-- More --"); getchar();
#endif

#if RTCSCFG_ENABLE_ICMP_STATS
         printf("\nICMP:\n");
         printf("\t%ld packets received\n",                  icmp->COMMON.ST_RX_TOTAL);
         printf("\t%ld discarded for lack of resources\n",   icmp->COMMON.ST_RX_MISSED);
         printf("\t%ld discarded due to internal errors\n",  icmp->COMMON.ST_RX_ERRORS);
         printf("\t%ld discarded for other reasons:\n",      icmp->COMMON.ST_RX_DISCARDED);
         printf("\t\t%ld with header errors\n",              icmp->ST_RX_BAD_CHECKSUM + icmp->ST_RX_SMALL_DGRAM);
         printf("\t\t%ld unrecognized codes\n",              icmp->ST_RX_BAD_CODE);
         printf("\t\t%ld redirects from non-gateways\n",     icmp->ST_RX_RD_NOTGATE);
         printf("\t%ld packets sent\n",                      icmp->COMMON.ST_TX_TOTAL);
         printf("\t%ld discarded for lack of resources\n",   icmp->COMMON.ST_TX_MISSED);
         printf("\t%ld discarded due to internal errors\n",  icmp->COMMON.ST_TX_ERRORS);
         printf("\t%ld with illegal type or code\n",         icmp->COMMON.ST_TX_DISCARDED);
         printf("\tInput histogram:\n");
         if (icmp->ST_RX_DESTUNREACH) printf("\t\t%ld Destination Unreachables\n", icmp->ST_RX_DESTUNREACH);
         if (icmp->ST_RX_TIMEEXCEED)  printf("\t\t%ld Time Exceededs\n",           icmp->ST_RX_TIMEEXCEED);
         if (icmp->ST_RX_PARMPROB)    printf("\t\t%ld Parameter Problems\n",       icmp->ST_RX_PARMPROB);
         if (icmp->ST_RX_SRCQUENCH)   printf("\t\t%ld Source Quenches\n",          icmp->ST_RX_SRCQUENCH);
         if (icmp->ST_RX_REDIRECT)    printf("\t\t%ld Redirects\n",                icmp->ST_RX_REDIRECT);
         if (icmp->ST_RX_ECHO_REQ)    printf("\t\t%ld Echo Requests\n",            icmp->ST_RX_ECHO_REQ);
         if (icmp->ST_RX_ECHO_REPLY)  printf("\t\t%ld Echo Replies\n",             icmp->ST_RX_ECHO_REPLY);
         if (icmp->ST_RX_TIME_REQ)    printf("\t\t%ld Timestamp Requests\n",       icmp->ST_RX_TIME_REQ);
         if (icmp->ST_RX_TIME_REPLY)  printf("\t\t%ld Timestamp Replies\n",        icmp->ST_RX_TIME_REPLY);
         if (icmp->ST_RX_INFO_REQ)    printf("\t\t%ld Information Requests\n",     icmp->ST_RX_INFO_REQ);
         if (icmp->ST_RX_INFO_REPLY)  printf("\t\t%ld Information Replies\n",      icmp->ST_RX_INFO_REPLY);
         if (icmp->ST_RX_OTHER)       printf("\t\t%ld Unknown\n",                  icmp->ST_RX_OTHER);
         printf("\tOutput histogram:\n");
         if (icmp->ST_TX_DESTUNREACH) printf("\t\t%ld Destination Unreachables\n", icmp->ST_TX_DESTUNREACH);
         if (icmp->ST_TX_TIMEEXCEED)  printf("\t\t%ld Time Exceededs\n",           icmp->ST_TX_TIMEEXCEED);
         if (icmp->ST_TX_PARMPROB)    printf("\t\t%ld Parameter Problems\n",       icmp->ST_TX_PARMPROB);
         if (icmp->ST_TX_SRCQUENCH)   printf("\t\t%ld Source Quenches\n",          icmp->ST_TX_SRCQUENCH);
         if (icmp->ST_TX_REDIRECT)    printf("\t\t%ld Redirects\n",                icmp->ST_TX_REDIRECT);
         if (icmp->ST_TX_ECHO_REQ)    printf("\t\t%ld Echo Requests\n",            icmp->ST_TX_ECHO_REQ);
         if (icmp->ST_TX_ECHO_REPLY)  printf("\t\t%ld Echo Replies\n",             icmp->ST_TX_ECHO_REPLY);
         if (icmp->ST_TX_TIME_REQ)    printf("\t\t%ld Timestamp Requests\n",       icmp->ST_TX_TIME_REQ);
         if (icmp->ST_TX_TIME_REPLY)  printf("\t\t%ld Timestamp Replies\n",        icmp->ST_TX_TIME_REPLY);
         if (icmp->ST_TX_INFO_REQ)    printf("\t\t%ld Information Requests\n",     icmp->ST_TX_INFO_REQ);
         if (icmp->ST_TX_INFO_REPLY)  printf("\t\t%ld Information Replies\n",      icmp->ST_TX_INFO_REPLY);
         if (icmp->ST_TX_OTHER)       printf("\t\t%ld Unknown\n",                  icmp->ST_TX_OTHER);
         printf("-- More --"); getchar();
#endif

#if RTCSCFG_ENABLE_UDP_STATS
         printf("\nUDP:\n");
         printf("\t%ld packets received\n",                  udp->COMMON.ST_RX_TOTAL);
         printf("\t%ld discarded for lack of resources\n",   udp->COMMON.ST_RX_MISSED);
         printf("\t%ld discarded due to internal errors\n",  udp->COMMON.ST_RX_ERRORS);
         printf("\t%ld discarded for other reasons:\n",      udp->COMMON.ST_RX_DISCARDED);
         printf("\t\t%ld with header errors\n",              udp->ST_RX_BAD_PORT + udp->ST_RX_BAD_CHECKSUM + udp->ST_RX_SMALL_DGRAM + udp->ST_RX_SMALL_PKT);
         printf("\t\t%ld with unknown ports\n",              udp->ST_RX_NO_PORT);
         printf("\t%ld packets sent\n",                      udp->COMMON.ST_TX_TOTAL);
         printf("\t%ld unsent for lack of resources\n",      udp->COMMON.ST_TX_MISSED);
         printf("\t%ld unsent due to internal errors\n",     udp->COMMON.ST_TX_ERRORS);
         printf("\t%ld with illegal destination port\n",     udp->COMMON.ST_TX_DISCARDED);
         printf("-- More --"); getchar();
#endif

#if RTCSCFG_ENABLE_TCP_STATS
         printf("\nTCP:\n");
         printf("\t%ld packets received\n",                  tcp->COMMON.ST_RX_TOTAL);
         printf("\t%ld discarded for lack of resources\n",   tcp->COMMON.ST_RX_MISSED);
         printf("\t%ld discarded due to internal errors\n",  tcp->COMMON.ST_RX_ERRORS);
         printf("\t%ld discarded for other reasons:\n",      tcp->COMMON.ST_RX_DISCARDED);
         printf("\t\t%ld with header errors\n",              tcp->ST_RX_BAD_PORT + tcp->ST_RX_BAD_CHECKSUM + tcp->ST_RX_SMALL_HDR + tcp->ST_RX_SMALL_DGRAM + tcp->ST_RX_SMALL_PKT);
         printf("\t\t%ld acks for unsent data\n",            tcp->ST_RX_BAD_ACK);
         printf("\t\t%ld with data outside window\n",        tcp->ST_RX_BAD_DATA);
         printf("\t\t%ld with data after close\n",           tcp->ST_RX_LATE_DATA);
         printf("\t%ld segments with data\n",                tcp->ST_RX_DATA);
         printf("\t%ld segments with duplicate data\n",      tcp->ST_RX_DATA_DUP);
         printf("\t%ld segments with only an ACK\n",         tcp->ST_RX_ACK);
         printf("\t%ld segments with a duplicate ACK\n",     tcp->ST_RX_ACK_DUP);
         printf("\t%ld segments with a RST\n",               tcp->ST_RX_RESET);
         printf("\t%ld window probes\n",                     tcp->ST_RX_PROBE);
         printf("\t%ld window updates\n",                    tcp->ST_RX_WINDOW);
         printf("-- More --"); getchar();
         printf("\t%ld packets sent\n",                      tcp->COMMON.ST_TX_TOTAL);
         printf("\t%ld discarded for lack of resources\n",   tcp->COMMON.ST_TX_MISSED);
         printf("\t%ld discarded due to internal errors\n",  tcp->COMMON.ST_TX_ERRORS);
         printf("\t%ld with illegal destination port\n",     tcp->COMMON.ST_TX_DISCARDED);
         printf("\t%ld segments with data\n",                tcp->ST_TX_DATA);
         printf("\t%ld segments with retransmitted data\n",  tcp->ST_TX_DATA_DUP);
         printf("\t%ld segments with only an ACK\n",         tcp->ST_TX_ACK);
         printf("\t%ld segments with a delayed ACK\n",       tcp->ST_TX_ACK_DELAYED);
         printf("\t%ld segments with a RST\n",               tcp->ST_TX_RESET);
         printf("\t%ld window probes\n",                     tcp->ST_TX_PROBE);
         printf("\t%ld window updates\n",                    tcp->ST_TX_WINDOW);
         printf("\t%ld active opens\n",                      tcp->ST_CONN_ACTIVE);
         printf("\t%ld passive opens\n",                     tcp->ST_CONN_PASSIVE);
         printf("\t%ld connections currently established\n", tcp->ST_CONN_OPEN);
         printf("\t%ld connections gracefully closed\n",     tcp->ST_CONN_CLOSED);
         printf("\t%ld connections aborted\n",               tcp->ST_CONN_RESET);
         printf("\t%ld failed connection attempts\n",        tcp->ST_CONN_FAILED);
#endif

#if RTCSCFG_ENABLE_DNS
      } else if (strcmp(arg0, "ping") == 0) {

         host_ptr = gethostbyname(arg1);
         if ((host_ptr == NULL)
          || (*host_ptr->h_addr_list == NULL)) {
            printf("Unable to resolve IP address for host: %s\n", arg1);
            if (host_ptr) DNS_free_HOSTENT_STRUCT(host_ptr);
            continue;
         } /* Endif */

         hostaddr = *(_ip_address _PTR_)*host_ptr->h_addr_list;

         sprintf(addrstr, "%ld.%ld.%ld.%ld", ((hostaddr>>24)&0xFF),
                                             ((hostaddr>>16)&0xFF),
                                             ((hostaddr>> 8)&0xFF),
                                             ( hostaddr     &0xFF));

         printf("Pinging %s [%s]:\n", host_ptr->h_name, addrstr);
         DNS_free_HOSTENT_STRUCT(host_ptr);

         for (i=0; i<4; i++) {
            time = 5000; /* 5 seconds */
            error = RTCS_ping(hostaddr, &time, ++pingid, 0, 0, 0);
            if (error == RTCSERR_ICMP_ECHO_TIMEOUT) {
               printf("Request timed out\n");
            } else if (error) {
               printf("Error 0x%04lX\n", error);
            } else {
               printf("Reply from %s: time=%ldms\n", addrstr, time);
               if ((time<1000) && (i<3)) {
                  RTCS_time_delay(1000-time);
               } /* Endif */
            } /* Endif */
         } /* Endfor */

      } else if (strcmp(arg0, "telnet") == 0) {

         host_ptr = gethostbyname(arg1);
         if ((host_ptr == NULL)
          || (*host_ptr->h_addr_list == NULL)) {
            printf("Unable to resolve IP address for host: %s\n", arg1);
            if (host_ptr) DNS_free_HOSTENT_STRUCT(host_ptr);
            continue;
         } /* Endif */

         hostaddr = *(_ip_address _PTR_)*host_ptr->h_addr_list;

         sprintf(addrstr, "%ld.%ld.%ld.%ld", ((hostaddr>>24)&0xFF),
                                             ((hostaddr>>16)&0xFF),
                                             ((hostaddr>> 8)&0xFF),
                                             ( hostaddr     &0xFF));

         printf("Trying %s [%s]:\n", host_ptr->h_name, addrstr);
         DNS_free_HOSTENT_STRUCT(host_ptr);

         error = TELNET_connect(hostaddr);
         if (error) {
            printf("Connection failed, error 0x%04lX\n", error);
         } /* Endif */
         printf("Connection closed\n", error);
#endif
      } else if (strcmp(arg0, "help") == 0) {

         printf("Available commands:\n");
         printf("\tnetstat       \tdisplay RTCS statistics\n");
         printf("\tping <host>   \tping a host\n");
         printf("\ttelnet <host> \ttelnet to a host\n");
         printf("\thelp          \tdisplay this message\n");
         printf("\texit          \texit the shell\n");

      } else if (strcmp(arg0, "exit") == 0) {

         break;

      } else {

         printf("Invalid command.  Type 'help' for a list of commands.\n");

      } /* Endif */

   } /* Endwhile */

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/mmu.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mmu.h$
* $Version : 3.8.7.0$
* $Date    : Oct-5-2011$
*
* Comments:
*
*   This file contains the type definitions for the generic MMU interface
*   functions.
*
*END************************************************************************/
#ifndef __mmu_h__
#define __mmu_h__

/* When a region is added to the mmu, the default is to make this region 
 * cachable, copyback, writeable, for both code and data accesses
 */

/* Write accesses to this page are not allowed. */
#define PSP_MMU_WRITE_PROTECTED         (0x00000001)

/* This page is NOT to be cached in the code cache */
#define PSP_MMU_CODE_CACHE_INHIBITED    (0x00000002)

/* This page is NOT to be cached in the data cache */
#define PSP_MMU_DATA_CACHE_INHIBITED    (0x00000004)

/* This page is NOT to be cached in the code or data cache */
#define PSP_MMU_CACHE_INHIBITED         (0x00000006)

/* Write accesses immediately propagate to physical memory. */
#define PSP_MMU_WRITE_THROUGH           (0x00000008)

/* On some MMUs, a write can be made without updating the cache. */
#define PSP_MMU_WRITE_NO_UPDATE         (0x00000020)

/* On some MMUs, a write can be stored into a write buffer, and 
 * stores to memory performed at some future time. 
 */
#define PSP_MMU_WRITE_BUFFERED          (0x00000040)

/* This page is shared with an external hardware device that can snoop. */
#define PSP_MMU_COHERENT                (0x00000080)

/* This page requires that memory accesses are not out-of-order, 
 * or that memory not specifically requested by the software be accessed. 
 */
#define PSP_MMU_GUARDED                 (0x00000100)

/* Read accesses to this page are not allowed. */
#define PSP_MMU_READ_PROTECTED          (0x00000200)

/* Page can contain executable instructions. */
#define PSP_MMU_EXEC_ALLOWED            (0x00000400)

/* Page is locked. Note: Cannot be used for a virtual context */
#define PSP_MMU_PAGE_LOCKED             (0x00000800)

/* Page contains VLE code */
#define PSP_MMU_PAGE_VLE             (0x00001000)

#ifndef __ASM__

/*--------------------------------------------------------------------------*/

/* PSP MMU VINIT STRUCT */
/*!
 * \brief This structure is used to initialize the virtual memory support.
 */
typedef struct psp_mmu_vinit_struct
{
   /*! \brief Where MMU pages can exist. */
   uchar_ptr MMU_PAGE_TABLE_BASE;

   /*! \brief How much memory allocated for the tables. */
   uint_32   MMU_PAGE_TABLE_SIZE;

   /*! \brief Where does unmapped memory start. */
   uchar_ptr UNMAPPED_MEMORY_BASE;

   /*! \brief How much memory available. */
   uint_32   UNMAPPED_MEMORY_SIZE;

} PSP_MMU_VINIT_STRUCT, _PTR_ PSP_MMU_VINIT_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
 *                  FUNCTION PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__

extern _mqx_uint _mmu_add_region(uchar_ptr, _mem_size, _mqx_uint);
extern void      _mmu_disable(void);
extern void      _mmu_enable(void);
extern void      _mmu_init(pointer);

extern _mqx_uint _mmu_add_vregion(pointer, pointer, _mem_size, _mqx_uint);
extern _mem_size _mmu_get_vpage_size(void);
extern _mqx_uint _mmu_get_vmem_attributes(pointer, pointer _PTR_,
   pointer _PTR_, _mem_size_ptr, _mqx_uint_ptr);
extern _mqx_uint _mmu_set_vmem_attributes(pointer, _mqx_uint, _mem_size);
extern _mqx_uint _mmu_vinit(_mqx_uint, pointer);
extern void      _mmu_venable(void);
extern void      _mmu_vdisable(void);
extern _mqx_uint _mmu_vtop(pointer, pointer _PTR_);

extern _mqx_uint _mmu_add_vcontext(_task_id, pointer, _mem_size, _mqx_uint);
extern _mqx_uint _mmu_create_vcontext(_task_id);
extern _task_id  _mmu_create_vtask(_mqx_uint, _mqx_uint, pointer, pointer, 
   _mem_size, _mqx_uint);
extern _mqx_uint _mmu_destroy_vcontext(_task_id);
#endif

#ifdef __cplusplus
}
#endif

#endif  /* __ASM__ */

#endif 
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/kadc/adc_mk40.c<|end_filename|>
/**HEADER***********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
********************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************
*
* $FileName: adc_mk40.c$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END***************************************************************************/

#include "mqx.h"
#include "bsp.h"

static const pointer adc_address[] = {
    (pointer)ADC0_BASE_PTR,
    (pointer)ADC1_BASE_PTR
};

/*FUNCTION**********************************************************************
*
* Function Name    : _bsp_get_adc_base_address
* Returned Value   : pointer to base of ADC registers
* Comments         :
*    This function returns base address of ADC related register space.
*
*END***************************************************************************/
pointer _bsp_get_adc_base_address(uint_32 device_number)
{
    /* Check if device number is correct */
    if (device_number < ELEMENTS_OF(adc_address)) {
        return (pointer)adc_address[device_number];
    }
    return NULL;
}


<|start_filename|>Firmware/Inverter_firmware/shell/source/shell/sh_help.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_help.c$
* $Version : 3.6.5.0$
* $Date    : Oct-26-2010$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include "shell.h"
#include "sh_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_help
*  Returned Value:  none
*  Comments  :  
*
*END*-----------------------------------------------------------------*/

int_32  Shell_help(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   SHELL_COMMAND_PTR    command_ptr; 

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc==1)  {
         shell_ptr->ARGV[1] = "help";
         shell_ptr->ARGV[2] = "short"; 
         shell_ptr->ARGV[3] = NULL; 
         printf("Available commands:\n");
         command_ptr = shell_ptr->COMMAND_LIST_PTR; 
         while (command_ptr->COMMAND != NULL)  {
            shell_ptr->ARGV[0] = command_ptr->COMMAND;
            printf("   ");
            return_code = (*command_ptr->SHELL_FUNC)(3, shell_ptr->ARGV);
            command_ptr++;        
         } /* Endwhile */        
      } else {
         /* Help on a specific command */
         if (argc==2)  {
            shell_ptr->ARGV[0] = argv[1];
            shell_ptr->ARGV[1] = "help";
            shell_ptr->ARGV[2] = "usage"; 
            shell_ptr->ARGV[3] = NULL; 
            command_ptr = shell_ptr->COMMAND_LIST_PTR; 
            while (command_ptr->COMMAND != NULL)  {
               if (strcmp(argv[0], command_ptr->COMMAND) == 0)  {
                  return_code = (*command_ptr->SHELL_FUNC)(3, shell_ptr->ARGV);
                  break;   
               } 
               command_ptr++;        
            } /* Endwhile */
            if (command_ptr->COMMAND == NULL)  {
               printf("Error, command \"%s\" not registered.\n", argv[1] );
            }
         } else {
            print_usage = TRUE;
         }    
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s [<command>]\n", argv[0]);
      } else  {
         printf("Usage: %s [<command>]\n", argv[0]);
         printf("   <command> = command to get help on\n");
      }
   }
   return return_code;
} /* Endbody */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_c90i_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_c90i_prv.h$
* $Version : 3.8.2.0$
* $Date    : Sep-17-2012$
*
* Comments:
*
*   The file contains function prototypes and defines for the internal 
*   flash driver.
*
*END************************************************************************/
#ifndef __flash_c90i_prv_h__
#define __flash_c90i_prv_h__


#include "flashx.h"
#include "flashxprv.h"


/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

// SPECIAL_TAG definitions
#define C90_ASPACE_MASK     0x0000000f
#define C90_CONTROLLER_MASK 0x000000f0
#define C90_WIDTH_MASK      0x0000ff00
#define C90_ASPACE_SHIFT        (0)
#define C90_CONTROLLER_SHIFT    (4)
#define C90_WIDTH_SHIFT         (8)

#define C90_CONTROLLER_0    0x00000010
#define C90_CONTROLLER_1    0x00000020
#define C90_INTERLEAVED     (C90_CONTROLLER_0|C90_CONTROLLER_1)

#define C90_WIDTH_32        (32<<C90_WIDTH_SHIFT)
#define C90_WIDTH_64        (64<<C90_WIDTH_SHIFT)
#define C90_WIDTH_128       (128<<C90_WIDTH_SHIFT)

#define C90_ASPACE(x)       ((x&C90_ASPACE_MASK)>>C90_ASPACE_SHIFT)
#define C90_WIDTH(x)        ((x&C90_WIDTH_MASK)>>C90_WIDTH_SHIFT)

/*----------------------------------------------------------------------*/
/*
**                    Structure Definitions
*/

typedef struct c90i_flash_internal_struct 
{
    VC90_REG_STRUCT_PTR reg0_ptr;
    VC90_REG_STRUCT_PTR reg1_ptr;
   void (_CODE_PTR_ flash_exec)(VC90_REG_STRUCT_PTR);
   uint_32 aspace_sectors[C90_ASPACE_COUNT];
} C90I_FLASH_INTERNAL_STRUCT, _PTR_ C90I_FLASH_INTERNAL_STRUCT_PTR;


/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

boolean c90i_flash_init (IO_FLASHX_STRUCT_PTR);
void    c90i_flash_deinit (IO_FLASHX_STRUCT_PTR);
boolean c90i_flash_sector_erase (IO_FLASHX_STRUCT_PTR, char_ptr, _mem_size);
boolean c90i_flash_sector_program (IO_FLASHX_STRUCT_PTR, char_ptr, char_ptr, _mem_size);
boolean c90i_flash_chip_erase (IO_FLASHX_STRUCT_PTR);
boolean c90i_flash_write_protect(IO_FLASHX_STRUCT_PTR, _mqx_uint);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_clock.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_clock.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the RTCS shell.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h"

#define SHELL_CLOCK_SERVER_PRIO        8
#define SHELL_CLOCK_SERVER_STACK       4000
#define SHELL_CLOCK_CHILD_PRIO         7
#define SHELL_CLOCK_CHILD_STACK        4000

#define CREATE_WITH_RTCS 1

/*TASK*-----------------------------------------------------------------
*
* Function Name  : Clock_child_task
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/

static void Clock_child_task
   (
#if CREATE_WITH_RTCS
      pointer  param,
      pointer  creator
#else
   uint_32     sock
#endif
   )

{
#if CREATE_WITH_RTCS
   uint_32     sock = (uint_32) param;
#endif
   int_32      size;
   char        buffer[256];
   TIME_STRUCT time;

#if CREATE_WITH_RTCS
   RTCS_task_resume_creator(creator, RTCS_OK);
#endif

   printf("Clock child: Servicing socket %x\n", sock);
#if USE_RTCS_ATTACH_DETACH
   RTCS_attachsock(sock);
#endif

   while (sock) {
      _time_get(&time);
      size = sprintf(buffer, "\r\nSeconds elapsed = %d.%03d", time.SECONDS, time.MILLISECONDS);
      size++; // account for null byte
      if (size != send(sock, buffer, size, 0)) {
         printf("\nClock child: closing socket %x\n",sock);
         shutdown(sock, FLAG_CLOSE_TX);
         sock=0;
      } else {
         _time_delay(5000);
      }
   }
   printf("Clock child: Terminating\n");

}

/*TASK*-----------------------------------------------------------------
*
* Function Name  : Clock_server_task
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/

static void Clock_server_task
(
   pointer unused1,
   pointer unused2
)
{
   sockaddr_in    laddr, raddr={0};
   uint_32        sock, listensock;
   uint_32        error;
   uint_16        rlen;


   /* Clock server services port 999 */
   laddr.sin_family      = AF_INET;
   laddr.sin_port        = 999;
   laddr.sin_addr.s_addr = INADDR_ANY;


   /* Listen on TCP port */
   listensock= socket(PF_INET, SOCK_STREAM, 0);
   if (listensock == RTCS_HANDLE_ERROR) {
      printf("\nCreate stream socket failed");
      _task_block();
   } 
   error = bind(listensock, (const struct sockaddr *)&laddr, sizeof(laddr));
   if (error != RTCS_OK) {
      printf("\nStream bind failed - 0x%lx", error);
      _task_block();
   } 
   error = listen(listensock, 0);
   if (error != RTCS_OK) {
      printf("\nListen failed - 0x%lx", error);
      _task_block();
   } 

   printf("\nClock Server active on port 999\n");

   for (;;) {
      /* Connection requested; accept it */
      rlen = sizeof(raddr);
      printf("Clock server: Waiting on accept\n");
      sock = accept(listensock, (struct sockaddr *)&raddr, &rlen);
      if (sock == RTCS_HANDLE_ERROR) {
         printf("\n\n*** Clock server: Accept failed, error 0x%lx *** \n\n\n",
            RTCS_geterror(listensock));
      } else {
         printf("Clock server: Connection from %ld.%ld.%ld.%ld, port %d, socket %x\n",
            (raddr.sin_addr.s_addr >> 24) & 0xFF,
            (raddr.sin_addr.s_addr >> 16) & 0xFF,
            (raddr.sin_addr.s_addr >>  8) & 0xFF,
             raddr.sin_addr.s_addr        & 0xFF,
             raddr.sin_port, sock);

         /* Create a task to look after it */
         printf("Clock server: detaching socket %x\n",sock);
#if USE_RTCS_ATTACH_DETACH
         RTCS_detachsock(sock);
#endif
         printf("Clock server: spawning child task\n");
         #if CREATE_WITH_RTCS
         RTCS_task_create("Clock_child", SHELL_CLOCK_CHILD_PRIO,
             SHELL_CLOCK_CHILD_STACK, Clock_child_task, (pointer) sock);
         #else
            {
               TASK_TEMPLATE_STRUCT    task_template = {0};
               task_template.TASK_NAME          = "Clock_child";
               task_template.TASK_PRIORITY      = SHELL_CLOCK_CHILD_PRIO;
               task_template.TASK_STACKSIZE     = SHELL_CLOCK_CHILD_STACK;
               task_template.TASK_ADDRESS       = Clock_child_task;
               task_template.CREATION_PARAMETER = (uint_32)sock;
               if (_task_create(0, 0, (uint_32)&task_template) == MQX_NULL_TASK_ID) {
                  printf("Clock server: failed to spawn child task\n");
               } 
            }
         #endif
      } 
   }
} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name :  Shell_Clock_server_start
*  Returned Value:  none
*  Comments  :  SHELL utility to start clock server
*  Usage:  Clock_server 
*
*END*-----------------------------------------------------------------*/

int_32  Shell_Clock_server_start(int_32 argc, char_ptr argv[] )
{
   uint_32  result;
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc == 1)  {
         result =RTCS_task_create("Clock_server", SHELL_CLOCK_SERVER_PRIO, 
            SHELL_CLOCK_SERVER_STACK, Clock_server_task, NULL);
         if (result ==  0)  {
            printf("Clock Server Started.\n");
         } else  {
            printf("Unable to start Clock Server, error = 0x%x\n",result);
            return_code = SHELL_EXIT_ERROR;
         }
      } else  {
         printf("Error, %s invoked with incorrect number of arguments\n", argv[0]);
         print_usage = TRUE;
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s \n", argv[0]);
      } else  {
         printf("Usage: %s\n",argv[0]);
      }
   }
   return return_code;
} /* Endbody */

#endif /* SHELLCFG_USES_RTCS */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_kinetis.h<|end_filename|>
/* WARNING!!! This file is deprecated. For Kinetis platforms, use flash_ftfl.h or
** flash_ftfe.h respectivelly (depending on flash integrated peripheral on your
** chip. We include flash_ftfl.h by default for backward compatibility, because
** FTFL peripheral was the only peripheral used on Kinetis in the early releases.
*/
#include <flash_ftfl.h>


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/khci/khci_dev_main.c<|end_filename|>
/**HEADER**********************************************************************
*
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
*******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: khci_dev_main.c$
* $Version : 3.8.25.0$
* $Date    : Sep-26-2012$
*
* Comments:
*
*   This file contains the main usbfs USB Device Controller interface
*   functions.
*
*END************************************************************************/

/******************************************************************************
 *               BUFFER DISCRIPTOR TABLE (BDT) DISCRIPTION                    *
 ******************************************************************************/
 /**
 * The USB-FS implements a Buffer Descriptor Table (BDT) in system memory. The
 * BDT resides on a 512 byte boundary in system memory and is pointed to by the
 * BDT Page Registers. Every endpoint direction requires two eight-byte Buffer
 * Descriptor entries.Therefore, a system with 16 fully bidirectional endpoints
 * would require 512 bytes of system memory to implement the BDT.The two Buffer
 * Descriptor (BD) entries allows for an EVEN BD and ODD BD entry for each
 * endpoint direction. This allows the microprocessor to process one BD while
 * the USB-FS is processing the other BD. Double buffering BDs in this way
 * allows the USB-FS to easily transfer data at the maximum throughput provided
 * by USB.
 *
 * Because the buffers are shared between the microprocessor and the USB-FS a
 * simple semaphore mechanism is used to distinguish who is allowed to update
 * the BDT and buffers in system memory. A semaphore bit, the OWN bit, is
 * cleared to 0 when the BD entry is owned by the microprocessor. The
 * microprocessor is allowed read and write access to the BD entry and the
 * buffer in system memory when the OWN bit is 0.
 * When the OWN bit is set to 1, the BD entry and the buffer in system memory
 * are owned by the USB-FS. The USB-FS now has full read and write access and
 * the microprocessor should not modify the BD or its corresponding data buffer.
 * The BD also contains indirect address pointers to where the actual buffer
 * resides in system memory.
 ******************************************************************************
 *                 BUFFER DISCRIPTOR FORMAT DISCRIPTION
 ******************************************************************************
 * The Buffer Descriptors have different meaning based on who is reading the BD
 * in memory.The USB-FS Controller uses the data stored in BDs to determine:
 *
 *       # Who owns the buffer in system memory
 *       # Data0 or Data1 PID
 *       # Release Own upon packet completion
 *       # No address increment (FIFO Mode)
 *       # Data toggle synchronization enable
 *       # How much data is to be transmitted or received
 *       # Where the buffer resides in system memory
 *
 * While the microprocessor uses the data stored in the BDs to determine:
 *       # Who owns the buffer in system memory
 *       # Data0 or Data1 PID
 *       # The received TOKEN PID
 *       # How much data was transmitted or received
 *       # Where the buffer resides in system memory
 *
 *    ------ ------ ------ ------ -------- ---------- ---------- ---------- ---------- ---------- ----------
 *   |31-26 |25-16 | 15-8 |  7   |   6    |   5      |   4      |   3      |   2      |   1      |   0      |
 *   |RSVD  | BC   | RSVD | OWN  |DATA0/1 |TOK_PID[3]|TOK_PID[2]|TOK_PID[1]|TOK_PID[0]|TOK_PID[n]| reserved |
 *    ------ ------ ------ ------ -------- ---------- ---------- ---------- ---------- ---------- ----------
 *   |                             ADDRESS[31--0]                                                           |
 *   |                                                                                                      |
 *    -------------------------------------------------------------------------------------------------------
 *
 * This Buffer Discriptor table is represented by the variable "BDT_BASE"
 * defined in file usbfs_dev_main.h. Macros such as "BD_ADDR_RX" and
 * "BD_ADDR_TX" is used to manipulate the address field and Macros such as
 * BD_CTRL_RX and BD_CTRL_TX is used to manipulate the control fields.
 */


/******************************************************************************
 * Includes
 *****************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "dev_cnfg.h"
#include "devapi.h"

#include "khci_dev_main.h"

/****************************************************************************
 * Global Variables
 ****************************************************************************/
/* TODO: rewrite following defintions to bit mask */
#define ISTAT_CLEAR_ALL         (0xFF) /* Value to clear all pending interrupts */
#define ERRSTAT_CLEAR_ALL       (0xFF) /* Value to clear all errors */
#define ERREN_ENABLE_ALL        (0xFF) /* Value to enable all error interrupts */
#define INTEN_BUS_RESET_VAL     (0x9F) /* Value to enable interrupts in bus reset */

#if defined( __ICCCF__ ) || defined( __ICCARM__ )
    #pragma segment="USB_BDT_Z"
    #pragma data_alignment=512
    __no_init static uint_8 bdt[512] @ "USB_BDT_Z";
#elif defined (__CC_ARM) || defined(__GNUC__)
    __attribute__((section(".usb_bdt"))) static uint_8 bdt[512] = { 1 };
#else
  #pragma define_section usb_bdt ".usb_bdt" RW
  __declspec(usb_bdt) static uint_8 bdt[512] = { 1 };    // DO NOT REMOVE INITIALIZATION !!! bug in CW (cw 7.1) - generate wrong binary code, data
#endif  

boolean g_zero_pkt_send = FALSE;

#ifdef KHCI_DEBUG
struct tk_dne_log {
    uint_32 len;
    uint_8 ep_num;
    uint_8 dir;
    uint_8 pid;
};
volatile static uint_16 tdl_index = 0;
volatile static struct tk_dne_log tdl[1024] = { 0 }; /* note, the array is for 1024 records only */
volatile static uint_16 pkb_index = 0;
volatile static uint_8 pkb[1024][8] = { 0 };
volatile static uint_32 pkbaddr[1024] = { 0 };
#   define KHCI_DEBUG_LOG(a, b, c, d) \
  { \
    tdl[tdl_index].ep_num = a; \
    tdl[tdl_index].dir = b; \
    tdl[tdl_index].len = c; \
    tdl[tdl_index].pid = d; \
    tdl_index++; \
  }
  
#   define KHCI_SAVE_SETUP(source) \
  { \
    pkb[pkb_index][0] = *((uint_8 *)source + 0); \
    pkb[pkb_index][1] = *((uint_8 *)source + 1); \
    pkb[pkb_index][2] = *((uint_8 *)source + 2); \
    pkb[pkb_index][3] = *((uint_8 *)source + 3); \
    pkb[pkb_index][4] = *((uint_8 *)source + 4); \
    pkb[pkb_index][5] = *((uint_8 *)source + 5); \
    pkb[pkb_index][6] = *((uint_8 *)source + 6); \
    pkb[pkb_index][7] = *((uint_8 *)source + 7); \
    pkb_index++; \
  }
  
#   define KHCI_SAVE_BUFADDR(addr) \
  { \
    pkbaddr[pkb_index] = (uint_32)(addr); \
  }
    
#else
#   define KHCI_DEBUG_LOG(a, b, c, d)
#   define KHCI_SAVE_SETUP(source)
#   define KHCI_SAVE_BUFADDR(addr)
#endif

/*****************************************************************************
 * Local Functions
 *****************************************************************************/
void _usb_device_alloc_XD
(
    _usb_device_handle handle,
    /* [IN] the dTD to enqueue */
    XD_STRUCT_PTR *xd_ptr
);

 /*****************************************************************************
 * Local Functions
 *****************************************************************************/
 /*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_alloc_XD
*  Returned Value : void
*  Comments       :
*        Allocates an XD from the free XD ring.
*
*END*-----------------------------------------------------------------*/
void _usb_device_alloc_XD
(
    _usb_device_handle handle,
    /* [IN] the dTD to enqueue */
    XD_STRUCT_PTR *xd_ptr_ptr
)
{   /* Body */
    volatile USB_DEV_STATE_STRUCT_PTR   usb_dev_ptr = handle;
    
    /* This function can be called from any context, and it needs mutual
      exclusion with itself.*/
    USB_lock();
    
    /* Get a transfer descriptor for the specified endpoint 
    ** and direction 
    */
    USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, *xd_ptr_ptr);
   
    usb_dev_ptr->XD_ENTRIES--;

    USB_unlock();
} /* Endbody */

/******************************************************************************
 *
 * @name  _usb_next_setup_token_prep
 *
 * @brief The function prepares for next setup token
 *
 * @param state_ptr:      Device info Structure.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_next_setup_token_prep(USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr)
{
    XD_STRUCT_PTR xd_ptr_temp;

    /* prepare XD queue for RECV CONTROL ENDPOINT*/
    _usb_device_alloc_XD (state_ptr, &xd_ptr_temp);
    xd_ptr_temp->EP_NUM = USB_CONTROL_ENDPOINT;
    xd_ptr_temp->BDIRECTION = USB_RECV;
    xd_ptr_temp->WTOTALLENGTH = ZERO_LENGTH;
    xd_ptr_temp->EP_TYPE = USB_CONTROL_PIPE;
    xd_ptr_temp->DONT_ZERO_TERMINATE = TRUE;
    xd_ptr_temp->WSTARTADDRESS = (uint_8_ptr) LONG_LE_TO_HOST(
        BD_ADDR_RX(USB_CONTROL_ENDPOINT,
        state_ptr->EP_INFO[USB_CONTROL_ENDPOINT].rx_buf_odd));

    USB_XD_QUEUE_ENQUEUE(&state_ptr->EP_INFO[USB_CONTROL_ENDPOINT].xd_queue_recv, xd_ptr_temp);
    
    /* toggle send buffer */
    state_ptr->EP_INFO[USB_CONTROL_ENDPOINT].tx_buf_odd ^= 1;
    
    /* configure data pid for setup token and give control to SEI*/
    state_ptr->EP_INFO[USB_CONTROL_ENDPOINT].rx_data0 = 0;
    BD_CTRL_RX(USB_CONTROL_ENDPOINT,
        state_ptr->EP_INFO[USB_CONTROL_ENDPOINT].rx_buf_odd) =
    LONG_LE_TO_HOST((uint_32)(USB_BD_BC(
        state_ptr->EP_INFO[USB_CONTROL_ENDPOINT].max_packet_size) |
        USB_BD_OWN | USB_BD_DTS | USB_BD_DATA01(state_ptr->EP_INFO[USB_CONTROL_ENDPOINT].rx_data0)));
    /* setup token is always on DATA0 PID */
    return;
}

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_ep_read
 *
 * @brief The function reads the endpoint buffers
 *
 * @param state_ptr:      Device info Structure.
 * @param ep_num:         endpoint number
 * @param buf_ptr:        buffer to receive in
 * @param buf_num_bytes:  number of bytes to read
 *
 * @return USB_OK         When Successfull
 *****************************************************************************/
static USB_STATUS _usb_device_usbfs_ep_read
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr,
     /*[IN]*/
    uint_8 ep_num,
     /*[OUT]*/
    uint_8_ptr buf_ptr,
     /*[IN]*/
    uint_32 buf_num_bytes
)
{
    volatile USB_MemMapPtr usb_ptr;
    
    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    
    _int_disable();
    
    /* USB data is directly transferred to App Buffer to Avoid one level of
     * memcpy. (i.e from Endpoint buffer to App buffer). So a hack here
     * is been provided. This hack stores the current endpoint buffer
     * address to a variable and programes the buffer address in the BDT
     * as APP buffer. Later when TOKEN_DNE interrupt is received for this Token
     * this buffer address saved is restored. Please note that at present
     * App should not release the buffer passed till he gets a notification from
     * interrupt handler.
     */
    
    state_ptr->EP_INFO[ep_num].save_recv_addr = 
        LONG_LE_TO_HOST(BD_ADDR_RX(ep_num,
            state_ptr->EP_INFO[ep_num].rx_buf_odd));

    BD_ADDR_RX(ep_num, state_ptr->EP_INFO[ep_num].rx_buf_odd) =
        LONG_LE_TO_HOST((uint_32)buf_ptr);

    /* Program number of bytes to be received and give
     * the Control to the SEI
     */
    BD_CTRL_RX(ep_num, state_ptr->EP_INFO[ep_num].rx_buf_odd) =
        LONG_LE_TO_HOST(USB_BD_BC(buf_num_bytes) |
            USB_BD_OWN | USB_BD_DTS | USB_BD_DATA01(state_ptr->EP_INFO[ep_num].rx_data0));
    
    _int_enable ();
    usb_ptr->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_ep_write
 *
 * @brief The function writes the endpoint buffers
 *
 * @param state_ptr:      Device info Structure.
 * @param ep_num:         endpoint number
 * @param buf_ptr:        buffer to send from
 * @param buf_num_bytes:  number of bytes to write
 * @param bytes_written_ptr: buffer that will  contian Number of bytes written
 *                           to device.
 *
 * @return USB_OK         When Successfull
 *****************************************************************************/
static USB_STATUS _usb_device_usbfs_ep_write
(
    /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr, 
    /*[IN]*/
    uint_8 ep_num,
    /*[IN]*/
    uint_8_ptr buf_ptr,
    /*[IN]*/
    uint_32 buf_num_bytes,
     /*[OUT]*/
    uint_32_ptr bytes_written_ptr 
)
{
    volatile USB_MemMapPtr usb_ptr;
    uint_16 max_packet_size;
    
    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* If the number of bytes to be sent is greater than the
     * maximum data that can be sent on the USB bus, then split the
     * transaction, into multiple transaction.
     */
    max_packet_size = state_ptr->EP_INFO[ep_num].max_packet_size;
    
    if (buf_num_bytes > max_packet_size)
    {
        buf_num_bytes = max_packet_size;
    }
    
    *bytes_written_ptr = buf_num_bytes;
    
    /* Program the endpoint buffer address in BDT
     * from where DMA will pick the Data to be sent over USB bus.
     */
    BD_ADDR_TX(ep_num, state_ptr->EP_INFO[ep_num].tx_buf_odd) =
        LONG_LE_TO_HOST((uint_32)buf_ptr);
    /* Program the number of bytes to be sent in BDT and Give
     * the onership to SEI
     */
    BD_CTRL_TX(ep_num, state_ptr->EP_INFO[ep_num].tx_buf_odd) =
        LONG_LE_TO_HOST((uint_32)(USB_BD_BC(buf_num_bytes) |
            USB_BD_OWN | USB_BD_DTS |
            USB_BD_DATA01(state_ptr->EP_INFO[ep_num].tx_data0)));
    
    usb_ptr->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
    return USB_OK;
}
    
/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_reset_ep_state
 *
 * @brief This Function Resets all the parameters required for End Point
 *        Initialization
 *
 * @param state_ptr: Device info Structure.
 * @return USB_OK         When Successfull
 *****************************************************************************/
static USB_STATUS _usb_device_usbfs_reset_ep_state
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr
)
{
    volatile USB_MemMapPtr usb_ptr;
    _mqx_int ep;
    
    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Clear all the error Status registor */
    usb_ptr->ERRSTAT = ERRSTAT_CLEAR_ALL;
    
    /*Reset all ODD and Even BDTs to Zero */
    usb_ptr->CTL |= USB_CTL_ODDRST_MASK;
    
    /* Initialize the address as zero in the Address register of USB IP*/
    usb_ptr->ADDR = 0;  
    
    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++)
    {
        /* Clearing all buffer descriptors for both ODD and even
         * for Both Receive and Transmit direction
         */
        BD_CTRL_RX(ep, EVEN_BUFF) = 0;
        BD_CTRL_RX(ep, ODD_BUFF) = 0;

        BD_CTRL_TX(ep, EVEN_BUFF) = 0;
        BD_CTRL_TX(ep, ODD_BUFF) = 0;

        state_ptr->EP_INFO[ep].rx_buf_odd = EVEN_BUFF;
        state_ptr->EP_INFO[ep].tx_buf_odd = EVEN_BUFF;
        state_ptr->EP_INFO[ep].data_buffer = NULL;
        state_ptr->EP_INFO[ep].save_recv_addr = USB_UNINITIALIZED_VAL_32;
        
        if(ep == USB_CONTROL_ENDPOINT)
        {
            state_ptr->EP_INFO[ep].tx_buf_odd = ODD_BUFF;
        }

        /* Initialize All End Point Control Registers with default value of 0*/
        usb_ptr->ENDPOINT[ep].ENDPT = 0;
    }
    
    g_zero_pkt_send = FALSE;
    
    usb_ptr->CTL &= ~USB_CTL_ODDRST_MASK;
    
    /* initializing device address to default  address
     * value for USB in Device strucutre.
     */
    state_ptr->G.DEVICE_ADDRESS = 0;

    /* Set Default state of USB in Device Structure.*/
    state_ptr->G.USB_STATE = USB_STATE_DEFAULT;

    /* Enable All Error Interrupts */
    usb_ptr->ERREN = ERREN_ENABLE_ALL;

    /* Enable All Interrupts except RESUME */
    usb_ptr->INTEN = INTEN_BUS_RESET_VAL;

    /* SEI if, has suspended packet trasmission resume packet transmission by
     * clearing TXD_SUSPEND in CTL register.
     */
    usb_ptr->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;

    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_process_transmit_request
 *
 * @brief : Service TOKEN DONE Interrupt when there is transmission of packet.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 * @param ep_num:    endpoint number
 * @param buffer_ptr:Holds Data that is send to Host.
 * @return USB_STATUS_TRANSFER_PENDING when there is split transaction or
 *                   USB_OK.
 *****************************************************************************/
static USB_STATUS _usb_device_usbfs_process_transmit_request
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr, 
    /*[IN]*/
    uchar ep_num,
     /*[OUT]*/
    uint_8** buffer_ptr
)
{
    volatile XD_STRUCT_PTR xd_ptr;
    
    USB_XD_QUEUE_GET_HEAD(&state_ptr->EP_INFO[ep_num].xd_queue_send,&xd_ptr);

    *buffer_ptr = (uint_8_ptr) LONG_LE_TO_HOST(BD_ADDR_TX(ep_num,
        state_ptr->EP_INFO[ep_num].tx_buf_odd));

    /* set DATA PID and buffer for next send transaction */
    state_ptr->EP_INFO[ep_num].tx_buf_odd ^= 1;
    state_ptr->EP_INFO[ep_num].tx_data0 ^= 1;

    /* If any split transaction is pending initiate that. */
    if((xd_ptr != NULL)&&(xd_ptr->WSOFAR != xd_ptr->WTOTALLENGTH))
    {
        _usb_dci_usbfs_send(state_ptr, xd_ptr);
        return USB_STATUS_TRANSFER_PENDING;
    }

    return USB_OK;
}

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_process_receive_request
 *
 * @brief : Service TOKEN DONE Interrupt when there is receive packet scenario.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function
 *                   USB_install_isr during ISR installation.
 * @param ep_num:    endpoint number
 * @param stat:      status of last transaction.
 * @param buffer_ptr:buffer holding data received from Host.
 *
 * @return USB_STATUS_TRANSFER_PENDING when there is split transaction else
 *                   USB_OK
 *****************************************************************************/
#if (__CWCC__ >= 4)
    /* Workaround for CodeWarrior 10.x ARM C compiler and optimization level > 1 */
    #pragma optimization_level 1
#endif

static USB_STATUS _usb_device_usbfs_process_receive_request
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr, 
    /*[IN]*/
    uchar ep_num, 
    /*[IN]*/
    uchar stat, 
     /*[OUT]*/
    uint_8** buffer_ptr
)
{
    volatile XD_STRUCT_PTR xd_ptr;
    uchar dir,buf_odd,token_pid;
    uint_32 len;
    
    USB_XD_QUEUE_GET_HEAD(&state_ptr->EP_INFO[ep_num].xd_queue_recv,&xd_ptr);
    
    *buffer_ptr = (uint_8_ptr) LONG_LE_TO_HOST(BD_ADDR_RX(ep_num,
        state_ptr->EP_INFO[ep_num].rx_buf_odd));
    KHCI_SAVE_BUFADDR(*buffer_ptr);
    KHCI_SAVE_SETUP(*buffer_ptr);
    
    dir = (stat & USB_STAT_TX_MASK) ? USB_SEND : USB_RECV;
    buf_odd = (stat & USB_STAT_ODD_MASK) ? ODD_BUFF : EVEN_BUFF;
    
    /* Get length of Data transmited or recevied in the last transaction. */
    len = HOST_TO_LE_LONG(BD_CTRL(ep_num,dir,buf_odd))>>16 & 0x3ff;
    
    token_pid = (uint_8)((HOST_TO_LE_LONG(BD_CTRL(ep_num,dir,buf_odd)) >> 2) & 0x0000000f);
    
    if((ep_num == USB_CONTROL_ENDPOINT) && (token_pid == USB_SETUP_TOKEN))
    {
        /* cancel any pending transfers in SEND QUEUE if present*/
        (void)_usb_device_cancel_transfer((_usb_device_handle)state_ptr,
            ep_num, USB_SEND);
        /* for first In/OUT after setup token DATA PID has to be always one */
        state_ptr->EP_INFO[ep_num].tx_data0 = 1;
        state_ptr->EP_INFO[ep_num].rx_data0 = 1;
        state_ptr->EP_INFO[ep_num].rx_buf_odd ^= 1;
        state_ptr->EP_INFO[ep_num].tx_buf_odd ^= 1;
    }
    else
    {
        /* set DATA PID and buffer for next recv transaction */
        state_ptr->EP_INFO[ep_num].rx_data0 ^= 1;
        state_ptr->EP_INFO[ep_num].rx_buf_odd ^= 1;
        
        if(state_ptr->EP_INFO[ep_num].save_recv_addr != 
            USB_UNINITIALIZED_VAL_32)
        {
            /* save original address */
            BD_ADDR_RX(ep_num, state_ptr->EP_INFO[ep_num].rx_buf_odd^1) =
                HOST_TO_LE_LONG(state_ptr->EP_INFO[ep_num].save_recv_addr);
            state_ptr->EP_INFO[ep_num].save_recv_addr = 
                USB_UNINITIALIZED_VAL_32;
        }
        
        /* if data in recv is queued -- split recv */
        if((xd_ptr)&&((xd_ptr->WSOFAR < xd_ptr->WTOTALLENGTH) && len))
        {
            _usb_dci_usbfs_recv(state_ptr, xd_ptr);
            return USB_STATUS_TRANSFER_PENDING;
        }
    }

    return USB_OK;
}

#if (__CWCC__ >= 4)
    /* End of workaround for CodeWarrior 10.x ARM C compiler and optimization level > 1 */
#pragma optimization_level reset
#endif

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_service_err_intr
 *
 * @brief : Service Error Interrupt.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_service_err_intr
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr 
)
{
    uchar device_error = 0, stat, ep_num;
    volatile USB_MemMapPtr usb_ptr;
    USB_EVENT_STRUCT event;
    
    /* This test is redundant, the condition is already tested in ISR
    if (state_ptr == NULL)
    {
        return;
    } */

    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }
    
    /* Get the status of previous transaction*/
    stat = usb_ptr->STAT;

    /* Clear the Error Interrupt */
    usb_ptr->ISTAT = USB_ISTAT_ERROR_MASK;
    
    /* Get the Endpoint number on which the transaction occured.
     * This is (7 - 5) [3:0] bit in STAT register.
     */
    ep_num = (uint_8)((stat & ENDPOINT_NUMBER_MASK) >> ENDPOINT_NUMBER_SHIFT);
    
    /* Read the ERRSTAT register to determine the source of the error
     * It is Andded with ERREN register to find out which of the
     * Error was enabled and report only the enabled error to the App layer
     */
    device_error = (uint_8)(usb_ptr->ERRSTAT & usb_ptr->ERREN);
    
    #ifdef _DEV_DEBUG
        printf("USB Err: 0x%x\n", device_error);
    #endif   
    
    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = (_usb_device_handle)state_ptr;
    event.ep_num = ep_num;
    event.setup = FALSE;
    event.direction = (boolean)(stat >> 3 & 1);
    event.buffer_ptr = (uchar*)&device_error;
    event.len = ZERO_LENGTH;
    
    /* Invoke Service Call */
    (void)_usb_device_call_service(USB_SERVICE_ERROR,&event);
    
    /*clear all errors*/
    usb_ptr->ERRSTAT = ERRSTAT_CLEAR_ALL; 
}

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_service_reset_intr
 *
 * @brief : Service reset Interrupt.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_service_reset_intr
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr 
)
{
    uint_8 cnt=0;
    uchar stat,ep_num;
    volatile USB_MemMapPtr usb_ptr;
    USB_EVENT_STRUCT event;
    
    /* This test is redundant, the condition is already tested in ISR
    if (state_ptr == NULL)
    {
        return;
    } */

    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }
    
    /* Clear Reset Interrupt */
    usb_ptr->ISTAT = USB_ISTAT_USBRST_MASK;
    
    /* Get the status of previous transaction*/
    stat = usb_ptr->STAT;
    
    /* Get the Endpoint number on which the transaction occured.
     * This is (7 - 5) [3:0] bit in STAT register.
     */
    ep_num = (uint_8)((stat & ENDPOINT_NUMBER_MASK) >> ENDPOINT_NUMBER_SHIFT);
    
    /* De-Init All the End Point.  */
    for (cnt = 0; cnt < USB_MAX_ENDPOINTS; cnt++)
    {
        _usb_dci_usbfs_deinit_endpoint(state_ptr,cnt,USB_RECV);
        _usb_dci_usbfs_deinit_endpoint(state_ptr,cnt,USB_SEND);
    }

    /* Re-Initialize All the end point */
    _usb_device_usbfs_reset_ep_state((USB_KHCI_DEV_STATE_STRUCT_PTR)state_ptr);
    
    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = (_usb_device_handle)state_ptr;
    event.ep_num = ep_num;
    event.setup = FALSE;
    event.direction = USB_RECV;
    event.buffer_ptr = (uchar*)NULL;
    event.len = ZERO_LENGTH;
    /* Inform Upper Layer of Reset Signal.
     * Remember Upper layer i.e class driver invokes
     * _usb_dci_usbfs_init_endpoint() as part of reset callback
     */
    (void)_usb_device_call_service(USB_SERVICE_BUS_RESET,&event);
}

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_service_tk_dne_intr
 *
 * @brief : Service Error Interrupt.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. It is the same
 *                   stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_service_tk_dne_intr
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr 
)
{
    uint_8 ep_num,stat,dir,buf_odd,setup,token_pid;
    uint_32 len = 0;
    USB_STATUS error;
    uint_32 buf_num_bytes;
    volatile USB_MemMapPtr usb_ptr;
    volatile XD_STRUCT_PTR xd_ptr;
    uint_8 * buffer_ptr = NULL;
    USB_EVENT_STRUCT event;
    
    /* This test is redundant, the condition is already tested in ISR
    if (state_ptr == NULL)
    {
        return;
    } */
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }

    /* Get the status of previous transaction*/
    stat = usb_ptr->STAT;

    /* Clear TOKEN  Done Interrupt. This clearing of TOKEN_DONE
     * should happen after STAT register is read. This is becouse
     * STAT register has four byte fifo and if TOKEN_DONE is cleared
     * in INT_STAT then the content of STAT register is updated with
     * the next value in the STAT fifo.
     */
    usb_ptr->ISTAT = USB_ISTAT_TOKDNE_MASK;

    /* Get the Endpoint number on which the transaction occured.
     * This is (7 - 5) [3:0] bit in STAT register.
     */
    ep_num = (uint_8)((stat & ENDPOINT_NUMBER_MASK) >> ENDPOINT_NUMBER_SHIFT);

    /* Get the Direction of transaction. (i.e the transaction was a receive
     * operation or transaction was a Transmit operation).It is Bit [3] in STAT
     * register.
     */
    dir = (stat & USB_STAT_TX_MASK) ? USB_SEND : USB_RECV;

    /* Get the last buffer transaction was in ODD buffer or Even Buffer*/
    buf_odd = (stat & USB_STAT_ODD_MASK) ? ODD_BUFF : EVEN_BUFF;

    /* Get length of Data transmited or recevied in the last transaction. */
    len = HOST_TO_LE_LONG(BD_CTRL(ep_num,dir,buf_odd))>>16 & 0x3ff;

    /* Get PID for this token */
    token_pid = (uint_8)((HOST_TO_LE_LONG(BD_CTRL(ep_num,dir,buf_odd))>>2) & 0x0000000f);

    /* if token PID is a setup token */
    setup = (token_pid == USB_SETUP_TOKEN) ? TRUE : FALSE;
    /* DEQUEUE the XD queue for previous transaction and perform split
     * transaction if required
     */
    
    KHCI_DEBUG_LOG(ep_num, dir, len, token_pid);
    
    if(dir)
    { /* direction is USB_SEND*/
        /* Get head of the send queue */
        USB_XD_QUEUE_GET_HEAD(&state_ptr->EP_INFO[ep_num].xd_queue_send,&xd_ptr);
        /* updating the WSOFAR field */
        xd_ptr->WSOFAR += len;
        /* total number of bytes send are updated for upper layer */
        event.len = xd_ptr->WSOFAR;
        /* buffer address is updated for upper layer */
        event.buffer_ptr = xd_ptr->WSTARTADDRESS; 
        /* Get the number of Bytes left to be transmitted. If it is not zero
         * its a split transaction and donot delete the XD pointer
         */
        buf_num_bytes = (uint_32)(xd_ptr->WTOTALLENGTH - xd_ptr->WSOFAR);
        
        /* dequeue if all bytes have been send or the last send transaction was
           of length less then the max packet size length configured for
           corresponding endpoint */
        if((buf_num_bytes == 0)||(state_ptr->EP_INFO[ep_num].max_packet_size >
            len))
        {
            xd_ptr->BSTATUS = USB_STATUS_IDLE;
            /* Remove from the EP_Info send queue*/
            USB_XD_QUEUE_DEQUEUE(&state_ptr->EP_INFO[ep_num].xd_queue_send, &xd_ptr);
            /* Add it to the free queue */
            if (xd_ptr != NULL)
            _usb_device_free_XD(state_ptr, xd_ptr);
            //_usb_device_free_XD(xd_ptr);
        }
        /* Process the Transmit token Done. If it was split transaction,
         * start transmit for the remaing data. Below function returns USB_OK
         * if all data is transmitted.
         */
        if(_usb_device_usbfs_process_transmit_request(state_ptr,ep_num,
            &buffer_ptr) != USB_OK)
            return;/*if above call returned USB_STATUS_TRANSFER_PENDING */
        
        /* to send zero bytes data on CONTROL ENDPOINT TO MARK END OF TRANSFER*/
        /* this is needed only when last send transaction was equal to
           max_buffer_size and there is no more data to send*/
        if((len==state_ptr->EP_INFO[ep_num].max_packet_size)&&
            (buf_num_bytes == 0)&&(ep_num==USB_CONTROL_ENDPOINT))
        {
            g_zero_pkt_send = TRUE;
            (void)_usb_device_send_data((_usb_device_handle)state_ptr,ep_num,
                NULL,0);
            return;
        }
    }
    else
    {/* direction is USB_RECV*/
        if(g_zero_pkt_send == TRUE)
        {
            g_zero_pkt_send = FALSE;
        }
        
        /* Get head of the send queue */
        USB_XD_QUEUE_GET_HEAD(&state_ptr->EP_INFO[ep_num].xd_queue_recv,
            &xd_ptr);
        xd_ptr->WSOFAR += len;/* updating the WSOFAR field */
        /* total number of bytes received are updated for upper layer */
        event.len = xd_ptr->WSOFAR;
        /* buffer address is updated for upper layer */
        event.buffer_ptr = xd_ptr->WSTARTADDRESS;
        /* check if number of bytes to be received is zero or if the
         * recevied packet is for Zero size packet.
         */
        buf_num_bytes = (uint_32)(xd_ptr->WTOTALLENGTH - xd_ptr->WSOFAR);


      /* dequeue if all bytes have been received or the last send transaction
         was of length less then the max packet size length configured for
         corresponding endpoint */
        if((!xd_ptr->WTOTALLENGTH)||(buf_num_bytes == 0)||
           (state_ptr->EP_INFO[ep_num].max_packet_size > len))
        {
            xd_ptr->BSTATUS = USB_STATUS_IDLE;
            /* Remove from the EP_Info send queue*/
            USB_XD_QUEUE_DEQUEUE(&state_ptr->EP_INFO[ep_num].xd_queue_recv, &xd_ptr);
            /* Add it to the free queue */
            if (xd_ptr != NULL)
            _usb_device_free_XD(state_ptr, xd_ptr);
        }
        /* Process the receive token Done. If it was split transaction,
         * start receive for the remaing data. Below function returns USB_OK
         * if all data is received.
         */

        if ( _usb_device_usbfs_process_receive_request(state_ptr,ep_num,
            stat,&buffer_ptr)!=USB_OK)
        {
            return;/*if above call returned USB_STATUS_TRANSFER_PENDING */  
        }       
    }

    /* prepare for next setup token if needed*/
    if((ep_num == USB_CONTROL_ENDPOINT)&&(!len)&&(g_zero_pkt_send ==FALSE))
    {
        _usb_next_setup_token_prep(state_ptr);
    }

    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = (_usb_device_handle)state_ptr;
    event.ep_num = ep_num;
    event.setup = setup;
    event.direction = (boolean)(stat >> 3 & 1);

    /* propagate control to upper layers for processing */
    error = _usb_device_call_service(ep_num,&event);

    usb_ptr->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
 }

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_service_sleep_intr
 *
 * @brief : Service Sleep Interrupt.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_service_sleep_intr
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr
)
{
    volatile USB_MemMapPtr usb_ptr;
    USB_EVENT_STRUCT event;
    
    /* This test is redundant, the condition is already tested in ISR
    if (state_ptr == NULL)
    {
        return;
    } */
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }
        
    usb_ptr->ISTAT = USB_ISTAT_RESUME_MASK;
    
    /* clear suspend interrupt */
    usb_ptr->ISTAT = USB_ISTAT_SLEEP_MASK;
    
    (void)_usb_device_get_status((_usb_device_handle)state_ptr, 
        USB_STATUS_DEVICE_STATE, &(state_ptr->G.USB_DEV_STATE_B4_SUSPEND));
        
    (void)_usb_device_set_status((_usb_device_handle)state_ptr,
        (uint_8)USB_STATUS_DEVICE_STATE, (uint_16)USB_STATE_SUSPEND);
    
    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = (_usb_device_handle)state_ptr;
    event.ep_num = (uint_8)USB_UNINITIALIZED_VAL_32;
    event.setup = 0;
    event.direction = 0;
    event.buffer_ptr = (uchar*)NULL;
    event.len = ZERO_LENGTH;

    /* Notify Device Layer of SLEEP Event */
    /* this callback need only handle and type -
       all other arguments are redundant */
    (void)_usb_device_call_service(USB_SERVICE_SLEEP,&event);
    
    /* Enable RESUME Interrupt */
    usb_ptr->INTEN |= USB_INTEN_RESUMEEN_MASK;
}

/************************************************************************//*!
 *
 * @name  _usb_device_usbfs_service_resume_intr
 *
 * @brief : Service resume Interrupt.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_service_resume_intr
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr
)
{
    volatile USB_MemMapPtr usb_ptr;
    USB_EVENT_STRUCT event;
    
    /* This test is redundant, the condition is already tested in ISR
    if (state_ptr == NULL)
    {
        return;
    } */
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }
        
    /* clear resume interrupt status bit */
    usb_ptr->ISTAT = USB_ISTAT_RESUME_MASK;
   
    (void)_usb_device_set_status((_usb_device_handle)state_ptr,
        (uint_8)USB_STATUS_DEVICE_STATE, (uint_16)state_ptr->G.USB_DEV_STATE_B4_SUSPEND);
    
    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = (_usb_device_handle)state_ptr;
    event.ep_num = (uint_8)USB_UNINITIALIZED_VAL_32;
    event.setup = 0;
    event.direction = 0;
    event.buffer_ptr = (uchar*)NULL;
    event.len = ZERO_LENGTH;
    
    /* Notify Device Layer of RESUME Event */
    /* this callback need only handle and type -
       all other arguments are redundant */
    (void)_usb_device_call_service(USB_SERVICE_RESUME,&event);
    
    /* Disable RESUME Interrupt */
    usb_ptr->INTEN &= ~USB_INTEN_RESUMEEN_MASK;
}

/***********************************************************************//*!
 *
 * @name  _usb_device_usbfs_service_sof_token_intr
 *
 * @brief : Service SOF Interrupt.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_service_sof_token_intr
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr
)
{
    uchar stat,ep_num;
    volatile USB_MemMapPtr usb_ptr;
    uint_8_ptr buffer_ptr;
    USB_EVENT_STRUCT event;

    /* This test is redundant, the condition is already tested in ISR
    if (state_ptr == NULL)
    {
        return;
    } */
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }
        
    /* Clear SOF Interrupt */
    usb_ptr->ISTAT = USB_ISTAT_SOFTOK_MASK;
    
    state_ptr->G.USB_SOF_COUNT = usb_ptr->FRMNUMH;
    state_ptr->G.USB_SOF_COUNT <<= FRAME_HIGH_BYTE_SHIFT;
    state_ptr->G.USB_SOF_COUNT |= usb_ptr->FRMNUML;
    
    /* address of Lower byte of Frame number.
     */
    buffer_ptr = (uint_8_ptr)&(state_ptr->G.USB_SOF_COUNT);
    
    /* clear resume interrupt status bit */
    usb_ptr->ISTAT = USB_ISTAT_RESUME_MASK;
    
    /* Get the status of previous transaction*/
    stat = usb_ptr->STAT;
    
    /* Get the Endpoint number on which the transaction occured.
     * This is (7 - 5) [3:0] bit in STAT register.
     */
    ep_num = (uint_8)((stat & ENDPOINT_NUMBER_MASK) >> ENDPOINT_NUMBER_SHIFT);
    
    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = (_usb_device_handle)state_ptr;
    event.ep_num = ep_num;
    event.setup = FALSE;
    event.direction =USB_RECV;
    event.buffer_ptr = (uchar*)buffer_ptr;
    event.len = ZERO_LENGTH;
    
    /* Notify Device Layer of SOF Event */
    (void)_usb_device_call_service(USB_SERVICE_SOF,&event);
}

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_service_attach_intr
 *
 * @brief : Service attach Interrupt.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_service_attach_intr
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr 
)
{
    volatile USB_MemMapPtr usb_ptr;
    
    /* This test is redundant, the condition is already tested in ISR
    if (state_ptr == NULL)
    {
        return;
    } */
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }

    usb_ptr->ISTAT = USB_ISTAT_ATTACH_MASK;
}

/************************************************************************//*!
 *
 * @name  _usb_device_usbfs_service_stall_intr
 *
 * @brief : Service stall Interrupt.
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_service_stall_intr
(
     /*[IN]*/
    USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr 
)
{
    volatile USB_MemMapPtr usb_ptr;
    USB_EVENT_STRUCT event;
    
    /*any value except USB_STATUS_STALLED to initialize with */
    uint_16 endp_status = USB_STATUS_IDLE;
    
    /* This test is redundant, the condition is already tested in ISR
    if (state_ptr == NULL)
    {
        return;
    } */
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr)state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }
    
    /* Clear Stall Interrupt */
    usb_ptr->ISTAT = USB_ISTAT_STALL_MASK;
    
    /* Initialize the event strucutre to be passed to the upper layer*/
    event.handle = (_usb_device_handle)state_ptr;
    event.setup = FALSE;
    event.direction = (uint_8)USB_UNINITIALIZED_VAL_32;
    event.buffer_ptr = (uchar*)NULL;
    event.len = ZERO_LENGTH;

    /* check if the stall interrupt received was for CONTROL ENDPOINT */
    (void)_usb_device_get_status(event.handle,
        (uint_8)(USB_CONTROL_ENDPOINT|USB_STATUS_ENDPOINT), &endp_status);
    if(endp_status == USB_STATUS_STALLED)
    {
        event.ep_num = USB_CONTROL_ENDPOINT;
    }
    else
    {
        event.ep_num = (uint_8)USB_UNINITIALIZED_VAL_32;
    }

    /* Notify Device Layer of STALL Event */
    (void)_usb_device_call_service(USB_SERVICE_STALL,&event);

    /* prepare for next setup token if stall was received for Control Endp*/
    if(event.ep_num == USB_CONTROL_ENDPOINT)
    {
        _usb_next_setup_token_prep(state_ptr);
    }
}

/**************************************************************************//*!
 *
 * @name  _usb_device_usbfs_isr
 *
 * @brief : Service all the interrupts in the kirin usb hardware
 *
 * @param state_ptr: Device Structure Pointer Passed to ISR. The is the
 *                   same stracutre which was passed in function USB_install_isr
 *                   During ISR installation.
 *
 * @return NONE
 *****************************************************************************/
static void _usb_device_usbfs_isr(USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr)
{
    uchar error;
    volatile USB_MemMapPtr usb_ptr;
    
    if (state_ptr == NULL)
    {
        return;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return;
    }

    error = (uint_8)(usb_ptr->ISTAT & usb_ptr->INTEN);
    
    /* This interrupt comes when any of the error conditions within
     * the ERRSTAT register occur. The ColdFire core must
     * then read the ERRSTAT register to determine the source of the error.
     */
    if (error & USB_ISTAT_ERROR_MASK)
    {
         _usb_device_usbfs_service_err_intr(state_ptr);
    }
    /* This reset interrupt comes when the USB Module has decoded a valid USB reset.
     * This informs the Microprocessor that it should write 0x00 into the address
     * register and enable endpoint 0. USB_RST bit is set after a USB reset has been
     * detected for 2.5 microseconds. It is not asserted again until the USB reset
     * condition has been removed and then reasserted.
     */
    if (error & USB_ISTAT_USBRST_MASK)
    {
       _usb_device_usbfs_service_reset_intr(state_ptr);
    }
    /* This TOKEN_DONE interrupt comes when the current token being processed
     * has completed. The ColdFire core should immediately read the STAT register
     * to determine the EndPoint and BD used for this token. Clearing this bit
     * (by writing a one) causes the STAT register to be cleared or the
     * STAT holding register to be loaded into the STAT register.
     */
    if (error & USB_ISTAT_TOKDNE_MASK)
    {
        _usb_device_usbfs_service_tk_dne_intr(state_ptr);
    }
    /* This sleep interrupt comes when the USB Module detects a constant idle
     * on the USB bus for 3 milliseconds.
     */
    if (error & USB_ISTAT_SLEEP_MASK)
    {
        _usb_device_usbfs_service_sleep_intr(state_ptr);
    }
    
    /* This interrupt comes depending upon the DP/DM signals, and can be used
     * to signal remote wake-up signaling on the USB bus. When not in suspend
     * mode this interrupt should be disabled
     */
    if (error & USB_ISTAT_RESUME_MASK)
    {
        _usb_device_usbfs_service_resume_intr(state_ptr);
    }
    /* Thisinterrupt comes when the USB Module receives a Start Of Frame
     * (SOF) token.
     */
    if(error & USB_ISTAT_SOFTOK_MASK)
    {
       _usb_device_usbfs_service_sof_token_intr(state_ptr);
    }
    
    /* This interrupt comes when the USB Module detects an attach of a 
     * USB device. This signal is only valid if HOST_MODE_EN is true. 
     * This interrupt signifies that a peripheral is now present and must
     * be configured.
     */
    if(error & USB_ISTAT_ATTACH_MASK)
    {
       _usb_device_usbfs_service_attach_intr(state_ptr);
    }
    
    /* In Target mode this interrupt comes when a STALL handshake is sent 
       by the SIE.*/
    if (error & USB_ISTAT_STALL_MASK)
    {
         _usb_device_usbfs_service_stall_intr(state_ptr);
    }

    return;
}

/*****************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
*
* @name        : _usb_dci_usbfs_preinit
* @brief       : Allocates space for the USB device controller.
* @param handle: Handle to USB Device to be filled
* @return   USB_OK on successful.
******************************************************************************/
USB_STATUS _usb_dci_usbfs_preinit
(
    /* [IN] the USB device handle */
    _usb_device_handle _PTR_ handle_ptr
)
{
    USB_KHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR) USB_mem_alloc_zero(sizeof(USB_KHCI_DEV_STATE_STRUCT));
    KHCI_XD_STRUCT_PTR            xd_ptr;
    SCRATCH_STRUCT_PTR            temp_scratch_ptr;
    _mqx_uint j;

    if (NULL != usb_dev_ptr) {
        /* Allocate MAX_XDS_FOR_TR_CALLS */
        usb_dev_ptr->G.XD_BASE = (XD_STRUCT_PTR) USB_mem_alloc_zero(sizeof(KHCI_XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);

        if (usb_dev_ptr->G.XD_BASE == NULL)
        {
            #if DEV_DEBUG
            printf("2 memalloc failed in _usb_device_init\n");
            #endif

            _mem_free(usb_dev_ptr);
            return USBERR_ALLOC;
        } /* Endif */

        /* Allocate memory for internal scratch structure */
        usb_dev_ptr->G.XD_SCRATCH_STRUCT_BASE = (SCRATCH_STRUCT_PTR) USB_mem_alloc_zero(sizeof(SCRATCH_STRUCT) * MAX_XDS_FOR_TR_CALLS);

        if (usb_dev_ptr->G.XD_SCRATCH_STRUCT_BASE == NULL)
        {
            #if DEV_DEBUG
            printf("3 memalloc failed in _usb_device_init\n");
            #endif

            _mem_free(usb_dev_ptr->G.XD_BASE);
            _mem_free(usb_dev_ptr);
            return USBERR_ALLOC;
        } /* Endif */

        usb_dev_ptr->G.TEMP_XD_PTR = (XD_STRUCT_PTR)USB_mem_alloc_zero(sizeof(KHCI_XD_STRUCT));
        if(usb_dev_ptr->G.TEMP_XD_PTR == NULL)
        {
            #ifdef _DEV_DEBUG
                printf("4 memalloc failed in _usb_device_init\n");
            #endif  
            _mem_free(usb_dev_ptr->G.XD_SCRATCH_STRUCT_BASE);
            _mem_free(usb_dev_ptr->G.XD_BASE);
            _mem_free(usb_dev_ptr);
            return USBERR_ALLOC;
        }

        usb_dev_ptr->G.XD_HEAD = NULL;
        usb_dev_ptr->G.XD_TAIL = NULL;
        usb_dev_ptr->G.XD_ENTRIES = 0;

        /* Enqueue all the XDs */   
        xd_ptr = (KHCI_XD_STRUCT_PTR) usb_dev_ptr->G.XD_BASE;
        temp_scratch_ptr = usb_dev_ptr->G.XD_SCRATCH_STRUCT_BASE;

        for (j = 0; j < MAX_XDS_FOR_TR_CALLS; j++) 
        {
           xd_ptr->G.SCRATCH_PTR = temp_scratch_ptr;
           xd_ptr->G.SCRATCH_PTR->FREE = _usb_device_free_XD;
           xd_ptr->G.SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
           _usb_device_free_XD(usb_dev_ptr,(pointer)xd_ptr);
           xd_ptr++;
           temp_scratch_ptr++;
        }

        *handle_ptr = (_usb_device_handle) usb_dev_ptr;
    }
    else { //NULL == usb_dev_ptr
        return USBERR_ALLOC;
    }

    return USB_OK;
}	


/**************************************************************************//*!
*
* @name        : _usb_dci_usbfs_init
* @brief       : Initializes the USB device controller.
* @param handle: USB device handle.
* @param init_param: initialization parameters specific for device
* @return   USB_OK on successful.
******************************************************************************/
USB_STATUS _usb_dci_usbfs_init
(
    /* [IN] the USB device handle */
    _usb_device_handle         handle
)
{
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR usb_dev_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;
    USB_KHCI_DEV_INIT_STRUCT_PTR       param = (USB_KHCI_DEV_INIT_STRUCT_PTR) usb_dev_ptr->G.INIT_PARAM;
    volatile USB_MemMapPtr             usb_ptr;

    if (usb_dev_ptr == NULL) {
        return USBERR_INVALID_DEVICE_NUM;
    }
    usb_dev_ptr->G.DEV_PTR = param->BASE_PTR;
    usb_dev_ptr->G.DEV_VEC = param->VECTOR;
    usb_dev_ptr->G.USB_STATE = USB_STATE_UNKNOWN;
   
    /* Get the maximum number of endpoints supported by this USB controller */
    usb_dev_ptr->G.MAX_ENDPOINTS = param->MAX_ENDPOINTS;

    /* Get the USB IP base address in the controller */
    usb_ptr = (USB_MemMapPtr) param->BASE_PTR;
    usb_dev_ptr->G.DEV_PTR = (pointer) usb_ptr;
    usb_dev_ptr->G.DEV_VEC = param->VECTOR;
//    usb_dev_ptr->G.PRIORITY = param->PRIORITY;

    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Install the ISR
     * Device Pointer is passed as an Argument when the
     * ISR is invoked.
     */
    if (!(USB_install_isr(usb_dev_ptr->G.DEV_VEC, (void (*)(void *))_usb_device_usbfs_isr, usb_dev_ptr)))
       return USBERR_INSTALL_ISR;

    /* Memory for BD is created by creating a data section "usb_bdt"
     * of 512 bytes in usbfs_dev_main.h. This memory is cleared here.
     */
    USB_mem_zero(bdt, sizeof(bdt));
    
    /* Initialize the end point state*/
    _usb_device_usbfs_reset_ep_state(usb_dev_ptr);
        
    /* Initialize BDT Page register 1,2,3. The Buffer
     * Descriptor Table Page Register 1 2,3 contains an
     * 8-bit value used to compute the address where
     * the current Buffer Descriptor Table (BDT)
     * resides in system memory.
     */
    usb_ptr->BDTPAGE1 = (uint_8)((uint_32)BDT_BASE >> 8);
    usb_ptr->BDTPAGE2 = (uint_8)((uint_32)BDT_BASE >> 16);
    usb_ptr->BDTPAGE3 = (uint_8)((uint_32)BDT_BASE >> 24);
    
    /* Clear all interrupts and bring it to finite
     * state before device starts functioning.
     */
    usb_ptr->ISTAT = ISTAT_CLEAR_ALL;
    
    /* Enable Sleep,Token Done,Error,USB Reset,Stall,
     * Resume and SOF Interrupt.
     */
    usb_ptr->INTEN = INTEN_BUS_RESET_VAL;
    
    /* Enable USB module*/
    usb_ptr->CTL = USB_CTL_USBENSOFEN_MASK;

    /* Remove suspend state */
    usb_ptr->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
    
    /* Enable D+ pull up register
     * Note, that this D+ external resistor is not applicable for some devices
    */
    usb_ptr->OTGCTL = USB_OTGCTL_DPHIGH_MASK |  USB_OTGCTL_OTGEN_MASK;

    return USB_OK;
}

/**************************************************************************//*!
* @name        : _usb_dci_usbfs_init_endpoint
*
* @brief       : Initialize the Endpoint
* @param handle: Handle to USB Device.
* @param xd_ptr: Transaction Discriptor.
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_init_endpoint
(
     /*[IN]*/
    _usb_device_handle handle, 
    /*[IN]*/
    XD_STRUCT_PTR xd_ptr
)
{
    USB_STATUS error = USB_OK;
    uint_8 ep_ctrl = 0;
    XD_STRUCT_PTR xd_temp_ptr;
    uint_16 max_pkt_size = 0;

    /* Get the device pointer initialized in _usb_dci_usbfs_init*/
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;
    volatile USB_MemMapPtr usb_ptr;

    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }

    
    if((xd_ptr->EP_TYPE > USB_INTERRUPT_PIPE) || 
        (xd_ptr->BDIRECTION > USB_SEND))
    {
        return USBERR_EP_INIT_FAILED;
    }
    
    if(state_ptr->EP_INFO[xd_ptr->EP_NUM].ep_init_flag[xd_ptr->BDIRECTION]
        == TRUE) 
    {/* If endpoint is already initialized, then deinitialize it before initializing it again */
        (void)_usb_dci_usbfs_deinit_endpoint(handle, xd_ptr->EP_NUM, 
            xd_ptr->BDIRECTION);
    }

    /* mark this endpoint as initialized */
    state_ptr->EP_INFO[xd_ptr->EP_NUM].ep_init_flag[xd_ptr->BDIRECTION] = TRUE;
        
    /*before initializing cancel all transfers on EP as there may be calls
     for endpoint initialization more than once. This will free any allocated
     queue*/

    /*
     * Since this is endpoint initialization section there will
     * not be any pending transfers on this endpoint
     */
    state_ptr->G.PENDING_XD_PTR = NULL;

    /* alloc XD for RECV ONLY and WSOFAR is zero*/
    if((xd_ptr->WSOFAR == 0)&&(!xd_ptr->BDIRECTION))
    {
        _usb_device_alloc_XD (state_ptr, &xd_temp_ptr);
        xd_temp_ptr->EP_NUM = xd_ptr->EP_NUM;
        xd_temp_ptr->BDIRECTION = xd_ptr->BDIRECTION;
        xd_temp_ptr->WTOTALLENGTH =xd_ptr->WTOTALLENGTH;
        xd_temp_ptr->WSOFAR = xd_ptr->WSOFAR;
        xd_temp_ptr->EP_TYPE = xd_ptr->EP_TYPE;
        xd_temp_ptr->DONT_ZERO_TERMINATE = xd_ptr->DONT_ZERO_TERMINATE;
    }

    /* Enable hand shaking at this endpoint if this is not an Isochronous
     * transfer
     */
    ep_ctrl |= (xd_ptr->EP_TYPE != USB_ISOCHRONOUS_PIPE ? USB_ENDPT_EPHSHK_MASK : 0);
        
    /* The end point buffer size will be set as required by app.
     * but if the size crosses MAX_EP_BUFFER_SIZE size then truncate the
     * max packet size.
     */
    max_pkt_size = (uint_16)((xd_ptr->WMAXPACKETSIZE > MAX_EP_BUFFER_SIZE)?
        MAX_EP_BUFFER_SIZE:xd_ptr->WMAXPACKETSIZE);
    
    /* Initialize the End Point Information Structure which is part of device
     * structure. It is done so that it can be used at later point of time
     * like ISR handler, any other function call.
     */
    state_ptr->EP_INFO[xd_ptr->EP_NUM].type = xd_ptr->EP_TYPE;
    state_ptr->EP_INFO[xd_ptr->EP_NUM].direction = xd_ptr->BDIRECTION;
    state_ptr->EP_INFO[xd_ptr->EP_NUM].max_packet_size = max_pkt_size;
    state_ptr->EP_INFO[xd_ptr->EP_NUM].endpoint_status = USB_STATUS_DISABLED;
    state_ptr->EP_INFO[xd_ptr->EP_NUM].stall_flag = FALSE;
    
    /* Write the initialized control values to end point control register*/
    usb_ptr->ENDPOINT[xd_ptr->EP_NUM].ENDPT |=  ep_ctrl;
    
    /*Configure this endpoint for receive or Send direction as reuired by APP*/
    usb_ptr->ENDPOINT[xd_ptr->EP_NUM].ENDPT |= (xd_ptr->BDIRECTION ? USB_ENDPT_EPTXEN_MASK: USB_ENDPT_EPRXEN_MASK);
    
    /* Set the BDT and buffer data pointer for Receive Direction*/
    if(USB_RECV == xd_ptr->BDIRECTION)
    {
        const uint_8 control[2] = { 
            USB_BD_DATA01(0) | USB_BD_DTS | USB_BD_OWN,
            USB_BD_DATA01(1) | USB_BD_DTS
        };

        /* Initialize the DATA PID to DATA0*/
        state_ptr->EP_INFO[xd_ptr->EP_NUM].rx_data0 = 0;
                            
        /* Allocate memory for both endpoint even and odd buffers*/
        state_ptr->EP_INFO[xd_ptr->EP_NUM].data_buffer =
            (uint_8_ptr)USB_mem_alloc_uncached_zero(2 * sizeof(uint_8) * max_pkt_size);
        
        if(state_ptr->EP_INFO[xd_ptr->EP_NUM].data_buffer == NULL)
        {
            #ifdef _DEV_DEBUG
                printf("malloc failed in _usb_dci_usbfs_init_endpoint for even and odd buffers\n");
            #endif  
            return USBERR_ALLOC;
        }
        
        /*Configure Even buff for the end point*/
        BD_ADDR_RX(xd_ptr->EP_NUM, 
            state_ptr->EP_INFO[xd_ptr->EP_NUM].rx_buf_odd) =
                LONG_LE_TO_HOST((uint_32)
                    state_ptr->EP_INFO[xd_ptr->EP_NUM].data_buffer);
        
        /* configure first start address for recv transaction */
        if((xd_ptr->WSOFAR == 0)&&(!xd_ptr->BDIRECTION))
        {
            xd_temp_ptr->WSTARTADDRESS = (uint_8_ptr) LONG_LE_TO_HOST(BD_ADDR_RX(xd_ptr->EP_NUM,
                state_ptr->EP_INFO[xd_ptr->EP_NUM].rx_buf_odd));
                /* Queue the XD taken from free list to End Point Info struncture*/
            USB_XD_QUEUE_ENQUEUE(&state_ptr->EP_INFO[xd_ptr->EP_NUM].xd_queue_recv, xd_temp_ptr);
        }

        BD_CTRL_RX(xd_ptr->EP_NUM, 
            state_ptr->EP_INFO[xd_ptr->EP_NUM].rx_buf_odd) =
                LONG_LE_TO_HOST((uint_32)(USB_BD_BC(max_pkt_size) | control[0]));
        
        /*Configure Even buff for odd end point*/
        BD_ADDR_RX(xd_ptr->EP_NUM, 
            state_ptr->EP_INFO[xd_ptr->EP_NUM].rx_buf_odd ^ 1) =
                LONG_LE_TO_HOST((uint_32)
                (state_ptr->EP_INFO[xd_ptr->EP_NUM].data_buffer + max_pkt_size));
        
        BD_CTRL_RX(xd_ptr->EP_NUM, 
            state_ptr->EP_INFO[xd_ptr->EP_NUM].rx_buf_odd ^ 1) =
                LONG_LE_TO_HOST((uint_32)(USB_BD_BC(max_pkt_size) | control[1]));
    }
    else /* Set the BDT and buffer data pointer for Send direction */
    {
        /* Initialize the DATA PID to DATA0*/
        state_ptr->EP_INFO[xd_ptr->EP_NUM].tx_data0 = 0;
        
        BD_CTRL_TX(xd_ptr->EP_NUM, 
            state_ptr->EP_INFO[xd_ptr->EP_NUM].tx_buf_odd) =
                LONG_LE_TO_HOST((uint_32)(USB_BD_BC(max_pkt_size) |
                    USB_BD_DATA01(0) | USB_BD_DTS));

        BD_CTRL_TX(xd_ptr->EP_NUM, 
            state_ptr->EP_INFO[xd_ptr->EP_NUM].tx_buf_odd ^ 1) =
                LONG_LE_TO_HOST((uint_32)(USB_BD_BC(max_pkt_size) | 
                    USB_BD_DATA01(1) | USB_BD_DTS));
     }
    return error;
}

/**************************************************************************//*!
* @name  : _usb_dci_usbfs_deinit_endpoint
*
* @brief       : De-Initialize the Endpoint
* @param handle: Handle to USB Device.
* @param ep_num: End Point Number.
* @param direction: USB_SEND or USB_RECV.
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_deinit_endpoint
(
     /*[IN]*/
    _usb_device_handle handle, 
    /*[IN]*/
    uint_8 ep_num,
    /*[IN]*/
    uint_8 direction 
)
{
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;
    volatile USB_MemMapPtr usb_ptr;
    
    if (state_ptr == NULL)
    {
        return USBERR_EP_DEINIT_FAILED;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_EP_DEINIT_FAILED;
    }

    /*before de-initializing cancel all transfers on EP */
    (void)_usb_device_cancel_transfer(handle, ep_num, direction);
    
    /*Disable the trasmit or receive endpoint*/
    usb_ptr->ENDPOINT[ep_num].ENDPT = EP_DISABLE;
    
    /* Free the Memory Allocated for Data buffers in endpoint number ep_num*/
    if ((direction == USB_RECV) && state_ptr->EP_INFO[ep_num].data_buffer)
    {
        USB_mem_free(state_ptr->EP_INFO[ep_num].data_buffer);
        state_ptr->EP_INFO[ep_num].data_buffer = NULL;
    }
    
    /* uninitialise the strucrure for this endpoint */
    BD_ADDR(ep_num,direction,EVEN_BUFF) =
        LONG_LE_TO_HOST_CONST((uint_32)USB_UNINITIALIZED_VAL_32);
    BD_ADDR(ep_num,direction,ODD_BUFF) =
        LONG_LE_TO_HOST_CONST((uint_32)USB_UNINITIALIZED_VAL_32);
    
    state_ptr->EP_INFO[ep_num].max_packet_size =    
        (uint_16)USB_UNINITIALIZED_VAL_32;

    /* mark this endpoint as de-initialized */
    state_ptr->EP_INFO[ep_num].ep_init_flag[direction] = FALSE;
        
    return USB_OK;
}

/**************************************************************************//*!
* @name  _usb_dci_usbfs_send
* @brief       : Sends data. Non-blocking.
* @param handle: Handle to USB Device.
* @param xd_ptr: Transaction Discriptor.
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_send
(
     /*[IN]*/
    _usb_device_handle handle, 
    /*[IN]*/
    XD_STRUCT_PTR xd_ptr 
)
{
    USB_STATUS error = USBERR_TX_FAILED;/* initializing to failed value */
    uint_32 buf_num_bytes = (uint_32)(xd_ptr->WTOTALLENGTH - xd_ptr->WSOFAR);
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;
    
    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Allocate XD stucutre from Free List maintained by Device strucutre,
     * if it is not any split transaction.
     */
    if (xd_ptr->WSOFAR == 0)
    {
        USB_XD_QUEUE_ENQUEUE(&state_ptr->EP_INFO[xd_ptr->EP_NUM].xd_queue_send, xd_ptr);
    }
    
    /* Upper layer wants to send Zero Packet data
     * Note that this situation will only come when
     * Upper layer wants to send Zero packet data not
     * in case of split transaction
     */
    if (buf_num_bytes == 0)
    {
        error = _usb_device_usbfs_ep_write(state_ptr, xd_ptr->EP_NUM,
            xd_ptr->WSTARTADDRESS, buf_num_bytes, (uint_32*)&buf_num_bytes);
        
        if (error != USB_OK)
        {
            /* If write returns error release the XD pointer
             * from Endpoint send queue and return it to Free list of XD pointers.
             */
            xd_ptr->BSTATUS = USB_STATUS_IDLE;
            USB_XD_QUEUE_DEQUEUE (&state_ptr->EP_INFO[xd_ptr->EP_NUM].xd_queue_send, &xd_ptr);
            if (xd_ptr != NULL)
            _usb_device_free_XD(state_ptr, xd_ptr);
            //_usb_device_free_XD(xd_ptr);
        }
        return error;
    }
    
    /* If not Zero Size packet send the data from here*/
    error = _usb_device_usbfs_ep_write(state_ptr, xd_ptr->EP_NUM,
        (uint_8_ptr)xd_ptr->WSTARTADDRESS + xd_ptr->WSOFAR, buf_num_bytes,
        (uint_32*)&buf_num_bytes);
    
    if (error != USB_OK)
    {
        /* If write returns error release the XD pointer
         * from Endpoint send queue and return it to Free list of XD pointers.
         */
        xd_ptr->BSTATUS = USB_STATUS_IDLE;
        USB_XD_QUEUE_DEQUEUE (&state_ptr->EP_INFO[xd_ptr->EP_NUM].xd_queue_send, &xd_ptr);
        if (xd_ptr != NULL)
            _usb_device_free_XD(state_ptr, xd_ptr);
    }   
    return error;
}

/**************************************************************************//*!
* @name        : _usb_dci_usbfs_recv
* @brief       : Receives data. Non-blocking.
* @param handle: Handle to USB Device.
* @param xd_ptr: Transaction Discriptor.
* @return      : USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_recv
(
     /*[IN]*/
    _usb_device_handle handle, 
    /*[IN]*/
    XD_STRUCT_PTR xd_ptr 
)
{
    USB_STATUS error = USBERR_RX_FAILED;/* initializing to failed value */
    uint_32 buf_num_bytes;
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;
    
    if ((state_ptr == NULL) || (xd_ptr == NULL))
    {
        return USBERR_ERROR;
    }
    
    buf_num_bytes = xd_ptr->WTOTALLENGTH - xd_ptr->WSOFAR;
    
    /* Allocate XD stucutre from Free List maintained by Device strucutre,
     * if it is not any split transaction.
     */
    if (xd_ptr->WSOFAR == 0)
    {
        USB_XD_QUEUE_ENQUEUE(&state_ptr->EP_INFO[xd_ptr->EP_NUM].xd_queue_recv, xd_ptr);
    }

    /* If the number of bytes to be received is greater than the
     * maximum data that can be received on the USB bus, then split the
     * transaction into multiple receive transaction.
     */
    if (buf_num_bytes > state_ptr->EP_INFO[xd_ptr->EP_NUM].max_packet_size)
    {
        buf_num_bytes = state_ptr->EP_INFO[xd_ptr->EP_NUM].max_packet_size;
    }
    
    /* Send the receiv command to the device.*/
    error = _usb_device_usbfs_ep_read(handle, xd_ptr->EP_NUM,
        (uint_8_ptr)((uint_32)xd_ptr->WSTARTADDRESS + (uint_32)xd_ptr->WSOFAR),
        buf_num_bytes);
    
    if (error != USB_OK)
    {
        USB_XD_QUEUE_DEQUEUE(&state_ptr->EP_INFO[xd_ptr->EP_NUM].xd_queue_recv, &xd_ptr);
    }
    
    return error;
}

/**************************************************************************//*!*
* @name  : _usb_dci_usbfs_stall_endpoint
* @brief      : Stalls the specified endpoint
* @param handle: Handle to USB Device.
* @param ep_num: End Point Number.
* @param direction: USB_SEND or USB_RECV.
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_stall_endpoint
(
     /*[IN]*/
    _usb_device_handle handle, 
    /*[IN]*/
    uint_8 ep_num, 
    /*[IN]*/
    uint_8 direction
)
{
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;
    USB_MemMapPtr usb_ptr;

    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr = (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* set  the stall flag in device structure to be true */
    state_ptr->EP_INFO[ep_num].stall_flag = TRUE;
    
    /* retiring pending IRPs on stall detection */
    (void)_usb_device_cancel_transfer(handle,ep_num,direction);
    
    /* If Stall is for Send packet update Send BDT */
    if (direction)
    {/* USB_SEND */
        BD_CTRL_TX(ep_num, state_ptr->EP_INFO[ep_num].tx_buf_odd) =
            LONG_LE_TO_HOST((uint_32)(USB_BD_BC(state_ptr->EP_INFO[ep_num].
                max_packet_size)| USB_BD_OWN | USB_BD_STALL | USB_BD_DTS));
    }
    else
    {/* USB_RECV */
        /* If Stall is for Receive transaction, Update Recevice BDT*/
        BD_CTRL_RX(ep_num, state_ptr->EP_INFO[ep_num].rx_buf_odd) =
            LONG_LE_TO_HOST((uint_32)(USB_BD_BC(state_ptr->EP_INFO[ep_num].
                max_packet_size) | USB_BD_OWN | USB_BD_STALL | USB_BD_DTS));
    }
    
    /* Continue Further processing as the IP stops on receiving
     * Setup Token.
     */
    usb_ptr->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
    
    return USB_OK;
}

/**************************************************************************//*!*
* @name  : _usb_dci_usbfs_unstall_endpoint
* @brief       : Unstall the Endpoint in specific direction
* @param handle: Handle to USB Device.
* @param ep_num: End Point Number.
* @param direction: USB_SEND or USB_RECV.
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_unstall_endpoint
(
     /*[IN]*/
    _usb_device_handle handle, 
    /*[IN]*/
    uint_8 ep_num, 
    /*[IN]*/
    uint_8 direction 
)
{
    XD_STRUCT_PTR xd_ptr_temp;
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;
    USB_MemMapPtr usb_ptr;
    
    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr = (USB_MemMapPtr) state_ptr->G.DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* clear  the stall flag in device structure */
    state_ptr->EP_INFO[ep_num].stall_flag = FALSE;
    
    usb_ptr->ENDPOINT[ep_num].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
    if (direction)
    {/* USB_SEND */      
        usb_ptr->ENDPOINT[ep_num].ENDPT |= 
            (USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPTXEN_MASK);
        BD_CTRL_TX(ep_num, state_ptr->EP_INFO[ep_num].tx_buf_odd) =
            LONG_LE_TO_HOST((uint_32)(USB_BD_BC(state_ptr->EP_INFO[ep_num].max_packet_size) |
            USB_BD_DTS | USB_BD_DATA01(0)));
    }
    else
    {/* USB_RECV */
        usb_ptr->ENDPOINT[ep_num].ENDPT |= 
            (USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK);
        /* prepare XD queue for RECV CONTROL ENDPOINT*/
        _usb_device_alloc_XD (state_ptr, &xd_ptr_temp);
        xd_ptr_temp->EP_NUM = ep_num;
        xd_ptr_temp->BDIRECTION = USB_RECV;
        xd_ptr_temp->WTOTALLENGTH = ZERO_LENGTH;
        xd_ptr_temp->EP_TYPE = state_ptr->EP_INFO[ep_num].type;
        xd_ptr_temp->DONT_ZERO_TERMINATE = TRUE;
        
        /* Enqueue the Prepared XD to the receive queue*/
        USB_XD_QUEUE_ENQUEUE(&state_ptr->EP_INFO[ep_num].xd_queue_recv, xd_ptr_temp);
        
        BD_CTRL_RX(ep_num, state_ptr->EP_INFO[ep_num].rx_buf_odd) =
            LONG_LE_TO_HOST((uint_32)(USB_BD_BC(state_ptr->EP_INFO[ep_num].max_packet_size) |
                USB_BD_OWN | USB_BD_DTS | USB_BD_DATA01(0)));
    }

    usb_ptr->CTL &= (~ USB_CTL_TXSUSPENDTOKENBUSY_MASK);
    return USB_OK;
}

/**************************************************************************//*!*
* @name  : _usb_dci_usbfs_cancel
* @brief : Cancels all pending transfers on an endpoint.
* @param handle: Handle to USB Device.
* @param ep_num: End Point Number.
* @param direction: USB_SEND or USB_RECV.
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_cancel
(
     /*[IN]*/
    _usb_device_handle handle,
    /*[IN]*/
    uint_8 ep_num, 
    /*[IN]*/
    uint_8 direction 
)
{
    volatile XD_STRUCT_PTR xd_temp_ptr;
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;

    if (state_ptr == NULL)
    {
       return USBERR_ERROR;
    }

    /* Empty the queue and add the XD release stucture to the Free list*/
    do
    {
        if(direction)
        {
            USB_XD_QUEUE_DEQUEUE(&state_ptr->EP_INFO[ep_num].xd_queue_send, &xd_temp_ptr);
            
            if(xd_temp_ptr)
            {
                xd_temp_ptr->BSTATUS = USB_STATUS_IDLE;
                if (xd_temp_ptr != NULL)
                _usb_device_free_XD(state_ptr, xd_temp_ptr);
                //_usb_device_free_XD(xd_temp_ptr);
            }
        }
        else
        {
            USB_XD_QUEUE_DEQUEUE(&state_ptr->EP_INFO[ep_num].xd_queue_recv, &xd_temp_ptr);
            
            if(xd_temp_ptr)
            {
                xd_temp_ptr->BSTATUS = USB_STATUS_IDLE;
                if (xd_temp_ptr != NULL)
                _usb_device_free_XD(state_ptr, xd_temp_ptr);
                //_usb_device_free_XD(xd_temp_ptr);
            }
        }
    }
    while (xd_temp_ptr);

    return USB_OK;
}

/**************************************************************************//*!*
* @name  : _usb_dci_usbfs_set_addr
* @brief       : Set device address.
* @param handle : Device handle.
* @param addr :   Address to be set into Device Address register.
* @return     :   Returns USB_OK or error code.
******************************************************************************/
USB_STATUS _usb_dci_usbfs_set_addr
(
     /*[IN]*/
    _usb_device_handle handle, 
    /*[IN]*/
    uint_8 addr
)
{
    volatile USB_DEV_STATE_STRUCT_PTR state_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
    volatile USB_MemMapPtr usb_ptr;

    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }

    if (addr)
    {
        /* Update USB address in Device registers. This 7-bit value
         * defines the USB address that the USB Module decodes
         * in device mode
         */
        usb_ptr->ADDR = addr;
        /* Update the USB device address in Device Info Strucutre for
         * Future Referances.
         */
        state_ptr->DEVICE_ADDRESS = addr;
        /* Set the Device Start as Address Asigned State.*/
        ((USB_DEV_STATE_STRUCT_PTR)handle)->USB_STATE = USB_STATE_ADDRESS;
    }
    return USB_OK;
}

/**************************************************************************//*!*
* @name : _usb_dci_usbfs_shutdown
* @brief      : Shuts down the usbfs Device Controller
*                   Note: There is no function in MQX to uninstall ISR.
*                         Hence ISR is not Uninstalled here.However, installing
*                         ISR twice will not have any negative impact.
* @param handle : Device handle.
* @return     :   Returns USB_OK or error code.
******************************************************************************/
USB_STATUS _usb_dci_usbfs_shutdown
(
     /*[IN]*/
    _usb_device_handle handle 
)
{
    volatile USB_DEV_STATE_STRUCT_PTR state_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
    volatile USB_MemMapPtr usb_ptr;

    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }

    /* Reset the Control Register */
    usb_ptr->CTL = 0; /* disables the USB MODULE */

    (void)_usb_device_set_status(handle, (uint_8)USB_STATUS_DEVICE_STATE,
        (uint_16)USB_STATE_UNKNOWN);

    return USB_OK;
}

/**************************************************************************//*!*
* @name : _usb_dci_usbfs_get_setup_data
* @brief       : Reads the Setup data from the 8-byte setup buffer
* @param handle: Handle to USB Device.
* @param ep_num: End Point Number.
* @param buffer_ptr: Buffer Pointer holding output Data..
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_get_setup_data
(
     /*[IN]*/
    _usb_device_handle handle, 
     /*[IN]*/
    uint_8 ep_num,
    /*[OUT]*/
    uchar_ptr buffer_ptr
)
{
    uint_8 loop_index=0;
    volatile uint_8_ptr addr;
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;

    if (state_ptr == NULL)
    {
       return USBERR_ERROR;
    }
    
    if (buffer_ptr == NULL)
    {
       return USBERR_ERROR;
    }
    
    /* address correponding to the endpoint tbuffers */
    addr = (uint_8_ptr) LONG_LE_TO_HOST(
        BD_ADDR_RX(ep_num, state_ptr->EP_INFO[ep_num].rx_buf_odd));
    
    /* copy bdt buffer to application buffer */
    for(loop_index = 0; loop_index < USB_SETUP_PKT_SIZE; loop_index++)
    {
        buffer_ptr[loop_index]=addr[loop_index];
    }
    
    *((uint_16*)&buffer_ptr[2]) = SHORT_LE_TO_HOST(*((uint_16*)&buffer_ptr[2]));
    *((uint_16*)&buffer_ptr[4]) = SHORT_LE_TO_HOST(*((uint_16*)&buffer_ptr[4]));
    *((uint_16*)&buffer_ptr[6]) = SHORT_LE_TO_HOST(*((uint_16*)&buffer_ptr[6]));

    return USB_OK;
}

/**************************************************************************//*!*
* @name  : _usb_dci_usbfs_assert_resume
* @brief : Resume signalling for remote wakeup
* @param handle: Handle to USB Device.
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_assert_resume
(
     /*[IN]*/
    _usb_device_handle handle 
)
{
    uint_16 delay_count;
    volatile USB_MemMapPtr usb_ptr;
    volatile USB_DEV_STATE_STRUCT_PTR state_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
    
    if (state_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }
    
    /* clear resume FLAG*/
    usb_ptr->ISTAT = USB_ISTAT_RESUME_MASK;

    /* Disable RESUME Interrupt */
//    usb_ptr->INTEN &= ~USB_INTEN_RESUME_EN_MASK; //already done in RESUME interrupt

    /* continue processing */
    usb_ptr->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;

    /* Start RESUME signaling and make SUSPEND bit 0*/
    usb_ptr->CTL |= USB_CTL_RESUME_MASK;

    /* Set RESUME line for 1-15 ms*/
    delay_count = ASSERT_RESUME_DELAY_COUNT;
    do
    {
       delay_count--;
    } while(delay_count);

    /* Stop RESUME signalling */
    usb_ptr->CTL &= ~USB_CTL_RESUME_MASK;

    return USB_OK;
}

/**************************************************************************//*!*
* @name : _usb_dci_usbfs_get_endpoint_status
* @brief : Get Endpoint Transfer Status
* @param handle: Handle to USB Device.
* @param component: End Point Number.
* @param endp_status: Variable containig endpint status..
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_get_endpoint_status
(
     /*[IN]*/
    _usb_device_handle handle,
     /*[IN]*/
    uint_8 component,
    /*[OUT]*/
    uint_16_ptr endp_status
)
{
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR)handle;

    if (state_ptr == NULL)
    {
        return USBERR_ERROR;    
    }       

    *endp_status = state_ptr->EP_INFO[component].endpoint_status;
    return USB_OK;
}

/**************************************************************************//*!*
* @name  : _usb_dci_usbfs_set_endpoint_status
* @brief   : Set Endpoint Transfer Status
* @param handle: Handle to USB Device.
* @param component: End Point Number.
* @param setting: Variable containing new settings..
* @return      :  USB_OK or error code
******************************************************************************/
USB_STATUS _usb_dci_usbfs_set_endpoint_status
(
     /*[IN]*/
    _usb_device_handle handle,
     /*[IN]*/
    uint_8 component,
     /*[IN]*/
    uint_16 setting
)
{
    volatile USB_KHCI_DEV_STATE_STRUCT_PTR state_ptr = (USB_KHCI_DEV_STATE_STRUCT_PTR) handle;
    USB_STATUS error = USBERR_ERROR;/* initializing */
    uint_8 ep_num = (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK);
    /* direction is in most significant bit */
    uint_8 direction = (uint_8)((component>>COMPONENT_PREPARE_SHIFT) & 0x01);

    if (state_ptr == NULL)
    {
        return error;
    }

    if (ep_num > USB_MAX_ENDPOINTS) {
        return error;
    }
    
    state_ptr->EP_INFO[ep_num].endpoint_status = setting;
    
    /* check if the setting was to halt endpoint or unhalt it*/
    if(setting == USB_STATUS_STALLED)
    {   /* stall the endpoint */
        error = _usb_device_stall_endpoint(handle,ep_num,direction);
    }
    else if((setting == USB_STATUS_IDLE) && (state_ptr->EP_INFO[ep_num].stall_flag == TRUE))
    {   /* unstall the endpoint*/
        /* need to update the direction here for unstalling
        (as it was not passed from above layers for unstall because the
         STAT register doesn't get updated in STALL ISR and we need to unstall
         directly from STALL_SERVICE for CONTROL ENDPOINT. Therefore, this
         method of unstall was employed to make the structure generic)*/
        direction = state_ptr->EP_INFO[ep_num].direction;
        error = _usb_device_unstall_endpoint(handle,ep_num,direction);
    }

    return error;
}

/**************************************************************************//*!
 *
 * @name  _usb_dci_usbfs_get_transfer_status
 *
 * @brief The function retrieves the Transfer status of an endpoint
 *
 * @param handle
 * @param ep_num       : endpoint number
 * @param direction    : direction of endpoint
 *
 * @return error
 *         USB_STATUS_IDLE                 : No transfer on endpoint
 *         USB_STATUS_DISABLED             : endpoint is disabled
 *         USB_STATUS_STALLED              : endpoint is stalled
 *         USB_STATUS_TRANSFER_IN_PROGRESS : When SIE has control of BDT
 ******************************************************************************
 *
 * This function retrieves the transfer status of the endpoint by checking the
 * BDT as well as the endpoint control register
 *
 *****************************************************************************/
USB_STATUS _usb_dci_usbfs_get_transfer_status
(
     /*[IN]*/
    _usb_device_handle handle,
     /*[IN]*/
    uint_8 ep_num,
     /*[IN]*/
    uint_8 direction
)
{
    USB_STATUS error = USB_STATUS_DISABLED;
    volatile USB_MemMapPtr usb_ptr;
    volatile USB_DEV_STATE_STRUCT_PTR state_ptr = (USB_DEV_STATE_STRUCT_PTR) handle;

    if (state_ptr == NULL)
    {
        return USBERR_ERROR;    
    }       

    /* Get the USB IP base address in the controller */
    usb_ptr =  (USB_MemMapPtr) state_ptr->DEV_PTR;
    if (usb_ptr == NULL)
    {
        return USBERR_ERROR;
    }

    if(ep_num < USB_MAX_ENDPOINTS)
    {
        uint_8 ep_control = usb_ptr->ENDPOINT[ep_num].ENDPT;

        error = USB_STATUS_IDLE;
        
        /* Check for direction in endpoint control register */
        if((ep_control & (USB_ENDPT_EPTXEN_MASK |
            USB_ENDPT_EPRXEN_MASK)) == EP_DISABLE)
        {
            error = USB_STATUS_DISABLED;
        }
        /* Check for stall bit in endpoint control register */
        else if ((ep_control &  USB_ENDPT_EPSTALL_MASK) ==
            USB_ENDPT_EPSTALL_MASK)
        {
            error = USB_STATUS_STALLED ;
        }
        /* Check whether SIE has control of BDT */
        else if((LONG_LE_TO_HOST(BD_CTRL(ep_num,direction,EVEN_BUFF)) & USB_BD_OWN) ||
            (LONG_LE_TO_HOST(BD_CTRL(ep_num,direction,ODD_BUFF)) & USB_BD_OWN))
        {
            error = USB_STATUS_TRANSFER_IN_PROGRESS;
        }
    }
    return error;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/TSS/shared/TSS_StatusCodes.h<|end_filename|>
/**********************************************************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2006-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
********************************************************************************************************************//*!
*
* @file   TSS_StatusCodes.h
*
* @brief  Header file that defines the Return Status Codes used by the TSS Library
*
* @version 1.0.32.0
* 
* @date Sep-12-2012
* 
* These Return Status Codes are used by the User Application Level and also internally in the Library
*
***********************************************************************************************************************/


#ifndef TSS_STATUSCODES_H
  #define TSS_STATUSCODES_H

  /* TSS Task & TSS Init Status Codes */
  #define TSS_STATUS_OK                           0u
  #define TSS_STATUS_PROCESSING                   1u
  #define TSS_STATUS_RECALIBRATION_FAULT          2u

  /* Sample Electrode Commands */
  #define TSS_SAMPLE_COMMAND_DUMMY                0x00u   /* Command for SampleElectrode function */
  #define TSS_SAMPLE_COMMAND_RESTART              0x01u   /* Command for SampleElectrode function */
  #define TSS_SAMPLE_COMMAND_PROCESS              0x02u   /* Command for SampleElectrode function */        
  #define TSS_SAMPLE_COMMAND_RECALIB              0x03u   /* Command for SampleElectrode function */        
  #define TSS_SAMPLE_COMMAND_GET_NEXT_ELECTRODE   0x04u   /* Command for SampleElectrode function */        
  #define TSS_SAMPLE_COMMAND_ENABLE_ELECTRODE     0x05u   /* Command for SampleElectrode function */        

  /* Sample Electrode Status Codes */
  #define TSS_SAMPLE_STATUS_OK                    0x00u   /* Return value from the SampleElectrode function */
  #define TSS_SAMPLE_STATUS_PROCESSING            0x01u   /* Return value from the SampleElectrode function */
  #define TSS_SAMPLE_STATUS_CALIBRATION_CHANGED   0x02u   /* Return value from the SampleElectrode function */
  #define TSS_SAMPLE_RECALIB_REQUEST_LOCAP        0x03u   /* Return value from the SampleElectrode function */
  #define TSS_SAMPLE_RECALIB_REQUEST_HICAP        0x04u   /* Return value from the SampleElectrode function */
  #define TSS_SAMPLE_ERROR_SMALL_TRIGGER_PERIOD   0x05u   /* Return value from the SampleElectrode function */
  #define TSS_SAMPLE_ERROR_CHARGE_TIMEOUT         0x06u   /* Return value from the SampleElectrode function */
  #define TSS_SAMPLE_ERROR_SMALL_CAP              0x07u   /* Return value from the SampleElectrode function */
  #define TSS_SAMPLE_ERROR_SMALL_AUTOTRG_PERIOD   TSS_SAMPLE_ERROR_SMALL_TRIGGER_PERIOD

  /* Sensor Init Commands Commands */
  #define TSS_INIT_COMMAND_DUMMY                  0x00u   /* Command for SensorInit function */
  #define TSS_INIT_COMMAND_INIT_MODULES           0x01u   /* Command for SensorInit function */        
  #define TSS_INIT_COMMAND_ENABLE_ELECTRODES      0x02u   /* Command for SensorInit function */        
  #define TSS_INIT_COMMAND_SET_NSAMPLES           0x03u   /* Command for SensorInit function */        
  #define TSS_INIT_COMMAND_INIT_TRIGGER           0x04u   /* Command for SensorInit function */        
  #define TSS_INIT_COMMAND_SW_TRIGGER             0x05u   /* Command for SensorInit function */        
  #define TSS_INIT_COMMAND_INIT_LOWPOWER          0x06u   /* Command for SensorInit function */        
  #define TSS_INIT_COMMAND_GOTO_LOWPOWER          0x07u   /* Command for SensorInit function */        
  #define TSS_INIT_COMMAND_RECALIBRATE            0x08u   /* Command for SensorInit function */        

  /* Sensor Init Return Codes */
  #define TSS_INIT_STATUS_OK                      0x00u   /* Return values from SensorInit function */
  #define TSS_INIT_STATUS_LOWPOWER_SET            0x01u   /* Return values from SensorInit function */
  #define TSS_INIT_STATUS_LOWPOWER_ELEC_SET       0x02u   /* Return values from SensorInit function */
  #define TSS_INIT_STATUS_TRIGGER_SET             0x04u   /* Return values from SensorInit function */
  #define TSS_INIT_STATUS_AUTOTRIGGER_SET         0x08u   /* Return values from SensorInit function */
  #define TSS_INIT_STATUS_CALIBRATION_CHANGED     0x10u   /* Return values from SensorInit function */
  #define TSS_INIT_ERROR_RECALIB_FAULT            0x20u   /* Return values from SensorInit function */

  /* Decoder Commands */
  #define TSS_DECODER_COMMAND_DUMMY               0x00u   /* Command for Decoder function */
  #define TSS_DECODER_COMMAND_PROCESS             0x01u   /* Command for Decoder function */        
  #define TSS_DECODER_COMMAND_GET_TOUCH_STATUS    0x02u   /* Command for Decoder function */        
  #define TSS_DECODER_COMMAND_GET_IDLE_SCAN_RATE  0x03u   /* Command for Decoder function */        
  #define TSS_DECODER_COMMAND_INIT                0x04u   /* Command for Decoder function */         
  #define TSS_DECODER_COMMAND_GET_ENABLE_STATUS   0x05u   /* Command for Decoder function */
  #define TSS_DECODER_COMMAND_GET_THRSHLD_RATIO   0x06u   /* Command for Decoder function */

  /* Decoder Return Codes */
  #define TSS_DECODER_STATUS_OK                   0x00u   /* Return values from Decoder function */
  #define TSS_DECODER_STATUS_TOUCHED              0x01u   /* Return values from Decoder function */
  #define TSS_DECODER_ERROR_ILLEGAL_CONTROL_TYPE  0x02u   /* Return values from Decoder function */
  #define TSS_DECODER_STATUS_BUSY                 0x03u   /* Return values from Decoder function */
  #define TSS_DECODER_STATUS_ENABLED              0x04u   /* Return values from Decoder function */

  /* Key Detector Status Codes */
  #define TSS_KEYDETECT_STATUS_OK                 0x00u   /* Return value from the KeyDetector function */
  #define TSS_KEYDETECT_STATUS_PROCESSING         0x01u   /* Return value from the KeyDetector function */
  #define TSS_KEYDETECT_ERROR_LARGE_CAP           0x02u   /* Return value from the KeyDetector function */
  #define TSS_KEYDETECT_ERROR_SMALL_CAP           0x04u   /* Return value from the KeyDetector function */        
  #define TSS_KEYDETECT_ERROR_SMALL_TRIGGER_VAL   0x08u   /* Return value from the KeyDetector function */
  #define TSS_KEYDETECT_STATUS_DECODER_BUSY       0x10u   /* Return value from the KeyDetector function */
  #define TSS_KEYDETECT_STATUS_TRIGGER_WAIT       0x20u   /* Return value from the KeyDetector function */
  #define TSS_KEYDETECT_STATUS_PROXIMITY_WAIT     0x40u   /* Return value from the KeyDetector function */

  /* Keypad Decoder Config Status Codes */
  #define TSS_ERROR_KEYPAD_NOT_IDLE               0x11u   /* Return values from the KeyPadConfig function */
  #define TSS_ERROR_KEYPAD_ILLEGAL_PARAMETER      0x12u   /* Return values from the KeyPadConfig function */
  #define TSS_ERROR_KEYPAD_READ_ONLY_PARAMETER    0x13u   /* Return values from the KeyPadConfig function */
  #define TSS_ERROR_KEYPAD_OUT_OF_RANGE           0x14u   /* Return values from the KeyPadConfig function */
  #define TSS_ERROR_KEYPAD_ILLEGAL_CONTROL_TYPE   0x15u   /* Return values from the KeyPadConfig function */

  /* Slider Decoder Config Status Codes */
  #define TSS_ERROR_SLIDER_NOT_IDLE               0x21u   /* Return values from the TSS_SliderConfig function */
  #define TSS_ERROR_SLIDER_ILLEGAL_PARAMETER      0x22u   /* Return values from the TSS_SliderConfig function */
  #define TSS_ERROR_SLIDER_READ_ONLY_PARAMETER    0x23u   /* Return values from the TSS_SliderConfig function */
  #define TSS_ERROR_SLIDER_OUT_OF_RANGE           0x24u   /* Return values from the TSS_SliderConfig function */
  #define TSS_ERROR_SLIDER_ILLEGAL_CONTROL_TYPE   0x25u   /* Return values from the TSS_SliderConfig function */

  /* Rotary Decoder Config Status Codes */
  #define TSS_ERROR_ROTARY_NOT_IDLE               TSS_ERROR_SLIDER_NOT_IDLE
  #define TSS_ERROR_ROTARY_ILLEGAL_PARAMETER      TSS_ERROR_SLIDER_ILLEGAL_PARAMETER
  #define TSS_ERROR_ROTARY_READ_ONLY_PARAMETER    TSS_ERROR_SLIDER_READ_ONLY_PARAMETER
  #define TSS_ERROR_ROTARY_OUT_OF_RANGE           TSS_ERROR_SLIDER_OUT_OF_RANGE
  #define TSS_ERROR_ROTARY_ILLEGAL_CONTROL_TYPE   TSS_ERROR_SLIDER_ILLEGAL_CONTROL_TYPE

  /* Analog Slider Decoder Config Status Codes */
  #define TSS_ERROR_ASLIDER_NOT_IDLE              0x31u   /* Return values from the TSS_ASliderConfig function */
  #define TSS_ERROR_ASLIDER_ILLEGAL_PARAMETER     0x32u   /* Return values from the TSS_ASliderConfig function */
  #define TSS_ERROR_ASLIDER_READ_ONLY_PARAMETER   0x33u   /* Return values from the TSS_ASliderConfig function */
  #define TSS_ERROR_ASLIDER_ILEGAL_VALUE          0x34u   /* Return values from the TSS_ASliderConfig function */
  #define TSS_ERROR_ASLIDER_OUT_OF_RANGE          0x35u   /* Return values from the TSS_ASliderConfig function */
  #define TSS_ERROR_ASLIDER_ILLEGAL_CONTROL_TYPE  0x36u   /* Return values from the TSS_ASliderConfig function */

  /* Analog Rotary Decoder Config Status Codes */
  #define TSS_ERROR_AROTARY_NOT_IDLE              TSS_ERROR_ASLIDER_NOT_IDLE
  #define TSS_ERROR_AROTARY_ILLEGAL_PARAMETER     TSS_ERROR_ASLIDER_ILLEGAL_PARAMETER
  #define TSS_ERROR_AROTARY_READ_ONLY_PARAMETER   TSS_ERROR_ASLIDER_READ_ONLY_PARAMETER
  #define TSS_ERROR_AROTARY_ILLEGAL_VALUE         TSS_ERROR_ASLIDER_ILEGAL_VALUE 
  #define TSS_ERROR_AROTARY_OUT_OF_RANGE          TSS_ERROR_ASLIDER_OUT_OF_RANGE
  #define TSS_ERROR_AROTARY_ILLEGAL_CONTROL_TYPE  TSS_ERROR_ASLIDER_ILLEGAL_CONTROL_TYPE 

  /* Matrix Decoder Config Status Codes */
  #define TSS_ERROR_MATRIX_NOT_IDLE               0x41u   /* Return values from the TSS_MatrixConfig function */
  #define TSS_ERROR_MATRIX_ILLEGAL_PARAMETER      0x42u   /* Return values from the TSS_MatrixConfig function */
  #define TSS_ERROR_MATRIX_READ_ONLY_PARAMETER    0x43u   /* Return values from the TSS_MatrixConfig function */
  #define TSS_ERROR_MATRIX_ILEGAL_VALUE           0x44u   /* Return values from the TSS_MatrixConfig function */
  #define TSS_ERROR_MATRIX_OUT_OF_RANGE           0x45u   /* Return values from the TSS_MatrixConfig function */
  #define TSS_ERROR_MATRIX_ILLEGAL_CONTROL_TYPE   0x46u   /* Return values from the TSS_MatrixConfig function */

  /* System Config & Mgnt Status Codes */
  #define TSS_ERROR_CONFSYS_NOT_IDLE              0x01u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_ILLEGAL_PARAMETER     0x02u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_READ_ONLY_PARAMETER   0x03u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_OUT_OF_RANGE          0x04u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_LOWPOWER_SOURCE_NA    0x05u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_INCORRECT_LOWPOWER_EL 0x06u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_TRIGGER_SOURCE_NA     0x07u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_PROXIMITY_CALLBACK_NA 0x08u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_RECALIBRATION_FAULT   0x09u   /* Return values from the TSS_SetSystemConfig function */
  #define TSS_ERROR_CONFSYS_SHIELD_NA             0x0Au   /* Return values from the TSS_SetSystemConfig function */
 
#endif /* TSS_STATUSCODES_H */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/cm/cm_kinetis.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: cm_kinetis.h$
* $Version : 3.8.2.0$
* $Date    : Aug-29-2011$
*
* Comments:
*   Clock manager Kinetis specific definitions.
*
*END************************************************************************/

#ifndef __cm_kinetis_h__
    #define __cm_kinetis_h__

#ifdef __cplusplus
extern "C" {
#endif

#ifndef PE_LDD_VERSION
    
typedef struct  {
    uint32_t cpu_core_clk_hz;            /* Core clock frequency in clock configuration */       
    uint32_t cpu_bus_clk_hz;             /* Bus clock frequency in clock configuration */
    uint32_t cpu_flexbus_clk_hz;         /* Flexbus clock frequency in clock configuration */
    uint32_t cpu_flash_clk_hz;           /* FLASH clock frequency in clock configuration */
    uint32_t cpu_usb_clk_hz;             /* USB clock frequency in clock configuration */
    uint32_t cpu_pll_fll_clk_hz;         /* PLL/FLL clock frequency in clock configuration */
    uint32_t cpu_mcgir_clk_hz;           /* MCG internal reference clock frequency in clock configuration */
    uint32_t cpu_oscer_clk_hz;           /* System OSC external reference clock frequency in clock configuration */
    uint32_t cpu_erclk32k_clk_hz;        /* External reference clock 32k frequency in clock configuration */
    uint32_t cpu_mcgff_clk_hz;           /* MCG fixed frequency clock */
} TCpuClockConfiguration;
    
#endif  /* PE_LDD_VERSION */

typedef enum  {
    CM_CLOCK_SOURCE_CORE = 0,
    CM_CLOCK_SOURCE_BUS,
    CM_CLOCK_SOURCE_FLEXBUS,
    CM_CLOCK_SOURCE_FLASH,
    CM_CLOCK_SOURCE_USB,
    CM_CLOCK_SOURCE_PLLFLL,
    CM_CLOCK_SOURCE_MCGIR,
    CM_CLOCK_SOURCE_OSCER,
    CM_CLOCK_SOURCE_ERCLK32K,
    CM_CLOCK_SOURCE_MCGFF,
    CM_CLOCK_SOURCES,            /* Number of clock sources available */
    CM_CLOCK_SOURCE_SYSTEM = CM_CLOCK_SOURCE_CORE
} CM_CLOCK_SOURCE;

#ifdef __cplusplus
}
#endif


#endif /* __cm_kinetis_h__ */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_gate.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_gate.c$
* $Version : 3.7.8.0$
* $Date    : Feb-24-2011$
*
* Comments:
*
*   Example using RTCS Library.
*
*END************************************************************************/

#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include "sh_rtcs.h"



/*TASK*-----------------------------------------------------------------
*
* Function Name  : Shell_gate
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/

int_32 Shell_gate(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;

   _ip_address       gate_ipaddr;
   _ip_address       ipaddr = INADDR_ANY;
   _ip_address       ipmask = INADDR_ANY;
   uint_32           error = 0;
  
   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if ((argc <= 1) || (argc > 4))  {
         return_code = SHELL_EXIT_ERROR;
         print_usage = TRUE;
      } else  {
         if (! Shell_parse_ip_address( argv[1], &gate_ipaddr  ))  {
            printf("Error, invalid gateway address\n");
            return_code = SHELL_EXIT_ERROR;
         } else if (argc > 2)  {
            if (! Shell_parse_ip_address( argv[2], &ipaddr  ))  {
               printf("Error, invalid ip address\n");
               return_code = SHELL_EXIT_ERROR;
            } else if (argc > 3)  {
               if (! Shell_parse_netmask( argv[3], &ipmask ))  {
                  printf("Error, invalid ip mask\n");
                  return_code = SHELL_EXIT_ERROR;
               }          
            }          
         }          
      }          
         
         
      if (return_code == SHELL_EXIT_SUCCESS)  {
         printf("Adding gateway %d.%d.%d.%d, ip address: %d.%d.%d.%d, netmask: %d.%d.%d.%d\n",
              IPBYTES(gate_ipaddr),IPBYTES(ipaddr),IPBYTES(ipmask));
         error = RTCS_gate_add(gate_ipaddr, ipaddr, ipmask);
         if (error) {
            printf("Error, could not initialize gateway %d.%d.%d.%d\n", gate_ipaddr);
            printf("RCS_gate_add returned: %d\n", error);
            return_code = SHELL_EXIT_ERROR;
         } 
      } 
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <gateway> [<ipaddr>] [<netmask>]\n", argv[0]);
      } else  {
         printf("Usage: %s  <gateway> [<ipaddr>] [<netmask>]\n", argv[0]);
         printf("   <gateway> = IP address of gateway\n");
         printf("   <ipaddr>  = IP address \n");
         printf("   <netmask> = Network mask\n");
      }
   }

   return return_code;
} /* Endbody */

#endif /* SHELLCFG_USES_RTCS */
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/io_pcb.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_pcb.c$
* $Version : 3.8.6.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This file contains the functions for use with IO PCB device drivers.
*
*END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_IPC

#include "partition.h"
#include "fio.h"
#include "io.h"
#include "io_prv.h"
#include "io_pcb.h"
#include "iopcbprv.h"


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_create_pool
* Returned Value   : MQX_OK or a MQX error code
* Comments         :
*   Create a pool of pcbs.
*END*-------------------------------------------------------------------------*/

_io_pcb_pool_id _io_pcb_create_pool
   (
      /* The maximum number of fragments in the PCB */
      _mqx_uint                     max_number_of_fragments,

      /* 
      ** The number of bytes of extra data to append to the PCB 
      ** (following the fragments) 
      */
      _mem_size                     size_extra_data,

      /* The initial number of PCBS to acquire */
      _mqx_uint                     initial_number_of_pcbs, 

      /* The number of PCBS to add when the pool is exhausted */
      _mqx_uint                     grow_number_of_pcbs, 

      /* The maximum number of PCBS allowed in the pool (0 implies unlimited) */
      _mqx_uint                     max_number_of_pcbs,
      
      /*
      ** The function to call when a pcb is allocated from this pool.  If this
      ** function returns NULL, then the pcb should not be allocated
      */
      IO_PCB_STRUCT_PTR (_CODE_PTR_ pcb_alloc_function)
         (IO_PCB_STRUCT_PTR, pointer),
      
      /* Data to pass to the allocation function */
      pointer  alloc_function_data_ptr,

      /* The function to call when a pcb is freed to this pool */
      IO_PCB_STRUCT_PTR (_CODE_PTR_ pcb_free_function)
         (IO_PCB_STRUCT_PTR, pointer),

      /* Data to pass to the free function */
      pointer                       free_function_data_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   IO_PCB_POOL_STRUCT_PTR pool_ptr;
   _partition_id          pid;
   
   if (max_number_of_fragments < 1) {
      _task_set_error(MQX_INVALID_PARAMETER);
      return(IO_PCB_NULL_POOL_ID);
   }/* Endif */
   pool_ptr = _mem_alloc_system_zero((_mem_size)sizeof(IO_PCB_POOL_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (pool_ptr == NULL) {
      return(IO_PCB_NULL_POOL_ID);
   }/* Endif */
#endif

   pid = _partition_create( (_mem_size)(sizeof(IO_PCB_STRUCT) + 
      (sizeof(IO_PCB_FRAGMENT_STRUCT) * (max_number_of_fragments - 1))) + 
      size_extra_data, initial_number_of_pcbs, grow_number_of_pcbs, 
      max_number_of_pcbs);
#if MQX_CHECK_ERRORS
   if (pid == PARTITION_NULL_ID) {
      _mem_free(pool_ptr);
      return(IO_PCB_NULL_POOL_ID);
   }/* Endif */
#endif
   pool_ptr->VALID                   = IO_PCB_VALID;
   pool_ptr->PARTITION               = pid;
   pool_ptr->NUM_FRAGS               = max_number_of_fragments;
   pool_ptr->EXTRA_DATA_SIZE         = size_extra_data;
   pool_ptr->PCB_ALLOC_FUNCTION_PTR  = pcb_alloc_function;
   pool_ptr->ALLOC_FUNCTION_DATA_PTR = alloc_function_data_ptr;
   pool_ptr->PCB_FREE_FUNCTION_PTR   = pcb_free_function;
   pool_ptr->FREE_FUNCTION_DATA_PTR  = free_function_data_ptr;

   _lwsem_create(&pool_ptr->PCB_LWSEM, initial_number_of_pcbs);
   _GET_KERNEL_DATA(kernel_data);

   if (kernel_data->IO_PCB_POOLS.NEXT == NULL) {
      _queue_init((QUEUE_STRUCT_PTR)(&kernel_data->IO_PCB_POOLS), 0);
   } /* Endif */
   _queue_enqueue((QUEUE_STRUCT_PTR)(&kernel_data->IO_PCB_POOLS), &pool_ptr->QUEUE);

   return(IO_PCB_CREATE_POOL_ID(pool_ptr));

} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_alloc
* Returned Value   : a PCB pointer or NULL upon error, setting task error code
* Comments         :
*   This function obtains a pcb from the specified pcb pool
*END*-------------------------------------------------------------------------*/

IO_PCB_STRUCT_PTR _io_pcb_alloc
   (
      /* [IN] The PCB pool to obtain a pcb from */
      _io_pcb_pool_id pool,
      
      /* [IN] A boolean flag, if TRUE indicates block waiting for a PCB */
      boolean         blocking
   )
{ /* Body */
   IO_PCB_POOL_STRUCT_PTR pool_ptr = IO_PCB_GET_POOL_PTR(pool);
   IO_PCB_STRUCT_PTR      pcb_ptr;
   IO_PCB_STRUCT_PTR      new_pcb_ptr;
   
#if MQX_CHECK_VALIDITY
   if (pool_ptr->VALID != IO_PCB_VALID) {
      _task_set_error(IO_PCB_POOL_INVALID);
      return(NULL );
   }/* Endif */
#endif
   if (blocking) {
      _lwsem_wait(&pool_ptr->PCB_LWSEM);
   } else {
      _lwsem_poll(&pool_ptr->PCB_LWSEM);
   } /* Endif */

   pcb_ptr = (IO_PCB_STRUCT_PTR)_partition_alloc_system_zero(
      pool_ptr->PARTITION);

   if (pcb_ptr != NULL) {
      pcb_ptr->FREE_PCB_FUNCTION_PTR = _io_pcb_free_internal;
      pcb_ptr->VALID               = IO_PCB_VALID;
      pcb_ptr->POOL_ID             = pool;
      pcb_ptr->NUMBER_OF_FRAGMENTS = pool_ptr->NUM_FRAGS;
      if (pool_ptr->EXTRA_DATA_SIZE) {
         pcb_ptr->FRAGMENTS[0].FRAGMENT = (uchar_ptr)pcb_ptr + 
            sizeof(IO_PCB_STRUCT) + (sizeof(IO_PCB_FRAGMENT_STRUCT) *
            (pool_ptr->NUM_FRAGS - 1));
         /* Start CR 397 */
         pcb_ptr->FRAGMENTS[0].LENGTH = pool_ptr->EXTRA_DATA_SIZE;
         /* End CR 397 */
      }/* Endif */
      if (pool_ptr->PCB_ALLOC_FUNCTION_PTR) {
         new_pcb_ptr = (*pool_ptr->PCB_ALLOC_FUNCTION_PTR)(pcb_ptr, 
            pool_ptr->ALLOC_FUNCTION_DATA_PTR);
         if (new_pcb_ptr == NULL) {
            _task_set_error(IO_PCB_ALLOC_CALLBACK_FAILED);
            _partition_free(pcb_ptr);
            _lwsem_post(&pool_ptr->PCB_LWSEM);
            return(NULL);
         } /* Endif */
         pcb_ptr = new_pcb_ptr;
      /* Start CR 321 */
      /*
      } else {
         _task_set_error(IO_PCB_ALLOC_CALLBACK_FAILED);
      */
      /* End CR 321 */
      } /* Endif */
   }/* Endif */
   return(pcb_ptr);

} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_read
* Returned Value   : MQX_OK or an error code
* Comments         :
*   returns a PCB that has been read from the device.
*END*-------------------------------------------------------------------------*/

_mqx_int _io_pcb_read
   (
      /* The device to read from */
      MQX_FILE_PTR            fd_ptr,

      /* The PCB to return from the read */
      IO_PCB_STRUCT_PTR _PTR_ pcb_ptr_ptr
   )
{ /* Body */
   IO_PCB_DEVICE_STRUCT_PTR dev_ptr = (IO_PCB_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   
#if MQX_CHECK_ERRORS
   if (!(fd_ptr->FLAGS & IO_FLAG_IS_PCB_DEVICE)) {
      fd_ptr->ERROR = IO_PCB_NOT_A_PCB_DEVICE;
      return(IO_ERROR);
   }/* Endif */
#endif
   if (dev_ptr->IO_READ) {
      return((*dev_ptr->IO_READ)(fd_ptr,pcb_ptr_ptr));
   }/* Endif */
   fd_ptr->ERROR = IO_PCB_READ_NOT_AVAILABLE;
   *pcb_ptr_ptr = NULL;
   return(IO_ERROR);
   
} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_write
* Returned Value   : MQX_OK or an error code
* Comments         :
*   uses the PCB to write the data to the device
*END*-------------------------------------------------------------------------*/

_mqx_int _io_pcb_write
   (
      /* The device to read from */
      MQX_FILE_PTR         fd_ptr,

      /* The PCB to use for writing */
      IO_PCB_STRUCT _PTR_  pcb_ptr
   )
{ /* Body */
   IO_PCB_DEVICE_STRUCT_PTR dev_ptr = (IO_PCB_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   
#if MQX_CHECK_VALIDITY
   if (pcb_ptr->VALID != IO_PCB_VALID) {
      fd_ptr->ERROR = IO_PCB_NOT_A_PCB;
      return(IO_ERROR);
   }/* Endif */
#endif
#if MQX_CHECK_ERRORS
   if (!(fd_ptr->FLAGS & IO_FLAG_IS_PCB_DEVICE)) {
      fd_ptr->ERROR = IO_PCB_NOT_A_PCB_DEVICE;
      return(IO_ERROR);
   }/* Endif */
#endif
   if (dev_ptr->IO_WRITE) {
      return((*dev_ptr->IO_WRITE)(fd_ptr, pcb_ptr));
   }/* Endif */
   IO_PCB_FREE(pcb_ptr);
   fd_ptr->ERROR = IO_PCB_WRITE_NOT_AVAILABLE;
   return(IO_ERROR);

} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_free
* Returned Value   : MQX_OK or an error code
* Comments         :
*   Calls the pcb free function of the pcb
*END*-------------------------------------------------------------------------*/

_mqx_uint _io_pcb_free
   (
      /* The pcb to free */
      IO_PCB_STRUCT _PTR_ pcb_ptr
   )
{ /* Body */

   return(*(pcb_ptr)->FREE_PCB_FUNCTION_PTR)(pcb_ptr);

} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_free_internal
* Returned Value   : MQX_OK or an error code
* Comments         :
*   returns the PCB to the PCB pool it came from
*END*-------------------------------------------------------------------------*/

_mqx_uint _io_pcb_free_internal
   (
      /* The pcb to free */
      IO_PCB_STRUCT _PTR_ pcb_ptr
   )
{ /* Body */
   IO_PCB_POOL_STRUCT_PTR pool_ptr;
   _mqx_uint              result;

#if MQX_CHECK_VALIDITY
   if (pcb_ptr->VALID != IO_PCB_VALID) {
      return(IO_PCB_INVALID);
   }/* Endif */
#endif

   pool_ptr = IO_PCB_GET_POOL_PTR(pcb_ptr->POOL_ID);
#if MQX_CHECK_VALIDITY
   if (pool_ptr->VALID != IO_PCB_VALID) {
      return(IO_PCB_POOL_INVALID);
   }/* Endif */
#endif

   if (pool_ptr->PCB_FREE_FUNCTION_PTR) {
      pcb_ptr = (*pool_ptr->PCB_FREE_FUNCTION_PTR)(pcb_ptr, 
         pool_ptr->FREE_FUNCTION_DATA_PTR);
   }/* Endif */

   result = _partition_free((pointer)pcb_ptr);

   _lwsem_post(&pool_ptr->PCB_LWSEM);

   return result;

} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_start
* Returned Value   : MQX_OK or an error code
* Comments         :
*   Starts a PCB device
*END*-------------------------------------------------------------------------*/

_mqx_int _io_pcb_start
   (
      /* The device to start */
      MQX_FILE_PTR         fd_ptr
   )
{ /* Body */

   return ioctl(fd_ptr, IO_PCB_IOCTL_START, NULL);

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Ramp.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Ramp.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_Ramp function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90. 
*
******************************************************************************/
#ifndef _GFLIB_RAMP_H
#define _GFLIB_RAMP_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE    
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif
     
/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GFLIB_RampANSIC function.*/
#define GFLIB_Ramp(in, pParam)  GFLIB_RampANSIC(in, pParam)

/*! Macro containing default values of the Ramp structure.*/
#define GFLIB_RAMP_DEFAULT   {0,0,0}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_RAMP_T "\GFLIB_Ramp.h"

@brief  Structure containing controller parameters and coefficients.
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32 f32State;       /*!< ramp state value */
    Frac32 f32RampUp;      /*!< ramp up increment coefficient */
    Frac32 f32RampDown;    /*!< ramp down increment(decrement) coefficient */
}GFLIB_RAMP_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*! 
* @ingroup GFLIB_GROUP 
*/

extern Frac32 GFLIB_RampANSIC(Frac32 f32In, GFLIB_RAMP_T *pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GFLIB_RAMP_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/int_ctrl/int_ctrl_qintc.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: int_ctrl_qintc.c$
* $Version : 3.8.5.0$
* $Date    : Jul-9-2012$
*
* Comments:
*
*   This file contains the source functions for the QINTC driver.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "bsp.h"
#include "psp.h"


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_init
* Returned Value   : none
* Comments         :
*    Initializes interrupt controller
*
*END*------------------------------------------------------------------------*/

static void _qintc_init
    (
        /* [IN] interrupt controller base address */
        VQINTC_REG_STRUCT_PTR qintc_ptr,

        /* [IN] vector mode */
        int mode
    )
{
    uint_32              i;

    /* Disable interrupts */
    qintc_ptr->CPR = QINTC_PRI_MAX;

    /*
    ** Vector table entry size: 4 bytes
    ** Vector mode: software
    */
    if (mode)
    {
        qintc_ptr->BCR = QINTC_BCR_HVEN;
    }
    else
    {
        qintc_ptr->BCR &= ~(QINTC_BCR_VTES | QINTC_BCR_HVEN);
    }

    qintc_ptr->IACKR = _PSP_GET_VECTOR_TABLE();

    for (i=0; i<8; i++) qintc_ptr->SSCIR[i]=QINTC_SSCIR_CLR;
    for (i=0; i<=_PSP_VECTOR_TO_IRQ(QINTC_LAST_VECTOR); i++) qintc_ptr->PSR[i]=0;

    /* lower PRI in QINTC_CPR to zero */
    qintc_ptr->CPR = QINTC_PRI_MIN;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_set_prio
* Returned Value   : none
* Comments         :
*    Sets priority for given interrupt vector
*
*END*------------------------------------------------------------------------*/

uint_32 _qintc_set_prio
    (
        /* [IN] interrupt vector number */
        uint_32 vector,

        /* [IN] interrupt  priority*/
        uint_32  prio
    )
{
    VQINTC_REG_STRUCT_PTR qintc_ptr = _bsp_get_qintc_base_address();
    uint_32 irq;

    if ((vector < QINTC_FIRST_VECTOR) || (vector > QINTC_LAST_VECTOR))
    {
        return MQX_INVALID_PARAMETER;
    }
    irq = _PSP_VECTOR_TO_IRQ(vector);

    if (prio > QINTC_PRI_MAX) prio = QINTC_PRI_MAX;
    qintc_ptr->PSR[irq]=prio;

    return MQX_OK;
}


/*ISR*---------------------------------------------------------------------
*
* Function Name    : _qintc_external_isr
* Comments         :
*   This ISR is to be installed into the external interrupt vector
* location in order to capture all external interrupts
*
*END*----------------------------------------------------------------------*/

void _qintc_external_isr
    (
        /* [IN] interrupt controller base address */
           pointer base
    )
{
    VQINTC_REG_STRUCT_PTR qintc_ptr = (VQINTC_REG_STRUCT_PTR)base;
    uint_32 vector;

    /* Find the interrupt source */
    vector = _PSP_IRQ_TO_VECTOR((qintc_ptr->IACKR & QINTC_IACKR_INTVEC) >> 2);

     /* invoke the interrupt service routine associated with the interrupt code */
    _psp_generate_interrupt(vector);

    /* End of interrupt */
    qintc_ptr->EOIR = 0;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_install
* Returned Value   : none
* Comments         :
*    Initializes interrupt controller in sw vector mode and intalls isr
*
*END*------------------------------------------------------------------------*/

uint_32 _qintc_install
    (
        /* [IN] interrupt controller base address */
        VQINTC_REG_STRUCT_PTR base,

        /* [IN] external vector/exception number */
        int vector
    )
{
    #if PSP_HAS_DEVICE_PROTECTION
    if (!_bsp_qintc_enable_access()) {
        return MQX_INVALID_DEVICE;
    }
    #endif

    _qintc_init(base, 0);

    /* Install the decrementer interrupt handler */
    if (_int_install_isr(vector, _qintc_external_isr, (pointer)base) == NULL)
    {
        return _task_get_error();
    }

    return MQX_OK;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_set_sw_interrupt
* Returned Value   : none
* Comments         :
*    Causes the sw interrupt for the specified vector to occur
*
*END*------------------------------------------------------------------------*/

uint_32 _qintc_set_sw_interrupt
    (
        /* [IN] interrupt vector number */
        uint_32 vector
    )
{
    VQINTC_REG_STRUCT_PTR qintc_ptr = _bsp_get_qintc_base_address();
    uint_32 irq;

    irq = _PSP_VECTOR_TO_IRQ(vector);

    if (irq > 7)
    {
        return MQX_INVALID_PARAMETER;
    }

    qintc_ptr->SSCIR[irq]=QINTC_SSCIR_SET;
    return MQX_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_clear_sw_interrupt
* Returned Value   : none
* Comments         :
*    Clears the sw interrupt for the specified vector
*
*END*------------------------------------------------------------------------*/

uint_32 _qintc_clear_sw_interrupt
    (
        /* [IN] interrupt vector number */
        uint_32 vector
    )
{
    VQINTC_REG_STRUCT_PTR qintc_ptr = _bsp_get_qintc_base_address();
    uint_32 irq;

    irq = _PSP_VECTOR_TO_IRQ(vector);

    if (irq > 7)
    {
        return MQX_INVALID_PARAMETER;
    }

    qintc_ptr->SSCIR[irq]=QINTC_SSCIR_CLR;
    return MQX_OK;
}

#if PSP_NUM_CORES>1
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_set_core_sw_interrupt
* Returned Value   : none
* Comments         :
*    Causes the sw interrupt for the specified vector to occur
*
*END*------------------------------------------------------------------------*/

uint_32 _qintc_set_core_sw_interrupt
    (
        /* [IN] core number */
        uint_32 core_num,
        /* [IN] interrupt vector number */
        uint_32 vector
    )
{
    VQINTC_REG_STRUCT_PTR qintc_ptr = _bsp_get_core_qintc_base_address(core_num);
    uint_32 irq;

    irq = _PSP_VECTOR_TO_IRQ(vector);

    if (irq > 7)
    {
        return MQX_INVALID_PARAMETER;
    }

    qintc_ptr->SSCIR[irq]=QINTC_SSCIR_SET;
    return MQX_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_set_core0_sw_interrupt
* Returned Value   : none
* Comments         :
*    Causes the sw interrupt for the specified vector to occur
*
*END*------------------------------------------------------------------------*/
uint_32 _qintc_set_core0_sw_interrupt
    (
        /* [IN] interrupt vector number */
        uint_32 vector
    )
{
    return _qintc_set_core_sw_interrupt(0,vector);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_set_core1_sw_interrupt
* Returned Value   : none
* Comments         :
*    Causes the sw interrupt for the specified vector to occur
*
*END*------------------------------------------------------------------------*/
uint_32 _qintc_set_core1_sw_interrupt
    (
        /* [IN] interrupt vector number */
        uint_32 vector
    )
{
    return _qintc_set_core_sw_interrupt(1,vector);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _qintc_clear_core_sw_interrupt
* Returned Value   : none
* Comments         :
*    Clears the sw interrupt for the specified vector
*
*END*------------------------------------------------------------------------*/

uint_32 _qintc_clear_core_sw_interrupt
    (
        /* [IN] core number */
        uint_32 core_num,
        /* [IN] interrupt vector number */
        uint_32 vector
    )
{
    VQINTC_REG_STRUCT_PTR qintc_ptr = _bsp_get_core_qintc_base_address(core_num);
    uint_32 irq;

    irq = _PSP_VECTOR_TO_IRQ(vector);

    if (irq > 7)
    {
        return MQX_INVALID_PARAMETER;
    }

    qintc_ptr->SSCIR[irq]=QINTC_SSCIR_CLR;
    return MQX_OK;
}
#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sai/sai_ksai_prv.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sai_ksai_prv.h$
* $Version : 3.8.3.0$
* $Date    : Sep-11-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the SAI/I2S driver
*
*END************************************************************************/
#ifndef __SAI_KSAI_PRV_H__
#define __SAI_KSAI_PRV_H__

#include "sai_ksai.h"
#include "sai_audio.h"

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/* Limits for master clock divider */
#define FRACT_MAX 256
#define DIV_MAX 4096

/*
** SAI limits
*/

#define BCLK_DIV_MIN    1
#define BCLK_DIV_MAX    4096

/* Hardware FIFO size */
#if !PSP_MQX_CPU_IS_VYBRID
  #define SIZE_OF_FIFO    8
#else
  #define SIZE_OF_FIFO    32
#endif

#define MEM_TYPE_IO_I2S_INFO_STRUCT     1046
#define MEM_TYPE_IO_I2S_LEFT_BUFFER     1047
#define MEM_TYPE_IO_I2S_RIGHT_BUFFER    1048

/* Number of data channels on both RX and TX */
#if !PSP_MQX_CPU_IS_VYBRID
  #define SAI_DATA_CHANNELS 2
#else
  #define SAI_DATA_CHANNELS 1
#endif

#define DEFAULT_BCLK_DIV 8


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** SAI software buffer structure
*/
typedef struct ksai_buffer
{
    /* Pointer to data */
    uint_32_ptr DATA;
    
    /* Buffer size */
    uint_32 SIZE;
    
    /* Data input index */
    uint_32 IN;
    
    /* Data output index */
    uint_32 OUT;
    
    /* Free space in buffer */
    uint_32 SPACE;
    
} KSAI_BUFFER, _PTR_ KSAI_BUFFER_PTR;

typedef struct ksai_dummy_data
{
    /* Pointer to dummy data (sine wave) */
    int_16_ptr DATA;

    /* Length in samples of dummy data */
    uint_32 LENGTH;

    /* Output index */
    uint_32 INDEX;

} KSAI_DUMMY_DATA, _PTR_  KSAI_DUMMY_DATA_PTR;

typedef struct ksai_info_struct
{  
    /* Current initialized values */
    KSAI_INIT_STRUCT INIT;

    I2S_MemMapPtr SAI_PTR;

    /* The previous TX interrupt handler and data */
    void (_CODE_PTR_ OLD_TX_ISR)(pointer);
    pointer  OLD_TX_ISR_DATA;
    
    /* The previous TX interrupt handler and data */
    void (_CODE_PTR_ OLD_RX_ISR)(pointer);
    pointer  OLD_RX_ISR_DATA;
    
    /* Selected SAI HW module */
    uint_8 HW_CHANNEL;
    
    /* I2S TX channel */
    uint_8 TX_CHANNEL;

    /* I2S RX channel */
    uint_8 RX_CHANNEL;
    
    /* Divider of fsys to create SSI clock*/
    uint_8 MCLK_DIV;
    
    /* Master clock source*/
    CM_CLOCK_SOURCE MCLK_SRC;
    
    /* Bit clock divider */
    uint_16 BCLK_DIV;

    /* 
    ** Oversampling clock frequency in Hz - only valid 
    ** when internal clock source is selected, ignored otherwise 
    */
    uint_32 MCLK_FREQ;
    
    /* 
    ** Bit clock frequency in Hz - only valid 
    ** when internal clock source is selected, ignored otherwise 
    */
    uint_32 BCLK_FREQ;

    /* 
    ** Frame sync frequency in Hz - only valid 
    ** when internal clock source is selected, ignored otherwise 
    */
    uint_32 FS_FREQ;
    
    /* I2S module clock source (only affects SAI master mode) */
    uint_8 CLOCK_SOURCE;

    /* I2S mode of operation (master/slave)*/
    uint_8 MODE;

    /* I2S I/O mode (write/read) */
    uint_8 IO_MODE;

    /* Audio data input/output format */
    AUDIO_DATA_FORMAT IO_FORMAT;

    /* Transmit SAI clocks and dummy data when buffer is empty */
    boolean TX_DUMMY;

    /* Number of valid data bits */
    uint_8 DATA_BITS;

    /* Transmission in progress */
    boolean ONTHEWAY;

    /* Pointer to the buffer to use for current data */
    KSAI_BUFFER BUFFER;

    /* Transmission statistics */
    I2S_STATISTICS_STRUCT STATS;

    /* Data for dummy transmission*/
    KSAI_DUMMY_DATA DUMMY;

    /* Pointer to data that are going to be processed in channel*/
    char_ptr DATA;

    /* Event signaling finished read/write operation */
    LWSEM_STRUCT EVENT_IO_FINISHED;
    
    /* Clock state when no tx/rx */
    boolean CLK_ALWAYS_ON;

    /* First Input/Output operation */
    boolean FIRST_IO;
    
    /* Clock setup: sync-async; bitclock: normal-swapped */
    uint_8 CLOCK_MODE;
    
} KSAI_INFO_STRUCT, _PTR_ KSAI_INFO_STRUCT_PTR;

#endif /* __SAI_KSAI_PRV_H__ */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/media/ip-e.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip-e.c$
* $Version : 3.8.19.0$
* $Date    : Sep-19-2012$
*
* Comments:
*
*   This file contains the interface between IP and
*   the Ethernet packet driver.
*
*END************************************************************************/


#include <string.h>
#include <rtcs.h>
#include <ethernet.h>
#include <enet.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "arp.h"
#include "ip-e.h"

#if BSP_ENET_DEVICE_COUNT > 0

#define IPE_ADDR_BC(addr)     \
            (addr)[0] = 0xFF, \
            (addr)[1] = 0xFF, \
            (addr)[2] = 0xFF, \
            (addr)[3] = 0xFF, \
            (addr)[4] = 0xFF, \
            (addr)[5] = 0xFF

#define IPE_ADDR_MC(addr,ip)  \
            (addr)[0] = 0x01, \
            (addr)[1] = 0x00, \
            (addr)[2] = 0x5E, \
            (addr)[3] = ((ip) >> 16) & 0x7F, \
            (addr)[4] = ((ip) >>  8) & 0xFF, \
            (addr)[5] =  (ip)        & 0xFF

/*
** Ethernet packet header
*/

/*
** The structure used by the application to bind an IP address
** to an Ethernet packet driver.
*/

static const RTCS_IF_STRUCT rtcs_enet =
{
    IPE_open,
    IPE_close
#if RTCSCFG_ENABLE_IP4     
    ,
    IPE_send_IP
#if RTCSCFG_ENABLE_IGMP && BSPCFG_ENABLE_ENET_MULTICAST
    ,
    IPE_join,
    IPE_leave
#endif
#endif /* RTCSCFG_ENABLE_IP4 */

#if RTCSCFG_ENABLE_IP6
    ,
    IP6E_send,
    IP6E_join,
    IP6E_leave
#endif

};

const RTCS_IF_STRUCT_PTR RTCS_IF_ENET = (RTCS_IF_STRUCT_PTR)&rtcs_enet;


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_open
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Registers IP and ARP with an Ethernet packet driver.
*
*END*-----------------------------------------------------------------*/

uint_32 IPE_open
   (
      IP_IF_PTR   if_ptr
         /* [IN] the IP interface structure */
   )
{ /* Body */
   uint_32  error;


#if RTCSCFG_ENABLE_IP4
   error = ARP_open(if_ptr);
   if (error) {
      return error;
   } /* Endif */

   error = ENET_open(if_ptr->HANDLE, ENETPROT_IP, IPE_recv_IP, if_ptr);
   if (error) {
      ARP_close(if_ptr);
      return error;
   } /* Endif */

   error = ENET_open(if_ptr->HANDLE, ENETPROT_ARP, IPE_recv_ARP, if_ptr);
   if (error) {
      ENET_close(if_ptr->HANDLE, ENETPROT_IP);
      ARP_close(if_ptr);
      return error;
   } /* Endif */
#endif /* RTCSCFG_ENABLE_IP4 */
 
   
   if_ptr->MTU = ENET_get_MTU(if_ptr->HANDLE);

   if_ptr->DEV_TYPE    = 1;
   if_ptr->DEV_ADDRLEN = 6;
   ENET_get_address(if_ptr->HANDLE, if_ptr->DEV_ADDR);
   
#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4
   switch (ENET_get_speed(if_ptr->HANDLE)) {
   case 100:
      if_ptr->SNMP_IF_TYPE = IPIFTYPE_FASTETHERNET;
      break;
   case 1000:
      if_ptr->SNMP_IF_TYPE = IPIFTYPE_GIGABITETHERNET;
      break;
   default:
      if_ptr->SNMP_IF_TYPE = IPIFTYPE_ETHERNET;
      break;
   } /* Endswitch */
#endif

   /* Add some uniqueness to the seed */
   RTCS_rand_seed(if_ptr->DEV_ADDR[0]);
   RTCS_rand_seed(if_ptr->DEV_ADDR[1]);
   RTCS_rand_seed(if_ptr->DEV_ADDR[2]);
   RTCS_rand_seed(if_ptr->DEV_ADDR[3]);
   RTCS_rand_seed(if_ptr->DEV_ADDR[4]);
   RTCS_rand_seed(if_ptr->DEV_ADDR[5]);

#if RTCSCFG_ENABLE_IP6
    error = IP6E_open(if_ptr);
    if (error) 
    {
        ENET_close(if_ptr->HANDLE, ENETPROT_ARP);
        ENET_close(if_ptr->HANDLE, ENETPROT_IP);
    #if RTCSCFG_ENABLE_IP4
        ARP_close(if_ptr);
    #endif /* RTCSCFG_ENABLE_IP4 */
        return error;
    }     
#endif  


   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_close
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Registers IP and ARP with an Ethernet packet driver.
*
*END*-----------------------------------------------------------------*/

uint_32 IPE_close
   (
      IP_IF_PTR   if_ptr
         /* [IN] the IP interface structure */
   )
{ /* Body */
   uint_32  firsterror, error;

   firsterror = RTCS_OK;

#if RTCSCFG_ENABLE_IP4
   error = ARP_close(if_ptr);
   if (error && !firsterror) {
      firsterror = error;
   } /* Endif */

   error = ENET_close(if_ptr->HANDLE, ENETPROT_IP);
   if (error && !firsterror) {
      firsterror = error;
   } /* Endif */

   error = ENET_close(if_ptr->HANDLE, ENETPROT_ARP);
   if (error && !firsterror) {
      firsterror = error;
   } /* Endif */
#endif /* RTCSCFG_ENABLE_IP4 */

#if RTCSCFG_ENABLE_IP6
   error = IP6E_close (if_ptr);
   if (error && !firsterror)
   { //TBD  error handling.
      firsterror = error;
   } /* Endif */
#endif 

   return firsterror;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_recv
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Services an Ethernet packet.
*
*END*-----------------------------------------------------------------*/

/* //AB static*/ void IPE_recv
   (
      PCB_PTR           pcb,
         /* [IN] the received packet */
      pointer           handle,
         /* [IN] the IP interface structure */
      void (_CODE_PTR_  service)(RTCSPCB_PTR)
         /* [IN] IP_service or ARP_service */
   )
{ /* Body */
   IP_IF_PTR            if_ptr = handle;
   RTCSPCB_PTR          rtcs_pcb;
   ENET_HEADER_PTR      enetpkt;
#if RTCSCFG_LINKOPT_8021Q_PRIO || RTCSCFG_LINKOPT_8023
   uchar_ptr            type_ptr;
#endif
   uint_32              hdrlen, error;
   uchar                rladdr[6];
   
   RTCSLOG_FNE4(RTCSLOG_FN_IPE_recv, pcb, handle, service);
   
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_TOTAL++);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_RX_OCTETS += pcb->FRAG[0].LENGTH);

   rtcs_pcb = RTCSPCB_alloc_recv(pcb);
   if (rtcs_pcb == NULL) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_MISSED++);
      PCB_free(pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IPE_recv, -1);
      return;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(rtcs_pcb);

   enetpkt = (ENET_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
   if (enetpkt->DEST[0] & 1) {
      if ((enetpkt->DEST[0] == 0xFF)
       && (enetpkt->DEST[1] == 0xFF)
       && (enetpkt->DEST[2] == 0xFF)
       && (enetpkt->DEST[3] == 0xFF)
       && (enetpkt->DEST[4] == 0xFF)
       && (enetpkt->DEST[5] == 0xFF)) {
         IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_RX_BROADCAST++);
         rtcs_pcb->TYPE = RTCSPCB_TYPE_BROADCAST;
      } else {
         IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_RX_MULTICAST++);
         rtcs_pcb->TYPE = RTCSPCB_TYPE_MULTICAST;
      } /* Endif */
   } else {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_RX_UNICAST++);
      rtcs_pcb->TYPE = RTCSPCB_TYPE_UNICAST;
   } /* Endif */

#if RTCSCFG_LINKOPT_8021Q_PRIO || RTCSCFG_LINKOPT_8023
   type_ptr = enetpkt->TYPE;
#endif
   hdrlen = sizeof(ENET_HEADER);

#if RTCSCFG_LINKOPT_8021Q_PRIO
   if (ntohs(type_ptr) == 0x8100) {
      rtcs_pcb->LINK_OPTIONS.RX.OPT_PRIO = 1;
      rtcs_pcb->LINK_OPTIONS.RX.PRIO = (ntohc(type_ptr+2) >> 5) & 0x7;
      hdrlen += sizeof(ENET_8021QTAG_HEADER);
      type_ptr += sizeof(ENET_8021QTAG_HEADER);
   } /* Endif */
#endif

#if RTCSCFG_LINKOPT_8023
   if (ntohs(type_ptr) < ENET_FRAMESIZE_MAXDATA) {
      rtcs_pcb->LINK_OPTIONS.RX.OPT_8023 = 1;
      hdrlen += sizeof(ENET_8022_HEADER);
      type_ptr += sizeof(ENET_8022_HEADER);
   } /* Endif */
#endif

   error = RTCSPCB_next(rtcs_pcb, hdrlen);
   if (error) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_ERRORS++);
      IF_IPIF_STATS_ENABLED(RTCS_seterror(&if_ptr->STATS.ERR_RX, error, (uint_32)rtcs_pcb));
      RTCSLOG_PCB_FREE(rtcs_pcb, error);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IPE_recv, -2);
      return;
   } /* Endif */

   RTCSLOG_PCB_READ(RTCSPCB_DATA(rtcs_pcb), RTCS_LOGCTRL_IFTYPE(IPIFTYPE_ETHERNET), 0);

   rtcs_pcb->LINK_OPTIONS.TX = rtcs_pcb->LINK_OPTIONS.RX;
   rtcs_pcb->IFSRC = handle;

#if RTCSCFG_DISCARD_SELF_BCASTS
   /* discard any broadcast pkts that we sent, as they are likely echoes */ 
   ntohe(enetpkt->SOURCE, rladdr);
   if ((rtcs_pcb->TYPE == RTCSPCB_TYPE_BROADCAST) && 
       (memcmp(rladdr, if_ptr->DEV_ADDR, sizeof(rladdr)) == 0)) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
      RTCSPCB_free(rtcs_pcb);
      RTCSLOG_FNX2(RTCSLOG_FN_IPE_recv, -3);
      return;
   }
#endif

   if (!RTCSCMD_service(rtcs_pcb, service)) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_MISSED++);
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
      RTCSPCB_free(rtcs_pcb);
   }
   
   RTCSLOG_FNX4(RTCSLOG_FN_IPE_recv, 0, ntohl(&(enetpkt->SOURCE[2])), /*ntohs(enetpkt->TYPE), */ntohl(((uint_8*)enetpkt + 0x26)));
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_recv_IP
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Services an IP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

void IPE_recv_IP
   (
      PCB_PTR  pcb,
         /* [IN] the received packet */
      pointer  handle
         /* [IN] the IP interface structure */
   )
{ 
   RTCSLOG_FNE3(RTCSLOG_FN_IPE_recv_IP, pcb, handle);
   IPE_recv(pcb, handle, IP_service);
   RTCSLOG_FNX1(RTCSLOG_FN_IPE_recv_IP);
}

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_recv_ARP
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Services an ARP packet.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4

void IPE_recv_ARP
   (
      PCB_PTR  pcb,
         /* [IN] the received packet */
      pointer  handle
         /* [IN] the IP interface structure */
   )
{ 
   IPE_recv(pcb, handle, ARP_service);
}

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_send
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Sends a packet.
*
*END*-----------------------------------------------------------------*/
uint_32 IPE_send
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] the packet to send */
      uint_16        protocol,
         /* [IN] ENETPROT_IP or ENETPROT_ARP */
      uchar          dest[6]
         /* [IN] the destination Ethernet address */
   )
{ /* Body */
   uint_32        hdrlen, flags, error;
   
   RTCSLOG_FNE5(RTCSLOG_FN_IPE_send, if_ptr, rtcs_pcb, protocol, *(uint_32*)dest);

   hdrlen = sizeof(ENET_HEADER);
   flags = 0;

#if RTCSCFG_LINKOPT_8021Q_PRIO
   if (rtcs_pcb->LINK_OPTIONS.TX.OPT_PRIO) {
      hdrlen += sizeof(ENET_8021QTAG_HEADER);
      flags |= ENET_SETOPT_8021QPRIO(rtcs_pcb->LINK_OPTIONS.TX.PRIO);
   } /* Endif */
#endif

#if RTCSCFG_LINKOPT_8023
   if (rtcs_pcb->LINK_OPTIONS.TX.OPT_8023) {
      hdrlen += sizeof(ENET_8022_HEADER);
      flags |= ENET_OPT_8023;
   } /* Endif */
#endif

   RTCSLOG_PCB_WRITE(rtcs_pcb, RTCS_LOGCTRL_IFTYPE(IPIFTYPE_ETHERNET), 0);

   error = RTCSPCB_insert_header(rtcs_pcb, hdrlen);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_OCTETS += RTCSPCB_SIZE(rtcs_pcb));
   if (error) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_ERRORS++);
      IF_IPIF_STATS_ENABLED(RTCS_seterror(&if_ptr->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
      RTCSLOG_PCB_FREE(rtcs_pcb, error);
      RTCSPCB_free(rtcs_pcb);
      
      RTCSLOG_FNX2(RTCSLOG_FN_IPE_send, error);
      return error;
   } /* Endif */

   rtcs_pcb->PCBPTR->FRAG[0].LENGTH   = rtcs_pcb->HEADER_FRAG_USED;
   rtcs_pcb->PCBPTR->FRAG[0].FRAGMENT = RTCSPCB_DATA(rtcs_pcb);

   error = ENET_send(if_ptr->HANDLE, rtcs_pcb->PCBPTR, protocol, dest, flags);
   RTCSLOG_PCB_FREE(rtcs_pcb, error);
   if (error) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_ERRORS++);
      IF_IPIF_STATS_ENABLED(RTCS_seterror(&if_ptr->STATS.ERR_TX, error, (uint_32)rtcs_pcb));
   } /* Endif */
   
   RTCSLOG_FNX2(RTCSLOG_FN_IPE_send, error);
   return error;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_send_IP
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Sends an IP packet.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
uint_32 IPE_send_IP
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] the packet to send */
      _ip_address    src,
         /* [IN] the next-hop source address */
      _ip_address    dest,
         /* [IN] the next-hop destination address */
      pointer        data
         /* [IN] unused */
   )
{ /* Body */
   uchar    enetdest[6];
   uint_32 error;
   
   RTCSLOG_FNE5(RTCSLOG_FN_IPE_send_IP, if_ptr, rtcs_pcb, src, dest);

   IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_TOTAL++);

   if (dest == INADDR_BROADCAST) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_BROADCAST++);
      IPE_ADDR_BC(enetdest);

   } else if (IN_MULTICAST(dest)) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_MULTICAST++);
      IPE_ADDR_MC(enetdest, dest);

   } else {
      /* ARP_resolve() will record an error if one occurs */
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_UNICAST++);
      error = ARP_resolve(if_ptr, rtcs_pcb, src, dest);
      RTCSLOG_FNX2(RTCSLOG_FN_IPE_send_IP, error);
      return error;

   } /* Endif */

   error = IPE_send(if_ptr, rtcs_pcb, ENETPROT_IP, enetdest);
   RTCSLOG_FNX2(RTCSLOG_FN_IPE_send_IP, error);
   return error;
} /* Endbody */
#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_send_IP_ucast
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Called from ARP.  Sends a resolved IP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 IPE_send_IP_ucast
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] the packet to send */
      uchar          dest[6]
         /* [IN] the destination Ethernet address */
   )
{ /* Body */

   return IPE_send(if_ptr, rtcs_pcb, ENETPROT_IP, dest);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_send_ARP_bcast
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Sends a broadcast ARP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 IPE_send_ARP_bcast
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      RTCSPCB_PTR    rtcs_pcb
         /* [IN] the packet to send */
   )
{ /* Body */
   uchar    enetdest[6];

   IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_TOTAL++);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_BROADCAST++);
   IPE_ADDR_BC(enetdest);
   return IPE_send(if_ptr, rtcs_pcb, ENETPROT_ARP, enetdest);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_send_ARP_ucast
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Sends a unicast ARP packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4

uint_32 IPE_send_ARP_ucast
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] the packet to send */
      uchar          dest[6]
         /* [IN] the next-hop destination address */
   )
{ /* Body */

   IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_TX_TOTAL++);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_TX_UNICAST++);
   return IPE_send(if_ptr, rtcs_pcb, ENETPROT_ARP, dest);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

#if BSPCFG_ENABLE_ENET_MULTICAST && RTCSCFG_ENABLE_IP4
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_join
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Joins a multicast group.
*
*END*-----------------------------------------------------------------*/

uint_32 IPE_join
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      _ip_address    group
         /* [IN] the multicast group */
   )
{ /* Body */
   uchar    enetgroup[6];

   IPE_ADDR_MC(enetgroup, group);
   return ENET_join(if_ptr->HANDLE, ENETPROT_IP, enetgroup);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPE_leave
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Leaves a multicast group.
*
*END*-----------------------------------------------------------------*/

uint_32 IPE_leave
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      _ip_address    group
         /* [IN] the multicast group */
   )
{ /* Body */
   uchar    enetgroup[6];

   IPE_ADDR_MC(enetgroup, group);
   return ENET_leave(if_ptr->HANDLE, ENETPROT_IP, enetgroup);

} /* Endbody */
#endif /* BSPCFG_ENABLE_ENET_MULTICAST && RTCSCFG_ENABLE_IP4 */

#endif /* BSP_ENET_DEVICE_COUNT > 0 */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_ControllerPIpAW.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_ControllerPIpAW.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_ControllerPIpAW function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_CONTROLLER_PIPAW_H
#define _GFLIB_CONTROLLER_PIPAW_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif

/******************************************************************************
| Defines and macros            (scope: module-local)
-----------------------------------------------------------------------------*/
    /*! Function alias for the #GFLIB_ControllerPIpAWANSIC function.*/
#define GFLIB_ControllerPIpAW(f32InErr,pParam)\
                    GFLIB_ControllerPIpAWANSIC(f32InErr, pParam)

/*! Macro containing default values for the structure of parameters of
 *  the parallel PI controller with anti-windup.*/
#define GFLIB_CONTROLLER_PIAW_P_DEFAULT   {0,0,0,0,INT32_MIN,INT32_MAX,0,0,0}

/******************************************************************************
| Typedefs and structures       (scope: module-local)
-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_CONTROLLER_PIAW_P_T "\GFLIB_ControllerPIpAW.h"

@brief  Structure containing parameters and states of the the parallel form PI controller
        with anti-windup.
*//*-------------------------------------------------------------------------*/
typedef struct {
  Frac32   f32PropGain;        /*!< Proportional Gain, fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ */
  Frac32   f32IntegGain;       /*!< Integral Gain, fractional format normalized to fit into  \f$\left[-2^{31},2^{31}-1\right)\f$ */
  Word16   w16PropGainShift;   /*!< Proportional Gain Shift, integer format \f$\left[-31,31\right]\f$ */
  Word16   w16IntegGainShift;  /*!< Integral Gain Shift, integer format \f$\left[-31,31\right]\f$ */
  Frac32   f32LowerLimit;      /*!< Lower Limit of the controller, fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ */
  Frac32   f32UpperLimit;      /*!< Upper Limit of the controller, fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ */
  Frac32   f32IntegPartK_1;    /*!< State variable integral part at step k-1*/
  Frac32   f32InK_1;           /*!< State variable input error at step k-1*/
  UWord16  u16LimitFlag;       /*!< Limitation flag, if set to 1, the controller output has reached either the UpperLimit or LowerLimit*/
} GFLIB_CONTROLLER_PIAW_P_T;

/******************************************************************************
| Exported Variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| Exported function prototypes
-----------------------------------------------------------------------------*/
/*!
* @ingroup GFLIB_GROUP
*/
extern Frac32 GFLIB_ControllerPIpAWANSIC(Frac32 f32InErr,
                                          GFLIB_CONTROLLER_PIAW_P_T *pParam);

/******************************************************************************
| Inline functions
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* _GFLIB_CONTROLLER_PIPAW_H */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/task.c<|end_filename|>
/*HEADER*********************************************************************
 *
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *****************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************
 *
 * $FileName: task.c$
 * $Version : 3.8.0.2$
 * $Date    : Feb-27-2012$
 *
 * Comments:
 *
 *   This file contains functions of the Task Management component.
 *
 *END************************************************************************/

#include <string.h>
#include "mqx_inc.h"

/*!
 * \private
 *
 * This variable has no use to MQX.
 * Its been created for Task Aware Debug module.
 */
volatile uint_32 _tad_task_at_flag;

/*!
 * \private
 *
 * \brief Makes a task run its task exit handler and then destroys itself.
 *
 * \param[in] task_id The task id of the task to abort.
 * \param[in] user User mode functionality.
 *
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID
 *
 * \see _task_abort
 */
_mqx_uint _task_abort_internal
(
    _task_id    task_id,
    boolean     user
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR          td_ptr;
    pointer                stack_ptr;
    _processor_number processor;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_task_abort, task_id);

    if (task_id != MQX_NULL_TASK_ID)
    {
        processor = PROC_NUMBER_FROM_TASKID(task_id);
        if (processor != (_processor_number) kernel_data->INIT.PROCESSOR_NUMBER)
        {
#if MQX_IS_MULTI_PROCESSOR
            if ( kernel_data->IPC != NULL )
            {
                _KLOGX2(KLOG_task_abort, MQX_OK);
                return( (*kernel_data->IPC)(FALSE, processor,
                                                KERNEL_MESSAGES, IPC_TASK_ABORT, 1, (_mqx_uint)task_id) );
            }
            else
            {
#endif
            _KLOGX2(KLOG_task_abort, MQX_INVALID_TASK_ID);
            return (MQX_INVALID_TASK_ID);
#if MQX_IS_MULTI_PROCESSOR
        } /* Endif */
#endif
        }/* Endif */
    }/* Endif */

    td_ptr = (TD_STRUCT_PTR) _task_get_td(task_id);

#if MQX_ENABLE_USER_MODE
    /* check template for correct user task parameters */
    if (user)
    {
        if (!(td_ptr->FLAGS & MQX_USER_TASK))
        {
            return MQX_INVALID_TASK_ID;
        }
    }
#endif

#if MQX_CHECK_ERRORS
    if ((td_ptr == NULL) || (td_ptr == SYSTEM_TD_PTR(kernel_data)))
    {
        _KLOGX2(KLOG_task_abort, MQX_INVALID_TASK_ID);
        return (MQX_INVALID_TASK_ID);
    } /* Endif */
#endif

    if (td_ptr == kernel_data->ACTIVE_PTR)
    {
        if (kernel_data->IN_ISR)
        {
            stack_ptr = (pointer) td_ptr->STACK_PTR;
            _PSP_SET_PC_OF_INTERRUPTED_TASK(stack_ptr,
                            _task_exit_function_internal);
        }
        else
        {
            _task_exit_function_internal();
        }/* Endif */
    }
    else
    {

        _int_disable();
        /* Task is not running */
        stack_ptr = (pointer) td_ptr->STACK_PTR;
        _PSP_SET_PC_OF_BLOCKED_TASK(stack_ptr,
                        _task_exit_function_internal);
        if (td_ptr->STATE & IS_ON_TIMEOUT_Q)
        {
            /* Remove from time queue (uses NEXT, PREV field) */
            _TIME_DEQUEUE(td_ptr, kernel_data);
        }
        else if (td_ptr->STATE & TD_IS_ON_QUEUE)
        {
            _QUEUE_REMOVE(td_ptr->INFO, td_ptr);
        }
        else if ((td_ptr->STATE & BLOCKED_ON_AUX_QUEUE) == BLOCKED_ON_AUX_QUEUE)
        {
            /* We need to remove it here because _task_ready() below will
             change its state to READY */
            _QUEUE_REMOVE(td_ptr->INFO, &td_ptr->AUX_QUEUE);
        } /* Endif */
        if (td_ptr->STATE & IS_BLOCKED)
        {
            _task_ready(td_ptr);
        } /* Endif */
        _int_enable();
    }/* Endif */

    _KLOGX2(KLOG_task_abort, MQX_OK);
    return (MQX_OK);
}

/*!
 * \brief Makes a task run its task exit handler and then destroys itself.
 *
 * While _task_destroy causes the task destroy to happen from the context
 * of the caller and is performed immediately, _task_abort causes the destroy
 * to happen from the context of the victim. _task_abort causes the victim task
 * to be removed from any queues it is blocked on, it's PC is effectively set to
 * the task exit handler and then the victim task is added to the ready to run
 * queue. Normal task scheduling and priority rules apply, so the actual task
 * destruction may be deferred indefinitely (or for a long time). The implication
 * is that there is no guarantee that the victim task is destroyed upon return
 * from _task_abort.

 *
 * \param[in] task_id One of the following:
 * \n - Task ID of the task to be destroyed.
 * \n - MQX_NULL_TASK_ID (Abort the calling task.)
 *
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID (Task_id does not represent a valid task.)
 *
 * \see _task_destroy
 * \see _task_get_exit_handler
 * \see _task_set_exit_handler
 */
_mqx_uint _task_abort
(
    _task_id    task_id
)
{
#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_task_abort(task_id);
    }
#endif

    return _task_abort_internal(task_id, FALSE);
}

#if MQX_ENABLE_USER_MODE

/*!
 * \brief Makes a task run its task exit handler and then destroys itself.
 *
 * This function is an equivalent to the _task_abort() API call but it can be
 * executed from within the User task or other code running in the CPU User mode.
 * Parameters passed to this function by pointer are required to meet the memory
 * protection requirements as described in the parameter list below.
 *
 * \param[in] task_id One of the following:
 * \n - Task ID of the task to be destroyed.
 * \n - MQX_NULL_TASK_ID (Abort the calling task.)
 *
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID
 *
 * \see _task_abort
 * \see _usr_task_destroy
 */
_mqx_uint _usr_task_abort
(
    _task_id    task_id
)
{
    MQX_API_CALL_PARAMS params = {(uint_32)task_id, 0, 0, 0, 0};
    return _mqx_api_call(MQX_API_TASK_ABORT, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

#if !MQX_LITE_VERSION_NUMBER
/*!
 * \private
 *
 * \brief Creates the task and make it ready.
 *
 * \param[in] processor_number One of the following:
 * \n - Processor number of the processor where the task is to be created.
 * \n - 0 (Create on the local processor.)
 * \param[in] template_index One of the following:
 * \n - Index of the task template in the processor's task template list to use
 * for the child task.
 * \n - 0 (Use the task template that create_parameter defines.)
 * \param[in] parameter Pointer:
 * \n - Template_index is not 0 (Pointer to the parameter that MQX passes to the
 * child task.)
 * \n - Template_index is 0 (Pointer to the task template.)
 * \param[in] user User mode functionality.
 *
 * \return Task ID of the child task (Success.)
 * \return MQX_NULL_TASK_ID
 *
 * \warning If the child is on another processor, blocks the creator until the
 * child is created.
 * \warning On failure, _task_set_error() is called to set the the following task
 * error codes:
 * \n - MQX_INVALID_PROCESSOR_NUMBER (Processor_number is not one of the allowed
 * processor numbers.)
 * \n - MQX_NO_TASK_TEMPLATE (Template_index is not in the task template list.)
 * \n - MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the task data structures.)
 * \warning For _task_create(): If the child is on the same processor, preempts
 * the creator if the
 * child is a higher priority.
 *
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 * \see _usr_task_create
 */
_task_id _task_create_internal
(
    _processor_number   processor_number,
    _mqx_uint           template_index,
    uint_32             parameter,
    boolean             user
)
{
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    TD_STRUCT_PTR            td_ptr;
#if MQX_IS_MULTI_PROCESSOR
    TASK_TEMPLATE_STRUCT_PTR task_template_ptr;
    boolean                  blocking;
#endif
    _task_id                 result = MQX_NULL_TASK_ID;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE4(KLOG_task_create, processor_number, template_index, parameter);

#if MQX_CHECK_ERRORS
    if (template_index & SYSTEM_TASK_FLAG)
    {
        _task_set_error(MQX_INVALID_TEMPLATE_INDEX);
        _KLOGX3(KLOG_task_create, MQX_NULL_TASK_ID, MQX_INVALID_TEMPLATE_INDEX);
        return MQX_NULL_TASK_ID;
    }
#endif

#if MQX_ENABLE_USER_MODE
    if (user)
    {
        if (kernel_data->INIT.MAX_USER_TASK_COUNT && kernel_data->USR_TASK_RUN_COUNT >= kernel_data->INIT.MAX_USER_TASK_COUNT)
        {
            _task_set_error(MQX_TOO_MANY_USER_TASKS);
            _KLOGX3(KLOG_task_create, MQX_NULL_TASK_ID, MQX_TOO_MANY_USER_TASKS);
            return MQX_NULL_TASK_ID;
        }

        kernel_data->USR_TASK_RUN_COUNT++;
    }
#endif /* MQX_ENABLE_USER_MODE */
    if (processor_number == 0)
    {
        processor_number = (_processor_number) kernel_data->INIT.PROCESSOR_NUMBER;
#if MQX_CHECK_ERRORS
    }
    else if (processor_number > MQX_MAX_PROCESSOR_NUMBER)
    {
        _task_set_error(MQX_INVALID_PROCESSOR_NUMBER);
        _KLOGX3(KLOG_task_create, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER);
        return MQX_NULL_TASK_ID;
#endif
    }
    else if (processor_number != kernel_data->INIT.PROCESSOR_NUMBER)
    {
#if MQX_ENABLE_USER_MODE
        if (user)
        {
            /* usermode don't support multiprocessor functionality */
            _task_set_error(MQX_INVALID_PROCESSOR_NUMBER);
            _KLOGX3(KLOG_task_create, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER);
            return MQX_NULL_TASK_ID;
        }
#endif

#if MQX_IS_MULTI_PROCESSOR
        if ( kernel_data->IPC != NULL )
        {
#if MQX_TASK_CREATION_BLOCKS
            blocking = TRUE;
#else
            blocking = FALSE;
#endif
            if (template_index == 0)
            {
                /* Task template is pointed to by the parameter */
                task_template_ptr = (TASK_TEMPLATE_STRUCT_PTR)parameter;
                (*kernel_data->IPC)(blocking, processor_number,
                                KERNEL_MESSAGES,
                                IPC_TASK_CREATE_WITH_TEMPLATE,
                                8L,
                                task_template_ptr->TASK_TEMPLATE_INDEX,
                                task_template_ptr->TASK_ADDRESS,
                                task_template_ptr->TASK_STACKSIZE,
                                task_template_ptr->TASK_PRIORITY,
                                task_template_ptr->TASK_NAME,
                                task_template_ptr->TASK_ATTRIBUTES,
                                task_template_ptr->CREATION_PARAMETER,
                                task_template_ptr->DEFAULT_TIME_SLICE);
            }
            else
            {
                (*kernel_data->IPC)(blocking, processor_number,
                                KERNEL_MESSAGES, IPC_TASK_CREATE, 3,
                                processor_number, template_index, parameter);
            } /* Endif */
            return(kernel_data->ACTIVE_PTR->INFO);
        }
        else
        {
#endif
        _task_set_error(MQX_INVALID_PROCESSOR_NUMBER);
        _KLOGX3(KLOG_task_create, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER);
        return MQX_NULL_TASK_ID;
#if MQX_IS_MULTI_PROCESSOR
    } /* Endif */
#endif
    } /* Endif */

    td_ptr = _task_build_internal(template_index, parameter, NULL, 0, user);

    if (td_ptr != NULL)
    {
        result = td_ptr->TASK_ID;
        _INT_DISABLE();
        _task_ready_internal(td_ptr);
        _INT_ENABLE();
        _CHECK_RUN_SCHEDULER(); /* Let a higher priority task run */
    }

    _KLOGX3(KLOG_task_create, result, kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);

    return (result);
}

/*!
 * \brief Creates the task and make it ready.
 *
 * \param[in] processor_number One of the following:
 * \n - Processor number of the processor where the task is to be created.
 * \n - 0 (Create on the local processor.)
 * \param[in] template_index   One of the following:
 * \n - Index of the task template in the processor's task template list to use
 * for the child task.
 * \n - 0 (Use the task template that create_parameter defines.)
 * \param[in] parameter        Pointer:
 * \n - Template_index is not 0 (Pointer to the parameter that MQX passes to the
 * child task.)
 * \n - Template_index is 0 (Pointer to the task template.)
 *
 * \return Task ID of the child task (Success.)
 * \return MQX_NULL_TASK_ID (Failure.)
 *
 * \warning If the child is on another processor, blocks the creator until the
 * child is created.
 * \warning On failure, _task_set_error() is called to set the the following task
 * error codes:
 * \n - MQX_INVALID_PROCESSOR_NUMBER (Processor_number is not one of the allowed
 * processor numbers.)
 * \n - MQX_NO_TASK_TEMPLATE (Template_index is not in the task template list.)
 * \n - MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the task data structures.)
 * \warning If the child is on the same processor, preempts the creator if the
 * child is a higher priority.
 *
 * \see _task_create_blocked
 * \see _task_create_at
 * \see _task_abort
 * \see _task_block
 * \see _task_destroy
 * \see _task_get_parameter
 * \see _task_get_parameter_for
 * \see _task_set_parameter
 * \see _task_set_parameter_for
 * \see _task_ready
 * \see _task_set_error
 */
_task_id _task_create
(
    _processor_number   processor_number,
    _mqx_uint           template_index,
    uint_32             parameter
)
{
#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_task_create(processor_number, template_index, parameter);
    }
#endif
    return _task_create_internal(processor_number, template_index, parameter, FALSE);
}
#endif /* MQX_LITE_VERSION_NUMBER */

#if MQX_ENABLE_USER_MODE

/*!
 * \brief Creates the task and make it ready.
 *
 * This function is an equivalent to the _task_create() API call but it can be
 * executed from within the User task or other code running in the CPU User mode.
 * Parameters passed to this function by pointer are required to meet the memory
 * protection requirements as described in the parameter list below.
 *
 * \param[in] processor_number One of the following:
 * \n - Processor number of the processor where the task is to be created.
 * \n - 0 (Create on the local processor.)
 * \param[in] template_index   One of the following:
 * \n - Index of the task template in the processor's task template list to use
 * for the child task.
 * \n - 0 (Use the task template that create_parameter defines.)
 * \param[in] parameter        Pointer:
 * \n - Template_index is not 0 (Pointer to the parameter that MQX passes to the
 * child task.)
 * \n - Template_index is 0 (Pointer to the task template.)
 *
 * \return Task ID of the child task (Success.)
 * \return MQX_NULL_TASK_ID (Failure.)
 *
 * \warning If the child is on another processor, blocks the creator until the
 * child is created.
 * \warning On failure, _task_set_error() is called to set the the following task
 * error codes:
 * \n - MQX_INVALID_PROCESSOR_NUMBER (Processor_number is not one of the allowed
 * processor numbers.)
 * \n - MQX_NO_TASK_TEMPLATE (Template_index is not in the task template list.)
 * \n - MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the task data structures.)
 * \warning If the child is on the same processor, preempts the creator if the
 * child is a higher priority.
 *
 * \see _task_create
 * \see _usr_task_abort
 * \see _usr_task_destroy
 * \see _usr_task_ready
 * \see _usr_task_set_error
 */
_task_id _usr_task_create
(
    _processor_number   processor_number,
    _mqx_uint           template_index,
    uint_32             parameter
)
{
    MQX_API_CALL_PARAMS params =
        {(uint_32)processor_number, (uint_32)template_index, (uint_32)parameter, 0, 0};

    return _mqx_api_call(MQX_API_TASK_CREATE, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

#if !MQX_LITE_VERSION_NUMBER
/*!
 * \brief Creates the task, but do not make it ready.
 *
 * \param[in] processor_number One of the following:
 * \n - Processor number of the processor where the task is to be created.
 * \n - 0 (Create on the local processor.)
 * \param[in] template_index   One of the following:
 * \n - Index of the task template in the processor's task template list to use
 * for the child task.
 * \n - 0 (Use the task template that create_parameter defines.)
 * \param[in] parameter        Pointer:
 * \n - Template_index is not 0 (Pointer to the parameter that MQX passes to the
 * child task.)
 * \n - Template_index is 0 (Pointer to the task template.)
 *
 * \return Task ID of the child task (Success.)
 * \return MQX_NULL_TASK_ID (Failure.)
 *
 * \warning If the child is on another processor, blocks the creator until the
 * child is created.
 * \warning On failure, _task_set_error() is called to set the the following task
 * error codes:
 * \n - MQX_INVALID_PROCESSOR_NUMBER (Processor_number is not one of the allowed
 * processor numbers.)
 * \n - MQX_NO_TASK_TEMPLATE (Template_index is not in the task template list.)
 * \n - MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the task data structures.)
 * \warning If the child is on the same processor, preempts the creator if the
 * child is a higher priority.
 *
 * \see _task_create
 * \see _task_create_at
 * \see _task_abort
 * \see _task_block
 * \see _task_destroy
 * \see _task_get_parameter
 * \see _task_get_parameter_for
 * \see _task_set_parameter
 * \see _task_set_parameter_for
 * \see _task_ready
 * \see _task_set_error
 */
_task_id _task_create_blocked
(
    _processor_number   processor_number,
    _mqx_uint           template_index,
    uint_32             parameter
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    TD_STRUCT_PTR            td_ptr;
#if MQX_IS_MULTI_PROCESSOR
    TASK_TEMPLATE_STRUCT_PTR task_template_ptr;
    boolean                  blocking;
#endif
    _task_id                 result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE4(KLOG_task_create_block, processor_number, template_index, parameter);

#if MQX_CHECK_ERRORS
    if (template_index & SYSTEM_TASK_FLAG)
    {
        _task_set_error(MQX_INVALID_TEMPLATE_INDEX);
        _KLOGX3(KLOG_task_create_block, MQX_NULL_TASK_ID,
                        MQX_INVALID_TEMPLATE_INDEX);
        return MQX_NULL_TASK_ID;
    } /* Endif */
#endif

    if (processor_number == 0)
    {
        processor_number = (_processor_number) kernel_data->INIT.PROCESSOR_NUMBER;
#if MQX_CHECK_ERRORS
    }
    else if (processor_number > MQX_MAX_PROCESSOR_NUMBER)
    {
        _task_set_error(MQX_INVALID_PROCESSOR_NUMBER);
        _KLOGX3(KLOG_task_create_block, MQX_NULL_TASK_ID,
                        MQX_INVALID_PROCESSOR_NUMBER);
        return MQX_NULL_TASK_ID;
#endif
    }
    else if (processor_number != kernel_data->INIT.PROCESSOR_NUMBER)
    {
#if MQX_IS_MULTI_PROCESSOR
        if ( kernel_data->IPC != NULL )
        {
#if MQX_TASK_CREATION_BLOCKS
            blocking = TRUE;
#else
            blocking = FALSE;
#endif
            if (template_index == 0)
            {
                /* Task template is pointed to by the parameter */
                task_template_ptr = (TASK_TEMPLATE_STRUCT_PTR)parameter;
                (*kernel_data->IPC)(blocking, processor_number,
                                KERNEL_MESSAGES, IPC_TASK_CREATE_WITH_TEMPLATE, 8L,
                                task_template_ptr->TASK_TEMPLATE_INDEX,
                                task_template_ptr->TASK_ADDRESS,
                                task_template_ptr->TASK_STACKSIZE,
                                task_template_ptr->TASK_PRIORITY,
                                task_template_ptr->TASK_NAME,
                                task_template_ptr->TASK_ATTRIBUTES,
                                task_template_ptr->CREATION_PARAMETER,
                                task_template_ptr->DEFAULT_TIME_SLICE
                );
            }
            else
            {
                (*kernel_data->IPC)(blocking, processor_number,
                                KERNEL_MESSAGES, IPC_TASK_CREATE, 3,
                                processor_number, template_index, parameter);
            } /* Endif */
            return(kernel_data->ACTIVE_PTR->INFO);
        }
        else
        {
#endif
        _task_set_error(MQX_INVALID_PROCESSOR_NUMBER);
        _KLOGX3(KLOG_task_create_block, MQX_NULL_TASK_ID,
                        MQX_INVALID_PROCESSOR_NUMBER);
        return MQX_NULL_TASK_ID;
#if MQX_IS_MULTI_PROCESSOR
    } /* Endif */
#endif
    } /* Endif */

    td_ptr = _task_build_internal(template_index, parameter, NULL, 0, FALSE);
    if (td_ptr != NULL)
    {
        td_ptr->STATE = BLOCKED;
        result = td_ptr->TASK_ID;
    }
    else
    {
        result = MQX_NULL_TASK_ID;
    }/* Endif */

    _KLOGX3(KLOG_task_create_block, result,
                    kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);

    return (result);

} /* Endbody */
#endif /* MQX_LITE_VERSION_NUMBER */

/*!
 * \brief Creates the task with the stack location specified.
 *
 * \param[in] processor_number One of the following:
 * \n - Processor number of the processor where the task is to be created.
 * \n - 0 (Create on the local processor.)
 * \param[in] template_index   One of the following:
 * \n - Index of the task template in the processor's task template list to use
 * for the child task.
 * \n - 0 (Use the task template that create_parameter defines.)
 * \param[in] parameter        Pointer:
 * \n - Template_index is not 0 (Pointer to the parameter that MQX passes to the
 * child task.)
 * \n - Template_index is 0 (Pointer to the task template.)
 * \param[in] stack_ptr        Pointer to where the stack and TD are to be created.
 * \param[in] stack_size       The size of the stack.
 *
 * \return Task ID of the child task (Success.)
 * \return MQX_NULL_TASK_ID (Failure.)
 *
 * \warning If the child is on another processor, blocks the creator until the
 * child is created.
 * \warning On failure, _task_set_error() is called to set the following task
 * error codes:
 * \n Task Error Codes
 * \n - MQX_INVALID_PROCESSOR_NUMBER (Processor_number is not one of the allowed
 * processor numbers.)
 * \n - MQX_NO_TASK_TEMPLATE (Template_index is not in the task template list.)
 * \n - MQX_OUT_OF_MEMORY (MQX cannot allocate memory for the task data structures.)
 *
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_abort
 * \see _task_block
 * \see _task_destroy
 * \see _task_get_parameter
 * \see _task_get_parameter_for
 * \see _task_set_parameter
 * \see _task_set_parameter_for
 * \see _task_ready
 * \see _task_set_error
 */
_task_id _task_create_at
(
    _processor_number   processor_number,
    _mqx_uint           template_index,
    uint_32             parameter,
    pointer             stack_ptr,
    _mem_size           stack_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR          td_ptr;
    _task_id               result;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE5(KLOG_task_create_at, processor_number, template_index, parameter,
                    stack_ptr);

#if MQX_CHECK_ERRORS
    if (template_index & SYSTEM_TASK_FLAG)
    {
        _task_set_error(MQX_INVALID_TEMPLATE_INDEX);
        _KLOGX3(KLOG_task_create_at, MQX_NULL_TASK_ID,
                        MQX_INVALID_TEMPLATE_INDEX);
        return MQX_NULL_TASK_ID;
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (processor_number != 0)
    {
        _task_set_error(MQX_INVALID_PROCESSOR_NUMBER);
        _KLOGX3(KLOG_task_create_at, MQX_NULL_TASK_ID,
                        MQX_INVALID_PROCESSOR_NUMBER);
        return MQX_NULL_TASK_ID;
    } /* Endif */
#endif

    td_ptr = _task_build_internal(template_index, parameter, stack_ptr, stack_size, FALSE);
    if (td_ptr != NULL)
    {
        result = td_ptr->TASK_ID;
        _INT_DISABLE();
        _task_ready_internal(td_ptr);
        _INT_ENABLE();
        _CHECK_RUN_SCHEDULER(); /* Let a higher priority task run */
    }
    else
    {
        result = MQX_NULL_TASK_ID;
    }/* Endif */

    _KLOGX3(KLOG_task_create_at, result,
                    kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);

    _tad_task_at_flag++;

    return (result);

} /* Endbody */

/*!
 * \private
 *
 * \brief Destroys the task.
 *
 * \param[in] task_id One of the following:
 * \n - Task ID of the task to be destroyed.
 * \n - MQX_NULL_TASK_ID (Destroy the calling task.)
 * \param[in] user    User mode functionality.
 *
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID
 *
 * \see _task_destroy
 * \see _usr_task_destroy
 */
_mqx_uint _task_destroy_internal
(
    _task_id task_id,
    boolean  user
)
{
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    TD_STRUCT_PTR            victim_ptr;
    TD_STRUCT_PTR            td_ptr;
    _processor_number        processor;
    uint_16                  task_num;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_task_destroy, task_id);

    if (task_id != MQX_NULL_TASK_ID) {
        processor = PROC_NUMBER_FROM_TASKID(task_id);
        if (processor != (_processor_number)kernel_data->INIT.PROCESSOR_NUMBER ) {
#if MQX_IS_MULTI_PROCESSOR
            if ( kernel_data->IPC != NULL ) {
                _KLOGX2(KLOG_task_destroy, MQX_OK);
                return( (*kernel_data->IPC)(FALSE, processor,
                                KERNEL_MESSAGES, IPC_TASK_DESTROY, 1, (_mqx_uint)task_id) );
            } else {
#endif
                _KLOGX2(KLOG_task_destroy, MQX_INVALID_TASK_ID);
                return(MQX_INVALID_TASK_ID);
#if MQX_IS_MULTI_PROCESSOR
            } /* Endif */
#endif
        }/* Endif */
    }/* Endif */

    victim_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);

#if MQX_ENABLE_USER_MODE
    /* check template for correct user task parameters */
    if (user) {
        if (!(victim_ptr->FLAGS & MQX_USER_TASK)) {
            return MQX_INVALID_TASK_ID;
        }
    }
#endif

    /* Make sure we are not trying to destroy the system task */
#if MQX_CHECK_ERRORS
    if ((victim_ptr == NULL) || (victim_ptr == SYSTEM_TD_PTR(kernel_data))) {
        _KLOGX2(KLOG_task_destroy, MQX_INVALID_TASK_ID);
        return MQX_INVALID_TASK_ID;
    } /* Endif */
#endif

    /* First, serialize task creation/destruction */
    _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    _int_disable();

    if (victim_ptr->STATE == DYING) {
        /* Task is already being destroyed */
        /* SPR P171-0021-01 re-enable interrupts */
        _int_enable();
        /* END SPR */
        _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);
        _KLOGX2(KLOG_task_destroy, MQX_OK);
        return MQX_OK;
    } /* Endif */

    /* remove the victim from any queues it may be in. */
    if (victim_ptr->STATE == READY) {
        if (victim_ptr != kernel_data->ACTIVE_PTR) {
            /* Remove other task from ready queue */
            _QUEUE_UNLINK(victim_ptr);
        } /* Endif */
    } else if (victim_ptr->STATE & IS_ON_TIMEOUT_Q) {
        /* Remove from time queue (uses NEXT, PREV field) */
        _TIME_DEQUEUE(victim_ptr, kernel_data);
    } else if (victim_ptr->STATE & TD_IS_ON_QUEUE) {
        /*
         * Remove from queue, where suspended
         * eg, MUTEX_BLOCKED, IO_BLOCKED, TASKQ_BLOCKED
         * (uses NEXT, PREV field)
         */
        _QUEUE_REMOVE(victim_ptr->INFO, victim_ptr);
    } /* Endif */

    if (victim_ptr->STATE & TD_IS_ON_AUX_QUEUE) {
        /*
         * Remove from queue, where suspended
         * eg, LWSEM_BLOCKED
         * (uses AUX_QUEUE field)
         */
        _QUEUE_REMOVE(victim_ptr->INFO, &victim_ptr->AUX_QUEUE);
    } /* Endif */

    victim_ptr->STATE   = DYING;

#if MQXCFG_ENABLE_FP && PSP_HAS_FPU
    /* Stop Floating point context monitoring */
    if (kernel_data->FP_ACTIVE_PTR == victim_ptr) {
        kernel_data->FP_ACTIVE_PTR = NULL;
    }/* Endif */
#endif

#if MQXCFG_ENABLE_DSP && PSP_HAS_DSP
    /* Stop DSP context monitoring */
    if (kernel_data->DSP_ACTIVE_PTR == victim_ptr) {
        kernel_data->DSP_ACTIVE_PTR = NULL;
    }/* Endif */
#endif

    _int_enable();

#if MQX_COMPONENT_DESTRUCTION
    {
        _mqx_uint i;
        for (i = 0; i < MAX_KERNEL_COMPONENTS; ++i) {
            if (kernel_data->COMPONENT_CLEANUP[i] != NULL) {
                (*kernel_data->COMPONENT_CLEANUP[i])(victim_ptr);
            }
        }
    }
#endif


    /* Save the task number */
    task_num = TASK_NUMBER_FROM_TASKID(victim_ptr->TASK_ID);

    td_ptr = kernel_data->ACTIVE_PTR;

#if !MQX_LITE_VERSION_NUMBER
    if ((victim_ptr->FLAGS & TASK_STACK_PREALLOCATED) == 0) {
        pointer block_ptr = _mem_get_next_block_internal(victim_ptr, NULL);
        while (block_ptr != NULL) {
            pointer next_block_ptr = _mem_get_next_block_internal(victim_ptr, block_ptr);
            if (td_ptr != victim_ptr) {
                _mem_transfer_internal(block_ptr, SYSTEM_TD_PTR(kernel_data));
            }

            /* dealloc everything else except td and stack */
            if ((block_ptr != victim_ptr) && (block_ptr != victim_ptr->STACK_ALLOC_BLOCK)) {
                _mem_free(block_ptr);
            }
            block_ptr = next_block_ptr;
        }
    }
#endif /* MQX_LITE_VERSION_NUMBER */

    victim_ptr->TASK_ID = TASK_ID_DYING;

    /* Start SPR P171-0017-01                */
    /* Remove td from linked list of all tds */
    if (_QUEUE_GET_SIZE(&kernel_data->TD_LIST) == 1) {
        /* Destroying the last task */
        kernel_data->TASK_NUMBER   = 1;
        kernel_data->INSERT_TD_PTR = NULL;
    } else if (kernel_data->TASK_NUMBER > task_num) {
        kernel_data->TASK_NUMBER   = task_num;
        kernel_data->INSERT_TD_PTR =
                        (TD_STRUCT_PTR)((uchar_ptr)victim_ptr->TD_LIST_INFO.PREV -
                                        FIELD_OFFSET(TD_STRUCT,TD_LIST_INFO));
    } /* Endif */
    _QUEUE_REMOVE(&kernel_data->TD_LIST, &victim_ptr->TD_LIST_INFO);
    /* End SPR P171-0017-01                  */

    /* Free up create/destroy for other tasks */
    _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    if (victim_ptr == td_ptr) {
        /* We are destroying the current task */
        _int_disable();
        _QUEUE_UNLINK(victim_ptr);  /* Remove myself from the ready queue */
        _psp_destroy_stack_frame(victim_ptr);
#if !MQX_LITE_VERSION_NUMBER
        if ((victim_ptr->FLAGS & TASK_STACK_PREALLOCATED) == 0) {
            if (victim_ptr->STACK_ALLOC_BLOCK) {
                _mem_transfer_internal(victim_ptr->STACK_ALLOC_BLOCK, SYSTEM_TD_PTR(kernel_data));
                _mem_free(victim_ptr->STACK_ALLOC_BLOCK);   /* Free the task's stack */
            }

            _mem_transfer_internal(victim_ptr, SYSTEM_TD_PTR(kernel_data));
            _mem_free(victim_ptr);   /* Free the task descriptor */
        } /* Endif */
#endif /* MQX_LITE_VERSION_NUMBER */
        /* Now we must jump to the scheduler */
        _sched_run_internal();   /* WILL NEVER RETURN FROM HERE */
    }/* Endif */

    _psp_destroy_stack_frame(victim_ptr);

#if !MQX_LITE_VERSION_NUMBER
    /* Free the task descriptor. */
    if ((victim_ptr->FLAGS & TASK_STACK_PREALLOCATED) == 0) {
        if (victim_ptr->STACK_ALLOC_BLOCK) {
            _mem_free(victim_ptr->STACK_ALLOC_BLOCK);   /* Free the task's stack */
        }
        _mem_free(victim_ptr);  /* Free the task descriptor */
    } /* Endif */
#endif /* MQX_LITE_VERSION_NUMBER */

#if MQX_ENABLE_USER_MODE
    if (victim_ptr->FLAGS & MQX_USER_TASK) {
        _int_disable();
        kernel_data->USR_TASK_RUN_COUNT--;
        _int_enable();
    }
#endif /* MQX_ENABLE_USER_MODE */

    _KLOGX2(KLOG_task_destroy, MQX_OK);
    return(MQX_OK);

}

/*!
 * \brief Destroys the task.
 *
 * This function does the following for the task being destroyed:
 * \n - Frees memory resources that the task allocated with functions from the
 * _mem and _partition families.
 * \n - Closes all queues that the task owns and frees all the queue elements.
 * \n - Frees any other component resources that the task owns.
 *
 * While _task_abort causes the destroy to happen from the context of the victim
 * and may be deferred indefinitely (or for a long time), _task_destroy causes
 * the task destroy to happen from the context of the caller and is performed
 * immediately.
 *
 * \param[in] task_id One of the following:
 * \n - Task ID of the task to be destroyed.
 * \n - MQX_NULL_TASK_ID (Destroy the calling task.)
 *
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID
 *
 * \warning If the task being destroyed is remote, blocks the calling task until
 * the task is destroyed.
 * \warning If the task being destroyed is local, does not block the calling task.
 * \warning If the task being destroyed is the active task, blocks it.
 *
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 * \see _task_get_creator
 * \see _task_get_id
 * \see _task_abort
 */
_mqx_uint _task_destroy
(
    _task_id task_id
)
{
#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_task_destroy(task_id);
    }
#endif

    return _task_destroy_internal(task_id, FALSE);
}


#if MQX_ENABLE_USER_MODE
/*!
 * \brief Destroys the task.
 *
 * This function is an equivalent to the _task_destroy() API call but it can be
 * executed from within the User task or other code running in the CPU User mode.
 * Parameters passed to this function by pointer are required to meet the memory
 * protection requirements as described in the parameter list below.
 *
 * \param[in] task_id One of the following:
 * \n - Task ID of the task to be destroyed.
 * \n - MQX_NULL_TASK_ID (Destroy the calling task.)
 *
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID
 *
 * \warning If the task being destroyed is remote, blocks the calling task until
 * the task is destroyed.
 * \warning If the task being destroyed is local, does not block the calling task.
 * \warning If the task being destroyed is the active task, blocks it.
 *
 * \see _task_destroy
 * \see _usr_task_create
 * \see _usr_task_abort
 */
_mqx_uint _usr_task_destroy
(
    _task_id task_id
)
{
    MQX_API_CALL_PARAMS params = {(uint_32)task_id, 0, 0, 0, 0};
    return _mqx_api_call(MQX_API_TASK_DESTROY, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

#if MQXCFG_ENABLE_FP && PSP_HAS_FPU
#if !MQX_LITE_VERSION_NUMBER

/*!
 * \brief Enables floating-point context switching for the active task.
 *
 * When MQX performs a context switch (due to _task_enable_fp call), floating-point
 * registers are saved and restored. Otherwise ( _task_disable_fp call) floating-point
 * registers are not saved and restored.
 *
 * \warning Changes context information that MQX stores.
 *
 * \see _task_disable_fp
 */
boolean _task_enable_fp(void)
{
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR td_ptr;
    boolean res = TRUE;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE1(KLOG_task_enable_fp);

    td_ptr = kernel_data->ACTIVE_PTR;
    _int_disable();

    if (NULL == td_ptr->FLOAT_CONTEXT_PTR)
    {
        /* we dont have allocated space for fp context... try allocate it */
        _psp_build_float_context(td_ptr);
    }

    if (NULL != td_ptr->FLOAT_CONTEXT_PTR)
    {
        /* we have allocated space for fp context */
        td_ptr->FLAGS |= MQX_FLOATING_POINT_TASK;
        if (kernel_data->FP_ACTIVE_PTR != NULL)
        {
            if (kernel_data->FP_ACTIVE_PTR != kernel_data->ACTIVE_PTR)
            {
                _psp_save_fp_context_internal();
            }
        }
        kernel_data->FP_ACTIVE_PTR = kernel_data->ACTIVE_PTR;
    }
    else
    {
        /* some problem - TD dont have allocated space for fp context */
        res = FALSE;
    }

    _int_enable();
    _KLOGX1(KLOG_task_enable_fp);

    return res;
}

/*!
 * \brief Disables floating-point context switching for the active task if the
 * task is a floating-point task.
 *
 * When MQX performs a context switch (due to _task_enable_fp call), floating-point
 * registers are saved and restored. Otherwise ( _task_disable_fp call) floating-point
 * registers are not saved and restored.
 *
 * \warning Changes context information that MQX stores.
 *
 * \see _task_enable_fp
 */
void _task_disable_fp(void)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR                   td_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE1(KLOG_task_disable_fp);

    td_ptr = kernel_data->ACTIVE_PTR;
    _int_disable();
    if (td_ptr->FLAGS & MQX_FLOATING_POINT_TASK)
    {
        td_ptr->FLAGS &= ~MQX_FLOATING_POINT_TASK;
        kernel_data->FP_ACTIVE_PTR = NULL;
    }

    if (NULL != td_ptr->FLOAT_CONTEXT_PTR)
    {
        /* deallocate fp context area */
        _mem_free(td_ptr->FLOAT_CONTEXT_PTR);
        td_ptr->FLOAT_CONTEXT_PTR = NULL;
    }

    _int_enable();
    _KLOGX1(KLOG_task_disable_fp);

} /* Endbody */
#endif /* MQX_LITE_VERSION_NUMBER */
#endif /* MQXCFG_ENABLE_FP && PSP_HAS_FPU */

#if MQX_HAS_TASK_ENVIRONMENT

/*!
 * \brief Sets the address of the application-specific environment data for the task.
 *
 * \param[in] task_id         Task ID of the task whose environment is to be set.
 * \param[in] environment_ptr Pointer to the environment data.
 *
 * \return Previous environment data (Success.)
 * \return NULL (Failure.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code to
 * MQX_INVALID_TASK_ID.
 *
 * \see _task_get_environment
 * \see _task_get_parameter
 * \see _task_get_parameter_for
 * \see _task_set_parameter
 * \see _task_set_parameter_for
 * \see _task_set_error
 */
pointer _task_set_environment
(
    _task_id    task_id,
    pointer     environment_ptr
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    TD_STRUCT_PTR td_ptr;
    pointer       old_env_ptr;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE3(KLOG_task_set_environment, task_id, environment_ptr);

    td_ptr = (TD_STRUCT_PTR) _task_get_td(task_id);
    if (td_ptr == NULL)
    {
        _task_set_error(MQX_INVALID_TASK_ID);
        _KLOGX2(KLOG_task_set_environment, NULL);
        return (NULL);
    }/* Endif */

    old_env_ptr = td_ptr->ENVIRONMENT_PTR;
    td_ptr->ENVIRONMENT_PTR = environment_ptr;

    _KLOGX2(KLOG_task_set_environment, old_env_ptr);
    return (old_env_ptr);

} /* Endbody */

/*!
 * \brief Gets a pointer to the application-specific environment data for the task.
 *
 * \param[in] task_id Task ID of the task whose environment is to be obtained.
 *
 * \return Environment data (Success.)
 * \return NULL (Failure.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code to
 * MQX_INVALID_TASK_ID.
 *
 * \see _task_set_environment
 * \see _task_get_parameter
 * \see _task_get_parameter_for
 * \see _task_set_parameter
 * \see _task_set_parameter_for
 * \see _task_set_error
 */
pointer _task_get_environment
(
    _task_id task_id
)
{ /* Body */
    TD_STRUCT_PTR td_ptr;

    td_ptr = (TD_STRUCT_PTR) _task_get_td(task_id);
    if (td_ptr == NULL)
    {
        _task_set_error(MQX_INVALID_TASK_ID);
        return (NULL);
    }/* Endif */

    return (td_ptr->ENVIRONMENT_PTR);

} /* Endbody */

#endif /* MQX_HAS_TASK_ENVIRONMENT */

#if MQX_HAS_EXCEPTION_HANDLER

/*!
 * \brief Gets a pointer to the task exception handler.
 *
 * \param[in] task_id Task ID of the task whose exception handler is to be obtained.
 *
 * \return Pointer to the task exception handler for the task (might be NULL).
 * \return NULL (Task ID is not valid.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code to
 * MQX_INVALID_TASK_ID.
 *
 * \see _task_set_exception_handler
 * \see _task_get_exit_handler
 * \see _task_set_exit_handler
 * \see _int_exception_isr
 * \see _task_set_error
 */
TASK_EXCEPTION_FPTR _task_get_exception_handler
(
    _task_id        task_id
)
{ /* Body */
    TD_STRUCT_PTR       td_ptr;
    TASK_EXCEPTION_FPTR excpt_function;

    td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);
    if ( td_ptr == NULL )
    {
        _task_set_error(MQX_INVALID_TASK_ID);
        return( NULL );
    }/* Endif */

    excpt_function   = td_ptr->EXCEPTION_HANDLER_PTR;

    return(excpt_function);

} /* Endbody */

/*!
 * \brief Sets the address of the task exception handler.
 *
 * \param[in] task_id         Task ID of the task whose exception handler is to be set.
 * \param[in] handler_address Pointer to the task exception handler.
 *
 * \return Pointer to the previous task exception handler (might be NULL).
 * \return NULL (Task ID is not valid.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code to
 * MQX_INVALID_TASK_ID.
 *
 * \see _task_get_exception_handler
 * \see _task_get_exit_handler
 * \see _task_set_exit_handler
 * \see _int_exception_isr
 * \see _task_set_error
 */
TASK_EXCEPTION_FPTR _task_set_exception_handler
(
    _task_id            task_id,
    TASK_EXCEPTION_FPTR handler_address
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    TD_STRUCT_PTR       td_ptr;
    TASK_EXCEPTION_FPTR old_function;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE3(KLOG_task_set_exception_handler, task_id, handler_address);

    td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);
    if ( td_ptr == NULL )
    {
        _task_set_error(MQX_INVALID_TASK_ID);
        _KLOGX2(KLOG_task_set_exception_handler, NULL);
        return( NULL );
    } /* Endif */

    old_function = td_ptr->EXCEPTION_HANDLER_PTR;
    td_ptr->EXCEPTION_HANDLER_PTR = handler_address;

    _KLOGX2(KLOG_task_set_exception_handler, old_function);
    return(old_function);

} /* Endbody */

#endif /* MQX_HAS_EXCEPTION_HANDLER */

#if MQX_HAS_EXIT_HANDLER
/*!
 * \brief Gets a pointer to the task exit handler for the task.
 *
 * MQX calls a task's task exit handler if either of these conditions is true:
 * \n - Task is terminated with _task_abort().
 * \n - Task returns from its function body (for example, if it calls _mqx_exit()).
 *
 * \param[in] task_id Task ID of the task whose exit handler is to be obtained.
 *
 * \return Pointer to the exit handler (might be NULL).
 * \return NULL (Task_id is not valid.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code to
 * MQX_INVALID_TASK_ID.
 *
 * \see _task_set_exit_handler
 * \see _mqx_exit
 * \see _task_get_exception_handler
 * \see _task_set_exception_handler
 * \see _task_abort
 * \see _task_set_error
 */
TASK_EXIT_FPTR _task_get_exit_handler
(
    _task_id        task_id
)
{ /* Body */
    TD_STRUCT_PTR  td_ptr;
    TASK_EXIT_FPTR exit_function;

    td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);
    if ( td_ptr == NULL )
    {
        _task_set_error(MQX_INVALID_TASK_ID);
        return( NULL );
    }/* Endif */

    exit_function = td_ptr->EXIT_HANDLER_PTR;

    return(exit_function);
} /* Endbody */

/*!
 * \brief Sets the address of the task exit handler for the task.
 *
 * MQX calls a task's task exit handler if either of these conditions is true:
 * \n - Task is terminated with _task_abort().
 * \n - Task returns from its function body (for example, if it calls _mqx_exit()).
 *
 * \param[in] task_id              Task ID of the task whose exit handler is to be set.
 * \param[in] exit_handler_address Pointer to the exit handler for the task.
 *
 * \return Pointer to the previous exit handler (might be NULL).
 * \return NULL (Task_id is not valid.)
 *
 * \warning On failure, calls _task_set_error() to set the task error code to
 * MQX_INVALID_TASK_ID.
 *
 * \see _task_get_exit_handler
 * \see _mqx_exit
 * \see _task_get_exception_handler
 * \see _task_set_exception_handler
 * \see _task_abort
 * \see _task_set_error
 */
TASK_EXIT_FPTR _task_set_exit_handler
(
    _task_id       task_id,
    TASK_EXIT_FPTR exit_handler_address
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data;)
    TD_STRUCT_PTR  td_ptr;
    TASK_EXIT_FPTR old_function;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)
    _KLOGE3(KLOG_task_set_exit_handler, task_id, exit_handler_address);

    td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);
    if ( td_ptr == NULL )
    {
        _task_set_error(MQX_INVALID_TASK_ID);
        _KLOGX2(KLOG_task_set_exit_handler, NULL);
        return( NULL );
    }/* Endif */

    old_function = td_ptr->EXIT_HANDLER_PTR;
    td_ptr->EXIT_HANDLER_PTR = exit_handler_address;

    _KLOGX2(KLOG_task_set_exit_handler, old_function);
    return(old_function);

} /* Endbody */

#endif /* MQX_HAS_EXIT_HANDLER */

#if MQX_TD_HAS_TASK_TEMPLATE_PTR
/*!
 * \brief Gets the task ID that is associated with the task name.
 *
 * This function uses a task name (from its task template) to find a task id. Only
 * the first task found with the provided name is found.
 *
 * \param[in] name_ptr Pointer to the name to find in the task template list.
 *
 * \return Task ID that is associated with the first match of name_ptr.
 * \return MQX_NULL_TASK_ID (Name is not in the task template list.)
 *
 * \see _task_get_creator
 * \see _task_get_processor
 * \see _task_get_id
 */
_task_id _task_get_id_from_name
(
    char_ptr name_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    TD_STRUCT_PTR           td_ptr;
    _mqx_uint               size;

    _GET_KERNEL_DATA(kernel_data);

    _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    td_ptr = (TD_STRUCT_PTR)((uchar_ptr)kernel_data->TD_LIST.NEXT -
             FIELD_OFFSET(TD_STRUCT,TD_LIST_INFO));
    size   = _QUEUE_GET_SIZE(&kernel_data->TD_LIST);

    while (size && td_ptr)
    {
        if (strncmp( td_ptr->TASK_TEMPLATE_PTR->TASK_NAME, name_ptr,
                        MQX_MAX_TASK_NAME_SIZE) == 0)
        {
            _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);
            return td_ptr->TASK_ID;
        } /* Endif */
        size--;
        td_ptr = (TD_STRUCT_PTR)((uchar_ptr)(td_ptr->TD_LIST_INFO.NEXT) -
                 FIELD_OFFSET(TD_STRUCT,TD_LIST_INFO));
    } /* Endwhile */

    _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    return MQX_NULL_TASK_ID;

} /* Endbody */

/*!
 * \brief Gets the pointer to the task template for the task ID.
 *
 * \param[in] task_id Task ID for the task for which to get pointer.
 *
 * \return Pointer to the task's task template. NULL if an invalid task_id is
 * presented.
 *
 * \see _task_get_template_index
 * \see _task_get_index_from_id
 * \see TASK_TEMPLATE_STRUCT
 */
TASK_TEMPLATE_STRUCT_PTR  _task_get_template_ptr
(
    _task_id  task_id
)
{ /* Body */
    TD_STRUCT_PTR  td_ptr;

    td_ptr = _task_get_td(task_id);

    return (td_ptr ? td_ptr->TASK_TEMPLATE_PTR : NULL);

} /* Endbody */

#endif /* MQX_TD_HAS_TASK_TEMPLATE_PTR */

/*!
 * \brief Gets the task template index that is associated with the task name.
 *
 * \param[in] name_ptr Pointer to the name to find in the task template list.
 *
 * \return Task template index that is associated with the first match of name_ptr.
 * \return MQX_NULL_TASK_ID (Name is not in the task template list.)
 *
 * \see _task_get_id_from_name
 * \see _task_get_index_from_id
 */
_mqx_uint  _task_get_template_index
(
    char_ptr name_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    TASK_TEMPLATE_STRUCT_PTR task_template_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    /* Search all the local task templates for one whose index matches */
    task_template_ptr = kernel_data->INIT.TASK_TEMPLATE_LIST;

    while (task_template_ptr->TASK_TEMPLATE_INDEX)
    {
        if (task_template_ptr->TASK_NAME != NULL)
        {
            if (strncmp( task_template_ptr->TASK_NAME, name_ptr,
                            MQX_MAX_TASK_NAME_SIZE) == 0)
            {
                break;
            } /* Endif */
        } /* Endif */
        ++task_template_ptr;
    } /* Endwhile */

    _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    return task_template_ptr->TASK_TEMPLATE_INDEX;

} /* Endwhile */

/*!
 * \brief Gets the task ID out of the task descriptor.
 *
 * \param[in] td_ptr Pointer to the task descriptor.
 *
 * \return TASK_ID Task ID
 * \return MQX_NULL_TASK_ID
 */
_task_id _task_get_id_from_td
(
    pointer td_ptr
)
{
    if (NULL == td_ptr)
    {
        return MQX_NULL_TASK_ID;
    }
    return ((TD_STRUCT_PTR)td_ptr)->TASK_ID;
}

#if MQX_TD_HAS_TASK_TEMPLATE_PTR || MQX_TD_HAS_TEMPLATE_INDEX

/*!
 * \brief Gets the task template index for the task ID.
 *
 * \param[in] task_id Task ID to look up.
 *
 * \return Task template index.
 * \return 0 (Task ID was not found.)
 *
 * \see _task_get_template_index
 */
_mqx_uint _task_get_index_from_id
(
    _task_id task_id
)
{ /* Body */
    TD_STRUCT_PTR           td_ptr;

    td_ptr = _task_get_td(task_id);

    if (td_ptr == NULL)
    {
        return 0;
    } /* Endif */

#if MQX_TD_HAS_TASK_TEMPLATE_PTR
    return td_ptr->TASK_TEMPLATE_PTR->TASK_TEMPLATE_INDEX;
#elif MQX_TD_HAS_TEMPLATE_INDEX
    return td_ptr->TEMPLATE_INDEX;
#else
    return 0;
#endif

} /* Endbody */
#endif /* MQX_TD_HAS_TASK_TEMPLATE_PTR || MQX_TD_HAS_TEMPLATE_INDEX */

/*!
 * \brief Gets the task creation parameter of the active task.
 *
 * If a deeply nested function needs the task creation parameter, it can get the
 * parameter with _task_get_parameter() or _task_get_parameter_for() rather than
 * have the task's main body pass the parameter to it.
 *
 * \return Creation parameter (might be NULL).
 *
 * \see _task_get_parameter_for
 * \see _task_set_parameter
 * \see _task_set_parameter_for
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 */
uint_32 _task_get_parameter(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    return _task_get_parameter_internal(kernel_data->ACTIVE_PTR);

} /* Endbody */

/*!
 * \brief Gets the task creation parameter of the specified task.
 *
 * If a deeply nested function needs the task creation parameter, it can get the
 * parameter with _task_get_parameter() or _task_get_parameter_for() rather than
 * have the task's main body pass the parameter to it.
 *
 * \param[in] tid Task ID of the task to get creation parameter from.
 *
 * \return Creation parameter (might be NULL).
 *
 * \see _task_get_parameter
 * \see _task_set_parameter
 * \see _task_set_parameter_for
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 */
uint_32 _task_get_parameter_for
(
    _task_id  tid
)
{ /* Body */
    TD_STRUCT_PTR td_ptr;

    td_ptr = (TD_STRUCT_PTR)_task_get_td(tid);

    return _task_get_parameter_internal(td_ptr);

} /* Endbody */

/*!
 * \private
 *
 * \brief Gets the task creation parameter of the specified task.
 *
 * \param[in] td_ptr Task ID of the task to get creation parameter from.
 *
 * \return Creation parameter (might be NULL).
 *
 * \see _task_get_parameter
 * \see _task_get_parameter_for
 *
 * \see TD_STRUCT
 */
uint_32 _task_get_parameter_internal
(
    TD_STRUCT_PTR td_ptr
)
{
    PSP_STACK_START_STRUCT_PTR stack_start_ptr;
    stack_start_ptr = _psp_get_stack_start(td_ptr);
    return PSP_TASK_PARAM(stack_start_ptr);
}

/*!
 * \brief Sets the task creation parameter of the active task.
 *
 * \param[in] new_value Value to set the task parameter to.
 *
 * \return Previous creation parameter (might be NULL).
 *
 * \see _task_get_parameter
 * \see _task_get_parameter_for
 * \see _task_set_parameter_for
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 */
uint_32 _task_set_parameter
(
    uint_32 new_value
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    uint_32                    old_value;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_task_set_parameter, new_value);

    old_value = _task_set_parameter_internal(new_value, kernel_data->ACTIVE_PTR);

    _KLOGX2(KLOG_task_set_parameter, old_value);
    return old_value;

} /* Endbody */

/*!
 * \brief Sets the task creation parameter of the specified task.
 *
 * \param[in] new_value Value to set the task parameter to.
 * \param[in] tid       Task ID of the task to set.
 *
 * \return Previous creation parameter (might be NULL).
 *
 * \see _task_get_parameter
 * \see _task_get_parameter_for
 * \see _task_set_parameter
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 */
uint_32 _task_set_parameter_for
(
    uint_32   new_value,
    _task_id  tid
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    TD_STRUCT_PTR           td_ptr;
    uint_32                 old_value;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_task_set_parameter_for, tid, new_value);

    td_ptr = (TD_STRUCT_PTR)_task_get_td(tid);
#if MQX_CHECK_ERRORS
    if (td_ptr == NULL)
    {
        _KLOGX3(KLOG_task_set_parameter_for, tid, MQX_INVALID_PARAMETER);
        return 0;
    } /* Endif */
#endif

    old_value = _task_set_parameter_internal(new_value, td_ptr);

    _KLOGX2(KLOG_task_set_parameter_for, old_value);
    return old_value;

} /* Endbody */

/*!
 * \private
 *
 * \brief Sets the task creation parameter of the specified task.
 *
 * \param[in] new_value Value to set the task parameter to.
 * \param[in] td_ptr    Task ID of the task to set.
 *
 * \return Previous creation parameter (might be NULL).
 *
 * \see _task_set_parameter
 * \see _task_set_parameter_for
 * \see TD_STRUCT
 */
uint_32 _task_set_parameter_internal
(
    uint_32       new_value,
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    PSP_STACK_START_STRUCT_PTR stack_start_ptr;
    uint_32                    old_value;

    stack_start_ptr = _psp_get_stack_start(td_ptr);

    old_value = PSP_TASK_PARAM(stack_start_ptr);
    PSP_TASK_PARAM(stack_start_ptr) = new_value;

    return old_value;

} /* Endbody */

#if MQX_HAS_DYNAMIC_PRIORITIES

/*!
 * \brief Gets the priority of the task.
 *
 * \param[in]  task_id      One of the following:
 * \n - Task ID of the task for which to set or get info.
 * \n - MQX_NULL_TASK_ID (Use the calling task.)
 * \param[out] priority_ptr Pointer to the priority.
 *
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID (Task_id does not represent a currently valid task.)
 *
 * \warning Might dispatch a task.
 *
 * \see _task_set_priority
 * \see _task_get_creator
 * \see _task_get_processor
 * \see _sem_create
 * \see _sem_create_fast
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until
 * \see _mutatr_get_sched_protocol
 * \see _mutatr_set_sched_protocol
 * \see _mutex_lock
 */
_mqx_uint _task_get_priority
(
    _task_id      task_id,
    _mqx_uint_ptr priority_ptr
)
{ /* Body */
    TD_STRUCT_PTR           td_ptr;

    td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);
    if (td_ptr == NULL)
    {
        return(MQX_INVALID_TASK_ID);
    } /* Endif */
    *priority_ptr = td_ptr->HOME_QUEUE->PRIORITY;
    return MQX_OK;

} /* Endbody */

/*!
 * \brief Sets the priority of the task.
 *
 * MQX might boost the priority of a task that waits for a semaphore or locks a
 * mutex. If MQX has boosted the priority of the task that is specified by task_id,
 * _task_set_priority() will raise but not lower the task's priority.
 * \n If the task is in the blocked state, priority change takes place when task
 * is ready.
 * \n When the task is in the ready state, priority change takes place immediately.
 *
 * \param[in]  task_id      One of the following:
 * \n - Task ID of the task for which to set or get info.
 * \n - MQX_NULL_TASK_ID (Use the calling task.)
 * \param[in]  new_priority New task priority.
 * \param[out] priority_ptr Pointer to the previous task priority.
 *
 * \return MQX_OK
 * \return MQX_INVALID_TASK_ID (Task_id does not represent a currently valid task.)
 * \return MQX_INVALID_PARAMETER (New_priority is numerically greater than the
 * lowest-allowable priority of an application task.)
 *
 * \warning Might dispatch a task.
 *
 * \see _task_get_priority
 * \see _task_get_creator
 * \see _task_get_processor
 * \see _sem_create
 * \see _sem_create_fast
 * \see _sem_wait
 * \see _sem_wait_for
 * \see _sem_wait_ticks
 * \see _sem_wait_until
 * \see _mutatr_get_sched_protocol
 * \see _mutatr_set_sched_protocol
 * \see _mutex_lock
 */
_mqx_uint _task_set_priority
(
    _task_id     task_id,
    _mqx_uint     new_priority,
    _mqx_uint_ptr priority_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    READY_Q_STRUCT_PTR      ready_q_ptr;
    TD_STRUCT_PTR           td_ptr;
    TASK_QUEUE_STRUCT_PTR   task_queue_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_task_set_priority, task_id, new_priority);

#if MQX_CHECK_ERRORS
    if (new_priority > kernel_data->LOWEST_TASK_PRIORITY)
    {
        _KLOGX2(KLOG_task_set_priority, MQX_INVALID_PARAMETER);
        return(MQX_INVALID_PARAMETER);
    }/* Endif */
#endif

    td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);
    if (td_ptr == NULL)
    {
        _KLOGX2(KLOG_task_set_priority, MQX_INVALID_TASK_ID);
        return(MQX_INVALID_TASK_ID);
    } /* Endif */

    _int_disable();
    /* Return old priority */
    *priority_ptr = td_ptr->HOME_QUEUE->PRIORITY;

    /* Make the change permanent */
    ready_q_ptr = kernel_data->READY_Q_LIST;
    td_ptr->HOME_QUEUE = ready_q_ptr - new_priority;

    if (td_ptr->BOOSTED)
    {
        /* Can only change priority to a higher (lower value) */
        if (new_priority < td_ptr->MY_QUEUE->PRIORITY)
        {
            /* Move the task to the correct priority level */
            _sched_set_priority_internal(td_ptr, new_priority);
        } /* Endif */
    }
    else
    {
        /* Move the task to the correct priority level */
        _sched_set_priority_internal(td_ptr, new_priority);
    } /* Endif */

    if (td_ptr->STATE == TASK_QUEUE_BLOCKED)
    {
        task_queue_ptr = (TASK_QUEUE_STRUCT_PTR)
                         ((uchar_ptr)td_ptr->INFO - FIELD_OFFSET(TASK_QUEUE_STRUCT, TD_QUEUE));
        if (task_queue_ptr->POLICY & MQX_TASK_QUEUE_BY_PRIORITY)
        {
            /* Requeue the td by priority */
            _QUEUE_REMOVE(&task_queue_ptr->TD_QUEUE, td_ptr);
            _sched_insert_priorityq_internal(&task_queue_ptr->TD_QUEUE, td_ptr);
        }/* Endif */
    }/* Endif */

    /* Allow higher priority tasks to run */
    _CHECK_RUN_SCHEDULER();

    _int_enable();

    _KLOGX2(KLOG_task_set_priority, MQX_OK);
    return MQX_OK;

} /* Endbody */

#endif /* MQX_HAS_DYNAMIC_PRIORITIES */

/*!
 * \brief Makes the task ready to run by putting it in its ready queue.
 *
 * This function is the only way to make ready a task that called _task_block().
 *
 * \param[in] td Pointer to the task descriptor of the task (on this processor)
 * to be made ready.
 *
 * \warning If the new ready task has higher priority than the calling task,
 * MQX makes the new ready task active.
 * \warning Might set one of the following task error codes:
 * \n - MQX_INVALID_TASK_ID (Task_id is not valid for this processor.)
 * \n - MQX_INVALID_TASK_STATE (Task is already in its ready queue.)
 *
 * \see _task_block
 * \see _time_dequeue
 * \see _taskq_resume
 */
void _task_ready
(
    pointer td
)
{
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    TD_STRUCT_PTR           td_ptr = (TD_STRUCT_PTR)td;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        _usr_task_ready(td);
        return;
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    /* Perform a validity check on the td */
#if MQX_CHECK_ERRORS
    if (PROC_NUMBER_FROM_TASKID(td_ptr->TASK_ID) != kernel_data->INIT.PROCESSOR_NUMBER)
    {
        _KLOGE2(KLOG_task_ready, td_ptr);
        _task_set_error(MQX_INVALID_TASK_ID);
        _KLOGX1(KLOG_task_ready);
        return;
    }
#endif

    _INT_DISABLE();

    if (td_ptr->STATE == READY)
    {
        /* The task is already on the ready to run Queue! */
        _int_enable();
        _KLOGE2(KLOG_task_ready, td_ptr);
        _task_set_error(MQX_INVALID_TASK_STATE);
        _KLOGX1(KLOG_task_ready);
        return;
    }/* Endif */

    _task_ready_internal(td_ptr);

    _INT_ENABLE();

    _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */
}

#if MQX_ENABLE_USER_MODE

/*!
 * \brief Makes the task ready to run by putting it in its ready queue.
 *
 * This function is an equivalent to the _task_ready() API call but it can be
 * executed from within the User task or other code running in the CPU User mode.
 * Parameters passed to this function by pointer are required to meet the memory
 * protection requirements as described in the parameter list below.
 *
 * \param[in] td Pointer to the task descriptor of the task (on this processor)
 * to be made ready.
 *
 * \warning If the new ready task has higher priority than the calling task,
 * MQX makes the new ready task active.
 * \warning Might set one of the following task error codes:
 * \n - MQX_INVALID_TASK_ID (Task_id is not valid for this processor.)
 * \n - MQX_INVALID_TASK_STATE (Task is already in its ready queue.)
 *
 * \see _task_ready
 */
void _usr_task_ready
(
    pointer td
)
{
    MQX_API_CALL_PARAMS params = {(uint_32)td, 0, 0, 0, 0};
    _mqx_api_call(MQX_API_TASK_READY, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

#if MQX_TD_HAS_TASK_TEMPLATE_PTR

/*!
 * \brief Restart the specified task.
 *
 * Restart the task specified by the given task_id (the victim).
 * \n All of the victim's resources are released, specifically all queues are
 * closed and all memory is freed.
 * \n Component cleanup functions are called to free any component resources
 * owned by this task.
 *
 * \param[in] task_id   Task ID of the task to restart.
 * \param[in] param_ptr One of the following:
 * \n - Pointer to a new task creation parameter.
 * \n - NULL (victim's creation parameter used).
 * \param[in] blocked   Whether the task should be restarted in the blocked state or not.
 *
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_TASK_ID (Task_id is invalid.)
 * \return MQX_OUT_OF_MEMORY (Not enough memory to rebuild stack.)
 *
 * \warning Cannot be called from an ISR.
 *
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 */
static _mqx_uint _task_restart_func
(
    _task_id    task_id,
    uint_32_ptr param_ptr,
    boolean     blocked
)
{ /* Body */
    PSP_STACK_START_STRUCT_PTR  stack_start_ptr;
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    TASK_TEMPLATE_STRUCT_PTR    template_ptr;
    TD_STRUCT_PTR               victim_ptr;
    TD_STRUCT_PTR               td_ptr;
    READY_Q_STRUCT_PTR          ready_q_ptr;
    char_ptr                    stack_ptr;
    uint_32                     create_param;
    _processor_number           processor;
    _mem_size                   stack_size;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_task_restart, task_id);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        /* Cannot be called from an ISR */
        _KLOGX2(KLOG_task_restart, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    if (task_id != MQX_NULL_TASK_ID)
    {
        processor = PROC_NUMBER_FROM_TASKID(task_id);
        if (processor != (_processor_number)kernel_data->INIT.PROCESSOR_NUMBER )
        {
#if MQX_IS_MULTI_PROCESSOR
            if ( kernel_data->IPC != NULL )
            {
                _KLOGX2(KLOG_task_restart, MQX_OK);
                return( (*kernel_data->IPC)(FALSE, processor,
                                KERNEL_MESSAGES, IPC_TASK_RESTART, 3, (_mqx_uint)task_id,
                                (_mqx_uint)param_ptr, (_mqx_uint)blocked));
            }
            else
            {
#endif
                _KLOGX2(KLOG_task_restart, MQX_INVALID_TASK_ID);
                return(MQX_INVALID_TASK_ID);
#if MQX_IS_MULTI_PROCESSOR
            } /* Endif */
#endif
        }/* Endif */
    }/* Endif */

    victim_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);

#if MQX_CHECK_ERRORS
    if (victim_ptr == NULL)
    {
        _KLOGX2(KLOG_task_restart, MQX_INVALID_TASK_ID);
        return(MQX_INVALID_TASK_ID);
    } /* Endif */

    if (victim_ptr == SYSTEM_TD_PTR(kernel_data))
    {
        _KLOGX2(KLOG_task_restart, MQX_INVALID_TASK_ID);
        return(MQX_INVALID_TASK_ID);
    } /* Endif */
#endif

    /* First, serialize task creation/destruction/restart */
    _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    _int_disable();
    /* remove the victim from any queues it may be in. */
    if (victim_ptr->STATE == READY)
    {
        if (victim_ptr != kernel_data->ACTIVE_PTR)
        {
            /* Remove other task from ready queue */
            _QUEUE_UNLINK(victim_ptr);
        } /* Endif */
    }
    else if (victim_ptr->STATE & IS_ON_TIMEOUT_Q)
    {
        /* Remove from time queue */
        _TIME_DEQUEUE(victim_ptr, kernel_data);
    }
    else if (victim_ptr->STATE & TD_IS_ON_QUEUE)
    {
        /* Remove from queue, where suspended
         * eg, MUTEX_BLOCKED, IO_BLOCKED, TASKQ_BLOCKED
         */
        _QUEUE_REMOVE(victim_ptr->INFO, victim_ptr);
    } /* Endif */

    if (victim_ptr->STATE & TD_IS_ON_AUX_QUEUE)
    {
        /*
         * Remove from queue, where suspended
         * eg, LWSEM_BLOCKED
         * (uses AUX_QUEUE field)
         */
        _QUEUE_REMOVE(victim_ptr->INFO, &victim_ptr->AUX_QUEUE);
    } /* Endif */

    victim_ptr->STATE   = DYING;

#if MQXCFG_ENABLE_FP && PSP_HAS_FPU
    /* Stop Floating point context monitoring */
    if (kernel_data->FP_ACTIVE_PTR == victim_ptr)
    {
        kernel_data->FP_ACTIVE_PTR = NULL;
    }/* Endif */
#endif

    _int_enable();

#if MQX_COMPONENT_DESTRUCTION
    {
        _mqx_uint   i;
        for (i = 0; i < MAX_KERNEL_COMPONENTS; ++i)
        {
            if (kernel_data->COMPONENT_CLEANUP[i] != NULL)
            {
                (*kernel_data->COMPONENT_CLEANUP[i])(victim_ptr);
            } /* Endif */
        } /* Endfor */
    }
#endif

    td_ptr = kernel_data->ACTIVE_PTR;
#if !MQX_LITE_VERSION_NUMBER
    {
        pointer                     block_ptr;
        block_ptr = _mem_get_next_block_internal(victim_ptr, NULL);
        while (block_ptr != NULL)
        {
            if (block_ptr           == victim_ptr ||
                MEM_TYPE_TD         == GET_MEMBLOCK_TYPE(block_ptr) ||
                MEM_TYPE_TASK_STACK == GET_MEMBLOCK_TYPE(block_ptr))
            {

                block_ptr = _mem_get_next_block_internal (victim_ptr, block_ptr);
                if (block_ptr == victim_ptr)
                    break;
            }
            else
            {
                _mem_transfer_td_internal(block_ptr, victim_ptr, td_ptr);
                _mem_free(block_ptr);
                block_ptr = _mem_get_next_block_internal (victim_ptr, NULL);
            }
        }
    }
#endif /* MQX_LITE_VERSION_NUMBER */

    /* Free up create/destroy/restart for other tasks */
    _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    template_ptr    = victim_ptr->TASK_TEMPLATE_PTR;
    stack_start_ptr = _psp_get_stack_start(victim_ptr);
    if (param_ptr == NULL)
    {
        create_param = stack_start_ptr->PARAMETER;
    }
    else
    {
        create_param = *param_ptr;
    } /* Endif */

    stack_ptr = victim_ptr->STACK_ALLOC_BLOCK; /* get mem allocated block for stack */

    if (stack_ptr == (pointer)template_ptr)
    {
        /* task has been created with temporary template, copy of template is before stack in allocated block for stack */
            stack_ptr +=  sizeof(TASK_TEMPLATE_STRUCT);
    }

    stack_size = template_ptr->TASK_STACKSIZE;
    if ( stack_size <= PSP_MINSTACKSIZE  )
    {
        stack_size = PSP_MINSTACKSIZE;
    } /* Endif */

    /* Make the size a multiple of the memory alignment */
    _MEMORY_ALIGN_VAL_LARGER(stack_size);

    ready_q_ptr = kernel_data->READY_Q_LIST - template_ptr->TASK_PRIORITY;
    victim_ptr->MY_QUEUE = ready_q_ptr;
#if MQX_HAS_DYNAMIC_PRIORITIES
    victim_ptr->HOME_QUEUE  = ready_q_ptr;
#endif
    victim_ptr->TASK_SR     = ready_q_ptr->ENABLE_SR;
    victim_ptr->FLAGS       = template_ptr->TASK_ATTRIBUTES;

#if MQX_ENABLE_USER_MODE
    if (template_ptr->TASK_ATTRIBUTES & MQX_USER_TASK)
    {
        victim_ptr->FLAGS |= TASK_USER_MODE;
    }
#endif /* MQX_ENABLE_USER_MODE */

#if MQX_HAS_TIME_SLICE
    /* Reset the time slice back to the default */
    if (template_ptr->DEFAULT_TIME_SLICE)
    {
#if (MQX_DEFAULT_TIME_SLICE_IN_TICKS == 0)
        uint_32 ticks;

        ticks = ((template_ptr->DEFAULT_TIME_SLICE * 2 *
                        kernel_data->TICKS_PER_SECOND) / 1000) / 2  /* Rounding.. */;
        PSP_ADD_TICKS_TO_TICK_STRUCT(&td_ptr->TIME_SLICE,
            ticks, &td_ptr->TIME_SLICE);
#else
        PSP_ADD_TICKS_TO_TICK_STRUCT(&victim_ptr->TIME_SLICE,
            template_ptr->DEFAULT_TIME_SLICE, &victim_ptr->TIME_SLICE);
#endif
    }
    else
    {
        victim_ptr->TIME_SLICE = kernel_data->SCHED_TIME_SLICE;
    } /* Endif */
    /* Reset scheduling policy for task */
    if (kernel_data->SCHED_POLICY == MQX_SCHED_RR)
    {
        victim_ptr->FLAGS |= MQX_TIME_SLICE_TASK;
    } /* Endif */
#endif

#if MQX_USE_IO
    /* Reset the io streams back to the default */
    victim_ptr->STDIN_STREAM  = kernel_data->PROCESSOR_STDIN;
    victim_ptr->STDOUT_STREAM = kernel_data->PROCESSOR_STDOUT;
    victim_ptr->STDERR_STREAM = kernel_data->PROCESSOR_STDERR;
#endif

    _int_disable();

    if (victim_ptr == td_ptr)
    {
        _QUEUE_UNLINK(victim_ptr);  /* Remove victim from the queue */
    } /* Endif */

    /* Rebuild the task's initial context */
    if (FALSE == _psp_build_stack_frame(victim_ptr, stack_ptr, stack_size, template_ptr, victim_ptr->TASK_SR, create_param))
    {
        /* build stack failed */
        return MQX_OUT_OF_MEMORY;
    }

    if (blocked)
    {
        victim_ptr->STATE = BLOCKED;
    }
    else
    {
        _task_ready_internal(victim_ptr);
    } /* Endif */

    victim_ptr->DISABLED_LEVEL = 0;

    if (victim_ptr == td_ptr)
    {
        /*
         * The active task is to be restarted.
         * Will not return from here
         */
        _sched_run_internal();
    } /* Endif */

    /* The victim has been added to the ready Q. Preemption check must be made */
    if (kernel_data->CURRENT_READY_Q != td_ptr->MY_QUEUE)
    {
        _sched_execute_scheduler_internal();
    } /* Endif */

    _int_enable();

    _KLOGX2(KLOG_task_restart, MQX_OK);
    return(MQX_OK);

} /* Endbody */

/*!
 * \brief Restart the specified task.
 *
 * This function closes all queues that the task has open, releases all the task's
 * resources, and frees all memory that is associated with the task's resources.
 * \n This function restarts the task with the same task descriptor, task ID, and
 * task stack (Reserve stack for Stack Start Structure and call the
 * _task_restart_func().).
 *
 * \param[in] task_id   Task ID of the task to restart.
 * \param[in] param_ptr One of the following:
 * \n - Pointer to a new task creation parameter.
 * \n - NULL
 * \param[in] blocked   Whether the task should be restarted in the blocked state or not.
 *
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_TASK_ID (Task_id is invalid.)
 * \return MQX_OUT_OF_MEMORY (Not enough memory to restart function.)
 *
 * \warning Cannot be called from an ISR.
 *
 * \see _task_create
 * \see _task_create_blocked
 * \see _task_create_at
 */
_mqx_uint _task_restart
(
    _task_id    task_id,
    uint_32_ptr param_ptr,
    boolean     blocked
)
{ /* Body */
    /* reserve memory in stack */
    volatile char dummy_stack_start_struct[sizeof(PSP_STACK_START_STRUCT)];
    dummy_stack_start_struct[0] = 0x00;

    /* call the right _task_restart function */
    return(_task_restart_func(task_id, param_ptr, blocked));
}

#endif /* MQX_TD_HAS_TASK_TEMPLATE_PTR */

/*!
 * \brief Disables preemption of the current task.
 *
 * The _task_stop_preemption() function disables preemption of the active task
 * unless the task blocks explicitly (_task_block()) or calls _task_start_preemption().
 *
 * \warning Changes the preemption ability of tasks.
 * \warning Interrupts are still handled.
 *
 * \see _task_start_preemption
 * \see _task_ready
 * \see _task_block
 */
void _task_stop_preemption(void)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR                   td_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE1(KLOG_task_stop_preemption);

    td_ptr      = kernel_data->ACTIVE_PTR;
    _int_disable();
    td_ptr->FLAGS |= TASK_PREEMPTION_DISABLED;
    _int_enable();
    _KLOGX1(KLOG_task_stop_preemption);

} /* Endbody */

/*!
 * \brief Enables preemption of the current task.
 *
 * The _task_start_preemption() function enables preemption of the active task
 * after _task_stop_preemption() was called.
 *
 * \warning Changes the preemption ability of tasks.
 * \warning Interrupts are still handled.
 *
 * \see _task_stop_preemption
 * \see _task_ready
 * \see _task_block
 */
void _task_start_preemption(void)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR                   td_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE1(KLOG_task_start_preemption);

    td_ptr      = kernel_data->ACTIVE_PTR;
    _int_disable();
    td_ptr->FLAGS &= ~TASK_PREEMPTION_DISABLED;
    _CHECK_RUN_SCHEDULER(); /* Allow higher priority tasks to run */
    _int_enable();

    _KLOGX1(KLOG_task_start_preemption);

} /* Endbody */

/*!
 * \brief Determines whether the active task's stack is currently overflowed.
 *
 * This function indicates whether the stack is currently past its limit. The
 * function does not indicate whether the stack previously passed its limit.
 *
 * \return TRUE (Stack is out of bounds.)
 * \return FALSE (Stack is not out of bounds.)
 *
 * \see _task_set_error
 */
boolean _task_check_stack(void)
{ /* Body */
#if MQX_TD_HAS_STACK_LIMIT
    register  KERNEL_DATA_STRUCT_PTR kernel_data;
    volatile  char                   loc = (char)0;

    _GET_KERNEL_DATA(kernel_data);

#if PSP_STACK_GROWS_TO_LOWER_MEM
    if ( &loc < ((char_ptr)kernel_data->ACTIVE_PTR->STACK_LIMIT) )
    {
#else
        if ( &loc > ((char_ptr)kernel_data->ACTIVE_PTR->STACK_LIMIT) )
        {
#endif
            return (TRUE);
        }
        else
        {
            return (FALSE);
        } /* Endif */
#else
        return (FALSE);
#endif
} /* Endbody */

#if !MQX_LITE_VERSION_NUMBER

/*!
 * \brief Gets the processor number of the task's home processor.
 *
 * This function returns the processor-number portion of task_id. It cannot check
 * the validity of task_id because MQX on one processor is unaware of which tasks
 * might reside on another processor.
 *
 * \param[in] task_id Task ID of the task for which to get info.
 *
 * \return Processor number of the processor where the task resides.
 *
 * \see _task_get_id
 */
_processor_number _task_get_processor
(
    _task_id task_id
)
{ /* Body */

    return PROC_NUMBER_FROM_TASKID(task_id);

} /* Endbody */

#endif /* MQX_LITE_VERSION_NUMBER */
#if MQX_TD_HAS_PARENT

/*!
 * \brief Gets parent's task ID to the calling task.
 *
 * \return Task ID of the parent task.
 *
 * \see _task_get_processor
 * \see _task_get_id
 */
_task_id _task_get_creator(void)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return( kernel_data->ACTIVE_PTR->PARENT );

} /* Endbody */
#endif /* MQX_TD_HAS_PARENT */

#if MQX_TD_HAS_ERROR_CODE

/*!
 * \brief Gets the task error code.
 *
 * \return Task error code for the active task.
 *
 * \see _task_get_error_ptr
 * \see _task_set_error
 * \see _task_errno
 */
_mqx_uint _task_get_error(void)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    if (kernel_data->IN_ISR)
    {
        return( kernel_data->INTERRUPT_CONTEXT_PTR->ERROR_CODE );
    }
    else
    {
        return( kernel_data->ACTIVE_PTR->TASK_ERROR_CODE );
    } /* Endif */
} /* Endbody */

/*!
 * \brief Gets a pointer to the task error code.
 *
 * \return Pointer to the task error code.
 *
 * \warning If a task writes to the pointer that _task_get_error_ptr() returns,
 * the task error code is changed to the value, overwriting any previous error code. To
 * avoid overwriting a previous error code, a task should use _task_set_error().
 *
 * \see _task_get_error
 * \see _task_set_error
 * \see _task_errno
 */
_mqx_uint _PTR_ _task_get_error_ptr(void)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    if (kernel_data->IN_ISR)
    {
        return( &kernel_data->INTERRUPT_CONTEXT_PTR->ERROR_CODE );
    }
    else
    {
        return( &kernel_data->ACTIVE_PTR->TASK_ERROR_CODE );
    } /* Endif */
} /* Endbody */
#endif /* MQX_TD_HAS_ERROR_CODE */

/*!
 * \brief Gets the task ID of the active task.
 *
 * \return Task ID of the active task.
 *
 * \see _task_get_creator
 * \see _task_get_processor
 * \see _task_get_id_from_name
 */
_task_id _task_get_id(void)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return( kernel_data->ACTIVE_PTR->TASK_ID );
} /* Endbody */

/*!
 * \brief Gets a pointer to the task descriptor for the task ID.
 *
 * \param[in] task_id One of:
 * \n - Task ID for a task on this processor.
 * \n - MQX_NULL_TASK_ID (Use the current task.)
 *
 * \return Pointer to the task descriptor for task_id.
 * \return NULL (Task_id is not valid for this processor.)
 *
 * \see _task_ready
 */
pointer _task_get_td
(
    _task_id task_id
)
{
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    TD_STRUCT_PTR           td_ptr;
    _mqx_uint               size;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_task_get_td(task_id);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);
    if (task_id == MQX_NULL_TASK_ID)
    {
        return((pointer)kernel_data->ACTIVE_PTR);
    }

    /* check task_id for SYSTEM_TASK_ID */
    if (task_id == kernel_data->SYSTEM_TD.TASK_ID)
    {
        return((pointer)&(kernel_data->SYSTEM_TD));
    }

    /* SPR P171-0022-01 Use int disable, not a semaphore */
    _INT_DISABLE();
    /* END SPR */

    td_ptr = (TD_STRUCT_PTR)((uchar_ptr)kernel_data->TD_LIST.NEXT - FIELD_OFFSET(TD_STRUCT,TD_LIST_INFO));

    size   = _QUEUE_GET_SIZE(&kernel_data->TD_LIST);
    while (size--)
    {
        /* END SPR */
        if (td_ptr->TASK_ID == task_id)
        {
            /* SPR P171-0022-01 Use int disable, not a semaphore */
            _INT_ENABLE();
            /* END SPR */
            return (pointer)td_ptr;
        } /* Endif */
        td_ptr = (TD_STRUCT_PTR)((uchar_ptr)td_ptr->TD_LIST_INFO.NEXT - FIELD_OFFSET(TD_STRUCT,TD_LIST_INFO));
    } /* Endwhile */

    /* SPR P171-0022-01 Use int disable, not a semaphore */
    _int_enable();
    /* END SPR */

    return NULL;
}

#if MQX_ENABLE_USER_MODE

/*!
 * \brief Gets a pointer to the task descriptor for the task ID.
 *
 * This function is an equivalent to the _task_get_td() API call but it can be
 * executed from within the User task or other code running in the CPU User mode.
 * Parameters passed to this function by pointer are required to meet the memory
 * protection requirements as described in the parameter list below.
 *
 * \param[in] task_id One of:
 * \n - Task ID for a task on this processor.
 * \n - MQX_NULL_TASK_ID (Use the current task.)
 *
 * \return Pointer to the task descriptor for task_id.
 * \return NULL (Task_id is not valid for this processor.)
 *
 * \see _task_get_td
 * \see _usr_task_ready
 */
pointer _usr_task_get_td
(
    _task_id task_id
)
{
    MQX_API_CALL_PARAMS params = {(uint_32)task_id, 0, 0, 0, 0};
    return (pointer)_mqx_api_call(MQX_API_TASK_GET_TD, &params);
}

#endif /* MQX_ENABLE_USER_MODE */
/*!
 * \brief Sets the task error code.
 *
 * MQX uses this function to indicate an error. MQX never sets the task error code
 * to MQX_OK; that is, MQX does not reset the task error code. It is the responsibility
 * of the application to reset the task error code. As a result, when an application
 * calls _task_get_error(), it gets the first error that MQX detected since the
 * last time the application reset the task error code.
 *
 * <table>
 *  <tr>
 *      <td><b> If the current task error code is: </b></td>
 *      <td><b> Function changes the task error code: </b></td>
 *  </tr>
 *  <tr>
 *      <td> MQX_OK </td>
 *      <td> To new_error_code. </td>
 *  </tr>
 *  <tr>
 *      <td> Not MQX_OK </td>
 *      <td> To new_error_code if new_error_code is MQX_OK. </td>
 *  </tr>
 * </table>
 *
 * \n If this function is called from an ISR, the function sets the interrupt error code.
 *
 * \param[in] new_error_code New task error code.
 *
 * \return Previous task error code.
 *
 * \see _task_check_stack
 * \see _task_get_error
 * \see _task_get_error_ptr
 * \see _task_errno
 */
_mqx_uint _task_set_error
(
    _mqx_uint new_error_code
)
{ /* Body */
#if MQX_TD_HAS_ERROR_CODE
    register KERNEL_DATA_STRUCT_PTR  kernel_data;
    register _mqx_uint               old_error_code;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_task_set_error, new_error_code);

    /* get the old value */
    if (kernel_data->IN_ISR)
    {
        old_error_code = kernel_data->INTERRUPT_CONTEXT_PTR->ERROR_CODE;
    }
    else
    {
        old_error_code = kernel_data->ACTIVE_PTR->TASK_ERROR_CODE;
    } /* Endif */

    if (( new_error_code == MQX_OK ) || ( old_error_code == MQX_OK ))
    {
        if (kernel_data->IN_ISR)
        {
            kernel_data->INTERRUPT_CONTEXT_PTR->ERROR_CODE = new_error_code;
        }
        else
        {
            kernel_data->ACTIVE_PTR->TASK_ERROR_CODE = new_error_code;
        } /* Endif */
    } /* Endif */

    _KLOGX2(KLOG_task_set_error, old_error_code);
    return( old_error_code );
#else
    return MQX_OK;
#endif

}

#if MQX_ENABLE_USER_MODE

/*!
 * \brief Sets the task error code.
 *
 * This function is an equivalent to the _task_set_error() API call but it can be
 * executed from within the User task or other code running in the CPU User mode.
 * Parameters passed to this function by pointer are required to meet the memory
 * protection requirements as described in the parameter list below.
 *
 * \param[in] new_error_code New task error code.
 *
 * \return Previous task error code.
 *
 * \see _task_set_error
 */
_task_id _usr_task_set_error
(
    _mqx_uint new_error_code
)
{
    MQX_API_CALL_PARAMS params = {(uint_32)new_error_code, 0, 0, 0, 0};
    return _mqx_api_call(MQX_API_TASK_SET_ERROR, &params);
}

#endif /* MQX_ENABLE_USER_MODE */
/*!
 * \private
 *
 * \brief Creates a new task of the type specified by the task template number,
 * but not make it ready to run.
 *
 * \param[in] template_index Task template index number for this task.
 * \param[in] parameter      The parameter to pass to the newly created task.
 * \param[in] stack_ptr      Pointer to the stack (if not NULL).
 * \param[in] stack_size     Stack size if provided by the application.
 * \param[in] user           User mode functionality.
 *
 * \return Pointer to the task descriptor for created task.
 * \return NULL
 *
 * \see TD_STRUCT
 */
TD_STRUCT_PTR _task_build_internal
(
    _mqx_uint     template_index,
    uint_32       parameter,
    pointer       stack_ptr,
    _mqx_uint     stack_size,
    boolean       user
)
{
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    TD_STRUCT_PTR            td_ptr;
    TASK_TEMPLATE_STRUCT_PTR task_template_ptr;
    boolean                  dynamic;
    uint_32                  create_parameter;

    _GET_KERNEL_DATA(kernel_data);

    if ( template_index )
    {
        dynamic = FALSE;
        create_parameter = parameter;

        /* Search all the local task templates for one whose index matches */
        task_template_ptr = kernel_data->INIT.TASK_TEMPLATE_LIST;

        while ( task_template_ptr->TASK_TEMPLATE_INDEX &&
                        (task_template_ptr->TASK_TEMPLATE_INDEX != template_index) )
        {
            ++task_template_ptr;
        } /* Endwhile */
        if (task_template_ptr->TASK_TEMPLATE_INDEX == 0)
        {
            /* Task not found */
            task_template_ptr = NULL;
        } /* Endif */
    }
    else
    {
        task_template_ptr = (TASK_TEMPLATE_STRUCT_PTR)parameter;
        create_parameter  = task_template_ptr->CREATION_PARAMETER;
        dynamic = TRUE;
    } /* Endif */

#if MQX_CHECK_ERRORS
    if (task_template_ptr == NULL)
    {
        _task_set_error(MQX_NO_TASK_TEMPLATE);
        return NULL;
    } /* Endif */
#endif


#if MQX_ENABLE_USER_MODE
    /* check template for correct user task parameters */
    if (user)
    {
        if (!(task_template_ptr->TASK_ATTRIBUTES & MQX_USER_TASK))
        {
            _task_set_error(MQX_INVALID_PARAMETER);
            return NULL;
        }

        if (kernel_data->INIT.MAX_USER_TASK_PRIORITY && kernel_data->INIT.MAX_USER_TASK_PRIORITY > task_template_ptr->TASK_PRIORITY)
        {
            _task_set_error(MQX_INVALID_TASK_PRIORITY);
            return NULL;
        }
    }
#endif

    /* serialize task creation/destruction */
    _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    /* Create the task, but do not ready it */
    td_ptr = _task_init_internal(task_template_ptr, kernel_data->ACTIVE_PTR->TASK_ID, \
                    create_parameter, dynamic, stack_ptr, stack_size);

    /* Allow other tasks to create */
    _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->TASK_CREATE_LWSEM);

    return(td_ptr);

} /* Endbody */


/*! \private */
extern void _task_exiting_function_internal(void);  /* Dummy prototype */
/*!
 * \private
 *
 * \brief Dummy function so debuggers will display stack correctly.
 */
void _task_exiting_function_internal(void){}

/*!
 * \private
 *
 * \brief Executes the exit handler for the current task, then destroys the current task.
 */
void _task_exit_function_internal(void)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR          td_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_task_exit_function, kernel_data->ACTIVE_PTR->TASK_ID);

    td_ptr = kernel_data->ACTIVE_PTR;
#if MQX_TASK_DESTRUCTION

#if MQX_HAS_EXIT_HANDLER
    if (td_ptr->EXIT_HANDLER_PTR != NULL)
    {
        (*td_ptr->EXIT_HANDLER_PTR)();
    }
#endif
    (void)_task_destroy(MQX_NULL_TASK_ID); /* Never returns */
#else
    td_ptr->STATE = DYING;
    while(TRUE)
    {
        _task_block();
    }
#endif /* MQX_TASK_DESTRUCTION */
}

#if MQX_EXTRA_TASK_STACK_ENABLE
#if !MQX_LITE_VERSION_NUMBER
/*!
 * \brief Gets the base address of the space reserved for the active task.
 *
 * \return TD_STRUCT.TOS_RESERVED
 * \return 0 (MQX is currently in ISR.)
 *
 * \see _task_reserve_space
 */
pointer _task_get_reserved_base(void)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _GET_KERNEL_DATA(kernel_data);

    if (kernel_data->IN_ISR)
    {
        return 0;
    } /* Endif */

    return kernel_data->ACTIVE_PTR->TOS_RESERVED;

} /* Endbody */
#endif /* MQX_LITE_VERSION_NUMBER */
#endif /* MQX_EXTRA_TASK_STACK_ENABLE */

/*!
 * \private
 *
 * \brief Creates task for given task template.
 *
 * \param[in] template_ptr     Task template for the new task.
 * \param[in] creator_task_id  Task ID of the creating task.
 * \param[in] create_parameter Creation parameter for the task.
 * \param[in] dynamic          TRUE (Template_ptr is a dynamic template.), FALSE
 * (Template_ptr is not a dynamic template.)
 * \param[in] input_stack_ptr  If not NULL, the location of the stack if provided.
 * \param[in] input_stack_size Input stack size if provided by the application.
 *
 * \return Pointer to the created task's descriptor.
 * \return NULL (Failure)
 *
 * \see TASK_TEMPLATE_STRUCT
 * \see TD_STRUCT
 */
TD_STRUCT_PTR _task_init_internal
(
    TASK_TEMPLATE_STRUCT_PTR template_ptr,
    _task_id                 creator_task_id,
    uint_32                  create_parameter,
    boolean                  dynamic,
    pointer                  input_stack_ptr,
    _mem_size                input_stack_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    TD_STRUCT_PTR            td_ptr;
    READY_Q_STRUCT_PTR       ready_q_ptr;
    TASK_TEMPLATE_STRUCT_PTR new_template_ptr;
#if MQX_USE_LWMEM_ALLOCATOR == 0 && !MQX_LITE_VERSION_NUMBER
    STOREBLOCK_STRUCT_PTR    block_ptr;
#endif

    char_ptr                 stack_ptr;
    _mqx_uint                stack_size;
    _mqx_uint                td_size;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (template_ptr->TASK_PRIORITY > kernel_data->LOWEST_TASK_PRIORITY)
    {
#if MQX_USE_IDLE_TASK
        if (template_ptr != &kernel_data->IDLE_TASK_TEMPLATE)
        {
#endif /* MQX_USE_IDLE_TASK */

            _task_set_error(MQX_INVALID_TASK_PRIORITY);
            return (NULL);

#if MQX_USE_IDLE_TASK
        }
#endif /* MQX_USE_IDLE_TASK */
    }
#endif /* MQX_CHECK_ERRORS */


    /*
     * Calculate space for the stack. Note that the stack size
     * must be no smaller than a specified minimum, and it
     * is made to be a multiple of longwords. The space allocated
     * for the stack includes the specified stacksize and the
     * overhead required by the kernel.
     */
    if (input_stack_ptr)
    {
        /* force stack size, ignore stack size from template */
        stack_size = input_stack_size;
#if MQX_CHECK_ERRORS
        if (stack_size <= (PSP_MINSTACKSIZE+sizeof(TD_STRUCT)))
        {
            _task_set_error(MQX_INVALID_SIZE);
            return(NULL);
        } /* Endif */
#endif
        td_ptr = _task_alloc_td_internal(stack_size, &td_size, input_stack_ptr, template_ptr->TASK_ATTRIBUTES & MQX_USER_TASK);
        stack_size -= td_size;

        if (dynamic)
        {
            stack_size -=  sizeof(TASK_TEMPLATE_STRUCT);
        }

    }
    else
    {
        /* take stack size from template */
        stack_size = template_ptr->TASK_STACKSIZE;
#if MQX_CHECK_ERRORS
        if ( stack_size <= PSP_MINSTACKSIZE  )
        {
            stack_size = PSP_MINSTACKSIZE;
        } /* Endif */
#endif
        /* Make the size a multiple of the memory alignment */
        _STACK_ALIGN_VAL_LARGER(stack_size);

#if 0 /* we dont need this, because we using _mem_alloc_align function in _task_alloc_td_internal */
#if PSP_MEMORY_ALIGNMENT
        /* But we need to add size to allow for alignment of stack base */
        stack_size += PSP_STACK_ALIGNMENT + 1;
#endif
#endif

        /*
         * Allocate space for a task descriptor and stack.
         * If there is none available,
         * then indicate that the create failed.
         */
        /* function allocate task descriptor, stack and optionally increase stack block size by size required for task template (dynamic = nonzero) */
        td_ptr = _task_alloc_td_internal(dynamic ? (stack_size +  sizeof(TASK_TEMPLATE_STRUCT)) : stack_size,
                                                 &td_size, NULL, template_ptr->TASK_ATTRIBUTES & MQX_USER_TASK);
    }/* Endif */


#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (td_ptr == NULL)
    {
        _task_set_error(MQX_OUT_OF_TASK_DESCRIPTORS);
        return (NULL);
    } /* Endif */
#endif
    td_ptr->STATE = BLOCKED;

    /* get begin of new stack */
    if (td_ptr->STACK_ALLOC_BLOCK)
    {
        /* (stack has been allocated) */
        /* stack start in new allocated block */
        stack_ptr = td_ptr->STACK_ALLOC_BLOCK;
    }
    else
    {
        /* (this will be executed if user provide input_stack_size) */
        /* stack start in provided block behind TD */
        stack_ptr = (char_ptr)td_ptr + td_size;
    }

    if (dynamic)
    {
        /* task is creating from temporary template, store template before stack (in stack allocated memory) */
        new_template_ptr = (pointer)stack_ptr;
        stack_ptr +=  sizeof(TASK_TEMPLATE_STRUCT);
        *new_template_ptr = *template_ptr;
        template_ptr = new_template_ptr;
        template_ptr->TASK_TEMPLATE_INDEX |= SYSTEM_TASK_FLAG;
        /* stack_ptr is moved behind template */
    }

#if MQX_MONITOR_STACK
    /* fill stack with mark for TAD stack overflow functionality */
    _task_fill_stack_internal((_mqx_uint_ptr)stack_ptr, stack_size);
#endif

    /*  Find the ready_q that the new task belongs to.  */
    /* The ready queues are stored as a array as follows:
     *     lowest priority - eg 9
     *                          8
     *                        ...
     *     highest priority     0
     * With the READY_Q_LIST pointer pointing to the highest priority queue
     */
    ready_q_ptr = kernel_data->READY_Q_LIST - template_ptr->TASK_PRIORITY;
    td_ptr->MY_QUEUE = ready_q_ptr;
#if MQX_HAS_DYNAMIC_PRIORITIES
    td_ptr->HOME_QUEUE  = ready_q_ptr;
#endif
    td_ptr->TASK_SR     = ready_q_ptr->ENABLE_SR;
    td_ptr->FLAGS       = template_ptr->TASK_ATTRIBUTES;

#if MQX_ENABLE_USER_MODE
    if (template_ptr->TASK_ATTRIBUTES & MQX_USER_TASK)
    {
        td_ptr->FLAGS |= TASK_USER_MODE;
    }
#endif /* MQX_ENABLE_USER_MODE */

    if (input_stack_ptr)
    {
        td_ptr->FLAGS |= TASK_STACK_PREALLOCATED;
    } /* Endif */

    /* create stack frame - initialize stack parameters in TD and stack itself (registers required by scheduller, etc.) */
    if (FALSE == _psp_build_stack_frame(td_ptr, stack_ptr, stack_size, template_ptr, (_mqx_uint)ready_q_ptr->ENABLE_SR, create_parameter))
    {
        /* build stack failed */
        return NULL;
    }


    /* Initialize the task's task descriptor. */
#if MQX_TD_HAS_TASK_TEMPLATE_PTR
    td_ptr->TASK_TEMPLATE_PTR = template_ptr;
#endif
#if MQX_TD_HAS_TEMPLATE_INDEX
    td_ptr->TEMPLATE_INDEX    = template_ptr->TASK_TEMPLATE_INDEX;
#endif

#if MQX_HAS_TIME_SLICE
    /* Use the provided default time slice */
    if (template_ptr->DEFAULT_TIME_SLICE)
    {
#if (MQX_DEFAULT_TIME_SLICE_IN_TICKS == 0)
        uint_32 ticks;

        ticks = ((template_ptr->DEFAULT_TIME_SLICE * 2 *
                        kernel_data->TICKS_PER_SECOND) / 1000) / 2  /* Rounding.. */;
        PSP_ADD_TICKS_TO_TICK_STRUCT(&td_ptr->TIME_SLICE,
            ticks, &td_ptr->TIME_SLICE);
#else
        PSP_ADD_TICKS_TO_TICK_STRUCT(&td_ptr->TIME_SLICE,
            template_ptr->DEFAULT_TIME_SLICE, &td_ptr->TIME_SLICE);
#endif
    }
    else
    {
        td_ptr->TIME_SLICE = kernel_data->SCHED_TIME_SLICE;
    } /* Endif */
    if (kernel_data->SCHED_POLICY == MQX_SCHED_RR)
    {
        td_ptr->FLAGS |= MQX_TIME_SLICE_TASK;
    } /* Endif */
#endif

#if MQX_USE_IO
    td_ptr->STDIN_STREAM  = kernel_data->PROCESSOR_STDIN;
    td_ptr->STDOUT_STREAM = kernel_data->PROCESSOR_STDOUT;
    td_ptr->STDERR_STREAM = kernel_data->PROCESSOR_STDERR;
#endif

#if MQX_TD_HAS_PARENT
    td_ptr->PARENT = creator_task_id;
#endif

#if !MQX_LITE_VERSION_NUMBER
    /*
     * Move ownership of the td from the creating task, to the
     * newly created task.
     */
#if MQX_USE_LWMEM_ALLOCATOR==0
    block_ptr = GET_MEMBLOCK_PTR(td_ptr);
    kernel_data->ACTIVE_PTR->MEMORY_RESOURCE_LIST = block_ptr->NEXTBLOCK;
#endif

    if (input_stack_ptr == 0)
    {
        _mem_transfer_internal(td_ptr, td_ptr);
        _mem_transfer_internal(td_ptr->STACK_ALLOC_BLOCK, td_ptr);
    } /* Endif */
#endif /* MQX_LITE_VERSION_NUMBER */

    return (td_ptr);

} /* Endbody */

#if MQX_MONITOR_STACK
/*!
 * \private
 *
 * \brief Initializes a stack to be filled with the MQX_MONITOR_STACK_VALUE: "stak".
 *
 * \param[in] addr_ptr Pointer to the start of the stack which is to be filled.
 * \param[in] size     The number of bytes to be filled.
 */
void _task_fill_stack_internal
(
    _mqx_uint_ptr addr_ptr,
    _mqx_uint     size
)
{ /* Body */

    size = (size/sizeof(_mqx_uint)) + 1;  /* Calculate # _mqx_uints */
    while (--size)
    {
        *addr_ptr++ = MQX_STACK_MONITOR_VALUE;
    } /* Endwhile */

} /* Endbody */
#endif

/*!
 * \private
 *
 * \brief Adds a task to the ready to run queue.
 *
 * This function MUST BE CALLED DISABLED.
 *
 * \param[in] td_ptr Pointer to the task descriptor to add.
 *
 * \see TD_STRUCT
 */
void _task_ready_internal
(
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR       kernel_data;
    register READY_Q_STRUCT_PTR  ready_q_ptr;
    register TD_STRUCT_PTR       old_tail_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_task_ready, td_ptr);

    ready_q_ptr   = td_ptr->MY_QUEUE;
    old_tail_ptr  = ready_q_ptr->TAIL_READY_Q;
    /*
     * Ready queues are ALWAYS allocated with higher priority queues in higher
     * memory, thus we need to update the CURRENT_READY_Q field (which
     * always points to the highest priority ready queue with a task
     * on it.
     */
    if ( (uchar_ptr)ready_q_ptr > (uchar_ptr)(kernel_data->CURRENT_READY_Q) )
    {
        kernel_data->CURRENT_READY_Q = ready_q_ptr;
    } /* Endif */

    td_ptr->STATE              = READY;
    td_ptr->TD_PREV            = old_tail_ptr;
    td_ptr->TD_NEXT            = old_tail_ptr->TD_NEXT;
    old_tail_ptr->TD_NEXT      = td_ptr;
    ready_q_ptr->TAIL_READY_Q  = td_ptr;
    /* SPR P171-0020-01 add macro to zero tick structure */
#if MQX_HAS_TIME_SLICE
    MQX_ZERO_TICK_STRUCT(&td_ptr->CURRENT_TIME_SLICE);
#endif
    /* END SPR */
    _KLOGX1(KLOG_task_ready);

} /* Endbody */

#if MQX_EXTRA_TASK_STACK_ENABLE
#if !MQX_LITE_VERSION_NUMBER
/*!
 * \brief Reserves space to add to every stack.
 *
 * This function reserves 'size' bytes that will be added to the size of every
 * task's stack. It can be thought of as a way of allocating "task local storage"
 * or perhaps as a way of dynamically adding to the TD_STRUCT. Both "OS Changer"
 * and the MetaWare C/C++ runtime want additional per-task variables. However,
 * this is a general feature that can be used for many more purposes.
 *
 * \note
 * The space added to each task must be known before ANY tasks are created.
 *
 * \param[in] size Amount of space to reserve.
 *
 * \return Byte offset from reserved area base address.
 *
 * \see _task_get_reserved_base
 * \see _task_alloc_td_internal
 */
_mqx_uint _task_reserve_space
(
    _mqx_uint size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint              off, algn;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    /* Can only be called prior to creating any tasks! */
    if (_QUEUE_GET_SIZE(&kernel_data->TD_LIST) != 0)
    {
        _mqx_fatal_error(MQX_EINVAL);
    } /* Endif */
#endif

    if      (size > 7) algn = 7;
    else if (size > 3) algn = 3;
    else if (size > 1) algn = 1;
    else               algn = 0;

    if (algn > kernel_data->TOS_RESERVED_ALIGN_MASK)
    {
        kernel_data->TOS_RESERVED_ALIGN_MASK = algn;
    } /* Endif */

    off = (kernel_data->TOS_RESERVED_SIZE + algn) & ~algn;
    kernel_data->TOS_RESERVED_SIZE = off + size;

    return off;

} /* Endbody */
#endif /* MQX_LITE_VERSION_NUMBER */
#endif /* MQX_EXTRA_TASK_STACK_ENABLE */

/*!
 * \private
 *
 * \brief Changes task's priority level.
 *
 * This function is called when a quiescent task's priority level has changed, and
 * the hardware disable/enable bits may need to be patched to the correct level.
 *
 * \param[in] td_ptr Task descriptor whose stack is to be modified.
 *
 * \see TD_STRUCT
 */
void _task_sync_priority_internal
(
    TD_STRUCT_PTR td_ptr
)
{ /* Body */
    pointer stack_ptr = td_ptr->STACK_PTR;

    _PSP_SET_SR_OF_BLOCKED_TASK(stack_ptr, td_ptr->MY_QUEUE->ENABLE_SR);

} /* Endbody */

/* Start SPR P171-0016-01 */

/*!
 * \private
 *
 * \brief Gets a pointer to an initialized task descriptor.
 *
 * Note that the task descriptor is initialized to zero.
 *
 * \param[in]  stack_size      Size of the stack for the newly created task.
 * \param[out] overhead        Size of TD_STRUCT and other overhead.
 * \param[in]  input_stack_ptr If not NULL, the location of the stack is provided.
 * \param[in]  user            User mode functionality.
 *
 * \return Pointer to an initialized task descriptor.
 * \return NULL
 * \return 0 (Not enough resources to create a task.)
 *
 * \see TD_STRUCT
 */

TD_STRUCT_PTR _task_alloc_td_internal
(
    _mem_size     stack_size,
    _mem_size_ptr overhead,
    pointer    input_stack_ptr,
    _mqx_uint user
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    TD_STRUCT_PTR               insert_td_ptr;
    TD_STRUCT_PTR               next_td_ptr;
    TD_STRUCT_PTR               new_td_ptr;
    TD_STRUCT_PTR               prev_td_ptr;
    QUEUE_ELEMENT_STRUCT_PTR    q_ptr;
    _mem_size                   extra = sizeof(TD_STRUCT);
#if MQX_EXTRA_TASK_STACK_ENABLE
    _mem_size                tos, tos_offset = 0;
#endif
    uint_16                  task_num;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (_QUEUE_GET_SIZE(&kernel_data->TD_LIST) >= (MAX_UINT_16-1))
    {
        /* We already have maximum number of tasks in system */
        return NULL;
    } /* Endif */
#endif

#if MQX_EXTRA_TASK_STACK_ENABLE
    tos = kernel_data->TOS_RESERVED_SIZE;
    if (tos != 0)
    {
        uint_32 align_mask = kernel_data->TOS_RESERVED_ALIGN_MASK;
        extra = (extra + align_mask) & ~align_mask;
        tos_offset = extra;
        /* must be word multiple */
        extra = (extra + tos + 3) & ~3;
    } /* Endif */
#endif
    *overhead = extra;


    if (input_stack_ptr)
    {
        new_td_ptr = (TD_STRUCT_PTR)input_stack_ptr;
        _mem_zero((pointer)new_td_ptr, extra);
    }
#if !MQX_LITE_VERSION_NUMBER
    else
    {
        new_td_ptr = (TD_STRUCT_PTR)_mem_alloc_zero(extra);

        if (new_td_ptr)
        {
#if MQX_ENABLE_USER_MODE
            if (user)
            {
                new_td_ptr->STACK_ALLOC_BLOCK = (TD_STRUCT_PTR)_mem_alloc_from(kernel_data->KD_USER_POOL, stack_size);
            }
            else
            {
                new_td_ptr->STACK_ALLOC_BLOCK = (TD_STRUCT_PTR)_mem_alloc(stack_size);
            }
#else
            new_td_ptr->STACK_ALLOC_BLOCK = (TD_STRUCT_PTR)_mem_alloc(stack_size);
#endif /* MQX_ENABLE_USER_MODE */
        }

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if ( new_td_ptr == NULL )
        {
            return ((TD_STRUCT_PTR)new_td_ptr);
        } /* Endif */

        if (new_td_ptr->STACK_ALLOC_BLOCK == NULL )
        {
            /* dealloc TD, because we do not have enough resources to create task */
            _mem_free(new_td_ptr);
            return 0;
        }

        _mem_set_type(new_td_ptr, MEM_TYPE_TD);
        _mem_set_type(new_td_ptr->STACK_ALLOC_BLOCK, MEM_TYPE_TASK_STACK);
#endif
    } /* Endif */
#endif /* MQX_LITE_VERSION_NUMBER */


#if MQX_EXTRA_TASK_STACK_ENABLE
    if (tos != 0)
    {
        new_td_ptr->TOS_RESERVED = ((uchar_ptr) new_td_ptr) + tos_offset;
    } /* Endif */
#endif

    /* Add new task to list */
    task_num = kernel_data->TASK_NUMBER;
    insert_td_ptr = kernel_data->INSERT_TD_PTR;
    new_td_ptr->TASK_ID = BUILD_TASKID(kernel_data->INIT.PROCESSOR_NUMBER, task_num);

    if (!insert_td_ptr)
    {
        q_ptr = (QUEUE_ELEMENT_STRUCT_PTR)((pointer)&kernel_data->TD_LIST);
    }
    else
    {
        q_ptr = &insert_td_ptr->TD_LIST_INFO;
    } /* Endif */

    _QUEUE_INSERT(&kernel_data->TD_LIST, q_ptr, &new_td_ptr->TD_LIST_INFO);

    /*
     * New task may not have been inserted at the end of the list. Search for a
     * spot to insert the next td and also calculate its task number
     */
    prev_td_ptr = new_td_ptr;
    do
    {
        insert_td_ptr = prev_td_ptr;
        next_td_ptr   = (TD_STRUCT_PTR)((uchar_ptr)insert_td_ptr->TD_LIST_INFO.NEXT - FIELD_OFFSET(TD_STRUCT,TD_LIST_INFO));
        prev_td_ptr   = next_td_ptr;
        INC_TASK_NUMBER(task_num);
    } while( ((pointer)next_td_ptr != ((pointer)&kernel_data->TD_LIST)) &&
                    (TASK_NUMBER_FROM_TASKID(next_td_ptr->TASK_ID) == task_num) );

    kernel_data->INSERT_TD_PTR = insert_td_ptr;
    kernel_data->TASK_NUMBER   = task_num;

    return ((TD_STRUCT_PTR)new_td_ptr);

} /* Endbody */

/* End SPR P171-0016-01 */

/*!
 * \private
 *
 * \brief Sets the task error code of the specified task.
 *
 * If the task error code does not equal MQX_OK, then the value is not changed.
 * However, the value of the task error code may be reset to MQX_OK by setting the
 * task error code to MQX_OK.  The old value of the task error code is returned.
 *
 * \param[in] td_ptr         Pointer to the task descriptor whose error is to be set.
 * \param[in] new_error_code The new error code.
 *
 * \return MQX_OK
 * \return Old task error code.
 *
 * \see TD_STRUCT
 */
_mqx_uint _task_set_error_td_internal
(
    TD_STRUCT_PTR td_ptr,
    _mqx_uint new_error_code
)
{ /* Body */
#if MQX_TD_HAS_ERROR_CODE
    _KLOGM(KERNEL_DATA_STRUCT_PTR  kernel_data;)
    _mqx_uint                      old_error_code;

    _KLOGM(_GET_KERNEL_DATA(kernel_data);)

    _KLOGE2(KLOG_task_set_error, new_error_code);

    /* get the old value */
    old_error_code = td_ptr->TASK_ERROR_CODE;
    if (( new_error_code == MQX_OK ) || ( old_error_code == MQX_OK ))
    {
        td_ptr->TASK_ERROR_CODE = new_error_code;
    } /* Endif */

    _KLOGX2(KLOG_task_set_error, old_error_code);
    return( old_error_code );
#else
    return MQX_OK;
#endif

} /* Endbody */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/flashx.h<|end_filename|>
#ifndef _flashx_h_
#define _flashx_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flashx.h$
* $Version : 3.8.16.0$
* $Date    : Oct-11-2011$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions specific for the flash drivers
*
*END************************************************************************/

#include "ioctl.h"

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/*
** Flash IOCTL calls
*/
#define FLASH_IOCTL_GET_BASE_ADDRESS     _IO(IO_TYPE_FLASH,0x01)
#define FLASH_IOCTL_GET_NUM_SECTORS      _IO(IO_TYPE_FLASH,0x02)
#define FLASH_IOCTL_GET_SECTOR_SIZE      _IO(IO_TYPE_FLASH,0x03)
#define FLASH_IOCTL_GET_WIDTH            _IO(IO_TYPE_FLASH,0x04)
#define FLASH_IOCTL_GET_SECTOR_BASE      _IO(IO_TYPE_FLASH,0x05)
#define FLASH_IOCTL_GET_BLOCK_GROUPS     _IO(IO_TYPE_FLASH,0x06)
#define FLASH_IOCTL_GET_BLOCK_MAP        _IO(IO_TYPE_FLASH,0x07)
#define FLASH_IOCTL_FLUSH_BUFFER         _IO(IO_TYPE_FLASH,0x08)
#define FLASH_IOCTL_ENABLE_BUFFERING     _IO(IO_TYPE_FLASH,0x09)
#define FLASH_IOCTL_DISABLE_BUFFERING    _IO(IO_TYPE_FLASH,0x0A)
#define FLASH_IOCTL_ERASE_SECTOR         _IO(IO_TYPE_FLASH,0x0B)
#define FLASH_IOCTL_ERASE_CHIP           _IO(IO_TYPE_FLASH,0x0C)
#define FLASH_IOCTL_ENABLE_SECTOR_CACHE  _IO(IO_TYPE_FLASH,0x0D)
#define FLASH_IOCTL_DISABLE_SECTOR_CACHE _IO(IO_TYPE_FLASH,0x0E)
#define FLASH_IOCTL_WRITE_PROTECT        _IO(IO_TYPE_FLASH,0x0F)
#define FLASH_IOCTL_GET_WRITE_PROTECT    _IO(IO_TYPE_FLASH,0x10)
#define FLASH_IOCTL_SWAP_FLASH_AND_RESET _IO(IO_TYPE_FLASH,0x11)
#define FLASH_IOCTL_WRITE_ERASE_CMD_FROM_FLASH_ENABLE   _IO(IO_TYPE_FLASH,0x12) 
#define FLASH_IOCTL_WRITE_ERASE_CMD_FROM_FLASH_DISABLE  _IO(IO_TYPE_FLASH,0x13) 
 
/*
** Flash Error Codes 
*/

#define FLASHXERR_NO_ERROR                (0)
#define FLASHXERR_INVALID_SIZE             (FLASHX_ERROR_BASE | 0x01)

/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/
/* The flash buffering is delayed write caching */
#define FLASHX_FLASH_BUFFER_ENABLED      (0x00000001)
/* Sector cache enables the driver to allocate sector-sized cache.
** Without this feature buffering is not possible.
** Without this feature also partial writes to sector are not possible
** (besides the cases when the sector was erased before).
*/
#define FLASHX_SECTOR_CACHE_ENABLED      (0x00000002)
#define FLASHX_WR_ERASE_FROM_FLASH_ENABLED  (0x00000004)

/*----------------------------------------------------------------------*/
/*
**                    Structure Definitions
*/

/* Forward declaration of private structure */
struct io_flashx_struct;

/*
** This structure is used to describe HW layout of flashx blocks belonging to specific controller
*/
typedef struct flashx_block_info_struct
{
    /* The number of sectors with the same size in this block */
    _mqx_uint        NUM_SECTORS;
   
    /* Physical start address of the block of same size sectors */
    _mem_size        START_ADDR;

    /* The size of the sectors in this block */
    _mem_size        SECTOR_SIZE;

    /* Any tag that will be handled by corresponding layer (usually HW layer) */
    uint_32          SPECIAL_TAG;

} FLASHX_BLOCK_INFO_STRUCT, _PTR_ FLASHX_BLOCK_INFO_STRUCT_PTR;

/*
** This structure is used to describe file management of flashx
** driver instance. Note that the file can span over several HW blocks.
*/
typedef struct flashx_file_block
{
    /* The name of file associated with the region */
    char_ptr const   FILENAME;
   
    /* Physical start address of the file */
    _mem_size        START_ADDR;

    /* The size of the sectors in this block */
    _mem_size        END_ADDR;

} FLASHX_FILE_BLOCK, _PTR_ FLASHX_FILE_BLOCK_PTR;

/* 
** This structure is used solely by the driver to describe the low level driver.
*/
typedef struct flashx_device_if_struct
{
    /* The function to call to erase a sector on the device */
    boolean (_CODE_PTR_           SECTOR_ERASE)(struct io_flashx_struct *, char_ptr, _mem_size);

    /* The function to call to program a sector on the device */
    boolean (_CODE_PTR_           SECTOR_PROGRAM)(struct io_flashx_struct *, char_ptr, char_ptr, _mem_size);
   
    /* The function to call to erase the entire device */
    boolean (_CODE_PTR_           CHIP_ERASE)(struct io_flashx_struct *);
   
    /* The function to call to read data from flash */
    _mqx_int (_CODE_PTR_          READ)(struct io_flashx_struct *, char_ptr, char_ptr, _mem_size);

    /* The function to call to initialize the device */
    boolean (_CODE_PTR_           INIT)(struct io_flashx_struct *);
   
    /* The function to call to disable the device */
    void (_CODE_PTR_              DEINIT)(struct io_flashx_struct *);

    /* The function to call to write enable or protect the device */
    boolean (_CODE_PTR_           WRITE_PROTECT)(struct io_flashx_struct *, _mqx_uint);
   
    /* The ioctl function to call */
    _mqx_int (_CODE_PTR_          IOCTL)(struct io_flashx_struct *, _mqx_uint, pointer);

} FLASHX_DEVICE_IF_STRUCT, _PTR_ FLASHX_DEVICE_IF_STRUCT_PTR;

/* 
** This structure is used to install a flash device. Configurable by BSP.
*/
typedef struct flashx_init_struct
{
    /* Base address of the flash device. Useful for external flash devices
    ** whose address space is determined by BSP.
    */
    _mem_size                             BASE_ADDR;

    /* This array of strutures provides the description of HW flash configuration */ 
    const FLASHX_BLOCK_INFO_STRUCT _PTR_  HW_BLOCK;

    /* This array of strutures provides the description of files */ 
    const FLASHX_FILE_BLOCK _PTR_         FILE_BLOCK;

    /* Interface to device algorithms */
    const FLASHX_DEVICE_IF_STRUCT _PTR_   DEVICE_IF;

    /* The bus width of the device (in bytes, i.e. WIDTH = 4 for 32 bits) */
    _mqx_uint                             WIDTH;

    /* The number of devices in parallel */
    _mqx_uint                             DEVICES;

    /* When finished programming, should a comparison of data be made
    ** to verify that the write worked correctly?
    */
    _mqx_uint                             WRITE_VERIFY;

    /* The address of device specific structure */ 
    pointer                               DEVICE_SPECIFIC_INIT;

} FLASHX_INIT_STRUCT, _PTR_ FLASHX_INIT_STRUCT_PTR;

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif
  
_mqx_uint _io_flashx_install(char_ptr, FLASHX_INIT_STRUCT const _PTR_);
_mqx_int  _io_flashx_uninstall(IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/bootp.h<|end_filename|>
#ifndef __bootp_h__
#define __bootp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: bootp.h$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   Bootstrap Protocol definitions.
*
*END************************************************************************/

#include "ip_prv.h"


/***************************************
**
** Constants
**
*/

#define BOOTP_TIMEOUT_MIN     4000     /* 4 sec */
#define BOOTP_TIMEOUT_MAX     64000    /* 64 sec */

#define BOOTPOP_BOOTREQUEST   1
#define BOOTPOP_BOOTREPLY     2

#define BOOTPFLAG_BROADCAST   0x8000

#define BOOTP_MAGIC           0x63825363L

/*
** BOOTP options
*/
#define BOOTPOPT_PAD    0
#define BOOTPOPT_END    255
#define BOOTPOPT_MASK   1


/***************************************
**
** Type definitions
**
*/

/*
** Contents of a BOOTP packet
*/
typedef struct bootp_header
{
   uchar    OP[1];
   uchar    HTYPE[1];
   uchar    HLEN[1];
   uchar    HOPS[1];
   uchar    XID[4];
   uchar    SECS[2];
   uchar    FLAGS[2];
   uchar    CIADDR[4];
   uchar    YIADDR[4];
   uchar    SIADDR[4];
   uchar    GIADDR[4];
   uchar    CHADDR[16];
} BOOTP_HEADER, _PTR_ BOOTP_HEADER_PTR;

typedef struct bootp_data
{
   uchar    SNAME[64];
   uchar    FILE[128];
   uchar    VEND[64];
} BOOTP_DATA, _PTR_ BOOTP_DATA_PTR;

typedef struct bootp_packet
{
   BOOTP_HEADER   HEAD;
   BOOTP_DATA     DATA;
} BOOTP_PACKET, _PTR_ BOOTP_PACKET_PTR;

/*
** BOOTP Configuration
*/
typedef struct bootp_cfg
{
   uint_32        XID;
   uint_32        TIMEOUT;
   uint_32        SECS;
   TCPIP_EVENT    RESEND;
   BOOTP_HEADER   PACKET;
} BOOTP_CFG, _PTR_ BOOTP_CFG_PTR;


/***************************************
**
** Function-specific type definitions
**
*/

/* BOOTP_open() */
typedef struct tcpip_parm_bootp {
   TCPIP_PARM              COMMON;
   _rtcs_if_handle         handle;  /* [IN] the RTCS interface state structure */
   BOOTP_DATA_STRUCT_PTR   data;    /* [IN/OUT] BOOTP parameters */
   BOOTP_CFG               config;
} TCPIP_PARM_BOOTP;


/***************************************
**
** Prototypes
**
*/

void BOOTP_open
(
   TCPIP_PARM_BOOTP _PTR_ parms
);

uint_32 BOOTP_close
(
   IP_IF_PTR                     /* [IN]     IP interface structure */
);

boolean BOOTP_send
(
   TCPIP_EVENT_PTR               /* [IN/OUT] the resend event       */
);

void BOOTP_service
(
   RTCSPCB_PTR                   /* [IN]     BOOTREPLY packet       */
);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/checksum.h<|end_filename|>
#ifndef __checksum_h__
#define __checksum_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: checksum.h$
* $Version : 3.8.4.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the IP checksum function prototypes.
*
*END************************************************************************/


/***************************************
**
** Code macros
**
*/

#define IP_Sum_invert(s)   (((s) == 0xFFFF) ? (s) : ~(s) & 0xFFFF)


/***************************************
**
** Prototypes
**
*/

uint_16 IP_Sum_immediate
(
   uint_16,             /* [IN] initial sum           */
   uint_16              /* [IN] number to add to sum  */
);

uint_16 IP_Sum_PCB
(
   uint_16,             /* [IN] initial sum           */
   RTCSPCB_PTR          /* [IN] the PCB               */
);

uint_16 IP_Sum_pseudo
(
   uint_16,             /* [IN] initial sum           */
   RTCSPCB_PTR,         /* [IN] the PCB               */
   int_32               /* [IN] IP layer              */
);

#if RTCSCFG_ENABLE_IP6
    uint_16 IP6_Sum_pseudo ( uint_16, RTCSPCB_PTR );
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/sosel0.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sosel0.c$
* $Version : 3.0.4.0$
* $Date    : Jan-13-2009$
*
* Comments:
*
*   This file contains the RTCS select() support functions.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "socket.h"
#include "tcpip.h"
#include "tcp_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_select_activity
* Returned Value  : TRUE or FALSE
* Comments        : Determine whether there is any activity on a socket.
*
*END*-----------------------------------------------------------------*/

boolean SOCK_select_activity
   (
      SOCKET_STRUCT_PTR    socket_ptr,
      int flag                          // direction flag - 0 recv, non zero send
   )
{ /* Body */
   TCB_STRUCT_PTR tcb_ptr;
   boolean        activity = FALSE;

   /* Check closing and connected stream sockets for data */
   if (socket_ptr->TCB_PTR) {
      tcb_ptr = socket_ptr->TCB_PTR;
   
      if (!flag) {
         /*
         ** Check that there is data in the receive ring or
         ** that the socket has been closed by the peer
         */
         if ((tcb_ptr->conn_pending) || (tcb_ptr->state == CLOSED) ||
            /* START CR 2349 */
            //(tcb_ptr->rcvnxt > tcb_ptr->rcvbufseq)) {
            (GT32(tcb_ptr->rcvnxt, tcb_ptr->rcvbufseq))) {
            /* END CR 2349 */
            activity = TRUE;
         }
      }
      else {
         if (!tcb_ptr->sndlen) {    // TODO - remake for partialy empty send buffers
            activity = TRUE;
         }
      }

   /* Check datagram sockets for data */
   } else if (socket_ptr->UCB_PTR) {
      /*
      ** Check that there is queued data
      */
      if (socket_ptr->UCB_PTR->PHEAD) {
         activity = TRUE;
      } /* Endif */

   /* TCB=UCB=NULL is a TCP connection reset by peer */
   } else {

      activity = TRUE;

   } /* Endif */

   return activity;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_select_block
* Returned Values :
* Comments  :
*     Enqueues a select() call on the select queue.
*
*END*-----------------------------------------------------------------*/

void SOCK_select_block
   (
      SOCKSELECT_PARM_PTR  parms
   )
{ /* Body */
   SOCKET_CONFIG_STRUCT_PTR   socket_cfg_ptr = RTCS_getcfg(SOCKET);

   parms->NEXT = socket_cfg_ptr->SELECT_HEAD;
   if (parms->NEXT) {
      parms->NEXT->PREV = &parms->NEXT;
   } /* Endif */
   socket_cfg_ptr->SELECT_HEAD = parms;
   parms->PREV = &socket_cfg_ptr->SELECT_HEAD;

   if (parms->timeout) {
      parms->EXPIRE.TIME    = parms->timeout;
      parms->EXPIRE.EVENT   = SOCK_select_expire;
      parms->EXPIRE.PRIVATE = parms;
      TCPIP_Event_add(&parms->EXPIRE);
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_select_expire
* Returned Values :
* Comments  :
*     Called by the Timer.  Expire a select call.
*
*END*-----------------------------------------------------------------*/

boolean SOCK_select_expire
   (
      TCPIP_EVENT_PTR   event
   )
{ /* Body */
   SOCKSELECT_PARM_PTR  parms = event->PRIVATE;

   if (parms->NEXT) {
      parms->NEXT->PREV = parms->PREV;
   } /* Endif */
   *parms->PREV = parms->NEXT;

   parms->sock = 0;
   RTCSCMD_complete(parms, RTCS_OK);

   return FALSE;
} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/SWLIBS_Typedefs.h<|end_filename|>
/******************************************************************************
 *
 * (c) Copyright 2009, Freescale & STMicroelectronics
 *
 ***************************************************************************//*!
 *
 * @file     SWLIBS_Typedefs.h
 *
 * @author   r63172
 * 
 * @version  1.0.1.0
 * 
 * @date     Dec-6-2012
 * 
 * @brief    Basic types definition file.
 *
 *******************************************************************************
 *
 ******************************************************************************/
#ifndef _SWLIBS_TYPEDEFS_H
#define _SWLIBS_TYPEDEFS_H

/******************************************************************************
 * Defines and macros            (scope: module-local)
 ******************************************************************************/
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#define NULL ((void*)0)
#endif
#endif

/******************************************************************************
 * Typedefs and structures       (scope: module-local)
 ******************************************************************************/

//typedef unsigned char bool; /*!< basic boolean type */


#ifndef FALSE
#define FALSE ((bool)0)                    /*!< Boolean type FALSE constant */
#endif

#ifndef TRUE
#define TRUE ((bool)1)                     /*!< Boolean type TRUE constant */
#endif

typedef unsigned char UWord8; /*!< unsigned 8-bit integer type */
typedef signed char Word8; /*!< signed 8-bit integer type */
typedef unsigned short UWord16; /*!< unsigned 16-bit integer type */
typedef signed short Word16; /*!< signed 16-bit integer type */
typedef unsigned int UWord32; /*!< unsigned 32-bit integer type */
typedef signed int Word32; /*!< signed 32-bit integer type */
typedef unsigned long long UWord64; /*!< unsigned 64-bit integer type */
typedef signed long long Word64; /*!< signed 64-bit integer type */

typedef unsigned char UInt8; /*!< unsigned 8-bit integer type */
typedef signed char Int8; /*!< signed 8-bit integer type */
typedef unsigned short UInt16; /*!< unsigned 16-bit integer type */
typedef signed short Int16; /*!< signed 16-bit integer type */
typedef unsigned int UInt32; /*!< unsigned 32-bit integer type */
typedef signed int Int32; /*!< signed 32-bit integer type */
typedef unsigned long long UInt64; /*!< unsigned 64-bit integer type */
typedef signed long long Int64; /*!< signed 64-bit integer type */

typedef Word16 Frac16; /*!< 16-bit signed fractional 
 Q1.15 type */
typedef Word32 Frac32; /*!< 32-bit signed fractional 
 Q1.31 type */

/*------------------------------------------------------------------------*//*!
 @struct MCLIB_3_COOR_SYST_T "\SWLIBS_Typedefs.h"

 @brief  Structure data type for three phase system with A,B and C components - input/output variables.
 *//*-------------------------------------------------------------------------*/
typedef struct {
	Frac32 f32A; /*!< A component, type signed 32-bit fractional */
	Frac32 f32B; /*!< B component, type signed 32-bit fractional */
	Frac32 f32C; /*!< C component, type signed 32-bit fractional */
} MCLIB_3_COOR_SYST_T;

/*------------------------------------------------------------------------*//*!
 @struct MCLIB_2_COOR_SYST_ALPHA_BETA_T "\SWLIBS_Typedefs.h"

 @brief  Structure data type for two phase system with alpha and beta components - input/output variables.
 *//*-------------------------------------------------------------------------*/
typedef struct {
	Frac32 f32Alpha; /*!< Alpha component, type signed 32-bit fractional */
	Frac32 f32Beta;  /*!< Beta component, type signed 32-bit fractional */
} MCLIB_2_COOR_SYST_ALPHA_BETA_T;

/*------------------------------------------------------------------------*//*!
 @struct MCLIB_2_COOR_SYST_D_Q_T "\SWLIBS_Typedefs.h"

 @brief  Structure data type for two phase system with direct and quadrature components - input/output variables.
 *//*-------------------------------------------------------------------------*/
typedef struct {
	Frac32 f32D;     /*!< Direct axis component, type signed 32-bit fractional */
	Frac32 f32Q;     /*!< Quadrature axis component, type signed 32-bit fractional */
} MCLIB_2_COOR_SYST_D_Q_T;

/*------------------------------------------------------------------------*//*!
 @struct MCLIB_ANGLE_T "\SWLIBS_Typedefs.h"

 @brief  Structure data type for two axis of two phase system with sine and cosine components - input/output variables.
 *//*-------------------------------------------------------------------------*/
typedef struct {
	Frac32 f32Sin;   /*!< Sine component, type signed 32-bit fractional */
	Frac32 f32Cos;   /*!< Cosine component, type signed 32-bit fractional */
} MCLIB_ANGLE_T;

/******************************************************************************
 * Exported variables
 ******************************************************************************/

/******************************************************************************
 * Exported function prototypes
 ******************************************************************************/

/******************************************************************************
 * Inline functions
 ******************************************************************************/

#endif /* _SWLIBS_TYPEDEFS_H */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/udp.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: udp.c$
* $Version : 3.8.14.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the User
*   Datagram Protocol.  For more details, refer to RFC768.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "udp_prv.h"
#include "icmp_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_init
* Returned Values : uint_32
* Comments        :
*     Initialize the UDP layer.
*
*END*-----------------------------------------------------------------*/

uint_32 UDP_init
   (
      void
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   uint_32              status = RTCS_OK;

   UDP_cfg_ptr = RTCS_mem_alloc_zero(sizeof(UDP_CFG_STRUCT));
   if (UDP_cfg_ptr == NULL)  {
      return RTCSERR_OUT_OF_MEMORY;
   }
   _mem_set_type(UDP_cfg_ptr, MEM_TYPE_UDP_CFG_STRUCT);

   RTCS_LIST_INIT(UDP_cfg_ptr->BOUND_UCB_HEAD);
   RTCS_LIST_INIT(UDP_cfg_ptr->LBOUND_UCB_HEAD);
   RTCS_LIST_INIT(UDP_cfg_ptr->GROUND_UCB_HEAD);
   RTCS_LIST_INIT(UDP_cfg_ptr->OPEN_UCB_HEAD);
   UDP_cfg_ptr->LAST_PORT = IPPORT_USERRESERVED;

   RTCS_setcfg(UDP, UDP_cfg_ptr);

#if RTCSCFG_ENABLE_IP4
    IP_open(IPPROTO_UDP, UDP_service, NULL, &status);
    if(status != RTCS_OK)
    {
        return status;
    }
#endif /*RTCSCFG_ENABLE_IP4*/
   /* Initialisation of the UDP IPv6 service */
#if RTCSCFG_ENABLE_IP6
   IP6_open(IPPROTO_UDP, UDP_service6, NULL, &status);
#endif

   return status;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_openbind_internal
* Returned Values : error code
* Comments        :
*     Opens and binds a new UCB.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4

uint_32 UDP_openbind_internal
   (
      uint_16              localport,  /* [IN] local UDP port */
      void (_CODE_PTR_     service)(RTCSPCB_PTR, UCB_STRUCT_PTR),
      UCB_STRUCT_PTR _PTR_ ucb         /* [OUT] new UCB */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;

   error = RTCSCMD_internal(parms, UDP_open);
   if (error) {
      return error;
   } /* Endif */

   parms.udpservice = service;
   parms.ipaddress  = INADDR_ANY;
   parms.udpport    = localport;
   parms.udpword    = 0;
   error = RTCSCMD_internal(parms, UDP_bind);
   if (error) {
      RTCSCMD_internal(parms, UDP_close);
      return error;
   } /* Endif */

   *ucb = parms.ucb;
   return RTCS_OK;

} /* Endbody */

#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_close_internal
* Returned Values : error code
* Comments        :
*     Closes a UCB.
*
*END*-----------------------------------------------------------------*/

uint_32 UDP_close_internal
   (
      UCB_STRUCT_PTR    ucb         /* [IN] old UCB */
   )
{ /* Body */
   UDP_PARM    parms;
   uint_32     error;

   parms.ucb = ucb;
   error = RTCSCMD_internal(parms, UDP_close);
   if (error) {
      return error;
   } /* Endif */

   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_open
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [OUT] unbound UCB
*    _CODE_PTR_         udpservice  not used
*     _ip_address       ipaddress   not used
*     uint_16           udpport     not used
*     uint_16           udpflags    not used
*     pointer           udpptr      not used
*     uint_32           udpword     not used
*
* Comments        :
*     Creates an unbound UCB.
*
*END*-----------------------------------------------------------------*/

void UDP_open
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UCB_STRUCT_PTR       ucb;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   ucb = RTCS_mem_alloc(sizeof(UCB_STRUCT));
   if (!ucb) {
      RTCSCMD_complete(parms, RTCSERR_UDP_UCB_ALLOC);
      return;
   } /* Endif */

   _mem_set_type(ucb, MEM_TYPE_UCB_STRUCT);

   ucb->PORT = 0;
   ucb->REMOTE_PORT = 0;
   ucb->SOCKET      = 0;
   ucb->REMOTE_HOST = INADDR_ANY;
   ucb->BYPASS_RX   = FALSE;
   ucb->BYPASS_TX   = FALSE;
   ucb->NONBLOCK_RX = FALSE;
   ucb->NONBLOCK_TX = FALSE;

   RTCS_QUEUE_INIT(ucb->PHEAD, ucb->PTAIL);
   RTCS_QUEUE_INIT(ucb->RHEAD, ucb->RTAIL);

   /* Initialize the list of joined multicast groups */
   RTCS_LIST_INIT(ucb->MCB_PTR);
   ucb->IGMP_LEAVEALL = NULL;

   /* Add the new UCB into the chain of ground UCBs */
   RTCS_LIST_INS(UDP_cfg_ptr->GROUND_UCB_HEAD, ucb);

   parms->ucb = ucb;
   RTCSCMD_complete(parms, RTCS_OK);
   return;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_bind
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] unbound UCB
*    _CODE_PTR_         udpservice  [IN] service function for incoming datagrams
*     _ip_address       ipaddress   [IN] local IP address
*     uint_16           udpport     [IN] local port
*     uint_16           udpflags    not used
*     pointer           udpptr      not used
*     uint_32           udpword     [IN] socket handle
*
* Comments        :
*     Binds a UCB to a local port.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
void UDP_bind
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UCB_STRUCT_PTR       ucb, search_ptr, _PTR_ tmp_ptr, _PTR_ list_ptr;
   uint_16              port;
   _ip_address          ipaddr;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   /* Initialize the UCB */
   port = parms->udpport & 0xFFFF;
   ipaddr = parms->ipaddress;

   if (port) {

      /*
      ** If port is specified, make sure its not in use with same local
      ** IP addr. We can only have one UCB per (IPADDR/port) combination,
      ** including the case were the IPADDR is INADDR_ANY.
      */
      if (ipaddr) {
         RTCS_LIST_SEARCH(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr) {
            if (search_ptr->PORT == port &&
                search_ptr->IPADDR == ipaddr)
            {
               RTCSCMD_complete(parms, RTCSERR_UDP_PORT_OPEN);
               return;
            } /* Endif */
         } /* End SEARCH */

         RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr) {
            if (search_ptr->PORT == port &&
                search_ptr->IPADDR == ipaddr)
            {
               RTCSCMD_complete(parms, RTCSERR_UDP_PORT_OPEN);
               return;
            } /* Endif */
         } /* End SEARCH */
      } else {
         RTCS_LIST_SEARCH(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr) {
            if (search_ptr->PORT == port) {
               RTCSCMD_complete(parms, RTCSERR_UDP_PORT_OPEN);
               return;
            } /* Endif */
         } /* End SEARCH */
      } /* Endif */
   }
   else
   {
      port = UDP_cfg_ptr->LAST_PORT;
      for (;;)
      {
         /* Get next port */
         if (--port < IPPORT_RESERVED)
         {
            port = IPPORT_USERRESERVED;
         } /* Endif */
         /* If we tested them all, return an error */
         if (port == UDP_cfg_ptr->LAST_PORT)
         {
            RTCSCMD_complete(parms, RTCSERR_UDP_PORT_ALLOC);
            return;
         } /* Endif */
         /*
         ** Check if it's in use
         */
         RTCS_LIST_SEARCH(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr)
         {
            if (search_ptr->PORT == port)
            {
               break;
            } /* Endif */
         } /* End SEARCH */
         if (!search_ptr)
         {
            RTCS_LIST_SEARCH(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr)
            {
               if (search_ptr->PORT == port)
               {
                  break;
               } /* Endif */
            } /* End SEARCH */
         } /* Endif */
         if (!search_ptr)
         {
            RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr)
            {
               if (search_ptr->PORT == port)
               {
                  break;
               } /* Endif */
            } /* End SEARCH */
         } /* Endif */
         /* If it's not in use, keep it */
         if (!search_ptr)
         {
            break;
         } /* Endif */
      } /* Endfor */

      UDP_cfg_ptr->LAST_PORT = port;

   } /* Endif */
   ucb = parms->ucb;
   ucb->PORT         = port;
   ucb->PCOUNT       = 0;
   ucb->IPADDR       = ipaddr;
   ucb->KEEP_IPADDR  = (boolean) (ipaddr != INADDR_ANY);
   ucb->SOCKET       = parms->udpword;
   ucb->SERVICE      = parms->udpservice;
   /* This is the list the UCB will be moved to */
   if (ipaddr == INADDR_ANY) {
      list_ptr = &(UDP_cfg_ptr->BOUND_UCB_HEAD);
   } else {
      list_ptr = &(UDP_cfg_ptr->LBOUND_UCB_HEAD);
   } /* Endif */
   /* Move the UCB fromt the GROUND list to the BOUND list */
   RTCS_LIST_SEARCHMOD(UDP_cfg_ptr->GROUND_UCB_HEAD, tmp_ptr) {
      if (*tmp_ptr == ucb) {
         RTCS_LIST_DEL(UDP_cfg_ptr->GROUND_UCB_HEAD,tmp_ptr);
         break;
      } /* Endif */
   } /* End SEARCH */
   RTCS_LIST_INS_END((*list_ptr), ucb, tmp_ptr);
   RTCSCMD_complete(parms, RTCS_OK);
   return;
} /* Endbody */
#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_bind6
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] unbound UCB
*    _CODE_PTR_         udpservice  [IN] service function for incoming datagrams
*     _ip_address       ipaddress   [IN] local IP address
*     in6_addr          ipv6address [IN] local IPv6 address
*     uint_16           udpport     [IN] local port
*     uint_16           udpflags    not used
*     pointer           udpptr      not used
*     uint_32           udpword     [IN] socket handle
*
* Comments        :
*     Binds a UCB to a local port.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6

void UDP_bind6
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UCB_STRUCT_PTR       ucb, search_ptr, _PTR_ tmp_ptr, _PTR_ list_ptr;
   uint_16              port;
   in6_addr             ipv6address;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   /* Initialize the UCB */
   port = parms->udpport & 0xFFFF;
   /* copy IPv6 addr */
   IN6_ADDR_COPY(&(parms->ipv6address),&(ipv6address));//from ->to
   if (port) {

      /*
      ** If port is specified, make sure its not in use with same local
      ** IP addr. We can only have one UCB per (IPADDR/port) combination,
      ** including the case were the IPADDR is INADDR_ANY.
      */
      if (!IN6_ARE_ADDR_EQUAL(&(ipv6address), &in6addr_any))
      {
            RTCS_LIST_SEARCH(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr)
            {
                if  (
                        search_ptr->PORT == port &&
                        IN6_ARE_ADDR_EQUAL(&(search_ptr->IPV6ADDR), &(ipv6address))
                    )
                {
                    RTCSCMD_complete(parms, RTCSERR_UDP_PORT_OPEN);
                    return;
                } /* Endif */
            } /* End SEARCH */

            RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr)
            {
                if  (
                        search_ptr->PORT == port &&
                        IN6_ARE_ADDR_EQUAL(&(search_ptr->IPV6ADDR), &(ipv6address))
                    )
                {
                    RTCSCMD_complete(parms, RTCSERR_UDP_PORT_OPEN);
                    return;
                } /* Endif */
            } /* End SEARCH */
      }else
      {
            RTCS_LIST_SEARCH(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr)
            {
                if(search_ptr->PORT == port)
                {
                    RTCSCMD_complete(parms, RTCSERR_UDP_PORT_OPEN);
                    return;
                } /* Endif */
            } /* End SEARCH */
      } /* Endif */

   } else
   {
      port = UDP_cfg_ptr->LAST_PORT;

      for (;;)
      {

         /* Get next port */
         if (--port < IPPORT_RESERVED)
         {
            port = IPPORT_USERRESERVED;
         } /* Endif */

         /* If we tested them all, return an error */
         if (port == UDP_cfg_ptr->LAST_PORT)
         {
            RTCSCMD_complete(parms, RTCSERR_UDP_PORT_ALLOC);
            return;
         } /* Endif */

         /*
         ** Check if it's in use
         */
         RTCS_LIST_SEARCH(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr)
         {
            if (search_ptr->PORT == port)
            {
               break;
            } /* Endif */
         } /* End SEARCH */

         if (!search_ptr)
         {
            RTCS_LIST_SEARCH(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr)
            {
               if (search_ptr->PORT == port)
               {
                  break;
               } /* Endif */
            } /* End SEARCH */
         } /* Endif */

         if (!search_ptr)
         {
            RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr)
            {
               if (search_ptr->PORT == port)
               {
                  break;
               } /* Endif */
            } /* End SEARCH */
         } /* Endif */

         /* If it's not in use, keep it */
         if (!search_ptr)
         {
            break;
         } /* Endif */

      } /* Endfor */

      UDP_cfg_ptr->LAST_PORT = port;

   } /* Endif */

   ucb = parms->ucb;

   ucb->PORT         = port;
   ucb->PCOUNT       = 0;
   IN6_ADDR_COPY(&(ipv6address), &(ucb->IPV6ADDR));//from ->to
   ucb->KEEP_IPADDR  = (boolean) (!IN6_ARE_ADDR_EQUAL(&(ipv6address), &in6addr_any));
   ucb->SOCKET       = parms->udpword;
   ucb->SERVICE      = parms->udpservice;
   ucb->IF_SCOPE_ID  = parms->if_scope_id;
   /* This is the list the UCB will be moved to */
   if (IN6_ARE_ADDR_EQUAL(&(ipv6address), &in6addr_any))
   {
      list_ptr = &(UDP_cfg_ptr->BOUND_UCB_HEAD);
   }
   else
   {
      list_ptr = &(UDP_cfg_ptr->LBOUND_UCB_HEAD);
   } /* Endif */
   /* Move the UCB fromt the GROUND list to the BOUND list */
   RTCS_LIST_SEARCHMOD(UDP_cfg_ptr->GROUND_UCB_HEAD, tmp_ptr) {
      if (*tmp_ptr == ucb) {
         RTCS_LIST_DEL(UDP_cfg_ptr->GROUND_UCB_HEAD,tmp_ptr);
         break;
      } /* Endif */
   } /* End SEARCH */
   RTCS_LIST_INS_END((*list_ptr), ucb, tmp_ptr);
   RTCSCMD_complete(parms, RTCS_OK);
   return;
} /* Endbody */
#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_connect6
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] bound or open UCB
*    _CODE_PTR_         udpservice  not used
*     in6_addr          ipv6address [IN] peer IPv6 address
*     uint_16           udpport     [IN] peer port
*     uint_16           udpflags    not used
*     pointer           udpptr      not used
*     uint_32           udpword     [IN] socket level error
*
* Comments        :
*     Connects a UCB to a peer port.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6
void UDP_connect6
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UCB_STRUCT_PTR       ucb = parms->ucb, search_ptr, _PTR_ tmp_ptr;
   UCB_STRUCT_PTR       _PTR_ ins_ptr, _PTR_ del_ptr;
   uint_16              port;
   uint_32              error = parms->udpword;
   in6_addr             *t_ipv6address;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   if (!error &&(!(parms->udpport) || IN6_ARE_ADDR_EQUAL(&(parms->ipv6address), &in6addr_any)))
   {
      /* Connect requires both a port AND and IP address.  */
      error = RTCSERR_UDP_PORT_ZERO;

   }
   else if (!error)
   {
        /* Bind a local address if none is specified */
        if (IN6_ARE_ADDR_EQUAL(&(ucb->IPV6ADDR), &in6addr_any))
        {
            t_ipv6address = IP6_route_find(&(parms->ipv6address), 0);
            IN6_ADDR_COPY(t_ipv6address,&(ucb->IPV6ADDR));
            if(IN6_ARE_ADDR_EQUAL(&(ucb->IPV6ADDR), &in6addr_any))
            {
                error = RTCSERR_IP_UNREACH;
            } else
            {
                /*
                ** Make sure this connect request does not put two UCB's into the
                ** same configuration.
                */
                port = ucb->PORT;
                RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr)
                {
                    if  (
                            search_ptr != ucb &&
                            search_ptr->PORT == port &&
                            IN6_ARE_ADDR_EQUAL(&(search_ptr->IPV6ADDR), &(ucb->IPV6ADDR))
                        )
                    {
                        error = RTCSERR_UDP_PORT_OPEN;
                        IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(ucb->IPV6ADDR));
                        break;
                } /* Endif */
            } /* End SEARCH */
         } /* Endif */
      } /* Endif */
   }  /*Endif */

   /*
   ** Check for errors and location of UCB. If TRUE, UCB must be moved.
   ** This is an evaluates to TRUE if one of the following is true:
   ** A. There is an error, and there is a remote port  OR
   ** B. There is no error, and there is no remote port
   */
   if(!(error) == !(ucb->REMOTE_PORT))
   {
        if(ucb->REMOTE_PORT)
        {
            if(ucb->KEEP_IPADDR)
            {
                ins_ptr = &(UDP_cfg_ptr->LBOUND_UCB_HEAD);
            }
            else
            {
                ins_ptr = &(UDP_cfg_ptr->BOUND_UCB_HEAD);
            }
            del_ptr = &(UDP_cfg_ptr->OPEN_UCB_HEAD);
        }
        else
        {
            ins_ptr = &(UDP_cfg_ptr->OPEN_UCB_HEAD);
            if(ucb->KEEP_IPADDR)
            {
                del_ptr = &(UDP_cfg_ptr->LBOUND_UCB_HEAD);
            }
            else
            {
                del_ptr = &(UDP_cfg_ptr->BOUND_UCB_HEAD);
            }
        }
        /* Move the UCB from one list to the other */
        RTCS_LIST_SEARCHMOD(*del_ptr, tmp_ptr)
        {
            if(*tmp_ptr == ucb)
            {
                RTCS_LIST_DEL(*del_ptr, tmp_ptr);
                break;
            } /* Endif */
        } /* End SEARCH */
        RTCS_LIST_INS_END(*ins_ptr, ucb, tmp_ptr);
   } /* Endif */

   /* If there was no error, set the peer endpoint */
   if(!error)
   {
      IN6_ADDR_COPY(&(parms->ipv6address),&(ucb->REMOTE_HOST6));
      ucb->REMOTE_PORT = parms->udpport;
   }
   else
   {
        /* Disconnect the UCB. It is in bound state now */
        if(!ucb->KEEP_IPADDR)
        {
            IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(ucb->IPV6ADDR));
        } /* Endif */
        IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(ucb->REMOTE_HOST6));
        ucb->REMOTE_PORT = 0;
   } /* Endif */
   /* add scope_id here */
   ucb->IF_SCOPE_ID = parms->if_scope_id;
   RTCSCMD_complete(parms, error);
   return;

} /* Endbody */

#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_connect
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] bound or open UCB
*    _CODE_PTR_         udpservice  not used
*     _ip_address       ipaddress   [IN] peer IP address
*     uint_16           udpport     [IN] peer port
*     uint_16           udpflags    not used
*     pointer           udpptr      not used
*     uint_32           udpword     [IN] socket level error
*
* Comments        :
*     Connects a UCB to a peer port.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
void UDP_connect
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UCB_STRUCT_PTR       ucb = parms->ucb, search_ptr, _PTR_ tmp_ptr;
   UCB_STRUCT_PTR       _PTR_ ins_ptr, _PTR_ del_ptr;
   uint_16              port;
   uint_32              error = parms->udpword;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   if (!error && (!(parms->udpport) || parms->ipaddress == INADDR_ANY)) {
      /* Connect requires both a port AND and IP address.  */
      error = RTCSERR_UDP_PORT_ZERO;

   } else if (!error)  {
      /* Bind a local address if none is specified */
      if (ucb->IPADDR == INADDR_ANY) {
         ucb->IPADDR = IP_route_find(parms->ipaddress, 0);
         if (ucb->IPADDR == INADDR_ANY) {
            error = RTCSERR_IP_UNREACH;
         } else {
            /*
            ** Make sure this connect request does not put two UCB's into the
            ** same configuration.
            */
            port = ucb->PORT;
            RTCS_LIST_SEARCH(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr) {
               if (search_ptr != ucb && search_ptr->PORT == port &&
                  search_ptr->IPADDR == ucb->IPADDR)
               {
                  error = RTCSERR_UDP_PORT_OPEN;
                  ucb->IPADDR = INADDR_ANY;
                  break;
               } /* Endif */
            } /* End SEARCH */
         } /* Endif */
      } /* Endif */
   }  /*Endif */

   /*
   ** Check for errors and location of UCB. If TRUE, UCB must be moved.
   ** This is an evaluates to TRUE if one of the following is true:
   ** A. There is an error, and there is a remote port  OR
   ** B. There is no error, and there is no remote port
   */
   if (!(error) == !(ucb->REMOTE_PORT)) {
      if (ucb->REMOTE_PORT)  {
         if (ucb->KEEP_IPADDR) {
            ins_ptr = &(UDP_cfg_ptr->LBOUND_UCB_HEAD);
         } else {
            ins_ptr = &(UDP_cfg_ptr->BOUND_UCB_HEAD);
         } /* Endif */
         del_ptr = &(UDP_cfg_ptr->OPEN_UCB_HEAD);
      } else {
         ins_ptr = &(UDP_cfg_ptr->OPEN_UCB_HEAD);
         if (ucb->KEEP_IPADDR) {
            del_ptr = &(UDP_cfg_ptr->LBOUND_UCB_HEAD);
         } else {
            del_ptr = &(UDP_cfg_ptr->BOUND_UCB_HEAD);
         } /* Endif */
      } /* Endif */

      /* Move the UCB from one list to the other */
      RTCS_LIST_SEARCHMOD(*del_ptr, tmp_ptr)
      {
         if (*tmp_ptr == ucb) {
            RTCS_LIST_DEL(*del_ptr, tmp_ptr);
            break;
         } /* Endif */
      } /* End SEARCH */

      RTCS_LIST_INS_END(*ins_ptr, ucb, tmp_ptr);
   } /* Endif */

   /* If there was no error, set the peer endpoint */
   if (!error)  {
      ucb->REMOTE_HOST = parms->ipaddress;
      ucb->REMOTE_PORT = parms->udpport;
   } else {
      /* Disconnect the UCB. It is in bound state now */
      if (!ucb->KEEP_IPADDR) {
         ucb->IPADDR = INADDR_ANY;
      } /* Endif */
      ucb->REMOTE_HOST = INADDR_ANY;
      ucb->REMOTE_PORT = 0;
   } /* Endif */

   RTCSCMD_complete(parms, error);
   return;

} /* Endbody */

#endif //RTCSCFG_ENABLE_IP4

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_receive6
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] UCB
*    _CODE_PTR_         udpservice  not used
*     in6_addr                ipv6address;
*     uint_16           udpport     [OUT] source UDP port
*     uint_16           udpflags    [IN] flags
*     pointer           udpptr      [IN/OUT] data buffer
*     uint_32           udpword     [IN/OUT] length of buffer
*
* Comments        :
*     Processes a receive request from the application.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6
void UDP_receive6
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   RTCSPCB_PTR       pcb_ptr;

   /*
   ** Search for a waiting packet on incoming queue
   */
   RTCS_QUEUE_PEEK(parms->ucb->PHEAD, parms->ucb->PTAIL, pcb_ptr);
   if(pcb_ptr)
   {

      if(!(parms->udpflags & RTCS_MSG_PEEK))
      {
         RTCS_QUEUE_DEL_NONEMPTY(parms->ucb->PHEAD, parms->ucb->PTAIL);
         parms->ucb->PCOUNT--;
      } /* Endif */

      /*
      ** Return request to Socket Layer with packet
      */
      IN6_ADDR_COPY((in6_addr *)(((IP_V6_HEADER_PTR)(pcb_ptr->NETWORK_LAYER))->SOURCE),&(parms->ipv6address));



      parms->udpport   = UDP_source(pcb_ptr);

      if(parms->udpword > RTCSPCB_SIZE(pcb_ptr))
      {
         parms->udpword = RTCSPCB_SIZE(pcb_ptr);
      } /* Endif */
      RTCSPCB_memcopy(pcb_ptr, parms->udpptr, 0, parms->udpword);

      ((SOCKET_STRUCT_PTR)parms->ucb->SOCKET)->LINK_OPTIONS.RX = pcb_ptr->LINK_OPTIONS.RX;

      if(!(parms->udpflags & RTCS_MSG_PEEK))
      {
         RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
         RTCSPCB_free(pcb_ptr);
      } /* Endif */

      RTCSCMD_complete(parms, RTCS_OK);
      return;

   }else if(parms->ucb->NONBLOCK_RX || (parms->udpflags & RTCS_MSG_PEEK))
         {

            /*
            ** Return request to Socket Layer with zero bytes
            */
            parms->ipaddress = INADDR_ANY;
            parms->udpport   = 0;
            parms->udpword   = 0;
            RTCSCMD_complete(parms, RTCS_OK);
            return;

   }
   else
   {

      /*
      ** Otherwise, enqueue the request
      */
      RTCS_QUEUE_INS(parms->ucb->RHEAD, parms->ucb->RTAIL, parms);

   } /* Endif */

} /* Endbody */

#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_receive
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] UCB
*    _CODE_PTR_         udpservice  not used
*     _ip_address       ipaddress   [OUT] source IP address
*     uint_16           udpport     [OUT] source UDP port
*     uint_16           udpflags    [IN] flags
*     pointer           udpptr      [IN/OUT] data buffer
*     uint_32           udpword     [IN/OUT] length of buffer
*
* Comments        :
*     Processes a receive request from the application.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
void UDP_receive
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   RTCSPCB_PTR       pcb_ptr;

   /*
   ** Search for a waiting packet on incoming queue
   */
   RTCS_QUEUE_PEEK(parms->ucb->PHEAD, parms->ucb->PTAIL, pcb_ptr);
   if (pcb_ptr) {

      if (!(parms->udpflags & RTCS_MSG_PEEK)) {
         RTCS_QUEUE_DEL_NONEMPTY(parms->ucb->PHEAD, parms->ucb->PTAIL);
         parms->ucb->PCOUNT--;
      } /* Endif */

      /*
      ** Return request to Socket Layer with packet
      */
      parms->ipaddress = IP_source(pcb_ptr);
      parms->udpport   = UDP_source(pcb_ptr);

      if (parms->udpword > RTCSPCB_SIZE(pcb_ptr)) {
         parms->udpword = RTCSPCB_SIZE(pcb_ptr);
      } /* Endif */
      RTCSPCB_memcopy(pcb_ptr, parms->udpptr, 0, parms->udpword);

      ((SOCKET_STRUCT_PTR)parms->ucb->SOCKET)->LINK_OPTIONS.RX = pcb_ptr->LINK_OPTIONS.RX;

      if (!(parms->udpflags & RTCS_MSG_PEEK)) {
         RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
         RTCSPCB_free(pcb_ptr);
      } /* Endif */

      RTCSCMD_complete(parms, RTCS_OK);
      return;

   } else if (parms->ucb->NONBLOCK_RX || (parms->udpflags & RTCS_MSG_PEEK)) {

      /*
      ** Return request to Socket Layer with zero bytes
      */
      parms->ipaddress = INADDR_ANY;
      parms->udpport   = 0;
      parms->udpword   = 0;
      RTCSCMD_complete(parms, RTCS_OK);
      return;

   } else {

      /*
      ** Otherwise, enqueue the request
      */
      RTCS_QUEUE_INS(parms->ucb->RHEAD, parms->ucb->RTAIL, parms);

   } /* Endif */

} /* Endbody */
#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_send
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] UCB
*    _CODE_PTR_         udpservice  not used
*     _ip_address       ipaddress   [IN] destination IP address
*     uint_16           udpport     [IN] destination UDP port
*     uint_16           udpflags    [IN] flags
*     pointer           udpptr      [IN] data to send
*     uint_32           udpword     [IN] length of data to send
*
* Comments        :
*     Sends a UDP packet.
*
*END*-----------------------------------------------------------------*/
void UDP_send
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   RTCSPCB_PTR          pcb;
   register boolean     nonblock;
   uint_32              error;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   if (parms->udpport == 0) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_DISCARDED++);
      RTCSCMD_complete(parms, RTCSERR_UDP_PORT_ZERO);
      return;
   } /* Endif */

   pcb = RTCSPCB_alloc_send();
   if (pcb == NULL) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      RTCSCMD_complete(parms, RTCSERR_PCB_ALLOC);
      return;
   } /* Endif */
   if (parms->udpflags & RTCS_MSG_O_NONBLOCK) {
      nonblock = parms->udpflags & RTCS_MSG_S_NONBLOCK;
   } else {
      nonblock = parms->ucb->NONBLOCK_TX;
   } /* Endif */

   if (nonblock) {
      uchar_ptr udpbuffer;

      udpbuffer = RTCS_mem_alloc_system(parms->udpword);
      if (!udpbuffer) {
         IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
         IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         RTCSLOG_PCB_FREE(pcb, RTCSERR_PCB_ALLOC);
         RTCSPCB_free(pcb);
         RTCSCMD_complete(parms, RTCSERR_PCB_ALLOC);
         return;
      } /* Endif */

       _mem_set_type(udpbuffer, MEM_TYPE_UDP_BUFFER);


      error = RTCSPCB_append_fragment_autofree(pcb, parms->udpword, udpbuffer);
      if (error) {
         IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
         IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb));
         _mem_free(udpbuffer);
         RTCSLOG_PCB_FREE(pcb, error);
         RTCSPCB_free(pcb);
         RTCSCMD_complete(parms, error);
         return;
      } /* Endif */

      _mem_copy(parms->udpptr, udpbuffer, parms->udpword);

   } else {

      error = RTCSPCB_append_fragment(pcb, parms->udpword, parms->udpptr);
      if (error) {
         IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
         IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
         IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb));
         RTCSLOG_PCB_FREE(pcb, error);
         RTCSPCB_free(pcb);
         RTCSCMD_complete(parms, error);
         return;
      } /* Endif */

      pcb->UDP_REQUEST = parms;

   } /* Endif */

   pcb->LINK_OPTIONS.TX = ((SOCKET_STRUCT_PTR)parms->ucb->SOCKET)->LINK_OPTIONS.TX;

   parms->COMMON.ERROR = RTCS_OK;

   /* Added IPv6 support */
   /*
        TBD :
                I create UDP_send_internal6 just for compatibility and clear view.
                Later  it should be integrated with UDP_send_internal
    */
   error=1;
#if RTCSCFG_ENABLE_IP4
   if(((SOCKET_STRUCT_PTR)parms->ucb->SOCKET)->AF == AF_INET)
   {
        error = UDP_send_internal(parms->ucb, parms->ucb->IPADDR, parms->ipaddress, parms->udpport, pcb, parms->udpflags);
   }
   #if RTCSCFG_ENABLE_IP6
   else
   #endif
#endif

#if RTCSCFG_ENABLE_IP6
   if((((SOCKET_STRUCT_PTR)parms->ucb->SOCKET)->AF == AF_INET6))
   {
     if(parms->if_scope_id)
        {
         /* parms->if_scope_id has value of scope_id from destination address.
          * If it is not NULL we will use it for calculation what interface we will be used for send packet.
          */
            pcb->IFSRC = ip6_if_get_by_scope_id( parms->if_scope_id);
        }
        else if(parms->ucb->IF_SCOPE_ID)
        {/* parms->ucb->IF_SCOPE_ID has value of scope_id from local address.
          * If it is not NULL we will use it for calculation what interface we will be used for send packet.
          */
            pcb->IFSRC = ip6_if_get_by_scope_id( parms->ucb->IF_SCOPE_ID);
        }
        else
        {   /*
             * if scope_id was not defined( is NULL) let IP level calculate send interface
             */
            pcb->IFSRC = NULL;
        }


        error = UDP_send_internal6(parms->ucb, parms->ucb->IPV6ADDR, parms->ipv6address, parms->udpport, pcb, parms->udpflags);
   }
#endif /* RTCSCFG_ENABLE_IP6 */

   if (nonblock)
   {
        RTCSCMD_complete(parms, error);
   }
   else if (error)
   {
        parms->COMMON.ERROR = error;  /* Assumes application is lower priority */
   } /* Endif */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_send_internal6
* Returned Values : error code
* Comments        :
*     Sends a UDP packet.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6
uint_32 UDP_send_internal6
   (
      UCB_STRUCT_PTR    ucb,        /* [IN] UDP layer context        */
      in6_addr          srcaddr,    /* [IN] source IPv6 address      */
      in6_addr          destaddr,   /* [IN] destination IPv6 address */
      uint_16           destport,   /* [IN] destination UDP port     */
      RTCSPCB_PTR       pcb_ptr,    /* [IN] packet to send           */
      uint_32           flags       /* [IN] optional flags           */
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UDP_HEADER_PTR       packet;
   register boolean     nochksum;
   uint_32              error;

   UDP_cfg_ptr = RTCS_getcfg(UDP);
   IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);

   error = RTCSPCB_insert_header(pcb_ptr, sizeof(UDP_HEADER));
   if (error) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb_ptr));
      RTCSLOG_PCB_FREE(pcb_ptr, error);
      RTCSPCB_free(pcb_ptr);
      return error;
   } /* Endif */

   RTCSLOG_PCB_WRITE(pcb_ptr, RTCS_LOGCTRL_PROTO(IPPROTO_UDP), 0);

   packet = (UDP_HEADER_PTR)RTCSPCB_DATA(pcb_ptr);
   RTCSPCB_DATA_TRANSPORT(pcb_ptr) = RTCSPCB_DATA(pcb_ptr);
   htons(packet->SRC_PORT, ucb->PORT);
   htons(packet->DEST_PORT, destport);
   htons(packet->LENGTH, RTCSPCB_SIZE(pcb_ptr));
   htons(packet->CHECKSUM, 0);

   if (flags & RTCS_MSG_O_NOCHKSUM) {
      nochksum = flags & RTCS_MSG_S_NOCHKSUM;
   } else {
      nochksum = ucb->BYPASS_TX;
   } /* Endif */
   if (!nochksum)
   {
      pcb_ptr->IP_SUM     = IP_Sum_PCB(RTCSPCB_SIZE(pcb_ptr), pcb_ptr);
      pcb_ptr->IP_SUM_PTR = packet->CHECKSUM;
   } /* Endif */
   /*
        Here I am checking is local IP is  NULL or not
        It is necessary for allow IPsend change NULL local ipv6 to correct local IPv6
    */
   if(IN6_ARE_ADDR_EQUAL(&srcaddr, &in6addr_any))
   {
        return IP6_send(pcb_ptr, IPPROTO_UDP, NULL,&destaddr, pcb_ptr->IFSRC, 0);
   }
   else
   {
        return IP6_send(pcb_ptr, IPPROTO_UDP, &srcaddr,&destaddr, pcb_ptr->IFSRC, 0);
   }
} /* Endbody */

#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_send_internal
* Returned Values : error code
* Comments        :
*     Sends a UDP packet.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
uint_32 UDP_send_internal
   (
      UCB_STRUCT_PTR    ucb,        /* [IN] UDP layer context      */
      _ip_address       srcaddr,    /* [IN] source IP address      */
      _ip_address       destaddr,   /* [IN] destination IP address */
      uint_16           destport,   /* [IN] destination UDP port   */
      RTCSPCB_PTR       pcb_ptr,    /* [IN] packet to send         */
      uint_32           flags       /* [IN] optional flags         */
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UDP_HEADER_PTR       packet;
   register boolean     nochksum;
   uint_32              error;

   UDP_cfg_ptr = RTCS_getcfg(UDP);
   IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);

   error = RTCSPCB_insert_header(pcb_ptr, sizeof(UDP_HEADER));
   if (error) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb_ptr));
      RTCSLOG_PCB_FREE(pcb_ptr, error);
      RTCSPCB_free(pcb_ptr);
      return error;
   } /* Endif */

   RTCSLOG_PCB_WRITE(pcb_ptr, RTCS_LOGCTRL_PROTO(IPPROTO_UDP), 0);

   packet = (UDP_HEADER_PTR)RTCSPCB_DATA(pcb_ptr);
   RTCSPCB_DATA_TRANSPORT(pcb_ptr) = RTCSPCB_DATA(pcb_ptr);
   htons(packet->SRC_PORT, ucb->PORT);
   htons(packet->DEST_PORT, destport);
   htons(packet->LENGTH, RTCSPCB_SIZE(pcb_ptr));
   htons(packet->CHECKSUM, 0);

   if (flags & RTCS_MSG_O_NOCHKSUM) {
      nochksum = flags & RTCS_MSG_S_NOCHKSUM;
   } else {
      nochksum = ucb->BYPASS_TX;
   } /* Endif */

   if (!nochksum) {
      pcb_ptr->IP_SUM     = IP_Sum_PCB(RTCSPCB_SIZE(pcb_ptr), pcb_ptr);
      pcb_ptr->IP_SUM_PTR = packet->CHECKSUM;
   } /* Endif */

   return IP_send(pcb_ptr, IPPROTO_UDP, srcaddr, destaddr, flags);

} /* Endbody */
#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_send_IF
* Returned Values : uint_32 (error code)
* Comments        :
*     Sends a UDP packet through a specific IP interface.
*
*END*-----------------------------------------------------------------*/

uint_32 UDP_send_IF
   (
      UCB_STRUCT_PTR    ucb,           /* [IN/OUT] UDP layer context   */
      pointer           dest_if,       /* [IN]     dest interface      */
      uint_16           dest_port,     /* [IN]     dest port           */
      RTCSPCB_PTR       pcb_ptr        /* [IN/OUT] packet to send      */
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UDP_HEADER_PTR packet;
   uint_32        error;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);

   if (dest_port == 0) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_DISCARDED++);
      RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_PORT_ZERO);
      RTCSPCB_free(pcb_ptr);
      return RTCSERR_UDP_PORT_ZERO;
   } /* Endif */

   error = RTCSPCB_insert_header(pcb_ptr, sizeof(UDP_HEADER));
   if (error) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb_ptr));
      RTCSLOG_PCB_FREE(pcb_ptr, error);
      RTCSPCB_free(pcb_ptr);
      return error;
   } /* Endif */

   RTCSLOG_PCB_WRITE(pcb_ptr, RTCS_LOGCTRL_PROTO(IPPROTO_UDP), 0);

   packet = (UDP_HEADER_PTR)RTCSPCB_DATA(pcb_ptr);
   RTCSPCB_DATA_TRANSPORT(pcb_ptr) = RTCSPCB_DATA(pcb_ptr);
   htons(packet->SRC_PORT, ucb->PORT);
   htons(packet->DEST_PORT, dest_port);
   htons(packet->LENGTH, RTCSPCB_SIZE(pcb_ptr));
   htons(packet->CHECKSUM, 0);

   pcb_ptr->IP_SUM     = IP_Sum_PCB(RTCSPCB_SIZE(pcb_ptr), pcb_ptr);
   pcb_ptr->IP_SUM_PTR = packet->CHECKSUM;

   return IP_send_IF(pcb_ptr, IPPROTO_UDP, dest_if);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_service6
* Returned Values : void
* Comments        :
*     Process incoming UDP packets for IPv6 family.  Called from IP6_service.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6
void UDP_service6
   (
      RTCSPCB_PTR    pcb_ptr,          /* [IN/OUT] incoming packet */
      pointer        dummy             /* [IN]     not used        */
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UDP_HEADER_PTR       packet;
   uint_16              port, src_port, len, sum;
   UCB_STRUCT_PTR       ucb_ptr = NULL;
   UCB_STRUCT_PTR       _PTR_ search_ptr;
  /*IPv6 part************/
   IP6_HEADER_PTR          ip6_packet;
   in6_addr                ipv6source;
   in6_addr                ipv6dest;
   uint_32              error;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_TOTAL++);
   packet = (UDP_HEADER_PTR)RTCSPCB_DATA(pcb_ptr);
   RTCSPCB_DATA_TRANSPORT(pcb_ptr) = RTCSPCB_DATA(pcb_ptr);
   port = ntohs(packet->DEST_PORT);
   len = ntohs(packet->LENGTH);

   /*
   ** Make sure that
   **    sizeof(UDP_HEADER) <= pktlen <= RTCSPCB_SIZE(pcb)
   **
   ** Note: If RTCSPCB_SIZE(pcb) is too small, then pktlen is
   **       undefined.  However, if the following conditions pass,
   **       then RTCSPCB_SIZE(pcb) >= sizeof(UDP_HEADER), and
   **       therefore, pktlen is valid.
   */
   if(
        len < sizeof(UDP_HEADER)
     )
   {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_SMALL_DGRAM++);
      RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_BAD_HEADER);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */

   if(
        RTCSPCB_SIZE(pcb_ptr) < len
     )
   {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_SMALL_PKT++);
      RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_BAD_HEADER);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */

   RTCSLOG_PCB_READ(pcb_ptr, RTCS_LOGCTRL_PROTO(IPPROTO_UDP), 0);

   /*
   ** Port zero is an illegal destination
   */
   if(
        port == 0
     )
   {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_BAD_PORT++);
      RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_BAD_HEADER);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */

   /*
   ** Find a listening UCB, and move it to the front.
   ** There are multiple lists to search. If the UNICAST bit in the pcb is not
   ** set, we will only check the BOUND list, because this is the only list
   ** that can receive Multicast or Broadcast packets. No ucb that is bound to
   ** a specific local IP can receive a multicast or broadcast packet.
   */

   /*convert packet to IP6_HEADER_PTR type*/
   ip6_packet= (IP6_HEADER_PTR)RTCSPCB_DATA_NETWORK(pcb_ptr);

   /* extract source port number */
   src_port = ntohs(packet->SRC_PORT);

   /* using IPv6 copy macros to copy the IPv6 address structure */
   IN6_ADDR_COPY((in6_addr *)ip6_packet->SOURCE, &ipv6source);
   IN6_ADDR_COPY((in6_addr *)ip6_packet->DEST, &ipv6dest);

   /*
   ** Only search this list if the packet might be unicast.
   ** The search criterion is matching host PORT/IP and matching peer PORT/IP
   */
   if(
        pcb_ptr->TYPE & RTCSPCB_TYPE_UNICAST
     )
   {
      RTCS_LIST_PEEK(UDP_cfg_ptr->OPEN_UCB_HEAD, ucb_ptr);
      if(
            ucb_ptr &&(
                        ucb_ptr->PORT != port                                       ||
                        (!IN6_ARE_ADDR_EQUAL(&(ucb_ptr->REMOTE_HOST6), &ipv6source))||
                        ucb_ptr->REMOTE_PORT != src_port                            ||
                        (!IN6_ARE_ADDR_EQUAL(&(ucb_ptr->IPV6ADDR), &ipv6dest))
                      )
        )
      {
            ucb_ptr = NULL;
            RTCS_LIST_SEARCHMOD_NOHEAD(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr)
            {
                if(
                    (*search_ptr)->PORT == port &&
                    (IN6_ARE_ADDR_EQUAL(&((*search_ptr)->REMOTE_HOST6), &ipv6source))&&
                    (*search_ptr)->REMOTE_PORT == src_port &&
                    (IN6_ARE_ADDR_EQUAL(&((*search_ptr)->IPV6ADDR), &ipv6dest))
                  )
                {
                    ucb_ptr = *search_ptr;
                    RTCS_LIST_DEL(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr);
                    RTCS_LIST_INS(UDP_cfg_ptr->OPEN_UCB_HEAD, ucb_ptr);
                    break;
                } /* Endif */
            } /* End SEARCH */
      } /* Endif */
   } /* Endif */

#if RTCSCFG_UDP_ENABLE_LBOUND_MULTICAST && RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   /*
   ** If no OPEN ucb matches, search the LBOUND ucb list,
   ** allowing multicast.  The local port must match the
   ** packet destination port.
   */
   if(!ucb_ptr && UDP_cfg_ptr->LBOUND_UCB_HEAD)
   {
   /*TODO:tihs part of code looks like never was tested and work at all*/
        RTCS_LIST_PEEK(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb_ptr);
        if(
            ucb_ptr &&
                        (
                            (ucb_ptr->PORT != port) ||
                            (!IN6_IS_ADDR_MULTICAST(&ipv6dest)
                        ) ||

                        (
                            !IGMP_is_member (&ucb_ptr->MCB_PTR, pcb_ptr->IFSRC, ipdest)

                        )

          )
        {
            ucb_ptr = NULL;
            RTCS_LIST_SEARCHMOD_NOHEAD(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr)
            {
                if (
                        (
                            (*search_ptr)->PORT == port) &&
                            (IN_MULTICAST(ipdest)) &&
                            (IGMP_is_member(&(*search_ptr)->MCB_PTR, pcb_ptr->IFSRC, ipdest))
                        )
                {
                    ucb_ptr = *search_ptr;
                    RTCS_LIST_DEL(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr);
                    RTCS_LIST_INS(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb_ptr);
                    break;
                } /* Endif */
            } /* End SEARCH */
        } /* Endif */
    } /* Endif */
#else

   /*
   ** If no OPEN ucb matches, search the LBOUND ucb list.
   ** Only search this list if the packet could be unicast.
   ** The search criterion is a matching local IP/PORT
   */
   if(
        !ucb_ptr && UDP_cfg_ptr->LBOUND_UCB_HEAD &&
        (pcb_ptr->TYPE & RTCSPCB_TYPE_UNICAST)
     )
   {
        RTCS_LIST_PEEK(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb_ptr);
        if(
            ucb_ptr &&
            ucb_ptr->PORT != port ||
            (!IN6_ARE_ADDR_EQUAL(&(ucb_ptr->IPV6ADDR), &ipv6dest))
         )
        {
            ucb_ptr = NULL;
            RTCS_LIST_SEARCHMOD_NOHEAD(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr)
            {
                if(
                    (*search_ptr)->PORT == port &&
                    IN6_ARE_ADDR_EQUAL(&((*search_ptr)->IPV6ADDR), &ipv6dest)
                  )
                {
                    ucb_ptr = *search_ptr;
                    RTCS_LIST_DEL(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr);
                    RTCS_LIST_INS(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb_ptr);
                    break;
                } /* Endif */
            } /* End SEARCH */
        }/* Endif */
    } /* Endif */

#endif

   /*
   ** If no LBOUND ucb matches, search the BOUND ucb list
   ** Always search this list, regardless of packet type.
   ** The local port must match the packet destination port
   */
   if(!ucb_ptr && UDP_cfg_ptr->BOUND_UCB_HEAD)
   {
        RTCS_LIST_PEEK(UDP_cfg_ptr->BOUND_UCB_HEAD, ucb_ptr);
        if(ucb_ptr && ucb_ptr->PORT != port)
        {
            ucb_ptr = NULL;
            RTCS_LIST_SEARCHMOD_NOHEAD(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr)
            {
                if((*search_ptr)->PORT == port)
                {
                    ucb_ptr = *search_ptr;
                    RTCS_LIST_DEL(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr);
                    RTCS_LIST_INS(UDP_cfg_ptr->BOUND_UCB_HEAD, ucb_ptr);
                    break;
                } /* Endif */
            } /* End SEARCH */
        }/* Endif */

      /* Check the message was multicast, and if the ucb is a member */
        if (
                ucb_ptr &&
                IN6_IS_ADDR_MULTICAST(&ipv6dest)
           )
        {
            ucb_ptr = NULL;
        } /* Endif */
    } /* Endif */

    /* Lets check scope_id there binded socket and scope _id of input packet*/
    error = ip6_if_get_scope_id(pcb_ptr->IFSRC);

    /*
     * If scope_id of input packet is different from UCB scope_id set UCB to NULL and
     * UCB to NULL, to discard packet and generate error.
     */
    if(ucb_ptr->IF_SCOPE_ID)
    {
        if(ucb_ptr->IF_SCOPE_ID != error)
        {
            ucb_ptr = NULL;
        }
    }
   /*
   ** If no UCB was found on the destination port, discard packet and generate
   ** a ICMP error packet
   */
   if(!ucb_ptr)
   {
        IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
        IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_NO_PORT++);
        ICMP6_send_error (ICMP6_TYPE_DEST_UNREACH, ICMP6_CODE_DU_PORT_UNREACH,
                                0   /* [IN] error parameter */,
                                pcb_ptr   /* [IN] the packet which caused the error */);
        RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
        RTCSPCB_free(pcb_ptr);
        return;
   } /* Endif */


   /*
   ** Verify the checksum if present
   */
   if(ntohs(packet->CHECKSUM) && !ucb_ptr->BYPASS_RX)
   {
        /*IP6 use different method for calculation checksum*/
        sum = IP6_Sum_pseudo(RTCSPCB_SIZE(pcb_ptr), pcb_ptr);
        sum = IP_Sum_PCB(sum, pcb_ptr);

        if (sum != 0xFFFF)
        {
            IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
            IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_BAD_CHECKSUM++);
            RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_BAD_CHECKSUM);
            RTCSPCB_free(pcb_ptr);
            return;
        } /* Endif */
   } /* Endif */


   /*
   ** Although RTCSPCB_shrink() always shrinks the first fragment,
   ** this is OK, because if RTCSPCB_SIZE(pcb_ptr) != len, then the
   ** datagram must have originated from another host, in which
   ** case the PCB only has one fragment.
   **
   ** If the packet originated on this host (and was looped back),
   ** the datagram could have several fragments, but in this case,
   ** RTCSPCB_SIZE(pcb_ptr) == len, so we'll always shrink zero bytes.
   */
   error = RTCSPCB_shrink(pcb_ptr, RTCSPCB_SIZE(pcb_ptr) - len);
   if(error)
   {
        IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_ERRORS++);
        IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_RX, error, (uint_32)pcb_ptr));
        RTCSLOG_PCB_FREE(pcb_ptr, error);
        RTCSPCB_free(pcb_ptr);
        return;
   } /* Endif */
   error = RTCSPCB_next(pcb_ptr, sizeof(UDP_HEADER));
   if(error)
   {
        IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_ERRORS++);
        IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_RX, error, (uint_32)pcb_ptr));
        RTCSLOG_PCB_FREE(pcb_ptr, error);
        RTCSPCB_free(pcb_ptr);
        return;
   } /* Endif */

   ucb_ptr->SERVICE(pcb_ptr, ucb_ptr);

} /* Endbody */

#endif


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_service
* Returned Values : void
* Comments        :
*     Process incoming UDP packets.  Called from IP_service.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
void UDP_service
   (
      RTCSPCB_PTR    pcb_ptr,          /* [IN/OUT] incoming packet */
      pointer        dummy             /* [IN]     not used        */
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UDP_HEADER_PTR       packet;
   uint_16              port, src_port, len, sum;
   UCB_STRUCT_PTR       ucb_ptr = NULL;
   UCB_STRUCT_PTR       _PTR_ search_ptr;
   _ip_address          ipdest, ipsource;
   uint_32              error;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_TOTAL++);
   packet = (UDP_HEADER_PTR)RTCSPCB_DATA(pcb_ptr);
   RTCSPCB_DATA_TRANSPORT(pcb_ptr) = RTCSPCB_DATA(pcb_ptr);
   port = ntohs(packet->DEST_PORT);
   len = ntohs(packet->LENGTH);

   /*
   ** Make sure that
   **    sizeof(UDP_HEADER) <= pktlen <= RTCSPCB_SIZE(pcb)
   **
   ** Note: If RTCSPCB_SIZE(pcb) is too small, then pktlen is
   **       undefined.  However, if the following conditions pass,
   **       then RTCSPCB_SIZE(pcb) >= sizeof(UDP_HEADER), and
   **       therefore, pktlen is valid.
   */
   if (len < sizeof(UDP_HEADER)) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_SMALL_DGRAM++);
      RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_BAD_HEADER);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */
   if (RTCSPCB_SIZE(pcb_ptr) < len) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_SMALL_PKT++);
      RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_BAD_HEADER);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */

   RTCSLOG_PCB_READ(pcb_ptr, RTCS_LOGCTRL_PROTO(IPPROTO_UDP), 0);

   /*
   ** Port zero is an illegal destination
   */
   if (port == 0) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_BAD_PORT++);
      RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_BAD_HEADER);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */

   /*
   ** Find a listening UCB, and move it to the front.
   ** There are multiple lists to search. If the UNICAST bit in the pcb is not
   ** set, we will only check the BOUND list, because this is the only list
   ** that can receive Multicast or Broadcast packets. No ucb that is bound to
   ** a specific local IP can receive a multicast or broadcast packet.
   */
   src_port = ntohs(packet->SRC_PORT);
   ipsource = IP_source(pcb_ptr);
   ipdest = IP_dest(pcb_ptr);

   /*
   ** Only search this list if the packet might be unicast.
   ** The search criterion is matching host PORT/IP and matching peer PORT/IP
   */
   if (pcb_ptr->TYPE & RTCSPCB_TYPE_UNICAST) {
      RTCS_LIST_PEEK(UDP_cfg_ptr->OPEN_UCB_HEAD, ucb_ptr);
      if (ucb_ptr &&
         (ucb_ptr->PORT != port ||
          ucb_ptr->REMOTE_HOST != ipsource ||
          ucb_ptr->REMOTE_PORT != src_port ||
          ucb_ptr->IPADDR != ipdest))
      {
         ucb_ptr = NULL;
         RTCS_LIST_SEARCHMOD_NOHEAD(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr) {
            if ((*search_ptr)->PORT == port &&
            (*search_ptr)->REMOTE_HOST == ipsource &&
            (*search_ptr)->REMOTE_PORT == src_port &&
            (*search_ptr)->IPADDR == ipdest)
            {
               ucb_ptr = *search_ptr;
               RTCS_LIST_DEL(UDP_cfg_ptr->OPEN_UCB_HEAD, search_ptr);
               RTCS_LIST_INS(UDP_cfg_ptr->OPEN_UCB_HEAD, ucb_ptr);
               break;
            } /* Endif */
         } /* End SEARCH */
      } /* Endif */
   } /* Endif */

#if RTCSCFG_UDP_ENABLE_LBOUND_MULTICAST && RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
   /*
   ** If no OPEN ucb matches, search the LBOUND ucb list,
   ** allowing multicast.  The local port must match the
   ** packet destination port.
   */
   if (!ucb_ptr && UDP_cfg_ptr->LBOUND_UCB_HEAD)  {
      RTCS_LIST_PEEK(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb_ptr);
      if (ucb_ptr && ((ucb_ptr->PORT != port) || ((IN_MULTICAST(ipdest)) && (!IGMP_is_member(&ucb_ptr->MCB_PTR, pcb_ptr->IFSRC, ipdest)))))  {
         ucb_ptr = NULL;
         RTCS_LIST_SEARCHMOD_NOHEAD(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr)  {
            if ((((*search_ptr)->PORT == port) && (!IN_MULTICAST(ipdest))) ||
                (((*search_ptr)->PORT == port) && (IN_MULTICAST(ipdest)) && (IGMP_is_member(&(*search_ptr)->MCB_PTR, pcb_ptr->IFSRC, ipdest))))  {
               ucb_ptr = *search_ptr;
               RTCS_LIST_DEL(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr);
               RTCS_LIST_INS(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb_ptr);
               break;
            } /* Endif */
         } /* End SEARCH */
      } /* Endif */
   } /* Endif */
#else

   /*
   ** If no OPEN ucb matches, search the LBOUND ucb list.
   ** Only search this list if the packet could be unicast.
   ** The search criterion is a matching local IP/PORT
   */
   if (!ucb_ptr && UDP_cfg_ptr->LBOUND_UCB_HEAD &&
       (pcb_ptr->TYPE & RTCSPCB_TYPE_UNICAST)) {
      RTCS_LIST_PEEK(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb_ptr);
      if (ucb_ptr && ucb_ptr->PORT != port ||
          ucb_ptr->IPADDR != ipdest)
      {
         ucb_ptr = NULL;
         RTCS_LIST_SEARCHMOD_NOHEAD(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr)  {
            if ((*search_ptr)->PORT == port &&
                (*search_ptr)->IPADDR == ipdest)
            {
               ucb_ptr = *search_ptr;
               RTCS_LIST_DEL(UDP_cfg_ptr->LBOUND_UCB_HEAD, search_ptr);
               RTCS_LIST_INS(UDP_cfg_ptr->LBOUND_UCB_HEAD, ucb_ptr);
               break;
            } /* Endif */
         } /* End SEARCH */
      }/* Endif */
   } /* Endif */

#endif

   /*
   ** If no LBOUND ucb matches, search the BOUND ucb list
   ** Always search this list, regardless of packet type.
   ** The local port must match the packet destination port
   */
   if (!ucb_ptr && UDP_cfg_ptr->BOUND_UCB_HEAD)  {
      RTCS_LIST_PEEK(UDP_cfg_ptr->BOUND_UCB_HEAD, ucb_ptr);
      if (ucb_ptr && ucb_ptr->PORT != port)  {
         ucb_ptr = NULL;
         RTCS_LIST_SEARCHMOD_NOHEAD(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr)  {
            if ((*search_ptr)->PORT == port)  {
               ucb_ptr = *search_ptr;
               RTCS_LIST_DEL(UDP_cfg_ptr->BOUND_UCB_HEAD, search_ptr);
               RTCS_LIST_INS(UDP_cfg_ptr->BOUND_UCB_HEAD, ucb_ptr);
               break;
            } /* Endif */
         } /* End SEARCH */
      }/* Endif */

      /* Check the message was multicast, and if the ucb is a member */
      if (ucb_ptr && IN_MULTICAST(ipdest)) {
#if RTCSCFG_ENABLE_IGMP && RTCSCFG_ENABLE_IP4
         if (!IGMP_is_member(&ucb_ptr->MCB_PTR, pcb_ptr->IFSRC, ipdest)) {
            ucb_ptr = NULL;
         }
#else
         ucb_ptr = NULL;
#endif
      } /* Endif */
   } /* Endif */

   /*
   ** If no UCB was found on the destination port, discard packet and generate
   ** a ICMP error packet
   */
   if (!ucb_ptr) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_NO_PORT++);
      #if RTCSCFG_ENABLE_ICMP
      ICMP_send_error(ICMPTYPE_DESTUNREACH, ICMPCODE_DU_PORT_UNREACH, 0, pcb_ptr, -1);
      #endif
      RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */

   /*
   ** Verify the checksum if present
   */
   if (ntohs(packet->CHECKSUM) && !ucb_ptr->BYPASS_RX) {
      sum = IP_Sum_pseudo(len, pcb_ptr, -1);
      sum = IP_Sum_PCB(sum, pcb_ptr);
      if (sum != 0xFFFF) {
         IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
         IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.ST_RX_BAD_CHECKSUM++);
         RTCSLOG_PCB_FREE(pcb_ptr, RTCSERR_UDP_BAD_CHECKSUM);
         RTCSPCB_free(pcb_ptr);
         return;
      } /* Endif */
   } /* Endif */

   /*
   ** Although RTCSPCB_shrink() always shrinks the first fragment,
   ** this is OK, because if RTCSPCB_SIZE(pcb_ptr) != len, then the
   ** datagram must have originated from another host, in which
   ** case the PCB only has one fragment.
   **
   ** If the packet originated on this host (and was looped back),
   ** the datagram could have several fragments, but in this case,
   ** RTCSPCB_SIZE(pcb_ptr) == len, so we'll always shrink zero bytes.
   */
   error = RTCSPCB_shrink(pcb_ptr, RTCSPCB_SIZE(pcb_ptr) - len);
   if (error) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_ERRORS++);
      IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_RX, error, (uint_32)pcb_ptr));
      RTCSLOG_PCB_FREE(pcb_ptr, error);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */
   error = RTCSPCB_next(pcb_ptr, sizeof(UDP_HEADER));
   if (error) {
      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_ERRORS++);
      IF_UDP_STATS_ENABLED(RTCS_seterror(&UDP_cfg_ptr->STATS.ERR_RX, error, (uint_32)pcb_ptr));
      RTCSLOG_PCB_FREE(pcb_ptr, error);
      RTCSPCB_free(pcb_ptr);
      return;
   } /* Endif */

   ucb_ptr->SERVICE(pcb_ptr, ucb_ptr);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_process6
* Returned Values : void
* Comments        :
*     Process valid incoming UDP packets for IPv6 family. Called from UDP_service.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP6

void UDP_process6
   (
      RTCSPCB_PTR    pcb_ptr,          /* [IN/OUT] incoming packet */
      UCB_STRUCT_PTR ucb_ptr           /* [IN]     target UCB      */
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UDP_PARM_PTR         req_ptr;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   /*
   ** If there is a pending request, unblock it
   */
   RTCS_QUEUE_PEEK(ucb_ptr->RHEAD, ucb_ptr->RTAIL, req_ptr);
   if (req_ptr)
   {
      RTCS_QUEUE_DEL_NONEMPTY(ucb_ptr->RHEAD, ucb_ptr->RTAIL);
      IN6_ADDR_COPY((in6_addr *)(((IP_V6_HEADER_PTR)(pcb_ptr->NETWORK_LAYER))->SOURCE),&(req_ptr->ipv6address));
      req_ptr->udpport   = UDP_source(pcb_ptr);
      /* here we get scope_id */
      req_ptr->if_scope_id = ip6_if_get_scope_id(pcb_ptr->IFSRC);
      if (req_ptr->udpword > RTCSPCB_SIZE(pcb_ptr)) {
         req_ptr->udpword = RTCSPCB_SIZE(pcb_ptr);
      } /* Endif */
      RTCSPCB_memcopy(pcb_ptr, req_ptr->udpptr, 0, req_ptr->udpword);
      ((SOCKET_STRUCT_PTR)ucb_ptr->SOCKET)->LINK_OPTIONS.RX = pcb_ptr->LINK_OPTIONS.RX;
      RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
      RTCSPCB_free(pcb_ptr);
      RTCSCMD_complete(req_ptr, RTCS_OK);
      return;
   }
   else if (ucb_ptr->PCOUNT >= _UDP_max_queue_size)
   {
       IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_MISSED++);
       RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
       RTCSPCB_free(pcb_ptr);
       return;
   /*
   ** Otherwise, enqueue the packet
   */
   }
   else
   {

        RTCS_QUEUE_INS(ucb_ptr->PHEAD, ucb_ptr->PTAIL, pcb_ptr);
        ucb_ptr->PCOUNT++;

      /*
      ** Notify socket layer in case some task is blocked on select()
      ** waiting for this data.
      */
        SOCK_select_signal(ucb_ptr->SOCKET, UDP_SOCKET_ENQUEUED);
   } /* Endif */

} /* Endbody */

#endif


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_process
* Returned Values : void
* Comments        :
*     Process valid incoming UDP packets.  Called from UDP_service.
*
*END*-----------------------------------------------------------------*/
#if RTCSCFG_ENABLE_IP4
void UDP_process
   (
      RTCSPCB_PTR    pcb_ptr,          /* [IN/OUT] incoming packet */
      UCB_STRUCT_PTR ucb_ptr           /* [IN]     target UCB      */
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UDP_PARM_PTR         req_ptr;

   UDP_cfg_ptr = RTCS_getcfg(UDP);

   /*
   ** If there is a pending request, unblock it
   */
   RTCS_QUEUE_PEEK(ucb_ptr->RHEAD, ucb_ptr->RTAIL, req_ptr);
   if (req_ptr) {

      RTCS_QUEUE_DEL_NONEMPTY(ucb_ptr->RHEAD, ucb_ptr->RTAIL);

      req_ptr->ipaddress = IP_source(pcb_ptr);
      req_ptr->udpport   = UDP_source(pcb_ptr);

      if (req_ptr->udpword > RTCSPCB_SIZE(pcb_ptr)) {
         req_ptr->udpword = RTCSPCB_SIZE(pcb_ptr);
      } /* Endif */

      RTCSPCB_memcopy(pcb_ptr, req_ptr->udpptr, 0, req_ptr->udpword);

      ((SOCKET_STRUCT_PTR)ucb_ptr->SOCKET)->LINK_OPTIONS.RX = pcb_ptr->LINK_OPTIONS.RX;

      RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
      RTCSPCB_free(pcb_ptr);
      RTCSCMD_complete(req_ptr, RTCS_OK);
      return;

   } else if (ucb_ptr->PCOUNT >= _UDP_max_queue_size) {

      IF_UDP_STATS_ENABLED(UDP_cfg_ptr->STATS.COMMON.ST_RX_MISSED++);
      RTCSLOG_PCB_FREE(pcb_ptr, RTCS_OK);
      RTCSPCB_free(pcb_ptr);
      return;

   /*
   ** Otherwise, enqueue the packet
   */
   } else {

      RTCS_QUEUE_INS(ucb_ptr->PHEAD, ucb_ptr->PTAIL, pcb_ptr);
      ucb_ptr->PCOUNT++;

      /*
      ** Notify socket layer in case some task is blocked on select()
      ** waiting for this data.
      */
      SOCK_select_signal(ucb_ptr->SOCKET, UDP_SOCKET_ENQUEUED);
   } /* Endif */

} /* Endbody */
#endif

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_close
* Parameters      :
*
*     UCB_STRUCT_PTR    ucb         [IN] UCB
*    _CODE_PTR_         udpservice  not used
*     _ip_address       ipaddress   not used
*     uint_16           udpport     not used
*     uint_16           udpflags    not used
*     pointer           udpptr      not used
*     uint_32           udpword     not used
*
* Comments        :
*     Closes a UCB.
*
*END*-----------------------------------------------------------------*/

void UDP_close
   (
      UDP_PARM_PTR      parms
   )
{ /* Body */
   UDP_CFG_STRUCT_PTR   UDP_cfg_ptr;
   UCB_STRUCT_PTR       ucb, _PTR_ tmp;
   UCB_STRUCT_PTR _PTR_ search_ptr;       /* Temporary UCB pointer */
   UDP_PARM_PTR         req, nextreq;     /* Temporary request pointers */
   RTCSPCB_PTR          pcb, nextpcb;     /* Temporary packet pointers */
   uint_32              error;


   UDP_cfg_ptr = RTCS_getcfg(UDP);
   ucb = parms->ucb;

   /*
   ** Remove the UCB from the chain of UCBs
   */
   if (!ucb->PORT) {
      tmp = &(UDP_cfg_ptr->GROUND_UCB_HEAD);
   } else if (!ucb->REMOTE_HOST) {
      if (ucb->IPADDR) {
         tmp = &(UDP_cfg_ptr->LBOUND_UCB_HEAD);
      } else {
         tmp = &(UDP_cfg_ptr->BOUND_UCB_HEAD);
      } /* Endif */
   } else {
      tmp = &(UDP_cfg_ptr->OPEN_UCB_HEAD);
   } /* Endif */

   RTCS_LIST_SEARCHMOD(*tmp, search_ptr) {
      if (*search_ptr == ucb) {
         break;
      } /* Endif */
   } /* End SEARCH */

   if (!*search_ptr) {
      RTCSCMD_complete(parms, RTCSERR_UDP_UCB_CLOSE);
      return;
   } /* Endif */

   RTCS_LIST_DEL(tmp, search_ptr);

   /*
   ** Free all queued packets
   */
   RTCS_QUEUE_DELALL(ucb->PHEAD, ucb->PTAIL, pcb, nextpcb) {
      RTCSLOG_PCB_FREE(pcb, RTCS_OK);
      RTCSPCB_free(pcb);
   } /* End DELALL */

   /*
   ** Release pending receive requests from host
   */
   RTCS_QUEUE_DELALL(ucb->RHEAD, ucb->RTAIL, req, nextreq) {
      RTCSCMD_complete(req, RTCSERR_READ_ABORTED);
   } /* End DELALL */

   /*
   ** Notify socket layer in case some task is blocked on select()
   ** waiting for data on this socket.
   */
   SOCK_select_signal(ucb->SOCKET, UDP_SOCKET_CLOSE);


   /*
   ** Leave all joined multicast groups
   */
   if (ucb->IGMP_LEAVEALL) {
      ucb->IGMP_LEAVEALL(&ucb->MCB_PTR);
   } /* Endif */

   /*
   ** Free the UCB memory
   */
   error = _mem_free(ucb);
   if (error) {
      RTCSCMD_complete(parms, RTCSERR_UDP_UCB_FREE);
      return;
   } /* Endif */

   RTCSCMD_complete(parms, RTCS_OK);
   return;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : UDP_source
* Returned Value  : source UDP port
* Comments        :
*     Return source UDP port of packet.
*
*END*-----------------------------------------------------------------*/

uint_16 UDP_source
   (
      RTCSPCB_PTR    pcb      /* [IN] packet to find source of */
   )
{ /* Body */
   uchar_ptr srcptr = ((UDP_HEADER_PTR)RTCSPCB_DATA_TRANSPORT(pcb))->SRC_PORT;

   return ntohs(srcptr);

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sai/sai_ksai.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sai_ksai.h$
* $Version : 3.8.4.0$
* $Date    : Sep-11-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the SAI driver
*
*END************************************************************************/

#ifndef __SAI_KSAI_H__
#define __SAI_KSAI_H__

#include "sai_audio.h"

#if !PSP_MQX_CPU_IS_VYBRID
#include <cm_kinetis.h>
#else
#include <cm_vybrid.h>
#endif
/*
** Constants
*/

/* Maximum value  that can be stored in 16 bit long variable */
#define BIT16_MAX 32767

/*
** Types declaration
*/ 
#ifdef __cplusplus
extern "C" 
{
#endif

typedef struct ki2s_init_struct
{
    /* Selected SAI HW module */
    uint_8 HW_CHANNEL;
        
    /* The SAI TX channel to initialize */
    uint_8 TX_CHANNEL;
    
    /* The SAI RX channel to initialize */
    uint_8 RX_CHANNEL;
    
    /* Clock setup: sync-async; bitclock: normal-swapped */
    uint_8 CLOCK_MODE;

    /* Default operating mode */
    uint_8 MODE;

    /* Number of valid data bits*/
    uint_8 DATA_BITS;

    /* I2S master clock source*/
    uint_8 CLOCK_SOURCE;

    /* Transmit dummy data */
    boolean TX_DUMMY;

    /* Interrupt level to use */
    _mqx_uint LEVEL;

    /* Tx buffer size */
    uint_32 BUFFER_SIZE;
    
    /* Internal master clock source */
    CM_CLOCK_SOURCE MCLK_SRC;
    
    /* I/O data format */
    AUDIO_DATA_FORMAT const * IO_FORMAT;

} KSAI_INIT_STRUCT, _PTR_ KSAI_INIT_STRUCT_PTR;

typedef const KSAI_INIT_STRUCT _PTR_ KSAI_INIT_STRUCT_CPTR;

/*
** Global functions
*/

_mqx_int _ksai_int_init(pointer);
_mqx_int _ksai_int_deinit(pointer, pointer);    
_mqx_int _ksai_int_tx(pointer, char_ptr, uint_32);
_mqx_int _ksai_int_rx(pointer, char_ptr, uint_32);
_mqx_int _ksai_int_ioctl(pointer, _mqx_int, pointer);

pointer _bsp_get_sai_base_address(uint_8);
uint_32 _bsp_get_sai_tx_vector(uint_8);
uint_32 _bsp_get_sai_rx_vector(uint_8);
    
#ifdef __cplusplus
}
#endif

#endif /* __SAI_KSAI_H__ */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/macnet/macnet_vybrid.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: macnet_vybrid.h$
* $Version : 3.8.2.0$
* $Date    : Sep-20-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the ethernet drivers for the mk60 processor
*
*END************************************************************************/
#ifndef _macnet_faraday_h
#define _macnet_faraday_h

#define MACNET_DEVICE_0                0
#define MACNET_DEVICE_1                1

#define MACNET_DEVICE_COUNT            2
   
#define MACNET_RX_BUFFER_ALIGNMENT     16  
#define MACNET_TX_BUFFER_ALIGNMENT     16
#define MACNET_BD_ALIGNMENT            16

/* Needs to be here, because a SMALL packet must be a multiple of the RX_BUFFER_ALIGNMENT */
#define MACNET_SMALL_PACKET_SIZE           ENET_ALIGN(64, MACNET_RX_BUFFER_ALIGNMENT)
       
/* MACNET 1588 TIMER the precise 1588timebase is linked to */
#define MACNET_PTP_TIMER  2 

/* EXTAL is used for clocking the 1588 timer */
#define MACNET_1588_CLOCK_SRC (BSP_CLOCK_SRC)

/* Value of the Timer Period Register - should be initialized to 1000000000
   to represent a timer wrap around of one second */
#define MACNET_1588_ATPER_VALUE (1000000000)

/* 1588 timer increment */
#define MACNET_1588_CLOCK_INC (MACNET_1588_ATPER_VALUE / (MACNET_1588_CLOCK_SRC))

#endif /* _macnet_faraday_h */



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/iplocal.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iplocal.c$
* $Version : 3.8.20.0$
* $Date    : Oct-2-2012$
*
* Comments:
*
*   This file contains the interface between IP and
*   the local host.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "icmp_prv.h"


/*
** The structure used by the application to bind an IP address
** to an Ethernet packet driver.
*/

static const RTCS_IF_STRUCT rtcs_local =
{
    IPLOCAL_open,
    IPLOCAL_close
#if RTCSCFG_ENABLE_IP4    
    ,
    IPLOCAL_send
#if RTCSCFG_ENABLE_IGMP 
    ,
    NULL,
    NULL
#endif
#endif /* RTCSCFG_ENABLE_IP4 */

#if RTCSCFG_ENABLE_IP6
    ,
    IP6LOCAL_send,   /* SEND6 */
    NULL,            /* JOIN6 */
    NULL             /* LEAVE6 */
#endif
};

const RTCS_IF_STRUCT_PTR RTCS_IF_LOCALHOST = (RTCS_IF_STRUCT_PTR)&rtcs_local;

IP_IF_PTR   RTCS_IF_LOCALHOST_PRV = 0;  /* the local host interface */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : IP_open
* Returned Value  : ICB_STRUCT_PTR
* Comments        :
*     Registers a transport protocol with IP.
*
*END*-----------------------------------------------------------------*/

ICB_STRUCT_PTR IP_open
   (
      uchar             protocol,   /* [IN]  Protocol to use */
      IP_SERVICE_FN     service,    /* [IN]  Packet receive function */
      pointer           private,    /* [IN]  Owner's config block */
      uint_32_ptr       status      /* [OUT] return code */
   )
{ /* Body */
 
#if RTCSCFG_ENABLE_IP4  
 
   IP_CFG_STRUCT_PTR    IP_cfg_ptr;
   ICB_STRUCT_PTR icb, search_ptr;

   IP_cfg_ptr = RTCS_getcfg(IP);

   /* Make sure the protocol isn't already is use */
   RTCS_LIST_SEARCH(IP_cfg_ptr->ICB_HEAD, search_ptr) {
      if (search_ptr->PROTOCOL == protocol) {
         *status = RTCSERR_IP_PROT_OPEN;
         return NULL;
      } /* Endif */
   } /* End SEARCH */

   icb = RTCS_mem_alloc(sizeof(ICB_STRUCT));
   if (!icb) {
      *status = RTCSERR_IP_ICB_ALLOC;
      return NULL;
   } /* Endif */

   _mem_set_type(icb, MEM_TYPE_ICB);

   icb->PROTOCOL = protocol & 0xFF;
   icb->SERVICE  = service;
   icb->PRIVATE  = private;

   /*
   ** Add the record into the chain of open ICBs
   */
   RTCS_LIST_INS(IP_cfg_ptr->ICB_HEAD, icb);

   /*
   ** Open new ICB succeeded
   */
   *status = RTCS_OK;
   return icb;

#else

    *status = RTCSERR_IP_IS_DISABLED;
    return NULL;

#endif /* RTCSCFG_ENABLE_IP4 */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPLOCAL_open
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Registers the local host as an IP interface.
*
*END*-----------------------------------------------------------------*/

uint_32 IPLOCAL_open
   (
      IP_IF_PTR   if_ptr
         /* [IN] the IP interface structure */
   )
{ /* Body */
    uint_32 error = RTCS_OK;
    if_ptr->MTU = IP_MAX_MTU;
    if_ptr->ARP = NULL;

    if_ptr->DEV_TYPE     = 0;
    if_ptr->DEV_ADDRLEN  = 0;
#if RTCSCFG_ENABLE_SNMP && RTCSCFG_ENABLE_IP4
    if_ptr->SNMP_IF_TYPE = IPIFTYPE_LOOPBACK;
#endif


/* parms.ihandle set by IPIF_add() */ //PFI Move to IPLOCAL_open()
#if RTCSCFG_ENABLE_LOOPBACK && RTCSCFG_ENABLE_IP4
    /* Create the localhost route entry */
    error = IP_route_add_direct(INADDR_LOOPBACK, IN_CLASSA_NET, if_ptr, if_ptr);

    if (error)
    {
        return error;
    }

    #if RTCSCFG_ENABLE_IGMP 
       /* IGMP_ipif_bind failure isn't sufficient reason to abort */
       IGMP_ipif_bind(if_ptr, INADDR_LOOPBACK);
    #endif
#endif 



#if RTCSCFG_ENABLE_IP6
    IP6LOCAL_open (if_ptr);
#endif    

    return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPLOCAL_close
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Unregisters the local host as an IP interface.
*
*END*-----------------------------------------------------------------*/

uint_32 IPLOCAL_close
   (
      IP_IF_PTR   if_ptr
         /* [IN] the IP interface structure */
   )
{ /* Body */

   return RTCS_OK;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPLOCAL_send
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Sends a packet.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4  

uint_32 IPLOCAL_send
   (
      IP_IF_PTR      if_ptr,
         /* [IN] the IP interface structure */
      RTCSPCB_PTR    rtcs_pcb,
         /* [IN] the packet to send */
      _ip_address    src,
         /* [IN] the next-hop source address */
      _ip_address    dest,
         /* [IN] the next-hop destination address */
      pointer        data
         /* [IN] unused */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR    IP_cfg_ptr = RTCS_getcfg(IP);
   IP_HEADER_PTR        iph = (IP_HEADER_PTR)RTCSPCB_DATA(rtcs_pcb);
   uint_32 error;

   RTCSLOG_FNE4(RTCSLOG_FN_IPLOCAL_send, if_ptr, rtcs_pcb, src);
   
   /*
   ** ST_RX_TOTAL is incremented in IP_service(), which catches
   ** all packets except those which arrived through the loopback
   ** interface.  Those are caught here.
   **
   ** Additionally, those packets that arrive by loopback are
   ** enqueued back onto the TCPIP task's message queue to
   ** prevent the task's stack requirements from getting too
   ** large (this is mainly for TCP loopback).
   */
   if (rtcs_pcb->IFSRC == RTCS_IF_LOCALHOST_PRV) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_TOTAL++);

      if (!RTCSCMD_service(rtcs_pcb, IPLOCAL_service)) {
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_MISSED++);
         RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_OUT_OF_BUFFERS);
         RTCSPCB_free(rtcs_pcb);
         
         RTCSLOG_FNX2(RTCSLOG_FN_IPLOCAL_send, RTCSERR_OUT_OF_BUFFERS);
         return RTCSERR_OUT_OF_BUFFERS;
      } /* Endif */

      error = RTCS_OK;
   } else {
      /* If it is a fragmented packet, reassemble it */
      if (ntohs(iph->FRAGMENT) & (IP_FRAG_MF | IP_FRAG_MASK)) {
#if RTCSCFG_ENABLE_IP_REASSEMBLY
         error = IP_reasm(rtcs_pcb, &rtcs_pcb);
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_FRAG_RECVD++);
         if (rtcs_pcb) {
            IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_FRAG_REASMD++);
#if RTCSCFG_ENABLE_IPSEC
            if (IP_cfg_ptr->SEC_SEND_FN) {
               error = IP_cfg_ptr->SEC_SERVICE_FN(IP_cfg_ptr->SEC_FN_ARG,
                  if_ptr, &rtcs_pcb, src, dest);
               if (error) {
                  RTCSLOG_PCB_FREE(rtcs_pcb, error);
                  RTCSPCB_free(rtcs_pcb);
                  
                  RTCSLOG_FNX2(RTCSLOG_FN_IPLOCAL_send, error);
                  return error;
               } /* Endif */
            } /* Endif */
#endif
         } else {
            if (error) {
               IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_FRAG_DISCARDED++);
            } /* Endif */
            
            RTCSLOG_FNX2(RTCSLOG_FN_IPLOCAL_send, error);
            return error;
         } /* Endif */
#else
         IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_FRAG_DISCARDED++);
         RTCSLOG_PCB_FREE(rtcs_pcb, RTCSERR_FEATURE_NOT_ENABLED);
         RTCSPCB_free(rtcs_pcb);
         
         RTCSLOG_FNX2(RTCSLOG_FN_IPLOCAL_send, RTCSERR_FEATURE_NOT_ENABLED);
         return RTCSERR_FEATURE_NOT_ENABLED;

#endif
      } /* Endif */

      /* If not, don't wait and forward it to the upper layer */
      
      error = IPLOCAL_service(rtcs_pcb);
   } /* Endif */

   RTCSLOG_FNX2(RTCSLOG_FN_IPLOCAL_send, error);
   return error;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPLOCAL_service
*  Returned Value : RTCS_OK or error code
*  Comments       :
*        Delivers a packet to the loopback interface.
*
*END*-----------------------------------------------------------------*/

#if RTCSCFG_ENABLE_IP4 

uint_32 IPLOCAL_service
   (
      RTCSPCB_PTR    rtcs_pcb
         /* [IN] the packet to deliver */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR    IP_cfg_ptr;
   ICB_STRUCT_PTR       search_ptr;
   uchar                hdrlen;
   uchar                protocol;
   uint_32              error;
   
   RTCSLOG_FNE2(RTCSLOG_FN_IPLOCAL_service, rtcs_pcb);

   IP_cfg_ptr = RTCS_getcfg(IP);

   /* Find an ICB for the received packet's protocol */
   protocol = RTCSPCB_TRANSPORT_PROTL(rtcs_pcb);
   RTCS_LIST_SEARCH(IP_cfg_ptr->ICB_HEAD, search_ptr) {
      if (search_ptr->PROTOCOL == protocol) {
         break;
      } /* Endif */
   } /* End SEARCH */

   if (!search_ptr) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_NO_PROTO++);
      #if RTCSCFG_ENABLE_ICMP
      ICMP_send_error(ICMPTYPE_DESTUNREACH, ICMPCODE_DU_PROTO_UNREACH, 0, rtcs_pcb, 0);
      #endif
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
      RTCSPCB_free(rtcs_pcb);
      
      RTCSLOG_FNX2(RTCSLOG_FN_IPLOCAL_service, RTCS_OK);
      return RTCS_OK;
   } /* Endif */

   hdrlen = RTCSPCB_TRANSPORT_DELTA(rtcs_pcb);
   error = RTCSPCB_next(rtcs_pcb, hdrlen);
   if (error) {
      IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.COMMON.ST_RX_ERRORS++);
      IF_IP_STATS_ENABLED(RTCS_seterror(&IP_cfg_ptr->STATS.ERR_RX, error, (uint_32)rtcs_pcb));
      RTCSLOG_PCB_FREE(rtcs_pcb, error);
      RTCSPCB_free(rtcs_pcb);
      
      RTCSLOG_FNX2(RTCSLOG_FN_IPLOCAL_service, error);
      return error;
   } /* Endif */

   IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_DELIVERED++);
   search_ptr->SERVICE(rtcs_pcb, search_ptr->PRIVATE);
   
   RTCSLOG_FNX2(RTCSLOG_FN_IPLOCAL_service, RTCS_OK);
   return RTCS_OK;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/************************************************************************
* NAME: IPLOCAL_init
*
* DESCRIPTION: Adds LOCALHOST interface.
*************************************************************************/
uint_32 IPLOCAL_init (void)
{
   uint_32           error;
   IPIF_PARM         parms;
   
   parms.mhandle = NULL;
   parms.if_ptr  = RTCS_IF_LOCALHOST;
   error = RTCSCMD_internal(parms, IPIF_add);
   if (error) {
      return error;
   } /* Endif */
   
   RTCS_IF_LOCALHOST_PRV = parms.ihandle;
   
   return RTCS_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/int_kisr.c<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: int_kisr.c$
* $Version : 3.7.4.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the function for installing a kernel level isr.
*
*END************************************************************************/

#include "mqx_inc.h"

/*!
 * \brief Installs the kernel ISR handler. The kernel ISR depends on the PSP.
 *
 * Some real-time applications need special event handling to occur outside the
 * scope of MQX. The need might arise that the latency in servicing an interrupt
 * be less than the MQX interrupt latency. If this is the case, an application can
 * use _int_install_kernel_isr() to bypass MQX and let the interrupt be serviced
 * immediately.
 * \n Because the function returns the previous kernel ISR, applications can
 * temporarily install an ISR or chain ISRs so that each new one calls the one
 * installed before it.
 * \n A kernel ISR must save the registers that it needs and must service the
 * hardware interrupt. When the kernel ISR is finished, it must restore the
 * registers and perform a return-from-interrupt instruction.
 * \n A kernel ISR cannot call MQX functions. However, it can put data in global
 * data, which a task can access.
 *
 * \note The function is not available for all PSPs.
 *
 * \param[in] vector  Vector where the ISR is to be installed.
 * \param[in] isr_ptr Pointer to the ISR to install into the vector table.
 *
 * \return Pointer to the previous kernel ISR for the vector (Success.).
 * \return NULL
 *
 * \see _int_kernel_isr
 * \see _int_get_kernel_isr
 */
INT_KERNEL_ISR_FPTR _int_install_kernel_isr
(
    uint_32             vector,
    INT_KERNEL_ISR_FPTR isr_ptr
)
{
#if !MQX_ROM_VECTORS

#if MQX_KERNEL_LOGGING
   KERNEL_DATA_STRUCT_PTR kernel_data;
#endif
   INT_KERNEL_ISR_FPTR    old_isr_ptr;
   uint_32                result_code;
   uint_32_ptr            loc_ptr;

#if MQX_KERNEL_LOGGING
   _GET_KERNEL_DATA(kernel_data);
#endif

   _KLOGE3(KLOG_int_install_kernel_isr, vector, isr_ptr);

#if MQX_CHECK_ERRORS
   result_code = MQX_OK;
   old_isr_ptr = NULL;

   if ( vector >= PSP_MAXIMUM_INTERRUPT_VECTORS ) {
      result_code = MQX_INVALID_VECTORED_INTERRUPT;
   } else {
#endif

   loc_ptr = (uint_32_ptr)_int_get_vector_table();
   old_isr_ptr = (INT_KERNEL_ISR_FPTR)loc_ptr[vector];
   loc_ptr[vector] = (uint_32)isr_ptr;

#if MQX_CHECK_ERRORS
   } /* Endif */

   /* Set result code and return result. */
   _task_set_error(result_code);
#endif

   _KLOGX3(KLOG_int_install_kernel_isr, old_isr_ptr, result_code);
   return (old_isr_ptr);
#else

#if MQX_CHECK_ERRORS
   /* Set result code and return result. */
   _task_set_error(MQX_INVALID_CONFIGURATION);
#endif

   return NULL;
#endif
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/istrata/istrata.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: istrata.c$
* $Version : 3.8.14.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions to program Intel's StrataFlash 
*   devices
*   While this driver is generic to Intel's StrataFlash family of
*   products it has only been tested on the following parts:
*   28F128J3A
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "istrata.h"
#include "istrataprv.h"

#define LOCK    1
#define UNLOCK  0
#define BYTES_IN_WORD    2
#define BYTES_IN_DWORD   4

const FLASHX_DEVICE_IF_STRUCT _intel_strata_if = {
    _intel_strata_erase,
    _intel_strata_program,
    NULL,
    NULL,
    _intel_strata_init,
    NULL,
    _intel_strata_write_protect,
    _io_intel_strata_ioctl
};

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_program
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs a sector of flash
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_program
   (  
      /* [IN] device handle */
      IO_FLASHX_STRUCT_PTR  dev_ptr,

      /* [IN] where to copy data from */
      char_ptr              from_ptr,
      
      /* [OUT} where to copy data to */
      char_ptr              to_ptr,

      /* [IN] the sector size to copy */
      _mem_size             sector_size
   )
{ /* Body */
   _mqx_uint   total_width;
   _mqx_uint   i = 0;
   boolean     program = FALSE;
   boolean     result;
   _mqx_uint   write_protect = TRUE;
   _mqx_uint_ptr write_protect_ptr = &write_protect;
   uint_32     temp_data = 0xFFFFFFFF;
   uint_8_ptr  temp_data_ptr;
   uint_8      byte_data_counter = 0;
   
   temp_data_ptr = (uint_8_ptr)&temp_data;
   
   total_width = dev_ptr->DEVICES * dev_ptr->WIDTH;

   /* First make sure we actually need to program the sector */
   if (total_width == 1) {
      uint_8_ptr  from8_ptr = (uint_8_ptr)((pointer)from_ptr);
      uint_8_ptr  to8_ptr   = (uint_8_ptr)((pointer)to_ptr);

      while( !program && (i < sector_size) ) {
         program = *from8_ptr++ != *to8_ptr++;
         i++;
      } /* Endwhile */

      i--;
   } else if (total_width == 2) {
      uint_16_ptr  from16_ptr = (uint_16_ptr)((pointer)from_ptr);
      uint_16_ptr  to16_ptr   = (uint_16_ptr)((pointer)to_ptr);

      while( !program && (i < sector_size) ) {
         program = *from16_ptr++ != *to16_ptr++;
         i += 2;
      } /* Endwhile */

      i -= 2;
   } else if (total_width == 4) {
      uint_32_ptr  from32_ptr = (uint_32_ptr)((pointer)from_ptr);
      uint_32_ptr  to32_ptr   = (uint_32_ptr)((pointer)to_ptr);

      while( !program && (i < sector_size) ) {
         program = *from32_ptr++ != *to32_ptr++;
         i += 4;
      } /* Endwhile */

      i -= 4;
   } else {
      /* Unsupported configuration */
      return FALSE;
   } /* Endif */

   if (!program) {
      return !program;
   } /* Endif */

   /* get the flash write protect status */
   _io_intel_strata_ioctl(dev_ptr, FLASH_IOCTL_GET_WRITE_PROTECT, write_protect_ptr); 
   /* if the flash is write protect, return */
   if(write_protect){
      return(FALSE);
   }

   switch (dev_ptr->WIDTH) {
      case 1:
         result = _intel_strata_program_1byte(dev_ptr, from_ptr, to_ptr, sector_size, i);
         break;
      case 2:
         if((uint_32)to_ptr & 0x01){
            to_ptr -= 0x01;
            byte_data_counter = 0x01;
            *temp_data_ptr = *to_ptr;
         
            while(sector_size) {            
               while( byte_data_counter < BYTES_IN_WORD && sector_size ){
                  *(uchar_ptr)(temp_data_ptr+byte_data_counter) = *from_ptr++;
                  byte_data_counter++;
                  sector_size--;
               }
               byte_data_counter = 0;
               
               result = _intel_strata_program_2byte(dev_ptr, (uint_16_ptr)temp_data_ptr,
                  (uint_16_ptr)to_ptr, 2, i);
               if(FALSE == result)
                  return result;
               if(i >> 1)
                  i += 2;
               temp_data = 0xFFFFFFFF;
               to_ptr += 2;
            }
         }
         else if(sector_size & 0x01){
            sector_size++;
            result = _intel_strata_program_2byte(dev_ptr, (uint_16_ptr)from_ptr,
                  (uint_16_ptr)to_ptr, sector_size, i);
         }
         else
            result = _intel_strata_program_2byte(dev_ptr, (uint_16_ptr)from_ptr,
               (uint_16_ptr)to_ptr, sector_size, i);
         break;
      case 4:
         if((uint_32)to_ptr & 0x03){
            to_ptr -= (uint_32)to_ptr & 0x03;
            byte_data_counter = (uint_32)to_ptr & 0x03;
            *temp_data_ptr = *to_ptr;
         
            while(sector_size) {            
               while( byte_data_counter < BYTES_IN_DWORD && sector_size ){
                  *(uchar_ptr)(temp_data_ptr+byte_data_counter) = *from_ptr++;
                  byte_data_counter++;
                  sector_size--;
               }
               byte_data_counter = 0;
               
               result = _intel_strata_program_4byte(dev_ptr, (uint_32_ptr)temp_data_ptr,
                  (uint_32_ptr)to_ptr, 4, i);
               if(FALSE == result)
                  return result;
               if(i >> 1)
                  i += 4;
               temp_data = 0xFFFFFFFF;
               to_ptr += 4;
            }
         }
         else if(sector_size & 0x01){
            sector_size++;
            result = _intel_strata_program_4byte(dev_ptr, (uint_32_ptr)from_ptr,
                  (uint_32_ptr)to_ptr, sector_size, i);
         }
         else
            result = _intel_strata_program_4byte(dev_ptr, (uint_32_ptr)from_ptr,
               (uint_32_ptr)to_ptr, sector_size, i);
         break;
   } /* Endswitch */

   return result;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases a sector of flash
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_erase
   (  
      /* [IN] device info */
      IO_FLASHX_STRUCT_PTR  dev_ptr,

      /* [IN] the sector to erase */
      char_ptr             input_sect_ptr,
      
      /* [IN] the number of bytes to erase */
      _mem_size            bytes
   )
{ /* Body */
   _mqx_uint  total_width;
   _mqx_uint  i = 0;
   boolean    result = TRUE;
   boolean    erase = FALSE;
   MQX_TICK_STRUCT  tmp_ticks;
   _mqx_uint  write_protect = TRUE;
   _mqx_uint_ptr write_protect_ptr = &write_protect;

#if 0   
   if (dev_ptr->WRITE_PROTECT) {
      (*dev_ptr->WRITE_PROTECT)(dev_ptr, FALSE);
   }/* Endif */
#endif

   /* get the flash write protect status */
   _io_intel_strata_ioctl(dev_ptr, FLASH_IOCTL_GET_WRITE_PROTECT, write_protect_ptr); 
   /* if the flash is write protect, return */
   if(write_protect){
      return(FALSE);
   }

   total_width = dev_ptr->DEVICES * dev_ptr->WIDTH;

   /* First make sure we actually need to erase the sector */
   if (total_width == 1) {
      uint_8_ptr  to8_ptr   = (uint_8_ptr)((pointer)input_sect_ptr);

      while( !erase && (i < bytes) ) {
         erase = 0xff != *to8_ptr++;
         i++;
      } /* Endwhile */

   } else if (total_width == 2) {
      uint_16_ptr  to16_ptr   = (uint_16_ptr)((pointer)input_sect_ptr);

      while( !erase && (i < bytes) ) {
         erase = 0xffff != *to16_ptr++;
         i += 2;
      } /* Endwhile */

   } else if (total_width == 4) {
      uint_32_ptr  to32_ptr   = (uint_32_ptr)((pointer)input_sect_ptr);

      while( !erase && (i < bytes) ) {
         erase = 0xffffffff != *to32_ptr++;
         i += 4;
      } /* Endwhile */

   } else {
      /* Unsupported configuration */
      return FALSE;
   } /* Endif */

   if (!erase) {
      return !erase;
   } /* Endif */

   switch (dev_ptr->WIDTH) {
      case 1:
         result = _intel_strata_erase_1byte(dev_ptr, input_sect_ptr, 
            bytes, &tmp_ticks);
         break;
      case 2:
         result = _intel_strata_erase_2byte(dev_ptr, (uint_16_ptr)input_sect_ptr,
            bytes, &tmp_ticks);
         break;
      case 4:
         result = _intel_strata_erase_4byte(dev_ptr, (uint_32_ptr)input_sect_ptr,
            bytes, &tmp_ticks);
         break;
   } /* Endswitch */

   return result;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_check_timeout
* Returned Value   : TRUE if timeout occurs
* Comments         : 
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_check_timeout
   (  
      /* [IN] Time operation started in ticks */
      MQX_TICK_STRUCT_PTR   start_tick_ptr,

      /* [IN] The number of ticks the operation is expected to take */
      _mqx_uint             period
   )
{ /* Body */
   MQX_TICK_STRUCT  end_ticks;
   MQX_TICK_STRUCT  current_ticks;
   _mqx_int         result;

   PSP_ADD_TICKS_TO_TICK_STRUCT(start_tick_ptr, period, &end_ticks);
   _time_get_elapsed_ticks(&current_ticks);

   result = PSP_CMP_TICKS(&current_ticks, &end_ticks);

   if (result >= 0) {
      return TRUE;
   } else {
      return FALSE;
   } /* Endif */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_test_lock_bits
* Returned Value   : TRUE if locked
* Comments         : 
*
*   This function test, if the flash is locked  
*END*----------------------------------------------------------------------*/
static boolean _intel_strata_test_lock_bits
    (
        /* [IN] device handle */
      IO_FLASHX_STRUCT_PTR  dev_ptr
    ) 
{
    uint_32 block_size;
    uint_32 num_blocks;
    volatile uchar _PTR_    dest_ptr;
    int i = 0;
    uchar   status;
    
    num_blocks = dev_ptr->HW_BLOCK->NUM_SECTORS; /* sector == block */
    block_size = dev_ptr->HW_BLOCK->SECTOR_SIZE;
    /* test all sectors for lock */ 
    for(i = 0; i < num_blocks; i++) {
        /* set block address */
        dest_ptr = (volatile uchar _PTR_)(dev_ptr->BASE_ADDR + dev_ptr->HW_BLOCK[0].START_ADDR + i * block_size);
        /* return in status block-bit value 0- unlock, 1- locked */ 
        ISTRATA_READ_LOCK_STATUS(ISTRATA_READ_MODE_CMD_8X1, ISTRATA_READ_ID_MODE_CMD_16X1, ISTRATA_STATUS_BUSY_8X1);
        /* is some sector locked? */
        if(status & 0x01){
            /* yes, some sector is locked */
            return TRUE;
        }
    }
    return FALSE;
}
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_write_protect
* Returned Value   : TRUE if successful
* Comments         : 
*    This function sets or clears the lock bits on all sectors
*    lock = 1 - device is to be write protect, 0 - allow writing device
* 
*END*----------------------------------------------------------------------*/
boolean _intel_strata_write_protect
    (
        /* [IN] the device handle */
      IO_FLASHX_STRUCT_PTR  dev_ptr,
      
      /* [IN]  */
      _mqx_uint             lock
    ) 
{
    boolean result = TRUE;
    
    /* set the lock bits */
    if(lock == LOCK){
        result = _intel_strata_set_lock_bits(dev_ptr);   
    }
    /* clear lock bits */   
    else{
        /* is the flash locked? */
        if(_intel_strata_test_lock_bits(dev_ptr)){
            /* unlock */
            result = _intel_strata_clear_lock_bits(dev_ptr);
        }
    }
    return(result);
}

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_clear_lock_bits
* Returned Value   : TRUE if successful
* Comments         : 
*    This function clears the lock bits on all sectors
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_clear_lock_bits
   (  
      /* [IN] the device handle */
      IO_FLASHX_STRUCT_PTR  dev_ptr
   )
{ /* Body */
   boolean          result;
   MQX_TICK_STRUCT  start_ticks;

   switch (dev_ptr->WIDTH) {
      case 1:
         result = _intel_strata_clearlockbits_1byte(dev_ptr, &start_ticks);
         break;
      case 2:
         result = _intel_strata_clearlockbits_2byte(dev_ptr, &start_ticks);
         break;
      case 4:
         result = _intel_strata_clearlockbits_4byte(dev_ptr, &start_ticks);
         break;
   } /* Endswitch */

   return result;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_set_lock_bits
* Returned Value   : TRUE if successful
* Comments         : 
*    This function sets the lock bits on all sectors
* 
*END*----------------------------------------------------------------------*/

boolean _intel_strata_set_lock_bits
   (  
      /* [IN] the device handle */
      IO_FLASHX_STRUCT_PTR  dev_ptr
   )
{ /* Body */
   boolean          result;
   MQX_TICK_STRUCT  start_ticks;

   switch (dev_ptr->WIDTH) {
      case 1:
         result = _intel_strata_setlockbits_1byte(dev_ptr, &start_ticks);
         break;
      case 2:
         result = _intel_strata_setlockbits_2byte(dev_ptr, &start_ticks);
         break;
      case 4:
         result = _intel_strata_setlockbits_4byte(dev_ptr, &start_ticks);
         break;
   } /* Endswitch */

   return result;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_intel_strata_ioctl
* Returned Value   : TRUE if successful
* Comments         : 
*    flash ioctl function
* 
*END*----------------------------------------------------------------------*/
_mqx_int _io_intel_strata_ioctl
   (
      /* [IN] the handle returned from _fopen */
      IO_FLASHX_STRUCT_PTR   dev_ptr,

      /* [IN] the ioctl command */
      _mqx_uint              cmd,

      /* [IN] the ioctl parameters */
      pointer                param_ptr
   )
{ /* Body */
    _mqx_uint                       result = MQX_OK;
    switch(cmd) {
        case FLASH_IOCTL_GET_WRITE_PROTECT:
            /* is the flash locked ? */
            if (_intel_strata_test_lock_bits(dev_ptr)) {
                *((boolean _PTR_)param_ptr) = TRUE;
            } else {
                *((boolean _PTR_)param_ptr) = FALSE;
            }
            break;
        default:
            break;
    }
    return result;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _intel_strata_init
* Returned Value   : TRUE if successful
* Comments         : 
*    This function initializes intel strata flash
* 
*END*----------------------------------------------------------------------*/
boolean _intel_strata_init
(
    /* [IN] File pointer */
    IO_FLASHX_STRUCT_PTR dev_ptr
)
{
    if (_intel_strata_test_lock_bits(dev_ptr))
        return _intel_strata_clear_lock_bits(dev_ptr);

    return TRUE;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_cluster.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_cluster.c$
* $Version : 3.8.19.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   This file contains the functions that are used to be used on clusters.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"

#if !MFSCFG_READ_ONLY


void MFS_Increment_free_clusters(MFS_DRIVE_STRUCT_PTR drive_ptr)
{
#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return;
    }
#endif
    if ( drive_ptr->FREE_COUNT != FSI_UNKNOWN )
    {
        drive_ptr->FREE_COUNT++;
    }
}

void MFS_Decrement_free_clusters(MFS_DRIVE_STRUCT_PTR drive_ptr)
{
#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return;
    }
#endif
    if ( drive_ptr->FREE_COUNT != FSI_UNKNOWN )
    {
        drive_ptr->FREE_COUNT--;
    }
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Find_unused_cluster_from
* Returned Value   :  cluster_number, 0xffff means that none is available
* Comments  :
*      Get an unused cluster number. Assumes that the FAT has been read
*      Assumes drive SEM is locked.
*END*---------------------------------------------------------------------*/

uint_32 MFS_Find_unused_cluster_from
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,      /*[IN] the drive on which to operate */
    uint_32                 cluster_number  /*[IN] first cluster number to search */   
    )
{
    uint_32      max_clusters,cluster;
    _mfs_error   error_code;
    uint_32      cluster_status;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return CLUSTER_INVALID;
    }
#endif

    max_clusters = drive_ptr->LAST_CLUSTER;
    for ( cluster = cluster_number; cluster <= max_clusters; cluster++ )
    {
        error_code = MFS_get_cluster_from_fat(drive_ptr,cluster,&cluster_status);
        if ( error_code != MFS_NO_ERROR )
        {
            return(CLUSTER_INVALID);
        }
        else if ( cluster_status == CLUSTER_UNUSED )
        {
            drive_ptr->NEXT_FREE_CLUSTER = cluster;
            return(cluster);
        }
    }  

    for ( cluster = CLUSTER_MIN_GOOD; cluster < cluster_number; cluster++ )
    {
        error_code = MFS_get_cluster_from_fat(drive_ptr,cluster, &cluster_status);
        if ( error_code != MFS_NO_ERROR )
        {
            return(CLUSTER_INVALID);
        }
        else if ( cluster_status == CLUSTER_UNUSED )
        {
            drive_ptr->NEXT_FREE_CLUSTER = cluster;      
            return(cluster);
        }
    }  

    return(CLUSTER_INVALID);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Release_chain
* Returned Value   :  MFS error code
* Comments  :
*      Follow a chain of clusters and mark the entries as unused.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Release_chain
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,      /*[IN] the drive on which to operate */
    uint_32                 cluster_number  /*[IN] first cluster number to release */
    )
{
    uint_32    next_cluster,first_sector_in_cluster,last_sector_in_cluster;
    _mfs_error error_code;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    if ( (cluster_number >= CLUSTER_MIN_GOOD) && (cluster_number <= drive_ptr->LAST_CLUSTER) )
    {
        do
        {
            error_code = MFS_get_cluster_from_fat(drive_ptr,cluster_number,&next_cluster);
            if ( error_code != MFS_NO_ERROR )
            {
                break;
            }
            else if ( ((next_cluster > drive_ptr->LAST_CLUSTER) || (next_cluster < CLUSTER_MIN_GOOD)) && (next_cluster != CLUSTER_EOF) )
            {
                error_code = MFS_LOST_CHAIN;
                break;
            }

            first_sector_in_cluster = CLUSTER_TO_SECTOR(cluster_number);
            last_sector_in_cluster = first_sector_in_cluster+ drive_ptr->BPB.SECTORS_PER_CLUSTER -1;

            // Check to see if the currently cached data sector is being deleted.
            if ( (drive_ptr->DATA_SECTOR_NUMBER >= first_sector_in_cluster) && (drive_ptr->DATA_SECTOR_NUMBER <= last_sector_in_cluster) )
            {
                error_code = MFS_Invalidate_data_sector(drive_ptr);

                if ( error_code != MFS_NO_ERROR )
                {
                    return error_code;
                }
            }

            error_code = MFS_Put_fat(drive_ptr,cluster_number, CLUSTER_UNUSED);
            if ( error_code )
            {
                break;
            }
            cluster_number = next_cluster;
        } while ( cluster_number != CLUSTER_EOF );
        error_code = MFS_Write_back_fat(drive_ptr);
    }
    else
    {
        error_code = MFS_NO_ERROR;
    }  

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Extend_chain
* Returned Value   :  MFS error code
* Comments  :
*      Find a free cluster, follow a chain and add it to the chain.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Extend_chain
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,      /*[IN] the drive on which to operate */
    uint_32                 cluster_number, /*[IN] number of a cluster within the chain */
    uint_32                 num_clusters,   /*[IN] number of clusters to append to chain */   
    uint_32_ptr             added_cluster   /* [IN] pointer to the place where we should put the # of the first  new cluster. */
    )
{
    uint_32    next_cluster;
    uint_32    extended;
    _mfs_error error_code;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    if ( cluster_number < CLUSTER_MIN_GOOD || cluster_number > drive_ptr->LAST_CLUSTER )
    {
        return MFS_INVALID_CLUSTER_NUMBER;
    }

    if ( num_clusters <= 0 )
    {
        return MFS_NO_ERROR;
    }

    /* Find the end of the chain */
    next_cluster = cluster_number;
    do
    {
        cluster_number = next_cluster;
        error_code = MFS_get_cluster_from_fat(drive_ptr, cluster_number, &next_cluster);
        if ( error_code != MFS_NO_ERROR )
        {
            return error_code;
        }
        else if ( (next_cluster > drive_ptr->LAST_CLUSTER || next_cluster < CLUSTER_MIN_GOOD) && next_cluster != CLUSTER_EOF )
        {
            return MFS_LOST_CHAIN;
        }
    } while ( next_cluster != CLUSTER_EOF );

    extended = 0;

    while ( num_clusters )
    {
        /* Find a free cluster */
        next_cluster = MFS_Find_unused_cluster_from(drive_ptr, cluster_number+1);

        /* Check to see if the disk is not full */
        if ( next_cluster == CLUSTER_INVALID )
        {
            break; /* Condition handled after the loop */
        }

        /* Link the free cluster to the chain, at the end */
        error_code = MFS_Put_fat(drive_ptr, cluster_number, next_cluster);
        if ( error_code != MFS_NO_ERROR )
        {
            return error_code;
        }

        if ( extended==0 && added_cluster!=NULL )
        {
            *added_cluster = next_cluster;
        }

        extended++;
        cluster_number = next_cluster;
        num_clusters--;
    }

    /* If the chain was extended, write EOF to it's last link */
    if ( extended )
    {
        error_code = MFS_Put_fat(drive_ptr, cluster_number, CLUSTER_EOF);
    }

    if ( num_clusters && !error_code)
    {
        error_code = MFS_DISK_FULL;
    }

    return error_code;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Add_cluster_to_chain
* Returned Value   :  MFS error code
* Comments  :
*      Find a free cluster, follow a chain and add it to the chain.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Add_cluster_to_chain
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,      /*[IN] the drive on which to operate */
    uint_32                 cluster_number, /*[IN] number of a cluster within the chain */
    uint_32_ptr             added_cluster   /*[IN] pointer to the place where we should put the # of the new cluster. */
    )
{
    return MFS_Extend_chain(drive_ptr, cluster_number, 1, added_cluster);
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Clear_cluster
* Returned Value   :  MFS error code
* Comments  :
*     It resets all the bytes in a cluster to zero.
*END*---------------------------------------------------------------------*/

_mfs_error  MFS_Clear_cluster
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,  /*[IN] the drive on which to operate */
    uint_32                 cluster     /*[IN]  the # of the cluster to clear*/
    )
{
    uint_32      sector,i;
    _mfs_error   error_code;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (NULL, drive_ptr))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_Flush_directory_sector_buffer(drive_ptr);
    sector = CLUSTER_TO_SECTOR(cluster);

    _mem_zero(drive_ptr->DIR_SECTOR_PTR, drive_ptr->BPB.SECTOR_SIZE);
    for ( i = 0; ((i<drive_ptr->BPB.SECTORS_PER_CLUSTER) && (error_code==MFS_NO_ERROR));i++ )
    {
        error_code = MFS_Write_device_sector(drive_ptr,sector+i,drive_ptr->DIR_SECTOR_PTR);
    } 
    drive_ptr->DIR_SECTOR_NUMBER = sector;
    return(error_code);
}  

#endif


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Bad_clusters
* Returned Value   :  uint_32
* Comments  :  Return the number of bad clusters in the file system.
*
*END*---------------------------------------------------------------------*/

uint_32  MFS_Bad_clusters
    (
    MQX_FILE_PTR            mfs_fd_ptr  
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    uint_32                 last_cluster;
    uint_32                 k;
    uint_32                 bad_slots;
    uint_32                 error_code;
    uint_32                 cluster_status;

    bad_slots = 0;


    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }

    last_cluster = drive_ptr->LAST_CLUSTER;

    for ( k = CLUSTER_MIN_GOOD; k <= last_cluster; k++ )
    {
        error_code = MFS_get_cluster_from_fat(drive_ptr, k, &cluster_status);
        if ( error_code != MFS_NO_ERROR )
        {
            break;
        }
        else if ( cluster_status == CLUSTER_BAD )
        {
            bad_slots++;
        }
    }  

    MFS_unlock(drive_ptr,FALSE);

    return(bad_slots);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Last_cluster
* Returned Value   :  uint_32
* Comments  :  Return the number of the last cluster in the file system.
*
*END*---------------------------------------------------------------------*/

uint_32  MFS_Last_cluster
    (
    MQX_FILE_PTR            mfs_fd_ptr  
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    uint_32                 last_cluster;
    uint_32                 error_code;

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }

    last_cluster = drive_ptr->LAST_CLUSTER;

    MFS_unlock(drive_ptr,FALSE);
    return(last_cluster);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Get_disk_free_space
* Returned Value   :  bytes_free
* Comments  :  Returns the number of free bytes on the disk.
*
*END*---------------------------------------------------------------------*/

uint_64  MFS_Get_disk_free_space
    (
    MQX_FILE_PTR            mfs_fd_ptr  
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    uint_32                 clusters_free;
    uint_32                 error_code;
    uint_64                 bytes_free;

    if ( MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr) != MFS_NO_ERROR )
    {
        return 0;
    }

    clusters_free = MFS_Get_disk_free_space_internal(drive_ptr,&error_code);   

    if (error_code == MFS_NO_ERROR)
    {
        bytes_free = ((uint_64)clusters_free) << drive_ptr->CLUSTER_POWER_BYTES;
    }
    else
    {
        bytes_free = 0;
    }  

    MFS_unlock(drive_ptr,FALSE);

    return bytes_free;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Get_disk_free_space_internal
* Returned Value   :  bytes_free
* Comments  :  Returns the number of free clusters on the disk.
*
*END*---------------------------------------------------------------------*/

uint_32  MFS_Get_disk_free_space_internal
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32_ptr             error_ptr
    )
{
    uint_32  last_cluster, k, free_slots;
    uint_32  error_code = MFS_NO_ERROR;
    uint_32  cluster_status;

    last_cluster = drive_ptr->LAST_CLUSTER;

    if ( drive_ptr->FREE_COUNT == FSI_UNKNOWN )
    {
        free_slots = 0;

        for ( k = CLUSTER_MIN_GOOD; k <= last_cluster; k++ )
        {
            error_code = MFS_get_cluster_from_fat(drive_ptr, k, &cluster_status);
            if ( error_code != MFS_NO_ERROR )
            {
                break;
            }
            else if ( cluster_status == CLUSTER_UNUSED )
            {
                free_slots++;
            }
        }  

        if ( error_code == MFS_NO_ERROR )
        {
            drive_ptr->FREE_COUNT = free_slots;
        }
    }
    else
    {
        free_slots = drive_ptr->FREE_COUNT;    
    }  

    MFS_set_error_and_return(error_ptr, error_code, free_slots);
}


<|start_filename|>Firmware/Inverter_bootloader/BSP/CAN_control.h<|end_filename|>
#ifndef __CAN_CONTROL
  #define __CAN_CONTROL

  #define CAN_DEVICE  0

  #define CAN_SPEED   100000

  #define CAN_MIN_TQ  8
  #define CAN_MAX_TQ  25

  #define CAN_MAX_PROPSEG 8
  #define CAN_MAX_RJW 4
  #define CAN_MIN_PSEG2 2

  
  // Майлбоксы на чтение 
  #define CAN_RX_MB1     0
  #define CAN_RX_MB2     1
  #define CAN_RX_MB3     2
  #define CAN_RX_MB4     3
  #define CAN_RX_MB5     4
  #define CAN_RX_MB6     5
  #define CAN_RX_MB7     6
  #define CAN_RX_MB8     7
  // Всего майлбоксов на чтение
  #define RX_MBOX_CNT    8

  // Майлбоксы на передачу 
  #define CAN_TX_MB1     8

  // Количество сообщений в логе приемника
  #define CAN_RX_LOG_SZ  128



typedef struct
{
  INT32U pseg1;
  INT32U pseg2;
  INT32U propseg;
  INT32U rjw;
  INT32U presdiv;
}
T_can_ctrl;


typedef struct 
{
  INT32U canid;   // Полученый идентификатор CAN пакета           
  INT8U  data[8]; // Буффер с данными длинной 8 байт                          
  INT8U  len;     // Длина данных                                
  INT8U  format;  // Формат идентификатора           0 - STANDARD,   1 - EXTENDED IDENTIFIER    
  INT8U  type;    // Признак  Remote Request Frame   0 - DATA FRAME, 1 - REMOTE FRAME      
  INT8U  code;    // Message Buffer Code
} 
T_can_msg;

typedef struct
{
  INT8U  mb_num;
  INT32U canid; 
  INT32U canid_mask; 

} T_can_rx_config;



int  CAN_init(CAN_MemMapPtr ptr, INT32U bitrate);
void CAN_Tx_Task(INT32U parameter);
void CAN_Rx_Task(INT32U parameter);
int  Read_can_msg(T_can_msg *rcv_msg);
int  Send_can_msg(T_can_msg *can_msg);
int  CAN_set_tx_mbox(volatile CAN_MemMapPtr CAN, INT8U n, INT32U id, INT8U *data, INT8U len, INT8U ext, INT8U rtr);
void CAN_set_rx_mbox(volatile CAN_MemMapPtr CAN, INT8U n, INT32U id, INT32U mask, INT8U ext, INT8U rtr);
#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ppp_prv.h<|end_filename|>
#ifndef __ppp_prv_h__
#define __ppp_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ppp_prv.h$
* $Version : 3.8.7.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the private defines, externs and data
*   structure definitions required by the PPP Library.
*
*END************************************************************************/

#include "pppfsm.h"
#include "lcp.h"
#include "pap.h"
#include "chap.h"
#include "ccp.h"


/*
** Assorted PPP constants
*/

#define PPP_VALID       0x1A0A80CFl
#define PPP_PROT_CP     0x00FD
#define PPP_PROT_CCP    0x80FD
#define PPP_PROT_LCP    0xC021
#define PPP_PROT_PAP    0xC023
#define PPP_PROT_CHAP   0xC223

/*
** Control packet types
*/

#define PPPCMD_SEND     0
#define PPPCMD_RESTART  1
#define PPPCMD_STOP     2
#define PPPCMD_SHUTDOWN 3

/*
** Constants for the Message Pool
*/

#define PPP_MESSAGE_INITCOUNT    8
#define PPP_MESSAGE_GROWTH       4
#define PPP_MESSAGE_LIMIT        32


struct ppp_opt;
struct ppp_cfg;

typedef struct ppp_message {
   MESSAGE_HEADER_STRUCT   HEADER;
   uint_16                 COMMAND;
   uint_16                 PROTOCOL;
   PCB_PTR                 PCB;
   void (_CODE_PTR_        ORIG_FREE)(PCB_PTR);
   uint_32                 TIMEOUT;
   uint_32                 RETRY;
   void (_CODE_PTR_        CALL)(pointer, PCB_PTR, boolean);
   pointer                 PARAM;
   int_32                  DELTA;
   struct ppp_message _PTR_    NEXT;
} PPP_MESSAGE, _PTR_ PPP_MESSAGE_PTR;

/*
** The PPP Options structure.  This structure contains all the
** negotiated options for an open PPP link.
*/

typedef struct ppp_opt {
   uint_32           ACCM;
   uint_32           MRU;
   uint_16           AP;
   uint_16           QP;            /* Not implemented */
   void (_CODE_PTR_  AP_Start)(_ppp_handle);
/*
   union {}          QP_DATA;
*/
   uint_32           MAGIC;
   boolean           PFC;
   boolean           ACFC;
   CP_CALL_PTR       CP;
} PPP_OPT, _PTR_ PPP_OPT_PTR;

extern PPP_OPT PPP_DEFAULT_OPTIONS;
extern PPP_OPT PPP_DEFAULT_OPTIONS_PPPOE;


/*
** The LCP Options state used during negotiation
*/

typedef struct lcp_neg {
   unsigned NEG_MRU   : 1;
   unsigned NEG_ACCM  : 1;
   unsigned NEG_AP    : 1;
   unsigned NEG_QP    : 1;    /* Not used */
   unsigned NEG_MAGIC : 1;    /* Not used */
   unsigned NEG_PFC   : 1;
   unsigned NEG_ACFC  : 1;
   unsigned NEG_FCS   : 1;    /* Not used */
   unsigned           : 0;
   uint_16  MRU;
   uint_32  ACCM;       /* LCP only negotiates 32 bits of the ACCM */
   uint_16  AP;
} LCP_NEG, _PTR_ LCP_NEG_PTR;

/*
** The LCP Configuration structure
*/

typedef struct lcp_cfg {

   /* Statistics counters */
   uint_32        ST_LCP_RX_REJECT;
   uint_32        ST_LCP_RX_ECHO;
   uint_32        ST_LCP_RX_REPLY;
   uint_32        ST_LCP_RX_DISCARD;
   uint_32        ST_LCP_TX_REJECT;
   uint_32        ST_LCP_TX_ECHO;
   uint_32        ST_LCP_TX_REPLY;
   uint_32        ST_LCP_TX_DISCARD;

   _iopcb_handle  DEVICE;
   PPP_OPT        SEND_OPT;
   PPP_OPT        RECV_OPT;
   LCP_NEG        RECV_NEG;
/* Start CR 2207 */
#if PPP_SECRETS_NOT_SHARED
    _ppp_handle    HANDLE;
#endif
/* End CR 2207 */
} LCP_CFG, _PTR_ LCP_CFG_PTR;


/*
** The PPP Callback structure.  An array of these structures allows
** PPP to inform the application when certain events occur.
*/

typedef struct ppp_call_internal {
   void (_CODE_PTR_  CALLBACK)();
   pointer           PARAM;
} PPP_CALL_INTERNAL, _PTR_ PPP_CALL_INTERNAL_PTR;


/*
** The Protocol Callback structure.  A linked list of these structures allows
** PPP_rx_task to forward incoming packets to upper layer protocols.
*/

typedef struct prot_call {
   uint_16                 PROTOCOL;
   void (_CODE_PTR_        CALLBACK)(PCB_PTR, pointer);
   pointer                 PARAM;
   struct prot_call _PTR_  NEXT;
} PROT_CALL, _PTR_ PROT_CALL_PTR;


/*
** The PPP Configuration structure.
**
** MUTEX provides mutual exclusion on LINK_STATE, RECV_OPTIONS and
** SEND_OPTIONS, since they are read by both the Rx and Tx tasks,
** and written by the Rx task and any task that calls PPP_open or PPP_close.
**
** MUTEX is also used for mutual exclusion on the PROT_CALLS linked
** list.  We don't have to use the same mutex, but it saves space.
*/

typedef struct ppp_cfg {

   /* Statistics counters */
   uint_32                 ST_RX_RECEIVED;
   uint_32                 ST_RX_ABORTED;
   uint_32                 ST_RX_DISCARDED;
   uint_32                 ST_RX_RUNT;
   uint_32                 ST_RX_LONG;
   uint_32                 ST_RX_BAD_ADDR;
   uint_32                 ST_RX_BAD_CTRL;
   uint_32                 ST_RX_BAD_FCS;
   uint_32                 ST_TX_SENT;
   uint_32                 ST_TX_DISCARDED;
   uint_32                 ST_TX_BAD_FCS;

   uint_32                 VALID;
   boolean                 LINK_STATE;    /* TRUE if PPP link is up */
   boolean                 LINK_AUTH;     /* TRUE if the peer is authentic */
   _ppp_mutex              MUTEX;
   LCP_CFG                 LCP_STATE;
   PPPFSM_CFG              LCP_FSM;
   PPP_CALL_INTERNAL       LCP_CALL[PPP_CALL_MAX];

   _iopcb_handle           DEVICE;        /* for _iopcb_read/_iopcb_write */
   _queue_id               MSG_QUEUE;     /* for Tx task */
   _queue_id               RESERVED1;
   _pool_id                MSG_POOL;      /* for Tx task */

   PROT_CALL_PTR           PROT_CALLS;
   PPP_OPT volatile _PTR_  RECV_OPTIONS;
   PPP_OPT volatile _PTR_  SEND_OPTIONS;

   PAP_DATA                PAP_STATE;
   CHAP_DATA               CHAP_STATE;

   CCP_CFG                 CCP_STATE;
   PPPFSM_CFG              CCP_FSM;

   _rtcs_taskid            RX_TASKID;
   /* new fix */
volatile   boolean                 STOP_RX;
   /***********/
/* Start CR 2207 */
#if PPP_SECRETS_NOT_SHARED
   PPP_SECRET_PTR   _PPP_PAP_LSECRET;

   /* The array of secrets to use to authenticate the peer with PAP */
   PPP_SECRET_PTR   _PPP_PAP_RSECRETS;

   /* The name of the local host (required for CHAP) */
   char_ptr   _PPP_CHAP_LNAME;

   /* The array of secrets to use if the peer requests CHAP authentication */
   PPP_SECRET_PTR   _PPP_CHAP_LSECRETS;

   /* The array of secrets to use to authenticate the peer with CHAP */
   PPP_SECRET_PTR   _PPP_CHAP_RSECRETS;
#endif
/* End CR 2207 */
} PPP_CFG, _PTR_ PPP_CFG_PTR;


extern PCB_PTR PPP_pcballoc (uint_16, uint_32);

extern uint_32 PPP_send_one      (PPP_CFG_PTR, uint_16, PCB_PTR);
extern uint_32 PPP_send_rexmit   (PPP_CFG_PTR, uint_16, PCB_PTR,
                                  uint_32, void (_CODE_PTR_)(pointer, PCB_PTR, boolean), pointer);
extern uint_32 PPP_send_restart  (PPP_CFG_PTR, uint_16);
extern uint_32 PPP_send_stop     (PPP_CFG_PTR, uint_16);
extern uint_32 PPP_send_shutdown (PPP_CFG_PTR, pointer);

extern void PPP_up(_ppp_handle);
extern void PPP_MD5_block(uint_32_ptr, uint_32_ptr, const uint_32 _PTR_);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2s/i2s_ki2s.h<|end_filename|>
#ifndef _i2s_ki2s_h
#define _i2s_ki2s_h 1
/*
**************************************************************************
*
* $FileName: i2s_ki2s.h$
* $Version : 3.8.4.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the I2S drivers for the MCF54XX.
*
*END************************************************************************/

#include "i2s_audio.h"

#define BIT16_MAX 32767
/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** MCF54XX_I2S_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a serial port is initialized.
*/
typedef struct ki2s_init_struct
{
   /* The I2S channel to initialize */
   uint_8 CHANNEL;
   
   /* Default operating mode */
   uint_8 MODE;
   
   /* Number of valid data bits*/
   uint_8 DATA_BITS;
   
   /* SSI_CLOCK source*/
   uint_8 CLOCK_SOURCE;
   
   /* Data are stereo */
   boolean STEREO;
   
   /* Transmit dummy data */
   boolean TX_DUMMY;
   
   /* Interrupt level to use */
   _int_level LEVEL;
   
   /* Tx buffer size */
   uint_32 BUFFER_SIZE;
   
   /* I/O data format */
   AUDIO_DATA_FORMAT const * IO_FORMAT;

} KI2S_INIT_STRUCT, _PTR_ KI2S_INIT_STRUCT_PTR;
typedef const KI2S_INIT_STRUCT _PTR_ KI2S_INIT_STRUCT_CPTR;

/*--------------------------------------------------------------------------*/
/* 
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

extern uint_32 _ki2s_int_install (char_ptr, KI2S_INIT_STRUCT_CPTR);
extern pointer _bsp_get_i2s_base_address (uint_8);
extern uint_32 _bsp_get_i2s_vector (uint_8);
#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/mem_prv.h<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mem_prv.h$
* $Version : 3.8.6.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains definitions private to the memory manger.
*
*END************************************************************************/
#ifndef __mem_prv_h__
#define __mem_prv_h__

#if MQX_USE_MEM

/*--------------------------------------------------------------------------*/
/*
 *                    CONSTANT DEFINITIONS
 */

#define MEMPOOL_VALID                (_mqx_uint)(0x6D656D70)     /* "memp" */

/* The smallest amount of memory that is allocated */
#define MQX_MIN_MEMORY_STORAGE_SIZE \
   ((_mem_size)(sizeof(STOREBLOCK_STRUCT) + PSP_MEMORY_ALIGNMENT) & \
   PSP_MEMORY_ALIGNMENT_MASK)


/*--------------------------------------------------------------------------*/
/*
 *                      MACROS DEFINITIONS
 *
 * The following macros are defined to calculate block locations and checksums
 */

/*
 * get the location of the block pointer, given the address as provided
 * to the application by _mem_alloc.
 */
#define GET_MEMBLOCK_PTR(addr) \
   (STOREBLOCK_STRUCT_PTR)((pointer)(((uchar_ptr)(addr) - \
      FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA))))

/*
 * Calculate the next physical block (in higher memory)
 * The next physical block is adjacent to the provided block
 */
#define NEXT_PHYS(block) \
   ((STOREBLOCK_STRUCT_PTR)((char _PTR_)block + \
   ((STOREBLOCK_STRUCT_PTR)(block))->BLOCKSIZE))

/*
 * Calculate the previous physical block (in lower memory)
 * The previous physical block is adjacent to the provided block
 */
#define PREV_PHYS(block) \
   ((STOREBLOCK_STRUCT_PTR)(block))->PREVBLOCK


/*
 * Calculate the next block on the free list.
 * (assuming the current block is on the free list)
 */
#define NEXT_FREE(block) \
   ((STOREBLOCK_STRUCT_PTR)(block))->NEXTBLOCK

/*
 * Calculate the previous free block on the free list.
 * (assuming the current block is on the free list)
 */
#define PREV_FREE(block) \
   ((STOREBLOCK_STRUCT_PTR)(block))->USER_AREA


/* Calculate the checksum for the current block */
#if MQX_CHECK_VALIDITY
#define CALC_CHECKSUM(block) \
   ((STOREBLOCK_STRUCT_PTR)(block))->CHECKSUM = \
   (_mqx_uint) ( ((STOREBLOCK_STRUCT_PTR)(block))->BLOCKSIZE) + \
   (_mqx_uint) ( ((STOREBLOCK_STRUCT_PTR)(block))->PREVBLOCK) + \
   (_mqx_uint) ( ((STOREBLOCK_STRUCT_PTR)(block))->TASK_NUMBER) + \
   (_mqx_uint) ( ((STOREBLOCK_STRUCT_PTR)(block))->MEM_TYPE);
#else
#define CALC_CHECKSUM(block)
#endif

/* Validate the checksum of the current block */
#if MQX_CHECK_VALIDITY
#define VALID_CHECKSUM(block) \
   ( ((STOREBLOCK_STRUCT_PTR)(block))->CHECKSUM == \
   ((_mqx_uint)(((STOREBLOCK_STRUCT_PTR)(block))->BLOCKSIZE) + \
   (_mqx_uint)(((STOREBLOCK_STRUCT_PTR)(block))->PREVBLOCK) + \
   (_mqx_uint)(((STOREBLOCK_STRUCT_PTR)(block))->TASK_NUMBER) + \
   (_mqx_uint)(((STOREBLOCK_STRUCT_PTR)(block))->MEM_TYPE)) )
#else
#define VALID_CHECKSUM(block) (TRUE)
#endif

#define MARK_BLOCK_AS_USED(block, tid) \
   ( ((STOREBLOCK_STRUCT_PTR)(block))->TASK_NUMBER = TASK_NUMBER_FROM_TASKID(tid) )

#define MARK_BLOCK_AS_FREE(block) \
   ( ((STOREBLOCK_STRUCT_PTR)(block))->TASK_NUMBER = (_task_number)0)

#define BLOCK_IS_FREE(block) \
   ( ((STOREBLOCK_STRUCT_PTR)(block))->TASK_NUMBER == (_task_number)0 \
   ? TRUE : FALSE )

#define BLOCK_IS_USED(block) \
   ( ((STOREBLOCK_STRUCT_PTR)(block))->TASK_NUMBER == (_task_number)0 \
   ? FALSE : TRUE )

#define BLOCK_IS_OWNED(block) \
   ( ((STOREBLOCK_STRUCT_PTR)(block))->TASK_NUMBER == (_task_number)SYSTEM_TASK_NUMBER  ? FALSE : TRUE )


/*--------------------------------------------------------------------------*/
/*
 *                    DATATYPE DECLARATIONS
 */


/*
 * The memory management component of MQX maintains pools of memory blocks
 * of variable size.
 * These pools contains contiguous neighbouring blocks that may be
 * in use (task_id is non-zero) or on the free list (task_id is zero)
 *
 * To get to the right physical neighbour, the size field can be
 * added to the current block's address.
 * To get to the left physical neighbour, the PREVBLOCK field
 * points to that block.
 *
 * For an allocated block, NEXTBLOCK points to the next block
 * belonging to the TASK who owns this block.
 *
 * On the free list, the NEXTBLOCK field points to the next
 * block on the free list.
 * The USERAREA field points to the previous block on the free
 * list.
 */

/* STOREBLOCK STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure is used to define the storage blocks used by the memory 
 * manager in MQX.
 */
typedef struct storeblock_struct
{
   /*! \brief Task number. */
   _task_number                   TASK_NUMBER;
   /*! \brief Memory type. */
   _mem_type                      MEM_TYPE;

   /*! \brief The size of the block. */
   _mem_size                      BLOCKSIZE;

   /*! \brief The memory pool the block was allocated from. */
   pointer                        MEM_POOL_PTR;

   /*!
    * \brief Pointer to the next block.
    *     
    * For an allocated block, this points to the next block on the allocation 
    * list. It points to the USER_AREA in the next block.
    * \n When on the free list, this points to the next block on the free list 
    * (start of the block).
    */
   pointer                        NEXTBLOCK;

   /*! \brief The address of the physical block previous to this block. */
   struct storeblock_struct _PTR_ PREVBLOCK;

   /*!
    * \brief A checksum of the header: a simple sum of the BLOCKSIZE, PREVBLOCK 
    * and TASK_ID.
    */
   _mqx_uint                      CHECKSUM;

#ifdef PSP_MEM_STOREBLOCK_ALIGNMENT
   /*! \brief Makes sure that the USER_AREA field is properly aligned. */
   _mqx_uint                      RESERVED[PSP_MEM_STOREBLOCK_ALIGNMENT];
#endif

   /*!
    * \brief The field whose address is provided to the user when the block is 
    * allocated to him.  It is also used by the memory manager to maintain a 
    * reverse link for a block that is on the free list.
    */
   pointer                        USER_AREA;

} STOREBLOCK_STRUCT, _PTR_ STOREBLOCK_STRUCT_PTR;
/*! \endcond */

/* MEMORY COMPONENT STRUCT */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief This structure is used to store information required for the memory 
 * component.
 */
typedef struct memory_component_struct
{
   /*! \brief A queue of all created memory pools. */
   QUEUE_STRUCT  POOLS;

   /*! \brief A semaphore to protect the creatation of pools. */
   LWSEM_STRUCT  SEM;

   /*! \brief A validation field for memory pools. */
   _mqx_uint     VALID;

} MEMORY_COMPONENT_STRUCT, _PTR_ MEMORY_COMPONENT_STRUCT_PTR;
/*! \endcond */


/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief Context information for pool extensions. This information is kept on 
 * the top of the block of memory to be made into an extension.
 */
typedef struct mempool_extension_struct
{
   /*! \brief Used to link extensions together in a memory pool. */
   QUEUE_ELEMENT_STRUCT   LINK;

   /*! \brief The start address of the extension supplied. */
   pointer                REAL_START;

   /*! \brief The start of the memory blocks contained in this particular extension. */
   pointer                START;

   /*! \brief The size of this particular extension. */
   _mem_size              SIZE;

} MEMPOOL_EXTENSION_STRUCT, _PTR_ MEMPOOL_EXTENSION_STRUCT_PTR;
/*! \endcond */

/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief Context information for a memory pool.
 */
typedef struct mempool_struct
{
   /*! \brief Used to link memory pools together. */
   QUEUE_ELEMENT_STRUCT   LINK;

   /*! \brief Used to verify if handle is valid. */
   _mqx_uint              VALID;

   /*! \brief The size of the memory pool in bytes. */
   _mem_size              POOL_SIZE;

   /*! \brief Used for pool size error check. */
   _mem_size              POOL_CHECK_POOL_SIZE;
   /*! \brief Used for pool start pointer error check. */
   char _PTR_             POOL_CHECK_POOL_PTR;
   /*! \brief Used for pool end pointer error check. */
   STOREBLOCK_STRUCT_PTR  POOL_CHECK_POOL_END_PTR;

   /*! \brief Address of the start of the Memory Pool. */
   pointer                POOL_PTR;

   /*! \brief The address of the start of Memory Pool blocks. */
   STOREBLOCK_STRUCT_PTR  POOL_ALLOC_START_PTR;

   /*! \brief The physical end of the memory pool. */
   pointer                POOL_LIMIT;

   /*! \brief The highest memory location allocated from kernel memory. */
   pointer                POOL_HIGHEST_MEMORY_USED;

   /*!
    * \brief Used in mem_alloc_x when marching down the free list.
    *     
    * This allows for higher priority tasks to bump a lower one.
    */
   STOREBLOCK_STRUCT_PTR  POOL_ALLOC_CURRENT_BLOCK;

   /*! \brief Used by _mem_test_at when checking the physical blocks in the pool. */
   volatile STOREBLOCK_STRUCT _PTR_  POOL_PHYSICAL_CHECK_BLOCK;

   /*! \brief Used by _mem_test_at when checking the free list in the pool. */
   STOREBLOCK_STRUCT_PTR  POOL_FREE_CHECK_BLOCK;

   /*!
    * \brief Variable used by _mem_free_at when traversing the free list so as 
    * to allow higher priority tasks to run.
    */
   STOREBLOCK_STRUCT_PTR  POOL_FREE_CURRENT_BLOCK;

   /*! \brief The memory block that caused the error. */
   STOREBLOCK_STRUCT_PTR  POOL_BLOCK_IN_ERROR;

   /*! \brief The address of the head of the memory pool free list. */
   STOREBLOCK_STRUCT_PTR  POOL_FREE_LIST_PTR;

   /*! \brief The address of the last memory pool entry. */
   STOREBLOCK_STRUCT_PTR  POOL_END_PTR;

   /*! \brief A queue of all extensions to memory pool. */
   QUEUE_STRUCT           EXT_LIST;

} MEMPOOL_STRUCT, _PTR_ MEMPOOL_STRUCT_PTR;
/*! \endcond */

#define _GET_MEMBLOCK_TYPE(ptr)     (((STOREBLOCK_STRUCT_PTR)GET_MEMBLOCK_PTR(ptr))->MEM_TYPE)

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern boolean   _mem_check_coalesce_internal(STOREBLOCK_STRUCT_PTR);
extern _mqx_uint _mem_create_pool_internal(pointer, pointer, MEMPOOL_STRUCT_PTR);
extern _mqx_uint _mem_extend_pool_internal(pointer, _mem_size, MEMPOOL_STRUCT_PTR);
#endif

#ifdef __cplusplus
}
#endif

#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/msd/usb_msc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_msc.c$
* $Version : 3.8.6.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
* @brief The file contains USB stack MSC layer implimentation.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
 #include "usb_stack_config.h"
 
 #if MSD_CONFIG 
    #include "usb_msc.h"
/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/

/****************************************************************************
 * Global Variables
 ****************************************************************************/
 /* Add all the variables needed for usb_msc.c to this structure */
 MSC_DEVICE_STRUCT_PTR   msc_device_array[MAX_MSC_DEVICE];
/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
uint_8 USB_MSC_Other_Requests(USB_SETUP_STRUCT * setup_packet, 
                              uint_8_ptr *data, 
                              uint_32 *size,pointer arg);
uint_8 process_mass_storage_command (MSC_DEVICE_STRUCT_PTR mscDevicePtr,
                                     PTR_CBW cbw_ptr, 
                                     uint_32* csw_residue_ptr, 
                                     uint_8* csw_status_ptr);                           
                          
/*****************************************************************************
 * Local Variables - None
 *****************************************************************************/
 
 /*****************************************************************************
 * Local Functions
 *****************************************************************************/
/*************************************************************************//*!
 *
 * @name  USB_Msd_Allocate_Handle
 *
 * @brief The funtion reserves entry in device array and returns the index.
 *
 * @param none.
 * @return returns the reserved handle or if no entry found device busy.      
 *
 *****************************************************************************/
static MSD_HANDLE  USB_Msd_Allocate_Handle()
{
    uint_32 cnt = 0;
    for (;cnt< MAX_MSC_DEVICE;cnt++)
    {
       if (msc_device_array[cnt] == NULL)
        return cnt;
    }
    return USBERR_DEVICE_BUSY;
}

/*************************************************************************//*!
 *
 * @name  USB_Msd_Free_Handle
 *
 * @brief The funtion releases entry in device array .
 *
 * @param handle  index in device array to be released..
 * @return returns and error code or USB_OK.      
 *
 *****************************************************************************/
static uint_32 USB_Msd_Free_Handle(MSD_HANDLE handle)
{
    if (/*(handle < 0) || */(handle > MAX_MSC_DEVICE))
        return USBERR_ERROR;
    
    USB_mem_free((void *)msc_device_array[handle]);
    msc_device_array[handle] = NULL;
    return USB_OK;
}

/*************************************************************************//*!
 *
 * @name  USB_Msd_Get_Device_Ptr
 *
 * @brief The funtion gets the device pointer from device array .
 *
 * @param handle  index in device array.
 * @return returns returns pointer to MSD device structure..      
 *
 *****************************************************************************/
static MSC_DEVICE_STRUCT_PTR USB_Msd_Get_Device_Ptr(MSD_HANDLE handle)
{
     return msc_device_array[handle]; 
}
 
/**************************************************************************//*!
 *
 * @name  process_mass_storage_command
 *
 * @brief Process a Mass storage class command 
 *        This function is added here to add more sub class specific commands)
 *
 * @param MSC_DEVICE_STRUCT_PTR 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
uint_8 process_mass_storage_command 
(
    MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
    PTR_CBW cbw_ptr, 
    uint_32* csw_residue_ptr, 
    uint_8* csw_status_ptr
)
{   
    uint_8 error = USBERR_ERROR;/* initializing to error value */
    switch (cbw_ptr->command_block[0]) 
    {
        /* commands to be supported by all devices */
        case INQUIRY_COMMAND : /*opcode : 0x12*/
               error = msc_inquiry_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;
        case READ_10_COMMAND : /*opcode : 0x28 */
        case READ_12_COMMAND : /*opcode : 0xA8 */
            error = msc_read_command(msc_obj_ptr, 
            cbw_ptr,csw_residue_ptr,csw_status_ptr);
            break;      
        case REQUEST_SENSE_COMMAND : /*opcode : 0x03*/
            error = msc_request_sense_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
           break;           
        case TEST_UNIT_READY_COMMAND : /*opcode : 0x00 */ 
           error = msc_test_unit_ready_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break; 
        case WRITE_10_COMMAND : /*opcode : 0x2A */
        case WRITE_12_COMMAND : /*opcode : 0xAA */
           error = msc_write_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
           csw_status_ptr);
            break; 
        case PREVENT_ALLOW_MEDIUM_REM_COMMAND : /*opcode :0x1E */
           error = msc_prevent_allow_medium_removal(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;                   
        case FORMAT_UNIT_COMMAND : /*opcode : 0x04*/
           error = msc_format_unit_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;
        case READ_CAPACITY_10_COMMAND : /*opcode : 0x25*/
           error = msc_read_capacity_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;       
        case MODE_SENSE_10_COMMAND : /* opcode :0x5A*/
        case MODE_SENSE_6_COMMAND : /* opcode : 0x1A */
           error = msc_mode_sense_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;
        case MODE_SELECT_10_COMMAND : /*opcode : 0x55 */
        case MODE_SELECT_6_COMMAND : /*opcode : 0x15 */
           error = msc_mode_select_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;
        case READ_FORMAT_CAPACITIES_COMMAND : /*opcode : 0x23 */
           error = msc_read_format_capacity_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;
        case SEND_DIAGNOSTIC_COMMAND : /*opcode : 0x1D*/
            error = msc_send_diagnostic_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break; 
        case VERIFY_COMMAND : /*opcode : 0x2F*/
            error = msc_verify_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;
        case START_STOP_UNIT_COMMAND : /*opcode : 0x1B*/
            error = msc_start_stop_unit_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            break;                                  
        default: /* for all unsupported commands */
            error = msc_unsupported_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr,
                csw_status_ptr);
            msc_obj_ptr->out_flag = FALSE;
            msc_obj_ptr->in_flag = FALSE;
            msc_obj_ptr->out_stall_flag = FALSE;
            msc_obj_ptr->in_stall_flag = FALSE;
            break;
    }
    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_Service_Bulk_In
 *
 * @brief The funtion ic callback function of DIC Bulk In Endpoint 
 *
 * @param event
 * @param arg
 * @return None       
 *
 *****************************************************************************/
void USB_Service_Bulk_In(PTR_USB_EVENT_STRUCT event, pointer arg)
{
    uint_8 event_type; 
    PTR_CSW csw_ptr;
    MSC_DEVICE_STRUCT_PTR msc_obj_ptr;
    
    #if IMPLEMENT_QUEUING 
        uint_8 index;
        uint_8 producer, consumer;
        USB_ENDPOINTS *usb_ep_data ;
            
        USB_CLASS_MSC_QUEUE queue;
    #endif
    
    msc_obj_ptr = (MSC_DEVICE_STRUCT_PTR)arg;  
    
    if (NULL == msc_obj_ptr)
    {
        #if _DEBUG
            printf("USB_Service_Bulk_In: msc_obj_ptr is NULL\n");
        #endif  
        return;
    }
    
    #if IMPLEMENT_QUEUING    
        usb_ep_data = msc_obj_ptr->ep_desc_data; 
        
        /* map the endpoint num to the index of the endpoint structure */
        for(index = 0; index < usb_ep_data->count; index++) 
        {
            if(usb_ep_data->ep[index].ep_num == event->ep_num)
            break;
        }
                                                   
        producer = msc_obj_ptr->ep[index].bin_producer;         
        /* if there are no errors de-queue the queue and decrement the no. of 
           transfers left, else send the same data again */
        msc_obj_ptr->ep[index].bin_consumer++;              
        consumer = msc_obj_ptr->ep[index].bin_consumer;         
        
        if(consumer != producer) 
        {/*if bin is not empty */
                            
            queue = msc_obj_ptr->ep[index].queue[consumer%MSD_MAX_QUEUE_ELEMS];                         
            (void)USB_Class_Send_Data(msc_obj_ptr->class_handle, queue.channel, 
                queue.app_data.data_ptr, queue.app_data.data_size);
            return;
        }          
    #endif

    if(msc_obj_ptr->transfer_remaining >= event->len)
    {   /* decrement the global count */
        msc_obj_ptr->transfer_remaining -= event->len;          
    }
        
    /* check if there is need to stall BULK IN ENDPOINT And
       there isn't any transfer in progress*/
    if( (msc_obj_ptr->in_stall_flag == TRUE)&&
        (!msc_obj_ptr->transfer_remaining))
    {
        uint_8 component = (uint_8)(event->ep_num | 
            (USB_SEND<<COMPONENT_PREPARE_SHIFT));
        msc_obj_ptr->in_stall_flag = FALSE; /* clear the flag */
        msc_obj_ptr->in_flag = FALSE; /* clear send flag */
        /* now, stalling the status phase - CASE 5th of THIRTEEN CASES*/           
        (void)_usb_device_set_status(msc_obj_ptr->controller_handle,
            (uint_8)(component|USB_STATUS_ENDPOINT),
            (uint_16)USB_STATUS_STALLED);
        return;                 
    }

    /* If its not a data phase on bulk endpoint */
    if ((!msc_obj_ptr->in_flag) && (event->len == MSC_CSW_LENGTH)) 
    {
        csw_ptr = (PTR_CSW)(event->buffer_ptr);
    } 
   
    if(msc_obj_ptr->in_flag) /* bulk in transaction has occured before CSW */
    {           
        if(msc_obj_ptr->param_callback.callback != NULL) 
        {
            event_type = (uint_8)(msc_obj_ptr->transfer_remaining?
                USB_MSC_DEVICE_READ_REQUEST : USB_APP_SEND_COMPLETE);
            
            if(event_type == USB_APP_SEND_COMPLETE)
            {       
                APP_DATA_STRUCT bulk_in_recv;
                bulk_in_recv.data_ptr = event->buffer_ptr;
                bulk_in_recv.data_size = event->len; 
                msc_obj_ptr->param_callback.callback(event_type,
                    (void*)&bulk_in_recv, msc_obj_ptr->param_callback.arg);
            }
            else
            {
                LBA_APP_STRUCT lba_data;        
                msc_obj_ptr->current_offset += event->len;
                lba_data.offset = msc_obj_ptr->current_offset;
                lba_data.size = (msc_obj_ptr->transfer_remaining > 
                    msc_obj_ptr->msd_buff.msc_lba_send_buff_size) ? msc_obj_ptr->msd_buff.msc_lba_send_buff_size : 
                    msc_obj_ptr->transfer_remaining; 
                /* whichever is smaller */
                lba_data.buff_ptr = msc_obj_ptr->msd_buff.msc_lba_send_ptr;
                /* fetch data from MSD App(e.g)ram disk or Sd card, etc*/
                msc_obj_ptr->param_callback.callback(event_type,
                    (void*)&lba_data, msc_obj_ptr->param_callback.arg);
                /* Send data on USB Bus */
                (void)USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, 
                    (uint_8_ptr)lba_data.buff_ptr,lba_data.size);    
            }
        }        
        
        if(!msc_obj_ptr->transfer_remaining)
        {   /* marks the end of data phase */
            msc_obj_ptr->in_flag = FALSE; /* clear the flag for next CBW */         
            /* Send the command status information */
            (void)USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, 
                (uint_8_ptr)msc_obj_ptr->csw_ptr, MSC_CSW_LENGTH);                  
        }
    } 
    else if ((event->len == MSC_CSW_LENGTH) /* CSW is 13 bytes in length */
        && (csw_ptr->signature == USB_DCSWSIGNATURE)) /*valid CSW signature*/                 
    {
        /* this flag will now be set on reset or after CSW being sent */
        msc_obj_ptr->cbw_valid_flag = TRUE;        
        /* prepare for next CBW */  
        (void)USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle,
            (uint_8*)msc_obj_ptr->cbw_ptr, MSC_CBW_LENGTH);
    }     
}

/**************************************************************************//*!
 *
 * @name  USB_Service_Bulk_Out
 *
 * @brief The funtion ic callback function of DIC Bulk Out Endpoint 
 *
 * @param event
 * @param arg
 * @return None       
 *
 *****************************************************************************/
void USB_Service_Bulk_Out(PTR_USB_EVENT_STRUCT event,pointer arg)
{       
    uint_8 event_type; 
    PTR_CBW cbw_ptr = NULL;
    uint_8 error;
    MSC_DEVICE_STRUCT_PTR msc_obj_ptr;
    
    msc_obj_ptr = (MSC_DEVICE_STRUCT_PTR)arg;  
    
    if (NULL == msc_obj_ptr)
    {
        #if _DEBUG
            printf("USB_Service_Bulk_Out: msc_dev_ptr is NULL\n");
        #endif  
        return;
    }
         
     /* check if there is need to stall BULK IN ENDPOINT */
    if( (msc_obj_ptr->out_stall_flag == TRUE)&&
        (!msc_obj_ptr->transfer_remaining))
    {
        uint_8 component = (uint_8)(event->ep_num | 
            (USB_RECV<<COMPONENT_PREPARE_SHIFT));
        msc_obj_ptr->out_stall_flag = FALSE; /* clear the flag */
        msc_obj_ptr->out_flag = FALSE; /* clear send flag */
        /* now, stalling the status phase - CASE 5th of THIRTEEN CASES*/           
        (void)_usb_device_set_status(msc_obj_ptr->controller_handle,
            (uint_8)(component|USB_STATUS_ENDPOINT),
            (uint_16)USB_STATUS_STALLED);
        return;                 
    }
    
    /* If its not a data phase on bulk endpoint */
    if ((!msc_obj_ptr->out_flag) && (event->len == MSC_CBW_LENGTH)) 
    {
        cbw_ptr = (PTR_CBW)(event->buffer_ptr);
    } 

    if(msc_obj_ptr->out_flag) /* bulk out transaction has occured after CBW */
    {           
        if(msc_obj_ptr->param_callback.callback != NULL) 
        {
            event_type = (uint_8)(msc_obj_ptr->transfer_remaining?
                USB_MSC_DEVICE_WRITE_REQUEST : USB_APP_DATA_RECEIVED);
                                        
            if(event_type == USB_APP_DATA_RECEIVED)
            {
                APP_DATA_STRUCT bulk_out_recv;                  
                bulk_out_recv.data_ptr = event->buffer_ptr;
                bulk_out_recv.data_size = event->len; 
                
                msc_obj_ptr->param_callback.callback(event_type,
                    (void*)&bulk_out_recv, msc_obj_ptr->param_callback.arg);
            }
            else
            {
                LBA_APP_STRUCT lba_data1;
                lba_data1.buff_ptr = msc_obj_ptr->msd_buff.msc_lba_recv_ptr;
                lba_data1.offset = msc_obj_ptr->current_offset;
                lba_data1.size = event->len;                                
                /* copy the data received on USB Bus, to MSD Disk 
                   (e.g.) CD/DVD or SD Card, etc */
                msc_obj_ptr->param_callback.callback(event_type,
                    (void*)&lba_data1, msc_obj_ptr->param_callback.arg);
            }            
        }
        
        if(msc_obj_ptr->transfer_remaining >= event->len)
        {   /* decrement the global count */
            msc_obj_ptr->transfer_remaining -= event->len;
                                  
            if((msc_obj_ptr->out_stall_flag == TRUE)&&
               (!msc_obj_ptr->transfer_remaining))
            {
                uint_8 component = (uint_8)(event->ep_num | 
                    (event->direction<<COMPONENT_PREPARE_SHIFT));
                msc_obj_ptr->out_stall_flag = FALSE; /* clear the flag */
                msc_obj_ptr->out_flag = FALSE; /* clear send flag */
                /* now, stalling the status phase - CASE 5th of THIRTEEN CASES*/           
                (void)_usb_device_set_status(msc_obj_ptr->controller_handle,
                    (uint_8)(component|USB_STATUS_ENDPOINT),
                    (uint_16)USB_STATUS_STALLED);
                return;                 
            }
        }
        
        if(msc_obj_ptr->transfer_remaining)
        {   /* Transfers Remaining -- Again invoke recv_data */         
            LBA_APP_STRUCT lba_data0;           
            msc_obj_ptr->current_offset += event->len;
            lba_data0.size = (msc_obj_ptr->transfer_remaining > msc_obj_ptr->msd_buff.msc_lba_recv_buff_size) ? 
                msc_obj_ptr->msd_buff.msc_lba_recv_buff_size : msc_obj_ptr->transfer_remaining; /* whichever is smaller */
            lba_data0.buff_ptr = msc_obj_ptr->msd_buff.msc_lba_recv_ptr;                
            (void)USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle,
                lba_data0.buff_ptr,lba_data0.size);
            return;
        }
        else
        {   /* marks the end of data phase */
            msc_obj_ptr->out_flag = FALSE; /* clear the flag for next CBW */
            /* Send the command status information */
            (void)USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, 
                (uint_8_ptr)msc_obj_ptr->csw_ptr, MSC_CSW_LENGTH); 
        }
    } 
    else if(/* check for valid and meaningful CBW */
        /* CBW received after device had sent a CSW or after a reset */
        (msc_obj_ptr->cbw_valid_flag)         
        /* CBW is 31 bytes in length */
        && (event->len == MSC_CBW_LENGTH) 
        /* valid CBW signature*/
        && (cbw_ptr != NULL) && (cbw_ptr->signature == USB_DCBWSIGNATURE) 
        /* all reserved bits should be zero*/
        && (!((cbw_ptr->lun & 0xF0) || (cbw_ptr->cb_length & 0xE0)))         
        /* host should send command to valid LUN */
        && (cbw_ptr->lun<msc_obj_ptr->device_info.num_lun_supported)                                    
        /* valid cbwcb length*/
        && ((cbw_ptr->cb_length >= 0x01)&&(cbw_ptr->cb_length <= 0x10))                                                     
          )
    {
        msc_obj_ptr->re_stall_flag = TRUE;
        /* A valid CBW was received */
        msc_obj_ptr->csw_ptr->signature = USB_DCSWSIGNATURE;
        msc_obj_ptr->csw_ptr->tag = cbw_ptr->tag;
        /*this flag will now be set on reset or after CSW being sent */
        msc_obj_ptr->cbw_valid_flag = FALSE;
        
        cbw_ptr->data_length = LONG_LE_TO_HOST(cbw_ptr->data_length);
        
        /* set flag if device is going to recv data in coming transaction */
        msc_obj_ptr->out_flag = (boolean)(( (!(cbw_ptr->flag & USB_CBW_DIRECTION_BIT))
            && (cbw_ptr->data_length))?TRUE:FALSE);
        /* set flag if send is going to send data in coming transaction */
        msc_obj_ptr->in_flag = (boolean)(( (cbw_ptr->flag & USB_CBW_DIRECTION_BIT)
            && (cbw_ptr->data_length))?TRUE:FALSE);                
        /* Process the command */
        error = process_mass_storage_command(msc_obj_ptr, cbw_ptr, 
            &(msc_obj_ptr->csw_ptr->residue), &(msc_obj_ptr->csw_ptr->csw_status));
        
        if(error == USBERR_ENDPOINT_STALLED)
        {
            if(msc_obj_ptr->out_flag==TRUE)
            {
                msc_obj_ptr->out_stall_flag = TRUE; 
                msc_obj_ptr->out_flag = FALSE; /* so as to send status phase */
            }
            else if(msc_obj_ptr->in_flag==TRUE)
            {
                msc_obj_ptr->in_stall_flag = TRUE;  
            }           
        }
        
        /* if there is no data phase on bulk endpoints*/
        if(!(msc_obj_ptr->out_flag || msc_obj_ptr->in_flag)) 
        {   /* Send the command status information */
            (void)USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, 
                (uint_8_ptr)msc_obj_ptr->csw_ptr, MSC_CSW_LENGTH);         
        }
    } 
    else /* Invalid/NMreceived */
    {        
        uint_8 direction;
        uint_8 ep_num;
        /* prepare the component to be sent in lower layer with 
           endpoint number and direction*/
        uint_8 component;
        
        direction  = USB_RECV; 
        ep_num = msc_obj_ptr->bulk_out_endpoint;
        component = (uint_8)(ep_num | (direction<<COMPONENT_PREPARE_SHIFT));

        /* incase of error Stall endpoint and update the status*/        
        (void)_usb_device_set_status(msc_obj_ptr->controller_handle,
            (uint_8)(component|USB_STATUS_ENDPOINT),
            (uint_16)USB_STATUS_STALLED);

        direction  = USB_SEND; 
        ep_num = msc_obj_ptr->bulk_in_endpoint;
        component = (uint_8)(ep_num | (direction<<COMPONENT_PREPARE_SHIFT));

        /* incase of error Stall endpoint and update the status*/        
        (void)_usb_device_set_status(msc_obj_ptr->controller_handle,
            (uint_8)(component|USB_STATUS_ENDPOINT),
            (uint_16)USB_STATUS_STALLED);
        /* make the following CBWs invalid */
        msc_obj_ptr->cbw_valid_flag = FALSE;
    }    
}


/**************************************************************************//*!
 *
 * @name  USB_Class_MSC_Event
 *
 * @brief The funtion initializes MSC endpoints 
 *
 * @param arg             handle to Identify class object.
 * @param event           pointer to event structure
 * @param val             gives the configuration value 
 *
 * @return None       
 *
 *****************************************************************************/
 void USB_Class_MSC_Event(uint_8 event, void* val,pointer arg) 
{   
    MSC_DEVICE_STRUCT_PTR msc_dev_ptr;
    #if IMPLEMENT_QUEUING    
        uint_8 index;
    #endif    
    USB_ENDPOINTS *usb_ep_data;
    
    msc_dev_ptr = (MSC_DEVICE_STRUCT_PTR)arg;
    
    if (NULL == msc_dev_ptr)
    {
        #if _DEBUG
            printf("USB_Class_MSC_Event: msc_dev_ptr is NULL\n");
        #endif  
        return;
    }
    
    /* get the endpoints from the descriptor module */            
    usb_ep_data = msc_dev_ptr->ep_desc_data; 
        
    if(event == USB_APP_ENUM_COMPLETE)
    {
        uint_8 count = 0;
        /* intialize all non control endpoints */            
        while(count < usb_ep_data->count) 
        {
            USB_EP_STRUCT_PTR ep_struct_ptr= 
                (USB_EP_STRUCT_PTR) (&usb_ep_data->ep[count]);
            uint_8 component = (uint_8)(ep_struct_ptr->ep_num | 
                (ep_struct_ptr->direction << COMPONENT_PREPARE_SHIFT));

            (void)_usb_device_init_endpoint(msc_dev_ptr->controller_handle,
                ep_struct_ptr, TRUE);
            
            /* register callback service for Non Control EndPoints */
            if(ep_struct_ptr->type == USB_BULK_PIPE) 
            {             
                if(ep_struct_ptr->direction == USB_RECV) 
                {
                    (void)_usb_device_register_service(msc_dev_ptr->controller_handle,
                        (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                        USB_Service_Bulk_Out,(void *)msc_dev_ptr);
                } 
                else
                {
                    (void)_usb_device_register_service(msc_dev_ptr->controller_handle,
                        (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                        USB_Service_Bulk_In,(void *)msc_dev_ptr);
                }            
            }
                          
            /* set the EndPoint Status as Idle in the device layer */
            /* (no need to specify direction for this case) */
            (void)_usb_device_set_status(msc_dev_ptr->controller_handle,
                (uint_8)(USB_STATUS_ENDPOINT|component),
                (uint_16)USB_STATUS_IDLE);                                                                                                         
            count++;                                                    
        }
        msc_dev_ptr->re_stall_flag = FALSE;
        msc_dev_ptr->out_flag = FALSE;
        msc_dev_ptr->in_flag = FALSE;
        msc_dev_ptr->out_stall_flag = FALSE;
        msc_dev_ptr->in_stall_flag = FALSE;
        msc_dev_ptr->cbw_valid_flag = TRUE; /*making the first CBW valid */ 
        msc_dev_ptr->transfer_remaining = 0; 
                
    }
    else if(event == USB_APP_BUS_RESET)
    {
        #if IMPLEMENT_QUEUING
            for(index = 0; index < usb_ep_data->count; index++) 
            {            
                msc_dev_ptr->ep[index].bin_consumer = 0x00;         
                msc_dev_ptr->ep[index].bin_producer = 0x00;        
            }
        #endif 
    }
    else if(event == USB_APP_EP_UNSTALLED)
    {
        uint_8 value;
        value = *((uint_8_ptr)val);
        
        if( (msc_dev_ptr->re_stall_flag == TRUE)
            &&
            (((value & 0x0F) == msc_dev_ptr->bulk_in_endpoint) || 
            ((value & 0x0F) == msc_dev_ptr->bulk_out_endpoint)))
        {   /* For MASS Storage Class BULK ENDPOINTS have to be unstalled 
               only on receiving Bulk Only Reset. 
               Therefore, if Host sends clear feature to unstall these 
               endpoints, re-stall them
             */     
            (void)_usb_device_set_status(msc_dev_ptr->controller_handle,
                (uint_8)(value|USB_STATUS_ENDPOINT),
                (uint_16)USB_STATUS_STALLED);
        }       
    }
    else if(event == USB_APP_EP_STALLED)
    {
        /* Code to be added here, 
           if there is some action needed at app level */           
    }
            
    if(msc_dev_ptr->msc_callback.callback != NULL) 
    {
        msc_dev_ptr->msc_callback.callback(event,val,
            msc_dev_ptr->msc_callback.arg);
    } 
}

/**************************************************************************//*!
 *
 * @name  USB_MSC_Other_Requests
 *
 * @brief The funtion provides flexibilty to add class and vendor specific
 *        requests 
 *
 * @param arg
 * @param setup_packet:     setup packet recieved      
 * @param data:             data to be send back
 * @param size:             size to be returned    
 *
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_MSC_Other_Requests
(
    USB_SETUP_STRUCT * setup_packet, 
    uint_8_ptr *data, 
    uint_32 *size,
    pointer arg
) 
{
    MSC_DEVICE_STRUCT_PTR msc_dev_ptr;
    uint_8 error = USBERR_INVALID_REQ_TYPE;  
     
    msc_dev_ptr = (MSC_DEVICE_STRUCT_PTR)arg;
    
    if (NULL == msc_dev_ptr)
    {
        #if _DEBUG
            printf("USB_MSC_Other_Requests: msc_dev_ptr is NULL\n");
        #endif  
        return USBERR_ERROR;
    }
    
    *size=0;   
 
     if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
        USB_REQUEST_CLASS_CLASS) 
     {  /* class request so handle it here */
     
        error = USB_OK;
        
        /* call for class/subclass specific requests */
        switch(setup_packet->request) 
        {
            case GET_MAX_LUN :
                if((setup_packet->index < msc_dev_ptr->usb_max_suported_interfaces)&&
                    (!setup_packet->value)&&(setup_packet->length == 0x0001)&&
                    ((setup_packet->request_type & USB_DATA_DIREC_MASK) == 
                    USB_DATA_TO_HOST))
                {
                    /* return the maximum number of logical units supported */
                    *data = &msc_dev_ptr->lun;
                    *size=1;
                    msc_dev_ptr->re_stall_flag = TRUE;
                }
                else 
                {   /* for Get Max LUN request with invalid wIndex parameter, 
                       host expects stall */
                    error = USBERR_INVALID_REQ_TYPE; 
                }              
              break;
            case BULK_ONLY_MASS_STORAGE_RESET :
                /* Steps to be taken in this command :
                1) ready the device for the next CBW from the host
                2) preserve the value of its bulk data toggle bits 
                3) preserve the value of its bulk endpoint STALL conditions
                4) device shall NAK the status stage of device request until 
                   command is complete*/

                if((setup_packet->index < msc_dev_ptr->usb_max_suported_interfaces)&&
                    (!setup_packet->value)&&(!setup_packet->length) &&
                    ((setup_packet->request_type & USB_DATA_DIREC_MASK) == 
                    USB_DATA_TO_DEVICE))
                {
                    /* get the endpoints from the descriptor module */            
                    USB_ENDPOINTS *usb_ep_data = msc_dev_ptr->ep_desc_data;
                    uint_8 count = 0;

                    /* deinitialize and intialize bulk endpoints */            
                    while(count < usb_ep_data->count) 
                    {
                        USB_EP_STRUCT_PTR ep_struct_ptr= 
                            (USB_EP_STRUCT_PTR) (&usb_ep_data->ep[count]);
                        uint_8 component = (uint_8)(ep_struct_ptr->ep_num | 
                            (ep_struct_ptr->direction << COMPONENT_PREPARE_SHIFT));
                        
                        if(ep_struct_ptr->type == USB_BULK_PIPE)
                        {
                            (void)_usb_device_deinit_endpoint(msc_dev_ptr->controller_handle,
                                ep_struct_ptr->ep_num, ep_struct_ptr->direction);
                            (void)_usb_device_init_endpoint(msc_dev_ptr->controller_handle,
                                ep_struct_ptr, TRUE);
                            /* set EndPoint Status as Idle */                       
                            (void)_usb_device_set_status(msc_dev_ptr->controller_handle,
                                (uint_8)(USB_STATUS_ENDPOINT|component),
                                (uint_16)USB_STATUS_IDLE);                                                        
                        }
                        count++;
                    }
                    msc_dev_ptr->out_flag = FALSE;
                    msc_dev_ptr->in_flag = FALSE;
                    msc_dev_ptr->out_stall_flag = FALSE;
                    msc_dev_ptr->in_stall_flag = FALSE;
                    /*making the first CBW valid */
                    msc_dev_ptr->cbw_valid_flag = TRUE;                
                    msc_dev_ptr->re_stall_flag = FALSE;
                    msc_dev_ptr->transfer_remaining = 0;
                }
                else 
                {   /* for Get Max LUN request with invalid wIndex parameter, 
                       host expects stall */
                    error = USBERR_INVALID_REQ_TYPE; 
                }    
                break;           
            default :break;        
        }
    } 
    else if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == 
        USB_REQUEST_CLASS_VENDOR) 
    {   /* vendor specific request  */    
        if(msc_dev_ptr->vendor_callback.callback != NULL) 
        {
            error = msc_dev_ptr->vendor_callback.callback(setup_packet,
            data,size,msc_dev_ptr->vendor_callback.arg);
        }
    }
     
    return error;
}


/*****************************************************************************
 * Global Functions
 *****************************************************************************/


/**************************************************************************//*!
 *
 * @name  USB_Class_MSC_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param msd_config_ptr    : Configuration paramemter strucutre pointer
 *                            passed by APP.
 * @return status       
 *         MSD Handle           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the MSC Class layer and layers it is dependednt on 
 ******************************************************************************/
MSD_HANDLE USB_Class_MSC_Init
(
   USB_MSD_CONFIG_STRUCT_PTR msd_config_ptr /*[IN]*/
) 
{   
    #if IMPLEMENT_QUEUING    
        uint_8 index;
    #endif    
    uint_8 error;
    MSD_HANDLE msd_handle;
    MSC_DEVICE_STRUCT_PTR devicePtr = NULL;
    USB_CLASS_CALLBACK_STRUCT scsi_cb;
    USB_ENDPOINTS *usb_ep_data;

    if (msd_config_ptr == NULL)
    {
        return USBERR_ERROR;    
    }
    
    devicePtr = (MSC_DEVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(MSC_DEVICE_STRUCT));
    if (NULL == devicePtr)
    {
        #if _DEBUG
            printf("1: USB_Class_MSC_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }
    
    msd_handle = USB_Msd_Allocate_Handle();
    if (USBERR_DEVICE_BUSY == msd_handle) 
    {
        USB_mem_free(devicePtr);
        devicePtr = NULL;
        return USBERR_INIT_FAILED;
    }

        /* initialize the Global Variable Structure */
    USB_mem_zero(devicePtr, sizeof(MSC_DEVICE_STRUCT));
     /* Initialize number of Logical Units */
    devicePtr->ep = msd_config_ptr->ep;
    usb_ep_data = msd_config_ptr->ep_desc_data;
    USB_mem_copy(&msd_config_ptr->device_info, &devicePtr->device_info, 
        sizeof(DEVICE_LBA_INFO_STRUCT));
    USB_mem_copy(&msd_config_ptr->msd_buff, &devicePtr->msd_buff, 
        sizeof(MSD_BUFF_INFO));
    devicePtr->lun = (uint_8)(msd_config_ptr->device_info.num_lun_supported - 1);
    
    /* Initialize the device layer*/
    error = _usb_device_init(USBCFG_DEFAULT_DEVICE_CONTROLLER,
        &devicePtr->controller_handle, 
        (uint_8)(usb_ep_data->count+1));
    /* +1 is for Control Endpoint */
    if(error != USB_OK)
    {
      goto error1;  
    }

    msd_config_ptr->desc_callback_ptr->handle = msd_handle;
    /* Initialize the generic class functions */
    devicePtr->class_handle = USB_Class_Init(devicePtr->controller_handle,USB_Class_MSC_Event,
       USB_MSC_Other_Requests,(void *)devicePtr,msd_config_ptr->desc_callback_ptr);
            
    /* Initialize the pstn subclass functions */
    scsi_cb.callback = USB_Class_MSC_Event;
    scsi_cb.arg   = devicePtr; 
    error = USB_MSC_SCSI_Init(devicePtr,&scsi_cb, &msd_config_ptr->device_info,
        msd_config_ptr->implementing_disk_drive); 
    
    if(error != USB_OK)
    {
      goto error2;  
    }
    
    devicePtr->cbw_ptr = NULL; /* Initializing */
    devicePtr->csw_ptr = NULL;
    
    devicePtr->cbw_ptr = (PTR_CBW)USB_mem_alloc_uncached(MSC_CBW_LENGTH); 
    if (NULL == devicePtr->cbw_ptr)
    {
        #if _DEBUG
            printf("2: USB_Class_MSC_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }
    _mem_zero(devicePtr->cbw_ptr, MSC_CBW_LENGTH);
    
    devicePtr->csw_ptr = (PTR_CSW)USB_mem_alloc_uncached(MSC_CSW_LENGTH); 
    if (NULL == devicePtr->csw_ptr)
    {
        #if _DEBUG
            printf("3: USB_Class_MSC_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }
    _mem_zero(devicePtr->csw_ptr, MSC_CSW_LENGTH);
    
    devicePtr->ep_desc_data = usb_ep_data;
    devicePtr->bulk_in_endpoint =   msd_config_ptr->bulk_in_endpoint;
    devicePtr->bulk_in_endpoint_packet_size =   
        msd_config_ptr->bulk_in_endpoint_packet_size;
    devicePtr->bulk_out_endpoint = 
        msd_config_ptr->bulk_out_endpoint;
    devicePtr->usb_max_suported_interfaces = 
        msd_config_ptr->usb_max_suported_interfaces;
                                                           
    #if IMPLEMENT_QUEUING
        for(index = 0; index < usb_ep_data->count; index++) 
        {            
            devicePtr->ep[index].endpoint = usb_ep_data->ep[index].ep_num;
            devicePtr->ep[index].type = usb_ep_data->ep[index].type;        
            devicePtr->ep[index].bin_consumer = 0x00;         
            devicePtr->ep[index].bin_producer = 0x00;        
        }
    #endif
        
    /* save the callback pointer */
    devicePtr->msc_callback.callback = msd_config_ptr->msc_class_callback->callback;
    devicePtr->msc_callback.arg = msd_config_ptr->msc_class_callback->arg;
           
    /* save the callback pointer */
    devicePtr->vendor_callback.callback =
        msd_config_ptr->vendor_req_callback->callback;
    devicePtr->vendor_callback.arg = msd_config_ptr->vendor_req_callback->arg;
           
    /* save the callback pointer */
    devicePtr->param_callback.callback = msd_config_ptr->param_callback->callback;           
    devicePtr->param_callback.arg = msd_config_ptr->param_callback->arg;

    devicePtr->msc_handle = msd_handle;
    msc_device_array[msd_handle] = devicePtr;
    
    return msd_handle;
   
    error2:
        /* Implement Denit class and invoke here*/    
    error1: 
        USB_Msd_Free_Handle(msd_handle);
        USB_mem_free(devicePtr);
        devicePtr = NULL; 
    return error;     
}

/**************************************************************************//*!
 *
 * @name  USB_Class_MSC_Send_Data
 *
 * @brief 
 *
 * @param msc_handle   :   handle returned from USB_Class_MSC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
uint_8 USB_Class_MSC_Send_Data
(
    MSD_HANDLE msc_handle, /*[IN]*/
    uint_8 ep_num, /*[IN]*/
    uint_8_ptr app_buff, /*[IN]*/
    uint_32 size /*[IN]*/
) 
{
    MSC_DEVICE_STRUCT_PTR devicePtr;
    #if IMPLEMENT_QUEUING    
        uint_8 index;
        uint_8 producer, consumer; 
        USB_ENDPOINTS *usb_ep_data;
    #endif
    uint_8 error = USB_OK;


    if (/*(msc_handle < 0) || */ (msc_handle > MAX_MSC_DEVICE))
       return USBERR_ERROR;
      
    devicePtr = USB_Msd_Get_Device_Ptr(msc_handle);
    if (devicePtr == NULL)
        return USBERR_ERROR;

    #if IMPLEMENT_QUEUING    
 
        usb_ep_data = devicePtr->ep_desc_data; 
      
        /* map the endpoint num to the index of the endpoint structure */
        for(index = 0; index < usb_ep_data->count; index++) 
        {
            if(usb_ep_data->ep[index].ep_num == ep_num)
            break;
        }
        
        producer = devicePtr->ep[index].bin_producer;
        consumer = devicePtr->ep[index].bin_consumer;
                                
        if(((uint_8)(producer - consumer)) != (uint_8)(MSD_MAX_QUEUE_ELEMS))  
        {
            /* the bin is not full*/        
            uint_8 queue_num = (uint_8)(producer % MSD_MAX_QUEUE_ELEMS);
            
            /* put all send request parameters in the endpoint data structure*/
            devicePtr->ep[index].queue[queue_num].channel = ep_num;
            devicePtr->ep[index].queue[queue_num].app_data.data_ptr = app_buff;
            devicePtr->ep[index].queue[queue_num].app_data.data_size = size;
            devicePtr->ep[index].queue[queue_num].handle = 
            devicePtr->controller_handle; 
            
            /* increment producer bin by 1*/       
            devicePtr->ep[index].bin_producer = ++producer;
                    
            if((uint_8)(producer - consumer) == (uint_8)1)         
            {          
    #endif            
                error = USB_Class_Send_Data(devicePtr->class_handle, 
                    ep_num, app_buff,size);
    #if IMPLEMENT_QUEUING
            }
        }
        else /* bin is full */
        {
            error = USBERR_DEVICE_BUSY; 
        }    
    #endif 
    
    return error;
}

/**************************************************************************//*!
 *
 * @name  USB_MSC_LBA_Transfer
 *
 * @brief 
 *
 * @param MSC_DEVICE_STRUCT_PTR   
 * @param direction       :   transfer direction
 * @param lba_info_ptr    :   buffer to send
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
uint_8 USB_MSC_LBA_Transfer
(
    MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
    boolean direction,
    PTR_LBA_INFO_STRUCT lba_info_ptr
)
{
    uint_8 error;
    LBA_APP_STRUCT lba_data;    
    
    if((!((lba_info_ptr->starting_lba<msc_obj_ptr->device_info.total_lba_device_supports)&&
        (lba_info_ptr->lba_transfer_num <= (msc_obj_ptr->device_info.total_lba_device_supports - 
        lba_info_ptr->starting_lba)))) || (msc_obj_ptr->param_callback.callback == NULL))
    {
        /* host trying to access region beyond MASS STORAGE SPACE 
           Or no param_callback is registered */
        return(uint_8)((direction?USBERR_TX_FAILED:USBERR_RX_FAILED));
    }

    msc_obj_ptr->transfer_remaining = lba_info_ptr->lba_transfer_num * 
        msc_obj_ptr->device_info.length_of_each_lab_of_device;              
    msc_obj_ptr->current_offset = lba_info_ptr->starting_lba * 
        msc_obj_ptr->device_info.length_of_each_lab_of_device;
    
    lba_data.offset = msc_obj_ptr->current_offset;

    if(direction == USB_SEND)
    {
        lba_data.size = (msc_obj_ptr->transfer_remaining > msc_obj_ptr->msd_buff.msc_lba_send_buff_size) ? 
            msc_obj_ptr->msd_buff.msc_lba_send_buff_size : msc_obj_ptr->transfer_remaining; /* whichever is smaller */
        lba_data.buff_ptr = msc_obj_ptr->msd_buff.msc_lba_send_ptr;
        
        msc_obj_ptr->param_callback.callback(USB_MSC_DEVICE_READ_REQUEST,
            (void*)&lba_data, msc_obj_ptr->param_callback.arg);

        error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle,lba_data.buff_ptr,lba_data.size);
    }
    else
    {
        lba_data.size = (msc_obj_ptr->transfer_remaining > msc_obj_ptr->msd_buff.msc_lba_recv_buff_size) ? 
            msc_obj_ptr->msd_buff.msc_lba_recv_buff_size : msc_obj_ptr->transfer_remaining; /* whichever is smaller */
        lba_data.buff_ptr = msc_obj_ptr->msd_buff.msc_lba_recv_ptr;
        
        error = USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle,lba_data.buff_ptr,lba_data.size);
    }               
    return error;
}

#endif /*MSD_CONFIG*/
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_dir.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_dir.c$
* $Version : 3.8.14.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_prv.h>

#if SHELLCFG_USES_MFS
#define BUFFER_SIZE  256

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_dir
* Returned Value   :  int_32 error code
* Comments  :  Reads from a file .
*
*END*---------------------------------------------------------------------*/

int_32  Shell_dir(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean              print_usage, shorthelp = FALSE;
   int_32               return_code = SHELL_EXIT_SUCCESS;
   int_32               len;
   MQX_FILE_PTR         fs_ptr;
   char_ptr             path_ptr, mode_ptr;
   pointer              dir_ptr;
   char_ptr             buffer = NULL;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   int_32               error = 0;


   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc > 3)  {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else {
         path_ptr  ="*.*";
         mode_ptr = "m";
         if (argc >= 2)  {
            path_ptr = argv[1];
            if (argc== 3)  {
               mode_ptr = argv[2];
            }
         }
         
         fs_ptr = Shell_get_current_filesystem(argv);
         /* check if filesystem is mounted */ 
         if (fs_ptr == NULL)  {
             printf("Error, file system not mounted\n");
             return_code = SHELL_EXIT_ERROR;
         } else  {
            buffer = _mem_alloc(BUFFER_SIZE);
            error = ioctl(fs_ptr, IO_IOCTL_CHANGE_CURRENT_DIR, shell_ptr->CURRENT_DIR);
            if (buffer && !error) {
            
               dir_ptr = _io_mfs_dir_open(fs_ptr, path_ptr, mode_ptr );
            
               if (dir_ptr == NULL)  {
                  printf("File not found.\n");
                  return_code = SHELL_EXIT_ERROR;
               } else {
                  while ((_io_is_fs_valid(fs_ptr)) && (len = _io_mfs_dir_read(dir_ptr, buffer, BUFFER_SIZE)) > 0) {
                     printf(buffer);
                  } 
                  _io_mfs_dir_close(dir_ptr);
               }
               _mem_free(buffer);
            } else {
               if(buffer == NULL){
                 printf("Error, unable to allocate space.\n" );
               } else {
                 printf("Error, directory does not exist.\n" );
               }
               return_code = SHELL_EXIT_ERROR;
            }
         }
      }
   }

   if (print_usage)  {
      if (shorthelp)  {
         printf("%s [<filespec>] [<attr>]]\n", argv[0]);
      } else  {
         printf("Usage: %s [<filespec> [<attr>]]\n", argv[0]);
         printf("   <filespec>   = files to list\n");
         printf("   <attr>       = attributes of files: adhrsv*\n");
      }
   }
   return return_code;
} /* Endbody */
#endif //SHELLCFG_USES_MFS
/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/tcpip.h<|end_filename|>
#ifndef __tcpip_h__
#define __tcpip_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcpip.h$
* $Version : 3.8.10.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Definitions for the TCP/IP layer error codes.
*
*END************************************************************************/

#include "rtcstime.h"
#include "ipradix.h"
#include "checksum.h"
#include "ip.h"
#include "icmp.h"
#include "igmp.h"
#include "udp.h"
#include "tcp.h"
#include "icmp6.h"

/***************************************
**
** Type definitions
**
*/

typedef struct tcpip_message {
   MESSAGE_HEADER_STRUCT   HEAD;
   void (_CODE_PTR_        COMMAND)(pointer);
   pointer                 DATA;
} TCPIP_MESSAGE, _PTR_ TCPIP_MESSAGE_PTR;

/*  TCP Configuration
**    This information is persistent for the TCP layer.
*/
typedef struct tcpip_cfg_struct {

   uint_32     status;           /* task status - RTCS_OK => running */

} TCPIP_CFG_STRUCT, _PTR_ TCPIP_CFG_STRUCT_PTR;


/***************************************
**
** Function-specific type definitions
**
*/


/* IPIF_*() */
typedef struct ipif_parm {
   TCPIP_PARM           COMMON;
   pointer              mhandle;
   _rtcs_if_handle      ihandle;
   RTCS_IF_STRUCT_PTR   if_ptr;
   _ip_address          address;
   _ip_address          locmask;
   _ip_address          network;
   _ip_address          netmask;
   boolean              probe;
} IPIF_PARM, _PTR_ IPIF_PARM_PTR;


/* SOCK_selectall() and SOCK_select() */
typedef struct sockselect_parm {
   TCPIP_PARM                          COMMON;
   struct sockselect_parm _PTR_        NEXT;
   struct sockselect_parm _PTR_ _PTR_  PREV;
   TCPIP_EVENT                         EXPIRE;
   _rtcs_taskid                        owner;
   uint_32 _PTR_                       sock_ptr;
   uint_32 _PTR_                       writesock_ptr;
   uint_32 _PTR_                       exceptsock_ptr;
   uint_32                             sock_count;
   uint_32                             writesock_count;
   uint_32                             timeout;
   uint_32                             sock;
} SOCKSELECT_PARM, _PTR_ SOCKSELECT_PARM_PTR;


/***************************************
**
** Globals
**
*/

/* The TCP tick server */
extern uint_32 (_CODE_PTR_ TCP_tick)(void);


/***************************************
**
** Prototypes
**
*/

void TCPIP_task (pointer, pointer);

/* Select functions */
extern void    SOCK_selectall       (SOCKSELECT_PARM_PTR);
extern void    SOCK_select          (SOCKSELECT_PARM_PTR);

extern boolean SOCK_select_activity (SOCKET_STRUCT_PTR, int);
extern void    SOCK_select_block    (SOCKSELECT_PARM_PTR);
extern boolean SOCK_select_expire   (TCPIP_EVENT_PTR);
extern void    SOCK_select_unblock  (SOCKSELECT_PARM_PTR, uint_16);

#define SOCK_select_signal(a, b)    _SOCK_select_signal(a, b, 0)

extern void    _SOCK_select_signal   (uint_32, uint_16, uint_32);

/* BOOTP and DHCP common functions */

uint_32 BOOT_init
(
   void
);

uint_32 BOOT_open
(
   void (_CODE_PTR_)(RTCSPCB_PTR, UCB_STRUCT_PTR)
);

uint_32 BOOT_close
(
   void
);

uint_32 BOOT_send
(
   RTCSPCB_PTR       ,        /* [IN]     outgoing packet  */
   pointer                    /* [IN]     target interface */
);

void BOOT_service
(
   RTCSPCB_PTR       ,        /* [IN/OUT] incoming packet  */
   UCB_STRUCT_PTR             /* [IN]     target UCB       */
);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ipcfg_prv.h<|end_filename|>
#ifndef __ipcfg_prv_h__
#define __ipcfg_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcfg_prv.h$
* $Version : 3.8.4.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Private definitions for the IPCFG layer.
*
*END************************************************************************/


#include <rtcs.h>


typedef struct ipcfg_context
{
    /* runtime context */
    LWSEM_STRUCT                control_semaphore;
    LWSEM_STRUCT                request_semaphore;
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
    LWSEM_STRUCT                dhcp_response_semaphore;
    uint_32                     dhcp_retries;
#endif
    _rtcs_if_handle             ihandle;
    
    /* parameters for monitoring task */
    IPCFG_STATE                 desired_state;
    IPCFG_IP_ADDRESS_DATA       desired_ip_data;
    
    /* results */ 
    IPCFG_STATE                 actual_state;
    IPCFG_IP_ADDRESS_DATA       actual_ip_data;
#if RTCSCFG_IPCFG_ENABLE_DNS
    _ip_address                 dns;
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT
    _ip_address                 tftp_serveraddress;
    uchar                       tftp_servername[RTCS_SNAME_LEN];
    uchar                       boot_filename[RTCS_BOOTFILE_LEN];
#endif  
} IPCFG_CONTEXT, _PTR_ IPCFG_CONTEXT_PTR;


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/iwcfg.h<|end_filename|>
#ifndef __iwcfg_h__
#define __iwcfg_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iwcfg.h$
* $Version : 3.6.3.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   Definitions for WIFI device configurations.
*
*END************************************************************************/
#include <mqx.h>
#include <bsp.h>
#include <enet_wifi.h>


#define         MAX_RSSI_TABLE_SZ    5


typedef struct _iw_rssi_quanta{
  uint_8 max;
  uint_8 min;
} RSSI_QUANTA,* RSSI_QUANTA_PTR;


/***************************************
**
** Prototypes
**
*/
uint_32 iwcfg_set_essid
    (
        uint_32 dev_num,
        char_ptr essid
    );

uint_32 iwcfg_commit
    (
        uint_32 dev_num
    );

uint_32 iwcfg_set_mode
    (
        uint_32 dev_num,
        char_ptr mode
    );

uint_32 iwcfg_set_wep_key 
    (
        uint_32 dev_num,
        char_ptr wep_key,
        uint_32 key_len,
        uint_32 key_index
        
    );
    
uint_32 iwcfg_set_sec_type 
    (
        uint_32 dev_num,
        char_ptr  sec_type
    );

uint_32 iwcfg_set_passphrase
    (
        uint_32 dev_num,
        char_ptr passphrase
    );
uint_32 iwcfg_set_power 
    (
        uint_32 dev_num,
        uint_32 pow_val,
        uint_32 flags
        
    );

uint_32 iwcfg_set_scan
    (
        uint_32 dev_num,
        char_ptr ssid
    );

uint_32 iwcfg_get_essid
    (
        uint_32 dev_num,
        char_ptr essid /*[OUT]*/
    );

uint_32 iwcfg_get_mode
    (
        uint_32 dev_num,
        char_ptr essid /*[OUT]*/
    );
    
uint_32 iwcfg_get_sectype
    (
        uint_32 dev_num,
        char_ptr sectype /*[OUT]*/
    );  
uint_32 iwcfg_get_wep_key 
    (
        uint_32 dev_num,
        char_ptr wep_key,
        uint_32_ptr key_index
  
    );
uint_32 iwcfg_get_passphrase 
    (
        uint_32 dev_num,
        char_ptr passphrase
         
    );          
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/UARTLP_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type UARTLP
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(UARTLP_PDD_H_)
#define UARTLP_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error UARTLP PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MKL04Z4) /* UART0 */ && \
      !defined(MCU_MKL05Z4) /* UART0 */ && \
      !defined(MCU_MKL14Z4) /* UART0 */ && \
      !defined(MCU_MKL15Z4) /* UART0 */ && \
      !defined(MCU_MKL24Z4) /* UART0 */ && \
      !defined(MCU_MKL25Z4) /* UART0 */
  // Unsupported MCU is active
  #error UARTLP PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Interrupt masks */
#define UARTLP_PDD_INTERRUPT_TRANSMITTER UARTLP_C2_TIE_MASK /**< Transmitter interrupt enable mask */
#define UARTLP_PDD_INTERRUPT_TRANSMITTER_COMPLETE UARTLP_C2_TCIE_MASK /**< Transmitter complete interrupt enable mask */
#define UARTLP_PDD_INTERRUPT_RECEIVER UARTLP_C2_RIE_MASK /**< Receiver interrupt enable mask */
#define UARTLP_PDD_INTERRUPT_IDLE UARTLP_C2_ILIE_MASK /**< Idle interrupt enable mask */
#define UARTLP_PDD_INTERRUPT_PARITY_ERROR UARTLP_C3_PEIE_MASK /**< Parity error interrupt enable mask */
#define UARTLP_PDD_INTERRUPT_FRAMING_ERROR UARTLP_C3_FEIE_MASK /**< Framing error interrupt enable mask */
#define UARTLP_PDD_INTERRUPT_NOISE_ERROR UARTLP_C3_NEIE_MASK /**< Noise error interrupt enable mask */
#define UARTLP_PDD_INTERRUPT_OVERRUN_ERROR UARTLP_C3_ORIE_MASK /**< Overrun error interrupt enable mask */

/* Parity types */
#define UARTLP_PDD_PARITY_NONE 0U                /**< No parity */
#define UARTLP_PDD_PARITY_EVEN 0x2U              /**< Even parity */
#define UARTLP_PDD_PARITY_ODD 0x3U               /**< Even parity */

/* Data width */
#define UARTLP_PDD_WIDTH_8 0U                    /**< 8-bits communication */
#define UARTLP_PDD_WIDTH_9 0x10U                 /**< 9-bits communication */

/* Loop mode */
#define UARTLP_PDD_LOOP_MODE_NORMAL 0U           /**< Normal operation mode. No loopback selected. */
#define UARTLP_PDD_LOOP_MODE_LOCAL_LOOP 0x80U    /**< Local loopback mode. */

/* Position of a parity bit */
#define UARTLP_PDD_PARITY_BIT_POSITION_9 0U      /**< Parity bit is the 9-th bit in the serial transmission */
#define UARTLP_PDD_PARITY_BIT_POSITION_10 0x20U  /**< Parity bit is the 10-th bit in the serial transmission */


/* ----------------------------------------------------------------------------
   -- EnableTransmitter
   ---------------------------------------------------------------------------- */

/**
 * Enables UART transmitter.
 * @param PeripheralBase Peripheral base address.
 * @param State Enables or disables transmitter.
 */
#define UARTLP_PDD_EnableTransmitter(PeripheralBase, State) ( \
    UARTLP_C2_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UARTLP_C2_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UARTLP_C2_TE_MASK))) | ( \
      (uint8_t)((uint8_t)(State) << UARTLP_C2_TE_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- EnableReceiver
   ---------------------------------------------------------------------------- */

/**
 * Enables UART receiver.
 * @param PeripheralBase Peripheral base address.
 * @param State Enables or disables receiver.
 */
#define UARTLP_PDD_EnableReceiver(PeripheralBase, State) ( \
    UARTLP_C2_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UARTLP_C2_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UARTLP_C2_RE_MASK))) | ( \
      (uint8_t)((uint8_t)(State) << UARTLP_C2_RE_SHIFT))) \
  )

/* ----------------------------------------------------------------------------
   -- ReadDataReg
   ---------------------------------------------------------------------------- */

/**
 * Reads data register.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_ReadDataReg(PeripheralBase) ( \
    UARTLP_D_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteDataReg
   ---------------------------------------------------------------------------- */

/**
 * Writes data specified by the Value parameter into data register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Value to be written to the data register.
 */
#define UARTLP_PDD_WriteDataReg(PeripheralBase, Value) ( \
    UARTLP_D_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- PutChar8
   ---------------------------------------------------------------------------- */

/**
 * Puts 8-bits character into the transmit buffer.
 * @param PeripheralBase Peripheral base address.
 * @param Char 8-bits character to be written to the data register.
 */
#define UARTLP_PDD_PutChar8(PeripheralBase, Char) ( \
    UARTLP_D_REG(PeripheralBase) = \
     (uint8_t)(Char) \
  )

/* ----------------------------------------------------------------------------
   -- PutChar9
   ---------------------------------------------------------------------------- */

/**
 * Puts 9-bits character into the transmit buffer.
 * @param PeripheralBase Peripheral base address.
 * @param Char 9-bits character to be written to the data register.
 */
#define UARTLP_PDD_PutChar9(PeripheralBase, Char) ( \
    (UARTLP_C3_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UARTLP_C3_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UARTLP_C3_R9T8_MASK))) | ( \
      (uint8_t)((uint8_t)((uint16_t)(Char) >> 8U) << UARTLP_C3_R9T8_SHIFT)))), \
    (UARTLP_D_REG(PeripheralBase) = \
     (uint8_t)(Char)) \
  )

/* ----------------------------------------------------------------------------
   -- GetChar8
   ---------------------------------------------------------------------------- */

/**
 * Returns 8-bits character from the receive buffer.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_GetChar8(PeripheralBase) ( \
    UARTLP_D_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- GetChar9Bit
   ---------------------------------------------------------------------------- */

/**
 * Returns a mask of the ninth bit of the received character.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_GetChar9Bit(PeripheralBase) ( \
    (uint8_t)(UARTLP_C3_REG(PeripheralBase) & UARTLP_C3_R8T9_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * Enables interrupts specified by the Mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask.
 */
#define UARTLP_PDD_EnableInterrupt(PeripheralBase, Mask) ( \
    (UARTLP_C2_REG(PeripheralBase) |= \
     (uint8_t)((uint8_t)(Mask) & (uint8_t)(~(uint8_t)0xFU))), \
    (UARTLP_C3_REG(PeripheralBase) |= \
     (uint8_t)((uint8_t)(Mask) & 0xFU)) \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * Disables interrupts specified by the Mask parameter.
 * @param PeripheralBase Peripheral base address.
 * @param Mask Interrupt mask.
 */
#define UARTLP_PDD_DisableInterrupt(PeripheralBase, Mask) ( \
    (UARTLP_C2_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)((uint8_t)(Mask) & (uint8_t)(~(uint8_t)0xFU)))), \
    (UARTLP_C3_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)((uint8_t)(Mask) & 0xFU))) \
  )

/* ----------------------------------------------------------------------------
   -- GetTxCompleteInterruptMask
   ---------------------------------------------------------------------------- */

/**
 * Gets the status of the transmiter complete interrupt enable bit.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_GetTxCompleteInterruptMask(PeripheralBase) ( \
    (uint8_t)(UARTLP_C2_REG(PeripheralBase) & UARTLP_C2_TCIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetTxCompleteStatus
   ---------------------------------------------------------------------------- */

/**
 * Gets the status of the transmiter complete interrupt flag.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_GetTxCompleteStatus(PeripheralBase) ( \
    (uint8_t)(UARTLP_S1_REG(PeripheralBase) & UARTLP_S1_TC_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- SetParity
   ---------------------------------------------------------------------------- */

/**
 * Sets a communication parity type.
 * @param PeripheralBase Peripheral base address.
 * @param Parity Parity type.
 */
#define UARTLP_PDD_SetParity(PeripheralBase, Parity) ( \
    UARTLP_C1_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UARTLP_C1_REG(PeripheralBase) & (uint8_t)(~(uint8_t)0x3U))) | ( \
      (uint8_t)(Parity))) \
  )

/* ----------------------------------------------------------------------------
   -- SetDataWidth
   ---------------------------------------------------------------------------- */

/**
 * Sets the communication width.
 * @param PeripheralBase Peripheral base address.
 * @param Width Data width.
 */
#define UARTLP_PDD_SetDataWidth(PeripheralBase, Width) ( \
    UARTLP_C1_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UARTLP_C1_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UARTLP_C1_M_MASK))) | ( \
      (uint8_t)(Width))) \
  )

/* ----------------------------------------------------------------------------
   -- SetLoopMode
   ---------------------------------------------------------------------------- */

/**
 * Selects the loop mode operation.
 * @param PeripheralBase Peripheral base address.
 * @param LoopMode Loop mode.
 */
#define UARTLP_PDD_SetLoopMode(PeripheralBase, LoopMode) ( \
    UARTLP_C1_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UARTLP_C1_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UARTLP_C1_LOOPS_MASK))) | ( \
      (uint8_t)(LoopMode))) \
  )

/* ----------------------------------------------------------------------------
   -- ReadInterruptStatusReg
   ---------------------------------------------------------------------------- */

/**
 * Returns the interrupt status register.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_ReadInterruptStatusReg(PeripheralBase) ( \
    UARTLP_S1_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- SetBaudRate
   ---------------------------------------------------------------------------- */

/**
 * Sets new baud rate value.
 * @param PeripheralBase Peripheral base address.
 * @param BaudRate New baud rate value.
 */
#define UARTLP_PDD_SetBaudRate(PeripheralBase, BaudRate) ( \
    (UARTLP_BDH_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UARTLP_BDH_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UARTLP_BDH_SBR_MASK))) | ( \
      (uint8_t)((uint16_t)(BaudRate) >> 8U)))), \
    (UARTLP_BDL_REG(PeripheralBase) = \
     (uint8_t)(BaudRate)) \
  )

/* ----------------------------------------------------------------------------
   -- SetBreak
   ---------------------------------------------------------------------------- */

/**
 * Set the break signal.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_SetBreak(PeripheralBase) ( \
    UARTLP_C2_REG(PeripheralBase) |= \
     UARTLP_C2_SBK_MASK \
  )

/* ----------------------------------------------------------------------------
   -- ClearBreak
   ---------------------------------------------------------------------------- */

/**
 * Clears the break signal.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_ClearBreak(PeripheralBase) ( \
    UARTLP_C2_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)UARTLP_C2_SBK_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetBreak
   ---------------------------------------------------------------------------- */

/**
 * Returns .
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_GetBreak(PeripheralBase) ( \
    (( \
      (uint8_t)(( \
       UARTLP_S1_REG(PeripheralBase)) & ( \
       (uint8_t)(UARTLP_S1_FE_MASK | UARTLP_S1_RDRF_MASK)))) == ( \
      (uint8_t)(UARTLP_S1_FE_MASK | UARTLP_S1_RDRF_MASK))) ? ( \
      0x1U) : ( \
      0U) \
  )

/* ----------------------------------------------------------------------------
   -- SendBreak
   ---------------------------------------------------------------------------- */

/**
 * Send the break character.
 * @param PeripheralBase Peripheral base address.
 */
#define UARTLP_PDD_SendBreak(PeripheralBase) ( \
    (UARTLP_C2_REG(PeripheralBase) |= \
     UARTLP_C2_SBK_MASK), \
    (UARTLP_C2_REG(PeripheralBase) &= \
     (uint8_t)(~(uint8_t)UARTLP_C2_SBK_MASK)) \
  )

/* ----------------------------------------------------------------------------
   -- SetPositionOfParityBit
   ---------------------------------------------------------------------------- */

/**
 * Sets the position of the parity bit.
 * @param PeripheralBase Peripheral base address.
 * @param Position Position of a parity bit.
 */
#define UARTLP_PDD_SetPositionOfParityBit(PeripheralBase, Position) ( \
    UARTLP_C4_REG(PeripheralBase) = \
     (uint8_t)(( \
      (uint8_t)(UARTLP_C4_REG(PeripheralBase) & (uint8_t)(~(uint8_t)UARTLP_C4_M10_MASK))) | ( \
      (uint8_t)(Position))) \
  )
#endif  /* #if defined(UARTLP_PDD_H_) */

/* UARTLP_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/freescale/flash_mcf51xx_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flash_mcf51xx_prv.h$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines for the internal 
*   flash driver
*
*END************************************************************************/
#ifndef __INT_FLASH_MCF51XX_PRV_H__
#define __INT_FLASH_MCF51XX_PRV_H__


#define CFM_IPS_FLASH_ADDR              0x44000000

/* address in memory map to write in FLASH */
#define FLASH_START_ADDRESS  CFM_IPS_FLASH_ADDR

/* End address for region of flash */
#define FLASH_END_ADDRESS   (vuint32)&__FLASH_SIZE

#define FSTR_SET_STD    0
#define FSTR_SET_1      1
#define FSTR_SET_2      2

#define MEMORY_ARRAY_STD    0
#define MEMORY_ARRAY_1      1
#define MEMORY_ARRAY_2      2

typedef struct mcf51xx_flash_internal_struct
{
    vuchar_ptr   ftsr_ptr;  /* pointer to proper FSTAT register */
    uchar_ptr   flash_execute_code_ptr; /* pointer to flash write and erase code */
        
} MCF51XX_FLASH_INTERNAL_STRUCT, _PTR_ MCF51XX_FLASH_INTERNAL_STRUCT_PTR;

/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/
#ifdef __cplusplus
extern "C" {
#endif

void _mcf51xx_set_cfmclkd(uint_8);

boolean mcf51xx_erase_flash(IO_FLASHX_STRUCT_PTR);
boolean mcf51xx_flash_init(IO_FLASHX_STRUCT_PTR);
void    mcf51xx_flash_deinit(IO_FLASHX_STRUCT_PTR);
boolean mcf51xx_flash_erase_sector(IO_FLASHX_STRUCT_PTR, char_ptr, _mem_size);
boolean mcf51xx_flash_write_sector(IO_FLASHX_STRUCT_PTR, char_ptr, char_ptr, _mem_size);
_mqx_int _io_mcf51xx_flash_ioctl(IO_FLASHX_STRUCT_PTR, _mqx_uint, pointer);
void _mcf51_swap_flash_and_reset();

#ifdef __cplusplus
}
#endif

#endif /* __INT_FLASH_MCF51XX_H__ */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/pppfsm.h<|end_filename|>
#ifndef __fsm_h__
#define __fsm_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pppfsm.h$
* $Version : 3.5.5.0$
* $Date    : Dec-8-2009$
*
* Comments:
*
*   This file contains the defines and data structure
*   definitions required by the PPP Finite State Machine.
*
*END************************************************************************/

/*
** fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.
**
** Copyright (c) 1989 Carnegie Mellon University.
** All rights reserved.
**
** Redistribution and use in source and binary forms are permitted
** provided that the above copyright notice and this paragraph are
** duplicated in all such forms and that any documentation,
** advertising materials, and other materials related to such
** distribution and use acknowledge that the software was developed
** by Carnegie Mellon University.  The name of the
** University may not be used to endorse or promote products derived
** from this software without specific prior written permission.
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
** WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

/*
** Packet header = Code, id, length.
*/

#define CP_HDR_LEN   4


/*
**  CP (LCP, IPCP, etc.) codes.
*/

#define CP_CODE_CONF_REQ  1     /* Configuration Request */
#define CP_CODE_CONF_ACK  2     /* Configuration Ack */
#define CP_CODE_CONF_NAK  3     /* Configuration Nak */
#define CP_CODE_CONF_REJ  4     /* Configuration Reject */
#define CP_CODE_TERM_REQ  5     /* Termination Request */
#define CP_CODE_TERM_ACK  6     /* Termination Ack */
#define CP_CODE_CODE_REJ  7     /* Code Reject */


/*
** The FSM call table.  Contains a list a functions to call when various
** events occur in the FSM.
*/
struct pppfsm_cfg;

typedef struct pppfsm_call {
   uint_16             PROTOCOL;       /* Protocol number */
   boolean (_CODE_PTR_ linkup)  (struct pppfsm_cfg _PTR_); /* Link open */
   void    (_CODE_PTR_ linkdown)(struct pppfsm_cfg _PTR_); /* Link no longer open */
   void    (_CODE_PTR_ resetreq)(struct pppfsm_cfg _PTR_); /* Reset configuration options */
   uint_32 (_CODE_PTR_ buildreq)(struct pppfsm_cfg _PTR_, uchar_ptr, uint_32); /* Build ConfReq */
   uint_32 (_CODE_PTR_ recvreq) (struct pppfsm_cfg _PTR_, boolean); /* Convert ConfReq to ConfAck/Nak/Rej */
   boolean (_CODE_PTR_ recvack) (struct pppfsm_cfg _PTR_); /* TRUE if ConfAck is PPP_OK */
   boolean (_CODE_PTR_ recvnak) (struct pppfsm_cfg _PTR_); /* TRUE if ConfNak is PPP_OK */
   boolean (_CODE_PTR_ recvrej) (struct pppfsm_cfg _PTR_); /* TRUE if ConfRej is PPP_OK */
   boolean (_CODE_PTR_ testcode)(struct pppfsm_cfg _PTR_); /* TRUE if CodeRej is catastrophic */
   boolean (_CODE_PTR_ recvcode)(struct pppfsm_cfg _PTR_); /* TRUE if code is PPP_OK */
} PPPFSM_CALL, _PTR_ PPPFSM_CALL_PTR;

/*
** The FSM Configuration structure.
*/

typedef struct pppfsm_cfg {

   /* Statistics counters */
   uint_32           ST_CP_SHORT;
   uint_32           ST_CP_DOWN;
   uint_32           ST_CP_NOBUFS;
   uint_32           ST_CP_BAD_ACK;
   uint_32           ST_CP_BAD_NAK;
   uint_32           ST_CP_BAD_REJ;

   _ppp_handle       HANDLE;     /* the PPP state structure */
   PPPFSM_CALL_PTR   CALL;       /* The protocol-specific call table */
   pointer           PRIVATE;    /* Parameter for protocol-specific functions */
   uint_32           STATE;      /* Current state */
   _ppp_mutex        MUTEX;      /* Mutual exclusion for the STATE field */

   uchar             CURID;      /* ID of the next ConfReq */
   uchar             REQID;      /* ID of the last ConfReq */
   uint_32           NAKS;       /* Number of consecutive NAKs */

   PCB_PTR           PACKET;     /* Current packet */
   uchar             CODE;       /* Temporary location for the code, */
   uchar             ID;         /*    id and length fields for the  */
   uint_16           LENGTH;     /*    current packet                */
   uchar_ptr         DATA;       /* Current position in the current packet */

   uint_32           OPTIONS;    /* Options passed to PPPFSM_open() */

} PPPFSM_CFG, _PTR_ PPPFSM_CFG_PTR;


/*
** Prototypes
*/

extern uint_32 PPPFSM_init      (PPPFSM_CFG_PTR, _ppp_handle, PPPFSM_CALL_PTR, pointer);
extern uint_32 PPPFSM_destroy   (PPPFSM_CFG_PTR);
extern void    PPPFSM_open      (PPPFSM_CFG_PTR, uint_32);
extern void    PPPFSM_close     (PPPFSM_CFG_PTR);
extern void    PPPFSM_lowerup   (PPPFSM_CFG_PTR);
extern void    PPPFSM_lowerdown (PPPFSM_CFG_PTR);

extern void    PPPFSM_input (PCB_PTR, pointer);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/include/host_dev_list.h<|end_filename|>
#ifndef __host_dev_list_h__
#define __host_dev_list_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_dev_list.h$
* $Version : 3.8.20.0$
* $Date    : Jun-22-2012$
*
* Comments:
*
*   This file defines the device list for USB class drivers.
*   +--------+                           
*   \  ROOT  \---+                       List of devices, one entry  
*   +--------+   \    +--------+           for each attached device
*                +--->\  NEXT  \---+
*                     \--------\   \    +--------+
*                  +--\ MEMLST \   +--->\  NEXT  \---+
*                  \  \--------\        \--------\   \    +--------+
*   Fixed-size     \  \ Device \     +--\ MEMLST \   +--->\  NULL  \
*     per-device   \  \ struct \     \  \--------\        \--------\
*     memory       \  +--------+     \  \ Device \     +--\ MEMLST \
*                  \                 \  \ struct \     \  \--------\
*                  \                 \  +--------+     \  \ Device \
*                  \                 \                 \  \ struct \
*                  +->+--------+     \                 \  +--------+
*   Lists of other    \  NEXT  \     \                 \
*     memory per   +--\--------\     +->+--------+     \
*     device --    \  \ LENGTH \        \  NULL  \     \
*     e.g. pipes,  \  \--------\        \--------\     +->+--------+
*     buffers,     \  \ Device \        \ LENGTH \        \  NULL  \
*     structs      \  \ malloc \        \--------\        \--------\
*                  \  \ memory \        \ Device \        \ LENGTH \
*                  \  +--------+        \ malloc \        \--------\
*                  \                    \ memory \        \ Device \
*                  \                    +--------+        \ malloc \
*                  +->+--------+                          \ memory \
*                     \  NULL  \                          +--------+
*                     \--------\
*                     \ LENGTH \  Length used to check
*                     \--------\    buffer overrun etc.
*                     \ Device \
*                     \ malloc \
*                     \ memory \
*                     +--------+
*   IMPLEMENTATION:
*   Linking list items depends on root pointers behaving like
*   a short entry containing a "next" pointer = NULL when
*   the list is empty.  So next MUST BE FIRST in the structs.
*
*END************************************************************************/
#include "host_common.h"

#if PSP_HAS_DATA_CACHE
#include "ehci_cache.h" //for USB_DMA_ALIGN
#endif

#define  MAX_DEV_INTFS  (32)

/* Types of malloc memory used with USB devices */
enum memory_type 
{
   USB_MEMTYPE_MIN_VALUE,  /* lowest value - 1     */
   USB_MEMTYPE_CONFIG,     /* device configuration */
   USB_MEMTYPE_INTERFACE,  /* Interface descr */
   USB_MEMTYPE_PIPES,      /* pipe bundle          */
   USB_MEMTYPE_BUFFER,     /* buffer               */
   USB_MEMTYPE_CLASS,      /* class driver struct  */
   USB_MEMTYPE_MAX_VALUE   /* highest value + 1    */
};
typedef enum memory_type memory_type;

typedef struct dev_memory
{
   struct dev_memory _PTR_ next;    /* next memory block or NULL */
   uint_32                 blktype; /* type of data, block usage */
   uint_32                 blksize; /* size of data area following */
   /* We store offset of payload to determine real payload location. Offset is needed for alignment.
   ** Since there is also the same byte written just before payload, the offset must be 1B wide.
   ** That determines maximum alignment of 256 Bytes.
   ** Note that this internal method to achieve alignment is not memory friendly, because it inserts
   ** dummy bytes and allocates more memory than needed
   */
   uint_8                  filler[3]; /* since offset MUST be 1B long, we have to put 3 bytes */
   uint_8                  offset;  /* number of bytes inserted after this item when payload starts */
    
   /* Note that normally here are bytes inserted to achieve requested alignement.
   ** Do not use address of payload directly, but always add offset bytes to get the address of payload.
   */
   union {   
      uint_8         data[1];    /* actually [0 ... blksize-1] */
      uchar          bufr[1];    /* uchars [0 ... blksize-1] */
      uint_32        word[1];    /* general-purpose array */
      pointer        bundle[1];  /* pipe bundle */
   } payload;                    /* payload of data */
} DEV_MEMORY, _PTR_ DEV_MEMORY_PTR;
#define  MEM_HEADER_LEN     (16)

/********************************************************************
Note that device instance structure keeps data buffers inside it. 
These buffers are passed to DMA when host does enumeration. This
means that we must ensure that buffers inside this stucture
are aligned in PSP cache line size. 
********************************************************************/

/* Fixed-length fields applicable to all devices */
typedef struct dev_instance
{
    struct dev_instance  _PTR_ next;             /* next device, or NULL */
    DEV_MEMORY_PTR             memlist;          /* list of malloc'd memory */
    _usb_host_handle           host;             /* host (several can exist) */
    uint_8                     speed;            /* device speed */
    uint_8                     hub_no;           /* hub # (root hub = 0) */
    uint_8                     port_no;          /* hub's port # (1 - 8) */
    uint_8                     address;          /* USB address, 1 - 127 */

    uint_16                    cfg_value;
    uint_8                     ctrl_retries;
    uint_8                     new_config;       /* non-zero = new config */

    uint_8                     num_of_interfaces;
    uint_8                     RESERVED0[1];

    uint_16                    state;            /* device state */
    _usb_pipe_handle           control_pipe;     /* control pipe handle */
    tr_callback                control_callback; /* control pipe callback */
    pointer                    control_callback_param; /* control callback param */

#if USB_DMA_ALIGN
    /***********************************************************
    40 bytes have been used above. Device descriptor must be
    aligned on a cache boundary so we must ensure that there
    is enough padding before it.
    ***********************************************************/
    
    uint_8                     RESERVED1[USB_DMA_ALIGN(40) - 40];
#endif // USB_DMA_ALIGN
   
    DEVICE_DESCRIPTOR          dev_descriptor;   /* device descriptor */

#if USB_DMA_ALIGN
    uint_8                     RESERVED2[USB_DMA_ALIGN(sizeof(DEVICE_DESCRIPTOR)) - sizeof(DEVICE_DESCRIPTOR)];   // complete padding
#endif // USB_DMA_ALIGN

    uchar                      buffer[9];        /* enumeration buffer */
   
#if USB_DMA_ALIGN
    uint_8                     RESERVED3[USB_DMA_ALIGN(9) - 9];
#endif // USB_DMA_ALIGN

   /* Interface/s which have been selected (pipes are open) */
   INTERFACE_DESCRIPTOR_PTR   intf_descriptor[MAX_DEV_INTFS];

} DEV_INSTANCE, _PTR_ DEV_INSTANCE_PTR;

/* Prototypes */

#ifdef __cplusplus
extern "C" {
#endif

USB_STATUS usb_dev_list_free_memlist (_usb_device_instance_handle);
USB_STATUS usb_dev_list_free_mem (DEV_INSTANCE_PTR, DEV_MEMORY_PTR);
USB_STATUS usb_dev_list_get_mem (DEV_INSTANCE_PTR, uint_32, memory_type, uint_32 align, DEV_MEMORY_PTR _PTR_);
USB_STATUS usb_dev_list_attach_device (_usb_host_handle, uint_8, uint_8, uint_8);
void usb_dev_list_close_pipe_bundle (PIPE_BUNDLE_STRUCT_PTR);
void usb_dev_list_detach_device (_usb_host_handle, uint_8, uint_8);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/bootp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: bootp.c$
* $Version : 3.8.8.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of the BOOTP client
*   for the TCP/IP protocol suite.
*   This implementation does not:
*   - allow the client to specify its own IP address in
*   the BOOTREQUEST.  BOOTREQUESTs are always sent with
*   source = 0.0.0.0 and destination = 255.255.255.255.
*   If the client really does know its IP address, it
*   can bind the address to the interface and then
*   transmit a BOOTREQUEST through a UDP socket.
*   - allow the client to direct the BOOTREQUEST to a
*   specific server.  ARP is not initialized until the
*   BOOTREPLY is received, so the client will not be
*   able to ARP the server.  Thus, BOOTREQUESTs are
*   always sent via limited broadcast.
*   For more information, refer to:
*   RFC 951  (BOOTP)
*   RFC 1542 (BOOTP Extensions)
*   RPC 1533 (BOOTP Options)
*   Limitations:  Although BOOTP can be used over any medium, this
*   implementation will work only over an Ethernet
*   link layer.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_IP4

#include "rtcs_prv.h"
#include "tcpip.h"
#include "bootp.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : BOOTP_open
* Returned Values : uint_32 (error code)
* Comments        :
*     Initialize the BOOTP client.
*
*END*-----------------------------------------------------------------*/

void BOOTP_open
   (
      TCPIP_PARM_BOOTP _PTR_ parms
   )
{ /* Body */
   IP_IF_PTR      if_ptr = (IP_IF_PTR)parms->handle;
   BOOTP_CFG_PTR  bootp = (BOOTP_CFG_PTR) &parms->config;
   uint_32        error;

   error = BOOT_open(BOOT_service);
   if (error) {
      RTCSCMD_complete(parms, error);
      return;
   } /* Endif */

   if_ptr->BOOTFN = BOOTP_service;

   /* Pick a random transaction ID */
   bootp->XID = RTCS_rand();

   /* Set initial timeout */
   bootp->TIMEOUT = BOOTP_TIMEOUT_MIN;
   bootp->SECS = 0;

   /* Build a BOOTREQUEST packet */
   htonc(bootp->PACKET.OP,    BOOTPOP_BOOTREQUEST);
   htonc(bootp->PACKET.HTYPE, if_ptr->DEV_TYPE);
   htonc(bootp->PACKET.HLEN,  if_ptr->DEV_ADDRLEN);
   htonc(bootp->PACKET.HOPS,  0);
   htonl(bootp->PACKET.XID,   bootp->XID);
   htons(bootp->PACKET.FLAGS, 0x8000);
   htonl(bootp->PACKET.CIADDR, INADDR_ANY);
   htonl(bootp->PACKET.YIADDR, INADDR_ANY);
   htonl(bootp->PACKET.SIADDR, INADDR_ANY);
   htonl(bootp->PACKET.GIADDR, INADDR_ANY);

   _mem_zero(bootp->PACKET.CHADDR, sizeof(bootp->PACKET.CHADDR));
   _mem_copy(if_ptr->DEV_ADDR, bootp->PACKET.CHADDR, if_ptr->DEV_ADDRLEN);

   /* Start the retransmission timer to start sending immediately */
   bootp->RESEND.TIME    = 0;
   bootp->RESEND.EVENT   = BOOTP_send;
   bootp->RESEND.PRIVATE = if_ptr;
   TCPIP_Event_add(&bootp->RESEND);

   if_ptr->BOOT = (pointer)parms;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : BOOTP_close
* Returned Values : uint_32 (error code)
* Comments        :
*     Terminate the BOOTP client.
*
*END*-----------------------------------------------------------------*/

uint_32 BOOTP_close
   (
      IP_IF_PTR   if_ptr
         /* [IN] IP interface structure */
   )
{ /* Body */
   BOOTP_CFG_PTR  bootp = (BOOTP_CFG_PTR) &((TCPIP_PARM_BOOTP _PTR_)if_ptr->BOOT)->config;

   TCPIP_Event_cancel(&bootp->RESEND);
   if_ptr->BOOTFN = NULL;
   if_ptr->BOOT   = NULL;

   return BOOT_close();

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : BOOTP_send
* Returned Values :
* Comments        :
*     Called by the Timer.  Send a BOOTP BOOTREQUEST packet.
*
*END*-----------------------------------------------------------------*/

boolean BOOTP_send
   (
      TCPIP_EVENT_PTR   event
         /* [IN/OUT] the resend event */
   )
{ /* Body */
   IP_IF_PTR               if_ptr = (IP_IF_PTR)event->PRIVATE;
   TCPIP_PARM_BOOTP _PTR_  parms = (TCPIP_PARM_BOOTP _PTR_)if_ptr->BOOT;
   BOOTP_CFG_PTR           bootp = (BOOTP_CFG_PTR) &parms->config;
   RTCSPCB_PTR             pcb_ptr;

   /* Set the event to trigger for the next retransmission (+/- 1 sec) */
   bootp->RESEND.TIME = bootp->TIMEOUT + (RTCS_rand() & 0x7FF) - 0x400;

   /* Allocate a PCB */
   pcb_ptr = RTCSPCB_alloc_send();
   if (pcb_ptr == NULL) {
      return TRUE;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(pcb_ptr);

   /* The only field that changes in BOOTREQUEST packets is 'secs' */
   htons(bootp->PACKET.SECS, bootp->SECS);
   bootp->SECS += bootp->RESEND.TIME >> 10;     /* approx. divide by 1000 */

   /* Double the timeout */
   bootp->TIMEOUT <<= 1;
   if (bootp->TIMEOUT > BOOTP_TIMEOUT_MAX) {
      bootp->TIMEOUT = BOOTP_TIMEOUT_MAX;
   } /* Endif */

   /* Put the BOOTREQUEST in the PCB */
   RTCSPCB_append_fragment(pcb_ptr, sizeof(BOOTP_HEADER), (uchar_ptr)&bootp->PACKET);
   RTCSPCB_append_fragment(pcb_ptr, sizeof(BOOTP_DATA),   parms->data->SNAME);

   RTCSLOG_PCB_WRITE(pcb_ptr, RTCS_LOGCTRL_PORT(IPPORT_BOOTPC), 0);

   /* Send the datagram */
   BOOT_send(pcb_ptr, if_ptr);

   /* Always retransmit */
   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : BOOTP_service
* Returned Values : void
* Comments        :
*     Services a BOOTREPLY packet.
*
*END*-----------------------------------------------------------------*/

void BOOTP_service
   (
      RTCSPCB_PTR    rtcs_pcb     /* [IN] BOOTREPLY packet */
   )
{ /* Body */
   IP_IF_PTR               if_ptr = (IP_IF_PTR)rtcs_pcb->IFSRC;
   TCPIP_PARM_BOOTP _PTR_  parms = (TCPIP_PARM_BOOTP _PTR_)if_ptr->BOOT;
   BOOTP_CFG_PTR           bootp = (BOOTP_CFG_PTR) &parms->config;
   BOOTP_PACKET_PTR        bootreply;
   IPIF_PARM               parms_bind;
   uint_32                 error;

   uchar_ptr   opt;
   uchar       len, optval, optlen;

   /* Make sure the datagram is large enough */
   bootreply = (BOOTP_PACKET_PTR)RTCSPCB_DATA(rtcs_pcb);
   if (RTCSPCB_SIZE(rtcs_pcb) < sizeof(BOOTP_PACKET)) {
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
      RTCSPCB_free(rtcs_pcb);
      return;
   } /* Endif */

   /* Make sure the XID matches */
   if (ntohl(bootreply->HEAD.XID) != bootp->XID) {
      RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
      RTCSPCB_free(rtcs_pcb);
      return;
   } /* Endif */

   RTCSLOG_PCB_READ(rtcs_pcb, RTCS_LOGCTRL_PORT(IPPORT_BOOTPC), 0);

   /* OK, assume this reply is for us */
   BOOTP_close(if_ptr);

   /* Get our IP address, and pick the default netmask */
   parms_bind.ihandle = if_ptr;
   parms_bind.address = ntohl(bootreply->HEAD.YIADDR);
   parms_bind.locmask = 0xFFFFFFFFL;
   parms_bind.netmask = IN_DEFAULT_NET(parms_bind.address);
   parms_bind.probe = FALSE;

   parms->data->SADDR = ntohl(bootreply->HEAD.SIADDR);
#if RTCSCFG_BOOTP_RETURN_YIADDR
   parms->data->CLIENTADDR = ntohl(bootreply->HEAD.YIADDR);
#endif
   _mem_copy(bootreply->DATA.SNAME, parms->data->SNAME, sizeof(BOOTP_DATA));
   RTCSLOG_PCB_FREE(rtcs_pcb, RTCS_OK);
   RTCSPCB_free(rtcs_pcb);

   /* Parse the vend field for recognized options */
   opt = parms->data->OPTIONS;
   len = sizeof(parms->data->OPTIONS);
   if (ntohl(opt) == BOOTP_MAGIC) {
      opt += 4;
      len -= 4;

#define BOOTP_NEXTOPT   opt += optlen; \
                        break

      while (len) {

         /* Get the next option code */
         optval = ntohc(opt);
         opt++;
         len--;

         /* Interpret the pad and end options */
         if (optval == BOOTPOPT_END) break;
         if (optval == BOOTPOPT_PAD) continue;

         /* All other codes have a length byte */
         if (len == 0) break;
         optlen = ntohc(opt);
         opt++;
         len--;
         if (len < optlen) break;
         len -= optlen;

         switch (optval) {

         case BOOTPOPT_MASK:
            if (optlen != 4) {BOOTP_NEXTOPT;}
            parms_bind.netmask = ntohl(opt);
            opt += 4;
            break;

         default:
            BOOTP_NEXTOPT;
         } /* Endswitch */

      } /* Endwhile */
   } /* Endif */

   /* Bind the received IP address to this interface */
   error = RTCSCMD_internal(parms_bind, IPIF_bind);

   /* Done -- unblock the application */
   RTCSCMD_complete(parms, error);

} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/common/usb_class.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_class.c$
* $Version : 3.8.6.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
* @brief The file contains USB stack Class module implimentation.
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_class.h"
#include "devapi.h"
#include "usb_framework.h"

/*****************************************************************************
 * Constant and Macro's
 *****************************************************************************/


/****************************************************************************
 * Global Variables
 ****************************************************************************/
static USB_CLASS_OBJECT_STRUCT_PTR usb_class_object[USB_MAX_CLASS_OBJECT];
/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes 
 *****************************************************************************/
static void USB_Suspend_Service (PTR_USB_EVENT_STRUCT event,pointer arg ); 
static void USB_Resume_Service (PTR_USB_EVENT_STRUCT event,pointer arg );
static void USB_Stall_Service (PTR_USB_EVENT_STRUCT event, pointer arg);
static void USB_Sof_Service (PTR_USB_EVENT_STRUCT event, pointer arg);
static void USB_Reset_Service (PTR_USB_EVENT_STRUCT event ,pointer arg);
static void USB_Error_Service (PTR_USB_EVENT_STRUCT event ,pointer arg);
/*****************************************************************************
 * Local Variables 
 *****************************************************************************/ 
 
 /*****************************************************************************
 * Local Functions - None
 *****************************************************************************/

/*****************************************************************************
 * Global Functions
 *****************************************************************************/

 /*************************************************************************//*!
 *
 * @name  USB_Class_Allocate_Handle
 *
 * @brief The funtion reserves entry in device array and returns the index.
 *
 * @param none.
 * @return returns the reserved handle or if no entry found device busy.      
 *
 *****************************************************************************/
static USB_CLASS_HANDLE  USB_Class_Allocate_Handle()
{
    int cnt = 0;
    for (;cnt< USB_MAX_CLASS_OBJECT;cnt++)
    {
       if (usb_class_object[cnt] == NULL)
        return cnt;
    }
    return USBERR_DEVICE_BUSY;
}

 /*************************************************************************//*!
 *
 * @name  USB_Class_Free_Handle
 *
 * @brief The funtion releases entry in device array .
 *
 * @param handle  index in device array to be released..
 * @return returns and error code or USB_OK.      
 *
 *****************************************************************************/

static int_32 USB_Class_Free_Handle(USB_CLASS_HANDLE handle)
{
    if ((handle < 0) || (handle > USB_MAX_CLASS_OBJECT))
        return USBERR_ERROR;
    
    USB_mem_free((void *)usb_class_object[handle]);
    usb_class_object[handle] = NULL;
    return USB_OK;
}
 /*************************************************************************//*!
 *
 * @name  Get_Usb_Class_Object_Ptr
 *
 * @brief The funtion gets the class object pointer from class array .
 *
 * @param handle  index in class object array.
 * @return returns returns pointer to USB Class Object structure..      
 *
 *****************************************************************************/
static USB_CLASS_OBJECT_STRUCT_PTR Get_Usb_Class_Object_Ptr(USB_CLASS_HANDLE handle)
{
     return usb_class_object[handle]; 
}
/**************************************************************************//*!
 *
 * @name  USB_Suspend_Service
 *
 * @brief The funtion is called when host suspends the USB port
 *
 * @param event:        for Service callback function     
 *
 * @return None       
 *****************************************************************************/
static void USB_Suspend_Service (PTR_USB_EVENT_STRUCT event,pointer arg )
{    
    UNUSED_ARGUMENT(event)
    UNUSED_ARGUMENT(arg)
    return;
}

/**************************************************************************//*!
 *
 * @name  USB_Resume_Service
 *
 * @brief The funtion is called when host resumes the USB port
 *
  * @param event:        for Service callback function     
 *
 * @return None       
 *****************************************************************************/
static void USB_Resume_Service (PTR_USB_EVENT_STRUCT event,pointer arg )
{    
    UNUSED_ARGUMENT(event)
    UNUSED_ARGUMENT(arg)
    return;
}

/**************************************************************************//*!
 *
 * @name  USB_Stall_Service
 *
 * @brief The funtion is called when endpoint is stalled
 *
  * @param event:        for Service callback function     
 *
 * @return None       
 *****************************************************************************/
static void USB_Stall_Service (PTR_USB_EVENT_STRUCT event,pointer arg )
{
    UNUSED_ARGUMENT(arg)       
    /* need to unstall control endpoint immediately. For other endpoint 
       types there will be class specific request to unstall or a reset*/                   
    if(event->ep_num == USB_CONTROL_ENDPOINT)
    {
        /* incase of error Stall endpoint and update the status*/        
        (void)_usb_device_set_status(event->handle,
            (uint_8)(event->ep_num|USB_STATUS_ENDPOINT),
            (uint_16)USB_STATUS_IDLE);
    }
    return;
}

/**************************************************************************//*!
 *
 * @name  USB_Sof_Service
 *
 * @brief The funtion is called when sof flag is set (from ISR)
 *
 * @param event:        for Service callback function     
 *
 * @return None       
 *****************************************************************************/
static void USB_Sof_Service (PTR_USB_EVENT_STRUCT event,pointer arg )
{
    uint_16 sof_count = 0;
    UNUSED_ARGUMENT(arg)
    
    /* update SOF */
    sof_count = event->buffer_ptr[0];
    sof_count <<= SOF_HIGH_BYTE_SHIFT;
    sof_count |= event->buffer_ptr[1];
     
    /* write SOF to status */
    (void)_usb_device_set_status(event->handle, 
        (uint_8)USB_STATUS_SOF_COUNT,
        (uint_16)sof_count);
    return; 
}
 

/**************************************************************************//*!
 *
 * @name  USB_Reset_Service
 *
 * @brief The funtion is called upon a bus reset event.  
              Initialises the control endpoint.
 *
 * @param event:        for Service callback function     
 *
 * @return None       
 *****************************************************************************/
static void USB_Reset_Service(PTR_USB_EVENT_STRUCT event,/*[IN]*/
pointer arg/*[IN]*/
)
{    
    USB_EP_STRUCT ep_struct;
    USB_CLASS_OBJECT_STRUCT_PTR class_object_ptr;
    uint_8 component;
    
    class_object_ptr = (USB_CLASS_OBJECT_STRUCT_PTR)arg;

    if (NULL == class_object_ptr)
    {
        #if _DEBUG
            printf("RESET SERVICE ERROR: Class not intialized.\n");
        #endif  
        return;
    }

    /* Initialize the endpoint 0 in both directions */
    ep_struct.direction = USB_RECV;
    ep_struct.ep_num = USB_CONTROL_ENDPOINT;
    ep_struct.size = CONTROL_MAX_PACKET_SIZE;
    ep_struct.type = USB_CONTROL_PIPE;

    (void)_usb_device_init_endpoint(event->handle, &ep_struct, TRUE);
    component = (uint_8)(ep_struct.ep_num | 
        (USB_RECV << COMPONENT_PREPARE_SHIFT));
    /* set the EndPoint Status as Idle in the device layer */
    (void)_usb_device_set_status(event->handle,
        (uint_8)(USB_STATUS_ENDPOINT|component), 
        (uint_16)USB_STATUS_IDLE);    
    
    ep_struct.direction = USB_SEND;   
    (void)_usb_device_init_endpoint(event->handle, &ep_struct, TRUE);
    component = (uint_8)(ep_struct.ep_num | 
        (uint_8)(USB_SEND << COMPONENT_PREPARE_SHIFT));
    /* set the EndPoint Status as Idle in the device layer */
    (void)_usb_device_set_status(event->handle,
        (uint_8)(USB_STATUS_ENDPOINT|component), 
        (uint_16)USB_STATUS_IDLE);    
    
    /* let the application know that bus reset has taken place */
    if (class_object_ptr->class_callback!=NULL)
    {
        class_object_ptr->class_callback(USB_APP_BUS_RESET,NULL,class_object_ptr->arg); 
    }

    /* set the default device state */
    (void)_usb_device_set_status(event->handle, 
        (uint_8)USB_STATUS_DEVICE_STATE, 
        (uint_16)USB_STATE_DEFAULT);
    /* set the default device state -- 
       remote wakeup field is set to zero when device is reset*/
    (void)_usb_device_set_status(event->handle, 
        (uint_8)USB_STATUS_DEVICE,                           
        (uint_16)(SELF_POWERED>>SELF_POWER_BIT_SHIFT));
                                                                      
    return;
}

/**************************************************************************//*!
 *
 * @name  USB_Error_Service
 *
 * @brief The funtion is called when an error has been detected
 *
 * @param event:        for Service callback function     
 *
 * @return None       
 *****************************************************************************/
static void USB_Error_Service (PTR_USB_EVENT_STRUCT event,/*[IN]*/
pointer arg /*[IN]*/
)
{
    USB_CLASS_OBJECT_STRUCT_PTR class_object_ptr;
    
    class_object_ptr = (USB_CLASS_OBJECT_STRUCT_PTR)arg;
    
    if (NULL == class_object_ptr)
    {
        #if _DEBUG
            printf("ERROR SERVICE ERROR: Class not intialized.\n");
        #endif  
        return;
    }

    /* notify the application of the error */
    if (class_object_ptr->class_callback!=NULL)
        class_object_ptr->class_callback(USB_APP_ERROR,event->buffer_ptr,class_object_ptr->arg);
    return; 
}

/**************************************************************************//*!
 *
 * @name  USB_Class_Init
 *
 * @brief The funtion initializes the Class Module 
 *
 * @param handle             :handle to Identify the controller
 * @param class_callback     :event callback      
 * @param other_req_callback :call back for class/vendor specific requests on 
 *                            CONTROL ENDPOINT
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
USB_CLASS_HANDLE USB_Class_Init
(
    _usb_device_handle handle, /* [IN] the USB device controller to initialize */                  
    USB_CLASS_CALLBACK class_callback,/*[IN]*/
    USB_REQ_FUNC       other_req_callback,/*[IN]*/
    pointer user_arg,/*[IN]*/
    DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr/*[IN]*/
 ) 
{
    USB_CLASS_HANDLE  class_handle;
    USB_CLASS_OBJECT_STRUCT_PTR class_object_ptr = NULL;
    
    class_object_ptr = (USB_CLASS_OBJECT_STRUCT_PTR)USB_mem_alloc_zero(
        sizeof(USB_CLASS_OBJECT_STRUCT));
    if (NULL == class_object_ptr)
    {
        #if _DEBUG
            printf("USB_Class_Init: Memalloc failed\n");
        #endif  
        return USBERR_ALLOC;
    }
    
    class_handle = USB_Class_Allocate_Handle();
    if (USBERR_DEVICE_BUSY == class_handle) 
    {
        USB_mem_free((void*)class_object_ptr);
        class_object_ptr = NULL;
        return USBERR_DEVICE_BUSY;
    }
        
    class_object_ptr->controller_handle = handle;
    class_object_ptr->class_callback = class_callback;
    class_object_ptr->arg = user_arg;
       
    /* Store Framework handle for later use from callbacks*/    
    class_object_ptr->usb_fw_handle = USB_Framework_Init(handle, class_callback,
        other_req_callback, user_arg, class_handle,desc_callback_ptr);

    if(class_object_ptr->usb_fw_handle != USBERR_ERROR) 
    {   /* Register all the services here */  
        _usb_device_register_service(handle,
            USB_SERVICE_BUS_RESET, USB_Reset_Service,(void *)class_object_ptr);
        _usb_device_register_service(handle,
            USB_SERVICE_SOF,USB_Sof_Service,(void *)class_object_ptr);
        _usb_device_register_service(handle,
            USB_SERVICE_SLEEP,USB_Suspend_Service,(void *)class_object_ptr);
        _usb_device_register_service(handle,
            USB_SERVICE_RESUME,USB_Resume_Service,(void *)class_object_ptr);
        _usb_device_register_service(handle,
            USB_SERVICE_STALL,USB_Stall_Service,(void *)class_object_ptr);    
        _usb_device_register_service
            (handle, USB_SERVICE_ERROR,USB_Error_Service,(void *)class_object_ptr);
        /* set the device state as powered */
        (void)_usb_device_set_status(handle,
            (uint_8)USB_STATUS_DEVICE_STATE, 
            (uint_16)USB_STATE_POWERED);
    }  
    
    usb_class_object[class_handle] = class_object_ptr;     
    return class_handle;     
}

/**************************************************************************//*!
 *
 * @name  USB_Class_Deinit
 *
 * @brief The funtion initializes the Class Module 
 *
 * @param handle             :handle to Identify the controller
 * @param class_handle       :class handle      
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Class_Deinit
(
    _usb_device_handle handle, /* [IN] the USB device controller to initialize */                  
    USB_CLASS_HANDLE  class_handle
 ) 
{
    USB_CLASS_OBJECT_STRUCT_PTR class_object_ptr = NULL;
    uint_8 error = USB_OK;
    class_object_ptr = Get_Usb_Class_Object_Ptr(class_handle);
    /* call USB_Framework_Deinit */
    error = USB_Framework_Deinit(handle,class_object_ptr->usb_fw_handle);
    /* Unregister all the services */ 
    if(error == USB_OK)
    error = _usb_device_unregister_service(handle,USB_SERVICE_BUS_RESET);
    if(error == USB_OK)
    error = _usb_device_unregister_service(handle,USB_SERVICE_SOF);
    if(error == USB_OK)
    error = _usb_device_unregister_service(handle,USB_SERVICE_SLEEP);
    if(error == USB_OK)
    error = _usb_device_unregister_service(handle,USB_SERVICE_RESUME);
    if(error == USB_OK)
    error = _usb_device_unregister_service(handle,USB_SERVICE_STALL);  
    if(error == USB_OK)
    error = _usb_device_unregister_service(handle,USB_SERVICE_ERROR);
    if(error == USB_OK)
    /* set the device state as USB_STATE_DEFAULT */
    error = _usb_device_set_status(handle,
		     (uint_8)USB_STATUS_DEVICE_STATE, 
		     (uint_16)USB_STATE_DEFAULT);
    if(error == USB_OK)
    /* free the USB class handle */
    error = USB_Class_Free_Handle(class_handle); 
    return error;     
}

/**************************************************************************//*!
 *
 * @name  USB_Class_Send_Data
 *
 * @brief The funtion calls the device to send data upon recieving an IN token 
 *
 * @param handle:               handle to Identify the controller
 * @param ep_num:               The endpoint number     
 * @param buff_ptr:             buffer to send
 * @param size:                 length of transfer
 * 
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *
 *****************************************************************************/
uint_8 USB_Class_Send_Data
(
    USB_CLASS_HANDLE handle, /*[IN]*/
    uint_8 ep_num,        /* [IN] the Endpoint number */                  
    uint_8_ptr buff_ptr,      /* [IN] buffer to send */      
    uint_32 size           /* [IN] length of the transfer */
) 
{
    uint_8 error = USB_OK;
    uint_16 device_state, state;
    USB_CLASS_OBJECT_STRUCT_PTR class_object_ptr;   
    
    class_object_ptr = Get_Usb_Class_Object_Ptr(handle); 
    if (NULL == class_object_ptr) 
        return USBERR_ERROR;

    (void)_usb_device_get_status(class_object_ptr->controller_handle, 
        (uint_8)USB_STATUS_DEVICE_STATE, &device_state);
    
    (void)_usb_device_get_status(class_object_ptr->controller_handle, 
        (uint_8)USB_STATUS_DEVICE, &state);
    
    
    if((device_state == USB_STATE_SUSPEND) 
        && (state & REMOTE_WAKEUP_STATUS_MASK) 
        && (USB_Framework_Remote_wakeup(class_object_ptr->usb_fw_handle) == TRUE))
    {        
        _int_disable();       
        /* Resume the bus */         
        (void)_usb_device_assert_resume(class_object_ptr->controller_handle);           
        
        device_state = USB_STATE_CONFIG; 
        /* Set the device state in the Device Layer to DEFAULT */
        (void)_usb_device_set_status(class_object_ptr->controller_handle,
            (uint_8)USB_STATUS_DEVICE_STATE,
            (uint_16)USB_STATE_CONFIG);                      
        _int_enable();
    }
    if(device_state != USB_STATE_SUSPEND) 
    {    /* if not suspended */ 
    
         error = _usb_device_send_data(class_object_ptr->controller_handle,
            ep_num,buff_ptr,size);
    }

    return error;      
}
 
/**************************************************************************//*!
 *
 * @name   USB_Class_Periodic_Task
 *
 * @brief  The funtion calls for periodic tasks 
 *
 * @param  None
 *
 * @return None
 *
 *****************************************************************************/
void USB_Class_Periodic_Task(void) 
{
    #ifdef DELAYED_PROCESSING  
        USB_Framework_Periodic_Task();
    #endif  
}
/**************************************************************************//*!
 *
 * @name  USB_Class_Get_Desc
 *
 * @brief  This function is called in to get the discriptor as specified in cmd.
 *
 * @param handle:           USB class handle. Received from
 *                          USB_Class_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param in_buff           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Class_Get_Desc(USB_CLASS_HANDLE handle,/*[IN]*/
int_32 cmd,/*[IN]*/
uint_8 input_data,/*[IN]*/
uint_8_ptr *in_buf /*[OUT]*/
)
{
   USB_CLASS_OBJECT_STRUCT_PTR class_obj_ptr;
    
   if ((handle < 0)||(handle > USB_MAX_CLASS_OBJECT))
      return USBERR_ERROR;
   
   class_obj_ptr = Get_Usb_Class_Object_Ptr(handle);
   if (class_obj_ptr == NULL)
        return USBERR_ERROR;
   
   return USB_Framework_GetDesc(class_obj_ptr->usb_fw_handle,cmd,input_data,in_buf);
            
}
/**************************************************************************//*!
 *
 * @name  USB_Class_Set_Desc
 *
 * @brief  This function is called in to Set the discriptor as specified in cmd.
 *
 * @param handle:           USB class handle. Received from
 *                          USB_Class_Init      
 * @param cmd:              command for USB discriptor to get.
 * @param in_data:          input to the Application functions.
 * @param in_buff           buffer which will contian the discriptors.
 * @return status:       
 *                        USB_OK : When Successfull       
 *                        Others : When Error
 *
 *****************************************************************************/
uint_8 USB_Class_Set_Desc(USB_CLASS_HANDLE handle,/*[IN]*/
int_32 cmd,/*[IN]*/
uint_8 input_data,/*[IN]*/
uint_8_ptr *out_buf /*[IN]*/
)
{
   USB_CLASS_OBJECT_STRUCT_PTR class_obj_ptr;
    
   if ((handle < 0)||(handle > USB_MAX_CLASS_OBJECT))
      return USBERR_ERROR;
   
   class_obj_ptr = Get_Usb_Class_Object_Ptr(handle);
   if (class_obj_ptr == NULL)
        return USBERR_ERROR;
   
   return USB_Framework_SetDesc(class_obj_ptr->usb_fw_handle,cmd,input_data,out_buf);
            
}

/* EOF */



<|start_filename|>Firmware/Inverter_bootloader/USB_DRIVER/usb_driver.c<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/ /*!
 *
 * @file usb_driver.c
 *
 * @author
 *
 * @version
 *
 * @date
 *
 * @brief The file contains S08 USB stack device layer implementation.
 *
 *****************************************************************************/
/******************************************************************************
* Includes
*****************************************************************************/
#include "string.h"
#include "usb_devapi.h" /* USB Device Layer API Header File */
#include "usb_dciapi.h" /* USB Controller API Header File */
/*****************************************************************************
* Constant and Macro's
*****************************************************************************/
/****************************************************************************
* Global Variables
****************************************************************************/
/* Array of USB Service pointers */
static USB_SERVICE_CALLBACK g_usb_CB[USB_SERVICE_MAX];
/* Array of USB Component Status */
/* Test mode is the last service */
static INT16U g_usb_component_status[USB_STATUS_TEST_MODE];
/* Array of USB Endpoint Status */
static INT16U g_usb_ep_status[MAX_SUPPORTED_ENDPOINTS];
/* Current un-initialized non CONTROL Endpoint */
static INT8U g_EPn = 0;
/* Maximum number of Non CONTROL Endpoint required by upper layer */
static INT8U g_EPn_max = 0;
/*****************************************************************************
* Local Types - None
*****************************************************************************/
/*****************************************************************************
* Local Functions Prototypes - None
*****************************************************************************/
static void USB_Device_Init_Params(void);
/*****************************************************************************
* Local Variables - None
*****************************************************************************/
extern INT8U USB_DCI_DeInit(void); /*FSL: new!*/
/*****************************************************************************
* Local Functions 
*****************************************************************************/
#if (defined(_MC9S08MM128_H) || defined(_MC9S08JE128_H))
  #pragma CODE_SEG DEFAULT
#endif
/**************************************************************************/ /*!
 *
 * @name  USB_Device_Init_Params
 *
 * @brief The funtion initializes the Device Layer Structures
 *
 * @param  None
 *
 * @return None
 *
 ******************************************************************************
 * Initializes USB Device Layer Structures
 *****************************************************************************/
static void USB_Device_Init_Params(void)
{
  
  INT8U loop_index = 0;
  g_EPn = g_EPn_max; /* 1 control endpoint */
  /* 
  Initialize USB_STATUS_DEVICE_STATE, USB_STATUS_INTERFACE,
  USB_STATUS_ADDRESS, USB_STATUS_CURRENT_CONFIG, USB_STATUS_SOF_COUNT
  and USB_STATUS_DEVICE to USB_STATUS_UNKNOWN 
  */
  for (loop_index = 0; loop_index < USB_STATUS_TEST_MODE; loop_index++)
  {
#ifdef OTG_BUILD
    if ( loop_index != (USB_STATUS_OTG - 1) ) /* Do not initialize the OTG status with 0xFFFF */
#endif
    {
      g_usb_component_status[loop_index] = USB_STATUS_UNKNOWN;
    } 
  } 
  /* Initialize status of All Endpoints to USB_STATUS_DISABLED */
  for (loop_index = 0; loop_index < MAX_SUPPORTED_ENDPOINTS; loop_index++)
  {
    g_usb_ep_status[loop_index] = USB_STATUS_DISABLED;
  } 
} 
/*****************************************************************************
* Global Functions
*****************************************************************************/
/**************************************************************************/ /*!
 *
 * @name  USB_Devie_Init
 *
 * @brief The funtion initializes the Device and Controller layer
 *
 * @param controller_ID : Controller ID
 * @param endpoints     : Endpoint count of the application
 *
 * @return status
 *         USB_OK                              : When Successfull
 *         USBERR_INVALID_NUM_OF_ENDPOINTS     : When endpoints > max Supported
 ******************************************************************************
 * This function initializes the Device layer and the Controller layer of the
 * S08 USB stack. It initialised the variables used for this layer and then
 * calls the controller layer initialize function
 *****************************************************************************/
INT8U USB_Device_Init
(
 INT8U    controller_ID, /* [IN] Controller ID */
 INT8U    endpoints      /* [IN] Endpoint count of the application */
 )
{
  
  /* validate endpoints param */
  if ( (endpoints > MAX_SUPPORTED_ENDPOINTS) || (endpoints < MIN_SUPPORTED_ENDPOINTS) )
  {
    return USBERR_INVALID_NUM_OF_ENDPOINTS;
  } 
  /*init variables */
  g_EPn_max = (INT8U)(endpoints - 1);
  USB_Device_Init_Params();
  /* Initialize all services to null value */
  Clear_Mem((INT8U_ptr)g_usb_CB, (sizeof(USB_SERVICE_CALLBACK) * USB_SERVICE_MAX), (INT8U)NULL);
  /* Call controller layer initialization function */
  return USB_DCI_Init(controller_ID);
} 
/**************************************************************************/ /*!
 *
 * @name  USB_Devie_DeInit
 *
 * @brief The funtion de-initializes the Device and Controller layer
 *
 * @param controller_ID : Controller ID
 *
 * @return status
 *         USB_OK                              : When Successfull
 *         USBERR_INVALID_NUM_OF_ENDPOINTS     : When endpoints > max Supported
 ******************************************************************************
 * This function de-initializes the Device layer and the Controller layer
 *****************************************************************************/
INT8U USB_Device_DeInit(void)
{
  
  g_EPn_max = 0;
  /* Call controller layer de-initialization function */
  return USB_DCI_DeInit();
} 
/**************************************************************************/ /*!
 *
 * @name  USB_Device_Init_EndPoint
 *
 * @brief The funtion initializes the endpoint
 *
 * @param controller_ID : Controller ID
 * @param ep_ptr        : Pointer to endpoint detail structure
 * @param flag          : Zero termination flag
 *
 * @return status
 *         USB_OK                              : When Successfull
 *         USBERR_EP_INIT_FAILED     : When endpoints > max Supported
 ******************************************************************************
 *
 * This function initializes an endpoint the Device layer and the Controller
 * layer in the S08 USB stack. It validate whether all endpoints have already
 * been initialized or not and then calls the controller layer endpoint
 *  initialize function
 *
 *****************************************************************************/
INT8U USB_Device_Init_EndPoint
(
 INT8U               controller_ID, /* [IN] Controller ID */
 USB_EP_STRUCT_PTR    ep_ptr,        /* [IN] Pointer to endpoint detail
                                             structure */
 INT8U               flag           /* [IN] Zero termination flag */
 )
{
  
  INT8U status = USB_OK;
  /* check if all endpoint have already been initialised */
  if ( (g_EPn == 0) && (ep_ptr->ep_num != CONTROL_ENDPOINT) )
  {
    return USBERR_EP_INIT_FAILED;
  } 
  /* call controller layer for initiazation */
  status = USB_DCI_Init_EndPoint(controller_ID, ep_ptr, flag);
  /* if endpoint successfully initialised update counter */
  if ( (ep_ptr->ep_num != CONTROL_ENDPOINT) && (status == USB_OK) )
  {
    g_EPn--;
  } 
  return status;
} 
/**************************************************************************/ /*!
 *
 * @name  USB_Device_Deinit_EndPoint
 *
 * @brief The funtion De-initializes the endpoint
 *
 * @param controller_ID : Controller ID
 * @param ep_ptr        : Pointer to endpoint detail structure
 * @param flag          : Zero termination flag
 *
 * @return status
 *         USB_OK                              : When Successfull
 *         USBERR_EP_DEINIT_FAILED     : When endpoints > max Supported
 ******************************************************************************
 *
 * This function deinitializes an endpoint the Device layer and the Controller
 * layer in the S08 USB stack. It validate whether all endpoints have already
 * been deinitialized or not and then calls the controller layer endpoint
 * deinitialize function
 *
 *****************************************************************************/
INT8U USB_Device_Deinit_EndPoint
(
 INT8U    controller_ID,  /* [IN] Controller ID */
 INT8U    ep_num,         /* [IN] Endpoint number */
 INT8U    direction       /* [IN] Direction */
 )
{
  
  INT8U status = USB_OK;
  /* check if all endpoint have already been initialised */
  if ( (g_EPn == g_EPn_max) && (ep_num != CONTROL_ENDPOINT) )
  {
    return USBERR_EP_DEINIT_FAILED;
  } 
  /* call controller layer for initiazation */
  status = USB_DCI_Deinit_EndPoint(controller_ID, ep_num, direction);
  /* if endpoint successfully deinitialised update counter */
  if ( (ep_num != CONTROL_ENDPOINT) && (status == USB_OK) )
  {
    g_EPn++;
  } 
  return status;
} 
/**************************************************************************/ /*!
 *
 * @name  USB_Device_Get_Status
 *
 * @brief The funtion retrieves various endpoint as well as USB component status
 *
 * @param controller_ID : Controller ID
 * @param component     : USB component
 * @param status        : Pointer to 16 bit return value
 *
 * @return status
 *         USB_OK                : When Successfull
 *         USBERR_BAD_STATUS     : When error
 *
 ******************************************************************************
 * This function retrieves the endpoint as well USB component status which is
 * stored by calling USB_Device_Set_Status. This function can be called by Ap-
 * plication as well as the DCI layer.
 *****************************************************************************/
INT8U USB_Device_Get_Status
(
 INT8U        controller_ID,  /* [IN]  Controller ID  */
 INT8U        component,      /* [IN]  USB component */
 INT16U_ptr   status          /* [OUT] Pointer to 16 bit return value */
 )
{
  
  /* get the endpoint number from component input variable */
  INT8U ep_num = (INT8U)(component & USB_STATUS_ENDPOINT_NUMBER_MASK);
  UNUSED(controller_ID)
  if ( (component <= USB_STATUS_TEST_MODE) && (component >= USB_STATUS_DEVICE_STATE) )
  {
    /* Get the corresponding component status
    -1 as components start from 1 */
    *status = g_usb_component_status[component - 1];
  }
  else if ( (component & USB_STATUS_ENDPOINT) && (ep_num < MAX_SUPPORTED_ENDPOINTS) )
  {
    /* Get the corresponding endpoint status */
    *status = g_usb_ep_status[ep_num];
  }
  else
  {
    return USBERR_BAD_STATUS;
  } 
  return USB_OK;
} 
/**************************************************************************/ /*!
 *
 * @name  USB_Device_Set_Status
 *
 * @brief The funtion saves status of endpoints as well as USB components.
 *
 * @param controller_ID : Controller ID
 * @param component     : USB component
 * @param setting       : Value to be set
 *
 * @return status
 *         USB_OK                : When Successfull
 *         USBERR_BAD_STATUS     : When error
 *
 ******************************************************************************
 * This function sets the endpoint as well USB component status which can be
 * retrieved by calling USB_Device_Get_Status. This function can be called by
 * Application as well as the DCI layer.
 *****************************************************************************/
INT8U USB_Device_Set_Status
(
 INT8U    controller_ID,  /* [IN] Controller ID */
 INT8U    component,      /* [IN] USB component */
 INT16U   setting         /* [IN] Value to be set */
 )
{
  
  /* get the endpoint number from component input variable */
  INT8U ep_num = (INT8U)(component & USB_STATUS_ENDPOINT_NUMBER_MASK);
  UNUSED(controller_ID)
  if ( (component <= USB_STATUS_TEST_MODE) && (component >= USB_STATUS_DEVICE_STATE) )
  {
    /* 
    Set the corresponding component setting
    -1 as components start from 1 
    */
    g_usb_component_status[component - 1] = setting;
  }
  else if ( (component & USB_STATUS_ENDPOINT) && (ep_num < MAX_SUPPORTED_ENDPOINTS) )
  {
    INT8U direction = (INT8U)((component >> USB_COMPONENT_DIRECTION_SHIFT) & USB_COMPONENT_DIRECTION_MASK);
    /* HALT Endpoint */
    if ( setting == USB_STATUS_STALLED )
    {
      USB_Device_Stall_EndPoint(controller_ID, ep_num, direction);
    }
    else if ( (setting == USB_STATUS_IDLE) && (g_usb_ep_status[ep_num] == USB_STATUS_STALLED) )
    {
      USB_Device_Unstall_EndPoint(controller_ID, ep_num, direction);
      if ( ep_num == CONTROL_ENDPOINT )
      {
        direction = (INT8U)((direction == USB_SEND) ? (USB_RECV) : (USB_SEND));
        USB_Device_Unstall_EndPoint(controller_ID, ep_num, direction);
      } 
    } 
    /* Set the corresponding endpoint setting */
    g_usb_ep_status[ep_num] = setting;
  }
  else
  {
    return USBERR_BAD_STATUS;
  } 
  return USB_OK;
} 
/**************************************************************************/ /*!
 *
 * @name  USB_Device_Register_Service
 *
 * @brief The funtion registers a callback function from the Application layer
 *
 * @param controller_ID : Controller ID
 * @param type          : event type or endpoint number
 * @param service       : callback function pointer
 *
 * @return status
 *         USB_OK                   : When Successfull
 *         USBERR_ALLOC_SERVICE     : When invalid type or already registered
 *
 ******************************************************************************
 * This function registers a callback function from the application if it is
 * called not already registered so that the regitered callback function can
 * be if the event of that type occurs
 *****************************************************************************/
INT8U USB_Device_Register_Service
(
 INT8U                    controller_ID, /* [IN] Controller ID           */
 INT8U                    type,          /* [IN] type of event or endpoint number to service       */
 USB_SERVICE_CALLBACK     service        /* [IN] pointer to callback function                */
 )
{
  
  UNUSED(controller_ID)
  /* check if the type is valid and callback for the type
  is not already registered */
  if ( ((type  <= USB_SERVICE_MAX_EP) ||((type < USB_SERVICE_MAX) && (type >= USB_SERVICE_BUS_RESET))) &&(g_usb_CB[type] == NULL) )
  {
    /* register the callback function */
    g_usb_CB[type] = service;
    return USB_OK;
  }
  else
  {
    return USBERR_ALLOC_SERVICE;
  } 
} 
/**************************************************************************/ /*!
 *
 * @name  USB_Device_Unregister_Service
 *
 * @brief The funtion unregisters an event or endpoint callback function
 *
 * @param controller_ID : Controller ID
 * @param type          : event type or endpoint number
 *
 * @return status
 *         USB_OK                   : When Successfull
 *         USBERR_UNKNOWN_ERROR     : When invalid type or not registered
 *
 *****************************************************************************
 * This function un registers a callback function which has been previously
 * registered by the application layer
 *****************************************************************************/
INT8U USB_Device_Unregister_Service
(
 INT8U controller_ID, /* [IN] Controller ID */
 INT8U type           /* [IN] type of event or endpoint number
                                 to service */
 )
{
  
  UNUSED(controller_ID)
  /* check if the type is valid and callback for the type
  is already registered */
  if ( ((type  <= USB_SERVICE_MAX_EP) ||
        ((type < USB_SERVICE_MAX) && (type >= USB_SERVICE_BUS_RESET))) &&
       (g_usb_CB[type] != NULL) )
  {
    /* unregister the callback */
    g_usb_CB[type] = NULL;
    return USB_OK;
  }
  else
  {
    return USBERR_UNKNOWN_ERROR;
  } 
} 
/**************************************************************************/ /*!
 *
 * @name  USB_Device_Call_Service
 *
 * @brief The funtion is a device layer event handler
 *
 * @param type  : Type of service or endpoint
 * @param event : Pointer to event structure
 *
 * @return status
 *         USB_OK      : Always
 *
 *****************************************************************************
 *
 * This function calls the registered service callback function of the applic-
 * ation layer based on the type of event received. This function is called
 * from the DCI layer.
 *
 *****************************************************************************/
INT8U USB_Device_Call_Service
(
 INT8U                    type,    /* [IN] Type of service or endpoint */
 PTR_USB_DEV_EVENT_STRUCT  event    /* [IN] Pointer to event structure  */
 )
{
 
  if ( type == USB_SERVICE_BUS_RESET )
  {    /* if it is an reset interrupt then reset all status structures */
    USB_Device_Init_Params();
  } 
  
  if ( g_usb_CB[type] != NULL )
  {
    
    g_usb_CB[type](event);
  } 
  return USB_OK;
} 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/Pins_control.h<|end_filename|>
#ifndef __PINS_CONTROL
  #define __PINS_CONTROL

#define LED1 1
#define LED2 2
#define LED3 3


void Led_control(int led_num, int state);
void Fun_control(int state);
int  Fun_state(void);
void IGBT_reg_control(int state);
void NTC_bypass_control(int state);
void Pin_PWM_OE_int_install(void);
void Pin_VFO_int_install(void);
int  Pin_PWM_OE_state(void);

void LCD_RST(int state);
void LCD_SCL(int state);
void LCD_SI(int state);
void LCD_RS(int state);
void LCD_SCB(int state);
#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/dns.h<|end_filename|>
#ifndef __dns_h__
#define __dns_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dns.h$
* $Version : 172.16.31.10$
* $Date    : Aug-10-2011$
*
* Comments:
*
*   Definitions for use by either the Domain Name Server
*   or Resolver.
*
*END************************************************************************/

extern void DNS_Resolver_task      (pointer, pointer);
extern void DNS_Name_Server_task   (uint_32);
extern void DNS_Stub_Resolver_task (uint_32);

/***************************************
**
** Constants
**
*/

#define DNSALLOC_SIZE                       4


#define DNS_NAME_SERVER_MODULE              1
#define DNS_FULL_RESOLVER_MODULE            2
#define DNS_STUB_RESOLVER_MODULE            3

/* maximum UDP size is 512 bytes, not counting headers */
#define DNS_MAX_PACKET_SIZE                 1024
#define DNS_MAX_UDP_MESSAGE_SIZE            512
#define DNS_MAX_IP_STRING_SIZE              16

/* maximum number of query tries for one DNS server address */
#define DNS_MAX_NUMBER_OF_QUERY_TRIES       5

/* picked 400 for now, need to find exact size that won't overflow a UDP send
   with headers, ect... SMR June 19, 1998 */
#define DNS_NULL_RECORD_SIZE                400

#define DNS_MAX_LABEL_LENGTH_ARRAY_SIZE     130
#define DNS_LAST_LABEL_ALLOWED              127
#define DNS_NAME_CONTROL_BUFFER             DNS_LAST_LABEL_ALLOWED + 1
#define DNS_NAME_LENGTH_BUFFER              DNS_MAX_LABEL_LENGTH_ARRAY_SIZE - 1
#define DNS_MAX_LABEL_LENGTH                63
#define DNS_MAX_CHARS_IN_NAME               0xFF
#define DNS_MAX_ID_CHECK                    0xFFFE
#define DNS_NAME_ADDITION_ERROR             0x00BADADD
#define DNS_MAX_ALLOWED_NAMES               30
/* one week, as required by RFC 1035 */
#define DNS_MAX_ALLOWED_TTL                 604800L
/* ten minutes as required by RFC 2308 */
#define DNS_NAME_ERROR_TTL                  600L
/*
** 4 seconds is BIND standard, but any reasonable value will do.
** This value is kept in seconds so that TTL for information
** coming in from the net can be kept in a consistant format and
** all functions can be kept common for all TTL's
*/
#define DNS_QUERY_RETRY_TIME                4L /* in seconds */
#define DNS_SERVER_RETRY_TIME               4000
#define DNS_RESOLVER_RETRY_TIME             4000
/* timeout for the response from the DNS server */
#define DNS_QUERY_TIMEOUT                   40000 

/* Name server and resolver ports and IP addresses */

#define DNS_NAMESERVER_PORT                 53
/* Start CR 2176 */
#define DNS_RESOLVER_PORT                   1024
/* End CR 2176 */

#define DNS_RESOLVER_IP_ADDR                INADDR_LOOPBACK


/* these are used to check and add to cached data */

#define DNS_NS_AUTH_DATA              1
#define DNS_NS_CACHE_DATA             2
#define DNS_RES_CACHE_DATA            3

/* RFC 1035 suggests 8 as a maximum, but it is a SHOULD item, not a MUST. */
#define DNS_MAX_NUM_CNAME_RETRIES     8

/* This is used to assign the size of a global buffer. */
#define DNS_MAX_NAMES  MAX_HOST_ALIASES
#define DNS_MAX_ADDRS  MAX_HOST_ADDRESSES


/* Error codes specific to DNS - backward compatibility */
#define DNS_QUERY_OK                        RTCSERR_DNS_QUERY_OK
#define DNS_NO_NAME_SERVER_RESPONSE         RTCSERR_DNS_NO_NAME_SERVER_RESPONSE
#define DNS_UNABLE_TO_OPEN_SOCKET           RTCSERR_DNS_UNABLE_TO_OPEN_SOCKET
#define DNS_UNABLE_TO_BIND_SOCKET           RTCSERR_DNS_UNABLE_TO_BIND_SOCKET
#define DNS_UNABLE_TO_UPDATE_ROOT_SERVERS   RTCSERR_DNS_UNABLE_TO_UPDATE_ROOT_SERVERS
#define DNS_SOCKET_RECV_ERROR               RTCSERR_DNS_SOCKET_RECV_ERROR
#define DNS_UNABLE_TO_SEND_QUERY            RTCSERR_DNS_UNABLE_TO_SEND_QUERY
#define DNS_NO_RESPONSE_FROM_RESOLVER       RTCSERR_DNS_NO_RESPONSE_FROM_RESOLVER
#define DNS_PACKET_RECEPTION_ERROR          RTCSERR_DNS_PACKET_RECEPTION_ERROR
#define DNS_INVALID_NAME                    RTCSERR_DNS_INVALID_NAME
#define DNS_INVALID_IP_ADDR                 RTCSERR_DNS_INVALID_IP_ADDR
#define DNS_ALL_SERVERS_QUERIED             RTCSERR_DNS_ALL_SERVERS_QUERIED
#define DNS_INVALID_LOCAL_NAME              RTCSERR_DNS_INVALID_LOCAL_NAME
#define DNS_UNABLE_TO_ALLOCATE_MEMORY       RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY
#define DNS_UNABLE_TO_FREE_SOCKET           RTCSERR_DNS_UNABLE_TO_FREE_SOCKET
#define DNS_VALID_IP_ADDR                   RTCSERR_DNS_VALID_IP_ADDR
#define DNS_INITIALIZATION_FAILURE          RTCSERR_DNS_INITIALIZATION_FAILURE
#define DNS_NOT_IMPLEMENTED                 RTCSERR_DNS_NOT_IMPLEMENTED
#define DNS_UNABLE_TO_CREATE_PARTITION      RTCSERR_DNS_UNABLE_TO_CREATE_PARTITION
#define DNS_SHORT_MESSAGE_ERROR             RTCSERR_DNS_SHORT_MESSAGE_ERROR


/* Any value from 64 to 255 will do if there is a conflict with these */
#define DNS_APPEND_LOCAL_NAME               0xFF
#define DNS_NOT_DOTTED_NAME_FORMAT          0xFE


/* Query Codes */

#define DNS_STANDARD_QUERY                  0x0000
#define DNS_INVERSE_QUERY                   0x0800
#define DNS_STATUS_REQUEST                  0x1000
#define DNS_RECURSION_DESIRED               0x0100

/* QDCOUNT Codes */
#define DNS_SINGLE_QUERY                    0x0001
#define DNS_DOUBLE_QUERY                    0x0002
#define DNS_TRIPLE_QUERY                    0x0003

/* ANCOUNT Codes */
#define DNS_NO_ANSWER                       0x0000
#define DNS_SINGLE_ANSWER                   0x0001
#define DNS_DOUBLE_ANSWER                   0x0002
#define DNS_TRIPLE_ANSWER                   0x0003
#define DNS_QADRUPLE_ANSWER                 0x0004

/* Response Codes  */

#define DNS_RESPONSE                        0x8000
#define DNS_RECURSION_DESIRED               0x0100
#define DNS_RECURSION_AVAILABLE             0x0080
#define DNS_AUTHORITATIVE_ANSWER            0x0400
#define DNS_TRUNCATION                      0x0200
#define DNS_NO_ERROR                        0x0000
#define DNS_FORMAT_ERROR                    0x0001
#define DNS_SERVER_FAILURE                  0x0002
#define DNS_NAME_ERROR                      0x0003
#define DNS_AUTHORITATIVE_NAME_ERROR        0x0403
#define DNS_QUERY_NOT_IMPLEMENTED           0x0004
#define DNS_QUERY_REFUSED                   0x0005

#define DNS_RCODE_MASK                      0x000F
#define DNS_OPCODE_MASK                     0x7800
#define DNS_COMPRESSED_NAME_MASK            0xC0
#define DNS_COMPRESSED_LOCATION_MASK        0x3FFF

/* These are needed for the TI board */
#define DNS_UINT_16_MASK                    0xFFFF
#define DNS_CHAR_MASK                       0xFF

/* TYPE and QTYPE definitions [RFC 1035] -- all TYPES are valid QTYPES
   Those marked EXPERIMENTAL or OBSOLETE should never be sent,
   however provisions should be made in case they are received  */


/* Class specific TYPES */

#define DNS_A          0x0001   /* A host address */
#define DNS_MD         0x0003   /* Mail Destination (OBSOLETE) */
#define DNS_MF         0x0004   /* Mail Forward     (OBSOLETE) */
#define DNS_MB         0x0007   /* Mailbox Domain Name (EXPERIMENTAL) */
#define DNS_MG         0x0008   /* Mail Group Member (EXPERIMENTAL) */
#define DNS_MR         0x0009   /* Mail Rename Domain Name (EXPERIMENTAL) */
#define DNS_NULL       0x000A   /* Null Resource Record */
#define DNS_WKS        0x000B   /* Service Description */
#define DNS_HINFO      0x000D   /* Host information */
#define DNS_MINFO      0x000E   /* Mailbox or mail list information */
#define DNS_MX         0x000F   /* Mail Exchange */
#define DNS_TXT        0x0010   /* Text Strings */

/* Types to be used by all classes */
#define DNS_NS         0x0002   /* Authoritative name server */
#define DNS_SOA        0x0006   /* Start of Zone of Authority */
#define DNS_CNAME      0x0005   /* Canonical Name for an alias */
#define DNS_PTR        0x000C   /* Domain name pointer */

/* QTYPES */

#define DNS_AXFR       0x00FC   /* Request for transfer of entire zone */
#define DNS_MAILB      0x00FD   /* Request for mailbox related records */
#define DNS_MAILA      0x00FE   /* Request for mail agent RR's (OBSOLETE) */

/* This is used for both QTYPE and QCLASS definitions */
#define DNS_ALL        0x00FF   /* Request for all records or for all classes */


/* CLASS values */

#define DNS_IN         0x0001   /* The Internet */
#define DNS_CS         0x0002   /* CSNET Class   (OBSOLETE) */
#define DNS_CH         0x0003   /* CHAOS Class  */
#define DNS_HS         0x0004   /* Hessoid [Dyer 87] */


#define DNS_RESERVED_CLASS 0xFFFF

 /***************************************
**
** Structure Definitions
**
*/


/*
**  Resource Record Header Structure
*/

typedef struct dns_rr_header {
   uint_32                       LAST_TTL_CHECK;
   struct dns_rr_header   _PTR_  NEXT;
   uchar _PTR_                   DOMAIN_NAME_PTR;
   int_32                        TTL;
   uint_16                       CLASS;
   uint_16                       TYPE;

}DNS_RR_HEADER_STRUCT, _PTR_ DNS_RR_HEADER_STRUCT_PTR;


/*
** Record-specific data structures, traditional record types.
*/

typedef struct dns_addr_record_struct {
   DNS_RR_HEADER_STRUCT             RR;
   _ip_address                      IPADDR;

}DNS_ADDR_RECORD_STRUCT, _PTR_ DNS_ADDR_RECORD_STRUCT_PTR;

typedef struct dns_name_record_struct {
   DNS_RR_HEADER_STRUCT             RR;
   uchar _PTR_                      ANS_NAME_PTR;

}DNS_NAME_RECORD_STRUCT, _PTR_ DNS_NAME_RECORD_STRUCT_PTR;


typedef struct dns_null_record_struct {
   DNS_RR_HEADER_STRUCT             RR;
   uchar                            NULL_BUFFER[DNS_NULL_RECORD_SIZE];

}DNS_NULL_RECORD_STRUCT, _PTR_ DNS_NULL_RECORD_STRUCT_PTR;


/*
** Structure used to maintain the linked list of resource records.
** NAME_SIZE is used for parsing name into response buffers of
** correct size.
*/

typedef struct dns_rr_list_struct {

   uchar                       _PTR_  NAME_PTR;
   DNS_RR_HEADER_STRUCT        _PTR_  RR_HEAD_PTR;
   struct dns_rr_list_struct   _PTR_  NEXT;

}DNS_RR_LIST_STRUCT, _PTR_ DNS_RR_LIST_STRUCT_PTR;


/*
** Domain Name Server Response Resource Record Structure
** This is defined to make writing a response easier.  This section of
** the response buffer should have a name first, this information second,
** and then response information of RDLENGTH after the structure.
*/

typedef struct dns_response_rr_middle_struct {

   uchar         TYPE[2];
   uchar         CLASS[2];
   uchar         TTL[4];
   uchar         RDLENGTH[2];

}DNS_RESPONSE_RR_MIDDLE_STRUCT, _PTR_ DNS_RESPONSE_RR_MIDDLE_STRUCT_PTR;

/*
** Domain Name Server Message Header Structure
*/

typedef struct dns_message_header_struct {

  uchar          ID[2];          /* Identifier used to match replies to
                                    outstanding queries */
  uchar          CONTROL[2];     /* Bits set to define query or response */
  uchar          QDCOUNT[2];     /* Number of entries in question section */
  uchar          ANCOUNT[2];     /* Number of RR's in answer section */
  uchar          NSCOUNT[2];     /* Number of Name Server RR's in the
                                    authority records   */
  uchar          ARCOUNT[2];     /* Number of RR's in the additional records */

}DNS_MESSAGE_HEADER_STRUCT, _PTR_ DNS_MESSAGE_HEADER_STRUCT_PTR;

/*
** Domain Name Server Message Tail Structure
*/

typedef struct dns_message_tail_struct {

  uchar       QTYPE[2];
  uchar       QCLASS[2];

}DNS_MESSAGE_TAIL_STRUCT, _PTR_ DNS_MESSAGE_TAIL_STRUCT_PTR;


/*
** Domain Name Server Server List Structure.  This structure is used
** exclusively by the resolver to keep a list of Name Servers to connect
** to when a query is made. Used only in the Root Server Structure
*/

typedef struct dns_slist_struct {

   char            _PTR_  NAME_PTR;
   struct dns_slist_struct _PTR_ NEXT;
   _ip_address            IPADDR;
   uint_32                LAST_TTL_CHECK;
   int_32                 TTL;
   uint_32                NUMBER_OF_HITS;
   uint_32                NUMBER_OF_TRIES;
   uint_32                AVG_RESPONSE_TIME;
   uint_16                TYPE;
   uint_16                CLASS;

}DNS_SLIST_STRUCT, _PTR_ DNS_SLIST_STRUCT_PTR;

/*
** Canonical Name Structure
*/

typedef struct dns_cname_struct {
   uchar                     _PTR_ CNAME_PTR;
   struct dns_cname_struct _PTR_ NEXT;
} DNS_CNAME_STRUCT, _PTR_ DNS_CNAME_STRUCT_PTR;

/*
**  Domain Name Server Query Id Structure. This structure is used in a
**  linked list of all outstanding queries.
**  The entries are deleted when expired or answered.
*/

typedef struct dns_internal_query_struct {


   _ip_address                     SERVER_IPADDR;
   uint_16                         QUERY_ID;
   uint_16                         CONTROL;
   uint_16                         QTYPE;
   uint_16                         QCLASS;
   /*
   ** This field is to keep track of which query was the reason for an
   ** internal query.
   */
   uint_16                         ORIGINAL_QID;
   uint_16                         RESERVED;
   int_32                          TTL;
   uint_32                         QUERY_RETRIES;
   uint_32                         LAST_TTL_CHECK;
   uchar                     _PTR_ QNAME_PTR;
   DNS_CNAME_STRUCT          _PTR_ CNAME;
   struct dns_internal_query_struct _PTR_ NEXT;
   sockaddr_in                     CLIENT_SIN;
   boolean                         INTERNAL_QUERY;

} DNS_INTERNAL_QUERY_STRUCT, _PTR_ DNS_INTERNAL_QUERY_STRUCT_PTR;

/*
** DNS Configuration Structure.  Used so DNS server and resolver functions
** only need to have one parameter passed to them and keep all necessary
** structures private.
*/

typedef struct dns_control_struct {

   DNS_INTERNAL_QUERY_STRUCT _PTR_ NS_QUERY_HEAD_PTR;
   DNS_INTERNAL_QUERY_STRUCT _PTR_ RES_QUERY_HEAD_PTR;
   DNS_RR_LIST_STRUCT        _PTR_ NS_ZONE_AUTH_LIST;
   DNS_RR_LIST_STRUCT        _PTR_ CACHE_PTR;
   DNS_SLIST_STRUCT          _PTR_ ROOT_SLIST_PTR;
   DNS_SLIST_STRUCT          _PTR_ LOCAL_SLIST_PTR;
   uchar                     _PTR_ NS_BUFFER;
   uchar                     _PTR_ RES_BUFFER;
   int_32                          NS_BUFFER_SIZE;
   int_32                          RES_BUFFER_SIZE;
   uint_32                         NS_SOCKET;
   uint_32                         RES_SOCKET;
   boolean                         UPDATING;
   _rtcs_mutex                     CACHE_MUTEX;
   uint_32                         NUM_NAMES_CACHED;
   _rtcs_part                      INT_QUERY_PARTID;
   _rtcs_part                      ADDR_RR_PARTID;
   _rtcs_part                      NAME_RR_PARTID;
   _rtcs_part                      RR_LIST_PARTID;
   _rtcs_part                      CNAME_PARTID;
   _rtcs_mutex                     SLIST_MUTEX;
} DNS_CONTROL_STRUCT, _PTR_ DNS_CONTROL_STRUCT_PTR;

/* Used to keep from blowing the stack in a recursive call */
typedef struct dns_recursive_cache_struct {
   DNS_INTERNAL_QUERY_STRUCT _PTR_ NEW_QUERY_PTR;
   DNS_CONTROL_STRUCT        _PTR_ CONTROL_PTR;
   DNS_RR_LIST_STRUCT        _PTR_ CACHE_HEAD;
   uchar                     _PTR_ NAME_PTR;
   uchar                     _PTR_ BUFFER_PTR;
   int_32                    _PTR_ BUFFER_SIZE_PTR;
   uint_32                         NUM_TRIES;
} DNS_RECURSIVE_CACHE_STRUCT, _PTR_ DNS_RECURSIVE_CACHE_STRUCT_PTR;


/* Function definitions required by DNS_gethostbyname and DNS_gethostbyaddr */

DNS_RR_LIST_STRUCT _PTR_ DNS_dynamically_allocate_zone_list
(
     DNS_CONTROL_STRUCT _PTR_ control_ptr
);

uint_32 DNS_is_dotted_domain_name
(
     uchar _PTR_ domain_name,
     uchar _PTR_ qname_buffer
);

uint_32 DNS_is_dotted_IP_addr
(
     uchar _PTR_ addr_ptr,
     uchar _PTR_ qname_buffer
);

HOSTENT_STRUCT _PTR_ DNS_parse_UDP_response
(
     uchar _PTR_ buffer_ptr,
     uchar _PTR_ name_ptr,
     uint_16     query_type
);

HOSTENT_STRUCT _PTR_ DNS_query_resolver_task
(
     uchar _PTR_ name,
     uint_16    query_type
);

HOSTENT_STRUCT_PTR DNS_check_local_host_file
(
     uchar _PTR_ name
);

uint_32 DNS_is_valid_domain_name
(
     uchar    _PTR_         buffer_ptr,
     uchar    _PTR_         domain_name,
     uchar    _PTR_  _PTR_  local_name_buffer
);


/*
* extern struct of initial root server information
*/

extern DNS_SLIST_STRUCT   DNS_A_Root_server[];
extern char         DNS_Local_network_name[];
extern uint_32 DNS_CACHE_NAME_LIMIT;
extern DNS_RR_LIST_STRUCT DNS_Zone_of_Authority_list[];

/* Start CR 2257 */
extern DNS_SLIST_STRUCT _PTR_ DNS_First_Local_server;
extern char         DNS_Local_server_name[];
extern void DNS_init_slist_entry   (DNS_SLIST_STRUCT _PTR_);
extern uint_32 DNS_append_slist_entry (DNS_SLIST_STRUCT _PTR_);
extern uint_32 DNS_prepend_slist_entry (DNS_SLIST_STRUCT _PTR_);
extern uint_32 DNS_remove_slist_entry (_ip_address);
extern DNS_SLIST_STRUCT _PTR_ DNS_find_slist_entry (_ip_address);
#define DNS_add_slist_entry(x) DNS_prepend_slist_entry(x)
/* End CR 2257 */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi/spi.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi.c$
* $Version : 3.8.1.0$
* $Date    : Sep-25-2012$
*
* Comments:
*
*   This file contains functions for generic SPI layer.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include <stdlib.h>

#include "spi.h"
#include "spi_prv.h"


/* Forward declarations */
static _mqx_int _io_spi_open(MQX_FILE_PTR fd_ptr, char _PTR_ open_name_ptr, char _PTR_ flags);
static _mqx_int _io_spi_close(MQX_FILE_PTR fd_ptr);
static _mqx_int _io_spi_read(MQX_FILE_PTR fd_ptr, char_ptr data_ptr, _mqx_int n);
static _mqx_int _io_spi_write(MQX_FILE_PTR fd_ptr, char_ptr data_ptr, _mqx_int n);
static _mqx_int _io_spi_ioctl(MQX_FILE_PTR fd_ptr, uint_32 cmd, pointer param_ptr);
static _mqx_int _io_spi_uninstall(IO_DEVICE_STRUCT_PTR io_dev_ptr);


/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_install
* Returned Value   : MQX error code
* Comments         :
*    Installs SPI device.
*
*END**********************************************************************/
_mqx_int _io_spi_install
    (
        /* [IN] A string that identifies the device for fopen */
        char_ptr                       identifier,

        /* [IN] Pointer to driver initialization data */
        SPI_INIT_STRUCT_CPTR           init_data_ptr
    )
{
    SPI_DRIVER_DATA_STRUCT_PTR driver_data;

    _mqx_int error_code;

    if ((init_data_ptr->DEVIF->SETPARAM == NULL) || (init_data_ptr->DEVIF->TX_RX == NULL))
    {
        /* Missing mandatory low level driver function */
        return IO_ERROR_DEVICE_INVALID;
    }

    driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(SPI_DRIVER_DATA_STRUCT));
    if (driver_data == NULL)
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type(driver_data, MEM_TYPE_IO_SPI_POLLED_DEVICE_STRUCT);

    driver_data->CS_CALLBACK = init_data_ptr->CS_CALLBACK;
    driver_data->CS_USERDATA= init_data_ptr->CS_USERDATA;
    driver_data->PARAMS = init_data_ptr->PARAMS;
    driver_data->DEVIF = init_data_ptr->DEVIF;

    /* initialize low level driver */
    if (driver_data->DEVIF->INIT)
        error_code = driver_data->DEVIF->INIT(init_data_ptr->DEVIF_INIT, &(driver_data->DEVIF_DATA));

    if (error_code != MQX_OK)
    {
        _mem_free(driver_data);
        return error_code;
    }

    _lwsem_create(&driver_data->BUS_LOCK, 1);

    error_code = _io_dev_install_ext(identifier,
        _io_spi_open, _io_spi_close,
        _io_spi_read, _io_spi_write,
        _io_spi_ioctl,
        _io_spi_uninstall,
        (pointer)driver_data);

    if (error_code)
    {
        _lwsem_destroy(&driver_data->BUS_LOCK);
        _mem_free(driver_data);
        return error_code;
    }

    return MQX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_uninstall
* Returned Value   : MQX error code
* Comments         :
*    Uninstalls SPI device.
*
*END**********************************************************************/
static _mqx_int _io_spi_uninstall
    (
        /* [IN] The IO device structure for the device */
        IO_DEVICE_STRUCT_PTR           io_dev_ptr
    )
{
    SPI_DRIVER_DATA_STRUCT_PTR driver_data;

    _mqx_int error_code = MQX_OK;

    driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)(io_dev_ptr->DRIVER_INIT_PTR);

    /* deinitialize low level driver */
    if (driver_data->DEVIF->DEINIT)
        error_code = driver_data->DEVIF->DEINIT(driver_data->DEVIF_DATA);

    if (error_code != MQX_OK)
    {
        return error_code;
    }

    _lwsem_destroy(&driver_data->BUS_LOCK);
    _mem_free(driver_data);

    return MQX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_read_write
* Returned Value   : Number of bytes read
* Comments         :
*    Claims the bus and performs SPI transfer by calling low level driver.
*    Returns number of bytes processed.
*
*END*********************************************************************/
static _mqx_int _io_spi_read_write
    (
        /* [IN] The handle returned from _fopen */
        MQX_FILE_PTR                   fd_ptr,

        /* Buffer containing bytes to write */
        char_ptr                       wrbuf,

        /* Buffer containing bytes read after transfer */
        char_ptr                       rdbuf,

        /* Byte length of each buffer */
        uint_32                        len
    )
{
    SPI_DEV_DATA_STRUCT_PTR    dev_data;
    SPI_DRIVER_DATA_STRUCT_PTR driver_data;

    _mqx_int result;
    _mqx_int error_code;

    /* parameter sanity check */
    if (len == 0 || ((wrbuf == NULL) && (rdbuf == NULL)))
    {
        return IO_ERROR;
    }

    dev_data = (SPI_DEV_DATA_STRUCT_PTR)(fd_ptr->DEV_DATA_PTR);
    driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)(fd_ptr->DEV_PTR->DRIVER_INIT_PTR);

    if (!(dev_data->BUS_OWNER))
    {
        error_code = _lwsem_wait(&(driver_data->BUS_LOCK));
        if (error_code != MQX_OK)
        {
            _task_set_error(error_code);
            return IO_ERROR;
        }
        dev_data->BUS_OWNER = TRUE;
        dev_data->PARAMS_DIRTY = TRUE;
    }

    if (dev_data->PARAMS_DIRTY)
    {
        error_code = driver_data->DEVIF->SETPARAM(driver_data->DEVIF_DATA, &(dev_data->PARAMS));
        if (error_code != MQX_OK)
        {
            _task_set_error(error_code);
            return IO_ERROR;
        }
        dev_data->PARAMS_DIRTY = FALSE;
    }

    if (driver_data->CS_CALLBACK)
    {
        error_code = driver_data->CS_CALLBACK(dev_data->PARAMS.CS, driver_data->CS_USERDATA);
        if (error_code != MQX_OK)
        {
            _task_set_error(error_code);
            return IO_ERROR;
        }
    }

    if ((wrbuf == NULL) && (dev_data->FLAGS & SPI_FLAG_FULL_DUPLEX))
    {
        wrbuf = rdbuf;
    }

    result = driver_data->DEVIF->TX_RX(driver_data->DEVIF_DATA, (uint_8_ptr)wrbuf, (uint_8_ptr)rdbuf, len);

    #if BSPCFG_ENABLE_SPI_STATS
    /* update statistics */
    if (result > 0)
    {
        int frames;
        frames = result / ((dev_data->PARAMS.FRAMESIZE + 7 ) / 8);
        if (rdbuf) dev_data->STATS.RX_PACKETS += frames;
        if (wrbuf) dev_data->STATS.TX_PACKETS += frames;
    }
    #endif

    return result;
}


/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_flush
* Returned Value   : Error code
* Comments         :
*    Finishes the transfer deasserting CS and releasing the bus
*
*END*********************************************************************/
static _mqx_int _io_spi_flush
    (
        /* [IN] The handle returned from _fopen */
        MQX_FILE_PTR                   fd_ptr,

        /* [IN] Requests keeping CS in current state (for SPI_FLAG_NO_DEASSERT_ON_FLUSH) */
        boolean                        cs_keep
    )
{
    SPI_DEV_DATA_STRUCT_PTR    dev_data;
    SPI_DRIVER_DATA_STRUCT_PTR driver_data;

    _mqx_int result = MQX_OK;
    _mqx_int error_code;

    dev_data = (SPI_DEV_DATA_STRUCT_PTR)(fd_ptr->DEV_DATA_PTR);
    driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)(fd_ptr->DEV_PTR->DRIVER_INIT_PTR);

    if (dev_data->BUS_OWNER)
    {
        if (!cs_keep)
        {
            if (driver_data->DEVIF->CS_DEASSERT)
            {
                error_code = driver_data->DEVIF->CS_DEASSERT(driver_data->DEVIF_DATA);
                if (result == MQX_OK)
                    result = error_code;
            }

            if (driver_data->CS_CALLBACK)
            {
                error_code = driver_data->CS_CALLBACK(0, driver_data->CS_USERDATA);
                if (result == MQX_OK)
                    result = error_code;
            }
        }
        error_code = _lwsem_post(&(driver_data->BUS_LOCK));
        dev_data->BUS_OWNER = FALSE;
        if (result == MQX_OK)
            result = error_code;
    }
    dev_data->PARAMS_DIRTY = TRUE; /* forces resetting parameters before next transfer */

    return result;
}


/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_open
* Returned Value   : MQX error code
* Comments         :
*    This routine opens the SPI I/O channel.
*
*END**********************************************************************/
static _mqx_int _io_spi_open
    (
        /* [IN] The file handle for the device being opened */
        MQX_FILE_PTR         fd_ptr,

        /* [IN] The remaining portion of the name of the device */
        char                 _PTR_ open_name_ptr,

        /* [IN] The flags to be used during operation */
        char                 _PTR_ flags
    )
{
    SPI_DEV_DATA_STRUCT_PTR    dev_data;
    SPI_DRIVER_DATA_STRUCT_PTR driver_data;

    char_ptr file_name_ptr;
    char_ptr endptr;

    uint_32  cs = 0; /* initialization required to avoid compilation warning */

    file_name_ptr = open_name_ptr;
    while (*file_name_ptr && *file_name_ptr++ != ':') {}

    if (*file_name_ptr)
    {
        cs = strtoul(file_name_ptr, &endptr, 0);
        if (*endptr)
        {
            return IO_ERROR_DEVICE_INVALID;
        }
    }

    dev_data = _mem_alloc_system_zero(sizeof(SPI_DEV_DATA_STRUCT));
    if (dev_data == NULL )
    {
        return MQX_OUT_OF_MEMORY;
    }
    fd_ptr->DEV_DATA_PTR = dev_data;

    driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)(fd_ptr->DEV_PTR->DRIVER_INIT_PTR);

    /* copy default parameters */
    dev_data->PARAMS = driver_data->PARAMS;
    dev_data->PARAMS_DIRTY = TRUE;

    /* optionally assign CS according to file name */
    if (*file_name_ptr)
    {
        dev_data->PARAMS.CS = cs;
    }

    /* open flags */
    dev_data->FLAGS = (uint_32)flags;

    return MQX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_close
* Returned Value   : MQX error code
* Comments         :
*    This routine closes the SPI I/O channel.
*
*END**********************************************************************/
static _mqx_int _io_spi_close
    (
        /* [IN] The file handle for the device being closed */
        MQX_FILE_PTR         fd_ptr
    )
{
    _io_spi_flush(fd_ptr, 0);
    _mem_free(fd_ptr->DEV_DATA_PTR);

    return MQX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_read
* Returned Value   : Number of bytes read
* Comments         :
*    POSIX wrapper to perform SPI transfer storing received data into the buffer.
*    Returns number of bytes received.
*
*END*********************************************************************/
static _mqx_int _io_spi_read
    (
        /* [IN] The handle returned from _fopen */
        MQX_FILE_PTR                   fd_ptr,

        /* [OUT] Where the characters are to be stored */
        char_ptr                       data_ptr,

        /* [IN] The number of bytes to read */
        _mqx_int                       n
    )
{
    return _io_spi_read_write(fd_ptr, NULL, data_ptr, n);
}


/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_write
* Returned Value   : Number of bytes to write
* Comments         :
*    POSIX wrapper to perform SPI transfer sending data from the buffer.
*    Returns number of bytes received.
*
*END**********************************************************************/
static _mqx_int _io_spi_write
    (
        /* [IN] The handle returned from _fopen */
        MQX_FILE_PTR                   fd_ptr,

        /* [IN] Where the bytes are stored */
        char_ptr                       data_ptr,

        /* [IN] The number of bytes to output */
        _mqx_int                       n
    )
{
    return _io_spi_read_write(fd_ptr, data_ptr, NULL, n);
}


/*FUNCTION*****************************************************************
*
* Function Name    : _io_spi_ioctl
* Returned Value   : MQX error code
* Comments         :
*    Returns result of SPI ioctl operation.
*
*END*********************************************************************/
static _mqx_int _io_spi_ioctl
    (
        /* [IN] the file handle for the device */
        MQX_FILE_PTR                   fd_ptr,

        /* [IN] the ioctl command */
        uint_32                        cmd,

        /* [IN] the ioctl parameters */
        pointer                        param_ptr
    )
{
    SPI_DEV_DATA_STRUCT_PTR    dev_data;
    SPI_DRIVER_DATA_STRUCT_PTR driver_data;

    _mqx_int result = MQX_OK;
    _mqx_int lldrv_result = MQX_OK;

    dev_data = (SPI_DEV_DATA_STRUCT_PTR)(fd_ptr->DEV_DATA_PTR);
    driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)(fd_ptr->DEV_PTR->DRIVER_INIT_PTR);

    switch (cmd) {

        case IO_IOCTL_DEVICE_IDENTIFY:
            /* return the device identification */
            ((_mqx_uint_ptr)param_ptr)[0] = IO_DEV_TYPE_PHYS_SPI;
            ((_mqx_uint_ptr)param_ptr)[1] = 0;
            ((_mqx_uint_ptr)param_ptr)[2] = IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
            break;

        case IO_IOCTL_FLUSH_OUTPUT:
            result = _io_spi_flush(fd_ptr, ((dev_data->FLAGS & SPI_FLAG_NO_DEASSERT_ON_FLUSH)!=0));
            break;

        case IO_IOCTL_SPI_FLUSH_DEASSERT_CS:
            result = _io_spi_flush(fd_ptr, 0);
            break;

        case IO_IOCTL_SPI_READ_WRITE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                SPI_READ_WRITE_STRUCT_PTR rw_ptr = (SPI_READ_WRITE_STRUCT_PTR)param_ptr;
                if (rw_ptr->BUFFER_LENGTH != _io_spi_read_write(fd_ptr, rw_ptr->WRITE_BUFFER, rw_ptr->READ_BUFFER, rw_ptr->BUFFER_LENGTH))
                    result = IO_ERROR;

            }
            break;

        case IO_IOCTL_SPI_GET_FLAGS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint_32_ptr)param_ptr) = dev_data->FLAGS;
            }
            break;

        case IO_IOCTL_SPI_SET_FLAGS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->FLAGS = *((uint_32_ptr)param_ptr);
            }
            break;

        case IO_IOCTL_SPI_GET_BAUD:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint_32_ptr)param_ptr) = dev_data->PARAMS.BAUDRATE;

                /* Pass IOCTL also to the low level driver */
                if (driver_data->DEVIF->IOCTL != NULL)
                    result = driver_data->DEVIF->IOCTL(driver_data->DEVIF_DATA, &(dev_data->PARAMS), cmd, param_ptr);

                /* Invalid IOCTL reported by the low level driver is not an error (implementation is not mandatory) */
                if (result == IO_ERROR_INVALID_IOCTL_CMD)
                    result = MQX_OK;
            }
            break;

        case IO_IOCTL_SPI_SET_BAUD:
            if (NULL == param_ptr || 0 == *((uint_32_ptr)param_ptr))
            {
                /* use default baudrate */
                dev_data->PARAMS.BAUDRATE = driver_data->PARAMS.BAUDRATE;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else
            {
                dev_data->PARAMS.BAUDRATE = *((uint_32_ptr)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_GET_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint_32_ptr)param_ptr) = dev_data->PARAMS.MODE;
            }
            break;

        case IO_IOCTL_SPI_SET_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->PARAMS.MODE = *((uint_32_ptr)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_GET_CS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint_32_ptr)param_ptr) = dev_data->PARAMS.CS;
            }
            break;

        case IO_IOCTL_SPI_SET_CS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->PARAMS.CS = *((uint_32_ptr)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_GET_FRAMESIZE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint_32_ptr)param_ptr) = dev_data->PARAMS.FRAMESIZE;
            }
            break;

        case IO_IOCTL_SPI_SET_FRAMESIZE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->PARAMS.FRAMESIZE = *((uint_32_ptr)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_GET_TRANSFER_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if ((dev_data->PARAMS.ATTR & SPI_ATTR_TRANSFER_MODE_MASK) == SPI_ATTR_SLAVE_MODE)
            {
                *((uint_32_ptr)param_ptr) = SPI_DEVICE_SLAVE_MODE;
            }
            else
            {
                *((uint_32_ptr)param_ptr) = SPI_DEVICE_MASTER_MODE;
            }
            break;

        case IO_IOCTL_SPI_SET_TRANSFER_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if (*((uint_32_ptr)param_ptr) == SPI_DEVICE_SLAVE_MODE)
            {
                dev_data->PARAMS.ATTR &= ~SPI_ATTR_TRANSFER_MODE_MASK;
                dev_data->PARAMS.ATTR |= SPI_ATTR_SLAVE_MODE;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else if (*((uint_32_ptr)param_ptr) == SPI_DEVICE_MASTER_MODE)
            {
                dev_data->PARAMS.ATTR &= ~SPI_ATTR_TRANSFER_MODE_MASK;
                dev_data->PARAMS.ATTR |= SPI_ATTR_MASTER_MODE;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else
            {
                result = SPI_ERROR_TRANSFER_MODE_INVALID;
            }
            break;

        case IO_IOCTL_SPI_GET_ENDIAN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if ((dev_data->PARAMS.ATTR & SPI_ATTR_ENDIAN_MASK) == SPI_ATTR_LITTLE_ENDIAN)
            {
                *((uint_32_ptr)param_ptr) = SPI_DEVICE_LITTLE_ENDIAN;
            }
            else
            {
                *((uint_32_ptr)param_ptr) = SPI_DEVICE_BIG_ENDIAN;
            }
            break;

        case IO_IOCTL_SPI_SET_ENDIAN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if (*((uint_32_ptr)param_ptr) == SPI_DEVICE_LITTLE_ENDIAN)
            {
                dev_data->PARAMS.ATTR &= ~SPI_ATTR_ENDIAN_MASK;
                dev_data->PARAMS.ATTR |= SPI_ATTR_LITTLE_ENDIAN;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else if (*((uint_32_ptr)param_ptr) == SPI_DEVICE_BIG_ENDIAN)
            {
                dev_data->PARAMS.ATTR &= ~SPI_ATTR_ENDIAN_MASK;
                dev_data->PARAMS.ATTR |= SPI_ATTR_BIG_ENDIAN;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else
            {
                result = SPI_ERROR_ENDIAN_INVALID;
            }
            break;

        case IO_IOCTL_SPI_GET_DUMMY_PATTERN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint_32_ptr)param_ptr) = dev_data->PARAMS.DUMMY_PATTERN;
            }
            break;

        case IO_IOCTL_SPI_SET_DUMMY_PATTERN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->PARAMS.DUMMY_PATTERN = *((uint_32_ptr)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_SET_CS_CALLBACK:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                if (!(dev_data->BUS_OWNER) && ((result=_lwsem_wait(&(driver_data->BUS_LOCK))) != MQX_OK))
                    break;

                driver_data->CS_CALLBACK = ((SPI_CS_CALLBACK_STRUCT_PTR)param_ptr)->CALLBACK;
                driver_data->CS_USERDATA = ((SPI_CS_CALLBACK_STRUCT_PTR)param_ptr)->USERDATA;

                if (!(dev_data->BUS_OWNER))
                    result = _lwsem_post(&(driver_data->BUS_LOCK));
            }
            break;

        case IO_IOCTL_SPI_GET_STATS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                #if BSPCFG_ENABLE_SPI_STATS
                *((SPI_STATISTICS_STRUCT_PTR)param_ptr) = dev_data->STATS;
                #else
                _mem_zero(param_ptr, sizeof(SPI_STATISTICS_STRUCT));
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                #endif
            }
            break;

        case IO_IOCTL_SPI_CLEAR_STATS:
            #if BSPCFG_ENABLE_SPI_STATS
            _mem_zero(&(dev_data->STATS), sizeof(dev_data->STATS));
            #else
            result = MQX_IO_OPERATION_NOT_AVAILABLE;
            #endif
            break;

        case IO_IOCTL_SPI_DEVICE_ENABLE:
            break;

        case IO_IOCTL_SPI_DEVICE_DISABLE:
            break;

        default:
            /* Pass unhandled IOCTL to the low level driver */
            if (driver_data->DEVIF->IOCTL != NULL)
            {
                /* Do not assume that the low level driver is re-entrant, lock semaphore */
                if (!(dev_data->BUS_OWNER) && ((result=_lwsem_wait(&(driver_data->BUS_LOCK))) != MQX_OK))
                    break;

                lldrv_result = driver_data->DEVIF->IOCTL(driver_data->DEVIF_DATA, &(dev_data->PARAMS), cmd, param_ptr);

                if (!(dev_data->BUS_OWNER))
                    result = _lwsem_post(&(driver_data->BUS_LOCK));

                /* Report low level driver error, if any */
                if (lldrv_result != MQX_OK)
                    result = lldrv_result;
            }
            else
            {
                result = IO_ERROR_INVALID_IOCTL_CMD;
            }
            break;
    }

    return result;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwgpio/lwgpio_mcf5225.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwgpio_mcf5225.c$
* $Version : 3.8.9.1$
* $Date    : Aug-1-2012$
*
* Comments:
*
*   This file contains the GPIO standard functions used on boards
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "lwgpio.h"

enum {
    PORTTE = 0, PORTTF, PORTTG, PORTTH,
    PORTTI, DUMMY0, PORTTJ, DUMMY1,
    PORTNQ, DUMMY2, PORTAN, PORTAS, 
    PORTQS, DUMMY3, PORTTA, PORTTC, 
    DUMMY4, PORTUA, PORTUB, PORTUC, 
    PORTDD, DUMMY5, DUMMY6, DUMMY7
};

enum {
    REG_PORT = 0,
    REG_DDR = 1,
    REG_SET = 2, /* also REG_PORTP */
    REG_CLR = 3,
    REG_PAR = 4,
    REG_PCR = 5
    
};

#define LWGPIO_PIN_FROM_ID(id) (((id) & LWGPIO_PIN_MASK) >> LWGPIO_PIN_SHIFT)
#define LWGPIO_PORT_FROM_ID(id) (((id) & LWGPIO_PORT_MASK) >> LWGPIO_PORT_SHIFT)

/* Interrupt mode definitions */
#define LWGPIO_INT_MODE_SHIFT (11)
#define LWGPIO_INT_MODE_MASK (0x03 << LWGPIO_INT_MODE_SHIFT)
#define LWGPIO_INT_MODE(x) (((x) << LWGPIO_INT_MODE_SHIFT) & LWGPIO_INT_MODE_MASK)
#define LWGPIO_INT_MODE_FROM_ID(id) (((id) & LWGPIO_INT_MODE_MASK) >> LWGPIO_INT_MODE_SHIFT)

/* Direction field definitions */
#define LWGPIO_DIR_SHIFT (13)
#define LWGPIO_DIR_MASK (0x01 << LWGPIO_DIR_SHIFT)

static volatile uint_8 *gpio_ptr[REG_PCR + 1];

static VMCF522XX_EPORT_STRUCT_PTR eport_ptr;

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_init
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    Decodes ID to HW specific struct and then performs pin initialization
*
*END*********************************************************************/
boolean lwgpio_init
(
    /* Pointer to LWGPIO internal structure to be filled in */
    LWGPIO_STRUCT_PTR handle,
    /* Pin ID, bitmask integer value */
    LWGPIO_PIN_ID     id,
    /* Direction to be set within initialization */
    LWGPIO_DIR        dir,
    /* Value to be set within initialization */
    LWGPIO_VALUE      value
)
{ /* Body */
    static boolean first_run = TRUE;
    uint_32 port_idx, pin_idx;

    if (first_run) {
        /* Update gpio_ptr to point to the register based on IPSBAR */
        gpio_ptr[REG_PORT] = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.PORTTE);
        gpio_ptr[REG_DDR] = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.DDRTE);
        gpio_ptr[REG_SET] = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.PORTTEP_SETTE);
        gpio_ptr[REG_CLR] = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.CLRTE);
        gpio_ptr[REG_PAR] = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.PTEPAR);
        (volatile uint_32 *)gpio_ptr[REG_PCR] = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.PSRR);

        eport_ptr = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->EPORT[0]);
        first_run = FALSE;
    }

    handle->port_idx = LWGPIO_PORT_FROM_ID(id);
    handle->pinmask = 1 << LWGPIO_PIN_FROM_ID(id);
    handle->flags = id;

    /* By default, port has pins 0..7 available. There are exceptions, handled here. */
    switch(handle->port_idx) {
        case PORTTA:
        case PORTTC:
        case PORTUA:
        case PORTUB:
        case PORTUC:
            if (LWGPIO_PIN_FROM_ID(id) > 3)
                return FALSE;
            break;
        case PORTQS:
            if ((LWGPIO_PIN_FROM_ID(id)== 4)||(LWGPIO_PIN_FROM_ID(id)== 7))
                return FALSE;
            break;
        case PORTTH:
        	break;
        case PORTAS:
            if (LWGPIO_PIN_FROM_ID(id) > 2)
                return FALSE;
            break;
        case PORTNQ:
            if (LWGPIO_PIN_FROM_ID(id) & 0x01 == 0x00)
                return FALSE;
            break;
    }

    /* Set value prior to set to output */
    if (value != LWGPIO_VALUE_NOCHANGE) {
        /* Note: there is no check for values not defined as LWGPIO_VALUE enum */
        lwgpio_set_value(handle, value);
    }

    if (dir != LWGPIO_DIR_NOCHANGE) {
        /* Note: there is no check for values not defined as LWGPIO_DIR enum */
        lwgpio_set_direction(handle, dir);
    }
    
    return TRUE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_attribute
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    Sets attributes
*
*END*********************************************************************/
boolean lwgpio_set_attribute
(
    /* Pin handle to get function from */
    LWGPIO_STRUCT_PTR  handle,
    /* PORT attribute */
    uint_32 attribute_id,
    /* Attribute value */
    uint_32 value
)
{
/* shift mask for set_attribute */
static const uint_8 port_shift[]={
    0, 8, 24, 16,
    0, 0, 8, 0,
    0, 0, 0, 18,
    1, 0, 20, 16,
    0, 8, 12, 24,
    0, 0, 0, 0
};
    switch(handle->port_idx)
    {
    case PORTTA:
    case PORTAS:
    case PORTQS:
    case PORTTC:
    case PORTUA:
    case PORTUB:
    case PORTUC:
    { 
    if (((LWGPIO_PIN_FROM_ID(handle->flags)) == 2) && handle->port_idx==PORTAS)    /* PAS2 exception */
        { 
        /* PSSRL */
            if (attribute_id == LWGPIO_ATTR_SLEW_RATE) 
            {
                volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+8);
                
                if (value == LWGPIO_AVAL_SLEW_RATE_FAST) 
                {
                    *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+18);
                }
                else
                {
                    *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+18);
                }
                return TRUE;
            /* PDSRL */
            } else if (attribute_id == LWGPIO_ATTR_DRIVE_STRENGTH)
            {
                volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+16);
                
                if (value == LWGPIO_AVAL_DRIVE_STRENGTH_LOW) 
                {
                    *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+18);
                }
                else
                {
                    *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+18);
                }
                return TRUE;
            }
            break;
        }
    /* PSSR */
        if (attribute_id == LWGPIO_ATTR_SLEW_RATE) 
        {
            volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]);
            
            if (value == LWGPIO_AVAL_SLEW_RATE_FAST) 
            {
                *pcr &= value << ((LWGPIO_PIN_FROM_ID(handle->flags)) + port_shift[handle->flags]);
            }
            else
            {
                *pcr |= value  << ((LWGPIO_PIN_FROM_ID(handle->flags)) + port_shift[handle->flags]);
            }
            return TRUE;
    /* PDSR */
        } else if (attribute_id == LWGPIO_ATTR_DRIVE_STRENGTH)
        {
            volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+4);
            
            if (value == LWGPIO_AVAL_DRIVE_STRENGTH_LOW) 
            {
                *pcr &= value << ((LWGPIO_PIN_FROM_ID(handle->flags))+port_shift[handle->flags]);
            }
            else
            {
                *pcr |= value  << ((LWGPIO_PIN_FROM_ID(handle->flags))+port_shift[handle->flags]);
            }
            return TRUE;
        }
        break;
    }    
    case PORTTJ:
    case PORTTI:
    {    
    /* PSRRH */
        if (attribute_id == LWGPIO_ATTR_SLEW_RATE) 
        {
            volatile uint_16 *pcr = (volatile uint_16 *)(gpio_ptr[REG_PCR]+14);
            
            if (value == LWGPIO_AVAL_SLEW_RATE_FAST) 
            {
                *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+port_shift[handle->flags]);
            }
            else
            {
                *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+port_shift[handle->flags]);
            }
            return TRUE;
    /* PDSRH */
        } else if (attribute_id == LWGPIO_ATTR_DRIVE_STRENGTH)
        {
            volatile uint_16 *pcr = (volatile uint_16 *)(gpio_ptr[REG_PCR]+22);
            
            if (value == LWGPIO_AVAL_DRIVE_STRENGTH_LOW) 
            {
                *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+port_shift[handle->flags]);
            }
            else
            {
                *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+port_shift[handle->flags]);
            }
            return TRUE;
        }
        break;
    }
    case PORTTE:
    case PORTTF:
    case PORTTG:
    case PORTTH:
    { 
    /* PSSRL */
        if (LWGPIO_PIN_FROM_ID(handle->flags) >5 && (handle->port_idx == PORTTH)) /* PTH6 & PTH7 exception */
        {
            if (attribute_id == LWGPIO_ATTR_SLEW_RATE) 
            {
                volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+8);
                
                if (value == LWGPIO_AVAL_SLEW_RATE_FAST) 
                {
                    *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+16);
                }
                else
                {
                    *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+16);
                }
                return TRUE;
        /* PDSRL */
            } else if ( attribute_id == LWGPIO_ATTR_DRIVE_STRENGTH)
            {
                volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+16);
                
                if (value == LWGPIO_AVAL_DRIVE_STRENGTH_LOW) 
                {
                    *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+16);
                }
                else
                {
                    *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+16);
                }
                return TRUE;
            }
        }
        if (LWGPIO_PIN_FROM_ID(handle->flags) >5 && (handle->port_idx == PORTTG)) /* PTG6 & PTG7 exception */
        {
            if (attribute_id == LWGPIO_ATTR_SLEW_RATE) 
            {
                volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+8);
                
                if (value == LWGPIO_AVAL_SLEW_RATE_FAST) 
                {
                    *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+24);
                }
                else
                {
                    *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+24);
                }
                return TRUE;
        /* PDSRL */
            } else if (attribute_id == LWGPIO_ATTR_DRIVE_STRENGTH)
            {
                volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+16);
                
                if (value == LWGPIO_AVAL_DRIVE_STRENGTH_LOW) 
                {
                    *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+24);
                }
                else
                {
                    *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+24);
                }
                return TRUE;
            }
        }
        if (attribute_id == LWGPIO_ATTR_SLEW_RATE) 
        {
            volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+8);
            
            if (value == LWGPIO_AVAL_SLEW_RATE_FAST) 
            {
                *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+port_shift[handle->flags]);
            }
            else
            {
                *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+port_shift[handle->flags]);
            }
            return TRUE;
    /* PDSRL */
        } else if (attribute_id == LWGPIO_ATTR_DRIVE_STRENGTH)
        {
            volatile uint_32 *pcr = (volatile uint_32 *)(gpio_ptr[REG_PCR]+16);
            
            if (value == LWGPIO_AVAL_DRIVE_STRENGTH_LOW) 
            {
                *pcr &= value << (LWGPIO_PIN_FROM_ID(handle->flags)+port_shift[handle->flags]);
            }
            else
            {
                *pcr |= value  << (LWGPIO_PIN_FROM_ID(handle->flags)+port_shift[handle->flags]);
            }
            return TRUE;
        }
        break;
    }
    default:
        return FALSE;
    }
    return FALSE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_functionality
* Returned Value   : void
* Comments         :
*    Sets functionality (peripheral mode) of the pin
*
*END*********************************************************************/
void lwgpio_set_functionality
(
    /* Pin handle to set function on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Function to be set (integer value) */
    uint_32            function
)
{
    switch (handle->port_idx) {
        case PORTTE:
        case PORTTF:
        case PORTTG:
        case PORTTI:
        case PORTTJ:
        case PORTAN:
        case PORTAS:
        case PORTDD: /* 8-bit PAR registers, standard */
            {
                volatile uint_8 *par = gpio_ptr[REG_PAR] + handle->port_idx;

                if (function == 0)
                    *par &= ~handle->pinmask;
                else if (function == 1)
                    *par |= handle->pinmask;
            }
            break;
        case PORTTA:
        case PORTTC:
        case PORTUA:
        case PORTUB:
        case PORTUC: /* 8-bit PAR registers with quad-function */
            {
                volatile uint_8 *par = gpio_ptr[REG_PAR] + handle->port_idx;
                /* Create temp. new special pinmask for 16-bit registers */
                uint_8 pinmask = 0x03 << (2 * LWGPIO_PIN_FROM_ID(handle->flags));
                uint_8 functionmask = (function & 0x03) << (2 * LWGPIO_PIN_FROM_ID(handle->flags));

                *par &= ~pinmask;
                *par |= functionmask;
            }
            break;
        case PORTNQ:
        case PORTQS: /* 16-bit PAR registers with quad-function */
            {
                volatile uint_16 *par = (volatile uint_16 *) (gpio_ptr[REG_PAR] + handle->port_idx);
                /* Create temp. new special pinmask for 16-bit registers */
                uint_16 pinmask = 0x03 << (2 * LWGPIO_PIN_FROM_ID(handle->flags));
                uint_16 functionmask = (function & 0x03) << (2 * LWGPIO_PIN_FROM_ID(handle->flags));

                *par &= ~pinmask;
                *par |= functionmask;
            }
            break;
        case PORTTH: /* 16-bit PAR register with quad-funcition residing outside PAR area */
            {
                /* Create temp. new special pinmask for 16-bit registers */
                uint_16 pinmask = 0x03 << (2 * LWGPIO_PIN_FROM_ID(handle->flags));
                uint_16 functionmask = (function & 0x03) << (2 * LWGPIO_PIN_FROM_ID(handle->flags));

                ((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.PTHPAR &= ~pinmask;
                ((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.PTHPAR |= functionmask;
            }
            break;
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_functionality
* Returned Value   : void
* Comments         :
*    Gets function (peripheral mode) of the pin
*
*END*********************************************************************/
uint_32 lwgpio_get_functionality
(
    /* Pin handle to get function from */
    LWGPIO_STRUCT_PTR  handle
)
{
    uint_32 retval;

    switch (handle->port_idx) {
        case PORTTE:
        case PORTTF:
        case PORTTG:
        case PORTTI:
        case PORTTJ:
        case PORTAN:
        case PORTAS:
        case PORTDD: /* 8-bit PAR registers, standard */
            retval = (*(gpio_ptr[REG_PAR] + handle->port_idx) & handle->pinmask) ? 1 : 0;
            break;
        case PORTTA:
        case PORTTC:
        case PORTUA:
        case PORTUB:
        case PORTUC: /* 8-bit PAR registers with quad-function */
            {
                /* Create temp. new special pinmask for 16-bit registers */
                uint_8 pinmask = 0x03 << (2 * LWGPIO_PIN_FROM_ID(handle->flags));
                /* Get 16-bit PAR value for specific port, mask to get 2-bits for specific pin */
                uint_8 parval = *(gpio_ptr[REG_PAR] + handle->port_idx) & handle->pinmask;

                retval = (parval >> (2 * LWGPIO_PIN_FROM_ID(handle->flags))) & 0x03;
            }
            break;
        case PORTNQ:
        case PORTQS: /* 16-bit PAR registers with quad-function */
            {
                /* Create temp. new special pinmask for 16-bit registers */
                uint_16 pinmask = 0x03 << (2 * LWGPIO_PIN_FROM_ID(handle->flags));
                /* Get 16-bit PAR value for specific port, mask to get 2-bits for specific pin */
                uint_16 parval = *(volatile uint_16 *)(gpio_ptr[REG_PAR] + handle->port_idx);

                retval = (parval >> (2 * LWGPIO_PIN_FROM_ID(handle->flags))) & 0x03;
            }                            
            break;
        case PORTTH: /* 16-bit PAR register with quad-funcition residing outside PAR area */
            {
                /* Create temp. new special pinmask for 16-bit registers */
                uint_16 pinmask = 0x03 << (2 * LWGPIO_PIN_FROM_ID(handle->flags));
                /* Get 16-bit PAR value for specific port, mask to get 2-bits for specific pin */
                uint_16 parval = ((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO.PTHPAR;

                retval = (parval >> (2 * LWGPIO_PIN_FROM_ID(handle->flags))) & 0x03;
            }                            
            break;
        default:
            /* Bad port specified, return *any* value. MAX_UINT_32 is quite ok to signal some error */
            retval = MAX_UINT_32;
            break;
    }

    return retval;
}


/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_direction
* Returned Value   : void
* Comments         :
*    Sets direction of the pin
*
*END*********************************************************************/
void lwgpio_set_direction
(
    /* Pin handle to set direction on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Direction to be set */
    LWGPIO_DIR         dir
)
{
    if (dir == LWGPIO_DIR_INPUT) {
        *(gpio_ptr[REG_DDR] + handle->port_idx) &= ~handle->pinmask;
        handle->flags |= LWGPIO_DIR_MASK; /* mark the pin is input */
    }
    else if (dir == LWGPIO_DIR_OUTPUT) {
        *(gpio_ptr[REG_DDR] + handle->port_idx) |= handle->pinmask;
        handle->flags &= ~LWGPIO_DIR_MASK; /* mark the pin is output */
    }
    else { /* LWGPIO_DIR_NOCHANGE or other value */
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_set_value
* Returned Value   : void
* Comments         :
*    Sets value (output latch) of the pin
*
*END*********************************************************************/
void lwgpio_set_value
(
    /* Pin handle to set value on */
    LWGPIO_STRUCT_PTR  handle, 
    /* Direction to be set */
    LWGPIO_VALUE       out_value
)
{
    if (out_value == LWGPIO_VALUE_LOW) {
        *(gpio_ptr[REG_CLR] + handle->port_idx) = ~handle->pinmask;
    }
    else if (out_value == LWGPIO_VALUE_HIGH) {
        *(gpio_ptr[REG_SET] + handle->port_idx) = handle->pinmask;
    }
    else { /* LWGPIO_VALUE_NOCHANGE or other value */
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_toggle_value
* Returned Value   : void
* Comments         :
*    Toggles value of output latch of the pin
*
*END*********************************************************************/
void lwgpio_toggle_value
(
    /* Pin handle to toggle value on */
    LWGPIO_STRUCT_PTR  handle
)
{
    lwgpio_set_value(handle, lwgpio_get_value(handle) == LWGPIO_VALUE_HIGH ? LWGPIO_VALUE_LOW : LWGPIO_VALUE_HIGH);
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_value
* Returned Value   : LWGPIO_VALUE of pin status
* Comments         :
*    Returns value (output latch or read data) of the pin
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_value
(
    /* Pin handle to get value from */
    LWGPIO_STRUCT_PTR  handle
)
{
    /* if the port is set to the interrupt functionality */
    if ((handle->port_idx == PORTNQ) && (eport_ptr->EPIER & handle->pinmask))
        return (eport_ptr->EPPDR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
    /* if the pin is set to output */
    if (*(gpio_ptr[REG_DDR] + handle->port_idx) & handle->pinmask) /* alternative: (handle->flags & LWGPIO_DIR_MASK == 0) */
        return (*(gpio_ptr[REG_PORT] + handle->port_idx) & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
    else
        /* Note: REG_SET is an union with REG_PORTP = getting value */
        return (*(gpio_ptr[REG_SET] + handle->port_idx) & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_get_raw
* Returned Value   : LWGPIO_VALUE of pin status
* Comments         :
*    Returns read level of the pin
*
*END*********************************************************************/
LWGPIO_VALUE lwgpio_get_raw
(
    /* Pin handle to get value from */
    LWGPIO_STRUCT_PTR  handle
)
{
    /* if the port is set to the interrupt functionality */
    if ((handle->port_idx == PORTNQ) && (eport_ptr->EPIER & handle->pinmask))
        return (eport_ptr->EPPDR & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
    /* Note: REG_SET is an union with REG_PORTP = getting value */
    return (*(gpio_ptr[REG_SET] + handle->port_idx) & handle->pinmask) ? LWGPIO_VALUE_HIGH : LWGPIO_VALUE_LOW;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_init
* Returned Value   : TRUE if succesfull, FALSE otherwise
* Comments         :
*    Initializes pin to generate interrupt
*
*END*********************************************************************/
boolean lwgpio_int_init
(
    /* Pin handle to initialize interrupt on */
    LWGPIO_STRUCT_PTR handle,
    /* Interrupt mode */
    LWGPIO_INT_MODE   mode
)
{ /* Body */
    /* Create temp. new special pinmask for 16-bit registers */
    uint_16 pinmask = 0x03 << (2 * LWGPIO_PIN_FROM_ID(handle->flags));

    if (handle->port_idx != PORTNQ)
        return FALSE; /* MCF5225 ONLY: interrupts are allowed only on PORTNQ */
    if (handle->pinmask & 0x55)
        return FALSE; /* MCF5225 ONLY: interrupts are allowed only on pin 1, 3, 5 and 7 */
    if (mode > 0x04)
        return FALSE; /* interrupts are only rising, falling, rising+falling and high */
    if (mode == LWGPIO_INT_MODE_NONE)
        return TRUE; /* don't setup interrupts */

    /* setup EPPAR */
    switch (mode) {
        case LWGPIO_INT_MODE_HIGH:
            eport_ptr->EPPAR &= ~pinmask;
            break;
        case LWGPIO_INT_MODE_FALLING | LWGPIO_INT_MODE_RISING:
            eport_ptr->EPPAR |= pinmask;
            break;
        case LWGPIO_INT_MODE_FALLING:
        case LWGPIO_INT_MODE_RISING:
            eport_ptr->EPPAR &= ~pinmask;
            eport_ptr->EPPAR |= (mode & 0x03) << (2 * LWGPIO_PIN_FROM_ID(handle->flags));
            break;
    }

    return TRUE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_enable
* Returned Value   : void
* Comments         :
*    Enables / disables interrupts for specified pin
*
*END*********************************************************************/
void lwgpio_int_enable
(
    /* Pin handle to enable interrupt on */
    LWGPIO_STRUCT_PTR handle,
    /* Enable or disable interrupt? TRUE = enable */
    boolean           ena
)
{ /* Body */
    if (ena) {
        /* enable pin interrupts */
        eport_ptr->EPIER |= handle->pinmask;
    }
    else {
        /* disable pin interrupts */
        eport_ptr->EPIER &= ~handle->pinmask;
    }
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_get_flag
* Returned Value   : TRUE if interrupt flag is set
* Comments         :
*    Checks if there is pending interrupt flag for specified pin
*
*END*********************************************************************/
boolean lwgpio_int_get_flag
(
    /* Pin handle to get interrupt flag on */
    LWGPIO_STRUCT_PTR handle
)
{ /* Body */
    return (eport_ptr->EPFR & handle->pinmask) ? TRUE : FALSE;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : lwgpio_int_clear_flag
* Returned Value   : void
* Comments         :
*    Clears pending interrupt flag on peripheral
*
*END*********************************************************************/
void lwgpio_int_clear_flag
(
    /* Pin handle to clear interrupt flag on */
    LWGPIO_STRUCT_PTR handle
)
{ /* Body */
    /* Clear interrupt flag. Note that if an interrupt was acknowledged by NVIC,
    it will generate interrupt anyway. Interrupts on NVIC are grouped for each
    port */
    eport_ptr->EPFR = handle->pinmask;
}


/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_int_get_vector
* Returned Value   : vector index
* Comments         :
*    This function returns vector index for specified pin
*
*END*********************************************************************/
uint_32 lwgpio_int_get_vector
(
    /* Pin handle to get vector of */
    LWGPIO_STRUCT_PTR  handle
)
{
    return MCF5225_INT_EPORT0_EPF1 - 1 + LWGPIO_PIN_FROM_ID(handle->flags);
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enmediactl.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved
*
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enmediactl.c$
* $Version : 3.5.2.0$
* $Date    : Nov-27-2009$
*
* Comments:
*
*   This file contains the Ethernet IOCTL implementation
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

#include "enet.h"
#include "enetprv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_mediactl
*  PARAMS         : handle -> handle to enet layer.
*                   command_id -> ENET command to execute.
*                   inout_param -> input/output data for command.
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Joins a multicast group on an Ethernet channel.
*
*END*-----------------------------------------------------------------*/
uint_32 ENET_mediactl
   (
      /* [IN] the Ethernet state structure */
      _enet_handle      handle,

      /* [IN] IOCTL COMMAND */
      uint_32           command_id,

      /* [IN]/[OUT] input/output param */
      pointer     inout_param
   )
{ 
   uint_32 error = ENET_ERROR;
   ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

   #if MQX_CHECK_ERRORS
      if (NULL == handle) {
         return ENET_ERROR;
      } /* Endif */
   #endif

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself and with ENET_leave.
   */
   if (enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->MEDIACTL)
   {  
      error =  (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->MEDIACTL)(enet_ptr, command_id,inout_param);
   }
   
   return error;
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/genmd5.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: genmd5.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file generates the lookup table for the MD5 hash.
*
*END************************************************************************/

#include <stdio.h>
#include <math.h>
#define SIZE 64

#if RCTSCFG_GENERATE_HASH_TABLES && RTCSCFG_ENABLE_IP4
/* Start CR 1679 */
int RTCS_PPP_SUPPORT_genmd5 (void)
/* End CR 1679 */
{ /* Body */
   int count = 0;

   printf("/*\n** The MD5 Lookup Table\n*/\n\n"
          "static uint_32 mdtab[] = {");

   for (;;) {
      if (!(count%4)) printf("\n  ");
      printf(" 0x%08lXl", (long)ldexp(fabs(sin(++count)),32));
      if (count == SIZE) break;
      printf(",");
   } /* Endfor */
   printf("\n};\n");

   return 0;
} /* Endbody */
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/rtcslog1.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcslog1.c$
* $Version : 3.7.9.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the RTCS logging control functions.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"

#if RTCSCFG_LOGGING
#if RTCSCFG_LOG_SOCKET_API || RTCSCFG_LOG_PCB || RTCSCFG_LOGGING
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSLOG_enable
* Returned Value  : void
* Comments  :  Enables logging of certain RTCS events
*
*END*-----------------------------------------------------------------*/

void RTCSLOG_enable
   (
      uint_32     logtype
         /* [IN] the type of log entry to enable */
   )
{ /* Body */
   RTCS_DATA_PTR rtcs = RTCS_get_data();

   if (rtcs) {
      rtcs->RTCS_LOG_CONTROL |= logtype;
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_IFTYPE (IPIFTYPE_ETHERNET) );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_IFTYPE (IPIFTYPE_PPP)      );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_IFTYPE (IPIFTYPE_LOOPBACK) );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_ARP    (IPIFTYPE_ETHERNET) );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO  (IPPROTO_ICMP)      );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO  (IPPROTO_IGMP)      );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO  (IPPROTO_IP)        );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO  (IPPROTO_TCP)       );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO  (IPPROTO_UDP)       );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PROTO  (IPPROTO_OSPF)      );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PORT   (IPPORT_BOOTPC)     );
      RTCSLOG_enable_prot(logtype, RTCS_LOGCTRL_PORT   (IPPORT_RIP)        );
   }
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSLOG_disable
* Returned Value  : void
* Comments  :  Disables logging of certain RTCS events
*
*END*-----------------------------------------------------------------*/

void RTCSLOG_disable
   (
      uint_32     logtype
         /* [IN] the type of log entry to disable */
   )
{ /* Body */
   RTCS_DATA_PTR rtcs = RTCS_get_data();
   uint_32       i;

   if (rtcs) {
      rtcs->RTCS_LOG_CONTROL &= ~logtype;

      if (logtype & RTCS_LOGCTRL_PCB) {
         for (i=0; i<RTCSLOG_PROT_MAX; i++) {
            rtcs->RTCS_LOG_PCB[i] = 0;
         } /* Endfor */
      } /* Endif */

      if (logtype & RTCS_LOGCTRL_TIMER) {
         for (i=0; i<RTCSLOG_PROT_MAX; i++) {
            rtcs->RTCS_LOG_TIMER[i] = 0;
         } /* Endfor */
      } /* Endif */
   }
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSLOG_enable_prot
* Returned Value  : void
* Comments  :  Enables logging of certain RTCS events for a specific
*              protocol
*
*END*-----------------------------------------------------------------*/

void RTCSLOG_enable_prot
   (
      uint_32     logtype,
         /* [IN] the type of log entry to enable */
      uint_32     protocol
         /* [IN] the protocol to enable */
   )
{ /* Body */
   RTCS_DATA_PTR rtcs = RTCS_get_data();
   uint_32       i, j;

   rtcs->RTCS_LOG_CONTROL |= logtype;

   if (logtype & RTCS_LOGCTRL_PCB) {
      j = RTCSLOG_PROT_MAX;
      for (i = RTCSLOG_PROT_MAX; i > 0; ) {
         i--;
         if (rtcs->RTCS_LOG_PCB[i] == protocol) {
            j = i;
            break;
         } else if (rtcs->RTCS_LOG_PCB[i] == 0) {
            j = i;
         } /* Endif */
      } /* Endfor */
      if (j < RTCSLOG_PROT_MAX) {
         rtcs->RTCS_LOG_PCB[j] = protocol;
      } /* Endif */
   } /* Endif */

   if (logtype & RTCS_LOGCTRL_TIMER) {
      j = RTCSLOG_PROT_MAX;
      for (i = RTCSLOG_PROT_MAX; i > 0; ) {
         i--;
         if (rtcs->RTCS_LOG_TIMER[i] == protocol) {
            j = i;
            break;
         } else if (rtcs->RTCS_LOG_TIMER[i] == 0) {
            j = i;
         } /* Endif */
      } /* Endfor */
      if (j < RTCSLOG_PROT_MAX) {
         rtcs->RTCS_LOG_TIMER[j] = protocol;
      } /* Endif */
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCSLOG_disable_prot
* Returned Value  : void
* Comments  :  Disables logging of certain RTCS events for a specific
*              protocol
*
*END*-----------------------------------------------------------------*/

void RTCSLOG_disable_prot
   (
      uint_32     logtype,
         /* [IN] the type of log entry to disable */
      uint_32     protocol
         /* [IN] the protocol to disable */
   )
{ /* Body */
   RTCS_DATA_PTR rtcs = RTCS_get_data();
   uint_32       i, j;

   rtcs->RTCS_LOG_CONTROL &= ~logtype | (RTCS_LOGCTRL_PCB | RTCS_LOGCTRL_TIMER);

   if (logtype & RTCS_LOGCTRL_PCB) {
      j = RTCSLOG_PROT_MAX;
      for (i = 0; i < RTCSLOG_PROT_MAX; i++) {
         if (rtcs->RTCS_LOG_PCB[i] == protocol) {
            rtcs->RTCS_LOG_PCB[i] = 0;
         } else if (rtcs->RTCS_LOG_PCB[i] != 0) {
            j = i;
         } /* Endif */
      } /* Endfor */
      if (j < RTCSLOG_PROT_MAX) {
         rtcs->RTCS_LOG_CONTROL &= ~RTCS_LOGCTRL_PCB;
      } /* Endif */
   } /* Endif */

   if (logtype & RTCS_LOGCTRL_TIMER) {
      j = RTCSLOG_PROT_MAX;
      for (i = 0; i < RTCSLOG_PROT_MAX; i++) {
         if (rtcs->RTCS_LOG_TIMER[i] == protocol) {
            rtcs->RTCS_LOG_TIMER[i] = 0;
         } else if (rtcs->RTCS_LOG_TIMER[i] != 0) {
            j = i;
         } /* Endif */
      } /* Endfor */
      if (j < RTCSLOG_PROT_MAX) {
         rtcs->RTCS_LOG_CONTROL &= ~RTCS_LOGCTRL_TIMER;
      } /* Endif */
   } /* Endif */

} /* Endbody */

#endif
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/gpio/mcf5225/io_gpio_mcf5225.h<|end_filename|>
#ifndef __io_gpio_cpu_h__
#define __io_gpio_cpu_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_gpio_mcf5225x.h$
* $Version : 3.0.14.0$
* $Date    : May-21-2009$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

typedef struct irq_map_struct {
   uint_8  portnq;
} GPIO_IRQ_MAP, _PTR_ GPIO_IRQ_MAP_PTR;

#define GPIO_PORT_TE ((0x0000 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_TF ((0x0001 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_TG ((0x0002 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_TH ((0x0003 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_TI ((0x0004 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_TJ ((0x0006 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_NQ ((0x0008 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_AN ((0x000A << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_AS ((0x000B << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_QS ((0x000C << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_TA ((0x000E << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_TC ((0x000F << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_UA ((0x0011 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_UB ((0x0012 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_UC ((0x0013 << 3) | GPIO_PIN_VALID)
#define GPIO_PORT_DD ((0x0014 << 3) | GPIO_PIN_VALID)

#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/ifnat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifnat.c$
* $Version : 3.0.2.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the NAT interface functions.
*
*END************************************************************************/


#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_init
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Starts network address translation.
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_init
   (
      _ip_address    private_network,
      _ip_address    private_netmask
   )
{ /* Body */
   NAT_PARM    parms;
   
   parms.IP_PRV = private_network;
   parms.IP_MASK = private_netmask;
   
   return RTCSCMD_issue(parms, NAT_init_internal);
   
} /* Endbody */
   
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_add_network
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Add another private network.
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_add_network
   (
      _ip_address    private_network,
      _ip_address    private_netmask
   )
{ /* Body */
   NAT_PARM    parms;
   
   parms.IP_PRV = private_network;
   parms.IP_MASK = private_netmask;
   
   return RTCSCMD_issue(parms, NAT_add_network_internal);
   
} /* Endbody */
   

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_remove_network
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Add another private network.
*
*END*-----------------------------------------------------------------*/

uint_32 NAT_remove_network
   (
      _ip_address    private_network,
      _ip_address    private_netmask
   )
{ /* Body */
   NAT_PARM    parms;
   
   parms.IP_PRV = private_network;
   parms.IP_MASK = private_netmask;
   
   return RTCSCMD_issue(parms, NAT_remove_network_internal);
   
} /* Endbody */
   

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_close
* Returned Value  : RTCS_OK or error code
* Comments        :
*        Stops network address translation.
*
*END*-----------------------------------------------------------------*/
   
uint_32 NAT_close
   (
      void
   )
{ /* Body */
   NAT_PARM    parms;

   return RTCSCMD_issue(parms, NAT_close_internal);
   
} /* Endbody */
      

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_stats
* Returned Value  : NULL, or a pointer to the NAT stats
* Comments        :
*        Returns a pointer to the NAT statistics
*
*END*-----------------------------------------------------------------*/

NAT_STATS_PTR NAT_stats
   (
      void
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR nat_cfg_ptr = RTCS_getcfg(NAT);
   
   if (nat_cfg_ptr) {
      return &nat_cfg_ptr->STATS;
   } /* Endif */
 
   return NULL;  
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_networks
* Returned Value  : NULL, or a pointer to the NAT networks structure
* Comments        :
*        Returns a pointer to the NAT statistics
*
*END*-----------------------------------------------------------------*/

NAT_NETWORK_STRUCT_PTR NAT_networks
   (
      void
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR nat_cfg_ptr = RTCS_getcfg(NAT);
   
   if (nat_cfg_ptr) {
      return &nat_cfg_ptr->PRIVATE_NETWORKS;
   } /* Endif */
 
   return NULL;  
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_find_next_session
* Returned Value  : 
* Comments        :
*        
*
*END*-----------------------------------------------------------------*/

pointer NAT_find_next_session
   (
      pointer  session,
      uint_32  tree
   )
{ /* Body */
   NAT_PARM    parms;
   uint_32     result;
   
   parms.CONFIG = session;
   parms.OPTION = tree;
   
   result = RTCSCMD_issue(parms, NAT_find_next_session_internal);
   if (result != RTCS_OK) {
      return NULL;
   }
 
   return parms.CONFIG;  
} /* Endbody */

#endif


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/polled/i2c_pol_prv.h<|end_filename|>
#ifndef _i2c_pol_prv_h_
#define _i2c_pol_prv_h_ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_pol_prv.h$
* $Version : 3.0.1.0$
* $Date    : Jun-4-2009$
*
* Comments:
*
*   This file includes the private definitions for the polled I2C
*   serial I/O drivers.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/


/*---------------------------------------------------------------------
**
** IO I2C POLLED DEVICE STRUCT
**
** This structure used to store information about an I2C polled io device
** for the IO device table
*/
typedef struct io_i2c_polled_device_struct
{

   /* The I/O init function */
   _mqx_uint (_CODE_PTR_ DEV_INIT)(pointer, pointer _PTR_, char_ptr);

   /* The I/O deinit function */
   _mqx_uint (_CODE_PTR_ DEV_DEINIT)(pointer, pointer);
   
   /* The read function */
   _mqx_int  (_CODE_PTR_ DEV_READ)(pointer, char_ptr, _mqx_int);
      
   /* The write function */
   _mqx_int  (_CODE_PTR_ DEV_WRITE)(pointer, char_ptr, _mqx_int);
   
   /* The ioctl function, (change bauds etc) */
   _mqx_int  (_CODE_PTR_ DEV_IOCTL)(pointer, _mqx_uint, _mqx_uint_ptr);

   /* The I/O channel initialization data */
   pointer               DEV_INIT_DATA_PTR;
   
   /* Device specific information */
   pointer               DEV_INFO_PTR;

   /* Open count for number of accessing file descriptors */
   _mqx_uint             COUNT;

   /* Open flags for this channel */
   _mqx_uint             FLAGS;

} IO_I2C_POLLED_DEVICE_STRUCT, _PTR_ IO_I2C_POLLED_DEVICE_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

/* I/O prototypes */
extern _mqx_int _io_i2c_polled_open (FILE_DEVICE_STRUCT_PTR, char_ptr, char_ptr);
extern _mqx_int _io_i2c_polled_close (FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_i2c_polled_read (FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_i2c_polled_write (FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_i2c_polled_ioctl (FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);
extern _mqx_int _io_i2c_polled_uninstall (IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pccard/pccardflexbus.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pccardflexbus.c$
* $Version : 3.8.14.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   PC Card FlexBus device driver functions.
*   Uses memory mapped access to PC Card.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "bsp.h"
#include "bsp_prv.h"
#include "fio.h"
#include "io.h"
#include "io_prv.h"
#include "pccardflexbus.h"
#include "pccardflexbuspr.h"


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pccard_install
* Returned Value   : uint_32 - a task error code or MQX_OK 
* Comments         : Install the PC Card device driver
*
*END*-------------------------------------------------------------------------*/

uint_32 _io_pccardflexbus_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr                    identifier,

      /* [IN] Pointer to initialization info. */
      PCCARDFLEXBUS_INIT_STRUCT_CPTR  init_ptr
   )
{ /* Body */
  IO_PCCARDFLEXBUS_STRUCT_PTR      info_ptr;

   /* Allocate memory for the PCCARD state structure */
  info_ptr = (IO_PCCARDFLEXBUS_STRUCT_PTR)_mem_alloc_system_zero((uint_32)sizeof(IO_PCCARDFLEXBUS_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (!info_ptr) {
      return MQX_OUT_OF_MEMORY;
   } /* Endif */
#endif
   
   info_ptr->INIT_DATA = *init_ptr;

   return (_io_dev_install(identifier,
      _io_pccardflexbus_open,
      _io_pccardflexbus_close,
      NULL,
      NULL,
      _io_pccardflexbus_ioctl,
      (pointer)info_ptr));
} /* Endbody */   

/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pccardflexbus_open
* Returned Value   : 
* Comments         :
*
*END*-------------------------------------------------------------------------*/

_mqx_int _io_pccardflexbus_open
   (
      /* [IN] the file handle for the device being opened */
      FILE_DEVICE_STRUCT_PTR   fd_ptr,
      
      /* [IN] the remaining portion of the name of the device */
      char _PTR_               open_name_ptr,

      /* [IN] the flags to be used during operation (not used) */
      char _PTR_               flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR          io_dev_ptr = fd_ptr->DEV_PTR;
   IO_PCCARDFLEXBUS_STRUCT_PTR   info_ptr   = (IO_PCCARDFLEXBUS_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   
   /* Initialize mini flexbus */
   _bsp_flexbus_pccard_setup((uint_32)info_ptr->INIT_DATA.PCMCIA_BASE);   

  /* 
   ** Allocate driver a PCMCIA CS for attribute space. This is needed for
   ** functions that access the CIS. Slot A has offset 0 while slot B has 
   ** the next offset PCCARDFLEXBUS_ATTRIB_SIZE to ensure they don't overlap.
   */
   info_ptr->PCMCIA_BASE = (volatile uchar _PTR_)info_ptr->INIT_DATA.PCMCIA_BASE;
   info_ptr->ATTRIB_PTR  = (volatile uchar _PTR_)((uint_32)info_ptr->PCMCIA_BASE | PCCARDFLEXBUS_REGISTER_MASK);

    /* Detect if card is present in slot */
   if (_io_pccardflexbus_card_detect(info_ptr)) 
   {
      _time_get_elapsed(&info_ptr->START_TIME);
      info_ptr->STATE   = PCCARDFLEXBUS_CARD_INSERTED;
      info_ptr->CARD_IN = TRUE;
   } 
   else 
   {
      info_ptr->STATE   = PCCARDFLEXBUS_CARD_REMOVED;
      info_ptr->CARD_IN = FALSE;
   } 

   return MQX_OK;

} /* Endbody */

/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pccardflexbus_close
* Returned Value   : 
* Comments         :
*
*END*-------------------------------------------------------------------------*/

_mqx_int _io_pccardflexbus_close
   (
      /* [IN] the file handle for the device being closed */
      FILE_DEVICE_STRUCT_PTR fd_ptr
   )
{ /* Body */
   /* Nothing to be done here */
   return MQX_OK;
} /* Endbody */

/*FUNCTION*---------------------------------------------------------------------
* 
* Function Name    : _io_pccardflexbus_ioctl
* Returned Value   : int_32
* Comments         :
*    Returns result of ioctl operation.
*
*END*-------------------------------------------------------------------------*/

_mqx_int _io_pccardflexbus_ioctl
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint              cmd,

      /* [IN] the ioctl parameters */
      pointer                input_param_ptr
   )
{ /* Body */
   APCCARD_ADDR_INFO_STRUCT_PTR   addr_ptr;
   IO_DEVICE_STRUCT_PTR           io_dev_ptr = fd_ptr->DEV_PTR;
   IO_PCCARDFLEXBUS_STRUCT_PTR    info_ptr = (IO_PCCARDFLEXBUS_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;
   int_32                         result   = MQX_OK;
   uint_32_ptr                    param_ptr = input_param_ptr;
   
   switch (cmd) {
      case APCCARD_IOCTL_IS_CARD_INSERTED:
         *param_ptr = _io_pccardflexbus_card_detect(info_ptr);
         break;
      case APCCARD_IOCTL_GET_ADDR_SPACE:
         addr_ptr = (APCCARD_ADDR_INFO_STRUCT_PTR)((pointer)param_ptr);
         addr_ptr->ADDRESS = (pointer)(((uint_32)info_ptr->PCMCIA_BASE | PCCARDFLEXBUS_COMMON_MEM_MASK) + addr_ptr->OFFSET);
         break;

      case APCCARD_IOCTL_FREE_ADDR_SPACE:
         break;
      case APCCARD_IOCTL_POWERDOWN_CARD:
         break;
      case APCCARD_IOCTL_CARD_READY:
         *param_ptr = info_ptr->STATE == PCCARDFLEXBUS_ACCESS_ALLOWED;
         break;
      case APCCARD_IOCTL_WAIT_TILL_READY:
         _io_pccardflexbus_card_wait_till_ready(info_ptr);
         break;
      case APCCARD_IOCTL_READ_TUPLE:
         _io_pccardflexbus_read_tuple(info_ptr->ATTRIB_PTR,
            *param_ptr, (uchar_ptr)(param_ptr + 1));
            break;
      case IO_IOCTL_DEVICE_IDENTIFY:
         param_ptr[0] = IO_DEV_TYPE_PHYS_ADV_PCCARD;
         param_ptr[1] = 0;
         param_ptr[2] = 0;
         break;
// folowing io-controls can not be supported by Flexbus CF driver 
//       case APCCARD_IOCTL_SET_CRD_INSERT_CALLBACK:
//       case APCCARD_IOCTL_SET_CRD_REMOVE_CALLBACK:
//       case APCCARD_IOCTL_VCC_ENABLE:
//       case APCCARD_IOCTL_VPP_ENABLE:
//       case APCCARD_IOCTL_SENSE_VOLTAGE:
//       case APCCARD_IOCTL_RESET:
//       case APCCARD_IOCTL_POWERUP_CARD:

      default:
         result = IO_ERROR_INVALID_IOCTL_CMD;
         break;
   } /* Endswitch */

   return result;

} /* Endbody */



/* Private functions */
/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pccardflexbus_card_detect
* Returned Value   : TRUE is card is in, FALSE otherwise
* Comments         :
*
*END*-------------------------------------------------------------------------*/

boolean _io_pccardflexbus_card_detect    
   (
      /* [IN] The info driver */
      IO_PCCARDFLEXBUS_STRUCT_PTR  info_ptr
   )
{ /* Body */
   uint_16 card_state; 
   
#if (BSP_PCCARDFLEXBUS_WIDTH == 2) 
   card_state = *(volatile uint_16 *)((uint_32)info_ptr->PCMCIA_BASE | PCCARDFLEXBUS_CARD_PRESENT_MASK);
#else
   card_state = *(volatile uchar *)((uint_32)info_ptr->PCMCIA_BASE | PCCARDFLEXBUS_CARD_PRESENT_MASK);
#endif
   
   if(card_state == BSP_PCCARDFLEXBUS_CARD_PRESENT) // card is in the slot
      return (TRUE);
   else if (card_state == BSP_PCCARDFLEXBUS_SLOT_EMPTY) // card is not present in the slot
      return (FALSE);
   else // wrong CPLD code 
      return (FALSE);
} /* Endbody */



/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pccardflexbus_card_wait_till_ready
* Returned Value  : none
* Comments        : waits until the card has had a chance to powerup 
*   completely.
*   
*
*END*---------------------------------------------------------------------*/

void _io_pccardflexbus_card_wait_till_ready
   (
      /* [IN] The info for this slot */
      IO_PCCARDFLEXBUS_STRUCT_PTR  info_ptr
   )
{ /* Body */

   /* Wait until the card is ready */
   if (!info_ptr->CARD_IN) {
      return;
   } /* Endif */

   _io_pccardflexbus_wait(info_ptr, PCCARDFLEXBUS_RESET_ALLOWED_TIME);

} /* Endbody */



/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_pccardflexbus_card_wait
* Returned Value  : none
* Comments        : 
*   
*
*END*---------------------------------------------------------------------*/

void _io_pccardflexbus_wait
   (
      /* [IN] The info for this slot */
      IO_PCCARDFLEXBUS_STRUCT_PTR  info_ptr,

      /* [IN] The time to wait in ms */
      uint_32                    wait_ms
   )
{ /* Body */
   TIME_STRUCT   now, diff;
   uint_32       diff_ms = 0;

   while (diff_ms < wait_ms) {
      _time_get_elapsed(&now);
      _time_diff(&info_ptr->START_TIME, &now, &diff);
      diff_ms = diff.MILLISECONDS + diff.SECONDS * 1000;
   } /* Endwhile */
      
} /* Endbody */



/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _io_apccardflexbus_read_tuple
* Returned Value  : uint_32 - actual size of tuple info data
* Comments        :
*   This function finds and reads the specified tuple
*
*END*---------------------------------------------------------------------*/

uint_32 _io_pccardflexbus_read_tuple
   (
      /* [IN] Pointer to the start of the CIS */
      volatile uchar _PTR_  cis_ptr,

      /* [IN] The tuple to search for */
      uint_32               tuple_code,

      /* [IN] Address to store the tuple data */
      uchar_ptr             dest_ptr

   )
{ /* Body */
   int                        i;
   int                        tuple_size;
   volatile uchar             cis_data;
   volatile uchar _PTR_       cis_end;
   
#if (PSP_ENDIAN == MQX_BIG_ENDIAN) && (BSP_PCCARDFLEXBUS_WIDTH == 2)
   /* if the bus is 16 bits wide and platform is big endian,
      then use odd addresses to read lower half of data bus */
   cis_ptr = (uchar _PTR_)((uint_32)cis_ptr | 0x01);
#endif

   cis_end = cis_ptr + (0x1000<<BSP_PCCARDFLEXBUS_ADDR_SHIFT);
   
   /* search CIS for tuple_code */
   while ((cis_data = *cis_ptr) != tuple_code) {   

      if (cis_data == IO_APCCARD_TUPLE_END_OF_CIS)
        return 0; /* Reached end of CIS */

      /* Handle null tuple */
      if (cis_data == IO_APCCARD_TUPLE_CISTPL_NULL) {
        /* Just advance next position */
        tuple_size = 0;      	
      }
      else {
        /* Get link field */
        cis_ptr += IO_APCCARD_TUPLE_LINK_CIS_OFFSET<<BSP_PCCARDFLEXBUS_ADDR_SHIFT;
        if(cis_ptr >= cis_end)
          return 0; // tuple not found
        tuple_size = *cis_ptr;
      }      

      /* Calculate the location of the next tuple  */
      cis_ptr += ((tuple_size + 1) * 2)<<BSP_PCCARDFLEXBUS_ADDR_SHIFT;
      if(cis_ptr >= cis_end)
        return 0; // tuple not found
        
   } /* Endwhile */

   /* Get link field */
   tuple_size = cis_ptr[IO_APCCARD_TUPLE_LINK_CIS_OFFSET<<BSP_PCCARDFLEXBUS_ADDR_SHIFT];

   /* Advance to tuple data */
   cis_ptr += IO_APCCARD_TUPLE_DATA_CIS_OFFSET<<BSP_PCCARDFLEXBUS_ADDR_SHIFT;

   for (i = 0; i < tuple_size; i++) {
      *dest_ptr = *cis_ptr;
      dest_ptr++;
      cis_ptr += 2<<BSP_PCCARDFLEXBUS_ADDR_SHIFT;
   } /* Endfor */

   return tuple_size;

} /* Endbody */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_sendto.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_sendto.c$
* $Version : 3.8.7.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Example using RTCS Library.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h" 
#if SHELLCFG_USES_RTCS
#include <rtcs.h>
#include "sh_rtcs.h" 



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :   Shell_sendto
* Returned Value   :  int_32 error code
* Comments  :  Send a UDP broadcase packet to the local network.
*
*END*---------------------------------------------------------------------*/

int_32  Shell_sendto(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean           print_usage, shorthelp = FALSE;
   int_32            return_code = SHELL_EXIT_SUCCESS;
   uint_32           length = 64, count = 1, port =0;
   _ip_address       hostaddr = 0;
   char              hostname[MAX_HOSTNAMESIZE];

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if ((argc<3) || (argc>5)) {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } else {
         if (argc>4) {
            if (! Shell_parse_number( argv[4], &count ))  {
               printf("Error, invalid count\n");
               return_code = SHELL_EXIT_ERROR;
            }
         }
         if (argc>3) {
            if (! Shell_parse_number( argv[3], &length ))  {
               printf("Error, invalid length\n");
               return_code = SHELL_EXIT_ERROR;
            }
         }

         if (! Shell_parse_number( argv[2], &port ))  {
            printf("Error, invalid port\n");
            return_code = SHELL_EXIT_ERROR;
         }

         RTCS_resolve_ip_address( argv[1], &hostaddr, hostname, MAX_HOSTNAMESIZE ); 

         if (!hostaddr)  {
            printf("Unable to resolve host\n");
            return_code = SHELL_EXIT_ERROR;
         } else  {
            printf("Sending to %s [%ld.%ld.%ld.%ld]:\n", hostname, IPBYTES(hostaddr));
         }

      }
      if (return_code != SHELL_EXIT_ERROR) {
         uchar_ptr   buffer = _mem_alloc(length);
         uint_32     sock = socket(PF_INET, SOCK_DGRAM, 0);
         sockaddr_in laddr, raddr;
         uint_32     result;
         uint_32     i;
         uint_16     rlen = sizeof(raddr);

         if ((buffer!=NULL) && (sock!=RTCS_SOCKET_ERROR)) {
            memset((char *) &laddr, 0, sizeof(laddr));
            laddr.sin_family = AF_INET;
            laddr.sin_port = 0;
            laddr.sin_addr.s_addr = INADDR_ANY;

            raddr.sin_family = AF_INET;
            raddr.sin_port = (uint_16) port;
            raddr.sin_addr.s_addr = hostaddr;


            result = bind(sock, (const struct sockaddr *)&laddr, sizeof (sockaddr_in));
            if (result != RTCS_OK) {   
               printf("Error, unable to bind socket\n");
               return_code = SHELL_EXIT_ERROR;
            } else {

               for (i=0;i<length;i++) {
                  buffer[i] = (uchar) (i & 0xff);
               }
               printf("\n");
               for (i=0;i<count;i++) {
                  printf("Sending  packet # %d\r",i+1);
                  sendto(sock, buffer, length, 0, (sockaddr *)&raddr, rlen);
               }
               printf("\n");
            }
         } else {
            printf("Error, unable to allocate resources for this command\n");
            return_code = SHELL_EXIT_ERROR;
         }
         if (sock!=RTCS_SOCKET_ERROR) {
            shutdown(sock, FLAG_ABORT_CONNECTION);
         }
         if (buffer!=NULL) {
            _mem_free(buffer);
         }
      }
   }
   
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <host> <port> [<length>] [<count>]\n", argv[0]);
      } else  {
         printf("Usage: %s <host> <port> [<length>] [<count>]\n", argv[0]);
         printf("   <host>   = destination host\n");
         printf("   <port>   = destination port\n");
         printf("   <length> = number of bytes\n");
         printf("   <count>  = number of messages\n");
      }
   }
   return return_code;
} /* Endbody */
#endif /* SHELLCFG_USES_RTCS */
/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwadc/lwadc_mpxsxx.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2011 Embedded Access Inc
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwadc_mpxsxx.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END************************************************************************/

#ifndef __lwadc_mpxsxx_h__
#define __lwadc_mpxsxx_h__

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

#define ADC_RESOLUTION_12BIT    0x1000
#define ADC_RESOLUTION_DEFAULT  ADC_RESOLUTION_12BIT

#define ADC_DEV_SHIFT           (4)
#define ADC_DEV_MASK            (0xf0)
#define ADC_CHANNEL_MASK        (0xf)

#define ADC_INPUT(dev,channel)  (dev<<ADC_DEV_SHIFT | channel)
#define ADC_DEVICE(input)       (input>>ADC_DEV_SHIFT)
#define ADC_CHANNEL(input)      (input&ADC_CHANNEL_MASK)
#define ADC_SOURCE_AN0          0x00
#define ADC_SOURCE_AN1          0x01
#define ADC_SOURCE_AN2          0x02
#define ADC_SOURCE_AN3          0x03
#define ADC_SOURCE_AN4          0x04
#define ADC_SOURCE_AN5          0x05
#define ADC_SOURCE_AN6          0x06
#define ADC_SOURCE_AN7          0x07
#define ADC_SOURCE_AN8          0x08
#define ADC_SOURCE_AN9          0x09
#define ADC_SOURCE_AN10         0x0a
#define ADC_SOURCE_AN11         0x0b
#define ADC_SOURCE_AN12         0x0c
#define ADC_SOURCE_AN13         0x0d
#define ADC_SOURCE_AN14         0x0e
#define ADC_SOURCE_AN15         0x0f
#define ADC_SOURCE_MAX          0x0f

#define ADC_AN0_MASK            (1<<ADC_SOURCE_AN0)
#define ADC_AN1_MASK            (1<<ADC_SOURCE_AN1)
#define ADC_AN2_MASK            (1<<ADC_SOURCE_AN2)
#define ADC_AN3_MASK            (1<<ADC_SOURCE_AN3)
#define ADC_AN4_MASK            (1<<ADC_SOURCE_AN4)
#define ADC_AN5_MASK            (1<<ADC_SOURCE_AN5)
#define ADC_AN6_MASK            (1<<ADC_SOURCE_AN6)
#define ADC_AN7_MASK            (1<<ADC_SOURCE_AN7)
#define ADC_AN8_MASK            (1<<ADC_SOURCE_AN8)
#define ADC_AN9_MASK            (1<<ADC_SOURCE_AN9)
#define ADC_AN10_MASK           (1<<ADC_SOURCE_AN10)
#define ADC_AN11_MASK           (1<<ADC_SOURCE_AN11)
#define ADC_AN12_MASK           (1<<ADC_SOURCE_AN12)
#define ADC_AN13_MASK           (1<<ADC_SOURCE_AN13)
#define ADC_AN14_MASK           (1<<ADC_SOURCE_AN14)
#define ADC_AN15_MASK           (1<<ADC_SOURCE_AN15)

#define ADC_ALL_CHANNEL_MASK    (0x0000ffff)


typedef struct lwadc_init_struct {
    uint_32                     device;
    uint_32                     format;
    uint_32                     clock;
    uint_32                     reference;
}LWADC_INIT_STRUCT, * LWADC_INIT_STRUCT_PTR;


typedef struct adc_context {
    VPXADC_REG_STRUCT_PTR       adc_ptr;
    const LWADC_INIT_STRUCT *   init_ptr;
    uint_32                     mcr;
    uint_32                     channels;
}ADC_CONTEXT, * ADC_CONTEXT_PTR;

typedef struct lwadc_struct {
    ADC_CONTEXT_PTR             context_ptr;
    uint_32                     input;
    uint_32                     mask;
    uint_32                     numerator;
    uint_32                     denominator;
}LWADC_STRUCT, * LWADC_STRUCT_PTR;



#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/tfs/tfs.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tfs.c$
* $Version : 3.8.10.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the functions that are used to initialize TFS
*   It also contains the TFS driver functions.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>
#include <io_prv.h>

#include <tfs.h>
#include <tfs_prv.h>
 
 
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_tfs_install
* Returned Value   : TFS error code.
* Comments         : Initialize the Trivial File System.
*
*END*---------------------------------------------------------------------*/

uint_32 _io_tfs_install
   (
      /*[IN] the name that should be given to tfs (ex: "C:", "TFS1:", etc..) */
      char_ptr              identifier,
      
      /*[IN] pointer to the first entry of the root TFS directory  */  
      const TFS_DIR_ENTRY   *root
   )
{ /* Body */
   uint_32                      error_code;
   TFS_DRIVE_STRUCT_PTR         drive_ptr;
   
   drive_ptr = _mem_alloc_system_zero( sizeof(TFS_DRIVE_STRUCT) );
   if ( drive_ptr == NULL ) {
      return( TFS_INSUFFICIENT_MEMORY );
   }/* Endif */
   _mem_set_type(drive_ptr,MEM_TYPE_IO_TFS_DRIVE_STRUCT);      
   
   _int_disable();

   error_code = _io_dev_install_ext( identifier, 
      _io_tfs_open,                     
      _io_tfs_close, 
      _io_tfs_read,                      
      _io_tfs_write,                     
      _io_tfs_ioctl,
      _io_tfs_uninstall,
      (pointer)drive_ptr);

   if (error_code != IO_OK) {
      _mem_free(drive_ptr);
      drive_ptr = NULL;
      _int_enable();      
      return error_code;
   } /* Endif */

   drive_ptr->IDENTIFIER = identifier;
   drive_ptr->ROOT     = root;
 
   _int_enable();

   return(error_code);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_tfs_uninstall
* Returned Value   : TFS error code.
* Comments  :   Uninstalls the Trivial File System and frees all memory allocated
*               to it.
*
*END*---------------------------------------------------------------------*/

int_32 _io_tfs_uninstall
   (
       /* [IN/OUT] The device to uninstall */            
      IO_DEVICE_STRUCT_PTR   dev_ptr
   )
{ /* Body */
   TFS_DRIVE_STRUCT_PTR   drive_ptr;
   int_32                 error;
   
   drive_ptr = (TFS_DRIVE_STRUCT_PTR)dev_ptr->DRIVER_INIT_PTR;
   if (drive_ptr) {
      _mem_free(drive_ptr);
      dev_ptr->DRIVER_INIT_PTR = NULL;
      error = TFS_NO_ERROR;
   } else {
      error = TFS_SHARING_VIOLATION;
   } /* Endif */

   return error;

} /* Endbody */

 
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_tfs_open
* Returned Value   : TFS error code.
* Comments         : Opens TFS driver and initializes given file descriptor.
* 
*END*----------------------------------------------------------------------*/

int_32 _io_tfs_open
   (
      /* [IN/OUT] the file handle for the device being opened */
      MQX_FILE_PTR             fd_ptr,
      
      /* [IN] the remaining portion of the name of the device */
      char_ptr                 open_name_ptr,

      /* [IN] the flags to specify file type:
      ** r  read
      ** w  write 
      */
      char_ptr                 flags_str
   )
{ /* Body */
    TFS_DRIVE_STRUCT_PTR        drive_ptr;
    uint_32                     error_code = TFS_NO_ERROR;
    
    drive_ptr = (TFS_DRIVE_STRUCT_PTR)fd_ptr->DEV_PTR->DRIVER_INIT_PTR;

    open_name_ptr = TFS_Parse_Out_Device_Name(open_name_ptr);

    /* Check for a filename, if none, then check for the temp flag */
    if ( *(open_name_ptr-1) != ':' ) {
       error_code = TFS_PATH_NOT_FOUND;         
    } else if ( *open_name_ptr == '\0' ) {
       error_code = TFS_PATH_NOT_FOUND;
    } else {
     /* 
     ** When opening a file, only read-only attributes are set. The other
     ** attributes (such as hidden, system, etc..) must be set afterwards
     ** with an ioctl call.
     */  
     switch ( *flags_str ) {
        case 'r':
           fd_ptr->DEV_DATA_PTR = TFS_Open_File(drive_ptr, open_name_ptr, &error_code);
           break;
        case 'w':
           error_code = TFS_DISK_IS_WRITE_PROTECTED;
           break;
        default:
           error_code = TFS_INVALID_PARAMETER;
           break;
     } /* Endswitch */
    } /* Endif */

    /* Check to make sure the error code is OK */
    if ( error_code == TFS_NO_ERROR ) {
      /* Initialise the file information fields */
      fd_ptr->LOCATION = 0; 
      fd_ptr->FLAGS = 0;    
      fd_ptr->ERROR = 0;    
      fd_ptr->SIZE = ((TFS_DIR_ENTRY_PTR)fd_ptr->DEV_DATA_PTR)->SIZE;
    } else {
      // An error occured, so the calling function (_io_fopen) will
      // free the MQX_FILE_PTR. Need to release the handle
      fd_ptr->ERROR = error_code;
      if (fd_ptr->DEV_DATA_PTR) {
         TFS_Close_File(fd_ptr);
      }
    }/* Endif */

   return(error_code);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_tfs_close
* Returned Value   : TFS error code.
* Comments         : Closes given file descriptor.
* 
*END*----------------------------------------------------------------------*/

int_32 _io_tfs_close
   (
      /* [IN/OUT] the file handle for the device being closed */
      MQX_FILE_PTR                   fd_ptr
   )
{ /* Body */
    uint_32                     error_code = TFS_NO_ERROR;
   
    if ( fd_ptr->DEV_DATA_PTR) {
        error_code = TFS_Close_File (fd_ptr);   
    }/* Endif */
         
    return(error_code);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_tfs_read
* Returned Value   : Number of characters read.
* Comments         : Reads data from given file.
* 
*END*----------------------------------------------------------------------*/

int_32 _io_tfs_read
   ( 
      /* [IN/OUT] the stream to perform the operation on */
      MQX_FILE_PTR file_ptr,

      /* [IN] the data location to write to */
      char_ptr    data_ptr,

      /* [IN] the number of bytes to read */
      int_32      num      
   )
{
    uint_32        bytes_read;
    uint_32        error_code = TFS_NO_ERROR;

    bytes_read = TFS_Read(file_ptr, num, data_ptr, &error_code);

    /* Check for EOF. The TFS EOF must be translated to the standard EOF */
    file_ptr->FLAGS = 0;
    if ( error_code == TFS_EOF ) 
    {
        file_ptr->FLAGS = IO_FLAG_AT_EOF;
    }
    if (error_code != TFS_NO_ERROR)
    {
        file_ptr->ERROR = error_code;
    }
    return( (int_32) bytes_read );
}   


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_tfs_write
* Returned Value   : Number of characters written.
* Comments         : Writes data to the given file.
* 
*END*----------------------------------------------------------------------*/

int_32 _io_tfs_write
   ( 
      /* [IN/OUT] the stream to perform the operation on */
      MQX_FILE_PTR file_ptr,

      /* [IN] the data location to read from */
      char_ptr    data_ptr,

      /* [IN] the number of bytes to read */
      int_32      num      
   )
{ /* Body */
    uint_32        bytes_written;
    uint_32        error_code = TFS_NO_ERROR;
   
    bytes_written = TFS_Write(file_ptr, num, data_ptr, &error_code);
    
    if (error_code != TFS_NO_ERROR)
    {
        file_ptr->ERROR = error_code;
    }
    return ((int_32)bytes_written);
   
} /* Endbody */  


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_tfs_ioctl
* Returned Value   : TFS error code.
* Comments         : Performs specified operation related to given file.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_tfs_ioctl
   ( 
      /* [IN] the stream to perform the operation on */
      MQX_FILE_PTR file_ptr,

      /* [IN] the ioctl command */
      _mqx_uint   cmd,

      /* [IN/OUT] the ioctl parameters */
      pointer     param_ptr
   )
{ /* Body */
    uint_32        error_code = TFS_NO_ERROR;
   
   switch (cmd) {
      case IO_IOCTL_SEEK:
        TFS_Move_File_Pointer(file_ptr, &error_code);
        file_ptr->FLAGS = 0;
        if ( error_code == TFS_EOF ) 
        {
            file_ptr->FLAGS = IO_FLAG_AT_EOF;
        }
        break;
      case IO_IOCTL_TFS_GET_NAME:
        if (file_ptr->DEV_DATA_PTR == NULL) 
        {
            error_code = TFS_ERROR_INVALID_FILE_HANDLE;
        }
        else
        {
            *((char_ptr _PTR_)param_ptr) = ((TFS_DIR_ENTRY_PTR)file_ptr->DEV_DATA_PTR)->NAME;
        }
        break;
      case IO_IOCTL_TFS_GET_ATTRIBUTES:
        if (file_ptr->DEV_DATA_PTR == NULL) 
        {
            error_code = TFS_ERROR_INVALID_FILE_HANDLE;
        }
        else
        {
            *((uint_32_ptr)param_ptr) = ((TFS_DIR_ENTRY_PTR)file_ptr->DEV_DATA_PTR)->FLAGS;
        }
        break;
      case IO_IOCTL_TFS_GET_LENGTH:
        if (file_ptr->DEV_DATA_PTR == NULL) 
        {
            error_code = TFS_ERROR_INVALID_FILE_HANDLE;
        }
        else
        {
            *((uint_32_ptr)param_ptr) = file_ptr->SIZE;
        }
        break;
      case IO_IOCTL_TFS_GET_CURRENT_DATA_PTR:
        if (file_ptr->DEV_DATA_PTR == NULL) 
        {
            error_code = TFS_ERROR_INVALID_FILE_HANDLE;
        }
        else
        {
            *((uchar_ptr _PTR_)param_ptr) = ((TFS_DIR_ENTRY_PTR)file_ptr->DEV_DATA_PTR)->DATA+file_ptr->LOCATION;
        }
        break;
      case IO_IOCTL_TFS_GET_LAST_ERROR:
        error_code = file_ptr->ERROR;
        break;
      default:
        error_code = IO_ERROR_INVALID_IOCTL_CMD;
        break;
   } /* Endswitch */
                  
   return( (_mqx_uint) error_code);
} /* Endbody */
  

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : TFS_Parse_Out_Device_name
* Returned Value   : A pointer to character following the semi-colon (':').
* Comments         : Isolates the devoce name and file name.
*
*END*---------------------------------------------------------------------*/

char_ptr TFS_Parse_Out_Device_Name
   (
      /* [IN] the stream to perform the operation on */
      char_ptr          name_ptr
   )
{ /* Body */
   char_ptr             start_path_ptr;
   
   start_path_ptr = name_ptr;
   
   /* Parse out the device name */
   while ((*start_path_ptr  != ':') && (*start_path_ptr != '\0') ) {
      start_path_ptr = start_path_ptr + 1;   
   } /* Endwhile */
   
   if ( *start_path_ptr == '\0' ) {
      start_path_ptr = name_ptr;
   } else {
      start_path_ptr++;
   }/* Endif */
   
   return (start_path_ptr );
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : TFS_Cmp
* Returned Value   : -1, 0, 1 depending on path1 <, ==, > path2.
* Comments         : Compares file paths. Not case sensitive. Both delimiters 
*                    '/' and '\' supported.
*
*END*---------------------------------------------------------------------*/

int_32 TFS_Cmp 
    (
        /* [IN] first file path to compare */
        char_ptr path1, 
        
        /* [IN] second file path to compare */
        char_ptr path2
    )
{ /* Body */
    uint_32 ch1, ch2;
    
    if (path1 == path2) return 0;
    if (path1 == NULL) return -1;
    if (path2 == NULL) return 1;
    do 
    {
        ch1 = *path1++;
        ch2 = *path2++;
        if ((uint_32)(ch1 - 'a') <= (uint_32)('z' - 'a')) ch1 = ch1 - 'a' + 'A';
        if (ch1 == '\\') ch1 = '/';
        if ((uint_32)(ch2 - 'a') <= (uint_32)('z' - 'a')) ch2 = ch2 - 'a' + 'A';
        if (ch2 == '\\') ch2 = '/';
        if ((ch1 == '\0') || (ch2 == '\0')) return (int_32)(ch1 - ch2);
    } while (ch1 == ch2);
    return (int_32)(ch1 - ch2);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : TFS_Open_File
* Returned Value   : Pointer to TFS directory entry or NULL.
* Comments         : Searches for specified file and returns directory entry.
*
*END*---------------------------------------------------------------------*/

pointer TFS_Open_File
    (
        /* [IN] TFS IO drive information */
        TFS_DRIVE_STRUCT_PTR   drive_ptr,

        /* [IN] file path */
        char_ptr               pathname,

        /* [OUT] error result */
        uint_32_ptr            error_ptr
    )
{ /* Body */
    TFS_DIR_ENTRY_PTR entry;
    
    if ((drive_ptr == NULL) || (pathname == NULL) || (*pathname == '\0')) 
    {
        *error_ptr = TFS_INVALID_PARAMETER;
        return NULL;
    } 
    *error_ptr = TFS_FILE_NOT_FOUND;
    entry = (TFS_DIR_ENTRY_PTR)drive_ptr->ROOT;
    while (entry->NAME != NULL)
    {
        if (TFS_Cmp (entry->NAME, pathname) == 0)
        {
            *error_ptr = TFS_NO_ERROR;
            return (pointer)entry;
        }
        entry++;
    }
    return NULL;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : TFS_Read
* Returned Value   : Number of bytes actually read.
* Comments         : Reads given file and stores data into the given buffer.
*
*END*---------------------------------------------------------------------*/

uint_32 TFS_Read
    (
        /* [IN/OUT] file to read from */
        MQX_FILE_PTR           file_fd_ptr,

        /* [IN] number of bytes to read */
        uint_32                num_bytes,

        /* [OUT] buffer to write the data to */
        char_ptr               buffer_address,

        /* [OUT] error information */
        uint_32_ptr            error_ptr
    )
{ /* Body */
    uint_32 i;
    uchar_ptr data;
    
    *error_ptr = TFS_NO_ERROR;
    if (file_fd_ptr->DEV_DATA_PTR == NULL) 
    {
        *error_ptr = TFS_ERROR_INVALID_FILE_HANDLE;
        return 0;
    }
    if (file_fd_ptr->LOCATION >= file_fd_ptr->SIZE)
    {
        *error_ptr = TFS_EOF;
        return 0;
    }
    if (num_bytes > file_fd_ptr->SIZE - file_fd_ptr->LOCATION) 
    {
        num_bytes = file_fd_ptr->SIZE - file_fd_ptr->LOCATION;
    }
    data = ((TFS_DIR_ENTRY_PTR)file_fd_ptr->DEV_DATA_PTR)->DATA + file_fd_ptr->LOCATION;
    for (i = num_bytes; i != 0; i--) *buffer_address++ = *data++;
    file_fd_ptr->LOCATION += num_bytes;
    return num_bytes;   
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : TFS_Write
* Returned Value   : Number of bytes actually written.
* Comments         : Writes data from given buffer into the given file.
*
*END*---------------------------------------------------------------------*/

uint_32 TFS_Write
    (
        /* [IN/OUT] file to write to */
        MQX_FILE_PTR           file_fd_ptr,

        /* [IN] number of bytes to write */
        uint_32                num_bytes,

        /* [IN] buffer to read data from */
        char_ptr               buffer_address,

        /* [OUT] error information */
        uint_32_ptr            error_ptr
    )
{ /* Body */
    *error_ptr = TFS_DISK_IS_WRITE_PROTECTED;
    if (file_fd_ptr->DEV_DATA_PTR == NULL) 
    {
        *error_ptr = TFS_ERROR_INVALID_FILE_HANDLE;
    }
    return 0;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : TFS_Move_File_Pointer
* Returned Value   : New file location.
* Comments         : Performs seek within given file.
*
*END*---------------------------------------------------------------------*/

uint_32 TFS_Move_File_Pointer
    (  
        /* [IN/OUT] file to seek within */
        MQX_FILE_PTR           file_fd_ptr,

        /* [OUT] error information */
        uint_32_ptr            error_ptr
    )
{ /* Body */
    *error_ptr = TFS_NO_ERROR;
    if (file_fd_ptr->DEV_DATA_PTR == NULL) 
    {
        *error_ptr = TFS_ERROR_INVALID_FILE_HANDLE;
        return 0;
    }
    if (file_fd_ptr->LOCATION > file_fd_ptr->SIZE) 
    {
        *error_ptr = TFS_EOF;
        file_fd_ptr->LOCATION = file_fd_ptr->SIZE;
    }
    return(file_fd_ptr->LOCATION);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : TFS_Move_File_Pointer
* Returned Value   : Error information.
* Comments         : Closes given file.
*
*END*---------------------------------------------------------------------*/

int_32 TFS_Close_File
    (
        /* [IN/OUT] file to seek within */
        MQX_FILE_PTR           file_fd_ptr
    )
{ /* Body */
    file_fd_ptr->DEV_DATA_PTR = NULL;
    return TFS_NO_ERROR;
} /* Endbody */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/flashx/amd/29bddxxx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: 29bddxxx.c$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions to program any AMD29BDDXXX
*   and AM29LV800BT flash devices.
*
*END************************************************************************/

#include "mqx.h" 
#include "bsp.h"
#include "flashx.h"
#include "flashxprv.h"
#include "29bddxxx.h"
#include "29bddxxx_prv.h"

const FLASHX_DEVICE_IF_STRUCT _29bddxxx_if = {
    _29bdd160_sector_erase,
    _29bdd160_program,
    _29bddxxx_chip_erase,
    NULL,
    _29bdd160_init_device,
    NULL,
    NULL,
    NULL
};

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29bdd160_init_device
* Returned Value   : TRUE if successful
* Comments         : 
*    This function is to verify the configuration Register
* 
*END*----------------------------------------------------------------------*/

boolean _29bdd160_init_device
   (
      /* [IN] the flash information */
      IO_FLASHX_STRUCT_PTR flashx_ptr
   )
{ /* Body */
   boolean result = TRUE;

      if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
      } /* Endif */
   
   if (flashx_ptr->WIDTH == 32) {

      volatile uint_32 _PTR_  base32_ptr;
      
      base32_ptr = (volatile uint_32 _PTR_)flashx_ptr->BASE_ADDR;

      base32_ptr[0x555] = 0xAA;
      base32_ptr[0x2AA] = 0x55;
      base32_ptr[0x555] = 0xD0;  /* Register Write Command */
      base32_ptr[4] = 0x0CC7;   

      base32_ptr[0x555] = 0xAA;
      base32_ptr[0x2AA] = 0x55;
      base32_ptr[0x555] = 0xC6;

    } else if (flashx_ptr->WIDTH == 16) {

              volatile uint_16 _PTR_  base16_ptr;
      
              base16_ptr = (volatile uint_16 _PTR_)flashx_ptr->BASE_ADDR;

              base16_ptr[0x555] = 0xAA;
              base16_ptr[0x2AA] = 0x55;
              base16_ptr[0x555] = 0xD0;  /* Register Write Command */
              base16_ptr[4]     = 0x0CC7;   

              base16_ptr[0x555] = 0xAA;
              base16_ptr[0x2AA] = 0x55;
              base16_ptr[0x555] = 0xC6;
    } /* Endif */

      if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
      } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29bdd160_program
* Returned Value   : TRUE if successful
* Comments         : 
*    This function programs the flash device listed below:
* 
*END*----------------------------------------------------------------------*/

boolean _29bdd160_program
   (  
      /* [IN] the flash information */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] where to copy data from */
      char_ptr             from_ptr,
      
      /* [OUT} where to copy data to */
      char_ptr             to_ptr,

      /* [IN] the amount to program */
      _mem_size            bytes
   )
{ /* Body */
   boolean result = TRUE;   
   uint_32 count = bytes;
   uint_32 timeout;
   uint_32 tmp1;
   uint_32 tmp2;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   }/* Endif */

   if (flashx_ptr->WIDTH == 32){
      volatile uint_32 _PTR_  base32_ptr;
      volatile uint_32 _PTR_  dest32_ptr;
      uint_32_ptr             src32_ptr;

      src32_ptr  = (uint_32_ptr)from_ptr;         
      dest32_ptr = (volatile uint_32 _PTR_)to_ptr;
      base32_ptr = (volatile uint_32 _PTR_)to_ptr;

      *base32_ptr = 0xFFFFFFFF;  /* Set read mode */

      count = (count+3) & ~3;   /* Round count up, multiple of 4 */
      while (count > 0) {
         tmp1 = *src32_ptr++;
         if (tmp1 != 0xFFFFFFFF) {
            base32_ptr[0x555] = 0xAAAAAAAA; 
            base32_ptr[0x2AA] = 0x55555555;
            base32_ptr[0x555] = 0xA0A0A0A0;       /* Write command */
            dest32_ptr[0]     = tmp1;
            timeout = 100;
            while (timeout) {
               tmp2 = dest32_ptr[0];
               /* Check timeout or data bit of byte being programmed */
               if ((tmp2 & 0x80808080) != (tmp1 & 0x80808080)) {
                  /* Check for timeout error */
                  if ((tmp2 & 0x20202020) == 0x20202020) {
                     tmp2 = dest32_ptr[0];
                     if ((tmp2 & 0x80808080) != (tmp1 & 0x80808080)) {
                        result = FALSE;
                        *base32_ptr = 0xFFFFFFFF; /* Set read mode */
                        goto done;
                     } /* Endif */
                     break;
                  } /* Endif */
               } else  {
                  break;      /* done: byte programmed */
               } /* Endif */
               _io_flashx_wait_us(10);
               timeout--;
            } /* Endwhile */
            if (timeout==0) {
               result = FALSE;
               *base32_ptr = 0xFFFFFFFF; /* Set read mode */
               goto done;
            } /* Endif */
         } /* Endif */
         dest32_ptr++;
         count -= 4;
      } /* Endwhile */
            
      *base32_ptr = 0xFFFFFFFF;  /* Set read mode */

   } else if (flashx_ptr->WIDTH == 16){
      volatile uint_16 _PTR_  base16_ptr;
      volatile uint_16 _PTR_  dest16_ptr;
      uint_16_ptr             src16_ptr;

      src16_ptr  = (uint_16_ptr)from_ptr;         
      dest16_ptr = (volatile uint_16 _PTR_)to_ptr;
      base16_ptr = (volatile uint_16 _PTR_)to_ptr;

      *base16_ptr = 0xFFFF; /* Set read mode */

      count = (count+1) & ~1;   /* Round count up, multiple of 2 */
      while (count > 0) {
         tmp1 = *src16_ptr++;
         if (tmp1 != 0xFFFF) {
            base16_ptr[0x555] = 0xAAAA; 
            base16_ptr[0x2AA] = 0x5555;
            base16_ptr[0x555] = 0xA0A0;       /* Write command */
            dest16_ptr[0]      = tmp1;
            timeout = 100;
            while (timeout) {
               tmp2 = dest16_ptr[0];
               /* Check timeout or data bit of byte being programmed */
               if ((tmp2 & 0x8080) != (tmp1 & 0x8080)) {
                  /* Check for timeout error */
                  if ((tmp2 & 0x2020) == 0x2020) {
                     tmp2 = dest16_ptr[0];
                     if ((tmp2 & 0x8080) != (tmp1 & 0x8080)) {
                        result = FALSE;
                        *base16_ptr = 0xFFFF; /* Set read mode */
                        goto done;  /*** */
                     } /* Endif */
                     break;
                  } /* Endif */
               } else  {
                  break;      /* done: byte programmed */
               } /* Endif */
               _io_flashx_wait_us(10);
               timeout--;
            } /* Endwhile */
            
            if (timeout==0) {
               result = FALSE;
               *base16_ptr = 0xFFFF; /* Set read mode */
               goto done;  /*** */
            } /* Endif */
         } /* Endif */
         dest16_ptr++;
         count -= 2;
      } /* Endwhile */
      *base16_ptr = 0xFFFF; /* Set read mode */
   } /* Endif */
   
   if (flashx_ptr->WRITE_VERIFY) {
      /* Verify sector(s) is(are) written correctly */
      uint_32_ptr  src32_ptr  = (uint_32_ptr)from_ptr;
      uint_32_ptr  dest32_ptr =  (uint_32_ptr)to_ptr;
      count = bytes/4 + 1;
      while (--count) {
         if (*src32_ptr++ != *dest32_ptr++) {
            result = FALSE;
            break;
         } /* Endif */
      } /* Endwhile */
   } /* Endif */   

done:
   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   } /* Endif */
   return(result);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29bdd160_sector_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases all 29bddxxx devices.
* 
*END*----------------------------------------------------------------------*/

boolean _29bdd160_sector_erase
   (
      /* [IN] the flash information */
      IO_FLASHX_STRUCT_PTR flashx_ptr,

      /* [IN] the sector to erase */
      char_ptr             input_sect_ptr,

      /* [IN] the number of bytes to erase */
      _mem_size            bytes
   )
{ /* Body */
   boolean result = TRUE;
   uint_32 timeout;
   uint_32 tmp1;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   } /* Endif */

   if (flashx_ptr->WIDTH == 32){
      volatile uint_32 _PTR_  base32_ptr;

      base32_ptr = (volatile uint_32 _PTR_)input_sect_ptr;
      /* Erase a sector */
      base32_ptr[0x555] = 0xAAAAAAAA;
      base32_ptr[0x2AA] = 0x55555555;
      base32_ptr[0x555] = 0x80808080; /* Erase command */
      base32_ptr[0x555] = 0xAAAAAAAA;
      base32_ptr[0x2AA] = 0x55555555;
      base32_ptr[0]     = 0x30303030; /* sector to be erased */

      timeout = 9000000;
      while (timeout) {
         tmp1 = base32_ptr[0];
         if ((tmp1 & 0x80808080) == 0x80808080) {
            break;
         } /* Endif */
         if ((tmp1 & 0x20202020) == 0x20202020) {
            tmp1 = base32_ptr[0];
            if ((tmp1 & 0x80808080) != 0x80808080) {
               base32_ptr[0] = 0xFFFFFFFF; /* Set read mode */
               /* Reset FLASH */
               base32_ptr[0x555] = 0xF0F0F0F0;  /* Reset command */
               result = FALSE;
               break;
            } /* Endif */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      tmp1 = base32_ptr[0];
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */
      base32_ptr[0] = 0xFFFFFFFF; /* Set read mode */
      
   } else if (flashx_ptr->WIDTH == 16){
      volatile uint_16 _PTR_  base16_ptr;

      base16_ptr = (volatile uint_16 _PTR_)input_sect_ptr;

      /* Erase a sector */
      base16_ptr[0x555] = 0xAAAA;
      base16_ptr[0x2AA] = 0x5555;
      base16_ptr[0x555] = 0x8080; /* Erase command */
      base16_ptr[0x555] = 0xAAAA;
      base16_ptr[0x2AA] = 0x5555;
      base16_ptr[0]     = 0x3030;

      timeout = 9000000;
      while (timeout) {
         tmp1 = base16_ptr[0];
         if ((tmp1 & 0x8080) == 0x8080) {
            break;
         } /* Endif */
         if ((tmp1 & 0x2020) == 0x2020) {
            tmp1 = base16_ptr[0];
            if ( (tmp1 & 0x8080) != 0x8080) {
               base16_ptr[0] = 0xFFFF; /* Set read mode */
               /* Reset FLASH */
               base16_ptr[0x555] = 0xF0F0;  /* Reset command */
               result = FALSE;
               break;
            } /* Endif */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      tmp1 = base16_ptr[0];
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */
      base16_ptr[0] = 0xFFFF; /* Set read mode */
   } /* Endif */
   
   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   } /* Endif */

   return(result);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _29bddxxx_chip_erase
* Returned Value   : TRUE if successful
* Comments         : 
*    This function erases all 29bddxxx devices.
* 
*END*----------------------------------------------------------------------*/

boolean _29bddxxx_chip_erase
   (
      /* [IN] the flash information */
      IO_FLASHX_STRUCT_PTR flashx_ptr
   )
{ /* Body */
   boolean result = TRUE;
   uint_32 timeout;
   uint_32 tmp1;

   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, FALSE);
   } /* Endif */

   if (flashx_ptr->WIDTH == 32){
      volatile uint_32 _PTR_  base32_ptr;

      base32_ptr = (volatile uint_32 _PTR_)flashx_ptr->BASE_ADDR;
      /* Erase entire chip */
      base32_ptr[0x555] = 0xAAAAAAAA;
      base32_ptr[0x2AA] = 0x55555555;
      base32_ptr[0x555] = 0x80808080; /* Erase command */
      base32_ptr[0x555] = 0xAAAAAAAA;
      base32_ptr[0x2AA] = 0x55555555;
      base32_ptr[0x555] = 0x10101010;
      
      timeout = 9000000;
      while (timeout) {
         tmp1 = base32_ptr[0];
         if ((tmp1 & 0x80808080) == 0x80808080) {
            break;
         } /* Endif */
         if ((tmp1 & 0x20202020) == 0x20202020) {
            tmp1 = base32_ptr[0];
            if ((tmp1 & 0x80808080) != 0x80808080) {
               base32_ptr[0] = 0xFFFFFFFF; /* Set read mode */
               /* Reset FLASH */
               base32_ptr[0x555] = 0xF0F0F0F0;  /* Reset command */
               result = FALSE;
               break;
            } /* Endif */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      tmp1 = base32_ptr[0];
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */
      base32_ptr[0] = 0xFFFFFFFF; /* Set read mode */
      
   } else if (flashx_ptr->WIDTH == 16){
      volatile uint_16 _PTR_  base16_ptr;

      base16_ptr = (volatile uint_16 _PTR_)flashx_ptr->BASE_ADDR;

      /* Erase entire chip */
      base16_ptr[0x555] = 0xAAAA;
      base16_ptr[0x2AA] = 0x5555;
      base16_ptr[0x555] = 0x8080; /* Erase command */
      base16_ptr[0x555] = 0xAAAA;
      base16_ptr[0x2AA] = 0x5555;
      base16_ptr[0x555] = 0x1010;

      timeout = 9000000;
      while (timeout) {
         tmp1 = base16_ptr[0];
         if ((tmp1 & 0x8080) == 0x8080) {
            break;
         } /* Endif */
         if ((tmp1 & 0x2020) == 0x2020) {
            tmp1 = base16_ptr[0];
            if ( (tmp1 & 0x8080) != 0x8080) {
               base16_ptr[0] = 0xFFFF; /* Set read mode */
               /* Reset FLASH */
               base16_ptr[0x555] = 0xF0F0;  /* Reset command */
               result = FALSE;
               break;
            } /* Endif */
            break;
         } /* Endif */
         _io_flashx_wait_us(10);
         timeout--;
      } /* Endwhile */
      tmp1 = base16_ptr[0];
      if (timeout == 0) {
         result = FALSE;
      } /* Endif */
      base16_ptr[0] = 0xFFFF; /* Set read mode */
   } /* Endif */
   
   if (flashx_ptr->WRITE_PROTECT) {
      (*flashx_ptr->WRITE_PROTECT)(flashx_ptr, TRUE);
   } /* Endif */

   return(result);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/USB_CLASS/usb_dfu.c<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/ /*!
  *
  * @file usb_dfu.c
  *
  * @author
  *
  * @version
  *
  * @date
  *
  * @brief The file contains USB stack DFU layer implementation.
  *
  *****************************************************************************/

#include "app_cfg.h"

#include "usb_dfu.h"            /* USB DFU Class Header File */
#include "usb_devapi.h"         /* USB device Header File */
#include "USB_timer.h" /* USB RTC Header File */


extern void  Loader_init(void);
extern INT8U Flash_recv_buff(INT8U *dfu_recv_buff, INT32U dfu_data_size);

void         USB_Class_DFU_task(void);
void         DFU_set_poll_delay(INT32U timeout);
static void  USB_Class_DFU_Process_bwPoll_TimeOut(void);
static INT8U USB_Class_DFU_Getstatus(INT8U controller_ID, INT8U interface, INT8U_ptr *data, INT16U *size);
static INT8U USB_Class_DFU_Getstate(INT8U controller_ID, INT8U interface, INT8U_ptr *data, INT16U *size);
static INT8U USB_Other_Requests(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_App_Detach_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Idle_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Dnload_Sync_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Dnbusy_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Dnload_Idle_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Manifest_Sync_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Manifest_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Manifest_Wait_Reset_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Upload_Idle_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);
static INT8U DFU_Error_State(INT8U controller_ID, USB_SETUP_STRUCT *setup_packet, INT8U_ptr *data, INT16U *size);


INT8U USB_Class_DFU_receive_block(INT8U controller_ID, INT16U wBlockNum, INT8U_ptr *data, INT16U *size);
INT8U USB_Class_DFU_transmit_block(INT8U controller_ID, INT16U BlockNum, INT8U_ptr *data, INT16U *size, INT16U wLength);


static USB_CLASS_CALLBACK               g_dfu_class_callback  = NULL;      /* DFU Class Callback Function Pointer */
static USB_REQ_FUNC                     g_vendor_req_callback = NULL;       /* DFU Class Vendor Callback Function Pointer */
static USB_CLASS_SPECIFIC_HANDLER_FUNC  g_param_callback      = NULL;      /* DFU Class requests Callback Function Pointer */
static INT8U                            g_dfu_state;                       /* state of DFU device */
static INT8U                            g_dfu_status[GETSTATUS_DATA_SIZE] =
{ 0x00,              // bStatus, An indication of the status resulting from the execution of the most recent request.
  POLLTIMEOUT, 0, 0,   // bwPollTimeout (3 byte). Minimum time, in milliseconds, that the host should wait before sending a subsequent DFU_GETSTATUS request. *
  0x00,              // bState.  An indication of the state that the device is going to enter immediately following transmission of this response.
  0x00               // iString. Index of status description in string table.
};                             /* status of DFU device */
static INT16U                           wlength;                           /* length of data */
static BOOLEAN                          g_block_flashing_done = FALSE;       /* Flag to check download block process complete or not */
static BOOLEAN                          g_flash_manifest_done = FALSE;    /* Flag to check manifest phase complete or not */
static TIMER_OBJECT                     bwPoll_TimeOut;                    /* Poll Timeout */

extern INT8U  g_dfu_flash_result;
static INT8U  dfu_recv_buff[DFU_RECV_BUFFER_LENGTH];  // Накопительный буффер при приеме данных от хоста
static INT16U dfu_last_block_num;                     // Номер последнего принятого блока
static INT32U dfu_firmware_size;                      // Текущий размер загруженного или читаемого фирмваре
static INT8U  dfu_buff_ready;                         // Накопительный буффер готов к парсингу и программированию
static INT32U dfu_buff_indx;                          // Индекс текущей позиции в буфере приема DFU
static INT32U dfu_data_size;                          // Количество данных в буфере для программирования



/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_Process_bwPoll_TimeOut
  *
  * @brief  To check timeout of block download process and manifest phase
  *
  *
  * @return :  None
  *
  ******************************************************************************
  *
  *****************************************************************************/
static void USB_Class_DFU_Process_bwPoll_TimeOut()
{
  if ( g_dfu_state == USB_DFU_DNBUSY ) g_dfu_state = USB_DFU_DNLOAD_SYNC;
  if ( g_dfu_state == USB_DFU_MANIFEST )
  {
#if(MANIFESTATION)
    g_dfu_state = USB_DFU_MANIFEST_SYNC;
#else
    g_dfu_state = USB_DFU_MANIFEST_WAIT_RESET;
#endif
  }
}
/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_App_SetIdle
  *
  * @brief  This function is called to set device state is Idle
  *
  *
  * @return : status
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *****************************************************************************/

void USB_Class_DFU_App_SetIdle(void)
{
  g_dfu_state = USB_APP_IDLE;
}
/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_App_SetDetach
  *
  * @brief  This function is called to set device state is Detach
  *
  *
  * @return : status
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  ******************************************************************************/
void USB_Class_DFU_App_SetDetach(void)
{
  g_dfu_state = USB_APP_DETACH;
}
/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_App_Getstate
  *
  * @brief  This function is called by App layer to get state from DFU class
  *
  *
  * @return :  state of device
  *
  *****************************************************************************/

INT8U USB_Class_DFU_App_Getstate(void)
{
  return g_dfu_state;
}
/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_App_Setstate
  *
  * @brief  This function is called when detect USB reset signal
  *
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
void USB_Class_DFU_App_Set_Usbreset(void)
{
  switch (g_dfu_state)
  {
  case USB_APP_DETACH:
    g_dfu_state = USB_DFU_IDLE;
    break;
  default:
    if ( !g_flash_manifest_done )
    {
      g_dfu_state = USB_DFU_ERROR;
    }
    break;
  }
}
/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_App_Set_Flag_Manifest
  *
  * @brief  This function is called when app layer need set Flag to inform
  *
  * completed manifest phase
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
void USB_Class_DFU_App_Set_Flag_Manifest(void)
{
  g_flash_manifest_done = TRUE;
}
/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_App_Reset_Flag_Manifest
  *
  * @brief  This function is called when app layer need set Flag to inform
  *
  * completed manifest phase
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
void USB_Class_DFU_App_Reset_Flag_Manifest(void)
{
  g_flash_manifest_done = FALSE;
}
/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_App_Set_Flag_Manifest
  *
  * @brief  This function is called when app layer need set Flag to inform
  *
  * completed manifest phase
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
BOOLEAN USB_Class_DFU_App_Get_Flag_Manifest(void)
{
  return g_flash_manifest_done;
}

/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_Getstatus
  *
  * @brief   The funtion gets status of device and generate timeout for
  *          transition between phases.
  *
  * @param controller_ID     : Controller ID
  * @param interface         : Interface
  * @param data              : Pointer to data
  * @param size              : Pointer to size of data
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        USBERR_INVALID_REQ_TYPE : When  request for invalid
  *                                Interface is presented
  ******************************************************************************
  * Return status of device
  *****************************************************************************/
static INT8U USB_Class_DFU_Getstatus(
                                     INT8U controller_ID,               /* [IN] Controller ID */
                                     INT8U interface,                   /* [IN] Interface */
                                     INT8U_ptr *data,                   /* [OUT] Pointer to Data */
                                     INT16U *size               /* [OUT] Pointer to Size of Data */
                                     )
{
  UNUSED(controller_ID)
  /* if interface valid */
  if ( interface < USB_MAX_SUPPORTED_INTERFACES )
  {
    /* get status data*/
    *size = GETSTATUS_DATA_SIZE;
    *data = g_dfu_status;
    return USB_OK;
  }
  return USBERR_INVALID_REQ_TYPE;
}

/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_Getstate
  *
  * @brief   The funtion gets state of device
  *
  * @param controller_ID     : Controller ID
  * @param interface         : Interface
  * @param data              : Pointer to data
  * @param size              : Pointer to size of Data
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        USBERR_INVALID_REQ_TYPE : When  request for invalid
  *                                Interface is presented
  ******************************************************************************
  * Return state of device.
  *****************************************************************************/
static INT8U USB_Class_DFU_Getstate(
                                    INT8U controller_ID,               /* [IN] Controller ID */
                                    INT8U interface,                   /* [IN] Interface */
                                    INT8U_ptr *data,                   /* [OUT] Pointer to Data */
                                    INT16U *size               /* [OUT] Pointer to Size of Data */
                                    )
{
  UNUSED(controller_ID)
  /* if interface valid */
  if ( interface < USB_MAX_SUPPORTED_INTERFACES )
  {
    /* get state data*/
    *size = GETSTATE_DATA_SIZE;
    *data = &g_dfu_state;
    return USB_OK;
  }
  return USBERR_INVALID_REQ_TYPE;
}

/**************************************************************************/ /*!
  *
  * @name  USB_Other_Requests
  *
  * @brief   The funtion provides flexibilty to add class and vendor specific
  *              requests
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  ******************************************************************************
  * Handles DFU Class requests and forwards vendor specific request to the
  * application
  *****************************************************************************/
static INT8U USB_Other_Requests(
                                INT8U controller_ID,               /* [IN] Controller ID */
                                USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
                                INT8U_ptr *data,                   /* [OUT] Data to be send back */
                                INT16U *size               /* [OUT] Size to be returned*/
                                )
{
  INT8U status = USBERR_INVALID_REQ_TYPE;
  /* Check size NULL */
  if ( size == NULL )
  {
    return USBERR_GET_MEMORY_FAILED;
  }
  *size = 0;
  if ( (setup_packet->request_type & USB_REQUEST_CLASS_MASK) == USB_REQUEST_CLASS_CLASS )
  {
    g_dfu_status[BSTATE] = g_dfu_state;
    switch (g_dfu_state)
    {
      /* State1: App_Detach */
    case USB_APP_DETACH:
      status = DFU_App_Detach_State(controller_ID, setup_packet, data, size);
      break;
      /* State2: Dfu_Idle */
    case USB_DFU_IDLE:
      status = DFU_Idle_State(controller_ID, setup_packet, data, size);
      break;
      /* State3: Dfu_Dnload_Sync */
    case USB_DFU_DNLOAD_SYNC:
      status = DFU_Dnload_Sync_State(controller_ID, setup_packet, data, size);
      break;
      /* State4: Dfu_Dnbusy */
    case USB_DFU_DNBUSY:
      /*FSL: change to allow fast connections: no more*/ /*FSL: as it was from the begging*/
      //********status = DFU_Dnbusy_State(controller_ID, setup_packet, data, size);// -> Earlier change
      status = DFU_Upload_Idle_State(controller_ID, setup_packet, data, size); // -> 8/24/2012
      break;
      /* State5: Dfu_Dnload_Idle*/
    case USB_DFU_DNLOAD_IDLE:
      status = DFU_Dnload_Idle_State(controller_ID, setup_packet, data, size);
      break;
      /* State6: Dfu_Mani_Sync */
    case USB_DFU_MANIFEST_SYNC:
      status = DFU_Manifest_Sync_State(controller_ID, setup_packet, data, size);
      break;
      /* State7: Dfu_Mani */
    case USB_DFU_MANIFEST:
      status = DFU_Manifest_State(controller_ID, setup_packet, data, size);
      break;
      /* State8: Dfu_Mani_Wait_Reset */
    case USB_DFU_MANIFEST_WAIT_RESET:
      status = DFU_Manifest_Wait_Reset_State(controller_ID, setup_packet, data, size);
      break;
      /* State9: Dfu_Upload_Idle */
    case USB_DFU_UPLOAD_IDLE:
      status = DFU_Upload_Idle_State(controller_ID, setup_packet, data, size);
      break;
      /* State10: Dfu_Error */
    case USB_DFU_ERROR:
      status = DFU_Error_State(controller_ID, setup_packet, data, size);
      break;
    default:
      status = USB_OK;
      break;
    }
  }
  g_dfu_status[BSTATUS] = status;
  return status;
}
/**************************************************************************/ /*!
  *
  * @name  DFU_App_Detach_State
  *
  * @brief   The funtion processes requests at USB_APP_DETACH  state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
static INT8U DFU_App_Detach_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  INT8U status;
  INT8U interface;

  interface = (INT8U)setup_packet->index;
  switch (setup_packet->request)
  {
    /* DFU_GETSTATUS Request */
  case USB_DFU_GETSTATUS:
    status = USB_Class_DFU_Getstatus(controller_ID, interface, data, size);
    break;
    /* DFU_GETSTATE Request */
  case USB_DFU_GETSTATE:
    status = USB_Class_DFU_Getstate(controller_ID, interface, data, size);
    break;
  default:
    status = USBERR_INVALID_REQ_TYPE;
    g_dfu_state = USB_APP_IDLE;
    break;
  }
  return status;
}

/**************************************************************************/ /*!
  *
  * @name  DFU_Idle_State
  *
  * @brief   The funtion processes requests at USB_DFU_IDLE state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
static INT8U DFU_Idle_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  INT8U status; //,check_request_type;
  INT16U interface, BlockNum, wBlockNum;

  interface = setup_packet->index;
  BlockNum = setup_packet->value;
  wBlockNum = setup_packet->value;
  //check_request_type =(uint_8)setup_packet->request_type;
  *data = ((INT8U *)setup_packet) + USB_SETUP_PKT_SIZE;
  switch (setup_packet->request)
  {
    
  case USB_DFU_DNLOAD:
    
    wlength = setup_packet->length;

    if ( wlength > 0 )
    {
      (void)Remove_periodic_callback(0);

#if(BITCANDOWNLOAD)
      /* Start check download timeout */
      g_dfu_state = USB_DFU_DNLOAD_SYNC;
      g_block_flashing_done = FALSE;
      /* Call to application */
      status = USB_Class_DFU_receive_block(controller_ID, wBlockNum, data, &wlength);
      if ( USB_OK != status )
      {
        g_dfu_state = USB_DFU_ERROR;
      }
#else
      status = USBERR_INVALID_REQ_TYPE;
      ;
      g_dfu_state = USB_DFU_ERROR;
#endif
    }
    /* the last block */
    if ( wlength == 0 )
    {
      status = USBERR_INVALID_REQ_TYPE;
      ;
      g_dfu_state = USB_DFU_ERROR;
    }
    break;
    
  case USB_DFU_UPLOAD:
#if(BITCANUPLOAD)
    BlockNum = (INT8U)setup_packet->value;
    /* Call to application */
    status = USB_Class_DFU_transmit_block(controller_ID, BlockNum, data, size, setup_packet->length);
    if ( *size < setup_packet->length ) g_dfu_state = USB_DFU_IDLE;
    else g_dfu_state = USB_DFU_UPLOAD_IDLE;
#else
    status = USBERR_INVALID_REQ_TYPE;
    ;
    g_dfu_state = USB_DFU_ERROR;
#endif
    break;
    /* DFU_ABORT request */
  case USB_DFU_ABORT:
    status = USB_OK;
    break;
    /* DFU_GETSTATUS request */
  case USB_DFU_GETSTATUS:
    status = USB_Class_DFU_Getstatus(controller_ID, (INT8U)interface, data, size);
    break;
    /* DFU_GETSTATE request */
  case USB_DFU_GETSTATE:
    status = USB_Class_DFU_Getstate(controller_ID, (INT8U)interface, data, size);
    break;
  default:
    status = USBERR_INVALID_REQ_TYPE;
    g_dfu_state = USB_DFU_ERROR;
    break;
  }
  return status;
}

/**************************************************************************/ /*!
  *
  * @name  DFU_Dnload_Sync_State
  *
  * @brief   The funtion processes requests at USB_DFU_DNLOAD_SYNC  state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
static INT8U DFU_Dnload_Sync_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  INT8U status;
  INT8U interface;

  interface = (INT8U)setup_packet->index;
  switch (setup_packet->request)
  {
    /* DFU_GETSTATUS request */
  case USB_DFU_GETSTATUS:
    if ( g_block_flashing_done ) g_dfu_state = USB_DFU_DNLOAD_IDLE;
    else
    {
      /* Set time out for writing to flash*/
      (void)Remove_periodic_callback(0);
      g_block_flashing_done = FALSE;
      if ( g_dfu_status[BWPOLLTIMEOUT + 2] > 0 ) bwPoll_TimeOut.msCount = 0xFFFF; /* Max Poll Time Out */
      else bwPoll_TimeOut.msCount = (INT16U)(g_dfu_status[BWPOLLTIMEOUT] + (g_dfu_status[BWPOLLTIMEOUT + 1] << 8));
      bwPoll_TimeOut.pfnTimerCallback = USB_Class_DFU_Process_bwPoll_TimeOut;
      (void)Add_periodic_callback(&bwPoll_TimeOut);

      g_dfu_state = USB_DFU_DNBUSY;
    }
    g_dfu_status[BSTATE] = g_dfu_state;
    status = USB_Class_DFU_Getstatus(controller_ID, interface, data, size);
    break;
    /* DFU_GETSTATE request */
  case USB_DFU_GETSTATE:
    status = USB_Class_DFU_Getstate(controller_ID, interface, data, size);
    break;
  default:
    status = USBERR_INVALID_REQ_TYPE;
    g_dfu_state = USB_DFU_ERROR;
    break;
  }
  return status;
}
/**************************************************************************/ /*!
 *
 * @name  DFU_Dnbusy_State
 *
 * @brief   The funtion processes requests at USB_DFU_DNBUSY  state
 *
 * @param controller_ID     : Controller ID
 * @param setup_packet      : Setup packet received
 * @param data              : Data to be send back
 * @param size              : Size to be returned
 *
 * @return status:
 *                        USB_OK        : When Successfull
 *                        Others        : When Error
 *
 *****************************************************************************/
static INT8U DFU_Dnbusy_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  UNUSED(controller_ID)
  UNUSED(setup_packet)
  UNUSED(data)
  UNUSED(size)
  g_dfu_state = USB_DFU_ERROR;
  return USBERR_INVALID_REQ_TYPE;
}
/**************************************************************************/ /*!
  *
  * @name  DFU_Dnload_Idle_State
  *
  * @brief   The funtion processes requests at USB_DFU_DNLOAD_IDLE   state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
static INT8U DFU_Dnload_Idle_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  INT8U status;
  INT8U interface; //, check_request_type;
  INT16U /*BlockNum,*/ wBlockNum;

  interface = (INT8U)setup_packet->index;
  //BlockNum = setup_packet->value;
  wBlockNum = setup_packet->value;
  //check_request_type =(uint_8)setup_packet->request_type;
  *data = ((INT8U *)setup_packet) + USB_SETUP_PKT_SIZE;

  switch (setup_packet->request)
  {
    /* DFU_DNLOAD request*/
  case USB_DFU_DNLOAD:

#if defined(_MC9S08JS16_H)
    wlength = (INT8U)setup_packet->length;
#else
    wlength = setup_packet->length;
#endif

    /* check wlength */
    if ( wlength > 0 )
    {
      g_dfu_state = USB_DFU_DNLOAD_SYNC;
      g_block_flashing_done = FALSE;
    }
    if ( wlength == 0 )
    {
      g_dfu_state = USB_DFU_MANIFEST_SYNC;
      status = USB_OK;
    }
    /* Call to application */
    status = USB_Class_DFU_receive_block(controller_ID, wBlockNum, data, &wlength);
    if ( USB_OK != status )
    {
      g_dfu_state = USB_DFU_ERROR;
    }
    break;
    /* DFU_ABORT request */
  case USB_DFU_ABORT:
    status = USB_OK;
    g_dfu_state = USB_DFU_IDLE;
    break;
    /* DFU_GETSTATUS request */
  case USB_DFU_GETSTATUS:
    status = USB_Class_DFU_Getstatus(controller_ID, interface, data, size);
    break;
    /* DFU_GETSTATE request */
  case USB_DFU_GETSTATE:
    status = USB_Class_DFU_Getstate(controller_ID, interface, data, size);
    break;
  default:
    status = USBERR_INVALID_REQ_TYPE;
    g_dfu_state = USB_DFU_ERROR;
    break;
  }
  return status;
}

/**************************************************************************/ /*!
  *
  * @name  DFU_Manifest_Sync_State
  *
  * @brief   The funtion processes requests at USB_DFU_MANIFEST_SYNC   state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  ******************************************************************************/
static INT8U DFU_Manifest_Sync_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  INT8U status;
  INT8U interface;

  interface = (INT8U)setup_packet->index;
  switch (setup_packet->request)
  {
    /* DFU_GETSTATUS request */
  case USB_DFU_GETSTATUS:
    if ( g_flash_manifest_done )
    {
#if(MANIFESTATION)
      g_dfu_state = USB_DFU_IDLE;
      g_dfu_status[BSTATE] = g_dfu_state;
      status = USB_Class_DFU_Getstatus(controller_ID, interface, data, size);
#endif
    }
    else
    {   /* poll time out for manifest process */
      (void)Remove_periodic_callback(0);
      if ( g_dfu_status[BWPOLLTIMEOUT + 2] > 0 ) bwPoll_TimeOut.msCount = 0xFFFF; /* Max Poll Time Out */
      else bwPoll_TimeOut.msCount = (INT16U)(g_dfu_status[BWPOLLTIMEOUT] + (g_dfu_status[BWPOLLTIMEOUT + 1] << 8));
      bwPoll_TimeOut.pfnTimerCallback = USB_Class_DFU_Process_bwPoll_TimeOut;
      (void)Add_periodic_callback(&bwPoll_TimeOut);
      g_dfu_state = USB_DFU_MANIFEST;
      g_dfu_status[BSTATE] = g_dfu_state;
      status = USB_Class_DFU_Getstatus(controller_ID, interface, data, size);

    }
    break;
    /* DFU_GETSTATE request */
  case USB_DFU_GETSTATE:
    status = USB_Class_DFU_Getstate(controller_ID, interface, data, size);
    break;
  default:
    status = USBERR_INVALID_REQ_TYPE;
    g_dfu_state = USB_DFU_ERROR;
    break;
  }
  return status;
}
/**************************************************************************/ /*!
  *
  * @name  DFU_Manifest_State
  *
  * @brief   The funtion processes requests at DFU_MANIFEST  state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
static INT8U DFU_Manifest_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  UNUSED(controller_ID);
  UNUSED(setup_packet);
  UNUSED(data);
  UNUSED(size);
  g_dfu_state = USB_DFU_ERROR;
  return USBERR_INVALID_REQ_TYPE;
}
/**************************************************************************/ /*!
  *
  * @name  DFU_Manifest_Wait_Reset_State
  *
  * @brief   The funtion processes requests at USB_DFU_MANIFEST_WAIT_RESET  state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
static INT8U DFU_Manifest_Wait_Reset_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  UNUSED(controller_ID);
  UNUSED(setup_packet);
  UNUSED(data);
  UNUSED(size);

  return USBERR_INVALID_REQ_TYPE;
  ;
}
/**************************************************************************/ /*!
  *
  * @name  DFU_Upload_Idle_State
  *
  * @brief   The funtion processes requests at USB_DFU_UPLOAD_IDLE    state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  ******************************************************************************/
static INT8U DFU_Upload_Idle_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  INT8U status;
  INT8U interface; //, check_request_type;
  INT16U BlockNum; //,wBlockNum;

  interface = (INT8U)setup_packet->index;
  BlockNum = setup_packet->value;
  //wBlockNum = setup_packet->value;
  //check_request_type =(uint_8)setup_packet->request_type;
  *data = ((INT8U *)setup_packet) + USB_SETUP_PKT_SIZE;

  switch (setup_packet->request)
  {
    /* DFU_UPLOAD Request */
  case USB_DFU_UPLOAD:
    status = USB_Class_DFU_transmit_block(controller_ID, BlockNum, data, size, setup_packet->length);
    if ( *size < setup_packet->length ) g_dfu_state = USB_DFU_IDLE;
    break;
    /* DFU_ABORT Request */
  case USB_DFU_ABORT:
    status = USB_OK;
    g_dfu_state = USB_DFU_IDLE;
    break;
    /* DFU_GETSTATUS Request */
  case USB_DFU_GETSTATUS:
    status = USB_Class_DFU_Getstatus(controller_ID, interface, data, size);
    break;
    /* DFU_GETSTATE Request */
  case USB_DFU_GETSTATE:
    status = USB_Class_DFU_Getstate(controller_ID, interface, data, size);
    break;
  default:
    status = USBERR_INVALID_REQ_TYPE;
    g_dfu_state = USB_DFU_ERROR;
    break;
  }
  return status;
}

/**************************************************************************/ /*!
  *
  * @name  DFU_Error_State
  *
  * @brief   The funtion processes requests at USB_DFU_ERROR    state
  *
  * @param controller_ID     : Controller ID
  * @param setup_packet      : Setup packet received
  * @param data              : Data to be send back
  * @param size              : Size to be returned
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  *****************************************************************************/
static INT8U DFU_Error_State
(
 INT8U controller_ID,               /* [IN] Controller ID */
 USB_SETUP_STRUCT *setup_packet,    /* [IN] Setup packet received */
 INT8U_ptr *data,                   /* [OUT] Data to be send back */
 INT16U *size               /* [OUT] Size to be returned*/
 )
{
  INT8U status;
  INT8U interface;

  interface = (INT8U)setup_packet->index;
  switch (setup_packet->request)
  {
    /* DFU_GETSTATUS Request */
  case USB_DFU_GETSTATUS:
    status = USB_Class_DFU_Getstatus(controller_ID, interface, data, size);
    break;
    /* DFU_GETSTATE Request */
  case USB_DFU_GETSTATE:
    status = USB_Class_DFU_Getstate(controller_ID, interface, data, size);
    break;
    /* DFU_CLRSTATUS Request */
  case USB_DFU_CLRSTATUS:
    status = USB_OK;
    g_dfu_state = USB_DFU_IDLE;
    break;
  default:
    status = USBERR_INVALID_REQ_TYPE;
    break;
  }

  return status;
}

/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_Event
  *
  * @brief The funtion initializes DFU endpoint
  *
  * @param controller_ID     : Controller ID
  * @param event             : Event Type
  * @param val               : Pointer to configuration Value
  *
  * @return None
  *
  ******************************************************************************
  * The funtion initializes the DFU endpoints when Enumeration complete event is
  * received
  *****************************************************************************/
static void USB_Class_DFU_Event
(
 INT8U controller_ID,   /* [IN] Controller ID */
 INT8U event,           /* [IN] Event Type */
 void *val               /* [IN] Pointer to configuration Value */
 )
{
  switch (event)
  {

  case USB_APP_BUS_RESET:
    if ( g_dfu_class_callback != NULL )
    {
      /* notify the application of the event */
      g_dfu_class_callback(controller_ID, event, val);
    }
    break;

  case BUS_POWERED:
    g_dfu_state = USB_APP_DETACH;
    break;
  }
}

/*****************************************************************************
 * Global Functions
 *****************************************************************************

 *****************************************************************************
 *
 * @name  USB_Class_DFU_Init
 *
 * @brief   The funtion initializes the Device and Controller layer
 *
 * @param   controller_ID               : Controller ID
 * @param   dfu_class_callback          : DFU Class Callback
 * @param   vendor_req_callback         : Vendor Request Callback
 * @param   param_callback              : Class requests Callback
 *
 * @return status:
 *                        USB_OK        : When Successfull
 *                        Others        : When Error
 *
 ******************************************************************************
 *This function initializes the DFU Class layer and layers it is dependent on
 *****************************************************************************/
INT8U USB_Class_DFU_Init
(
 INT8U    controller_ID,                /* [IN] Controller ID */
 USB_CLASS_CALLBACK dfu_class_callback,  /* [IN] DFU Class Callback */
 USB_REQ_FUNC       vendor_req_callback, /* [IN] Vendor Request Callback */
 USB_CLASS_SPECIFIC_HANDLER_FUNC param_callback
 /* [ IN] DFU Class requests Callback */
 )
{
  USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID);

  /* Initialize the device layer*/
  INT8U status = USB_Device_Init(controller_ID, (INT8U)(ep_desc_data->count + 1));
  if ( status == USB_OK )
  {
    /* Initialize the generic class functions */
    status = USB_Class_Init(controller_ID, USB_Class_DFU_Event, USB_Other_Requests);

    if ( status == USB_OK )
    {
      /* save the DFU class callback pointer */
      g_dfu_class_callback = dfu_class_callback;

      /* save the vendor request callback pointer */
      g_vendor_req_callback = vendor_req_callback;

      /* Save the callback to ask application for class specific params*/
      g_param_callback = param_callback;
    }
  }
  return status;
}

/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_DeInit
  *
  * @brief   The funtion de-initializes the Device and Controller layer
  *
  * @param   controller_ID               : Controller ID
  *
  * @return status:
  *                        USB_OK        : When Successfull
  *                        Others        : When Error
  *
  ******************************************************************************
  *This function de-initializes the DFU Class layer
  *****************************************************************************/
INT8U USB_Class_DFU_DeInit
(
 INT8U controller_ID              /* [IN] Controller ID */
 )
{
  INT8U status;

  /* free the HID class callback pointer */
  g_dfu_class_callback = NULL;

  /* free the vendor request callback pointer */
  g_vendor_req_callback = NULL;

  /* free the callback to ask application for class specific params*/
  g_param_callback = NULL;

  /* Call common class deinit function */
  status = USB_Class_DeInit(controller_ID);

  if ( status == USB_OK )
    /* Call device deinit function */
    status = USB_Device_DeInit();

  return status;
}

/**************************************************************************/ /*!
  *
  * @name  USB_Class_DFU_Set_bwPoll_TimeOut
  *
  * @brief  To set timeout of block download process and manifest phase
  *
  *
  * @return :  None
  *
  ******************************************************************************
  *
  *****************************************************************************/
void DFU_set_poll_delay(INT32U app_timeout)
{
  g_dfu_status[BWPOLLTIMEOUT] = (INT8U)((app_timeout) & (0xFF));
  g_dfu_status[BWPOLLTIMEOUT + 1] = (INT8U)((app_timeout >> 8) & (0xFF));
  g_dfu_status[BWPOLLTIMEOUT + 2] = (INT8U)((app_timeout >> 16) & (0xFF));
}

//-------------------------------------------------------------------------------------------------------
//  Функция передачи блока данных от хоста
//
//  controller_ID     : Controller ID
//  bl_num            : порадковый номер принимаемого блока от начала чтения фирмваре
//  data              : Pointer to data
//  psize             : Реально отправленное количество данных
//
//  status:
//                  USB_OK : When Successfull
//                  Other  : When Error
//
//-------------------------------------------------------------------------------------------------------
INT8U USB_Class_DFU_receive_block(INT8U controller_ID, INT16U bl_num, INT8U_ptr *data, INT16U  *psize)
{

  INT32U i = 0;
  INT32U timeout = 0;
  UNUSED(controller_ID)

  if ( *psize != 0 )
  {
    if ( (bl_num * DFU_MAX_BLOCK_SIZE) > FIRMWARE_SIZE )
    {
      return USBERR_INVALID_REQ_TYPE;
    }
    dfu_last_block_num = bl_num;

    if ( bl_num == 0 )
    {
      // Первый блок
      timeout = ((MAX_FLASH1_ADDRESS - (INT32U)IMAGE_START_ADDR) / ERASE_SECTOR_SIZE) * 10;
      DFU_set_poll_delay(timeout); 
      (void)USB_Class_DFU_App_Reset_Flag_Manifest();
      dfu_firmware_size = 0;
      dfu_buff_indx     = 0;
      Loader_init();
    }
    else
    {
      // Последующие блоки
      DFU_set_poll_delay(1); 
    }

    for (i = 0; i < *psize; i++)
    {
      if ( dfu_buff_indx < DFU_RECV_BUFFER_LENGTH )
      {
        dfu_recv_buff[dfu_buff_indx] = *(*data + i);
        dfu_buff_indx++;
      }
    }
  }

  if ( (dfu_buff_indx == DFU_RECV_BUFFER_LENGTH) || (*psize == 0) )
  {
    
    timeout = (INT32U)(dfu_buff_indx >> 4);
    DFU_set_poll_delay(timeout); // Устанавливаем время задержки отправки пакетов необходимое для программирования уже принятых  
    dfu_buff_ready = 1;  // Сообщаем основной задаче о готовности буфера для программирования

    dfu_data_size = dfu_buff_indx;
  }
  else
  {
    /* PwPollTimeOut for manifestation phase */
    DFU_set_poll_delay(15); /* time out for accumulate blocks */
  }
  dfu_firmware_size += *psize;
  return USB_OK;
}


//-------------------------------------------------------------------------------------------------------
//  Функция передачи блока данных хосту
//
//  controller_ID     : Controller ID
//  bl_num            : порадковый номер запраашиваемого блока от начала чтения фирмваре
//  data              : Pointer to data
//  psize             : Реально отправленное количество данных
//  len               : Запрашиваемое количество данных
//
//  status:
//                  USB_OK : When Successfull
//                  Other  : When Error
//
//-------------------------------------------------------------------------------------------------------
INT8U USB_Class_DFU_transmit_block(INT8U controller_ID, INT16U bl_num, INT8U_ptr *data, INT16U *psize, INT16U len)
{
  static INT32U addr;
  static INT8U  tx_buff[DFU_MAX_BLOCK_SIZE];          // Промежуточный буффер при отправке данных хосту

  INT8U i = 0;
  UNUSED(controller_ID)

  if ( bl_num == 0 )
  {
    addr = 0;
    dfu_firmware_size = FIRMWARE_SIZE;
  }

  if ( (dfu_firmware_size - addr) >= len )
  {
    *psize = len;
  }
  else
  {
    *psize = (INT16U)(dfu_firmware_size - addr);
  }
  // Копируем данные из Flash
  for (i = 0; i < *psize; i++)
  {
    tx_buff[i] = *(INT8U *)((INT8U *)IMAGE_START_ADDR + addr + i);
  }
  addr = addr + len;
  *data = tx_buff;
  return USB_OK;
}

//-------------------------------------------------------------------------------------------------------
//  Выполнение операций иницируемых классом DFU.
//-------------------------------------------------------------------------------------------------------
void USB_Class_DFU_task(void)
{
  if ( g_dfu_state == USB_DFU_DNBUSY )
  {
    if ( g_block_flashing_done == FALSE )
    {
      if ( dfu_buff_ready == 1 )
      {
        g_dfu_flash_result = Flash_recv_buff(dfu_recv_buff, dfu_data_size);
        dfu_buff_ready = 0;
      }
      g_block_flashing_done = TRUE;
    }
  }
  if  ( g_dfu_state == USB_DFU_MANIFEST )
  {
    //  Программирование заканчивается фазой манифеста в течении которой программируется последний блок и
    //  дополнительная информация если необходимо
    if ( g_flash_manifest_done  == FALSE )
    {
      if ( dfu_buff_ready == 1 )
      {
        (void)Flash_recv_buff(dfu_recv_buff, dfu_data_size);
        dfu_buff_ready = 0;
      }
      LCD_show_programming_end(SUCCESS);   

      // Записываем манифест фирмваре(т.е. нечто описывающее само фирмваре в памяти микроконтроллера, например размер и контрольную сумму)

      //__disable_interrupt();
      //(void)Erase_sectors((INT32U *)(FIRMWARE_SIZE_ADD), 4);
      //(void)Flash_ByteProgram((INT32U *)(FIRMWARE_SIZE_ADD), (INT32U_ptr)(&SizeOfFirmware), 4);
      //__enable_interrupt();
      //
      g_flash_manifest_done  = TRUE;
    }
  }
}




<|start_filename|>Firmware/Inverter_firmware/Main/CAN_control.c<|end_filename|>
#include "App.h"

LWEVENT_STRUCT can_event;



const T_can_rx_config rx_mboxes[RX_MBOX_CNT] =
{
  { CAN_RX_MB1, INVERT_REQ, 0xFFF00000 },
  { CAN_RX_MB2, INVERT_REQ, 0xFFF00000 },
  { CAN_RX_MB3, INVERT_REQ, 0xFFF00000 },
  { CAN_RX_MB4, INVERT_REQ, 0xFFF00000 },
  { CAN_RX_MB5, INVERT_REQ, 0xFFF00000 },
  { CAN_RX_MB6, INVERT_REQ, 0xFFF00000 },
  { CAN_RX_MB7, INVERT_REQ, 0xFFF00000 },
  { CAN_RX_MB8, INVERT_REQ, 0xFFF00000 },
};

INT32U       rx_log_head;
INT32U       rx_log_tail;
T_can_rx     rx_log[CAN_RX_LOG_SZ];
LWSEM_STRUCT can_log_sem;


/*-------------------------------------------------------------------------------------------------------------
  Обслуживание прерываний CAN шины при отправке и получении данных
-------------------------------------------------------------------------------------------------------------*/
void CAN_isr(pointer ptr)
{
  volatile CAN_MemMapPtr   CAN;
  INT32U                   reg;

  CAN = (CAN_MemMapPtr)ptr;

  reg = CAN->IFLAG1; // Получить флаги прерываний (всего в работе 16-ть младших флагов).
                     // Если не разрешен FIFO то каждый флаг отмечает прерывание от соответствующего буфера.
                     // Снимаються флаги записью 1
                     // Каждый флаг может отмечать, как прерывание по приему так и по передаче.
  if ( reg )
  {
    _lwevent_set(&can_event, reg); // Создать для каждого флага событие
    CAN->IFLAG1 = reg;             // Сбрасываем флаги, но только те о которых мы сообщили
  }
}
/*-------------------------------------------------------------------------------------------------------------
  Обслуживание прерываний CAN шины в результате ошибок м других событий
-------------------------------------------------------------------------------------------------------------*/
void CAN_err_isr(pointer ptr)
{
  volatile CAN_MemMapPtr   CAN;
  INT32U                   reg;

  CAN = (CAN_MemMapPtr)ptr;

  // Получить флаги ошибок и сбросить их
  reg = CAN->ESR1 & (
                     BIT(17)   // TWRNINT. 1 The Tx error counter transitioned from less than 96 to greater than or equal to 96.
                     + BIT(16) // RWRNINT. 1 The Rx error counter transitioned from less than 96 to greater than or equal to 96.
                     + BIT(2)  // BOFFINT. ‘Bus Off’ Interrupt
                     + BIT(1)  // ERRINT . Error Interrupt
                     + BIT(0)  // WAKINT . Wake-Up Interrupt
                     );
  if ( reg  )
  {
    CAN->ESR1 = reg; // Сбрасываем флаги
  }
}

/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
int Solve_can_timings(INT32U clk, INT32U bitrate, T_can_ctrl *ctrl)
{
  INT32U TQ_x_Prescaler = clk / bitrate;
  INT32U TQ;
  INT32U lowest_diff;
  INT32U diff;
  INT32U best_TQ;
  INT32U actual_freq;


  ctrl->pseg1    = 0;
  ctrl->pseg2    = 0;
  ctrl->propseg  = 0;
  ctrl->rjw      = 0;
  ctrl->presdiv  = 0;


  // If BSP_CANPE_CLOCK is defined, then we will calculate the CAN bit timing parameters
  // using the method outlined in AN1798, section 4.1. A maximum time for PROP_SEG will be used,
  // the remaining TQ will be split equally between PSEG1 and PSEG2, provided PSEG2 >=2. RJW is
  // set to the minimum of 4 or PSEG1.


  if ( TQ_x_Prescaler < (CAN_MIN_TQ - 1) )
  {
    // We will be off by more than 12.5%
    return MQX_ERROR;
  }

  // First, find the best TQ and pre-scaler to use for the desired frequency. If any exact matches
  // is found, we use the match that gives us the lowest pre-scaler and highest TQ, otherwise we pick
  // the TQ and prescaler that generates the closest frequency to the desired frequency.

  lowest_diff = bitrate;
  best_TQ = 0;
  for (TQ = CAN_MAX_TQ; TQ >= CAN_MIN_TQ; TQ--)
  {
    ctrl->presdiv = TQ_x_Prescaler / TQ;
    if ( ctrl->presdiv <= 256 )
    {
      if ( TQ_x_Prescaler == TQ * ctrl->presdiv )
      {
        best_TQ = TQ;
        break;
      }
      actual_freq = (clk / ctrl->presdiv) / TQ;

      if ( actual_freq > bitrate )
      {
        diff = actual_freq - bitrate;
      }
      else
      {
        diff = bitrate - actual_freq;
      }

      if ( diff < lowest_diff )
      {
        lowest_diff = diff;
        best_TQ = TQ;
      }
    }
  }
  if ( (best_TQ >= CAN_MIN_TQ) && (ctrl->presdiv <= 256) )
  {
    ctrl->pseg2 = (best_TQ - CAN_MAX_PROPSEG) / 2;
    if ( ctrl->pseg2 < CAN_MIN_PSEG2 ) ctrl->pseg2 = CAN_MIN_PSEG2;

    if ( best_TQ == CAN_MIN_TQ )
    {
      ctrl->pseg1 = 1;
    }
    else
    {
      ctrl->pseg1 = ctrl->pseg2;
    }

    ctrl->propseg = best_TQ - ctrl->pseg1 - ctrl->pseg2 - 1;

    if ( ctrl->pseg1 < CAN_MAX_RJW  )
    {
      ctrl->rjw = ctrl->pseg1;
    }
    else
    {
      ctrl->rjw = CAN_MAX_RJW;
    }

    ctrl->propseg -= 1;
    ctrl->rjw     -= 1;
    ctrl->pseg1   -= 1;
    ctrl->pseg2   -= 1;
    ctrl->presdiv -= 1;
  }
  else
  {
    return MQX_ERROR;
  }

  return MQX_OK;

}

/*-------------------------------------------------------------------------------------------------------------
  Обслуживание прерываний CAN шины
 
  ptr - указатель на область регистров контроллера CAN:  CAN0_BASE_PTR или CAN1_BASE_PTR  
-------------------------------------------------------------------------------------------------------------*/
int CAN_init(CAN_MemMapPtr ptr, INT32U bitrate)
{
  volatile CAN_MemMapPtr   CAN = ptr;
  SIM_MemMapPtr            SIM = SIM_BASE_PTR;
  INT32U                   clk = BSP_SYSTEM_CLOCK / 2;
  T_can_ctrl               ctrl;
  INT32U                   i;


  _lwevent_create(&can_event, 0);
  _lwsem_create(&can_log_sem, 1);

  if ( ptr == CAN0_BASE_PTR )
  {
    SIM->SCGC6 |= BIT(4);  // Разрешаем тактирование CAN0
    CAN->CTRL1 |= BIT(13); // Тактирование от источника тактирования периферии

    // Инициализация всех прерываний
    _int_install_isr(INT_CAN0_ORed_Message_buffer, CAN_isr, (void *)ptr);
    _bsp_int_init(INT_CAN0_ORed_Message_buffer, CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN0_Bus_Off,    CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN0_Bus_Off,       CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN0_Error,      CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN0_Error,         CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN0_Tx_Warning, CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN0_Tx_Warning,    CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN0_Rx_Warning, CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN0_Rx_Warning,    CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN0_Wake_Up,    CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN0_Wake_Up,       CAN_ISR_PRIO, 0, TRUE);
  }
  else if ( ptr == CAN1_BASE_PTR )
  {
    SIM->SCGC3 |= BIT(4);  // Разрешаем тактирование CAN1
    CAN->CTRL1 |= BIT(13); // Тактирование от источника тактирования периферии

    // Инициализация всех прерываний
    _int_install_isr(INT_CAN1_ORed_Message_buffer, CAN_isr, (void *)ptr);
    _bsp_int_init(INT_CAN1_ORed_Message_buffer, CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN1_Bus_Off,    CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN1_Bus_Off,       CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN1_Error,      CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN1_Error,         CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN1_Tx_Warning, CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN1_Tx_Warning,    CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN1_Rx_Warning, CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN1_Rx_Warning,    CAN_ISR_PRIO, 0, TRUE);
    _int_install_isr(INT_CAN1_Wake_Up,    CAN_err_isr,  (void *)ptr);
    _bsp_int_init(INT_CAN1_Wake_Up,       CAN_ISR_PRIO, 0, TRUE);
  }
  else    return MQX_ERROR;

  // Выполняем программный сброс и переходим во Freeze mode
  if ( CAN->MCR & BIT(20) ) // Проверим выключен ли модуль, и сбросим этот режим если надо
  {
    CAN->MCR &= (~BIT(31));       // Включаем модуль
    while (CAN->MCR & BIT(20))    // Ждем пока флаг не сбросится
    {}
  }

  CAN->MCR = BIT(25);             // Выполняем SOFTRESET
  while (CAN->MCR & BIT(25))      // Ожидаем пока SOFTRESET закончится
  {}

  CAN->MCR |= 0
              + BIT(30) // FRZ    . Freeze Enable. 1 Enabled to enter Freeze Mode
              + BIT(28) // HALT   . Halt FlexCAN. 1 Enters Freeze Mode if the FRZ bit is asserted.
  ;
  while ((CAN->MCR & BIT(24)) == 0)   // Ожидаем установки FRZACK
  {}

  Solve_can_timings(clk, bitrate, &ctrl);

  CAN->CTRL1 = 0
               + LSHIFT(ctrl.presdiv, 24) // PRESDIV. Prescaler Division Factor
               + LSHIFT(ctrl.rjw,     22) // RJW    . Resync Jump Width
               + LSHIFT(ctrl.pseg1,   19) // PSEG1  . Phase Segment 1
               + LSHIFT(ctrl.pseg2,   16) // PSEG2  . Phase Segment 2
               + LSHIFT(1,            15) // BOFFMSK. Bus Off Mask. 1 Bus Off interrupt enabled
               + LSHIFT(1,            14) // ERRMSK . Error Mask.   1 Error interrupt enabled
               + LSHIFT(1,            13) // CLKSRC . CAN Engine Clock Source. 1 The CAN engine clock source is the peripheral clock
               + LSHIFT(0,            12) // LPB    . Loop Back Mode
               + LSHIFT(1,            11) // TWRNMSK. Tx Warning Interrupt Mask. 1 Tx Warning Interrupt enabled
               + LSHIFT(1,            10) // RWRNMSK. Rx Warning Interrupt Mask. 1 Rx Warning Interrupt enabled
               + LSHIFT(0,             7) // SMP    . CAN Bit Sampling. 0 Just one sample is used to determine the bit value
               + LSHIFT(0,             6) // BOFFREC. Bus Off Recovery. 1 Automatic recovering from Bus Off state disabled
               + LSHIFT(0,             5) // TSYN   . Timer Sync. 1 Timer Sync feature enabled
               + LSHIFT(0,             4) // LBUF   . Lowest Buffer Transmitted First. 1 Lowest number buffer is transmitted first.
               + LSHIFT(0,             3) // LOM    . Listen-Only Mode. 1 FlexCAN module operates in Listen-Only Mode.
               + LSHIFT(ctrl.propseg,  0) // PROPSEG. Propagation Segment.
  ;

  CAN->CTRL2 = 0
               + LSHIFT(1,    28) // WRMFRZ. Write-Access to Memory in Freeze mode. 1 Enable unrestricted write access to FlexCAN memory.
               + LSHIFT(0,    24) // RFFN  . Number of Rx FIFO Filters
               + LSHIFT(0x22, 19) // TASD  . Tx Arbitration Start Delay.
               + LSHIFT(0,    18) // MRP   . Mailboxes Reception Priority. 0 Matching starts from Rx FIFO and continues on Mailboxes.
               + LSHIFT(0,    17) // RRS   . Remote Request Storing. 0 Remote Response Frame is generated.
               + LSHIFT(0,    16) // EACEN . Entire Frame Arbitration Field Comparison Enable for Rx Mailboxes.0 Rx Mailbox filter’s IDE bit is always compared and RTR is never compared despite mask bits.
  ;

  for (i = 0; i < 16; i++)
  {
    CAN->RXIMR[i] = 0; // Сбросим все маски
    CAN->MB[i].CS = 0;    // Все буфферы сообщений не активны
    CAN->MB[i].ID = 0;    //
    CAN->MB[i].WORD0 = 0; //
    CAN->MB[i].WORD1 = 0; //
  }
  //CAN->RXIMR[CAN_RX_MB1] = 0xFF000000;

  // Выходим из режима Freeze
  CAN->MCR = 0
             + LSHIFT(0,  31) // MDIS   . Module Disable. 1 Disable the FlexCAN module.
             + LSHIFT(0,  30) // FRZ    . Freeze Enable. 1 Enabled to enter Freeze Mode
             + LSHIFT(0,  29) // RFEN   . Rx FIFO Enable. 1 Rx FIFO enabled
             + LSHIFT(0,  28) // HALT   . Halt FlexCAN. 1 Enters Freeze Mode if the FRZ bit is asserted.
             + LSHIFT(0,  26) // WAKMSK . Wake Up Interrupt Mask. 1 Wake Up Interrupt is enabled.
             + LSHIFT(0,  25) // SOFTRST. Soft Reset. 1 Resets the registers affected by soft reset.
             + LSHIFT(0,  23) // SUPV   . Supervisor Mode. 1 FlexCAN is in Supervisor Mode.
             + LSHIFT(0,  22) // SLFWAK . Self Wake Up. 1 FlexCAN Self Wake Up feature is enabled.
             + LSHIFT(1,  21) // WRNEN  . Warning Interrupt Enable. 1 TWRNINT and RWRNINT bits are set when the respective error counter transitions from less than 96 to greater than or equal to 96.
             + LSHIFT(1,  17) // SRXDIS . Self Reception Disable. 1 Self reception disabled
             + LSHIFT(1,  16) // IRMQ   . Individual Rx Masking and Queue Enable. 1 Individual Rx masking and queue feature are enabled.
             + LSHIFT(0,  13) // LPRIOEN. Local Priority Enable. 1 Local Priority enabled
             + LSHIFT(0,  12) // AEN    . Abort Enable. 0 Abort disabled.  !!!Не выставлять 1, поскольку процедуры инициализации MB расчитаны на режим 0
             + LSHIFT(0,   8) // IDAM   . ID Acceptance Mode. 00 Format A: One full ID (standard and extended) per ID Filter Table element.
             + LSHIFT(16,  0) // MAXMB  . Number of the Last Message Buffer.
  ;

  return MQX_OK;
}



/*-------------------------------------------------------------------------------------------------------------
  Установка буффера на прием и инициация приема
  n    - номер буфера
  id   - идентификатор CAN пакета
  mask - фильтр-маска принимаемого идентификатора
  ext  - если расширенный формат то 1, иначе 0
  rtr  - если 1 то будет отправлен пакет вида Remote Request Frame 
-------------------------------------------------------------------------------------------------------------*/
void CAN_set_rx_mbox(volatile CAN_MemMapPtr CAN, INT8U n, INT32U id, INT32U mask, INT8U ext, INT8U rtr)
{
  // Переходим в Freeze режим поскольку маску фильтра можно изменить только в этом режиме
  CAN->MCR |= 0
              + BIT(30) // FRZ    . Freeze Enable. 1 Enabled to enter Freeze Mode
              + BIT(28) // HALT   . Halt FlexCAN. 1 Enters Freeze Mode if the FRZ bit is asserted.
  ;
  while ((CAN->MCR & BIT(24)) == 0)   // Ожидаем установки FRZACK
  {}

  // Сбросим флаг прерывания
  CAN->IFLAG1  |= (1 << n);

  // Инициализируем mailbox на передачу
  CAN->MB[n].CS = 0
                  + LSHIFT(0x0,     24) // CODE. 0b0000:INACTIVE- MB is not active.
                  + LSHIFT(1,       22) // SRR.  Substitute Remote Request. (должен быть 1 в расширенном формате)
                  + LSHIFT(ext,     21) // IDE.  ID Extended Bit.           1 = расширенный формат
                  + LSHIFT(rtr,     20) // RTR.  Remote Transmission Request. 1 - это mailbox с Remote Request Frame
                  + LSHIFT(0,       16) // DLC.  Длина данных
  ;
  CAN->MB[n].ID    = id;
  CAN->MB[n].WORD0 = 0;
  CAN->MB[n].WORD1 = 0;
  CAN->RXIMR[n] = mask; // Установим маску


  CAN->IMASK1  |= (1 << n); // Разрешаем прерывания после приема

  // Обозначаем готовность к приему
  CAN->MB[n].CS |= BIT(26); // 0b0100: EMPTY - MB is active and empty.

  CAN->MCR &= ~(BIT(30) + BIT(28)); // Выходим из режиме Freeze
  while (CAN->MCR & BIT(24))        // Ожидаем сброса FRZACK
  {}

}

/*-------------------------------------------------------------------------------------------------------------
  Установка буффера на отправку и инициация отправки
  n    - номер буфера
  id   - идентификатор CAN пакета
  data - буффер с данными длинной 8 байт
  len  - длина данных
  ext  - если расширенный формат то 1, иначе 0
  rtr  - если 1 то будет отправлен пакет вида Remote Request Frame 
-------------------------------------------------------------------------------------------------------------*/
void CAN_set_tx_mbox(volatile CAN_MemMapPtr CAN, INT8U n, INT32U id, INT8U *data, INT8U len, INT8U ext, INT8U rtr)
{
  // Сбросим флаг прерывания
  CAN->IFLAG1  |= (1 << n);
  // Инициализируем mailbox на передачу
  CAN->MB[n].CS = 0
                  + LSHIFT(0x8,     24) // CODE. 0b1000:MB is not active
                  + LSHIFT(1,       22) // SRR.  Substitute Remote Request. (должен быть 1 в расширенном формате)
                  + LSHIFT(ext,     21) // IDE.  ID Extended Bit.           1 = расширенный формат
                  + LSHIFT(rtr,     20) // RTR.  Remote Transmission Request. 1 - это mailbox с Remote Request Frame
                  + LSHIFT(len,     16) // DLC.  Длина данных
  ;
  CAN->MB[n].ID = id;
  CAN->MB[n].WORD0 = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
  CAN->MB[n].WORD1 = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];

  // Разрешаем прерывания после передачи
  CAN->IMASK1  |= (1 << n);
  // Запускаем передачу
  CAN->MB[n].CS |= BIT(26); // 0b1100: DATA - MB is a Tx Data Frame (MB RTR must be 0)
}


/*-------------------------------------------------------------------------------------------------------------
  Выборка данных из mailbox-а с принятым пакетом
  n    - номер буфера
-------------------------------------------------------------------------------------------------------------*/
void CAN_read_rx_mbox(volatile CAN_MemMapPtr CAN, INT8U n, T_can_rx *rx)
{

  INT32U cs;
  INT32U w;
  volatile INT32U tmp;

  cs = CAN->MB[n].CS;
  rx->len  = (cs >> 16) & 0x0F;
  rx->ext  = (cs >> 21) & 1;
  rx->rtr  = (cs >> 20) & 1;
  rx->code = (cs >> 24) & 0x0F;
  rx->canid  = CAN->MB[n].ID;
  w = CAN->MB[n].WORD0;
  rx->data[0] = (w >> 24) & 0xFF;
  rx->data[1] = (w >> 16) & 0xFF;
  rx->data[2] = (w >>  8) & 0xFF;
  rx->data[3] = (w >>  0) & 0xFF;
  w = CAN->MB[n].WORD1;
  rx->data[4] = (w >> 24) & 0xFF;
  rx->data[5] = (w >> 16) & 0xFF;
  rx->data[6] = (w >>  8) & 0xFF;
  rx->data[7] = (w >>  0) & 0xFF;
  tmp = CAN->TIMER; // Разблокировка Mialbox

}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void CAN_Tx_Task(uint_32 parameter)
{
  volatile CAN_MemMapPtr   CAN = (CAN_MemMapPtr)parameter;

  INT8U databl[8] =
  {
    0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
  };

  // Периодическая отправка тестового сообщения
  while (1)
  {
/*
    CAN_set_tx_mbox(CAN, CAN_TX_MB1, PDISPLx_REQ, databl, 3, 1, 0);
    databl[1]++;
    if ( databl[1] > 15 )
    {
      databl[1] = 0;
    }
*/
    _time_delay(1000);
  }

}


/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
_mqx_uint CAN_wait_log_rec(_mqx_uint ticks)
{
  if ( _lwevent_wait_ticks(&can_event, 0x80000000, FALSE, ticks) == MQX_OK )
  {
    _lwevent_clear(&can_event, 0x80000000);
    return MQX_OK;
  }
  return MQX_ERROR;
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
_mqx_uint CAN_pop_log_rec(T_can_rx  *rx)
{
  _lwsem_wait(&can_log_sem);
  if ( rx_log_head != rx_log_tail )
  {
    *rx = rx_log[rx_log_tail];
    rx_log_tail++;
    if ( rx_log_tail >= CAN_RX_LOG_SZ )
    {
      rx_log_tail = 0; 
    }
    _lwsem_post(&can_log_sem);
    return MQX_OK;
  }
  _lwsem_post(&can_log_sem);
  return MQX_ERROR;
}
/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
static _mqx_uint CAN_push_log_rec(T_can_rx  *rx)
{
  _lwsem_wait(&can_log_sem);
  rx_log[rx_log_head] = *rx;
  rx_log_head++;
  if ( rx_log_head >= CAN_RX_LOG_SZ )
  {
    rx_log_head = 0;
  }
  if ( rx_log_head == rx_log_tail )
  {
    rx_log_tail++;  
    if ( rx_log_tail >= CAN_RX_LOG_SZ )
    {
      rx_log_tail = 0; 
    }
  }
  _lwsem_post(&can_log_sem);

  _lwevent_set(&can_event, 0x80000000); // Уведомить о записи в лог
  return 0;
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void CAN_Rx_Task(uint_32 parameter)
{
  volatile CAN_MemMapPtr   CAN = (CAN_MemMapPtr)parameter;
  _mqx_uint events;
  T_can_rx  rx;
  T_MC_CBL     *mc_pcbl;


  INT32U    n;
  INT32U    events_mask = 0;

  mc_pcbl = MC_get_pcbl();

  rx_log_head=0;
  rx_log_tail=0;
  // Инициализация всех майлбоксов предназначенных для приема сообщений
  for (n = 0; n < RX_MBOX_CNT; n++)
  {
    CAN_set_rx_mbox(CAN, rx_mboxes[n].mb_num, rx_mboxes[n].canid, rx_mboxes[n].canid_mask, 1, 0);
    events_mask |= (1 << rx_mboxes[n].mb_num);
  }

  while (1)
  {

    if ( _lwevent_wait_ticks(&can_event, events_mask, FALSE, 0) == MQX_OK )
    {
      events = _lwevent_get_signalled();
      _lwevent_clear(&can_event, events);

      for (n = 0; n < RX_MBOX_CNT; n++)
      {
        if ( events & (1 << rx_mboxes[n].mb_num) )
        {
          CAN_read_rx_mbox(CAN, rx_mboxes[n].mb_num, &rx);
 
          CAN_push_log_rec(&rx);

          // Парсинг полученного пакета 
          
          if ( rx.canid == INVERT_REQ )
          {
            switch (rx.data[0])
            {
            case START_MOVING:
              
              if ( rx.data[1] == MOVING_UP )
              {
                 mc_pcbl->up_move_freq    = rx.data[2];
                 mc_pcbl->up_acceler_time = rx.data[3];
                 MC_set_events(MOTOR_START_UP);
              }
              else if ( rx.data[1] == MOVING_DOWN )
              {
                mc_pcbl->down_move_freq    = rx.data[2];    
                mc_pcbl->down_acceler_time = rx.data[3];    
                MC_set_events(MOTOR_START_DOWN);
              }

              //MC_start_motor_moving(rx.data[1], rx.data[2], rx.data[3]);
              break;
            case STOP_MOVING:
              if ( mc_pcbl->direction == MOVING_DOWN )
              {
                mc_pcbl->down_deceler_time = rx.data[1];
              }
              else
              {
                mc_pcbl->up_deceler_time = rx.data[1];
              }

              MC_set_events(MOTOR_STOP);

              //MC_stop_motor_moving(rx.data[1]);
              break;

            case EMERGENCY_STOP_MOVING:
              MC_emergency_stop_motor();
              break;
            }
          }
        }
      }
    }
  }
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/UART0.c<|end_filename|>
/* ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : UART0.c
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : Init_UART
**     Version     : Component 01.004, Driver 01.04, CPU db: 3.00.000
**     Compiler    : GNU C Compiler
**     Date/Time   : 2013-08-09, 15:03, # CodeGen: 12
**     Abstract    :
**          This file implements the UART (UART0) module initialization
**          according to the Peripheral Initialization settings, and
**          defines interrupt service routines prototypes.
**     Settings    :
**          Component name                                 : UART0
**          Device                                         : UART0
**          Settings                                       : 
**            Clock gate                                   : Enabled
**            Clock settings                               : 
**              Baud rate divisor                          : 65
**              Baud rate fine adjust                      : 3
**              Baud rate                                  : 115218.435 baud
**            Transfer settings                            : 
**              Data format                                : 8bit
**              Bits ordering                              : LSB first
**              Parity                                     : Off
**              Parity placement                           : Parity in last data bit
**            Idle character counting                      : After start bit
**            Break character generation length            : Short
**            LIN Break detection                          : Disabled
**            Stop in Wait mode                            : Disabled
**            Receiver wakeup settings                     : 
**              Receiver wakeup                            : Normal operation
**              Receiver wake up method                    : Idle-line
**              Receive wakeup idle detect                 : Don't set IDLE bit
**              Match address settings                     : 
**                Match address 1                          : Disabled
**                Match address 1 value                    : 0
**                Match address 2                          : Disabled
**                Match address 2 value                    : 0
**            Modem settings                               : 
**              Tx CTS                                     : Disabled
**              Tx RTS                                     : Disabled
**              Tx RTS polarity                            : Active low
**              Rx RTS                                     : Disabled
**            Infrared settings                            : 
**              Infrared                                   : Disabled
**              Tx narrow pulse width                      : 3/16
**            FIFOs settings                               : 
**              Tx FIFO                                    : Enabled
**              Tx watermark                               : 32
**              Rx FIFO                                    : Enabled
**              Rx watermark                               : 32
**            Smartcards interface (ISO7816) settings      : 
**              ISO7816 functionality                      : Disabled
**              Transfer type                              : T=0
**                Rx error action                          : Error NACK not generated
**                Rx FIFO overflow action                  : Overflow NACK not generated
**                Rx NACK threshold                        : 0
**                Tx NACK threshold                        : 0
**                Wait time value                          : 10
**              Init char detection                        : Disabled
**              Guard band N                               : 0
**              FD multiplier                              : 1
**            CEA709.1-B interface settings                : 
**              CEA709 functionality                       : Disabled
**              Collision detection                        : Disabled
**              Transmitter                                : Disabled
**              Collision signal polarity                  : Low
**              Packet time counter                        : 0
**              Beta 1 timer                               : 0
**              Secondary delay timer                      : 0
**              Preamble                                   : 0
**              WBase                                      : 0
**              Collision pulse width                      : 0
**              Receive indeterminate time                 : 0
**              Transmit indeterminate time                : 0
**            Loops and Single wire settings               : 
**              Loop mode                                  : Disabled
**              Receiver source in Loop mode               : Loop mode
**              TxD pin direction in Single-wire mode      : Input
**            Receiver input                               : Not inverted
**            Transmitter output                           : Not inverted
**          Pins/Signals                                   : 
**            Receiver pin                                 : Enabled
**              Pin                                        : TSI0_CH9/PTB16/SPI1_SOUT/UART0_RX/I2S1_TXD0/FBa_AD17/EWM_IN
**              Pin signal                                 : 
**            Transmitter pin                              : Enabled
**              Pin                                        : TSI0_CH10/PTB17/SPI1_SIN/UART0_TX/I2S1_TXD1/FBa_AD16/EWM_OUT_b
**              Pin signal                                 : 
**              Transmitter modulation                     : Disabled
**            CTS pin                                      : Disabled
**            RTS pin                                      : Disabled
**          Interrupts/DMA                                 : 
**            Common Tx/Rx interrupt                       : 
**              Interrupt                                  : INT_UART0_RX_TX
**              Interrupt request                          : Disabled
**              Interrupt priority                         : 0 (Highest)
**              ISR name                                   : 
**              Transmit empty request                     : Disabled
**              Transmit empty request type                : IRQ
**              Transmit complete request                  : Disabled
**              Receiver full request                      : Disabled
**              Receiver full request type                 : IRQ
**              Idle line request                          : Disabled
**              LIN break detect request                   : Disabled
**              Rx active edge interrupt                   : Disabled
**              Smartcards interface (ISO7816) interrupts  : 
**                Init char detected interrupt             : Disabled
**            Error Interrupt                              : 
**              Error interrupt                            : INT_UART0_ERR
**              Interrupt request                          : Disabled
**              Interrupt priority                         : 0 (Highest)
**              ISR name                                   : 
**              Overrun error interrupt                    : Disabled
**              Noise error interrupt                      : Disabled
**              Framing error interrupt                    : Disabled
**              Parity error interrupt                     : Disabled
**              FIFOs interrupts                           : 
**                Tx FIFO overflow interrupt               : Disabled
**                Rx FIFO underflow interrupt              : Disabled
**              Smartcards interface (ISO7816) interrupts  : 
**                Wait timer interrupt                     : Disabled
**                Char wait timer interrupt                : Disabled
**                Block wait timer interrupt               : Disabled
**                Tx threshold exceeded interrupt          : Disabled
**                Rx threshold exceeded                    : Disabled
**                Guard timer violated interrupt           : Disabled
**            CEA709 Interrupt                             : 
**              CEA709 interrupt                           : INT_UART0_LON
**              Interrupt request                          : Disabled
**              Interrupt priority                         : 0 (Highest)
**              ISR name                                   : 
**              Wbase expired interrupt                    : Disabled
**              Initial sync detection interrupt           : Disabled
**              Packet received interrupt                  : Disabled
**              Packet transmitted interrupt               : Disabled
**              Packet cycle timer interrupt               : Disabled
**              Preamble start interrupt                   : Disabled
**              Transmission fail interrupt                : Disabled
**          Initialization                                 : 
**            Send break                                   : Disabled
**            Enable transmitter                           : Enabled
**            Enable receiver                              : Enabled
**            Call Init method                             : yes
**     Contents    :
**         Init - void UART0_Init(void);
**
**     Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved.
**     SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/
/*!
** @file UART0.c
** @version 01.04
** @brief
**          This file implements the UART (UART0) module initialization
**          according to the Peripheral Initialization settings, and
**          defines interrupt service routines prototypes.
*/         
/*!
**  @addtogroup UART0_module UART0 module documentation
**  @{
*/         

/* MODULE UART0. */

#include "UART0.h"
  /* Including shared modules, which are used in the whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
#include "Cpu.h"


/*
** ===================================================================
**     Method      :  UART0_Init (component Init_UART)
**     Description :
**         This method initializes registers of the UART module
**         according to the Peripheral Initialization settings.
**         Call this method in user code to initialize the module. By
**         default, the method is called by PE automatically; see "Call
**         Init method" property of the component for more details.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void UART0_Init(void)
{
  /* SIM_SCGC4: UART0=1 */
  SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;                                   
  /* UART0_C2: TE=0,RE=0 */
  UART0_C2 &= (uint8_t)~(uint8_t)((UART_C2_TE_MASK | UART_C2_RE_MASK));                                   
  /* UART0_BDL: SBR=0x41 */
  UART0_BDL = UART_BDL_SBR(0x41);                                   
  /* UART0_BDH: LBKDIE=0,RXEDGIE=0,??=0,SBR=0 */
  UART0_BDH = UART_BDH_SBR(0x00);                                   
  /* UART0_MA1: MA=0 */
  UART0_MA1 = UART_MA1_MA(0x00);                                   
  /* UART0_MA2: MA=0 */
  UART0_MA2 = UART_MA2_MA(0x00);                                   
  /* UART0_C4: MAEN1=0,MAEN2=0,M10=0,BRFA=3 */
  UART0_C4 = UART_C4_BRFA(0x03);                                   
  /* UART0_C1: LOOPS=0,UARTSWAI=0,RSRC=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */
  UART0_C1 = 0x00U;                                   
  /* UART0_S2: LBKDIF=1,RXEDGIF=1,MSBF=0,RXINV=0,RWUID=0,BRK13=0,LBKDE=0,RAF=0 */
  UART0_S2 = (UART_S2_LBKDIF_MASK | UART_S2_RXEDGIF_MASK);                                   
  /* UART0_MODEM: ??=0,??=0,??=0,??=0,RXRTSE=0,TXRTSPOL=0,TXRTSE=0,TXCTSE=0 */
  UART0_MODEM = 0x00U;                                   
  /* UART0_IR: ??=0,??=0,??=0,??=0,??=0,IREN=0,TNP=0 */
  UART0_IR = UART_IR_TNP(0x00);                                   
  /* UART0_TWFIFO: TXWATER=0x20 */
  UART0_TWFIFO = UART_TWFIFO_TXWATER(0x20);                                   
  /* UART0_RWFIFO: RXWATER=0x20 */
  UART0_RWFIFO = UART_RWFIFO_RXWATER(0x20);                                   
  /* UART0_SFIFO: TXEMPT=0,RXEMPT=0,??=0,??=0,??=0,RXOF=0,TXOF=1,RXUF=1 */
  UART0_SFIFO = (UART_SFIFO_TXOF_MASK | UART_SFIFO_RXUF_MASK);                                   
  /* UART0_CFIFO: TXFLUSH=1,RXFLUSH=1,??=0,??=0,??=0,RXOFE=0,TXOFE=0,RXUFE=0 */
  UART0_CFIFO = (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK);                                   
  /* UART0_PFIFO: TXFE=1,RXFE=1 */
  UART0_PFIFO |= (UART_PFIFO_TXFE_MASK | UART_PFIFO_RXFE_MASK);                                   
  /* UART0_WN7816: GTN=0 */
  UART0_WN7816 = UART_WN7816_GTN(0x00);                                   
  /* UART0_WF7816: GTFD=1 */
  UART0_WF7816 = UART_WF7816_GTFD(0x01);                                   
  /* UART0_WP7816T0: WI=0x0A */
  UART0_WP7816T0 = UART_WP7816_T_TYPE0_WI(0x0A);                                   
  /* UART0_ET7816: TXTHRESHOLD=0,RXTHRESHOLD=0 */
  UART0_ET7816 = (UART_ET7816_TXTHRESHOLD(0x00) | UART_ET7816_RXTHRESHOLD(0x00));                                   
  /* UART0_IS7816: WT=1,CWT=1,BWT=1,INITD=1,??=0,GTV=1,TXT=1,RXT=1 */
  UART0_IS7816 = UART_IS7816_WT_MASK |
                 UART_IS7816_CWT_MASK |
                 UART_IS7816_BWT_MASK |
                 UART_IS7816_INITD_MASK |
                 UART_IS7816_GTV_MASK |
                 UART_IS7816_TXT_MASK |
                 UART_IS7816_RXT_MASK;       
  /* UART0_IE7816: WTE=0,CWTE=0,BWTE=0,INITDE=0,??=0,GTVE=0,TXTE=0,RXTE=0 */
  UART0_IE7816 = 0x00U;                                   
  /* UART0_C7816: ??=0,??=0,??=0,ONACK=0,ANACK=0,INIT=0,TTYPE=0,ISO_7816E=0 */
  UART0_C7816 = 0x00U;                                   
  /* UART0_PCTH: PCTH=0 */
  UART0_PCTH = UART_PCTH_PCTH(0x00);                                   
  /* UART0_PCTL: PCTL=0 */
  UART0_PCTL = UART_PCTL_PCTL(0x00);                                   
  /* UART0_B1T: B1T=0 */
  UART0_B1T = UART_B1T_B1T(0x00);                                   
  /* UART0_SDTH: SDTH=0 */
  UART0_SDTH = UART_SDTH_SDTH(0x00);                                   
  /* UART0_SDTL: SDTL=0 */
  UART0_SDTL = UART_SDTL_SDTL(0x00);                                   
  /* UART0_PRE: PREAMBLE=0 */
  UART0_PRE = UART_PRE_PREAMBLE(0x00);                                   
  /* UART0_WB: WBASE=0 */
  UART0_WB = UART_WB_WBASE(0x00);                                   
  /* UART0_CPW: CPW=0 */
  UART0_CPW = UART_CPW_CPW(0x00);                                   
  /* UART0_RIDT: RIDT=0 */
  UART0_RIDT = UART_RIDT_RIDT(0x00);                                   
  /* UART0_TIDT: TIDT=0 */
  UART0_TIDT = UART_TIDT_TIDT(0x00);                                   
  /* UART0_C6: EN709=0,TX709=0,CE=0,CP=0 */
  UART0_C6 &= (uint8_t)~(uint8_t)(
               UART_C6_EN709_MASK |
               UART_C6_TX709_MASK |
               UART_C6_CE_MASK |
               UART_C6_CP_MASK
              );                                   
  /* UART0_S3: PEF=1,WBEF=1,ISD=0,PRXF=1,PTXF=1,PCTEF=1,PSF=1,TXFF=1 */
  UART0_S3 = UART_S3_PEF_MASK |
             UART_S3_WBEF_MASK |
             UART_S3_PRXF_MASK |
             UART_S3_PTXF_MASK |
             UART_S3_PCTEF_MASK |
             UART_S3_PSF_MASK |
             UART_S3_TXFF_MASK;       
  /* UART0_S4: ??=0,??=0,??=0,INITF=0,CDET=3,ILCV=1,FE=1 */
  UART0_S4 = (UART_S4_CDET(0x03) | UART_S4_ILCV_MASK | UART_S4_FE_MASK);                                   
  /* UART0_IE: WBEIE=0,ISDIE=0,PRXIE=0,PTXIE=0,PCTEIE=0,PSIE=0,TXFIE=0 */
  UART0_IE &= (uint8_t)~(uint8_t)(
               UART_IE_WBEIE_MASK |
               UART_IE_ISDIE_MASK |
               UART_IE_PRXIE_MASK |
               UART_IE_PTXIE_MASK |
               UART_IE_PCTEIE_MASK |
               UART_IE_PSIE_MASK |
               UART_IE_TXFIE_MASK
              );                                   
      (void) UART0_S1;                 /* Dummy read of the UART0_S1 register to clear flags */
      (void) UART0_D;                  /* Dummy read of the UART0_D register to clear flags */
  /* UART0_C5: TDMAS=0,??=0,RDMAS=0,??=0,??=0,??=0,??=0,??=0 */
  UART0_C5 = 0x00U;                                   
  /* UART0_C3: R8=0,T8=0,TXDIR=0,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */
  UART0_C3 = 0x00U;                                   
  /* UART0_C2: TIE=0,TCIE=0,RIE=0,ILIE=0,TE=1,RE=1,RWU=0,SBK=0 */
  UART0_C2 = (UART_C2_TE_MASK | UART_C2_RE_MASK);                                   
}


/* END UART0. */
/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.2 [05.06]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/telnsrv.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: telnsrv.c$
* $Version : 172.16.58.3$
* $Date    : Sep-21-2012$
*
* Comments:
*
*   This file contains the Telnet server implementation.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include <serial.h>
#include "telnet.h"


struct telnetsrv_init {
   RTCS_TASK_PTR  shell;
   uint_32        sock;
};

typedef struct  telnetsrv_context {
   uint_32     UDPSOCK;
   uint_32     LISTENSOCK;
} TELNETSRV_CONTEXT, _PTR_ TELNETSRV_CONTEXT_PTR;

_rtcs_taskid TELNETSRV_task_id = 0;

#ifdef __MQX__ 
void TELNETSRV_Exit_handler(void);
#endif

void TELNETSRV_task  (pointer, pointer);
void TELNETSRV_child (pointer, pointer);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TELNETSRV_test_run
* Returned Value   : updated TELNETSRV_task_id
* Comments  :  Test if Telnet server is running and update TELNETSRV_task_id.
*
*END*-----------------------------------------------------------------*/

static _rtcs_taskid TELNETSRV_test_run
   (
       void
   )
{
   if (TELNETSRV_task_id != 0) {
     if (_task_get_td (RTCS_task_id_from_td (TELNETSRV_task_id)) == NULL) {
       TELNETSRV_task_id = 0;
     }
   }
   return TELNETSRV_task_id;
}


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TELNETSRV_run
* Returned Value   : error code
* Comments  :  Become the Telnet server.
*
*END*-----------------------------------------------------------------*/

uint_32 TELNETSRV_run
   (
       RTCS_TASK_PTR  shell
   )
{ 
   struct telnetsrv_init init;
   if (TELNETSRV_test_run () != 0)  {
     return RTCSERR_SERVER_ALREADY_RUNNING;
   }
   init.shell = shell;
   init.sock  = RTCS_SOCKET_ERROR;
   TELNETSRV_task_id = RTCS_task_getid();
   TELNETSRV_task(&init,0);
   TELNETSRV_task_id = 0;
   return RTCSERR_SERVER_NOT_RUNNING;
} 


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TELNETSRV_init
* Returned Value   : error code
* Comments  :  Start the Telnet server.
*
*END*-----------------------------------------------------------------*/

uint_32 TELNETSRV_init
   (
      char_ptr       name,
      uint_32        priority,
      uint_32        stacksize,
      RTCS_TASK_PTR  shell
   )
{ /* Body */
   struct telnetsrv_init init;

   if (TELNETSRV_test_run () == 0)  {
      init.shell = shell;
      init.sock  = RTCS_SOCKET_ERROR;
      return RTCS_task_create(name, priority, stacksize, TELNETSRV_task, &init);
   } else  {
      return RTCSERR_SERVER_ALREADY_RUNNING;
   }
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TELNETSRV_sockinit
* Returned Value   : error code
* Comments  :  Start the Telnet server with an existing socket.
*
*END*-----------------------------------------------------------------*/

uint_32 TELNETSRV_sockinit
   (
      char_ptr       name,
      uint_32        priority,
      uint_32        stacksize,
      RTCS_TASK_PTR  shell,
      uint_32        sock
   )
{ /* Body */
   struct telnetsrv_init init;

   if (TELNETSRV_test_run () == 0)  {
      init.shell = shell;
      init.sock  = sock;
      return RTCS_task_create(name, priority, stacksize, TELNETSRV_task, &init);
   } else  {
      return RTCSERR_SERVER_ALREADY_RUNNING;
   }

} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name    : TELNET_server
* Returned Value   : none
* Comments  :  A TCP/IP based Telnet Server
*
*END*-----------------------------------------------------------------*/

void TELNET_server
   (
      uint_32 template_index
   )
{ /* Body */
   struct telnetsrv_init      init;
   RTCS_TASK                  shell;
   TASK_TEMPLATE_STRUCT_PTR   template_ptr;

   template_ptr = _mqx_get_initialization()->TASK_TEMPLATE_LIST;
   while (template_ptr->TASK_TEMPLATE_INDEX &&
          (template_ptr->TASK_TEMPLATE_INDEX != template_index)) {
      template_ptr++;
   } /* Endwhile */

   shell.NAME      = template_ptr->TASK_NAME;
   shell.PRIORITY  = template_ptr->TASK_PRIORITY;
   shell.STACKSIZE = template_ptr->TASK_STACKSIZE;
   shell.START     = (void(_CODE_PTR_)(pointer))template_ptr->TASK_ADDRESS;
   shell.ARG       = (pointer)template_ptr->CREATION_PARAMETER;

   init.shell = &shell;
   init.sock  = RTCS_SOCKET_ERROR;

   TELNETSRV_task(&init, NULL);

} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name    : TELNETSRV_task
* Returned Value   : none
* Comments  :  A TCP/IP based Telnet Server
*
* If sock<0, *sockp is set to a newly created TCP socket, and it
* is connected to raddr.
*
*END*-----------------------------------------------------------------*/

void TELNETSRV_task
   (
      pointer  init_ptr,
      pointer  creator
   )
{ /* Body */
   struct telnetsrv_init init;
   RTCS_TASK             shell = *((struct telnetsrv_init _PTR_)init_ptr)->shell;
   uint_32               sock = ((struct telnetsrv_init _PTR_)init_ptr)->sock;
   sockaddr_in           addr;
   uint_32               error,option;
   TELNETSRV_CONTEXT     telnetsrv_context =  { 0 };

   TELNETSRV_task_id = RTCS_task_getid();
#ifdef __MQX__ 
   /* Set up exit handler and context so that we can clean up if the Echo Server is terminated */
   _task_set_environment( _task_get_id(), (pointer) &telnetsrv_context );
   _task_set_exit_handler( _task_get_id(), TELNETSRV_Exit_handler );
#endif 

   /* Install device drivers for socket and telnet I/O */
   _io_socket_install("socket:");
   _io_telnet_install("telnet:");

   /* Allocate a socket if the caller didn't provide one */
   if (sock == RTCS_SOCKET_ERROR) {
      sock = socket(PF_INET, SOCK_STREAM, 0);
      if (sock == RTCS_SOCKET_ERROR) {
         RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
      }
   }
  
   telnetsrv_context.LISTENSOCK = sock;
  
   option = TELNETDCFG_BUFFER_SIZE;   
   error = setsockopt(telnetsrv_context.LISTENSOCK, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));
   if (error) {
      RTCS_task_exit(creator, error);
   }      

   option = TELNETDCFG_BUFFER_SIZE;   
   error = setsockopt(telnetsrv_context.LISTENSOCK, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));
   if (error) {
      RTCS_task_exit(creator, error);
   }   

   option = TELNETDCFG_NOWAIT;   
   error = setsockopt(telnetsrv_context.LISTENSOCK, SOL_TCP, OPT_NOWAIT, &option, sizeof(option));
   if (error) {
      RTCS_task_exit(creator, error);
   }      

   option = TELENETDCFG_SEND_TIMEOUT;   
   error = setsockopt(telnetsrv_context.LISTENSOCK, SOL_TCP, OPT_SEND_TIMEOUT, &option, sizeof(option));
   if (error) {
      RTCS_task_exit(creator, error);
   }      

   option = TELENETDCFG_CONNECT_TIMEOUT;   
   error = setsockopt(telnetsrv_context.LISTENSOCK, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));
   if (error) {
      RTCS_task_exit(creator, error);
   }      

   option = TELENETDCFG_TIMEWAIT_TIMEOUT;   
   error = setsockopt(telnetsrv_context.LISTENSOCK, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));
   if (error) {
      RTCS_task_exit(creator, error);
   }      

   /* Bind the socket to the Telnet port */
   addr.sin_family      = AF_INET;
   addr.sin_port        = IPPORT_TELNET;
   addr.sin_addr.s_addr = INADDR_ANY;

   error = bind(sock,(const sockaddr *)&addr, sizeof(addr));
   if (error != RTCS_OK) {
      RTCS_task_exit(creator, error);
   } /* Endif */

   /* Put the socket into listening mode */
   error = listen(sock, 0);
   if (error != RTCS_OK) {
      RTCS_task_exit(creator, error);
   } /* Endif */

   RTCS_task_resume_creator(creator, RTCS_OK);

   init.shell = &shell;
   while (TRUE) {

      /* Wait for a connection */
      init.sock = accept(sock, NULL, NULL);
      if (init.sock == RTCS_SOCKET_ERROR) {
         continue;
      } /*Endif*/
      
#if TELNETDCFG_ENABLE_MULTIPLE_CLIENTS

      /* Create a task to look after it */
      RTCS_detachsock(init.sock);
      if (RTCS_task_create(shell.NAME, shell.PRIORITY, shell.STACKSIZE, TELNETSRV_child, &init)!=RTCS_OK) {
         RTCS_attachsock(init.sock);
         shutdown(init.sock, FLAG_ABORT_CONNECTION);
      }
      #else
         TELNETSRV_child((pointer) &init,0);
      #endif

   } /* Endwhile */

} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Task Name      : TELNETSRV_child
* Returned Value : void
* Comments       : Telnet child task.
*
*END*-----------------------------------------------------------------*/

void TELNETSRV_child
   (
      pointer  init_ptr,
      pointer  creator
   )
{ /* Body */
   struct telnetsrv_init _PTR_ init = init_ptr;
   uint_32                     sock = init->sock;
   _mqx_uint                   param;
   void (_CODE_PTR_            start)(pointer) = init->shell->START;
   pointer                     arg = init->shell->ARG;

   MQX_FILE_PTR sockfd, telnetfd;

   sockfd = fopen("socket:", (char_ptr)sock);
   if (sockfd == NULL) {
      RTCS_task_exit(creator, RTCSERR_FOPEN_FAILED);
   } /* Endif */

#ifndef TELNETDCFG_SOCKIO_BUFFER_SIZE
#define TELNETDCFG_SOCKIO_BUFFER_SIZE  100 // 1460
#endif 
   param =  TELNETDCFG_SOCKIO_BUFFER_SIZE;
   ioctl(sockfd, IO_IOCTL_SET_BLOCK_MODE, &param);

   telnetfd = fopen("telnet:", (char_ptr)sockfd);
   if (telnetfd == NULL) {
      RTCS_task_exit(creator, RTCSERR_FOPEN_FAILED);
   } /* Endif */


   param = IO_SERIAL_ECHO;
   ioctl(telnetfd, IO_IOCTL_SERIAL_SET_FLAGS, &param);

   _io_set_handle(IO_STDIN, telnetfd);
   _io_set_handle(IO_STDOUT, telnetfd);

   RTCS_task_resume_creator(creator, RTCS_OK);

   /*
   ** Send a greeting message to the user
   */
   printf("\nRTCS v%d.%02d.%02d Telnet server\n",
          RTCS_VERSION_MAJOR, RTCS_VERSION_MINOR, RTCS_VERSION_REV);

   /*
   ** Call user application function
   */
   start(arg);

   printf("\nGoodbye\n");

   /*
   ** Allow some time for queued data to go out.
   */
   RTCS_time_delay(100);

   /*
   ** Child task is done
   */
   fclose(telnetfd);
   fclose(sockfd);
   shutdown(sock, FLAG_CLOSE_TX);
} /* Endbody */

#ifdef __MQX__ 
/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TELNETSRV_stop
* Returned Value   : error code
* Comments  :  Start the TELNETSRV task.
*
*END*-----------------------------------------------------------------*/

uint_32 TELNETSRV_stop( void )
{ /* Body */
   if (TELNETSRV_test_run () == 0)  {
      return RTCSERR_SERVER_NOT_RUNNING;
   }
   RTCS_task_abort(TELNETSRV_task_id);
   TELNETSRV_task_id = 0;
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TELNETSRV_Exit_handler
* Returned Value   : error code
* Comments  :  Start the TELNETSRV task.
*
*END*-----------------------------------------------------------------*/

void TELNETSRV_Exit_handler( void )
{ /* Body */
   TELNETSRV_CONTEXT_PTR    telnetsrv_context_ptr;
   
   telnetsrv_context_ptr = (TELNETSRV_CONTEXT_PTR) _task_get_environment( _task_get_id() );
   if (telnetsrv_context_ptr != NULL)  {
      if (telnetsrv_context_ptr->UDPSOCK)  {
         shutdown(telnetsrv_context_ptr->UDPSOCK, 0);
         telnetsrv_context_ptr->UDPSOCK = 0;   
      }   
      if (telnetsrv_context_ptr->LISTENSOCK)  {
         shutdown(telnetsrv_context_ptr->LISTENSOCK, FLAG_ABORT_CONNECTION);   
         telnetsrv_context_ptr->LISTENSOCK = 0;   
      }   
   }
   TELNETSRV_task_id = 0;
} /* Endbody */
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/tad/tad.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tad.c$
* $Version : 3.8.10.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   Serial version of Task Aware Debugging.
*
*END************************************************************************/


#include <mqx.h>
#include <psp.h>
#include <mem_prv.h>
#include <mqx_prv.h>
#include <lwmem.h>
#include <lwmem_prv.h>
#include <fio.h>
#include <string.h>
#include "tad.h"


#define MEM_TYPE_MAX_STRING_LENGTH 32


const char_ptr MQX_mem_type_str[] = 
{
   NULL,
   "SYSTEM_STACK",
   "INTERRUPT_STACK",
   "INTERRUPT_TABLE",
   "TASK",
   "READYQ",
   "PARTITION_COMPONENT",
   "PARTITION",
   "PARTITION_BLOCKS",
   "MESSAGE_COMPONENT",
   "MESSAGE_QUEUES",
   "MESSAGE_POOLS",
   "MESSAGE_POOL_BLOCKS",
   "LWLOG_COMPONENT",
   "LWLOG",
   "IO_DEVICE",
   "MQX_FILE_PTR",
   "TASK_Q",
   "EDS_BUFFER",
   "EVENT_COMPONENT",
   "EVENT_CONNECTION",
   "EVENT",
   "LOG_COMPONENT",
   "LOG",
   "MUTEX_COMPONENT",
   "NAME_COMPONENT",
   "SEMAPHORE_COMPONENT",
   "SEMAPHORE_CONNECTION",
   "SEMAPHORE",
   "TIMER_COMPONENT",
   "TIMER_ENTRY",
   "WATCHDOG_COMPONENT",
   "WATCHDOG_ALARM",
   "PSP_SUPPORT_STRUCT",
   "FP_CONTEXT",
   "INTERRUPT_VECTOR"
};


const char_ptr MQX_IO_mem_type_str[] = 
{
   NULL,
   "IO_PCFLASH",
   "IO_SECTOR_BUFFER",
   "IO_CHAN_STRUCT",
   "IO_ENET_CFG_STRUCT",
   "IO_ENET_BUFFERS",
   "IO_ENET_MCB",
   "IO_ENET_ECB",
   NULL,
   NULL,
   "IO_DUN",
   "IO_DUN_DEV",
   "IO_GPIO_DEV_DATA",
   "IO_GPIO_PIN_MAP",
   "IO_MEM_STRUCT",
   "IO_MEM_DATA",
   "IO_SERIAL_INT_DEVICE_STRUCT",
   "IO_SERIAL_POLLED_DEVICE_STRUCT",
   "IO_SERIAL_IN_QUEUE",
   "IO_SERIAL_OUT_QUEUE",
   "IO_SERIAL_CHARQ",
   "IO_SERIAL_INFO_STRUCT",
   "IO_TFS_DRIVE_STRUCT",
   "IO_SPI_INT_DEVICE_STRUCT",
   "IO_SPI_POLLED_DEVICE_STRUCT",
   "IO_SPI_IN_BUFFER",
   "IO_SPI_OUT_BUFFER",
   "IO_SPI_INFO_STRUCT",
   "IO_FLASHX_RAM_FUNCT",
   "IO_FLASHX_SECTOR_CACHE",
   "IO_FLASHX_SECTOR_MAP",
   "IO_I2C_INT_DEVICE_STRUCT",
   "IO_I2C_POLLED_DEVICE_STRUCT",
   "IO_I2C_IN_BUFFER",
   "IO_I2C_OUT_BUFFER",
   "IO_I2C_INFO_STRUCT",
   "IO_PCB_PTR",
   "IO_PCB_STRUCT",
   "IO_BD_STRUCT",
   "IO_ENET_MAC_CONTEXT_STRUCT",
   "IO_SDCARD_STRUCT",
   "IO_ESDHC_DEVICE_STRUCT",
   "IO_ESDHC_INFO_STRUCT"
};

  
const char_ptr RTCS_mem_type_str[] = 
{
   NULL,
   "RTCS_DATA",
   "ARP_CFG",
   "ARP_ENTRY",
   "DHCP_CLNT_STRUCT",
   "DHCPSRV_OPTIONS_STRUCT",
   "FTPd_SESSION_PTR",
   "FTPd_DATA_BUFFER",
   "ICMP_CFG_STRUCT",
   "ICMP_DATA",
   "IP_CFG_STRUCT",
   "IP_DATA",
   "ICB",
   "IP_IF",
   "SOCKET_CONFIG_STRUCT",
   "RTCS_PARTITION",
   "IO_SOCKET",
   "SOCKET_OWNER_STRUCT",
   "TCP_CFG_STRUCT",
   "TCB",
   "TCP_TX_WINDOW",
   "TCP_RX_WINDOW",
   "TCP_SEND_CLOCK",
   "UDP_CFG_STRUCT",
   "UCB_STRUCT ",
   "UDP_BUFFER",
   "IO_TELNET",
   "SbufNode",
   "Rchunk",
   "FTPc_CONTEXT_STRUCT",
   "DHCPSRV_ADDR_STRUCT",
   "DHCPSRV_CID",
   "DNS_CONTROL_STRUCT",
   "DNS_UDP_MESSAGE",
   "FTPc_RX_BUFFER",
   "FTPc_COMMAND_BUFFER",
   "HOSTENT_STRUCT",
   "TFTP_PACKET",
   "TFTP_TRANS_STRUCT",
   NULL,
   "MEM_TYPE_HTTPD_STRUCT",
   "HTTPD_PARAMS",
   "HTTPD_SESSION_STRUCT",
   "HTTPD_URI",
   "HTTPD_AUTH",
   "HTTPD_LINE",               
};

/*!
 * \brief Gets string representation of given memory type.
 * 
 * \param[in] type_str String representation of memory type.
 * \param[in] mem_type Memory type.
 * 
 * \return String representation of memory type. 
 */ 
static char_ptr mem_type_str 
   (
      char      type_str[MEM_TYPE_MAX_STRING_LENGTH], 
      _mem_type mem_type
   )
{
   char_ptr  str = NULL;
   _mem_type component = mem_type >> MEM_TYPE_COMPONENT_SHIFT;  
   uint_32   index = 0xfff & mem_type; 

   switch (component) 
   {
      case 0:
         if (index < 1000)
         {
            if (index < sizeof (MQX_mem_type_str) / sizeof (char_ptr))
            {
               str = MQX_mem_type_str[index];
            }
         } 
         else 
         {
            index -= 1000;
            if (index < sizeof (MQX_IO_mem_type_str) / sizeof (char_ptr))
            {
               str = MQX_IO_mem_type_str[index];
            }
         }
         break;

      case IO_RTCS_COMPONENT:
         if (index < sizeof (RTCS_mem_type_str) / sizeof (char_ptr))
         {
            str = RTCS_mem_type_str[index];
         }
         break;

      case IO_MFS_COMPONENT:
         str = "MFS";
         break;

      case IO_USB_COMPONENT:
         str = "USB";
         break;

      case IO_SHELL_COMPONENT:
         str = "SHELL";
         break;
      default:
         break;
   }
   if (NULL != str) 
   {
      strncpy (type_str, str, MEM_TYPE_MAX_STRING_LENGTH);
   } 
   else 
   {
      sprintf (type_str, "Unknown mem type 0x%x", mem_type);
   }
   return type_str;
}   

/*!
 * \brief Prints intormation of memory blocks. 
 */ 
void _tad_lightweight_memory_blocks 
   (
       void
   ) 
{
   uint_32                size, next_free;
   char                   owner[8], mem_type[MEM_TYPE_MAX_STRING_LENGTH];
   LWMEM_POOL_STRUCT_PTR  mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR) _lwmem_get_system_pool_id();
   uint_32                start_ptr = (uint_32) mem_pool_ptr->POOL_ALLOC_START_PTR;
   uint_32                end_ptr = (uint_32) mem_pool_ptr->POOL_ALLOC_END_PTR;
   LWMEM_BLOCK_STRUCT_PTR mem_ptr = (LWMEM_BLOCK_STRUCT_PTR) start_ptr;

   printf ("\nLightweight Memory Blocks:\n");
   printf ("Address   Size(hex)   Size(dec)   Owner   Type\n");
   
   while ((uint_32) mem_ptr < end_ptr)
   {
      size = mem_ptr->BLOCKSIZE;
      next_free = (uint_32)mem_ptr->U.NEXTBLOCK;

      if ((next_free >= start_ptr) && (next_free <= end_ptr) || (next_free == 0)) 
      {
         sprintf (owner, "Free");
         mem_type[0] = 0;
      } 
      else 
      {
         mem_type_str (mem_type, mem_ptr->U.S.MEM_TYPE);
         if (mem_ptr->U.S.TASK_NUMBER == TASK_NUMBER_FROM_TASKID(MQX_DEFAULT_TASK_ID))
         {
            sprintf (owner,"System");
         } 
         else 
         {
            sprintf (owner,"0x1%04x", mem_ptr->U.S.TASK_NUMBER);
         }
      }
      printf ("0x%lx   0x%x   %d   %s   %s\n", (uint_32)mem_ptr, size, size, owner, mem_type);
      mem_ptr = (LWMEM_BLOCK_STRUCT_PTR)(((uint_32)mem_ptr) + size); 
      if (((uint_32)mem_ptr < start_ptr) || ((uint_32)mem_ptr > end_ptr)) 
      {
         printf ("Block out of range!\n");
         break;
      }
   }
}

/*!
 * \brief Prints stacks usage. 
 */ 
void _tad_stack_usage 
   (
       void
   ) 
{
#if MQX_MONITOR_STACK && MQX_TD_HAS_STACK_LIMIT
   _mqx_uint_ptr            stack_used, stack_limit;
   _mqx_int                 percent, size;
   TD_STRUCT_PTR            td_ptr;
   TASK_TEMPLATE_STRUCT_PTR template_ptr;
   KERNEL_DATA_STRUCT_PTR   kernel_data_ptr = _mqx_get_kernel_data ();
   char_ptr                 task_name;

   printf ("\nStack Usage:\n");
   printf ("Task   Stack Base   Stack Limit   Stack Used   %% Used   Overflow?\n");


   size = _QUEUE_GET_SIZE(&kernel_data_ptr->TD_LIST);
   td_ptr = (TD_STRUCT_PTR)((uchar_ptr)kernel_data_ptr->TD_LIST.NEXT - FIELD_OFFSET(TD_STRUCT,TD_LIST_INFO));
   while ((0 != size) && (NULL != td_ptr))
   {
#if MQX_TD_HAS_TASK_TEMPLATE_PTR
      template_ptr = td_ptr->TASK_TEMPLATE_PTR;
      task_name = template_ptr->TASK_NAME;
#else
      char  name[12];
      sprintf(name, "0x%x", td_ptr->TASK_ID);
      task_name = name;
#endif        
      stack_used = td_ptr->STACK_LIMIT;
      stack_used++;
      while (*stack_used == 0x7374616B) 
      {
         stack_used++;
      }
      if ((stack_used == td_ptr->STACK_LIMIT) || (stack_used == (_mqx_uint_ptr)td_ptr->STACK_LIMIT + 1)) 
      {
         percent=100;
      }
      else 
      {
         percent = ((_mqx_uint_ptr)td_ptr->STACK_BASE - stack_used) * 100 / ((_mqx_uint_ptr)td_ptr->STACK_BASE - (_mqx_uint_ptr)td_ptr->STACK_LIMIT);
      }
      printf ("%s   0x%lx   0x%lx   0x%lx   %ld %%   %s\n", task_name, td_ptr->STACK_BASE, td_ptr->STACK_LIMIT, stack_used, percent,percent>=100?"Yes":"No");
        
      size--;
      td_ptr = (TD_STRUCT_PTR)((uchar_ptr)(td_ptr->TD_LIST_INFO.NEXT) - FIELD_OFFSET(TD_STRUCT,TD_LIST_INFO));
   }
    
   stack_used = stack_limit = (_mqx_uint_ptr)(((_mqx_uint)(kernel_data_ptr->INTERRUPT_STACK_PTR)) - kernel_data_ptr->INIT.INTERRUPT_STACK_SIZE);
   stack_used++;
   while (*stack_used == 0x7374616B) 
   {
      stack_used++;
   }
   if ((stack_used == td_ptr->STACK_LIMIT) || (stack_used == (_mqx_uint_ptr)td_ptr->STACK_LIMIT + 1)) 
   {
      printf ("Interrupt   0x%lx   0x%lx   0x%lx   100 %%   Yes", kernel_data_ptr->INTERRUPT_STACK_PTR, stack_limit, stack_used);
   }
   else 
   {
      percent = ((_mqx_uint_ptr)kernel_data_ptr->INTERRUPT_STACK_PTR - stack_used) * 100 / ((_mqx_uint_ptr)kernel_data_ptr->INTERRUPT_STACK_PTR - stack_limit);
      printf ("Interrupt   0x%lx   0x%lx   0x%lx   %ld %%   No", kernel_data_ptr->INTERRUPT_STACK_PTR, stack_limit, stack_used, percent);
   }
   printf ("\n");
#endif
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi/spi_dspi.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_dspi.c$
* $Version : 3.8.2.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   The file contains low level SPI driver functions for DSPI module
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>

#include "spi.h"
#include "spi_prv.h"
#include "spi_dspi_prv.h"


/* SPI low level driver interface functions */
static _mqx_int _dspi_init(const void _PTR_ init_data_ptr, pointer *io_info_ptr_ptr);
static _mqx_int _dspi_deinit(pointer io_info_ptr);
static _mqx_int _dspi_setparam(pointer io_info_ptr, SPI_PARAM_STRUCT_PTR params);
static _mqx_int _dspi_tx_rx(pointer io_info_ptr, uint_8_ptr txbuf, uint_8_ptr rxbuf, uint_32 len);
static _mqx_int _dspi_cs_deassert(pointer io_info_ptr);
static _mqx_int _dspi_ioctl(pointer io_info_ptr, SPI_PARAM_STRUCT_PTR params, uint_32 cmd, uint_32_ptr param_ptr);

const SPI_DEVIF_STRUCT _spi_dspi_devif = {
    _dspi_init,
    _dspi_deinit,
    _dspi_setparam,
    _dspi_tx_rx,
    _dspi_cs_deassert,
    _dspi_ioctl
};


/* Forward declarations */
static void _dspi_isr(pointer parameter);

static const uint_32 BAUDRATE_PRESCALER[] = { 2, 3, 5, 7 };
static const uint_32 BAUDRATE_SCALER[] = { 2, 4, 6, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 };

static const uint_32 DELAY_PRESCALER[] = { 1, 3, 5, 7 };

/*FUNCTION****************************************************************
*
* Function Name    : _dspi_find_baudrate
* Returned Value   : Actual baudrate obtained by programming the CTAR register
* Comments         :
*    Find closest setting of divider register for given baudrate.
*    Value of CTAR register is returned via pointer.
*
*END*********************************************************************/
static uint_32 _dspi_find_baudrate
    (
        /* [IN] Module input clock in Hz */
        uint_32 clock,

        /* [IN] Desired baudrate in Hz */
        uint_32 baudrate,

        /* [IN] Timing parameters of CTAR register to configure use */
        uint_32_ptr ctar
    )
{
    uint_32 pres, best_pres;
    uint_32 scaler, best_scaler;
    uint_32 dbr, best_dbr;
    uint_32 real_baudrate, best_baudrate;

    uint_32 delayrate;

    int_32  diff;
    uint_32 min_diff;

    /* find combination of prescaler and scaler resulting in baudrate closest to the requested value */
    min_diff = (uint_32)-1;
    best_pres = 0;
    best_scaler = 0;
    best_dbr = 1;
    best_baudrate = 0; /* required to avoid compilation warning */
    for (pres = 0; (pres < 4) && min_diff; pres++)
    {
        for (scaler = 0; (scaler < 16) && min_diff; scaler++)
        {
            for (dbr = 1; (dbr < 3) && min_diff; dbr++)
            {
                real_baudrate = ((clock * dbr) / (BAUDRATE_PRESCALER[pres] * (BAUDRATE_SCALER[scaler])));

                diff = baudrate - real_baudrate;
                if (diff < 0)
                    diff = -diff;

                if (min_diff > diff)
                {
                    /* a better match found */
                    min_diff = diff;
                    best_pres = pres;
                    best_scaler = scaler;
                    best_baudrate = real_baudrate;
                    best_dbr = dbr;
                }
            }
        }
    }

    if (ctar == NULL)
        return best_baudrate;

    /* store baudrate scaler and prescaler settings to ctar */
    *ctar = DSPI_CTAR_PBR(best_pres) | DSPI_CTAR_BR(best_scaler);
    *ctar |= ((best_dbr - 1) * DSPI_CTAR_DBR_MASK);

    /* similar lookup for delay prescalers */
    min_diff = (uint_32)-1;
    delayrate = baudrate * 4; /* double the baudrate (half period delay is sufficient) and divisor is (2<<scaler), thus times 4 */
    /* initialize prescaler and scaler to slowest possible rate to cover the case when no better match is found */
    best_pres = ELEMENTS_OF(BAUDRATE_PRESCALER)-1;
    best_scaler = ELEMENTS_OF(BAUDRATE_SCALER)-1;
    for (pres = 0; (pres < 4) && min_diff; pres++)
    {
        for (scaler = 0; scaler < 16; scaler++)
        {
            diff = delayrate - ((clock / DELAY_PRESCALER[pres])>>scaler);
            if (diff >= 0) {  /* To ensure that the delay time is larger than half period of baudrate */
               if (min_diff > diff)
               {
                  /* a better match found */
                  min_diff = diff;
                  best_pres = pres;
                  best_scaler = scaler;
               }
               else break; /* higher scaler value cannot provide with better match */
            }
        }
    }

    /* add delay scalers and prescaler settings to ctar */
    *ctar |= DSPI_CTAR_CSSCK(best_scaler) | DSPI_CTAR_PCSSCK(best_pres);
    *ctar |= DSPI_CTAR_DT(best_scaler) | DSPI_CTAR_PDT(best_pres);
    *ctar |= DSPI_CTAR_ASC(best_scaler) | DSPI_CTAR_PASC(best_pres); /* CS deasserted in sw, slow enough */

    return best_baudrate;
}


/*FUNCTION****************************************************************
*
* Function Name    : _dspi_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes the SPI driver
*
*END*********************************************************************/
static _mqx_int _dspi_init
    (
        /* [IN] The initialization information for the device being opened */
        const void _PTR_               init_data_ptr,

        /* [OUT] The address to store device specific information */
        pointer                        *io_info_ptr_ptr
    )
{
    DSPI_INIT_STRUCT_PTR               dspi_init_ptr = (DSPI_INIT_STRUCT_PTR)init_data_ptr;

    DSPI_INFO_STRUCT_PTR               dspi_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr;

    const uint_32 _PTR_                vectors;
    uint_32                            i;

    #if PSP_HAS_DEVICE_PROTECTION
    if (!_bsp_dspi_enable_access(dspi_init_ptr->CHANNEL)) {
        return SPI_ERROR_CHANNEL_INVALID;
    }
    #endif

    /* Check channel */
    dspi_ptr = _bsp_get_dspi_base_address (dspi_init_ptr->CHANNEL);
    if (NULL == dspi_ptr)
    {
        return SPI_ERROR_CHANNEL_INVALID;
    }

    if (_bsp_dspi_io_init (dspi_init_ptr->CHANNEL) == -1)
    {
        return SPI_ERROR_CHANNEL_INVALID;
    }

    /* Initialize internal data */
    dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)_mem_alloc_system_zero((uint_32)sizeof(DSPI_INFO_STRUCT));
    if (dspi_info_ptr == NULL)
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type (dspi_info_ptr,MEM_TYPE_IO_SPI_INFO_STRUCT);

    *io_info_ptr_ptr = (pointer)dspi_info_ptr;

    dspi_info_ptr->DSPI_PTR = dspi_ptr;
    dspi_info_ptr->CHANNEL = dspi_init_ptr->CHANNEL;
    dspi_info_ptr->CLOCK_SOURCE = dspi_init_ptr->CLOCK_SOURCE;

    /* Disable and clear SPI */
    dspi_ptr->MCR &= (~ DSPI_MCR_MDIS_MASK);
    dspi_ptr->MCR = DSPI_MCR_HALT_MASK | DSPI_MCR_CLR_TXF_MASK | DSPI_MCR_CLR_RXF_MASK;

    #if DSPI_FIFO_DEPTH == 1
    /* Disable FIFO */
    dspi_ptr->MCR |= DSPI_MCR_DIS_RXF_MASK | DSPI_MCR_DIS_TXF_MASK;
    #endif

    /* Receive FIFO overflow disable */
    dspi_ptr->MCR |= DSPI_MCR_ROOE_MASK;

    /* Set CS0-7 inactive high */
    dspi_ptr->MCR |= DSPI_MCR_PCSIS(0xFF);

    /* Disable interrupts */
    dspi_ptr->RSER = 0;

    /* Clear all flags */
    dspi_ptr->SR = ~ DSPI_SR_TFFF_MASK;

    dspi_info_ptr->NUM_VECTORS = _bsp_get_dspi_vectors(dspi_info_ptr->CHANNEL, &vectors);

    /* Install ISRs */
    for (i=0; i<dspi_info_ptr->NUM_VECTORS; i++)
    {
        dspi_info_ptr->OLD_ISR_DATA[i] = _int_get_isr_data(vectors[i]);
        dspi_info_ptr->OLD_ISR[i] = _int_install_isr(vectors[i], _dspi_isr, dspi_info_ptr);
        _bsp_int_init((PSP_INTERRUPT_TABLE_INDEX)vectors[i], BSP_DSPI_INT_LEVEL, 0, TRUE);
    }

    _lwsem_create(&dspi_info_ptr->EVENT_IO_FINISHED, 0);

    /* Enable SPI */
    dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);

    return SPI_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _dspi_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes the SPI module
*
*END*********************************************************************/
static _mqx_int _dspi_deinit
    (
        /* [IN] the address of the device specific information */
        pointer                        io_info_ptr
    )
{
    DSPI_INFO_STRUCT_PTR               dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)io_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr = dspi_info_ptr->DSPI_PTR;

    const uint_32 _PTR_                vectors;
    int                                num_vectors;
    int                                i;

    if (NULL == dspi_info_ptr)
    {
        return SPI_ERROR_DEINIT_FAILED;
    }

    /* Disable the SPI */
    dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;

    /* Disable interrupts */
    dspi_ptr->RSER = 0;

    /* Return original interrupt vectors */
    num_vectors = _bsp_get_dspi_vectors(dspi_info_ptr->CHANNEL, &vectors);

    for (i=0; i<num_vectors; i++)
    {
        _int_install_isr(vectors[i], dspi_info_ptr->OLD_ISR[i], dspi_info_ptr->OLD_ISR_DATA[i]);
    }

    _lwsem_destroy(&dspi_info_ptr->EVENT_IO_FINISHED);

    _mem_free(dspi_info_ptr);
    return SPI_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _dspi_setparam
* Returned Value   :
* Comments         :
*    Set parameters for following transfers.
*
*END*********************************************************************/
static _mqx_int _dspi_setparam
   (
        /* [IN] Device specific context structure */
        pointer                        io_info_ptr,

        /* [IN] Parameters to set */
        SPI_PARAM_STRUCT_PTR           params
   )
{
    DSPI_INFO_STRUCT_PTR               dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)io_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr = dspi_info_ptr->DSPI_PTR;

    BSP_CLOCK_CONFIGURATION clock_config;
    uint_32 clock_speed;

    uint_32 ctar;

    clock_config = _bsp_get_clock_configuration();

    /* Check the parameter against most recent values to avoid time consuming baudrate finding routine */
    if ((dspi_info_ptr->CLOCK_CONFIG != clock_config) || (dspi_info_ptr->BAUDRATE != params->BAUDRATE))
    {
        dspi_info_ptr->CLOCK_CONFIG = clock_config;
        dspi_info_ptr->BAUDRATE = params->BAUDRATE;

        /* Find configuration of prescalers best matching the desired value */
        clock_speed = _bsp_get_clock(dspi_info_ptr->CLOCK_CONFIG, dspi_info_ptr->CLOCK_SOURCE);
        _dspi_find_baudrate(clock_speed, dspi_info_ptr->BAUDRATE, &(dspi_info_ptr->CTAR_TIMING));
    }

    /* Set up prescalers */
    ctar = dspi_info_ptr->CTAR_TIMING;

    /* Set up SPI clock polarity and phase */
    if (params->MODE & SPI_CPHA_MASK)
        ctar |= DSPI_CTAR_CPHA_MASK;

    if (params->MODE & SPI_CPOL_MASK)
        ctar |= DSPI_CTAR_CPOL_MASK;

    /* Set up frame size */
    if (params->FRAMESIZE < 3 || params->FRAMESIZE > 16)
        return SPI_ERROR_FRAMESIZE_INVALID;
    ctar |= DSPI_CTAR_FMSZ(params->FRAMESIZE - 1);

    /* Transfer mode */
    if ((params->ATTR & SPI_ATTR_TRANSFER_MODE_MASK) != SPI_ATTR_MASTER_MODE)
        return SPI_ERROR_TRANSFER_MODE_INVALID;

    /* Endianess */
    if ((params->ATTR & SPI_ATTR_ENDIAN_MASK) == SPI_ATTR_LITTLE_ENDIAN)
        ctar |= DSPI_CTAR_LSBFE_MASK;

    /* Disable SPI module */
    dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;

    dspi_ptr->CTAR[0] = ctar;

    /* Receive FIFO overflow disable */
    dspi_ptr->MCR |= DSPI_MCR_ROOE_MASK;

    /* Set CS0-7 inactive high */
    dspi_ptr->MCR |= DSPI_MCR_PCSIS(0xFF);

    /* Set master mode */
    dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK;

    /* Disable interrupts */
    dspi_ptr->RSER = 0;

    /* Clear all flags */
    dspi_ptr->SR = ~ DSPI_SR_TFFF_MASK;

    /* Enable SPI module */
    dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);

    dspi_info_ptr->CS = params->CS;
    dspi_info_ptr->DUMMY_PATTERN = params->DUMMY_PATTERN;
    dspi_info_ptr->ATTR = params->ATTR;

    return SPI_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _dspi_isr
* Returned Value   : SPI interrupt routine
* Comments         :
*   State machine transferring data between buffers and DSPI FIFO.
*
*END*********************************************************************/
static void _dspi_isr
    (
        /* [IN] The address of the device specific information */
        pointer                        parameter
    )
{
    DSPI_INFO_STRUCT_PTR               dspi_info_ptr = parameter;
    VDSPI_REG_STRUCT_PTR               dspi_ptr = dspi_info_ptr->DSPI_PTR;

    uint_32                            command;
    uint_32                            data;

    /* drain RX FIFO */
    if (DSPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) > 7)
    {
        /* frame is larger than a single byte */
        while (dspi_ptr->SR & DSPI_SR_RFDF_MASK)
        {
            data = DSPI_POPR_RXDATA_GET(dspi_ptr->POPR);
            dspi_ptr->SR = DSPI_SR_RFDF_MASK;
            if (dspi_info_ptr->RX_LEN)
            {
                dspi_info_ptr->RX_LEN--;
                if (dspi_info_ptr->RX_BUF)
                {
                    dspi_info_ptr->RX_BUF[0] = data>>8;
                    dspi_info_ptr->RX_BUF[1] = data&0xff;
                    dspi_info_ptr->RX_BUF += 2;
                }
            }
        }
    }
    else
    {
        /* single byte frame */
        while (dspi_ptr->SR & DSPI_SR_RFDF_MASK)
        {
            data = DSPI_POPR_RXDATA_GET(dspi_ptr->POPR);
            dspi_ptr->SR = DSPI_SR_RFDF_MASK;
            if (dspi_info_ptr->RX_LEN)
            {
                dspi_info_ptr->RX_LEN--;
                if (dspi_info_ptr->RX_BUF)
                {
                    *(dspi_info_ptr->RX_BUF) = data;
                    dspi_info_ptr->RX_BUF++;
                }
            }
        }
    }

    /* check whether all requested data was received */
    if (dspi_info_ptr->RX_LEN == 0)
    {
        /* signalize finished job and disable further interrupts */
        dspi_ptr->RSER = 0;
        _lwsem_post(&dspi_info_ptr->EVENT_IO_FINISHED);
        return;
    }

    /* fill TX FIFO */
    command = DSPI_PUSHR_CONT_MASK | DSPI_PUSHR_PCS(dspi_info_ptr->CS) | DSPI_PUSHR_CTAS(0);
    if (DSPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) > 7)
    {
        /* frame is larger than a single byte */
        while (dspi_info_ptr->TX_LEN && (dspi_ptr->SR & DSPI_SR_TFFF_MASK) && ((dspi_info_ptr->RX_LEN-dspi_info_ptr->TX_LEN)<DSPI_FIFO_DEPTH))
        {
            dspi_info_ptr->TX_LEN--;
            if (dspi_info_ptr->TX_BUF)
            {
                data = dspi_info_ptr->TX_BUF[0];
                data = (data << 8) | dspi_info_ptr->TX_BUF[1];
                dspi_info_ptr->TX_BUF += 2;
            }
            else
            {
              data = dspi_info_ptr->DUMMY_PATTERN;
            }
            dspi_ptr->PUSHR = command | DSPI_PUSHR_TXDATA(data);
            dspi_ptr->SR = DSPI_SR_TFFF_MASK;
        }
    }
    else
    {
        /* single byte frame */
        while (dspi_info_ptr->TX_LEN && (dspi_ptr->SR & DSPI_SR_TFFF_MASK) && ((dspi_info_ptr->RX_LEN-dspi_info_ptr->TX_LEN)<DSPI_FIFO_DEPTH))
        {
            dspi_info_ptr->TX_LEN--;
            if (dspi_info_ptr->TX_BUF)
            {
                data = *(dspi_info_ptr->TX_BUF);
                dspi_info_ptr->TX_BUF ++;
            }
            else
            {
                data = dspi_info_ptr->DUMMY_PATTERN;
            }
            dspi_ptr->PUSHR = command | DSPI_PUSHR_TXDATA(data);
            dspi_ptr->SR = DSPI_SR_TFFF_MASK;
        }
    }
}


/*FUNCTION****************************************************************
*
* Function Name    : _dspi_tx_rx
* Returned Value   : number of bytes transferred
* Comments         :
*   Actual transmit and receive function.
*   Overrun prevention used, no need to update statistics in this function
*
*END*********************************************************************/
static _mqx_int _dspi_tx_rx
    (
        /* [IN] Device specific context structure */
        pointer                        io_info_ptr,

        /* [IN] Data to transmit */
        uint_8_ptr                     txbuf,

        /* [OUT] Received data */
        uint_8_ptr                     rxbuf,

        /* [IN] Length of transfer in bytes */
        uint_32                        len
    )
{
    DSPI_INFO_STRUCT_PTR               dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)io_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr = dspi_info_ptr->DSPI_PTR;

    uint_32                            tx_len;
    uint_32                            rx_len;

    uint_32                            command;
    uint_32                            data;

    boolean                            use_isr;

    use_isr = dspi_info_ptr->NUM_VECTORS && dspi_info_ptr->ATTR & DSPI_ATTR_USE_ISR;

    command = DSPI_PUSHR_CONT_MASK | DSPI_PUSHR_PCS(dspi_info_ptr->CS) | DSPI_PUSHR_CTAS(0);
    data = dspi_info_ptr->DUMMY_PATTERN;

    /* Is frame larger than a single byte? */
    if (DSPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) > 7)
    {
        len = len & (~1UL);
        rx_len = tx_len = len;

        while (rx_len)
        {
            if (tx_len) {
                if ((dspi_ptr->SR & DSPI_SR_TFFF_MASK) && ((rx_len-tx_len)<DSPI_FIFO_DEPTH))
                {
                    if (txbuf)
                    {
                        data = *txbuf++;
                        data = (data << 8) | *txbuf++;
                    }
                    dspi_ptr->PUSHR = command | DSPI_PUSHR_TXDATA(data);
                    dspi_ptr->SR = DSPI_SR_TFFF_MASK;
                    tx_len--;
                }
                else if (use_isr)
                {
                    /* do not wait for RX data in a loop, break it and use ISR */
                    break;
                }
            }

            if (dspi_ptr->SR & DSPI_SR_RFDF_MASK)
            {
                data = DSPI_POPR_RXDATA_GET(dspi_ptr->POPR);
                dspi_ptr->SR = DSPI_SR_RFDF_MASK;
                if (rxbuf)
                {
                    *rxbuf++ = data >> 8;
                    *rxbuf++ = data & 0xff;
                }
                rx_len--;
            }
            else if (tx_len == 0 && use_isr)
            {
                /* do not wait for RX data in a loop, break it and use ISR */
                break;
            }
        }
    }
    else
    {
        rx_len = tx_len = len;

        /* Optimized loop for single byte frames */
        while (rx_len)
        {
            if (tx_len) {
                if ((dspi_ptr->SR & DSPI_SR_TFFF_MASK) && ((rx_len-tx_len)<DSPI_FIFO_DEPTH))
                {
                    if (txbuf)
                        data = *txbuf++;
                    dspi_ptr->PUSHR = command | DSPI_PUSHR_TXDATA(data);
                    dspi_ptr->SR = DSPI_SR_TFFF_MASK;
                    tx_len--;
                }
                else if (use_isr)
                {
                    /* do not wait for RX data in a loop, break it and use ISR */
                    break;
                }
            }

            if (dspi_ptr->SR & DSPI_SR_RFDF_MASK)
            {
                if (rxbuf)
                    *rxbuf++ = DSPI_POPR_RXDATA_GET(dspi_ptr->POPR);
                else
                    dspi_ptr->POPR; /* dummy read to drain FIFO */
                dspi_ptr->SR = DSPI_SR_RFDF_MASK;
                rx_len--;
            }
            else if (tx_len == 0 && use_isr)
            {
                /* do not wait for RX data in a loop, break it and use ISR */
                break;
            }
        }
    }

    if (rx_len)
    {
        /* finish the transfer using ISR */
        dspi_info_ptr->TX_BUF = txbuf;
        dspi_info_ptr->TX_LEN = tx_len;
        dspi_info_ptr->RX_BUF = rxbuf;
        dspi_info_ptr->RX_LEN = rx_len;

        /* enable interrupt and wait for ISR state machine to finish the job */
        dspi_ptr->RSER = DSPI_RSER_RFDF_RE_MASK;
        _lwsem_wait(&dspi_info_ptr->EVENT_IO_FINISHED);
    }

    return len;
}


/*FUNCTION****************************************************************
*
* Function Name    : _dspi_cs_deassert
* Returned Value   :
* Comments         :
*   Deactivates chip select signals.
*
*END*********************************************************************/
static _mqx_int _dspi_cs_deassert
    (
        /* [IN] The address of the device registers */
        pointer                        io_info_ptr
    )
{
    DSPI_INFO_STRUCT_PTR               dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)io_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr = dspi_info_ptr->DSPI_PTR;

    dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;
    dspi_ptr->MCR &= (~ DSPI_MCR_MSTR_MASK);
    dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK;
    dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);

    return MQX_OK;
}


/*FUNCTION****************************************************************
*
* Function Name    : _dspi_ioctl
* Returned Value   : MQX error code
* Comments         :
*    This function performs miscellaneous services for
*    the SPI I/O device.
*
*END*********************************************************************/
static _mqx_int _dspi_ioctl
    (
        /* [IN] The address of the device specific information */
        pointer                        io_info_ptr,

        /* [IN] SPI transfer parameters */
        SPI_PARAM_STRUCT_PTR           params,

        /* [IN] The command to perform */
        uint_32                        cmd,

        /* [IN] Parameters for the command */
        uint_32_ptr                    param_ptr
    )
{
    DSPI_INFO_STRUCT_PTR               dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)io_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr = dspi_info_ptr->DSPI_PTR;

    uint_32                            result = SPI_OK;

    BSP_CLOCK_CONFIGURATION clock_config;
    uint_32 clock_speed;

    switch (cmd)
    {
        case IO_IOCTL_SPI_GET_BAUD:
            clock_config = _bsp_get_clock_configuration();
            clock_speed = _bsp_get_clock(clock_config, dspi_info_ptr->CLOCK_SOURCE);
            *((uint_32_ptr)param_ptr) = _dspi_find_baudrate(clock_speed, *((uint_32_ptr)param_ptr), NULL);
            break;

        default:
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }
    return result;
}



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcstime.h<|end_filename|>
#ifndef __rtcstime_h__
#define __rtcstime_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcstime.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   TCP/IP internal Time Server definitions
*
*END************************************************************************/


/***************************************
**
** Type definitions
**
*/

/*
** A timer event
*/
typedef struct tcpip_event {

   uint_32                    TIME;
   boolean (_CODE_PTR_        EVENT)(struct tcpip_event _PTR_);
   pointer                    PRIVATE;

   struct tcpip_event _PTR_   NEXT;

} TCPIP_EVENT, _PTR_ TCPIP_EVENT_PTR;


/***************************************
**
** Prototypes
**
*/

void TCPIP_Event_init(void);

void TCPIP_Event_add(TCPIP_EVENT_PTR);
void TCPIP_Event_cancel(TCPIP_EVENT_PTR);

uint_32 TCPIP_Event_expire(TCPIP_EVENT_PTR);

uint_32 TCPIP_Event_time(uint_32);

#define TCPIP_Event_launch(var, time, event, private) \
         {                             \
            (var)->TIME = time;        \
            (var)->EVENT = event;      \
            (var)->PRIVATE = private;  \
            TCPIP_Event_add(var);      \
         }

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_directory.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_directory.c$
* $Version : 3.8.11.0$
* $Date    : Aug-30-2011$
*
* Comments:
*
*   This file contains the functions that are used to create, remove, change,
*   and search through directories.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"



#if !MFSCFG_READ_ONLY

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Create_subdir
* Returned Value   :  error_code
* Comments  :  Create a subdirectory.
*
*END*---------------------------------------------------------------------*/

_mfs_error  MFS_Create_subdir
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    char_ptr                pathname    /*[IN] pathname of the directory to be created */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    uint_32                 dir_cluster;
    uint_32                 parent_cluster;
    uint_32                 free_cluster;
    uint_32                 dir_index;
    _mfs_error              error_code;
    char_ptr                temp_dirname;
    char_ptr                temp_filename;

    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        return MFS_INVALID_PARAMETER;
    }

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_alloc_2paths(&temp_dirname,&temp_filename);
    if ( error_code != MFS_NO_ERROR )
    {
        return( error_code );
    }
    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        MFS_free_path(temp_dirname);
        MFS_free_path(temp_filename);
        return error_code;
    }

    MFS_Parse_pathname (temp_dirname, temp_filename, pathname);
    dir_cluster = drive_ptr->CUR_DIR_CLUSTER;
    parent_cluster = MFS_Find_directory (drive_ptr, temp_dirname, dir_cluster);

    dir_cluster = parent_cluster;
    if ( MFS_is_valid_lfn(temp_filename) )
    {
        if ( dir_cluster != CLUSTER_INVALID )
        {
            /*
            ** We'll obtain a cluster for the new directory first. If we
            ** cannot create the directory afterwards, it is easier to re-free
            ** the cluster than to remove the new entry.
            */
            free_cluster = MFS_Find_unused_cluster_from(drive_ptr, drive_ptr->NEXT_FREE_CLUSTER);
            if ( free_cluster != CLUSTER_INVALID )
            {
                error_code = MFS_Clear_cluster(drive_ptr, free_cluster);
                if ( error_code )
                {
                    MFS_unlock(drive_ptr,TRUE);
                    MFS_free_path(temp_dirname);
                    MFS_free_path(temp_filename);
                    return( error_code );
                }
                error_code = MFS_Put_fat(drive_ptr, free_cluster, CLUSTER_EOF);
                dir_entry_ptr = MFS_Create_directory_entry(drive_ptr, temp_filename, MFS_ATTR_DIR_NAME, &dir_cluster, &dir_index, &error_code);
                if ( error_code == MFS_NO_ERROR )
                {
                    clustod(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER, free_cluster);
                    drive_ptr->DIR_SECTOR_DIRTY = TRUE;

                    /*
                    ** We shall now create the "." and ".." entries.
                    */
                    dir_cluster = free_cluster;
                    dir_entry_ptr = MFS_Create_directory_entry(drive_ptr,".",  MFS_ATTR_DIR_NAME, &dir_cluster, &dir_index, &error_code);
                    if ( error_code == MFS_NO_ERROR )
                    {
                        clustod(dir_entry_ptr->HFIRST_CLUSTER,  dir_entry_ptr->LFIRST_CLUSTER, free_cluster);
                        drive_ptr->DIR_SECTOR_DIRTY = TRUE;
                        dir_entry_ptr = MFS_Create_directory_entry(drive_ptr,"..", MFS_ATTR_DIR_NAME, &dir_cluster, &dir_index, &error_code);

                        if ( error_code == MFS_NO_ERROR )
                        {
                            if ( drive_ptr->FAT_TYPE == MFS_FAT32 )
                            {
                                if ( drive_ptr->BPB32.ROOT_CLUSTER == parent_cluster )
                                {
                                    /* 
                                    ** Even though the FAT32 root sector can be 
                                    ** anywhere, it is identified as 0 when referenced 
                                    ** through a directory entry
                                    */          
                                    parent_cluster = 0;
                                }
                            }
                            clustod(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER, parent_cluster);
                            drive_ptr->DIR_SECTOR_DIRTY = TRUE;
                        }
                    }
                }
                else
                {
                    MFS_Put_fat(drive_ptr, free_cluster, CLUSTER_UNUSED);
                }  
            }
            else
            {
                error_code = MFS_DISK_FULL;
            }  
        }
        else
        {
            error_code = MFS_PATH_NOT_FOUND;
        }  
    }
    else if ( MFS_lfn_dirname_valid(temp_filename) )
    {
        if ( dir_cluster )
        {
            error_code = MFS_FILE_EXISTS;
        }
        else
        {
            error_code = MFS_CANNOT_CREATE_DIRECTORY;
        }  
    }
    else
    {
        error_code = MFS_INVALID_PARAMETER;
    }  

    MFS_free_path(temp_dirname);
    MFS_free_path(temp_filename);
    MFS_unlock(drive_ptr,TRUE);

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Remove_subdir
* Returned Value   :  error_code
* Comments  :  If the specified subdirectory has no entries, then remove
*                    the directory.
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Remove_subdir
    (
    MQX_FILE_PTR            mfs_fd_ptr,  /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    char_ptr                pathname     /*[IN] pathname of the directory to be removed */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    _mfs_error              error_code, saved_error = 0;
    uint_32                 dir_cluster, parent_cluster, dir_index;
    MFS_DIR_ENTRY_PTR       dir_entry_ptr;
    uint_32                 prev_cluster= CLUSTER_INVALID; 
    uint_32                 parent_prev_cluster= CLUSTER_INVALID; 

    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        return MFS_INVALID_PARAMETER;
    }

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }

    dir_entry_ptr = MFS_Find_entry_on_disk (drive_ptr, pathname, &error_code, &parent_cluster, &dir_index,  &parent_prev_cluster);  

    if ( dir_entry_ptr )
    {
        if ( dtohc(dir_entry_ptr->ATTRIBUTE) & MFS_ATTR_DIR_NAME )
        {
            dir_cluster = clustoh(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER);
            if ( dir_cluster != drive_ptr->CUR_DIR_CLUSTER )
            {
                dir_index = 2;  /* Skip over '.' and '..' */
                dir_entry_ptr = MFS_Find_directory_entry (drive_ptr, NULL, &dir_cluster, &dir_index, &prev_cluster, MFS_ATTR_ANY, &error_code);  
                if ( dir_entry_ptr == NULL && !error_code )
                {
                    dir_index = 0;
                    dir_entry_ptr = MFS_Find_entry_on_disk (drive_ptr, pathname, &error_code, &parent_cluster, &dir_index, &parent_prev_cluster);
                    if ( dir_entry_ptr )
                    {
                        *dir_entry_ptr->NAME = MFS_DEL_FILE;
                        drive_ptr->DIR_SECTOR_DIRTY = TRUE;
                        error_code = MFS_remove_lfn_entries(drive_ptr, parent_cluster, dir_index, parent_prev_cluster); 
                        if ( !error_code )
                        {
                            saved_error = MFS_Release_chain(drive_ptr, dir_cluster);
                        }
                    }
                }
                else if ( dir_entry_ptr != NULL && !error_code )
                {
                    error_code = MFS_FILE_EXISTS;
                }
            }
            else
            {
                error_code = MFS_ATTEMPT_TO_REMOVE_CURRENT_DIR;
            }  
        }
        else
        {
            error_code = MFS_WRITE_FAULT;
        }  
    }
    else
    {
        error_code = MFS_PATH_NOT_FOUND;
    }  

    MFS_unlock(drive_ptr,TRUE);

    if ( saved_error == MFS_LOST_CHAIN && error_code == MFS_NO_ERROR )
    {
        error_code = saved_error;
    }

    return(error_code);
}  

#endif

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Get_current_dir
* Returned Value   :  error_code
* Comments  :  Return the pathname of the current directory.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Get_current_dir
    (
    MQX_FILE_PTR            mfs_fd_ptr,     /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    char_ptr                buffer_address  /*[IN/OUT] address of the buffer where the pathname is to be written */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    _mfs_error              error_code;

    if ( buffer_address == NULL )
    {
        return MFS_INVALID_PARAMETER;
    }

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }

    strcpy(buffer_address, drive_ptr->CURRENT_DIR);

    MFS_unlock(drive_ptr,FALSE);

    return(error_code);
}  



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Change_current_dir
* Returned Value   :  error_code
* Comments  :  Change the current directory.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Change_current_dir
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    char_ptr               pathname     /*[IN] pathname of the directory to become the current dir */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    uint_32                 dir_cluster;
    uint_16                 length;
    _mfs_error              error_code;
    char_ptr                directory;
    char_ptr                temp_cur;
    register char_ptr       src, dest, dest_start;

    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        return MFS_INVALID_PARAMETER;
    }

    error_code = MFS_alloc_2paths(&directory,&temp_cur);
    if ( error_code != MFS_NO_ERROR )
    {
        return( error_code );
    }

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        MFS_free_path(directory);
        MFS_free_path(temp_cur);
        return error_code;
    }

    dir_cluster = drive_ptr->CUR_DIR_CLUSTER;
    dir_cluster = MFS_Find_directory(drive_ptr, pathname, dir_cluster);

    if ( dir_cluster != CLUSTER_INVALID )
    {
        src = pathname;
        dest = temp_cur;

        if ( *src == '\\' || *src == '/' )
        {
            temp_cur[0] = '\\';
            temp_cur[1] = '\0';
            src++;
        }
        else
        {
            strcpy (temp_cur, drive_ptr->CURRENT_DIR);
            dest = temp_cur + strlen(temp_cur) - 1;
        }  
        dest_start = temp_cur;

        length = strlen(dest_start);

        while ( src )
        {
            if ( *src )
            {
                src = MFS_Parse_next_filename(src, directory);
                if ( src != NULL )
                {
                    MFS_strupr(directory);
                }
                if ( directory[0] == '.' && directory[1] == '.' )
                {
                    if ( dest != dest_start )
                    {
                        while ( dest != dest_start && *dest != '\\' )
                        {
                            dest--;
                        }  
                        /* Erase the previous backslash, unless it is the
                        ** first (root directory).
                        */
                        if ( dest != dest_start )
                        {
                            *dest-- = '\0';
                        }
                        else
                        {
                            *(dest+1) = '\0';
                        }  
                    }
                    else
                    {
                        /*
                        ** The check for underflow is redundant, because the path
                        ** has been found already.
                        */
                        error_code = MFS_PATH_NOT_FOUND;
                        break;
                    }  
                }
                else if ( directory[0] && directory[0] != '.' )
                {
                    if ( *dest != '\\' )
                    {
                        *(++dest) = '\\';
                        length++;
                    }
                    length += strlen(directory);
                    if ( length < sizeof (drive_ptr->CURRENT_DIR) )
                    {
                        strcpy (++dest, directory);
                        dest = temp_cur + length - 1;
                    }
                    else
                    {
                        error_code = MFS_INVALID_LENGTH_IN_DISK_OPERATION;
                        break;
                    }  
                }
            }
            else
            {
                break;
            }  
        }  
        if ( error_code == MFS_NO_ERROR )
        {
            strcpy (drive_ptr->CURRENT_DIR, dest_start);
            drive_ptr->CUR_DIR_CLUSTER = dir_cluster;
        }
    }
    else
    {
        error_code = MFS_PATH_NOT_FOUND;
    }  

    MFS_free_path(directory);
    MFS_free_path(temp_cur);
    MFS_unlock(drive_ptr,FALSE);

    return(error_code);
}  

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Check_dir_exist
* Returned Value   :  error_code
* Comments  :  Check if directory exist on device
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Check_dir_exist
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    char_ptr               pathname     /*[IN] pathname of the directory to become the current dir */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    uint_32                 dir_cluster;
    _mfs_error              error_code;
    char_ptr                directory;

    // for empty string return error
    if ( (pathname == NULL) || (*pathname == '\0') )
    {
        return MFS_INVALID_PARAMETER;
    }

    // allocate memory for directory
    error_code = MFS_alloc_path(&directory);
    if ( error_code != MFS_NO_ERROR )
    {
        return( error_code );
    }

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        MFS_free_path(directory);
        return error_code;
    }

    dir_cluster = ROOT_CLUSTER(drive_ptr);
    dir_cluster = MFS_Find_directory(drive_ptr, pathname, dir_cluster);

    if ( dir_cluster == CLUSTER_INVALID )
    {
        error_code = MFS_PATH_NOT_FOUND;
    }  

    MFS_free_path(directory);
    MFS_unlock(drive_ptr,FALSE);

    return(error_code);
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Find_first_file
* Returned Value   : error_code
* Comments  :   Find the first file that matches the input criteria.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Find_first_file
    (
    MQX_FILE_PTR            mfs_fd_ptr,     /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    uchar                   attribute,      /*[IN] type of file to find, Search attributes */
    char_ptr                pathname,       /*[IN] optionally the directory and filename to search for */
    MFS_SEARCH_DATA_PTR     transfer_ptr    /*[IN] address of search data block into which the results of the search are put */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    MFS_INTERNAL_SEARCH_PTR internal_search_ptr;
    char_ptr                temp_dirname;
    char_ptr                temp_filename;
    uint_32                 current_cluster;
    _mfs_error              error_code;
    uint_32                 i;
    char                    c;

    if ( (pathname==NULL) || (*pathname=='\0') )
    {
        return MFS_INVALID_PARAMETER;
    }

    if ( transfer_ptr == NULL )
    {
        return MFS_INVALID_MEMORY_BLOCK_ADDRESS;
    }

    error_code = MFS_alloc_2paths(&temp_dirname,&temp_filename);
    if ( error_code != MFS_NO_ERROR )
    {
        return( error_code );
    }

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        MFS_free_path(temp_dirname);
        MFS_free_path(temp_filename);
        return error_code;
    }

    _mem_zero(transfer_ptr, sizeof (MFS_SEARCH_DATA));
    transfer_ptr->DRIVE_PTR = drive_ptr;

    MFS_Parse_pathname(temp_dirname, temp_filename, pathname);

    current_cluster = drive_ptr->CUR_DIR_CLUSTER;
    current_cluster = MFS_Find_directory(drive_ptr, temp_dirname, current_cluster);

    if ( current_cluster == CLUSTER_INVALID )
    {
        error_code = MFS_PATH_NOT_FOUND;
    }
    else
    {
        /*
        ** The internal search is only initialised if the directory exists.
        */
        internal_search_ptr = &transfer_ptr->INTERNAL_SEARCH_DATA;
        internal_search_ptr->CURRENT_CLUSTER = current_cluster;
        internal_search_ptr->PREV_CLUSTER = CLUSTER_INVALID;  
        internal_search_ptr->DIR_ENTRY_INDEX = 0;

        MFS_Expand_wildcard(temp_filename, internal_search_ptr->FILENAME);   
        internal_search_ptr->FULLNAME = temp_filename;

        i = _strnlen(pathname, PATHNAME_SIZE + FILENAME_SIZE + 1);
        c = pathname[--i];
        while ( (c != '\\') && (c != '/') && (c != ':') && i )
        {
            i--;         
            c = pathname[i];
        }  
        if ( i || c == '\\' || c == '/' )
        {
            i++;
        }

        internal_search_ptr->SRC_PTR = pathname + i;
        internal_search_ptr->ATTRIBUTE = attribute;
        error_code = MFS_Find_next_slave(drive_ptr, transfer_ptr);
    }  

    MFS_free_path(temp_dirname);
    MFS_free_path(temp_filename);
    MFS_unlock(drive_ptr,FALSE);

    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Find_next_file
* Returned Value   : error_code
* Comments  :   Find the next file that matches the input criteria. Must
*    follow a Find_first_file and the search data block from the search
*    must be supplied.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Find_next_file
    (
    MQX_FILE_PTR            mfs_fd_ptr,     /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    MFS_SEARCH_DATA_PTR     transfer_ptr    /* [IN/OUT] address of search data block indicating the current criteria and the results of 
                                            ** the last search results of this search are placed in this data block */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    _mfs_error              error_code;

    error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr );

    if ( error_code == MFS_NO_ERROR )
    {
        error_code = MFS_Find_next_slave(drive_ptr, transfer_ptr);
        MFS_unlock(drive_ptr,FALSE);
    }
    return(error_code);
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Set_volume
* Returned Value   : error_code
* Comments  :   Sets the drive volume. Assumes the drive is NOT locked.
*
*END*---------------------------------------------------------------------*/

#if !MFSCFG_READ_ONLY
_mfs_error MFS_Set_volume
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    char_ptr                volume_name /*[IN] name to use for the volune */
    )
{
    MFS_DRIVE_STRUCT_PTR       drive_ptr;
    MFS_DIR_ENTRY_PTR          dir_entry_ptr;
    _mfs_error                 error_code;
    uint_32                    vol_cluster, vol_index;
    uint_32                    prev_cluster= CLUSTER_INVALID; 

    if ( volume_name == NULL )
    {
        return( MFS_INVALID_PARAMETER );
    }

    if ( *volume_name == '\0' )
    {
        return( MFS_INVALID_PARAMETER );
    }

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_lock_dos_disk(mfs_fd_ptr, &drive_ptr);

    if ( !error_code )
    {
        vol_cluster = ROOT_CLUSTER(drive_ptr);
        vol_index = 0;
        dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &vol_cluster, &vol_index, &prev_cluster, MFS_ATTR_VOLUME_NAME, &error_code); 

        if ( dir_entry_ptr )
        {
            MFS_Expand_dotfile(volume_name, dir_entry_ptr->NAME);
            *dir_entry_ptr->ATTRIBUTE = MFS_ATTR_VOLUME_NAME;
            drive_ptr->DIR_SECTOR_DIRTY = TRUE;

        }
        else if ( !error_code )
        {
            vol_cluster = ROOT_CLUSTER(drive_ptr);
            vol_index = 0;
            dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &vol_cluster, &vol_index, &prev_cluster, MFS_ATTR_ANY, &error_code); 
            if ( dir_entry_ptr )
            {
                MFS_Expand_dotfile(volume_name, dir_entry_ptr->NAME);
                *dir_entry_ptr->ATTRIBUTE = MFS_ATTR_VOLUME_NAME;
                drive_ptr->DIR_SECTOR_DIRTY = TRUE;
            }
        }
    }

    MFS_unlock(drive_ptr,TRUE);
    return( error_code );
}  

#endif

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Get_volume
* Returned Value   : error_code
* Comments  :   Gets the drive volume. Assumes the drive is NOT locked.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Get_volume
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */
    char_ptr                volume_name /*[OUT] name of the volune */
    )
{
    MFS_DRIVE_STRUCT_PTR       drive_ptr;
    MFS_DIR_ENTRY_PTR          dir_entry_ptr;
    _mfs_error                 error_code;
    uint_32                    vol_cluster, vol_index, i;
    char_ptr                   disk_vol_name;
    uint_32                    prev_cluster= CLUSTER_INVALID; 

    if ( volume_name == NULL )
    {
        return( MFS_INVALID_PARAMETER );
    }

    error_code = MFS_lock_dos_disk(mfs_fd_ptr, &drive_ptr);

    if ( !error_code )
    {
        vol_cluster = ROOT_CLUSTER(drive_ptr);
        vol_index = 0;
        dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &vol_cluster, &vol_index, &prev_cluster, MFS_ATTR_VOLUME_NAME, &error_code); 

        if ( dir_entry_ptr )
        {
            disk_vol_name = dir_entry_ptr->NAME;
            for ( i = 0 ; i < SFILENAME_SIZE - 1; i++ )
            {
                *volume_name++ = *disk_vol_name++;
            }  
        }
        *volume_name = '\0'; 
    }

    MFS_unlock(drive_ptr,FALSE);   
    return( error_code );
}  

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/coff.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: coff.c$
* $Version : 3.5.9.0$
* $Date    : Jan-22-2010$
*
* Comments:
*
*   This file contains the COFF File decoder for the
*   Exec function of the RTCS Communication Library.
*
*END************************************************************************/

#include <rtcs.h>
#include "dhcpsrv.h"
/* The COFF decoder information to pass to RTCS_load() */
uint_32 COFF_start  (pointer ff_data);
uint_32 COFF_decode (uint_32 size, uchar_ptr data);
uint_32 COFF_eod    (void);
void    COFF_exec   (void);

static FF_CALL_STRUCT ff_coff = {
   COFF_start,
   COFF_decode,
   COFF_eod,
   COFF_exec
};

const FF_CALL_STRUCT_PTR FF_COFF = &ff_coff;

#if PSP_ENDIAN == MQX_BIG_ENDIAN

   #define COFF_GET_UINT_16(i) \
      (((uint_16)COFF_config.TMP[i+0] << 8) | \
        (uint_16)COFF_config.TMP[i+1]);       \
      i+=2;

   #define COFF_GET_UINT_32(i) \
      (((uint_32)COFF_config.TMP[i+0] << 24) | \
       ((uint_32)COFF_config.TMP[i+1] << 16) | \
       ((uint_32)COFF_config.TMP[i+2] <<  8) | \
        (uint_32)COFF_config.TMP[i+3]);        \
      i+=4;

#else

   #define COFF_GET_UINT_16(i) \
      (((uint_16)COFF_config.TMP[i+1] << 8) | \
        (uint_16)COFF_config.TMP[i+0]);       \
      i+=2;

   #define COFF_GET_UINT_32(i) \
      (((uint_32)COFF_config.TMP[i+3] << 24) | \
       ((uint_32)COFF_config.TMP[i+2] << 16) | \
       ((uint_32)COFF_config.TMP[i+1] <<  8) | \
        (uint_32)COFF_config.TMP[i+0]);        \
      i+=4;

#endif

#ifndef min
#define min(x,y) ((x) < (y) ? (x) : (y))
#endif

/* Decoder States */
#define COFF_GETTING_HEADER          1
#define COFF_GETTING_OPTIONAL_HEADER 2
#define COFF_GETTING_SECTION_HEADERS 3
#define COFF_LOADING_SECTIONS        4
#define COFF_LOADING_DONE            5


/*
** Sizes of the COFF headers, in bytes
*/
#ifdef PSP_TI32060
#  define COFF_HEADER_SIZE         22
#  define COFF_SECTION_HEADER_SIZE 48
#else
#  define COFF_HEADER_SIZE         20
#  define COFF_SECTION_HEADER_SIZE 40
#endif

/*
** COFF HEADER STRUCT
** this structure defines what the first few bytes of a COFF file look like.
*/
typedef struct coff_header_struct {

   uint_16 C_MAGIC;        /* Magic Number */
   uint_16 C_NSCNS;        /* The Number of sections */
   uint_32 C_TIMDAT;       /* The time and date stamp */
   uint_32 C_SYMPTR;       /* The file pointer to symbol table */
   uint_32 C_NSYMS;        /* The number of symbol table entries */
   uint_16 C_OPTHDR;       /* The optional header size */
   uint_16 C_FLAGS;        /* Flags */

} COFF_HEADER_STRUCT, _PTR_ COFF_HEADER_STRUCT_PTR;

/*
** COFF OPTIONAL HEADER STRUCT
** this structure defines what the COFF optional information contains
** this is usually System V a.out header
*/
typedef struct coff_optional_header_struct {

   uint_16 CO_MAGIC;       /* Magic Number */
   uint_16 CO_VSTAMP;      /* Version Stamp */
   uint_32 CO_TSIZE;       /* Text size in bytes */
   uint_32 CO_DSIZE;       /* Initialized data size in bytes */
   uint_32 CO_BSIZE;       /* Uninitialized data size in bytes */
   uint_32 CO_ENTRY;       /* Entry point */
   uint_32 CO_TEXT_START;  /* Base of text used for this file */
   uint_32 CO_DATA_START;  /* Base of data used for this file */

} COFF_OPTIONAL_HEADER_STRUCT, _PTR_ COFF_OPTIONAL_HEADER_STRUCT_PTR;

/*
** COFF SECTION HEADER STRUCT
** This structure defines what a COFF section header looks like
*/
typedef struct coff_section_header_struct {

   uchar   CS_NAME[8];     /* Section name */
   uint_32 CS_PADDR;       /* Physical address */
   uint_32 CS_VADDR;       /* Virtual address */
   uint_32 CS_SIZE;        /* Section size */
   uint_32 CS_SCNPTR;      /* File pointer to raw data for section */
   uint_32 CS_RELPTR;      /* File opinter to relocation entries */
   uint_32 CS_LNNOPTR;     /* File pointer to line number entries */
   uint_16 CS_NRELOC;      /* Number of relocation entries */
   uint_16 CS_NLNNO;       /* Number of line number entries */
   uint_32 CS_FLAGS;       /* Type and content flags */

} COFF_SECTION_HEADER_STRUCT, _PTR_ COFF_SECTION_HEADER_STRUCT_PTR;


/* COFF decoder state information */
static struct {
   uint_32                         STATE;   /* the current state */
   COFF_HEADER_STRUCT              FILE_HEADER;
   COFF_OPTIONAL_HEADER_STRUCT     OPTIONAL_FILE_HEADER;
   COFF_SECTION_HEADER_STRUCT_PTR  SECTION_HEADERS;
   uint_32                         COUNT;
   uint_32                         TOTAL_COUNT;
   uint_32                         SECTION_COUNT;
   uchar_ptr                       LOAD_ADDR;
   uchar                           TMP[128];
} COFF_config;


#define COFF_NEXT_SECTION(h)  \
   (h) = &COFF_config.SECTION_HEADERS[COFF_config.SECTION_COUNT];          \
   for (;;) {                                                              \
      if (COFF_config.SECTION_COUNT == COFF_config.FILE_HEADER.C_NSCNS) {  \
         COFF_config.STATE = COFF_LOADING_DONE;                            \
         return RTCS_OK;                                                   \
      } /* Endif */                                                        \
      if (((h)->CS_VADDR  == 0)                                            \
       || ((h)->CS_SIZE   == 0)                                            \
       || ((h)->CS_SCNPTR == 0)) {                                         \
         COFF_config.SECTION_COUNT++;                                      \
         (h)++;                                                            \
         continue;                                                         \
      } /* Endif */                                                        \
      break;                                                               \
   } /* Endfor */                                                          \
   COFF_config.LOAD_ADDR = (uchar_ptr)(h)->CS_VADDR;



/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : COFF_start
* Returned Value   : error code
* Comments  :  Routine to begin decoding a HEX file.
*
*END*-----------------------------------------------------------------*/

uint_32 COFF_start
   (
      pointer  data
   )
{ /* Body */

   COFF_config.STATE        = COFF_GETTING_HEADER;
   COFF_config.COUNT        = 0;
   COFF_config.TOTAL_COUNT  = 0;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : COFF_decode
* Returned Value   : error code
* Comments  :  Routine to decode Coff Files
*
*END*-----------------------------------------------------------------*/

uint_32 COFF_decode
   (
      /* [IN] number of bytes to decode */
      uint_32 size,

      /* [IN] bytes to decode */
      uchar_ptr data
   )
{ /* Body */
   COFF_SECTION_HEADER_STRUCT_PTR h_ptr;
   uchar_ptr t_ptr;
   uint_32   i;
   uint_32   amount;
   uchar     c;

   while (size--) {
      c = ntohc(data);
      data++;
      COFF_config.TOTAL_COUNT++;

      switch (COFF_config.STATE) {

         case COFF_GETTING_HEADER:
            COFF_config.TMP[COFF_config.COUNT++] = c;
            if (COFF_config.COUNT == COFF_HEADER_SIZE) {
               i = 0;
               COFF_config.FILE_HEADER.C_MAGIC  = COFF_GET_UINT_16(i);
               COFF_config.FILE_HEADER.C_NSCNS  = COFF_GET_UINT_16(i);
               COFF_config.FILE_HEADER.C_TIMDAT = COFF_GET_UINT_32(i);
               COFF_config.FILE_HEADER.C_SYMPTR = COFF_GET_UINT_32(i);
               COFF_config.FILE_HEADER.C_NSYMS  = COFF_GET_UINT_32(i);
               COFF_config.FILE_HEADER.C_OPTHDR = COFF_GET_UINT_16(i);
               COFF_config.FILE_HEADER.C_FLAGS  = COFF_GET_UINT_16(i);

               COFF_config.COUNT = 0;
               COFF_config.STATE = COFF_GETTING_OPTIONAL_HEADER;

               COFF_config.SECTION_HEADERS = RTCS_mem_alloc(
                  COFF_config.FILE_HEADER.C_NSCNS *
                  sizeof(COFF_SECTION_HEADER_STRUCT));
               if (COFF_config.SECTION_HEADERS == NULL) {
                  COFF_eod();
                  return RTCSERR_COFF_ALLOC_FAILED;
               } /* Endif */

               /* Cannot verify magic, as it is different on very many architectures */
               if (COFF_config.FILE_HEADER.C_MAGIC == 0) {
                  COFF_eod();
                  return RTCSERR_COFF_BAD_MAGIC;
               } /* Endif */
            } /* Endif */
            break;

         case COFF_GETTING_OPTIONAL_HEADER:
            COFF_config.TMP[COFF_config.COUNT++] = c;
            if (COFF_config.COUNT == COFF_config.FILE_HEADER.C_OPTHDR) {
               i = 0;
               COFF_config.OPTIONAL_FILE_HEADER.CO_MAGIC      = COFF_GET_UINT_16(i);
               COFF_config.OPTIONAL_FILE_HEADER.CO_VSTAMP     = COFF_GET_UINT_16(i);
               COFF_config.OPTIONAL_FILE_HEADER.CO_TSIZE      = COFF_GET_UINT_32(i);
               COFF_config.OPTIONAL_FILE_HEADER.CO_DSIZE      = COFF_GET_UINT_32(i);
               COFF_config.OPTIONAL_FILE_HEADER.CO_BSIZE      = COFF_GET_UINT_32(i);
               COFF_config.OPTIONAL_FILE_HEADER.CO_ENTRY      = COFF_GET_UINT_32(i);
               COFF_config.OPTIONAL_FILE_HEADER.CO_TEXT_START = COFF_GET_UINT_32(i);
               COFF_config.OPTIONAL_FILE_HEADER.CO_DATA_START = COFF_GET_UINT_32(i);

               COFF_config.COUNT = 0;
               COFF_config.STATE = COFF_GETTING_SECTION_HEADERS;
               COFF_config.SECTION_COUNT = 0;

               if (COFF_config.OPTIONAL_FILE_HEADER.CO_MAGIC == 0) {
                  COFF_eod();
                  return RTCSERR_COFF_BAD_MAGIC;
               } /* Endif */
            } /* Endif */
            break;

         case COFF_GETTING_SECTION_HEADERS:

            /* Program headers should follow the COFF headers */
            COFF_config.TMP[COFF_config.COUNT++] = c;
            if (COFF_config.COUNT == COFF_SECTION_HEADER_SIZE) {
               h_ptr = &COFF_config.SECTION_HEADERS[COFF_config.SECTION_COUNT++];
               for (i = 0; i < 8; i++) {
                  h_ptr->CS_NAME[i] = COFF_config.TMP[i];
               } /* Endfor */
               h_ptr->CS_PADDR   = COFF_GET_UINT_32(i);
               h_ptr->CS_VADDR   = COFF_GET_UINT_32(i);
               h_ptr->CS_SIZE    = COFF_GET_UINT_32(i);
               h_ptr->CS_SCNPTR  = COFF_GET_UINT_32(i);
               h_ptr->CS_RELPTR  = COFF_GET_UINT_32(i);
               h_ptr->CS_LNNOPTR = COFF_GET_UINT_32(i);
               h_ptr->CS_NRELOC  = COFF_GET_UINT_16(i);
               h_ptr->CS_NLNNO   = COFF_GET_UINT_16(i);
               h_ptr->CS_FLAGS   = COFF_GET_UINT_32(i);
               COFF_config.COUNT = 0;
               if (COFF_config.SECTION_COUNT == COFF_config.FILE_HEADER.C_NSCNS) {
                  COFF_config.STATE = COFF_LOADING_SECTIONS;
                  COFF_config.SECTION_COUNT = 0;
                  COFF_NEXT_SECTION(h_ptr);
               } /* Endif */
            } /* Endif */
         break;

         case COFF_LOADING_SECTIONS:
            /* Loadable sections should follow the Program headers */
            h_ptr = &COFF_config.SECTION_HEADERS[COFF_config.SECTION_COUNT];
            if (COFF_config.TOTAL_COUNT > h_ptr->CS_SCNPTR) {
               /* We have reached the correct location in the file */
               t_ptr = COFF_config.LOAD_ADDR;
               *t_ptr++ = c;
               amount = min(size, (h_ptr->CS_SIZE - COFF_config.COUNT - 1));
               COFF_config.COUNT += amount + 1;
               COFF_config.TOTAL_COUNT += amount;
               size -= amount;
               while (amount--) {
                  *t_ptr++ = ntohc(data);
                  data++;
               } /* Endwhile */
               COFF_config.LOAD_ADDR = t_ptr;
               if (COFF_config.COUNT >= h_ptr->CS_SIZE) {
                  COFF_config.COUNT = 0;
                  COFF_config.SECTION_COUNT++;
                  COFF_NEXT_SECTION(h_ptr);
               } /* Endif */
            } /* Endif */
         break;

         case COFF_LOADING_DONE:
            /* Nothing to do, toss the data */
            return RTCS_OK;

         default:
            /* Should never get here. */
            COFF_eod();
            return RTCSERR_COFF_ERROR;
      } /* Endswitch */

   } /* Endwhile */

   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : COFF_eod
* Returned Value   : error code
* Comments  :  Routine to end decoding an COFF file.
*
*END*-----------------------------------------------------------------*/

uint_32 COFF_eod
   (
      void
   )
{ /* Body */

   if (COFF_config.SECTION_HEADERS)  {
      _mem_free(COFF_config.SECTION_HEADERS);
   } /* Endif */
   COFF_config.SECTION_HEADERS = NULL;

   switch (COFF_config.STATE) {
      case COFF_LOADING_DONE:
         return RTCS_OK;
      default:
         return RTCSERR_COFF_TRUNCATED;
   } /* Endswitch */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : COFF_exec
* Returned Value   : none
* Comments  :  Routine to execute a decoded COFF file.
*
*END*-----------------------------------------------------------------*/

void COFF_exec
   (
      void
   )
{ /* Body */

   (*(void(_CODE_PTR_)(void))(COFF_config.OPTIONAL_FILE_HEADER.CO_ENTRY))();

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_write.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_write.c$
* $Version : 3.8.7.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   Contains the function _io_write.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Writes data to selected stream.
 * 
 * \param[in] file_ptr The stream to perform the operation on.
 * \param[in] data_ptr The data location to write from.
 * \param[in] num      The number of bytes to write.
 * 
 * \return The number of characters written.
 * \return IO_ERROR  
 */ 
_mqx_int _io_write
   ( 
      MQX_FILE_PTR file_ptr,
      pointer      data_ptr,
      _mqx_int     num      
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   dev_ptr;

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(IO_ERROR);
   } /* Endif */
#endif

   dev_ptr = file_ptr->DEV_PTR;
#if MQX_CHECK_ERRORS
   if (dev_ptr->IO_WRITE == NULL) {
      file_ptr->ERROR = MQX_IO_OPERATION_NOT_AVAILABLE;
      return(IO_ERROR);
   } /* Endif */
#endif

   return((*dev_ptr->IO_WRITE)(file_ptr, (char *)data_ptr, num));

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/pcb/io_pcb2.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_pcb2.c$
* $Version : 3.8.7.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This file contains the functions for use with IO PCB device drivers.
*
*END************************************************************************/

#include "mqx_inc.h"
#if MQX_USE_IPC
#include "partition.h"
#include "fio.h"
#include "io.h"
#include "io_prv.h"
#include "io_pcb.h"
#include "iopcbprv.h"


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_destroy_pool
* Returned Value   : MQX_OK or an error code
* Comments         :
*   Destroys a pool of pcbs.
*END*-------------------------------------------------------------------------*/

_mqx_uint _io_pcb_destroy_pool
   (
      /* The PCB pool to destroy */
      _io_pcb_pool_id pool
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   IO_PCB_POOL_STRUCT_PTR pool_ptr = IO_PCB_GET_POOL_PTR(pool);
   _mqx_uint              result;
   
#if MQX_CHECK_VALIDITY
   if (pool_ptr->VALID != IO_PCB_VALID) {
      return(IO_PCB_POOL_INVALID);
   }/* Endif */
#endif

   pool_ptr->VALID = 0;
  
   result = _partition_destroy(pool_ptr->PARTITION);
   if (result != MQX_OK ) {
      return(result);
   }/* Endif */

  _lwsem_destroy(&pool_ptr->PCB_LWSEM);
   _GET_KERNEL_DATA(kernel_data);
  _queue_unlink((QUEUE_STRUCT_PTR)(&kernel_data->IO_PCB_POOLS), 
     &pool_ptr->QUEUE);
  return(_mem_free(pool_ptr));

} /* Endbody */


/*FUNCTION*---------------------------------------------------------------------
*
* Function Name    : _io_pcb_test
* Returned Value   : MQX_OK or an error code
* Comments         :
*   test all pcb pools
*END*-------------------------------------------------------------------------*/

_mqx_uint _io_pcb_test
   (
      /* The PCB pool in error */
      pointer _PTR_ pool_in_error,

      /* The PCB in error */
      pointer _PTR_ pcb_in_error
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   IO_PCB_POOL_STRUCT_PTR pool_ptr;
   _mqx_uint              i;
   _mqx_uint              result;
   
   _GET_KERNEL_DATA(kernel_data);

   *pool_in_error = NULL;
   *pcb_in_error = NULL;
   _INT_DISABLE();
   result = _queue_test((QUEUE_STRUCT_PTR)(&kernel_data->IO_PCB_POOLS), 
      pool_in_error);
   if (result != MQX_OK) {
      _int_enable();
      return(result);
   }/* Endif */
   pool_ptr = (pointer)kernel_data->IO_PCB_POOLS.NEXT;
   for (i = 0; i < 
      _queue_get_size((QUEUE_STRUCT_PTR)(&kernel_data->IO_PCB_POOLS)); i++) 
   {
      if (pool_ptr->VALID != IO_PCB_VALID) {
         /* START CR 2062 */
         _int_enable();
         /* END CR 2062 */
         *pool_in_error = (pointer)pool_ptr;
         return(IO_PCB_POOL_INVALID);
      }/* Endif */
      pool_ptr = (pointer)pool_ptr->QUEUE.NEXT;
   } /* Endfor */

   /* START CR 2062 */
   _int_enable();
   /* END CR 2062 */

   return(MQX_OK);

} /* Endbody */
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/eninit.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: eninit.c$
* $Version : 3.8.12.0$
* $Date    : Sep-11-2012$
*
* Comments:
*
*   This file contains the MCF52xx Coldfire processor
*   Ethernet initialization
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "bsp_prv.h"




/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_initialize_ex
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Initializes the chip (extended version).
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_initialize_ex
   (
         /* [IN] optional parameters */
      const ENET_PARAM_STRUCT *   param_ptr,
         /* [IN] the local Ethernet address */
      _enet_address           address,
         /* [OUT] the Ethernet state structure */
      _enet_handle _PTR_      handle
   )
{
   ENET_CONTEXT_STRUCT_PTR enet_ptr = NULL;//, other_enet_ptr;
   uint_32                 result;
   boolean                 vlan;
   
   if (param_ptr == NULL)
      return ENETERR_INVALID_DEVICE;

   if (param_ptr->NUM_RX_BUFFERS < param_ptr->NUM_RX_ENTRIES) 
      return ENETERR_INVALID_INIT_PARAM;
   
   enet_ptr = _mqx_get_io_component_handle(IO_ENET_COMPONENT);
   
   while (enet_ptr) {
      if (enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER == param_ptr->ENET_IF->MAC_NUMBER)
         break;
      
      enet_ptr = enet_ptr->NEXT;
   }
   
   if (enet_ptr) {
      *handle = enet_ptr;
   
      return ENETERR_INITIALIZED_DEVICE;
   }
   else
      *handle = NULL;

   // Allocate the Enet context structure
   enet_ptr = _mem_alloc_system_zero(sizeof(ENET_CONTEXT_STRUCT));
   if (NULL==enet_ptr)
      return ENETERR_ALLOC_CFG;
      
   _mem_set_type((pointer)enet_ptr, MEM_TYPE_IO_ENET_CONTEXT_STRUCT);

   // Initialize the Enet context structure
   eaddrcpy(enet_ptr->ADDRESS, address);
   enet_ptr->PARAM_PTR = param_ptr;
   vlan = (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_VLAN) == ENET_OPTION_VLAN;
   enet_ptr->MaxTxFrameSize = ENET_max_framesize(enet_ptr->PARAM_PTR->TX_BUFFER_SIZE,0,vlan);
   enet_ptr->MaxRxFrameSize = ENET_max_framesize(enet_ptr->PARAM_PTR->RX_BUFFER_SIZE,enet_ptr->PARAM_PTR->NUM_LARGE_BUFFERS,vlan);
   
   _lwsem_create(&enet_ptr->CONTEXT_LOCK, 1);
    
   // Initialize the MAC
   result = (*param_ptr->ENET_IF->MAC_IF->INIT)(enet_ptr);
   
    if (ENET_OK == result)
    {
        // Link the driver into the kernel component list
        _mqx_link_io_component_handle(IO_ENET_COMPONENT,enet_ptr, (pointer *)&enet_ptr->NEXT);

        *handle = enet_ptr;
    } 
    else
    {
        _lwsem_destroy(&enet_ptr->CONTEXT_LOCK);
        _mem_free(enet_ptr);
        *handle = NULL;
    }
   
    return result;
}   

 
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_initialize
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Initializes the chip.
*
*END*-----------------------------------------------------------------*/

uint_32 ENET_initialize
   (
         /* [IN] the FEC to initialize */
      uint_32              device,
         /* [IN] the local Ethernet address */
      _enet_address        address,
         /* [IN] optional flags, zero = default, 
            this parameter IS NOT USED! (ignored) */
      uint_32              flags,
         /* [OUT] the Ethernet state structure */
      _enet_handle _PTR_   handle
   )
{ 
   if (device <BSP_ENET_DEVICE_COUNT) {
      return ENET_initialize_ex(&ENET_default_params[device],address,handle);
   } else {
      return ENETERR_INVALID_DEVICE;
   }
}

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/APP/aes.c<|end_filename|>
#include "app_cfg.h"

extern const unsigned char AESKey[32];

#define BPOLY     0x1b //!< Lower 8 bits of (x^8+x^4+x^3+x+1), ie. (x^4+x^3+x+1).
#define BLOCKSIZE 16   //!< Block size in number of bytes.



#if KEY_COUNT == 1
  #define KEYBITS 128 //!< Use AES128.
#elif KEY_COUNT == 2
  #define KEYBITS 192 //!< Use AES196.
#elif KEY_COUNT == 3
  #define KEYBITS 256 //!< Use AES256.
#else
  #error Use 1, 2 or 3 keys!
#endif

#if KEYBITS == 128
  #define ROUNDS 10 //!< Number of rounds.
  #define KEYLENGTH 16 //!< Key length in number of bytes.
#elif KEYBITS == 192
  #define ROUNDS 12 //!< Number of rounds.
  #define KEYLENGTH 24 //!< // Key length in number of bytes.
#elif KEYBITS == 256
  #define ROUNDS 14 //!< Number of rounds.
  #define KEYLENGTH 32 //!< Key length in number of bytes.
#else
  #error Key must be 128, 192 or 256 bits!
#endif

#define EXPANDED_KEY_SIZE (BLOCKSIZE * (ROUNDS+1)) //!< 176, 208 or 240 bytes.



INT8U block1[ 256 ]; //!< Workspace 1.
INT8U block2[ 256 ]; //!< Worksapce 2.
INT8U sBox[256];


INT8U * powTbl; //!< Final location of exponentiation lookup table.
INT8U * logTbl; //!< Final location of logarithm lookup table.
INT8U * sBoxInv; //!< Final location of inverse s-box.
INT8U * expandedKey; //!< Final location of expanded key.



void CalcPowLog( INT8U * powTbl, INT8U * logTbl )
{
  INT8U i = 0;
  INT8U t = 1;

  do
  {
    // Use 0x03 as root for exponentiation and logarithms.
    powTbl[i] = t;
    logTbl[t] = i;
    i++;

    // Muliply t by 3 in GF(2^8).
    t ^= (t << 1) ^ (t & 0x80 ? BPOLY : 0);
  } while ( t != 1 ); // Cyclic properties ensure that i < 255.

  powTbl[255] = powTbl[0]; // 255 = '-0', 254 = -1, etc.
}



void CalcSBox( INT8U * sBox )
{
  INT8U i, rot;
  INT8U temp;
  INT8U result;

  // Fill all entries of sBox[].
  i = 0;
  do
  {
    // Inverse in GF(2^8).
    if ( i > 0 )
    {
      temp = powTbl[ 255 - logTbl[i] ];
    }
    else
    {
      temp = 0;
    }

    // Affine transformation in GF(2).
    result = temp ^ 0x63; // Start with adding a vector in GF(2).
    for ( rot = 0; rot < 4; rot++ )
    {
      // Rotate left.
      temp = (temp<<1) | (temp>>7);

      // Add rotated byte in GF(2).
      result ^= temp;
    }

    // Put result in table.
    sBox[i] = result;
  } while ( ++i != 0 );
}



void CalcSBoxInv( INT8U * sBox, INT8U * sBoxInv )
{
  INT8U i = 0;
  INT8U j = 0;

  // Iterate through all elements in sBoxInv using  i.
  do
  {
    // Search through sBox using j.
    do
    {
      // Check if current j is the inverse of current i.
      if ( sBox[ j ] == i )
      {
        // If so, set sBoxInc and indicate search finished.
        sBoxInv[ i ] = j;
        j = 255;
      }
    } while ( ++j != 0 );
  } while ( ++i != 0 );
}



void CycleLeft( INT8U * row )
{
  // Cycle 4 bytes in an array left once.
  INT8U temp = row[0];
  row[0] = row[1];
  row[1] = row[2];
  row[2] = row[3];
  row[3] = temp;
}



void InvMixColumn( INT8U * column )
{
  INT8U r0, r1, r2, r3;

  r0 = column[1] ^ column[2] ^ column[3];
  r1 = column[0] ^ column[2] ^ column[3];
  r2 = column[0] ^ column[1] ^ column[3];
  r3 = column[0] ^ column[1] ^ column[2];

  column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);
  column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);
  column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);
  column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);

  r0 ^= column[0] ^ column[1];
  r1 ^= column[1] ^ column[2];
  r2 ^= column[2] ^ column[3];
  r3 ^= column[0] ^ column[3];

  column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);
  column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);
  column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);
  column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);

  r0 ^= column[0] ^ column[2];
  r1 ^= column[1] ^ column[3];
  r2 ^= column[0] ^ column[2];
  r3 ^= column[1] ^ column[3];

  column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);
  column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);
  column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);
  column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);

  column[0] ^= column[1] ^ column[2] ^ column[3];
  r0 ^= column[0];
  r1 ^= column[0];
  r2 ^= column[0];
  r3 ^= column[0];

  column[0] = r0;
  column[1] = r1;
  column[2] = r2;
  column[3] = r3;
}



void SubBytes( INT8U * bytes, INT8U count )
{
  do
  {
    *bytes = sBox[ *bytes ]; // Substitute every byte in state.
    bytes++;
  } while ( --count );
}



void InvSubBytesAndXOR( INT8U * bytes, INT8U * key, INT8U count )
{
  do
  {
//    *bytes = sBoxInv[ *bytes ] ^ *key; // Inverse substitute every byte in state and add key.
    *bytes = block2[ *bytes ] ^ *key; // Use block2 directly. Increases speed.
    bytes++;
    key++;
  } while ( --count );
}



void InvShiftRows( INT8U * state )
{
  INT8U temp;

  // Note: State is arranged column by column.

  // Cycle second row right one time.
  temp = state[ 1 + 3*4 ];
  state[ 1 + 3*4 ] = state[ 1 + 2*4 ];
  state[ 1 + 2*4 ] = state[ 1 + 1*4 ];
  state[ 1 + 1*4 ] = state[ 1 + 0*4 ];
  state[ 1 + 0*4 ] = temp;

  // Cycle third row right two times.
  temp = state[ 2 + 0*4 ];
  state[ 2 + 0*4 ] = state[ 2 + 2*4 ];
  state[ 2 + 2*4 ] = temp;
  temp = state[ 2 + 1*4 ];
  state[ 2 + 1*4 ] = state[ 2 + 3*4 ];
  state[ 2 + 3*4 ] = temp;

  // Cycle fourth row right three times, ie. left once.
  temp = state[ 3 + 0*4 ];
  state[ 3 + 0*4 ] = state[ 3 + 1*4 ];
  state[ 3 + 1*4 ] = state[ 3 + 2*4 ];
  state[ 3 + 2*4 ] = state[ 3 + 3*4 ];
  state[ 3 + 3*4 ] = temp;
}



void InvMixColumns( INT8U * state )
{
  InvMixColumn( state + 0*4 );
  InvMixColumn( state + 1*4 );
  InvMixColumn( state + 2*4 );
  InvMixColumn( state + 3*4 );
}



void XORBytes( INT8U * bytes1, INT8U * bytes2, INT8U count )
{
  do
  {
    *bytes1 ^= *bytes2; // Add in GF(2), ie. XOR.
    bytes1++;
    bytes2++;
  } while ( --count );
}



void CopyBytes( INT8U * to, INT8U * from, INT8U count )
{
  do
  {
    *to = *from;
    to++;
    from++;
  } while ( --count );
}



void KeyExpansion( INT8U * expandedKey )
{
  INT8U temp[4];
  INT8U i;
  INT8U Rcon[4] = { 0x01, 0x00, 0x00, 0x00}; // Round constant.

  unsigned char const * key = AESKey;

  // Copy key to start of expanded key.
  i = KEYLENGTH;
  do
  {
    *expandedKey = *key;
    expandedKey++;
    key++;
  } while ( --i );

  // Prepare last 4 bytes of key in temp.
  expandedKey -= 4;
  temp[0] = *(expandedKey++);
  temp[1] = *(expandedKey++);
  temp[2] = *(expandedKey++);
  temp[3] = *(expandedKey++);

  // Expand key.
  i = KEYLENGTH;
  while ( i < BLOCKSIZE*(ROUNDS+1) )
  {
    // Are we at the start of a multiple of the key size?
    if ( (i % KEYLENGTH) == 0 )
    {
      CycleLeft( temp ); // Cycle left once.
      SubBytes( temp, 4 ); // Substitute each byte.
      XORBytes( temp, Rcon, 4 ); // Add constant in GF(2).
      *Rcon = (*Rcon << 1) ^ (*Rcon & 0x80 ? BPOLY : 0);
    }

    // Keysize larger than 24 bytes, ie. larger that 192 bits?
#if KEYLENGTH > 24
    // Are we right past a block size?
    else if ( (i % KEYLENGTH) == BLOCKSIZE )
    {
      SubBytes( temp, 4 ); // Substitute each byte.
    }
#endif

    // Add bytes in GF(2) one KEYLENGTH away.
    XORBytes( temp, expandedKey - KEYLENGTH, 4 );

    // Copy result to current 4 bytes.
    *(expandedKey++) = temp[ 0 ];
    *(expandedKey++) = temp[ 1 ];
    *(expandedKey++) = temp[ 2 ];
    *(expandedKey++) = temp[ 3 ];

    i += 4; // Next 4 bytes.
  }
}



void InvCipher( INT8U * block, INT8U * expandedKey )
{
  INT8U round = ROUNDS-1;
  expandedKey += BLOCKSIZE * ROUNDS;

  XORBytes( block, expandedKey, 16 );
  expandedKey -= BLOCKSIZE;

  do
  {
    InvShiftRows( block );
    InvSubBytesAndXOR( block, expandedKey, 16 );
    expandedKey -= BLOCKSIZE;
    InvMixColumns( block );
  } while ( --round );

  InvShiftRows( block );
  InvSubBytesAndXOR( block, expandedKey, 16 );
}



void aesInit(void)
{
  powTbl = block1;
  logTbl = block2;
  CalcPowLog( powTbl, logTbl );

//  sBox = tempbuf;
  CalcSBox( sBox );

  expandedKey = block1;
  KeyExpansion( expandedKey );

  sBoxInv = block2; // Must be block2.
  CalcSBoxInv( sBox, sBoxInv );
}



void aesDecrypt( unsigned char * buffer, unsigned char * chainBlock )
{
  INT8U temp[ BLOCKSIZE ];

  CopyBytes( temp, buffer, BLOCKSIZE );
  InvCipher( buffer, expandedKey );
  XORBytes( buffer, chainBlock, BLOCKSIZE );
  CopyBytes( chainBlock, temp, BLOCKSIZE );
}



<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fgetc.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fgetc.c$
* $Version : 3.8.6.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the functions for reading a character.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief This function returns the next character as an unsigned char (converted 
 * to an int) or IO_EOF if end of file or error occurs.
 *  
 * \param[in] file_ptr The stream to read the character from.
 * 
 * \return Converted character.
 * \return IO_EOF  
 */ 
_mqx_int _io_fgetc
   (
      MQX_FILE_PTR file_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR   dev_ptr;
   char                   tmp;
   _mqx_int               ungot;

#if MQX_CHECK_ERRORS
   if (file_ptr == NULL) {
      return(IO_EOF);
   } /* Endif */
#endif

   if ( file_ptr->HAVE_UNGOT_CHARACTER ) {
      ungot = file_ptr->UNGOT_CHARACTER;
      file_ptr->HAVE_UNGOT_CHARACTER = FALSE;
      return ungot;
   } /* Endif */

   dev_ptr = file_ptr->DEV_PTR;
#if MQX_CHECK_ERRORS
   if (dev_ptr->IO_READ == NULL) {
      file_ptr->ERROR = MQX_IO_OPERATION_NOT_AVAILABLE;
      return(IO_EOF);
   } /* Endif */
#endif

   if ((*dev_ptr->IO_READ)(file_ptr, &tmp, 1) == 1) {
      return (_mqx_int)(uchar)tmp;
   } else {
      return(IO_EOF);
   } /* Endif */

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/EWM_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type EWM
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(EWM_PDD_H_)
#define EWM_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error EWM PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* EWM */ && \
      !defined(MCU_MK10D5) /* EWM */ && \
      !defined(MCU_MK10D7) /* EWM */ && \
      !defined(MCU_MK10F12) /* EWM */ && \
      !defined(MCU_MK10DZ10) /* EWM */ && \
      !defined(MCU_MK11D5) /* EWM */ && \
      !defined(MCU_MK11D5WS) /* EWM */ && \
      !defined(MCU_MK12D5) /* EWM */ && \
      !defined(MCU_MK20D10) /* EWM */ && \
      !defined(MCU_MK20D5) /* EWM */ && \
      !defined(MCU_MK20D7) /* EWM */ && \
      !defined(MCU_MK20F12) /* EWM */ && \
      !defined(MCU_MK20DZ10) /* EWM */ && \
      !defined(MCU_MK21D5) /* EWM */ && \
      !defined(MCU_MK21D5WS) /* EWM */ && \
      !defined(MCU_MK22D5) /* EWM */ && \
      !defined(MCU_MK30D10) /* EWM */ && \
      !defined(MCU_MK30D7) /* EWM */ && \
      !defined(MCU_MK30DZ10) /* EWM */ && \
      !defined(MCU_MK40D10) /* EWM */ && \
      !defined(MCU_MK40D7) /* EWM */ && \
      !defined(MCU_MK40DZ10) /* EWM */ && \
      !defined(MCU_MK40X256VMD100) /* EWM */ && \
      !defined(MCU_MK50D10) /* EWM */ && \
      !defined(MCU_MK50D7) /* EWM */ && \
      !defined(MCU_MK50DZ10) /* EWM */ && \
      !defined(MCU_MK51D10) /* EWM */ && \
      !defined(MCU_MK51D7) /* EWM */ && \
      !defined(MCU_MK51DZ10) /* EWM */ && \
      !defined(MCU_MK52D10) /* EWM */ && \
      !defined(MCU_MK52DZ10) /* EWM */ && \
      !defined(MCU_MK53D10) /* EWM */ && \
      !defined(MCU_MK53DZ10) /* EWM */ && \
      !defined(MCU_MK60D10) /* EWM */ && \
      !defined(MCU_MK60F12) /* EWM */ && \
      !defined(MCU_MK60F15) /* EWM */ && \
      !defined(MCU_MK60DZ10) /* EWM */ && \
      !defined(MCU_MK60N512VMD100) /* EWM */ && \
      !defined(MCU_MK61F12) /* EWM */ && \
      !defined(MCU_MK61F15) /* EWM */ && \
      !defined(MCU_MK61F12WS) /* EWM */ && \
      !defined(MCU_MK61F15WS) /* EWM */ && \
      !defined(MCU_MK70F12) /* EWM */ && \
      !defined(MCU_MK70F15) /* EWM */ && \
      !defined(MCU_MK70F12WS) /* EWM */ && \
      !defined(MCU_MK70F15WS) /* EWM */ && \
      !defined(MCU_PCK20L4) /* EWM */
  // Unsupported MCU is active
  #error EWM PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* Service constants */
#define EWM_PDD_KEY_1 0xB4U                      /**< First key */
#define EWM_PDD_KEY_2 0x2CU                      /**< Second key */


/* ----------------------------------------------------------------------------
   -- WriteControlReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the control register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the control register. This parameter is a 8-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: EWM_CTRL.
 * @par Example:
 *      @code
 *      EWM_PDD_WriteControlReg(deviceID, 1);
 *      @endcode
 */
#define EWM_PDD_WriteControlReg(PeripheralBase, Value) ( \
    EWM_CTRL_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- GetEnableDeviceStatus
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns current state of EWM device.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: EWM_CTRL.
 * @par Example:
 *      @code
 *      uint8_t result = EWM_PDD_GetEnableDeviceStatus(deviceID);
 *      @endcode
 */
#define EWM_PDD_GetEnableDeviceStatus(PeripheralBase) ( \
    (uint8_t)(EWM_CTRL_REG(PeripheralBase) & EWM_CTRL_EWMEN_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- WriteCompareLowReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the compare low register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the compare low register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: EWM_CMPL.
 * @par Example:
 *      @code
 *      EWM_PDD_WriteCompareLowReg(deviceID, 1);
 *      @endcode
 */
#define EWM_PDD_WriteCompareLowReg(PeripheralBase, Value) ( \
    EWM_CMPL_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadCompareLowReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the compare low register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: EWM_CMPL.
 * @par Example:
 *      @code
 *      uint8_t result = EWM_PDD_ReadCompareLowReg(deviceID);
 *      @endcode
 */
#define EWM_PDD_ReadCompareLowReg(PeripheralBase) ( \
    EWM_CMPL_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteCompareHighReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the compare high register.
 * @param PeripheralBase Peripheral base address.
 * @param Value New content of the compare high register. This parameter is a
 *        8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: EWM_CMPH.
 * @par Example:
 *      @code
 *      EWM_PDD_WriteCompareHighReg(deviceID, 1);
 *      @endcode
 */
#define EWM_PDD_WriteCompareHighReg(PeripheralBase, Value) ( \
    EWM_CMPH_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadCompareHighReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the compare high register.
 * @param PeripheralBase Peripheral base address.
 * @return Returns a 8-bit value.
 * @remarks The macro accesses the following registers: EWM_CMPH.
 * @par Example:
 *      @code
 *      uint8_t result = EWM_PDD_ReadCompareHighReg(deviceID);
 *      @endcode
 */
#define EWM_PDD_ReadCompareHighReg(PeripheralBase) ( \
    EWM_CMPH_REG(PeripheralBase) \
  )

/* ----------------------------------------------------------------------------
   -- WriteServiceReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the service register.
 * @param PeripheralBase Peripheral base address.
 * @param Value Service constant. This parameter is a 8-bit value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: EWM_SERV.
 * @par Example:
 *      @code
 *      EWM_PDD_WriteServiceReg(deviceID, 1);
 *      @endcode
 */
#define EWM_PDD_WriteServiceReg(PeripheralBase, Value) ( \
    EWM_SERV_REG(PeripheralBase) = \
     (uint8_t)(Value) \
  )
#endif  /* #if defined(EWM_PDD_H_) */

/* EWM_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/include/host_ch9.h<|end_filename|>
#ifndef __host_ch9_h__
#define __host_ch9_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_ch9.h$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains definitions for standard device requests,
*   i.e. USB specification Chapter 9 requests.
*
*END************************************************************************/
#include "host_common.h"

/*----------------------------------------------------------------**
** Chapter 9.4 Standard Device Requests -- all devices            **
** See Table 9-3 p. 250 of USB 2.0 spec for combinations          **
**   of request type bitfields with requests, WVALUE, WINDEX etc. **
**----------------------------------------------------------------*/
#define  REQ_TYPE_DEVICE    0x00
#define  REQ_TYPE_INTERFACE 0x01
#define  REQ_TYPE_ENDPOINT  0x02

/* Combine one of the 3 above with one of the following 2 */
#define  REQ_TYPE_IN        0x80
#define  REQ_TYPE_OUT       0x00

/* Also for class requests set the following bit */
#define  REQ_TYPE_CLASS     0x20

/* Standard USB requests, see Chapter 9 */
#define  REQ_GET_STATUS          0
#define  REQ_CLEAR_FEATURE       1
#define  REQ_SET_FEATURE         3
#define  REQ_SET_ADDRESS         5
#define  REQ_GET_DESCRIPTOR      6
#define  REQ_SET_DESCRIPTOR      7
#define  REQ_GET_CONFIGURATION   8
#define  REQ_SET_CONFIGURATION   9
#define  REQ_GET_INTERFACE       10
#define  REQ_SET_INTERFACE       11
#define  REQ_SYNCH_FRAME         12

/*
NOTE!!!
DEPRECATED: Use USB_DESC_TYPE_xxx constant from usb_desc.h !
#define  DESCTYPE_DEVICE         0x1
#define  DESCTYPE_CONFIG         0x2
#define  DESCTYPE_STRING         0x3
#define  DESCTYPE_INTERFACE      0x4
#define  DESCTYPE_ENDPOINT       0x5
#define  DESCTYPE_QUALIFIER      0x6
#define  DESCTYPE_OTHER_SPEED    0x7
#define  DESCTYPE_INTF_POWER     0x8
#define  DESCTYPE_OTG            0x9
*/ 

/*******************************************************************
**
** Values specific to CLEAR FEATURE commands (must go to common.h later)
*/

#define  ENDPOINT_HALT        0
#define  DEVICE_REMOTE_WAKEUP 1
#define  TEST_MODE            2

/* States of device instances on the device list */

/* initial device state */
#define  DEVSTATE_INITIAL        0x00
/* device descriptor [0..7]*/
#define  DEVSTATE_DEVDESC8       0x01
/* address set */
#define  DEVSTATE_ADDR_SET       0x02
/* full device descriptor */
#define  DEVSTATE_DEV_DESC       0x03
/* config descriptor [0..7] */
#define  DEVSTATE_GET_CFG9       0x04
/* config set */
#define  DEVSTATE_SET_CFG        0x05
/* full config desc. read in */
#define  DEVSTATE_CFG_READ       0x06
/* application callbacks */
#define  DEVSTATE_APP_CALL       0x07
/* Select interface done */
#define  DEVSTATE_SET_INTF       0x08
#define  DEVSTATE_ENUM_OK        0x09
#define  DEVSTATE_CHK_OTG        0x0A

/* Alphabetical list of Function Prototypes */

#ifdef __cplusplus
extern "C" {
#endif

USB_STATUS _usb_host_register_ch9_callback(_usb_device_instance_handle, tr_callback, pointer);
USB_STATUS _usb_host_ch9_clear_feature(_usb_device_instance_handle, uint_8, uint_8, uint_16);
USB_STATUS _usb_host_ch9_get_configuration(_usb_device_instance_handle, uchar_ptr);     
USB_STATUS _usb_host_ch9_get_descriptor(_usb_device_instance_handle, uint_16, uint_16, uint_16, uchar_ptr);     
USB_STATUS _usb_host_ch9_get_interface(_usb_device_instance_handle, uint_8, uchar_ptr);     
USB_STATUS _usb_host_ch9_get_status(_usb_device_instance_handle, uint_8, uint_8, uchar_ptr);     
USB_STATUS _usb_host_ch9_set_address(_usb_device_instance_handle);     
USB_STATUS _usb_host_ch9_set_configuration(_usb_device_instance_handle, uint_16);     
USB_STATUS _usb_host_ch9_set_descriptor(_usb_device_instance_handle, uint_16, uint_16, uint_16, uchar_ptr);     
USB_STATUS _usb_host_ch9_set_feature(_usb_device_instance_handle, uint_8, uint_8, uint_16);
USB_STATUS _usb_host_ch9_set_interface(_usb_device_instance_handle, uint_8, uint_8);
USB_STATUS _usb_host_ch9_synch_frame(_usb_device_instance_handle, uint_8, uchar_ptr);
USB_STATUS _usb_hostdev_cntrl_request(_usb_device_instance_handle, USB_SETUP_PTR, uchar_ptr, tr_callback, pointer);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/rtcs25x.h<|end_filename|>
#ifndef __rtcs25x_h__
#define __rtcs25x_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: rtcs25x.h$
* $Version : 3.8.16.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This file contains the definitions required to
*   use RTCS with MQX2.5X.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#define MQX_DISABLE_CONFIG_CHECK 1
#include <message.h>
#include <partition.h>
#include <log.h>
#include <klog.h>
#include <pcb.h>
#undef MQX_DISABLE_CONFIG_CHECK

#include <rtcscfg.h>

#define RTCS_get_data()  _mqx_get_io_component_handle(IO_RTCS_COMPONENT)
#define RTCS_set_data(p) _mqx_set_io_component_handle(IO_RTCS_COMPONENT,p)

#define SNMP_get_data()  _mqx_get_io_component_handle(IO_SNMP_COMPONENT)
#define SNMP_set_data(p) _mqx_set_io_component_handle(IO_SNMP_COMPONENT,p)



/***************************************
**
** Memory management
*/

extern pointer RTCS_mem_alloc(_mem_size size);
extern pointer RTCS_mem_alloc_zero(_mem_size size);
extern pointer RTCS_mem_alloc_system(_mem_size size);
extern pointer RTCS_mem_alloc_system_zero(_mem_size size);



/***************************************
**
** Message passing
*/

extern boolean _msgq_send_blocked_internal(pointer);
#define RTCS_msgq_send_blocked(a,b)    _msgq_send_blocked_internal(a)
#define RTCS_msgq_send(a,b)            _msgq_send(a)
#define RTCS_msgq_get_id               _msgq_get_id
#define RTCS_msg_free                  _msg_free
#define RTCS_msg_alloc                 _msg_alloc
#define RTCS_msgq_receive(a,b,c)       _msgq_receive(a,b)
#define RTCS_msgpool_create            _msgpool_create
#define RTCS_msgpool_destroy           _msgpool_destroy
#define RTCS_msgq_open                 _msgq_open
#define RTCS_msgq_close                _msgq_close


/***************************************
**
** PPP Memory management
*/

#define PPP_memzero(ptr, bsize)        _mem_zero(ptr, bsize)
#define PPP_memcopy(src, dest, bsize)  _mem_copy(src, dest, bsize)
#define PPP_memalloc(bsize)            _mem_alloc_zero(bsize)
#define PPP_memfree(ptr)               _mem_free(ptr)


/***************************************
**
** PPP Mutual exclusion
*/

#define _ppp_mutex            LWSEM_STRUCT

#define PPP_mutex_init(p)     _lwsem_create_hidden(p, 1)
#define PPP_mutex_destroy(p)  _lwsem_destroy(p)
#define PPP_mutex_lock(p)     _lwsem_wait(p)
#define PPP_mutex_unlock(p)   _lwsem_post(p)

/***************************************
**
** Partitions
*/
typedef struct rtcs_partition{
#if RTCSCFG_USE_MQX_PARTITIONS
   _partition_id        PART;
   uint_32              SIZE;
#endif
#if RTCSCFG_USE_INTERNAL_PARTITIONS

   uint_32              BLOCK_SIZE;
   uint_32              NUM_BLOCKS;
   uint_32              GROW_BLOCKS;
   uint_32              MAX_BLOCKS;
   pointer              GROW;
#endif
   pointer              FREE;
   int_32 (_CODE_PTR_   CONSTR)(pointer);
   int_32 (_CODE_PTR_   DESTR)(pointer);
} RTCS_PARTITION, _PTR_ _rtcs_part;


extern _rtcs_part RTCS_part_create(
                     uint_32 size,
                     uint_32 init, uint_32 grow, uint_32 max,
                     int_32 (_CODE_PTR_ cons)(pointer),
                     int_32 (_CODE_PTR_ dest)(pointer)
                  );

extern void    RTCS_part_destroy    (_rtcs_part);
extern pointer RTCS_part_alloc      (_rtcs_part);
extern pointer RTCS_part_alloc_zero (_rtcs_part);
extern void    RTCS_part_free       (pointer);


/***************************************
**
** Time
*/

#define RTCS_time_delay       _time_delay
#define RTCS_get_milliseconds RTCS_time_get

extern uint_32 RTCS_time_get     (void);
extern uint_32 RTCS_time_get_sec (void);

/* This function calculates an interval between two moments in time
 * This function takes into account also a possible counter overrun @c (start>end).*/
extern uint_32 RTCS_timer_get_interval( uint_32, uint_32);


/***************************************
**
** Date
*/

extern void RTCS_date_get (uint_32_ptr, uint_32_ptr);
extern void RTCS_date_set (uint_32, uint_32);


/***************************************
**
** Synchronization
*/

#define _rtcs_sem             LWSEM_STRUCT

#define RTCS_sem_init(p)      _lwsem_create_hidden(p, 0)
#define RTCS_sem_destroy(p)   _lwsem_destroy(p)
#define RTCS_sem_post(p)      _lwsem_post(p)
#define RTCS_sem_wait(p)      _lwsem_wait(p)
#define RTCS_sem_trywait(p)   (_lwsem_poll(p) ? RTCS_OK : RTCS_ERROR)


/***************************************
**
** Mutual exclusion
*/

#define _rtcs_mutex           LWSEM_STRUCT

#define RTCS_mutex_init(p)    _lwsem_create_hidden(p, 1)
#define RTCS_mutex_destroy(p) _lwsem_destroy(p)
#define RTCS_mutex_lock(p)    _lwsem_wait(p)
#define RTCS_mutex_unlock(p)  _lwsem_post(p)


/***************************************
**
** Task management
*/

typedef pointer   _rtcs_taskid;

#define RTCS_task_getid()  _task_get_td(0)

extern uint_32 RTCS_task_create
(
   char_ptr          name,
   uint_32           priority,
   uint_32           stacksize,
   void (_CODE_PTR_  start)(pointer, pointer),
   pointer           arg
);

extern void RTCS_task_resume_creator (pointer, uint_32);
extern void RTCS_task_exit           (pointer, uint_32);

extern void RTCS_task_destroy (_rtcs_taskid);
extern void RTCS_task_abort (_rtcs_taskid);
extern _task_id RTCS_task_id_from_td (_rtcs_taskid);


/***************************************
**
** I/O
*/

#define RTCS_EACCES MQX_EACCES
#define RTCS_ENOENT MQX_ENOENT
#define RTCS_EEXIST MQX_EEXIST

extern pointer RTCS_io_open(char_ptr, char_ptr, uint_32 _PTR_);

#define RTCS_io_read(f,p,l)   ((int_32)read(f,(char_ptr)(p),l))
#define RTCS_io_write(f,p,l)  ((int_32)write(f,(char_ptr)(p),l))
#define RTCS_io_close(f)      fclose(f)

extern int_32 _io_socket_install(char_ptr);
extern int_32 _io_telnet_install(char_ptr);


/***************************************
**
** Logging
*/

#define RTCSLOG_TYPE_FNENTRY  KLOG_FUNCTION_ENTRY
#define RTCSLOG_TYPE_FNEXIT   KLOG_FUNCTION_EXIT
#define RTCSLOG_TYPE_PCB      KLOG_RTCS_PCB
#define RTCSLOG_TYPE_TIMER    KLOG_RTCS_TIMER
#define RTCSLOG_TYPE_ERROR    KLOG_RTCS_ERROR


#if MQX_KERNEL_LOGGING
   extern void _klog_log(uint_32, uint_32, uint_32, uint_32, uint_32, uint_32);
   #define RTCS_log_internal(type,p1,p2,p3,p4,p5)  _klog_log(type,p1,p2,p3,p4,p5)
#else
   #define RTCS_log_internal(type,p1,p2,p3,p4,p5) 
#endif


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_cpudef.h<|end_filename|>
/**HEADER**********************************************************************
*
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* $FileName: psp_cpudef.h$
* $Version : 3.8.20.0$
* $Date    : Oct-4-2012$
*
* Comments:
*   Processor and platform identifiers defined here
*
*END**************************************************************************/

#ifndef __psp_cpudef_h__
    #define __psp_cpudef_h__

#include "mqx_cpudef.h"

/* CPU groups for Kinetis K-Series */
#define PSP_CPU_GROUP_KINETIS_K1X       (0x01)
#define PSP_CPU_GROUP_KINETIS_K2X       (0x02)
#define PSP_CPU_GROUP_KINETIS_K3X       (0x03)
#define PSP_CPU_GROUP_KINETIS_K4X       (0x04)
#define PSP_CPU_GROUP_KINETIS_K5X       (0x05)
#define PSP_CPU_GROUP_KINETIS_K6X       (0x06)
#define PSP_CPU_GROUP_KINETIS_K7X       (0x07)

/* CPU groups for Kinetis GP L-Series */
#define PSP_CPU_GROUP_KINETIS_KL0X      (0x20)
#define PSP_CPU_GROUP_KINETIS_KL1X      (0x21)
#define PSP_CPU_GROUP_KINETIS_KL2X      (0x22)
#define PSP_CPU_GROUP_KINETIS_KL3X      (0x23)
#define PSP_CPU_GROUP_KINETIS_KL4X      (0x24)

/* TODO propose and check new numbers for Vybrid family a */
#define PSP_CPU_GROUP_VYBRID_M4         (0x41)
#define PSP_CPU_GROUP_VYBRID_A5         (0x51)


/* Specific CPU identification macros */
/* Kinetis GP K-Series K10 family with Cortex M4 core */
#define PSP_CPU_MK10DX128Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K1X, 0))
#define PSP_CPU_MK10DX256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K1X, 1))
#define PSP_CPU_MK10DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K1X, 2))
#define PSP_CPU_MK10F12         (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K1X, 3))
#define PSP_CPU_MK1X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K1X, 0xF))
/* Kinetis GP K-Series K20 family with Cortex M4 core */
#define PSP_CPU_MK20DX128Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K2X, 0))
#define PSP_CPU_MK20DX256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K2X, 1))
#define PSP_CPU_MK20DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K2X, 2))
#define PSP_CPU_MK20F12         (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K2X, 3))
#define PSP_CPU_MK20DX256       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K2X, 4))
#define PSP_CPU_MK20D50M        (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K2X, 5))
#define PSP_CPU_MK21DN512       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K2X, 6))
#define PSP_CPU_MK2X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K2X, 0xF))
/* Kinetis GP K-Series K30 family with Cortex M4 core */
#define PSP_CPU_MK30DX128Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K3X, 0))
#define PSP_CPU_MK30DX256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K3X, 1))
#define PSP_CPU_MK30DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K3X, 2))
#define PSP_CPU_MK3X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K3X, 0xF))
/* Kinetis GP K-Series 40 family with Cortex M4 core */
#define PSP_CPU_MK40DX128Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K4X, 0))
#define PSP_CPU_MK40DX256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K4X, 1))
#define PSP_CPU_MK40DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K4X, 2))
#define PSP_CPU_MK40DX128       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K4X, 3))
#define PSP_CPU_MK40DX256       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K4X, 4))
#define PSP_CPU_MK40D100M       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K4X, 5))
#define PSP_CPU_MK4X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K4X, 0xF))
/* Kinetis GP K-Series K50 family with Cortex M4 core */
#define PSP_CPU_MK53DN256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 0))
#define PSP_CPU_MK53DX256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 1))
#define PSP_CPU_MK53DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 2))
#define PSP_CPU_MK50DX256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 3))
#define PSP_CPU_MK50DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 4))
#define PSP_CPU_MK51DX256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 5))
#define PSP_CPU_MK51DN256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 4))
#define PSP_CPU_MK51DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 7))
#define PSP_CPU_MK52DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 8))
#define PSP_CPU_MK5X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K5X, 0xF))
/* Kinetis GP K-Series K60 family with Cortex M4 core */
#define PSP_CPU_MK60DN256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K6X, 0))
#define PSP_CPU_MK60DX256Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K6X, 1))
#define PSP_CPU_MK60DN512Z      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K6X, 2))
#define PSP_CPU_MK60DF120M      (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K6X, 3))
#define PSP_CPU_MK60D100M       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K6X, 4))
#define PSP_CPU_MK6X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K6X, 0xF))
/* Kinetis GP K-Series K70 family with Cortex M4 core */
#define PSP_CPU_MK70DP256       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K7X, 0))
#define PSP_CPU_MK70F120M       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K7X, 1))
#define PSP_CPU_MK70F150M       (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K7X, 2))
#define PSP_CPU_MK7X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K7X, 0xF))

/* Vybrid series family */
#define PSP_CPU_VF65GS10_M4     (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_VYBRID_M4, 0))

/* Kinetis GP L-Series family with Cortex M0+ core */
#define PSP_CPU_KL0X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M0P, PSP_CPU_GROUP_KINETIS_KL0X, 0xF))
#define PSP_CPU_KL1X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M0P, PSP_CPU_GROUP_KINETIS_KL1X, 0xF))
#define PSP_CPU_KL2X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M0P, PSP_CPU_GROUP_KINETIS_KL2X, 0xF))
#define PSP_CPU_KL3X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M0P, PSP_CPU_GROUP_KINETIS_KL3X, 0xF))
#define PSP_CPU_KL4X            (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M0P, PSP_CPU_GROUP_KINETIS_KL4X, 0xF))


/* CPU id check support macros */
/* Kinetis GP K-Series family */
#define PSP_MQX_CPU_IS_KINETIS_K1X  ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_K1X))
#define PSP_MQX_CPU_IS_KINETIS_K2X  ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_K2X))
#define PSP_MQX_CPU_IS_KINETIS_K3X  ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_K3X))
#define PSP_MQX_CPU_IS_KINETIS_K4X  ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_K4X))
#define PSP_MQX_CPU_IS_KINETIS_K5X  ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_K5X))
#define PSP_MQX_CPU_IS_KINETIS_K6X  ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_K6X))
#define PSP_MQX_CPU_IS_KINETIS_K7X  ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_K7X))

/* Kinetis GP L-Series family */
#define PSP_MQX_CPU_IS_KINETIS_KL0X ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_KL0X))
#define PSP_MQX_CPU_IS_KINETIS_KL1X ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_KL1X))
#define PSP_MQX_CPU_IS_KINETIS_KL2X ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_KL2X))
#define PSP_MQX_CPU_IS_KINETIS_KL3X ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_KL3X))
#define PSP_MQX_CPU_IS_KINETIS_KL4X ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_KINETIS_KL4X))

/* Kinetis GP K-Series family */
#define PSP_MQX_CPU_IS_KINETIS_K    (PSP_MQX_CPU_IS_KINETIS_K1X | \
                                     PSP_MQX_CPU_IS_KINETIS_K2X | \
                                     PSP_MQX_CPU_IS_KINETIS_K3X | \
                                     PSP_MQX_CPU_IS_KINETIS_K4X | \
                                     PSP_MQX_CPU_IS_KINETIS_K5X | \
                                     PSP_MQX_CPU_IS_KINETIS_K6X | \
                                     PSP_MQX_CPU_IS_KINETIS_K7X )
/* Kinetis GP L-Series family */
#define PSP_MQX_CPU_IS_KINETIS_L    (PSP_MQX_CPU_IS_KINETIS_KL0X | \
                                     PSP_MQX_CPU_IS_KINETIS_KL1X | \
                                     PSP_MQX_CPU_IS_KINETIS_KL2X | \
                                     PSP_MQX_CPU_IS_KINETIS_KL3X | \
                                     PSP_MQX_CPU_IS_KINETIS_KL4X )

/* Vybrid series family */
#define PSP_MQX_CPU_IS_VYBRID_M4    ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_VYBRID_M4))
#define PSP_MQX_CPU_IS_VYBRID_A5    ((PSP_GET_CPU_GROUP(MQX_CPU) == PSP_CPU_GROUP_VYBRID_A5))

#define PSP_MQX_CPU_IS_VYBRID       (PSP_MQX_CPU_IS_VYBRID_A5 | PSP_MQX_CPU_IS_VYBRID_M4)

/********************************************************************************************
 * Backward compatibility with older versions
 ********************************************************************************************/
#define PSP_CPU_GROUP_KINETIS_K10   PSP_CPU_GROUP_KINETIS_K1X
#define PSP_CPU_GROUP_KINETIS_K20   PSP_CPU_GROUP_KINETIS_K2X
#define PSP_CPU_GROUP_KINETIS_K30   PSP_CPU_GROUP_KINETIS_K3X
#define PSP_CPU_GROUP_KINETIS_K40   PSP_CPU_GROUP_KINETIS_K4X
#define PSP_CPU_GROUP_KINETIS_K50   PSP_CPU_GROUP_KINETIS_K5X
#define PSP_CPU_GROUP_KINETIS_K60   PSP_CPU_GROUP_KINETIS_K6X
#define PSP_CPU_GROUP_KINETIS_K70   PSP_CPU_GROUP_KINETIS_K7X

#define PSP_MQX_CPU_IS_KINETIS_K10  PSP_MQX_CPU_IS_KINETIS_K1X
#define PSP_MQX_CPU_IS_KINETIS_K20  PSP_MQX_CPU_IS_KINETIS_K2X
#define PSP_MQX_CPU_IS_KINETIS_K30  PSP_MQX_CPU_IS_KINETIS_K3X
#define PSP_MQX_CPU_IS_KINETIS_K40  PSP_MQX_CPU_IS_KINETIS_K4X
#define PSP_MQX_CPU_IS_KINETIS_K50  PSP_MQX_CPU_IS_KINETIS_K5X
#define PSP_MQX_CPU_IS_KINETIS_K60  PSP_MQX_CPU_IS_KINETIS_K6X
#define PSP_MQX_CPU_IS_KINETIS_K70  PSP_MQX_CPU_IS_KINETIS_K7X

#define PSP_MQX_CPU_IS_KINETIS      PSP_MQX_CPU_IS_KINETIS_K

/* K40 */
#define PSP_CPU_K40N256         PSP_CPU_MK40DX256Z
#define PSP_CPU_K40N512         PSP_CPU_MK40DN512Z
#define PSP_CPU_MK40X256        PSP_CPU_MK40DX256Z
/* K53 */
#define PSP_CPU_K53N512         PSP_CPU_MK53DN512Z
#define PSP_CPU_MK53N512        PSP_CPU_MK53DN512Z
/* K60 */
#define PSP_CPU_K60N512         PSP_CPU_MK60DN512Z
#define PSP_CPU_MK60N512        PSP_CPU_MK60DN512Z



#endif /* __psp_cpudef_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/can/flexcan/kflexcan.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: kflexcan.c$
* $Version : 3.8.13.0$
* $Date    : Jun-6-2012$
*
* Comments:
*   Kinetis FlexCAN specific code.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Start
* Returned Value   : uint_32
* Comments         :
*    This function starts the specified FlexCAN device
*
*END*********************************************************************/
uint_32 FLEXCAN_Start
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /* Starting FLEXCAN in normal mode */
   can_reg_ptr->MCR &= ~(CAN_MCR_HALT_MASK | CAN_MCR_MDIS_MASK
                            | CAN_MCR_FRZ_MASK);

   /* wait for synchronization */
   while(can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK){}

   return( FLEXCAN_OK );
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Softreset
* Returned Value   : uint_32
* Comments         :
*    This function resets the specific CAN device
*
*END*********************************************************************/
uint_32 FLEXCAN_Softreset
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{ /* Body */

   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

  /* check for low power mode */
  if(can_reg_ptr->MCR & CAN_MCR_LPMACK_MASK)
  {
     /* Enable clock */
     can_reg_ptr->MCR &= (~ CAN_MCR_MDIS_MASK);
     /* wait until enabled */
     while (can_reg_ptr->MCR & CAN_MCR_LPMACK_MASK){}
  }

  /* Reset the FLEXCAN */
  can_reg_ptr->MCR = CAN_MCR_SOFTRST_MASK;

  /* Wait for reset cycle to complete */
  while (can_reg_ptr->MCR & CAN_MCR_SOFTRST_MASK){}

  /* Set Freeze, Halt */
  can_reg_ptr->MCR |= (CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK);

  /* check for freeze Ack */
  if(
     ( (can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) != CAN_MCR_FRZACK_MASK ) ||
     ( (can_reg_ptr->MCR & CAN_MCR_NOTRDY_MASK) != CAN_MCR_NOTRDY_MASK )
    )
     return (FLEXCAN_SOFTRESET_FAILED);

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Get_msg_object
* Returned Value   : pointer
* Comments         :
*    This function returns a pointer to the mailbox object specified
*    by the mailbox number.
*
*END*********************************************************************/
pointer FLEXCAN_Get_msg_object
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number
)
{ /* Body */

   volatile uchar_ptr      temp_ptr;
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (NULL);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (NULL);
   }

   temp_ptr = (uchar_ptr)can_reg_ptr;
   temp_ptr += FLEXCAN_MSG_BUFADDR_OFFSET;


   /*
   ** Calculate what message object to point to
   */
  temp_ptr += sizeof(can_reg_ptr->MB[0]) * mailbox_number;

   return ((pointer)temp_ptr);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Select_mode
* Returned Value   : uint_32
* Comments         :
*    This function sets FlexCAN module operation mode
*
*END*********************************************************************/
uint_32 FLEXCAN_Select_mode
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] operation Mode */
   uint_32 mode
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   volatile uint_32        ret_code = FLEXCAN_OK;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   switch(mode)
   {
   case (FLEXCAN_NORMAL_MODE):
      /*
      ** Normal mode, check freeze ACK bit
      ** call start if bit is set
      */
      if( (can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == CAN_MCR_FRZACK_MASK)
      {
         if( FLEXCAN_Start(dev_num) )
            ret_code = FLEXCAN_START_FAILED;
      }
      break;
   case (FLEXCAN_LISTEN_MODE):
      /* Set CTRL1[LOM], listen-only mode */
      can_reg_ptr->CTRL1 |= CAN_CTRL1_LOM_MASK;
      break;
   case (FLEXCAN_TIMESYNC_MODE):
      /* Timer Synchronization mode (Global Network Time) */
      can_reg_ptr->CTRL1 |= CAN_CTRL1_TSYN_MASK;
      break;
   case (FLEXCAN_LOOPBK_MODE):
      /* Self test mode, Loop Back */
      can_reg_ptr->CTRL1 |= CAN_CTRL1_LPB_MASK;
      break;
   case (FLEXCAN_BOFFREC_MODE):
      /* Bus Off Recovery mode (according to CAN 2.0b) */
      can_reg_ptr->CTRL1 &= ~(CAN_CTRL1_BOFFMSK_MASK);
      break;
   case (FLEXCAN_FREEZE_MODE):
      /* Debug mode, Halt and Freeze */
      can_reg_ptr->MCR |= (CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK);
     /* check for freeze Ack */
     if( (can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) != CAN_MCR_FRZACK_MASK)
        ret_code = FLEXCAN_FREEZE_FAILED;
      break;
   case (FLEXCAN_DISABLE_MODE):
      /* Debug mode, Halt and Freeze */
      can_reg_ptr->MCR |= CAN_MCR_MDIS_MASK;
      break;
   default:
      ret_code = FLEXCAN_INVALID_MODE;
   }

   return( ret_code );
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Select_CLK
* Returned Value   : uint_32
* Comments         :
*    This function sets FlexCAN module operation mode
*
*END*********************************************************************/
uint_32 FLEXCAN_Select_clk
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] FlexCAN clock source */
   uint_32 clk
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if(clk == FLEXCAN_IPBUS_CLK)
   /* Internal bus clock (fsys/2) */
      can_reg_ptr->CTRL1 |= CAN_CTRL1_CLKSRC_MASK;

   else if (clk == FLEXCAN_OSC_CLK)
      /* External clock */
      can_reg_ptr->CTRL1 &= (~ CAN_CTRL1_CLKSRC_MASK);

   else
      return (FLEXCAN_CLOCK_SOURCE_INVALID);


   return( FLEXCAN_OK );
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Initialize
* Returned Value   : uint_32
* Comments         :
*    This function initializes all mailbox-independant registers of the
*    FLEXCAN chip.
*    NOTE:
*         TimeSeg1 = PROP_SEG + PHASE_SEG1
*         TimeSeg2 = PHASE_SEG2
*       Ex. PHASE_SEG1 = 0xF and PROP_SEG = 0x7 => bit_timing0 = 0x000F0007
*
*END*********************************************************************/
uint_32 FLEXCAN_Initialize
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] MS 16 bits = TimeSeg1, LS 16 bits = TimeSeg2 */
   uint_32 bit_timing0,
   /* [IN] MS 16 bits = prescaller value, LS 16 bits = SJW */
   uint_32 bit_timing1,
   /* [IN] Bit rate in Kbps */
   uint_32 frequency,
   /* [IN] clock source */
   uint_32 clk
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   vuint_32                PSEG1 =0;
   vuint_32                PSEG2 = 0;
   vuint_32                PROPSEG = 0;
   vuint_32                RJW = 0;
   vuint_32                PRESDIV = 0;
   uint_32                 i;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /*
   ** To access the memory mapped registers
   ** Entre disable mode (hard reset).
   */
   if((can_reg_ptr->MCR & CAN_MCR_MDIS_MASK) == 0x00000000)
   {
      /* clock disable (module) */
      can_reg_ptr->MCR = CAN_MCR_MDIS_MASK;

      /* wait until disable mode acknowledged */
      while (!can_reg_ptr->MCR & CAN_MCR_LPMACK_MASK) {}
   }

   /* Reset FLEXCAN, Halt, freeze mode */
   if(FLEXCAN_Softreset(dev_num))
      return (FLEXCAN_INIT_FAILED);
   
   /*  Wait for entering the freeze mode */
   while((can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == 0) {}
   
   /* 
   ** Select the clock source 
   ** Default: internal bus clock (fsys/2).
   */
   FLEXCAN_Select_clk (dev_num, clk);
   
   if (can_reg_ptr->CTRL1 & CAN_CTRL1_CLKSRC_MASK) 
   {
       clk = _cm_get_clock(_cm_get_clock_configuration(), CM_CLOCK_SOURCE_BUS);
   }
   else
   {
       clk = _cm_get_clock(_cm_get_clock_configuration(), CM_CLOCK_SOURCE_OSCER);
   }   

   frequency *= 1000;

   /* bit timing settings */
   if( (bit_timing0 == 0x00) && (bit_timing1 == 0x00) )
   {
       // If BSP_CANPE_CLOCK is defined, then we will calculate the CAN bit timing parameters
       // using the method outlined in AN1798, section 4.1. A maximum time for PROP_SEG will be used,
       // the remaining TQ will be split equally between PSEG1 and PSEG2, provided PSEG2 >=2. RJW is
       // set to the minimum of 4 or PSEG1.
       
       uint_32 TQ_x_Prescaler = clk / frequency;
       uint_32 TQ, lowest_diff, diff, best_TQ, actual_freq;
    
       if (TQ_x_Prescaler < (CAN_MIN_TQ-1)) {
           // We will be off by more than 12.5%
           return FLEXCAN_INVALID_FREQUENCY;
       }
    
       // First, find the best TQ and pre-scaler to use for the desired frequency. If any exact matches
       // is found, we use the match that gives us the lowest pre-scaler and highest TQ, otherwise we pick
       // the TQ and prescaler that generates the closest frequency to the desired frequency.
    
       lowest_diff = frequency;
       best_TQ=0;
       for (TQ=CAN_MAX_TQ;TQ>=CAN_MIN_TQ;TQ--) {
           PRESDIV = TQ_x_Prescaler/TQ;
           if ( PRESDIV <=256){
               if (TQ_x_Prescaler == TQ*PRESDIV) {
                   best_TQ=TQ;
                   break;
               }
               actual_freq = (clk/PRESDIV)/TQ;
               diff = (actual_freq>frequency)?actual_freq-frequency:frequency-actual_freq;
               if (diff<lowest_diff) {
                   lowest_diff=diff;
                   best_TQ=TQ;
               }
           }
       }
       if ((best_TQ>=CAN_MIN_TQ) && ( PRESDIV <=256)) {
           PSEG2 = (best_TQ-CAN_MAX_PROPSEG)/2;
           if (PSEG2 < CAN_MIN_PSEG2) PSEG2=CAN_MIN_PSEG2;
           PSEG1 = (best_TQ == CAN_MIN_TQ)?1:PSEG2;
           PROPSEG = best_TQ - PSEG1 - PSEG2 - 1;
           RJW = (PSEG1<CAN_MAX_RJW)?PSEG1:CAN_MAX_RJW;

           can_reg_ptr->CTRL1 &= (~ (CAN_CTRL1_SMP_MASK | CAN_CTRL1_PROPSEG_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK | CAN_CTRL1_PRESDIV_MASK));
           can_reg_ptr->CTRL1 |= (0 | CAN_CTRL1_PROPSEG(PROPSEG - 1) | CAN_CTRL1_RJW(RJW - 1)
                                    | CAN_CTRL1_PSEG1(PSEG1 - 1) | CAN_CTRL1_PSEG2(PSEG2 - 1)
                                    | CAN_CTRL1_PRESDIV(PRESDIV - 1));
       } else {
           return FLEXCAN_INVALID_FREQUENCY;
       }
   }
   else
   {
      PSEG1 = (bit_timing0 & 0x00070000) >> 16;
      PROPSEG = bit_timing0 & 0x7;
      PSEG2 = (bit_timing1 & 0x00070000) >> 16;
      RJW = (bit_timing1 & 0x00000300) >> 8;
      PRESDIV = bit_timing1 & 0x000000FF;

      can_reg_ptr->CTRL1 &= (~ (CAN_CTRL1_SMP_MASK | CAN_CTRL1_PROPSEG_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK | CAN_CTRL1_PRESDIV_MASK));
      can_reg_ptr->CTRL1 |= (0 | CAN_CTRL1_PROPSEG(PROPSEG) | CAN_CTRL1_RJW(RJW)
                                 | CAN_CTRL1_PSEG1(PSEG1) | CAN_CTRL1_PSEG2(PSEG2)
                                 | CAN_CTRL1_PRESDIV(PRESDIV));
   }

   /* Set maximum number of message buffers */
   can_reg_ptr->MCR |= CAN_MCR_MAXMB(0xFFFFFFFF);

   /* Rx global mask */
   can_reg_ptr->RXMGMASK   = CAN_ID_EXT(0xFFFFFFFF);

   /* Rx reg 14 mask */
   can_reg_ptr->RX14MASK  = CAN_ID_EXT(0xFFFFFFFF);

   /* Rx reg 15 mask */
   can_reg_ptr->RX15MASK  = CAN_ID_EXT(0xFFFFFFFF);

   /*
   * Initialize all message buffers as inactive
   */
   for (i = 0; i <= CAN_MCR_MAXMB(0xF); i++)
   {
       can_reg_ptr->MB[i].CS = 0x00000000;
   }

   return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Initialize_mailbox
* Returned Value   : uint_32
* Comments         :
*    This function initializes the specified FlexCAN mailbox (Message Buffer)
*
*END*********************************************************************/
uint_32 FLEXCAN_Initialize_mailbox
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number,
   /* [IN] message ID */
   uint_32 identifier,
   /* [IN] number of bytes to write to the mailbox (0 to 8) */
   uint_32 data_len_code,
   /* [IN] transmission or reception direction (CAN_TX or CAN_RX) */
   uint_32 direction,
   /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
   uint_32 format,
   /* [IN] enable/disable interrupt for the mailbox */
   uint_32 int_enable
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   vuint_32                temp_msg_config;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( (mailbox_number > CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   if (8 < data_len_code)
   {
      return (FLEXCAN_DATA_SIZE_ERROR);
   }

   /*
   ** TX = 0x80: MB is not ready for transmit (code=0b1000)
   ** RX = 0x00: MB is not active (code=0b0000)
   ** Set code depending on direction and set the number of data bytes to be stored
   */
   if (direction == FLEXCAN_TX)
   {
      temp_msg_config = CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE);
   }
   else if (direction == FLEXCAN_RX)
   {
      temp_msg_config = CAN_CS_CODE(CAN_RX_MSG_BUFFER_NOT_ACTIVE);
   }
   else
   {
      return (FLEXCAN_INVALID_DIRECTION);
   }/* Endif */

   /* Set transmit length to data length in bytes */
   temp_msg_config |= (data_len_code << CAN_CS_DLC_SHIFT);
   can_reg_ptr->MB[mailbox_number].CS = temp_msg_config;

   /* Set the ID according the format structure */
   if ( format == FLEXCAN_EXTENDED )
   {
      /* Set IDE */
      can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_IDE_MASK;

      /* Set SRR bit for Tx buffers */
      if(direction == FLEXCAN_TX)
         can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_SRR_MASK;

      /* Start CR# 1730 */
      can_reg_ptr->MB[mailbox_number].ID &= ~(0x1FFFFFFF);
      can_reg_ptr->MB[mailbox_number].ID |= (identifier & 0x1FFFFFFF);
   }
   else if( format == FLEXCAN_STANDARD )
   {
      /* make sure IDE and SRR are not set */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_IDE_MASK | CAN_CS_SRR_MASK);

      /* ID[28-18] */
      can_reg_ptr->MB[mailbox_number].ID &= ~CAN_ID_STD_MASK;
      can_reg_ptr->MB[mailbox_number].ID |= CAN_ID_STD(identifier);
   }
   else
      return (FLEXCAN_MESSAGE_FORMAT_UNKNOWN);
   /* Endif */

   /* Enable CAN interrupt */
   if(int_enable == FLEXCAN_ENABLE)
   {
      /* Enable interrupt line */
      if( FLEXCAN_Int_enable(dev_num, mailbox_number) )
         return (FLEXCAN_INT_ENABLE_FAILED);
   }
   else
   {
      /* Disable interrupt line */
      if( FLEXCAN_Int_disable(dev_num, mailbox_number) )
         return (FLEXCAN_INT_DISABLE_FAILED);
   }

   return ( FLEXCAN_OK );
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Request_mailbox
* Returned Value   : uint_32
* Comments         :
*    This function sets the RTR bit (reomte frame) for the
*    specified mailbox
*
*END*********************************************************************/
uint_32 FLEXCAN_Request_mailbox
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number,
   /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
   uint_32 format
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   /* Set RTR */
   can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_RTR_MASK;

   return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Activate_mailbox
* Returned Value   : uint_32
* Comments         :
*    This function activates the specified mailbox with the activation code
*    provided.
*
*END*********************************************************************/
uint_32 FLEXCAN_Activate_mailbox
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number,
   /* [IN] Code value for CONTROL/STATUS field */
   uint_32 code_val
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   /* Reset the code */
   can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

   /* Activating mailbox */
   can_reg_ptr->MB[mailbox_number].CS |= code_val;

   /* // Unlock the mailbox ... ???
   can_reg_ptr = (CAN_MemMapPtr)can_ptr;
   code_val = can_reg_ptr->TIMER;
   */

   return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Lock_mailbox
* Returned Value   : uint_32
* Comments         :
*    This function locks the specified mailbox
*
*END*********************************************************************/
uint_32 FLEXCAN_Lock_mailbox
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   vuint_32 temp;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return( FLEXCAN_INVALID_MAILBOX );
   }

   /* Lock the mailbox */
   temp = can_reg_ptr->MB[mailbox_number].CS ;

   return( FLEXCAN_OK );

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_unlock_mailbox
* Returned Value   : uint_32
* Comments         :
*    This function unlocks flexcan mailbox
*
*END*********************************************************************/
uint_32 FLEXCAN_Unlock_mailbox
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   vuint_32                temp;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /* Unlock the mailbox */
   temp = can_reg_ptr->TIMER;

   return( FLEXCAN_OK );

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Set_global_extmask
* Returned Value   : uint_32
* Comments         :
*    This function sets the FLEXCAN chip global extended mask.
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_global_extmask
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] Mask */
   uint_32 extmask
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /* Set Freeze mode */
   can_reg_ptr->MCR |= CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK | CAN_MCR_NOTRDY_MASK;

   /* Wait for entering the freeze mode */
   while((can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == 0){}

   /* MID[28-0] */
   can_reg_ptr->RXMGMASK = CAN_ID_EXT(extmask);

   /* De-assert Freeze Mode */
   can_reg_ptr->MCR &= ~(CAN_MCR_FRZ_MASK);

   /* Wait till exit of freeze mode */
   while( can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK){}

   return (FLEXCAN_OK);

} /* Endbody */

 /*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Set_Buf14_extmask
* Returned Value   : uint_32
* Comments         :
*    This function sets the FlexCAN buf14 extended mask.
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_buf14_extmask
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] Mask */
   uint_32 extmask
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /* Set Freeze mode */
   can_reg_ptr->MCR |= CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK | CAN_MCR_NOTRDY_MASK;

   /* Wait for entering the freeze mode */
   while((can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == 0){}

   /* MID[28-0] */
   can_reg_ptr->RX14MASK = CAN_ID_EXT(extmask);

   /* De-assert Freeze Mode */
   can_reg_ptr->MCR &= ~(CAN_MCR_FRZ_MASK);

   /* Wait till exit of freeze mode */
   while( can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK){}

   return (FLEXCAN_OK);

} /* Endbody */

 /*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Set_Buf15_extmask
* Returned Value   : uint_32
* Comments         :
*    This function sets the FlexCAN buf15 extended mask.
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_buf15_extmask
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] Mask */
   uint_32 extmask
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /* Set Freeze mode */
   can_reg_ptr->MCR |= CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK | CAN_MCR_NOTRDY_MASK;

   /* Wait for entering the freeze mode */
   while((can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == 0){}

   /* MID[28-0] */
   can_reg_ptr->RX15MASK = CAN_ID_EXT(extmask);

   /* De-assert Freeze Mode */
   can_reg_ptr->MCR &= ~(CAN_MCR_FRZ_MASK);

   /* Wait till exit of freeze mode */
   while( can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK){}

   return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Set_global_stdmask
* Returned Value   : uint_32
* Comments         :
*    This function sets the CAN chip global standard mask.
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_global_stdmask
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] Mask */
   uint_32 stdmask
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /* Set Freeze mode */
   can_reg_ptr->MCR |= CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK | CAN_MCR_NOTRDY_MASK;

   /* Wait for entering the freeze mode */
   while((can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == 0){}

   /* 11 bit standard mask */
   can_reg_ptr->RXMGMASK = CAN_ID_STD(stdmask);

   /* De-assert Freeze Mode */
   can_reg_ptr->MCR &= ~(CAN_MCR_FRZ_MASK);

   /* Wait till exit of freeze mode */
   while( can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK){}

   return (FLEXCAN_OK);

} /* Endbody */
 /*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Set_Buf14_stdmask
* Returned Value   : uint_32
* Comments         :
*    This function sets the FlexCAN buf14 standard mask.
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_buf14_stdmask
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] Mask */
   uint_32 stdmask
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /* Set Freeze mode */
   can_reg_ptr->MCR |= CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK | CAN_MCR_NOTRDY_MASK;

   /* Wait for entering the freeze mode */
   while((can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == 0){}

    /* 11 bit standard mask */
   can_reg_ptr->RX14MASK = CAN_ID_STD(stdmask);

   /* De-assert Freeze Mode */
   can_reg_ptr->MCR &= ~(CAN_MCR_FRZ_MASK);

   /* Wait till exit of freeze mode */
   while( can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK){}

   return (FLEXCAN_OK);

} /* Endbody */

 /*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Set_Buf15_stdmask
* Returned Value   : uint_32
* Comments         :
*    This function sets the FlexCAN buf15 standard mask.
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_buf15_stdmask
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] Mask */
   uint_32 stdmask
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   /* Set Freeze mode */
   can_reg_ptr->MCR |= CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK | CAN_MCR_NOTRDY_MASK;

   /* Wait for entering the freeze mode */
   while((can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == 0){}

    /* 11 bit standard mask */
   can_reg_ptr->RX15MASK = CAN_ID_STD(stdmask);

   /* De-assert Freeze Mode */
   can_reg_ptr->MCR &= ~(CAN_MCR_FRZ_MASK);

   /* Wait till exit of freeze mode */
   while( can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK){}

   return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Tx_successful
* Returned Value   : boolean
* Comments         :
*    This function returns TRUE or FALSE depending on whether or not
*    the message has been placed in the mailbox.
*
*END*********************************************************************/
boolean FLEXCAN_Tx_successful
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num
)
{  /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   return ((can_reg_ptr->IFLAG1 & CAN_IMASK1_BUFLM_MASK) != 0);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Tx_mailbox
* Returned Value   : uint_32
* Comments         :
*    This function writes a message to the specified mailbox and sends once
*
*END*********************************************************************/
uint_32 FLEXCAN_Tx_mailbox
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number,
   /* [IN] Data to be written to the mailbox */
   pointer data
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   volatile uchar_ptr      data_array;
   vuint_32                data_length;
   vuint_32                temp;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   /* Locking mailbox */
   can_reg_ptr->MB[mailbox_number].CS  |= CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE);

   data_length = ( (can_reg_ptr->MB[mailbox_number].CS) & CAN_CS_DLC_MASK );

   /* Copy user's buffer into mailbox data area */
   data_array = (uchar_ptr) data;

   can_reg_ptr->MB[mailbox_number].WORD0 = data_array[3] | data_array[2]<<8 | data_array[1]<<16 | data_array[0]<<24;
   can_reg_ptr->MB[mailbox_number].WORD1 = data_array[7] | data_array[6]<<8 | data_array[5]<<16 | data_array[4]<<24;

   /* transmit data in message buffer */
   can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_ONCE) | data_length);

   /* Unlock message buffer */
   temp = can_reg_ptr->TIMER;

   return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Rx_mailbox
* Returned Value   : uint_32
* Comments         :
*    This function reads a message from the specified mailbox
*
*END*********************************************************************/
uint_32 FLEXCAN_Rx_mailbox
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32  mailbox_number,
   /* [IN] Location to store the data from the mailbox */
   pointer  data
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   volatile uchar_ptr      data_array;
   uint_32                 i;
   uint_32                 return_code = FLEXCAN_OK;
   vuint_32                data_length;
   vuint_32                DLC;
   vuint_32                temp;
   volatile                uchar_ptr mb_data_array;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   data_array = (uchar_ptr)data;

   /* Lock */
   temp = can_reg_ptr->MB[mailbox_number].CS;

   /* Data length */
   data_length = ( temp & CAN_CS_DLC_MASK );
   DLC = data_length >> CAN_CS_DLC_SHIFT;

   /* Check for mailbox activation code */
   if ( (temp & CAN_CS_CODE_MASK) == CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY))
   {
      /* No data return */
      return_code = FLEXCAN_NO_MESSAGE;
   }

   if ( (temp & CAN_CS_CODE_MASK) == CAN_CS_CODE(CAN_RX_MSG_BUFFER_NOT_ACTIVE) )
   {
      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* mailbox is not active, return */
      can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | data_length;

      return_code = FLEXCAN_NO_MESSAGE;
   }

   /* initialize message buffer data pointer */
   mb_data_array = (uchar_ptr) &can_reg_ptr->MB[mailbox_number].WORD0;

   /*
   ** Copy data to user buffer
   */
   if ( (temp & CAN_CS_CODE_MASK) == CAN_CS_CODE(CAN_RX_MSG_BUFFER_BUSY) )
   {
	  /* Wait for copying data */
      while(can_reg_ptr->MB[mailbox_number].CS & CAN_CS_CODE(CAN_RX_MSG_BUFFER_BUSY)) {}

	  /* Copying data */
      for ( i=0; i<DLC; i++ )
      {
         data_array[i] = mb_data_array[3 - (i&0x3) + (i&0x4)];
      } /* Endfor */
	  can_reg_ptr->MB[mailbox_number].WORD0 = 0;
      can_reg_ptr->MB[mailbox_number].WORD1 = 0;

      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* Set the code */
      can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | data_length;

      return_code = FLEXCAN_MESSAGE_BUSY;
   }
   else if ( (temp & CAN_CS_CODE_MASK) == CAN_CS_CODE(CAN_RX_MSG_BUFFER_FULL) )
   {
      /* Copying data */
      for ( i=0; i<DLC; i++ )
      {
         data_array[i] = mb_data_array[3 - (i&0x3) + (i&0x4)];
      } /* Endfor */

      can_reg_ptr->MB[mailbox_number].WORD0 = 0;
      can_reg_ptr->MB[mailbox_number].WORD1 = 0;

      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* Set the code */
      can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | data_length;

      return_code = FLEXCAN_OK;

   } else if ( (temp & CAN_CS_CODE_MASK) == CAN_CS_CODE(CAN_RX_MSG_BUFFER_OVERRUN) )
   {
      /* Copying data */
      for ( i=0; i<DLC; i++ )
      {
         data_array[i] = mb_data_array[3 - (i&0x3) + (i&0x4)];
      } /* Endfor */

      can_reg_ptr->MB[mailbox_number].WORD0 = 0;
      can_reg_ptr->MB[mailbox_number].WORD1 = 0;

      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* Set the code */
      can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | data_length;

      return_code = FLEXCAN_MESSAGE_LOST;
   }

   /* Unlock message buffer */
   temp = can_reg_ptr->TIMER;

   return return_code;

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Disable_mailbox
* Returned Value   : uint_32
* Comments         :
*    This function disables the specified mailbox
*
*END*********************************************************************/
uint_32 FLEXCAN_Disable_mailbox
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number
)
{ /* Body */

   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   can_reg_ptr->MB[mailbox_number].CS &= ~CAN_CS_CODE_MASK;

   return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Request_message
* Returned Value   : uint_32
* Comments         :
*    This function requests remote messages as specified by the
*    mailbox number and format parameters. Sets the message buffer's code
*
*END*********************************************************************/
uint_32 FLEXCAN_Request_message
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number,
   /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
   uint_32 format
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   uint_32                 error_code;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return( FLEXCAN_INVALID_MAILBOX );
   }

   /* Set message format to remote */
   error_code = FLEXCAN_Request_mailbox( dev_num, mailbox_number, format );
   if ( error_code != FLEXCAN_OK )
   {
      return( error_code );
   }

   /*
   ** Activate mailbox: code 0b1100
   ** Data field length and data in remote message is ignored.
   ** Mailbox becomes receive mailbox.
   */
   error_code = FLEXCAN_Activate_mailbox( dev_num, mailbox_number, CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_REMOTE) );
   if ( error_code != FLEXCAN_OK )
   {
      return( error_code );
   }

   return( FLEXCAN_OK );

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Rx_message
* Returned Value   : uint_32
* Comments         :
*    This function receives a message from the specified masked mailbox .
*
*
*END*********************************************************************/
uint_32 FLEXCAN_Rx_message
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32     mailbox_number,
   /* [IN/OUT] message ID */
   uint_32_ptr identifier,
   /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
   uint_32     format,
   /* [IN/OUT] number of bytes to write to the mailbox (0 to 8) */
   uint_32_ptr data_len_code,
   /* [IN/OUT] Location to store the data from the mailbox */
   pointer     data,
   /* [IN] enable/disable interrupt for the mailbox */
   uint_32     int_enable
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   vuint_32                code;
   uint_32                 i;
   uint_32                 return_code = FLEXCAN_OK;
   vuint_32                temp;
   vuint_32                DLC;
   vuint_32                ID;
   vuint_32                dlen;
   volatile uchar_ptr      mb_data_array;
   volatile uchar_ptr      data_array;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return( FLEXCAN_INVALID_MAILBOX );
   }

   /* store data len */
   dlen = can_reg_ptr->MB[mailbox_number].CS & CAN_CS_DLC_MASK;
   DLC = dlen >> CAN_CS_DLC_SHIFT;

   /* Reassemble the message ID */
   switch (format)
   {
   case (FLEXCAN_EXTENDED):
      /* Start CR# 1730 */
      ID = (can_reg_ptr->MB[mailbox_number].ID & 0x1FFFFFFF);
      break;
   case (FLEXCAN_STANDARD):
      /* ID[28-18] */
      ID = ((can_reg_ptr->MB[mailbox_number].ID & CAN_ID_STD_MASK) >> CAN_ID_STD_SHIFT);
      break;
   default:
      return (FLEXCAN_MESSAGE_FORMAT_UNKNOWN);
   } /* Endswitch */

   /*
   ** if "code" value for specified Rx message buffer is full
   ** copy data to the buffer and set the code to empty and return.
   ** if "code" value is set to not active, set the code to empty and
   ** return message buffer empty.
   ** if "code" value is set to overrun, copy data to the buffer and
   ** set the code to empty then return overrun.
   ** if "code" value is set to busy, copy data to the buffer and
   ** set the code to empty then return busy.
   */
   code = can_reg_ptr->MB[mailbox_number].CS & CAN_CS_CODE_MASK;

   /* initialize message buffer data pointer */
   mb_data_array = (uchar_ptr) &can_reg_ptr->MB[mailbox_number].WORD0;

   if ( code == CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY))
   {
      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* Set the code */
      can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | dlen);

      /* No data return */
      return_code = FLEXCAN_NO_MESSAGE;
   }

   if ( code == CAN_CS_CODE(CAN_RX_MSG_BUFFER_NOT_ACTIVE) )
   {
      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* Set the code */
      can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | dlen);

      /* No data return */
      return_code = FLEXCAN_NO_MESSAGE;
   }

   if ( code == CAN_CS_CODE(CAN_RX_MSG_BUFFER_FULL) )
   {
      data_array = (uchar_ptr)data;
      for ( i=0 ; i<DLC ; i++ )
      {
         data_array[i] = mb_data_array[3 - (i&0x3) + (i&0x4)];
      } /* Endfor */

      can_reg_ptr->MB[mailbox_number].WORD0 = 0;
      can_reg_ptr->MB[mailbox_number].WORD1 = 0;

      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* Set the code */
      can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | dlen);
      return_code = FLEXCAN_OK;
   }
   else if ( code == CAN_CS_CODE(CAN_RX_MSG_BUFFER_OVERRUN) )
   {
      data_array = (uchar_ptr)data;
      for ( i=0 ;i<DLC ; i++ )
      {
         data_array[i] = mb_data_array[3 - (i&0x3) + (i&0x4)];
      } /* Endfor */

      can_reg_ptr->MB[mailbox_number].WORD0 = 0;
      can_reg_ptr->MB[mailbox_number].WORD1 = 0;

      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* Set the code */
      can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | dlen);
      return_code = FLEXCAN_NO_MESSAGE;
   }
   else if ( code == CAN_CS_CODE(CAN_RX_MSG_BUFFER_BUSY) )
   {
      data_array = (uchar_ptr)data;
      for ( i=0 ;i<DLC ; i++ )
      {
         data_array[i] = mb_data_array[3 - (i&0x3) + (i&0x4)];
      } /* Endfor */

      can_reg_ptr->MB[mailbox_number].WORD0 = 0;
      can_reg_ptr->MB[mailbox_number].WORD1 = 0;

      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* Set the code */
      can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | dlen);
      return_code =  FLEXCAN_MESSAGE_OVERWRITTEN;
   } /* Endif */

   /* Unlock message buffer. only in polling mode */
   if(int_enable == FLEXCAN_DISABLE)
   {
      temp = can_reg_ptr->TIMER;
   }

   /* Store data length */
   *data_len_code = DLC;

   /* Store identifier */
   *identifier = ID;

   return return_code;
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Tx_message
* Returned Value   : uint_32
* Comments         :
*    This function sends a message from the specified mailbox
*
*END*********************************************************************/
uint_32 FLEXCAN_Tx_message
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] mailbox number */
   uint_32 mailbox_number,
   /* [IN] message ID */
   uint_32 identifier,
   /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
   uint_32 format,
   /* [IN] number of bytes to write to the mailbox (0 to 8) */
   uint_32 data_len_code,
   /* [IN] Location to store the data from the mailbox */
   pointer data
)
{ /* Body */

   volatile CAN_MemMapPtr  can_reg_ptr;
   uint_32                 i;
   vuint_32                temp16;
   vuint_32                code;
   uchar_ptr               mb_data_array;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   if (8 < data_len_code)
   {
      return (FLEXCAN_DATA_SIZE_ERROR);
   }

   /* Set the ID according the format structure */
   if ( format == FLEXCAN_EXTENDED )
   {
      /* Set IDE */
      can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_IDE_MASK;

      /* Set SRR bit */
      can_reg_ptr->MB[mailbox_number].CS |= CAN_CS_SRR_MASK;

      /* Start CR# 1730 */
      can_reg_ptr->MB[mailbox_number].ID &= ~(0x1FFFFFFF);
      can_reg_ptr->MB[mailbox_number].ID |= (identifier & 0x1FFFFFFF);
   }
   else if( format == FLEXCAN_STANDARD )
   {
      /* make sure IDE and SRR are not set */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_IDE_MASK | CAN_CS_SRR_MASK);

      /* ID[28-18] */
      can_reg_ptr->MB[mailbox_number].ID &= ~CAN_ID_STD_MASK;
      can_reg_ptr->MB[mailbox_number].ID |= CAN_ID_STD(identifier);
   }
   else
   {
      return (FLEXCAN_MESSAGE_FORMAT_UNKNOWN);
   }/* Endif */


   mb_data_array = (uchar_ptr) &can_reg_ptr->MB[mailbox_number].WORD0;
   /*
   ** Copy user's buffer into mailbox data area
   */
   for ( i=0 ; i < data_len_code ; i++ )
   {
      mb_data_array[3 - (i&0x3) + (i&0x4)] = ((uchar_ptr)data)[i];
   } /* Endfor */

   data_len_code <<= CAN_CS_DLC_SHIFT;
   /*
   ** Set data up for send
   ** send is automatic when remote message is received
   ** send when message buffer is not active
   */
   code = can_reg_ptr->MB[mailbox_number].CS;
   if( (code & CAN_CS_CODE_MASK ) == CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE) )
   {
      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);
      /* Clear the DLC */
      can_reg_ptr->MB[mailbox_number].CS &= ~CAN_CS_DLC_MASK;
      can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_ONCE) | data_len_code);
   }

   /* Update data to respond to remote request frame */
   if( ((code & CAN_CS_CODE_MASK) == CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_RESPONED_ONLY)) ||
       ((code & CAN_CS_CODE_MASK) == CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_RESPONED)) )
   {
      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);
      /* Clear the DLC */
      can_reg_ptr->MB[mailbox_number].CS &= ~CAN_CS_DLC_MASK;
      can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_RESPONED) | data_len_code);
   }

   /* Unlock message buffer */
   temp16 = can_reg_ptr->TIMER;

   return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Read
* Returned Value   : uint_32
* Comments         :
*    This function reads the contents of the specified CAN memory.
*
*END*********************************************************************/
uint_32 FLEXCAN_Read
(
   /* [IN] FlexCAN device number */
    uint_8 dev_num,
   /* [IN] offset from the base address of the device */
    uint_32         offset,
   /* [IN/OUT] pointer to location of where the data is to be read to */
    uint_32_ptr     data_ptr
)
{ /* Body */

   volatile CAN_MemMapPtr  can_reg_ptr;
   uint_32                 read_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   read_ptr = (vuint_32)can_reg_ptr + offset;
   *data_ptr = (uint_32) *(uchar_ptr)read_ptr;

   return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Write
* Returned Value   : uint_32
* Comments         :
*    This function writes the specified value to the specified CAN
*    memory.
*
*END*********************************************************************/
uint_32 FLEXCAN_Write
(
   /* [IN] FlexCAN device number */
    uint_8 dev_num,
   /* [IN] offset from the base address of the device */
    uint_32     offset,
   /* Data to be written at the start of the offset */
    uint_32     value
)
{ /* Body */

   volatile CAN_MemMapPtr  can_reg_ptr;
   vuint_32                write_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   write_ptr = (uint_32)can_reg_ptr + offset;
   *(uchar_ptr)write_ptr = (uchar)value;

   return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_Get_status
* Returned Value   : uint_32
* Comments         :
*    This function gets the CAN chip in the specified state.
*
*END*********************************************************************/
uint_32 FLEXCAN_Get_status
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN/OUT] pointer to Error/Status registry */
   uint_32_ptr can_status
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   *can_status = can_reg_ptr->ESR1;

   return(FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : FLEXCAN_update_message
* Returned Value   : uint_32
* Comments         :
*    This function updates data as a response to a remote frame.
*
*END*********************************************************************/
uint_32 FLEXCAN_Update_message
(
   /* [IN] FlexCAN device number */
   uint_8 dev_num,
   /* [IN] pointer to data */
   pointer data_ptr,
   /* [IN] number of bytes to write to the mailbox (0 to 8) */
   uint_32 data_len_code,
   /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
   uint_32 format,
   /* [IN] mailbox number */
   uint_32 mailbox_number
)
{ /* Body */
   volatile CAN_MemMapPtr  can_reg_ptr;
   uint_32                 i;
   uchar_ptr               data_array;
   vuint_32                code;
   uchar_ptr               mb_data_array;

   can_reg_ptr = _bsp_get_flexcan_base_address (dev_num);
   if (NULL == can_reg_ptr)
   {
      return (FLEXCAN_INVALID_ADDRESS);
   }

   if ( mailbox_number > (CAN_MCR_MAXMB (0xFFFFFFFF)) )
   {
      return (FLEXCAN_INVALID_MAILBOX);
   }

   if (8 < data_len_code)
   {
      return (FLEXCAN_DATA_SIZE_ERROR);
   }

   /* check for RTR bit */
   code = can_reg_ptr->MB[mailbox_number].CS;
   if( (code & CAN_CS_RTR_MASK) == CAN_CS_RTR_MASK)
      return FLEXCAN_RTR_NOT_SET;

   /* check if mailbox is set for transmit */
   if( (code & CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE)) == CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE))
   {
      /* Reset the code */
      can_reg_ptr->MB[mailbox_number].CS &= ~(CAN_CS_CODE_MASK);

      /* store data */
      mb_data_array = (uchar_ptr) &can_reg_ptr->MB[mailbox_number].WORD0;
      data_array = (uchar_ptr) data_ptr;
      for(i=0; i<data_len_code; i++)
      {
         mb_data_array[3 - (i&0x3) + (i&0x4)] = data_array[i];;
      }

      /*
      ** Data frame to be transmitted only as a response to
      ** a remote frame. code 0b1010
      */
      can_reg_ptr->MB[mailbox_number].CS |= (CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_RESPONED) | data_len_code);
    }
    else
        return FLEXCAN_INVALID_MAILBOX;

   return FLEXCAN_OK;

} /* Endbody */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/httpd/httpd_prv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: httpd_prv.h$
* $Version : 3.7.1.0$
* $Date    : Mar-9-2011$
*
* Comments:
*
*   Header for HTTPD.
*
*END************************************************************************/

#ifndef HTTPD_PRV_H_
#define HTTPD_PRV_H_

#include "httpd_types.h"
#include "httpd_supp.h"


#define HTTPD_SERVER_STACK_SIZE     (1000)
#define HTTPD_MIN_SES_STACK_SIZE    (2500)


typedef struct {
    HTTPD_STRUCT *server;
    uint_32 sock;
} HTTPD_SES_TASK_PARAM;

void httpd_poll(HTTPD_STRUCT *server);
//_mqx_int httpd_get_varval(HTTPD_SESSION_STRUCT *session, char *var_str, char *var_name, char *var_val, _mqx_int var_val_len);
void httpd_ses_process(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session);


HTTPD_SESSION_STRUCT* httpd_ses_alloc(HTTPD_STRUCT *server);

/** Release session - free memory allocated by session.
 * \param session < pointer to session
 */
void httpd_ses_free(HTTPD_SESSION_STRUCT *session);


void httpd_ses_poll(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session/*, int loop*/);

void httpd_ses_init(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session, const int sock);


#endif /* HTTP_PRV_H_ */


<|start_filename|>Firmware/Inverter_bootloader/APP/Y_Loader.h<|end_filename|>
#ifndef __LOADER
  #define __LOADER


  #define ABORT_SESSION           (-1)
  #define FIRST_PACKET            0
  #define NEXT_PACKET             1
  #define SKIP_SESSION           (-2)

  #define PACKET_SEQNO_INDEX      (1)
  #define PACKET_SEQNO_COMP_INDEX (2)

  #define PACKET_HEADER           (3)
  #define PACKET_TRAILER          (2)
  #define PACKET_OVERHEAD         (PACKET_HEADER + PACKET_TRAILER)
  #define PACKET_128B_SIZE             (128)
  #define PACKET_1K_SIZE          (1024)

  #define FILE_NAME_LENGTH        (32)
  #define FILE_SIZE_LENGTH        (16)

  #define SOH                     (0x01)  /* start of 128-byte data packet */
  #define STX                     (0x02)  /* start of 1024-byte data packet */
  #define EOT                     (0x04)  /* end of transmission */
  #define ACK                     (0x06)  /* acknowledge */
  #define NAK                     (0x15)  /* negative acknowledge */
  #define CA                      (0x18)  /* two of these in succession aborts transfer */
  #define CRC16                   (0x43)  /* 'C' == 0x43, request 16-bit CRC */

  #define ABORT1                  (0x41)  /* 'A' == 0x41, abort by user */
  #define ABORT2                  (0x61)  /* 'a' == 0x61, abort by user */

  #define NAK_TIMEOUT             (5000)   // В тактах по 10 мс
  #define MAX_ERRORS              (5)

INT32S Ymodem_programmator (void);
void   Send_byte(unsigned char byte);
int    Wait_byte(unsigned char *ptr_c, unsigned int timeout);


#endif



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sai/int/sai_int_ksai.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sai_int_ksai.c$
* $Version : 3.8.10.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains low level functions for the SAI interrupt device driver
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "sai_int_prv.h"
#include "sai_ksai_prv.h"

#if PSP_MQX_CPU_IS_VYBRID // BEGIN - Platform specific macros + functions for Vybrid

#define PLL_DIV_MAX 16
#define SAI_DIV_MAX 16
#define I2S_RX_FIFO_FULL_MASK 0x20
/*
** Values of Vybrid watermarks are set to 
** experimentally tested default values.
*/
#define I2S_TX_FIFO_DEFAULT_WATERMARK 8 
#define I2S_RX_FIFO_DEFAULT_WATERMARK 25

#define I2S_RX_WRITE_PTR_MASK 0x1F
#define I2S_RX_READ_PTR_MASK  0x1F
#define I2S_TX_WRITE_PTR_MASK 0x1F
#define I2S_TX_READ_PTR_MASK  0x1F

static uint_32 _vi2s_get_mclk_value(KSAI_INFO_STRUCT_PTR io_info_ptr);
static void _vi2s_set_mclk_freq(KSAI_INFO_STRUCT_PTR io_info_ptr, uint_32 freq);
static void _vi2s_set_clk_src_int(uint_8 hw_channel);
static void _vi2s_set_clk_src_ext(uint_8 hw_channel);
static void _vi2s_set_sai_div(uint_8 hw_channel, uint_8 value);
#else //  Platform specific macros + functions for Kinetis

#define I2S_RX_FIFO_FULL_MASK 0x10
/*
** Values of Kinetis watermarks are set to 
** experimentally tested default values.
*/
#define I2S_TX_FIFO_DEFAULT_WATERMARK 3
#define I2S_RX_FIFO_DEFAULT_WATERMARK 4

#define I2S_RX_WRITE_PTR_MASK 0x7
#define I2S_RX_READ_PTR_MASK  0x7
#define I2S_TX_WRITE_PTR_MASK 0x7
#define I2S_TX_READ_PTR_MASK  0x7

static uint_32 _ki2s_get_mclk_value(KSAI_INFO_STRUCT_PTR io_info_ptr);
#endif // END - Platform specific macros

static void _ksai_tx_irq_handler(pointer);
static void _ksai_rx_irq_handler(pointer);
static void _ksai_rx_tx_irq_handler(pointer);

static void _ksai_hw_init(KSAI_INIT_STRUCT_PTR, I2S_MemMapPtr, _mqx_int);
static uint_32 _ksai_format_in_data(char_ptr input, AUDIO_DATA_FORMAT_PTR format);
static void _ksai_format_out_data(uint_32 input, char_ptr output, AUDIO_DATA_FORMAT_PTR format);
static uint_32 _ksai_sine_wave(uint_32, uint_32, int_16_ptr*);

static uint_32 _ksai_format_in_data(char_ptr input, AUDIO_DATA_FORMAT_PTR format);
static uint_32 _ki2s_find_mclk_freq_div(CM_CLOCK_SOURCE src, uint_16_ptr frct, uint_16_ptr div, uint_32 frequency);
static uint_32 _ki2s_set_master_mode(KSAI_INFO_STRUCT_PTR io_info_ptr, uint_8 mode);
static uint_32 _ki2s_set_slave_mode(KSAI_INFO_STRUCT_PTR io_info_ptr, uint_8 mode);
static uint_32 _ki2s_set_bclk_mode(I2S_MemMapPtr i2s_ptr, uint_8 bclk_mode);

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_int_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an SAI device.
*
*END*********************************************************************/

_mqx_int _ksai_int_init
(
    /* [IN] Initialization information for the device being opened */
    pointer io_dev_ptr
)
{   /* Body */
    IO_SAI_DEVICE_STRUCT_PTR    io_sai_dev_ptr = (IO_SAI_DEVICE_STRUCT_PTR)io_dev_ptr;
    KSAI_INIT_STRUCT_PTR        ksai_init_ptr = (KSAI_INIT_STRUCT_PTR)io_sai_dev_ptr->DEV_INIT_DATA_PTR;
    KSAI_INFO_STRUCT_PTR        ksai_info_ptr;
    I2S_MemMapPtr               i2s_ptr = NULL;
    _mqx_uint                   tx_vector, rx_vector, buffer_size;
    _mqx_uint                   result = 0;
    uint_8                      channel, mode, data_bits, clk_source, endianity, aligment, bits, size, channels, bclk_mode;
    
    /* Check init structure */
    if (ksai_init_ptr == NULL)
    {
        I2S_LOG("\n  _i2s_init: Error - ksai_init_ptr is NULL");
        return -1;
    }
    else
    {
        channel     = ksai_init_ptr->HW_CHANNEL;
        mode        = ksai_init_ptr->MODE;
        data_bits   = ksai_init_ptr->DATA_BITS;
        clk_source  = ksai_init_ptr->CLOCK_SOURCE;
        buffer_size = ksai_init_ptr->BUFFER_SIZE;
        endianity   = ksai_init_ptr->IO_FORMAT->ENDIAN;
        aligment    = ksai_init_ptr->IO_FORMAT->ALIGNMENT;
        bits        = ksai_init_ptr->IO_FORMAT->BITS;
        size        = ksai_init_ptr->IO_FORMAT->SIZE;
        channels    = ksai_init_ptr->IO_FORMAT->CHANNELS;
        bclk_mode   = ksai_init_ptr->CLOCK_MODE;
    }
    /* Check if valid data bit length is selected */
    if ((data_bits < AUDIO_BIT_SIZE_MIN) || (data_bits > AUDIO_BIT_SIZE_MAX))
    {
        I2S_LOG("\n  _i2s_init: Error - Unsupported data word length.");
        return (I2S_ERROR_WORD_LENGTH_UNSUPPORTED);
    }   
    /* Check mode of operation */
    if (mode > (I2S_TX_SLAVE | I2S_RX_SLAVE))
    {
        I2S_LOG("\n  _i2s_init: Error - Invalid I2S mode.");
        return(I2S_ERROR_MODE_INVALID);
    }
    /* Check clock source */
    if (clk_source > I2S_CLK_EXT)
    {
        I2S_LOG("\n  _i2s_init: Error - Invalid I2S clock source.");
        return(I2S_ERROR_CLK_INVALID);
    }
    /* Check buffer size */
    if (buffer_size < 2)
    {
        I2S_LOG("\n  _i2s_init: Error - I2S transmit buffer size too small.");
        return(I2S_ERROR_BUFFER_SMALL);
    }
    /* Check bit clock setting */
    if ((bclk_mode & I2S_TX_SYNCHRONOUS) && (bclk_mode & I2S_RX_SYNCHRONOUS))
    {
        I2S_LOG("\n  _i2s_init: Error - Invalid bit clock configuration selected.");
        return(I2S_ERROR_INVALID_BCLK);
    }
    /* Check audio data format */
    if (
        (aligment > AUDIO_ALIGNMENT_LEFT) || (bits < AUDIO_BIT_SIZE_MIN) ||
        (bits > AUDIO_BIT_SIZE_MAX) || (endianity > AUDIO_LITTLE_ENDIAN) ||
        (size * I2S_CHAR_BIT < bits) || (channels > 2) || (channels == 0)
       )
    {
        I2S_LOG("\n  _i2s_init: Error - Invalid I/O data format.");
        return(AUDIO_ERROR_INVALID_IO_FORMAT);
    }
    /* Check selected data channels */
    if (ksai_init_ptr->TX_CHANNEL >= SAI_DATA_CHANNELS)
    {
        I2S_LOG("\n  _i2s_init: Error - Invalid transmitter data channel selected.");
        return(I2S_ERROR_INVALID_TX_CHANNEL);
    }
    if (ksai_init_ptr->RX_CHANNEL >= SAI_DATA_CHANNELS)
    {
        I2S_LOG("\n  _i2s_init: Error - Invalid receiver data channel selected.");
        return(I2S_ERROR_INVALID_RX_CHANNEL);
    }
    /* Check if valid peripheral is selected */
    i2s_ptr = _bsp_get_sai_base_address(channel);
    if (i2s_ptr == NULL)
    {
        I2S_LOG("\n  _i2s_init: Error - Invalid hardware channel selected.");
        return(I2S_ERROR_CHANNEL_INVALID);
    }
    ksai_info_ptr = (KSAI_INFO_STRUCT_PTR) _mem_alloc_system_zero((uint_32) sizeof(KSAI_INFO_STRUCT));
    if (NULL == ksai_info_ptr)
    {
        I2S_LOG("\n  _i2s_init: Error - Allocation of KI2S_INFO_STRUCT failed.");
        return(MQX_OUT_OF_MEMORY);
    }
    _mem_set_type (ksai_info_ptr, MEM_TYPE_IO_I2S_INFO_STRUCT);
    
    /* If the device is not alreadz open do I/O initialization */
    if ((io_sai_dev_ptr->READ_COUNT == 0) && (io_sai_dev_ptr->WRITE_COUNT == 0))
    {
        /* SAI board specific IO pins initialization */
        _bsp_sai_io_init(channel);  
    }
    /* Copy clock source to context structure */
    ksai_info_ptr->MCLK_SRC = ksai_init_ptr->MCLK_SRC;
    /* SAI board specific registers initialization */
    _ksai_hw_init(ksai_init_ptr, i2s_ptr, io_sai_dev_ptr->FLAGS);

    /*Info struct setup*/
    ksai_info_ptr->INIT           = *ksai_init_ptr;
    ksai_info_ptr->SAI_PTR        = i2s_ptr;
    ksai_info_ptr->MODE           = ksai_init_ptr->MODE;
    ksai_info_ptr->DATA_BITS      = ksai_init_ptr->DATA_BITS;
    ksai_info_ptr->CLOCK_SOURCE   = ksai_init_ptr->CLOCK_SOURCE;
    ksai_info_ptr->CLOCK_MODE     = ksai_init_ptr->CLOCK_MODE;
    ksai_info_ptr->TX_CHANNEL     = ksai_init_ptr->TX_CHANNEL;
    ksai_info_ptr->RX_CHANNEL     = ksai_init_ptr->RX_CHANNEL;
    ksai_info_ptr->IO_MODE        = io_sai_dev_ptr->FLAGS;
    ksai_info_ptr->HW_CHANNEL     = channel;
        
    ksai_info_ptr->IO_FORMAT.ENDIAN       = endianity;
    ksai_info_ptr->IO_FORMAT.BITS         = bits;
    ksai_info_ptr->IO_FORMAT.ALIGNMENT    = aligment;
    ksai_info_ptr->IO_FORMAT.SIZE         = size;
    ksai_info_ptr->IO_FORMAT.CHANNELS     = channels;
    
    if (ksai_info_ptr->CLOCK_SOURCE == I2S_CLK_INT)
    {
#if PSP_MQX_CPU_IS_VYBRID
        ksai_info_ptr->MCLK_FREQ  = _vi2s_get_mclk_value(ksai_info_ptr);
#else
        ksai_info_ptr->MCLK_FREQ  = _ki2s_get_mclk_value(ksai_info_ptr);
#endif
        ksai_info_ptr->BCLK_FREQ  = ksai_info_ptr->MCLK_FREQ / DEFAULT_BCLK_DIV;
        ksai_info_ptr->FS_FREQ    = ksai_info_ptr->BCLK_FREQ / (ksai_info_ptr->DATA_BITS * ksai_info_ptr->IO_FORMAT.CHANNELS);
    }
    else
    {
        ksai_info_ptr->MCLK_FREQ  = 0;
        ksai_info_ptr->BCLK_FREQ  = 0;
        ksai_info_ptr->FS_FREQ    = 0;
    }

    ksai_info_ptr->BCLK_DIV = DEFAULT_BCLK_DIV;
    ksai_info_ptr->TX_DUMMY = ksai_init_ptr->TX_DUMMY;
    ksai_info_ptr->ONTHEWAY = FALSE;
    ksai_info_ptr->DATA = NULL;
    
    result = _lwsem_create(&(ksai_info_ptr->EVENT_IO_FINISHED), 0);
    if (result != MQX_OK) 
    {
        I2S_LOG("\n  _i2s_init: Error - Unable to create event_int_done.");
        _task_set_error(result);
    }
    
    ksai_info_ptr->DUMMY.DATA     = NULL;
    ksai_info_ptr->DUMMY.LENGTH   = 0;
    ksai_info_ptr->DUMMY.INDEX    = 0;
    ksai_info_ptr->CLK_ALWAYS_ON  = TRUE;
    ksai_info_ptr->FIRST_IO       = TRUE;
    
    /* Buffers allocation */
    ksai_info_ptr->BUFFER.DATA = (uint_32_ptr)_mem_alloc_system_zero(buffer_size * sizeof(uint_32));
    if (ksai_info_ptr->BUFFER.DATA == NULL)
    {
        return MQX_OUT_OF_MEMORY;
    }
    ksai_info_ptr->BUFFER.SPACE = buffer_size;
    ksai_info_ptr->BUFFER.SIZE  = buffer_size;    

    _mem_set_type (ksai_info_ptr->BUFFER.DATA, MEM_TYPE_IO_I2S_LEFT_BUFFER);
    
    io_sai_dev_ptr->DEV_INFO_PTR = ksai_info_ptr;

    /* Interrupt vectors setup */
    tx_vector = _bsp_get_sai_tx_vector(channel);
    rx_vector = _bsp_get_sai_rx_vector(channel);
    
    if (tx_vector == rx_vector)
    {
        ksai_info_ptr->OLD_TX_ISR_DATA = _int_get_isr_data(tx_vector);
        ksai_info_ptr->OLD_TX_ISR = _int_install_isr(tx_vector, _ksai_rx_tx_irq_handler, ksai_info_ptr);
        ksai_info_ptr->OLD_RX_ISR_DATA = ksai_info_ptr->OLD_TX_ISR_DATA;
        ksai_info_ptr->OLD_RX_ISR = ksai_info_ptr->OLD_TX_ISR;
        _bsp_int_init(tx_vector, ksai_info_ptr->INIT.LEVEL, 0, TRUE);
    }
    else
    {
        /* Interrupt Tx vector setup */
        if (io_sai_dev_ptr->FLAGS & I2S_IO_WRITE)
        {
            ksai_info_ptr->OLD_TX_ISR_DATA = _int_get_isr_data(tx_vector);
            ksai_info_ptr->OLD_TX_ISR = _int_install_isr(tx_vector, _ksai_tx_irq_handler, ksai_info_ptr);
            _bsp_int_init(tx_vector, ksai_info_ptr->INIT.LEVEL, 0, TRUE);
        }
        /* Interrupt Rx vector setup */
        if (io_sai_dev_ptr->FLAGS & I2S_IO_READ)
        {
            ksai_info_ptr->OLD_RX_ISR_DATA = _int_get_isr_data(rx_vector);
            ksai_info_ptr->OLD_RX_ISR = _int_install_isr(rx_vector, _ksai_rx_irq_handler, ksai_info_ptr);
            _bsp_int_init(rx_vector, ksai_info_ptr->INIT.LEVEL, 0, TRUE);
        }
    }

    return MQX_OK;
} /* End body */

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_int_deinit
* Returned Value   : MQX error code
* Comments         :
*    This function de-initializes an SAI device.
*
*END*********************************************************************/

_mqx_int _ksai_int_deinit
(
    /* [IN] Initialization information for the device being closed */
    pointer io_dev_ptr,
    
    pointer io_info_ptr
)
{
    IO_SAI_DEVICE_STRUCT_PTR    io_sai_dev_ptr = (IO_SAI_DEVICE_STRUCT_PTR)io_dev_ptr;
    KSAI_INFO_STRUCT_PTR        ksai_info_ptr = (KSAI_INFO_STRUCT_PTR)io_info_ptr;
    KSAI_INIT_STRUCT_PTR        sai_init_ptr;
    I2S_MemMapPtr               i2s_ptr;    
    _mqx_uint                   errcode;
    _mqx_uint                   result = 0;
    uint_8                      channel = ksai_info_ptr->HW_CHANNEL;
    
    if ((NULL == ksai_info_ptr) || (NULL == io_sai_dev_ptr))
    {
        I2S_LOG("\n  _i2s_deinit: Error - Null pointer.");
        return I2S_ERROR_INVALID_PARAMETER;
    }
    
    i2s_ptr = ksai_info_ptr->SAI_PTR;
    sai_init_ptr = (KSAI_INIT_STRUCT_PTR)(io_sai_dev_ptr->DEV_INIT_DATA_PTR);
        
    if (io_sai_dev_ptr->FLAGS & I2S_IO_WRITE)
    {
        /* Disable transmitter */
        i2s_ptr->TCSR &= ~I2S_TCSR_TE_MASK;
        /* Disable transmit channel */
        i2s_ptr->TCR3 &= ~I2S_TCR3_TCE_MASK;
        /* Disable transmitter bit clock */
        i2s_ptr->TCSR &= ~I2S_TCSR_BCE_MASK;
        /* Install original tx vectors */
        _bsp_int_init((IRQInterruptIndex) _bsp_get_sai_tx_vector(channel), sai_init_ptr->LEVEL, 0, TRUE);
        _int_install_isr(_bsp_get_sai_tx_vector(channel), ksai_info_ptr->OLD_TX_ISR, ksai_info_ptr->OLD_TX_ISR_DATA);
    }
    
    if ((ksai_info_ptr->OLD_TX_ISR != ksai_info_ptr->OLD_RX_ISR) && (io_sai_dev_ptr->FLAGS & I2S_IO_READ))
    {
        /* Disable receiver */
        i2s_ptr->RCSR &= ~I2S_RCSR_RE_MASK;
        /* Disable receiver channel */
        i2s_ptr->RCR3 &= ~I2S_RCR3_RCE_MASK;
        /* Disable receiver bit clock */
        i2s_ptr->RCSR &= ~I2S_RCSR_BCE_MASK;
        /* Install original rx vectors */
        _bsp_int_init((IRQInterruptIndex)_bsp_get_sai_rx_vector(channel), sai_init_ptr->LEVEL, 0, TRUE);
        _int_install_isr(_bsp_get_sai_rx_vector(channel), ksai_info_ptr->OLD_RX_ISR, ksai_info_ptr->OLD_RX_ISR_DATA);
    }
#if !PSP_MQX_CPU_IS_VYBRID
    i2s_ptr->MCR &= ~(I2S_MCR_MOE_MASK);
#endif
    /* Destroy event */
    result = _lwsem_destroy(&(ksai_info_ptr->EVENT_IO_FINISHED));

    if (result != MQX_OK)
    {
        I2S_LOG("\n  _i2s_deinit: Error - unable to destroy event_int_done.\n");
        _task_set_error(result);
    }
    
    ksai_info_ptr->ONTHEWAY = FALSE;
    
    /* Free buffers and info struct */
    errcode = _mem_free(ksai_info_ptr->BUFFER.DATA);
    if (errcode != MQX_OK)
    {
        I2S_LOG("\n  _i2s_deinit: Error - Free data buffer failed.");
        return errcode;
    }
    _mem_zero(&(ksai_info_ptr->BUFFER), sizeof(ksai_info_ptr->BUFFER));
        
    if (ksai_info_ptr->TX_DUMMY)
    {
        errcode = _mem_free (ksai_info_ptr->DUMMY.DATA);
        if (errcode != MQX_OK)
        {
            I2S_LOG("\n  _i2s_deinit: Error - Free dummy data failed.");
            return errcode;
        }
        ksai_info_ptr->DUMMY.DATA = NULL;
        _mem_zero(&(ksai_info_ptr->DUMMY), sizeof(ksai_info_ptr->DUMMY));
    }
    
    errcode = _mem_free(io_sai_dev_ptr->DEV_INFO_PTR);
    if (errcode != MQX_OK)
    {
        I2S_LOG("\n  _i2s_deinit: Error - Free device information pointer failed.");
        return errcode;
    }
    io_sai_dev_ptr->DEV_INFO_PTR = NULL;
    
    return(MQX_OK);
}

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_int_tx
* Returned Value   : number of bytes written
* Comments         :
*   Returns the number of bytes written.
*   Writes the data provided into transmition buffer if available.
*
*END*********************************************************************/

_mqx_int _ksai_int_tx
(
    /* [IN] the address of the device specific information */
    pointer io_dev_ptr, 
    
    /* [IN] The array to be read from */
    char_ptr buff, 
    
    /* [IN] number of packets to output */
    uint_32 length
)
{
    IO_SAI_DEVICE_STRUCT_PTR   io_sai_dev_ptr   = (IO_SAI_DEVICE_STRUCT_PTR)io_dev_ptr;
    KSAI_INFO_STRUCT_PTR       ksai_info_ptr    = (KSAI_INFO_STRUCT_PTR)io_sai_dev_ptr->DEV_INFO_PTR;
    I2S_MemMapPtr              i2s_ptr          = ksai_info_ptr->SAI_PTR;
    KSAI_BUFFER_PTR            buffer           = &(ksai_info_ptr->BUFFER);
    I2S_STATISTICS_STRUCT_PTR  stats            = &(ksai_info_ptr->STATS);
    AUDIO_DATA_FORMAT_PTR      io_format        = &(ksai_info_ptr->IO_FORMAT);
    LWSEM_STRUCT_PTR           event_int_done   = &(ksai_info_ptr->EVENT_IO_FINISHED);
    _mqx_uint                  result           = MQX_OK;
   
    if ((buff == NULL) && !(ksai_info_ptr->TX_DUMMY))
    {
        I2S_LOG("\n  _i2s_tx: Error - Null pointer.");
        _task_set_error(I2S_ERROR_INVALID_PARAMETER);
        return (0);
    }
    ksai_info_ptr->DATA = buff;
    
    /* Initialize statistics and buffers */    
    stats->PACKETS_REQUESTED += length / io_format->SIZE;
    /* In dummy mode, data are already in memory, so we don't have to buffer them */
    if (ksai_info_ptr->TX_DUMMY)
    {
        stats->PACKETS_QUEUED = stats->PACKETS_REQUESTED;
    }
    
    /* Set device into busy state */
    ksai_info_ptr->ONTHEWAY = TRUE;

    while(ksai_info_ptr->ONTHEWAY)
    {
        if (!(ksai_info_ptr->TX_DUMMY))
        {
            /* Copy data from input to buffer (reformat them when necessary) */
            while ((buffer->SPACE > 0) && (stats->PACKETS_QUEUED < stats->PACKETS_REQUESTED))
            {
                /* Disable interrupts with buffer access */
                i2s_ptr->TCSR &= ~(I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK);
                buffer->DATA[buffer->IN++] = _ksai_format_in_data(ksai_info_ptr->DATA, io_format);
                buffer->SPACE--;
                stats->PACKETS_QUEUED++;
                ksai_info_ptr->DATA += io_format->SIZE;
                (buffer->IN >= buffer->SIZE) ? (buffer->IN = 0) : (0);
                /* Enable interrupts */
                if (!(ksai_info_ptr->FIRST_IO))
                {
                    i2s_ptr->TCSR |= (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK);                  
                }
            }
        }
        if (ksai_info_ptr->FIRST_IO)
        {
            ksai_info_ptr->FIRST_IO = FALSE;
            /* Invert transmiter frame sync in TX mode */
            i2s_ptr->TCR4 |= (I2S_TCR4_FSP_MASK);
            
            /* First transmit operation - enable transmitter */
            i2s_ptr->TCSR |= (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK);
            i2s_ptr->TCSR |= (I2S_TCSR_TE_MASK);
            /* 
            ** We have to enable receiver in order to get clock signals (BCLK and FS)
            ** if transmitter is synchronous.
            */
            if (ksai_info_ptr->CLOCK_MODE & I2S_TX_SYNCHRONOUS)
            {
                i2s_ptr->RCSR |= (I2S_RCSR_RE_MASK);
                
            }
        }

        /* If all requested packets are queued break and return from function */
        if (stats->PACKETS_QUEUED >= stats->PACKETS_REQUESTED)
        {
            break;
        }
        
        /* Wait for transmit finish (task is blocked during wait) */
        result = _lwsem_wait(event_int_done);
        if (result != MQX_OK)
        {
            I2S_LOG("\n  _i2s_tx: Error - Wait for event_int_done failed.\n");
            _task_set_error(result);
        }
    }
    /* return number of processed data */
    return ((length / io_format->SIZE) * io_format->SIZE);
}

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_int_rx
* Returned Value   : number of bytes read
* Comments         :
*   Returns the number of bytes received.
*   Reads the data into provided array when data is available.
*
*END*********************************************************************/

_mqx_int _ksai_int_rx
(
    /* [IN] the address of the device specific information */
    pointer io_dev_ptr, 
    
    /* [IN] The array to copy data into */
    char_ptr buff, 
    
    /* [IN] number of bytes to read */
    uint_32 length
) 
{
    IO_SAI_DEVICE_STRUCT_PTR   io_sai_dev_ptr   = (IO_SAI_DEVICE_STRUCT_PTR)io_dev_ptr;
    KSAI_INFO_STRUCT_PTR       ksai_info_ptr    = (KSAI_INFO_STRUCT_PTR)io_sai_dev_ptr->DEV_INFO_PTR;
    I2S_MemMapPtr              i2s_ptr          = ksai_info_ptr->SAI_PTR;
    KSAI_BUFFER_PTR            buffer           = &(ksai_info_ptr->BUFFER);
    I2S_STATISTICS_STRUCT_PTR  stats            = &(ksai_info_ptr->STATS);
    AUDIO_DATA_FORMAT_PTR      io_format        = &(ksai_info_ptr->IO_FORMAT);
    LWSEM_STRUCT_PTR           event_int_done   = &(ksai_info_ptr->EVENT_IO_FINISHED);
    _mqx_uint                  result           = MQX_OK;

    if (buff == NULL)
    {
        I2S_LOG("\n  _i2s_rx: Error - Null pointer.");
        _task_set_error(I2S_ERROR_INVALID_PARAMETER);
        return (0);
    }
    
    ksai_info_ptr->DATA = buff;
        
    /* Initialize statistics and buffers to default values */    
    stats->PACKETS_REQUESTED += length / io_format->SIZE;

    ksai_info_ptr->ONTHEWAY = TRUE;
    
    while(ksai_info_ptr->ONTHEWAY)
    {
        /* Enable receiver and interrupts in case of first run to get some data */
        if (ksai_info_ptr->FIRST_IO) 
        {
            ksai_info_ptr->FIRST_IO = FALSE;
            /* First receive operation - enable receiver */
            i2s_ptr->RCSR |= (I2S_RCSR_FRIE_MASK | I2S_RCSR_FEIE_MASK);
            i2s_ptr->RCSR |= (I2S_RCSR_RE_MASK);
            /* 
            ** We have to enable transmitter in order to get clock signals 
            ** (BCLK and FS) if the receiver is synchronous.
            */
            if (ksai_info_ptr->CLOCK_MODE & I2S_RX_SYNCHRONOUS)
            {
                i2s_ptr->TCSR |= (I2S_TCSR_TE_MASK);
                i2s_ptr->TCR4 &= ~(I2S_TCR4_FSP_MASK); 
            }
        }
        /* Wait for receive finish */
        result = _lwsem_wait(event_int_done);
        
        if (result != MQX_OK)
        {
            I2S_LOG("\n  _i2s_rx: Error - Wait for event_int_done failed.");
            _task_set_error(result);
        }

        while ((buffer->SPACE < buffer->SIZE) &&
               (stats->PACKETS_PROCESSED < stats->PACKETS_REQUESTED))
        {
            /* Disable interrupts with buffer access */
            i2s_ptr->RCSR &= ~(I2S_RCSR_FRIE_MASK | I2S_RCSR_FEIE_MASK);
            (buffer->OUT >= buffer->SIZE) ? (buffer->OUT = 0) : (0);
            _ksai_format_out_data(buffer->DATA[buffer->OUT], ksai_info_ptr->DATA, io_format);
            buffer->OUT++;
            ksai_info_ptr->DATA += io_format->SIZE;
            stats->PACKETS_PROCESSED++;
            buffer->SPACE++;
            /* Enable interrupts */
            i2s_ptr->RCSR |= (I2S_RCSR_FRIE_MASK | I2S_RCSR_FEIE_MASK);
        }
        
        if (stats->PACKETS_PROCESSED >= stats->PACKETS_REQUESTED)
        {
            break;
        }
    }
    
    
    return ((length / io_format->SIZE) * io_format->SIZE);
}

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_tx_irq_handler
* Returned Value   : void
* Comment          :
*   TX interrupt handler of SAI driver
*
*END*********************************************************************/

void _ksai_tx_irq_handler
(
    /* [IN] Parameter pointer */
    pointer param
)
{
    KSAI_INFO_STRUCT_PTR       ksai_info_ptr = (KSAI_INFO_STRUCT_PTR) param;
    I2S_MemMapPtr              i2s_ptr = ksai_info_ptr->SAI_PTR;
    KSAI_BUFFER_PTR            buffer = &(ksai_info_ptr->BUFFER);
    I2S_STATISTICS_STRUCT_PTR  stats = &(ksai_info_ptr->STATS);
    KSAI_DUMMY_DATA_PTR        dummy = &(ksai_info_ptr->DUMMY);
    uint_32                    i = 0;
    uint_32                    space;
    uint_8                     tx_channel = ksai_info_ptr->TX_CHANNEL;
    uint_32                    read_ptr;
    uint_32                    write_ptr;
    boolean                    stop = FALSE;

    stats->INTERRUPTS++;
    
    /* Check FIFO error flag */
    if (i2s_ptr->TCSR & I2S_TCSR_FEF_MASK)
    {
        /* Reset FIFO */
        i2s_ptr->TCSR |= I2S_TCSR_FR_MASK;
        stats->FIFO_ERROR++;
    }
    
    read_ptr = (i2s_ptr->TFR[tx_channel] & I2S_TFR_RFP_MASK) >> I2S_TFR_RFP_SHIFT;
    write_ptr = (i2s_ptr->TFR[tx_channel] & I2S_TFR_WFP_MASK) >> I2S_TFR_WFP_SHIFT;
    
    /* All data transmitted, disable transmitter */
    if ((stats->PACKETS_PROCESSED >= stats->PACKETS_REQUESTED) &&  /* All data send       */ 
        (read_ptr == write_ptr))                                   /* FIFO is empty       */
    {
        ksai_info_ptr->ONTHEWAY = FALSE;
        ksai_info_ptr->FIRST_IO = TRUE;
        /* Disable interrupts and transmitter */
        i2s_ptr->TCSR &= ~(I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK); 
        i2s_ptr->TCSR &= ~(I2S_TCSR_TE_MASK);
        stop = TRUE; 
    }
 
    /* Check FIFO request flag */
    if (i2s_ptr->TCSR & I2S_TCSR_FRF_MASK)
    {   
        if (write_ptr == read_ptr) /* FIFO is empty */
        {
            space = SIZE_OF_FIFO;
        }
        else /* FIFO is not empty */
        {
            int result; 
            
            result = (write_ptr & I2S_TX_WRITE_PTR_MASK) - (read_ptr & I2S_TX_READ_PTR_MASK);
            space = (result < 0) ? -(unsigned)result : result;
        }
        /* Copy data from buffer to FIFO */
        for (i = 0; (i < space) && (stats->PACKETS_PROCESSED < stats->PACKETS_QUEUED); i++)
        {
            if (ksai_info_ptr->TX_DUMMY)
            {
                i2s_ptr->TDR[ksai_info_ptr->TX_CHANNEL] = dummy->DATA[dummy->INDEX] & 0xFFFFFFFF;
                (i % 2) ? (dummy->INDEX++) : (0);
                (dummy->INDEX >= dummy->LENGTH) ? (dummy->INDEX = 0) : (0);
                stats->PACKETS_PROCESSED++;
            }
            else
            {
                i2s_ptr->TDR[ksai_info_ptr->TX_CHANNEL] = buffer->DATA[buffer->OUT++];
                (buffer->OUT >= buffer->SIZE) ? (buffer->OUT = 0) : (0);
                stats->PACKETS_PROCESSED++;
            }
        }
        /* Check software buffer underrun */
        if ((!stop) && (i == 0)) 
        {
            stats->BUFFER_ERROR++;
        }
        stats->TX_PACKETS += i;
        buffer->SPACE += i;
    }
    /* Clear Word start flag */
    i2s_ptr->TCSR |= I2S_TCSR_WSF_MASK; 
    /* Data are ready in FIFO - clear error flag */
    i2s_ptr->TCSR |= I2S_TCSR_FEF_MASK;
    
    if (_lwsem_post(&(ksai_info_ptr->EVENT_IO_FINISHED)) != MQX_OK)
    {
        I2S_LOG("\n  i2s_tx_irq_handler: Error - Unable to set EVENT_IO_FINISHED.");
    }
}

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_rx_irq_handler
* Returned Value   : void
* Comment          :
*   RX interrupt handler of SAI driver
*
*END*********************************************************************/

void _ksai_rx_irq_handler
(
    /* [IN] Parameter pointer */
    pointer param
) 
{
    KSAI_INFO_STRUCT_PTR       ksai_info_ptr = (KSAI_INFO_STRUCT_PTR)param;
    I2S_MemMapPtr              i2s_ptr = ksai_info_ptr->SAI_PTR;
    KSAI_BUFFER_PTR            buffer = &(ksai_info_ptr->BUFFER);
    I2S_STATISTICS_STRUCT_PTR  stats = &(ksai_info_ptr->STATS);
    uint_32                    i = 0;
    uint_32                    data_n;
    uint_8                     rx_channel = ksai_info_ptr->RX_CHANNEL;
    uint_32                    read_ptr;
    uint_32                    write_ptr;
    boolean                    stop = FALSE;
    
    stats->INTERRUPTS++;
    
    read_ptr = i2s_ptr->RFR[rx_channel] & I2S_RFR_RFP_MASK;
    write_ptr = (i2s_ptr->RFR[rx_channel] & I2S_RFR_WFP_MASK) >> I2S_RFR_WFP_SHIFT;
    
    /* Check FIFO request flag */
    if (i2s_ptr->RCSR & I2S_RCSR_FRF_MASK)
    { 
        /* FIFO is full */
        if ((write_ptr ^ read_ptr) == I2S_RX_FIFO_FULL_MASK)
        {
            data_n = SIZE_OF_FIFO;
        }

        else /* FIFO is not full */
        {
            int result;

            result = (write_ptr & I2S_RX_WRITE_PTR_MASK) - (read_ptr & I2S_RX_READ_PTR_MASK);
            data_n = (result < 0) ? -(unsigned)result : result;
        }
        /* Copy data from FIFO to buffer */
        if (data_n + stats->PACKETS_QUEUED >= stats->PACKETS_REQUESTED)
        {
            data_n = stats->PACKETS_REQUESTED - stats->PACKETS_QUEUED;
        }
        /* Check software buffer overrun */
        if (data_n > buffer->SPACE)
        { 
            data_n = buffer->SPACE;
            stats->BUFFER_ERROR++;
        }
        for (i = 0; i < data_n; i++)
        {
            (buffer->IN >= buffer->SIZE) ? (buffer->IN = 0) : (0);
            buffer->DATA[buffer->IN++] = i2s_ptr->RDR[ksai_info_ptr->RX_CHANNEL];
        }
        buffer->SPACE -= i;
        stats->PACKETS_QUEUED += i; 
        stats->RX_PACKETS += i;
    }
    
    /* Check FIFO error flag */
    if (i2s_ptr->RCSR & I2S_RCSR_FEF_MASK)
    {
        /* Reset FIFO */
        i2s_ptr->RCSR |= I2S_RCSR_FEF_MASK;
        i2s_ptr->RCSR |= I2S_RCSR_FR_MASK;
        stats->FIFO_ERROR++;
    }
    /* All data received, disable receiver */
    if (stats->PACKETS_QUEUED >= stats->PACKETS_REQUESTED)
    {
        ksai_info_ptr->ONTHEWAY = FALSE;
        ksai_info_ptr->FIRST_IO = TRUE;
        
        /* Disable interrupts and receiver */
        i2s_ptr->RCSR &= ~(I2S_RCSR_FRIE_MASK | I2S_RCSR_FEIE_MASK); 
        i2s_ptr->RCSR &= ~(I2S_RCSR_RE_MASK);
    }

    if (_lwsem_post(&(ksai_info_ptr->EVENT_IO_FINISHED)) != MQX_OK)
    {
        I2S_LOG("\n  i2s_rx_irq_handler: Error - Unable to set EVENT_IO_FINISHED.");
    }
}

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_rx_tx_irq_handler
* Returned Value   : void
* Comment          :
*       Interrupt handler of SAI driver. Used when only one interrupt is 
*       available.
*
*END*********************************************************************/

void _ksai_rx_tx_irq_handler
(
    /* [IN] Parameter pointer */
    pointer param
)
{
    KSAI_INFO_STRUCT_PTR       ksai_info_ptr = (KSAI_INFO_STRUCT_PTR) param;
    I2S_MemMapPtr              i2s_ptr = ksai_info_ptr->SAI_PTR;
    
    if ((i2s_ptr->TCSR & (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK)) &&
        (i2s_ptr->TCSR & (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
    {
        _ksai_tx_irq_handler(param);
    }
    
    if ((i2s_ptr->RCSR & (I2S_RCSR_FRIE_MASK | I2S_RCSR_FEIE_MASK)) && 
        (i2s_ptr->RCSR & (I2S_RCSR_FRF_MASK | I2S_RCSR_FEF_MASK)))
    {
        _ksai_rx_irq_handler(param);
    }
}


/*FUNCTION****************************************************************
*
* Function Name    : _ksai_int_ioctl
* Returned Value   : MQX error code.
* Comments         :
*    This function performs miscellaneous services for
*    the SAI I/O device.
*
*END*********************************************************************/

_mqx_int _ksai_int_ioctl
(
    /* [IN] the address of the device specific information */
    pointer     io_sai_dev_ptr, 
    
    /* [IN] The command to perform */
    _mqx_int    cmd, 
    
    /* [IN] Parameters for the command */
    pointer     param
)
{
    KSAI_INFO_STRUCT_PTR io_info_ptr = (KSAI_INFO_STRUCT_PTR) io_sai_dev_ptr;
    KSAI_DUMMY_DATA_PTR dummy = &io_info_ptr->DUMMY;
    I2S_MemMapPtr i2s_ptr = io_info_ptr->SAI_PTR;
    uint_32 result = MQX_OK;
    uint_32 sample_rate = 0;
    uint_8 bclk_mode = 0;
    switch (cmd)
    {
        case IO_IOCTL_I2S_SET_MODE_MASTER:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break; 
            }
            if (io_info_ptr->ONTHEWAY)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Device is busy.");
                result = I2S_ERROR_DEVICE_BUSY;
                break;
            }
            result = _ki2s_set_master_mode(io_info_ptr, *((uint_8_ptr) param));
            if (result != MQX_OK)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid RX/TX master mode combination selected.");
                break;
            }
            break;
            
        case IO_IOCTL_I2S_SET_MODE_SLAVE:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break; 
            }
            if (io_info_ptr->ONTHEWAY)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Device is busy.");
                result = I2S_ERROR_DEVICE_BUSY;
                break;
            }
            result = _ki2s_set_slave_mode(io_info_ptr, *((uint_8_ptr) param));
            if (result != MQX_OK)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid RX/TX slave mode combination selected.");
                break;
            }
            break;
            
        case IO_IOCTL_I2S_SET_CLOCK_SOURCE_INT:
            if (io_info_ptr->ONTHEWAY)
            {
               I2S_LOG("\n  _i2s_ioctl: Error - Cannot change I2S clock source while I/O actions are in progress.");
               result = I2S_ERROR_DEVICE_BUSY;
               break;
            }
            /* Clock source should not change, when in slave mode */
            if ((io_info_ptr->MODE & I2S_TX_SLAVE) || (io_info_ptr->MODE & I2S_RX_SLAVE))
            {
               I2S_LOG("\n  _i2s_ioctl: Error - Cannot chnage I2S clock source while in slave mode.");
               result = IO_ERROR_INVALID_IOCTL_CMD;
               break;
            }
            
            io_info_ptr->CLOCK_SOURCE = I2S_CLK_INT;
            /* Set master clock to be generated internally */
#if PSP_MQX_CPU_IS_VYBRID
            _vi2s_set_clk_src_int(io_info_ptr->HW_CHANNEL);
            io_info_ptr->MCLK_FREQ = _vi2s_get_mclk_value(io_info_ptr);
#else
            i2s_ptr->MCR |= (I2S_MCR_MOE_MASK);
            io_info_ptr->MCLK_FREQ = _ki2s_get_mclk_value(io_info_ptr);
#endif       
            io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_DIV;
            io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * 2/*io_info_ptr->IO_FORMAT.CHANNELS*/);
            break;
            
        case IO_IOCTL_I2S_SET_CLOCK_SOURCE_EXT:
            if (io_info_ptr->ONTHEWAY)
            {
               I2S_LOG("\n  _i2s_ioctl: Error - Cannot chnage I2S clock source while I/O actions are in progress.");
               result = I2S_ERROR_DEVICE_BUSY;
               break;
            }
            /* You should not change clock source, when in slave mode */
            if ((io_info_ptr->MODE & I2S_TX_SLAVE) || (io_info_ptr->MODE & I2S_RX_SLAVE))
            {
               I2S_LOG("\n  _i2s_ioctl: Error - Cannot chnage I2S clock source while in slave mode.");
               result = IO_ERROR_INVALID_IOCTL_CMD;
               break;
            }
            
            io_info_ptr->CLOCK_SOURCE = I2S_CLK_EXT;
            /* Set master clock to be generated externally */
#if PSP_MQX_CPU_IS_VYBRID
            _vi2s_set_clk_src_ext(io_info_ptr->HW_CHANNEL);
#else
            i2s_ptr->MCR &= ~(I2S_MCR_MOE_MASK);
#endif
            io_info_ptr->MCLK_FREQ = 0;
            io_info_ptr->BCLK_FREQ = 0;
            io_info_ptr->FS_FREQ = 0;
            break;
            
        case IO_IOCTL_I2S_SET_DATA_BITS:
            if(io_info_ptr->ONTHEWAY)
            {
               I2S_LOG("\n  _i2s_ioctl: Error - Cannot chnage I2S data bit length while I/O actions are in progress.");
               result = I2S_ERROR_DEVICE_BUSY;
               break;
            }
            if (param == NULL)
            {
                 result = I2S_ERROR_INVALID_PARAMETER;
            }
            else
            {
               uint_8 data_bits =  *((uint_8_ptr) param);
               if ((data_bits < 8) || (data_bits > 32))
               {
                  I2S_LOG("\n  _i2s_ioctl: Error - Unsupported data word length.\n");
                  result = I2S_ERROR_WORD_LENGTH_UNSUPPORTED;
                  break;
               }
               io_info_ptr->DATA_BITS = data_bits;
               /* Setup transmitter */
               if ((io_info_ptr->IO_MODE & I2S_IO_WRITE) || (io_info_ptr->CLOCK_MODE & I2S_RX_SYNCHRONOUS))
               {
                   /* Set 0th word length */
                   i2s_ptr->TCR5 &= ~(I2S_TCR5_W0W_MASK);
                   i2s_ptr->TCR5 |= I2S_TCR5_W0W(data_bits-1);
                   /* Set Nth word length */
                   i2s_ptr->TCR5 &= ~(I2S_TCR5_WNW_MASK);
                   i2s_ptr->TCR5 |= I2S_TCR5_WNW(data_bits-1);
                   /* Set first bit shifted to highest index in register */
                   i2s_ptr->TCR5 &= ~(I2S_TCR5_FBT_MASK);
                   i2s_ptr->TCR5 |= I2S_TCR5_FBT(data_bits);
                   /* Set sync width to match word length */
                   i2s_ptr->TCR4 &= ~(I2S_TCR4_SYWD_MASK);
                   i2s_ptr->TCR4 |= I2S_TCR4_SYWD(data_bits-1); 
               }
               /* Setup receiver */
               if ((io_info_ptr->IO_MODE & I2S_IO_READ) || (io_info_ptr->CLOCK_MODE & I2S_TX_SYNCHRONOUS))
               {
                   /* Set 0th word length */
                   i2s_ptr->RCR5 &= ~(I2S_RCR5_W0W_MASK);
                   i2s_ptr->RCR5 |= I2S_RCR5_W0W(data_bits-1);
                   /* Set Nth word length */
                   i2s_ptr->RCR5 &= ~(I2S_RCR5_WNW_MASK);
                   i2s_ptr->RCR5 |= I2S_RCR5_WNW(data_bits-1);
                   /* Set first bit shifted to highest index in register */
                   i2s_ptr->RCR5 &= ~(I2S_RCR5_FBT_MASK);
                   i2s_ptr->RCR5 |= I2S_RCR5_FBT(data_bits-1);
                   /* Set sync width to match word length */
                   i2s_ptr->RCR4 &= ~(I2S_RCR4_SYWD_MASK);
                   i2s_ptr->RCR4 |= I2S_RCR4_SYWD(data_bits-1);  
               }
               /* Recalculate frame sync frequency to match settings */
               io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * 2/*io_info_ptr->IO_FORMAT.CHANNELS*/);
            }
            break;
            
        case IO_IOCTL_I2S_DISABLE_DEVICE:
            if ((io_info_ptr->IO_MODE & I2S_IO_WRITE) && 
                (io_info_ptr->IO_MODE & I2S_IO_READ))
            {
                if (io_info_ptr->CLOCK_MODE & I2S_RX_SYNCHRONOUS)
                {
                    i2s_ptr->TCSR &= ~( 
                        I2S_TCSR_TE_MASK   | /* Disable transmitter            */
                        I2S_TCSR_BCE_MASK  | /* Disable bit clock              */
                        I2S_TCSR_FEIE_MASK | /* Disable FIFO error interrupt   */
                        I2S_TCSR_FRIE_MASK   /* Disable FIFO request interrupt */
                        );
                    i2s_ptr->RCSR &= ~(
                        I2S_RCSR_RE_MASK   | /* Disable receiver               */
                        I2S_RCSR_BCE_MASK  | /* Disable bit clock              */
                        I2S_RCSR_FEIE_MASK | /* Disable FIFO error interrupt   */
                        I2S_RCSR_FRIE_MASK   /* Disable FIFO request interrupt */
                        );
                }
                else if (io_info_ptr->CLOCK_MODE & I2S_TX_SYNCHRONOUS)
                {
                    i2s_ptr->RCSR &= ~(
                        I2S_RCSR_RE_MASK   | /* Disable receiver               */
                        I2S_RCSR_BCE_MASK  | /* Disable bit clock              */
                        I2S_RCSR_FEIE_MASK | /* Disable FIFO error interrupt   */
                        I2S_RCSR_FRIE_MASK   /* Disable FIFO request interrupt */
                        );
                    i2s_ptr->TCSR &= ~( 
                        I2S_TCSR_TE_MASK   | /* Disable transmitter            */
                        I2S_TCSR_BCE_MASK  | /* Disable bit clock              */
                        I2S_TCSR_FEIE_MASK | /* Disable FIFO error interrupt   */
                        I2S_TCSR_FRIE_MASK   /* Disable FIFO request interrupt */
                        );
                }
            }
            else if (io_info_ptr->IO_MODE & I2S_IO_WRITE) /* Disable transmitter */
            {
                i2s_ptr->TCSR &= ~( 
                    I2S_TCSR_TE_MASK   | /* Disable transmitter            */
                    I2S_TCSR_BCE_MASK  | /* Disable bit clock              */
                    I2S_TCSR_FEIE_MASK | /* Disable FIFO error interrupt   */
                    I2S_TCSR_FRIE_MASK   /* Disable FIFO request interrupt */
                    );
            }
            else if (io_info_ptr->IO_MODE & I2S_IO_READ) /* Disable receiver */
            {
                i2s_ptr->RCSR &= ~(
                    I2S_RCSR_RE_MASK   | /* Disable receiver               */
                    I2S_RCSR_BCE_MASK  | /* Disable bit clock              */
                    I2S_RCSR_FEIE_MASK | /* Disable FIFO error interrupt   */
                    I2S_RCSR_FRIE_MASK   /* Disable FIFO request interrupt */
                    );
            }
            break;
            
        case IO_IOCTL_I2S_ENABLE_DEVICE:
            if ((io_info_ptr->IO_MODE & I2S_IO_WRITE) && 
                (io_info_ptr->IO_MODE & I2S_IO_READ))
            {
                if (io_info_ptr->CLOCK_MODE & I2S_RX_SYNCHRONOUS) /* Receiver must be enabled first */
                {
                    i2s_ptr->RCSR |= (
                        I2S_RCSR_RE_MASK   | /* Enable receiver  */
                        I2S_RCSR_BCE_MASK    /* Enable bit clock */
                        );
                    i2s_ptr->TCSR |= ( 
                        I2S_TCSR_TE_MASK   | /* Enable transmitter */
                        I2S_TCSR_BCE_MASK    /* Enable bit clock   */
                        );
                }
                else if (io_info_ptr->CLOCK_MODE & I2S_TX_SYNCHRONOUS) /* Transmitter must be enabled first */
                {
                    i2s_ptr->TCSR |= ( 
                        I2S_TCSR_TE_MASK   | /* Enable transmitter */
                        I2S_TCSR_BCE_MASK    /* Enable bit clock   */
                        );
                     i2s_ptr->RCSR |= (
                        I2S_RCSR_RE_MASK   | /* Enable receiver  */
                        I2S_RCSR_BCE_MASK    /* Enable bit clock */
                        );
                }
            } 
            else if (io_info_ptr->IO_MODE & I2S_IO_WRITE) /* Enable transmitter */
            {
                i2s_ptr->TCSR |= ( 
                    I2S_TCSR_TE_MASK   | /* Enable transmitter */
                    I2S_TCSR_BCE_MASK    /* Enable bit clock   */
                    );
            }
            else if (io_info_ptr->IO_MODE & I2S_IO_READ)  /* Enable receiver */
            {
                i2s_ptr->RCSR &= ~(
                    I2S_RCSR_RE_MASK   | /* Enable transmitter */
                    I2S_RCSR_BCE_MASK    /* Enable bit clock   */
                    );
            }
            break;
            
        case IO_IOCTL_I2S_SET_MCLK_FREQ:
            if (io_info_ptr->ONTHEWAY)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Device is busy.");
                result = I2S_ERROR_DEVICE_BUSY;
                break;
            }
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break; 
            }
            else
            {
                uint_16 fract;
                uint_16 div;
                uint_32 frequency;
#if PSP_MQX_CPU_IS_VYBRID     
                /* Find values for SAI clock divider */
                _vi2s_set_mclk_freq(io_info_ptr, *((uint_32_ptr) param));
                frequency = _vi2s_get_mclk_value(io_info_ptr);
#else
                frequency = _ki2s_find_mclk_freq_div(io_info_ptr->MCLK_SRC, &fract, &div, *((uint_32_ptr) param));            
                i2s_ptr->MDR = (I2S_MDR_DIVIDE(div-1) | I2S_MDR_FRACT(fract-1));
                while(i2s_ptr->MCR & I2S_MCR_DUF_MASK) {}; // wait until new value is set
#endif
                /* Recalculate clock values according to new setting */
                io_info_ptr->MCLK_FREQ = frequency;
                io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_DIV;
                io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * 2/*io_info_ptr->IO_FORMAT.CHANNELS*/);
            }
            break;
            
        case IO_IOCTL_I2S_SET_FS_FREQ:
            if (io_info_ptr->ONTHEWAY)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Device is busy.");
                result = I2S_ERROR_DEVICE_BUSY;
                break;
            }
            
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            else
            {
                sample_rate = *((uint_32_ptr) param);
                if (sample_rate == 0)
                {
                    I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                    result = I2S_ERROR_INVALID_PARAMETER;
                    break;
                }
            }
            if (io_info_ptr->CLOCK_SOURCE == I2S_CLK_INT)
            {
                /* Get bit clock value for selected sample rate*/
                io_info_ptr->BCLK_FREQ = sample_rate * io_info_ptr->DATA_BITS * 2/*io_info_ptr->IO_FORMAT.CHANNELS*/;
                /* Get divider value for calculated bit clock frequency */
                io_info_ptr->BCLK_DIV = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_FREQ;
                if (io_info_ptr->BCLK_DIV == 0)
                {
                    I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                    result = I2S_ERROR_INVALID_PARAMETER;
                    break;
                }
                /* Recalculate bit clock to match divider value */
                io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_DIV;
                /* Get sampling frequency from new bit clock value */
                io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * 2/*io_info_ptr->IO_FORMAT.CHANNELS*/);     
                if ((io_info_ptr->IO_MODE & I2S_IO_WRITE) || (io_info_ptr->CLOCK_MODE & I2S_RX_SYNCHRONOUS))
                {
                    /* Set bit clock divider in TCR2 register */
                    i2s_ptr->TCR2 &= ~I2S_TCR2_DIV_MASK;
                    i2s_ptr->TCR2 |= I2S_TCR2_DIV((io_info_ptr->BCLK_DIV / 2) - 1);   
                }
                if ((io_info_ptr->IO_MODE & I2S_IO_READ) || (io_info_ptr->CLOCK_MODE & I2S_TX_SYNCHRONOUS))
                {
                    /* Set bit clock divider in RCR2 register */
                    i2s_ptr->RCR2 &= ~I2S_RCR2_DIV_MASK;
                    i2s_ptr->RCR2 |= I2S_RCR2_DIV((io_info_ptr->BCLK_DIV / 2) - 1);   
                }
                
            }
            else
            {
                /* If the clock source is external, set up frame sync frequency and recalculate bit clock frequency */
                io_info_ptr->FS_FREQ = sample_rate;
                io_info_ptr->BCLK_FREQ = sample_rate * io_info_ptr->DATA_BITS * 2/*io_info_ptr->IO_FORMAT.CHANNELS*/;
            }
            
            result = MQX_OK;
            break;
#if I2S_USE_FLOAT    
        case IO_IOCTL_I2S_TX_DUMMY_ON:
            if (!(io_info_ptr->IO_MODE & I2S_IO_WRITE))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid IOCTL command.");
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            }
            if (io_info_ptr->TX_DUMMY == FALSE)
            {
                io_info_ptr->TX_DUMMY = TRUE;
                dummy->LENGTH = _ksai_sine_wave(io_info_ptr->FS_FREQ, 440, &(dummy->DATA));
                dummy->INDEX = 0;
            }
            break;
            
        case IO_IOCTL_I2S_TX_DUMMY_OFF:
            if (!(io_info_ptr->IO_MODE & I2S_IO_WRITE))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid IOCTL command.");
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            }
            if (io_info_ptr->TX_DUMMY == TRUE)
            {
                io_info_ptr->TX_DUMMY = FALSE;
                result = _mem_free(dummy->DATA);
                if (result == MQX_OK)
                {
                    dummy->LENGTH = 0;
                    dummy->DATA = NULL;
                }
                dummy->INDEX = 0;
            }
            break;
#endif 
        case IO_IOCTL_I2S_GET_MODE:
            if (param == NULL)
            {
                 result = I2S_ERROR_INVALID_PARAMETER;
                 break;
            }
            *((uint_8_ptr) param) = io_info_ptr->MODE;
            break;
        
        case IO_IOCTL_I2S_GET_CLOCK_SOURCE:
            if (param == NULL)
            {
                 result = I2S_ERROR_INVALID_PARAMETER;
                 break;
            }
            *((uint_8_ptr) param) = io_info_ptr->CLOCK_SOURCE;
            break;
        
        case IO_IOCTL_I2S_GET_DATA_BITS:
             if (param == NULL)
             {
                  I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter."); 
                  result = I2S_ERROR_INVALID_PARAMETER;
                  break;
             }
             *((uint_8_ptr) param) = io_info_ptr->DATA_BITS;
             break;
            
        case IO_IOCTL_I2S_GET_MCLK_FREQ:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break; 
            }
            else
            {
                *((uint_32_ptr)param) = io_info_ptr->MCLK_FREQ;
            }
            result = MQX_OK;
            break;
                
        case IO_IOCTL_I2S_GET_BCLK_FREQ:
            if (param == NULL)
            {
                 I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                 result = I2S_ERROR_INVALID_PARAMETER;
                 break;
            }
            *((uint_32_ptr) param) = io_info_ptr->BCLK_FREQ;
            break;
            
        case IO_IOCTL_I2S_GET_TX_DUMMY:
            if (!(io_info_ptr->IO_MODE & I2S_IO_WRITE))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid IOCTL command.");
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            }
            if (param == NULL)
            {
                 I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                 result = I2S_ERROR_INVALID_PARAMETER;
                 break;
            }
            *((boolean*) param) = io_info_ptr->TX_DUMMY;
            break;
            
        case IO_IOCTL_I2S_GET_FS_FREQ:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            else
            {
                *((uint_32_ptr)param) = io_info_ptr->FS_FREQ;
            }
            result = MQX_OK;
            break;
            
        case IO_IOCTL_I2S_GET_STATISTICS:
            if (param == NULL)
            {
                 I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                 result = I2S_ERROR_INVALID_PARAMETER;
                 break;
            }
            _mem_copy(&(io_info_ptr->STATS), param, sizeof(io_info_ptr->STATS));
            break;
            
        case IO_IOCTL_I2S_SET_TXFIFO_WATERMARK:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            else if (*((uint_8_ptr) param) > (SIZE_OF_FIFO - 1))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Parameter out of range.");
                result = I2S_ERROR_PARAM_OUT_OF_RANGE;
                break;
            }
            if (!(io_info_ptr->IO_MODE & I2S_IO_WRITE) && (io_info_ptr->IO_MODE & I2S_IO_READ))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid IOCTL command.");
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            }
            i2s_ptr->TCR1 = I2S_TCR1_TFW(*((uint_8_ptr) param));
            break;
            
        case IO_IOCTL_I2S_SET_RXFIFO_WATERMARK:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            else if (*((uint_8_ptr) param) > (SIZE_OF_FIFO - 1))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Parameter out of range.");
                result = I2S_ERROR_PARAM_OUT_OF_RANGE;
                break;
            }
            if (!(io_info_ptr->IO_MODE & I2S_IO_READ) && (io_info_ptr->IO_MODE & I2S_IO_WRITE))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid IOCTL command.");
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            }
            i2s_ptr->RCR1 = I2S_RCR1_RFW(*((uint_8_ptr) param));
            break;
            
        case IO_IOCTL_I2S_GET_TXFIFO_WATERMARK:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            if (!(io_info_ptr->IO_MODE & I2S_IO_WRITE) && (io_info_ptr->IO_MODE & I2S_IO_READ))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid IOCTL command.");
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            }
            *((uint_8_ptr) param) = i2s_ptr->TCR1;
            break;

        case IO_IOCTL_I2S_GET_RXFIFO_WATERMARK:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            if (!(io_info_ptr->IO_MODE & I2S_IO_READ) && (io_info_ptr->IO_MODE & I2S_IO_WRITE))
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid IOCTL command.");
                result = IO_ERROR_INVALID_IOCTL_CMD;
                break;
            }
            *((uint_8_ptr) param) = i2s_ptr->RCR1;
            break;
            
        case IO_IOCTL_I2S_CLEAR_STATISTICS:
            _mem_zero(&(io_info_ptr->STATS), sizeof(io_info_ptr->STATS));
            break;
            
        case IO_IOCTL_AUDIO_SET_IO_DATA_FORMAT:
            if(io_info_ptr->ONTHEWAY)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Cannot change I/O data format while I/O actions are in progress.\n");
                result = I2S_ERROR_DEVICE_BUSY;
                break;
            }
            
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            else
            {
                uint_8 aligment, endianity, bits, channels, size;
                
                endianity = ((AUDIO_DATA_FORMAT_PTR) param)->ENDIAN;
                bits = ((AUDIO_DATA_FORMAT_PTR) param)->BITS;
                aligment = ((AUDIO_DATA_FORMAT_PTR) param)->ALIGNMENT;
                channels = ((AUDIO_DATA_FORMAT_PTR) param)->CHANNELS;
                size = ((AUDIO_DATA_FORMAT_PTR) param)->SIZE;
                
                if ((aligment > AUDIO_ALIGNMENT_LEFT) || (bits < AUDIO_BIT_SIZE_MIN) ||
                    (bits > AUDIO_BIT_SIZE_MAX) || (endianity > AUDIO_LITTLE_ENDIAN)  ||
                    (channels > 2) || (channels == 0))
                {
                    I2S_LOG("\n  _i2s_ioctl: Error - Invalid I/O data format.");
                    result = AUDIO_ERROR_INVALID_IO_FORMAT;
                    break;
                }
                _mem_copy(param, &(io_info_ptr->IO_FORMAT), sizeof(AUDIO_DATA_FORMAT));
                /* Setup frame sync for transmitter */
                if ((io_info_ptr->IO_MODE & I2S_IO_WRITE) || (io_info_ptr->CLOCK_MODE & I2S_RX_SYNCHRONOUS))
                {
                    i2s_ptr->TCR4 &= ~(I2S_TCR4_FRSZ_MASK);
                    i2s_ptr->TCR4 |= (I2S_TCR4_FRSZ(1));
                    /* Mask second transmitter channel if there is only one data channel */
                    if (channels == 1)
                    {
                        i2s_ptr->TMR = 0x02;
                    }
                }
                /* Setup frame sync for receiver */
                if ((io_info_ptr->IO_MODE & I2S_IO_READ) || (io_info_ptr->CLOCK_MODE & I2S_TX_SYNCHRONOUS))
                {
                    i2s_ptr->RCR4 &= ~(I2S_RCR4_FRSZ_MASK);
                    i2s_ptr->RCR4 |= (I2S_RCR4_FRSZ(1));
                    /* Mask second receiver channel if there is only one data channel */
                    if (channels == 1)
                    {
                        i2s_ptr->RMR = 0x02;
                    }
                }
            }
            break;
            
        case IO_IOCTL_AUDIO_GET_IO_DATA_FORMAT:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            _mem_copy(&(io_info_ptr->IO_FORMAT), param, sizeof(io_info_ptr->IO_FORMAT));
            break;
            
        case IO_IOCTL_I2S_SET_CLOCK_MODE:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            bclk_mode = *((uint_8_ptr) param);
            if ((io_info_ptr->IO_MODE & I2S_IO_WRITE) && !(io_info_ptr->IO_MODE & I2S_IO_READ))
            {
                // Set receiver bit clock settings to zero if transmitter is being set.
                bclk_mode &= 0xF0; 
            }
            if ((io_info_ptr->IO_MODE & I2S_IO_READ) && !(io_info_ptr->IO_MODE & I2S_IO_WRITE))
            {
                // Set transmitter bit clock settings to zero if receiver is being set.
                bclk_mode &= 0x0F;
            }
            result = _ki2s_set_bclk_mode(i2s_ptr, bclk_mode);
            if (result != I2S_OK)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid BCLK setting selected.");
            }
            break;
            
        case IO_IOCTL_I2S_GET_CLOCK_MODE:
            if (param == NULL)
            {
                I2S_LOG("\n  _i2s_ioctl: Error - Invalid parameter.");
                result = I2S_ERROR_INVALID_PARAMETER;
                break;
            }
            *((uint_8_ptr) param) = io_info_ptr->CLOCK_MODE;
            break;
            
        case IO_IOCTL_FLUSH_OUTPUT:
            while (io_info_ptr->ONTHEWAY)
            {
                uint_32 time = 0;
                time = (io_info_ptr->BUFFER.SIZE - io_info_ptr->BUFFER.SPACE) * (1000 / io_info_ptr->FS_FREQ) + 1;
                _time_delay(time);
            }
            break;
        default:
            I2S_LOG("\n  _i2s_ioctl: Error - Invalid IOCTL command.");
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }
    return result;
}

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_hw_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes an SAI hardware control registers.
*
*END*********************************************************************/

void _ksai_hw_init
(
    /* [IN] SAI init parameter pointer */
    KSAI_INIT_STRUCT_PTR ksai_init_ptr,
    
    /* [IN] SAI register pointer */
    I2S_MemMapPtr i2s_ptr,
    
    /* [IN] I/O mode (read/write) */
    _mqx_int io_mode
)
{    
    uint_8 data_bits  = ksai_init_ptr->DATA_BITS;
    uint_8 i2s_mode   = ksai_init_ptr->MODE;
    uint_8 clk_source = ksai_init_ptr->CLOCK_SOURCE;
    uint_8 bclk_mode  = ksai_init_ptr->CLOCK_MODE;
    uint_16 fract = 0;
    uint_16 div = 0;
    boolean set_tx = io_mode & I2S_IO_WRITE;
    boolean set_rx = io_mode & I2S_IO_READ;
#if PSP_MQX_CPU_IS_VYBRID
    CCM_MemMapPtr ccm = CCM_BASE_PTR;
#endif
    /* 
    ** Set the divider input clock to system clock
    */
#if !PSP_MQX_CPU_IS_VYBRID
    i2s_ptr->MCR &= ~I2S_MCR_MICS_MASK;
#endif
    /* ================ General transmitter configuration =================== */ 
    if (set_tx)
    {
        uint_8 tx_channel = ksai_init_ptr->TX_CHANNEL;
        boolean tx_empty  = ksai_init_ptr->TX_DUMMY;
        /* 
        ** Software reset -> reset internal transmitter logic including the FIFO writer
        */
        i2s_ptr->TCSR = 0;
        i2s_ptr->TCSR |= I2S_TCSR_SR_MASK;
        i2s_ptr->TCSR &= ~(I2S_TCSR_SR_MASK);
        /*
        ** Enable transmitter in debug mode - this must be done else synchronous mode 
        ** will not work while debugging.
        */
        i2s_ptr->TCSR |= I2S_TCSR_DBGE_MASK; 
        /* 
        ** Set FIFO watermark
        */
        i2s_ptr->TCR1 = I2S_TCR1_TFW(I2S_TX_FIFO_DEFAULT_WATERMARK);      
        /* 
        ** Set the synch mode, clock polarity, master clock source and bit clock 
        */
        i2s_ptr->TCR2 = 0;
        i2s_ptr->TCR2 |= (
            I2S_TCR2_BCP_MASK | /* Bit clock active low           */
            I2S_TCR2_MSEL(1)  | /* MCLK from divider (CLKGEN)     */
            I2S_TCR2_DIV(3)     /* Bit clock frequency = MCLK / 8 */
            );
        /*
        ** First word in frame sets start of word flag
        */
        i2s_ptr->TCR3 = 0;
        i2s_ptr->TCR3 |= (I2S_TCR3_WDFL(0));
        /* 
        ** Enable selected transmitter channel
        */
        switch (tx_channel)
        {
            case 0:
                i2s_ptr->TCR3 |= (I2S_TCR3_TCE(1));
                break;
            case 1:
                i2s_ptr->TCR3 |= (I2S_TCR3_TCE(2));
                break;
            default:
                break;
        }
        /*
        ** Configure frame size, sync width, MSB and frame sync
        */
        i2s_ptr->TCR4 = 0;
        i2s_ptr->TCR4 = (
            I2S_TCR4_FRSZ(1)           | /* Two words in each frame          */
            I2S_TCR4_SYWD(data_bits-1) | /* Synch width as long as data word */
            I2S_TCR4_MF_MASK           | /* MSB shifted out first            */
            I2S_TCR4_FSE_MASK            /* Frame sync one bit early         */
            );
        /* 
        ** Fist bit shifted is always MSB (bit with highest index in register)
        ** and word length is set according to user configuration.
        */
        i2s_ptr->TCR5 = 0;
        i2s_ptr->TCR5 = (
            I2S_TCR5_WNW(data_bits-1) | /* Word length for Nth word is data_bits   */
            I2S_TCR5_W0W(data_bits-1) | /* Word length for 0th word is data_bits   */
            I2S_TCR5_FBT(data_bits)     /* First bit shifted is on data_bits index */
            );
        /*
        ** Reset word mask 
        */
        i2s_ptr->TMR = 0;
     
    }
    
    /* ================== General receiver configuration ==================== */  
    if (set_rx)
    {
        uint_8 rx_channel = ksai_init_ptr->RX_CHANNEL;
        i2s_ptr->RCSR = 0;
        /* 
        ** Software reset -> reset internal receiver logic including the FIFO writer
        */
        i2s_ptr->RCSR |= I2S_RCSR_SR_MASK;
        i2s_ptr->RCSR &= ~(I2S_RCSR_SR_MASK);
        /*
        ** Enable receiver in debug mode - this must be done else synchronous mode 
        ** will not work while debugging.
        */
        i2s_ptr->RCSR |= I2S_RCSR_DBGE_MASK;
        /* 
        ** Set FIFO watermark
        */
        i2s_ptr->RCR1 = I2S_RCR1_RFW(I2S_RX_FIFO_DEFAULT_WATERMARK);   
        /* 
        ** Set the clock polarity and master clock source 
        */
        i2s_ptr->RCR2 = 0;
        i2s_ptr->RCR2 |= (
            I2S_RCR2_BCP_MASK |                          /* Bit clock active low           */
            I2S_RCR2_MSEL(1)  |                          /* MCLK from divider (CLKGEN)     */
            I2S_RCR2_DIV((DEFAULT_BCLK_DIV / 2) - 1)     /* Bit clock frequency = MCLK / 8 */
            );
        /*
        ** First word in frame sets start of word flag
        */
        i2s_ptr->RCR3 |= (I2S_RCR3_WDFL(0));
        /* 
        ** Enable selected receiver channel
        */
        switch (rx_channel)
        {
            case 0:
                i2s_ptr->RCR3 |= (I2S_RCR3_RCE(1));
                break;
            case 1:
                i2s_ptr->RCR3 |= (I2S_RCR3_RCE(2));
                break;
            default:
                break;
        }
        /*
        ** Configure frame size, sync width, MSB and frame sync
        */
        i2s_ptr->RCR4 = 0;
        i2s_ptr->RCR4 = (
            I2S_RCR4_FRSZ(1)           | /* Two words in each frame          */
            I2S_RCR4_SYWD(data_bits-1) | /* Synch width as long as data word */
            I2S_RCR4_MF_MASK           | /* MSB shifted out first            */
            I2S_RCR4_FSE_MASK            /* Frame sync one bit early         */
            );
        /* 
        ** Fist bit shifted is always MSB (bit with highest index in register)
        ** and word length is set according to user configuration.
        */
        i2s_ptr->RCR5 = 0;
        i2s_ptr->RCR5 = (
            I2S_RCR5_WNW(data_bits-1) | /* Word length for Nth word is data_bits   */
            I2S_RCR5_W0W(data_bits-1) | /* Word length for 0th word is data_bits   */
            I2S_RCR5_FBT(data_bits-1)     /* First bit shifted is on data_bits index */
            );
        /*
        ** Reset word mask 
        */
        i2s_ptr->RMR = 0;
    }
    
    /*================= I2S clock source specific code =======================*/
    switch (clk_source)
    {
        case I2S_CLK_INT:
            /* 
            ** Set divider to get the 12.2880 MHz master clock
            */
#if PSP_MQX_CPU_IS_VYBRID
            _vi2s_set_clk_src_int(ksai_init_ptr->HW_CHANNEL);
            _vi2s_set_sai_div(ksai_init_ptr->HW_CHANNEL, 6);
#else
            _ki2s_find_mclk_freq_div(ksai_init_ptr->MCLK_SRC, &fract, &div, 12288000);
            i2s_ptr->MDR = (I2S_MDR_DIVIDE(div-1) | I2S_MDR_FRACT(fract-1));
            while(i2s_ptr->MCR & I2S_MCR_DUF_MASK) {}; // wait until new value is set
            /* 
            ** MCLK signal pin is configured as an output from the MCLK divider
            ** and the MCLK divider is enabled.
            */
            i2s_ptr->MCR |= (I2S_MCR_MOE_MASK);
            while (i2s_ptr->MCR & I2S_MCR_DUF_MASK) {};
#endif
            break;
        case I2S_CLK_EXT:
            /* 
            ** MCLK signal pin is configured as an input that bypasses
            ** the MCLK divider.
            */
#if PSP_MQX_CPU_IS_VYBRID
            _vi2s_set_clk_src_ext(ksai_init_ptr->HW_CHANNEL);
#else
            i2s_ptr->MCR &= ~(I2S_MCR_MOE_MASK);
            while (i2s_ptr->MCR & I2S_MCR_DUF_MASK) {};
#endif
            break;
        default:
            break;
    }
    /*================= I2S mode of operation specific code ===================*/
    if (i2s_mode & I2S_TX_MASTER)
    {
        /* 
        ** Transmit bit clock generated internally
        */
        i2s_ptr->TCR2 |= (I2S_TCR2_BCD_MASK);
        /*
        ** Transmit frame sync generated internally
        */
        i2s_ptr->TCR4 |= (I2S_TCR4_FSD_MASK);
    }
    if (i2s_mode & I2S_RX_MASTER)
    {
        /*
        ** Receive bit clock generated internally
        */
        i2s_ptr->RCR2 |= (I2S_RCR2_BCD_MASK);
        /* 
        ** Receive frame sync generated internally
        */
        i2s_ptr->RCR4 |= (I2S_RCR4_FSD_MASK);
    }
    if (i2s_mode & I2S_TX_SLAVE)
    {
        /*
        ** Transmit bit clock generated externally
        */
        i2s_ptr->TCR2 &= ~(I2S_TCR2_BCD_MASK);
        /* 
        ** Transmit frame sync generated externally
        */
        i2s_ptr->TCR4 &= ~(I2S_TCR4_FSD_MASK);
    }
    if (i2s_mode & I2S_RX_SLAVE)
    {
        /* 
        ** Receive bit clock generated externally
        */
        i2s_ptr->RCR2 &= ~(I2S_RCR2_BCD_MASK);
        /*
        ** Receive frame sync generated externally
        */
        i2s_ptr->RCR4 &= ~(I2S_RCR4_FSD_MASK);
    }
    /*========================== I2S clock setup =============================*/
    _ki2s_set_bclk_mode(i2s_ptr, bclk_mode);
}

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_format_in_data
* Returned Value   : formatted input data
* Comments         : Function performs SAI input data formatting
*
*END*********************************************************************/

static uint_32 _ksai_format_in_data
(
    /* [IN] data to format */
    char_ptr input,

    /* [IN] Requested format */
    AUDIO_DATA_FORMAT_PTR format
)
{/* Body */
   int_32 retval = 0;
   uint_8 i;
   
   if (format->ENDIAN == AUDIO_BIG_ENDIAN)
   {
      for (i = 0; i < format->SIZE; i++)
      {
          retval |= ((((uint_32) *(input + i)) << (format->SIZE - 1 - i) * 8) & (0xFF) << (format->SIZE - 1 - i) * 8);
      }
      if ((format->ALIGNMENT == AUDIO_ALIGNMENT_RIGHT) && (format->BITS < (format->SIZE * 8)))
      {
         retval <<= (format->SIZE * I2S_CHAR_BIT) - format->BITS;
      }
   }
   else
   {
      for (i = 0; i < format->SIZE; i++)
      {
          retval |= ((uint_32) *(input + i) << i * 8);
      }
   }
   if (retval & (1 << (format->SIZE * 8) - 1))
   {
       switch (format->SIZE)
       {
           case 1:
                retval |= 0xFFFFFF00;
                break;
           case 2:
                retval |= 0xFFFF0000;
                break;
           case 3:
                retval |= 0xFF000000;
           default:
                break;
       }
   }
   return(~((unsigned) retval));
}/* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _ksai_format_out_data
* Returned Value   : none
* Comments         : Function performs SAI output data formatting
*
*END*********************************************************************/

static void _ksai_format_out_data
(
    /* [IN] data to format */
    uint_32 input,

    /* [OUT] location for output */
    char_ptr output,

    /* [IN] Requested format */
    AUDIO_DATA_FORMAT_PTR format
)
{
    uint_8 i;
    input = ~input;
    
    if (format->ENDIAN == AUDIO_BIG_ENDIAN)
    {
        for(i = 0; i < format->SIZE; i++)
        {
            output[i] = (input >> I2S_CHAR_BIT * (format->SIZE - i - 1) & 0xFF);
        }
        if ((format->ALIGNMENT == AUDIO_ALIGNMENT_LEFT) && (format->BITS < (format->SIZE * 8)))
        {
            input <<= (format->SIZE * I2S_CHAR_BIT) - format->BITS;
        }
    }
    else
    {
        for(i = 0; i < format->SIZE; i++)
        {
            output[i] = (input & (0xFF << (i * I2S_CHAR_BIT))) >> (i * I2S_CHAR_BIT);
        }
    }
    
    return;
}

#ifndef I2S_USE_FLOAT // Floating point enabled
/*FUNCTION****************************************************************
*
* Function Name    : _ksai_sine_wave
* Returned Value   : samples number if successful, 0 otherwise
* Comments         :
*    This function generate a sine wave.
*
*END*********************************************************************/

static uint_32 _ksai_sine_wave
(
    /* [IN] Sample rate frequency */
    uint_32 fs, 
    
    /* [IN] Input frequency */
    uint_32 freq, 

    /* [OUT] Pointer to data */
    int_16_ptr* output
)
{
    uint_32 samples, i;
    boolean over180 = 0;
    ieee_single period, step, angle = 0.0;
    period = 1 / (ieee_single) freq;
    samples = (uint_32) (fs * period);
    
    if (samples == 0)
    {
        return(0);
    }
    *output = (int_16_ptr) _mem_alloc(sizeof(int_16) * samples);
    if (*output == NULL)
    {
        return(0);
    }
    step = 360.0 / (ieee_single) samples;
    for(i = 0; i < samples; i++)
    {
        if (angle > 180)
        {
            angle = angle - 180;
            over180 = TRUE;
        }
        *((*output) + i) = (int_16) (BIT16_MAX * (4*angle*(180 - angle))/(40500 - angle * (180 - angle)));
        if (over180)
        {
            *((*output) + i) = -(*((*output) + i));
        }
        angle += step;
    }
    return(samples);
}
#endif // I2S_USE_FLOAT - Floating point enabled

#if PSP_MQX_CPU_IS_VYBRID // PSP_MQX_CPU_IS_VYBRID - Functions specific for Vybrid
/*FUNCTION****************************************************************
*
* Function Name    : _vi2s_get_mclk_value
* Returned Value   : Master clock frequency
* Comments         :
*    This function calculates master clock value from FRACT and DIV.
*
*END*********************************************************************/

static uint_32 _vi2s_get_mclk_value
(
   KSAI_INFO_STRUCT_PTR io_info_ptr /* Device internal info struct */
)
{
    I2S_MemMapPtr i2s_ptr = io_info_ptr->SAI_PTR;
    CCM_MemMapPtr ccm = CCM_BASE_PTR;

    CM_CLOCK_SOURCE src = io_info_ptr->MCLK_SRC;
    uint_32 source_freq = 0;
    uint_32 mclk_freq = 0;
    source_freq = _bsp_get_clock(_bsp_get_clock_configuration(), src);
    
    mclk_freq = source_freq / (((ccm->CACRR & CCM_CACRR_PLL4_CLK_DIV_MASK) >> CCM_CACRR_PLL4_CLK_DIV_SHIFT)*2 + 2);
    switch (io_info_ptr->HW_CHANNEL)
    {
        case 0:
            mclk_freq /= ((ccm->CSCDR1 & CCM_CSCDR1_SAI0_DIV_MASK) >> CCM_CSCDR1_SAI0_DIV_SHIFT) + 1;
            break;
        case 1:
            mclk_freq /= ((ccm->CSCDR1 & CCM_CSCDR1_SAI1_DIV_MASK) >> CCM_CSCDR1_SAI1_DIV_SHIFT) + 1;
            break;
        case 2:
            mclk_freq /= ((ccm->CSCDR1 & CCM_CSCDR1_SAI2_DIV_MASK) >> CCM_CSCDR1_SAI2_DIV_SHIFT) + 1;
            break;
        case 3:
            mclk_freq /= ((ccm->CSCDR1 & CCM_CSCDR1_SAI3_DIV_MASK) >> CCM_CSCDR1_SAI3_DIV_SHIFT) + 1;
            break;
        default:
            break;
    }
    return (mclk_freq);
}

/*FUNCTION****************************************************************
*
* Function Name    : _vi2s_set_mclk_value
* Returned Value   : None
* Comments         :
*    This function sets master clock frequency to closest to selected value.
*
*END*********************************************************************/
static void _vi2s_set_mclk_freq(KSAI_INFO_STRUCT_PTR io_info_ptr, uint_32 freq)
{
    uint_32 remainders[] = {
                            CPU_PLL_AUDIO_CLK_HZ_0,
                            CPU_PLL_AUDIO_CLK_HZ_1,
                            CPU_PLL_AUDIO_CLK_HZ_2
                            };
    uint_32 result = 0;
    uint_32 source_freq = 0;
    uint_32 iter_mclk = 0;
    CCM_MemMapPtr ccm = CCM_BASE_PTR;
    uint_8 pll_div = 4;
    uint_8 sai_div = 1;
    uint_8 temp_pll_div = 0;
    uint_8 temp_sai_div = 0;
    boolean found = FALSE;

    /* Calculate remainders */
    remainders[0] %= freq;
    remainders[1] %= freq; 
    remainders[2] %= freq;
    
    /* Select closest PLL4 frequency */
    if (remainders[0] < remainders[1])
    {
        _bsp_set_clock(CPU_PLL_AUDIO_CLK_HZ_0, io_info_ptr->MCLK_SRC);
    }
    else if (remainders[1] < remainders[2])
    {
        _bsp_set_clock(CPU_PLL_AUDIO_CLK_HZ_1, io_info_ptr->MCLK_SRC);
    }
    else
    {
        _bsp_set_clock(CPU_PLL_AUDIO_CLK_HZ_2, io_info_ptr->MCLK_SRC);
    }
    
    /* Read PLL4 freqency */
    source_freq =  _bsp_get_clock(_bsp_get_clock_configuration(), io_info_ptr->MCLK_SRC);
    
    /* Find dividers values for selecter master clock frequency */
    for (; pll_div < PLL_DIV_MAX; pll_div += 2)
    {
       for(sai_div = 1; sai_div < SAI_DIV_MAX; sai_div++)
       {
           uint_32 iter_mclk = source_freq / (pll_div * sai_div);
           if (iter_mclk < freq) break; // Value too low, try next setting
           if ((iter_mclk - freq) == 0) // Found value that matches exactly 
           {
               found = TRUE;
               break;
           }
           /* 
           ** If a new iteration of mclk is better than last that we have adapt 
           ** it as the new best value.
           */
           else if ((result == 0) || ((iter_mclk % freq) < (result % freq)))
           {
               temp_pll_div = pll_div;
               temp_sai_div = sai_div;
               result = iter_mclk;
           }
       }
       if (found) break;
    }
    if (found == FALSE)
    {
       pll_div = temp_pll_div;
       sai_div = temp_sai_div;
    }
    /* Set PLL4 divider */
    ccm->CACRR = (ccm->CACRR & ~CCM_CACRR_PLL4_CLK_DIV_MASK) | CCM_CACRR_PLL4_CLK_DIV(pll_div/2 - 1);
    
    /* Set SAI divider */
    _vi2s_set_sai_div(io_info_ptr->HW_CHANNEL, sai_div);
}

/*FUNCTION****************************************************************
*
* Function Name    : _vi2s_set_clk_src_int
* Returned Value   : None
* Comments         :
*    This function selects internal clock source for appropriate SAI peripheral
*
*END*********************************************************************/
static void _vi2s_set_clk_src_int(uint_8 hw_channel)
{
    CCM_MemMapPtr ccm = CCM_BASE_PTR;
    
    switch (hw_channel)
    {
        case 0: //SAI0_CLK_SEL
            /* Select internal clock source (PLL4) */
            ccm->CSCMR1 = (ccm->CSCMR1 & ~CCM_CSCMR1_SAI0_CLK_SEL_MASK) | CCM_CSCMR1_SAI0_CLK_SEL(3);
            /* Enable SAI0 master clock */
            ccm->CSCDR1 |= CCM_CSCDR1_SAI0_EN_MASK;
            break;
        case 1: //SAI1_CLK_SEL
            ccm->CSCMR1 = (ccm->CSCMR1 & ~CCM_CSCMR1_SAI1_CLK_SEL_MASK) | CCM_CSCMR1_SAI1_CLK_SEL(3);
            /* Enable SAI1 master clock */
            ccm->CSCDR1 |= CCM_CSCDR1_SAI1_EN_MASK;
            break;
        case 2: //SAI2_CLK_SEL
            ccm->CSCMR1 = (ccm->CSCMR1 & ~CCM_CSCMR1_SAI2_CLK_SEL_MASK) | CCM_CSCMR1_SAI2_CLK_SEL(3);
            /* Enable SAI2 master clock */
            ccm->CSCDR1 |= CCM_CSCDR1_SAI2_EN_MASK;
            break;
        case 3: //SAI3_CLK_SEL
            ccm->CSCMR1 = (ccm->CSCMR1 & ~CCM_CSCMR1_SAI3_CLK_SEL_MASK) | CCM_CSCMR1_SAI3_CLK_SEL(3);
            /* Enable SAI3 master clock */
            ccm->CSCDR1 |= CCM_CSCDR1_SAI3_EN_MASK;
            break;
        default:
            break;
    }
}

/*FUNCTION****************************************************************
*
* Function Name    : _vi2s_set_clk_src_ext
* Returned Value   : None
* Comments         :
*    This function selects external clock source for appropriate SAI peripheral
*
*END*********************************************************************/
static void _vi2s_set_clk_src_ext(uint_8 hw_channel)
{
    CCM_MemMapPtr ccm = CCM_BASE_PTR;
    
    switch (hw_channel)
    {
        case 0: //SAI0_CLK_SEL
            /* Clock source for SAI0 is Audio External Clock */
            ccm->CSCMR1 &= ~(CCM_CSCMR1_SAI0_CLK_SEL_MASK);
            break;
        case 1: //SAI1_CLK_SEL
            ccm->CSCMR1 &= ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK);
            break;
        case 2: //SAI2_CLK_SEL
            ccm->CSCMR1 &= ~(CCM_CSCMR1_SAI2_CLK_SEL_MASK);
            break;
        case 3: //SAI3_CLK_SEL
            ccm->CSCMR1 &= ~(CCM_CSCMR1_SAI3_CLK_SEL_MASK);
            break;
        default:
            break;
    }
    /* Set SAI clock divider to 1 (do not divide external clock) */
    _vi2s_set_sai_div(hw_channel, 1);
}

/*FUNCTION****************************************************************
*
* Function Name    : _vi2s_set_sai_div
* Returned Value   : None
* Comments         :
*    This function sets SAI clock divider for selected SAI peripheral
*
*END*********************************************************************/
static void _vi2s_set_sai_div(uint_8 hw_channel, uint_8 value)
{
    CCM_MemMapPtr ccm = CCM_BASE_PTR;
    
    switch (hw_channel)
    {
        case 0: //SAI0
            ccm->CSCDR1 = (ccm->CSCDR1 & ~CCM_CSCDR1_SAI0_DIV_MASK | CCM_CSCDR1_SAI0_DIV(value-1));
            break;
        case 1: //SAI1
            ccm->CSCDR1 = (ccm->CSCDR1 & ~CCM_CSCDR1_SAI1_DIV_MASK | CCM_CSCDR1_SAI1_DIV(value-1));
            break;
        case 2: //SAI2
            ccm->CSCDR1 = (ccm->CSCDR1 & ~CCM_CSCDR1_SAI2_DIV_MASK | CCM_CSCDR1_SAI2_DIV(value-1));
            break;  
        case 3: //SAI3
            ccm->CSCDR1 = (ccm->CSCDR1 & ~CCM_CSCDR1_SAI3_DIV_MASK | CCM_CSCDR1_SAI3_DIV(value-1));
            break;
        default:
            break;
    }
}
#else // !PSP_MQX_CPU_IS_VYBRID - Functions specific for Kinetis
/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_get_mclk_value
* Returned Value   : Master clock frequency
* Comments         :
*    This function calculates master clock value from FRACT and DIV.
*
*END*********************************************************************/
static uint_32 _ki2s_get_mclk_value
(
   KSAI_INFO_STRUCT_PTR io_info_ptr
)
{
    I2S_MemMapPtr i2s_ptr = io_info_ptr->SAI_PTR;
    uint_32 freq = _bsp_get_clock(_bsp_get_clock_configuration(), io_info_ptr->MCLK_SRC);
    uint_32 fract = 0;
    uint_32 div = 0;
    fract = (i2s_ptr->MDR & I2S_MDR_FRACT_MASK) >> I2S_MDR_FRACT_SHIFT;
    div = (i2s_ptr->MDR & I2S_MDR_DIVIDE_MASK) >> I2S_MDR_DIVIDE_SHIFT;
    return ((freq / (div + 1)) * (fract + 1));
}

#endif // END OF PSP_MQX_CPU_IS_VYBRID - Functions specific for platform

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_find_mclk_freq_div
* Returned Value   : Master clock frequency  
* Comments         :
*    This function tries to find master clock divider value required for 
*    selected master clock frequency.
*
*END*********************************************************************/
static uint_32 _ki2s_find_mclk_freq_div
(
    CM_CLOCK_SOURCE src,      /* Master clock source               */
    uint_16_ptr     frct,     /* Calculated FRACT value            */
    uint_16_ptr     div,      /* Calculated DIVIDER value          */
    uint_32         frequency /* Calculated master clock frequency */
)
{
    uint_32 closest_mclk = 0;
    uint_32 temp_fract;
    uint_32 temp_div;
    uint_32 iter_mclk;
    uint_16 fract = 0;
    uint_16 divide = 0;
    boolean found = FALSE;
    uint_32 i = 0;
    uint_32 source_freq = 0;

    source_freq = _bsp_get_clock(_bsp_get_clock_configuration(), src);
    /*
    ** Find best divider value for selected mclk frequency.
    */
    for (fract = 1; fract < FRACT_MAX; fract++)
    {
       for(divide = 1; divide < DIV_MAX; divide++)
       {
           iter_mclk = (source_freq / divide) * fract;
           if (iter_mclk < frequency) break; // Value too low, try next setting
           if ((iter_mclk - frequency) == 0) // Found value that matches exactly 
           {
               found = TRUE;
               break;
           }
           /* 
           ** If a new iteration of mclk is better than last that we have adapt 
           ** it as the new best value.
           */
           else if ((closest_mclk == 0) || ((iter_mclk % frequency) < (closest_mclk % frequency)))
           {
               temp_fract = fract;
               temp_div = divide;
               closest_mclk = iter_mclk;
           }
       }
       if (found) break;
    }
    /* 
    ** If we failed to find exact match use closest value we have.
    */
    if (found == FALSE)
    {
       fract = temp_fract;
       divide = temp_div;
       frequency = closest_mclk;
    }
    *frct = fract;
    *div = divide;
    return(frequency);
}
/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_set_master_mode
* Returned Value   : I2S_OK if everything is OK, error code otherwise.  
* Comments         :
*    This function sets up master mode for TX and RX (called from ioctl)
*
*END*********************************************************************/
static uint_32 _ki2s_set_master_mode
(
    KSAI_INFO_STRUCT_PTR io_info_ptr, /* Info struct                   */
    uint_8 mode                       /* Required master mode settings */
)
{
    I2S_MemMapPtr i2s_ptr = io_info_ptr->SAI_PTR;
    boolean set_tx_as_master = ((mode & I2S_TX_MASTER) >> 4) && (io_info_ptr->IO_MODE & I2S_IO_WRITE);
    boolean set_rx_as_master = (mode & I2S_RX_MASTER) && (io_info_ptr->IO_MODE & I2S_IO_READ);
    /* 
    ** If the master clock source is internal, enable it and recalculate
    ** values of frequencies in the internal info structure.
    */
    if (io_info_ptr->CLOCK_SOURCE == I2S_CLK_INT)
    {
#if PSP_MQX_CPU_IS_VYBRID
        _vi2s_set_clk_src_int(io_info_ptr->HW_CHANNEL);
        io_info_ptr->MCLK_FREQ = _vi2s_get_mclk_value(io_info_ptr);
#else
        i2s_ptr->MCR |= (I2S_MCR_MOE_MASK);
        io_info_ptr->MCLK_FREQ = _ki2s_get_mclk_value(io_info_ptr); 
#endif   
        io_info_ptr->BCLK_FREQ = io_info_ptr->MCLK_FREQ / io_info_ptr->BCLK_DIV;
        io_info_ptr->FS_FREQ = io_info_ptr->BCLK_FREQ / (io_info_ptr->DATA_BITS * 2/*io_info_ptr->IO_FORMAT.CHANNELS*/);
    }
    /*
    ** Else disable master clock signal and set pin as input. Also reset values
    ** of frequencies in the info structure.
    */
    else if (io_info_ptr->CLOCK_SOURCE == I2S_CLK_EXT)
    {
#if PSP_MQX_CPU_IS_VYBRID
        _vi2s_set_clk_src_ext(io_info_ptr->HW_CHANNEL);
#else
        i2s_ptr->MCR &= ~(I2S_MCR_MOE_MASK);
#endif
        io_info_ptr->MCLK_FREQ = 0;
        io_info_ptr->BCLK_FREQ = 0;
        io_info_ptr->FS_FREQ = 0;
    }
    /*
    ** In case we want to set the transmitter and it is enabled, device is busy.
    */
    if ((i2s_ptr->TCSR & I2S_TCSR_TE_MASK) && (set_tx_as_master))
    {
        return(I2S_ERROR_DEVICE_BUSY);
    }
    if ((io_info_ptr->CLOCK_MODE & I2S_TX_ASYNCHRONOUS) && (set_tx_as_master))
    {
        /* Reset Tx mode setting */
        io_info_ptr->MODE &= 0x0F;
        /* Set Tx into master mode */
        io_info_ptr->MODE |= I2S_TX_MASTER;
        i2s_ptr->TCR2 |= (I2S_TCR2_BCD_MASK);
        i2s_ptr->TCR4 |= (I2S_TCR4_FSD_MASK);
        i2s_ptr->TCR4 |= (I2S_TCR4_FSP_MASK);
        /* 
        ** If the the receiver is synchronous settings must same as the
        ** transmitter settings.
        */
        if (io_info_ptr->CLOCK_MODE & I2S_RX_SYNCHRONOUS)
        {
            io_info_ptr->MODE &= 0xF0;
            io_info_ptr->MODE |= I2S_RX_MASTER;
            i2s_ptr->RCR2 |= (I2S_RCR2_BCD_MASK);
            i2s_ptr->RCR4 |= (I2S_RCR4_FSD_MASK);
        }
        /* 
        ** If transmitter have swapped bit clock. set receiver bit clock to be
        ** generated internally
        */
        if (io_info_ptr->CLOCK_MODE & I2S_TX_BCLK_SWAPPED)
        {
            i2s_ptr->RCR2 |= (I2S_RCR2_BCD_MASK);
        }
    }
    
    /*
    ** In case we want to the set receiver and it is enabled, device is busy.
    */
    if ((i2s_ptr->RCSR & I2S_RCSR_RE_MASK) && (set_rx_as_master))
    {
        return(I2S_ERROR_DEVICE_BUSY);
    }
    if ((io_info_ptr->CLOCK_MODE & I2S_RX_ASYNCHRONOUS) && (set_rx_as_master))
    {
        /* Reset Rx mode setting */
        io_info_ptr->MODE &= 0xF0;
        /* Set Rx in master mode */
        io_info_ptr->MODE |= I2S_RX_MASTER;
        i2s_ptr->RCR2 |= (I2S_RCR2_BCD_MASK);
        i2s_ptr->RCR4 |= (I2S_RCR4_FSD_MASK);
        /* 
        ** If the the transmitter is synchronous settings must same as the
        ** receiver settings.
        */
        if (io_info_ptr->CLOCK_MODE & I2S_TX_SYNCHRONOUS)
        {
            
            io_info_ptr->MODE &= 0x0F;
            io_info_ptr->MODE |= I2S_TX_MASTER;
            i2s_ptr->TCR2 |= (I2S_TCR2_BCD_MASK);
            i2s_ptr->TCR4 |= (I2S_TCR4_FSD_MASK);
        }
        /* 
        ** If receiver have swapped bit clock. Set transmitter bit clock to be
        ** generated internally.
        */
        if (io_info_ptr->CLOCK_MODE & I2S_RX_BCLK_SWAPPED)
        {
            i2s_ptr->TCR2 |= (I2S_TCR2_BCD_MASK);
        }
    }
    return(I2S_OK);
}
/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_set_slave_mode
* Returned Value   : I2S_OK if everything is OK, error code otherwise.  
* Comments         :
*    This function sets up slave mode for TX and RX (called from ioctl)
*
*END*********************************************************************/
static uint_32 _ki2s_set_slave_mode
(
    KSAI_INFO_STRUCT_PTR io_info_ptr, /* Info struct                  */
    uint_8 mode                       /* Required slave mode settings */
)
{
    I2S_MemMapPtr i2s_ptr = io_info_ptr->SAI_PTR;
    boolean set_tx_as_slave = ((mode & I2S_TX_SLAVE) >> 4) && (io_info_ptr->IO_MODE & I2S_IO_WRITE);
    boolean set_rx_as_slave = (mode & I2S_RX_SLAVE) && (io_info_ptr->IO_MODE & I2S_IO_READ);
    /*
    ** Disable the master clock signal and set pin as input. Also reset values
    ** of frequencies in the info structure.
    */
#if PSP_MQX_CPU_IS_VYBRID
    _vi2s_set_clk_src_ext(io_info_ptr->HW_CHANNEL);
#else
    i2s_ptr->MCR &= ~(I2S_MCR_MOE_MASK);
#endif
    io_info_ptr->MCLK_FREQ = 0;
    io_info_ptr->BCLK_FREQ = 0;
    io_info_ptr->FS_FREQ = 0;
    /*
    ** In case we want to setup the transmitter and it is enabled, device is busy.
    */
    if ((i2s_ptr->TCSR & I2S_TCSR_TE_MASK) && (set_tx_as_slave))
    {
        return(I2S_ERROR_DEVICE_BUSY);
    }
    if ((io_info_ptr->CLOCK_MODE & I2S_TX_ASYNCHRONOUS) && (set_tx_as_slave))
    {
        /* Reset Tx mode setting */
        io_info_ptr->MODE &= 0x0F;
        /* Set Tx into slave mode */
        io_info_ptr->MODE |= I2S_TX_SLAVE;
        i2s_ptr->TCR2 &= ~(I2S_TCR2_BCD_MASK);
        i2s_ptr->TCR4 &= ~(I2S_TCR4_FSD_MASK);
        /* 
        ** If the the receiver is synchronous settings must same as the
        ** transmitter settings.
        */
        if (io_info_ptr->CLOCK_MODE & I2S_RX_SYNCHRONOUS)
        {
            io_info_ptr->MODE &= 0xF0;
            io_info_ptr->MODE |= I2S_RX_SLAVE;
            i2s_ptr->RCR2 &= ~(I2S_RCR2_BCD_MASK);
            i2s_ptr->RCR4 &= ~(I2S_RCR4_FSD_MASK);
        }
        /* 
        ** If transmitter have swapped bit clock set receiver bit clock to be
        ** generated externally
        */
        if (io_info_ptr->CLOCK_MODE & I2S_TX_BCLK_SWAPPED)
        {
            i2s_ptr->RCR2 &= ~(I2S_RCR2_BCD_MASK);
        }
    }
    
    /*
    ** In case we want to the setup receiver and it is enabled, device is busy.
    */
    if ((i2s_ptr->RCSR & I2S_RCSR_RE_MASK) && (set_rx_as_slave))
    {
        return(I2S_ERROR_DEVICE_BUSY);
    }
    if ((io_info_ptr->CLOCK_MODE & I2S_RX_ASYNCHRONOUS) && (set_rx_as_slave))
    {
        /* Reset Rx mode setting */
        io_info_ptr->MODE &= 0xF0;
        /* Set Rx in master mode */
        io_info_ptr->MODE |= I2S_RX_SLAVE;
        i2s_ptr->RCR2 &= ~(I2S_RCR2_BCD_MASK);
        i2s_ptr->RCR4 &= ~(I2S_RCR4_FSD_MASK);
        /* 
        ** If the the transmitter is synchronous settings must same as the
        ** receiver settings.
        */
        if (io_info_ptr->CLOCK_MODE & I2S_TX_SYNCHRONOUS)
        {
            
            io_info_ptr->MODE &= 0x0F;
            io_info_ptr->MODE |= I2S_TX_SLAVE;
            i2s_ptr->TCR2 &= ~(I2S_TCR2_BCD_MASK);
            i2s_ptr->TCR4 &= ~(I2S_TCR4_FSD_MASK);
        }
        /* 
        ** If receiver have swapped bit clock. Set transmitter bit clock to be
        ** generated externally.
        */
        if (io_info_ptr->CLOCK_MODE & I2S_RX_BCLK_SWAPPED)
        {
            i2s_ptr->TCR2 &= ~(I2S_TCR2_BCD_MASK);
        }
    }
    return(I2S_OK);
}

/*FUNCTION****************************************************************
*
* Function Name    : _ki2s_set_bclk_mode
* Returned Value   : I2S_OK if everything is OK, error code otherwise.  
* Comments         :
*       This function modifies SAI registers to set up synchronous mode and
*       clock swapping.
*
*END*********************************************************************/
static uint_32 _ki2s_set_bclk_mode
(
    I2S_MemMapPtr i2s_ptr, /* Pointer to registers */
    uint_8 bclk_mode       /* Bit clock mode       */
)
{
    if ((bclk_mode & I2S_TX_SYNCHRONOUS) && (bclk_mode & I2S_RX_SYNCHRONOUS))
    {
        /* Invalid combination of bclk modes */
        return(I2S_ERROR_INVALID_PARAMETER);
    }
    /*
    ** Transmitter clock:
    */
    if (bclk_mode & I2S_TX_ASYNCHRONOUS) // Transmitter is asynchronous
    {
       i2s_ptr->TCR2 &= ~(I2S_TCR2_SYNC_MASK);
    }
    else if (bclk_mode & I2S_TX_SYNCHRONOUS) // Transmitter is synchronous
    {
       /*
       ** If transmitter is synchronous, receiver must be asynchronous
       */
       if (i2s_ptr->RCR2 & I2S_RCR2_SYNC_MASK)
       {
          /* Invalid combination of bclk modes */
          return(I2S_ERROR_INVALID_PARAMETER); 
       }
       i2s_ptr->TCR2 |= (I2S_TCR2_SYNC(1));
    }
   
    if (bclk_mode & I2S_TX_BCLK_NORMAL) // Transmitter BCLK not swapped
    {
        i2s_ptr->TCR2 &= ~(I2S_TCR2_BCS_MASK);
    }
    else if (bclk_mode & I2S_TX_BCLK_SWAPPED) // Transmitter BCLK swapped
    {
       /*
       ** TX_BCLK = SAI_RX_BCLK
       ** TX_FS = SAI_TX_SYNC
       */
       i2s_ptr->TCR2 |= (I2S_TCR2_BCS_MASK);
       /*
       ** When Tx is synch. BCS bit must be set also for Rx.
       */
       if (bclk_mode & I2S_TX_SYNCHRONOUS) 
       {
           /*
           ** TX_BCLK = SAI_TX_BCLK
           ** TX_FS = SAI_RX_SYNC
           */
           i2s_ptr->RCR2 |= (I2S_RCR2_BCS_MASK);
       }
    }
   
    /*
    ** Receiver clock:
    */
    if (bclk_mode & I2S_RX_ASYNCHRONOUS) // Receiver is asynchronous
    {
        i2s_ptr->RCR2 &= ~(I2S_RCR2_SYNC_MASK);
    }
    else if (bclk_mode & I2S_RX_SYNCHRONOUS) // Receiver is synchronous
    {
        /*
        ** If receiver is synchronous, transmitter must be asynchronous
        */
        if (i2s_ptr->TCR2 & I2S_TCR2_SYNC_MASK)
        {
            /* Invalid combination of bclk modes */
            return(I2S_ERROR_INVALID_PARAMETER); 
        }
        i2s_ptr->RCR2 |= (I2S_RCR2_SYNC(1));
    }
   
    if (bclk_mode & I2S_RX_BCLK_NORMAL) // Receiver BCLK not swapped
    {
        i2s_ptr->RCR2 &= ~(I2S_RCR2_BCS_MASK);
    }
    else if (bclk_mode & I2S_RX_BCLK_SWAPPED) // Receiver BCLK swapped
    {
        /*
        ** RX_BCLK = SAI_TX_BCLK
        ** RX_FS = SAI_RX_SYNC
        */
        i2s_ptr->RCR2 |= (I2S_RCR2_BCS_MASK);
        /*
        ** When Rx is synch. BCS bit must be set also for Tx.
        */
        if (bclk_mode & I2S_RX_SYNCHRONOUS)
        {
            /*
            ** RX_BCLK = SAI_RX_BCLK
            ** RX_FS = SAI_TX_SYNC
            */
            i2s_ptr->TCR2 |= (I2S_TCR2_BCS_MASK);
        }
    }
    return(I2S_OK);
}
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/compiler/iar/asm_mac.h<|end_filename|>
/**HEADER*********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2008 Embedded Access Inc.;
* All Rights Reserved
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* $FileName: asm_mac.h$
* $Version : 3.8.6.0$
* $Date    : Oct-3-2012$
*
* Comments:
*   This file contains macros used by the IAR ARM assembler
*
*END*************************************************************************/

#ifndef __asm_mac_h__
#define __asm_mac_h__   1

#define ASM_PREFIX(x) x

#define ASM_LABEL(value)      value
#define ASM_EXTERN(value)     EXTERN  value
#define ASM_ALIGN(value)      ALIGNROM  value/4
#define ASM_PUBLIC(label)     PUBLIC label
#define ASM_SET(label, value) ASM_LABEL(label) SET value
#define ASM_CONST16(value)    DC16 value
#define ASM_CONST32(value)    DC32 value
#define ASM_LABEL_CONST32(label, value) ASM_LABEL(label) DC32 value
#define ASM_DATA_SECTION(label)    SECTION label : DATA (4)
#define ASM_CODE_SECTION(label)    SECTION label : CODE (4)  
#define ASM_CODE_SECTION_NOOPT(label)    SECTION label : CODE (4) : ROOT  
#define ASM_END               END
#define ASM_COMP_SPECIFIC_DIRECTIVES
#define ASM_EQUATE(label, value) label   EQU  value

/* CFI annotations for public symbols called from C code */

  CFI Names CFINames0
  CFI StackFrame CFA R13 DATA
  CFI Resource R0:32, R1:32, R2:32, R3:32, R4:32, R5:32, R6:32, R7:32
  CFI Resource R8:32, R9:32, R10:32, R11:32, R12:32, R13:32, R14:32
  CFI EndNames         CFINames0

  CFI Common CFICommon0 Using         CFINames0
  CFI CodeAlign 2
  CFI DataAlign 4
  CFI ReturnAddress R14 CODE
  CFI CFA R13+0
  CFI R0 SameValue
  CFI R1 SameValue
  CFI R2 SameValue
  CFI R3 SameValue
  CFI R4 SameValue
  CFI R5 SameValue
  CFI R6 SameValue
  CFI R7 SameValue
  CFI R8 SameValue
  CFI R9 SameValue
  CFI R10 SameValue
  CFI R11 SameValue
  CFI R12 SameValue
  CFI R14 SameValue
  CFI EndCommon CFICommon0

/* Note that these macros should NOT be on the beggining of line when used
   in assembler code. Prepend allways by at least one space. 
   (was not an issue in EWARM 6.40.x, space seems to be needed in 6.50.x) */
#define ASM_PUBLIC_BEGIN(name) CFI Block CFIBlock_##name Using CFICommon0
#define ASM_PUBLIC_FUNC(name)  CFI Function name
#define ASM_PUBLIC_END(name)   CFI EndBlock CFIBlock_##name

#endif /* __asm_mac_h__ */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/include/dev_cnfg.h<|end_filename|>
#ifndef __usbdev_cnfg_h__
#define __usbdev_cnfg_h__

#include "mqx.h"
#include "bsp.h"        // bsp.h include user_config.h, too

#ifndef USBCFG_DEFAULT_DEVICE_CONTROLLER
#define USBCFG_DEFAULT_DEVICE_CONTROLLER  (0)
#endif

#ifndef USBCFG_MAX_DRIVERS
extern const pointer _bsp_usb_table[];
#define USBCFG_MAX_DRIVERS                (sizeof(_bsp_usb_table) / sizeof(_bsp_usb_table[0]))
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/sonat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sonat.c$
* $Version : 3.6.3.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the implementation of getsockopt()
*   and setsockopt() at the SOL_NAT level.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>
#include <stddef.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"


#define RTCS_ENTER(f,a) RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_NAT_ ## f, a)

#define RTCS_EXIT(f,a)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_NAT_ ## f, a); \
                        return a


uint_32 SOL_NAT_getsockopt  (uint_32, uint_32, uint_32, pointer, uint_32 _PTR_);
uint_32 SOL_NAT_setsockopt  (uint_32, uint_32, uint_32, pointer, uint_32);

const RTCS_SOCKOPT_CALL_STRUCT SOL_NAT_CALL = {
   SOL_NAT_getsockopt,
   SOL_NAT_setsockopt
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_NAT_getsockopt
* Returned Value  : error code
* Comments  :  Obtain the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_NAT_getsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] buffer for the current value of the option */
      uint_32  _PTR_ optlen
         /* [IN/OUT] length of the option value, in bytes */
   )
{ /* Body */
   NAT_PARM                   parms;
   uint_32                    error;

   RTCS_ENTER(GETSOCKOPT, sock);

   parms.LEN_PTR = optlen;
   parms.OPTION = optname;
   parms.CONFIG = optval;

   error = RTCSCMD_issue(parms, NAT_getopt);

   RTCS_EXIT(GETSOCKOPT, error);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOL_NAT_setsockopt
* Returned Value  : error code
* Comments  :  Modify the current value for a socket option.
*
*END*-----------------------------------------------------------------*/

uint_32  SOL_NAT_setsockopt
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        level,
         /* [IN] protocol level for the option */
      uint_32        optname,
         /* [IN] name of the option */
      pointer        optval,
         /* [IN] new value for the option */
      uint_32        optlen
         /* [IN] length of the option value, in bytes */
   )
{ /* Body */
   NAT_PARM                parms;
   uint_32                 error;

   RTCS_ENTER(SETSOCKOPT, sock);

   parms.LEN_PTR = &optlen;
   parms.OPTION = optname;
   parms.CONFIG = optval;

   error = RTCSCMD_issue(parms, NAT_setopt);

   if (error) {
      RTCS_EXIT(SETSOCKOPT, error);
   } /* Endif */

   RTCS_EXIT(SETSOCKOPT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_setopt
* Parameters      :
*
*        _ip_address       IP_PRV      not used
*        _ip_address       IP_MASK     not used
*        uint_32_ptr       LEN_PTR     [IN] length of option value
*        uint_32           OPTION      [IN] option
*        pointer           CONFIG      [IN] option value
*
* Comments        :
*     Sets the value of a NAT option.
*
*END*-----------------------------------------------------------------*/

void NAT_setopt
   (
      NAT_PARM_PTR      parm_ptr
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR   nat_cfg = RTCS_getcfg(NAT);
   uint_32     error = RTCS_OK;

   if (nat_cfg==NULL) {
      RTCSCMD_complete(parm_ptr, RTCSERR_NAT_NOT_INITIALIZED);
      return;
   } /* Endif */

   if (parm_ptr->CONFIG == NULL) {
      RTCSCMD_complete(parm_ptr, RTCSERR_INVALID_ADDRESS);
      return;
   } /* Endif */

   switch (parm_ptr->OPTION) {

      case RTCS_SO_NAT_TIMEOUTS:
         if (*parm_ptr->LEN_PTR < sizeof(NAT_TIMEOUTS_STRUCT)) {
            error = RTCSERR_SOCK_SHORT_OPTION;
         } else {
            NAT_config_timeouts(parm_ptr->CONFIG);
         } /* Endif */
         break;

      case RTCS_SO_NAT_PORTS:
         if (*parm_ptr->LEN_PTR < sizeof(NAT_PORTS_STRUCT)) {
            error = RTCSERR_SOCK_SHORT_OPTION;
         } else {
            NAT_config_ports(parm_ptr->CONFIG);
         } /* Endif */
         break;


  default:
      error = RTCSERR_SOCK_INVALID_OPTION;
   } /* Endswitch */

   RTCSCMD_complete(parm_ptr, error);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : NAT_getopt
* Parameters      :
*
*        _ip_address       IP_PRV      not used
*        _ip_address       IP_MASK     not used
*        uint_32_ptr       LEN_PTR     [IN/OUT] length of option value
*        uint_32           OPTION      [IN] option
*        pointer           CONFIG      [OUT] option value
*
* Comments        :
*     Retrieves the value of a NAT option.
*
*END*-----------------------------------------------------------------*/

void NAT_getopt
   (
      NAT_PARM_PTR      parm_ptr
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   NAT_TIMEOUTS_STRUCT_PTR nat_timeouts_ptr;
   NAT_PORTS_STRUCT_PTR    nat_ports_ptr;
   uint_32                 error = RTCS_OK;
   uint_32                 len = 0;

   if (nat_cfg_ptr==NULL) {
      RTCSCMD_complete(parm_ptr, RTCSERR_NAT_NOT_INITIALIZED);
      return;
   } /* Endif */

   if ((parm_ptr->CONFIG == NULL) || (parm_ptr->LEN_PTR == NULL)) {
      RTCSCMD_complete(parm_ptr, RTCSERR_INVALID_ADDRESS);
      return;
   } /* Endif */
   switch (parm_ptr->OPTION) {

      case RTCS_SO_NAT_TIMEOUTS:
         len = sizeof(NAT_TIMEOUTS_STRUCT);

         if (*parm_ptr->LEN_PTR >= sizeof(NAT_TIMEOUTS_STRUCT)) {
            nat_timeouts_ptr = parm_ptr->CONFIG;
            nat_timeouts_ptr->timeout_tcp = nat_cfg_ptr->TIMEOUT_TCP;
            nat_timeouts_ptr->timeout_fin = nat_cfg_ptr->TIMEOUT_FIN;
            nat_timeouts_ptr->timeout_udp = nat_cfg_ptr->TIMEOUT_UDP;
            nat_timeouts_ptr->timeout_icmp = nat_cfg_ptr->TIMEOUT_ICMP;
         } else {
            NAT_TIMEOUTS_STRUCT   temp;

            temp.timeout_tcp = nat_cfg_ptr->TIMEOUT_TCP;
            temp.timeout_fin = nat_cfg_ptr->TIMEOUT_FIN;
            temp.timeout_udp = nat_cfg_ptr->TIMEOUT_UDP;
            temp.timeout_icmp = nat_cfg_ptr->TIMEOUT_ICMP;
            _mem_copy(&temp, parm_ptr->CONFIG, *parm_ptr->LEN_PTR);
         } /* Endif */

         break;

      case RTCS_SO_NAT_PORTS:
         len = sizeof(NAT_PORTS_STRUCT);

         if (*parm_ptr->LEN_PTR >= sizeof(NAT_PORTS_STRUCT)) {
            nat_ports_ptr = parm_ptr->CONFIG;
            nat_ports_ptr->port_min = nat_cfg_ptr->PORT_MIN;
            nat_ports_ptr->port_max = nat_cfg_ptr->PORT_MAX;
         } else {
            NAT_PORTS_STRUCT   temp;

            temp.port_min = nat_cfg_ptr->PORT_MIN;
            temp.port_max = nat_cfg_ptr->PORT_MAX;
            _mem_copy(&temp, parm_ptr->CONFIG, *parm_ptr->LEN_PTR);
         } /* Endif */

         break;

   default:
      error = RTCSERR_SOCK_INVALID_OPTION;
   } /* Endswitch */

   if (error == RTCS_OK) {
   *parm_ptr->LEN_PTR = len;
   }

   RTCSCMD_complete(parm_ptr, error);

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/tftp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tftp.c$
* $Version : 3.8.13.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the TFTP client implementation for
*   the Exec function of the RTCS Communication Library.
*
*END************************************************************************/

#include <rtcs.h>

#if RTCSCFG_ENABLE_UDP

#include <fio.h>
#include "tftp.h"

/* The File Transfer client information to pass to RTCS_load() */
uint_32   TFTP_open  (pointer ft_data);
uchar_ptr TFTP_read  (uint_32_ptr size);
boolean   TFTP_eof   (void);
uint_32   TFTP_close (void);

static FT_CALL_STRUCT ft_tftp = {
   TFTP_open,
   TFTP_read,
   TFTP_eof,
   TFTP_close
};

const FT_CALL_STRUCT_PTR FT_TFTP = &ft_tftp;

/* TFTP state information */
static struct {
   TFTP_PACKET    PACKET;
   TFTP_HEADER    ACK;
   sockaddr_in    SADDR;
   uchar_ptr      RRQ_PTR;
   uint_32        RRQ_LEN;
   TFTP_TO_STRUCT TIMEOUT;
   uint_32        SOCK;
   boolean        LAST;
} TFTP_config;


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TFTP_open
* Returned Value   : socket handle or RTCS_ERROR
* Comments  :  Routine to initiate a TFTP session.
*
*END*-----------------------------------------------------------------*/

uint_32 TFTP_open
   (
      pointer  ft_data
         /* [IN] the address and filename of the bootimage */
   )
{ /* Body */
   TFTP_DATA_STRUCT_PTR    tftp;
   sockaddr_in             local_addr;
   char_ptr                str_ptr;
   uchar_ptr               packet;
   uint_32                 sock;
   uint_32                 error;
   uint_32                 fn_len, fm_len;
   uint_32                 pkt_len;

   tftp = (TFTP_DATA_STRUCT_PTR) ft_data;

   /* Get a socket */
   sock = socket(AF_INET, SOCK_DGRAM, 0);
   if (sock == RTCS_SOCKET_ERROR) {
      return RTCSERR_TFTP_SOCKET;
   } /* Endif */

   /* Must be initialized in order for TFTP_close to be able to release socket and memory */
   TFTP_config.SOCK = sock;  
   TFTP_config.RRQ_PTR = NULL;  

   /* Bind it */
   local_addr.sin_family      = AF_INET;
   local_addr.sin_port        = 0;
   local_addr.sin_addr.s_addr = INADDR_ANY;
   error = bind(sock, (const sockaddr *)&local_addr, sizeof(local_addr));
   if (error != RTCS_OK) {
      TFTP_close();
      return error;
   } /* Endif */

   if ( (tftp->FILENAME == NULL) || (tftp->FILEMODE == NULL) ){      
      TFTP_close();
      return TFTPERR_FILE_NOT_FOUND;
   } /* Endif */

   /* Prepare a read request (RRQ) */
   str_ptr = tftp->FILENAME;
   while (*str_ptr++) {};
   fn_len = str_ptr - tftp->FILENAME;
   str_ptr = tftp->FILEMODE;
   while (*str_ptr++) {};
   fm_len = str_ptr - tftp->FILEMODE;
   pkt_len = 2 + fn_len + fm_len;
   packet = RTCS_mem_alloc(pkt_len);
   if (packet == NULL) {
      TFTP_close();
      return RTCSERR_TFTP_RRQ_ALLOC;
   } /* Endif */
   _mem_set_type(packet, MEM_TYPE_TFTP_PACKET);
   TFTP_config.RRQ_PTR = packet;  
   htons(packet, TFTPOP_RRQ);
   _mem_copy(tftp->FILENAME, &packet[       2], fn_len);
   _mem_copy(tftp->FILEMODE, &packet[fn_len+2], fm_len);

   /* Send the RRQ */
   TFTP_config.SOCK = sock;
   TFTP_config.SADDR.sin_family      = AF_INET;
   TFTP_config.SADDR.sin_port        = IPPORT_TFTP;
   TFTP_config.SADDR.sin_addr.s_addr = tftp->SERVER;
   TFTP_timeout_init(&TFTP_config.TIMEOUT);
   error = sendto(sock, packet, pkt_len, 0,
                  (sockaddr *)(&TFTP_config.SADDR), sizeof(TFTP_config.SADDR));
   if (error != pkt_len) {
      TFTP_close();
      return RTCSERR_TFTP_RRQ_SEND;
   } /* Endif */

   /* Initialize the TFTP client */
   TFTP_config.RRQ_PTR = packet;
   TFTP_config.RRQ_LEN = pkt_len;
   TFTP_config.LAST    = FALSE;
   htons(TFTP_config.ACK.OP,    TFTPOP_ACK);
   htons(TFTP_config.ACK.BLOCK, 0);
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TFTP_read
* Returned Value   : pointer to read data, or NULL on error
* Comments  :  Routine to retrieve one file block via TFTP.
*
*END*-----------------------------------------------------------------*/

uchar_ptr TFTP_read
   (
      uint_32_ptr    size
         /* [OUT] number of bytes read, or error code */
   )
{ /* Body */
   uint_32        sock;
   sockaddr_in    remote_addr;
   uint_16        remote_size;
   uint_16        ack_block;
   uint_16        pkt_op, pkt_block;
   uint_32        pkt_size;
   uint_32        time_left;
   boolean        expired;
#if TFTP_TIMEOUT_RETRIES
   uint_32        retries = 0;
#endif

   ack_block = ntohs(TFTP_config.ACK.BLOCK);
   TFTP_timeout_restart(&TFTP_config.TIMEOUT);

   for (;;) {

      /* Check for timeout */
      time_left = TFTP_timeout_left(&TFTP_config.TIMEOUT, &expired);
      if (expired) {
#if TFTP_TIMEOUT_RETRIES
         retries++;
         if (retries > TFTP_TIMEOUT_RETRIES) {
            *size = RTCSERR_TFTP_TIMEOUT;
            TFTP_close();
            return NULL;
         } /* Endif */
#endif
         /* Retransmit the last packet */
         TFTP_RESEND();
      } /* Endif */

      /* Wait for a packet */
      sock = TFTP_WAIT(time_left);

      /* Timeout -- retransmit last packet */
      if (sock != TFTP_config.SOCK) {
         continue;
      } /* Endif */

      remote_size = sizeof(remote_addr);
      pkt_size = TFTP_RECV(TFTP_config.PACKET);

      pkt_op    = ntohs(TFTP_config.PACKET.HEAD.OP);
      pkt_block = ntohs(TFTP_config.PACKET.HEAD.BLOCK);

      /* Check source address of received packet */
      if (remote_addr.sin_addr.s_addr != TFTP_config.SADDR.sin_addr.s_addr) {
         continue;
      } /* Endif */

      /* Validate source port */
      if (ack_block && remote_addr.sin_port != TFTP_config.SADDR.sin_port) {
         TFTP_SEND(TFTP_config.SOCK, _tftp_error_tid, remote_addr);
         continue;
      } /* Endif */

      /* Check size of received packet */
      if (pkt_size < sizeof(TFTP_HEADER)) {
         TFTP_SEND(TFTP_config.SOCK, _tftp_error_op, remote_addr);
         *size = RTCSERR_TFTP_ERROR + TFTPERR_ILLEGAL_OP;
         TFTP_close();
         return NULL;
      } /* Endif */

      /* Check for error packet */
      if (pkt_op == TFTPOP_ERROR) {
         *size = RTCSERR_TFTP_ERROR + pkt_block;
         TFTP_close();
         return NULL;
      } /* Endif */

      /* Check for data packet */
      if ((pkt_op != TFTPOP_DATA)
       || (pkt_size > sizeof(TFTP_PACKET))) {
         TFTP_SEND(TFTP_config.SOCK, _tftp_error_op, remote_addr);
         *size = RTCSERR_TFTP_ERROR + TFTPERR_ILLEGAL_OP;
         TFTP_close();
         return NULL;
      } /* Endif */

      /* Check for retransmitted packet */
      if (pkt_block == ack_block) {
         TFTP_timeout_restart(&TFTP_config.TIMEOUT);
         TFTP_SEND(TFTP_config.SOCK, TFTP_config.ACK, TFTP_config.SADDR);
         continue;
      } /* Endif */

      /* Aknowledge also packets with lower id, some servers do retransmit them until they get an ack */
      if (pkt_block < ack_block) {
         TFTP_timeout_restart(&TFTP_config.TIMEOUT);
         htons(TFTP_config.ACK.BLOCK, pkt_block);
         TFTP_SEND(TFTP_config.SOCK, TFTP_config.ACK, TFTP_config.SADDR);
         htons(TFTP_config.ACK.BLOCK, ack_block); /* Restore id of last acknowledged packet */
         continue;
      } /* Endif */

      /* Drop unexpected packets */
      if (pkt_block > ack_block+1) {
         /* Some server do send more than one packet at a time, these will eventually retransmitted */
         continue;
      }

      /* We have the next packet */
      break;
   } /* Endfor */

   /* Update the adaptive timeout */
   TFTP_timeout_update(&TFTP_config.TIMEOUT);

   /* Free the original RRQ */
   if (!ack_block) {
      TFTP_config.SADDR.sin_port = remote_addr.sin_port;
      _mem_free(TFTP_config.RRQ_PTR);
      TFTP_config.RRQ_PTR = NULL;
   } /* Endif */

   /* ACK it */
   ack_block++;
   htons(TFTP_config.ACK.BLOCK, ack_block);
   TFTP_SEND(TFTP_config.SOCK, TFTP_config.ACK, TFTP_config.SADDR);
   TFTP_config.LAST = (pkt_size < sizeof(TFTP_PACKET));

   /* Return the data */
   *size = pkt_size - sizeof(TFTP_HEADER);
   return TFTP_config.PACKET.DATA;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TFTP_eof
* Returned Value   : TRUE or FALSE
* Comments  :  Routine to determine whether the file transfer is complete.
*
*END*-----------------------------------------------------------------*/

boolean TFTP_eof
   (
      void
   )
{ /* Body */

   return TFTP_config.LAST;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TFTP_close
* Returned Value   : error code
* Comments  :  Routine to close a TFTP session.
*
*END*-----------------------------------------------------------------*/

uint_32 TFTP_close
   (
      void
   )
{ /* Body */
   uint_32  result = RTCSERR_SOCK_INVALID;

   if (TFTP_config.RRQ_PTR != NULL)  {
      _mem_free(TFTP_config.RRQ_PTR);  
      TFTP_config.RRQ_PTR = NULL; 
   }

   if (TFTP_config.SOCK != RTCS_SOCKET_ERROR)  {
      result = shutdown(TFTP_config.SOCK, 0);
      TFTP_config.SOCK = RTCS_SOCKET_ERROR;
      TFTP_config.LAST = TRUE;
   }
   return result;
   
} /* Endbody */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lpm/lpm_kinetis.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* $FileName: lpm_kinetis.h$
* $Version : 3.8.5.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   Low Power Manager declarations specific to Kinetis.
*
*END************************************************************************/


#ifndef __lpm_kinetis_h__
#define __lpm_kinetis_h__

/*-------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

typedef enum 
{
    LPM_CPU_POWER_MODE_RUN = 0,
    LPM_CPU_POWER_MODE_WAIT,
    LPM_CPU_POWER_MODE_STOP,
    LPM_CPU_POWER_MODE_VLPR,
    LPM_CPU_POWER_MODE_VLPW,
    LPM_CPU_POWER_MODE_VLPS,
    LPM_CPU_POWER_MODE_LLS,
    LPM_CPU_POWER_MODES
} LPM_CPU_POWER_MODE_INDEX;

#define LPM_CPU_POWER_MODE_FLAG_DEEP_SLEEP          (0x01)
#define LPM_CPU_POWER_MODE_FLAG_USE_WFI             (0x02)
#define LPM_CPU_POWER_MODE_FLAG_SLEEP_ON_EXIT       (0x04)
#define LPM_CPU_POWER_MODE_FLAG_USER_MASK           (LPM_CPU_POWER_MODE_FLAG_SLEEP_ON_EXIT)

#ifndef SMC_PMCTRL_LPWUI_MASK
#define SMC_PMCTRL_LPWUI_MASK                       (0x80)
#endif

/*-------------------------------------------------------------------------*/
/*
**                            MACRO DECLARATIONS
*/


/*-------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/

typedef struct lpm_cpu_power_mode {
    /* Mode control register setup */
    uint_8      PMCTRL;

    /* Flags specifying low power mode behavior */
    uint_8      FLAGS;

} LPM_CPU_POWER_MODE, _PTR_ LPM_CPU_POWER_MODE_PTR;


typedef struct lpm_cpu_operation_mode {
    /* Index into predefined cpu operation modes */
    LPM_CPU_POWER_MODE_INDEX    MODE_INDEX;

    /* Additional modification flags */
    uint_8                      FLAGS;

    /* LLWU specific settings */
    uint_8                      PE1;
    uint_8                      PE2;
    uint_8                      PE3;
    uint_8                      PE4;
    uint_8                      ME;
    
} LPM_CPU_OPERATION_MODE, _PTR_ LPM_CPU_OPERATION_MODE_PTR;


/*-------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

    
extern _mqx_uint _lpm_set_cpu_operation_mode (const LPM_CPU_OPERATION_MODE _PTR_, LPM_OPERATION_MODE);
extern void      _lpm_wakeup_core (void);
extern _mqx_uint _lpm_idle_sleep_check (void);


#ifdef __cplusplus
}
#endif


#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fopen.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fopen.c$
* $Version : 3.6.7.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   Contains the function fopen.
*
*END************************************************************************/

#include <string.h>
#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io_prv.h"

#if MQX_USE_IO

/*!
 * \brief The returned value is a pointer to an I/O model.
 * 
 * \param[in] open_type_ptr The name of the device to open.
 * \param[in] open_mode_ptr I/O initialization parameter to pass to the device 
 * initialization.
 * 
 * \return Pointer to MQX_FILE structure
 * \return NULL (Failure.)  
 */ 
MQX_FILE_PTR _io_fopen
   ( 
      const char _PTR_ open_type_ptr,
      const char _PTR_ open_mode_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   MQX_FILE_PTR           file_ptr;
   IO_DEVICE_STRUCT_PTR   dev_ptr;
   char _PTR_             dev_name_ptr;
   char _PTR_             tmp_ptr;
   _mqx_int                result;

   _GET_KERNEL_DATA(kernel_data);

   _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)kernel_data->IO_DEVICES.NEXT);
   while (dev_ptr != (pointer)&kernel_data->IO_DEVICES.NEXT) {
      dev_name_ptr = dev_ptr->IDENTIFIER;
      tmp_ptr      = (char _PTR_)open_type_ptr;
      while (*tmp_ptr && *dev_name_ptr &&
         (*tmp_ptr == *dev_name_ptr))
      {
         ++tmp_ptr;
         ++dev_name_ptr;
      } /* Endwhile */
      if (*dev_name_ptr == '\0') {
         /* Match */
         break;
      } /* Endif */
      dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)dev_ptr->QUEUE_ELEMENT.NEXT);
   } /* Endwhile */
   
   _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   
   if (dev_ptr == (pointer)&kernel_data->IO_DEVICES.NEXT) {
      return(NULL);
   } /* Endif */

   file_ptr = (MQX_FILE_PTR)_mem_alloc_system_zero((_mem_size)sizeof(MQX_FILE));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (file_ptr == NULL) {
      return(NULL);
   } /* Endif */
#endif
   _mem_set_type(file_ptr, MEM_TYPE_FILE_PTR);
   
   file_ptr->DEV_PTR = dev_ptr;
   if (dev_ptr->IO_OPEN != NULL) {
      result = (*dev_ptr->IO_OPEN)(file_ptr, (char _PTR_)open_type_ptr, (char _PTR_)open_mode_ptr);
      if (result != MQX_OK) {
         _task_set_error(result);
         _mem_free(file_ptr);
         return(NULL);
      } /* Endif */
   } /* Endif */

   return(file_ptr);

} /* Endbody */
#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_copy.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_copy.c$
* $Version : 3.8.16.0$
* $Date    : Aug-6-2012$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_prv.h>

#if SHELLCFG_USES_MFS
#define MIN_COPY_BLOCK_SIZE  512
#define MAX_COPY_BLOCK_SIZE 8192

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  Shell_copy
* Returned Value   :  uint_32 error code
* Comments  :  Renames or moves a file.
*
*END*---------------------------------------------------------------------*/

int_32  Shell_copy(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean     print_usage, shorthelp = FALSE;
   int_32      size = 0, wsize = 0, copysize = MAX_COPY_BLOCK_SIZE, return_code = SHELL_EXIT_SUCCESS;
   MQX_FILE_PTR in_fd=NULL, out_fd=NULL;
   char_ptr    abs_path=NULL;   
   boolean     cache_enabled=TRUE;
   char_ptr    copybuffer = NULL;
   _mqx_int    c;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   int_32               error = 0;

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  
   {
      if (argc != 3)  
      {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } 
      /* check if filesystem is mounted */ 
      else if (NULL == Shell_get_current_filesystem(argv))  
      {
         printf("Error, file system not mounted\n");
         return_code = SHELL_EXIT_ERROR;
      }
      else if (MFS_alloc_path(&abs_path) != MFS_NO_ERROR) 
      {
         printf("Error, unable to allocate memory for paths\n" );
         return_code = SHELL_EXIT_ERROR;
      } 
      else 
      {
         error = _io_rel2abs(abs_path,shell_ptr->CURRENT_DIR,(char *) argv[1],PATHNAME_SIZE,shell_ptr->CURRENT_DEVICE_NAME);
         if(!error)
         {
             in_fd = fopen(abs_path, "r");
         }
         
         if (in_fd == NULL || error)  {
             printf("Error, unable to open source file\n" );
             return_code = SHELL_EXIT_ERROR;
         } else {
            error = _io_rel2abs(abs_path,shell_ptr->CURRENT_DIR,(char *) argv[2],PATHNAME_SIZE,shell_ptr->CURRENT_DEVICE_NAME);
            if(!error)
            {
                out_fd = fopen(abs_path, "w");
            }
            if (out_fd == NULL || error)  {
               printf("Error, unable to create destination file\n" );
               return_code = SHELL_EXIT_ERROR;
            } else {
               MFS_free_path(abs_path);         
               abs_path = NULL;

               do {
                  copybuffer = _mem_alloc(copysize);
                  if (copybuffer != NULL) break;
                  else copysize >>= 1;
               } while (copysize >= MIN_COPY_BLOCK_SIZE);
               
               if (copybuffer == NULL)
               {
                  printf("Warning, unable to allocate copy buffer, copy will be slower\n" );
                  while ((c = fgetc(in_fd)) >= 0) {
                     fputc(c, out_fd);
                  }
               }
               else {
                  do {
                     size = read(in_fd, copybuffer, copysize);
                     if (size > 0) {
                        wsize = write(out_fd, copybuffer, size);
                     }
                     else
                        break;
                  } while (wsize == size);
               }
            }
         }
         if (abs_path) MFS_free_path(abs_path);
         if (copybuffer) _mem_free(copybuffer);
         if (in_fd) fclose(in_fd); 
         if (out_fd) fclose(out_fd); 
      }
   }
      
      
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <source> <dest> \n", argv[0]);
      } else  {
         printf("Usage: %s <source> <dest>\n", argv[0]);
         printf("   <source> = source file to copy\n");
         printf("   <dest>   = name of new file\n");
      }
   }
   return return_code;
} /* Endbody */
#endif //SHELLCFG_USES_MFS

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/device/dev_main.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dev_main.c$
* $Version : 3.8.8.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
*  This file contains the main USB device API functions that will be 
*  used by most applications.
*                                                               
*END*********************************************************************/
#include <mqx.h>
#include <bsp.h>

#include "usb.h"     //common public
#include "usb_prv.h" //common private
#include "usb_bsp.h" 

#include "dev_cnfg.h"
#include "devapi.h"  //device public
#include "dev_main.h" //device private


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_free_XD
*  Returned Value : void
*  Comments       :
*        Enqueues a XD onto the free XD ring.
*
*END*-----------------------------------------------------------------*/

void _usb_device_free_XD
   (
     _usb_device_handle  handle,
      /* [IN] the dTD to enqueue */
      pointer  xd_ptr
   )
{ /* Body */
    USB_DEV_STATE_STRUCT_PTR usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   USB_lock();

   /*
   ** Add the XD to the free XD queue (linked via PRIVATE) and
   ** increment the tail to the next descriptor
   */
   USB_XD_QADD(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, (struct xd_struct *)xd_ptr);
   usb_dev_ptr->XD_ENTRIES++;

   USB_unlock();
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_init
*  Returned Value : USB_OK or error code
*  Comments       :
*        Initializes the USB device specific data structures and calls 
*  the low-level device controller chip initialization routine.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_init
   (
      /* [IN] the USB device controller to initialize */
      struct usb_dev_if_struct  *usb_if,

      /* [OUT] the USB_USB_dev_initialize state structure */
      _usb_device_handle _PTR_  handle,

      /* [IN] number of endpoints to initialize */
      _mqx_uint                 endpoints
   )
{ /* Body */
    USB_DEV_IF_STRUCT_PTR            usb_c;
    USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
    _mqx_uint                        temp, i, j;
    SCRATCH_STRUCT_PTR               temp_scratch_ptr;
    USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR call_back_table_ptr;
    USB_STATUS                       error;
    USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR dev_if;
    
   /* Check usb_if structure */
   if (usb_if == NULL) {
      return USBERR_DEVICE_NOT_FOUND;
   }
   if (usb_if->DEV_IF == NULL) {
      /* The interface does not support device functionality */
      return USBERR_DEVICE_NOT_FOUND;
   }

   USB_lock();

   usb_c = _mqx_get_io_component_handle(IO_USB_COMPONENT);

   /* Check if the interface is registered */
   if (!usb_c) {
      /* No interface was registered yet */
      USB_unlock();
      return USBERR_DEVICE_NOT_FOUND;
   }
   else {
      /* Find out if the interface has been installed */
      for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
         if (usb_c[i].DEV_INIT_PARAM == usb_if->DEV_INIT_PARAM) {
            /* Found installed device */
            break;
         }
      }
   }

   if (i == USBCFG_MAX_DRIVERS) {
      /* The interface has not been registered, so it cannot be initialized */
      USB_unlock();
      return USBERR_DEVICE_NOT_FOUND;
   }
   else {
      /* check if the registered interface was already initialized */
      if (usb_c[i].DEV_HANDLE != NULL) {
         /* The interface was already installed- return handle and USBERR_DEVICE_BUSY value */
         *handle = (_usb_device_handle) usb_c[i].DEV_HANDLE;

         USB_unlock();
         return USBERR_DEVICE_BUSY;
      }
   }

   dev_if = (USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR) usb_c[i].DEV_IF;
   /* Initialize the USB interface. */
   if (dev_if->DEV_PREINIT != NULL)
   {
      error = dev_if->DEV_PREINIT((_usb_device_handle _PTR_) &usb_dev_ptr);
   }
      
   if (usb_dev_ptr == NULL)
   {
      #ifdef _DEV_DEBUG
         printf("1 memalloc failed in _usb_device_init\n");
      #endif  
      USB_unlock();
      return USBERR_ALLOC_STATE;
   } /* Endif */
   
   usb_dev_ptr->CALLBACK_STRUCT_PTR = (pointer) usb_c[i].DEV_IF;
   usb_dev_ptr->INIT_PARAM = usb_c[i].DEV_INIT_PARAM;

   error = _bsp_usb_dev_init(&usb_c[i]);

   if (error != MQX_OK)
   {     
      USB_unlock();
      USB_mem_free(usb_dev_ptr->TEMP_XD_PTR);
      USB_mem_free(usb_dev_ptr->XD_SCRATCH_STRUCT_BASE);
      USB_mem_free(usb_dev_ptr->XD_BASE);
      USB_mem_free(usb_dev_ptr);
      return USBERR_UNKNOWN_ERROR;
   }

   /* Initialize the USB controller chip */
   if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
      usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_INIT != NULL) 
   {
       error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR) usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_INIT(usb_dev_ptr);     
   }
   else
   {
        #ifdef _DEV_DEBUG
            printf("_usb_device_init: DEV_INIT is NULL\n");                   
        #endif  
        return USBERR_ERROR;
   }

   if (error) 
   {
      USB_unlock();
      USB_mem_free(usb_dev_ptr->TEMP_XD_PTR);
      USB_mem_free(usb_dev_ptr->XD_SCRATCH_STRUCT_BASE);
      USB_mem_free(usb_dev_ptr->XD_BASE);
      USB_mem_free(usb_dev_ptr);
      return USBERR_INIT_FAILED;
   } /* Endif */
   
   usb_c[i].DEV_HANDLE = *handle = usb_dev_ptr;  

   USB_unlock();

   return error;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_deinit
*  Returned Value : USB_OK or error code
*  Comments       :
*  uninitializes the USB device specific data structures and calls 
*  the low-level device controller chip initialization routine.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_deinit
   (
      /* [OUT] the USB_USB_dev_initialize state structure */
      _usb_device_handle  handle
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
   USB_DEV_IF_STRUCT_PTR            usb_c;
   USB_STATUS                       error;
   SERVICE_STRUCT_PTR               service_ptr, prev_service_ptr;
   _mqx_uint                        i;


   if (handle == NULL)
   {
        return USBERR_ERROR;
   }
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   USB_lock();

   error = _usb_device_shutdown(handle);

   /* Free all the Callback function structure memory */
   for (service_ptr = usb_dev_ptr->SERVICE_HEAD_PTR; service_ptr != NULL;) {
      prev_service_ptr = service_ptr;
      service_ptr = service_ptr->NEXT;
      USB_mem_free(prev_service_ptr);
   }

   /* Free all internal transfer descriptors */
   USB_mem_free((pointer)usb_dev_ptr->XD_BASE);

   /* Free all XD scratch memory */
   USB_mem_free((pointer)usb_dev_ptr->XD_SCRATCH_STRUCT_BASE);

   /* Free the temp ep init XD */
   USB_mem_free((pointer)usb_dev_ptr->TEMP_XD_PTR);

   /* Find the initialized device controller in the USB components */
   usb_c = _mqx_get_io_component_handle(IO_USB_COMPONENT);
   /* Check if the interface is registered */
   if (!usb_c) {
      /* No interface was registered yet */
      USB_unlock();
      return USBERR_DEVICE_NOT_FOUND;
   }
   else {
      /* Find out where the interface has been installed */
      for (i = 0; i < USBCFG_MAX_DRIVERS; i++) {
         if (usb_c[i].DEV_HANDLE == handle) {
            /* Found installed device, remove it */
            usb_c[i].DEV_HANDLE = NULL;
            break;
         }
      }
   }

   if (i == USBCFG_MAX_DRIVERS) {
      /* The interface has not been registered, so it cannot be initialized */
      USB_unlock();
      return USBERR_DEVICE_NOT_FOUND;
   }

   /* Free the USB state structure */
   USB_mem_free((pointer)usb_dev_ptr);

   USB_unlock();
   return error;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_init_endpoint
*  Returned Value : USB_OK or error code
*  Comments       :
*     Initializes the endpoint and the data structures associated with the 
*  endpoint
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_init_endpoint
   (
    /* [IN] the USB_USB_dev_initialize state structure */
    _usb_device_handle         handle,

    /* [IN] the endpoint structure, include members such as endpoint number, 
     * endpoint type, endpoint direction and the max packet size 
     */                  
    USB_EP_STRUCT_PTR    ep_ptr, 
    
    /* [IN] After all data is transfered, should we terminate the transfer
     * with a zero length packet if the last packet size == MAX_PACKET_SIZE?
     */
      uint_8                     flag
   )
{ /* Body */
   USB_STATUS                    error = 0;
   USB_DEV_STATE_STRUCT_PTR      usb_dev_ptr;
   
   if (handle == NULL)
   {
        return USBERR_ERROR;
   }

   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

   /* Initialize the transfer descriptor */
   usb_dev_ptr->TEMP_XD_PTR->EP_NUM = ep_ptr->ep_num;
   usb_dev_ptr->TEMP_XD_PTR->BDIRECTION = ep_ptr->direction;
   usb_dev_ptr->TEMP_XD_PTR->WMAXPACKETSIZE = (uint_16)(ep_ptr->size & 0x0000FFFF);
   usb_dev_ptr->TEMP_XD_PTR->EP_TYPE = ep_ptr->type;
   usb_dev_ptr->TEMP_XD_PTR->DONT_ZERO_TERMINATE = flag;

   if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
      usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_INIT_ENDPOINT != NULL) 
   {
        error=((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
          usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_INIT_ENDPOINT(handle, 
          usb_dev_ptr->TEMP_XD_PTR);
   }
   else
   {
        #ifdef _DEV_DEBUG
            printf("_usb_device_init_endpoint: DEV_INIT_ENDPOINT is NULL\n");                     
        #endif  
        return USBERR_ERROR;
   }
   
   return error;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_device_register_service
* Returned Value : USB_OK or error code
* Comments       :
*     Registers a callback routine for a specified event or endpoint.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_device_register_service
   (
      /* [IN] Handle to the USB device */
      _usb_device_handle         handle,
      
      /* [IN] type of event or endpoint number to service */
      uint_8                     type,
      
      /* [IN] Pointer to the service's callback function */
      void(_CODE_PTR_ service)(PTR_USB_EVENT_STRUCT, pointer),
      
      /*[IN] User Argument to be passed to Services when invoked.*/
      pointer arg
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR   usb_dev_ptr;
   SERVICE_STRUCT_PTR         service_ptr;
   SERVICE_STRUCT_PTR _PTR_   search_ptr;

   if (handle == NULL)
   {
        return USBERR_ERROR;
   }
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   /* Needs mutual exclusion */
   USB_lock();
   
   /* Search for an existing entry for type */
   for (search_ptr = &usb_dev_ptr->SERVICE_HEAD_PTR;
      *search_ptr;
      search_ptr = &(*search_ptr)->NEXT) 
   {
      if ((*search_ptr)->TYPE == type) 
      {
         /* Found an existing entry */
         USB_unlock();
         return USBERR_OPEN_SERVICE;
      } /* Endif */
   } /* Endfor */
   
   /* No existing entry found - create a new one */
   service_ptr = (SERVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(SERVICE_STRUCT));

   if (!service_ptr) 
   {
      USB_unlock();
      #ifdef _DEV_DEBUG
        printf("memalloc failed in _usb_device_register_service\n");
      #endif    
      return USBERR_ALLOC;
   } /* Endif */
   
   service_ptr->TYPE = type;
   service_ptr->SERVICE = service;
   service_ptr->arg = arg;
   service_ptr->NEXT = NULL;
   *search_ptr = service_ptr;
   
   USB_unlock();
   return USB_OK;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_device_unregister_service
* Returned Value : USB_OK or error code
* Comments       :
*     Unregisters a callback routine for a specified event or endpoint.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_device_unregister_service
   (
      /* [IN] Handle to the USB device */
      _usb_device_handle         handle,

      /* [IN] type of event or endpoint number to service */
      uint_8                     type
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR   usb_dev_ptr;
   SERVICE_STRUCT_PTR         service_ptr;
   SERVICE_STRUCT_PTR _PTR_   search_ptr;

   if (handle == NULL)
   {
      return USBERR_ERROR;
   }
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   /* Needs mutual exclusion */
   USB_lock();
   
   /* Search for an existing entry for type */
   for (search_ptr = &usb_dev_ptr->SERVICE_HEAD_PTR;
      *search_ptr;
      search_ptr = &(*search_ptr)->NEXT) 
   {
      if ((*search_ptr)->TYPE == type) 
      {
         /* Found an existing entry - delete it */
         break;
      } /* Endif */
   } /* Endfor */
   
   /* No existing entry found */
   if (!*search_ptr) 
   {
      USB_unlock();
      return USBERR_CLOSED_SERVICE;
   } /* Endif */
   
   service_ptr = *search_ptr;
   *search_ptr = service_ptr->NEXT;

   USB_mem_free((pointer)service_ptr);
   
   USB_unlock();
   return USB_OK;

} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_device_call_service
* Returned Value : USB_OK or error code
* Comments       :
*     Calls the appropriate service for the specified type, if one is
*     registered. Used internally only.
* 
*END*--------------------------------------------------------------------*/
USB_STATUS _usb_device_call_service
   (
       /* [IN] Type of service or endpoint */    
      uint_8                  type,
      
      /* [IN] pointer to event structure  */ 
      PTR_USB_EVENT_STRUCT    event            
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR      usb_dev_ptr;
   SERVICE_STRUCT _PTR_          service_ptr;

   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)event->handle;
   /* Needs mutual exclusion */
   USB_lock();
   
   /* Search for an existing entry for type */
   for (service_ptr = usb_dev_ptr->SERVICE_HEAD_PTR;
      service_ptr;
      service_ptr = service_ptr->NEXT) 
   {
      if (service_ptr->TYPE == type) 
      {
         service_ptr->SERVICE(event,service_ptr->arg);
         USB_unlock();
         return USB_OK;
      } /* Endif */
      
   } /* Endfor */

   USB_unlock();

   return USBERR_CLOSED_SERVICE;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_get_transfer_status
*  Returned Value : Status of the transfer
*  Comments       :
*        returns the status of the transaction on the specified endpoint.
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_get_transfer_status
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] direction */
      uint_8                     direction
   )
{ /* Body */
   USB_STATUS                    error;
   USB_DEV_STATE_STRUCT_PTR      usb_dev_ptr;
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   
   USB_lock();

   if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
      usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_GET_TRANSFER_STATUS != NULL) 
   {
       error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
          usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_GET_TRANSFER_STATUS(handle, ep_num,
          direction);
   }
   else
   {
        #ifdef _DEV_DEBUG
            printf("_usb_device_get_transfer_status: DEV_GET_TRANSFER_STATUS is NULL\n");                     
        #endif  
        return USBERR_ERROR;
   }
   
   USB_unlock();
   /* Return the status of the last queued transfer */
   return error;

} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_read_setup_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Reads the setup data from the hardware
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_read_setup_data
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] buffer for receiving Setup packet */
      uint_8_ptr                  buff_ptr
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR      usb_dev_ptr;
   USB_STATUS                    error = USB_OK;
  
   if (handle == NULL)
   {
      return USBERR_ERROR;
   }
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

   if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
      usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_GET_SETUP_DATA != NULL) 
   {
        error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
            usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_GET_SETUP_DATA(handle, 
            ep_num, buff_ptr);
   }
   else
   {
        #ifdef _DEV_DEBUG
            printf("_usb_device_read_setup_data: DEV_GET_SETUP_DATA is NULL\n");                      
        #endif  
        return USBERR_ERROR;
   }
  
   return error;
} /* EndBody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_set_address
*  Returned Value : USB_OK or error code
*  Comments       :
*        Sets the device address as assigned by the host during enumeration
*
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_device_set_address
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
      
      /* [IN] the USB address to be set in the hardware */
      uint_8                     address
   )
{ 
   USB_DEV_STATE_STRUCT_PTR      usb_dev_ptr;
   USB_STATUS                    error;
   
   if (handle == NULL)
   {
      return USBERR_ERROR;
   }
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
      usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SET_ADDRESS != NULL) 
    {
        error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)
            usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SET_ADDRESS(handle, address);
    }
    else
    {
        #ifdef _DEV_DEBUG
            printf("_usb_device_read_setup_data: DEV_GET_SETUP_DATA is NULL\n");                      
        #endif  
        return USBERR_ERROR;
    }

   return error;
} 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/gpio/kgpio/io_gpio_kgpio.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_gpio_kgpio.h$
* $Version : 3.8.3.0$
* $Date    : Sep-22-2011$
*
* Comments:
*
*   The file contains definitions used in user program and/or in other
*   kernel modules to access GPIO pins
*
*END************************************************************************/

#ifndef __io_gpio_cpu_h__
#define __io_gpio_cpu_h__

#ifdef __cplusplus
extern "C" {
#endif


/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/


#define GPIO_PORT_A ((0x0000 << GPIO_PIN_PORT_SHIFT) | GPIO_PIN_VALID)
#define GPIO_PORT_B ((0x0001 << GPIO_PIN_PORT_SHIFT) | GPIO_PIN_VALID)
#define GPIO_PORT_C ((0x0002 << GPIO_PIN_PORT_SHIFT) | GPIO_PIN_VALID)
#define GPIO_PORT_D ((0x0003 << GPIO_PIN_PORT_SHIFT) | GPIO_PIN_VALID)
#define GPIO_PORT_E ((0x0004 << GPIO_PIN_PORT_SHIFT) | GPIO_PIN_VALID)
#ifdef PORTF_BASE_PTR 
	#define GPIO_PORT_F	((0x0005 << GPIO_PIN_PORT_SHIFT) | GPIO_PIN_VALID)
#endif
/*----------------------------------------------------------------------*/
/*
**                          TYPE DEFINITIONS
*/


typedef struct irq_map_struct {
   uint_8  portnq;
} GPIO_IRQ_MAP, _PTR_ GPIO_IRQ_MAP_PTR;



#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/lwadc/lwadc_vadc.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2011 Embedded Access Inc
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: lwadc_vadc.h$
* $Version : 3.8.1.0$
* $Date    : Oct-3-2012$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END************************************************************************/

#ifndef __lwadc_vadc_h__
#define __lwadc_vadc_h__

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

#define ADC_HW_CHANNELS           16
#define ADC_NUM_DEVICES           2
#define LWADC_RESOLUTION_12BIT    0x1000
#define LWADC_RESOLUTION_10BIT    0x400
#define LWADC_RESOLUTION_8BIT     0x100
#define LWADC_RESOLUTION_DEFAULT  (LWADC_RESOLUTION_12BIT)
#define ADC_CDR_CDATA_MASK      0x00000FFF
#define ADC_DEV_SHIFT           (8)
#define ADC_DEV_MASK            (0xf00)
#define ADC_CHANNEL_MASK        (0xff)
    
#define ADC_INPUT(dev,channel)  (dev<<ADC_DEV_SHIFT | channel)
#define ADC_DEVICE(input)       (input>>ADC_DEV_SHIFT)
#define ADC_CHANNEL(input)      (input&ADC_CHANNEL_MASK)

#define LWADC0_AN0 (8)
#define LWADC0_AN1 (9)
#define LWADC0_AN2 (22)
#define LWADC0_AN3 (23)
#define LWADC0_AN4 (26)
#define LWADC0_AN5 (103)
#define LWADC0_AN6 (59)
#define LWADC0_AN7 (60)

#define LWADC1_AN0 (6)
#define LWADC1_AN1 (7)
#define LWADC1_AN2 (24)
#define LWADC1_AN3 (25)
#define LWADC1_AN4 (27)
#define LWADC1_AN5 (104)
#define LWADC1_AN6 (61)
#define LWADC1_AN7 (62)
#define LWADC_SIG_NC (0)

#define ADC_INPUT_ADC0_AN0          ADC_INPUT(0,0)
#define ADC_INPUT_ADC0_AN1          ADC_INPUT(0,1)
#define ADC_INPUT_ADC0_AN2          ADC_INPUT(0,2)
#define ADC_INPUT_ADC0_AN3          ADC_INPUT(0,3)
#define ADC_INPUT_ADC0_AN4          ADC_INPUT(0,4)
#define ADC_INPUT_ADC0_AN5          ADC_INPUT(0,5)
#define ADC_INPUT_ADC0_AN6          ADC_INPUT(0,6)
#define ADC_INPUT_ADC0_AN7          ADC_INPUT(0,7)
#define ADC_INPUT_ADC0_AN8          ADC_INPUT(0,8)
#define ADC_INPUT_ADC0_AN9          ADC_INPUT(0,9)
#define ADC_INPUT_ADC0_AN10         ADC_INPUT(0,10)
#define ADC_INPUT_ADC0_AN11         ADC_INPUT(0,11)
#define ADC_INPUT_ADC0_AN12         ADC_INPUT(0,12)
#define ADC_INPUT_ADC0_AN13         ADC_INPUT(0,13)
#define ADC_INPUT_ADC0_AN14         ADC_INPUT(0,14)
#define ADC_INPUT_ADC0_AN15         ADC_INPUT(0,15)
#define ADC_INPUT_ADC0_VREG_1V2     ADC_INPUT_ADC0_AN10
#define ADC_INPUT_ADC0_TSENS        ADC_INPUT_ADC0_AN15

#define ADC_INPUT_ADC1_AN0          ADC_INPUT(1,0)
#define ADC_INPUT_ADC1_AN1          ADC_INPUT(1,1)
#define ADC_INPUT_ADC1_AN2          ADC_INPUT(1,2)
#define ADC_INPUT_ADC1_AN3          ADC_INPUT(1,3)
#define ADC_INPUT_ADC1_AN4          ADC_INPUT(1,4)
#define ADC_INPUT_ADC1_AN5          ADC_INPUT(1,5)
#define ADC_INPUT_ADC1_AN6          ADC_INPUT(1,6)
#define ADC_INPUT_ADC1_AN7          ADC_INPUT(1,7)
#define ADC_INPUT_ADC1_AN8          ADC_INPUT(1,8)
#define ADC_INPUT_ADC1_AN9          ADC_INPUT(1,9)
#define ADC_INPUT_ADC1_AN10         ADC_INPUT(1,10)
#define ADC_INPUT_ADC1_AN11         ADC_INPUT(1,11)
#define ADC_INPUT_ADC1_AN12         ADC_INPUT(1,12)
#define ADC_INPUT_ADC1_AN13         ADC_INPUT(1,13)
#define ADC_INPUT_ADC1_AN14         ADC_INPUT(1,14)
#define ADC_INPUT_ADC1_AN15         ADC_INPUT(1,15)
#define ADC_INPUT_ADC1_VREG_1V2     ADC_INPUT_ADC1_AN10
#define ADC_INPUT_ADC1_TSENS        ADC_INPUT_ADC1_AN15

typedef enum {
    LWADC_CLK_BUSCLK,     /* selects BUSCLK */
    LWADC_CLK_BUSCLK2,    /* selects BUSCLK/2 */
    LWADC_CLK_BUSCLK_ANY, /* selects BUSCLK or BUSCLK/2 */
    LWADC_CLK_ALTERNATE,
    LWADC_CLK_ASYNC
} LWADC_CLOCK_SOURCE;

typedef enum {
    LWADC_DIV_1 = 0,
    LWADC_DIV_2 = 1,
    LWADC_DIV_4 = 2,
    LWADC_DIV_8 = 3,
    LWADC_DIV_ANY = -1 /* selects automatically the fastest one */
} LWADC_CLOCK_DIV;

typedef enum {
    LWADC_LPC_LOW =    ADC_CFG_ADLPC_MASK, /* use low power of ADC (reduces max. ADCCLK frequency) */
    LWADC_LPC_NORMAL = 0                    /* use normal power of ADC */
} LWADC_LPC;

typedef enum {
    LWADC_HSC_NORMAL = ADC_CFG_ADHSC_MASK, /* use normal speed */
    LWADC_HSC_HIGH = 0                      /* use high speed */
} LWADC_HSC;

typedef enum {
    LWADC_PDB_COMP1OUT = 0,   /* Comparator 1 output trigger */
    LWADC_PDB_COMP2OUT = 4,   /* Comparator 2 output trigger */
    LWADC_PDB_EXTRIG   = 16,  /* External event trigger */
    LWADC_PDB_SWTRIG   = 28   /* Software trigger */
} LWADC_PDB_TRIGSEL;


typedef struct lwadc_init_struct {
    /* The number of ADC peripheral, use adc_t enum from PSP */
    uint_8 ADC_NUMBER;

    /* The clock source */
    LWADC_CLOCK_SOURCE CLOCK_SOURCE;

    /* The clock divisor for ADC */
    LWADC_CLOCK_DIV CLOCK_DIV;

    /* ADC high speed control, see ADC_HSC enum */
    LWADC_HSC SPEED;

    /* ADC low power control, see ADC_LPC enum */
    LWADC_LPC POWER;

    /* The calibration data pointer */
    uint_8_ptr CALIBRATION_DATA_PTR;

    /* ADC interrupt vector */
    uint_32 ADC_VECTOR;

    /* ADC interrupt vector */
    uint_32 ADC_PRIORITY;
    
    uint_32 reference;
}LWADC_INIT_STRUCT, * LWADC_INIT_STRUCT_PTR;


typedef struct adc_context {
    const LWADC_INIT_STRUCT *   init_ptr;
    uint_32                     mcr;
    uint_32                     channels;
    uint_32                     default_numerator;
    uint_32                     default_denominator;
}ADC_CONTEXT, * ADC_CONTEXT_PTR;

typedef struct lwadc_struct {
    ADC_CONTEXT_PTR             context_ptr;
    uint_32                     input;
    uint_32                     mask;
    uint_32                     numerator;
    uint_32                     denominator;
}LWADC_STRUCT, * LWADC_STRUCT_PTR;
typedef enum {
    LWADC_RESOLUTION=1,
    LWADC_REFERENCE,
    LWADC_FREQUENCY,
    LWADC_DIVIDER,
    LWADC_DIFFERENTIAL,
    LWADC_POWER_DOWN,
    LWADC_NUMERATOR ,
    LWADC_DENOMINATOR,
    LWADC_DEFAULT_NUMERATOR ,
    LWADC_DEFAULT_DENOMINATOR,
    LWADC_FORMAT,
    LWADC_INPUT_CONVERSION_ENABLE
} LWADC_ATTRIBUTE;

#define LWADC_FORMAT_LEFT_JUSTIFIED     1
#define LWADC_FORMAT_RIGHT_JUSTIFIED    2


typedef uint_32 LWADC_VALUE, * LWADC_VALUE_PTR;

extern uint_32 _lwadc_init( const LWADC_INIT_STRUCT * init_ptr);
extern boolean _lwadc_init_input( LWADC_STRUCT_PTR lwadc_ptr, uint_32 input);
extern boolean _lwadc_read_raw( LWADC_STRUCT_PTR lwadc_ptr,  LWADC_VALUE_PTR outSample);
extern boolean _lwadc_read( LWADC_STRUCT_PTR lwadc_ptr, LWADC_VALUE_PTR outSample);
extern boolean _lwadc_wait_next( LWADC_STRUCT_PTR lwadc_ptr);
extern boolean _lwadc_read_average( LWADC_STRUCT_PTR lwadc_ptr, uint_32 num_samples, LWADC_VALUE_PTR outSample);
extern boolean _lwadc_set_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute, uint_32 value);
extern boolean _lwadc_get_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute, uint_32_ptr value_ptr);


#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/int/i2c_int_prv.h<|end_filename|>
#ifndef _i2c_int_prv_h_
#define _i2c_int_prv_h_ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_int_prv.h$
* $Version : 3.0.1.0$
* $Date    : Jun-4-2009$
*
* Comments:
*
*   This file includes the private definitions for the interrupt I2C
*   serial I/O drivers.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/


/*---------------------------------------------------------------------
**
** IO I2C INT DEVICE STRUCT
**
** This structure used to store information about an I2C interrupt io device
** for the IO device table
*/
typedef struct io_i2c_int_device_struct
{

   /* The I/O init function */
   _mqx_uint (_CODE_PTR_ DEV_INIT)(pointer, char_ptr);

   /* The I/O deinit function */
   _mqx_uint (_CODE_PTR_ DEV_DEINIT)(pointer, pointer);
   
   /* [IN] The READ function */
   _mqx_int  (_CODE_PTR_ DEV_READ)(pointer, char_ptr, _mqx_int);
      
   /* [IN] The WRITE function */
   _mqx_int  (_CODE_PTR_ DEV_WRITE)(pointer, char_ptr, _mqx_int);
   
   /* The ioctl function, (change bauds etc) */
   _mqx_int  (_CODE_PTR_ DEV_IOCTL)(pointer, _mqx_uint, _mqx_uint_ptr);

   /* The I/O channel initialization data */
   pointer               DEV_INIT_DATA_PTR;
   
   /* Device specific information */
   pointer               DEV_INFO_PTR;

   /* Open count for number of accessing file descriptors */
   _mqx_uint             COUNT;

   /* Open flags for this channel */
   _mqx_uint             FLAGS;

} IO_I2C_INT_DEVICE_STRUCT, _PTR_ IO_I2C_INT_DEVICE_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

/* I/O prototypes */
extern _mqx_int _io_i2c_int_open(FILE_DEVICE_STRUCT_PTR, char_ptr, char_ptr);
extern _mqx_int _io_i2c_int_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int _io_i2c_int_read(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_i2c_int_write(FILE_DEVICE_STRUCT_PTR, char_ptr, _mqx_int);
extern _mqx_int _io_i2c_int_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, pointer);
extern _mqx_int _io_i2c_int_uninstall(IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/mfs/sh_compare.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_compare.c$
* $Version : 3.8.12.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   This file contains the source for an MFS shell function.
*
*END************************************************************************/

#include <string.h>
#include <mqx.h>
#include <fio.h>
#include <mfs.h>
#include <shell.h>
#include <sh_prv.h>

#if SHELLCFG_USES_MFS
#define COMPARE_BLOCK_SIZE 512

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  Shell_compare
* Returned Value   :  uint_32 error code
* Comments  :  Renames or moves a file.
*
*END*---------------------------------------------------------------------*/

int_32  Shell_compare(int_32 argc, char_ptr argv[] )
{ /* Body */
   boolean     print_usage, shorthelp = FALSE;
   int_32      size1, size2, return_code = SHELL_EXIT_SUCCESS;
   MQX_FILE_PTR in_fd_1=NULL, in_fd_2=NULL;
   char_ptr    file1=NULL,file2=NULL;
   SHELL_CONTEXT_PTR    shell_ptr = Shell_get_context( argv );
   int_32               error = 0;      

   print_usage = Shell_check_help_request(argc, argv, &shorthelp );

   if (!print_usage)  {
      if (argc != 3)  {
         printf("Error, invalid number of parameters\n");
         return_code = SHELL_EXIT_ERROR;
         print_usage=TRUE;
      } 
      /* check if filesystem is mounted */ 
      else if (NULL == Shell_get_current_filesystem(argv))  
      {
         printf("Error, file system not mounted\n");
         return_code = SHELL_EXIT_ERROR;
      }
      else if (MFS_alloc_path(&file1) != MFS_NO_ERROR) {
         printf("Error, unable to allocate memory for paths\n" );
         return_code = SHELL_EXIT_ERROR;
      } else {
         error = _io_rel2abs(file1,shell_ptr->CURRENT_DIR,(char *) argv[1],PATHNAME_SIZE,shell_ptr->CURRENT_DEVICE_NAME);
         if(!error)
         {
            in_fd_1 = fopen(file1, "r");
         }      

         error = _io_rel2abs(file1,shell_ptr->CURRENT_DIR,(char *) argv[2],PATHNAME_SIZE,shell_ptr->CURRENT_DEVICE_NAME);
         if(!error)
         {
            in_fd_2 = fopen(file1, "r");
         }  

         MFS_free_path(file1);         

         if (in_fd_1 == NULL)  {
             printf("Error, unable to open file %s\n", argv[1] );
             return_code = SHELL_EXIT_ERROR;
         } else  if (in_fd_2 == NULL)  {
             printf("Error, unable to open file %s\n", argv[2] );
             return_code = SHELL_EXIT_ERROR;
         } else {
            file1 = _mem_alloc(COMPARE_BLOCK_SIZE);
            file2 = _mem_alloc(COMPARE_BLOCK_SIZE);
            if ((file1==NULL) || (file2==NULL)) {
               printf("Error, unable to allocate buffer space" );
               return_code = SHELL_EXIT_ERROR;
            } else {
               do {
                  size1 = read(in_fd_1, file1, COMPARE_BLOCK_SIZE);
                  size2 = read(in_fd_2, file2, COMPARE_BLOCK_SIZE);
                  if (size1!=size2) {
                     printf("Compare failed, files have different sizes\n" );
                     return_code = SHELL_EXIT_ERROR;
                  } else if (size1 > 0) {
                     if (memcmp(file1,file2,COMPARE_BLOCK_SIZE)!=0) {
                        printf("Compare failed, files are different\n" );
                        return_code = SHELL_EXIT_ERROR;
                     }                     
                  }
               } while ((size1>0) && (return_code == SHELL_EXIT_SUCCESS));
               if (return_code == SHELL_EXIT_SUCCESS) {
                  printf("The files are identical\n" );
               }
            }
            if (file1) _mem_free(file1);
            if (file2) _mem_free(file2);
         }
         if (in_fd_1) fclose(in_fd_1); 
         if (in_fd_2) fclose(in_fd_2); 
      }
   }
      
      
   if (print_usage)  {
      if (shorthelp)  {
         printf("%s <file1> <file2> \n", argv[0]);
      } else  {
         printf("Usage: %s <file1> <file2>\n", argv[0]);
         printf("   <file1> = first file to compare\n");
         printf("   <file2> = second file to compare\n");
      }
   }
   return return_code;
} /* Endbody */

#endif //SHELLCFG_USES_MFS
/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/arp_prv.h<|end_filename|>
#ifndef __arp_prv_h__
#define __arp_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: arp_prv.h$
* $Version : 3.5.7.0$
* $Date    : Dec-4-2009$
*
* Comments:
*
*   Address Resolution Protocol definitions.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

/*
** ARP operation codes
*/
#define ARPOP_REQUEST   1
#define ARPOP_REPLY     2

/*
** ARP protocol types
*/
#define ARPPROT_IP      0x800


/*
** Warning: ARPCACHE_HASH() should really be ((a) % ARPCACHE_SIZE),
** but this is faster when ARPCACHE_SIZE is a power of two.
** Note however, that if ARPCACHE_SIZE must be increased, a power
** of two is NOT a good choice -- an odd number (i.e. anything
** coprime to the size of the subnet) would be better.
*/
#define ARPCACHE_HASH(a)   ((a) & (ARPCACHE_SIZE - 1))

#if (ARP_ENTRY_MAX_QUEUED_PCBS>1)
#define ARP_ENTRY_QUEUE_SIZE(e)    (e->QUEUED_PCBS)
#define ARP_ENTRY_DEQUEUE_PCB(e)    _arp_entry_dequeue_pcb(e)
#define ARP_ENTRY_ENQUEUE_PCB(e,p)  _arp_entry_enqueue_pcb(e,p)
#define ARP_ENTRY_QUEUE_PEEK(e)     _arp_entry_queue_peek(e)
#define ARP_ENTRY_QUEUE_INIT(e)     _arp_entry_queue_init(e)
#define ARP_ENTRY_QUEUE_FULL(e)     (e->QUEUED_PCBS == ARP_ENTRY_MAX_QUEUED_PCBS)
#else
#define ARP_ENTRY_QUEUE_SIZE(e)  ((e->WAITING != NULL)?1:0)
#define ARP_ENTRY_ENQUEUE_PCB(e,p)     (e->WAITING=p)
#define ARP_ENTRY_DEQUEUE_PCB(e)    e->WAITING; e->WAITING=NULL
#define ARP_ENTRY_QUEUE_PEEK(e)       (e->WAITING)
#define ARP_ENTRY_QUEUE_FULL(e)     (e->WAITING != NULL)
#define ARP_ENTRY_QUEUE_INIT(e)     (e->WAITING = NULL)

#endif
// END CR 2233


#if RTCSCFG_ENABLE_ARP_STATS
#define IF_ARP_STATS_ENABLED(x) x
#else
#define IF_ARP_STATS_ENABLED(x)
#endif

/***************************************
**
** Type definitions
**
*/

/*
** Contents of an ARP packet
*/
typedef struct arp_packet
{
   uchar    LINKTYPE[2];
   uchar    PROTTYPE[2];
   uchar    LINKLEN[1];
   uchar    PROTLEN[1];
   uchar    OPCODE[2];
   uchar    LINKSRC[6];
   uchar    PROTSRC[4];
   uchar    LINKDEST[6];
   uchar    PROTDEST[4];
} ARP_PACKET, _PTR_ ARP_PACKET_PTR;


typedef struct arp_entry {

   _ip_address             PADDR;
   uchar                   LADDR[6];   /* ignored when COMPLETE == FALSE */
   uchar                   RESERVED[2];

   IP_IF_PTR               HEAD;
   struct arp_entry _PTR_  PREV;
   struct arp_entry _PTR_  NEXT;

   boolean                 COMPLETE;
   boolean                 AGED;       /* ignored when COMPLETE == FALSE */
   boolean                 HIT;        /* ignored when COMPLETE == FALSE */

// START CR 2233
#if (ARP_ENTRY_MAX_QUEUED_PCBS==1)
   /* There is at most one queued PCB on any incomplete entry */
   RTCSPCB_PTR             WAITING;

#else
   /* There may be multiple queued PCB on any incomplete entry */
   RTCSPCB_PTR             WAITING[ARP_ENTRY_MAX_QUEUED_PCBS];
   uint_32                 QUEUED_PCBS;
#endif
// END CR 2233

   _ip_address             WAITADDR;   /* ignored when RESEND_TIMER inactive */
   RTCS_LINKOPT_STRUCT     WAITOPT;    /* ignored when RESEND_TIMER inactive */

   uint_32                 RESEND_INTERVAL;
   TCPIP_EVENT             RESEND_TIMER;
   TCPIP_EVENT             AGE_TIMER;
   TCPIP_EVENT             EXPIRE_TIMER;

} ARP_ENTRY, _PTR_ ARP_ENTRY_PTR;


/*
** ARP Configuration
**    This information is persistent for the ARP layer.
*/
typedef struct arp_cfg {

#if RTCSCFG_ENABLE_ARP_STATS
   ARP_STATS      STATS;
#endif

   ARP_ENTRY_PTR  CACHE[ARPCACHE_SIZE];

   uchar          LADDR[6];
   uchar          RESERVED[2];

   ARP_PACKET     ARP_REQUEST;

} ARP_CFG, _PTR_ ARP_CFG_PTR;


/***************************************
**
** Global variables
**
*/
extern pointer ARP_freelist;

// START CR 2233
#if (ARP_ENTRY_MAX_QUEUED_PCBS!=1)
extern RTCSPCB_PTR   _arp_entry_dequeue_pcb(ARP_ENTRY_PTR e);
extern boolean       _arp_entry_enqueue_pcb(ARP_ENTRY_PTR e,RTCSPCB_PTR p);
extern RTCSPCB_PTR   _arp_entry_queue_peek(ARP_ENTRY_PTR e);
extern boolean       _arp_entry_queue_init(ARP_ENTRY_PTR e);
#endif
// END CR 2233

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_enet.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_enet.c$
* $Version : 3.8.6.0$
* $Date    : Sep-19-2011$
*
* Comments:
*
*   Example using RTCS Library.
*
*END************************************************************************/

#include <ctype.h>
#include <string.h>
#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <rtcs.h>
#include <enet.h>
#include "sh_rtcs.h" 
#include "sh_enet.h" 

 

boolean Shell_parse_enet_address( char_ptr arg, _enet_address enet_address)
{
   int i,j=0;
   
   if (strlen(arg) != 17)  {
      return FALSE;
   }
   
   for (i=0;i<16;i+=3)  {
      if ( isxdigit(arg[i]) && isxdigit(arg[i+1]) && ((arg[i+2]==':') || (arg[i+2]=='\0')) )  {
         enet_address[j++] = hexnum(arg[i]) * 16 + hexnum(arg[i+1]);
      } else  {
         return FALSE;
      }
   } 
   return TRUE;   
}

#endif /* SHELLCFG_USES_RTCS */
/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/SWLIBS_Defines.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     SWLIBS_Defines.h
*
* @author   r63172
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Defines and common Macros definition file.
*
*******************************************************************************
*
******************************************************************************/
#ifndef _SWLIBS_DEFINES_H
#define _SWLIBS_DEFINES_H

#include "SWLIBS_Typedefs.h"

/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*! If USE_ASM macro is enabled then, if existing, an assembly version of
* the functions are used */
//#define USE_ASM

/*! If USE_FRAC32_ARITHMETIC macro is enabled then, 32bit arithmetic is used
* for intermediate calculations, achieving best possible calculation accuracy.*/
#define USE_FRAC32_ARITHMETIC

/*! Constant representing the maximal negative value of a signed fixed point 16-bit fractional
 * number eq -1.0 */
#define SFRACT_MIN          (-1.0)

/*! Constant representing the maximal positive value of a signed fixed point 16-bit fractional
 * number eq 0.999969482421875 */
#define SFRACT_MAX          (0.999969482421875)

/*! Constant representing the maximal negative value of a signed fixed point 32-bit fractional
 * number eq -1.0 */
#define FRACT_MIN           (-1.0)

/*! Constant representing the maximal positive value of a signed fixed point 32-bit fractional
 * number eq 0.9999999995343387126922607421875 */
#define FRACT_MAX           (0.9999999995343387126922607421875)

/*! Constant representing the maximal positive value of a signed fixed point 16-bit integer
 * number eq \f$ 2^{16-1}-1 = \f$ 0x7fff. */
#ifndef INT16_MAX
#define INT16_MAX           ((Word16) 0x7fff)
#endif

/*! Constant representing the maximal negative value of a signed fixed point 16-bit integer
 * number eq \f$ -2^{16-1} = \f$ 0x8000. */
#ifndef INT16_MIN
#define INT16_MIN           ((Word16) 0x8000)
#endif

/*! Constant representing the maximal positive value of a signed fixed point 32-bit integer
 * number eq \f$ 2^{32-1}-1 = \f$ 0x7fff ffff. */
#ifndef INT32_MAX
#define INT32_MAX           ((Word32) 0x7fffffff)
#endif

/*! Constant representing the maximal negative value of a signed fixed point 32-bit integer
 * number eq \f$ -2^{32-1} = \f$ 0x8000 0000. */
#ifndef INT32_MIN
#define INT32_MIN           ((Word32) 0x80000000)
#endif

/*! Macro converting a signed fractional [-1,1) number into a fixed point 16-bit
 * number in the format Q1.15. */
#define FRAC16(x)           ((Frac16) ((x) < (SFRACT_MAX) ? ((x) >= SFRACT_MIN ? (x)*0x8000 : 0x8000) : 0x7fff))

/*! Macro converting a signed fractional [-1,1) number into a fixed point 32-bit
 * number in the format Q1.31. */
#define FRAC32(x)           ((Frac32) ((x) < (FRACT_MAX) ? ((x) >= FRACT_MIN ? (x)*0x80000000 : 0x80000000) : 0x7fffffff))

/*! Type casting - a signed 16-bit fractional value cast as a signed 16-bit integer */
#define F16TOINT16(x)       ((Word16) (x))

/*! Type casting - the lower 16 bits of a signed fractional 32-bit fractional value cast
 * as a signed integer 16-bit integer */
#define F32TOINT16(x)       ((Word16) (x))

/*! Type casting - the lower 16 bits of a signed fractional 64-bit fractional value cast
 * as a signed integer 16-bit integer */
#define F64TOINT16(x)       ((Word16) (x))

/*! Type casting - a signed 16-bit fractional value cast as a signed 32-bit 
 * integer, the value placed at the lower 16 bits of the 32-bit result */
#define F16TOINT32(x)       ((Word32) (x))

/*! Type casting - a signed 32-bit fractional value cast as a signed
 * 32-bit integer */
#define F32TOINT32(x)       ((Word32) (x))

/*! Type casting - lower 32 bits of a signed 64-bit fractional value cast as a
 * signed 32-bit integer */
#define F64TOINT32(x)       ((Word32) (x))

/*! Type casting - a signed 16-bit fractional value cast as a signed 64-bit
 * integer, the value placed at the lower 16 bits of the 64-bit result */
#define F16TOINT64(x)       ((Word64) (x))

/*! Type casting - a signed 32-bit fractional value cast as a signed 64-bit integer,
 *  the value placed at the lower 32 bits of the 64-bit result */
#define F32TOINT64(x)       ((Word64) (x))

/*! Type casting - a signed 64-bit fractional value cast as a signed
 * 64-bit integer */
#define F64TOINT64(x)       ((Word64) (x))

/*! Type casting - a signed 16-bit integer value cast as a signed
 * 16-bit fractional */
#define INT16TOF16(x)       ((Frac16) (x))

/*! Type casting - a signed 16-bit integer value cast as a signed 32-bit 
 * fractional, the value placed at the lower 16 bits of the 32-bit result */
#define INT16TOF32(x)       ((Frac32) (x))

/*! Type casting - the lower 16 bits of a signed 32-bit integer value cast as a
 * signed 16-bit fractional */
#define INT32TOF16(x)       ((Frac16) (x))

/*! Type casting - a signed 32-bit integer value cast as a signed fractional
 * 32-bit fractional */
#define INT32TOF32(x)       ((Frac32) (x))

/*! Type casting - the lower 16 bits of a signed 64-bit integer value cast as a
 * signed 16-bit fractional */
#define INT64TOF16(x)       ((Frac16) (x))

/*! Type casting - the lower 32 bits of a signed 64-bit integer value cast as a
 * signed 32-bit fractional */
#define INT64TOF32(x)       ((Frac32) (x))

/*! One over sqrt(3) with a 16-bit result, the result rounded for a better
 * precision, i.e. \f$ round(1/sqrt(3)*2^{15}) \f$ */
#define F16_1_DIVBY_SQRT3   ((Frac16) 0x49E7)

/*! One over sqrt(3) with a 32-bit result, the result rounded for a better
 *  precision, i.e. \f$ round(1/sqrt(3)*2^{31}) \f$ */
#define F32_1_DIVBY_SQRT3   ((Frac32) 0x49E69D16)

/*! Sqrt(3) divided by two with a 16-bit result, the result rounded for a better
 * precision, i.e. \f$ round(sqrt(3)/2*2^{15}) \f$ */
#define F16_SQRT3_DIVBY_2   ((Frac16) 0x6EDA)

/*! Sqrt(3) divided by two with a 32-bit result, the result rounded for a better
 * precision, i.e. \f$ round(sqrt(3)/2*2^{31}) \f$ */
#define F32_SQRT3_DIVBY_2   ((Frac32) 0x6ED9EBA1)

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/

/******************************************************************************
* Exported variables
******************************************************************************/

/******************************************************************************
* Exported function prototypes
******************************************************************************/

/******************************************************************************
* Inline functions
******************************************************************************/

#endif /* _SWLIBS_DEFINES_H */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/watchdog_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: watchdog_prv.h$
* $Version : 3.8.4.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   watchdog component.
*
*END************************************************************************/
#ifndef __watchdog_prv_h__
#define __watchdog_prv_h__ 1

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* The number of tasks in the alarm table */
#define WATCHDOG_TABLE_SIZE   (16)

/* The watchdog validation number */
#define WATCHDOG_VALID        (_mqx_uint)(0x77646f67)     /* "wdog" */

/*--------------------------------------------------------------------------*/
/*                       DATATYPE DEFINITIONS                               */


/*  WATCHDOG ALARM TABLE STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief Watchdog alarm table structure. 
 */
typedef struct watchdog_alarm_table_struct
{
   /*! \brief The next table if required. */
   struct watchdog_alarm_table_struct _PTR_ NEXT_TABLE_PTR;

   /*! \brief The tasks being monitored. */
   TD_STRUCT_PTR                            TD_PTRS[WATCHDOG_TABLE_SIZE];

} WATCHDOG_ALARM_TABLE_STRUCT, _PTR_ WATCHDOG_ALARM_TABLE_STRUCT_PTR;
/*! \endcond */


/* WATCHDOG COMPONENT STRUCTURE */
/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief Watchdog component structure. 
 */
typedef struct watchdog_component_struct
{
   /*! \brief The table of alarms. */
   WATCHDOG_ALARM_TABLE_STRUCT ALARM_ENTRIES;

   /*! \brief Watchdog validation stamp. */
   _mqx_uint                    VALID;
   
   /*! \brief The function to call when the watchdog expires. */
   WATCHDOG_ERROR_FPTR          ERROR_FUNCTION;
   
   /*! \brief The old timer interrupt handler. */
   INT_ISR_FPTR                 TIMER_INTERRUPT_HANDLER;

   /*! \brief The interrupt vector. */
   _mqx_uint                    INTERRUPT_VECTOR;

} WATCHDOG_COMPONENT_STRUCT, _PTR_ WATCHDOG_COMPONENT_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/*                       PROTOTYPE DEFINITIONS                              */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern void     _watchdog_cleanup(TD_STRUCT_PTR);
extern void     _watchdog_isr(pointer);
extern boolean  _watchdog_start_internal(MQX_TICK_STRUCT_PTR);
#endif

#ifdef __cplusplus
}
#endif

#endif /* __watchdog_prv_h__ */
/* EOF */



<|start_filename|>Firmware/Inverter_bootloader/APP/app_cfg.h<|end_filename|>
#ifndef __APP_CFG_H
#define __APP_CFG_H

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <MK60F15.h>
#include "intrinsics.h"
#include "app_types.h"
#include "md5.h"
#include "aes.h"
#include "app_IDs.h"
#include "CAN_control.h"
#include "CAN_task.h"
#include "Y_Loader.h"
#include "flash_FTFL.h"
         
#include "USB_timer.h" 
#include "Diagnostic_print.h"
#include "LCD_control.h"


#define BOOTLODER_WAIT_TIME    60000  // Время пребывания в состоянии загрузчика при отсутствии команд по CAN  

#define SYSTEM_CLOCK           (120000000ul)
#define PERIPH_CLOCK           (60000000ul)
#define BASEPRI                (0x0F)


#define MIN_RAM1_ADDRESS        0x1FFF0000
#define MAX_RAM1_ADDRESS        0x20010000
#define MIN_FLASH1_ADDRESS      0x00008000
#define MAX_FLASH1_ADDRESS      0x00018000
#define IMAGE_START_ADDR        ((INT32U_ptr)0x00008000)
#define ERASE_SECTOR_SIZE       0x1000  /* 4K bytes*/
#define FIRMWARE_SIZE           (MAX_FLASH1_ADDRESS - MIN_FLASH1_ADDRESS +1)

#define DFU_RECV_BUFFER_LENGTH  (DFU_MAX_BLOCK_SIZE*40) 

#define BOOTL_IMG_SIZE          0x00008000  
#define FLASH_AREA_ADDR         0x00000000
#define FLASH_AREA_SIZE         0x00100000
#define PROGRAMM_AREA_BEG_ADDR  0x00008000
#define MAX_SECTOR_NUM     ((FLASH_AREA_SIZE - BOOTL_IMG_SIZE)/ERASE_SECTOR_SIZE)


#define MAGIC_TAG      0xAA553311
#define COMPESSION_TAG 0x778811EE

#define HEADER_BLOCK_SZ    512



#define  HIGH_SPEED_DEVICE            (1)

/* Below two MACROS are required for Keyboard Application to execute */
#define LONG_SEND_TRANSACTION       /* support to send large data pkts */
#define LONG_RECIEVE_TRANSACTION    /* support to receive large data pkts */

/* User Defined MACRO to set number of Timer Objects */
#define MAX_TIMER_OBJECTS           2

/* When Enabled Timer Callback is invoked with an argument */
#define TIMER_CALLBACK_ARG
#undef TIMER_CALLBACK_ARG


/* Use double buffered endpoints 5 & 6. To be only used with S08 cores */
#define DOUBLE_BUFFERING_USED


typedef struct 
{
  const char  *img_filename;
  const char  *used_filename;
  unsigned int target_rx_can_id; // CAN идентификатор для приема, если 0 то файл предназначен для данного контроллера 
  unsigned int target_tx_can_id; // CAN идентификатор для передачи, если 0 то файл предназначен для данного контроллера 

} T_img_file_cbl;

typedef struct
{
  unsigned char  md5_hash[16];
  unsigned int   orig_img_size;
  unsigned int   date;
  unsigned int   time;
  unsigned int   image_offset;
  unsigned int   compr_algor_type;
  unsigned int   compress_flag;
  unsigned int   image_size_val;
  unsigned int   magic_val;
    
} T_Boot_record;


void Watchdog_refresh(void);
void LCD_show_programming_progress(INT32U addr, INT32U sz);
void LCD_show_programming_end(int state);
void Check_and_Jump_to_App(void);
#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hmi/hmi_client.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: hmi_client.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the implementation of HMI clients
*
*END************************************************************************/
#include "hmi_client.h"

#define HMI_START_PROVIDER_COUNT       2
#define HMI_GROW_UP_PROVIDER_COUNT     2

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_client_init
* Returned Value   : allocated HMI_CLIENT_STRUCT_PTR
* Comments         :
*   This function adds provider.
*
*END*--------------------------------------------------------------------*/
HMI_CLIENT_STRUCT_PTR hmi_client_init(void)
{
    HMI_CLIENT_STRUCT_PTR       btnled_struct;
    HMI_PROVIDER_STRUCT_PTR     provider_table;

    btnled_struct = _mem_alloc_system_zero(sizeof(HMI_CLIENT_STRUCT));
    if(btnled_struct == NULL)
    {
        return NULL;
    }
    /* allocate provider tablet */
    provider_table = _mem_alloc_system_zero(HMI_START_PROVIDER_COUNT * sizeof(HMI_PROVIDER_STRUCT_PTR));
    if(provider_table == NULL)
    {
        _mem_free(btnled_struct);
        return NULL;
    }
    btnled_struct->PROVIDER_TABLE = (pointer)provider_table;
    btnled_struct->MAX_PROVIDER_COUNT = HMI_START_PROVIDER_COUNT;

    return btnled_struct;
}
/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_add_provider
* Returned Value   : TRUE if adding success, else FALSE
* Comments         :
*   This function adds provider
*
*END*--------------------------------------------------------------------*/
boolean hmi_add_provider(HMI_CLIENT_STRUCT_PTR client_handle, HMI_PROVIDER_STRUCT_PTR provider_handle)
{
    boolean result = FALSE;
    uint_32 i;

    if((provider_handle == NULL) || (client_handle==NULL))
    {
        return result;
    }
    /* add provider into the table*/
    for(i=0; i<client_handle->MAX_PROVIDER_COUNT; i++)
    {
        if(client_handle->PROVIDER_TABLE[i] == NULL)
        {
            result = TRUE;
            client_handle->PROVIDER_TABLE[i] = provider_handle;
            client_handle->PROVIDER_TABLE[i]->ATTACH_CLIENT(provider_handle, client_handle);
            if (client_handle->PROVIDER_TABLE[i]->INSTALL_INTERRUPT_PTR != NULL)
            {
                /* register callback */
                client_handle->PROVIDER_TABLE[i]->INSTALL_INTERRUPT_PTR(provider_handle);
            }
            break;
        }
    }
    /* if array is full do re-alloc */
    if(result == FALSE)
    {
        HMI_PROVIDER_STRUCT_PTR     provider_table_new;

        provider_table_new = _mem_alloc_system_zero(client_handle->MAX_PROVIDER_COUNT * HMI_GROW_UP_PROVIDER_COUNT * sizeof(HMI_PROVIDER_STRUCT_PTR));
        if(provider_table_new == NULL)
        {
            return FALSE;
        }
        /* copy smaller array to bigger array*/
        _mem_copy(client_handle->PROVIDER_TABLE, provider_table_new, client_handle->MAX_PROVIDER_COUNT * sizeof(client_handle->PROVIDER_TABLE));
        _mem_free(client_handle->PROVIDER_TABLE);
        client_handle->PROVIDER_TABLE = (pointer) provider_table_new;
        client_handle->MAX_PROVIDER_COUNT = client_handle->MAX_PROVIDER_COUNT * HMI_GROW_UP_PROVIDER_COUNT;
        for(i=0; i<client_handle->MAX_PROVIDER_COUNT; i++)
        {
            if(client_handle->PROVIDER_TABLE[i] == NULL)
            {
                result = TRUE;
                client_handle->PROVIDER_TABLE[i] = provider_handle;
                client_handle->PROVIDER_TABLE[i]->ATTACH_CLIENT(provider_handle,client_handle);
                if (client_handle->PROVIDER_TABLE[i]->INSTALL_INTERRUPT_PTR != NULL)
                {
                    /* register callback */
                    client_handle->PROVIDER_TABLE[i]->INSTALL_INTERRUPT_PTR(provider_handle);
                }
                break;
            }
        }
    }

    return result;
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name    : hmi_remove_provider
* Returned Value   : TRUE if removing success, else FALSE
* Comments         :
*   This function removes provider
*
*END*--------------------------------------------------------------------*/
boolean hmi_remove_provider(HMI_CLIENT_STRUCT_PTR client_handle, HMI_PROVIDER_STRUCT_PTR provider_handle)
{
    boolean result = FALSE;
    uint_32 i;

    if((provider_handle == NULL) || (client_handle==NULL))
    {
        return result;
    }
    /* remove provider from the table */
    for(i=0; i<client_handle->MAX_PROVIDER_COUNT; i++)
    {
        if(client_handle->PROVIDER_TABLE[i] == provider_handle)
        {
            result = TRUE;
            if (client_handle->PROVIDER_TABLE[i]->UNINSTALL_INTERRUPT_PTR != NULL)
            {
                /* unregister callback */
                client_handle->PROVIDER_TABLE[i]->UNINSTALL_INTERRUPT_PTR(provider_handle);
            }
            client_handle->PROVIDER_TABLE[i] = NULL;
            break;
        }
    }
    return result;
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/time_tables.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: time_tables.c$
* $Version : 3.8.1.0$
* $Date    : Apr-13-2012$
*
* Comments:
*
*   This file contains the function for adding days to a tick
*   struct
*
*END************************************************************************/

#include "mqx_inc.h"


const uchar _time_days_in_month_internal[2][13] =
{
  { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
  { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};

const uint_32 _time_secs_before_month_internal[2][13] =
{
   {
      0,
      31UL*SECS_IN_DAY,
      59UL*SECS_IN_DAY,
      90UL*SECS_IN_DAY,
      120UL*SECS_IN_DAY,
      151UL*SECS_IN_DAY,
      181UL*SECS_IN_DAY,
      212UL*SECS_IN_DAY,
      243UL*SECS_IN_DAY,
      273UL*SECS_IN_DAY,
      304UL*SECS_IN_DAY,
      334UL*SECS_IN_DAY,
      ~0
   },
   {
      0,
      31UL*SECS_IN_DAY,
      60UL*SECS_IN_DAY,
      91UL*SECS_IN_DAY,
      121UL*SECS_IN_DAY,
      152UL*SECS_IN_DAY,
      182UL*SECS_IN_DAY,
      213UL*SECS_IN_DAY,
      244UL*SECS_IN_DAY,
      274UL*SECS_IN_DAY,
      305UL*SECS_IN_DAY,
      335UL*SECS_IN_DAY,
      ~0
   }
};

/*
 * The following array contains the number of seconds between Jan 1, 1970
 * and a given year. For example, to determine the number of seconds 
 * between Jan 1, 1970 and Jan 1, 1988, the subscript (1988-1970) would
 * be used to index into this table. Note that the first entry is equal to 
 * zero (0).
 *
 * NOTE:  If this table is expanded to include the year 2100, then it must
 * be noted that the year 2100 is NOT a leap year.  Only century years 
 * divisible by 400 are leap years.
 */

const uint_32 _time_secs_before_year_internal[] =
{
   ((1970UL-1970UL) * SECS_IN_YEAR) + ( 0UL * SECS_IN_DAY),
   ((1971UL-1970UL) * SECS_IN_YEAR) + ( 0UL * SECS_IN_DAY),
   ((1972UL-1970UL) * SECS_IN_YEAR) + ( 0UL * SECS_IN_DAY),
   ((1973UL-1970UL) * SECS_IN_YEAR) + ( 1UL * SECS_IN_DAY),
   ((1974UL-1970UL) * SECS_IN_YEAR) + ( 1UL * SECS_IN_DAY),
   ((1975UL-1970UL) * SECS_IN_YEAR) + ( 1UL * SECS_IN_DAY),
   ((1976UL-1970UL) * SECS_IN_YEAR) + ( 1UL * SECS_IN_DAY),
   ((1977UL-1970UL) * SECS_IN_YEAR) + ( 2UL * SECS_IN_DAY),
   ((1978UL-1970UL) * SECS_IN_YEAR) + ( 2UL * SECS_IN_DAY),
   ((1979UL-1970UL) * SECS_IN_YEAR) + ( 2UL * SECS_IN_DAY),
   ((1980UL-1970UL) * SECS_IN_YEAR) + ( 2UL * SECS_IN_DAY),
   ((1981UL-1970UL) * SECS_IN_YEAR) + ( 3UL * SECS_IN_DAY),
   ((1982UL-1970UL) * SECS_IN_YEAR) + ( 3UL * SECS_IN_DAY),
   ((1983UL-1970UL) * SECS_IN_YEAR) + ( 3UL * SECS_IN_DAY),
   ((1984UL-1970UL) * SECS_IN_YEAR) + ( 3UL * SECS_IN_DAY),
   ((1985UL-1970UL) * SECS_IN_YEAR) + ( 4UL * SECS_IN_DAY),
   ((1986UL-1970UL) * SECS_IN_YEAR) + ( 4UL * SECS_IN_DAY),
   ((1987UL-1970UL) * SECS_IN_YEAR) + ( 4UL * SECS_IN_DAY),
   ((1988UL-1970UL) * SECS_IN_YEAR) + ( 4UL * SECS_IN_DAY),
   ((1989UL-1970UL) * SECS_IN_YEAR) + ( 5UL * SECS_IN_DAY),
   ((1990UL-1970UL) * SECS_IN_YEAR) + ( 5UL * SECS_IN_DAY),
   ((1991UL-1970UL) * SECS_IN_YEAR) + ( 5UL * SECS_IN_DAY),
   ((1992UL-1970UL) * SECS_IN_YEAR) + ( 5UL * SECS_IN_DAY),
   ((1993UL-1970UL) * SECS_IN_YEAR) + ( 6UL * SECS_IN_DAY),
   ((1994UL-1970UL) * SECS_IN_YEAR) + ( 6UL * SECS_IN_DAY),
   ((1996UL-1970UL) * SECS_IN_YEAR) + ( 6UL * SECS_IN_DAY),
   ((1996UL-1970UL) * SECS_IN_YEAR) + ( 6UL * SECS_IN_DAY),
   ((1997UL-1970UL) * SECS_IN_YEAR) + ( 7UL * SECS_IN_DAY),
   ((1998UL-1970UL) * SECS_IN_YEAR) + ( 7UL * SECS_IN_DAY),
   ((1999UL-1970UL) * SECS_IN_YEAR) + ( 7UL * SECS_IN_DAY),
   ((2000UL-1970UL) * SECS_IN_YEAR) + ( 7UL * SECS_IN_DAY),
   ((2001UL-1970UL) * SECS_IN_YEAR) + ( 8UL * SECS_IN_DAY),
   ((2002UL-1970UL) * SECS_IN_YEAR) + ( 8UL * SECS_IN_DAY),
   ((2003UL-1970UL) * SECS_IN_YEAR) + ( 8UL * SECS_IN_DAY),
   ((2004UL-1970UL) * SECS_IN_YEAR) + ( 8UL * SECS_IN_DAY),
   ((2005UL-1970UL) * SECS_IN_YEAR) + ( 9UL * SECS_IN_DAY),
   ((2006UL-1970UL) * SECS_IN_YEAR) + ( 9UL * SECS_IN_DAY),
   ((2007UL-1970UL) * SECS_IN_YEAR) + ( 9UL * SECS_IN_DAY),
   ((2008UL-1970UL) * SECS_IN_YEAR) + ( 9UL * SECS_IN_DAY),
   ((2009UL-1970UL) * SECS_IN_YEAR) + (10UL * SECS_IN_DAY),
   ((2010UL-1970UL) * SECS_IN_YEAR) + (10UL * SECS_IN_DAY),
   ((2011UL-1970UL) * SECS_IN_YEAR) + (10UL * SECS_IN_DAY),
   ((2012UL-1970UL) * SECS_IN_YEAR) + (10UL * SECS_IN_DAY),
   ((2013UL-1970UL) * SECS_IN_YEAR) + (11UL * SECS_IN_DAY),
   ((2014UL-1970UL) * SECS_IN_YEAR) + (11UL * SECS_IN_DAY),
   ((2015UL-1970UL) * SECS_IN_YEAR) + (11UL * SECS_IN_DAY),
   ((2016UL-1970UL) * SECS_IN_YEAR) + (11UL * SECS_IN_DAY),
   ((2017UL-1970UL) * SECS_IN_YEAR) + (12UL * SECS_IN_DAY),
   ((2018UL-1970UL) * SECS_IN_YEAR) + (12UL * SECS_IN_DAY),
   ((2019UL-1970UL) * SECS_IN_YEAR) + (12UL * SECS_IN_DAY),
   ((2020UL-1970UL) * SECS_IN_YEAR) + (12UL * SECS_IN_DAY),
   ((2021UL-1970UL) * SECS_IN_YEAR) + (13UL * SECS_IN_DAY),
   ((2022UL-1970UL) * SECS_IN_YEAR) + (13UL * SECS_IN_DAY),
   ((2023UL-1970UL) * SECS_IN_YEAR) + (13UL * SECS_IN_DAY),
   ((2024UL-1970UL) * SECS_IN_YEAR) + (13UL * SECS_IN_DAY),
   ((2025UL-1970UL) * SECS_IN_YEAR) + (14UL * SECS_IN_DAY),
   ((2026UL-1970UL) * SECS_IN_YEAR) + (14UL * SECS_IN_DAY),
   ((2027UL-1970UL) * SECS_IN_YEAR) + (14UL * SECS_IN_DAY),
   ((2028UL-1970UL) * SECS_IN_YEAR) + (14UL * SECS_IN_DAY),
   ((2029UL-1970UL) * SECS_IN_YEAR) + (15UL * SECS_IN_DAY),
   ((2030UL-1970UL) * SECS_IN_YEAR) + (15UL * SECS_IN_DAY),
   ((2031UL-1970UL) * SECS_IN_YEAR) + (15UL * SECS_IN_DAY),
   ((2032UL-1970UL) * SECS_IN_YEAR) + (15UL * SECS_IN_DAY),
   ((2033UL-1970UL) * SECS_IN_YEAR) + (16UL * SECS_IN_DAY),
   ((2034UL-1970UL) * SECS_IN_YEAR) + (16UL * SECS_IN_DAY),
   ((2035UL-1970UL) * SECS_IN_YEAR) + (16UL * SECS_IN_DAY),
   ((2036UL-1970UL) * SECS_IN_YEAR) + (16UL * SECS_IN_DAY),
   ((2037UL-1970UL) * SECS_IN_YEAR) + (17UL * SECS_IN_DAY),
   ((2038UL-1970UL) * SECS_IN_YEAR) + (17UL * SECS_IN_DAY),
   ((2039UL-1970UL) * SECS_IN_YEAR) + (17UL * SECS_IN_DAY),
   ((2040UL-1970UL) * SECS_IN_YEAR) + (17UL * SECS_IN_DAY),
   ((2041UL-1970UL) * SECS_IN_YEAR) + (18UL * SECS_IN_DAY),
   ((2042UL-1970UL) * SECS_IN_YEAR) + (18UL * SECS_IN_DAY),
   ((2043UL-1970UL) * SECS_IN_YEAR) + (18UL * SECS_IN_DAY),
   ((2044UL-1970UL) * SECS_IN_YEAR) + (18UL * SECS_IN_DAY),
   ((2045UL-1970UL) * SECS_IN_YEAR) + (19UL * SECS_IN_DAY),
   ((2046UL-1970UL) * SECS_IN_YEAR) + (19UL * SECS_IN_DAY),
   ((2047UL-1970UL) * SECS_IN_YEAR) + (19UL * SECS_IN_DAY),
   ((2048UL-1970UL) * SECS_IN_YEAR) + (19UL * SECS_IN_DAY),
   ((2049UL-1970UL) * SECS_IN_YEAR) + (20UL * SECS_IN_DAY),
   ((2050UL-1970UL) * SECS_IN_YEAR) + (20UL * SECS_IN_DAY),
   ((2051UL-1970UL) * SECS_IN_YEAR) + (20UL * SECS_IN_DAY),
   ((2052UL-1970UL) * SECS_IN_YEAR) + (20UL * SECS_IN_DAY),
   ((2053UL-1970UL) * SECS_IN_YEAR) + (21UL * SECS_IN_DAY),
   ((2054UL-1970UL) * SECS_IN_YEAR) + (21UL * SECS_IN_DAY),
   ((2055UL-1970UL) * SECS_IN_YEAR) + (21UL * SECS_IN_DAY),
   ((2056UL-1970UL) * SECS_IN_YEAR) + (21UL * SECS_IN_DAY),
   ((2057UL-1970UL) * SECS_IN_YEAR) + (22UL * SECS_IN_DAY),
   ((2058UL-1970UL) * SECS_IN_YEAR) + (22UL * SECS_IN_DAY),
   ((2059UL-1970UL) * SECS_IN_YEAR) + (22UL * SECS_IN_DAY),
   ((2060UL-1970UL) * SECS_IN_YEAR) + (22UL * SECS_IN_DAY),
   ((2061UL-1970UL) * SECS_IN_YEAR) + (23UL * SECS_IN_DAY),
   ((2062UL-1970UL) * SECS_IN_YEAR) + (23UL * SECS_IN_DAY),
   ((2063UL-1970UL) * SECS_IN_YEAR) + (23UL * SECS_IN_DAY),
   ((2064UL-1970UL) * SECS_IN_YEAR) + (23UL * SECS_IN_DAY),
   ((2065UL-1970UL) * SECS_IN_YEAR) + (24UL * SECS_IN_DAY),
   ((2066UL-1970UL) * SECS_IN_YEAR) + (24UL * SECS_IN_DAY),
   ((2067UL-1970UL) * SECS_IN_YEAR) + (24UL * SECS_IN_DAY),
   ((2068UL-1970UL) * SECS_IN_YEAR) + (24UL * SECS_IN_DAY),
   ((2069UL-1970UL) * SECS_IN_YEAR) + (25UL * SECS_IN_DAY),
   ((2070UL-1970UL) * SECS_IN_YEAR) + (25UL * SECS_IN_DAY),
   ((2071UL-1970UL) * SECS_IN_YEAR) + (25UL * SECS_IN_DAY),
   ((2072UL-1970UL) * SECS_IN_YEAR) + (25UL * SECS_IN_DAY),
   ((2073UL-1970UL) * SECS_IN_YEAR) + (26UL * SECS_IN_DAY),
   ((2074UL-1970UL) * SECS_IN_YEAR) + (26UL * SECS_IN_DAY),
   ((2075UL-1970UL) * SECS_IN_YEAR) + (26UL * SECS_IN_DAY),
   ((2076UL-1970UL) * SECS_IN_YEAR) + (26UL * SECS_IN_DAY),
   ((2077UL-1970UL) * SECS_IN_YEAR) + (27UL * SECS_IN_DAY),
   ((2078UL-1970UL) * SECS_IN_YEAR) + (27UL * SECS_IN_DAY),
   ((2079UL-1970UL) * SECS_IN_YEAR) + (27UL * SECS_IN_DAY),
   ((2080UL-1970UL) * SECS_IN_YEAR) + (27UL * SECS_IN_DAY),
   ((2081UL-1970UL) * SECS_IN_YEAR) + (28UL * SECS_IN_DAY),
   ((2082UL-1970UL) * SECS_IN_YEAR) + (28UL * SECS_IN_DAY),
   ((2083UL-1970UL) * SECS_IN_YEAR) + (28UL * SECS_IN_DAY),
   ((2084UL-1970UL) * SECS_IN_YEAR) + (28UL * SECS_IN_DAY),
   ((2085UL-1970UL) * SECS_IN_YEAR) + (29UL * SECS_IN_DAY),
   ((2086UL-1970UL) * SECS_IN_YEAR) + (29UL * SECS_IN_DAY),
   ((2087UL-1970UL) * SECS_IN_YEAR) + (29UL * SECS_IN_DAY),
   ((2088UL-1970UL) * SECS_IN_YEAR) + (29UL * SECS_IN_DAY),
   ((2089UL-1970UL) * SECS_IN_YEAR) + (30UL * SECS_IN_DAY),
   ((2090UL-1970UL) * SECS_IN_YEAR) + (30UL * SECS_IN_DAY),
   ((2091UL-1970UL) * SECS_IN_YEAR) + (30UL * SECS_IN_DAY),
   ((2092UL-1970UL) * SECS_IN_YEAR) + (30UL * SECS_IN_DAY),
   ((2093UL-1970UL) * SECS_IN_YEAR) + (31UL * SECS_IN_DAY),
   ((2094UL-1970UL) * SECS_IN_YEAR) + (31UL * SECS_IN_DAY),
   ((2095UL-1970UL) * SECS_IN_YEAR) + (31UL * SECS_IN_DAY),
   ((2096UL-1970UL) * SECS_IN_YEAR) + (31UL * SECS_IN_DAY),
   ((2097UL-1970UL) * SECS_IN_YEAR) + (32UL * SECS_IN_DAY),
   ((2098UL-1970UL) * SECS_IN_YEAR) + (32UL * SECS_IN_DAY),
   ((2099UL-1970UL) * SECS_IN_YEAR) + (32UL * SECS_IN_DAY),
   ~0
};

const uint_16 _time_days_before_month_internal[2][13] =
{
   {  0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, ~0},
   {  0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, ~0}
};

/*
 * The following array contains the number of days between Jan 1, 1970
 * and a given year. For example, to determine the number of days 
 * between Jan 1, 1970 and Jan 1, 1988, the subscript (1988-1970) would
 * be used to index into this table. Note that the first entry is equal to 
 * zero (0).
 *
 */
const uint_32 _time_days_before_year_internal[XCLK_ENTRIES+1] =
{
   ((1970-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (0UL),
   ((1971-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (0UL),
   ((1972-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (0UL),
   ((1973-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (1UL),
   ((1974-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (1UL),
   ((1975-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (1UL),
   ((1976-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (1UL),
   ((1977-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (2UL),
   ((1978-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (2UL),
   ((1979-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (2UL),
   ((1980-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (2UL),
   ((1981-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (3UL),
   ((1982-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (3UL),
   ((1983-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (3UL),
   ((1984-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (3UL),
   ((1985-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (4UL),
   ((1986-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (4UL),
   ((1987-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (4UL),
   ((1988-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (4UL),
   ((1989-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (5UL),
   ((1990-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (5UL),
   ((1991-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (5UL),
   ((1992-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (5UL),
   ((1993-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (6UL),
   ((1994-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (6UL),
   ((1995-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (6UL),
   ((1996-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (6UL),
   ((1997-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (7UL),
   ((1998-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (7UL),
   ((1999-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (7UL),
   ((2000-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (7UL),
   ((2001-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (8UL),
   ((2002-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (8UL),
   ((2003-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (8UL),
   ((2004-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (8UL),
   ((2005-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (9UL),
   ((2006-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (9UL),
   ((2007-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (9UL),
   ((2008-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (9UL),
   ((2009-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (10UL),
   ((2010-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (10UL),
   ((2011-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (10UL),
   ((2012-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (10UL),
   ((2013-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (11UL),
   ((2014-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (11UL),
   ((2015-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (11UL),
   ((2016-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (11UL),
   ((2017-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (12UL),
   ((2018-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (12UL),
   ((2019-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (12UL),
   ((2020-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (12UL),
   ((2021-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (13UL),
   ((2022-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (13UL),
   ((2023-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (13UL),
   ((2024-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (13UL),
   ((2025-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (14UL),
   ((2026-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (14UL),
   ((2027-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (14UL),
   ((2028-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (14UL),
   ((2029-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (15UL),
   ((2030-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (15UL),
   ((2031-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (15UL),
   ((2032-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (15UL),
   ((2033-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (16UL),
   ((2034-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (16UL),
   ((2035-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (16UL),
   ((2036-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (16UL),
   ((2037-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (17UL),
   ((2038-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (17UL),
   ((2039-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (17UL),
   ((2040-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (17UL),
   ((2041-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (18UL),
   ((2042-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (18UL),
   ((2043-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (18UL),
   ((2044-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (18UL),
   ((2045-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (19UL),
   ((2046-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (19UL),
   ((2047-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (19UL),
   ((2048-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (19UL),
   ((2049-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (20UL),
   ((2050-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (20UL),
   ((2051-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (20UL),
   ((2052-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (20UL),
   ((2053-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (21UL),
   ((2054-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (21UL),
   ((2055-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (21UL),
   ((2056-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (21UL),
   ((2057-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (22UL),
   ((2058-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (22UL),
   ((2059-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (22UL),
   ((2060-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (22UL),
   ((2061-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (23UL),
   ((2062-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (23UL),
   ((2063-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (23UL),
   ((2064-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (23UL),
   ((2065-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (24UL),
   ((2066-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (24UL),
   ((2067-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (24UL),
   ((2068-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (24UL),
   ((2069-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (25UL),
   ((2070-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (25UL),
   ((2071-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (25UL),
   ((2072-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (25UL),
   ((2073-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (26UL),
   ((2074-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (26UL),
   ((2075-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (26UL),
   ((2076-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (26UL),
   ((2077-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (27UL),
   ((2078-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (27UL),
   ((2079-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (27UL),
   ((2080-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (27UL),
   ((2081-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (28UL),
   ((2082-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (28UL),
   ((2083-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (28UL),
   ((2084-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (28UL),
   ((2085-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (29UL),
   ((2086-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (29UL),
   ((2087-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (29UL),
   ((2088-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (29UL),
   ((2089-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (30UL),
   ((2090-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (30UL),
   ((2091-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (30UL),
   ((2092-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (30UL),
   ((2093-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (31UL),
   ((2094-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (31UL),
   ((2095-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (31UL),
   ((2096-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (31UL),
   ((2097-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (32UL),
   ((2098-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (32UL),
   ((2099-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (32UL),
   ((2100-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (32UL),
   ((2101-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (32UL),
   ((2102-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (32UL),
   ((2103-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (32UL),
   ((2104-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (32UL),
   ((2105-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (33UL),
   ((2106-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (33UL),
   ((2107-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (33UL),
   ((2108-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (33UL),
   ((2109-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (34UL),
   ((2110-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (34UL),
   ((2111-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (34UL),
   ((2112-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (34UL),
   ((2113-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (35UL),
   ((2114-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (35UL),
   ((2115-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (35UL),
   ((2116-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (35UL),
   ((2117-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (36UL),
   ((2118-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (36UL),
   ((2119-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (36UL),
   ((2120-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (36UL),
   ((2121-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (37UL),
   ((2122-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (37UL),
   ((2123-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (37UL),
   ((2124-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (37UL),
   ((2125-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (38UL),
   ((2126-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (38UL),
   ((2127-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (38UL),
   ((2128-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (38UL),
   ((2129-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (39UL),
   ((2130-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (39UL),
   ((2131-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (39UL),
   ((2132-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (39UL),
   ((2133-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (40UL),
   ((2134-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (40UL),
   ((2135-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (40UL),
   ((2136-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (40UL),
   ((2137-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (41UL),
   ((2138-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (41UL),
   ((2139-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (41UL),
   ((2140-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (41UL),
   ((2141-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (42UL),
   ((2142-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (42UL),
   ((2143-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (42UL),
   ((2144-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (42UL),
   ((2145-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (43UL),
   ((2146-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (43UL),
   ((2147-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (43UL),
   ((2148-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (43UL),
   ((2149-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (44UL),
   ((2150-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (44UL),
   ((2151-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (44UL),
   ((2152-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (44UL),
   ((2153-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (45UL),
   ((2154-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (45UL),
   ((2155-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (45UL),
   ((2156-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (45UL),
   ((2157-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (46UL),
   ((2158-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (46UL),
   ((2159-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (46UL),
   ((2160-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (46UL),
   ((2161-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (47UL),
   ((2162-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (47UL),
   ((2163-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (47UL),
   ((2164-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (47UL),
   ((2165-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (48UL),
   ((2166-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (48UL),
   ((2167-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (48UL),
   ((2168-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (48UL),
   ((2169-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (49UL),
   ((2170-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (49UL),
   ((2171-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (49UL),
   ((2172-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (49UL),
   ((2173-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (50UL),
   ((2174-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (50UL),
   ((2175-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (50UL),
   ((2176-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (50UL),
   ((2177-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (51UL),
   ((2178-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (51UL),
   ((2179-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (51UL),
   ((2180-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (51UL),
   ((2181-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (52UL),
   ((2182-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (52UL),
   ((2183-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (52UL),
   ((2184-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (52UL),
   ((2185-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (53UL),
   ((2186-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (53UL),
   ((2187-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (53UL),
   ((2188-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (53UL),
   ((2189-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (54UL),
   ((2190-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (54UL),
   ((2191-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (54UL),
   ((2192-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (54UL),
   ((2193-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (55UL),
   ((2194-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (55UL),
   ((2195-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (55UL),
   ((2196-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (55UL),
   ((2197-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (56UL),
   ((2198-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (56UL),
   ((2199-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (56UL),
   ((2200-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (56UL),
   ((2201-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (56UL),
   ((2202-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (56UL),
   ((2203-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (56UL),
   ((2204-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (56UL),
   ((2205-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (57UL),
   ((2206-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (57UL),
   ((2207-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (57UL),
   ((2208-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (57UL),
   ((2209-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (58UL),
   ((2210-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (58UL),
   ((2211-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (58UL),
   ((2212-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (58UL),
   ((2213-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (59UL),
   ((2214-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (59UL),
   ((2215-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (59UL),
   ((2216-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (59UL),
   ((2217-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (60UL),
   ((2218-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (60UL),
   ((2219-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (60UL),
   ((2220-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (60UL),
   ((2221-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (61UL),
   ((2222-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (61UL),
   ((2223-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (61UL),
   ((2224-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (61UL),
   ((2225-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (62UL),
   ((2226-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (62UL),
   ((2227-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (62UL),
   ((2228-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (62UL),
   ((2229-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (63UL),
   ((2230-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (63UL),
   ((2231-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (63UL),
   ((2232-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (63UL),
   ((2233-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (64UL),
   ((2234-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (64UL),
   ((2235-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (64UL),
   ((2236-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (64UL),
   ((2237-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (65UL),
   ((2238-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (65UL),
   ((2239-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (65UL),
   ((2240-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (65UL),
   ((2241-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (66UL),
   ((2242-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (66UL),
   ((2243-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (66UL),
   ((2244-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (66UL),
   ((2245-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (67UL),
   ((2246-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (67UL),
   ((2247-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (67UL),
   ((2248-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (67UL),
   ((2249-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (68UL),
   ((2250-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (68UL),
   ((2251-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (68UL),
   ((2252-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (68UL),
   ((2253-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (69UL),
   ((2254-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (69UL),
   ((2255-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (69UL),
   ((2256-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (69UL),
   ((2257-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (70UL),
   ((2258-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (70UL),
   ((2259-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (70UL),
   ((2260-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (70UL),
   ((2261-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (71UL),
   ((2262-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (71UL),
   ((2263-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (71UL),
   ((2264-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (71UL),
   ((2265-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (72UL),
   ((2266-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (72UL),
   ((2267-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (72UL),
   ((2268-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (72UL),
   ((2269-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (73UL),
   ((2270-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (73UL),
   ((2271-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (73UL),
   ((2272-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (73UL),
   ((2273-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (74UL),
   ((2274-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (74UL),
   ((2275-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (74UL),
   ((2276-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (74UL),
   ((2277-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (75UL),
   ((2278-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (75UL),
   ((2279-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (75UL),
   ((2280-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (75UL),
   ((2281-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (76UL),
   ((2282-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (76UL),
   ((2283-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (76UL),
   ((2284-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (76UL),
   ((2285-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (77UL),
   ((2286-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (77UL),
   ((2287-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (77UL),
   ((2288-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (77UL),
   ((2289-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (78UL),
   ((2290-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (78UL),
   ((2291-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (78UL),
   ((2292-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (78UL),
   ((2293-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (79UL),
   ((2294-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (79UL),
   ((2295-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (79UL),
   ((2296-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (79UL),
   ((2297-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (80UL),
   ((2298-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (80UL),
   ((2299-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (80UL),
   ((2300-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (80UL),
   ((2301-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (80UL),
   ((2302-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (80UL),
   ((2303-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (80UL),
   ((2304-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (80UL),
   ((2305-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (81UL),
   ((2306-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (81UL),
   ((2307-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (81UL),
   ((2308-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (81UL),
   ((2309-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (82UL),
   ((2310-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (82UL),
   ((2311-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (82UL),
   ((2312-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (82UL),
   ((2313-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (83UL),
   ((2314-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (83UL),
   ((2315-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (83UL),
   ((2316-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (83UL),
   ((2317-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (84UL),
   ((2318-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (84UL),
   ((2319-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (84UL),
   ((2320-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (84UL),
   ((2321-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (85UL),
   ((2322-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (85UL),
   ((2323-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (85UL),
   ((2324-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (85UL),
   ((2325-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (86UL),
   ((2326-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (86UL),
   ((2327-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (86UL),
   ((2328-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (86UL),
   ((2329-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (87UL),
   ((2330-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (87UL),
   ((2331-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (87UL),
   ((2332-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (87UL),
   ((2333-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (88UL),
   ((2334-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (88UL),
   ((2335-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (88UL),
   ((2336-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (88UL),
   ((2337-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (89UL),
   ((2338-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (89UL),
   ((2339-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (89UL),
   ((2340-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (89UL),
   ((2341-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (90UL),
   ((2342-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (90UL),
   ((2343-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (90UL),
   ((2344-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (90UL),
   ((2345-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (91UL),
   ((2346-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (91UL),
   ((2347-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (91UL),
   ((2348-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (91UL),
   ((2349-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (92UL),
   ((2350-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (92UL),
   ((2351-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (92UL),
   ((2352-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (92UL),
   ((2353-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (93UL),
   ((2354-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (93UL),
   ((2355-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (93UL),
   ((2356-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (93UL),
   ((2357-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (94UL),
   ((2358-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (94UL),
   ((2359-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (94UL),
   ((2360-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (94UL),
   ((2361-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (95UL),
   ((2362-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (95UL),
   ((2363-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (95UL),
   ((2364-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (95UL),
   ((2365-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (96UL),
   ((2366-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (96UL),
   ((2367-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (96UL),
   ((2368-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (96UL),
   ((2369-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (97UL),
   ((2370-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (97UL),
   ((2371-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (97UL),
   ((2372-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (97UL),
   ((2373-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (98UL),
   ((2374-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (98UL),
   ((2375-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (98UL),
   ((2376-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (98UL),
   ((2377-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (99UL),
   ((2378-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (99UL),
   ((2379-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (99UL),
   ((2380-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (99UL),
   ((2381-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (100UL),
   ((2382-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (100UL),
   ((2383-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (100UL),
   ((2384-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (100UL),
   ((2385-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (101UL),
   ((2386-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (101UL),
   ((2387-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (101UL),
   ((2388-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (101UL),
   ((2389-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (102UL),
   ((2390-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (102UL),
   ((2391-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (102UL),
   ((2392-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (102UL),
   ((2393-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (103UL),
   ((2394-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (103UL),
   ((2395-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (103UL),
   ((2396-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (103UL),
   ((2397-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (104UL),
   ((2398-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (104UL),
   ((2399-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (104UL),
   ((2400-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (104UL),
   ((2401-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (105UL),
   ((2402-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (105UL),
   ((2403-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (105UL),
   ((2404-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (105UL),
   ((2405-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (106UL),
   ((2406-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (106UL),
   ((2407-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (106UL),
   ((2408-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (106UL),
   ((2409-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (107UL),
   ((2410-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (107UL),
   ((2411-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (107UL),
   ((2412-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (107UL),
   ((2413-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (108UL),
   ((2414-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (108UL),
   ((2415-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (108UL),
   ((2416-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (108UL),
   ((2417-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (109UL),
   ((2418-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (109UL),
   ((2419-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (109UL),
   ((2420-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (109UL),
   ((2421-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (110UL),
   ((2422-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (110UL),
   ((2423-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (110UL),
   ((2424-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (110UL),
   ((2425-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (111UL),
   ((2426-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (111UL),
   ((2427-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (111UL),
   ((2428-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (111UL),
   ((2429-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (112UL),
   ((2430-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (112UL),
   ((2431-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (112UL),
   ((2432-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (112UL),
   ((2433-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (113UL),
   ((2434-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (113UL),
   ((2435-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (113UL),
   ((2436-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (113UL),
   ((2437-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (114UL),
   ((2438-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (114UL),
   ((2439-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (114UL),
   ((2440-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (114UL),
   ((2441-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (115UL),
   ((2442-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (115UL),
   ((2443-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (115UL),
   ((2444-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (115UL),
   ((2445-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (116UL),
   ((2446-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (116UL),
   ((2447-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (116UL),
   ((2448-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (116UL),
   ((2449-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (117UL),
   ((2450-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (117UL),
   ((2451-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (117UL),
   ((2452-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (117UL),
   ((2453-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (118UL),
   ((2454-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (118UL),
   ((2455-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (118UL),
   ((2456-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (118UL),
   ((2457-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (119UL),
   ((2458-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (119UL),
   ((2459-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (119UL),
   ((2460-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (119UL),
   ((2461-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (120UL),
   ((2462-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (120UL),
   ((2463-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (120UL),
   ((2464-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (120UL),
   ((2465-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (121UL),
   ((2466-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (121UL),
   ((2467-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (121UL),
   ((2468-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (121UL),
   ((2469-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (122UL),
   ((2470-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (122UL),
   ((2471-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (122UL),
   ((2472-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (122UL),
   ((2473-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (123UL),
   ((2474-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (123UL),
   ((2475-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (123UL),
   ((2476-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (123UL),
   ((2477-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (124UL),
   ((2478-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (124UL),
   ((2479-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (124UL),
   ((2480-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (124UL),
   ((2481-XCLK_FIRST_YEAR) * DAYS_IN_YEAR) + (125UL),
   ~0
};

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sdcard/sdcard.h<|end_filename|>
#ifndef __sdcard_h__
#define __sdcard_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sdcard.h$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions private to the SD card.
*
*END************************************************************************/

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

#define IO_SDCARD_BLOCK_SIZE_POWER   (9)
#define IO_SDCARD_BLOCK_SIZE         (1 << IO_SDCARD_BLOCK_SIZE_POWER)


/*----------------------------------------------------------------------*/
/*
**                    DATATYPE DEFINITIONS
*/

/*
** SDCARD_INIT STRUCT
**
** The address of this structure is used to maintain sd card init
** information.
*/
typedef struct sdcard_init_struct
{
   /* The function to call to initialize sd card */
   boolean  (_CODE_PTR_ INIT_FUNC)(MQX_FILE_PTR);

   /* The function to call to read blocks from sd card */
   _mqx_int (_CODE_PTR_ READ_FUNC)(MQX_FILE_PTR, uchar_ptr, uint_32, uint_32);

   /* The function to call to write blocks to sd card */
   _mqx_int (_CODE_PTR_ WRITE_FUNC)(MQX_FILE_PTR, uchar_ptr, uint_32, uint_32);
   
   /* Signal specification */
   uint_32             SIGNALS;

} SDCARD_INIT_STRUCT, _PTR_ SDCARD_INIT_STRUCT_PTR;


#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_int _io_sdcard_install(char_ptr,SDCARD_INIT_STRUCT_PTR,MQX_FILE_PTR);

#ifdef __cplusplus
}
#endif


#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/io_dun/io_dun.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_dun.c$
* $Version : 3.8.11.0$
* $Date    : Sep-26-2012$
*
* Comments:
*
*   This file contains a driver used by PPP to communicate to
*   Windows Dial-Up Networking or to Windows NT RAS.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>
#include "io_dun.h"

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dun_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install the Dial-Up Networking driver.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_dun_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr    identifier
   )
{ /* Body */
   IODUN_DEV_STRUCT_PTR dev_ptr = _mem_alloc_system_zero(sizeof(IODUN_DEV_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(dev_ptr,MEM_TYPE_IO_DUN_DEV);               

   dev_ptr->RECV      = "CLIENTCLIENT";
   dev_ptr->SEND      = "CLIENTSERVER";
   dev_ptr->RECV_SIZE = 12;
   dev_ptr->SEND_SIZE = 12;

   return (_io_dev_install(identifier,
      _io_dun_open,
      _io_dun_close,
      _io_dun_read,
      _io_dun_write,
      _io_dun_ioctl,
      dev_ptr)); 
 
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_ras_install
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install the RAS driver.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_ras_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr    identifier
   )
{ /* Body */
   IODUN_DEV_STRUCT_PTR dev_ptr = _mem_alloc_system_zero(sizeof(IODUN_DEV_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(dev_ptr,MEM_TYPE_IO_DUN_DEV);               

   dev_ptr->RECV      = "CLIENTSERVER";
   dev_ptr->SEND      = "CLIENTCLIENT";
   dev_ptr->RECV_SIZE = 12;
   dev_ptr->SEND_SIZE = 12;

   return (_io_dev_install(identifier,
      _io_dun_open,
      _io_dun_close,
      _io_dun_read,
      _io_dun_write,
      _io_dun_ioctl,
      dev_ptr)); 
 
} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dun_open
* Returned Value   : MQX_OK
* Comments         : Opens and initializes the DUN or RAS driver.
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_dun_open
   (
      /* [IN] the file handle for the device being opened */
      MQX_FILE_PTR fd_ptr,
      
      /* [IN] the name of the device */
      char_ptr    open_name_ptr,

      /* [IN] the flags to be used during operation:
      ** echo, translation, xon/xoff, encoded into a pointer.
      */
      char_ptr    f_ptr
   )
{  /* Body */
   IODUN_DEV_STRUCT_PTR dev_ptr = fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
   IODUN_STRUCT_PTR ras_ptr = _mem_alloc_system_zero(sizeof(IODUN_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (ras_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(ras_ptr,MEM_TYPE_IO_DUN);                   
   fd_ptr->DEV_DATA_PTR = ras_ptr;

   _lwsem_create(&ras_ptr->LWSEM,1);

   ras_ptr->STATE = 0;
   ras_ptr->F_PTR = (MQX_FILE_PTR)f_ptr;
   ras_ptr->PARSE = dev_ptr->RECV;

   _io_write(ras_ptr->F_PTR, dev_ptr->SEND, dev_ptr->SEND_SIZE);

   return(MQX_OK);   

} /* Endbody */ 

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dun_close
* Returned Value   : ERROR CODE
* Comments         : Closes ras driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_dun_close
   (
      /* [IN] the file handle for the device being closed */
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */
   IODUN_STRUCT_PTR ras_ptr = fd_ptr->DEV_DATA_PTR;

   _lwsem_destroy(&ras_ptr->LWSEM);
   _mem_free(ras_ptr);

   return(MQX_OK);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dun_read
* Returned Value   : number of characters read
* Comments         : Reads data from ras driver
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_dun_read
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the characters are to be stored */
      char_ptr    data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int    num
   )
{ /* Body */
   IODUN_STRUCT_PTR ras_ptr = fd_ptr->DEV_DATA_PTR;
   _mqx_int         numchar = num;

   _lwsem_wait(&ras_ptr->LWSEM);

   while (numchar--) {
      *data_ptr++ = _io_dun_read_char(fd_ptr);
   } /* Endwhile */

   _lwsem_post(&ras_ptr->LWSEM);
   return(num);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dun_write
* Returned Value   : number of characters written
* Comments         : Writes data to the ras device
* 
*END*----------------------------------------------------------------------*/

_mqx_int _io_dun_write
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] where the characters are */
      char_ptr    data_ptr,

      /* [IN] the number of characters to output */
      _mqx_int    num
   )
{ /* Body */
   IODUN_STRUCT_PTR ras_ptr = fd_ptr->DEV_DATA_PTR;

   return _io_write(ras_ptr->F_PTR, data_ptr, num);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dun_ioctl
* Returned Value   : _mqx_int
* Comments         :
*    Returns result of ioctl operation.
*
*END*-----------------------------------------------------------------------*/

_mqx_int _io_dun_ioctl
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint   cmd,

      /* [IN] the ioctl parameters */
      pointer     param_ptr
   )
{ /* Body */
   IODUN_STRUCT_PTR ras_ptr = fd_ptr->DEV_DATA_PTR;

   return _io_ioctl(ras_ptr->F_PTR, cmd, param_ptr);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_dun_read_char
* Returned Value   : 
* Comments         : Reads data from ras driver
* 
*END*----------------------------------------------------------------------*/

char _io_dun_read_char
   (
      /* [IN] the file handle for the device */
      MQX_FILE_PTR fd_ptr
   )
{  /* Body */
   IODUN_STRUCT_PTR  ras_ptr = fd_ptr->DEV_DATA_PTR;
   IODUN_DEV_STRUCT_PTR dev_ptr = fd_ptr->DEV_PTR->DRIVER_INIT_PTR;

   if (ras_ptr->STATE == 0) {
      ras_ptr->PARSE = dev_ptr->RECV;
      for (;;) {
         ras_ptr->F_CHAR = _io_fgetc(ras_ptr->F_PTR);
         ras_ptr->STATE++;
         if (ras_ptr->F_CHAR != *ras_ptr->PARSE++) {
            ras_ptr->PARSE = dev_ptr->RECV;
            break;
         } /* Endif */
         if (ras_ptr->STATE == dev_ptr->RECV_SIZE) {
            _io_write(ras_ptr->F_PTR, dev_ptr->SEND, dev_ptr->SEND_SIZE);
            ras_ptr->STATE = 0;
            ras_ptr->PARSE = dev_ptr->RECV;
         } /* Endif */
      } /* Endfor */
   } /* Endif */

   if (--ras_ptr->STATE) {
      return *ras_ptr->PARSE++;
   } else {
      return ras_ptr->F_CHAR;
   } /* Endif */

} /* Endbody */ 

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/printer/usb_host_printer.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_printer.c$
* $Version : 3.8.10.0$
* $Date    : Sep-13-2012$
*
* Comments:
*
*   This file contains  the USB printer class driver
*   Implementation notes:
*   Do not send class "GET" requests while printing -- bidirectional
*   printers may place the status in the print buffer (e.g. some HP).
*   Multiple driver instances require structs customized with 
*   endpoint/interface etc. to be locked or allocated per-instance.
*
*END************************************************************************/
#include "usb_host_printer.h"

#include "mqx_host.h"

/*--------------------------------------------------------------**
** This anchor points to the first class/interface in a linked  **
**   chain of structs, one for each functional print interface. **
**   Items are added by calling "select interface" and removed  **
**   by "delete interface".  Typically an application will call **
**   these select in its attach callback routine.  It may later **
**   call delete, or the call may be automatic during detach.   **
**--------------------------------------------------------------*/

static PRINTER_INTERFACE_STRUCT_PTR prt_anchor = NULL;

/* Private functions for use within this file only */
static USB_STATUS usb_printer_bulk_inout(CLASS_CALL_STRUCT_PTR,
   TR_INIT_PARAM_STRUCT_PTR, boolean);
static USB_STATUS usb_printer_class_send(CLASS_CALL_STRUCT_PTR,
   TR_INIT_PARAM_STRUCT_PTR);
static USB_STATUS usb_printer_class_verify(CLASS_CALL_STRUCT_PTR,
   TR_INIT_PARAM_STRUCT_PTR, tr_callback, pointer);


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_bulk_inout
* Returned Value : USB_OK or error code
* Comments       :
*     Send/receive data already built into a TR structure.
*     This function is a common epilog used by the bulk IO calls.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_printer_bulk_inout
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR      cc_ptr,
      
      /* [IN] TR containing setup packet to be sent */
      TR_INIT_PARAM_STRUCT_PTR   tr_ptr,
      
      /* [IN] send_flag = TRUE means send, = FALSE means receive */
      boolean                    send_flag
   )
{ /* Body */

   PRINTER_INTERFACE_STRUCT_PTR  pis_ptr;
   USB_STATUS                    error = USBERR_NO_INTERFACE;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_bulk_inout");
   #endif

   USB_lock ();

   if (usb_host_class_intf_validate(cc_ptr)) {
      pis_ptr = (PRINTER_INTERFACE_STRUCT_PTR)cc_ptr->class_intf_handle;

      if (send_flag) {
         error = _usb_host_send_data (pis_ptr->host_handle,
            pis_ptr->bulk_out_pipe, tr_ptr);
      } else {
         error = _usb_host_recv_data (pis_ptr->host_handle,
            pis_ptr->control_pipe, tr_ptr);

      } /* EndIf */
   } /* Endif */

   USB_unlock ();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_bulk_inout, SUCCESSFUL");
   #endif
   
   return error;   

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_class_send
* Returned Value : USB_OK or error code
* Comments       :
*     Send a setup packet already built into a TR structure.
*     This function is a common epilog used by the class calls.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_printer_class_send
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR      cc_ptr,
      
      /* [IN] TR containing setup packet to be sent */
      TR_INIT_PARAM_STRUCT_PTR   tr_ptr
   )
{ /* Body */

   DESCRIPTOR_UNION              desc;
   PRINTER_INTERFACE_STRUCT_PTR  pis_ptr;
   USB_STATUS                    error = USBERR_NO_INTERFACE;
   USB_SETUP_PTR                 dev_req;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_class_send");
   #endif
   
   USB_lock ();
   if (usb_host_class_intf_validate (cc_ptr)) {
      pis_ptr = (PRINTER_INTERFACE_STRUCT_PTR)
         cc_ptr->class_intf_handle;
      desc.pntr = pis_ptr->intf_handle;
      dev_req = (USB_SETUP_PTR)tr_ptr->DEV_REQ_PTR;

      *(uint_16*)dev_req->WVALUE = HOST_TO_LE_SHORT_CONST(0);
      dev_req->WINDEX[0] = desc.intf->bAlternateSetting;
      dev_req->WINDEX[1] = desc.intf->bInterfaceNumber;
      *(uint_16*)dev_req->WLENGTH = HOST_TO_LE_SHORT(tr_ptr->G.RX_LENGTH);
         
      error = _usb_host_send_setup (pis_ptr->host_handle, 
            pis_ptr->control_pipe, 
            tr_ptr);
   } /* EndIf */

   USB_unlock ();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_class_send, SUCCESSFUL");
   #endif
   
   return error;   

} /* Endbody */



/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_class_verify
* Returned Value : USB_OK or error code
* Comments       :
*     Verify that the device is still valid -- in particular that
*     it has not been detached (since that occurs without notice).
*     This function is a common prolog used by class calls.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_printer_class_verify
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR      cc_ptr,
      
      /* [IN] TR memory already allocated, initialized here */
      TR_INIT_PARAM_STRUCT_PTR   tr_ptr,
   
      /* [IN] callback for completion/status */
      tr_callback                callback,
   
      /* [IN] user parameter returned by callback */
      pointer                    call_parm
   )
{ /* Body */

   PRINTER_INTERFACE_STRUCT_PTR  pis_ptr;
   USB_STATUS                    error = USBERR_NO_INTERFACE;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_class_verify");
   #endif
   
   USB_lock ();

   if (usb_host_class_intf_validate (cc_ptr)) {
      pis_ptr = (PRINTER_INTERFACE_STRUCT_PTR)
         cc_ptr->class_intf_handle;
      error =  usb_hostdev_validate (pis_ptr->dev_handle);

      if (error == USB_OK) {
         if (callback == NULL) {
            error = USBERR_NULL_CALLBACK;
         } else {
            usb_hostdev_tr_init (tr_ptr, callback, call_parm);
         } /* Endif */
      } /* EndIf */
   } /* Endif */

   USB_unlock ();   

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_class_verify, SUCCESSFUL");
   #endif
   
   return error;   

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_get_device_ID
* Returned Value : USB_OK or error code
* Comments       :
*     Get IEEE 1284 Device ID string.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_printer_get_device_ID
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR      cc_ptr,
      
      /* [IN] callback for completion/status */
      tr_callback                callback,
      
      /* [IN] user parameter returned by callback */
      pointer                    call_parm,
      
      /* [IN] buffer length */
      uint_32                    buf_size,
      
      /* [OUT] device ID buffer */
      uchar_ptr                  buffer
   )
{ /* Body */

   TR_INIT_PARAM_STRUCT          tr;
   USB_STATUS                    error;
   USB_SETUP                     dev_req;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_get_device_ID");
   #endif

   if (USB_OK != (error = usb_printer_class_verify 
      (cc_ptr, &tr, callback, call_parm)))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_printer_get_device_ID, error validating class");
      #endif
      return error;
   } /* Endif */

   tr.G.RX_BUFFER = (pointer)buffer;
   tr.G.RX_LENGTH = buf_size;
   tr.DEV_REQ_PTR = (uchar_ptr)(&dev_req);
   dev_req.BMREQUESTTYPE = REQ_TYPE_CLASS | REQ_TYPE_INTERFACE | REQ_TYPE_IN;
   dev_req.BREQUEST = USB_PRINTER_GET_DEVICE_ID;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_get_device_ID, SUCCESSFUL");
   #endif

   return usb_printer_class_send(cc_ptr, &tr);

} /* Endbody */
 

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_get_port_status
* Returned Value : USB_OK or error code
* Comments       :
*     Get current printer status byte.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_printer_get_port_status
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR      cc_ptr,
      
      /* [IN] callback for completion/status */
      tr_callback                callback,
      
      /* [IN] user parameter returned by callback */
      pointer                    call_parm,
      
      /* [OUT] device ID buffer */
      uint_8_ptr                 status_ptr
   )
{ /* Body */

   TR_INIT_PARAM_STRUCT          tr;
   USB_STATUS                    error;
   USB_SETUP                     dev_req;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_get_port_status");
   #endif
   
   if (USB_OK != (error = usb_printer_class_verify 
      (cc_ptr, &tr, callback, call_parm)))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_printer_get_port_status, error class verify");
      #endif
      return error;
   } /* Endif */

   tr.G.RX_BUFFER = (pointer)status_ptr;
   tr.G.RX_LENGTH = 1;
   tr.DEV_REQ_PTR = (uchar_ptr)(&dev_req);
   dev_req.BMREQUESTTYPE = REQ_TYPE_CLASS | REQ_TYPE_INTERFACE | REQ_TYPE_IN;
   dev_req.BREQUEST = USB_PRINTER_GET_PORT_STATUS;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_get_port_status, SUCCESSFUL");
   #endif
   
   return usb_printer_class_send(cc_ptr, &tr);   

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_soft_reset
* Returned Value : USB_OK or error code
* Comments       :
*     Flush buffers, reset BULK IN & BULK OUT, clear all stalls.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_printer_soft_reset
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR      cc_ptr,
      
      /* [IN] callback for completion/status */
      tr_callback                callback,
      
      /* [IN] user parameter returned by callback */
      pointer                    call_parm     
   )
{ /* Body */

   TR_INIT_PARAM_STRUCT          tr;
   USB_STATUS                    error;
   USB_SETUP                     dev_req;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_soft_reset");
   #endif

   if (USB_OK != (error = usb_printer_class_verify 
      (cc_ptr, &tr, callback, call_parm)))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_printer_soft_reset, error class verify failed");
      #endif
      return error;
   } /* Endif */

   tr.G.RX_BUFFER = NULL;
   tr.G.RX_LENGTH = 0;
   tr.DEV_REQ_PTR = (uchar_ptr)(&dev_req);
   dev_req.BMREQUESTTYPE = REQ_TYPE_CLASS | REQ_TYPE_INTERFACE;
   dev_req.BREQUEST = USB_PRINTER_SOFT_RESET;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_soft_reset, SUCCESSFUL");
   #endif
   return usb_printer_class_send (cc_ptr, &tr);   

} /* Endbody */


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_init
* Returned Value : none
* Comments       :
*     Initialize printer-class interface info struct.
* 
*END*--------------------------------------------------------------------*/

void usb_printer_init
   (
      /* [IN] device/descriptor/pipe handles */
      PIPE_BUNDLE_STRUCT_PTR  pbs_ptr,
      
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR   prt_call_ptr
   )
{ /* Body */

   PRINTER_INTERFACE_STRUCT_PTR  prt_intf;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_init");
   #endif

   /* Pointer validity-checking, clear memory, init header */
   prt_intf = prt_call_ptr->class_intf_handle;
   if (USB_OK != usb_host_class_intf_init (pbs_ptr, (pointer)prt_intf, (pointer)&prt_anchor, NULL))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_printer_init, error class init");
      #endif
      return;
   }

   USB_lock();
   prt_call_ptr->code_key = 0;
   prt_call_ptr->code_key = usb_host_class_intf_validate(prt_call_ptr);

   if (NULL == 
         (prt_intf->control_pipe = usb_hostdev_get_pipe_handle 
         (pbs_ptr, USB_CONTROL_PIPE, 0) ))
      goto Bad_Exit;

   if (NULL == 
         (prt_intf->bulk_out_pipe = usb_hostdev_get_pipe_handle 
         (pbs_ptr, USB_BULK_PIPE, USB_SEND) ))
      goto Bad_Exit;

   /* Uni-directional printers don't have a bulk-in pipe */
   if (((INTERFACE_DESCRIPTOR_PTR)prt_intf->intf_handle)->
         bInterfaceSubClass > USB_PROTOCOL_PRT_UNIDIR)
      {
      if (NULL ==
            (prt_intf->bulk_in_pipe = usb_hostdev_get_pipe_handle 
            (pbs_ptr, USB_BULK_PIPE, USB_RECV) ))
         goto Bad_Exit;
      } /* EndIf */

   USB_unlock ();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_init, SUCCESSFUL");
   #endif
   
   return;  /* Good exit, interface struct initialized */

   Bad_Exit:
   USB_mem_zero (prt_intf,sizeof(PRINTER_INTERFACE_STRUCT_PTR));
   prt_call_ptr->class_intf_handle = NULL;
   prt_call_ptr->code_key = 0;
   USB_unlock ();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_init, bad exit");
   #endif
   
} /* Endbody */
                  


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_recv_data
* Returned Value : none
* Comments       :
*     Receive printer data from a bulk-in pipe.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_printer_recv_data 
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR   cc_ptr,
      
      /* [IN] callback upon completion */
      tr_callback             callback,
      
      /* [IN] user parameter returned by callback */
      pointer                 call_parm,
      
      /* [IN] data length */
      uint_32                 buf_size,
      
      /* [IN] buffer pointer */
      uchar_ptr               buffer
   )
{ /* Body */

   TR_INIT_PARAM_STRUCT    tr;
   USB_STATUS              error;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_recv_data");
   #endif

   if (USB_OK != (error = usb_printer_class_verify 
         (cc_ptr, &tr, callback, call_parm)))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_printer_recv_data, error verifying class");
      #endif
      return error;

   }

   tr.G.RX_BUFFER = buffer;
   tr.G.RX_LENGTH = buf_size;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_recv_data, SUCCESSFUL");
   #endif
   return usb_printer_bulk_inout (cc_ptr, &tr, FALSE);   

} /* Endbody */
                  


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_printer_send_data
* Returned Value : none
* Comments       :
*     Send data to a printer through a bulk-out pipe.
* 
*END*--------------------------------------------------------------------*/

USB_STATUS usb_printer_send_data 
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR   cc_ptr,
      
      /* [IN] callback upon completion */
      tr_callback             callback,
      
      /* [IN] user parameter returned by callback */
      pointer                 call_parm,
      
      /* [IN] data length */
      uint_32                 buf_size,
      
      /* [IN] buffer pointer */
      uchar_ptr               buffer
   )
{ /* Body */

  TR_INIT_PARAM_STRUCT  tr;
  USB_STATUS            error;

  #ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_printer_send_data");
  #endif

   if (USB_OK != (error = usb_printer_class_verify 
         (cc_ptr, &tr, callback, call_parm)))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_printer_send_data, error verifying class");
      #endif
      return error;
   }

   tr.G.TX_BUFFER = buffer;
   tr.G.TX_LENGTH = buf_size;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_send_data, SUCCESSFUL");
   #endif

   return usb_printer_bulk_inout (cc_ptr, &tr, TRUE);   

} /* Endbody */
  
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/gflib.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     gflib.h
*	
* @author   r63172
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Master header file for GFLIB library.
*
*******************************************************************************
*
******************************************************************************/

#ifndef _GFLIB_H
#define _GFLIB_H

/******************************************************************************
* Includes
******************************************************************************/
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"

#include "GFLIB_Sin.h"
#include "GFLIB_Cos.h"
#include "GFLIB_Tan.h"
#include "GFLIB_Sqrt.h"
#include "GFLIB_ControllerPIr.h"
#include "GFLIB_ControllerPIp.h"
#include "GFLIB_ControllerPIpAW.h"
#include "GFLIB_Asin.h"
#include "GFLIB_Acos.h"
#include "GFLIB_Atan.h"
#include "GFLIB_AtanYX.h"
#include "GFLIB_Sign.h"
#include "GFLIB_Lut1D.h"
#include "GFLIB_Limit.h"
#include "GFLIB_LowerLimit.h"
#include "GFLIB_UpperLimit.h"
#include "GFLIB_Hyst.h"
#include "GFLIB_IntegratorTR.h"
#include "GFLIB_Ramp.h"
#include "GFLIB_AtanYXShifted.h"

/******************************************************************************
* Constants
******************************************************************************/

/******************************************************************************
* Macros
******************************************************************************/

/******************************************************************************
* Types
******************************************************************************/

/******************************************************************************
* Global variables
******************************************************************************/

/******************************************************************************
* Global functions
******************************************************************************/

/******************************************************************************
* Inline functions
******************************************************************************/

#endif /* _GFLIB_H */



<|start_filename|>Firmware/Inverter_firmware/usb/device/source/include/ehci/ehci_usbprv.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_usbprv.h$
* $Version : 3.8.4.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*  This file contains the private defines, externs and
*  data structure definitions required by the VUSB_HS Device
*  driver.
*                                                               
*END*********************************************************************/

#ifndef __ehci_dev_usbprv_h__
#define __ehci_dev_usbprv_h__ 1

#include "dev_cnfg.h"
#include "ehci_dev_main.h"

#define  MAX_EP_TR_DESCRS                    (32) 
#define  MAX_XDS_FOR_TR_CALLS                (32) 
#define  ZERO_LENGTH                         (0) 
#define  USB_MAX_ENDPOINTS                   (6) 

#define  USB_MAX_CTRL_PAYLOAD                (64)
 
/* Macro for aligning the EP queue head to 32 byte boundary */
#define USB_MEM32_ALIGN(n)                   ((n) + (-(n) & 31))

/* Macro for aligning the EP queue head to 1024 byte boundary */
#define USB_MEM1024_ALIGN(n)                 ((n) + (-(n) & 1023))

/* Macro for aligning the EP queue head to 1024 byte boundary */
#define USB_MEM2048_ALIGN(n)                 ((n) + (-(n) & 2047))

#define EHCI_DTD_QADD(head,tail,dTD)      \
   if ((head) == NULL) {         \
      (head) = (dTD);            \
   } else {                      \
      (tail)->SCRATCH_PTR->PRIVATE = (void *) (dTD);   \
   } /* Endif */                 \
   (tail) = (dTD);               \
   (dTD)->SCRATCH_PTR->PRIVATE = NULL
   
#define EHCI_DTD_QGET(head,tail,dTD)      \
   (dTD) = (head);               \
   if (head) {                   \
      (head) = (head)->SCRATCH_PTR->PRIVATE;  \
      if ((head) == NULL) {      \
         (tail) = NULL;          \
      } /* Endif */              \
   } /* Endif */

/***************************************
**
** Data structures
**
*/

typedef struct ehci_xd_struct 
{
   struct xd_struct G;

   uint_8         MAX_PKTS_PER_UFRAME;
} EHCI_XD_STRUCT, _PTR_ EHCI_XD_STRUCT_PTR;

/* The USB Device State Structure */
typedef struct _usb_ehci_device_state_struct 
{
   USB_DEV_STATE_STRUCT             G;
   void(_CODE_PTR_                  OLDISR_PTR)(pointer);
   pointer                          OLDISR_DATA;

   pointer                          CAP_BASE_PTR;

   boolean                          BUS_RESETTING;       /* Device is being reset */
   boolean                          TRANSFER_PENDING;    /* Transfer pending ? */

   USBHS_EP_QUEUE_HEAD_STRUCT_PTR   EP_QUEUE_HEAD_PTR;   /* Endpoint Queue head */
   uint_8_ptr                       DRIVER_MEMORY;       /* pointer to driver memory*/
   uint_32                          TOTAL_MEMORY;        /* total memory occupied by driver */
   USBHS_EP_QUEUE_HEAD_STRUCT_PTR   EP_QUEUE_HEAD_BASE;
   USBHS_EP_TR_STRUCT_PTR           DTD_BASE_PTR;         /* Device transfer descriptor pool address */
   USBHS_EP_TR_STRUCT_PTR           DTD_ALIGNED_BASE_PTR; /* Aligned transfer descriptor pool address */
   USBHS_EP_TR_STRUCT_PTR           DTD_HEAD;
   USBHS_EP_TR_STRUCT_PTR           DTD_TAIL;
   USBHS_EP_TR_STRUCT_PTR           EP_DTD_HEADS[USB_MAX_ENDPOINTS * 2];
   USBHS_EP_TR_STRUCT_PTR           EP_DTD_TAILS[USB_MAX_ENDPOINTS * 2];
   uint_16                          DTD_ENTRIES;

} USB_EHCI_DEV_STATE_STRUCT, _PTR_ USB_EHCI_DEV_STATE_STRUCT_PTR;

/***************************************
**
** Prototypes
**
*/
#ifdef __cplusplus
extern "C" {
#endif
extern void _usb_dci_usbhs_isr(pointer);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/nat/dnat.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dnat.c$
* $Version : 3.8.4.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the DNAT specific functions.
*
*END************************************************************************/

#include <rtcsrtos.h>
#include <rtcs.h>
#include <rtcs_prv.h>

#if RTCSCFG_ENABLE_NAT

#include "nat.h"
#include "nat_prv.h"

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNAT_lookup_rule
* Returned Value  : RTCS_OK or error code
* Comments        :
*     Lookup all dnat rule from the dnat rule table and return
*     the match for the current port.
*
*END*-----------------------------------------------------------------*/

DNAT_RULE_STRUCT_PTR DNAT_lookup_rule
   (
      NAT_CFG_STRUCT_PTR      nat_cfg_ptr,
      IP_HEADER_PTR           ip_header_ptr,
      boolean                 pub_to_prv
    )
{ /* Body */
   TRANSPORT_UNION            transport;
   DNAT_ELEMENT_STRUCT_PTR    element_ptr;
   _ip_address                source_ip = ntohl(ip_header_ptr->SOURCE);
   _ip_address                target_ip = ntohl(ip_header_ptr->DEST);
   uint_32                    ip_protocol;
   uint_16                    source_port, destination_port; /* source port and destination port */
 
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);
   
   ip_protocol = ntohc(ip_header_ptr->PROTOCOL);

   /* NAT spports ICMP, UDP and TCP transport layer protocols */
   switch (ip_protocol) {
      case IPPROTO_TCP:
          destination_port = ntohs(transport.TCP_PTR->dest_port);
          source_port = ntohs(transport.TCP_PTR->source_port);
          break;
      
      case IPPROTO_UDP:
          destination_port = ntohs(transport.UDP_PTR->DEST_PORT);
          source_port = ntohs(transport.UDP_PTR->SRC_PORT);
          break;
      
      case IPPROTO_ICMP:
          /* Allow all ICMP request/reply */
          return NULL;
   } /* Endswitch */
     
     
   element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE);  

   /*
   ** Check for the target port and then forward the packet to the corresponding 
   ** DNAT rule target ip.
   */
   while (element_ptr != NULL) {
      if (element_ptr->RULE.IP_PROTOCOL == ip_protocol) {
         if (pub_to_prv) {
            if ((destination_port >= element_ptr->RULE.PUBLIC_START_PORT) &&
                (destination_port <= element_ptr->RULE.PUBLIC_END_PORT)) {
               break;
            }
         } else {
            if ((source_ip == element_ptr->RULE.PRIVATE_IP) &&
                (source_port >= element_ptr->RULE.PRIVATE_START_PORT) &&  
                (source_port <= element_ptr->RULE.PRIVATE_END_PORT)) {
               break;  
            }
         }
      }
      element_ptr = (DNAT_ELEMENT_STRUCT_PTR)  _queue_next(&nat_cfg_ptr->RULE_QUEUE, &element_ptr->ELEMENT);
   } /* Endwhile */
   
   if (element_ptr!=NULL) {
      return &element_ptr->RULE;
   } else {
      return NULL;
   }
}/* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNAT_add_rule_internal
* Returned Value  : RTCS_OK or error code
* Parameters     : 
* Comments        : Add rule to internal structures.
*        
*
*END*-----------------------------------------------------------------*/

void DNAT_add_rule_internal
   (
      DNAT_PARM_PTR           dparm_ptr      /* [IN] */   
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR         nat_cfg_ptr = RTCS_getcfg(NAT);
   DNAT_ELEMENT_STRUCT_PTR    new_element_ptr, prev_element_ptr, next_element_ptr;

   if (nat_cfg_ptr == NULL) {
      RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_NOT_INITIALIZED);
      return;
   }

   if (! NAT_is_private_addr(&nat_cfg_ptr->PRIVATE_NETWORKS,dparm_ptr->RULE.PRIVATE_IP)) {
      RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_INVALID_PRIVATE_ADDRESS);
      return;
   }

   if (IP_is_local(NULL, dparm_ptr->RULE.PRIVATE_IP)) {
      RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_INVALID_PRIVATE_ADDRESS);
      return;
   }
        
   prev_element_ptr = NULL;
   next_element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE);  
   
   while ((next_element_ptr != NULL) && 
          (next_element_ptr->RULE.PRIORITY > dparm_ptr->RULE.PRIORITY)) {
      prev_element_ptr = next_element_ptr;
      next_element_ptr = (DNAT_ELEMENT_STRUCT_PTR) 
         _queue_next(&nat_cfg_ptr->RULE_QUEUE, &prev_element_ptr->ELEMENT);
   }
   
   if (next_element_ptr != NULL) {
      if (next_element_ptr->RULE.PRIORITY == dparm_ptr->RULE.PRIORITY) {
         // A rule of the given priority exist
         RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_DUPLICATE_PRIORITY);
         return;
      }
   }

   new_element_ptr = (DNAT_ELEMENT_STRUCT_PTR)_mem_alloc_system_zero(sizeof(DNAT_ELEMENT_STRUCT));

   if (new_element_ptr == NULL) {
      RTCSCMD_complete(dparm_ptr, RTCSERR_OUT_OF_MEMORY);
      return;
   } /* Endif */

   new_element_ptr->RULE    = dparm_ptr->RULE;

   _queue_insert(&nat_cfg_ptr->RULE_QUEUE, &prev_element_ptr->ELEMENT, &new_element_ptr->ELEMENT);    
   RTCSCMD_complete(dparm_ptr, RTCS_OK);
}/* Endbody */
  
  
  
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNAT_delete_rule_internal
* Returned Value  : RTCS_OK or error code
* Comments        : Removes a rule from the dnat rule table.
*
*END*-----------------------------------------------------------------*/

void  DNAT_delete_rule_internal
   (
      DNAT_PARM_PTR           dparm_ptr      /* [IN] */
    )
{ /* Body */   
   NAT_CFG_STRUCT_PTR      nat_cfg_ptr = RTCS_getcfg(NAT);
   DNAT_ELEMENT_STRUCT_PTR element_ptr;
   uint_32                 priority = dparm_ptr->RULE.PRIORITY;

   if (nat_cfg_ptr == NULL) {
      RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_NOT_INITIALIZED);
      return;
   }

   element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE); 

   while (element_ptr != NULL) {
      if (element_ptr->RULE.PRIORITY == priority) {
         _queue_unlink(&nat_cfg_ptr->RULE_QUEUE, &element_ptr->ELEMENT); 
         _mem_free((pointer)element_ptr);
         RTCSCMD_complete(dparm_ptr, RTCS_OK);
         return;
      } 
      element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_next(&nat_cfg_ptr->RULE_QUEUE, &element_ptr->ELEMENT);
   }
   
   RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_INVALID_RULE);
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : DNAT_add_rule_internal
* Returned Value  : RTCS_OK or error code
* Parameters     : 
* Comments        : Add rule to internal structures.
*        
*
*END*-----------------------------------------------------------------*/

void DNAT_get_next_rule_internal
   (
      DNAT_PARM_PTR           dparm_ptr      /* [IN] */   
   )
{ /* Body */
   NAT_CFG_STRUCT_PTR         nat_cfg_ptr = RTCS_getcfg(NAT);
   DNAT_ELEMENT_STRUCT_PTR    prev_element_ptr, next_element_ptr;

   if (nat_cfg_ptr == NULL) {
      RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_NOT_INITIALIZED);
      return;
   }

        
   prev_element_ptr = NULL;
   next_element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE);  
   
   while ((next_element_ptr != NULL) && 
          (next_element_ptr->RULE.PRIORITY >= dparm_ptr->RULE.PRIORITY)) {
      prev_element_ptr = next_element_ptr;
      next_element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_next(&nat_cfg_ptr->RULE_QUEUE, &prev_element_ptr->ELEMENT);
   }
   
   if (next_element_ptr == NULL) {
      RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_END_OF_RULES);
   } else {
      dparm_ptr->RULE    = next_element_ptr->RULE;

      RTCSCMD_complete(dparm_ptr, RTCS_OK);
   }
}/* Endbody */

#endif
  
  
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/kernel/time.c<|end_filename|>
/*HEADER**********************************************************************
 *
 * Copyright (c) 2008 Freescale Semiconductor;
 * All Rights Reserved
 *
 * Copyright (c) 2004-2008 Embedded Access Inc.;
 * All Rights Reserved
 *
 * Copyright (c) 1989-2008 ARC International;
 * All Rights Reserved
 *
 *****************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************
 *
 * $FileName: time.c$
 * $Version : 3.8.1.0$
 * $Date    : Apr-13-2012$
 *
 * Comments:
 *
 *END************************************************************************/

#include "mqx_inc.h"

#include "timer.h"
#include "timer_prv.h"

/*!
 * \brief Add time in days to tick time struct.
 * 
 * The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert units to tick time.
 * 
 * \param[in] tick_ptr Tick time to add to.
 * \param[in] days     The number of days to add.
 * 
 * \return Tick time struct.
 * 
 * \see _time_add_hour_to_ticks
 * \see _time_add_min_to_ticks
 * \see _time_add_sec_to_ticks
 * \see _time_add_msec_to_ticks
 * \see _time_add_usec_to_ticks
 * \see _time_add_nsec_to_ticks
 * \see _time_add_psec_to_ticks
 * \see _mqx_zero_tick_struct 
 */ 
MQX_TICK_STRUCT_PTR _time_add_day_to_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           days
)
{ /* Body */
    MQX_TICK_STRUCT tmp;

    if (days) {
        PSP_DAYS_TO_TICKS(days, &tmp);
        PSP_ADD_TICKS(tick_ptr, &tmp, tick_ptr);
    } /* Endif */

    return tick_ptr;

} /* Endbody */

/*!
 * \brief Add time in hours to tick time struct.
 * 
 * The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert units to tick time.
 * 
 * \param[in] tick_ptr Tick time to add to.
 * \param[in] hours    The number of hours to add.
 * 
 * \return Tick time struct.
 * 
 * \see _time_add_day_to_ticks
 * \see _time_add_min_to_ticks
 * \see _time_add_sec_to_ticks
 * \see _time_add_msec_to_ticks
 * \see _time_add_usec_to_ticks
 * \see _time_add_nsec_to_ticks
 * \see _time_add_psec_to_ticks
 * \see _mqx_zero_tick_struct 
 */ 
MQX_TICK_STRUCT_PTR _time_add_hour_to_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           hours
)
{ /* Body */
    MQX_TICK_STRUCT tmp;

    if (hours) {
        PSP_HOURS_TO_TICKS(hours, &tmp);
        PSP_ADD_TICKS(tick_ptr, &tmp, tick_ptr);
    } /* Endif */

    return tick_ptr;

} /* Endbody */

/*!
 * \brief Add time in minutes to tick time struct.
 * 
 * The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert units to tick time.
 * 
 * \param[in] tick_ptr Tick time to add to.
 * \param[in] minutes  The number of minutes to add.
 * 
 * \return Tick time struct.
 * 
 * \see _time_add_day_to_ticks
 * \see _time_add_hour_to_ticks
 * \see _time_add_sec_to_ticks
 * \see _time_add_msec_to_ticks
 * \see _time_add_usec_to_ticks
 * \see _time_add_nsec_to_ticks
 * \see _time_add_psec_to_ticks
 * \see _mqx_zero_tick_struct 
 */
MQX_TICK_STRUCT_PTR _time_add_min_to_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           minutes
)
{ /* Body */
    MQX_TICK_STRUCT tmp;

    if (minutes) {
        PSP_MINUTES_TO_TICKS(minutes, &tmp);
        PSP_ADD_TICKS(tick_ptr, &tmp, tick_ptr);
    } /* Endif */

    return tick_ptr;

} /* Endbody */

/*!
 * \brief Add time in milliseconds to tick time struct.
 * 
 * The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert units to tick time.
 * 
 * \param[in] tick_ptr Tick time to add to.
 * \param[in] msecs    The number of milliseconds to add.
 * 
 * \return Tick time struct.
 * 
 * \see _time_add_day_to_ticks
 * \see _time_add_hour_to_ticks
 * \see _time_add_min_to_ticks 
 * \see _time_add_sec_to_ticks
 * \see _time_add_usec_to_ticks
 * \see _time_add_nsec_to_ticks
 * \see _time_add_psec_to_ticks
 * \see _mqx_zero_tick_struct 
 */
MQX_TICK_STRUCT_PTR _time_add_msec_to_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           msecs
)
{ /* Body */
    MQX_TICK_STRUCT tmp;

    if (msecs) {
        PSP_MILLISECONDS_TO_TICKS(msecs, &tmp);
        PSP_ADD_TICKS(tick_ptr, &tmp, tick_ptr);
    } /* Endif */

    return tick_ptr;

} /* Endbody */

/*!
 * \brief Add time in nanoseconds to tick time struct.
 * 
 * The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert units to tick time.
 * 
 * \param[in] tick_ptr Tick time to add to.
 * \param[in] nsecs    The number of nanoseconds to add.
 * 
 * \return Tick time struct.
 * 
 * \see _time_add_day_to_ticks
 * \see _time_add_hour_to_ticks
 * \see _time_add_min_to_ticks 
 * \see _time_add_sec_to_ticks
 * \see _time_add_msec_to_ticks 
 * \see _time_add_usec_to_ticks
 * \see _time_add_psec_to_ticks
 * \see _mqx_zero_tick_struct 
 */
MQX_TICK_STRUCT_PTR _time_add_nsec_to_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           nsecs
)
{ /* Body */
    MQX_TICK_STRUCT tmp;

    if (nsecs) {
        PSP_NANOSECONDS_TO_TICKS(nsecs, &tmp);
        PSP_ADD_TICKS(tick_ptr, &tmp, tick_ptr);
    } /* Endif */

    return tick_ptr;

} /* Endbody */

/*!
 * \brief Add time in picoseconds to tick time struct.
 * 
 * The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert units to tick time.
 * 
 * \param[in] tick_ptr Tick time to add to.
 * \param[in] psecs    The number of picoseconds to add.
 * 
 * \return Tick time struct.
 * 
 * \see _time_add_day_to_ticks
 * \see _time_add_hour_to_ticks
 * \see _time_add_min_to_ticks 
 * \see _time_add_sec_to_ticks
 * \see _time_add_msec_to_ticks 
 * \see _time_add_usec_to_ticks
 * \see _time_add_nsec_to_ticks
 * \see _mqx_zero_tick_struct 
 */
MQX_TICK_STRUCT_PTR _time_add_psec_to_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           psecs
)
{ /* Body */
    MQX_TICK_STRUCT tmp;

    if (psecs) {
        PSP_PICOSECONDS_TO_TICKS(psecs, &tmp);
        PSP_ADD_TICKS(tick_ptr, &tmp, tick_ptr);
    } /* Endif */

    return tick_ptr;

} /* Endbody */

/*!
 * \brief Add time in seconds to tick time struct.
 * 
 * The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert units to tick time.
 * 
 * \param[in] tick_ptr Tick time to add to.
 * \param[in] secs     The number of seconds to add.
 * 
 * \return Tick time struct.
 * 
 * \see _time_add_day_to_ticks
 * \see _time_add_hour_to_ticks
 * \see _time_add_min_to_ticks 
 * \see _time_add_msec_to_ticks 
 * \see _time_add_usec_to_ticks
 * \see _time_add_nsec_to_ticks
 * \see _time_add_psec_to_ticks 
 * \see _mqx_zero_tick_struct 
 */
MQX_TICK_STRUCT_PTR _time_add_sec_to_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           secs
)
{ /* Body */
    MQX_TICK_STRUCT tmp;

    if (secs) {
        PSP_SECONDS_TO_TICKS(secs, &tmp);
        PSP_ADD_TICKS(tick_ptr, &tmp, tick_ptr);
    } /* Endif */

    return tick_ptr;

} /* Endbody */

/*!
 * \brief Add time in microseconds to tick time struct.
 * 
 * The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert units to tick time.
 * 
 * \param[in] tick_ptr Tick time to add to.
 * \param[in] usecs    The number of microseconds to add.
 * 
 * \return Tick time struct.
 * 
 * \see _time_add_day_to_ticks
 * \see _time_add_hour_to_ticks
 * \see _time_add_min_to_ticks 
 * \see _time_add_sec_to_ticks 
 * \see _time_add_msec_to_ticks 
 * \see _time_add_nsec_to_ticks
 * \see _time_add_psec_to_ticks 
 * \see _mqx_zero_tick_struct 
 */
MQX_TICK_STRUCT_PTR _time_add_usec_to_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           usecs
)
{ /* Body */
    MQX_TICK_STRUCT tmp;

    if (usecs) {
        PSP_MICROSECONDS_TO_TICKS(usecs, &tmp);
        PSP_ADD_TICKS(tick_ptr, &tmp, tick_ptr);
    } /* Endif */

    return tick_ptr;

} /* Endbody */

#if MQX_HAS_TICK

/*!
 * \brief Suspend the active task for the number of milliseconds.
 * 
 * The functions put the active task in the timeout queue for the specified time.
 * \n Before the time expires, any task can remove the task from the timeout 
 * queue by calling _time_dequeue().
 * 
 * \param[in] milliseconds Minimum number of milliseconds to suspend the task.
 * 
 * \warning Blocks the calling task.
 * 
 * \see _time_delay_for
 * \see _time_delay_ticks
 * \see _time_delay_until
 * \see _time_dequeue 
 */ 
void _time_delay
(
    register uint_32 milliseconds
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TD_STRUCT_PTR td_ptr;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        _usr_time_delay(milliseconds);
        return;
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_time_delay, milliseconds);

    if ( ! milliseconds ) {
        _KLOGX1(KLOG_time_delay);
        return;
    } /* Endif */

    td_ptr = kernel_data->ACTIVE_PTR;

    /* Convert milliseconds to ticks */
    PSP_MILLISECONDS_TO_TICKS_QUICK(milliseconds, &td_ptr->TIMEOUT);

    _INT_DISABLE();

    /* Calculate time to wake up the task */
    PSP_ADD_TICKS(&td_ptr->TIMEOUT, &kernel_data->TIME, &td_ptr->TIMEOUT);

    _time_delay_internal(td_ptr);

    _INT_ENABLE();

    _KLOGX1(KLOG_time_delay);

} /* Endbody */


#if MQX_ENABLE_USER_MODE
/*!
 * \brief Suspend the active task for the number of milliseconds.
 * 
 * This function is equivalent to _time_delay() API call but it can be executed 
 * from within the User task or other code running in the CPU User mode. 
 * Parameters passed to this function by pointer are required to meet the memory 
 * protection requirements as described in the parameter list below.
 * 
 * \param[in] milliseconds Minimum number of milliseconds to suspend the task.
 * 
 * \see _time_delay
 * \see _usr_time_get_elapsed_ticks
 */
void _usr_time_delay
(
    register uint_32 milliseconds
)
{
    MQX_API_CALL_PARAMS params = {milliseconds, 0, 0, 0, 0};
    _mqx_api_call(MQX_API_TIME_DELAY, &params);
}

#endif /* MQX_ENABLE_USER_MODE */
#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Suspend the active task for the number of ticks (in tick time).
 * 
 * The functions put the active task in the timeout queue for the specified time.
 * \n Before the time expires, any task can remove the task from the timeout 
 * queue by calling _time_dequeue().
 * 
 * \param[in] ticks Pointer to the minimum number of ticks to suspend the task.
 * 
 * \warning Blocks the calling task.
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li MQX_INVALID_PARAMETER
 * 
 * \see _time_delay
 * \see _time_delay_ticks
 * \see _time_delay_until
 * \see _time_dequeue 
 */ 
void _time_delay_for
(
    register MQX_TICK_STRUCT_PTR ticks)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TD_STRUCT_PTR td_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_time_delay_for, ticks);

#if MQX_CHECK_ERRORS
    if (ticks == NULL) {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_time_delay_for, MQX_INVALID_PARAMETER);
        return;
    } /* Endif */
#endif

    td_ptr = kernel_data->ACTIVE_PTR;

    _INT_DISABLE();

    /* Calculate time to wake up the task */
    PSP_ADD_TICKS(ticks, &kernel_data->TIME, &td_ptr->TIMEOUT);

    _time_delay_internal(td_ptr);

    _INT_ENABLE();

    _KLOGX1( KLOG_time_delay_for);

} /* Endbody */

#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \private
 *  
 * \brief Suspend the active task for the specified time.
 * 
 * This function puts a task on the timeout queue for the specified number of 
 * ticks, or until removed by another task. Must be called int disabled.
 * 
 * \param[in] td_ptr The task to delay.
 * 
 * \see _time_delay
 * \see _time_delay_for
 * \see _time_delay_ticks
 * \see _time_delay_until 
 */
void _time_delay_internal
   (
      register TD_STRUCT_PTR td_ptr
   )
{ /* Body */
   register KERNEL_DATA_STRUCT_PTR  kernel_data;
   register TD_STRUCT_PTR           td2_ptr;
   register TD_STRUCT_PTR           tdprev_ptr;
   register _mqx_uint               count;
   register _mqx_int                result;
   
   _GET_KERNEL_DATA(kernel_data);

   /* Remove task from ready to run queue */
   tdprev_ptr = (TD_STRUCT_PTR)((pointer)&kernel_data->TIMEOUT_QUEUE);
   if ( _QUEUE_GET_SIZE(&kernel_data->TIMEOUT_QUEUE) ) {

      /* Perform insertion sort by time */
      td2_ptr    = (TD_STRUCT_PTR)((pointer)kernel_data->TIMEOUT_QUEUE.NEXT);

      /* SPR P171-0023-01 use pre-decrement on while loop */
      count      = _QUEUE_GET_SIZE(&kernel_data->TIMEOUT_QUEUE) + 1;
      while ( --count ) {
      /* END SPR */
         result = PSP_CMP_TICKS(&td2_ptr->TIMEOUT, &td_ptr->TIMEOUT);
         if (MQX_DELAY_ENQUEUE_POLICY(result)) {
            /* Enqueue before td2_ptr */
            break;
         } /* Endif */

         tdprev_ptr = td2_ptr;
         td2_ptr    = td2_ptr->TD_NEXT;
      } /* Endwhile */

   } /* Endif */

   /* Remove from ready queue */
   _QUEUE_UNLINK(td_ptr);

   /* Insert into timeout queue */
   _QUEUE_INSERT(&kernel_data->TIMEOUT_QUEUE,tdprev_ptr,td_ptr);

   td_ptr->STATE |= IS_ON_TIMEOUT_Q;

   _sched_execute_scheduler_internal();

} /* Endbody */
#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Suspend the active task for the number of ticks.
 * 
 * The functions put the active task in the timeout queue for the specified time.
 * \n Before the time expires, any task can remove the task from the timeout 
 * queue by calling _time_dequeue().
 * 
 * \param[in] time_in_ticks Minimum number of ticks to suspend the task.
 * 
 * \warning Blocks the calling task.
 * 
 * \see _time_delay
 * \see _time_delay_for
 * \see _time_delay_until
 * \see _time_dequeue 
 */
void _time_delay_ticks
(
    register _mqx_uint time_in_ticks
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TD_STRUCT_PTR td_ptr;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        _usr_time_delay_ticks(time_in_ticks);
        return;
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_time_delay_ticks, time_in_ticks);

    if ( !time_in_ticks ) {
        _KLOGX1(KLOG_time_delay_ticks);
        return;
    } /* Endif */

    td_ptr = kernel_data->ACTIVE_PTR;

    _INT_DISABLE();

    PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->TIME, time_in_ticks, &td_ptr->TIMEOUT);

    _time_delay_internal(td_ptr);

    _INT_ENABLE();
    _KLOGX1(KLOG_time_delay_ticks);

}

#if MQX_ENABLE_USER_MODE
/*!
 * \brief Suspend the active task for the number of ticks.
 * 
 * This function is equivalent to _time_delay_ticks() API call but it can be 
 * executed from within the User task or other code running in the CPU User mode. 
 * Parameters passed to this function by pointer are required to meet the memory 
 * protection requirements as described in the parameter list below.
 * 
 * \param[in] time_in_ticks Minimum number of ticks to suspend the task.
 * 
 * \see _time_delay_ticks
 * \see _usr_time_get_elapsed_ticks
 */
void _usr_time_delay_ticks
(
    register _mqx_uint time_in_ticks
)
{
    MQX_API_CALL_PARAMS params = {(uint_32)time_in_ticks, 0, 0, 0, 0};
    _mqx_api_call(MQX_API_TIME_DELAY_TICKS, &params);
}

#endif /* MQX_ENABLE_USER_MODE */
#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Suspend the active task until the specified time (in tick time).
 * 
 * The functions put the active task in the timeout queue for the specified time.
 * \n Before the time expires, any task can remove the task from the timeout 
 * queue by calling _time_dequeue().
 * 
 * \param[in] ticks Pointer to the time (in tick time) until which to suspend 
 * the task.
 * 
 * \warning Blocks the calling task.
 * \warning On failure, calls _task_set_error() to set the following task error 
 * code:
 * \li MQX_INVALID_PARAMETER
 * 
 * \see _time_delay
 * \see _time_delay_for
 * \see _time_delay_ticks
 * \see _time_dequeue 
 */
void _time_delay_until
(
    register MQX_TICK_STRUCT_PTR ticks
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TD_STRUCT_PTR td_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_time_delay_until, ticks);

#if MQX_CHECK_ERRORS
    if (ticks == NULL) {
        _task_set_error(MQX_INVALID_PARAMETER);
        _KLOGX2(KLOG_time_delay_until, MQX_INVALID_PARAMETER);
        return;
    } /* Endif */
#endif

    td_ptr = kernel_data->ACTIVE_PTR;

    /* Calculate time to wake up the task */
    td_ptr->TIMEOUT = *ticks;

    _INT_DISABLE();

    _time_delay_internal(td_ptr);

    _INT_ENABLE();

    _KLOGX1(KLOG_time_delay_until);

} /* Endbody */

#endif /* MQX_HAS_TICK */

/*!
 * \brief Get the difference between two tick times in days.
 * 
 * If the calculation overflows int_32, the function sets the boolean at 
 * overflow_ptr to TRUE. If this happens, use the _time_diff function for a 
 * larger unit. For example, if _time_diff_hours() sets the overflow, use 
 * _time_diff_days().
 * \n The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert tick time to units.
 * 
 * \param[in]  end_tick_ptr   Pointer to the ending tick time, which must be 
 * greater than the starting tick time.
 * \param[in]  start_tick_ptr Pointer to the starting tick time.
 * \param[out] overflow_ptr   TRUE if overflow occurs (see Description).
 * 
 * \return Difference in days.
 * \return MAX_INT_32 (Failure.)  
 * 
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_seconds
 * \see _time_diff_milliseconds
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds
 * \see _mqx_zero_tick_struct 
 * \see _time_diff
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */ 
int_32 _time_diff_days
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */
    MQX_TICK_STRUCT diff_tick;
    _mqx_uint result;

#if MQX_CHECK_ERRORS
    if (overflow_ptr == NULL) {
        return MAX_INT_32;
    } /* Endif */
#endif

    result = _time_diff_ticks(end_tick_ptr, start_tick_ptr, &diff_tick);

#if MQX_CHECK_ERRORS
    if (result != MQX_OK) {
        return MAX_INT_32;
    } /* Endif */
#endif

    return( PSP_TICKS_TO_DAYS(&diff_tick, overflow_ptr) );

} /* Endbody */

/*!
 * \brief Get the difference between two second/millisecond times.
 * 
 * \param[in]  start_time_ptr Pointer to the normalized start time in 
 * second/millisecond time.
 * \param[in]  end_time_ptr   Pointer to the normalized end time, which must be 
 * greater than the start time.
 * \param[out] diff_time_ptr  Pointer to the time difference (the time is 
 * normalized).
 * 
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_seconds
 * \see _time_diff_milliseconds
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT 
 * \see TIME_STRUCT 
 */
void _time_diff
(
    TIME_STRUCT_PTR start_time_ptr,
    TIME_STRUCT_PTR end_time_ptr,
    TIME_STRUCT_PTR diff_time_ptr
)
{ /* Body */
    TIME_STRUCT temp;

    /*
     * Use temporary variable in case diff_time_ptr is the
     * same as either start or end pointers
     */
    temp.SECONDS = end_time_ptr->SECONDS;
    temp.MILLISECONDS = end_time_ptr->MILLISECONDS;
    if (temp.MILLISECONDS < start_time_ptr->MILLISECONDS) {
        temp.MILLISECONDS += 1000;
        temp.SECONDS--;
    } /* Endif */
    temp.SECONDS -= start_time_ptr->SECONDS;
    temp.MILLISECONDS -= start_time_ptr->MILLISECONDS;

    if (temp.MILLISECONDS > 1000) {
        temp.SECONDS += (temp.MILLISECONDS / 1000);
        temp.MILLISECONDS = temp.MILLISECONDS % 1000;
    } /* Endif */

    *diff_time_ptr = temp;

} /* Endbody */

/*!
 * \brief Get the difference between two tick times.
 * 
 * \param[in]  end_tick_ptr   Pointer to the normalized end time, which must be 
 * greater than the start time.
 * \param[in]  start_tick_ptr Pointer to the normalized start time in tick time.
 * \param[out] diff_tick_ptr  Pointer to the time difference (the time is 
 * normalized).
 * 
 * \return MQX_OK
 * \return MQX_INVALID_PARAMETER (One or more pointers are NULL.) 
 * 
 * \see _time_diff
 * \see _time_diff_ticks_int32 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_seconds
 * \see _time_diff_milliseconds
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT 
 * \see TIME_STRUCT 
 */
_mqx_uint _time_diff_ticks
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    MQX_TICK_STRUCT_PTR diff_tick_ptr
)
{ /* Body */

#if MQX_CHECK_ERRORS
    if ((end_tick_ptr == NULL) || (start_tick_ptr == NULL) ||
                    (diff_tick_ptr == NULL))
    {
        return MQX_INVALID_PARAMETER;
    } /* Endif */
#endif

    PSP_SUB_TICKS(end_tick_ptr, start_tick_ptr, diff_tick_ptr);

    return MQX_OK;

} /* Endbody */

/*!
 * \brief Get the difference between two tick times and clamps result into 
 * int_32 interval.
 * 
 * \param[in]  end_tick_ptr   Pointer to the normalized end time, which must be 
 * greater than the start time.
 * \param[in]  start_tick_ptr Pointer to the normalized start time in tick time.
 * \param[out] overflow_ptr  Set to TRUE if overflow occurs, otherwise FALSE.
 * 
 * \return ticks difference in int32
 * \return MAX_INT_32 (Failure.) 
 * 
 * \see _time_diff
 * \see _time_diff_ticks 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_seconds
 * \see _time_diff_milliseconds
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT 
 * \see TIME_STRUCT 
 */
int_32 _time_diff_ticks_int32
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */

#if MQX_CHECK_ERRORS
    if ((end_tick_ptr == NULL) || (start_tick_ptr == NULL))
    {
        if (overflow_ptr != NULL) *overflow_ptr = TRUE;
        return MAX_INT_32;
    } /* Endif */
#endif

    return (PSP_SUB_TICKS_INT32(end_tick_ptr, start_tick_ptr, overflow_ptr));
} /* Endbody */

/*!
 * \brief Get the difference between two tick times in hours.
 * 
 * If the calculation overflows int_32, the function sets the boolean at 
 * overflow_ptr to TRUE. If this happens, use the _time_diff function for a 
 * larger unit. For example, if _time_diff_hours() sets the overflow, use 
 * _time_diff_days().
 * \n The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert tick time to units.
 * 
 * \param[in]  end_tick_ptr   Pointer to the ending tick time, which must be 
 * greater than the starting tick time.
 * \param[in]  start_tick_ptr Pointer to the starting tick time.
 * \param[out] overflow_ptr   TRUE if overflow occurs (see Description).
 * 
 * \return Difference in hours.  
 * 
 * \see _time_diff_days
 * \see _time_diff_minutes
 * \see _time_diff_seconds
 * \see _time_diff_milliseconds
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds
 * \see _mqx_zero_tick_struct 
 * \see _time_diff
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */
int_32 _time_diff_hours
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */
    MQX_TICK_STRUCT diff_tick;

    _time_diff_ticks(end_tick_ptr, start_tick_ptr, &diff_tick);

    return( PSP_TICKS_TO_HOURS(&diff_tick, overflow_ptr) );

} /* Endbody */

/*!
 * \brief Get the difference between two tick times in minutes.
 * 
 * If the calculation overflows int_32, the function sets the boolean at 
 * overflow_ptr to TRUE. If this happens, use the _time_diff function for a 
 * larger unit. For example, if _time_diff_hours() sets the overflow, use 
 * _time_diff_days().
 * \n The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert tick time to units.
 * 
 * \param[in]  end_tick_ptr   Pointer to the ending tick time, which must be 
 * greater than the starting tick time.
 * \param[in]  start_tick_ptr Pointer to the starting tick time.
 * \param[out] overflow_ptr   TRUE if overflow occurs (see Description).
 * 
 * \return Difference in minutes.  
 * 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_seconds
 * \see _time_diff_milliseconds
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds
 * \see _mqx_zero_tick_struct 
 * \see _time_diff
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */
int_32 _time_diff_minutes
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */
    MQX_TICK_STRUCT diff_tick;

    _time_diff_ticks(end_tick_ptr, start_tick_ptr, &diff_tick);

    return( PSP_TICKS_TO_MINUTES(&diff_tick, overflow_ptr) );

} /* Endbody */

/*!
 * \brief Get the difference between two tick times in milliseconds.
 * 
 * If the calculation overflows int_32, the function sets the boolean at 
 * overflow_ptr to TRUE. If this happens, use the _time_diff function for a 
 * larger unit. For example, if _time_diff_hours() sets the overflow, use 
 * _time_diff_days().
 * \n The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert tick time to units.
 * 
 * \param[in]  end_tick_ptr   Pointer to the ending tick time, which must be 
 * greater than the starting tick time.
 * \param[in]  start_tick_ptr Pointer to the starting tick time.
 * \param[out] overflow_ptr   TRUE if overflow occurs (see Description).
 * 
 * \return Difference in milliseconds.  
 * 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_seconds
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds
 * \see _mqx_zero_tick_struct 
 * \see _time_diff
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */
int_32 _time_diff_milliseconds
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */
    MQX_TICK_STRUCT diff_tick;

    _time_diff_ticks(end_tick_ptr, start_tick_ptr, &diff_tick);

    return( PSP_TICKS_TO_MILLISECONDS(&diff_tick, overflow_ptr) );

} /* Endbody */

/*!
 * \brief Get the difference between two tick times in nanoseconds.
 * 
 * If the calculation overflows int_32, the function sets the boolean at 
 * overflow_ptr to TRUE. If this happens, use the _time_diff function for a 
 * larger unit. For example, if _time_diff_hours() sets the overflow, use 
 * _time_diff_days().
 * \n The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert tick time to units.
 * 
 * \param[in]  end_tick_ptr   Pointer to the ending tick time, which must be 
 * greater than the starting tick time.
 * \param[in]  start_tick_ptr Pointer to the starting tick time.
 * \param[out] overflow_ptr   TRUE if overflow occurs (see Description).
 * 
 * \return Difference in nanoseconds.  
 * 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_seconds
 * \see _time_diff_milliseconds 
 * \see _time_diff_microseconds
 * \see _time_diff_picoseconds
 * \see _mqx_zero_tick_struct 
 * \see _time_diff
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */
int_32 _time_diff_nanoseconds
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */
    MQX_TICK_STRUCT diff_tick;

    _time_diff_ticks(end_tick_ptr, start_tick_ptr, &diff_tick);

    return( PSP_TICKS_TO_NANOSECONDS(&diff_tick, overflow_ptr) );

} /* Endbody */

/*!
 * \brief Get the difference between two tick times in picoseconds.
 * 
 * If the calculation overflows int_32, the function sets the boolean at 
 * overflow_ptr to TRUE. If this happens, use the _time_diff function for a 
 * larger unit. For example, if _time_diff_hours() sets the overflow, use 
 * _time_diff_days().
 * \n The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert tick time to units.
 * 
 * \param[in]  end_tick_ptr   Pointer to the ending tick time, which must be 
 * greater than the starting tick time.
 * \param[in]  start_tick_ptr Pointer to the starting tick time.
 * \param[out] overflow_ptr   TRUE if overflow occurs (see Description).
 * 
 * \return Difference in picoseconds.  
 * 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_seconds
 * \see _time_diff_milliseconds 
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds 
 * \see _mqx_zero_tick_struct 
 * \see _time_diff
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */
int_32 _time_diff_picoseconds
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */
    MQX_TICK_STRUCT diff_tick;

    _time_diff_ticks(end_tick_ptr, start_tick_ptr, &diff_tick);

    return( PSP_TICKS_TO_PICOSECONDS(&diff_tick, overflow_ptr) );

} /* Endbody */

/*!
 * \brief Get the difference between two tick times in seconds.
 * 
 * If the calculation overflows int_32, the function sets the boolean at 
 * overflow_ptr to TRUE. If this happens, use the _time_diff function for a 
 * larger unit. For example, if _time_diff_hours() sets the overflow, use 
 * _time_diff_days().
 * \n The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert tick time to units.
 * 
 * \param[in]  end_tick_ptr   Pointer to the ending tick time, which must be 
 * greater than the starting tick time.
 * \param[in]  start_tick_ptr Pointer to the starting tick time.
 * \param[out] overflow_ptr   TRUE if overflow occurs (see Description).
 * 
 * \return Difference in seconds.  
 * 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_milliseconds 
 * \see _time_diff_microseconds
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds  
 * \see _mqx_zero_tick_struct 
 * \see _time_diff
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */
int_32 _time_diff_seconds
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */
    MQX_TICK_STRUCT diff_tick;

    _time_diff_ticks(end_tick_ptr, start_tick_ptr, &diff_tick);

    return( PSP_TICKS_TO_SECONDS(&diff_tick, overflow_ptr) );

} /* Endbody */

/*!
 * \brief Get the difference between two tick times in microseconds.
 * 
 * If the calculation overflows int_32, the function sets the boolean at 
 * overflow_ptr to TRUE. If this happens, use the _time_diff function for a 
 * larger unit. For example, if _time_diff_hours() sets the overflow, use 
 * _time_diff_days().
 * \n The functions can also be used in conjunction with the global constant 
 * _mqx_zero_tick_struct to convert tick time to units.
 * 
 * \param[in]  end_tick_ptr   Pointer to the ending tick time, which must be 
 * greater than the starting tick time.
 * \param[in]  start_tick_ptr Pointer to the starting tick time.
 * \param[out] overflow_ptr   TRUE if overflow occurs (see Description).
 * 
 * \return Difference in microseconds.  
 * 
 * \see _time_diff_days
 * \see _time_diff_hours
 * \see _time_diff_minutes
 * \see _time_diff_seconds 
 * \see _time_diff_milliseconds 
 * \see _time_diff_nanoseconds
 * \see _time_diff_picoseconds  
 * \see _mqx_zero_tick_struct 
 * \see _time_diff
 * \see _time_diff_ticks
 * \see _time_diff_ticks_int32 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */
int_32 _time_diff_microseconds
(
    MQX_TICK_STRUCT_PTR end_tick_ptr,
    MQX_TICK_STRUCT_PTR start_tick_ptr,
    boolean _PTR_       overflow_ptr
)
{ /* Body */
    MQX_TICK_STRUCT diff_tick;

    _time_diff_ticks(end_tick_ptr, start_tick_ptr, &diff_tick);

    return( PSP_TICKS_TO_MICROSECONDS(&diff_tick, overflow_ptr) );

} /* Endbody */

/*!
 * \brief Removes the task (specified by task ID) from the timeout queue. It 
 * does not reschedule the task.
 * 
 * The function removes from the timeout queue a task that has put itself there 
 * for a period of time (_time_delay()).
 * \n If tid is invalid or represents a task that is on another processor, the 
 * function does nothing.
 * \n A task that calls the function must subsequently put the task in the task's 
 * ready queue with _task_ready().
 * 
 * \param[in] tid Task ID of the task to be removed from the timeout queue.
 * 
 * \warning Removes the task from the timeout queue, but does not put it in the 
 * task's ready queue.
 * 
 * \see _task_ready
 * \see _time_delay
 * \see _time_delay_for
 * \see _time_delay_ticks
 * \see _time_delay_until 
 * \see _time_dequeue_td
 */ 
void _time_dequeue
(
    _task_id tid
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR td_ptr;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_time_dequeue, tid);

    td_ptr = (TD_STRUCT_PTR) _task_get_td(tid);
    if (td_ptr == NULL) {
        _KLOGX1( KLOG_time_dequeue);
        return;
    }/* Endif */

    _int_disable();
    _TIME_DEQUEUE(td_ptr, kernel_data);
    _int_enable();

    _KLOGX1( KLOG_time_dequeue);

} /* Endbody */

/*!
 * \brief Removes the task (specified by task descriptor) from the timeout queue. 
 * It does not reschedule the task.
 * 
 * The function removes from the timeout queue a task that has put itself there 
 * for a period of time (_time_delay()).
 * \n If tid is invalid or represents a task that is on another processor, the 
 * function does nothing.
 * \n A task that calls the function must subsequently put the task in the task's 
 * ready queue with _task_ready().
 * 
 * \param[in] td Pointer to the task descriptor of the task to be removed from 
 * the timeout queue.
 * 
 * \warning Removes the task from the timeout queue, but does not put it in the 
 * task's ready queue.
 * 
 * \see _task_ready
 * \see _time_delay
 * \see _time_delay_for
 * \see _time_delay_ticks
 * \see _time_delay_until 
 * \see _time_dequeue
 */ 
void _time_dequeue_td
(
    pointer td
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR td_ptr = (TD_STRUCT_PTR) td;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_time_dequeue_td, td);

    _int_disable();
    _TIME_DEQUEUE(td_ptr, kernel_data);
    _int_enable();

    _KLOGX1( KLOG_time_dequeue_td);

} /* Endbody */

/*!
 * \brief Gets the number of seconds and milliseconds since the processor 
 * started (without any time offset information).
 * 
 * The function always returns elapsed time; it is not affected by _time_set() 
 * or _time_set_ticks().
 * 
 * \param[in,out] time_ptr Where to store the elapsed normalized second/millisecond.
 * 
 * \see _time_get_elapsed_ticks
 * \see _time_get_elapsed_ticks_fast
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see TIME_STRUCT
 * \see MQX_TICK_STRUCT 
 */ 
void _time_get_elapsed
(
    TIME_STRUCT_PTR time_ptr
)
{ /* Body */
    MQX_TICK_STRUCT tick;

#if MQX_CHECK_ERRORS
    if ( time_ptr == NULL ) {
        return;
    } /* Endif */
#endif

    _time_get_elapsed_ticks(&tick);

    PSP_TICKS_TO_TIME(&tick, time_ptr);

} /* Endbody */

/*!
 * \brief Gets the number of ticks since the processor started (without any time 
 * offset information).
 * 
 * The function always returns elapsed time; it is not affected by _time_set() 
 * or _time_set_ticks().
 * 
 * \param[in,out] tick_ptr Where to store the elapsed tick time.
 * 
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks_fast 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see TIME_STRUCT
 * \see MQX_TICK_STRUCT 
 */ 
void _time_get_elapsed_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;

#if MQX_CHECK_ERRORS
    if ( tick_ptr == NULL ) {
        return;
    }
#endif

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        _usr_time_get_elapsed_ticks(tick_ptr);
        return;
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _INT_DISABLE();

    *tick_ptr = kernel_data->TIME;

    if (kernel_data->GET_HWTICKS) {
        /* The hardware clock may have counted passed it's reference
         * and have an interrupt pending.  Thus, HW_TICKS may exceed
         * kernel_data->HW_TICKS_PER_TICK and this tick_ptr may need
         * normalizing.  This is done in a moment.
         */
        tick_ptr->HW_TICKS = (*kernel_data->GET_HWTICKS)(kernel_data->GET_HWTICKS_PARAM);
    } /* Endif */

    /* The timer ISR may go off and increment kernel_data->TIME */
    _INT_ENABLE();

    /* The tick_ptr->HW_TICKS value might exceed the
     * kernel_data->HW_TICKS_PER_TICK and need to be
     * normalized for the PSP.
     */
    PSP_NORMALIZE_TICKS(tick_ptr);

}

#if MQX_ENABLE_USER_MODE
/*!
 * \brief Gets the number of ticks since the processor started (without any time 
 * offset information).
 * 
 * This function is an equivalent to the _time_get_elapsed_ticks() API call but it 
 * can be executed from within the User task or other code running in the CPU 
 * User mode. Parameters passed to this function by pointer are required to meet 
 * the memory protection requirements as described in the parameter list below.
 * 
 * \param[in,out] tick_ptr Read/write. An address where the time is to be put.
 * 
 * \see _time_get_elapsed_ticks
 * \see _usr_time_delay()
 * \see _usr_time_delay_ticks()
 * \see MQX_TICK_STRUCT
 */ 
void _usr_time_get_elapsed_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr
)
{
    MQX_API_CALL_PARAMS params = {(uint_32)tick_ptr, 0, 0, 0, 0};
    _mqx_api_call(MQX_API_TIME_GET_ELAPSED_TICKS, &params);
}

#endif /* MQX_ENABLE_USER_MODE */

#if MQX_HAS_TICK
/*!
 * \brief Gets the number of ticks since the processor started (without any time 
 * offset information).
 * 
 * The function always returns elapsed time; it is not affected by _time_set() 
 * or _time_set_ticks().
 * \n The only difference between _time_get_elapsed_ticks_fast() and
 * _time_get_elapsed_ticks() is that this one is supposed to be called from code
 * with interrupts DISABLED. Do not use this function with interrupts ENABLED. 
 * 
 * \param[in,out] tick_ptr Where to store the elapsed tick time.
 * 
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see TIME_STRUCT
 * \see MQX_TICK_STRUCT 
 */ 
void _time_get_elapsed_ticks_fast
(
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

#if MQX_CHECK_ERRORS
    if ( tick_ptr == NULL ) {
        return;
    } /* Endif */
#endif

    _GET_KERNEL_DATA(kernel_data);

    *tick_ptr = kernel_data->TIME;

    if (kernel_data->GET_HWTICKS) {
        /* The hardware clock may have counted passed it's reference
         * and have an interrupt pending.  Thus, HW_TICKS may exceed
         * kernel_data->HW_TICKS_PER_TICK and this tick_ptr may need
         * normalizing.  This is done in a moment.
         */
        tick_ptr->HW_TICKS = (*kernel_data->GET_HWTICKS)(kernel_data->GET_HWTICKS_PARAM);
    } /* Endif */

    /* The tick_ptr->HW_TICKS value might exceed the
     * kernel_data->HW_TICKS_PER_TICK and need to be
     * normalized for the PSP.
     */
    PSP_NORMALIZE_TICKS(tick_ptr);

} /* Endbody */
#endif /* MQX_HAS_TICK */

/*!
 * \brief Gets second/millisecond time format from date format.
 * 
 * The function verifies that the fields in the input structure are within the 
 * following ranges.
 * 
 * <table>
 *   <tr>
 *     <td><b>Field</b></td>
 *     <td><b>Minimum</b></td>
 *     <td><b>Maximum</b></td>  
 *   </tr>
 *   <tr>
 *     <td><b>YEAR</b></td>
 *     <td>1970</td>
 *     <td>2099</td>  
 *   </tr>
 *   <tr>
 *     <td><b>MONTH</b></td>
 *     <td>1</td>
 *     <td>12</td>  
 *   </tr>
 *   <tr>
 *     <td><b>DAY</b></td>
 *     <td>1</td>
 *     <td>31 (Depending on the month.)</td>  
 *   </tr>
 *   <tr>
 *     <td><b>HOUR</b></td>
 *     <td>0</td>
 *     <td>23 (Since midnight.)</td>  
 *   </tr>
 *   <tr>
 *     <td><b>MINUTE</b></td>
 *     <td>0</td>
 *     <td>59</td>  
 *   </tr>
 *   <tr>
 *     <td><b>SECOND</b></td>
 *     <td>0</td>
 *     <td>59</td>  
 *   </tr>
 *   <tr>
 *     <td><b>MILLISEC</b></td>
 *     <td>0</td>
 *     <td>999</td>  
 *   </tr>        
 * </table>
 * 
 * The function converts the fields in the input structure to the fields in the 
 * output structure, taking into account leap years.
 * \n The time is since 0:00:00.00, January 1, 1970.
 * 
 * \param[in]  time_ptr Pointer to a date and time structure.
 * \param[out] ts_ptr   Pointer to a normalized second/millisecond time structure.
 * 
 * \return TRUE (Success), FALSE (Fields in time_ptr are out of range or 
 * time_ptr or ts_ptr are NULL).
 * 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see _time_to_date
 * \see _time_xdate_to_ticks
 * \see DATE_STRUCT
 * \see TIME_STRUCT    
 */ 
boolean _time_from_date
(
    DATE_STRUCT_PTR time_ptr,
    TIME_STRUCT_PTR ts_ptr
)
{ /* Body */
    uint_32 time;
    _mqx_uint leap;

    /* Validate each of the parameters before doing time conversion. */

#if MQX_CHECK_ERRORS
    if ((time_ptr == NULL) || (ts_ptr == NULL)) {
        return (FALSE);
    } /* Endif */
#endif

    if (time_ptr->MILLISEC >= (uint_16) MILLISECS_IN_SECOND) {
        time_ptr->SECOND += (time_ptr->MILLISEC / (uint_16) MILLISECS_IN_SECOND);
        time_ptr->MILLISEC = (time_ptr->MILLISEC % (uint_16) MILLISECS_IN_SECOND);
    } /* Endif */

    if (time_ptr->SECOND >= (uint_16) SECS_IN_MINUTE) {
        time_ptr->MINUTE += (time_ptr->SECOND / (uint_16) SECS_IN_MINUTE);
        time_ptr->SECOND = (time_ptr->SECOND % (uint_16) SECS_IN_MINUTE);
    } /* Endif */

    if (time_ptr->MINUTE >= (uint_16) MINUTES_IN_HOUR) {
        time_ptr->HOUR += (time_ptr->MINUTE / (uint_16) 60);
        time_ptr->MINUTE = (time_ptr->MINUTE % (uint_16) 60);
    } /* Endif */

    if (time_ptr->HOUR >= (uint_16) HOURS_IN_DAY) {
        time_ptr->DAY += (time_ptr->HOUR / (uint_16) HOURS_IN_DAY);
        time_ptr->HOUR = (time_ptr->HOUR % (uint_16) HOURS_IN_DAY);
    } /* Endif */

    if (time_ptr->DAY < 1) {
        return (FALSE);
    } /* Endif */

    if (time_ptr->MONTH > (uint_16) MONTHS_IN_YEAR) {
        time_ptr->YEAR += (time_ptr->MONTH / (uint_16) MONTHS_IN_YEAR);
        time_ptr->MONTH = (time_ptr->MONTH % (uint_16) MONTHS_IN_YEAR);
    } /* Endif */

    if (time_ptr->YEAR < (uint_16) CLK_FIRST_YEAR) {
        time_ptr->YEAR = (uint_16) CLK_FIRST_YEAR;
    } /* Endif */

    while (1) {

        /* Find out if we are in a leap year. */
        leap = (_mqx_uint) _time_check_if_leap(time_ptr->YEAR);

        if (time_ptr->DAY > (uint_16) _time_days_in_month_internal[leap][time_ptr->MONTH]) {
            time_ptr->DAY -= (uint_16) _time_days_in_month_internal[leap][time_ptr->MONTH];
            time_ptr->MONTH++;
        }
        else {
            break;
        } /* Endif */

        if (time_ptr->MONTH > (uint_16) MONTHS_IN_YEAR) {
            time_ptr->YEAR += (time_ptr->MONTH / (uint_16) MONTHS_IN_YEAR);
            time_ptr->MONTH = (time_ptr->MONTH % (uint_16) MONTHS_IN_YEAR);
        } /* Endif */

    } /* Endwhile */

    if (time_ptr->YEAR > (uint_16) CLK_LAST_YEAR) {
        return (FALSE);
    } /* Endif */

    /*
     * Determine the number of seconds since Jan 1, 1970 at 00:00:00
     */
    time = _time_secs_before_year_internal[time_ptr->YEAR - (uint_16) CLK_FIRST_YEAR];

    /*
     * Add the number of seconds_ptr since 0000 hours, Jan 1, to the first
     * day of month.
     */
    time += _time_secs_before_month_internal[leap][time_ptr->MONTH - 1];

    /*
     * Add the number of seconds in the days since the beginning of the
     * month
     */
    time += ((uint_32) time_ptr->DAY - 1) * SECS_IN_DAY;

    /*
     * Add the number of seconds in the hours since midnight
     */
    time += (uint_32) time_ptr->HOUR * SECS_IN_HOUR;

    /*
     * Add the number of seconds in the minutes since the hour
     */
    time += (uint_32) time_ptr->MINUTE * 60;

    /*
     * add the number of seconds since the beginning of the minute
     */
    time += (uint_32) time_ptr->SECOND;

    /*
     * assign the times
     */
    ts_ptr->SECONDS = time;
    ts_ptr->MILLISECONDS = (uint_32) time_ptr->MILLISEC;

    return (TRUE);

} /* Endbody */

/*!
 * \brief Get the absolute time in second/millisecond time.
 * 
 * If the application changed the absolute time with _time_set() (or 
 * _time_set_ticks()), _time_get() (or _time_get_ticks()) returns the time that 
 * was set plus the number of seconds and milliseconds (or ticks) since the time 
 * was set.
 * \n If the application has not changed the absolute time with _time_set() (or 
 * _time_set_ticks()), _time_get() (or _time_get_ticks()) returns the same as 
 * _time_get_elapsed() (or _time_get_elapsed_ticks()), which is the number of 
 * seconds and milliseconds (or ticks) since MQX started.
 * 
 * \param[in,out] time_ptr Where to store the normalized absolute time in 
 * second/millisecond time.
 * 
 * \see _time_get_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT
 * \see TIME_STRUCT 
 */ 
void _time_get
(
    register TIME_STRUCT_PTR time_ptr
)
{ /* Body */

    MQX_TICK_STRUCT ticks;

    _time_get_ticks(&ticks);

    PSP_TICKS_TO_TIME(&ticks, time_ptr);

} /* Endbody */

#if MQX_HAS_HW_TICKS
/*!
 * \brief Gets the number of hardware ticks since the last tick.
 * 
 * \return Number of hardware ticks since the last tick. (Success.)
 * \return 0 (Failure.)
 * 
 * \see _time_get_hwticks_per_tick
 * \see _time_set_hwticks_per_tick  
 */ 
uint_32 _time_get_hwticks
(
    void
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    if (kernel_data->GET_HWTICKS) {
        return (*kernel_data->GET_HWTICKS)(kernel_data->GET_HWTICKS_PARAM);
    } /* Endif */

    return 0;

} /* Endbody */
#endif /* MQX_HAS_HW_TICKS */

/*!
 * \brief Gets the calculated number of nanoseconds since the last periodic 
 * timer interrupt.
 * 
 * \return Number of nanoseconds since the last periodic timer interrupt.
 * \return 0 (BSP does not support the feature).
 * 
 * \warning Resolution depends on the periodic timer device.
 * 
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks   
 */ 
uint_32 _time_get_nanoseconds
(
    void
)
{
    uint_32 hwticks;
    uint_32 tickper;

    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    if (kernel_data->GET_HWTICKS == NULL) return 0; /* BSP does not support HW ticks */

    hwticks = (*kernel_data->GET_HWTICKS)(kernel_data->GET_HWTICKS_PARAM);

    /* Tick period in time units (ns) */
    tickper = 1000000000 / kernel_data->TICKS_PER_SECOND; /* 32 bit div */

    /* The result fits in 32 bits */
    return (uint_32)(((uint_64) hwticks * tickper) / kernel_data->HW_TICKS_PER_TICK); /* 64 bit mul and div */
}

#if MQX_HAS_TICK
/*!
 * \brief Gets the timer frequency (in ticks per second) that MQX uses.
 * 
 * \warning If the timer frequency does not correspond with the interrupt period 
 * that was programmed at the hardware level, some timing functions will give 
 * incorrect results.
 * 
 * \return Period of clock interrupt in ticks per second.
 * 
 * \see _time_set_ticks_per_sec 
 */ 
_mqx_uint _time_get_ticks_per_sec
(
    void
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    return( kernel_data->TICKS_PER_SECOND );

} /* Endbody */
#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Gets the resolution of the periodic timer interrupt.
 * 
 * On each clock interrupt, MQX increments time by the resolution.
 * 
 * \return Resolution of the periodic timer interrupt in milliseconds.
 * 
 * \see _time_set_resolution
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see TIME_STRUCT  
 */ 
_mqx_uint _time_get_resolution
(
    void
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register _mqx_uint result;

    _GET_KERNEL_DATA(kernel_data);

    result = kernel_data->TICKS_PER_SECOND;

    return( MILLISECS_IN_SECOND / result );

} /* Endbody */
#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Get the absolute time in tick time.
 * 
 * If the application changed the absolute time with _time_set_ticks() (or 
 * _time_set()), _time_get_ticks() (or _time_get()) returns the time that was 
 * set plus the number of ticks (seconds and milliseconds) since the time was 
 * set.
 * \n If the application has not changed the absolute time with 
 * _time_set_ticks() (or _time_set()), _time_get_ticks() (or _time_get()) 
 * returns the same as _time_get_elapsed_ticks() (or _time_get_elapsed()), which
 * is the number of seconds and milliseconds (or ticks) since MQX started.
 * 
 * \param[in,out] tick_ptr Where to store the absolute time in tick time.
 * 
 * \see _time_get
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT
 * \see TIME_STRUCT
 */ 
void _time_get_ticks
(
    register MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

#if MQX_CHECK_ERRORS
    if ( tick_ptr == NULL ) {
        return;
    } /* Endif */
#endif

    _GET_KERNEL_DATA(kernel_data);

    _INT_DISABLE();

    *tick_ptr = kernel_data->TIME;

    /* The hardware clock keeps counting... */

    if (kernel_data->GET_HWTICKS) {
        /* The hardware clock may have counted passed it's reference
         * and have an interrupt pending.  Thus, HW_TICKS may exceed
         * kernel_data->HW_TICKS_PER_TICK and this tick_ptr may need
         * normalizing.  This is done in a moment.
         */
        tick_ptr->HW_TICKS = (*kernel_data->GET_HWTICKS)(kernel_data->GET_HWTICKS_PARAM);
    } /* Endif */

    PSP_ADD_TICKS(tick_ptr, &kernel_data->TIME_OFFSET, tick_ptr);

    /* The timer ISR may go off and increment kernel_data->TIME */
    _INT_ENABLE();

    /* The tick_ptr->HW_TICKS value might exceed the
     * kernel_data->HW_TICKS_PER_TICK and need to be
     * normalized for the PSP.
     */
    PSP_NORMALIZE_TICKS(tick_ptr);

} /* Endbody */
#endif /* MQX_HAS_TICK */

/*!
 * \brief Gets the calculated number of microseconds since the last periodic 
 * timer interrupt.
 * 
 * \return Number of microseconds since the last periodic timer interrupt.
 * \return 0 (BSP does not support the feature.)
 * 
 * \warning Resolution depends on the periodic timer device.
 * 
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set_
 * \see _time_set_ticks
 */ 
uint_16 _time_get_microseconds
(
    void
)
{
    uint_32 hwticks;
    uint_32 tickper;

    KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    /* BSP does not support HW ticks */
    if (kernel_data->GET_HWTICKS == NULL) return 0;

    hwticks = (*kernel_data->GET_HWTICKS)(kernel_data->GET_HWTICKS_PARAM);

    /* Tick period in time units (us) */
    tickper = 1000000 / kernel_data->TICKS_PER_SECOND; /* 32bit div */

    /* The result shall fit into 16 bits */
    return (uint_16)((hwticks * tickper) / kernel_data->HW_TICKS_PER_TICK); /* 32bit mul and div */
}

#if MQX_HAS_HW_TICKS
/*!
 * \brief Gets the number of hardware ticks per tick.
 * 
 * \return Number of hardware ticks per tick.
 * 
 * \see _time_set_hwticks_per_tick
 * \see _time_get_hwticks 
 */ 
uint_32 _time_get_hwticks_per_tick
(
    void
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    return kernel_data->HW_TICKS_PER_TICK;

} /* Endbody */
#endif /* MQX_HAS_HW_TICKS */

/*!
 * \brief Initializes a tick time structure with the number of ticks.
 * 
 * \param[out] tick_ptr Pointer to the tick time structure to initialize.
 * \param[in]  ticks    Number of ticks with which to initialize the structure.
 * 
 * \return MQX_OK
 * \return MQX_INVALID_PARAMETER (Tick_ptr is NULL.)
 * 
 * \see _time_ticks_to_xdate
 * \see _time_set
 * \see _time_set_ticks
 * \see MQX_TICK_STRUCT  
 */ 
_mqx_uint _time_init_ticks
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    _mqx_uint           ticks
)
{ /* Body */

#if MQX_CHECK_ERRORS
    if (tick_ptr == NULL) {
        return MQX_INVALID_PARAMETER;
    } /* Endif */
#endif

    if (ticks) {
        tick_ptr->HW_TICKS = 0;
        PSP_ADD_TICKS_TO_TICK_STRUCT(&_mqx_zero_tick_struct, ticks, tick_ptr);
    }
    else {
        *tick_ptr = _mqx_zero_tick_struct;
    } /* Endif */

    return MQX_OK;

} /* Endbody */

#if MQX_HAS_TICK
/*!
 * \brief The BSP periodic timer ISR calls the function when a periodic timer 
 * interrupt occurs.
 * 
 * The BSP installs an ISR for the periodic timer interrupt. The ISR calls 
 * _time_notify_kernel(), which does the following:
 * \li Increments kernel time.
 * \li If the active task is a time slice task whose time slice has expired, 
 * puts it at the end of the task's ready queue.
 * \li If the timeout has expired for tasks on the timeout queue, puts them in 
 * their ready queues.
 * \n If the BSP does not have periodic timer interrupts, MQX components that 
 * use time will not operate.
 * 
 * \warning See Description.
 * 
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set  
 * \see _time_set_ticks
 * \see TIME_STRUCT
 */ 
void _time_notify_kernel
(
    void
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    register TD_STRUCT_PTR td_ptr;
    register TD_STRUCT_PTR next_td_ptr;
    register _mqx_uint count;
    register _mqx_int result;

    _GET_KERNEL_DATA(kernel_data);

    /*
     * Update the current time.
     */
    PSP_INC_TICKS(&kernel_data->TIME);

    _INT_DISABLE();

    if (kernel_data->GET_HWTICKS) {
        /* The hardware clock may have counted passed it's reference
         * and have an interrupt pending.  Thus, HW_TICKS may exceed
         * kernel_data->HW_TICKS_PER_TICK and this tick_ptr may need
         * normalizing.  This is done in a moment.
         */
        kernel_data->TIME.HW_TICKS = (*kernel_data->GET_HWTICKS)(kernel_data->GET_HWTICKS_PARAM);
    } /* Endif */

    /* The tick_ptr->HW_TICKS value might exceed the
     * kernel_data->HW_TICKS_PER_TICK and need to be
     * normalized for the PSP.
     */
    PSP_NORMALIZE_TICKS(&kernel_data->TIME);

    /*
     * Check for tasks on the timeout queue, and wake the appropriate
     * ones up.  The timeout queue is a time-priority queue.
     */
    count = _QUEUE_GET_SIZE(&kernel_data->TIMEOUT_QUEUE);
    if (count) {
        td_ptr = (TD_STRUCT_PTR)((pointer) kernel_data->TIMEOUT_QUEUE.NEXT);
        ++count;
        while (--count) {
            next_td_ptr = td_ptr->TD_NEXT;
            result = PSP_CMP_TICKS(&kernel_data->TIME, &td_ptr->TIMEOUT);
            if (result >= 0) {
                --kernel_data->TIMEOUT_QUEUE.SIZE;
                _QUEUE_UNLINK(td_ptr);
                td_ptr->STATE &= ~IS_ON_TIMEOUT_Q;
                if (td_ptr->STATE & TD_IS_ON_AUX_QUEUE) {
                    td_ptr->STATE &= ~TD_IS_ON_AUX_QUEUE;
                    _QUEUE_REMOVE(td_ptr->INFO, &td_ptr->AUX_QUEUE);
                } /* Endif */
                _TASK_READY(td_ptr, kernel_data);
            }
            else {
                break; /* No more to do */
            } /* Endif */
            td_ptr = next_td_ptr;
        } /* Endwhile */
    } /* Endif */

#if MQX_HAS_TIME_SLICE
    /*
     * Check if the currently running task is a time slice task
     * and if its time has expired, put it at the end of its queue
     */
    td_ptr = kernel_data->ACTIVE_PTR;
    if ( td_ptr->FLAGS & MQX_TIME_SLICE_TASK ) {
        PSP_INC_TICKS(&td_ptr->CURRENT_TIME_SLICE);
        if (! (td_ptr->FLAGS & TASK_PREEMPTION_DISABLED) ) {
            result = PSP_CMP_TICKS(&td_ptr->CURRENT_TIME_SLICE, &td_ptr->TIME_SLICE);
            if ( result >= 0 ) {
                _QUEUE_UNLINK(td_ptr);
                _TASK_READY(td_ptr,kernel_data);
            } /* Endif */
        } /* Endif */
    } /* Endif */
#endif

    _INT_ENABLE();
#if MQX_USE_TIMER
    /* If the timer component needs servicing, call its ISR function */
    if (kernel_data->TIMER_COMPONENT_ISR != NULL) {
        (*kernel_data->TIMER_COMPONENT_ISR)();
    }/* Endif */
#endif

#if MQX_USE_LWTIMER
    /* If the lwtimer needs servicing, call its ISR function */
    if (kernel_data->LWTIMER_ISR != NULL) {
        (*kernel_data->LWTIMER_ISR)();
    }/* Endif */
#endif

} /* Endbody */

#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Set the absolute time in second/millisecond time. The input time is
 * the UCT time.
 * 
 * The function affects _time_get() (and _time_get_ticks()), but does not affect 
 * time _time_get_elapsed() (or _time_get_elapsed_ticks()).
 * 
 * \param[in] time_ptr Pointer to a structure that contains the new normalized 
 * time in second/millisecond time.  
 * 
 * \see _time_set_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_to_date
 * \see _time_init_ticks
 * \see _time_to_ticks
 * \see _time_from_date
 * \see TIME_STRUCT
 * \see MQX_TICK_TIME
 */ 
void _time_set
(
    register TIME_STRUCT_PTR time_ptr
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;
    MQX_TICK_STRUCT ticks;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE4(KLOG_time_set, time_ptr, time_ptr->SECONDS, time_ptr->MILLISECONDS);

    /* Normalize time */
    MQX_NORMALIZE_TIME_STRUCT(time_ptr);

    /* First convert old time struct into the tick struct */
    PSP_TIME_TO_TICKS(time_ptr, &ticks);

    _INT_DISABLE();

    /* Calculate offset */
    PSP_SUB_TICKS(&ticks, &kernel_data->TIME, &kernel_data->TIME_OFFSET);

    _INT_ENABLE();

    _KLOGX1(KLOG_time_set);

} /* Endbody */
#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Set the absolute time in tick time. The input time is the UCT time.
 * 
 * The function affects _time_get_ticks() (and _time_get()), but does not affect 
 * time _time_get_elapsed_ticks() (or _time_get_elapsed()).
 * 
 * \param[in] ticks Pointer to the structure that contains the new time in tick 
 * time.  
 * 
 * \see _time_set
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_to_date
 * \see _time_init_ticks
 * \see _time_to_ticks
 * \see _time_from_date
 * \see TIME_STRUCT
 * \see MQX_TICK_TIME
 */ 
void _time_set_ticks
(
    register MQX_TICK_STRUCT_PTR ticks
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_time_set_ticks, ticks);

    _INT_DISABLE();

    PSP_SUB_TICKS(ticks, &kernel_data->TIME, &kernel_data->TIME_OFFSET);

    _INT_ENABLE();

    _KLOGX1(KLOG_time_set_ticks);

} /* Endbody */
#endif /* MQX_HAS_TICK */

/*!
 * \brief Determines whether given year is a leap year.
 * 
 * \param[in] year The year to check.
 * 
 * \return TRUE (Year is a leap year.), FALSE (Year is not a leap year.) 
 */ 
boolean _time_check_if_leap
(
    uint_16 year
)
{ /* Body */
    boolean leap;

    /*
     * If the year is a century year not divisible by 400
     * then it is not a leap year, otherwise if year divisible by
     * four then it is a leap year
     */
    if (year % (uint_16) 100 == (uint_16) 0) {

        if (year % (uint_16) 400 == (uint_16) 0) {
            leap = TRUE;
        }
        else {
            leap = FALSE;
        } /* Endif */

    }
    else {

        if (year % (uint_16) 4 == (uint_16) 0) {
            leap = TRUE;
        }
        else {
            leap = FALSE;
        } /* Endif */

    } /* Endif */

    return leap;
} /* Endbody */

/*!
 * \brief Normalizes the extended date structure.
 * 
 * \param[in,out] xdate_ptr Pointer to the extended date structure.
 * 
 * \return TRUE (Success), FALSE (Failure: input year is earlier than 1970 or 
 * output year is later than 2481).
 * 
 * \see _time_xdate_to_ticks 
 */ 
boolean _time_normalize_xdate
(
    MQX_XDATE_STRUCT_PTR xdate_ptr
)
{ /* Body */
    _mqx_uint leap;

    if (xdate_ptr->YEAR < (_mqx_uint) XCLK_FIRST_YEAR) {
        return FALSE;
    } /* Endif */

    if (xdate_ptr->PSEC >= PICOSECS_IN_NANOSECOND) {
        xdate_ptr->NSEC += xdate_ptr->PSEC / PICOSECS_IN_NANOSECOND;
        xdate_ptr->PSEC = xdate_ptr->PSEC % PICOSECS_IN_NANOSECOND;
    } /* Endif */

    if (xdate_ptr->NSEC >= NANOSECS_IN_MICROSECOND) {
        xdate_ptr->USEC += xdate_ptr->NSEC / NANOSECS_IN_MICROSECOND;
        xdate_ptr->NSEC = xdate_ptr->NSEC % NANOSECS_IN_MICROSECOND;
    } /* Endif */

    if (xdate_ptr->USEC >= MICROSECS_IN_MILLISECOND) {
        xdate_ptr->MSEC += xdate_ptr->USEC / MICROSECS_IN_MILLISECOND;
        xdate_ptr->USEC = xdate_ptr->USEC % MICROSECS_IN_MILLISECOND;
    } /* Endif */

    if (xdate_ptr->MSEC >= MILLISECS_IN_SECOND) {
        xdate_ptr->SEC += xdate_ptr->MSEC / MILLISECS_IN_SECOND;
        xdate_ptr->MSEC = xdate_ptr->MSEC % MILLISECS_IN_SECOND;
    } /* Endif */

    if (xdate_ptr->SEC >= SECS_IN_MINUTE) {
        xdate_ptr->MIN += xdate_ptr->SEC / SECS_IN_MINUTE;
        xdate_ptr->SEC = xdate_ptr->SEC % SECS_IN_MINUTE;
    } /* Endif */

    if (xdate_ptr->MIN >= MINUTES_IN_HOUR) {
        xdate_ptr->HOUR += xdate_ptr->MIN / MINUTES_IN_HOUR;
        xdate_ptr->MIN = xdate_ptr->MIN % MINUTES_IN_HOUR;
    } /* Endif */

    if (xdate_ptr->HOUR >= HOURS_IN_DAY) {
        xdate_ptr->MDAY += xdate_ptr->HOUR / HOURS_IN_DAY;
        xdate_ptr->HOUR = xdate_ptr->HOUR % HOURS_IN_DAY;
    } /* Endif */

    if (xdate_ptr->MONTH > MONTHS_IN_YEAR) {
        /* Months range from 1 to 12 */
        xdate_ptr->YEAR += (xdate_ptr->MONTH - 1) / MONTHS_IN_YEAR;
        xdate_ptr->MONTH = (xdate_ptr->MONTH - 1) % MONTHS_IN_YEAR + 1;
    } /* Endif */

    while (1) {

        leap = (_mqx_uint) _time_check_if_leap(xdate_ptr->YEAR);

        if (xdate_ptr->MDAY > _time_days_in_month_internal[leap][xdate_ptr->MONTH]) {
            xdate_ptr->MDAY -= _time_days_in_month_internal[leap][xdate_ptr->MONTH];
            xdate_ptr->MONTH++;
        }
        else {
            break;
        } /* Endif */

        if (xdate_ptr->MONTH > MONTHS_IN_YEAR) {
            xdate_ptr->YEAR += (xdate_ptr->MONTH / MONTHS_IN_YEAR);
            xdate_ptr->MONTH = (xdate_ptr->MONTH % MONTHS_IN_YEAR);
        } /* Endif */

    } /* Endwhile */

    if (xdate_ptr->YEAR > XCLK_LAST_YEAR) {
        return (FALSE);
    } /* Endif */

    return TRUE;

} /* Endbody */

#if MQX_HAS_TICK
/*!
 * \brief Sets the resolution of the periodic timer interrupt.
 * 
 * On each clock interrupt, MQX increments time by the resolution.
 * 
 * \warning If the resolution does not agree with the interrupt period that was
 * programmed at the hardware level, some timing functions will give incorrect 
 * results.
 * 
 * \param[in] resolution Periodic timer resolution (in milliseconds) to be used 
 * by MQX.
 * 
 * \return MQX_OK
 *  
 * \see _time_get_resolution
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see TIME_STRUCT
 */ 
_mqx_uint _time_set_resolution
(
    _mqx_uint resolution
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    /*
     * Convert resolution into ticks per second so new tick format will
     * work
     */
    kernel_data->TICKS_PER_SECOND = 1000 / resolution;

    /* Also set hw ticks per tick */
    kernel_data->HW_TICKS_PER_TICK = resolution * 1000;

    kernel_data->GET_HWTICKS = (MQX_GET_HWTICKS_FPTR)_time_get_microseconds;

    return MQX_OK;

} /* Endbody */
#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Sets the timer frequency (in ticks per second) that MQX uses.
 * 
 * \param[in] ticks_per_sec New timer frequency in ticks per second. 
 * 
 * \warning If the timer frequency does not agree with the interrupt period that 
 * was programmed at the hardware level, some timing functions will give 
 * incorrect results.
 *  
 * \see _time_get_ticks_per_sec
 */ 
void _time_set_ticks_per_sec
(
    _mqx_uint ticks_per_sec
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    kernel_data->TICKS_PER_SECOND = ticks_per_sec;

} /* Endbody */

#endif /* MQX_HAS_TICK */

#if MQX_HAS_TICK
/*!
 * \brief Sets the internal periodic timer interrupt vector number that MQX uses.
 * 
 * The BSP should call the function during initialization.
 *  
 * \param[in] vector Periodic timer interrupt vector to use.
 * 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_get_resolution
 * \see _time_set_resolution 
 */ 
void _time_set_timer_vector
(
    _mqx_uint vector
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);
    kernel_data->SYSTEM_CLOCK_INT_NUMBER = vector;

} /* Endbody */
#endif /* MQX_HAS_TICK */

#if MQX_HAS_HW_TICKS
/*!
 * \brief Sets the fields in kernel data to get the hardware ticks.
 * 
 * \param[in] hwtick_function_ptr Pointer to the function that returns hw tick, 
 * to be executed by the kernel.
 * \param[in] parameter           Parameter of the function that returns hw tick.
 */ 
void _time_set_hwtick_function
(
    MQX_GET_HWTICKS_FPTR hwtick_function_ptr,
    pointer              parameter
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    kernel_data->GET_HWTICKS = hwtick_function_ptr;
    kernel_data->GET_HWTICKS_PARAM = parameter;

} /* Endbody */
#endif /* MQX_HAS_HW_TICKS */

#if MQX_HAS_HW_TICKS
/*!
 * \brief Sets the number of hardware ticks per tick.
 * 
 * \param[in] new_val New number of hardware ticks per tick.
 * 
 * \see _time_get_hwticks_per_tick
 * \see _time_get_hwticks
 */ 
void _time_set_hwticks_per_tick
(
    uint_32 new_val
)
{ /* Body */
    register KERNEL_DATA_STRUCT_PTR kernel_data;

    _GET_KERNEL_DATA(kernel_data);

    kernel_data->HW_TICKS_PER_TICK = new_val;

} /* Endbody */

#endif /* MQX_HAS_HW_TICKS */

/*!
 * \brief Converts tick time format to extended date format.
 * 
 * The function verifies that the fields in the input structure are within the 
 * following ranges.
 * <table>
 *   <tr>
 *     <td><b>Field</b></td>
 *     <td><b>Minimum</b></td>
 *     <td><b>Maximum</b></td>  
 *   </tr>
 *   <tr>
 *     <td><b>TICKS</b></td>
 *     <td>0</td>
 *     <td>(2^64)-1</td>  
 *   </tr>
 *   <tr>
 *     <td><b>HW_TICKS</b></td>
 *     <td>0</td>
 *     <td>(2^32)-1</td>  
 *   </tr>     
 * </table>
 * 
 * The function converts the fields in the input structure to the fields in the 
 * output structure, taking into account leap years.
 * \n The time is since 0:00:00.00, January 1, 1970.
 * 
 * \param[in]  tick_ptr  Pointer to a tick structure.
 * \param[out] xdate_ptr Pointer to the corresponding normalized extended date 
 * format.
 * 
 * \return TRUE (Success), FALSE (Failure: tick_ptr or xdate_ptr is NULL).
 * 
 * \see _time_xdate_to_ticks
 * \see MQX_TICK_STRUCT
 * \see MQX_XDATE_STRUCT   
 */ 
boolean _time_ticks_to_xdate
(
    MQX_TICK_STRUCT_PTR  tick_ptr,
    MQX_XDATE_STRUCT_PTR xdate_ptr
)
{ /* Body */

#if MQX_CHECK_ERRORS
    if ((tick_ptr == NULL) || (xdate_ptr == NULL)) {
        return (FALSE);
    } /* Endif */
#endif

    return PSP_TICKS_TO_XDATE(tick_ptr, xdate_ptr);

} /* Endbody */

/*!
 * \brief Converts seconds/msecs value into a date and time from Jan.1 1970.
 * 
 * The function verifies that the fields in the input structure are within the 
 * following ranges.
 * <table>
 *   <tr>
 *     <td><b>Field</b></td>
 *     <td><b>Minimum</b></td>
 *     <td><b>Maximum</b></td>  
 *   </tr>
 *   <tr>
 *     <td><b>SECONDS</b></td>
 *     <td>0</td>
 *     <td>MAXIMUM_SECONDS_IN_TIME (4,102,444,800)</td>  
 *   </tr>
 *   <tr>
 *     <td><b>MILLISECONDS</b></td>
 *     <td>0</td>
 *     <td>999</td>  
 *   </tr>     
 * </table>
 * 
 * The function converts the fields in the input structure to the fields in the 
 * output structure, taking into account leap years.
 * \n The time is since 0:00:00.00, January 1, 1970.
 * 
 * \param[in] ts_ptr   Pointer to time structure.
 * \param[in] time_ptr Pointer to a date/time structure.
 * 
 * \return TRUE (Success), FALSE (Failure: ts_ptr or time_ptr is NULL or ts_ptr 
 * is out of range).
 * 
 * \see _time_get
 * \see _time_get_ticks
 * \see _time_get_elapsed
 * \see _time_get_elapsed_ticks
 * \see _time_set
 * \see _time_set_ticks
 * \see _time_from_date
 * \see DATE_STRUCT
 * \see TIME_STRUCT  
 */ 
boolean _time_to_date
(
    TIME_STRUCT_PTR ts_ptr,
    DATE_STRUCT_PTR time_ptr
)
{ /* Body */
    uint_32 time;
    _mqx_uint leap;

#if MQX_CHECK_ERRORS
    if ((ts_ptr == NULL) || (time_ptr == NULL)) {
        return (FALSE);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if ((ts_ptr->SECONDS > MAXIMUM_SECONDS_IN_TIME) ||
                    (ts_ptr->MILLISECONDS > MAXIMUM_MILLISECONDS))
    {
        return( FALSE );
    } /* Endif */
#endif

    /* Find the year the date is in. */

    time_ptr->YEAR = 0;
    while (ts_ptr->SECONDS >= _time_secs_before_year_internal[time_ptr->YEAR + 1]) {
        time_ptr->YEAR++;
    } /* Endwhile */

    /* Calculate the number of seconds since the beginning of the year */
    time = ts_ptr->SECONDS - _time_secs_before_year_internal[time_ptr->YEAR];

    time_ptr->YEAR += (uint_16) CLK_FIRST_YEAR;

    /* Find out if we are in a leap year. */
    leap = (_mqx_uint) _time_check_if_leap(time_ptr->YEAR);

    /* calculate the month */
    time_ptr->MONTH = 1;
    while (time >= _time_secs_before_month_internal[leap][time_ptr->MONTH]) {
        time_ptr->MONTH++;
    } /* Endwhile */
    time -= _time_secs_before_month_internal[leap][time_ptr->MONTH - 1];

    /* calculate the day */
    time_ptr->DAY = (uint_16)(time / SECS_IN_DAY);
    time -= ((uint_32) time_ptr->DAY * SECS_IN_DAY);

    /* first day is 1*/
    time_ptr->DAY++;

    /* calculate the hour */
    time_ptr->HOUR = (uint_16)(time / SECS_IN_HOUR);
    time -= ((uint_32) time_ptr->HOUR * SECS_IN_HOUR);

    /* calculate the minute */
    time_ptr->MINUTE = (uint_16)(time / SECS_IN_MINUTE);
    time -= ((uint_32) time_ptr->MINUTE * SECS_IN_MINUTE);

    /* the second */
    time_ptr->SECOND = (uint_16) time;

    /* the millisecond */
    time_ptr->MILLISEC = (uint_16) ts_ptr->MILLISECONDS;

    return (TRUE);

} /* Endbody */

#if MQX_HAS_TICK
/*!
 * \brief Converts extended date format to tick time format.
 * 
 * The function verifies that the fields in the input structure are within the 
 * following ranges.
 * 
 * \param[in]  xdate_ptr Pointer to the extended date structure.
 * \param[out] tick_ptr  Pointer to structure where the number of ticks is to be 
 * written. 
 * 
 * \return TRUE (Success), FALSE (Failure: xdate_time_ptr or tick_time_ptr is 
 * NULL or xdate_ptr is not normalized).
 * 
 * \see _time_ticks_to_xdate
 * \see MQX_TICK_STRUCT
 * \see MQX_XDATE_STRUCT
 */ 
boolean _time_xdate_to_ticks
(
    MQX_XDATE_STRUCT_PTR xdate_ptr,
    MQX_TICK_STRUCT_PTR  tick_ptr
)
{ /* Body */
    uint_32 time;
    _mqx_uint tmp;
    MQX_TICK_STRUCT t2;
    KERNEL_DATA_STRUCT_PTR kernel_data;

#if MQX_CHECK_ERRORS
    if ((xdate_ptr == NULL) || (tick_ptr == NULL)) {
        return FALSE;
    } /* Endif */
#endif

    if (!_time_normalize_xdate(xdate_ptr)) {
        return FALSE;
    } /* Endif */

    /*
     * Determine the number of days since Jan 1, 1970 at 00:00:00
     */
    time = _time_days_before_year_internal[(xdate_ptr->YEAR -
                    (uint_16)XCLK_FIRST_YEAR)];

    tmp = (_mqx_uint)_time_check_if_leap(xdate_ptr->YEAR);

    /*
     * Add the number of days since 0000 hours, Jan 1, to the first
     * day of month.
     */
    time += _time_days_before_month_internal[tmp][xdate_ptr->MONTH-1];

    /*
     * Add the number of days since the beginning of the month.
     */
    time += (uint_32)(xdate_ptr->MDAY - 1);

    /* Convert everything so far into hours */
    time = time * HOURS_IN_DAY + xdate_ptr->HOUR;

    /* Convert to seconds */
    tick_ptr->HW_TICKS = 0;
    t2 = _mqx_zero_tick_struct;
    PSP_ADD_TICKS_TO_TICK_STRUCT(&t2, SECS_IN_HOUR, &t2);
    PSP_MULTIPLY_TICKS_BY_UINT_32(&t2, time, tick_ptr);

    /* Add in seconds and minutes from XDATE struct */
    tmp = xdate_ptr->SEC + xdate_ptr->MIN * SECS_IN_MINUTE;
    PSP_ADD_TICKS_TO_TICK_STRUCT(tick_ptr, tmp, tick_ptr);

    /* Convert everything into ticks */
    _GET_KERNEL_DATA(kernel_data);
    time = (uint_32)kernel_data->TICKS_PER_SECOND;
    PSP_MULTIPLY_TICKS_BY_UINT_32(tick_ptr, time, tick_ptr);

    if (xdate_ptr->MSEC) {
        PSP_MILLISECONDS_TO_TICKS(xdate_ptr->MSEC, &t2);
        PSP_ADD_TICKS(tick_ptr, &t2, tick_ptr);
    } /* Endif */

    if (xdate_ptr->USEC) {
        PSP_MICROSECONDS_TO_TICKS(xdate_ptr->USEC, &t2);
        PSP_ADD_TICKS(tick_ptr, &t2, tick_ptr);
    } /* Endif */

    if (xdate_ptr->NSEC) {
        PSP_NANOSECONDS_TO_TICKS(xdate_ptr->NSEC, &t2);
        PSP_ADD_TICKS(tick_ptr, &t2, tick_ptr);
    } /* Endif */

    if (xdate_ptr->PSEC) {
        PSP_PICOSECONDS_TO_TICKS(xdate_ptr->PSEC, &t2);
        PSP_ADD_TICKS(tick_ptr, &t2, tick_ptr);
    } /* Endif */

    return TRUE;

} /* Endbody */

#endif /* MQX_HAS_TICK */

/*!
 * \brief Converts second/millisecond time format to tick time format.
 * 
 * The function verifies that the fields in the input structure are within the 
 * following ranges.
 * <table>
 *   <tr>
 *     <td><b>Field</b></td>
 *     <td><b>Minimum</b></td>
 *     <td><b>Maximum</b></td>  
 *   </tr>
 *   <tr>
 *     <td><b>SECONDS</b></td>
 *     <td>0</td>
 *     <td>MAXIMUM_SECONDS_IN_TIME (4,102,444,800)</td>  
 *   </tr>
 *   <tr>
 *     <td><b>MILLISECONDS</b></td>
 *     <td>0</td>
 *     <td>999</td>  
 *   </tr>     
 * </table>
 * 
 * The function converts the fields in the input structure to the fields in the 
 * output structure, taking into account leap years.
 * 
 * \param[in]  time_ptr Pointer to a normalized second/millisecond time structure.
 * \param[out] tick_ptr Pointer to the corresponding tick time structure.
 * 
 * \return TRUE (Success), FALSE (Failure: tick_ptr or time_ptr is NULL).
 * 
 * \see _ticks_to_time
 * \see MQX_TICK_STRUCT
 * \see TIME_STRUCT   
 */ 
boolean _time_to_ticks
(
    TIME_STRUCT_PTR     time_ptr,
    MQX_TICK_STRUCT_PTR tick_ptr
)
{ /* Body */

#if MQX_CHECK_ERRORS
    if ((tick_ptr == NULL) || (time_ptr == NULL)) {
        return (FALSE);
    } /* Endif */
#endif
    PSP_TIME_TO_TICKS(time_ptr, tick_ptr);

    return (TRUE);

} /* Endbody */

/*!
 * \brief Converts tick format to second/millisecond format.
 * 
 * The function verifies that the fields in the input structure are within the 
 * following ranges.
 * <table>
 *   <tr>
 *     <td><b>Field</b></td>
 *     <td><b>Minimum</b></td>
 *     <td><b>Maximum</b></td>  
 *   </tr>
 *   <tr>
 *     <td><b>TICKS</b></td>
 *     <td>0</td>
 *     <td>(2^64)-1</td>  
 *   </tr>
 *   <tr>
 *     <td><b>HW_TICKS</b></td>
 *     <td>0</td>
 *     <td>(2^32)-1</td>  
 *   </tr>     
 * </table>
 * 
 * \param[in]  tick_ptr Pointer to a tick structure.
 * \param[out] time_ptr Pointer to the corresponding normalized 
 * second/millisecond time structure.
 *  
 * \return TRUE (Success), FALSE (Failure: tick_ptr or time_ptr is NULL).
 * 
 * \see _time_to_ticks
 * \see MQX_TICK_STRUCT
 * \see TIME_STRUCT  
 */ 
boolean _ticks_to_time
(
    MQX_TICK_STRUCT_PTR tick_ptr,
    TIME_STRUCT_PTR     time_ptr
)
{ /* Body */

#if MQX_CHECK_ERRORS
    if ((tick_ptr == NULL) || (time_ptr == NULL)) {
        return (FALSE);
    } /* Endif */
#endif
    PSP_TICKS_TO_TIME(tick_ptr, time_ptr);

    return (TRUE);

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/core_mutex/core_mutex_sema4.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: core_mutex_sema4.h$
* $Version : 3.8.2.0$
* $Date    : Sep-24-2012$
*
* Comments:
*
*   This file contains the type definitions for the core mutex driver for the SEMA4.
*
*END************************************************************************/

#ifndef __core_mutex_sema4_h__
#define __core_mutex_sema4_h__

#define __core_mutex_sema4_h__version "$Version:3.8.2.0$"
#define __core_mutex_sema4_h__date    "$Date:Sep-24-2012$"

#include <sema4.h>

#ifndef BSPCFG_CORE_MUTEX_STATS
#define BSPCFG_CORE_MUTEX_STATS 0
#endif

typedef struct core_mutex_struct {
    uint_32                 VALID;
    uint_32                 GATE_NUM;
    vuchar_ptr              GATE_PTR;
    pointer                 WAIT_Q;
#if BSPCFG_CORE_MUTEX_STATS
    uint_32                 LOCKS;
    uint_32                 WAITS;
    uint_32                 UNLOCKS;
#endif
} CORE_MUTEX_STRUCT, * CORE_MUTEX_PTR;


typedef struct core_mutex_device {
    SEMA4_MemMapPtr SEMA4_PTR;
    vuint_16_ptr            CPNTF_PTR;

    uint_32                 ALLOCED;
    CORE_MUTEX_PTR          MUTEX_PTR[SEMA4_NUM_GATES];
} CORE_MUTEX_DEVICE, * CORE_MUTEX_DEVICE_PTR;

#ifdef __cplusplus
extern "C" {
#endif


SEMA4_MemMapPtr _bsp_get_sema4_base_address(uint_32);
uint_32 _bsp_get_sema4_vector(uint_32 device);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/route.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: route.h$
* $Version : 3.5.2.0$
* $Date    : Jan-15-2010$
*
* Comments:
*
*   Definition for the route core functions
*
*END************************************************************************/

#ifndef __route_h__
#define __route_h__

/***************************************
**
** Constants
**
*/


/***************************************
**
** Type definitions
**
*/


/***************************************
**
** Prototypes
**
*/
void ROUTE_register(
   IP_ROUTE_FN_PTR   routefn  /* [IN] list of routing functions */
);

uint_32 ROUTE_new_bindif(
   IP_ROUTE_DIRECT_PTR   bindif   /* [IN] the outgoing binded interface */
);

IP_ROUTE_INDIRECT_PTR ROUTE_get(
   _ip_address    netaddr, /* [IN] the network address */
   _ip_address    netmask  /* [IN] the network mask */
);

uint_32 ROUTE_insert(
   IP_ROUTE_INDIRECT_PTR    gate,    /* [IN] the route entry to insert */
   _ip_address              netaddr, /* [IN] the network address */
   _ip_address              netmask  /* [IN] the network mask */

);

uint_32 ROUTE_remove(
   IP_ROUTE_INDIRECT_PTR    gate     /* [IN] the route entry to insert */
);

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/sstream.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sstream.c$
* $Version : 3.8.10.0$
* $Date    : Sep-10-2012$
*
* Comments:
*
*   This file contains the socket interface functions for
*   (PF_INET,SOCK_STREAM) sockets.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "socket.h"

#if RTCSCFG_ENABLE_TCP

#define RTCS_ENTER(f,a)    RTCSLOG_API(RTCSLOG_TYPE_FNENTRY, RTCSLOG_FN_STREAM_ ## f, a)

#define RTCS_EXIT(f,a)     RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_STREAM_ ## f, a); \
                           return a

#define RTCS_EXIT2(f,a,e)  RTCSLOG_API(RTCSLOG_TYPE_FNEXIT,  RTCSLOG_FN_STREAM_ ## f, a); \
                           return e



uint_32 SOCK_STREAM_socket      (uint_32);

uint_32 SOCK_STREAM_bind      (uint_32, const sockaddr _PTR_, uint_16);
uint_32 SOCK_STREAM_connect     (uint_32, const sockaddr _PTR_, uint_16);
uint_32 SOCK_STREAM_listen      (uint_32, uint_32);
uint_32 SOCK_STREAM_accept      (uint_32, sockaddr _PTR_, uint_16 _PTR_);
uint_32 SOCK_STREAM_getsockname (uint_32, sockaddr _PTR_, uint_16 _PTR_);
uint_32 SOCK_STREAM_getpeername (uint_32, sockaddr _PTR_, uint_16 _PTR_);
 int_32 SOCK_STREAM_recv        (uint_32, pointer, uint_32, uint_32);
 int_32 SOCK_STREAM_send        (uint_32, pointer, uint_32, uint_32);
uint_32 SOCK_STREAM_shutdown    (uint_32, uint_32);



const RTCS_SOCKET_CALL_STRUCT SOCK_STREAM_CALL = {
   SOCK_STREAM_socket,
   SOCK_STREAM_bind,
   SOCK_STREAM_connect,
   SOCK_STREAM_listen,
   SOCK_STREAM_accept,
   SOCK_STREAM_getsockname,
   SOCK_STREAM_getpeername,
   SOCK_STREAM_recv,
   NULL,
   NULL,
   SOCK_STREAM_send,
   NULL,
   NULL,
   NULL,
   SOCK_STREAM_shutdown
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_STREAM_socket
* Returned Value  : error code
* Comments  :  Creates an unbound socket.
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_STREAM_socket
   (
      uint_32     sock
         /* [IN] socket handle */
   )
{ /* Body */
   TCP_PARM    parms;
   uint_32     error;

   parms.SOCKET = sock;

   error = RTCSCMD_issue(parms, TCP_Process_create);
   if (error) return error;

   ((SOCKET_STRUCT_PTR)sock)->STATE   = SOCKSTATE_STREAM_GROUND;
   ((SOCKET_STRUCT_PTR)sock)->TCB_PTR = parms.TCB_PTR;
   return RTCS_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name     : SOCK_STREAM_bind
* Returned Value    : error code
* Comments          : Binds the local endpoint of a socket for IPv4 and IPv6 families.
*END*-----------------------------------------------------------------*/
uint_32  SOCK_STREAM_bind
   (
        uint_32                    sock,
         /* [IN] socket handle */
        const sockaddr _PTR_    localaddr,
         /* [IN] IPv4 or IPv6 local address to which to bind the socket */
        uint_16                    addrlen
         /* [IN] length of the address, in bytes */
   )
{ /* Body */
    TCP_PARM    parms;
    uint_32     error=0;

    RTCS_ENTER(BIND, sock);

#if RTCSCFG_CHECK_ERRORS
    if (((SOCKET_STRUCT_PTR)sock)->STATE != SOCKSTATE_STREAM_GROUND) 
    {
        RTCS_EXIT(BIND, RTCSERR_SOCK_IS_BOUND);
    } /* Endif */
#endif

#if RTCSCFG_CHECK_ADDRSIZE
    if((localaddr->sa_family)==AF_INET)
    { 
        if (addrlen < sizeof(sockaddr_in)) 
        {
            RTCS_EXIT(BIND, RTCSERR_SOCK_SHORT_ADDRESS);
        } /* Endif */
    }
#if RTCSCFG_ENABLE_IP6    
    else if((localaddr->sa_family)==AF_INET6)
    { 
        if (addrlen < sizeof(struct sockaddr_in6)) 
        {
            RTCS_EXIT(BIND, RTCSERR_SOCK_SHORT_ADDRESS);
        } /* Endif */
    }
#endif    
    else
    {
        /* wrong inet family */
        RTCS_EXIT(BIND, RTCSERR_SOCK_INVALID_AF);
    }
#endif


#if!RTCSCFG_CHECK_ADDRSIZE
    #if RTCSCFG_CHECK_ERRORS

        #if RTCSCFG_ENABLE_IP6    
            if ((localaddr->sa_family != AF_INET)&&(localaddr->sa_family != AF_INET6)) 
            {
                RTCS_EXIT(BIND, RTCSERR_SOCK_INVALID_AF);
            } /* Endif */
        #else
            if (localaddr->sa_family != AF_INET) 
            {
                RTCS_EXIT(BIND, RTCSERR_SOCK_INVALID_AF);
            } /* Endif */
        #endif

    #endif
#endif

    if (!((SOCKET_STRUCT_PTR)sock)->TCB_PTR) 
    {
      RTCS_EXIT(BIND, RTCSERR_TCP_CONN_RLSD);
    } /* Endif */

    parms.TCB_PTR  = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR;

#if RTCSCFG_ENABLE_IP6    
    if(localaddr->sa_family == AF_INET)
    {
#endif
        parms.IP_ADDR  = ((sockaddr_in*)localaddr)->sin_addr.s_addr;
        parms.TCP_PORT = ((sockaddr_in *)localaddr)->sin_port; 
                                                               
#if RTCSCFG_ENABLE_IP6                                                                     
    }                                                             
    else if(localaddr->sa_family == AF_INET6)
    {
        IN6_ADDR_COPY((in6_addr*)(&( ((sockaddr_in6 *)localaddr)->sin6_addr )),&(parms.IPV6_ADDR));
        parms.TCP_PORT = ((struct sockaddr_in6 *)localaddr)->sin6_port;//TBD: To take port value here we can use only (sockaddr_in *)localaddr)->sin_port
                                                                      //     but to avoid a problem uncompatibility we are checking family.       
        
        /* set a scope_id of binded address */
        parms.IF_SCOPE_ID = ((struct sockaddr_in6 *)localaddr)->sin6_scope_id;
    }

#endif
    /* set family here to send it to TCP_process_bind */
    parms.AF = localaddr->sa_family;
    
    /* Call main bind function */
    error = RTCSCMD_issue(parms, TCP_Process_bind);
    if (error) 
    {
      RTCS_EXIT(BIND, error);
    } /* Endif */

#if RTCSCFG_ENABLE_IP6    
    if((localaddr->sa_family)==AF_INET)
    {
#endif    

        ((SOCKET_STRUCT_PTR)sock)->LOCAL_PORT = ((sockaddr_in *)localaddr)->sin_port;
#if RTCSCFG_ENABLE_IP6    
    }                                                                                
    else if((localaddr->sa_family)==AF_INET6)
    {
        ((SOCKET_STRUCT_PTR)sock)->LOCAL_PORT = ((struct sockaddr_in6 *)localaddr)->sin6_port;
    }
#endif

    ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_STREAM_BOUND;
    RTCS_EXIT(BIND, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name     : SOCK_STREAM_connect
* Returned Value    : error code
* Comments          : Binds the remote endpoint of a socket. IPv4 and IPv6 support.
*END*-----------------------------------------------------------------*/
uint_32  SOCK_STREAM_connect 
   (
      uint_32                   sock,
         /* [IN] socket handle */
      const sockaddr _PTR_      peeraddr,
         /* [IN] remote IPv4 or IPv6 address to which to bind the socket */
      uint_16                   addrlen
         /* [IN] length of the address, in bytes */
   )
{ /* Body */
            TCP_PARM            parms;
            TCP_OPTIONS_STRUCT  options;
   register SOCKET_STRUCT_PTR   socket_ptr = (SOCKET_STRUCT_PTR)sock;
            uint_32             error=0;

   RTCS_ENTER(CONNECT, sock);

#if RTCSCFG_CHECK_ERRORS
    switch (((SOCKET_STRUCT_PTR)sock)->STATE) 
    {
        case SOCKSTATE_STREAM_LISTENING: RTCS_EXIT(CONNECT, RTCSERR_SOCK_IS_LISTENING);
        case SOCKSTATE_STREAM_CONNECTED: RTCS_EXIT(CONNECT, RTCSERR_SOCK_IS_CONNECTED);
    } /* Endswitch */
#endif


    /* Checking right family */
    error=1;
#if RTCSCFG_ENABLE_IP4
    if(peeraddr->sa_family == AF_INET)
    {
        error=0;
    } /* Endif */
#endif
#if RTCSCFG_ENABLE_IP6    
    if(peeraddr->sa_family == AF_INET6) 
    {
        error=0;
    } /* Endif */
#endif    
    if(error)
    {
        RTCS_EXIT(CONNECT, RTCSERR_SOCK_INVALID_AF);    
    }


    /* Checking address lenght */
#if RTCSCFG_CHECK_ADDRSIZE

    #if RTCSCFG_ENABLE_IP6
    if((peeraddr->sa_family)==AF_INET)
    { 
    #endif

        if (addrlen < sizeof(sockaddr_in)) 
        {
            RTCS_EXIT(CONNECT, RTCSERR_SOCK_SHORT_ADDRESS);
        } /* Endif */
        
    #if RTCSCFG_ENABLE_IP6    
    }
    else if((peeraddr->sa_family)==AF_INET6)
    { 
        if (addrlen < sizeof(struct sockaddr_in6)) 
        {
            RTCS_EXIT(CONNECT, RTCSERR_SOCK_SHORT_ADDRESS);
        } /* Endif */
    }
    #endif
        
#endif // end RTCSCFG_CHECK_ADDRSIZE



    if (!((SOCKET_STRUCT_PTR)sock)->TCB_PTR)
    {
        RTCS_EXIT(CONNECT, RTCSERR_TCP_CONN_RLSD);
    } /* Endif */

    /* Bind if socket was not binded yet */
    if (((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_STREAM_GROUND) 
    {
        #if RTCSCFG_ENABLE_IP6    
        if((peeraddr->sa_family)==AF_INET)
        {    
        #endif

            sockaddr_in localaddr;
            localaddr.sin_family      = AF_INET;
            localaddr.sin_port        = 0;
            localaddr.sin_addr.s_addr = INADDR_ANY;
            error = SOCK_STREAM_bind(sock, (const sockaddr*)(&localaddr), sizeof(localaddr));                  

        #if RTCSCFG_ENABLE_IP6        
        }
        else if((peeraddr->sa_family)==AF_INET6)
        {    
            sockaddr_in6 localaddr;
            localaddr.sin6_family      = AF_INET6;
            localaddr.sin6_port        = 0;
            /* set scope_id to NULL */
            localaddr.sin6_scope_id    = 0;// Let to IP level to choose interface.
            IN6_ADDR_COPY((in6_addr*)(&in6addr_any), &(localaddr.sin6_addr));
            //localaddr.sin_addr.s_addr = INADDR_ANY;
            error = SOCK_STREAM_bind(sock, (const sockaddr*)(&localaddr), sizeof(localaddr));      
        }
        #endif
    }      
      
    if (error) 
    {
        RTCS_EXIT(CONNECT, error);
    } /* Endif */


   /*
   **  Setup the known 'connect' options
   */
   
    #if RTCSCFG_ENABLE_IP6    
    if((peeraddr->sa_family)==AF_INET)
    {
    #endif    
    
        options.remhost    = ((sockaddr_in *)peeraddr)->sin_addr.s_addr;    
        options.remport    = ((sockaddr_in *)peeraddr)->sin_port;
    
    #if RTCSCFG_ENABLE_IP6    
    }
    else if((peeraddr->sa_family)==AF_INET6)
    {
        IN6_ADDR_COPY((in6_addr*)&(((sockaddr_in6 *)peeraddr)->sin6_addr),&(options.remhost_ipv6)); 
        options.remport    = ((sockaddr_in6 *)peeraddr)->sin6_port;
   /*  
    *  Chose and add scope_id here. 
    *  If peeraddr scope_id is not NULL we will use it.  
    *  If it is NULL, we will use scope_id of local binded address
    */
        parms.IF_SCOPE_ID = ((sockaddr_in6 *)peeraddr)->sin6_scope_id;       
        if(parms.IF_SCOPE_ID ==0)
        {
          //Here if_scope_id is if nember that was binded with local address
            parms.IF_SCOPE_ID =((SOCKET_STRUCT_PTR)sock)->TCB_PTR->if_scope_id;
        }   
    }
    #endif
 //  options.remhost    = peeraddr->sin_addr.s_addr;
 //  IN6_ADDR_COPY((in6_addr*)&(peeraddr->sin6_addr),&(options.remhost_ipv6)); 
 //options.remport    = peeraddr->sin6_port;

   options.utimeout   = socket_ptr->SEND_TIMEOUT;
   options.timeout    = socket_ptr->CONNECT_TIMEOUT;
   options.rto        = socket_ptr->RETRANSMISSION_TIMEOUT;
   options.active     = socket_ptr->ACTIVE;
   options.tbsize     = socket_ptr->TBSIZE;
   options.rbsize     = socket_ptr->RBSIZE;
   options.maxrto     = socket_ptr->MAXRTO;
   options.maxrcvwnd  = socket_ptr->MAXRCV_WND;
   options.keepalive  = socket_ptr->KEEPALIVE;
   options.nowait     = socket_ptr->NOWAIT;
   options.nonagle    = socket_ptr->NO_NAGLE_ALGORITHM;
   options.noswrbuf   = socket_ptr->NOSWRBUF;
   options.timewaitto = socket_ptr->TIMEWAIT_TIMEOUT;
   /* Start CR 1576 */
   options.tcpsecuredraft0 = socket_ptr->TCPSECUREDRAFT_0;
   /* End CR 1576 */
   options.delayackto = socket_ptr->DELAY_ACK;

   /*
   **  Setup the default 'connect' options
   */
   options.tos        = 0;
   options.precede    = 0xFF;
   options.ttl        = 0;

   parms.TCB_PTR     = socket_ptr->TCB_PTR;
   parms.OPTIONS_PTR = &options;
   
   parms.AF = socket_ptr->AF;

   error = RTCSCMD_issue(parms, TCP_Process_open);
   if (error) {
      RTCS_EXIT(CONNECT, error);
   } /* Endif */

   ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_STREAM_CONNECTED;
   RTCS_EXIT(CONNECT, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_STREAM_listen
* Returned Value  : error code
* Comments  :  Enables remote connections on a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_STREAM_listen
   (
      uint_32     sock,
         /* [IN] socket handle */
      uint_32     backlog
         /* [IN] not implemented */
   )
{ /* Body */
            TCP_PARM             parms;
            TCP_OPTIONS_STRUCT   options;
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;
            uint_32              error=0;

   RTCS_ENTER(LISTEN, sock);

#if RTCSCFG_CHECK_ERRORS
   switch (((SOCKET_STRUCT_PTR)sock)->STATE) {
   case SOCKSTATE_STREAM_GROUND:    RTCS_EXIT(LISTEN, RTCSERR_SOCK_NOT_BOUND);
   case SOCKSTATE_STREAM_LISTENING: RTCS_EXIT(LISTEN, RTCSERR_SOCK_IS_LISTENING);
   case SOCKSTATE_STREAM_CONNECTED: RTCS_EXIT(LISTEN, RTCSERR_SOCK_IS_CONNECTED);
   } /* Endswitch */
#endif

   if (!((SOCKET_STRUCT_PTR)sock)->TCB_PTR) {
      RTCS_EXIT(LISTEN, RTCSERR_TCP_CONN_RLSD);
   } /* Endif */

   /*
   **  Setup the known 'connect' options
   */
   /*  Checking right family  */
    error=1;
#if RTCSCFG_ENABLE_IP4
    if(socket_ptr->AF == AF_INET) 
    {
        error=0;
    } /* Endif */
#endif
#if RTCSCFG_ENABLE_IP6    
    if(socket_ptr->AF == AF_INET6) 
    {
        error=0;
    } /* Endif */
#endif    
    if(error)
    {
        RTCS_EXIT(LISTEN, RTCSERR_SOCK_INVALID_AF);    
    }
   
   #if RTCSCFG_ENABLE_IP6
    
   if(socket_ptr->AF == AF_INET6 )
   {
        IN6_ADDR_COPY((in6_addr *)&in6addr_any, &options.remhost_ipv6);
        
        /* add scope_id of listen interface here */
        parms.IF_SCOPE_ID = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->if_scope_id;
        
   }
   else if(socket_ptr->AF == AF_INET)
   {
   #endif
        options.remhost    = INADDR_ANY;
   #if RTCSCFG_ENABLE_IP6
   }
   #endif

   options.remport    = 0;
   options.utimeout   = socket_ptr->SEND_TIMEOUT;
   options.timeout    = socket_ptr->CONNECT_TIMEOUT;
   options.rto        = socket_ptr->RETRANSMISSION_TIMEOUT;
   options.active     = FALSE;
   options.tbsize     = socket_ptr->TBSIZE;
   options.rbsize     = socket_ptr->RBSIZE;
   options.maxrto     = socket_ptr->MAXRTO;
   options.maxrcvwnd  = socket_ptr->MAXRCV_WND;
   options.keepalive  = socket_ptr->KEEPALIVE;
   options.nowait     = socket_ptr->NOWAIT;
   options.nonagle    = socket_ptr->NO_NAGLE_ALGORITHM;
   options.noswrbuf   = socket_ptr->NOSWRBUF;
   options.timewaitto = socket_ptr->TIMEWAIT_TIMEOUT;
   options.delayackto = socket_ptr->DELAY_ACK;

   /*
   **  Setup the default 'connect' options
   */
   options.tos        = 0;
   options.precede    = 0xFF;
   options.ttl        = 0;

   parms.TCB_PTR     = socket_ptr->TCB_PTR;
   parms.OPTIONS_PTR = &options;
   parms.SOCKET      = sock;
   parms.AF          = socket_ptr->AF;

   error = RTCSCMD_issue(parms, TCP_Process_open);

   if(error) 
   {
        RTCS_EXIT(LISTEN, error);
   } /* Endif */

   ((SOCKET_STRUCT_PTR)sock)->STATE = SOCKSTATE_STREAM_LISTENING;
   
   RTCS_EXIT(LISTEN, RTCS_OK);
} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_STREAM_accept
* Returned Value  : socket
* Comments  :  Wait for a connection on a socket, support IPv4 and IPv6.
*
*END*-----------------------------------------------------------------*/
uint_32  SOCK_STREAM_accept
   (
             uint_32                sock,
         /* [IN] socket handle */
      struct sockaddr _PTR_     peeraddr,
         /* [OUT] remote address IPv6 to which the socket is connected */
             uint_16     _PTR_      addrlen
         /* [IN/OUT] length of the address IPv6, in bytes */
   )
{ /* Body */
   TCP_PARM             parms;
   SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;
   SOCKET_STRUCT_PTR    new_socket_ptr;
   uint_32              error;
   uint_32              newsock;

   RTCS_ENTER(ACCEPT, sock);

#if RTCSCFG_CHECK_ERRORS
   switch (((SOCKET_STRUCT_PTR)sock)->STATE) {
   case SOCKSTATE_STREAM_GROUND:
            RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_LISTENING);
            RTCS_EXIT2(ACCEPT, RTCSERR_SOCK_NOT_LISTENING, RTCS_SOCKET_ERROR);
   case SOCKSTATE_STREAM_BOUND:
            RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_LISTENING);
            RTCS_EXIT2(ACCEPT, RTCSERR_SOCK_NOT_LISTENING, RTCS_SOCKET_ERROR);
   case SOCKSTATE_STREAM_CONNECTED:
            RTCS_setsockerror(sock, RTCSERR_SOCK_IS_CONNECTED);
            RTCS_EXIT2(ACCEPT, RTCSERR_SOCK_IS_CONNECTED, RTCS_SOCKET_ERROR);
   } /* Endswitch */
#endif

   /*
   ** Allocate a new socket structure for the established TCB
   */
   new_socket_ptr = SOCK_Get_sock_struct((RTCS_SOCKET_CALL_STRUCT_PTR)SOCK_STREAM,
                                         RTCS_task_getid());
   newsock = (uint_32)new_socket_ptr;

   if (new_socket_ptr == NULL) {
      RTCS_setsockerror(sock, RTCSERR_OUT_OF_SOCKETS);
      RTCS_EXIT2(ACCEPT, RTCSERR_OUT_OF_SOCKETS, RTCS_SOCKET_ERROR);
   } /* Endif */

   parms.TCB_PTR = socket_ptr->TCB_PTR;
   new_socket_ptr->AF = socket_ptr->AF;
   parms.SOCKET = newsock;

   error = RTCSCMD_issue(parms, TCP_Process_accept);
   if (error) {
      SOCK_Free_sock_struct(new_socket_ptr);
      RTCS_setsockerror(sock, error);
      RTCS_EXIT2(ACCEPT, error, RTCS_SOCKET_ERROR);
   } /* Endif */

   new_socket_ptr->STATE = SOCKSTATE_STREAM_CONNECTED;
   
   error = SOCK_STREAM_getpeername(newsock, peeraddr, addrlen);

   /*
   ** If there is an error, it is because the TCB was freed (by a RST).
   ** We will free the socket and return a socket error
   */
   if (error) {
      SOCK_Free_sock_struct(new_socket_ptr);
      RTCS_setsockerror(sock, error);
      RTCS_EXIT2(ACCEPT, error, RTCS_SOCKET_ERROR);
   } /* Endif */

   /*
   ** inherit the socket options from listen socket
   */
   new_socket_ptr->CONNECT_TIMEOUT        = socket_ptr->CONNECT_TIMEOUT;
   new_socket_ptr->RETRANSMISSION_TIMEOUT = socket_ptr->RETRANSMISSION_TIMEOUT;
   new_socket_ptr->SEND_TIMEOUT           = socket_ptr->SEND_TIMEOUT;
   new_socket_ptr->RECEIVE_TIMEOUT        = socket_ptr->RECEIVE_TIMEOUT;
   new_socket_ptr->RECEIVE_PUSH           = socket_ptr->RECEIVE_PUSH;
   new_socket_ptr->SEND_NOWAIT            = socket_ptr->SEND_NOWAIT;
   new_socket_ptr->SEND_WAIT              = socket_ptr->SEND_WAIT;
   new_socket_ptr->SEND_PUSH              = socket_ptr->SEND_PUSH;
   new_socket_ptr->RECEIVE_NOWAIT         = socket_ptr->RECEIVE_NOWAIT;
   new_socket_ptr->CHECKSUM_BYPASS        = socket_ptr->CHECKSUM_BYPASS;
   new_socket_ptr->ACTIVE                 = socket_ptr->ACTIVE;
   new_socket_ptr->TBSIZE                 = socket_ptr->TBSIZE;
   new_socket_ptr->RBSIZE                 = socket_ptr->RBSIZE;
   new_socket_ptr->MAXRTO                 = socket_ptr->MAXRTO;
   new_socket_ptr->MAXRCV_WND             = socket_ptr->MAXRCV_WND;
   new_socket_ptr->KEEPALIVE              = socket_ptr->KEEPALIVE;
   new_socket_ptr->NOWAIT                 = socket_ptr->NOWAIT;
   new_socket_ptr->NO_NAGLE_ALGORITHM     = socket_ptr->NO_NAGLE_ALGORITHM;
   new_socket_ptr->NOSWRBUF               = socket_ptr->NOSWRBUF;
   new_socket_ptr->CALL_BACK              = socket_ptr->CALL_BACK;
   new_socket_ptr->TYPE_MIRROR            = socket_ptr->TYPE_MIRROR;
   new_socket_ptr->TIMEWAIT_TIMEOUT       = socket_ptr->TIMEWAIT_TIMEOUT;
   new_socket_ptr->LOCAL_PORT             = socket_ptr->LOCAL_PORT;
   new_socket_ptr->AF                     = socket_ptr->AF;
   
   /* Start CR 1144 */
   new_socket_ptr->LINK_OPTIONS           = socket_ptr->LINK_OPTIONS;
   /* End CR 1144 */

   RTCS_EXIT2(ACCEPT, RTCS_OK, newsock);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_STREAM_send
* Returned Value  : number of bytes sent or RTCS_ERROR
* Comments  :  Send data to a connected socket.
*
*END*-----------------------------------------------------------------*/

int_32  SOCK_STREAM_send
   (
      uint_32        sock,
         /* [IN] socket handle */
      pointer        buffer,
         /* [IN] data to transmit */
      uint_32        buflen,
         /* [IN] length of the buffer, in bytes */
      uint_32        flags
         /* [IN] flags to underlying protocols */
   )
{ /* Body */
            TCP_PARM             parms;
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;
            uint_32              error;

   RTCS_ENTER(SEND, sock);

#if RTCSCFG_CHECK_ERRORS
   if (((SOCKET_STRUCT_PTR)sock)->STATE != SOCKSTATE_STREAM_CONNECTED) {
      RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_CONNECTED);
      RTCS_EXIT2(SEND, RTCSERR_SOCK_NOT_CONNECTED, RTCS_ERROR);
   } /* Endif */
#endif

   if (!((SOCKET_STRUCT_PTR)sock)->TCB_PTR) {
      RTCS_setsockerror(sock, RTCSERR_TCP_CONN_RLSD);
      RTCS_EXIT2(SEND, RTCSERR_TCP_CONN_RLSD, RTCS_ERROR);
   } /* Endif */

   if (flags == 0) {
      if (socket_ptr->SEND_NOWAIT) flags |= TCPO_NOWAIT;
      if (socket_ptr->SEND_WAIT)   flags |= TCPO_WAIT;
      if (socket_ptr->SEND_PUSH)   flags |= TCPO_PUSH;
   } /* Endif */

   parms.TCB_PTR    = socket_ptr->TCB_PTR;
   parms.SOCKET     = sock;
   parms.BUFFER_PTR = buffer;
   parms.BUFF_LENG  = buflen;
   parms.TIMEOUT    = socket_ptr->SEND_TIMEOUT;
   parms.OPTIONS    = flags;

    if(flags & (TCPO_NOWAIT|TCPO_WAIT)!= 0) /* TCPO_NOWAIT or TCPO_WAIT */
    {   
       error = RTCSCMD_issue(parms, TCP_Process_send);
       if (error)
       {
            RTCS_setsockerror(sock, error);
            RTCS_EXIT2(SEND, error, RTCS_ERROR);
       } 
     
       RTCS_EXIT2(SEND, RTCS_OK, parms.BUFF_LENG);
    }   
    else /* Default */
    {
        uint_32 result_length = 0;
        do
        {
            error = RTCSCMD_issue(parms, TCP_Process_send);
            if (error)
            {
                RTCS_setsockerror(sock, error);
                RTCS_EXIT2(SEND, error, RTCS_ERROR);
            } 
             
            if(parms.BUFF_LENG >0)
            {  
                result_length += parms.BUFF_LENG;
            }
            else
            {
                RTCS_selectset(&sock, 1, 1);
            }
            
            parms.BUFFER_PTR = (pointer) ((uint_32)(parms.BUFFER_PTR) + parms.BUFF_LENG);
            parms.BUFF_LENG  = buflen - result_length;
        }
        while(parms.BUFF_LENG > 0);
        
        RTCS_EXIT2(SEND, RTCS_OK, result_length);
    }

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_STREAM_recv
* Returned Value  : number of bytes received or RTCS_ERROR
* Comments  :  Receive data from a connected socket.
*
*END*-----------------------------------------------------------------*/

int_32  SOCK_STREAM_recv
   (
      uint_32        sock,
         /* [IN] socket handle */
      pointer        buffer,
         /* [IN] buffer for received data */
      uint_32        buflen,
         /* [IN] length of the buffer, in bytes */
      uint_32        flags
         /* [IN] flags to underlying protocols */
   )
{ /* Body */
            TCP_PARM             parms;
   register SOCKET_STRUCT_PTR    socket_ptr = (SOCKET_STRUCT_PTR)sock;
            uint_32              error;

   RTCS_ENTER(RECV, sock);

#if RTCSCFG_CHECK_ERRORS
   if (((SOCKET_STRUCT_PTR)sock)->STATE != SOCKSTATE_STREAM_CONNECTED) {
      RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_CONNECTED);
      RTCS_EXIT2(RECV, RTCSERR_SOCK_NOT_CONNECTED, RTCS_ERROR);
   } /* Endif */
#endif

   if (!((SOCKET_STRUCT_PTR)sock)->TCB_PTR) {
      RTCS_setsockerror(sock, RTCSERR_TCP_CONN_RLSD);
      RTCS_EXIT2(RECV, RTCSERR_TCP_CONN_RLSD, RTCS_ERROR);
   } /* Endif */

   if (flags == 0) {
      if (socket_ptr->RECEIVE_NOWAIT) flags |= TCPO_NOWAIT;
                                 else flags |= TCPO_WAIT;
      if (socket_ptr->RECEIVE_PUSH)   flags |= TCPO_PUSH;
   } /* Endif */

   parms.TCB_PTR    = socket_ptr->TCB_PTR;
   parms.SOCKET     = sock;
   parms.BUFFER_PTR = buffer;
   parms.BUFF_LENG  = buflen;
   parms.TIMEOUT    = socket_ptr->RECEIVE_TIMEOUT;
   parms.OPTIONS    = flags;

   error = RTCSCMD_issue(parms, TCP_Process_receive);
   if (error) {
      RTCS_setsockerror(sock, error);
  
      /* Start CR 2340 */
      /* If data was copied to the userbuf, but not all that
         the recv() asked for, and a timer was started that has
         now timed out, we need to return with the count, and not
         RTCS_ERROR */
      if (error == RTCSERR_TCP_TIMED_OUT) {
         /* rcvusernxt is the number of data bytes in rcvuserbuf.
            TCB comments say this is undefined in the special case 
            when rcvuserbuf == rcvbuf.  However, TCP_Setup_receive() 
            does not use the rcvuserbuf when there is a timeout.  So
            this test is not needed, but do it anyway to be safe. */
         if (parms.TCB_PTR->rcvuserbuf != parms.TCB_PTR->rcvbuf) {
            if (parms.TCB_PTR->rcvusernxt > 0) {
               RTCS_EXIT2(RECV, RTCS_OK, parms.TCB_PTR->rcvusernxt);
            }
         }
      }
      /* End CR 2340 */
      
      RTCS_EXIT2(RECV, error, RTCS_ERROR);
   } /* Endif */

   RTCS_EXIT2(RECV, RTCS_OK, parms.BUFF_LENG);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_STREAM_getsockname
* Returned Value  : error code
* Comments  :  Retrieve the address of the local endpoint of a
*              bound socket. Support IPv6 and IPv4.
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_STREAM_getsockname
   (
      uint_32              sock,
         /* [IN] socket handle */
      sockaddr _PTR_    name,
         /* [OUT] address of local endpoint */
      uint_16     _PTR_    namelen
         /* [IN/OUT] length of the address, in bytes */
   )
{ /* Body */

   RTCS_ENTER(GETSOCKNAME, sock);

#if RTCSCFG_CHECK_ERRORS
   if (((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_STREAM_GROUND) {
      RTCS_EXIT(GETSOCKNAME, RTCSERR_SOCK_NOT_BOUND);
   } /* Endif */
#endif

   if (!((SOCKET_STRUCT_PTR)sock)->TCB_PTR) {
      RTCS_EXIT(GETSOCKNAME, RTCSERR_TCP_CONN_RLSD);
   } /* Endif */


    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif
                if(!namelen) 
                {
        #if RTCSCFG_CHECK_ADDRSIZE
                }
                else if (*namelen < sizeof(sockaddr_in)) 
                {
                    sockaddr_in fullname;
                    fullname.sin_family      = AF_INET;
                    fullname.sin_port        = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->local_port;
                    fullname.sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->local_host;
                    _mem_copy(&fullname, name, *namelen);
                    *namelen = sizeof(sockaddr_in);
        #endif
                }
                else 
                {
                    ((sockaddr_in *)name)->sin_family      = AF_INET;
                    ((sockaddr_in *)name)->sin_port        = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->local_port;
                    ((sockaddr_in *)name)->sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->local_host;
                   *namelen = sizeof(sockaddr_in);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                if(!namelen) 
                {

        #if RTCSCFG_CHECK_ADDRSIZE
                } 
                else if (*namelen < sizeof(struct sockaddr_in6)) 
                {
                    struct sockaddr_in6 fullname;
                    fullname.sin6_family      = AF_INET6;
                    fullname.sin6_port        = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->local_port;
                    IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->TCB_PTR->local_ipv6_host,&(fullname.sin6_addr));
                    _mem_copy(&fullname,name, *namelen);
        #endif
                } 
                else 
                {
                    ((sockaddr_in6 *)name)->sin6_family   = AF_INET6;
                    ((sockaddr_in6 *)name)->sin6_port     = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->local_port;
                    IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->TCB_PTR->local_ipv6_host,&(((sockaddr_in6 *)name)->sin6_addr));
                } /* Endif */
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif

   RTCS_EXIT(GETSOCKNAME, RTCS_OK);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_STREAM_getpeername
* Returned Value  : error code
* Comments  :  Retrieve the address of the remote endpoint of a
*              connected socket. Support IPv4 and IPv6
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_STREAM_getpeername
   (
      uint_32                     sock,
         /* [IN] socket handle */
      struct sockaddr _PTR_   name,
         /* [IN] address of remote endpoint */
      uint_16     _PTR_           namelen
         /* [IN/OUT] length of the address, in bytes */
   )
{ /* Body */

   RTCS_ENTER(GETPEERNAME, sock);

#if RTCSCFG_CHECK_ERRORS
   if (((SOCKET_STRUCT_PTR)sock)->STATE != SOCKSTATE_STREAM_CONNECTED) 
   {
      RTCS_EXIT(GETPEERNAME, RTCSERR_SOCK_NOT_CONNECTED);
   } /* Endif */
#endif

   if (!((SOCKET_STRUCT_PTR)sock)->TCB_PTR) 
   {
      RTCS_EXIT(GETPEERNAME, RTCSERR_TCP_CONN_RLSD);
   } /* Endif */

   
#if RTCSCFG_ENABLE_IP4       

    #if RTCSCFG_ENABLE_IP6   //it is switch off if else  if only one family used    
    if (((SOCKET_STRUCT_PTR)sock)->AF ==AF_INET)
    {
    #endif
        if (!namelen) 
        {
     #if RTCSCFG_CHECK_ADDRSIZE
        } 
        else if (*namelen < sizeof(sockaddr_in)) 
        {
            sockaddr_in fullname;
            fullname.sin_family      = AF_INET;
            fullname.sin_port        = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->remote_port;
            fullname.sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->remote_host;
            _mem_copy(&fullname, name, *namelen);
            *namelen = sizeof(sockaddr_in);
     #endif
        } 
        else 
        {
            ((struct sockaddr_in*)name)->sin_family      = AF_INET;
            ((struct sockaddr_in*)name)->sin_port        = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->remote_port;
            ((struct sockaddr_in*)name)->sin_addr.s_addr = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->remote_host;
            *namelen = sizeof(sockaddr_in);
        } /* Endif */

    #if RTCSCFG_ENABLE_IP6   //it is switch off if else  if only one family used    
        goto rtcs_exit_0;
    }
    #endif

#endif

#if RTCSCFG_ENABLE_IP6       

    #if RTCSCFG_ENABLE_IP4   //it is switch off if else  if only one family used    
    else if (((SOCKET_STRUCT_PTR)sock)->AF ==AF_INET6)
    {
    #endif
        if (!namelen) 
        {

        #if RTCSCFG_CHECK_ADDRSIZE
        } 
        else if (*namelen < sizeof(struct sockaddr_in6)) 
        {
            struct sockaddr_in6 fullname;
            fullname.sin6_family      = AF_INET6;
            fullname.sin6_port        = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->remote_port;
            IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->TCB_PTR->remote_ipv6_host, &(fullname.sin6_addr));
            _mem_copy(&fullname, name, *namelen);
            *namelen = sizeof(struct sockaddr_in6);
        #endif
        } 
        else 
        {
            ((struct sockaddr_in6*)name)->sin6_family      = AF_INET6;
            ((struct sockaddr_in6*)name)->sin6_port        = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR->remote_port;
            IN6_ADDR_COPY(&((SOCKET_STRUCT_PTR)sock)->TCB_PTR->remote_ipv6_host, &(((struct sockaddr_in6*)name)->sin6_addr));
            *namelen = sizeof(struct sockaddr_in6);
        } /* Endif */

    #if RTCSCFG_ENABLE_IP4       
    }
    #endif
#endif      

rtcs_exit_0:

           RTCS_EXIT(GETPEERNAME, RTCS_OK);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_STREAM_shutdown
* Returned Value  : error code
* Comments  :  Close a socket.
*
*END*-----------------------------------------------------------------*/

uint_32  SOCK_STREAM_shutdown
   (
      uint_32        sock,
         /* [IN] socket handle */
      uint_32        how
         /* [IN] how to terminate the socket */
   )
{ /* Body */
   TCP_PARM    parms;
   uint_32     error;

   RTCS_ENTER(SHUTDOWN, sock);

   if (!((SOCKET_STRUCT_PTR)sock)->TCB_PTR) {
      RTCS_EXIT(SHUTDOWN, RTCS_OK);
   } /* Endif */

   parms.TCB_PTR = ((SOCKET_STRUCT_PTR)sock)->TCB_PTR;

   if (how == FLAG_ABORT_CONNECTION) {
      error = RTCSCMD_issue(parms, TCP_Process_abort);
   } else {
      error = RTCSCMD_issue(parms, TCP_Process_close);
   } /* Endif */

   if (error) {
      RTCS_EXIT(SHUTDOWN, error);
   } /* Endif */

   RTCS_EXIT(SHUTDOWN, RTCS_OK);

} /* Endbody */

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/Main.c<|end_filename|>
#include "App.h"

void LCD_task(uint_32 initial_data);
static void Measure_task(uint_32 initial_data);

const TASK_TEMPLATE_STRUCT  MQX_template_list[] =
{
  /* Task Index,    Function,                 Stack,  Priority,          Name,      Attributes,                                                           Param, Time Slice */
  { MOTISR_IDX,      Motor_ISR_task,           1000,   MOTISR_ID_PRIO,    "MotIsr",    MQX_FLOATING_POINT_TASK,                                             0,     0 },
  { CTRL_IDX,        Control_task,             1500,   CTRL_ID_PRIO,      "Ctrl",      MQX_FLOATING_POINT_TASK + MQX_AUTO_START_TASK,                       0,     0 },
  { MEAS_IDX,        Measure_task,             1500,   MEAS_ID_PRIO,      "Meas",      MQX_FLOATING_POINT_TASK,                                             0,     0 },
  { VT100_IDX,       VT100_task,               3000,   VT100_ID_PRIO,     "VT100",     MQX_FLOATING_POINT_TASK + MQX_TIME_SLICE_TASK,                       0,     2 },
  { LCD_IDX,         LCD_task,                 2000,   LCD_ID_PRIO,       "LCD",       MQX_FLOATING_POINT_TASK,                                             0,     0 },
  { CAN_TX_IDX,      CAN_Tx_Task,              1500,   CAN_TX_ID_PRIO,    "CAN_TX",    0,                                                                   0,     0 },
  { CAN_RX_IDX,      CAN_Rx_Task,              1500,   CAN_RX_ID_PRIO,    "CAN_RX",    MQX_FLOATING_POINT_TASK,                                             0,     0 },
  { 0 }
};


static float INT_smpl_to_current(int smpl);
static float INT_smpl_to_15v_meas(int smpl);
static float INT_smpl_to_5v_meas(int smpl);
static float INT_smpl_to_VBUS_meas(int smpl);
static float INT_smpl_to_Phase_meas(int smpl);
static float INT_smpl_to_Temper(int smpl);
static float INT_pwm_to_voltage(int smpl);

static float FLT_smpl_to_current(float smpl);
static float FLT_smpl_to_15v_meas(float smpl);
static float FLT_smpl_to_5v_meas(float smpl);
static float FLT_smpl_to_VBUS_meas(float smpl);
static float FLT_smpl_to_Phase_meas(float smpl);
static float FLT_smpl_to_Temper(float smpl);
static float FLT_pwm_to_voltage(float smpl);

static T_meas_results  meas_results[MEAS_RES_ARR_SZ];
static float           aver_curr_rms;
static unsigned int    aver_curr_cnt;

static MUTEX_STRUCT    meas_mutex;

const T_vals_scaling vscal[MEAS_RES_ARR_SZ] =
{
  { "ii_w  ", INT_smpl_to_current,    FLT_smpl_to_current    },
  { "ii_v  ", INT_smpl_to_current,    FLT_smpl_to_current    },
  { "ii_u  ", INT_smpl_to_current,    FLT_smpl_to_current    },
  { "v_bus ", INT_smpl_to_VBUS_meas,  FLT_smpl_to_VBUS_meas  },
  { "temper", INT_smpl_to_Temper,     FLT_smpl_to_Temper     },
  { "15v   ", INT_smpl_to_15v_meas,   FLT_smpl_to_15v_meas   },
  { "5v    ", INT_smpl_to_5v_meas,    FLT_smpl_to_5v_meas    },
  { "ii_u  ", INT_smpl_to_Phase_meas, FLT_smpl_to_Phase_meas },
  { "vv_w  ", INT_pwm_to_voltage,     FLT_pwm_to_voltage     },
  { "vv_v  ", INT_pwm_to_voltage,     FLT_pwm_to_voltage     },
  { "vv_u  ", INT_pwm_to_voltage,     FLT_pwm_to_voltage     },
}; 
/*
INT32U rms_log_pos; 
float meas_rms_log[MEAS_RES_ARR_SZ][MEAS_RES_LOG_SZ];
*/
float meas_stat_res[MEAS_RES_ARR_SZ];
/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
/*
INT32U  Reset_rms_log(void)
{
  rms_log_pos = 0;
  return rms_log_pos;
} 
*/ 
/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
/*
INT32U  Get_rms_log_pos(void)
{
  return rms_log_pos;
} 
*/ 
/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
/*
void Get_rms_log_arr(float **ptr)
{
  int i;
  for (i=0;i<MEAS_RES_ARR_SZ;i++)
  {
    ptr[i] = &meas_rms_log[i][0]; 
  }
}
*/

/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/
static void Create_meas_mutex(void)
{
  MUTEX_ATTR_STRUCT mutexattr;
  _mutatr_init(&mutexattr);
  _mutex_init(&meas_mutex, &mutexattr);
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void Control_task(uint_32 initial_data)
{
  unsigned int cycle_cnt;
  T_MC_CBL     *mc_pcbl;

  Led_control(LED1, 1);
  Led_control(LED2, 0);
  Led_control(LED3, 0);

  MC_create_event();
  Create_meas_mutex();
  TempCtrl_init_drivers();

  CAN_init(CAN0_BASE_PTR, CAN_SPEED);

  ADCs_prepare(); // Подготовка и калибровка АЦП


  _task_create(0, MEAS_IDX,  0);
  _task_create(0, VT100_IDX, 0);
  _task_create(0, LCD_IDX,   0);


  _time_delay(1000); // Делаем паузу для заряда конденсаторов
  NTC_bypass_control(1);
  _time_delay(100);  // Делаем задержку для переключения контактов реле
  Led_control(LED1, 0);

  MC_init_PWM();
  Pin_PWM_OE_int_install();
  Pin_VFO_int_install();
  IGBT_reg_control(1); // Разрешаем регистр сигналов IGBT
  _task_create(0, MOTISR_IDX, 0);

  _task_create(0, CAN_RX_IDX, (uint_32)CAN0_BASE_PTR); // Задачу CAN запускаем после готовности остальных задач к приему команд, во избежании конфликтов  
  _task_create(0, CAN_TX_IDX, (uint_32)CAN0_BASE_PTR);


  mc_pcbl = MC_get_pcbl();

  // Следим за событиями
//  MC_set_events(MOTOR_START_R);

  for (;;)
  {
    _mqx_uint events;

    if  ( MC_get_events(&events, 2, VFO_FALL | PWM_OE_RISE | MOTOR_STOP | MOTOR_START_DOWN | MOTOR_START_UP) == MQX_OK )
    {
      if ( events & VFO_FALL )
      {
        MC_emergency_stop_motor();

        mc_pcbl->motor_drv_fail = 1;
        mc_pcbl->fail_cnt++;
        _time_delay(5000); // После сигнала аварии делаем продолжительную паузу
        mc_pcbl->motor_drv_fail = 0;
      }
      else if ( events & PWM_OE_RISE )
      {
        // Разорвалась цепь безопасности
        
        MC_emergency_stop_motor();
      }
      else if ( events & MOTOR_STOP )
      {
        if ( mc_pcbl->direction == MOVING_DOWN )
        {
          MC_stop_motor_moving(mc_pcbl->down_deceler_time);
        }
        else
        {
          MC_stop_motor_moving(mc_pcbl->up_deceler_time);
        }
      }
      else if ( events & MOTOR_START_DOWN )
      {
        MC_start_motor_moving(MOVING_DOWN, mc_pcbl->down_move_freq, mc_pcbl->down_acceler_time);
      }
      else if ( events & MOTOR_START_UP )
      {
        MC_start_motor_moving(MOVING_UP, mc_pcbl->up_move_freq, mc_pcbl->up_acceler_time);
      }
    }
    else
    {
      Led_control(LED1, cycle_cnt);
      cycle_cnt++;
    }

  }


//  _task_block();
}


/*-----------------------------------------------------------------------------------------------------
  Чувствительность дачика тока 40 mV/A
-----------------------------------------------------------------------------------------------------*/
static float INT_smpl_to_current(int smpl)
{
  float s  = 0.04;    // Чувствительность датчика
  float sr = 0.6875;  // Аттенюация резистивного делителя
  return (float)smpl * 3.3 / (4096.0 * s * sr);
}
/*-----------------------------------------------------------------------------------------------------
  Чувствительность дачика тока 40 mV/A
-----------------------------------------------------------------------------------------------------*/
static float FLT_smpl_to_current(float smpl)
{
  float s  = 0.04;    // Чувствительность датчика
  float sr = 0.6875;  // Аттенюация резистивного делителя
  return smpl * 3.3 / (4096.0 * s * sr);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float INT_smpl_to_15v_meas(int smpl)
{
  float r1 = 4700.0;
  float r2 = 33000.0;
  return (float)smpl * 3.3 * (r1 + r2) * 1.013 / (r1 * 4096.0);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float FLT_smpl_to_15v_meas(float smpl)
{
  float r1 = 4700.0;
  float r2 = 33000.0;
  return (float)smpl * 3.3 * (r1 + r2) * 1.013 / (r1 * 4096.0);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float INT_smpl_to_5v_meas(int smpl)
{
  float r1 = 4700.0;
  float r2 = 4700.0;
  return (float)smpl * 3.3 * (r1 + r2) / (r1 * 4096.0);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float FLT_smpl_to_5v_meas(float smpl)
{
  float r1 = 4700.0;
  float r2 = 4700.0;
  return (float)smpl * 3.3 * (r1 + r2) / (r1 * 4096.0);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float INT_smpl_to_VBUS_meas(int smpl)
{
  float r1 = 2200.0;
  float r2 = 300000.0;
  return (float)smpl * 3.3 * (r1 + r2) * 0.964 / (r1 * 4096.0);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float FLT_smpl_to_VBUS_meas(float smpl)
{
  float r1 = 2200.0;
  float r2 = 300000.0;
  return (float)smpl * 3.3 * (r1 + r2) * 0.964 / (r1 * 4096.0);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float INT_smpl_to_Phase_meas(int smpl)
{
  float r1 = 2200.0;
  float r2 = 300000.0;
  return (float)smpl * 3.3 * (r1 + r2) / (r1 * 4096.0);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float FLT_smpl_to_Phase_meas(float smpl)
{
  float r1 = 2200.0;
  float r2 = 300000.0;
  return (float)smpl * 3.3 * (r1 + r2) / (r1 * 4096.0);
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float INT_smpl_to_Temper(int smpl)
{
  float t;
  t = (float)smpl * 3.3 / 4096.0;
  t = 25.0 - (t - 0.719) / 0.001715;
  return t;
}
/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
static float FLT_smpl_to_Temper(float smpl)
{
  float t;
  t = (float)smpl * 3.3 / 4096.0;
  t = 25.0 - (t - 0.719) / 0.001715;
  return t;
}
/*-----------------------------------------------------------------------------------------------------
  
-----------------------------------------------------------------------------------------------------*/
static float INT_pwm_to_voltage(int smpl)
{
  return (float)smpl ;
}
/*-----------------------------------------------------------------------------------------------------
  
-----------------------------------------------------------------------------------------------------*/
static float FLT_pwm_to_voltage(float smpl)
{
  return (float)smpl;
}


/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/

void Lock_meas_mutex(void)
{
  _mutex_lock(&meas_mutex);
} 
 
/*-------------------------------------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------------------------------------*/

void Unlock_meas_mutex(void)
{
  _mutex_unlock(&meas_mutex);
} 
 
/*-------------------------------------------------------------------------------------------------------------
  Задача выпоняющая измерения
-------------------------------------------------------------------------------------------------------------*/
static void Measure_task(uint_32 initial_data)
{
  signed short   *arr[MEAS_RES_ARR_SZ];
  unsigned int   n;
  unsigned int   i;
  unsigned int   sindx; // Стартовый индекс буфера
  T_meas_stat    stat;


  aver_curr_rms = 0;
  aver_curr_cnt = 0;
  for (;;)
  {
    
    _mqx_uint events;

    Lock_meas_mutex();
    if  ( MC_get_events(&events, 2, SMPL_ARR1_FULL + SMPL_ARR2_FULL) == MQX_OK )
    {
      // Обработать массив отсчетов

      // Получим указатели на массивы отсчетов
      ADC_get_smpl_arr(arr);
      sindx = 0;
      if ( events == SMPL_ARR2_FULL)
      {
        sindx = TST_SMPLS_ARR_SZ/2;
      }
      // Для каждого массива находим: минимум, максимум, среднее, среднеквадратическое
      // Выполнение этого блока длиться 4.8  мс
      for (n = 0; n < MEAS_RES_ARR_SZ; n++)
      {
        stat.maxv  = arr[n][sindx];
        stat.minv  = arr[n][sindx];
        stat.averv = 0;
        stat.rmsv  = 0;
        for (i = 0; i < (TST_SMPLS_ARR_SZ/2); i++)
        {
          if ( arr[n][i+sindx] > stat.maxv ) stat.maxv = arr[n][i+sindx];
          if ( arr[n][i+sindx] < stat.minv ) stat.minv = arr[n][i+sindx];
          stat.averv += arr[n][i+sindx];
          stat.rmsv  += arr[n][i+sindx] * arr[n][i+sindx];
        }
        stat.averv = stat.averv / (TST_SMPLS_ARR_SZ/2);
        stat.rmsv  = stat.rmsv / (TST_SMPLS_ARR_SZ/2);

        meas_results[n].fmax = vscal[n].int_converter(stat.maxv);
        meas_results[n].fmin = vscal[n].int_converter(stat.minv);
        meas_results[n].favr = vscal[n].int_converter(stat.averv);
        meas_results[n].frms = vscal[n].flt_converter(sqrt(stat.rmsv)); // sqrt выполняеться 756 тактов(6.3 мкс) включая перевод из double во float

      }
/*
      if ( rms_log_pos != MEAS_RES_LOG_SZ )
      {
        for (n = 0; n < MEAS_RES_ARR_SZ; n++)
        {
          meas_rms_log[n][rms_log_pos] = meas_results[n].frms;
        }
        rms_log_pos++;
      }
      ADC_reset_smpl_arr_pos();
*/ 
      {
        float  val = (meas_results[0].frms + meas_results[1].frms + meas_results[2].frms)/3;

        _int_disable();
         aver_curr_rms += val;
         aver_curr_cnt++; 
        _int_enable();
      }

      MC_set_events(MEAS_RES_READY);  
      

      Unlock_meas_mutex();
    }
  }
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
float Get_aver_curr(void)
{
  float val;
  _int_disable();
  val = aver_curr_rms/aver_curr_cnt;
  _int_enable();
  return val;
}

/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void  Reset_aver_curr(void)
{
  _int_disable();
  aver_curr_rms = 0;
  aver_curr_cnt = 0;
  _int_enable();
}
/*-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------*/
void Get_copy_meas_results(T_meas_results *mres)
{
  _task_stop_preemption();
  memcpy(mres, meas_results, sizeof(meas_results));
  _task_start_preemption();
}


/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
#define HIGH_TEMPER_BOUND  50
#define LOW_TEMPER_BOUND   40

#define STR_SZ 64
void LCD_task(uint_32 initial_data)
{
  T_meas_results     mres[8];
  float              temp;
  char               str[STR_SZ + 1];
  T_MC_CBL          *mc_pcbl;
  int                terr; // Флаг ошибки чтения температуры

  mc_pcbl = MC_get_pcbl();
  LCD_init();

  for (;;)
  {
    Get_copy_meas_results(mres);

    terr = 0;
    if (TempCtrl_read_IGBT_temperature(&temp)!=MQX_OK)
    {
      terr = 1;
    }
    
    if ( terr==0 )
    {
      // Управление вентилятором
      if ( temp > HIGH_TEMPER_BOUND )
      {
        Fun_control(1);
      }
      if ( temp < LOW_TEMPER_BOUND )
      {
        Fun_control(0);
      }
    }



    if ( mc_pcbl->motor_drv_fail == 0 )
    {
      LCD_clear_row(0);
      LCD_clear_row(1);
      if ( terr!=0 )
      {
        snprintf(str, STR_SZ, "T:----- DC:%.0f", mres[3].frms);
      }
      else
      {
        snprintf(str, STR_SZ, "T:%0.1f DC:%.0f", temp, mres[3].frms);
      }
      LCD_print_str(str, 0, 0);
      {
        float iaver = (mres[0].frms + mres[1].frms + mres[2].frms)/3;

        if ( mc_pcbl->fail_cnt != 0 )
        {
          snprintf(str, STR_SZ, "I:%4.1f Err.N:%d", iaver, mc_pcbl->fail_cnt);
        }
        else
        {
          snprintf(str, STR_SZ, "I:%4.1f ", iaver);
        }
      }
      LCD_print_str(str, 0, 1);
    }
    else
    {
      snprintf(str, STR_SZ, "****OVERLOAD****");
      LCD_print_str(str, 0, 0);
      snprintf(str, STR_SZ, "*****ERROR******");
      LCD_print_str(str, 0, 1);
    }

    _time_delay(500);
  }

}



<|start_filename|>Firmware/Inverter_firmware/shell/source/rtcs/sh_ipconfig.c<|end_filename|>
/**HEADER*******************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sh_ipconfig.c$
* $Version : 172.16.17.32$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Example using RTCS Library.
*
*END************************************************************************/


#include <mqx.h>
#include "shell.h"
#if SHELLCFG_USES_RTCS

#include <bsp.h>
#include <rtcs.h>
#include <enet.h>
#include <ipcfg.h>


#include "sh_rtcs.h"
#include "sh_enet.h"
#include "string.h"

#ifdef BSP_ENET_DEVICE_COUNT
#if  (BSP_ENET_DEVICE_COUNT > 0)

static int_32 Shell_ipconfig_status (uint_32 enet_device)
{
    IPCFG_STATE             state;
    boolean                 link;
    boolean                 task;
    _enet_address           mac = {0};
    IPCFG_IP_ADDRESS_DATA   ip_data ;
#if RTCSCFG_IPCFG_ENABLE_DNS
    _ip_address             dns;
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT
    _ip_address             tftp_serveraddress;
    uchar_ptr               tftp_servername;
    uchar_ptr               boot_filename;
#endif


#if RTCSCFG_ENABLE_IP6
    uint_32                 result,n=0,i=0;
    IPCFG6_GET_ADDR_DATA    data[RTCSCFG_IP6_IF_ADDRESSES_MAX];
    char prn_addr6[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
#endif


    state = ipcfg_get_state (enet_device);
    if (state != IPCFG_STATE_INIT)
    {
        link = ipcfg_get_link_active (enet_device);
        task = ipcfg_task_status ();
        ipcfg_get_mac (enet_device, mac);
        ipcfg_get_ip (enet_device, &ip_data);

/* It take amount of addresses for device and store it to n */
#if RTCSCFG_ENABLE_IP6
    n=0;
    while(!ipcfg6_get_addr_info_n (enet_device, n,&data[n]))
    {
       // printf("ai_addr_in->sin6_addr      = %X...h\n", data[n].ip_addr);
        n++;
    }
#endif

#if RTCSCFG_IPCFG_ENABLE_DNS
        dns = ipcfg_get_dns_ip (enet_device, 0);
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT
        tftp_serveraddress = ipcfg_get_tftp_serveraddress (enet_device);
        tftp_servername = ipcfg_get_tftp_servername (enet_device);
        boot_filename = ipcfg_get_boot_filename (enet_device);
#endif
        printf ("Eth#: %d\n", enet_device);
        printf ("Link: %s\n", link ? "on" : "off");
        printf ("MAC : %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

#if RTCSCFG_ENABLE_IP4
        printf ("IP4 : %d.%d.%d.%d type: %s\n", IPBYTES(ip_data.ip), ipcfg_get_state_string (state) );
#endif

/************************************************/
#if RTCSCFG_ENABLE_IP6
        i=0;
        while(i<n)
  	    {
  	        if(inet_ntop(AF_INET6,&data[i].ip_addr, prn_addr6, sizeof(prn_addr6)))
		    {
		        printf("IP6 : %s ",prn_addr6);
                /* IPv6 address state */
  		        if(data[i].ip_addr_state==IP6_ADDR_STATE_PREFERRED)
		        {
		            printf("state: PREFERRED, ");
		        }
		        else if(data[i].ip_addr_state==IP6_ADDR_STATE_TENTATIVE)
		        {
		            printf("state: TENTATIVE, ");
		        }
   		        else if(data[i].ip_addr_state==IP6_ADDR_STATE_NOT_USED)
		        {
		            printf("state: NOT_USED, ");
		        }
		        else
                {
                    printf("state: %d, ",data[i].ip_addr_state);
                }
                /* IPv6 address type */
		        if(data[i].ip_addr_type==IP6_ADDR_TYPE_MANUAL)
		        {
		            printf("type: MANUAL\n");
		        }
		        else if(data[i].ip_addr_type==IP6_ADDR_TYPE_AUTOCONFIGURABLE)
		        {
		            printf("type: AUTOCONFIGURABLE\n");
		        }
		        else
                {
                    printf("type: %d\n",data[i].ip_addr_type);
                }
		    }
		    else
		    {
		        printf("IPv6 : ERROR IP CONVERT\n");
		    }
		    i++;
        }
#endif
/************************************************/

#if RTCSCFG_ENABLE_IP4


        printf ("MASK: %d.%d.%d.%d\n", IPBYTES(ip_data.mask));
#if RTCSCFG_ENABLE_GATEWAYS
        printf ("GATE: %d.%d.%d.%d\n", IPBYTES(ip_data.gateway));
#endif
#if RTCSCFG_IPCFG_ENABLE_DNS
        printf ("DNS1: %d.%d.%d.%d\n", IPBYTES(dns));
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT
        printf ("TFTP: %d.%d.%d.%d '%s'\n", IPBYTES(tftp_serveraddress), tftp_servername);
        printf ("BOOT: '%s'\n", boot_filename);
#endif

#endif //RTCSCFG_ENABLE_IP4
        printf ("Link status task %s\n", task ? "running" : "stopped");
    }
    else
    {
        printf ("Ethernet device %d not yet initialized.\n", enet_device);
    }
    return SHELL_EXIT_SUCCESS;
}



static int_32 Shell_ipconfig_init (uint_32 enet_device, uint_32 index, int_32 argc, char_ptr argv[])
{
    uint_32         error;
    _enet_address   mac;

    ipcfg_get_mac(enet_device, mac);
    mac[5] += enet_device;

    if (argc > ++index)
    {
        if (! Shell_parse_enet_address(argv[index], mac))
        {
            printf ("Error init ethernet device %d, invalid MAC address!\n", enet_device);
            return SHELL_EXIT_ERROR;
        }
    }

    error = ipcfg_init_device (enet_device, mac);
    if (error != 0)
    {
        printf ("Error init ethernet device %d, interface error %08x!\n", enet_device, error);
        return SHELL_EXIT_ERROR;
    }

    printf ("Ethernet device %d initialization successful.\n", enet_device);
    return SHELL_EXIT_SUCCESS;
}

static int_32 Shell_ipconfig_release (uint_32 enet_device, uint_32 index, int_32 argc, char_ptr argv[])
{
    uint_32         error;
    _enet_address   mac;

    error = ipcfg_release_device (enet_device);
    if (error != 0)
    {
        printf ("Error release ethernet device %d, error %08x!\n", enet_device, error);
        return SHELL_EXIT_ERROR;
    }

    printf ("Ethernet device %d release successful.\n", enet_device);
    return SHELL_EXIT_SUCCESS;
}



static int_32 Shell_ipconfig_task (uint_32 enet_device, uint_32 index, int_32 argc, char_ptr argv[])
{
    uint_32 error;
    uint_32 priority;
    uint_32 period;

    if (argc > ++index)
    {
        if (strcmp (argv[index], "start") == 0)
        {
            if (argc > ++index)
            {
                if (! Shell_parse_number(argv[index], &priority))
                {
                    printf ("Error in task command, invalid priority parameter!\n");
                    return SHELL_EXIT_ERROR;
                }
            }
            else
            {
                printf ("Error in task command, missing priority parameter!\n");
                return SHELL_EXIT_ERROR;
            }

            if (argc > ++index)
            {
                if (! Shell_parse_number(argv[index], &period))
                {
                    printf ("Error in task command, invalid priority parameter!\n");
                    return SHELL_EXIT_ERROR;
                }
            }
            else
            {
                printf ("Error in task command, missing period parameter!\n");
                return SHELL_EXIT_ERROR;
            }

            error = ipcfg_task_create (priority, period);
            if (error != 0)
            {
                printf ("Error in task command, create failed!\n", enet_device, error);
                return SHELL_EXIT_ERROR;
            }
        }
        else if (strcmp (argv[index], "stop") == 0)
        {
            ipcfg_task_destroy (TRUE);
        }
        else
        {
            printf ("Error in task command, invalid parameter!\n");
            return SHELL_EXIT_ERROR;
        }
    }

    printf ("Link status task %s\n", ipcfg_task_status () ? "running" : "stopped");
    return SHELL_EXIT_SUCCESS;
}



#if RTCSCFG_IPCFG_ENABLE_DNS
static int_32 Shell_ipconfig_dns (uint_32 enet_device, uint_32 index, int_32 argc, char_ptr argv[])
{
    uint_32     i;
    _ip_address dns = 0;

    if (argc > ++index)
    {
        if (strcmp (argv[index], "add") == 0)
        {
            if (argc > ++index)
            {
                if (! Shell_parse_ip_address (argv[index], &dns))
                {
                    printf ("Error in dns command, invalid ip address!\n");
                    return SHELL_EXIT_ERROR;
                }
                if (ipcfg_add_dns_ip (enet_device, dns))
                {
                    printf ("Add dns ip successful.\n");
                }
                else
                {
                    printf ("Add dns ip failed!\n");
                    return SHELL_EXIT_ERROR;
                }
            }
            else
            {
                printf ("Error in dns command, missing ip parameter!\n");
                return SHELL_EXIT_ERROR;
            }
        }
        else if (strcmp (argv[index], "del") == 0)
        {
            if (argc > ++index)
            {
                if (! Shell_parse_ip_address (argv[index], &dns))
                {
                    printf ("Error in dns command, invalid ip address!\n");
                    return SHELL_EXIT_ERROR;
                }
                if (ipcfg_del_dns_ip (enet_device, dns))
                {
                    printf ("Del dns ip successful.\n");
                }
                else
                {
                    printf ("Del dns ip failed!\n");
                    return SHELL_EXIT_ERROR;
                }
            }
            else
            {
                printf ("Error in dns command, missing ip parameter!\n");
                return SHELL_EXIT_ERROR;
            }
        }
        else
        {
            printf ("Error in dns command, unknown parameter!\n");
            return SHELL_EXIT_ERROR;
        }

    }
    else
    {
        for (i = 0, dns = ipcfg_get_dns_ip (enet_device, i); dns != 0 ; i++, dns = ipcfg_get_dns_ip (enet_device, i))
        {
            printf ("%d: %d.%d.%d.%d\n", i + 1, IPBYTES(dns));
        }
    }

    return SHELL_EXIT_SUCCESS;
}
#endif



static int_32 Shell_ipconfig_staticip (uint_32 enet_device, uint_32 index, int_32 argc, char_ptr argv[])
{
    uint_32                 error;

#if RTCSCFG_ENABLE_IP4
    IPCFG_IP_ADDRESS_DATA   ip_data;
#endif


#if RTCSCFG_ENABLE_IP6
    /*IPv6 adds*/
    struct addrinfo         hints;          // used for getaddrinfo()
    struct addrinfo         * addrinfo_res; // used for getaddrinfo()
    IPCFG6_BIND_ADDR_DATA	ip6_bind_data;  // structure for bind interface
    in6_addr                ip6;
#endif
    /* Here we need validate IP address and detect it family */
    /* Dont forget destroy addrinfo_res by freeaddrinfo(addrinfo_res) */


#if RTCSCFG_ENABLE_IP6

    memset(&hints,0,sizeof(hints));
    hints.ai_family 	= AF_UNSPEC;
    hints.ai_socktype 	= SOCK_DGRAM;
    hints.ai_flags 		= AI_NUMERICHOST|AI_CANONNAME;
    if (getaddrinfo ( argv[index+1], NULL, &hints, &addrinfo_res) != 0)
    {
        printf("GETADDRINFO error\n");
		return(SHELL_EXIT_ERROR); // we can return right here and do not need free freeaddrinfo(addrinfo_res)
	}
	if(addrinfo_res->ai_family == AF_INET6)
	{
        IN6_ADDR_COPY(&((struct sockaddr_in6 *)((*addrinfo_res).ai_addr))->sin6_addr,&ip6_bind_data.ip_addr);
        ip6_bind_data.ip_addr_type = IP6_ADDR_TYPE_MANUAL;
        freeaddrinfo(addrinfo_res);



        error = ipcfg6_bind_addr (enet_device, &ip6_bind_data);
        if (error != RTCS_OK)
        {
            printf("\nIPCFG Bind IP6(1) is failed, error = %X\n", error);
            return SHELL_EXIT_ERROR;
        }
        printf ("IP6 bind successful.\n");
        return SHELL_EXIT_SUCCESS;
	}
 #if RTCSCFG_ENABLE_IP4

    else if(addrinfo_res->ai_family == AF_INET)
    {
        freeaddrinfo(addrinfo_res);
 #endif

#endif //RTCSCFG_ENABLE_IP6

    #if RTCSCFG_ENABLE_IP4

        if (argc > ++index)
        {
            if (! Shell_parse_ip_address (argv[index], &ip_data.ip))
            {
                printf ("Error in static ip command, invalid ip address!\n");
                return SHELL_EXIT_ERROR;
            }
        }
        else
        {
            printf ("Error in static ip command, missing ip address parameter!\n");
            return SHELL_EXIT_ERROR;
        }

        if (argc > ++index)
        {
            if (! Shell_parse_ip_address (argv[index], &ip_data.mask))
            {
                printf ("Error in static ip command, invalid mask!\n");
                return SHELL_EXIT_ERROR;
            }
        }
        else
        {
            printf ("Error in static ip command, missing mask parameter!\n");
            return SHELL_EXIT_ERROR;
        }

#if RTCSCFG_ENABLE_GATEWAYS
        if (argc > ++index)
        {
            if (! Shell_parse_ip_address (argv[index], &ip_data.gateway))
            {
                printf ("Error in static ip command, invalid gateway!\n");
                return SHELL_EXIT_ERROR;
            }
        }
#endif

        error = ipcfg_bind_staticip (enet_device, &ip_data);
        if (error != 0)
        {
            printf ("Error during static ip bind %08x!\n", error);
            return SHELL_EXIT_ERROR;
        }

        printf ("Static IP4 bind successful.\n");
        return SHELL_EXIT_SUCCESS;
     #endif


#if RTCSCFG_ENABLE_IP6
    #if RTCSCFG_ENABLE_IP4
    }//end if family
    #endif
    printf ("Static bind unsuccessful. Unknown family detected.\n");
    return SHELL_EXIT_ERROR;
#endif


}




#if RTCSCFG_IPCFG_ENABLE_DHCP
static int_32 Shell_ipconfig_dhcp (uint_32 enet_device, uint_32 index, int_32 argc, char_ptr argv[])
{
    uint_32                     error;
    IPCFG_IP_ADDRESS_DATA       auto_ip_data;
    boolean                     auto_ip = FALSE ;

    if (argc > ++index)
    {
        if (strcmp (argv[index], "noauto") == 0)
        {
            auto_ip = FALSE;
        }
        else
        {
            if (! Shell_parse_ip_address (argv[index], &auto_ip_data.ip))
            {
                printf ("Error in dhcp command, invalid ip address!\n");
                return SHELL_EXIT_ERROR;
            }

            if (argc > ++index)
            {
                if (! Shell_parse_ip_address (argv[index], &auto_ip_data.mask))
                {
                    printf ("Error in dhcp command, invalid mask!\n");
                    return SHELL_EXIT_ERROR;
                }
            }
            else
            {
                printf ("Error in dhcp command, missing mask parameter!\n");
                return SHELL_EXIT_ERROR;
            }

#if RTCSCFG_ENABLE_GATEWAYS
            if (argc > ++index)
            {
                if (! Shell_parse_ip_address (argv[index], &auto_ip_data.gateway))
                {
                    printf ("Error dhcp command, invalid gateway!\n");
                    return SHELL_EXIT_ERROR;
                }
            }
            else
            {
                printf ("Error in dhcp command, missing gateway parameter!\n");
                return SHELL_EXIT_ERROR;
            }
#endif
            auto_ip = TRUE;
        }
    }

    error = ipcfg_bind_dhcp_wait (enet_device, auto_ip, &auto_ip_data);
    if (error != IPCFG_OK)
    {
        printf ("Error during dhcp bind %08x!\n", error);
        return SHELL_EXIT_ERROR;
    }

    printf ("Bind via dhcp successful.\n");
    return SHELL_EXIT_SUCCESS;
}
#endif

static int_32 Shell_ipconfig_unbind (uint_32 enet_device)
{
    uint_32 error;

    error = ipcfg_unbind (enet_device);
    if (error != 0)
    {
        printf ("Error during unbind %08x!\n", error);
        return SHELL_EXIT_ERROR;
    }

    printf ("Unbind successful.\n");
    return SHELL_EXIT_SUCCESS;
}

#if RTCSCFG_ENABLE_IP6
/* undind IP6 address on device */
static int_32 Shell_ipconfig_unbind6 (uint_32 enet_device, uint_32 index, int_32 argc, char_ptr argv[])
{
    uint_32                 error;
    IPCFG6_UNBIND_ADDR_DATA ip6_data;
    struct addrinfo         hints;          // used for getaddrinfo()
    struct addrinfo         * addrinfo_res; // used for getaddrinfo()

    /* Here we need validate IP address and detect it family */
    memset(&hints,0,sizeof(hints));
    hints.ai_family 	= AF_UNSPEC;
    hints.ai_socktype 	= SOCK_DGRAM;
    hints.ai_flags 		= AI_NUMERICHOST|AI_CANONNAME;
    if (getaddrinfo ( argv[index+1], NULL, &hints, &addrinfo_res) != 0)
    {
        printf("GETADDRINFO error\n");
		return(SHELL_EXIT_ERROR); // we can return right here and do not need free freeaddrinfo(addrinfo_res)
	}
	if(addrinfo_res->ai_family == AF_INET6)
	{
        IN6_ADDR_COPY(&((struct sockaddr_in6 *)((*addrinfo_res).ai_addr))->sin6_addr,&ip6_data.ip_addr);
        freeaddrinfo(addrinfo_res);

        error = ipcfg6_unbind_addr ( enet_device, &ip6_data);
        if (error != 0)
        {
            printf ("Error during unbind %08x!\n", error);
            return SHELL_EXIT_ERROR;
        }
        printf ("Unbind successful.\n");
        return SHELL_EXIT_SUCCESS;
    }
        printf ("Unbind unsuccessful. Unexpected inet family\n");
        return SHELL_EXIT_SUCCESS;
}
#endif



static int_32 Shell_ipcfg_phy_registers(uint_32 enet_device)
{
    uint_32  i,regs[32];

    if (ipcfg_phy_registers (enet_device,32,regs))
    {
    printf ("Phy registers.\n");
    for (i=0;i<32;i++) {
       printf("Register %2d = 0x%04x\n",i,regs[i]);
    }
   } else {
        printf ("Error reading phy registers!\n");
    }
    return SHELL_EXIT_SUCCESS;
}






/*TASK*-----------------------------------------------------------------
*
* Function Name  : Shell_ipconfig
* Returned Value : void
* Comments       :
*
*END------------------------------------------------------------------*/

int_32 Shell_ipconfig(int_32 argc, char_ptr argv[] )
{ /* Body */
    boolean                 print_usage, shorthelp = FALSE;
    int_32                  return_code = SHELL_EXIT_SUCCESS;
    uint_32                 enet_device = BSP_DEFAULT_ENET_DEVICE;
    uint_32                 index = 1;

    print_usage = Shell_check_help_request (argc, argv, &shorthelp);

    if (!print_usage)
    {
        if (argc > index)
        {
            if (Shell_parse_number (argv[index], &enet_device))
            {
                index++;
            }
        }

        if (enet_device >= BSP_ENET_DEVICE_COUNT)
        {
            printf ("Wrong number of ethernet device (%d)!\n", enet_device);
            return_code = SHELL_EXIT_ERROR;
        }
        else
        {
            if (argc > index)
            {
                if (strcmp (argv[index], "init") == 0)
                {
                    return_code = Shell_ipconfig_init (enet_device, index, argc, argv);
                }
                else if (strcmp (argv[index], "release") == 0)
                {
                    return_code = Shell_ipconfig_release (enet_device, index, argc, argv);
                }
                else if (strcmp (argv[index], "task") == 0)
                {
                    return_code = Shell_ipconfig_task (enet_device, index, argc, argv);
                }
#if RTCSCFG_IPCFG_ENABLE_DNS
                else if (strcmp (argv[index], "dns") == 0)
                {
                    return_code = Shell_ipconfig_dns (enet_device, index, argc, argv);
                }
#endif
                else if (strcmp (argv[index], "ip") == 0)
                {
                    return_code = Shell_ipconfig_staticip (enet_device, index, argc, argv);
                }
#if RTCSCFG_IPCFG_ENABLE_DHCP
                else if (strcmp (argv[index], "dhcp") == 0)
                {
                    return_code = Shell_ipconfig_dhcp (enet_device, index, argc, argv);
                }
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT
                else if (strcmp (argv[index], "boot") == 0)
                {
                    return_code = Shell_ipconfig_boot (enet_device);
                }
#endif
                else if (strcmp (argv[index], "unbind") == 0)
                {


            #if RTCSCFG_ENABLE_IP6
                #if RTCSCFG_ENABLE_IP4
                    if(argc > 2)
                    {
                #endif
                       return_code = Shell_ipconfig_unbind6 (enet_device, index, argc, argv);
                #if RTCSCFG_ENABLE_IP4
                    }
                    else
                    {
                #endif
            #endif

            #if RTCSCFG_ENABLE_IP4
                        return_code = Shell_ipconfig_unbind (enet_device);
            #endif

            #if RTCSCFG_ENABLE_IP6
                 #if RTCSCFG_ENABLE_IP4
                    }
                 #endif
            #endif

                }
                else if (strcmp (argv[index], "phyinfo") == 0)
                {
                    return_code = Shell_ipcfg_phy_registers (enet_device);
                }
                else
                {
                    printf ("Unknown ipconfig command!\n");
                    return_code = SHELL_EXIT_ERROR;
                }
            }
            else
            {
                return_code = Shell_ipconfig_status (enet_device);
            }
        }
    }

    if ((print_usage) || (return_code != SHELL_EXIT_SUCCESS))
    {
        if (shorthelp)
        {
            printf ("%s [<device>] [<command>]\n", argv[0]);
        }
        else
        {
            printf ("Usage: %s [<device>] [<command>]\n", argv[0]);
            printf ("  Commands:\n");

            printf ("    init [<mac>]\n");
            printf ("        Initialize ethernet device (once).\n");
            printf ("    release\n");
            printf ("        Release ethernet device (once).\n");
            printf ("    task [start <priority> <period> | stop]\n");
            printf ("        Manage link status checking task.\n");

#if RTCSCFG_IPCFG_ENABLE_DNS
            printf ("    dns [add <ipv4> | del <ipv4>]\n");
            printf ("        Manage dns ip list. IPv4 only.\n");
#endif
            printf ("    ip <ip> <mask> [<gateway>]\n");
            printf ("        Bind with ip for IPv4. For IPv6 you should put ipv6 address only.\n");
            printf ("        Like \'ip <ipv6>\' to  bind IPv6 address manually.\n");

#if RTCSCFG_IPCFG_ENABLE_DHCP
            printf ("    dhcp [<ipv4> <mask> [<gateway>]]\n");
            printf ("        Bind with dhcp [use <ip> & <mask> in case dhcp fails].\n");
            printf ("        Support IPv4 only.\n");
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT
            printf ("    boot\n");
            printf ("        Bind with boot protocol.\n");
#endif
            printf ("    unbind [<ipv6>]\n");
            printf ("        Unbind network interface. Using \'unbind\' without parameter\n");
            printf ("        will unbind IPv4 address from interface. In case IPv6 you should\n");
            printf ("        use ipv6 address like parameter to unbind it from interface.\n");


            printf ("  Parameters:\n");
            printf ("    <device>   = Ethernet device number (default %d).\n", BSP_DEFAULT_ENET_DEVICE);
            printf ("    <mac>      = Ethernet MAC address.\n"  );
            printf ("    <priority> = Link status task MQX priority.\n");
            printf ("    <period>   = Link status task check period (ms).\n");
            printf ("    <ip>       = IP address to use both familys. \n");
            printf ("    <ipv4>     = IPv4 address to use. \n");
            printf ("    <ipv6>     = IPv6 address to use. \n");
            printf ("    <mask>     = Network mask to use. \n");
            printf ("    <gateway>  = Network gateway to use.\n");
        }
    }

    return return_code;
} /* Endbody */
#else /* (BSP_ENET_DEVICE_COUNT > 0) */
int_32 Shell_ipconfig(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;
}
#endif /* (BSP_ENET_DEVICE_COUNT > 0) */
#else /* BSP_ENET_DEVICE_COUNT */
int_32 Shell_ipconfig(int_32 argc, char_ptr argv[] )
{
   printf ("Cannot use this command, no enet device driver available in this BSP.");
   return SHELL_EXIT_ERROR;
}
#endif /* BSP_ENET_DEVICE_COUNT */
#endif /* SHELLCFG_USES_RTCS */
/* EOF */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/edserprv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: edserprv.h$
* $Version : 3.6.5.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   Serial Embedded Debug Server private header file
*
*END************************************************************************/
#ifndef __edserprv_h__
#define __edserprv_h__

#include "fio.h"
#include "pcb.h"

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* Define the following to send a space character after each byte */
/* #define EDS_USE_DEBUG_SPACES */

/* Define the following for extra debug information */
/* #define DO_DEBUG */
#ifdef DO_DEBUG
#define DEBUGM(x) x
#define EDS_USE_DEBUG_SPACES 
#else
#define DEBUGM(x)
#undef EDS_USE_DEBUG_SPACES 
#endif

/* Private defines */

/* The eds task message queue number for ipc operation */
#define EDS_IPC_MESSAGE_QUEUE_NUMBER  (2)

/* ED Serial Task info */
#define EDS_SERIAL_STACK_SIZE            1500L
#define EDS_SERIAL_TASK_NAME             "EDS_Serial_task"

/* server operations */
#define EDS_IDENTIFY               1
#define EDS_LITTLE_ENDIAN_IDENTIFY 0x80000000 /* PRIVATE */
#define EDS_READ                   2
#define EDS_WRITE                  3
#define EDS_CHANGE_PROCESSOR       4
#define EDS_CONFIG_MULTIPROC       5

#define EDS_BIG_ENDIAN      0
#define EDS_LITTLE_ENDIAN   0xFFFFFFFF

/* Start and end of frame characters */
#define STX                 0x02
#define ETX                 0x03

/* Receive states */
#define STATE_WAIT_STX      0x0001
#define STATE_WAIT_NON_STX  0x0002
#define STATE_GETTING_DATA  0x0003

/* error codes */
#define EDS_OK              0
#define EDS_INVALID_OP      1
#define EDS_INVALID_SIZE    2

#define EDS_OP_STRUCT_SIZE  (sizeof(EDS_OP_STRUCT))
#define EDS_BUFFER_SIZE     (128)

#define EDS_PROC_DEF_STRUCT_SIZE  (sizeof(EDS_PROC_DEF_STRUCT))

#define EDS_SERIAL_VALID    ((_mqx_uint)0x65647373)   /* "edss" */

/* Macros */
#if (PSP_MEMORY_ADDRESSING_CAPABILITY != 8)
   #if (PSP_MEMORY_ADDRESSING_CAPABILITY == 32)
      #define UNPACK(src,dest,size) \
         { \
            uint_32 i; \
            uint_32 _PTR_ src_lp;\
            uchar   _PTR_ dest_lp;\
            src_lp = (src);\
            dest_lp = (dest);\
            for(i = 0; i < (size); i+=4) { \
               htonl(dest_lp,*src_lp);\
               src_lp++;\
               dest_lp+=4;\
            }\
         }
      #define PACK(src,dest,size) \
         { \
            uint_32 i; \
            uchar  _PTR_ src_lp;\
            uchar  _PTR_ dest_lp;\
            src_lp = (src);\
            dest_lp = (dest);\
            for(i = 0; i < (size); i+=4) { \
               *dest_lp = ntohl(src_lp);\
               dest_lp++;\
               src_lp +=4;\
            }\
         }
   #elif (PSP_MEMORY_ADDRESSING_CAPABILITY == 24)
      #define UNPACK(src,dest,size) \
         { \
            uint_24 i; \
            uint_24 _PTR_ src_lp;\
            uchar   _PTR_ dest_lp;\
            src_lp = (src);\
            dest_lp = (dest);\
            for(i = 0; i < (size); i+=3) { \
               htonls(dest_lp,*src_lp);\
               src_lp++;\
               dest_lp+=3;\
            }\
         }
      #define PACK(src,dest,size) \
         { \
            uint_24 i; \
            uchar _PTR_  src_lp;\
            uchar  _PTR_ dest_lp;\
            src_lp = (src);\
            dest_lp = (dest);\
            for(i = 0; i < (size); i+=3) { \
               *dest_lp = ntohls(src_lp);\
               dest_lp++;\
               src_lp +=3;\
            }\
         }
   #elif (PSP_MEMORY_ADDRESSING_CAPABILITY == 16)
      #define UNPACK(src,dest,size) \
         { \
            uint_16 i; \
            uint_16 _PTR_ src_lp;\
            uchar   _PTR_ dest_lp;\
            src_lp = (src);\
            dest_lp = (dest);\
            for(i = 0; i < (size); i+=2) { \
               htons(dest_lp,*src_lp);\
               src_lp++;\
               dest_lp+=2;\
            }\
         }
      #define PACK(src,dest,size) \
         { \
            uint_16 i; \
            uchar _PTR_  src_lp;\
            uchar  _PTR_ dest_lp;\
            src_lp = (src);\
            dest_lp = (dest);\
            for(i = 0; i < (size); i+=2) { \
               *dest_lp = ntohs(src_lp);\
               dest_lp++;\
               src_lp +=2;\
            }\
         }
   #else
      #error "Memory type not understood"
   #endif

   #define READ_BYTES(src,dest,size)   UNPACK(src,dest,size)
   #define WRITE_BYTES(src,dest,size)  PACK(src,dest,size)

#else 
   #define READ_BYTES(dest,src,size)   _mem_copy(dest,src,size)
   #define WRITE_BYTES(dest,src,size)  _mem_copy(dest,src,size)
#endif

/*--------------------------------------------------------------------------*/
/*                      DATA STRUCTURE DEFINITIONS                          */

/* Structures */
/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief Operation structure
 */ 
typedef struct op_struct {
   /*! \brief Server operation. */
   uchar OPERATION[4];   
   /*! \brief Read/write memory address. */
   uchar ADDRESS[4];     
   /*! \brief Extra address field. */
   uchar ADDRESS2[4];    
   /*! \brief Size of buffer. */
   uchar SIZE[4];        
   /*! \brief Processor type. */
   uchar PROCESSOR[4];   
   /*! \brief Endian of processor. */
   uchar ENDIAN[4];      
   /*! \brief Error code. */
   uchar EDS_ERROR[4];   
} EDS_OP_STRUCT, _PTR_ EDS_OP_STRUCT_PTR;
/*! \endcond */

/*!
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief EDS data structure.
 */ 
typedef struct eds_data_struct {
   /*! \brief EDS operation data structure. */
   EDS_OP_STRUCT  EDS_OP_DATA;
   /*! \brief Buffer. Size is specified by EDS_BUFFER_SIZE. */
   uchar          BUFFER[EDS_BUFFER_SIZE];
} EDS_DATA_STRUCT, _PTR_ EDS_DATA_STRUCT_PTR;
/*! \endcond */

/*! 
 * \cond DOXYGEN_PRIVATE
 *  
 * \brief Structure used to define a processor. 
 */
typedef struct eds_proc_def_struct {
   /*! \brief Endian of processor. */
   uchar        ENDIAN[4];
   uchar        KD_START[4];
   uchar        KD_END[4];
   /*! \brief Processor number. */
   uchar        PROC_NUM[4];
   /*! \brief CPU type. */
   uchar        CPU_TYPE[4];
} EDS_PROC_DEF_STRUCT, _PTR_ EDS_PROC_DEF_STRUCT_PTR;
/*! \endcond */

/*!
 * \cond DOXYGEN_PRIVATE
 */ 
typedef struct eds_proc_reg_struct {
   EDS_PROC_DEF_STRUCT   PROC_DATA;
   QUEUE_ELEMENT_STRUCT  LIST;
} EDS_PROC_REG_STRUCT, _PTR_ EDS_PROC_REG_STRUCT_PTR;
/*! \endcond */

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief EDS component structure.
 */ 
typedef struct eds_component_struct
{
   /*! \brief Lightweight semaphore. */
   LWSEM_STRUCT SEM;
   /*! \brief state flag. */
   _mqx_uint     STATE;
   /*! \brief Valid flag. */
   _mqx_uint     VALID;
} EDS_COMPONENT_STRUCT, _PTR_ EDS_COMPONENT_STRUCT_PTR;
/*! \endcond */

/*!
 * \cond DOXYGEN_PRIVATE
 * 
 * \brief Configuration structure for IO channel.
 */ 
typedef struct io_channel_struct
{
    /*! \brief Pointer to channel to use. */
    char_ptr    CHANNEL;
    /*! \brief Baud rate. */
    uint_32     BAUD;
} IO_CHAN_STRUCT, _PTR_ IO_CHAN_STRUCT_PTR;
/*! \endcond */
/* function prototypes */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern void    _eds_serial_master_task(uint_32);
extern void    _eds_serial_slave_task(uint_32);

extern boolean _eds_serial_process_master(EDS_COMPONENT_STRUCT_PTR);
extern boolean _eds_serial_process_slave(EDS_COMPONENT_STRUCT_PTR);

extern void    _eds_serial_task(uint_32);
extern boolean _eds_serial_process(MQX_FILE_PTR, char_ptr);
extern void    _eds_serial_check_errors(EDS_OP_STRUCT_PTR);
extern void    _eds_serial_identify(EDS_OP_STRUCT_PTR);
extern int_32  _eds_serial_send(MQX_FILE_PTR, char_ptr, int_32);
extern int_32  _eds_serial_recv(MQX_FILE_PTR, char_ptr, int_32);
#endif
 
#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/hwtimer/hwtimer_pit.h<|end_filename|>
#ifndef __hwtimer_pit_h__
#define __hwtimer_pit_h__
/*HEADER********************************************************************
 *
 * Copyright (c) 2013 Freescale Semiconductor;
 * All Rights Reserved
 *
 ***************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************
 *
 * $FileName: hwtimer_pit.h$
 * $Version : 4.0.1$
 * $Date : Jan-18-2013$
 *
 * Comments:
 *
 *   This include file is used to define constants and data types for the
 *   hwtimer low level PIT modul.
 *
 *END************************************************************************/
#include "hwtimer.h"

/*! \brief Instance of HWTIMER_DEVIF_STRUCT structure initialized \n
 * with pointers to API functions the  pit driver implements
 */
extern const HWTIMER_DEVIF_STRUCT pit_devif;

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/spi_legacy/polled/spi_pol.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2009 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: spi_pol.c$
* $Version : 3.8.13.0$
* $Date    : Aug-30-2011$
*
* Comments:
*
*   This file contains the SPI polled I/O (master) driver functions.
*
*END************************************************************************/

#include <mqx_inc.h>
#include <fio.h>
#include <fio_prv.h>
#include <io.h>
#include <io_prv.h>
#include "spi.h"
#include "spi_pol_prv.h"

/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_polled_install
* Returned Value   : MQX error code
* Comments         :
*    Install polled SPI device.
*
*END**********************************************************************/
_mqx_uint _io_spi_polled_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr              identifier,
  
      /* [IN] The I/O init function */
      _mqx_uint (_CODE_PTR_ init)(pointer, pointer _PTR_, char _PTR_),
      
      /* [IN] The I/O de-init function */
      _mqx_uint (_CODE_PTR_ deinit)(pointer, pointer),
      
      /* [IN] The input function */
      _mqx_int  (_CODE_PTR_ recv)(pointer, char _PTR_, _mqx_int),
     
      /* [IN] The output function */
      _mqx_int  (_CODE_PTR_ xmit)(pointer, char _PTR_, _mqx_int),

      /* [IN] The I/O ioctl function */
      _mqx_int  (_CODE_PTR_ ioctl)(pointer, _mqx_uint, _mqx_uint_ptr, _mqx_uint),

      /* [IN] The I/O init data pointer */
      pointer               init_data_ptr
      
   )
{ /* Body */
   IO_SPI_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;

   polled_dev_ptr = (IO_SPI_POLLED_DEVICE_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(IO_SPI_POLLED_DEVICE_STRUCT));
   if (polled_dev_ptr == NULL) 
   {
      return MQX_OUT_OF_MEMORY;
   }
   _mem_set_type(polled_dev_ptr,MEM_TYPE_IO_SPI_POLLED_DEVICE_STRUCT);

   polled_dev_ptr->DEV_INIT          = init;
   polled_dev_ptr->DEV_DEINIT        = deinit;
   polled_dev_ptr->DEV_READ          = recv;
   polled_dev_ptr->DEV_WRITE         = xmit;
   polled_dev_ptr->DEV_IOCTL         = ioctl;
   polled_dev_ptr->DEV_INIT_DATA_PTR = init_data_ptr;
   
   return (_io_dev_install_ext(identifier,
      _io_spi_polled_open, _io_spi_polled_close,
      _io_spi_polled_read, 
      _io_spi_polled_write, 
      _io_spi_polled_ioctl, _io_spi_polled_uninstall,
      (pointer)polled_dev_ptr));
} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_polled_uninstall
* Returned Value   : MQX error code
* Comments         :
*    Uninstall polled SPI device.
*
*END**********************************************************************/
_mqx_int _io_spi_polled_uninstall
   (
      /* [IN] The IO device structure for the device */
      IO_DEVICE_STRUCT_PTR         io_dev_ptr
   )
{ /* Body */
   IO_SPI_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

   if (polled_dev_ptr->COUNT == 0) 
   {
      if (polled_dev_ptr->DEV_DEINIT) 
      {
         (*polled_dev_ptr->DEV_DEINIT)(polled_dev_ptr->DEV_INIT_DATA_PTR,
            polled_dev_ptr->DEV_INFO_PTR);
      }
      _mem_free(io_dev_ptr->DRIVER_INIT_PTR);
      io_dev_ptr->DRIVER_INIT_PTR = NULL;
      return IO_OK;
   } else {
      return IO_ERROR_DEVICE_BUSY;
   } /* Endif */
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_polled_open
* Returned Value   : MQX error code
* Comments         :
*    This routine initializes the SPI I/O channel. It acquires
*    memory, then stores information into it about the channel.
*    It then calls the hardware interface function to initialize the channel.
* 
*END**********************************************************************/
_mqx_int _io_spi_polled_open
   (
      /* [IN] The file handle for the device being opened */
      FILE_DEVICE_STRUCT_PTR         fd_ptr,
       
      /* [IN] The remaining portion of the name of the device */
      char                           _PTR_ open_name_ptr,

      /* [IN] The flags to be used during operation */
      char                           _PTR_ flags
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR              io_dev_ptr;
   IO_SPI_POLLED_DEVICE_STRUCT_PTR   polled_dev_ptr;
   _mqx_int                          result = MQX_OK;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   polled_dev_ptr = (IO_SPI_POLLED_DEVICE_STRUCT_PTR)(io_dev_ptr->DRIVER_INIT_PTR);

   _int_disable();
   if (polled_dev_ptr->COUNT) 
   {
      /* Device is already opened */
      result = MQX_IO_OPERATION_NOT_AVAILABLE;
      _int_enable();
      return result;
   }
   polled_dev_ptr->COUNT = 1;
   _int_enable();
      
   polled_dev_ptr->FLAGS = (_mqx_uint)flags;
   fd_ptr->FLAGS         = (_mqx_uint)flags;
            
   result = (*polled_dev_ptr->DEV_INIT)((pointer)polled_dev_ptr->DEV_INIT_DATA_PTR, 
                                        &polled_dev_ptr->DEV_INFO_PTR, open_name_ptr);
   if (result != MQX_OK) 
   {
      polled_dev_ptr->COUNT = 0;
   }
   return result;
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_polled_close
* Returned Value   : MQX error code
* Comments         :
*    This routine closes the SPI I/O channel.
* 
*END**********************************************************************/
_mqx_int _io_spi_polled_close
   (
      /* [IN] The file handle for the device being closed */
      FILE_DEVICE_STRUCT_PTR        fd_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR             io_dev_ptr;
   IO_SPI_POLLED_DEVICE_STRUCT_PTR  polled_dev_ptr;
   _mqx_int                         result = MQX_OK;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   _int_disable();
   if (--polled_dev_ptr->COUNT == 0) 
   {
      if (polled_dev_ptr->DEV_DEINIT) 
      {
         result = (*polled_dev_ptr->DEV_DEINIT)(polled_dev_ptr, polled_dev_ptr->DEV_INFO_PTR);
      }
   }
   _int_enable();
   return result;
} /* Endbody */
  
/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_polled_read
* Returned Value   : Number of bytes read
* Comments         :
*    Reads bytes into array from SPI input buffers.
*    Returns number of bytes received.
*
*END*********************************************************************/
_mqx_int _io_spi_polled_read
   (
      /* [IN] The handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR          fd_ptr,

      /* [OUT] Where the characters are to be stored */
      char_ptr                        data_ptr,

      /* [IN] The number of bytes to read */
      _mqx_int                        n
   )
{  /* Body */
   IO_DEVICE_STRUCT_PTR              io_dev_ptr;
   IO_SPI_POLLED_DEVICE_STRUCT_PTR   polled_dev_ptr;
   
   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   return (*polled_dev_ptr->DEV_READ)(polled_dev_ptr, data_ptr, n);
}  /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : _io_spi_polled_write
* Returned Value   : Number of bytes to write
* Comments         :
*   Returns  
*   This routine calls the appropriate write routine.
*
*END**********************************************************************/
_mqx_int _io_spi_polled_write
   (
      /* [IN] The handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR       fd_ptr,

      /* [IN] Where the bytes are stored */
      char_ptr                     data_ptr,

      /* [IN] The number of bytes to output */
      _mqx_int                     n
   )
{  /* Body */
   IO_DEVICE_STRUCT_PTR            io_dev_ptr;
   IO_SPI_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;
   
   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;
               
   return (*polled_dev_ptr->DEV_WRITE)(polled_dev_ptr, data_ptr, n);
} /* Endbody */
   
/*FUNCTION*****************************************************************
* 
* Function Name    : _io_spi_polled_ioctl
* Returned Value   : MQX error code
* Comments         :
*    Returns result of SPI ioctl operation.
*
*END*********************************************************************/
_mqx_int _io_spi_polled_ioctl
   (
      /* [IN] the file handle for the device */
      FILE_DEVICE_STRUCT_PTR       fd_ptr,

      /* [IN] the ioctl command */
      _mqx_uint                    cmd,

      /* [IN] the ioctl parameters */
      pointer                      input_param_ptr
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR            io_dev_ptr;
   IO_SPI_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;
   _mqx_int                        result = MQX_OK;
   _mqx_uint_ptr                   param_ptr = (_mqx_uint_ptr)input_param_ptr;

   io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
   polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

   switch (cmd) {
      case IO_IOCTL_SPI_GET_FLAGS:
         *param_ptr = polled_dev_ptr->FLAGS;
         break;
         
      case IO_IOCTL_SPI_SET_FLAGS:
         polled_dev_ptr->FLAGS = *param_ptr;
         fd_ptr->FLAGS = *param_ptr;
         break;
      
      case IO_IOCTL_DEVICE_IDENTIFY :
          /* return the device identify */
          param_ptr[0] = IO_DEV_TYPE_PHYS_SPI;
          param_ptr[1] = 0;
          param_ptr[2] = IO_DEV_ATTR_POLL | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
          result = MQX_OK;  
          break;  
            
      default:
          if (polled_dev_ptr->DEV_IOCTL != NULL) {
              result = (*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR, cmd, param_ptr, polled_dev_ptr->FLAGS);
          }
          break;             
   }
   return result;
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/can/flexcan/flexcan_regs.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008-2011 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2011 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flexcan_regs.h$
* $Version : 3.8.2.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the type definitions for the FlexCAN module.
*
*END************************************************************************/

#ifndef __flexcan_regs_h__
#define __flexcan_regs_h__

#define __flexcan_regs_h__version "$Version:3.8.2.0$"
#define __flexcan_regs_h__date    "$Date:Jun-6-2012$"

#ifdef __cplusplus
extern "C" {
#endif

/* Message buffer memory map */
#define FLEXCAN_MSGCTRL_RTR              (0x00100000)
#define FLEXCAN_MSGCTRL_IDE              (0x00200000)
#define FLEXCAN_MSGCTRL_SRR              (0x00400000)
#define FLEXCAN_MSGCRTL_CODE             (0x0F000000)
#define FLEXCAN_MSG_CTRL_DLEN            (0x000F0000)
#define FLEXCAN_MSG_DISABLE              (~ FLEXCAN_MSGCRTL_CODE)

/*
** Message Buffer Codes for Rx Buffers
*/
#define FLEXCAN_RX_MSG_BUFFER_NOT_ACTIVE (0x00000000)
#define FLEXCAN_RX_MSG_BUFFER_EMPTY      (0x04000000)
#define FLEXCAN_RX_MSG_BUFFER_FULL       (0x02000000)
#define FLEXCAN_RX_MSG_BUFFER_OVERRUN    (0x06000000)
#define FLEXCAN_RX_MSG_BUFFER_BUSY       (0x01000000)

/* Message Buffer Codes for Tx Buffers */
#define FLEXCAN_TX_MSG_BUFFER_NOT_ACTIVE        (0x08000000)
#define FLEXCAN_MESSAGE_TRANSMIT_ONCE           (0x0C000000)
#define FLEXCAN_MESSAGE_TRANSMIT_REMOTE         (0x0C000000)
#define FLEXCAN_MESSAGE_TRANSMIT_RESPONED       (0x0A000000)
#define FLEXCAN_MESSAGE_TRANSMIT_RESPONED_ONLY  (0x0E000000)

/* Interrupt masks */
#define FLEXCAN_WAKEUP_INT               (0x0001)
#define FLEXCAN_ERROR_INT                (0x0002)
#define FLEXCAN_BUSOFF_INT               (0x0004)
#define FLEXCAN_ALL_INT                  (0x0007)
#define FLEXCAN_TX_RX_INT                (~ FLEXCAN_ALL_INT)
#define FLEXCAN_IMASK_VALUE              (0xFFFF)


/*------------------------------------------------------------------------*/
/*
** FCAN  registers bit set.
*/

/* Bit definitions and macros for FLEXCAN_CANMCR */
#define FLEXCAN_CANMCR_MAXMB(x)          (((x)&0xF)<<0)
#define FLEXCAN_CANMCR_LPMACK            (0x100000)
#define FLEXCAN_CANMCR_SUPV              (0x800000)
#define FLEXCAN_CANMCR_FRZACK            (0x1000000)
#define FLEXCAN_CANMCR_SOFTRST           (0x2000000)
#define FLEXCAN_CANMCR_NOTRDY            (0x8000000)
#define FLEXCAN_CANMCR_HALT              (0x10000000)
#define FLEXCAN_CANMCR_FRZ               (0x40000000)
#define FLEXCAN_CANMCR_MDIS              (0x80000000)

/* Bit definitions and macros for FLEXCAN_CANCTRL */
#define FLEXCAN_CANCTRL_PROPSEG(x)       (((x)&0x7)<<0)
#define FLEXCAN_CANCTRL_LOM              (0x8)
#define FLEXCAN_CANCTRL_LBUF             (0x10)
#define FLEXCAN_CANCTRL_TSYNC            (0x20)
#define FLEXCAN_CANCTRL_BOFFREC          (0x40)
#define FLEXCAN_CANCTRL_SAMP             (0x80)
#define FLEXCAN_CANCTRL_LPB              (0x1000)
#define FLEXCAN_CANCTRL_CLK_SRC          (0x2000)
#define FLEXCAN_CANCTRL_ERRMSK           (0x4000)
#define FLEXCAN_CANCTRL_BOFFMSK          (0x8000)
#define FLEXCAN_CANCTRL_PSEG2(x)         (((x)&0x7)<<0x10)
#define FLEXCAN_CANCTRL_PSEG1(x)         (((x)&0x7)<<0x13)
#define FLEXCAN_CANCTRL_RJW(x)           (((x)&0x3)<<0x16)
#define FLEXCAN_CANCTRL_PRESDIV(x)       (((x)&0xFF)<<0x18)

/* Bit definitions and macros for FLEXCAN_TIMER */
#define FLEXCAN_TIMER_TIMER(x)           (((x)&0xFFFF)<<0)

/* Bit definitions and macros for FLEXCAN_RXGMASK */
#define FLEXCAN_RXGMASK_MI(x)            (((x)&0x1FFFFFFF)<<0)

/* Bit definitions and macros for FLEXCAN_RX14MASK */
#define FLEXCAN_RX14MASK_MI(x)           (((x)&0x1FFFFFFF)<<0)

/* Bit definitions and macros for FLEXCAN_RX15MASK */
#define FLEXCAN_RX15MASK_MI(x)           (((x)&0x1FFFFFFF)<<0)

/* Bit definitions and macros for FLEXCAN_RX15MASK */
#define FLEXCAN_RX15MASK_MI(x)           (((x)&0x1FFFFFFF)<<0)

/* Bit definitions and macros for ID masks */
#define FLEXCAN_STANDARD_ID_MASK(x)      (((x)&0x7FF)<<18)
#define FLEXCAN_EXTENDED_ID_MASK(x)      (((x)&0x1FFFFFFF)<<0)

/* Bit definitions and macros for FLEXCAN_ERRCNT */
#define FLEXCAN_ERRCNT_TXECTR(x)         (((x)&0xFF)<<0)
#define FLEXCAN_ERRCNT_RXECTR(x)         (((x)&0xFF)<<0x8)

/* Bit definitions and macros for FLEXCAN_ERRSTAT */
#define FLEXCAN_ERRSTAT_ERRINT           (0x2)
#define FLEXCAN_ERRSTAT_BOFFINT          (0x4)
#define FLEXCAN_ERRSTAT_FLTCONF(x)       (((x)&0x3)<<0x4)
#define FLEXCAN_ERRSTAT_FLTCONF_ACTIVE   (0)
#define FLEXCAN_ERRSTAT_FLTCONF_PASSIVE  (0x10)
#define FLEXCAN_ERRSTAT_FLTCONF_BUSOFF   (0x20)
#define FLEXCAN_ERRSTAT_TXRX             (0x40)
#define FLEXCAN_ERRSTAT_IDLE             (0x80)
#define FLEXCAN_ERRSTAT_RXWRN            (0x100)
#define FLEXCAN_ERRSTAT_TXWRN            (0x200)
#define FLEXCAN_ERRSTAT_STFERR           (0x400)
#define FLEXCAN_ERRSTAT_FRMERR           (0x800)
#define FLEXCAN_ERRSTAT_CRCERR           (0x1000)
#define FLEXCAN_ERRSTAT_ACKERR           (0x2000)
#define FLEXCAN_ERRSTAT_BIT0ERR          (0x4000)
#define FLEXCAN_ERRSTAT_BIT1ERR          (0x8000)

/* Bit definitions and macros for FLEXCAN_IMASK */
#define FLEXCAN_IMASK_BUF0M              (0x1)
#define FLEXCAN_IMASK_BUF1M              (0x2)
#define FLEXCAN_IMASK_BUF2M              (0x4)
#define FLEXCAN_IMASK_BUF3M              (0x8)
#define FLEXCAN_IMASK_BUF4M              (0x10)
#define FLEXCAN_IMASK_BUF5M              (0x20)
#define FLEXCAN_IMASK_BUF6M              (0x40)
#define FLEXCAN_IMASK_BUF7M              (0x80)
#define FLEXCAN_IMASK_BUF8M              (0x100)
#define FLEXCAN_IMASK_BUF9M              (0x200)
#define FLEXCAN_IMASK_BUF10M             (0x400)
#define FLEXCAN_IMASK_BUF11M             (0x800)
#define FLEXCAN_IMASK_BUF12M             (0x1000)
#define FLEXCAN_IMASK_BUF13M             (0x2000)
#define FLEXCAN_IMASK_BUF14M             (0x4000)
#define FLEXCAN_IMASK_BUF15M             (0x8000)
#define FLEXCAN_IMASK_BUF(x)             (0x1<<(x))

/* Bit definitions and macros for FLEXCAN_IFLAG */
#define FLEXCAN_IFLAG_BUF0I              (0x1)
#define FLEXCAN_IFLAG_BUF1I              (0x2)
#define FLEXCAN_IFLAG_BUF2I              (0x4)
#define FLEXCAN_IFLAG_BUF3I              (0x8)
#define FLEXCAN_IFLAG_BUF4I              (0x10)
#define FLEXCAN_IFLAG_BUF5I              (0x20)
#define FLEXCAN_IFLAG_BUF6I              (0x40)
#define FLEXCAN_IFLAG_BUF7I              (0x80)
#define FLEXCAN_IFLAG_BUF8I              (0x100)
#define FLEXCAN_IFLAG_BUF9I              (0x200)
#define FLEXCAN_IFLAG_BUF10I             (0x400)
#define FLEXCAN_IFLAG_BUF11I             (0x800)
#define FLEXCAN_IFLAG_BUF12I             (0x1000)
#define FLEXCAN_IFLAG_BUF13I             (0x2000)
#define FLEXCAN_IFLAG_BUF14I             (0x4000)
#define FLEXCAN_IFLAG_BUF15I             (0x8000)
#define FLEXCAN_IFLAG_BUF(x)             (0x1<<(x))



#define _flexcan_int_init _bsp_int_init


/*
** FLEXCAN_STRUCT
** FlexCAN Registers
*/
typedef struct flexcan_struct
{
    uint_32  CANMCR;          /* Module Configuration Register*/
    uint_32  CANCTRL;         /* FlexCAN Control Register*/
    uint_32  TIMER;           /* Free Running TImer*/
    uint_32  filler2;
    uint_32  RXGMASK;         /* Rx Global Mask*/
    uint_32  RX14MASK;        /* Rx Buffer 14 Mask*/
    uint_32  RX15MASK;        /* Rx Buffer 15 Mask*/
    uint_32  ERRCNT;          /* Error Counter Register*/
    uint_32  ERRSTAT;         /* Error and Status*/
    uint_32  IMASK2;          /* Interrupt Mask Register 2*/
    uint_32  IMASK;           /* Interrupt Mask Register 1*/
    uint_32  IFLAG2;          /* Interrupt Flag Register 2*/
    uint_32  IFLAG;           /* Interrupt Flag Register 1*/
} FLEXCAN_STRUCT;
typedef volatile struct flexcan_struct _PTR_ VFLEXCAN_STRUCT_PTR;

/* FlexCAN MSG Object structure */
typedef struct flexcan_msg_struct
{
    uint_32 CONTROL;            /* CTRL/STATUS */
    uint_32 ID;                 /* ID */
    uchar   DATA[8];            /* bytes Data Field */

} FLEXCAN_MSG_STRUCT, _PTR_ FLEXCAN_MSG_STRUCT_PTR;
typedef volatile struct flexcan_msg_struct VFLEXCAN_MSG_STRUCT;
typedef volatile struct flexcan_msg_struct _PTR_ VFLEXCAN_MSG_STRUCT_PTR;

typedef VFLEXCAN_MSG_STRUCT      FLEXCAN_MSG_OBJECT_STRUCT;
typedef VFLEXCAN_MSG_STRUCT_PTR  FLEXCAN_MSG_OBJECT_STRUCT_PTR;
typedef VFLEXCAN_STRUCT_PTR      FLEXCAN_REG_STRUCT_PTR;

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/tftpsrv.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tftpsrv.c$
* $Version : 192.168.3.11$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the TFTP server implementation.
*
*END************************************************************************/


#include <rtcs.h>
#include "rtcs_prv.h"

#if RTCSCFG_ENABLE_UDP

#include <string.h>
#include <fio.h>
#include "tftp.h"

_rtcs_taskid TFTPSRV_task_id = 0;

#ifdef __MQX__ 
void TFTPSRV_Exit_handler(void);
#endif

void TFTPSRV_task(pointer, pointer);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TFTPSRV_init
* Returned Value   : error code
* Comments  :  Start the TFTP server
*
*END*-----------------------------------------------------------------*/

uint_32 TFTPSRV_init
   (
      char_ptr name,
      uint_32  priority,
      uint_32  stacksize
   )
{ /* Body */
   if (TFTPSRV_task_id == 0)  {
      return RTCS_task_create(name, priority, stacksize, TFTPSRV_task, NULL);
   } else  {
      return RTCSERR_SERVER_ALREADY_RUNNING;
   }
} /* Endbody */


/*TASK*-----------------------------------------------------------------
*
* Function Name   : TFTPSRV_task
* Returned Value  : void
* Comments        : This task waits on port 69 for read and write
*                   requests, as well as servicing TFTP transactions
*                   already in progress.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_task
   (
      pointer dummy,
      pointer creator
   )
{ /* Body */
   TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr;
   sockaddr_in                laddr;
   uint_32                    i, numtrans, timeout;
   uint_32                    error;
   
   tftpsrv_ptr = RTCS_mem_alloc_zero(sizeof(TFTPSRV_STATE_STRUCT));
  
   if (tftpsrv_ptr == NULL) {
      RTCS_task_exit(creator, RTCSERR_OUT_OF_MEMORY);
   } /* Endif */

    TFTPSRV_task_id = RTCS_task_getid();
#ifdef __MQX__ 
   /* Set up exit handler and context so that we can clean up if the TFTP Server is terminated */
   _task_set_environment( _task_get_id(), (pointer) tftpsrv_ptr );
   _task_set_exit_handler( _task_get_id(), TFTPSRV_Exit_handler );
#endif 

   tftpsrv_ptr->SRV_SOCK = socket(PF_INET, SOCK_DGRAM, 0);
   if (tftpsrv_ptr->SRV_SOCK == RTCS_SOCKET_ERROR) {
      RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
   } /* Endif */

   laddr.sin_family      = AF_INET;
   laddr.sin_port        = IPPORT_TFTP;
   laddr.sin_addr.s_addr = INADDR_ANY;

   error = bind(tftpsrv_ptr->SRV_SOCK, (const sockaddr *)&laddr, sizeof(laddr));
   if (error != RTCS_OK) {
      RTCS_task_exit(creator, error);
   } /* Endif */

   RTCS_task_resume_creator(creator, RTCS_OK);

   for (;;) {
      timeout = TFTPSRV_service_timer(tftpsrv_ptr);
      numtrans = tftpsrv_ptr->NUM_TRANSACTIONS;
      error = RTCS_selectset(&tftpsrv_ptr->SRV_SOCK, numtrans+1, timeout);
      if ((error == RTCS_OK) || (error == RTCS_SOCKET_ERROR)) {
         continue;
      } /* Endif */
      if (error == tftpsrv_ptr->SRV_SOCK) {
         /* New request, service it */
         TFTPSRV_service_request(tftpsrv_ptr);
      } else {
         for (i = 0; i < numtrans; i++) {
            if (error == tftpsrv_ptr->SOCKETS[i]) {
               TFTPSRV_service_transaction(tftpsrv_ptr, tftpsrv_ptr->TRANS_PTRS[i]);
               break;
            } /* Endif */
         } /* Endfor */
      } /* Endif */
   } /* Endfor */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_service_request
* Returned Value  : void
* Comments        : This function takes an initial TFTP request and
*                   starts the transaction process.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_service_request
   (
      TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr
         /* [IN/OUT] The TFTP Server state */
   )
{ /* Body */
   TFTP_TRANS_STRUCT_PTR   trans_ptr;
   sockaddr_in             sockaddr_t;
   int_32                  pkt_len, i;
   uint_32                 error;
   char_ptr                filename, filemode;
   uint_16                 sockaddrlen, pkt_op;

   /* receive the datagram */
   sockaddrlen = sizeof(sockaddr_t);
   pkt_len = recvfrom(tftpsrv_ptr->SRV_SOCK, tftpsrv_ptr->BUFFER,
                      TFTP_MAX_MESSAGE_SIZE, 0, (sockaddr *)&sockaddr_t, &sockaddrlen);
   if (pkt_len == RTCS_ERROR) {
      return;
   } /* Endif */

   /* limit the number of concurrent transactions */
   if (tftpsrv_ptr->NUM_TRANSACTIONS >= TFTPSRV_MAX_TRANSACTIONS) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_busy, sockaddr_t);
      return;
   } /* Endif */

   /* parse the request; extract op, filename and filemode */
   i = 2;
   filename = (char_ptr)tftpsrv_ptr->BUFFER + i;
   for (; i<pkt_len; i++) {
      if (tftpsrv_ptr->BUFFER[i] == '\0') break;
   } /* Endfor */
   i++;
   filemode = (char_ptr)tftpsrv_ptr->BUFFER + i;
   for (; i<pkt_len; i++) {
      if (tftpsrv_ptr->BUFFER[i] == '\0') break;
   } /* Endfor */
   if (i >= pkt_len) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_op, sockaddr_t);
      return;
   } /* Endif */
   pkt_op = ntohs(tftpsrv_ptr->BUFFER);

   /* allocate state for the new transaction */
   trans_ptr = RTCS_mem_alloc_zero(sizeof(TFTP_TRANS_STRUCT));
   if (trans_ptr == NULL) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
      return;
   } /* Endif */
   _mem_set_type(trans_ptr, MEM_TYPE_TFTP_TRANS_STRUCT);
   
   /* validate the requested operation */
   switch (pkt_op) {
   case TFTPOP_RRQ:
      trans_ptr->RECV_OP = TFTPOP_ACK;
      trans_ptr->SEND_OP = TFTPOP_DATA;
      break;
   case TFTPOP_WRQ:
      trans_ptr->RECV_OP = TFTPOP_DATA;
      trans_ptr->SEND_OP = TFTPOP_ACK;
      break;
   default:
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_op, sockaddr_t);
      _mem_free(trans_ptr);
      return;
   } /* Endswitch */

   /* open the requested file */
   error = TFTPSRV_open_device(pkt_op, filename, filemode, &trans_ptr->TRANS_FILE_PTR);
   if (error) {
      switch (error) {
      case RTCS_EACCES:
         TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_accvio, sockaddr_t);
         break;
      case RTCS_ENOENT:
         TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_nofile, sockaddr_t);
         break;
      case RTCS_EEXIST:
         TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_exists, sockaddr_t);
         break;
      default:
         TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
         break;
      } /* Endswitch */
      _mem_free(trans_ptr);
      return;
   } /* Endif */

   /* create a socket for the new transaction */
   trans_ptr->SOCK = socket(PF_INET, SOCK_DGRAM, 0);
   if (trans_ptr->SOCK == RTCS_SOCKET_ERROR) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
      RTCS_io_close(trans_ptr->TRANS_FILE_PTR);
      _mem_free(trans_ptr);
      return;
   } /* Endif */

   trans_ptr->ADDR.sin_family      = sockaddr_t.sin_family;
   trans_ptr->ADDR.sin_port        = sockaddr_t.sin_port;
   trans_ptr->ADDR.sin_addr.s_addr = sockaddr_t.sin_addr.s_addr;

   sockaddr_t.sin_family      = AF_INET;
   sockaddr_t.sin_port        = 0;
   sockaddr_t.sin_addr.s_addr = INADDR_ANY;

   error = bind(trans_ptr->SOCK, (const sockaddr *)&sockaddr_t, sizeof(sockaddr_t));
   if (error != RTCS_OK) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
      shutdown(trans_ptr->SOCK, 0);
      RTCS_io_close(trans_ptr->TRANS_FILE_PTR);
      _mem_free(trans_ptr);
      return;
   } /* Endif */

   /* build the first packet */
   trans_ptr->BLOCK = 0;
   switch (trans_ptr->SEND_OP) {
   case TFTPOP_DATA:
      TFTPSRV_build_DATA(trans_ptr);
      break;
   case TFTPOP_ACK:
      TFTPSRV_build_ACK(trans_ptr);
      trans_ptr->EXIT = FALSE;
      break;
   } /* Endswitch */
   if (trans_ptr->SEND_SIZE < sizeof(TFTP_HEADER)) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
      shutdown(trans_ptr->SOCK, 0);
      RTCS_io_close(trans_ptr->TRANS_FILE_PTR);
      _mem_free(trans_ptr);
      return;
   } /* Endif */

   /* send the first packet */
   TFTPSRV_timer_start(tftpsrv_ptr, trans_ptr, TFTP_timeout_init(&trans_ptr->XMIT_TIMER));
   TFTPSRV_send(trans_ptr);

   tftpsrv_ptr->SOCKETS[tftpsrv_ptr->NUM_TRANSACTIONS] = trans_ptr->SOCK;
   tftpsrv_ptr->TRANS_PTRS[tftpsrv_ptr->NUM_TRANSACTIONS] = trans_ptr;
   tftpsrv_ptr->NUM_TRANSACTIONS++;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_open_device
* Returned Value  : error code
* Comments        : This function opens the requested device, if possible.
*
*END*-----------------------------------------------------------------*/

uint_32 TFTPSRV_open_device
   (
      uint_32        pkt_op,
         /* [IN] the transaction type */
      char_ptr       filename,
         /* [IN] the requested file */
      char_ptr       filemode,
         /* [IN] the transfer mode */
      MQX_FILE_PTR _PTR_ fd_ptr
         /* [OUT] the open file descriptor */
   )
{ /* Body */
   char_ptr open_mode;
   uint_32  error;

   if (strcmp(filemode, "netascii") == 0) {
      if (pkt_op == TFTPOP_RRQ) {
         open_mode = "r";
      } else {
         open_mode = "w";
      } /* Endif */
   } else if (strcmp(filemode, "octet") == 0) {
      if (pkt_op == TFTPOP_RRQ) {
         open_mode = "rb";
      } else {
         open_mode = "wb";
      } /* Endif */
   } else {
      return RTCS_EACCES;
   } /* Endif */

   if (!TFTPSRV_access(filename, pkt_op)) {
      return RTCS_EACCES;
   } /* Endif */

   *fd_ptr = RTCS_io_open(filename, open_mode, &error);
   return error;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_service_transaction
* Returned Value  : void
* Comments        : This function services a transaction in progress
*                   which has just received a packet.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_service_transaction
   (
      TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr,
         /* [IN/OUT] The TFTP Server state */
      TFTP_TRANS_STRUCT_PTR      trans_ptr
         /* [IN/OUT] The transaction state */
   )

{ /* Body */
   sockaddr_in sockaddr_tftp;
   uint_32     block_num;
   int_32      pkt_len, write_len;
   uint_16     sockaddrlen, pkt_op;

   /* receive the datagram */
   sockaddrlen = sizeof(sockaddr_tftp);
   pkt_len = recvfrom(trans_ptr->SOCK, tftpsrv_ptr->BUFFER,
                      TFTP_MAX_MESSAGE_SIZE, 0,(sockaddr *)&sockaddr_tftp, &sockaddrlen);
   if (pkt_len == RTCS_ERROR) {
      return;
   } /* Endif */

   /* verify the sender's address and port */
   if ((trans_ptr->ADDR.sin_port        != sockaddr_tftp.sin_port) ||
       (trans_ptr->ADDR.sin_addr.s_addr != sockaddr_tftp.sin_addr.s_addr)) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_tid, sockaddr_tftp);
      return;
   } /* Endif */

   /* get op and block number */
   if (pkt_len < sizeof(TFTP_HEADER)) {
      TFTP_SEND(trans_ptr->SOCK, _tftp_error_tid, sockaddr_tftp);
      return;
   } /* Endif */
   pkt_op    = ntohs(tftpsrv_ptr->BUFFER);
   block_num = ntohs(tftpsrv_ptr->BUFFER + 2);

   /* verify the requested operation */
   if (pkt_op != trans_ptr->RECV_OP) {
      if (pkt_op != TFTPOP_ERROR) {
         TFTP_SEND(trans_ptr->SOCK, _tftp_error_op, sockaddr_tftp);
      } /* Endif */
      TFTPSRV_close_transaction(tftpsrv_ptr, trans_ptr);
      return;
   } /* Endif */

   switch (pkt_op) {
   case TFTPOP_DATA:
      /* We are servicing a write request from a TFTP Client here */
      if (block_num == trans_ptr->BLOCK) {

         pkt_len -= sizeof(TFTP_HEADER);
         write_len = RTCS_io_write(trans_ptr->TRANS_FILE_PTR,
                                   tftpsrv_ptr->BUFFER + sizeof(TFTP_HEADER),
                                   pkt_len);
         if (write_len != pkt_len) {
            TFTP_SEND(trans_ptr->SOCK, _tftp_error_srv, trans_ptr->ADDR);
            TFTPSRV_close_transaction(tftpsrv_ptr, trans_ptr);
            return;
         } /* Endif */

         TFTPSRV_build_ACK(trans_ptr);
         trans_ptr->EXIT = (write_len < sizeof(TFTP_PACKET) - sizeof(TFTP_HEADER));
         TFTPSRV_timer_cancel(tftpsrv_ptr, trans_ptr);
         TFTPSRV_timer_start(tftpsrv_ptr, trans_ptr, TFTP_timeout_update(&trans_ptr->XMIT_TIMER));
         TFTPSRV_send(trans_ptr);

      } else if (block_num == trans_ptr->BLOCK - 1) {
         TFTPSRV_timer_cancel(tftpsrv_ptr, trans_ptr);
         TFTPSRV_timer_start(tftpsrv_ptr, trans_ptr, TFTP_timeout_restart(&trans_ptr->XMIT_TIMER));
         TFTPSRV_send(trans_ptr);
      } /* Endif */
      break;

   case TFTPOP_ACK:
      /* We are servicing a read request */
      if (block_num == trans_ptr->BLOCK) {
         if (trans_ptr->EXIT) {
            /* We've received the last ACK, exit */
            TFTPSRV_close_transaction(tftpsrv_ptr, trans_ptr);
            return;
         } /* Endif */
         TFTPSRV_build_DATA(trans_ptr);
         if (trans_ptr->SEND_SIZE < sizeof(TFTP_HEADER)) {
            TFTP_SEND(trans_ptr->SOCK, _tftp_error_srv, sockaddr_tftp);
            TFTPSRV_close_transaction(tftpsrv_ptr, trans_ptr);
            return;
         } /* Endif */
         TFTPSRV_timer_cancel(tftpsrv_ptr, trans_ptr);
         TFTPSRV_timer_start(tftpsrv_ptr, trans_ptr, TFTP_timeout_update(&trans_ptr->XMIT_TIMER));
         TFTPSRV_send(trans_ptr);
      } /* Endif */
      break;

   } /* Endswitch */
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_build_ACK
* Returned Value  : void
* Comments        : This function builds an ACK packet for client
*                   write requests.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_build_ACK
   (
      TFTP_TRANS_STRUCT_PTR   trans_ptr
         /* [IN/OUT] The transaction state */
   )
{ /* Body */
   htons(trans_ptr->SND.HEAD.OP,    trans_ptr->SEND_OP);
   htons(trans_ptr->SND.HEAD.BLOCK, trans_ptr->BLOCK);
   trans_ptr->BLOCK++;
   trans_ptr->SEND_SIZE = sizeof(TFTP_HEADER);
   trans_ptr->NUM_RETRIES = 0;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_build_DATA
* Returned Value  : void
* Comments        : This function builds a DATA packet for client
*                   read requests.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_build_DATA
   (
      TFTP_TRANS_STRUCT_PTR   trans_ptr
         /* [IN/OUT] The transaction state */
   )
{ /* Body */
   int_32 datalen;

   datalen = RTCS_io_read(trans_ptr->TRANS_FILE_PTR, (char_ptr)trans_ptr->SND.DATA, TFTP_DATA_SIZE);
   if (datalen < 0) {
      datalen = 0;
   } /* Endif */

   trans_ptr->BLOCK++;
   htons(trans_ptr->SND.HEAD.OP,    trans_ptr->SEND_OP);
   htons(trans_ptr->SND.HEAD.BLOCK, trans_ptr->BLOCK);
   trans_ptr->SEND_SIZE = sizeof(TFTP_HEADER) + datalen;
   trans_ptr->NUM_RETRIES = 0;
   trans_ptr->EXIT = (trans_ptr->SEND_SIZE < sizeof(TFTP_PACKET));
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_send
* Returned Value  : void
* Comments        : This function (re)sends a packet.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_send
   (
      TFTP_TRANS_STRUCT_PTR   trans_ptr
         /* [IN/OUT] The transaction state */
   )
{ /* Body */
   sendto(trans_ptr->SOCK, &trans_ptr->SND, trans_ptr->SEND_SIZE, 0,
          (sockaddr *)(&trans_ptr->ADDR), sizeof(trans_ptr->ADDR));
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_timer_start
* Returned Value  : void
* Comments        : This function starts the retransmission timer.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_timer_start
   (
      TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr,
         /* [IN/OUT] The TFTP Server state */
      TFTP_TRANS_STRUCT_PTR      trans_ptr,
         /* [IN/OUT] The transaction state */
      uint_32                    timeout
         /* [IN] The retransmission timeout */
   )
{ /* Body */
   TFTP_TRANS_STRUCT_PTR _PTR_ search_ptr;

   trans_ptr->TIME = timeout;
   for (search_ptr = &tftpsrv_ptr->EVENT_HEAD;;
        search_ptr = &(*search_ptr)->NEXT) {
      if (*search_ptr == NULL) {
         /* Append to tail of list */
         RTCS_DLIST_INS(*search_ptr, trans_ptr);
         break;
      } /* Endif */
      if ((*search_ptr)->TIME > trans_ptr->TIME) {
         /* Insert in middle (or head) of list */
         (*search_ptr)->TIME -= trans_ptr->TIME;
         RTCS_DLIST_INS(*search_ptr, trans_ptr);
         break;
      } /* Endif */
      trans_ptr->TIME -= (*search_ptr)->TIME;
   } /* Endfor */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_timer_cancel
* Returned Value  : void
* Comments        : This function stops the retransmission timer.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_timer_cancel
   (
      TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr,
         /* [IN/OUT] The TFTP Server state */
      TFTP_TRANS_STRUCT_PTR      trans_ptr
         /* [IN/OUT] The transaction state */
   )
{ /* Body */

   RTCS_DLIST_DEL(&tftpsrv_ptr->EVENT_HEAD, trans_ptr);
   if (trans_ptr->NEXT) {
      trans_ptr->NEXT->TIME += trans_ptr->TIME;
   } /* Endif */

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_service_timer
* Returned Value  : time until the first transaction expiry in
*                   milliseconds, 0 if no pending transactions.
* Comments        : This retransmits the last packet for all expired
*                   transactions.  The transaction list is sorted by
*                   expiry time, so we can stop when the head of the list
*                   is unexpired.
*
*END*-----------------------------------------------------------------*/

uint_32 TFTPSRV_service_timer
   (
      TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr
         /* [IN/OUT] The TFTP Server state */
   )
{ /* Body */
   TFTP_TRANS_STRUCT_PTR   trans_ptr;
   uint_32                 time;
   boolean                 expired;

   while (tftpsrv_ptr->EVENT_HEAD) {

      trans_ptr = tftpsrv_ptr->EVENT_HEAD;
      time = TFTP_timeout_left(&trans_ptr->XMIT_TIMER, &expired);
      if (!expired) {
         trans_ptr->TIME = time;
         return time;
      } /* Endif */

      RTCS_DLIST_DEL(tftpsrv_ptr->EVENT_HEAD, trans_ptr);

      if (trans_ptr->EXIT) {
         TFTPSRV_close_transaction(tftpsrv_ptr, trans_ptr);
         continue;
      } /* Endif */

#if TFTPSRV_TIMEOUT_RETRIES != TFTPSRV_INFINITE_RETRIES
      if (++trans_ptr->NUM_RETRIES > TFTPSRV_TIMEOUT_RETRIES) {
         TFTP_SEND(trans_ptr->SOCK, _tftp_error_to, trans_ptr->ADDR);
         TFTPSRV_close_transaction(tftpsrv_ptr, trans_ptr);
         continue;
      } /* Endif */
#endif

      TFTPSRV_send(trans_ptr);
      TFTPSRV_timer_start(tftpsrv_ptr, trans_ptr, time);

   } /* Endwhile */

   /* Nothing in the event queue */
   return 0;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TFTPSRV_close_transaction
* Returned Value  : void
* Comments        : This function closes a transaction.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_close_transaction
   (
      TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr,
         /* [IN/OUT] The TFTP Server state */
      TFTP_TRANS_STRUCT_PTR      trans_ptr
         /* [IN/OUT] The transaction state */
   )
{ /* Body */
   uint_32 i;

   TFTPSRV_timer_cancel(tftpsrv_ptr, trans_ptr);

   for (i = 0; i < tftpsrv_ptr->NUM_TRANSACTIONS; i++) {
      if (tftpsrv_ptr->TRANS_PTRS[i] == trans_ptr) {
         break;
      } /* Endif */
   } /* Endfor */

   RTCS_io_close(trans_ptr->TRANS_FILE_PTR);
   shutdown(trans_ptr->SOCK, 0);
   if (--tftpsrv_ptr->NUM_TRANSACTIONS) {
      tftpsrv_ptr->TRANS_PTRS[i] = tftpsrv_ptr->TRANS_PTRS[tftpsrv_ptr->NUM_TRANSACTIONS];
      tftpsrv_ptr->SOCKETS[i]    = tftpsrv_ptr->SOCKETS[tftpsrv_ptr->NUM_TRANSACTIONS];
   } /* Endif */
   _mem_free(trans_ptr);

} /* Endbody */

#ifdef __MQX__ 
/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TFTPSRV_stop
* Returned Value   : error code
* Comments  :  Start the TFTPSRV task.
*
*END*-----------------------------------------------------------------*/

uint_32 TFTPSRV_stop( void )
{ /* Body */
   if (TFTPSRV_task_id == 0)  {
      return RTCSERR_SERVER_NOT_RUNNING;
   }
   RTCS_task_abort(TFTPSRV_task_id);
   TFTPSRV_task_id = 0;
   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : TFTPSRV_Exit_handler
* Returned Value   : error code
* Comments  :  Start the TFTPSRV task.
*
*END*-----------------------------------------------------------------*/

void TFTPSRV_Exit_handler( void )
{ /* Body */
   TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr;
   
   tftpsrv_ptr = (TFTPSRV_STATE_STRUCT_PTR) _task_get_environment( _task_get_id() );
   if (tftpsrv_ptr != NULL)  {
      while (tftpsrv_ptr->NUM_TRANSACTIONS)  {
         TFTPSRV_close_transaction(tftpsrv_ptr,tftpsrv_ptr->EVENT_HEAD );    
      }
      if (tftpsrv_ptr->SRV_SOCK)  {
         shutdown(tftpsrv_ptr->SRV_SOCK, 0);
         tftpsrv_ptr->SRV_SOCK = 0;   
      }   
   }
   TFTPSRV_task_id = 0;
} /* Endbody */
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/_PE_Types.h<|end_filename|>
/** ###################################################################
**     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename    : PE_Types.h
**     Project     : ProcessorExpert
**     Processor   : MK60FN1M0VLQ12
**     Component   : PE_Types
**     Version     : Driver 01.00
**     Compiler    : CodeWarrior ARM C Compiler
**     Date/Time   : 2012-04-13, 15:02, # CodeGen: 0
**     Abstract    :
**         PE_Types.h - contains definitions of basic types,
**         register access macros and hardware specific macros
**         which can be used in user application.
**     Settings    :
**     Contents    :
**         No public methods
**
**     Copyright : 1997 - 2011 Freescale Semiconductor, Inc. All Rights Reserved.
**     
**     http      : www.freescale.com
**     mail      : <EMAIL>
** ###################################################################*/

#ifndef __PE_Types_H
#define __PE_Types_H

/* Standard ANSI C types */
#include <stdint.h>

#ifndef FALSE
  #define  FALSE  0x00u                /* Boolean value FALSE. FALSE is defined always as a zero value. */
#endif
#ifndef TRUE
  #define  TRUE   0x01u                /* Boolean value TRUE. TRUE is defined always as a non zero value. */
#endif

#ifndef NULL
  #define  NULL   0x00u
#endif

/* PE types definition */
#ifndef __cplusplus
typedef unsigned char           bool;
#endif
typedef unsigned char           byte;
typedef unsigned short          word;
typedef unsigned long           dword;
typedef unsigned long long      dlong;
typedef unsigned char           TPE_ErrCode;
#ifndef TPE_Float
typedef float                   TPE_Float;
#endif

/* Other basic data types */
typedef signed char             int8;
typedef signed short int        int16;
typedef signed long int         int32;

typedef unsigned char           uint8;
typedef unsigned short int      uint16;
typedef unsigned long int       uint32;


/**********************************************************/
/* Uniform multiplatform 8-bits peripheral access macros */
/**********************************************************/

/* Enable maskable interrupts */
#define __EI()\
 do {\
  /*lint -save  -e950 Disable MISRA rule (1.1) checking. */\
     asm(CPSIE f);\
  /*lint -restore Enable MISRA rule (1.1) checking. */\
 } while(0)

/* Disable maskable interrupts */
#define __DI() \
 do {\
  /*lint -save  -e950 Disable MISRA rule (1.1) checking. */\
     asm (CPSID f);\
  /*lint -restore Enable MISRA rule (1.1) checking. */\
 } while(0)


/* Save status register and disable interrupts */
#define EnterCritical() \
 do {\
   if (++SR_lock == 1u) {\
  /*lint -save  -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\
     asm (PUSH {R0,R1});asm(MRS R0, FAULTMASK);asm(CPSID f);asm(LDA R1, SR_reg);asm(STRB R0, [R1]);asm(POP {R0,R1});\
  /*lint -restore Enable MISRA rule (2.1,1.1) checking. */\
   }\
 } while(0)

/* Restore status register  */
#define ExitCritical() \
 do {\
   if (--SR_lock == 0u) { \
  /*lint -save  -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\
     asm (PUSH {R0,R1});asm(LDA R1, SR_reg);asm(LDRB R0, [R1]);asm(MSR FAULTMASK,R0;);asm(POP {R0,R1});\
  /*lint -restore Enable MISRA rule (2.1,1.1) checking. */\
   }\
 } while(0)


#define PE_DEBUGHALT() \
  /*lint -save  -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\
  asm (BKPT 255) \
  /*lint -restore Enable MISRA rule (2.1,1.1) checking. */

#define PE_NOP() \
  /*lint -save  -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\
  asm (NOP) \
  /*lint -restore Enable MISRA rule (2.1,1.1) checking. */

#define PE_WFI() \
  /*lint -save  -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\
  asm (WFI) \
  /*lint -restore Enable MISRA rule (2.1,1.1) checking. */


/* Interrupt definition template */
#if !defined(PE_ISR)
  #define PE_ISR(ISR_name) void ISR_name(void)
#endif

#endif /* __PE_Types_H */

/*
** ###################################################################
**
**     This file was created by Processor Expert 5.3 [05.01]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/pap.h<|end_filename|>
#ifndef __pap_h__
#define __pap_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pap.h$
* $Version : 3.0.4.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   This file contains the defines and data structure
*   definitions required by PAP.
*
*END************************************************************************/


/*
** PAP header = Code, id, length.
*/

#define PAP_HDR_LEN   (4)

/*
** PAP packet types
*/

#define PAP_CODE_AUTH_REQ  1     /* Authenticate Request */
#define PAP_CODE_AUTH_ACK  2     /* Authenticate Ack */
#define PAP_CODE_AUTH_NAK  3     /* Authenticate Nak */

/*
** Internal PAP states
*/

#define PAP_STATE_CLOSED   0
#define PAP_STATE_INITIAL  1
#define PAP_STATE_AUTH_ACK PAP_CODE_AUTH_ACK
#define PAP_STATE_AUTH_NAK PAP_CODE_AUTH_NAK

/*
** Private state required by the PAP server
*/

typedef struct pap_data {

   /* Statistics counters */
   uint_32  ST_PAP_SHORT;     /* packet too short */
   uint_32  ST_PAP_CODE;      /* invalid code */
   uint_32  ST_PAP_ID;        /* incorrect id */
   uint_32  ST_PAP_NOAUTH;    /* request received but PAP not negotiated */
   uint_32  ST_PAP_NOREQ;     /* reply received but no request made */

   uchar CLIENT_STATE;
   uchar SERVER_STATE;
   uchar CURID;
} PAP_DATA, _PTR_ PAP_DATA_PTR;


/*
** Prototypes
*/

extern void PAP_init  (_ppp_handle);
extern void PAP_send  (_ppp_handle);
extern void PAP_open  (_ppp_handle);

extern void PAP_input (PCB_PTR, _ppp_handle);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_format.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_format.c$
* $Version : 3.8.14.0$
* $Date    : Jun-27-2012$
*
* Comments:
*
*   This file contains drive specific interface functions related to 
*   formating the drive. 
*
*END*********************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"
#include "part_mgr.h"


#if !MFSCFG_READ_ONLY
    #ifdef MFSCFG_ENABLE_FORMAT


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Format
* Returned Value   : error code
* Comments  :   Perform a high-level DOS format.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Format
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] the MFS device on which to operate */
    MFS_FORMAT_DATA_PTR     format_ptr  /*[IN] information about the disk to format */
    )
{
    MFS_DRIVE_STRUCT_PTR       drive_ptr;
    FILESYSTEM_INFO_DISK_PTR   fsinfo_ptr;
    uchar_ptr                  boot_sector;
    _mfs_error                 error_code;
    uint_32                    fat_type;
    uint_32                    i;
    uint_32                    temp1;
    uint_32                    temp2;
    uint_32                    num_sectors;
    uint_32                    fat_size;
    uint_32                    rootdir_size;
    uint_32                    sys_size;
    int_32                     fat_count;
    uchar                      cluster_size;
    char                       version_str[6];

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_lock( mfs_fd_ptr, &drive_ptr );
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }

    if ( !_queue_is_empty(&drive_ptr->HANDLE_LIST) )
    {
        MFS_unlock(drive_ptr,FALSE);
        return MFS_SHARING_VIOLATION;
    }

    error_code = MFS_NO_ERROR;

    /*
    ** We are reformatting the disk, so mark it as not accessible. 
    ** ie: it's not a dos disk during the format.
    */
    drive_ptr->DOS_DISK = FALSE;

    MFS_Invalidate_directory_sector(drive_ptr);

    boot_sector = (uchar_ptr) drive_ptr->DIR_SECTOR_PTR;

    if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND1 )
    {
        fat_type = MFS_FAT12;
        rootdir_size = 7;
        cluster_size = 1;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND2 )
    {
        fat_type = MFS_FAT12;
        rootdir_size = 14;
        cluster_size = 1;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND3 )
    {
        fat_type = MFS_FAT12;
        rootdir_size = 32;
        cluster_size = 2;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND4 )
    {
        fat_type = MFS_FAT12;
        rootdir_size = 32;
        cluster_size = 4;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND5 )
    {
        fat_type = MFS_FAT12;
        rootdir_size = 32;
        cluster_size = 8;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND6 )
    {
        fat_type = MFS_FAT16;
        rootdir_size = 32;
        cluster_size = 8;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND7 )
    {
        fat_type = MFS_FAT16;
        rootdir_size = 32;
        cluster_size = 16;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND11 )
    {
        fat_type = MFS_FAT16;
        rootdir_size = 32;
        cluster_size = 32;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND8 )
    {
        fat_type = MFS_FAT32;
        rootdir_size = 0;
        cluster_size = 8;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND9 )
    {
        fat_type = MFS_FAT32;
        rootdir_size = 0;
        cluster_size = 16;
    }
    else if ( format_ptr->NUMBER_OF_SECTORS < SECTOR_BOUND10 )
    {
        fat_type = MFS_FAT32;
        rootdir_size = 0;
        cluster_size = 32;
    }
    else
    {
        fat_type = MFS_FAT32;
        rootdir_size = 0;
        cluster_size = 64;
    }  

    if ( (fat_type == MFS_FAT32) && (format_ptr->RESERVED_SECTORS < 32) )
    {
        MFS_unlock(drive_ptr,FALSE);
        return(MFS_INVALID_PARAMETER);
    }

    /* 
    ** Make sure the format parameters are big enoughh to initialize file system
    */
    if ( format_ptr->NUMBER_OF_SECTORS <= (format_ptr->RESERVED_SECTORS + rootdir_size) )
    {
        MFS_unlock(drive_ptr,FALSE);
        return(MFS_INVALID_PARAMETER);
    }


    drive_ptr->BPB.MEGA_SECTORS = format_ptr->NUMBER_OF_SECTORS;

    num_sectors = format_ptr->NUMBER_OF_SECTORS - format_ptr->RESERVED_SECTORS - rootdir_size;


    /*
    ** The formula is:
    **
    **                  / cluster_size * sector_size     \
    **   num_sectors = (  -------------------------- + 2  ) * fat_size
    **                  \         (1.5 or 2)             /
    **
    */
    if ( fat_type == MFS_FAT12 )
    {
        i = 2*format_ptr->BYTES_PER_SECTOR*cluster_size + 6;
        fat_size = 1 + (3*num_sectors - 1) / i;
    }
    else if ( fat_type == MFS_FAT16 )
    {
        i = format_ptr->BYTES_PER_SECTOR*cluster_size/2 + 2;
        fat_size = 1 + (num_sectors - 1) / i;
    }
    else
    {
        temp1 = format_ptr->NUMBER_OF_SECTORS - format_ptr->RESERVED_SECTORS;
        temp2 = (256 * cluster_size + MFSCFG_NUM_OF_FATS) / 2;
        fat_size = (temp1 + temp2 - 1) /temp2;
    } 

    _mem_zero( boot_sector, format_ptr->BYTES_PER_SECTOR );
    sys_size = rootdir_size+MFSCFG_NUM_OF_FATS*fat_size+format_ptr->RESERVED_SECTORS;
    for ( i=format_ptr->RESERVED_SECTORS+1; i < sys_size; i++ )
    {
        error_code = MFS_Write_device_sector(drive_ptr, i,(char_ptr)boot_sector);
        if ( error_code )
        {
            MFS_unlock(drive_ptr,TRUE);
            return(error_code);
        }
    }  


    /* If we have a fat32 drive, we must clear the root dir cluster */
    if ( fat_type == MFS_FAT32 )
    {
        for ( i = 0 ; i < cluster_size && !error_code; i++ )
        {
            error_code = MFS_Write_device_sector(drive_ptr, sys_size + i, (char_ptr)boot_sector);
        }  
        if ( error_code )
        {
            MFS_unlock(drive_ptr,TRUE);
            return( error_code );
        }
    }


    /* now write the first sector of each FAT */
    boot_sector[0] = format_ptr->MEDIA_DESCRIPTOR;
    boot_sector[1] = 0xFF;
    boot_sector[2] = 0xFF;

    if ( fat_type == MFS_FAT16 )
    {
        boot_sector[3] = 0xFF;
    }

    if ( fat_type == MFS_FAT32 )
    {
        boot_sector[3] = 0x0F;
        boot_sector[4] = 0xFF;
        boot_sector[5] = 0xFF;
        boot_sector[6] = 0xFF;
        boot_sector[7] = 0x0F;

        /* First cluster of root entry */
        boot_sector[8] = 0xFF;
        boot_sector[9] = 0xFF;
        boot_sector[10] = 0xFF;
        boot_sector[11] = 0x0F;
    }

    fat_count = MFSCFG_NUM_OF_FATS;
    while ( --fat_count >= 0 )
    {
        error_code = MFS_Write_device_sector(drive_ptr, format_ptr->RESERVED_SECTORS + (uint_32) fat_count * fat_size, (char_ptr)boot_sector);

        if ( error_code )
        {
            MFS_unlock(drive_ptr,TRUE);
            return(error_code);
        }
    } /* EndWhile */

    boot_sector[0] = 0xEB;    /* jmp boot_sector[62] */
    boot_sector[1] = 0x3C;
    boot_sector[2] = 0x90;    /* nop */

    /* Write MFS and version number as OEM name */
    sprintf(version_str,"%x",MFS_VERSION);
    _mem_copy("MFS", boot_sector+3, 3);
    _mem_copy(version_str, boot_sector+6, 5);

    boot_sector[11] = (uchar) ((format_ptr->BYTES_PER_SECTOR)      & 0xFF);
    boot_sector[12] = (uchar) ((format_ptr->BYTES_PER_SECTOR >> 8) & 0xFF);

    boot_sector[13] = cluster_size;

    boot_sector[14] = (uchar) ((format_ptr->RESERVED_SECTORS)      & 0xFF);
    boot_sector[15] = (uchar) ((format_ptr->RESERVED_SECTORS >> 8) & 0xFF);

    boot_sector[16] = MFSCFG_NUM_OF_FATS;      /* number of FATs */

    rootdir_size *= format_ptr->BYTES_PER_SECTOR >> 5;
    boot_sector[17] = (uchar) ((rootdir_size)      & 0xFF);
    boot_sector[18] = (uchar) ((rootdir_size >> 8) & 0xFF);

    if ( (format_ptr->NUMBER_OF_SECTORS+format_ptr->HIDDEN_SECTORS) <= MAX_UINT_16 )
    {
        boot_sector[19] = (uchar) ((format_ptr->NUMBER_OF_SECTORS)      & 0xFF);
        boot_sector[20] = (uchar) ((format_ptr->NUMBER_OF_SECTORS >> 8) & 0xFF);
    }
    else
    {
        /* boot_sector[19..20] should already be 0 */
        boot_sector[32] = (uchar) ((format_ptr->NUMBER_OF_SECTORS)       & 0xFF);
        boot_sector[33] = (uchar) ((format_ptr->NUMBER_OF_SECTORS >>  8) & 0xFF);
        boot_sector[34] = (uchar) ((format_ptr->NUMBER_OF_SECTORS >> 16) & 0xFF);
        boot_sector[35] = (uchar) ((format_ptr->NUMBER_OF_SECTORS >> 24) & 0xFF);
    }  

    boot_sector[21] = format_ptr->MEDIA_DESCRIPTOR;

    if ( fat_type != MFS_FAT32 )
    {
        boot_sector[22] = (uchar) ((fat_size)       & 0xFF);
        boot_sector[23] = (uchar) ((fat_size >> 8)  & 0xFF);
    }
    else
    {
        boot_sector[36] = (uchar) ((fat_size)       & 0xFF);
        boot_sector[37] = (uchar) ((fat_size >> 8)  & 0xFF);
        boot_sector[38] = (uchar) ((fat_size >> 16) & 0xFF);
        boot_sector[39] = (uchar) ((fat_size >> 24) & 0xFF);      
    }

    boot_sector[24] = (uchar) ((format_ptr->SECTORS_PER_TRACK)      & 0xFF);
    boot_sector[25] = (uchar) ((format_ptr->SECTORS_PER_TRACK >> 8) & 0xFF);

    boot_sector[26] = (uchar) ((format_ptr->NUMBER_OF_HEADS)      & 0xFF);
    boot_sector[27] = (uchar) ((format_ptr->NUMBER_OF_HEADS >> 8) & 0xFF);

    boot_sector[28] = (uchar) ((format_ptr->HIDDEN_SECTORS)       & 0xFF);
    boot_sector[29] = (uchar) ((format_ptr->HIDDEN_SECTORS >>  8) & 0xFF);
    boot_sector[30] = (uchar) ((format_ptr->HIDDEN_SECTORS >> 16) & 0xFF);
    boot_sector[31] = (uchar) ((format_ptr->HIDDEN_SECTORS >> 24) & 0xFF);

    if ( fat_type == MFS_FAT32 )
    {
        /* fields 40 and 41 are for FAT mirroring */
        boot_sector[40] = 0x00;    
        boot_sector[41] = 0x00;   

        boot_sector[42] = (uchar) ((MFS_FAT32_VER) & 0xFF); /* Minor FAT 32 rev */
        boot_sector[43] = (uchar) ((MFS_FAT32_VER >> 8) & 0xFF); /* Major rev  */

        /* Root Cluster for FAT32... cluster 2 is the standard */
        boot_sector[44] = 0x02;    
        boot_sector[45] = 0x00;
        boot_sector[46] = 0x00;
        boot_sector[47] = 0x00;

        /* BPB_FSINFO struct...  The standard is sector 1 */
        boot_sector[48] = (uchar) ((FSINFO_SECTOR)      & 0xFF);
        boot_sector[49] = (uchar) ((FSINFO_SECTOR >> 8) & 0xFF);

        /* Back up boot sector... The standard is sector 6  */
        boot_sector[50] = (uchar) ((BKBOOT_SECTOR)      & 0xFF);
        boot_sector[51] = (uchar) ((BKBOOT_SECTOR >> 8) & 0xFF);

        /* Fields 52 to 63 are reserved. They are already zeroed */

        boot_sector[64] = format_ptr->PHYSICAL_DRIVE;
        boot_sector[66] = 0x29;  /* Extended boot signature */

        /* Volume label and ID */       
        _mem_copy("NO NAME    FAT32   ", boot_sector+71, 19);  
    }
    else
    {

        boot_sector[36] = format_ptr->PHYSICAL_DRIVE;

        boot_sector[38] = 0x29;  /* Extended boot signature */

        if ( fat_type == MFS_FAT12 )
        {
            /* Volume label and ID */
            _mem_copy("NO NAME    FAT12   ", boot_sector+43, 19);  
        }
        else if ( fat_type == MFS_FAT16 )
        {
            /* Volume label and ID */
            _mem_copy("NO NAME    FAT16   ", boot_sector+43, 19);  
        }

        boot_sector[62] = 0x33;  /* xor ax, ax */
        boot_sector[63] = 0xC0;
        boot_sector[64] = 0x8E;  /* mov ss, ax */
        boot_sector[65] = 0xD0;
        boot_sector[66] = 0xBC;  /* mov sp, 7C00 */
        boot_sector[67] = 0x00;
        boot_sector[68] = 0x7C;
        boot_sector[69] = 0xFC;  /* cld */
        boot_sector[70] = 0xE8;  /* call boot_sector[118] */
        boot_sector[71] = 45;
        boot_sector[72] = 0;

        _mem_copy("\r\nNon-System disk\r\nPress any key to reboot\r\n", boot_sector+73, 45);

        boot_sector[118] = 0x5E; /* pop si */
        boot_sector[119] = 0xEB; /* jmp boot_sector[123] */
        boot_sector[120] = 0x02;
        boot_sector[121] = 0xCD; /* int 10 */
        boot_sector[122] = 0x10;
        boot_sector[123] = 0xB4; /* mov ah, 0E */
        boot_sector[124] = 0x0E;
        boot_sector[125] = 0xBB; /* mov bx, 0007 */
        boot_sector[126] = 0x07;
        boot_sector[127] = 0x00;
        boot_sector[128] = 0x2E; /* cs:lodsb */
        boot_sector[129] = 0xAC;
        boot_sector[130] = 0x84; /* test al, al */
        boot_sector[131] = 0xC0;
        boot_sector[132] = 0x75; /* jnz boot_sector[121] */
        boot_sector[133] = 0xF3;
        boot_sector[134] = 0x98; /* cbw */
        boot_sector[135] = 0xCD; /* int 16 */
        boot_sector[136] = 0x16;
        boot_sector[137] = 0xCD; /* int 19 */
        boot_sector[138] = 0x19;
        boot_sector[139] = 0xEB; /* jmp boot_sector[62] */
        boot_sector[140] = 0xB1;
    }
    boot_sector[format_ptr->BYTES_PER_SECTOR-2] = 0x55;
    boot_sector[format_ptr->BYTES_PER_SECTOR-1] = 0xAA;

    error_code = MFS_Write_device_sector(drive_ptr, BOOT_SECTOR, (char_ptr)boot_sector);

    if ( (error_code == MFS_NO_ERROR) && ( fat_type == MFS_FAT32) )
    {
        error_code = MFS_Write_device_sector(drive_ptr, BKBOOT_SECTOR, (char_ptr)boot_sector);

        if ( error_code == MFS_NO_ERROR )
        {
             fsinfo_ptr = (FILESYSTEM_INFO_DISK_PTR) drive_ptr->DIR_SECTOR_PTR;
             htodl(fsinfo_ptr->LEAD_SIG, FSI_LEADSIG);
             htodl(fsinfo_ptr->STRUCT_SIG, FSI_STRUCTSIG);
             htodl(fsinfo_ptr->FREE_COUNT, 0xFFFFFFFF);   /* compute it */
             htodl(fsinfo_ptr->NEXT_FREE, 0xFFFFFFFF);  /* compute it */
             htodl(fsinfo_ptr->TRAIL_SIG, FSI_TRAILSIG);

             error_code = MFS_Write_device_sector(drive_ptr, FSINFO_SECTOR, (char_ptr)fsinfo_ptr);

             if ( error_code == MFS_NO_ERROR )
             {
                 error_code = MFS_Read_device_sector (drive_ptr, 0, drive_ptr->DIR_SECTOR_PTR);
             }             
        }
    }

    drive_ptr->DIR_SECTOR_NUMBER = 0;
    drive_ptr->DIR_SECTOR_DIRTY  = FALSE;

    if ( error_code == MFS_NO_ERROR )
    {
        MFS_Mount_drive_internal( drive_ptr );
    }

    /* Calculate the free space on disk */
    if ( error_code == MFS_NO_ERROR )
    {
        MFS_Get_disk_free_space_internal(drive_ptr,&error_code);
    }
    MFS_unlock(drive_ptr,FALSE);

    return(error_code);
}  

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Default_Format
* Returned Value   : error code
* Comments  :   Perform a high-level DOS format with default values.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Default_Format
    (
    MQX_FILE_PTR            mfs_fd_ptr /*[IN] the MFS device on which to operate */
    )
{
    MFS_DRIVE_STRUCT_PTR   drive_ptr;
    MFS_FORMAT_DATA        format_data;
    uint_32                sector_size, num_sectors, reserved_sectors;
    _mfs_error             error_code;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif
    
    /* lock the drive */
    error_code = MFS_lock( mfs_fd_ptr, &drive_ptr );
    if (error_code != MFS_NO_ERROR) {
        return error_code;
    }
    
    /* get the device sector size */
    error_code  = _io_ioctl(drive_ptr->DEV_FILE_PTR, IO_IOCTL_GET_BLOCK_SIZE, &sector_size);
    /* get the number of sectors */
    if (error_code == MFS_NO_ERROR) {
        error_code  = _io_ioctl(drive_ptr->DEV_FILE_PTR, IO_IOCTL_GET_NUM_SECTORS, &num_sectors);
    }
    /* unlock the drive */
    MFS_unlock(drive_ptr,FALSE);

    if (error_code == MFS_NO_ERROR) {
        /* set reserved sectors. For FAT12, FAT16 should be 1 */
        /* for FAT32 usualy 32 */
        if (num_sectors < SECTOR_BOUND11) {
            reserved_sectors = 1;
        } else {
            reserved_sectors = 32;
        }
        /* fill the MFS_FORMAT_DATA structure. This values are used in format command */
        /* this is the default settings */
        format_data.PHYSICAL_DRIVE    = 0x80;
        format_data.MEDIA_DESCRIPTOR  = 0xf8;
        format_data.BYTES_PER_SECTOR  = sector_size;
        format_data.SECTORS_PER_TRACK = 0x00;
        format_data.NUMBER_OF_HEADS   = 0x00;
        format_data.NUMBER_OF_SECTORS = num_sectors - reserved_sectors;
        format_data.HIDDEN_SECTORS    = 0;
        format_data.RESERVED_SECTORS  = reserved_sectors;
    
        /* format drive */
        error_code = MFS_Format(mfs_fd_ptr, &format_data);
    }
    return error_code;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Test_unused_clusters
* Returned Value   : error code
* Comments  :   Perform a sector test.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Test_unused_clusters
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] the MFS device on which to operate */
    uint_32_ptr             count_ptr   /*[IN/OUT] number of bad clusters detected */
    )
{
    MFS_DRIVE_STRUCT_PTR    drive_ptr;
    uchar_ptr               cluster_buffer;
    uint_32                 cluster_status;
    uint_32                 cluster_num;
    uint_32                 sector_num;
    _mfs_error              error_code;
    uint_32                 io_error;

#if MFSCFG_READ_ONLY_CHECK
    if ( MFS_is_read_only(mfs_fd_ptr, NULL) )
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_lock_dos_disk(mfs_fd_ptr, &drive_ptr);
    if ( error_code != MFS_NO_ERROR )
    {
        return error_code;
    }

    cluster_buffer = MFS_mem_alloc_system_zero(drive_ptr->CLUSTER_SIZE_BYTES);

    if ( cluster_buffer == NULL )
    {
        error_code = MFS_INSUFFICIENT_MEMORY;
        MFS_unlock(drive_ptr, FALSE);
        return error_code;
    }
    _mem_set_type(cluster_buffer,MEM_TYPE_MFS_CLUSTER);

    *count_ptr = 0;

    cluster_num = CLUSTER_MIN_GOOD;
    sector_num = drive_ptr->DATA_START_SECTOR;

    while ( cluster_num<=drive_ptr->LAST_CLUSTER && error_code==MFS_NO_ERROR )
    {
        /*
        ** Test all UNUSED clusters (after a format, all clusters are free)
        */

        error_code = MFS_get_cluster_from_fat(drive_ptr, cluster_num, &cluster_status);

        if ( error_code==MFS_NO_ERROR && cluster_status==CLUSTER_UNUSED )
        {
            /* Check the cluster by performing write with no retries */
            io_error = MFS_Write_device_sectors(drive_ptr, sector_num, drive_ptr->BPB.SECTORS_PER_CLUSTER, 0, (char_ptr)cluster_buffer, NULL);

            switch ( io_error )
            {
                case MFS_WRITE_FAULT:
                case MFS_READ_FAULT:
                case MFS_SECTOR_NOT_FOUND:
                    error_code = MFS_Put_fat(drive_ptr, cluster_num, CLUSTER_BAD);
                    (*count_ptr)++;
                    break;
                case MFS_DISK_IS_WRITE_PROTECTED:
                    error_code = MFS_DISK_IS_WRITE_PROTECTED;
                    break;
            }
        }

        cluster_num++;
        sector_num += drive_ptr->BPB.SECTORS_PER_CLUSTER;
    }  

    if ( error_code==MFS_NO_ERROR )
    {
        error_code = MFS_Write_back_fat(drive_ptr);
    }

    _mem_free(cluster_buffer);
    MFS_unlock(drive_ptr,TRUE);

    return error_code;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_Format_and_test
* Returned Value   : error code
* Comments  :   Perform a high-level DOS format.
*
*END*---------------------------------------------------------------------*/

_mfs_error MFS_Format_and_test
    (
    MQX_FILE_PTR            mfs_fd_ptr, /*[IN] logical number of the storage medium for the file system */
    MFS_FORMAT_DATA_PTR     format_ptr, /*[IN] information about the disk to format */
    uint_32_ptr             count_ptr   /*[IN/OUT] number of bad clusters detected */
    )
{
    _mfs_error        error_code;

#if MFSCFG_READ_ONLY_CHECK
    if (MFS_is_read_only (mfs_fd_ptr, NULL))
    {
        return MFS_DISK_IS_WRITE_PROTECTED;
    }
#endif

    error_code = MFS_Format( mfs_fd_ptr, format_ptr );

    if ( !error_code )
    {
        error_code = MFS_Test_unused_clusters( mfs_fd_ptr, count_ptr );
    }

    return(error_code);
}  

    #endif
#endif



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ifppp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ifppp.c$
* $Version : 3.6.6.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the interface functions for the
*   IPCP client.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ipcp.h"


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : RTCS_if_bind_IPCP
* Returned Values : uint_32 (error code)
* Comments        :
*     Initialize a PPP interface.
*
*END*-----------------------------------------------------------------*/

uint_32 RTCS_if_bind_IPCP
   (
      _rtcs_if_handle         handle,
         /* [IN] the RTCS interface state structure */
      IPCP_DATA_STRUCT_PTR    data_ptr
         /* [IN/OUT] IPCP parameters */
   )
{ /* Body */
   TCPIP_PARM_IPCP         parms;

   if (handle==NULL) 
   {
      return RTCSERR_INVALID_PARAMETER; 
   }
   
   parms.handle = handle;
   parms.data   = data_ptr;

   return RTCSCMD_issue(parms, IPCP_bind);

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/Tests.h<|end_filename|>
#ifndef __TESTS
  #define __TESTS


#endif


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/classes/include/usb_msc.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_msc.h$
* $Version : 3.8.5.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
* @brief The file contains USB stack MSC class layer api header function.
*
*****************************************************************************/

#ifndef _USB_MSC_H
#define _USB_MSC_H 1

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "devapi.h"  
#include "usb_class.h"
#include "usb_framework.h"
/******************************************************************************
 * Constants - None
 *****************************************************************************/

/******************************************************************************
 * Macro's
 *****************************************************************************/
#define USB_MSC_DEVICE_READ_REQUEST     (0x81)
#define USB_MSC_DEVICE_WRITE_REQUEST    (0x82) 
#define USB_MSC_DEVICE_FORMAT_COMPLETE  (0x83)
#define USB_MSC_DEVICE_REMOVAL_REQUEST  (0x84)
#define USB_MSC_DEVICE_GET_INFO         (0x85)
#define USB_MSC_START_STOP_EJECT_MEDIA  (0x86) 

/* Class specific request Codes */
#define BULK_ONLY_MASS_STORAGE_RESET          (0xFF)
#define GET_MAX_LUN                           (0xFE)
#define PUT_REQUESTS                          (0xFD)
#define GET_REQUESTS                          (0xFC)

/* Events to the Application */ /* 0 to 4 are reserved for class events */

/* other macros */
#define  USB_DCBWSIGNATURE       LONG_BE_TO_HOST_CONST(0x55534243)
#define  USB_DCSWSIGNATURE       LONG_BE_TO_HOST_CONST(0x55534253)
#define  USB_CBW_DIRECTION_BIT   (0x80)
#define  USB_CBW_DIRECTION_SHIFT (7)
#define  MSC_CBW_LENGTH          (31)
#define  MSC_CSW_LENGTH          (13)

#define COMMAND_PASSED                (0x00)
#define COMMAND_FAILED                (0x01)
#define PHASE_ERROR                   (0x02)
/* macros for queuing */
 #define MSD_MAX_QUEUE_ELEMS  (4)

/* MACROS FOR COMMANDS SUPPORTED */
 #define INQUIRY_COMMAND                    (0x12)
 #define READ_10_COMMAND                    (0x28)
 #define READ_12_COMMAND                    (0xA8)
 #define REQUEST_SENSE_COMMAND              (0x03)
 #define TEST_UNIT_READY_COMMAND            (0x00)
 #define WRITE_10_COMMAND                   (0x2A)
 #define WRITE_12_COMMAND                   (0xAA)
 #define PREVENT_ALLOW_MEDIUM_REM_COMMAND   (0x1E)
 #define FORMAT_UNIT_COMMAND                (0x04)
 #define READ_CAPACITY_10_COMMAND           (0x25)
 #define READ_FORMAT_CAPACITIES_COMMAND     (0x23)
 #define MODE_SENSE_10_COMMAND              (0x5A) 
 #define MODE_SENSE_6_COMMAND               (0x1A)
 #define MODE_SELECT_10_COMMAND             (0x55)
 #define MODE_SELECT_6_COMMAND              (0x15)
 #define SEND_DIAGNOSTIC_COMMAND            (0x1D)
 #define VERIFY_COMMAND                     (0x2F)
 #define START_STOP_UNIT_COMMAND            (0x1B)
  
 #define MAX_MSC_DEVICE                     (0x01)
 
/*****************************************************************************
 * Local Functions
 *****************************************************************************/
void USB_Service_Bulk_In(PTR_USB_EVENT_STRUCT event,pointer arg);
void USB_Service_Bulk_Out(PTR_USB_EVENT_STRUCT event,pointer arg);
void USB_Class_MSC_Event(uint_8 event, void* val,pointer arg);
/******************************************************************************
 * Types
 *****************************************************************************/
 
typedef uint_32 MSD_HANDLE;

typedef struct _app_data_struct 
{
    uint_8_ptr      data_ptr;         /* pointer to buffer       */            
    uint_32 data_size;                /* buffer size of endpoint */
}APP_DATA_STRUCT;
 
/* structure to hold a request in the endpoint queue */
typedef struct _usb_class_msc_queue 
{
    _usb_device_handle  handle;
    uint_8 channel;       
    APP_DATA_STRUCT app_data;  
}USB_CLASS_MSC_QUEUE, *PTR_USB_CLASS_MSC_QUEUE;
 
/* USB class msc endpoint data */
typedef struct _usb_class_msc_endpoint 
{
    uint_8 endpoint; /* endpoint num */                    
    uint_8 type;     /* type of endpoint (interrupt, bulk or isochronous) */   
    uint_8 bin_consumer;/* the num of queued elements */
    uint_8 bin_producer;/* the num of de-queued elements */
    USB_CLASS_MSC_QUEUE queue[MSD_MAX_QUEUE_ELEMS]; /* queue data */  
}USB_CLASS_MSC_ENDPOINT;

typedef struct _usb_msc_cbw   /* Command Block Wrapper -- 31 bytes */
{
    uint_32 signature;        /*0-3  : dCBWSignature*/
    uint_32 tag;              /*4-7  : dCBWTag*/
    uint_32 data_length;      /*8-11 : dCBWDataTransferLength*/
    uint_8  flag;             /*12   : bmCBWFlags*/
    uint_8  lun;              /*13   : bCBWLUN(bits 3 to 0)*/
    uint_8  cb_length;        /*14   : bCBWCBLength*/
    uint_8  command_block[16];/*15-30 : CBWCB*/
}CBW, *PTR_CBW ;

typedef struct _usb_msc_csw   /* Command Status Wrapper -- 13 bytes */
{
    uint_32 signature; /*0-3  : dCSWSignature*/
    uint_32 tag;       /*4-7 : dCSWTag*/
    uint_32 residue;   /*8-11 : dCSWDataResidue*/
    uint_8 csw_status; /*12 : bCSWStatus*/
}CSW, *PTR_CSW;

typedef struct _lba_info_struct
{
    uint_32 starting_lba;/* LBA to start transfering with */
    uint_32 lba_transfer_num;/* number of LBAs to transfer */    
}LBA_INFO_STRUCT, * PTR_LBA_INFO_STRUCT;

typedef struct _lba_app_struct
{
    uint_32 offset;
    uint_32 size;
    uint_8_ptr buff_ptr;
}LBA_APP_STRUCT, * PTR_LBA_APP_STRUCT;

typedef struct _device_lba_info_struct
{
    uint_32 total_lba_device_supports;/* lab : LOGICAL ADDRESS BLOCK */ 
    uint_32 length_of_each_lab_of_device;
    uint_8 num_lun_supported; 
}DEVICE_LBA_INFO_STRUCT, * PTR_DEVICE_LBA_INFO_STRUCT;

typedef struct _msc_thirteen_case_check
{
    _usb_device_handle handle;
    uint_32 host_expected_data_len;
    uint_8 host_expected_direction;
    uint_32 device_expected_data_len;
    uint_8 device_expected_direction;
    uint_8_ptr csw_status_ptr;
    uint_32_ptr csw_residue_ptr;
    uint_8_ptr buffer_ptr;
    boolean lba_txrx_select;
    LBA_INFO_STRUCT lba_info;
}MSC_THIRTEEN_CASE_STRUCT, *PTR_MSC_THIRTEEN_CASE_STRUCT;

typedef struct _msd_buffers_info
{
     uint_8_ptr msc_lba_send_ptr;
     uint_8_ptr msc_lba_recv_ptr;
     uint_32 msc_lba_send_buff_size;
     uint_32 msc_lba_recv_buff_size;
}MSD_BUFF_INFO, *PTR_MSD_BUFF_INFO;
/* MSD Device Structure */
typedef struct _msc_variable_struct
{
    _usb_device_handle controller_handle;
    MSD_HANDLE msc_handle;
    USB_CLASS_HANDLE class_handle;
    USB_ENDPOINTS *ep_desc_data;
    USB_CLASS_CALLBACK_STRUCT msc_callback;
    USB_REQ_CALLBACK_STRUCT       vendor_callback;            
    USB_CLASS_CALLBACK_STRUCT param_callback;
    uint_8            bulk_in_endpoint; 
    uint_32           bulk_in_endpoint_packet_size;
    uint_8            bulk_out_endpoint;
    uint_32           usb_max_suported_interfaces;
     /* contains the endpoint info */
    /* Memory Allocation for endpoint done at App layer. Only App
       Knows how many endpoints to allocate.
     */
     void *  scsi_object_ptr;
     
    USB_CLASS_MSC_ENDPOINT *ep;
     /* macro configuired by user*/
     /* LUN can have value only from 0 to 15 decimal */
    uint_8 lun;
    /* flag to track bulk out data processing after CBW if needed*/
    boolean out_flag; 
    /* flag to track bulk in data processing before CSW if needed*/
    boolean in_flag; 
    /* flag to track if there is need to stall BULK IN ENDPOINT 
       because of BULK COMMAND*/
    boolean in_stall_flag; 
    /* flag to track if there is need to stall BULK OUT ENDPOINT
       because of BULK COMMAND */
    boolean out_stall_flag; 
    /* flag to validate CBW */
    boolean cbw_valid_flag; 
    /* global structure for command status wrapper */
    PTR_CSW csw_ptr; 
    /* global structure for command block wrapper */
    PTR_CBW cbw_ptr; 
    boolean re_stall_flag;
    DEVICE_LBA_INFO_STRUCT device_info;
    MSD_BUFF_INFO msd_buff;
    /* following two macros are used to manage transfers involving read/write 
       on APPLICATION MASS STORAGE DEVICE */
    uint_32 transfer_remaining;
    uint_32 current_offset;     
}MSC_DEVICE_STRUCT, _PTR_ MSC_DEVICE_STRUCT_PTR; 

/* MSD Configuration structure to be passed by APP*/
typedef struct _usb_msd_config 
{
    /* SCSI related initialization data. To be moved to SCSI layer.*/
     DEVICE_LBA_INFO_STRUCT device_info;
     boolean implementing_disk_drive;
     uint_32 usb_max_suported_interfaces;
     /*****************************************/
     uint_8  bulk_in_endpoint; 
     uint_32 bulk_in_endpoint_packet_size;
     uint_8  bulk_out_endpoint;
     uint_32 desc_endpoint_cnt;
     MSD_BUFF_INFO msd_buff;
     USB_ENDPOINTS *ep_desc_data;
     USB_CLASS_MSC_ENDPOINT *ep;
     USB_CLASS_CALLBACK_STRUCT_PTR msc_class_callback;
     USB_REQ_CALLBACK_STRUCT_PTR   vendor_req_callback;
     USB_CLASS_CALLBACK_STRUCT_PTR param_callback; 
     DESC_CALLBACK_FUNCTIONS_STRUCT_PTR  desc_callback_ptr; 
}USB_MSD_CONFIG_STRUCT, _PTR_ USB_MSD_CONFIG_STRUCT_PTR;
/******************************************************************************
 * Global Functions
 *****************************************************************************/
/**************************************************************************//*!
 *
 * @name  USB_Class_MSC_Init
 *
 * @brief The funtion initializes the Device and Controller layer 
 *
 * @param msd_config_ptr    : Configuration paramemter strucutre pointer
 *                            passed by APP.
 * @return status       
 *         MSD Handle           : When Successfull 
 *         Others           : Errors
 ******************************************************************************
 *
 *This function initializes the MSC Class layer and layers it is dependednt on 
 ******************************************************************************/
MSD_HANDLE USB_Class_MSC_Init
(
   USB_MSD_CONFIG_STRUCT_PTR msd_config_ptr /*[IN]*/
); 

/**************************************************************************//*!
 *
 * @name  USB_Class_MSC_Send_Data
 *
 * @brief 
 *
 * @param msc_handle   :   handle returned from USB_Class_MSC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
extern uint_8 USB_Class_MSC_Send_Data
(
    MSD_HANDLE          msc_handle,
    uint_8              ep_num,
    uint_8_ptr           buff_ptr,      /* [IN] buffer to send */      
    uint_32             size           /* [IN] length of the transfer */
);

/**************************************************************************//*!
 *
 * @name  USB_MSC_LBA_Transfer
 *
 * @brief 
 *
 * @param MSC_DEVICE_STRUCT_PTR   
 * @param direction       :   transfer direction
 * @param lba_info_ptr    :   buffer to send
 *
 * @return status       
 *         USB_OK           : When Successfull 
 *         Others           : Errors
 *****************************************************************************/
extern uint_8 USB_MSC_LBA_Transfer
(
    MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
    boolean direction,
    PTR_LBA_INFO_STRUCT lba_info_ptr
);

#define USB_MSC_Bulk_Send_Data(a,b,c)  USB_Class_MSC_Send_Data(a,msc_obj_ptr->bulk_in_endpoint,b,c)
#define USB_MSC_Bulk_Recv_Data(a,b,c)  _usb_device_recv_data(a,msc_obj_ptr->bulk_out_endpoint,b,c)

#define USB_MSC_Periodic_Task USB_Class_Periodic_Task 

/* Sub Class Functions */

 /**************************************************************************//*!
 *
 * @name  USB_MSC_SCSI_Init
 *
 * @brief The funtion initializes the SCSI parameters and callbacks
 *
 * @param msc_obj_ptr         MSD class object pointer.
 * @param cb:                 event callback
 * @param storage_disk        Ramdisk Memory pointer.
 * @param lb                  logical block
 * @param lab_len             lenght of each logical blocks
 *
 * @return status
 *         USB_OK           : When Successfull
 *         Others           : Errors
 *
 *****************************************************************************/
extern uint_8 USB_MSC_SCSI_Init
(
     MSC_DEVICE_STRUCT_PTR  msc_obj_ptr,
     USB_CLASS_CALLBACK_STRUCT_PTR cb,
     PTR_DEVICE_LBA_INFO_STRUCT device_info_ptr,
     uint_32 implementing_disk_drive
);
                                       

/**************************************************************************//*!
 *
 * @name  msc_inquiry_command
 *
 * @brief It requests that information regarding parameters of the Device be
 *        sent to the Host Computer
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/

extern uint_8 msc_inquiry_command (MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                   PTR_CBW cbw_ptr, 
                                   uint_32* csw_residue_ptr, 
                                   uint_8* csw_status_ptr);
/**************************************************************************//*!
 *
 * @name  msc_read_command
 *
 * @brief command requests that device transfer data to the host computer
 *        (read (10) command)
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_read_command (MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                PTR_CBW cbw_ptr, 
                                uint_32* csw_residue_ptr, 
                                uint_8* csw_status_ptr); 
 /**************************************************************************//*!
 *
 * @name  msc_request_sense_command
 *
 * @brief command instructs the Device to transfer sense data to host computer
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return NONE
 *
 *****************************************************************************/
extern uint_8 msc_request_sense_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                        PTR_CBW cbw_ptr, 
                                        uint_32* csw_residue_ptr, 
                                        uint_8* csw_status_ptr); 
/**************************************************************************//*!
 *
 * @name  msc_test_unit_ready_command
 *
 * @brief It provides a means to check if the device is ready
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_test_unit_ready_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                          PTR_CBW cbw_ptr, 
                                          uint_32* csw_residue_ptr, 
                                          uint_8* csw_status_ptr); 
/**************************************************************************//*!
 *
 * @name  msc_verify_command
 *
 * @brief requests that device verifies the data on medium
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_verify_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                 PTR_CBW cbw_ptr,
                                 uint_32* csw_residue_ptr,
                                 uint_8* csw_status_ptr);                                         
/**************************************************************************//*!
 *
 * @name  msc_mode_sense_command
 *
 * @brief command provides a means for a Device to report parameters to Host
 *        Computer.It is a complementary command to the MODE SELECT command.
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_mode_sense_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                     PTR_CBW cbw_ptr, 
                                     uint_32* csw_residue_ptr, 
                                     uint_8* csw_status_ptr);
/**************************************************************************//*!
 *
 * @name  msc_mode_select_command
 *
 * @brief command provides a means for a Device to report parameters to Host
 *        Computer.It is a complementary command to the MODE SENSE command.
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_mode_select_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                      PTR_CBW cbw_ptr, 
                                      uint_32* csw_residue_ptr, 
                                      uint_8* csw_status_ptr);                                     
/**************************************************************************//*!
 *
 * @name  msc_read_capacity_command
 *
 * @brief command provides a means for the host computer to request information
 *        regarding the capacity of the installed medium of the device.
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_read_capacity_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                        PTR_CBW cbw_ptr, 
                                        uint_32* csw_residue_ptr, 
                                        uint_8* csw_status_ptr); 
/**************************************************************************//*!
 *
 * @name  msc_format_unit_command
 *
 * @brief host sends the FORMAT UNIT command to physically format a diskette
 *        according to selected options
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_format_unit_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                      PTR_CBW cbw_ptr, 
                                      uint_32* csw_residue_ptr, 
                                      uint_8* csw_status_ptr); 
/**************************************************************************//*!
 *
 * @name  msc_write_command
 *
 * @brief command requests that the Device write the data transferred by the
 *        Host Computer to the medium.
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_write_command (MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                 PTR_CBW cbw_ptr, 
                                 uint_32* csw_residue_ptr, 
                                 uint_8* csw_status_ptr); 
/**************************************************************************//*!
 *
 * @name  msc_start_stop_unit_command
 *
 * @brief command instructs device to enable or disable media access operations
 *
 * @param controller_ID:        To identify the controller 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_start_stop_unit_command
(
    MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
    PTR_CBW cbw_ptr,
    uint_32* csw_residue_ptr,
    uint_8* csw_status_ptr
);
                                 
/**************************************************************************//*!
 *
 * @name  msc_prevent_allow_medium_removal
 *
 * @brief command tells the UFI device to enable or disable the removal of the
 *        medium in the logical unit.
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_prevent_allow_medium_removal(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                               PTR_CBW cbw_ptr, 
                                               uint_32* csw_residue_ptr, 
                                               uint_8* csw_status_ptr); 
/**************************************************************************//*!
 *
 * @name  msc_read_format_capacity_command
 *
 * @brief allows the host to request a list of the possible capacities that
 *        can be formatted on the currently installed medium
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_read_format_capacity_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                               PTR_CBW cbw_ptr, 
                                               uint_32* csw_residue_ptr, 
                                               uint_8* csw_status_ptr);  
                                               
/**************************************************************************//*!
 *
 * @name  msc_send_diagnostic_command
 *
 * @brief requests the device to perform self test
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_send_diagnostic_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                          PTR_CBW cbw_ptr, 
                                          uint_32* csw_residue_ptr, 
                                          uint_8* csw_status_ptr);     
                                                                                  
/**************************************************************************//*!
 *
 * @name  msc_unsupported_command
 *
 * @brief Responds appropriately to unsupported commands
 *
 * @param msc_obj_ptr 
 * @param cbw_ptr        : pointer to Command Block Wrapper sent by host
 * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper
 * @param csw_status_ptr : pointer to bCSWStatus  of Command Status Wrapper
 *
 * @return error
 *
 *****************************************************************************/
extern uint_8 msc_unsupported_command(MSC_DEVICE_STRUCT_PTR msc_obj_ptr,
                                      PTR_CBW cbw_ptr, 
                                      uint_32* csw_residue_ptr, 
                                      uint_8* csw_status_ptr);

/* EOF */
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/sdcard/sdcard_spi/sdcard_spi.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sdcard_spi.c$
* $Version : 3.8.16.0$
* $Date    : Sep-25-2012$
*
* Comments:
*
*   This file contains the SD card driver functions.
*
*END************************************************************************/


#include <string.h>
#include <mqx.h>
#include <bsp.h>
#include <io_prv.h>
#include <sdcard.h>
#include <sdcard_prv.h>
#include <sdcard_spi.h>
#include <spi.h>


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_crc7
* Returned Value   : CRC value
* Comments         :
*    Optimized CRC7 code calculation.
*
*END*----------------------------------------------------------------------*/
static uint_32 _io_sdcard_crc7
(
    /* [IN] Initial value, maybe previous partial result */
    uint_32 crc,

    /* [IN] Input bit stream (big endian) for CRC calculation */
    uint_8 input[],

    /* [IN] Length of the bit stream in bytes */
    uint_32 len
)
{
    /* pre-calculated table for CRC7 polynomial 0x89 */
    static const uint_8 crc_table[] = {
        0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F,
        0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77
    };

    int index;

    while (len) {
        index = ((crc>>3) & 0x0f) ^ ((*input)>>4);
        crc = (crc<<4) ^ crc_table[index];

        index = ((crc>>3) & 0x0f) ^ ((*input)&0x0f);
        crc = (crc<<4) ^ crc_table[index];

        input++;
        len--;
    }

    return (crc & 0x7f);
}



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_crc16
* Returned Value   : CRC value
* Comments         :
*    Optimized CRC16 code calculation.
*
*END*----------------------------------------------------------------------*/

/* Optional faster CRC16 caclulation may be used - larger table footprint */
#ifndef SDCARD_SPI_FAST_CRC
#define SDCARD_SPI_FAST_CRC 0
#endif

#if SDCARD_SPI_FAST_CRC
static uint_32 _io_sdcard_crc16
(
    /* [IN] Initial value, maybe previous partial result */
    uint_32 crc,

    /* [IN] Input bit stream (big endian) for CRC calculation */
    uint_8 input[],

    /* [IN] Length of the bit stream in bytes */
    uint_32 len
)
{
    /* pre-calculated table for CRC16 polynomial 0x11021 */
    static const uint_16 crc_table[] = {
        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
    };

    int index;

    while (len > 0) {
        index = ((crc>>8) & 0xff) ^ (*input);
        crc = (crc<<8) ^ crc_table[index];

        input++;
        len--;
    }

    return (crc & 0xffff);
}

#else /* !SDCARD_SPI_FAST_CRC */

static uint_32 _io_sdcard_crc16
(
    /* [IN] Initial value, maybe previous partial result */
    uint_32 crc,

    /* [IN] Input bit stream (big endian) for CRC calculation */
    uint_8 input[],

    /* [IN] Length of the bit stream in bytes */
    uint_32 len
)
{
    /* pre-calculated table for CRC16 polynomial 0x11021 */
    static const uint_16 crc_table[] = {
        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
    };

    int index;

    while (len > 0) {
        index = ((crc>>12) & 0x0f) ^ ((*input)>>4);
        crc = (crc<<4) ^ crc_table[index];

        index = ((crc>>12) & 0x0f) ^ ((*input)&0x0f);
        crc = (crc<<4) ^ crc_table[index];

        input++;
        len--;
    }

    return (crc & 0xffff);
}
#endif


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_read
* Returned Value   : number of bytes read
* Comments         :
*    Read wrapper that works on top of both polled and interrupt SPI drivers.
*
*END*----------------------------------------------------------------------*/
static uint_32 _io_sdcard_spi_read
(
    /* [OUT] Input buffer pointer */
    uchar_ptr    buffer,

    /* [IN] Size of buffer elements */
    uint_32      size,

    /* [IN] Number of elements to read */
    uint_32      number,

    /* [IN] Opened SPI driver handle */
    MQX_FILE_PTR spifd
)
{
    uint_32 count = 0;
    do
    {
        count += fread(buffer+count, size, number-count, spifd);
    } while (count < number);
    return count;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_write
* Returned Value   : number of bytes written
* Comments         :
*    Write wrapper that works on top of both polled and interrupt SPI drivers.
*
*END*----------------------------------------------------------------------*/
static uint_32 _io_sdcard_spi_write
(
    /* [IN] Output buffer pointer */
    uchar_ptr    buffer,

    /* [IN] Size of buffer elements */
    uint_32      size,

    /* [IN] Number of elements to write */
    uint_32      number,

    /* [IN] Opened SPI driver handle */
    MQX_FILE_PTR spifd
)
{
    uint_32 count = 0;
    do
    {
        count += fwrite (buffer + count, size, number - count, spifd);
    } while (count < number);
    return count;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_wait
* Returned Value   : success or failure
* Comments         :
*    Reads bytes until receiving a one not matching the given pattern.
*    Writes first non-matching byte to response buffer.
*
*END*----------------------------------------------------------------------*/
static boolean _io_sdcard_spi_wait
(
    /* [IN] SD card info */
    SDCARD_STRUCT_PTR sdcard_ptr,

    /* [IN] Pattern to skip, typically SDCARD_SPI_IDLE or SDCARD_SPI_BUSY */
    uint_8 skip,

    /* [OUT] First non-idle byte received */
    uint_8 *response
)
{
    uint_8  sdi;
    uint_32 timeout;

    /* wait for a non-matching byte */
    for (timeout = sdcard_ptr->TIMEOUT; timeout; timeout--)
    {
        sdi = SDCARD_SPI_IDLE;

        if (1 != _io_sdcard_spi_read(&sdi, 1, 1, sdcard_ptr->COM_DEVICE))
            return FALSE;

        if (sdi != skip)
            break;
    }

    /* check for timeout */
    if (0 == timeout)
        return FALSE;

    if (response)
        *response=sdi;

    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_command
* Returned Value   : Success or failure
* Comments         :
*    Sends command, reads R1 response and optional extended response
*
*END*----------------------------------------------------------------------*/
static boolean _io_sdcard_spi_command
(
    /* [IN] SD card info */
    SDCARD_STRUCT_PTR sdcard_ptr,

    /* [OUT] command to send */
    uint_8 command,

    /* [OUT] parameter to the command */
    uint_32 param,

    /* [OUT] common response to all commands (R1) */
    uint_8  *r1,

    /* [OUT] extended response pointer, may be NULL */
    uint_32 *response,

    /* [IN] length of extended response in bytes (up to 4) */
    uint_32 resplen
)
{
    int i;
    uint_8  buffer[7];

    if (!_io_sdcard_spi_wait(sdcard_ptr, SDCARD_SPI_BUSY , NULL))
        return FALSE;

    buffer[0] = command;
    buffer[1] = (param >> 24) & 0xFF;
    buffer[2] = (param >> 16) & 0xFF;
    buffer[3] = (param >>  8) & 0xFF;
    buffer[4] =  param        & 0xFF;
    buffer[5] = (_io_sdcard_crc7(0, buffer, 5) << 1) | SDCARD_SPI_END_BIT;

    /* dummy byte, Ncr is min 1, speed up, also simplifies STOP command handling */
    buffer[6] = SDCARD_SPI_IDLE;

    if (sizeof(buffer) != _io_sdcard_spi_write(buffer, 1, sizeof(buffer), sdcard_ptr->COM_DEVICE))
        return FALSE;

    /* wait for first byte of the response (R1) */
    if (!_io_sdcard_spi_wait(sdcard_ptr, SDCARD_SPI_IDLE, r1))
        return FALSE;

    /* is the response valid? */
    if (*r1 & SDCARD_SPI_R1_START_MASK)
        return FALSE;

    /* is extended response is expected at all?*/
    if (0 == resplen)
        return TRUE;

    /* read the extended response to buffer */
    buffer[0] = SDCARD_SPI_IDLE;
    buffer[1] = SDCARD_SPI_IDLE;
    buffer[2] = SDCARD_SPI_IDLE;
    buffer[3] = SDCARD_SPI_IDLE;

    if (resplen != _io_sdcard_spi_read(buffer, 1, resplen, sdcard_ptr->COM_DEVICE))
        return FALSE;

    /* is extended response data required by the caller? */
    if (response == NULL)
        return TRUE;

    /* return the extended response as a single 32-bit value */
    *response = 0;
    for (i=0; i<resplen; i++)
    {
        *response <<= 8;
        *response |= buffer[i];
    }

    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_read_data
* Returned Value   : success or failure
* Comments         :
*    Waits for data token and reads it into given buffer.
*
*END*----------------------------------------------------------------------*/
static boolean _io_sdcard_spi_read_data
(
    /* [IN] SD card info */
    SDCARD_STRUCT_PTR sdcard_ptr,

    /* [IN] Data to read*/
    uint_8 data[],

    /* [IN] Length of data */
    uint_32 data_len
)
{
    uint_8  tmp[2];
    uint_16 crc;

    if (!_io_sdcard_spi_wait(sdcard_ptr, SDCARD_SPI_IDLE, data))
        return FALSE;

    if (SDCARD_SPI_START != data[0])
        return FALSE;

    memset(data, SDCARD_SPI_IDLE, data_len);
    if (data_len != _io_sdcard_spi_read(data, 1, data_len, sdcard_ptr->COM_DEVICE))
        return FALSE;

    tmp[0] = tmp[1] = SDCARD_SPI_IDLE;
    if (2 != _io_sdcard_spi_read(tmp, 1, 2, sdcard_ptr->COM_DEVICE))
        return FALSE;

    crc = (tmp[0]<<8) | tmp[1];
    if (crc != _io_sdcard_crc16(0, data, data_len))
        return FALSE;

    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_write_data
* Returned Value   : success or failure
* Comments         :
*    Sends data token, reads response and  and waits while the card is busy.
*
*END*----------------------------------------------------------------------*/
static boolean _io_sdcard_spi_write_data
(
    /* [IN] SD card info */
    SDCARD_STRUCT_PTR sdcard_ptr,

    /* [IN] Data to write*/
    uint_8 data[],

    /* [IN] Length of data */
    uint_32 data_len,

    /* [IN] Token header to be sent before the data  */
    uint_8  token,

    /* [OUT] Response to data token sent by the card */
    uint_8  *response
)
{
    uint_8  tmp[2];
    uint_16 crc;

    /* Calculate CRC */
    crc = _io_sdcard_crc16 (0, data, data_len);
    tmp[0] = crc>>8;
    tmp[1] = crc&0xff;

    /* Send token header */
    if (1 != _io_sdcard_spi_write(&token, 1, 1, sdcard_ptr->COM_DEVICE))
        return FALSE;

    /* Send the data */
    if (data_len != _io_sdcard_spi_write(data, 1, data_len, sdcard_ptr->COM_DEVICE))
        return FALSE;

    /* Send CRC */
    if (2 != _io_sdcard_spi_write(tmp, 1, 2, sdcard_ptr->COM_DEVICE))
        return FALSE;

    /* Wait for response and read it */
    if (!_io_sdcard_spi_wait(sdcard_ptr, SDCARD_SPI_IDLE, response))
        return FALSE;

    /* Wait while the card busy writing the data */
    if (!_io_sdcard_spi_wait(sdcard_ptr, SDCARD_SPI_BUSY, NULL))
        return FALSE;

    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_write_stop
* Returned Value   : success or failure
* Comments         :
*    Sends data stop token and waits while the card is busy.
*
*END*----------------------------------------------------------------------*/
static boolean _io_sdcard_spi_write_stop
(
    /* [IN] SD card info */
    SDCARD_STRUCT_PTR sdcard_ptr
)
{
    uint_8  tmp[2];

    tmp[0] = SDCARD_SPI_MULTI_STOP;
    tmp[1] = SDCARD_SPI_IDLE; /* 8 dummy clocks */

    /* Send stop token and 8 dummy clocks */
    if (2 != _io_sdcard_spi_write(tmp, 1, 2, sdcard_ptr->COM_DEVICE))
        return FALSE;

    /* Wait while the card busy writing the data */
    if (!_io_sdcard_spi_wait(sdcard_ptr, SDCARD_SPI_BUSY, NULL))
        return FALSE;

    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_init
* Returned Value   : TRUE if successful, FALSE otherwise
* Comments         :
*    Initializes SPI communication, SD card itself and reads its parameters.
*
*END*----------------------------------------------------------------------*/
boolean _io_sdcard_spi_init
(
    /* [IN/OUT] SD card info */
    MQX_FILE_PTR fd_ptr
)
{
    uint_8               r1;
    uint_32              ifc;
    uint_32              ocr;
    uint_8               csd[16];

    uint_32              param;
    uint_32              baudrate;

    int                  i;

    IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
    SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

    if ((NULL == sdcard_ptr) || (NULL == sdcard_ptr->COM_DEVICE) || (NULL == sdcard_ptr->INIT))
        return FALSE;

    sdcard_ptr->TIMEOUT = 0;
    sdcard_ptr->NUM_BLOCKS = 0;
    sdcard_ptr->ADDRESS = 0;
    sdcard_ptr->SDHC = FALSE;
    sdcard_ptr->VERSION2 = FALSE;

    /* communication setup */
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_CS, &sdcard_ptr->INIT->SIGNALS))
        return FALSE;

    /* Revert to default baudrate of the com device */
    ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_BAUD, NULL);

    /* Get the baudrate */
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_GET_BAUD, &baudrate))
        return FALSE;

    param = 8;
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_FRAMESIZE, &param))
        return FALSE;

    param = SPI_DEVICE_BIG_ENDIAN;
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_ENDIAN, &param))
        return FALSE;

    param = SPI_CLK_POL_PHA_MODE0;
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_MODE, &param))
        return FALSE;

    param = SPI_DEVICE_MASTER_MODE;
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_TRANSFER_MODE, &param))
        return FALSE;

    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_DEVICE_ENABLE, NULL))
        return FALSE;


    /* set 400 kbps for max compatibility */
    param = 400000;
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_BAUD, &param))
        return FALSE;

    /* max timeout = 250 ms = 1 sec / (4 * 10 bits in transfer at baudrate) */
    sdcard_ptr->TIMEOUT = param / 40;


    /* disable CS for a while */
    param = 0;
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_CS, &param))
        return FALSE;

    /* send 80 dummy clocks without CS, CSD buffer used as temp */
    memset(csd, SDCARD_SPI_IDLE, 10);
    if (10 != _io_sdcard_spi_write(csd, 1, 10, sdcard_ptr->COM_DEVICE))
    {
        fflush (sdcard_ptr->COM_DEVICE);
        return FALSE;
    }

    /* return original CS signal */
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_CS, &sdcard_ptr->INIT->SIGNALS))
        return FALSE;


    /* send CMD0 = go idle */
    for (i = 0; i < SDCARD_SPI_RETRIES; i++)
    {
        if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD0_GO_IDLE_STATE, 0, &r1, NULL, 0))
            return FALSE;

        if (r1 == SDCARD_SPI_R1_IDLE_STATE)
            break;
    }

    if (i >= SDCARD_SPI_RETRIES)
        return FALSE;


    /* send CMD8 = test version */
    if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD8_SEND_IF_COND, SDCARD_SPI_IF_COND_VHS_27_36 | 0xAA, &r1, &ifc, 4))
        return FALSE;

    if (0 == (r1 & SDCARD_SPI_R1_ILLEGAL_CMD))
    {
        /* command supported, v2 card */
        sdcard_ptr->VERSION2 = TRUE;

        if (((ifc & 0xFF) != 0xAA) || ((ifc & SDCARD_SPI_IF_COND_VHS_MASK) != SDCARD_SPI_IF_COND_VHS_27_36))
            return FALSE;
    }


    /* send CMD58 = read OCR ... 3.3V */
    if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD58_READ_OCR, 0, &r1, &ocr, 4))
        return FALSE;

    if (0 == (r1 & SDCARD_SPI_R1_ILLEGAL_CMD))
    {
        if (r1 & SDCARD_SPI_R1_ERROR_MASK)
            return FALSE;

        if (SDCARD_SPI_OCR_VOLTAGE_3_3V != (ocr & SDCARD_SPI_OCR_VOLTAGE_3_3V))
            return FALSE;
    }


    /* send CMD55 + ACMD41 = initialize */
    for (i = 0; i < SDCARD_SPI_RETRIES; i++)
    {
        if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD55_APP_CMD, 0, &r1, NULL, 0))
            return FALSE;

        if (r1 & SDCARD_SPI_R1_ERROR_MASK)
            return FALSE;

        if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_ACMD41_SEND_OP_COND, sdcard_ptr->VERSION2 ? SDCARD_SPI_ACMD41_HCS : 0, &r1, NULL, 0))
            return FALSE;

        if (r1 & SDCARD_SPI_R1_ERROR_MASK)
            return FALSE;

        if (0 == (r1 & SDCARD_SPI_R1_IDLE_STATE))
            break;
    }

    if (i >= SDCARD_SPI_RETRIES)
        return FALSE;


    /* version 2 or later card */
    if (sdcard_ptr->VERSION2)
    {
        /* send CMD58 = read OCR to check CCS */
        if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD58_READ_OCR, 0, &r1, &ocr, 4))
            return FALSE;

        if (r1 & SDCARD_SPI_R1_ERROR_MASK)
            return FALSE;

        if (0 == (ocr & SDCARD_SPI_OCR_POWER_UP_STATUS))
            return FALSE;

        if (ocr & SDCARD_SPI_OCR_CCS)
            sdcard_ptr->SDHC = TRUE;
    }


    /* send CMD9 = get CSD */
    if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD9_SEND_CSD, 0, &r1, NULL, 0))
        return FALSE;

    if (r1 & SDCARD_SPI_R1_ERROR_MASK)
        return FALSE;

    if (!_io_sdcard_spi_read_data(sdcard_ptr, csd, 16))
        return FALSE;

    sdcard_ptr->NUM_BLOCKS = _io_sdcard_csd_capacity(csd);

    /* send CMD59 = CRC ON */
    if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD59_CRC_ON, 0x01, &r1, NULL, 0))
        return FALSE;

    if (r1 & SDCARD_SPI_R1_ERROR_MASK)
        return FALSE;


    /* send CMD16 = set block length to 512 */
    if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD16_SET_BLOCKLEN, 512, &r1, NULL, 0))
        return FALSE;

    if (r1 & SDCARD_SPI_R1_ERROR_MASK)
        return FALSE;


    param = _io_sdcard_csd_baudrate(csd);
    if (param > baudrate) param = baudrate;

    /* set baudrate */
    if (SPI_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_BAUD, &param))
        return FALSE;

    /* max timeout = 250 ms = 1 sec / (4 * 10 bits in transfer at baudrate) */
    sdcard_ptr->TIMEOUT = param / 40;


    return TRUE;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_read_block
* Returned Value   : Number of sectors successfully read or negative error code
* Comments         :
*    Reads sectors from SD card starting with given index into given buffer.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_spi_read_block
(
    /* [IN] SD card info */
    MQX_FILE_PTR fd_ptr,

    /* [OUT] Buffer to fill with read 512 bytes */
    uchar_ptr buffer,

    /* [IN] Index of sector to read */
    uint_32   index,

    /* [IN] Number of sectrors to read */
    uint_32   count
)
{
    IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
    SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

    uint_8               command;
    uint_8               r1;

    _mqx_int             result;

    /* Sanity checks */
    if ((NULL == sdcard_ptr) || (NULL == sdcard_ptr->COM_DEVICE) || (NULL == sdcard_ptr->INIT) || (NULL == buffer) || (0 == count))
        return IO_ERROR;

    /* Set proper SPI chip select */
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_CS, &sdcard_ptr->INIT->SIGNALS))
        return IO_ERROR;

    /* Non-SDHC cards are byte addressed */
    if (!sdcard_ptr->SDHC)
        index <<= IO_SDCARD_BLOCK_SIZE_POWER;

    /* Select command according to requested number of blocks */
    if (count>1)
    {
        command = SDCARD_SPI_CMD18_READ_MULTI_BLOCK;
    }
    else
    {
        command = SDCARD_SPI_CMD17_READ_BLOCK;
    }

    /* Send command and check the response */
    if (!_io_sdcard_spi_command(sdcard_ptr, command, index, &r1, NULL, 0) || (r1 & SDCARD_SPI_R1_ERROR_MASK))
    {
        fflush (sdcard_ptr->COM_DEVICE);
        return IO_ERROR;
    }

    result = 0;
    while (result < count)
    {
        /* Read data */
        if (!_io_sdcard_spi_read_data(sdcard_ptr, buffer, IO_SDCARD_BLOCK_SIZE))
            break;

        buffer+=IO_SDCARD_BLOCK_SIZE;
        result++;
    }

    /* Send stop command if reading multiple sectors */
    if (count>1)
    {
        _io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD12_STOP, 0, &r1, NULL, 0);
    }

    /* Deassert CS */
    fflush (sdcard_ptr->COM_DEVICE);
    return result;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_sdcard_spi_write_block
* Returned Value   : Number of sectors successfully written or negative error code
* Comments         :
*    Writes sectors starting with given index to SD card from given buffer.
*
*END*----------------------------------------------------------------------*/

_mqx_int _io_sdcard_spi_write_block
(
    /* [IN] SD card info */
    MQX_FILE_PTR fd_ptr,

    /* [IN] Buffer with 512 bytes to write */
    uchar_ptr buffer,

    /* [IN] Index of sector to write */
    uint_32   index,

    /* [IN] Number of sectrors to write */
    uint_32   count
)
{
    IO_DEVICE_STRUCT_PTR io_dev_ptr = fd_ptr->DEV_PTR;
    SDCARD_STRUCT_PTR    sdcard_ptr = (SDCARD_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR;

    uint_8               command;
    uint_8               token;
    uint_8               response;
    uint_8               r1;
    uint_32              r2;
    uint_8               tmp[4];

    _mqx_int             result;

    /* Sanity checks */
    if ((NULL == sdcard_ptr) || (NULL == sdcard_ptr->COM_DEVICE) || (NULL == sdcard_ptr->INIT) || (NULL == buffer) || (0 == count))
        return IO_ERROR;

    /* Set proper SPI chip select */
    if (SPI_OK != ioctl(sdcard_ptr->COM_DEVICE, IO_IOCTL_SPI_SET_CS, &sdcard_ptr->INIT->SIGNALS))
        return IO_ERROR;

    /* Non-SDHC cards are byte addressed */
    if (!sdcard_ptr->SDHC)
        index <<= IO_SDCARD_BLOCK_SIZE_POWER;

    if (count>1)
    {
        command = SDCARD_SPI_CMD25_WRITE_MULTI_BLOCK;
        token = SDCARD_SPI_MULTI_START;
    }
    else
    {
        command = SDCARD_SPI_CMD24_WRITE_BLOCK;
        token = SDCARD_SPI_START;
    }

    /* Send command and check the response. Second response byte is dummy, just to generate clocks. */
    if (!_io_sdcard_spi_command(sdcard_ptr, command, index, &r1, NULL, 1) || (r1 & SDCARD_SPI_R1_ERROR_MASK))
    {
        fflush(sdcard_ptr->COM_DEVICE);
        return IO_ERROR;
    }

    result = 0;
    while (result < count)
    {
        /* Write data */
        if (!_io_sdcard_spi_write_data(sdcard_ptr, buffer, IO_SDCARD_BLOCK_SIZE, token, &response))
        {
            fflush(sdcard_ptr->COM_DEVICE);
            return IO_ERROR;
        }

        /* Check the response */
        if ((response & SDCARD_SPI_DATA_RESPONSE_MASK) != SDCARD_SPI_DATA_RESPONSE_OK)
        {
            result = IO_ERROR;
            break;
        }

        buffer+=IO_SDCARD_BLOCK_SIZE;
        result++;
    }

    /* Send stop token if writing multiple sectors */
    if (count>1)
    {
        if (!_io_sdcard_spi_write_stop(sdcard_ptr))
        {
            fflush(sdcard_ptr->COM_DEVICE);
            return IO_ERROR;
        }
    }

    /* Fetch status from card */
    if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD13_SEND_STATUS, 0, &r1, &r2, 1))
    {
        fflush(sdcard_ptr->COM_DEVICE);
        return IO_ERROR;
    }

    /* Check whether the operation was successful */
    if ((r1 & SDCARD_SPI_R1_ERROR_MASK) || r2)
    {
        if (count>1)
        {
            /* Retrieve number of successfully written blocks */
            if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_CMD55_APP_CMD, 0, &r1, NULL, 0) || (r1 & SDCARD_SPI_R1_ERROR_MASK))
            {
                fflush(sdcard_ptr->COM_DEVICE);
                return IO_ERROR;
            }

            if (!_io_sdcard_spi_command(sdcard_ptr, SDCARD_SPI_ACMD22_SEND_NUM_WR_BLOCKS, 0, &r1, NULL, 0) || (r1 & SDCARD_SPI_R1_ERROR_MASK))
            {
                fflush(sdcard_ptr->COM_DEVICE);
                return IO_ERROR;
            }

            if (!_io_sdcard_spi_read_data(sdcard_ptr, tmp, 4))
            {
                fflush(sdcard_ptr->COM_DEVICE);
                return IO_ERROR;
            }

            result = (tmp[0]<<24) | (tmp[1]<<16) | (tmp[2]<<8) | (tmp[3]);
            if (result > count) result = IO_ERROR; /* Received invalid number */
        }
        else
        {
            result = 0;
        }
    }

    /* Deassert CS */
    fflush(sdcard_ptr->COM_DEVICE);
    return result;
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GMCLIB/GMCLIB_Clark.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file      GMCLIB_Clark.h
*
* @author    <NAME>
*
* @version   1.0.1.0
*
* @date      Dec-6-2012
*
* @brief     Header file for #GMCLIB_Clark transformation algorithm.
*
*******************************************************************************
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GMCLIB_CLARK_H_
#define _GMCLIB_CLARK_H_

#ifdef __cplusplus
extern "C" {
#endif

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Inlines.h"
#include "SWLIBS_Defines.h"
#endif

/******************************************************************************
| defines and macros (scope: module-local)
-----------------------------------------------------------------------------*/
/*! Function alias for the #GMCLIB_ClarkANSIC function.*/
#define GMCLIB_Clark(pOut,pIn) GMCLIB_ClarkANSIC(pOut,pIn)

/******************************************************************************
| typedefs and structures (scope: module-local)
-----------------------------------------------------------------------------*/

/******************************************************************************
| exported variables
-----------------------------------------------------------------------------*/

/******************************************************************************
| exported function prototypes
-----------------------------------------------------------------------------*/
/*!
* @ingroup GMCLIB_GROUP
*/
extern void GMCLIB_ClarkANSIC (MCLIB_2_COOR_SYST_ALPHA_BETA_T *pOut,
                               const MCLIB_3_COOR_SYST_T *const pIn);

#ifdef __cplusplus
}
#endif
#endif /* _GMCLIB_CLARK_H_ */

/* End of file */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/dhcp.h<|end_filename|>
#ifndef __dhcp_h__
#define __dhcp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: dhcp.h$
* $Version : 3.0.5.0$
* $Date    : Feb-26-2009$
*
* Comments:
*
*   Dynamic Host Configuration Protocol definitions.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

#define DHCPOP_BOOTREQUEST    1
#define DHCPOP_BOOTREPLY      2

#define DHCPTYPE_DHCPDISCOVER 1
#define DHCPTYPE_DHCPOFFER    2
#define DHCPTYPE_DHCPREQUEST  3
#define DHCPTYPE_DHCPDECLINE  4
#define DHCPTYPE_DHCPACK      5
#define DHCPTYPE_DHCPNAK      6
#define DHCPTYPE_DHCPRELEASE  7
#define DHCPTYPE_DHCPINFORM   8

#define DHCPTYPE_ISVALID(type)   ((type) >= 1 && (type) <= 8)

#define DHCPFLAG_BROADCAST                0x8000

#define DHCP_MAGIC            0x63825363L
#define DHCP_MIN_MESSAGE_SIZE 576
/*
** DHCP options
*/
#define DHCPOPT_PAD           0
#define DHCPOPT_END           255
#define DHCPOPT_MASK          1
/* Start CR 1152 */
#define DHCPOPT_TIMEOFFSET    2
#define DHCPOPT_ROUTER        3
#define DHCPOPT_TIMESERVER    4
#define DHCPOPT_NAMESERVER    5
#define DHCPOPT_DNSSERVER     6
#define DHCPOPT_HOSTNAME      12
#define DHCPOPT_BOOTFILESIZE  13
#define DHCPOPT_DOMAINNAME    15
#define DHCPOPT_ADDRESS       50
#define DHCPOPT_LEASE         51
#define DHCPOPT_OVERLOAD      52
#define DHCPOPT_MSGTYPE       53
#define DHCPOPT_SERVERID      54
#define DHCPOPT_PARAMLIST     55
#define DHCPOPT_MSGSIZE       57
#define DHCPOPT_RENEWALL      58
#define DHCPOPT_REBINDING     59
#define DHCPOPT_CLASSID       60
#define DHCPOPT_CLIENTID      61
#define DHCPOPT_SERVERNAME    66
#define DHCPOPT_TFTPSERVER    66
#define DHCPOPT_FILENAME      67
#define DHCPOPT_BOOTFILENAME  67
/* End CR 1152 */
#define DHCPOPT_WWW_SRV       72
#define DHCPOPT_FINGER_SRV    73

#define DHCPSIZE_MAGIC        4
#define DHCPSIZE_MASK         4
#define DHCPSIZE_ADDRESS      4
#define DHCPSIZE_LEASE        4
#define DHCPSIZE_MSGTYPE      1
#define DHCPSIZE_SERVERID     4
#define DHCPSIZE_MSGSIZE      2

#define DHCP_MSGSIZE_MIN      576

#define DHCP_LEASE_INFINITE   0xFFFFFFFF
/*
**  Flags
*/
#define DHCP_SEND_INFORM_MESSAGE              0x00000001
#define DHCP_MAINTAIN_STATE_ON_INFINITE_LEASE 0x00000002
/* Start CR 1547 */
#define DHCP_SEND_PROBE                       0x00000004
/* End CR 1547 */

/*
** Initialization Structure for DHCP Client
*/

typedef struct  dhcp_data_struct {
   int_32      (_CODE_PTR_ CHOICE_FUNC)(uchar _PTR_, uint_32);
   void        (_CODE_PTR_ BIND_FUNC)  (uchar _PTR_, uint_32, _rtcs_if_handle);
   void        (_CODE_PTR_ REBIND_FUNC)(uchar _PTR_, uint_32, _rtcs_if_handle);
   boolean     (_CODE_PTR_ UNBIND_FUNC)(_rtcs_if_handle);
   boolean     (_CODE_PTR_ FAILURE_FUNC)(_rtcs_if_handle);
   uint_32     FLAGS;
/* Start CR 2199 */   
   boolean     (_CODE_PTR_ NAK_FUNC)  (uchar _PTR_, uint_32, _rtcs_if_handle);
/* End CR 2199 */   
} DHCP_DATA_STRUCT, _PTR_ DHCP_DATA_STRUCT_PTR;

/***************************************
** Contents of a DHCP Packet Header
*/

typedef struct dhcp_header
{
   uchar    OP[1];
   uchar    HTYPE[1];
   uchar    HLEN[1];
   uchar    HOPS[1];
   uchar    XID[4];
   uchar    SECS[2];
   uchar    FLAGS[2];
   uchar    CIADDR[4];
   uchar    YIADDR[4];
   uchar    SIADDR[4];
   uchar    GIADDR[4];
   uchar    CHADDR[16];
   uchar    SNAME[64];
   uchar    FILE[128];
} DHCP_HEADER, _PTR_ DHCP_HEADER_PTR;

/***************************************
**
** Function definitions
**
*/
extern uint_32 RTCS_if_bind_DHCP_flagged(_rtcs_if_handle, DHCP_DATA_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 RTCS_if_bind_DHCP_timed(_rtcs_if_handle, DHCP_DATA_STRUCT_PTR, uchar_ptr, uint_32, uint_32);
extern uint_32 RTCS_if_bind_DHCP(_rtcs_if_handle, DHCP_DATA_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 RTCS_if_rebind_DHCP(_rtcs_if_handle, _ip_address, _ip_address, uint_32, _ip_address, DHCP_DATA_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 RTCS_request_DHCP_inform(_rtcs_if_handle, uchar_ptr, uint_32, _ip_address, _ip_address, void (_CODE_PTR_ inform_func)(uchar _PTR_, uint_32, _rtcs_if_handle));
extern void    DHCPCLNT_release     (_rtcs_if_handle);

extern uchar _PTR_ DHCPCLNT_find_option(uchar_ptr, uint_32, uchar);
extern uchar _PTR_ DHCP_find_option(uchar_ptr, uint_32, uchar);

extern boolean DHCP_option_int8     (uchar_ptr _PTR_, uint_32 _PTR_, uchar, uchar);
extern boolean DHCP_option_int16    (uchar_ptr _PTR_, uint_32 _PTR_, uchar, uint_16);
extern boolean DHCP_option_int32    (uchar_ptr _PTR_, uint_32 _PTR_, uchar, uint_32);
extern boolean DHCP_option_variable (uchar_ptr _PTR_, uint_32 _PTR_, uchar, uchar _PTR_, uint_32);
extern boolean DHCP_option_addr     (uchar_ptr _PTR_, uint_32 _PTR_, uchar, _ip_address);
extern boolean DHCP_option_addrlist (uchar_ptr _PTR_, uint_32 _PTR_, uchar, _ip_address _PTR_, uint_32);
extern boolean DHCP_option_string   (uchar_ptr _PTR_, uint_32 _PTR_, uchar, char_ptr);


#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2c/i2c_qi2c.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2c_qi2c.h$
* $Version : 3.8.3.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This file contains the definitions of constants and structures
*   required for the I2C drivers .
*
*END************************************************************************/

#ifndef _i2c_qi2c_h
#define _i2c_qi2c_h 1


/*--------------------------------------------------------------------------*/
/*
**                    DATATYPE DECLARATIONS
*/

/*
** QI2C_INIT_STRUCT
**
** This structure defines the initialization parameters to be used
** when a serial port is initialized.
*/
typedef struct qi2c_init_struct
{
    /* The I2C channel to initialize */
    uint_8                 CHANNEL;

    /* Default operating mode */
    uint_8                 MODE;

    /* The I2C station address for the channel */
    uint_8                 STATION_ADDRESS;

    /* Desired baud rate */
    uint_32                BAUD_RATE;

    /* Interrupt level to use if interrupt driven */
    uint_32                LEVEL;

    /* Tx buffer size (interrupt only) */
    uint_32                TX_BUFFER_SIZE;

    /* Rx buffer size (interrupt only) */
    uint_32                RX_BUFFER_SIZE;

} QI2C_INIT_STRUCT, _PTR_ QI2C_INIT_STRUCT_PTR;
typedef const QI2C_INIT_STRUCT _PTR_ QI2C_INIT_STRUCT_CPTR;

/*--------------------------------------------------------------------------*/
/*
**                        FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

uint_32 _qi2c_polled_install (char_ptr, QI2C_INIT_STRUCT_CPTR);
uint_32 _qi2c_int_install (char_ptr, QI2C_INIT_STRUCT_CPTR);
VQI2C_REG_STRUCT_PTR _bsp_get_i2c_base_address(uint_32 channel);
uint_32 _bsp_get_i2c_vector(uint_8 dev_num);
boolean _bsp_i2c_enable_access(uint_32 device);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/rtc/krtc_ext.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: krtc_ext.c$
* $Version : 3.8.2.0$
* $Date    : Oct-7-2011$
*
* Comments:
*   Kinetis RTC driver functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>


/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_inc_upcounter
* Returned Value   : none
* Comments         :
*    This function increments up-counter register by 1.
*
*END*********************************************************************/

void _rtc_inc_upcounter
(
    void
) 
{ 
    /* Increment monotinic counter register by 1*/
    RTC_MCLR = 1;
}


/*FUNCTION****************************************************************
* 
* Function Name    : _rtc_get_upcounter
* Returned Value   : value of up-counter register
* Comments         :
*    This function returns value of up-counter register.
*
*END*********************************************************************/

uint_32 _rtc_get_upcounter
(
    void
) 
{ 
    return RTC_MCLR;
}


/*FUNCTION**********************************************************************
* 
* Function Name    : _rtc_tamper_enable
* Returned Value   : _mqx_uint
* Comments         :
*
*END*********************************************************************/

_mqx_int _rtc_tamper_enable 
(
    RTC_TAMPER_TYPE enable_mask
) 
{ 
    RTC_MemMapPtr rtc = RTC_BASE_PTR;
    
    rtc->TER |= enable_mask;
    
    return MQX_OK;
}


/*FUNCTION**********************************************************************
* 
* Function Name    : _rtc_tamper_disable
* Returned Value   : _mqx_uint
* Comments         :
*
*END*********************************************************************/

_mqx_int _rtc_tamper_disable 
(
    RTC_TAMPER_TYPE disable_mask
) 
{ 
    RTC_MemMapPtr rtc = RTC_BASE_PTR;
    
    rtc->TER &= ~disable_mask; 

    return MQX_OK;
}

/*FUNCTION**********************************************************************
* 
* Function Name    : _rtc_get_tamper_timestamp
* Returned Value   : 
* Comments         :
*    
*
*END***************************************************************************/

void _rtc_get_tamper_timestamp
(
    /* [OUT] this parameter gets actual RTC time */
    RTC_TIME_STRUCT_PTR time
)
{
    RTC_MemMapPtr rtc = RTC_BASE_PTR;

    time->seconds = rtc->TSR;
}

/*FUNCTION**********************************************************************
* 
* Function Name    : _rtc_get_tamper_status
* Returned Value   : RTC_TAMPER_TYPE
* Comments         :
*
*END*********************************************************************/


RTC_TAMPER_TYPE _rtc_get_tamper_status 
(
    void
) 
{ 
    RTC_MemMapPtr rtc = RTC_BASE_PTR;
    
    return (RTC_TAMPER_TYPE)(rtc->TDR); 
}

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mcc/source/mcc_common.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2013 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************
* $FileName: mcc_common.c$
* $Version : 3.8.1.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This file contains MCC library common functions
*
*END************************************************************************/

#include "mcc_config.h"
#include "mcc_common.h"

#if (MCC_OS_USED == MCC_LINUX)
#include "linux/mcc_linux.h"
#include "linux/mcc_shm_linux.h"
#include <mach/hardware.h>
#include <linux/kernel.h>
#elif (MCC_OS_USED == MCC_MQX)
#include "mcc_mqx.h"
#endif


#if (MCC_OS_USED == MCC_MQX)
MCC_BOOKEEPING_STRUCT * bookeeping_data;
#endif

/*!
 * \brief This function registers an endpoint.
 *
 * Register an endpoint with specified structure / params (core, node and port).
 *
 * \param[in] endpoint Pointer to the endpoint structure.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_NOMEM (maximum number of endpoints exceeded)
 * \return MCC_ERR_ENDPOINT (invalid value for port or endpoint already registered)
 */
int mcc_register_endpoint(MCC_ENDPOINT endpoint)
{
    int i;

    /* must be valid */
    if(endpoint.port == MCC_RESERVED_PORT_NUMBER)
        return MCC_ERR_ENDPOINT;

    /* check not already registered */
    if(mcc_get_endpoint_list(endpoint))
        return MCC_ERR_ENDPOINT;

    MCC_DCACHE_INVALIDATE_MLINES(&bookeeping_data->endpoint_table[0], MCC_ATTR_MAX_RECEIVE_ENDPOINTS * sizeof(MCC_ENDPOINT_MAP_ITEM));
    for(i = 0; i < MCC_ATTR_MAX_RECEIVE_ENDPOINTS; i++) {
        if(bookeeping_data->endpoint_table[i].endpoint.port == MCC_RESERVED_PORT_NUMBER) {
            bookeeping_data->endpoint_table[i].endpoint.core = endpoint.core;
            bookeeping_data->endpoint_table[i].endpoint.node = endpoint.node;
            bookeeping_data->endpoint_table[i].endpoint.port = endpoint.port;
            MCC_DCACHE_FLUSH_MLINES(&bookeeping_data->endpoint_table[i], sizeof(MCC_ENDPOINT_MAP_ITEM));
            return MCC_SUCCESS;
        }
    }
    return MCC_ERR_NOMEM;
}

/*!
 * \brief This function removes an endpoint.
 *
 * Removes an endpoint with specified structure / params (core, node and port).
 *
 * \param[in] endpoint Pointer to the endpoint structure.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_ENDPOINT (invalid value for port or the endpoint doesn't exist)
 */
int mcc_remove_endpoint(MCC_ENDPOINT endpoint)
{
    int i=0;

    /* must be valid */
    if(endpoint.port == MCC_RESERVED_PORT_NUMBER)
        return MCC_ERR_ENDPOINT;

    MCC_DCACHE_INVALIDATE_MLINES(&bookeeping_data->endpoint_table[0], MCC_ATTR_MAX_RECEIVE_ENDPOINTS * sizeof(MCC_ENDPOINT_MAP_ITEM));
    for(i = 0; i < MCC_ATTR_MAX_RECEIVE_ENDPOINTS; i++) {

        if(MCC_ENDPOINTS_EQUAL(bookeeping_data->endpoint_table[i].endpoint, endpoint)) {
            /* clear the queue */
#if (MCC_OS_USED == MCC_LINUX)
            MCC_RECEIVE_BUFFER * buffer = mcc_dequeue_buffer((MCC_RECEIVE_LIST *)MQX_TO_VIRT(&bookeeping_data->endpoint_table[i].list));
            while(buffer) {
                mcc_queue_buffer((MCC_RECEIVE_LIST *)MQX_TO_VIRT(&bookeeping_data->free_list), buffer);
                buffer = mcc_dequeue_buffer((MCC_RECEIVE_LIST *)MQX_TO_VIRT(&bookeeping_data->endpoint_table[i].list));
            }
#elif (MCC_OS_USED == MCC_MQX)
            MCC_RECEIVE_BUFFER * buffer = mcc_dequeue_buffer((MCC_RECEIVE_LIST *)&bookeeping_data->endpoint_table[i].list);
            while(buffer) {
                mcc_queue_buffer(&bookeeping_data->free_list, buffer);
                buffer = mcc_dequeue_buffer((MCC_RECEIVE_LIST *)&bookeeping_data->endpoint_table[i].list);
            }
#endif
            /* indicate free */
            bookeeping_data->endpoint_table[i].endpoint.port = MCC_RESERVED_PORT_NUMBER;
            MCC_DCACHE_FLUSH_MLINES((void*)&bookeeping_data->endpoint_table[i].endpoint.port, sizeof(MCC_PORT));
            return MCC_SUCCESS;
        }
    }
    return MCC_ERR_ENDPOINT;
}

/*!
 * \brief This function dequeues the buffer.
 *
 * Dequeues the buffer from the list.
 *
 * \param[in] list Pointer to the MCC_RECEIVE_LIST structure.
 *  
 * \return Pointer to MCC_RECEIVE_BUFFER
 */
MCC_RECEIVE_BUFFER * mcc_dequeue_buffer(MCC_RECEIVE_LIST *list)
{
    MCC_DCACHE_INVALIDATE_MLINES((void*)list, sizeof(MCC_RECEIVE_LIST));
    MCC_RECEIVE_BUFFER * next_buf = list->head;

#if (MCC_OS_USED == MCC_LINUX)
    MCC_RECEIVE_BUFFER * next_buf_virt = (MCC_RECEIVE_BUFFER *)MQX_TO_VIRT(next_buf);
    if(next_buf) {
        MCC_DCACHE_INVALIDATE_MLINES((void*)&next_buf_virt->next, sizeof(MCC_RECEIVE_BUFFER*));
        list->head = next_buf_virt->next;
        if(list->tail == next_buf)
            list->tail = null;
    }
    MCC_DCACHE_FLUSH_MLINES(list, sizeof(MCC_RECEIVE_LIST));
    return next_buf_virt;
#elif (MCC_OS_USED == MCC_MQX)
    if(next_buf) {
        MCC_DCACHE_INVALIDATE_MLINES((void*)&next_buf->next, sizeof(MCC_RECEIVE_BUFFER*));
        list->head = next_buf->next;
        if(list->tail == next_buf)
            list->tail = null;
    }
    MCC_DCACHE_FLUSH_MLINES(list, sizeof(MCC_RECEIVE_LIST));
    return next_buf;
#endif
}

/*!
 * \brief This function queues the buffer.
 *
 * Queues the buffer in the list.
 *
 * \param[in] list Pointer to the MCC_RECEIVE_LIST structure.
 * \param[in] r_buffer Pointer to MCC_RECEIVE_BUFFER.
 *  
 * \return none
 */
void mcc_queue_buffer(MCC_RECEIVE_LIST *list, MCC_RECEIVE_BUFFER * r_buffer)
{
    MCC_DCACHE_INVALIDATE_MLINES((void*)list, sizeof(MCC_RECEIVE_LIST));

#if (MCC_OS_USED == MCC_LINUX)
    MCC_RECEIVE_BUFFER * last_buf = (MCC_RECEIVE_BUFFER *)MQX_TO_VIRT(list->tail);
    MCC_RECEIVE_BUFFER * r_buffer_mqx = (MCC_RECEIVE_BUFFER *)VIRT_TO_MQX(r_buffer);
    if(last_buf) {
        last_buf->next = r_buffer_mqx;
        MCC_DCACHE_FLUSH_MLINES((void*)&last_buf->next, sizeof(MCC_RECEIVE_BUFFER*));
    }
    else {
        list->head = r_buffer_mqx;
    }
    r_buffer->next = null;
    list->tail = r_buffer_mqx;
    MCC_DCACHE_FLUSH_MLINES(list, sizeof(MCC_RECEIVE_LIST));
    MCC_DCACHE_FLUSH_MLINES((void*)&r_buffer->next, sizeof(MCC_RECEIVE_BUFFER*));
#elif (MCC_OS_USED == MCC_MQX)
    MCC_RECEIVE_BUFFER * last_buf = list->tail;
    if(last_buf) {
        last_buf->next = r_buffer;
        MCC_DCACHE_FLUSH_MLINES((void*)&last_buf->next, sizeof(MCC_RECEIVE_BUFFER*));
    }
    else {
        list->head = r_buffer;
    }
    r_buffer->next = null;
    list->tail = r_buffer;
    MCC_DCACHE_FLUSH_MLINES(list, sizeof(MCC_RECEIVE_LIST));
    MCC_DCACHE_FLUSH_MLINES((void*)&r_buffer->next, sizeof(MCC_RECEIVE_BUFFER*));
#endif
}

/*!
 * \brief This function returns the endpoint list.
 *
 * Returns the MCC_RECEIVE_LIST respective to the endpoint structure provided.
 *
 * \param[in] endpoint Pointer to the MCC_ENDPOINT structure.
 *  
 * \return MCC_RECEIVE_LIST pointer 
 * \return null pointer
 */
MCC_RECEIVE_LIST * mcc_get_endpoint_list(MCC_ENDPOINT endpoint)
{
    int i=0;

    /* must be valid */
    if(endpoint.port == MCC_RESERVED_PORT_NUMBER)
        return null;

    MCC_DCACHE_INVALIDATE_MLINES(&bookeeping_data->endpoint_table[0], MCC_ATTR_MAX_RECEIVE_ENDPOINTS * sizeof(MCC_ENDPOINT_MAP_ITEM));
    for(i = 0; i<MCC_ATTR_MAX_RECEIVE_ENDPOINTS; i++) {

        if(MCC_ENDPOINTS_EQUAL(bookeeping_data->endpoint_table[i].endpoint, endpoint))
#if (MCC_OS_USED == MCC_LINUX)
            return (MCC_RECEIVE_LIST *)MQX_TO_VIRT(&bookeeping_data->endpoint_table[i].list);
#elif (MCC_OS_USED == MCC_MQX)
            return (MCC_RECEIVE_LIST *)&bookeeping_data->endpoint_table[i].list;
#endif
    }
    return null;
}

/*!
 * \brief This function queues a signal
 *  
 * Signal circular queue rules:
 * 	tail points to next free slot
 * 	head points to first occupied slot
 * 	head == tail indicates empty
 * 	(tail + 1) % len = fill
 * This method costs 1 slot since you need to differentiate
 * between full and empty (if you fill the last slot it looks
 * like empty since h == t)
 *
 * \param[in] core Core number.
 * \param[in] signal Signal to be queued.
 *  
 * \return MCC_SUCCESS
 * \return MCC_ERR_SQ_FULL (signal queue is full - no more that MCC_MAX_OUTSTANDING_SIGNALS items allowed)
 */
int mcc_queue_signal(MCC_CORE core, MCC_SIGNAL signal)
{
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signal_queue_head[core], sizeof(unsigned int));
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signal_queue_tail[core], sizeof(unsigned int));
    int tail = bookeeping_data->signal_queue_tail[core];
    int new_tail = tail == (MCC_MAX_OUTSTANDING_SIGNALS-1) ? 0 : tail+1;

    if(MCC_SIGNAL_QUEUE_FULL(core))
        return MCC_ERR_SQ_FULL;

    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signals_received[core][tail], sizeof(MCC_SIGNAL));
    bookeeping_data->signals_received[core][tail].type = signal.type;
    bookeeping_data->signals_received[core][tail].destination.core = signal.destination.core;
    bookeeping_data->signals_received[core][tail].destination.node = signal.destination.node;
    bookeeping_data->signals_received[core][tail].destination.port = signal.destination.port;

    bookeeping_data->signal_queue_tail[core] = new_tail;
    MCC_DCACHE_FLUSH_MLINES((void*)&bookeeping_data->signal_queue_tail[core], sizeof(unsigned int));
    MCC_DCACHE_FLUSH_MLINES((void*)&bookeeping_data->signals_received[core][tail], sizeof(MCC_SIGNAL));

    return MCC_SUCCESS;
}

/*!
 * \brief This function dequeues a signal
 * 
 * It dequeues a signal from the signal queue for the particular core.
 *    
 * \param[in] core Core number.
 * \param[in] signal Signal to be dequeued.
 *  
 * \return MCC_SUCCESS
 * \return MCC_ERR_SQ_EMPTY (signal queue is empty, nothing to dequeue)
 */
int mcc_dequeue_signal(MCC_CORE core, MCC_SIGNAL *signal)
{
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signal_queue_head[core], sizeof(unsigned int));
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signal_queue_tail[core], sizeof(unsigned int));
    int head = bookeeping_data->signal_queue_head[core];

    if(MCC_SIGNAL_QUEUE_EMPTY(core))
        return MCC_ERR_SQ_EMPTY;

    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signals_received[core][head], sizeof(MCC_SIGNAL));
    signal->type = bookeeping_data->signals_received[core][head].type;
    signal->destination.core = bookeeping_data->signals_received[core][head].destination.core;
    signal->destination.node = bookeeping_data->signals_received[core][head].destination.node;
    signal->destination.port = bookeeping_data->signals_received[core][head].destination.port;

    bookeeping_data->signal_queue_head[core] = head == (MCC_MAX_OUTSTANDING_SIGNALS-1) ? 0 : head+1;
    MCC_DCACHE_FLUSH_MLINES((void*)&bookeeping_data->signal_queue_head[core], sizeof(unsigned int));

    return MCC_SUCCESS;
}



<|start_filename|>Firmware/Inverter_bootloader/USB_DRIVER/usb_bdt_kinetis.h<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2009 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/ /*!
  *
  * @file usb_bdt_kinetis.h
  *
  * @author 
  *
  * @version 
  *
  * @date Jun-05-2009
  *
  * @brief The file contains definitions of Buffer Descriptor Table.
  *
  *****************************************************************************/

#ifndef _USBBDT_H
  #define _USBBDT_H

/* Buffer Descriptor Status Register Initialization Parameters */
  #define _BDTSTALL      (0x04)           /* Buffer Stall enable */
  #define _DATA0         (0x00)           /* DATA0 packet expected next */
  #define _DATA1         (0x40)           /* DATA1 packet expected next */
  #define _DTS           (0x08)           /* DTS Mask */
  #define _OWN           (0x80)           /* SIE owns buffer */
  #define _CPU           (0x00)           /* CPU owns buffer */
  #define _KEEP          (0x20)           /* keep bit */

  #define MAX_EP_CBL_INDEX  (64)             /* Maximum BDT Indexes */


/******************************************************************************
 * Types
 *****************************************************************************/
/* This structure is an exact replica of the BDT MAP in the USB RAM 
   The BDT_STAT defines the stat byte of the buffer descriptor vector.
   McuCtlBit structure defines the bits that have a meaning from CPU 
   point of view.SieCtlBit structure defines the bits that have a 
   meaning from USB controller point of view.      
*/

  #pragma pack(1)
typedef struct  
{
  INT8U :1;
  INT8U :1;
  INT8U bdtstall:1;            /* Buffer Stall Enable */
  INT8U dts:1;                 /* Data Toggle Synch Enable */
  INT8U ninc:1;                /* BD Keep Enable */
  INT8U keep:1;                /* Address Increment Disable */
  INT8U data:1;                /* Data Toggle Synch Value */
  INT8U own:1;                 /* USB Ownership */
}
T_EP_CBL_CBITS; 

typedef struct  
{
  INT8U    :2;
  INT8U pid:4;                 /* Packet Identifier */
  INT8U    :2;
}
T_EP_CBL_PID;

typedef union 
{
  INT8U             all;
  T_EP_CBL_CBITS    cbits;
  T_EP_CBL_PID      pack_pid;
} 
T_EP_CBL_BITS;                            /* Buffer Descriptor Status Register */

// Структура управляющего блока - элемента в таблице Buffer Descriptor Table  
typedef struct 
{
  T_EP_CBL_BITS  bits;
  INT8U          reserved1;
  INT16U         cnt;                  /* Count of bytes recieved or sent */
  INT32U         addr;                 /* Buffer Address */
} 
T_EP_CBL;              

// Структура таблицы Buffer Descriptor Table 
// В данной таблице находятся управляющие блоки конечных точек
// Для каждой конечной точки создается 4-е управляющих блока
// Назначается по два блока(четный и нечетный) для транзакций приема и транзакций передачи. 
typedef struct  
{
  T_EP_CBL ep_cbl[MAX_EP_CBL_INDEX];     /* Endpoint Descriptor */
}
T_USB_BDT;


  #pragma pack()

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ip6_if.h<|end_filename|>
#ifndef __ip6_if_h__
#define __ip6_if_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip6_if.h$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   Definitions for the Internet Protocol 6 Network Interfaces.
*
*END************************************************************************/

#include "rtcs.h"
#include "nd6.h"
#include "ipcfg.h"

/* Maxinmum number of IPv6 addresses per interface.*/ 
#define IP6_IF_ADDRESSES_MAX    (RTCSCFG_IP6_IF_ADDRESSES_MAX)

/* A lifetime value of all one bits (0xffffffff) represents infinity. */
#define IP6_IF_ADDRESS_LIFETIME_INFINITE    ND6_PREFIX_LIFETIME_INFINITE   

/*********************************************************************
 * Address information structure.
 *********************************************************************/
typedef struct ip6_if_addr_info
{
    in6_addr            ip_addr;                    /* IPv6 address.*/
    ip6_if_addr_state   ip_addr_state;              /* Address current state.*/
    ip6_if_addr_type    ip_addr_type;               /* How the address was acquired.*/
    in6_addr            solicited_multicast_addr;   /* Solicited-node multicast 
                                                     * group-address for assigned ip_addr.*/
    uint_32             creation_time;              /* Time of entry creation (in seconds).*/    
    uint_32             lifetime;                   /* Address lifetime (in seconds). 0xFFFFFFFF = Infinite Lifetime
                                                     * RFC4862. A link-local address has an infinite preferred and valid lifetime; it
                                                     * is never timed out.*/
    uint_32             prefix_length;              /* Prefix length (in bits). The number of leading bits
                                                     * in the Prefix that are valid. */                                        
    uint_32             dad_transmit_counter;       /* Counter used by DAD. Equals to the number 
                                                     * of NS transmits till DAD is finished.*/                                                    
    uint_32             state_time;                 /* Time of last state event.*/  
                                                    
} IP6_IF_ADDR_INFO, _PTR_ IP6_IF_ADDR_INFO_PTR;

struct ip_if; /* Just to avoid header conflicts.*/ //TBD 

/**********************************************************************
* Extension to the ip_if structure (in ip_prv.h).
***********************************************************************/
typedef struct ip6_if_struct
{
    struct ip_if            *next_if;                           /* Pointer to the next IF.*/
    struct ip_if            *prev_if;                           /* Pointer to the previous IF.*/
    uint_32                 scope_id;
    /* The IPv6 addressing architecture [1] allows multiple unicast
     * addresses to be assigned to interfaces. */
    IP6_IF_ADDR_INFO        address[IP6_IF_ADDRESSES_MAX];      /* RFC4862 5.2: A host maintains a list of addresses together with their
                                                                * corresponding lifetimes. The address list contains both
                                                                * autoconfigured addresses and those configured manually.
                                                                */
    ND6_CFG_PTR             ND6;                                /* Pointer to NDP control structure.*/ //TBD PFI=> NOT PRT
    void                    (*route)(RTCSPCB_PTR rtcs_pcb);     /* Routing ptotocol service function.*/
} IP6_IF_STRUCT, _PTR_ IP6_IF_STRUCT_PTR;

/************************************************************************
*     Function Prototypes
*************************************************************************/
extern boolean ip6_if_get_addr (_rtcs_if_handle ihandle, uint_32 n, IP6_IF_ADDR_INFO_PTR addr_info);
extern boolean ip6_if_is_my_addr(_rtcs_if_handle ihandle, in6_addr *ip_addr);
extern boolean ip6_if_is_my_solicited_multicast_addr(_rtcs_if_handle ihandle, in6_addr *ip_addr);

IP6_IF_ADDR_INFO_PTR ip6_if_get_addr_info(struct ip_if *if_ptr, in6_addr *ip_addr);
const in6_addr * ip6_if_select_src_addr(struct ip_if *if_ptr, in6_addr *dest_addr);
void ip6_if_unbind_addr ( struct ip_if *if_ptr, IP6_IF_ADDR_INFO_PTR if_addr );
uint_32 ip6_if_bind_addr (struct ip_if *if_ptr, in6_addr *addr, ip6_if_addr_type addr_type, uint_32 lifetime, uint_32 prefix_length);
uint_32 ip6_if_join (struct ip_if *if_ptr, const in6_addr *group_ip);
uint_32 ip6_if_leave(struct ip_if *if_ptr, const in6_addr *group_ip);
void ip6_if_add( struct ip_if *if_ptr );
void ip6_if_del( struct ip_if *if_ptr );
struct ip_if *ip6_if_get_by_n( uint_32 n );
struct ip_if *ip6_if_get_by_addr(in6_addr *addr);
struct ip_if *ip6_if_get_by_scope_id(uint_32 scope_id);
uint_32 ip6_if_get_scope_id(struct ip_if *if_ptr);
int ip6_if_addr_autoconf_set(struct ip_if *if_ptr, struct in6_addr *ipaddr);
void ip6_if_addr_timer(struct ip_if *if_ptr);
void ip6_if_route_instal(struct ip_if *if_ptr, void (*route)(RTCSPCB_PTR rtcs_pcb));  /* Instalation of Routing ptotocol service function.*/

/* For DEBUG needs only. */
void ip6_if_debug_print_addr_info( struct ip_if *if_ptr );

#endif /* __ip6_if_h__ */



<|start_filename|>Firmware/Inverter_bootloader/APP/CAN_task.c<|end_filename|>
#include "app_cfg.h"


static unsigned char tx_pack_id;
static T_can_msg rcv_msg;


unsigned char  rx_block[COMCH_BLOCK_MAX_SZ];
unsigned char  tx_block[COMCH_BLOCK_MAX_SZ];
unsigned int   rx_block_len;
static unsigned char *rx_block_ptr;
static unsigned int   rx_block_crc;
static unsigned int   rx_block_id;
static unsigned int   rx_block_cnt;
static unsigned int   rx_active;

extern volatile INT32U  g_1ms_cnt;
extern unsigned char    md5sum[16];
static md5_context      ctx;
static T_Boot_record    p_boot_rec;
volatile unsigned int   g_timeout_cnt;
unsigned int            g_run_app;
unsigned int            g_prolong_boot;


/*------------------------------------------------------------------------------
 Расчет контрольной суммы, согласно стандарту CRC-32
 ------------------------------------------------------------------------------*/
void Get_block_CRC32(INT8U *block, INT16U len, INT8U *dest)
{
  CRC_MemMapPtr  CRC  = CRC_BASE_PTR;

  int          i;

  //--------------------------------------------------------------------------------------------------------------------------------------
  // Инициализация модуля вычисления CRC
  CRC->CTRL = 0
              + LSHIFT(0x01, 30) // TOT  | Type of Transpose for Writes        | 00 No transposition.
              + LSHIFT(0x01, 28) // TOTR | Type of Transpose for Read          | 00 No transposition.
              + LSHIFT(0x01, 26) // FXOR | Complement Read of CRC data register| 0 No XOR on reading.
              + LSHIFT(0x01, 25) // WAS  | Write CRC data register as seed     | 1 Writes to the CRC data register are seed values.
              + LSHIFT(0x01, 24) // TCRC | Width of CRC protocol.              | 1 32-bit CRC protocol.
  ;
  CRC->CRC   = 0xFFFFFFFF;   // SEED = 0xFFFFFFFF
  CRC->CTRL &= ~BIT(25);
  CRC->GPOLY = 0x4C11DB7;
  for (i = 0; i < len; i++)
  {
      CRC->ACCESS8BIT.CRCHU = block[i];
  }

  *dest++ = CRC->ACCESS8BIT.CRCHU;
  *dest++ = CRC->ACCESS8BIT.CRCHL;
  *dest++ = CRC->ACCESS8BIT.CRCLU;
  *dest++ = CRC->ACCESS8BIT.CRCLL;
}


/*------------------------------------------------------------------------------
 Расчет контрольной суммы, так как он сделан на узлах сеты выполненных на STM32
 ------------------------------------------------------------------------------*/
void Get_block_CRC(INT8U *block, INT16U len, INT8U *dest)
{
  CRC_MemMapPtr  CRC  = CRC_BASE_PTR;

  int          i, k;
  INT32U       w;

  //--------------------------------------------------------------------------------------------------------------------------------------
  // Инициализация модуля вычисления CRC
  CRC->CTRL = 0
              + LSHIFT(0x00, 30) // TOT  | Type of Transpose for Writes        | 00 No transposition.
              + LSHIFT(0x00, 28) // TOTR | Type of Transpose for Read          | 00 No transposition.
              + LSHIFT(0x00, 26) // FXOR | Complement Read of CRC data register| 0 No XOR on reading.
              + LSHIFT(0x01, 25) // WAS  | Write CRC data register as seed     | 1 Writes to the CRC data register are seed values.
              + LSHIFT(0x01, 24) // TCRC | Width of CRC protocol.              | 1 32-bit CRC protocol.
  ;
  CRC->CRC = 0xFFFFFFFF;   // SEED = 0xFFFFFFFF
  CRC->CTRL &= ~BIT(25);
  CRC->GPOLY = 0x4C11DB7;
  w = 0;
  k = 0;
  for ( i=0;i<len;i++ )
  {
    w = block[i];
    w <<= 8;
    k++;
    if ( k==4 )
    {
      CRC->CRC = w;
      w = 0;
      k=0;
    }
  }

  if ( k!=0 )
  {
    CRC->CRC = w;
  }

  w = CRC->CRC;
  *dest++ = w & 0xFF;
  w >>= 8;
  *dest++ = w & 0xFF;
  w >>= 8;
  *dest++ = w & 0xFF;
  w >>= 8;
  *dest++ = w & 0xFF;
}

/*------------------------------------------------------------------------------

 ------------------------------------------------------------------------------*/
static int Send_data_chank(INT8U *data, INT8U len)
{
  T_can_msg can_msg;
  int       i;

  if ( (len > 0) && (len <= 8) )
  {
    can_msg.format  = EXTENDED_FORMAT;
    can_msg.type    = DATA_FRAME;
    can_msg.canid   = INVERT_UPGRADE_RX_ID;
    can_msg.len     = len;
    memset(can_msg.data, 0, 8);
    for (i = 0; i < len; i++)
    {
      can_msg.data[i] = data[i];
    }
    i = 0;
    do
    {
      if ( Send_can_msg(&can_msg) == SUCCESS ) break;
      DELAY_8us;
      i++;
      if ( i > 16000 ) return ERROR;
    }
    while (1);

    return SUCCESS;
  }
  return ERROR;
}

/*------------------------------------------------------------------------------

 ------------------------------------------------------------------------------*/
static int Send_ACK_msg(INT8U pack_id)
{
  int i;
  T_can_msg can_msg;

  can_msg.format  = EXTENDED_FORMAT;
  can_msg.type    = DATA_FRAME;
  can_msg.canid   = INVERT_UPGRADE_RX_ID;
  can_msg.len     = 1;
  memset(can_msg.data, 0, 8);
  can_msg.data[0] = pack_id;
  i = 0;
  do
  {
    if ( Send_can_msg(&can_msg) == SUCCESS ) break;
    DELAY_8us;
    i++;
    if ( i > 16000 ) return ERROR;
  }
  while (1);


  return SUCCESS;
}



/*------------------------------------------------------------------------------

 ------------------------------------------------------------------------------*/
int Init_CAN_manager(void)
{
  return SUCCESS;
}


/*------------------------------------------------------------------------------

 ------------------------------------------------------------------------------*/
int CAN_send_packet(unsigned int len, unsigned char *block)
{
  unsigned int n;
  INT8U buf[8];
  // Обрабатываем отправку очередного блока данных


  // Начинаем с отправки длины блока и контрольной суммы
  buf[0] = len & 0xFF;
  buf[1] = (len >> 8) & 0xFF;
  Get_block_CRC(block, len, &buf[2]);

  tx_pack_id++;
  buf[6] = tx_pack_id;

  if ( Send_data_chank(buf, 7) == SUCCESS )
  {
    while (len >= 8)
    {
      if ( Send_data_chank(block, 8) != SUCCESS )
      {
        return ERROR;
      }
      block += 8;
      len   -= 8;
    }
    if ( len != 0 )
    {
      // Дополняем нулями до 8-и байт оставшиеся данные
      memset(buf, 0, 8);
      memcpy(buf, block, len);
      if ( Send_data_chank(buf, 8) != SUCCESS )
      {
        return ERROR;
      }
      else
      {
        // Передача выполнена, ждать ответа

        // Ждем ответа около 1 сек
        n = 0;
        do
        {
          if ( Read_can_msg(&rcv_msg) == SUCCESS )
          {
            if ( rcv_msg.len == 1 )
            {
              if ( rcv_msg.data[0] == tx_pack_id )
              {
                return SUCCESS;
              }
            }

          }
          DELAY_8us;
          n++;
          if ( n > 100000ul ) return ERROR;
        }
        while (1);
      }
    }
  }

  return ERROR;
}


/*------------------------------------------------------------------------------
  Неблокирующий прием
 ------------------------------------------------------------------------------*/
int CAN_receiving_packet(void)
{
  if ( Read_can_msg(&rcv_msg) == SUCCESS )
  {

    if ( rcv_msg.len == 7 )
    {
      rx_block_len = rcv_msg.data[0] | (rcv_msg.data[1] << 8);
      rx_block_cnt = rx_block_len;
      rx_block_crc = (rcv_msg.data[5] << 24) | (rcv_msg.data[4] << 16) | (rcv_msg.data[3] << 8) | rcv_msg.data[2];
      rx_block_id  = rcv_msg.data[6];
      rx_block_ptr = rx_block;
      // Принимаем пакеты только не больше заданной длины
      if ( rx_block_len <= COMCH_BLOCK_MAX_SZ )
      {
        rx_active = 1;
      }
      else
      {
        rx_active = 0;
      }
    }
    else if ( (rcv_msg.len == 8) && (rx_active == 1) )
    {
      // Получены данные пакета
      if ( rx_block_cnt != 0 )
      {
        memcpy(rx_block_ptr, rcv_msg.data, 8);
        rx_block_ptr += 8;
        if ( rx_block_cnt > 8 )
        {
          rx_block_cnt -= 8;
        }
        else
        {
          INT32U ccrc;
          rx_active = 0;

          Get_block_CRC(rx_block, rx_block_len, (INT8U *)&ccrc);
          if ( ccrc == rx_block_crc )
          {
            Send_ACK_msg(rx_block_id);
            return SUCCESS;
          }
        }
      }
    }
  }
  return ERROR;

}

//--------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------
void CAN_loader(void)
{
  INT32U  i;
  INT32U  n;
  INT32U  crc;

  static unsigned int data_cnt;
  static unsigned int addr;



  do
  {

    // Ждем появления запроса о программировании
    if ( CAN_receiving_packet() == SUCCESS )
    {
      g_timeout_cnt = 0;
      if ( rx_block[0] == BOOTL_GET_CRC )
      {

        // Послать загрузочную запись
        tx_block[0] = BOOTL_ACK_CRC;
        memcpy(&tx_block[1], (void *)(FLASH_AREA_ADDR + FLASH_AREA_SIZE - sizeof(T_Boot_record)),  sizeof(T_Boot_record));
        CAN_send_packet(sizeof(T_Boot_record) + 1, tx_block);
      }
      else if ( rx_block[0] == BOOTL_SET_BOOT_REC )
      {
        LCD_print_str("CAN",0,0);
        // Принимаем новую загрузочную запись
        memcpy(&p_boot_rec, (void *)&rx_block[1],  sizeof(p_boot_rec));
        // Инициализируем программирование
        addr     = PROGRAMM_AREA_BEG_ADDR;
        data_cnt = 0;

        tx_block[0] = BOOTL_ACK_PRG;
        CAN_send_packet(1, tx_block);
      }
      else if ( rx_block[0] == BOOTL_ERASE_FLASH )
      {
        __disable_interrupt();
        // Начинаем со стирания последнего сектора
        Flash_SectorErase(FLASH_AREA_ADDR + FLASH_AREA_SIZE - ERASE_SECTOR_SIZE);

        n = p_boot_rec.orig_img_size / ERASE_SECTOR_SIZE;
        if ( (p_boot_rec.orig_img_size % ERASE_SECTOR_SIZE) != 0 ) n++;
        if ( n >= MAX_SECTOR_NUM ) n  = MAX_SECTOR_NUM - 1; // Чтобы не повтороять повтороное стирание последнего сектора

        // Стираем все изменяемые сектора
        for (i = 0; i < n; i++)
        {
          Flash_SectorErase(FLASH_AREA_ADDR + BOOTL_IMG_SIZE + i * ERASE_SECTOR_SIZE);
        }
        __enable_interrupt();

        // Инициализируем программирование
        addr     = PROGRAMM_AREA_BEG_ADDR;
        data_cnt = 0;

        tx_block[0] = BOOTL_ACK_ERASE;
        CAN_send_packet(1, tx_block);

      }
      else if ( rx_block[0] == BOOTL_DO_PRG )
      {

        __disable_interrupt();
        Flash_ByteProgram(addr, (unsigned char *)&rx_block[1], rx_block_len - 1);    // Программирование
        __enable_interrupt();
        addr += rx_block_len - 1;
        data_cnt += rx_block_len - 1;

        LCD_show_programming_progress(addr, data_cnt );

        if ( data_cnt >= p_boot_rec.orig_img_size )
        {
          // Здесь количество записанных данных сравнялось с заданным количеством,
          //  запись firmware закончена, произвести заключительные действия

          // Проверяем хеш MD5
          md5_starts(&ctx);
          md5_update(&ctx, (uint8 *)PROGRAMM_AREA_BEG_ADDR, p_boot_rec.orig_img_size);
          md5_finish(&ctx, md5sum);


          if ( memcmp(p_boot_rec.md5_hash, md5sum, 16) == 0 )
          {
            // Записываем запись boot
            addr = FLASH_AREA_ADDR + FLASH_AREA_SIZE - sizeof(p_boot_rec);
            __disable_interrupt();
            Flash_ByteProgram(addr, (unsigned char *)&p_boot_rec, sizeof(p_boot_rec));    // Программирование
            __enable_interrupt();
            LCD_show_programming_end(SUCCESS);
          }
          else
          {
            // MD5 хэш не совпадает
            LCD_show_programming_end(ERROR);
          }

        }

        tx_block[0] = BOOTL_ACK_PRG;
        CAN_send_packet(1, tx_block);
      }

    }

    if ( g_1ms_cnt > BOOTLODER_WAIT_TIME )
    {
      g_1ms_cnt = 0;
      Check_and_Jump_to_App();
    }
    if ( g_prolong_boot != 0 )
    {
      g_1ms_cnt = 0;
      g_prolong_boot = 0;
    }

  }
  while (1);


}


<|start_filename|>Firmware/Inverter_bootloader/USB_DRIVER/usb_dci_kinetis.c<|end_filename|>
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/ /*!
  *
  * @file usb_dci_kinetis.c
  *
  * @author
  *
  * @version
  *
  * @date
  *
  * @brief The file contains Kinetis USB stack controller layer implementation.
  *
  *****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include <string.h>
#include "app_cfg.h"
#include "usb_dciapi.h" /* USB DCI API Header File */
#include "usb_devapi.h" /* USB Device API Header File */
#include "usb_dci_kinetis.h"    /* USB DCI Header File */
#include "usb_bdt_kinetis.h"    /* USB BDT Structure Header File */
/*****************************************************************************
 * Constant and Macro's - None
 *****************************************************************************/
/****************************************************************************
 * Global Variables
 ****************************************************************************/
/* location for BDT Table and buff */
#pragma data_alignment = 512

static INT8U g_Mem[BYTES_1024];
/* Pointer to BDT Map Structure */
T_USB_BDT    *g_BDT = NULL;

static T_EP_STATE  g_ep_state_tbl[MAX_EP_CBL_INDEX >> 1]; // Таблица состояний конечных точек отдельно для принимающих и передающих

static INT8U  g_dci_controller_Id; /* stores Controller ID */

static INT32U g_bdt_address;     /* Start BDT buffer Address */

static INT8U  g_setup_direction = USB_TRF_UNKNOWN;  // Направление передачи задаваемое транзакцией SETUP 
/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/
static void USB_Bus_Reset_Handler(void);
static INT8U USB_DCI_Get_EP_CBL_Index(INT8U ep_num, INT8U direction, BOOLEAN odd);
static INT8U USB_DCI_Get_EP_CBL_Valid_Index(INT8U ep_num, INT8U direction, BOOLEAN odd);
#ifdef LONG_SEND_TRANSACTION
static void USB_DCI_Prepare_Send_Data(T_EP_CBL *p_ep_cbl, T_EP_STATE *p_ep_state);
#endif
static void USB_Packet_RXTX_Handler(INT8U stat, USB_DEV_EVENT_STRUCT *msg);
#ifdef USB_LOWPOWERMODE
static void Enter_StopMode(STOP_MODE stop_mode);
#endif
/*****************************************************************************
 * Local Variables - None
 *****************************************************************************/
extern void Watchdog_Reset(void);
/*****************************************************************************
 * Local Functions
 *****************************************************************************/

/**************************************************************************/ /*!
  *
  * @name  USB_Bus_Reset_Handler
  *
  * @brief The function handles Bus Reset Interrupt
  *
  * @param  None
  *
  * @return None
  *
  ******************************************************************************
  * This functions is called when USB Bus Reset event is received on USB Bus.
  * This function clears all the errors conditions and reinit Global data
  * structures. Also resets USB device controller.
  *****************************************************************************/
static void USB_Bus_Reset_Handler(void)
{
  USB0_ERRSTAT = ERR_STAT_CLEAR_ALL;  /* clear USB error flag */
  USB0_CTL |= USB_CTL_ODDRST_MASK;                /* Reset to Even buffer */
  USB0_ADDR = 0;                       /* reset to default address */
  /* Select System Clock and Disable Weak Pull Downs */
  USB0_USBCTRL = 0x00;

  /* Clear bdt elem structure */
  Clear_Mem((INT8U_ptr)(g_ep_state_tbl), (sizeof(T_EP_STATE) * (MAX_EP_CBL_INDEX >> 1)), (INT8U)UNINITIALISED_VAL);

  /* Clear Memory for BDT and buffer Data */
  Clear_Mem((INT8U_ptr)g_BDT, BYTES_1024, (INT8U)NULL);

  /* Initialize BDT buffer address */
  g_bdt_address = ((INT32U)g_BDT + BYTES_512);

  g_setup_direction = USB_TRF_UNKNOWN;

  USB0_CTL &= ~USB_CTL_ODDRST_MASK;
  USB0_USBTRC0 |= 0x40;             /* attach CFv1 core to USB bus */

  USB0_ERREN = ERR_ENB_ENABLE_ALL;   /* Enable All Error Interrupts */
  USB0_INTEN = INTENB_BUS_RESET_VAL; /* Enable All Interrupts except RESUME */
  USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;

  return;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Get_BDT_Index
  *
  * @brief The function maps endpoint number and direction to bdt index
  *
  * @param  ep_num   : Endpoint Number
  * @param  direction: Endpoint direction
  * @param  odd      : Odd or even buffer
  *
  * @return bdt index         : Mapped bdt index
  *         INVALID_BDT_INDEX : Incase of error
  *
  ******************************************************************************
  * This function returns BDT Index from Endpoint number, direction,
  * odd/even buffer
  *****************************************************************************/
static INT8U USB_DCI_Get_EP_CBL_Index(INT8U ep_num, INT8U direction,  BOOLEAN odd)
{
  INT8U ep_cbl_indx = INVALID_BDT_INDEX;

  if ( ep_num < MAX_SUPPORTED_ENDPOINTS )
  {
    /* per endpoint 4 ep_cbl_indx -- 2 for recv 2 for send */
    ep_cbl_indx = (INT8U)((ep_num * 4) + (INT8U)odd);

    if ( direction == USB_SEND )
    {
      ep_cbl_indx += 2;
    }
  }
  return ep_cbl_indx;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Validate_Param
  *
  * @brief The function validates endpoint number & direction parameters
  *        and returns bdt index.
  *
  * @param  ep_num   : Endpoint Number
  * @param  direction: Endpoint direction
  * @param  odd      : odd or even buffer
  *
  * @return bdt index         : mapped bdt index
  *         INVALID_BDT_INDEX : incase of error
  *
  ******************************************************************************
  * This function validates endpoint parameters and returns bdt index
  *****************************************************************************/
static INT8U USB_DCI_Get_EP_CBL_Valid_Index(INT8U ep_num,INT8U direction,BOOLEAN odd)
{
  /* Get bdt index mapped to endpoint number-direction and odd/even buffer */
  INT8U ep_cbl_indx = USB_DCI_Get_EP_CBL_Index(ep_num, direction, odd);

  if ( (ep_cbl_indx  != INVALID_BDT_INDEX) && (g_ep_state_tbl[TRANSFER_INDEX(ep_cbl_indx)].len == (INT16U)UNINITIALISED_VAL) )
  {
    /* Incase length in bdt_elem is uninitialised return invalid index */
    ep_cbl_indx = INVALID_BDT_INDEX;
  }
  return ep_cbl_indx;
}

#ifdef LONG_SEND_TRANSACTION
/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Prepare_Send_Data
  *
  * @brief The function sets up the BDT for Send
  *
  * @param  buffer_dsc   : Pointer to buffer descriptor element in USB_RAM
  * @param  bdt_elem     : Pointer to per endpoint/direction structure
  *
  * @return None
  *
  ******************************************************************************
  * This functions configures Buffer Descriptor (Address and Count)
  *****************************************************************************/
static void USB_DCI_Prepare_Send_Data(
                                      T_EP_CBL *p_ep_cbl,  /* [OUT] Pointer to buffer descriptor
                                                                  element in USB_RAM */
                                      T_EP_STATE *p_ep_state     /* [IN] Pointer to per endpoint/direction
                                                                  structure */
                                      )
{
  INT8U_ptr buff_ptr = p_ep_state->app_buffer + p_ep_state->curr_offset;
  INT16U current_count = 0;

  /* adjust size based on the input at the init endpoint */
  if ( (p_ep_state->app_len - p_ep_state->curr_offset) > p_ep_state->len )
  {
    /* If size of packet is greater than endpoint buffer size */
    current_count = p_ep_state->len;
  }
  else
  {
    /* If size of packet is smaller than endpoint buffer size */
    current_count = (INT16U)(p_ep_state->app_len - p_ep_state->curr_offset);
  }

  p_ep_cbl->cnt = current_count;

  p_ep_cbl->addr = (INT32U)buff_ptr;
}
#endif

/*****************************************************************************
 * Global Functions
 *****************************************************************************/

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Init
  *
  * @brief The function initializes the Controller layer
  *
  * @param controller_ID : Controller ID
  *
  * @return status
  *         USB_OK    : Always
  ******************************************************************************
  * Initializes the USB controller
  *****************************************************************************/
INT8U USB_DCI_Init(
                   INT8U    controller_ID   /* [IN] Controller ID */
                   )
{
  /* Select System Clock and Disable Weak Pull Downs */
  USB0_USBCTRL = 0x00;

  /* save the controller_ID for future use*/
  g_dci_controller_Id = controller_ID;

  /* Clear bdt elem structure */
  Clear_Mem((INT8U_ptr)(g_ep_state_tbl), (sizeof(T_EP_STATE) * (MAX_EP_CBL_INDEX >> 1)), (INT8U)UNINITIALISED_VAL);
  g_BDT = (T_USB_BDT *)((INT32U)g_Mem);

  /* Clear Memory for BDT and buffer Data */
  Clear_Mem((INT8U_ptr)g_BDT, BYTES_1024, (INT8U)NULL);

#ifndef OTG_BUILD
  /* Hard Reset to the USB Module */
  USB0_USBTRC0 |= USB_USBTRC0_USBRESET_MASK;

  /* loop till the Reset bit clears  */
  while ((USB0_USBTRC0 & USB_USBTRC0_USBRESET_MASK))
  {};

#endif

  g_setup_direction = USB_TRF_UNKNOWN;

  /* attach CFv1 core to USB bus*/
  //USB0_USBTRC0 |= 0x40;


  /* Set the BDT Table address, Need to be on 512 byte boundry */
  /* D8 Bit is masked in BDT_PAGE_01 */
  USB0_BDTPAGE1 = (INT8U)(((INT32U)g_BDT >> 8) & 0xFE);
  USB0_BDTPAGE2 = (INT8U)((INT32U)g_BDT >> 16);
  USB0_BDTPAGE3 = (INT8U)((INT32U)g_BDT >> 24);

  /* Initialized BDT buffer address */
  g_bdt_address = ((INT32U)g_BDT + BYTES_512);

#ifndef OTG_BUILD
  /* Pull Up configuration */
  USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK;
#endif


  USB0_CTL = USB_CTL_USBENSOFEN_MASK; /* Enable USB module */
  USB0_ISTAT = INT_STAT_CLEAR_ALL;      /* Clear USB interrupts*/

  /* Remove suspend state */
  USB0_USBCTRL &= ~USB_USBCTRL_SUSP_MASK;

  /* Enable USB RESET Interrupt */
  USB0_INTEN |= USB_INTEN_USBRSTEN_MASK;

  USB0_OTGCTL = USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK;

  Set_VIC_chanel(INT_USB0, 2, 0);

  return USB_OK;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_DeInit
  *
  * @brief The function de-initializes the Controller layer
  *
  * @param controller_ID : Controller ID
  *
  * @return status
  *         USB_OK    : Always
  ******************************************************************************
  * Initializes the USB controller
  *****************************************************************************/
INT8U USB_DCI_DeInit(void)
{
  /* Detach CFv1 core to USB bus*/
  USB0_USBTRC0 &= ~0x40;

  /* Clear USB interrupts*/
  USB0_ISTAT = INT_STAT_CLEAR_ALL;

  /* Disable USB RESET Interrupt */
  USB0_INTEN &= ~USB_INTEN_USBRSTEN_MASK;

  /* Disable USB module */
  USB0_CTL &= ~USB_CTL_USBENSOFEN_MASK;

  return USB_OK;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Init_EndPoint
  *
  * @brief The function initializes an endpoint
  *
  * @param controller_ID : Controller ID
  * @param ep_ptr        : Pointer to EndPoint Structures
  * @param flag          : Zero Termination
  *
  * @return status
  *         USB_OK                    : When Successfull
  *         USBERR_EP_INIT_FAILED     : When Error
  ******************************************************************************
  *
  * This function initializes an endpoint and the Bufffer Descriptor Table
  * entry associated with it. Incase the input parameters are invalid it will
  * return USBERR_EP_INIT_FAILED error.
  *
  *****************************************************************************/
INT8U USB_DCI_Init_EndPoint(
                            INT8U                controller_ID, /* [IN] Controller ID */
                            USB_EP_STRUCT_PTR    ep_ptr,       /* [IN] Pointer to Endpoint structure,
                                                                       (endpoint number,
                                                                        endpoint type,
                                                                        endpoint direction,
                                                                        max packet size) */
                            BOOLEAN              flag          /* [IN] Zero Termination */
                            )
{
  INT8U        bdtmap_index;
  INT8U        bdtelem_index;
  INT8U        ep_num     = ep_ptr->ep_num;
  INT8U        direction  = ep_ptr->direction;
  INT32U       ep_ctrl[2] = { EP_OUT, EP_IN };
  T_EP_CBL     *p_tmp_ep_cbl;
  T_EP_STATE   *p_ep_state;

  /* if the max packet size is greater than the max buffer size */
  if ( ep_ptr->size > MAX_EP_BUFFER_SIZE )
  {
    ep_ptr->size = MAX_EP_BUFFER_SIZE;
  }

  /* Get the bdt index correspoding to the endpoint */
  bdtmap_index = USB_DCI_Get_EP_CBL_Index(ep_num, direction, USB_RAM_EVEN_BUFFER);
  bdtelem_index = (INT8U)TRANSFER_INDEX(bdtmap_index);

  /*
     incase the bdtmap_index is invalid
     or already initialised return with an error
  */
  if ( (bdtmap_index  == INVALID_BDT_INDEX) ||
       (g_ep_state_tbl[bdtelem_index].len != (INT16U)UNINITIALISED_VAL) ||
       (g_bdt_address >= ((INT32U)g_Mem + BYTES_1024)) ||
       (ep_ptr->type > USB_INTERRUPT_PIPE) ||
       (ep_ptr->direction > USB_SEND) )
  {
    return USBERR_EP_INIT_FAILED;
  }

  p_ep_state = &g_ep_state_tbl[bdtelem_index];
  /* Reset Handler resets bdtmap_index to UNINITIALISED_VAL */
  if ( p_ep_state->ep_cbl_indx == (INT8U)UNINITIALISED_VAL )
  {
    p_ep_state->ep_cbl_indx = 0;
  }

  /* update bdt element structure */
  p_ep_state->len = (INT16U)ep_ptr->size;
  p_ep_state->flag = flag;
  /* preserving even/odd buffer bit */
  p_ep_state->ep_cbl_indx &= 0x01;
  p_ep_state->ep_cbl_indx |= ((direction << 1) | (ep_num << 2));
  p_ep_state->addr = g_bdt_address;
  p_ep_state->type = ep_ptr->type;
  p_ep_state->direction = direction;

  p_tmp_ep_cbl = &g_BDT->ep_cbl[p_ep_state->ep_cbl_indx];

  /* Update BDTMAP for endpoint's EVEN Buffer */
  p_tmp_ep_cbl->cnt = (INT16U)ep_ptr->size;
  p_tmp_ep_cbl->addr = g_bdt_address;
  p_tmp_ep_cbl->bits.all = (_CPU | _DATA0 | _DTS);

  /* Update BDTMAP for endpoint's ODD Buffer */
  p_tmp_ep_cbl = &g_BDT->ep_cbl[p_ep_state->ep_cbl_indx ^ 1];

  p_tmp_ep_cbl->cnt = (INT16U)ep_ptr->size;
  p_tmp_ep_cbl->addr = g_bdt_address;
  p_tmp_ep_cbl->bits.all = (_CPU | _DATA1 | _DTS);

  /* update the buffer address for the next endpoint */
  g_bdt_address += ep_ptr->size;

  if ( direction == USB_RECV )
  {
    /*
       For Recv Endpoints
       Give SIE Control to DATA0
    */
    p_tmp_ep_cbl = &g_BDT->ep_cbl[p_ep_state->ep_cbl_indx];
    p_tmp_ep_cbl->bits.all |= _OWN;
  }

  /* enable handshake for Non-Isochronous Endpoints */
  ep_ctrl[direction] |= ((ep_ptr->type != USB_ISOCHRONOUS_PIPE) ? HSHK_EN : 0x00);
  /* set the EndPoint Control MCU Register*/
  *((&USB0_ENDPT0) + (4 * ep_num)) |= ep_ctrl[direction];

  return USB_OK;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Cancel_Transfer
  *
  * @brief The function cancels any pending Transfers which ahve not been sent
  *
  * @param controller_ID : Controller ID
  * @param ep_num        : Endpoint number
  * @param direction     : Endpoint direction
  *
  * @return status
  *         USBERR_NOT_SUPPORTED : Always
  ******************************************************************************
  * This function just returns Error Code not supported
  *****************************************************************************/
INT8U USB_DCI_Cancel_Transfer(
                              INT8U    controller_ID,   /* [IN] Controller ID */
                              INT8U    ep_num,          /* [IN] Endpoint number */
                              INT8U    direction        /* [IN] Endpoint direction */
                              )
{
#ifdef LONG_TRANSACTION
  INT8U status = USBERR_UNKNOWN_ERROR;

  /* validate params and get the bdt index */
  INT8U ep_cbl_indx = USB_DCI_Get_EP_CBL_Valid_Index(ep_num, direction, USB_RAM_EVEN_BUFFER);
  INT8U bdtelem_index = (INT8U)TRANSFER_INDEX(ep_cbl_indx);

  /* Check for valid bdt index */
  if ( ep_cbl_indx != INVALID_BDT_INDEX )
  {
    T_EP_STATE *p_ep_state   = &g_ep_state_tbl[bdtelem_index];
    T_EP_CBL   *p_ep_cbl     = &g_BDT->ep_cbl[p_ep_state->ep_cbl_indx];
    T_EP_CBL   *p_ep_cbl_alt = &g_BDT->ep_cbl[p_ep_state->ep_cbl_indx ^ 1];


    /* Clear SIE Control Bit for both buffers*/
    p_ep_cbl->bits.all &= ~_OWN;
    p_ep_cbl_alt->bits.all &= ~_OWN;
    p_ep_state->app_len = (INT16U)UNINITIALISED_VAL;

    status = USB_OK;
  }
  return status;
#else
  return USBERR_NOT_SUPPORTED;
#endif
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Deinit_EndPoint
  *
  * @brief The function de initializes an endpoint
  *
  * @param controller_ID : Controller ID
  * @param ep_num        : Endpoint number
  * @param direction     : Endpoint direction
  *
  * @return status
  *         USB_OK                   : When successfull
  *         USBERR_EP_DEINIT_FAILED  : When unsuccessfull
  ******************************************************************************
  *
  * This function un-intializes the endpoint by clearing the corresponding
  * endpoint control register and then clearing the bdt elem.
  *
  *****************************************************************************/
INT8U USB_DCI_Deinit_EndPoint(
                              INT8U    controller_ID,   /* [IN] Controller ID */
                              INT8U    ep_num,          /* [IN] Endpoint number */
                              INT8U    direction        /* [IN] Endpoint direction */
                              )
{

  /* validate params and get the bdt index */
  INT8U ep_cbl_indx = USB_DCI_Get_EP_CBL_Valid_Index(ep_num, direction, USB_RAM_EVEN_BUFFER);
  INT8U bdtelem_index = (INT8U)TRANSFER_INDEX(ep_cbl_indx);

  /* incase the ep_cbl_indx is invalid*/
  if ( ep_cbl_indx  == INVALID_BDT_INDEX )
  {
    return USBERR_EP_DEINIT_FAILED;
  }
  USB_DCI_Cancel_Transfer(controller_ID, ep_num, direction);
  /* delete buffer space for both even and odd buffers */
  g_bdt_address -= (g_ep_state_tbl[bdtelem_index].len);

  /* Disable endpoint */
  *((&USB0_ENDPT0) + (4 * ep_num)) = EP_DISABLE;

  /* un-initialize the bdt_elem structure for this endpoint */
  g_ep_state_tbl[bdtelem_index].len = (INT16U)UNINITIALISED_VAL;
  g_ep_state_tbl[bdtelem_index].addr = (INT32U)UNINITIALISED_VAL;

  return USB_OK;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Stall_EndPoint
  *
  * @brief The function stalls an endpoint
  *
  * @param controller_ID : Controller ID
  * @param ep_num        : Endpoint number
  * @param direction     : Endpoint direction
  *
  * @return None
  *
  ******************************************************************************
  * This function stalls the endpoint by setting Endpoint BDT
  *****************************************************************************/
void USB_DCI_Stall_EndPoint(
                            INT8U    controller_ID,   /* [IN] Controller ID */
                            INT8U    ep_num,          /* [IN] Endpoint number */
                            INT8U    direction        /* [IN] Endpoint direction */
                            )
{

  /* validate params and get the bdt index */
  INT8U ep_cbl_indx = USB_DCI_Get_EP_CBL_Valid_Index(ep_num, direction, USB_RAM_EVEN_BUFFER);

  T_EP_STATE   *p_ep_state = &g_ep_state_tbl[TRANSFER_INDEX(ep_cbl_indx)];
  ep_cbl_indx = p_ep_state->ep_cbl_indx;

  /* Check for valid bdt index */
  if ( ep_cbl_indx != INVALID_BDT_INDEX )
  {
    (void)USB_DCI_Cancel_Transfer(controller_ID, ep_num, direction);

    /* Stall endpoint */
    g_BDT->ep_cbl[ep_cbl_indx].bits.all |= (_OWN | _BDTSTALL);
  }

  return;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Unstall_EndPoint
  *
  * @brief The function unstalls an endpoint
  *
  * @param controller_ID : Controller ID
  * @param ep_num        : Endpoint number
  * @param direction     : Endpoint direction
  *
  * @return None
  *
  ******************************************************************************
  * This function unstalls the endpoint by clearing Endpoint Control Register
  * and BDT
  *****************************************************************************/
void USB_DCI_Unstall_EndPoint(
                              INT8U    controller_ID,   /* [IN] Controller ID */
                              INT8U    ep_num,          /* [IN] Endpoint number */
                              INT8U    direction        /* [IN] Endpoint direction */
                              )
{

  /* validate params and get the bdt index */
  INT8U ep_cbl_indx = USB_DCI_Get_EP_CBL_Valid_Index(ep_num, direction, USB_RAM_EVEN_BUFFER);

  T_EP_STATE *p_ep_state = &g_ep_state_tbl[TRANSFER_INDEX(ep_cbl_indx)];

  ep_cbl_indx = p_ep_state->ep_cbl_indx;

  /* Check for valid bdt index */
  if ( ep_cbl_indx != INVALID_BDT_INDEX )
  {
    ENDPT0STR *endpoint = (ENDPT0STR *)(&USB0_ENDPT0 + (4 * ep_num));

    /* Enable ENDPTx for non control endpoints */
    /* For Control Endpoint the default Value 0x0D */
    if ( ep_num != CONTROL_ENDPOINT )
    {
      INT8U endpt;
      /* Enable handshaking for non isochronous endpoint */
      endpt = (INT8U)((p_ep_state->type != USB_ISOCHRONOUS_PIPE) ? HSHK_EN : 0);
      /*
         Enable the endpoint in the specified direction and disable
         control tranfers (valid only in case the endpoint is
         bidirectional)
      */
      endpt |= (INT8U)(EP_CTL_DIS | ((direction == USB_SEND) ? EP_IN : EP_OUT));
      endpoint->Byte |= endpt;
    }
    /* Clear Endpoint Stall bit is endpoint control register */
    endpoint->Bits.EP_STALL = 0;

    /* Unstall endpoint by clearing stall bit in BDT  */
    g_BDT->ep_cbl[ep_cbl_indx].bits.all &= ~(_OWN | _BDTSTALL);
    /* We Require DATA0 PID to be zero on unstall */
    g_BDT->ep_cbl[ep_cbl_indx].bits.all = _DATA0;
    if ( direction == USB_RECV )
    {
      /* Initiate Next receive Transfer */
      USB_DCI_Recv_Data(controller_ID, ep_num, NULL, 0);
    }
  }
  return;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Get_Setup_Data
  *
  * @brief The function copies Setup Packet from USB RAM to application buffer
  *
  * @param controller_ID : Controller ID
  * @param ep_num        : Endpoint number
  * @param buff_ptr      : Application buffer pointer
  *
  * @return None
  *
  ******************************************************************************
  * Copies setup packet from USB RAM to Application Buffer
  *****************************************************************************/
void USB_DCI_Get_Setup_Data(
                            INT8U      controller_ID,  /* [IN] Controller ID */
                            INT8U      ep_num,         /* [IN] Endpoint number */
                            INT8U_ptr  buff_ptr        /* [IN] Application buffer pointer */
                            )
{


  INT8U_ptr addr;
  /* validate params and get the bdt index */
  INT8U ep_cbl_indx = USB_DCI_Get_EP_CBL_Valid_Index(ep_num, USB_RECV, USB_RAM_EVEN_BUFFER);

  T_EP_STATE *p_ep_state = &g_ep_state_tbl[TRANSFER_INDEX(ep_cbl_indx)];
  ep_cbl_indx = p_ep_state->ep_cbl_indx;

  /* address correponding to the endpoint */
  addr = (INT8U_ptr)g_BDT->ep_cbl[ep_cbl_indx].addr;

  /* copy bdt buffer to application buffer */
  (void)memcpy(buff_ptr, addr, USB_SETUP_PKT_SIZE);
  return;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Get_Transfer_Status
  *
  * @brief The function retrieves the Transfer status of an endpoint
  *
  * @param controller_ID : Controller ID
  * @param ep_num        : Endpoint number
  * @param direction     : Endpoint direction
  *
  * @return status
  *         USBERR_TR_FAILED                : When unsuccessfull
  *         USB_STATUS_IDLE                 : No transfer on endpoint
  *         USB_STATUS_DISABLED             : endpoint is disabled
  *         USB_STATUS_STALLED              : endpoint is stalled
  *         USB_STATUS_TRANSFER_IN_PROGRESS : When SIE has control of BDT
  ******************************************************************************
  *
  * This function retrieves the transfer status of the endpoint by checking the
  * BDT as well as the endpoint control register
  *
  *****************************************************************************/
INT8U USB_DCI_Get_Transfer_Status(
                                  INT8U    controller_ID,   /* [IN] Controller ID */
                                  INT8U    ep_num,          /* [IN] Endpoint number */
                                  INT8U    direction        /* [IN] Endpoint direction */
                                  )
{

  INT8U status = USB_STATUS_DISABLED;

  /* validate params and get the bdt index */
  INT8U ep_cbl_indx = USB_DCI_Get_EP_CBL_Valid_Index(ep_num, direction, USB_RAM_EVEN_BUFFER);

  /* Check for valid bdt index */
  if ( ep_cbl_indx != INVALID_BDT_INDEX )
  {
    INT8U ep_control = (INT8U)(*((&USB0_ENDPT0) + 4 * ep_num));

    status = USB_STATUS_IDLE;

    /* Check for direction in endpoint control register */
    if ( (ep_control & (EP_IN | EP_OUT)) == EP_DISABLE )
    {
      status = USB_STATUS_DISABLED;
    }
    /* Check for stall bit in endpoint control register */
    else if ( (ep_control &  EPCTL_STALL) == EPCTL_STALL )
    {
      status = USB_STATUS_STALLED;
    }
    /* Check whether SIE has control of BDT */
    else if ( (g_BDT->ep_cbl[ep_cbl_indx].bits.cbits.own == 1) || (g_BDT->ep_cbl[ep_cbl_indx ^ 1].bits.cbits.own == 1) )
    {
      status = USB_STATUS_TRANSFER_IN_PROGRESS;
    }
  }
  return status;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Recv_Data
  *
  * @brief The function retrieves data recieved on an RECV endpoint
  *
  * @param controller_ID : Controller ID
  * @param ep_num        : Endpoint number
  * @param buff_ptr      : Application buffer pointer
  * @param size          : Size of the buffer
  *
  * @return status
  *         USB_OK                          : When successfull
  *         USBERR_RX_FAILED                : When unsuccessfull
  ******************************************************************************
  * This function retrieves data received data on a RECV endpoint by copying it
  * from USB RAM to application buffer
  *****************************************************************************/
INT8U USB_DCI_Recv_Data(INT8U controller_ID,INT8U ep_num,INT8U_ptr buff_ptr,INT16U size)
{

  INT8U status = USBERR_RX_FAILED;
  INT8U ep_cbl_indx;
  T_EP_STATE *p_ep_state;
  //uint_8_ptr addr = NULL;

  ep_cbl_indx = USB_DCI_Get_EP_CBL_Valid_Index(ep_num, USB_RECV, USB_RAM_EVEN_BUFFER);
  p_ep_state  = &g_ep_state_tbl[TRANSFER_INDEX(ep_cbl_indx)];
  ep_cbl_indx = p_ep_state->ep_cbl_indx;

  if ( ep_cbl_indx != INVALID_BDT_INDEX )
  {
    T_EP_CBL *p_ep_cbl     = &g_BDT->ep_cbl[ep_cbl_indx ^ 1];
    T_EP_CBL *p_ep_cbl_alt = NULL;


    if ( p_ep_state->len != (INT16U)UNINITIALISED_VAL )
    {
      // Обрабатываем пакет только если контрольный блок конечной точки разблокирован движком USB
      if ( p_ep_cbl->bits.cbits.own == 0 )
      {
        if ( size == 0 )
        {
          /* Give control to the other buffer to recv the next packet  */
          p_ep_cbl_alt = &g_BDT->ep_cbl[ep_cbl_indx];
          p_ep_cbl_alt->cnt = p_ep_state->len;
          p_ep_cbl_alt->addr = p_ep_state->addr;

          /* Give the ownership to SIE and TOGGLE DATA BIT */
          p_ep_cbl_alt->bits.all = (INT8U)((p_ep_cbl_alt->bits.cbits.data << 6) | _OWN | _DTS);
          return USB_OK;
        }

        /* adjust size based on the input at the init endpoint */
#ifdef LONG_RECIEVE_TRANSACTION
        /* Initialise transfer */
        p_ep_state->app_len = size;
        p_ep_state->app_buffer = buff_ptr;
#endif
        if ( size > p_ep_state->len )
        {
          size = p_ep_state->len;
        }

#ifdef LONG_RECIEVE_TRANSACTION
        p_ep_state->curr_offset = 0;
#endif
        p_ep_cbl_alt           = &g_BDT->ep_cbl[ep_cbl_indx];
        p_ep_cbl_alt->cnt      = size;
        p_ep_cbl_alt->addr     = (INT32U)buff_ptr;
        p_ep_cbl_alt->bits.all = (INT8U)((p_ep_cbl_alt->bits.cbits.data << 6) | _OWN | _DTS);
        status = USB_OK;
      }
    }
  }
  return status;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Send_Data
  *
  * @brief The function configures Controller to send data on an SEND endpoint
  *
  * @param controller_ID : Controller ID
  * @param ep_num        : Endpoint number
  * @param buff_ptr      : Application buffer pointer
  * @param size          : Size of the buffer
  *
  * @return status
  *         USB_OK           : When successfull
  *         USBERR_TX_FAILED : When unsuccessfull
  ******************************************************************************
  * This function configures Controller to send data on an SEND endpoint by
  * setting the BDT to send data.
  *****************************************************************************/
INT8U USB_DCI_Send_Data(
                        INT8U          controller_ID,  /* [IN] Controller ID */
                        INT8U          ep_num,         /* [IN] Endpoint number */
                        INT8U_ptr       buff_ptr,       /* [IN] Application buffer pointer */
                        INT16U size            /* [IN] Size of the buffer */
                        )
{

  INT8U       status = USBERR_TX_FAILED;
  T_EP_CBL   *p_ep_cbl;

  //Led_control(3, 1);

  /* validate params and get the bdt index */
  INT8U ep_cbl_indx = USB_DCI_Get_EP_CBL_Valid_Index(ep_num, USB_SEND, USB_RAM_EVEN_BUFFER);

  T_EP_STATE *p_ep_state = &g_ep_state_tbl[TRANSFER_INDEX(ep_cbl_indx)];

  if ( ep_cbl_indx == INVALID_BDT_INDEX ) return USBERR_TX_FAILED;

  /* Send Data After Toggling Buffer */
  ep_cbl_indx = (INT8U)p_ep_state->ep_cbl_indx;

  p_ep_cbl = &g_BDT->ep_cbl[ep_cbl_indx];
  /* Does MCU owns it and it is not stalled */
  if ( !((p_ep_cbl->bits.cbits.own) || (*(&USB0_ENDPT0 + (ep_num * 4)) & ENDPT_EP_STALL_MASK)) )
  {
    /* Now configure buffer_dsc->addr and buffer_dsc->cnt */
#ifdef LONG_SEND_TRANSACTION
    /* Initialise transfer */
    p_ep_state->app_len = size;
    p_ep_state->app_buffer = buff_ptr;
    p_ep_state->curr_offset = 0;

    /* prepare for send */
    USB_DCI_Prepare_Send_Data(p_ep_cbl, p_ep_state);
#else
    p_ep_cbl->addr = (INT32U)buff_ptr;

    /* adjust size based on the input at the init endpoint */
    if ( (INT16U)size > p_ep_state->len )
    {
      p_ep_cbl->cnt = p_ep_state->len;
    }
    else
    {
      p_ep_cbl->cnt = (INT16U)size;
    }
#endif
    if ( ep_num == CONTROL_ENDPOINT )
    {
      /* Set up the control endpoint bdt for next packet */
      p_ep_cbl->bits.all = (_OWN | _DATA1 | _DTS);
    }
    else
    {
      p_ep_cbl->bits.all = (INT8U)((p_ep_cbl->bits.cbits.data << 6) | _OWN | _DTS);
    }

    status = USB_OK;
  } /* Does MCU own IN BDT */

  //Led_control(3, 0);

  return status;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Set_Address
  *
  * @brief The function configures Controller to send data on an SEND endpoint
  *
  * @param controller_ID : Controller ID
  * @param address       : Controller Address
  *
  * @return None
  *
  ******************************************************************************
  * Assigns the Address to the Controller
  *****************************************************************************/
void  USB_DCI_Set_Address(
                          INT8U    controller_ID,    /* [IN] Controller ID */
                          INT8U    address           /* [IN] Controller Address */
                          )
{

  /* set the address */
  USB0_ADDR = address;

  USB_Device_Set_Status(g_dci_controller_Id, USB_STATUS_DEVICE_STATE, USB_STATE_ADDRESS);
  return;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Shutdown
  *
  * @brief The function shuts down the controller
  *
  * @param controller_ID : Controller ID
  *
  * @return None
  *
  ******************************************************************************
  * Resets USB Device Controller
  *****************************************************************************/
void USB_DCI_Shutdown(
                      INT8U    controller_ID     /* [IN] Controller ID */
                      )
{

  /* Reset the Control Register */
  USB0_CTL = 0;
  /* Initiate Reset in the USB Control0 Register */
#ifndef OTG_BUILD

  USB0_USBTRC0 = _USBRESET;
#endif

  USB_Device_Set_Status(g_dci_controller_Id, USB_STATUS_DEVICE_STATE, USB_STATE_UNKNOWN);
  return;
}

/**************************************************************************/ /*!
  *
  * @name  USB_DCI_Assert_Resume
  *
  * @brief The function makes the Controller start USB RESUME signaling
  *
  * @param controller_ID: Controller ID
  *
  * @return None
  *
  ******************************************************************************
  *
  * This function starts RESUME signalling and then stops it after some delay.
  * In this delay make sure that COP is reset.
  *
  *****************************************************************************/
void USB_DCI_Assert_Resume(
                           INT8U    controller_ID     /* [IN] Controller ID */
                           )
{

  INT16U delay_count;

#ifdef USB_LOWPOWERMODE
  /* Clear SUSP Bit from USB_CTRL */
  USB_CTRL_SUSP = 0;
#endif

  /* Reset Low Power RESUME enable */
  USB0_USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK;

  USB_DCI_WAKEUP

    USB0_CTL |= USB_CTL_RESUME_MASK;   /* Start RESUME signaling and make SUSPEND bit 0*/

  delay_count = ASSERT_RESUME_DELAY_COUNT; /* Set RESUME line for 1-15 ms*/

  do
  {
    delay_count--;
    Watchdog_refresh();    /* Reset the COP */
  }
  while (delay_count);

  USB0_CTL &= ~USB_CTL_RESUME_MASK;          /* Stop RESUME signalling */

  return;
}

//-------------------------------------------------------------------------------------------------------
//  Функция обрабатывающая из прерываний событие окончания приема или передачи пакета
//
//  usb_stat - содержимое регистра USB0_STAT
//  msg      - указатель на структуру с данными о полученном или тправленном пакете. Данная структура модифицируется в этой функции
//-------------------------------------------------------------------------------------------------------
void USB_Packet_RXTX_Handler(INT8U usb_stat,USB_DEV_EVENT_STRUCT *msg)
{
  INT8U          ep_cbl_indx   = 0;
  T_EP_CBL       *p_ep_cbl     = NULL;
  T_EP_CBL       *p_ep_cbl_alt = NULL;
  T_EP_STATE     *p_ep_state   = NULL;
  BOOLEAN        odd = (BOOLEAN)((usb_stat & 0x04) >> 2);


  odd = (usb_stat >> 2) & 1;                    // Определяем четный или не четный управляющий блок был использован. 1 означает нечетный
  msg->ep_num = (usb_stat >> 4) & 0x0F;         // Узнаем номер конечной точки
  msg->direction = (usb_stat >> 3) & 1;         // Читаем бит TX(3) в регистре USB->STAT. 1 - означает, что данные были переданы, 0 - приняты

  ep_cbl_indx = USB_DCI_Get_EP_CBL_Index(msg->ep_num, msg->direction, odd); // Вычисляем индекс управляющего блока конечной точки

  p_ep_cbl     = &g_BDT->ep_cbl[ep_cbl_indx];    // Получаем указатель на управляющий блок конечной точки
  p_ep_cbl_alt = &g_BDT->ep_cbl[ep_cbl_indx ^ 1];// Получаем указатель на следующий управляющий блок этой же конечной точки


  // Перехватываем транзакцию SETUP с командой DFU_DNLOAD
  //if ( p_ep_cbl->bits.pack_pid.pid == 0x0D )
  //{
  //  
  //  if (( ((INT8U*)(p_ep_cbl->addr))[0]==0x21 ) && ( ((INT8U*)(p_ep_cbl->addr))[1]==0x01 ))
  //  {
  //    __no_operation();
  //  }
  //}

  // Перехватываем транзакцию OUT с данными для программирования и первым байтом равным 0xFF
  //if ( p_ep_cbl->bits.pack_pid.pid == 0x01 )
  //{
  //  
  //  if ( ((INT8U*)(p_ep_cbl->addr))[0]==0xFF )
  //  {
  //    __no_operation();
  //  }
  //}



  p_ep_state = &g_ep_state_tbl[TRANSFER_INDEX(ep_cbl_indx)];// Получаем указатель на структуру параметров конечной точки

  msg->buffer_ptr = (INT8U_ptr)p_ep_cbl->addr;  // В сообщение записываем адрес и длину пакета
  msg->len = p_ep_cbl->cnt;

  p_ep_state->ep_cbl_indx = (INT8U)(p_ep_state->ep_cbl_indx ^ 1);// В структуре параметров конечной точки обновляем индекс на следующий управляющий блок 
                                                                 
  p_ep_cbl_alt->bits.all = (INT8U)((p_ep_cbl->bits.cbits.data ^ 1) << 6); // Переключаем бит data для следующей транзакции этой конечной точки

  if ( msg->direction == USB_SEND )
  {

    // Здесь если была завершена транзакция отправки данных хосту IN .................................................

    if ( msg->ep_num == CONTROL_ENDPOINT )
    {
      /* for Control Endpoint */
      /* For Transfer Direction Host to Device */
      if ( g_setup_direction == USB_RECV )
      {
        // Здесь оказываемся если последняя транзакция SETUP что-то записывала в устройство и устройство это подтвердило выдав транзакцию IN 
        // Это могут быть запросы SetAddress, SetConfiguration ...

        g_setup_direction = USB_TRF_UNKNOWN;
        USB_DCI_Cancel_Transfer(msg->controller_ID, CONTROL_ENDPOINT, USB_RECV); // Прекратить обработку транзакций конечной точкой  
        p_ep_cbl_alt->bits.all = _DATA0;                                         // Подготовить конечную точку к началу обработки новой передачи
        USB_DCI_Recv_Data(msg->controller_ID, CONTROL_ENDPOINT, NULL, 0);

      }
    } /* ep_num is CONTROL ENDPOINT */

#ifdef LONG_SEND_TRANSACTION
    if ( (g_setup_direction == USB_SEND) || (msg->ep_num != CONTROL_ENDPOINT) )
    {
      /* update the request */
      p_ep_state->curr_offset += msg->len;
      /*
         Initiate next USB SEND if:
         1. More Data is still pending OR
         2. Send Data == Endpoint Size AND
         3. Zero Termination Flag is TRUE
      */
      if ( (p_ep_state->app_len > p_ep_state->curr_offset) || ((INT8U)msg->len == p_ep_state->len) && (p_ep_state->flag == TRUE) )
      {
        /* send next Req */
        USB_DCI_Prepare_Send_Data(p_ep_cbl_alt, p_ep_state);

        /* give the ownership to SIE and TOGGLE DATA BIT */
        p_ep_cbl_alt->bits.all = (INT8U)(((p_ep_cbl_alt->bits.cbits.data) << 6) | _OWN | _DTS);
        ;
        return;
      }
      else
      {
        msg->buffer_ptr = p_ep_state->app_buffer;
        msg->len = p_ep_state->curr_offset;
      }
    }
#endif
  }
  else
  {
    // Здесь если была завершена транзакция приема данных OUT или SETUP .................................................

    if ( msg->ep_num == CONTROL_ENDPOINT )
    {
      /* for Control Endpoint */
      if ( p_ep_cbl->bits.pack_pid.pid == USB_SETUP_TOKEN )
      {
        // Обработана транзакция SETUP        
        msg->setup = TRUE;
        g_setup_direction = (INT8U)((INT8U)(msg->buffer_ptr[0]) >> 7);
      }
      else if ( g_setup_direction == USB_SEND )
      {
        // Мы здесь когда конечная приняла данные в запросе от хоста на чтение данных
        // Это прием конечной транзакции OUT, подтверждающей окончание процесса обработки запроса чтения данных хостом  
        g_setup_direction = USB_TRF_UNKNOWN;
        USB_DCI_Cancel_Transfer(msg->controller_ID, CONTROL_ENDPOINT, USB_SEND);
        p_ep_cbl_alt->bits.all = _DATA0;
        USB_DCI_Recv_Data(msg->controller_ID, CONTROL_ENDPOINT, NULL, 0);
      }
    }   

#ifdef LONG_RECIEVE_TRANSACTION
    /* For NON CONTROL ENDPOINT only */
    if ( p_ep_state->app_len != (INT16U)UNINITIALISED_VAL )
    {
      /* on control endpoint the data is only 8 bytes */
      INT16U size = msg->len;
      p_ep_state->curr_offset += size;

      /*
         Initiate next USB RECV if:
         1. More Data is still pending OR
         2. Received Data == Endpoint Size AND
         3. Zero Termination Flag is TRUE
      */
      if ( ((size == p_ep_state->len) && (p_ep_state->app_len > p_ep_state->curr_offset)) || 
           ((p_ep_state->app_len) && (!(p_ep_state->app_len % p_ep_state->len)) && (p_ep_state->flag == TRUE)) )
      {
        /* send next IO */
        INT16U cnt;
        if ( (p_ep_state->app_len - p_ep_state->curr_offset) > p_ep_state->len )
        {
          cnt = p_ep_state->len; 
        }
        else
        {
          cnt = p_ep_state->app_len - p_ep_state->curr_offset;
        }
        
        if ( cnt == 0 )
        {
          /* For Zero byte Packet Receive */
          p_ep_cbl_alt->addr = p_ep_state->addr;
          p_ep_cbl_alt->cnt = 0;
        }
        else
        {
          p_ep_cbl_alt->addr = (INT32U) & p_ep_state->app_buffer[p_ep_state->curr_offset];
          p_ep_cbl_alt->cnt = cnt;
        }

        /* give the ownership to SIE and Toggle DATA bit*/
        p_ep_cbl_alt->bits.all = (INT8U)(((p_ep_cbl_alt->bits.cbits.data) << 6) | _OWN | _DTS);
        return;
      }
      else /* request completed */
      {
        /* populate buffer structure */
        msg->buffer_ptr = p_ep_state->app_buffer;
        msg->len = p_ep_state->curr_offset;
        p_ep_state->app_len = (INT16U)UNINITIALISED_VAL;
      }
    }
#endif
  } /* End of RECV loop */

  /* Notify Device Layer of Data Recieved or Sent Event */
  (void)USB_Device_Call_Service(msg->ep_num, msg);

  return;
}
/**************************************************************************/ /*!
  *
  * @name  USB_ISR
  *
  * @brief The function handles USB interrupts on the bus.
  *
  * @param None
  *
  * @return None
  *
  ******************************************************************************
  * This function is hooked onto interrupt 69 and handles the USB interrupts.
  * After handling the interrupt it calls the Device Layer to notify it about
  * the event.
  *****************************************************************************/

void USB_OTG_IRQHandler(void)
{

  /* Which interrupt occured and also was enabled */
  INT8U                  intr_stat = (INT8U)(USB0_ISTAT & USB0_INTEN);
  INT8U                  usb_stat      = (INT8U)USB0_STAT;
  USB_DEV_EVENT_STRUCT   msg;
  INT16U                 dev_state = USB_STATUS_UNKNOWN;


  /* initialise msg structure */
  msg.controller_ID = g_dci_controller_Id;
  msg.setup         = FALSE;
  msg.buffer_ptr    = NULL;
  msg.len           = 0;
  msg.direction     = USB_RECV;
  msg.errors        = NO_ERRORS;

  msg.ep_num = (INT8U)UNINITIALISED_VAL;

  /* Get the device state from the Device Layer */
  (void)USB_Device_Get_Status(g_dci_controller_Id, USB_STATUS_DEVICE_STATE, &dev_state);

  /* if current devie state is SUSPEND and Low Powere Resume Flag set */
  if ( (USB0_USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) && (dev_state == USB_STATE_SUSPEND) )
  {
#ifdef USB_LOWPOWERMODE
    /* Clear SUSP Bit from USB_CTRL */
    USB_CTRL_SUSP = 0;
#endif
    /* Reset Low Power RESUME enable */
    USB0_USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK;
  }

  if ( SOF_TOKEN_FLAG(intr_stat) )
  {
    INT16U sof_count;

    /* Clear SOF Interrupt */
    USB0_ISTAT = USB_ISTAT_SOFTOK_MASK;
    sof_count = (INT16U)((USB0_FRMNUMH << FRAME_HIGH_BYTE_SHIFT) | USB0_FRMNUML);
    /*address of Lower byte of Frame number*/
    msg.buffer_ptr = (INT8U_ptr)(&sof_count);
    /* Notify Device Layer of SOF Event */
    (void)USB_Device_Call_Service(USB_SERVICE_SOF, &msg);
  }

  if ( BUS_RESET_FLAG(intr_stat) )
  {

    /* Clear Reset Flag */
    USB0_ISTAT = USB_ISTAT_USBRST_MASK;

    /* Handle RESET Interrupt */
    USB_Bus_Reset_Handler();

    /* Notify Device Layer of RESET Event */
    (void)USB_Device_Call_Service(USB_SERVICE_BUS_RESET, &msg);

    /* Clearing this bit allows the SIE to continue token processing
       and clear suspend condition */
    USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;

    /* No need to process other interrupts */
    return;
  }

  if ( TOKEN_COMPL_FLAG(intr_stat) )
  {
    // Реакция на прерывание по биту TOKDNE

    /* Clear TOKEN Interrupt */
    USB0_ISTAT = USB_ISTAT_TOKDNE_MASK;

    USB_Packet_RXTX_Handler(usb_stat, &msg);

    /* Clearing this bit allows the SIE to continue token processing and clear suspend condition */
    USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
  }

  if ( ERROR_FLAG(intr_stat) )
  {

    /* Clear ERROR Interrupt */
    USB0_ISTAT = USB_ISTAT_ERROR_MASK;

    msg.errors = (INT8U)(USB0_ERRSTAT & USB0_ERREN);

    /* Notify Device Layer of ERROR Event to error service */
    (void)USB_Device_Call_Service(USB_SERVICE_ERROR, &msg);

    USB0_ERRSTAT = ERR_STAT_CLEAR_ALL;  /*clear all errors*/
    /* Clearing this bit allows the SIE to continue token processing
       and clear suspend condition */
    USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
  }

  if ( SLEEP_FLAG(intr_stat) )
  {
    // This bit is set when the USB Module detects a constant idle on the USB bus for 3 milliseconds.
    // The sleep timer is reset by activity on the USB bus.


    /* Clear RESUME Interrupt if Pending */
    USB0_ISTAT = USB_ISTAT_RESUME_MASK;

    /* Clear SLEEP Interrupt */
    USB0_ISTAT = USB_ISTAT_SLEEP_MASK;

    /* Notify Device Layer of SLEEP Event */
    (void)USB_Device_Call_Service(USB_SERVICE_SLEEP, &msg);

    /* Set Low Power RESUME enable */
    USB0_USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK;

#ifdef USB_LOWPOWERMODE
    /* Set SUSP Bit in USB_CTRL */
    USB_CTRL_SUSP = 1;
#endif
    /* Enable RESUME Interrupt */
    USB0_INTEN |= USB_INTEN_RESUMEEN_MASK;
#ifdef USB_LOWPOWERMODE
    /* Enter Stop3 Mode*/
    Enter_StopMode(STOP_MODE3);
#endif
  }

  if ( RESUME_FLAG(intr_stat) )
  {
    // This bit is set depending upon the DP/DM signals, and can be used to signal remote wake-up signaling on  the USB bus.
    // When not in suspend mode this interrupt should be disabled.

    /* Clear RESUME Interrupt */
    USB0_ISTAT = USB_ISTAT_RESUME_MASK;

    /* Notify Device Layer of RESUME Event */
    (void)USB_Device_Call_Service(USB_SERVICE_RESUME, &msg);

    /* Disable RESUME Interrupt */
    USB0_INTEN &= ~USB_INTEN_RESUMEEN_MASK;
  }

  if ( STALL_FLAG(intr_stat) )
  {
    INT16U endp_status;


    msg.ep_num = (INT8U)UNINITIALISED_VAL;

    /* If Control Endpoint is stalled then unstall it.
    For other endpoints host issues clear endpoint feature request
    to unstall them */

    /* Get Control Endpoint Status*/
    (void)USB_Device_Get_Status(msg.controller_ID, (USB_STATUS_ENDPOINT | CONTROL_ENDPOINT), &endp_status);
    if ( endp_status == USB_STATUS_STALLED )
    {
      msg.ep_num = CONTROL_ENDPOINT;
      msg.direction = USB_SEND;
    }

    /* Clear STALL Interrupt */
    USB0_ISTAT = USB_ISTAT_STALL_MASK;

    /* Notify Device Layer of STALL Event */
    (void)USB_Device_Call_Service(USB_SERVICE_STALL, &msg);

    /* Clearing this bit allows the SIE to continue token processing
       and clear suspend condition */
    USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
  }

  return;
}

/**************************************************************************/ /*!
  *
  * @name  Clear_Mem
  *
  * @brief The function clears memory starting from start_addr till count bytes
  *
  * @param start_addr : Buffer Start address
  * @param count      : Count of Bytes
  * @param val        : Value to be set
  *
  * @return None
  ******************************************************************************
  * This function is an implementation of memset
  *****************************************************************************/
void Clear_Mem(
               INT8U_ptr start_addr,  /* [OUT] Buffer Start address */
               INT32U count,          /* [IN] Count of Bytes */
               INT8U val              /* [IN] Value to be set */
               )
{
  (void)memset(start_addr, val, count);
  return;
}

#ifdef USB_LOWPOWERMODE
/**************************************************************************/ /*!
  *
  * @name  Enter_StopMode
  *
  * @brief The function configures STOP Mode
  *
  * @param stop_mode : STOP MODE to be entered
  *
  * @return None
  ******************************************************************************
  * This function configures different STOP MODES defined by the controller.
  * Used to put controller into low power mode. Only STOP MODE 3 is implemented
  *****************************************************************************/
static void Enter_StopMode(STOP_MODE stop_mode)
{
  switch (stop_mode)
  {
  case STOP_MODE1:
    /*
       We enter Default Stop Mode
    */
    break;
  case STOP_MODE2:
    /* Save IO Pin Status in a global variable
        IO Pin Status is to be restored at POR.
        Check if PPDC
    */
    /* Set PPDC */
    break;
  case STOP_MODE3:
    /* Clear PPDC */
    SPMSC2_PPDC = 0;
    /* Disable Low Voltage Detect */
    SPMSC1_LVDSE = 0;
    break;
  case STOP_MODE4:
    break;
  }
  /* Enter STOP Mode*/
  _Stop;
}

#endif


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/if/ping6.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ping6.c$
* $Version : 3.8.1.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation of a minimal
*   ICMPv6 echo request.
*
*END************************************************************************/

#include <rtcs.h>

#include "rtcs_prv.h"
#include "tcpip.h"
#include "icmp6_prv.h"
#include "arp.h"

boolean ICMP6_expire_echo (TCPIP_EVENT_PTR);

/************************************************************************
* NAME: RTCS6_ping
* RETURNS : RTCS_OK or error code
* DESCRIPTION: Send an ICMPv6 echo request, and wait for a reply..
*************************************************************************/
uint_32 RTCS6_ping( sockaddr *ip_addr           /* [IN] remote sock addr structure       */,
                    uint_32_ptr timeout         /* [IN]  Maximum time to wait for reply  */
                                                /* [OUT] Round trip time                 */,
                    uint_16 id                  /* [IN] User id for the ping request     */, 
                    uint_8  hop_limit          /* [IN] Hope limit (optional)            */, 
                    pointer data_buffer         /* [IN] Pointer to ping data buffer (optional) */,
                    uint_32 data_buffer_size    /* [IN] Size of a ping data buffer (optional)  */ 
                  )
{
    ICMP6_PARM   parms;
    uint_32     error;

    parms.ip_addr = (in6_addr*)(&( ((sockaddr_in6 *)ip_addr)->sin6_addr ));
    parms.if_scope_id = ((struct sockaddr_in6 *)ip_addr)->sin6_scope_id; 
    parms.id        = id;
    parms.timeout   = *timeout;
    parms.hop_limit = hop_limit;
    parms.data_buffer  = data_buffer;           /* Pointer to a buffer. */
    parms.data_buffer_size = data_buffer_size;  /* Size of a buffer.    */
    
    error = RTCSCMD_issue(parms, ICMP6_send_echo);
    if (error)
        return error;

   *timeout = parms.timeout;
   return RTCS_OK;
} 

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ICMP_expire_echo
* Returned Values :
* Comments  :
*     Called by the Timer.  Expire a ICMP echo request.
*
*END*-----------------------------------------------------------------*/
boolean ICMP6_expire_echo(TCPIP_EVENT_PTR   event)
{
   ICMP6_PARM_PTR         parms = event->PRIVATE;

   RTCSCMD_complete(parms, RTCSERR_ICMP_ECHO_TIMEOUT);

   return FALSE;
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : ICMP_send_echo
* Parameters      :
*
*     _ip_address       ipaddress   [IN] destination IP address
*     uint_32           timeout     [IN/OUT] timeout/rtt
*     uint_16           id          [IN] identification for echo message.
*     uint_16           seq         not used
*
* Comments        :
*     Send an ICMP Echo Request packet.
*
*END*-----------------------------------------------------------------*/
void ICMP6_send_echo(ICMP6_PARM_PTR     parms)
{

#if RTCSCFG_ENABLE_IP6

   ICMP6_CFG_STRUCT_PTR     ICMP6_cfg_ptr = RTCS_getcfg(ICMP6);
   RTCSPCB_PTR              pcb;
   ICMP6_ECHO_HEADER_PTR    packet;
   _rtcs_if_handle          ihandle_dest = NULL; 
   uint_32                  error;


   IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_TOTAL++);
   parms->seq = ICMP6_cfg_ptr->ECHO_SEQ++;

   pcb = RTCSPCB_alloc_send();
   if (pcb == NULL)
   {
      IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      RTCSCMD_complete(parms, RTCSERR_PCB_ALLOC);
      return;
   } 
        
    if(parms->data_buffer && parms->data_buffer_size)
    {
        error = RTCSPCB_append_fragment(pcb, parms->data_buffer_size, parms->data_buffer);
        if (error) 
        {
            IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_ERRORS++);
            RTCSLOG_PCB_FREE(pcb, error);
            RTCSPCB_free(pcb);
            RTCSCMD_complete(parms, error);
            return;
        }
   }

   error = RTCSPCB_insert_header(pcb, sizeof(ICMP6_ECHO_HEADER));
   if (error)
   {
      IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_ERRORS++);
      IF_ICMP6_STATS_ENABLED(RTCS_seterror(&ICMP6_cfg_ptr->STATS.ERR_TX, error, (uint_32)pcb));
      RTCSLOG_PCB_FREE(pcb, error);
      RTCSPCB_free(pcb);
      RTCSCMD_complete(parms, error);
      return;
   } 

   RTCSLOG_PCB_WRITE(pcb, RTCS_LOGCTRL_PROTO(IPPROTO_ICMPV6), 0);

   packet = (ICMP6_ECHO_HEADER_PTR)RTCSPCB_DATA(pcb);
   pcb->TRANSPORT_LAYER = (uchar_ptr)packet;
   htonc(packet->HEAD.TYPE, ICMP6_TYPE_ECHO_REQ);
   htonc(packet->HEAD.CODE, 0);
   htons(packet->HEAD.CHECKSUM, 0);
   htons(packet->ID,  parms->id);
   htons(packet->SEQ, parms->seq);

   pcb->IP_SUM     = IP_Sum_PCB(RTCSPCB_SIZE(pcb), pcb);
   pcb->IP_SUM_PTR = packet->HEAD.CHECKSUM;
  
   if(parms->if_scope_id)
   {
        ihandle_dest = ip6_if_get_by_scope_id(parms->if_scope_id);
   }

   parms->EXPIRE.TIME    = parms->timeout;
   parms->EXPIRE.EVENT   = ICMP6_expire_echo;
   parms->EXPIRE.PRIVATE = parms;
   parms->timeout = RTCS_time_get();   /* get timestamp */

   /*TBD add to IP6_send(pcb, IPPROTO_ICMPV6, NULL,......  ipsrc address in depend on scope ID      */
   /*So, our ping6 should be able procced scope ID and choose right interface  source IPv6 address  */
   error = IP6_send(pcb, IPPROTO_ICMPV6|IPTTL(parms->hop_limit), NULL/*ipsrc*/, parms->ip_addr/*ipdest*/, ihandle_dest, 0);


   if (error != RTCS_OK)
   {
      IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.COMMON.ST_TX_MISSED++);
      RTCSCMD_complete(parms, error);
      return;
   }

   /*
   ** If there is no error add the parm struct to config struct
   ** and initiate the event timer
   */

   IF_ICMP6_STATS_ENABLED(ICMP6_cfg_ptr->STATS.ST_TX_ECHO_REQ++);

   /* add the prameter structure to ICMP  cfg */
   parms->NEXT = ICMP6_cfg_ptr->ECHO_PARM_HEAD;
   if (parms->NEXT)
   {
      parms->NEXT->PREV = &parms->NEXT;
   } /* Endif */
   ICMP6_cfg_ptr->ECHO_PARM_HEAD = parms;
   parms->PREV = &ICMP6_cfg_ptr->ECHO_PARM_HEAD;

   TCPIP_Event_add(&parms->EXPIRE);

#else
    RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);
#endif /* RTCSCFG_ENABLE_IP6 */
}



<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/tcp_clos.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: tcp_clos.c$
* $Version : 3.6.8.0$
* $Date    : Dec-1-2010$
*
* Comments:
*
*   A TCB can be released (via TCP_Process_release) only after the upper layer
*   has provided a tcpCLOSE (or tcpABORT) command or if a tcpOPEN
*   command has failed.  In all other cases the TCB may be moved to
*   CLOSED state (via TCP_Close_TCB), but the TCB cannot be released.
*   The cases where the upper layer has closed are not easy to see (because
*   in the normal case the connection stays up until the other side is
*   also ready to close), but this occurs while in states:
*   FINWAIT_1, FINWAIT_2, CLOSING, TIME_WAIT, and LAST_ACK.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "ticker.h"     /* for timer definitions */
#include "tcpip.h"      /* for error codes */
#include "tcp_prv.h"    /* for TCP internal definitions */
#include "socket.h"     /* for TCP internal definitions */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Free_TCB
* Returned Values : None.
* Comments        :
*
*  Deallocate TCB; must only be done when TCB has been closed and released.
*
*END*-----------------------------------------------------------------*/

void TCP_Free_TCB
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   TCB_STRUCT_PTR    tmp;

   /*
   ** Free everything which wasn't freed in TCP_Close_TCB() ...
   */
   TCP_Truncate_receive_chunks(tcb, tcp_cfg, tcb->rcvlen); /* delete all chunk nodes */
   if ( tcb->rcvringbuf != NULL ) {

      _mem_free(tcb->rcvringbuf);
      tcb->rcvringbuf = NULL;

   } /* Endif */

   /*
   ** Deallocate TCB itself
   */
   if ( tcb != NULL ) {

      if ( tcb == tcp_cfg->TCBhead ) {
         tcp_cfg->TCBhead = tcb->next;
      } else {
         tmp = tcp_cfg->TCBhead;
         while ( tmp != NULL && tmp->next != tcb ) {
            tmp = tmp->next;
         } /* Endwhile */
         if ( tmp != NULL ) {
            tmp->next = tcb->next;
         } /* Endif */
      } /* Endif */
   } /* Endif */

   if (tcb->SOCKET) {
      ((SOCKET_STRUCT_PTR)tcb->SOCKET)->TCB_PTR = NULL;
   } /* Endif */
   tcb->VALID = TCB_INVALID_ID;

   tcp_cfg->CONN_COUNT--;
#if RTCSCFG_TCP_MAX_HALF_OPEN
    TCB_HALF_OPEN_DROP
#endif

   _mem_free(tcb);

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_release
* Returned Values : None.
* Comments        :
*
*  Release the TCB so that it can no longer be used.  Called only
*     when in CLOSED state with no more data to receive.
*
*END*-----------------------------------------------------------------*/

void TCP_Process_release
   (
      TCB_STRUCT_PTR          tcb,     /* IN     - TCP context */
      TCP_CFG_STRUCT_PTR      tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   TCB_STRUCT_PTR _PTR_ search_ptr = &tcp_cfg->NOSOCK_TCB;
   TCB_STRUCT_PTR       temp_tcb;

   /*
   ** 1. Check if the TCB was spawned by a listening TCB, and if so remove it from
   **    the list of spawned listening TCBs.
   ** 2. If the TCB that is begin released is a listening TCB and it spawned
   **    other TCBs, they must also be freed.
   */
   while (*search_ptr) {
      if (*search_ptr == tcb) {
         /* The TCB we are releasing is a child of a listening TCB */
         *search_ptr = (*search_ptr)->NOSOCK_NEXT;
         break;
      } /* Endif */

      if (tcb && (*search_ptr)->LISTEN_TCB == tcb) {
         /*
         ** The TCB is a listening TCB and we have found one of its children.
         ** Delete the child. Recursion is only one level deep, because the
         ** child is not a listening TCB and has not spawned any TCBs of its own
         */
         temp_tcb = *search_ptr;
         *search_ptr = temp_tcb->NOSOCK_NEXT;
         TCP_Close_TCB(temp_tcb, RTCS_OK, tcp_cfg);
         TCP_Process_release(temp_tcb, tcp_cfg);
         continue;
      } /* Endif */

      search_ptr = &(*search_ptr)->NOSOCK_NEXT;
   } /* Endwhile */

   TCP_Free_TCB(tcb, tcp_cfg);

} /* Endbody */



/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Close_TCB
* Returned Values : None.
* Comments        :
*
*  Enter CLOSED state and terminate all requests with error code errnum.
*
*  Will be followed by a TCP_Process_release at some time, when there
*     is no more data to receive.  Note that this call will prevent
*     and further data from being queued (and so should immediately
*     be followed by a check for ability to release).
*
*  This is the only routine which puts a TCB in the CLOSED state.
*
*END*-----------------------------------------------------------------*/

void TCP_Close_TCB
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      int_32               errnum,  /* IN     - error code to return */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   TCP_PARM_PTR      req;
   SbufNode _PTR_    buf;
   boolean           first = TRUE;  /* for returning Sends */
   boolean           not_syn_recv = (tcb->state != SYN_RECEIVED);

   /*
   ** This prevents new packets from being queued on this TCB;
   **   however there might still be some queued (but only if
   **   there are no outstanding Receive requests).
   */
   tcb->state = CLOSED;

   /*
   ** Cancel timers...
   */
   (void)TCP_Timer_stop(&tcb->sndxmittq.t, tcp_cfg->qhead);
   (void)TCP_Timer_stop(&tcb->sndacktq.t, tcp_cfg->qhead);
   (void)TCP_Timer_stop(&tcb->sndtq.t, tcp_cfg->qhead);
   (void)TCP_Timer_stop(&tcb->rcvtq.t, tcp_cfg->qhead);

   /*
   ** Return open request if there is one.  This should
   ** only happen if we are closing on error.
   */
   if ( errnum != RTCS_OK && not_syn_recv) {
      TCP_Return_open(tcb, errnum, tcp_cfg);
   } /* Endif */

   /*
   ** Terminate any Receive requests.  We can't receive any more
   **    packets in the CLOSED state, and presence of any Receives
   **    means that all data that could be (contiguously) in the
   **    first Receive is already there (see TCP_Process_data).
   **
   ** In this case the TCB could actually be released, but wait for
   **    user to close it.  Don't have to delete all of the RcvChunks
   **    or indicate no data left in ring since a TCP_Process_close or
   **    TCP_Process_receive will do this.
   */
   while ( tcb->rcvHead != NULL ) {

      TCP_Reply_receive(tcb, tcp_cfg, errnum);
      if ( tcb->rcvHead != NULL ) {
         TCP_Setup_receive(tcb->rcvHead, tcb, tcp_cfg);
      } /* Endif */

   } /* Endwhile */

   /*
   ** Terminate any Send requests
   */
   buf = tcb->sndbuf;
   while ( buf != NULL ) {

      tcb->sndbuf = buf->next;
      if ( tcb->sndbuf == NULL ) {
         tcb->sndbuftail = NULL;
      } /* Endif */

      req = buf->req;
      if ( req != NULL ) {

         /* report actual amount sent */
         if ( first ) {
            req->BUFF_LENG  = tcb->snduna - tcb->sndbufseq;
         } else {
            req->BUFF_LENG = 0;
         } /* Endif */
         RTCSCMD_complete(req, errnum);

      } /* Endif */
      first = FALSE;

      _mem_free(buf);
      buf = tcb->sndbuf;

   } /* Endwhile */


   /*  Terminate any wait request
    */
#if 0
   req = tcb->oclient;
   if ( req != NULL ) {

      req->STATUS     = tcb->status;
      req->SOFTERROR  = tcb->lasterror;
      RTCSCMD_complete(req, errnum);
      tcb->oclient    = NULL;

   } /* Endif */
#endif

   /*
   ** Notify socket layer in case some task is blocked on select()
   ** waiting for data on this socket.
   */
   SOCK_select_signal(tcb->SOCKET, tcb->state);   

   /*  Delete send buffers (keep receive buffer in case there is
    *  pending data)
    */
   if ( tcb->sndringbuf != NULL ) {
      _mem_free(tcb->sndringbuf);
   } /* Endif */
   tcb->sndringbuf = NULL;

   if ( tcb->sndclk != NULL ) {
      _mem_free(tcb->sndclk);     /* xmit timestamps buffer */
   } /* Endif */
   tcb->sndclk = NULL;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_effective_close
* Returned Values : None.
* Comments        :
*
*  Called when the connection is actually closed, i.e., when all data
*   to send has been sent and FIN can at last be sent.
*
*END*-----------------------------------------------------------------*/

void TCP_Process_effective_close
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN     - TCP layer data */
   )
{ /* Body */
   RTCSLOG_FNE2(RTCSLOG_FN_TCP_Process_effective_close, tcb->state);
    
   switch ( tcb->state ) {

      case SYN_RECEIVED:
         /* no data has been sent  */

      case ESTABLISHED:
         tcb->state = FINWAIT_1;
         TCP_Must_send_ack(tcb, tcp_cfg);
         break;

      case CLOSE_WAIT:
         tcb->state = LAST_ACK;
         TCP_Must_send_ack(tcb, tcp_cfg);
         break;

      default:
         RTCS_log_error(ERROR_TCP,
                             RTCSERR_TCP_BAD_STATE_FOR_CLOSE,
                             (uint_32)tcb->state,
                             (uint_32)tcb, 0);

         break;

   } /* End Switch */

    SOCK_select_signal(tcb->SOCKET, tcb->state);
   
    RTCSLOG_FNX1(RTCSLOG_FN_TCP_Process_effective_close);
} /* Endbody */




/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_close
* Returned Values : None.
* Comments        :
*
*  Process TcpClose() requests, within TCP server.
*
*END*-----------------------------------------------------------------*/

void TCP_Process_close
   (
      TCP_PARM_PTR   req_ptr     /* IN/OUT - the open request */
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;
   TCB_STRUCT_PTR       tcb;
   int_32               reply = RTCS_OK;

   tcp_cfg = RTCS_getcfg(TCP);
   tcb = req_ptr->TCB_PTR;

   if ( tcb == NULL ) { 
      RTCSCMD_complete(req_ptr, RTCSERR_TCP_CONN_RLSD);
      return;
   } 

   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_CONN_CLOSED++);

   if ( tcb->VALID != TCB_VALID_ID ) {
      reply = RTCSERR_TCP_CONN_RLSD;
      RTCS_log_error( ERROR_TCP,
                           RTCSERR_TCP_BAD_STATE_FOR_CLOSE,
                           (uint_32)tcb,
                           (uint_32)tcb->state,
                           1 );

   } else if ( tcb->state == CLOSED ) {

      /* This should be the standard case if the other side aborted. */
      TCP_Process_release(tcb, tcp_cfg);

   } else if ( (tcb->status & TCPS_FINTOSEND) != 0 ) {

      /* Upper layer must have already given us a tcpCLOSE, so we
       *    can generate an error here. */
      reply = RTCSERR_TCP_CONN_CLOSING;

   } else {

      switch ( tcb->state ) {

         case LISTEN:
         case SYN_SENT:
            TCP_Close_TCB(tcb, RTCS_OK, tcp_cfg);
          case BOUND:
            TCP_Process_release(tcb, tcp_cfg);
            break;

         case SYN_RECEIVED:
            /* no data has been sent */

         case ESTABLISHED:
         case CLOSE_WAIT:

            TCP_Event(tcb,TCPS_FINTOSEND);

            /*  We can only effectively close if all data has been sent,
             *   allowing us to send a FIN immediately; otherwise closing
             *   is delayed (TCPS_FINTOSEND indicates that connection should
             *   be closed as soon as all data is sent)
             */
            if ( tcb->sndnxt == (tcb->sndbufseq + tcb->sndlen) ) {
               TCP_Process_effective_close(tcb, tcp_cfg);
            } else {
               /*
               **  Have to kick ourselves into sending the outstanding
               **  data or we'll sit here forever if the other side is
               **  just waiting.  This would happen if we send w/o PUSH
               **  just before closing.
               */
               TCP_Must_send_ack(tcb, tcp_cfg);
            } /* Endif */

            break;

         default:
            /*  we shouldn't reach here, but jic...  */
            RTCS_log_error( ERROR_TCP,
                                 RTCSERR_TCP_BAD_STATE_FOR_CLOSE,
                                 (uint_32)tcb,
                                 (uint_32)tcb->state,
                                 2);

            reply = RTCSERR_TCP_NOT_CONN;
            break;

      } /* End Switch */

   } /* Endif */

   /* The socket will be freed as soon as we return to shutdown() */
   if (tcb->VALID == TCB_VALID_ID) {
       tcb->SOCKET = 0;
   } /* Endif */

   RTCSCMD_complete(req_ptr, reply);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_Process_abort
* Returned Values : None.
* Comments        :
*
*  Process TcpAbort() requests, within TCP server.
*
*END*-----------------------------------------------------------------*/

void TCP_Process_abort
   (
      TCP_PARM_PTR   req_ptr     /* IN/OUT - the open request */
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;
   TCB_STRUCT_PTR       tcb;
   int_32               reply = RTCS_OK;

   tcp_cfg = RTCS_getcfg(TCP);
   tcb = req_ptr->TCB_PTR;

   if ( tcb == NULL ) { 
      RTCSCMD_complete(req_ptr, RTCSERR_TCP_CONN_RLSD);
      return;
   } 

   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_CONN_ABORTS++);

   if ( tcb->VALID != TCB_VALID_ID ) {
      reply = RTCSERR_TCP_CONN_RLSD;

   } else {

      switch ( tcb->state ) {

         case LISTEN:
            /*
            ** allows for shutdown of listening socket with ABORT option set.
            */
            TCP_Close_TCB(tcb, RTCS_OK, tcp_cfg);
            TCP_Process_release(tcb, tcp_cfg);
            break;

         case SYN_RECEIVED:
         case ESTABLISHED:
         case FINWAIT_1:
         case FINWAIT_2:
         case CLOSE_WAIT:
            TCP_Send_reset(tcb, tcp_cfg);      /* send reset packet */
            /*FALLTHROUGH*/

         case SYN_SENT:
         case CLOSING:
         case LAST_ACK:
         case TIME_WAIT:
            TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_ABORTED, tcp_cfg);
            /*FALLTHROUGH*/

         case BOUND:
         case CLOSED:
            TCP_Process_release(tcb, tcp_cfg);
            break;

         default:
            reply = RTCSERR_TCP_NOT_CONN;
            break;

      } /* End Switch */

   } /* Endif */

   /* The socket will be freed as soon as we return to shutdown() */
   if (tcb->VALID == TCB_VALID_ID) {
      /* Following code no longer needed, as the option is propagated to the TCB when set */ 
      tcb->SOCKET = 0;
   } /* Endif */

   RTCSCMD_complete(req_ptr, reply);

} /* Endbody */

#if RTCSCFG_TCP_MAX_HALF_OPEN
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : TCP_half_open_TCB_close
* Returned Values : void
* Comments        :
* This function can be called to recover from SYN attack.
*
*END*-----------------------------------------------------------------*/

void TCP_half_open_TCB_close
   (
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN/OUT - TCP layer data */
   )
{ /* Body */
   TCB_STRUCT_PTR       tcb;
   uint_32              curr_time;
   uint_32              removed_tcb_count = 0;
   int                  i;

   curr_time = RTCS_time_get();
   /*
   ** Delete all the TCBs older than the default retransmission
   ** timeout (3 seconds).
   */
   for (i = 0; i < tcp_cfg->HALF_OPEN_TCB_COUNT; i++) {
      tcb = tcp_cfg->HALF_OPEN_TCB_LIST[i];
      if(RTCS_timer_get_interval(tcb->tcb_spawn_time, curr_time) > TCP_INITIAL_RTO_DEFAULT) {
         TCP_Send_reset(tcb, tcp_cfg);      /* send reset packet */
         TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_ABORTED, tcp_cfg);
         TCP_Process_release(tcb, tcp_cfg);
         i--;   /* we removed a TCB  and replaced another TCB
                   from the end, so we need to check same spot again */
         removed_tcb_count++;
      } /* Endif */
   } /* Endfor */

   /*
   ** Remove one TCB from the half open list randomly. Remove the TCB
   ** with a reset. If this is not an attack the client will resend the SYN.
   */
   if (!removed_tcb_count && tcp_cfg->HALF_OPEN_TCB_COUNT) {
      i = RTCS_rand() % tcp_cfg->HALF_OPEN_TCB_COUNT;
      tcb = tcp_cfg->HALF_OPEN_TCB_LIST[i];
      TCP_Send_reset(tcb, tcp_cfg);      /* send reset packet */
      TCP_Close_TCB(tcb, RTCSERR_TCP_CONN_ABORTED, tcp_cfg);
      TCP_Process_release(tcb, tcp_cfg);
   } /* Endif */
} /* Endbody */
#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/nvic.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2012 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: cortexa5.h$
* $Version : 3.8.7.0$
* $Date    : Oct-2-2012$
*
* Comments:
* ARM Nested Vectored Interrupt Controller (NVIC)
*
*END************************************************************************/

#include "mqx_inc.h"
#include "nvic.h"

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _nvic_int_init
* Returned Value  : uint_32
*       MQX_OK or error code
* Comments        :
*  	Initialize a specific interrupt in the cortex core nvic
*
*END*---------------------------------------------------------------------*/

_mqx_uint _nvic_int_init
   (
      // [IN} Interrupt number
      _mqx_uint irq,

      // [IN} Interrupt priority
      _mqx_uint prior,

      // [IN] enable the interrupt now?
      boolean enable
   )
{
	VCORTEX_NVIC_STRUCT_PTR nvic = (VCORTEX_NVIC_STRUCT_PTR)&(((CORTEX_SCS_STRUCT_PTR)CORTEX_PRI_PERIPH_IN_BASE)->NVIC);
	_mqx_uint ext_irq_no = irq - 16;

	// check priority value, must be below maximal enabled/set value
	if (prior >= (1 << CORTEX_PRIOR_IMPL)) {
		return MQX_INVALID_PARAMETER;
	}

	if (irq >= PSP_INT_FIRST_INTERNAL && irq <= PSP_INT_LAST_INTERNAL) {
		nvic->PRIORITY[ext_irq_no >> 2] = (nvic->PRIORITY[ext_irq_no >> 2] & ~(0xff << ((ext_irq_no & 3) * 8))) | (((prior << CORTEX_PRIOR_SHIFT) & CORTEX_PRIOR_MASK) << ((ext_irq_no & 3) * 8));

		if (enable)
			_nvic_int_enable(irq);
		else
			_nvic_int_disable(irq);

    }
    else
        return MQX_INVALID_PARAMETER;

    return MQX_OK;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _nvic_int_enable
* Returned Value  : uint_32
*       MQX_OK or error code
* Comments        :
* 	Enable interrupt on cortex core NVIC
*
*END*---------------------------------------------------------------------*/
_mqx_uint _nvic_int_enable
   (
      // [IN] Interrupt number
      _mqx_uint  irq
   )
{
    VCORTEX_NVIC_STRUCT_PTR nvic = (VCORTEX_NVIC_STRUCT_PTR)&(((CORTEX_SCS_STRUCT_PTR)CORTEX_PRI_PERIPH_IN_BASE)->NVIC);
    uint_32 ext_irq_no = irq - 16;

    if (ext_irq_no >= PSP_INT_FIRST_INTERNAL && ext_irq_no <= PSP_INT_LAST_INTERNAL) {
        nvic->ENABLE[ext_irq_no >> 5] = 1 << (ext_irq_no & 0x1f);
    }
    else
        return MQX_INVALID_PARAMETER;

    return MQX_OK;
}

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _nvic_int_disable
* Returned Value  : uint_32
*       MQX_OK or error code
* Comments        :
* 	Disable interrupt on cortex core NVIC
*
*END*---------------------------------------------------------------------*/

_mqx_uint _nvic_int_disable
   (
      // [IN] Interrupt number
      _mqx_uint  irq
   )
{
    VCORTEX_NVIC_STRUCT_PTR nvic = (VCORTEX_NVIC_STRUCT_PTR)&(((CORTEX_SCS_STRUCT_PTR)CORTEX_PRI_PERIPH_IN_BASE)->NVIC);
    uint_32 ext_irq_no = irq - 16;

    if (ext_irq_no >= PSP_INT_FIRST_INTERNAL && ext_irq_no <= PSP_INT_LAST_INTERNAL) {
        nvic->DISABLE[ext_irq_no >> 5] = 1 << (ext_irq_no & 0x1f);
    }
    else
        return MQX_INVALID_PARAMETER;

    return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/apps/sockio.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: sockio.c$
* $Version : 3.8.16.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file contains the implementation of an MQX
*   socket I/O device.
*
*END************************************************************************/

#include <rtcs.h>
#include <fio.h>

#define SOCKIO_MIN_BUFFER 64
#define SOCKIO_MAX_BUFFER (64*1024)

typedef struct io_socket {
   uint_32  SOCKET;
   uint_32  COUNT;
   uint_32  SIZE;
   char_ptr BUFFER;
} IO_SOCKET, _PTR_ IO_SOCKET_PTR;

_mqx_int _io_socket_open  (MQX_FILE_PTR, char _PTR_,  char _PTR_);
_mqx_int _io_socket_close (MQX_FILE_PTR);
_mqx_int _io_socket_read  (MQX_FILE_PTR, char _PTR_, _mqx_int);
_mqx_int _io_socket_write (MQX_FILE_PTR, char _PTR_, _mqx_int);
_mqx_int _io_socket_ioctl (MQX_FILE_PTR, _mqx_uint, pointer);


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_socket_install
* Returned Value :
* Comments       :
*
*END*-----------------------------------------------------------------*/

int_32 _io_socket_install
   (
      char_ptr identifier
   )
{ /* Body */

   return _io_dev_install(identifier,
                          _io_socket_open,
                          _io_socket_close,
                          _io_socket_read,
                          _io_socket_write,
#if MQX_VERSION < 250
                          (int_32(_CODE_PTR_)(MQX_FILE_PTR, uint_32, uint_32_ptr))
#endif
                          _io_socket_ioctl,
                          NULL );
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_socket_open
* Returned Value :
* Comments       :
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_socket_open
   (
      MQX_FILE_PTR fd_ptr,
      char _PTR_  open_name_ptr,
      char _PTR_  flags_ptr
   )
{ /* Body */
   IO_SOCKET_PTR io_ptr;

   io_ptr = RTCS_mem_alloc_zero(sizeof(*io_ptr));
   if (io_ptr == NULL) {
      return MQX_OUT_OF_MEMORY;
   } /* Endif */
   
   _mem_set_type(io_ptr, MEM_TYPE_IO_SOCKET);
   
   fd_ptr->DEV_DATA_PTR = io_ptr;

   io_ptr->SOCKET = (uint_32)flags_ptr;

   return MQX_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_socket_close
* Returned Value :
* Comments       :
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_socket_close
   (
      MQX_FILE_PTR fd_ptr
   )
{ /* Body */

   IO_SOCKET_PTR  io_ptr;


   if (fd_ptr->DEV_DATA_PTR != NULL) 
   {
      io_ptr = fd_ptr->DEV_DATA_PTR;
      if (io_ptr->BUFFER != NULL) 
      {
         _mem_free(io_ptr->BUFFER);
      }
      fd_ptr->DEV_DATA_PTR = NULL;
      _mem_free(io_ptr);
   }
   return MQX_OK;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_socket_read
* Returned Value : void
* Comments       :
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_socket_read
   (
      MQX_FILE_PTR fd_ptr,
      char _PTR_  data_ptr,
      _mqx_int    num
   )
{ /* Body */
   IO_SOCKET_PTR io_ptr;

   io_ptr = fd_ptr->DEV_DATA_PTR;
   if (io_ptr != NULL) {
   
   // flush any pending data before reading
   if (io_ptr->COUNT) {
      send(io_ptr->SOCKET, io_ptr->BUFFER, io_ptr->COUNT, 0);
      io_ptr->COUNT = 0;
   }

     return (_mqx_int)recv(io_ptr->SOCKET, data_ptr, num, 0);
   } /* Endif */

   return -1;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_socket_set_send_push
* Returned Value : void
* Comments       :
*
*END*-----------------------------------------------------------------*/
static _mqx_int _io_socket_set_send_push( uint_32 sock, boolean value)
{
   return setsockopt(sock, SOL_TCP, OPT_SEND_PUSH, &value, sizeof(value));
}

/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_socket_write
* Returned Value : void
* Comments       :
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_socket_write
   (
      MQX_FILE_PTR fd_ptr,
      char _PTR_  data_ptr,
      _mqx_int    num
   )
{ /* Body */
   IO_SOCKET_PTR io_ptr = fd_ptr->DEV_DATA_PTR;
   _mqx_int      sent = IO_ERROR;

   if (io_ptr != NULL) {
      if ( io_ptr->SIZE ) {
         if  (io_ptr->COUNT+num > io_ptr->SIZE) {
            
            if (io_ptr->COUNT) {
               send(io_ptr->SOCKET, io_ptr->BUFFER, io_ptr->COUNT, 0);
               io_ptr->COUNT = 0;
            }
            sent = (_mqx_int)send(io_ptr->SOCKET, data_ptr, num, 0);

         } else if (num==1) {
            // most writes are 1 byte.
            io_ptr->BUFFER[io_ptr->COUNT++] = *data_ptr;
            
            sent=1;
            
            if (io_ptr->COUNT == io_ptr->SIZE) {
               // buffer is full, flush it
               send(io_ptr->SOCKET, io_ptr->BUFFER, io_ptr->COUNT, 0);
               io_ptr->COUNT=0;
            }
            
         } else {
            _mem_copy(data_ptr,&io_ptr->BUFFER[io_ptr->COUNT],num);
            io_ptr->COUNT+=num;
            sent=num;
         }
      } else {     
         sent = (_mqx_int)send(io_ptr->SOCKET, data_ptr, num, 0);
      } 
   }

   return sent;

} /* Endbody */

static char buffer[256];


/*FUNCTION*-------------------------------------------------------------
*
* Function Name  : _io_socket_ioctl
* Returned Value : void
* Comments       :
*
*END*-----------------------------------------------------------------*/

_mqx_int _io_socket_ioctl
   (
      MQX_FILE_PTR fd_ptr,
      _mqx_uint   cmd,
      pointer     param_ptr
   )
{ /* Body */
   IO_SOCKET_PTR  io_ptr;
   _mqx_int       result = IO_ERROR, bytes;
   uint_32        size;

   io_ptr = fd_ptr->DEV_DATA_PTR;
   if (io_ptr != NULL) {
      switch (cmd) {
         case IO_IOCTL_CHAR_AVAIL:
            if (RTCS_selectset(&io_ptr->SOCKET, 1, (uint_32)-1)) {
               *(boolean _PTR_)param_ptr = TRUE;
            } else {
               *(boolean _PTR_)param_ptr = FALSE;
            } /* Endif */
            result=MQX_OK;
            break;         
      
         case IO_IOCTL_FLUSH_OUTPUT:
            if (io_ptr->COUNT) {
               bytes = send(io_ptr->SOCKET, io_ptr->BUFFER, io_ptr->COUNT, 0);
               if (bytes==io_ptr->COUNT) {
                  io_ptr->COUNT = 0;
                  result = MQX_OK;
               }
            } else {
               result = MQX_OK;
            }
            break;
            
         case IO_IOCTL_SET_BLOCK_MODE:
            size = *(uint_32_ptr)param_ptr;
            result=MQX_OK;
            if (size != io_ptr->SIZE) {
               // First, clear out the old buffer
               if (io_ptr->BUFFER) {
                  if (io_ptr->COUNT) {
                     bytes = send(io_ptr->SOCKET, io_ptr->BUFFER, io_ptr->COUNT, 0);
                     io_ptr->COUNT = 0;
                  }
                  _mem_free(io_ptr->BUFFER);
                  io_ptr->BUFFER = NULL;
               }
            
               if (size) {
                  // Size is set, entering block mode
                  if (size < SOCKIO_MIN_BUFFER) {
                     size = SOCKIO_MIN_BUFFER;
                  }
                  if (size > SOCKIO_MAX_BUFFER) {
                     size = SOCKIO_MAX_BUFFER;
                  }

                  io_ptr->BUFFER = RTCS_mem_alloc(size);
                  if (io_ptr->BUFFER==NULL) {
                     size = 0;
                     result = IO_ERROR;
                  } else {
                     _io_socket_set_send_push(io_ptr->SOCKET, TRUE);
                  }
                  
               }                     

               io_ptr->SIZE = size;
            }
            break;      
            
         case IO_IOCTL_GET_BLOCK_SIZE:
            result=MQX_OK;
            *(boolean _PTR_)param_ptr = io_ptr->SIZE;
            break;
            
       }      
   }

   return result;

} /* Endbody */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/ip_reasm.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ip_reasm.c$
* $Version : 3.8.13.0$
* $Date    : Oct-9-2012$
*
* Comments:
*
*   This file contains the code to handle IP reassembly
*
*END************************************************************************/

#include <stddef.h>
#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "icmp_prv.h"
#if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) || (RTCSCFG_ENABLE_IP6_REASSEMBLY && RTCSCFG_ENABLE_IP6)

IP_DGRAM_PTR  IPREASM_head;  /* list of all IP_DGRAMs */
_rtcs_part    IPREASM_part;  /* the partition id for the buffer */

#if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4)
static IP_DGRAM_PTR IPREASM_get_dgram   (_ip_address, _ip_address, uint_8, uint_16);
static void         IPREASM_add_frag    (IP_DGRAM_PTR, RTCSPCB_PTR);
static RTCSPCB_PTR  IPREASM_reasm_dgram (IP_DGRAM_PTR);
static boolean IPREASM_expire (TCPIP_EVENT_PTR);
#endif /* (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_reasm_init
*  Returned Value : RTCS_OK or error code
*  Comments       : called by IP_init()
*
*END*-----------------------------------------------------------------*/

uint_32 IP_reasm_init
   (
      void
   )
{ /* Body */

   RTCS_DLIST_INIT(IPREASM_head);

   /*
   ** Allocate the memory partition.  Use an initial count of zero, since we
   ** usually never need to reassemble datagrams.
   */
   IPREASM_part =
      RTCS_part_create(sizeof(IPREASM_BLK),
         0, IPREASM_PART_GROW, IPREASM_PART_MAX, NULL, NULL);
   if (IPREASM_part == 0) {
      return RTCSERR_OUT_OF_MEMORY;
   } /* Endif */

   return RTCS_OK;
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPREASM_blk_get
*  Returned Value : pointer to block containing offset
*  Comments       :
*     Retrieve the block containing a particular datagram offset,
*     allocating one if necessary.
*
*END*-----------------------------------------------------------------*/

IPREASM_BLK_PTR IPREASM_blk_get
   (
      IP_DGRAM_PTR   dgram,  /* [IN] the IP datagram */
      uint_32        offset  /* [IN] the offset into the datagram */
   )
{ /* Body */
   IPREASM_BLK_PTR   blk;
   uint_32           nb;
   uint_32           ni;

   nb = IPREASM_BLK_NUM(offset);
   if (IPREASM_IS_DIRECT(nb)) {
      blk = dgram->DIRECT[nb];
      if (!blk) {
         blk = RTCS_part_alloc(IPREASM_part);
         if (blk) {
            blk->BUSYINT = 0;
            dgram->DIRECT[nb] = blk;
         } /* Endif */
      } /* Endif */
      return blk;
   } /* Endif */

   /* If we get here, it's an indirect block */

   ni = IPREASM_IND_NUM(nb);
   if (ni >= IPREASM_NB_IND) {
      return NULL;
   } /* Endif */

   if (!dgram->INDIR[ni]) {
      dgram->INDIR[ni] = RTCS_part_alloc_zero(IPREASM_part);
      if (!dgram->INDIR[ni]) {
         return NULL;
      } /* Endif */
   } /* Endif */

   nb = IPREASM_IND_OFS(nb);
   blk = dgram->INDIR[ni]->DIRECT[nb];
   if (!blk) {
      blk = RTCS_part_alloc(IPREASM_part);
      if (blk) {
         blk->BUSYINT = 0;
         dgram->INDIR[ni]->DIRECT[nb] = blk;
      } /* Endif */
   } /* Endif */
   return blk;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPREASM_blk_write
*  Returned Value : number of bytes written
*  Comments       :
*     Writes data to blk at offset.
*
*END*-----------------------------------------------------------------*/

uint_32 IPREASM_blk_write
   (
      IP_DGRAM_PTR      dgram,
      IPREASM_BLK_PTR   blk,
      uint_32           offset,
      uchar_ptr         ptr,
      uint_32           len
   )
{ /* Body */
   uint_32 blkoffset, bitoffset, numbits;
   uint_32 mask, oldbits;

   blkoffset = IPREASM_BLK_OFS(offset);

   if (blkoffset + len > IPREASM_BLK_SIZE) {
      len = IPREASM_BLK_SIZE - blkoffset;
   } /* Endif */
   _mem_copy(ptr, blk->DATA + blkoffset, len);

   bitoffset = blkoffset >> 3;  /* first bit to set in BUSYINT */
   numbits   = (len+7)   >> 3;  /* number of bits to set */
   /* mask = (1 << (bitoffset+numbits)) - (1 << bitoffset) */
   mask = (2 << (bitoffset+numbits-1)) - (1 << bitoffset);

   oldbits = mask & blk->BUSYINT;
   while (oldbits) {
      oldbits &= oldbits - 1;
      numbits--;
   } /* Endfor */
   blk->BUSYINT |= mask;

   dgram->CURLEN += numbits << 3;
   if (dgram->MAXLEN < offset + len) {
      dgram->MAXLEN = offset + len;
   } /* Endif */

   return len;

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPREASM_blk_read_all
*  Returned Value : void
*  Comments       :
*     Reads data into ptr.
*
*END*-----------------------------------------------------------------*/

void IPREASM_blk_read_all
   (
      IP_DGRAM_PTR   dgram,
      uchar_ptr      ptr,
      uint_32        len
   )
{ /* Body */
   uint_32              i, j;
   IPREASM_INDIDX_PTR   indir;

   /* Read the direct blocks */
   for (i = 0; i < IPREASM_NB_DIRECT; i++) {
      if (len <= IPREASM_BLK_SIZE) {
         _mem_copy(dgram->DIRECT[i]->DATA, ptr, len);
         return;
      } /* Endif */
      _mem_copy(dgram->DIRECT[i]->DATA, ptr, IPREASM_BLK_SIZE);
      ptr += IPREASM_BLK_SIZE;
      len -= IPREASM_BLK_SIZE;
   } /* Endfor */

   /* Read the indirect blocks */
   for (i = 0; i < IPREASM_NB_IND; i++) {
      indir = dgram->INDIR[i];
      for (j = 0; j < IPREASM_IND_SIZE; j++) {
         if (len <= IPREASM_BLK_SIZE) {
            _mem_copy(indir->DIRECT[j]->DATA, ptr, len);
            return;
         } /* Endif */
         _mem_copy(indir->DIRECT[j]->DATA, ptr, IPREASM_BLK_SIZE);
         ptr += IPREASM_BLK_SIZE;
         len -= IPREASM_BLK_SIZE;
      } /* Endfor */
   } /* Endfor */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPREASM_blk_del_all
*  Returned Value : void
*  Comments       :
*     Free all blocks allocated to a datagram.
*
*END*-----------------------------------------------------------------*/

void IPREASM_blk_del_all
   (
      IP_DGRAM_PTR    dgram   /* [IN] the IP datagram */
   )
{ /* Body */
   uint_32              i, j;
   IPREASM_INDIDX_PTR   indir;

   /* free the direct blocks */
   for (i = 0; i < IPREASM_NB_DIRECT; i++) {
      if (!dgram->DIRECT[i]) continue;
      RTCS_part_free(dgram->DIRECT[i]);
   } /* Endfor */

   /* free the indirect blocks */
   for (i = 0; i < IPREASM_NB_IND; i++) {
      indir = dgram->INDIR[i];
      if (!indir) continue;
      for (j = 0; j < IPREASM_IND_SIZE; j++) {
         if (!indir->DIRECT[j]) continue;
         RTCS_part_free(indir->DIRECT[j]);
      } /* Endfor */
      RTCS_part_free(indir);
   } /* Endfor */

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPREASM_get_dgram
*  Returned Value : pointer the matching IP datagram
*  Comments       :
*     Find the IP datagram matching the given (ipsrc, ipdst, proto, id)
*     key.
*
*     If the structure isn't in the list, allocate one.
*
*END*-----------------------------------------------------------------*/
#if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4)
static IP_DGRAM_PTR IPREASM_get_dgram
   (
      _ip_address ipsrc,   /* [IN] the IP source */
      _ip_address ipdst,   /* [IN] the IP destination */
      uint_8      proto,   /* [IN] the IP protocol */
      uint_16     id       /* [IN] the IP ID */
   )
{ /* Body */
   register IP_DGRAM_PTR dgram;

   RTCS_DLIST_PEEK(IPREASM_head, dgram);
   if (dgram) {

      /* There's a good probability our IP_DGRAM is at the head of the list */
      if (dgram->family==AF_INET
       && ipsrc == dgram->header.IP4.IPSRC
       && ipdst == dgram->header.IP4.IPDST
       && proto == dgram->header.IP4.PROTO
       && id    == dgram->header.IP4.ID) {
         return dgram;
      } /* Endif */

      /* It's not at the head.  Scan the list for it */
      RTCS_DLIST_SEARCH_REST(IPREASM_head, dgram) {
         if (ipsrc == dgram->header.IP4.IPSRC
          && ipdst == dgram->header.IP4.IPDST
          && proto == dgram->header.IP4.PROTO
          && id    == dgram->header.IP4.ID) {
            /* Found it.  Move it to the head of the list */
            RTCS_DLIST_DEL(IPREASM_head, dgram);
            RTCS_DLIST_INS(IPREASM_head, dgram);
            return dgram;
         } /* Endif */
      } /* End SEARCH */

   } /* Endif */

   /* Not found.  Allocate one */
   dgram = RTCS_part_alloc_zero(IPREASM_part);
   if (!dgram) return NULL;

   /* Initialize it */
    dgram->family=AF_INET;
   dgram->header.IP4.IPSRC = ipsrc;
   dgram->header.IP4.IPDST = ipdst;
   dgram->header.IP4.PROTO = proto;
   dgram->header.IP4.ID    = id;
   dgram->TIMER.TIME  = IPREASM_TTL;
   dgram->TIMER.EVENT = IPREASM_expire;
   dgram->TIMER.PRIVATE = dgram;
   TCPIP_Event_add(&dgram->TIMER);

   /* Add it to the list*/
   RTCS_DLIST_INS(IPREASM_head, dgram);
   return dgram;

} /* Endbody */
#endif /* (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) */
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPREASM_del_dgram
*  Returned Value : void
*  Comments       :
*     Free an IP datagram.
*
*END*-----------------------------------------------------------------*/

void IPREASM_del_dgram
   (
      IP_DGRAM_PTR   dgram    /* [IN] the IP datagram */
   )
{ /* Body */

   /* Cancel the expire timer and free all memory */
   TCPIP_Event_cancel(&dgram->TIMER);
   RTCS_DLIST_DEL(IPREASM_head, dgram);
   IPREASM_blk_del_all(dgram);
   RTCS_part_free(dgram);

} /* Endbody */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPREASM_add_frag
*  Returned Value : void
*  Comments       :
*     Adds a received IP fragment to an IP datagram.
*
*END*-----------------------------------------------------------------*/
#if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4)
static void IPREASM_add_frag
   (
      IP_DGRAM_PTR   dgram,   /* [IN] the dgram */
      RTCSPCB_PTR    inpcb    /* [IN] the received PCB */
   )
{ /* Body */
   IP_HEADER_PTR     iph     = (IP_HEADER_PTR)RTCSPCB_DATA(inpcb);
   uint_32           iphlen  = (ntohc(iph->VERSLEN) & 0xF) << 2;
   uint_32           totlen  = ntohs(iph->LENGTH);
   int_32            offset  = ntohs(iph->FRAGMENT);
   int_32            first   = (offset & IP_FRAG_MASK) << IP_FRAG_SHIFT;
   uint_32           datalen = totlen - iphlen;
   uchar_ptr         data    = (uchar_ptr)iph + iphlen;
   IPREASM_BLK_PTR   blk;
   uint_32           len;

   if (offset & IP_FRAG_MF) {

      /* Fragments (except the last) must be multiples of 8 bytes */
      if ((datalen & 0x07) != 0) {
         return;
      } /* Endif */

   } else {
      /* If this fragment is the last one, record the total length */
      dgram->TOTLEN = first + datalen;

   } /* Endif */

   /* Once we get the first fragment, record the IP header and 8 data bytes */
   if (first == 0) {
      _mem_copy(iph, &dgram->header.IP4.IPH, iphlen + 8);
      dgram->TYPE    = inpcb->TYPE;
      dgram->IFSRC   = inpcb->IFSRC;
      dgram->LINKOPT = inpcb->LINK_OPTIONS.RX;
   } /* Endif */

   while (datalen) {
      blk = IPREASM_blk_get(dgram, first);
      if (!blk) {
         return;
      } /* Endif */

      len = IPREASM_blk_write(dgram, blk, first, data, datalen);
      first   += len;
      data    += len;
      datalen -= len;
   } /* Endwhile */

} /* Endbody */
#endif /* RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4 */
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IPREASM_reasm_dgram
*  Returned Value : RTCSPCB containing the completed datagram.
*  Comments       :
*     Reassemble a completed datagram.
*
*END*-----------------------------------------------------------------*/
#if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4)
static RTCSPCB_PTR IPREASM_reasm_dgram
   (
      IP_DGRAM_PTR   dgram    /* [IN] the dgram descriptor */
   )
{ /* Body */
   RTCSPCB_PTR outpcb;
   PCB_PTR     bpcb;
   PCB_FRAGMENT _PTR_ pcb_frag_ptr;
   uchar_ptr   data;
   uint_32     iphlen  = (ntohc(dgram->header.IP4.IPH.VERSLEN) & 0xF) << 2;
   uint_32     ip_totlen = iphlen + dgram->TOTLEN;

   bpcb = RTCS_mem_alloc_system(sizeof(PCB) + sizeof(PCB_FRAGMENT) + ip_totlen);
   if (!bpcb) {
      return NULL;
   } /* Endif */

   data = (uchar_ptr)bpcb + sizeof(PCB) + sizeof(PCB_FRAGMENT);
   bpcb->FREE    = (void(_CODE_PTR_)(PCB_PTR))_mem_free;
   bpcb->PRIVATE = NULL;
 
   pcb_frag_ptr = bpcb->FRAG;
   pcb_frag_ptr->LENGTH   = ip_totlen;
   pcb_frag_ptr->FRAGMENT = data;
   pcb_frag_ptr++;
   pcb_frag_ptr->LENGTH   = 0;
   pcb_frag_ptr->FRAGMENT = NULL;

   /* Copy the IP header with options */
   htons(dgram->header.IP4.IPH.FRAGMENT, 0);
   _mem_copy(&dgram->header.IP4.IPH, data, iphlen);
   data += iphlen;

   /*
   ** At this point, we really should update the LENGTH
   ** and CHECKSUM fields in the new IP header, but we
   ** don't actually need to, because this datagram is
   ** going straight to IPLOCAL_service, which doesn't
   ** check these things.
   */

   /* Copy the stored data in the new packet */
   IPREASM_blk_read_all(dgram, data, dgram->TOTLEN);

   /* Put it in an RTCSPCB */
   outpcb = RTCSPCB_alloc_recv(bpcb);
   if (outpcb == NULL) {
      PCB_free(bpcb);
      return NULL;
   } /* Endif */
   //RTCSLOG_PCB_ALLOC(bpcb);
   outpcb->IFSRC           = dgram->IFSRC;
   outpcb->TYPE            = dgram->TYPE;
   outpcb->LINK_OPTIONS.RX = dgram->LINKOPT;
   RTCSPCB_DATA_NETWORK(outpcb) = RTCSPCB_DATA(outpcb);
   RTCSPCB_SET_TRANS_PROTL(outpcb, dgram->header.IP4.PROTO);
   RTCSPCB_SET_TRANS_DELTA(outpcb, iphlen);

   /* Delete the local structure */
   IPREASM_del_dgram(dgram);

   return outpcb;

} /* Endbody */
#endif /* (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) */
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name   : IPREASM_expire
*  Returned Values : boolean
*  Comments        :
*     Called by the Timer.  Expire an IP datagram.
*
*END*-----------------------------------------------------------------*/
#if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4)
static boolean IPREASM_expire
   (
      TCPIP_EVENT_PTR   event    /* [IN/OUT] the expire event */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP);
   IP_DGRAM_PTR      dgram = event->PRIVATE;

   IF_IP_STATS_ENABLED(IP_cfg_ptr->STATS.ST_RX_FRAG_DISCARDED++);

#if RTCSCFG_ENABLE_ICMP
   /* Send a ICMP Time Exceeded */
   if (dgram->DIRECT[0]
    && dgram->DIRECT[0]->BUSYINT & 1
    && dgram->TYPE & RTCSPCB_TYPE_UNICAST) {
      ICMP_send_error_internal(ICMPTYPE_TIMEEXCEED, ICMPCODE_TE_REASM, 0, 
         &dgram->header.IP4.IPH, NULL, 0);
   } /* Endif */
#endif

   IPREASM_del_dgram(dgram);
   return FALSE;

} /* Endbody */
#endif /* (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) */
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_reasm
*  Returned Value : RTCS_OK or error code
*  Comments       :
*     Process an IP fragment.  If an error occurs, outpcb is
*     guaranteed to be NULL.
*
*  Warning:
*     It is assumed the PCB is not fragmented.  This is
*     true for all PCBs that come from the link layer.
*     Loopback PCBs generally are fragmented, but IP
*     doesn't FRAGMENT them, so they don't go through
*     this function.
*
*  Warning:
*     I just realized that the word 'fragment' is overloaded
*     in the warning above.  There are PCB fragments and IP
*     fragments.  I've rewritten the previous warning so that
*     PCB fragments are 'fragments' (lowercase) and IP fragments
*     are 'FRAGMENTS' (uppercase).
*
*END*-----------------------------------------------------------------*/
#if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4)
uint_32 IP_reasm
   (
      RTCSPCB_PTR       pcb,     /* [IN] the packet to deliver */
      RTCSPCB_PTR _PTR_ outpcb   /* [OUT] the reassembled packet or NULL */
   )
{ /* Body */
   IP_HEADER_PTR  iph    = (IP_HEADER_PTR)RTCSPCB_DATA(pcb);
   _ip_address    ipsrc  = ntohl(iph->SOURCE);
   _ip_address    ipdst  = ntohl(iph->DEST);
   uint_8         proto  = ntohc(iph->PROTOCOL);
   uint_16        id     = ntohs(iph->ID);
   IP_DGRAM_PTR   dgram;

   *outpcb = NULL;

   dgram = IPREASM_get_dgram(ipsrc, ipdst, proto, id);
   if (!dgram) {
      RTCSLOG_PCB_FREE(pcb, RTCSERR_OUT_OF_MEMORY);
      RTCSPCB_free(pcb);
      return RTCSERR_OUT_OF_MEMORY;
   } /* Endif */

   IPREASM_add_frag(dgram, pcb);

   /*
   ** We're done when:
   **    0 < TOTLEN = MAXLEN <= CURLEN
   **
   ** Note: we can get TOTLEN < CURLEN because CURLEN is
   ** always a multiple of eight, but TOTLEN may not be.
   */
   if (dgram->TOTLEN > 0
    && dgram->MAXLEN == dgram->TOTLEN
    && dgram->CURLEN >= dgram->MAXLEN) {
      *outpcb = IPREASM_reasm_dgram(dgram);
   } /* Endif */

   /* Free the old pcb */
   RTCSLOG_PCB_FREE(pcb, RTCS_OK);
   RTCSPCB_free(pcb);

   return RTCS_OK;
} /* Endbody */
#endif /* (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) */
#endif /* (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) || (RTCSCFG_ENABLE_IP6_REASSEMBLY && RTCSCFG_ENABLE_IP6) */
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ipc_udp_prv.h<|end_filename|>
#ifndef __ipc_udp_prv_h__
#define __ipc_udp_prv_h__ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipc_udp_prv.h$
* $Version : 3.8.2.0$
* $Date    : Oct-11-2011$
*
* Comments:
*
*   This file contains the private definitions for the 
*   inter-processor drivers that work over Ethernet/UDP.
*
*END************************************************************************/


/*--------------------------------------------------------------------------*/
/*
**                          CONSTANT DECLARATIONS
*/

#define IPC_UDP_POOL_INIT   16
#define IPC_UDP_POOL_GROW   16 
#define IPC_UDP_POOL_MAX    0

/*--------------------------------------------------------------------------*/
/*
**                          DATATYPE DECLARATIONS
*/


/*
** IPC_UDP_CONTEXT
** This structure contains protocol information for the IPC over Ethernet/UDP
**
*/
typedef struct ipc_udp_context 
{
   /* Pointer to the standard inter-processor initialization structure */
   const IPC_PROTOCOL_INIT_STRUCT *    IPC_INIT_PTR;

   /* Pointer to the structure that contains initialization information 
      for Ethernet/UDP based communication */
   IPC_UDP_INIT_PTR                INIT_PTR;

   /* Message pool ID */
   _pool_id                        POOL_ID;

   /* UDP socket */
   uint_32                         SOCKET;

   /* TaskID of the task that handles outcomming messages */
   _task_id                        OUT_TID;

   /* TaskID of the task that handles incomming messages */
   _task_id                        IN_TID;

   /* Socket Address Structure */
   sockaddr_in                     RADDR;
}  IPC_UDP_CONTEXT, * IPC_UDP_CONTEXT_PTR;

/*--------------------------------------------------------------------------*/
/*
**                          C PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern boolean IPC_UDP_Init_internal(IPC_UDP_CONTEXT_PTR context_ptr );
extern void IPC_UDP_In( uint_32 param );
extern void IPC_UDP_Out( uint_32 param );
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/mqx_ioc.h<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mqx_ioc.h$
* $Version : 3.5.11.0$
* $Date    : Jan-22-2010$
*
* Comments:
*
*   This include file is used to define constants and data types for the
*   support functions for MQX I/O Components.
*
*END************************************************************************/
#ifndef __mqx_ioc_h__
#define __mqx_ioc_h__ 1

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */


/*
 * The IO component indexes, used to index into the component
 * arrays to access component specific data
 */
#define IO_SUBSYSTEM_COMPONENT        (0)
#define IO_RTCS_COMPONENT             (1)
#define IO_SNMP_COMPONENT             (2)
#define IO_MFS_COMPONENT              (3)
#define IO_USB_COMPONENT              (4)
#define IO_SHELL_COMPONENT            (5)
#define IO_ENET_COMPONENT             (6)
#define IO_EDS_COMPONENT              (7)
//#define IO_LAPB_COMPONENT             (2)  // obsolete
//#define IO_LAPD_COMPONENT             (3)  // obsolete
//#define IO_SDLC_COMPONENT             (4)  // obsolete
//#define IO_HDLC_COMPONENT             (5)
//#define IO_MFS_COMPONENT              (6)
//#define IO_CAN_COMPONENT              (7)
//#define IO_PPP_COMPONENT              (8)
//#define IO_SNMP_COMPONENT             (9)
//#define IO_EDS_COMPONENT              (10)
//#define IO_USB_COMPONENT              (11)
//#define IO_SHELL_COMPONENT            (12)

/* The maximum number of IO components */
#define MAX_IO_COMPONENTS                  (8)

/*--------------------------------------------------------------------------*/
/*                        DATATYPE DECLARATIONS                             */


/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifndef __ASM__

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __TAD_COMPILE__
extern pointer _mqx_get_io_component_handle(_mqx_uint);
extern pointer _mqx_set_io_component_handle(_mqx_uint, pointer);
extern uint_32 _mqx_link_io_component_handle(_mqx_uint, pointer, pointer *);
extern uint_32 _mqx_unlink_io_component_handle(_mqx_uint, pointer, pointer *);
#endif

#ifdef __cplusplus
}
#endif

#endif /* __ASM__ */

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/ftpd.h<|end_filename|>
#ifndef __ftpd_h__
#define __ftpd_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ftpd.h$
* $Version : 3.8.18.0$
* $Date    : Aug-27-2012$
*
* Comments:
*
*   This file contains the FTP server.
*
*END************************************************************************/

#include <fio.h>

#define FTPD_DEVLEN              8
#define FTPD_PATHLEN             260

#define FTPD_LINELEN             128

#define FTPD_PASV_PORT_START     3000
#define FTPD_PASV_PORT_END       3020
#define FTPD_NEED_PASSWORD       1
#define FTPD_LOGGED_IN           2
#define FTPD_LOGGED_OUT          0
#define FTPD_MAX_LOGIN_ATTEMPTS  3

#define FTPD_MAX_USERLEN         32

#define FTPd_OK                  0
#define FTPd_ERROR               (-1)

#ifndef min
    #define min(a,b) ((a<b)?a:b)
#endif

//#define FTPd_send_msg(p,m) send(p->CONTROL_SOCK, m, strlen(m), 0) 
void FTPd_send_msg(pointer p,const char * m);

typedef struct ftpd_session_struct  {
   sockaddr_in    USER_DATA_SOCKADDR;
   sockaddr_in    SERVER_DATA_SOCKADDR;
   sockaddr_in    SERVER_PASV_SOCKADDR;
   boolean        CONNECTED;
   uint_32        CONTROL_SOCK;
   _ip_address    LOCAL_ADDR;
   uint_32        DATA_SOCK;
   uint_32        PASV_SOCK;
   boolean        PASV_MODE;
#if FTPDCFG_ENABLE_USERNAME_AND_PASSWORD
   uint_32        LOGIN_STATE;
   uint_32        LOGIN_ATTEMPTS;
   char           USERNAME[FTPD_MAX_USERLEN];
   char           PASSWORD[FTPD_MAX_USERLEN];
#endif
   char           CURRENT_FS_DIR[FTPD_PATHLEN];
   char_ptr       CURRENT_FTP_DIR;
   char           CURRENT_FS_NAME[FTPD_DEVLEN];
   MQX_FILE_PTR   CURRENT_FS;               
   char           CMD_LINE[FTPD_LINELEN];    // TODO : Don't need both CMD_LINE and CMD_BUFFER
   char           CMD_BUFFER[FTPD_LINELEN];
   char_ptr       DATA_BUFFER_PTR;
   uint_32        DATA_BUFFER_SIZE;
#ifdef FTPDCFG_ENABLE_RENAME
   char_ptr       RENAME_FROM;
   MQX_FILE_PTR   RENAME_FS;
#endif
   
} FTPd_SESSION_STRUCT, _PTR_ FTPd_SESSION_PTR;


typedef struct FTPd_command_struct  {
   char_ptr  COMMAND;
   int_32      (*FTPd_FUNC)(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr);
} FTPd_COMMAND_STRUCT, _PTR_ FTPd_COMMAND_PTR; 


extern char FTPd_rootdir[];
extern const FTPd_COMMAND_STRUCT FTPd_commands[];
extern char_ptr FTPd_userfile;
extern uint_32 FTPd_window_size;
extern uint_32 FTPd_buffer_size;


extern uint_32 FTPd_init
   (
      char_ptr name,
      uint_32  priority,
      uint_32  stacksize
   );


extern void FTPd_task(pointer, pointer);
extern uint_32 FTPd_stop( void );
extern uint_32 FTPd_open_active_data_connection(FTPd_SESSION_PTR);
extern uint_32 FTPd_open_passive_data_connection(FTPd_SESSION_PTR);

int_32  FTPd_cd(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_cdup(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_dele(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_feat(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_help(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_list(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_mkdir(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_nlst(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_noop(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_opts(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_pass(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_pasv(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_port(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_pwd(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_quit(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_rmdir(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_retr(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_rnfr(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_rnto(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_site(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_size(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_stor(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_syst(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_type(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );
int_32  FTPd_user(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );

int_32  FTPd_unimplemented(FTPd_SESSION_PTR session_ptr, char_ptr cmd_ptr, char_ptr arg_ptr );

#ifndef min
    #define min(a,b) ((a<b)?a:b)
#endif


#endif

/* EOF*/


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/can/flexcan/flexcan.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: flexcan.c$
* $Version : 3.8.25.0$
* $Date    : Jun-6-2012$
*
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <flexcan.h>

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Start  
* Returned Value   : uint_32 
* Comments         :
*    This function starts the specified FlexCAN device
*
*END*********************************************************************/
uint_32 FLEXCAN_Start
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  /* Starting FLEXCAN in normal mode */
  can_reg_ptr->CANMCR &= ~(FLEXCAN_CANMCR_HALT | FLEXCAN_CANMCR_MDIS
                           | FLEXCAN_CANMCR_FRZ);

  /* wait for synchronization */
  while (can_reg_ptr->CANMCR & FLEXCAN_CANMCR_FRZACK)
  {}

  return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Softreset
* Returned Value   : uint_32 
* Comments         :
*    This function resets the specific CAN device
*
*END*********************************************************************/
uint_32 FLEXCAN_Softreset
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num
 )
{ /* Body */

  volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  /* check for low power mode */
  if ( can_reg_ptr->CANMCR & FLEXCAN_CANMCR_LPMACK )
  {
    /* Enable clock */
    can_reg_ptr->CANMCR &= (~FLEXCAN_CANMCR_MDIS);
    /* wait until enabled */
    while (can_reg_ptr->CANMCR & FLEXCAN_CANMCR_LPMACK)
    {}
  }

  /* Reset the FLEXCAN */
  can_reg_ptr->CANMCR = FLEXCAN_CANMCR_SOFTRST;

  /* Wait for reset cycle to complete */
  while (can_reg_ptr->CANMCR & FLEXCAN_CANMCR_SOFTRST)
  {}

  /* Set Freeze, Halt */
  can_reg_ptr->CANMCR |= (FLEXCAN_CANMCR_FRZ | FLEXCAN_CANMCR_HALT);

  /* check for freeze Ack */
  if (
       ((can_reg_ptr->CANMCR & FLEXCAN_CANMCR_FRZACK) != FLEXCAN_CANMCR_FRZACK) ||
       ((can_reg_ptr->CANMCR & FLEXCAN_CANMCR_NOTRDY) != FLEXCAN_CANMCR_NOTRDY)
       ) return (FLEXCAN_SOFTRESET_FAILED);

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Get_msg_object  
* Returned Value   : pointer 
* Comments         :
*    This function returns a pointer to the mailbox object specified
*    by the mailbox number.
*
*END*********************************************************************/
pointer FLEXCAN_Get_msg_object
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number
 )
{ /* Body */

  volatile uchar_ptr temp_ptr;
  volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (NULL);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (NULL);
  }

  temp_ptr = (uchar_ptr)can_reg_ptr;
  temp_ptr += FLEXCAN_MSG_BUFADDR_OFFSET;


  /*
  ** Calculate what message object to point to
  */
  temp_ptr += sizeof(FLEXCAN_MSG_OBJECT_STRUCT) * mailbox_number;

  return ((pointer)temp_ptr);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Select_mode  
* Returned Value   : uint_32 
* Comments         :
*    This function sets FlexCAN module operation mode
*
*END*********************************************************************/
uint_32 FLEXCAN_Select_mode
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] operation Mode */
 uint_32 mode
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR can_reg_ptr;
  volatile uint_32                ret_code = FLEXCAN_OK;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  switch (mode)
  {
  case (FLEXCAN_NORMAL_MODE):
    /* 
    ** Normal mode, check freeze ACK bit
    ** call start if bit is set 
    */
    if ( (can_reg_ptr->CANMCR & FLEXCAN_CANMCR_FRZACK) == FLEXCAN_CANMCR_FRZACK )
    {
      if ( FLEXCAN_Start(dev_num) ) ret_code = FLEXCAN_START_FAILED;
    }
    break;
  case (FLEXCAN_LISTEN_MODE):
    /* Set CANCTRL[LOM], listen-only mode */
    can_reg_ptr->CANCTRL |= FLEXCAN_CANCTRL_LOM;
    break;
  case (FLEXCAN_TIMESYNC_MODE):
    /* Timer Synchronization mode (Global Network Time) */
    can_reg_ptr->CANCTRL |= FLEXCAN_CANCTRL_TSYNC;
    break;
  case (FLEXCAN_LOOPBK_MODE):
    /* Self test mode, Loop Back */
    can_reg_ptr->CANCTRL |= FLEXCAN_CANCTRL_LPB;
    break;
  case (FLEXCAN_BOFFREC_MODE):
    /* Bus Off Recovery mode (according to CAN 2.0b) */
    can_reg_ptr->CANCTRL &= ~(FLEXCAN_CANCTRL_BOFFREC);
    break;
  case (FLEXCAN_FREEZE_MODE):
    /* Debug mode, Halt and Freeze */
    can_reg_ptr->CANMCR |= (FLEXCAN_CANMCR_FRZ | FLEXCAN_CANMCR_HALT);
    /* check for freeze Ack */
    if ( (can_reg_ptr->CANMCR & FLEXCAN_CANMCR_FRZACK) != FLEXCAN_CANMCR_FRZACK ) ret_code = FLEXCAN_FREEZE_FAILED;
    break;
  case (FLEXCAN_DISABLE_MODE):
    /* Debug mode, Halt and Freeze */
    can_reg_ptr->CANMCR |= FLEXCAN_CANMCR_MDIS;
    break;
  default:
    ret_code = FLEXCAN_INVALID_MODE;
  }

  return (ret_code);
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Select_CLK  
* Returned Value   : uint_32 
* Comments         :
*    This function sets FlexCAN module operation mode
*
*END*********************************************************************/
uint_32 FLEXCAN_Select_clk
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] FlexCAN clock source */
 uint_32 clk
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( clk == FLEXCAN_IPBUS_CLK )
    /* CANPE Clock */
    can_reg_ptr->CANCTRL |= FLEXCAN_CANCTRL_CLK_SRC;

  else if ( clk == FLEXCAN_OSC_CLK )
    /* External clock */
    can_reg_ptr->CANCTRL &= (~FLEXCAN_CANCTRL_CLK_SRC);

  else return (FLEXCAN_CLOCK_SOURCE_INVALID);


  return (FLEXCAN_OK);
} /* Endbody */


/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Initialize  
* Returned Value   : uint_32 
* Comments         :
*    This function initializes all mailbox-independent registers of the 
*    FLEXCAN chip.
*    NOTE:
*         TimeSeg1 = PROP_SEG + PHASE_SEG1
*         TimeSeg2 = PHASE_SEG2
*       Ex. PHASE_SEG1 = 0xF and PROP_SEG = 0x7 => bit_timing0 = 0x000F0007
*
*END*********************************************************************/
uint_32 FLEXCAN_Initialize
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] MS 16 bits = TimeSeg1, LS 16 bits = TimeSeg2 */
 uint_32 bit_timing0,
 /* [IN] MS 16 bits = pre-scaler value, LS 16 bits = SJW */
 uint_32 bit_timing1,
 /* [IN] Bit rate in Kbps */
 uint_32 frequency,
 /* [IN] clock frequency (needs to match either FLEXCAN_IPBUS_CLK or FLEXCAN_OSC_CLK */
 uint_32 clk
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR can_bufstruct_ptr;
  volatile uchar_ptr                     temp_ptr;
  vuint_32                               PSEG1 = 0;
  vuint_32                               PSEG2 = 0;
  vuint_32                               PROPSEG = 0;
  vuint_32                               RJW = 0;
  vuint_32                               PRESDIV = 0;
  uint_32                                i;
  uint_32                                result;

#if PSP_HAS_DEVICE_PROTECTION
  if ( !_bsp_flexcan_enable_access(dev_num) )
  {
    return FLEXCAN_INVALID_DEVICE;
  }
#endif

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  temp_ptr = (uchar_ptr)can_reg_ptr;
  temp_ptr += FLEXCAN_MSG_BUFADDR_OFFSET;

  can_bufstruct_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)temp_ptr;

  /* 
  ** To access the memory mapped registers 
  ** Enter disable mode (hard reset).
  */
  if ( (can_reg_ptr->CANMCR & FLEXCAN_CANMCR_MDIS) == 0x00000000 )
  {
    /* clock disable (module) */
    can_reg_ptr->CANMCR = FLEXCAN_CANMCR_MDIS;

    /* wait until disable mode acknowledged */
    while (!can_reg_ptr->CANMCR & FLEXCAN_CANMCR_LPMACK)
    {}
  }

  /* Reset FLEXCAN, Halt, freeze mode */
  result = FLEXCAN_Softreset(dev_num);
  if ( FLEXCAN_OK != result )
  {
    return (result);
  }

  /* 
  ** Select the clock source 
  ** Default: internal bus clock (fsys/2).
  */
  result = FLEXCAN_Select_clk(dev_num, clk);
  if ( FLEXCAN_OK != result )
  {
    return (result);
  }

  frequency *= 1000;

  /* bit timing settings */
  if ( (bit_timing0 == 0x00) && (bit_timing1 == 0x00) )
  {
    // If BSP_CANPE_CLOCK is defined, then we will calculate the CAN bit timing parameters
    // using the method outlined in AN1798, section 4.1. A maximum time for PROP_SEG will be used,
    // the remaining TQ will be split equally between PSEG1 and PSEG2, provided PSEG2 >=2. RJW is
    // set to the minimum of 4 or PSEG1.

    uint_32 TQ_x_Prescaler = clk / frequency;
    uint_32 TQ, lowest_diff, diff, best_TQ, actual_freq;

    if ( TQ_x_Prescaler < (CAN_MIN_TQ - 1) )
    {
      // We will be off by more than 12.5%
      return FLEXCAN_INVALID_FREQUENCY;
    }

    // First, find the best TQ and pre-scaler to use for the desired frequency. If any exact matches
    // is found, we use the match that gives us the lowest pre-scaler and highest TQ, otherwise we pick
    // the TQ and prescaler that generates the closest frequency to the desired frequency.

    lowest_diff = frequency;
    best_TQ = 0;
    for (TQ = CAN_MAX_TQ; TQ >= CAN_MIN_TQ; TQ--)
    {
      PRESDIV = TQ_x_Prescaler / TQ;
      if ( PRESDIV <= 256 )
      {
        if ( TQ_x_Prescaler == TQ * PRESDIV )
        {
          best_TQ = TQ;
          break;
        }
        actual_freq = (clk / PRESDIV) / TQ;
        diff = (actual_freq > frequency) ? actual_freq - frequency : frequency - actual_freq;
        if ( diff < lowest_diff )
        {
          lowest_diff = diff;
          best_TQ = TQ;
        }
      }
    }
    if ( (best_TQ >= CAN_MIN_TQ) && (PRESDIV <= 256) )
    {
      PSEG2 = (best_TQ - CAN_MAX_PROPSEG) / 2;
      if ( PSEG2 < CAN_MIN_PSEG2 ) PSEG2 = CAN_MIN_PSEG2;
      PSEG1 = (best_TQ == CAN_MIN_TQ) ? 1 : PSEG2;
      PROPSEG = best_TQ - PSEG1 - PSEG2 - 1;
      RJW = (PSEG1 < CAN_MAX_RJW) ? PSEG1 : CAN_MAX_RJW;

      can_reg_ptr->CANCTRL &= (~(FLEXCAN_CANCTRL_SAMP | FLEXCAN_CANCTRL_PROPSEG(0xFFFFFFFF) | FLEXCAN_CANCTRL_RJW(0xFFFFFFFF) | FLEXCAN_CANCTRL_PSEG1(0xFFFFFFFF) | FLEXCAN_CANCTRL_PSEG2(0xFFFFFFFF) | FLEXCAN_CANCTRL_PRESDIV(0xFFFFFFFF)));
      can_reg_ptr->CANCTRL |= (0 | FLEXCAN_CANCTRL_PROPSEG(PROPSEG - 1) | FLEXCAN_CANCTRL_RJW(RJW - 1) | FLEXCAN_CANCTRL_PSEG1(PSEG1 - 1) | FLEXCAN_CANCTRL_PSEG2(PSEG2 - 1) | FLEXCAN_CANCTRL_PRESDIV(PRESDIV - 1));
    }
    else
    {
      return FLEXCAN_INVALID_FREQUENCY;
    }
  }
  else
  {
    PSEG1 = (bit_timing0 & 0x00070000) >> 16;
    PROPSEG = bit_timing0 & 0x7;
    PSEG2 = (bit_timing1 & 0x00070000) >> 16;
    RJW = (bit_timing1 & 0x00000300) >> 8;
    PRESDIV = bit_timing1 & 0x000000FF;

    can_reg_ptr->CANCTRL &= (~(FLEXCAN_CANCTRL_SAMP | FLEXCAN_CANCTRL_PROPSEG(0xFFFFFFFF) | FLEXCAN_CANCTRL_RJW(0xFFFFFFFF)| FLEXCAN_CANCTRL_PSEG1(0xFFFFFFFF) | FLEXCAN_CANCTRL_PSEG2(0xFFFFFFFF)| FLEXCAN_CANCTRL_PRESDIV(0xFFFFFFFF)));
    can_reg_ptr->CANCTRL |= (0 | FLEXCAN_CANCTRL_PROPSEG(PROPSEG) | FLEXCAN_CANCTRL_RJW(RJW)| FLEXCAN_CANCTRL_PSEG1(PSEG1) | FLEXCAN_CANCTRL_PSEG2(PSEG2)| FLEXCAN_CANCTRL_PRESDIV(PRESDIV));
  }

  /* Set maximum number of message buffers */
  can_reg_ptr->CANMCR |= FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF);

  /* Rx global mask */
  can_reg_ptr->RXGMASK   = FLEXCAN_EXTENDED_ID_MASK(0xFFFFFFFF);

  /* Rx reg 14 mask */
  can_reg_ptr->RX14MASK  = FLEXCAN_EXTENDED_ID_MASK(0xFFFFFFFF);

  /* Rx reg 15 mask */
  can_reg_ptr->RX15MASK  = FLEXCAN_EXTENDED_ID_MASK(0xFFFFFFFF);

  /* 
  * Initialize all message buffers as inactive 
  */
  for (i = 0; i <= FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF); i++)
  {
    can_bufstruct_ptr[i].CONTROL  = 0x00000000;
  }

  return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Initialize_mailbox  
* Returned Value   : uint_32 
* Comments         :
*    This function initializes the specified FlexCAN mailbox (Message Buffer)
*
*END*********************************************************************/
uint_32 FLEXCAN_Initialize_mailbox
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number,
 /* [IN] message ID */
 uint_32 identifier,
 /* [IN] number of bytes to write to the mailbox (0 to 8) */
 uint_32 data_len_code,
 /* [IN] transmission or reception direction (CAN_TX or CAN_RX) */
 uint_32 direction,
 /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
 uint_32 format,
 /* [IN] enable/disable interrupt for the mailbox */
 uint_32 int_enable
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR msg_obj_ptr;
  vuint_32                               temp_msg_config;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( (mailbox_number > FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  if ( 8 < data_len_code )
  {
    return (FLEXCAN_DATA_SIZE_ERROR);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);
  /*
  ** TX = 0x80: MB is not ready for transmit (code=0b1000)
  ** RX = 0x00: MB is not active (code=0b0000)
  ** Set code depending on direction and set the number of data bytes to be stored 
  */
  if ( direction == FLEXCAN_TX )
  {
    temp_msg_config = FLEXCAN_TX_MSG_BUFFER_NOT_ACTIVE;
  }
  else if ( direction == FLEXCAN_RX )
  {
    temp_msg_config = FLEXCAN_RX_MSG_BUFFER_NOT_ACTIVE;
  }
  else
  {
    return (FLEXCAN_INVALID_DIRECTION);
  } /* Endif */

  /* Set transmit length to data length in bytes */
  temp_msg_config |= (data_len_code << 16);
  msg_obj_ptr->CONTROL = temp_msg_config;

  /* Set the ID according the format structure */
  if ( format == FLEXCAN_EXTENDED )
  {
    /* Set IDE */
    msg_obj_ptr->CONTROL |= FLEXCAN_MSGCTRL_IDE;

    /* Set SRR bit for Tx buffers */
    if ( direction == FLEXCAN_TX ) msg_obj_ptr->CONTROL |= FLEXCAN_MSGCTRL_SRR;

    /* Start CR# 1730 */
    msg_obj_ptr->ID = FLEXCAN_EXTENDED_ID_MASK(identifier);
  }
  else if ( format == FLEXCAN_STANDARD )
  {
    /* make sure IDE and SRR are not set */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCTRL_IDE | FLEXCAN_MSGCTRL_SRR);

    /* ID[28-18] */
    msg_obj_ptr->ID = FLEXCAN_STANDARD_ID_MASK(identifier);
  }
  else return (FLEXCAN_MESSAGE_FORMAT_UNKNOWN);
  /* Endif */

  /* Enable CAN interrupt */
  if ( int_enable == FLEXCAN_ENABLE )
  {
    /* Enable interrupt line */
    if ( FLEXCAN_Int_enable(dev_num, mailbox_number) ) return (FLEXCAN_INT_ENABLE_FAILED);
  }
  else
  {
    /* Disable interrupt line */
    if ( FLEXCAN_Int_disable(dev_num, mailbox_number) ) return (FLEXCAN_INT_DISABLE_FAILED);
  }

  return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Request_mailbox 
* Returned Value   : uint_32 
* Comments         :
*    This function sets the RTR bit (reomte frame) for the 
*    specified mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Request_mailbox
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number,
 /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
 uint_32 format
 )
{ /* Body */
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR msg_obj_ptr;
  volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(
                                                                      dev_num, mailbox_number);
  /* Set RTR */
  msg_obj_ptr->CONTROL |= FLEXCAN_MSGCTRL_RTR;

  return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Activate_mailbox  
* Returned Value   : uint_32 
* Comments         :
*    This function activates the specified mailbox with the activation code
*    provided.
*
*END*********************************************************************/
uint_32 FLEXCAN_Activate_mailbox
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number,
 /* [IN] Code value for CONTROL/STATUS field */
 uint_32 code_val
 )
{ /* Body */
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;
  volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num,
                                                                      mailbox_number);
  /* Reset the code */
  msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

  /* Activating mailbox */
  msg_obj_ptr->CONTROL |= code_val;

  /* // Unlock the mailbox ... ???
  can_reg_ptr = (FLEXCAN_REG_STRUCT_PTR)can_ptr;
  code_val = can_reg_ptr->TIMER;
  */

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Lock_mailbox  
* Returned Value   : uint_32 
* Comments         :
*    This function locks the specified mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Lock_mailbox
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;
  vuint_32 temp;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);

  /* Lock the mailbox */
  temp = msg_obj_ptr->CONTROL;

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_unlock_mailbox  
* Returned Value   : uint_32 
* Comments         :
*    This function unlocks flexcan mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Unlock_mailbox
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  vuint_32                                 temp;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  /* Unlock the mailbox */
  temp = can_reg_ptr->TIMER;

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Set_global_extmask  
* Returned Value   : uint_32 
* Comments         :
*    This function sets the FLEXCAN chip global extended mask.
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_global_extmask
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] Mask */
 uint_32 extmask
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR  can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  /* MID[28-0] */
  can_reg_ptr->RXGMASK = FLEXCAN_EXTENDED_ID_MASK(extmask);

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Set_Buf14_extmask  
* Returned Value   : uint_32 
* Comments         :
*    This function sets the FlexCAN buf14 extended mask. 
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_buf14_extmask
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] Mask */
 uint_32 extmask
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR  can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  /* MID[28-0] */
  can_reg_ptr->RX14MASK = FLEXCAN_EXTENDED_ID_MASK(extmask);

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Set_Buf15_extmask  
* Returned Value   : uint_32 
* Comments         :
*    This function sets the FlexCAN buf15 extended mask. 
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_buf15_extmask
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] Mask */
 uint_32 extmask
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR  can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  /* MID[28-0] */
  can_reg_ptr->RX15MASK = FLEXCAN_EXTENDED_ID_MASK(extmask);

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Set_global_stdmask  
* Returned Value   : uint_32 
* Comments         :
*    This function sets the CAN chip global standard mask.
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_global_stdmask
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] Mask */
 uint_32 stdmask
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR  can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  /* 11 bit standard mask */
  can_reg_ptr->RXGMASK = FLEXCAN_STANDARD_ID_MASK(stdmask);

  return (FLEXCAN_OK);

} /* Endbody */
/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Set_Buf14_stdmask  
* Returned Value   : uint_32 
* Comments         :
*    This function sets the FlexCAN buf14 standard mask. 
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_buf14_stdmask
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] Mask */
 uint_32 stdmask
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR  can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  can_reg_ptr->RX14MASK = FLEXCAN_STANDARD_ID_MASK(stdmask);

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Set_Buf15_stdmask  
* Returned Value   : uint_32 
* Comments         :
*    This function sets the FlexCAN buf15 standard mask. 
*
*END*********************************************************************/
uint_32 FLEXCAN_Set_buf15_stdmask
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] Mask */
 uint_32 stdmask
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR  can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  can_reg_ptr->RX15MASK = FLEXCAN_STANDARD_ID_MASK(stdmask);

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Tx_successful  
* Returned Value   : boolean 
* Comments         :
*    This function returns TRUE or FALSE depending on whether or not 
*    the message has been placed in the mailbox. 
*
*END*********************************************************************/
boolean FLEXCAN_Tx_successful
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num
 )
{  /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR  can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  return ((can_reg_ptr->IFLAG & FLEXCAN_IMASK_VALUE) != 0);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Tx_mailbox  
* Returned Value   : uint_32 
* Comments         :
*    This function writes a message to the specified mailbox and sends once
*
*END*********************************************************************/
uint_32 FLEXCAN_Tx_mailbox
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number,
 /* [IN] Data to be written to the mailbox */
 pointer data
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;
  volatile uchar_ptr                       data_array;
  uint_32                                  i;
  vuint_32                                 data_length;
  vuint_32                                 temp;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);

  /* Locking mailbox */
  msg_obj_ptr->CONTROL |= FLEXCAN_TX_MSG_BUFFER_NOT_ACTIVE;

  data_length = ((msg_obj_ptr->CONTROL) & FLEXCAN_MSG_CTRL_DLEN);

  /* Copy user's buffer into mailbox data area */
  data_array = (uchar_ptr)data;
  for (i = 0; i < FLEXCAN_MSG_BUFF_MAXDATA_SIZE; i++)
  {
    msg_obj_ptr->DATA[i] = data_array[i];
  } /* Endfor */

  /* transmit data in message buffer */
  msg_obj_ptr->CONTROL |= (FLEXCAN_MESSAGE_TRANSMIT_ONCE | data_length);

  /* Unlock message buffer */
  temp = can_reg_ptr->TIMER;

  return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Rx_mailbox  
* Returned Value   : uint_32 
* Comments         :
*    This function reads a message from the specified mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Rx_mailbox
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32  mailbox_number,
 /* [IN] Location to store the data from the mailbox */
 pointer  data
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;
  uchar_ptr  data_array;
  uint_32  i;
  uint_32  return_code = FLEXCAN_OK;
  vuint_32 data_length;
  vuint_32 DLC;
  vuint_32 temp;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);

  data_array = (uchar_ptr)data;

  /* Lock */
  temp = msg_obj_ptr->CONTROL;

  /* Data length */
  data_length = (temp & FLEXCAN_MSG_CTRL_DLEN);
  DLC = data_length >> 16;

  /* Check for mailbox activation code */
  if ( (temp & FLEXCAN_MSGCRTL_CODE) == FLEXCAN_RX_MSG_BUFFER_EMPTY )
  {
    /* No data return */
    return_code = FLEXCAN_NO_MESSAGE;
  }

  if ( (temp & FLEXCAN_MSGCRTL_CODE) == FLEXCAN_RX_MSG_BUFFER_NOT_ACTIVE )
  {
    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* mailbox is not active, return */
    msg_obj_ptr->CONTROL |= FLEXCAN_RX_MSG_BUFFER_EMPTY | data_length;

    return_code = FLEXCAN_NO_MESSAGE;
  }
  /*
  ** Copy data to user buffer
  */
  if ( (temp & FLEXCAN_MSGCRTL_CODE) == FLEXCAN_RX_MSG_BUFFER_BUSY )
  {
    // Wait for copying data
    while (msg_obj_ptr->CONTROL & FLEXCAN_RX_MSG_BUFFER_BUSY)
    {}

    // Copying data
    for (i = 0; i < DLC; i++)
    {
      data_array[i] = msg_obj_ptr->DATA[i];
      msg_obj_ptr->DATA[i] = 0;
    } /* Endfor */

    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* Set the code */
    msg_obj_ptr->CONTROL |= FLEXCAN_RX_MSG_BUFFER_EMPTY | data_length;

    return_code = FLEXCAN_MESSAGE_BUSY;
  }
  else if ( (temp & FLEXCAN_MSGCRTL_CODE) == FLEXCAN_RX_MSG_BUFFER_FULL )
  {
    // Copying data
    for (i = 0; i < DLC; i++)
    {
      data_array[i] = msg_obj_ptr->DATA[i];
      msg_obj_ptr->DATA[i] = 0;
    } /* Endfor */

    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* Set the code */
    msg_obj_ptr->CONTROL |= FLEXCAN_RX_MSG_BUFFER_EMPTY | data_length;

    return_code = FLEXCAN_OK;

  }
  else if ( (temp & FLEXCAN_MSGCRTL_CODE) == FLEXCAN_RX_MSG_BUFFER_OVERRUN )
  {
    // Copying data
    for (i = 0; i < DLC; i++)
    {
      data_array[i] = msg_obj_ptr->DATA[i];
      msg_obj_ptr->DATA[i] = 0;
    } /* Endfor */

    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* Set the code */
    msg_obj_ptr->CONTROL |= FLEXCAN_RX_MSG_BUFFER_EMPTY | data_length;

    return_code = FLEXCAN_MESSAGE_LOST;
  }

  /* Unlock message buffer */
  temp = can_reg_ptr->TIMER;

  return return_code;

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Disable_mailbox  
* Returned Value   : uint_32 
* Comments         :
*    This function disables the specified mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Disable_mailbox
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number
 )
{ /* Body */

  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);

  msg_obj_ptr->CONTROL &= FLEXCAN_MSG_DISABLE;

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Request_message  
* Returned Value   : uint_32 
* Comments         :
*    This function requests remote messages as specified by the
*    mailbox number and format parameters. Sets the message buffer's code 
*
*END*********************************************************************/
uint_32 FLEXCAN_Request_message
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number,
 /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
 uint_32 format
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;
  uint_32                                  error_code;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);

  /* Set message format to remote */
  error_code = FLEXCAN_Request_mailbox(dev_num, mailbox_number, format);
  if ( error_code != FLEXCAN_OK )
  {
    return (error_code);
  }

  /* 
  ** Activate mailbox: code 0b1100 
  ** Data field length and data in remote message is ignored.
  ** Mailbox becomes receive mailbox.
  */
  error_code = FLEXCAN_Activate_mailbox(dev_num, mailbox_number, FLEXCAN_MESSAGE_TRANSMIT_REMOTE);
  if ( error_code != FLEXCAN_OK )
  {
    return (error_code);
  }

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Rx_message  
* Returned Value   : uint_32 
* Comments         :
*    This function receives a message from the specified masked mailbox .
*   
*
*END*********************************************************************/
uint_32 FLEXCAN_Rx_message
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32     mailbox_number,
 /* [IN/OUT] message ID */
 uint_32_ptr identifier,
 /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
 uint_32     format,
 /* [IN/OUT] number of bytes to write to the mailbox (0 to 8) */
 uint_32_ptr data_len_code,
 /* [IN/OUT] Location to store the data from the mailbox */
 pointer     data,
 /* [IN] enable/disable interrupt for the mailbox */
 uint_32     int_enable
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;

  vuint_32                code;
  uint_32                 i;
  uint_32                 return_code = FLEXCAN_OK;
  vuint_32                temp;
  vuint_32                DLC;
  vuint_32                ID;
  vuint_32                dlen;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);

  /* store data len */
  dlen = msg_obj_ptr->CONTROL & FLEXCAN_MSG_CTRL_DLEN;
  DLC = dlen >> 16;

  /* Reassemble the message ID */
  switch (format)
  {
  case (FLEXCAN_EXTENDED):
    /* Start CR# 1730 */
    ID = (msg_obj_ptr->ID & 0x1FFFFFFF);
    break;
  case (FLEXCAN_STANDARD):
    /* ID[28-18] */
    ID = ((msg_obj_ptr->ID & 0x1FFC0000) >> 18);
    break;
  default:
    return (FLEXCAN_MESSAGE_FORMAT_UNKNOWN);
  } /* Endswitch */

  /*
  ** if "code" value for specified Rx message buffer is full
  ** copy data to the buffer and set the code to empty and return. 
  ** if "code" value is set to not active, set the code to empty and
  ** return message buffer empty.
  ** if "code" value is set to overrun, copy data to the buffer and
  ** set the code to empty then return overrun.
  ** if "code" value is set to busy, copy data to the buffer and
  ** set the code to empty then return busy.
  */
  code = msg_obj_ptr->CONTROL & FLEXCAN_MSGCRTL_CODE;
  if ( code == FLEXCAN_RX_MSG_BUFFER_EMPTY )
  {
    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* Set the code */
    msg_obj_ptr->CONTROL |= (FLEXCAN_RX_MSG_BUFFER_EMPTY | dlen);

    /* No data return */
    return_code = FLEXCAN_NO_MESSAGE;
  }

  if ( code == FLEXCAN_RX_MSG_BUFFER_NOT_ACTIVE )
  {
    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* Set the code */
    msg_obj_ptr->CONTROL |= (FLEXCAN_RX_MSG_BUFFER_EMPTY | dlen);

    /* No data return */
    return_code = FLEXCAN_NO_MESSAGE;
  }

  if ( code == FLEXCAN_RX_MSG_BUFFER_FULL )
  {
    for (i = 0; i < DLC; i++)
    {
      ((uchar_ptr)data)[i] = msg_obj_ptr->DATA[i];
      msg_obj_ptr->DATA[i] = 0;
    } /* Endfor */

    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* Set the code */
    msg_obj_ptr->CONTROL |= (FLEXCAN_RX_MSG_BUFFER_EMPTY | dlen);
    return_code = FLEXCAN_OK;
  }
  else if ( code == FLEXCAN_RX_MSG_BUFFER_OVERRUN )
  {
    for (i = 0; i < DLC; i++)
    {
      ((uchar_ptr)data)[i] = msg_obj_ptr->DATA[i];
      msg_obj_ptr->DATA[i] = 0;
    } /* Endfor */

    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* Set the code */
    msg_obj_ptr->CONTROL |= (FLEXCAN_RX_MSG_BUFFER_EMPTY | dlen);
    return_code = FLEXCAN_MESSAGE_OVERWRITTEN;
  }
  else if ( code == FLEXCAN_RX_MSG_BUFFER_BUSY )
  {
    for (i = 0; i < DLC; i++)
    {
      ((uchar_ptr)data)[i] = msg_obj_ptr->DATA[i];
      msg_obj_ptr->DATA[i] = 0;
    } /* Endfor */
    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* Set the code */
    msg_obj_ptr->CONTROL |= (FLEXCAN_RX_MSG_BUFFER_EMPTY | dlen);
    return_code =  FLEXCAN_MESSAGE_OVERWRITTEN;
  } /* Endif */

  /* Unlock message buffer. only in polling mode */
  if ( int_enable == FLEXCAN_DISABLE )
  {
    temp = can_reg_ptr->TIMER;
  }

  /* Store data length */
  *data_len_code = DLC;

  /* Store identifier */
  *identifier = ID;

  return return_code;
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Tx_message  
* Returned Value   : uint_32 
* Comments         :
*    This function sends a message from the specified mailbox 
*
*END*********************************************************************/
uint_32 FLEXCAN_Tx_message
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] mailbox number */
 uint_32 mailbox_number,
 /* [IN] message ID */
 uint_32 identifier,
 /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
 uint_32 format,
 /* [IN] number of bytes to write to the mailbox (0 to 8) */
 uint_32 data_len_code,
 /* [IN] Location to store the data from the mailbox */
 pointer data
 )
{ /* Body */

  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;
  uint_32                 i;
  vuint_32                temp16;
  vuint_32                code;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  if ( 8 < data_len_code )
  {
    return (FLEXCAN_DATA_SIZE_ERROR);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);

  /* Set the ID according the format structure */
  if ( format == FLEXCAN_EXTENDED )
  {
    /* Set IDE */
    msg_obj_ptr->CONTROL |= FLEXCAN_MSGCTRL_IDE;

    /* Set SRR bit */
    msg_obj_ptr->CONTROL |= FLEXCAN_MSGCTRL_SRR;

    /* Start CR# 1730 */
    msg_obj_ptr->ID = FLEXCAN_EXTENDED_ID_MASK(identifier);
  }
  else if ( format == FLEXCAN_STANDARD )
  {
    /* make sure IDE and SRR are not set */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCTRL_IDE | FLEXCAN_MSGCTRL_SRR);

    /* ID[28-18] */
    msg_obj_ptr->ID = FLEXCAN_STANDARD_ID_MASK(identifier);
  }
  else
  {
    return (FLEXCAN_MESSAGE_FORMAT_UNKNOWN);
  } /* Endif */

  /*
  ** Copy user's buffer into mailbox data area
  */
  for (i = 0; i < data_len_code; i++)
  {
    msg_obj_ptr->DATA[i] = ((uchar_ptr)data)[i];
  } /* Endfor */

  data_len_code <<= 16;
  /*
  ** Set data up for send 
  ** send is automatic when remote message is received
  ** send when message buffer is not active
  */
  code = msg_obj_ptr->CONTROL;
  if ( (code & FLEXCAN_MSGCRTL_CODE) == FLEXCAN_TX_MSG_BUFFER_NOT_ACTIVE )
  {
    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);
    /* Clear the DLC */
    msg_obj_ptr->CONTROL &= ~FLEXCAN_MSG_CTRL_DLEN;
    msg_obj_ptr->CONTROL |= (FLEXCAN_MESSAGE_TRANSMIT_ONCE | data_len_code);
  }

  /* Update data to respond to remote request frame */
  if ( ((code & FLEXCAN_MSGCRTL_CODE) == FLEXCAN_MESSAGE_TRANSMIT_RESPONED_ONLY) ||
       ((code & FLEXCAN_MSGCRTL_CODE) == FLEXCAN_MESSAGE_TRANSMIT_RESPONED) )
  {
    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);
    /* Clear the DLC */
    msg_obj_ptr->CONTROL &= ~FLEXCAN_MSG_CTRL_DLEN;
    msg_obj_ptr->CONTROL |= (FLEXCAN_MESSAGE_TRANSMIT_RESPONED | data_len_code);
  }

  /* Unlock message buffer */
  temp16 = can_reg_ptr->TIMER;

  return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Read  
* Returned Value   : uint_32 
* Comments         :
*    This function reads the contents of the specified CAN memory.
*
*END*********************************************************************/
uint_32 FLEXCAN_Read
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] offset from the base address of the device */
 uint_32         offset,
 /* [IN/OUT] pointer to location of where the data is to be read to */
 uint_32_ptr     data_ptr
 )
{ /* Body */

  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  uint_32                                  read_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  read_ptr = (vuint_32)can_reg_ptr + offset;
  *data_ptr = (uint_32) * (uchar_ptr)read_ptr;

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Write  
* Returned Value   : uint_32 
* Comments         :
*    This function writes the specified value to the specified CAN 
*    memory.
*
*END*********************************************************************/
uint_32 FLEXCAN_Write
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] offset from the base address of the device */
 uint_32     offset,
 /* Data to be written at the start of the offset */
 uint_32     value
 )
{ /* Body */

  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  vuint_32                                  write_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  write_ptr = (uint_32)can_reg_ptr + offset;
  *(uchar_ptr)write_ptr = (uchar)value;

  return (FLEXCAN_OK);

} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_Get_status  
* Returned Value   : uint_32 
* Comments         :
*    This function gets the CAN chip in the specified state.
*
*END*********************************************************************/
uint_32 FLEXCAN_Get_status
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN/OUT] pointer to Error/Status registry */
 uint_32_ptr can_status
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  *can_status = can_reg_ptr->ERRSTAT;

  return (FLEXCAN_OK);
} /* Endbody */

/*FUNCTION****************************************************************
* 
* Function Name    : FLEXCAN_update_message
* Returned Value   : uint_32 
* Comments         :
*    This function updates data as a response to a remote frame.
*
*END*********************************************************************/
uint_32 FLEXCAN_Update_message
(
 /* [IN] FlexCAN device number */
 uint_8 dev_num,
 /* [IN] pointer to data */
 pointer data_ptr,
 /* [IN] number of bytes to write to the mailbox (0 to 8) */
 uint_32 data_len_code,
 /* [IN] mailbox format (CAN_STANDARD OR CAN_EXTENDED) */
 uint_32 format,
 /* [IN] mailbox number */
 uint_32 mailbox_number
 )
{ /* Body */
  volatile FLEXCAN_REG_STRUCT_PTR          can_reg_ptr;
  volatile FLEXCAN_MSG_OBJECT_STRUCT_PTR   msg_obj_ptr;
  uint_32   i;
  uchar_ptr data_array;
  vuint_32  code;

  can_reg_ptr = _bsp_get_flexcan_base_address(dev_num);
  if ( NULL == can_reg_ptr )
  {
    return (FLEXCAN_INVALID_ADDRESS);
  }

  if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB(0xFFFFFFFF)) )
  {
    return (FLEXCAN_INVALID_MAILBOX);
  }

  if ( 8 < data_len_code )
  {
    return (FLEXCAN_DATA_SIZE_ERROR);
  }

  msg_obj_ptr = (FLEXCAN_MSG_OBJECT_STRUCT_PTR)FLEXCAN_Get_msg_object(dev_num, mailbox_number);

  /* check for RTR bit */
  code = msg_obj_ptr->CONTROL;
  if ( (code & FLEXCAN_MSGCTRL_RTR) == FLEXCAN_MSGCTRL_RTR ) return FLEXCAN_RTR_NOT_SET;

  /* check if mailbox is set for transmit */
  if ( (code & FLEXCAN_TX_MSG_BUFFER_NOT_ACTIVE) == FLEXCAN_TX_MSG_BUFFER_NOT_ACTIVE )
  {
    /* Reset the code */
    msg_obj_ptr->CONTROL &= ~(FLEXCAN_MSGCRTL_CODE);

    /* store data */
    data_array = (uchar_ptr)data_ptr;
    for (i = 0; i < data_len_code; i++)
    {
      msg_obj_ptr->DATA[i] = data_array[i];
    }

    /* 
    ** Data frame to be transmitted only as a response to 
    ** a remote frame. code 0b1010
    */
    msg_obj_ptr->CONTROL |= (FLEXCAN_MESSAGE_TRANSMIT_RESPONED | data_len_code);
  }
  else return FLEXCAN_INVALID_MAILBOX;

  return FLEXCAN_OK;

} /* Endbody */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/enstop.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: enstop.c$
* $Version : 3.8.5.0$
* $Date    : Aug-1-2011$
*
* Comments:
*
*   This file contains the MCF52xx Ethernet shutdown
*   functions.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : ENET_shutdown
*  Returned Value : ENET_OK or error code
*  Comments       :
*        Stops the chip.
*
*END*-----------------------------------------------------------------*/
uint_32 ENET_shutdown(_enet_handle   handle /* [IN] the Ethernet state structure */)
{  
    ENET_CONTEXT_STRUCT_PTR    enet_ptr;
    uint_32                    result;
   
    if(handle == NULL)
        return ENETERR_INVALID_DEVICE;
    
    enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle;

    /* Make sure upper layers have closed the device.*/
    if (enet_ptr->ECB_HEAD) 
        return ENETERR_DEVICE_IN_USE;
      
    /* Notify the lower layer.*/
    result = (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->STOP)(enet_ptr);
   
    if (result == ENET_OK)
    {
        _lwsem_destroy(&enet_ptr->CONTEXT_LOCK);
        _mqx_unlink_io_component_handle(IO_ENET_COMPONENT,enet_ptr, (pointer *)&enet_ptr->NEXT);
        _mem_free((pointer) enet_ptr);
    }

    return result;
} 




<|start_filename|>Firmware/Inverter_firmware/mcc/source/include/mcc_config.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2013 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************
* $FileName: mcc_config.h$
* $Version : 3.8.1.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This is the main MCC configuration file
*
*END************************************************************************/

#ifndef __MCC_CONFIG__
#define __MCC_CONFIG__

/* used OS */
#define MCC_OS_USED                    (MCC_MQX)

/* base address of shared memory */
#define MCC_BASE_ADDRESS               (BSP_SHARED_RAM_START)

/* size (in bytes) and number of receive buffers */
#define MCC_ATTR_NUM_RECEIVE_BUFFERS   (10)
#define MCC_ATTR_BUFFER_SIZE_IN_BYTES  (1024)

/* maximum number of receive endpoints (application specific setting),
 * do not assign it to a value greater than 255 ! */
#define MCC_ATTR_MAX_RECEIVE_ENDPOINTS (5)

/* size of the signal queue */
#define MCC_MAX_OUTSTANDING_SIGNALS    (10)

/* number of cores */
#define MCC_NUM_CORES                  (2)

/* core number */
#define MCC_CORE_NUMBER                (_psp_core_num())

/* semaphore number */
#define MCC_SHMEM_SEMAPHORE_NUMBER      (1)
#define MCC_PRINTF_SEMAPHORE_NUMBER     (2)
#define MCC_I2C_SEMAPHORE_NUMBER        (3)
#define MCC_RESERVED1_SEMAPHORE_NUMBER  (4)
#define MCC_RESERVED2_SEMAPHORE_NUMBER  (5)

#endif /* __MCC_CONFIG__ */


<|start_filename|>Firmware/Inverter_firmware/usb/host/build/bat/usbh_INV1_K60F120.bat<|end_filename|>
@echo off

rem convert path to backslash format
set MQXROOTDIR=%1
set MQXROOTDIR=%MQXROOTDIR:/=\%
set OUTPUTDIR=%2
set OUTPUTDIR=%OUTPUTDIR:/=\%
set TOOL=%3


rem copy common files
IF NOT EXIST %OUTPUTDIR% mkdir %OUTPUTDIR%
copy %MQXROOTDIR%\usb\common\include\usb.h %OUTPUTDIR%\usb.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_debug.h %OUTPUTDIR%\usb_debug.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_desc.h %OUTPUTDIR%\usb_desc.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_error.h %OUTPUTDIR%\usb_error.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_misc.h %OUTPUTDIR%\usb_misc.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_misc_prv.h %OUTPUTDIR%\usb_misc_prv.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_prv.h %OUTPUTDIR%\usb_prv.h /Y
copy %MQXROOTDIR%\usb\common\include\usb_types.h %OUTPUTDIR%\usb_types.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\audio\usb_host_audio.h %OUTPUTDIR%\usb_host_audio.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\cdc\usb_host_cdc.h %OUTPUTDIR%\usb_host_cdc.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\hid\usb_host_hid.h %OUTPUTDIR%\usb_host_hid.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\hub\usb_host_hub.h %OUTPUTDIR%\usb_host_hub.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\hub\usb_host_hub_sm.h %OUTPUTDIR%\usb_host_hub_sm.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\msd\mfs\usbmfs.h %OUTPUTDIR%\usbmfs.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\msd\mfs\usbmfspr.h %OUTPUTDIR%\usbmfspr.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\msd\usb_host_msd_bo.h %OUTPUTDIR%\usb_host_msd_bo.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\msd\usb_host_msd_ufi.h %OUTPUTDIR%\usb_host_msd_ufi.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\phdc\usb_host_phdc.h %OUTPUTDIR%\usb_host_phdc.h /Y
copy %MQXROOTDIR%\usb\host\source\classes\printer\usb_host_printer.h %OUTPUTDIR%\usb_host_printer.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci.h %OUTPUTDIR%\ehci.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci_bw.h %OUTPUTDIR%\ehci_bw.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci_cache.h %OUTPUTDIR%\ehci_cache.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci_cncl.h %OUTPUTDIR%\ehci_cncl.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci_intr.h %OUTPUTDIR%\ehci_intr.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci_iso.h %OUTPUTDIR%\ehci_iso.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci_main.h %OUTPUTDIR%\ehci_main.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci_shut.h %OUTPUTDIR%\ehci_shut.h /Y
copy %MQXROOTDIR%\usb\host\source\host\ehci\ehci_utl.h %OUTPUTDIR%\ehci_utl.h /Y
copy %MQXROOTDIR%\usb\host\source\host\khci\khci.h %OUTPUTDIR%\khci.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_ch9.h %OUTPUTDIR%\host_ch9.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_close.h %OUTPUTDIR%\host_close.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_cnfg.h %OUTPUTDIR%\host_cnfg.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_cnl.h %OUTPUTDIR%\host_cnl.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_common.h %OUTPUTDIR%\host_common.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_dev_list.h %OUTPUTDIR%\host_dev_list.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_main.h %OUTPUTDIR%\host_main.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_rcv.h %OUTPUTDIR%\host_rcv.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_shut.h %OUTPUTDIR%\host_shut.h /Y
copy %MQXROOTDIR%\usb\host\source\include\host_snd.h %OUTPUTDIR%\host_snd.h /Y
copy %MQXROOTDIR%\usb\host\source\include\hostapi.h %OUTPUTDIR%\hostapi.h /Y
copy %MQXROOTDIR%\usb\host\source\rtos\mqx\mqx_dll.h %OUTPUTDIR%\mqx_dll.h /Y
copy %MQXROOTDIR%\usb\host\source\rtos\mqx\mqx_host.h %OUTPUTDIR%\mqx_host.h /Y
copy %MQXROOTDIR%\usb\host\source\rtos\mqx\usb_mqx.h %OUTPUTDIR%\usb_mqx.h /Y


goto tool_%TOOL%

rem cw10 files
:tool_cw10
goto copy_end

rem iar files
:tool_iar
goto copy_end

rem cw10gcc files
:tool_cw10gcc
goto copy_end

rem uv4 files
:tool_uv4
goto copy_end

:copy_end



<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/eds_prv.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: eds_prv.h$
* $Version : 3.0.3.0$
* $Date    : Nov-21-2008$
*
* Comments:
*
*   IPC Embedded Debug Server private header file
*
*END************************************************************************/
#ifndef __eds_prv_h__
#define __eds_prv_h__

#include "message.h"
#include "msg_prv.h"
#include "ipc.h"
#include "ipc_prv.h"
#include "timer.h"

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */

/* 
 * How long to wait for all mult-proc configuration messages to
 * return.
 */
#define EDS_MSG_WAIT_TIMEOUT  (5000) /* Msec */

/* server operations */
#define EDS_IDENTIFY                 0x00000001
#define EDS_LITTLE_ENDIAN_IDENTIFY   0x01000000
#define EDS_READ                     0x00000002
#define EDS_WRITE                    0x00000003
#define EDS_CONFIG_MULTIPROC         0x00000004
#define EDS_CONFIG_MULTIPROC_END     0x00000005
#define EDS_CONFIG_REQUEST_TIMEOUT   0x00000006
#define EDS_IDENTIFY_MULTIPROC       0x00000008
#define EDS_CONFIG_MULTIPROC_RESPOND 0x00000064


#define EDS_BIG_ENDIAN      0
#define EDS_LITTLE_ENDIAN   0xFFFFFFFF

/* error codes */
#define EDS_OK              0
#define EDS_INVALID_OP      1
#define EDS_INVALID_SIZE    2

/* Usefull sizes */
#define IPC_COMMAND_SIZE \
   (sizeof(MESSAGE_HEADER_STRUCT) + (2*sizeof(uint_32)) + sizeof(_task_id))
#define EDS_COMMAND_SIZE  \
   (IPC_COMMAND_SIZE + sizeof(EDS_OP_STRUCT))
#define EDS_DATA_SIZE \
   (IPC_MAX_PARAMETERS - (sizeof(EDS_OP_STRUCT)/sizeof(uint_32)))

/* Validates the EDS component */
#define EDS_VALID    ((_mqx_uint)0x65647376)   /* "edsv" */

/* EDS States */
#define EDS_IDLE                 0
#define EDS_CONFIG_IN_PROGRESS   1

/*
** MACROS
*/


/*--------------------------------------------------------------------------*/
/*                      DATA STRUCTURE DEFINITIONS                          */

/*!
 * \cond DOXYGEN_PRIVATE 
 * 
 * \brief EDS operation structure.
 * 
 * This structure is always BIG Endian. */
typedef struct eds_op_struct 
{
   /*! \brief Server operation. */
   uint_32  OPERATION;   
   /*! \brief Read/write memory address. */
   uint_32  ADDRESS;     
   /*! \brief Extra address field. */
   uint_32  ADDRESS2;    
   /*! \brief Size of buffer. */
   uint_32  SIZE;        
   /*! \brief Processor type. */
   uint_32  PROCESSOR;   
   /*! \brief Endian of processor. */
   uint_32  ENDIAN;      
   /*! \brief Error code. */
   uint_32  EDS_ERROR;   
} EDS_OP_STRUCT, _PTR_ EDS_OP_STRUCT_PTR;
/*! \endcond */

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief EDS Message struct.
 *  
 * The EDS Message struct overlays the Parameters field of the IPC Message struct.
 */
typedef struct eds_msg_struct
{
   /*! \brief The EDS command to process, always in BIG endian format. */
   EDS_OP_STRUCT          OP_COMMAND;

   /*! \brief The maximum number of datums to send/receive. */
   uint_32                DATA[EDS_DATA_SIZE];

} EDS_MSG_STRUCT, _PTR_ EDS_MSG_STRUCT_PTR;
/*! \endcond */

/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief EDS component structure.
 */ 
typedef struct eds_component_struct
{
   /*! \brief Lightweight semaphore. */
   LWSEM_STRUCT           SEM;

   /*! \brief Pointer to saved messages. */
   IPC_MESSAGE_STRUCT_PTR SAVED_MSG_PTR;
   /*! \brief Valid flag. */
   _mqx_uint              VALID;
   /*! \brief state flag. */
   _mqx_uint              STATE;

   /*! \brief Timer ID. */
   _timer_id              TIMER_ID;
   /*! \brief Host queue ID. */
   _queue_id              HOST_QID;
   /*! \brief My queue ID. */
   _queue_id              MY_QID;
   /*! \brief Processor number whose responses are expected. */
   _processor_number      RESPONSES_EXPECTED;
   /*! \brief Host processor number. */
   _processor_number      HOST_PNUM;
   /*! \brief Queue number. */
   _queue_number          HOST_QNUM;

   /*! \brief Timeout time. */
   MQX_TICK_STRUCT        TIMEOUT;

} EDS_COMPONENT_STRUCT, _PTR_ EDS_COMPONENT_STRUCT_PTR;
/*! \endcond */

/*--------------------------------------------------------------------------*/
/*                      PROTOTYPES                                          */


#ifdef __cplusplus
extern "C" {
#endif

extern _mqx_uint _eds_ipc_handler(pointer);
extern void      _eds_ipc_return_message(IPC_MESSAGE_STRUCT_PTR);
extern void      _eds_timeout(_timer_id,pointer,MQX_TICK_STRUCT_PTR);
 
#ifdef __cplusplus
}
#endif

#endif

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/host_dev_list.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_dev_list.c$
* $Version : 3.8.27.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the device-tree root for USB class drivers
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_main.h"
#include "host_common.h"
#include "host_dev_list.h"
#include "host_ch9.h"
#include "host_close.h"

static const PIPE_INIT_PARAM_STRUCT pipe_init_params_prototype =
{
   {
      NULL,                   /* pointer to the next pipe */
      NULL,                   /* device instance pointer */
      0,                      /* polling interval */
      USBCFG_DEFAULT_MAX_NAK_COUNT,  /* max. NAKs */
      0, 0,                   /* 1st frame/uframe */
      0,                      /* zero-length last packet */
      64,                     /* max. packet size */
      0,                      /* pipe ID on a particular host controller */
      0,                      /* host controller number */
      0,                      /* endpoint # */
      0,                      /* direction */
      0,                      /* pipe type */
      0,                      /* speed */
      1,                      /* tr's per uframe */
      0,                      /* closed by default */
      0,                      /* start with DATA0 */
      NULL                    /* no transaction scheduled */
   }
};

/* Unpublished functions, not intended for application use */
static void  usb_dev_list_close_pipe(_usb_host_handle, PIPE_STRUCT_PTR);

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_dev_list_free_memlist
* Returned Value : USB_OK if valid device, else error code
* Comments       :
*     Close pipes & free memory on device's linked list, whose
*        anchor is dev_handle-->memlist
*     
*END*--------------------------------------------------------------------*/
USB_STATUS usb_dev_list_free_memlist
   (
      /* [IN] Handle for the USB device */
      _usb_device_instance_handle   dev_handle
   )
{ /* Body */
   DEV_INSTANCE_PTR  dev;
   DEV_MEMORY_PTR    mem_ptr, list_ptr;
   USB_STATUS        error;
   uint_8            intf_no;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_free_memlist");
   #endif

   error = usb_hostdev_validate(dev_handle);
   // EAI - missing {} so failed if debug on
   if (error != USB_OK) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_free_memlist invalid device handle");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   }
   dev = (DEV_INSTANCE_PTR)dev_handle;

   /* Deleting interfaces closes their pipes */
   for (intf_no = 0; intf_no < dev->num_of_interfaces; intf_no++)
      usb_hostdev_delete_interface(dev, dev->intf_descriptor[intf_no]);

   /* Free memory blocks on this device's list */
   USB_lock();
   mem_ptr = dev->memlist;

   while (mem_ptr != NULL) {
      list_ptr = mem_ptr->next;
      USB_mem_free(mem_ptr);
      mem_ptr = list_ptr;
   }

   dev->memlist = NULL;
   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_free_memlist SUCCESSFUL");
   #endif
   return USB_OK;

} /* Endbody */
  
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_dev_list_free_mem
* Returned Value : USB_OK if memory is freed, else error code
* Comments       :
*     Memory is unlinked and freed from dev_ptr->memlist
*     
*END*--------------------------------------------------------------------*/
USB_STATUS usb_dev_list_free_mem
   (
      /* [IN] Pointer to the USB device */
      DEV_INSTANCE_PTR        dev_ptr,

      /* [IN] Pointer to memory */
      DEV_MEMORY_PTR          header_ptr
   )
{ /* Body */

   DEV_MEMORY_PTR  mem_ptr, list_ptr;
   DEV_MEMORY_PTR  prev_ptr = NULL;
   USB_STATUS      error;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_free_mem");
   #endif

   USB_lock();
   error = usb_hostdev_validate((_usb_device_instance_handle)dev_ptr);
   USB_unlock();

   if (error != USB_OK) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_free_mem invalid device handle");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   }
   mem_ptr = (DEV_MEMORY_PTR) header_ptr;
   
   if (mem_ptr == NULL)
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_free_mem invalid memory pointer");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_MEM_TYPE);
   } /* Endif */

   for (list_ptr = dev_ptr->memlist; list_ptr != NULL; list_ptr = list_ptr->next) {
      if (list_ptr == mem_ptr)
         break;
      prev_ptr = list_ptr;
   }

   if (list_ptr == NULL) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_free_mem not found");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_NOT_FOUND);
   }

   /* Unlink the buffer from the list */
   if (dev_ptr->memlist == mem_ptr) {
      /* Unlink from anchor */
      /* WARNING!!! The first buffer in the chain is the full configuration descriptor,
      ** so there is probably some issue if there is attempt to free it, because
      ** configuration descriptor must have its lifetime till the device's detach or
      ** till selecting another configuration.
      */
      dev_ptr->memlist = mem_ptr->next;
   } else {
      if(prev_ptr != NULL) {
         /* Unlink from chain */
         prev_ptr->next = mem_ptr->next;
      }
   }

   /* Free associated memory */
   USB_mem_free(mem_ptr);

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_free_mem SUCCESSFUL");
   #endif

   return USB_OK;
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_dev_list_get_mem
* Returned Value : USB_OK if memory allocated, else error code
* Comments       :
*     Memory is added at the end of a linked list, whose
*        anchor is device.memlist 
*     
*END*--------------------------------------------------------------------*/
USB_STATUS usb_dev_list_get_mem
   (
      /* [IN] Pointer to the USB device */
      DEV_INSTANCE_PTR        dev_ptr,

      /* [IN] Size of memory payload required */
      uint_32                 mem_size,

      /* [IN] Type of memory payload required */
      memory_type             mem_type,

      /* [IN] Alignment required */
      uint_32                 align,

      /* [OUT] Pointer to memory block's header */
      DEV_MEMORY_PTR _PTR_    header_ptr
   )
{ /* Body */

   DEV_MEMORY_PTR  mem_ptr, list_ptr;
   USB_STATUS      error;
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_get_mem");
   #endif

   if (align > 256)
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid alignment");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_BAD_ALIGNMENT);
   }

   if ((mem_type <= USB_MEMTYPE_MIN_VALUE) || (mem_type >= USB_MEMTYPE_MAX_VALUE))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid memory type");
      #endif
      return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_MEM_TYPE);
   }

   USB_lock();
   error = usb_hostdev_validate((_usb_device_instance_handle)dev_ptr);

   if (error != USB_OK) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid device handle");
      #endif
      return USB_log_error(__FILE__,__LINE__,error);
   }
   
   /* get memory for header + payload, rounded up to align bytes */
   mem_ptr = (DEV_MEMORY_PTR) USB_mem_alloc_uncached_zero(MEM_HEADER_LEN + mem_size +  align - 1);

   if (mem_ptr == NULL) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_get_mem malloc FAILED");
      #endif

      return USB_log_error(__FILE__,__LINE__,USBERR_GET_MEMORY_FAILED);
   }
   _mem_set_type(mem_ptr, MEM_TYPE_USB_LIST_MEM_BUFF);
   
   if (dev_ptr->memlist == NULL) {
      dev_ptr->memlist = mem_ptr;
   } else {
      list_ptr = dev_ptr->memlist;

      while (list_ptr->next != NULL)
         list_ptr = list_ptr->next;

      list_ptr->next = mem_ptr;   
   } /* EndIf */

   mem_ptr->next = NULL;
   mem_ptr->blktype = mem_type;
   mem_ptr->blksize = mem_size;
   mem_ptr->offset = (~(uint_32) mem_ptr->payload.data + 1) & (align - 1);
   if (mem_ptr->offset) {
      /* Real payload is by offset bytes shifted from original payload. We want to write offset in the byte just before
      ** real payload. */
      mem_ptr->payload.data[mem_ptr->offset - 1] = mem_ptr->offset; /* write offset value also 1 byte before payload */
   }
   *header_ptr = (pointer)mem_ptr;

   USB_unlock();

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_get_mem SUCCESSFUL");
   #endif
   return USB_OK;
} /* Endbody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_dev_list_attach_device
* Returned Value : 
* Comments       :
*     This function will be called when attach interrupt happens, to
*       add onto the device list and do common initialization.     
* 
*END*--------------------------------------------------------------------*/
USB_STATUS usb_dev_list_attach_device
   (
      _usb_host_handle  handle,
      uint_8            speed,
      uint_8            hub_no,
      uint_8            port_no
   )
{ /* Body */
   USB_STATUS                 status;
   DEV_INSTANCE_PTR           new_instance_ptr, dev_instance_ptr, dev_instance_prev_ptr;
   PIPE_INIT_PARAM_STRUCT     ctrl_pipe_init_params;
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
   DEV_INSTANCE_PTR           device_root = NULL;
#ifdef __USB_OTG__
   uint_32                    state;
#endif

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_attach_device attach device");
   #endif
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

   /* Allocate new device instance */
   new_instance_ptr = (DEV_INSTANCE_PTR) USB_mem_alloc_uncached(sizeof(DEV_INSTANCE));

   if (new_instance_ptr == NULL) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_attach_device failed to malloc device handle");
      #endif
      return USB_log_error(__FILE__,__LINE__, USBERR_GET_MEMORY_FAILED);
   } /* EndIf */
   _mem_set_type(new_instance_ptr, MEM_TYPE_USB_HOST_STATE_STRUCT);

   USB_mem_zero(new_instance_ptr, sizeof(DEV_INSTANCE));

   new_instance_ptr->host = handle;
   new_instance_ptr->speed = speed;
   new_instance_ptr->hub_no = hub_no;
   new_instance_ptr->port_no = port_no;
   new_instance_ptr->cfg_value = 0; /* We don't know yet what the device's default configuration is */

   USB_lock();

   /* Find unused address from 1 - 127 for this host */
   dev_instance_ptr = usb_host_ptr->DEVICE_LIST_PTR;
   if ((dev_instance_ptr == NULL) || (dev_instance_ptr->address != 1)) {
      /* Insert at the beginning of list */
      new_instance_ptr->address = 1;
      new_instance_ptr->next = dev_instance_ptr;
      usb_host_ptr->DEVICE_LIST_PTR = new_instance_ptr;
   }
   else {
      dev_instance_prev_ptr = dev_instance_ptr;
      /* Searching for a 'hole' in devices instance adresses */
      while (dev_instance_ptr->address <= (dev_instance_prev_ptr->address + 1)) {
         new_instance_ptr->address = dev_instance_ptr->address;
         dev_instance_prev_ptr = dev_instance_ptr;
         dev_instance_ptr = dev_instance_ptr->next;
         if (dev_instance_ptr == NULL)
            break;
      } /* EndWhile */
      if (new_instance_ptr->address >= 127) {
         /* If all 127 addresses used up, delete instance & bail out */
         USB_unlock();
         USB_mem_free((pointer)new_instance_ptr);
         #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_dev_list_attach_device out of addresses");
         #endif
         return USB_log_error(__FILE__,__LINE__, USBERR_ADDRESS_ALLOC_FAILED);
      } /* EndIf */
      new_instance_ptr->address++;
      new_instance_ptr->next = dev_instance_ptr;
      dev_instance_prev_ptr->next = new_instance_ptr;
   };
      
   USB_unlock();

   /*-----------------------------------------------------------**
   ** Open control pipe, get first 8 bytes of device descriptor **
   ** The host_ch9 routine internally sets the callback to      **
   **    usb_host_cntrl_transaction_done (in usb_host_ch9.c)    **
   **    where the action resumes on completion of the get.     **
   **-----------------------------------------------------------*/
   
   ctrl_pipe_init_params = pipe_init_params_prototype;
   ctrl_pipe_init_params.G.DEV_INSTANCE = new_instance_ptr;
   ctrl_pipe_init_params.G.PIPETYPE = USB_CONTROL_PIPE;   
   ctrl_pipe_init_params.G.SPEED = new_instance_ptr->speed;

   ctrl_pipe_init_params.G.HUB_DEVICE_ADDR = hub_no;
   ctrl_pipe_init_params.G.HUB_PORT_NUM = port_no;
#ifdef __USB_OTG__
   _usb_otg_get_status((pointer)usb_otg_state_struct_ptr, 
      USB_OTG_STATE, &state);
   
   if (state < B_IDLE) {
      _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, 
         USB_OTG_A_BUS_REQ, TRUE);
      _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, 
         USB_OTG_B_CONN, TRUE);
   } else {
      _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, 
         USB_OTG_A_CONN, TRUE);
   } /* Endif */
#endif

   if (USB_OK != _usb_host_open_pipe(new_instance_ptr->host, 
      &ctrl_pipe_init_params, 
      &new_instance_ptr->control_pipe))
   {
      USB_mem_free((pointer)new_instance_ptr);
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_attach_device open pipe failed");
      #endif
      return USB_log_error(__FILE__,__LINE__, USBERR_PIPE_OPENED_FAILED);
   } /* Endif */

   /* Set state to enter after transaction completion */
   new_instance_ptr->state = DEVSTATE_DEVDESC8;

   status = _usb_host_ch9_get_descriptor((_usb_device_instance_handle)new_instance_ptr,
      USB_DESC_TYPE_DEV << 8, 0, 8, 
      (uchar_ptr)&new_instance_ptr->dev_descriptor);
      
   if (status != USB_STATUS_TRANSFER_QUEUED)
   {
      new_instance_ptr->state = DEVSTATE_INITIAL;
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_attach_device FAILED");
      #endif
      return USB_log_error(__FILE__,__LINE__, USBERR_NO_DESCRIPTOR);
   }
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_attach_device SUCCESSFUL");
   #endif
   return USB_OK;

} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_dev_list_close_pipe
* Returned Value : 
* Comments       :
*     Cancel pending TR's and close a pipe.
* 
*END*--------------------------------------------------------------------*/
static void  usb_dev_list_close_pipe
   (
      _usb_host_handle              handle,
      PIPE_STRUCT_PTR               pipe_ptr
   )
{ /* Body */
   USB_STATUS                       status;
   USB_HOST_STATE_STRUCT_PTR        usb_host_ptr;
   TR_STRUCT_PTR                    tr_ptr;   

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_close_pipe");
   #endif

   if (pipe_ptr == NULL)
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_close_pipe NULL pipe");
      #endif
      return;
   }

   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
      
   USB_lock();

   /* Cancel all active TR's in the pipe */
   tr_ptr = pipe_ptr->tr_list_ptr;
   if (tr_ptr != NULL) {
      do {
         tr_ptr->CALLBACK = NULL;
         if (tr_ptr->TR_INDEX != 0) {
            /* Cancel the transfer at low-level */
            status = _usb_host_cancel_call_interface(handle, pipe_ptr, tr_ptr);
         
            if (status != USB_OK)
            {
               #ifdef _HOST_DEBUG_
                  DEBUG_LOG_TRACE("usb_dev_list_close_pipe failed to cancel transaction");
               #endif
            }
         }

         tr_ptr->STATUS = USB_STATUS_IDLE;
         /* Indicate that the TR is idle */
         tr_ptr->TR_INDEX = 0;
         tr_ptr = tr_ptr->NEXT;
      } while (tr_ptr != pipe_ptr->tr_list_ptr); //this indicates end of queue
   } /* EndWhile */

   /* zero the pipe descriptor, except keep TR list */
   tr_ptr = pipe_ptr->tr_list_ptr;
   _usb_host_close_pipe(handle, (pointer)pipe_ptr);
   pipe_ptr->tr_list_ptr = tr_ptr;   

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_close_pipe SUCCESSFUL");
   #endif

} /* EndBody */


/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_dev_list_close_pipe_bundle
* Returned Value : 
* Comments       :
*    Close all pipes in an interface's bundle.
* 
*END*--------------------------------------------------------------------*/
void  usb_dev_list_close_pipe_bundle
   (
      PIPE_BUNDLE_STRUCT_PTR    pbs_ptr
   )
{ /* Body */

   _usb_host_handle  handle;
   uint_8            index, index_max;
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_close_pipe_bundle");
   #endif
   
   handle = ((DEV_INSTANCE_PTR)pbs_ptr->dev_handle)->host;
   index_max = ((INTERFACE_DESCRIPTOR_PTR) pbs_ptr->intf_handle)->bNumEndpoints;

   for (index = 0; index < index_max; index++)
      usb_dev_list_close_pipe(handle, (PIPE_STRUCT_PTR)pbs_ptr->pipe_handle[index]); 

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_close_pipe_bundle SUCCESSFUL");
   #endif

} /* EndBody */
    

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_dev_list_detach_device
* Returned Value : 
* Comments       :
*     This function will be called when detach interrupt happens.
* 
*END*--------------------------------------------------------------------*/
void  usb_dev_list_detach_device
   (
      _usb_host_handle  handle,
      uint_8            hub_no,
      uint_8            port_no
   )
{ /* Body */
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   DEV_INSTANCE_PTR  dev_instance_ptr;
   DEV_INSTANCE_PTR  _PTR_ device_root = (DEV_INSTANCE_PTR _PTR_)&usb_host_ptr->DEVICE_LIST_PTR;
#ifdef __USB_OTG__
   uint_32           state;
#endif
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_detach_device");
   #endif

   /* search device list for the one being detached */
   USB_lock();
   for (dev_instance_ptr = *device_root;   
      dev_instance_ptr != NULL;
      dev_instance_ptr = dev_instance_ptr->next)   
   {
      if (dev_instance_ptr->port_no != port_no)
         continue;
      if (dev_instance_ptr->hub_no != hub_no)
         continue;
      if (dev_instance_ptr->host != handle)
         continue;
      break;
   } /* EndFor */

   USB_unlock();

   if (dev_instance_ptr == NULL) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_detach_device NULL device pointer");
      #endif
      return;  /* No match, abandon ship! */
   } /* Endif */

   /* SGarg 09/23/2003 . Sometimes  a detach could come even before a 
   attach is finished. This means that we should make sure that device
   memory is not NULL before we try to clean it up. For example this happens
   with OPT tester test 4.10.*/
   
   if(dev_instance_ptr->memlist != NULL)
   {
      /* Notify the application of unavailable interfaces */
      usb_hostdev_attach_detach(dev_instance_ptr, USB_DETACH_EVENT);
      
   }

   /* Unlink device from the instance list */
   dev_instance_ptr->control_callback = NULL; /* no surprises */

   /* Close control pipe */
   usb_dev_list_close_pipe(handle, (PIPE_STRUCT_PTR)dev_instance_ptr->control_pipe);
   
   /* SGarg 09/24/2003 . Sometimes  a detach could come even before a 
   attach is finished. This means that we should make sure that device
   memory is not NULL before we try to clean it up. For example this happens
   with OPT tester test 4.10.*/
   if(dev_instance_ptr->memlist != NULL)
   {
      usb_dev_list_free_memlist((_usb_device_instance_handle)dev_instance_ptr);
   }

   USB_lock();

   /* Find the address of the "pointer to the detached device" */
   while (*device_root != dev_instance_ptr) {
      device_root = &(*device_root)->next;
   } /* Endwhile */

   /* Remove the device */
   *device_root = dev_instance_ptr->next;

   USB_mem_free(dev_instance_ptr);

#ifdef __USB_OTG__
   _usb_otg_get_status((pointer)usb_otg_state_struct_ptr, 
      USB_OTG_STATE, &state);

   if (state < B_IDLE) {
      _usb_otg_get_status((pointer)usb_otg_state_struct_ptr,
         USB_OTG_B_CONN, &state);
      if (state) {
         _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, 
            USB_OTG_B_CONN, FALSE);
      } /* Endif */
   } else {
      _usb_otg_get_status((pointer)usb_otg_state_struct_ptr,
         USB_OTG_A_CONN, &state);
      if (state) {
         _usb_otg_set_status((pointer)usb_otg_state_struct_ptr,
            USB_OTG_A_CONN, FALSE);
      } /* Endif */
   } /* Endif */
#endif

   USB_unlock();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_detach_device SUCCESSFUL");
   #endif

} /* EndBody */

/* EOF */


<|start_filename|>Firmware/Inverter_bootloader/BSP/app_types.h<|end_filename|>
#ifndef  __APP_TYPES
  #define  __APP_TYPES

  #define     BIT(n) (1u << n)
  #define     LSHIFT(v,n) (((unsigned int)(v) << n))

  #ifndef TRUE
    #define FALSE 0
    #define TRUE 1
  #endif

  #define RES_OK   (1)
  #define RES_NONE (0)

  #define  ERROR     (-1)
  #define  SUCCESS     0
  #define  BUSY      (-2)



  #define BYTESWAP16(x)	(INT16U)((((x) & 0xFF00) >> 0x8) | (((x) & 0xFF) << 0x8))
  #define BYTESWAP32(val)	(INT32U)((BYTESWAP16((INT32U)(val) & (INT32U)0xFFFF) << 0x10) |  \
					(BYTESWAP16((INT32U)((val) >> 0x10))))

  #define ieee_htons(x)		BYTESWAP16(x)
  #define ieee_htonl(x)		BYTESWAP32(x)
  #define ieee_ntohs(x)		BYTESWAP16(x)
  #define ieee_ntohl(x)		BYTESWAP32(x)

  #define UNUSED(x)   (void)x;


typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;                    /* Unsigned  8 bit quantity                           */
typedef signed   char  INT8S;                    /* Signed    8 bit quantity                           */
typedef unsigned short INT16U;                   /* Unsigned 16 bit quantity                           */
typedef signed   short INT16S;                   /* Signed   16 bit quantity                           */
typedef unsigned int   INT32U;                   /* Unsigned 32 bit quantity                           */
typedef signed   int   INT32S;                   /* Signed   32 bit quantity                           */
typedef unsigned long  INT64U;                   /* Unsigned 64 bit quantity                           */
typedef float          FP32;                     /* Single precision floating point                    */
typedef double         FP64;                     /* Double precision floating point                    */

typedef volatile unsigned long   VINT32U;
typedef volatile unsigned short  VINT16U;
typedef volatile unsigned char   VINT8U;

typedef INT8U  *INT8U_ptr;          /* ptr to 8-bit*/
typedef INT16U *INT16U_ptr;         /* ptr to 16-bit */
typedef INT32U *INT32U_ptr;         /* ptr to 32-bit*/

/* definition of 8 bit word */
typedef union _BYTE
{
  INT8U _byte;
  struct
  {
    unsigned b0:1;
    unsigned b1:1;
    unsigned b2:1;
    unsigned b3:1;
    unsigned b4:1;
    unsigned b5:1;
    unsigned b6:1;
    unsigned b7:1;
  }Bit;
} BYTE;

/* definition of 16 bit word */
typedef union _WORD
{
  INT16U _word;
  struct
  {
    INT8U byte1;
    INT8U byte0;
  }_byte;
  struct
  {
    BYTE HighB;
    BYTE LowB;
  }_Byte;
} WORD;

/* definition of 32 bit word */
typedef union _DWORD
{
  INT32U _dword;
  struct
  {
    INT8U byte3;
    INT8U byte2;
    INT8U byte1;
    INT8U byte0;
  }_byte;
  struct
  {
    INT16U word1;
    INT16U word0;
  }_word;
  struct
  {
    BYTE Byte3;
    BYTE Byte2;
    BYTE Byte1;
    BYTE Byte0;
  }_Byte;
  struct
  {
    WORD Word1;
    WORD Word0;
  }_Word;
} DWORD;

extern void Delay_m8(int cnt); // Задержка на (cnt+1)*8 тактов . Передача нуля недопускается

  #define  DELAY_1us    Delay_m8(15-1)
  #define  DELAY_2us    Delay_m8(2*15-1)
  #define  DELAY_4us    Delay_m8(4*15-1)
  #define  DELAY_8us    Delay_m8(8*15-1)
  #define  DELAY_30us   Delay_m8(30*15-1)
  #define  DELAY_ms(x)  Delay_m8(1000*15*x-1)


#endif


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/classes/hub/usb_host_hub_prv.h<|end_filename|>
#ifndef __usb_host_hub_prv_h__
#define __usb_host_hub_prv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: usb_host_hub_prv.h$
* $Version : 3.8.8.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   This file defines a structure(s) for hub class driver.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_ch9.h"
#include "host_rcv.h"
#include "host_dev_list.h"

#define  C_HUB_LOCAL_POWER          (0)
#define  C_HUB_OVER_CURRENT         (1)
#define  PORT_CONNECTION            (0)
#define  PORT_ENABLE                (1)
#define  PORT_SUSPEND               (2)
#define  PORT_OVER_CURRENT          (3)
#define  PORT_RESET                 (4)
#define  PORT_POWER                 (8)
#define  PORT_LOW_SPEED             (9)
#define  PORT_HIGH_SPEED            (10)
#define  C_PORT_CONNECTION          (16)
#define  C_PORT_ENABLE              (17)
#define  C_PORT_SUSPEND             (18)
#define  C_PORT_OVER_CURRENT        (19)
#define  C_PORT_RESET               (20)
#define  C_PORT_POWER               (24)
#define  PORT_TEST                  (21)
#define  PORT_INDICATOR             (22)

/* structure for HUB class descriptor */
typedef struct {
    uint_8     BLENGTH;
    uint_8     BDESCRIPTORTYPE;
    uint_8     BNRPORTS;
    uint_8     WHUBCHARACTERISTICS[2];
    uint_8     BPWRON2PWRGOOD;
    uint_8     BHUBCONTRCURRENT;
    uint_8     DEVICEREMOVABLE[];
/* not used: */
/*    uint_8     PORTPOWERCTRLMASK; */
} HUB_DESCRIPTOR_STRUCT, _PTR_ HUB_DESCRIPTOR_STRUCT_PTR;

typedef struct {
    uint_16    WHUBSTATUS;
    uint_16    WHUBCHANGE;
} HUB_STATUS_STRUCT, _PTR_ HUB_STATUS_STRUCT_PTR;

/* Class specific functions exported by hub class driver */
#ifdef __cplusplus
extern "C" {
#endif

USB_STATUS usb_class_hub_get_app(_usb_device_instance_handle, _usb_interface_descriptor_handle, CLASS_CALL_STRUCT_PTR _PTR_);
USB_STATUS usb_class_hub_cntrl_common(CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uint_8, uint_8, uint_16, uint_16, uint_16);
void usb_class_hub_cntrl_callback(pointer, pointer, uchar_ptr, uint_32, USB_STATUS);
USB_STATUS usb_class_hub_get_descriptor(CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uchar);
USB_STATUS usb_class_hub_set_port_feature(CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uint_8, uint_8);
USB_STATUS usb_class_hub_clear_feature(CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uint_8);
USB_STATUS usb_class_hub_clear_port_feature(CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uint_8, uint_8);
USB_STATUS usb_class_hub_get_status(CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uchar);
USB_STATUS usb_class_hub_get_port_status(CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uint_8, uchar);

USB_STATUS usb_class_hub_wait_for_interrupt(CLASS_CALL_STRUCT_PTR, tr_callback, pointer, uint_8);
void usb_class_hub_int_callback(pointer, pointer, uchar_ptr, uint_32, USB_STATUS);

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/PE/INC_PDD/PIT_PDD.h<|end_filename|>
/*
  PDD layer implementation for peripheral type PIT
  (C) 2010 Freescale, Inc. All rights reserved.

  This file is static and it is generated from API-Factory
*/

#if !defined(PIT_PDD_H_)
#define PIT_PDD_H_

/* ----------------------------------------------------------------------------
   -- Test if supported MCU is active
   ---------------------------------------------------------------------------- */

#if !defined(MCU_ACTIVE)
  // No MCU is active
  #error PIT PDD library: No derivative is active. Place proper #include with PDD memory map before including PDD library.
#elif \
      !defined(MCU_MK10D10) /* PIT */ && \
      !defined(MCU_MK10D5) /* PIT */ && \
      !defined(MCU_MK10D7) /* PIT */ && \
      !defined(MCU_MK10F12) /* PIT */ && \
      !defined(MCU_MK10DZ10) /* PIT */ && \
      !defined(MCU_MK11D5) /* PIT */ && \
      !defined(MCU_MK11D5WS) /* PIT */ && \
      !defined(MCU_MK12D5) /* PIT */ && \
      !defined(MCU_MK20D10) /* PIT */ && \
      !defined(MCU_MK20D5) /* PIT */ && \
      !defined(MCU_MK20D7) /* PIT */ && \
      !defined(MCU_MK20F12) /* PIT */ && \
      !defined(MCU_MK20DZ10) /* PIT */ && \
      !defined(MCU_MK21D5) /* PIT */ && \
      !defined(MCU_MK21D5WS) /* PIT */ && \
      !defined(MCU_MK22D5) /* PIT */ && \
      !defined(MCU_MK30D10) /* PIT */ && \
      !defined(MCU_MK30D7) /* PIT */ && \
      !defined(MCU_MK30DZ10) /* PIT */ && \
      !defined(MCU_MK40D10) /* PIT */ && \
      !defined(MCU_MK40D7) /* PIT */ && \
      !defined(MCU_MK40DZ10) /* PIT */ && \
      !defined(MCU_MK40X256VMD100) /* PIT */ && \
      !defined(MCU_MK50D10) /* PIT */ && \
      !defined(MCU_MK50D7) /* PIT */ && \
      !defined(MCU_MK50DZ10) /* PIT */ && \
      !defined(MCU_MK51D10) /* PIT */ && \
      !defined(MCU_MK51D7) /* PIT */ && \
      !defined(MCU_MK51DZ10) /* PIT */ && \
      !defined(MCU_MK52D10) /* PIT */ && \
      !defined(MCU_MK52DZ10) /* PIT */ && \
      !defined(MCU_MK53D10) /* PIT */ && \
      !defined(MCU_MK53DZ10) /* PIT */ && \
      !defined(MCU_MK60D10) /* PIT */ && \
      !defined(MCU_MK60F12) /* PIT */ && \
      !defined(MCU_MK60F15) /* PIT */ && \
      !defined(MCU_MK60DZ10) /* PIT */ && \
      !defined(MCU_MK60N512VMD100) /* PIT */ && \
      !defined(MCU_MK61F12) /* PIT */ && \
      !defined(MCU_MK61F15) /* PIT */ && \
      !defined(MCU_MK61F12WS) /* PIT */ && \
      !defined(MCU_MK61F15WS) /* PIT */ && \
      !defined(MCU_MK70F12) /* PIT */ && \
      !defined(MCU_MK70F15) /* PIT */ && \
      !defined(MCU_MK70F12WS) /* PIT */ && \
      !defined(MCU_MK70F15WS) /* PIT */ && \
      !defined(MCU_MKL04Z4) /* PIT */ && \
      !defined(MCU_MKL05Z4) /* PIT */ && \
      !defined(MCU_MKL14Z4) /* PIT */ && \
      !defined(MCU_MKL15Z4) /* PIT */ && \
      !defined(MCU_MKL16Z4) /* PIT */ && \
      !defined(MCU_MKL24Z4) /* PIT */ && \
      !defined(MCU_MKL25Z4) /* PIT */ && \
      !defined(MCU_MKL26Z4) /* PIT */ && \
      !defined(MCU_MKL34Z4) /* PIT */ && \
      !defined(MCU_MKL36Z4) /* PIT */ && \
      !defined(MCU_MKL46Z4) /* PIT */ && \
      !defined(MCU_PCK20L4) /* PIT */
  // Unsupported MCU is active
  #error PIT PDD library: Unsupported derivative is active.
#endif

#include "PDD_Types.h"

/* ----------------------------------------------------------------------------
   -- Method symbol definitions
   ---------------------------------------------------------------------------- */

/* PIT channel constants */
#define PIT_PDD_CHANNEL_0 0U                     /**< 0 */
#define PIT_PDD_CHANNEL_1 0x1U                   /**< 1 */
#define PIT_PDD_CHANNEL_2 0x2U                   /**< 2 */
#define PIT_PDD_CHANNEL_3 0x3U                   /**< 3 */

/* Module clock constants */
#define PIT_PDD_CLOCK_ENABLED  0U                /**< Enabled */
#define PIT_PDD_CLOCK_DISABLED PIT_MCR_MDIS_MASK /**< Disabled */

/* Freeze constants */
#define PIT_PDD_TIMERS_RUN     0U                /**< Run */
#define PIT_PDD_TIMERS_STOPPED PIT_MCR_FRZ_MASK  /**< Stopped */


/* ----------------------------------------------------------------------------
   -- GetInterruptMask
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt mask.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: TCTRL[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = PIT_PDD_GetInterruptMask(deviceID, PIT_PDD_CHANNEL_0);
 *      @endcode
 */
#define PIT_PDD_GetInterruptMask(PeripheralBase, ChannelIdx) ( \
    (uint32_t)(PIT_TCTRL_REG(PeripheralBase,(ChannelIdx)) & PIT_TCTRL_TIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- GetInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns interrupt flag bit.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: TFLG[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = PIT_PDD_GetInterruptFlag(deviceID, PIT_PDD_CHANNEL_0);
 *      @endcode
 */
#define PIT_PDD_GetInterruptFlag(PeripheralBase, ChannelIdx) ( \
    (uint32_t)(PIT_TFLG_REG(PeripheralBase,(ChannelIdx)) & PIT_TFLG_TIF_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- EnableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the PIT interrupt.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: TCTRL[ChannelIdx].
 * @par Example:
 *      @code
 *      PIT_PDD_EnableInterrupt(deviceID, PIT_PDD_CHANNEL_0);
 *      @endcode
 */
#define PIT_PDD_EnableInterrupt(PeripheralBase, ChannelIdx) ( \
    PIT_TCTRL_REG(PeripheralBase,(ChannelIdx)) |= \
     PIT_TCTRL_TIE_MASK \
  )

/* ----------------------------------------------------------------------------
   -- DisableInterrupt
   ---------------------------------------------------------------------------- */

/**
 * @brief Disables the PIT interrupt.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: TCTRL[ChannelIdx].
 * @par Example:
 *      @code
 *      PIT_PDD_DisableInterrupt(deviceID, PIT_PDD_CHANNEL_0);
 *      @endcode
 */
#define PIT_PDD_DisableInterrupt(PeripheralBase, ChannelIdx) ( \
    PIT_TCTRL_REG(PeripheralBase,(ChannelIdx)) &= \
     (uint32_t)(~(uint32_t)PIT_TCTRL_TIE_MASK) \
  )

/* ----------------------------------------------------------------------------
   -- ClearInterruptFlag
   ---------------------------------------------------------------------------- */

/**
 * @brief Clears PIT interrupt flag.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: TFLG[ChannelIdx],
 *          LDVAL[ChannelIdx] (depending on the peripheral).
 * @par Example:
 *      @code
 *      PIT_PDD_ClearInterruptFlag(deviceID, PIT_PDD_CHANNEL_0);
 *      @endcode
 */
#define PIT_PDD_ClearInterruptFlag(PeripheralBase, ChannelIdx) ( \
    (PIT_TFLG_REG(PeripheralBase,(ChannelIdx)) = \
     PIT_TFLG_TIF_MASK), \
    (void)PIT_LDVAL_REG(PeripheralBase,(ChannelIdx)) \
  )

/* ----------------------------------------------------------------------------
   -- ModuleClock
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables/disables PIT module clock.
 * @param PeripheralBase Peripheral base address.
 * @param Clock New value of the clock. Use constants from group "Module clock
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PIT_MCR.
 * @par Example:
 *      @code
 *      PIT_PDD_ModuleClock(deviceID, PIT_PDD_CLOCK_ENABLED);
 *      @endcode
 */
#define PIT_PDD_ModuleClock(PeripheralBase, Clock) ( \
    PIT_MCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(PIT_MCR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)PIT_MCR_MDIS_MASK))) | ( \
      (uint32_t)(Clock))) \
  )

/* ----------------------------------------------------------------------------
   -- ModuleFreeze
   ---------------------------------------------------------------------------- */

/**
 * @brief Allows the timers to be stopped when the device enters debug mode.
 * @param PeripheralBase Peripheral base address.
 * @param Freeze New value of the freeze. Use constants from group "Freeze
 *        constants". This parameter is 32 bits wide.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: PIT_MCR.
 * @par Example:
 *      @code
 *      PIT_PDD_ModuleFreeze(deviceID, PIT_PDD_TIMERS_RUN);
 *      @endcode
 */
#define PIT_PDD_ModuleFreeze(PeripheralBase, Freeze) ( \
    PIT_MCR_REG(PeripheralBase) = \
     (uint32_t)(( \
      (uint32_t)(PIT_MCR_REG(PeripheralBase) & (uint32_t)(~(uint32_t)PIT_MCR_FRZ_MASK))) | ( \
      (uint32_t)(Freeze))) \
  )

/* ----------------------------------------------------------------------------
   -- WriteLoadReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Writes value to the load register.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @param Value New content of the load register. This parameter is a 32-bit
 *        value.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: LDVAL[ChannelIdx].
 * @par Example:
 *      @code
 *      PIT_PDD_WriteLoadReg(deviceID, PIT_PDD_CHANNEL_0, 1);
 *      @endcode
 */
#define PIT_PDD_WriteLoadReg(PeripheralBase, ChannelIdx, Value) ( \
    PIT_LDVAL_REG(PeripheralBase,(ChannelIdx)) = \
     (uint32_t)(Value) \
  )

/* ----------------------------------------------------------------------------
   -- ReadLoadReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the load register.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: LDVAL[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = PIT_PDD_ReadLoadReg(deviceID, PIT_PDD_CHANNEL_0);
 *      @endcode
 */
#define PIT_PDD_ReadLoadReg(PeripheralBase, ChannelIdx) ( \
    PIT_LDVAL_REG(PeripheralBase,(ChannelIdx)) \
  )

/* ----------------------------------------------------------------------------
   -- ReadTimerValueReg
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns the content of the current timer value register.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: CVAL[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = PIT_PDD_ReadTimerValueReg(deviceID,
 *      PIT_PDD_CHANNEL_0);
 *      @endcode
 */
#define PIT_PDD_ReadTimerValueReg(PeripheralBase, ChannelIdx) ( \
    PIT_CVAL_REG(PeripheralBase,(ChannelIdx)) \
  )

/* ----------------------------------------------------------------------------
   -- EnableDevice
   ---------------------------------------------------------------------------- */

/**
 * @brief Enables the PIT channel device.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @param State Requested state of PIT channel. This parameter is of "Global
 *        enumeration used for specifying general enable/disable states (PDD_DISABLE
 *        and PDD_ENABLE defined in PDD_Types.h)" type.
 * @return Returns a value of void type.
 * @remarks The macro accesses the following registers: TCTRL[ChannelIdx].
 * @par Example:
 *      @code
 *      PIT_PDD_EnableDevice(deviceID, PIT_PDD_CHANNEL_0, PDD_DISABLE);
 *      @endcode
 */
#define PIT_PDD_EnableDevice(PeripheralBase, ChannelIdx, State) ( \
    PIT_TCTRL_REG(PeripheralBase,(ChannelIdx)) = \
     (uint32_t)(( \
      (uint32_t)(( \
       PIT_TCTRL_REG(PeripheralBase,(ChannelIdx))) & ( \
       (uint32_t)(~(uint32_t)PIT_TCTRL_TEN_MASK)))) | ( \
      (uint32_t)(State))) \
  )

/* ----------------------------------------------------------------------------
   -- GetEnableDeviceStatus
   ---------------------------------------------------------------------------- */

/**
 * @brief Returns current state of PIT channel device.
 * @param PeripheralBase Peripheral base address.
 * @param ChannelIdx PIT channel index. Use constants from group "PIT channel
 *        constants". This parameter is 32 bits wide.
 * @return Returns a 32-bit value.
 * @remarks The macro accesses the following registers: TCTRL[ChannelIdx].
 * @par Example:
 *      @code
 *      uint32_t result = PIT_PDD_GetEnableDeviceStatus(deviceID,
 *      PIT_PDD_CHANNEL_0);
 *      @endcode
 */
#define PIT_PDD_GetEnableDeviceStatus(PeripheralBase, ChannelIdx) ( \
    (uint32_t)(PIT_TCTRL_REG(PeripheralBase,(ChannelIdx)) & PIT_TCTRL_TEN_MASK) \
  )
#endif  /* #if defined(PIT_PDD_H_) */

/* PIT_PDD.h, eof. */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/bsp_cm.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: bsp_cm.c$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*   Clock manager Kinetis BSP specific definitions and function prototypes.
*
*       _bsp_initialize_hardware();
*       _bsp_set_clock_configuration();
*       _bsp_get_clock_configuration();
*       _bsp_get_clock();
*       _bsp_osc_autotrim();
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <bsp_prv.h>

//#define PE_LDD_VERSION

#ifdef PE_LDD_VERSION

extern const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER];

#else /* PE_LDD_VERSION */


/* Clock Manager Errors  */
  #define ERR_OK          CM_ERR_OK               /* OK */
  #define ERR_SPEED       CM_ERR_SPEED            /* This device does not work in the active speed mode. */
  #define ERR_RANGE       CM_ERR_RANGE            /* Parameter out of range. */
  #define ERR_VALUE       CM_ERR_VALUE            /* Parameter of incorrect value. */
  #define ERR_FAILED      CM_ERR_FAILED           /* Requested functionality or process failed. */
  #define ERR_PARAM_MODE  CM_ERR_PARAM_MODE       /* Invalid mode. */


  #define PE_WFI()        _ASM_WFI()

/* The following code is copied from the code generated by Processor Expert */

/*
** ===================================================================
** Global HAL types and constants
** ===================================================================
*/
typedef uint32_t    LDD_TPinMask;         /* Pin mask type. */
typedef uint16_t    LDD_TError;           /* Error type. */
typedef uint32_t    LDD_TEventMask;       /* Event mask type. */
typedef uint8_t     LDD_TClockConfiguration; /* CPU clock configuration type. */

typedef void LDD_TDeviceData;          /* Pointer to private device structure managed and used by HAL components. */

typedef void LDD_TData;                /* General pointer to data. */

typedef void LDD_TUserData;            /* Pointer to this type specifies the user or RTOS specific data will be passed as an event or callback parameter. */

typedef enum {
  DOM_NONE,
  DOM_RUN,
  DOM_WAIT,
  DOM_SLEEP,
  DOM_STOP
} LDD_TDriverOperationMode;            /* Driver operation mode type. */

typedef uint16_t LDD_TDriverState;     /* Driver state type. */

typedef void LDD_TCallbackParam;       /* Pointer to this type specifies the user data to be passed as a callback parameter. */
typedef void (*LDD_TCallback)(LDD_TCallbackParam *CallbackParam); /* Callback type used for definition of callback functions. */



/* Symbols representing MCG modes */
  #define MCG_MODE_FBI                    0x00U
  #define MCG_MODE_BLPI                   0x01U
  #define MCG_MODE_FBE                    0x02U
  #define MCG_MODE_PBE                    0x03U
  #define MCG_MODE_PEE                    0x04U
static const uint8_t MCGTransitionMatrix[5][5] = {
/* This matrix defines which mode is next in the MCG Mode state diagram in transitioning from the
   current mode to a target mode*/
  {  MCG_MODE_FBI,  MCG_MODE_BLPI,  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_FBE }, /* FBI */
  {  MCG_MODE_FBI,  MCG_MODE_BLPI,  MCG_MODE_FBI,  MCG_MODE_FBI,  MCG_MODE_FBI }, /* BLPI */
  {  MCG_MODE_FBI,  MCG_MODE_FBI,  MCG_MODE_FBE,  MCG_MODE_PBE,  MCG_MODE_PBE }, /* FBE */
  {  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_FBE,  MCG_MODE_PBE,  MCG_MODE_PEE }, /* PBE */
  {  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PBE,  MCG_MODE_PEE }  /* PEE */
};

/*
 * lint -esym(765, PE_CpuClockConfigurations) Disable MISRA rule (8.10) checking for symbols (PE_CpuClockConfigurations).
 */

/*
** ===========================================================================
** The array of clock frequencies in configured clock configurations.
** ===========================================================================
*/
const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER] = {
  /* Clock configuration 0 */
  {
    CPU_CORE_CLK_HZ_CONFIG_0,          /* Core clock frequency in clock configuration 0 */
    CPU_BUS_CLK_HZ_CONFIG_0,           /* Bus clock frequency in clock configuration 0 */
    CPU_FLEXBUS_CLK_HZ_CONFIG_0,       /* Flexbus clock frequency in clock configuration 0 */
    CPU_FLASH_CLK_HZ_CONFIG_0,         /* FLASH clock frequency in clock configuration 0 */
    CPU_USB_CLK_HZ_CONFIG_0,           /* USB clock frequency in clock configuration 0 */
    CPU_PLL_FLL_CLK_HZ_CONFIG_0,       /* PLL/FLL clock frequency in clock configuration 0 */
    CPU_MCGIR_CLK_HZ_CONFIG_0,         /* MCG internal reference clock frequency in clock configuration 0 */
    CPU_OSCER_CLK_HZ_CONFIG_0,         /* System OSC external reference clock frequency in clock configuration 0 */
    CPU_ERCLK32K_CLK_HZ_CONFIG_0,      /* External reference clock 32k frequency in clock configuration 0 */
    CPU_MCGFF_CLK_HZ_CONFIG_0          /* MCG fixed frequency clock */
  },
  /* Clock configuration 1 */
  {
    CPU_CORE_CLK_HZ_CONFIG_1,          /* Core clock frequency in clock configuration 1 */
    CPU_BUS_CLK_HZ_CONFIG_1,           /* Bus clock frequency in clock configuration 1 */
    CPU_FLEXBUS_CLK_HZ_CONFIG_1,       /* Flexbus clock frequency in clock configuration 1 */
    CPU_FLASH_CLK_HZ_CONFIG_1,         /* FLASH clock frequency in clock configuration 1 */
    CPU_USB_CLK_HZ_CONFIG_1,           /* USB clock frequency in clock configuration 1 */
    CPU_PLL_FLL_CLK_HZ_CONFIG_1,       /* PLL/FLL clock frequency in clock configuration 1 */
    CPU_MCGIR_CLK_HZ_CONFIG_1,         /* MCG internal reference clock frequency in clock configuration 1 */
    CPU_OSCER_CLK_HZ_CONFIG_1,         /* System OSC external reference clock frequency in clock configuration 1 */
    CPU_ERCLK32K_CLK_HZ_CONFIG_1,      /* External reference clock 32k frequency in clock configuration 1 */
    CPU_MCGFF_CLK_HZ_CONFIG_1          /* MCG fixed frequency clock */
  },
  /* Clock configuration 2 */
  {
    CPU_CORE_CLK_HZ_CONFIG_2,          /* Core clock frequency in clock configuration 2 */
    CPU_BUS_CLK_HZ_CONFIG_2,           /* Bus clock frequency in clock configuration 2 */
    CPU_FLEXBUS_CLK_HZ_CONFIG_2,       /* Flexbus clock frequency in clock configuration 2 */
    CPU_FLASH_CLK_HZ_CONFIG_2,         /* FLASH clock frequency in clock configuration 2 */
    CPU_USB_CLK_HZ_CONFIG_2,           /* USB clock frequency in clock configuration 2 */
    CPU_PLL_FLL_CLK_HZ_CONFIG_2,       /* PLL/FLL clock frequency in clock configuration 2 */
    CPU_MCGIR_CLK_HZ_CONFIG_2,         /* MCG internal reference clock frequency in clock configuration 2 */
    CPU_OSCER_CLK_HZ_CONFIG_2,         /* System OSC external reference clock frequency in clock configuration 2 */
    CPU_ERCLK32K_CLK_HZ_CONFIG_2,      /* External reference clock 32k frequency in clock configuration 2 */
    CPU_MCGFF_CLK_HZ_CONFIG_2          /* MCG fixed frequency clock */
  }
};

/* Global variables */
static uint8_t ClockConfigurationID = CPU_CLOCK_CONFIG_0; /* Active clock configuration */


/* Local function prototypes */
LDD_TError Cpu_MCGAutoTrim(uint8_t ClockSelect);
LDD_TError Cpu_VLPModeDisable(void);
LDD_TError Cpu_VLPModeEnable(void);
void       Cpu_EnableInt(void);
void       Cpu_DisableInt(void);
uint32_t   Cpu_GetLLSWakeUpFlags(void);
LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID);
uint8_t    Cpu_GetClockConfiguration(void);
LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr);

void       __pe_initialize_hardware(void);
void       PE_low_level_init(void);


/*
** ===================================================================
**     Method      :  LDD_SetClockConfiguration (component MK60FN1M0LQ15)
**
**     Description :
**         This method changes the clock configuration of all LDD
**         components in the project.
** ===================================================================
*/
void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration)
{
  (void)ClockConfiguration;            /* Parameter is not used, suppress unused argument warning */
}

/*
** ===================================================================
**     Method      :  Cpu_MCGAutoTrim (component MK60FN1M0LQ15)
**
**     Description :
**         This method uses MCG auto trim feature to trim internal
**         reference clock. This method can be used only in a clock
**         configuration which derives its bus clock from external
**         reference clock (<MCG mode> must be one of the following
**         modes - FEE, FBE, BLPE, PEE, PBE) and if value of <Bus clock>
**         is in the range <8; 16>MHz.
**         The slow internal reference clock is trimmed to the value
**         selected by <Slow internal reference clock [kHz]> property. 
**         The fast internal reference clock will be trimmed to value
**         4MHz.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ClockSelect     - Selects which internal
**                           reference clock will be trimmed.
**                           0 ... slow (32kHz) internal reference clock
**                           will be trimmed
**                           > 0 ... fast (4MHz) internal reference
**                           clock will be trimmed
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_SPEED - The method does not work in the
**                           active clock configuration.
**                           ERR_FAILED - Autotrim process failed.
** ===================================================================
*/
LDD_TError Cpu_MCGAutoTrim(uint8_t ClockSelect)
{
  switch (ClockConfigurationID)
  {
  case CPU_CLOCK_CONFIG_1:
    if ( ClockSelect == 0x00U )
    {
      /* Slow internal reference clock */
      MCG_ATCVH = 0x1EU;
      MCG_ATCVL = 0x0AU;
    }
    else
    {
      /* Fast internal reference clock */
      MCG_ATCVH = 0x1FU;
      MCG_ATCVL = 0x80U;
    }
    break;
  default:
    return ERR_SPEED;
  }
  if ( ClockSelect == 0x00U )
  {
    /* MCG_SC: ATME=1,ATMS=0,ATMF=0,FLTPRSRV=0,FCRDIV=0,LOCS0=0 */
    MCG_SC = (uint8_t)0x82U;           /* Start trimming of the slow internal reference clock */
  }
  else
  {
    /* MCG_SC: ATME=1,ATMS=1,ATMF=0,FLTPRSRV=0,FCRDIV=0,LOCS0=0 */
    MCG_SC = (uint8_t)0xC2U;           /* Start trimming of the fast internal reference clock */
  }
  while ((MCG_SC & MCG_SC_ATME_MASK) != 0x00U) /* Wait until autotrim completes */
  {}
  if ( (MCG_SC & MCG_SC_ATMF_MASK) == 0x00U )
  {
    return ERR_OK;                     /* Trim operation completed successfully */
  }
  else
  {
    return ERR_FAILED;                 /* Trim operation failed */
  }
}

/*
** ===================================================================
**     Method      :  Cpu_GetLLSWakeUpFlags (component MK60FN1M0LQ15)
**
**     Description :
**         This method returns the current status of the LLWU wake-up
**         flags indicating which wake-up source caused the MCU to exit
**         LLS or VLLSx low power mode.
**         The following predefined constants can be used to determine
**         the wake-up source:
**         LLWU_EXT_PIN0, ... LLWU_EXT_PIN15 - external pin 0 .. 15
**         caused the wake-up
**         LLWU_INT_MODULE0 .. LLWU_INT_MODULE7 - internal module 0..15
**         caused the wake-up.
**     Parameters  : None
**     Returns     :
**         ---             - Returns the current status of the LLWU
**                           wake-up flags indicating which wake-up
**                           source caused the MCU to exit LLS or VLLSx
**                           low power mode.
** ===================================================================
*/
uint32_t Cpu_GetLLSWakeUpFlags(void)
{
  uint32_t Flags;

  Flags = LLWU_F1;
  Flags |= (uint32_t)((uint32_t)LLWU_F2 << 8U);
  Flags |= (uint32_t)((uint32_t)LLWU_F3 << 16U);
  Flags |= LLWU_FILT1;
  Flags |= LLWU_FILT2;
  return Flags;
}

static void Cpu_SetMCGModePEE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePEE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PEE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModePBE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeFBE(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeBLPI(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeBLPI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to BLPI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCGModeFBI(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static void Cpu_SetMCG(uint8_t CLKMode);
/*
** ===================================================================
**     Method      :  Cpu_SetMCG (component MK60FN1M0LQ15)
**
**     Description :
**         This method updates the MCG according the requested clock 
**         source setting.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

static uint8_t Cpu_GetCurrentMCGMode(void);
/*
** ===================================================================
**     Method      :  Cpu_GetCurrentMCGMode (component MK60FN1M0LQ15)
**
**     Description :
**         This method returns the active MCG mode
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePEE (component MK60N512MD100)
**
**     Description :
**         This method sets the MCG to PEE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModePEE(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 0U:
    /* Switch to PEE Mode */
    /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC0_CR = OSC_CR_ERCLKEN_MASK;
    /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = OSC_CR_ERCLKEN_MASK;
    /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03));
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
    MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));




    while ((MCG_S & 0x0CU) != 0x0CU) /* Wait until output of the PLL is selected */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModePBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to PBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModePBE(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 0U:
    /* Switch to PBE Mode */
    /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC0_CR = OSC_CR_ERCLKEN_MASK;
    /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = OSC_CR_ERCLKEN_MASK;
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03));
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK);
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
    MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));
    while ((MCG_S & 0x0CU) != 0x08U) /* Wait until external reference clock is selected as MCG output */
    {}
    while ((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) /* Wait until PLL locked */
    {}
    break;
  case 1U:
    /* Switch to PBE Mode */
    /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC0_CR = 0x00U;
    /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = 0x00U;
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK);
    while ((MCG_S & 0x0CU) != 0x08U) /* Wait until external reference clock is selected as MCG output */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBE (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBE mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeFBE(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 0U:
    /* Switch to FBE Mode */
    /* MCG_C7: OSCSEL=0 */
    MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK);
    /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC0_CR = OSC_CR_ERCLKEN_MASK;
    /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = OSC_CR_ERCLKEN_MASK;
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03));
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
    MCG_C6 = MCG_C6_VDIV0(0x0E);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);
    while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) /* Check that the oscillator is running */
    {}
    while ((MCG_S & MCG_S_IREFST_MASK) != 0x00U) /* Check that the source of the FLL reference clock is the external reference clock. */
    {}
    while ((MCG_S & 0x0CU) != 0x08U) /* Wait until external reference clock is selected as MCG output */
    {}
    break;
  case 1U:
    /* Switch to FBE Mode */
    /* MCG_C7: OSCSEL=0 */
    MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK);
    /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC0_CR = 0x00U;
    /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = 0x00U;
    /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
    MCG_C6 = MCG_C6_VDIV0(0x00);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);
    while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) /* Check that the oscillator is running */
    {}
    while ((MCG_S & MCG_S_IREFST_MASK) != 0x00U) /* Check that the source of the FLL reference clock is the external reference clock. */
    {}
    while ((MCG_S & 0x0CU) != 0x08U) /* Wait until external reference clock is selected as MCG output */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeBLPI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to BLPI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeBLPI(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 1U:
    /* Switch to BLPI Mode */
    /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = MCG_C1_CLKS(0x01) |
             MCG_C1_FRDIV(0x00) |
             MCG_C1_IREFS_MASK |
             MCG_C1_IRCLKEN_MASK;
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=1,IRCS=1 */
    MCG_C2 = MCG_C2_RANGE0(0x02) |
             MCG_C2_EREFS0_MASK |
             MCG_C2_LP_MASK |
             MCG_C2_IRCS_MASK;
    /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC0_CR = 0x00U;
    /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = 0x00U;
    while ((MCG_S & MCG_S_IREFST_MASK) == 0x00U) /* Check that the source of the FLL reference clock is the internal reference clock. */
    {}
    while ((MCG_S & MCG_S_IRCST_MASK) == 0x00U) /* Check that the fast external reference clock is selected. */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCGModeFBI (component MK60FN1M0LQ15)
**
**     Description :
**         This method sets the MCG to FBI mode.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCGModeFBI(uint8_t CLKMode)
{
  switch (CLKMode)
  {
  case 0U:
    /* Switch to FBI Mode */
    /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=0,IREFSTEN=0 */
    MCG_C1 = (MCG_C1_CLKS(0x01) | MCG_C1_FRDIV(0x00) | MCG_C1_IREFS_MASK);
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK);
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
    /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC0_CR = OSC_CR_ERCLKEN_MASK;
    /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = OSC_CR_ERCLKEN_MASK;
    /* MCG_C7: OSCSEL=0 */
    MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
    MCG_C6 = MCG_C6_VDIV0(0x0E);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);       /* 7 */
    while ((MCG_S & MCG_S_IREFST_MASK) == 0x00U) /* Check that the source of the FLL reference clock is the internal reference clock. */
    {}
    while ((MCG_S & 0x0CU) != 0x04U) /* Wait until internal reference clock is selected as MCG output */
    {}
    break;
  case 1U:
    /* Switch to FBI Mode */
    /* MCG_C1: CLKS=1,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
    MCG_C1 = MCG_C1_CLKS(0x01) |
             MCG_C1_FRDIV(0x00) |
             MCG_C1_IREFS_MASK |
             MCG_C1_IRCLKEN_MASK;
    /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
    MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK);
    /* MCG_C4: DMX32=0,DRST_DRS=0 */
    MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
    /* OSC0_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC0_CR = 0x00U;
    /* OSC1_CR: ERCLKEN=0,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    OSC1_CR = 0x00U;
    /* MCG_C7: OSCSEL=0 */
    MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
    /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
    MCG_C5 = MCG_C5_PRDIV0(0x00);
    /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
    MCG_C6 = MCG_C6_VDIV0(0x00);
    /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
    MCG_C11 = MCG_C11_PRDIV1(0x00);
    /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
    MCG_C12 = MCG_C12_VDIV1(0x00);       /* 7 */
    while ((MCG_S & MCG_S_IREFST_MASK) == 0x00U) /* Check that the source of the FLL reference clock is the internal reference clock. */
    {}
    while ((MCG_S & 0x0CU) != 0x04U) /* Wait until internal reference clock is selected as MCG output */
    {}
    break;
  default:
    break;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetMCG (component MK60FN1M0LQ15)
**
**     Description :
**         This method updates the MCG according the requested clock 
**         source setting.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void Cpu_SetMCG(uint8_t CLKMode)
{
  uint8_t TargetMCGMode = 0x00U;
  uint8_t NextMCGMode;

  switch (CLKMode)
  {
  case 0U:
    TargetMCGMode = MCG_MODE_PEE;
    break;
  case 1U:
    TargetMCGMode = MCG_MODE_BLPI;
    break;
  default:
    break;
  }
  NextMCGMode = Cpu_GetCurrentMCGMode(); /* Identify the currently active MCG mode */
  do
  {
    NextMCGMode = MCGTransitionMatrix[NextMCGMode][TargetMCGMode]; /* Get the next MCG mode on the path to the target MCG mode */
    switch (NextMCGMode)             /* Set the next MCG mode on the path to the target MCG mode */
    {
    case MCG_MODE_FBI:
      Cpu_SetMCGModeFBI(CLKMode);
      break;
    case MCG_MODE_BLPI:
      Cpu_SetMCGModeBLPI(CLKMode);
      break;
    case MCG_MODE_FBE:
      Cpu_SetMCGModeFBE(CLKMode);
      break;
    case MCG_MODE_PBE:
      Cpu_SetMCGModePBE(CLKMode);
      break;
    case MCG_MODE_PEE:
      Cpu_SetMCGModePEE(CLKMode);
      break;
    default:
      break;
    }
  }
  while (TargetMCGMode != NextMCGMode); /* Loop until the target MCG mode is set */
}

/*
** ===================================================================
**     Method      :  Cpu_GetCurrentMCGMode (component MK60FN1M0LQ15)
**
**     Description :
**         This method returns the active MCG mode
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
uint8_t Cpu_GetCurrentMCGMode(void)
{
  switch (MCG_C1  & MCG_C1_CLKS_MASK)
  {
  case  0x00U:
    return MCG_MODE_PEE;
  case 0x40U:
    /* Internal reference clock is selected */
    if ( (MCG_C2 & MCG_C2_LP_MASK) == 0x00U )
    {
      /* Low power mode is disabled */
      return MCG_MODE_FBI;
    }
    else
    {
      /* Low power mode is enabled */
      return MCG_MODE_BLPI;
    }
  case 0x80U:
    if ( (MCG_C6 & MCG_C6_PLLS_MASK) == 0x00U )
    {
      /* FLL is selected */
      return MCG_MODE_FBE;
    }
    else
    {
      /* PLL is selected */
      return MCG_MODE_PBE;
    }
  default:
    return 0x00U;
  }
}

/*
** ===================================================================
**     Method      :  Cpu_SetClockConfiguration (component MK60FN1M0LQ15)
**
**     Description :
**         Calling of this method will cause the clock configuration
**         change and reconfiguration of all components according to
**         the requested clock configuration setting.
**     Parameters  :
**         NAME            - DESCRIPTION
**         ModeID          - Clock configuration identifier
**     Returns     :
**         ---             - ERR_OK - OK.
**                           ERR_RANGE - Mode parameter out of range
** ===================================================================
*/
LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID)
{
  if ( ModeID > 0x02U )
  {
    return ERR_RANGE;                  /* Undefined clock configuration requested requested */
  }
  switch (ModeID)
  {
  case CPU_CLOCK_CONFIG_0:
    if ( ClockConfigurationID == 2U )
    {
      /* Clock configuration 0 and clock configuration 2 use different clock configuration */
      /* MCG_C6: CME0=0 */
      MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
      /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
      SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                    SIM_CLKDIV1_OUTDIV2(0x03) |
                    SIM_CLKDIV1_OUTDIV3(0x07) |
                    SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
      if ( (MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U )
      {
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                                                         MCG_SC_FCRDIV(0x06)
                                                         )) | (uint8_t)(
                                                                        MCG_SC_FCRDIV(0x01)
                                                                        ));
      }
      else
      {
        /* MCG_C2: IRCS=0 */
        MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                                                         MCG_SC_FCRDIV(0x06)
                                                         )) | (uint8_t)(
                                                                        MCG_SC_FCRDIV(0x01)
                                                                        ));
        /* MCG_C2: IRCS=1 */
        MCG_C2 |= MCG_C2_IRCS_MASK;
      }
      Cpu_SetMCG(0U);                /* Update clock source setting */
      /* MCG_C6: CME0=1 */
      MCG_C6 |= MCG_C6_CME0_MASK;    /* Enable the clock monitor */
    }
    /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=2,OUTDIV4=5,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) |
                  SIM_CLKDIV1_OUTDIV2(0x01) |
                  SIM_CLKDIV1_OUTDIV3(0x02) |
                  SIM_CLKDIV1_OUTDIV4(0x05); /* Update system prescalers */
    /* SIM_SOPT2: PLLFLLSEL=1 */
    SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
                                                              SIM_SOPT2_PLLFLLSEL(0x02)
                                                              )) | (uint32_t)(
                                                                              SIM_SOPT2_PLLFLLSEL(0x01)
                                                                              ));                  /* Select PLL 0 as a clock source for various peripherals */
    /* SIM_SOPT1: OSC32KSEL=1 */
    SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; /* RTC oscillator drives 32 kHz clock for various peripherals */
    break;
  case CPU_CLOCK_CONFIG_1:
    if ( ClockConfigurationID == 2U )
    {
      /* Clock configuration 1 and clock configuration 2 use different clock configuration */
      /* MCG_C6: CME0=0 */
      MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
      /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
      SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                    SIM_CLKDIV1_OUTDIV2(0x03) |
                    SIM_CLKDIV1_OUTDIV3(0x07) |
                    SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
      if ( (MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U )
      {
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                                                         MCG_SC_FCRDIV(0x06)
                                                         )) | (uint8_t)(
                                                                        MCG_SC_FCRDIV(0x01)
                                                                        ));
      }
      else
      {
        /* MCG_C2: IRCS=0 */
        MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);
        /* MCG_SC: FCRDIV=1 */
        MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                                                         MCG_SC_FCRDIV(0x06)
                                                         )) | (uint8_t)(
                                                                        MCG_SC_FCRDIV(0x01)
                                                                        ));
        /* MCG_C2: IRCS=1 */
        MCG_C2 |= MCG_C2_IRCS_MASK;
      }
      Cpu_SetMCG(0U);                /* Update clock source setting */
      /* MCG_C6: CME0=1 */
      MCG_C6 |= MCG_C6_CME0_MASK;    /* Enable the clock monitor */
    }
    /* SIM_CLKDIV1: OUTDIV1=9,OUTDIV2=9,OUTDIV3=9,OUTDIV4=9,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x09) |
                  SIM_CLKDIV1_OUTDIV2(0x09) |
                  SIM_CLKDIV1_OUTDIV3(0x09) |
                  SIM_CLKDIV1_OUTDIV4(0x09); /* Update system prescalers */
    /* SIM_SOPT2: PLLFLLSEL=1 */
    SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
                                                              SIM_SOPT2_PLLFLLSEL(0x02)
                                                              )) | (uint32_t)(
                                                                              SIM_SOPT2_PLLFLLSEL(0x01)
                                                                              ));                  /* Select PLL 0 as a clock source for various peripherals */
    /* SIM_SOPT1: OSC32KSEL=1 */
    SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; /* RTC oscillator drives 32 kHz clock for various peripherals */
    break;
  case CPU_CLOCK_CONFIG_2:
    /* MCG_C6: CME0=0 */
    MCG_C6 &= (uint8_t)~(uint8_t)(MCG_C6_CME0_MASK); /* Disable the clock monitor */
    /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,OUTDIV3=7,OUTDIV4=7,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) |
                  SIM_CLKDIV1_OUTDIV2(0x03) |
                  SIM_CLKDIV1_OUTDIV3(0x07) |
                  SIM_CLKDIV1_OUTDIV4(0x07); /* Set the system prescalers to safe value */
    if ( (MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U )
    {
      /* MCG_SC: FCRDIV=1 */
      MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                                                       MCG_SC_FCRDIV(0x06)
                                                       )) | (uint8_t)(
                                                                      MCG_SC_FCRDIV(0x01)
                                                                      ));
    }
    else
    {
      /* MCG_C2: IRCS=0 */
      MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK);
      /* MCG_SC: FCRDIV=1 */
      MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)(
                                                       MCG_SC_FCRDIV(0x06)
                                                       )) | (uint8_t)(
                                                                      MCG_SC_FCRDIV(0x01)
                                                                      ));
      /* MCG_C2: IRCS=1 */
      MCG_C2 |= MCG_C2_IRCS_MASK;
    }
    Cpu_SetMCG(1U);                  /* Update clock source setting */
    /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV3=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) |
                  SIM_CLKDIV1_OUTDIV2(0x00) |
                  SIM_CLKDIV1_OUTDIV3(0x00) |
                  SIM_CLKDIV1_OUTDIV4(0x03); /* Update system prescalers */
    /* SIM_SOPT2: PLLFLLSEL=3 */
    SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x03); /* Select Core clock as a clock source for various peripherals */
    /* SIM_SOPT1: OSC32KSEL=0 */
    SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL_MASK); /* System oscillator drives 32 kHz clock for various peripherals */
    break;
  default:
    break;
  }
  LDD_SetClockConfiguration(ModeID);   /* Call all LDD components to update the clock configuration */
  ClockConfigurationID = ModeID;       /* Store clock configuration identifier */
  return ERR_OK;
}

/*
** ===================================================================
**     Method      :  Cpu_GetClockConfiguration (component MK60FN1M0LQ15)
**
**     Description :
**         Returns the active clock configuration identifier. The
**         method is enabled only if more than one clock configuration
**         is enabled in the component.
**     Parameters  : None
**     Returns     :
**         ---             - Active clock configuration identifier
** ===================================================================
*/
uint8_t Cpu_GetClockConfiguration(void)
{
  return ClockConfigurationID;         /* Return the actual clock configuration identifier */
}

/*
** ===================================================================
**     Method      :  Cpu_SetOperationMode (component MK60FN1M0LQ15)
**
**     Description :
**         This method requests to change the component's operation
**         mode (RUN, WAIT, SLEEP, STOP). The target operation mode
**         will be entered immediately. 
**         See <Operation mode settings> for further details of the
**         operation modes mapping to low power modes of the cpu.
**     Parameters  :
**         NAME            - DESCRIPTION
**         OperationMode   - Requested driver
**                           operation mode
**         ModeChangeCallback - Callback to
**                           notify the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**       * ModeChangeCallbackParamPtr 
**                           - Pointer to callback parameter to notify
**                           the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_PARAM_MODE - Invalid operation mode
** ===================================================================
*/
LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr)
{
  (void)ModeChangeCallback;           /* Parameter is not used, suppress unused argument warning */
  (void)ModeChangeCallbackParamPtr;   /* Parameter is not used, suppress unused argument warning */
  switch (OperationMode)
  {
  case DOM_RUN:
    /* SCB_SCR: SLEEPDEEP=0,SLEEPONEXIT=0 */
    SCB_SCR &= (uint32_t)~(uint32_t)(
                                     SCB_SCR_SLEEPDEEP_MASK |
                                       SCB_SCR_SLEEPONEXIT_MASK
                                     );
    if  ( ClockConfigurationID != 2U )
    {
      if ( (MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3) ) /* If in PBE mode, switch to PEE. PEE to PBE transition was caused by wakeup from low power mode. */
      {
        /* MCG_C1: CLKS=0,IREFS=0 */
        MCG_C1 &= (uint8_t)~(uint8_t)((MCG_C1_CLKS(0x03) | MCG_C1_IREFS_MASK));
        while ((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) /* Wait for PLL lock */
        {}
      }
    }
    break;
  case DOM_WAIT:
    /* SCB_SCR: SLEEPDEEP=0 */
    SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPDEEP_MASK);
    /* SCB_SCR: SLEEPONEXIT=0 */
    SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPONEXIT_MASK);
    PE_WFI();
    break;
  case DOM_SLEEP:
    /* SCB_SCR: SLEEPDEEP=1 */
    SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;
    /* SMC_PMCTRL: STOPM=0 */
    SMC_PMCTRL &= (uint8_t)~(uint8_t)(SMC_PMCTRL_STOPM(0x07));
    (void)(SMC_PMCTRL == 0U);        /* Dummy read of SMC_PMCTRL to ensure the register is written before enterring low power mode */
    /* SCB_SCR: SLEEPONEXIT=1 */
    SCB_SCR |= SCB_SCR_SLEEPONEXIT_MASK;
    PE_WFI();
    break;
  case DOM_STOP:
    /* Clear LLWU flags */
    /* LLWU_F1: WUF7=1,WUF6=1,WUF5=1,WUF4=1,WUF3=1,WUF2=1,WUF1=1,WUF0=1 */
    LLWU_F1 = LLWU_F1_WUF7_MASK |
              LLWU_F1_WUF6_MASK |
              LLWU_F1_WUF5_MASK |
              LLWU_F1_WUF4_MASK |
              LLWU_F1_WUF3_MASK |
              LLWU_F1_WUF2_MASK |
              LLWU_F1_WUF1_MASK |
              LLWU_F1_WUF0_MASK;
    /* LLWU_F2: WUF15=1,WUF14=1,WUF13=1,WUF12=1,WUF11=1,WUF10=1,WUF9=1,WUF8=1 */
    LLWU_F2 = LLWU_F2_WUF15_MASK |
              LLWU_F2_WUF14_MASK |
              LLWU_F2_WUF13_MASK |
              LLWU_F2_WUF12_MASK |
              LLWU_F2_WUF11_MASK |
              LLWU_F2_WUF10_MASK |
              LLWU_F2_WUF9_MASK |
              LLWU_F2_WUF8_MASK;
    /* LLWU_F3: MWUF7=1,MWUF6=1,MWUF5=1,MWUF4=1,MWUF3=1,MWUF2=1,MWUF1=1,MWUF0=1 */
    LLWU_F3 = LLWU_F3_MWUF7_MASK |
              LLWU_F3_MWUF6_MASK |
              LLWU_F3_MWUF5_MASK |
              LLWU_F3_MWUF4_MASK |
              LLWU_F3_MWUF3_MASK |
              LLWU_F3_MWUF2_MASK |
              LLWU_F3_MWUF1_MASK |
              LLWU_F3_MWUF0_MASK;
    /* LLWU_FILT1: FILTF=1 */
    LLWU_FILT1 |= LLWU_FILT1_FILTF_MASK;
    /* LLWU_FILT2: FILTF=1 */
    LLWU_FILT2 |= LLWU_FILT2_FILTF_MASK;
    /* SCB_SCR: SLEEPONEXIT=0 */
    SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPONEXIT_MASK);
    /* SCB_SCR: SLEEPDEEP=1 */
    SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;
    /* SMC_PMCTRL: STOPM=3 */
    SMC_PMCTRL = (uint8_t)((SMC_PMCTRL & (uint8_t)~(uint8_t)(
                                                             SMC_PMCTRL_STOPM(0x04)
                                                             )) | (uint8_t)(
                                                                            SMC_PMCTRL_STOPM(0x03)
                                                                            ));
    (void)(SMC_PMCTRL == 0U);        /* Dummy read of SMC_PMCTRL to ensure the register is written before enterring low power mode */
    PE_WFI();
    break;
  default:
    return ERR_PARAM_MODE;
  }
  return ERR_OK;
}


/*
** ===================================================================
**     Method      :  __pe_initialize_hardware (component MK60N512MD100)
**
**     Description :
**         Initializes the whole system like timing, external bus, etc.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/


void __pe_initialize_hardware(void)
{
  /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/

  /*** ### MK60FN1M0VLQ12 "Cpu" init code ... ***/
  /*** PE initialization code after reset ***/
  /* SIM_SCGC6: RTC=1 */
  SIM_SCGC6 |= SIM_SCGC6_RTC_MASK;
  if ( (RTC_CR & RTC_CR_OSCE_MASK) == 0u ) /* Only if the OSCILLATOR is not already enabled */
  {
    /* RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
    RTC_CR &= (uint32_t)~(uint32_t)(
                                    RTC_CR_SC2P_MASK |
                                      RTC_CR_SC4P_MASK |
                                      RTC_CR_SC8P_MASK |
                                      RTC_CR_SC16P_MASK
                                    );
    /* RTC_CR: OSCE=1 */
    RTC_CR |= RTC_CR_OSCE_MASK;
    /* RTC_CR: CLKO=0 */
    RTC_CR &= (uint32_t)~(uint32_t)(RTC_CR_CLKO_MASK);
  }
  /* Disable the WDOG module */
  /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */
  WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */
  /* WDOG_UNLOCK: WDOGUNLOCK=0xD928 */
  WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */
  /* WDOG_STCTRLH: ??=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,??=0,??=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */
  WDOG_STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) |
                 WDOG_STCTRLH_WAITEN_MASK |
                 WDOG_STCTRLH_STOPEN_MASK |
                 WDOG_STCTRLH_ALLOWUPDATE_MASK |
                 WDOG_STCTRLH_CLKSRC_MASK |
                 0x0100U;
  /* System clock initialization */
  /* SIM_SCGC5: PORTC=1,PORTA=1 */
  SIM_SCGC5 |= (SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTA_MASK); /* Enable clock gate for ports to enable pin routing */
  if ( *((uint8_t *)0x03FFU) != 0xFFU )
  {
    MCG_C3 = *((uint8_t *)0x03FFU);
    MCG_C4 = (MCG_C4 & 0xE0U) | ((*((uint8_t *)0x03FEU)) & 0x1FU);
  }
  /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=2,OUTDIV4=5,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) |
                SIM_CLKDIV1_OUTDIV2(0x01) |
                SIM_CLKDIV1_OUTDIV3(0x02) |
                SIM_CLKDIV1_OUTDIV4(0x05); /* Update system prescalers */
  /* SIM_SOPT2: PLLFLLSEL=1 */
  SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
                                                            SIM_SOPT2_PLLFLLSEL(0x02)
                                                            )) | (uint32_t)(
                                                                            SIM_SOPT2_PLLFLLSEL(0x01)
                                                                            ));                      /* Select PLL 0 as a clock source for various peripherals */
  /* SIM_SOPT1: OSC32KSEL=1 */
  SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; /* RTC oscillator drives 32 kHz clock for various peripherals */
  /* SIM_SCGC1: OSC1=1 */
  SIM_SCGC1 |= SIM_SCGC1_OSC1_MASK;
  /* PORTA_PCR18: ISF=0,MUX=0 */
  PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
  /* PORTA_PCR19: ISF=0,MUX=0 */
  PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
  /* Switch to FBE Mode */
  /* MCG_C7: OSCSEL=0 */
  MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK);
  /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
  MCG_C2 = MCG_C2_RANGE0(0x02) |
           MCG_C2_HGO0_MASK |
           MCG_C2_EREFS0_MASK |
           MCG_C2_IRCS_MASK;
  /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=1,SC8P=1,SC16P=0 */
  OSC0_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK);
  /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
  OSC1_CR = OSC_CR_ERCLKEN_MASK;
  /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
  MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
  /* MCG_C4: DMX32=0,DRST_DRS=0 */
  MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
  /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */
  MCG_C5 = MCG_C5_PRDIV0(0x00);
  /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0x0E */
  MCG_C6 = MCG_C6_VDIV0(0x0E);
  /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */
  MCG_C11 = MCG_C11_PRDIV1(0x00);
  /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */
  MCG_C12 = MCG_C12_VDIV1(0x00);
  while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) /* Check that the oscillator is running */
  {}
  while ((MCG_S & MCG_S_IREFST_MASK) != 0x00U) /* Check that the source of the FLL reference clock is the external reference clock. */
  {}
  while ((MCG_S & 0x0CU) != 0x08U)    /* Wait until external reference clock is selected as MCG output */
  {}
  /* Switch to PBE Mode */
  /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x0E */
  MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x0E));
  while ((MCG_S & 0x0CU) != 0x08U)    /* Wait until external reference clock is selected as MCG output */
  {}
  while ((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) /* Wait until PLL locked */
  {}
  /* Switch to PEE Mode */
  /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
  MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
  while ((MCG_S & 0x0CU) != 0x0CU)    /* Wait until output of the PLL is selected */
  {}
  /* MCG_C6: CME0=1 */
  MCG_C6 |= MCG_C6_CME0_MASK;          /* Enable the clock monitor */
  /*** End of PE initialization code after reset ***/

  /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/

}



/*
** ===================================================================
**     Method      :  PE_low_level_init (component MK60FN1M0LQ15)
**
**     Description :
**         Initializes beans and provides common register initialization. 
**         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 PE_low_level_init(void)
{
  /* Initialization of the SIM module */
  /* SIM_SOPT2: CMTUARTPAD=0 */
  SIM_SOPT2 &= (uint32_t)~0x0800UL;
  /* PORTA_PCR4: ISF=0,MUX=7 */
  PORTA_PCR4 = (uint32_t)((PORTA_PCR4 & (uint32_t)~0x01000000UL) | (uint32_t)0x0700UL);
  /* Initialization of the RCM module */
  /* RCM_RPFW: RSTFLTSEL=0 */
  RCM_RPFW &= (uint8_t)~(uint8_t)0x1FU;
  /* RCM_RPFC: RSTFLTSS=0,RSTFLTSRW=0 */
  RCM_RPFC &= (uint8_t)~(uint8_t)0x07U;
  /* Initialization of the PMC module */
  /* PMC_LVDSC1: LVDACK=1,LVDIE=0,LVDRE=1,LVDV=0 */
  PMC_LVDSC1 = (uint8_t)((PMC_LVDSC1 & (uint8_t)~(uint8_t)0x23U) | (uint8_t)0x50U);
  /* PMC_LVDSC2: LVWACK=1,LVWIE=0,LVWV=0 */
  PMC_LVDSC2 = (uint8_t)((PMC_LVDSC2 & (uint8_t)~(uint8_t)0x23U) | (uint8_t)0x40U);
  /* PMC_REGSC: BGEN=0,ACKISO=0,BGBE=0 */
  PMC_REGSC &= (uint8_t)~(uint8_t)0x19U;
  /* Initialization of the LLWU module */
  /* LLWU_PE1: WUPE3=0,WUPE2=0,WUPE1=0,WUPE0=0 */
  LLWU_PE1 = (uint8_t)0x00U;
  /* LLWU_PE2: WUPE7=0,WUPE6=0,WUPE5=0,WUPE4=0 */
  LLWU_PE2 = (uint8_t)0x00U;
  /* LLWU_PE3: WUPE11=0,WUPE10=0,WUPE9=0,WUPE8=0 */
  LLWU_PE3 = (uint8_t)0x00U;
  /* LLWU_PE4: WUPE15=0,WUPE14=0,WUPE13=0,WUPE12=0 */
  LLWU_PE4 = (uint8_t)0x00U;
  /* LLWU_ME: WUME7=0,WUME5=0,WUME4=0,WUME3=0,WUME2=0,WUME1=0,WUME0=1 */
  LLWU_ME = (uint8_t)((LLWU_ME & (uint8_t)~(uint8_t)0xBEU) | (uint8_t)0x01U);
  /* LLWU_FILT1: FILTF=1,FILTE=0,??=0,FILTSEL=0 */
  LLWU_FILT1 = (uint8_t)0x80U;
  /* LLWU_FILT2: FILTF=1,FILTE=0,??=0,FILTSEL=0 */
  LLWU_FILT2 = (uint8_t)0x80U;
  /* LLWU_RST: ??=0,??=0,??=0,??=0,??=0,??=0,LLRSTE=0,RSTFILT=0 */
  LLWU_RST = (uint8_t)0x00U;
  /* SMC_PMPROT: ??=0,??=0,AVLP=1,??=0,ALLS=1,??=0,AVLLS=0,??=0 */
  SMC_PMPROT = (uint8_t)0x28U;         /* Setup Power mode protection register */

}


#endif /* PE_LDD_VERSION */

/* [IN] runtime clock configuration */
uint16_t _bsp_set_clock_configuration(const BSP_CLOCK_CONFIGURATION clock_configuration)
{
  uint32_t    system_clock;
  uint16_t    cpu_error = ERR_OK;

  cpu_error = Cpu_SetClockConfiguration((uint8_t)clock_configuration);
  if ( cpu_error != ERR_OK )
  {
    return cpu_error;
  }

  /* Get system clock for active clock configuration */
  system_clock = _cm_get_clock(clock_configuration, CM_CLOCK_SOURCE_CORE);

  systick_config(system_clock, BSP_ALARM_FREQUENCY);

  return ERR_OK;
}


BSP_CLOCK_CONFIGURATION _bsp_get_clock_configuration(void)
{
  return (BSP_CLOCK_CONFIGURATION)Cpu_GetClockConfiguration();
}


uint32_t _bsp_get_clock(const BSP_CLOCK_CONFIGURATION clock_configuration,const CM_CLOCK_SOURCE clock_source)
{
  if (    (clock_configuration < CPU_CLOCK_CONFIG_NUMBER)
       && (clock_source        < sizeof(PE_CpuClockConfigurations) / sizeof(uint32_t))
       )
  {
    return *(((uint32_t *)&(PE_CpuClockConfigurations[clock_configuration])) + clock_source);
  }
  else
  {
    return 0;
  }
}


uint16_t _bsp_osc_autotrim(void)
{
  uint16_t        CPU_Error = ERR_OK;
  uint8_t         MCG_Mode;
  /*
   * Its assumed that before auto trimming process
   * the MCG is switched to a clock configuration
   * which derives its bus clock from external reference clock
   * and (<MCG mode> is set to one of the following modes
   * FEE, FBE, BLPE, PEE, PBE) and if value of <Bus clock>
   * is in the range <8; 16>MHz.
   */

  /* Auto trim Slow internal reference clock */
  CPU_Error = Cpu_MCGAutoTrim(0);
  if ( CPU_Error != ERR_OK ) return CPU_Error;

  /* Auto trim Fast internal reference clock */
  CPU_Error = Cpu_MCGAutoTrim(1);
  if ( CPU_Error != ERR_OK ) return CPU_Error;

  return ERR_OK;

}

void _bsp_low_level_init(void)
{
  PE_low_level_init();
}



void _bsp_initialize_hardware(void)
{
  __pe_initialize_hardware();
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/cm/cm.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: cm.h$
* $Version : 3.8.2.0$
* $Date    : Aug-29-2011$
*
* Comments:
*   Clock manager header file.
*
*END************************************************************************/

#ifndef __cm_h__
    #define __cm_h__

#ifdef __cplusplus
extern "C" {
#endif


/***************************************************************************
**
**  Clock manager public types and constants
**
***************************************************************************/
#define CM_ERR_OK           0x00U /* OK */
#define CM_ERR_SPEED        0x01U /* This device does not work in the active speed mode. */
#define CM_ERR_RANGE        0x02U /* Parameter out of range. */
#define CM_ERR_VALUE        0x03U /* Parameter of incorrect value. */
#define CM_ERR_FAILED       0x1BU /* Requested functionality or process failed. */
#define CM_ERR_PARAM_MODE   0x81U /* Invalid mode. */
    
_mqx_int _cm_set_clock_configuration
(
    /* [IN] runtime clock configuration */
    const BSP_CLOCK_CONFIGURATION clock_configuration
);

BSP_CLOCK_CONFIGURATION _cm_get_clock_configuration
(
    void
);

uint32_t _cm_get_clock
(
    /* [IN] clock configuration */
    const BSP_CLOCK_CONFIGURATION   clock_configuration,
    /* [IN] clock source index */
    const CM_CLOCK_SOURCE           clock_source
);


#ifdef __cplusplus
}
#endif


#endif /* __cm_h__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/mcf522xx/adt_pit_mcf522xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adt_pit_mcf522xx.c$
* $Version : 3.6.7.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the ADC driver CPU specific functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <fio.h>
#include <fio_prv.h>
#include "io.h"
#include "adc.h"
#include "adc_prv.h"
#include "adc_conf.h"
#include "adc_mcf522xx_prv.h"

#if BSPCFG_ENABLE_ADC

/* Peripherals pointer */
static VMCF522XX_PIT_STRUCT_PTR  mcf522xx_timer_ptr;

/* State values for timer */
static struct 
{
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle;
    uint_32  running_mask;
} adt_internal;

/* static variables storing information for deinitialization */
static void (_CODE_PTR_ old_isr_timer)(pointer);
static pointer          old_isr_timer_param;


/* Declarations of static functions */
static void _adt_scheduler(_mqx_uint time);
static void _adt_hw_set_wait(uint_32 time);
static uint_32 _adt_hw_get_time();
static _mqx_int _adt_hw_run();
static _mqx_int _adt_hw_stop();

/* Declarations of IRQ handlers */
static void adt_setup_timer(uint_32);
static void adt_cpu_isr(pointer);

/* Let's say that we want to set preset and prescaler value.
** The 32b. value representing [ prescaler | preset ] represents some time.
** If the 32b. value is 2^i, then the time is:
** 2^i / BSP_SYSTEM_CLOCK / 10^-6 [usec] =
** (1 << i) * 10^6 / BSP_SYSTEM_CLOCK [usec] =
** (10^6 << i) / BSP_SYSTEM_CLOCK [usec] =
** (0xF4240 << i) / BSP_SYSTEM_CLOCK [usec] = 
** (0x3D09 << (6 + i)) / BSP_SYSTEM_CLOCK [usec] =
** ((0x3D09 << (6 + i + 12 + 32)) / BSP_SYSTEM_CLOCK) >> (12 + 32) [usec] =
** ((0x3D09 << (6 + 12 + 32)) / BSP_SYSTEM_CLOCK) >> (12 + 32 - i) [usec] =
** TIMER_CONST >> (12 + 32 - i)
*/
#define TIMER_CONST (uint_64)(0xF424000000000000 / (BSP_SYSTEM_CLOCK / 2))

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_ioctl
* Returned Value   : _mqx_int
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/
_mqx_int _adt_hw_ioctl(MQX_FILE_PTR f, _mqx_uint cmd, pointer param_ptr)
{
    return IO_ERROR_INVALID_IOCTL_CMD;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_install
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific initialization for ADC driver
*
*END*********************************************************************/
_mqx_int _adt_hw_install(char_ptr drivername, ADC_DRIVER_BUNDLE_PTR adc_d_bundle, pointer init_struct)
{
    adt_internal.adc_d_bundle = adc_d_bundle;
    return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_init
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific initialization for ADC driver
*
*END*********************************************************************/
_mqx_int _adt_hw_init(MQX_FILE_PTR f, ADT_PTR adt)
{ /* Body */
#if PSP_MQX_CPU_IS_MCF5225X
    VMCF5225_STRUCT_PTR mcf522xx_ptr;
#elif PSP_MQX_CPU_IS_MCF5223X
    VMCF5223_STRUCT_PTR mcf522xx_ptr;
#elif PSP_MQX_CPU_IS_MCF5222X
    VMCF5222_STRUCT_PTR mcf522xx_ptr;
#else
    #error This CPU is not supported here
#endif
    
    _mqx_uint        div_register;
    _mqx_int         i;
    uint_32          frq_system_kHz;
    uint_16          prescaler, preset;
    uint_32          result;

    /* Prepare pointers to peripherals */
    mcf522xx_ptr = _PSP_GET_IPSBAR();
    mcf522xx_timer_ptr = &mcf522xx_ptr->PIT[BSP_ADC_TIMER];

    mcf522xx_timer_ptr->PCSR = 0x0038;
   
    old_isr_timer_param = _int_get_isr_data(BSP_ADC_TIMER_INTERRUPT_VECTOR);
    old_isr_timer = _int_install_isr(BSP_ADC_TIMER_INTERRUPT_VECTOR,
        adt_cpu_isr, NULL);
    if (NULL == old_isr_timer) {
        _int_install_isr(BSP_ADC_TIMER_INTERRUPT_VECTOR, old_isr_timer, old_isr_timer_param);
        return ADC_ERROR_ISR; /* could not install new interrupt routine */
    }

    /* We have two timer scales:
    ** the first one is generic driver time (32 bit)
    ** the second one is low level driver time (31 bit) and presents directly preset + prescaler settings
    ** and the relation between them is:
    ** Eq.1: generic_time = lowlevel_time << shift
    **
    ** From above, following implies:
    ** 1) lowlevel_time (31 bit) cannot fit all the scale range of generic_time
    ** (and to solve that, generic_time wait will be achieved by sequential lowlevel_time periods
    ** 2) generic_time has the smallest resolution of "shift" bits. Shift should be found to be
    ** less or equal to 1usec.
    ** 3) all generic_time(s) from init structures must be recomputed to match Eq.1
    **/
    result = (uint_32)(TIMER_CONST >> (12 + 32 - 31));
    for (i = 16 + 15; i > 0; i--) { /* preset_value = 0xFFFF, preset = 0x10000, prescaler = 1 << n, i = n + (log2 (preset)) */
        if (result == 0) { /* we reached the lowest resolution (lower than 1 usec) */
            /* store the exponent of 2 between 2 timer scales */
            adt->shift = i;
            break;
        }
        result = result >> 1;
    }

#if PSP_MQX_CPU_IS_MCF5225X
    /* Setup ISR levels for timer */
    _mcf5225_int_init(BSP_ADC_TIMER_INTERRUPT_VECTOR, BSP_ADC_TIMER_INTERRUPT_LEVEL, BSP_ADC_TIMER_INTERRUPT_SUBLEVEL, TRUE);
#elif PSP_MQX_CPU_IS_MCF5223X
    /* Setup ISR levels for timer */
    _mcf5223_int_init(BSP_ADC_TIMER_INTERRUPT_VECTOR, BSP_ADC_TIMER_INTERRUPT_LEVEL, BSP_ADC_TIMER_INTERRUPT_SUBLEVEL, TRUE);
#elif PSP_MQX_CPU_IS_MCF5222X
    /* Setup ISR levels for timer */
    _mcf5222_int_init(BSP_ADC_TIMER_INTERRUPT_VECTOR, BSP_ADC_TIMER_INTERRUPT_LEVEL, BSP_ADC_TIMER_INTERRUPT_SUBLEVEL, TRUE);
#else
        #error This CPU is not supported here
#endif
    
    return ADC_OK;
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_deinit
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific deinitialization for ADC driver
*
*END*********************************************************************/
_mqx_int _adt_hw_deinit(MQX_FILE_PTR f, ADT_PTR adt)
{
    mcf522xx_timer_ptr->PCSR &= 0x007e; /* stop timer */
    if (old_isr_timer != NULL)
        _int_install_isr(BSP_ADC_TIMER_INTERRUPT_VECTOR, old_isr_timer, old_isr_timer_param);
    
    return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_channel_init
* Returned Value   : int_32
* Comments         :
*    Returns result of HW channel initialization
*
*END*********************************************************************/
_mqx_int _adt_hw_channel_init(MQX_FILE_PTR f, ADT_CHANNEL_PTR adt_ch)
{ /* Body */
    _mqx_uint i, j = 0;

    /* we need to recompute timers (cross-multiplication):
    ** source (init value)                                                dest (working value)
    ** ---------------------------------------------------------------------------------------
    ** ((0x3D09 << (6 + 12 + 32)) / BSP_SYSTEM_CLOCK) >> (12 + 32 - i)    2^i
    ** ((0x3D09 << (6 + 12 + 32)) / BSP_SYSTEM_CLOCK) >> (12 + 32 - 31)   2^31
    ** input [usec]                                                       output
    **
    ** output = input * (TIMER_CONST >> (12 + 32 - 31)) * 2^31 = 
    */
    adt_ch->g.period = (((uint_64) adt_ch->g.period << 31) / (TIMER_CONST >> (12 + 32 - 31))) >> adt_internal.adc_d_bundle->adt->shift; /* note: we are losing bits for timer setting */;
    adt_ch->g.offset = (((uint_64) adt_ch->g.offset << 31) / (TIMER_CONST >> (12 + 32 - 31))) >> adt_internal.adc_d_bundle->adt->shift; /* note: we are losing bits for timer setting */;

    return ADC_OK;
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_channel_deinit
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific deinitialization for ADC channel
*
*END*********************************************************************/
_mqx_int _adt_hw_channel_deinit(MQX_FILE_PTR f, ADT_CHANNEL_PTR adt_ch)
{
    return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_scheduler
* Returned Value   : 
* Comments         : Schedules next ADC conversion and informs low-level
*                    driver about that time. Low-level driver must call
*                    this scheduler in that time.
*                    This function can run in interrupt (depends on
                     SW timer implementation)
*END*********************************************************************/
static void _adt_scheduler(_mqx_uint time)
{ /* gets actual time as parameter */
    ADT_CHANNEL_PTR *adt_ch = adt_internal.adc_d_bundle->adt_ch;
    ADC_CHANNEL_PTR *adc_ch = adt_internal.adc_d_bundle->adc_ch;
    _mqx_int i;
    _mqx_uint wait;
    _mqx_int rem;

    if (adt_internal.running_mask) { /* if there is any channel in the mask for measurement */
        _adc_hw_measure(adt_internal.running_mask); /* measure channels */

        for (i = 0; i < ADC_MAX_CHANNELS; i++) { /* update time of last measurement in channels */
            if (!adt_ch[i] || !(adt_internal.running_mask & (1 << adc_ch[i]->g.source)))
                continue;
            
            adt_ch[i]->g.time = time;
        }
    }
    
    /* look for closest AD conversion */
    for (i = 0, wait = -1, adt_internal.running_mask = 0; i < ADC_MAX_CHANNELS; i++) {
        if (adt_ch[i] && adt_ch[i]->g.runtime_flags & ADC_CHANNEL_RUNNING) {
            /* compute remaining time to next measurement:
            ** elapsed time from last measurement: time - adc_ch[i]->time
            ** remaining time to next measurement: adc_ch[i]->period - elapsed
            */
            rem = adt_ch[i]->g.period - (time - adt_ch[i]->g.time);
        
            if (rem < 0)
                rem = 0;
        
            if (rem < wait) {
                wait = rem;
                adt_internal.running_mask = (1 << adc_ch[i]->g.source);
            }
            else if (rem == wait) {
                adt_internal.running_mask |= (1 << adc_ch[i]->g.source);
            }
        }
    }
    
    /* test if any conversion should be performed next time */
    if (adt_internal.running_mask) {
        if (!adt_internal.adc_d_bundle->adt->g.run) {
            _adt_hw_run();
            adt_internal.adc_d_bundle->adt->g.run = 1;
        }
    }
    else {
        _adt_hw_stop();
        adt_internal.adc_d_bundle->adt->g.run = 0;
    }

    /* inform low level driver that next dispatch call should be done in 'wait' time */
    _adt_hw_set_wait(wait);
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_trigger
* Returned Value   : IO_OK
* Comments         : Starts channel measurement or more channels defined
*                    by trigger mask
*
*END*********************************************************************/
_mqx_int _adt_trigger(MQX_FILE_PTR f, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask)
{
    ADT_CHANNEL_PTR *adt_ch = adt_internal.adc_d_bundle->adt_ch;
    _mqx_int i;
    _mqx_uint time;

    _int_disable();
    time = _adt_hw_get_time();
    
    if (channel) {
        channel->time = time + channel->offset;
        channel->samples = channel->samples_preset;
        channel->runtime_flags |= ADC_CHANNEL_RUNNING | ADC_CHANNEL_RESUMED;
    }
    else {
        for (i = 0; i < ADC_MAX_CHANNELS; i++) {
            if (adt_ch[i] && (adt_ch[i]->g.trigger & mask)) {
                adt_ch[i]->g.time = time + adt_ch[i]->g.offset;
                /* period was subtracted because next scheduling will add it */
                adt_ch[i]->g.samples = adt_ch[i]->g.samples_preset;
                adt_ch[i]->g.runtime_flags |= ADC_CHANNEL_RUNNING | ADC_CHANNEL_RESUMED;
            }
        }
    }
    
    adt_internal.running_mask = 0;
    _adt_scheduler(time);

    _int_enable();
    return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_pause
* Returned Value   : IO_OK
* Comments         : Pauses measurement of single channel, or more channels
*                    defined by trigger mask
*
*END*********************************************************************/
_mqx_int _adt_pause(MQX_FILE_PTR f, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask)
{
    ADT_CHANNEL_PTR *adt_ch = adt_internal.adc_d_bundle->adt_ch;
    _mqx_int i;
    _mqx_uint time;

    _int_disable();

    if (channel) {
        channel->runtime_flags &= ~ADC_CHANNEL_RESUMED;
    }
    else {
        for (i = 0; i < ADC_MAX_CHANNELS; i++) {
            if (adt_ch[i] && (adt_ch[i]->g.trigger & mask)) {
                adt_ch[i]->g.runtime_flags &= ~ADC_CHANNEL_RESUMED;
            }
        }
    }

    _int_enable();
    return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_resume
* Returned Value   : IO_OK
* Comments         : Resumes measurement of single paused channel, or more
*                    channels defined by trigger mask
*
*END*********************************************************************/
_mqx_int _adt_resume(MQX_FILE_PTR f, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask)
{
    ADT_CHANNEL_PTR *adt_ch = adt_internal.adc_d_bundle->adt_ch;
    _mqx_int i;

    _int_disable();

    if (channel) {
        channel->runtime_flags |= ADC_CHANNEL_RESUMED;
    }
    else {
        for (i = 0; i < ADC_MAX_CHANNELS; i++) {
            if (adt_ch[i] && (adt_ch[i]->g.trigger & mask)) {
                adt_ch[i]->g.runtime_flags |= ADC_CHANNEL_RESUMED;
            }
        }
    }

    _int_enable();
    return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_stop
* Returned Value   : IO_OK
* Comments         : Stops (resets) measurement of single channel, or more
*                    channels defined by trigger mask
*
*END*********************************************************************/
_mqx_int _adt_stop(MQX_FILE_PTR f, ADT_CHANNEL_GENERIC_PTR channel, ADT_TRIGGER_MASK mask)
{
    ADT_CHANNEL_PTR *adt_ch = adt_internal.adc_d_bundle->adt_ch;
    _mqx_int i;
    _mqx_uint time;

    _int_disable();
    time = _adt_hw_get_time();
        
    if (channel) {
        channel->runtime_flags &= ~ADC_CHANNEL_RUNNING;
    }
    else {
        for (i = 0; i < ADC_MAX_CHANNELS; i++) {
            if (adt_ch[i] && (adt_ch[i]->g.trigger & mask)) {
                    adt_ch[i]->g.runtime_flags &= ~ADC_CHANNEL_RUNNING;
            }
        }
    }
    
    adt_internal.running_mask = 0;
    _adt_scheduler(time);

    _int_enable();
    return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_set_wait
* Returned Value   : void
* Comments         : sets the timer to elapse (to call dispatcher) in 'time'
*
*END**********************************************************************/
static void _adt_hw_set_wait(uint_32 time)
{
    /* dispatcher inform us to wait time since now */
    adt_internal.adc_d_bundle->adt->time_to_next_adc = time;
    adt_setup_timer(time);
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_get_time
* Returned Value   : uint_32 - actual absolute time
* Comments         : 
*
*END**********************************************************************/
static uint_32 _adt_hw_get_time()
{
    uint_32 elapsed;

    elapsed = adt_internal.adc_d_bundle->adt->time_to_next_irq * (mcf522xx_timer_ptr->PMR - mcf522xx_timer_ptr->PCNTR) / (mcf522xx_timer_ptr->PMR + 1);
    return adt_internal.adc_d_bundle->adt->dispatch_time + elapsed;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : adt_setup_timer
* Returned Value   : void
* Comments         : sets HW timer to be able to measure time effectivelly
*
*END**********************************************************************/
static void adt_setup_timer(uint_32 time)
{
    uint_32  j;
    _mqx_int i;
    uint_16  preset, prescaler;

    /* search for next IRQ time */
    j = (time << adt_internal.adc_d_bundle->adt->shift) & 0x7FFFFFFF;
    if (time != (j >> adt_internal.adc_d_bundle->adt->shift)) { /* only 31 bits for timer setting */
        /* Till now, we need to have all AD conversions done, because we are going to modify ADC
        ** interrupt internal structures.
        */
        preset = 0xFFFF;  /* use maximum time for preset */
        prescaler = 15 << 8; /* use maximum prescaler  */
        adt_internal.adc_d_bundle->adt->time_to_next_irq = 0x80000000 >> adt_internal.adc_d_bundle->adt->shift;
        adt_internal.adc_d_bundle->adt->dispatch_next = FALSE;
    }
    else {
        /* compute time needed for next ADC: searching for first 1 */
        for (i = 0; i < 15; i++, j <<= 1) {
            if (j & 0x40000000) {
                preset = 0xFFFF; /* set maximum preset */
                prescaler = (14 - i) << 8; /* set prescaler */
                adt_internal.adc_d_bundle->adt->time_to_next_irq = 0x40000000 >> (i + adt_internal.adc_d_bundle->adt->shift);
                if (j == 0x40000000)
                    adt_internal.adc_d_bundle->adt->dispatch_next = TRUE;
                else
                    adt_internal.adc_d_bundle->adt->dispatch_next = FALSE;
                goto Set_Timer;
            }
        }
        preset = j >> i; /* set preset */
        if (preset)
            preset--;
        prescaler = 0 << 8; /* set prescaler */
        adt_internal.adc_d_bundle->adt->time_to_next_irq = j >> (15 + adt_internal.adc_d_bundle->adt->shift);
        adt_internal.adc_d_bundle->adt->dispatch_next = TRUE;
    }

Set_Timer:
    /* setup timer constants that correspond to time_to_next_irq */
    mcf522xx_timer_ptr->PCSR &= 0x007e; /* stop timer */
    mcf522xx_timer_ptr->PCNTR = mcf522xx_timer_ptr->PMR = preset;
    mcf522xx_timer_ptr->PCSR |= prescaler | 0x0021; /* starts timer */
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_run
* Returned Value   : void
* Comments         : starts timer
*
*END*********************************************************************/
static _mqx_int _adt_hw_run()
{
    return 0;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adt_hw_stop
* Returned Value   : void
* Comments         : stops timer
*
*END*********************************************************************/
_mqx_int _adt_hw_stop()
{
    return adt_internal.adc_d_bundle->adt->dispatch_time = 0;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : adt_cpu_isr
* Returned Value   : void
* Comments         : PIT (= timer) interrupt for ADC driver planning
*
*END*********************************************************************/
static void adt_cpu_isr
    (
        /* [IN] the address of the device specific information */
        pointer parameter
    )
{
    _mqx_int i, j;
    uint_16  prescaler;
    uint_16  preset;
    boolean  performed_adc;

    adt_internal.adc_d_bundle->adt->time_to_next_adc -= adt_internal.adc_d_bundle->adt->time_to_next_irq; /* update remaining time to ADC */
    adt_internal.adc_d_bundle->adt->dispatch_time += adt_internal.adc_d_bundle->adt->time_to_next_irq; /* update absolute time */
    
    if (adt_internal.adc_d_bundle->adt->dispatch_next) {
        mcf522xx_timer_ptr->PCSR &= 0xfffe; /* stop timer */
        _adt_scheduler(adt_internal.adc_d_bundle->adt->dispatch_time);
    }
    else
        adt_setup_timer(adt_internal.adc_d_bundle->adt->time_to_next_adc);
}

#endif // BSPCFG_ENABLE_ADC
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/generic/mfs_misc.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs_misc.c$
* $Version : 3.8.15.0$
* $Date    : Jul-25-2012$
*
* Comments:
*
*   This file contains functions to lock and unlock the drive.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>

#include "mfs.h"
#include "mfs_prv.h"


#if MFSCFG_READ_ONLY_CHECK

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_lock 
* Returned Value   :  error code
* Comments  : Locks the drive. Cannot be called from an ISR.
*      
*      
*END*---------------------------------------------------------------------*/

boolean MFS_is_read_only
    (
    MQX_FILE_PTR                 mfs_fd_ptr,
    MFS_DRIVE_STRUCT_PTR         drive_ptr
    )
{
#if MFSCFG_READ_ONLY_CHECK_ALWAYS    
    uint_32                      id[3];
#endif
    if ( drive_ptr == NULL )
    {
        if ( mfs_fd_ptr == NULL )
        {
            return FALSE;
        }
        else if ( mfs_fd_ptr->DEV_PTR == NULL )
        {
            return FALSE;
        }
        else
        {
            drive_ptr = mfs_fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
        }
    }
#if MFSCFG_READ_ONLY_CHECK_ALWAYS    
    if (ioctl (drive_ptr->DEV_FILE_PTR, IO_IOCTL_DEVICE_IDENTIFY, id) != MQX_OK) 
    {
        return FALSE;
    }
    drive_ptr->READ_ONLY = (id[IO_IOCTL_ID_ATTR_ELEMENT] & IO_DEV_ATTR_WRITE) == 0;
#endif
    return drive_ptr->READ_ONLY;
}  

#endif


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : MFS_lock 
* Returned Value   :  error code
* Comments  : Locks the drive. Cannot be called from an ISR.
*      
*      
*END*---------------------------------------------------------------------*/


_mfs_error MFS_lock
    (
    MQX_FILE_PTR                 mfs_fd_ptr,
    MFS_DRIVE_STRUCT_PTR _PTR_   drive_ptr
    )
{
    _mfs_error error_code;

    if ( mfs_fd_ptr == NULL )
    {
        error_code = MFS_ERROR_INVALID_DRIVE_HANDLE;
    }
    else if ( mfs_fd_ptr->DEV_PTR == NULL )
    {
        error_code = MFS_ERROR_INVALID_DRIVE_HANDLE;
    }
    else
    {
        *drive_ptr = mfs_fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
        _lwsem_wait(&(*drive_ptr)->SEM);
        error_code = MFS_NO_ERROR;
    }  
    return error_code;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_lock_dos_disk
* Returned Value   :  error code
* Comments  : Locks the drive and verifies that it is a dos disk.
*             Cannot be called from an ISR.
*      
*END*---------------------------------------------------------------------*/

_mfs_error MFS_lock_dos_disk
    (
    MQX_FILE_PTR                 mfs_fd_ptr,
    MFS_DRIVE_STRUCT_PTR _PTR_   drive_ptr
    )
{
    _mfs_error error_code;

    if ( mfs_fd_ptr == NULL )
    {
        error_code = MFS_ERROR_INVALID_DRIVE_HANDLE;
    }
    else if ( mfs_fd_ptr->DEV_PTR == NULL )
    {
        error_code = MFS_ERROR_INVALID_DRIVE_HANDLE;
    }
    else
    {
        *drive_ptr = mfs_fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
        _lwsem_wait(&(*drive_ptr)->SEM);
        if ( !(*drive_ptr)->DOS_DISK )
        {
            _lwsem_post(&(*drive_ptr)->SEM);
            error_code =  MFS_NOT_A_DOS_DISK;
        }
        else
        {
            error_code = MFS_NO_ERROR;
        }  
    }  
    return error_code;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_lock_handle
* Returned Value   :  error code
* Comments  :  Locks the drive using a file handle and verifies that it is a 
*              DOS disk. Also extracts the file handle from the MQX_FILE_PTR
*              Cannot be called from an ISR.
*      
*END*---------------------------------------------------------------------*/

_mfs_error MFS_lock_handle
    (
    MQX_FILE_PTR               fd_ptr, 
    MFS_DRIVE_STRUCT_PTR _PTR_ drive_ptr, 
    MFS_HANDLE_PTR _PTR_       handle_ptr
    )
{
    _mfs_error error_code;

    if ( fd_ptr == NULL )
    {
        error_code = MFS_ERROR_INVALID_DRIVE_HANDLE;
    }
    else if ( fd_ptr->DEV_PTR == NULL )
    {
        error_code = MFS_ERROR_INVALID_DRIVE_HANDLE;
    }
    else if ( fd_ptr->DEV_DATA_PTR == NULL )
    {
        error_code = MFS_ERROR_INVALID_FILE_HANDLE;
    }
    else
    {
        *handle_ptr = fd_ptr->DEV_DATA_PTR;
        *drive_ptr = fd_ptr->DEV_PTR->DRIVER_INIT_PTR;

        _lwsem_wait(&(*drive_ptr)->SEM);
        if ( !(*drive_ptr)->DOS_DISK )
        {
            _lwsem_post(&(*drive_ptr)->SEM);
            error_code =  MFS_NOT_A_DOS_DISK;
        }
        else
        {
            error_code = MFS_NO_ERROR;
        }  
    }  
    return error_code;
}  


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_unlock
* Returned Value   :  error code
* Comments  :  Unlocks the drive.
*      
*END*---------------------------------------------------------------------*/
_mfs_error MFS_unlock
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    boolean                 flush_if_mixed_mode
    )
{
    _mfs_error error = MFS_NO_ERROR;
    
    boolean  flush = FALSE;

    switch ( drive_ptr->WRITE_CACHE_POLICY )
    {
        case  MFS_MIXED_MODE_CACHE:     
            flush = flush_if_mixed_mode;
            break;

        case  MFS_WRITE_BACK_CACHE: 
            flush = FALSE;
            break;

        case  MFS_WRITE_THROUGH_CACHE:  
        default:   
            flush = TRUE;
            break;

    }

    if ( flush )
    {
        error = MFS_Flush_directory_sector_buffer(drive_ptr);
        
        if (error == MFS_NO_ERROR)
            error = MFS_Flush_data_sector_buffer(drive_ptr);
    }

    switch ( drive_ptr->FAT_CACHE_POLICY )
    {
        case  MFS_MIXED_MODE_CACHE:     
            flush = flush_if_mixed_mode;
            break;

        case  MFS_WRITE_BACK_CACHE: 
            flush = FALSE;
            break;

        case  MFS_WRITE_THROUGH_CACHE:  
        default:   
            flush = TRUE;
            break;

    }

    if (error == MFS_NO_ERROR && flush)
    {
        error = MFS_Flush_fat_cache(drive_ptr);
    }

    _lwsem_post(&drive_ptr->SEM);
    
    return error;
} 


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_mem_alloc
* Returned Value   :  
* Comments  :  
*      
*END*---------------------------------------------------------------------*/

pointer MFS_mem_alloc(_mem_size size)
{
    if ( _MFS_pool_id )
    {
        return _mem_alloc_from(_MFS_pool_id, size);
    }
    else
    {
        return _mem_alloc_uncached(size);
    }
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_mem_alloc_zero
* Returned Value   :  
* Comments  :  
*      
*END*---------------------------------------------------------------------*/

pointer MFS_mem_alloc_zero(_mem_size size)
{
    if ( _MFS_pool_id )
    {
        return _mem_alloc_zero_from(_MFS_pool_id, size);
    }
    else
    {
        pointer p = _mem_alloc_uncached(size);
        
        if (p != NULL) 
        {
            _mem_zero(p, size);
        }

        return p;
    }
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_mem_alloc_system
* Returned Value   :  
* Comments  :  
*      
*END*---------------------------------------------------------------------*/

pointer MFS_mem_alloc_system(_mem_size size)
{
    if ( _MFS_pool_id )
    {
        return _mem_alloc_system_from(_MFS_pool_id, size);
    }
    else
    {
        return _mem_alloc_system_uncached(size);
    }
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_mem_alloc_system_zero
* Returned Value   :  
* Comments  :  
*      
*END*---------------------------------------------------------------------*/

pointer MFS_mem_alloc_system_zero(_mem_size size)
{
    if ( _MFS_pool_id )
    {
        return _mem_alloc_system_zero_from(_MFS_pool_id, size);
    }
    else
    {
        /* memory must be uncached, otherwise reading sector may fail on 54418 */
        return _mem_alloc_system_zero_uncached(size);
    }
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_alloc_path
* Returned Value   :  
* Comments  :  
*      
*END*---------------------------------------------------------------------*/

_mfs_error MFS_alloc_path(char_ptr * path_ptr_ptr)
{
    char_ptr path_ptr;

    path_ptr = MFS_mem_alloc_system(PATHNAME_SIZE + 1);
    if ( path_ptr == NULL )
    {
        return MFS_INSUFFICIENT_MEMORY;
    }
    _mem_set_type(path_ptr, MEM_TYPE_MFS_PATHNAME);
    *path_ptr_ptr = path_ptr;
    return MFS_NO_ERROR;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_alloc_2paths
* Returned Value   :  
* Comments  :  
*      
*END*---------------------------------------------------------------------*/

_mfs_error MFS_alloc_2paths(char_ptr * path1_ptr_ptr,char_ptr * path2_ptr_ptr)
{
    _mfs_error error_code;
    char_ptr path1_ptr,path2_ptr;

    error_code = MFS_alloc_path(&path1_ptr);
    if ( error_code == MFS_NO_ERROR )
    {
        error_code = MFS_alloc_path(&path2_ptr);
        if ( error_code == MFS_NO_ERROR )
        {
            *path1_ptr_ptr = path1_ptr;
            *path2_ptr_ptr = path2_ptr;
        }
        else
        {
            MFS_free_path(path1_ptr);
        }
    }

    return error_code;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_free_path
* Returned Value   :  
* Comments  :  
*      
*END*---------------------------------------------------------------------*/

boolean MFS_free_path(char_ptr path_ptr)
{
    if ( path_ptr != NULL )
    {
        _mem_free(path_ptr);
        return TRUE;
    }

    return FALSE;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Error_text
* Returned Value   : char_ptr
* Comments         :
*    Takes a MFS error code and returns the error description ptr.
*
*END*----------------------------------------------------------------------*/

char_ptr  MFS_Error_text
    (
    _mfs_error error_code
    )
{
    switch ( error_code )
    {
        case MFS_NO_ERROR :
            return("MFS NO ERROR");
        case MFS_INVALID_FUNCTION_CODE :
            return("MFS INVALID FUNCTION CODE");
        case MFS_FILE_NOT_FOUND :
            return("MFS FILE NOT FOUND");
        case MFS_PATH_NOT_FOUND :
            return("MFS PATH NOT FOUND");
        case MFS_ACCESS_DENIED :
            return("MFS ACCESS DENIED");
        case MFS_INVALID_HANDLE :
            return("MFS INVALID HANDLE");
        case MFS_INSUFFICIENT_MEMORY :
            return("MFS INSUFFICIENT MEMORY");
        case MFS_INVALID_MEMORY_BLOCK_ADDRESS :
            return("MFS INVALID MEMORY BLOCK ADDRESS");
        case MFS_ATTEMPT_TO_REMOVE_CURRENT_DIR :
            return("MFS ATTEMPT TO REMOVE CURRENT DIR");
        case MFS_DISK_IS_WRITE_PROTECTED :
            return("MFS DISK IS WRITE PROTECTED");
        case MFS_BAD_DISK_UNIT :
            return("MFS BAD DISK UNIT");
        case MFS_INVALID_LENGTH_IN_DISK_OPERATION:
            return("MFS INVALID LENGTH IN DISK OPERATION" );
        case MFS_NOT_A_DOS_DISK :
            return("MFS NOT A DOS DISK");
        case MFS_SECTOR_NOT_FOUND :
            return("MFS SECTOR NOT FOUND");
        case MFS_WRITE_FAULT :
            return("MFS WRITE FAULT");
        case MFS_READ_FAULT :
            return("MFS READ FAULT");
        case MFS_SHARING_VIOLATION :
            return("MFS SHARING VIOLATION");
        case MFS_FILE_EXISTS :
            return("MFS FILE EXISTS");
        case MFS_ALREADY_ASSIGNED :
            return("MFS ALREADY ASSIGNED");
        case MFS_INVALID_PARAMETER :
            return("MFS INVALID PARAMETER");
        case MFS_DISK_FULL :
            return("MFS DISK FULL");
        case MFS_ROOT_DIR_FULL:
            return("MFS ROOT DIR FULL");
        case MFS_EOF :
            return("MFS EOF");
        case MFS_CANNOT_CREATE_DIRECTORY:
            return("MFS CANNOT CREATE DIRECTORY");
        case MFS_NOT_INITIALIZED:
            return( "MFS NOT INITIALIZED" );
        case MFS_OPERATION_NOT_ALLOWED:
            return("MFS OPERATION NOT ALLOWED");
        case MFS_ERROR_INVALID_DRIVE_HANDLE:
            return("MFS INVALID DRIVE HANDLE" );
        case MFS_ERROR_INVALID_FILE_HANDLE:
            return( "MFS INVALID FILE HANDLE" );
        case MFS_ERROR_UNKNOWN_FS_VERSION:
            return( "MFS UNKNOWN FILESYSTEM VERSION" );
        case MFS_LOST_CHAIN:
            return( "MFS LOST CHAIN" );
        case MFS_INVALID_DEVICE :
            return( "MFS INVALID DEVICE" );
        case MFS_INVALID_CLUSTER_NUMBER:
            return( "MFS INVALID CLUSTER NUMBER" );
        case MFS_FAILED_TO_DELETE_LFN:
            return( "MFS FAILED TO DELETE LFN" );
        case MFS_BAD_LFN_ENTRY:
            return( "MFS BAD LFN ENTRY" );
        case PMGR_INVALID_PARTITION:
            return( "PMGR INVALID PARTITION" );
        case PMGR_INSUF_MEMORY:
            return( "PMGR INSUF MEMORY" );                
        case PMGR_UNKNOWN_PARTITION:
            return( "PMGR UNKNOWN PARTITION TYPE" );
        case PMGR_INVALID_PARTTABLE:
            return( "PMGR INVALID PARTITION TABLE" );
        default: return("UNKNOWN ERROR !!!");
    }  
}


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_math.h<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_math.h$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*   This file contains the definitions for functions that provide
*   mathematics for working on 64 bit, 96 bit and 128 bit numbers.
*   (Needed by the time conversion functions) The operations on the numbers 
*   are performed uing the 16-bit array representation of the numbers.
*
*END************************************************************************/
   
#ifndef __psp_math_h__
#define __psp_math_h__

/*-----------------------------------------------------------------------*/
/*
** PSP 64 BIT UNION
**
** The representation of a 64 bit number
**
*/
typedef union psp_64_bit_union
{
   uint_64  LLW;
   uint_32  LW[2];
   uint_16  W[4];
   uint_8   B[8];
} PSP_64_BIT_UNION, _PTR_ PSP_64_BIT_UNION_PTR;

/*-----------------------------------------------------------------------*/
/*
** PSP 96 BIT UNION
**
** The representation of a 96 bit number
**
*/
typedef union psp_96_bit_union
{
   uint_32         LW[3];
   uint_16         W[6];
   uint_8          B[12];
   PSP_TICK_STRUCT TICKS;
} PSP_96_BIT_UNION, _PTR_ PSP_96_BIT_UNION_PTR;

/*-----------------------------------------------------------------------*/
/*
** PSP 128 BIT UNION
**
** The representation of a 128 bit number
**
*/
typedef union psp_128_bit_union
{
   uint_64  LLW[2];
   uint_32  LW[4];
   uint_16  W[8];
   uint_8   B[16];
} PSP_128_BIT_UNION, _PTR_ PSP_128_BIT_UNION_PTR;


/*--------------------------------------------------------------------------*/
/*
**                  PROTOTYPES OF PSP FUNCTIONS
*/

#ifdef __cplusplus
extern "C" {
#endif

extern uint_32 _psp_add_element_to_array(uint_32_ptr, uint_32, uint_32, uint_32_ptr);
extern uint_32 _psp_div_128_by_32(PSP_128_BIT_UNION_PTR, uint_32, PSP_128_BIT_UNION_PTR);
extern uint_32 _psp_mul_128_by_32(PSP_128_BIT_UNION_PTR, uint_32, PSP_128_BIT_UNION_PTR);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/MotorControlLib/GFLIB/GFLIB_Hyst.h<|end_filename|>
/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file     GFLIB_Hyst.h
*
* @author   <NAME>
*
* @version  1.0.1.0
*
* @date     Dec-6-2012
*
* @brief    Header file for #GFLIB_Hyst function.
*
*******************************************************************************
*
* Function implemented as ANSIC ISO/IEC 9899:1990, C90.
*
******************************************************************************/
#ifndef _GFLIB_HYST_H
#define _GFLIB_HYST_H

#ifndef  _MATLAB_BAM_CREATE
#include "SWLIBS_Typedefs.h"
#include "SWLIBS_Defines.h"
#include "SWLIBS_Inlines.h"
#endif

/******************************************************************************
* Defines and macros            (scope: module-local)
******************************************************************************/
/*! Function alias for the #GFLIB_HystANSIC function.*/
#define GFLIB_Hyst(f32In, pParam) GFLIB_HystANSIC(f32In, pParam)

/*! Macro containing default values of the hysteresis function structure.*/
#define GFLIB_HYST_DEFAULT   {0,0,0,0,0}

/******************************************************************************
* Typedefs and structures       (scope: module-local)
******************************************************************************/
/*------------------------------------------------------------------------*//*!
@struct GFLIB_HYST_T "\GFLIB_Hyst.h"

@brief      Structure containing parameters and states for the hysteresis function
            implemented in #GFLIB_Hyst.

@details
*//*-------------------------------------------------------------------------*/
typedef struct
{
    Frac32  f32HystOn;     /*!< Value determining the upper threshold; fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ . */
    Frac32  f32HystOff;    /*!< Value determining the lower threshold; fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ . */
    Frac32  f32OutValOn;   /*!< Value of the output when input is higher than the upper threshold; fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ . */
    Frac32  f32OutValOff;  /*!< Value of the output when input is the lower than lower threshold; fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ . */
    Frac32  f32OutState;   /*!< Actual state of the output; fractional format normalized to fit into \f$\left[-2^{31},2^{31}-1\right)\f$ . */
}GFLIB_HYST_T;

/******************************************************************************
* Exported Variables
******************************************************************************/

/******************************************************************************
* Exported function prototypes
******************************************************************************/
/*!
* @ingroup GFLIB_GROUP
*/
extern Frac32 GFLIB_HystANSIC(Frac32 f32In, GFLIB_HYST_T *pParam);

/******************************************************************************
* Inline functions
******************************************************************************/

#endif /* _GFLIB_HYST_H */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/ppp/ccp.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ccp.c$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the implementation for the
*   Compression Control Protocol.
*
*END************************************************************************/

#include <ppp.h>

#if RTCSCFG_ENABLE_IP4

#include "ppp_prv.h"


static boolean CCP_up(PPPFSM_CFG_PTR);
static void    CCP_down(PPPFSM_CFG_PTR);

static void    CCP_resetconfreq(PPPFSM_CFG_PTR);
static uint_32 CCP_buildconfreq(PPPFSM_CFG_PTR, uchar_ptr, uint_32);

static uint_32 CCP_recvconfreq(PPPFSM_CFG_PTR, boolean);
static boolean CCP_recvconfack(PPPFSM_CFG_PTR);
static boolean CCP_recvconfnak(PPPFSM_CFG_PTR);
static boolean CCP_recvconfrej(PPPFSM_CFG_PTR);
static boolean CCP_recvcoderej(PPPFSM_CFG_PTR);
static boolean CCP_recvextcode(PPPFSM_CFG_PTR);

static PPPFSM_CALL CCP_CALL = {
   /* PROTOCOL    */    PPP_PROT_CCP,
   /* linkup()    */    CCP_up,
   /* linkdown()  */    CCP_down,
   /* resetreq()  */    CCP_resetconfreq,
   /* buildreq()  */    CCP_buildconfreq,
   /* recvreq()   */    CCP_recvconfreq,
   /* recvack()   */    CCP_recvconfack,
   /* recvnak()   */    CCP_recvconfnak,
   /* recvrej()   */    CCP_recvconfrej,
   /* testcode()  */    CCP_recvcoderej,
   /* recvcode()  */    CCP_recvextcode
};


/*
** The default CCP link options
*/

static CCP_OPT CCP_DEFAULT_OPTIONS = {
   /* CP    */    NULL,
   /* DATA  */    {0}
};

static CCP_NEG CCP_DEFAULT_NEG = {
   /* NEG_*     */   0,0
#ifdef PPP_CP_LZS
   /* LZS_HIST  */   ,1
   /* LZS_CHECK */   ,3
#endif
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_init
* Returned Value  :  error code
* Comments        :
*     Called by PPP_initialize.  Initializes the CCP Finite State Machine.
*
*END*-----------------------------------------------------------------*/

uint_32 CCP_init
   (
      _ppp_handle    handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = handle;

      /* Initialize the FSM */
   return PPPFSM_init(&ppp_ptr->CCP_FSM, handle, &CCP_CALL, &ppp_ptr->CCP_STATE);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_destroy
* Returned Value  :  error code
* Comments        :
*     Called by PPP_initialize.  Destroys the CCP Finite State Machine.
*     Assumes the Finite State Machine has been initialized.
*
*END*-----------------------------------------------------------------*/

uint_32 CCP_destroy
   (
      _ppp_handle      handle
            /* [IN] - the PPP state structure */
   )
{ /* Body */

   PPP_CFG_PTR ppp_ptr = handle;

      /* Destroy the FSM */
   return PPPFSM_destroy(&ppp_ptr->CCP_FSM);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_up
* Returned Value  :  TRUE (always)
* Comments        :
*     Called by the FSM when entering the OPENED state.
*
*END*-----------------------------------------------------------------*/

static boolean CCP_up
   (
      PPPFSM_CFG_PTR     fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = fsm->HANDLE;
   CCP_CFG_PTR ccp_ptr = fsm->PRIVATE;
   CP_CALL_PTR cprecv = ccp_ptr->RECV_OPT.CP;
   CP_CALL_PTR cpsend = ccp_ptr->SEND_OPT.CP;

      /* Initialize compression methods */
   if (cprecv) {
      cprecv->CP_init(&ccp_ptr->RECV_DATA, &ccp_ptr->RECV_OPT);
   } /* Endif */
   if (cpsend) {
      cpsend->CP_init(&ccp_ptr->SEND_DATA, &ccp_ptr->SEND_OPT);
   } /* Endif */

   PPP_mutex_lock(&ppp_ptr->MUTEX);
   ppp_ptr->RECV_OPTIONS->CP = cprecv;
   ppp_ptr->SEND_OPTIONS->CP = cpsend;
   PPP_mutex_unlock(&ppp_ptr->MUTEX);

   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_down
* Returned Value  :  void
* Comments        :
*     Called by the FSM when leaving the OPENED state.
*
*END*-----------------------------------------------------------------*/

static void CCP_down
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   PPP_CFG_PTR ppp_ptr = fsm->HANDLE;

      /* Restore default compression methods */
   PPP_mutex_lock(&ppp_ptr->MUTEX);
   ppp_ptr->RECV_OPTIONS->CP = PPP_DEFAULT_OPTIONS.CP;
   ppp_ptr->SEND_OPTIONS->CP = PPP_DEFAULT_OPTIONS.CP;
   PPP_mutex_unlock(&ppp_ptr->MUTEX);

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_resetconfreq
* Returned Value  :  void
* Comments        :
*     Called by PPPFSM_sendconfreq when starting negotiation.
*     Initializes the Send Options.
*
*END*-----------------------------------------------------------------*/

static void CCP_resetconfreq
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   CCP_CFG_PTR ccp_ptr = fsm->PRIVATE;

   ccp_ptr->SEND_OPT = CCP_DEFAULT_OPTIONS;
   ccp_ptr->RECV_OPT = CCP_DEFAULT_OPTIONS;
   ccp_ptr->RECV_NEG = CCP_DEFAULT_NEG;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_buildconfreq
* Returned Value  :  number of bytes written
* Comments        :
*     Called by PPPFSM_sendconfreq.  Builds a ConfReq packet.
*
*END*-----------------------------------------------------------------*/

static uint_32 CCP_buildconfreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN] - State Machine */
      uchar_ptr         outp,
            /* [IN] - free packet */
      uint_32           sizeleft
            /* [IN] - size of packet */
   )
{ /* Body */
#if defined(PPP_CP_LZS) || defined(PPP_CP_PRED1)
   CCP_CFG_PTR ccp_ptr = fsm->PRIVATE;
#endif
/* End SPR P122-0266-38. */
   uint_32     totlen = 0;

      /*
      ** Generate configuration information for each option
      ** we want to negotiate, in order of preference.
      */

#ifdef PPP_CP_LZS
   if (ccp_ptr->RECV_NEG.NEG_LZS) {
      if (sizeleft >= totlen+5) {
         *outp++ = CCP_CI_LZS;
         totlen += *outp++ = 5;
         *outp++ = ccp_ptr->RECV_NEG.LZS_HIST >> 8;
         *outp++ = ccp_ptr->RECV_NEG.LZS_HIST & 0xFF;
         *outp++ = ccp_ptr->RECV_NEG.LZS_CHECK;
      } /* Endif */
   } /* Endif */
#endif

#ifdef PPP_CP_PRED1
   if (ccp_ptr->RECV_NEG.NEG_PRED1) {
      if (sizeleft >= totlen+2) {
         *outp++ = CCP_CI_PRED1;
         len += *outp++ = 2;
      } /* Endif */
   } /* Endif */
#endif

   return totlen;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_recvconfack
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_recvconfack.  Parses a ConfAck packet.
*     This function should not modify any state if the ack is bad.
*
*END*-----------------------------------------------------------------*/

static boolean CCP_recvconfack
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   CCP_CFG_PTR ccp_ptr = fsm->PRIVATE;
#if defined(PPP_CP_LZS) || defined(PPP_CP_PRED1)
   uchar_ptr   inp = fsm->DATA;
#endif
   uint_16     len = fsm->LENGTH;
   CCP_OPT     ack_opt = ccp_ptr->RECV_OPT;
   ack_opt.CP = NULL;

      /*
      ** The ack must be identical to the last ConfReq we sent
      */

#ifdef PPP_CP_LZS
   if (ccp_ptr->RECV_NEG.NEG_LZS) {
      uint_16 hist;
      uchar   check;
      if (len < 5) goto badack;
      if (*inp++ != CCP_CI_LZS) goto badack;
      if (*inp++ != 5) goto badack;
      hist  = (uint_16)*inp++ << 8;
      hist |= (uint_16)*inp++;
      if (hist != ccp_ptr->RECV_NEG.LZS_HIST) goto badack;
      check = *inp++;
      if (check != ccp_ptr->RECV_NEG.LZS_CHECK) goto badack;
      if (!ack_opt.CP) {
         ack_opt.CP = &CP_LZS;
         ack_opt.DATA.LZS.HIST = hist;
         ack_opt.DATA.LZS.CHECK = check;
      } /* Endif */
      len -= 5;
   } /* Endif */
#endif

#ifdef PPP_CP_PRED1
   if (ccp_ptr->RECV_NEG.NEG_PRED1) {
      if (len < 2) goto badack;
      if (*inp++ != CCP_CI_PRED1) goto badack;
      if (*inp++ != 2) goto badack;
      if (!ack_opt.CP) {
         ack_opt.CP = &CP_PRED1;
      } /* Endif */
      len -= 2;
   } /* Endif */
#endif

   if (len) goto badack;

   if (fsm->STATE < PPP_STATE_OPENED) {
      ccp_ptr->RECV_OPT = ack_opt;
   } /* Endif */
   return TRUE;

badack:
   return FALSE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_recvconfnak
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_recvconfnak.  Parses a ConfNak packet.
*     This function should not modify any state if the nak is bad.
*
*END*-----------------------------------------------------------------*/

static boolean CCP_recvconfnak
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   CCP_CFG_PTR ccp_ptr = fsm->PRIVATE;
   uchar_ptr   inp = fsm->DATA;
   uint_16     len = fsm->LENGTH;
   CCP_NEG     req_neg = ccp_ptr->RECV_NEG;
   uchar       code;
   uchar       codelen;

      /*
      ** Nak'd codes must be in the same order as they were in the ConfReq
      */

   code = *inp++;

#ifdef PPP_CP_LZS
   if (len && req_neg.NEG_LZS && code == CCP_CI_LZS) {
      if (len < 5) goto badnak;
      if (*inp++ != 5) goto badnak;
      len -= 5;

         /* We are prepared to accept a history count of 0 or 1 */
      req_neg.LZS_HIST  = (uint_16)*inp++ << 8;
      req_neg.LZS_HIST |= (uint_16)*inp++;
      if (req_neg.LZS_HIST > 1) {
         req_neg.LZS_HIST = 1;
      } /* Endif */

         /* We are prepared to accept a check mode of 0 to 3 */
      req_neg.LZS_CHECK = *inp++;
      if (req_neg.LZS_CHECK > 3) {
         if (req_neg.LZS_HIST) {
            req_neg.LZS_CHECK = 3;
         } else {
            req_neg.LZS_CHECK = 0;
         } /* Endif */
      } /* Endif */

      code = *inp++;
   } /* Endif */
#endif

      /*
      ** If we advertised Predictor 1 and the peer doesn't want
      ** it, they should send a ConfRej rather than a ConfNak,
      ** so we're not going to check for it here.
      */

      /*
      ** There may be remaining codes if the peer wants us to
      ** negotiate an option we didn't include.
      */

   while (len) {
      switch (code) {
#ifdef PPP_CP_PRED1
      case CCP_CI_PRED1:
         if (req_neg.NEG_PRED1 || len < 2 || *inp++ != 2) goto badnak;
         len -= 2;
         req_neg.NEG_PRED1 = 1;
         break;
#endif
#ifdef PPP_CP_LZS
      case CCP_CI_LZS:
         if (req_neg.NEG_LZS || len < 5 || *inp++ != 5) goto badnak;
         len -= 5;
         req_neg.NEG_LZS = 1;

            /* We are prepared to accept a history count of 0 or 1 */
         req_neg.LZS_HIST  = (uint_16)*inp++ << 8;
         req_neg.LZS_HIST |= (uint_16)*inp++;
         if (req_neg.LZS_HIST > 1) {
            req_neg.LZS_HIST = 1;
         } /* Endif */

            /* We are prepared to accept a check mode of 0 to 3 */
         req_neg.LZS_CHECK = *inp++;
         if (req_neg.LZS_CHECK > 3) {
            if (req_neg.LZS_HIST) {
               req_neg.LZS_CHECK = 3;
            } else {
               req_neg.LZS_CHECK = 0;
            } /* Endif */
         } /* Endif */

         break;
#endif
      default:
         if (len < 2) goto badnak;
         codelen = *inp--;
         if (len < codelen) goto badnak;
         len -= codelen;
         inp += codelen;
      } /* Endswtich */
      code = *inp++;
   } /* Endwhile */

   if (fsm->STATE < PPP_STATE_OPENED) {
      ccp_ptr->RECV_NEG = req_neg;
   } /* Endif */
   return TRUE;

badnak:
   return FALSE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_recvconfrej
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_recvconfnak.  Parses a ConfRej packet.
*     This function should not modify any state if the rej is bad.
*
*END*-----------------------------------------------------------------*/

static boolean CCP_recvconfrej
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   CCP_CFG_PTR ccp_ptr = fsm->PRIVATE;
   uint_16     len = fsm->LENGTH;
   CCP_NEG     req_neg = ccp_ptr->RECV_NEG;

#if defined(PPP_CP_LZS) || defined(PPP_CP_PRED1)
   uchar_ptr   inp = fsm->DATA;
   uchar       code;

   /*
   ** Rej'd codes must be in the same order as they were in the ConfReq
   */
   code = *inp++;
#endif

#ifdef PPP_CP_LZS
   if (len && req_neg.NEG_LZS && (code == CCP_CI_LZS)) {
      if (len < 5) goto badrej;
      if (*inp++ != 5) goto badrej;
      len -= 5;
      if ((req_neg.LZS_HIST >> 8)   != *inp++) goto badrej;
      if ((req_neg.LZS_HIST & 0xFF) != *inp++) goto badrej;
      if ((req_neg.LZS_CHECK)       != *inp++) goto badrej;
      req_neg.NEG_LZS = 0;
      code = *inp++;
   } /* Endif */
#endif

#ifdef PPP_CP_PRED1
   if (len && req_neg.NEG_PRED1 && (code == CCP_CI_PRED1)) {
      if (len < 2) goto badrej;
      if (*inp++ != 2) goto badrej;
      len -= 2;
      req_neg.NEG_PRED1 = 0;
      code = *inp++;
   } /* Endif */
#endif

   if (len) goto badrej;

   if (fsm->STATE < PPP_STATE_OPENED) {
      ccp_ptr->RECV_NEG = req_neg;
   } /* Endif */
   return TRUE;

badrej:
   return FALSE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_recvconfreq
* Returned Value  :  number of bytes written
* Comments        :
*     Called by PPPFSM_recvconfreq.  Parses a ConfReq packet.
*     Builds a ConfAck/ConfNak/ConfRej packet out of fsm->PACKET,
*     and sets fsm->CODE appropriately.
*
*END*-----------------------------------------------------------------*/

static uint_32 CCP_recvconfreq
   (
      PPPFSM_CFG_PTR    fsm,
            /* [IN] - State Machine */
      boolean           reject
            /* [IN] - whether to ConfRej if we disagree */
   )
{ /* Body */
   CCP_CFG_PTR ccp_ptr = fsm->PRIVATE;
   uchar_ptr   inp = fsm->DATA;
#ifdef PPP_CP_LZS
   uchar_ptr nakp;
#endif
   uchar_ptr rejp;

   uint_16     len = fsm->LENGTH;
   uint_16     naklen, rejlen;
   CCP_OPT     req_opt = ccp_ptr->SEND_OPT;
   uchar       code;
   uchar       cicode, cilen;
#ifdef PPP_CP_LZS
   uint_16     lzshist;
   uchar       lzscheck;
#endif

#define CI_REJECT(n)                   \
   inp -= n;                           \
   code = CP_CODE_CONF_REJ;            \
   rejlen += cilen;                    \
   while (cilen--) *rejp++ = *inp++

#ifdef PPP_CP_LZS
#define CI_NAK                               \
   if (code != CP_CODE_CONF_REJ) {           \
      code = CP_CODE_CONF_NAK;               \
      if (reject) {                          \
         inp -= cilen;                       \
         naklen += cilen;                    \
         while (cilen--) *nakp++ = *inp++;   \
      } else
#else
#define CI_NAK                               \
   if (code != CP_CODE_CONF_REJ) {           \
      code = CP_CODE_CONF_NAK;               \
      if (reject) {                          \
         inp -= cilen;                       \
         naklen += cilen;                    \
         while (cilen--) *inp++;             \
      } else
#endif

#define CI_ENDNAK                            \
   } /* Endif */

      /*
      ** Process all requested codes
      */

#ifdef PPP_CP_LZS
   rejp = nakp = inp;
#else
   rejp = inp;
#endif
   rejlen = naklen = 0;
   code = CP_CODE_CONF_ACK;
   req_opt.CP = NULL;

   while (len) {
         /* check remaining length */
      if (len < 2 || inp[1] < 2 || inp[1] > len) {
         code = CP_CODE_CONF_REJ;
         rejlen += len;
         while (len--) *rejp++ = *inp++;
         break;
      } /* Endif */

      cicode = *inp++;
      len -= cilen = *inp++;

      switch (cicode) {

#ifdef PPP_CP_PRED1
      case CCP_CI_PRED1:
         if (cilen != 2) {
            CI_REJECT(2);
            break;
         } /* Endif */

         if (!req_opt.CP) {
            req_opt.CP = &CP_PRED1;
         } /* Endif */
         break;
#endif

#ifdef PPP_CP_LZS
      case CCP_CI_LZS:
         if (cilen != 5) {
            CI_REJECT(2);
            break;
         } /* Endif */

            /* Accept any history count, but only check modes 0 to 3 */
         lzshist  = (uint_16)*inp++ << 8;
         lzshist |= (uint_16)*inp++;
         lzscheck = *inp++;
         if (lzscheck > 3) {
            CI_NAK {
               *nakp++ = CCP_CI_LZS;
               naklen += *nakp++ = 5;
               *nakp++ = lzshist >> 8;
               *nakp++ = lzshist;
               if (lzshist) {
                  *nakp++ = 3;
               } else {
                  *nakp++ = 0;
               } /* Endif */
            } CI_ENDNAK;
         } /* Endif */

         if (!req_opt.CP) {
            req_opt.CP = &CP_LZS;
            req_opt.DATA.LZS.HIST = lzshist;
            req_opt.DATA.LZS.CHECK = lzscheck;
         } /* Endif */
         break;
#endif

      default:
         CI_REJECT(2);
         break;
      } /* Endswitch */
   } /* Endwhile */

   /*
   ** If we wanted to send additional naks for unsent codes, they
   ** would go here, at *nakp.
   */

   if (code == CP_CODE_CONF_ACK) {
      ccp_ptr->SEND_OPT = req_opt;
      len = fsm->LENGTH;
   } else if (code == CP_CODE_CONF_REJ) {
      len = rejlen;
   } else if (reject) {
      code = CP_CODE_CONF_REJ;
      len = naklen;
   } else { /* if code == NAK */
      len = naklen;
   } /* Endif */

   fsm->CODE = code;
   return len;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_recvcoderej
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_recvcoderej.  Returns TRUE if the rejected
*     code is catastrophic.
*
*END*-----------------------------------------------------------------*/

static boolean CCP_recvcoderej
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   uchar code = *fsm->DATA;
   return ((code >= 1 && code <= 7) || (code >= 14 && code <= 15));
} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
* Function Name   :  CCP_recvextcode
* Returned Value  :  TRUE or FALSE
* Comments        :
*     Called by PPPFSM_input.  Parses an CCP packet with an extended
*     code.
*
*END*-----------------------------------------------------------------*/

static boolean CCP_recvextcode
   (
      PPPFSM_CFG_PTR    fsm
            /* [IN] - State Machine */
   )
{ /* Body */
   CCP_CFG_PTR ccp_ptr = fsm->PRIVATE;
   CP_CALL_PTR cprecv = ccp_ptr->RECV_OPT.CP;
   CP_CALL_PTR cpsend = ccp_ptr->SEND_OPT.CP;

   switch (fsm->CODE) {

   case CCP_CODE_RESET_REQ:
      ccp_ptr->ST_CCP_RX_RESET++;
      if ((fsm->STATE < PPP_STATE_OPENED) || !cprecv) {
         PCB_free(fsm->PACKET);
      } else {
         cpsend->CP_resetreq(&ccp_ptr->SEND_DATA, fsm->PACKET);
      } /* Endif */
      break;

   case CCP_CODE_RESET_ACK:
      ccp_ptr->ST_CCP_RX_ACK++;
      if ((fsm->STATE < PPP_STATE_OPENED) || !cpsend) {
         PCB_free(fsm->PACKET);
      } else {
         cprecv->CP_resetack(&ccp_ptr->RECV_DATA, fsm->PACKET);
      } /* Endif */
      break;

   default:
      return FALSE;
   } /* Endswitch */

   return TRUE;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/host_rcv.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: host_rcv.c$
* $Version : 3.8.10.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
*   This file contains the USB Host API specific functions to receive data.
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "host_cnfg.h"
#include "hostapi.h"
#include "host_main.h"
#include "host_rcv.h"

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_recv_data
*  Returned Value : error or status of the transfer
*  Comments       :
* The Receive Data routine is non-blocking routine that causes a buffer 
* to be made available for data recieved from the 
* USB host. It takes the buffer and passes it down to lower
level hardware driver. 
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_recv_data
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle           handle, 

      /* [IN] the pipe handle */
      _usb_pipe_handle           pipe_handle,

      /* [IN] transfer parameters */
      TR_INIT_PARAM_STRUCT_PTR   tr_params_ptr
   )
{ /* Body */
   PIPE_STRUCT_PTR           pipe_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr;
   USB_STATUS    status;
   TR_STRUCT_PTR tr_ptr;
   USB_STATUS    return_code;   

#ifdef _HOST_DEBUG_
   DEBUG_LOG_TRACE("_usb_host_recv_data");
#endif

   USB_lock();

   return_code = _usb_host_set_up_tr(pipe_handle, tr_params_ptr, &tr_ptr);

   if (return_code != USB_STATUS_TRANSFER_QUEUED) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_recv_data transfer queue failed");
      #endif
      return USB_log_error(__FILE__,__LINE__,return_code);
   } /* Endif */

   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   pipe_ptr = (PIPE_STRUCT_PTR)pipe_handle;

   /* We will do soon cache invalidation of buffer. This can have an impact to the
   ** data that sit in the same cache line, but are not part of the buffer. In order
   ** not to invalidate their cached values, we do first flushing those data.
   */
   USB_dcache_flush_mlines((void *)tr_ptr->RX_BUFFER, tr_ptr->RX_LENGTH);

   /* To ensure that the USB DMA transfer will work on a buffer that is not cached,
   ** we invalidate buffer cache lines.
   */
   USB_dcache_invalidate_mlines((void *)tr_ptr->RX_BUFFER, tr_ptr->RX_LENGTH);

   /* We have obtained the current TR on the Pipe's TR list 
   ** from _usb_host_set_up_tr
   */

   /* Call the low-level routine to receive data */
   status = _usb_host_recv_data_call_interface (handle, pipe_ptr, tr_ptr);
         
   USB_unlock();
	   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_recv_data SUCCESSFUL");
   #endif

   if(status == USB_OK) 
   {
      return USB_STATUS_TRANSFER_QUEUED;
   }
   else
   {
      return USB_log_error(__FILE__,__LINE__,status);
   }

   
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/enet/mcf5xxx_fec/mcf5xxx_fec_receive.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mcf5xxx_fec_receive.c$
* $Version : 3.5.7.0$
* $Date    : Feb-3-2010$
*
* Comments:
*
*   This file contains the MCF5xxx Coldfire processor
*   Ethernet initialization
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "enet.h"
#include "enetprv.h"
#include "bsp_prv.h"
#include "mcf5xxx_fec_prv.h"          

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_rx_free_specific
*  Returned Value : void
*  Comments       :
*        Frees a receive buffer
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_rx_free_specific
   (
      MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr,
         /* [IN] the PCB to enqueue */
      PCB_PTR     pcb_ptr,
      pointer *   list
   )
{ 
   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   FEC_int_disable();
   ENET_Enqueue_Buffer(list, pcb_ptr->FRAG[0].FRAGMENT );
   pcb_ptr->FRAG[0].FRAGMENT = NULL;
   QADD(fec_context_ptr->RxPCBHead, fec_context_ptr->RxPCBTail, pcb_ptr);
   FEC_int_enable();
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_rx_free_small
*  Returned Value : void
*  Comments       :
*        Frees a small receive buffer
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_rx_free_small
   (
         /* [IN] the PCB to enqueue */
      PCB_PTR  pcb_ptr
   )
{ 
   ENET_CONTEXT_STRUCT_PTR          enet_ptr = (ENET_CONTEXT_STRUCT_PTR)pcb_ptr->PRIVATE;
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;


   MCF5XXX_FEC_rx_free_specific(fec_context_ptr, pcb_ptr, (pointer *)&fec_context_ptr->SMALL_BUFFERS);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_rx_free_large
*  Returned Value : void
*  Comments       :
*        Frees a small receive buffer
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_rx_free_large
   (
         /* [IN] the PCB to enqueue */
      PCB_PTR  pcb_ptr
   )
{ 
   ENET_CONTEXT_STRUCT_PTR          enet_ptr = (ENET_CONTEXT_STRUCT_PTR)pcb_ptr->PRIVATE;
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;


   MCF5XXX_FEC_rx_free_specific(fec_context_ptr, pcb_ptr, (pointer *)&fec_context_ptr->LARGE_BUFFERS);
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_rx_free
*  Returned Value : void
*  Comments       :
*        Frees a normal sized receive buffer
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_rx_free
   (
         /* [IN] the PCB to enqueue */
      PCB_PTR  pcb_ptr
   )
{ 
   ENET_CONTEXT_STRUCT_PTR          enet_ptr = (ENET_CONTEXT_STRUCT_PTR)pcb_ptr->PRIVATE;
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   #if ENETCFG_SUPPORT_FRAGMENTED_PCBS
   uint_32                          i;
   #endif

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   FEC_int_disable();

   #if ENETCFG_SUPPORT_FRAGMENTED_PCBS
      for (i=0;pcb_ptr->FRAG[i].FRAGMENT;i++) {
         ENET_Enqueue_Buffer((pointer*)&fec_context_ptr->RX_BUFFERS, pcb_ptr->FRAG[i].FRAGMENT );
         pcb_ptr->FRAG[i].FRAGMENT = NULL;
      }
   #else   
      ENET_Enqueue_Buffer((pointer*)&fec_context_ptr->RX_BUFFERS, pcb_ptr->FRAG[0].FRAGMENT );
      pcb_ptr->FRAG[0].FRAGMENT = NULL;
   #endif
   
   QADD(fec_context_ptr->RxPCBHead, fec_context_ptr->RxPCBTail, pcb_ptr);

   MCF5XXX_FEC_add_buffers_to_rx_ring(fec_context_ptr);
   FEC_int_enable();
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_add_buffers_to_rx_ring
*  Returned Value : void
*  Comments       :
*        Enqueues a PCB onto the receive ring.
*
*END*-----------------------------------------------------------------*/

void MCF5XXX_FEC_add_buffers_to_rx_ring(MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr)
{ 
   VMCF5XXX_FEC_STRUCT_PTR          fec_ptr = fec_context_ptr->FEC_ADDRESS;
   VMCF5XXX_FEC_BD_STRUCT_PTR       bd_ptr;

   if (fec_ptr == NULL) return;

   /*
   ** This function can be called from any context, and it needs mutual
   ** exclusion with itself.
   */
   FEC_int_disable();
   
   while (fec_context_ptr->ActiveRxBDs < fec_context_ptr->NumRxBDs) {

      bd_ptr = &fec_context_ptr->FEC_RX_RING_PTR[fec_context_ptr->LastRxBD];

      _DCACHE_INVALIDATE_MBYTES((pointer)bd_ptr, sizeof(MCF5XXX_FEC_BD_STRUCT));
      
      /* Initialize the descriptor and give it to the FEC */
      bd_ptr->BUFFER = ENET_Dequeue_Buffer((pointer *) &fec_context_ptr->RX_BUFFERS);
      if (bd_ptr->BUFFER == NULL) {
         FEC_int_enable();
         return;
      }
      bd_ptr->LENGTH = 0;

      /*
      ** The processor doesn't clear control bits when errors don't occur;
      ** it just sets bits when errors do occur.  So we clear all the
      ** control bits before enqueueing the descriptor.
      */
      bd_ptr->CONTROL &= (MCF5XXX_FEC_BD_ETHER_RX_WRAP);

      /*
      ** Add the PCB to the receive PCB queue (linked via PRIVATE) and
      ** increment the tail to the next descriptor
      */
      BD_INC(fec_context_ptr->LastRxBD, fec_context_ptr->NumRxBDs);
      fec_context_ptr->ActiveRxBDs++;

      bd_ptr->CONTROL |= MCF5XXX_FEC_BD_ETHER_RX_EMPTY;

      _DCACHE_FLUSH_MBYTES((pointer)bd_ptr, sizeof(MCF5XXX_FEC_BD_STRUCT));  

      /*
      ** Signals the FEC that empty buffers are available.
      */
      fec_ptr->RDAR = MCF5XXX_FEC_RDAR_ACTIVE;
   }
   FEC_int_enable();
} 



#if !ENETCFG_SUPPORT_FRAGMENTED_PCBS

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_discard_current_rx
*  Returned Value : void
*  Comments       :
 *
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_discard_current_rx(ENET_CONTEXT_STRUCT_PTR    enet_ptr,MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr, boolean last)
{
   uint_32  i;
   

   if (fec_context_ptr->CurrentRxECB) {
      for (i=0;i<fec_context_ptr->CurrentRxFrag;i++) {
         ENET_INC_STATS(COMMON.ST_RX_DISCARDED);
         if (fec_context_ptr->FRAGS[i].FRAGMENT) {
            ENET_Enqueue_Buffer((pointer*)&fec_context_ptr->RX_BUFFERS, fec_context_ptr->FRAGS[i].FRAGMENT);
         }
         fec_context_ptr->FRAGS[i].FRAGMENT = NULL;
      }
   }
   fec_context_ptr->CurrentRxECB=NULL;
   
   if (last) 
      fec_context_ptr->CurrentRxFrag=0;
}      


  
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_process_rx_bds
*  Returned Value : void
*  Comments       :
*        Processes received buffers.
*
* NOTE: For FEC, a frame consists of one or more buffers.
*       For ENET, a packet consists of one or more fragments
*        Therefore, a frame = a packet, and a buffer = a fragment.
*
*
*END*-----------------------------------------------------------------*/
static void MCF5XXX_FEC_process_rx_bds
   (
         /* [IN] the Ethernet state structure */
      ENET_CONTEXT_STRUCT_PTR    enet_ptr
   )
{ /* Body */
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   VMCF5XXX_FEC_BD_STRUCT_PTR       bd_ptr;
   PCB_PTR                          pcb_ptr=NULL;
   uint_16                          rx_status;
   uint_32                          i,length;
   int_32                           ilength;
   uchar_ptr                        buffer, small_packet, large_packet;
   boolean                          buffer_is_valid, consumed, first, last;
   
   //_DCACHE_INVALIDATE();    // temporary - I can't find fast actual part of memory for cache invalidation

   /* Dequeue all received buffers (fragments) */
   while (fec_context_ptr->ActiveRxBDs > 0) {

      bd_ptr = &fec_context_ptr->FEC_RX_RING_PTR[fec_context_ptr->NextRxBD];
      _DCACHE_INVALIDATE_MBYTES((pointer)bd_ptr, sizeof(MCF5XXX_FEC_BD_STRUCT));  

      if ((bd_ptr->CONTROL & MCF5XXX_FEC_BD_ETHER_RX_EMPTY) != 0) {
         break; // Currently being written to by MII
      }  

      BD_INC(fec_context_ptr->NextRxBD,fec_context_ptr->NumRxBDs);
      fec_context_ptr->ActiveRxBDs--;

      ENET_INC_STATS(COMMON.ST_RX_TOTAL);
      rx_status = bd_ptr->CONTROL;
      length = bd_ptr->LENGTH;
      buffer = bd_ptr->BUFFER;
      
      consumed = FALSE;
      first = fec_context_ptr->CurrentRxFrag == 0;
      last = TRUE;
      
      // Start by validating the received buffer 
      // a buffer is valid if:
      //   (it is error free) AND ( (it is the first buffer in a frame) OR (it is a subsequent buffer in a frame we want ) )
      // 
      buffer_is_valid = FALSE;
      if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_TRUNCATED) {
      
         ENET_INC_STATS(ST_RX_RUNT);
     
      } else if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_LAST_FRAME) {
         
         // Some error bits can only be checked on the last buffer
         
         // Overrun needs to be checked first,  If this bit is 
         // set, the other status bits, M, LG, NO, CR, and CL lose their normal meaning and are zero. This bit 
         // is valid only if the L-bit is set.
         if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_OVERRUN) {
            ENET_INC_STATS(ST_RX_OVERRUN);
         
         } else if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_LENGTH_VIOLATION) {
            ENET_INC_STATS(ST_RX_GIANT);
            
         } else if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_NON_OCTET) {
            ENET_INC_STATS(ST_RX_ALIGN);
            
         } else if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_CRC_ERROR) {
            ENET_INC_STATS(ST_RX_FCS);
         } else {
            #if BSPCFG_ENABLE_ENET_HISTOGRAM
               uint_32 index = length>> ENET_HISTOGRAM_SHIFT;
               
               if (index < ENET_HISTOGRAM_ENTRIES) {
                  ENET_INC_STATS(RX_HISTOGRAM[index]);
               }
            #endif
         
         
            // Good buffer (with Last bit set). 
            buffer_is_valid = TRUE;
            // Remove CRC and compute buffer length
            ilength = length - (ENET_FRAMESIZE_TAIL + (fec_context_ptr->CurrentRxFrag * enet_ptr->PARAM_PTR->RX_BUFFER_SIZE));
            
            // The last fragment may contain nothing but part of the CRC. If this is the case, length will be <= 0,
            // and if length < 0, the previous fragment contains part of the CRC, which needs to be removed.
            if (ilength < 0) {
               length = 0;
               if (!first) {
                  fec_context_ptr->FRAGS[fec_context_ptr->CurrentRxFrag-1].LENGTH += ilength;
               } else {
                  // Should never get here - would mean we received a really small packet which should have already been
                  // caught above. But if we do, discard it.
                  buffer_is_valid = TRUE;
               }
            } else {
               length = (uint_32) ilength;
            }
                  
         }
         
      }  else {
         // Good buffer (without Last bit set). Can only be processed if we are not currently discarding.
         buffer_is_valid = TRUE;
         last = FALSE;
      }   
      
      
         
      if (!buffer_is_valid) {
         // Was a buffer with an error
         ENET_INC_STATS(COMMON.ST_RX_ERRORS);
         MCF5XXX_FEC_discard_current_rx(enet_ptr,fec_context_ptr,last);
         
      } else {
         // If it is the first buffer in the frame, we have to see if the frame is of interest. 
         if (first) {
            // make sure we don't examine a cached copy of the buffer
            _DCACHE_INVALIDATE_MBYTES(buffer, length);  

            // the frame is of interest if there is a receiver registered for the destination and protocol. We can do this on the first buffer
            // of the frame, since  the ethernet header information always fits in  the first buffer of a frame.
            fec_context_ptr->CurrentRxECB = ENET_find_receiver(enet_ptr, (ENET_HEADER_PTR) buffer, &length);
         }

         
         // If we have an Rx ECB, it means we want this packet
         if (fec_context_ptr->CurrentRxECB ) {
            if (!first) {
               // If it is not the first packet, the cache is still valid. We could have put the invalidate before the first "if (first)",
               // but that would mean we may invalidate the cache on buffers that we know we are discarding.
               _DCACHE_INVALIDATE_MBYTES(buffer, length);  
            }            
            
            // Add the packet to the list of fragments in the PCB               
            fec_context_ptr->FRAGS[fec_context_ptr->CurrentRxFrag].FRAGMENT = buffer;
            fec_context_ptr->FRAGS[fec_context_ptr->CurrentRxFrag].LENGTH = length;
            fec_context_ptr->CurrentRxFrag++;

            consumed = TRUE;

            // Now, there are three cases:
            //  !l - start or mid frame buffer - store it for later coalecing into a large buffer
            //  !f, l - end of multi-buffer packet - coalece into a large buffer
            //   f, l - single buffer packet - ready to process 
            
            if (!last) { 

               // Not the last frame in the packet. Have to make sure there is room for at least one
               // more fragment. If not, the packet is too large
               if (fec_context_ptr->CurrentRxFrag >= MCF5XXX_MAX_FRAGS) {
                  MCF5XXX_FEC_discard_current_rx(enet_ptr,fec_context_ptr,last);
                  ENET_INC_STATS(RX_FRAGS_EXCEEDED);
               }                     

            } else {  
               // last buffer (may or may not also be the first buffer) so process it

               // There is a receiver, so need to allocate a receive PCB
               QGET(fec_context_ptr->RxPCBHead, fec_context_ptr->RxPCBTail, pcb_ptr);
               if (pcb_ptr) {
                  // allocation successful, initialize new receive PCB
                  pcb_ptr->PRIVATE = (pointer)enet_ptr;
                  pcb_ptr->FREE = MCF5XXX_FEC_rx_free;
                  
                  // Check to see if it is a large packet
                  if (!first) {
                     // Coalese
                     large_packet = ENET_Dequeue_Buffer((pointer *)&fec_context_ptr->LARGE_BUFFERS);
                     
                     if (large_packet) {
                        // need to compute the length of this fragment, because the length on a BD with the L bit set
                        // is not the length of the buffer, it is the length of the frame.
                        pcb_ptr->FRAG[0].FRAGMENT = large_packet;
                        pcb_ptr->FRAG[0].LENGTH = 0;
                        pcb_ptr->FREE = MCF5XXX_FEC_rx_free_large;

                        for (i=0;i<fec_context_ptr->CurrentRxFrag;i++) {
                           if (fec_context_ptr->FRAGS[i].LENGTH ) {
                              _mem_copy(fec_context_ptr->FRAGS[i].FRAGMENT, large_packet, fec_context_ptr->FRAGS[i].LENGTH  );
                              large_packet += fec_context_ptr->FRAGS[i].LENGTH;
                              pcb_ptr->FRAG[0].LENGTH += fec_context_ptr->FRAGS[i].LENGTH;
                           }
                           ENET_Enqueue_Buffer((pointer*)&fec_context_ptr->RX_BUFFERS, fec_context_ptr->FRAGS[i].FRAGMENT);
                           fec_context_ptr->FRAGS[i].FRAGMENT = NULL;
                        }
                  
                        ENET_INC_STATS(ST_RX_COPY_LARGE);
                     } else {
                        ENET_INC_STATS(RX_LARGE_BUFFERS_EXHAUSTED);
                     
                        MCF5XXX_FEC_discard_current_rx(enet_ptr,fec_context_ptr,last);
                        QADD(fec_context_ptr->RxPCBHead, fec_context_ptr->RxPCBTail, pcb_ptr);
                        pcb_ptr=NULL;
                     }                     
                  
                  // Check to see if it is a small packet
                  } else { 
                     pcb_ptr->FRAG[0].LENGTH = length;
                     pcb_ptr->FRAG[0].FRAGMENT = buffer;
                     if (length < MCF5XXX_SMALL_PACKET_SIZE) {
 
                        small_packet = ENET_Dequeue_Buffer((pointer *)&fec_context_ptr->SMALL_BUFFERS);
                        
                        if (small_packet) {
                           _mem_copy( fec_context_ptr->FRAGS[0].FRAGMENT, small_packet, length );

                           pcb_ptr->FRAG[0].FRAGMENT = small_packet;
                           pcb_ptr->FREE = MCF5XXX_FEC_rx_free_small;

                           consumed = FALSE;

                           ENET_INC_STATS(ST_RX_COPY_SMALL);
                        }
                     }
                  }
                  
                                    
                  if (pcb_ptr) {  
                     pcb_ptr->FRAG[1].LENGTH = 0;
                     pcb_ptr->FRAG[1].FRAGMENT = NULL;

                     // Call the receiver's service function to pass the PCB to the receiver
                     fec_context_ptr->CurrentRxECB->SERVICE(pcb_ptr, fec_context_ptr->CurrentRxECB->PRIVATE);

                     // and clear the current ECB and PCB info, as it's gone to the receiver now.
                     fec_context_ptr->CurrentRxECB = NULL;
                     fec_context_ptr->CurrentRxFrag = 0;
                  }                  
                  
                  
               } else {

                  // Couldn't get a Receive PCB, so need to discard buffers until last buffer in frame.
                  MCF5XXX_FEC_discard_current_rx(enet_ptr,fec_context_ptr,last);
                  ENET_INC_STATS(RX_PCBS_EXHAUSTED);
               }
            }
         }         
      }
      
      
      if (!consumed) {
         ENET_INC_STATS(COMMON.ST_RX_DISCARDED);
         ENET_Enqueue_Buffer((pointer*)&fec_context_ptr->RX_BUFFERS, buffer);
      }
   }
   MCF5XXX_FEC_add_buffers_to_rx_ring(fec_context_ptr);
} 

#else

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_discard_current_rx
*  Returned Value : void
*  Comments       :
 *
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_discard_current_rx(ENET_CONTEXT_STRUCT_PTR    enet_ptr,MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr, boolean last)
{
   uint_32  i;
   PCB_PTR pcb_ptr = (PCB_PTR) fec_context_ptr->CurrentRxPCB;
   
   fec_context_ptr->CurrentRxECB=NULL; 

   if (pcb_ptr) {
      for (i=0;i<fec_context_ptr->CurrentRxFrag;i++) {
         ENET_INC_STATS(COMMON.ST_RX_DISCARDED);
         ENET_Enqueue_Buffer((pointer*)&fec_context_ptr->RX_BUFFERS, pcb_ptr->FRAG[i].FRAGMENT);
      }
      QADD(fec_context_ptr->RxPCBHead, fec_context_ptr->RxPCBTail, pcb_ptr);

      fec_context_ptr->CurrentRxFrag=0;
      fec_context_ptr->CurrentRxPCB=NULL;
      MCF5XXX_FEC_add_buffers_to_rx_ring(fec_context_ptr);
   }
   
   fec_context_ptr->RxDiscarding = !last;
}      


  
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_process_rx_bds
*  Returned Value : void
*  Comments       :
*        Processes received buffers.
*
* NOTE: For FEC, a frame consists of one or more buffers.
*       For ENET, a packet consists of one or more fragments
*        Therefore, a frame = a packet, and a buffer = a fragment.
*
*
*END*-----------------------------------------------------------------*/

static void MCF5XXX_FEC_process_rx_bds
   (
         /* [IN] the Ethernet state structure */
      ENET_CONTEXT_STRUCT_PTR    enet_ptr
   )
{ /* Body */
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->DEVICE_CONTEXT_PTR;
   VMCF5XXX_FEC_BD_STRUCT_PTR       bd_ptr;
   PCB_PTR                          pcb_ptr=NULL;
   uint_16                          rx_status;
   uint_32                          length,i;
   uchar_ptr                        buffer, small_packet;
   boolean                          buffer_is_valid, processed, last;

   /* Dequeue all received buffers (fragments) */
   while (fec_context_ptr->ActiveRxBDs > 0) {

      bd_ptr = &fec_context_ptr->FEC_RX_RING_PTR[fec_context_ptr->NextRxBD];
      _DCACHE_INVALIDATE_MBYTES(bd_ptr, sizeof(MCF5XXX_FEC_BD_STRUCT));  

      if ((bd_ptr->CONTROL & MCF5XXX_FEC_BD_ETHER_RX_EMPTY) != 0) {
         break; // Currently being written to by MII
      }  

      BD_INC(fec_context_ptr->NextRxBD,fec_context_ptr->NumRxBDs);
      fec_context_ptr->ActiveRxBDs--;

      ENET_INC_STATS(COMMON.ST_RX_TOTAL);
      rx_status = bd_ptr->CONTROL;
      length = bd_ptr->LENGTH;
      buffer = bd_ptr->BUFFER;

      processed = FALSE;
      last = TRUE;
      
      // Start by validating the received buffer 
      buffer_is_valid = FALSE;
      if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_TRUNCATED) {
      
         ENET_INC_STATS(ST_RX_RUNT);
     
      } else if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_LAST_FRAME) {
         
         // Some error bits can only be checked on the last buffer
         
         // Overrun needs to be checked first,  If this bit is 
         // set, the other status bits, M, LG, NO, CR, and CL lose their normal meaning and are zero. This bit 
         // is valid only if the L-bit is set.
         if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_OVERRUN) {
            ENET_INC_STATS(ST_RX_OVERRUN);
         
         } else if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_LENGTH_VIOLATION) {
            ENET_INC_STATS(ST_RX_GIANT);
            
         } else if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_NON_OCTET) {
            ENET_INC_STATS(ST_RX_ALIGN);
            
         } else if (rx_status & MCF5XXX_FEC_BD_ETHER_RX_CRC_ERROR) {
            ENET_INC_STATS(ST_RX_FCS);
         } else {
            // Good buffer (with Last bit set). Can only be processed if we are not currently discarding.
            buffer_is_valid = !fec_context_ptr->RxDiscarding;
         }
         
      }  else {
         // Good buffer (without Last bit set). Can only be processed if we are not currently discarding.
         buffer_is_valid = !fec_context_ptr->RxDiscarding;
         last = FALSE;
      }      

      if (buffer_is_valid) {
         // make sure we don't examine a cached copy of the buffer
         _DCACHE_INVALIDATE_MBYTES(buffer, length);  

         // Check to see if there is a receiver - if there is, this is not the first buffer of the frame.
         if (fec_context_ptr->CurrentRxECB==NULL) {
            
            // There wasn't, so it is the first buffer of a frame. Check to see if there is a receiver registered for this packet's 
            // destination and protocol. We can do this on the first buffer of the frame, since this information always fits in 
            // the first buffer of a frame.
            fec_context_ptr->CurrentRxECB = ENET_find_receiver(enet_ptr, (ENET_HEADER_PTR) buffer, &length);
   
            if (fec_context_ptr->CurrentRxECB ) {
               // There is a receiver, so need to allocate a receive PCB
               QGET(fec_context_ptr->RxPCBHead, fec_context_ptr->RxPCBTail, pcb_ptr);
               if (pcb_ptr) {
                  // allocation successful, initialize new receive PCB
                  fec_context_ptr->CurrentRxPCB = pcb_ptr;
                  fec_context_ptr->CurrentRxFrag = 0;
                  pcb_ptr->FREE = MCF5XXX_FEC_rx_free;
                  pcb_ptr->PRIVATE = (pointer)enet_ptr;
                  
               } else {
                  // Couldn't get a Receive PCB, so need to discard buffers until last buffer in frame.
                  fec_context_ptr->RxDiscarding = !last;
                  fec_context_ptr->CurrentRxECB = NULL;
               }
            
            } else {
               // There isn't a receiver, so need to discard buffers until last buffer in frame.
               fec_context_ptr->RxDiscarding = !last;
               pcb_ptr = NULL;
            }
            
         
         } else {
            // we are already have a receiving ECB, and therefore a PCB.
            pcb_ptr = fec_context_ptr->CurrentRxPCB;
         }

         if (pcb_ptr) {
         
            // We have a receiver (ecb) and a pcb, so the packet can be processed.
            processed = TRUE;                  

            // Add the packet to the list of fragments in the PCB               
            pcb_ptr->FRAG[fec_context_ptr->CurrentRxFrag].FRAGMENT = buffer;
       
            // Check to see if this is the last buffer in the frame
            if (last) {
               // need to compute the length of this fragment, because the length on a BD with the L bit set
               // is not the length of the buffer, it is the length of the frame.
               for (i=0;i<fec_context_ptr->CurrentRxFrag;i++) {
                  length -= pcb_ptr->FRAG[i].LENGTH;
               }
               // remove CRC
               pcb_ptr->FRAG[fec_context_ptr->CurrentRxFrag].LENGTH = length - ENET_FRAMESIZE_TAIL;
                
               // Terminate the fragment list in the PCB.
               pcb_ptr->FRAG[fec_context_ptr->CurrentRxFrag+1].LENGTH = 0;
               pcb_ptr->FRAG[fec_context_ptr->CurrentRxFrag+1].FRAGMENT = 0;

               // Call the receiver's service function to pass the PCB to the receiver
               fec_context_ptr->CurrentRxECB->SERVICE(pcb_ptr, fec_context_ptr->CurrentRxECB->PRIVATE);

               // and clear the current ECB and PCB info, as it's gone to the receiver now.
               fec_context_ptr->CurrentRxECB = NULL;
               fec_context_ptr->CurrentRxPCB = NULL;
               fec_context_ptr->CurrentRxFrag = 0;
            } else {
               pcb_ptr->FRAG[fec_context_ptr->CurrentRxFrag].LENGTH = length;
               
               fec_context_ptr->CurrentRxFrag++;
               
               // Not the last frame in the packet. Have to make sure there is room for at least one
               // more fragment. If not, the packet is too large
               if (fec_context_ptr->CurrentRxFrag >= MCF5XXX_MAX_FRAGS) {
                  MCF5XXX_FEC_discard_current_rx(enet_ptr,fec_context_ptr,last);
               }                     
            }
         }
      } else {
         // Was a buffer with an error
         ENET_INC_STATS(COMMON.ST_RX_ERRORS);
         MCF5XXX_FEC_discard_current_rx(enet_ptr,fec_context_ptr,last);
      } 
      
     
      if (!processed) {
         ENET_INC_STATS(COMMON.ST_RX_DISCARDED);
         ENET_Enqueue_Buffer((pointer*)&fec_context_ptr->RX_BUFFERS, buffer);
         MCF5XXX_FEC_add_buffers_to_rx_ring(fec_context_ptr);
      }
   } 
} 

#endif                


/*NOTIFIER*-------------------------------------------------------------
*
*  Function Name  : MCF5XXX_FEC_RX_ISR
*  Returned Value : void
*  Comments       :
*        Interrupt service routine for Rx.
*
*END*-----------------------------------------------------------------*/

void MCF5XXX_FEC_RX_ISR
   (
         /* [IN] the Ethernet state structure */
      pointer  enet
   )
{ /* Body */

   ENET_CONTEXT_STRUCT_PTR          enet_ptr = (ENET_CONTEXT_STRUCT_PTR)enet;
   MCF5XXX_FEC_CONTEXT_STRUCT_PTR   fec_context_ptr = (MCF5XXX_FEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   VMCF5XXX_FEC_STRUCT_PTR          fec_ptr= fec_context_ptr->FEC_ADDRESS;
   uint_32                          events;

   if (fec_ptr == NULL) return;

   events = fec_ptr->EIR;
   while (events & (MCF5XXX_FEC_EIR_RXF | MCF5XXX_FEC_EIR_RXB)) {

      /* clear the RX interrupt */
      fec_ptr->EIR = (MCF5XXX_FEC_EIR_RXF | MCF5XXX_FEC_EIR_RXB); 
      MCF5XXX_FEC_process_rx_bds(enet_ptr);

      events = fec_ptr->EIR;
   }
} 


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/int/serl_int_kuart.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serl_int_kuart.c$
* $Version : 3.8.10.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This file contains the low level functions for the interrupt driven
*   serial I/O for the SCI device.
*
*END************************************************************************/

#include "mqx.h"
#include "bsp.h"
#include "io_prv.h"
#include "charq.h"
#include "fio_prv.h"
#include "serinprv.h"

/* Polled functions used */
extern uint_32 _kuart_change_baudrate(UART_MemMapPtr, uint_32, uint_32);
extern uint_32 _kuart_polled_init(KUART_INIT_STRUCT_PTR, pointer _PTR_, char _PTR_);
extern uint_32 _kuart_polled_deinit(KUART_INIT_STRUCT_PTR, KUART_INFO_STRUCT_PTR);
extern uint_32 _kuart_polled_ioctl(KUART_INFO_STRUCT_PTR, uint_32, uint_32_ptr);

/* Interrupt driver functions */

extern void    _kuart_int_putc(IO_SERIAL_INT_DEVICE_STRUCT_PTR, char);
extern uint_32 _kuart_int_init(IO_SERIAL_INT_DEVICE_STRUCT_PTR, char _PTR_);
extern uint_32 _kuart_int_deinit(KUART_INIT_STRUCT_PTR, KUART_INFO_STRUCT_PTR);
extern uint_32 _kuart_int_enable(KUART_INFO_STRUCT_PTR);
extern void    _kuart_int_err_isr(pointer);
extern void    _kuart_int_rx_tx_isr(pointer);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_int_peripheral_enable
* Returned Value   : None
* Comments         :
*    Enables the SCI peripheral.
*
*END*----------------------------------------------------------------------*/

static void _kuart_int_peripheral_enable
    (
        /* [IN] SCI channel */
        UART_MemMapPtr sci_ptr
    )
{
    /* Enable only receive interrupt, transmit will be enabled during sending first character */
    sci_ptr->C2 |= UART_C2_RE_MASK | UART_C2_TE_MASK | UART_C2_RIE_MASK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_int_peripheral_disable
* Returned Value   : None
* Comments         :
*    Disables the SCI peripheral.
*
*END*----------------------------------------------------------------------*/

static void _kuart_int_peripheral_disable
    (
        /* [IN] SCI channel */
        UART_MemMapPtr sci_ptr
    )
{
    /* Transmitter and receiver disable */
    sci_ptr->C2 &= (~ (UART_C2_RE_MASK | UART_C2_TE_MASK | UART_C2_RIE_MASK | UART_C2_TIE_MASK));
}


#if MQX_ENABLE_LOW_POWER

extern LPM_NOTIFICATION_RESULT _io_serial_int_clock_configuration_callback (LPM_NOTIFICATION_STRUCT_PTR, pointer);
extern LPM_NOTIFICATION_RESULT _io_serial_int_operation_mode_callback (LPM_NOTIFICATION_STRUCT_PTR, pointer);

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_serial_int_clock_configuration_callback
* Returned Value   : Notification error code
* Comments         :
*    Low power clock configuration callback for int serial.
*
*END*----------------------------------------------------------------------*/

LPM_NOTIFICATION_RESULT _io_serial_int_clock_configuration_callback
    (
        /* [IN] Low power notification */
        LPM_NOTIFICATION_STRUCT_PTR   notification,

        /* [IN/OUT] Device specific data */
        pointer                       device_specific_data
    )
{
    IO_SERIAL_INT_DEVICE_STRUCT_PTR dev_ptr = device_specific_data;
    KUART_INIT_STRUCT_PTR           init_data = dev_ptr->DEV_INIT_DATA_PTR;
    uint_8                          flags;

    /* Get the device registers */
    UART_MemMapPtr sci_ptr = _bsp_get_serial_base_address (init_data->DEVICE);
    if (NULL == sci_ptr)
    {
        return LPM_NOTIFICATION_RESULT_ERROR;
    }

    if (LPM_NOTIFICATION_TYPE_PRE == notification->NOTIFICATION_TYPE)
    {
        /* Lock access from the higher level */
        _lwsem_wait (&(dev_ptr->LPM_INFO.LOCK));

        /* Enable module clocks to be able to write registers */
        _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_ENABLE);

        /* Flush output if enabled */
        if (sci_ptr->C2 & UART_C2_TE_MASK)
        {
            while (! (sci_ptr->SFIFO & UART_SFIFO_TXEMPT_MASK))
                { };
            while (! (sci_ptr->S1 & UART_S1_TC_MASK))
                { };
        }

        /* Turn off module */
        _kuart_int_peripheral_disable (sci_ptr);
    }

    if (LPM_NOTIFICATION_TYPE_POST == notification->NOTIFICATION_TYPE)
    {
        /* Enable module clocks to be able to write registers */
        _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_ENABLE);

        /* Setup same baudrate for new clock frequency */
        _kuart_change_baudrate (sci_ptr, _cm_get_clock (notification->CLOCK_CONFIGURATION, init_data->CLOCK_SOURCE), init_data->BAUD_RATE);

        /* Turn on module if requested */
        flags = init_data->OPERATION_MODE[notification->OPERATION_MODE].FLAGS;
        if ((flags & IO_PERIPHERAL_MODULE_ENABLE) && (dev_ptr->COUNT > 0))
        {
            _kuart_int_peripheral_enable (sci_ptr);
        }

        /* Disable module clocks if required */
        if (flags & IO_PERIPHERAL_CLOCK_DISABLE)
        {
            _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_DISABLE);
        }

        /* Unlock */
        _lwsem_post (&(dev_ptr->LPM_INFO.LOCK));
    }
    return LPM_NOTIFICATION_RESULT_OK;
}

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_serial_int_operation_mode_callback
* Returned Value   : Notification error code
* Comments         :
*    Low power operation mode callback for int serial.
*
*END*----------------------------------------------------------------------*/

LPM_NOTIFICATION_RESULT _io_serial_int_operation_mode_callback
    (
        /* [IN] Low power notification */
        LPM_NOTIFICATION_STRUCT_PTR       notification,

        /* [IN/OUT] Device specific data */
        pointer                           device_specific_data
    )
{
    IO_SERIAL_INT_DEVICE_STRUCT_PTR     dev_ptr = device_specific_data;
    KUART_INIT_STRUCT_PTR               init_data = dev_ptr->DEV_INIT_DATA_PTR;
    uint_8                              flags, tmp, bits;

    if (LPM_NOTIFICATION_TYPE_PRE == notification->NOTIFICATION_TYPE)
    {
        /* Get the device registers */
        UART_MemMapPtr sci_ptr = _bsp_get_serial_base_address (init_data->DEVICE);
        if (NULL == sci_ptr)
        {
            return LPM_NOTIFICATION_RESULT_ERROR;
        }

        /* Lock access from the higher level */
        _lwsem_wait (&(dev_ptr->LPM_INFO.LOCK));

        /* Get required HW changes */
        flags = init_data->OPERATION_MODE[notification->OPERATION_MODE].FLAGS;

        /* Setup module clock to be able to write registers */
        _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_ENABLE);

        /* Flush output if enabled */
        if (sci_ptr->C2 & UART_C2_TE_MASK)
        {
            while (! (sci_ptr->SFIFO & UART_SFIFO_TXEMPT_MASK))
                { };
            while (! (sci_ptr->S1 & UART_S1_TC_MASK))
                { };
        }

        /* Setup pin mux */
        _bsp_serial_io_init (init_data->DEVICE, flags & (~ IO_PERIPHERAL_CLOCK_DISABLE));

        /* Setup wakeup */
        if (flags & IO_PERIPHERAL_WAKEUP_ENABLE)
        {
            bits = init_data->OPERATION_MODE[notification->OPERATION_MODE].WAKEUP_BITS;
            tmp = sci_ptr->C1 & (~ (UART_C1_WAKE_MASK | UART_C1_ILT_MASK));
            sci_ptr->C1 = tmp | (bits & (UART_C1_WAKE_MASK | UART_C1_ILT_MASK));
            tmp = sci_ptr->C4 & (~ (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
            sci_ptr->C4 = tmp | (bits & (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
            sci_ptr->MA1 = init_data->OPERATION_MODE[notification->OPERATION_MODE].MA1;
            sci_ptr->MA2 = init_data->OPERATION_MODE[notification->OPERATION_MODE].MA2;
            tmp = sci_ptr->C2 & (~ (UART_C2_RWU_MASK));
            sci_ptr->C2 = tmp | (bits & UART_C2_RWU_MASK);
            dev_ptr->LPM_INFO.FLAGS = (flags & (IO_PERIPHERAL_WAKEUP_ENABLE | IO_PERIPHERAL_WAKEUP_SLEEPONEXIT_DISABLE));
        }
        else
        {
            sci_ptr->C2 &= (~ (UART_C2_RWU_MASK));
            sci_ptr->C1 &= (~ (UART_C1_WAKE_MASK | UART_C1_ILT_MASK));
            sci_ptr->C4 &= (~ (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
            sci_ptr->MA1 = 0;
            sci_ptr->MA2 = 0;
            dev_ptr->LPM_INFO.FLAGS = 0;
        }

        /* Enable/disable module according to  operation mode */
        if ((flags & IO_PERIPHERAL_MODULE_ENABLE) && (dev_ptr->COUNT > 0))
        {
            _kuart_int_peripheral_enable (sci_ptr);
        }
        else
        {
            _kuart_int_peripheral_disable (sci_ptr);
        }

        /* Disable module clocks if required */
        if (flags & IO_PERIPHERAL_CLOCK_DISABLE)
        {
            _bsp_serial_io_init (init_data->DEVICE, IO_PERIPHERAL_CLOCK_DISABLE);
        }

        /* Unlock */
        _lwsem_post (&(dev_ptr->LPM_INFO.LOCK));
    }
    return LPM_NOTIFICATION_RESULT_OK;
}

#endif


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_int_install
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    Install an interrupt driven uart serial device.
*
*END*----------------------------------------------------------------------*/

uint_32 _kuart_int_install
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr identifier,

      /* [IN] The I/O init data pointer */
      KUART_INIT_STRUCT_CPTR  init_data_ptr,

      /* [IN] The I/O queue size to use */
      uint_32  queue_size
   )
{ /* Body */

#if PE_LDD_VERSION
    if (PE_PeripheralUsed((uint_32)_bsp_get_serial_base_address(init_data_ptr->DEVICE)))
    {
        return IO_ERROR;
    }
#endif

   return _io_serial_int_install(identifier,
      (uint_32 (_CODE_PTR_)(pointer, char _PTR_))_kuart_int_init,
      (uint_32 (_CODE_PTR_)(pointer))_kuart_int_enable,
      (uint_32 (_CODE_PTR_)(pointer,pointer))_kuart_int_deinit,
      (void    (_CODE_PTR_)(pointer, char))_kuart_int_putc,
      (uint_32 (_CODE_PTR_)(pointer, uint_32, pointer))_kuart_polled_ioctl,
      (pointer)init_data_ptr, queue_size);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_int_init
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function initializes the SCI in interrupt mode.
*
*END*********************************************************************/

uint_32 _kuart_int_init
   (
      /* [IN] the interrupt I/O initialization information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the rest of the name of the device opened */
      char _PTR_                      open_name_ptr
   )
{ /* Body */
   KUART_INFO_STRUCT_PTR sci_info_ptr;
   KUART_INIT_STRUCT_PTR sci_init_ptr;
   uint_32                     result;

   sci_init_ptr = int_io_dev_ptr->DEV_INIT_DATA_PTR;
   result = _kuart_polled_init((pointer)sci_init_ptr, &int_io_dev_ptr->DEV_INFO_PTR, open_name_ptr);
   if (result != MQX_OK) {
       return(result);
   }/* Endif */

   sci_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;

   sci_info_ptr->OLD_ISR_DATA = _int_get_isr_data(sci_init_ptr->RX_TX_VECTOR);
   sci_info_ptr->OLD_ISR_EXCEPTION_HANDLER = _int_get_exception_handler(sci_init_ptr->RX_TX_VECTOR);


#if PSP_MQX_CPU_IS_KINETIS
   /* Init RX error interrupt vector */
   sci_info_ptr->OLD_ISR =
     _int_install_isr(sci_init_ptr->ERR_VECTOR, _kuart_int_err_isr, int_io_dev_ptr);
    _bsp_int_init(sci_init_ptr->ERR_VECTOR, sci_init_ptr->ERR_PRIORITY, 0, TRUE);
#endif

   /* Init RX/TX interrupt vector */
   sci_info_ptr->OLD_ISR =
    _int_install_isr(sci_init_ptr->RX_TX_VECTOR, _kuart_int_rx_tx_isr, int_io_dev_ptr);
    _bsp_int_init(sci_init_ptr->RX_TX_VECTOR, sci_init_ptr->RX_TX_PRIORITY, 0, TRUE);
   return(MQX_OK);

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_int_deinit
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function de-initializes the UART in interrupt mode.
*
*END*********************************************************************/

uint_32 _kuart_int_deinit
   (
      /* [IN] the interrupt I/O initialization information */
      KUART_INIT_STRUCT_PTR io_init_ptr,

      /* [IN] the address of the device specific information */
      KUART_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   UART_MemMapPtr sci_ptr = io_info_ptr->SCI_PTR;

   _kuart_polled_deinit(io_init_ptr, io_info_ptr);

   _int_install_isr(io_init_ptr->RX_TX_VECTOR, io_info_ptr->OLD_ISR, io_info_ptr->OLD_ISR_DATA);

   return(MQX_OK);

} /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _kuart_int_enable
* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    This function enables the UART interrupts mode.
*
*END*********************************************************************/

uint_32 _kuart_int_enable
   (
      /* [IN] the address of the device specific information */
      KUART_INFO_STRUCT_PTR io_info_ptr
   )
{ /* Body */
   uint_8                  flags = IO_PERIPHERAL_MODULE_ENABLE | IO_PERIPHERAL_CLOCK_ENABLE;
   UART_MemMapPtr          sci_ptr = io_info_ptr->SCI_PTR;

#if MQX_ENABLE_LOW_POWER

   uint_32 clock, mode = _lpm_get_operation_mode ();
   if (mode >= LPM_OPERATION_MODES)
   {
      return MQX_INVALID_CONFIGURATION;
   }
   flags = io_info_ptr->INIT.OPERATION_MODE[mode].FLAGS;

   clock = _lpm_get_clock_configuration ();
   if (clock >= BSP_CLOCK_CONFIGURATIONS)
   {
      return MQX_INVALID_CONFIGURATION;
   }
#endif

   /* Enable module clocks to be able to write registers */
   _bsp_serial_io_init (io_info_ptr->INIT.DEVICE, IO_PERIPHERAL_CLOCK_ENABLE);

   /* Enable/disable module */
   if (flags & IO_PERIPHERAL_MODULE_ENABLE)
   {
      _kuart_int_peripheral_enable (sci_ptr);
   }
   else
   {
      _kuart_int_peripheral_disable (sci_ptr);
   }

   /* Disable module clocks if required */
   if (flags & IO_PERIPHERAL_CLOCK_DISABLE)
   {
      _bsp_serial_io_init (io_info_ptr->INIT.DEVICE, IO_PERIPHERAL_CLOCK_DISABLE);
   }

   return MQX_OK;

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_int_err_isr
* Returned Value   : none
* Comments         :
*   interrupt handler for the serial error interrupts.
*
*************************************************************************/

void _kuart_int_err_isr
   (
      /* [IN] the address of the device specific information */
      pointer parameter
   )
{ /* Body */

   IO_SERIAL_INT_DEVICE_STRUCT_PTR        int_io_dev_ptr = parameter;
   KUART_INFO_STRUCT_PTR                  sci_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   UART_MemMapPtr                         sci_ptr = sci_info_ptr->SCI_PTR;
   uint_16                                stat = sci_ptr->S1;

#if MQX_ENABLE_LOW_POWER

    if (int_io_dev_ptr->LPM_INFO.FLAGS & IO_PERIPHERAL_WAKEUP_ENABLE)
    {
        /* Disable wakeup settings */
        int_io_dev_ptr->LPM_INFO.FLAGS &= (~ IO_PERIPHERAL_WAKEUP_ENABLE);
        sci_ptr->C2 &= (~ (UART_C2_RWU_MASK));
        sci_ptr->C1 &= (~ (UART_C1_WAKE_MASK | UART_C1_ILT_MASK));
        sci_ptr->C4 &= (~ (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
        sci_ptr->MA1 = 0;
        sci_ptr->MA2 = 0;

        /* Do not return to CPU sleep anymore */
        if (int_io_dev_ptr->LPM_INFO.FLAGS & IO_PERIPHERAL_WAKEUP_SLEEPONEXIT_DISABLE)
        {
            int_io_dev_ptr->LPM_INFO.FLAGS &= (~ IO_PERIPHERAL_WAKEUP_SLEEPONEXIT_DISABLE);
            _lpm_wakeup_core ();
        }
    }

#endif

   ++sci_info_ptr->INTERRUPTS;

   if(stat & UART_S1_OR_MASK) {
      ++sci_info_ptr->RX_OVERRUNS;
   }
   if(stat & UART_S1_PF_MASK) {
      ++sci_info_ptr->RX_PARITY_ERRORS;
   }
   if(stat & UART_S1_NF_MASK) {
      ++sci_info_ptr->RX_NOISE_ERRORS;
   }
   if(stat & UART_S1_FE_MASK) {
      ++sci_info_ptr->RX_FRAMING_ERRORS;
   }

   /*
   if "framming error" or "overrun" error occours 
   perform 'S1' cleanup. if not, 'S1' cleanup will be 
   performed during regular reading of 'D' register.
   */
   if (stat & (UART_S1_OR_MASK | UART_S1_FE_MASK))
   {
      // reading register 'D' to cleanup 'S1' may cause 'RFIFO' underflow
      sci_ptr->D;
      // if 'RFIFO' underflow detected, perform flush to reinitialize 'RFIFO'
      if (sci_ptr->SFIFO & UART_SFIFO_RXUF_MASK)
      {
         sci_ptr->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
         sci_ptr->SFIFO |= UART_SFIFO_RXUF_MASK;
      }
      // set errno. transmit is corrupted, nothing to process
      // TODO: add valid errno. IO_ERROR causes signed/unsigned assignment warning
      // _task_set_error(IO_ERROR);
   }

}  /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _kuart_int_rx_tx_isr
* Returned Value   : none
* Comments         :
*   interrupt handler for the serial input interrupts.
*
*************************************************************************/

void _kuart_int_rx_tx_isr
   (
      /* [IN] the address of the device specific information */
      pointer parameter
   )
{ /* Body */
   IO_SERIAL_INT_DEVICE_STRUCT_PTR        int_io_dev_ptr = parameter;
   KUART_INFO_STRUCT_PTR                  sci_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   UART_MemMapPtr                         sci_ptr = sci_info_ptr->SCI_PTR;
   volatile int_32                        c;
   uint_16                                stat = sci_ptr->S1;

#if MQX_ENABLE_LOW_POWER

    if (int_io_dev_ptr->LPM_INFO.FLAGS & IO_PERIPHERAL_WAKEUP_ENABLE)
    {
        /* Disable wakeup settings */
        int_io_dev_ptr->LPM_INFO.FLAGS &= (~ IO_PERIPHERAL_WAKEUP_ENABLE);
        sci_ptr->C2 &= (~ (UART_C2_RWU_MASK));
        sci_ptr->C1 &= (~ (UART_C1_WAKE_MASK | UART_C1_ILT_MASK));
        sci_ptr->C4 &= (~ (UART_C4_MAEN1_MASK | UART_C4_MAEN2_MASK));
        sci_ptr->MA1 = 0;
        sci_ptr->MA2 = 0;

        /* Do not return to CPU sleep anymore */
        if (int_io_dev_ptr->LPM_INFO.FLAGS & IO_PERIPHERAL_WAKEUP_SLEEPONEXIT_DISABLE)
        {
            int_io_dev_ptr->LPM_INFO.FLAGS &= (~ IO_PERIPHERAL_WAKEUP_SLEEPONEXIT_DISABLE);
            _lpm_wakeup_core ();
        }
    }

#endif

   ++sci_info_ptr->INTERRUPTS;

   /* 
   process error flags in case:
   - there is single interrupt line for both data and errors
   - _kuart_int_err_isr has lower priority than _kuart_int_rx_tx_isr
   - error interrupts are not enabled
   */
   if(stat & UART_S1_OR_MASK) {
      ++sci_info_ptr->RX_OVERRUNS;
   }
   if(stat & UART_S1_PF_MASK) {
      ++sci_info_ptr->RX_PARITY_ERRORS;
   }
   if(stat & UART_S1_NF_MASK) {
      ++sci_info_ptr->RX_NOISE_ERRORS;
   }
   if(stat & UART_S1_FE_MASK) {
      ++sci_info_ptr->RX_FRAMING_ERRORS;
   }

   /*
   if "framming error" or "overrun" error occours 
   perform 'S1' cleanup. if not, 'S1' cleanup will be 
   performed during regular reading of 'D' register.
   */
   if (stat & (UART_S1_OR_MASK | UART_S1_FE_MASK))
   {
      // reading register 'D' to cleanup 'S1' may cause 'RFIFO' underflow
      sci_ptr->D;
      // if 'RFIFO' underflow detected, perform flush to reinitialize 'RFIFO'
      if (sci_ptr->SFIFO & UART_SFIFO_RXUF_MASK)
      {
         sci_ptr->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
         sci_ptr->SFIFO |= UART_SFIFO_RXUF_MASK;
      }
      // set errno. transmit is corrupted, nothing to process
      // TODO: add valid errno. IO_ERROR causes signed/unsigned assignment warning
      // _task_set_error(IO_ERROR);
      return;
   }

   /*
   try if RX buffer has some characters.
   */
   if (stat & UART_S1_RDRF_MASK) {
      // reading 'D' register performs also cleanup of 'S1'
      c = sci_ptr->D;
      if (!_io_serial_int_addc(int_io_dev_ptr, c)) {
          sci_info_ptr->RX_DROPPED_INPUT++;
      }
      sci_info_ptr->RX_CHARS++;
   }

   /* try if TX buffer is still not full */
   if (stat & UART_S1_TDRE_MASK) {
      c = _io_serial_int_nextc(int_io_dev_ptr);
      if (c >= 0) {
          sci_ptr->D = c;
      } else {
         /* All data sent, disable transmit interrupt */
         sci_ptr->C2 &= ~UART_C2_TIE_MASK;
      }
      sci_info_ptr->TX_CHARS++;
   }

}  /* Endbody */

/*FUNCTION****************************************************************
*
* Function Name    : _kuart_int_putc
* Returned Value   : none
* Comments         :
*   This function is called to write out the first character, when
* the output serial device and output ring buffers are empty.
*
*END*********************************************************************/

void _kuart_int_putc
   (
      /* [IN] the address of the device specific information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the character to write out now */
      char                       c
   )
{ /* Body */
   KUART_INFO_STRUCT_PTR                  sci_info_ptr;
   UART_MemMapPtr                         sci_ptr;

   sci_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
   sci_ptr = sci_info_ptr->SCI_PTR;

   while (!(sci_ptr->S1 & UART_S1_TDRE_MASK)) {
      /* Wait while buffer is full */
   } /* Endwhile */

   sci_ptr->D = c;
   sci_info_ptr->TX_CHARS++;

   /* Enable transmit iterrupt */
   sci_ptr->C2 |= UART_C2_TIE_MASK;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/tcpip/iputil.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: iputil.c$
* $Version : 3.8.9.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains various IP layer functions.
*
*END************************************************************************/

#include <rtcs.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"

#if RTCSCFG_ENABLE_IP4 

/* Used for most of the IP utility functions */
struct IP_util_struct {
   IP_IF_PTR      ipif;
   _ip_address    ipaddr;
   boolean        bool;
   uint_32        num;
};


/*FUNCTION*-------------------------------------------------------------
*
* Function Name    : IP_get_netmask
* Returned Value   : boolean
* Comments         : Gets the network mask. Returns TRUE if found, or
*                    FALSE if no netmask is found.
*
*END*-----------------------------------------------------------------*/

struct IPIF_getmask_struct {
   IP_IF_PTR      netif;
   _ip_address    address;
   _ip_address    mask;
};

static boolean IP_get_netmask_test
   (
      pointer  node,
      pointer  data
   )
{ /* Body */
   IP_ROUTE_PTR                      route = node;
   struct IPIF_getmask_struct _PTR_  getmask = data;
   IP_ROUTE_DIRECT_PTR               search_ptr;

   if (route->DIRECT) {
      search_ptr = route->DIRECT;
      do {
         if (search_ptr->ADDRESS == getmask->address &&
             search_ptr->DESTIF == getmask->netif)
         {
            getmask->mask = route->NODE.MASK;
            return TRUE;
         } /* Endif */
         search_ptr = search_ptr->NEXT;
      } while(search_ptr != route->DIRECT);
   } /* Endif */

   return FALSE;

} /* Endbody */


boolean IP_get_netmask
   (
      _rtcs_if_handle   ihandle,    /* [IN] Interface */
      _ip_address       address,    /* [IN] IP address */
      _ip_address _PTR_ mask_ptr    /* [OUT] netwask for the IP and interface */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg( IP );
   struct IPIF_getmask_struct    getmask;

   getmask.netif     = ihandle;
   getmask.address   = address;
   getmask.mask      = 1;   /* Invalid mask */

   IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, address,
      IP_get_netmask_test, &getmask);

   if (getmask.mask == 1) {
      return FALSE;
   } /* Endif */

   *mask_ptr = getmask.mask;
   return TRUE;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_get_ipif_addr
*  Returned Value : the ip address
*  Comments       : return the ip address of the interface
*
*END*-----------------------------------------------------------------*/

static boolean IP_get_ipif_addr_test
   (
      _ip_address    node_ip,
      _ip_address    node_mask,
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct IP_util_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                  route = node_data;
   IP_ROUTE_DIRECT_PTR           search_ptr;

   /* Make sure there are direct interfaces, with full IP addresses */
   if (!~node_mask && route && route->DIRECT) {
      search_ptr = route->DIRECT;
      do {
         if (search_ptr->NETIF == testdata->ipif) {
            testdata->ipaddr = node_ip;
            return TRUE;
         } /* Endif */
         search_ptr = search_ptr->NEXT;
      } while(search_ptr != route->DIRECT);
   } /* Endif */

   return FALSE;

} /* Endbody */


_ip_address IP_get_ipif_addr
   (
      IP_IF_PTR      ipif        /* [IN] the local interface */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg( IP );
   struct IP_util_struct   testdata;

   testdata.ipif     = ipif;
   testdata.ipaddr   = INADDR_ANY;

   /* Check all nodes of the tree */
   IPRADIX_walk(&IP_cfg_ptr->ROUTE_ROOT.NODE, IP_get_ipif_addr_test, &testdata);

   return testdata.ipaddr;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_is_local
*  Returned Value : TRUE or FALSE
*  Comments       :
*        Decides whether or not an IP address is local to an interface.
*        if iflocal is null, check all the interfaces.
*
*END*-----------------------------------------------------------------*/

static void IP_is_local_test
   (
      pointer _PTR_  node,
      pointer        data
   )
{ /* Body */
   struct IP_util_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                  route = NULL;
   IP_ROUTE_DIRECT_PTR           search_ptr = NULL;

   if (*node) {
      route = *node;
      search_ptr = route->DIRECT;
   } /* Endif */

   if (search_ptr) {
      do {
         if ((search_ptr->NETIF == testdata->ipif || testdata->ipif == NULL) &&
             (testdata->ipaddr == search_ptr->ADDRESS))
         {
            testdata->bool = TRUE;
            break;
         } /* Endif */
         search_ptr = search_ptr->NEXT;
      } while(search_ptr != route->DIRECT);
   } /* Endif */

} /* Endbody */


boolean IP_is_local
   (
      IP_IF_PTR      iflocal,    /* [IN] the local interface */
      _ip_address    iplocal     /* [IN] the IP address to test */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   struct IP_util_struct   testdata;

   testdata.ipif     = iflocal;
   testdata.ipaddr   = iplocal;
   testdata.bool     = FALSE;

   /* Will make testdata.bool TRUE if ip is local to interface */
   IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, iplocal, 0xFFFFFFFF, 0,
      IP_is_local_test, &testdata);

   return testdata.bool;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_is_direct
*  Returned Value : TRUE or FALSE
*  Comments       :
*        Decides whether or not an IP address can be directly reached
*        through a given local interface.
*
*END*-----------------------------------------------------------------*/

static boolean IP_is_direct_test
   (
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct IP_util_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                  route = node_data;

   if (route->DIRECT) {
      IP_ROUTE_DIRECT_PTR direct = route->DIRECT;
      do {
         if ((direct->DESTIF == testdata->ipif || testdata->ipif == NULL)) {
            testdata->bool = TRUE;
            return TRUE;
         } /* Endif */
         direct = direct->NEXT;
      } while(direct != route->DIRECT);
   } /* Endif */

   if (route->VIRTUAL) {
      IP_ROUTE_VIRTUAL_PTR virtual = route->VIRTUAL;
      do {
         if ((virtual->DESTIF == testdata->ipif || testdata->ipif == NULL)) {
            testdata->bool = TRUE;
            return TRUE;
         } /* Endif */
         virtual = virtual->NEXT;
      } while(virtual != route->VIRTUAL);
   } /* Endif */

   return FALSE;
} /* Endbody */


boolean IP_is_direct
   (
      IP_IF_PTR      iflocal,
       /* [IN] the local interface */
      _ip_address    iplocal
       /* [IN] the IP address to test */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   struct IP_util_struct   testdata;

   testdata.ipif     = iflocal;
   testdata.ipaddr   = iplocal;
   testdata.bool     = FALSE;

   IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, iplocal,
      IP_is_direct_test, &testdata);

   return testdata.bool;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_is_gate
*  Returned Value : TRUE or FALSE
*  Comments       :
*        Decides whether or not an IP address is a gateway for another.
*
*END*-----------------------------------------------------------------*/

static boolean IP_is_gate_test
   (
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct IP_util_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                  route = node_data;
   IP_ROUTE_INDIRECT_PTR         indirect;

   if (route->INDIRECT) {
      indirect = route->INDIRECT;
      do {
         if (indirect->GATEWAY == testdata->ipaddr) {
            testdata->bool = TRUE;
            return TRUE;
         } /* Endif */
         indirect = indirect->NEXT;
      } while(indirect != route->INDIRECT);
   } /* Endif */

   return FALSE;

} /* Endbody */


boolean IP_is_gate
   (
      _ip_address    gateway,
            /* [IN] the gateway */
      _ip_address    ipremote
            /* [IN] the IP address to test */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   struct IP_util_struct   data;

   data.ipaddr = gateway;
   data.bool = FALSE;

   IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, ipremote,
      IP_is_gate_test, &data);

   return data.bool;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_MTU
*  Returned Value : MTU for destination
*  Comments       :
*        Determines the Maximum Transmission Unit for a destination;
*        returns IP_DEFAULT_MTU if destination is not directly connected.
*
*END*-----------------------------------------------------------------*/

static boolean IP_MTU_test
   (
      pointer        node_data,
      pointer        data
   )
{ /* Body */
   struct IP_util_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                  route = node_data;
   IP_ROUTE_VIRTUAL_PTR          virtual;

   if (route->DIRECT) {
      testdata->num = route->DIRECT->DESTIF->MTU;
      return TRUE;
   } /* Endif */

   virtual = route->VIRTUAL;
   if (virtual) {
      if ((testdata->ipaddr & virtual->SOURCE_MASK) == virtual->SOURCE_NET) {
         if (virtual->DESTIF->MTU_FN) {
            testdata->num = virtual->DESTIF->MTU_FN(virtual->DATA);
         } else {
            testdata->num = virtual->DESTIF->MTU;
         } /* Endif */
         return TRUE;
      } /* Endif */
   } /* Endif */

   return FALSE;

} /* Endbody */


uint_32 IP_MTU
   (
      _ip_address    iplocal,
            /* [IN] the local IP address */
      _ip_address    ipremote
            /* [IN] the remote IP address to test */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   struct IP_util_struct   data;

   data.ipaddr = iplocal;
   data.num    = IP_DEFAULT_MTU;

   IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, ipremote,
      IP_MTU_test, &data);

   return data.num;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_find_if
*  Returned Value : interface handle
*  Comments       :
*        Returns the interface handle for a local IP address.
*
*END*-----------------------------------------------------------------*/

static void IP_find_if_test
   (
      pointer _PTR_  node,
      pointer        data
   )
{ /* Body */
   struct IP_util_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                  route;

   if (*node) {
      route = *node;
      if (route->DIRECT) {
         testdata->ipif = route->DIRECT->NETIF;
      } /* Endif */
   } /* Endif */

} /* Endbody */


IP_IF_PTR IP_find_if
   (
      _ip_address    iplocal
            /* [IN] the IP address to test */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   struct IP_util_struct   data;

   data.ipif     = NULL;
   data.ipaddr   = iplocal;

   IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, iplocal, 0xFFFFFFFF, 0,
      IP_find_if_test, &data);

   return data.ipif;

} /* Endbody */


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : IP_route_find
*  Returned Value : source IP address
*  Comments       :
*        Determine the source IP address to use when routing to a
*        specific destination.
*
*END*-----------------------------------------------------------------*/

static boolean IP_route_find_test
   (
      pointer  node,
      pointer  data
   )
{ /* Body */
   struct IP_util_struct _PTR_   testdata = data;
   IP_ROUTE_PTR                  route = node;

   /* Check for a direct route. */
   if (route->DIRECT) {
      testdata->ipaddr = route->DIRECT->ADDRESS;
      return TRUE;
   } /* Endif */

   /* Check for a numbered virtual route. */
   if (route->VIRTUAL) {
      IP_ROUTE_VIRTUAL_PTR virtual = route->VIRTUAL;
      do {
         if (virtual->ADDRESS) {
            testdata->ipaddr = virtual->ADDRESS;
            return TRUE;
         } /* Endif */
         virtual = virtual->NEXT;
      } while (virtual != route->VIRTUAL);
   } /* Endif */

   /*
   ** If no direct route was found, search for a gateway.
   */
   if (testdata->bool && route->INDIRECT) {
      IP_ROUTE_INDIRECT_PTR indirect = route->INDIRECT;
      do {
         if (indirect->FLAGS & RTF_UP) {
            testdata->ipaddr = indirect->GATEWAY;
            testdata->bool = FALSE;
            return TRUE;
         } /* Endif */
         indirect = indirect->NEXT;
      } while (indirect != route->INDIRECT);
   } /* Endif */

   return FALSE;
} /* Endbody */


_ip_address IP_route_find
   (
      _ip_address    ipdest,
            /* [IN] the ultimate destination */
      uint_32        flags
            /* [IN] optional flags */
   )
{ /* Body */
   IP_CFG_STRUCT_PTR       IP_cfg_ptr = RTCS_getcfg(IP);
   struct IP_util_struct   data;
   _ip_address             gateway;

   data.ipaddr  = INADDR_ANY;
   if (!flags) {
      data.bool   = TRUE;       /* Check gateways */
   } else {
      data.bool   = FALSE;
   } /* Endif */

   IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, ipdest,
      IP_route_find_test, &data);

   /* If we have found a gateway, find source addr for the gateway */
   if (!data.bool) {
      gateway = data.ipaddr;
      data.ipaddr = INADDR_ANY;
      IPRADIX_findbest(&IP_cfg_ptr->ROUTE_ROOT.NODE, gateway,
         IP_route_find_test, &data);
   } /* Endif */

   return data.ipaddr;
} /* Endbody */

#endif /* RTCSCFG_ENABLE_IP4 */

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : RTCS_get_enet_handle
*  Returned Value : ethernet handle (pointer)
*  Comments       :
*        Returns the ethernet handle associated with given interface.
*
*END*-----------------------------------------------------------------*/

pointer RTCS_get_enet_handle
   (
      _rtcs_if_handle   ihandle    /* [IN] Interface */
   )
{
   return ((IP_IF_PTR)ihandle)->HANDLE;
}

#if RTCSCFG_ENABLE_IP6

/************************************************************************
* NAME: IP6_MTU
* RETURNS : MTU for destination
* DESCRIPTION: Determines the Maximum Transmission Unit for a destination;
*        returns IP6_DEFAULT_MTU if destination is not directly connected
*        or source is not our address.
*************************************************************************/
uint_32 IP6_MTU ( in6_addr *iplocal     /* [IN] the local IP address */,
                  in6_addr *ipremote    /* [IN] the remote IP address to test */ )
{ 
    uint_32 mtu = IP_DEFAULT_MTU;
    IP_IF_PTR dest_if; 

    if( iplocal == NULL)
    /* Determine a source address.*/
    {
        iplocal = (in6_addr *)ip6_if_select_src_addr(NULL, ipremote);
                
        if(iplocal == NULL)
        {
            goto FAIL;;
        } 
    }

    dest_if = ip6_if_get_by_addr(iplocal);
        
    if(dest_if)
    {
        mtu = dest_if->IP6_IF.ND6->mtu;
    }
    
FAIL:    
    return mtu;
}

/************************************************************************
* NAME: IP6_route_find
* RETURNS : Source IPv6 address.
* DESCRIPTION: Determine the source IPv6 address to use when routing to a
*              specific destination.
*************************************************************************/
in6_addr * IP6_route_find( in6_addr *ipdest   /* [IN] the ultimate destination */,
                                 uint_32 flags      /* [IN] optional flags (Not used - TBD delete it*/)
{
    in6_addr * addr = (in6_addr *)ip6_if_select_src_addr(NULL, ipdest); 

    return addr;
}

#endif /* RTCSCFG_ENABLE_IP6 */


/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/device/source/include/rtos/mqx_dev.h<|end_filename|>
#ifndef __mqx_dev_h__
#define __mqx_dev_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mqx_dev.h$
* $Version : 3.8.13.0$
* $Date    : Jul-2-2012$
*
* Comments:
*
* Description:      
*  This file contains device-specifc defines for MQX RTOS.
*                                                               
*END*********************************************************************/

#include <mqx.h>
#include <psp.h>
#include <bsp.h>
#include "devapi.h"

/*
**
** Low-level function list structure for USB
**
** This is the structure used to store chip specific functions to be called 
** by generic layer
*/
struct xd_struct;

typedef struct usb_dev_callback_functions_struct
{
   /* The Host/Device init function */
   USB_STATUS (_CODE_PTR_ DEV_PREINIT)(_usb_device_handle _PTR_);

   /* The Host/Device init function */
   USB_STATUS (_CODE_PTR_ DEV_INIT)(_usb_device_handle);

   /* The function to send data */
   USB_STATUS (_CODE_PTR_ DEV_SEND)(_usb_device_handle, struct xd_struct *);

   /* The function to receive data */
   USB_STATUS (_CODE_PTR_ DEV_RECV)(_usb_device_handle, struct xd_struct *);
   
   /* The function to cancel the transfer */
   USB_STATUS (_CODE_PTR_ DEV_CANCEL_TRANSFER)(_usb_device_handle, uint_8, uint_8);
   
   USB_STATUS (_CODE_PTR_ DEV_INIT_ENDPOINT)(_usb_device_handle, struct xd_struct *);
   
   USB_STATUS (_CODE_PTR_ DEV_DEINIT_ENDPOINT)(_usb_device_handle, uint_8, uint_8);
   
   USB_STATUS (_CODE_PTR_ DEV_UNSTALL_ENDPOINT)(_usb_device_handle, uint_8, uint_8);
   
   USB_STATUS (_CODE_PTR_ DEV_GET_ENDPOINT_STATUS)(_usb_device_handle, uint_8, uint_16_ptr);
   
   USB_STATUS (_CODE_PTR_ DEV_SET_ENDPOINT_STATUS)(_usb_device_handle, uint_8, uint_16);

   USB_STATUS (_CODE_PTR_ DEV_GET_TRANSFER_STATUS)(_usb_device_handle, uint_8, uint_8);
   
   USB_STATUS (_CODE_PTR_ DEV_SET_ADDRESS)(_usb_device_handle, uint_8);
   
   USB_STATUS (_CODE_PTR_ DEV_SHUTDOWN)(_usb_device_handle);
   
   USB_STATUS (_CODE_PTR_ DEV_GET_SETUP_DATA)(_usb_device_handle, uint_8, uint_8_ptr);
   
   USB_STATUS (_CODE_PTR_ DEV_ASSERT_RESUME)(_usb_device_handle);
   
   USB_STATUS (_CODE_PTR_ DEV_STALL_ENDPOINT)(_usb_device_handle, uint_8, uint_8);

} USB_DEV_CALLBACK_FUNCTIONS_STRUCT, _PTR_ USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR;

#define USB_uint_16_low(x)          ((x) & 0xFF)
#define USB_uint_16_high(x)         (((x) >> 8) & 0xFF)

#ifdef __cplusplus
extern "C" {
#endif
extern uint_8 _usb_dev_driver_install(uint_32, pointer);
extern uint_8 _usb_dev_driver_uninstall(void);
#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/fio/io_fprt.c<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: io_fprt.c$
* $Version : 3.8.5.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   This file contains the function for fprintf.
*
*END************************************************************************/

#include "mqx.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"

/*!
 * \brief Similar to the fprintf function of ANSI 'C'.
 * 
 * \param[in] file_ptr The stream to print upon.
 * \param[in] fmt_ptr  The format string to use for printing.
 * 
 * \return Number of output characters.  
 */ 
_mqx_int _io_fprintf
    (
      MQX_FILE_PTR file_ptr,
      const char _PTR_  fmt_ptr,
      
      ...
   )
{ /* Body */
   va_list  ap;
   _mqx_int  result;
   
   va_start(ap, fmt_ptr);
   result = 0;
   if ( file_ptr ) {
      result = _io_doprint(file_ptr, _io_fputc, -1, (char _PTR_)fmt_ptr, ap );
   } /* Endif */
   va_end(ap);
   return result;

} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/rtcs/source/include/udp.h<|end_filename|>
#ifndef __udp_h__
#define __udp_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: udp.h$
* $Version : 3.8.5.0$
* $Date    : Jun-14-2012$
*
* Comments:
*
*   This file contains the User Datagram Protocol definitions.
*   For more details, refer to RFC768.
*
*END************************************************************************/


/***************************************
**
** Constants
**
*/

/*
** UDP Open Options
*/
#define UDPOPT_CHKSUM_RX   0x0001      /* Option to bypass UDP checksum on Rx */
#define UDPOPT_CHKSUM_TX   0x0002      /* Option to bypass UDP checksum on Tx */
#define UDPOPT_NOBLOCK     0x0004      /* Option to send non-blocking         */


/***************************************
**
** Type definitions
**
*/


/*
** UDP Channel Block for listeners
*/
struct ucb_parm;
struct MCB;
typedef struct ucb_struct {

   struct ucb_struct _PTR_        NEXT;
   uint_32                 SOCKET;

   /* local UDP port */
   uint_16                 PORT;
   uint_16                 PCOUNT;

   void (_CODE_PTR_ SERVICE)(RTCSPCB_PTR, struct ucb_struct _PTR_);

   /*
   ** Queue of incoming packets
   */
   RTCSPCB_PTR    PHEAD;
   RTCSPCB_PTR    PTAIL;

   /*
   ** Queue of waiting receive requests
   */
   struct ucb_parm _PTR_   RHEAD;
   struct ucb_parm _PTR_   RTAIL;

   /* Checksum bypass on reception */
   boolean        BYPASS_RX;

   /* Checksum bypass on transmission */
   boolean        BYPASS_TX;

   /* Non-blocking mode */
   boolean        NONBLOCK_RX;
   boolean        NONBLOCK_TX;

   /* local IP address, usually INADDR_ANY */
   _ip_address    IPADDR;
   in6_addr       IPV6ADDR;  
   uint_32        IF_SCOPE_ID;
    
   /* list of joined multicast groups */
   struct mc_member _PTR_        MCB_PTR;
   uint_32 (_CODE_PTR_     IGMP_LEAVEALL)(struct mc_member _PTR_ _PTR_);

   /*
   ** Determines if a connection failure keeps the ucb's local IP,
   ** or if it resets it to INADDR_ANY
   */
   boolean        KEEP_IPADDR;

   /* Remote IP address and port when connected. (0 when not connected) */
   _ip_address    REMOTE_HOST;
   in6_addr       REMOTE_HOST6;  
   uint_16        REMOTE_PORT;
   uint_16        RESERVED0;

} UCB_STRUCT, _PTR_ UCB_STRUCT_PTR;

/*
** UDP parameters
*/
typedef struct ucb_parm {
   TCPIP_PARM              COMMON;
   struct ucb_parm _PTR_   NEXT;
   UCB_STRUCT_PTR          ucb;
   void (_CODE_PTR_        udpservice)(RTCSPCB_PTR, UCB_STRUCT_PTR);
   _ip_address             ipaddress;
#if RTCSCFG_ENABLE_IP6    
   in6_addr                ipv6address; 
   uint_32                 if_scope_id; 
#endif   
   uint_16                 udpport;
   uint_16                 udpflags;
   pointer                 udpptr;
   uint_32                 udpword;
} UDP_PARM, _PTR_ UDP_PARM_PTR;


/***************************************
**
** Prototypes
**
*/

extern uint_32 UDP_init
(
   void
);

extern void UDP_open     (UDP_PARM_PTR);
extern void UDP_bind     (UDP_PARM_PTR);

#if RTCSCFG_ENABLE_IP6
    extern void UDP_bind6    (UDP_PARM_PTR);
#endif

extern void UDP_connect  (UDP_PARM_PTR);

#if RTCSCFG_ENABLE_IP6
    extern void UDP_connect6 (UDP_PARM_PTR);
#endif

extern void UDP_close    (UDP_PARM_PTR);
extern void UDP_send     (UDP_PARM_PTR);
extern void UDP_receive  (UDP_PARM_PTR);

#if RTCSCFG_ENABLE_IP6
extern void UDP_receive6 (UDP_PARM_PTR);
#endif

extern void UDP_getopt   (UDP_PARM_PTR);
extern void UDP_setopt   (UDP_PARM_PTR);

extern uint_32 UDP_openbind_internal
(
   uint_16              localport,
   void (_CODE_PTR_     service)(RTCSPCB_PTR, UCB_STRUCT_PTR),
   UCB_STRUCT_PTR _PTR_ ucb
);

extern uint_32 UDP_close_internal
(
   UCB_STRUCT_PTR       ucb
);

#if RTCSCFG_ENABLE_IP6
    extern uint_32 UDP_send_internal6
    (
        UCB_STRUCT_PTR       ucb,        /* [IN] UDP layer context      */
        in6_addr             srcaddr,    /* [IN] source IPv6 address      */
        in6_addr             destaddr,   /* [IN] destination IPv6 address */
        uint_16              destport,   /* [IN] destination UDP port   */
        RTCSPCB_PTR          pcb_ptr,    /* [IN] packet to send         */
        uint_32              flags       /* [IN] optional flags         */
    );
#endif


extern uint_32 UDP_send_internal
(
   UCB_STRUCT_PTR       ucb,        /* [IN] UDP layer context      */
   _ip_address          srcaddr,    /* [IN] source IP address      */
   _ip_address          destaddr,   /* [IN] destination IP address */
   uint_16              destport,   /* [IN] destination UDP port   */
   RTCSPCB_PTR          pcb_ptr,    /* [IN] packet to send         */
   uint_32              flags       /* [IN] optional flags         */
);

extern uint_32 UDP_send_IF
(
   UCB_STRUCT_PTR,
   pointer,
   uint_16,
   RTCSPCB_PTR
);


#if RTCSCFG_ENABLE_IP6
    extern void UDP_service6        /* Use function like service for UDP v6*/
    (
        RTCSPCB_PTR,
        pointer
    );
#endif    

#if RTCSCFG_ENABLE_IP4
    extern void UDP_service         /* Use function like service for UDP v4*/
    (
        RTCSPCB_PTR,
        pointer
    );
#endif

    extern void UDP_service_common     /* This function called from UDP_service or UDP_service6 */ 
    (                               /* with parameter of INET FAMILY */
        RTCSPCB_PTR,
        pointer,
        uint_16                     /* INET FAMILY parameter */
    );

extern void UDP_process
(
   RTCSPCB_PTR,
   UCB_STRUCT_PTR
);

#if RTCSCFG_ENABLE_IP6
    extern void UDP_process6
    (
        RTCSPCB_PTR,
        UCB_STRUCT_PTR
    );
#endif    

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/Main/Temperature_control.c<|end_filename|>
#include <mqx.h>
#include <bsp.h>
#include <fio.h>
#include "App.h"

#define I2C_DEVICE_POLLED    "i2c0:"
#define I2C_DEVICE_INTERRUPT "ii2c0:"
#define I2C_MAX31725_ADDRESS  (0x90>>1)
#define I2C_SPEED            400000 

static  MQX_FILE_PTR   i2c0_fd;


/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
_mqx_int TempCtrl_init_drivers(void)
{
  _mqx_int param;

  i2c0_fd = fopen(I2C_DEVICE_POLLED, NULL);
  if ( i2c0_fd == NULL )
  {
    return MQX_ERROR;
  }
  param = I2C_SPEED;
  if ( ioctl(i2c0_fd, IO_IOCTL_I2C_SET_BAUD, &param)!= I2C_OK )
  {
    fclose(i2c0_fd);
    return MQX_ERROR;
  }
  if (ioctl(i2c0_fd, IO_IOCTL_I2C_SET_MASTER_MODE, NULL)!= I2C_OK )
  {
    fclose(i2c0_fd);
    return MQX_ERROR;
  }
  return MQX_OK;
}


/*-----------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------*/
_mqx_int TempCtrl_read_IGBT_temperature(float *temp_ptr)
{
  _mqx_int  param;
  _mqx_int  result;
  uchar     buf[4];
  _mqx_int  n;
  float     f;

  param = I2C_MAX31725_ADDRESS;
  if ( ioctl(i2c0_fd, IO_IOCTL_I2C_SET_DESTINATION_ADDRESS, &param)!= I2C_OK )
  {
    return MQX_ERROR;
  }
  fwrite(buf, 1, 0, i2c0_fd);
  if ( ioctl(i2c0_fd, IO_IOCTL_FLUSH_OUTPUT, &param) == I2C_OK )
  {
    if ( param )
    {
      ioctl(i2c0_fd, IO_IOCTL_I2C_STOP, NULL);
      return MQX_ERROR;
    }
  }
  else
  {
    return MQX_ERROR;
  }
  buf[0] = 0;
  result = fwrite(buf, 1, 1, i2c0_fd);
  if ( 1 != result )
  {
    return MQX_ERROR;
  }
  if (ioctl(i2c0_fd, IO_IOCTL_I2C_REPEATED_START, NULL)!= I2C_OK  )
  {
    return MQX_ERROR;
  }

  n = 2; // Читаем 2-а байта
  param = n;
  if (ioctl(i2c0_fd, IO_IOCTL_I2C_SET_RX_REQUEST, &param)!= I2C_OK)
  {
    return MQX_ERROR;
  }

  result = fread(buf, 1, n, i2c0_fd);
  if ( result != n )
  {
    return MQX_ERROR;
  }

  ioctl(i2c0_fd, IO_IOCTL_I2C_STOP, NULL);


  f =  (float)buf[0] + (float)buf[1]/256.0;
  *temp_ptr = f;
  return MQX_OK;
}


<|start_filename|>Firmware/Inverter_firmware/mcc/source/include/mcc_mqx.h<|end_filename|>
/*HEADER*********************************************************************
*
* Copyright (c) 2013 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************
* $FileName: mcc_mqx.h$
* $Version : 3.8.1.0$
* $Date    : Jul-3-2012$
*
* Comments:
*
*   This file contains prototypes for MQX-specific MCC library functions
*
*END************************************************************************/

#ifndef __MCC_MQX__
#define __MCC_MQX__

#include <mqx.h>
#include <bsp.h>
#include <lwevent.h>
#include "core_mutex.h"
#include "vybrid.h"

#define MCC_MQX_LWEVENT_COMPONENTS_COUNT   (8)
#define MCC_MQX_LWEVENT_GROUP_SIZE         (32)

#define MCC_MQX_NODE_NUMBER                (0)

#define MCC_DCACHE_ENABLE(n)               _DCACHE_ENABLE(n)
#define MCC_DCACHE_DISABLE()               _DCACHE_DISABLE()
#define MCC_DCACHE_FLUSH()                 _DCACHE_FLUSH()
#define MCC_DCACHE_FLUSH_LINE(p)           _DCACHE_FLUSH_LINE(p)
#define MCC_DCACHE_FLUSH_MLINES(p, m)      _DCACHE_FLUSH_MLINES(p, m)
#define MCC_DCACHE_INVALIDATE()            _DCACHE_INVALIDATE()
#define MCC_DCACHE_INVALIDATE_LINE(p)      _DCACHE_INVALIDATE_LINE(p)
#define MCC_DCACHE_INVALIDATE_MLINES(p, m) _DCACHE_INVALIDATE_MLINES(p, m)

/* Semaphore-related functions */
int mcc_init_semaphore(unsigned int);
int mcc_deinit_semaphore(unsigned int);
int mcc_get_semaphore(void);
int mcc_release_semaphore(void);

/* CPU-to-CPU interrupt-related functions */
int mcc_register_cpu_to_cpu_isr(void);
int mcc_generate_cpu_to_cpu_interrupt(void);

/* Memory management-related functions */
void mcc_memcpy(void*, void*, unsigned int);

#endif /* __MCC_MQX__ */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/psp/cortex_m/psp_gelms.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: psp_gelms.c$
* $Version : 3.7.3.0$
* $Date    : Feb-7-2011$
*
* Comments:
*
*   This file contains the functions for obtaining the elapsed milliseconds
*
*END************************************************************************/

#include "mqx_inc.h"


/*FUNCTION*-----------------------------------------------------------------
* 
* Function Name    : _psp_get_milliseconds_elapsed
* Returned Value   : uint_32 - number of milliseconds
* Comments         :
*    This function obtains current elapsed milliseconds
*
*END*----------------------------------------------------------------------*/

uint_32 _psp_get_elapsed_milliseconds
   (
      void
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   uint_64                ticks;
   uint_32                ms_per_tick;
   uint_32                ms;

   _GET_KERNEL_DATA(kernel_data);

   ticks = ((PSP_TICK_STRUCT_PTR)&kernel_data->TIME)->TICKS[0];
   ms_per_tick = 1000 / kernel_data->TICKS_PER_SECOND;
   if ((ms_per_tick * kernel_data->TICKS_PER_SECOND) == 1000) {
      ms = (uint_32)(ticks * ms_per_tick);
   } else {
      ms = (uint_32)((ticks * 1000) / kernel_data->TICKS_PER_SECOND);
   } /* Endif */
   return(ms);
   
} /* Endbody */

/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/ehci/ehci_main.h<|end_filename|>
#ifndef __ehci_main_h__
#define __ehci_main_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_main.h$
* $Version : 3.8.8.0$
* $Date    : Jun-7-2012$
*
* Comments:
*
*   
*
*END************************************************************************/
#include <mqx.h>

#include "usb.h"
#include "usb_prv.h"

#include "hostapi.h"

#include "ehci_main.h"
#include "ehci_prv.h"

#ifdef __cplusplus
extern "C" {
#endif

extern USB_STATUS _usb_ehci_send_data (_usb_host_handle, PIPE_STRUCT_PTR, TR_STRUCT_PTR);
extern USB_STATUS _usb_ehci_send_setup (_usb_host_handle, PIPE_STRUCT_PTR, TR_STRUCT_PTR);
extern USB_STATUS _usb_ehci_recv_data (_usb_host_handle, PIPE_STRUCT_PTR, TR_STRUCT_PTR);
extern USB_STATUS _usb_ehci_queue_pkts ( _usb_host_handle, EHCI_PIPE_STRUCT_PTR, EHCI_TR_STRUCT_PTR);
extern void _usb_ehci_init_Q_HEAD (_usb_host_handle, EHCI_PIPE_STRUCT_PTR, EHCI_QH_STRUCT_PTR, EHCI_QH_STRUCT_PTR, EHCI_QTD_STRUCT_PTR);
extern void _usb_ehci_init_QTD (_usb_host_handle, EHCI_QTD_STRUCT_PTR, uchar_ptr, uint_32);
extern uint_32 _usb_ehci_init_Q_element (_usb_host_handle, EHCI_PIPE_STRUCT_PTR, EHCI_TR_STRUCT_PTR);
extern uint_32 _usb_ehci_add_xfer_to_asynch_schedule_list (_usb_host_handle, EHCI_PIPE_STRUCT_PTR, EHCI_TR_STRUCT_PTR);
extern boolean _usb_ehci_process_port_change (_usb_host_handle);
extern void _usb_ehci_reset_and_enable_port (_usb_host_handle, uint_8);
extern void _usb_host_process_reset_recovery_done (_usb_host_handle);

extern void _usb_ehci_isr (_usb_host_handle);

extern USB_STATUS _usb_ehci_preinit (_usb_host_handle *handle);
extern USB_STATUS _usb_ehci_init (_usb_host_handle);
extern void _usb_ehci_free_QTD (_usb_host_handle, pointer);
extern void _usb_ehci_free_QH (_usb_host_handle, pointer);
extern USB_STATUS _usb_ehci_free_resources (_usb_host_handle, PIPE_STRUCT_PTR);
extern void _usb_ehci_process_tr_complete (_usb_host_handle);
extern void _usb_host_delay (_usb_host_handle, uint_32);

extern USB_STATUS _usb_ehci_open_pipe(_usb_host_handle handle, PIPE_STRUCT_PTR);

extern void _usb_ehci_process_timer(_usb_host_handle);
extern USB_STATUS _usb_ehci_update_dev_address(_usb_host_handle, PIPE_STRUCT_PTR);
#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/include/ipc.h<|end_filename|>
/*HEADER*********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipc.h$
* $Version : 3.8.8.0$
* $Date    : Oct-13-2011$
*
* Comments:
*
*   This file contains the definitions for the interprocessor 
*   communications component.
*
*END************************************************************************/
#ifndef __ipc_h__
#define __ipc_h__ 1

#include <mqx_cnfg.h>
#if (!MQX_USE_IPC) && (! defined (MQX_DISABLE_CONFIG_CHECK))
#error IPC component is currently disabled in MQX kernel. Please set MQX_USE_IPC to 1 in user_config.h and recompile kernel.
#endif

/*--------------------------------------------------------------------------*/
/*
 *                          CONSTANT DECLARATIONS
 */

/*
 * Error messages
 */
#define IPC_ROUTE_EXISTS            (IPC_ERROR_BASE|0x01)

/*
 * Define the stack size for the IPC
 */
#define IPC_DEFAULT_STACK_SIZE \
   ((384*sizeof(_mem_size))+PSP_STACK_KLOG_OVERHEAD)

/* The size of the data portion of the IPC message in uint_32s */
#define IPC_DATA_SIZE              (19)

/* Maximum packet size sent between IPC tasks */
#define IPC_MAX_PACKET_SIZE \
   ((IPC_DATA_SIZE * sizeof(_mqx_uint)) + /* Data bytes */ \
   (4 * sizeof(_mqx_uint)))  /* Maximum size of message header */

/*
 * Types of Inter-processor low level protocols
 */
#define IPC_LOOPBACK_PROTOCOL       (1)
#define IPC_ASYNC_SERIAL_PROTOCOL   (2)
#define IPC_SYNC_SERIAL_PROTOCOL    (3)
#define IPC_SHARED_MEM_PROTOCOL     (4)
#define IPC_TI_COMPORT_PROTOCOL     (5)
#define IPC_SHARC_LINKPORT_PROTOCOL (6)
#define IPC_LAPB_PROTOCOL           (7)
#define IPC_RTCS_PROTOCOL           (8)
#define IPC_PCB_PROTOCOL            (9)

/*--------------------------------------------------------------------------*/
/*
 *                    TYPEDEFS FOR _CODE_PTR_ FUNCTIONS
 */ 
struct ipc_protocol_init_struct;
typedef _mqx_uint (_CODE_PTR_ IPC_INIT_FPTR)( 
        const struct ipc_protocol_init_struct _PTR_ ipc_init_ptr, pointer ipc_info_ptr);
typedef _mqx_uint (_CODE_PTR_ IPC_HANDLER_FPTR)( pointer);

 
/*--------------------------------------------------------------------------*/
/*
 *                          DATATYPE DECLARATIONS
 */


/* IPC PROTOCOL INIT STRUCT */
/*!
 * \brief The inter-processor initialization information.
 * 
 * The _ipc_init_table[] (an array of entries of type IPC_PROTOCOL_INIT_STRUCT) 
 * defines the communication paths between processors (IPCs). The table is 
 * terminated by a zero-filled entry.
 *  
 * \see IPC_ROUTING_STRUCT
 * \see IPC_INIT_STRUCT
 */
typedef struct ipc_protocol_init_struct
{

   /*! \brief Function that initializes the IPC. The function depends on the IPC. */
   IPC_INIT_FPTR IPC_PROTOCOL_INIT;

   /*!
    * \brief Pointer to the initialization data that is specific to the IPC
    * protocol. The format of the data depends on the IPC. 
    */
   pointer               IPC_PROTOCOL_INIT_DATA;

   /*! \brief A String name that identifies the IPC. */
   char _PTR_            IPC_NAME;

   /*!
    * \brief Queue number of the output queue to which MQX routes messages that 
    * are to be sent to the remote processor. The queue number must match a queue 
    * number that is in the IPC routing table.
    */
   _queue_number         IPC_OUT_QUEUE;

} IPC_PROTOCOL_INIT_STRUCT, _PTR_ IPC_PROTOCOL_INIT_STRUCT_PTR;


/* IPC_ROUTING_STRUCT */
/*!
 * \brief Entry in the IPC routing table for interprocessor communication.
 *  
 * When a request to a processor that is OFF board, the remote processor number 
 * is checked versus the minimum and maximum processor number in the 
 * _IP_routing_table, which is composed of these structures. If a match is found, 
 * then the message is placed onto the specified QUEUE number. 
 * \n The table is terminated with a zero-filled entry.
 */

typedef struct ipc_routing_struct
{
   /*! \brief The minimum processor number in the range that can be accessed from 
    * the communication path. 
    * 
    * In most cases, the minumim and maximum values are equal, indicating that 
    * the end of the communication is occupied by one processor. In some cases, 
    * the processor at the end of the path is connected to other processors, in 
    * which case the processor might also act as a gateway.
    */
   _processor_number MIN_PROC_NUMBER;

   /*! \brief The maximum processor number in the range that can be accessed from 
    * the communication path. 
    * 
    * In most cases, the minumim and maximum values are equal, indicating that 
    * the end of the communication is occupied by one processor. In some cases, 
    * the processor at the end of the path is connected to other processors, in 
    * which case the processor might also act as a gateway.
    */
   _processor_number MAX_PROC_NUMBER;

   /*! \brief Queue number of the IPC output queue. */
   _queue_number     QUEUE;

} IPC_ROUTING_STRUCT, _PTR_ IPC_ROUTING_STRUCT_PTR;


/* IPC PROTOCOL INFO STRUCT */
/*!
 * \brief This structure contains standard Inter-Processor protocol information,
 * kept with the inter-processor driver.
 */
typedef struct ipc_protocol_info_struct
{
   /*! \brief Type of the inter-processor communications protocol. */
   _mqx_uint           IPC_TYPE;

   /*!
    * \brief This is the output queue number to which MQX will send messages that 
    * are to be sent to the remote processor.
    */
   _queue_number       IPC_OUT_QUEUE;

   /*! \brief A string name used to identify this IPC, from the init record. */
   char _PTR_          IPC_NAME;

   /*! \brief The queue ID of the output queue. */
   _queue_id           IPC_OUT_QID;

   /*! \brief The address of protocol specific information. */
   pointer             IPC_PROTOCOL_INFO_PTR;
   
   /*! \brief The address of the initialization record used to initialize this IPC. */
   const IPC_PROTOCOL_INIT_STRUCT * IPC_INIT_PTR;

} IPC_PROTOCOL_INFO_STRUCT, _PTR_ IPC_PROTOCOL_INFO_STRUCT_PTR;

/*!
 * \brief IPC initialization structure that is passed to the _ipc_task function 
 * as a creation parameter.
 * 
 * This structure allows both user defined IPC routing table and IPC 
 * initialization table to be passed to the _ipc_task.
 * 
 * \see IPC_PROTOCOL_INIT_STRUCT
 * \see IPC_ROUTING_STRUCT 
 */ 
typedef struct ipc_init_struct {
    /*! \brief Pointer to the IPC routing table. */
    const IPC_ROUTING_STRUCT *        ROUTING_LIST_PTR;
    /*! \brief Pointer to the IPC initialization table. */
    const IPC_PROTOCOL_INIT_STRUCT *  PROTOCOL_LIST_PTR;
} IPC_INIT_STRUCT, * IPC_INIT_STRUCT_PTR
;
/*--------------------------------------------------------------------------*/
/*
 *                          C PROTOTYPES
 */

#ifdef __cplusplus
extern "C" {
#endif

extern const IPC_PROTOCOL_INIT_STRUCT _ipc_init_table[];
extern const IPC_ROUTING_STRUCT       _ipc_routing_table[];

/* Component IPC handlers */
#ifndef __TAD_COMPILE__
extern void _event_install_ipc_handler(void);

extern _mqx_uint _ipc_add_io_ipc_handler(IPC_HANDLER_FPTR handler, _mqx_uint);
extern _mqx_uint _ipc_add_ipc_handler(IPC_HANDLER_FPTR handler, _mqx_uint);
extern _mqx_uint _ipc_msg_route_add(_processor_number, _processor_number,
   _queue_number);
extern pointer   _ipc_msg_processor_route_exists(_processor_number);
extern _mqx_uint _ipc_msg_route_remove(_processor_number, _processor_number,
   _queue_number);
extern void      _ipc_task(uint_32);
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/bsp/INV1_K60F120/bsp_cm.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2011 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: bsp_cm.h$
* $Version : 3.8.1.0$
* $Date    : Jun-6-2012$
*
* Comments:
*   Clock manager Kinetis specific definitions and prototypes.
*
*       _bsp_initialize_hardware();
*       _bsp_set_clock_configuration();
*       _bsp_get_clock_configuration();
*       _bsp_get_clock();
*       _bsp_osc_autotrim();
*
*END************************************************************************/

#ifndef __bsp_cm_h__
  #define __bsp_cm_h__


  #ifndef PE_LDD_VERSION

/* Active configuration define symbol */
    #define PEcfg_INTERNAL_FLASH 1U

/* Methods configuration constants - generated for all enabled component's methods */
    #define Cpu_SetClockConfiguration_METHOD_ENABLED
    #define Cpu_GetClockConfiguration_METHOD_ENABLED
    #define Cpu_SetOperationMode_METHOD_ENABLED
    #define Cpu_EnableInt_METHOD_ENABLED
    #define Cpu_DisableInt_METHOD_ENABLED
    #define Cpu_GetLLSWakeUpFlags_METHOD_ENABLED
    #define Cpu_MCGAutoTrim_METHOD_ENABLED

/* Events configuration constants - generated for all enabled component's events */
    #define Cpu_OnLLSWakeUpINT_EVENT_ENABLED

    #define CPU_BUS_CLK_HZ                  60000000U /* Initial value of the bus clock frequency in Hz */
    #define CPU_CORE_CLK_HZ                 120000000U /* Initial value of the core/system clock frequency in Hz.  */

    #define CPU_CLOCK_CONFIG_NUMBER         0x03U /* Specifies number of defined sclock configurations. */

    #define CPU_BUS_CLK_HZ_CLOCK_CONFIG0    60000000U /* Value of the bus clock frequency in the clock configuration 0 in Hz. */
    #define CPU_CORE_CLK_HZ_CLOCK_CONFIG0   120000000U /* Value of the core/system clock frequency in the clock configuration 0 in Hz. */

    #define CPU_BUS_CLK_HZ_CLOCK_CONFIG1    12000000U /* Value of the bus clock frequency in the clock configuration 1 in Hz. */
    #define CPU_CORE_CLK_HZ_CLOCK_CONFIG1   12000000U /* Value of the core/system clock frequency in the clock configuration 1 in Hz. */

    #define CPU_BUS_CLK_HZ_CLOCK_CONFIG2    2000000U /* Value of the bus clock frequency in the clock configuration 2 in Hz. */
    #define CPU_CORE_CLK_HZ_CLOCK_CONFIG2   2000000U /* Value of the core/system clock frequency in the clock configuration 2 in Hz. */


    #define CPU_XTAL_CLK_HZ                 50000000U /* Value of the external crystal or oscillator clock frequency in Hz */
    #define CPU_XTAL32k_CLK_HZ              32768U /* Value of the external 32k crystal or oscillator clock frequency in Hz */
    #define CPU_INT_SLOW_CLK_HZ             32768U /* Value of the slow internal oscillator clock frequency in Hz  */
    #define CPU_INT_FAST_CLK_HZ             4000000U /* Value of the fast internal oscillator clock frequency in Hz  */

    #define CPU_FAMILY_Kinetis             /* Specification of the core type of the selected cpu */
    #define CPU_DERIVATIVE_MK60FN1M0LQ15   /* Name of the selected cpu derivative */
    #define CPU_PARTNUM_MK60FN1M0VLQ12     /* Part number of the selected cpu */
    #define CPU_LITTLE_ENDIAN              /* The selected cpu uses little endian */

/* CPU frequencies in clock configuration 0 */
    #define CPU_CLOCK_CONFIG_0              0x00U /* Clock configuration 0 identifier */
    #define CPU_CORE_CLK_HZ_CONFIG_0        120000000UL /* Core clock frequency in clock configuration 0 */
    #define CPU_BUS_CLK_HZ_CONFIG_0         60000000UL /* Bus clock frequency in clock configuration 0 */
    #define CPU_FLEXBUS_CLK_HZ_CONFIG_0     40000000UL /* Flexbus clock frequency in clock configuration 0 */
    #define CPU_FLASH_CLK_HZ_CONFIG_0       20000000UL /* FLASH clock frequency in clock configuration 0 */
    #define CPU_USB_CLK_HZ_CONFIG_0         0UL /* USB clock frequency in clock configuration 0 */
    #define CPU_PLL_FLL_CLK_HZ_CONFIG_0     120000000UL /* PLL/FLL clock frequency in clock configuration 0 */
    #define CPU_MCGIR_CLK_HZ_CONFIG_0       0UL /* MCG internal reference clock frequency in clock configuration 0 */
    #define CPU_OSCER_CLK_HZ_CONFIG_0       50000000UL /* System OSC external reference clock frequency in clock configuration 0 */
    #define CPU_ERCLK32K_CLK_HZ_CONFIG_0    32768UL /* External reference clock 32k frequency in clock configuration 0 */
    #define CPU_MCGFF_CLK_HZ_CONFIG_0       24414UL /* MCG fixed frequency clock */

/* CPU frequencies in clock configuration 1 */
    #define CPU_CLOCK_CONFIG_1              0x01U /* Clock configuration 1 identifier */
    #define CPU_CORE_CLK_HZ_CONFIG_1        12000000UL /* Core clock frequency in clock configuration 1 */
    #define CPU_BUS_CLK_HZ_CONFIG_1         12000000UL /* Bus clock frequency in clock configuration 1 */
    #define CPU_FLEXBUS_CLK_HZ_CONFIG_1     12000000UL /* Flexbus clock frequency in clock configuration 1 */
    #define CPU_FLASH_CLK_HZ_CONFIG_1       12000000UL /* FLASH clock frequency in clock configuration 1 */
    #define CPU_USB_CLK_HZ_CONFIG_1         0UL /* USB clock frequency in clock configuration 1 */
    #define CPU_PLL_FLL_CLK_HZ_CONFIG_1     120000000UL /* PLL/FLL clock frequency in clock configuration 1 */
    #define CPU_MCGIR_CLK_HZ_CONFIG_1       0UL /* MCG internal reference clock frequency in clock configuration 1 */
    #define CPU_OSCER_CLK_HZ_CONFIG_1       50000000UL /* System OSC external reference clock frequency in clock configuration 1 */
    #define CPU_ERCLK32K_CLK_HZ_CONFIG_1    32768UL /* External reference clock 32k frequency in clock configuration 1 */
    #define CPU_MCGFF_CLK_HZ_CONFIG_1       24414UL /* MCG fixed frequency clock */

/* CPU frequencies in clock configuration 2 */
    #define CPU_CLOCK_CONFIG_2              0x02U /* Clock configuration 2 identifier */
    #define CPU_CORE_CLK_HZ_CONFIG_2        2000000UL /* Core clock frequency in clock configuration 2 */
    #define CPU_BUS_CLK_HZ_CONFIG_2         2000000UL /* Bus clock frequency in clock configuration 2 */
    #define CPU_FLEXBUS_CLK_HZ_CONFIG_2     2000000UL /* Flexbus clock frequency in clock configuration 2 */
    #define CPU_FLASH_CLK_HZ_CONFIG_2       500000UL /* FLASH clock frequency in clock configuration 2 */
    #define CPU_USB_CLK_HZ_CONFIG_2         0UL /* USB clock frequency in clock configuration 2 */
    #define CPU_PLL_FLL_CLK_HZ_CONFIG_2     2000000UL /* PLL/FLL clock frequency in clock configuration 2 */
    #define CPU_MCGIR_CLK_HZ_CONFIG_2       2000000UL /* MCG internal reference clock frequency in clock configuration 2 */
    #define CPU_OSCER_CLK_HZ_CONFIG_2       50000000UL /* System OSC external reference clock frequency in clock configuration 2 */
    #define CPU_ERCLK32K_CLK_HZ_CONFIG_2    0UL /* External reference clock 32k frequency in clock configuration 2 */
    #define CPU_MCGFF_CLK_HZ_CONFIG_2       16384UL /* MCG fixed frequency clock */

  #endif /* PE_LDD_VERSION */


typedef enum {
  BSP_CLOCK_CONFIGURATION_0 = 0,      /* 120 MHZ PEE   */
  BSP_CLOCK_CONFIGURATION_1,          /* 12  MHZ PEE   */
  BSP_CLOCK_CONFIGURATION_2,          /* 2   MHZ BLPI  */
  BSP_CLOCK_CONFIGURATIONS,           /* Number of available clock configurations */
  BSP_CLOCK_CONFIGURATION_DEFAULT     = BSP_CLOCK_CONFIGURATION_0,
  BSP_CLOCK_CONFIGURATION_120MHZ      = BSP_CLOCK_CONFIGURATION_0,
  BSP_CLOCK_CONFIGURATION_12MHZ       = BSP_CLOCK_CONFIGURATION_1,
  BSP_CLOCK_CONFIGURATION_2MHZ        = BSP_CLOCK_CONFIGURATION_2,
  BSP_CLOCK_CONFIGURATION_AUTOTRIM    = BSP_CLOCK_CONFIGURATION_1
} BSP_CLOCK_CONFIGURATION;

  #define Cpu_SetOperationMode_METHOD_ENABLED


  #ifdef __cplusplus
extern "C"
{
  #endif


void _bsp_initialize_hardware(void);

BSP_CLOCK_CONFIGURATION _bsp_get_clock_configuration(void);

/* [IN] runtime clock configuration */
uint16_t _bsp_set_clock_configuration(const BSP_CLOCK_CONFIGURATION clock_configuration);

/* [IN] clock configuration */
/* [IN] clock source index */
uint32_t _bsp_get_clock(const BSP_CLOCK_CONFIGURATION clock_configuration,const CM_CLOCK_SOURCE clock_source);
uint16_t _bsp_osc_autotrim(void);
void _bsp_low_level_init(void);


  #ifdef __cplusplus
}
  #endif


#endif /* __bsp_cm_h__ */



<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/kadc/adc_mk40.h<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_mk40.h$
* $Version : 3.8.3.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   CPU specific ADC driver header file
*
*END************************************************************************/

#ifndef __adc_mk40_h__
#define __adc_mk40_h__


#define ADC_HAS_16BIT_RESOLUTION           1
#define ADC_HAS_DIFFERENTIAL_CHANNELS      1
#define ADC_HAS_PGA                        1


#define ADC0_SOURCE_ADPM0       (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0) | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_ADPM1       (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1) | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_ADPM2       (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2) | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_ADPM3       (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3) | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_AD0         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0))
#define ADC0_SOURCE_AD1         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1))
#define ADC0_SOURCE_AD2         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2))
#define ADC0_SOURCE_AD3         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3))
#define ADC0_SOURCE_AD4A        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD5A        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD6A        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD7A        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD4B        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(4))
#define ADC0_SOURCE_AD5B        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(5))
#define ADC0_SOURCE_AD6B        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(6))
#define ADC0_SOURCE_AD7B        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(7))
#define ADC0_SOURCE_AD8         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(8))
#define ADC0_SOURCE_AD9         (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(9))
#define ADC0_SOURCE_AD10        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(10))
#define ADC0_SOURCE_AD11        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(11))
#define ADC0_SOURCE_AD12        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(12))
#define ADC0_SOURCE_AD13        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(13))
#define ADC0_SOURCE_AD14        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(14))
#define ADC0_SOURCE_AD15        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(15))
#define ADC0_SOURCE_AD16        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(16))
#define ADC0_SOURCE_AD17        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(17))
#define ADC0_SOURCE_AD18        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(18))
#define ADC0_SOURCE_AD19        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(19))
#define ADC0_SOURCE_AD20        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(20))
#define ADC0_SOURCE_AD21        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(21))
#define ADC0_SOURCE_AD22        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(22))
#define ADC0_SOURCE_AD23        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(23))
#define ADC0_SOURCE_AD24        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(24))
#define ADC0_SOURCE_AD25        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(25))
#define ADC0_SOURCE_AD26        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC0_SOURCE_AD27        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(27))
#define ADC0_SOURCE_AD28        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(28))
#define ADC0_SOURCE_AD29        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(29))
#define ADC0_SOURCE_AD30        (ADC_SOURCE_MODULE(1) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(30))



#define ADC0_SOURCE_DAC0            (ADC0_SOURCE_AD23)
#define ADC0_SOURCE_TEMP            (ADC0_SOURCE_AD26)
#define ADC0_SOURCE_TEMP_DIFF       (ADC0_SOURCE_AD26 | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_BANDGAP         (ADC0_SOURCE_AD27)
#define ADC0_SOURCE_BANDGAP_DIFF    (ADC0_SOURCE_AD27 | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_VREFH           (ADC0_SOURCE_AD29)
#define ADC0_SOURCE_VREFH_DIFF      (ADC0_SOURCE_AD29 | ADC_SOURCE_DIFF)
#define ADC0_SOURCE_VREFL           (ADC0_SOURCE_AD30)

#define ADC1_SOURCE_ADPM0       (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0) | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_ADPM1       (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1) | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_ADPM2       (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2) | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_ADPM3       (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3) | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_AD0         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(0))
#define ADC1_SOURCE_AD1         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(1))
#define ADC1_SOURCE_AD2         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(2))
#define ADC1_SOURCE_AD3         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(3))
#define ADC1_SOURCE_AD4A        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(4))
#define ADC1_SOURCE_AD5A        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(5))
#define ADC1_SOURCE_AD6A        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(6))
#define ADC1_SOURCE_AD7A        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_A | ADC_SOURCE_CHANNEL(7))
#define ADC1_SOURCE_AD4B        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(4))
#define ADC1_SOURCE_AD5B        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(5))
#define ADC1_SOURCE_AD6B        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(6))
#define ADC1_SOURCE_AD7B        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_B | ADC_SOURCE_CHANNEL(7))
#define ADC1_SOURCE_AD8         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(8))
#define ADC1_SOURCE_AD9         (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(9))
#define ADC1_SOURCE_AD10        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(10))
#define ADC1_SOURCE_AD11        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(11))
#define ADC1_SOURCE_AD12        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(12))
#define ADC1_SOURCE_AD13        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(13))
#define ADC1_SOURCE_AD14        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(14))
#define ADC1_SOURCE_AD15        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(15))
#define ADC1_SOURCE_AD16        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(16))
#define ADC1_SOURCE_AD17        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(17))
#define ADC1_SOURCE_AD18        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(18))
#define ADC1_SOURCE_AD19        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(19))
#define ADC1_SOURCE_AD20        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(20))
#define ADC1_SOURCE_AD21        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(21))
#define ADC1_SOURCE_AD22        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(22))
#define ADC1_SOURCE_AD23        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(23))
#define ADC1_SOURCE_AD24        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(24))
#define ADC1_SOURCE_AD25        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(25))
#define ADC1_SOURCE_AD26        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC1_SOURCE_AD27        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(27))
#define ADC1_SOURCE_AD28        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(26))
#define ADC1_SOURCE_AD29        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(29))
#define ADC1_SOURCE_AD30        (ADC_SOURCE_MODULE(2) | ADC_SOURCE_MUXSEL_X | ADC_SOURCE_CHANNEL(30))

#define ADC1_SOURCE_VREF            (ADC1_SOURCE_AD18)

#define ADC1_SOURCE_DAC1            (ADC1_SOURCE_AD23)
#define ADC1_SOURCE_TEMP            (ADC1_SOURCE_AD26)
#define ADC1_SOURCE_TEMP_DIFF       (ADC1_SOURCE_AD26 | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_BANDGAP         (ADC1_SOURCE_AD27)
#define ADC1_SOURCE_BANDGAP_DIFF    (ADC1_SOURCE_AD27 | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_VREFH           (ADC1_SOURCE_AD29)
#define ADC1_SOURCE_VREFH_DIFF      (ADC1_SOURCE_AD29 | ADC_SOURCE_DIFF)
#define ADC1_SOURCE_VREFL           (ADC1_SOURCE_AD30)


#endif /* __adc_mk40_h__ */


<|start_filename|>Firmware/Inverter_firmware/mfs/source/include/mfs.h<|end_filename|>
#ifndef __mfs_h__
#define __mfs_h__
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mfs.h$
* $Version : 3.8.24.0$
* $Date    : Jul-25-2012$
*
* Comments:
*
*   This file contains the structure definitions and constants for a
*   user who will be compiling programs that will use the Embedded MS-DOS
*   File System (MFS)
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include "mfs_rev.h"
#include "mfs_cnfg.h"
#include "ioctl.h"

/*
** Defines specific to MFS
*/

#define MFS_VERSION             (0x00030000 | MFS_REVISION)

/* search attributes  */
#define  MFS_SEARCH_NORMAL      0x00
#define  MFS_SEARCH_READ_ONLY   0x01
#define  MFS_SEARCH_HIDDEN      0x02
#define  MFS_SEARCH_SYSTEM      0x04
#define  MFS_SEARCH_VOLUME      0x08
#define  MFS_SEARCH_SUBDIR      0x10
#define  MFS_SEARCH_ARCHIVE     0x20
#define  MFS_SEARCH_EXCLUSIVE   0x40
#define  MFS_SEARCH_ANY         0x80

/* file open access modes */
#define  MFS_ACCESS_READ_ONLY   0x00
#define  MFS_ACCESS_WRITE_ONLY  0x01
#define  MFS_ACCESS_READ_WRITE  0x02

/* file entry attributes */
#define  MFS_ATTR_READ_ONLY     0x01
#define  MFS_ATTR_HIDDEN_FILE   0x02
#define  MFS_ATTR_SYSTEM_FILE   0x04
#define  MFS_ATTR_VOLUME_NAME   0x08
#define  MFS_ATTR_DIR_NAME      0x10
#define  MFS_ATTR_ARCHIVE       0x20
#define  MFS_ATTR_LFN           0x0F

/* mask values for the date and time as recorded in the
** file entries
*/
#define  MFS_MASK_DAY           0x001F
#define  MFS_MASK_MONTH         0x01E0
#define  MFS_MASK_YEAR          0xFE00
#define  MFS_MASK_SECONDS       0x001F
#define  MFS_MASK_MINUTES       0x07E0
#define  MFS_MASK_HOURS         0xF800

/*
** shift for the above date and time masks
*/
#define  MFS_SHIFT_DAY          0
#define  MFS_SHIFT_MONTH        5
#define  MFS_SHIFT_YEAR         9
#define  MFS_SHIFT_SECONDS      0
#define  MFS_SHIFT_MINUTES      5
#define  MFS_SHIFT_HOURS        11

/*
** control for the write cache
*/
#define  MFS_WRCACHE_OFF        0
#define  MFS_WRCACHE_ON         1
#define  MFS_WRCACHE_FLUSH      2

#define  MFS_DEFAULT_SECTOR_SIZE       512

/*
** Sector boundries that determine the cluster size, the root dir size
** and the FAT type
*/
#define SECTOR_BOUND1   2048     /* TYPE: FAT12, Root dir:  7 * 32 root entries, CLUSTER SIZE:  1 sector */
#define SECTOR_BOUND2   4096     /* TYPE: FAT12, Root dir: 14 * 32 root entries, CLUSTER SIZE:  1 sector */
#define SECTOR_BOUND3   8192     /* TYPE: FAT12, Root dir: 32 * 32 root entries, CLUSTER SIZE:  2 sectors */
#define SECTOR_BOUND4   16384    /* TYPE: FAT12, Root dir: 32 * 32 root entries, CLUSTER SIZE:  4 sectors */
#define SECTOR_BOUND5   32768    /* TYPE: FAT12, Root dir: 32 * 32 root entries, CLUSTER SIZE:  2 sectors */
#define SECTOR_BOUND6   524288   /* TYPE: FAT16, Root dir: 32 * 32 root entries, CLUSTER SIZE:  8 sectors */
#define SECTOR_BOUND7   1048576  /* TYPE: FAT16, Root dir: 32 * 32 root entries, CLUSTER SIZE: 16 sectors */
#define SECTOR_BOUND8   16777216 /* TYPE: FAT32, Root dir: 64k entries,          CLUSTER SIZE:  8 sectors */
#define SECTOR_BOUND9   33554432 /* TYPE: FAT32, Root dir: 64k entries,          CLUSTER SIZE: 16 sectors */
#define SECTOR_BOUND10  67108864 /* TYPE: FAT32, Root dir: 64k entries,          CLUSTER SIZE: 32 sectors */
#define SECTOR_BOUND11  2097152  /* TYPE: FAT16, Root dir: 32 * 32 root entries, CLUSTER SIZE: 32 sectors */

#define MFS_FAT12             0x01
#define MFS_FAT16             0x06
#define MFS_FAT32             0x0C

/*
** FILENAME LENGTH CONSTANTS
*/
#define PATHNAME_SIZE         260
#define FILENAME_SIZE         255
#define SFILENAME_SIZE        12

/*
** error codes
*/
#define MFS_NO_ERROR                          FS_NO_ERROR
#define MFS_INVALID_FUNCTION_CODE             FS_INVALID_FUNCTION_CODE
#define MFS_FILE_NOT_FOUND                    FS_FILE_NOT_FOUND
#define MFS_PATH_NOT_FOUND                    FS_PATH_NOT_FOUND
#define MFS_ACCESS_DENIED                     FS_ACCESS_DENIED
#define MFS_INVALID_HANDLE                    FS_INVALID_HANDLE
#define MFS_INSUFFICIENT_MEMORY               FS_INSUFFICIENT_MEMORY
#define MFS_INVALID_MEMORY_BLOCK_ADDRESS      FS_INVALID_MEMORY_BLOCK_ADDRESS
#define MFS_ATTEMPT_TO_REMOVE_CURRENT_DIR     FS_ATTEMPT_TO_REMOVE_CURRENT_DIR
#define MFS_DISK_IS_WRITE_PROTECTED           FS_DISK_IS_WRITE_PROTECTED
#define MFS_BAD_DISK_UNIT                     FS_BAD_DISK_UNIT
#define MFS_INVALID_LENGTH_IN_DISK_OPERATION  FS_INVALID_LENGTH_IN_DISK_OPERATION
#define MFS_NOT_A_DOS_DISK                    FS_NOT_A_DOS_DISK
#define MFS_SECTOR_NOT_FOUND                  FS_SECTOR_NOT_FOUND
#define MFS_WRITE_FAULT                       FS_WRITE_FAULT
#define MFS_READ_FAULT                        FS_READ_FAULT
#define MFS_SHARING_VIOLATION                 FS_SHARING_VIOLATION
#define MFS_FILE_EXISTS                       FS_FILE_EXISTS
#define MFS_ALREADY_ASSIGNED                  FS_ALREADY_ASSIGNED
#define MFS_INVALID_PARAMETER                 FS_INVALID_PARAMETER
#define MFS_DISK_FULL                         FS_DISK_FULL
#define MFS_ROOT_DIR_FULL                     FS_ROOT_DIR_FULL
#define MFS_EOF                               FS_EOF
#define MFS_CANNOT_CREATE_DIRECTORY           FS_CANNOT_CREATE_DIRECTORY
#define MFS_NOT_INITIALIZED                   FS_NOT_INITIALIZED
#define MFS_OPERATION_NOT_ALLOWED             FS_OPERATION_NOT_ALLOWED
#define MFS_ERROR_INVALID_DRIVE_HANDLE        FS_ERROR_INVALID_DRIVE_HANDLE
#define MFS_ERROR_INVALID_FILE_HANDLE         FS_ERROR_INVALID_FILE_HANDLE
#define MFS_ERROR_UNKNOWN_FS_VERSION          FS_ERROR_UNKNOWN_FS_VERSION
#define MFS_LOST_CHAIN                        FS_LOST_CHAIN
#define MFS_INVALID_DEVICE                    FS_INVALID_DEVICE
#define MFS_INVALID_CLUSTER_NUMBER            FS_INVALID_CLUSTER_NUMBER
#define MFS_FAILED_TO_DELETE_LFN              FS_FAILED_TO_DELETE_LFN
#define MFS_BAD_LFN_ENTRY                     FS_BAD_LFN_ENTRY
#define PMGR_INVALID_PARTITION                FS_PMGR_INVALID_PARTITION
#define PMGR_INSUF_MEMORY                     FS_PMGR_INSUF_MEMORY
#define PMGR_UNKNOWN_PARTITION                FS_PMGR_UNKNOWN_PARTITION
#define PMGR_INVALID_PARTTABLE                FS_PMGR_INVALID_PARTTABLE

/*
** Extra IO_IOCTL codes
*/
#define IO_IOCTL_DELETE_FILE                  _IO(IO_TYPE_MFS,0x02)
#define IO_IOCTL_BAD_CLUSTERS                 _IO(IO_TYPE_MFS,0x03)
#define IO_IOCTL_FREE_SPACE                   _IO(IO_TYPE_MFS,0x04)
#define IO_IOCTL_TEST_UNUSED_CLUSTERS         _IO(IO_TYPE_MFS,0x05)
#define IO_IOCTL_CREATE_SUBDIR                _IO(IO_TYPE_MFS,0x06)
#define IO_IOCTL_REMOVE_SUBDIR                _IO(IO_TYPE_MFS,0x07)
#define IO_IOCTL_GET_CURRENT_DIR              _IO(IO_TYPE_MFS,0x08)
#define IO_IOCTL_CHANGE_CURRENT_DIR           _IO(IO_TYPE_MFS,0x09)
#define IO_IOCTL_WRITE_CACHE_ON               _IO(IO_TYPE_MFS,0x0A)
#define IO_IOCTL_WRITE_CACHE_OFF              _IO(IO_TYPE_MFS,0x0B)
#define IO_IOCTL_FORMAT                       _IO(IO_TYPE_MFS,0x0C)
#define IO_IOCTL_FORMAT_TEST                  _IO(IO_TYPE_MFS,0x0D)
#define IO_IOCTL_FIND_FIRST_FILE              _IO(IO_TYPE_MFS,0x0E)
#define IO_IOCTL_FIND_NEXT_FILE               _IO(IO_TYPE_MFS,0x0F)
#define IO_IOCTL_RENAME_FILE                  _IO(IO_TYPE_MFS,0x10)
#define IO_IOCTL_GET_FILE_ATTR                _IO(IO_TYPE_MFS,0x11)
#define IO_IOCTL_SET_FILE_ATTR                _IO(IO_TYPE_MFS,0x12)
#define IO_IOCTL_GET_DATE_TIME                _IO(IO_TYPE_MFS,0x13)
#define IO_IOCTL_SET_DATE_TIME                _IO(IO_TYPE_MFS,0x14)
#define IO_IOCTL_FLUSH_FAT                    _IO(IO_TYPE_MFS,0x15)
#define IO_IOCTL_FAT_CACHE_ON                 _IO(IO_TYPE_MFS,0x16)
#define IO_IOCTL_FAT_CACHE_OFF                _IO(IO_TYPE_MFS,0x17)
#define IO_IOCTL_SET_VOLUME                   _IO(IO_TYPE_MFS,0x18)
#define IO_IOCTL_GET_VOLUME                   _IO(IO_TYPE_MFS,0x19)
#define IO_IOCTL_GET_LFN                      _IO(IO_TYPE_MFS,0x1A)
#define IO_IOCTL_FREE_CLUSTERS                _IO(IO_TYPE_MFS,0x1B)
#define IO_IOCTL_GET_CLUSTER_SIZE             _IO(IO_TYPE_MFS,0x1C)
#define IO_IOCTL_LAST_CLUSTER                 _IO(IO_TYPE_MFS,0x20)
#define IO_IOCTL_SEL_PART                     _IO(IO_TYPE_MFS,0x21)
#define IO_IOCTL_USE_PARTITION                _IO(IO_TYPE_MFS,0x22)
#define IO_IOCTL_VAL_PART                     _IO(IO_TYPE_MFS,0x23)
#define IO_IOCTL_SET_PARTITION                _IO(IO_TYPE_MFS,0x24)
#define IO_IOCTL_GET_PARTITION                _IO(IO_TYPE_MFS,0x25)
#define IO_IOCTL_CLEAR_PARTITION              _IO(IO_TYPE_MFS,0x26)
#define IO_IOCTL_GET_DEVICE_HANDLE            _IO(IO_TYPE_MFS,0x27)
#define IO_IOCTL_GET_FAT_CACHE_MODE           _IO(IO_TYPE_MFS,0x28)
#define IO_IOCTL_SET_FAT_CACHE_MODE           _IO(IO_TYPE_MFS,0x29)
#define IO_IOCTL_GET_WRITE_CACHE_MODE         _IO(IO_TYPE_MFS,0x30)
#define IO_IOCTL_SET_WRITE_CACHE_MODE         _IO(IO_TYPE_MFS,0x31)
#define IO_IOCTL_DEFAULT_FORMAT               _IO(IO_TYPE_MFS,0x32)
#define IO_IOCTL_VERIFY_WRITES                _IO(IO_TYPE_MFS,0x33)
#define IO_IOCTL_CHECK_DIR_EXIST              _IO(IO_TYPE_MFS,0x34)

/*
Following IOCTL codes are obsolete.
No device locking is necessary anymore as partition manager may be open multiple times to allow for concurrent access to multiple partitions.
#define IO_IOCTL_DEV_LOCK
#define IO_IOCTL_DEV_UNLOCK
*/


#define MFS_MEM_TYPE_BASE                     ( (IO_MFS_COMPONENT) << (MEM_TYPE_COMPONENT_SHIFT))
#define MEM_TYPE_MFS_DRIVE_STRUCT             (MFS_MEM_TYPE_BASE+1)
#define MEM_TYPE_MFS_DIR_STRUCT               (MFS_MEM_TYPE_BASE+2)
#define MEM_TYPE_MFS_DATA_SECTOR              (MFS_MEM_TYPE_BASE+3)
#define MEM_TYPE_MFS_DIRECTORY_SECTOR         (MFS_MEM_TYPE_BASE+4)
#define MEM_TYPE_MFS_FAT_BUFFER               (MFS_MEM_TYPE_BASE+5)
#define MEM_TYPE_MFS_FILESYSTEM_INFO_DISK     (MFS_MEM_TYPE_BASE+6)
#define MEM_TYPE_MFS_CLUSTER                  (MFS_MEM_TYPE_BASE+7)
#define MEM_TYPE_MFS_PATHNAME                 (MFS_MEM_TYPE_BASE+8)
#define MEM_TYPE_PART_MGR_STRUCT              (MFS_MEM_TYPE_BASE+9)
#define MEM_TYPE_PART_MGR_SECTOR              (MFS_MEM_TYPE_BASE+10)
/*
** INDEX_TO_OFFSET converts a directory index to the offset within the right
** sector.
*/
#define INDEX_TO_OFFSET(x) ((x) & (drive_ptr->ENTRIES_PER_SECTOR-1))

#define PACK_TIME(x)  ((x.HOUR << MFS_SHIFT_HOURS) |\
                       (x.MINUTE << MFS_SHIFT_MINUTES) |\
                       (clk_time.SECOND >>1))

#define PACK_DATE(x) (((x.YEAR -1980)<< MFS_SHIFT_YEAR) |\
                      (x.MONTH << MFS_SHIFT_MONTH) |\
                      (x.DAY << MFS_SHIFT_DAY))

#define CAPITALIZE(c)  (c&((c>='a'&&c<='z')?(~0x20):~0))

/*
** Data Structures specific to MFS
*/
typedef uint_32 _mfs_error;
typedef uint_32_ptr _mfs_error_ptr;

typedef enum {
   MFS_WRITE_THROUGH_CACHE=0,    // No write caching (only read caching)
   MFS_MIXED_MODE_CACHE=1,       // Write Caching allowed on file write only
   MFS_WRITE_BACK_CACHE=2        // Write Caching fully enabled
} _mfs_cache_policy;

/*
** Information required for high-level format
*/
typedef struct mfs_format_data
{
   uchar    PHYSICAL_DRIVE;
   uchar    MEDIA_DESCRIPTOR;
   uint_16  BYTES_PER_SECTOR;
   uint_16  SECTORS_PER_TRACK;
   uint_16  NUMBER_OF_HEADS;
   uint_32  NUMBER_OF_SECTORS;
   uint_32  HIDDEN_SECTORS;
   uint_16  RESERVED_SECTORS;
} MFS_FORMAT_DATA, _PTR_ MFS_FORMAT_DATA_PTR;

/*
** Format information for ioctl calls involving format operations
*/
typedef struct mfs_ioctl_format
{
   MFS_FORMAT_DATA_PTR     FORMAT_PTR;
   uint_32_ptr             COUNT_PTR;      /* To count the bad clusters */
} MFS_IOCTL_FORMAT_PARAM, _PTR_ MFS_IOCTL_FORMAT_PARAM_PTR;


typedef struct mfs_internal_search
{
   char_ptr  FULLNAME;        // 0..3
   char_ptr  SRC_PTR;         // 4..7
   char      FILENAME[8];     // 8..15
   char      EXTENSION[3];    // 16..18
   char      ATTRIBUTE;       // 19
   uint_32   CURRENT_CLUSTER; // 20..23
   uint_32   DIR_ENTRY_INDEX; // 24..27
   uint_32   PREV_CLUSTER;    // 28..31
} MFS_INTERNAL_SEARCH, _PTR_ MFS_INTERNAL_SEARCH_PTR;

/*
** search data block, used for Find_first and Find_next
*/
typedef struct mfs_search_data
{
   pointer                 DRIVE_PTR;
   MFS_INTERNAL_SEARCH     INTERNAL_SEARCH_DATA;
   uchar                   ATTRIBUTE;
   char                    _UNUSED[3];
   uint_16                 TIME;
   uint_16                 DATE;
   uint_16                 RESERVED2;
   uint_32                 FILE_SIZE;
   char                    NAME[13];
} MFS_SEARCH_DATA, _PTR_ MFS_SEARCH_DATA_PTR;


/*
** Search information for ioctl find file first search calls
*/
typedef struct mfs_search_param
{
   uchar                   ATTRIBUTE;
   uchar                   RESERVED[3];
   char_ptr                WILDCARD;
   MFS_SEARCH_DATA_PTR     SEARCH_DATA_PTR;
} MFS_SEARCH_PARAM, _PTR_ MFS_SEARCH_PARAM_PTR;

/*
** Pathname information for the rename_file ioctl call
*/
typedef struct mfs_rename_param
{
   char_ptr                OLD_PATHNAME;
   char_ptr                NEW_PATHNAME;
} MFS_RENAME_PARAM, _PTR_ MFS_RENAME_PARAM_PTR;


/*
** Paramater information for get and set file attribute ioctl calls
*/
typedef struct mfs_file_attr_param
{
   char_ptr                PATHNAME;
   uchar_ptr               ATTRIBUTE_PTR;
} MFS_FILE_ATTR_PARAM, _PTR_ MFS_FILE_ATTR_PARAM_PTR;

typedef struct mfs_get_lfn_struct
{
   char_ptr                PATHNAME;
   char_ptr                LONG_FILENAME;
   MFS_SEARCH_DATA_PTR     SEARCH_DATA_PTR;
} MFS_GET_LFN_STRUCT, _PTR_ MFS_GET_LFN_STRUCT_PTR;


/*
** Parameter information for get/set date time ioctl calls
*/
typedef struct mfs_date_time_param
{
   uint_16_ptr             DATE_PTR;
   uint_16_ptr             TIME_PTR;
} MFS_DATE_TIME_PARAM, _PTR_ MFS_DATE_TIME_PARAM_PTR;

/*
** Data Structures specific to MFS
*/
/* structure of entries in the file system directory */
typedef struct mfs_dir_entry
{
   char     NAME[8];
   char     TYPE[3];
   uchar    ATTRIBUTE[1];
   char     RESERVED[8];
   uchar    HFIRST_CLUSTER[2];
   uchar    TIME[2];
   uchar    DATE[2];
   uchar    LFIRST_CLUSTER[2];
   uchar    FILE_SIZE[4];
} MFS_DIR_ENTRY, _PTR_ MFS_DIR_ENTRY_PTR;


/*
** file handle as defined by MFS
*/
typedef struct mfs_handle
{
   QUEUE_ELEMENT_STRUCT   HEADER_PTR;

   uint_32         VALID;
   MFS_DIR_ENTRY   DIR_ENTRY;
   uint_16         ACCESS;
   uint_16         TOUCHED;
   uint_32         CURRENT_CLUSTER;
   uint_32         PREVIOUS_CLUSTER;
   uint_32         SAVED_POSITION;
   uint_32         DIR_CLUSTER;
   uint_32         DIR_INDEX;

} MFS_HANDLE, _PTR_ MFS_HANDLE_PTR;

/*
** extern statements for MFS
*/

extern _mem_pool_id _MFS_pool_id;
extern uint_32 _MFS_handle_pool_init;
extern uint_32 _MFS_handle_pool_grow;
extern uint_32 _MFS_handle_pool_max;

#ifdef __cplusplus
extern "C" {
#endif

extern uint_32    _io_mfs_install(MQX_FILE_PTR dev_fd,char_ptr identifier, uint_32 part_num);
extern uint_32    _io_mfs_uninstall(char_ptr identifier);
extern int_32     _io_mfs_open(MQX_FILE_PTR fd_ptr,char_ptr, char_ptr flags_str);
extern int_32     _io_mfs_close(MQX_FILE_PTR fd_ptr);
extern int_32     _io_mfs_read(MQX_FILE_PTR file_ptr,char_ptr data_ptr,int_32 num);
extern int_32     _io_mfs_write(MQX_FILE_PTR file_ptr,char_ptr data_ptr,int_32 num);
extern int_32     _io_mfs_ioctl(MQX_FILE_PTR file_ptr,uint_32 cmd,uint_32_ptr param_ptr);
extern pointer    _io_mfs_dir_open(MQX_FILE_PTR fs_ptr, char_ptr wildcard_ptr, char_ptr mode_ptr);
extern int_32     _io_mfs_dir_read(pointer dir, char_ptr buffer, uint_32 size);
extern int_32     _io_mfs_dir_close(pointer dir);
extern boolean    MFS_is_autogenerated_name(char_ptr s_fname);
extern char_ptr   MFS_Error_text(uint_32 error_code);
extern pointer    MFS_mem_alloc(_mem_size size);
extern pointer    MFS_mem_alloc_zero(_mem_size size);
extern pointer    MFS_mem_alloc_system(_mem_size size);
extern pointer    MFS_mem_alloc_system_zero(_mem_size size);
extern _mfs_error MFS_alloc_path(char_ptr * path_ptr_ptr);
extern _mfs_error MFS_alloc_2paths(char_ptr * path1_ptr_ptr,char_ptr * path2_ptr_ptr);
extern boolean    MFS_free_path(char_ptr path_ptr);

#ifdef __cplusplus
}
#endif

#if (MFSCFG_NUM_OF_FATS == 0)
#error "Illegal number of FATS"
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/nandflash/nandflash.h<|end_filename|>
#ifndef _nandflash_h_
#define _nandflash_h_
/**HEADER********************************************************************
* 
* Copyright (c) 2010 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: nandflash.h$
* $Version : 3.8.7.0$
* $Date    : Jun-6-2012$
*
* Comments:
*
*   The file contains functions prototype, defines, structure 
*   definitions specific for the NAND flash driver.
*
*END************************************************************************/

#include "ioctl.h"

/*----------------------------------------------------------------------*/
/*
**                          CONSTANT DEFINITIONS
*/

/*
** NAND Flash command set
*/
#define NANDFLASH_CMD_PAGE_READ_CYCLE1       0x00
#define NANDFLASH_CMD_PAGE_READ_CYCLE2       0x30
#define NANDFLASH_CMD_RESET                  0xFF
#define NANDFLASH_CMD_PAGE_PROGRAM_CYCLE1    0x80
#define NANDFLASH_CMD_PAGE_PROGRAM_CYCLE2    0x10
#define NANDFLASH_CMD_BLOCK_ERASE_CYCLE1     0x60
#define NANDFLASH_CMD_BLOCK_ERASE_CYCLE2     0xD0
#define NANDFLASH_CMD_READ_STATUS            0x70
#define NANDFLASH_CMD_READ_ID                0x90

/*
** NAND Flash status response
*/
#define NANDFLASH_STATUS_PASS                0x00
#define NANDFLASH_STATUS_ERR                 0x01

/*
** NAND Flash IOCTL calls
*/
#define NANDFLASH_IOCTL_GET_PHY_PAGE_SIZE    _IO(IO_TYPE_NANDFLASH,0x01)
#define NANDFLASH_IOCTL_GET_SPARE_AREA_SIZE  _IO(IO_TYPE_NANDFLASH,0x02)
#define NANDFLASH_IOCTL_GET_BLOCK_SIZE       _IO(IO_TYPE_NANDFLASH,0x03)
#define NANDFLASH_IOCTL_GET_NUM_BLOCKS       _IO(IO_TYPE_NANDFLASH,0x04)
#define NANDFLASH_IOCTL_GET_WIDTH            _IO(IO_TYPE_NANDFLASH,0x05)
#define NANDFLASH_IOCTL_GET_NUM_VIRT_PAGES   _IO(IO_TYPE_NANDFLASH,0x06)
#define NANDFLASH_IOCTL_GET_VIRT_PAGE_SIZE   _IO(IO_TYPE_NANDFLASH,0x07)
#define NANDFLASH_IOCTL_ERASE_BLOCK          _IO(IO_TYPE_NANDFLASH,0x08)
#define NANDFLASH_IOCTL_ERASE_CHIP           _IO(IO_TYPE_NANDFLASH,0x09)
#define NANDFLASH_IOCTL_WRITE_PROTECT        _IO(IO_TYPE_NANDFLASH,0x0A)
#define NANDFLASH_IOCTL_GET_WRITE_PROTECT    _IO(IO_TYPE_NANDFLASH,0x0B)
#define NANDFLASH_IOCTL_CHECK_BLOCK          _IO(IO_TYPE_NANDFLASH,0x0C)
#define NANDFLASH_IOCTL_MARK_BLOCK_AS_BAD    _IO(IO_TYPE_NANDFLASH,0x0D)
#define NANDFLASH_IOCTL_GET_BAD_BLOCK_TABLE  _IO(IO_TYPE_NANDFLASH,0x0E)
#define NANDFLASH_IOCTL_GET_ID               _IO(IO_TYPE_NANDFLASH,0x0F)
#define NANDFLASH_IOCTL_ERASE_BLOCK_FORCE    _IO(IO_TYPE_NANDFLASH,0x10)
 
/*
** NAND Flash Error Codes 
*/

#define NANDFLASHERR_NO_ERROR                (0)
#define NANDFLASHERR_ECC_FAILED              (NANDFLASH_ERROR_BASE | 0x01)
#define NANDFLASHERR_ECC_CORRECTED           (NANDFLASH_ERROR_BASE | 0x02)
#define NANDFLASHERR_ERASE_FAILED            (NANDFLASH_ERROR_BASE | 0x03)
#define NANDFLASHERR_WRITE_FAILED            (NANDFLASH_ERROR_BASE | 0x04)
#define NANDFLASHERR_TIMEOUT                 (NANDFLASH_ERROR_BASE | 0x05)
#define NANDFLASHERR_BLOCK_BAD               (NANDFLASH_ERROR_BASE | 0x06)
#define NANDFLASHERR_BLOCK_NOT_BAD           (NANDFLASH_ERROR_BASE | 0x07)
#define NANDFLASHERR_INFO_STRUC_MISSING      (NANDFLASH_ERROR_BASE | 0x08)
#define NANDFLASHERR_IMPROPER_ECC_SIZE       (NANDFLASH_ERROR_BASE | 0x09)

/*
** NAND Flash ID Masks 
*/

#define NANDFLASH_ID_PAGE_SIZE_MASK           0x00000003
#define NANDFLASH_ID_SPARE_BYTES_NUM_MASK     0x0000000C
#define NANDFLASH_ID_BLOCK_SIZE_MASK          0x00000030
#define NANDFLASH_ID_WIDTH_MASK               0x00000040
#define NANDFLASH_ID_DENSITY_MASK             0x000F0000

#define NANDFLASH_DENSITY_1Gb                 0x01
#define NANDFLASH_DENSITY_2Gb                 0x0A
#define NANDFLASH_DENSITY_4Gb                 0x0C
#define NANDFLASH_DENSITY_8Gb                 0x03
#define NANDFLASH_DENSITY_16Gb                0x05

/*
** ECC size to ECC bytes conversion
*/

#define NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(x) ((x * 2) - (x >> 3))


/*----------------------------------------------------------------------*/
/*
**                    Structure Definitions
*/

/*
** NAND FLASH INFO STRUCT
**
** This structure is used to describe the organization of a NAND flash chip
*/
typedef struct nandflash_info_struct
{
   /* The size of the NAND Flash physical page in Bytes (without spare bytes) */
   _mem_size        PHY_PAGE_SIZE;

   /* The size of the NAND Flash spare area in Bytes */
   _mem_size        SPARE_AREA_SIZE;

   /* The size of one block in Bytes */
   _mem_size        BLOCK_SIZE;

   /* The number of NAND Flash blocks */
   _mqx_uint        NUM_BLOCKS;
   
   /* the width of the device in Bytes */
   _mqx_uint        WIDTH;

} NANDFLASH_INFO_STRUCT, _PTR_ NANDFLASH_INFO_STRUCT_PTR;

/*
** NANDFLASH STRUCT
**
** The address of this structure is used to maintain NAND flash specific 
** information.
*/

typedef struct io_nandflash_struct
{
   /* The function to call to initialize the NAND flash device, if needed */
   uint_32 (_CODE_PTR_           INIT)(struct io_nandflash_struct _PTR_);

   /* The function to call to disable the NAND flash device, if needed */
   void (_CODE_PTR_              DEINIT)(struct io_nandflash_struct _PTR_);
   
   /* The function to call to erase the entire NAND flash chip */
   uint_32 (_CODE_PTR_           CHIP_ERASE)(struct io_nandflash_struct _PTR_);

   /* The function to call to erase one NAND flash block */
   uint_32 (_CODE_PTR_           BLOCK_ERASE)(struct io_nandflash_struct _PTR_, 
      uint_32, boolean);

   /* The function to call to read one page of the NAND flash */
   uint_32 (_CODE_PTR_           PAGE_READ)(struct io_nandflash_struct _PTR_, 
      uchar_ptr, uint_32, uint_32);

   /* The function to call to program one page of the NAND flash */
   uint_32 (_CODE_PTR_           PAGE_PROGRAM)(struct io_nandflash_struct _PTR_, 
      uchar_ptr, uint_32, uint_32);
   
   /* The function to call to write-enable or write-protect the device */
   uint_32 (_CODE_PTR_           WRITE_PROTECT)(struct io_nandflash_struct _PTR_, 
      boolean);
   
   /* The function to call to check if the defined block is bad */
   uint_32 (_CODE_PTR_           IS_BLOCK_BAD)(struct io_nandflash_struct _PTR_, 
      uint_32);
   
   /* The function to call to mark the defined block as bad */
   uint_32 (_CODE_PTR_           MARK_BLOCK_AS_BAD)(struct io_nandflash_struct _PTR_, 
      uint_32);
   
   /* The ioctl function to call */
   _mqx_int (_CODE_PTR_          IOCTL)(struct io_nandflash_struct _PTR_, 
      _mqx_uint, pointer);

   /* This structure provides an orgaization of the NAND flash device */ 
   NANDFLASH_INFO_STRUCT_PTR     NANDFLASH_INFO_PTR;
   
   /* The size of one virtual page in Bytes.
      One Physical page can be divided into several virtual pages if supported 
      by the NAND Flash Controller. Virtual page is the smallest unit a block
      device can work with. */
   _mem_size                     VIRTUAL_PAGE_SIZE;

   /* The number of NAND Flash virtual pages */
   _mqx_uint                     NUM_VIRTUAL_PAGES;
   
   /* The ratio between the physical page size and the virtual page size */
   _mqx_uint                     PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO;
   
   /* The number of ECC correction bits per one virtual page */
   uint_32                       ECC_SIZE;
   
   /* When finished programming, should a comparison of data be made
   ** to verify that the write worked correctly.
   */
   _mqx_uint                     WRITE_VERIFY;

   /* Light weight semaphore struct */
   LWSEM_STRUCT                  LWSEM;
   
   /* The current error code for the device */
   _mqx_uint                     ERROR_CODE;
   
   /* The number of tasks which have access to the NAND flash device */
   _mqx_uint                     COUNT;
   
   /* Flags */
   _mqx_uint                     FLAGS;
   
   /* The address of device specific structure */ 
   pointer                       DEVICE_SPECIFIC_DATA;

} IO_NANDFLASH_STRUCT, _PTR_ IO_NANDFLASH_STRUCT_PTR;




/* 
** NANDFLASH INIT STRUCT
**
** This structure is used to initialize a NAND flash device.
*/
typedef struct nandflash_init_struct
{

   /* A pointer to a string that identifies the device for fopen */
   char_ptr                      ID_PTR;
   
   /* The function to call to initialize the NAND flash device, if needed */
   uint_32 (_CODE_PTR_           INIT)(struct io_nandflash_struct _PTR_);

   /* The function to call to disable the NAND flash device, if needed */
   void (_CODE_PTR_              DEINIT)(struct io_nandflash_struct _PTR_);
   
   /* The function to call to erase the entire NAND flash chip */
   uint_32 (_CODE_PTR_           CHIP_ERASE)(struct io_nandflash_struct _PTR_);

   /* The function to call to erase one NAND flash block */
   uint_32 (_CODE_PTR_           BLOCK_ERASE)(struct io_nandflash_struct _PTR_, 
      uint_32, boolean);

   /* The function to call to read one page of the NAND flash */
   uint_32 (_CODE_PTR_           PAGE_READ)(struct io_nandflash_struct _PTR_, 
      uchar_ptr, uint_32, uint_32);

   /* The function to call to program one page of the NAND flash */
   uint_32 (_CODE_PTR_           PAGE_PROGRAM)(struct io_nandflash_struct _PTR_, 
      uchar_ptr, uint_32, uint_32);
   
   /* The function to call to write-enable or write-protect the device */
   uint_32 (_CODE_PTR_           WRITE_PROTECT)(struct io_nandflash_struct _PTR_, 
      boolean);
   
   /* The function to call to check if the defined block is bad */
   uint_32 (_CODE_PTR_           IS_BLOCK_BAD)(struct io_nandflash_struct _PTR_, 
      uint_32);
   
   /* The function to call to mark the defined block as bad */
   uint_32 (_CODE_PTR_           MARK_BLOCK_AS_BAD)(struct io_nandflash_struct _PTR_, 
      uint_32);
   
   /* The ioctl function to call */
   _mqx_int (_CODE_PTR_          IOCTL)(IO_NANDFLASH_STRUCT_PTR, 
      _mqx_uint, pointer);

   /* This structure provides an orgaization of the NAND flash device */ 
   NANDFLASH_INFO_STRUCT_PTR     NANDFLASH_INFO_PTR;
      
   /* The size of one virtual page in Bytes.
      One Physical page can be divided into several virtual pages if supported 
      by the NAND Flash Controller. Virtual page is the smallest unit a block
      device can work with. */
   _mem_size                     VIRTUAL_PAGE_SIZE;

   /* The number of NAND Flash virtual pages */
   _mqx_uint                     NUM_VIRTUAL_PAGES;
   
   /* The ratio between the physical page size and the virtual page size */
   _mqx_uint                     PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO;
   
   /* The number of ECC correction bits per one virtual page */
   uint_32                       ECC_SIZE;
   
   /* When finished programming, should a comparison of data be made
   ** to verify that the write worked correctly.
   */
   _mqx_uint                     WRITE_VERIFY;

   /* The address of device specific structure */ 
   pointer                       DEVICE_SPECIFIC_DATA;
   

} NANDFLASH_INIT_STRUCT, _PTR_ NANDFLASH_INIT_STRUCT_PTR;

typedef const NANDFLASH_INIT_STRUCT _PTR_ NANDFLASH_INIT_STRUCT_CPTR;
/*----------------------------------------------------------------------*/
/*
**                    FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif
  
extern _mqx_uint _io_nandflash_install(NANDFLASH_INIT_STRUCT_CPTR);
extern _mqx_int  _io_nandflash_uninstall(IO_DEVICE_STRUCT_PTR);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/usb/host/source/host/ehci/ehci_prv.h<|end_filename|>
#ifndef __ehci_prv_h__
#define __ehci_prv_h__ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ehci_prv.h$
* $Version : 3.8.17.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This file contains the internal USB Host specific type definitions
*
*END************************************************************************/

#include "hostapi.h"
#include "host_cnfg.h"

#include "ehci_cache.h"
#include "ehci.h"


#define  HUB_LS_SETUP                        (333)

/***************************************
**
** Code macros
**
*/

/* Macro for alignment to specific byte boundary */
#define  USB_MEM32_ALIGN(n)                  ((n) + (-(n) & 31))
#define  USB_MEM512_ALIGN(n)                 ((n) + (-(n) & 511))
#define  USB_MEM4096_ALIGN(n)                ((n) + (-(n) & 4095))

#define  BitStuffTime(x)                     (7* 8 * x / 6)

typedef struct ehci_tr_struct
{
   TR_STRUCT                     G;  /* generic transfer fields */
  /* number of ITds/SITDs used for this transfer */
   uint_32                       no_of_itds_sitds;
   uint_32                       SOFAR; /* number of bytes sent/recv'd so far */

   /****************************************************
   Data cache requirement is that any buffer that stores
   the data should be cache aligned. This means that the
   setup packet buffer must be cache aligned too. Structure
   fields above this have occupied 28 + 16 = 44 bytes.
   We add a 20 bytes padding to makesure that it is aligned
   on a 32 byte boundry since 44 + 20 = 64; We also
   add a padding at the end to ensure that we don't corrupt
   someother memory when we flush the setup packet
   from cache.
   ****************************************************/
#if PSP_HAS_DATA_CACHE  // TODO check align
    uint_8                       RESERVED1[USB_CACHE_ALIGN(40) - 40];
#endif // PSP_HAS_DATA_CACHE
   
#if PSP_HAS_DATA_CACHE  // TODO check align
    uint_8               RESERVED2[USB_CACHE_ALIGN(8) - 8];
#endif
} EHCI_TR_STRUCT, _PTR_ EHCI_TR_STRUCT_PTR;
    
typedef struct ehci_pipe_struct
{
   PIPE_STRUCT          G;

   uint_32              CURRENT_NAK_COUNT;
   pointer              QH_FOR_THIS_PIPE; /* Queue head for this pipe */

   /* Special fields defined for periodic transfers */
   uint_32              START_FRAME;    /*frame number from which this pipe is started to schedule*/
   uint_32              START_UFRAME;   /*Micro frame number from which this pipe is started to schedule*/
   uint_32              NO_OF_START_SPLIT; /* store the number of start splits (used for ISO OUT )*/
   uint_8               START_SPLIT;    /* store the start split slots for full speed devices*/
   uint_8               COMPLETE_SPLIT; /* store the complete split slots for full speed devices*/
   uint_16              BWIDTH;         /* time take by this pipe (for periodic pipes only */
   uint_8               BWIDTH_SLOTS[8];/*micro frame slots budgeted for transaction */
   
   /* 84 bytes so far add padding to ensure cache alignment*/
#if PSP_HAS_DATA_CACHE  // TODO check align
   uint_8               reserved[USB_CACHE_ALIGN(74) - 74]; 
#endif  
    
} EHCI_PIPE_STRUCT, _PTR_ EHCI_PIPE_STRUCT_PTR;

/* Queue head management data structure */
typedef struct active_qh_mgmt_struct {
   EHCI_QH_STRUCT_PTR                  QH_PTR;
   EHCI_QTD_STRUCT_PTR                 FIRST_QTD_PTR;
   int_32                              TIME;
   struct active_qh_mgmt_struct _PTR_  NEXT_ACTIVE_QH_MGMT_STRUCT_PTR;
} ACTIVE_QH_MGMT_STRUCT, _PTR_ ACTIVE_QH_MGMT_STRUCT_PTR;

/* ITD,SITD list management data structure (doubly link list )*/
typedef struct list_node_struct {
   struct list_node_struct _PTR_  next;        /* next member in the list */
   struct list_node_struct _PTR_  prev;        /* previous member in the list */
   boolean   next_active; /* is next node a active node */
   pointer   member;      /* pointer to the currently active ITD or SITD*/
} LIST_NODE_STRUCT, _PTR_ LIST_NODE_STRUCT_PTR;


/* Class Callback function storage structure */
typedef struct class_service_struct {
   uint_8               CLASS_TYPE;
   uint_8               SUB_CLASS;
   uint_8               PROTOCOL;
   /* index of the instance */
   uint_8               INDEX;
   /* identification string unique to this type */
   char_ptr             CLASS_ID_STRING;
   /* class handle will be NULL if it is not initialized */
   pointer              CLASS_HANDLE;
   pointer (_CODE_PTR_  INIT)(pointer, uint_32);
   void    (_CODE_PTR_  DEINIT)(pointer);
   void    (_CODE_PTR_  CALL_BACK_INIT)(pointer, char_ptr);
   void    (_CODE_PTR_  CALL_BACK_REMOVE)(pointer);
   struct class_service_struct _PTR_ NEXT_INSTANCE;
   struct class_service_struct _PTR_ NEXT;
} USB_HOST_CLASS_DRIVER_STRUCT, _PTR_ USB_HOST_CLASS_DRIVER_STRUCT_PTR;

typedef struct  usb_ehci_host_state_structure {
   USB_HOST_STATE_STRUCT               G; /* generic host state */
   uint_32                             FRAME_LIST_SIZE;
   uint_8_ptr                          PERIODIC_FRAME_LIST_BW_PTR;
   pointer                             PERIODIC_LIST_BASE_ADDR;
   pointer                             ALIGNED_PERIODIC_LIST_BASE_ADDR;
   EHCI_QH_STRUCT_PTR                  ASYNC_LIST_BASE_ADDR;
   EHCI_QH_STRUCT_PTR                  ALIGNED_ASYNCLIST_ADDR;
   EHCI_QH_STRUCT_PTR                  QH_BASE_PTR; 
   EHCI_QH_STRUCT_PTR                  QH_ALIGNED_BASE_PTR; 
   uint_32                             QH_ENTRIES;
   EHCI_QH_STRUCT_PTR                  QH_HEAD;
   EHCI_QH_STRUCT_PTR                  QH_TAIL;
   ACTIVE_QH_MGMT_STRUCT_PTR           ACTIVE_ASYNC_LIST_PTR;
   ACTIVE_QH_MGMT_STRUCT_PTR           ACTIVE_INTERRUPT_PERIODIC_LIST_PTR;
   EHCI_QTD_STRUCT_PTR                 QTD_BASE_PTR;
   EHCI_QTD_STRUCT_PTR                 QTD_HEAD;
   EHCI_QTD_STRUCT_PTR                 QTD_TAIL;
   EHCI_QTD_STRUCT_PTR                 QTD_ALIGNED_BASE_PTR;
   uint_32                             QTD_ENTRIES;
   boolean                             HIGH_SPEED_ISO_QUEUE_ACTIVE; 
   LIST_NODE_STRUCT_PTR                ACTIVE_ISO_ITD_PERIODIC_LIST_HEAD_PTR;
   LIST_NODE_STRUCT_PTR                ACTIVE_ISO_ITD_PERIODIC_LIST_TAIL_PTR;
   EHCI_ITD_STRUCT_PTR                 ITD_BASE_PTR;
   EHCI_ITD_STRUCT_PTR                 ITD_ALIGNED_BASE_PTR;
   EHCI_ITD_STRUCT_PTR                 ITD_HEAD;
   EHCI_ITD_STRUCT_PTR                 ITD_TAIL;
   uint_32                             ITD_ENTRIES;
   boolean                             FULL_SPEED_ISO_QUEUE_ACTIVE; 
   LIST_NODE_STRUCT_PTR                ACTIVE_ISO_SITD_PERIODIC_LIST_HEAD_PTR;
   LIST_NODE_STRUCT_PTR                ACTIVE_ISO_SITD_PERIODIC_LIST_TAIL_PTR;
   EHCI_SITD_STRUCT_PTR                SITD_BASE_PTR;
   EHCI_SITD_STRUCT_PTR                SITD_ALIGNED_BASE_PTR;
   EHCI_SITD_STRUCT_PTR                SITD_HEAD;
   EHCI_SITD_STRUCT_PTR                SITD_TAIL;
   uint_32                             SITD_ENTRIES;
   uint_32                             RESET_RECOVERY_TIMER;
   uint_32                             PORT_NUM;
   uint_8                              UFRAME_COUNT;
   pointer                             CONTROLLER_MEMORY;
   boolean                             PERIODIC_LIST_INITIALIZED;
   boolean                             ITD_LIST_INITIALIZED;
   boolean                             SITD_LIST_INITIALIZED;
   boolean                             IS_RESETTING;
} USB_EHCI_HOST_STATE_STRUCT, _PTR_ USB_EHCI_HOST_STATE_STRUCT_PTR;

#define EHCI_GET_TYPE(data_struct_ptr) \
   (EHCI_MEM_READ(*((USB_Uncached uint_32 _PTR_)data_struct_ptr)) & EHCI_ELEMENT_TYPE_MASK)

#define EHCI_ITD_QADD(head, tail, ITD)      \
   if ((head) == NULL) {         \
      (head) = (ITD);            \
   } else {                      \
      (tail)->SCRATCH_PTR = (void *) (ITD);   \
   } /* Endif */                 \
   (tail) = (ITD);               \
   (ITD)->SCRATCH_PTR = NULL
   
#define EHCI_ITD_QGET(head, tail, ITD)      \
   (ITD) = (head);               \
   if (head) {                   \
      (head) = (EHCI_ITD_STRUCT_PTR)((head)->SCRATCH_PTR);  \
      if ((head) == NULL) {      \
         (tail) = NULL;          \
      } /* Endif */              \
   } /* Endif */

#define EHCI_ACTIVE_QUEUE_ADD_NODE(tail,member_ptr)     \
   if (tail->prev != NULL) {                             \
       tail->prev->next_active = TRUE;                   \
   }                                                     \
   tail->member = (pointer) member_ptr;                                  \
   tail->next_active = FALSE;                            \
   tail = tail->next;                   

#define EHCI_QUEUE_FREE_NODE(head,tail,node_ptr) \
   if(node_ptr->prev != NULL) {                             \
     node_ptr->prev->next = node_ptr->next;                 \
     node_ptr->prev->next_active = node_ptr->next_active;   \
     node_ptr->next->prev = node_ptr->prev;                 \
   } else  {                                                \
     head = node_ptr->next;                                 \
     head->prev = NULL;                                     \
   }                                                        \
   node_ptr->next = tail->next;                             \
   node_ptr->prev = tail;                                   \
   node_ptr->next_active = FALSE;                           \
   node_ptr->member = NULL;                                 \
   if(tail->next != NULL)   {                               \
      tail->next->prev = node_ptr;                          \
   }                                                        \
   tail->next = node_ptr;                                   \
   tail->next_active = FALSE;                             




#define EHCI_SITD_QADD(head, tail, SITD)      \
   if ((head) == NULL) {         \
      (head) = (SITD);            \
   } else {                      \
      (tail)->SCRATCH_PTR = (void *) (SITD);   \
   } /* Endif */                 \
   (tail) = (pointer) (SITD);               \
   (SITD)->SCRATCH_PTR = NULL
   
#define EHCI_SITD_QGET(head, tail, SITD)      \
   (SITD) = (head);               \
   if (head) {                   \
      (head) = (EHCI_SITD_STRUCT_PTR)((head)->SCRATCH_PTR);  \
      if ((head) == NULL) {      \
         (tail) = NULL;          \
      } /* Endif */              \
   } /* Endif */
   
#define EHCI_QTD_QADD(head, tail, QTD)      \
   if ((head) == NULL) {         \
      (head) = (QTD);            \
   } else {                      \
      (tail)->SCRATCH_PTR = (void *) (QTD);   \
   } /* Endif */                 \
   (tail) = (pointer) (QTD);               \
   (QTD)->SCRATCH_PTR = NULL
   
#define EHCI_QTD_QGET(head, tail, QTD)      \
   (QTD) = (head);               \
   if (head) {                   \
      (head) = (EHCI_QTD_STRUCT_PTR)((head)->SCRATCH_PTR);  \
      if ((head) == NULL) {      \
         (tail) = NULL;          \
      } /* Endif */              \
   } /* Endif */

#define EHCI_QH_QADD(head, tail, QH)      \
   if ((head) == NULL) {         \
      (head) = (pointer) (QH);            \
   } else {                      \
      (tail)->SCRATCH_PTR = (void *) (QH);   \
   } /* Endif */                 \
   (tail) = (QH);               \
   (QH)->SCRATCH_PTR = NULL
   
#define EHCI_QH_QGET(head, tail, QH)      \
   (QH) = (head);               \
   if (head) {                   \
      (head) = (EHCI_QH_STRUCT_PTR)((head)->SCRATCH_PTR);  \
      if ((head) == NULL) {      \
         (tail) = NULL;          \
      } /* Endif */              \
   } /* Endif */

/* Additional Includes */
#include "ehci_bw.h"
#include "ehci_cncl.h"
#include "ehci_intr.h"
#include "ehci_iso.h"
#include "ehci_main.h"
#include "ehci_shut.h"
#include "ehci_utl.h"

/* Prototypes */

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/serial/serinprv.h<|end_filename|>
#ifndef __serinprv_h__
#define __serinprv_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: serinprv.h$
* $Version : 3.8.8.0$
* $Date    : Aug-29-2011$
*
* Comments:
*
*   This file includes the private definitions for the interrupt
*   driven serial I/O drivers.
*
*END************************************************************************/

/*--------------------------------------------------------------------------*/
/*
**                            CONSTANT DEFINITIONS
*/

/*
** Xon/Xoff protocol characters
*/
#define CNTL_S   ((char) 0x13)  /* Control S == XOFF.   */
#define CNTL_Q   ((char) 0x11)  /* Control Q == XON.    */

/*--------------------------------------------------------------------------*/
/*
**                            DATATYPE DECLARATIONS
*/

/*---------------------------------------------------------------------
**
** IO SERIAL INT DEVICE STRUCT
**
** This structure used to store information about a interrupt serial io device
** for the IO device table
*/
typedef struct io_serial_int_device_struct
{

   /* The I/O init function */
   _mqx_uint (_CODE_PTR_ DEV_INIT)(pointer, char _PTR_);

   /* The enable interrupts function */
   _mqx_uint (_CODE_PTR_ DEV_ENABLE_INTS)(pointer);

   /* The I/O deinit function */
   _mqx_uint (_CODE_PTR_ DEV_DEINIT)(pointer, pointer);

   /* The output function, used to write out the first character */
   void    (_CODE_PTR_ DEV_PUTC)(pointer, char);

   /* The ioctl function, (change bauds etc) */
   _mqx_uint (_CODE_PTR_ DEV_IOCTL)(pointer, _mqx_uint, pointer);

   /* The I/O channel initialization data */
   pointer             DEV_INIT_DATA_PTR;
   
   /* Device specific information */
   pointer             DEV_INFO_PTR;

   /* The queue size to use */
   _mqx_uint             QUEUE_SIZE;
   
   /* Open count for number of accessing file descriptors */
   _mqx_uint             COUNT;

   /* Open flags for this channel */
   _mqx_uint             FLAGS;

   /* The input queue */
   CHARQ_STRUCT_PTR    IN_QUEUE;

   /* The input waiting tasks */
   pointer             IN_WAITING_TASKS;

   /* The output queue */
   CHARQ_STRUCT_PTR    OUT_QUEUE;

   /* The output waiting tasks */
   pointer             OUT_WAITING_TASKS;

   /* Has output been started */
   boolean             OUTPUT_ENABLED;

   /* Protocol flag information */
   _mqx_uint             HAVE_STOPPED_OUTPUT;
   _mqx_uint             HAVE_STOPPED_INPUT;
   _mqx_uint             MUST_STOP_INPUT;
   _mqx_uint             MUST_START_INPUT;
   _mqx_uint             INPUT_HIGH_WATER_MARK;
   _mqx_uint             INPUT_LOW_WATER_MARK;
   _mqx_uint             MUST_STOP_OUTPUT;
   
#if MQX_ENABLE_LOW_POWER
   
   /* Low power related state information */
   IO_SERIAL_LPM_STRUCT  LPM_INFO;
   
#endif

} IO_SERIAL_INT_DEVICE_STRUCT, _PTR_ IO_SERIAL_INT_DEVICE_STRUCT_PTR;


/*--------------------------------------------------------------------------*/
/*
**                            FUNCTION PROTOTYPES
*/

#ifdef __cplusplus
extern "C" {
#endif

/* Interrupt I/O prototypes */
extern _mqx_int  _io_serial_int_open(FILE_DEVICE_STRUCT_PTR, char _PTR_, 
   char _PTR_);
extern _mqx_int  _io_serial_int_close(FILE_DEVICE_STRUCT_PTR);
extern _mqx_int  _io_serial_int_read(FILE_DEVICE_STRUCT_PTR, char _PTR_, _mqx_int);
extern _mqx_int  _io_serial_int_write(FILE_DEVICE_STRUCT_PTR, char _PTR_, _mqx_int);
extern _mqx_int  _io_serial_int_ioctl(FILE_DEVICE_STRUCT_PTR, _mqx_uint, 
   pointer);
extern _mqx_int _io_serial_int_uninstall(IO_DEVICE_STRUCT_PTR);

/* Callback Functions called by lower level interrupt I/O interrupt handlers */
extern boolean _io_serial_int_addc(IO_SERIAL_INT_DEVICE_STRUCT_PTR, char);
extern _mqx_int  _io_serial_int_nextc(IO_SERIAL_INT_DEVICE_STRUCT_PTR);

/* Internal helper functions */
extern boolean    _io_serial_int_putc_internal(IO_SERIAL_INT_DEVICE_STRUCT_PTR, 
   char, _mqx_uint);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/adc/mcf522xx/adc_mcf522xx.c<|end_filename|>
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: adc_mcf522xx.c$
* $Version : 3.6.24.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains the ADC driver CPU specific functions
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <fio.h>
#include <fio_prv.h>
#include "io.h"
#include "adc.h"
#include "adc_prv.h"
#include "adc_conf.h"
#include "adc_mcf522xx_prv.h"

#if BSPCFG_ENABLE_ADC

/* Peripherals pointer */
static VMCF522XX_ADC_STRUCT_PTR  mcf522xx_adc_ptr;

/* static variables */
static void (_CODE_PTR_ old_isr_adc1)(pointer);
static pointer          old_isr_adc1_param;
static ADC_DRIVER_BUNDLE_PTR driver_bundle = NULL;

/* Declarations of IRQ handlers */
static void _adc_g_conv_end(uint_16_ptr results, ADC_HW_CHANNEL_MASK mask);
static void adc_complete_isr(pointer);
static uint_32 adc_channels_used = 0;

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_hw_ioctl
* Returned Value   : _mqx_int
* Comments         :
*    Returns result of ioctl operation.
*
*END*********************************************************************/
_mqx_int _adc_hw_ioctl(MQX_FILE_PTR f, _mqx_uint cmd, pointer param_ptr)
{
    return IO_ERROR_INVALID_IOCTL_CMD;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_hw_install
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific initialization for ADC driver (during install)
*
*END*********************************************************************/
_mqx_int _adc_hw_install(char_ptr a, ADC_DRIVER_BUNDLE_PTR b, pointer c)
{
   return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_hw_init
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific initialization for ADC driver
*
*END*********************************************************************/
_mqx_int _adc_hw_init(MQX_FILE_PTR f, ADC_PTR adc)
{ /* Body */
    ADC_DRIVER_BUNDLE_PTR adc_d_bundle = (ADC_DRIVER_BUNDLE_PTR) f->DEV_PTR->DRIVER_INIT_PTR;

#if PSP_MQX_CPU_IS_MCF5225X
    VMCF5225_STRUCT_PTR mcf522xx_ptr;
#elif PSP_MQX_CPU_IS_MCF5223X
    VMCF5223_STRUCT_PTR mcf522xx_ptr;
#elif PSP_MQX_CPU_IS_MCF5222X
    VMCF5222_STRUCT_PTR mcf522xx_ptr;
#else
    #error This CPU is not supported here
#endif
    
    _mqx_uint        div_register;
    _mqx_int         i;

    /* Prepare pointers to peripherals */
    mcf522xx_ptr = _PSP_GET_IPSBAR();
    mcf522xx_adc_ptr = _bsp_get_adc_base_address();

    if (adc->g.resolution != ADC_RESOLUTION_12BIT)
        return ADC_ERROR_BAD_PARAM; /* cannot set ADC resolution */

    /* Prepare ADC clocking to be as fast as possible */
    div_register = (BSP_SYSTEM_CLOCK - 1) / 20000000;
    if (div_register > 31)
        return ADC_ERROR_BAD_PARAM; /* cannot set ADC frequency */

    /* store information about exact ADC clock frequency */
    adc->g.adc_frq = (BSP_SYSTEM_CLOCK >> 2) / (div_register + 1);

    /* Prepare AD converter, but do not start it */
    mcf522xx_adc_ptr->CTRL2 = 0x0800 | div_register; /* Channel B can run in parallel with channel A */
    mcf522xx_adc_ptr->CTRL1 = 0x0800; /* Once mode, single conversion, all inputs single-ended */
    mcf522xx_adc_ptr->POWER &= 0xfff8; /* Power up ADC */

/* Install ISR for ADC */
#if PSP_MQX_CPU_IS_MCF5225X
    old_isr_adc1_param = _int_get_isr_data(BSP_ADC_INTERRUPT_VECTOR);
    old_isr_adc1 = _int_install_isr(BSP_ADC_INTERRUPT_VECTOR, adc_complete_isr, NULL);
#elif PSP_MQX_CPU_IS_MCF5223X
    old_isr_adc1_param = _int_get_isr_data(MCF5223_INT_ADC_ADCA);
    old_isr_adc1 = _int_install_isr(MCF5223_INT_ADC_ADCA, adc_complete_isr, NULL);
#elif PSP_MQX_CPU_IS_MCF5222X
    old_isr_adc1_param = _int_get_isr_data(MCF5222_INT_ADC_ADCA);
    old_isr_adc1 = _int_install_isr(MCF5222_INT_ADC_ADCA, adc_complete_isr, NULL);
#else
    #error This CPU is not supported here
#endif

    if (NULL == old_isr_adc1)
        return ADC_ERROR_ISR; /* could not install new interrupt routine */


#if PSP_MQX_CPU_IS_MCF5225X
    /* Setup ISR levels for ADC */
    _mcf5225_int_init(BSP_ADC_INTERRUPT_VECTOR, BSP_ADC_INTERRUPT_LEVEL, BSP_ADC_INTERRUPT_SUBLEVEL, TRUE);
#elif PSP_MQX_CPU_IS_MCF5223X
    /* Setup ISR levels for ADC */
    _mcf5223_int_init(BSP_ADC_INTERRUPT_VECTOR, BSP_ADC_INTERRUPT_LEVEL, BSP_ADC_INTERRUPT_SUBLEVEL, TRUE);
#elif PSP_MQX_CPU_IS_MCF5222X
    /* Setup ISR levels for ADC */
    _mcf5222_int_init(BSP_ADC_INTERRUPT_VECTOR, BSP_ADC_INTERRUPT_LEVEL, BSP_ADC_INTERRUPT_SUBLEVEL, TRUE);
#else
        #error This CPU is not supported here
#endif

    driver_bundle = adc_d_bundle;
    return ADC_OK;
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_hw_deinit
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific deinitialization for ADC driver
*
*END*********************************************************************/
_mqx_int _adc_hw_deinit(MQX_FILE_PTR f, ADC_PTR adc) {
    return ADC_OK;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_hw_channel_init
* Returned Value   : int_32
* Comments         :
*    Returns result of HW channel initialization
*
*END*********************************************************************/
_mqx_int _adc_hw_channel_init(MQX_FILE_PTR f, ADC_CHANNEL_PTR adc_ch)
{ /* Body */
    _mqx_uint result;

    if (adc_ch->g.source > ADC_SOURCE_AN6_AN7)
        return ADC_ERROR_BAD_PARAM; /* ADC_SOURCE_ constant does not match any source signal for this CPU */
    if ((1 << adc_ch->g.source) & adc_channels_used)
        return ADC_ERROR_OPENED; /* channel already used */
    /* configure GPIO and MUX for ADC */
    if (IO_OK == (result = _bsp_adc_io_init(adc_ch->g.source)))
        adc_channels_used |= 1 << adc_ch->g.source;

    return result;        
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_hw_channel_deinit
* Returned Value   : _mqx_int
* Comments         :
*    Performs CPU specific deinitialization for ADC channel
*
*END*********************************************************************/
_mqx_int _adc_hw_channel_deinit(MQX_FILE_PTR f, ADC_CHANNEL_PTR adc_ch) {
    adc_channels_used &= ~(1 << adc_ch->g.source);
    return ADC_OK;
}

/*FUNCTION****************************************************************
* 
* Function Name    : _adc_hw_measure
* Returned Value   : void
* Comments         : Prepares and runs ADC to measure data from channel
*
*END*********************************************************************/
void _adc_hw_measure(ADC_HW_CHANNEL_MASK mask) {
    _mqx_int i, j;

    mcf522xx_adc_ptr->ADSDIS = 0x00ff; /* presume all disabled */
    mcf522xx_adc_ptr->ADLST1 = mcf522xx_adc_ptr->ADLST2 = 0;
    for (i = 0, j = 0; i < ADC_SOURCE_MAX + 1; i++) {
        if ((1 << i) & mask) {
            if (j < 4)
                mcf522xx_adc_ptr->ADLST1 |= i << (4 * j++);
            else
                mcf522xx_adc_ptr->ADLST2 |= i << (4 * (j++ - 4));
            
            mcf522xx_adc_ptr->ADSDIS = mcf522xx_adc_ptr->ADSDIS << 1;
        }
    }
    mcf522xx_adc_ptr->CTRL1 |= 0x2000; /* start AD conversion */ 
    driver_bundle->last_mask = mask;
}

/*FUNCTION*****************************************************************
* 
* Function Name    : adc_complete_isr
* Returned Value   : void
* Comments         : IRQ handler for completed AD conversion(s)
*    In adc_c.channels_to_next_adc we have list of channels that
*    have been sampled and whole we need to handle the results.
*    We will copy results from AD converter to channels buffers.
*    Since AD converter can hold 8 samples a time, we check if any
*    other channel needs to be sampled and if yes, prepare next AD
*    conversion.
*
*END*********************************************************************/
static void adc_complete_isr
    (
        /* [IN] the address of the device specific information */
        pointer parameter
    )
{ /* Body */
    _mqx_int    i, j;
    uint_16_ptr results = (pointer) &mcf522xx_adc_ptr->ADRSLT[0]; /* prepare pointer to peripheral results */
    uint_16     results_internal[ADC_SOURCE_MAX]; /* 8 - number of results ADC can produce in one shot */
    mcf522xx_adc_ptr->ADSTAT |= 0x1800; /* clear interrupt flags */
   
    /* perform copies from ADC */
    for (i = 0; ((mcf522xx_adc_ptr->ADSDIS & 0x0001) == 0x0000) && (i < 8); i++, mcf522xx_adc_ptr->ADSDIS >>= 1) {
        if (i < 4) {
            j = mcf522xx_adc_ptr->ADLST1 & 0x000f;
            mcf522xx_adc_ptr->ADLST1 >>= 4;
        }
        else {
            j = mcf522xx_adc_ptr->ADLST2 & 0x000f;
            mcf522xx_adc_ptr->ADLST2 >>= 4;
        }
        results_internal[j] = results[i] >> 3;
    }
    _adc_g_conv_end(results_internal, driver_bundle->last_mask);
} /* Endbody */

/*FUNCTION*****************************************************************
* 
* Function Name    : _adc_g_conv_end
* Returned Value   : 
* Comments         : This is called by low-level driver to inform generic
*                    driver, that some conversion was performed. Function
*                    moves stored data to the channel buffers.
*END*********************************************************************/
static void _adc_g_conv_end(uint_16_ptr results_buf, ADC_HW_CHANNEL_MASK mask)
{
    _mqx_int i;
    ADC_CHANNEL_PTR *adc_ch = driver_bundle->adc_ch;
    ADT_CHANNEL_PTR *adt_ch = driver_bundle->adt_ch;

    for (i = 0; i < ADC_MAX_CHANNELS; i++) {
        if (!adt_ch[i] || !(adt_ch[i]->g.runtime_flags & ADC_CHANNEL_RESUMED) || !(mask & (1 << adc_ch[i]->g.source)))
            continue;
            
        if (adc_ch[i]->g.init_flags & ADC_CHANNEL_ACCUMULATE)
            /* if the channel has ADC_CHANNEL_ACCUMULATE, then accumulate result */
            adc_ch[i]->g.buffer_driver->result += results_buf[adc_ch[i]->g.source];

        else
            /* else copy the result to the channel buffer */
            adc_ch[i]->g.buffer_driver->result = results_buf[adc_ch[i]->g.source];

        if (!(adc_ch[i]->g.init_flags & ADC_CHANNEL_ACCUMULATE) || !(adt_ch[i]->g.samples)) {
            /* move driver pointer to next index, circullarily */
            if (++adc_ch[i]->g.buffer_driver >= adc_ch[i]->g.buffer_end)
                adc_ch[i]->g.buffer_driver = adc_ch[i]->g.buffer_start;

            /* if new value should overwrite old value in ring buffer, move read pointer to next value */
            if (adc_ch[i]->g.buffer_driver == adc_ch[i]->g.buffer_task) {
                if (++adc_ch[i]->g.buffer_task >= adc_ch[i]->g.buffer_end)
                    adc_ch[i]->g.buffer_task = adc_ch[i]->g.buffer_start;
            }
        }
        
        if (adt_ch[i]->g.samples) {
            adt_ch[i]->g.samples--;
        }
        else {
#if MQX_USE_LWEVENTS
            /* if it is the last sample in the batch, then set event */
            if (adt_ch[i]->g.complete_event)
                _lwevent_set(adt_ch[i]->g.complete_event, adt_ch[i]->g.event_mask); /* set completion event */
#endif
                
            if (adc_ch[i]->g.init_flags & ADC_CHANNEL_MEASURE_ONCE)
                adt_ch[i]->g.runtime_flags &= ~ADC_CHANNEL_RUNNING;
            
            adt_ch[i]->g.samples = adt_ch[i]->g.samples_preset;
        }
    }
}

/*FUNCTION****************************************************************
* 
* Function Name    : _bsp_get_adc_base_address
* Returned Value   : pointer to base of ADC registers
* Comments         :
*    This function returns base address of ADC related register space.
*
*END*********************************************************************/
pointer _bsp_get_adc_base_address
(
    void
)
{
#if PSP_MQX_CPU_IS_MCF5225X
    return (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->ADC);
#elif PSP_MQX_CPU_IS_MCF5222X
    return (pointer)(&((VMCF5222_STRUCT_PTR)_PSP_GET_IPSBAR())->ADC);
#elif PSP_MQX_CPU_IS_MCF5223X
    return (pointer)(&((VMCF5223_STRUCT_PTR)_PSP_GET_IPSBAR())->ADC);
#else
    #error This CPU is not supported here
    return NULL;
#endif
}

#endif // BSPCFG_ENABLE_ADC
/* EOF */


<|start_filename|>Firmware/Inverter_firmware/mqx/source/io/i2s/int/i2s_int.c<|end_filename|>
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: i2s_int.c$
* $Version : 3.8.2.0$
* $Date    : Oct-4-2012$
*
* Comments:
*
*   This include file is used to provide information needed by
*   applications using the I2S I/O functions.
*
*END************************************************************************/

#include <mqx.h>
#include <fio.h>
#include <io.h>
#include "i2s.h"
#include "i2s_int_prv.h"
#define MEM_TYPE_IO_I2S_DEVICE_STRUCT   1045
#define IO_DEV_TYPE_PHYS_I2S_INTERRUPT  (0x001E)


/*FUNCTION****************************************************************
*
* Function Name    : _io_i2s_install
* Returned Value   : MQX error code
* Comments         :
*    Install the I2S device.
*
*END**********************************************************************/

_mqx_uint _io_i2s_install
(
    /* [IN] A string that identifies the device for fopen */
    char_ptr                      identifier,

    /* [IN] The I/O init function */
    _mqx_uint (_CODE_PTR_ init)   (pointer, char_ptr),

    /* [IN] The I/O de-init function */
    _mqx_uint (_CODE_PTR_ deinit) (pointer, pointer),

    /* [IN] The input function */
    _mqx_int  (_CODE_PTR_ recv)   (pointer, char_ptr, _mqx_int),

    /* [IN] The output function */
    _mqx_int  (_CODE_PTR_ xmit)   (pointer, char_ptr, _mqx_int),

    /* [IN] The I/O ioctl function */
    _mqx_int  (_CODE_PTR_ ioctl)  (pointer, _mqx_uint, _mqx_uint_ptr),

    /* [IN] The I/O init data pointer */
    pointer                       init_data_ptr
)
{ /* Body */
    IO_I2S_DEVICE_STRUCT_PTR io_dev_ptr;

    io_dev_ptr = (IO_I2S_DEVICE_STRUCT_PTR) _mem_alloc_system_zero(sizeof (IO_I2S_DEVICE_STRUCT));

    if (io_dev_ptr == NULL)
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type (io_dev_ptr, MEM_TYPE_IO_I2S_DEVICE_STRUCT);

    io_dev_ptr->DEV_INIT          = init;
    io_dev_ptr->DEV_DEINIT        = deinit;
    io_dev_ptr->DEV_READ          = recv;
    io_dev_ptr->DEV_WRITE         = xmit;
    io_dev_ptr->DEV_IOCTL         = ioctl;
    io_dev_ptr->DEV_INIT_DATA_PTR = init_data_ptr;

    return (_io_dev_install_ext(identifier,
        _io_i2s_open, _io_i2s_close,
        _io_i2s_read, _io_i2s_write,
        _io_i2s_ioctl, _io_i2s_uninstall,
        (pointer)io_dev_ptr));

} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _io_i2s_uninstall
* Returned Value   : MQX error code
* Comments         :
*    UnInstall interrupt I2S device.
*
*END**********************************************************************/

_mqx_int _io_i2s_uninstall
(
    /* [IN] The IO device structure for the device */
    IO_DEVICE_STRUCT_PTR   io_dev_ptr
)
{ /* Body */
    IO_I2S_DEVICE_STRUCT_PTR io_i2s_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

    if (io_i2s_dev_ptr->COUNT == 0)
    {
        if (io_i2s_dev_ptr->DEV_DEINIT)
        {
            (*io_i2s_dev_ptr->DEV_DEINIT)(io_i2s_dev_ptr, io_i2s_dev_ptr->DEV_INFO_PTR);
        }
        _mem_free (io_i2s_dev_ptr);
        io_dev_ptr->DRIVER_INIT_PTR = NULL;
        return IO_OK;
    } else {
        return IO_ERROR_DEVICE_BUSY;
    }
} /* Endbody */


/*FUNCTION****************************************************************
*
* Function Name    : _io_i2s_open
* Returned Value   : MQX error code
* Comments         :
*    This routine initializes the I2S I/O channel. It acquires
*    memory, then stores information into it about the channel.
*    It then calls the hardware interface function to initialize the channel.
*
*END**********************************************************************/

_mqx_int _io_i2s_open
(
    /* [IN] the file handle for the device being opened */
    MQX_FILE_PTR         fd_ptr,

    /* [IN] the remaining portion of the name of the device */
    char_ptr             open_name_ptr,

    /* [IN] the flags to be used during operation */
    char_ptr             flags
)
{ /* Body */
    IO_DEVICE_STRUCT_PTR io_dev_ptr;
    IO_I2S_DEVICE_STRUCT_PTR io_i2s_dev_ptr;
    _mqx_int result = MQX_OK;

    io_dev_ptr = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_i2s_dev_ptr = (pointer)(io_dev_ptr->DRIVER_INIT_PTR);

    _int_disable ();
    if (io_i2s_dev_ptr->COUNT)
    {
        /* Device is already opened */
        _int_enable ();
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    io_i2s_dev_ptr->COUNT = 1;
    _int_enable ();

    io_i2s_dev_ptr->FLAGS = (_mqx_uint)flags;
    fd_ptr->FLAGS         = (_mqx_uint)flags;

    result = (*io_i2s_dev_ptr->DEV_INIT)(io_i2s_dev_ptr, open_name_ptr);
    if (result != MQX_OK)
    {
        io_i2s_dev_ptr->COUNT = 0;
    }
    return result;
} /* Endbody */



/*FUNCTION****************************************************************
*
* Function Name    : _io_i2s_close
* Returned Value   : MQX error code
* Comments         :
*    This routine closes the I2S I/O channel.
*
*END**********************************************************************/

_mqx_int _io_i2s_close
(
    /* [IN] the file handle for the device being closed */
    MQX_FILE_PTR    fd_ptr
)
{ /* Body */
    IO_DEVICE_STRUCT_PTR io_dev_ptr;
    IO_I2S_DEVICE_STRUCT_PTR io_i2s_dev_ptr;
    _mqx_int result = MQX_OK;

    io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_i2s_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

    _int_disable();
    if (io_i2s_dev_ptr->COUNT == 0)
    {
        /* Device is already closed */
        _int_enable ();
        return MQX_IO_OPERATION_NOT_AVAILABLE;
    }
    if (--io_i2s_dev_ptr->COUNT == 0)
    {
        if (io_i2s_dev_ptr->DEV_DEINIT)
        {
            result = (*io_i2s_dev_ptr->DEV_DEINIT)(io_i2s_dev_ptr, io_i2s_dev_ptr->DEV_INFO_PTR);
        }
    }
    _int_enable();

    return result;
} /* Endbody */



/*FUNCTION****************************************************************
*
* Function Name    : _io_i2s_read
* Returned Value   : number of bytes read
* Comments         :
*    Reads bytes into array from I2S input buffers.
*    Returns number of bytes received.
*
*END*********************************************************************/

_mqx_int _io_i2s_read
(
    /* [IN] the handle returned from _fopen */
    MQX_FILE_PTR       fd_ptr,

    /* [IN] where the data are to be stored */
    char_ptr           data_ptr,

    /* [IN] the number of bytes to read */
    _mqx_int           n
)
{  /* Body */
    IO_DEVICE_STRUCT_PTR           io_dev_ptr;
    IO_I2S_DEVICE_STRUCT_PTR       io_i2s_dev_ptr;

    io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_i2s_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

    return (*io_i2s_dev_ptr->DEV_READ)(io_i2s_dev_ptr, data_ptr, n);
}  /* Endbody */



/*FUNCTION****************************************************************
*
* Function Name    : _io_i2s_write
* Returned Value   : number of bytes written
* Comments         :
*    This routine calls the appropriate write routine.
*
*END**********************************************************************/

_mqx_int _io_i2s_write
(
    /* [IN] the handle returned from _fopen */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] where the bytes are stored */
    char_ptr        data_ptr,

    /* [IN] the number of bytes to output */
    _mqx_int        n
)
{  /* Body */
    IO_DEVICE_STRUCT_PTR         io_dev_ptr;
    IO_I2S_DEVICE_STRUCT_PTR io_i2s_dev_ptr;

    io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_i2s_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

    return (*io_i2s_dev_ptr->DEV_WRITE)(io_i2s_dev_ptr, data_ptr, n);
} /* Endbody */



/*FUNCTION*****************************************************************
*
* Function Name    : _io_i2s_ioctl
* Returned Value   : MQX error code
* Comments         :
*    Returns result of I2S ioctl operation.
*
*END*********************************************************************/

_mqx_int _io_i2s_ioctl
(
    /* [IN] the file handle for the device */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] the ioctl command */
    _mqx_uint       cmd,

    /* [IN] the ioctl parameters */
    pointer         input_param_ptr
)
{ /* Body */
    IO_DEVICE_STRUCT_PTR         io_dev_ptr;
    IO_I2S_DEVICE_STRUCT_PTR     io_i2s_dev_ptr;
    _mqx_int                     result = MQX_OK;
    _mqx_uint_ptr                param_ptr = (_mqx_uint_ptr)input_param_ptr;

    io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_i2s_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

    switch (cmd) {
        case IO_IOCTL_DEVICE_IDENTIFY :
            /* return the device identify */
            param_ptr[0] = IO_DEV_TYPE_PHYS_I2S_INTERRUPT;
            param_ptr[1] = 0;
            param_ptr[2] = IO_DEV_ATTR_INTERRUPT | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
            result = MQX_OK;
            break;
        default:
            if (io_i2s_dev_ptr->DEV_IOCTL != NULL)
            {
                result = (*io_i2s_dev_ptr->DEV_IOCTL)(io_i2s_dev_ptr->DEV_INFO_PTR, cmd, param_ptr);
            }
    }

    return result;
} /* Endbody */

/* EOF */
